From cda8aa4dc8d873fbd1958d7d7ba62bece2c3a790 Mon Sep 17 00:00:00 2001 From: zhanglu Date: Wed, 12 Feb 2020 10:08:31 +0800 Subject: [PATCH 1/3] update to 2.0.8 --- ...-least-some-tests-on-32-bit-machines.patch | 60 ----- ...f-bound-read-in-ldb_wildcard_compare.patch | 89 ------- ldb-1.4.2.tar.gz | Bin 1427857 -> 0 bytes ldb-2.0.8.tar.gz | Bin 0 -> 1676902 bytes libldb.spec | 219 +++++++++--------- 5 files changed, 105 insertions(+), 263 deletions(-) delete mode 100644 0002-ldb-Run-at-least-some-tests-on-32-bit-machines.patch delete mode 100644 0003-ldb-Out-ouf-bound-read-in-ldb_wildcard_compare.patch delete mode 100644 ldb-1.4.2.tar.gz create mode 100644 ldb-2.0.8.tar.gz diff --git a/0002-ldb-Run-at-least-some-tests-on-32-bit-machines.patch b/0002-ldb-Run-at-least-some-tests-on-32-bit-machines.patch deleted file mode 100644 index f553901..0000000 --- a/0002-ldb-Run-at-least-some-tests-on-32-bit-machines.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 04e74153057d34b5dbdbc03f47d7684b4d4c1093 Mon Sep 17 00:00:00 2001 -From: Lukas Slebodnik -Date: Wed, 30 May 2018 23:22:40 +0200 -Subject: [PATCH] ldb: Run at least some tests on 32 bit machines - -lmdb is supported only on 64 bit machines. But there also -unit tests which pass just with tdb on 32 bit architectures. - -Signed-off-by: Lukas Slebodnik ---- - lib/ldb/wscript | 19 +++++++++++-------- - 1 file changed, 11 insertions(+), 8 deletions(-) - -diff --git a/lib/ldb/wscript b/lib/ldb/wscript -index f5cb1e0ab28dc01e5b031c7c290bed26c7007676..03279772557284d96f5b8c81ed4a8513e5c65f17 100644 ---- a/wscript -+++ b/wscript -@@ -518,10 +518,6 @@ def test(ctx): - env = samba_utils.LOAD_ENVIRONMENT() - ctx.env = env - -- if not env.HAVE_LMDB: -- raise Utils.WafError('make test called, but ldb was built ' -- '--without-ldb-lmdb') -- - test_prefix = "%s/st" % (Utils.g_module.blddir) - shutil.rmtree(test_prefix, ignore_errors=True) - os.makedirs(test_prefix) -@@ -537,9 +533,13 @@ def test(ctx): - tmp_dir = os.path.join(test_prefix, 'tmp') - if not os.path.exists(tmp_dir): - os.mkdir(tmp_dir) -- pyret = samba_utils.RUN_PYTHON_TESTS( -- ['tests/python/api.py', 'tests/python/index.py'], -- extra_env={'SELFTEST_PREFIX': test_prefix}) -+ -+ if env.HAVE_LMDB: -+ pyret = samba_utils.RUN_PYTHON_TESTS( -+ ['tests/python/api.py', 'tests/python/index.py'], -+ extra_env={'SELFTEST_PREFIX': test_prefix}) -+ else: -+ pyret = 0 - print("Python testsuite returned %d" % pyret) - - cmocka_ret = 0 -@@ -549,7 +549,10 @@ def test(ctx): - 'ldb_tdb_guid_mod_op_test', - 'ldb_msg_test', - 'ldb_tdb_kv_ops_test', -- 'ldb_tdb_test', -+ 'ldb_tdb_test'] -+ -+ if env.HAVE_LMDB: -+ test_exes += [ - 'ldb_mdb_mod_op_test', - 'ldb_lmdb_test', - # we don't want to run ldb_lmdb_size_test (which proves we can --- -2.17.0 - diff --git a/0003-ldb-Out-ouf-bound-read-in-ldb_wildcard_compare.patch b/0003-ldb-Out-ouf-bound-read-in-ldb_wildcard_compare.patch deleted file mode 100644 index 4af1791..0000000 --- a/0003-ldb-Out-ouf-bound-read-in-ldb_wildcard_compare.patch +++ /dev/null @@ -1,89 +0,0 @@ -From f8dbb92b4ea46f86ff2fc448eb8dd989cc1efa51 Mon Sep 17 00:00:00 2001 -From: Lukas Slebodnik -Date: Fri, 18 Jan 2019 01:15:18 +0100 -Subject: [PATCH] ldb: Out ouf bound read in ldb_wildcard_compare - -There is valgrind error in few tests tests/test-generic.sh - 91 echo "Test wildcard match" - 92 $VALGRIND ldbadd $LDBDIR/tests/test-wildcard.ldif || exit 1 - 93 $VALGRIND ldbsearch '(cn=test*multi)' || exit 1 - 95 $VALGRIND ldbsearch '(cn=*test_multi)' || exit 1 - 97 $VALGRIND ldbsearch '(cn=test*multi*test*multi)' || exit 1 - -e.g. - ==3098== Memcheck, a memory error detector - ==3098== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. - ==3098== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info - ==3098== Command: ./bin/ldbsearch (cn=test*multi) - ==3098== - ==3098== Invalid read of size 1 - ==3098== at 0x483CEE7: memchr (vg_replace_strmem.c:890) - ==3098== by 0x49A9073: memmem (in /usr/lib64/libc-2.28.9000.so) - ==3098== by 0x485DFE9: ldb_wildcard_compare (ldb_match.c:313) - ==3098== by 0x485DFE9: ldb_match_substring (ldb_match.c:360) - ==3098== by 0x485DFE9: ldb_match_message (ldb_match.c:572) - ==3098== by 0x558F8FA: search_func (ldb_kv_search.c:549) - ==3098== by 0x48C78CA: ??? (in /usr/lib64/libtdb.so.1.3.17) - ==3098== by 0x48C7A60: tdb_traverse_read (in /usr/lib64/libtdb.so.1.3.17) - ==3098== by 0x557B7C4: ltdb_traverse_fn (ldb_tdb.c:274) - ==3098== by 0x558FBFA: ldb_kv_search_full (ldb_kv_search.c:594) - ==3098== by 0x558FBFA: ldb_kv_search (ldb_kv_search.c:854) - ==3098== by 0x558E497: ldb_kv_callback (ldb_kv.c:1713) - ==3098== by 0x48FCD58: tevent_common_invoke_timer_handler (in /usr/lib64/libtevent.so.0.9.38) - ==3098== by 0x48FCEFD: tevent_common_loop_timer_delay (in /usr/lib64/libtevent.so.0.9.38) - ==3098== by 0x48FE14A: ??? (in /usr/lib64/libtevent.so.0.9.38) - ==3098== Address 0x4b4ab81 is 0 bytes after a block of size 129 alloc'd - ==3098== at 0x483880B: malloc (vg_replace_malloc.c:309) - ==3098== by 0x491048B: talloc_strndup (in /usr/lib64/libtalloc.so.2.1.15) - ==3098== by 0x48593CA: ldb_casefold_default (ldb_utf8.c:59) - ==3098== by 0x485F68D: ldb_handler_fold (attrib_handlers.c:64) - ==3098== by 0x485DB88: ldb_wildcard_compare (ldb_match.c:257) - ==3098== by 0x485DB88: ldb_match_substring (ldb_match.c:360) - ==3098== by 0x485DB88: ldb_match_message (ldb_match.c:572) - ==3098== by 0x558F8FA: search_func (ldb_kv_search.c:549) - ==3098== by 0x48C78CA: ??? (in /usr/lib64/libtdb.so.1.3.17) - ==3098== by 0x48C7A60: tdb_traverse_read (in /usr/lib64/libtdb.so.1.3.17) - ==3098== by 0x557B7C4: ltdb_traverse_fn (ldb_tdb.c:274) - ==3098== by 0x558FBFA: ldb_kv_search_full (ldb_kv_search.c:594) - ==3098== by 0x558FBFA: ldb_kv_search (ldb_kv_search.c:854) - ==3098== by 0x558E497: ldb_kv_callback (ldb_kv.c:1713) - ==3098== by 0x48FCD58: tevent_common_invoke_timer_handler (in /usr/lib64/libtevent.so.0.9.38) - ==3098== - # record 1 - dn: cn=test_multi_test_multi_test_multi,o=University of Michigan,c=TEST - cn: test_multi_test_multi_test_multi - description: test multi wildcards matching - objectclass: person - sn: multi_test - name: test_multi_test_multi_test_multi - distinguishedName: cn=test_multi_test_multi_test_multi,o=University of Michiga - n,c=TEST - - # returned 1 records - # 1 entries - # 0 referrals - -Signed-off-by: Lukas Slebodnik ---- - common/ldb_match.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/common/ldb_match.c b/common/ldb_match.c -index 25fe3f9c21b14c23696eecd700b2170b0c3b1981..8eeedfb12e0600cdec7431a10fde8bdf9dcb2bd8 100644 ---- a/common/ldb_match.c -+++ b/common/ldb_match.c -@@ -308,9 +308,10 @@ static int ldb_wildcard_compare(struct ldb_context *ldb, - if (p == NULL) goto mismatch; - if ( (! tree->u.substring.chunks[c + 1]) && (! tree->u.substring.end_with_wildcard) ) { - uint8_t *g; -+ uint8_t *end = val.data + val.length; - do { /* greedy */ - g = memmem(p + cnk.length, -- val.length - (p - val.data), -+ end - (p + cnk.length), - (const uint8_t *)cnk.data, - cnk.length); - if (g) p = g; --- -2.20.1 - diff --git a/ldb-1.4.2.tar.gz b/ldb-1.4.2.tar.gz deleted file mode 100644 index 5f871eebd0a625843b53750884580130260f7864..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1427857 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%0AI)C`onEkP)a2oiL88LV5U8jik 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%0DM>&rV?9?St?MlGX&XRj^2RWh>!O*O%L~ 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�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¥^UN^^Xc{n2{l&W+Th}Z+1IQE9Vn5 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

    >A}I(ACVPOXE_GueQ|0 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 z%0A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 tW@DW9al2oSH2mZ7= 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


    W@X=TIQlBRHb(zG||U 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%0DSQ~ z#HM`~eMHhWOV6nZH5MK+>#P?_kwOC5BRP9IJaj($I zeB<(0YJrZ}FGV~wa4OcWo7Aj(Pue*j3Zc*`h%7e%tRA?h6D&)4+@lGd1I-?h3)xEW z>MW%C!egj&mlz!;Xar$Ski6>ok_CeS^>qqdNt|S<5TQeb3o98=%VfNWp3eVCMyb_; zpHd`%5v%l;9($D^<-~u)$i0Hg#)6qGQa0Xtc5XdO`bVj$3nwhPf4_+HXnd3u5oo!$ zo?8U$=~Q%#m=UFU(hEfm@qgMt1MkAXu7gi+I&($c_25nKF$P}l4T?Zs&lki-tY1Nr^Kn<)cU;B#)|#T*hCq(wS`LH)SgxcZhK+kC!w%a?f568 zu}Z~@XCu6ymz*4nbnZkK0ghH;{jl^HLo zaIJC3?ggemE7rA_7nF8ZN(Zui|RiU70znUo_GOU44VYYNA*_*k0 zx}f{&f)!X+lcUGkCCHTUjr#j6ss$?NmL>twYcg-ntO9&n{2Odvt14I@Bsdd2M%fda z2Tn0Yj$Y3$a*GPGi~71iYzYfc)o-=-Ly>nBHX70626v>;>DVlIvEBzPLol_+BE-Iv zdovIfpp%Y3+!*(-mQ7wE_@9z7;_ibX*x?wAIv0Bhdmg__GPT8m)RN(KtPJk2jKaFf zFd5()pA4Z%^wdrVKp zQd*(lJGC}x_&HItPR^Xu>QWa4Z>l!YW;%nDeMb`wjeNk#zR`r6F6l|Xm!EV~=2jEG z{-Gz{bhF&0+qimlIA6AMO6#fEhb@)s7q5h9KibBO#uu0*3+k+xwBIrnFi}-9MiR3$ z(6BCKL>$Uk$Qrf>X^F|tHn^H^5XPx?w@U36Hi|%OyYnHE1!N!|JaVmiX&DqfMPg(} z#FKcJf+C|rh9}J?oel`$6poSKhBv$%SVc5{ROr9Cy-mhOC=-yDUYMlJITI?8p1Gi^ z%-`(ARPL?0W{N$snu>bSb0_U{)O+|aq`!i9Z+aA1KNmR5HThKpwyp@8Y&@*@qr~uP z(A3w1vN{dQN)U=HanF3oYxV*P>+1qP9RsBxgmf^>@@%|p3$~AQ+ztw~H;97IGqF5t z#R?pCf>wz9CR$j4Bh3PCM)F2;R#KRiH#hKqrk#2P{4CV%g=^qKwIrB^;bDs7y4x{j zkoWdq#ixqPyUZ_N8_(>vwi}g$0aV@7eGaJ?HSkCRbW<)_wrLYwKw_0MxhfpLH_TFN zw4)d678I(o`RViZe4YGKxt_n%C9B7Pcg0m`9%Ze60NpR%)oS`SI4px_&B0_n1xrpQ6O(h#{ zwnSASFCF60bwztN4V5@L$&+5UccKEW3GWg2q!bd3b270Y3)FMOAm^@yUXI{p+j&V& zdZZJXB4aPuzM`{mdUAr2|K|(Q{=s(l5cvPf`_ES%zgK^zU6l8Ll7Ni7%WR2`B8zbB zuqaoev03;WudFay4G`Mre8~lWxN=zs1^9*uyBFJ!ZPD#ed`dse)JLj{esJ^iQ2CqeAZWx-+0487`Fz#|os_O$vFcxKBvD8h7*VarW0nitz}}+N zETW3OTv{mkG!Zm~aJ1slL!WGPVKwBHw{_f9y@6_Tis|a}(7AcBE+#oQ9-D(txxI)O zmWp208Zc`?SfoTnn*X3jZF#&orwDBQlmHNKDAa7{(1Q9FAA5CS^^v9H8hP0{V;Po+mLkU;6}ZA72h1s}N^ z9gxm5yos?sbp00c4?(}Z1XSfJnL6vLcc$D0X@z$l%+d=u_4dvu=QCM(1mVQ*5zZZu zlelsyB`J9ca65_m6KPE+ttwY8Rp_iL^;DAndG7P_zkYtB698BKJMJ$Qhs8x0kss(7 zFbkmvXt?|^z{GcVg102*GLpp5J^ZPxEaR2J{JghiUD5Z(60g5(OJrZwpK8)?H*gi~ zI3Wc1tS<}yH!g=FiHpZNbs9~>Iq-R5m_Xisq6#*}kaYZM!frlc5`}jsAoFDaCVHZT zfyO5{89`RD@xZaA$LO*dzs^$iFTSH|s#@-7Io=-TTJh%=9xsZ?rl@;`)9&45dCv~ZaJTT*MD zXDI88Fmdv`zu;@3tLxvKbzs+k#JWTJ3gaK0?p^mu>cmu8 zq4HTm&8GS~9!I7xE1N{Oogjb%)qCW`QcWkMe{9I=bh||12RognJn2fD7-fL-N)P^X>hNp z*)3Guc^>r@*OBYqZ^11#X3}uFI?WOT!&#TPrTILkaMGA6r+IF=pZ=7*=WWI(QhV>9rwb?YL~} zE}_D_o#laHkD~7di-HjwFg*}GR^|rqr(q^SytZv@M1vqGWUU!*pGnAeEB+L~yeYB(!Ro zH8@#8;q|tgvd%lodur84?O9Y+6EqlCWN?w{F+2ZfOeK`#wqujOKj-8SCqjS^HW7%@na2$D=mx{CRkXW#~TE%La$j{CKJizRX{6uvJ+<3;35V6Zu-t)aTkfGxlydr*xvGM&>DZ3C z9HE~MPJcTex=pBRtz>Y~h@1_$^1N>x9ySk-p6MlQo1d8@3GvH~$ygZcf@f>KJcme? z2`r3OIolNG^Kcd8qyQg;1qTT#yf6m-yb&(km|CNLQWiVBxB(i{)S5G(dR@%y!T6^iq+hbQeCqQJ!di-EvbpGlixr~%99@fTm%xe_6_sKVnwg(r`{`tqyd zDo;agtUmqf>DN!bd|FcP>t{;;dJ@C@K6B+m7)bO&cvxXv5}#L;wiaCBrpCV?KYsG$ ztH&!(zWn-&r(b>b#n&re?S$B{=(9>MK)oZ1g#IabORgkK*(1p7{6#)xKz<=b&+z~U zUk7QeRF13~^QHc*LX3Vv!D<2EeHwSF20-idu|6x$l?(eF3fN?bApSGDh|qci1JC{ zw#d3OgjGXY5d}>_TxD~STOhc|@cu>t=yFbZ(+%dQ;=BaA)!YYtBl^mSa`051j3`?Eu2yIKBAqp+fCL>vc)AS z;Wytes`gcMYecWM{pmKum+1`~R4Cn(-{x{IJ~ySbuuT}PtzWaAySNF%w&qQ%fuL7K z(CI=@TBt4dd+kn3*jVWhW%GZ`e}+j}P9lEkSS{G%(B03V5IWZJQ&Mj#fPQ1t7U#;N zwuj@9Xa`@+o7*6KXJO+bhD@b`gBWqHCJVa}g$JYx$`R?hrj}@1z2oL}U9Sfh-g!8% z+UcxbE-78aM5__-pR68jzTVsXVWYKwu)TZqvbAw^bg=#1@lmt3$|1FIk!+72WKr*Y zn2yFVUxiOHO}*`oo)HYTMhGN*wh5A_b8p3yae7Wep+Z3N{Um;8=soJhgddL9#`=wO zIN!&>BjY8AAQ2n{9-GO;H+S}Tb0q{>#n2Kc3 z&1sMTJ%pH+!eA&lDw=d0G&hc#(d*{n;l`^br7#kT7Y{-tmoWCv+BnYAY{5|S!zsCO zL)(n~{pRkL?7F>8#?n76ppa)A=gtekTE5Eb(Xqcx?uo5jKY{0b9T_s;EP6C zfOQ&(H@!8*LhGcDeeMyJH_69YqC3e(ELj>M$wm);U3nl8r|d*?eR!xx+lVw3yMxZn zk0tvuVD!t-|IqBrfSYG}ZNcXny$W$c%6_UC08Ki4ZUK0`&h0*+Uuc8%y4^fl17Wf7hx|yN&TGb`b19! zh&Qd5h$K$FI@MEMvL$SKVQy-#H+FXRHe0WbHx9O1hui-LR#x;_hIZ5T(YAAFAFZlw z>}lxHpX}Voh2OF^o@M@d0 zD~9`FdMpO|Fg&)vPU?@g9^H@rU(J6?YJ1V|ZCCC)oy4P@tOrXF4;I+>rF<6~?xTI! ztD6VAjeJ3C_^qKmRJ3_h01Z26{B3Hgd85)6ZHRb}oM8@lQ~?ruIGY<#V4CzjLNI5X zEmxW~P8PEZNv#iuQ1j(;mhtkXCVl#we~p=(jjZjjd7YuIX4g8Ldi?6Hu`h9y>oR$H z-r;1O04KAjvZPO@09mQ?M!}7K8TXS0vAk9tzMAiViijAPIouLaju$(Sq}-K8R0u7U zen#Ohzfq9fTDDElp@Fpp<`7Zy23mc8m<+Ps>3|c{>Nw53&uNNs9O7C-Vs?#)k2F)a z6p6Z!tisrEWDnQ6fJ|Vn7g(_SQ#}+C}n-x^(pU5coSW!ps|EzOpl~Vu#~= ztbg90aE`yxXfhm6F~lr4$h0PHR@Fl%<#-IuO}kH@(c;qB{UO7t8KOW_rn*mbl>mh{ zQ8twezpC6r9cKN$rjq(vuv&=~RQ?m69(Kcl`tdftf^Cn0 z7{vLKSBa1%>J*|kH(ackla-(6@;NxO?3Z@{Dm{hiOoO?c1t1PxFLAMGlUkkiL+$IO zljvlGwKR5JuC8V0?@2f5U-88Uxy-R6_+&IfliD*>aiS)}iO-~NgvEUdYjj*58mEjm3y}>q-Xs*F4OW=$lF}e!U_UV$`pEcc?L7BR;F5il6tEwv%u~i zTvWMLEslY>Jx!B6>qW}TLd~AJ|9%NlH7-~5YQ=w=SVqZh2nK+*dMA1^4WJ4%Q_;pN zVCqO4F}X82WLM0}i#MPgGY|4J&-%JxmE>TB*k1GCVDA9Us`Z`d=l_}TRMfIMSv#B2 z6(XqQhQG+$hgDT{u$s}>HG!=jN1?8DTIpmwoQxy&XB}VRy5{dSy`w=}z$mZ$!3toABptw6wGoEksj2?~vFhqvYN~fyC~afHrCnOeHFpejs0zb9Y8-uuxS3g z+1#hO+TYvWh4c7fv}g;dI2R`Cp)GyT+}u0Z5^g%W$|&iis7@10&WE=2qN$%9P-(fl zZT*CBJG>A0U`5SMv-gFx!zDUH3lkd&C=a@^)v|FHSctcN0-hpihYnp`*03!T9~C`^dgJ6gdI<}3>BZhK8ASV|^f!1}SpD&Gw0TAe0v=#3@1otX-!GSqH=r5~FR#_L`C|R4Wwt9G zKy~u4Y_a)sbMyG9+4_ECcWbA45KiWqtF^he3urrr{ieBbu=zbHS7tTGBb~Edst(sB;sA?M*mD||mtol6pZB?E7`;h6 z$D?U09uCPi)j3@P%6KHFqjWNaL)4&`owWdtvkmjhsUdyxkrl@2nBr=ngp_n|RGAN% zH)|KUMRudA*}EQ~t8%lj*`YAWbw`uIxHki;#-j-cznia*2fZ<#s}J!CDOv<7LmAE3 zw!hroX-11DLprJB?rLq;X?|0fUJ9|bVqct3`s3aZUY?LhZ{7*kB!=EAV^pw8TG)jO zEJ|;;aDl{N3A1L%%2Neh-4rLRpcnTE-#YXpCEaU@R_8Bfzh@Dal1q@hjgJu5) z{+{gipMNT}sQzVLPp$L~b^zicxx`&(>KQBKy zfp7Vf^a54G5)*iT!s=V|op%iVO>F}D>xF1@EhQS`xD|7$C-e^}oWD$dRgYbmSo z#zCbLa-Ypl>xd%PP-_Z)xPg5P)3#MGk-K|JjQ4xsb@{rCfFEfJ7F`Q5JYAI7SrN+< zMKoKScXrY||MfTDYv0$(6aVS>jlW4PmGc{LXc&od8@-lUiKfN?Z7SS&vs(D?Xl(7XP21{A>K)$j0Wu7N5FIW zj;3gjlWIkA4a_SPuYso#k_B9olUSFF#NFJ)GVz;LoClj-fMa*}5LT#ay+LNi=-Qn0 z)5~Xkf$wdaMRxvE_RZVuo&Gk%I~X1_JZ>7=YD$LBu^RK+X}w%J%|ZQjfHSB8V~1*o zb&n#v`N`Ys%GFgieY^)pvrV4@`!}6E9#WOb6NA6o$y0#E+y(hdZa$Tfz(a?*)u(Pq zhPj6{Zuo1K@MqIaYyy>BK}qvJB`RVMoOqcz_1`lOnU+aL2gkeo#!Qm6a4L>^8PFt_ zw81}nKis?xrIdV@k4`yFe)VaR1ZHE+qXWPe$f4IIW6BZt%y{!<%6uC+?l)^2-tpjO zSep?^AzWAMel?MB91mxc23MDt;mqtZ_?ZPf+v;DhhMr9*49R0AMv1i7Qk*_oz@YKz zyM;Axx8r6F_f(*8Yw!dp=K!vO8i3cKIrVQ2jSkgVZ-S=+&K-3h4d@Ne|yI4waTP))0QjqE5`GAb{cX;9eUyo6k`j+ z?qpaiQ$b+!RJd3*BHfq6Y6aAyQpcR9%ItgiX5}r834^2rO}A(OzoWaF2S9_y>&CND z?e_-27(6J@Nl#TtQ$M&HA$@Uyr01+&n%m#&fo^gS*2{a~sWQU2q^7lhLb!;H#=?;?FpPKZYmJpL>~Sa;xP8**@u#Y zDcMh!J-ag**n_Whpa_5Amh9An9KHE<@Ok#Oq7-PPo%THg2pBWTt9m-u0|VvgBB)fIE5^Inb;VQKn4OFFKJDIR&*u*<405!~|l zqBX$MFSuv=yFB+OXp}W7s(JO6{Cba~+G_LP6rENE^>r%&Gz^6mF-R=GNX>+5V1}tIvQ!Fk)_q*4vH^}RNf8LLquqIFD3uNddLb^LkB(OR~u3AxuJCh$B?*R8bPa$ zsEBvY64Z?-ptj2tgW%-E$1qJSw^=s@2*r==bC~Vm*sWtwh-HvF-JNqmw*96{U%a*4 zZ64e;8SxaO!P7dMKB4kDDBGj45_`V`S zk8S@9!U2a#NeBHa_{DMiqI47~a>dw^=y25iQIOU?8?Z z<@g31ouVK-stV_!3bizcKvNqEE=Ykb=F0;Cs0N@)BOiCeQM?AiQ&=4+$E0idu_>S% zhspSO!0@^z+Q3VWTrpqVFRt&*?mf5RYbO{vIhGSa@`i@=sB_MkSmnfE(e>2N7%t`Q z5gT&0lmU~J@@VrNi}cCJxQUsfZ%oelj>HAcYKxTMra+BXqTvI~#$e6gcb2Mu^;I06 zNW>v3Op$I}j8?*4hK9ozb)PERVmBPbqeYh#fZ@REAh5_eFq;a{X^L^2Ftk%HyUSaC}JC9@keZifZK z7Bg~u^L~T<a12V9oV-m2!KKUk@58SZ zM-DUJ5@ueN4bu&H5i9mPQ^uEzfvkBKc*T6*$`iWZ<$PRA{vCPf@nmGJ9=#Lk`1bPb zok+4uhMhrXtuC!P-lx;~Is2NHA4zU_453ie)ia*n;9xOh3$q;&atJQqZ+{yM&Q|({ z2e3OrV)gZ}(V5kXZuJP+ypzuVQL1kY=|1SH7!x6wF|ml8mQ1Z^hp(;Q%U3)`_ zM`070Q2ClM9{~B=C|j@v0yVn>+BQ^{RPSgi zxc0G#FAw8J`na1=(#NMgm3_h^wDnmDjosp=oNN%dI!EA*GfiH|5VW)j;hAMc*M z&=xNoBA;Q+CQ;gxwJ`$qZaEw~L~7l#&wxc_!As?=6n?1ZzAuOyPbKXRJl1v^AK-JyOx0P4YOIF;4}E z3IMD}FV=PZD9*O7MSMNacr{i;3w1xadU{e&whk-8H|bScdeur{ULWsT-W-E?74zmD zk4CXcuj4EKOuIQnpFW16;%*riyV3dHzwc%$F{N^M1ny${^Uuf>%^&BA%Z7KxK++Oj zqj*|EQq;2c@YdDyJYqS=*+q8Il`{h-ynsAy~#0taiVl0RMx zhFC??aMhIy>Wu)hP<6wt%!zL%T-+B-a<(oNs&fhieY|{NuE=yMMdWb!f$%CT-%WzC z2gD%zMrmMQlkW9&<7_0CEf~W{##7+m>gH25 zHA`D1aQu@<{^BdBv15q!&^p%pr0;U)?sX5>{eV_^H_C#erL==Bj(FwZqbzDt9(f@m zk&#cQ%h6LkgZ-JB>6lU_5>}B1fj=u1+$nPy3ZHqmR%xq($m-w9-a$fq0L=x$pOW9tOcMfcnOzF zV#0kGKd!Cj{y}qd<4A?B`#@d{toGIhur)9Bnw!hWv3Su%a$X7ggC(9)`~Ctjq|!7k zx*na@a!RCab(v`Nq3!(dz`lQ)0l(>`u^U;P>KO3PFu)J(3p%Nl(Bl2mP4xec=J_`; z&8INUawVd2#>{N%^Lnp%Ug;!|%ldIUv-bJv zX5%HDoq-60gvdWK&S-H*gT@*DDRQdqdxfx|#cSb{mHdCLmAos1X={T5gMpk;KpWUi zdZI*MHEwA5r?UjO!3a}-Ci<#IS~V?OzbewXwD66`J0%!Q_^B|Uv@s+KJ75fo_$t)9 zaW8@1C1XBg*bDwEX&5hnH zTtJCy&1-D7lNjW#L6=ZrPaKFZ9ac-@OG?$C&9ql5SJp}Q~!ogOxFw;1ZjkxEZ zf&-9QZ|P*9XB4M0Pje-<9kR~_$;E?QR+>Y2G6-w4D@!6lv56OzYw>WKMzn4#Z=9!A zU!ieDrA#P(DuSYfC_a%aY3{LPds6@VSu?5Nx(>H~UbL}>wi8;6?q=f31JbBLwPGHv z%|?&1mk%F$8Sd}7bdxg?N(Ue~PLd$mnRuvq(#xfjDigc&38e0Y_witS$Bb+?AYHy%c`9 zFPaD64^$3Vjg%;_Do$xGCsjp4V}|!EIG<4ezotvZW!A0DMU3)^I8WN!trl5P#=iSmwZXxEf=BcN8Oe(e2`dY>8 zWpqs@$t-tSHqa6fpvLODrHz-{vxbY%N_TmIu{Cnj8cHQv$PJ~;^hS#EZz(E)?tG~s zS4Fmd1J>>wiQV%ae<-@6*H=Le(8z+Rx=W2;+}Feq-hAxA0>

    -dp%#l*2eHmqhR}f|M=%zO|`8ICjEYG;k)Bk&(wKu@Bp<4uv?9idkb~PTX;&t z*RxCXIZ588w{r=2dQ!XKnZRELOMZs3U_!L$g{yu4m`TwT2MXygr=}-!*t4g%4C;q- zsmaW6@)^oP!w}aoVNHNIR-F$o2}4+Y7;^vtUl)wzN5qb50&Q z`8Aw_UvS}}uL5a=>Yg(PUFqlLE_$p^aE?+zn;}%Xl2|axR&5WWG_n)~)1eLH8W#2m zyOEYw`BCMr&Upr;811B7BK~c+eBl@7tLXxv0@Z{S0XNqRLHNabys(nfOSbv9(0P7j zUGYCa$L8uL9KQq;Ft7(qphWxjw^qK94j+a}bqv11;jx2h$9Z=v_pHTd*1GF!>il8%_KI_t zsT6Udzd(O323)QXPM0uAR z$Ujff^-0N9UCC9V=9y8;Q{vJQRQCL9hM#`7y|lXgboue4@mX)wZ4Kkm`05e+lBhq+ zXaBn0&kFo}`Q-}zg&+6tXRo=o__Jwlhv=D{%Zw(Jz4ozwDPZy@H4@1 z98vVIQJRj+%1wLk5AGlG^N3T8q{FLG@APaOJziP)I(n6+ry$yH4?4^95f#|!b&>(z zL{A1?W&F4?jDb}3n@03wGRjbDdAz&=OatC5s8@7CT#T;LNpv1xk%R0cOZal+q-PQ^ zz*YtF>G`nViwB(~0%7!w+EGxjC($noM%o_7Jv5fdx*)TOK3Yx5~mBuWXU*Wm~?t4y$%d*a5_QH##1!?r{nf88J+jC zjLg&GK^MXFd*?ljhKrAKnJXj}v+w)X{AcjBH%P=2&%@`lNPT^MxY_!#c`$FP zw8*Nu)q)R3Ho)qUYNR*lLorjFzd~XCJTfNC>J?@FqFqfl20P5^7b`3HRClA*8TKa` z{+mzUqsM!+u(^Qd=cw2qfTUIw9m&tm;v|{b=gB`I~E{(0S`0MIK$KvjluNyfaqYg zz!?TcnF$ln-k{T;bb-KOJ55KtT<{6d7Q&*{&!C725S@P8NxQUyK2x=$=YY|8bh>=@ zBKH`&oPSI%GV1ZSFk%IedyfWru+3hoJ6W}~nVzA4$do#;9i-2w|~ql^x`#etM${~!4`TR;NqtUoeAviV}Jq8p7c&BWep|W zBT(wlh%aH9+C4V$F}Je@8m$EGE65G4*88u&Y<>B()vD7)vVFe2v;X8VJVw$nOUrcW z%cn>(AOeM7(+cG)T^%G-t>3M^pMQDP+|@LsEEe&^K_-iYk>!Z-PDfcw9DOVcP}9lj z84mL-h3E0$3gIZ@NaA4#3O;6&;V>PInIj|5!F>XVX2eVffn$dzQ2soA-x`O^G1sgo z26P~f zFB0TF`H15la30f6OnVt@Ny9$utRZMIx_6x=?|WU?F3#ir@)Xo@3ooew%icA&FB!C~ z7%i;4|9tz)r|%a8z5+8s+_Eaj&p+!EJOgl+nz}0EKMJ{;mQ9KS?{;%>gL&BEDmR`E zRUZ%mb27QRIk9m2lbg(psILLs<@_WgoEwzT%zEsQJ$D)c!4sl7j^$e8wAJTwEzK86 zFI6M&%6jxG9p-95b8l6qPCYrqE7lx)g+_)Xo5CiAJQM{t*Ss9aLolr4?cJmOql4Cw zw?&xet*z$E?cL^9-P>CTg>~ZtMF_?1bP&hCm4)YId%uWerq`f#*$47q8ZY(IItv;V&SF?w$$(m+20s}P=QF~iVZ=$WQP z>53SlWEgfCC0AL?W>~=$tkzTc3N|3>HEj;07jWHepIeoVAO-9s*B636m7|n1o+^Xl z4!_#mjLzbVgcV{Z%y8ndI=S*S=W---CbnMf9&fgCXFe4JXXEJTVEen{qh>8`v^C;d zEdvn_dNq(%c{9W>Eu9j*)rjIo)J9Bx#`{Bs24pY@)v-vWeikw_zo`2VMdT8{hus9u z*rclC?nrRzyj2bkcJDr(yd|XYxNJ2md#e&ZZSU-~4w^^D2fM9}ou4*-IgFN8gKzhC zH=EJYl1u!oV{$Ze>_U7HSx$K+^`5h2{~S=#XkT z872KIWx1+)!^elw2n(GjSX zYZN6vsuiUJU>LFWHl=}cyoO~yZ&6L$p>cT+x-3_=>1<6>raDL2OUK?gOZq1bb*ViZ zrN9%;&-EmziJOeHt_@pE=rqjuUVi=vMy!z_29E`6&MSrC`xYgiC53b@w)6V2=ieaWh6Z9QeiKx6Z@RfC9&; znq)XrZs*8`2ki(Z=TL{#sk*Pw?TcO~S-Jpvj+d==2M!{rA3<1_GP3cc9RcJCOd;9m zBIdZ;u_T~@&N;;$a~5N&?<-Z46XgM#i>X;Yby*u#?^ePG9D}q_)Y~xtCe)pjH#%p*w<# zBee{%6`+JJdPXW56@cZWL(EesA=LWSGqUSeX3Cv zM#pskCz#bVW_>%13x*QoCy#6XsebQRSWR{D&0&fw-+HeOYVYZucV<_mJ$AbyhGPt9~^rkm>8%3WHWNO?j zCVHfLD@Smr^Cy=a^=D1Jp)b)oO%991%90?rf`T-_PkCmYuPnPGJSG($xozb$Wx10l z5q{5BST*&R8~E>_i>Qri?|zmFz~(T8U(Vxqyw$1jP|*Jj)#GQe5*(mG@~s!!F1^xv zkiR40F)J@7Jwq;B@GdA&P@g3}(@qHinldgCiX(51Aj>K8a7Y~s!Yr4L6&px_M;I!eO%XsCEfSPwB>hLc(wB@6SS(O4qPp7Fm(ea zC_{uOO>_ywm9&nMzmUy z_5RZdUDTz?q`E><1{8GYOfYss17X@(ddBT=M-3^uexbn*;I%2Y*rVuL*wv-ghJ_gh zMj2w`J_y&D3mCST^9hB!vJXvgmUPhJ`{(>ms2h((H;P&;7^@y%gLtf4A?%yq^s-e|4ixnCy?R`XMh(C>K7eKzZ&J5muf ztyu+Bc~*2pE}E;Q)k-3R;L+0wjnQ~(&aL4TFz~X$8N$e`KW|PYXi!##NN8e6(z6OH zB?1<)9mC=6a%aV7aK)3onPp0>k|YUOF~uW1C}U`!21_60&oNSW7y%5|RsTqTmFd`W zsB9vOlM|&AGkhq-7#j{?z*RdzxH#eg94bZ(T)|cvHd1F1_)Ou+YvR9n-95hhb;n4* z^|E6yceU#9TEVP2SYy$**JT!EEk50l2QwZG_l-im__jg2e!~fGOovNaeD=Vmw4!Lu zNUA+UGFDr!CwF@g#oca?-D((+yPp4tJf?<^~owi-Ypi-A>%p6WSog~X(F{!H*ineNc zLuGj+v1s=9NrD4ZmCpnhMcqwmdkM8h53ccD3`@ zB}#Zx*G_whF8&ftl2JuR$!&S$MpwcmZmf-`h5S!b$g_3(N7TvZEL!o~Mi;4D8OwSr z4v}dCKXDi&7|%tbRjqt<%v8?UMe&+%kksn5;opUZF{f9f2B@}67Cp;8@j^!*{@j@I zI(`Nj-KI%~p^OG>+>g-OZWMZLdrI0&WA0uoYF0*)-lIw}H4B=k^Epgy=PtUc;fP!* z3eYqaM^&XfR2`S&D}1D8r!fr$wy9vF7Mi2L$TVZ&`_#O)R>I)r>~>#mF=7xn@}T;J zYQxqX>ximQoxVaP?1k=w3v$^?go*{zdnpXs!8QC&HbkD8Xwh~dCnh?uZEXQL2iOAB z3V|ve3~2{^&;f116m@~<4ClJ7uA!qvI#3Hs%Q5+V$ed#E`dVKS=*1%_lTvldEuI16 z#x?4pKM1c8ZQzoZGX~Ozp_CrW7m^^QN^62*jimmtt1k~iP>Y8D<}E?wtmOu!+ULkU zu;J0iM?#+FdjkyLQAAUPry<>)B63$?gY+%{XaaX?Vx}ON~A3}&ZO*iv*`e?hs zXT>S%?t+cVdcQ~=M2`4-)tGVy5~xKA+*;x zFhd)S39v5L|0Dg>dHiPO?TjkwS=ac0jy`6c3sNw0+oyH@AvPR9{D<0f1n3zz9$WJ- z-+Vq1=BEwlgKR)K8vn4H&<&PUa3d0nTI?#f-WvEL=Wx`2x-W&AJC+E@gbwwZW;XHni&;BPe1&s~@)=w{?avSEV zizeU-EU9lU;=Y&))_@1$F)A6}WH`JLyvi~m&G;-!Q4P1?CHK8VFy!`vYtcZ~P;!Se zs$905eGoU_CP&FILA6)^s(kU#g@LzzJ}sVq_Tu@pUkBFP9kYnaC&?SE`Jw}5DX$A{ z-3Iip;TUyZi?V*I=bmT z{b?P2+NJ*ir|Q3ar@r~p|FuFUiL#UV%)5F?gGI8$EmdtEQz|fV{2!-Di(C^#LDd5RQXF;{3pu##N}_Yay}@hpJizj%Ir;9648BP1QDt>PscKJ(Mr;%6o&%WLmGOHT^+%0+iN1 zEz*y;8K59>R~v$WRee*imHxtw;SF=L<#P( zG|*m5uIb5nI{F`JRm&sizNpXT>yjeE@nXhLI$&&J)oLWq^^0hU{p`4mA#wauMBxft z_!3Nj@wO9wReFOaD&MW*X&RXd4)lp&KP16^+JkaSVb*0?Z5x_(wFNh#a>g<1VTH3w z));8rZTQZ&A(R{aok+~_rzQRu?@1`*-0{97K+d{1*{Xk+{YlcV<01P=ruwu+eWYX3 zN7$xrvhWJeOn0q(ZJO!_KOfS&4p z?;VGl)ETg&P0U>tkFFkYR81;fd*VeE-J`7b{E`B*sTi2Cj;1PGVLpF3>Wx)YOI6s( za>b1&qft6Sm46bSQ#?A3;pv6iT#mN*-bQAuSJb>oDZF*Qdor3!1_>rqwOPJRb}ltK zPMO6$e~{@^3ggj)^J&mq_3$JH`m!qpLr$gx5Lk3hU$vk{7;=@u>&0V^pxo7CRhThD zG0k!gZC+~~cbXcy`9HAGwaW0|_f5S-`Cb)hIQ`;qbZ(FA98$PUH8U#c=Abje=#&}P zyy#`Uc8?kCr83 zDoM&%%QOViO-2-u`qV|)+=;j9)CMLGoe&LiI4BUFcpV@Dh-$s%WVxXa#MUMUA^j&A zrNPMa0+7y3W9TFWNflT$^vIEZa#=m<{wsBXX5T7CDTz3PLB%7{UXD@9(w%zLa=w?x z=Br~^!fGBo(an=zRiO=>yS?GChcho=uBEqvT{+GMb<>Tv!N0#ih$vJzI{!djFI6e_3R5wfph+EtNwrj#mgf_qq2|1%uO9dkx4LQ^oW z!4d{d{R>t?NiQVf=wiO`U&a^*lYWTnK{Nb{wXF(R5jC08!9A~3h@WlW`v7~N!0mtG z?COaL%y9MD4bAMmN^@%__s%A5e3`lv$EgHpqnc^%@-yX6la}OjGsR6}a6hM6IaxY< zHTQ+`5y;bc@dZ#@R?Js%(mgQTbdcmX1)LX_Xn2ZaeQ(k(nq^yqa>#pIft8=8PkUUS z;$Bi(yIoTILsL<1NH|@h$_{x`{&Y8ci_?i| z9LrLfsy3a=x;c0HyKtuRsr##F=r5+9@^gKjx-6He zN?|i|uG?{~zZ1t|O~_x%uw);q@GIqlQ0Bp`$SkGXA5q>Crb{=DLP#3r$F7ZjAsIOU zLR91waE;}WXxt}A2zIhdNaBOg!C%RE3hD8q(t%j+H>ZViu97QsXEbrAbb+RTnY9J9 z^U`3XUiLD+mHG>4MRiF9U9YxF*nQqeQ6zCj-1sOS&{2^%7dk5}3B` zhiu5&8uFM1fTD4dc}9mkb7jP?OyVS=8+l)TZI>IyhM*zEyEd?`P%+m4PSCu1(l*v` zAD0`3sQ$0yik8wpQTYw2+-K>xr*xOUmr{F<%U7WIsT}@}WI<`7B63(bS1*Kcj_qeI z&fy=HbFPo5Tt3d{M_46J-+Kca?DtlIaGb!M`U_XX#D16Ibj?n9PW>fU%RjiNK#V1k zW$r9qt>31CUlg6T<(C(m`3iDEO;_3DxJM~8{IZJk#qtw z*{@aBryS$Q+&D85yYA=|3vIUz1&`}CltFtdJ>f`VS%BSFsMYx3lE~kI)c)~gCeko{ zP*M}^%t&t4YnGE-1#@7W=oTd%k2Wzc{2qQ(cXnZm;B9ixNKeKI=1CvGkUKrLl7j8w z9ZUon%5+M!^vdO+SuGQysiA!zD*KIy-pzy02e z=h=9a4o+Vv(|28#aB3Vt>dzmkV$l*3Dpn3wP}acFaFU%Ryo9M3874>RKv`~FS1L+bcoj7yi^eZ(^`pg;CT8jQgn7w+`%)~XCD9{ zi3!>P_lR#q&mS=^OE7{HpKlIl3^)2g*JKwbL*(9ov%A9?c{$o-3v#kzLoTL`zgdld zmnl2S%XBb%Vh zF(Bo10G)B6XE0c%R5~nCs&)i4N>F8LJjKvaqBrVH&e2Ovxl2Ha41GREY90ujVW?z> zHv#;O4Aa+o9lCQ$I}@W_z_-p`lVV?R{Uz_?^I;$6qTioDhiD%;gKowE8choc-2=`; zpIIhCRy%}C;f!KumuQe2_Qt)=1kFydVuL6~ku5CflU9b|dMqhF)7t}%4L@i{4^5u1oAphVsei}NY=3ic6wU4IGfYC z#WWPV7|6jX99bo^{!PWi(eGd~BIfM*S0Wo~C*+XnxDDxbEo07%nDotkYItp1(ZL^# zq9%9W&(m_te`MW)ZY(Muj*)3O%&GlqU33c1`+4PvD@Sc2TDVbI=iFv~NFw=U2S+QuUGzV5}x()8Dx{fyqc2=|r@dXGWAGl6G ziOCS7ll%?P>Us@VLapPKe=GDZRmJZ%$uuGS;;z$CE_XhzZ{jb17kCa!V8uudm%kef zKc49jm%L9p(ZOUez|HRnMZf6|owzez;$fR4MY_udD3h@kVK-l6rRstob96kxJjhTS zXDHYT3WFrvxXz!h6oI{7apkEs=jCetB{`~~91!;gydygT2=4(be!_5$p&JN@NBrh( zv~G)1amJBAZ%i$-YRg>fZsCvidEq*v$)H8kK^3za{ce!aJ^#L?eDpFMb)@+% zY!`Iw>7B!=qz5SLU(s>u_X!`rv|xh@p0G5-s-G79y|J_s=oX$b+LqiJQG0@OIC{s| zq1n6Ma7c?*brBzgyGU=Ki}d#{yI6?125Z>Jc81)V;!H3qP0?7rb)KEp7W8VvBZH@s zqq7*ax4;wc&3QWVfwH9y!9dtRzLlV_xgGjETTt#!_&wLOpb9E4jeOvHBU)Zw4pIu0 zHYHH=@`qx8gs>JhSzBlx9PAxDixwgr!NRWt=*(xIwOT)Jv^EZ29m15Ysai~Z`0W~* zJ20EtO2zqng`V2I4xnOumXd-1)*k9BS*()hS>U9@QPQD9z8i%A&rITF51rF5Qj%c9 z3%Yc(@?*O=eNcR21!N0O8<_!LSf#KvT8*1_;LIa#ST#*NdK7Ii(W0L;pN=TlCakeD zQjrZzDoRpeF+W9@7V33Nwde9y=8M-s4l8)3>Nnzncwr7|n4>+KCpSG^t9XAkMNVLe zi}H==MDxw#-R+~+QSCxK!HSfpUP_GyFd;dX2U1W9^-fJe}9`F|QW%@=q(@3#f4`AhwNMWN4 z4=@3ywis{*vp1w&s1ea;EwBJkqNs(|Li8EEQ3Z;dIcy#s??)AJ!-7G~F!RFRU0{p{ z7sgxhz)O*%FC8uZ@t1il>W-6m)J-o3s=7~O_26uHmGsx(oamRfSQ!Cq9Bl3Vv^(qM zXviOEel+-kDVl-n$0pSfl|u73V#>E6bte zj&gE8wWl)v9bOBeHVSsPvX&K6PRw>>x}orSn|=hSs;nyp$0u?cJ-pbJBl=XbE<*jg z<;tkKFs5PM8E}q#{fVeF@RI4!o^4b(B9U?#@6%1F4GPq#uE;o4m5IxdF-lJ-c>SaF zyI5BZm@Yss@eXLr4MPDs3Q)FsIB{cGH8v}OrhB@->KiT$`Xc!H;gGw>La+^*q=>?o>dfhG>5L_uAJAsmjXRJ$6Kc-9~#-qVH zG<`~H4=rK_d>0d@h(QNR3DD-oK&PJ1j46sFOWnBYR4)_r-j9{5vWwsbPEogq0s8t^ zhB)AaIKT*eICs?3f68o4Uwir43>T1x8+}Anx;1fVG}<;5iABAC=tJ zDJN)yQxLkb>6yjBSyw2xQ^iSl#X!wXYmEPRt$RCndm@J zFQW`7?0qIGs&E}4pqzfj=p4q3y^x-Tez3%1JjgBq=z4@E)@i4vhzQ=*t-%1U`kE=a z&PonfldUx~ORKilwfSV5dHPtYt0V3eJm&(=JB@<_TD3peyJIhV5v8%X=cVK zN+Wlp^#>t7H=NdefWn}@RRHU=05Es&6VJpBD4)VUSl*9n`u&^km8=Y>D$;l&rl{$~ z+YZH4*L$E0u&y;8+4$2g{Am~dvPpW7? ziQi>tY=XWWq}4d-rHC;f!&l(p@> zN{7M@3u-GLCBuH)NtE3_?5b)v!aTC-6MIJ>N3ScxZdy&YAboX8(-Tz%BqB6S>s=)M ztL3N}qd!dV9Q9#ssPK-sCf*ywjADZe38P28KpIzw4@@I58M4lb67Q%7WOt5mDa3X< zQHos~ji2mTC`>#_io# z?Dqsv2ORMtYRUDhb}E_QO~gO~Ik}%mGj}vuhgAdLrpebz+>H1Nmb*jCG1|vRE&ZpBH8Em2yc$!FeJ~br=1y6oo1A%T-20rITnO z4R#zFJaWR;U>+49Bh2p*BGLhrRDose@g`xfA9mm}2VFjE<*7DD^43ANCql<0$nqJI zf=}KC3f#-YIXhKSXlLW&bMA-l#i)33ldEVMa&Q z9*-)_q^@I1>#5AW_z-hRQp}Tj;f#3UgGH<*-Yn5l7(h6rE?_F`Sb@o4CX5U!gKrfM z^!I5_-qAtAcY}&mY7x;0h`RIEEmO^Kik`A~V;9(++)YGsQhQ03hGJp=E7-jN1iP55;k}$K1cGJ;0 zNnUOlmO8Us_N(m^nG6o)c-GpHl&!P2=_G|Zy$jXVzUmE9w0$)rvLWE35BCnIf*Z`x1;x#-1({f~`MS|*=sNz`)~ z5Xw${PP5dbysr~>FxHT^$wmCPiAKWsOr@1G!|9D-c86(}_1b+}vE6*`zJW;ng+b?f z1P!y-Dg`J4PA910NQXl*054Qft2qc{65y}>Pxw-j_QFEg>xyqtFDQhOQ^HqhGpML zvX;dfAi&$chW3uNu#``k+E5PU;373C-m7f6M)X&W^J62{*A`W|hY!nTdb3=74{Ud# z+D-IUvvu=1n&Lk?u)$8IQ0DeYQ3;VhPp&5wp%;qf657gz#r}l8HzZ|B#9#E%X*j=B z9D0+5otOt_>80{5a-D+snV}5TjD8$e!c#Ev(P_t>ICygL=B*R_qbR8iIMgJUhMKi(jeazgU;fDNq#;#`WoY?w>PL8&_`1d-j zueJigaFmWy%D{;Sb#s@40yk-2z1vb2zOg*=7$U*iqP~;RK%GrT&3<&KuC?!QsfQMm;#7>1jZ5t3q*xbm5&R1N6lwZ^8z&!o>hSk%7L+zv_p8Ug-4s9)svu zGe2!tmIoeoj1C4ZnJ+p!=~C7Pqv(V+pKsKErekWVp7;SKe2+ALxgxrzCQ^xN$?Yu-M3uelsI zUKzoEzYz*{}Tt{jsjx*Fv*rijaksa<|LtI!9VzU!~+ zM`4CiRWA-M#rE`L;7xlH&XIZZ-uOML(v`vthJH7krxlP=Xo7mf19qs_;f!=Q@A;ke zzRJSPpFK*_irn>?VcI6_cem)c^f&Hu{$zfm&fefueM98_eS159XNKkyP{8o>_CPy< z-r13BgXmC8^HI4_Q#zBbv8E9-?U+hoXq_eACeL7G!nG)h?F_Z>vyF>6lMJ1^TzTo} z6xH30VY~f!jAmOZ{!JJ}{JqPIy62=M%ov$RT`&YHb2NBAIKTT z;}4=$q0TLQCM)<$BHoPgZ#o$dCv0=U@pH*OLoKqt@Zk7JO>>PmjMtdkFvW|IgmDcDHRK+ppoTKozH=x)Sy9 zt97HCm1R2SsV(`6vK=?g<)J0Y(ncb+B<086?Edzh84UQ4WINfmY3`o5sZD|dU@*V{ z17IHg*6DK6o0H=*-_bs#mP zwumw!Q)*ohDgy(Ll`lO1W)cQI+1K2-;lxEP38v(UY1^&WCO0gL)Y@EZo5~hMj2Kf> zDEbMY7@`4GTB9+@jb(F>eA8LgJWBy1rys|Y5Y)fa#rgw1FaJpPOcbV4b$_P9k%Q^q zeEs=if2PB$O5NBp8dVtZ;n2b0T=!Ku9Qcm|6Uq(Rjg9}qI%@E_(s$|2LTo!`-DP#69z&27~E6emmBy01bP67D^)@U6s}Tl z9>?)~uUfsmy)|4y)(FDu>QsV7)nlt|c5Jf(2y=!rpTY%(-rpCb9f!V$q+v78(Np&p zXJ7X^^rXHHMw<*LsDM%yQ80>cU1_U5oZ#uv6-8W0>7~#^)B6kn8d&(E(6WVP7sP(c zwrsLOxUl+1F#C&(RAS>2`R~+;u8!Sd>CUE#xJ9a+Su|CeJ}e8Lh1!H5PNeI@Qd#I|j^gxtXC2&Ep<;C! z>Vq1BO5i}r<;uw@Q9Od5#BMEqD;TC|(f9Rrsv5D%Z*z4nS1Gp?1wTkDpeXJ!>Az+? z83S$wnJ1BWas{d?^Iw-gKk!x3Xl);!ukXa0b-kD*>JfG02xNZf$D3?NMr%4!A7SE6 zX-zMle?&K)FA;SehASv$&`LV;fj&Ebpwl`*rnpb*weu&s?fmh6TcJwwUClCVO@MRg zzB_mi>%=fhaGXrhK?p5(W6yqiHlt?0nJT3lay;VG;Pu;!JHYO2E!IPywBF>wAt5Pd751#1ZZkB=w( za%G>=2_KhtZHFvp{e;e0&YJ6}glp2C!oB4onv~~^^D~a9?be~`9QI68zvIwUXd{I$ z-zKj6=*;)7^pm)2V#-hd6dZU8<4#c(zjz@A<4j$IXKMJx>~$R*rpI<4iv>jR5A52U}-#UO(M9 zY!u{2r{Jgwps#OLHvFM0#;y#iI-1-Gm}^m-mF|?pWazmRA~8s}ARd~@$avaha&=2G z{56xQ0J8c3=4n0dH zOa!!1xRp+36k^;Y+ALgn%8^03OH2LB%Tj6YMdn2#?^Yt8ct2@Pqo53Fgp!POi)En6 zK30`$fHPMP2Po`&ID&#me;#{+`~tY|Ie;GnvQ-A5NfLP>a9DfN?)iL#eU+;+ay{gG4>cp?UyXAptuCm?v0;2kzLF|YV+Kg zGOa{ua1U9I08vi>J=&;aT6e^?6C#KKfK@?0_TN{rwhBhEsi6F!X|_AN%DU5Bpi@kM z5p`p`%r4USPK{lX##Hg+bpc!XfL4Uxfh)E(tq+3YeCR6aR@Rra5x~kUC3y^2!J?zF zkSnM3gEWaW>BTERM^j(w{ZEGfaW#N;{GR;3yZa#jZ*6Yv0{?F}YV}6F-l!q}?`-aV z<^Ml#{l_B<;0#!i_Jn13D?j|O{bQvL$^CIK1M$4$Uf-ALEUE&%R@1aXp`f9!I=_L6CVhu|K9jMd%t7XOgHaw}%*`OggvHW>Dvd{m7Qd^)6jQ#CTCM4}%-nzYXOs zEzX6lPdsKt8fKb#$nAAQDZ?=?nn`0e1E)+^gWmBkrclFkFWHAfDi!g!V9` zFcFM0)k#D894;vTPuz8 z4YVViVSKU)dXq~Com|0X8vu>kG*%*JxC`jOFuC7TVe3$r!5;=83LJfMDM(4xSI(3tldOTCNR3QK0SP5}F_?ZhTK&gLZ*~0D~_AgpJ6Naof?RC$s z1M@)aUyA;bDOzX!qi!#`XKQs1==RKfbJ{a)yjs(&lhb1hGNc!7Wnp#N$7cs1N0!C@ zSs(psh-2%-LOrs6w@d|dHZ6NkcPLKGUi%1MTl?0r)xV_r4y}F%>pBEHTH>_T>s#%! z<5o|cp7l<85kL_5jBP<# z9Z6$#`ev_pc8WKgCGDttVdCj|y9HSfh=$z`H5KU4?OkG_NCP5qSzH{MklsVGL96<` z77_!`ncDp<7}VGA_WB}iqv)8gkFD2cr)}cbE|zj(*=7lP#KK(!kd&&uXhEH4)MV@l zz)C)5#$K8FOIU}Zb#QJW+7eiU9=0tW4Mei`5tG}X*;8$~0(8TFA8D|ofj`FByW^9I zm$kb_Z4;K3(Vht139yt!IZWvr=>miwzPOIWDNWwM1ptRztecA3_v<{1O zj1w8Gh_t6Yi^Kapu6`cf4}zcQw=r5wr+P_yChzC>FqWaFL5JATJIw;fM@IcenD$L* zC#BpKfKWD!wqts3*PF$=qSkKEpTX@=G_hI`72z4m{aXNdP}1Cu#|FM?z($A7BFG*^ zxy{q>V9WN5&wlQ-RjRzI-EGo>I|4YBd9$cJ%VbaT8?>r7Xx9CRw@I7MhQk58NAYII}zEO|8Muztddp`*XR+hJMo z7%dBlGBoU~qSvR$|8zAOdX7BtamHJ)qxs|H|JrtKY5x!NT)p;H{{Kw!Kg#~m7!?k< z-=$L<&-X%CI=hwXH!45`ZnJ5yuomncNQWqKMz|-3Qs|qeT?12!!vFGtUIB&PDm=T3 zXmWZA3*#AE`LS)eU-XW)W%Ww#H><%PB0yQL~#I>7N+wt5M`KO(|{Qq8ZONx zP6V#^e3CSx=7v5PW|>}m_Z^89!VnedjZRc(3t9Z$csm%s!&`#JtMBUMP;N4(Qb7Fp zKlZ3b@6C-my~4JT-y8B4!i~iS!-x;-j?ZZdsoa2&lHVocjKX{90Xl)hW)`7{XV0>k zT8lWqlg|Me2&ANO<5k$#DdD)Rb@vDGxfp$@j-k$K?7P?Zl89<5`|#oVQ*(X*neM4v z>*nAOpOWb#Dyb%_Fz}OkseWv>?~})m&2nHKw$6_G&L?NIyJx+&x%D5R`SGPAlT z_(YZusWJ@wWZxw5X~ZFDRCSWpb7LT-`f%9~XINKemHJQ!{Pap}D7Mr7Noy#r5ji#; zH8)1`Mh!U|rhqFq@`%YdMkV?X*PGRNHm`0FgaLDgv9Te)G;&{j?^bV1bJYjlCgPs>w)^dVk4Q+eiFlg?>y6{ zL&LOTfSSMmh3o&shsAL^{cWrN)AD~~b^Wi`x4y3bpLzXIHsjz)Pc` zX}FYc@b}C*UP=Y*dEJQb;w)g}0l)?UDrTI&tvB9L%GbU47sLPFor`LGQ5B7n(dHZ7 z7{tc>{*U1QdVQx+!~4I@on4pM)3+3dg$4_%%j5UOp{QT1Bq%RV||>qmjId{)5|fyx_ts zD~!#FcSwv5F4How<#P#26|zd^FjZNSM!&aiq|`Ns2DPzIilBS&WK>h&U*Ww{$(2QE zMU}`cY8q>}W`${>sBsX*&6oK5Rgvm#NtFt3>Rtu7SrDB0b7BH-(DtzT5`VuEg-Rug z#!dKNR3_pjxx{|&-P88(RRMs}QfW8|n^iolt;RtWUSwB`)*Au*m-^8*K^%1)LBurTQIG>d= zA=yL7xh1b@WpLR*-f(m6NIAfdu;=Supwv{_qD#+gk+hWIds&Z*b_e8=t{4g2f2MdD z$$Ws3w&)JukGX^(RHGZ^X^c0hf}lkS@1j&4ddLX!w1F?=mBLM?o)%6y(Bk)QNQynA zM?Ya~)6OhYevH6yVD+A~xzABY7Ntu!0N8tK{vlI8a-kpIcp*6{GFYXOJ6&NN4}?IY2I9cMHyYG=0DgO?6&XO6lQK%nQlKK1BOTsClR78PhTK$Qu~PDkkqco_vl5+`TI zpfq7w1zo{8joX1W`~IYCk7YQc=0JIfc00% z3g7`W4^ytEaN!A-vZoOH>L>`RS8iBM!{|sYm5=E=Dj>dc|3QrI%V#W2_F@i{Sdv1e zX1g0(t5C?(yv#?ANJ@D~h@B~I0~BG2GD)Smu9V%F#X}ZrC`OPJLRLYh0WQNoN{tzl zQ!V8TQ1M0d*B239MeCBwFr7842Q$1}FG{AVRDj{Hup2Ak6y9J$23ezmaV;ZS#>qgZ z;)%kGsDQDdUPOB@qAHf04GfiMZ-vMbbIVbW_RGnfWt;|c&({H^vRulfPP2dvus}Dn zfYzz`m;=yw=!M~O23e&JMV0XazXWy9QGs)|@KJFL&!U);b3Ya!w_$I5=XI!qIKDTIVQ1`;gPj(JSj<~T=54n1r2ccSEYXhO0-Ew^!hGH#u4^J z#z=um#ovDsMfi_?OPveqvH(p$vcE5uBUo!h&$2}sZ&K7Sr2u{ys*i`=0{#6!VFh~F z6EBb|;%y*><#*yGzP}Q0vDxor_mP-_`XgBpMW_7SDH6hfWyuMc_h{cyER)dQETBL# zm`+eqqh*QLFLx?NQ};S5JZxw|qE8d@mmaQ(BpFo|4_+EdQkgLn)+ttrPBfmZ2}Ptw zs>1P=RFw+m=^o(83Q!(rLm?P z(UO}?a5#}iLidbo19y*Psgx`TTs)ME>p`(vTs8+1=%9M;4G~lhfEjSxAnbu`I%CYL3>m)ZJA;;jiOE)MLkUl#S}T= z8)Po6Q_1QJDHWm%m@ne|SDxra)f4xn$8KD1~SX?w5SV@A1;Of^H6b$<2lVO89Qu7I!sN^sfWbZb_FqikRZxg4j{!vmTNDxrGM8xxNmT;+5IDHkX zzb__(_iNCvROriU2DG_IVew6-k=b1S10`wN0G3%l{X(ytC;uf$(lihj)LHXhdRm@9 zW5)aVnJ@%=r_Lxrb`V<;wSB_d3&zf3x@R4Q(7* zgE&0@u0BOajvq<3Bm=gSXGxT2Fvt!Y47`AISjIh-*c;LSGNRl zvNO9TF-YBYJymtisdJ^TFa-B$kDuaZf4seo-WI!EYvwYu&X<3!(5r1UjnE)XmW%0C zI#FJM*5Oe&Ru@JjTlsJ8XKs~BMIqr_V@695Xx2vEfmYYU|HU8&H|M;v^z3N}a+1)s6fB7Yv5meAn@7r&?N3Sc`!*xnACpYNJhhZN$|BVX1oQ$LD zm%7<%^v|fb1YFt23wLX<)q)2p8Qj(W*ZHfxH)kh5{&ad#gQv<0@2|Q9n&d_GIKIp> zOaeP!{4-85bK*Z^H2nK#j0gfAP5OZbR+rR){{$#G^da!Wrl7C=N>s`UHIY&)u& zhckG<20;z9n9`s?^fj2ydrGItX}#fAn_!d@)M)@GdO1qRcyD{1_NVh?bE|UJJ$c)i zKx+{IGHP8Wfa{~yN2^^IPTxk)`swYn$rA9Tm^7IY+@Jq*k;Wf&{x_e$%-R2Z^*R3Q zpKt%u`QLKCjlSIY-#{H{lb@ywQexjt-|Eh(&gQ1Pf|^hpYE(I-1Tn?(2jY zyLJ_?#^+EDB`Vc+HM;nQ-d6q_H-AWu%iE;3V$Jz*ayz|2#Wkj{XX#B%Y>{hUknWE- zM(up8twyS<&DL)8t*$~1ebuuyZVpg|DJ!n>Er*G zUw!uf__Oi<@k#eb#Bm-Oz}tP`(hvL$n-lzxqgSVJ>&N(pnMw#12yTj(!#lVfk1>7$ zoY0;9pG9kWouDpg4oCsDQpjmxvw+*h7>zrqq#w!n0l&c&s~>5c9R2g3sB&FIo0TtN zu-3h(`sH7%)?2hqRg?UT4oc2HlI7pY^WDe)>#L0oFaFb4FSb7WfBu>0|1v=gfY-2A z%6~p0%l2j6pn?XSI$$o^?Fz?l74I+HEo|~#5oX{~)VhLeo#q8dB#(j~xF9~MRw!n! z^$aeO&)}*?Au#dtf)a%BM@nJOAK?ase__WGJs19Ek+S#ckW59g=u2v}${rkjViD1)e0|=8CyjHLBKxZ;#=((k^1yffBH&3J#TO5Pn%WRBs1D1su{gc=IH|VKa(h6 zZ;_19;Mi28soi+?ahvZHjvk)aAeI0Q^L()j#WGQAxwJ7dja;hsd=XM z=!{E4OB})>AF?ZY&^|0{P%-ViEoqf#y}YGj<6Tz6(zJ5xWWzI=k6Tb|`LT5cGlsQo zUG;ha5F7A*Q2^iF-A=f%+>vzW9p%ibeT(WE+=rm)nmLO9@gMFP)p(3Yy=yl&r^S|% zskPvQaR`AC82=^dKdd|Zlzy5(kgMW9KL6U&|80J~@$z&0w?E~_a^ql;FP`}tZG#%> z&B&6Tc0KJ6CBCHii{t|e2w}3wqBO~dXn%Eihy1)UGsd(F5<5EM;L#H5TI|K?(ok7q z_v8+N#Rsb7X7lOa(jI0~L}N_Mx--2@?@~ZYm9wM0qwUIn z%S>3y55t>bo3=Bh{~1pD>Bsi$diLxmpyZ$V|I+gxlaM@)AMEi#v#7I&l69b!TQgu-mYhDI2j z2%Et;cWh^+9t+bC?RH_y;lG0`wvh5+Q5Vq z4Hb$6`FAJX`1Srl7bDR(Rgjuy^yCTVc+&R!uqn-5#Mz~2{MpG_ zf=W9wG#IamPyeQS*ge@fJ36V?_7Ab=m`&QTZn>c&@=9!#ZjM=b4e{*hsCl8OJDi=` zYST-)4l8Jsmc~&)Spipt@JO3}?;`L&F4``jp{)DhGY9ua(tolD8TR5{@Aq(kE9n38 z7h5^|&##_;*8lt|KN9teBo-zZmgLix<&SoC84T~2Wb6c)!Oaf$1)BwtPRNR3tDIKV zvve|&9hub>uydmz{i2*EiUWa>ihHe4+uQTn?r!a3 zo8QPc=3hn_vKPK`T3l{~!u4`l`;k>mD0r`D7o#DH$3?wHQv$r(!CH-6Evk?#l2P57 zw)V3i>7~>%9rVWicrm4X^7USi-^yenEYmYj;=`S{U4pJ^zUD*JbQ`k_AtukCLdaT; zpPuZ-ud!3}gVf$CarWjcU*f#hqIGUf@wb2y%O4-3t}s45vui+$t$ifBkD^67o{h+B z9nVW&6qoFRi!?n`tmSApxk=|Xu%Y>b{lgz(UVr-fVsX3{l z2m7zQ38_hqiYGN1US?JU1yDICZGZtHjhvqCobB)WV^O2Xm2x^%U75-6bzfru@myPb zSc;wTv9%-IeE#II+)txs>pH?eSV5Qn9>@1~=j4a(iQDe0{vB{?xOX4r=3|$qvKSAV zwmEMFIf!cT@->DTo^?+Sr62NJ)Kxr#OVwv~4NqXpygt}@bE*eOi~hrG$UA!Pcpo>C zTLrh8U5To^G5d{6xg(-6!Q;nSJDZx3(cExkrVD!HcSBt$P+SBG+r8J~#{e^kJJ#V8It~X$ z)PitQyw`p84sc!v@Y0n{YWeL+_n^CT+U560TXq3Oh&v(1qQkrdk=+7LqQmS%Av0iq z>6CE-odWvbIrqC)bhhJ?SDUbQT$<|A=gum!?A1Q8Um$UvBk^w*((I0q>O7&A`c7S! zE_co^N~o~Z*F;zfzJ7Obz=iFSUZEUm?$oSNc+?kxK0spI)I_(4=3-GM>4hY>qe$(D zS&SmOicQ(`GwtOGYsVt0aAw-Ma|1Ls_e?HZXGwPRCY`8bIY`MP1P(47!+GVe@*OT0 z0yE@2dNe1vEc}&9)oTg*f5%8}@wNJPNunt8WP15Ge$t@Rje|hyjLAqS%|(`u_;5=u z5M(telM?#nUe8*~kDHs~mWy5Cq*4IJVoo)i$XWosM~NTwiI*|s%nmP%sB=UCCh!?z zkG2N7E^xUV7|E}a{(htwSLnLu%2hwM$@wHhQ^-0TmRchxRGn=>b05#QwlDlQf+duo zaF`{RS$(#ZZ-P9>sg><5O05AiZlm-toA)M|=}zSeQPXNbp(djv3^WO%al`NRZ3cF-NI9J5tmGaV$j!DL2eYV zg`CC9$?)$>;9V3ehhh_)Nu#o+Ad|M1zl(So&=MTLtc6rKpKCr zgAYi)AZ2CQdGbQ{o_O}E-F+aDv!RK2tRbE8f1W+{@{ zUF}MYeGbZ*-DFie#&k29L%Y*)(}1)>=}L)<{{Jo0rRK2dOGP*?E5odm{d>M_kh$0V zI~*@Gx{^ZOpLe?y;s}`klbzG=yL-*(?at4*G|gz|^oRIh2XJUJI{jh)_!wW}hxl!` zi3xLeyQim>%A1{IK&6{6D-{ZFKf-XFdRFZ-`qai?(8z_s-})1@Ey@{XIZUmzlq+g; zpY3qJN!9C@a_HXy&aMAFB%UU(f8#Z*qXV=r|P5p^{kB5`NwBBe` zLeoI&LzoPPcS^F11aSz}CB9CjJ9xX0Ms2#*Cf`9F%K0vmi}IlrbCO&fR&g zu?%Efy2y`~@DJLpF2W;}!&lMpF~#hKRrO}mY+-@S0viM5r)1#W%Qy;Xmigs1nDd>i z0p$`%JF8t>L7@?A6Uw_U^vmt?<*5YLMo#B(GDml>k$W;#aO0aaoe7oUqbhg{Q(R;! z3_FGck^tdbGD8{8WxyPc+dNRpf20%c zH`g#9c8uJ8=WLxUHvwpX=y83c;Q^0Qb|6r7tL&S|;Z^3-{;~&ygwZEnMFTk?DeB^f z!NuXaf}y3SbFTuD5h(i_SfUil)8WA(>l_3TmC(D>tUg)Q=#6`oF5*f0abeUz z{8Pm&7jq2CPyE+71rkeP$Ftsb+Fy<=&WODQFe&-4w;W;c|9Kyy%Xr!re`B~vMXbTK z_|JOgR|M=i(~Cl68L%n(&B@_2)cF%nMA4inWhBs%3a+?wE2X3@Cg`L{NG%N_&cwvLl$)+x%80p?dh zI^Tme7%WGP94415X=#8Ea>GN|tB@Nue3y=lhx$@)4VM7lg zJTe$vV?r$KGrek?X_6Uq_JV@jp`%rX0Bi;Yvkt*dg<*U^_wI~MLU3evbSP9>CjZ9? zcj2O-EG_DCGF8WrB04wC1If15>tM~)^Tya-@!0oqq^%3j~G=kD%w4&ux z>}PJsME$uDk-I%?2duS(_W)%WB|M^tmE&}qX|X<^6N=V*$D+#M*Z=~2A?ZYQcRo#v z(iN;e)3)MMyasGo`X>0fQVHaw&|*9LMrd_EPiJruBX?GhH{ob{DaGf+>1#f5WSLj_?-XwUnu^=tmlP)Kh~l6RpDN}9hD5``!joTr6R-Z>O$=kjGEu$80msmm;mcn+ z2-$D7MiX9if9~$a_FGD}q>FqGDe*t1@M;?7*n?Bc3~`rM>r=aR>PEP z6OwFrlN$`@z!_31zrt2jKQM6rBE8-XPc6|ndI~e-`Q^>wt!vz$5$=P~((w;(VvamP zVJA*G;>WDVIoja#O_t*h%2}G2W@w&JvapUNcma&0($Y|p93ZVR(^idLYhn$DDb8@% zU;YZca;JOyC%-u_QLWPb`FQ7W4|nqZ&MO=fzH4Z#F~Fr4+*(&7Z8%uO4AoPasURK$ zg#+8OUaf(N^PXCj(0Kq}RLhiax+UW`5e$051ucbYQQQ*^leI&isPHG9djvl*0Z=-F zr)z{gF>~$sGr?Kl{RZwj%VZSyQ{1NMq<2>*O*uk=?7!gd*-v|;WS-Us4bsUG5>WKx z!h%g(;-*;ATNF`{RV({m9UaE|ho@&d2M6AIh_}Y8n93oxv1*;30YG&T*mPwpn`^07 zvqys`B2?peXZMGlH{JNhE@0lHL!utbvExKT^zJ;eD5pm%b+5JP!tVn?qty(I(l6Y_ z5WvVm#zWJTwQHibX(8!Z@dce?++o4kG(J+mYl8Qv@-Oa7T+aW~@8^H4|HmdqfCK)2 zKV72jY>DrEF&N zh?qt^wv4J(1$?4ohO*)B5Gf_4poULqn4s?y+9gD85!2#3#59W$XU6lC`~mg#p(%wa zN$zAiPFa3|#e!+li|#yEQpjOE9e4JNrGKlmNIw^VrWZaF5-95F=p zTpn{QU%)cT`vhuG1Ctaba+tMV-T;;WMh>$mBjV}N+12Sh72vYxZklDf0LU&vZ&*t6 zE=h!*iyKt-9B_)N<{+6mHOD+zZ#g%qk{{8;m?Kuh;}s+m=@BQo7u+emnY379f9O<3 znL({h{%QQEMlQ>j!09MYoM|r^VeY(fAO4b0N;I8}G<^DOCHC%g|L{$G`pfBA_ig;c z$*Y%2>z;{Gpt>Q#oP=XJ?ViEi+pkx(?hM{wpYmwi&m`H>Ga1!0jQif3j$^pbuV9>u zYTwK+Up}zv6>OK;@cxx!+KFq_!`S$us16Pw$tIh)UJA?}h-(gr&-Px~&fxV$|1vf^ z9lwqGw8!~NZ#JWx;^dodQ7=AvH7HVRlq{FkM8Np7Xn7^8gUXq<{@l7hb`Q_o=}|@x zdxreLOp?E^nkSVipQ_W)eP_$HBl;6K2fKk`%aYG zUw5L%zz8|hoB`&wCP`oQ6zSWF31XSj>Di6kb8^(Sn%W~xY%?+ z!0+@qk?7MG4viPXQ*>^Tbl?_W1vmSXos(a9Z{Y2_8HN2fiun$kaWWDl)o{4Y5~fHh z8dgXiIK#I2tWP;=Y4_fP_Sv@p2a95GI@6zi)TZfs4_sF@W7m(I;d8e3Pd|2P_ud2N zdS=x8-5K)nFK6E$9e(;DOS|_TGS@Rh=I@_Fw|tKO;>iEvi@Sk;Xn5O{c7v0 z&97df{{O}E&-(vAN&aUN^dRvjYXBtQnEIXa&Iv8o61=?3PCP%SlKi1*OYI~n1iCFY zqrrr9)@(XJ7^ytE*kuYs(ox1V&p~oubY-f@wSVsZNW@&FY81@Lm@|+|S5mrM7 z-PtI`EPBdlRkeo6xsW-L%Q{`+FH>M@DzN`!EEQ9qo#uq0$U&&{>$@?)_=cv`abKt&))x9Z$E9k|Lw~fEMM*YCR#&4ziZd4zt1*4;`5|6z*pbC z|M2v?#?$*YSGO8zywCot&h7ly>UOM(C{o$@_%r+z7q2#>Z;ee`l%dbeq?bnZ_waL` zwEjV3YJ4aCR#i*-IzS#)&eqwkIO_IE$}TNt6Hlg-)`#i54+k%qC%pyo)x!yGPAp3M zSGy*n>dyH#Zi`QTz4ioW`2I=FaTyq&w>B>@c-&~R9M?%+NRKFRUhGBa8RH$H_Wu24 z&23^M*TP0o15!VF8X4`L17q}dx8ZZXxUiN(c~cFqD*o2L1?V7a?OFpDsI{33!Q`4kXVigeecRnTdSKon z<0EnpWHGz_ZjxTH^fUBQ=iMx5Sh}65-StI{wM)75vh>=M7BfcXz>+2*#)IPaN`!+_nB2PTBT!vC;>r#>Mr4(^W zy)zb!DvBqYRx2AdC@$uBIpZ2>NvM+mI2Xq4Tn5urJqw^L;Gv1Mj|la^-|n34esB8V zq(RoiC|?g7P>ytSHux#dkpq4m(N5PGX5`L>w8!@;!9Ly{@9ms*w{xy?Ywb`cf`=E{ zpk8}T>1W9_PHkhFA)L7??lX7H`e4E}d{VEy;qVwx-`oCd#FVdVM|qHuT2QkVK|L*4 zh)2xDlTkkgOTnV_;%d5x9gl1GxOsi%A!-$J3wXwybQZI_@#S=cCY*Q%$UR}6j;FWe zlrIeVa)vp%0So?Zs;T$;$@_%{*0unvopbH*GQi_jH z_J4#EA0t9gKpRdz#SXd;9AKvUg%=4Zherr;K>ebnM|HU>9JC%Jq%XaRwtspex$hOD6zQfl=vlr{S%k@qCW&cau?O0p(MYmpB|DFKHPp&J8U zX=4;#)N7gw*P0$hZlY7ubl$1GI(XNuk!@}~oOEjK%OSGQi}v4_Lt?UNDIbXzqly+$ z);Oy;K$t6B|K@2+OGSjNW0vxoRhm>UXn+n#LG0XV=nN+cqqBfH1)`!itVrr+P7RmS z2r?O@$ij`qJY+^Bs&CO5#cyz4OdS_o#j=%?ipCMNNxtvy{-E8duxo9zpa}4GkWy(^ zS-m^@(=Yeu;O^&Q8KZTuf)#yk`T!502jOI5S6E$JODsXvs^n-h4P) zWY45ZJG)lFWATZwLBJ+Fdz`f}`XnG0=FfA`6(X)ALkcUcG(8soIkcozL3@n@xbUvT zp*m-U-s*7pmPLF+HKF-7XiLq-c}J{<>PTPaoFc%_N^O9R#W#zu9W#6b#=bIflp2o5 z$;`T1i;Etzev0#Is?e+`#$%G9?G(9w&ALRuJjs-d(J|^%2i$9e@4WaPZWDI2wz2Tj z_)3Z5wyS6cpCfTnmQFtQ>^V2mvvVm$@o{;g7C6WWA-?6kR39`ANm9X)G;ow?LxCwT zjHp(tKVf?qdy!jYUX}CuDe3~FZK+7jEme$YL7O+xHju((91XUk*HD}7K{>P)!kI=4 zAMBzs=W~@&gSdtE`&(cJ!l??~n+M10vWZWgViu zA&Iwfz9Qw-dj)RFfi8?lB04}J@N}RnsDAhwfU%{Pm!n}%skCJxdg<-PG5VGm58T2y zj9kZDaJ`Mg1>0G=5L=_V+D5>uonJJRk$Wa5ew1VjktIu{FD(M=sN1vIIZ&`;380NA zi9Dz^nC;VWOFqkh$6}E$=pB0F2#ZwFPHtr@#e$H5c;TP~^b54B~iV&>1&r#hvzvU0f}cm!ahZ2b>UbKgRK~ zVn~-kR~AmOY@Y_&x09t*7U+eB4m5j}_pDTMs*vc4Nwkkr(K$>?kei@t6aA4eM0(@t z=5`BTRGHgqT=*?$A0g*tDV}W|-h?NQW1is%t`=lsopx#;M0W1PV+oRYf7sR&agVZy zeSo8|%3E?D8rN_FcbPl;2=qqNEUl~Eh2?)d-96bqK4TLTjm$lU)NmarQs>_8YR`o|Yyo@N+O+V3o`O&<{w~~PgXyq6h!ED(ZKxAmF6uQW#+;U1IhUa5 z_T-aRCBlT7Q8lhM%#)|pCOxp-y-i2*={^mV=DAn9Ze?=&P7YtLlit3=f69weoWV{_ zn$1>Nh>IJjln&6R+zr}R3lilD?16i#4i_#`kPDb~IkS;Qs8Dasy zb_2XZJgZd3!wkc9#@A`m=MefFz_jw{0Y8;TY@@HeO$mmv6&hE`i)MaJey2WH( zb(8rBXh%PK8r3>zFqAFk^;>1~cFksV(-=+FCRZ{wSt*YNg?G0Y8Z1%o*^ZBF3@~)? zbPzpK{v0ImQ**oSLtE-I)iL?G+VnupPZ~BeQ^o1;xfQO29<+h#;Wb0iX{p{Y0+(yN zJ5gDyO&AUtGU(BM`#AfK?HR6Z>jf-WvDbh1=KSV(i+3z zSx)+tq{PG?8AOxiXe2rm3GxoA z74BuLsF$s9FI$xo$ZUo;Q1@_8w$D7xmZQa*J1E#mONBxl4#EZ8C0wyO3MRp2DT7Qg znAy&v4A>NO3*mtLJ6g3UE9e;+a5v5Ax9=oA_Kc_1j8uM!+NhL z-kjR4v(TfH#|_WqQcq;8vx0(OTM4)Wi-QlfMuRP4t?fLRCs!Cv08_KSpJ1fWaWb6L zaaT8@Uv(6(Z=&CbboLA5KH*X6s54ejMuK~HHVWPgq&f;>;ZkGRhnPF#PWE=VlybG~ z2(Sx^0au7e1OBP)TGVTH)u}qh9}IudLR>q!W1XBr-Z8>hR)Gz}hsPja;Y0hFL!y%3 z!8$N>>8>r^t+o}aO}{LZa_VliAZA%iuP8dldYEP;8bN8KVzTn+b|ie1Hfqo_?)8@A zC8ZTbLm1K-N{YBPTZ!OTP7OC$jyMN1<{DEG!xp+%8JKk>v>}_Upbu&_I!mZXWH8L@ z+FUHK&9U8@)t4uw%oVi08E&^fx8u?&b~tA=7NQLOdDHKO*9$RDPHyYiHLeX77Z4{-42D?Xl3I;&kqWB{fE5PqO z!WD$8jNs@ck%JX3#VS%EPNnVPJmFtaJG_?)-%f5sHsO&aPLig!gLiC&=GYr%4N`$y z?NqZac=k%Rm%kI&qZZ`4Re-Ryub4WhbR-J!p?fUWTQX~VbYz!U)6k#R#iT1?8SfwF zhZu&Q1=^LTROOO&d3_npI?xGE+5t=m6RGg3((r9=L!eb>$w_b_ppeq4ougt}M;sEA ztaGC}Mj7FO-XCW%mbrDcZe>Wy2yxjOOga0KkA z*ozjnfFjB9@E<8&LNV%ZyIoMUW`!g58W|2IxW13Gf&!F-@k#vg8^F1pI)7{Y$K&i9 zHD7ekZNU4Y4uA{}2L&&6VBx}HOML6wB36DabZ+6$q7vm8`W~o$1vXz7Pq{d%ppcw5 z{u4T{d)?gwh0ZC?FF+i%n`#OpO+9cY5uQaSpt4X1;Ox5on{<<=%C2!}jLks-L~UKXKd`tuP- zaY$gN?&FNAhwC~-Er(%Om^-hvPwu(*in%iz0Z#|QtgRfQyG?`gnl+JTF&?v#5g?}( z2<6YfCMzHp)iJ9S+NhVp@E(ZgkHakaOHL^xWbn`HcZa*OlZl}OxUoRM+)N5|R~GqK zK{+h7jD4~Yd;^z~+oLm57*87%x_1l=D?qYe%fS-AZ+n>w*W9%d!;A$QXmr$9Nj9`r z6fT6ofnD7dw@|$Gv3cQd@MaVbfSHKnLW0gjAJ>Qgc(DI=|LipWzHIDT?=}KPp~_NSJw+le9jgstE&9o zo5%exAZl02Z6f}N>E`4zk-JNchfllT?p<#O-=F=< z?_}Crc}i(Zqv}4{#FzN25vH9UyF2)VQ2f2K4f48!Mu49{;{ctLxKt#B{E#bNdmvAw z?qWJ%S;_5Zu&zKYz^&mgEey+vk$#VK>~#Nsc8^{=cheG4V{blO4B=F;)q2k17f={t zAy(2`QtVZizuQ;~hU8vaG#6!S6BkLCyyj{=KmWp5ARpI0ScFR_w7m8DW;5DqMlYJt ze>S7dubR>Gtwxc?V)e~QBI+YEfm*gWna`8E^UbIgZADL_FY5LBXo^M(fPm{bjOn2M zIBPT-(YKxGaldi#jS|J+%f^b!g#tuTG0WiYciv|1fh%1(9{T3Vo_S1J#2)vn_6!>Z z_5vbT*E8hO1s9}X;3L=9&qJVUqZh`6sP0aeqdt0(_fudY$GF|pL~5|xNFdqp{A1h% zaQ3;(OL!07S?99kP=-z+88Y%QR8pd6T%`a%g%4oqL9-8;jCRdaw%%!}QIgd`z54j^ zvf7O5%LzsfNc#;s4~3WYHFmz@Sc=#Mt{DS}3X7~bIBOi5H4lt?SoFGzz&mHTh3*N${DvDtG3eYq)1O8HZ2$(Purx_9!2fE zk&FvwpTHOMqt+hC8z<*VPbaZ>*l-W1SMDvs0$fCRXo-zLR*XI={+|KinJ*{CCo*V% z#j2L=V%w-yO8636lupiop;9R`^irl&g~kT?_VPknX~gJ`WJ}r6^yxvQ>^1#Z`|9mR zMaiWyWj%t)o7rw$MqhWPgnQL8PjKwE@L!ZO-m)%9Xuu`W+_1|gTXNC52Hk{nt?OWL z`ReyngfTj>Mf#G0#>CX;2RZ=Pt5h~A8w$S_C` z9eo`28WCV+4B3N$LM5OITxrEZ6tfyc7;Ov#*{Vr#$9}d1Jz_#n7FpKlth&1!qjy)8 ze95a6iuvb{oI%&F0gqc`_D+!iIU)rZ7kR{uY(om>Q$WKB3xHj~Y$^ z<$9nR_Xc)8(n)?PJ_<77{PM!y*SZxS)*2DJ_#wtvXbLB=H|Orj(dlWtbMof2E;`3X z0di55&o7FF*i?OmHK_Wq!X8HcmYUSW;u%}Y-D~2Cad_3|RaT;9MxwGaI%-~ zd#fqU1}H@0wcrL-egI8g>0Pmwi-w`D*4WqE0-6$ru0^znU}?W}(Opn+ zAk~@p+Zlvimv`2N&)@L%Cg;MTcpOFY9iJolbR(Bn$V>!JYtD=9*7ECcWqUKaZtZnUW@jkgVCHS=+Kv9v>g? zoPEEt$(~Ex9XMD~3;Tgm8gc8kcwk;zO7@`mj_%KACp(IEa;Rh(_I6Q!s=&EdS&7=s zx>>dq|8I@m>=DHymqt=QvN78}L#n*eKgu>Z>V#b$Xqe3Xu7i@O+A?@FSbE<6$U zHL}n}5^f#YLhoz#A;S|YXTnO}W#+-x+YE!UWvafMX*m75i3A%#+yN*=u!)wMYkq_t zAx|=xPT^+rYegAxAr0F4#)jVQ6ZrmH#Z`_eL^kBXxMH)c;o~qVcfNh$+_SytFP1wp z1;jl4xu6!BTlZehv|`fTKFk@~8Y8WxKZMK^V~IewQ|m=Ns!+3T6Pk}U zHVQ1*i8I(%DL?UDk#me)$aC1=n`I(~+@SyX!Q}PFc}I9%DX+@570Pe5yiUbJMm=(* z12nJ^iO!6tl+1OS4%w6B)!)9#*&3BO;`w1w$aErjsNha4QKAl;ytvl+GO#4E1Nf3HTr^?;?B; z4U(^=)!qf4v&ucD%93brt~^UY35`;ekT>iJ8#x)rH)ZD}>z70MbYjq?c5S~g%Vug7 zy)YrbjXXeSy0$ho;L#f8Bjo$&Z898@iwi%eq3gQ`<;YIv%B@}ES0xL5d`xvB8D@7@ ztR_t0aaNXEmEg!3C|Mr#413C>0gN7A>^y)tP!*hcX?!yJFeB5OBG$Rh{N`h{3w05 z$`?+!%r%PBUHQZ_cXJIo8|2L2q_s8!s6Nmm%F!ilw2Uy^2Rr9169lRzwu50tW!MfPF&`at zVm_|Rg0c3LN|+%yN3qz->r)eDn;@4Oit5E)(@6BPQ;TYx4n$9~5wye*bJ7x{(K4&i z{loZR2m1a#-rHy8NTD2wTx}2?k-trf8+X2(Fsnd#EdjV)M>;gJCu3CMfdOrdC`h-h z8pk7$E1;6EalO(T2NPx5Xw7=|`D2Lnz@gy0CYJ?SjCR~bY1gRdhg!qe4KLQvU z!c-XQ&O{Ug1r~mF*-M41Y00rFIcEhSGyrzCVxqo!2~OxT)y@e0DEW{u5lc;|!l2~X z@~JYx1+zteI7PRlO3nj^1kC#JuP&#Ct~`tLO$vE>;rjD@xW?Gu^#LG{3_~)Afh`^s z>}}HU{C~6nTR%0fJ}~HJr9_6UE*Q1eAX_B8n-(n1f;NIxPhC1n3l$2sU1RwnM@)tJ zV-8ahXy@B)1UTlMy*;Ha3XG%?uAp=c!5V70{d|a&64cY;I=x@PwG#IW!$tC17B+U9 zj;6CsB(S1bRO?-#=wX*7#eLp00&16e$u8=(gnTryK+mf)>Sm zY5in<`;?t5f!!M}hHzeyc(#6WzJHpI%=Q5MwYZ*7msg*3vE&fJ#brLgtcChmsVAMS zdvsUUALj(?Y(W=*q4-?Nk{){W!z4xEEw2}cE00-bMQUlaa)}A(n zC7-8%j}>PiE!Aw4d8U(6GH=b=Cb|msFXJpt=Dll_S0>TnyMqHspeCW)tY(yeVxrPx zqRCn2TKeLr5wR4P$m1eHZddY-Pqy8`dDR6AX4^0;R=sFy(L7C^p4W+Qd%|CuQM=u4 zL~)Edq#+C{jpL|Zmub}Fn0-UyxEY~yRs;FAif?{Uap23HY*-AQVeWpbpy)pw5kvGl zr8X&fA)!<0!YC6~mGmQX`+#f|Gefgs?*^~SVU`H@EZRDooqN2$`@=7)V^|UCiO-Wl zy|5K~m?7GxB5Uy=tNPM?EHL)MXnKXtR>)|~;5u^;7I2U(k`d>)&9+PN1s3E!vwO5Z zOZ#v|8}>@uzDIk)55-x6sQn+ob#i#G=@_x~JQ=4gA+b^GXcPH*X<-c(E6B3nvpQ{7 zXyc@NdK#bZ9PXd(|Ih9T?QQ0)<(hZ^4B0H5&fuPfF_jUwU`9+9L`Kj6R6IJ|If#Gd zX*Oj{ze#=QXE>iuh`cM`H5G;uZ@SaT=uYwuTrav{ib zW!NFn2+S;8tCz)V)lL|=3fGjkv&Kx6?z?m<3i{q$Y=gDjAdFJIcs9CB>2!ScJPeW) z>p6oXs?9mkT)&~363pO1na->u;%cD^8!#&SoEL(!w0(Pg&^_zcgLY?VIw9nht!O0y zrxgJo=-JFR-nyhS2>gt(*P_7Zk`y*i$JlllTUGfQpVhX*bW7!omGY}pa&{H7K*uND z*ZV&M4tc8Eu_m4)Blhe?M{7`)=u#ZsN$1T32;dEqI2$=rI(N)?%rV%F9gn3p!Rw{& z!@8EjOU6I+98IJgD@l74mV(57tPhKB-hgd-qbHEpKd>2!|}UiyMv>*C(PB=o0(dxA4NcO!WK zc|eB0z;bPX!_W!4jq$<0kG|dAruhK+ms_I4^dz=j%$(y(d5p7>mPJdJYapg zlMyf~D>)=SF$a69{y-+z^c{iVm=%ruMdc4Mw&QMUDkGYYbrT{Xx^ehG9O!B zeVA?-jTEs~Bt|Zjphy{4pcQ%6mYWEr`NmcQY;JpZ*V-$gI=OVuR#j4yZn`+_5nIY2 zmYfWGaGiw9cZPMz_F0Fw7W^M%<#N-Y7P^B zf7Tyn#IW{~-Zh1|Fqba5R9Ogy>ufuQ*Xbl`?M5UPn`Y^xiE0I+HYgcOfPM~dG0g?H zkNXQ>x~Ap;iYaDu2fQXms@iRtC2k}yT>$x`q@{E(O>75E9Y+%5wsCOq)~;Do>^c^M zUZuQdjXi=Awl5%8U=`ZK%H;tHgO31+PINdjQA-miRG zbF6weRm$uhqrgaPfvK4CU<8f!gP~z5pCut=TaP*BF{{WE7&S9WhnSrMU;z6{EAo|U zJVV=mZ}U{_rmv=Pa+ys>9I`^Wq2{a(2r0cgWCz#1`1F^zuZ|94!>h>o@l6SUYqCtP z(SLB-M|&_f7lVxpK%6fp2v4aGaKyn#bTz@hHZ?$tmDwmE32K{=ScV(BUd0sSms!6W z!des$6vKL2-Ub0F)K8;kYcg%=(j|hl^@d`^3+^a5Mui!SYd@t#7A{M8UULRk>)*kZ zW!Q@mNi1iMP@-V&ey`E0CPPk~Z^SF-$qoE7*$Rc4kspHcE4-@fLY4mq^8b>m_JIk2 z%k%$kY`)xh{+G?IuQtEl+rKr6`}On9&-s7sRmg5BB0WCr9s&>ov;^L2<7m%{e%OBes{V;+oV} zHt$WQ{j?2ahTaQ@C?P`}zC)T&)8K->jVH~MrEWEvIX;z93CCa8m{5A5;wB3h0SEI| zd5P`$DyBn7nHS4hADFcm?pVl5dm*~u_JD6Xz$jT-Rq?3n)Oz+)S_h!1{-4+Iv#@_fA~D4*tJf zqB&>(q3PdO;Qy_y7tg=;^S?iTzVR9V|2g>I7*r!m%|XQ?S#sNPQ1Ew2iubiLyBB9~ zXUuy%UYL zLsr#JP+oMy{(@2%uBep@1wA4~<<7xDZLMCo_~FrEx3;2vd7w3u1Q%q|&d_Rp|JBLP z$u9;Qltj}|2R*x{7z39qG+YcP6>Zn9Q!25W1icqW=j&w7NY8VR@K%V|QEf|inETz+ zW+V=)0e-@p6YOs9i8uGX?(3a*2WJ?yq^YKoIeKUgA~{Ac@EKYS!2|@1+L=x2S?GtY zEilGH(z{8n>=c-_+bBaOZ#$Bzzgn~355!$K(Q6nidwlrCe-Jk_`ku<1@GZYj3hi~xp zcK>ky?Yp zirw8_0T#;cCX0mf#lclaAlZ_Mw`Afb2KBf+#<_~#Ck7<~`XJ^_&NnZ@h}Q_k(E0l9 z&M)z+E?k!n_YS&y?wXn)J@UZG7p`qbDy)5>9nSC9h%*Ex zQ4gtH5ZH)7_wMxUfw23tr;h~v0RwQuJBDX3*dsW56;37Jzrs1#e>9y}yl8^Cx!UCe zk=oRBWKSOd@W#hZaP;J~b!r=J_|I_(`>5WrFTQ+>FGmUces<0;OmQ@t91f%?`2eK- zxS!6HC;#jwoR->QUofbW>rw9_Me%_rMHyLXE{LpiK1%4J#rmScaB?BI)D<*Vq&8Gw zF(5M^*R5+nYCf)6HxK>XlQmnCmEu2Z)^Qfp{<3C$Tz&Yra+BU?gO-7JogJHxp@Axc)LH&8c{2%i90_LiRfwBk*cXFvwhxjn4xF53B6HUQQc!QA7@RqRUglJ z80x|OLj91+URhBMF7gnOaq9>(DzX9wI4A}^!$d7DmoAF}X@-DBFC1&}5O?BIX2%qa zTgYXGa;bkV=7)C?SFQx+=qc`&><_1;=2t;i7OFX~q{PHT1CeB*tQz1B%i_M2+NXQO zM=iR%lcuB%t!K1xtuIFkC8thLM8msyL z`>z^OAXaK?jIVHRj0oN~=L9r$osMRy3By5WEp(#oI0F<<#lhwzTC+cE*t;oH{G=v< zH7Jr*xkN0SpM`Bs-4H1zl#|ndMT_s5Qd()!Otcj-d$cH+7jDhkkkgxBCgS2LQ=0hOrH4F2qA@%syYxn{1 zEok`*x8++Mz-s|?3m!4^Yw?;GMBDL@ds7!FGTv+oqx@s$k6IN4S*?}?Y;B>ai~Dv5 z*C-1pPDkBYN&5?#rFjwTiwK*W6tpOWU{Ux$G1JI}5X_TcUoT=`g9`fMR^z?y@u}&{ zu2-7CV;$NzT%YW(F{_m`d+6+bM|{Vk1quPJjBmO(YZzb)PjmbrFo_BgJkCszvnJc) zqiPy)znE(GeST2m6*H}Zl$Xlvl{AgZ83wq}lt?w=$m6h3T0h6^h95aK)JF@mh{U_v zt~M^#5Vies_WjXej^dG_Y>{9ic$1&qEv}Jsrkd`3UfC)$gw^T477e?(YYREn6Y*W1 z?r}HzH@^FP5)Nfy8$*ntp*Ut+jySHH#TA#`j~E>*+NbwjJQTJ_f^WU%ta+K${BVKR z(A%*ZZX8?YYSh_|3T5H-7w$9cORLHiof)L{{<{FZH_;27YtBRQ$gy({{zNpwp+p&t z93CB>e!p`9$Nbg);kugn%i$!Tm?y^#bnl{+hP>yE8a}&^9^M<(3Prp>2TX?OJ*xbh z+xC4b`#;>UDB8^a5c}^J8ynAG`1XHaZ@&0!|M%zE|LODr!sydVvxwU=W)n96a=6kA zW95;GI7w^*hpq!!hYmVvKbYAjvkb;Du>l$aHsN@CHig=Nuo=BWQ^8MXW!MzIZEYlg z!5##!QPd6UC+r7;h9a!6M=97gTAJSu`wXKhxv5nn9YqO21C6zX&zfQ>5*&=60Vp@V4=8MfHayZf=@E$315XmH?3==Z8+{AFJaBD=G z(bAz_)z0#*H)}u?NUePH!9WC|fzK}#43Kj4rn9@czW4Hs?N~HoKZ*OC{0#LfP1UBv z?Vo;3;0BW_XE7NjP_ZGja~rk3%h{{Yix?fM@U5GSPOGl4OjU&}m)JfSZZ~s8J~g-% z=O)X7B-#M**7e%|Xj>_%^^*-De|VU2KE^e6sFKcngd3LHh@{r$XwR5Sc@lkWdmGZo zAz@&u2@fnysMb%>__0>Yt6nH@N;sW?4NhMST^0A;3Y0{^TznYz(rw_?d#R2^ zL@VA;7724x$rXlX6CR&~wplwPTlN6$VSu>N^n;eHn?sP{nCjRU`sLb5$MkaG%RHoU zFVk!C|K-F!0RUKUac4Ll5V%MpRjoBJLWxzlyg$H_CH=|UV1H;usr!23cjt;8mK-0KaSNO?t$Q!3wmRzOrW?gUhh7|xn=eb^ZX50!5%$Jk6$AS+R2g;2? z)0+0KjTGp9ff{A&@(>u+7L5u}8x0JA^Go;O;OHmUXso7V56eNOO~>e4y~szwr#k{* z&C4ke>+gIAbe%oH&9$Ao?C5b*=(c(-kNr^H4K%8b*WAbR23{nn!f1Ncwk~^4%Q$v8 z7Cj7kh6oqK0hB_CmjXC^fD?gidLs~n<*;H@K8mE-FQS_?oza1m?fgt_H47<}?>0pS z?9B$(>IKUpz3m|9Ly=&KMO{-jjhu*J&i2(CtD_?9?;c4|1g*&63=D@mXZ!Gn-WR0` zWfEhVJD{0!GJ+Kg#FODzangw|0P&PyHAAD&iI%?A>;xumvIQ>CzRrbLD9&(PZdH~~ zr-d@U*ZT+E5UBJ^$Fw)4&;dHAI#E}=NTM&h@_12TfK|nIP5x9z+4c7A&f#ADye6d( zA_uQeO#ruVDuz1R&4>V&=Hy6V>%J~c-J8FtOT6^yU=S}z*zli?TDdYzf#Rp5lOOgE zDf1v|ykcvJaGi5&_ama#@%U_S8)TVOHE#g$X*F6oKdZ@B7nNvzsoGR?}&@( zSQ+yQ>rqG}c#JqW(8hKs(GtEs-`*m#+iGjC8s<;1R7~Pi*jH3#Yx_c35O+enjpAlcb0=p;-K)@afCx@pDx`$W6CJUjJz+tuB6`s}+~P6?qbrjS;= z*4QrA_5N$kQ)fWfixC0FN3UO#qx1gRY3HjKwR^y)poIdAUdt5*toYT7#=jxlhB9bXSfQbCIXqJ@qJf>(YM>g;k(wyz&j2HcM=vZ+O^#0Rp1>; z&N|VG78QhxrL|rtGHYe`y1NIbbu+f&giIl$baK|nuKdfa0lhs^Tn0&0CEXQRJo9dQ zoP85v;Ogi}{1Mu$^XG@cO{zn&x}@mZgX!+S z-#NkK-u)SVB&@(+u~yqK*#YSl}_lV?BbSQoA^(Letg z@yEKf+GuSy)VNxkrR~5li$M2@&eqz@tFj>}KTMY$b=kSc0d24x8OGXI5sC52>1OW2 zw|M>1@=J^twVa6HeW;xb(bSIbjhss9Ci*s_OiR|T8qU`UZ^jqd_%Uh!ZW_hfRTjs$ z=VSCJuTx4dPqBJ*8qlcXeX_Vw7#*ew2{q>yyqu@WjgcLofzoC`-3;wvP(8f6n>PLS z2nr(0fb&e037TJ|cFblYyJK;@nB7vN!G7I&tkI`ZpsdxU?T$B`=aKH|_oy`9KRi3x zIo&_pr3eYJ9Z?mL^|piEO#V-i6Idd3m17=_3)2PpEno@qt>R?RMudW~;BVa2&)H-+ zi`=}=l~XpMS$UVNm2Cs-mAOm3}!jQs2}a1i+b;#!ktb*ttGkW^7hvz^tkfkt?bU-Eur zpf3x1s$xRM9(Grif!d95MR`FQHIAD;s5>ojF&5sAdYkPYX6LQt)5N`>;98^29dbx2 z2}p#zZS({^NCr$~U{@fOnFEpe?fpchDg*3~;2^hSk#TXN#Ef5ugoC$8Gy2y~~`TB>h-nn`UIe5#PeTg|lvl z7&0$|JKGD?)T!xpd!~V&&skR(nb?o-B<)#E;DJ_8LwJosT5$%Nx@W}bh-d3`@M^%x zxfv_`+e;8F7PRD2mTU@4dolu^WWLDS z(SEHjEm2}mD4^K@v3fB1Akgs&PJj~;39lj)!WXe6C%&Tr(OpO) z&GOd3G!B;~05tUUmHb_t9 z#J$-1CSvkg-Yz$aX}PG;{Jka6%Qw(&K|wpemzK}z+9Za4vGxBRVYed8YU>O4)NcFa zTNxr$DG0BM>(P=k{y2Mf%OBBq1v{iA^+HOnUi#Xt3SRp2>C%vK;DtfOnC<0ghx-jbtjJEuGN-p1+zWWA6g4#w6R^eW?b7 zRX4qN;v_;MIJfsa?wht5DZ61L`FzRFd&ZNlY1S-vprL|iJxAsWCgitw{U2dmYHeX| zBC_iM;eKluC4?p1nzrsxNnyMu>+7szBanQX#4=_*o8%J(&rzB<1O&s;@+-=}NntiS z-_*_t+|RWrm7|kSdr*=O^Na$OAJcW|T&)sX&0u?!DI24&I%W4UYA(D;=kweP?x7BK znwVx1kTi9Ndv3hMD18gH?><;)m{AHpu4jum))%z%pkd);r#WYxof8lq^j?-MpZ5_Le9M^`yY~!~(hsQf_y5`cM zqfij5=%=YyNlVD^zyuVWrE|)Wz+x9*foCwFwU{&MC&*?|tI*iv%yd;H`y8VRDdp2t z12`HhXmYg(gz;vb6$Af5TwF12l=J=;DxuQ1eSClv60?J#c&__#K~=Z6u>k&?e^dDh zn^6@w;BpPcZ8iMV`7Wyclnl;b@IqqXQmzzx`1ahqk1i^3se-^GrL&fFI|LCR@VA`*v3o@Ake6+#t1e-NK46Myj8Dhw-+=` znvSOPPTs;!0`FCd4ixNv4QIF`_Cvc!gW667GbYQnwj=_s0j7AIb$>p4pFQoszxw+R zPsLhJ^q|mD!w)+#4%oRoXqH}xK@k>^ztq)yx}4==Mfkly=^Tdv&k9iijB9%1s;DGK zX-;V<=2N0A9QSQJYUu+p?us4R2Uzpzbd)9&KQ$Cm=R_w@!+#o)BU!dI(?P82tNvIQ zSBq+*NE!F76p~6n5TBmyz|CC~b0~#`blgARwgT_uTvefflQXlBLueFPsq)5zb|g@{ z8DEft)Z^^}#LM_b8MA=6tQE7)j;=GXb3J1}ZFb}mAf6ZIl)_xuGhg`V^sPztJ-eQx zuJP~7sptjQNKW;R0#CadJI?kgF0E7`ej-E2yhLM43aTCQtJz&fI+bzKyGDWFJOw}l z;gMTlHJ>yuZ%VO_rk8`;Qt;BrVt_Nq7EwOY_cyEBfW=t$77<(vXxNjL6;MUI#Ip7O zn2=OpeXTGPI2v#DF=?bH?Z?^bF|s!Kc4cf3WfAEtokW#T+V+)=tZx;mdyMA_cdaUK z_U6i>+Qt@k)H7KgOp&{)-a~?_AUZPsD73m{193M?s}zzW7lX&~sI^a6&d&Mp08glU z!c5#Q6PWxq87>8@xp9d5$r$C_=S9r;Y(CE(zK0lqTh5CT{ciij3Gx5dvfkz}hDHrH!qXz>oG_&LGXmU#zzxbiPA|?-VeCLqBx55`$Q*|0Mj&ytQ*hW= zxp99!Jvci)Ioefs!PDR#hH-t&Mhjxw(UJ(66tYypjeRw|O((D$?nY^Lou=&CSIOJY zahxKIQdCpD=IjdT#wCJ@dQJ5S@ViZbF*Mcg-FjZE1UN@h0raOm;1q7!EQN!kb(OX! z>Ef9XwP!GlXJQ}tOkHnvC3tC{V23Hh;5n_<1Q@gh9)+#%BAo<=4Tn^yS2bd|dapVQ zc~eaTdExd}1@BU)DYy1Dn@e5i*eD*>upz6~#Pnq?4pGafx+A$y(Q{Fy=Ci;YeMmCQ zQ^$b^rjzIn)=LaFtI>OJq*WY4Hbiq2aT}qyiX792Ra??_3)-$$Dvv6UqP=vH&d12m zNW#rYKbe!$z7|2^3$oM`iRZit^|C1$*TKmc!S!%1CNh|rVv07|_(-z7W~N!Fr&LJT zdd6uJDPt~qtn(my%ULF|Ix%SQBMBO!9?eruU}6nbwI=6th?SIlzur1PehDU<(?g%Z zj@>ySVU$i4uagAARPZb;qN`qyQ{;^jjP)m`=BOmx&NKOPkFb({KE(`nwA?MeTB65m zW=Tg8Oa=D>$=%Z&5_NM+UMuU?>7By@8jPc@m*PsyOmkuTm&(vLIf1~avgyB(lZ%$7^mi;Ns# z${{pw4aIeS9g&UZ1VOm%1(zlxP5hI)mFR%o6DPY!RV!JyqfRxD)LKRX%}LAW=+NO; zyC|whfK;N032^cxGO{D{m=3IP^ijS+CZ0~Xqqe`7p*Lyn|AF8apMTbi|1qCt*@Lrx zt&0D#`F!)`mY@G|<8%JUKR^E$B9!YyA_mc-w=6GrH*m*YhQbw$;4w-+sy7m<16`7J zz>cy|9Th-GqnO0mN{d(7IXwNTdjePW9}bUxIz$2S*2@C0HM`?u*NZck@ zD6!|JRLbRnd5IF!F{XJ0_H06CStDWh$Uj1vVX0hWlo+{(rozc3vL>h>O?rzZajBC9 zdJNT7P=!ovxuovhFr_eQX^VPbMuzC~yw6~!b-ObcDH{sX2n)INHBRQxF`pfRE^d|9 zOT#fWTt9ldFI39L`S>_bJYvnmCBIIew# z!;`Z{&2APpOC>r{_2`Ex0ziHJrF$B1#5TL6Ai}dgt6st@9ZBq zvpGEa9o-!s1$$E4q*{AG(@0~X4OtXu!;4PubyBTWe|IO)My`{P#R|ETeZSckU(zc9aGckkT@EMDG7P?0 zYoYS5n)a@zQENi%z&8=z|D(r!;s|tu`VQ5&uw;9z`2YgD06nx(&P1Cv0AygZc5(5GIBp8RngYH?k$VT8p$`BAB)vPM z3_>&lgpQol=gU!=g_S{zAtuLiBe{#eJ2LcM5O)df&I%%Ypman1^m2JssyDJ?yiKB5BIuw!On?x z+Oq57w9Sm+vPRbozUude^B!F7Oj4X4CD=_DA5vhmOqxt9mk7lHXloNu8S@T$M>yl~ zCz-iR`~=pHf_B=G<CUTz?jC87^waL!(mC#$dSXg6 z3Ti5yesRrcO5szy26&@zztjNMPG@75PD6c(h=NxE$;<6_Q8Y5Cr+x|>=25NHzR}t1 zIdSX)CP?WdzPzKE)Qi?Uw5{yCf3T&DApu38GsReAP}DLmZa=@H{cYtrmRi7vr8}2% zQ@aS2^7gA$_rjOw*fq$cUvJ!|+O8LC>J?W)tVpsJJewSWlroT-BwQqRapBaoLDRJ7 z(`c-m?CHB#l3Y13$w!=K%gT_4kzvq?g7+acQ^&C-ibH9z>=k|mTC;#c;Wsg&4r22O zWx0S|ME6&Cmt+pJ(xfCeyq1AxiNJGd4k(LaVBM8cSqQOV)8=H6r%h4r#IyqxL@_89 z%o~-pYQlcB*uQ#dS>%0)Cesxvw#gA?G%ysINGFwIqGz#qhSmx2+R;8T+Y^B90Ii~t z|0DYuAy8;(qo@HRkTW9mNv6OmoB3}`%wjTSs{(9+r4>)=4d&&s+(H86)0$4EK-b zz>COp&2Fy5Yu+;UxXe^m5@*~_nj(@F_ayGVvRQ9Nz1a+JCk;+kY;GZvaES&=6EZWJ zq#t5s^R7XsQuA=N8n23!;*3-0mc_EwgcAM9R}XM*KOMWGBhvS}hix?d5bIEG0Fd$J zbd>3cC>$M3Wpgs+r0MN^e1D>6YgX__-=3#q;CbtV#vd`};nie1PwzkUvU<502wJpf zK$q@%jS}|~C%;^Tt}~kAZA(C%4p2QOv<`f?&Iji3_9-bJbS8k-5p3qqV>5T&8s+FB zNFg5?bjXS6lyi!l9|?CVSg?oJxuU~qB4)kE042)2+zwDv&l3s|4BiqQaAwkloD(fV70kxqCFT!!~)X|idCq3dC zF$}vjrf?dI7Pvpyb@fIw`t`SluEw)6T13oHc*jX2#S2gsDwu-f0IuS<5;)5W#)IJ; zBiwLtOM@t#sgp>-Yn-tv>|$YPJ!Ok$R^}xf(RTlE_u$>0NGc_zZ)l9H5A$ae7@iD5 znmYHpx$p}PMk@GI2FPWpCy;}YUt~+T3{=CbfFX#)2?6#2oBaxCE zasllL-1B*vCaOODeHzuC)!;W2_3zjSZ!RoLn5CfldOEQM(t;9#mEoMYln zMk7gAt;kQZJFQ3sdQ#Y-jb27Nbe^M#s6)}FbkQh0q*Az$Ru`iP1kk5N6OW+H4?s7Q zNk(C7^Yn(3e7JNE|I7@DQ?dGp&J9tPJ)5UlIuX}ZIK>FY56M8})x?fx6#pLGNk|B< zW-#&nPeto zU*z|yKsjubA0F5^xQ)D!Yx&LBz<3h&4pX(<4aUti4XY{fP(u+)L&L?jcq+}?ITkI_ zX0w)d6OBslYU1!?)@?+SckjZHyKJa}4a@h744$+j-2K?Y;ljAkX+9#v0T}JadfEsb zS9F#d$EPfvAx8zfT*P|3W9hykiR|&zirB8i?qt6orz3wPKIvS{vHNcJ06e zx;Fkj-`H;brw~9Ts)*Js zsvAArdv>J6j22fjyGzHHKv&HzPGZ}JSw=)%aE~A5N9OF!Sd~LD7+PcLkpA~kTbaCP zMS$pelAekqlFob@?re^5`l6Cz?e&U1^NRHxSw^k3cY3ySw!a%c&f>R6d+!dqryWVy zq>n$tuF-HKYbwZh1f*Ve8%zg=Q8FdyJ|zo_v6udGJie2y8B;M1mtEC;dWd@EfH||9 zH*9LzzvuQ$f>IWrg*Fuh8O04K%NEo^j@@$_RC`npr;)P{Bb8Nwx?q)qazGKJj9&>7 z<3j!v8=Mpf16-9;c0SIhK2{1NOTBbK0f)3wD8$K`PPO^Mxr=;j7aregk2Ao$uDuV( z!9BR?n0$C0O|P!TNW?IegZ|zm?)}_Ls8}na;!!s9c9 zgpb6Ff(-<~LHFXBwJ>tG7htfc#VQ}*nt%OGam6fUOmrk7wa-XEn!@$Y+0I6Ny=s?< zNI;PmneYW^7ot*aWVA}AfxW`?s9#&9;R*G(NbC`m8$pFeAQ^&yP9KFW!_VsXH4!c5 zb6wjTGA#UHkYq*td{7&ooo5%kUxq3~)8Mnjfhz(HFh?wpvDsn9XMvaa0=WeJ8Fk$9X;lB;x{^LP4af`Ki>%RHmD z$RTwIyWV|z{_%n$^}?I0#>M%DCCk22@^`yKsceRIC08_O)b38icCM(EECwXzVL8G5 z4CxNHCr(@Q8FV`{$Ya?5s57CiKf=-hN+0J6i$E9V&_j1t>e2i0FM%k~1%zfH${?G8 zv4{d+y@AQF-`lEjE|9-6EnFRhCMl~F5$aC074{7)G@}DBZW5dsqRzrz_$9aOl3Q-k zob?+P|Bl)(=VZ=A2sn?l_K~;MV`V^|k)@d~MhBClPrAhkA(c7QE|etEnI?SQ(l4A@ zHG+XHOz=s-?O8SZt9O&*F~E!FN$GmIh-#@nah+266~Tpy4dmg<+kx88Z3XF~NVjcWPyI3tw}D2K+jVR9?UNMp7*bhXKl7l(JTGwL z=rgq;A&a@m!q+>)GOmd&?JeSMfjezhxW*k6`sF)lV7qS@naHb3+Ce3^VqrfOD zRh`}&;jmam6OX*Xd&cx^Bw5DFh`||}({o{EnvIuqc|_)&8J>IcRYLg?L*OBJLF8RX z)QO1?R&kyAELVPI1t#<-WZ315gs|#p5``}wKhRqd_#S3rd zV(TgKK+b@8n~A!%;GR${0FWFy(Hd^6aA0ZkON#gfk*xH$9lqKL-RWD1zx*clZh{UY z6B~~xrJ$A~_a7ofw&{bC#j>|o)An6l*Y(S74vCGD;gY|se=GUIFTgJ(Xr|emocm}y z==1~(56Av6KFcI1o2M9)r-ybrrp9)qB>R;YbASnev{_O!gsx~hs%l|P3azOiCZ$)vZ6ypJ z*r|VGXQgKCV$BiUr~9G+nW62w@4Mp@M?<_Q-aV$``YfAvRSY$?m`&@d?*XFGC~c%@ z=NF==PbIUn(eq@=X8Dh80N4zA(>jI^MblfpPfirr9wAJf-xK{nK-p0H=B5BW?3^BM zmT2V)4_!ZCYlxhs!l!PO0VSd_`zuD~s7@RbfKEZOB&G)zRi>@XSoMcwTZ7j*6VXG9 zLX@l{XFrw`s3BOWMJs|dezgKgSQhO$b(~YSpa}xmLTl10oCnQXKw;LK7}#+*X>x5_ zFwtAiGaz~xwlo=Gv=7m}s8;laBM?zTL_*Zq&Lm%joS*f*6lo%dy2zAH#vx?v58}BP z>wCdG^)2X~dHRNeSUhMdXa^26?Yiu|)(*S-(~$&783JpLAuQO7IlXZXHKZD%B0C?6Zo#Rxw9AB+^l=y?TB@QSk|8Cy@2v`#%HY`{Ti#1hIiIdS?~8!Z@F zeko>H3nPddXemaJGWXiDIp@%lE$fsm-m*?HcgwoVzuvBOn=9P4+Aa7#8`sDN=Av21 zZC!Pz4{zOd_N>+hthZ;q;%3j%G+@{2rENv-?l#Z;eV?mAE|mV^fCGWrzEBZYCR(!j zeQ^Em&7WKGU}y#Bh=kmvOOHq1>ukNvU2rsL&ll_)wdWtW*}b{1vDf`^l!NBY?vyh=_!6L1F>_4Y{dV>4EW*t0{C+3Tmb*SkT#oRzb*Sqf#Odh; z`ZL*);GWqEY?|N2m8`$#L*()v$eA-;xy7%qoi7rG7$Kf@?bku7B!i@8=-9J3 zEEgf$1|=haFNIQqkc8mV?3+J?FL1|HhASzDX6$X2Le&)MiIJjGHUIXn19$TE-x$0p z5CklqmopX^h~Alst<)c{bq&fFckb~;WeZ4$6t`AWO@knzg&u2Jl(?dad`uj~^el z1#Th?2%)g93Lf@~kycSxc?YqpMZvBy0xhbEv3$%o!4R@aSBp}hm5t2I3t)#7 zaL4IAk+GVmGF}(xnxQvWTN6R}&O3?apf6M_WATP}Zr6#L=!Gt{sZh+!FzV0SibNA*+aB$w`$H{9s zG=G%AOQ<3-4?;7b{8eIw@lOGg&Qqfh?fKNi#)1#lEHM26+T(3DiyUFSu=>iSzF4JL z1&41H)U{@ypwSgA+0>^?dp7M`jp z!(5Cp=JCJ*V_b?vrY;$mM0d3VZJCJMh&D!d@pNKc3ra1a0x}@Zu`QRX$rafuTfPVb z75$sgSIGKak;aSdythw&3?T~pMTfd5usM1po?0Jhn-dYt;btkzM=L>Xo!0ZwMb3(_u$cLx@RC1TZ$I<=Do&C# zo<~lMX`ORsg)S4!Ma9PZsyPV+&0#0ef@V1bgmZZ(OcP)*iP|`_c%^v|9)(Qe+_ty$ zXXBq&k=6)Y<`*G{P~-Tdf*z9yk4_pq*`(ia;>2}6wG-HCN2osFd&)gW?jlp$2ZE@M zm40MX-JZ6L`EZGtZ_}}~z-naRY0(#hb~MS~E{y2XU&DG|o4=*$Dy0V&@y%@z1c>ca z^t{e@7?Pu3@$E-(E=7LMH3xdw(sqQcP}}aFwhUQlMB$a}+sn8m>*!8Hn3BFu0k2dO zg&uJ^CA6!}V6QPX6I}HY@?1g)A4QmEYGLAdjgybV@p3GwiAQeE6o(LTNGI1iN?rO_ z3hK&Fny1I`S}m0puC~N}B&6ARMo*VO%|^GD<*7@&ipj72rjYXtHx>@E;2{~mNkNj7 z|B78mCeukPyC#nom4soi`u)yHcQ58QdI;`#ADYbO{yGGY z8B<;~s5c?gciO;W@yzLn9>7UKeR1y_Ip+QMV7a7;Fh5jc4_RR6Y$ro8su5Iz6n3=A ztkd6PqHYT}wk{o9#Z89g17-P$Jmwn>4=iZ3C|(e!pqUW;3dz`RO zf6~@DaSu9qf9wf#2)Vii*iNK)g2H0>HK~ekfFG7v2N82ltoxvwu19vaN-@9Z8YMn( z&8WH}Q(rag-|8YS40q4YHKJqWfHY!4!dwl7qTe5o#z|t$yGBmorrDhybLipiXR;h$ zrgM%+Pl5{S>Jl9gGx4s6YsB($H0+JUL%Mv};uJJaZYZM?>&QN!-3uzkj9oL!uJ?A{ zR7y`A^WWa3++oKb>-)LuwWFgWHA!Z2=e$lxjbN1tR`U>}$ zeM4dLrMTvvfGN1PR z7bRjXO7Iy;;G{=>ya6??zKQ`L@6-v$`H?s9G|k{nB8}Kt$aMHayNXWBq0*AkQz=OK zFiNDRT4-vi6Xo3>B|KfBobr?hiLL!m? z-a}W(aPmbtt4ndM30xiBc+^H2v?8B>g)KCK(Kr3z0~{08_wgf%dq zSO25Cdv@B`)~hPO$(h9u}R+vrb{i5nXK`IAw|U9L&Nwjv$PKz$}%P~u&&}j zMUyWFMF3R&eZd{00FqlPaP}muGW89m)}a;j>Y5Fq!Q&2H4Q;hr`Ki$zjmWYsSQ&7RrQ~%NkdZ8O{r686@^r@`gZc z!(0OD;`GYl*7K3K{6vz`g@M6zxga1Q40IM-KaQ&xx3y*f6COg(1oX7#5wPN@xdtKb zxG*awjcfmKH$L7u`~K7}0B>(GhXWSyRLlF_Q*1a8Z4MuEa?IV=2Rm=9?+1I{1CylF z>Xee{$&M*#-X=eJU9}f2&uW?}BR5U{PjCSoWzRk&1A^N#1HJa_4k|K9hT5@tQ%H;P z&^WwW!J*;QZ%rkyRI58!&PlHznc)UW2A5K03ev}Q>O|ei?QlMwpp|*s`drs2b#mJ_ zr_eu`ri_0&t+Mx?8hdd+up)9=nkhh@sP}b44TjfmV&Qja5 zXI1TdaKTAYG9dnLE|g$0!e%sRG@x)iUJS>UU2D(jj>qox#}ChY7a<<1XOZ&MX-iI> z*BC!Nr}*+J32l0@hS>~lOp3ov_i$Vc6SUcnUzv+1Z)M!Doe{kK;!?fakiUU(k+ulw zZP-!T8N@l($64Px*IgRl7dSxQ@m6g_JFf>7uM|N=_UI=BiyV!AHMsDwN&s_@`9XU* z<$@|lDUMc+n+ox_d(8lAg=c`DC_#^xs}#@6C2&&Bs7i<&%T*f|l3T#NC`Oc9S4}ij z+}P1H>92wQu^4br7}|6=U1lmY413u+*LO^`aze>8xO_<5C zj&-Cgh*lFntnAEGnxY894qf~rNEkoSAXiXTsGT~a6jnox(h%G)Y>K<~;CL4YN46q| z%fBqmwe+N#%6eXCqrOZcK!-~*G?;qUrW1L1bf@>C>6T zgDQpCB_(P_lnF&8wp21vJk?n;F_|pa2)Uu)%Lg@9Uuhg%VvPhXn&0oG?sTBldMJY& zUV(j5>iw)pJlAl%fkIuA_sSYr88QZSnYTQL^x7*c_`o=9~SRx!l+E;>Y_HsA5y!HH?CM6F-u<&;Dc)-#eifLfr-Ht=A`P-J+x6;nJ{@rl_*Ej$@;V zwVi_k(+gGpU6U)!9J!W;Nt=)?S>q05gKjk%FGUhUemc)w?)O}63=4`)d8R~~O~Q0e z0`Sb%+N^U($#=sgPQtwTz>A2r7OIt=j!0R4|fmU_8VNFAD| zTVcIandL0WNR>;>7Tn}^f50^4sM3#5Fe$mqY^7{Dpg}VoXrL*uP#)a`FoYeu zT&1`nQ(2b>2}Ut5DQ`0nSPT);3}ryeNj<gS71xFXLk?oV*`G^`f7vz!jJcN^XskW8-Lk+{`~oimtQ~M{QAXTHnujtdb#D9=Rj*pLl5gIP(R2}whk$osnS{vcnw&;)I5${QyoIF_!GyW(>0D=-MzcvWk?r#x zbp{*GhP<}{{#~nsq7ZxM28riN;*c%|v~dIGji$20hu9rm9gkFvP0jBL$~=(oaUlVu~dB6W++}=rxKPKPE`wn^t>?>KI4U zZa;(nDF+B)#f-LU_AFU0roc_N;DofZYjzT`CpAT**m?S4K3ps?HD=~EYvI{&i#Cuk z$c;eu5|v-0RUCk(bOuTMgV2~R*>NSA&G1>v)+|f#k$51Ur?qD_7E9BE zb_VR{q7Dxm=bPIX4Z9mG#fzuo8R!Xm>bEPrGQhw+MTzaNV4k8M*At>JVgx#HE%1io$9PnEYInb@eq;2JUy=j{6-F9mvy zeA>0)T=Ir(*BU4%4J8bNE7t-FcCfH4!!|C%MIh8yuGGdwWwisH^nk10t_8-3t|bDg zP(Cv`S*L7R&#nT`mgtczb5FA8G4PK5@}U$-^nFLCUDveRwmA1}nQ2asQThvv zOhzHqkRBk5LYD(Tga3u91x?zD+{ypAWgTD&YM^hEx-*E}YBy;z)62hg22x~jjrY4O zt*iUmZ7)M46RSuJb&EHsR;wqxQ%DTN=sxX>5)|#_P?}HZkT>!+FW+`_AV$gfE^}x& zF;mjGl6+1jI*{XV1Wy5@Ri9PeIQE*CfkC^-7^^g+Dgbv;^^JE&qL7VyV~ojl9@U@} zS-E8j*_=dLR0VJ#;WBDey5#7fvE&<$c31a$bG2 ze-`iUpHwe=qUX%E!2ihtZ=OcZrdG}ZEaL%to&Xzf6y^2ma*{1)GdAd@ypp(gB*HsN z56nIk^g>*D8z3&q`MSLdO@vGb{xxx;9Za6C=$uN2hWZiVH99p|AlZQM8CF-D5hIe} zRu|J)a1djgY~CZ{41cpFTT=81mD6AKNb~D_SiBTYhMNz@sIZy+b63qp0?~k$-{g>Y z)>933;DybBG3fDA^3ZmGSfOL>fT)r#+jt6$mLGxVgk9?R{0eicr{H%>6VPwh%!aDV zThSncW3X>Cr6bXnEjr5nJMdWtL!{2sV~R8epgI}<9jk`XW)tYXgKNLW?oqxm@2y-D_#b7m3&96-V0 z%7;j%;Nbkzo=gNcw`d`rCz z8i6tM%o_f6TDMnmgt)_uWSxAG;@~`$vcNbfoO| z`juHUPwTw$g5{GfuSr}KBE)dh^IpkDas}uC;e*Wx{xV%g<0T;TWtK*kxN>j*l&J7& zy+Ixla5rJcRYxQ<6#-0IE7NR{h=}i&wZ~aYtW@+)5a^Yt_x9f$#wXo_?#^k~Qkr42 zicfr;wc+SeySh8eSCtH^<&3w9iPW`$3Hl(TcdvSZ_S;wgcxV^fP*p4T4FPqF@<^4!~0Bg2JDxTF0nEaA`(p10-@LsN%&_mROz=xw$Zvw{FMbZ)4d~1nE z#QK&hl#56TO0F#?vFcZRt}tW+thquqN?yfxP_YuegWi`3aMTz>vLQ9@5KM5R2AKe7 zr~V;3W;Nh71!PTqTRn%%>tm58vD;r)-;9D{u!!fHOa8y?|$HRtAb!fo! zyPTkUd!Ao`sT)q z|9tuNS2<%?t`_3MoixarYTC z-xvH*`|fPE;?dNg;GsOog0j|^r*Opakjn+doA;}Oo!uV};8R`W+x!w~Wi8+x%H~C4 z(g#i3z4_Zy4_x|lT2@oLqBX$nzTqkVpRvFAcd-As8vZWxj}`VG8_!>CeEpZrt(VWg z`g&ty>-iSif4qR=pY1>Xgdc4>q3klU<>hQX?WM?jAaX%&9Ctt+MZV;pq7@CVmEIrq zEF6ratyBbv*CvkV3h}tLH~VKb3d(A`8w%M$={Xg+Q0A;}QZ21uR0VG<9w!ZVn+&d4 z)o06W{tQO(jKu5P0W*VTmJXI9R;u@>D0`uxe}s0Fvb-l2C-BxEp4)>%FgdLb!RtE7 z(3)JLVtc9?vUkS;kmq=!LP;7kh9TM2w2a;cfri0nO_NG*GfU>lSn?_yqjVZjHk;}A zt$Ml}8gacuE5lMlrIo=U_?)fOBwo9ystmWvAuu>iQqniDiP0Z!nMsxW?qXPRA-w9Y z2LarQ?!=`SdB8A#41x7$8K&sbzgW&jN_?j~k3@Y$3&Vrcz^SvDz;;xF zoz$8RT76)(kQ;_0&=R}R7QCWh60_D~$^{zIJ1K8YmJ_t-IK?wz1?%~^aQ)5Uv~56mHOZ&P&C8dAuR33iJ_Af)oep>!N9p>nZRL#uHWmJ|RB58$ytgLW*V_8fye&n$jlHYvQb#R^myZD*{sDsu|R zFcLuo@N*46ObwO6$TVBl7Q=znt1X1Z)2b&8xWnBValP|RfKk=jeOCL#Yg#>YI&K%J zOl(zGwe4-?lJ>vLHy^ER-W&_3W&g^SKP&aBF$utvlIG6GcJz4Ognwi;&5xSAB7mSi z^M57$-!*Z(u@6WOS&1PwDn9#k9 zELerc@S5To;YwB@e`*=#EyN!Bu-xekjyNS31o8RRbK zb97?Tqcjt*ROYE*2FhE9bajUOVC{ds&z?Mjf8srM9=%^&JgL^t|5x?mX`@=hebe5L z{)vCy0&9p?w`f#@j2UpiDl51!vC;z@B_VF7tP0NKia-i#iubO*w`9w!s}v0bWTf@$ zz;?lWH&V=Q7kh&ngW3+BaVdT!_2#u>Lt|9lxKh{FI>P9JR#B#*hBCU$MJ!O-?b^4G zv+q!DXWBf!zGxH{uRhMIRNS%gfj{D8O|rn4L8>6MNU|Ht&6)$CCm!7CIAidX;Vs36 zoB$>er*+E)n`5ag=BWl^Ht&&^F}vYN0~zp3I`RcQ*8C$Ia?&$#>Bq8{qrO+R;5vv# z#M=RZtT8SIOvA(R4a4ARGg2M2&yJ4w_D@tl6Vmu7X*rbyCL`_C=EBCqSd~&}#$I8n zgwoO?Q^^TL$eK{XlqU1ubs+q7ztA_1y020%hv&Ctfl&ZSs>h8>jSH6BWUg zhOG;Y2~A3WZAQ#kz_|g8!!~Q~6x>=xLvqK`)Hy6H6sJpHi+S6)O+K5psu%`EZ|#j# zMInfgiD&+OM72eK&o{ShleR~^DLAP8hvY8ft&;ZF*$~;ykh6Gj4<*|GOa6WUewfa0 zBIQ6KP$N;&JRLwUKp!l!jLA`a<2mw)Lax+ zk&3*ZR9!kU3uOLP(+cLpbya4_bztf36<{q{Uk>R>iC!j!Ne5ohYmXeMiE&iiiH>Q_ z#JMS`-h<#nw!~t7C;mN?VNYAp_c2Kmp!+!n%@tmPEW3cg9Fe00s#J`$Kyw?NQZA+9 zkF;3LNL0->_+WvDTKUJ>_T%NY$dr~=wg!sU?g8_07S+ee9n2ADE1oZpvj*>&dQcST zkWR~35YvTfG9eqeX#ilY2;b=0And1Pkh{~XvDyrpT5fmz>ZuW`N^s;nmQp(-Pitjl zO!FMT`-{P>l#hUh=vl^2-R>*r-a-;jzl6H&bnw&}PE4LM0+pgsE8?D%ki3Z|-s9y2 zm3ekv2JcQ2?l35$(`>B1Z#Z>rLoR3~R=7WOZ*#9~4uL7R`9YTGT8YfIJ=6JXr3jBQ z-=>E~ByTg@G$=1nGOb(}HWA?1E5=H>-`+nwJ=-}r5Dj$g%U^{f1NQMZVCSxtLLat1 z*~ja))h0TA_v&DOH~zl6v)4U2{lj+;BR2a2jNYk|E$#(;;Mqno&Zv*q8)yRnCNJ~&Z=S*(MFC#xO3L*YER zWcDwc$}ba8pAq;z3@zB=gB96`3RXY-xDkx%^eD2@T=|4m^n17I#Bhv{qTB`VGp<-4 zR|v7(3|u`60zy(Smz>4=NM&gcwZg@@YOY1c>=$VDI%eH!)XmaU)HF-mX!vpIyeoPx z6s8)p9+dAA7G@HZ%U@2J`dF-bJoct)5{FQC1`qpi@l88}m3;qe83s!f2iE1GnRARs z3mYjSwe(pMX-Vw)9hI)lmLf8Z+@KWxUuRSTFU3>`e60x#>kUnB2N%xf=4oyqYPuI} zh_1S@VjW8)?bDsNuXf@$-NWw5&e_pPy~Y$Xew;m{|H*{Tz$7??=E~%BbQA8>WMkJ> zSHQqCosdjzbyZ&dj<5(Ti!*dOe#)MOBQ5G^6yX(MiB=@Q%pnK=)T-m|k(9hwS4lzF z6R4zM(2u8J57}4Y6%6fqELvq9sIMxe*}K(KXktdR1#@blcttKh2rzUXRQ@depMdiZ z(*JF3yxiJC{onJgt(Pyq+Im6yzZYMB*8lw}`oGorW;m`*CZSxefHYXKU;0xPNb?p! ztEorg@Ft=9dpd-V7}ZOntHFSxkr`W>>tqhM)kiwP)e__S=FHP9b>bP^+1~(PDsKjW zc$cV>yi8$4X!t*Xt45*b5z~zzo@_>MkM_Fp*Dqf-)hyz9-KFBo zAxeh-O5N0JfVf6?aSwXNhdc)L6lFA&F^0ZPFaH)}SYIf|IhAyCFztGljt2RATO#&# z$Q)4!wxq`?I)#?2w7d$U82=G{gsdwPC9N6_P=%uSex25s^U>hCQaW?=rL$I*)`x&m zQG6~ASk>ydaN`+RQA$-gqBsVmRzy~zG-`OkfO(IizoDC-+IMKt%u|KRA6TT!vBC95 zG)fL=mMEjpMQ2zAS0YFFYjaOc2^ouvfKWyORp!7&_#zeD8@so%CkY*>Nw9CcHv=7d zwSP!7DAW)_r2F&n&f#AC{4c>5&Tgxvz=y(yI zXm`NU zL7eHnfM3iW6wX$%|FJLu%_Pk^@R!$`KI*G#Z5&2TEjMhZ<%~L;leUVt7DY5-z{oVz z;48t6CsokND7zNXxg9;x752HPx~E(hbfas9^GOVu1|<=h0GM< zTY3Lbgp1~nE&}MoagV*;VU)ISiodQQtSxG{n4^(UC`@P%zGde%c~`s02jjt*6tZ2< zYx}1$>x{!`W(yk4bq74^Jel1suBVflrQ}6xG0IUhvV@`~bj66a z)}%1^pfdgv`{-vqQuAPPr=j7ciuxtbm)sjj`GzB$Wfz$TP+n%fbvq< zY(UErA`dfNj&D>n)i#;pESio8-fAHV2HI@tvFDnWcGOlYuT7I2+5s(#sy8i8L|jRW zu?izAI4vU%11@L zvNEVdq_=YAAZ}*Tx?G~<1_ zV(r1XDYuYfoE~9trug*C=ME@2QHo50lD+T^jj4ekQ`t2B=CTJINCU=^^GSRT_npxa zu0sd=hd-zczTUv1$4-0epo@q1kO#hBwiBtuOy&1kA2jP4V4(_yHraKSF3w@owqX;lKr73uo)P#fLP| z{9_wGH}Z}7r}Wc7^Oggkd*H+{#X_K4T)>Kv2lznULWuPZg6{jBAG`4ZTmdJ%$=7%ttzzCPD(sYqW(P-+TP&ua0OG!QDDZWz zSRCeBs;CfyS|H>rv-Jx^+RFXnQe*}6l1A@)nK;#rm&qfY^-E}xj(1OhMemp4LV?xy zF3+av$3;i{u<<11Wj1s^Y(Whs|HP8P{GZey2d{&RaDdZR-X=FjDd2TTFAXA5eL8jU z%v%^&&~u@JA;%_J>umAxIChtoxI?RY40JUtXmV#)dz?L!dddpKX!+DI%XrCrb0y6L z!0THyk)@DTB=4;>5?d&{P(ko)GW52~(WbK#cQ`LQ9kta%32*~8?Igm!fnR&%EGOJVVwLzqS49}BT<*R_}~m+tdLqZfUz!x!3$w5rHFBIj~Lm; z??hwvJu!!VlpwnhIc=Al%-1GUodTELH#piixuIAPQdHj@33&Pd#3*<<7#`a~zHPS6 z-P=Fu?w%c;{L(Dx#5!JqlOmm!o)T3icS7_F^t9ypu6a6CO@CiXE6qq3_`lEp9}PFg z!;CnKhZq5^%K!ECi(?2R6Uc=s-WMDF5dQ{I{^S5MdN9vt~6Qd z6+|uBY?@_5^xL^idkNZ-$n|HQqC-Is6#$G;Z64_nD?&Je(RGr!Ihy2of0|~PY6iUs z# zvJ!5?UOd`6;{0g1UtsINxFd=5LvbmV3yw`OPc8rCOZKruLOkUZ-Sma4H@x5p;yP-S z;k(Dj$lAroMML?E?T}DcRU3s;8H|kGs-Y2RmC7sEzM95BIHw~3M|d!*ASW%Go5Z`H zU@Vp3%pE|f-Ws_~@`YW6XBSB~K*cHT!L!;nNxC(4hJy8iL<&J5mJ1~H^&E#{-Opu3 zYt5(t1kQBu!syF?hXXwiNjA04G*&IS*P}iKNLt9N1p}LUvnPSQJ(fqF&d6^}uE74l zI4~2kKHo)wklKroj>2jl4(d7C=I08@f&U@B3xqJXj{UhZ?Uxqmp6*PV;|`RlXG3GO z#%IZEhkaRlFUa?*u@*LC#%XuBJ||xjOzog= zW#$z3dNu~HR;yIkL-KSSbmuBO9NQGBp;jaT1w66_zMKsIF1r8TY({=ZL?j$sda7eM zjjCXgTM;4rgC`!~zdiG9+uj`PMKsAS^jHW#d@=L}WJtX4;xNk0u-Jc>g^A-Se zh%pxxK9uk>PS6dupVF&#v0W(+0SBL|`f)VW zK~Pu|;k|_OuU}rQF&wq<-uhsax-9dcq$ID(HK+(a3ISWR6n0PD>A@d(L-S9_CpDw4 z#T#XE zh@K-Z#(}ocl_XadP*;9@RGfafBT8_FYVyJwHtB;CrU&^>8LwoZnfJs6cyYC`gJ)t% zw9&zPHU4^)WazJ+WLcV>W8DjVfp01e^mN`ac6pq@%F5)2Ex{&;IcN{M`Rjtvcc7qL z=S^S&fd&?+$Q;}FC5Han)(m0X);Aqe^%`YE6iWuvX;`};QAZzzhb(9%(JI!d*P%u| zsn?jHW+A7iuagplBg+cF!GYPYDj~r=^F?rkaZGCv$L(?Q@o&@1tl@wL#$9oj%%8VR z%YI}52v(B_fZ5Z{hzP<+haVgEKO(qbyu&^rhz9Vy_*Iw7V`Viuvh7NG*J+#$uc)JQ zXzrp?N>@z^gRxF7H159?C$n*TIm1wo^_nD}J;$*i21za&60Z$ViW=NS!$hgq)@Jz; zQ5c*45F<>~b8)W%URDn96o}P#@yyTQe55hn^8~so$*us_4*8^B*;x=^mU^S2HNrTZ zU!}-A^wby~nDZ!m$HU&uC~fzb<5?YB;BK2yYqLNf>I9}JLWgE9v=`JDp6F< z_O$0f`^(*Ip;p%6Q`T&Xd6%MNNc9+pm!CX7BUW)#X!N)n)WqqVAhJxjB^Q8*ei&69DU#0qmm7J9_Q^o9*7ja;WlWWu!@p-7Q9m5+p)KgvbgQD+2C z*hh;G^^*Ql7_2j&%CekQHsV`-t~3a&xf8M(&or0RPvMqLcsOgI;Q_FGON^X{^6onW z78b-)F)I@@G-StVyi~@K@Vq^n&PM6L&N2BYVhHwm-jg1Jg{)Jj05~T;xoV2Ak{_il zA299C=6M_fqgu*E8@O8|;zw{4R&- z>TWm>F+0iFaM1N>u;{^E)5blT66Eb2WN+Mw7W-U%XwNy&&a)cc66`SchKf1t#9aZA z(%1jfGl0|X!TzgS({$|%dOh-J8qE{NvJM|bKkb|x?jOEk)eUxs0n;!(6)X9#P}7Cl z6>2XFk2p70-=*dnW#0XCp1FD_cyrpCK|29>sf?>^(^}LY%p2mW=Mu7z3c-3!$6V^?xgR*A%F7H2 zXdztK)5*eUx}K7b!KU)1W6lxCD>PJ%rfy7SayEc8*hZ)oz%pt@m#8sATn-z32AiH- z4d8ag+ScpjmI9pVgY2lMZgc9QyS!3O*{L}I=TZgW=9dKQVyF?MG{PX|+-(8CR90g> z+M?c_Ga#b?B#_P*^^Im^to*iCFd(o8vti$8AU_uN>_TxCBeo_E(sP|jMiy^&ev6K6 zH06&uqzgq$6k(2Xf#g5PZd87!{f7$L_s{?^E8@Rwy?nX(m(Ax}TVFkYzOlLSHO7B= z`TY53`;R}z{v#1Ti|Gi>DG-$qCqg;5(ArU1Na)aw`D73z;$hPUwRMzj1MeVZ+ssLH z@j^wBY4!79?D^RoQxHj!_O;G?TpCPXsXx2`@g~E0en4Kpca_f;Gg7IC&B(Z#^Fu8* z_Z-pXe#3z?S=Q?22luHMhv?-Bj<|9|WRD!}?ClR?%+Apxl|iip4y(z_nt`6;2qF$alQe5)@n&v3K@@h;|<@GX7q&?+gf1eD$Kq%fmX+Co6dxS zG)Vd~2fPPx#mWQv5v7irr+6;`z~xG-=~POi!YP=PN9>}gZK2&*UQGbcf69wG(b~$3 za!~Y+zoi0FYj0No47?{5`<$@{v;<&Mr)@AZyM>D3?FIJ4h=cz)b=p03>IO3vRr=YJ z_Y(=QX&%Ctca!1A==ANYXS@5aPa_I>ijrA29}HKasj2MCW^+cTXk`_yvJ3ZM_MNNm zHliPq{fQ2e$<1{F==|H;k$n6sY|Z7zb}#uZ+S=H7zD`>^lm0yY5WPy~i&45*MBgTt z{PC}ZJKEFv6*aaQXe``5nb^rq15d+Xo?^tu!QulPp>LwQ>5?ucz(Ef)CH^6iM*kUr zVm$2+2Y2C?p%h$vQ@%C;dLCzrV|jDJcN86SM8|_+5Ab@5$>u3wUUp44<8aH^ z#%mnssf;svjdyHX#cx!UV1-tnt6rrGj2;tiwhmk;%y%x)z|chZE`p1WX{`NVuo~!T zOmU6YfgHbhp(Q+=2eKJ%6dC59_RqdQdUqD>9R7mW$djGJvtPc^DI!x0hD%QG=;ws# z`I7lOnJiE&6K?Zu_hk2bXk_Qr{=xp)FL;xEy?=JtJw1(HADu)y(ecg+FuLy!c21(> zcPGb3r`>iGou-7m!%dbf?|}Bq9FgjRQUIU|chS1t zL$JzvkDfjGgg=4yuhS7`SJ1+Q9C-@uj!*dW?9;7Qprv2Kr-ogKvHomvq0;J<2Bx0Onh{T{QPL2P=QhcRl^@jq17^|`Xe6^n`8ZJ+ zT2QD23WKOF+c_$MtCFV0GO+j6$JzU8GeSuJ7yaIbhIHz?83?Spm2B zN27ujc=diq9(Qn^w#-5I$L>M&ZSpgeXy$;&5C(#ind_#TT zbeWkHeVj59l@oRzhalukf*VAjf;-_zyq_GCycRx`A40z-?tPA>xgEh_!|IgzDh4VZ z%bR-Ro-GzO_`vpdj}Bk&zhT3{T$|?Qz1uxFqI$1(PD2e_Z|~po+wYG~&raPT>xRwC z`!`JS+yZUV^Lsb<_Gs_jLH9J+q3F|@pOMa%QvdtJYcPMe+bW&5q*`#G@VQ)MBCUU2AA?7P!kO9e?nAL^ zu54Zp9Wpw;-G7{CP>b8UFTIIqC9&#sP)A<9v8_q)WeX6-4_=ikv&WV&0Ur|9=|w*;X4XRM*PqB~XkcXYP-mF{hg&ZzY7 z=F8j&aU2*A$&I621O$UQ`eF$>t z2jh+DJ-Xu359|sfd#&FUm%b-G2%&P+BP@m!6qzqa55?!2H#t2!**|;}vlW8k9~;FN z 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

    nq{KC&~*1m?*5W{qE1Jh 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�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 `Yx2G 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

      *3+Yw7=Ji%PQZ~Ah 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

      KYX9X(zYYEc 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%0Dh;!|A#pNciK5R?GBRPU13;vZ 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%0Afj@NrZ@<{e?SC`_`Mm%CJ@!9x9GSKGD;3xb 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

      {vcJ{Sg*2vQA9n?o~C0 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

      >hXvL578Dl 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%0Axe!kMm$~vRu==ll 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%0DZ#))}jAhQF1S5k|KnMC$t5y1b95Urci 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 2.1.11 doxygen openldap-devel libcmocka-devel -BuildRequires: libtdb-devel >= 1.3.14 libtevent-devel >= 0.9.36 chrpath -BuildRequires: lmdb-devel >= 0.9.16 python3-devel python3-tdb python3-talloc-devel python3-tevent -Requires: libtalloc%{?_isa} >= 2.1.11 libtdb%{?_isa} >= 1.3.14 libtevent%{?_isa} >= 0.9.36 - -Provides: bundled(libreplace) ldb-tools -Obsoletes: ldb-tools +%global with_lmdb 1 +%global with_python3 1 +%global talloc_version 2.2.0 +%global tdb_version 1.4.1 +%global tevent_version 0.10.0 + +Name: libldb +Version: 2.0.8 +Release: 1 +Summary: A schema-less, ldap like, API and database +Requires: libtalloc%{?_isa} >= %{talloc_version} +Requires: libtdb%{?_isa} >= %{tdb_version} +Requires: libtevent%{?_isa} >= %{tevent_version} +License: LGPLv3+ +URL: http://ldb.samba.org/ +Source: http://samba.org/ftp/ldb/ldb-%{version}.tar.gz + +BuildRequires: gcc libtalloc-devel >= %{talloc_version} libtdb-devel >= %{tdb_version} +BuildRequires: libtevent-devel >= %{tevent_version} lmdb-devel >= 0.9.16 popt-devel +BuildRequires: libxslt docbook-style-xsl python3-devel python3-tdb python3-talloc-devel +BuildRequires: python3-tevent doxygen openldap-devel libcmocka-devel + +Provides: bundled(libreplace) ldb-tools +Obsoletes: python2-ldb < 2.0.5-1 python2-ldb-devel < 2.0.5-1 pyldb < 1.1.26-2 ldb-tools %description -ldb is a LDAP-like embedded database and is not at all LDAP standards compliant.It provide a -fast database with an LDAP-like API designed to be used within an application. +An extensible library that implements an LDAP like API to access remote LDAP +servers, or use local tdb databases. -%package devel -Summary: Developer files for ldb -Requires: libldb%{?_isa} = %{version}-%{release} pkgconfig libtevent-devel%{?_isa} >= 0.9.36 -Requires: libtdb-devel%{?_isa} >= 1.3.14 libtalloc-devel%{?_isa} >= 2.1.11 +%package devel +Summary: Developer tools for the LDB library +Requires: libldb%{?_isa} = %{version}-%{release} libtdb-devel%{?_isa} >= %{tdb_version} +Requires: libtalloc-devel%{?_isa} >= %{talloc_version} libtevent-devel%{?_isa} >= %{tevent_version} -%description devel -Develop files for use LDB library. +%description devel +Header files needed to develop programs that link against the LDB library. -%package -n python2-ldb -Summary: Python2 bindings for ldb -Requires: libldb%{?_isa} = %{version}-%{release} python2-tdb%{?_isa} >= 1.3.14 +%package -n python-ldb-devel-common +Summary: Common development files for the Python bindings for the LDB library -Provides: pyldb = %{version}-%{release} pyldb%{?_isa} = %{version}-%{release} -Obsoletes: pyldb < 1.1.26-2 -%{?python_provide:%python_provide python2-ldb} - -%description -n python2-ldb -Python2 bindings for ldb. - -%package -n python2-ldb-devel -Summary: Develop files for python2 bindings for ldb -Requires: python2-ldb%{?_isa} = %{version}-%{release} python-ldb-devel-common%{?_isa} = %{version}-%{release} - -Provides: pyldb-devel = %{version}-%{release} pyldb-devel%{?_isa} = %{version}-%{release} -Obsoletes: pyldb-devel < 1.1.26-2 -%{?python_provide:%python_provide python2-ldb-devel} - -%description -n python2-ldb-devel -Develop files for python2 bindings for ldb. - -%package -n python-ldb-devel-common -Summary: Common develop files for python bindings for ldb - -Provides: pyldb-devel%{?_isa} = %{version}-%{release} +Provides: pyldb-devel%{?_isa} = %{version}-%{release} %{?python_provide:%python_provide python2-ldb-devel} %description -n python-ldb-devel-common -This packages provides develop files for python bindings for ldb. +Development files for the Python bindings for the LDB library. +This package includes files that aren't specific to a Python version. + +%package -n python3-ldb +Summary: Python bindings for the LDB library +Requires: libldb%{?_isa} = %{version}-%{release} python3-tdb%{?_isa} >= %{tdb_version} -%package -n python3-ldb -Summary: Python3 bindings for ldb -Requires: libldb%{?_isa} = %{version}-%{release} python3-tdb%{?_isa} >= %{tdb_version} %{?python_provide:%python_provide python3-ldb} %description -n python3-ldb -Python3 bindings for ldb. +Python bindings for the LDB library + +%package -n python3-ldb-devel +Summary: Development files for the Python bindings for the LDB library +Requires: python3-ldb%{?_isa} = %{version}-%{release} +Requires: python-ldb-devel-common%{?_isa} = %{version}-%{release} -%package -n python3-ldb-devel -Summary: Develop files for python3 bindings for ldb -Requires: python3-ldb%{?_isa} = %{version}-%{release} python-ldb-devel-common%{?_isa} = %{version}-%{release} %{?python_provide:%python_provide python3-ldb-devel} %description -n python3-ldb-devel -Develop files for the python3 bindings for ldb. +Development files for the Python bindings for the LDB library -%package help -Summary: Document files for libldb - -%description help -Document files for libldb. +%package_help %prep %autosetup -n ldb-%{version} -p1 %build -pathfix.py -n -p -i %{__python2} buildtools/bin/waf -%configure --disable-rpath --disable-rpath-install --bundled-libraries=NONE \ - --builtin-libraries=replace --with-modulesdir=%{_libdir}/ldb/modules \ - --extra-python=%{__python3} --with-privatelibdir=%{_libdir}/ldb -%make_build V=1 -doxygen Doxyfile - -%install -%make_install -find $RPM_BUILD_ROOT -name "*.so*" -exec chmod -c +x {} \; -cp -a apidocs/man/* $RPM_BUILD_ROOT/%{_mandir} +export python_LDFLAGS="" -chrpath -d $RPM_BUILD_ROOT%{_libdir}/ldb/modules/ldb/*.so* -chrpath -d $RPM_BUILD_ROOT%{_libdir}/ldb/*.so* +%configure --disable-rpath \ + --disable-rpath-install \ + --bundled-libraries=NONE \ + --builtin-libraries=replace \ + --with-modulesdir=%{_libdir}/ldb/modules \ + %{?without_lmdb_flags} \ + --with-privatelibdir=%{_libdir}/ldb -mkdir -p $RPM_BUILD_ROOT/etc/ld.so.conf.d -echo "%{_libdir}/ldb" > $RPM_BUILD_ROOT/etc/ld.so.conf.d/%{name}-%{_arch}.conf -rm -f $RPM_BUILD_ROOT%{_libdir}/libldb.a +make %{?_smp_mflags} V=1 +doxygen Doxyfile %check -%if %{?_with_check:1}%{!?_with_check:0} -%make_build check +%ifarch ppc64le +echo disabling one assertion in tests/python/repack.py +sed -e '/test_guid_indexed_v1_db/,+18{/toggle_guidindex_check_pack/d}' -i tests/python/repack.py %endif -%post -ldconfig -%post -n python2-ldb -ldconfig -%post -n python3-ldb -ldconfig -%postun -ldconfig -%postun -n python2-ldb -ldconfig -%postun -n python3-ldb -ldconfig +make %{?_smp_mflags} check + +%install +make install DESTDIR=$RPM_BUILD_ROOT +cp -a apidocs/man/* $RPM_BUILD_ROOT/%{_mandir} +rm -f $RPM_BUILD_ROOT/%{_mandir}/man3/_* + +%ldconfig_scriptlets %files +%{_bindir}/ldbadd +%{_bindir}/ldbdel +%{_bindir}/ldbedit +%{_bindir}/ldbmodify +%{_bindir}/ldbrename +%{_bindir}/ldbsearch +%dir %{_libdir}/ldb %{_libdir}/libldb.so.* -%{_libdir}/ldb/lib*.so +%{_libdir}/ldb/libldb-key-value.so +%{_libdir}/ldb/libldb-tdb-err-map.so +%{_libdir}/ldb/libldb-tdb-int.so +%{_libdir}/ldb/libldb-mdb-int.so +%dir %{_libdir}/ldb/modules +%dir %{_libdir}/ldb/modules/ldb %{_libdir}/ldb/modules/ldb/*.so -%{_bindir}/ldb* -%config(noreplace) /etc/ld.so.conf.d/* -%exclude %{_libdir}/libldb.a +%{_libdir}/ldb/libldb-cmdline.so %files devel -%{_includedir}/ldb*.h +%{_includedir}/ldb_module.h +%{_includedir}/ldb_handlers.h +%{_includedir}/ldb_errors.h +%{_includedir}/ldb_version.h +%{_includedir}/ldb.h %{_libdir}/libldb.so %{_libdir}/pkgconfig/ldb.pc -%files -n python2-ldb -%{python2_sitearch}/ldb.so -%{_libdir}/libpyldb-util.so.1* -%{python2_sitearch}/_ldb_text.py* - -%files -n python2-ldb-devel -%{_libdir}/libpyldb-util.so -%{_libdir}/pkgconfig/pyldb-util.pc - %files -n python-ldb-devel-common %{_includedir}/pyldb.h %files -n python3-ldb %{python3_sitearch}/ldb.cpython-*.so -%{_libdir}/libpyldb-util.cpython-*.so.1* +%{_libdir}/libpyldb-util.cpython-*.so.2* %{python3_sitearch}/_ldb_text.py %{python3_sitearch}/__pycache__/_ldb_text.cpython-*.py* @@ -160,14 +139,26 @@ ldconfig %{_libdir}/libpyldb-util.cpython-*.so %{_libdir}/pkgconfig/pyldb-util.cpython-*.pc +%ldconfig_scriptlets -n python3-ldb + %files help -%{_mandir}/man1/ldb*.1.* +%{_mandir}/man*/Py*.gz %{_mandir}/man3/ldb*.gz %{_mandir}/man3/ldif*.gz -%{_mandir}/man*/Py*.gz -%exclude /%{_mandir}/man3/_* +%{_mandir}/man1/ldbadd.1.* +%{_mandir}/man1/ldbdel.1.* +%{_mandir}/man1/ldbedit.1.* +%{_mandir}/man1/ldbmodify.1.* +%{_mandir}/man1/ldbrename.1.* +%{_mandir}/man1/ldbsearch.1.* %changelog +* Wed Feb 12 2020 openEuler Buildteam - 2.0.8-1 +- Type:update +- ID:NA +- SUG:NA +- DESC:update to 2.0.8 + * Thu Dec 26 2019 openEuler Buildteam - 1.4.2-3 - Type:enhancement - ID:NA -- Gitee From 7df2deff729262d401b3e70e5297792202dc06de Mon Sep 17 00:00:00 2001 From: zhanglu Date: Tue, 18 Feb 2020 15:26:18 +0800 Subject: [PATCH 2/3] update to 2.0.8 --- ldb-2.0.8/ABI/ldb-0.9.10.sigs | 218 + ldb-2.0.8/ABI/ldb-0.9.12.sigs | 219 + ldb-2.0.8/ABI/ldb-0.9.15.sigs | 226 + ldb-2.0.8/ABI/ldb-0.9.16.sigs | 228 + ldb-2.0.8/ABI/ldb-0.9.17.sigs | 229 + ldb-2.0.8/ABI/ldb-0.9.18.sigs | 240 + ldb-2.0.8/ABI/ldb-0.9.19.sigs | 245 + ldb-2.0.8/ABI/ldb-0.9.20.sigs | 245 + ldb-2.0.8/ABI/ldb-0.9.22.sigs | 245 + ldb-2.0.8/ABI/ldb-0.9.23.sigs | 247 + ldb-2.0.8/ABI/ldb-0.9.24.sigs | 248 + ldb-2.0.8/ABI/ldb-1.0.0.sigs | 248 + ldb-2.0.8/ABI/ldb-1.0.1.sigs | 248 + ldb-2.0.8/ABI/ldb-1.0.2.sigs | 250 + ldb-2.0.8/ABI/ldb-1.1.0.sigs | 253 + ldb-2.0.8/ABI/ldb-1.1.1.sigs | 254 + ldb-2.0.8/ABI/ldb-1.1.10.sigs | 259 + ldb-2.0.8/ABI/ldb-1.1.11.sigs | 259 + ldb-2.0.8/ABI/ldb-1.1.12.sigs | 260 + ldb-2.0.8/ABI/ldb-1.1.13.sigs | 260 + ldb-2.0.8/ABI/ldb-1.1.14.sigs | 262 + ldb-2.0.8/ABI/ldb-1.1.15.sigs | 262 + ldb-2.0.8/ABI/ldb-1.1.16.sigs | 262 + ldb-2.0.8/ABI/ldb-1.1.17.sigs | 262 + ldb-2.0.8/ABI/ldb-1.1.18.sigs | 262 + ldb-2.0.8/ABI/ldb-1.1.19.sigs | 263 + ldb-2.0.8/ABI/ldb-1.1.2.sigs | 256 + ldb-2.0.8/ABI/ldb-1.1.20.sigs | 263 + ldb-2.0.8/ABI/ldb-1.1.21.sigs | 263 + ldb-2.0.8/ABI/ldb-1.1.22.sigs | 264 + ldb-2.0.8/ABI/ldb-1.1.23.sigs | 264 + ldb-2.0.8/ABI/ldb-1.1.24.sigs | 264 + ldb-2.0.8/ABI/ldb-1.1.25.sigs | 265 + ldb-2.0.8/ABI/ldb-1.1.26.sigs | 265 + ldb-2.0.8/ABI/ldb-1.1.27.sigs | 266 + ldb-2.0.8/ABI/ldb-1.1.28.sigs | 266 + ldb-2.0.8/ABI/ldb-1.1.29.sigs | 268 + ldb-2.0.8/ABI/ldb-1.1.3.sigs | 256 + ldb-2.0.8/ABI/ldb-1.1.30.sigs | 272 + ldb-2.0.8/ABI/ldb-1.1.31.sigs | 274 + ldb-2.0.8/ABI/ldb-1.1.4.sigs | 256 + ldb-2.0.8/ABI/ldb-1.1.5.sigs | 257 + ldb-2.0.8/ABI/ldb-1.1.6.sigs | 258 + ldb-2.0.8/ABI/ldb-1.1.7.sigs | 258 + ldb-2.0.8/ABI/ldb-1.1.8.sigs | 258 + ldb-2.0.8/ABI/ldb-1.1.9.sigs | 258 + ldb-2.0.8/ABI/ldb-1.2.0.sigs | 276 + ldb-2.0.8/ABI/ldb-1.2.1.sigs | 276 + ldb-2.0.8/ABI/ldb-1.2.2.sigs | 277 + ldb-2.0.8/ABI/ldb-1.2.3.sigs | 277 + ldb-2.0.8/ABI/ldb-1.3.0.sigs | 279 + ldb-2.0.8/ABI/ldb-1.3.1.sigs | 279 + ldb-2.0.8/ABI/ldb-1.3.2.sigs | 279 + ldb-2.0.8/ABI/ldb-1.4.0.sigs | 279 + ldb-2.0.8/ABI/ldb-1.4.1.sigs | 279 + ldb-2.0.8/ABI/ldb-1.5.0.sigs | 279 + ldb-2.0.8/ABI/ldb-1.5.1.sigs | 280 + ldb-2.0.8/ABI/ldb-1.5.2.sigs | 280 + ldb-2.0.8/ABI/ldb-1.5.3.sigs | 280 + ldb-2.0.8/ABI/ldb-1.6.0.sigs | 280 + ldb-2.0.8/ABI/ldb-1.6.1.sigs | 280 + ldb-2.0.8/ABI/ldb-1.6.2.sigs | 280 + ldb-2.0.8/ABI/ldb-1.6.3.sigs | 280 + ldb-2.0.8/ABI/ldb-2.0.0.sigs | 280 + ldb-2.0.8/ABI/ldb-2.0.1.sigs | 280 + ldb-2.0.8/ABI/ldb-2.0.2.sigs | 281 + ldb-2.0.8/ABI/ldb-2.0.3.sigs | 281 + ldb-2.0.8/ABI/ldb-2.0.4.sigs | 282 + ldb-2.0.8/ABI/ldb-2.0.5.sigs | 283 + ldb-2.0.8/ABI/ldb-2.0.6.sigs | 283 + ldb-2.0.8/ABI/ldb-2.0.7.sigs | 283 + ldb-2.0.8/ABI/ldb-2.0.8.sigs | 283 + ldb-2.0.8/ABI/ldb-ildap-0.9.12.sigs | 224 + ldb-2.0.8/ABI/ldb-samba4-0.9.10.sigs | 223 + ldb-2.0.8/ABI/ldb-samba4-0.9.11.sigs | 224 + ldb-2.0.8/ABI/pyldb-util-1.1.10.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.11.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.12.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.13.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.14.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.15.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.16.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.17.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.18.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.19.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.2.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.20.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.21.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.22.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.23.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.24.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.25.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.26.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.27.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.28.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.29.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.3.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.30.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.31.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.4.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.5.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.6.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.7.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.8.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.1.9.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.2.0.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.2.1.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.2.2.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.2.3.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.3.0.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.3.1.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.3.2.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.4.0.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.4.1.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.5.0.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.5.1.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.5.2.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.5.3.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.6.0.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.6.1.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.6.2.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-1.6.3.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-2.0.0.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-2.0.1.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-2.0.2.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-2.0.3.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-2.0.4.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-2.0.5.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-2.0.6.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-2.0.7.sigs | 2 + ldb-2.0.8/ABI/pyldb-util-2.0.8.sigs | 2 + ldb-2.0.8/ABI/pyldb-util.py3-2.0.0.sigs | 2 + ldb-2.0.8/Doxyfile | 26 + ldb-2.0.8/Makefile | 53 + ldb-2.0.8/README_gcov.txt | 29 + ldb-2.0.8/_ldb_text.py | 146 + ldb-2.0.8/buildtools/README | 12 + ldb-2.0.8/buildtools/bin/waf | 167 + ldb-2.0.8/buildtools/compare_config_h4.sh | 12 + ldb-2.0.8/buildtools/compare_generated.sh | 50 + ldb-2.0.8/buildtools/compare_install.sh | 8 + .../buildtools/examples/run_on_target.py | 148 + ldb-2.0.8/buildtools/scripts/Makefile.waf | 72 + ldb-2.0.8/buildtools/scripts/abi_gen.sh | 21 + ldb-2.0.8/buildtools/scripts/autogen-waf.sh | 27 + ldb-2.0.8/buildtools/scripts/configure.waf | 14 + ldb-2.0.8/buildtools/testwaf.sh | 70 + ldb-2.0.8/buildtools/wafsamba/README | 8 + ldb-2.0.8/buildtools/wafsamba/__init__.py | 0 .../buildtools/wafsamba/configure_file.py | 41 + ldb-2.0.8/buildtools/wafsamba/generic_cc.py | 70 + ldb-2.0.8/buildtools/wafsamba/pkgconfig.py | 68 + ldb-2.0.8/buildtools/wafsamba/samba3.py | 105 + ldb-2.0.8/buildtools/wafsamba/samba_abi.py | 261 + .../buildtools/wafsamba/samba_autoconf.py | 948 ++++ .../buildtools/wafsamba/samba_autoproto.py | 24 + .../buildtools/wafsamba/samba_bundled.py | 274 + .../buildtools/wafsamba/samba_conftests.py | 528 ++ ldb-2.0.8/buildtools/wafsamba/samba_cross.py | 175 + ldb-2.0.8/buildtools/wafsamba/samba_deps.py | 1181 +++++ ldb-2.0.8/buildtools/wafsamba/samba_dist.py | 280 + ldb-2.0.8/buildtools/wafsamba/samba_git.py | 57 + .../buildtools/wafsamba/samba_headers.py | 181 + .../buildtools/wafsamba/samba_install.py | 236 + .../buildtools/wafsamba/samba_patterns.py | 201 + ldb-2.0.8/buildtools/wafsamba/samba_perl.py | 59 + ldb-2.0.8/buildtools/wafsamba/samba_pidl.py | 150 + ldb-2.0.8/buildtools/wafsamba/samba_python.py | 159 + .../buildtools/wafsamba/samba_third_party.py | 66 + ldb-2.0.8/buildtools/wafsamba/samba_utils.py | 763 +++ .../buildtools/wafsamba/samba_version.py | 267 + ldb-2.0.8/buildtools/wafsamba/samba_waf18.py | 431 ++ .../buildtools/wafsamba/samba_wildcard.py | 151 + ldb-2.0.8/buildtools/wafsamba/stale_files.py | 113 + ldb-2.0.8/buildtools/wafsamba/symbols.py | 659 +++ .../wafsamba/test_duplicate_symbol.sh | 12 + .../buildtools/wafsamba/tests/__init__.py | 35 + .../buildtools/wafsamba/tests/test_abi.py | 134 + .../buildtools/wafsamba/tests/test_bundled.py | 27 + .../buildtools/wafsamba/tests/test_utils.py | 76 + ldb-2.0.8/buildtools/wafsamba/wafsamba.py | 950 ++++ ldb-2.0.8/buildtools/wafsamba/wscript | 611 +++ ldb-2.0.8/common/attrib_handlers.c | 639 +++ ldb-2.0.8/common/ldb.c | 2194 ++++++++ ldb-2.0.8/common/ldb_attributes.c | 411 ++ ldb-2.0.8/common/ldb_controls.c | 1319 +++++ ldb-2.0.8/common/ldb_debug.c | 150 + ldb-2.0.8/common/ldb_dn.c | 2240 ++++++++ ldb-2.0.8/common/ldb_ldif.c | 1108 ++++ ldb-2.0.8/common/ldb_match.c | 755 +++ ldb-2.0.8/common/ldb_modules.c | 1236 +++++ ldb-2.0.8/common/ldb_msg.c | 1469 +++++ ldb-2.0.8/common/ldb_options.c | 107 + ldb-2.0.8/common/ldb_pack.c | 1261 +++++ ldb-2.0.8/common/ldb_parse.c | 974 ++++ ldb-2.0.8/common/ldb_utf8.c | 136 + ldb-2.0.8/common/qsort.c | 251 + ldb-2.0.8/configure | 21 + ldb-2.0.8/docs/builddocs.sh | 52 + ldb-2.0.8/docs/design.txt | 41 + ldb-2.0.8/docs/installdocs.sh | 17 + ldb-2.0.8/examples.dox | 16 + ldb-2.0.8/examples/ldbreader.c | 122 + ldb-2.0.8/examples/ldifreader.c | 125 + ldb-2.0.8/include/dlinklist.h | 178 + ldb-2.0.8/include/ldb.h | 2365 +++++++++ ldb-2.0.8/include/ldb_errors.h | 312 ++ ldb-2.0.8/include/ldb_handlers.h | 45 + ldb-2.0.8/include/ldb_module.h | 595 +++ ldb-2.0.8/include/ldb_private.h | 320 ++ ldb-2.0.8/ldb.pc.in | 16 + ldb-2.0.8/ldb_key_value/ldb_kv.c | 2292 ++++++++ ldb-2.0.8/ldb_key_value/ldb_kv.h | 336 ++ ldb-2.0.8/ldb_key_value/ldb_kv_cache.c | 697 +++ ldb-2.0.8/ldb_key_value/ldb_kv_index.c | 3917 ++++++++++++++ ldb-2.0.8/ldb_key_value/ldb_kv_search.c | 707 +++ ldb-2.0.8/ldb_ldap/ldb_ldap.c | 969 ++++ ldb-2.0.8/ldb_ldb/ldb_ldb.c | 80 + ldb-2.0.8/ldb_map/ldb_map.c | 1156 ++++ ldb-2.0.8/ldb_map/ldb_map.h | 174 + ldb-2.0.8/ldb_map/ldb_map_inbound.c | 846 +++ ldb-2.0.8/ldb_map/ldb_map_outbound.c | 1417 +++++ ldb-2.0.8/ldb_map/ldb_map_private.h | 96 + ldb-2.0.8/ldb_mdb/ldb_mdb.c | 1126 ++++ ldb-2.0.8/ldb_mdb/ldb_mdb.h | 60 + ldb-2.0.8/ldb_mdb/ldb_mdb_init.c | 31 + ldb-2.0.8/ldb_sqlite3/README | 7 + ldb-2.0.8/ldb_sqlite3/base160.c | 154 + ldb-2.0.8/ldb_sqlite3/ldb_sqlite3.c | 1958 +++++++ ldb-2.0.8/ldb_sqlite3/schema | 328 ++ ldb-2.0.8/ldb_sqlite3/trees.ps | 1760 ++++++ ldb-2.0.8/ldb_tdb/ldb_tdb.c | 593 +++ ldb-2.0.8/ldb_tdb/ldb_tdb.h | 16 + ldb-2.0.8/ldb_tdb/ldb_tdb_err_map.c | 84 + ldb-2.0.8/ldb_tdb/ldb_tdb_init.c | 59 + ldb-2.0.8/ldb_tdb/ldb_tdb_wrap.c | 162 + ldb-2.0.8/lib/replace/.checker_innocent | 4 + ldb-2.0.8/lib/replace/Makefile | 64 + ldb-2.0.8/lib/replace/README | 128 + ldb-2.0.8/lib/replace/closefrom.c | 138 + ldb-2.0.8/lib/replace/configure | 21 + ldb-2.0.8/lib/replace/crypt.c | 770 +++ ldb-2.0.8/lib/replace/cwrap.c | 46 + ldb-2.0.8/lib/replace/dlfcn.c | 76 + ldb-2.0.8/lib/replace/getaddrinfo.c | 493 ++ ldb-2.0.8/lib/replace/getaddrinfo.h | 91 + ldb-2.0.8/lib/replace/getifaddrs.c | 383 ++ ldb-2.0.8/lib/replace/hdr_replace.h | 2 + ldb-2.0.8/lib/replace/inet_aton.c | 33 + ldb-2.0.8/lib/replace/inet_ntoa.c | 39 + ldb-2.0.8/lib/replace/inet_ntop.c | 191 + ldb-2.0.8/lib/replace/inet_pton.c | 213 + ldb-2.0.8/lib/replace/poll.c | 139 + ldb-2.0.8/lib/replace/replace-test.h | 9 + ldb-2.0.8/lib/replace/replace-testsuite.h | 10 + ldb-2.0.8/lib/replace/replace.c | 1058 ++++ ldb-2.0.8/lib/replace/replace.h | 976 ++++ ldb-2.0.8/lib/replace/snprintf.c | 1534 ++++++ ldb-2.0.8/lib/replace/socket.c | 39 + ldb-2.0.8/lib/replace/socketpair.c | 46 + ldb-2.0.8/lib/replace/strptime.c | 995 ++++ ldb-2.0.8/lib/replace/system/README | 4 + ldb-2.0.8/lib/replace/system/aio.h | 32 + ldb-2.0.8/lib/replace/system/capability.h | 57 + ldb-2.0.8/lib/replace/system/dir.h | 71 + ldb-2.0.8/lib/replace/system/filesys.h | 242 + ldb-2.0.8/lib/replace/system/glob.h | 37 + ldb-2.0.8/lib/replace/system/gssapi.h | 53 + ldb-2.0.8/lib/replace/system/iconv.h | 57 + ldb-2.0.8/lib/replace/system/kerberos.h | 41 + ldb-2.0.8/lib/replace/system/locale.h | 42 + ldb-2.0.8/lib/replace/system/network.h | 372 ++ ldb-2.0.8/lib/replace/system/nis.h | 55 + ldb-2.0.8/lib/replace/system/passwd.h | 92 + ldb-2.0.8/lib/replace/system/readline.h | 61 + ldb-2.0.8/lib/replace/system/select.h | 81 + ldb-2.0.8/lib/replace/system/shmem.h | 59 + ldb-2.0.8/lib/replace/system/syslog.h | 70 + ldb-2.0.8/lib/replace/system/terminal.h | 46 + ldb-2.0.8/lib/replace/system/threads.h | 72 + ldb-2.0.8/lib/replace/system/time.h | 99 + ldb-2.0.8/lib/replace/system/wait.h | 55 + .../lib/replace/system/wscript_configure | 18 + ldb-2.0.8/lib/replace/tests/getifaddrs.c | 105 + ldb-2.0.8/lib/replace/tests/incoherent_mmap.c | 83 + ldb-2.0.8/lib/replace/tests/main.c | 35 + ldb-2.0.8/lib/replace/tests/os2_delete.c | 134 + ldb-2.0.8/lib/replace/tests/shared_mmap.c | 71 + ldb-2.0.8/lib/replace/tests/shared_mremap.c | 51 + ldb-2.0.8/lib/replace/tests/snprintf.c | 29 + ldb-2.0.8/lib/replace/tests/strptime.c | 173 + ldb-2.0.8/lib/replace/tests/testsuite.c | 1151 ++++ ldb-2.0.8/lib/replace/timegm.c | 78 + ldb-2.0.8/lib/replace/win32_replace.h | 159 + ldb-2.0.8/lib/replace/wscript | 955 ++++ ldb-2.0.8/lib/replace/xattr.c | 785 +++ .../lib/talloc/ABI/pytalloc-util-2.0.6.sigs | 6 + .../lib/talloc/ABI/pytalloc-util-2.0.7.sigs | 6 + .../lib/talloc/ABI/pytalloc-util-2.0.8.sigs | 6 + .../lib/talloc/ABI/pytalloc-util-2.1.0.sigs | 6 + .../lib/talloc/ABI/pytalloc-util-2.1.1.sigs | 6 + .../lib/talloc/ABI/pytalloc-util-2.1.10.sigs | 16 + .../lib/talloc/ABI/pytalloc-util-2.1.11.sigs | 16 + .../lib/talloc/ABI/pytalloc-util-2.1.12.sigs | 16 + .../lib/talloc/ABI/pytalloc-util-2.1.13.sigs | 16 + .../lib/talloc/ABI/pytalloc-util-2.1.14.sigs | 16 + .../lib/talloc/ABI/pytalloc-util-2.1.15.sigs | 16 + .../lib/talloc/ABI/pytalloc-util-2.1.16.sigs | 16 + .../lib/talloc/ABI/pytalloc-util-2.1.2.sigs | 6 + .../lib/talloc/ABI/pytalloc-util-2.1.3.sigs | 6 + .../lib/talloc/ABI/pytalloc-util-2.1.4.sigs | 6 + .../lib/talloc/ABI/pytalloc-util-2.1.5.sigs | 6 + .../lib/talloc/ABI/pytalloc-util-2.1.6.sigs | 13 + .../lib/talloc/ABI/pytalloc-util-2.1.7.sigs | 13 + .../lib/talloc/ABI/pytalloc-util-2.1.8.sigs | 13 + .../lib/talloc/ABI/pytalloc-util-2.1.9.sigs | 16 + .../lib/talloc/ABI/pytalloc-util-2.2.0.sigs | 15 + ldb-2.0.8/lib/talloc/ABI/talloc-2.0.2.sigs | 62 + ldb-2.0.8/lib/talloc/ABI/talloc-2.0.3.sigs | 62 + ldb-2.0.8/lib/talloc/ABI/talloc-2.0.4.sigs | 62 + ldb-2.0.8/lib/talloc/ABI/talloc-2.0.5.sigs | 62 + ldb-2.0.8/lib/talloc/ABI/talloc-2.0.6.sigs | 62 + ldb-2.0.8/lib/talloc/ABI/talloc-2.0.7.sigs | 62 + ldb-2.0.8/lib/talloc/ABI/talloc-2.0.8.sigs | 63 + ldb-2.0.8/lib/talloc/ABI/talloc-2.1.0.sigs | 64 + ldb-2.0.8/lib/talloc/ABI/talloc-2.1.1.sigs | 64 + ldb-2.0.8/lib/talloc/ABI/talloc-2.1.10.sigs | 65 + ldb-2.0.8/lib/talloc/ABI/talloc-2.1.11.sigs | 65 + ldb-2.0.8/lib/talloc/ABI/talloc-2.1.12.sigs | 65 + ldb-2.0.8/lib/talloc/ABI/talloc-2.1.13.sigs | 65 + ldb-2.0.8/lib/talloc/ABI/talloc-2.1.14.sigs | 65 + ldb-2.0.8/lib/talloc/ABI/talloc-2.1.15.sigs | 65 + ldb-2.0.8/lib/talloc/ABI/talloc-2.1.16.sigs | 65 + ldb-2.0.8/lib/talloc/ABI/talloc-2.1.2.sigs | 64 + ldb-2.0.8/lib/talloc/ABI/talloc-2.1.3.sigs | 64 + ldb-2.0.8/lib/talloc/ABI/talloc-2.1.4.sigs | 65 + ldb-2.0.8/lib/talloc/ABI/talloc-2.1.5.sigs | 65 + ldb-2.0.8/lib/talloc/ABI/talloc-2.1.6.sigs | 65 + ldb-2.0.8/lib/talloc/ABI/talloc-2.1.7.sigs | 65 + ldb-2.0.8/lib/talloc/ABI/talloc-2.1.8.sigs | 65 + ldb-2.0.8/lib/talloc/ABI/talloc-2.1.9.sigs | 65 + ldb-2.0.8/lib/talloc/ABI/talloc-2.2.0.sigs | 65 + ldb-2.0.8/lib/talloc/Makefile | 68 + ldb-2.0.8/lib/talloc/NEWS | 13 + ldb-2.0.8/lib/talloc/compat/talloc_compat1.c | 51 + ldb-2.0.8/lib/talloc/compat/talloc_compat1.mk | 21 + ldb-2.0.8/lib/talloc/configure | 21 + ldb-2.0.8/lib/talloc/doc/context.png | Bin 0 -> 4715 bytes ldb-2.0.8/lib/talloc/doc/context_tree.png | Bin 0 -> 6158 bytes ldb-2.0.8/lib/talloc/doc/mainpage.dox | 111 + ldb-2.0.8/lib/talloc/doc/stealing.png | Bin 0 -> 6994 bytes .../lib/talloc/doc/tutorial_bestpractices.dox | 192 + ldb-2.0.8/lib/talloc/doc/tutorial_context.dox | 198 + .../lib/talloc/doc/tutorial_debugging.dox | 116 + .../lib/talloc/doc/tutorial_destructors.dox | 82 + ldb-2.0.8/lib/talloc/doc/tutorial_dts.dox | 109 + .../lib/talloc/doc/tutorial_introduction.dox | 45 + ldb-2.0.8/lib/talloc/doc/tutorial_pools.dox | 93 + .../lib/talloc/doc/tutorial_stealing.dox | 55 + ldb-2.0.8/lib/talloc/doc/tutorial_threads.dox | 203 + ldb-2.0.8/lib/talloc/doxy.config | 1807 +++++++ ldb-2.0.8/lib/talloc/man/talloc.3.xml | 814 +++ ldb-2.0.8/lib/talloc/pytalloc-util.pc.in | 11 + ldb-2.0.8/lib/talloc/pytalloc.c | 309 ++ ldb-2.0.8/lib/talloc/pytalloc.h | 79 + ldb-2.0.8/lib/talloc/pytalloc_guide.txt | 252 + ldb-2.0.8/lib/talloc/pytalloc_private.h | 26 + ldb-2.0.8/lib/talloc/pytalloc_util.c | 333 ++ ldb-2.0.8/lib/talloc/talloc.c | 3050 +++++++++++ ldb-2.0.8/lib/talloc/talloc.h | 1945 +++++++ ldb-2.0.8/lib/talloc/talloc.pc.in | 11 + ldb-2.0.8/lib/talloc/talloc_guide.txt | 768 +++ ldb-2.0.8/lib/talloc/talloc_testsuite.h | 7 + ldb-2.0.8/lib/talloc/test_magic_differs.sh | 16 + .../lib/talloc/test_magic_differs_helper.c | 12 + ldb-2.0.8/lib/talloc/test_pytalloc.c | 244 + ldb-2.0.8/lib/talloc/test_pytalloc.py | 189 + ldb-2.0.8/lib/talloc/testsuite.c | 2169 ++++++++ ldb-2.0.8/lib/talloc/testsuite_main.c | 36 + ldb-2.0.8/lib/talloc/web/index.html | 51 + ldb-2.0.8/lib/talloc/wscript | 198 + ldb-2.0.8/lib/tdb/ABI/tdb-1.2.1.sigs | 95 + ldb-2.0.8/lib/tdb/ABI/tdb-1.2.10.sigs | 66 + ldb-2.0.8/lib/tdb/ABI/tdb-1.2.11.sigs | 67 + ldb-2.0.8/lib/tdb/ABI/tdb-1.2.12.sigs | 67 + ldb-2.0.8/lib/tdb/ABI/tdb-1.2.13.sigs | 67 + ldb-2.0.8/lib/tdb/ABI/tdb-1.2.2.sigs | 60 + ldb-2.0.8/lib/tdb/ABI/tdb-1.2.3.sigs | 60 + ldb-2.0.8/lib/tdb/ABI/tdb-1.2.4.sigs | 60 + ldb-2.0.8/lib/tdb/ABI/tdb-1.2.5.sigs | 61 + ldb-2.0.8/lib/tdb/ABI/tdb-1.2.6.sigs | 61 + ldb-2.0.8/lib/tdb/ABI/tdb-1.2.7.sigs | 61 + ldb-2.0.8/lib/tdb/ABI/tdb-1.2.8.sigs | 61 + ldb-2.0.8/lib/tdb/ABI/tdb-1.2.9.sigs | 62 + ldb-2.0.8/lib/tdb/ABI/tdb-1.3.0.sigs | 68 + ldb-2.0.8/lib/tdb/ABI/tdb-1.3.1.sigs | 68 + ldb-2.0.8/lib/tdb/ABI/tdb-1.3.10.sigs | 69 + ldb-2.0.8/lib/tdb/ABI/tdb-1.3.11.sigs | 70 + ldb-2.0.8/lib/tdb/ABI/tdb-1.3.12.sigs | 70 + ldb-2.0.8/lib/tdb/ABI/tdb-1.3.13.sigs | 70 + ldb-2.0.8/lib/tdb/ABI/tdb-1.3.14.sigs | 71 + ldb-2.0.8/lib/tdb/ABI/tdb-1.3.15.sigs | 71 + ldb-2.0.8/lib/tdb/ABI/tdb-1.3.16.sigs | 71 + ldb-2.0.8/lib/tdb/ABI/tdb-1.3.17.sigs | 73 + ldb-2.0.8/lib/tdb/ABI/tdb-1.3.18.sigs | 73 + ldb-2.0.8/lib/tdb/ABI/tdb-1.3.2.sigs | 68 + ldb-2.0.8/lib/tdb/ABI/tdb-1.3.3.sigs | 68 + ldb-2.0.8/lib/tdb/ABI/tdb-1.3.4.sigs | 68 + ldb-2.0.8/lib/tdb/ABI/tdb-1.3.5.sigs | 69 + ldb-2.0.8/lib/tdb/ABI/tdb-1.3.6.sigs | 69 + ldb-2.0.8/lib/tdb/ABI/tdb-1.3.7.sigs | 69 + ldb-2.0.8/lib/tdb/ABI/tdb-1.3.8.sigs | 69 + ldb-2.0.8/lib/tdb/ABI/tdb-1.3.9.sigs | 69 + ldb-2.0.8/lib/tdb/ABI/tdb-1.4.0.sigs | 73 + ldb-2.0.8/lib/tdb/ABI/tdb-1.4.1.sigs | 73 + ldb-2.0.8/lib/tdb/ABI/tdb-1.4.2.sigs | 73 + ldb-2.0.8/lib/tdb/Makefile | 68 + ldb-2.0.8/lib/tdb/_tdb_text.py | 137 + ldb-2.0.8/lib/tdb/common/check.c | 489 ++ ldb-2.0.8/lib/tdb/common/dump.c | 149 + ldb-2.0.8/lib/tdb/common/error.c | 57 + ldb-2.0.8/lib/tdb/common/freelist.c | 747 +++ ldb-2.0.8/lib/tdb/common/freelistcheck.c | 107 + ldb-2.0.8/lib/tdb/common/hash.c | 345 ++ ldb-2.0.8/lib/tdb/common/io.c | 806 +++ ldb-2.0.8/lib/tdb/common/lock.c | 1031 ++++ ldb-2.0.8/lib/tdb/common/mutex.c | 1077 ++++ ldb-2.0.8/lib/tdb/common/open.c | 962 ++++ ldb-2.0.8/lib/tdb/common/rescue.c | 351 ++ ldb-2.0.8/lib/tdb/common/summary.c | 219 + ldb-2.0.8/lib/tdb/common/tdb.c | 1324 +++++ ldb-2.0.8/lib/tdb/common/tdb_private.h | 370 ++ ldb-2.0.8/lib/tdb/common/transaction.c | 1387 +++++ ldb-2.0.8/lib/tdb/common/traverse.c | 510 ++ ldb-2.0.8/lib/tdb/configure | 21 + ldb-2.0.8/lib/tdb/docs/README | 273 + ldb-2.0.8/lib/tdb/docs/mainpage.dox | 61 + ldb-2.0.8/lib/tdb/docs/mutex.txt | 136 + ldb-2.0.8/lib/tdb/docs/tdb.magic | 10 + ldb-2.0.8/lib/tdb/docs/tracing.txt | 46 + ldb-2.0.8/lib/tdb/doxy.config | 1697 ++++++ ldb-2.0.8/lib/tdb/include/tdb.h | 1025 ++++ ldb-2.0.8/lib/tdb/man/tdbbackup.8.xml | 157 + ldb-2.0.8/lib/tdb/man/tdbdump.8.xml | 93 + ldb-2.0.8/lib/tdb/man/tdbrestore.8.xml | 67 + ldb-2.0.8/lib/tdb/man/tdbtool.8.xml | 275 + ldb-2.0.8/lib/tdb/pytdb.c | 830 +++ ldb-2.0.8/lib/tdb/python/tdbdump.py | 13 + ldb-2.0.8/lib/tdb/python/tests/simple.py | 311 ++ ldb-2.0.8/lib/tdb/tdb.pc.in | 11 + ldb-2.0.8/lib/tdb/test/circular_chain.tdb | Bin 0 -> 272 bytes ldb-2.0.8/lib/tdb/test/circular_freelist.tdb | Bin 0 -> 400 bytes ldb-2.0.8/lib/tdb/test/external-agent.c | 224 + ldb-2.0.8/lib/tdb/test/external-agent.h | 44 + ldb-2.0.8/lib/tdb/test/jenkins-be-hash.tdb | Bin 0 -> 696 bytes ldb-2.0.8/lib/tdb/test/jenkins-le-hash.tdb | Bin 0 -> 696 bytes ldb-2.0.8/lib/tdb/test/lock-tracking.c | 157 + ldb-2.0.8/lib/tdb/test/lock-tracking.h | 25 + ldb-2.0.8/lib/tdb/test/logging.c | 33 + ldb-2.0.8/lib/tdb/test/logging.h | 11 + ldb-2.0.8/lib/tdb/test/old-nohash-be.tdb | Bin 0 -> 696 bytes ldb-2.0.8/lib/tdb/test/old-nohash-le.tdb | Bin 0 -> 696 bytes ldb-2.0.8/lib/tdb/test/run-3G-file.c | 145 + .../test/run-allrecord-traverse-deadlock.c | 203 + ldb-2.0.8/lib/tdb/test/run-bad-tdb-header.c | 59 + ldb-2.0.8/lib/tdb/test/run-check.c | 65 + ldb-2.0.8/lib/tdb/test/run-circular-chain.c | 42 + .../lib/tdb/test/run-circular-freelist.c | 50 + ldb-2.0.8/lib/tdb/test/run-corrupt.c | 132 + .../lib/tdb/test/run-die-during-transaction.c | 232 + ldb-2.0.8/lib/tdb/test/run-endian.c | 64 + ldb-2.0.8/lib/tdb/test/run-fcntl-deadlock.c | 202 + ldb-2.0.8/lib/tdb/test/run-incompatible.c | 188 + .../lib/tdb/test/run-marklock-deadlock.c | 278 + .../lib/tdb/test/run-mutex-allrecord-bench.c | 82 + .../lib/tdb/test/run-mutex-allrecord-block.c | 120 + .../tdb/test/run-mutex-allrecord-trylock.c | 113 + ldb-2.0.8/lib/tdb/test/run-mutex-die.c | 269 + ldb-2.0.8/lib/tdb/test/run-mutex-openflags2.c | 146 + .../lib/tdb/test/run-mutex-transaction1.c | 236 + ldb-2.0.8/lib/tdb/test/run-mutex-trylock.c | 122 + ldb-2.0.8/lib/tdb/test/run-mutex1.c | 138 + .../lib/tdb/test/run-nested-transactions.c | 79 + ldb-2.0.8/lib/tdb/test/run-nested-traverse.c | 111 + .../tdb/test/run-no-lock-during-traverse.c | 114 + ldb-2.0.8/lib/tdb/test/run-oldhash.c | 50 + .../tdb/test/run-open-during-transaction.c | 183 + ldb-2.0.8/lib/tdb/test/run-rdlock-upgrade.c | 166 + ldb-2.0.8/lib/tdb/test/run-readonly-check.c | 53 + .../lib/tdb/test/run-rescue-find_entry.c | 51 + ldb-2.0.8/lib/tdb/test/run-rescue.c | 127 + ldb-2.0.8/lib/tdb/test/run-rwlock-check.c | 46 + ldb-2.0.8/lib/tdb/test/run-summary.c | 65 + .../lib/tdb/test/run-transaction-expand.c | 125 + ldb-2.0.8/lib/tdb/test/run-traverse-chain.c | 94 + .../tdb/test/run-traverse-in-transaction.c | 90 + ldb-2.0.8/lib/tdb/test/run-wronghash-fail.c | 121 + ldb-2.0.8/lib/tdb/test/run-zero-append.c | 41 + ldb-2.0.8/lib/tdb/test/run.c | 50 + ldb-2.0.8/lib/tdb/test/rwlock-be.tdb | Bin 0 -> 696 bytes ldb-2.0.8/lib/tdb/test/rwlock-le.tdb | Bin 0 -> 696 bytes ldb-2.0.8/lib/tdb/test/sample_tdb.tdb | Bin 0 -> 8192 bytes ldb-2.0.8/lib/tdb/test/tap-interface.h | 58 + ldb-2.0.8/lib/tdb/test/tap-to-subunit.h | 155 + ldb-2.0.8/lib/tdb/test/tdb.corrupt | Bin 0 -> 192512 bytes ldb-2.0.8/lib/tdb/test/test_tdbbackup.sh | 54 + ldb-2.0.8/lib/tdb/tools/tdbbackup.c | 370 ++ ldb-2.0.8/lib/tdb/tools/tdbdump.c | 181 + ldb-2.0.8/lib/tdb/tools/tdbrestore.c | 222 + ldb-2.0.8/lib/tdb/tools/tdbtest.c | 290 + ldb-2.0.8/lib/tdb/tools/tdbtool.c | 944 ++++ ldb-2.0.8/lib/tdb/tools/tdbtorture.c | 501 ++ ldb-2.0.8/lib/tdb/web/index.html | 48 + ldb-2.0.8/lib/tdb/wscript | 259 + ldb-2.0.8/lib/tevent/ABI/tevent-0.10.0.sigs | 126 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.10.sigs | 73 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.11.sigs | 73 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.12.sigs | 74 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.13.sigs | 75 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.14.sigs | 78 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.15.sigs | 78 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.16.sigs | 82 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.17.sigs | 82 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.18.sigs | 83 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.19.sigs | 83 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.20.sigs | 87 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.21.sigs | 88 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.22.sigs | 88 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.23.sigs | 88 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.24.sigs | 88 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.25.sigs | 88 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.26.sigs | 90 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.27.sigs | 90 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.28.sigs | 90 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.29.sigs | 90 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.30.sigs | 96 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.31.sigs | 99 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.32.sigs | 99 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.33.sigs | 99 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.34.sigs | 99 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.35.sigs | 99 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.36.sigs | 100 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.37.sigs | 126 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.38.sigs | 126 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.39.sigs | 126 + ldb-2.0.8/lib/tevent/ABI/tevent-0.9.9.sigs | 73 + ldb-2.0.8/lib/tevent/Makefile | 52 + ldb-2.0.8/lib/tevent/bindings.py | 116 + ldb-2.0.8/lib/tevent/configure | 21 + .../doc/img/tevent_context_stucture.png | Bin 0 -> 21888 bytes .../lib/tevent/doc/img/tevent_subrequest.png | Bin 0 -> 22453 bytes ldb-2.0.8/lib/tevent/doc/mainpage.dox | 47 + ldb-2.0.8/lib/tevent/doc/tevent_context.dox | 75 + ldb-2.0.8/lib/tevent/doc/tevent_data.dox | 137 + ldb-2.0.8/lib/tevent/doc/tevent_events.dox | 341 ++ ldb-2.0.8/lib/tevent/doc/tevent_queue.dox | 275 + ldb-2.0.8/lib/tevent/doc/tevent_request.dox | 189 + ldb-2.0.8/lib/tevent/doc/tevent_thread.dox | 322 ++ ldb-2.0.8/lib/tevent/doc/tevent_tutorial.dox | 22 + ldb-2.0.8/lib/tevent/doc/tutorials.dox | 43 + ldb-2.0.8/lib/tevent/doxy.config | 1908 +++++++ ldb-2.0.8/lib/tevent/echo_server.c | 667 +++ ldb-2.0.8/lib/tevent/pytevent.c | 945 ++++ ldb-2.0.8/lib/tevent/test_req.c | 288 + ldb-2.0.8/lib/tevent/testsuite.c | 1821 +++++++ ldb-2.0.8/lib/tevent/tevent.c | 1037 ++++ ldb-2.0.8/lib/tevent/tevent.h | 2511 +++++++++ ldb-2.0.8/lib/tevent/tevent.pc.in | 12 + ldb-2.0.8/lib/tevent/tevent.py | 28 + ldb-2.0.8/lib/tevent/tevent_debug.c | 135 + ldb-2.0.8/lib/tevent/tevent_epoll.c | 956 ++++ ldb-2.0.8/lib/tevent/tevent_fd.c | 161 + ldb-2.0.8/lib/tevent/tevent_immediate.c | 210 + ldb-2.0.8/lib/tevent/tevent_internal.h | 471 ++ ldb-2.0.8/lib/tevent/tevent_liboop.c | 292 + ldb-2.0.8/lib/tevent/tevent_poll.c | 663 +++ ldb-2.0.8/lib/tevent/tevent_port.c | 803 +++ ldb-2.0.8/lib/tevent/tevent_queue.c | 370 ++ ldb-2.0.8/lib/tevent/tevent_req.c | 570 ++ ldb-2.0.8/lib/tevent/tevent_signal.c | 518 ++ ldb-2.0.8/lib/tevent/tevent_standard.c | 238 + ldb-2.0.8/lib/tevent/tevent_threads.c | 601 +++ ldb-2.0.8/lib/tevent/tevent_timed.c | 449 ++ ldb-2.0.8/lib/tevent/tevent_util.c | 107 + ldb-2.0.8/lib/tevent/tevent_util.h | 185 + ldb-2.0.8/lib/tevent/tevent_wakeup.c | 67 + ldb-2.0.8/lib/tevent/tevent_wrapper.c | 571 ++ ldb-2.0.8/lib/tevent/wscript | 142 + ldb-2.0.8/lib/util/attr.h | 101 + ldb-2.0.8/lib/util/binsearch.h | 121 + ldb-2.0.8/mainpage.dox | 80 + ldb-2.0.8/man/ldb.3.xml | 265 + ldb-2.0.8/man/ldbadd.1.xml | 108 + ldb-2.0.8/man/ldbdel.1.xml | 108 + ldb-2.0.8/man/ldbedit.1.xml | 203 + ldb-2.0.8/man/ldbmodify.1.xml | 96 + ldb-2.0.8/man/ldbrename.1.xml | 110 + ldb-2.0.8/man/ldbsearch.1.xml | 122 + ldb-2.0.8/modules/asq.c | 416 ++ ldb-2.0.8/modules/paged_searches.c | 391 ++ ldb-2.0.8/modules/rdn_name.c | 610 +++ ldb-2.0.8/modules/skel.c | 147 + ldb-2.0.8/modules/sort.c | 402 ++ ldb-2.0.8/nssldb/README.txt | 34 + ldb-2.0.8/nssldb/ldb-grp.c | 429 ++ ldb-2.0.8/nssldb/ldb-nss.c | 395 ++ ldb-2.0.8/nssldb/ldb-nss.h | 84 + ldb-2.0.8/nssldb/ldb-pwd.c | 242 + ldb-2.0.8/pyldb-util.pc.in | 13 + ldb-2.0.8/pyldb.c | 4470 ++++++++++++++++ ldb-2.0.8/pyldb.h | 109 + ldb-2.0.8/pyldb_util.c | 113 + ldb-2.0.8/tests/guidindexpackv1.ldb | Bin 0 -> 1286144 bytes ldb-2.0.8/tests/init.ldif | 41 + ldb-2.0.8/tests/init_slapd.sh | 41 + ldb-2.0.8/tests/kill_slapd.sh | 12 + ldb-2.0.8/tests/ldapi_url.sh | 11 + ldb-2.0.8/tests/ldb_filter_attrs_test.c | 988 ++++ .../ldb_key_value_sub_txn_mdb_test.valgrind | 97 + ldb-2.0.8/tests/ldb_key_value_sub_txn_test.c | 843 +++ ldb-2.0.8/tests/ldb_key_value_test.c | 388 ++ ldb-2.0.8/tests/ldb_kv_ops_test.c | 1804 +++++++ ldb-2.0.8/tests/ldb_kv_ops_test.valgrind | 97 + ldb-2.0.8/tests/ldb_lmdb_size_test.c | 210 + ldb-2.0.8/tests/ldb_lmdb_test.c | 589 ++ ldb-2.0.8/tests/ldb_match_test.c | 191 + ldb-2.0.8/tests/ldb_match_test.valgrind | 16 + ldb-2.0.8/tests/ldb_mod_op_test.c | 4721 +++++++++++++++++ ldb-2.0.8/tests/ldb_msg.c | 380 ++ ldb-2.0.8/tests/ldb_no_lmdb_test.c | 158 + ldb-2.0.8/tests/ldb_parse_test.c | 93 + ldb-2.0.8/tests/ldb_tdb_test.c | 389 ++ ldb-2.0.8/tests/photo.ldif | 5 + ldb-2.0.8/tests/python/api.py | 3326 ++++++++++++ ldb-2.0.8/tests/python/index.py | 1455 +++++ ldb-2.0.8/tests/python/repack.py | 204 + ldb-2.0.8/tests/samba4.png | Bin 0 -> 6239 bytes ldb-2.0.8/tests/sample_module.c | 122 + .../tests/schema-tests/schema-add-test.ldif | 66 + .../tests/schema-tests/schema-mod-test-1.ldif | 5 + .../tests/schema-tests/schema-mod-test-2.ldif | 5 + .../tests/schema-tests/schema-mod-test-3.ldif | 5 + .../tests/schema-tests/schema-mod-test-4.ldif | 5 + .../tests/schema-tests/schema-mod-test-5.ldif | 5 + ldb-2.0.8/tests/schema-tests/schema.ldif | 100 + ldb-2.0.8/tests/slapd.conf | 26 + ldb-2.0.8/tests/start_slapd.sh | 14 + ldb-2.0.8/tests/test-attribs.ldif | 6 + ldb-2.0.8/tests/test-config.ldif | 67 + ldb-2.0.8/tests/test-controls.sh | 43 + ldb-2.0.8/tests/test-default-config.ldif | 17 + ldb-2.0.8/tests/test-dup-2.ldif | 6 + ldb-2.0.8/tests/test-dup.ldif | 13 + ldb-2.0.8/tests/test-extended.sh | 69 + ldb-2.0.8/tests/test-generic.sh | 157 + ldb-2.0.8/tests/test-index.ldif | 7 + ldb-2.0.8/tests/test-ldap.sh | 54 + ldb-2.0.8/tests/test-modify-modrdn.ldif | 12 + ldb-2.0.8/tests/test-modify-unmet-2.ldif | 7 + ldb-2.0.8/tests/test-modify-unmet.ldif | 15 + ldb-2.0.8/tests/test-modify.ldif | 23 + ldb-2.0.8/tests/test-schema.sh | 34 + ldb-2.0.8/tests/test-soloading.sh | 32 + ldb-2.0.8/tests/test-sqlite3.sh | 25 + ldb-2.0.8/tests/test-tdb-features.sh | 178 + ldb-2.0.8/tests/test-tdb-subunit.sh | 7 + ldb-2.0.8/tests/test-tdb.sh | 38 + ldb-2.0.8/tests/test-wildcard.ldif | 5 + ldb-2.0.8/tests/test-wrong_attributes.ldif | 3 + ldb-2.0.8/tests/test.ldif | 440 ++ ldb-2.0.8/tests/test_ldb_dn.c | 232 + ldb-2.0.8/tests/test_ldb_qsort.c | 65 + ldb-2.0.8/tests/testdata.txt | 8 + ldb-2.0.8/tests/testsearch.txt | 5 + ldb-2.0.8/third_party/cmocka/cmocka.c | 3431 ++++++++++++ ldb-2.0.8/third_party/cmocka/cmocka.h | 2298 ++++++++ ldb-2.0.8/third_party/cmocka/cmocka_private.h | 163 + ldb-2.0.8/third_party/cmocka/wscript | 24 + ldb-2.0.8/third_party/popt/CHANGES | 46 + ldb-2.0.8/third_party/popt/COPYING | 22 + ldb-2.0.8/third_party/popt/README | 16 + ldb-2.0.8/third_party/popt/findme.h | 20 + ldb-2.0.8/third_party/popt/lookup3.c | 969 ++++ ldb-2.0.8/third_party/popt/popt.c | 1787 +++++++ ldb-2.0.8/third_party/popt/popt.h | 744 +++ ldb-2.0.8/third_party/popt/poptconfig.c | 582 ++ ldb-2.0.8/third_party/popt/popthelp.c | 925 ++++ ldb-2.0.8/third_party/popt/poptint.c | 199 + ldb-2.0.8/third_party/popt/poptint.h | 222 + ldb-2.0.8/third_party/popt/poptparse.c | 230 + ldb-2.0.8/third_party/popt/system.h | 103 + ldb-2.0.8/third_party/popt/wscript | 24 + ldb-2.0.8/third_party/waf/waflib/Build.py | 1512 ++++++ ldb-2.0.8/third_party/waf/waflib/ConfigSet.py | 361 ++ ldb-2.0.8/third_party/waf/waflib/Configure.py | 649 +++ ldb-2.0.8/third_party/waf/waflib/Context.py | 737 +++ ldb-2.0.8/third_party/waf/waflib/Errors.py | 68 + ldb-2.0.8/third_party/waf/waflib/Logs.py | 382 ++ ldb-2.0.8/third_party/waf/waflib/Node.py | 969 ++++ ldb-2.0.8/third_party/waf/waflib/Options.py | 342 ++ ldb-2.0.8/third_party/waf/waflib/Runner.py | 622 +++ ldb-2.0.8/third_party/waf/waflib/Scripting.py | 625 +++ ldb-2.0.8/third_party/waf/waflib/Task.py | 1406 +++++ ldb-2.0.8/third_party/waf/waflib/TaskGen.py | 917 ++++ .../third_party/waf/waflib/Tools/__init__.py | 3 + ldb-2.0.8/third_party/waf/waflib/Tools/ar.py | 24 + ldb-2.0.8/third_party/waf/waflib/Tools/asm.py | 108 + .../third_party/waf/waflib/Tools/bison.py | 49 + ldb-2.0.8/third_party/waf/waflib/Tools/c.py | 39 + .../third_party/waf/waflib/Tools/c_aliases.py | 146 + .../third_party/waf/waflib/Tools/c_config.py | 1352 +++++ .../third_party/waf/waflib/Tools/c_osx.py | 193 + .../third_party/waf/waflib/Tools/c_preproc.py | 1091 ++++ .../third_party/waf/waflib/Tools/c_tests.py | 230 + .../third_party/waf/waflib/Tools/ccroot.py | 791 +++ .../third_party/waf/waflib/Tools/clang.py | 29 + .../third_party/waf/waflib/Tools/clangxx.py | 30 + .../waf/waflib/Tools/compiler_c.py | 110 + .../waf/waflib/Tools/compiler_cxx.py | 111 + .../waf/waflib/Tools/compiler_d.py | 85 + .../waf/waflib/Tools/compiler_fc.py | 73 + ldb-2.0.8/third_party/waf/waflib/Tools/cs.py | 211 + ldb-2.0.8/third_party/waf/waflib/Tools/cxx.py | 40 + ldb-2.0.8/third_party/waf/waflib/Tools/d.py | 97 + .../third_party/waf/waflib/Tools/d_config.py | 64 + .../third_party/waf/waflib/Tools/d_scan.py | 211 + .../third_party/waf/waflib/Tools/dbus.py | 70 + ldb-2.0.8/third_party/waf/waflib/Tools/dmd.py | 80 + .../third_party/waf/waflib/Tools/errcheck.py | 237 + ldb-2.0.8/third_party/waf/waflib/Tools/fc.py | 203 + .../third_party/waf/waflib/Tools/fc_config.py | 488 ++ .../third_party/waf/waflib/Tools/fc_scan.py | 120 + .../third_party/waf/waflib/Tools/flex.py | 62 + ldb-2.0.8/third_party/waf/waflib/Tools/g95.py | 66 + ldb-2.0.8/third_party/waf/waflib/Tools/gas.py | 19 + ldb-2.0.8/third_party/waf/waflib/Tools/gcc.py | 156 + ldb-2.0.8/third_party/waf/waflib/Tools/gdc.py | 55 + .../third_party/waf/waflib/Tools/gfortran.py | 93 + .../third_party/waf/waflib/Tools/glib2.py | 489 ++ .../third_party/waf/waflib/Tools/gnu_dirs.py | 131 + ldb-2.0.8/third_party/waf/waflib/Tools/gxx.py | 157 + ldb-2.0.8/third_party/waf/waflib/Tools/icc.py | 30 + .../third_party/waf/waflib/Tools/icpc.py | 30 + .../third_party/waf/waflib/Tools/ifort.py | 413 ++ .../third_party/waf/waflib/Tools/intltool.py | 231 + .../third_party/waf/waflib/Tools/irixcc.py | 66 + .../third_party/waf/waflib/Tools/javaw.py | 593 +++ .../third_party/waf/waflib/Tools/ldc2.py | 56 + ldb-2.0.8/third_party/waf/waflib/Tools/lua.py | 38 + .../waf/waflib/Tools/md5_tstamp.py | 41 + .../third_party/waf/waflib/Tools/msvc.py | 1020 ++++ .../third_party/waf/waflib/Tools/nasm.py | 31 + .../third_party/waf/waflib/Tools/nobuild.py | 24 + .../third_party/waf/waflib/Tools/perl.py | 156 + .../third_party/waf/waflib/Tools/python.py | 644 +++ ldb-2.0.8/third_party/waf/waflib/Tools/qt5.py | 800 +++ .../third_party/waf/waflib/Tools/ruby.py | 186 + .../third_party/waf/waflib/Tools/suncc.py | 67 + .../third_party/waf/waflib/Tools/suncxx.py | 67 + ldb-2.0.8/third_party/waf/waflib/Tools/tex.py | 543 ++ .../third_party/waf/waflib/Tools/vala.py | 355 ++ .../waf/waflib/Tools/waf_unit_test.py | 296 ++ .../third_party/waf/waflib/Tools/winres.py | 78 + ldb-2.0.8/third_party/waf/waflib/Tools/xlc.py | 65 + .../third_party/waf/waflib/Tools/xlcxx.py | 65 + ldb-2.0.8/third_party/waf/waflib/Utils.py | 1035 ++++ ldb-2.0.8/third_party/waf/waflib/__init__.py | 3 + ldb-2.0.8/third_party/waf/waflib/ansiterm.py | 342 ++ .../third_party/waf/waflib/extras/__init__.py | 3 + .../waf/waflib/extras/batched_cc.py | 173 + .../third_party/waf/waflib/extras/biber.py | 58 + .../third_party/waf/waflib/extras/bjam.py | 128 + .../third_party/waf/waflib/extras/blender.py | 108 + .../third_party/waf/waflib/extras/boo.py | 81 + .../third_party/waf/waflib/extras/boost.py | 525 ++ .../waf/waflib/extras/build_file_tracker.py | 28 + .../waf/waflib/extras/build_logs.py | 110 + .../waf/waflib/extras/buildcopy.py | 85 + .../third_party/waf/waflib/extras/c_bgxlc.py | 32 + .../waf/waflib/extras/c_dumbpreproc.py | 72 + .../waf/waflib/extras/c_emscripten.py | 87 + .../third_party/waf/waflib/extras/c_nec.py | 74 + .../third_party/waf/waflib/extras/cabal.py | 152 + .../waf/waflib/extras/cfg_altoptions.py | 110 + .../extras/clang_compilation_database.py | 85 + .../waf/waflib/extras/clang_cross.py | 92 + .../waf/waflib/extras/clang_cross_common.py | 113 + .../waf/waflib/extras/clangxx_cross.py | 106 + .../third_party/waf/waflib/extras/codelite.py | 875 +++ .../waf/waflib/extras/color_gcc.py | 39 + .../waf/waflib/extras/color_msvc.py | 59 + .../waf/waflib/extras/color_rvct.py | 51 + .../third_party/waf/waflib/extras/compat15.py | 406 ++ .../third_party/waf/waflib/extras/cppcheck.py | 591 +++ .../third_party/waf/waflib/extras/cpplint.py | 209 + .../waf/waflib/extras/cross_gnu.py | 227 + .../third_party/waf/waflib/extras/cython.py | 147 + .../third_party/waf/waflib/extras/dcc.py | 72 + .../third_party/waf/waflib/extras/distnet.py | 430 ++ .../third_party/waf/waflib/extras/doxygen.py | 235 + .../third_party/waf/waflib/extras/dpapi.py | 87 + .../third_party/waf/waflib/extras/eclipse.py | 431 ++ .../third_party/waf/waflib/extras/erlang.py | 110 + .../waf/waflib/extras/fast_partial.py | 531 ++ .../third_party/waf/waflib/extras/fc_bgxlf.py | 32 + .../third_party/waf/waflib/extras/fc_cray.py | 51 + .../third_party/waf/waflib/extras/fc_nag.py | 61 + .../third_party/waf/waflib/extras/fc_nec.py | 60 + .../third_party/waf/waflib/extras/fc_nfort.py | 52 + .../waf/waflib/extras/fc_open64.py | 58 + .../waf/waflib/extras/fc_pgfortran.py | 68 + .../waf/waflib/extras/fc_solstudio.py | 62 + .../third_party/waf/waflib/extras/fc_xlf.py | 63 + .../waf/waflib/extras/file_to_object.py | 137 + .../third_party/waf/waflib/extras/fluid.py | 30 + .../waf/waflib/extras/freeimage.py | 74 + .../third_party/waf/waflib/extras/fsb.py | 31 + .../third_party/waf/waflib/extras/fsc.py | 64 + .../third_party/waf/waflib/extras/gccdeps.py | 214 + .../third_party/waf/waflib/extras/gdbus.py | 87 + .../waf/waflib/extras/genpybind.py | 194 + .../third_party/waf/waflib/extras/gob2.py | 17 + .../third_party/waf/waflib/extras/halide.py | 151 + .../third_party/waf/waflib/extras/javatest.py | 118 + .../third_party/waf/waflib/extras/kde4.py | 93 + .../waf/waflib/extras/local_rpath.py | 21 + .../third_party/waf/waflib/extras/make.py | 142 + .../third_party/waf/waflib/extras/midl.py | 69 + .../third_party/waf/waflib/extras/msvcdeps.py | 251 + .../third_party/waf/waflib/extras/msvs.py | 1048 ++++ .../waf/waflib/extras/netcache_client.py | 390 ++ .../third_party/waf/waflib/extras/objcopy.py | 53 + .../third_party/waf/waflib/extras/ocaml.py | 348 ++ .../third_party/waf/waflib/extras/package.py | 76 + .../waf/waflib/extras/parallel_debug.py | 462 ++ .../third_party/waf/waflib/extras/pch.py | 148 + .../third_party/waf/waflib/extras/pep8.py | 106 + .../third_party/waf/waflib/extras/pgicc.py | 75 + .../third_party/waf/waflib/extras/pgicxx.py | 20 + .../third_party/waf/waflib/extras/proc.py | 54 + .../third_party/waf/waflib/extras/protoc.py | 224 + .../third_party/waf/waflib/extras/pyqt5.py | 246 + .../third_party/waf/waflib/extras/pytest.py | 225 + .../third_party/waf/waflib/extras/qnxnto.py | 72 + .../third_party/waf/waflib/extras/qt4.py | 695 +++ .../waf/waflib/extras/relocation.py | 85 + .../third_party/waf/waflib/extras/remote.py | 327 ++ .../third_party/waf/waflib/extras/resx.py | 35 + .../third_party/waf/waflib/extras/review.py | 325 ++ .../third_party/waf/waflib/extras/rst.py | 260 + .../waf/waflib/extras/run_do_script.py | 139 + .../waf/waflib/extras/run_m_script.py | 88 + .../waf/waflib/extras/run_py_script.py | 104 + .../waf/waflib/extras/run_r_script.py | 86 + .../third_party/waf/waflib/extras/sas.py | 71 + .../waf/waflib/extras/satellite_assembly.py | 57 + .../third_party/waf/waflib/extras/scala.py | 128 + .../third_party/waf/waflib/extras/slow_qt4.py | 96 + .../waf/waflib/extras/softlink_libs.py | 76 + .../third_party/waf/waflib/extras/sphinx.py | 81 + .../third_party/waf/waflib/extras/stale.py | 98 + .../waf/waflib/extras/stracedeps.py | 174 + .../third_party/waf/waflib/extras/swig.py | 237 + .../third_party/waf/waflib/extras/syms.py | 84 + .../third_party/waf/waflib/extras/ticgt.py | 300 ++ .../third_party/waf/waflib/extras/unity.py | 108 + .../waf/waflib/extras/use_config.py | 185 + .../third_party/waf/waflib/extras/valadoc.py | 140 + .../waf/waflib/extras/waf_xattr.py | 150 + .../third_party/waf/waflib/extras/why.py | 78 + .../waf/waflib/extras/win32_opts.py | 170 + .../third_party/waf/waflib/extras/wix.py | 87 + .../third_party/waf/waflib/extras/xcode6.py | 727 +++ ldb-2.0.8/third_party/waf/waflib/fixpy2.py | 64 + ldb-2.0.8/third_party/waf/waflib/processor.py | 68 + ldb-2.0.8/tools/cmdline.c | 521 ++ ldb-2.0.8/tools/cmdline.h | 59 + ldb-2.0.8/tools/ldbadd.c | 186 + ldb-2.0.8/tools/ldbdel.c | 135 + ldb-2.0.8/tools/ldbdump.c | 383 ++ ldb-2.0.8/tools/ldbedit.c | 383 ++ ldb-2.0.8/tools/ldbmodify.c | 184 + ldb-2.0.8/tools/ldbrename.c | 85 + ldb-2.0.8/tools/ldbsearch.c | 342 ++ ldb-2.0.8/tools/ldbtest.c | 438 ++ ldb-2.0.8/tools/ldbutil.c | 220 + ldb-2.0.8/tools/ldbutil.h | 46 + ldb-2.0.8/web/index.html | 74 + ldb-2.0.8/wscript | 650 +++ libldb.spec | 2 - 890 files changed, 226699 insertions(+), 2 deletions(-) create mode 100644 ldb-2.0.8/ABI/ldb-0.9.10.sigs create mode 100644 ldb-2.0.8/ABI/ldb-0.9.12.sigs create mode 100644 ldb-2.0.8/ABI/ldb-0.9.15.sigs create mode 100644 ldb-2.0.8/ABI/ldb-0.9.16.sigs create mode 100644 ldb-2.0.8/ABI/ldb-0.9.17.sigs create mode 100644 ldb-2.0.8/ABI/ldb-0.9.18.sigs create mode 100644 ldb-2.0.8/ABI/ldb-0.9.19.sigs create mode 100644 ldb-2.0.8/ABI/ldb-0.9.20.sigs create mode 100644 ldb-2.0.8/ABI/ldb-0.9.22.sigs create mode 100644 ldb-2.0.8/ABI/ldb-0.9.23.sigs create mode 100644 ldb-2.0.8/ABI/ldb-0.9.24.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.0.0.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.0.1.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.0.2.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.0.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.1.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.10.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.11.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.12.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.13.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.14.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.15.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.16.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.17.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.18.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.19.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.2.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.20.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.21.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.22.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.23.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.24.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.25.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.26.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.27.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.28.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.29.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.3.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.30.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.31.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.4.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.5.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.6.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.7.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.8.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.1.9.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.2.0.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.2.1.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.2.2.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.2.3.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.3.0.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.3.1.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.3.2.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.4.0.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.4.1.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.5.0.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.5.1.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.5.2.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.5.3.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.6.0.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.6.1.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.6.2.sigs create mode 100644 ldb-2.0.8/ABI/ldb-1.6.3.sigs create mode 100644 ldb-2.0.8/ABI/ldb-2.0.0.sigs create mode 100644 ldb-2.0.8/ABI/ldb-2.0.1.sigs create mode 100644 ldb-2.0.8/ABI/ldb-2.0.2.sigs create mode 100644 ldb-2.0.8/ABI/ldb-2.0.3.sigs create mode 100644 ldb-2.0.8/ABI/ldb-2.0.4.sigs create mode 100644 ldb-2.0.8/ABI/ldb-2.0.5.sigs create mode 100644 ldb-2.0.8/ABI/ldb-2.0.6.sigs create mode 100644 ldb-2.0.8/ABI/ldb-2.0.7.sigs create mode 100644 ldb-2.0.8/ABI/ldb-2.0.8.sigs create mode 100644 ldb-2.0.8/ABI/ldb-ildap-0.9.12.sigs create mode 100644 ldb-2.0.8/ABI/ldb-samba4-0.9.10.sigs create mode 100644 ldb-2.0.8/ABI/ldb-samba4-0.9.11.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.10.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.11.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.12.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.13.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.14.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.15.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.16.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.17.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.18.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.19.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.2.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.20.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.21.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.22.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.23.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.24.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.25.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.26.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.27.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.28.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.29.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.3.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.30.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.31.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.4.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.5.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.6.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.7.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.8.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.9.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.2.0.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.2.1.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.2.2.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.2.3.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.3.0.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.3.1.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.3.2.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.4.0.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.4.1.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.5.0.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.5.1.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.5.2.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.5.3.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.6.0.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.6.1.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.6.2.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-1.6.3.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-2.0.0.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-2.0.1.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-2.0.2.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-2.0.3.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-2.0.4.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-2.0.5.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-2.0.6.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-2.0.7.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util-2.0.8.sigs create mode 100644 ldb-2.0.8/ABI/pyldb-util.py3-2.0.0.sigs create mode 100644 ldb-2.0.8/Doxyfile create mode 100644 ldb-2.0.8/Makefile create mode 100644 ldb-2.0.8/README_gcov.txt create mode 100644 ldb-2.0.8/_ldb_text.py create mode 100644 ldb-2.0.8/buildtools/README create mode 100755 ldb-2.0.8/buildtools/bin/waf create mode 100755 ldb-2.0.8/buildtools/compare_config_h4.sh create mode 100755 ldb-2.0.8/buildtools/compare_generated.sh create mode 100755 ldb-2.0.8/buildtools/compare_install.sh create mode 100755 ldb-2.0.8/buildtools/examples/run_on_target.py create mode 100644 ldb-2.0.8/buildtools/scripts/Makefile.waf create mode 100755 ldb-2.0.8/buildtools/scripts/abi_gen.sh create mode 100755 ldb-2.0.8/buildtools/scripts/autogen-waf.sh create mode 100755 ldb-2.0.8/buildtools/scripts/configure.waf create mode 100755 ldb-2.0.8/buildtools/testwaf.sh create mode 100644 ldb-2.0.8/buildtools/wafsamba/README create mode 100644 ldb-2.0.8/buildtools/wafsamba/__init__.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/configure_file.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/generic_cc.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/pkgconfig.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/samba3.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_abi.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_autoconf.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_autoproto.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_bundled.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_conftests.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_cross.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_deps.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_dist.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_git.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_headers.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_install.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_patterns.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_perl.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_pidl.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_python.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_third_party.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_utils.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_version.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_waf18.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_wildcard.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/stale_files.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/symbols.py create mode 100755 ldb-2.0.8/buildtools/wafsamba/test_duplicate_symbol.sh create mode 100644 ldb-2.0.8/buildtools/wafsamba/tests/__init__.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/tests/test_abi.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/tests/test_bundled.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/tests/test_utils.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/wafsamba.py create mode 100644 ldb-2.0.8/buildtools/wafsamba/wscript create mode 100644 ldb-2.0.8/common/attrib_handlers.c create mode 100644 ldb-2.0.8/common/ldb.c create mode 100644 ldb-2.0.8/common/ldb_attributes.c create mode 100644 ldb-2.0.8/common/ldb_controls.c create mode 100644 ldb-2.0.8/common/ldb_debug.c create mode 100644 ldb-2.0.8/common/ldb_dn.c create mode 100644 ldb-2.0.8/common/ldb_ldif.c create mode 100644 ldb-2.0.8/common/ldb_match.c create mode 100644 ldb-2.0.8/common/ldb_modules.c create mode 100644 ldb-2.0.8/common/ldb_msg.c create mode 100644 ldb-2.0.8/common/ldb_options.c create mode 100644 ldb-2.0.8/common/ldb_pack.c create mode 100644 ldb-2.0.8/common/ldb_parse.c create mode 100644 ldb-2.0.8/common/ldb_utf8.c create mode 100644 ldb-2.0.8/common/qsort.c create mode 100755 ldb-2.0.8/configure create mode 100755 ldb-2.0.8/docs/builddocs.sh create mode 100644 ldb-2.0.8/docs/design.txt create mode 100755 ldb-2.0.8/docs/installdocs.sh create mode 100644 ldb-2.0.8/examples.dox create mode 100644 ldb-2.0.8/examples/ldbreader.c create mode 100644 ldb-2.0.8/examples/ldifreader.c create mode 100644 ldb-2.0.8/include/dlinklist.h create mode 100644 ldb-2.0.8/include/ldb.h create mode 100644 ldb-2.0.8/include/ldb_errors.h create mode 100644 ldb-2.0.8/include/ldb_handlers.h create mode 100644 ldb-2.0.8/include/ldb_module.h create mode 100644 ldb-2.0.8/include/ldb_private.h create mode 100644 ldb-2.0.8/ldb.pc.in create mode 100644 ldb-2.0.8/ldb_key_value/ldb_kv.c create mode 100644 ldb-2.0.8/ldb_key_value/ldb_kv.h create mode 100644 ldb-2.0.8/ldb_key_value/ldb_kv_cache.c create mode 100644 ldb-2.0.8/ldb_key_value/ldb_kv_index.c create mode 100644 ldb-2.0.8/ldb_key_value/ldb_kv_search.c create mode 100644 ldb-2.0.8/ldb_ldap/ldb_ldap.c create mode 100644 ldb-2.0.8/ldb_ldb/ldb_ldb.c create mode 100644 ldb-2.0.8/ldb_map/ldb_map.c create mode 100644 ldb-2.0.8/ldb_map/ldb_map.h create mode 100644 ldb-2.0.8/ldb_map/ldb_map_inbound.c create mode 100644 ldb-2.0.8/ldb_map/ldb_map_outbound.c create mode 100644 ldb-2.0.8/ldb_map/ldb_map_private.h create mode 100644 ldb-2.0.8/ldb_mdb/ldb_mdb.c create mode 100644 ldb-2.0.8/ldb_mdb/ldb_mdb.h create mode 100644 ldb-2.0.8/ldb_mdb/ldb_mdb_init.c create mode 100644 ldb-2.0.8/ldb_sqlite3/README create mode 100644 ldb-2.0.8/ldb_sqlite3/base160.c create mode 100644 ldb-2.0.8/ldb_sqlite3/ldb_sqlite3.c create mode 100644 ldb-2.0.8/ldb_sqlite3/schema create mode 100644 ldb-2.0.8/ldb_sqlite3/trees.ps create mode 100644 ldb-2.0.8/ldb_tdb/ldb_tdb.c create mode 100644 ldb-2.0.8/ldb_tdb/ldb_tdb.h create mode 100644 ldb-2.0.8/ldb_tdb/ldb_tdb_err_map.c create mode 100644 ldb-2.0.8/ldb_tdb/ldb_tdb_init.c create mode 100644 ldb-2.0.8/ldb_tdb/ldb_tdb_wrap.c create mode 100644 ldb-2.0.8/lib/replace/.checker_innocent create mode 100644 ldb-2.0.8/lib/replace/Makefile create mode 100644 ldb-2.0.8/lib/replace/README create mode 100644 ldb-2.0.8/lib/replace/closefrom.c create mode 100755 ldb-2.0.8/lib/replace/configure create mode 100644 ldb-2.0.8/lib/replace/crypt.c create mode 100644 ldb-2.0.8/lib/replace/cwrap.c create mode 100644 ldb-2.0.8/lib/replace/dlfcn.c create mode 100644 ldb-2.0.8/lib/replace/getaddrinfo.c create mode 100644 ldb-2.0.8/lib/replace/getaddrinfo.h create mode 100644 ldb-2.0.8/lib/replace/getifaddrs.c create mode 100644 ldb-2.0.8/lib/replace/hdr_replace.h create mode 100644 ldb-2.0.8/lib/replace/inet_aton.c create mode 100644 ldb-2.0.8/lib/replace/inet_ntoa.c create mode 100644 ldb-2.0.8/lib/replace/inet_ntop.c create mode 100644 ldb-2.0.8/lib/replace/inet_pton.c create mode 100644 ldb-2.0.8/lib/replace/poll.c create mode 100644 ldb-2.0.8/lib/replace/replace-test.h create mode 100644 ldb-2.0.8/lib/replace/replace-testsuite.h create mode 100644 ldb-2.0.8/lib/replace/replace.c create mode 100644 ldb-2.0.8/lib/replace/replace.h create mode 100644 ldb-2.0.8/lib/replace/snprintf.c create mode 100644 ldb-2.0.8/lib/replace/socket.c create mode 100644 ldb-2.0.8/lib/replace/socketpair.c create mode 100644 ldb-2.0.8/lib/replace/strptime.c create mode 100644 ldb-2.0.8/lib/replace/system/README create mode 100644 ldb-2.0.8/lib/replace/system/aio.h create mode 100644 ldb-2.0.8/lib/replace/system/capability.h create mode 100644 ldb-2.0.8/lib/replace/system/dir.h create mode 100644 ldb-2.0.8/lib/replace/system/filesys.h create mode 100644 ldb-2.0.8/lib/replace/system/glob.h create mode 100644 ldb-2.0.8/lib/replace/system/gssapi.h create mode 100644 ldb-2.0.8/lib/replace/system/iconv.h create mode 100644 ldb-2.0.8/lib/replace/system/kerberos.h create mode 100644 ldb-2.0.8/lib/replace/system/locale.h create mode 100644 ldb-2.0.8/lib/replace/system/network.h create mode 100644 ldb-2.0.8/lib/replace/system/nis.h create mode 100644 ldb-2.0.8/lib/replace/system/passwd.h create mode 100644 ldb-2.0.8/lib/replace/system/readline.h create mode 100644 ldb-2.0.8/lib/replace/system/select.h create mode 100644 ldb-2.0.8/lib/replace/system/shmem.h create mode 100644 ldb-2.0.8/lib/replace/system/syslog.h create mode 100644 ldb-2.0.8/lib/replace/system/terminal.h create mode 100644 ldb-2.0.8/lib/replace/system/threads.h create mode 100644 ldb-2.0.8/lib/replace/system/time.h create mode 100644 ldb-2.0.8/lib/replace/system/wait.h create mode 100644 ldb-2.0.8/lib/replace/system/wscript_configure create mode 100644 ldb-2.0.8/lib/replace/tests/getifaddrs.c create mode 100644 ldb-2.0.8/lib/replace/tests/incoherent_mmap.c create mode 100644 ldb-2.0.8/lib/replace/tests/main.c create mode 100644 ldb-2.0.8/lib/replace/tests/os2_delete.c create mode 100644 ldb-2.0.8/lib/replace/tests/shared_mmap.c create mode 100644 ldb-2.0.8/lib/replace/tests/shared_mremap.c create mode 100644 ldb-2.0.8/lib/replace/tests/snprintf.c create mode 100644 ldb-2.0.8/lib/replace/tests/strptime.c create mode 100644 ldb-2.0.8/lib/replace/tests/testsuite.c create mode 100644 ldb-2.0.8/lib/replace/timegm.c create mode 100644 ldb-2.0.8/lib/replace/win32_replace.h create mode 100644 ldb-2.0.8/lib/replace/wscript create mode 100644 ldb-2.0.8/lib/replace/xattr.c create mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.6.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.7.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.8.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.0.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.1.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.10.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.11.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.12.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.13.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.14.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.15.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.16.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.2.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.3.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.4.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.5.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.6.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.7.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.8.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.9.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.2.0.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.0.2.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.0.3.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.0.4.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.0.5.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.0.6.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.0.7.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.0.8.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.0.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.1.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.10.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.11.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.12.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.13.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.14.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.15.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.16.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.2.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.3.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.4.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.5.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.6.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.7.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.8.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.9.sigs create mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.2.0.sigs create mode 100644 ldb-2.0.8/lib/talloc/Makefile create mode 100644 ldb-2.0.8/lib/talloc/NEWS create mode 100644 ldb-2.0.8/lib/talloc/compat/talloc_compat1.c create mode 100644 ldb-2.0.8/lib/talloc/compat/talloc_compat1.mk create mode 100755 ldb-2.0.8/lib/talloc/configure create mode 100644 ldb-2.0.8/lib/talloc/doc/context.png create mode 100644 ldb-2.0.8/lib/talloc/doc/context_tree.png create mode 100644 ldb-2.0.8/lib/talloc/doc/mainpage.dox create mode 100644 ldb-2.0.8/lib/talloc/doc/stealing.png create mode 100644 ldb-2.0.8/lib/talloc/doc/tutorial_bestpractices.dox create mode 100644 ldb-2.0.8/lib/talloc/doc/tutorial_context.dox create mode 100644 ldb-2.0.8/lib/talloc/doc/tutorial_debugging.dox create mode 100644 ldb-2.0.8/lib/talloc/doc/tutorial_destructors.dox create mode 100644 ldb-2.0.8/lib/talloc/doc/tutorial_dts.dox create mode 100644 ldb-2.0.8/lib/talloc/doc/tutorial_introduction.dox create mode 100644 ldb-2.0.8/lib/talloc/doc/tutorial_pools.dox create mode 100644 ldb-2.0.8/lib/talloc/doc/tutorial_stealing.dox create mode 100644 ldb-2.0.8/lib/talloc/doc/tutorial_threads.dox create mode 100644 ldb-2.0.8/lib/talloc/doxy.config create mode 100644 ldb-2.0.8/lib/talloc/man/talloc.3.xml create mode 100644 ldb-2.0.8/lib/talloc/pytalloc-util.pc.in create mode 100644 ldb-2.0.8/lib/talloc/pytalloc.c create mode 100644 ldb-2.0.8/lib/talloc/pytalloc.h create mode 100644 ldb-2.0.8/lib/talloc/pytalloc_guide.txt create mode 100644 ldb-2.0.8/lib/talloc/pytalloc_private.h create mode 100644 ldb-2.0.8/lib/talloc/pytalloc_util.c create mode 100644 ldb-2.0.8/lib/talloc/talloc.c create mode 100644 ldb-2.0.8/lib/talloc/talloc.h create mode 100644 ldb-2.0.8/lib/talloc/talloc.pc.in create mode 100644 ldb-2.0.8/lib/talloc/talloc_guide.txt create mode 100644 ldb-2.0.8/lib/talloc/talloc_testsuite.h create mode 100755 ldb-2.0.8/lib/talloc/test_magic_differs.sh create mode 100644 ldb-2.0.8/lib/talloc/test_magic_differs_helper.c create mode 100644 ldb-2.0.8/lib/talloc/test_pytalloc.c create mode 100644 ldb-2.0.8/lib/talloc/test_pytalloc.py create mode 100644 ldb-2.0.8/lib/talloc/testsuite.c create mode 100644 ldb-2.0.8/lib/talloc/testsuite_main.c create mode 100644 ldb-2.0.8/lib/talloc/web/index.html create mode 100644 ldb-2.0.8/lib/talloc/wscript create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.1.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.10.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.11.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.12.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.13.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.2.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.3.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.4.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.5.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.6.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.7.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.8.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.9.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.0.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.1.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.10.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.11.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.12.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.13.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.14.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.15.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.16.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.17.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.18.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.2.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.3.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.4.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.5.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.6.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.7.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.8.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.9.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.4.0.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.4.1.sigs create mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.4.2.sigs create mode 100644 ldb-2.0.8/lib/tdb/Makefile create mode 100644 ldb-2.0.8/lib/tdb/_tdb_text.py create mode 100644 ldb-2.0.8/lib/tdb/common/check.c create mode 100644 ldb-2.0.8/lib/tdb/common/dump.c create mode 100644 ldb-2.0.8/lib/tdb/common/error.c create mode 100644 ldb-2.0.8/lib/tdb/common/freelist.c create mode 100644 ldb-2.0.8/lib/tdb/common/freelistcheck.c create mode 100644 ldb-2.0.8/lib/tdb/common/hash.c create mode 100644 ldb-2.0.8/lib/tdb/common/io.c create mode 100644 ldb-2.0.8/lib/tdb/common/lock.c create mode 100644 ldb-2.0.8/lib/tdb/common/mutex.c create mode 100644 ldb-2.0.8/lib/tdb/common/open.c create mode 100644 ldb-2.0.8/lib/tdb/common/rescue.c create mode 100644 ldb-2.0.8/lib/tdb/common/summary.c create mode 100644 ldb-2.0.8/lib/tdb/common/tdb.c create mode 100644 ldb-2.0.8/lib/tdb/common/tdb_private.h create mode 100644 ldb-2.0.8/lib/tdb/common/transaction.c create mode 100644 ldb-2.0.8/lib/tdb/common/traverse.c create mode 100755 ldb-2.0.8/lib/tdb/configure create mode 100644 ldb-2.0.8/lib/tdb/docs/README create mode 100644 ldb-2.0.8/lib/tdb/docs/mainpage.dox create mode 100644 ldb-2.0.8/lib/tdb/docs/mutex.txt create mode 100644 ldb-2.0.8/lib/tdb/docs/tdb.magic create mode 100644 ldb-2.0.8/lib/tdb/docs/tracing.txt create mode 100644 ldb-2.0.8/lib/tdb/doxy.config create mode 100644 ldb-2.0.8/lib/tdb/include/tdb.h create mode 100644 ldb-2.0.8/lib/tdb/man/tdbbackup.8.xml create mode 100644 ldb-2.0.8/lib/tdb/man/tdbdump.8.xml create mode 100644 ldb-2.0.8/lib/tdb/man/tdbrestore.8.xml create mode 100644 ldb-2.0.8/lib/tdb/man/tdbtool.8.xml create mode 100644 ldb-2.0.8/lib/tdb/pytdb.c create mode 100644 ldb-2.0.8/lib/tdb/python/tdbdump.py create mode 100644 ldb-2.0.8/lib/tdb/python/tests/simple.py create mode 100644 ldb-2.0.8/lib/tdb/tdb.pc.in create mode 100644 ldb-2.0.8/lib/tdb/test/circular_chain.tdb create mode 100644 ldb-2.0.8/lib/tdb/test/circular_freelist.tdb create mode 100644 ldb-2.0.8/lib/tdb/test/external-agent.c create mode 100644 ldb-2.0.8/lib/tdb/test/external-agent.h create mode 100644 ldb-2.0.8/lib/tdb/test/jenkins-be-hash.tdb create mode 100644 ldb-2.0.8/lib/tdb/test/jenkins-le-hash.tdb create mode 100644 ldb-2.0.8/lib/tdb/test/lock-tracking.c create mode 100644 ldb-2.0.8/lib/tdb/test/lock-tracking.h create mode 100644 ldb-2.0.8/lib/tdb/test/logging.c create mode 100644 ldb-2.0.8/lib/tdb/test/logging.h create mode 100644 ldb-2.0.8/lib/tdb/test/old-nohash-be.tdb create mode 100644 ldb-2.0.8/lib/tdb/test/old-nohash-le.tdb create mode 100644 ldb-2.0.8/lib/tdb/test/run-3G-file.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-allrecord-traverse-deadlock.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-bad-tdb-header.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-check.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-circular-chain.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-circular-freelist.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-corrupt.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-die-during-transaction.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-endian.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-fcntl-deadlock.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-incompatible.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-marklock-deadlock.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-bench.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-block.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-trylock.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-mutex-die.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-mutex-openflags2.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-mutex-transaction1.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-mutex-trylock.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-mutex1.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-nested-transactions.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-nested-traverse.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-no-lock-during-traverse.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-oldhash.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-open-during-transaction.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-rdlock-upgrade.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-readonly-check.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-rescue-find_entry.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-rescue.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-rwlock-check.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-summary.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-transaction-expand.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-traverse-chain.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-traverse-in-transaction.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-wronghash-fail.c create mode 100644 ldb-2.0.8/lib/tdb/test/run-zero-append.c create mode 100644 ldb-2.0.8/lib/tdb/test/run.c create mode 100644 ldb-2.0.8/lib/tdb/test/rwlock-be.tdb create mode 100644 ldb-2.0.8/lib/tdb/test/rwlock-le.tdb create mode 100644 ldb-2.0.8/lib/tdb/test/sample_tdb.tdb create mode 100644 ldb-2.0.8/lib/tdb/test/tap-interface.h create mode 100644 ldb-2.0.8/lib/tdb/test/tap-to-subunit.h create mode 100644 ldb-2.0.8/lib/tdb/test/tdb.corrupt create mode 100755 ldb-2.0.8/lib/tdb/test/test_tdbbackup.sh create mode 100644 ldb-2.0.8/lib/tdb/tools/tdbbackup.c create mode 100644 ldb-2.0.8/lib/tdb/tools/tdbdump.c create mode 100644 ldb-2.0.8/lib/tdb/tools/tdbrestore.c create mode 100644 ldb-2.0.8/lib/tdb/tools/tdbtest.c create mode 100644 ldb-2.0.8/lib/tdb/tools/tdbtool.c create mode 100644 ldb-2.0.8/lib/tdb/tools/tdbtorture.c create mode 100644 ldb-2.0.8/lib/tdb/web/index.html create mode 100644 ldb-2.0.8/lib/tdb/wscript create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.10.0.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.10.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.11.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.12.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.13.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.14.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.15.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.16.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.17.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.18.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.19.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.20.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.21.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.22.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.23.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.24.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.25.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.26.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.27.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.28.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.29.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.30.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.31.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.32.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.33.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.34.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.35.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.36.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.37.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.38.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.39.sigs create mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.9.sigs create mode 100644 ldb-2.0.8/lib/tevent/Makefile create mode 100644 ldb-2.0.8/lib/tevent/bindings.py create mode 100755 ldb-2.0.8/lib/tevent/configure create mode 100644 ldb-2.0.8/lib/tevent/doc/img/tevent_context_stucture.png create mode 100644 ldb-2.0.8/lib/tevent/doc/img/tevent_subrequest.png create mode 100644 ldb-2.0.8/lib/tevent/doc/mainpage.dox create mode 100644 ldb-2.0.8/lib/tevent/doc/tevent_context.dox create mode 100644 ldb-2.0.8/lib/tevent/doc/tevent_data.dox create mode 100644 ldb-2.0.8/lib/tevent/doc/tevent_events.dox create mode 100644 ldb-2.0.8/lib/tevent/doc/tevent_queue.dox create mode 100644 ldb-2.0.8/lib/tevent/doc/tevent_request.dox create mode 100644 ldb-2.0.8/lib/tevent/doc/tevent_thread.dox create mode 100644 ldb-2.0.8/lib/tevent/doc/tevent_tutorial.dox create mode 100644 ldb-2.0.8/lib/tevent/doc/tutorials.dox create mode 100644 ldb-2.0.8/lib/tevent/doxy.config create mode 100644 ldb-2.0.8/lib/tevent/echo_server.c create mode 100644 ldb-2.0.8/lib/tevent/pytevent.c create mode 100644 ldb-2.0.8/lib/tevent/test_req.c create mode 100644 ldb-2.0.8/lib/tevent/testsuite.c create mode 100644 ldb-2.0.8/lib/tevent/tevent.c create mode 100644 ldb-2.0.8/lib/tevent/tevent.h create mode 100644 ldb-2.0.8/lib/tevent/tevent.pc.in create mode 100644 ldb-2.0.8/lib/tevent/tevent.py create mode 100644 ldb-2.0.8/lib/tevent/tevent_debug.c create mode 100644 ldb-2.0.8/lib/tevent/tevent_epoll.c create mode 100644 ldb-2.0.8/lib/tevent/tevent_fd.c create mode 100644 ldb-2.0.8/lib/tevent/tevent_immediate.c create mode 100644 ldb-2.0.8/lib/tevent/tevent_internal.h create mode 100644 ldb-2.0.8/lib/tevent/tevent_liboop.c create mode 100644 ldb-2.0.8/lib/tevent/tevent_poll.c create mode 100644 ldb-2.0.8/lib/tevent/tevent_port.c create mode 100644 ldb-2.0.8/lib/tevent/tevent_queue.c create mode 100644 ldb-2.0.8/lib/tevent/tevent_req.c create mode 100644 ldb-2.0.8/lib/tevent/tevent_signal.c create mode 100644 ldb-2.0.8/lib/tevent/tevent_standard.c create mode 100644 ldb-2.0.8/lib/tevent/tevent_threads.c create mode 100644 ldb-2.0.8/lib/tevent/tevent_timed.c create mode 100644 ldb-2.0.8/lib/tevent/tevent_util.c create mode 100644 ldb-2.0.8/lib/tevent/tevent_util.h create mode 100644 ldb-2.0.8/lib/tevent/tevent_wakeup.c create mode 100644 ldb-2.0.8/lib/tevent/tevent_wrapper.c create mode 100644 ldb-2.0.8/lib/tevent/wscript create mode 100644 ldb-2.0.8/lib/util/attr.h create mode 100644 ldb-2.0.8/lib/util/binsearch.h create mode 100644 ldb-2.0.8/mainpage.dox create mode 100644 ldb-2.0.8/man/ldb.3.xml create mode 100644 ldb-2.0.8/man/ldbadd.1.xml create mode 100644 ldb-2.0.8/man/ldbdel.1.xml create mode 100644 ldb-2.0.8/man/ldbedit.1.xml create mode 100644 ldb-2.0.8/man/ldbmodify.1.xml create mode 100644 ldb-2.0.8/man/ldbrename.1.xml create mode 100644 ldb-2.0.8/man/ldbsearch.1.xml create mode 100644 ldb-2.0.8/modules/asq.c create mode 100644 ldb-2.0.8/modules/paged_searches.c create mode 100644 ldb-2.0.8/modules/rdn_name.c create mode 100644 ldb-2.0.8/modules/skel.c create mode 100644 ldb-2.0.8/modules/sort.c create mode 100644 ldb-2.0.8/nssldb/README.txt create mode 100644 ldb-2.0.8/nssldb/ldb-grp.c create mode 100644 ldb-2.0.8/nssldb/ldb-nss.c create mode 100644 ldb-2.0.8/nssldb/ldb-nss.h create mode 100644 ldb-2.0.8/nssldb/ldb-pwd.c create mode 100644 ldb-2.0.8/pyldb-util.pc.in create mode 100644 ldb-2.0.8/pyldb.c create mode 100644 ldb-2.0.8/pyldb.h create mode 100644 ldb-2.0.8/pyldb_util.c create mode 100644 ldb-2.0.8/tests/guidindexpackv1.ldb create mode 100644 ldb-2.0.8/tests/init.ldif create mode 100755 ldb-2.0.8/tests/init_slapd.sh create mode 100755 ldb-2.0.8/tests/kill_slapd.sh create mode 100755 ldb-2.0.8/tests/ldapi_url.sh create mode 100644 ldb-2.0.8/tests/ldb_filter_attrs_test.c create mode 100644 ldb-2.0.8/tests/ldb_key_value_sub_txn_mdb_test.valgrind create mode 100644 ldb-2.0.8/tests/ldb_key_value_sub_txn_test.c create mode 100644 ldb-2.0.8/tests/ldb_key_value_test.c create mode 100644 ldb-2.0.8/tests/ldb_kv_ops_test.c create mode 100644 ldb-2.0.8/tests/ldb_kv_ops_test.valgrind create mode 100644 ldb-2.0.8/tests/ldb_lmdb_size_test.c create mode 100644 ldb-2.0.8/tests/ldb_lmdb_test.c create mode 100644 ldb-2.0.8/tests/ldb_match_test.c create mode 100644 ldb-2.0.8/tests/ldb_match_test.valgrind create mode 100644 ldb-2.0.8/tests/ldb_mod_op_test.c create mode 100644 ldb-2.0.8/tests/ldb_msg.c create mode 100644 ldb-2.0.8/tests/ldb_no_lmdb_test.c create mode 100644 ldb-2.0.8/tests/ldb_parse_test.c create mode 100644 ldb-2.0.8/tests/ldb_tdb_test.c create mode 100644 ldb-2.0.8/tests/photo.ldif create mode 100755 ldb-2.0.8/tests/python/api.py create mode 100755 ldb-2.0.8/tests/python/index.py create mode 100644 ldb-2.0.8/tests/python/repack.py create mode 100644 ldb-2.0.8/tests/samba4.png create mode 100644 ldb-2.0.8/tests/sample_module.c create mode 100644 ldb-2.0.8/tests/schema-tests/schema-add-test.ldif create mode 100644 ldb-2.0.8/tests/schema-tests/schema-mod-test-1.ldif create mode 100644 ldb-2.0.8/tests/schema-tests/schema-mod-test-2.ldif create mode 100644 ldb-2.0.8/tests/schema-tests/schema-mod-test-3.ldif create mode 100644 ldb-2.0.8/tests/schema-tests/schema-mod-test-4.ldif create mode 100644 ldb-2.0.8/tests/schema-tests/schema-mod-test-5.ldif create mode 100644 ldb-2.0.8/tests/schema-tests/schema.ldif create mode 100644 ldb-2.0.8/tests/slapd.conf create mode 100755 ldb-2.0.8/tests/start_slapd.sh create mode 100644 ldb-2.0.8/tests/test-attribs.ldif create mode 100644 ldb-2.0.8/tests/test-config.ldif create mode 100755 ldb-2.0.8/tests/test-controls.sh create mode 100644 ldb-2.0.8/tests/test-default-config.ldif create mode 100644 ldb-2.0.8/tests/test-dup-2.ldif create mode 100644 ldb-2.0.8/tests/test-dup.ldif create mode 100755 ldb-2.0.8/tests/test-extended.sh create mode 100755 ldb-2.0.8/tests/test-generic.sh create mode 100644 ldb-2.0.8/tests/test-index.ldif create mode 100755 ldb-2.0.8/tests/test-ldap.sh create mode 100644 ldb-2.0.8/tests/test-modify-modrdn.ldif create mode 100644 ldb-2.0.8/tests/test-modify-unmet-2.ldif create mode 100644 ldb-2.0.8/tests/test-modify-unmet.ldif create mode 100644 ldb-2.0.8/tests/test-modify.ldif create mode 100755 ldb-2.0.8/tests/test-schema.sh create mode 100755 ldb-2.0.8/tests/test-soloading.sh create mode 100755 ldb-2.0.8/tests/test-sqlite3.sh create mode 100644 ldb-2.0.8/tests/test-tdb-features.sh create mode 100755 ldb-2.0.8/tests/test-tdb-subunit.sh create mode 100755 ldb-2.0.8/tests/test-tdb.sh create mode 100644 ldb-2.0.8/tests/test-wildcard.ldif create mode 100644 ldb-2.0.8/tests/test-wrong_attributes.ldif create mode 100644 ldb-2.0.8/tests/test.ldif create mode 100644 ldb-2.0.8/tests/test_ldb_dn.c create mode 100644 ldb-2.0.8/tests/test_ldb_qsort.c create mode 100644 ldb-2.0.8/tests/testdata.txt create mode 100644 ldb-2.0.8/tests/testsearch.txt create mode 100644 ldb-2.0.8/third_party/cmocka/cmocka.c create mode 100644 ldb-2.0.8/third_party/cmocka/cmocka.h create mode 100644 ldb-2.0.8/third_party/cmocka/cmocka_private.h create mode 100644 ldb-2.0.8/third_party/cmocka/wscript create mode 100644 ldb-2.0.8/third_party/popt/CHANGES create mode 100644 ldb-2.0.8/third_party/popt/COPYING create mode 100644 ldb-2.0.8/third_party/popt/README create mode 100644 ldb-2.0.8/third_party/popt/findme.h create mode 100644 ldb-2.0.8/third_party/popt/lookup3.c create mode 100644 ldb-2.0.8/third_party/popt/popt.c create mode 100644 ldb-2.0.8/third_party/popt/popt.h create mode 100644 ldb-2.0.8/third_party/popt/poptconfig.c create mode 100644 ldb-2.0.8/third_party/popt/popthelp.c create mode 100644 ldb-2.0.8/third_party/popt/poptint.c create mode 100644 ldb-2.0.8/third_party/popt/poptint.h create mode 100644 ldb-2.0.8/third_party/popt/poptparse.c create mode 100644 ldb-2.0.8/third_party/popt/system.h create mode 100644 ldb-2.0.8/third_party/popt/wscript create mode 100644 ldb-2.0.8/third_party/waf/waflib/Build.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/ConfigSet.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Configure.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Context.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Errors.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Logs.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Node.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Options.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Runner.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Scripting.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Task.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/TaskGen.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/__init__.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/ar.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/asm.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/bison.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/c.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/c_aliases.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/c_config.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/c_osx.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/c_preproc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/c_tests.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/ccroot.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/clang.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/clangxx.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/compiler_c.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/compiler_cxx.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/compiler_d.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/compiler_fc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/cs.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/cxx.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/d.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/d_config.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/d_scan.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/dbus.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/dmd.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/errcheck.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/fc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/fc_config.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/fc_scan.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/flex.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/g95.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/gas.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/gcc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/gdc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/gfortran.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/glib2.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/gnu_dirs.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/gxx.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/icc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/icpc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/ifort.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/intltool.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/irixcc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/javaw.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/ldc2.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/lua.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/md5_tstamp.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/msvc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/nasm.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/nobuild.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/perl.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/python.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/qt5.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/ruby.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/suncc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/suncxx.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/tex.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/vala.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/waf_unit_test.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/winres.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/xlc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/xlcxx.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/Utils.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/__init__.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/ansiterm.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/__init__.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/batched_cc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/biber.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/bjam.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/blender.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/boo.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/boost.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/build_file_tracker.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/build_logs.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/buildcopy.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/c_bgxlc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/c_dumbpreproc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/c_emscripten.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/c_nec.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/cabal.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/cfg_altoptions.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/clang_compilation_database.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/clang_cross.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/clang_cross_common.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/clangxx_cross.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/codelite.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/color_gcc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/color_msvc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/color_rvct.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/compat15.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/cppcheck.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/cpplint.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/cross_gnu.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/cython.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/dcc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/distnet.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/doxygen.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/dpapi.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/eclipse.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/erlang.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fast_partial.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fc_bgxlf.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fc_cray.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fc_nag.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fc_nec.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fc_nfort.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fc_open64.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fc_pgfortran.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fc_solstudio.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fc_xlf.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/file_to_object.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fluid.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/freeimage.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fsb.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fsc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/gccdeps.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/gdbus.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/genpybind.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/gob2.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/halide.py create mode 100755 ldb-2.0.8/third_party/waf/waflib/extras/javatest.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/kde4.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/local_rpath.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/make.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/midl.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/msvcdeps.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/msvs.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/netcache_client.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/objcopy.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/ocaml.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/package.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/parallel_debug.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/pch.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/pep8.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/pgicc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/pgicxx.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/proc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/protoc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/pyqt5.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/pytest.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/qnxnto.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/qt4.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/relocation.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/remote.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/resx.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/review.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/rst.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/run_do_script.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/run_m_script.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/run_py_script.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/run_r_script.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/sas.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/satellite_assembly.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/scala.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/slow_qt4.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/softlink_libs.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/sphinx.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/stale.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/stracedeps.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/swig.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/syms.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/ticgt.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/unity.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/use_config.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/valadoc.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/waf_xattr.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/why.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/win32_opts.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/wix.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/xcode6.py create mode 100644 ldb-2.0.8/third_party/waf/waflib/fixpy2.py create mode 100755 ldb-2.0.8/third_party/waf/waflib/processor.py create mode 100644 ldb-2.0.8/tools/cmdline.c create mode 100644 ldb-2.0.8/tools/cmdline.h create mode 100644 ldb-2.0.8/tools/ldbadd.c create mode 100644 ldb-2.0.8/tools/ldbdel.c create mode 100644 ldb-2.0.8/tools/ldbdump.c create mode 100644 ldb-2.0.8/tools/ldbedit.c create mode 100644 ldb-2.0.8/tools/ldbmodify.c create mode 100644 ldb-2.0.8/tools/ldbrename.c create mode 100644 ldb-2.0.8/tools/ldbsearch.c create mode 100644 ldb-2.0.8/tools/ldbtest.c create mode 100644 ldb-2.0.8/tools/ldbutil.c create mode 100644 ldb-2.0.8/tools/ldbutil.h create mode 100644 ldb-2.0.8/web/index.html create mode 100644 ldb-2.0.8/wscript diff --git a/ldb-2.0.8/ABI/ldb-0.9.10.sigs b/ldb-2.0.8/ABI/ldb-0.9.10.sigs new file mode 100644 index 0000000..012ac65 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-0.9.10.sigs @@ -0,0 +1,218 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(void *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(void *, const char *, int) +ldb_binary_decode: struct ldb_val (void *, const char *) +ldb_binary_encode: char *(void *, struct ldb_val) +ldb_binary_encode_string: char *(void *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, void *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, void *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, void *, const char *, size_t) +ldb_casefold_default: char *(void *, void *, const char *, size_t) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(void *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) +ldb_dn_canonical_string: char *(void *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(void *, struct ldb_dn *) +ldb_dn_escape_value: char *(void *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(void *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(void *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(void *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(void *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(void *, struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_init_module_chain: int (struct ldb_context *, struct ldb_module *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(void *) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(void *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (void *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-0.9.12.sigs b/ldb-2.0.8/ABI/ldb-0.9.12.sigs new file mode 100644 index 0000000..2206e79 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-0.9.12.sigs @@ -0,0 +1,219 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(void *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(void *, const char *, int) +ldb_binary_decode: struct ldb_val (void *, const char *) +ldb_binary_encode: char *(void *, struct ldb_val) +ldb_binary_encode_string: char *(void *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, void *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, void *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, void *, const char *, size_t) +ldb_casefold_default: char *(void *, void *, const char *, size_t) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(void *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) +ldb_dn_canonical_string: char *(void *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(void *, struct ldb_dn *) +ldb_dn_escape_value: char *(void *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(void *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(void *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(void *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(void *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(void *, struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_init_module_chain: int (struct ldb_context *, struct ldb_module *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(void *) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(void *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (void *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-0.9.15.sigs b/ldb-2.0.8/ABI/ldb-0.9.15.sigs new file mode 100644 index 0000000..39d2f3e --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-0.9.15.sigs @@ -0,0 +1,226 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_init_module_chain: int (struct ldb_context *, struct ldb_module *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-0.9.16.sigs b/ldb-2.0.8/ABI/ldb-0.9.16.sigs new file mode 100644 index 0000000..610a0a4 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-0.9.16.sigs @@ -0,0 +1,228 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_init_module_chain: int (struct ldb_context *, struct ldb_module *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-0.9.17.sigs b/ldb-2.0.8/ABI/ldb-0.9.17.sigs new file mode 100644 index 0000000..d0f5699 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-0.9.17.sigs @@ -0,0 +1,229 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_init_module_chain: int (struct ldb_context *, struct ldb_module *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-0.9.18.sigs b/ldb-2.0.8/ABI/ldb-0.9.18.sigs new file mode 100644 index 0000000..15913c9 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-0.9.18.sigs @@ -0,0 +1,240 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_asq_init: int (const char *) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_init_module_chain: int (struct ldb_context *, struct ldb_module *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_paged_results_init: int (const char *) +ldb_paged_searches_init: int (const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_rdn_name_init: int (const char *) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_sample_init: int (const char *) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_server_sort_init: int (const char *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_skel_init: int (const char *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_tdb_init: int (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-0.9.19.sigs b/ldb-2.0.8/ABI/ldb-0.9.19.sigs new file mode 100644 index 0000000..6273870 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-0.9.19.sigs @@ -0,0 +1,245 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_asq_init: int (const char *) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_paged_results_init: int (const char *) +ldb_paged_searches_init: int (const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_rdn_name_init: int (const char *) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_sample_init: int (const char *) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_server_sort_init: int (const char *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_skel_init: int (const char *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_tdb_init: int (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-0.9.20.sigs b/ldb-2.0.8/ABI/ldb-0.9.20.sigs new file mode 100644 index 0000000..6273870 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-0.9.20.sigs @@ -0,0 +1,245 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_asq_init: int (const char *) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_paged_results_init: int (const char *) +ldb_paged_searches_init: int (const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_rdn_name_init: int (const char *) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_sample_init: int (const char *) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_server_sort_init: int (const char *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_skel_init: int (const char *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_tdb_init: int (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-0.9.22.sigs b/ldb-2.0.8/ABI/ldb-0.9.22.sigs new file mode 100644 index 0000000..b5a69c1 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-0.9.22.sigs @@ -0,0 +1,245 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-0.9.23.sigs b/ldb-2.0.8/ABI/ldb-0.9.23.sigs new file mode 100644 index 0000000..73e5caa --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-0.9.23.sigs @@ -0,0 +1,247 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-0.9.24.sigs b/ldb-2.0.8/ABI/ldb-0.9.24.sigs new file mode 100644 index 0000000..5cb32f7 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-0.9.24.sigs @@ -0,0 +1,248 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.0.0.sigs b/ldb-2.0.8/ABI/ldb-1.0.0.sigs new file mode 100644 index 0000000..5cb32f7 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.0.0.sigs @@ -0,0 +1,248 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.0.1.sigs b/ldb-2.0.8/ABI/ldb-1.0.1.sigs new file mode 100644 index 0000000..5cb32f7 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.0.1.sigs @@ -0,0 +1,248 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.0.2.sigs b/ldb-2.0.8/ABI/ldb-1.0.2.sigs new file mode 100644 index 0000000..c13ac87 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.0.2.sigs @@ -0,0 +1,250 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.0.sigs b/ldb-2.0.8/ABI/ldb-1.1.0.sigs new file mode 100644 index 0000000..149d4bc --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.0.sigs @@ -0,0 +1,253 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.1.sigs b/ldb-2.0.8/ABI/ldb-1.1.1.sigs new file mode 100644 index 0000000..2fe215c --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.1.sigs @@ -0,0 +1,254 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.10.sigs b/ldb-2.0.8/ABI/ldb-1.1.10.sigs new file mode 100644 index 0000000..de5026e --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.10.sigs @@ -0,0 +1,259 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.11.sigs b/ldb-2.0.8/ABI/ldb-1.1.11.sigs new file mode 100644 index 0000000..de5026e --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.11.sigs @@ -0,0 +1,259 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.12.sigs b/ldb-2.0.8/ABI/ldb-1.1.12.sigs new file mode 100644 index 0000000..c8ccd25 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.12.sigs @@ -0,0 +1,260 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.13.sigs b/ldb-2.0.8/ABI/ldb-1.1.13.sigs new file mode 100644 index 0000000..c8ccd25 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.13.sigs @@ -0,0 +1,260 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.14.sigs b/ldb-2.0.8/ABI/ldb-1.1.14.sigs new file mode 100644 index 0000000..eac5194 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.14.sigs @@ -0,0 +1,262 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.15.sigs b/ldb-2.0.8/ABI/ldb-1.1.15.sigs new file mode 100644 index 0000000..eac5194 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.15.sigs @@ -0,0 +1,262 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.16.sigs b/ldb-2.0.8/ABI/ldb-1.1.16.sigs new file mode 100644 index 0000000..eac5194 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.16.sigs @@ -0,0 +1,262 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.17.sigs b/ldb-2.0.8/ABI/ldb-1.1.17.sigs new file mode 100644 index 0000000..eac5194 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.17.sigs @@ -0,0 +1,262 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.18.sigs b/ldb-2.0.8/ABI/ldb-1.1.18.sigs new file mode 100644 index 0000000..eac5194 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.18.sigs @@ -0,0 +1,262 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.19.sigs b/ldb-2.0.8/ABI/ldb-1.1.19.sigs new file mode 100644 index 0000000..b46c5c7 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.19.sigs @@ -0,0 +1,263 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.2.sigs b/ldb-2.0.8/ABI/ldb-1.1.2.sigs new file mode 100644 index 0000000..d0df756 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.2.sigs @@ -0,0 +1,256 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.20.sigs b/ldb-2.0.8/ABI/ldb-1.1.20.sigs new file mode 100644 index 0000000..b46c5c7 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.20.sigs @@ -0,0 +1,263 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.21.sigs b/ldb-2.0.8/ABI/ldb-1.1.21.sigs new file mode 100644 index 0000000..b46c5c7 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.21.sigs @@ -0,0 +1,263 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.22.sigs b/ldb-2.0.8/ABI/ldb-1.1.22.sigs new file mode 100644 index 0000000..6d9767b --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.22.sigs @@ -0,0 +1,264 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.23.sigs b/ldb-2.0.8/ABI/ldb-1.1.23.sigs new file mode 100644 index 0000000..6d9767b --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.23.sigs @@ -0,0 +1,264 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.24.sigs b/ldb-2.0.8/ABI/ldb-1.1.24.sigs new file mode 100644 index 0000000..6d9767b --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.24.sigs @@ -0,0 +1,264 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.25.sigs b/ldb-2.0.8/ABI/ldb-1.1.25.sigs new file mode 100644 index 0000000..3f33df9 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.25.sigs @@ -0,0 +1,265 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.26.sigs b/ldb-2.0.8/ABI/ldb-1.1.26.sigs new file mode 100644 index 0000000..3f33df9 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.26.sigs @@ -0,0 +1,265 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.27.sigs b/ldb-2.0.8/ABI/ldb-1.1.27.sigs new file mode 100644 index 0000000..4fa30d8 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.27.sigs @@ -0,0 +1,266 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.28.sigs b/ldb-2.0.8/ABI/ldb-1.1.28.sigs new file mode 100644 index 0000000..4fa30d8 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.28.sigs @@ -0,0 +1,266 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.29.sigs b/ldb-2.0.8/ABI/ldb-1.1.29.sigs new file mode 100644 index 0000000..0ea968d --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.29.sigs @@ -0,0 +1,268 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.3.sigs b/ldb-2.0.8/ABI/ldb-1.1.3.sigs new file mode 100644 index 0000000..d0df756 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.3.sigs @@ -0,0 +1,256 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.30.sigs b/ldb-2.0.8/ABI/ldb-1.1.30.sigs new file mode 100644 index 0000000..ef9c53e --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.30.sigs @@ -0,0 +1,272 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.31.sigs b/ldb-2.0.8/ABI/ldb-1.1.31.sigs new file mode 100644 index 0000000..d183708 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.31.sigs @@ -0,0 +1,274 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.4.sigs b/ldb-2.0.8/ABI/ldb-1.1.4.sigs new file mode 100644 index 0000000..d0df756 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.4.sigs @@ -0,0 +1,256 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.5.sigs b/ldb-2.0.8/ABI/ldb-1.1.5.sigs new file mode 100644 index 0000000..cc0f859 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.5.sigs @@ -0,0 +1,257 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.6.sigs b/ldb-2.0.8/ABI/ldb-1.1.6.sigs new file mode 100644 index 0000000..f90fa13 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.6.sigs @@ -0,0 +1,258 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.7.sigs b/ldb-2.0.8/ABI/ldb-1.1.7.sigs new file mode 100644 index 0000000..f90fa13 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.7.sigs @@ -0,0 +1,258 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.8.sigs b/ldb-2.0.8/ABI/ldb-1.1.8.sigs new file mode 100644 index 0000000..f90fa13 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.8.sigs @@ -0,0 +1,258 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.9.sigs b/ldb-2.0.8/ABI/ldb-1.1.9.sigs new file mode 100644 index 0000000..f90fa13 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.1.9.sigs @@ -0,0 +1,258 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.2.0.sigs b/ldb-2.0.8/ABI/ldb-1.2.0.sigs new file mode 100644 index 0000000..1be2ae7 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.2.0.sigs @@ -0,0 +1,276 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.2.1.sigs b/ldb-2.0.8/ABI/ldb-1.2.1.sigs new file mode 100644 index 0000000..1be2ae7 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.2.1.sigs @@ -0,0 +1,276 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.2.2.sigs b/ldb-2.0.8/ABI/ldb-1.2.2.sigs new file mode 100644 index 0000000..9dc61cd --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.2.2.sigs @@ -0,0 +1,277 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.2.3.sigs b/ldb-2.0.8/ABI/ldb-1.2.3.sigs new file mode 100644 index 0000000..9dc61cd --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.2.3.sigs @@ -0,0 +1,277 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.3.0.sigs b/ldb-2.0.8/ABI/ldb-1.3.0.sigs new file mode 100644 index 0000000..a31b84e --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.3.0.sigs @@ -0,0 +1,279 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.3.1.sigs b/ldb-2.0.8/ABI/ldb-1.3.1.sigs new file mode 100644 index 0000000..a31b84e --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.3.1.sigs @@ -0,0 +1,279 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.3.2.sigs b/ldb-2.0.8/ABI/ldb-1.3.2.sigs new file mode 100644 index 0000000..a31b84e --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.3.2.sigs @@ -0,0 +1,279 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.4.0.sigs b/ldb-2.0.8/ABI/ldb-1.4.0.sigs new file mode 100644 index 0000000..a31b84e --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.4.0.sigs @@ -0,0 +1,279 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.4.1.sigs b/ldb-2.0.8/ABI/ldb-1.4.1.sigs new file mode 100644 index 0000000..a31b84e --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.4.1.sigs @@ -0,0 +1,279 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.5.0.sigs b/ldb-2.0.8/ABI/ldb-1.5.0.sigs new file mode 100644 index 0000000..a31b84e --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.5.0.sigs @@ -0,0 +1,279 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.5.1.sigs b/ldb-2.0.8/ABI/ldb-1.5.1.sigs new file mode 100644 index 0000000..0c1234f --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.5.1.sigs @@ -0,0 +1,280 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.5.2.sigs b/ldb-2.0.8/ABI/ldb-1.5.2.sigs new file mode 100644 index 0000000..0c1234f --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.5.2.sigs @@ -0,0 +1,280 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.5.3.sigs b/ldb-2.0.8/ABI/ldb-1.5.3.sigs new file mode 100644 index 0000000..0c1234f --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.5.3.sigs @@ -0,0 +1,280 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.6.0.sigs b/ldb-2.0.8/ABI/ldb-1.6.0.sigs new file mode 100644 index 0000000..0c1234f --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.6.0.sigs @@ -0,0 +1,280 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.6.1.sigs b/ldb-2.0.8/ABI/ldb-1.6.1.sigs new file mode 100644 index 0000000..0c1234f --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.6.1.sigs @@ -0,0 +1,280 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.6.2.sigs b/ldb-2.0.8/ABI/ldb-1.6.2.sigs new file mode 100644 index 0000000..0c1234f --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.6.2.sigs @@ -0,0 +1,280 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.6.3.sigs b/ldb-2.0.8/ABI/ldb-1.6.3.sigs new file mode 100644 index 0000000..0c1234f --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-1.6.3.sigs @@ -0,0 +1,280 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-2.0.0.sigs b/ldb-2.0.8/ABI/ldb-2.0.0.sigs new file mode 100644 index 0000000..0c1234f --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-2.0.0.sigs @@ -0,0 +1,280 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) +ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-2.0.1.sigs b/ldb-2.0.8/ABI/ldb-2.0.1.sigs new file mode 100644 index 0000000..f782d73 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-2.0.1.sigs @@ -0,0 +1,280 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-2.0.2.sigs b/ldb-2.0.8/ABI/ldb-2.0.2.sigs new file mode 100644 index 0000000..5fc5560 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-2.0.2.sigs @@ -0,0 +1,281 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) +ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-2.0.3.sigs b/ldb-2.0.8/ABI/ldb-2.0.3.sigs new file mode 100644 index 0000000..5fc5560 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-2.0.3.sigs @@ -0,0 +1,281 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) +ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-2.0.4.sigs b/ldb-2.0.8/ABI/ldb-2.0.4.sigs new file mode 100644 index 0000000..446804b --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-2.0.4.sigs @@ -0,0 +1,282 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_copy: const char **(TALLOC_CTX *, const char **) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) +ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-2.0.5.sigs b/ldb-2.0.8/ABI/ldb-2.0.5.sigs new file mode 100644 index 0000000..5049dc6 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-2.0.5.sigs @@ -0,0 +1,283 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_copy: const char **(TALLOC_CTX *, const char **) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_options_get: const char **(struct ldb_context *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) +ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-2.0.6.sigs b/ldb-2.0.8/ABI/ldb-2.0.6.sigs new file mode 100644 index 0000000..5049dc6 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-2.0.6.sigs @@ -0,0 +1,283 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_copy: const char **(TALLOC_CTX *, const char **) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_options_get: const char **(struct ldb_context *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) +ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-2.0.7.sigs b/ldb-2.0.8/ABI/ldb-2.0.7.sigs new file mode 100644 index 0000000..5049dc6 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-2.0.7.sigs @@ -0,0 +1,283 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_copy: const char **(TALLOC_CTX *, const char **) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_options_get: const char **(struct ldb_context *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) +ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-2.0.8.sigs b/ldb-2.0.8/ABI/ldb-2.0.8.sigs new file mode 100644 index 0000000..5049dc6 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-2.0.8.sigs @@ -0,0 +1,283 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(TALLOC_CTX *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) +ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) +ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) +ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) +ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) +ldb_check_critical_controls: int (struct ldb_control **) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) +ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) +ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_comp_num: int (struct ldb_dn *) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) +ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_minimise: bool (struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) +ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handle_use_global_event_context: void (struct ldb_handle *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_map_add: int (struct ldb_module *, struct ldb_request *) +ldb_map_delete: int (struct ldb_module *, struct ldb_request *) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_map_modify: int (struct ldb_module *, struct ldb_request *) +ldb_map_rename: int (struct ldb_module *, struct ldb_request *) +ldb_map_search: int (struct ldb_module *, struct ldb_request *) +ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) +ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_flags: uint32_t (struct ldb_context *) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) +ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_next: struct ldb_module *(struct ldb_module *) +ldb_module_popt_options: struct poptOption **(struct ldb_context *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_modules_load: int (const char *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) +ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(TALLOC_CTX *) +ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_read_lock: int (struct ldb_module *) +ldb_next_read_unlock: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_options_copy: const char **(TALLOC_CTX *, const char **) +ldb_options_find: const char *(struct ldb_context *, const char **, const char *) +ldb_options_get: const char **(struct ldb_context *) +ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t) +ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn, bool) +ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) +ldb_register_hook: int (ldb_hook_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_req_get_custom_flags: uint32_t (struct ldb_request *) +ldb_req_is_untrusted: bool (struct ldb_request *) +ldb_req_location: const char *(struct ldb_request *) +ldb_req_mark_trusted: void (struct ldb_request *) +ldb_req_mark_untrusted: void (struct ldb_request *) +ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) +ldb_req_set_location: void (struct ldb_request *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) +ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_require_private_event_context: void (struct ldb_context *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) +ldb_unpack_data_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) +ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) +ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_string_cmp: int (const struct ldb_val *, const char *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-ildap-0.9.12.sigs b/ldb-2.0.8/ABI/ldb-ildap-0.9.12.sigs new file mode 100644 index 0000000..4639220 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-ildap-0.9.12.sigs @@ -0,0 +1,224 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(void *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(void *, const char *, int) +ldb_binary_decode: struct ldb_val (void *, const char *) +ldb_binary_encode: char *(void *, struct ldb_val) +ldb_binary_encode_string: char *(void *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, void *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, void *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, void *, const char *, size_t) +ldb_casefold_default: char *(void *, void *, const char *, size_t) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(void *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) +ldb_dn_canonical_string: char *(void *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(void *, struct ldb_dn *) +ldb_dn_escape_value: char *(void *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(void *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(void *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(void *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(void *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(void *, struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_init_module_chain: int (struct ldb_context *, struct ldb_module *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(void *) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(void *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_register_samba_handlers: int (struct ldb_context *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_samba_syntax_by_lDAPDisplayName: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_samba_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (void *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) +ldb_wrap_connect: struct ldb_context *(TALLOC_CTX *, struct tevent_context *, struct loadparm_context *, const char *, struct auth_session_info *, struct cli_credentials *, unsigned int) +ldb_wrap_fork_hook: void (void) diff --git a/ldb-2.0.8/ABI/ldb-samba4-0.9.10.sigs b/ldb-2.0.8/ABI/ldb-samba4-0.9.10.sigs new file mode 100644 index 0000000..7f9dbb5 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-samba4-0.9.10.sigs @@ -0,0 +1,223 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(void *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(void *, const char *, int) +ldb_binary_decode: struct ldb_val (void *, const char *) +ldb_binary_encode: char *(void *, struct ldb_val) +ldb_binary_encode_string: char *(void *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, void *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, void *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, void *, const char *, size_t) +ldb_casefold_default: char *(void *, void *, const char *, size_t) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(void *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) +ldb_dn_canonical_string: char *(void *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(void *, struct ldb_dn *) +ldb_dn_escape_value: char *(void *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(void *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(void *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(void *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(void *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(void *, struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_init_module_chain: int (struct ldb_context *, struct ldb_module *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(void *) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(void *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_register_samba_handlers: int (struct ldb_context *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_samba_syntax_by_lDAPDisplayName: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_samba_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (void *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) +ldb_wrap_connect: struct ldb_context *(TALLOC_CTX *, struct tevent_context *, struct loadparm_context *, const char *, struct auth_session_info *, struct cli_credentials *, unsigned int) +ldb_wrap_fork_hook: void (void) diff --git a/ldb-2.0.8/ABI/ldb-samba4-0.9.11.sigs b/ldb-2.0.8/ABI/ldb-samba4-0.9.11.sigs new file mode 100644 index 0000000..4639220 --- /dev/null +++ b/ldb-2.0.8/ABI/ldb-samba4-0.9.11.sigs @@ -0,0 +1,224 @@ +ldb_add: int (struct ldb_context *, const struct ldb_message *) +ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) +ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) +ldb_attr_casefold: char *(void *, const char *) +ldb_attr_dn: int (const char *) +ldb_attr_in_list: int (const char * const *, const char *) +ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) +ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) +ldb_base64_decode: int (char *) +ldb_base64_encode: char *(void *, const char *, int) +ldb_binary_decode: struct ldb_val (void *, const char *) +ldb_binary_encode: char *(void *, struct ldb_val) +ldb_binary_encode_string: char *(void *, const char *) +ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, void *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, void *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) +ldb_casefold: char *(struct ldb_context *, void *, const char *, size_t) +ldb_casefold_default: char *(void *, void *, const char *, size_t) +ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) +ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) +ldb_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) +ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_debug_add: void (struct ldb_context *, const char *, ...) +ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) +ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) +ldb_delete: int (struct ldb_context *, struct ldb_dn *) +ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) +ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) +ldb_dn_alloc_casefold: char *(void *, struct ldb_dn *) +ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) +ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) +ldb_dn_canonical_string: char *(void *, struct ldb_dn *) +ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) +ldb_dn_check_special: bool (struct ldb_dn *, const char *) +ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) +ldb_dn_copy: struct ldb_dn *(void *, struct ldb_dn *) +ldb_dn_escape_value: char *(void *, struct ldb_val) +ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) +ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) +ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) +ldb_dn_from_ldb_val: struct ldb_dn *(void *, struct ldb_context *, const struct ldb_val *) +ldb_dn_get_casefold: const char *(struct ldb_dn *) +ldb_dn_get_comp_num: int (struct ldb_dn *) +ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) +ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) +ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) +ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) +ldb_dn_get_linearized: const char *(struct ldb_dn *) +ldb_dn_get_parent: struct ldb_dn *(void *, struct ldb_dn *) +ldb_dn_get_rdn_name: const char *(struct ldb_dn *) +ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) +ldb_dn_has_extended: bool (struct ldb_dn *) +ldb_dn_is_null: bool (struct ldb_dn *) +ldb_dn_is_special: bool (struct ldb_dn *) +ldb_dn_is_valid: bool (struct ldb_dn *) +ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) +ldb_dn_new: struct ldb_dn *(void *, struct ldb_context *, const char *) +ldb_dn_new_fmt: struct ldb_dn *(void *, struct ldb_context *, const char *, ...) +ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) +ldb_dn_remove_extended_components: void (struct ldb_dn *) +ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) +ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) +ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) +ldb_dn_validate: bool (struct ldb_dn *) +ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) +ldb_errstring: const char *(struct ldb_context *) +ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) +ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_filter_from_tree: char *(void *, struct ldb_parse_tree *) +ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_create_perms: unsigned int (struct ldb_context *) +ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_event_context: struct tevent_context *(struct ldb_context *) +ldb_get_flags: unsigned int (struct ldb_context *) +ldb_get_opaque: void *(struct ldb_context *, const char *) +ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) +ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) +ldb_global_init: int (void) +ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) +ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) +ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) +ldb_init_module_chain: int (struct ldb_context *, struct ldb_module *) +ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) +ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) +ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) +ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) +ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) +ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) +ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) +ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) +ldb_load_modules: int (struct ldb_context *, const char **) +ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) +ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) +ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) +ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) +ldb_mod_register_control: int (struct ldb_module *, const char *) +ldb_modify: int (struct ldb_context *, const struct ldb_message *) +ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) +ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) +ldb_module_get_name: const char *(struct ldb_module *) +ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) +ldb_module_get_private: void *(struct ldb_module *) +ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) +ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) +ldb_module_send_referral: int (struct ldb_request *, char *) +ldb_module_set_private: void (struct ldb_module *, void *) +ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) +ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) +ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) +ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) +ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) +ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) +ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) +ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) +ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) +ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) +ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) +ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) +ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) +ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) +ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, const struct ldb_message *, const char *) +ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) +ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) +ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) +ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) +ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) +ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) +ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) +ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) +ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) +ldb_msg_new: struct ldb_message *(void *) +ldb_msg_remove_attr: void (struct ldb_message *, const char *) +ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) +ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) +ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) +ldb_msg_sort_elements: void (struct ldb_message *) +ldb_next_del_trans: int (struct ldb_module *) +ldb_next_end_trans: int (struct ldb_module *) +ldb_next_init: int (struct ldb_module *) +ldb_next_prepare_commit: int (struct ldb_module *) +ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_request: int (struct ldb_module *, struct ldb_request *) +ldb_next_start_trans: int (struct ldb_module *) +ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) +ldb_parse_tree: struct ldb_parse_tree *(void *, const char *) +ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) +ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) +ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) +ldb_register_backend: int (const char *, ldb_connect_fn) +ldb_register_module: int (const struct ldb_module_ops *) +ldb_register_samba_handlers: int (struct ldb_context *) +ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) +ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) +ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) +ldb_request: int (struct ldb_context *, struct ldb_request *) +ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) +ldb_request_done: int (struct ldb_request *, int) +ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) +ldb_request_get_status: int (struct ldb_request *) +ldb_request_set_state: void (struct ldb_request *, int) +ldb_reset_err_string: void (struct ldb_context *) +ldb_samba_syntax_by_lDAPDisplayName: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_samba_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) +ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) +ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) +ldb_schema_attribute_remove: void (struct ldb_context *, const char *) +ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) +ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) +ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) +ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) +ldb_set_create_perms: void (struct ldb_context *, unsigned int) +ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) +ldb_set_debug_stderr: int (struct ldb_context *) +ldb_set_default_dns: void (struct ldb_context *) +ldb_set_errstring: void (struct ldb_context *, const char *) +ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) +ldb_set_flags: void (struct ldb_context *, unsigned int) +ldb_set_modules_dir: void (struct ldb_context *, const char *) +ldb_set_opaque: int (struct ldb_context *, const char *, void *) +ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) +ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) +ldb_set_utf8_default: void (struct ldb_context *) +ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) +ldb_setup_wellknown_attributes: int (struct ldb_context *) +ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) +ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) +ldb_strerror: const char *(int) +ldb_string_to_time: time_t (const char *) +ldb_string_utc_to_time: time_t (const char *) +ldb_timestring: char *(TALLOC_CTX *, time_t) +ldb_timestring_utc: char *(TALLOC_CTX *, time_t) +ldb_transaction_cancel: int (struct ldb_context *) +ldb_transaction_cancel_noerr: int (struct ldb_context *) +ldb_transaction_commit: int (struct ldb_context *) +ldb_transaction_prepare_commit: int (struct ldb_context *) +ldb_transaction_start: int (struct ldb_context *) +ldb_val_dup: struct ldb_val (void *, const struct ldb_val *) +ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) +ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) +ldb_val_to_time: int (const struct ldb_val *, time_t *) +ldb_valid_attr_name: int (const char *) +ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) +ldb_wrap_connect: struct ldb_context *(TALLOC_CTX *, struct tevent_context *, struct loadparm_context *, const char *, struct auth_session_info *, struct cli_credentials *, unsigned int) +ldb_wrap_fork_hook: void (void) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.10.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.10.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.10.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.11.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.11.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.11.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.12.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.12.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.12.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.13.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.13.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.13.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.14.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.14.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.14.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.15.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.15.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.15.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.16.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.16.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.16.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.17.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.17.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.17.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.18.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.18.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.18.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.19.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.19.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.19.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.2.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.2.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.2.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.20.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.20.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.20.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.21.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.21.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.21.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.22.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.22.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.22.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.23.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.23.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.23.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.24.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.24.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.24.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.25.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.25.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.25.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.26.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.26.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.26.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.27.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.27.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.27.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.28.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.28.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.28.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.29.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.29.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.29.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.3.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.3.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.3.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.30.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.30.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.30.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.31.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.31.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.31.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.4.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.4.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.4.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.5.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.5.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.5.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.6.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.6.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.6.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.7.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.7.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.7.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.8.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.8.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.8.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.9.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.9.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.1.9.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.2.0.sigs b/ldb-2.0.8/ABI/pyldb-util-1.2.0.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.2.0.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.2.1.sigs b/ldb-2.0.8/ABI/pyldb-util-1.2.1.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.2.1.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.2.2.sigs b/ldb-2.0.8/ABI/pyldb-util-1.2.2.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.2.2.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.2.3.sigs b/ldb-2.0.8/ABI/pyldb-util-1.2.3.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.2.3.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.3.0.sigs b/ldb-2.0.8/ABI/pyldb-util-1.3.0.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.3.0.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.3.1.sigs b/ldb-2.0.8/ABI/pyldb-util-1.3.1.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.3.1.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.3.2.sigs b/ldb-2.0.8/ABI/pyldb-util-1.3.2.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.3.2.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.4.0.sigs b/ldb-2.0.8/ABI/pyldb-util-1.4.0.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.4.0.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.4.1.sigs b/ldb-2.0.8/ABI/pyldb-util-1.4.1.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.4.1.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.5.0.sigs b/ldb-2.0.8/ABI/pyldb-util-1.5.0.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.5.0.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.5.1.sigs b/ldb-2.0.8/ABI/pyldb-util-1.5.1.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.5.1.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.5.2.sigs b/ldb-2.0.8/ABI/pyldb-util-1.5.2.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.5.2.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.5.3.sigs b/ldb-2.0.8/ABI/pyldb-util-1.5.3.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.5.3.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.6.0.sigs b/ldb-2.0.8/ABI/pyldb-util-1.6.0.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.6.0.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.6.1.sigs b/ldb-2.0.8/ABI/pyldb-util-1.6.1.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.6.1.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.6.2.sigs b/ldb-2.0.8/ABI/pyldb-util-1.6.2.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.6.2.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.6.3.sigs b/ldb-2.0.8/ABI/pyldb-util-1.6.3.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-1.6.3.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-2.0.0.sigs b/ldb-2.0.8/ABI/pyldb-util-2.0.0.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-2.0.0.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-2.0.1.sigs b/ldb-2.0.8/ABI/pyldb-util-2.0.1.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-2.0.1.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-2.0.2.sigs b/ldb-2.0.8/ABI/pyldb-util-2.0.2.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-2.0.2.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-2.0.3.sigs b/ldb-2.0.8/ABI/pyldb-util-2.0.3.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-2.0.3.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-2.0.4.sigs b/ldb-2.0.8/ABI/pyldb-util-2.0.4.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-2.0.4.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-2.0.5.sigs b/ldb-2.0.8/ABI/pyldb-util-2.0.5.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-2.0.5.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-2.0.6.sigs b/ldb-2.0.8/ABI/pyldb-util-2.0.6.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-2.0.6.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-2.0.7.sigs b/ldb-2.0.8/ABI/pyldb-util-2.0.7.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-2.0.7.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-2.0.8.sigs b/ldb-2.0.8/ABI/pyldb-util-2.0.8.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util-2.0.8.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util.py3-2.0.0.sigs b/ldb-2.0.8/ABI/pyldb-util.py3-2.0.0.sigs new file mode 100644 index 0000000..74d6719 --- /dev/null +++ b/ldb-2.0.8/ABI/pyldb-util.py3-2.0.0.sigs @@ -0,0 +1,2 @@ +pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) +pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/Doxyfile b/ldb-2.0.8/Doxyfile new file mode 100644 index 0000000..07b12b5 --- /dev/null +++ b/ldb-2.0.8/Doxyfile @@ -0,0 +1,26 @@ +PROJECT_NAME = LDB +OUTPUT_DIRECTORY = apidocs +REPEAT_BRIEF = YES +OPTIMIZE_OUTPUT_FOR_C = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +GENERATE_TODOLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +SHOW_USED_FILES = NO +SHOW_DIRECTORIES = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +INPUT = include . +FILE_PATTERNS = *.h *.dox +EXCLUDE = include/config.h include/dlinklist.h \ + include/includes.h +EXAMPLE_PATH = examples +GENERATE_HTML = YES +HTML_OUTPUT = html +GENERATE_MAN = YES +ALWAYS_DETAILED_SEC = YES +JAVADOC_AUTOBRIEF = YES diff --git a/ldb-2.0.8/Makefile b/ldb-2.0.8/Makefile new file mode 100644 index 0000000..b82723f --- /dev/null +++ b/ldb-2.0.8/Makefile @@ -0,0 +1,53 @@ +# simple makefile wrapper to run waf + +WAF_BIN=`PATH=buildtools/bin:../../buildtools/bin:$$PATH which waf` +WAF_BINARY=$(PYTHON) $(WAF_BIN) +WAF=PYTHONHASHSEED=1 WAF_MAKE=1 $(WAF_BINARY) + +all: + $(WAF) build + +install: + $(WAF) install + +uninstall: + $(WAF) uninstall + +test: + $(WAF) test $(TEST_OPTIONS) + +dist: + touch .tmplock + WAFLOCK=.tmplock $(WAF) dist + +distcheck: + touch .tmplock + WAFLOCK=.tmplock $(WAF) distcheck + +clean: + $(WAF) clean + +distclean: + $(WAF) distclean + +reconfigure: configure + $(WAF) reconfigure + +show_waf_options: + $(WAF) --help + +# some compatibility make targets +everything: all + +testsuite: all + +check: test + +# this should do an install as well, once install is finished +installcheck: test + +etags: + $(WAF) etags + +ctags: + $(WAF) ctags diff --git a/ldb-2.0.8/README_gcov.txt b/ldb-2.0.8/README_gcov.txt new file mode 100644 index 0000000..2abd937 --- /dev/null +++ b/ldb-2.0.8/README_gcov.txt @@ -0,0 +1,29 @@ +Here is how to use gcov to test code coverage in ldb. + +Step 1: build ldb with gcov enabled + + make clean all WITH_GCOV=1 + +Step 3: run the test suite + make test-tdb + +Step 4: produce the gcov report + make gcov + +Step 5: read the summary reports + less *.report.gcov + +Step 6: examine the per-file reports + less ldb_tdb\#ldb_tdb.c.gcov + +You can also combine steps 2 to 4 like this: + + make clean all test-tdb gcov WITH_GCOV=1 + +Note that you should not expect 100% coverage, as some error paths +(such as memory allocation failures) are very hard to trigger. There +are ways of working around this, but they are quite tricky (they +involve allocation wrappers that "fork and fail on malloc"). + +The lines to look for in the per-file reports are the ones starting +with "#####". Those are lines that are never executed. diff --git a/ldb-2.0.8/_ldb_text.py b/ldb-2.0.8/_ldb_text.py new file mode 100644 index 0000000..e0505e1 --- /dev/null +++ b/ldb-2.0.8/_ldb_text.py @@ -0,0 +1,146 @@ +# Text wrapper for ldb bindings +# +# Copyright (C) 2015 Petr Viktorin +# Published under the GNU LGPLv3 or later + +import ldb + + +def _recursive_encode(obj): + if isinstance(obj, bytes): + return obj + elif isinstance(obj, str): + return obj.encode('utf-8') + else: + return [_recursive_encode(o) for o in obj] + + +class _WrapBase(object): + + @classmethod + def _wrap(cls, wrapped): + self = cls.__new__(cls) + self._wrapped = wrapped + return self + + def __len__(self): + return len(self._wrapped) + + def __eq__(self, other): + if hasattr(other, '_wrapped'): + return self._wrapped == other._wrapped + else: + return self._wrapped == other + + def __ne__(self, other): + if hasattr(other, '_wrapped'): + return self._wrapped != other._wrapped + else: + return self._wrapped != other + + def __lt__(self, other): + if hasattr(other, '_wrapped'): + return self._wrapped < other._wrapped + else: + return self._wrapped < other + + def __le__(self, other): + if hasattr(other, '_wrapped'): + return self._wrapped >= other._wrapped + else: + return self._wrapped >= other + + def __gt__(self, other): + if hasattr(other, '_wrapped'): + return self._wrapped > other._wrapped + else: + return self._wrapped > other + + def __ge__(self, other): + if hasattr(other, '_wrapped'): + return self._wrapped >= other._wrapped + else: + return self._wrapped >= other + + def __repr__(self): + return '%s.text' % repr(self._wrapped) + + +class MessageElementTextWrapper(_WrapBase): + + """Text interface for a LDB message element""" + + def __iter__(self): + for item in self._wrapped: + yield item.decode('utf-8') + + def __getitem__(self, key): + result = self._wrapped[key] + if result is None: + return None + else: + return result.decode('utf-8') + + @property + def flags(self): + return self._wrapped.flags + + @property + def set_flags(self): + return self._wrapped.set_flags + + +_wrap_element = MessageElementTextWrapper._wrap + + +class MessageTextWrapper(_WrapBase): + + """Text interface for a LDB message""" + + def __getitem__(self, key): + result = self._wrapped[key] + if result is None: + return None + else: + return _wrap_element(result) + + def get(self, *args, **kwargs): + result = self._wrapped.get(*args, **kwargs) + if isinstance(result, ldb.MessageElement): + return _wrap_element(result) + elif isinstance(result, bytes): + return result.decode('utf-8') + else: + return result + + def __setitem__(self, key, item): + self._wrapped[key] = _recursive_encode(item) + + def __delitem__(self, key): + del self._wrapped[key] + + def elements(self): + return [_wrap_element(el) for el in self._wrapped.elements()] + + def items(self): + return [(attr, _wrap_element(el)) for attr, el in self._wrapped.items()] + + @property + def keys(self): + return self._wrapped.keys + + @property + def remove(self): + return self._wrapped.remove + + @property + def add(self): + return self._wrapped.add + + @property + def dn(self): + return self._wrapped.dn + + @dn.setter + def dn(self, new_value): + self._wrapped.dn = new_value diff --git a/ldb-2.0.8/buildtools/README b/ldb-2.0.8/buildtools/README new file mode 100644 index 0000000..eab0382 --- /dev/null +++ b/ldb-2.0.8/buildtools/README @@ -0,0 +1,12 @@ +See http://code.google.com/p/waf/ for more information on waf + +You can get a svn copy of the upstream source with: + + svn checkout http://waf.googlecode.com/svn/trunk/ waf-read-only + +Samba currently uses waf 1.5, which can be found at: + + http://waf.googlecode.com/svn/branches/waf-1.5 + +To update the current copy of waf, use the update-waf.sh script in this +directory. diff --git a/ldb-2.0.8/buildtools/bin/waf b/ldb-2.0.8/buildtools/bin/waf new file mode 100755 index 0000000..11ce8e7 --- /dev/null +++ b/ldb-2.0.8/buildtools/bin/waf @@ -0,0 +1,167 @@ +#!/usr/bin/env python3 +# encoding: latin-1 +# Thomas Nagy, 2005-2018 +# +""" +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +""" + +import os, sys, inspect + +VERSION="2.0.18" +REVISION="x" +GIT="x" +INSTALL="x" +C1='x' +C2='x' +C3='x' +cwd = os.getcwd() +join = os.path.join + +if sys.hexversion<0x206000f: + raise ImportError('Python >= 2.6 is required to create the waf file') + +WAF='waf' +def b(x): + return x +if sys.hexversion>0x300000f: + WAF='waf3' + def b(x): + return x.encode() + +def err(m): + print(('\033[91mError: %s\033[0m' % m)) + sys.exit(1) + +def unpack_wafdir(dir, src): + f = open(src,'rb') + c = 'corrupt archive (%d)' + while 1: + line = f.readline() + if not line: err('run waf-light from a folder containing waflib') + if line == b('#==>\n'): + txt = f.readline() + if not txt: err(c % 1) + if f.readline() != b('#<==\n'): err(c % 2) + break + if not txt: err(c % 3) + txt = txt[1:-1].replace(b(C1), b('\n')).replace(b(C2), b('\r')).replace(b(C3), b('\x00')) + + import shutil, tarfile + try: shutil.rmtree(dir) + except OSError: pass + try: + for x in ('Tools', 'extras'): + os.makedirs(join(dir, 'waflib', x)) + except OSError: + err("Cannot unpack waf lib into %s\nMove waf in a writable directory" % dir) + + os.chdir(dir) + tmp = 't.bz2' + t = open(tmp,'wb') + try: t.write(txt) + finally: t.close() + + try: + t = tarfile.open(tmp) + except: + try: + os.system('bunzip2 t.bz2') + t = tarfile.open('t') + tmp = 't' + except: + os.chdir(cwd) + try: shutil.rmtree(dir) + except OSError: pass + err("Waf cannot be unpacked, check that bzip2 support is present") + + try: + for x in t: t.extract(x) + finally: + t.close() + + for x in ('Tools', 'extras'): + os.chmod(join('waflib',x), 493) + + if sys.hexversion<0x300000f: + sys.path = [join(dir, 'waflib')] + sys.path + import fixpy2 + fixpy2.fixdir(dir) + + os.remove(tmp) + os.chdir(cwd) + + try: dir = unicode(dir, 'mbcs') + except: pass + try: + from ctypes import windll + windll.kernel32.SetFileAttributesW(dir, 2) + except: + pass + +def test(dir): + try: + os.stat(join(dir, 'waflib')) + return os.path.abspath(dir) + except OSError: + pass + +def find_lib(): + path = '../../third_party/waf' + paths = [path, path+'/waflib'] + return [os.path.abspath(os.path.join(os.path.dirname(__file__), x)) for x in paths] + +wafdir = find_lib() +for p in wafdir: + sys.path.insert(0, p) + +if __name__ == '__main__': + #import extras.compat15#PRELUDE + import sys + + from waflib.Tools import ccroot, c, ar, compiler_c, gcc + sys.modules['cc'] = c + sys.modules['ccroot'] = ccroot + sys.modules['ar'] = ar + sys.modules['compiler_cc'] = compiler_c + sys.modules['gcc'] = gcc + + from waflib import Options + Options.lockfile = os.environ.get('WAFLOCK', '.lock-wscript') + if os.path.isfile(Options.lockfile) and os.stat(Options.lockfile).st_size == 0: + os.environ['NOCLIMB'] = "1" + # there is a single top-level, but libraries must build independently + os.environ['NO_LOCK_IN_TOP'] = "1" + + from waflib import Task + class o(object): + display = None + Task.classes['cc_link'] = o + + from waflib import Scripting + Scripting.waf_entry_point(cwd, VERSION, wafdir[0]) + diff --git a/ldb-2.0.8/buildtools/compare_config_h4.sh b/ldb-2.0.8/buildtools/compare_config_h4.sh new file mode 100755 index 0000000..b78b36f --- /dev/null +++ b/ldb-2.0.8/buildtools/compare_config_h4.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +# compare the generated config.h from a waf build with existing samba +# build + +grep "^.define" bin/default/source4/include/config.h | sort > waf-config.h +grep "^.define" $HOME/samba_old/source4/include/config.h | sort > old-config.h + +comm -23 old-config.h waf-config.h + +#echo +#diff -u old-config.h waf-config.h diff --git a/ldb-2.0.8/buildtools/compare_generated.sh b/ldb-2.0.8/buildtools/compare_generated.sh new file mode 100755 index 0000000..ebef8a9 --- /dev/null +++ b/ldb-2.0.8/buildtools/compare_generated.sh @@ -0,0 +1,50 @@ +#!/bin/sh + +# compare the generated files from a waf + +old_build=$HOME/samba_old + +gen_files=$(cd bin/default && find . -type f -name '*.[ch]') + +2>&1 + +strip_file() +{ + in_file=$1 + out_file=$2 + cat $in_file | + grep -v 'The following definitions come from' | + grep -v 'Automatically generated at' | + grep -v 'Generated from' | + sed 's|/home/tnagy/samba/source4||g' | + sed 's|/home/tnagy/samba/|../|g' | + sed 's|bin/default/source4/||g' | + sed 's|bin/default/|../|g' | + sed 's/define _____/define ___/g' | + sed 's/define __*/define _/g' | + sed 's/define _DEFAULT_/define _/g' | + sed 's/define _SOURCE4_/define ___/g' | + sed 's/define ___/define _/g' | + sed 's/ifndef ___/ifndef _/g' | + sed 's|endif /* ____|endif /* __|g' | + sed s/__DEFAULT_SOURCE4/__/ | + sed s/__DEFAULT_SOURCE4/__/ | + sed s/__DEFAULT/____/ > $out_file +} + +compare_file() +{ + f=$f + bname=$(basename $f) + t1=/tmp/$bname.old.$$ + t2=/tmp/$bname.new.$$ + strip_file $old_build/$f $t1 + strip_file bin/default/$f $t2 + diff -u -b $t1 $t2 2>&1 + rm -f $t1 $t2 +} + +for f in $gen_files; do + compare_file $f +done + diff --git a/ldb-2.0.8/buildtools/compare_install.sh b/ldb-2.0.8/buildtools/compare_install.sh new file mode 100755 index 0000000..b964117 --- /dev/null +++ b/ldb-2.0.8/buildtools/compare_install.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +prefix1="$1" +prefix2="$2" + +(cd $prefix1 && find . ) | sort > p1.txt +(cd $prefix2 && find . ) | sort > p2.txt +diff -u p[12].txt diff --git a/ldb-2.0.8/buildtools/examples/run_on_target.py b/ldb-2.0.8/buildtools/examples/run_on_target.py new file mode 100755 index 0000000..79c5730 --- /dev/null +++ b/ldb-2.0.8/buildtools/examples/run_on_target.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python3 + +# +# Sample run-on-target script +# This is a script that can be used as cross-execute parameter to samba +# configuration process, running the command on a remote target for which +# the cross-compiled configure test was compiled. +# +# To use: +# ./configure \ +# --cross-compile \ +# '--cross-execute=./buildtools/example/run_on_target.py --host=' +# +# A more elaborate example: +# ./configure \ +# --cross-compile \ +# '--cross-execute=./buildtools/example/run_on_target.py --host= --user= "--ssh=ssh -i " --destdir=/path/to/dir' +# +# Typically this is to be used also with --cross-answers, so that the +# cross answers file gets built and further builds can be made without +# the help of a remote target. +# +# The following assumptions are made: +# 1. rsync is available on build machine and target machine +# 2. A running ssh service on target machine with password-less shell login +# 3. A directory writable by the password-less login user +# 4. The tests on the target can run and provide reliable results +# from the login account's home directory. This is significant +# for example in locking tests which +# create files in the current directory. As a workaround to this +# assumption, the TESTDIR environment variable can be set on the target +# (using ssh command line or server config) and the tests shall +# chdir to that directory. +# + +import sys +import os +import subprocess +from optparse import OptionParser + +# those are defaults, but can be overidden using command line +SSH = 'ssh' +USER = None +HOST = 'localhost' + + +def xfer_files(ssh, srcdir, host, user, targ_destdir): + """Transfer executable files to target + + Use rsync to copy the directory containing program to run + INTO a destination directory on the target. An exact copy + of the source directory is created on the target machine, + possibly deleting files on the target machine which do not + exist on the source directory. + + The idea is that the test may include files in addition to + the compiled binary, and all of those files reside alongside + the binary in a source directory. + + For example, if the test to run is /foo/bar/test and the + destination directory on the target is /tbaz, then /tbaz/bar + on the target shall be an exact copy of /foo/bar on the source, + including deletion of files inside /tbaz/bar which do not exist + on the source. + """ + + userhost = host + if user: + userhost = '%s@%s' % (user, host) + + cmd = 'rsync --verbose -rl --ignore-times --delete -e "%s" %s %s:%s/' % \ + (ssh, srcdir, userhost, targ_destdir) + p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + (out, err) = p.communicate() + if p.returncode != 0: + raise Exception('failed syncing files\n stdout:\n%s\nstderr:%s\n' + % (out, err)) + + +def exec_remote(ssh, host, user, destdir, targdir, prog, args): + """Run a test on the target + + Using password-less ssh, run the compiled binary on the target. + + An assumption is that there's no need to cd into the target dir, + same as there's no need to do it on a native build. + """ + userhost = host + if user: + userhost = '%s@%s' % (user, host) + + cmd = '%s %s %s/%s/%s' % (ssh, userhost, destdir, targdir, prog) + if args: + cmd = cmd + ' ' + ' '.join(args) + p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + (out, err) = p.communicate() + return (p.returncode, out) + + +def main(argv): + usage = "usage: %prog [options] [args]" + parser = OptionParser(usage) + + parser.add_option('--ssh', help="SSH client and additional flags", + default=SSH) + parser.add_option('--host', help="target host name or IP address", + default=HOST) + parser.add_option('--user', help="login user on target", + default=USER) + parser.add_option('--destdir', help="work directory on target", + default='~') + + (options, args) = parser.parse_args(argv) + if len(args) < 1: + parser.error("please supply test program to run") + + progpath = args[0] + + # assume that a test that was not compiled fails (e.g. getconf) + if progpath[0] != '/': + return (1, "") + + progdir = os.path.dirname(progpath) + prog = os.path.basename(progpath) + targ_progdir = os.path.basename(progdir) + + xfer_files( + options.ssh, + progdir, + options.host, + options.user, + options.destdir) + + (rc, out) = exec_remote(options.ssh, + options.host, + options.user, + options.destdir, + targ_progdir, + prog, args[1:]) + return (rc, out) + + +if __name__ == '__main__': + (rc, out) = main(sys.argv[1:]) + sys.stdout.write(out) + sys.exit(rc) diff --git a/ldb-2.0.8/buildtools/scripts/Makefile.waf b/ldb-2.0.8/buildtools/scripts/Makefile.waf new file mode 100644 index 0000000..5fc939c --- /dev/null +++ b/ldb-2.0.8/buildtools/scripts/Makefile.waf @@ -0,0 +1,72 @@ +# simple makefile wrapper to run waf + +WAF_BINARY=BUILDTOOLS/bin/waf +WAF=WAF_MAKE=1 $(WAF_BINARY) + +all: + $(WAF) build + +install: + $(WAF) install + +uninstall: + $(WAF) uninstall + +test: + $(WAF) test $(TEST_OPTIONS) + +help: + @echo NOTE: to run extended waf options use $(WAF_BINARY) or modify your PATH + $(WAF) --help + +testenv: + $(WAF) test --testenv $(TEST_OPTIONS) + +quicktest: + $(WAF) test --quick $(TEST_OPTIONS) + +dist: + $(WAF) dist + +distcheck: + $(WAF) distcheck + +clean: + $(WAF) clean + +distclean: + $(WAF) distclean + +reconfigure: configure + $(WAF) reconfigure + +show_waf_options: + $(WAF) --help + +# some compatibility make targets +everything: all + +testsuite: all + +check: test + +torture: all + +# this should do an install as well, once install is finished +installcheck: test + +etags: + $(WAF) etags + +ctags: + $(WAF) ctags + +bin/%:: FORCE + $(WAF) --targets=$@ +FORCE: + +configure: autogen-waf.sh BUILDTOOLS/scripts/configure.waf + ./autogen-waf.sh + +Makefile: autogen-waf.sh configure BUILDTOOLS/scripts/Makefile.waf + ./autogen-waf.sh diff --git a/ldb-2.0.8/buildtools/scripts/abi_gen.sh b/ldb-2.0.8/buildtools/scripts/abi_gen.sh new file mode 100755 index 0000000..6dd6d32 --- /dev/null +++ b/ldb-2.0.8/buildtools/scripts/abi_gen.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# generate a set of ABI signatures from a shared library + +SHAREDLIB="$1" + +GDBSCRIPT="gdb_syms.$$" + +( +cat < $GDBSCRIPT + +# forcing the terminal avoids a problem on Fedora12 +TERM=none gdb -n -batch -x $GDBSCRIPT "$SHAREDLIB" < /dev/null +rm -f $GDBSCRIPT diff --git a/ldb-2.0.8/buildtools/scripts/autogen-waf.sh b/ldb-2.0.8/buildtools/scripts/autogen-waf.sh new file mode 100755 index 0000000..7a6e94c --- /dev/null +++ b/ldb-2.0.8/buildtools/scripts/autogen-waf.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +p=`dirname $0` + +echo "Setting up for waf build" + +echo "Looking for the buildtools directory" + +d="buildtools" +while test \! -d "$p/$d"; do d="../$d"; done + +echo "Found buildtools in $p/$d" + +echo "Setting up configure" +rm -f $p/configure $p/include/config*.h* +sed "s|BUILDTOOLS|$d|g;s|BUILDPATH|$p|g" < "$p/$d/scripts/configure.waf" > $p/configure +chmod +x $p/configure + +echo "Setting up Makefile" +rm -f $p/makefile $p/Makefile +sed "s|BUILDTOOLS|$d|g" < "$p/$d/scripts/Makefile.waf" > $p/Makefile + +echo "done. Now run $p/configure or $p/configure.developer then make." +if [ $p != "." ]; then + echo "Notice: The build invoke path is not 'source4'! Use make with the parameter" + echo "-C <'source4' path>. Example: make -C source4 all" +fi diff --git a/ldb-2.0.8/buildtools/scripts/configure.waf b/ldb-2.0.8/buildtools/scripts/configure.waf new file mode 100755 index 0000000..a7d8d1d --- /dev/null +++ b/ldb-2.0.8/buildtools/scripts/configure.waf @@ -0,0 +1,14 @@ +#!/bin/sh + +PREVPATH=`dirname $0` + +WAF=BUILDTOOLS/bin/waf + +# using JOBS=1 gives maximum compatibility with +# systems like AIX which have broken threading in python +JOBS=1 +export JOBS + +cd BUILDPATH || exit 1 +$WAF configure "$@" || exit 1 +cd $PREVPATH diff --git a/ldb-2.0.8/buildtools/testwaf.sh b/ldb-2.0.8/buildtools/testwaf.sh new file mode 100755 index 0000000..127e525 --- /dev/null +++ b/ldb-2.0.8/buildtools/testwaf.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +set -e +set -x + +d=$(dirname $0) + +cd $d/.. +PREFIX=$HOME/testprefix + +if [ $# -gt 0 ]; then + tests="$*" +else + tests="lib/replace lib/talloc lib/tevent lib/tdb lib/ldb" +fi + +echo "testing in dirs $tests" + +for d in $tests; do + echo "`date`: testing $d" + pushd $d + rm -rf bin + type waf + waf dist + ./configure -C --enable-developer --prefix=$PREFIX + time make + make install + make distcheck + case $d in + "lib/ldb") + ldd bin/ldbadd + ;; + "lib/replace") + ldd bin/replace_testsuite + ;; + "lib/talloc") + ldd bin/talloc_testsuite + ;; + "lib/tdb") + ldd bin/tdbtool + ;; + esac + popd +done + +echo "testing python portability" +pushd lib/talloc +versions="python2.4 python2.5 python2.6 python3.0 python3.1" +for p in $versions; do + ret=$(which $p || echo "failed") + if [ $ret = "failed" ]; then + echo "$p not found, skipping" + continue + fi + echo "Testing $p" + $p ../../buildtools/bin/waf configure -C --enable-developer --prefix=$PREFIX + $p ../../buildtools/bin/waf build install +done +popd + +echo "testing cross compiling" +pushd lib/talloc +ret=$(which arm-linux-gnueabi-gcc || echo "failed") +if [ $ret != "failed" ]; then + CC=arm-linux-gnueabi-gcc ./configure -C --prefix=$PREFIX --cross-compile --cross-execute='runarm' + make && make install +else + echo "Cross-compiler not installed, skipping test" +fi +popd diff --git a/ldb-2.0.8/buildtools/wafsamba/README b/ldb-2.0.8/buildtools/wafsamba/README new file mode 100644 index 0000000..1968b55 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/README @@ -0,0 +1,8 @@ +This is a set of waf 'tools' to help make building the Samba +components easier, by having common functions in one place. This gives +us a more consistent build, and ensures that our project rules are +obeyed + + +TODO: + see http://wiki.samba.org/index.php/Waf diff --git a/ldb-2.0.8/buildtools/wafsamba/__init__.py b/ldb-2.0.8/buildtools/wafsamba/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ldb-2.0.8/buildtools/wafsamba/configure_file.py b/ldb-2.0.8/buildtools/wafsamba/configure_file.py new file mode 100644 index 0000000..6ad4354 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/configure_file.py @@ -0,0 +1,41 @@ +# handle substitution of variables in .in files + +import sys +import re +import os +from waflib import Build, Logs +from samba_utils import SUBST_VARS_RECURSIVE + +def subst_at_vars(task): + '''substiture @VAR@ style variables in a file''' + + env = task.env + s = task.inputs[0].read() + + # split on the vars + a = re.split('(@\w+@)', s) + out = [] + for v in a: + if re.match('@\w+@', v): + vname = v[1:-1] + if not vname in task.env and vname.upper() in task.env: + vname = vname.upper() + if not vname in task.env: + Logs.error("Unknown substitution %s in %s" % (v, task.name)) + sys.exit(1) + v = SUBST_VARS_RECURSIVE(task.env[vname], task.env) + out.append(v) + contents = ''.join(out) + task.outputs[0].write(contents) + return 0 + +def CONFIGURE_FILE(bld, in_file, **kwargs): + '''configure file''' + + base=os.path.basename(in_file) + t = bld.SAMBA_GENERATOR('INFILE_%s' % base, + rule = subst_at_vars, + source = in_file + '.in', + target = in_file, + vars = kwargs) +Build.BuildContext.CONFIGURE_FILE = CONFIGURE_FILE diff --git a/ldb-2.0.8/buildtools/wafsamba/generic_cc.py b/ldb-2.0.8/buildtools/wafsamba/generic_cc.py new file mode 100644 index 0000000..1352c54 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/generic_cc.py @@ -0,0 +1,70 @@ + +# compiler definition for a generic C compiler +# based on suncc.py from waf + +import os, optparse +from waflib import Errors +from waflib.Tools import ccroot, ar +from waflib.Configure import conf + +# +# Let waflib provide useful defaults, but +# provide generic_cc as last resort fallback on +# all platforms +# +from waflib.Tools.compiler_c import c_compiler +for key in c_compiler.keys(): + c_compiler[key].append('generic_cc') + +@conf +def find_generic_cc(conf): + v = conf.env + cc = None + if v.CC: + cc = v.CC + elif 'CC' in conf.environ: + cc = conf.environ['CC'] + if not cc: + cc = conf.find_program('cc', var='CC') + if not cc: + conf.fatal('generic_cc was not found') + + try: + conf.cmd_and_log(cc + ['--version']) + except Errors.WafError: + conf.fatal('%r --version could not be executed' % cc) + + v.CC = cc + v.CC_NAME = 'generic_cc' + +@conf +def generic_cc_common_flags(conf): + v = conf.env + + v.CC_SRC_F = '' + v.CC_TGT_F = ['-c', '-o'] + v.CPPPATH_ST = '-I%s' + v.DEFINES_ST = '-D%s' + + if not v.LINK_CC: + v.LINK_CC = v.CC + + v.CCLNK_SRC_F = '' + v.CCLNK_TGT_F = ['-o'] + + v.LIB_ST = '-l%s' # template for adding libs + v.LIBPATH_ST = '-L%s' # template for adding libpaths + v.STLIB_ST = '-l%s' + v.STLIBPATH_ST = '-L%s' + + v.cprogram_PATTERN = '%s' + v.cshlib_PATTERN = 'lib%s.so' + v.cstlib_PATTERN = 'lib%s.a' + +def configure(conf): + conf.find_generic_cc() + conf.find_ar() + conf.generic_cc_common_flags() + conf.cc_load_tools() + conf.cc_add_flags() + conf.link_add_flags() diff --git a/ldb-2.0.8/buildtools/wafsamba/pkgconfig.py b/ldb-2.0.8/buildtools/wafsamba/pkgconfig.py new file mode 100644 index 0000000..b83d5f3 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/pkgconfig.py @@ -0,0 +1,68 @@ +# handle substitution of variables in pc files + +import os, re, sys +from waflib import Build, Logs +from samba_utils import SUBST_VARS_RECURSIVE, TO_LIST + +def subst_at_vars(task): + '''substiture @VAR@ style variables in a file''' + + s = task.inputs[0].read() + # split on the vars + a = re.split('(@\w+@)', s) + out = [] + done_var = {} + back_sub = [ ('PREFIX', '${prefix}'), ('EXEC_PREFIX', '${exec_prefix}')] + for v in a: + if re.match('@\w+@', v): + vname = v[1:-1] + if not vname in task.env and vname.upper() in task.env: + vname = vname.upper() + if not vname in task.env: + Logs.error("Unknown substitution %s in %s" % (v, task.name)) + sys.exit(1) + v = SUBST_VARS_RECURSIVE(task.env[vname], task.env) + # now we back substitute the allowed pc vars + for (b, m) in back_sub: + s = task.env[b] + if s == v[0:len(s)]: + if not b in done_var: + # we don't want to substitute the first usage + done_var[b] = True + else: + v = m + v[len(s):] + break + out.append(v) + contents = ''.join(out) + task.outputs[0].write(contents) + return 0 + + +def PKG_CONFIG_FILES(bld, pc_files, vnum=None, extra_name=None): + '''install some pkg_config pc files''' + dest = '${PKGCONFIGDIR}' + dest = bld.EXPAND_VARIABLES(dest) + for f in TO_LIST(pc_files): + if extra_name: + target = f.split('.pc')[0] + extra_name + ".pc" + else: + target = f + base=os.path.basename(target) + t = bld.SAMBA_GENERATOR('PKGCONFIG_%s' % base, + rule=subst_at_vars, + source=f+'.in', + target=target) + bld.add_manual_dependency(bld.path.find_or_declare(f), bld.env['PREFIX'].encode('utf8')) + t.vars = [] + if t.env.RPATH_ON_INSTALL: + t.env.LIB_RPATH = t.env.RPATH_ST % t.env.LIBDIR + else: + t.env.LIB_RPATH = '' + if vnum: + t.env.PACKAGE_VERSION = vnum + for v in [ 'PREFIX', 'EXEC_PREFIX', 'LIB_RPATH' ]: + t.vars.append(t.env[v]) + bld.INSTALL_FILES(dest, target, flat=True, destname=base) +Build.BuildContext.PKG_CONFIG_FILES = PKG_CONFIG_FILES + + diff --git a/ldb-2.0.8/buildtools/wafsamba/samba3.py b/ldb-2.0.8/buildtools/wafsamba/samba3.py new file mode 100644 index 0000000..5aab250 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/samba3.py @@ -0,0 +1,105 @@ +# a waf tool to add autoconf-like macros to the configure section +# and for SAMBA_ macros for building libraries, binaries etc + +import os +from waflib import Build +from samba_utils import os_path_relpath, TO_LIST +from samba_autoconf import library_flags + +def SAMBA3_IS_STATIC_MODULE(bld, module): + '''Check whether module is in static list''' + if module in bld.env['static_modules']: + return True + return False +Build.BuildContext.SAMBA3_IS_STATIC_MODULE = SAMBA3_IS_STATIC_MODULE + +def SAMBA3_IS_SHARED_MODULE(bld, module): + '''Check whether module is in shared list''' + if module in bld.env['shared_modules']: + return True + return False +Build.BuildContext.SAMBA3_IS_SHARED_MODULE = SAMBA3_IS_SHARED_MODULE + +def SAMBA3_IS_ENABLED_MODULE(bld, module): + '''Check whether module is in either shared or static list ''' + return SAMBA3_IS_STATIC_MODULE(bld, module) or SAMBA3_IS_SHARED_MODULE(bld, module) +Build.BuildContext.SAMBA3_IS_ENABLED_MODULE = SAMBA3_IS_ENABLED_MODULE + + + +def s3_fix_kwargs(bld, kwargs): + '''fix the build arguments for s3 build rules to include the + necessary includes, subdir and cflags options ''' + s3dir = os.path.join(bld.env.srcdir, 'source3') + s3reldir = os_path_relpath(s3dir, bld.path.abspath()) + + # the extra_includes list is relative to the source3 directory + extra_includes = [ '.', 'include', 'lib' ] + # local heimdal paths only included when USING_SYSTEM_KRB5 is not set + if not bld.CONFIG_SET("USING_SYSTEM_KRB5"): + extra_includes += [ '../source4/heimdal/lib/com_err', + '../source4/heimdal/lib/krb5', + '../source4/heimdal/lib/gssapi', + '../source4/heimdal_build', + '../bin/default/source4/heimdal/lib/asn1' ] + + if bld.CONFIG_SET('USING_SYSTEM_TDB'): + (tdb_includes, tdb_ldflags, tdb_cpppath) = library_flags(bld, 'tdb') + extra_includes += tdb_cpppath + else: + extra_includes += [ '../lib/tdb/include' ] + + if bld.CONFIG_SET('USING_SYSTEM_TEVENT'): + (tevent_includes, tevent_ldflags, tevent_cpppath) = library_flags(bld, 'tevent') + extra_includes += tevent_cpppath + else: + extra_includes += [ '../lib/tevent' ] + + if bld.CONFIG_SET('USING_SYSTEM_TALLOC'): + (talloc_includes, talloc_ldflags, talloc_cpppath) = library_flags(bld, 'talloc') + extra_includes += talloc_cpppath + else: + extra_includes += [ '../lib/talloc' ] + + if bld.CONFIG_SET('USING_SYSTEM_POPT'): + (popt_includes, popt_ldflags, popt_cpppath) = library_flags(bld, 'popt') + extra_includes += popt_cpppath + else: + extra_includes += [ '../lib/popt' ] + + # s3 builds assume that they will have a bunch of extra include paths + includes = [] + for d in extra_includes: + includes += [ os.path.join(s3reldir, d) ] + + # the rule may already have some includes listed + if 'includes' in kwargs: + includes += TO_LIST(kwargs['includes']) + kwargs['includes'] = includes + +# these wrappers allow for mixing of S3 and S4 build rules in the one build + +def SAMBA3_LIBRARY(bld, name, *args, **kwargs): + s3_fix_kwargs(bld, kwargs) + return bld.SAMBA_LIBRARY(name, *args, **kwargs) +Build.BuildContext.SAMBA3_LIBRARY = SAMBA3_LIBRARY + +def SAMBA3_MODULE(bld, name, *args, **kwargs): + s3_fix_kwargs(bld, kwargs) + return bld.SAMBA_MODULE(name, *args, **kwargs) +Build.BuildContext.SAMBA3_MODULE = SAMBA3_MODULE + +def SAMBA3_SUBSYSTEM(bld, name, *args, **kwargs): + s3_fix_kwargs(bld, kwargs) + return bld.SAMBA_SUBSYSTEM(name, *args, **kwargs) +Build.BuildContext.SAMBA3_SUBSYSTEM = SAMBA3_SUBSYSTEM + +def SAMBA3_BINARY(bld, name, *args, **kwargs): + s3_fix_kwargs(bld, kwargs) + return bld.SAMBA_BINARY(name, *args, **kwargs) +Build.BuildContext.SAMBA3_BINARY = SAMBA3_BINARY + +def SAMBA3_PYTHON(bld, name, *args, **kwargs): + s3_fix_kwargs(bld, kwargs) + return bld.SAMBA_PYTHON(name, *args, **kwargs) +Build.BuildContext.SAMBA3_PYTHON = SAMBA3_PYTHON diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_abi.py b/ldb-2.0.8/buildtools/wafsamba/samba_abi.py new file mode 100644 index 0000000..5e7686d --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/samba_abi.py @@ -0,0 +1,261 @@ +# functions for handling ABI checking of libraries + +import os +import sys +import re +import fnmatch + +from waflib import Options, Utils, Logs, Task, Build, Errors +from waflib.TaskGen import feature, before, after +from wafsamba import samba_utils + +# these type maps cope with platform specific names for common types +# please add new type mappings into the list below +abi_type_maps = { + '_Bool' : 'bool', + 'struct __va_list_tag *' : 'va_list' + } + +version_key = lambda x: list(map(int, x.split("."))) + +def normalise_signature(sig): + '''normalise a signature from gdb''' + sig = sig.strip() + sig = re.sub('^\$[0-9]+\s=\s\{(.+)\}$', r'\1', sig) + sig = re.sub('^\$[0-9]+\s=\s\{(.+)\}(\s0x[0-9a-f]+\s<\w+>)+$', r'\1', sig) + sig = re.sub('^\$[0-9]+\s=\s(0x[0-9a-f]+)\s?(<\w+>)?$', r'\1', sig) + sig = re.sub('0x[0-9a-f]+', '0xXXXX', sig) + sig = re.sub('", ', r'\1"', sig) + + for t in abi_type_maps: + # we need to cope with non-word characters in mapped types + m = t + m = m.replace('*', '\*') + if m[-1].isalnum() or m[-1] == '_': + m += '\\b' + if m[0].isalnum() or m[0] == '_': + m = '\\b' + m + sig = re.sub(m, abi_type_maps[t], sig) + return sig + + +def normalise_varargs(sig): + '''cope with older versions of gdb''' + sig = re.sub(',\s\.\.\.', '', sig) + return sig + + +def parse_sigs(sigs, abi_match): + '''parse ABI signatures file''' + abi_match = samba_utils.TO_LIST(abi_match) + ret = {} + a = sigs.split('\n') + for s in a: + if s.find(':') == -1: + continue + sa = s.split(':') + if abi_match: + matched = False + negative = False + for p in abi_match: + if p[0] == '!' and fnmatch.fnmatch(sa[0], p[1:]): + negative = True + break + elif fnmatch.fnmatch(sa[0], p): + matched = True + break + if (not matched) and negative: + continue + Logs.debug("%s -> %s" % (sa[1], normalise_signature(sa[1]))) + ret[sa[0]] = normalise_signature(sa[1]) + return ret + +def save_sigs(sig_file, parsed_sigs): + '''save ABI signatures to a file''' + sigs = '' + for s in sorted(parsed_sigs.keys()): + sigs += '%s: %s\n' % (s, parsed_sigs[s]) + return samba_utils.save_file(sig_file, sigs, create_dir=True) + + +def abi_check_task(self): + '''check if the ABI has changed''' + abi_gen = self.ABI_GEN + + libpath = self.inputs[0].abspath(self.env) + libname = os.path.basename(libpath) + + sigs = samba_utils.get_string(Utils.cmd_output([abi_gen, libpath])) + parsed_sigs = parse_sigs(sigs, self.ABI_MATCH) + + sig_file = self.ABI_FILE + + old_sigs = samba_utils.load_file(sig_file) + if old_sigs is None or Options.options.ABI_UPDATE: + if not save_sigs(sig_file, parsed_sigs): + raise Errors.WafError('Failed to save ABI file "%s"' % sig_file) + Logs.warn('Generated ABI signatures %s' % sig_file) + return + + parsed_old_sigs = parse_sigs(old_sigs, self.ABI_MATCH) + + # check all old sigs + got_error = False + for s in parsed_old_sigs: + if not s in parsed_sigs: + Logs.error('%s: symbol %s has been removed - please update major version\n\tsignature: %s' % ( + libname, s, parsed_old_sigs[s])) + got_error = True + elif normalise_varargs(parsed_old_sigs[s]) != normalise_varargs(parsed_sigs[s]): + Logs.error('%s: symbol %s has changed - please update major version\n\told_signature: %s\n\tnew_signature: %s' % ( + libname, s, parsed_old_sigs[s], parsed_sigs[s])) + got_error = True + + for s in parsed_sigs: + if not s in parsed_old_sigs: + Logs.error('%s: symbol %s has been added - please mark it _PRIVATE_ or update minor version\n\tsignature: %s' % ( + libname, s, parsed_sigs[s])) + got_error = True + + if got_error: + raise Errors.WafError('ABI for %s has changed - please fix library version then build with --abi-update\nSee http://wiki.samba.org/index.php/Waf#ABI_Checking for more information\nIf you have not changed any ABI, and your platform always gives this error, please configure with --abi-check-disable to skip this check' % libname) + + +t = Task.task_factory('abi_check', abi_check_task, color='BLUE', ext_in='.bin') +t.quiet = True +# allow "waf --abi-check" to force re-checking the ABI +if '--abi-check' in sys.argv: + t.always_run = True + +@after('apply_link') +@feature('abi_check') +def abi_check(self): + '''check that ABI matches saved signatures''' + env = self.bld.env + if not env.ABI_CHECK or self.abi_directory is None: + return + + # if the platform doesn't support -fvisibility=hidden then the ABI + # checks become fairly meaningless + if not env.HAVE_VISIBILITY_ATTR: + return + + topsrc = self.bld.srcnode.abspath() + abi_gen = os.path.join(topsrc, 'buildtools/scripts/abi_gen.sh') + + abi_file = "%s/%s-%s.sigs" % (self.abi_directory, self.version_libname, + self.vnum) + + tsk = self.create_task('abi_check', self.link_task.outputs[0]) + tsk.ABI_FILE = abi_file + tsk.ABI_MATCH = self.abi_match + tsk.ABI_GEN = abi_gen + + +def abi_process_file(fname, version, symmap): + '''process one ABI file, adding new symbols to the symmap''' + for line in Utils.readf(fname).splitlines(): + symname = line.split(":")[0] + if not symname in symmap: + symmap[symname] = version + + +def abi_write_vscript(f, libname, current_version, versions, symmap, abi_match): + """Write a vscript file for a library in --version-script format. + + :param f: File-like object to write to + :param libname: Name of the library, uppercased + :param current_version: Current version + :param versions: Versions to consider + :param symmap: Dictionary mapping symbols -> version + :param abi_match: List of symbols considered to be public in the current + version + """ + + invmap = {} + for s in symmap: + invmap.setdefault(symmap[s], []).append(s) + + last_key = "" + versions = sorted(versions, key=version_key) + for k in versions: + symver = "%s_%s" % (libname, k) + if symver == current_version: + break + f.write("%s {\n" % symver) + if k in sorted(invmap.keys()): + f.write("\tglobal:\n") + for s in invmap.get(k, []): + f.write("\t\t%s;\n" % s); + f.write("}%s;\n\n" % last_key) + last_key = " %s" % symver + f.write("%s {\n" % current_version) + local_abi = list(filter(lambda x: x[0] == '!', abi_match)) + global_abi = list(filter(lambda x: x[0] != '!', abi_match)) + f.write("\tglobal:\n") + if len(global_abi) > 0: + for x in global_abi: + f.write("\t\t%s;\n" % x) + else: + f.write("\t\t*;\n") + # Always hide symbols that must be local if exist + local_abi.extend(["!_end", "!__bss_start", "!_edata"]) + f.write("\tlocal:\n") + for x in local_abi: + f.write("\t\t%s;\n" % x[1:]) + if global_abi != ["*"]: + if len(global_abi) > 0: + f.write("\t\t*;\n") + f.write("};\n") + + +def abi_build_vscript(task): + '''generate a vscript file for our public libraries''' + + tgt = task.outputs[0].bldpath(task.env) + + symmap = {} + versions = [] + for f in task.inputs: + fname = f.abspath(task.env) + basename = os.path.basename(fname) + version = basename[len(task.env.LIBNAME)+1:-len(".sigs")] + versions.append(version) + abi_process_file(fname, version, symmap) + f = open(tgt, mode='w') + try: + abi_write_vscript(f, task.env.LIBNAME, task.env.VERSION, versions, + symmap, task.env.ABI_MATCH) + finally: + f.close() + + +def ABI_VSCRIPT(bld, libname, abi_directory, version, vscript, abi_match=None): + '''generate a vscript file for our public libraries''' + if abi_directory: + source = bld.path.ant_glob('%s/%s-[0-9]*.sigs' % (abi_directory, libname), flat=True) + def abi_file_key(path): + return version_key(path[:-len(".sigs")].rsplit("-")[-1]) + source = sorted(source.split(), key=abi_file_key) + else: + source = '' + + libname = os.path.basename(libname) + version = os.path.basename(version) + libname = libname.replace("-", "_").replace("+","_").upper() + version = version.replace("-", "_").replace("+","_").upper() + + t = bld.SAMBA_GENERATOR(vscript, + rule=abi_build_vscript, + source=source, + group='vscripts', + target=vscript) + if abi_match is None: + abi_match = ["*"] + else: + abi_match = samba_utils.TO_LIST(abi_match) + t.env.ABI_MATCH = abi_match + t.env.VERSION = version + t.env.LIBNAME = libname + t.vars = ['LIBNAME', 'VERSION', 'ABI_MATCH'] +Build.BuildContext.ABI_VSCRIPT = ABI_VSCRIPT diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_autoconf.py b/ldb-2.0.8/buildtools/wafsamba/samba_autoconf.py new file mode 100644 index 0000000..62d3e20 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/samba_autoconf.py @@ -0,0 +1,948 @@ +# a waf tool to add autoconf-like macros to the configure section + +import os, sys +from waflib import Build, Options, Logs, Context +from waflib.Configure import conf +from waflib.TaskGen import feature +from waflib.Tools import c_preproc as preproc +from samba_utils import TO_LIST, GET_TARGET_TYPE, SET_TARGET_TYPE, unique_list, mkdir_p + +missing_headers = set() + +#################################################### +# some autoconf like helpers, to make the transition +# to waf a bit easier for those used to autoconf +# m4 files + +@conf +def DEFINE(conf, d, v, add_to_cflags=False, quote=False): + '''define a config option''' + conf.define(d, v, quote=quote) + if add_to_cflags: + conf.env.append_value('CFLAGS', '-D%s=%s' % (d, str(v))) + +def hlist_to_string(conf, headers=None): + '''convert a headers list to a set of #include lines''' + hdrs='' + hlist = conf.env.hlist + if headers: + hlist = hlist[:] + hlist.extend(TO_LIST(headers)) + for h in hlist: + hdrs += '#include <%s>\n' % h + return hdrs + + +@conf +def COMPOUND_START(conf, msg): + '''start a compound test''' + def null_check_message_1(self,*k,**kw): + return + def null_check_message_2(self,*k,**kw): + return + + v = getattr(conf.env, 'in_compound', []) + if v != [] and v != 0: + conf.env.in_compound = v + 1 + return + conf.start_msg(msg) + conf.saved_check_message_1 = conf.start_msg + conf.start_msg = null_check_message_1 + conf.saved_check_message_2 = conf.end_msg + conf.end_msg = null_check_message_2 + conf.env.in_compound = 1 + + +@conf +def COMPOUND_END(conf, result): + '''start a compound test''' + conf.env.in_compound -= 1 + if conf.env.in_compound != 0: + return + conf.start_msg = conf.saved_check_message_1 + conf.end_msg = conf.saved_check_message_2 + p = conf.end_msg + if result is True: + p('ok') + elif not result: + p('not found', 'YELLOW') + else: + p(result) + + +@feature('nolink') +def nolink(self): + '''using the nolink type in conf.check() allows us to avoid + the link stage of a test, thus speeding it up for tests + that where linking is not needed''' + pass + + +def CHECK_HEADER(conf, h, add_headers=False, lib=None): + '''check for a header''' + if h in missing_headers and lib is None: + return False + d = h.upper().replace('/', '_') + d = d.replace('.', '_') + d = d.replace('-', '_') + d = 'HAVE_%s' % d + if CONFIG_SET(conf, d): + if add_headers: + if not h in conf.env.hlist: + conf.env.hlist.append(h) + return True + + (ccflags, ldflags, cpppath) = library_flags(conf, lib) + + hdrs = hlist_to_string(conf, headers=h) + if lib is None: + lib = "" + ret = conf.check(fragment='%s\nint main(void) { return 0; }\n' % hdrs, + type='nolink', + execute=0, + cflags=ccflags, + mandatory=False, + includes=cpppath, + uselib=lib.upper(), + msg="Checking for header %s" % h) + if not ret: + missing_headers.add(h) + return False + + conf.DEFINE(d, 1) + if add_headers and not h in conf.env.hlist: + conf.env.hlist.append(h) + return ret + + +@conf +def CHECK_HEADERS(conf, headers, add_headers=False, together=False, lib=None): + '''check for a list of headers + + when together==True, then the headers accumulate within this test. + This is useful for interdependent headers + ''' + ret = True + if not add_headers and together: + saved_hlist = conf.env.hlist[:] + set_add_headers = True + else: + set_add_headers = add_headers + for hdr in TO_LIST(headers): + if not CHECK_HEADER(conf, hdr, set_add_headers, lib=lib): + ret = False + if not add_headers and together: + conf.env.hlist = saved_hlist + return ret + + +def header_list(conf, headers=None, lib=None): + '''form a list of headers which exist, as a string''' + hlist=[] + if headers is not None: + for h in TO_LIST(headers): + if CHECK_HEADER(conf, h, add_headers=False, lib=lib): + hlist.append(h) + return hlist_to_string(conf, headers=hlist) + + +@conf +def CHECK_TYPE(conf, t, alternate=None, headers=None, define=None, lib=None, msg=None): + '''check for a single type''' + if define is None: + define = 'HAVE_' + t.upper().replace(' ', '_') + if msg is None: + msg='Checking for %s' % t + ret = CHECK_CODE(conf, '%s _x' % t, + define, + execute=False, + headers=headers, + local_include=False, + msg=msg, + lib=lib, + link=False) + if not ret and alternate: + conf.DEFINE(t, alternate) + return ret + + +@conf +def CHECK_TYPES(conf, list, headers=None, define=None, alternate=None, lib=None): + '''check for a list of types''' + ret = True + for t in TO_LIST(list): + if not CHECK_TYPE(conf, t, headers=headers, + define=define, alternate=alternate, lib=lib): + ret = False + return ret + + +@conf +def CHECK_TYPE_IN(conf, t, headers=None, alternate=None, define=None): + '''check for a single type with a header''' + return CHECK_TYPE(conf, t, headers=headers, alternate=alternate, define=define) + + +@conf +def CHECK_VARIABLE(conf, v, define=None, always=False, + headers=None, msg=None, lib=None): + '''check for a variable declaration (or define)''' + if define is None: + define = 'HAVE_%s' % v.upper() + + if msg is None: + msg="Checking for variable %s" % v + + return CHECK_CODE(conf, + # we need to make sure the compiler doesn't + # optimize it out... + ''' + #ifndef %s + void *_x; _x=(void *)&%s; return (int)_x; + #endif + return 0 + ''' % (v, v), + execute=False, + link=False, + msg=msg, + local_include=False, + lib=lib, + headers=headers, + define=define, + always=always) + + +@conf +def CHECK_DECLS(conf, vars, reverse=False, headers=None, always=False): + '''check a list of variable declarations, using the HAVE_DECL_xxx form + of define + + When reverse==True then use HAVE_xxx_DECL instead of HAVE_DECL_xxx + ''' + ret = True + for v in TO_LIST(vars): + if not reverse: + define='HAVE_DECL_%s' % v.upper() + else: + define='HAVE_%s_DECL' % v.upper() + if not CHECK_VARIABLE(conf, v, + define=define, + headers=headers, + msg='Checking for declaration of %s' % v, + always=always): + if not CHECK_CODE(conf, + ''' + return (int)%s; + ''' % (v), + execute=False, + link=False, + msg='Checking for declaration of %s (as enum)' % v, + local_include=False, + headers=headers, + define=define, + always=always): + ret = False + return ret + + +def CHECK_FUNC(conf, f, link=True, lib=None, headers=None): + '''check for a function''' + define='HAVE_%s' % f.upper() + + ret = False + + in_lib_str = "" + if lib: + in_lib_str = " in %s" % lib + conf.COMPOUND_START('Checking for %s%s' % (f, in_lib_str)) + + if link is None or link: + ret = CHECK_CODE(conf, + # this is based on the autoconf strategy + ''' + #define %s __fake__%s + #ifdef HAVE_LIMITS_H + # include + #else + # include + #endif + #undef %s + #if defined __stub_%s || defined __stub___%s + #error "bad glibc stub" + #endif + extern char %s(); + int main() { return %s(); } + ''' % (f, f, f, f, f, f, f), + execute=False, + link=True, + addmain=False, + add_headers=False, + define=define, + local_include=False, + lib=lib, + headers=headers, + msg='Checking for %s' % f) + + if not ret: + ret = CHECK_CODE(conf, + # it might be a macro + # we need to make sure the compiler doesn't + # optimize it out... + 'void *__x = (void *)%s; return (int)__x' % f, + execute=False, + link=True, + addmain=True, + add_headers=True, + define=define, + local_include=False, + lib=lib, + headers=headers, + msg='Checking for macro %s' % f) + + if not ret and (link is None or not link): + ret = CHECK_VARIABLE(conf, f, + define=define, + headers=headers, + msg='Checking for declaration of %s' % f) + conf.COMPOUND_END(ret) + return ret + + +@conf +def CHECK_FUNCS(conf, list, link=True, lib=None, headers=None): + '''check for a list of functions''' + ret = True + for f in TO_LIST(list): + if not CHECK_FUNC(conf, f, link=link, lib=lib, headers=headers): + ret = False + return ret + + +@conf +def CHECK_SIZEOF(conf, vars, headers=None, define=None, critical=True): + '''check the size of a type''' + for v in TO_LIST(vars): + v_define = define + ret = False + if v_define is None: + v_define = 'SIZEOF_%s' % v.upper().replace(' ', '_') + for size in list((1, 2, 4, 8, 16, 32, 64)): + if CHECK_CODE(conf, + 'static int test_array[1 - 2 * !(((long int)(sizeof(%s))) <= %d)];' % (v, size), + define=v_define, + quote=False, + headers=headers, + local_include=False, + msg="Checking if size of %s == %d" % (v, size)): + conf.DEFINE(v_define, size) + ret = True + break + if not ret and critical: + Logs.error("Couldn't determine size of '%s'" % v) + sys.exit(1) + return ret + +@conf +def CHECK_VALUEOF(conf, v, headers=None, define=None): + '''check the value of a variable/define''' + ret = True + v_define = define + if v_define is None: + v_define = 'VALUEOF_%s' % v.upper().replace(' ', '_') + if CHECK_CODE(conf, + 'printf("%%u", (unsigned)(%s))' % v, + define=v_define, + execute=True, + define_ret=True, + quote=False, + headers=headers, + local_include=False, + msg="Checking value of %s" % v): + return int(conf.env[v_define]) + + return None + +@conf +def CHECK_CODE(conf, code, define, + always=False, execute=False, addmain=True, + add_headers=True, mandatory=False, + headers=None, msg=None, cflags='', includes='# .', + local_include=True, lib=None, link=True, + define_ret=False, quote=False, + on_target=True, strict=False): + '''check if some code compiles and/or runs''' + + if CONFIG_SET(conf, define): + return True + + if headers is not None: + CHECK_HEADERS(conf, headers=headers, lib=lib) + + if add_headers: + hdrs = header_list(conf, headers=headers, lib=lib) + else: + hdrs = '' + if execute: + execute = 1 + else: + execute = 0 + + if addmain: + fragment='%s\n int main(void) { %s; return 0; }\n' % (hdrs, code) + else: + fragment='%s\n%s\n' % (hdrs, code) + + if msg is None: + msg="Checking for %s" % define + + cflags = TO_LIST(cflags) + + # Be strict when relying on a compiler check + # Some compilers (e.g. xlc) ignore non-supported features as warnings + if strict: + if 'WERROR_CFLAGS' in conf.env: + cflags.extend(conf.env['WERROR_CFLAGS']) + + if local_include: + cflags.append('-I%s' % conf.path.abspath()) + + if not link: + type='nolink' + else: + type='cprogram' + + uselib = TO_LIST(lib) + + (ccflags, ldflags, cpppath) = library_flags(conf, uselib) + + includes = TO_LIST(includes) + includes.extend(cpppath) + + uselib = [l.upper() for l in uselib] + + cflags.extend(ccflags) + + if on_target: + test_args = conf.SAMBA_CROSS_ARGS(msg=msg) + else: + test_args = [] + + conf.COMPOUND_START(msg) + + try: + ret = conf.check(fragment=fragment, + execute=execute, + define_name = define, + cflags=cflags, + ldflags=ldflags, + includes=includes, + uselib=uselib, + type=type, + msg=msg, + quote=quote, + test_args=test_args, + define_ret=define_ret) + except Exception: + if always: + conf.DEFINE(define, 0) + else: + conf.undefine(define) + conf.COMPOUND_END(False) + if mandatory: + raise + return False + else: + # Success is indicated by ret but we should unset + # defines set by WAF's c_config.check() because it + # defines it to int(ret) and we want to undefine it + if not ret: + conf.undefine(define) + conf.COMPOUND_END(False) + return False + if not define_ret: + conf.DEFINE(define, 1) + conf.COMPOUND_END(True) + else: + conf.DEFINE(define, ret, quote=quote) + conf.COMPOUND_END(ret) + return True + + +@conf +def CHECK_STRUCTURE_MEMBER(conf, structname, member, + always=False, define=None, headers=None, + lib=None): + '''check for a structure member''' + if define is None: + define = 'HAVE_%s' % member.upper() + return CHECK_CODE(conf, + '%s s; void *_x; _x=(void *)&s.%s' % (structname, member), + define, + execute=False, + link=False, + lib=lib, + always=always, + headers=headers, + local_include=False, + msg="Checking for member %s in %s" % (member, structname)) + + +@conf +def CHECK_CFLAGS(conf, cflags, fragment='int main(void) { return 0; }\n'): + '''check if the given cflags are accepted by the compiler + ''' + check_cflags = TO_LIST(cflags) + if 'WERROR_CFLAGS' in conf.env: + check_cflags.extend(conf.env['WERROR_CFLAGS']) + return conf.check(fragment=fragment, + execute=0, + mandatory=False, + type='nolink', + cflags=check_cflags, + msg="Checking compiler accepts %s" % cflags) + +@conf +def CHECK_LDFLAGS(conf, ldflags): + '''check if the given ldflags are accepted by the linker + ''' + return conf.check(fragment='int main(void) { return 0; }\n', + execute=0, + ldflags=ldflags, + mandatory=False, + msg="Checking linker accepts %s" % ldflags) + + +@conf +def CONFIG_GET(conf, option): + '''return True if a configuration option was found''' + if (option in conf.env): + return conf.env[option] + else: + return None + +@conf +def CONFIG_SET(conf, option): + '''return True if a configuration option was found''' + if option not in conf.env: + return False + v = conf.env[option] + if v is None: + return False + if v == []: + return False + if v == (): + return False + return True + +@conf +def CONFIG_RESET(conf, option): + if option not in conf.env: + return + del conf.env[option] + +Build.BuildContext.CONFIG_RESET = CONFIG_RESET +Build.BuildContext.CONFIG_SET = CONFIG_SET +Build.BuildContext.CONFIG_GET = CONFIG_GET + + +def library_flags(self, libs): + '''work out flags from pkg_config''' + ccflags = [] + ldflags = [] + cpppath = [] + for lib in TO_LIST(libs): + # note that we do not add the -I and -L in here, as that is added by the waf + # core. Adding it here would just change the order that it is put on the link line + # which can cause system paths to be added before internal libraries + extra_ccflags = TO_LIST(getattr(self.env, 'CFLAGS_%s' % lib.upper(), [])) + extra_ldflags = TO_LIST(getattr(self.env, 'LDFLAGS_%s' % lib.upper(), [])) + extra_cpppath = TO_LIST(getattr(self.env, 'CPPPATH_%s' % lib.upper(), [])) + ccflags.extend(extra_ccflags) + ldflags.extend(extra_ldflags) + cpppath.extend(extra_cpppath) + + extra_cpppath = TO_LIST(getattr(self.env, 'INCLUDES_%s' % lib.upper(), [])) + cpppath.extend(extra_cpppath) + if 'EXTRA_LDFLAGS' in self.env: + ldflags.extend(self.env['EXTRA_LDFLAGS']) + + ccflags = unique_list(ccflags) + ldflags = unique_list(ldflags) + cpppath = unique_list(cpppath) + return (ccflags, ldflags, cpppath) + + +@conf +def CHECK_LIB(conf, libs, mandatory=False, empty_decl=True, set_target=True, shlib=False): + '''check if a set of libraries exist as system libraries + + returns the sublist of libs that do exist as a syslib or [] + ''' + + fragment= ''' +int foo() +{ + int v = 2; + return v*2; +} +''' + ret = [] + liblist = TO_LIST(libs) + for lib in liblist[:]: + if GET_TARGET_TYPE(conf, lib) == 'SYSLIB': + ret.append(lib) + continue + + (ccflags, ldflags, cpppath) = library_flags(conf, lib) + if shlib: + res = conf.check(features='c cshlib', fragment=fragment, lib=lib, uselib_store=lib, cflags=ccflags, ldflags=ldflags, uselib=lib.upper(), mandatory=False) + else: + res = conf.check(lib=lib, uselib_store=lib, cflags=ccflags, ldflags=ldflags, uselib=lib.upper(), mandatory=False) + + if not res: + if mandatory: + Logs.error("Mandatory library '%s' not found for functions '%s'" % (lib, list)) + sys.exit(1) + if empty_decl: + # if it isn't a mandatory library, then remove it from dependency lists + if set_target: + SET_TARGET_TYPE(conf, lib, 'EMPTY') + else: + conf.define('HAVE_LIB%s' % lib.upper().replace('-','_').replace('.','_'), 1) + conf.env['LIB_' + lib.upper()] = lib + if set_target: + conf.SET_TARGET_TYPE(lib, 'SYSLIB') + ret.append(lib) + + return ret + + + +@conf +def CHECK_FUNCS_IN(conf, list, library, mandatory=False, checklibc=False, + headers=None, link=True, empty_decl=True, set_target=True): + """ + check that the functions in 'list' are available in 'library' + if they are, then make that library available as a dependency + + if the library is not available and mandatory==True, then + raise an error. + + If the library is not available and mandatory==False, then + add the library to the list of dependencies to remove from + build rules + + optionally check for the functions first in libc + """ + remaining = TO_LIST(list) + liblist = TO_LIST(library) + + # check if some already found + for f in remaining[:]: + if CONFIG_SET(conf, 'HAVE_%s' % f.upper()): + remaining.remove(f) + + # see if the functions are in libc + if checklibc: + for f in remaining[:]: + if CHECK_FUNC(conf, f, link=True, headers=headers): + remaining.remove(f) + + if remaining == []: + for lib in liblist: + if GET_TARGET_TYPE(conf, lib) != 'SYSLIB' and empty_decl: + SET_TARGET_TYPE(conf, lib, 'EMPTY') + return True + + checklist = conf.CHECK_LIB(liblist, empty_decl=empty_decl, set_target=set_target) + for lib in liblist[:]: + if not lib in checklist and mandatory: + Logs.error("Mandatory library '%s' not found for functions '%s'" % (lib, list)) + sys.exit(1) + + ret = True + for f in remaining: + if not CHECK_FUNC(conf, f, lib=' '.join(checklist), headers=headers, link=link): + ret = False + + return ret + + +@conf +def IN_LAUNCH_DIR(conf): + '''return True if this rule is being run from the launch directory''' + return os.path.realpath(conf.path.abspath()) == os.path.realpath(Context.launch_dir) +Options.OptionsContext.IN_LAUNCH_DIR = IN_LAUNCH_DIR + + +@conf +def SAMBA_CONFIG_H(conf, path=None): + '''write out config.h in the right directory''' + # we don't want to produce a config.h in places like lib/replace + # when we are building projects that depend on lib/replace + if not IN_LAUNCH_DIR(conf): + return + + # we need to build real code that can't be optimized away to test + stack_protect_list = ['-fstack-protector-strong', '-fstack-protector'] + for stack_protect_flag in stack_protect_list: + flag_supported = conf.check(fragment=''' + #include + + int main(void) + { + char t[100000]; + while (fgets(t, sizeof(t), stdin)); + return 0; + } + ''', + execute=0, + cflags=[ '-Werror', '-Wp,-D_FORTIFY_SOURCE=2', stack_protect_flag], + mandatory=False, + msg='Checking if compiler accepts %s' % (stack_protect_flag)) + if flag_supported: + conf.ADD_CFLAGS('%s' % (stack_protect_flag)) + break + + flag_supported = conf.check(fragment=''' + #include + + int main(void) + { + char t[100000]; + while (fgets(t, sizeof(t), stdin)); + return 0; + } + ''', + execute=0, + cflags=[ '-Werror', '-fstack-clash-protection'], + mandatory=False, + msg='Checking if compiler accepts -fstack-clash-protection') + if flag_supported: + conf.ADD_CFLAGS('-fstack-clash-protection') + + if Options.options.debug: + conf.ADD_CFLAGS('-g', testflags=True) + + if Options.options.developer: + conf.env.DEVELOPER_MODE = True + + conf.ADD_CFLAGS('-g', testflags=True) + conf.ADD_CFLAGS('-Wall', testflags=True) + conf.ADD_CFLAGS('-Wshadow', testflags=True) + conf.ADD_CFLAGS('-Wmissing-prototypes', testflags=True) + if CHECK_CODE(conf, + 'struct a { int b; }; struct c { struct a d; } e = { };', + 'CHECK_C99_INIT', + link=False, + cflags='-Wmissing-field-initializers -Werror=missing-field-initializers', + msg="Checking C99 init of nested structs."): + conf.ADD_CFLAGS('-Wmissing-field-initializers', testflags=True) + conf.ADD_CFLAGS('-Wformat-overflow=2', testflags=True) + conf.ADD_CFLAGS('-Wformat-zero-length', testflags=True) + conf.ADD_CFLAGS('-Wcast-align -Wcast-qual', testflags=True) + conf.ADD_CFLAGS('-fno-common', testflags=True) + + conf.ADD_CFLAGS('-Werror=address', testflags=True) + # we add these here to ensure that -Wstrict-prototypes is not set during configure + conf.ADD_CFLAGS('-Werror=strict-prototypes -Wstrict-prototypes', + testflags=True) + conf.ADD_CFLAGS('-Werror=write-strings -Wwrite-strings', + testflags=True) + conf.ADD_CFLAGS('-Werror-implicit-function-declaration', + testflags=True) + conf.ADD_CFLAGS('-Werror=pointer-arith -Wpointer-arith', + testflags=True) + conf.ADD_CFLAGS('-Werror=declaration-after-statement -Wdeclaration-after-statement', + testflags=True) + conf.ADD_CFLAGS('-Werror=return-type -Wreturn-type', + testflags=True) + conf.ADD_CFLAGS('-Werror=uninitialized -Wuninitialized', + testflags=True) + conf.ADD_CFLAGS('-Wimplicit-fallthrough', + testflags=True) + conf.ADD_CFLAGS('-Werror=strict-overflow -Wstrict-overflow=2', + testflags=True) + + conf.ADD_CFLAGS('-Wformat=2 -Wno-format-y2k', testflags=True) + conf.ADD_CFLAGS('-Wno-format-zero-length', testflags=True) + conf.ADD_CFLAGS('-Werror=format-security -Wformat-security', + testflags=True, prereq_flags='-Wformat') + # This check is because for ldb_search(), a NULL format string + # is not an error, but some compilers complain about that. + if CHECK_CFLAGS(conf, ["-Werror=format", "-Wformat=2"], ''' +int testformat(char *format, ...) __attribute__ ((format (__printf__, 1, 2))); + +int main(void) { + testformat(0); + return 0; +} + +'''): + if not 'EXTRA_CFLAGS' in conf.env: + conf.env['EXTRA_CFLAGS'] = [] + conf.env['EXTRA_CFLAGS'].extend(TO_LIST("-Werror=format")) + + if Options.options.picky_developer: + conf.ADD_NAMED_CFLAGS('PICKY_CFLAGS', '-Werror -Wno-error=deprecated-declarations', testflags=True) + conf.ADD_NAMED_CFLAGS('PICKY_CFLAGS', '-Wno-error=tautological-compare', testflags=True) + + if Options.options.fatal_errors: + conf.ADD_CFLAGS('-Wfatal-errors', testflags=True) + + if Options.options.pedantic: + conf.ADD_CFLAGS('-W', testflags=True) + + if (Options.options.address_sanitizer or + Options.options.undefined_sanitizer): + conf.ADD_CFLAGS('-g -O1', testflags=True) + if Options.options.address_sanitizer: + conf.ADD_CFLAGS('-fno-omit-frame-pointer', testflags=True) + conf.ADD_CFLAGS('-fsanitize=address', testflags=True) + conf.ADD_LDFLAGS('-fsanitize=address', testflags=True) + conf.env['ADDRESS_SANITIZER'] = True + if Options.options.undefined_sanitizer: + conf.ADD_CFLAGS('-fsanitize=undefined', testflags=True) + conf.ADD_CFLAGS('-fsanitize=null', testflags=True) + conf.ADD_CFLAGS('-fsanitize=alignment', testflags=True) + conf.ADD_LDFLAGS('-fsanitize=undefined', testflags=True) + conf.env['UNDEFINED_SANITIZER'] = True + + + # Let people pass an additional ADDITIONAL_{CFLAGS,LDFLAGS} + # environment variables which are only used the for final build. + # + # The CFLAGS and LDFLAGS environment variables are also + # used for the configure checks which might impact their results. + conf.add_os_flags('ADDITIONAL_CFLAGS') + if conf.env.ADDITIONAL_CFLAGS and conf.CHECK_CFLAGS(conf.env['ADDITIONAL_CFLAGS']): + conf.env['EXTRA_CFLAGS'].extend(conf.env['ADDITIONAL_CFLAGS']) + conf.add_os_flags('ADDITIONAL_LDFLAGS') + if conf.env.ADDITIONAL_LDFLAGS and conf.CHECK_LDFLAGS(conf.env['ADDITIONAL_LDFLAGS']): + conf.env['EXTRA_LDFLAGS'].extend(conf.env['ADDITIONAL_LDFLAGS']) + + if path is None: + conf.write_config_header('default/config.h', top=True, remove=False) + else: + conf.write_config_header(os.path.join(conf.variant, path), remove=False) + for key in conf.env.define_key: + conf.undefine(key, from_env=False) + conf.env.define_key = [] + conf.SAMBA_CROSS_CHECK_COMPLETE() + + +@conf +def CONFIG_PATH(conf, name, default): + '''setup a configurable path''' + if not name in conf.env: + if default[0] == '/': + conf.env[name] = default + else: + conf.env[name] = conf.env['PREFIX'] + default + +@conf +def ADD_NAMED_CFLAGS(conf, name, flags, testflags=False, prereq_flags=[]): + '''add some CFLAGS to the command line + optionally set testflags to ensure all the flags work + ''' + prereq_flags = TO_LIST(prereq_flags) + if testflags: + ok_flags=[] + for f in flags.split(): + if CHECK_CFLAGS(conf, [f] + prereq_flags): + ok_flags.append(f) + flags = ok_flags + if not name in conf.env: + conf.env[name] = [] + conf.env[name].extend(TO_LIST(flags)) + +@conf +def ADD_CFLAGS(conf, flags, testflags=False, prereq_flags=[]): + '''add some CFLAGS to the command line + optionally set testflags to ensure all the flags work + ''' + ADD_NAMED_CFLAGS(conf, 'EXTRA_CFLAGS', flags, testflags=testflags, + prereq_flags=prereq_flags) + +@conf +def ADD_LDFLAGS(conf, flags, testflags=False): + '''add some LDFLAGS to the command line + optionally set testflags to ensure all the flags work + + this will return the flags that are added, if any + ''' + if testflags: + ok_flags=[] + for f in flags.split(): + if CHECK_LDFLAGS(conf, f): + ok_flags.append(f) + flags = ok_flags + if not 'EXTRA_LDFLAGS' in conf.env: + conf.env['EXTRA_LDFLAGS'] = [] + conf.env['EXTRA_LDFLAGS'].extend(TO_LIST(flags)) + return flags + + +@conf +def ADD_EXTRA_INCLUDES(conf, includes): + '''add some extra include directories to all builds''' + if not 'EXTRA_INCLUDES' in conf.env: + conf.env['EXTRA_INCLUDES'] = [] + conf.env['EXTRA_INCLUDES'].extend(TO_LIST(includes)) + + + +def CURRENT_CFLAGS(bld, target, cflags, allow_warnings=False, hide_symbols=False): + '''work out the current flags. local flags are added first''' + ret = TO_LIST(cflags) + if not 'EXTRA_CFLAGS' in bld.env: + list = [] + else: + list = bld.env['EXTRA_CFLAGS']; + ret.extend(list) + if not allow_warnings and 'PICKY_CFLAGS' in bld.env: + list = bld.env['PICKY_CFLAGS']; + ret.extend(list) + if hide_symbols and bld.env.HAVE_VISIBILITY_ATTR: + ret.append(bld.env.VISIBILITY_CFLAGS) + return ret + + +@conf +def CHECK_CC_ENV(conf): + """trim whitespaces from 'CC'. + The build farm sometimes puts a space at the start""" + if os.environ.get('CC'): + conf.env.CC = TO_LIST(os.environ.get('CC')) + + +@conf +def SETUP_CONFIGURE_CACHE(conf, enable): + '''enable/disable cache of configure results''' + if enable: + # when -C is chosen, we will use a private cache and will + # not look into system includes. This roughtly matches what + # autoconf does with -C + cache_path = os.path.join(conf.bldnode.abspath(), '.confcache') + mkdir_p(cache_path) + Options.cache_global = os.environ['WAFCACHE'] = cache_path + else: + # when -C is not chosen we will not cache configure checks + # We set the recursion limit low to prevent waf from spending + # a lot of time on the signatures of the files. + Options.cache_global = os.environ['WAFCACHE'] = '' + preproc.recursion_limit = 1 + # in either case we don't need to scan system includes + preproc.go_absolute = False + + +@conf +def SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS(conf): + if not sys.platform.startswith("openbsd"): + # we don't want any libraries or modules to rely on runtime + # resolution of symbols + conf.env.undefined_ldflags = conf.ADD_LDFLAGS('-Wl,-no-undefined', testflags=True) + + if (conf.env.undefined_ignore_ldflags == [] and + conf.CHECK_LDFLAGS(['-undefined', 'dynamic_lookup'])): + conf.env.undefined_ignore_ldflags = ['-undefined', 'dynamic_lookup'] diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_autoproto.py b/ldb-2.0.8/buildtools/wafsamba/samba_autoproto.py new file mode 100644 index 0000000..ace434f --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/samba_autoproto.py @@ -0,0 +1,24 @@ +# waf build tool for building automatic prototypes from C source + +import os +from waflib import Build +from samba_utils import SET_TARGET_TYPE, os_path_relpath + +def SAMBA_AUTOPROTO(bld, header, source): + '''rule for samba prototype generation''' + bld.SET_BUILD_GROUP('prototypes') + relpath = os_path_relpath(bld.path.abspath(), bld.srcnode.abspath()) + name = os.path.join(relpath, header) + SET_TARGET_TYPE(bld, name, 'PROTOTYPE') + t = bld( + name = name, + source = source, + target = header, + update_outputs=True, + ext_out='.c', + before ='c', + rule = '${PERL} "${SCRIPT}/mkproto.pl" --srcdir=.. --builddir=. --public=/dev/null --private="${TGT}" ${SRC}' + ) + t.env.SCRIPT = os.path.join(bld.srcnode.abspath(), 'source4/script') +Build.BuildContext.SAMBA_AUTOPROTO = SAMBA_AUTOPROTO + diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_bundled.py b/ldb-2.0.8/buildtools/wafsamba/samba_bundled.py new file mode 100644 index 0000000..60ce7da --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/samba_bundled.py @@ -0,0 +1,274 @@ +# functions to support bundled libraries + +import sys +from waflib import Build, Options, Logs +from waflib.Configure import conf +from wafsamba import samba_utils + +def PRIVATE_NAME(bld, name, private_extension, private_library): + '''possibly rename a library to include a bundled extension''' + + if not private_library: + return name + + # we now use the same private name for libraries as the public name. + # see http://git.samba.org/?p=tridge/junkcode.git;a=tree;f=shlib for a + # demonstration that this is the right thing to do + # also see http://lists.samba.org/archive/samba-technical/2011-January/075816.html + if private_extension: + return name + + extension = bld.env.PRIVATE_EXTENSION + + if extension and name.startswith('%s' % extension): + return name + + if extension and name.endswith('%s' % extension): + return name + + return "%s-%s" % (name, extension) + + +def target_in_list(target, lst, default): + for l in lst: + if target == l: + return True + if '!' + target == l: + return False + if l == 'ALL': + return True + if l == 'NONE': + return False + return default + + +def BUILTIN_LIBRARY(bld, name): + '''return True if a library should be builtin + instead of being built as a shared lib''' + return target_in_list(name, bld.env.BUILTIN_LIBRARIES, False) +Build.BuildContext.BUILTIN_LIBRARY = BUILTIN_LIBRARY + + +def BUILTIN_DEFAULT(opt, builtins): + '''set a comma separated default list of builtin libraries for this package''' + if 'BUILTIN_LIBRARIES_DEFAULT' in Options.options.__dict__: + return + Options.options.__dict__['BUILTIN_LIBRARIES_DEFAULT'] = builtins +Options.OptionsContext.BUILTIN_DEFAULT = BUILTIN_DEFAULT + + +def PRIVATE_EXTENSION_DEFAULT(opt, extension, noextension=''): + '''set a default private library extension''' + if 'PRIVATE_EXTENSION_DEFAULT' in Options.options.__dict__: + return + Options.options.__dict__['PRIVATE_EXTENSION_DEFAULT'] = extension + Options.options.__dict__['PRIVATE_EXTENSION_EXCEPTION'] = noextension +Options.OptionsContext.PRIVATE_EXTENSION_DEFAULT = PRIVATE_EXTENSION_DEFAULT + + +def minimum_library_version(conf, libname, default): + '''allow override of mininum system library version''' + + minlist = Options.options.MINIMUM_LIBRARY_VERSION + if not minlist: + return default + + for m in minlist.split(','): + a = m.split(':') + if len(a) != 2: + Logs.error("Bad syntax for --minimum-library-version of %s" % m) + sys.exit(1) + if a[0] == libname: + return a[1] + return default + + +@conf +def LIB_MAY_BE_BUNDLED(conf, libname): + if libname in conf.env.SYSTEM_LIBS: + return False + if libname in conf.env.BUNDLED_LIBS: + return True + if '!%s' % libname in conf.env.BUNDLED_LIBS: + return False + if 'NONE' in conf.env.BUNDLED_LIBS: + return False + return True + +@conf +def LIB_MUST_BE_BUNDLED(conf, libname): + if libname in conf.env.BUNDLED_LIBS: + return True + if '!%s' % libname in conf.env.BUNDLED_LIBS: + return False + if 'ALL' in conf.env.BUNDLED_LIBS: + return True + return False + +@conf +def LIB_MUST_BE_PRIVATE(conf, libname): + return ('ALL' in conf.env.PRIVATE_LIBS or + libname in conf.env.PRIVATE_LIBS) + +@conf +def CHECK_BUNDLED_SYSTEM_PKG(conf, libname, minversion='0.0.0', + maxversion=None, version_blacklist=[], + onlyif=None, implied_deps=None, pkg=None): + '''check if a library is available as a system library. + + This only tries using pkg-config + ''' + return conf.CHECK_BUNDLED_SYSTEM(libname, + minversion=minversion, + maxversion=maxversion, + version_blacklist=version_blacklist, + onlyif=onlyif, + implied_deps=implied_deps, + pkg=pkg) + +@conf +def CHECK_BUNDLED_SYSTEM(conf, libname, minversion='0.0.0', + maxversion=None, version_blacklist=[], + checkfunctions=None, headers=None, checkcode=None, + onlyif=None, implied_deps=None, + require_headers=True, pkg=None, set_target=True): + '''check if a library is available as a system library. + this first tries via pkg-config, then if that fails + tries by testing for a specified function in the specified lib + ''' + # We always do a logic validation of 'onlyif' first + missing = [] + if onlyif: + for l in samba_utils.TO_LIST(onlyif): + f = 'FOUND_SYSTEMLIB_%s' % l + if not f in conf.env: + Logs.error('ERROR: CHECK_BUNDLED_SYSTEM(%s) - ' % (libname) + + 'missing prerequisite check for ' + + 'system library %s, onlyif=%r' % (l, onlyif)) + sys.exit(1) + if not conf.env[f]: + missing.append(l) + found = 'FOUND_SYSTEMLIB_%s' % libname + if found in conf.env: + return conf.env[found] + if conf.LIB_MUST_BE_BUNDLED(libname): + conf.env[found] = False + return False + + # see if the library should only use a system version if another dependent + # system version is found. That prevents possible use of mixed library + # versions + if missing: + if not conf.LIB_MAY_BE_BUNDLED(libname): + Logs.error('ERROR: Use of system library %s depends on missing system library/libraries %r' % (libname, missing)) + sys.exit(1) + conf.env[found] = False + return False + + def check_functions_headers_code(): + '''helper function for CHECK_BUNDLED_SYSTEM''' + if require_headers and headers and not conf.CHECK_HEADERS(headers, lib=libname): + return False + if checkfunctions is not None: + ok = conf.CHECK_FUNCS_IN(checkfunctions, libname, headers=headers, + empty_decl=False, set_target=False) + if not ok: + return False + if checkcode is not None: + define='CHECK_BUNDLED_SYSTEM_%s' % libname.upper() + ok = conf.CHECK_CODE(checkcode, lib=libname, + headers=headers, local_include=False, + msg=msg, define=define) + conf.CONFIG_RESET(define) + if not ok: + return False + return True + + minversion = minimum_library_version(conf, libname, minversion) + + msg = 'Checking for system %s' % libname + msg_ver = [] + if minversion != '0.0.0': + msg_ver.append('>=%s' % minversion) + if maxversion is not None: + msg_ver.append('<=%s' % maxversion) + for v in version_blacklist: + msg_ver.append('!=%s' % v) + if msg_ver != []: + msg += " (%s)" % (" ".join(msg_ver)) + + uselib_store=libname.upper() + if pkg is None: + pkg = libname + + version_checks = '%s >= %s' % (pkg, minversion) + if maxversion is not None: + version_checks += ' %s <= %s' % (pkg, maxversion) + for v in version_blacklist: + version_checks += ' %s != %s' % (pkg, v) + + # try pkgconfig first + if (conf.CHECK_CFG(package=pkg, + args='"%s" --cflags --libs' % (version_checks), + msg=msg, uselib_store=uselib_store) and + check_functions_headers_code()): + if set_target: + conf.SET_TARGET_TYPE(libname, 'SYSLIB') + conf.env[found] = True + if implied_deps: + conf.SET_SYSLIB_DEPS(libname, implied_deps) + return True + if checkfunctions is not None: + if check_functions_headers_code(): + conf.env[found] = True + if implied_deps: + conf.SET_SYSLIB_DEPS(libname, implied_deps) + if set_target: + conf.SET_TARGET_TYPE(libname, 'SYSLIB') + return True + conf.env[found] = False + if not conf.LIB_MAY_BE_BUNDLED(libname): + Logs.error('ERROR: System library %s of version %s not found, and bundling disabled' % (libname, minversion)) + sys.exit(1) + return False + + +def tuplize_version(version): + return tuple([int(x) for x in version.split(".")]) + +@conf +def CHECK_BUNDLED_SYSTEM_PYTHON(conf, libname, modulename, minversion='0.0.0'): + '''check if a python module is available on the system and + has the specified minimum version. + ''' + if conf.LIB_MUST_BE_BUNDLED(libname): + return False + + # see if the library should only use a system version if another dependent + # system version is found. That prevents possible use of mixed library + # versions + minversion = minimum_library_version(conf, libname, minversion) + + try: + m = __import__(modulename) + except ImportError: + found = False + else: + try: + version = m.__version__ + except AttributeError: + found = False + else: + found = tuplize_version(version) >= tuplize_version(minversion) + if not found and not conf.LIB_MAY_BE_BUNDLED(libname): + Logs.error('ERROR: Python module %s of version %s not found, and bundling disabled' % (libname, minversion)) + sys.exit(1) + return found + + +def NONSHARED_BINARY(bld, name): + '''return True if a binary should be built without non-system shared libs''' + return target_in_list(name, bld.env.NONSHARED_BINARIES, False) +Build.BuildContext.NONSHARED_BINARY = NONSHARED_BINARY + + diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_conftests.py b/ldb-2.0.8/buildtools/wafsamba/samba_conftests.py new file mode 100644 index 0000000..ef632ba --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/samba_conftests.py @@ -0,0 +1,528 @@ +# a set of config tests that use the samba_autoconf functions +# to test for commonly needed configuration options + +import os, shutil, re +from waflib import Build, Configure, Utils, Options, Logs, Errors +from waflib.Configure import conf +from samba_utils import TO_LIST, ADD_LD_LIBRARY_PATH, get_string + + +def add_option(self, *k, **kw): + '''syntax help: provide the "match" attribute to opt.add_option() so that folders can be added to specific config tests''' + Options.OptionsContext.parser = self + match = kw.get('match', []) + if match: + del kw['match'] + opt = self.parser.add_option(*k, **kw) + opt.match = match + return opt +Options.OptionsContext.add_option = add_option + +@conf +def check(self, *k, **kw): + '''Override the waf defaults to inject --with-directory options''' + + if not 'env' in kw: + kw['env'] = self.env.derive() + + # match the configuration test with specific options, for example: + # --with-libiconv -> Options.options.iconv_open -> "Checking for library iconv" + additional_dirs = [] + if 'msg' in kw: + msg = kw['msg'] + for x in Options.OptionsContext.parser.parser.option_list: + if getattr(x, 'match', None) and msg in x.match: + d = getattr(Options.options, x.dest, '') + if d: + additional_dirs.append(d) + + # we add the additional dirs twice: once for the test data, and again if the compilation test suceeds below + def add_options_dir(dirs, env): + for x in dirs: + if not x in env.CPPPATH: + env.CPPPATH = [os.path.join(x, 'include')] + env.CPPPATH + if not x in env.LIBPATH: + env.LIBPATH = [os.path.join(x, 'lib')] + env.LIBPATH + + add_options_dir(additional_dirs, kw['env']) + + self.validate_c(kw) + self.start_msg(kw['msg']) + ret = None + try: + ret = self.run_c_code(*k, **kw) + except Configure.ConfigurationError as e: + self.end_msg(kw['errmsg'], 'YELLOW') + if 'mandatory' in kw and kw['mandatory']: + if Logs.verbose > 1: + raise + else: + self.fatal('the configuration failed (see %r)' % self.log.name) + else: + kw['success'] = ret + self.end_msg(self.ret_msg(kw['okmsg'], kw)) + + # success! keep the CPPPATH/LIBPATH + add_options_dir(additional_dirs, self.env) + + self.post_check(*k, **kw) + if not kw.get('execute', False): + return ret == 0 + return ret + + +@conf +def CHECK_ICONV(conf, define='HAVE_NATIVE_ICONV'): + '''check if the iconv library is installed + optionally pass a define''' + if conf.CHECK_FUNCS_IN('iconv_open', 'iconv', checklibc=True, headers='iconv.h'): + conf.DEFINE(define, 1) + return True + return False + + +@conf +def CHECK_LARGEFILE(conf, define='HAVE_LARGEFILE'): + '''see what we need for largefile support''' + getconf_cflags = conf.CHECK_COMMAND(['getconf', 'LFS_CFLAGS']); + if getconf_cflags is not False: + if (conf.CHECK_CODE('if (sizeof(off_t) < 8) return 1', + define='WORKING_GETCONF_LFS_CFLAGS', + execute=True, + cflags=getconf_cflags, + msg='Checking getconf large file support flags work')): + conf.ADD_CFLAGS(getconf_cflags) + getconf_cflags_list=TO_LIST(getconf_cflags) + for flag in getconf_cflags_list: + if flag[:2] == "-D": + flag_split = flag[2:].split('=') + if len(flag_split) == 1: + conf.DEFINE(flag_split[0], '1') + else: + conf.DEFINE(flag_split[0], flag_split[1]) + + if conf.CHECK_CODE('if (sizeof(off_t) < 8) return 1', + define, + execute=True, + msg='Checking for large file support without additional flags'): + return True + + if conf.CHECK_CODE('if (sizeof(off_t) < 8) return 1', + define, + execute=True, + cflags='-D_FILE_OFFSET_BITS=64', + msg='Checking for -D_FILE_OFFSET_BITS=64'): + conf.DEFINE('_FILE_OFFSET_BITS', 64) + return True + + if conf.CHECK_CODE('if (sizeof(off_t) < 8) return 1', + define, + execute=True, + cflags='-D_LARGE_FILES', + msg='Checking for -D_LARGE_FILES'): + conf.DEFINE('_LARGE_FILES', 1) + return True + return False + + +@conf +def CHECK_C_PROTOTYPE(conf, function, prototype, define, headers=None, msg=None): + '''verify that a C prototype matches the one on the current system''' + if not conf.CHECK_DECLS(function, headers=headers): + return False + if not msg: + msg = 'Checking C prototype for %s' % function + return conf.CHECK_CODE('%s; void *_x = (void *)%s' % (prototype, function), + define=define, + local_include=False, + headers=headers, + link=False, + execute=False, + msg=msg) + + +@conf +def CHECK_CHARSET_EXISTS(conf, charset, outcharset='UCS-2LE', headers=None, define=None): + '''check that a named charset is able to be used with iconv_open() for conversion + to a target charset + ''' + msg = 'Checking if can we convert from %s to %s' % (charset, outcharset) + if define is None: + define = 'HAVE_CHARSET_%s' % charset.upper().replace('-','_') + return conf.CHECK_CODE(''' + iconv_t cd = iconv_open("%s", "%s"); + if (cd == 0 || cd == (iconv_t)-1) return -1; + ''' % (charset, outcharset), + define=define, + execute=True, + msg=msg, + lib='iconv', + headers=headers) + +def find_config_dir(conf): + '''find a directory to run tests in''' + k = 0 + while k < 10000: + dir = os.path.join(conf.bldnode.abspath(), '.conf_check_%d' % k) + try: + shutil.rmtree(dir) + except OSError: + pass + try: + os.stat(dir) + except: + break + k += 1 + + try: + os.makedirs(dir) + except: + conf.fatal('cannot create a configuration test folder %r' % dir) + + try: + os.stat(dir) + except: + conf.fatal('cannot use the configuration test folder %r' % dir) + return dir + +@conf +def CHECK_SHLIB_INTRASINC_NAME_FLAGS(conf, msg): + ''' + check if the waf default flags for setting the name of lib + are ok + ''' + + snip = ''' +int foo(int v) { + return v * 2; +} +''' + return conf.check(features='c cshlib',vnum="1",fragment=snip,msg=msg, mandatory=False) + +@conf +def CHECK_NEED_LC(conf, msg): + '''check if we need -lc''' + + dir = find_config_dir(conf) + + env = conf.env + + bdir = os.path.join(dir, 'testbuild2') + if not os.path.exists(bdir): + os.makedirs(bdir) + + + subdir = os.path.join(dir, "liblctest") + + os.makedirs(subdir) + + Utils.writef(os.path.join(subdir, 'liblc1.c'), '#include \nint lib_func(void) { FILE *f = fopen("foo", "r");}\n') + + bld = Build.BuildContext() + bld.log = conf.log + bld.all_envs.update(conf.all_envs) + bld.all_envs['default'] = env + bld.lst_variants = bld.all_envs.keys() + bld.load_dirs(dir, bdir) + + bld.rescan(bld.srcnode) + + bld(features='c cshlib', + source='liblctest/liblc1.c', + ldflags=conf.env['EXTRA_LDFLAGS'], + target='liblc', + name='liblc') + + try: + bld.compile() + conf.check_message(msg, '', True) + return True + except: + conf.check_message(msg, '', False) + return False + + +@conf +def CHECK_SHLIB_W_PYTHON(conf, msg): + '''check if we need -undefined dynamic_lookup''' + + dir = find_config_dir(conf) + snip = ''' +#include +#include +#define environ (*_NSGetEnviron()) + +static PyObject *ldb_module = NULL; +int foo(int v) { + extern char **environ; + environ[0] = 1; + ldb_module = PyImport_ImportModule("ldb"); + return v * 2; +} +''' + return conf.check(features='c cshlib',uselib='PYEMBED',fragment=snip,msg=msg, mandatory=False) + +# this one is quite complex, and should probably be broken up +# into several parts. I'd quite like to create a set of CHECK_COMPOUND() +# functions that make writing complex compound tests like this much easier +@conf +def CHECK_LIBRARY_SUPPORT(conf, rpath=False, version_script=False, msg=None): + '''see if the platform supports building libraries''' + + if msg is None: + if rpath: + msg = "rpath library support" + else: + msg = "building library support" + + dir = find_config_dir(conf) + + bdir = os.path.join(dir, 'testbuild') + if not os.path.exists(bdir): + os.makedirs(bdir) + + env = conf.env + + subdir = os.path.join(dir, "libdir") + + os.makedirs(subdir) + + Utils.writef(os.path.join(subdir, 'lib1.c'), 'int lib_func(void) { return 42; }\n') + Utils.writef(os.path.join(dir, 'main.c'), + 'int lib_func(void);\n' + 'int main(void) {return !(lib_func() == 42);}\n') + + bld = Build.BuildContext() + bld.log = conf.log + bld.all_envs.update(conf.all_envs) + bld.all_envs['default'] = env + bld.lst_variants = bld.all_envs.keys() + bld.load_dirs(dir, bdir) + + bld.rescan(bld.srcnode) + + ldflags = [] + if version_script: + ldflags.append("-Wl,--version-script=%s/vscript" % bld.path.abspath()) + Utils.writef(os.path.join(dir,'vscript'), 'TEST_1.0A2 { global: *; };\n') + + bld(features='c cshlib', + source='libdir/lib1.c', + target='libdir/lib1', + ldflags=ldflags, + name='lib1') + + o = bld(features='c cprogram', + source='main.c', + target='prog1', + uselib_local='lib1') + + if rpath: + o.rpath=os.path.join(bdir, 'default/libdir') + + # compile the program + try: + bld.compile() + except: + conf.check_message(msg, '', False) + return False + + # path for execution + lastprog = o.link_task.outputs[0].abspath(env) + + if not rpath: + if 'LD_LIBRARY_PATH' in os.environ: + old_ld_library_path = os.environ['LD_LIBRARY_PATH'] + else: + old_ld_library_path = None + ADD_LD_LIBRARY_PATH(os.path.join(bdir, 'default/libdir')) + + # we need to run the program, try to get its result + args = conf.SAMBA_CROSS_ARGS(msg=msg) + proc = Utils.subprocess.Popen([lastprog] + args, + stdout=Utils.subprocess.PIPE, stderr=Utils.subprocess.PIPE) + (out, err) = proc.communicate() + w = conf.log.write + w(str(out)) + w('\n') + w(str(err)) + w('\nreturncode %r\n' % proc.returncode) + ret = (proc.returncode == 0) + + if not rpath: + os.environ['LD_LIBRARY_PATH'] = old_ld_library_path or '' + + conf.check_message(msg, '', ret) + return ret + + + +@conf +def CHECK_PERL_MANPAGE(conf, msg=None, section=None): + '''work out what extension perl uses for manpages''' + + if msg is None: + if section: + msg = "perl man%s extension" % section + else: + msg = "perl manpage generation" + + conf.start_msg(msg) + + dir = find_config_dir(conf) + + bdir = os.path.join(dir, 'testbuild') + if not os.path.exists(bdir): + os.makedirs(bdir) + + Utils.writef(os.path.join(bdir, 'Makefile.PL'), """ +use ExtUtils::MakeMaker; +WriteMakefile( + 'NAME' => 'WafTest', + 'EXE_FILES' => [ 'WafTest' ] +); +""") + back = os.path.abspath('.') + os.chdir(bdir) + proc = Utils.subprocess.Popen(['perl', 'Makefile.PL'], + stdout=Utils.subprocess.PIPE, + stderr=Utils.subprocess.PIPE) + (out, err) = proc.communicate() + os.chdir(back) + + ret = (proc.returncode == 0) + if not ret: + conf.end_msg('not found', color='YELLOW') + return + + if section: + man = Utils.readf(os.path.join(bdir,'Makefile')) + m = re.search('MAN%sEXT\s+=\s+(\w+)' % section, man) + if not m: + conf.end_msg('not found', color='YELLOW') + return + ext = m.group(1) + conf.end_msg(ext) + return ext + + conf.end_msg('ok') + return True + + +@conf +def CHECK_COMMAND(conf, cmd, msg=None, define=None, on_target=True, boolean=False): + '''run a command and return result''' + if msg is None: + msg = 'Checking %s' % ' '.join(cmd) + conf.COMPOUND_START(msg) + cmd = cmd[:] + if on_target: + cmd.extend(conf.SAMBA_CROSS_ARGS(msg=msg)) + try: + ret = get_string(Utils.cmd_output(cmd)) + except: + conf.COMPOUND_END(False) + return False + if boolean: + conf.COMPOUND_END('ok') + if define: + conf.DEFINE(define, '1') + else: + ret = ret.strip() + conf.COMPOUND_END(ret) + if define: + conf.DEFINE(define, ret, quote=True) + return ret + + +@conf +def CHECK_UNAME(conf): + '''setup SYSTEM_UNAME_* defines''' + ret = True + for v in "sysname machine release version".split(): + if not conf.CHECK_CODE(''' + int printf(const char *format, ...); + struct utsname n; + if (uname(&n) == -1) return -1; + printf("%%s", n.%s); + ''' % v, + define='SYSTEM_UNAME_%s' % v.upper(), + execute=True, + define_ret=True, + quote=True, + headers='sys/utsname.h', + local_include=False, + msg="Checking uname %s type" % v): + ret = False + return ret + +@conf +def CHECK_INLINE(conf): + '''check for the right value for inline''' + conf.COMPOUND_START('Checking for inline') + for i in ['inline', '__inline__', '__inline']: + ret = conf.CHECK_CODE(''' + typedef int foo_t; + static %s foo_t static_foo () {return 0; } + %s foo_t foo () {return 0; }\n''' % (i, i), + define='INLINE_MACRO', + addmain=False, + link=False) + if ret: + if i != 'inline': + conf.DEFINE('inline', i, quote=False) + break + if not ret: + conf.COMPOUND_END(ret) + else: + conf.COMPOUND_END(i) + return ret + +@conf +def CHECK_XSLTPROC_MANPAGES(conf): + '''check if xsltproc can run with the given stylesheets''' + + + if not conf.CONFIG_SET('XSLTPROC'): + conf.find_program('xsltproc', var='XSLTPROC') + if not conf.CONFIG_SET('XSLTPROC'): + return False + + s='http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl' + conf.CHECK_COMMAND('%s --nonet %s 2> /dev/null' % (conf.env.get_flat('XSLTPROC'), s), + msg='Checking for stylesheet %s' % s, + define='XSLTPROC_MANPAGES', on_target=False, + boolean=True) + if not conf.CONFIG_SET('XSLTPROC_MANPAGES'): + print("A local copy of the docbook.xsl wasn't found on your system" \ + " consider installing package like docbook-xsl") + +# +# Determine the standard libpath for the used compiler, +# so we can later use that to filter out these standard +# library paths when some tools like cups-config or +# python-config report standard lib paths with their +# ldflags (-L...) +# +@conf +def CHECK_STANDARD_LIBPATH(conf): + # at least gcc and clang support this: + try: + cmd = conf.env.CC + ['-print-search-dirs'] + out = get_string(Utils.cmd_output(cmd)).split('\n') + except ValueError: + # option not supported by compiler - use a standard list of directories + dirlist = [ '/usr/lib', '/usr/lib64' ] + except: + raise Errors.WafError('Unexpected error running "%s"' % (cmd)) + else: + dirlist = [] + for line in out: + line = line.strip() + if line.startswith("libraries: ="): + dirliststr = line[len("libraries: ="):] + dirlist = [ os.path.normpath(x) for x in dirliststr.split(':') ] + break + + conf.env.STANDARD_LIBPATH = dirlist + diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_cross.py b/ldb-2.0.8/buildtools/wafsamba/samba_cross.py new file mode 100644 index 0000000..0868a85 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/samba_cross.py @@ -0,0 +1,175 @@ +# functions for handling cross-compilation + +import os, sys, re, shlex +from waflib import Utils, Logs, Options, Errors, Context +from waflib.Configure import conf +from wafsamba import samba_utils + +real_Popen = None + +ANSWER_UNKNOWN = (254, "") +ANSWER_NO = (1, "") +ANSWER_OK = (0, "") + +cross_answers_incomplete = False + + +def add_answer(ca_file, msg, answer): + '''add an answer to a set of cross answers''' + try: + f = open(ca_file, 'a') + except: + Logs.error("Unable to open cross-answers file %s" % ca_file) + sys.exit(1) + (retcode, retstring) = answer + # if retstring is more than one line then we probably + # don't care about its actual content (the tests should + # yield one-line output in order to comply with the cross-answer + # format) + retstring = retstring.strip() + if len(retstring.split('\n')) > 1: + retstring = '' + answer = (retcode, retstring) + + if answer == ANSWER_OK: + f.write('%s: OK\n' % msg) + elif answer == ANSWER_UNKNOWN: + f.write('%s: UNKNOWN\n' % msg) + elif answer == ANSWER_NO: + f.write('%s: NO\n' % msg) + else: + if retcode == 0: + f.write('%s: "%s"\n' % (msg, retstring)) + else: + f.write('%s: (%d, "%s")\n' % (msg, retcode, retstring)) + f.close() + + +def cross_answer(ca_file, msg): + '''return a (retcode,retstring) tuple from a answers file''' + try: + f = open(ca_file, 'r') + except: + return ANSWER_UNKNOWN + for line in f: + line = line.strip() + if line == '' or line[0] == '#': + continue + if line.find(':') != -1: + a = line.split(':', 1) + thismsg = a[0].strip() + if thismsg != msg: + continue + ans = a[1].strip() + if ans == "OK" or ans == "YES": + f.close() + return ANSWER_OK + elif ans == "UNKNOWN": + f.close() + return ANSWER_UNKNOWN + elif ans == "FAIL" or ans == "NO": + f.close() + return ANSWER_NO + elif ans[0] == '"': + f.close() + return (0, ans.strip('"')) + elif ans[0] == "'": + f.close() + return (0, ans.strip("'")) + else: + m = re.match('\(\s*(-?\d+)\s*,\s*\"(.*)\"\s*\)', ans) + if m: + f.close() + return (int(m.group(1)), m.group(2)) + else: + raise Errors.WafError("Bad answer format '%s' in %s" % (line, ca_file)) + f.close() + return ANSWER_UNKNOWN + + +class cross_Popen(Utils.subprocess.Popen): + '''cross-compilation wrapper for Popen''' + def __init__(*k, **kw): + (obj, args) = k + use_answers = False + ans = ANSWER_UNKNOWN + + # Three possibilities: + # 1. Only cross-answers - try the cross-answers file, and if + # there's no corresponding answer, add to the file and mark + # the configure process as unfinished. + # 2. Only cross-execute - get the answer from cross-execute + # 3. Both - try the cross-answers file, and if there is no + # corresponding answer - use cross-execute to get an answer, + # and add that answer to the file. + if '--cross-answers' in args: + # when --cross-answers is set, then change the arguments + # to use the cross answers if available + use_answers = True + i = args.index('--cross-answers') + ca_file = args[i+1] + msg = args[i+2] + ans = cross_answer(ca_file, msg) + + if '--cross-execute' in args and ans == ANSWER_UNKNOWN: + # when --cross-execute is set, then change the arguments + # to use the cross emulator + i = args.index('--cross-execute') + newargs = shlex.split(args[i+1]) + newargs.extend(args[0:i]) + if use_answers: + p = real_Popen(newargs, + stdout=Utils.subprocess.PIPE, + stderr=Utils.subprocess.PIPE, + env=kw.get('env', {})) + ce_out, ce_err = p.communicate() + ans = (p.returncode, samba_utils.get_string(ce_out)) + add_answer(ca_file, msg, ans) + else: + args = newargs + + if use_answers: + if ans == ANSWER_UNKNOWN: + global cross_answers_incomplete + cross_answers_incomplete = True + add_answer(ca_file, msg, ans) + (retcode, retstring) = ans + args = ['/bin/sh', '-c', "echo -n '%s'; exit %d" % (retstring, retcode)] + real_Popen.__init__(*(obj, args), **kw) + + +@conf +def SAMBA_CROSS_ARGS(conf, msg=None): + '''get test_args to pass when running cross compiled binaries''' + if not conf.env.CROSS_COMPILE: + return [] + + global real_Popen + if real_Popen is None: + real_Popen = Utils.subprocess.Popen + Utils.subprocess.Popen = cross_Popen + Utils.run_process = Utils.run_regular_process + Utils.get_process = Utils.alloc_process_pool = Utils.nada + + ret = [] + + if conf.env.CROSS_EXECUTE: + ret.extend(['--cross-execute', conf.env.CROSS_EXECUTE]) + + if conf.env.CROSS_ANSWERS: + if msg is None: + raise Errors.WafError("Cannot have NULL msg in cross-answers") + ret.extend(['--cross-answers', os.path.join(Context.launch_dir, conf.env.CROSS_ANSWERS), msg]) + + if ret == []: + raise Errors.WafError("Cannot cross-compile without either --cross-execute or --cross-answers") + + return ret + +@conf +def SAMBA_CROSS_CHECK_COMPLETE(conf): + '''check if we have some unanswered questions''' + global cross_answers_incomplete + if conf.env.CROSS_COMPILE and cross_answers_incomplete: + raise Errors.WafError("Cross answers file %s is incomplete" % conf.env.CROSS_ANSWERS) + return True diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_deps.py b/ldb-2.0.8/buildtools/wafsamba/samba_deps.py new file mode 100644 index 0000000..03c3707 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/samba_deps.py @@ -0,0 +1,1181 @@ +# Samba automatic dependency handling and project rules + +import os, sys, re + +from waflib import Build, Options, Logs, Utils, Errors +from waflib.Logs import debug +from waflib.Configure import conf +from waflib import ConfigSet + +from samba_bundled import BUILTIN_LIBRARY +from samba_utils import LOCAL_CACHE, TO_LIST, get_tgt_list, unique_list, os_path_relpath +from samba_autoconf import library_flags + +@conf +def ADD_GLOBAL_DEPENDENCY(ctx, dep): + '''add a dependency for all binaries and libraries''' + if not 'GLOBAL_DEPENDENCIES' in ctx.env: + ctx.env.GLOBAL_DEPENDENCIES = [] + ctx.env.GLOBAL_DEPENDENCIES.append(dep) + + +@conf +def BREAK_CIRCULAR_LIBRARY_DEPENDENCIES(ctx): + '''indicate that circular dependencies between libraries should be broken.''' + ctx.env.ALLOW_CIRCULAR_LIB_DEPENDENCIES = True + + +@conf +def SET_SYSLIB_DEPS(conf, target, deps): + '''setup some implied dependencies for a SYSLIB''' + cache = LOCAL_CACHE(conf, 'SYSLIB_DEPS') + cache[target] = deps + + +def expand_subsystem_deps(bld): + '''expand the reverse dependencies resulting from subsystem + attributes of modules. This is walking over the complete list + of declared subsystems, and expands the samba_deps_extended list for any + module<->subsystem dependencies''' + + subsystem_list = LOCAL_CACHE(bld, 'INIT_FUNCTIONS') + targets = LOCAL_CACHE(bld, 'TARGET_TYPE') + + for subsystem_name in subsystem_list: + bld.ASSERT(subsystem_name in targets, "Subsystem target %s not declared" % subsystem_name) + type = targets[subsystem_name] + if type == 'DISABLED' or type == 'EMPTY': + continue + + # for example, + # subsystem_name = dcerpc_server (a subsystem) + # subsystem = dcerpc_server (a subsystem object) + # module_name = rpc_epmapper (a module within the dcerpc_server subsystem) + # module = rpc_epmapper (a module object within the dcerpc_server subsystem) + + subsystem = bld.get_tgen_by_name(subsystem_name) + bld.ASSERT(subsystem is not None, "Unable to find subsystem %s" % subsystem_name) + for d in subsystem_list[subsystem_name]: + module_name = d['TARGET'] + module_type = targets[module_name] + if module_type in ['DISABLED', 'EMPTY']: + continue + bld.ASSERT(subsystem is not None, + "Subsystem target %s for %s (%s) not found" % (subsystem_name, module_name, module_type)) + if module_type in ['SUBSYSTEM']: + # if a module is a plain object type (not a library) then the + # subsystem it is part of needs to have it as a dependency, so targets + # that depend on this subsystem get the modules of that subsystem + subsystem.samba_deps_extended.append(module_name) + subsystem.samba_deps_extended = unique_list(subsystem.samba_deps_extended) + + + +def build_dependencies(self): + '''This builds the dependency list for a target. It runs after all the targets are declared + + The reason this is not just done in the SAMBA_*() rules is that we have no way of knowing + the full dependency list for a target until we have all of the targets declared. + ''' + + if self.samba_type in ['LIBRARY', 'BINARY', 'PYTHON']: + self.uselib = list(self.final_syslibs) + self.uselib_local = list(self.final_libs) + self.add_objects = list(self.final_objects) + + # extra link flags from pkg_config + libs = self.final_syslibs.copy() + + (cflags, ldflags, cpppath) = library_flags(self, list(libs)) + new_ldflags = getattr(self, 'samba_ldflags', [])[:] + new_ldflags.extend(ldflags) + self.ldflags = new_ldflags + + if getattr(self, 'allow_undefined_symbols', False) and self.env.undefined_ldflags: + for f in self.env.undefined_ldflags: + self.ldflags.remove(f) + + if getattr(self, 'allow_undefined_symbols', False) and self.env.undefined_ignore_ldflags: + for f in self.env.undefined_ignore_ldflags: + self.ldflags.append(f) + + debug('deps: computed dependencies for target %s: uselib=%s uselib_local=%s add_objects=%s', + self.sname, self.uselib, self.uselib_local, self.add_objects) + + if self.samba_type in ['SUBSYSTEM']: + # this is needed for the cflags of libs that come from pkg_config + self.uselib = list(self.final_syslibs) + self.uselib.extend(list(self.direct_syslibs)) + for lib in self.final_libs: + t = self.bld.get_tgen_by_name(lib) + self.uselib.extend(list(t.final_syslibs)) + self.uselib = unique_list(self.uselib) + + if getattr(self, 'uselib', None): + up_list = [] + for l in self.uselib: + up_list.append(l.upper()) + self.uselib = up_list + + +def build_includes(self): + '''This builds the right set of includes for a target. + + One tricky part of this is that the includes= attribute for a + target needs to use paths which are relative to that targets + declaration directory (which we can get at via t.path). + + The way this works is the includes list gets added as + samba_includes in the main build task declaration. Then this + function runs after all of the tasks are declared, and it + processes the samba_includes attribute to produce a includes= + attribute + ''' + + if getattr(self, 'samba_includes', None) is None: + return + + bld = self.bld + + inc_deps = includes_objects(bld, self, set(), {}) + + includes = [] + + # maybe add local includes + if getattr(self, 'local_include', True) and getattr(self, 'local_include_first', True): + includes.append('.') + + includes.extend(self.samba_includes_extended) + + if 'EXTRA_INCLUDES' in bld.env and getattr(self, 'global_include', True): + includes.extend(bld.env['EXTRA_INCLUDES']) + + includes.append('#') + + inc_set = set() + inc_abs = [] + + for d in inc_deps: + t = bld.get_tgen_by_name(d) + bld.ASSERT(t is not None, "Unable to find dependency %s for %s" % (d, self.sname)) + inclist = getattr(t, 'samba_includes_extended', [])[:] + if getattr(t, 'local_include', True): + inclist.append('.') + if inclist == []: + continue + tpath = t.samba_abspath + for inc in inclist: + npath = tpath + '/' + inc + if not npath in inc_set: + inc_abs.append(npath) + inc_set.add(npath) + + mypath = self.path.abspath(bld.env) + for inc in inc_abs: + relpath = os_path_relpath(inc, mypath) + includes.append(relpath) + + if getattr(self, 'local_include', True) and not getattr(self, 'local_include_first', True): + includes.append('.') + + # now transform the includes list to be relative to the top directory + # which is represented by '#' in waf. This allows waf to cache the + # includes lists more efficiently + includes_top = [] + for i in includes: + if i[0] == '#': + # some are already top based + includes_top.append(i) + continue + absinc = os.path.join(self.path.abspath(), i) + relinc = os_path_relpath(absinc, self.bld.srcnode.abspath()) + includes_top.append('#' + relinc) + + self.includes = unique_list(includes_top) + debug('deps: includes for target %s: includes=%s', + self.sname, self.includes) + + +def add_init_functions(self): + '''This builds the right set of init functions''' + + bld = self.bld + + subsystems = LOCAL_CACHE(bld, 'INIT_FUNCTIONS') + + # cope with the separated object lists from BINARY and LIBRARY targets + sname = self.sname + if sname.endswith('.objlist'): + sname = sname[0:-8] + + modules = [] + if sname in subsystems: + modules.append(sname) + + m = getattr(self, 'samba_modules', None) + if m is not None: + modules.extend(TO_LIST(m)) + + m = getattr(self, 'samba_subsystem', None) + if m is not None: + modules.append(m) + + if 'pyembed' in self.features: + return + + sentinel = getattr(self, 'init_function_sentinel', 'NULL') + + targets = LOCAL_CACHE(bld, 'TARGET_TYPE') + cflags = getattr(self, 'samba_cflags', [])[:] + + if modules == []: + sname = sname.replace('-','_') + sname = sname.replace('.','_') + sname = sname.replace('/','_') + cflags.append('-DSTATIC_%s_MODULES=%s' % (sname, sentinel)) + if sentinel == 'NULL': + proto = "extern void __%s_dummy_module_proto(void)" % (sname) + cflags.append('-DSTATIC_%s_MODULES_PROTO=%s' % (sname, proto)) + self.cflags = cflags + return + + for m in modules: + bld.ASSERT(m in subsystems, + "No init_function defined for module '%s' in target '%s'" % (m, self.sname)) + init_fn_list = [] + for d in subsystems[m]: + if targets[d['TARGET']] != 'DISABLED': + init_fn_list.append(d['INIT_FUNCTION']) + if init_fn_list == []: + cflags.append('-DSTATIC_%s_MODULES=%s' % (m, sentinel)) + if sentinel == 'NULL': + proto = "extern void __%s_dummy_module_proto(void)" % (m) + cflags.append('-DSTATIC_%s_MODULES_PROTO=%s' % (m, proto)) + else: + cflags.append('-DSTATIC_%s_MODULES=%s' % (m, ','.join(init_fn_list) + ',' + sentinel)) + proto='' + for f in init_fn_list: + proto += '_MODULE_PROTO(%s)' % f + proto += "extern void __%s_dummy_module_proto(void)" % (m) + cflags.append('-DSTATIC_%s_MODULES_PROTO=%s' % (m, proto)) + self.cflags = cflags + + +def check_duplicate_sources(bld, tgt_list): + '''see if we are compiling the same source file more than once''' + + debug('deps: checking for duplicate sources') + targets = LOCAL_CACHE(bld, 'TARGET_TYPE') + + for t in tgt_list: + source_list = TO_LIST(getattr(t, 'source', '')) + tpath = os.path.normpath(os_path_relpath(t.path.abspath(bld.env), t.env.BUILD_DIRECTORY + '/default')) + obj_sources = set() + for s in source_list: + if not isinstance(s, str): + print('strange path in check_duplicate_sources %r' % s) + s = s.abspath() + p = os.path.normpath(os.path.join(tpath, s)) + if p in obj_sources: + Logs.error("ERROR: source %s appears twice in target '%s'" % (p, t.sname)) + sys.exit(1) + obj_sources.add(p) + t.samba_source_set = obj_sources + + subsystems = {} + + # build a list of targets that each source file is part of + for t in tgt_list: + if not targets[t.sname] in [ 'LIBRARY', 'BINARY', 'PYTHON' ]: + continue + for obj in t.add_objects: + t2 = t.bld.get_tgen_by_name(obj) + source_set = getattr(t2, 'samba_source_set', set()) + for s in source_set: + if not s in subsystems: + subsystems[s] = {} + if not t.sname in subsystems[s]: + subsystems[s][t.sname] = [] + subsystems[s][t.sname].append(t2.sname) + + for s in subsystems: + if len(subsystems[s]) > 1 and Options.options.SHOW_DUPLICATES: + Logs.warn("WARNING: source %s is in more than one target: %s" % (s, subsystems[s].keys())) + for tname in subsystems[s]: + if len(subsystems[s][tname]) > 1: + raise Errors.WafError("ERROR: source %s is in more than one subsystem of target '%s': %s" % (s, tname, subsystems[s][tname])) + + return True + +def check_group_ordering(bld, tgt_list): + '''see if we have any dependencies that violate the group ordering + + It is an error for a target to depend on a target from a later + build group + ''' + + def group_name(g): + tm = bld.task_manager + return [x for x in tm.groups_names if id(tm.groups_names[x]) == id(g)][0] + + for g in bld.task_manager.groups: + gname = group_name(g) + for t in g.tasks_gen: + t.samba_group = gname + + grp_map = {} + idx = 0 + for g in bld.task_manager.groups: + name = group_name(g) + grp_map[name] = idx + idx += 1 + + targets = LOCAL_CACHE(bld, 'TARGET_TYPE') + + ret = True + for t in tgt_list: + tdeps = getattr(t, 'add_objects', []) + getattr(t, 'uselib_local', []) + for d in tdeps: + t2 = bld.get_tgen_by_name(d) + if t2 is None: + continue + map1 = grp_map[t.samba_group] + map2 = grp_map[t2.samba_group] + + if map2 > map1: + Logs.error("Target %r in build group %r depends on target %r from later build group %r" % ( + t.sname, t.samba_group, t2.sname, t2.samba_group)) + ret = False + + return ret +Build.BuildContext.check_group_ordering = check_group_ordering + +def show_final_deps(bld, tgt_list): + '''show the final dependencies for all targets''' + + targets = LOCAL_CACHE(bld, 'TARGET_TYPE') + + for t in tgt_list: + if not targets[t.sname] in ['LIBRARY', 'BINARY', 'PYTHON', 'SUBSYSTEM']: + continue + debug('deps: final dependencies for target %s: uselib=%s uselib_local=%s add_objects=%s', + t.sname, t.uselib, getattr(t, 'uselib_local', []), getattr(t, 'add_objects', [])) + + +def add_samba_attributes(bld, tgt_list): + '''ensure a target has a the required samba attributes''' + + targets = LOCAL_CACHE(bld, 'TARGET_TYPE') + + for t in tgt_list: + if t.name != '': + t.sname = t.name + else: + t.sname = t.target + t.samba_type = targets[t.sname] + t.samba_abspath = t.path.abspath(bld.env) + t.samba_deps_extended = t.samba_deps[:] + t.samba_includes_extended = TO_LIST(t.samba_includes)[:] + t.cflags = getattr(t, 'samba_cflags', '') + +def replace_grouping_libraries(bld, tgt_list): + '''replace dependencies based on grouping libraries + + If a library is marked as a grouping library, then any target that + depends on a subsystem that is part of that grouping library gets + that dependency replaced with a dependency on the grouping library + ''' + + targets = LOCAL_CACHE(bld, 'TARGET_TYPE') + + grouping = {} + + # find our list of grouping libraries, mapped from the subsystems they depend on + for t in tgt_list: + if not getattr(t, 'grouping_library', False): + continue + for dep in t.samba_deps_extended: + bld.ASSERT(dep in targets, "grouping library target %s not declared in %s" % (dep, t.sname)) + if targets[dep] == 'SUBSYSTEM': + grouping[dep] = t.sname + + # now replace any dependencies on elements of grouping libraries + for t in tgt_list: + for i in range(len(t.samba_deps_extended)): + dep = t.samba_deps_extended[i] + if dep in grouping: + if t.sname != grouping[dep]: + debug("deps: target %s: replacing dependency %s with grouping library %s" % (t.sname, dep, grouping[dep])) + t.samba_deps_extended[i] = grouping[dep] + + + +def build_direct_deps(bld, tgt_list): + '''build the direct_objects and direct_libs sets for each target''' + + targets = LOCAL_CACHE(bld, 'TARGET_TYPE') + syslib_deps = LOCAL_CACHE(bld, 'SYSLIB_DEPS') + + global_deps = bld.env.GLOBAL_DEPENDENCIES + global_deps_exclude = set() + for dep in global_deps: + t = bld.get_tgen_by_name(dep) + for d in t.samba_deps: + # prevent loops from the global dependencies list + global_deps_exclude.add(d) + global_deps_exclude.add(d + '.objlist') + + for t in tgt_list: + t.direct_objects = set() + t.direct_libs = set() + t.direct_syslibs = set() + deps = t.samba_deps_extended[:] + if getattr(t, 'samba_use_global_deps', False) and not t.sname in global_deps_exclude: + deps.extend(global_deps) + for d in deps: + if d == t.sname: continue + if not d in targets: + Logs.error("Unknown dependency '%s' in '%s'" % (d, t.sname)) + sys.exit(1) + if targets[d] in [ 'EMPTY', 'DISABLED' ]: + continue + if targets[d] == 'PYTHON' and targets[t.sname] != 'PYTHON' and t.sname.find('.objlist') == -1: + # this check should be more restrictive, but for now we have pidl-generated python + # code that directly depends on other python modules + Logs.error('ERROR: Target %s has dependency on python module %s' % (t.sname, d)) + sys.exit(1) + if targets[d] == 'SYSLIB': + t.direct_syslibs.add(d) + if d in syslib_deps: + for implied in TO_LIST(syslib_deps[d]): + if BUILTIN_LIBRARY(bld, implied): + t.direct_objects.add(implied) + elif targets[implied] == 'SYSLIB': + t.direct_syslibs.add(implied) + elif targets[implied] in ['LIBRARY', 'MODULE']: + t.direct_libs.add(implied) + else: + Logs.error('Implied dependency %s in %s is of type %s' % ( + implied, t.sname, targets[implied])) + sys.exit(1) + continue + t2 = bld.get_tgen_by_name(d) + if t2 is None: + Logs.error("no task %s of type %s in %s" % (d, targets[d], t.sname)) + sys.exit(1) + if t2.samba_type in [ 'LIBRARY', 'MODULE' ]: + t.direct_libs.add(d) + elif t2.samba_type in [ 'SUBSYSTEM', 'ASN1', 'PYTHON' ]: + t.direct_objects.add(d) + debug('deps: built direct dependencies') + + +def dependency_loop(loops, t, target): + '''add a dependency loop to the loops dictionary''' + if t.sname == target: + return + if not target in loops: + loops[target] = set() + if not t.sname in loops[target]: + loops[target].add(t.sname) + + +def indirect_libs(bld, t, chain, loops): + '''recursively calculate the indirect library dependencies for a target + + An indirect library is a library that results from a dependency on + a subsystem + ''' + + ret = getattr(t, 'indirect_libs', None) + if ret is not None: + return ret + + ret = set() + for obj in t.direct_objects: + if obj in chain: + dependency_loop(loops, t, obj) + continue + chain.add(obj) + t2 = bld.get_tgen_by_name(obj) + r2 = indirect_libs(bld, t2, chain, loops) + chain.remove(obj) + ret = ret.union(t2.direct_libs) + ret = ret.union(r2) + + for obj in indirect_objects(bld, t, set(), loops): + if obj in chain: + dependency_loop(loops, t, obj) + continue + chain.add(obj) + t2 = bld.get_tgen_by_name(obj) + r2 = indirect_libs(bld, t2, chain, loops) + chain.remove(obj) + ret = ret.union(t2.direct_libs) + ret = ret.union(r2) + + t.indirect_libs = ret + + return ret + + +def indirect_objects(bld, t, chain, loops): + '''recursively calculate the indirect object dependencies for a target + + indirect objects are the set of objects from expanding the + subsystem dependencies + ''' + + ret = getattr(t, 'indirect_objects', None) + if ret is not None: return ret + + ret = set() + for lib in t.direct_objects: + if lib in chain: + dependency_loop(loops, t, lib) + continue + chain.add(lib) + t2 = bld.get_tgen_by_name(lib) + r2 = indirect_objects(bld, t2, chain, loops) + chain.remove(lib) + ret = ret.union(t2.direct_objects) + ret = ret.union(r2) + + t.indirect_objects = ret + return ret + + +def extended_objects(bld, t, chain): + '''recursively calculate the extended object dependencies for a target + + extended objects are the union of: + - direct objects + - indirect objects + - direct and indirect objects of all direct and indirect libraries + ''' + + ret = getattr(t, 'extended_objects', None) + if ret is not None: return ret + + ret = set() + ret = ret.union(t.final_objects) + + for lib in t.final_libs: + if lib in chain: + continue + t2 = bld.get_tgen_by_name(lib) + chain.add(lib) + r2 = extended_objects(bld, t2, chain) + chain.remove(lib) + ret = ret.union(t2.final_objects) + ret = ret.union(r2) + + t.extended_objects = ret + return ret + + +def includes_objects(bld, t, chain, inc_loops): + '''recursively calculate the includes object dependencies for a target + + includes dependencies come from either library or object dependencies + ''' + ret = getattr(t, 'includes_objects', None) + if ret is not None: + return ret + + ret = t.direct_objects.copy() + ret = ret.union(t.direct_libs) + + for obj in t.direct_objects: + if obj in chain: + dependency_loop(inc_loops, t, obj) + continue + chain.add(obj) + t2 = bld.get_tgen_by_name(obj) + r2 = includes_objects(bld, t2, chain, inc_loops) + chain.remove(obj) + ret = ret.union(t2.direct_objects) + ret = ret.union(r2) + + for lib in t.direct_libs: + if lib in chain: + dependency_loop(inc_loops, t, lib) + continue + chain.add(lib) + t2 = bld.get_tgen_by_name(lib) + if t2 is None: + targets = LOCAL_CACHE(bld, 'TARGET_TYPE') + Logs.error('Target %s of type %s not found in direct_libs for %s' % ( + lib, targets[lib], t.sname)) + sys.exit(1) + r2 = includes_objects(bld, t2, chain, inc_loops) + chain.remove(lib) + ret = ret.union(t2.direct_objects) + ret = ret.union(r2) + + t.includes_objects = ret + return ret + + +def break_dependency_loops(bld, tgt_list): + '''find and break dependency loops''' + loops = {} + inc_loops = {} + + # build up the list of loops + for t in tgt_list: + indirect_objects(bld, t, set(), loops) + indirect_libs(bld, t, set(), loops) + includes_objects(bld, t, set(), inc_loops) + + # break the loops + for t in tgt_list: + if t.sname in loops: + for attr in ['direct_objects', 'indirect_objects', 'direct_libs', 'indirect_libs']: + objs = getattr(t, attr, set()) + setattr(t, attr, objs.difference(loops[t.sname])) + + for loop in loops: + debug('deps: Found dependency loops for target %s : %s', loop, loops[loop]) + + for loop in inc_loops: + debug('deps: Found include loops for target %s : %s', loop, inc_loops[loop]) + + # expand the loops mapping by one level + for loop in loops.copy(): + for tgt in loops[loop]: + if tgt in loops: + loops[loop] = loops[loop].union(loops[tgt]) + + for loop in inc_loops.copy(): + for tgt in inc_loops[loop]: + if tgt in inc_loops: + inc_loops[loop] = inc_loops[loop].union(inc_loops[tgt]) + + + # expand indirect subsystem and library loops + for loop in loops.copy(): + t = bld.get_tgen_by_name(loop) + if t.samba_type in ['SUBSYSTEM']: + loops[loop] = loops[loop].union(t.indirect_objects) + loops[loop] = loops[loop].union(t.direct_objects) + if t.samba_type in ['LIBRARY','PYTHON']: + loops[loop] = loops[loop].union(t.indirect_libs) + loops[loop] = loops[loop].union(t.direct_libs) + if loop in loops[loop]: + loops[loop].remove(loop) + + # expand indirect includes loops + for loop in inc_loops.copy(): + t = bld.get_tgen_by_name(loop) + inc_loops[loop] = inc_loops[loop].union(t.includes_objects) + if loop in inc_loops[loop]: + inc_loops[loop].remove(loop) + + # add in the replacement dependencies + for t in tgt_list: + for loop in loops: + for attr in ['indirect_objects', 'indirect_libs']: + objs = getattr(t, attr, set()) + if loop in objs: + diff = loops[loop].difference(objs) + if t.sname in diff: + diff.remove(t.sname) + if diff: + debug('deps: Expanded target %s of type %s from loop %s by %s', t.sname, t.samba_type, loop, diff) + objs = objs.union(diff) + setattr(t, attr, objs) + + for loop in inc_loops: + objs = getattr(t, 'includes_objects', set()) + if loop in objs: + diff = inc_loops[loop].difference(objs) + if t.sname in diff: + diff.remove(t.sname) + if diff: + debug('deps: Expanded target %s includes of type %s from loop %s by %s', t.sname, t.samba_type, loop, diff) + objs = objs.union(diff) + setattr(t, 'includes_objects', objs) + + +def reduce_objects(bld, tgt_list): + '''reduce objects by looking for indirect object dependencies''' + rely_on = {} + + for t in tgt_list: + t.extended_objects = None + + changed = False + + for type in ['BINARY', 'PYTHON', 'LIBRARY']: + for t in tgt_list: + if t.samba_type != type: continue + # if we will indirectly link to a target then we don't need it + new = t.final_objects.copy() + for l in t.final_libs: + t2 = bld.get_tgen_by_name(l) + t2_obj = extended_objects(bld, t2, set()) + dup = new.intersection(t2_obj) + if t.sname in rely_on: + dup = dup.difference(rely_on[t.sname]) + if dup: + # Do not remove duplicates of BUILTINS + d = next(iter(dup)) + if BUILTIN_LIBRARY(bld, d): + continue + + debug('deps: removing dups from %s of type %s: %s also in %s %s', + t.sname, t.samba_type, dup, t2.samba_type, l) + new = new.difference(dup) + changed = True + if not l in rely_on: + rely_on[l] = set() + rely_on[l] = rely_on[l].union(dup) + t.final_objects = new + + if not changed: + return False + + # add back in any objects that were relied upon by the reduction rules + for r in rely_on: + t = bld.get_tgen_by_name(r) + t.final_objects = t.final_objects.union(rely_on[r]) + + return True + + +def show_library_loop(bld, lib1, lib2, path, seen): + '''show the detailed path of a library loop between lib1 and lib2''' + + t = bld.get_tgen_by_name(lib1) + if not lib2 in getattr(t, 'final_libs', set()): + return + + for d in t.samba_deps_extended: + if d in seen: + continue + seen.add(d) + path2 = path + '=>' + d + if d == lib2: + Logs.warn('library loop path: ' + path2) + return + show_library_loop(bld, d, lib2, path2, seen) + seen.remove(d) + + +def calculate_final_deps(bld, tgt_list, loops): + '''calculate the final library and object dependencies''' + for t in tgt_list: + # start with the maximum possible list + t.final_libs = t.direct_libs.union(indirect_libs(bld, t, set(), loops)) + t.final_objects = t.direct_objects.union(indirect_objects(bld, t, set(), loops)) + + for t in tgt_list: + # don't depend on ourselves + if t.sname in t.final_libs: + t.final_libs.remove(t.sname) + if t.sname in t.final_objects: + t.final_objects.remove(t.sname) + + # handle any non-shared binaries + for t in tgt_list: + if t.samba_type == 'BINARY' and bld.NONSHARED_BINARY(t.sname): + subsystem_list = LOCAL_CACHE(bld, 'INIT_FUNCTIONS') + targets = LOCAL_CACHE(bld, 'TARGET_TYPE') + + # replace lib deps with objlist deps + for l in t.final_libs: + objname = l + '.objlist' + t2 = bld.get_tgen_by_name(objname) + if t2 is None: + Logs.error('ERROR: subsystem %s not found' % objname) + sys.exit(1) + t.final_objects.add(objname) + t.final_objects = t.final_objects.union(extended_objects(bld, t2, set())) + if l in subsystem_list: + # its a subsystem - we also need the contents of any modules + for d in subsystem_list[l]: + module_name = d['TARGET'] + if targets[module_name] == 'LIBRARY': + objname = module_name + '.objlist' + elif targets[module_name] == 'SUBSYSTEM': + objname = module_name + else: + continue + t2 = bld.get_tgen_by_name(objname) + if t2 is None: + Logs.error('ERROR: subsystem %s not found' % objname) + sys.exit(1) + t.final_objects.add(objname) + t.final_objects = t.final_objects.union(extended_objects(bld, t2, set())) + t.final_libs = set() + + # find any library loops + for t in tgt_list: + if t.samba_type in ['LIBRARY', 'PYTHON']: + for l in t.final_libs.copy(): + t2 = bld.get_tgen_by_name(l) + if t.sname in t2.final_libs: + if getattr(bld.env, "ALLOW_CIRCULAR_LIB_DEPENDENCIES", False): + # we could break this in either direction. If one of the libraries + # has a version number, and will this be distributed publicly, then + # we should make it the lower level library in the DAG + Logs.warn('deps: removing library loop %s from %s' % (t.sname, t2.sname)) + dependency_loop(loops, t, t2.sname) + t2.final_libs.remove(t.sname) + else: + Logs.error('ERROR: circular library dependency between %s and %s' + % (t.sname, t2.sname)) + show_library_loop(bld, t.sname, t2.sname, t.sname, set()) + show_library_loop(bld, t2.sname, t.sname, t2.sname, set()) + sys.exit(1) + + for loop in loops: + debug('deps: Found dependency loops for target %s : %s', loop, loops[loop]) + + # we now need to make corrections for any library loops we broke up + # any target that depended on the target of the loop and doesn't + # depend on the source of the loop needs to get the loop source added + for type in ['BINARY','PYTHON','LIBRARY','BINARY']: + for t in tgt_list: + if t.samba_type != type: continue + for loop in loops: + if loop in t.final_libs: + diff = loops[loop].difference(t.final_libs) + if t.sname in diff: + diff.remove(t.sname) + if t.sname in diff: + diff.remove(t.sname) + # make sure we don't recreate the loop again! + for d in diff.copy(): + t2 = bld.get_tgen_by_name(d) + if t2.samba_type == 'LIBRARY': + if t.sname in t2.final_libs: + debug('deps: removing expansion %s from %s', d, t.sname) + diff.remove(d) + if diff: + debug('deps: Expanded target %s by loop %s libraries (loop %s) %s', t.sname, loop, + loops[loop], diff) + t.final_libs = t.final_libs.union(diff) + + # remove objects that are also available in linked libs + count = 0 + while reduce_objects(bld, tgt_list): + count += 1 + if count > 100: + Logs.warn("WARNING: Unable to remove all inter-target object duplicates") + break + debug('deps: Object reduction took %u iterations', count) + + # add in any syslib dependencies + for t in tgt_list: + if not t.samba_type in ['BINARY','PYTHON','LIBRARY','SUBSYSTEM']: + continue + syslibs = set() + for d in t.final_objects: + t2 = bld.get_tgen_by_name(d) + syslibs = syslibs.union(t2.direct_syslibs) + # this adds the indirect syslibs as well, which may not be needed + # depending on the linker flags + for d in t.final_libs: + t2 = bld.get_tgen_by_name(d) + syslibs = syslibs.union(t2.direct_syslibs) + t.final_syslibs = syslibs + + + # find any unresolved library loops + lib_loop_error = False + for t in tgt_list: + if t.samba_type in ['LIBRARY', 'PYTHON']: + for l in t.final_libs.copy(): + t2 = bld.get_tgen_by_name(l) + if t.sname in t2.final_libs: + Logs.error('ERROR: Unresolved library loop %s from %s' % (t.sname, t2.sname)) + lib_loop_error = True + if lib_loop_error: + sys.exit(1) + + debug('deps: removed duplicate dependencies') + + +def show_dependencies(bld, target, seen): + '''recursively show the dependencies of target''' + + if target in seen: + return + + t = bld.get_tgen_by_name(target) + if t is None: + Logs.error("ERROR: Unable to find target '%s'" % target) + sys.exit(1) + + Logs.info('%s(OBJECTS): %s' % (target, t.direct_objects)) + Logs.info('%s(LIBS): %s' % (target, t.direct_libs)) + Logs.info('%s(SYSLIBS): %s' % (target, t.direct_syslibs)) + + seen.add(target) + + for t2 in t.direct_objects: + show_dependencies(bld, t2, seen) + + +def show_object_duplicates(bld, tgt_list): + '''show a list of object files that are included in more than + one library or binary''' + + targets = LOCAL_CACHE(bld, 'TARGET_TYPE') + + used_by = {} + + Logs.info("showing duplicate objects") + + for t in tgt_list: + if not targets[t.sname] in [ 'LIBRARY', 'PYTHON' ]: + continue + for n in getattr(t, 'final_objects', set()): + t2 = bld.get_tgen_by_name(n) + if not n in used_by: + used_by[n] = set() + used_by[n].add(t.sname) + + for n in used_by: + if len(used_by[n]) > 1: + Logs.info("target '%s' is used by %s" % (n, used_by[n])) + + Logs.info("showing indirect dependency counts (sorted by count)") + + def indirect_count(t1, t2): + return len(t2.indirect_objects) - len(t1.indirect_objects) + + sorted_list = sorted(tgt_list, cmp=indirect_count) + for t in sorted_list: + if len(t.indirect_objects) > 1: + Logs.info("%s depends on %u indirect objects" % (t.sname, len(t.indirect_objects))) + + +###################################################################### +# this provides a way to save our dependency calculations between runs +savedeps_version = 3 +savedeps_inputs = ['samba_deps', 'samba_includes', 'local_include', 'local_include_first', 'samba_cflags', + 'source', 'grouping_library', 'samba_ldflags', 'allow_undefined_symbols', + 'use_global_deps', 'global_include' ] +savedeps_outputs = ['uselib', 'uselib_local', 'add_objects', 'includes', + 'cflags', 'ldflags', 'samba_deps_extended', 'final_libs'] +savedeps_outenv = ['INC_PATHS'] +savedeps_envvars = ['NONSHARED_BINARIES', 'GLOBAL_DEPENDENCIES', 'EXTRA_CFLAGS', 'EXTRA_LDFLAGS', 'EXTRA_INCLUDES' ] +savedeps_caches = ['GLOBAL_DEPENDENCIES', 'TARGET_TYPE', 'INIT_FUNCTIONS', 'SYSLIB_DEPS'] +savedeps_files = ['buildtools/wafsamba/samba_deps.py'] + +def save_samba_deps(bld, tgt_list): + '''save the dependency calculations between builds, to make + further builds faster''' + denv = ConfigSet.ConfigSet() + + denv.version = savedeps_version + denv.savedeps_inputs = savedeps_inputs + denv.savedeps_outputs = savedeps_outputs + denv.input = {} + denv.output = {} + denv.outenv = {} + denv.caches = {} + denv.envvar = {} + denv.files = {} + + for f in savedeps_files: + denv.files[f] = os.stat(os.path.join(bld.srcnode.abspath(), f)).st_mtime + + for c in savedeps_caches: + denv.caches[c] = LOCAL_CACHE(bld, c) + + for e in savedeps_envvars: + denv.envvar[e] = bld.env[e] + + for t in tgt_list: + # save all the input attributes for each target + tdeps = {} + for attr in savedeps_inputs: + v = getattr(t, attr, None) + if v is not None: + tdeps[attr] = v + if tdeps != {}: + denv.input[t.sname] = tdeps + + # save all the output attributes for each target + tdeps = {} + for attr in savedeps_outputs: + v = getattr(t, attr, None) + if v is not None: + tdeps[attr] = v + if tdeps != {}: + denv.output[t.sname] = tdeps + + tdeps = {} + for attr in savedeps_outenv: + if attr in t.env: + tdeps[attr] = t.env[attr] + if tdeps != {}: + denv.outenv[t.sname] = tdeps + + depsfile = os.path.join(bld.cache_dir, "sambadeps") + denv.store_fast(depsfile) + + + +def load_samba_deps(bld, tgt_list): + '''load a previous set of build dependencies if possible''' + depsfile = os.path.join(bld.cache_dir, "sambadeps") + denv = ConfigSet.ConfigSet() + try: + debug('deps: checking saved dependencies') + denv.load_fast(depsfile) + if (denv.version != savedeps_version or + denv.savedeps_inputs != savedeps_inputs or + denv.savedeps_outputs != savedeps_outputs): + return False + except Exception: + return False + + # check if critical files have changed + for f in savedeps_files: + if f not in denv.files: + return False + if denv.files[f] != os.stat(os.path.join(bld.srcnode.abspath(), f)).st_mtime: + return False + + # check if caches are the same + for c in savedeps_caches: + if c not in denv.caches or denv.caches[c] != LOCAL_CACHE(bld, c): + return False + + # check if caches are the same + for e in savedeps_envvars: + if e not in denv.envvar or denv.envvar[e] != bld.env[e]: + return False + + # check inputs are the same + for t in tgt_list: + tdeps = {} + for attr in savedeps_inputs: + v = getattr(t, attr, None) + if v is not None: + tdeps[attr] = v + if t.sname in denv.input: + olddeps = denv.input[t.sname] + else: + olddeps = {} + if tdeps != olddeps: + #print '%s: \ntdeps=%s \nodeps=%s' % (t.sname, tdeps, olddeps) + return False + + # put outputs in place + for t in tgt_list: + if not t.sname in denv.output: continue + tdeps = denv.output[t.sname] + for a in tdeps: + setattr(t, a, tdeps[a]) + + # put output env vars in place + for t in tgt_list: + if not t.sname in denv.outenv: continue + tdeps = denv.outenv[t.sname] + for a in tdeps: + t.env[a] = tdeps[a] + + debug('deps: loaded saved dependencies') + return True + + + +def check_project_rules(bld): + '''check the project rules - ensuring the targets are sane''' + + loops = {} + inc_loops = {} + + tgt_list = get_tgt_list(bld) + + add_samba_attributes(bld, tgt_list) + + force_project_rules = (Options.options.SHOWDEPS or + Options.options.SHOW_DUPLICATES) + + if not force_project_rules and load_samba_deps(bld, tgt_list): + return + + timer = Utils.Timer() + + bld.new_rules = True + Logs.info("Checking project rules ...") + + debug('deps: project rules checking started') + + expand_subsystem_deps(bld) + + debug("deps: expand_subsystem_deps: %s" % str(timer)) + + replace_grouping_libraries(bld, tgt_list) + + debug("deps: replace_grouping_libraries: %s" % str(timer)) + + build_direct_deps(bld, tgt_list) + + debug("deps: build_direct_deps: %s" % str(timer)) + + break_dependency_loops(bld, tgt_list) + + debug("deps: break_dependency_loops: %s" % str(timer)) + + if Options.options.SHOWDEPS: + show_dependencies(bld, Options.options.SHOWDEPS, set()) + + calculate_final_deps(bld, tgt_list, loops) + + debug("deps: calculate_final_deps: %s" % str(timer)) + + if Options.options.SHOW_DUPLICATES: + show_object_duplicates(bld, tgt_list) + + # run the various attribute generators + for f in [ build_dependencies, build_includes, add_init_functions ]: + debug('deps: project rules checking %s', f) + for t in tgt_list: f(t) + debug("deps: %s: %s" % (f, str(timer))) + + debug('deps: project rules stage1 completed') + + if not check_duplicate_sources(bld, tgt_list): + Logs.error("Duplicate sources present - aborting") + sys.exit(1) + + debug("deps: check_duplicate_sources: %s" % str(timer)) + + if not bld.check_group_ordering(tgt_list): + Logs.error("Bad group ordering - aborting") + sys.exit(1) + + debug("deps: check_group_ordering: %s" % str(timer)) + + show_final_deps(bld, tgt_list) + + debug("deps: show_final_deps: %s" % str(timer)) + + debug('deps: project rules checking completed - %u targets checked', + len(tgt_list)) + + if not bld.is_install: + save_samba_deps(bld, tgt_list) + + debug("deps: save_samba_deps: %s" % str(timer)) + + Logs.info("Project rules pass") + + +def CHECK_PROJECT_RULES(bld): + '''enable checking of project targets for sanity''' + if bld.env.added_project_rules: + return + bld.env.added_project_rules = True + bld.add_pre_fun(check_project_rules) +Build.BuildContext.CHECK_PROJECT_RULES = CHECK_PROJECT_RULES + + diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_dist.py b/ldb-2.0.8/buildtools/wafsamba/samba_dist.py new file mode 100644 index 0000000..6af7bb4 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/samba_dist.py @@ -0,0 +1,280 @@ +# customised version of 'waf dist' for Samba tools +# uses git ls-files to get file lists + +import os, sys, tarfile +from waflib import Utils, Scripting, Logs, Options +from waflib.Configure import conf +from samba_utils import os_path_relpath, get_string +from waflib import Context + +dist_dirs = None +dist_files = None +dist_blacklist = "" +dist_archive = None + +class Dist(Context.Context): + # TODO remove + cmd = 'dist' + fun = 'dist' + def execute(self): + Context.g_module.dist() + +class DistCheck(Scripting.DistCheck): + fun = 'distcheck' + cmd = 'distcheck' + def execute(self): + Options.options.distcheck_args = '' + if Context.g_module.distcheck is Scripting.distcheck: + # default + Context.g_module.distcheck(self) + else: + Context.g_module.distcheck() + Context.g_module.dist() + self.check() + def get_arch_name(self): + global dist_archive + return dist_archive + def make_distcheck_cmd(self, tmpdir): + waf = os.path.abspath(sys.argv[0]) + return [sys.executable, waf, 'configure', 'build', 'install', 'uninstall', '--destdir=' + tmpdir] + +def add_symlink(tar, fname, abspath, basedir): + '''handle symlinks to directories that may move during packaging''' + if not os.path.islink(abspath): + return False + tinfo = tar.gettarinfo(name=abspath, arcname=fname) + tgt = os.readlink(abspath) + + if dist_dirs: + # we need to find the target relative to the main directory + # this is here to cope with symlinks into the buildtools + # directory from within the standalone libraries in Samba. For example, + # a symlink to ../../builtools/scripts/autogen-waf.sh needs + # to be rewritten as a symlink to buildtools/scripts/autogen-waf.sh + # when the tarball for talloc is built + + # the filename without the appname-version + rel_fname = '/'.join(fname.split('/')[1:]) + + # join this with the symlink target + tgt_full = os.path.join(os.path.dirname(rel_fname), tgt) + + # join with the base directory + tgt_base = os.path.normpath(os.path.join(basedir, tgt_full)) + + # see if this is inside one of our dist_dirs + for dir in dist_dirs.split(): + if dir.find(':') != -1: + destdir=dir.split(':')[1] + dir=dir.split(':')[0] + else: + destdir = '.' + if dir == basedir: + # internal links don't get rewritten + continue + if dir == tgt_base[0:len(dir)] and tgt_base[len(dir)] == '/': + new_tgt = destdir + tgt_base[len(dir):] + tinfo.linkname = new_tgt + break + + tinfo.uid = 0 + tinfo.gid = 0 + tinfo.uname = 'root' + tinfo.gname = 'root' + tar.addfile(tinfo) + return True + +def add_tarfile(tar, fname, abspath, basedir): + '''add a file to the tarball''' + if add_symlink(tar, fname, abspath, basedir): + return + try: + tinfo = tar.gettarinfo(name=abspath, arcname=fname) + except OSError: + Logs.error('Unable to find file %s - missing from git checkout?' % abspath) + sys.exit(1) + tinfo.uid = 0 + tinfo.gid = 0 + tinfo.uname = 'root' + tinfo.gname = 'root' + fh = open(abspath, "rb") + tar.addfile(tinfo, fileobj=fh) + fh.close() + + +def vcs_dir_contents(path): + """Return the versioned files under a path. + + :return: List of paths relative to path + """ + repo = path + while repo != "/": + if os.path.isdir(os.path.join(repo, ".git")): + ls_files_cmd = [ 'git', 'ls-files', '--full-name', + os_path_relpath(path, repo) ] + cwd = None + env = dict(os.environ) + env["GIT_DIR"] = os.path.join(repo, ".git") + break + repo = os.path.dirname(repo) + if repo == "/": + raise Exception("unsupported or no vcs for %s" % path) + return get_string(Utils.cmd_output(ls_files_cmd, cwd=cwd, env=env)).split('\n') + + +def dist(appname='', version=''): + + def add_files_to_tarball(tar, srcdir, srcsubdir, dstdir, dstsubdir, blacklist, files): + if blacklist is None: + blacklist = [] + for f in files: + abspath = os.path.join(srcdir, f) + + if srcsubdir != '.': + f = f[len(srcsubdir)+1:] + + # Remove files in the blacklist + if f in blacklist: + continue + blacklisted = False + # Remove directories in the blacklist + for d in blacklist: + if f.startswith(d): + blacklisted = True + if blacklisted: + continue + if os.path.isdir(abspath) and not os.path.islink(abspath): + continue + if dstsubdir != '.': + f = dstsubdir + '/' + f + fname = dstdir + '/' + f + add_tarfile(tar, fname, abspath, srcsubdir) + + + def list_directory_files(path): + curdir = os.getcwd() + os.chdir(srcdir) + out_files = [] + for root, dirs, files in os.walk(path): + for f in files: + out_files.append(os.path.join(root, f)) + os.chdir(curdir) + return out_files + + + if not isinstance(appname, str) or not appname: + # this copes with a mismatch in the calling arguments for dist() + appname = Context.g_module.APPNAME + version = Context.g_module.VERSION + if not version: + version = Context.g_module.VERSION + + srcdir = os.path.normpath( + os.path.join(os.path.dirname(Context.g_module.root_path), + Context.g_module.top)) + + if not dist_dirs: + Logs.error('You must use samba_dist.DIST_DIRS() to set which directories to package') + sys.exit(1) + + dist_base = '%s-%s' % (appname, version) + + if Options.options.SIGN_RELEASE: + dist_name = '%s.tar' % (dist_base) + tar = tarfile.open(dist_name, 'w') + else: + dist_name = '%s.tar.gz' % (dist_base) + tar = tarfile.open(dist_name, 'w:gz') + + blacklist = dist_blacklist.split() + + for dir in dist_dirs.split(): + if dir.find(':') != -1: + destdir=dir.split(':')[1] + dir=dir.split(':')[0] + else: + destdir = '.' + absdir = os.path.join(srcdir, dir) + try: + files = vcs_dir_contents(absdir) + except Exception as e: + Logs.error('unable to get contents of %s: %s' % (absdir, e)) + sys.exit(1) + add_files_to_tarball(tar, srcdir, dir, dist_base, destdir, blacklist, files) + + if dist_files: + for file in dist_files.split(): + if file.find(':') != -1: + destfile = file.split(':')[1] + file = file.split(':')[0] + else: + destfile = file + + absfile = os.path.join(srcdir, file) + + if os.path.isdir(absfile) and not os.path.islink(absfile): + destdir = destfile + dir = file + files = list_directory_files(dir) + add_files_to_tarball(tar, srcdir, dir, dist_base, destdir, blacklist, files) + else: + fname = dist_base + '/' + destfile + add_tarfile(tar, fname, absfile, destfile) + + tar.close() + + if Options.options.SIGN_RELEASE: + import gzip + try: + os.unlink(dist_name + '.asc') + except OSError: + pass + + cmd = "gpg --detach-sign --armor " + dist_name + os.system(cmd) + uncompressed_tar = open(dist_name, 'rb') + compressed_tar = gzip.open(dist_name + '.gz', 'wb') + while 1: + buffer = uncompressed_tar.read(1048576) + if buffer: + compressed_tar.write(buffer) + else: + break + uncompressed_tar.close() + compressed_tar.close() + os.unlink(dist_name) + Logs.info('Created %s.gz %s.asc' % (dist_name, dist_name)) + dist_name = dist_name + '.gz' + else: + Logs.info('Created %s' % dist_name) + + # TODO use the ctx object instead + global dist_archive + dist_archive = dist_name + return dist_name + + +@conf +def DIST_DIRS(dirs): + '''set the directories to package, relative to top srcdir''' + global dist_dirs + if not dist_dirs: + dist_dirs = dirs + +@conf +def DIST_FILES(files, extend=False): + '''set additional files for packaging, relative to top srcdir''' + global dist_files + if not dist_files: + dist_files = files + elif extend: + dist_files = dist_files + " " + files + +@conf +def DIST_BLACKLIST(blacklist): + '''set the files to exclude from packaging, relative to top srcdir''' + global dist_blacklist + if not dist_blacklist: + dist_blacklist = blacklist + +Scripting.dist = dist diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_git.py b/ldb-2.0.8/buildtools/wafsamba/samba_git.py new file mode 100644 index 0000000..09a204f --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/samba_git.py @@ -0,0 +1,57 @@ +import os +import subprocess + +def find_git(env=None): + """Find the git binary.""" + if env is not None and 'GIT' in env: + return env.get_flat('GIT') + + # Get version from GIT + if os.path.exists("/usr/bin/git"): + # this is useful when doing make dist without configuring + return "/usr/bin/git" + + return None + + +def has_submodules(path): + """Check whether a source directory is git-versioned and has submodules. + + :param path: Path to Samba source directory + """ + return (os.path.isdir(os.path.join(path, ".git")) and + os.path.isfile(os.path.join(path, ".gitmodules"))) + + +def read_submodule_status(path, env=None): + """Check status of submodules. + + :param path: Path to git directory + :param env: Optional waf environment + :return: Yields tuples with submodule relpath and status + (one of: 'out-of-date', 'not-checked-out', 'up-to-date') + :raise RuntimeError: raised when parsing of 'git submodule status' output + fails. + """ + if not has_submodules(path): + # No point in running git. + return + git = find_git(env) + if git is None: + return + p = subprocess.Popen([git, "submodule", "status"], stdout=subprocess.PIPE, + cwd=path) + (stdout, stderr) = p.communicate(None) + for l in stdout.splitlines(): + l = l.rstrip() + status = l[0] + l = l[1:] + parts = l.split(" ") + if len(parts) > 2 and status in ("-", "+"): + yield (parts[1], "out-of-date") + elif len(parts) == 2 and status == "-": + yield (parts[1], "not-checked-out") + elif len(parts) > 2 and status == " ": + yield (parts[1], "up-to-date") + else: + raise RuntimeError("Unable to parse submodule status: %r, %r" % (status, parts)) diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_headers.py b/ldb-2.0.8/buildtools/wafsamba/samba_headers.py new file mode 100644 index 0000000..a268c01 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/samba_headers.py @@ -0,0 +1,181 @@ +# specialist handling of header files for Samba + +import os, re, sys, fnmatch +from waflib import Build, Logs, Utils, Errors +from samba_utils import TO_LIST, os_path_relpath + + +def header_install_path(header, header_path): + '''find the installation path for a header, given a header_path option''' + if not header_path: + return '' + if not isinstance(header_path, list): + return header_path + for (p1, dir) in header_path: + for p2 in TO_LIST(p1): + if fnmatch.fnmatch(header, p2): + return dir + # default to current path + return '' + + +re_header = re.compile('^\s*#\s*include[ \t]*"([^"]+)"', re.I | re.M) + +# a dictionary mapping source header paths to public header paths +header_map = {} + +def find_suggested_header(hpath): + '''find a suggested header path to use''' + base = os.path.basename(hpath) + ret = [] + for h in header_map: + if os.path.basename(h) == base: + ret.append('<%s>' % header_map[h]) + ret.append('"%s"' % h) + return ret + +def create_public_header(task): + '''create a public header from a private one, output within the build tree''' + src = task.inputs[0].abspath(task.env) + tgt = task.outputs[0].bldpath(task.env) + + if os.path.exists(tgt): + os.unlink(tgt) + + relsrc = os_path_relpath(src, task.env.TOPDIR) + + infile = open(src, mode='r') + outfile = open(tgt, mode='w') + linenumber = 0 + + search_paths = [ '', task.env.RELPATH ] + for i in task.env.EXTRA_INCLUDES: + if i.startswith('#'): + search_paths.append(i[1:]) + + for line in infile: + linenumber += 1 + + # allow some straight substitutions + if task.env.public_headers_replace and line.strip() in task.env.public_headers_replace: + outfile.write(task.env.public_headers_replace[line.strip()] + '\n') + continue + + # see if its an include line + m = re_header.match(line) + if m is None: + outfile.write(line) + continue + + # its an include, get the header path + hpath = m.group(1) + if hpath.startswith("bin/default/"): + hpath = hpath[12:] + + # some are always allowed + if task.env.public_headers_skip and hpath in task.env.public_headers_skip: + outfile.write(line) + continue + + # work out the header this refers to + found = False + for s in search_paths: + p = os.path.normpath(os.path.join(s, hpath)) + if p in header_map: + outfile.write("#include <%s>\n" % header_map[p]) + found = True + break + if found: + continue + + if task.env.public_headers_allow_broken: + Logs.warn("Broken public header include '%s' in '%s'" % (hpath, relsrc)) + outfile.write(line) + continue + + # try to be nice to the developer by suggesting an alternative + suggested = find_suggested_header(hpath) + outfile.close() + os.unlink(tgt) + sys.stderr.write("%s:%u:Error: unable to resolve public header %s (maybe try one of %s)\n" % ( + os.path.relpath(src, os.getcwd()), linenumber, hpath, suggested)) + raise Errors.WafError("Unable to resolve header path '%s' in public header '%s' in directory %s" % ( + hpath, relsrc, task.env.RELPATH)) + infile.close() + outfile.close() + + +def public_headers_simple(bld, public_headers, header_path=None, public_headers_install=True): + '''install some headers - simple version, no munging needed + ''' + if not public_headers_install: + return + for h in TO_LIST(public_headers): + inst_path = header_install_path(h, header_path) + if h.find(':') != -1: + s = h.split(":") + h_name = s[0] + inst_name = s[1] + else: + h_name = h + inst_name = os.path.basename(h) + bld.INSTALL_FILES('${INCLUDEDIR}', h_name, destname=inst_name) + + +def PUBLIC_HEADERS(bld, public_headers, header_path=None, public_headers_install=True): + '''install some headers + + header_path may either be a string that is added to the INCLUDEDIR, + or it can be a dictionary of wildcard patterns which map to destination + directories relative to INCLUDEDIR + ''' + bld.SET_BUILD_GROUP('final') + + if not bld.env.build_public_headers: + # in this case no header munging neeeded. Used for tdb, talloc etc + public_headers_simple(bld, public_headers, header_path=header_path, + public_headers_install=public_headers_install) + return + + # create the public header in the given path + # in the build tree + for h in TO_LIST(public_headers): + inst_path = header_install_path(h, header_path) + if h.find(':') != -1: + s = h.split(":") + h_name = s[0] + inst_name = s[1] + else: + h_name = h + inst_name = os.path.basename(h) + curdir = bld.path.abspath() + relpath1 = os_path_relpath(bld.srcnode.abspath(), curdir) + relpath2 = os_path_relpath(curdir, bld.srcnode.abspath()) + targetdir = os.path.normpath(os.path.join(relpath1, bld.env.build_public_headers, inst_path)) + if not os.path.exists(os.path.join(curdir, targetdir)): + raise Errors.WafError("missing source directory %s for public header %s" % (targetdir, inst_name)) + target = os.path.join(targetdir, inst_name) + + # the source path of the header, relative to the top of the source tree + src_path = os.path.normpath(os.path.join(relpath2, h_name)) + + # the install path of the header, relative to the public include directory + target_path = os.path.normpath(os.path.join(inst_path, inst_name)) + + header_map[src_path] = target_path + + t = bld.SAMBA_GENERATOR('HEADER_%s/%s/%s' % (relpath2, inst_path, inst_name), + group='headers', + rule=create_public_header, + source=h_name, + target=target) + t.env.RELPATH = relpath2 + t.env.TOPDIR = bld.srcnode.abspath() + if not bld.env.public_headers_list: + bld.env.public_headers_list = [] + bld.env.public_headers_list.append(os.path.join(inst_path, inst_name)) + if public_headers_install: + bld.INSTALL_FILES('${INCLUDEDIR}', + target, + destname=os.path.join(inst_path, inst_name), flat=True) +Build.BuildContext.PUBLIC_HEADERS = PUBLIC_HEADERS diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_install.py b/ldb-2.0.8/buildtools/wafsamba/samba_install.py new file mode 100644 index 0000000..07b01d6 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/samba_install.py @@ -0,0 +1,236 @@ +########################### +# this handles the magic we need to do for installing +# with all the configure options that affect rpath and shared +# library use + +import os +from waflib import Utils, Errors +from waflib.TaskGen import feature, before, after +from samba_utils import LIB_PATH, MODE_755, install_rpath, build_rpath + +@feature('install_bin') +@after('apply_core') +@before('apply_link', 'apply_obj_vars') +def install_binary(self): + '''install a binary, taking account of the different rpath varients''' + bld = self.bld + + # get the ldflags we will use for install and build + install_ldflags = install_rpath(self) + build_ldflags = build_rpath(bld) + + if not self.bld.is_install: + # just need to set rpath if we are not installing + self.env.RPATH = build_ldflags + return + + # work out the install path, expanding variables + install_path = getattr(self, 'samba_inst_path', None) or '${BINDIR}' + install_path = bld.EXPAND_VARIABLES(install_path) + + orig_target = os.path.basename(self.target) + + if install_ldflags != build_ldflags: + # we will be creating a new target name, and using that for the + # install link. That stops us from overwriting the existing build + # target, which has different ldflags + self.target += '.inst' + + # setup the right rpath link flags for the install + self.env.RPATH = install_ldflags + + if not self.samba_install: + # this binary is marked not to be installed + return + + # tell waf to install the right binary + bld.install_as(os.path.join(install_path, orig_target), + self.path.find_or_declare(self.target), + chmod=MODE_755) + + + +@feature('install_lib') +@after('apply_core') +@before('apply_link', 'apply_obj_vars') +def install_library(self): + '''install a library, taking account of the different rpath varients''' + if getattr(self, 'done_install_library', False): + return + + bld = self.bld + + default_env = bld.all_envs['default'] + try: + install_ldflags = install_rpath(self) + build_ldflags = build_rpath(bld) + + if not self.bld.is_install or not getattr(self, 'samba_install', True): + # just need to set the build rpath if we are not installing + self.env.RPATH = build_ldflags + return + + # setup the install path, expanding variables + install_path = getattr(self, 'samba_inst_path', None) + if install_path is None: + if getattr(self, 'private_library', False): + install_path = '${PRIVATELIBDIR}' + else: + install_path = '${LIBDIR}' + install_path = bld.EXPAND_VARIABLES(install_path) + + target_name = self.target + + if install_ldflags != build_ldflags: + # we will be creating a new target name, and using that for the + # install link. That stops us from overwriting the existing build + # target, which has different ldflags + self.done_install_library = True + t = self.clone(self.env) + t.posted = False + t.target += '.inst' + t.name = self.name + '.inst' + self.env.RPATH = build_ldflags + else: + t = self + + t.env.RPATH = install_ldflags + + dev_link = None + + # in the following the names are: + # - inst_name is the name with .inst. in it, in the build + # directory + # - install_name is the name in the install directory + # - install_link is a symlink in the install directory, to install_name + + if getattr(self, 'samba_realname', None): + install_name = self.samba_realname + install_link = None + if getattr(self, 'soname', ''): + install_link = self.soname + if getattr(self, 'samba_type', None) == 'PYTHON': + inst_name = bld.make_libname(t.target, nolibprefix=True, python=True) + else: + inst_name = bld.make_libname(t.target) + elif self.vnum: + vnum_base = self.vnum.split('.')[0] + install_name = bld.make_libname(target_name, version=self.vnum) + install_link = bld.make_libname(target_name, version=vnum_base) + inst_name = bld.make_libname(t.target) + if not self.private_library or not t.env.SONAME_ST: + # only generate the dev link for non-bundled libs + dev_link = bld.make_libname(target_name) + elif getattr(self, 'soname', ''): + install_name = bld.make_libname(target_name) + install_link = self.soname + inst_name = bld.make_libname(t.target) + else: + install_name = bld.make_libname(target_name) + install_link = None + inst_name = bld.make_libname(t.target) + + if t.env.SONAME_ST: + # ensure we get the right names in the library + if install_link: + t.env.append_value('LINKFLAGS', t.env.SONAME_ST % install_link) + else: + t.env.append_value('LINKFLAGS', t.env.SONAME_ST % install_name) + t.env.SONAME_ST = '' + + # tell waf to install the library + bld.install_as(os.path.join(install_path, install_name), + self.path.find_or_declare(inst_name), + chmod=MODE_755) + + if install_link and install_link != install_name: + # and the symlink if needed + bld.symlink_as(os.path.join(install_path, install_link), os.path.basename(install_name)) + if dev_link: + bld.symlink_as(os.path.join(install_path, dev_link), os.path.basename(install_name)) + finally: + bld.all_envs['default'] = default_env + + +@feature('cshlib') +@after('apply_implib') +@before('apply_vnum') +def apply_soname(self): + '''install a library, taking account of the different rpath varients''' + + if self.env.SONAME_ST and getattr(self, 'soname', ''): + self.env.append_value('LINKFLAGS', self.env.SONAME_ST % self.soname) + self.env.SONAME_ST = '' + +@feature('cshlib') +@after('apply_implib') +@before('apply_vnum') +def apply_vscript(self): + '''add version-script arguments to library build''' + + if self.env.HAVE_LD_VERSION_SCRIPT and getattr(self, 'version_script', ''): + self.env.append_value('LINKFLAGS', "-Wl,--version-script=%s" % + self.version_script) + self.version_script = None + + +############################## +# handle the creation of links for libraries and binaries in the build tree + +@feature('symlink_lib') +@after('apply_link') +def symlink_lib(self): + '''symlink a shared lib''' + + if self.target.endswith('.inst'): + return + + blddir = os.path.dirname(self.bld.srcnode.abspath(self.bld.env)) + libpath = self.link_task.outputs[0].abspath(self.env) + + # calculat the link target and put it in the environment + soext="" + vnum = getattr(self, 'vnum', None) + if vnum is not None: + soext = '.' + vnum.split('.')[0] + + link_target = getattr(self, 'link_name', '') + if link_target == '': + basename = os.path.basename(self.bld.make_libname(self.target, version=soext)) + if getattr(self, "private_library", False): + link_target = '%s/private/%s' % (LIB_PATH, basename) + else: + link_target = '%s/%s' % (LIB_PATH, basename) + + link_target = os.path.join(blddir, link_target) + + if os.path.lexists(link_target): + if os.path.islink(link_target) and os.readlink(link_target) == libpath: + return + os.unlink(link_target) + + link_container = os.path.dirname(link_target) + if not os.path.isdir(link_container): + os.makedirs(link_container) + + os.symlink(libpath, link_target) + + +@feature('symlink_bin') +@after('apply_link') +def symlink_bin(self): + '''symlink a binary into the build directory''' + + if self.target.endswith('.inst'): + return + + if not self.link_task.outputs or not self.link_task.outputs[0]: + raise Errors.WafError('no outputs found for %s in symlink_bin' % self.name) + binpath = self.link_task.outputs[0].abspath(self.env) + bldpath = os.path.join(self.bld.env.BUILD_DIRECTORY, self.link_task.outputs[0].name) + + if os.path.lexists(bldpath): + if os.path.islink(bldpath) and os.readlink(bldpath) == binpath: + return + os.unlink(bldpath) + os.symlink(binpath, bldpath) diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_patterns.py b/ldb-2.0.8/buildtools/wafsamba/samba_patterns.py new file mode 100644 index 0000000..d0fe965 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/samba_patterns.py @@ -0,0 +1,201 @@ +# a waf tool to add extension based build patterns for Samba + +import sys +from waflib import Build +from wafsamba import samba_version_file + +def write_version_header(task): + '''print version.h contents''' + src = task.inputs[0].srcpath(task.env) + + version = samba_version_file(src, task.env.srcdir, env=task.env, is_install=task.generator.bld.is_install) + string = str(version) + + task.outputs[0].write(string) + return 0 + + +def SAMBA_MKVERSION(bld, target, source='VERSION'): + '''generate the version.h header for Samba''' + + # We only force waf to re-generate this file if we are installing, + # because only then is information not included in the deps (the + # git revision) included in the version. + t = bld.SAMBA_GENERATOR('VERSION', + rule=write_version_header, + source=source, + target=target, + always=bld.is_install) +Build.BuildContext.SAMBA_MKVERSION = SAMBA_MKVERSION + + +def write_build_options_header(fp): + '''write preamble for build_options.c''' + fp.write("/*\n") + fp.write(" Unix SMB/CIFS implementation.\n") + fp.write(" Build Options for Samba Suite\n") + fp.write(" Copyright (C) Vance Lankhaar 2003\n") + fp.write(" Copyright (C) Andrew Bartlett 2001\n") + fp.write("\n") + fp.write(" This program is free software; you can redistribute it and/or modify\n") + fp.write(" it under the terms of the GNU General Public License as published by\n") + fp.write(" the Free Software Foundation; either version 3 of the License, or\n") + fp.write(" (at your option) any later version.\n") + fp.write("\n") + fp.write(" This program is distributed in the hope that it will be useful,\n") + fp.write(" but WITHOUT ANY WARRANTY; without even the implied warranty of\n") + fp.write(" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") + fp.write(" GNU General Public License for more details.\n") + fp.write("\n") + fp.write(" You should have received a copy of the GNU General Public License\n") + fp.write(" along with this program; if not, see .\n") + fp.write("*/\n") + fp.write("\n") + fp.write("#include \"includes.h\"\n") + fp.write("#include \"dynconfig/dynconfig.h\"\n") + fp.write("#include \"lib/cluster_support.h\"\n") + + fp.write("\n") + fp.write("static int output(bool screen, const char *format, ...) PRINTF_ATTRIBUTE(2,3);\n") + fp.write("void build_options(bool screen);\n") + fp.write("\n") + fp.write("\n") + fp.write("/****************************************************************************\n") + fp.write("helper function for build_options\n") + fp.write("****************************************************************************/\n") + fp.write("static int output(bool screen, const char *format, ...)\n") + fp.write("{\n") + fp.write(" char *ptr = NULL;\n") + fp.write(" int ret = 0;\n") + fp.write(" va_list ap;\n") + fp.write(" \n") + fp.write(" va_start(ap, format);\n") + fp.write(" ret = vasprintf(&ptr,format,ap);\n") + fp.write(" va_end(ap);\n") + fp.write("\n") + fp.write(" if (screen) {\n") + fp.write(" d_printf(\"%s\", ptr ? ptr : \"\");\n") + fp.write(" } else {\n") + fp.write(" DEBUG(4,(\"%s\", ptr ? ptr : \"\"));\n") + fp.write(" }\n") + fp.write(" \n") + fp.write(" SAFE_FREE(ptr);\n") + fp.write(" return ret;\n") + fp.write("}\n") + fp.write("\n") + fp.write("/****************************************************************************\n") + fp.write("options set at build time for the samba suite\n") + fp.write("****************************************************************************/\n") + fp.write("void build_options(bool screen)\n") + fp.write("{\n") + fp.write(" if ((DEBUGLEVEL < 4) && (!screen)) {\n") + fp.write(" return;\n") + fp.write(" }\n") + fp.write("\n") + fp.write("\n") + fp.write(" /* Output various paths to files and directories */\n") + fp.write(" output(screen,\"\\nPaths:\\n\");\n") + fp.write(" output(screen,\" SBINDIR: %s\\n\", get_dyn_SBINDIR());\n") + fp.write(" output(screen,\" BINDIR: %s\\n\", get_dyn_BINDIR());\n") + fp.write(" output(screen,\" CONFIGFILE: %s\\n\", get_dyn_CONFIGFILE());\n") + fp.write(" output(screen,\" LOGFILEBASE: %s\\n\", get_dyn_LOGFILEBASE());\n") + fp.write(" output(screen,\" LMHOSTSFILE: %s\\n\",get_dyn_LMHOSTSFILE());\n") + fp.write(" output(screen,\" LIBDIR: %s\\n\",get_dyn_LIBDIR());\n") + fp.write(" output(screen,\" MODULESDIR: %s\\n\",get_dyn_MODULESDIR());\n") + fp.write(" output(screen,\" SHLIBEXT: %s\\n\",get_dyn_SHLIBEXT());\n") + fp.write(" output(screen,\" LOCKDIR: %s\\n\",get_dyn_LOCKDIR());\n") + fp.write(" output(screen,\" STATEDIR: %s\\n\",get_dyn_STATEDIR());\n") + fp.write(" output(screen,\" CACHEDIR: %s\\n\",get_dyn_CACHEDIR());\n") + fp.write(" output(screen,\" PIDDIR: %s\\n\", get_dyn_PIDDIR());\n") + fp.write(" output(screen,\" SMB_PASSWD_FILE: %s\\n\",get_dyn_SMB_PASSWD_FILE());\n") + fp.write(" output(screen,\" PRIVATE_DIR: %s\\n\",get_dyn_PRIVATE_DIR());\n") + fp.write(" output(screen,\" BINDDNS_DIR: %s\\n\",get_dyn_BINDDNS_DIR());\n") + fp.write("\n") + +def write_build_options_footer(fp): + fp.write(" /* Output the sizes of the various cluster features */\n") + fp.write(" output(screen, \"\\n%s\", cluster_support_features());\n") + fp.write("\n") + fp.write(" /* Output the sizes of the various types */\n") + fp.write(" output(screen, \"\\nType sizes:\\n\");\n") + fp.write(" output(screen, \" sizeof(char): %lu\\n\",(unsigned long)sizeof(char));\n") + fp.write(" output(screen, \" sizeof(int): %lu\\n\",(unsigned long)sizeof(int));\n") + fp.write(" output(screen, \" sizeof(long): %lu\\n\",(unsigned long)sizeof(long));\n") + fp.write(" output(screen, \" sizeof(long long): %lu\\n\",(unsigned long)sizeof(long long));\n") + fp.write(" output(screen, \" sizeof(uint8_t): %lu\\n\",(unsigned long)sizeof(uint8_t));\n") + fp.write(" output(screen, \" sizeof(uint16_t): %lu\\n\",(unsigned long)sizeof(uint16_t));\n") + fp.write(" output(screen, \" sizeof(uint32_t): %lu\\n\",(unsigned long)sizeof(uint32_t));\n") + fp.write(" output(screen, \" sizeof(short): %lu\\n\",(unsigned long)sizeof(short));\n") + fp.write(" output(screen, \" sizeof(void*): %lu\\n\",(unsigned long)sizeof(void*));\n") + fp.write(" output(screen, \" sizeof(size_t): %lu\\n\",(unsigned long)sizeof(size_t));\n") + fp.write(" output(screen, \" sizeof(off_t): %lu\\n\",(unsigned long)sizeof(off_t));\n") + fp.write(" output(screen, \" sizeof(ino_t): %lu\\n\",(unsigned long)sizeof(ino_t));\n") + fp.write(" output(screen, \" sizeof(dev_t): %lu\\n\",(unsigned long)sizeof(dev_t));\n") + fp.write("\n") + fp.write(" output(screen, \"\\nBuiltin modules:\\n\");\n") + fp.write(" output(screen, \" %s\\n\", STRING_STATIC_MODULES);\n") + fp.write("}\n") + +def write_build_options_section(fp, keys, section): + fp.write("\n\t/* Show %s */\n" % section) + fp.write(" output(screen, \"\\n%s:\\n\");\n\n" % section) + + for k in sorted(keys): + fp.write("#ifdef %s\n" % k) + fp.write(" output(screen, \" %s\\n\");\n" % k) + fp.write("#endif\n") + fp.write("\n") + +def write_build_options(task): + tbl = task.env + keys_option_with = [] + keys_option_utmp = [] + keys_option_have = [] + keys_header_sys = [] + keys_header_other = [] + keys_misc = [] + if sys.hexversion>0x300000f: + trans_table = bytes.maketrans(b'.-()', b'____') + else: + import string + trans_table = string.maketrans('.-()', '____') + + for key in tbl: + if key.startswith("HAVE_UT_UT_") or key.find("UTMP") >= 0: + keys_option_utmp.append(key) + elif key.startswith("WITH_"): + keys_option_with.append(key) + elif key.startswith("HAVE_SYS_"): + keys_header_sys.append(key) + elif key.startswith("HAVE_"): + if key.endswith("_H"): + keys_header_other.append(key) + else: + keys_option_have.append(key) + elif key.startswith("static_init_"): + l = key.split("(") + keys_misc.append(l[0]) + else: + keys_misc.append(key.translate(trans_table)) + + tgt = task.outputs[0].bldpath(task.env) + f = open(tgt, 'w') + write_build_options_header(f) + write_build_options_section(f, keys_header_sys, "System Headers") + write_build_options_section(f, keys_header_other, "Headers") + write_build_options_section(f, keys_option_utmp, "UTMP Options") + write_build_options_section(f, keys_option_have, "HAVE_* Defines") + write_build_options_section(f, keys_option_with, "--with Options") + write_build_options_section(f, keys_misc, "Build Options") + write_build_options_footer(f) + f.close() + return 0 + + +def SAMBA_BLDOPTIONS(bld, target): + '''generate the bld_options.c for Samba''' + t = bld.SAMBA_GENERATOR(target, + rule=write_build_options, + dep_vars=['defines'], + target=target) +Build.BuildContext.SAMBA_BLDOPTIONS = SAMBA_BLDOPTIONS diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_perl.py b/ldb-2.0.8/buildtools/wafsamba/samba_perl.py new file mode 100644 index 0000000..e019acb --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/samba_perl.py @@ -0,0 +1,59 @@ +from waflib import Utils +from waflib.Configure import conf +from samba_utils import get_string +done = {} + +@conf +def SAMBA_CHECK_PERL(conf, mandatory=True, version=(5,0,0)): + if "done" in done: + return + done["done"] = True + conf.find_program('perl', var='PERL', mandatory=mandatory) + conf.load('perl') + path_perl = conf.find_program('perl') + conf.env.PERL_SPECIFIED = (conf.env.PERL != path_perl) + conf.check_perl_version(version) + + def read_perl_config_var(cmd): + output = Utils.cmd_output([conf.env.get_flat('PERL'), '-MConfig', '-e', cmd]) + if not isinstance(output, str): + output = get_string(output) + return Utils.to_list(output) + + def check_perl_config_var(var): + conf.start_msg("Checking for perl $Config{%s}:" % var) + try: + v = read_perl_config_var('print $Config{%s}' % var)[0] + conf.end_msg("'%s'" % (v), 'GREEN') + return v + except IndexError: + conf.end_msg(False, 'YELLOW') + pass + return None + + vendor_prefix = check_perl_config_var('vendorprefix') + + perl_arch_install_dir = None + if vendor_prefix == conf.env.PREFIX: + perl_arch_install_dir = check_perl_config_var('vendorarch'); + if perl_arch_install_dir is None: + perl_arch_install_dir = "${LIBDIR}/perl5"; + conf.start_msg("PERL_ARCH_INSTALL_DIR: ") + conf.end_msg("'%s'" % (perl_arch_install_dir), 'GREEN') + conf.env.PERL_ARCH_INSTALL_DIR = perl_arch_install_dir + + perl_lib_install_dir = None + if vendor_prefix == conf.env.PREFIX: + perl_lib_install_dir = check_perl_config_var('vendorlib'); + if perl_lib_install_dir is None: + perl_lib_install_dir = "${DATADIR}/perl5"; + conf.start_msg("PERL_LIB_INSTALL_DIR: ") + conf.end_msg("'%s'" % (perl_lib_install_dir), 'GREEN') + conf.env.PERL_LIB_INSTALL_DIR = perl_lib_install_dir + + perl_inc = read_perl_config_var('print "@INC"') + if '.' in perl_inc: + perl_inc.remove('.') + conf.start_msg("PERL_INC: ") + conf.end_msg("%s" % (perl_inc), 'GREEN') + conf.env.PERL_INC = perl_inc diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_pidl.py b/ldb-2.0.8/buildtools/wafsamba/samba_pidl.py new file mode 100644 index 0000000..3fecfa9 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/samba_pidl.py @@ -0,0 +1,150 @@ +# waf build tool for building IDL files with pidl + +import os +from waflib import Build, Utils +from waflib.TaskGen import feature, before +from samba_utils import SET_TARGET_TYPE, TO_LIST, LOCAL_CACHE + +def SAMBA_PIDL(bld, pname, source, + options='', + output_dir='.', + generate_tables=True): + '''Build a IDL file using pidl. + This will produce up to 13 output files depending on the options used''' + + bname = source[0:-4]; # strip off the .idl suffix + bname = os.path.basename(bname) + name = "%s_%s" % (pname, bname.upper()) + + if not SET_TARGET_TYPE(bld, name, 'PIDL'): + return + + bld.SET_BUILD_GROUP('build_source') + + # the output files depend on the options used. Use this dictionary + # to map between the options and the resulting file names + options_map = { '--header' : '%s.h', + '--ndr-parser' : 'ndr_%s.c ndr_%s.h', + '--samba3-ndr-server' : 'srv_%s.c srv_%s.h', + '--samba3-ndr-client' : 'cli_%s.c cli_%s.h', + '--server' : 'ndr_%s_s.c', + '--client' : 'ndr_%s_c.c ndr_%s_c.h', + '--python' : 'py_%s.c', + '--tdr-parser' : 'tdr_%s.c tdr_%s.h', + '--dcom-proxy' : '%s_p.c', + '--com-header' : 'com_%s.h' + } + + table_header_idx = None + out_files = [] + options_list = TO_LIST(options) + + for o in options_list: + if o in options_map: + ofiles = TO_LIST(options_map[o]) + for f in ofiles: + out_files.append(os.path.join(output_dir, f % bname)) + if f == 'ndr_%s.h': + # remember this one for the tables generation + table_header_idx = len(out_files) - 1 + + # depend on the full pidl sources + source = TO_LIST(source) + try: + pidl_src_nodes = bld.pidl_files_cache + except AttributeError: + bld.pidl_files_cache = bld.srcnode.ant_glob('pidl/lib/Parse/**/*.pm', flat=False) + bld.pidl_files_cache.extend(bld.srcnode.ant_glob('pidl', flat=False)) + pidl_src_nodes = bld.pidl_files_cache + + # the cd .. is needed because pidl currently is sensitive to the directory it is run in + cpp = "" + cc = "" + if bld.CONFIG_SET("CPP") and bld.CONFIG_GET("CPP") != "": + if isinstance(bld.CONFIG_GET("CPP"), list): + cpp = 'CPP="%s"' % " ".join(bld.CONFIG_GET("CPP")) + else: + cpp = 'CPP="%s"' % bld.CONFIG_GET("CPP") + + if cpp == "CPP=xlc_r": + cpp = "" + + + if bld.CONFIG_SET("CC"): + if isinstance(bld.CONFIG_GET("CC"), list): + cc = 'CC="%s"' % " ".join(bld.CONFIG_GET("CC")) + else: + cc = 'CC="%s"' % bld.CONFIG_GET("CC") + + t = bld(rule='cd ${PIDL_LAUNCH_DIR} && %s %s ${PERL} ${PIDL} --quiet ${OPTIONS} --outputdir ${OUTPUTDIR} -- "${IDLSRC}"' % (cpp, cc), + ext_out = '.c', + before = 'c', + update_outputs = True, + shell = True, + source = source, + target = out_files, + name = name, + samba_type = 'PIDL') + + + t.env.PIDL_LAUNCH_DIR = bld.srcnode.path_from(bld.bldnode) + pnode = bld.srcnode.find_resource('pidl/pidl') + t.env.PIDL = pnode.path_from(bld.srcnode) + t.env.OPTIONS = TO_LIST(options) + snode = t.path.find_resource(source[0]) + t.env.IDLSRC = snode.path_from(bld.srcnode) + t.env.OUTPUTDIR = bld.bldnode.path_from(bld.srcnode) + '/' + bld.path.find_dir(output_dir).path_from(bld.srcnode) + + bld.add_manual_dependency(snode, pidl_src_nodes) + + if generate_tables and table_header_idx is not None: + pidl_headers = LOCAL_CACHE(bld, 'PIDL_HEADERS') + pidl_headers[name] = [bld.path.find_or_declare(out_files[table_header_idx])] + + t.more_includes = '#' + bld.path.path_from(bld.srcnode) +Build.BuildContext.SAMBA_PIDL = SAMBA_PIDL + + +def SAMBA_PIDL_LIST(bld, name, source, + options='', + output_dir='.', + generate_tables=True): + '''A wrapper for building a set of IDL files''' + for p in TO_LIST(source): + bld.SAMBA_PIDL(name, p, options=options, output_dir=output_dir, generate_tables=generate_tables) +Build.BuildContext.SAMBA_PIDL_LIST = SAMBA_PIDL_LIST + + +################################################################# +# the rule for generating the NDR tables +@feature('collect') +@before('exec_rule') +def collect(self): + pidl_headers = LOCAL_CACHE(self.bld, 'PIDL_HEADERS') + # The first source is tables.pl itself + self.source = Utils.to_list(self.source) + for (name, hd) in pidl_headers.items(): + y = self.bld.get_tgen_by_name(name) + self.bld.ASSERT(y is not None, 'Failed to find PIDL header %s' % name) + y.post() + for node in hd: + self.bld.ASSERT(node is not None, 'Got None as build node generating PIDL table for %s' % name) + self.source.append(node) + + +def SAMBA_PIDL_TABLES(bld, name, target): + '''generate the pidl NDR tables file''' + bld.SET_BUILD_GROUP('main') + t = bld( + features = 'collect', + rule = '${PERL} ${SRC} > ${TGT}', + ext_out = '.c', + before = 'c', + update_outputs = True, + shell = True, + source = '../../librpc/tables.pl', + target = target, + name = name) + t.env.LIBRPC = os.path.join(bld.srcnode.abspath(), 'librpc') +Build.BuildContext.SAMBA_PIDL_TABLES = SAMBA_PIDL_TABLES + diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_python.py b/ldb-2.0.8/buildtools/wafsamba/samba_python.py new file mode 100644 index 0000000..4476d33 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/samba_python.py @@ -0,0 +1,159 @@ +# waf build tool for building IDL files with pidl + +import os, sys +from waflib import Build, Logs, Utils, Configure, Errors +from waflib.Configure import conf + +@conf +def SAMBA_CHECK_PYTHON(conf, version=(3,4,0)): + + if conf.env.disable_python: + version=(2,6,0) + + # enable tool to build python extensions + if conf.env.HAVE_PYTHON_H: + conf.check_python_version(version) + return + + interpreters = [] + + conf.find_program('python3', var='PYTHON', + mandatory=not conf.env.disable_python) + conf.load('python') + path_python = conf.find_program('python3') + + conf.env.PYTHON_SPECIFIED = (conf.env.PYTHON != path_python) + conf.check_python_version(version) + + interpreters.append(conf.env['PYTHON']) + conf.env.python_interpreters = interpreters + + +@conf +def SAMBA_CHECK_PYTHON_HEADERS(conf): + if conf.env.disable_python: + + conf.msg("python headers", "Check disabled due to --disable-python") + # we don't want PYTHONDIR in config.h, as otherwise changing + # --prefix causes a complete rebuild + conf.env.DEFINES = [x for x in conf.env.DEFINES + if not x.startswith('PYTHONDIR=') + and not x.startswith('PYTHONARCHDIR=')] + + return + + if conf.env["python_headers_checked"] == []: + _check_python_headers(conf) + conf.env["python_headers_checked"] = "yes" + + else: + conf.msg("python headers", "using cache") + + # we don't want PYTHONDIR in config.h, as otherwise changing + # --prefix causes a complete rebuild + conf.env.DEFINES = [x for x in conf.env.DEFINES + if not x.startswith('PYTHONDIR=') + and not x.startswith('PYTHONARCHDIR=')] + +def _check_python_headers(conf): + conf.check_python_headers() + + if conf.env['PYTHON_VERSION'] > '3': + abi_pattern = os.path.splitext(conf.env['pyext_PATTERN'])[0] + conf.env['PYTHON_SO_ABI_FLAG'] = abi_pattern % '' + else: + conf.env['PYTHON_SO_ABI_FLAG'] = '' + conf.env['PYTHON_LIBNAME_SO_ABI_FLAG'] = ( + conf.env['PYTHON_SO_ABI_FLAG'].replace('_', '-')) + + for lib in conf.env['LINKFLAGS_PYEMBED']: + if lib.startswith('-L'): + conf.env.append_unique('LIBPATH_PYEMBED', lib[2:]) # strip '-L' + conf.env['LINKFLAGS_PYEMBED'].remove(lib) + + # same as in waf 1.5, keep only '-fno-strict-aliasing' + # and ignore defines such as NDEBUG _FORTIFY_SOURCE=2 + conf.env.DEFINES_PYEXT = [] + conf.env.CFLAGS_PYEXT = ['-fno-strict-aliasing'] + + return + +def PYTHON_BUILD_IS_ENABLED(self): + return self.CONFIG_SET('HAVE_PYTHON_H') + +Build.BuildContext.PYTHON_BUILD_IS_ENABLED = PYTHON_BUILD_IS_ENABLED + + +def SAMBA_PYTHON(bld, name, + source='', + deps='', + public_deps='', + realname=None, + cflags='', + cflags_end=None, + includes='', + init_function_sentinel=None, + local_include=True, + vars=None, + install=True, + enabled=True): + '''build a python extension for Samba''' + + # force-disable when we can't build python modules, so + # every single call doesn't need to pass this in. + if not bld.PYTHON_BUILD_IS_ENABLED(): + enabled = False + + # when we support static python modules we'll need to gather + # the list from all the SAMBA_PYTHON() targets + if init_function_sentinel is not None: + cflags += ' -DSTATIC_LIBPYTHON_MODULES=%s' % init_function_sentinel + + # From https://docs.python.org/2/c-api/arg.html: + # Starting with Python 2.5 the type of the length argument to + # PyArg_ParseTuple(), PyArg_ParseTupleAndKeywords() and PyArg_Parse() + # can be controlled by defining the macro PY_SSIZE_T_CLEAN before + # including Python.h. If the macro is defined, length is a Py_ssize_t + # rather than an int. + + # Because if often included before includes.h/config.h + # This must be in the -D compiler options + cflags += ' -DPY_SSIZE_T_CLEAN=1' + + source = bld.EXPAND_VARIABLES(source, vars=vars) + + if realname is not None: + link_name = 'python/%s' % realname + else: + link_name = None + + bld.SAMBA_LIBRARY(name, + source=source, + deps=deps, + public_deps=public_deps, + includes=includes, + cflags=cflags, + cflags_end=cflags_end, + local_include=local_include, + vars=vars, + realname=realname, + link_name=link_name, + pyext=True, + target_type='PYTHON', + install_path='${PYTHONARCHDIR}', + allow_undefined_symbols=True, + install=install, + enabled=enabled) + +Build.BuildContext.SAMBA_PYTHON = SAMBA_PYTHON + + +def pyembed_libname(bld, name): + if bld.env['PYTHON_SO_ABI_FLAG']: + return name + bld.env['PYTHON_SO_ABI_FLAG'] + else: + return name + +Build.BuildContext.pyembed_libname = pyembed_libname + + diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_third_party.py b/ldb-2.0.8/buildtools/wafsamba/samba_third_party.py new file mode 100644 index 0000000..f7410ec --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/samba_third_party.py @@ -0,0 +1,66 @@ +# functions to support third party libraries + +import os +from waflib import Utils, Build, Context +from waflib.Configure import conf + +@conf +def CHECK_FOR_THIRD_PARTY(conf): + return os.path.exists(os.path.join(Context.g_module.top, 'third_party')) + +Build.BuildContext.CHECK_FOR_THIRD_PARTY = CHECK_FOR_THIRD_PARTY + +@conf +def CHECK_ZLIB(conf): + version_check=''' + #if (ZLIB_VERNUM >= 0x1230) + #else + #error "ZLIB_VERNUM < 0x1230" + #endif + z_stream *z; + inflateInit2(z, -15); + ''' + return conf.CHECK_BUNDLED_SYSTEM('z', minversion='1.2.3', pkg='zlib', + checkfunctions='zlibVersion', + headers='zlib.h', + checkcode=version_check, + implied_deps='replace') + +Build.BuildContext.CHECK_ZLIB = CHECK_ZLIB + +@conf +def CHECK_POPT(conf): + return conf.CHECK_BUNDLED_SYSTEM('popt', checkfunctions='poptGetContext', headers='popt.h') + +Build.BuildContext.CHECK_POPT = CHECK_POPT + +@conf +def CHECK_CMOCKA(conf): + return conf.CHECK_BUNDLED_SYSTEM_PKG('cmocka', minversion='1.1.3') + +Build.BuildContext.CHECK_CMOCKA = CHECK_CMOCKA + +@conf +def CHECK_SOCKET_WRAPPER(conf): + return conf.CHECK_BUNDLED_SYSTEM_PKG('socket_wrapper', minversion='1.2.3') +Build.BuildContext.CHECK_SOCKET_WRAPPER = CHECK_SOCKET_WRAPPER + +@conf +def CHECK_NSS_WRAPPER(conf): + return conf.CHECK_BUNDLED_SYSTEM_PKG('nss_wrapper', minversion='1.1.6') +Build.BuildContext.CHECK_NSS_WRAPPER = CHECK_NSS_WRAPPER + +@conf +def CHECK_RESOLV_WRAPPER(conf): + return conf.CHECK_BUNDLED_SYSTEM_PKG('resolv_wrapper', minversion='1.1.4') +Build.BuildContext.CHECK_RESOLV_WRAPPER = CHECK_RESOLV_WRAPPER + +@conf +def CHECK_UID_WRAPPER(conf): + return conf.CHECK_BUNDLED_SYSTEM_PKG('uid_wrapper', minversion='1.2.4') +Build.BuildContext.CHECK_UID_WRAPPER = CHECK_UID_WRAPPER + +@conf +def CHECK_PAM_WRAPPER(conf): + return conf.CHECK_BUNDLED_SYSTEM_PKG('pam_wrapper', minversion='1.0.7') +Build.BuildContext.CHECK_PAM_WRAPPER = CHECK_PAM_WRAPPER diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_utils.py b/ldb-2.0.8/buildtools/wafsamba/samba_utils.py new file mode 100644 index 0000000..ad97de1 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/samba_utils.py @@ -0,0 +1,763 @@ +# a waf tool to add autoconf-like macros to the configure section +# and for SAMBA_ macros for building libraries, binaries etc + +import errno +import os, sys, re, fnmatch, shlex, inspect +from optparse import SUPPRESS_HELP +from waflib import Build, Options, Utils, Task, Logs, Configure, Errors, Context +from waflib import Scripting +from waflib.TaskGen import feature, before, after +from waflib.Configure import ConfigurationContext +from waflib.Logs import debug +from waflib import ConfigSet +from waflib.Build import CACHE_SUFFIX + +# TODO: make this a --option +LIB_PATH="shared" + + +PY3 = sys.version_info[0] == 3 + +if PY3: + + # helper function to get a string from a variable that maybe 'str' or + # 'bytes' if 'bytes' then it is decoded using 'utf8'. If 'str' is passed + # it is returned unchanged + # Using this function is PY2/PY3 code should ensure in most cases + # the PY2 code runs unchanged in PY2 whereas the code in PY3 possibly + # decodes the variable (see PY2 implementation of this function below) + def get_string(bytesorstring): + tmp = bytesorstring + if isinstance(bytesorstring, bytes): + tmp = bytesorstring.decode('utf8') + elif not isinstance(bytesorstring, str): + raise ValueError('Expected byte of string for %s:%s' % (type(bytesorstring), bytesorstring)) + return tmp + +else: + + # Helper function to return string. + # if 'str' or 'unicode' passed in they are returned unchanged + # otherwise an exception is generated + # Using this function is PY2/PY3 code should ensure in most cases + # the PY2 code runs unchanged in PY2 whereas the code in PY3 possibly + # decodes the variable (see PY3 implementation of this function above) + def get_string(bytesorstring): + tmp = bytesorstring + if not(isinstance(bytesorstring, str) or isinstance(bytesorstring, unicode)): + raise ValueError('Expected str or unicode for %s:%s' % (type(bytesorstring), bytesorstring)) + return tmp + +# sigh, python octal constants are a mess +MODE_644 = int('644', 8) +MODE_744 = int('744', 8) +MODE_755 = int('755', 8) +MODE_777 = int('777', 8) + +def conf(f): + # override in order to propagate the argument "mandatory" + def fun(*k, **kw): + mandatory = True + if 'mandatory' in kw: + mandatory = kw['mandatory'] + del kw['mandatory'] + + try: + return f(*k, **kw) + except Errors.ConfigurationError: + if mandatory: + raise + + fun.__name__ = f.__name__ + if 'mandatory' in inspect.getsource(f): + fun = f + + setattr(Configure.ConfigurationContext, f.__name__, fun) + setattr(Build.BuildContext, f.__name__, fun) + return f +Configure.conf = conf +Configure.conftest = conf + +@conf +def SET_TARGET_TYPE(ctx, target, value): + '''set the target type of a target''' + cache = LOCAL_CACHE(ctx, 'TARGET_TYPE') + if target in cache and cache[target] != 'EMPTY': + Logs.error("ERROR: Target '%s' in directory %s re-defined as %s - was %s" % (target, ctx.path.abspath(), value, cache[target])) + sys.exit(1) + LOCAL_CACHE_SET(ctx, 'TARGET_TYPE', target, value) + debug("task_gen: Target '%s' created of type '%s' in %s" % (target, value, ctx.path.abspath())) + return True + + +def GET_TARGET_TYPE(ctx, target): + '''get target type from cache''' + cache = LOCAL_CACHE(ctx, 'TARGET_TYPE') + if not target in cache: + return None + return cache[target] + + +def ADD_LD_LIBRARY_PATH(path): + '''add something to LD_LIBRARY_PATH''' + if 'LD_LIBRARY_PATH' in os.environ: + oldpath = os.environ['LD_LIBRARY_PATH'] + else: + oldpath = '' + newpath = oldpath.split(':') + if not path in newpath: + newpath.append(path) + os.environ['LD_LIBRARY_PATH'] = ':'.join(newpath) + + +def needs_private_lib(bld, target): + '''return True if a target links to a private library''' + for lib in getattr(target, "final_libs", []): + t = bld.get_tgen_by_name(lib) + if t and getattr(t, 'private_library', False): + return True + return False + + +def install_rpath(target): + '''the rpath value for installation''' + bld = target.bld + bld.env['RPATH'] = [] + ret = set() + if bld.env.RPATH_ON_INSTALL: + ret.add(bld.EXPAND_VARIABLES(bld.env.LIBDIR)) + if bld.env.RPATH_ON_INSTALL_PRIVATE and needs_private_lib(bld, target): + ret.add(bld.EXPAND_VARIABLES(bld.env.PRIVATELIBDIR)) + return list(ret) + + +def build_rpath(bld): + '''the rpath value for build''' + rpaths = [os.path.normpath('%s/%s' % (bld.env.BUILD_DIRECTORY, d)) for d in ("shared", "shared/private")] + bld.env['RPATH'] = [] + if bld.env.RPATH_ON_BUILD: + return rpaths + for rpath in rpaths: + ADD_LD_LIBRARY_PATH(rpath) + return [] + + +@conf +def LOCAL_CACHE(ctx, name): + '''return a named build cache dictionary, used to store + state inside other functions''' + if name in ctx.env: + return ctx.env[name] + ctx.env[name] = {} + return ctx.env[name] + + +@conf +def LOCAL_CACHE_SET(ctx, cachename, key, value): + '''set a value in a local cache''' + cache = LOCAL_CACHE(ctx, cachename) + cache[key] = value + + +@conf +def ASSERT(ctx, expression, msg): + '''a build assert call''' + if not expression: + raise Errors.WafError("ERROR: %s\n" % msg) +Build.BuildContext.ASSERT = ASSERT + + +def SUBDIR(bld, subdir, list): + '''create a list of files by pre-pending each with a subdir name''' + ret = '' + for l in TO_LIST(list): + ret = ret + os.path.normpath(os.path.join(subdir, l)) + ' ' + return ret +Build.BuildContext.SUBDIR = SUBDIR + + +def dict_concat(d1, d2): + '''concatenate two dictionaries d1 += d2''' + for t in d2: + if t not in d1: + d1[t] = d2[t] + +def ADD_COMMAND(opt, name, function): + '''add a new top level command to waf''' + Context.g_module.__dict__[name] = function + opt.name = function +Options.OptionsContext.ADD_COMMAND = ADD_COMMAND + + +@feature('c', 'cc', 'cshlib', 'cprogram') +@before('apply_core','exec_rule') +def process_depends_on(self): + '''The new depends_on attribute for build rules + allow us to specify a dependency on output from + a source generation rule''' + if getattr(self , 'depends_on', None): + lst = self.to_list(self.depends_on) + for x in lst: + y = self.bld.get_tgen_by_name(x) + self.bld.ASSERT(y is not None, "Failed to find dependency %s of %s" % (x, self.name)) + y.post() + if getattr(y, 'more_includes', None): + self.includes += " " + y.more_includes + + +os_path_relpath = getattr(os.path, 'relpath', None) +if os_path_relpath is None: + # Python < 2.6 does not have os.path.relpath, provide a replacement + # (imported from Python2.6.5~rc2) + def os_path_relpath(path, start): + """Return a relative version of a path""" + start_list = os.path.abspath(start).split("/") + path_list = os.path.abspath(path).split("/") + + # Work out how much of the filepath is shared by start and path. + i = len(os.path.commonprefix([start_list, path_list])) + + rel_list = ['..'] * (len(start_list)-i) + path_list[i:] + if not rel_list: + return start + return os.path.join(*rel_list) + + +def unique_list(seq): + '''return a uniquified list in the same order as the existing list''' + seen = {} + result = [] + for item in seq: + if item in seen: continue + seen[item] = True + result.append(item) + return result + + +def TO_LIST(str, delimiter=None): + '''Split a list, preserving quoted strings and existing lists''' + if str is None: + return [] + if isinstance(str, list): + # we need to return a new independent list... + return list(str) + if len(str) == 0: + return [] + lst = str.split(delimiter) + # the string may have had quotes in it, now we + # check if we did have quotes, and use the slower shlex + # if we need to + for e in lst: + if e[0] == '"': + return shlex.split(str) + return lst + + +def subst_vars_error(string, env): + '''substitute vars, throw an error if a variable is not defined''' + lst = re.split('(\$\{\w+\})', string) + out = [] + for v in lst: + if re.match('\$\{\w+\}', v): + vname = v[2:-1] + if not vname in env: + raise KeyError("Failed to find variable %s in %s in env %s <%s>" % (vname, string, env.__class__, str(env))) + v = env[vname] + if isinstance(v, list): + v = ' '.join(v) + out.append(v) + return ''.join(out) + + +@conf +def SUBST_ENV_VAR(ctx, varname): + '''Substitute an environment variable for any embedded variables''' + return subst_vars_error(ctx.env[varname], ctx.env) +Build.BuildContext.SUBST_ENV_VAR = SUBST_ENV_VAR + + +def recursive_dirlist(dir, relbase, pattern=None): + '''recursive directory list''' + ret = [] + for f in os.listdir(dir): + f2 = dir + '/' + f + if os.path.isdir(f2): + ret.extend(recursive_dirlist(f2, relbase)) + else: + if pattern and not fnmatch.fnmatch(f, pattern): + continue + ret.append(os_path_relpath(f2, relbase)) + return ret + + +def symlink(src, dst, force=True): + """Can create symlink by force""" + try: + os.symlink(src, dst) + except OSError as exc: + if exc.errno == errno.EEXIST and force: + os.remove(dst) + os.symlink(src, dst) + else: + raise + + +def mkdir_p(dir): + '''like mkdir -p''' + if not dir: + return + if dir.endswith("/"): + mkdir_p(dir[:-1]) + return + if os.path.isdir(dir): + return + mkdir_p(os.path.dirname(dir)) + os.mkdir(dir) + + +def SUBST_VARS_RECURSIVE(string, env): + '''recursively expand variables''' + if string is None: + return string + limit=100 + while (string.find('${') != -1 and limit > 0): + string = subst_vars_error(string, env) + limit -= 1 + return string + + +@conf +def EXPAND_VARIABLES(ctx, varstr, vars=None): + '''expand variables from a user supplied dictionary + + This is most useful when you pass vars=locals() to expand + all your local variables in strings + ''' + + if isinstance(varstr, list): + ret = [] + for s in varstr: + ret.append(EXPAND_VARIABLES(ctx, s, vars=vars)) + return ret + + if not isinstance(varstr, str): + return varstr + + env = ConfigSet.ConfigSet() + ret = varstr + # substitute on user supplied dict if avaiilable + if vars is not None: + for v in vars.keys(): + env[v] = vars[v] + ret = SUBST_VARS_RECURSIVE(ret, env) + + # if anything left, subst on the environment as well + if ret.find('${') != -1: + ret = SUBST_VARS_RECURSIVE(ret, ctx.env) + # make sure there is nothing left. Also check for the common + # typo of $( instead of ${ + if ret.find('${') != -1 or ret.find('$(') != -1: + Logs.error('Failed to substitute all variables in varstr=%s' % ret) + sys.exit(1) + return ret +Build.BuildContext.EXPAND_VARIABLES = EXPAND_VARIABLES + + +def RUN_COMMAND(cmd, + env=None, + shell=False): + '''run a external command, return exit code or signal''' + if env: + cmd = SUBST_VARS_RECURSIVE(cmd, env) + + status = os.system(cmd) + if os.WIFEXITED(status): + return os.WEXITSTATUS(status) + if os.WIFSIGNALED(status): + return - os.WTERMSIG(status) + Logs.error("Unknown exit reason %d for command: %s" % (status, cmd)) + return -1 + + +def RUN_PYTHON_TESTS(testfiles, pythonpath=None, extra_env=None): + env = LOAD_ENVIRONMENT() + if pythonpath is None: + pythonpath = os.path.join(Context.g_module.out, 'python') + result = 0 + for interp in env.python_interpreters: + if not isinstance(interp, str): + interp = ' '.join(interp) + for testfile in testfiles: + cmd = "PYTHONPATH=%s %s %s" % (pythonpath, interp, testfile) + if extra_env: + for key, value in extra_env.items(): + cmd = "%s=%s %s" % (key, value, cmd) + print('Running Python test with %s: %s' % (interp, testfile)) + ret = RUN_COMMAND(cmd) + if ret: + print('Python test failed: %s' % cmd) + result = ret + return result + + +# make sure we have md5. some systems don't have it +try: + from hashlib import md5 + # Even if hashlib.md5 exists, it may be unusable. + # Try to use MD5 function. In FIPS mode this will cause an exception + # and we'll get to the replacement code + foo = md5(b'abcd') +except: + try: + import md5 + # repeat the same check here, mere success of import is not enough. + # Try to use MD5 function. In FIPS mode this will cause an exception + foo = md5.md5(b'abcd') + except: + Context.SIG_NIL = hash('abcd') + class replace_md5(object): + def __init__(self): + self.val = None + def update(self, val): + self.val = hash((self.val, val)) + def digest(self): + return str(self.val) + def hexdigest(self): + return self.digest().encode('hex') + def replace_h_file(filename): + f = open(filename, 'rb') + m = replace_md5() + while (filename): + filename = f.read(100000) + m.update(filename) + f.close() + return m.digest() + Utils.md5 = replace_md5 + Task.md5 = replace_md5 + Utils.h_file = replace_h_file + + +def LOAD_ENVIRONMENT(): + '''load the configuration environment, allowing access to env vars + from new commands''' + env = ConfigSet.ConfigSet() + try: + p = os.path.join(Context.g_module.out, 'c4che/default'+CACHE_SUFFIX) + env.load(p) + except (OSError, IOError): + pass + return env + + +def IS_NEWER(bld, file1, file2): + '''return True if file1 is newer than file2''' + curdir = bld.path.abspath() + t1 = os.stat(os.path.join(curdir, file1)).st_mtime + t2 = os.stat(os.path.join(curdir, file2)).st_mtime + return t1 > t2 +Build.BuildContext.IS_NEWER = IS_NEWER + + +@conf +def RECURSE(ctx, directory): + '''recurse into a directory, relative to the curdir or top level''' + try: + visited_dirs = ctx.visited_dirs + except AttributeError: + visited_dirs = ctx.visited_dirs = set() + d = os.path.join(ctx.path.abspath(), directory) + if os.path.exists(d): + abspath = os.path.abspath(d) + else: + abspath = os.path.abspath(os.path.join(Context.g_module.top, directory)) + ctxclass = ctx.__class__.__name__ + key = ctxclass + ':' + abspath + if key in visited_dirs: + # already done it + return + visited_dirs.add(key) + relpath = os_path_relpath(abspath, ctx.path.abspath()) + if ctxclass in ['tmp', 'OptionsContext', 'ConfigurationContext', 'BuildContext']: + return ctx.recurse(relpath) + if 'waflib.extras.compat15' in sys.modules: + return ctx.recurse(relpath) + Logs.error('Unknown RECURSE context class: {}'.format(ctxclass)) + raise +Options.OptionsContext.RECURSE = RECURSE +Build.BuildContext.RECURSE = RECURSE + + +def CHECK_MAKEFLAGS(options): + '''check for MAKEFLAGS environment variable in case we are being + called from a Makefile try to honor a few make command line flags''' + if not 'WAF_MAKE' in os.environ: + return + makeflags = os.environ.get('MAKEFLAGS') + if makeflags is None: + makeflags = "" + jobs_set = False + jobs = None + # we need to use shlex.split to cope with the escaping of spaces + # in makeflags + for opt in shlex.split(makeflags): + # options can come either as -x or as x + if opt[0:2] == 'V=': + options.verbose = Logs.verbose = int(opt[2:]) + if Logs.verbose > 0: + Logs.zones = ['runner'] + if Logs.verbose > 2: + Logs.zones = ['*'] + elif opt[0].isupper() and opt.find('=') != -1: + # this allows us to set waf options on the make command line + # for example, if you do "make FOO=blah", then we set the + # option 'FOO' in Options.options, to blah. If you look in wafsamba/wscript + # you will see that the command line accessible options have their dest= + # set to uppercase, to allow for passing of options from make in this way + # this is also how "make test TESTS=testpattern" works, and + # "make VERBOSE=1" as well as things like "make SYMBOLCHECK=1" + loc = opt.find('=') + setattr(options, opt[0:loc], opt[loc+1:]) + elif opt[0] != '-': + for v in opt: + if re.search(r'j[0-9]*$', v): + jobs_set = True + jobs = opt.strip('j') + elif v == 'k': + options.keep = True + elif re.search(r'-j[0-9]*$', opt): + jobs_set = True + jobs = opt.strip('-j') + elif opt == '-k': + options.keep = True + if not jobs_set: + # default to one job + options.jobs = 1 + elif jobs_set and jobs: + options.jobs = int(jobs) + +waflib_options_parse_cmd_args = Options.OptionsContext.parse_cmd_args +def wafsamba_options_parse_cmd_args(self, _args=None, cwd=None, allow_unknown=False): + (options, commands, envvars) = \ + waflib_options_parse_cmd_args(self, + _args=_args, + cwd=cwd, + allow_unknown=allow_unknown) + CHECK_MAKEFLAGS(options) + if options.jobs == 1: + # + # waflib.Runner.Parallel processes jobs inline if the possible number + # of jobs is just 1. But (at least in waf <= 2.0.12) it still calls + # create a waflib.Runner.Spawner() which creates a single + # waflib.Runner.Consumer() thread that tries to process jobs from the + # queue. + # + # This has strange effects, which are not noticed typically, + # but at least on AIX python has broken threading and fails + # in random ways. + # + # So we just add a dummy Spawner class. + class NoOpSpawner(object): + def __init__(self, master): + return + from waflib import Runner + Runner.Spawner = NoOpSpawner + return options, commands, envvars +Options.OptionsContext.parse_cmd_args = wafsamba_options_parse_cmd_args + +option_groups = {} + +def option_group(opt, name): + '''find or create an option group''' + global option_groups + if name in option_groups: + return option_groups[name] + gr = opt.add_option_group(name) + option_groups[name] = gr + return gr +Options.OptionsContext.option_group = option_group + + +def save_file(filename, contents, create_dir=False): + '''save data to a file''' + if create_dir: + mkdir_p(os.path.dirname(filename)) + try: + f = open(filename, 'w') + f.write(contents) + f.close() + except: + return False + return True + + +def load_file(filename): + '''return contents of a file''' + try: + f = open(filename, 'r') + r = f.read() + f.close() + except: + return None + return r + + +def reconfigure(ctx): + '''rerun configure if necessary''' + if not os.path.exists(os.environ.get('WAFLOCK', '.lock-wscript')): + raise Errors.WafError('configure has not been run') + import samba_wildcard + bld = samba_wildcard.fake_build_environment() + Configure.autoconfig = True + Scripting.check_configured(bld) + + +def map_shlib_extension(ctx, name, python=False): + '''map a filename with a shared library extension of .so to the real shlib name''' + if name is None: + return None + if name[-1:].isdigit(): + # some libraries have specified versions in the wscript rule + return name + (root1, ext1) = os.path.splitext(name) + if python: + return ctx.env.pyext_PATTERN % root1 + else: + (root2, ext2) = os.path.splitext(ctx.env.cshlib_PATTERN) + return root1+ext2 +Build.BuildContext.map_shlib_extension = map_shlib_extension + +def apply_pattern(filename, pattern): + '''apply a filename pattern to a filename that may have a directory component''' + dirname = os.path.dirname(filename) + if not dirname: + return pattern % filename + basename = os.path.basename(filename) + return os.path.join(dirname, pattern % basename) + +def make_libname(ctx, name, nolibprefix=False, version=None, python=False): + """make a library filename + Options: + nolibprefix: don't include the lib prefix + version : add a version number + python : if we should use python module name conventions""" + + if python: + libname = apply_pattern(name, ctx.env.pyext_PATTERN) + else: + libname = apply_pattern(name, ctx.env.cshlib_PATTERN) + if nolibprefix and libname[0:3] == 'lib': + libname = libname[3:] + if version: + if version[0] == '.': + version = version[1:] + (root, ext) = os.path.splitext(libname) + if ext == ".dylib": + # special case - version goes before the prefix + libname = "%s.%s%s" % (root, version, ext) + else: + libname = "%s%s.%s" % (root, ext, version) + return libname +Build.BuildContext.make_libname = make_libname + + +def get_tgt_list(bld): + '''return a list of build objects for samba''' + + targets = LOCAL_CACHE(bld, 'TARGET_TYPE') + + # build a list of task generators we are interested in + tgt_list = [] + for tgt in targets: + type = targets[tgt] + if not type in ['SUBSYSTEM', 'MODULE', 'BINARY', 'LIBRARY', 'ASN1', 'PYTHON']: + continue + t = bld.get_tgen_by_name(tgt) + if t is None: + Logs.error("Target %s of type %s has no task generator" % (tgt, type)) + sys.exit(1) + tgt_list.append(t) + return tgt_list + +from waflib.Context import WSCRIPT_FILE +def PROCESS_SEPARATE_RULE(self, rule): + ''' cause waf to process additional script based on `rule'. + You should have file named wscript__rule in the current directory + where stage is either 'configure' or 'build' + ''' + stage = '' + if isinstance(self, Configure.ConfigurationContext): + stage = 'configure' + elif isinstance(self, Build.BuildContext): + stage = 'build' + file_path = os.path.join(self.path.abspath(), WSCRIPT_FILE+'_'+stage+'_'+rule) + node = self.root.find_node(file_path) + if node: + try: + cache = self.recurse_cache + except AttributeError: + cache = self.recurse_cache = {} + if node not in cache: + cache[node] = True + self.pre_recurse(node) + try: + function_code = node.read('rU', None) + exec(compile(function_code, node.abspath(), 'exec'), self.exec_dict) + finally: + self.post_recurse(node) + +Build.BuildContext.PROCESS_SEPARATE_RULE = PROCESS_SEPARATE_RULE +ConfigurationContext.PROCESS_SEPARATE_RULE = PROCESS_SEPARATE_RULE + +def AD_DC_BUILD_IS_ENABLED(self): + if self.CONFIG_SET('AD_DC_BUILD_IS_ENABLED'): + return True + return False + +Build.BuildContext.AD_DC_BUILD_IS_ENABLED = AD_DC_BUILD_IS_ENABLED + +@feature('cprogram', 'cshlib', 'cstaticlib') +@after('apply_lib_vars') +@before('apply_obj_vars') +def samba_before_apply_obj_vars(self): + """before apply_obj_vars for uselib, this removes the standard paths""" + + def is_standard_libpath(env, path): + for _path in env.STANDARD_LIBPATH: + if _path == os.path.normpath(path): + return True + return False + + v = self.env + + for i in v['RPATH']: + if is_standard_libpath(v, i): + v['RPATH'].remove(i) + + for i in v['LIBPATH']: + if is_standard_libpath(v, i): + v['LIBPATH'].remove(i) + +def samba_add_onoff_option(opt, option, help=(), dest=None, default=True, + with_name="with", without_name="without"): + if default is None: + default_str = "auto" + elif default is True: + default_str = "yes" + elif default is False: + default_str = "no" + else: + default_str = str(default) + + if help == (): + help = ("Build with %s support (default=%s)" % (option, default_str)) + if dest is None: + dest = "with_%s" % option.replace('-', '_') + + with_val = "--%s-%s" % (with_name, option) + without_val = "--%s-%s" % (without_name, option) + + opt.add_option(with_val, help=help, action="store_true", dest=dest, + default=default) + opt.add_option(without_val, help=SUPPRESS_HELP, action="store_false", + dest=dest) +Options.OptionsContext.samba_add_onoff_option = samba_add_onoff_option diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_version.py b/ldb-2.0.8/buildtools/wafsamba/samba_version.py new file mode 100644 index 0000000..f0e7b4d --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/samba_version.py @@ -0,0 +1,267 @@ +import os, sys +from waflib import Utils, Context +import samba_utils +from samba_git import find_git + +def git_version_summary(path, env=None): + git = find_git(env) + + if git is None: + return ("GIT-UNKNOWN", {}) + + env.GIT = git + + environ = dict(os.environ) + environ["GIT_DIR"] = '%s/.git' % path + environ["GIT_WORK_TREE"] = path + git = samba_utils.get_string(Utils.cmd_output(env.GIT + ' show --pretty=format:"%h%n%ct%n%H%n%cd" --stat HEAD', silent=True, env=environ)) + + lines = git.splitlines() + if not lines or len(lines) < 4: + return ("GIT-UNKNOWN", {}) + + fields = { + "GIT_COMMIT_ABBREV": lines[0], + "GIT_COMMIT_FULLREV": lines[2], + "COMMIT_TIME": int(lines[1]), + "COMMIT_DATE": lines[3], + } + + ret = "GIT-" + fields["GIT_COMMIT_ABBREV"] + + if env.GIT_LOCAL_CHANGES: + clean = Utils.cmd_output('%s diff HEAD | wc -l' % env.GIT, silent=True).strip() + if clean == "0": + fields["COMMIT_IS_CLEAN"] = 1 + else: + fields["COMMIT_IS_CLEAN"] = 0 + ret += "+" + + return (ret, fields) + + +def distversion_version_summary(path): + #get version from .distversion file + suffix = None + fields = {} + + for line in Utils.readf(path + '/.distversion').splitlines(): + if line == '': + continue + if line.startswith("#"): + continue + try: + split_line = line.split("=") + if split_line[1] != "": + key = split_line[0] + value = split_line[1] + if key == "SUFFIX": + suffix = value + continue + fields[key] = value + except: + print("Failed to parse line %s from .distversion file." % (line)) + raise + + if "COMMIT_TIME" in fields: + fields["COMMIT_TIME"] = int(fields["COMMIT_TIME"]) + + if suffix is None: + return ("UNKNOWN", fields) + + return (suffix, fields) + + +class SambaVersion(object): + + def __init__(self, version_dict, path, env=None, is_install=True): + '''Determine the version number of samba + +See VERSION for the format. Entries on that file are +also accepted as dictionary entries here + ''' + + self.MAJOR=None + self.MINOR=None + self.RELEASE=None + self.REVISION=None + self.TP_RELEASE=None + self.ALPHA_RELEASE=None + self.BETA_RELEASE=None + self.PRE_RELEASE=None + self.RC_RELEASE=None + self.IS_SNAPSHOT=True + self.RELEASE_NICKNAME=None + self.VENDOR_SUFFIX=None + self.VENDOR_PATCH=None + + for a, b in version_dict.items(): + if a.startswith("SAMBA_VERSION_"): + setattr(self, a[14:], b) + else: + setattr(self, a, b) + + if self.IS_GIT_SNAPSHOT == "yes": + self.IS_SNAPSHOT=True + elif self.IS_GIT_SNAPSHOT == "no": + self.IS_SNAPSHOT=False + else: + raise Exception("Unknown value for IS_GIT_SNAPSHOT: %s" % self.IS_GIT_SNAPSHOT) + + ## + ## start with "3.0.22" + ## + self.MAJOR=int(self.MAJOR) + self.MINOR=int(self.MINOR) + self.RELEASE=int(self.RELEASE) + + SAMBA_VERSION_STRING = ("%u.%u.%u" % (self.MAJOR, self.MINOR, self.RELEASE)) + +## +## maybe add "3.0.22a" or "4.0.0tp11" or "4.0.0alpha1" or "4.0.0beta1" or "3.0.22pre1" or "3.0.22rc1" +## We do not do pre or rc version on patch/letter releases +## + if self.REVISION is not None: + SAMBA_VERSION_STRING += self.REVISION + if self.TP_RELEASE is not None: + self.TP_RELEASE = int(self.TP_RELEASE) + SAMBA_VERSION_STRING += "tp%u" % self.TP_RELEASE + if self.ALPHA_RELEASE is not None: + self.ALPHA_RELEASE = int(self.ALPHA_RELEASE) + SAMBA_VERSION_STRING += ("alpha%u" % self.ALPHA_RELEASE) + if self.BETA_RELEASE is not None: + self.BETA_RELEASE = int(self.BETA_RELEASE) + SAMBA_VERSION_STRING += ("beta%u" % self.BETA_RELEASE) + if self.PRE_RELEASE is not None: + self.PRE_RELEASE = int(self.PRE_RELEASE) + SAMBA_VERSION_STRING += ("pre%u" % self.PRE_RELEASE) + if self.RC_RELEASE is not None: + self.RC_RELEASE = int(self.RC_RELEASE) + SAMBA_VERSION_STRING += ("rc%u" % self.RC_RELEASE) + + if self.IS_SNAPSHOT: + if not is_install: + suffix = "DEVELOPERBUILD" + self.vcs_fields = {} + elif os.path.exists(os.path.join(path, ".git")): + suffix, self.vcs_fields = git_version_summary(path, env=env) + elif os.path.exists(os.path.join(path, ".distversion")): + suffix, self.vcs_fields = distversion_version_summary(path) + else: + suffix = "UNKNOWN" + self.vcs_fields = {} + self.vcs_fields["SUFFIX"] = suffix + SAMBA_VERSION_STRING += "-" + suffix + else: + self.vcs_fields = {} + + self.OFFICIAL_STRING = SAMBA_VERSION_STRING + + if self.VENDOR_SUFFIX is not None: + SAMBA_VERSION_STRING += ("-" + self.VENDOR_SUFFIX) + self.VENDOR_SUFFIX = self.VENDOR_SUFFIX + + if self.VENDOR_PATCH is not None: + SAMBA_VERSION_STRING += ("-" + self.VENDOR_PATCH) + self.VENDOR_PATCH = self.VENDOR_PATCH + + self.STRING = SAMBA_VERSION_STRING + + if self.RELEASE_NICKNAME is not None: + self.STRING_WITH_NICKNAME = "%s (%s)" % (self.STRING, self.RELEASE_NICKNAME) + else: + self.STRING_WITH_NICKNAME = self.STRING + + def __str__(self): + string="/* Autogenerated by waf */\n" + string+="#define SAMBA_VERSION_MAJOR %u\n" % self.MAJOR + string+="#define SAMBA_VERSION_MINOR %u\n" % self.MINOR + string+="#define SAMBA_VERSION_RELEASE %u\n" % self.RELEASE + if self.REVISION is not None: + string+="#define SAMBA_VERSION_REVISION %u\n" % self.REVISION + + if self.TP_RELEASE is not None: + string+="#define SAMBA_VERSION_TP_RELEASE %u\n" % self.TP_RELEASE + + if self.ALPHA_RELEASE is not None: + string+="#define SAMBA_VERSION_ALPHA_RELEASE %u\n" % self.ALPHA_RELEASE + + if self.BETA_RELEASE is not None: + string+="#define SAMBA_VERSION_BETA_RELEASE %u\n" % self.BETA_RELEASE + + if self.PRE_RELEASE is not None: + string+="#define SAMBA_VERSION_PRE_RELEASE %u\n" % self.PRE_RELEASE + + if self.RC_RELEASE is not None: + string+="#define SAMBA_VERSION_RC_RELEASE %u\n" % self.RC_RELEASE + + for name in sorted(self.vcs_fields.keys()): + string+="#define SAMBA_VERSION_%s " % name + value = self.vcs_fields[name] + string_types = str + if sys.version_info[0] < 3: + string_types = basestring + if isinstance(value, string_types): + string += "\"%s\"" % value + elif type(value) is int: + string += "%d" % value + else: + raise Exception("Unknown type for %s: %r" % (name, value)) + string += "\n" + + string+="#define SAMBA_VERSION_OFFICIAL_STRING \"" + self.OFFICIAL_STRING + "\"\n" + + if self.VENDOR_SUFFIX is not None: + string+="#define SAMBA_VERSION_VENDOR_SUFFIX " + self.VENDOR_SUFFIX + "\n" + if self.VENDOR_PATCH is not None: + string+="#define SAMBA_VERSION_VENDOR_PATCH " + self.VENDOR_PATCH + "\n" + + if self.RELEASE_NICKNAME is not None: + string+="#define SAMBA_VERSION_RELEASE_NICKNAME " + self.RELEASE_NICKNAME + "\n" + + # We need to put this #ifdef in to the headers so that vendors can override the version with a function + string+=''' +#ifdef SAMBA_VERSION_VENDOR_FUNCTION +# define SAMBA_VERSION_STRING SAMBA_VERSION_VENDOR_FUNCTION +#else /* SAMBA_VERSION_VENDOR_FUNCTION */ +# define SAMBA_VERSION_STRING "''' + self.STRING_WITH_NICKNAME + '''" +#endif +''' + string+="/* Version for mkrelease.sh: \nSAMBA_VERSION_STRING=" + self.STRING_WITH_NICKNAME + "\n */\n" + + return string + + +def samba_version_file(version_file, path, env=None, is_install=True): + '''Parse the version information from a VERSION file''' + + f = open(version_file, 'r') + version_dict = {} + for line in f: + line = line.strip() + if line == '': + continue + if line.startswith("#"): + continue + try: + split_line = line.split("=") + if split_line[1] != "": + value = split_line[1].strip('"') + version_dict[split_line[0]] = value + except: + print("Failed to parse line %s from %s" % (line, version_file)) + raise + + return SambaVersion(version_dict, path, env=env, is_install=is_install) + + + +def load_version(env=None, is_install=True): + '''load samba versions either from ./VERSION or git + return a version object for detailed breakdown''' + if not env: + env = samba_utils.LOAD_ENVIRONMENT() + + version = samba_version_file("./VERSION", ".", env, is_install=is_install) + Context.g_module.VERSION = version.STRING + return version diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_waf18.py b/ldb-2.0.8/buildtools/wafsamba/samba_waf18.py new file mode 100644 index 0000000..c0bb6bf --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/samba_waf18.py @@ -0,0 +1,431 @@ +# compatibility layer for building with more recent waf versions + +import os, shlex, sys +from waflib import Build, Configure, Node, Utils, Options, Logs, TaskGen +from waflib import ConfigSet +from waflib.TaskGen import feature, after +from waflib.Configure import conf, ConfigurationContext + +from waflib.Tools.flex import decide_ext + +# This version of flexfun runs in tsk.get_cwd() as opposed to the +# bld.variant_dir: since input paths adjusted against tsk.get_cwd(), we have to +# use tsk.get_cwd() for the work directory as well. +def flexfun(tsk): + env = tsk.env + bld = tsk.generator.bld + def to_list(xx): + if isinstance(xx, str): + return [xx] + return xx + tsk.last_cmd = lst = [] + lst.extend(to_list(env.FLEX)) + lst.extend(to_list(env.FLEXFLAGS)) + inputs = [a.path_from(tsk.get_cwd()) for a in tsk.inputs] + if env.FLEX_MSYS: + inputs = [x.replace(os.sep, '/') for x in inputs] + lst.extend(inputs) + lst = [x for x in lst if x] + txt = bld.cmd_and_log(lst, cwd=tsk.get_cwd(), env=env.env or None, quiet=0) + tsk.outputs[0].write(txt.replace('\r\n', '\n').replace('\r', '\n')) # issue #1207 + +TaskGen.declare_chain( + name = 'flex', + rule = flexfun, # issue #854 + ext_in = '.l', + decider = decide_ext, +) + + +for y in (Build.BuildContext, Build.CleanContext, Build.InstallContext, Build.UninstallContext, Build.ListContext): + class tmp(y): + variant = 'default' + +def abspath(self, env=None): + if env and hasattr(self, 'children'): + return self.get_bld().abspath() + return self.old_abspath() +Node.Node.old_abspath = Node.Node.abspath +Node.Node.abspath = abspath + +def bldpath(self, env=None): + return self.abspath() + #return self.path_from(self.ctx.bldnode.parent) +Node.Node.bldpath = bldpath + +def srcpath(self, env=None): + return self.abspath() + #return self.path_from(self.ctx.bldnode.parent) +Node.Node.srcpath = srcpath + +def store_fast(self, filename): + file = open(filename, 'wb') + data = self.get_merged_dict() + try: + Build.cPickle.dump(data, file, -1) + finally: + file.close() +ConfigSet.ConfigSet.store_fast = store_fast + +def load_fast(self, filename): + file = open(filename, 'rb') + try: + data = Build.cPickle.load(file) + finally: + file.close() + self.table.update(data) +ConfigSet.ConfigSet.load_fast = load_fast + +@feature('c', 'cxx', 'd', 'asm', 'fc', 'includes') +@after('propagate_uselib_vars', 'process_source') +def apply_incpaths(self): + lst = self.to_incnodes(self.to_list(getattr(self, 'includes', [])) + self.env['INCLUDES']) + self.includes_nodes = lst + cwdx = getattr(self.bld, 'cwdx', self.bld.bldnode) + self.env['INCPATHS'] = [x.path_from(cwdx) for x in lst] + +@conf +def define(self, key, val, quote=True, comment=None): + assert key and isinstance(key, str) + + if val is None: + val = () + elif isinstance(val, bool): + val = int(val) + + # waf 1.5 + self.env[key] = val + + if isinstance(val, int) or isinstance(val, float): + s = '%s=%s' + else: + s = quote and '%s="%s"' or '%s=%s' + app = s % (key, str(val)) + + ban = key + '=' + lst = self.env.DEFINES + for x in lst: + if x.startswith(ban): + lst[lst.index(x)] = app + break + else: + self.env.append_value('DEFINES', app) + + self.env.append_unique('define_key', key) + +# compat15 removes this but we want to keep it +@conf +def undefine(self, key, from_env=True, comment=None): + assert key and isinstance(key, str) + + ban = key + '=' + self.env.DEFINES = [x for x in self.env.DEFINES if not x.startswith(ban)] + self.env.append_unique('define_key', key) + # waf 1.5 + if from_env: + self.env[key] = () + +class ConfigurationContext(Configure.ConfigurationContext): + def init_dirs(self): + self.setenv('default') + self.env.merge_config_header = True + return super(ConfigurationContext, self).init_dirs() + +def find_program_samba(self, *k, **kw): + # Override the waf default set in the @conf decorator in Configure.py + if 'mandatory' not in kw: + kw['mandatory'] = False + ret = self.find_program_old(*k, **kw) + return ret +Configure.ConfigurationContext.find_program_old = Configure.ConfigurationContext.find_program +Configure.ConfigurationContext.find_program = find_program_samba + +Build.BuildContext.ENFORCE_GROUP_ORDERING = Utils.nada +Build.BuildContext.AUTOCLEANUP_STALE_FILES = Utils.nada + +@conf +def check(self, *k, **kw): + '''Override the waf defaults to inject --with-directory options''' + + # match the configuration test with speficic options, for example: + # --with-libiconv -> Options.options.iconv_open -> "Checking for library iconv" + self.validate_c(kw) + + additional_dirs = [] + if 'msg' in kw: + msg = kw['msg'] + for x in Options.OptionsContext.parser.parser.option_list: + if getattr(x, 'match', None) and msg in x.match: + d = getattr(Options.options, x.dest, '') + if d: + additional_dirs.append(d) + + # we add the additional dirs twice: once for the test data, and again if the compilation test suceeds below + def add_options_dir(dirs, env): + for x in dirs: + if not x in env.CPPPATH: + env.CPPPATH = [os.path.join(x, 'include')] + env.CPPPATH + if not x in env.LIBPATH: + env.LIBPATH = [os.path.join(x, 'lib')] + env.LIBPATH + + add_options_dir(additional_dirs, kw['env']) + + self.start_msg(kw['msg'], **kw) + ret = None + try: + ret = self.run_build(*k, **kw) + except self.errors.ConfigurationError: + self.end_msg(kw['errmsg'], 'YELLOW', **kw) + if Logs.verbose > 1: + raise + else: + self.fatal('The configuration failed') + else: + kw['success'] = ret + # success! time for brandy + add_options_dir(additional_dirs, self.env) + + ret = self.post_check(*k, **kw) + if not ret: + self.end_msg(kw['errmsg'], 'YELLOW', **kw) + self.fatal('The configuration failed %r' % ret) + else: + self.end_msg(self.ret_msg(kw['okmsg'], kw), **kw) + return ret + +@conf +def CHECK_LIBRARY_SUPPORT(conf, rpath=False, version_script=False, msg=None): + '''see if the platform supports building libraries''' + + if msg is None: + if rpath: + msg = "rpath library support" + else: + msg = "building library support" + + def build(bld): + lib_node = bld.srcnode.make_node('libdir/liblc1.c') + lib_node.parent.mkdir() + lib_node.write('int lib_func(void) { return 42; }\n', 'w') + main_node = bld.srcnode.make_node('main.c') + main_node.write('int main(void) {return !(lib_func() == 42);}', 'w') + linkflags = [] + if version_script: + script = bld.srcnode.make_node('ldscript') + script.write('TEST_1.0A2 { global: *; };\n', 'w') + linkflags.append('-Wl,--version-script=%s' % script.abspath()) + bld(features='c cshlib', source=lib_node, target='lib1', linkflags=linkflags, name='lib1') + o = bld(features='c cprogram', source=main_node, target='prog1', uselib_local='lib1') + if rpath: + o.rpath = [lib_node.parent.abspath()] + def run_app(self): + args = conf.SAMBA_CROSS_ARGS(msg=msg) + env = dict(os.environ) + env['LD_LIBRARY_PATH'] = self.inputs[0].parent.abspath() + os.pathsep + env.get('LD_LIBRARY_PATH', '') + self.generator.bld.cmd_and_log([self.inputs[0].abspath()] + args, env=env) + o.post() + bld(rule=run_app, source=o.link_task.outputs[0]) + + # ok, so it builds + try: + conf.check(build_fun=build, msg='Checking for %s' % msg) + except conf.errors.ConfigurationError: + return False + return True + +@conf +def CHECK_NEED_LC(conf, msg): + '''check if we need -lc''' + def build(bld): + lib_node = bld.srcnode.make_node('libdir/liblc1.c') + lib_node.parent.mkdir() + lib_node.write('#include \nint lib_func(void) { FILE *f = fopen("foo", "r");}\n', 'w') + bld(features='c cshlib', source=[lib_node], linkflags=conf.env.EXTRA_LDFLAGS, target='liblc') + try: + conf.check(build_fun=build, msg=msg, okmsg='-lc is unnecessary', errmsg='-lc is necessary') + except conf.errors.ConfigurationError: + return False + return True + +# already implemented on "waf -v" +def order(bld, tgt_list): + return True +Build.BuildContext.check_group_ordering = order + +@conf +def CHECK_CFG(self, *k, **kw): + if 'args' in kw: + kw['args'] = shlex.split(kw['args']) + if not 'mandatory' in kw: + kw['mandatory'] = False + kw['global_define'] = True + return self.check_cfg(*k, **kw) + +def cmd_output(cmd, **kw): + + silent = False + if 'silent' in kw: + silent = kw['silent'] + del(kw['silent']) + + if 'e' in kw: + tmp = kw['e'] + del(kw['e']) + kw['env'] = tmp + + kw['shell'] = isinstance(cmd, str) + kw['stdout'] = Utils.subprocess.PIPE + if silent: + kw['stderr'] = Utils.subprocess.PIPE + + try: + p = Utils.subprocess.Popen(cmd, **kw) + output = p.communicate()[0] + except OSError as e: + raise ValueError(str(e)) + + if p.returncode: + if not silent: + msg = "command execution failed: %s -> %r" % (cmd, str(output)) + raise ValueError(msg) + output = '' + return output +Utils.cmd_output = cmd_output + + +@TaskGen.feature('c', 'cxx', 'd') +@TaskGen.before('apply_incpaths', 'propagate_uselib_vars') +@TaskGen.after('apply_link', 'process_source') +def apply_uselib_local(self): + """ + process the uselib_local attribute + execute after apply_link because of the execution order set on 'link_task' + """ + env = self.env + from waflib.Tools.ccroot import stlink_task + + # 1. the case of the libs defined in the project (visit ancestors first) + # the ancestors external libraries (uselib) will be prepended + self.uselib = self.to_list(getattr(self, 'uselib', [])) + self.includes = self.to_list(getattr(self, 'includes', [])) + names = self.to_list(getattr(self, 'uselib_local', [])) + get = self.bld.get_tgen_by_name + seen = set() + seen_uselib = set() + tmp = Utils.deque(names) # consume a copy of the list of names + if tmp: + if Logs.verbose: + Logs.warn('compat: "uselib_local" is deprecated, replace by "use"') + while tmp: + lib_name = tmp.popleft() + # visit dependencies only once + if lib_name in seen: + continue + + y = get(lib_name) + y.post() + seen.add(lib_name) + + # object has ancestors to process (shared libraries): add them to the end of the list + if getattr(y, 'uselib_local', None): + for x in self.to_list(getattr(y, 'uselib_local', [])): + obj = get(x) + obj.post() + if getattr(obj, 'link_task', None): + if not isinstance(obj.link_task, stlink_task): + tmp.append(x) + + # link task and flags + if getattr(y, 'link_task', None): + + link_name = y.target[y.target.rfind(os.sep) + 1:] + if isinstance(y.link_task, stlink_task): + env.append_value('STLIB', [link_name]) + else: + # some linkers can link against programs + env.append_value('LIB', [link_name]) + + # the order + self.link_task.set_run_after(y.link_task) + + # for the recompilation + self.link_task.dep_nodes += y.link_task.outputs + + # add the link path too + tmp_path = y.link_task.outputs[0].parent.bldpath() + if not tmp_path in env['LIBPATH']: + env.prepend_value('LIBPATH', [tmp_path]) + + # add ancestors uselib too - but only propagate those that have no staticlib defined + for v in self.to_list(getattr(y, 'uselib', [])): + if v not in seen_uselib: + seen_uselib.add(v) + if not env['STLIB_' + v]: + if not v in self.uselib: + self.uselib.insert(0, v) + + # if the library task generator provides 'export_includes', add to the include path + # the export_includes must be a list of paths relative to the other library + if getattr(y, 'export_includes', None): + self.includes.extend(y.to_incnodes(y.export_includes)) + +@TaskGen.feature('cprogram', 'cxxprogram', 'cstlib', 'cxxstlib', 'cshlib', 'cxxshlib', 'dprogram', 'dstlib', 'dshlib') +@TaskGen.after('apply_link') +def apply_objdeps(self): + "add the .o files produced by some other object files in the same manner as uselib_local" + names = getattr(self, 'add_objects', []) + if not names: + return + names = self.to_list(names) + + get = self.bld.get_tgen_by_name + seen = [] + while names: + x = names[0] + + # visit dependencies only once + if x in seen: + names = names[1:] + continue + + # object does not exist ? + y = get(x) + + # object has ancestors to process first ? update the list of names + if getattr(y, 'add_objects', None): + added = 0 + lst = y.to_list(y.add_objects) + lst.reverse() + for u in lst: + if u in seen: + continue + added = 1 + names = [u]+names + if added: + continue # list of names modified, loop + + # safe to process the current object + y.post() + seen.append(x) + + for t in getattr(y, 'compiled_tasks', []): + self.link_task.inputs.extend(t.outputs) + +@TaskGen.after('apply_link') +def process_obj_files(self): + if not hasattr(self, 'obj_files'): + return + for x in self.obj_files: + node = self.path.find_resource(x) + self.link_task.inputs.append(node) + +@TaskGen.taskgen_method +def add_obj_file(self, file): + """Small example on how to link object files as if they were source + obj = bld.create_obj('cc') + obj.add_obj_file('foo.o')""" + if not hasattr(self, 'obj_files'): + self.obj_files = [] + if not 'process_obj_files' in self.meths: + self.meths.append('process_obj_files') + self.obj_files.append(file) diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_wildcard.py b/ldb-2.0.8/buildtools/wafsamba/samba_wildcard.py new file mode 100644 index 0000000..6173ce8 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/samba_wildcard.py @@ -0,0 +1,151 @@ +# based on playground/evil in the waf svn tree + +import os, datetime, fnmatch +from waflib import Scripting, Utils, Options, Logs, Errors +from waflib import ConfigSet, Context +from samba_utils import LOCAL_CACHE, os_path_relpath + +def run_task(t, k): + '''run a single build task''' + ret = t.run() + if ret: + raise Errors.WafError("Failed to build %s: %u" % (k, ret)) + + +def run_named_build_task(cmd): + '''run a named build task, matching the cmd name using fnmatch + wildcards against inputs and outputs of all build tasks''' + bld = fake_build_environment(info=False) + found = False + cwd_node = bld.root.find_dir(os.getcwd()) + top_node = bld.root.find_dir(bld.srcnode.abspath()) + + cmd = os.path.normpath(cmd) + + # cope with builds of bin/*/* + if os.path.islink(cmd): + cmd = os_path_relpath(os.readlink(cmd), os.getcwd()) + + if cmd[0:12] == "bin/default/": + cmd = cmd[12:] + + for g in bld.task_manager.groups: + for attr in ['outputs', 'inputs']: + for t in g.tasks: + s = getattr(t, attr, []) + for k in s: + relpath1 = k.relpath_gen(cwd_node) + relpath2 = k.relpath_gen(top_node) + if (fnmatch.fnmatch(relpath1, cmd) or + fnmatch.fnmatch(relpath2, cmd)): + t.position = [0,0] + print(t.display()) + run_task(t, k) + found = True + + + if not found: + raise Errors.WafError("Unable to find build target matching %s" % cmd) + + +def rewrite_compile_targets(): + '''cope with the bin/ form of compile target''' + if not Options.options.compile_targets: + return + + bld = fake_build_environment(info=False) + targets = LOCAL_CACHE(bld, 'TARGET_TYPE') + tlist = [] + + for t in Options.options.compile_targets.split(','): + if not os.path.islink(t): + tlist.append(t) + continue + link = os.readlink(t) + list = link.split('/') + for name in [list[-1], '/'.join(list[-2:])]: + if name in targets: + tlist.append(name) + continue + Options.options.compile_targets = ",".join(tlist) + + + +def wildcard_main(missing_cmd_fn): + '''this replaces main from Scripting, allowing us to override the + behaviour for unknown commands + + If a unknown command is found, then missing_cmd_fn() is called with + the name of the requested command + ''' + Scripting.commands = Options.arg_line[:] + + # rewrite the compile targets to cope with the bin/xx form + rewrite_compile_targets() + + while Scripting.commands: + x = Scripting.commands.pop(0) + + ini = datetime.datetime.now() + if x == 'configure': + fun = Scripting.configure + elif x == 'build': + fun = Scripting.build + else: + fun = getattr(Utils.g_module, x, None) + + # this is the new addition on top of main from Scripting.py + if not fun: + missing_cmd_fn(x) + break + + ctx = getattr(Utils.g_module, x + '_context', Utils.Context)() + + if x in ['init', 'shutdown', 'dist', 'distclean', 'distcheck']: + try: + fun(ctx) + except TypeError: + fun() + else: + fun(ctx) + + ela = '' + if not Options.options.progress_bar: + ela = ' (%s)' % Utils.get_elapsed_time(ini) + + if x != 'init' and x != 'shutdown': + Logs.info('%r finished successfully%s' % (x, ela)) + + if not Scripting.commands and x != 'shutdown': + Scripting.commands.append('shutdown') + + + + +def fake_build_environment(info=True, flush=False): + """create all the tasks for the project, but do not run the build + return the build context in use""" + bld = getattr(Context.g_module, 'build_context', Utils.Context)() + bld = Scripting.check_configured(bld) + + Options.commands['install'] = False + Options.commands['uninstall'] = False + + bld.is_install = 0 # False + + try: + proj = ConfigSet.ConfigSet(Options.lockfile) + except IOError: + raise Errors.WafError("Project not configured (run 'waf configure' first)") + + bld.load_envs() + + if info: + Logs.info("Waf: Entering directory `%s'" % bld.bldnode.abspath()) + bld.add_subdirs([os.path.split(Context.g_module.root_path)[0]]) + + bld.pre_build() + if flush: + bld.flush() + return bld + diff --git a/ldb-2.0.8/buildtools/wafsamba/stale_files.py b/ldb-2.0.8/buildtools/wafsamba/stale_files.py new file mode 100644 index 0000000..175f573 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/stale_files.py @@ -0,0 +1,113 @@ +# encoding: utf-8 +# Thomas Nagy, 2006-2010 (ita) + +""" +Add a pre-build hook to remove all build files +which do not have a corresponding target + +This can be used for example to remove the targets +that have changed name without performing +a full 'waf clean' + +Of course, it will only work if there are no dynamically generated +nodes/tasks, in which case the method will have to be modified +to exclude some folders for example. +""" + +from waflib import Logs, Build, Options, Utils, Errors +import os +from wafsamba import samba_utils +from Runner import Parallel + +old_refill_task_list = Parallel.refill_task_list +def replace_refill_task_list(self): + '''replacement for refill_task_list() that deletes stale files''' + + iit = old_refill_task_list(self) + bld = self.bld + + if not getattr(bld, 'new_rules', False): + # we only need to check for stale files if the build rules changed + return iit + + if Options.options.compile_targets: + # not safe when --target is used + return iit + + # execute only once + if getattr(self, 'cleanup_done', False): + return iit + self.cleanup_done = True + + def group_name(g): + tm = self.bld.task_manager + return [x for x in tm.groups_names if id(tm.groups_names[x]) == id(g)][0] + + bin_base = bld.bldnode.abspath() + bin_base_len = len(bin_base) + + # paranoia + if bin_base[-4:] != '/bin': + raise Errors.WafError("Invalid bin base: %s" % bin_base) + + # obtain the expected list of files + expected = [] + for i in range(len(bld.task_manager.groups)): + g = bld.task_manager.groups[i] + tasks = g.tasks_gen + for x in tasks: + try: + if getattr(x, 'target'): + tlist = samba_utils.TO_LIST(getattr(x, 'target')) + ttype = getattr(x, 'samba_type', None) + task_list = getattr(x, 'compiled_tasks', []) + if task_list: + # this gets all of the .o files, including the task + # ids, so foo.c maps to foo_3.o for idx=3 + for tsk in task_list: + for output in tsk.outputs: + objpath = os.path.normpath(output.abspath(bld.env)) + expected.append(objpath) + for t in tlist: + if ttype in ['LIBRARY','MODULE']: + t = samba_utils.apply_pattern(t, bld.env.shlib_PATTERN) + if ttype == 'PYTHON': + t = samba_utils.apply_pattern(t, bld.env.pyext_PATTERN) + p = os.path.join(x.path.abspath(bld.env), t) + p = os.path.normpath(p) + expected.append(p) + for n in x.allnodes: + p = n.abspath(bld.env) + if p[0:bin_base_len] == bin_base: + expected.append(p) + except: + pass + + for root, dirs, files in os.walk(bin_base): + for f in files: + p = root + '/' + f + if os.path.islink(p): + link = os.readlink(p) + if link[0:bin_base_len] == bin_base: + p = link + if f in ['config.h']: + continue + (froot, fext) = os.path.splitext(f) + if fext not in [ '.c', '.h', '.so', '.o' ]: + continue + if f[-7:] == '.inst.h': + continue + if p.find("/.conf") != -1: + continue + if not p in expected and os.path.exists(p): + Logs.warn("Removing stale file: %s" % p) + os.unlink(p) + return iit + + +def AUTOCLEANUP_STALE_FILES(bld): + """automatically clean up any files in bin that shouldn't be there""" + old_refill_task_list = Parallel.refill_task_list + Parallel.refill_task_list = replace_refill_task_list + Parallel.bld = bld +Build.BuildContext.AUTOCLEANUP_STALE_FILES = AUTOCLEANUP_STALE_FILES diff --git a/ldb-2.0.8/buildtools/wafsamba/symbols.py b/ldb-2.0.8/buildtools/wafsamba/symbols.py new file mode 100644 index 0000000..3eca3d4 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/symbols.py @@ -0,0 +1,659 @@ +# a waf tool to extract symbols from object files or libraries +# using nm, producing a set of exposed defined/undefined symbols + +import os, re, subprocess +from waflib import Utils, Build, Options, Logs, Errors +from waflib.Logs import debug +from samba_utils import TO_LIST, LOCAL_CACHE, get_tgt_list, os_path_relpath + +# these are the data structures used in symbols.py: +# +# bld.env.symbol_map : dictionary mapping public symbol names to list of +# subsystem names where that symbol exists +# +# t.in_library : list of libraries that t is in +# +# bld.env.public_symbols: set of public symbols for each subsystem +# bld.env.used_symbols : set of used symbols for each subsystem +# +# bld.env.syslib_symbols: dictionary mapping system library name to set of symbols +# for that library +# bld.env.library_dict : dictionary mapping built library paths to subsystem names +# +# LOCAL_CACHE(bld, 'TARGET_TYPE') : dictionary mapping subsystem name to target type + + +def symbols_extract(bld, objfiles, dynamic=False): + '''extract symbols from objfile, returning a dictionary containing + the set of undefined and public symbols for each file''' + + ret = {} + + # see if we can get some results from the nm cache + if not bld.env.nm_cache: + bld.env.nm_cache = {} + + objfiles = set(objfiles).copy() + + remaining = set() + for obj in objfiles: + if obj in bld.env.nm_cache: + ret[obj] = bld.env.nm_cache[obj].copy() + else: + remaining.add(obj) + objfiles = remaining + + if len(objfiles) == 0: + return ret + + cmd = ["nm"] + if dynamic: + # needed for some .so files + cmd.append("-D") + cmd.extend(list(objfiles)) + + nmpipe = subprocess.Popen(cmd, stdout=subprocess.PIPE).stdout + if len(objfiles) == 1: + filename = list(objfiles)[0] + ret[filename] = { "PUBLIC": set(), "UNDEFINED" : set()} + + for line in nmpipe: + line = line.strip() + if line.endswith(b':'): + filename = line[:-1] + ret[filename] = { "PUBLIC": set(), "UNDEFINED" : set() } + continue + cols = line.split(b" ") + if cols == [b'']: + continue + # see if the line starts with an address + if len(cols) == 3: + symbol_type = cols[1] + symbol = cols[2] + else: + symbol_type = cols[0] + symbol = cols[1] + if symbol_type in b"BDGTRVWSi": + # its a public symbol + ret[filename]["PUBLIC"].add(symbol) + elif symbol_type in b"U": + ret[filename]["UNDEFINED"].add(symbol) + + # add to the cache + for obj in objfiles: + if obj in ret: + bld.env.nm_cache[obj] = ret[obj].copy() + else: + bld.env.nm_cache[obj] = { "PUBLIC": set(), "UNDEFINED" : set() } + + return ret + + +def real_name(name): + if name.find(".objlist") != -1: + name = name[:-8] + return name + + +def find_ldd_path(bld, libname, binary): + '''find the path to the syslib we will link against''' + ret = None + if not bld.env.syslib_paths: + bld.env.syslib_paths = {} + if libname in bld.env.syslib_paths: + return bld.env.syslib_paths[libname] + + lddpipe = subprocess.Popen(['ldd', binary], stdout=subprocess.PIPE).stdout + for line in lddpipe: + line = line.strip() + cols = line.split(b" ") + if len(cols) < 3 or cols[1] != b"=>": + continue + if cols[0].startswith(b"libc."): + # save this one too + bld.env.libc_path = cols[2] + if cols[0].startswith(libname): + ret = cols[2] + bld.env.syslib_paths[libname] = ret + return ret + + +# some regular expressions for parsing readelf output +re_sharedlib = re.compile(b'Shared library: \[(.*)\]') +# output from readelf could be `Library rpath` or `Libray runpath` +re_rpath = re.compile(b'Library (rpath|runpath): \[(.*)\]') + +def get_libs(bld, binname): + '''find the list of linked libraries for any binary or library + binname is the path to the binary/library on disk + + We do this using readelf instead of ldd as we need to avoid recursing + into system libraries + ''' + + # see if we can get the result from the ldd cache + if not bld.env.lib_cache: + bld.env.lib_cache = {} + if binname in bld.env.lib_cache: + return bld.env.lib_cache[binname].copy() + + rpath = [] + libs = set() + + elfpipe = subprocess.Popen(['readelf', '--dynamic', binname], stdout=subprocess.PIPE).stdout + for line in elfpipe: + m = re_sharedlib.search(line) + if m: + libs.add(m.group(1)) + m = re_rpath.search(line) + if m: + # output from Popen is always bytestr even in py3 + rpath.extend(m.group(2).split(b":")) + + ret = set() + for lib in libs: + found = False + for r in rpath: + path = os.path.join(r, lib) + if os.path.exists(path): + ret.add(os.path.realpath(path)) + found = True + break + if not found: + # we didn't find this lib using rpath. It is probably a system + # library, so to find the path to it we either need to use ldd + # or we need to start parsing /etc/ld.so.conf* ourselves. We'll + # use ldd for now, even though it is slow + path = find_ldd_path(bld, lib, binname) + if path: + ret.add(os.path.realpath(path)) + + bld.env.lib_cache[binname] = ret.copy() + + return ret + + +def get_libs_recursive(bld, binname, seen): + '''find the recursive list of linked libraries for any binary or library + binname is the path to the binary/library on disk. seen is a set used + to prevent loops + ''' + if binname in seen: + return set() + ret = get_libs(bld, binname) + seen.add(binname) + for lib in ret: + # we don't want to recurse into system libraries. If a system + # library that we use (eg. libcups) happens to use another library + # (such as libkrb5) which contains common symbols with our own + # libraries, then that is not an error + if lib in bld.env.library_dict: + ret = ret.union(get_libs_recursive(bld, lib, seen)) + return ret + + + +def find_syslib_path(bld, libname, deps): + '''find the path to the syslib we will link against''' + # the strategy is to use the targets that depend on the library, and run ldd + # on it to find the real location of the library that is used + + linkpath = deps[0].link_task.outputs[0].abspath(bld.env) + + if libname == "python": + libname += bld.env.PYTHON_VERSION + + return find_ldd_path(bld, "lib%s" % libname.lower(), linkpath) + + +def build_symbol_sets(bld, tgt_list): + '''build the public_symbols and undefined_symbols attributes for each target''' + + if bld.env.public_symbols: + return + + objlist = [] # list of object file + objmap = {} # map from object filename to target (subsystem) name + + for t in tgt_list: + t.public_symbols = set() + t.undefined_symbols = set() + t.used_symbols = set() + for tsk in getattr(t, 'compiled_tasks', []): + for output in tsk.outputs: + objpath = output.abspath(bld.env) + objlist.append(objpath) + objmap[objpath] = t + + symbols = symbols_extract(bld, objlist) + for obj in objlist: + t = objmap[obj] + t.public_symbols = t.public_symbols.union(symbols[obj]["PUBLIC"]) + t.undefined_symbols = t.undefined_symbols.union(symbols[obj]["UNDEFINED"]) + t.used_symbols = t.used_symbols.union(symbols[obj]["UNDEFINED"]) + + t.undefined_symbols = t.undefined_symbols.difference(t.public_symbols) + + # and the reverse map of public symbols to subsystem name + bld.env.symbol_map = {} + + for t in tgt_list: + for s in t.public_symbols: + if not s in bld.env.symbol_map: + bld.env.symbol_map[s] = [] + bld.env.symbol_map[s].append(real_name(t.sname)) + + targets = LOCAL_CACHE(bld, 'TARGET_TYPE') + + bld.env.public_symbols = {} + for t in tgt_list: + name = real_name(t.sname) + if name in bld.env.public_symbols: + bld.env.public_symbols[name] = bld.env.public_symbols[name].union(t.public_symbols) + else: + bld.env.public_symbols[name] = t.public_symbols + if t.samba_type == 'LIBRARY': + for dep in t.add_objects: + t2 = bld.get_tgen_by_name(dep) + bld.ASSERT(t2 is not None, "Library '%s' has unknown dependency '%s'" % (name, dep)) + bld.env.public_symbols[name] = bld.env.public_symbols[name].union(t2.public_symbols) + + bld.env.used_symbols = {} + for t in tgt_list: + name = real_name(t.sname) + if name in bld.env.used_symbols: + bld.env.used_symbols[name] = bld.env.used_symbols[name].union(t.used_symbols) + else: + bld.env.used_symbols[name] = t.used_symbols + if t.samba_type == 'LIBRARY': + for dep in t.add_objects: + t2 = bld.get_tgen_by_name(dep) + bld.ASSERT(t2 is not None, "Library '%s' has unknown dependency '%s'" % (name, dep)) + bld.env.used_symbols[name] = bld.env.used_symbols[name].union(t2.used_symbols) + + +def build_library_dict(bld, tgt_list): + '''build the library_dict dictionary''' + + if bld.env.library_dict: + return + + bld.env.library_dict = {} + + for t in tgt_list: + if t.samba_type in [ 'LIBRARY', 'PYTHON' ]: + linkpath = os.path.realpath(t.link_task.outputs[0].abspath(bld.env)) + bld.env.library_dict[linkpath] = t.sname + + +def build_syslib_sets(bld, tgt_list): + '''build the public_symbols for all syslibs''' + + if bld.env.syslib_symbols: + return + + # work out what syslibs we depend on, and what targets those are used in + syslibs = {} + objmap = {} + for t in tgt_list: + if getattr(t, 'uselib', []) and t.samba_type in [ 'LIBRARY', 'BINARY', 'PYTHON' ]: + for lib in t.uselib: + if lib in ['PYEMBED', 'PYEXT']: + lib = "python" + if not lib in syslibs: + syslibs[lib] = [] + syslibs[lib].append(t) + + # work out the paths to each syslib + syslib_paths = [] + for lib in syslibs: + path = find_syslib_path(bld, lib, syslibs[lib]) + if path is None: + Logs.warn("Unable to find syslib path for %s" % lib) + if path is not None: + syslib_paths.append(path) + objmap[path] = lib.lower() + + # add in libc + syslib_paths.append(bld.env.libc_path) + objmap[bld.env.libc_path] = 'c' + + symbols = symbols_extract(bld, syslib_paths, dynamic=True) + + # keep a map of syslib names to public symbols + bld.env.syslib_symbols = {} + for lib in symbols: + bld.env.syslib_symbols[lib] = symbols[lib]["PUBLIC"] + + # add to the map of symbols to dependencies + for lib in symbols: + for sym in symbols[lib]["PUBLIC"]: + if not sym in bld.env.symbol_map: + bld.env.symbol_map[sym] = [] + bld.env.symbol_map[sym].append(objmap[lib]) + + # keep the libc symbols as well, as these are useful for some of the + # sanity checks + bld.env.libc_symbols = symbols[bld.env.libc_path]["PUBLIC"] + + # add to the combined map of dependency name to public_symbols + for lib in bld.env.syslib_symbols: + bld.env.public_symbols[objmap[lib]] = bld.env.syslib_symbols[lib] + + +def build_autodeps(bld, t): + '''build the set of dependencies for a target''' + deps = set() + name = real_name(t.sname) + + targets = LOCAL_CACHE(bld, 'TARGET_TYPE') + + for sym in t.undefined_symbols: + if sym in t.public_symbols: + continue + if sym in bld.env.symbol_map: + depname = bld.env.symbol_map[sym] + if depname == [ name ]: + # self dependencies aren't interesting + continue + if t.in_library == depname: + # no need to depend on the library we are part of + continue + if depname[0] in ['c', 'python']: + # these don't go into autodeps + continue + if targets[depname[0]] in [ 'SYSLIB' ]: + deps.add(depname[0]) + continue + t2 = bld.get_tgen_by_name(depname[0]) + if len(t2.in_library) != 1: + deps.add(depname[0]) + continue + if t2.in_library == t.in_library: + # if we're part of the same library, we don't need to autodep + continue + deps.add(t2.in_library[0]) + t.autodeps = deps + + +def build_library_names(bld, tgt_list): + '''add a in_library attribute to all targets that are part of a library''' + + if bld.env.done_build_library_names: + return + + for t in tgt_list: + t.in_library = [] + + for t in tgt_list: + if t.samba_type in [ 'LIBRARY' ]: + for obj in t.samba_deps_extended: + t2 = bld.get_tgen_by_name(obj) + if t2 and t2.samba_type in [ 'SUBSYSTEM', 'ASN1' ]: + if not t.sname in t2.in_library: + t2.in_library.append(t.sname) + bld.env.done_build_library_names = True + + +def check_library_deps(bld, t): + '''check that all the autodeps that have mutual dependency of this + target are in the same library as the target''' + + name = real_name(t.sname) + + if len(t.in_library) > 1: + Logs.warn("WARNING: Target '%s' in multiple libraries: %s" % (t.sname, t.in_library)) + + for dep in t.autodeps: + t2 = bld.get_tgen_by_name(dep) + if t2 is None: + continue + for dep2 in t2.autodeps: + if dep2 == name and t.in_library != t2.in_library: + Logs.warn("WARNING: mutual dependency %s <=> %s" % (name, real_name(t2.sname))) + Logs.warn("Libraries should match. %s != %s" % (t.in_library, t2.in_library)) + # raise Errors.WafError("illegal mutual dependency") + + +def check_syslib_collisions(bld, tgt_list): + '''check if a target has any symbol collisions with a syslib + + We do not want any code in Samba to use a symbol name from a + system library. The chance of that causing problems is just too + high. Note that libreplace uses a rep_XX approach of renaming + symbols via macros + ''' + + has_error = False + for t in tgt_list: + for lib in bld.env.syslib_symbols: + common = t.public_symbols.intersection(bld.env.syslib_symbols[lib]) + if common: + Logs.error("ERROR: Target '%s' has symbols '%s' which is also in syslib '%s'" % (t.sname, common, lib)) + has_error = True + if has_error: + raise Errors.WafError("symbols in common with system libraries") + + +def check_dependencies(bld, t): + '''check for depenencies that should be changed''' + + if bld.get_tgen_by_name(t.sname + ".objlist"): + return + + targets = LOCAL_CACHE(bld, 'TARGET_TYPE') + + remaining = t.undefined_symbols.copy() + remaining = remaining.difference(t.public_symbols) + + sname = real_name(t.sname) + + deps = set(t.samba_deps) + for d in t.samba_deps: + if targets[d] in [ 'EMPTY', 'DISABLED', 'SYSLIB', 'GENERATOR' ]: + continue + bld.ASSERT(d in bld.env.public_symbols, "Failed to find symbol list for dependency '%s'" % d) + diff = remaining.intersection(bld.env.public_symbols[d]) + if not diff and targets[sname] != 'LIBRARY': + Logs.info("Target '%s' has no dependency on %s" % (sname, d)) + else: + remaining = remaining.difference(diff) + + t.unsatisfied_symbols = set() + needed = {} + for sym in remaining: + if sym in bld.env.symbol_map: + dep = bld.env.symbol_map[sym] + if not dep[0] in needed: + needed[dep[0]] = set() + needed[dep[0]].add(sym) + else: + t.unsatisfied_symbols.add(sym) + + for dep in needed: + Logs.info("Target '%s' should add dep '%s' for symbols %s" % (sname, dep, " ".join(needed[dep]))) + + + +def check_syslib_dependencies(bld, t): + '''check for syslib depenencies''' + + if bld.get_tgen_by_name(t.sname + ".objlist"): + return + + sname = real_name(t.sname) + + remaining = set() + + features = TO_LIST(t.features) + if 'pyembed' in features or 'pyext' in features: + if 'python' in bld.env.public_symbols: + t.unsatisfied_symbols = t.unsatisfied_symbols.difference(bld.env.public_symbols['python']) + + needed = {} + for sym in t.unsatisfied_symbols: + if sym in bld.env.symbol_map: + dep = bld.env.symbol_map[sym][0] + if dep == 'c': + continue + if not dep in needed: + needed[dep] = set() + needed[dep].add(sym) + else: + remaining.add(sym) + + for dep in needed: + Logs.info("Target '%s' should add syslib dep '%s' for symbols %s" % (sname, dep, " ".join(needed[dep]))) + + if remaining: + debug("deps: Target '%s' has unsatisfied symbols: %s" % (sname, " ".join(remaining))) + + + +def symbols_symbolcheck(task): + '''check the internal dependency lists''' + bld = task.env.bld + tgt_list = get_tgt_list(bld) + + build_symbol_sets(bld, tgt_list) + build_library_names(bld, tgt_list) + + for t in tgt_list: + t.autodeps = set() + if getattr(t, 'source', ''): + build_autodeps(bld, t) + + for t in tgt_list: + check_dependencies(bld, t) + + for t in tgt_list: + check_library_deps(bld, t) + +def symbols_syslibcheck(task): + '''check the syslib dependencies''' + bld = task.env.bld + tgt_list = get_tgt_list(bld) + + build_syslib_sets(bld, tgt_list) + check_syslib_collisions(bld, tgt_list) + + for t in tgt_list: + check_syslib_dependencies(bld, t) + + +def symbols_whyneeded(task): + """check why 'target' needs to link to 'subsystem'""" + bld = task.env.bld + tgt_list = get_tgt_list(bld) + + why = Options.options.WHYNEEDED.split(":") + if len(why) != 2: + raise Errors.WafError("usage: WHYNEEDED=TARGET:DEPENDENCY") + target = why[0] + subsystem = why[1] + + build_symbol_sets(bld, tgt_list) + build_library_names(bld, tgt_list) + build_syslib_sets(bld, tgt_list) + + Logs.info("Checking why %s needs to link to %s" % (target, subsystem)) + if not target in bld.env.used_symbols: + Logs.warn("unable to find target '%s' in used_symbols dict" % target) + return + if not subsystem in bld.env.public_symbols: + Logs.warn("unable to find subsystem '%s' in public_symbols dict" % subsystem) + return + overlap = bld.env.used_symbols[target].intersection(bld.env.public_symbols[subsystem]) + if not overlap: + Logs.info("target '%s' doesn't use any public symbols from '%s'" % (target, subsystem)) + else: + Logs.info("target '%s' uses symbols %s from '%s'" % (target, overlap, subsystem)) + + +def report_duplicate(bld, binname, sym, libs, fail_on_error): + '''report duplicated symbols''' + if sym in ['_init', '_fini', '_edata', '_end', '__bss_start']: + return + libnames = [] + for lib in libs: + if lib in bld.env.library_dict: + libnames.append(bld.env.library_dict[lib]) + else: + libnames.append(lib) + if fail_on_error: + raise Errors.WafError("%s: Symbol %s linked in multiple libraries %s" % (binname, sym, libnames)) + else: + print("%s: Symbol %s linked in multiple libraries %s" % (binname, sym, libnames)) + + +def symbols_dupcheck_binary(bld, binname, fail_on_error): + '''check for duplicated symbols in one binary''' + + libs = get_libs_recursive(bld, binname, set()) + symlist = symbols_extract(bld, libs, dynamic=True) + + symmap = {} + for libpath in symlist: + for sym in symlist[libpath]['PUBLIC']: + if sym == '_GLOBAL_OFFSET_TABLE_': + continue + if not sym in symmap: + symmap[sym] = set() + symmap[sym].add(libpath) + for sym in symmap: + if len(symmap[sym]) > 1: + for libpath in symmap[sym]: + if libpath in bld.env.library_dict: + report_duplicate(bld, binname, sym, symmap[sym], fail_on_error) + break + +def symbols_dupcheck(task, fail_on_error=False): + '''check for symbols defined in two different subsystems''' + bld = task.env.bld + tgt_list = get_tgt_list(bld) + + targets = LOCAL_CACHE(bld, 'TARGET_TYPE') + + build_library_dict(bld, tgt_list) + for t in tgt_list: + if t.samba_type == 'BINARY': + binname = os_path_relpath(t.link_task.outputs[0].abspath(bld.env), os.getcwd()) + symbols_dupcheck_binary(bld, binname, fail_on_error) + + +def symbols_dupcheck_fatal(task): + '''check for symbols defined in two different subsystems (and fail if duplicates are found)''' + symbols_dupcheck(task, fail_on_error=True) + + +def SYMBOL_CHECK(bld): + '''check our dependency lists''' + if Options.options.SYMBOLCHECK: + bld.SET_BUILD_GROUP('symbolcheck') + task = bld(rule=symbols_symbolcheck, always=True, name='symbol checking') + task.env.bld = bld + + bld.SET_BUILD_GROUP('syslibcheck') + task = bld(rule=symbols_syslibcheck, always=True, name='syslib checking') + task.env.bld = bld + + bld.SET_BUILD_GROUP('syslibcheck') + task = bld(rule=symbols_dupcheck, always=True, name='symbol duplicate checking') + task.env.bld = bld + + if Options.options.WHYNEEDED: + bld.SET_BUILD_GROUP('syslibcheck') + task = bld(rule=symbols_whyneeded, always=True, name='check why a dependency is needed') + task.env.bld = bld + + +Build.BuildContext.SYMBOL_CHECK = SYMBOL_CHECK + +def DUP_SYMBOL_CHECK(bld): + if Options.options.DUP_SYMBOLCHECK and bld.env.DEVELOPER: + '''check for duplicate symbols''' + bld.SET_BUILD_GROUP('syslibcheck') + task = bld(rule=symbols_dupcheck_fatal, always=True, name='symbol duplicate checking') + task.env.bld = bld + +Build.BuildContext.DUP_SYMBOL_CHECK = DUP_SYMBOL_CHECK diff --git a/ldb-2.0.8/buildtools/wafsamba/test_duplicate_symbol.sh b/ldb-2.0.8/buildtools/wafsamba/test_duplicate_symbol.sh new file mode 100755 index 0000000..46f44a6 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/test_duplicate_symbol.sh @@ -0,0 +1,12 @@ +#!/bin/sh +# Run the waf duplicate symbol check, wrapped in subunit. + +. testprogs/blackbox/subunit.sh + +subunit_start_test duplicate_symbols + +if $PYTHON ./buildtools/bin/waf build --dup-symbol-check; then + subunit_pass_test duplicate_symbols +else + echo | subunit_fail_test duplicate_symbols +fi diff --git a/ldb-2.0.8/buildtools/wafsamba/tests/__init__.py b/ldb-2.0.8/buildtools/wafsamba/tests/__init__.py new file mode 100644 index 0000000..ae27418 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/tests/__init__.py @@ -0,0 +1,35 @@ +# Copyright (C) 2012 Jelmer Vernooij + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +"""Tests for wafsamba.""" + +from unittest import ( + TestCase, + TestLoader, + ) + +def test_suite(): + names = [ + 'abi', + 'bundled', + 'utils', + ] + module_names = ['wafsamba.tests.test_' + name for name in names] + loader = TestLoader() + result = loader.suiteClass() + suite = loader.loadTestsFromNames(module_names) + result.addTests(suite) + return result diff --git a/ldb-2.0.8/buildtools/wafsamba/tests/test_abi.py b/ldb-2.0.8/buildtools/wafsamba/tests/test_abi.py new file mode 100644 index 0000000..d6bdb04 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/tests/test_abi.py @@ -0,0 +1,134 @@ +# Copyright (C) 2012 Jelmer Vernooij + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +from wafsamba.tests import TestCase + +from wafsamba.samba_abi import ( + abi_write_vscript, + normalise_signature, + ) + +from samba.compat import StringIO + + +class NormaliseSignatureTests(TestCase): + + def test_function_simple(self): + self.assertEquals("int (const struct GUID *, const struct GUID *)", + normalise_signature("$2 = {int (const struct GUID *, const struct GUID *)} 0xe871 ")) + + def test_maps_Bool(self): + # Some types have different internal names + self.assertEquals("bool (const struct GUID *)", + normalise_signature("$1 = {_Bool (const struct GUID *)} 0xe75b ")) + + def test_function_keep(self): + self.assertEquals( + "enum ndr_err_code (struct ndr_push *, int, const union winreg_Data *)", + normalise_signature("enum ndr_err_code (struct ndr_push *, int, const union winreg_Data *)")) + + def test_struct_constant(self): + self.assertEquals( + 'uuid = {time_low = 0, time_mid = 0, time_hi_and_version = 0, clock_seq = "\\000", node = "\\000\\000\\000\\000\\000"}, if_version = 0', + normalise_signature('$239 = {uuid = {time_low = 0, time_mid = 0, time_hi_and_version = 0, clock_seq = "\\000", node = "\\000\\000\\000\\000\\000"}, if_version = 0}')) + + def test_incomplete_sequence(self): + # Newer versions of gdb insert these incomplete sequence elements + self.assertEquals( + 'uuid = {time_low = 2324192516, time_mid = 7403, time_hi_and_version = 4553, clock_seq = "\\237\\350", node = "\\b\\000+\\020H`"}, if_version = 2', + normalise_signature('$244 = {uuid = {time_low = 2324192516, time_mid = 7403, time_hi_and_version = 4553, clock_seq = "\\237", , node = "\\b\\000+\\020H`"}, if_version = 2}')) + self.assertEquals( + 'uuid = {time_low = 2324192516, time_mid = 7403, time_hi_and_version = 4553, clock_seq = "\\237\\350", node = "\\b\\000+\\020H`"}, if_version = 2', + normalise_signature('$244 = {uuid = {time_low = 2324192516, time_mid = 7403, time_hi_and_version = 4553, clock_seq = "\\237\\350", node = "\\b\\000+\\020H`"}, if_version = 2}')) + + +class WriteVscriptTests(TestCase): + + def test_one(self): + f = StringIO() + abi_write_vscript(f, "MYLIB", "1.0", [], { + "old": "1.0", + "new": "1.0"}, ["*"]) + self.assertEquals(f.getvalue(), """\ +1.0 { +\tglobal: +\t\t*; +\tlocal: +\t\t_end; +\t\t__bss_start; +\t\t_edata; +}; +""") + + def test_simple(self): + # No restrictions. + f = StringIO() + abi_write_vscript(f, "MYLIB", "1.0", ["0.1"], { + "old": "0.1", + "new": "1.0"}, ["*"]) + self.assertEquals(f.getvalue(), """\ +MYLIB_0.1 { +\tglobal: +\t\told; +}; + +1.0 { +\tglobal: +\t\t*; +\tlocal: +\t\t_end; +\t\t__bss_start; +\t\t_edata; +}; +""") + + def test_exclude(self): + f = StringIO() + abi_write_vscript(f, "MYLIB", "1.0", [], { + "exc_old": "0.1", + "old": "0.1", + "new": "1.0"}, ["!exc_*"]) + self.assertEquals(f.getvalue(), """\ +1.0 { +\tglobal: +\t\t*; +\tlocal: +\t\texc_*; +\t\t_end; +\t\t__bss_start; +\t\t_edata; +}; +""") + + def test_excludes_and_includes(self): + f = StringIO() + abi_write_vscript(f, "MYLIB", "1.0", [], { + "pub_foo": "1.0", + "exc_bar": "1.0", + "other": "1.0" + }, ["pub_*", "!exc_*"]) + self.assertEquals(f.getvalue(), """\ +1.0 { +\tglobal: +\t\tpub_*; +\tlocal: +\t\texc_*; +\t\t_end; +\t\t__bss_start; +\t\t_edata; +\t\t*; +}; +""") diff --git a/ldb-2.0.8/buildtools/wafsamba/tests/test_bundled.py b/ldb-2.0.8/buildtools/wafsamba/tests/test_bundled.py new file mode 100644 index 0000000..c5f0db6 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/tests/test_bundled.py @@ -0,0 +1,27 @@ +# Copyright (C) 2012 Jelmer Vernooij + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +from wafsamba.tests import TestCase + +from wafsamba.samba_bundled import ( + tuplize_version, + ) + + +class TuplizeVersionTests(TestCase): + + def test_simple(self): + self.assertEquals((1, 2, 10), tuplize_version("1.2.10")) diff --git a/ldb-2.0.8/buildtools/wafsamba/tests/test_utils.py b/ldb-2.0.8/buildtools/wafsamba/tests/test_utils.py new file mode 100644 index 0000000..a9578e2 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/tests/test_utils.py @@ -0,0 +1,76 @@ +# Copyright (C) 2012 Jelmer Vernooij + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +from wafsamba.tests import TestCase + +from wafsamba.samba_utils import ( + TO_LIST, + dict_concat, + subst_vars_error, + unique_list, + ) + +class ToListTests(TestCase): + + def test_none(self): + self.assertEquals([], TO_LIST(None)) + + def test_already_list(self): + self.assertEquals(["foo", "bar", 1], TO_LIST(["foo", "bar", 1])) + + def test_default_delimiter(self): + self.assertEquals(["foo", "bar"], TO_LIST("foo bar")) + self.assertEquals(["foo", "bar"], TO_LIST(" foo bar ")) + self.assertEquals(["foo ", "bar"], TO_LIST(" \"foo \" bar ")) + + def test_delimiter(self): + self.assertEquals(["foo", "bar"], TO_LIST("foo,bar", ",")) + self.assertEquals([" foo", "bar "], TO_LIST(" foo,bar ", ",")) + self.assertEquals([" \" foo\"", " bar "], TO_LIST(" \" foo\", bar ", ",")) + + +class UniqueListTests(TestCase): + + def test_unique_list(self): + self.assertEquals(["foo", "bar"], unique_list(["foo", "bar", "foo"])) + + +class SubstVarsErrorTests(TestCase): + + def test_valid(self): + self.assertEquals("", subst_vars_error("", {})) + self.assertEquals("FOO bar", subst_vars_error("${F} bar", {"F": "FOO"})) + + def test_invalid(self): + self.assertRaises(KeyError, subst_vars_error, "${F}", {}) + + +class DictConcatTests(TestCase): + + def test_empty(self): + ret = {} + dict_concat(ret, {}) + self.assertEquals({}, ret) + + def test_same(self): + ret = {"foo": "bar"} + dict_concat(ret, {"foo": "bla"}) + self.assertEquals({"foo": "bar"}, ret) + + def test_simple(self): + ret = {"foo": "bar"} + dict_concat(ret, {"blie": "bla"}) + self.assertEquals({"foo": "bar", "blie": "bla"}, ret) diff --git a/ldb-2.0.8/buildtools/wafsamba/wafsamba.py b/ldb-2.0.8/buildtools/wafsamba/wafsamba.py new file mode 100644 index 0000000..205d5b4 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/wafsamba.py @@ -0,0 +1,950 @@ +# a waf tool to add autoconf-like macros to the configure section +# and for SAMBA_ macros for building libraries, binaries etc + +import os, sys, re, shutil, fnmatch +from waflib import Build, Options, Task, Utils, TaskGen, Logs, Context, Errors +from waflib.Configure import conf +from waflib.Logs import debug +from samba_utils import SUBST_VARS_RECURSIVE +TaskGen.task_gen.apply_verif = Utils.nada + +# bring in the other samba modules +from samba_utils import * +from samba_utils import symlink +from samba_version import * +from samba_autoconf import * +from samba_patterns import * +from samba_pidl import * +from samba_autoproto import * +from samba_python import * +from samba_perl import * +from samba_deps import * +from samba_bundled import * +from samba_third_party import * +import samba_cross +import samba_install +import samba_conftests +import samba_abi +import samba_headers +import generic_cc +import samba_dist +import samba_wildcard +import symbols +import pkgconfig +import configure_file +import samba_waf18 + +LIB_PATH="shared" + +os.environ['PYTHONUNBUFFERED'] = '1' + +if Context.HEXVERSION not in (0x2001200,): + Logs.error(''' +Please use the version of waf that comes with Samba, not +a system installed version. See http://wiki.samba.org/index.php/Waf +for details. + +Alternatively, please run ./configure and make as usual. That will +call the right version of waf.''') + sys.exit(1) + +@conf +def SAMBA_BUILD_ENV(conf): + '''create the samba build environment''' + conf.env.BUILD_DIRECTORY = conf.bldnode.abspath() + mkdir_p(os.path.join(conf.env.BUILD_DIRECTORY, LIB_PATH)) + mkdir_p(os.path.join(conf.env.BUILD_DIRECTORY, LIB_PATH, "private")) + mkdir_p(os.path.join(conf.env.BUILD_DIRECTORY, "modules")) + mkdir_p(os.path.join(conf.env.BUILD_DIRECTORY, 'python/samba/dcerpc')) + # this allows all of the bin/shared and bin/python targets + # to be expressed in terms of build directory paths + mkdir_p(os.path.join(conf.env.BUILD_DIRECTORY, 'default')) + for (source, target) in [('shared', 'shared'), ('modules', 'modules'), ('python', 'python')]: + link_target = os.path.join(conf.env.BUILD_DIRECTORY, 'default/' + target) + if not os.path.lexists(link_target): + symlink('../' + source, link_target) + + # get perl to put the blib files in the build directory + blib_bld = os.path.join(conf.env.BUILD_DIRECTORY, 'default/pidl/blib') + blib_src = os.path.join(conf.srcnode.abspath(), 'pidl/blib') + mkdir_p(blib_bld + '/man1') + mkdir_p(blib_bld + '/man3') + if os.path.islink(blib_src): + os.unlink(blib_src) + elif os.path.exists(blib_src): + shutil.rmtree(blib_src) + + +def ADD_INIT_FUNCTION(bld, subsystem, target, init_function): + '''add an init_function to the list for a subsystem''' + if init_function is None: + return + bld.ASSERT(subsystem is not None, "You must specify a subsystem for init_function '%s'" % init_function) + cache = LOCAL_CACHE(bld, 'INIT_FUNCTIONS') + if not subsystem in cache: + cache[subsystem] = [] + cache[subsystem].append( { 'TARGET':target, 'INIT_FUNCTION':init_function } ) +Build.BuildContext.ADD_INIT_FUNCTION = ADD_INIT_FUNCTION + + +def generate_empty_file(task): + task.outputs[0].write('') + return 0 + +################################################################# +def SAMBA_LIBRARY(bld, libname, source, + deps='', + public_deps='', + includes='', + public_headers=None, + public_headers_install=True, + private_headers=None, + header_path=None, + pc_files=None, + vnum=None, + soname=None, + cflags='', + cflags_end=None, + ldflags='', + external_library=False, + realname=None, + keep_underscore=False, + autoproto=None, + autoproto_extra_source='', + group='main', + depends_on='', + local_include=True, + global_include=True, + vars=None, + subdir=None, + install_path=None, + install=True, + pyembed=False, + pyext=False, + target_type='LIBRARY', + bundled_extension=False, + bundled_name=None, + link_name=None, + abi_directory=None, + abi_match=None, + hide_symbols=False, + manpages=None, + private_library=False, + grouping_library=False, + allow_undefined_symbols=False, + allow_warnings=False, + enabled=True): + '''define a Samba library''' + + if private_library and public_headers: + raise Errors.WafError("private library '%s' must not have public header files" % + libname) + + if LIB_MUST_BE_PRIVATE(bld, libname): + private_library = True + + if not enabled: + SET_TARGET_TYPE(bld, libname, 'DISABLED') + return + + source = bld.EXPAND_VARIABLES(source, vars=vars) + if subdir: + source = bld.SUBDIR(subdir, source) + + # remember empty libraries, so we can strip the dependencies + if ((source == '') or (source == [])): + if deps == '' and public_deps == '': + SET_TARGET_TYPE(bld, libname, 'EMPTY') + return + empty_c = libname + '.empty.c' + bld.SAMBA_GENERATOR('%s_empty_c' % libname, + rule=generate_empty_file, + target=empty_c) + source=empty_c + + if BUILTIN_LIBRARY(bld, libname): + obj_target = libname + else: + obj_target = libname + '.objlist' + + if group == 'libraries': + subsystem_group = 'main' + else: + subsystem_group = group + + # first create a target for building the object files for this library + # by separating in this way, we avoid recompiling the C files + # separately for the install library and the build library + bld.SAMBA_SUBSYSTEM(obj_target, + source = source, + deps = deps, + public_deps = public_deps, + includes = includes, + public_headers = public_headers, + public_headers_install = public_headers_install, + private_headers= private_headers, + header_path = header_path, + cflags = cflags, + cflags_end = cflags_end, + group = subsystem_group, + autoproto = autoproto, + autoproto_extra_source=autoproto_extra_source, + depends_on = depends_on, + hide_symbols = hide_symbols, + allow_warnings = allow_warnings, + pyembed = pyembed, + pyext = pyext, + local_include = local_include, + global_include = global_include) + + if BUILTIN_LIBRARY(bld, libname): + return + + if not SET_TARGET_TYPE(bld, libname, target_type): + return + + # the library itself will depend on that object target + deps += ' ' + public_deps + deps = TO_LIST(deps) + deps.append(obj_target) + + realname = bld.map_shlib_extension(realname, python=(target_type=='PYTHON')) + link_name = bld.map_shlib_extension(link_name, python=(target_type=='PYTHON')) + + # we don't want any public libraries without version numbers + if (not private_library and target_type != 'PYTHON' and not realname): + if vnum is None and soname is None: + raise Errors.WafError("public library '%s' must have a vnum" % + libname) + if pc_files is None: + raise Errors.WafError("public library '%s' must have pkg-config file" % + libname) + if public_headers is None: + raise Errors.WafError("public library '%s' must have header files" % + libname) + + if bundled_name is not None: + pass + elif target_type == 'PYTHON' or realname or not private_library: + if keep_underscore: + bundled_name = libname + else: + bundled_name = libname.replace('_', '-') + else: + assert (private_library == True and realname is None) + if abi_directory or vnum or soname: + bundled_extension=True + bundled_name = PRIVATE_NAME(bld, libname.replace('_', '-'), + bundled_extension, private_library) + + ldflags = TO_LIST(ldflags) + if bld.env['ENABLE_RELRO'] is True: + ldflags.extend(TO_LIST('-Wl,-z,relro,-z,now')) + + features = 'c cshlib symlink_lib install_lib' + if pyext: + features += ' pyext' + if pyembed: + features += ' pyembed' + + if abi_directory: + features += ' abi_check' + + if pyembed and bld.env['PYTHON_SO_ABI_FLAG']: + # For ABI checking, we don't care about the Python version. + # Remove the Python ABI tag (e.g. ".cpython-35m") + abi_flag = bld.env['PYTHON_SO_ABI_FLAG'] + replacement = '' + version_libname = libname.replace(abi_flag, replacement) + else: + version_libname = libname + + vscript = None + if bld.env.HAVE_LD_VERSION_SCRIPT: + if private_library: + version = "%s_%s" % (Context.g_module.APPNAME, Context.g_module.VERSION) + elif vnum: + version = "%s_%s" % (libname, vnum) + else: + version = None + if version: + vscript = "%s.vscript" % libname + bld.ABI_VSCRIPT(version_libname, abi_directory, version, vscript, + abi_match) + fullname = apply_pattern(bundled_name, bld.env.cshlib_PATTERN) + fullpath = bld.path.find_or_declare(fullname) + vscriptpath = bld.path.find_or_declare(vscript) + if not fullpath: + raise Errors.WafError("unable to find fullpath for %s" % fullname) + if not vscriptpath: + raise Errors.WafError("unable to find vscript path for %s" % vscript) + bld.add_manual_dependency(fullpath, vscriptpath) + if bld.is_install: + # also make the .inst file depend on the vscript + instname = apply_pattern(bundled_name + '.inst', bld.env.cshlib_PATTERN) + bld.add_manual_dependency(bld.path.find_or_declare(instname), bld.path.find_or_declare(vscript)) + vscript = os.path.join(bld.path.abspath(bld.env), vscript) + + bld.SET_BUILD_GROUP(group) + t = bld( + features = features, + source = [], + target = bundled_name, + depends_on = depends_on, + samba_ldflags = ldflags, + samba_deps = deps, + samba_includes = includes, + version_script = vscript, + version_libname = version_libname, + local_include = local_include, + global_include = global_include, + vnum = vnum, + soname = soname, + install_path = None, + samba_inst_path = install_path, + name = libname, + samba_realname = realname, + samba_install = install, + abi_directory = "%s/%s" % (bld.path.abspath(), abi_directory), + abi_match = abi_match, + private_library = private_library, + grouping_library=grouping_library, + allow_undefined_symbols=allow_undefined_symbols + ) + + if realname and not link_name: + link_name = 'shared/%s' % realname + + if link_name: + if 'waflib.extras.compat15' in sys.modules: + link_name = 'default/' + link_name + t.link_name = link_name + + if pc_files is not None and not private_library: + if pyembed: + bld.PKG_CONFIG_FILES(pc_files, vnum=vnum, extra_name=bld.env['PYTHON_SO_ABI_FLAG']) + else: + bld.PKG_CONFIG_FILES(pc_files, vnum=vnum) + + if (manpages is not None and 'XSLTPROC_MANPAGES' in bld.env and + bld.env['XSLTPROC_MANPAGES']): + bld.MANPAGES(manpages, install) + + +Build.BuildContext.SAMBA_LIBRARY = SAMBA_LIBRARY + + +################################################################# +def SAMBA_BINARY(bld, binname, source, + deps='', + includes='', + public_headers=None, + private_headers=None, + header_path=None, + modules=None, + ldflags=None, + cflags='', + cflags_end=None, + autoproto=None, + use_hostcc=False, + use_global_deps=True, + compiler=None, + group='main', + manpages=None, + local_include=True, + global_include=True, + subsystem_name=None, + pyembed=False, + vars=None, + subdir=None, + install=True, + install_path=None, + enabled=True): + '''define a Samba binary''' + + if not enabled: + SET_TARGET_TYPE(bld, binname, 'DISABLED') + return + + if not SET_TARGET_TYPE(bld, binname, 'BINARY'): + return + + features = 'c cprogram symlink_bin install_bin' + if pyembed: + features += ' pyembed' + + obj_target = binname + '.objlist' + + source = bld.EXPAND_VARIABLES(source, vars=vars) + if subdir: + source = bld.SUBDIR(subdir, source) + source = unique_list(TO_LIST(source)) + + if group == 'binaries': + subsystem_group = 'main' + else: + subsystem_group = group + + # only specify PIE flags for binaries + pie_cflags = cflags + pie_ldflags = TO_LIST(ldflags) + if bld.env['ENABLE_PIE'] is True: + pie_cflags += ' -fPIE' + pie_ldflags.extend(TO_LIST('-pie')) + if bld.env['ENABLE_RELRO'] is True: + pie_ldflags.extend(TO_LIST('-Wl,-z,relro,-z,now')) + + # first create a target for building the object files for this binary + # by separating in this way, we avoid recompiling the C files + # separately for the install binary and the build binary + bld.SAMBA_SUBSYSTEM(obj_target, + source = source, + deps = deps, + includes = includes, + cflags = pie_cflags, + cflags_end = cflags_end, + group = subsystem_group, + autoproto = autoproto, + subsystem_name = subsystem_name, + local_include = local_include, + global_include = global_include, + use_hostcc = use_hostcc, + pyext = pyembed, + use_global_deps= use_global_deps) + + bld.SET_BUILD_GROUP(group) + + # the binary itself will depend on that object target + deps = TO_LIST(deps) + deps.append(obj_target) + + t = bld( + features = features, + source = [], + target = binname, + samba_deps = deps, + samba_includes = includes, + local_include = local_include, + global_include = global_include, + samba_modules = modules, + top = True, + samba_subsystem= subsystem_name, + install_path = None, + samba_inst_path= install_path, + samba_install = install, + samba_ldflags = pie_ldflags + ) + + if manpages is not None and 'XSLTPROC_MANPAGES' in bld.env and bld.env['XSLTPROC_MANPAGES']: + bld.MANPAGES(manpages, install) + +Build.BuildContext.SAMBA_BINARY = SAMBA_BINARY + + +################################################################# +def SAMBA_MODULE(bld, modname, source, + deps='', + includes='', + subsystem=None, + init_function=None, + module_init_name='samba_init_module', + autoproto=None, + autoproto_extra_source='', + cflags='', + cflags_end=None, + internal_module=True, + local_include=True, + global_include=True, + vars=None, + subdir=None, + enabled=True, + pyembed=False, + manpages=None, + allow_undefined_symbols=False, + allow_warnings=False, + install=True + ): + '''define a Samba module.''' + + bld.ASSERT(subsystem, "You must specify a subsystem for SAMBA_MODULE(%s)" % modname) + + source = bld.EXPAND_VARIABLES(source, vars=vars) + if subdir: + source = bld.SUBDIR(subdir, source) + + if internal_module or BUILTIN_LIBRARY(bld, modname): + # Do not create modules for disabled subsystems + if GET_TARGET_TYPE(bld, subsystem) == 'DISABLED': + return + bld.SAMBA_SUBSYSTEM(modname, source, + deps=deps, + includes=includes, + autoproto=autoproto, + autoproto_extra_source=autoproto_extra_source, + cflags=cflags, + cflags_end=cflags_end, + local_include=local_include, + global_include=global_include, + allow_warnings=allow_warnings, + enabled=enabled) + + bld.ADD_INIT_FUNCTION(subsystem, modname, init_function) + return + + if not enabled: + SET_TARGET_TYPE(bld, modname, 'DISABLED') + return + + # Do not create modules for disabled subsystems + if GET_TARGET_TYPE(bld, subsystem) == 'DISABLED': + return + + realname = modname + deps += ' ' + subsystem + while realname.startswith("lib"+subsystem+"_"): + realname = realname[len("lib"+subsystem+"_"):] + while realname.startswith(subsystem+"_"): + realname = realname[len(subsystem+"_"):] + + build_name = "%s_module_%s" % (subsystem, realname) + + realname = bld.make_libname(realname) + while realname.startswith("lib"): + realname = realname[len("lib"):] + + build_link_name = "modules/%s/%s" % (subsystem, realname) + + if init_function: + cflags += " -D%s=%s" % (init_function, module_init_name) + + bld.SAMBA_LIBRARY(modname, + source, + deps=deps, + includes=includes, + cflags=cflags, + cflags_end=cflags_end, + realname = realname, + autoproto = autoproto, + local_include=local_include, + global_include=global_include, + vars=vars, + bundled_name=build_name, + link_name=build_link_name, + install_path="${MODULESDIR}/%s" % subsystem, + pyembed=pyembed, + manpages=manpages, + allow_undefined_symbols=allow_undefined_symbols, + allow_warnings=allow_warnings, + install=install + ) + + +Build.BuildContext.SAMBA_MODULE = SAMBA_MODULE + + +################################################################# +def SAMBA_SUBSYSTEM(bld, modname, source, + deps='', + public_deps='', + includes='', + public_headers=None, + public_headers_install=True, + private_headers=None, + header_path=None, + cflags='', + cflags_end=None, + group='main', + init_function_sentinel=None, + autoproto=None, + autoproto_extra_source='', + depends_on='', + local_include=True, + local_include_first=True, + global_include=True, + subsystem_name=None, + enabled=True, + use_hostcc=False, + use_global_deps=True, + vars=None, + subdir=None, + hide_symbols=False, + allow_warnings=False, + pyext=False, + pyembed=False): + '''define a Samba subsystem''' + + if not enabled: + SET_TARGET_TYPE(bld, modname, 'DISABLED') + return + + # remember empty subsystems, so we can strip the dependencies + if ((source == '') or (source == [])): + if deps == '' and public_deps == '': + SET_TARGET_TYPE(bld, modname, 'EMPTY') + return + empty_c = modname + '.empty.c' + bld.SAMBA_GENERATOR('%s_empty_c' % modname, + rule=generate_empty_file, + target=empty_c) + source=empty_c + + if not SET_TARGET_TYPE(bld, modname, 'SUBSYSTEM'): + return + + source = bld.EXPAND_VARIABLES(source, vars=vars) + if subdir: + source = bld.SUBDIR(subdir, source) + source = unique_list(TO_LIST(source)) + + deps += ' ' + public_deps + + bld.SET_BUILD_GROUP(group) + + features = 'c' + if pyext: + features += ' pyext' + if pyembed: + features += ' pyembed' + + t = bld( + features = features, + source = source, + target = modname, + samba_cflags = CURRENT_CFLAGS(bld, modname, cflags, + allow_warnings=allow_warnings, + hide_symbols=hide_symbols), + depends_on = depends_on, + samba_deps = TO_LIST(deps), + samba_includes = includes, + local_include = local_include, + local_include_first = local_include_first, + global_include = global_include, + samba_subsystem= subsystem_name, + samba_use_hostcc = use_hostcc, + samba_use_global_deps = use_global_deps, + ) + + if cflags_end is not None: + t.samba_cflags.extend(TO_LIST(cflags_end)) + + if autoproto is not None: + bld.SAMBA_AUTOPROTO(autoproto, source + TO_LIST(autoproto_extra_source)) + if public_headers is not None: + bld.PUBLIC_HEADERS(public_headers, header_path=header_path, + public_headers_install=public_headers_install) + return t + + +Build.BuildContext.SAMBA_SUBSYSTEM = SAMBA_SUBSYSTEM + + +def SAMBA_GENERATOR(bld, name, rule, source='', target='', + group='generators', enabled=True, + public_headers=None, + public_headers_install=True, + private_headers=None, + header_path=None, + vars=None, + dep_vars=[], + always=False): + '''A generic source generator target''' + + if not SET_TARGET_TYPE(bld, name, 'GENERATOR'): + return + + if not enabled: + return + + dep_vars.append('ruledeps') + dep_vars.append('SAMBA_GENERATOR_VARS') + + bld.SET_BUILD_GROUP(group) + t = bld( + rule=rule, + source=bld.EXPAND_VARIABLES(source, vars=vars), + target=target, + shell=isinstance(rule, str), + update_outputs=True, + before='c', + ext_out='.c', + samba_type='GENERATOR', + dep_vars = dep_vars, + name=name) + + if vars is None: + vars = {} + t.env.SAMBA_GENERATOR_VARS = vars + + if always: + t.always = True + + if public_headers is not None: + bld.PUBLIC_HEADERS(public_headers, header_path=header_path, + public_headers_install=public_headers_install) + return t +Build.BuildContext.SAMBA_GENERATOR = SAMBA_GENERATOR + + + +@Utils.run_once +def SETUP_BUILD_GROUPS(bld): + '''setup build groups used to ensure that the different build + phases happen consecutively''' + bld.p_ln = bld.srcnode # we do want to see all targets! + bld.env['USING_BUILD_GROUPS'] = True + bld.add_group('setup') + bld.add_group('build_compiler_source') + bld.add_group('vscripts') + bld.add_group('base_libraries') + bld.add_group('generators') + bld.add_group('compiler_prototypes') + bld.add_group('compiler_libraries') + bld.add_group('build_compilers') + bld.add_group('build_source') + bld.add_group('prototypes') + bld.add_group('headers') + bld.add_group('main') + bld.add_group('symbolcheck') + bld.add_group('syslibcheck') + bld.add_group('final') +Build.BuildContext.SETUP_BUILD_GROUPS = SETUP_BUILD_GROUPS + + +def SET_BUILD_GROUP(bld, group): + '''set the current build group''' + if not 'USING_BUILD_GROUPS' in bld.env: + return + bld.set_group(group) +Build.BuildContext.SET_BUILD_GROUP = SET_BUILD_GROUP + + + +def SAMBA_SCRIPT(bld, name, pattern, installdir, installname=None): + '''used to copy scripts from the source tree into the build directory + for use by selftest''' + + source = bld.path.ant_glob(pattern, flat=True) + + bld.SET_BUILD_GROUP('build_source') + for s in TO_LIST(source): + iname = s + if installname is not None: + iname = installname + target = os.path.join(installdir, iname) + tgtdir = os.path.dirname(os.path.join(bld.srcnode.abspath(bld.env), '..', target)) + mkdir_p(tgtdir) + link_src = os.path.normpath(os.path.join(bld.path.abspath(), s)) + link_dst = os.path.join(tgtdir, os.path.basename(iname)) + if os.path.islink(link_dst) and os.readlink(link_dst) == link_src: + continue + if os.path.islink(link_dst): + os.unlink(link_dst) + Logs.info("symlink: %s -> %s/%s" % (s, installdir, iname)) + symlink(link_src, link_dst) +Build.BuildContext.SAMBA_SCRIPT = SAMBA_SCRIPT + + +def copy_and_fix_python_path(task): + pattern='sys.path.insert(0, "bin/python")' + if task.env["PYTHONARCHDIR"] in sys.path and task.env["PYTHONDIR"] in sys.path: + replacement = "" + elif task.env["PYTHONARCHDIR"] == task.env["PYTHONDIR"]: + replacement="""sys.path.insert(0, "%s")""" % task.env["PYTHONDIR"] + else: + replacement="""sys.path.insert(0, "%s") +sys.path.insert(1, "%s")""" % (task.env["PYTHONARCHDIR"], task.env["PYTHONDIR"]) + + if task.env["PYTHON"][0].startswith("/"): + replacement_shebang = "#!%s\n" % task.env["PYTHON"][0] + else: + replacement_shebang = "#!/usr/bin/env %s\n" % task.env["PYTHON"][0] + + installed_location=task.outputs[0].bldpath(task.env) + source_file = open(task.inputs[0].srcpath(task.env)) + installed_file = open(installed_location, 'w') + lineno = 0 + for line in source_file: + newline = line + if (lineno == 0 and + line[:2] == "#!"): + newline = replacement_shebang + elif pattern in line: + newline = line.replace(pattern, replacement) + installed_file.write(newline) + lineno = lineno + 1 + installed_file.close() + os.chmod(installed_location, 0o755) + return 0 + +def copy_and_fix_perl_path(task): + pattern='use lib "$RealBin/lib";' + + replacement = "" + if not task.env["PERL_LIB_INSTALL_DIR"] in task.env["PERL_INC"]: + replacement = 'use lib "%s";' % task.env["PERL_LIB_INSTALL_DIR"] + + if task.env["PERL"][0] == "/": + replacement_shebang = "#!%s\n" % task.env["PERL"] + else: + replacement_shebang = "#!/usr/bin/env %s\n" % task.env["PERL"] + + installed_location=task.outputs[0].bldpath(task.env) + source_file = open(task.inputs[0].srcpath(task.env)) + installed_file = open(installed_location, 'w') + lineno = 0 + for line in source_file: + newline = line + if lineno == 0 and task.env["PERL_SPECIFIED"] == True and line[:2] == "#!": + newline = replacement_shebang + elif pattern in line: + newline = line.replace(pattern, replacement) + installed_file.write(newline) + lineno = lineno + 1 + installed_file.close() + os.chmod(installed_location, 0o755) + return 0 + + +def install_file(bld, destdir, file, chmod=MODE_644, flat=False, + python_fixup=False, perl_fixup=False, + destname=None, base_name=None): + '''install a file''' + if not isinstance(file, str): + file = file.abspath() + destdir = bld.EXPAND_VARIABLES(destdir) + if not destname: + destname = file + if flat: + destname = os.path.basename(destname) + dest = os.path.join(destdir, destname) + if python_fixup: + # fix the path python will use to find Samba modules + inst_file = file + '.inst' + bld.SAMBA_GENERATOR('python_%s' % destname, + rule=copy_and_fix_python_path, + dep_vars=["PYTHON","PYTHON_SPECIFIED","PYTHONDIR","PYTHONARCHDIR"], + source=file, + target=inst_file) + file = inst_file + if perl_fixup: + # fix the path perl will use to find Samba modules + inst_file = file + '.inst' + bld.SAMBA_GENERATOR('perl_%s' % destname, + rule=copy_and_fix_perl_path, + dep_vars=["PERL","PERL_SPECIFIED","PERL_LIB_INSTALL_DIR"], + source=file, + target=inst_file) + file = inst_file + if base_name: + file = os.path.join(base_name, file) + bld.install_as(dest, file, chmod=chmod) + + +def INSTALL_FILES(bld, destdir, files, chmod=MODE_644, flat=False, + python_fixup=False, perl_fixup=False, + destname=None, base_name=None): + '''install a set of files''' + for f in TO_LIST(files): + install_file(bld, destdir, f, chmod=chmod, flat=flat, + python_fixup=python_fixup, perl_fixup=perl_fixup, + destname=destname, base_name=base_name) +Build.BuildContext.INSTALL_FILES = INSTALL_FILES + + +def INSTALL_WILDCARD(bld, destdir, pattern, chmod=MODE_644, flat=False, + python_fixup=False, exclude=None, trim_path=None): + '''install a set of files matching a wildcard pattern''' + files=TO_LIST(bld.path.ant_glob(pattern, flat=True)) + if trim_path: + files2 = [] + for f in files: + files2.append(os_path_relpath(f, trim_path)) + files = files2 + + if exclude: + for f in files[:]: + if fnmatch.fnmatch(f, exclude): + files.remove(f) + INSTALL_FILES(bld, destdir, files, chmod=chmod, flat=flat, + python_fixup=python_fixup, base_name=trim_path) +Build.BuildContext.INSTALL_WILDCARD = INSTALL_WILDCARD + +def INSTALL_DIR(bld, path, chmod=0o755, env=None): + """Install a directory if it doesn't exist, always set permissions.""" + + if not path: + return [] + + destpath = bld.EXPAND_VARIABLES(path) + if Options.options.destdir: + destpath = os.path.join(Options.options.destdir, destpath.lstrip(os.sep)) + + if bld.is_install > 0: + if not os.path.isdir(destpath): + try: + Logs.info('* create %s', destpath) + os.makedirs(destpath) + os.chmod(destpath, chmod) + except OSError as e: + if not os.path.isdir(destpath): + raise Errors.WafError("Cannot create the folder '%s' (error: %s)" % (path, e)) +Build.BuildContext.INSTALL_DIR = INSTALL_DIR + +def INSTALL_DIRS(bld, destdir, dirs, chmod=0o755, env=None): + '''install a set of directories''' + destdir = bld.EXPAND_VARIABLES(destdir) + dirs = bld.EXPAND_VARIABLES(dirs) + for d in TO_LIST(dirs): + INSTALL_DIR(bld, os.path.join(destdir, d), chmod, env) +Build.BuildContext.INSTALL_DIRS = INSTALL_DIRS + + +def MANPAGES(bld, manpages, install): + '''build and install manual pages''' + bld.env.MAN_XSL = 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl' + for m in manpages.split(): + source = m + '.xml' + bld.SAMBA_GENERATOR(m, + source=source, + target=m, + group='final', + rule='${XSLTPROC} --xinclude -o ${TGT} --nonet ${MAN_XSL} ${SRC}' + ) + if install: + bld.INSTALL_FILES('${MANDIR}/man%s' % m[-1], m, flat=True) +Build.BuildContext.MANPAGES = MANPAGES + +def SAMBAMANPAGES(bld, manpages, extra_source=None): + '''build and install manual pages''' + bld.env.SAMBA_EXPAND_XSL = bld.srcnode.abspath() + '/docs-xml/xslt/expand-sambadoc.xsl' + bld.env.SAMBA_MAN_XSL = bld.srcnode.abspath() + '/docs-xml/xslt/man.xsl' + bld.env.SAMBA_CATALOG = bld.bldnode.abspath() + '/docs-xml/build/catalog.xml' + bld.env.SAMBA_CATALOGS = 'file:///etc/xml/catalog file:///usr/local/share/xml/catalog file://' + bld.env.SAMBA_CATALOG + + for m in manpages.split(): + source = m + '.xml' + if extra_source is not None: + source = [source, extra_source] + bld.SAMBA_GENERATOR(m, + source=source, + target=m, + group='final', + dep_vars=['SAMBA_MAN_XSL', 'SAMBA_EXPAND_XSL', 'SAMBA_CATALOG'], + rule='''XML_CATALOG_FILES="${SAMBA_CATALOGS}" + export XML_CATALOG_FILES + ${XSLTPROC} --xinclude --stringparam noreference 0 -o ${TGT}.xml --nonet ${SAMBA_EXPAND_XSL} ${SRC[0].abspath(env)} + ${XSLTPROC} --nonet -o ${TGT} ${SAMBA_MAN_XSL} ${TGT}.xml''' + ) + bld.INSTALL_FILES('${MANDIR}/man%s' % m[-1], m, flat=True) +Build.BuildContext.SAMBAMANPAGES = SAMBAMANPAGES + +@after('apply_link') +@feature('cshlib') +def apply_bundle_remove_dynamiclib_patch(self): + if self.env['MACBUNDLE'] or getattr(self,'mac_bundle',False): + if not getattr(self,'vnum',None): + try: + self.env['LINKFLAGS'].remove('-dynamiclib') + self.env['LINKFLAGS'].remove('-single_module') + except ValueError: + pass diff --git a/ldb-2.0.8/buildtools/wafsamba/wscript b/ldb-2.0.8/buildtools/wafsamba/wscript new file mode 100644 index 0000000..8014716 --- /dev/null +++ b/ldb-2.0.8/buildtools/wafsamba/wscript @@ -0,0 +1,611 @@ +#!/usr/bin/env python + +# this is a base set of waf rules that everything else pulls in first + +import os, sys +from waflib import Configure, Logs, Options, Utils, Context, Errors +import wafsamba +from samba_utils import os_path_relpath +from optparse import SUPPRESS_HELP + +# this forces configure to be re-run if any of the configure +# sections of the build scripts change. We have to check +# for this in sys.argv as options have not yet been parsed when +# we need to set this. This is off by default until some issues +# are resolved related to WAFCACHE. It will need a lot of testing +# before it is enabled by default. +if '--enable-auto-reconfigure' in sys.argv: + Configure.autoconfig = 'clobber' + +def default_value(option, default=''): + if option in Options.options.__dict__: + return Options.options.__dict__[option] + return default + +def options(opt): + opt.load('compiler_cc') + + opt.load('gnu_dirs') + + gr = opt.option_group('library handling options') + + gr.add_option('--bundled-libraries', + help=("comma separated list of bundled libraries. May include !LIBNAME to disable bundling a library. Can be 'NONE' or 'ALL' [auto]"), + action="store", dest='BUNDLED_LIBS', default='') + + gr.add_option('--private-libraries', + help=("comma separated list of normally public libraries to build instead as private libraries. May include !LIBNAME to disable making a library private. Can be 'NONE' or 'ALL' [auto]"), + action="store", dest='PRIVATE_LIBS', default='') + + extension_default = default_value('PRIVATE_EXTENSION_DEFAULT') + gr.add_option('--private-library-extension', + help=("name extension for private libraries [%s]" % extension_default), + action="store", dest='PRIVATE_EXTENSION', default=extension_default) + + extension_exception = default_value('PRIVATE_EXTENSION_EXCEPTION') + gr.add_option('--private-extension-exception', + help=("comma separated list of libraries to not apply extension to [%s]" % extension_exception), + action="store", dest='PRIVATE_EXTENSION_EXCEPTION', default=extension_exception) + + builtin_default = default_value('BUILTIN_LIBRARIES_DEFAULT') + gr.add_option('--builtin-libraries', + help=("command separated list of libraries to build directly into binaries [%s]" % builtin_default), + action="store", dest='BUILTIN_LIBRARIES', default=builtin_default) + + gr.add_option('--minimum-library-version', + help=("list of minimum system library versions (LIBNAME1:version,LIBNAME2:version)"), + action="store", dest='MINIMUM_LIBRARY_VERSION', default='') + + gr.add_option('--disable-rpath', + help=("Disable use of rpath for build binaries"), + action="store_true", dest='disable_rpath_build', default=False) + gr.add_option('--disable-rpath-install', + help=("Disable use of rpath for library path in installed files"), + action="store_true", dest='disable_rpath_install', default=False) + gr.add_option('--disable-rpath-private-install', + help=("Disable use of rpath for private library path in installed files"), + action="store_true", dest='disable_rpath_private_install', default=False) + gr.add_option('--nonshared-binary', + help=("Disable use of shared libs for the listed binaries"), + action="store", dest='NONSHARED_BINARIES', default='') + gr.add_option('--disable-symbol-versions', + help=("Disable use of the --version-script linker option"), + action="store_true", dest='disable_symbol_versions', default=False) + + opt.add_option('--with-modulesdir', + help=("modules directory [PREFIX/modules]"), + action="store", dest='MODULESDIR', default='${PREFIX}/modules') + + opt.add_option('--with-privatelibdir', + help=("private library directory [PREFIX/lib/%s]" % Context.g_module.APPNAME), + action="store", dest='PRIVATELIBDIR', default=None) + + opt.add_option('--with-libiconv', + help='additional directory to search for libiconv', + action='store', dest='iconv_open', default='/usr/local', + match = ['Checking for library iconv', 'Checking for iconv_open', 'Checking for header iconv.h']) + opt.add_option('--without-gettext', + help=("Disable use of gettext"), + action="store_true", dest='disable_gettext', default=False) + + gr = opt.option_group('developer options') + + gr.add_option('-C', + help='enable configure cacheing', + action='store_true', dest='enable_configure_cache') + gr.add_option('--enable-auto-reconfigure', + help='enable automatic reconfigure on build', + action='store_true', dest='enable_auto_reconfigure') + gr.add_option('--enable-debug', + help=("Turn on debugging symbols"), + action="store_true", dest='debug', default=False) + gr.add_option('--enable-developer', + help=("Turn on developer warnings and debugging"), + action="store_true", dest='developer', default=False) + opt.add_option('--enable-coverage', + help=("enable options necessary for code coverage " + "reporting on selftest (default=no)"), + action="store_true", dest='enable_coverage', default=False) + def picky_developer_callback(option, opt_str, value, parser): + parser.values.developer = True + parser.values.picky_developer = True + gr.add_option('--picky-developer', + help=("Treat all warnings as errors (enable -Werror)"), + action="callback", callback=picky_developer_callback, + dest='picky_developer', default=False) + gr.add_option('--fatal-errors', + help=("Stop compilation on first error (enable -Wfatal-errors)"), + action="store_true", dest='fatal_errors', default=False) + gr.add_option('--enable-gccdeps', + help=("Enable use of gcc -MD dependency module"), + action="store_true", dest='enable_gccdeps', default=True) + gr.add_option('--pedantic', + help=("Enable even more compiler warnings"), + action='store_true', dest='pedantic', default=False) + gr.add_option('--git-local-changes', + help=("mark version with + if local git changes"), + action='store_true', dest='GIT_LOCAL_CHANGES', default=False) + gr.add_option('--address-sanitizer', + help=("Enable address sanitizer compile and linker flags"), + action="store_true", dest='address_sanitizer', default=False) + gr.add_option('--undefined-sanitizer', + help=("Enable undefined behaviour sanitizer compile and linker flags"), + action="store_true", + dest='undefined_sanitizer', + default=False) + + gr.add_option('--abi-check', + help=("Check ABI signatures for libraries"), + action='store_true', dest='ABI_CHECK', default=False) + gr.add_option('--abi-check-disable', + help=("Disable ABI checking (used with --enable-developer)"), + action='store_true', dest='ABI_CHECK_DISABLE', default=False) + gr.add_option('--abi-update', + help=("Update ABI signature files for libraries"), + action='store_true', dest='ABI_UPDATE', default=False) + + gr.add_option('--show-deps', + help=("Show dependency tree for the given target"), + dest='SHOWDEPS', default='') + + gr.add_option('--symbol-check', + help=("check symbols in object files against project rules"), + action='store_true', dest='SYMBOLCHECK', default=False) + + gr.add_option('--dup-symbol-check', + help=("check for duplicate symbols in object files and system libs (must be configured with --enable-developer)"), + action='store_true', dest='DUP_SYMBOLCHECK', default=False) + + gr.add_option('--why-needed', + help=("TARGET:DEPENDENCY check why TARGET needs DEPENDENCY"), + action='store', type='str', dest='WHYNEEDED', default=None) + + gr.add_option('--show-duplicates', + help=("Show objects which are included in multiple binaries or libraries"), + action='store_true', dest='SHOW_DUPLICATES', default=False) + + gr = opt.add_option_group('cross compilation options') + + gr.add_option('--cross-compile', + help=("configure for cross-compilation"), + action='store_true', dest='CROSS_COMPILE', default=False) + gr.add_option('--cross-execute', + help=("command prefix to use for cross-execution in configure"), + action='store', dest='CROSS_EXECUTE', default='') + gr.add_option('--cross-answers', + help=("answers to cross-compilation configuration (auto modified)"), + action='store', dest='CROSS_ANSWERS', default='') + gr.add_option('--hostcc', + help=("set host compiler when cross compiling"), + action='store', dest='HOSTCC', default=False) + + # we use SUPPRESS_HELP for these, as they are ignored, and are there only + # to allow existing RPM spec files to work + opt.add_option('--build', + help=SUPPRESS_HELP, + action='store', dest='AUTOCONF_BUILD', default='') + opt.add_option('--host', + help=SUPPRESS_HELP, + action='store', dest='AUTOCONF_HOST', default='') + opt.add_option('--target', + help=SUPPRESS_HELP, + action='store', dest='AUTOCONF_TARGET', default='') + opt.add_option('--program-prefix', + help=SUPPRESS_HELP, + action='store', dest='AUTOCONF_PROGRAM_PREFIX', default='') + opt.add_option('--disable-dependency-tracking', + help=SUPPRESS_HELP, + action='store_true', dest='AUTOCONF_DISABLE_DEPENDENCY_TRACKING', default=False) + opt.add_option('--disable-silent-rules', + help=SUPPRESS_HELP, + action='store_true', dest='AUTOCONF_DISABLE_SILENT_RULES', default=False) + + gr = opt.option_group('dist options') + gr.add_option('--sign-release', + help='sign the release tarball created by waf dist', + action='store_true', dest='SIGN_RELEASE') + gr.add_option('--tag', + help='tag release in git at the same time', + type='string', action='store', dest='TAG_RELEASE') + + opt.add_option('--disable-python', + help='do not generate python modules', + action='store_true', dest='disable_python', default=False) + + +@Utils.run_once +def configure(conf): + conf.env.hlist = [] + conf.env.srcdir = conf.srcnode.abspath() + + conf.define('SRCDIR', conf.env['srcdir']) + + conf.SETUP_CONFIGURE_CACHE(Options.options.enable_configure_cache) + + # load our local waf extensions + conf.load('gnu_dirs') + conf.load('wafsamba') + + conf.CHECK_CC_ENV() + + conf.load('compiler_c') + + conf.CHECK_STANDARD_LIBPATH() + + # we need git for 'waf dist' + conf.find_program('git', var='GIT') + + # older gcc versions (< 4.4) does not work with gccdeps, so we have to see if the .d file is generated + if Options.options.enable_gccdeps: + # stale file removal - the configuration may pick up the old .pyc file + p = os.path.join(conf.env.srcdir, 'buildtools/wafsamba/gccdeps.pyc') + if os.path.exists(p): + os.remove(p) + conf.load('gccdeps') + + # make the install paths available in environment + conf.env.LIBDIR = Options.options.LIBDIR or '${PREFIX}/lib' + conf.env.BINDIR = Options.options.BINDIR or '${PREFIX}/bin' + conf.env.SBINDIR = Options.options.SBINDIR or '${PREFIX}/sbin' + conf.env.MODULESDIR = Options.options.MODULESDIR + conf.env.PRIVATELIBDIR = Options.options.PRIVATELIBDIR + conf.env.BUNDLED_LIBS = Options.options.BUNDLED_LIBS.split(',') + conf.env.SYSTEM_LIBS = () + conf.env.PRIVATE_LIBS = Options.options.PRIVATE_LIBS.split(',') + conf.env.BUILTIN_LIBRARIES = Options.options.BUILTIN_LIBRARIES.split(',') + conf.env.NONSHARED_BINARIES = Options.options.NONSHARED_BINARIES.split(',') + + conf.env.PRIVATE_EXTENSION = Options.options.PRIVATE_EXTENSION + conf.env.PRIVATE_EXTENSION_EXCEPTION = Options.options.PRIVATE_EXTENSION_EXCEPTION.split(',') + + conf.env.CROSS_COMPILE = Options.options.CROSS_COMPILE + conf.env.CROSS_EXECUTE = Options.options.CROSS_EXECUTE + conf.env.CROSS_ANSWERS = Options.options.CROSS_ANSWERS + conf.env.HOSTCC = Options.options.HOSTCC + + conf.env.AUTOCONF_BUILD = Options.options.AUTOCONF_BUILD + conf.env.AUTOCONF_HOST = Options.options.AUTOCONF_HOST + conf.env.AUTOCONF_PROGRAM_PREFIX = Options.options.AUTOCONF_PROGRAM_PREFIX + + conf.env.disable_python = Options.options.disable_python + + if (conf.env.AUTOCONF_HOST and + conf.env.AUTOCONF_BUILD and + conf.env.AUTOCONF_BUILD != conf.env.AUTOCONF_HOST): + Logs.error('ERROR: Mismatch between --build and --host. Please use --cross-compile instead') + sys.exit(1) + if conf.env.AUTOCONF_PROGRAM_PREFIX: + Logs.error('ERROR: --program-prefix not supported') + sys.exit(1) + + # enable ABI checking for developers + conf.env.ABI_CHECK = Options.options.ABI_CHECK or Options.options.developer + if Options.options.ABI_CHECK_DISABLE: + conf.env.ABI_CHECK = False + try: + conf.find_program('gdb', mandatory=True) + except: + conf.env.ABI_CHECK = False + + conf.env.enable_coverage = Options.options.enable_coverage + if conf.env.enable_coverage: + conf.ADD_LDFLAGS('-lgcov', testflags=True) + conf.ADD_CFLAGS('--coverage', testflags=True) + # disable abi check for coverage, otherwise ld will fail + conf.env.ABI_CHECK = False + + conf.env.GIT_LOCAL_CHANGES = Options.options.GIT_LOCAL_CHANGES + + conf.CHECK_UNAME() + + # see if we can compile and run a simple C program + conf.CHECK_CODE('printf("hello world")', + define='HAVE_SIMPLE_C_PROG', + mandatory=True, + execute=True, + headers='stdio.h', + msg='Checking simple C program') + + # Try to find the right extra flags for -Werror behaviour + for f in ["-Werror", # GCC + "-errwarn=%all", # Sun Studio + "-qhalt=w", # IBM xlc + "-w2", # Tru64 + ]: + if conf.CHECK_CFLAGS([f]): + if not 'WERROR_CFLAGS' in conf.env: + conf.env['WERROR_CFLAGS'] = [] + conf.env['WERROR_CFLAGS'].extend([f]) + break + + # check which compiler/linker flags are needed for rpath support + if conf.CHECK_LDFLAGS(['-Wl,-rpath,.']): + conf.env['RPATH_ST'] = '-Wl,-rpath,%s' + elif conf.CHECK_LDFLAGS(['-Wl,-R,.']): + conf.env['RPATH_ST'] = '-Wl,-R,%s' + + # check for rpath + if conf.CHECK_LIBRARY_SUPPORT(rpath=True): + support_rpath = True + conf.env.RPATH_ON_BUILD = not Options.options.disable_rpath_build + conf.env.RPATH_ON_INSTALL = (conf.env.RPATH_ON_BUILD and + not Options.options.disable_rpath_install) + if not conf.env.PRIVATELIBDIR: + conf.env.PRIVATELIBDIR = '%s/%s' % (conf.env.LIBDIR, Context.g_module.APPNAME) + conf.env.RPATH_ON_INSTALL_PRIVATE = ( + not Options.options.disable_rpath_private_install) + else: + support_rpath = False + conf.env.RPATH_ON_INSTALL = False + conf.env.RPATH_ON_BUILD = False + conf.env.RPATH_ON_INSTALL_PRIVATE = False + if not conf.env.PRIVATELIBDIR: + # rpath is not possible so there is no sense in having a + # private library directory by default. + # the user can of course always override it. + conf.env.PRIVATELIBDIR = conf.env.LIBDIR + + if (not Options.options.disable_symbol_versions and + conf.CHECK_LIBRARY_SUPPORT(rpath=support_rpath, + version_script=True, + msg='-Wl,--version-script support')): + conf.env.HAVE_LD_VERSION_SCRIPT = True + else: + conf.env.HAVE_LD_VERSION_SCRIPT = False + + if conf.CHECK_CFLAGS(['-fvisibility=hidden']): + conf.env.VISIBILITY_CFLAGS = '-fvisibility=hidden' + conf.CHECK_CODE('''int main(void) { return 0; } + __attribute__((visibility("default"))) void vis_foo2(void) {}\n''', + cflags=conf.env.VISIBILITY_CFLAGS, + strict=True, + define='HAVE_VISIBILITY_ATTR', addmain=False) + + # check HAVE_CONSTRUCTOR_ATTRIBUTE + conf.CHECK_CODE(''' + void test_constructor_attribute(void) __attribute__ ((constructor)); + + void test_constructor_attribute(void) + { + return; + } + + int main(void) { + return 0; + } + ''', + 'HAVE_CONSTRUCTOR_ATTRIBUTE', + addmain=False, + strict=True, + msg='Checking for library constructor support') + + # check HAVE_DESTRUCTOR_ATTRIBUTE + conf.CHECK_CODE(''' + void test_destructor_attribute(void) __attribute__ ((destructor)); + + void test_destructor_attribute(void) + { + return; + } + + int main(void) { + return 0; + } + ''', + 'HAVE_DESTRUCTOR_ATTRIBUTE', + addmain=False, + strict=True, + msg='Checking for library destructor support') + + conf.CHECK_CODE(''' + void test_attribute(void) __attribute__ (()); + + void test_attribute(void) + { + return; + } + + int main(void) { + return 0; + } + ''', + 'HAVE___ATTRIBUTE__', + addmain=False, + strict=True, + msg='Checking for __attribute__') + + if sys.platform.startswith('aix'): + conf.DEFINE('_ALL_SOURCE', 1, add_to_cflags=True) + # Might not be needed if ALL_SOURCE is defined + # conf.DEFINE('_XOPEN_SOURCE', 600, add_to_cflags=True) + + # we should use the PIC options in waf instead + # Some compilo didn't support -fPIC but just print a warning + if conf.env['COMPILER_CC'] == "suncc": + conf.ADD_CFLAGS('-KPIC', testflags=True) + # we really want define here as we need to have this + # define even during the tests otherwise detection of + # boolean is broken + conf.DEFINE('_STDC_C99', 1, add_to_cflags=True) + conf.DEFINE('_XPG6', 1, add_to_cflags=True) + else: + conf.ADD_CFLAGS('-fPIC', testflags=True) + + # On Solaris 8 with suncc (at least) the flags for the linker to define the name of the + # library are not always working (if the command line is very very long and with a lot + # files) + + if conf.env['COMPILER_CC'] == "suncc": + save = conf.env['SONAME_ST'] + conf.env['SONAME_ST'] = '-Wl,-h,%s' + if not conf.CHECK_SHLIB_INTRASINC_NAME_FLAGS("Checking if flags %s are ok" % conf.env['SONAME_ST']): + conf.env['SONAME_ST'] = save + + conf.CHECK_INLINE() + + # check for pkgconfig + conf.CHECK_CFG(atleast_pkgconfig_version='0.0.0') + + conf.DEFINE('_GNU_SOURCE', 1, add_to_cflags=True) + conf.DEFINE('_XOPEN_SOURCE_EXTENDED', 1, add_to_cflags=True) + + # + # Needs to be defined before std*.h and string*.h are included + # As Python.h already brings string.h we need it in CFLAGS. + # See memset_s() details here: + # https://en.cppreference.com/w/c/string/byte/memset + # + if conf.CHECK_CFLAGS(['-D__STDC_WANT_LIB_EXT1__=1']): + conf.ADD_CFLAGS('-D__STDC_WANT_LIB_EXT1__=1') + + # on Tru64 certain features are only available with _OSF_SOURCE set to 1 + # and _XOPEN_SOURCE set to 600 + if conf.env['SYSTEM_UNAME_SYSNAME'] == 'OSF1': + conf.DEFINE('_OSF_SOURCE', 1, add_to_cflags=True) + conf.DEFINE('_XOPEN_SOURCE', 600, add_to_cflags=True) + + # SCM_RIGHTS is only avail if _XOPEN_SOURCE iÑ• defined on IRIX + if conf.env['SYSTEM_UNAME_SYSNAME'] == 'IRIX': + conf.DEFINE('_XOPEN_SOURCE', 600, add_to_cflags=True) + conf.DEFINE('_BSD_TYPES', 1, add_to_cflags=True) + + # Try to find the right extra flags for C99 initialisers + for f in ["", "-AC99", "-qlanglvl=extc99", "-qlanglvl=stdc99", "-c99"]: + if conf.CHECK_CFLAGS([f], ''' +struct foo {int x;char y;}; +struct foo bar = { .y = 'X', .x = 1 }; +'''): + if f != "": + conf.ADD_CFLAGS(f) + break + + # get the base headers we'll use for the rest of the tests + conf.CHECK_HEADERS('stdio.h sys/types.h sys/stat.h stdlib.h stddef.h memory.h string.h', + add_headers=True) + conf.CHECK_HEADERS('strings.h inttypes.h stdint.h unistd.h minix/config.h', add_headers=True) + conf.CHECK_HEADERS('ctype.h', add_headers=True) + + if sys.platform != 'darwin': + conf.CHECK_HEADERS('standards.h', add_headers=True) + + conf.CHECK_HEADERS('stdbool.h stdint.h stdarg.h vararg.h', add_headers=True) + conf.CHECK_HEADERS('limits.h assert.h') + + # see if we need special largefile flags + if not conf.CHECK_LARGEFILE(): + raise Errors.WafError('Samba requires large file support support, but not available on this platform: sizeof(off_t) < 8') + + if conf.env.HAVE_STDDEF_H and conf.env.HAVE_STDLIB_H: + conf.DEFINE('STDC_HEADERS', 1) + + conf.CHECK_HEADERS('sys/time.h time.h', together=True) + + if conf.env.HAVE_SYS_TIME_H and conf.env.HAVE_TIME_H: + conf.DEFINE('TIME_WITH_SYS_TIME', 1) + + # cope with different extensions for libraries + (root, ext) = os.path.splitext(conf.env.cshlib_PATTERN) + if ext[0] == '.': + conf.define('SHLIBEXT', ext[1:], quote=True) + else: + conf.define('SHLIBEXT', "so", quote=True) + + # First try a header check for cross-compile friendlyness + conf.CHECK_CODE(code = """#ifdef __BYTE_ORDER + #define B __BYTE_ORDER + #elif defined(BYTE_ORDER) + #define B BYTE_ORDER + #endif + + #ifdef __LITTLE_ENDIAN + #define LITTLE __LITTLE_ENDIAN + #elif defined(LITTLE_ENDIAN) + #define LITTLE LITTLE_ENDIAN + #endif + + #if !defined(LITTLE) || !defined(B) || LITTLE != B + #error Not little endian. + #endif + int main(void) { return 0; }\n""", + addmain=False, + headers="endian.h sys/endian.h", + define="HAVE_LITTLE_ENDIAN") + conf.CHECK_CODE(code = """#ifdef __BYTE_ORDER + #define B __BYTE_ORDER + #elif defined(BYTE_ORDER) + #define B BYTE_ORDER + #endif + + #ifdef __BIG_ENDIAN + #define BIG __BIG_ENDIAN + #elif defined(BIG_ENDIAN) + #define BIG BIG_ENDIAN + #endif + + #if !defined(BIG) || !defined(B) || BIG != B + #error Not big endian. + #endif + int main(void) { return 0; }\n""", + addmain=False, + headers="endian.h sys/endian.h", + define="HAVE_BIG_ENDIAN") + + if not conf.CONFIG_SET("HAVE_BIG_ENDIAN") and not conf.CONFIG_SET("HAVE_LITTLE_ENDIAN"): + # That didn't work! Do runtime test. + conf.CHECK_CODE("""union { int i; char c[sizeof(int)]; } u; + u.i = 0x01020304; + return u.c[0] == 0x04 && u.c[1] == 0x03 && u.c[2] == 0x02 && u.c[3] == 0x01 ? 0 : 1;""", + addmain=True, execute=True, + define='HAVE_LITTLE_ENDIAN', + msg="Checking for HAVE_LITTLE_ENDIAN - runtime") + conf.CHECK_CODE("""union { int i; char c[sizeof(int)]; } u; + u.i = 0x01020304; + return u.c[0] == 0x01 && u.c[1] == 0x02 && u.c[2] == 0x03 && u.c[3] == 0x04 ? 0 : 1;""", + addmain=True, execute=True, + define='HAVE_BIG_ENDIAN', + msg="Checking for HAVE_BIG_ENDIAN - runtime") + + # Extra sanity check. + if conf.CONFIG_SET("HAVE_BIG_ENDIAN") == conf.CONFIG_SET("HAVE_LITTLE_ENDIAN"): + Logs.error("Failed endian determination. The PDP-11 is back?") + sys.exit(1) + else: + if conf.CONFIG_SET("HAVE_BIG_ENDIAN"): + conf.DEFINE('WORDS_BIGENDIAN', 1) + + # check if signal() takes a void function + if conf.CHECK_CODE('return *(signal (0, 0)) (0) == 1', + define='RETSIGTYPE_INT', + execute=False, + headers='signal.h', + msg='Checking if signal handlers return int'): + conf.DEFINE('RETSIGTYPE', 'int') + else: + conf.DEFINE('RETSIGTYPE', 'void') + + conf.CHECK_VARIABLE('__FUNCTION__', define='HAVE_FUNCTION_MACRO') + + conf.CHECK_CODE('va_list ap1,ap2; va_copy(ap1,ap2)', + define="HAVE_VA_COPY", + msg="Checking for va_copy") + + conf.CHECK_CODE(''' + #define eprintf(...) fprintf(stderr, __VA_ARGS__) + eprintf("bla", "bar") + ''', define='HAVE__VA_ARGS__MACRO') + + conf.SAMBA_BUILD_ENV() + + +def build(bld): + # give a more useful message if the source directory has moved + curdir = bld.path.abspath() + srcdir = bld.srcnode.abspath() + relpath = os_path_relpath(curdir, srcdir) + if relpath.find('../') != -1: + Logs.error('bld.path %s is not a child of %s' % (curdir, srcdir)) + raise Errors.WafError('''The top source directory has moved. Please run distclean and reconfigure''') + + bld.SETUP_BUILD_GROUPS() + bld.ENFORCE_GROUP_ORDERING() + bld.CHECK_PROJECT_RULES() diff --git a/ldb-2.0.8/common/attrib_handlers.c b/ldb-2.0.8/common/attrib_handlers.c new file mode 100644 index 0000000..b5212b7 --- /dev/null +++ b/ldb-2.0.8/common/attrib_handlers.c @@ -0,0 +1,639 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2005 + Copyright (C) Andrew Bartlett 2006-2009 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ +/* + attribute handlers for well known attribute types, selected by syntax OID + see rfc2252 +*/ + +#include "ldb_private.h" +#include "system/locale.h" +#include "ldb_handlers.h" + +/* + default handler that just copies a ldb_val. +*/ +int ldb_handler_copy(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + *out = ldb_val_dup(mem_ctx, in); + if (in->length > 0 && out->data == NULL) { + ldb_oom(ldb); + return -1; + } + return 0; +} + +/* + a case folding copy handler, removing leading and trailing spaces and + multiple internal spaces + + We exploit the fact that utf8 never uses the space octet except for + the space itself +*/ +int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + char *s, *t; + size_t l; + + if (!in || !out || !(in->data)) { + return -1; + } + + out->data = (uint8_t *)ldb_casefold(ldb, mem_ctx, (const char *)(in->data), in->length); + if (out->data == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_handler_fold: unable to casefold string [%.*s]", (int)in->length, (const char *)in->data); + return -1; + } + + s = (char *)(out->data); + + /* remove trailing spaces if any */ + l = strlen(s); + while (l > 0 && s[l - 1] == ' ') l--; + s[l] = '\0'; + + /* remove leading spaces if any */ + if (*s == ' ') { + for (t = s; *s == ' '; s++) ; + + /* remove leading spaces by moving down the string */ + memmove(t, s, l); + + s = t; + } + + /* check middle spaces */ + while ((t = strchr(s, ' ')) != NULL) { + for (s = t; *s == ' '; s++) ; + + if ((s - t) > 1) { + l = strlen(s); + + /* remove all spaces but one by moving down the string */ + memmove(t + 1, s, l); + } + } + + out->length = strlen((char *)out->data); + return 0; +} + +/* length limited conversion of a ldb_val to a int32_t */ +static int val_to_int64(const struct ldb_val *in, int64_t *v) +{ + char *end; + char buf[64]; + + /* make sure we don't read past the end of the data */ + if (in->length > sizeof(buf)-1) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + strncpy(buf, (char *)in->data, in->length); + buf[in->length] = 0; + + /* We've to use "strtoll" here to have the intended overflows. + * Otherwise we may get "LONG_MAX" and the conversion is wrong. */ + *v = (int64_t) strtoll(buf, &end, 0); + if (*end != 0) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + return LDB_SUCCESS; +} + + +/* + canonicalise a ldap Integer + rfc2252 specifies it should be in decimal form +*/ +static int ldb_canonicalise_Integer(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + int64_t i; + int ret; + + ret = val_to_int64(in, &i); + if (ret != LDB_SUCCESS) { + return ret; + } + out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%lld", (long long)i); + if (out->data == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + out->length = strlen((char *)out->data); + return 0; +} + +/* + * Lexicographically ordered format for a ldap Integer + * + * [ INT64_MIN ... -3, -2, -1 | 0 | +1, +2, +3 ... INT64_MAX ] + * n o p + * + * For human readability sake, we continue to format the key as a string + * (like the canonicalize) rather than store as a fixed binary representation. + * + * In order to sort the integers in the correct string order, there are three + * techniques we use: + * + * 1. Zero padding + * 2. Negative integer inversion + * 3. 1-byte prefixes: 'n' < 'o' < 'p' + * + * 1. To have a fixed-width representation so that 10 sorts after 2 rather than + * after 1, we zero pad, like this 4-byte width example: + * + * 0001, 0002, 0010 + * + * INT64_MAX = 2^63 - 1 = 9223372036854775807 (19 characters long) + * + * Meaning we need to pad to 19 characters. + * + * 2. This works for positive integers, but negative integers will still be + * sorted backwards, for example: + * + * -9223372036854775808 ..., -0000000000000000002, -0000000000000000001 + * INT64_MIN -2 -1 + * + * gets sorted based on string as: + * + * -0000000000000000001, -0000000000000000002, ... -9223372036854775808 + * + * In order to fix this, we invert the negative integer range, so that they + * get sorted the same way as positive numbers. INT64_MIN becomes the lowest + * possible non-negative number (zero), and -1 becomes the highest (INT64_MAX). + * + * The actual conversion applied to negative number 'x' is: + * INT64_MAX - abs(x) + 1 + * (The +1 is needed because abs(INT64_MIN) is one greater than INT64_MAX) + * + * 3. Finally, we now have two different numbers that map to the same key, e.g. + * INT64_MIN maps to -0000000000000000000 and zero maps to 0000000000000000000. + * In order to avoid confusion, we give every number a prefix representing its + * sign: 'n' for negative numbers, 'o' for zero, and 'p' for positive. (Note + * that '+' and '-' weren't used because they sort the wrong way). + * + * The result is a range of key values that look like this: + * + * n0000000000000000000, ... n9223372036854775807, + * INT64_MIN -1 + * + * o0000000000000000000, + * ZERO + * + * p0000000000000000001, ... p9223372036854775807 + * +1 INT64_MAX + */ +static int ldb_index_format_Integer(struct ldb_context *ldb, + void *mem_ctx, + const struct ldb_val *in, + struct ldb_val *out) +{ + int64_t i; + int ret; + char prefix; + size_t len; + + ret = val_to_int64(in, &i); + if (ret != LDB_SUCCESS) { + return ret; + } + + if (i < 0) { + /* + * i is negative, so this is subtraction rather than + * wrap-around. + */ + prefix = 'n'; + i = INT64_MAX + i + 1; + } else if (i > 0) { + prefix = 'p'; + } else { + prefix = 'o'; + } + + out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%c%019lld", prefix, (long long)i); + if (out->data == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + len = talloc_array_length(out->data) - 1; + if (len != 20) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + __location__ ": expected index format str %s to" + " have length 20 but got %zu", + (char*)out->data, len); + return LDB_ERR_OPERATIONS_ERROR; + } + + out->length = 20; + return 0; +} + +/* + compare two Integers +*/ +static int ldb_comparison_Integer(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, const struct ldb_val *v2) +{ + int64_t i1=0, i2=0; + val_to_int64(v1, &i1); + val_to_int64(v2, &i2); + if (i1 == i2) return 0; + return i1 > i2? 1 : -1; +} + +/* + canonicalise a ldap Boolean + rfc2252 specifies it should be either "TRUE" or "FALSE" +*/ +static int ldb_canonicalise_Boolean(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + if (in->length >= 4 && strncasecmp((char *)in->data, "TRUE", in->length) == 0) { + out->data = (uint8_t *)talloc_strdup(mem_ctx, "TRUE"); + out->length = 4; + } else if (in->length >= 5 && strncasecmp((char *)in->data, "FALSE", in->length) == 0) { + out->data = (uint8_t *)talloc_strdup(mem_ctx, "FALSE"); + out->length = 5; + } else { + return -1; + } + return 0; +} + +/* + compare two Booleans +*/ +static int ldb_comparison_Boolean(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, const struct ldb_val *v2) +{ + if (v1->length != v2->length) { + return v1->length - v2->length; + } + return strncasecmp((char *)v1->data, (char *)v2->data, v1->length); +} + + +/* + compare two binary blobs +*/ +int ldb_comparison_binary(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, const struct ldb_val *v2) +{ + if (v1->length != v2->length) { + return v1->length - v2->length; + } + return memcmp(v1->data, v2->data, v1->length); +} + +/* + compare two case insensitive strings, ignoring multiple whitespaces + and leading and trailing whitespaces + see rfc2252 section 8.1 + + try to optimize for the ascii case, + but if we find out an utf8 codepoint revert to slower but correct function +*/ +int ldb_comparison_fold(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, const struct ldb_val *v2) +{ + const char *s1=(const char *)v1->data, *s2=(const char *)v2->data; + size_t n1 = v1->length, n2 = v2->length; + char *b1, *b2; + const char *u1, *u2; + int ret; + while (n1 && *s1 == ' ') { s1++; n1--; }; + while (n2 && *s2 == ' ') { s2++; n2--; }; + + while (n1 && n2 && *s1 && *s2) { + /* the first 127 (0x7F) chars are ascii and utf8 guarantes they + * never appear in multibyte sequences */ + if (((unsigned char)s1[0]) & 0x80) goto utf8str; + if (((unsigned char)s2[0]) & 0x80) goto utf8str; + if (toupper((unsigned char)*s1) != toupper((unsigned char)*s2)) + break; + if (*s1 == ' ') { + while (n1 && s1[0] == s1[1]) { s1++; n1--; } + while (n2 && s2[0] == s2[1]) { s2++; n2--; } + } + s1++; s2++; + n1--; n2--; + } + + /* check for trailing spaces only if the other pointers has + * reached the end of the strings otherwise we can + * mistakenly match. ex. "domain users" <-> + * "domainUpdates" + */ + if (n1 && *s1 == ' ' && (!n2 || !*s2)) { + while (n1 && *s1 == ' ') { s1++; n1--; } + } + if (n2 && *s2 == ' ' && (!n1 || !*s1)) { + while (n2 && *s2 == ' ') { s2++; n2--; } + } + if (n1 == 0 && n2 != 0) { + return -(int)toupper(*s2); + } + if (n2 == 0 && n1 != 0) { + return (int)toupper(*s1); + } + if (n1 == 0 && n2 == 0) { + return 0; + } + return (int)toupper(*s1) - (int)toupper(*s2); + +utf8str: + /* no need to recheck from the start, just from the first utf8 char found */ + b1 = ldb_casefold(ldb, mem_ctx, s1, n1); + b2 = ldb_casefold(ldb, mem_ctx, s2, n2); + + if (!b1 || !b2) { + /* One of the strings was not UTF8, so we have no + * options but to do a binary compare */ + talloc_free(b1); + talloc_free(b2); + ret = memcmp(s1, s2, MIN(n1, n2)); + if (ret == 0) { + if (n1 == n2) return 0; + if (n1 > n2) { + return (int)toupper(s1[n2]); + } else { + return -(int)toupper(s2[n1]); + } + } + return ret; + } + + u1 = b1; + u2 = b2; + + while (*u1 & *u2) { + if (*u1 != *u2) + break; + if (*u1 == ' ') { + while (u1[0] == u1[1]) u1++; + while (u2[0] == u2[1]) u2++; + } + u1++; u2++; + } + if (! (*u1 && *u2)) { + while (*u1 == ' ') u1++; + while (*u2 == ' ') u2++; + } + ret = (int)(*u1 - *u2); + + talloc_free(b1); + talloc_free(b2); + + return ret; +} + + +/* + canonicalise a attribute in DN format +*/ +static int ldb_canonicalise_dn(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + struct ldb_dn *dn; + int ret = -1; + + out->length = 0; + out->data = NULL; + + dn = ldb_dn_from_ldb_val(mem_ctx, ldb, in); + if ( ! ldb_dn_validate(dn)) { + return LDB_ERR_INVALID_DN_SYNTAX; + } + + out->data = (uint8_t *)ldb_dn_alloc_casefold(mem_ctx, dn); + if (out->data == NULL) { + goto done; + } + out->length = strlen((char *)out->data); + + ret = 0; + +done: + talloc_free(dn); + + return ret; +} + +/* + compare two dns +*/ +static int ldb_comparison_dn(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, const struct ldb_val *v2) +{ + struct ldb_dn *dn1 = NULL, *dn2 = NULL; + int ret; + + dn1 = ldb_dn_from_ldb_val(mem_ctx, ldb, v1); + if ( ! ldb_dn_validate(dn1)) return -1; + + dn2 = ldb_dn_from_ldb_val(mem_ctx, ldb, v2); + if ( ! ldb_dn_validate(dn2)) { + talloc_free(dn1); + return -1; + } + + ret = ldb_dn_compare(dn1, dn2); + + talloc_free(dn1); + talloc_free(dn2); + return ret; +} + +/* + compare two utc time values. 1 second resolution +*/ +static int ldb_comparison_utctime(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, const struct ldb_val *v2) +{ + time_t t1=0, t2=0; + ldb_val_to_time(v1, &t1); + ldb_val_to_time(v2, &t2); + if (t1 == t2) return 0; + return t1 > t2? 1 : -1; +} + +/* + canonicalise a utc time +*/ +static int ldb_canonicalise_utctime(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + time_t t; + int ret; + ret = ldb_val_to_time(in, &t); + if (ret != LDB_SUCCESS) { + return ret; + } + out->data = (uint8_t *)ldb_timestring_utc(mem_ctx, t); + if (out->data == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + out->length = strlen((char *)out->data); + return 0; +} + +/* + canonicalise a generalized time +*/ +static int ldb_canonicalise_generalizedtime(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + time_t t; + int ret; + ret = ldb_val_to_time(in, &t); + if (ret != LDB_SUCCESS) { + return ret; + } + out->data = (uint8_t *)ldb_timestring(mem_ctx, t); + if (out->data == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + out->length = strlen((char *)out->data); + return 0; +} + +/* + table of standard attribute handlers +*/ +static const struct ldb_schema_syntax ldb_standard_syntaxes[] = { + { + .name = LDB_SYNTAX_INTEGER, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = ldb_canonicalise_Integer, + .comparison_fn = ldb_comparison_Integer + }, + { + .name = LDB_SYNTAX_ORDERED_INTEGER, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = ldb_canonicalise_Integer, + .index_format_fn = ldb_index_format_Integer, + .comparison_fn = ldb_comparison_Integer + }, + { + .name = LDB_SYNTAX_OCTET_STRING, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = ldb_handler_copy, + .comparison_fn = ldb_comparison_binary + }, + { + .name = LDB_SYNTAX_DIRECTORY_STRING, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = ldb_handler_fold, + .comparison_fn = ldb_comparison_fold + }, + { + .name = LDB_SYNTAX_DN, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = ldb_canonicalise_dn, + .comparison_fn = ldb_comparison_dn + }, + { + .name = LDB_SYNTAX_OBJECTCLASS, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = ldb_handler_fold, + .comparison_fn = ldb_comparison_fold + }, + { + .name = LDB_SYNTAX_UTC_TIME, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = ldb_canonicalise_utctime, + .comparison_fn = ldb_comparison_utctime + }, + { + .name = LDB_SYNTAX_GENERALIZED_TIME, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = ldb_canonicalise_generalizedtime, + .comparison_fn = ldb_comparison_utctime + }, + { + .name = LDB_SYNTAX_BOOLEAN, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = ldb_canonicalise_Boolean, + .comparison_fn = ldb_comparison_Boolean + }, +}; + + +/* + return the attribute handlers for a given syntax name +*/ +const struct ldb_schema_syntax *ldb_standard_syntax_by_name(struct ldb_context *ldb, + const char *syntax) +{ + unsigned int i; + unsigned num_handlers = sizeof(ldb_standard_syntaxes)/sizeof(ldb_standard_syntaxes[0]); + /* TODO: should be replaced with a binary search */ + for (i=0;i. +*/ + +/* + * Name: ldb + * + * Component: ldb core API + * + * Description: core API routines interfacing to ldb backends + * + * Author: Andrew Tridgell + */ + +#define TEVENT_DEPRECATED 1 +#include "ldb_private.h" +#include "ldb.h" + +static int ldb_context_destructor(void *ptr) +{ + struct ldb_context *ldb = talloc_get_type(ptr, struct ldb_context); + + if (ldb->transaction_active) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "A transaction is still active in ldb context [%p] on %s", + ldb, (const char *)ldb_get_opaque(ldb, "ldb_url")); + } + + return 0; +} + +/* + this is used to catch debug messages from events +*/ +static void ldb_tevent_debug(void *context, enum tevent_debug_level level, + const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); + +static void ldb_tevent_debug(void *context, enum tevent_debug_level level, + const char *fmt, va_list ap) +{ + struct ldb_context *ldb = talloc_get_type(context, struct ldb_context); + enum ldb_debug_level ldb_level = LDB_DEBUG_FATAL; + + switch (level) { + case TEVENT_DEBUG_FATAL: + ldb_level = LDB_DEBUG_FATAL; + break; + case TEVENT_DEBUG_ERROR: + ldb_level = LDB_DEBUG_ERROR; + break; + case TEVENT_DEBUG_WARNING: + ldb_level = LDB_DEBUG_WARNING; + break; + case TEVENT_DEBUG_TRACE: + ldb_level = LDB_DEBUG_TRACE; + break; + }; + + /* There isn't a tevent: prefix here because to add it means + * actually printing the string, and most of the time we don't + * want to show it */ + ldb_vdebug(ldb, ldb_level, fmt, ap); +} + +/* + initialise a ldb context + The mem_ctx is required + The event_ctx is required +*/ +struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx) +{ + struct ldb_context *ldb; + int ret; + const char *modules_path = getenv("LDB_MODULES_PATH"); + + if (modules_path == NULL) { + modules_path = LDB_MODULESDIR; + } + + ret = ldb_modules_load(modules_path, LDB_VERSION); + if (ret != LDB_SUCCESS) { + return NULL; + } + + ldb = talloc_zero(mem_ctx, struct ldb_context); + if (ldb == NULL) { + return NULL; + } + + /* A new event context so that callers who don't want ldb + * operating on their global event context can work without + * having to provide their own private one explicitly */ + if (ev_ctx == NULL) { + ev_ctx = tevent_context_init(ldb); + if (ev_ctx == NULL) { + talloc_free(ldb); + return NULL; + } + tevent_set_debug(ev_ctx, ldb_tevent_debug, ldb); + tevent_loop_allow_nesting(ev_ctx); + } + + ret = ldb_setup_wellknown_attributes(ldb); + if (ret != LDB_SUCCESS) { + talloc_free(ldb); + return NULL; + } + + ldb_set_utf8_default(ldb); + ldb_set_create_perms(ldb, 0666); + ldb_set_modules_dir(ldb, LDB_MODULESDIR); + ldb_set_event_context(ldb, ev_ctx); + ret = ldb_register_extended_match_rules(ldb); + if (ret != LDB_SUCCESS) { + talloc_free(ldb); + return NULL; + } + + /* TODO: get timeout from options if available there */ + ldb->default_timeout = 300; /* set default to 5 minutes */ + + talloc_set_destructor((TALLOC_CTX *)ldb, ldb_context_destructor); + + return ldb; +} + +/* + try to autodetect a basedn if none specified. This fixes one of my + pet hates about ldapsearch, which is that you have to get a long, + complex basedn right to make any use of it. +*/ +void ldb_set_default_dns(struct ldb_context *ldb) +{ + TALLOC_CTX *tmp_ctx; + int ret; + struct ldb_result *res; + struct ldb_dn *tmp_dn=NULL; + static const char *attrs[] = { + "rootDomainNamingContext", + "configurationNamingContext", + "schemaNamingContext", + "defaultNamingContext", + NULL + }; + + tmp_ctx = talloc_new(ldb); + ret = ldb_search(ldb, tmp_ctx, &res, ldb_dn_new(tmp_ctx, ldb, NULL), + LDB_SCOPE_BASE, attrs, "(objectClass=*)"); + if (ret != LDB_SUCCESS) { + talloc_free(tmp_ctx); + return; + } + + if (res->count != 1) { + talloc_free(tmp_ctx); + return; + } + + if (!ldb_get_opaque(ldb, "rootDomainNamingContext")) { + tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], + "rootDomainNamingContext"); + ldb_set_opaque(ldb, "rootDomainNamingContext", tmp_dn); + } + + if (!ldb_get_opaque(ldb, "configurationNamingContext")) { + tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], + "configurationNamingContext"); + ldb_set_opaque(ldb, "configurationNamingContext", tmp_dn); + } + + if (!ldb_get_opaque(ldb, "schemaNamingContext")) { + tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], + "schemaNamingContext"); + ldb_set_opaque(ldb, "schemaNamingContext", tmp_dn); + } + + if (!ldb_get_opaque(ldb, "defaultNamingContext")) { + tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], + "defaultNamingContext"); + ldb_set_opaque(ldb, "defaultNamingContext", tmp_dn); + } + + talloc_free(tmp_ctx); +} + +struct ldb_dn *ldb_get_root_basedn(struct ldb_context *ldb) +{ + void *opaque = ldb_get_opaque(ldb, "rootDomainNamingContext"); + return talloc_get_type(opaque, struct ldb_dn); +} + +struct ldb_dn *ldb_get_config_basedn(struct ldb_context *ldb) +{ + void *opaque = ldb_get_opaque(ldb, "configurationNamingContext"); + return talloc_get_type(opaque, struct ldb_dn); +} + +struct ldb_dn *ldb_get_schema_basedn(struct ldb_context *ldb) +{ + void *opaque = ldb_get_opaque(ldb, "schemaNamingContext"); + return talloc_get_type(opaque, struct ldb_dn); +} + +struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb) +{ + void *opaque = ldb_get_opaque(ldb, "defaultNamingContext"); + return talloc_get_type(opaque, struct ldb_dn); +} + +/* + connect to a database. The URL can either be one of the following forms + ldb://path + ldapi://path + + flags is made up of LDB_FLG_* + + the options are passed uninterpreted to the backend, and are + backend specific +*/ +int ldb_connect(struct ldb_context *ldb, const char *url, + unsigned int flags, const char *options[]) +{ + int ret; + char *url2; + /* We seem to need to do this here, or else some utilities don't + * get ldb backends */ + + ldb->flags = flags; + + url2 = talloc_strdup(ldb, url); + if (!url2) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + ret = ldb_set_opaque(ldb, "ldb_url", url2); + if (ret != LDB_SUCCESS) { + return ret; + } + + /* + * Take a copy of the options. + */ + ldb->options = ldb_options_copy(ldb, options); + if (ldb->options == NULL && options != NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_module_connect_backend(ldb, url, options, &ldb->modules); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_load_modules(ldb, options); + if (ret != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "Unable to load modules for %s: %s", + url, ldb_errstring(ldb)); + return ret; + } + + /* set the default base dn */ + ldb_set_default_dns(ldb); + + return LDB_SUCCESS; +} + +void ldb_set_errstring(struct ldb_context *ldb, const char *err_string) +{ + ldb_asprintf_errstring(ldb, "%s", err_string); +} + +void ldb_asprintf_errstring(struct ldb_context *ldb, const char *format, ...) +{ + va_list ap; + char *old_err_string = NULL; + if (ldb->err_string) { + old_err_string = ldb->err_string; + } + + va_start(ap, format); + ldb->err_string = talloc_vasprintf(ldb, format, ap); + va_end(ap); + + TALLOC_FREE(old_err_string); + + if (ldb->flags & LDB_FLG_ENABLE_TRACING) { + ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_asprintf/set_errstring: %s", + ldb->err_string); + } +} + +void ldb_reset_err_string(struct ldb_context *ldb) +{ + if (ldb->err_string) { + talloc_free(ldb->err_string); + ldb->err_string = NULL; + } +} + + + +/* + set an ldb error based on file:line +*/ +int ldb_error_at(struct ldb_context *ldb, int ecode, + const char *reason, const char *file, int line) +{ + if (reason == NULL) { + reason = ldb_strerror(ecode); + } + ldb_asprintf_errstring(ldb, "%s at %s:%d", reason, file, line); + return ecode; +} + + +#define FIRST_OP_NOERR(ldb, op) do { \ + next_module = ldb->modules; \ + while (next_module && next_module->ops->op == NULL) { \ + next_module = next_module->next; \ + }; \ + if ((ldb->flags & LDB_FLG_ENABLE_TRACING) && next_module) { \ + ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_trace_request: (%s)->" #op, \ + next_module->ops->name); \ + } \ +} while (0) + +#define FIRST_OP(ldb, op) do { \ + FIRST_OP_NOERR(ldb, op); \ + if (next_module == NULL) { \ + ldb_asprintf_errstring(ldb, "unable to find module or backend to handle operation: " #op); \ + return LDB_ERR_OPERATIONS_ERROR; \ + } \ +} while (0) + + +/* + start a transaction +*/ +int ldb_transaction_start(struct ldb_context *ldb) +{ + struct ldb_module *next_module; + int status; + + ldb_debug(ldb, LDB_DEBUG_TRACE, + "start ldb transaction (nesting: %d)", + ldb->transaction_active); + + /* explicit transaction active, count nested requests */ + if (ldb->transaction_active) { + ldb->transaction_active++; + return LDB_SUCCESS; + } + + /* start a new transaction */ + ldb->transaction_active++; + ldb->prepare_commit_done = false; + + FIRST_OP(ldb, start_transaction); + + ldb_reset_err_string(ldb); + + status = next_module->ops->start_transaction(next_module); + if (status != LDB_SUCCESS) { + if (ldb->err_string == NULL) { + /* no error string was setup by the backend */ + ldb_asprintf_errstring(ldb, + "ldb transaction start: %s (%d)", + ldb_strerror(status), + status); + ldb->transaction_active--; + } + if ((next_module && next_module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { + ldb_debug(next_module->ldb, LDB_DEBUG_TRACE, "start ldb transaction error: %s", + ldb_errstring(next_module->ldb)); + } + } else { + if ((next_module && next_module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { + ldb_debug(next_module->ldb, LDB_DEBUG_TRACE, "start ldb transaction success"); + } + } + return status; +} + +/* + prepare for transaction commit (first phase of two phase commit) +*/ +int ldb_transaction_prepare_commit(struct ldb_context *ldb) +{ + struct ldb_module *next_module; + int status; + + if (ldb->prepare_commit_done) { + return LDB_SUCCESS; + } + + /* commit only when all nested transactions are complete */ + if (ldb->transaction_active > 1) { + return LDB_SUCCESS; + } + + ldb->prepare_commit_done = true; + + if (ldb->transaction_active < 0) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "prepare commit called but no ldb transactions are active!"); + ldb->transaction_active = 0; + return LDB_ERR_OPERATIONS_ERROR; + } + + /* call prepare transaction if available */ + FIRST_OP_NOERR(ldb, prepare_commit); + if (next_module == NULL) { + return LDB_SUCCESS; + } + + ldb_reset_err_string(ldb); + + status = next_module->ops->prepare_commit(next_module); + if (status != LDB_SUCCESS) { + ldb->transaction_active--; + /* if a next_module fails the prepare then we need + to call the end transaction for everyone */ + FIRST_OP(ldb, del_transaction); + next_module->ops->del_transaction(next_module); + if (ldb->err_string == NULL) { + /* no error string was setup by the backend */ + ldb_asprintf_errstring(ldb, + "ldb transaction prepare commit: %s (%d)", + ldb_strerror(status), + status); + } + if ((next_module && next_module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { + ldb_debug(next_module->ldb, LDB_DEBUG_TRACE, "prepare commit transaction error: %s", + ldb_errstring(next_module->ldb)); + } + } + + return status; +} + + +/* + commit a transaction +*/ +int ldb_transaction_commit(struct ldb_context *ldb) +{ + struct ldb_module *next_module; + int status; + + status = ldb_transaction_prepare_commit(ldb); + if (status != LDB_SUCCESS) { + return status; + } + + ldb->transaction_active--; + + ldb_debug(ldb, LDB_DEBUG_TRACE, + "commit ldb transaction (nesting: %d)", + ldb->transaction_active); + + /* commit only when all nested transactions are complete */ + if (ldb->transaction_active > 0) { + return LDB_SUCCESS; + } + + if (ldb->transaction_active < 0) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "commit called but no ldb transactions are active!"); + ldb->transaction_active = 0; + return LDB_ERR_OPERATIONS_ERROR; + } + + ldb_reset_err_string(ldb); + + FIRST_OP(ldb, end_transaction); + status = next_module->ops->end_transaction(next_module); + if (status != LDB_SUCCESS) { + if (ldb->err_string == NULL) { + /* no error string was setup by the backend */ + ldb_asprintf_errstring(ldb, + "ldb transaction commit: %s (%d)", + ldb_strerror(status), + status); + } + if ((next_module && next_module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { + ldb_debug(next_module->ldb, LDB_DEBUG_TRACE, "commit ldb transaction error: %s", + ldb_errstring(next_module->ldb)); + } + } + return status; +} + + +/* + cancel a transaction +*/ +int ldb_transaction_cancel(struct ldb_context *ldb) +{ + struct ldb_module *next_module; + int status; + + ldb->transaction_active--; + + ldb_debug(ldb, LDB_DEBUG_TRACE, + "cancel ldb transaction (nesting: %d)", + ldb->transaction_active); + + /* really cancel only if all nested transactions are complete */ + if (ldb->transaction_active > 0) { + return LDB_SUCCESS; + } + + if (ldb->transaction_active < 0) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "cancel called but no ldb transactions are active!"); + ldb->transaction_active = 0; + return LDB_ERR_OPERATIONS_ERROR; + } + + FIRST_OP(ldb, del_transaction); + + status = next_module->ops->del_transaction(next_module); + if (status != LDB_SUCCESS) { + if (ldb->err_string == NULL) { + /* no error string was setup by the backend */ + ldb_asprintf_errstring(ldb, + "ldb transaction cancel: %s (%d)", + ldb_strerror(status), + status); + } + if ((next_module && next_module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { + ldb_debug(next_module->ldb, LDB_DEBUG_TRACE, "cancel ldb transaction error: %s", + ldb_errstring(next_module->ldb)); + } + } + return status; +} + +/* + cancel a transaction with no error if no transaction is pending + used when we fork() to clear any parent transactions +*/ +int ldb_transaction_cancel_noerr(struct ldb_context *ldb) +{ + if (ldb->transaction_active > 0) { + return ldb_transaction_cancel(ldb); + } + return LDB_SUCCESS; +} + + +/* autostarts a transaction if none active */ +static int ldb_autotransaction_request(struct ldb_context *ldb, + struct ldb_request *req) +{ + int ret; + + ret = ldb_transaction_start(ldb); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_request(ldb, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + if (ret == LDB_SUCCESS) { + return ldb_transaction_commit(ldb); + } + ldb_transaction_cancel(ldb); + + return ret; +} + +int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type) +{ + struct tevent_context *ev; + int ret; + + if (handle == NULL) { + return LDB_ERR_UNAVAILABLE; + } + + if (handle->state == LDB_ASYNC_DONE) { + if ((handle->status != LDB_SUCCESS) && + (handle->ldb->err_string == NULL)) { + /* if no error string was setup by the backend */ + ldb_asprintf_errstring(handle->ldb, + "ldb_wait from %s with LDB_ASYNC_DONE: %s (%d)", + handle->location, + ldb_strerror(handle->status), + handle->status); + } + return handle->status; + } + + ev = ldb_handle_get_event_context(handle); + if (NULL == ev) { + return ldb_oom(handle->ldb); + } + + switch (type) { + case LDB_WAIT_NONE: + ret = tevent_loop_once(ev); + if (ret != 0) { + return ldb_operr(handle->ldb); + } + if (handle->status == LDB_SUCCESS) { + return LDB_SUCCESS; + } + if (handle->ldb->err_string != NULL) { + return handle->status; + } + /* + * if no error string was setup by the backend + */ + ldb_asprintf_errstring(handle->ldb, + "ldb_wait from %s with LDB_WAIT_NONE: %s (%d)", + handle->location, + ldb_strerror(handle->status), + handle->status); + return handle->status; + + case LDB_WAIT_ALL: + while (handle->state != LDB_ASYNC_DONE) { + ret = tevent_loop_once(ev); + if (ret != 0) { + return ldb_operr(handle->ldb); + } + if (handle->status != LDB_SUCCESS) { + if (handle->ldb->err_string != NULL) { + return handle->status; + } + /* + * if no error string was setup by the + * backend + */ + ldb_asprintf_errstring(handle->ldb, + "ldb_wait from %s with " + "LDB_WAIT_ALL: %s (%d)", + handle->location, + ldb_strerror(handle->status), + handle->status); + return handle->status; + } + } + if (handle->status == LDB_SUCCESS) { + return LDB_SUCCESS; + } + if (handle->ldb->err_string != NULL) { + return handle->status; + } + /* + * if no error string was setup by the backend + */ + ldb_asprintf_errstring(handle->ldb, + "ldb_wait from %s with LDB_WAIT_ALL," + " LDB_ASYNC_DONE: %s (%d)", + handle->location, + ldb_strerror(handle->status), + handle->status); + return handle->status; + } + + return LDB_SUCCESS; +} + +/* set the specified timeout or, if timeout is 0 set the default timeout */ +int ldb_set_timeout(struct ldb_context *ldb, + struct ldb_request *req, + int timeout) +{ + if (req == NULL) return LDB_ERR_OPERATIONS_ERROR; + + if (timeout != 0) { + req->timeout = timeout; + } else { + req->timeout = ldb->default_timeout; + } + req->starttime = time(NULL); + + return LDB_SUCCESS; +} + +/* calculates the new timeout based on the previous starttime and timeout */ +int ldb_set_timeout_from_prev_req(struct ldb_context *ldb, + struct ldb_request *oldreq, + struct ldb_request *newreq) +{ + if (newreq == NULL) return LDB_ERR_OPERATIONS_ERROR; + + if (oldreq == NULL) { + return ldb_set_timeout(ldb, newreq, 0); + } + + newreq->starttime = oldreq->starttime; + newreq->timeout = oldreq->timeout; + + return LDB_SUCCESS; +} + + +struct ldb_handle *ldb_handle_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb) +{ + struct ldb_handle *h; + + h = talloc_zero(mem_ctx, struct ldb_handle); + if (h == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return NULL; + } + + h->status = LDB_SUCCESS; + h->state = LDB_ASYNC_INIT; + h->ldb = ldb; + h->flags = 0; + h->location = NULL; + h->parent = NULL; + + if (h->ldb->require_private_event_context == true) { + h->event_context = tevent_context_init(h); + if (h->event_context == NULL) { + ldb_set_errstring(ldb, + "Out of Memory allocating " + "event context for new handle"); + return NULL; + } + tevent_set_debug(h->event_context, ldb_tevent_debug, ldb); + tevent_loop_allow_nesting(h->event_context); + } + + return h; +} + +static struct ldb_handle *ldb_handle_new_child(TALLOC_CTX *mem_ctx, + struct ldb_request *parent_req) +{ + struct ldb_handle *h; + + h = talloc_zero(mem_ctx, struct ldb_handle); + if (h == NULL) { + ldb_set_errstring(parent_req->handle->ldb, + "Out of Memory"); + return NULL; + } + + h->status = LDB_SUCCESS; + h->state = LDB_ASYNC_INIT; + h->ldb = parent_req->handle->ldb; + h->parent = parent_req; + h->nesting = parent_req->handle->nesting + 1; + h->flags = parent_req->handle->flags; + h->custom_flags = parent_req->handle->custom_flags; + h->event_context = parent_req->handle->event_context; + + return h; +} + +/* + set the permissions for new files to be passed to open() in + backends that use local files + */ +void ldb_set_create_perms(struct ldb_context *ldb, unsigned int perms) +{ + ldb->create_perms = perms; +} + +unsigned int ldb_get_create_perms(struct ldb_context *ldb) +{ + return ldb->create_perms; +} + +void ldb_set_event_context(struct ldb_context *ldb, struct tevent_context *ev) +{ + ldb->ev_ctx = ev; +} + +struct tevent_context * ldb_get_event_context(struct ldb_context *ldb) +{ + return ldb->ev_ctx; +} + +void ldb_request_set_state(struct ldb_request *req, int state) +{ + req->handle->state = state; +} + +int ldb_request_get_status(struct ldb_request *req) +{ + return req->handle->status; +} + +/* + * This function obtains the private event context for the handle, + * which may have been created to avoid nested event loops during + * ldb_tdb with the locks held + */ +struct tevent_context *ldb_handle_get_event_context(struct ldb_handle *handle) +{ + if (handle->event_context != NULL) { + return handle->event_context; + } + return ldb_get_event_context(handle->ldb); +} + +/* + * This function forces a specific ldb handle to use the global event + * context. This allows a nested event loop to operate, so any open + * transaction also needs to be aborted. + * + * Any events on this event context will be lost + * + * This is used in Samba when sending an IRPC to another part of the + * same process instead of making a local DB modification. + */ +void ldb_handle_use_global_event_context(struct ldb_handle *handle) +{ + TALLOC_FREE(handle->event_context); +} + +void ldb_set_require_private_event_context(struct ldb_context *ldb) +{ + ldb->require_private_event_context = true; +} + +/* + trace a ldb request +*/ +static void ldb_trace_request(struct ldb_context *ldb, struct ldb_request *req) +{ + TALLOC_CTX *tmp_ctx = talloc_new(req); + unsigned int i; + struct ldb_ldif ldif; + + switch (req->operation) { + case LDB_SEARCH: + ldb_debug_add(ldb, "ldb_trace_request: SEARCH\n"); + ldb_debug_add(ldb, " dn: %s\n", + ldb_dn_is_null(req->op.search.base)?"": + ldb_dn_get_linearized(req->op.search.base)); + ldb_debug_add(ldb, " scope: %s\n", + req->op.search.scope==LDB_SCOPE_BASE?"base": + req->op.search.scope==LDB_SCOPE_ONELEVEL?"one": + req->op.search.scope==LDB_SCOPE_SUBTREE?"sub":"UNKNOWN"); + ldb_debug_add(ldb, " expr: %s\n", + ldb_filter_from_tree(tmp_ctx, req->op.search.tree)); + if (req->op.search.attrs == NULL) { + ldb_debug_add(ldb, " attr: \n"); + } else { + for (i=0; req->op.search.attrs[i]; i++) { + ldb_debug_add(ldb, " attr: %s\n", req->op.search.attrs[i]); + } + } + break; + case LDB_DELETE: + ldb_debug_add(ldb, "ldb_trace_request: DELETE\n"); + ldb_debug_add(ldb, " dn: %s\n", + ldb_dn_get_linearized(req->op.del.dn)); + break; + case LDB_RENAME: + ldb_debug_add(ldb, "ldb_trace_request: RENAME\n"); + ldb_debug_add(ldb, " olddn: %s\n", + ldb_dn_get_linearized(req->op.rename.olddn)); + ldb_debug_add(ldb, " newdn: %s\n", + ldb_dn_get_linearized(req->op.rename.newdn)); + break; + case LDB_EXTENDED: + ldb_debug_add(ldb, "ldb_trace_request: EXTENDED\n"); + ldb_debug_add(ldb, " oid: %s\n", req->op.extended.oid); + ldb_debug_add(ldb, " data: %s\n", req->op.extended.data?"yes":"no"); + break; + case LDB_ADD: + ldif.changetype = LDB_CHANGETYPE_ADD; + ldif.msg = discard_const_p(struct ldb_message, req->op.add.message); + + ldb_debug_add(ldb, "ldb_trace_request: ADD\n"); + + /* + * The choice to call + * ldb_ldif_write_redacted_trace_string() is CRITICAL + * for security. It ensures that we do not output + * passwords into debug logs + */ + + ldb_debug_add(req->handle->ldb, "%s\n", + ldb_ldif_write_redacted_trace_string(req->handle->ldb, tmp_ctx, &ldif)); + break; + case LDB_MODIFY: + ldif.changetype = LDB_CHANGETYPE_MODIFY; + ldif.msg = discard_const_p(struct ldb_message, req->op.mod.message); + + ldb_debug_add(ldb, "ldb_trace_request: MODIFY\n"); + + /* + * The choice to call + * ldb_ldif_write_redacted_trace_string() is CRITICAL + * for security. It ensures that we do not output + * passwords into debug logs + */ + + ldb_debug_add(req->handle->ldb, "%s\n", + ldb_ldif_write_redacted_trace_string(req->handle->ldb, tmp_ctx, &ldif)); + break; + case LDB_REQ_REGISTER_CONTROL: + ldb_debug_add(ldb, "ldb_trace_request: REGISTER_CONTROL\n"); + ldb_debug_add(req->handle->ldb, "%s\n", + req->op.reg_control.oid); + break; + case LDB_REQ_REGISTER_PARTITION: + ldb_debug_add(ldb, "ldb_trace_request: REGISTER_PARTITION\n"); + ldb_debug_add(req->handle->ldb, "%s\n", + ldb_dn_get_linearized(req->op.reg_partition.dn)); + break; + default: + ldb_debug_add(ldb, "ldb_trace_request: UNKNOWN(%u)\n", + req->operation); + break; + } + + if (req->controls == NULL) { + ldb_debug_add(ldb, " control: \n"); + } else { + for (i=0; req->controls && req->controls[i]; i++) { + if (req->controls[i]->oid) { + ldb_debug_add(ldb, " control: %s crit:%u data:%s\n", + req->controls[i]->oid, + req->controls[i]->critical, + req->controls[i]->data?"yes":"no"); + } + } + } + + ldb_debug_end(ldb, LDB_DEBUG_TRACE); + + talloc_free(tmp_ctx); +} + +/* + check that the element flags don't have any internal bits set + */ +static int ldb_msg_check_element_flags(struct ldb_context *ldb, + const struct ldb_message *message) +{ + unsigned i; + for (i=0; inum_elements; i++) { + if (message->elements[i].flags & LDB_FLAG_INTERNAL_MASK) { + ldb_asprintf_errstring(ldb, "Invalid element flags 0x%08x on element %s in %s\n", + message->elements[i].flags, message->elements[i].name, + ldb_dn_get_linearized(message->dn)); + return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; + } + } + return LDB_SUCCESS; +} + +/* + * This context allows us to make the unlock be a talloc destructor + * + * This ensures that a request started, but not waited on, will still + * unlock. + */ +struct ldb_db_lock_context { + struct ldb_request *req; + struct ldb_context *ldb; +}; + +/* + * We have to have a the unlock on a destructor so that we unlock the + * DB if a caller calls talloc_free(req). We trust that the ldb + * context has not already gone away. + */ +static int ldb_db_lock_destructor(struct ldb_db_lock_context *lock_context) +{ + int ret; + struct ldb_module *next_module; + FIRST_OP_NOERR(lock_context->ldb, read_unlock); + if (next_module != NULL) { + ret = next_module->ops->read_unlock(next_module); + } else { + ret = LDB_SUCCESS; + } + + if (ret != LDB_SUCCESS) { + ldb_debug(lock_context->ldb, + LDB_DEBUG_FATAL, + "Failed to unlock db: %s / %s", + ldb_errstring(lock_context->ldb), + ldb_strerror(ret)); + } + return 0; +} + +static int ldb_lock_backend_callback(struct ldb_request *req, + struct ldb_reply *ares) +{ + struct ldb_db_lock_context *lock_context; + int ret; + + lock_context = talloc_get_type(req->context, + struct ldb_db_lock_context); + + if (!ares) { + return ldb_module_done(lock_context->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS || ares->type == LDB_REPLY_DONE) { + ret = ldb_module_done(lock_context->req, ares->controls, + ares->response, ares->error); + /* + * If this is a LDB_REPLY_DONE or an error, unlock the + * DB by calling the destructor on this context + */ + talloc_free(lock_context); + return ret; + } + + /* Otherwise pass on the callback */ + switch (ares->type) { + case LDB_REPLY_ENTRY: + return ldb_module_send_entry(lock_context->req, ares->message, + ares->controls); + + case LDB_REPLY_REFERRAL: + return ldb_module_send_referral(lock_context->req, + ares->referral); + default: + /* Can't happen */ + return LDB_ERR_OPERATIONS_ERROR; + } +} + +/* + * Do an ldb_search() with a lock held, but release it if the request + * is freed with talloc_free() + */ +static int lock_search(struct ldb_module *lock_module, struct ldb_request *req) +{ + /* Used in FIRST_OP_NOERR to find where to send the lock request */ + struct ldb_module *next_module = NULL; + struct ldb_request *down_req = NULL; + struct ldb_db_lock_context *lock_context; + struct ldb_context *ldb = ldb_module_get_ctx(lock_module); + int ret; + + lock_context = talloc(req, struct ldb_db_lock_context); + if (lock_context == NULL) { + return ldb_oom(ldb); + } + + lock_context->ldb = ldb; + lock_context->req = req; + + ret = ldb_build_search_req_ex(&down_req, ldb, req, + req->op.search.base, + req->op.search.scope, + req->op.search.tree, + req->op.search.attrs, + req->controls, + lock_context, + ldb_lock_backend_callback, + req); + LDB_REQ_SET_LOCATION(down_req); + if (ret != LDB_SUCCESS) { + return ret; + } + + /* call DB lock */ + FIRST_OP_NOERR(ldb, read_lock); + if (next_module != NULL) { + ret = next_module->ops->read_lock(next_module); + } else { + ret = LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; + } + + if (ret == LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION) { + /* We might be talking LDAP */ + ldb_reset_err_string(ldb); + TALLOC_FREE(lock_context); + + return ldb_next_request(lock_module, req); + } else if ((ret != LDB_SUCCESS) && (ldb->err_string == NULL)) { + /* if no error string was setup by the backend */ + ldb_asprintf_errstring(ldb, "Failed to get DB lock: %s (%d)", + ldb_strerror(ret), ret); + } else { + talloc_set_destructor(lock_context, ldb_db_lock_destructor); + } + + if (ret != LDB_SUCCESS) { + return ret; + } + + return ldb_next_request(lock_module, down_req); +} + +/* + start an ldb request + NOTE: the request must be a talloc context. + returns LDB_ERR_* on errors. +*/ +int ldb_request(struct ldb_context *ldb, struct ldb_request *req) +{ + struct ldb_module *next_module; + int ret; + + if (req->callback == NULL) { + ldb_set_errstring(ldb, "Requests MUST define callbacks"); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + ldb_reset_err_string(ldb); + + if (ldb->flags & LDB_FLG_ENABLE_TRACING) { + ldb_trace_request(ldb, req); + } + + /* call the first module in the chain */ + switch (req->operation) { + case LDB_SEARCH: + { + /* + * A fake module to allow ldb_next_request() to be + * re-used and to keep the locking out of this function. + */ + static const struct ldb_module_ops lock_module_ops = { + .name = "lock_searches", + .search = lock_search + }; + struct ldb_module lock_module = { + .ldb = ldb, + .next = ldb->modules, + .ops = &lock_module_ops + }; + next_module = &lock_module; + + /* due to "ldb_build_search_req" base DN always != NULL */ + if (!ldb_dn_validate(req->op.search.base)) { + ldb_asprintf_errstring(ldb, "ldb_search: invalid basedn '%s'", + ldb_dn_get_linearized(req->op.search.base)); + return LDB_ERR_INVALID_DN_SYNTAX; + } + + ret = next_module->ops->search(next_module, req); + break; + } + case LDB_ADD: + if (!ldb_dn_validate(req->op.add.message->dn)) { + ldb_asprintf_errstring(ldb, "ldb_add: invalid dn '%s'", + ldb_dn_get_linearized(req->op.add.message->dn)); + return LDB_ERR_INVALID_DN_SYNTAX; + } + /* + * we have to normalize here, as so many places + * in modules and backends assume we don't have two + * elements with the same name + */ + ret = ldb_msg_normalize(ldb, req, req->op.add.message, + discard_const(&req->op.add.message)); + if (ret != LDB_SUCCESS) { + ldb_oom(ldb); + return ret; + } + FIRST_OP(ldb, add); + ret = ldb_msg_check_element_flags(ldb, req->op.add.message); + if (ret != LDB_SUCCESS) { + /* + * "ldb_msg_check_element_flags" generates an error + * string + */ + return ret; + } + ret = next_module->ops->add(next_module, req); + break; + case LDB_MODIFY: + if (!ldb_dn_validate(req->op.mod.message->dn)) { + ldb_asprintf_errstring(ldb, "ldb_modify: invalid dn '%s'", + ldb_dn_get_linearized(req->op.mod.message->dn)); + return LDB_ERR_INVALID_DN_SYNTAX; + } + FIRST_OP(ldb, modify); + ret = ldb_msg_check_element_flags(ldb, req->op.mod.message); + if (ret != LDB_SUCCESS) { + /* + * "ldb_msg_check_element_flags" generates an error + * string + */ + return ret; + } + ret = next_module->ops->modify(next_module, req); + break; + case LDB_DELETE: + if (!ldb_dn_validate(req->op.del.dn)) { + ldb_asprintf_errstring(ldb, "ldb_delete: invalid dn '%s'", + ldb_dn_get_linearized(req->op.del.dn)); + return LDB_ERR_INVALID_DN_SYNTAX; + } + FIRST_OP(ldb, del); + ret = next_module->ops->del(next_module, req); + break; + case LDB_RENAME: + if (!ldb_dn_validate(req->op.rename.olddn)) { + ldb_asprintf_errstring(ldb, "ldb_rename: invalid olddn '%s'", + ldb_dn_get_linearized(req->op.rename.olddn)); + return LDB_ERR_INVALID_DN_SYNTAX; + } + if (!ldb_dn_validate(req->op.rename.newdn)) { + ldb_asprintf_errstring(ldb, "ldb_rename: invalid newdn '%s'", + ldb_dn_get_linearized(req->op.rename.newdn)); + return LDB_ERR_INVALID_DN_SYNTAX; + } + FIRST_OP(ldb, rename); + ret = next_module->ops->rename(next_module, req); + break; + case LDB_EXTENDED: + FIRST_OP(ldb, extended); + ret = next_module->ops->extended(next_module, req); + break; + default: + FIRST_OP(ldb, request); + ret = next_module->ops->request(next_module, req); + break; + } + + if ((ret != LDB_SUCCESS) && (ldb->err_string == NULL)) { + /* if no error string was setup by the backend */ + ldb_asprintf_errstring(ldb, "ldb_request: %s (%d)", + ldb_strerror(ret), ret); + } + + return ret; +} + +int ldb_request_done(struct ldb_request *req, int status) +{ + req->handle->state = LDB_ASYNC_DONE; + req->handle->status = status; + return status; +} + +/* + search the database given a LDAP-like search expression + + returns an LDB error code + + Use talloc_free to free the ldb_message returned in 'res', if successful + +*/ +int ldb_search_default_callback(struct ldb_request *req, + struct ldb_reply *ares) +{ + struct ldb_result *res; + unsigned int n; + + res = talloc_get_type(req->context, struct ldb_result); + + if (!ares) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_request_done(req, ares->error); + } + + switch (ares->type) { + case LDB_REPLY_ENTRY: + res->msgs = talloc_realloc(res, res->msgs, + struct ldb_message *, res->count + 2); + if (! res->msgs) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + + res->msgs[res->count + 1] = NULL; + + res->msgs[res->count] = talloc_move(res->msgs, &ares->message); + res->count++; + break; + + case LDB_REPLY_REFERRAL: + if (res->refs) { + for (n = 0; res->refs[n]; n++) /*noop*/ ; + } else { + n = 0; + } + + res->refs = talloc_realloc(res, res->refs, char *, n + 2); + if (! res->refs) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + + res->refs[n] = talloc_move(res->refs, &ares->referral); + res->refs[n + 1] = NULL; + break; + + case LDB_REPLY_DONE: + /* TODO: we should really support controls on entries + * and referrals too! */ + res->controls = talloc_move(res, &ares->controls); + + /* this is the last message, and means the request is done */ + /* we have to signal and eventual ldb_wait() waiting that the + * async request operation was completed */ + talloc_free(ares); + return ldb_request_done(req, LDB_SUCCESS); + } + + talloc_free(ares); + + return LDB_SUCCESS; +} + +int ldb_modify_default_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct ldb_result *res; + unsigned int n; + int ret; + + res = talloc_get_type(req->context, struct ldb_result); + + if (!ares) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + + if (ares->error != LDB_SUCCESS) { + ret = ares->error; + talloc_free(ares); + return ldb_request_done(req, ret); + } + + switch (ares->type) { + case LDB_REPLY_REFERRAL: + if (res->refs) { + for (n = 0; res->refs[n]; n++) /*noop*/ ; + } else { + n = 0; + } + + res->refs = talloc_realloc(res, res->refs, char *, n + 2); + if (! res->refs) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + + res->refs[n] = talloc_move(res->refs, &ares->referral); + res->refs[n + 1] = NULL; + break; + + case LDB_REPLY_DONE: + talloc_free(ares); + return ldb_request_done(req, LDB_SUCCESS); + default: + talloc_free(ares); + ldb_asprintf_errstring(req->handle->ldb, "Invalid LDB reply type %d", ares->type); + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + + talloc_free(ares); + return ldb_request_done(req, LDB_SUCCESS); +} + +int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + int ret; + + if (!ares) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + + if (ares->error != LDB_SUCCESS) { + ret = ares->error; + talloc_free(ares); + return ldb_request_done(req, ret); + } + + if (ares->type != LDB_REPLY_DONE) { + talloc_free(ares); + ldb_asprintf_errstring(req->handle->ldb, "Invalid LDB reply type %d", ares->type); + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + + talloc_free(ares); + return ldb_request_done(req, LDB_SUCCESS); +} + +static struct ldb_request *ldb_build_req_common(TALLOC_CTX *mem_ctx, + struct ldb_context *ldb, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent) +{ + struct ldb_request *req = NULL; + + req = talloc_zero(mem_ctx, struct ldb_request); + if (req == NULL) { + return NULL; + } + req->controls = controls; + req->context = context; + req->callback = callback; + + ldb_set_timeout_from_prev_req(ldb, parent, req); + + if (parent != NULL) { + req->handle = ldb_handle_new_child(req, parent); + if (req->handle == NULL) { + TALLOC_FREE(req); + return NULL; + } + } else { + req->handle = ldb_handle_new(req, ldb); + if (req->handle == NULL) { + TALLOC_FREE(req); + return NULL; + } + } + + return req; +} + +int ldb_build_search_req_ex(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *base, + enum ldb_scope scope, + struct ldb_parse_tree *tree, + const char * const *attrs, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent) +{ + struct ldb_request *req; + + *ret_req = NULL; + + req = ldb_build_req_common(mem_ctx, ldb, controls, + context, callback, parent); + if (req == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + req->operation = LDB_SEARCH; + if (base == NULL) { + req->op.search.base = ldb_dn_new(req, ldb, NULL); + } else { + req->op.search.base = base; + } + req->op.search.scope = scope; + + req->op.search.tree = tree; + if (req->op.search.tree == NULL) { + ldb_set_errstring(ldb, "'tree' can't be NULL"); + talloc_free(req); + return LDB_ERR_OPERATIONS_ERROR; + } + + req->op.search.attrs = attrs; + *ret_req = req; + return LDB_SUCCESS; +} + +int ldb_build_search_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *base, + enum ldb_scope scope, + const char *expression, + const char * const *attrs, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent) +{ + struct ldb_parse_tree *tree; + int ret; + + tree = ldb_parse_tree(mem_ctx, expression); + if (tree == NULL) { + ldb_set_errstring(ldb, "Unable to parse search expression"); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_build_search_req_ex(ret_req, ldb, mem_ctx, base, + scope, tree, attrs, controls, + context, callback, parent); + if (ret == LDB_SUCCESS) { + talloc_steal(*ret_req, tree); + } + return ret; +} + +int ldb_build_add_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const struct ldb_message *message, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent) +{ + struct ldb_request *req; + + *ret_req = NULL; + + req = ldb_build_req_common(mem_ctx, ldb, controls, + context, callback, parent); + if (req == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + + req->operation = LDB_ADD; + req->op.add.message = message; + *ret_req = req; + return LDB_SUCCESS; +} + +int ldb_build_mod_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const struct ldb_message *message, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent) +{ + struct ldb_request *req; + + *ret_req = NULL; + + req = ldb_build_req_common(mem_ctx, ldb, controls, + context, callback, parent); + if (req == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + + req->operation = LDB_MODIFY; + req->op.mod.message = message; + + *ret_req = req; + return LDB_SUCCESS; +} + +int ldb_build_del_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *dn, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent) +{ + struct ldb_request *req; + + *ret_req = NULL; + + req = ldb_build_req_common(mem_ctx, ldb, controls, + context, callback, parent); + if (req == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + + req->operation = LDB_DELETE; + req->op.del.dn = dn; + *ret_req = req; + return LDB_SUCCESS; +} + +int ldb_build_rename_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *olddn, + struct ldb_dn *newdn, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent) +{ + struct ldb_request *req; + + *ret_req = NULL; + + req = ldb_build_req_common(mem_ctx, ldb, controls, + context, callback, parent); + if (req == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + + req->operation = LDB_RENAME; + req->op.rename.olddn = olddn; + req->op.rename.newdn = newdn; + *ret_req = req; + return LDB_SUCCESS; +} + +int ldb_extended_default_callback(struct ldb_request *req, + struct ldb_reply *ares) +{ + struct ldb_result *res; + + res = talloc_get_type(req->context, struct ldb_result); + + if (!ares) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_request_done(req, ares->error); + } + + if (ares->type == LDB_REPLY_DONE) { + + /* TODO: we should really support controls on entries and referrals too! */ + res->extended = talloc_move(res, &ares->response); + res->controls = talloc_move(res, &ares->controls); + + talloc_free(ares); + return ldb_request_done(req, LDB_SUCCESS); + } + + talloc_free(ares); + ldb_asprintf_errstring(req->handle->ldb, "Invalid LDB reply type %d", ares->type); + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); +} + +int ldb_build_extended_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const char *oid, + void *data, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent) +{ + struct ldb_request *req; + + *ret_req = NULL; + + req = ldb_build_req_common(mem_ctx, ldb, controls, + context, callback, parent); + if (req == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + + req->operation = LDB_EXTENDED; + req->op.extended.oid = oid; + req->op.extended.data = data; + *ret_req = req; + return LDB_SUCCESS; +} + +int ldb_extended(struct ldb_context *ldb, + const char *oid, + void *data, + struct ldb_result **_res) +{ + struct ldb_request *req; + int ret; + struct ldb_result *res; + + *_res = NULL; + req = NULL; + + res = talloc_zero(ldb, struct ldb_result); + if (!res) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_build_extended_req(&req, ldb, ldb, + oid, data, NULL, + res, ldb_extended_default_callback, + NULL); + ldb_req_set_location(req, "ldb_extended"); + + if (ret != LDB_SUCCESS) goto done; + + ldb_set_timeout(ldb, req, 0); /* use default timeout */ + + ret = ldb_request(ldb, req); + + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + +done: + if (ret != LDB_SUCCESS) { + talloc_free(res); + res = NULL; + } + + talloc_free(req); + + *_res = res; + return ret; +} + +/* + note that ldb_search() will automatically replace a NULL 'base' value + with the defaultNamingContext from the rootDSE if available. +*/ +int ldb_search(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + struct ldb_result **result, struct ldb_dn *base, + enum ldb_scope scope, const char * const *attrs, + const char *exp_fmt, ...) +{ + struct ldb_request *req; + struct ldb_result *res; + char *expression; + va_list ap; + int ret; + + expression = NULL; + *result = NULL; + req = NULL; + + res = talloc_zero(mem_ctx, struct ldb_result); + if (!res) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (exp_fmt) { + va_start(ap, exp_fmt); + expression = talloc_vasprintf(mem_ctx, exp_fmt, ap); + va_end(ap); + + if (!expression) { + talloc_free(res); + return LDB_ERR_OPERATIONS_ERROR; + } + } + + ret = ldb_build_search_req(&req, ldb, mem_ctx, + base?base:ldb_get_default_basedn(ldb), + scope, + expression, + attrs, + NULL, + res, + ldb_search_default_callback, + NULL); + ldb_req_set_location(req, "ldb_search"); + + if (ret != LDB_SUCCESS) goto done; + + ret = ldb_request(ldb, req); + + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + +done: + if (ret != LDB_SUCCESS) { + talloc_free(res); + res = NULL; + } + + talloc_free(expression); + talloc_free(req); + + *result = res; + return ret; +} + +/* + add a record to the database. Will fail if a record with the given class + and key already exists +*/ +int ldb_add(struct ldb_context *ldb, + const struct ldb_message *message) +{ + struct ldb_request *req; + int ret; + + ret = ldb_msg_sanity_check(ldb, message); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_build_add_req(&req, ldb, ldb, + message, + NULL, + NULL, + ldb_op_default_callback, + NULL); + ldb_req_set_location(req, "ldb_add"); + + if (ret != LDB_SUCCESS) return ret; + + /* do request and autostart a transaction */ + ret = ldb_autotransaction_request(ldb, req); + + talloc_free(req); + return ret; +} + +/* + modify the specified attributes of a record +*/ +int ldb_modify(struct ldb_context *ldb, + const struct ldb_message *message) +{ + struct ldb_request *req; + int ret; + + ret = ldb_msg_sanity_check(ldb, message); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_build_mod_req(&req, ldb, ldb, + message, + NULL, + NULL, + ldb_op_default_callback, + NULL); + ldb_req_set_location(req, "ldb_modify"); + + if (ret != LDB_SUCCESS) return ret; + + /* do request and autostart a transaction */ + ret = ldb_autotransaction_request(ldb, req); + + talloc_free(req); + return ret; +} + + +/* + delete a record from the database +*/ +int ldb_delete(struct ldb_context *ldb, struct ldb_dn *dn) +{ + struct ldb_request *req; + int ret; + + ret = ldb_build_del_req(&req, ldb, ldb, + dn, + NULL, + NULL, + ldb_op_default_callback, + NULL); + ldb_req_set_location(req, "ldb_delete"); + + if (ret != LDB_SUCCESS) return ret; + + /* do request and autostart a transaction */ + ret = ldb_autotransaction_request(ldb, req); + + talloc_free(req); + return ret; +} + +/* + rename a record in the database +*/ +int ldb_rename(struct ldb_context *ldb, + struct ldb_dn *olddn, struct ldb_dn *newdn) +{ + struct ldb_request *req; + int ret; + + ret = ldb_build_rename_req(&req, ldb, ldb, + olddn, + newdn, + NULL, + NULL, + ldb_op_default_callback, + NULL); + ldb_req_set_location(req, "ldb_rename"); + + if (ret != LDB_SUCCESS) return ret; + + /* do request and autostart a transaction */ + ret = ldb_autotransaction_request(ldb, req); + + talloc_free(req); + return ret; +} + + +/* + return the global sequence number +*/ +int ldb_sequence_number(struct ldb_context *ldb, + enum ldb_sequence_type type, uint64_t *seq_num) +{ + struct ldb_seqnum_request *seq; + struct ldb_seqnum_result *seqr; + struct ldb_result *res; + TALLOC_CTX *tmp_ctx; + int ret; + + *seq_num = 0; + + tmp_ctx = talloc_zero(ldb, struct ldb_request); + if (tmp_ctx == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + seq = talloc_zero(tmp_ctx, struct ldb_seqnum_request); + if (seq == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + seq->type = type; + + ret = ldb_extended(ldb, LDB_EXTENDED_SEQUENCE_NUMBER, seq, &res); + if (ret != LDB_SUCCESS) { + goto done; + } + talloc_steal(tmp_ctx, res); + + if (strcmp(LDB_EXTENDED_SEQUENCE_NUMBER, res->extended->oid) != 0) { + ldb_set_errstring(ldb, "Invalid OID in reply"); + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + seqr = talloc_get_type(res->extended->data, + struct ldb_seqnum_result); + *seq_num = seqr->seq_num; + +done: + talloc_free(tmp_ctx); + return ret; +} + +/* + return extended error information +*/ +const char *ldb_errstring(struct ldb_context *ldb) +{ + if (ldb->err_string) { + return ldb->err_string; + } + + return NULL; +} + +/* + return a string explaining what a ldb error constant meancs +*/ +const char *ldb_strerror(int ldb_err) +{ + switch (ldb_err) { + case LDB_SUCCESS: + return "Success"; + case LDB_ERR_OPERATIONS_ERROR: + return "Operations error"; + case LDB_ERR_PROTOCOL_ERROR: + return "Protocol error"; + case LDB_ERR_TIME_LIMIT_EXCEEDED: + return "Time limit exceeded"; + case LDB_ERR_SIZE_LIMIT_EXCEEDED: + return "Size limit exceeded"; + case LDB_ERR_COMPARE_FALSE: + return "Compare false"; + case LDB_ERR_COMPARE_TRUE: + return "Compare true"; + case LDB_ERR_AUTH_METHOD_NOT_SUPPORTED: + return "Auth method not supported"; + case LDB_ERR_STRONG_AUTH_REQUIRED: + return "Strong auth required"; +/* 9 RESERVED */ + case LDB_ERR_REFERRAL: + return "Referral error"; + case LDB_ERR_ADMIN_LIMIT_EXCEEDED: + return "Admin limit exceeded"; + case LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION: + return "Unsupported critical extension"; + case LDB_ERR_CONFIDENTIALITY_REQUIRED: + return "Confidentiality required"; + case LDB_ERR_SASL_BIND_IN_PROGRESS: + return "SASL bind in progress"; + case LDB_ERR_NO_SUCH_ATTRIBUTE: + return "No such attribute"; + case LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE: + return "Undefined attribute type"; + case LDB_ERR_INAPPROPRIATE_MATCHING: + return "Inappropriate matching"; + case LDB_ERR_CONSTRAINT_VIOLATION: + return "Constraint violation"; + case LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS: + return "Attribute or value exists"; + case LDB_ERR_INVALID_ATTRIBUTE_SYNTAX: + return "Invalid attribute syntax"; +/* 22-31 unused */ + case LDB_ERR_NO_SUCH_OBJECT: + return "No such object"; + case LDB_ERR_ALIAS_PROBLEM: + return "Alias problem"; + case LDB_ERR_INVALID_DN_SYNTAX: + return "Invalid DN syntax"; +/* 35 RESERVED */ + case LDB_ERR_ALIAS_DEREFERENCING_PROBLEM: + return "Alias dereferencing problem"; +/* 37-47 unused */ + case LDB_ERR_INAPPROPRIATE_AUTHENTICATION: + return "Inappropriate authentication"; + case LDB_ERR_INVALID_CREDENTIALS: + return "Invalid credentials"; + case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: + return "insufficient access rights"; + case LDB_ERR_BUSY: + return "Busy"; + case LDB_ERR_UNAVAILABLE: + return "Unavailable"; + case LDB_ERR_UNWILLING_TO_PERFORM: + return "Unwilling to perform"; + case LDB_ERR_LOOP_DETECT: + return "Loop detect"; +/* 55-63 unused */ + case LDB_ERR_NAMING_VIOLATION: + return "Naming violation"; + case LDB_ERR_OBJECT_CLASS_VIOLATION: + return "Object class violation"; + case LDB_ERR_NOT_ALLOWED_ON_NON_LEAF: + return "Not allowed on non-leaf"; + case LDB_ERR_NOT_ALLOWED_ON_RDN: + return "Not allowed on RDN"; + case LDB_ERR_ENTRY_ALREADY_EXISTS: + return "Entry already exists"; + case LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED: + return "Object class mods prohibited"; +/* 70 RESERVED FOR CLDAP */ + case LDB_ERR_AFFECTS_MULTIPLE_DSAS: + return "Affects multiple DSAs"; +/* 72-79 unused */ + case LDB_ERR_OTHER: + return "Other"; + } + + return "Unknown error"; +} + +/* + set backend specific opaque parameters +*/ +int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value) +{ + struct ldb_opaque *o; + + /* allow updating an existing value */ + for (o=ldb->opaque;o;o=o->next) { + if (strcmp(o->name, name) == 0) { + o->value = value; + return LDB_SUCCESS; + } + } + + o = talloc(ldb, struct ldb_opaque); + if (o == NULL) { + ldb_oom(ldb); + return LDB_ERR_OTHER; + } + o->next = ldb->opaque; + o->name = name; + o->value = value; + ldb->opaque = o; + return LDB_SUCCESS; +} + +/* + get a previously set opaque value +*/ +void *ldb_get_opaque(struct ldb_context *ldb, const char *name) +{ + struct ldb_opaque *o; + for (o=ldb->opaque;o;o=o->next) { + if (strcmp(o->name, name) == 0) { + return o->value; + } + } + return NULL; +} + +int ldb_global_init(void) +{ + /* Provided for compatibility with some older versions of ldb */ + return 0; +} + +/* return the ldb flags */ +unsigned int ldb_get_flags(struct ldb_context *ldb) +{ + return ldb->flags; +} + +/* set the ldb flags */ +void ldb_set_flags(struct ldb_context *ldb, unsigned flags) +{ + ldb->flags = flags; +} + + +/* + set the location in a ldb request. Used for debugging + */ +void ldb_req_set_location(struct ldb_request *req, const char *location) +{ + if (req && req->handle) { + req->handle->location = location; + } +} + +/* + return the location set with dsdb_req_set_location + */ +const char *ldb_req_location(struct ldb_request *req) +{ + return req->handle->location; +} + +/** + mark a request as untrusted. This tells the rootdse module to remove + unregistered controls + */ +void ldb_req_mark_untrusted(struct ldb_request *req) +{ + req->handle->flags |= LDB_HANDLE_FLAG_UNTRUSTED; +} + +/** + mark a request as trusted. + */ +void ldb_req_mark_trusted(struct ldb_request *req) +{ + req->handle->flags &= ~LDB_HANDLE_FLAG_UNTRUSTED; +} + +/** + set custom flags. Those flags are set by applications using ldb, + they are application dependent and the same bit can have different + meaning in different application. + */ +void ldb_req_set_custom_flags(struct ldb_request *req, uint32_t flags) +{ + if (req != NULL && req->handle != NULL) { + req->handle->custom_flags = flags; + } +} + + +/** + get custom flags. Those flags are set by applications using ldb, + they are application dependent and the same bit can have different + meaning in different application. + */ +uint32_t ldb_req_get_custom_flags(struct ldb_request *req) +{ + if (req != NULL && req->handle != NULL) { + return req->handle->custom_flags; + } + + /* + * 0 is not something any better or worse than + * anything else as req or the handle is NULL + */ + return 0; +} + + +/** + * return true if a request is untrusted + */ +bool ldb_req_is_untrusted(struct ldb_request *req) +{ + return (req->handle->flags & LDB_HANDLE_FLAG_UNTRUSTED) != 0; +} diff --git a/ldb-2.0.8/common/ldb_attributes.c b/ldb-2.0.8/common/ldb_attributes.c new file mode 100644 index 0000000..32f25fd --- /dev/null +++ b/ldb-2.0.8/common/ldb_attributes.c @@ -0,0 +1,411 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2005 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ +/* + register handlers for specific attributes and objectclass relationships + + this allows a backend to store its schema information in any format + it likes (or to not have any schema information at all) while keeping the + message matching logic generic +*/ + +#include "ldb_private.h" +#include "ldb_handlers.h" + +/* + fill in an attribute to the ldb_schema into the supplied buffer + + if flags contains LDB_ATTR_FLAG_ALLOCATED + the attribute name string will be copied using + talloc_strdup(), otherwise it needs to be a static const + string at least with a lifetime longer than the ldb struct! + + the ldb_schema_syntax structure should be a pointer + to a static const struct or at least it needs to be + a struct with a longer lifetime than the ldb context! + +*/ +int ldb_schema_attribute_fill_with_syntax(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const char *attribute, + unsigned flags, + const struct ldb_schema_syntax *syntax, + struct ldb_schema_attribute *a) +{ + a->name = attribute; + a->flags = flags; + a->syntax = syntax; + + if (a->flags & LDB_ATTR_FLAG_ALLOCATED) { + a->name = talloc_strdup(mem_ctx, a->name); + if (a->name == NULL) { + ldb_oom(ldb); + return -1; + } + } + + return 0; +} + +/* + add a attribute to the ldb_schema + + if flags contains LDB_ATTR_FLAG_ALLOCATED + the attribute name string will be copied using + talloc_strdup(), otherwise it needs to be a static const + string at least with a lifetime longer than the ldb struct! + + the ldb_schema_syntax structure should be a pointer + to a static const struct or at least it needs to be + a struct with a longer lifetime than the ldb context! + +*/ +int ldb_schema_attribute_add_with_syntax(struct ldb_context *ldb, + const char *attribute, + unsigned flags, + const struct ldb_schema_syntax *syntax) +{ + unsigned int i, n; + struct ldb_schema_attribute *a; + + if (!syntax) { + return LDB_ERR_OPERATIONS_ERROR; + } + + n = ldb->schema.num_attributes + 1; + + a = talloc_realloc(ldb, ldb->schema.attributes, + struct ldb_schema_attribute, n); + if (a == NULL) { + ldb_oom(ldb); + return -1; + } + ldb->schema.attributes = a; + + for (i = 0; i < ldb->schema.num_attributes; i++) { + int cmp = ldb_attr_cmp(attribute, a[i].name); + if (cmp == 0) { + /* silently ignore attempts to overwrite fixed attributes */ + if (a[i].flags & LDB_ATTR_FLAG_FIXED) { + return 0; + } + if (a[i].flags & LDB_ATTR_FLAG_ALLOCATED) { + talloc_free(discard_const_p(char, a[i].name)); + } + /* To cancel out increment below */ + ldb->schema.num_attributes--; + break; + } else if (cmp < 0) { + memmove(a+i+1, a+i, sizeof(*a) * (ldb->schema.num_attributes-i)); + break; + } + } + ldb->schema.num_attributes++; + + a[i].name = attribute; + a[i].flags = flags; + a[i].syntax = syntax; + + if (a[i].flags & LDB_ATTR_FLAG_ALLOCATED) { + a[i].name = talloc_strdup(a, a[i].name); + if (a[i].name == NULL) { + ldb_oom(ldb); + return -1; + } + } + + return 0; +} + +static const struct ldb_schema_syntax ldb_syntax_default = { + .name = LDB_SYNTAX_OCTET_STRING, + .ldif_read_fn = ldb_handler_copy, + .ldif_write_fn = ldb_handler_copy, + .canonicalise_fn = ldb_handler_copy, + .comparison_fn = ldb_comparison_binary +}; + +static const struct ldb_schema_attribute ldb_attribute_default = { + .name = NULL, + .flags = 0, + .syntax = &ldb_syntax_default +}; + +/* + * Return the attribute handlers for a given attribute + * + * @param ldb ldb context + * @param name attribute name to search for + * @return Always return valid pointer to schema attribute. + * In case there is no attribute with name, + * ldb_attribute_default is returned + */ +static const struct ldb_schema_attribute *ldb_schema_attribute_by_name_internal( + struct ldb_context *ldb, + const char *name) +{ + /* for binary search we need signed variables */ + unsigned int i, e, b = 0; + int r; + const struct ldb_schema_attribute *def = &ldb_attribute_default; + + /* fallback to default attribute implementation */ + if (name == NULL) { + return def; + } + + /* as handlers are sorted, '*' must be the first if present */ + if (strcmp(ldb->schema.attributes[0].name, "*") == 0) { + def = &ldb->schema.attributes[0]; + b = 1; + } + + /* do a binary search on the array */ + e = ldb->schema.num_attributes - 1; + + while ((b <= e) && (e != (unsigned int) -1)) { + i = (b + e) / 2; + + r = ldb_attr_cmp(name, ldb->schema.attributes[i].name); + if (r == 0) { + return &ldb->schema.attributes[i]; + } + if (r < 0) { + e = i - 1; + } else { + b = i + 1; + } + } + + return def; +} + +/* + return the attribute handlers for a given attribute +*/ +const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_context *ldb, + const char *name) +{ + if (ldb->schema.attribute_handler_override) { + const struct ldb_schema_attribute *ret = + ldb->schema.attribute_handler_override(ldb, + ldb->schema.attribute_handler_override_private, + name); + if (ret) { + return ret; + } + } + + return ldb_schema_attribute_by_name_internal(ldb, name); +} + + +/* + add to the list of ldif handlers for this ldb context +*/ +void ldb_schema_attribute_remove(struct ldb_context *ldb, const char *name) +{ + const struct ldb_schema_attribute *a; + ptrdiff_t i; + + a = ldb_schema_attribute_by_name_internal(ldb, name); + if (a == NULL || a->name == NULL) { + return; + } + + /* FIXED attributes are never removed */ + if (a->flags & LDB_ATTR_FLAG_FIXED) { + return; + } + + if (a->flags & LDB_ATTR_FLAG_ALLOCATED) { + talloc_free(discard_const_p(char, a->name)); + } + + i = a - ldb->schema.attributes; + if (i < ldb->schema.num_attributes - 1) { + memmove(&ldb->schema.attributes[i], + a+1, sizeof(*a) * (ldb->schema.num_attributes-(i+1))); + } + + ldb->schema.num_attributes--; +} + +/* + remove attributes with a specified flag (eg LDB_ATTR_FLAG_FROM_DB) for this ldb context + + This is to permit correct reloads +*/ +void ldb_schema_attribute_remove_flagged(struct ldb_context *ldb, unsigned int flag) +{ + ptrdiff_t i; + + for (i = 0; i < ldb->schema.num_attributes;) { + const struct ldb_schema_attribute *a + = &ldb->schema.attributes[i]; + /* FIXED attributes are never removed */ + if (a->flags & LDB_ATTR_FLAG_FIXED) { + i++; + continue; + } + if ((a->flags & flag) == 0) { + i++; + continue; + } + if (a->flags & LDB_ATTR_FLAG_ALLOCATED) { + talloc_free(discard_const_p(char, a->name)); + } + if (i < ldb->schema.num_attributes - 1) { + memmove(&ldb->schema.attributes[i], + a+1, sizeof(*a) * (ldb->schema.num_attributes-(i+1))); + } + + ldb->schema.num_attributes--; + } +} + +/* + setup a attribute handler using a standard syntax +*/ +int ldb_schema_attribute_add(struct ldb_context *ldb, + const char *attribute, + unsigned flags, + const char *syntax) +{ + const struct ldb_schema_syntax *s = ldb_standard_syntax_by_name(ldb, syntax); + return ldb_schema_attribute_add_with_syntax(ldb, attribute, flags, s); +} + +/* + setup the attribute handles for well known attributes +*/ +int ldb_setup_wellknown_attributes(struct ldb_context *ldb) +{ + const struct { + const char *attr; + const char *syntax; + } wellknown[] = { + { "dn", LDB_SYNTAX_DN }, + { "distinguishedName", LDB_SYNTAX_DN }, + { "cn", LDB_SYNTAX_DIRECTORY_STRING }, + { "dc", LDB_SYNTAX_DIRECTORY_STRING }, + { "ou", LDB_SYNTAX_DIRECTORY_STRING }, + { "objectClass", LDB_SYNTAX_OBJECTCLASS } + }; + unsigned int i; + int ret; + + for (i=0;ischema.num_dn_extended_syntax + 1; + + a = talloc_realloc(ldb, ldb->schema.dn_extended_syntax, + struct ldb_dn_extended_syntax, n); + + if (!a) { + return LDB_ERR_OPERATIONS_ERROR; + } + + a[ldb->schema.num_dn_extended_syntax] = *syntax; + ldb->schema.dn_extended_syntax = a; + + ldb->schema.num_dn_extended_syntax = n; + + return LDB_SUCCESS; +} + +/* + return the extended dn syntax for a given name +*/ +const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb, + const char *name) +{ + unsigned int i; + for (i=0; i < ldb->schema.num_dn_extended_syntax; i++) { + if (ldb_attr_cmp(ldb->schema.dn_extended_syntax[i].name, name) == 0) { + return &ldb->schema.dn_extended_syntax[i]; + } + } + return NULL; +} + +/* + set an attribute handler override function - used to delegate schema handling + to external code + */ +void ldb_schema_attribute_set_override_handler(struct ldb_context *ldb, + ldb_attribute_handler_override_fn_t override, + void *private_data) +{ + ldb->schema.attribute_handler_override_private = private_data; + ldb->schema.attribute_handler_override = override; +} + +/* + set that the attribute handler override function - used to delegate + schema handling to external code, is handling setting + LDB_ATTR_FLAG_INDEXED + */ +void ldb_schema_set_override_indexlist(struct ldb_context *ldb, + bool one_level_indexes) +{ + ldb->schema.index_handler_override = true; + ldb->schema.one_level_indexes = one_level_indexes; +} + +/* + * set that the GUID index mode is in operation + * + * The caller must ensure the supplied strings do not go out of + * scope (they are typically constant memory). + */ +void ldb_schema_set_override_GUID_index(struct ldb_context *ldb, + const char *GUID_index_attribute, + const char *GUID_index_dn_component) +{ + ldb->schema.GUID_index_attribute = GUID_index_attribute; + ldb->schema.GUID_index_dn_component = GUID_index_dn_component; +} diff --git a/ldb-2.0.8/common/ldb_controls.c b/ldb-2.0.8/common/ldb_controls.c new file mode 100644 index 0000000..e0f0eb4 --- /dev/null +++ b/ldb-2.0.8/common/ldb_controls.c @@ -0,0 +1,1319 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2005 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb_controls.c + * + * Component: ldb controls utility functions + * + * Description: helper functions for control modules + * + * Author: Simo Sorce + */ + +#include "ldb_private.h" + +/* check if a control with the specified "oid" exist and return it */ +/* returns NULL if not found */ +struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid) +{ + unsigned int i; + + if (req->controls != NULL) { + for (i = 0; req->controls[i]; i++) { + if (req->controls[i]->oid && strcmp(oid, req->controls[i]->oid) == 0) { + break; + } + } + + return req->controls[i]; + } + + return NULL; +} + +/* check if a control with the specified "oid" exist and return it */ +/* returns NULL if not found */ +struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid) +{ + unsigned int i; + + if (rep->controls != NULL) { + for (i = 0; rep->controls[i]; i++) { + if (rep->controls[i]->oid && strcmp(oid, rep->controls[i]->oid) == 0) { + break; + } + } + + return rep->controls[i]; + } + + return NULL; +} + +/* + * Saves the current controls list into the "saver" (can also be NULL) and + * replace the one in "req" with a new one excluding the "exclude" control + * (if it is NULL then the list remains the same) + * + * Returns 0 on error. + */ +int ldb_save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver) +{ + struct ldb_control **lcs, **lcs_old; + unsigned int i, j; + + lcs_old = req->controls; + if (saver != NULL) { + *saver = lcs_old; + } + + for (i = 0; req->controls && req->controls[i]; i++); + if (i == 0) { + req->controls = NULL; + return 1; + } + + lcs = talloc_array(req, struct ldb_control *, i + 1); + if (!lcs) { + return 0; + } + + for (i = 0, j = 0; lcs_old[i]; i++) { + if (exclude == lcs_old[i]) continue; + lcs[j] = lcs_old[i]; + j++; + } + lcs[j] = NULL; + + req->controls = talloc_realloc(req, lcs, struct ldb_control *, j + 1); + if (req->controls == NULL) { + return 0; + } + return 1; +} + +/* + * Returns a list of controls, except the one specified with "exclude" (can + * also be NULL). Included controls become a child of returned list if they + * were children of "controls_in". + * + * Returns NULL on error (OOM) or an empty control list. + */ +struct ldb_control **ldb_controls_except_specified(struct ldb_control **controls_in, + TALLOC_CTX *mem_ctx, + struct ldb_control *exclude) +{ + struct ldb_control **lcs = NULL; + unsigned int i, j, n; + + for (i = 0; controls_in && controls_in[i]; i++); + if (i == 0) { + return NULL; + } + n = i; + + for (i = 0, j = 0; controls_in && controls_in[i]; i++) { + if (exclude == controls_in[i]) continue; + + if (!lcs) { + /* Allocate here so if we remove the only + * control, or there were no controls, we + * don't allocate at all, and just return + * NULL */ + lcs = talloc_array(mem_ctx, struct ldb_control *, + n + 1); + if (!lcs) { + return NULL; + } + } + + lcs[j] = controls_in[i]; + talloc_reparent(controls_in, lcs, lcs[j]); + j++; + } + if (lcs) { + lcs[j] = NULL; + + lcs = talloc_realloc(mem_ctx, lcs, struct ldb_control *, j + 1); + } + + return lcs; +} + +/* check if there's any control marked as critical in the list */ +/* return True if any, False if none */ +int ldb_check_critical_controls(struct ldb_control **controls) +{ + unsigned int i; + + if (controls == NULL) { + return 0; + } + + for (i = 0; controls[i]; i++) { + if (controls[i]->critical) { + return 1; + } + } + + return 0; +} + +int ldb_request_add_control(struct ldb_request *req, const char *oid, bool critical, void *data) +{ + unsigned int i, n; + struct ldb_control **ctrls; + struct ldb_control *ctrl; + + for (n=0; req->controls && req->controls[n];n++) { + /* having two controls of the same OID makes no sense */ + if (req->controls[n]->oid && strcmp(oid, req->controls[n]->oid) == 0) { + return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + } + } + + ctrls = talloc_array(req, + struct ldb_control *, + n + 2); + if (!ctrls) return LDB_ERR_OPERATIONS_ERROR; + + for (i=0; icontrols[i]; + } + + req->controls = ctrls; + ctrls[n] = NULL; + ctrls[n+1] = NULL; + + ctrl = talloc(ctrls, struct ldb_control); + if (!ctrl) return LDB_ERR_OPERATIONS_ERROR; + + ctrl->oid = talloc_strdup(ctrl, oid); + if (!ctrl->oid) return LDB_ERR_OPERATIONS_ERROR; + ctrl->critical = critical; + ctrl->data = data; + + ctrls[n] = ctrl; + return LDB_SUCCESS; +} + +int ldb_reply_add_control(struct ldb_reply *ares, const char *oid, bool critical, void *data) +{ + unsigned n; + struct ldb_control **ctrls; + struct ldb_control *ctrl; + + for (n=0; ares->controls && ares->controls[n];) { + /* having two controls of the same OID makes no sense */ + if (ares->controls[n]->oid && strcmp(oid, ares->controls[n]->oid) == 0) { + return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + } + n++; + } + + ctrls = talloc_realloc(ares, ares->controls, + struct ldb_control *, + n + 2); + if (!ctrls) return LDB_ERR_OPERATIONS_ERROR; + ares->controls = ctrls; + ctrls[n] = NULL; + ctrls[n+1] = NULL; + + ctrl = talloc(ctrls, struct ldb_control); + if (!ctrl) return LDB_ERR_OPERATIONS_ERROR; + + ctrl->oid = talloc_strdup(ctrl, oid); + if (!ctrl->oid) return LDB_ERR_OPERATIONS_ERROR; + ctrl->critical = critical; + ctrl->data = data; + + ctrls[n] = ctrl; + return LDB_SUCCESS; +} + +/* Add a control to the request, replacing the old one if it is already in the request */ +int ldb_request_replace_control(struct ldb_request *req, const char *oid, bool critical, void *data) +{ + unsigned int n; + int ret; + + ret = ldb_request_add_control(req, oid, critical, data); + if (ret != LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) { + return ret; + } + + for (n=0; req->controls[n];n++) { + if (req->controls[n]->oid && strcmp(oid, req->controls[n]->oid) == 0) { + req->controls[n]->critical = critical; + req->controls[n]->data = data; + return LDB_SUCCESS; + } + } + + return LDB_ERR_OPERATIONS_ERROR; +} + +/* + * Return a control as string + * the project (ie. name:value1:value2:...:valuen + * The string didn't include the criticity of the critical flag + */ +char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *control) +{ + char *res = NULL; + + if (strcmp(control->oid, LDB_CONTROL_PAGED_RESULTS_OID) == 0) { + struct ldb_paged_control *rep_control = talloc_get_type(control->data, struct ldb_paged_control); + char *cookie; + + cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, rep_control->cookie_len); + if (cookie == NULL) { + return NULL; + } + if (cookie[0] != '\0') { + res = talloc_asprintf(mem_ctx, "%s:%d:%s", + LDB_CONTROL_PAGED_RESULTS_NAME, + control->critical, + cookie); + + talloc_free(cookie); + } else { + res = talloc_asprintf(mem_ctx, "%s:%d", + LDB_CONTROL_PAGED_RESULTS_NAME, + control->critical); + } + return res; + } + + if (strcmp(control->oid, LDB_CONTROL_VLV_RESP_OID) == 0) { + struct ldb_vlv_resp_control *rep_control = talloc_get_type(control->data, + struct ldb_vlv_resp_control); + + char *cookie; + + cookie = ldb_base64_encode(mem_ctx, + (char *)rep_control->contextId, + rep_control->ctxid_len); + if (cookie == NULL) { + return NULL; + } + + res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%d:%s", + LDB_CONTROL_VLV_RESP_NAME, + control->critical, + rep_control->targetPosition, + rep_control->contentCount, + rep_control->vlv_result, + cookie); + + return res; + } + + if (strcmp(control->oid, LDB_CONTROL_SORT_RESP_OID) == 0) { + struct ldb_sort_resp_control *rep_control = talloc_get_type(control->data, + struct ldb_sort_resp_control); + + res = talloc_asprintf(mem_ctx, "%s:%d:%d:%s", + LDB_CONTROL_SORT_RESP_NAME, + control->critical, + rep_control->result, + rep_control->attr_desc); + + return res; + } + + if (strcmp(control->oid, LDB_CONTROL_ASQ_OID) == 0) { + struct ldb_asq_control *rep_control = talloc_get_type(control->data, + struct ldb_asq_control); + + res = talloc_asprintf(mem_ctx, "%s:%d:%d", + LDB_CONTROL_SORT_RESP_NAME, + control->critical, + rep_control->result); + + return res; + } + + if (strcmp(control->oid, LDB_CONTROL_DIRSYNC_OID) == 0) { + char *cookie; + struct ldb_dirsync_control *rep_control = talloc_get_type(control->data, + struct ldb_dirsync_control); + + cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, + rep_control->cookie_len); + if (cookie == NULL) { + return NULL; + } + res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%s", + LDB_CONTROL_DIRSYNC_NAME, + control->critical, + rep_control->flags, + rep_control->max_attributes, + cookie); + + talloc_free(cookie); + return res; + } + if (strcmp(control->oid, LDB_CONTROL_DIRSYNC_EX_OID) == 0) { + char *cookie; + struct ldb_dirsync_control *rep_control = talloc_get_type(control->data, + struct ldb_dirsync_control); + + cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, + rep_control->cookie_len); + if (cookie == NULL) { + return NULL; + } + res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%s", + LDB_CONTROL_DIRSYNC_EX_NAME, + control->critical, + rep_control->flags, + rep_control->max_attributes, + cookie); + + talloc_free(cookie); + return res; + } + + if (strcmp(control->oid, LDB_CONTROL_VERIFY_NAME_OID) == 0) { + struct ldb_verify_name_control *rep_control = talloc_get_type(control->data, struct ldb_verify_name_control); + + if (rep_control->gc != NULL) { + res = talloc_asprintf(mem_ctx, "%s:%d:%d:%s", + LDB_CONTROL_VERIFY_NAME_NAME, + control->critical, + rep_control->flags, + rep_control->gc); + + } else { + res = talloc_asprintf(mem_ctx, "%s:%d:%d", + LDB_CONTROL_VERIFY_NAME_NAME, + control->critical, + rep_control->flags); + } + return res; + } + + /* + * From here we don't know the control + */ + if (control->data == NULL) { + /* + * We don't know the control but there is no real data attached + * to it so we can represent it with local_oid:oid:criticity. + */ + res = talloc_asprintf(mem_ctx, "local_oid:%s:%d", + control->oid, + control->critical); + } else { + res = talloc_asprintf(mem_ctx, "unknown oid:%s", + control->oid); + } + return res; +} + + +/* + * A little trick to allow one to use constants defined in headers rather than + * hardwritten in the file. + * "sizeof" will return the \0 char as well so it will take the place of ":" + * in the length of the string. + */ +#define LDB_CONTROL_CMP(control, NAME) strncmp(control, NAME ":", sizeof(NAME)) + +/* Parse one string and return associated control if parsing is successful*/ +struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *control_strings) +{ + struct ldb_control *ctrl; + + if (!(ctrl = talloc(mem_ctx, struct ldb_control))) { + ldb_oom(ldb); + return NULL; + } + + if (LDB_CONTROL_CMP(control_strings, + LDB_CONTROL_VLV_REQ_NAME) == 0) { + struct ldb_vlv_req_control *control; + const char *p; + char attr[1024]; + char ctxid[1024]; + int crit, bc, ac, os, cc, ret; + + attr[0] = '\0'; + ctxid[0] = '\0'; + p = &(control_strings[sizeof(LDB_CONTROL_VLV_REQ_NAME)]); + ret = sscanf(p, "%d:%d:%d:%d:%d:%1023[^$]", &crit, &bc, &ac, &os, &cc, ctxid); + /* We allow 2 ways to encode the GT_EQ case, because the + comparison string might contain null bytes or colons, which + would break sscanf (or indeed any parsing mechanism). */ + if (ret == 3) { + ret = sscanf(p, "%d:%d:%d:>=%1023[^:]:%1023[^$]", &crit, &bc, &ac, attr, ctxid); + } + if (ret == 3) { + int len; + ret = sscanf(p, "%d:%d:%d:base64>=%1023[^:]:%1023[^$]", &crit, &bc, &ac, attr, ctxid); + len = ldb_base64_decode(attr); + if (len < 0) { + ret = -1; + } + } + + if ((ret < 4) || (crit < 0) || (crit > 1)) { + ldb_set_errstring(ldb, + "invalid VLV control syntax\n" + " syntax: crit(b):bc(n):ac(n):" + "{os(n):cc(n)|>=val(s)|base64>=val(o)}[:ctxid(o)]\n" + " note: b = boolean, n = number, s = string, o = b64 binary blob"); + talloc_free(ctrl); + return NULL; + } + ctrl->oid = LDB_CONTROL_VLV_REQ_OID; + ctrl->critical = crit; + if (!(control = talloc(ctrl, + struct ldb_vlv_req_control))) { + ldb_oom(ldb); + talloc_free(ctrl); + return NULL; + } + control->beforeCount = bc; + control->afterCount = ac; + if (attr[0]) { + control->type = 1; + control->match.gtOrEq.value = talloc_strdup(control, attr); + control->match.gtOrEq.value_len = strlen(attr); + } else { + control->type = 0; + control->match.byOffset.offset = os; + control->match.byOffset.contentCount = cc; + } + if (ctxid[0]) { + int len = ldb_base64_decode(ctxid); + if (len < 0) { + ldb_set_errstring(ldb, + "invalid VLV context_id\n"); + talloc_free(ctrl); + return NULL; + } + control->ctxid_len = len; + control->contextId = talloc_memdup(control, ctxid, + control->ctxid_len); + if (control->contextId == NULL) { + ldb_oom(ldb); + talloc_free(ctrl); + return NULL; + } + } else { + control->ctxid_len = 0; + control->contextId = NULL; + } + ctrl->data = control; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DIRSYNC_NAME) == 0) { + struct ldb_dirsync_control *control; + const char *p; + char *cookie = NULL; + int crit, max_attrs, ret; + uint32_t flags; + + cookie = talloc_zero_array(ctrl, char, + strlen(control_strings) + 1); + if (cookie == NULL) { + ldb_oom(ldb); + talloc_free(ctrl); + return NULL; + } + + p = &(control_strings[sizeof(LDB_CONTROL_DIRSYNC_NAME)]); + ret = sscanf(p, "%d:%u:%d:%[^$]", &crit, &flags, &max_attrs, cookie); + + if ((ret < 3) || (crit < 0) || (crit > 1) || (max_attrs < 0)) { + ldb_set_errstring(ldb, + "invalid dirsync control syntax\n" + " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n" + " note: b = boolean, n = number, o = b64 binary blob"); + talloc_free(ctrl); + return NULL; + } + + /* w2k3 seems to ignore the parameter, + * but w2k sends a wrong cookie when this value is to small + * this would cause looping forever, while getting + * the same data and same cookie forever + */ + if (max_attrs == 0) max_attrs = 0x0FFFFFFF; + + ctrl->oid = LDB_CONTROL_DIRSYNC_OID; + ctrl->critical = crit; + control = talloc(ctrl, struct ldb_dirsync_control); + if (control == NULL) { + ldb_oom(ldb); + talloc_free(ctrl); + return NULL; + } + control->flags = flags; + control->max_attributes = max_attrs; + if (*cookie) { + int len = ldb_base64_decode(cookie); + if (len < 0) { + ldb_set_errstring(ldb, + "invalid dirsync cookie\n"); + talloc_free(ctrl); + return NULL; + } + control->cookie_len = len; + control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len); + if (control->cookie == NULL) { + ldb_oom(ldb); + talloc_free(ctrl); + return NULL; + } + } else { + control->cookie = NULL; + control->cookie_len = 0; + } + ctrl->data = control; + TALLOC_FREE(cookie); + + return ctrl; + } + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DIRSYNC_EX_NAME) == 0) { + struct ldb_dirsync_control *control; + const char *p; + char *cookie = NULL; + int crit, max_attrs, ret; + uint32_t flags; + + cookie = talloc_zero_array(ctrl, char, + strlen(control_strings) + 1); + if (cookie == NULL) { + ldb_oom(ldb); + talloc_free(ctrl); + return NULL; + } + + p = &(control_strings[sizeof(LDB_CONTROL_DIRSYNC_EX_NAME)]); + ret = sscanf(p, "%d:%u:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie); + + if ((ret < 3) || (crit < 0) || (crit > 1) || (max_attrs < 0)) { + ldb_set_errstring(ldb, + "invalid dirsync_ex control syntax\n" + " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n" + " note: b = boolean, n = number, o = b64 binary blob"); + talloc_free(ctrl); + return NULL; + } + + /* w2k3 seems to ignore the parameter, + * but w2k sends a wrong cookie when this value is to small + * this would cause looping forever, while getting + * the same data and same cookie forever + */ + if (max_attrs == 0) max_attrs = 0x0FFFFFFF; + + ctrl->oid = LDB_CONTROL_DIRSYNC_EX_OID; + ctrl->critical = crit; + control = talloc(ctrl, struct ldb_dirsync_control); + if (control == NULL) { + ldb_oom(ldb); + talloc_free(ctrl); + return NULL; + } + control->flags = flags; + control->max_attributes = max_attrs; + if (*cookie) { + int len = ldb_base64_decode(cookie); + if (len < 0) { + ldb_set_errstring(ldb, + "invalid dirsync_ex cookie" + " (probably too long)\n"); + talloc_free(ctrl); + return NULL; + } + control->cookie_len = len; + control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len); + if (control->cookie == NULL) { + ldb_oom(ldb); + talloc_free(ctrl); + return NULL; + } + } else { + control->cookie = NULL; + control->cookie_len = 0; + } + ctrl->data = control; + TALLOC_FREE(cookie); + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_ASQ_NAME) == 0) { + struct ldb_asq_control *control; + const char *p; + char attr[256]; + int crit, ret; + + attr[0] = '\0'; + p = &(control_strings[sizeof(LDB_CONTROL_ASQ_NAME)]); + ret = sscanf(p, "%d:%255[^$]", &crit, attr); + if ((ret != 2) || (crit < 0) || (crit > 1) || (attr[0] == '\0')) { + ldb_set_errstring(ldb, + "invalid asq control syntax\n" + " syntax: crit(b):attr(s)\n" + " note: b = boolean, s = string"); + talloc_free(ctrl); + return NULL; + } + + ctrl->oid = LDB_CONTROL_ASQ_OID; + ctrl->critical = crit; + control = talloc(ctrl, struct ldb_asq_control); + if (control == NULL) { + ldb_oom(ldb); + talloc_free(ctrl); + return NULL; + } + control->request = 1; + control->source_attribute = talloc_strdup(control, attr); + control->src_attr_len = strlen(attr); + ctrl->data = control; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_EXTENDED_DN_NAME) == 0) { + struct ldb_extended_dn_control *control; + const char *p; + int crit, type, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_EXTENDED_DN_NAME)]); + ret = sscanf(p, "%d:%d", &crit, &type); + if ((ret != 2) || (crit < 0) || (crit > 1) || (type < 0) || (type > 1)) { + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + ldb_set_errstring(ldb, + "invalid extended_dn control syntax\n" + " syntax: crit(b)[:type(i)]\n" + " note: b = boolean\n" + " i = integer\n" + " valid values are: 0 - hexadecimal representation\n" + " 1 - normal string representation"); + talloc_free(ctrl); + return NULL; + } + control = NULL; + } else { + control = talloc(ctrl, struct ldb_extended_dn_control); + if (control == NULL) { + ldb_oom(ldb); + talloc_free(ctrl); + return NULL; + } + control->type = type; + } + + ctrl->oid = LDB_CONTROL_EXTENDED_DN_OID; + ctrl->critical = crit; + ctrl->data = talloc_steal(ctrl, control); + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SD_FLAGS_NAME) == 0) { + struct ldb_sd_flags_control *control; + const char *p; + int crit, ret; + unsigned secinfo_flags; + + p = &(control_strings[sizeof(LDB_CONTROL_SD_FLAGS_NAME)]); + ret = sscanf(p, "%d:%u", &crit, &secinfo_flags); + if ((ret != 2) || (crit < 0) || (crit > 1) || (secinfo_flags > 0xF)) { + ldb_set_errstring(ldb, + "invalid sd_flags control syntax\n" + " syntax: crit(b):secinfo_flags(n)\n" + " note: b = boolean, n = number"); + talloc_free(ctrl); + return NULL; + } + + ctrl->oid = LDB_CONTROL_SD_FLAGS_OID; + ctrl->critical = crit; + control = talloc(ctrl, struct ldb_sd_flags_control); + if (control == NULL) { + ldb_oom(ldb); + talloc_free(ctrl); + return NULL; + } + + control->secinfo_flags = secinfo_flags; + ctrl->data = control; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SEARCH_OPTIONS_NAME) == 0) { + struct ldb_search_options_control *control; + const char *p; + int crit, ret; + unsigned search_options; + + p = &(control_strings[sizeof(LDB_CONTROL_SEARCH_OPTIONS_NAME)]); + ret = sscanf(p, "%d:%u", &crit, &search_options); + if ((ret != 2) || (crit < 0) || (crit > 1) || (search_options > 0xF)) { + ldb_set_errstring(ldb, + "invalid search_options control syntax\n" + " syntax: crit(b):search_options(n)\n" + " note: b = boolean, n = number"); + talloc_free(ctrl); + return NULL; + } + + ctrl->oid = LDB_CONTROL_SEARCH_OPTIONS_OID; + ctrl->critical = crit; + control = talloc(ctrl, struct ldb_search_options_control); + if (control == NULL) { + ldb_oom(ldb); + talloc_free(ctrl); + return NULL; + } + + control->search_options = search_options; + ctrl->data = control; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_BYPASS_OPERATIONAL_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_BYPASS_OPERATIONAL_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + ldb_set_errstring(ldb, + "invalid bypassopreational control syntax\n" + " syntax: crit(b)\n" + " note: b = boolean"); + talloc_free(ctrl); + return NULL; + } + + ctrl->oid = LDB_CONTROL_BYPASS_OPERATIONAL_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RELAX_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_RELAX_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + ldb_set_errstring(ldb, + "invalid relax control syntax\n" + " syntax: crit(b)\n" + " note: b = boolean"); + talloc_free(ctrl); + return NULL; + } + + ctrl->oid = LDB_CONTROL_RELAX_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RECALCULATE_SD_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_RECALCULATE_SD_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + ldb_set_errstring(ldb, + "invalid recalculate_sd control syntax\n" + " syntax: crit(b)\n" + " note: b = boolean"); + talloc_free(ctrl); + return NULL; + } + + ctrl->oid = LDB_CONTROL_RECALCULATE_SD_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DOMAIN_SCOPE_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_DOMAIN_SCOPE_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + ldb_set_errstring(ldb, + "invalid domain_scope control syntax\n" + " syntax: crit(b)\n" + " note: b = boolean"); + talloc_free(ctrl); + return NULL; + } + + ctrl->oid = LDB_CONTROL_DOMAIN_SCOPE_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PAGED_RESULTS_NAME) == 0) { + struct ldb_paged_control *control; + const char *p; + char cookie[1024]; + int crit, size, ret; + + cookie[0] = '\0'; + p = &(control_strings[sizeof(LDB_CONTROL_PAGED_RESULTS_NAME)]); + ret = sscanf(p, "%d:%d:%1023[^$]", &crit, &size, cookie); + if ((ret < 2) || (ret > 3) || (crit < 0) || (crit > 1) || + (size < 0)) { + ldb_set_errstring(ldb, + "invalid paged_results control syntax\n" + " syntax: crit(b):size(n)[:cookie(base64)]\n" + " note: b = boolean, n = number"); + talloc_free(ctrl); + return NULL; + } + + ctrl->oid = LDB_CONTROL_PAGED_RESULTS_OID; + ctrl->critical = crit; + control = talloc(ctrl, struct ldb_paged_control); + if (control == NULL) { + ldb_oom(ldb); + talloc_free(ctrl); + return NULL; + } + + control->size = size; + if (cookie[0] != '\0') { + int len = ldb_base64_decode(cookie); + if (len < 0) { + ldb_set_errstring(ldb, + "invalid paged_results cookie" + " (probably too long)\n"); + talloc_free(ctrl); + return NULL; + } + control->cookie_len = len; + control->cookie = talloc_memdup(control, cookie, control->cookie_len); + if (control->cookie == NULL) { + ldb_oom(ldb); + talloc_free(ctrl); + return NULL; + } + } else { + control->cookie = NULL; + control->cookie_len = 0; + } + ctrl->data = control; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SERVER_SORT_NAME) == 0) { + struct ldb_server_sort_control **control; + const char *p; + char attr[256]; + char rule[128]; + int crit, rev, ret; + + attr[0] = '\0'; + rule[0] = '\0'; + p = &(control_strings[sizeof(LDB_CONTROL_SERVER_SORT_NAME)]); + ret = sscanf(p, "%d:%d:%255[^:]:%127[^:]", &crit, &rev, attr, rule); + if ((ret < 3) || (crit < 0) || (crit > 1) || (rev < 0 ) || (rev > 1) ||attr[0] == '\0') { + ldb_set_errstring(ldb, + "invalid server_sort control syntax\n" + " syntax: crit(b):rev(b):attr(s)[:rule(s)]\n" + " note: b = boolean, s = string"); + talloc_free(ctrl); + return NULL; + } + ctrl->oid = LDB_CONTROL_SERVER_SORT_OID; + ctrl->critical = crit; + control = talloc_array(ctrl, struct ldb_server_sort_control *, 2); + if (control == NULL) { + ldb_oom(ldb); + talloc_free(ctrl); + return NULL; + } + + control[0] = talloc(control, struct ldb_server_sort_control); + if (control[0] == NULL) { + ldb_oom(ldb); + talloc_free(ctrl); + return NULL; + } + + control[0]->attributeName = talloc_strdup(control, attr); + if (control[0]->attributeName == NULL) { + ldb_oom(ldb); + talloc_free(ctrl); + return NULL; + } + + if (rule[0]) { + control[0]->orderingRule = talloc_strdup(control, rule); + if (control[0]->orderingRule == NULL) { + ldb_oom(ldb); + talloc_free(ctrl); + return NULL; + } + } else { + control[0]->orderingRule = NULL; + } + control[0]->reverse = rev; + control[1] = NULL; + ctrl->data = control; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_NOTIFICATION_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_NOTIFICATION_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + ldb_set_errstring(ldb, + "invalid notification control syntax\n" + " syntax: crit(b)\n" + " note: b = boolean"); + talloc_free(ctrl); + return NULL; + } + + ctrl->oid = LDB_CONTROL_NOTIFICATION_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_TREE_DELETE_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_TREE_DELETE_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + ldb_set_errstring(ldb, + "invalid tree_delete control syntax\n" + " syntax: crit(b)\n" + " note: b = boolean"); + talloc_free(ctrl); + return NULL; + } + + ctrl->oid = LDB_CONTROL_TREE_DELETE_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_DELETED_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_SHOW_DELETED_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + ldb_set_errstring(ldb, + "invalid show_deleted control syntax\n" + " syntax: crit(b)\n" + " note: b = boolean"); + talloc_free(ctrl); + return NULL; + } + + ctrl->oid = LDB_CONTROL_SHOW_DELETED_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + ldb_set_errstring(ldb, + "invalid show_deactivated_link control syntax\n" + " syntax: crit(b)\n" + " note: b = boolean"); + talloc_free(ctrl); + return NULL; + } + + ctrl->oid = LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_RECYCLED_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_SHOW_RECYCLED_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + ldb_set_errstring(ldb, + "invalid show_recycled control syntax\n" + " syntax: crit(b)\n" + " note: b = boolean"); + talloc_free(ctrl); + return NULL; + } + + ctrl->oid = LDB_CONTROL_SHOW_RECYCLED_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PERMISSIVE_MODIFY_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_PERMISSIVE_MODIFY_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + ldb_set_errstring(ldb, + "invalid permissive_modify control syntax\n" + " syntax: crit(b)\n" + " note: b = boolean"); + talloc_free(ctrl); + return NULL; + } + + ctrl->oid = LDB_CONTROL_PERMISSIVE_MODIFY_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_REVEAL_INTERNALS_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_REVEAL_INTERNALS_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + ldb_set_errstring(ldb, + "invalid reveal_internals control syntax\n" + " syntax: crit(b)\n" + " note: b = boolean"); + talloc_free(ctrl); + return NULL; + } + + ctrl->oid = LDB_CONTROL_REVEAL_INTERNALS; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (strncmp(control_strings, "local_oid:", 10) == 0) { + const char *p; + int crit = 0, ret = 0; + char oid[256]; + + oid[0] = '\0'; + p = &(control_strings[10]); + ret = sscanf(p, "%255[^:]:%d", oid, &crit); + + if ((ret != 2) || strlen(oid) == 0 || (crit < 0) || (crit > 1)) { + ldb_set_errstring(ldb, + "invalid local_oid control syntax\n" + " syntax: oid(s):crit(b)\n" + " note: b = boolean, s = string"); + talloc_free(ctrl); + return NULL; + } + + ctrl->oid = talloc_strdup(ctrl, oid); + if (!ctrl->oid) { + ldb_oom(ldb); + talloc_free(ctrl); + return NULL; + } + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RODC_DCPROMO_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_RODC_DCPROMO_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + ldb_set_errstring(ldb, + "invalid rodc_join control syntax\n" + " syntax: crit(b)\n" + " note: b = boolean"); + talloc_free(ctrl); + return NULL; + } + + ctrl->oid = LDB_CONTROL_RODC_DCPROMO_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PROVISION_NAME) == 0) { + const char *p; + int crit, ret; + + p = &(control_strings[sizeof(LDB_CONTROL_PROVISION_NAME)]); + ret = sscanf(p, "%d", &crit); + if ((ret != 1) || (crit < 0) || (crit > 1)) { + ldb_set_errstring(ldb, + "invalid provision control syntax\n" + " syntax: crit(b)\n" + " note: b = boolean"); + talloc_free(ctrl); + return NULL; + } + + ctrl->oid = LDB_CONTROL_PROVISION_OID; + ctrl->critical = crit; + ctrl->data = NULL; + + return ctrl; + } + if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_VERIFY_NAME_NAME) == 0) { + const char *p; + char gc[1024]; + int crit, flags, ret; + struct ldb_verify_name_control *control; + + gc[0] = '\0'; + + p = &(control_strings[sizeof(LDB_CONTROL_VERIFY_NAME_NAME)]); + ret = sscanf(p, "%d:%d:%1023[^$]", &crit, &flags, gc); + if ((ret != 3) || (crit < 0) || (crit > 1)) { + ret = sscanf(p, "%d:%d", &crit, &flags); + if ((ret != 2) || (crit < 0) || (crit > 1)) { + ldb_set_errstring(ldb, + "invalid verify_name control syntax\n" + " syntax: crit(b):flags(i)[:gc(s)]\n" + " note: b = boolean" + " note: i = integer" + " note: s = string"); + talloc_free(ctrl); + return NULL; + } + } + + ctrl->oid = LDB_CONTROL_VERIFY_NAME_OID; + ctrl->critical = crit; + control = talloc(ctrl, struct ldb_verify_name_control); + if (control == NULL) { + ldb_oom(ldb); + talloc_free(ctrl); + return NULL; + } + + control->gc = talloc_strdup(control, gc); + if (control->gc == NULL) { + ldb_oom(ldb); + talloc_free(ctrl); + return NULL; + } + + control->gc_len = strlen(gc); + control->flags = flags; + ctrl->data = control; + return ctrl; + } + /* + * When no matching control has been found. + */ + return NULL; +} + +/* Parse controls from the format used on the command line and in ejs */ +struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char **control_strings) +{ + unsigned int i; + struct ldb_control **ctrl; + + if (control_strings == NULL || control_strings[0] == NULL) + return NULL; + + for (i = 0; control_strings[i]; i++); + + ctrl = talloc_array(mem_ctx, struct ldb_control *, i + 1); + + ldb_reset_err_string(ldb); + for (i = 0; control_strings[i]; i++) { + ctrl[i] = ldb_parse_control_from_string(ldb, ctrl, control_strings[i]); + if (ctrl[i] == NULL) { + if (ldb_errstring(ldb) == NULL) { + /* no controls matched, throw an error */ + ldb_asprintf_errstring(ldb, "Invalid control name: '%s'", control_strings[i]); + } + talloc_free(ctrl); + return NULL; + } + } + + ctrl[i] = NULL; + + return ctrl; +} + + diff --git a/ldb-2.0.8/common/ldb_debug.c b/ldb-2.0.8/common/ldb_debug.c new file mode 100644 index 0000000..d5e9e7a --- /dev/null +++ b/ldb-2.0.8/common/ldb_debug.c @@ -0,0 +1,150 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb debug + * + * Description: functions for printing debug messages + * + * Author: Andrew Tridgell + */ + +#include "ldb_private.h" + +/* + this allows the user to choose their own debug function +*/ +int ldb_set_debug(struct ldb_context *ldb, + void (*debug)(void *context, enum ldb_debug_level level, + const char *fmt, va_list ap), + void *context) +{ + ldb->debug_ops.debug = debug; + ldb->debug_ops.context = context; + return 0; +} + +/* + debug function for ldb_set_debug_stderr +*/ +static void ldb_debug_stderr(void *context, enum ldb_debug_level level, + const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); +static void ldb_debug_stderr(void *context, enum ldb_debug_level level, + const char *fmt, va_list ap) +{ + if (level <= LDB_DEBUG_WARNING) { + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + } +} + +static void ldb_debug_stderr_all(void *context, enum ldb_debug_level level, + const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); +static void ldb_debug_stderr_all(void *context, enum ldb_debug_level level, + const char *fmt, va_list ap) +{ + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); +} + +/* + convenience function to setup debug messages on stderr + messages of level LDB_DEBUG_WARNING and higher are printed +*/ +int ldb_set_debug_stderr(struct ldb_context *ldb) +{ + return ldb_set_debug(ldb, ldb_debug_stderr, ldb); +} + +/* + log a message (va_list helper for ldb_tevent_debug) +*/ +void ldb_vdebug(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, va_list ap) +{ + if (ldb->debug_ops.debug == NULL) { + if (ldb->flags & LDB_FLG_ENABLE_TRACING) { + ldb_set_debug(ldb, ldb_debug_stderr_all, ldb); + } else { + ldb_set_debug_stderr(ldb); + } + } + ldb->debug_ops.debug(ldb->debug_ops.context, level, fmt, ap); +} + +/* + log a message +*/ +void ldb_debug(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + ldb_vdebug(ldb, level, fmt, ap); + va_end(ap); +} + +/* + add to an accumulated log message + */ +void ldb_debug_add(struct ldb_context *ldb, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + if (ldb->partial_debug == NULL) { + ldb->partial_debug = talloc_vasprintf(ldb, fmt, ap); + } else { + ldb->partial_debug = talloc_vasprintf_append(ldb->partial_debug, + fmt, ap); + } + va_end(ap); +} + +/* + send the accumulated log message, and free it + */ +void ldb_debug_end(struct ldb_context *ldb, enum ldb_debug_level level) +{ + ldb_debug(ldb, level, "%s", ldb->partial_debug); + talloc_free(ldb->partial_debug); + ldb->partial_debug = NULL; +} + +/* + log a message, and set the ldb error string to the same message +*/ +void ldb_debug_set(struct ldb_context *ldb, enum ldb_debug_level level, + const char *fmt, ...) +{ + va_list ap; + char *msg; + va_start(ap, fmt); + msg = talloc_vasprintf(ldb, fmt, ap); + va_end(ap); + if (msg != NULL) { + ldb_set_errstring(ldb, msg); + ldb_debug(ldb, level, "%s", msg); + } + talloc_free(msg); +} + diff --git a/ldb-2.0.8/common/ldb_dn.c b/ldb-2.0.8/common/ldb_dn.c new file mode 100644 index 0000000..83f94e3 --- /dev/null +++ b/ldb-2.0.8/common/ldb_dn.c @@ -0,0 +1,2240 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2005 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb dn creation and manipulation utility functions + * + * Description: - explode a dn into it's own basic elements + * and put them in a structure (only if necessary) + * - manipulate ldb_dn structures + * + * Author: Simo Sorce + */ + +#include "ldb_private.h" +#include + +#define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed + +#define LDB_FREE(x) do { talloc_free(x); x = NULL; } while(0) + +/** + internal ldb exploded dn structures +*/ +struct ldb_dn_component { + + char *name; + struct ldb_val value; + + char *cf_name; + struct ldb_val cf_value; +}; + +struct ldb_dn_ext_component { + + const char *name; + struct ldb_val value; +}; + +struct ldb_dn { + + struct ldb_context *ldb; + + /* Special DNs are always linearized */ + bool special; + bool invalid; + + bool valid_case; + + char *linearized; + char *ext_linearized; + char *casefold; + + unsigned int comp_num; + struct ldb_dn_component *components; + + unsigned int ext_comp_num; + struct ldb_dn_ext_component *ext_components; +}; + +/* it is helpful to be able to break on this in gdb */ +static void ldb_dn_mark_invalid(struct ldb_dn *dn) +{ + dn->invalid = true; +} + +/* strdn may be NULL */ +struct ldb_dn *ldb_dn_from_ldb_val(TALLOC_CTX *mem_ctx, + struct ldb_context *ldb, + const struct ldb_val *strdn) +{ + struct ldb_dn *dn; + + if (ldb == NULL || strdn == NULL) { + return NULL; + } + if (strdn->data + && (strnlen((const char*)strdn->data, strdn->length) != strdn->length)) { + /* The RDN must not contain a character with value 0x0 */ + return NULL; + } + + dn = talloc_zero(mem_ctx, struct ldb_dn); + LDB_DN_NULL_FAILED(dn); + + dn->ldb = talloc_get_type(ldb, struct ldb_context); + if (dn->ldb == NULL) { + /* the caller probably got the arguments to + ldb_dn_new() mixed up */ + talloc_free(dn); + return NULL; + } + + if (strdn->data && strdn->length) { + const char *data = (const char *)strdn->data; + size_t length = strdn->length; + + if (data[0] == '@') { + dn->special = true; + } + dn->ext_linearized = talloc_strndup(dn, data, length); + LDB_DN_NULL_FAILED(dn->ext_linearized); + + if (data[0] == '<') { + const char *p_save, *p = dn->ext_linearized; + do { + p_save = p; + p = strstr(p, ">;"); + if (p) { + p = p + 2; + } + } while (p); + + if (p_save == dn->ext_linearized) { + dn->linearized = talloc_strdup(dn, ""); + } else { + dn->linearized = talloc_strdup(dn, p_save); + } + LDB_DN_NULL_FAILED(dn->linearized); + } else { + dn->linearized = dn->ext_linearized; + dn->ext_linearized = NULL; + } + } else { + dn->linearized = talloc_strdup(dn, ""); + LDB_DN_NULL_FAILED(dn->linearized); + } + + return dn; + +failed: + talloc_free(dn); + return NULL; +} + +/* strdn may be NULL */ +struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx, + struct ldb_context *ldb, + const char *strdn) +{ + struct ldb_val blob; + blob.data = discard_const_p(uint8_t, strdn); + blob.length = strdn ? strlen(strdn) : 0; + return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob); +} + +struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx, + struct ldb_context *ldb, + const char *new_fmt, ...) +{ + char *strdn; + va_list ap; + + if (! ldb) return NULL; + + va_start(ap, new_fmt); + strdn = talloc_vasprintf(mem_ctx, new_fmt, ap); + va_end(ap); + + if (strdn) { + struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn); + talloc_free(strdn); + return dn; + } + + return NULL; +} + +/* see RFC2253 section 2.4 */ +static int ldb_dn_escape_internal(char *dst, const char *src, int len) +{ + char c; + char *d; + int i; + d = dst; + + for (i = 0; i < len; i++){ + c = src[i]; + switch (c) { + case ' ': + if (i == 0 || i == len - 1) { + /* if at the beginning or end + * of the string then escape */ + *d++ = '\\'; + *d++ = c; + } else { + /* otherwise don't escape */ + *d++ = c; + } + break; + + case '#': + /* despite the RFC, windows escapes a # + anywhere in the string */ + case ',': + case '+': + case '"': + case '\\': + case '<': + case '>': + case '?': + /* these must be escaped using \c form */ + *d++ = '\\'; + *d++ = c; + break; + + case ';': + case '\r': + case '\n': + case '=': + case '\0': { + /* any others get \XX form */ + unsigned char v; + const char *hexbytes = "0123456789ABCDEF"; + v = (const unsigned char)c; + *d++ = '\\'; + *d++ = hexbytes[v>>4]; + *d++ = hexbytes[v&0xF]; + break; + } + default: + *d++ = c; + } + } + + /* return the length of the resulting string */ + return (d - dst); +} + +char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value) +{ + char *dst; + size_t len; + if (!value.length) + return NULL; + + /* allocate destination string, it will be at most 3 times the source */ + dst = talloc_array(mem_ctx, char, value.length * 3 + 1); + if ( ! dst) { + talloc_free(dst); + return NULL; + } + + len = ldb_dn_escape_internal(dst, (const char *)value.data, value.length); + + dst = talloc_realloc(mem_ctx, dst, char, len + 1); + if ( ! dst) { + talloc_free(dst); + return NULL; + } + dst[len] = '\0'; + return dst; +} + +/* + explode a DN string into a ldb_dn structure + based on RFC4514 except that we don't support multiple valued RDNs + + TODO: according to MS-ADTS:3.1.1.5.2 Naming Constraints + DN must be compliant with RFC2253 +*/ +static bool ldb_dn_explode(struct ldb_dn *dn) +{ + char *p, *ex_name = NULL, *ex_value = NULL, *data, *d, *dt, *t; + bool trim = true; + bool in_extended = true; + bool in_ex_name = false; + bool in_ex_value = false; + bool in_attr = false; + bool in_value = false; + bool in_quote = false; + bool is_oid = false; + bool escape = false; + unsigned int x; + size_t l = 0; + int ret; + char *parse_dn; + bool is_index; + + if (dn == NULL || dn->invalid == true) { + return false; + } + + if (dn->components != NULL) { + return true; + } + + if (dn->ext_linearized != NULL) { + parse_dn = dn->ext_linearized; + } else { + parse_dn = dn->linearized; + } + + if (parse_dn == NULL) { + return false; + } + + is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0); + + /* Empty DNs */ + if (parse_dn[0] == '\0') { + return true; + } + + /* Special DNs case */ + if (dn->special == true) { + return true; + } + + LDB_FREE(dn->ext_components); + dn->ext_comp_num = 0; + dn->comp_num = 0; + + /* in the common case we have 3 or more components */ + /* make sure all components are zeroed, other functions depend on it */ + dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3); + if (dn->components == NULL) { + return false; + } + + /* Components data space is allocated here once */ + data = talloc_array(dn->components, char, strlen(parse_dn) + 1); + if (data == NULL) { + goto failed; + } + + p = parse_dn; + t = NULL; + d = dt = data; + + while (*p) { + if (in_extended == true) { + + if (!in_ex_name && !in_ex_value) { + + if (p[0] == '<') { + p++; + ex_name = d; + in_ex_name = true; + continue; + } else { + in_extended = false; + in_attr = true; + dt = d; + + continue; + } + } + + if (in_ex_name && *p == '=') { + *d++ = '\0'; + p++; + ex_value = d; + in_ex_name = false; + in_ex_value = true; + continue; + } + + if (in_ex_value && *p == '>') { + struct ldb_dn_ext_component *ext_comp = NULL; + const struct ldb_dn_extended_syntax *ext_syntax; + struct ldb_val ex_val = { + .data = (uint8_t *)ex_value, + .length = d - ex_value + }; + + *d++ = '\0'; + p++; + in_ex_value = false; + + /* Process name and ex_value */ + + ext_comp = talloc_realloc( + dn, + dn->ext_components, + struct ldb_dn_ext_component, + dn->ext_comp_num + 1); + + if (ext_comp == NULL) { + /* ouch ! */ + goto failed; + } + + dn->ext_components = ext_comp; + + ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name); + if (ext_syntax == NULL) { + /* We don't know about this type of extended DN */ + goto failed; + } + + dn->ext_components[dn->ext_comp_num].name = ext_syntax->name; + ret = ext_syntax->read_fn(dn->ldb, dn->ext_components, + &ex_val, &dn->ext_components[dn->ext_comp_num].value); + if (ret != LDB_SUCCESS) { + ldb_dn_mark_invalid(dn); + goto failed; + } + + dn->ext_comp_num++; + + if (*p == '\0') { + /* We have reached the end (extended component only)! */ + talloc_free(data); + return true; + + } else if (*p == ';') { + p++; + continue; + } else { + ldb_dn_mark_invalid(dn); + goto failed; + } + } + + *d++ = *p++; + continue; + } + if (in_attr == true) { + if (trim == true) { + if (*p == ' ') { + p++; + continue; + } + + /* first char */ + trim = false; + + if (!isascii(*p)) { + /* attr names must be ascii only */ + ldb_dn_mark_invalid(dn); + goto failed; + } + + if (isdigit(*p)) { + is_oid = true; + } else + if ( ! isalpha(*p)) { + /* not a digit nor an alpha, + * invalid attribute name */ + ldb_dn_mark_invalid(dn); + goto failed; + } + + /* Copy this character across from parse_dn, + * now we have trimmed out spaces */ + *d++ = *p++; + continue; + } + + if (*p == ' ') { + p++; + /* valid only if we are at the end */ + trim = true; + continue; + } + + if (*p == '=') { + /* attribute terminated */ + in_attr = false; + in_value = true; + trim = true; + l = 0; + + /* Terminate this string in d + * (which is a copy of parse_dn + * with spaces trimmed) */ + *d++ = '\0'; + dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt); + if (dn->components[dn->comp_num].name == NULL) { + /* ouch */ + goto failed; + } + + dt = d; + + p++; + continue; + } + + if (!isascii(*p)) { + /* attr names must be ascii only */ + ldb_dn_mark_invalid(dn); + goto failed; + } + + if (is_oid == true && ( ! (isdigit(*p) || (*p == '.')))) { + /* not a digit nor a dot, + * invalid attribute oid */ + ldb_dn_mark_invalid(dn); + goto failed; + } else + if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) { + /* not ALPHA, DIGIT or HYPHEN */ + ldb_dn_mark_invalid(dn); + goto failed; + } + + *d++ = *p++; + continue; + } + + if (in_value == true) { + if (in_quote == true) { + if (*p == '\"') { + if (p[-1] != '\\') { + p++; + in_quote = false; + continue; + } + } + *d++ = *p++; + l++; + continue; + } + + if (trim == true) { + if (*p == ' ') { + p++; + continue; + } + + /* first char */ + trim = false; + + if (*p == '\"') { + in_quote = true; + p++; + continue; + } + } + + switch (*p) { + + /* TODO: support ber encoded values + case '#': + */ + + case ',': + if (escape == true) { + *d++ = *p++; + l++; + escape = false; + continue; + } + /* ok found value terminator */ + + if (t != NULL) { + /* trim back */ + d -= (p - t); + l -= (p - t); + } + + in_attr = true; + in_value = false; + trim = true; + + p++; + *d++ = '\0'; + + /* + * This talloc_memdup() is OK with the + * +1 because *d has been set to '\0' + * just above + */ + dn->components[dn->comp_num].value.data = \ + (uint8_t *)talloc_memdup(dn->components, dt, l + 1); + dn->components[dn->comp_num].value.length = l; + if (dn->components[dn->comp_num].value.data == NULL) { + /* ouch ! */ + goto failed; + } + talloc_set_name_const(dn->components[dn->comp_num].value.data, + (const char *)dn->components[dn->comp_num].value.data); + + dt = d; + + dn->comp_num++; + if (dn->comp_num > 2) { + dn->components = talloc_realloc(dn, + dn->components, + struct ldb_dn_component, + dn->comp_num + 1); + if (dn->components == NULL) { + /* ouch ! */ + goto failed; + } + /* make sure all components are zeroed, other functions depend on this */ + memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component)); + } + + continue; + + case '+': + case '=': + /* to main compatibility with earlier + versions of ldb indexing, we have to + accept the base64 encoded binary index + values, which contain a '+' or '=' + which should normally be escaped */ + if (is_index == true) { + if (t != NULL) { + t = NULL; + } + *d++ = *p++; + l++; + break; + } + + FALL_THROUGH; + case '\"': + case '<': + case '>': + case ';': + /* a string with not escaped specials is invalid (tested) */ + if (escape == false) { + ldb_dn_mark_invalid(dn); + goto failed; + } + escape = false; + + *d++ = *p++; + l++; + + if (t != NULL) { + t = NULL; + } + break; + + case '\\': + if (escape == false) { + escape = true; + p++; + continue; + } + escape = false; + + *d++ = *p++; + l++; + + if (t != NULL) { + t = NULL; + } + break; + + default: + if (escape == true) { + if (isxdigit(p[0]) && isxdigit(p[1])) { + if (sscanf(p, "%02x", &x) != 1) { + /* invalid escaping sequence */ + ldb_dn_mark_invalid(dn); + goto failed; + } + p += 2; + *d++ = (unsigned char)x; + } else { + *d++ = *p++; + } + + escape = false; + l++; + if (t != NULL) { + t = NULL; + } + break; + } + + if (*p == ' ') { + if (t == NULL) { + t = p; + } + } else { + if (t != NULL) { + t = NULL; + } + } + + *d++ = *p++; + l++; + + break; + } + + } + } + + if (in_attr == true || in_quote == true) { + /* invalid dn */ + ldb_dn_mark_invalid(dn); + goto failed; + } + + if (in_value == true) { + /* save last element */ + if (t != NULL) { + /* trim back */ + d -= (p - t); + l -= (p - t); + } + + *d++ = '\0'; + /* + * This talloc_memdup() is OK with the + * +1 because *d has been set to '\0' + * just above. + */ + dn->components[dn->comp_num].value.length = l; + dn->components[dn->comp_num].value.data = + (uint8_t *)talloc_memdup(dn->components, dt, l + 1); + if (dn->components[dn->comp_num].value.data == NULL) { + /* ouch */ + goto failed; + } + talloc_set_name_const(dn->components[dn->comp_num].value.data, + (const char *)dn->components[dn->comp_num].value.data); + + dn->comp_num++; + } + talloc_free(data); + return true; + +failed: + LDB_FREE(dn->components); /* "data" is implicitly free'd */ + dn->comp_num = 0; + LDB_FREE(dn->ext_components); + dn->ext_comp_num = 0; + + return false; +} + +bool ldb_dn_validate(struct ldb_dn *dn) +{ + return ldb_dn_explode(dn); +} + +const char *ldb_dn_get_linearized(struct ldb_dn *dn) +{ + unsigned int i; + size_t len; + char *d, *n; + + if ( ! dn || ( dn->invalid)) return NULL; + + if (dn->linearized) return dn->linearized; + + if ( ! dn->components) { + ldb_dn_mark_invalid(dn); + return NULL; + } + + if (dn->comp_num == 0) { + dn->linearized = talloc_strdup(dn, ""); + if ( ! dn->linearized) return NULL; + return dn->linearized; + } + + /* calculate maximum possible length of DN */ + for (len = 0, i = 0; i < dn->comp_num; i++) { + /* name len */ + len += strlen(dn->components[i].name); + /* max escaped data len */ + len += (dn->components[i].value.length * 3); + len += 2; /* '=' and ',' */ + } + dn->linearized = talloc_array(dn, char, len); + if ( ! dn->linearized) return NULL; + + d = dn->linearized; + + for (i = 0; i < dn->comp_num; i++) { + + /* copy the name */ + n = dn->components[i].name; + while (*n) *d++ = *n++; + + *d++ = '='; + + /* and the value */ + d += ldb_dn_escape_internal( d, + (char *)dn->components[i].value.data, + dn->components[i].value.length); + *d++ = ','; + } + + *(--d) = '\0'; + + /* don't waste more memory than necessary */ + dn->linearized = talloc_realloc(dn, dn->linearized, + char, (d - dn->linearized + 1)); + + return dn->linearized; +} + +static int ldb_dn_extended_component_compare(const void *p1, const void *p2) +{ + const struct ldb_dn_ext_component *ec1 = (const struct ldb_dn_ext_component *)p1; + const struct ldb_dn_ext_component *ec2 = (const struct ldb_dn_ext_component *)p2; + return strcmp(ec1->name, ec2->name); +} + +char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode) +{ + const char *linearized = ldb_dn_get_linearized(dn); + char *p = NULL; + unsigned int i; + + if (!linearized) { + return NULL; + } + + if (!ldb_dn_has_extended(dn)) { + return talloc_strdup(mem_ctx, linearized); + } + + if (!ldb_dn_validate(dn)) { + return NULL; + } + + /* sort the extended components by name. The idea is to make + * the resulting DNs consistent, plus to ensure that we put + * 'DELETED' first, so it can be very quickly recognised + */ + TYPESAFE_QSORT(dn->ext_components, dn->ext_comp_num, + ldb_dn_extended_component_compare); + + for (i = 0; i < dn->ext_comp_num; i++) { + const struct ldb_dn_extended_syntax *ext_syntax; + const char *name = dn->ext_components[i].name; + struct ldb_val ec_val = dn->ext_components[i].value; + struct ldb_val val; + int ret; + + ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name); + if (!ext_syntax) { + return NULL; + } + + if (mode == 1) { + ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx, + &ec_val, &val); + } else if (mode == 0) { + ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx, + &ec_val, &val); + } else { + ret = -1; + } + + if (ret != LDB_SUCCESS) { + return NULL; + } + + if (i == 0) { + p = talloc_asprintf(mem_ctx, "<%s=%.*s>", + name, + (int)val.length, + val.data); + } else { + p = talloc_asprintf_append_buffer(p, ";<%s=%.*s>", + name, + (int)val.length, + val.data); + } + + talloc_free(val.data); + + if (!p) { + return NULL; + } + } + + if (dn->ext_comp_num && *linearized) { + p = talloc_asprintf_append_buffer(p, ";%s", linearized); + } + + if (!p) { + return NULL; + } + + return p; +} + +/* + filter out all but an acceptable list of extended DN components + */ +void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list) +{ + unsigned int i; + for (i=0; iext_comp_num; i++) { + if (!ldb_attr_in_list(accept_list, dn->ext_components[i].name)) { + memmove(&dn->ext_components[i], + &dn->ext_components[i+1], + (dn->ext_comp_num-(i+1))*sizeof(dn->ext_components[0])); + dn->ext_comp_num--; + i--; + } + } + LDB_FREE(dn->ext_linearized); +} + + +char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) +{ + return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn)); +} + +/* + casefold a dn. We need to casefold the attribute names, and canonicalize + attribute values of case insensitive attributes. +*/ + +static bool ldb_dn_casefold_internal(struct ldb_dn *dn) +{ + unsigned int i; + int ret; + + if ( ! dn || dn->invalid) return false; + + if (dn->valid_case) return true; + + if (( ! dn->components) && ( ! ldb_dn_explode(dn))) { + return false; + } + + for (i = 0; i < dn->comp_num; i++) { + const struct ldb_schema_attribute *a; + + dn->components[i].cf_name = + ldb_attr_casefold(dn->components, + dn->components[i].name); + if (!dn->components[i].cf_name) { + goto failed; + } + + a = ldb_schema_attribute_by_name(dn->ldb, + dn->components[i].cf_name); + + ret = a->syntax->canonicalise_fn(dn->ldb, dn->components, + &(dn->components[i].value), + &(dn->components[i].cf_value)); + if (ret != 0) { + goto failed; + } + } + + dn->valid_case = true; + + return true; + +failed: + for (i = 0; i < dn->comp_num; i++) { + LDB_FREE(dn->components[i].cf_name); + LDB_FREE(dn->components[i].cf_value.data); + } + return false; +} + +const char *ldb_dn_get_casefold(struct ldb_dn *dn) +{ + unsigned int i; + size_t len; + char *d, *n; + + if (dn->casefold) return dn->casefold; + + if (dn->special) { + dn->casefold = talloc_strdup(dn, dn->linearized); + if (!dn->casefold) return NULL; + dn->valid_case = true; + return dn->casefold; + } + + if ( ! ldb_dn_casefold_internal(dn)) { + return NULL; + } + + if (dn->comp_num == 0) { + dn->casefold = talloc_strdup(dn, ""); + return dn->casefold; + } + + /* calculate maximum possible length of DN */ + for (len = 0, i = 0; i < dn->comp_num; i++) { + /* name len */ + len += strlen(dn->components[i].cf_name); + /* max escaped data len */ + len += (dn->components[i].cf_value.length * 3); + len += 2; /* '=' and ',' */ + } + dn->casefold = talloc_array(dn, char, len); + if ( ! dn->casefold) return NULL; + + d = dn->casefold; + + for (i = 0; i < dn->comp_num; i++) { + + /* copy the name */ + n = dn->components[i].cf_name; + while (*n) *d++ = *n++; + + *d++ = '='; + + /* and the value */ + d += ldb_dn_escape_internal( d, + (char *)dn->components[i].cf_value.data, + dn->components[i].cf_value.length); + *d++ = ','; + } + *(--d) = '\0'; + + /* don't waste more memory than necessary */ + dn->casefold = talloc_realloc(dn, dn->casefold, + char, strlen(dn->casefold) + 1); + + return dn->casefold; +} + +char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) +{ + return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn)); +} + +/* Determine if dn is below base, in the ldap tree. Used for + * evaluating a subtree search. + * 0 if they match, otherwise non-zero + */ + +int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn) +{ + int ret; + unsigned int n_base, n_dn; + + if ( ! base || base->invalid) return 1; + if ( ! dn || dn->invalid) return -1; + + if (( ! base->valid_case) || ( ! dn->valid_case)) { + if (base->linearized && dn->linearized && dn->special == base->special) { + /* try with a normal compare first, if we are lucky + * we will avoid exploding and casfolding */ + int dif; + dif = strlen(dn->linearized) - strlen(base->linearized); + if (dif < 0) { + return dif; + } + if (strcmp(base->linearized, + &dn->linearized[dif]) == 0) { + return 0; + } + } + + if ( ! ldb_dn_casefold_internal(base)) { + return 1; + } + + if ( ! ldb_dn_casefold_internal(dn)) { + return -1; + } + + } + + /* if base has more components, + * they don't have the same base */ + if (base->comp_num > dn->comp_num) { + return (dn->comp_num - base->comp_num); + } + + if ((dn->comp_num == 0) || (base->comp_num == 0)) { + if (dn->special && base->special) { + return strcmp(base->linearized, dn->linearized); + } else if (dn->special) { + return -1; + } else if (base->special) { + return 1; + } else { + return 0; + } + } + + n_base = base->comp_num - 1; + n_dn = dn->comp_num - 1; + + while (n_base != (unsigned int) -1) { + char *b_name = base->components[n_base].cf_name; + char *dn_name = dn->components[n_dn].cf_name; + + char *b_vdata = (char *)base->components[n_base].cf_value.data; + char *dn_vdata = (char *)dn->components[n_dn].cf_value.data; + + size_t b_vlen = base->components[n_base].cf_value.length; + size_t dn_vlen = dn->components[n_dn].cf_value.length; + + /* compare attr names */ + ret = strcmp(b_name, dn_name); + if (ret != 0) return ret; + + /* compare attr.cf_value. */ + if (b_vlen != dn_vlen) { + return b_vlen - dn_vlen; + } + ret = strncmp(b_vdata, dn_vdata, b_vlen); + if (ret != 0) return ret; + + n_base--; + n_dn--; + } + + return 0; +} + +/* compare DNs using casefolding compare functions. + + If they match, then return 0 + */ + +int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1) +{ + unsigned int i; + int ret; + + if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) { + return -1; + } + + if (( ! dn0->valid_case) || ( ! dn1->valid_case)) { + if (dn0->linearized && dn1->linearized) { + /* try with a normal compare first, if we are lucky + * we will avoid exploding and casfolding */ + if (strcmp(dn0->linearized, dn1->linearized) == 0) { + return 0; + } + } + + if ( ! ldb_dn_casefold_internal(dn0)) { + return 1; + } + + if ( ! ldb_dn_casefold_internal(dn1)) { + return -1; + } + + } + + if (dn0->comp_num != dn1->comp_num) { + return (dn1->comp_num - dn0->comp_num); + } + + if (dn0->comp_num == 0) { + if (dn0->special && dn1->special) { + return strcmp(dn0->linearized, dn1->linearized); + } else if (dn0->special) { + return 1; + } else if (dn1->special) { + return -1; + } else { + return 0; + } + } + + for (i = 0; i < dn0->comp_num; i++) { + char *dn0_name = dn0->components[i].cf_name; + char *dn1_name = dn1->components[i].cf_name; + + char *dn0_vdata = (char *)dn0->components[i].cf_value.data; + char *dn1_vdata = (char *)dn1->components[i].cf_value.data; + + size_t dn0_vlen = dn0->components[i].cf_value.length; + size_t dn1_vlen = dn1->components[i].cf_value.length; + + /* compare attr names */ + ret = strcmp(dn0_name, dn1_name); + if (ret != 0) { + return ret; + } + + /* compare attr.cf_value. */ + if (dn0_vlen != dn1_vlen) { + return dn0_vlen - dn1_vlen; + } + ret = strncmp(dn0_vdata, dn1_vdata, dn0_vlen); + if (ret != 0) { + return ret; + } + } + + return 0; +} + +static struct ldb_dn_component ldb_dn_copy_component( + TALLOC_CTX *mem_ctx, + struct ldb_dn_component *src) +{ + struct ldb_dn_component dst; + + memset(&dst, 0, sizeof(dst)); + + if (src == NULL) { + return dst; + } + + dst.value = ldb_val_dup(mem_ctx, &(src->value)); + if (dst.value.data == NULL) { + return dst; + } + + dst.name = talloc_strdup(mem_ctx, src->name); + if (dst.name == NULL) { + LDB_FREE(dst.value.data); + return dst; + } + + if (src->cf_value.data) { + dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value)); + if (dst.cf_value.data == NULL) { + LDB_FREE(dst.value.data); + LDB_FREE(dst.name); + return dst; + } + + dst.cf_name = talloc_strdup(mem_ctx, src->cf_name); + if (dst.cf_name == NULL) { + LDB_FREE(dst.cf_name); + LDB_FREE(dst.value.data); + LDB_FREE(dst.name); + return dst; + } + } else { + dst.cf_value.data = NULL; + dst.cf_name = NULL; + } + + return dst; +} + +static struct ldb_dn_ext_component ldb_dn_ext_copy_component( + TALLOC_CTX *mem_ctx, + struct ldb_dn_ext_component *src) +{ + struct ldb_dn_ext_component dst; + + memset(&dst, 0, sizeof(dst)); + + if (src == NULL) { + return dst; + } + + dst.value = ldb_val_dup(mem_ctx, &(src->value)); + if (dst.value.data == NULL) { + return dst; + } + + dst.name = talloc_strdup(mem_ctx, src->name); + if (dst.name == NULL) { + LDB_FREE(dst.value.data); + return dst; + } + + return dst; +} + +struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) +{ + struct ldb_dn *new_dn; + + if (!dn || dn->invalid) { + return NULL; + } + + new_dn = talloc_zero(mem_ctx, struct ldb_dn); + if ( !new_dn) { + return NULL; + } + + *new_dn = *dn; + + if (dn->components) { + unsigned int i; + + new_dn->components = + talloc_zero_array(new_dn, + struct ldb_dn_component, + dn->comp_num); + if ( ! new_dn->components) { + talloc_free(new_dn); + return NULL; + } + + for (i = 0; i < dn->comp_num; i++) { + new_dn->components[i] = + ldb_dn_copy_component(new_dn->components, + &dn->components[i]); + if ( ! new_dn->components[i].value.data) { + talloc_free(new_dn); + return NULL; + } + } + } + + if (dn->ext_components) { + unsigned int i; + + new_dn->ext_components = + talloc_zero_array(new_dn, + struct ldb_dn_ext_component, + dn->ext_comp_num); + if ( ! new_dn->ext_components) { + talloc_free(new_dn); + return NULL; + } + + for (i = 0; i < dn->ext_comp_num; i++) { + new_dn->ext_components[i] = + ldb_dn_ext_copy_component( + new_dn->ext_components, + &dn->ext_components[i]); + if ( ! new_dn->ext_components[i].value.data) { + talloc_free(new_dn); + return NULL; + } + } + } + + if (dn->casefold) { + new_dn->casefold = talloc_strdup(new_dn, dn->casefold); + if ( ! new_dn->casefold) { + talloc_free(new_dn); + return NULL; + } + } + + if (dn->linearized) { + new_dn->linearized = talloc_strdup(new_dn, dn->linearized); + if ( ! new_dn->linearized) { + talloc_free(new_dn); + return NULL; + } + } + + if (dn->ext_linearized) { + new_dn->ext_linearized = talloc_strdup(new_dn, + dn->ext_linearized); + if ( ! new_dn->ext_linearized) { + talloc_free(new_dn); + return NULL; + } + } + + return new_dn; +} + +/* modify the given dn by adding a base. + * + * return true if successful and false if not + * if false is returned the dn may be marked invalid + */ +bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base) +{ + const char *s; + char *t; + + if ( !base || base->invalid || !dn || dn->invalid) { + return false; + } + + if (dn == base) { + return false; /* or we will visit infinity */ + } + + if (dn->components) { + unsigned int i; + + if ( ! ldb_dn_validate(base)) { + return false; + } + + s = NULL; + if (dn->valid_case) { + if ( ! (s = ldb_dn_get_casefold(base))) { + return false; + } + } + + dn->components = talloc_realloc(dn, + dn->components, + struct ldb_dn_component, + dn->comp_num + base->comp_num); + if ( ! dn->components) { + ldb_dn_mark_invalid(dn); + return false; + } + + for (i = 0; i < base->comp_num; dn->comp_num++, i++) { + dn->components[dn->comp_num] = + ldb_dn_copy_component(dn->components, + &base->components[i]); + if (dn->components[dn->comp_num].value.data == NULL) { + ldb_dn_mark_invalid(dn); + return false; + } + } + + if (dn->casefold && s) { + if (*dn->casefold) { + t = talloc_asprintf(dn, "%s,%s", + dn->casefold, s); + } else { + t = talloc_strdup(dn, s); + } + LDB_FREE(dn->casefold); + dn->casefold = t; + } + } + + if (dn->linearized) { + + s = ldb_dn_get_linearized(base); + if ( ! s) { + return false; + } + + if (*dn->linearized) { + t = talloc_asprintf(dn, "%s,%s", + dn->linearized, s); + } else { + t = talloc_strdup(dn, s); + } + if ( ! t) { + ldb_dn_mark_invalid(dn); + return false; + } + LDB_FREE(dn->linearized); + dn->linearized = t; + } + + /* Wipe the ext_linearized DN, + * the GUID and SID are almost certainly no longer valid */ + LDB_FREE(dn->ext_linearized); + LDB_FREE(dn->ext_components); + dn->ext_comp_num = 0; + + return true; +} + +/* modify the given dn by adding a base. + * + * return true if successful and false if not + * if false is returned the dn may be marked invalid + */ +bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...) +{ + struct ldb_dn *base; + char *base_str; + va_list ap; + bool ret; + + if ( !dn || dn->invalid) { + return false; + } + + va_start(ap, base_fmt); + base_str = talloc_vasprintf(dn, base_fmt, ap); + va_end(ap); + + if (base_str == NULL) { + return false; + } + + base = ldb_dn_new(base_str, dn->ldb, base_str); + + ret = ldb_dn_add_base(dn, base); + + talloc_free(base_str); + + return ret; +} + +/* modify the given dn by adding children elements. + * + * return true if successful and false if not + * if false is returned the dn may be marked invalid + */ +bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child) +{ + const char *s; + char *t; + + if ( !child || child->invalid || !dn || dn->invalid) { + return false; + } + + if (dn->components) { + unsigned int n; + unsigned int i, j; + + if (dn->comp_num == 0) { + return false; + } + + if ( ! ldb_dn_validate(child)) { + return false; + } + + s = NULL; + if (dn->valid_case) { + if ( ! (s = ldb_dn_get_casefold(child))) { + return false; + } + } + + n = dn->comp_num + child->comp_num; + + dn->components = talloc_realloc(dn, + dn->components, + struct ldb_dn_component, + n); + if ( ! dn->components) { + ldb_dn_mark_invalid(dn); + return false; + } + + for (i = dn->comp_num - 1, j = n - 1; i != (unsigned int) -1; + i--, j--) { + dn->components[j] = dn->components[i]; + } + + for (i = 0; i < child->comp_num; i++) { + dn->components[i] = + ldb_dn_copy_component(dn->components, + &child->components[i]); + if (dn->components[i].value.data == NULL) { + ldb_dn_mark_invalid(dn); + return false; + } + } + + dn->comp_num = n; + + if (dn->casefold && s) { + t = talloc_asprintf(dn, "%s,%s", s, dn->casefold); + LDB_FREE(dn->casefold); + dn->casefold = t; + } + } + + if (dn->linearized) { + if (dn->linearized[0] == '\0') { + return false; + } + + s = ldb_dn_get_linearized(child); + if ( ! s) { + return false; + } + + t = talloc_asprintf(dn, "%s,%s", s, dn->linearized); + if ( ! t) { + ldb_dn_mark_invalid(dn); + return false; + } + LDB_FREE(dn->linearized); + dn->linearized = t; + } + + /* Wipe the ext_linearized DN, + * the GUID and SID are almost certainly no longer valid */ + LDB_FREE(dn->ext_linearized); + LDB_FREE(dn->ext_components); + dn->ext_comp_num = 0; + + return true; +} + +/* modify the given dn by adding children elements. + * + * return true if successful and false if not + * if false is returned the dn may be marked invalid + */ +bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...) +{ + struct ldb_dn *child; + char *child_str; + va_list ap; + bool ret; + + if ( !dn || dn->invalid) { + return false; + } + + va_start(ap, child_fmt); + child_str = talloc_vasprintf(dn, child_fmt, ap); + va_end(ap); + + if (child_str == NULL) { + return false; + } + + child = ldb_dn_new(child_str, dn->ldb, child_str); + + ret = ldb_dn_add_child(dn, child); + + talloc_free(child_str); + + return ret; +} + +/* modify the given dn by adding a single child element. + * + * return true if successful and false if not + * if false is returned the dn may be marked invalid + */ +bool ldb_dn_add_child_val(struct ldb_dn *dn, + const char *rdn, + struct ldb_val value) +{ + bool ret; + int ldb_ret; + struct ldb_dn *child = NULL; + + if ( !dn || dn->invalid) { + return false; + } + + child = ldb_dn_new(dn, dn->ldb, "X=Y"); + ret = ldb_dn_add_child(dn, child); + + if (ret == false) { + return false; + } + + ldb_ret = ldb_dn_set_component(dn, + 0, + rdn, + value); + if (ldb_ret != LDB_SUCCESS) { + return false; + } + + return true; +} + +bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num) +{ + unsigned int i; + + if ( ! ldb_dn_validate(dn)) { + return false; + } + + if (dn->comp_num < num) { + return false; + } + + /* free components */ + for (i = dn->comp_num - num; i < dn->comp_num; i++) { + LDB_FREE(dn->components[i].name); + LDB_FREE(dn->components[i].value.data); + LDB_FREE(dn->components[i].cf_name); + LDB_FREE(dn->components[i].cf_value.data); + } + + dn->comp_num -= num; + + if (dn->valid_case) { + for (i = 0; i < dn->comp_num; i++) { + LDB_FREE(dn->components[i].cf_name); + LDB_FREE(dn->components[i].cf_value.data); + } + dn->valid_case = false; + } + + LDB_FREE(dn->casefold); + LDB_FREE(dn->linearized); + + /* Wipe the ext_linearized DN, + * the GUID and SID are almost certainly no longer valid */ + LDB_FREE(dn->ext_linearized); + LDB_FREE(dn->ext_components); + dn->ext_comp_num = 0; + + return true; +} + +bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num) +{ + unsigned int i, j; + + if ( ! ldb_dn_validate(dn)) { + return false; + } + + if (dn->comp_num < num) { + return false; + } + + for (i = 0, j = num; j < dn->comp_num; i++, j++) { + if (i < num) { + LDB_FREE(dn->components[i].name); + LDB_FREE(dn->components[i].value.data); + LDB_FREE(dn->components[i].cf_name); + LDB_FREE(dn->components[i].cf_value.data); + } + dn->components[i] = dn->components[j]; + } + + dn->comp_num -= num; + + if (dn->valid_case) { + for (i = 0; i < dn->comp_num; i++) { + LDB_FREE(dn->components[i].cf_name); + LDB_FREE(dn->components[i].cf_value.data); + } + dn->valid_case = false; + } + + LDB_FREE(dn->casefold); + LDB_FREE(dn->linearized); + + /* Wipe the ext_linearized DN, + * the GUID and SID are almost certainly no longer valid */ + LDB_FREE(dn->ext_linearized); + LDB_FREE(dn->ext_components); + dn->ext_comp_num = 0; + + return true; +} + + +/* replace the components of a DN with those from another DN, without + * touching the extended components + * + * return true if successful and false if not + * if false is returned the dn may be marked invalid + */ +bool ldb_dn_replace_components(struct ldb_dn *dn, struct ldb_dn *new_dn) +{ + unsigned int i; + + if ( ! ldb_dn_validate(dn) || ! ldb_dn_validate(new_dn)) { + return false; + } + + /* free components */ + for (i = 0; i < dn->comp_num; i++) { + LDB_FREE(dn->components[i].name); + LDB_FREE(dn->components[i].value.data); + LDB_FREE(dn->components[i].cf_name); + LDB_FREE(dn->components[i].cf_value.data); + } + + dn->components = talloc_realloc(dn, + dn->components, + struct ldb_dn_component, + new_dn->comp_num); + if (dn->components == NULL) { + ldb_dn_mark_invalid(dn); + return false; + } + + dn->comp_num = new_dn->comp_num; + dn->valid_case = new_dn->valid_case; + + for (i = 0; i < dn->comp_num; i++) { + dn->components[i] = ldb_dn_copy_component(dn->components, &new_dn->components[i]); + if (dn->components[i].name == NULL) { + ldb_dn_mark_invalid(dn); + return false; + } + } + if (new_dn->linearized == NULL) { + dn->linearized = NULL; + } else { + dn->linearized = talloc_strdup(dn, new_dn->linearized); + if (dn->linearized == NULL) { + ldb_dn_mark_invalid(dn); + return false; + } + } + + return true; +} + + +struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) +{ + struct ldb_dn *new_dn; + + new_dn = ldb_dn_copy(mem_ctx, dn); + if ( !new_dn ) { + return NULL; + } + + if ( ! ldb_dn_remove_child_components(new_dn, 1)) { + talloc_free(new_dn); + return NULL; + } + + return new_dn; +} + +/* Create a 'canonical name' string from a DN: + + ie dc=samba,dc=org -> samba.org/ + uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator + + There are two formats, + the EX format has the last '/' replaced with a newline (\n). + +*/ +static char *ldb_dn_canonical(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int ex_format) { + unsigned int i; + TALLOC_CTX *tmpctx; + char *cracked = NULL; + const char *format = (ex_format ? "\n" : "/" ); + + if ( ! ldb_dn_validate(dn)) { + return NULL; + } + + tmpctx = talloc_new(mem_ctx); + + /* Walk backwards down the DN, grabbing 'dc' components at first */ + for (i = dn->comp_num - 1; i != (unsigned int) -1; i--) { + if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) { + break; + } + if (cracked) { + cracked = talloc_asprintf(tmpctx, "%s.%s", + ldb_dn_escape_value(tmpctx, + dn->components[i].value), + cracked); + } else { + cracked = ldb_dn_escape_value(tmpctx, + dn->components[i].value); + } + if (!cracked) { + goto done; + } + } + + /* Only domain components? Finish here */ + if (i == (unsigned int) -1) { + cracked = talloc_strdup_append_buffer(cracked, format); + talloc_steal(mem_ctx, cracked); + goto done; + } + + /* Now walk backwards appending remaining components */ + for (; i > 0; i--) { + cracked = talloc_asprintf_append_buffer(cracked, "/%s", + ldb_dn_escape_value(tmpctx, + dn->components[i].value)); + if (!cracked) { + goto done; + } + } + + /* Last one, possibly a newline for the 'ex' format */ + cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format, + ldb_dn_escape_value(tmpctx, + dn->components[i].value)); + + talloc_steal(mem_ctx, cracked); +done: + talloc_free(tmpctx); + return cracked; +} + +/* Wrapper functions for the above, for the two different string formats */ +char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) { + return ldb_dn_canonical(mem_ctx, dn, 0); + +} + +char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) { + return ldb_dn_canonical(mem_ctx, dn, 1); +} + +int ldb_dn_get_comp_num(struct ldb_dn *dn) +{ + if ( ! ldb_dn_validate(dn)) { + return -1; + } + return dn->comp_num; +} + +int ldb_dn_get_extended_comp_num(struct ldb_dn *dn) +{ + if ( ! ldb_dn_validate(dn)) { + return -1; + } + return dn->ext_comp_num; +} + +const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num) +{ + if ( ! ldb_dn_validate(dn)) { + return NULL; + } + if (num >= dn->comp_num) return NULL; + return dn->components[num].name; +} + +const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, + unsigned int num) +{ + if ( ! ldb_dn_validate(dn)) { + return NULL; + } + if (num >= dn->comp_num) return NULL; + return &dn->components[num].value; +} + +const char *ldb_dn_get_rdn_name(struct ldb_dn *dn) +{ + if ( ! ldb_dn_validate(dn)) { + return NULL; + } + if (dn->comp_num == 0) return NULL; + return dn->components[0].name; +} + +const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn) +{ + if ( ! ldb_dn_validate(dn)) { + return NULL; + } + if (dn->comp_num == 0) return NULL; + return &dn->components[0].value; +} + +int ldb_dn_set_component(struct ldb_dn *dn, int num, + const char *name, const struct ldb_val val) +{ + char *n; + struct ldb_val v; + + if ( ! ldb_dn_validate(dn)) { + return LDB_ERR_OTHER; + } + + if (num < 0) { + return LDB_ERR_OTHER; + } + + if ((unsigned)num >= dn->comp_num) { + return LDB_ERR_OTHER; + } + + if (val.length > val.length + 1) { + return LDB_ERR_OTHER; + } + + n = talloc_strdup(dn, name); + if ( ! n) { + return LDB_ERR_OTHER; + } + + v.length = val.length; + + /* + * This is like talloc_memdup(dn, v.data, v.length + 1), but + * avoids the over-read + */ + v.data = (uint8_t *)talloc_size(dn, v.length+1); + if ( ! v.data) { + talloc_free(n); + return LDB_ERR_OTHER; + } + memcpy(v.data, val.data, val.length); + + /* + * Enforce NUL termination outside the stated length, as is + * traditional in LDB + */ + v.data[v.length] = '\0'; + + talloc_free(dn->components[num].name); + talloc_free(dn->components[num].value.data); + dn->components[num].name = n; + dn->components[num].value = v; + + if (dn->valid_case) { + unsigned int i; + for (i = 0; i < dn->comp_num; i++) { + LDB_FREE(dn->components[i].cf_name); + LDB_FREE(dn->components[i].cf_value.data); + } + dn->valid_case = false; + } + LDB_FREE(dn->casefold); + LDB_FREE(dn->linearized); + + /* Wipe the ext_linearized DN, + * the GUID and SID are almost certainly no longer valid */ + LDB_FREE(dn->ext_linearized); + LDB_FREE(dn->ext_components); + dn->ext_comp_num = 0; + + return LDB_SUCCESS; +} + +const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, + const char *name) +{ + unsigned int i; + if ( ! ldb_dn_validate(dn)) { + return NULL; + } + for (i=0; i < dn->ext_comp_num; i++) { + if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) { + return &dn->ext_components[i].value; + } + } + return NULL; +} + +int ldb_dn_set_extended_component(struct ldb_dn *dn, + const char *name, const struct ldb_val *val) +{ + struct ldb_dn_ext_component *p; + unsigned int i; + struct ldb_val v2; + const struct ldb_dn_extended_syntax *ext_syntax; + + if ( ! ldb_dn_validate(dn)) { + return LDB_ERR_OTHER; + } + + ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name); + if (ext_syntax == NULL) { + /* We don't know how to handle this type of thing */ + return LDB_ERR_INVALID_DN_SYNTAX; + } + + for (i=0; i < dn->ext_comp_num; i++) { + if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) { + if (val) { + dn->ext_components[i].value = + ldb_val_dup(dn->ext_components, val); + + dn->ext_components[i].name = ext_syntax->name; + if (!dn->ext_components[i].value.data) { + ldb_dn_mark_invalid(dn); + return LDB_ERR_OPERATIONS_ERROR; + } + } else { + if (i != (dn->ext_comp_num - 1)) { + memmove(&dn->ext_components[i], + &dn->ext_components[i+1], + ((dn->ext_comp_num-1) - i) * + sizeof(*dn->ext_components)); + } + dn->ext_comp_num--; + + dn->ext_components = talloc_realloc(dn, + dn->ext_components, + struct ldb_dn_ext_component, + dn->ext_comp_num); + if (!dn->ext_components) { + ldb_dn_mark_invalid(dn); + return LDB_ERR_OPERATIONS_ERROR; + } + } + LDB_FREE(dn->ext_linearized); + + return LDB_SUCCESS; + } + } + + if (val == NULL) { + /* removing a value that doesn't exist is not an error */ + return LDB_SUCCESS; + } + + v2 = *val; + + p = dn->ext_components + = talloc_realloc(dn, + dn->ext_components, + struct ldb_dn_ext_component, + dn->ext_comp_num + 1); + if (!dn->ext_components) { + ldb_dn_mark_invalid(dn); + return LDB_ERR_OPERATIONS_ERROR; + } + + p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, &v2); + p[dn->ext_comp_num].name = talloc_strdup(p, name); + + if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) { + ldb_dn_mark_invalid(dn); + return LDB_ERR_OPERATIONS_ERROR; + } + dn->ext_components = p; + dn->ext_comp_num++; + + LDB_FREE(dn->ext_linearized); + + return LDB_SUCCESS; +} + +void ldb_dn_remove_extended_components(struct ldb_dn *dn) +{ + LDB_FREE(dn->ext_linearized); + LDB_FREE(dn->ext_components); + dn->ext_comp_num = 0; +} + +bool ldb_dn_is_valid(struct ldb_dn *dn) +{ + if ( ! dn) return false; + return ! dn->invalid; +} + +bool ldb_dn_is_special(struct ldb_dn *dn) +{ + if ( ! dn || dn->invalid) return false; + return dn->special; +} + +bool ldb_dn_has_extended(struct ldb_dn *dn) +{ + if ( ! dn || dn->invalid) return false; + if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true; + return dn->ext_comp_num != 0; +} + +bool ldb_dn_check_special(struct ldb_dn *dn, const char *check) +{ + if ( ! dn || dn->invalid) return false; + return ! strcmp(dn->linearized, check); +} + +bool ldb_dn_is_null(struct ldb_dn *dn) +{ + if ( ! dn || dn->invalid) return false; + if (ldb_dn_has_extended(dn)) return false; + if (dn->linearized && (dn->linearized[0] == '\0')) return true; + return false; +} + +/* + this updates dn->components, taking the components from ref_dn. + This is used by code that wants to update the DN path of a DN + while not impacting on the extended DN components + */ +int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn) +{ + dn->components = talloc_realloc(dn, dn->components, + struct ldb_dn_component, ref_dn->comp_num); + if (!dn->components) { + return LDB_ERR_OPERATIONS_ERROR; + } + memcpy(dn->components, ref_dn->components, + sizeof(struct ldb_dn_component)*ref_dn->comp_num); + dn->comp_num = ref_dn->comp_num; + + LDB_FREE(dn->casefold); + LDB_FREE(dn->linearized); + LDB_FREE(dn->ext_linearized); + + return LDB_SUCCESS; +} + +/* + minimise a DN. The caller must pass in a validated DN. + + If the DN has an extended component then only the first extended + component is kept, the DN string is stripped. + + The existing dn is modified + */ +bool ldb_dn_minimise(struct ldb_dn *dn) +{ + unsigned int i; + + if (!ldb_dn_validate(dn)) { + return false; + } + if (dn->ext_comp_num == 0) { + return true; + } + + /* free components */ + for (i = 0; i < dn->comp_num; i++) { + LDB_FREE(dn->components[i].name); + LDB_FREE(dn->components[i].value.data); + LDB_FREE(dn->components[i].cf_name); + LDB_FREE(dn->components[i].cf_value.data); + } + dn->comp_num = 0; + dn->valid_case = false; + + LDB_FREE(dn->casefold); + LDB_FREE(dn->linearized); + + /* note that we don't free dn->components as this there are + * several places in ldb_dn.c that rely on it being non-NULL + * for an exploded DN + */ + + for (i = 1; i < dn->ext_comp_num; i++) { + LDB_FREE(dn->ext_components[i].value.data); + } + dn->ext_comp_num = 1; + + dn->ext_components = talloc_realloc(dn, dn->ext_components, struct ldb_dn_ext_component, 1); + if (dn->ext_components == NULL) { + ldb_dn_mark_invalid(dn); + return false; + } + + LDB_FREE(dn->ext_linearized); + + return true; +} + +struct ldb_context *ldb_dn_get_ldb_context(struct ldb_dn *dn) +{ + return dn->ldb; +} diff --git a/ldb-2.0.8/common/ldb_ldif.c b/ldb-2.0.8/common/ldb_ldif.c new file mode 100644 index 0000000..6f7589f --- /dev/null +++ b/ldb-2.0.8/common/ldb_ldif.c @@ -0,0 +1,1108 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldif routines + * + * Description: ldif pack/unpack routines + * + * Author: Andrew Tridgell + */ + +/* + see RFC2849 for the LDIF format definition +*/ + +#include "ldb_private.h" +#include "system/locale.h" + +/* + +*/ +static int ldb_read_data_file(TALLOC_CTX *mem_ctx, struct ldb_val *value) +{ + struct stat statbuf; + char *buf; + int count, size, bytes; + int ret; + int f; + const char *fname = (const char *)value->data; + + if (strncmp(fname, "file://", 7) != 0) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + fname += 7; + + f = open(fname, O_RDONLY); + if (f == -1) { + return -1; + } + + if (fstat(f, &statbuf) != 0) { + ret = -1; + goto done; + } + + if (statbuf.st_size == 0) { + ret = -1; + goto done; + } + + value->data = (uint8_t *)talloc_size(mem_ctx, statbuf.st_size + 1); + if (value->data == NULL) { + ret = -1; + goto done; + } + value->data[statbuf.st_size] = 0; + + count = 0; + size = statbuf.st_size; + buf = (char *)value->data; + while (count < statbuf.st_size) { + bytes = read(f, buf, size); + if (bytes == -1) { + talloc_free(value->data); + ret = -1; + goto done; + } + count += bytes; + buf += bytes; + size -= bytes; + } + + value->length = statbuf.st_size; + ret = statbuf.st_size; + +done: + close(f); + return ret; +} + +/* + this base64 decoder was taken from jitterbug (written by tridge). + we might need to replace it with a new version +*/ +int ldb_base64_decode(char *s) +{ + const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + int bit_offset=0, byte_offset, idx, i, n; + uint8_t *d = (uint8_t *)s; + char *p=NULL; + + n=i=0; + + while (*s && (p=strchr(b64,*s))) { + idx = (int)(p - b64); + byte_offset = (i*6)/8; + bit_offset = (i*6)%8; + d[byte_offset] &= ~((1<<(8-bit_offset))-1); + if (bit_offset < 3) { + d[byte_offset] |= (idx << (2-bit_offset)); + n = byte_offset+1; + } else { + d[byte_offset] |= (idx >> (bit_offset-2)); + d[byte_offset+1] = 0; + d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF; + n = byte_offset+2; + } + s++; i++; + } + if (bit_offset >= 3) { + n--; + } + + if (*s && !p) { + /* the only termination allowed */ + if (*s != '=') { + return -1; + } + } + + /* null terminate */ + d[n] = 0; + return n; +} + + +/* + encode as base64 + caller frees +*/ +char *ldb_base64_encode(TALLOC_CTX *mem_ctx, const char *buf, int len) +{ + const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + int bit_offset, byte_offset, idx, i; + const uint8_t *d = (const uint8_t *)buf; + int bytes = (len*8 + 5)/6, pad_bytes = (bytes % 4) ? 4 - (bytes % 4) : 0; + char *out; + + out = talloc_array(mem_ctx, char, bytes+pad_bytes+1); + if (!out) return NULL; + + for (i=0;i> (2-bit_offset)) & 0x3F; + } else { + idx = (d[byte_offset] << (bit_offset-2)) & 0x3F; + if (byte_offset+1 < len) { + idx |= (d[byte_offset+1] >> (8-(bit_offset-2))); + } + } + out[i] = b64[idx]; + } + + for (;idata; + + if (val->length == 0) { + return 0; + } + + if (p[0] == ' ' || p[0] == ':') { + return 1; + } + + for (i=0; ilength; i++) { + if (!isprint(p[i]) || p[i] == '\n') { + return 1; + } + } + return 0; +} + +/* this macro is used to handle the return checking on fprintf_fn() */ +#define CHECK_RET do { if (ret < 0) return ret; total += ret; } while (0) + +/* + write a line folded string onto a file +*/ +static int fold_string(int (*fprintf_fn)(void *, const char *, ...), void *private_data, + const char *buf, size_t length, int start_pos) +{ + size_t i; + size_t total = 0; + int ret; + + for (i=0;imsg; + p = ldb_dn_get_extended_linearized(mem_ctx, msg->dn, 1); + ret = fprintf_fn(private_data, "dn: %s\n", p); + talloc_free(p); + CHECK_RET; + + if (ldif->changetype != LDB_CHANGETYPE_NONE) { + for (i=0;ldb_changetypes[i].name;i++) { + if (ldb_changetypes[i].changetype == ldif->changetype) { + break; + } + } + if (!ldb_changetypes[i].name) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Invalid ldif changetype %d", + ldif->changetype); + talloc_free(mem_ctx); + return -1; + } + ret = fprintf_fn(private_data, "changetype: %s\n", ldb_changetypes[i].name); + CHECK_RET; + } + + for (i=0;inum_elements;i++) { + const struct ldb_schema_attribute *a; + size_t namelen; + + if (msg->elements[i].name == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: Invalid element name (NULL) at position %d", i); + talloc_free(mem_ctx); + return -1; + } + + namelen = strlen(msg->elements[i].name); + a = ldb_schema_attribute_by_name(ldb, msg->elements[i].name); + + if (ldif->changetype == LDB_CHANGETYPE_MODIFY) { + switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) { + case LDB_FLAG_MOD_ADD: + fprintf_fn(private_data, "add: %s\n", + msg->elements[i].name); + break; + case LDB_FLAG_MOD_DELETE: + fprintf_fn(private_data, "delete: %s\n", + msg->elements[i].name); + break; + case LDB_FLAG_MOD_REPLACE: + fprintf_fn(private_data, "replace: %s\n", + msg->elements[i].name); + break; + } + } + + if (in_trace && secret_attributes && ldb_attr_in_list(secret_attributes, msg->elements[i].name)) { + /* Deliberatly skip printing this password */ + ret = fprintf_fn(private_data, "# %s::: REDACTED SECRET ATTRIBUTE\n", + msg->elements[i].name); + CHECK_RET; + continue; + } + for (j=0;jelements[i].num_values;j++) { + struct ldb_val v; + bool use_b64_encode = false; + bool copy_raw_bytes = false; + + ret = a->syntax->ldif_write_fn(ldb, mem_ctx, &msg->elements[i].values[j], &v); + if (ret != LDB_SUCCESS) { + v = msg->elements[i].values[j]; + } + + if (ldb->flags & LDB_FLG_SHOW_BINARY) { + use_b64_encode = false; + copy_raw_bytes = true; + } else if (a->flags & LDB_ATTR_FLAG_FORCE_BASE64_LDIF) { + use_b64_encode = true; + } else if (msg->elements[i].flags & + LDB_FLAG_FORCE_NO_BASE64_LDIF) { + use_b64_encode = false; + copy_raw_bytes = true; + } else { + use_b64_encode = ldb_should_b64_encode(ldb, &v); + } + + if (ret != LDB_SUCCESS || use_b64_encode) { + ret = fprintf_fn(private_data, "%s:: ", + msg->elements[i].name); + CHECK_RET; + ret = base64_encode_f(ldb, fprintf_fn, private_data, + (char *)v.data, v.length, + namelen + 3); + CHECK_RET; + ret = fprintf_fn(private_data, "\n"); + CHECK_RET; + } else { + ret = fprintf_fn(private_data, "%s: ", msg->elements[i].name); + CHECK_RET; + if (copy_raw_bytes) { + ret = fprintf_fn(private_data, "%*.*s", + v.length, v.length, (char *)v.data); + } else { + ret = fold_string(fprintf_fn, private_data, + (char *)v.data, v.length, + namelen + 2); + } + CHECK_RET; + ret = fprintf_fn(private_data, "\n"); + CHECK_RET; + } + if (v.data != msg->elements[i].values[j].data) { + talloc_free(v.data); + } + } + if (ldif->changetype == LDB_CHANGETYPE_MODIFY) { + fprintf_fn(private_data, "-\n"); + } + } + ret = fprintf_fn(private_data,"\n"); + CHECK_RET; + + talloc_free(mem_ctx); + + return total; +} + +#undef CHECK_RET + + +/* + write to ldif, using a caller supplied write method +*/ +int ldb_ldif_write(struct ldb_context *ldb, + int (*fprintf_fn)(void *, const char *, ...), + void *private_data, + const struct ldb_ldif *ldif) +{ + return ldb_ldif_write_trace(ldb, fprintf_fn, private_data, ldif, false); +} + + +/* + pull a ldif chunk, which is defined as a piece of data ending in \n\n or EOF + this routine removes any RFC2849 continuations and comments + + caller frees +*/ +static char *next_chunk(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + int (*fgetc_fn)(void *), void *private_data) +{ + size_t alloc_size=0, chunk_size = 0; + char *chunk = NULL; + int c; + int in_comment = 0; + + while ((c = fgetc_fn(private_data)) != EOF) { + if (chunk_size+1 >= alloc_size) { + char *c2; + alloc_size += 1024; + c2 = talloc_realloc(mem_ctx, chunk, char, alloc_size); + if (!c2) { + talloc_free(chunk); + errno = ENOMEM; + return NULL; + } + chunk = c2; + } + + if (in_comment) { + if (c == '\n') { + in_comment = 0; + } + continue; + } + + /* handle continuation lines - see RFC2849 */ + if (c == ' ' && chunk_size > 1 && chunk[chunk_size-1] == '\n') { + chunk_size--; + continue; + } + + /* chunks are terminated by a double line-feed */ + if (c == '\n' && chunk_size > 0 && chunk[chunk_size-1] == '\n') { + chunk[chunk_size-1] = 0; + return chunk; + } + + if (c == '#' && (chunk_size == 0 || chunk[chunk_size-1] == '\n')) { + in_comment = 1; + continue; + } + + /* ignore leading blank lines */ + if (chunk_size == 0 && c == '\n') { + continue; + } + + chunk[chunk_size++] = c; + } + + if (chunk) { + chunk[chunk_size] = 0; + } + + return chunk; +} + + +/* simple ldif attribute parser */ +static int next_attr(TALLOC_CTX *mem_ctx, char **s, const char **attr, struct ldb_val *value) +{ + char *p; + int base64_encoded = 0; + int binary_file = 0; + + if (strncmp(*s, "-\n", 2) == 0) { + value->length = 0; + *attr = "-"; + *s += 2; + return 0; + } + + p = strchr(*s, ':'); + if (!p) { + return -1; + } + + *p++ = 0; + + if (*p == ':') { + base64_encoded = 1; + p++; + } + + if (*p == '<') { + binary_file = 1; + p++; + } + + *attr = *s; + + while (*p == ' ' || *p == '\t') { + p++; + } + + value->data = (uint8_t *)p; + + p = strchr(p, '\n'); + + if (!p) { + value->length = strlen((char *)value->data); + *s = ((char *)value->data) + value->length; + } else { + value->length = p - (char *)value->data; + *s = p+1; + *p = 0; + } + + if (base64_encoded) { + int len = ldb_base64_decode((char *)value->data); + if (len == -1) { + /* it wasn't valid base64 data */ + return -1; + } + value->length = len; + } + + if (binary_file) { + int len = ldb_read_data_file(mem_ctx, value); + if (len == -1) { + /* an error occurred while trying to retrieve the file */ + return -1; + } + } + + return 0; +} + + +/* + free a message from a ldif_read +*/ +void ldb_ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *ldif) +{ + talloc_free(ldif); +} + +int ldb_ldif_parse_modrdn(struct ldb_context *ldb, + const struct ldb_ldif *ldif, + TALLOC_CTX *mem_ctx, + struct ldb_dn **_olddn, + struct ldb_dn **_newrdn, + bool *_deleteoldrdn, + struct ldb_dn **_newsuperior, + struct ldb_dn **_newdn) +{ + struct ldb_message *msg = ldif->msg; + struct ldb_val *newrdn_val = NULL; + struct ldb_val *deleteoldrdn_val = NULL; + struct ldb_val *newsuperior_val = NULL; + struct ldb_dn *olddn = NULL; + struct ldb_dn *newrdn = NULL; + bool deleteoldrdn = true; + struct ldb_dn *newsuperior = NULL; + struct ldb_dn *newdn = NULL; + struct ldb_val tmp_false; + struct ldb_val tmp_true; + bool ok; + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + + if (tmp_ctx == NULL) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "Error: talloc_new() failed"); + goto err_op; + } + + if (ldif->changetype != LDB_CHANGETYPE_MODRDN) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: invalid changetype '%d'", + ldif->changetype); + goto err_other; + } + + if (msg->num_elements < 2) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: num_elements[%u] < 2", + msg->num_elements); + goto err_other; + } + + if (msg->num_elements > 3) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: num_elements[%u] > 3", + msg->num_elements); + goto err_other; + } + +#define CHECK_ELEMENT(i, _name, v, needed) do { \ + v = NULL; \ + if (msg->num_elements < (i + 1)) { \ + if (needed) { \ + ldb_debug(ldb, LDB_DEBUG_ERROR, \ + "Error: num_elements[%u] < (%u + 1)", \ + msg->num_elements, i); \ + goto err_other; \ + } \ + } else if (ldb_attr_cmp(msg->elements[i].name, _name) != 0) { \ + ldb_debug(ldb, LDB_DEBUG_ERROR, \ + "Error: elements[%u].name[%s] != [%s]", \ + i, msg->elements[i].name, _name); \ + goto err_other; \ + } else if (msg->elements[i].flags != 0) { \ + ldb_debug(ldb, LDB_DEBUG_ERROR, \ + "Error: elements[%u].flags[0x%X} != [0x0]", \ + i, msg->elements[i].flags); \ + goto err_other; \ + } else if (msg->elements[i].num_values != 1) { \ + ldb_debug(ldb, LDB_DEBUG_ERROR, \ + "Error: elements[%u].num_values[%u] != 1", \ + i, msg->elements[i].num_values); \ + goto err_other; \ + } else { \ + v = &msg->elements[i].values[0]; \ + } \ +} while (0) + + CHECK_ELEMENT(0, "newrdn", newrdn_val, true); + CHECK_ELEMENT(1, "deleteoldrdn", deleteoldrdn_val, true); + CHECK_ELEMENT(2, "newsuperior", newsuperior_val, false); + +#undef CHECK_ELEMENT + + olddn = ldb_dn_copy(tmp_ctx, msg->dn); + if (olddn == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: failed to copy olddn '%s'", + ldb_dn_get_linearized(msg->dn)); + goto err_op; + } + + newrdn = ldb_dn_from_ldb_val(tmp_ctx, ldb, newrdn_val); + if (!ldb_dn_validate(newrdn)) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: Unable to parse dn '%s'", + (char *)newrdn_val->data); + goto err_dn; + } + + tmp_false.length = 1; + tmp_false.data = discard_const_p(uint8_t, "0"); + tmp_true.length = 1; + tmp_true.data = discard_const_p(uint8_t, "1"); + if (ldb_val_equal_exact(deleteoldrdn_val, &tmp_false) == 1) { + deleteoldrdn = false; + } else if (ldb_val_equal_exact(deleteoldrdn_val, &tmp_true) == 1) { + deleteoldrdn = true; + } else { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: deleteoldrdn value invalid '%s' not '0'/'1'", + (char *)deleteoldrdn_val->data); + goto err_attr; + } + + if (newsuperior_val) { + newsuperior = ldb_dn_from_ldb_val(tmp_ctx, ldb, newsuperior_val); + if (!ldb_dn_validate(newsuperior)) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: Unable to parse dn '%s'", + (char *)newsuperior_val->data); + goto err_dn; + } + } else { + newsuperior = ldb_dn_get_parent(tmp_ctx, msg->dn); + if (newsuperior == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: Unable to get parent dn '%s'", + ldb_dn_get_linearized(msg->dn)); + goto err_dn; + } + } + + newdn = ldb_dn_copy(tmp_ctx, newrdn); + if (newdn == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: failed to copy newrdn '%s'", + ldb_dn_get_linearized(newrdn)); + goto err_op; + } + + ok = ldb_dn_add_base(newdn, newsuperior); + if (!ok) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: failed to base '%s' to newdn '%s'", + ldb_dn_get_linearized(newsuperior), + ldb_dn_get_linearized(newdn)); + goto err_op; + } + + if (_olddn) { + *_olddn = talloc_move(mem_ctx, &olddn); + } + if (_newrdn) { + *_newrdn = talloc_move(mem_ctx, &newrdn); + } + if (_deleteoldrdn) { + *_deleteoldrdn = deleteoldrdn; + } + if (_newsuperior != NULL && _newrdn != NULL) { + if (newsuperior_val) { + *_newrdn = talloc_move(mem_ctx, &newrdn); + } else { + *_newrdn = NULL; + } + } + if (_newdn) { + *_newdn = talloc_move(mem_ctx, &newdn); + } + + talloc_free(tmp_ctx); + return LDB_SUCCESS; +err_other: + talloc_free(tmp_ctx); + return LDB_ERR_OTHER; +err_op: + talloc_free(tmp_ctx); + return LDB_ERR_OPERATIONS_ERROR; +err_attr: + talloc_free(tmp_ctx); + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; +err_dn: + talloc_free(tmp_ctx); + return LDB_ERR_INVALID_DN_SYNTAX; +} + +/* + read from a LDIF source, creating a ldb_message +*/ +struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, + int (*fgetc_fn)(void *), void *private_data) +{ + struct ldb_ldif *ldif; + struct ldb_message *msg; + const char *attr=NULL; + char *chunk=NULL, *s; + struct ldb_val value; + unsigned flags = 0; + value.data = NULL; + + ldif = talloc(ldb, struct ldb_ldif); + if (!ldif) return NULL; + + ldif->msg = ldb_msg_new(ldif); + if (ldif->msg == NULL) { + talloc_free(ldif); + return NULL; + } + + ldif->changetype = LDB_CHANGETYPE_NONE; + msg = ldif->msg; + + chunk = next_chunk(ldb, ldif, fgetc_fn, private_data); + if (!chunk) { + goto failed; + } + + s = chunk; + + if (next_attr(ldif, &s, &attr, &value) != 0) { + goto failed; + } + + /* first line must be a dn */ + if (ldb_attr_cmp(attr, "dn") != 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: First line of ldif must be a dn not '%s'", + attr); + goto failed; + } + + msg->dn = ldb_dn_from_ldb_val(msg, ldb, &value); + + if ( ! ldb_dn_validate(msg->dn)) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'", + (char *)value.data); + goto failed; + } + + while (next_attr(ldif, &s, &attr, &value) == 0) { + const struct ldb_schema_attribute *a; + struct ldb_message_element *el; + int ret, empty = 0; + + if (ldb_attr_cmp(attr, "changetype") == 0) { + int i; + for (i=0;ldb_changetypes[i].name;i++) { + if (ldb_attr_cmp((char *)value.data, ldb_changetypes[i].name) == 0) { + ldif->changetype = ldb_changetypes[i].changetype; + break; + } + } + if (!ldb_changetypes[i].name) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: Bad ldif changetype '%s'",(char *)value.data); + } + flags = 0; + continue; + } + + if (ldb_attr_cmp(attr, "add") == 0) { + flags = LDB_FLAG_MOD_ADD; + empty = 1; + } + if (ldb_attr_cmp(attr, "delete") == 0) { + flags = LDB_FLAG_MOD_DELETE; + empty = 1; + } + if (ldb_attr_cmp(attr, "replace") == 0) { + flags = LDB_FLAG_MOD_REPLACE; + empty = 1; + } + if (ldb_attr_cmp(attr, "-") == 0) { + flags = 0; + continue; + } + + if (empty) { + if (ldb_msg_add_empty(msg, (char *)value.data, flags, NULL) != 0) { + goto failed; + } + continue; + } + + el = &msg->elements[msg->num_elements-1]; + + a = ldb_schema_attribute_by_name(ldb, attr); + + if (msg->num_elements > 0 && ldb_attr_cmp(attr, el->name) == 0 && + flags == el->flags) { + /* its a continuation */ + el->values = + talloc_realloc(msg->elements, el->values, + struct ldb_val, el->num_values+1); + if (!el->values) { + goto failed; + } + ret = a->syntax->ldif_read_fn(ldb, el->values, &value, &el->values[el->num_values]); + if (ret != 0) { + goto failed; + } + if (value.length == 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: Attribute value cannot be empty for attribute '%s'", el->name); + goto failed; + } + if (value.data != el->values[el->num_values].data) { + talloc_steal(el->values, el->values[el->num_values].data); + } + el->num_values++; + } else { + /* its a new attribute */ + msg->elements = talloc_realloc(msg, msg->elements, + struct ldb_message_element, + msg->num_elements+1); + if (!msg->elements) { + goto failed; + } + el = &msg->elements[msg->num_elements]; + el->flags = flags; + el->name = talloc_strdup(msg->elements, attr); + el->values = talloc(msg->elements, struct ldb_val); + if (!el->values || !el->name) { + goto failed; + } + el->num_values = 1; + ret = a->syntax->ldif_read_fn(ldb, el->values, &value, &el->values[0]); + if (ret != 0) { + goto failed; + } + if (value.data != el->values[0].data) { + talloc_steal(el->values, el->values[0].data); + } + msg->num_elements++; + } + } + + if (ldif->changetype == LDB_CHANGETYPE_MODRDN) { + int ret; + + ret = ldb_ldif_parse_modrdn(ldb, ldif, ldif, + NULL, NULL, NULL, NULL, NULL); + if (ret != LDB_SUCCESS) { + goto failed; + } + } + + return ldif; + +failed: + talloc_free(ldif); + return NULL; +} + + + +/* + a wrapper around ldif_read() for reading from FILE* +*/ + +static int fgetc_file(void *private_data) +{ + int c; + struct ldif_read_file_state *state = + (struct ldif_read_file_state *)private_data; + c = fgetc(state->f); + if (c == '\n') { + state->line_no++; + } + return c; +} + +struct ldb_ldif *ldb_ldif_read_file_state(struct ldb_context *ldb, + struct ldif_read_file_state *state) +{ + return ldb_ldif_read(ldb, fgetc_file, state); +} + +struct ldb_ldif *ldb_ldif_read_file(struct ldb_context *ldb, FILE *f) +{ + struct ldif_read_file_state state; + state.f = f; + return ldb_ldif_read_file_state(ldb, &state); +} + +/* + a wrapper around ldif_read() for reading from const char* +*/ +struct ldif_read_string_state { + const char *s; +}; + +static int fgetc_string(void *private_data) +{ + struct ldif_read_string_state *state = + (struct ldif_read_string_state *)private_data; + if (state->s[0] != 0) { + return *state->s++; + } + return EOF; +} + +struct ldb_ldif *ldb_ldif_read_string(struct ldb_context *ldb, const char **s) +{ + struct ldif_read_string_state state; + struct ldb_ldif *ldif; + state.s = *s; + ldif = ldb_ldif_read(ldb, fgetc_string, &state); + *s = state.s; + return ldif; +} + + +/* + wrapper around ldif_write() for a file +*/ +struct ldif_write_file_state { + FILE *f; +}; + +static int fprintf_file(void *private_data, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); + +static int fprintf_file(void *private_data, const char *fmt, ...) +{ + struct ldif_write_file_state *state = + (struct ldif_write_file_state *)private_data; + int ret; + va_list ap; + + va_start(ap, fmt); + ret = vfprintf(state->f, fmt, ap); + va_end(ap); + return ret; +} + +int ldb_ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif *ldif) +{ + struct ldif_write_file_state state; + state.f = f; + return ldb_ldif_write(ldb, fprintf_file, &state, ldif); +} + +/* + wrapper around ldif_write() for a string +*/ +struct ldif_write_string_state { + char *string; +}; + +static int ldif_printf_string(void *private_data, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); + +static int ldif_printf_string(void *private_data, const char *fmt, ...) +{ + struct ldif_write_string_state *state = + (struct ldif_write_string_state *)private_data; + va_list ap; + size_t oldlen = talloc_get_size(state->string); + va_start(ap, fmt); + + state->string = talloc_vasprintf_append(state->string, fmt, ap); + va_end(ap); + if (!state->string) { + return -1; + } + + return talloc_get_size(state->string) - oldlen; +} + +char *ldb_ldif_write_redacted_trace_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + const struct ldb_ldif *ldif) +{ + struct ldif_write_string_state state; + state.string = talloc_strdup(mem_ctx, ""); + if (!state.string) { + return NULL; + } + if (ldb_ldif_write_trace(ldb, ldif_printf_string, &state, ldif, true) == -1) { + return NULL; + } + return state.string; +} + +char *ldb_ldif_write_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + const struct ldb_ldif *ldif) +{ + struct ldif_write_string_state state; + state.string = talloc_strdup(mem_ctx, ""); + if (!state.string) { + return NULL; + } + if (ldb_ldif_write(ldb, ldif_printf_string, &state, ldif) == -1) { + return NULL; + } + return state.string; +} + +/* + convenient function to turn a ldb_message into a string. Useful for + debugging + */ +char *ldb_ldif_message_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + enum ldb_changetype changetype, + const struct ldb_message *msg) +{ + struct ldb_ldif ldif; + + ldif.changetype = changetype; + ldif.msg = discard_const_p(struct ldb_message, msg); + + return ldb_ldif_write_string(ldb, mem_ctx, &ldif); +} + +/* + * convenient function to turn a ldb_message into a string. Useful for + * debugging but also safer if some of the LDIF could be sensitive. + * + * The secret attributes are specified in a 'const char * const *' within + * the LDB_SECRET_ATTRIBUTE_LIST opaque set on the ldb + * + */ +char *ldb_ldif_message_redacted_string(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + enum ldb_changetype changetype, + const struct ldb_message *msg) +{ + struct ldb_ldif ldif; + + ldif.changetype = changetype; + ldif.msg = discard_const_p(struct ldb_message, msg); + + return ldb_ldif_write_redacted_trace_string(ldb, mem_ctx, &ldif); +} diff --git a/ldb-2.0.8/common/ldb_match.c b/ldb-2.0.8/common/ldb_match.c new file mode 100644 index 0000000..829afa7 --- /dev/null +++ b/ldb-2.0.8/common/ldb_match.c @@ -0,0 +1,755 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004-2005 + Copyright (C) Simo Sorce 2005 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb expression matching + * + * Description: ldb expression matching + * + * Author: Andrew Tridgell + */ + +#include "ldb_private.h" +#include "dlinklist.h" + +/* + check if the scope matches in a search result +*/ +static int ldb_match_scope(struct ldb_context *ldb, + struct ldb_dn *base, + struct ldb_dn *dn, + enum ldb_scope scope) +{ + int ret = 0; + + if (base == NULL || dn == NULL) { + return 1; + } + + switch (scope) { + case LDB_SCOPE_BASE: + if (ldb_dn_compare(base, dn) == 0) { + ret = 1; + } + break; + + case LDB_SCOPE_ONELEVEL: + if (ldb_dn_get_comp_num(dn) == (ldb_dn_get_comp_num(base) + 1)) { + if (ldb_dn_compare_base(base, dn) == 0) { + ret = 1; + } + } + break; + + case LDB_SCOPE_SUBTREE: + default: + if (ldb_dn_compare_base(base, dn) == 0) { + ret = 1; + } + break; + } + + return ret; +} + + +/* + match if node is present +*/ +static int ldb_match_present(struct ldb_context *ldb, + const struct ldb_message *msg, + const struct ldb_parse_tree *tree, + enum ldb_scope scope, bool *matched) +{ + const struct ldb_schema_attribute *a; + struct ldb_message_element *el; + + if (ldb_attr_dn(tree->u.present.attr) == 0) { + *matched = true; + return LDB_SUCCESS; + } + + el = ldb_msg_find_element(msg, tree->u.present.attr); + if (el == NULL) { + *matched = false; + return LDB_SUCCESS; + } + + a = ldb_schema_attribute_by_name(ldb, el->name); + if (!a) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + + if (a->syntax->operator_fn) { + unsigned int i; + for (i = 0; i < el->num_values; i++) { + int ret = a->syntax->operator_fn(ldb, LDB_OP_PRESENT, a, &el->values[i], NULL, matched); + if (ret != LDB_SUCCESS) return ret; + if (*matched) return LDB_SUCCESS; + } + *matched = false; + return LDB_SUCCESS; + } + + *matched = true; + return LDB_SUCCESS; +} + +static int ldb_match_comparison(struct ldb_context *ldb, + const struct ldb_message *msg, + const struct ldb_parse_tree *tree, + enum ldb_scope scope, + enum ldb_parse_op comp_op, bool *matched) +{ + unsigned int i; + struct ldb_message_element *el; + const struct ldb_schema_attribute *a; + + /* FIXME: APPROX comparison not handled yet */ + if (comp_op == LDB_OP_APPROX) { + return LDB_ERR_INAPPROPRIATE_MATCHING; + } + + el = ldb_msg_find_element(msg, tree->u.comparison.attr); + if (el == NULL) { + *matched = false; + return LDB_SUCCESS; + } + + a = ldb_schema_attribute_by_name(ldb, el->name); + if (!a) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + + for (i = 0; i < el->num_values; i++) { + if (a->syntax->operator_fn) { + int ret; + ret = a->syntax->operator_fn(ldb, comp_op, a, &el->values[i], &tree->u.comparison.value, matched); + if (ret != LDB_SUCCESS) return ret; + if (*matched) return LDB_SUCCESS; + } else { + int ret = a->syntax->comparison_fn(ldb, ldb, &el->values[i], &tree->u.comparison.value); + + if (ret == 0) { + *matched = true; + return LDB_SUCCESS; + } + if (ret > 0 && comp_op == LDB_OP_GREATER) { + *matched = true; + return LDB_SUCCESS; + } + if (ret < 0 && comp_op == LDB_OP_LESS) { + *matched = true; + return LDB_SUCCESS; + } + } + } + + *matched = false; + return LDB_SUCCESS; +} + +/* + match a simple leaf node +*/ +static int ldb_match_equality(struct ldb_context *ldb, + const struct ldb_message *msg, + const struct ldb_parse_tree *tree, + enum ldb_scope scope, + bool *matched) +{ + unsigned int i; + struct ldb_message_element *el; + const struct ldb_schema_attribute *a; + struct ldb_dn *valuedn; + int ret; + + if (ldb_attr_dn(tree->u.equality.attr) == 0) { + valuedn = ldb_dn_from_ldb_val(ldb, ldb, &tree->u.equality.value); + if (valuedn == NULL) { + return LDB_ERR_INVALID_DN_SYNTAX; + } + + ret = ldb_dn_compare(msg->dn, valuedn); + + talloc_free(valuedn); + + *matched = (ret == 0); + return LDB_SUCCESS; + } + + /* TODO: handle the "*" case derived from an extended search + operation without the attibute type defined */ + el = ldb_msg_find_element(msg, tree->u.equality.attr); + if (el == NULL) { + *matched = false; + return LDB_SUCCESS; + } + + a = ldb_schema_attribute_by_name(ldb, el->name); + if (a == NULL) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + + for (i=0;inum_values;i++) { + if (a->syntax->operator_fn) { + ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a, + &tree->u.equality.value, &el->values[i], matched); + if (ret != LDB_SUCCESS) return ret; + if (*matched) return LDB_SUCCESS; + } else { + if (a->syntax->comparison_fn(ldb, ldb, &tree->u.equality.value, + &el->values[i]) == 0) { + *matched = true; + return LDB_SUCCESS; + } + } + } + + *matched = false; + return LDB_SUCCESS; +} + +static int ldb_wildcard_compare(struct ldb_context *ldb, + const struct ldb_parse_tree *tree, + const struct ldb_val value, bool *matched) +{ + const struct ldb_schema_attribute *a; + struct ldb_val val; + struct ldb_val cnk; + struct ldb_val *chunk; + uint8_t *save_p = NULL; + unsigned int c = 0; + + if (tree->operation != LDB_OP_SUBSTRING) { + *matched = false; + return LDB_ERR_INAPPROPRIATE_MATCHING; + } + + a = ldb_schema_attribute_by_name(ldb, tree->u.substring.attr); + if (!a) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + + if (tree->u.substring.chunks == NULL) { + *matched = false; + return LDB_SUCCESS; + } + + if (a->syntax->canonicalise_fn(ldb, ldb, &value, &val) != 0) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + + save_p = val.data; + cnk.data = NULL; + + if ( ! tree->u.substring.start_with_wildcard ) { + + chunk = tree->u.substring.chunks[c]; + if (a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto mismatch; + + /* This deals with wildcard prefix searches on binary attributes (eg objectGUID) */ + if (cnk.length > val.length) { + goto mismatch; + } + /* + * Empty strings are returned as length 0. Ensure + * we can cope with this. + */ + if (cnk.length == 0) { + goto mismatch; + } + + if (memcmp((char *)val.data, (char *)cnk.data, cnk.length) != 0) goto mismatch; + val.length -= cnk.length; + val.data += cnk.length; + c++; + talloc_free(cnk.data); + cnk.data = NULL; + } + + while (tree->u.substring.chunks[c]) { + uint8_t *p; + + chunk = tree->u.substring.chunks[c]; + if(a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto mismatch; + + /* + * Empty strings are returned as length 0. Ensure + * we can cope with this. + */ + if (cnk.length == 0) { + goto mismatch; + } + /* + * Values might be binary blobs. Don't use string + * search, but memory search instead. + */ + p = memmem((const void *)val.data,val.length, + (const void *)cnk.data, cnk.length); + if (p == NULL) goto mismatch; + + /* + * At this point we know cnk.length <= val.length as + * otherwise there could be no match + */ + + if ( (! tree->u.substring.chunks[c + 1]) && (! tree->u.substring.end_with_wildcard) ) { + uint8_t *g; + uint8_t *end = val.data + val.length; + do { /* greedy */ + + /* + * haystack is a valid pointer in val + * because the memmem() can only + * succeed if the needle (cnk.length) + * is <= haystacklen + * + * p will be a pointer at least + * cnk.length from the end of haystack + */ + uint8_t *haystack + = p + cnk.length; + size_t haystacklen + = end - (haystack); + + g = memmem(haystack, + haystacklen, + (const uint8_t *)cnk.data, + cnk.length); + if (g) { + p = g; + } + } while(g); + } + val.length = val.length - (p - (uint8_t *)(val.data)) - cnk.length; + val.data = (uint8_t *)(p + cnk.length); + c++; + talloc_free(cnk.data); + cnk.data = NULL; + } + + /* last chunk may not have reached end of string */ + if ( (! tree->u.substring.end_with_wildcard) && (val.length != 0) ) goto mismatch; + talloc_free(save_p); + *matched = true; + return LDB_SUCCESS; + +mismatch: + *matched = false; + talloc_free(save_p); + talloc_free(cnk.data); + return LDB_SUCCESS; +} + +/* + match a simple leaf node +*/ +static int ldb_match_substring(struct ldb_context *ldb, + const struct ldb_message *msg, + const struct ldb_parse_tree *tree, + enum ldb_scope scope, bool *matched) +{ + unsigned int i; + struct ldb_message_element *el; + + el = ldb_msg_find_element(msg, tree->u.substring.attr); + if (el == NULL) { + *matched = false; + return LDB_SUCCESS; + } + + for (i = 0; i < el->num_values; i++) { + int ret; + ret = ldb_wildcard_compare(ldb, tree, el->values[i], matched); + if (ret != LDB_SUCCESS) return ret; + if (*matched) return LDB_SUCCESS; + } + + *matched = false; + return LDB_SUCCESS; +} + + +/* + bitwise and/or comparator depending on oid +*/ +static int ldb_comparator_bitmask(const char *oid, const struct ldb_val *v1, const struct ldb_val *v2, + bool *matched) +{ + uint64_t i1, i2; + char ibuf[100]; + char *endptr = NULL; + + if (v1->length >= sizeof(ibuf)-1) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + memcpy(ibuf, (char *)v1->data, v1->length); + ibuf[v1->length] = 0; + i1 = strtoull(ibuf, &endptr, 0); + if (endptr != NULL) { + if (endptr == ibuf || *endptr != 0) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + } + + if (v2->length >= sizeof(ibuf)-1) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + endptr = NULL; + memcpy(ibuf, (char *)v2->data, v2->length); + ibuf[v2->length] = 0; + i2 = strtoull(ibuf, &endptr, 0); + if (endptr != NULL) { + if (endptr == ibuf || *endptr != 0) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + } + if (strcmp(LDB_OID_COMPARATOR_AND, oid) == 0) { + *matched = ((i1 & i2) == i2); + } else if (strcmp(LDB_OID_COMPARATOR_OR, oid) == 0) { + *matched = ((i1 & i2) != 0); + } else { + return LDB_ERR_INAPPROPRIATE_MATCHING; + } + return LDB_SUCCESS; +} + +static int ldb_match_bitmask(struct ldb_context *ldb, + const char *oid, + const struct ldb_message *msg, + const char *attribute_to_match, + const struct ldb_val *value_to_match, + bool *matched) +{ + unsigned int i; + struct ldb_message_element *el; + + /* find the message element */ + el = ldb_msg_find_element(msg, attribute_to_match); + if (el == NULL) { + *matched = false; + return LDB_SUCCESS; + } + + for (i=0;inum_values;i++) { + int ret; + struct ldb_val *v = &el->values[i]; + + ret = ldb_comparator_bitmask(oid, v, value_to_match, matched); + if (ret != LDB_SUCCESS) { + return ret; + } + if (*matched) { + return LDB_SUCCESS; + } + } + + *matched = false; + return LDB_SUCCESS; +} + +/* + always return false +*/ +static int ldb_comparator_false(struct ldb_context *ldb, + const char *oid, + const struct ldb_message *msg, + const char *attribute_to_match, + const struct ldb_val *value_to_match, + bool *matched) +{ + *matched = false; + return LDB_SUCCESS; +} + + +static const struct ldb_extended_match_rule *ldb_find_extended_match_rule(struct ldb_context *ldb, + const char *oid) +{ + struct ldb_extended_match_entry *extended_match_rule; + + for (extended_match_rule = ldb->extended_match_rules; + extended_match_rule; + extended_match_rule = extended_match_rule->next) { + if (strcmp(extended_match_rule->rule->oid, oid) == 0) { + return extended_match_rule->rule; + } + } + + return NULL; +} + + +/* + extended match, handles things like bitops +*/ +static int ldb_match_extended(struct ldb_context *ldb, + const struct ldb_message *msg, + const struct ldb_parse_tree *tree, + enum ldb_scope scope, bool *matched) +{ + const struct ldb_extended_match_rule *rule; + + if (tree->u.extended.dnAttributes) { + /* FIXME: We really need to find out what this ":dn" part in + * an extended match means and how to handle it. For now print + * only a warning to have s3 winbind and other tools working + * against us. - Matthias */ + ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb: dnAttributes extended match not supported yet"); + } + if (tree->u.extended.rule_id == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: no-rule extended matches not supported yet"); + return LDB_ERR_INAPPROPRIATE_MATCHING; + } + if (tree->u.extended.attr == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: no-attribute extended matches not supported yet"); + return LDB_ERR_INAPPROPRIATE_MATCHING; + } + + rule = ldb_find_extended_match_rule(ldb, tree->u.extended.rule_id); + if (rule == NULL) { + *matched = false; + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: unknown extended rule_id %s", + tree->u.extended.rule_id); + return LDB_SUCCESS; + } + + return rule->callback(ldb, rule->oid, msg, + tree->u.extended.attr, + &tree->u.extended.value, matched); +} + +/* + Check if a particular message will match the given filter + + set *matched to true if it matches, false otherwise + + returns LDB_SUCCESS or an error + + this is a recursive function, and does short-circuit evaluation + */ +int ldb_match_message(struct ldb_context *ldb, + const struct ldb_message *msg, + const struct ldb_parse_tree *tree, + enum ldb_scope scope, bool *matched) +{ + unsigned int i; + int ret; + + *matched = false; + + if (scope != LDB_SCOPE_BASE && ldb_dn_is_special(msg->dn)) { + /* don't match special records except on base searches */ + return LDB_SUCCESS; + } + + switch (tree->operation) { + case LDB_OP_AND: + for (i=0;iu.list.num_elements;i++) { + ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched); + if (ret != LDB_SUCCESS) return ret; + if (!*matched) return LDB_SUCCESS; + } + *matched = true; + return LDB_SUCCESS; + + case LDB_OP_OR: + for (i=0;iu.list.num_elements;i++) { + ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched); + if (ret != LDB_SUCCESS) return ret; + if (*matched) return LDB_SUCCESS; + } + *matched = false; + return LDB_SUCCESS; + + case LDB_OP_NOT: + ret = ldb_match_message(ldb, msg, tree->u.isnot.child, scope, matched); + if (ret != LDB_SUCCESS) return ret; + *matched = ! *matched; + return LDB_SUCCESS; + + case LDB_OP_EQUALITY: + return ldb_match_equality(ldb, msg, tree, scope, matched); + + case LDB_OP_SUBSTRING: + return ldb_match_substring(ldb, msg, tree, scope, matched); + + case LDB_OP_GREATER: + return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_GREATER, matched); + + case LDB_OP_LESS: + return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_LESS, matched); + + case LDB_OP_PRESENT: + return ldb_match_present(ldb, msg, tree, scope, matched); + + case LDB_OP_APPROX: + return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_APPROX, matched); + + case LDB_OP_EXTENDED: + return ldb_match_extended(ldb, msg, tree, scope, matched); + } + + return LDB_ERR_INAPPROPRIATE_MATCHING; +} + +/* + return 0 if the given parse tree matches the given message. Assumes + the message is in sorted order + + return 1 if it matches, and 0 if it doesn't match +*/ + +int ldb_match_msg(struct ldb_context *ldb, + const struct ldb_message *msg, + const struct ldb_parse_tree *tree, + struct ldb_dn *base, + enum ldb_scope scope) +{ + bool matched; + int ret; + + if ( ! ldb_match_scope(ldb, base, msg->dn, scope) ) { + return 0; + } + + ret = ldb_match_message(ldb, msg, tree, scope, &matched); + if (ret != LDB_SUCCESS) { + /* to match the old API, we need to consider this a + failure to match */ + return 0; + } + return matched?1:0; +} + +int ldb_match_msg_error(struct ldb_context *ldb, + const struct ldb_message *msg, + const struct ldb_parse_tree *tree, + struct ldb_dn *base, + enum ldb_scope scope, + bool *matched) +{ + if ( ! ldb_match_scope(ldb, base, msg->dn, scope) ) { + *matched = false; + return LDB_SUCCESS; + } + + return ldb_match_message(ldb, msg, tree, scope, matched); +} + +int ldb_match_msg_objectclass(const struct ldb_message *msg, + const char *objectclass) +{ + unsigned int i; + struct ldb_message_element *el = ldb_msg_find_element(msg, "objectClass"); + if (!el) { + return 0; + } + for (i=0; i < el->num_values; i++) { + if (ldb_attr_cmp((const char *)el->values[i].data, objectclass) == 0) { + return 1; + } + } + return 0; +} + +_PRIVATE_ int ldb_register_extended_match_rules(struct ldb_context *ldb) +{ + struct ldb_extended_match_rule *bitmask_and; + struct ldb_extended_match_rule *bitmask_or; + struct ldb_extended_match_rule *always_false; + int ret; + + /* Register bitmask-and match */ + bitmask_and = talloc_zero(ldb, struct ldb_extended_match_rule); + if (bitmask_and == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + bitmask_and->oid = LDB_OID_COMPARATOR_AND; + bitmask_and->callback = ldb_match_bitmask; + + ret = ldb_register_extended_match_rule(ldb, bitmask_and); + if (ret != LDB_SUCCESS) { + return ret; + } + + /* Register bitmask-or match */ + bitmask_or = talloc_zero(ldb, struct ldb_extended_match_rule); + if (bitmask_or == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + bitmask_or->oid = LDB_OID_COMPARATOR_OR; + bitmask_or->callback = ldb_match_bitmask; + + ret = ldb_register_extended_match_rule(ldb, bitmask_or); + if (ret != LDB_SUCCESS) { + return ret; + } + + /* Register always-false match */ + always_false = talloc_zero(ldb, struct ldb_extended_match_rule); + if (always_false == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + always_false->oid = SAMBA_LDAP_MATCH_ALWAYS_FALSE; + always_false->callback = ldb_comparator_false; + + ret = ldb_register_extended_match_rule(ldb, always_false); + if (ret != LDB_SUCCESS) { + return ret; + } + + return LDB_SUCCESS; +} + +/* + register a new ldb extended matching rule +*/ +int ldb_register_extended_match_rule(struct ldb_context *ldb, + const struct ldb_extended_match_rule *rule) +{ + const struct ldb_extended_match_rule *lookup_rule; + struct ldb_extended_match_entry *entry; + + lookup_rule = ldb_find_extended_match_rule(ldb, rule->oid); + if (lookup_rule) { + return LDB_ERR_ENTRY_ALREADY_EXISTS; + } + + entry = talloc_zero(ldb, struct ldb_extended_match_entry); + if (!entry) { + return LDB_ERR_OPERATIONS_ERROR; + } + entry->rule = rule; + DLIST_ADD_END(ldb->extended_match_rules, entry); + + return LDB_SUCCESS; +} + diff --git a/ldb-2.0.8/common/ldb_modules.c b/ldb-2.0.8/common/ldb_modules.c new file mode 100644 index 0000000..cc067ab --- /dev/null +++ b/ldb-2.0.8/common/ldb_modules.c @@ -0,0 +1,1236 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2004-2008 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb modules core + * + * Description: core modules routines + * + * Author: Simo Sorce + */ + +#include "ldb_private.h" +#include "dlinklist.h" +#include "system/dir.h" + +static char *ldb_modules_strdup_no_spaces(TALLOC_CTX *mem_ctx, const char *string) +{ + size_t i, len; + char *trimmed; + + trimmed = talloc_strdup(mem_ctx, string); + if (!trimmed) { + return NULL; + } + + len = strlen(trimmed); + for (i = 0; trimmed[i] != '\0'; i++) { + switch (trimmed[i]) { + case ' ': + case '\t': + case '\n': + memmove(&trimmed[i], &trimmed[i + 1], len -i -1); + break; + } + } + + return trimmed; +} + + +/* modules are called in inverse order on the stack. + Lets place them as an admin would think the right order is. + Modules order is important */ +const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string) +{ + char **modules = NULL; + const char **m; + char *modstr, *p; + unsigned int i; + + /* spaces not admitted */ + modstr = ldb_modules_strdup_no_spaces(mem_ctx, string); + if ( ! modstr) { + ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_strdup_no_spaces()"); + return NULL; + } + + modules = talloc_realloc(mem_ctx, modules, char *, 2); + if ( ! modules ) { + ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()"); + talloc_free(modstr); + return NULL; + } + talloc_steal(modules, modstr); + + if (modstr[0] == '\0') { + modules[0] = NULL; + m = discard_const_p(const char *, modules); + return m; + } + + i = 0; + /* The str*r*chr walks backwards: This is how we get the inverse order mentioned above */ + while ((p = strrchr(modstr, ',')) != NULL) { + *p = '\0'; + p++; + modules[i] = p; + + i++; + modules = talloc_realloc(mem_ctx, modules, char *, i + 2); + if ( ! modules ) { + ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()"); + return NULL; + } + + } + modules[i] = modstr; + + modules[i + 1] = NULL; + + m = discard_const_p(const char *, modules); + + return m; +} + +static struct backends_list_entry { + struct ldb_backend_ops *ops; + struct backends_list_entry *prev, *next; +} *ldb_backends = NULL; + +static struct ops_list_entry { + const struct ldb_module_ops *ops; + struct ops_list_entry *next; +} *registered_modules = NULL; + +static struct backends_list_entry *ldb_find_backend(const char *url_prefix) +{ + struct backends_list_entry *backend; + + for (backend = ldb_backends; backend; backend = backend->next) { + if (strcmp(backend->ops->name, url_prefix) == 0) { + return backend; + } + } + + return NULL; +} + +/* + register a new ldb backend + + if override is true, then override any existing backend for this prefix +*/ +int ldb_register_backend(const char *url_prefix, ldb_connect_fn connectfn, bool override) +{ + struct backends_list_entry *be; + + be = ldb_find_backend(url_prefix); + if (be) { + if (!override) { + return LDB_SUCCESS; + } + } else { + be = talloc_zero(ldb_backends, struct backends_list_entry); + if (!be) { + return LDB_ERR_OPERATIONS_ERROR; + } + be->ops = talloc_zero(be, struct ldb_backend_ops); + if (!be->ops) { + talloc_free(be); + return LDB_ERR_OPERATIONS_ERROR; + } + DLIST_ADD_END(ldb_backends, be); + } + + be->ops->name = url_prefix; + be->ops->connect_fn = connectfn; + + return LDB_SUCCESS; +} + +/* + Return the ldb module form of a database. + The URL can either be one of the following forms + ldb://path + ldapi://path + + flags is made up of LDB_FLG_* + + the options are passed uninterpreted to the backend, and are + backend specific. + + This allows modules to get at only the backend module, for example where a + module may wish to direct certain requests at a particular backend. +*/ +int ldb_module_connect_backend(struct ldb_context *ldb, + const char *url, + const char *options[], + struct ldb_module **backend_module) +{ + int ret; + char *backend; + struct backends_list_entry *be; + + if (strchr(url, ':') != NULL) { + backend = talloc_strndup(ldb, url, strchr(url, ':')-url); + } else { + /* Default to tdb */ + backend = talloc_strdup(ldb, "tdb"); + } + if (backend == NULL) { + return ldb_oom(ldb); + } + + be = ldb_find_backend(backend); + + talloc_free(backend); + + if (be == NULL) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "Unable to find backend for '%s' - do you need to set LDB_MODULES_PATH?", url); + return LDB_ERR_OTHER; + } + + ret = be->ops->connect_fn(ldb, url, ldb->flags, options, backend_module); + + if (ret != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Failed to connect to '%s' with backend '%s': %s", url, be->ops->name, ldb_errstring(ldb)); + return ret; + } + return ret; +} + +static struct ldb_hooks { + struct ldb_hooks *next, *prev; + ldb_hook_fn hook_fn; +} *ldb_hooks; + +/* + register a ldb hook function + */ +int ldb_register_hook(ldb_hook_fn hook_fn) +{ + struct ldb_hooks *lc; + lc = talloc_zero(ldb_hooks, struct ldb_hooks); + if (lc == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + lc->hook_fn = hook_fn; + DLIST_ADD_END(ldb_hooks, lc); + return LDB_SUCCESS; +} + +/* + call ldb hooks of a given type + */ +int ldb_modules_hook(struct ldb_context *ldb, enum ldb_module_hook_type t) +{ + struct ldb_hooks *lc; + for (lc = ldb_hooks; lc; lc=lc->next) { + int ret = lc->hook_fn(ldb, t); + if (ret != LDB_SUCCESS) { + return ret; + } + } + return LDB_SUCCESS; +} + + +static const struct ldb_module_ops *ldb_find_module_ops(const char *name) +{ + struct ops_list_entry *e; + + for (e = registered_modules; e; e = e->next) { + if (strcmp(e->ops->name, name) == 0) + return e->ops; + } + + return NULL; +} + + +int ldb_register_module(const struct ldb_module_ops *ops) +{ + struct ops_list_entry *entry; + + if (ldb_find_module_ops(ops->name) != NULL) + return LDB_ERR_ENTRY_ALREADY_EXISTS; + + /* + * ldb modules are not (yet) unloaded and + * are only loaded once (the above check + * makes sure of this). Allocate off the NULL + * context. We never want this to be freed + * until process shutdown. If eventually we + * want to unload ldb modules we can add a + * deregister function that walks and + * frees the list. + */ + entry = talloc(NULL, struct ops_list_entry); + if (entry == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + entry->ops = ops; + entry->next = registered_modules; + registered_modules = entry; + + return LDB_SUCCESS; +} + +/* + load a list of modules + */ +int ldb_module_load_list(struct ldb_context *ldb, const char **module_list, + struct ldb_module *backend, struct ldb_module **out) +{ + struct ldb_module *module; + unsigned int i; + + module = backend; + + for (i = 0; module_list && module_list[i] != NULL; i++) { + struct ldb_module *current; + const struct ldb_module_ops *ops; + + if (strcmp(module_list[i], "") == 0) { + continue; + } + + ops = ldb_find_module_ops(module_list[i]); + + if (ops == NULL) { + ldb_debug(ldb, LDB_DEBUG_FATAL, "WARNING: Module [%s] not found - do you need to set LDB_MODULES_PATH?", + module_list[i]); + return LDB_ERR_OPERATIONS_ERROR; + } + + current = talloc_zero(ldb, struct ldb_module); + if (current == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + talloc_set_name(current, "ldb_module: %s", module_list[i]); + + current->ldb = ldb; + current->ops = ops; + + DLIST_ADD(module, current); + } + *out = module; + return LDB_SUCCESS; +} + +/* + initialise a chain of modules + */ +int ldb_module_init_chain(struct ldb_context *ldb, struct ldb_module *module) +{ + while (module && module->ops->init_context == NULL) + module = module->next; + + /* init is different in that it is not an error if modules + * do not require initialization */ + + if (module) { + int ret = module->ops->init_context(module); + if (ret != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_FATAL, "module %s initialization failed : %s", + module->ops->name, ldb_strerror(ret)); + return ret; + } + } + + return LDB_SUCCESS; +} + +int ldb_load_modules(struct ldb_context *ldb, const char *options[]) +{ + const char *modules_string; + const char **modules = NULL; + int ret; + TALLOC_CTX *mem_ctx = talloc_new(ldb); + if (!mem_ctx) { + return ldb_oom(ldb); + } + + /* find out which modules we are requested to activate */ + + /* check if we have a custom module list passd as ldb option */ + if (options) { + modules_string = ldb_options_find(ldb, options, "modules"); + if (modules_string) { + modules = ldb_modules_list_from_string(ldb, mem_ctx, modules_string); + } + } + + /* if not overloaded by options and the backend is not ldap try to load the modules list from ldb */ + if ((modules == NULL) && (strcmp("ldap", ldb->modules->ops->name) != 0)) { + const char * const attrs[] = { "@LIST" , NULL}; + struct ldb_result *res = NULL; + struct ldb_dn *mods_dn; + + mods_dn = ldb_dn_new(mem_ctx, ldb, "@MODULES"); + if (mods_dn == NULL) { + talloc_free(mem_ctx); + return ldb_oom(ldb); + } + + ret = ldb_search(ldb, mods_dn, &res, mods_dn, LDB_SCOPE_BASE, attrs, "@LIST=*"); + + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db"); + } else if (ret != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for modules, bailing out", ldb_errstring(ldb)); + talloc_free(mem_ctx); + return ret; + } else { + const char *module_list; + if (res->count == 0) { + ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db"); + } else if (res->count > 1) { + ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%u), bailing out", res->count); + talloc_free(mem_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } else { + module_list = ldb_msg_find_attr_as_string(res->msgs[0], "@LIST", NULL); + if (!module_list) { + ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db"); + } + modules = ldb_modules_list_from_string(ldb, mem_ctx, + module_list); + } + } + + talloc_free(mods_dn); + } + + if (modules != NULL) { + ret = ldb_module_load_list(ldb, modules, ldb->modules, &ldb->modules); + if (ret != LDB_SUCCESS) { + talloc_free(mem_ctx); + return ret; + } + } else { + ldb_debug(ldb, LDB_DEBUG_TRACE, "No modules specified for this database"); + } + + ret = ldb_module_init_chain(ldb, ldb->modules); + talloc_free(mem_ctx); + return ret; +} + +/* + by using this we allow ldb modules to only implement the functions they care about, + which makes writing a module simpler, and makes it more likely to keep working + when ldb is extended +*/ +#define FIND_OP_NOERR(module, op) do { \ + module = module->next; \ + while (module && module->ops->op == NULL) module = module->next; \ + if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { \ + ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_trace_next_request: (%s)->" #op, \ + module->ops->name); \ + } \ +} while (0) + +#define FIND_OP(module, op) do { \ + struct ldb_context *ldb = module->ldb; \ + FIND_OP_NOERR(module, op); \ + if (module == NULL) { \ + ldb_asprintf_errstring(ldb, "Unable to find backend operation for " #op ); \ + return LDB_ERR_OPERATIONS_ERROR; \ + } \ +} while (0) + + +struct ldb_module *ldb_module_new(TALLOC_CTX *memctx, + struct ldb_context *ldb, + const char *module_name, + const struct ldb_module_ops *ops) +{ + struct ldb_module *module; + + module = talloc(memctx, struct ldb_module); + if (!module) { + ldb_oom(ldb); + return NULL; + } + talloc_set_name_const(module, module_name); + module->ldb = ldb; + module->prev = module->next = NULL; + module->ops = ops; + + return module; +} + +const char * ldb_module_get_name(struct ldb_module *module) +{ + return module->ops->name; +} + +struct ldb_context *ldb_module_get_ctx(struct ldb_module *module) +{ + return module->ldb; +} + +const struct ldb_module_ops *ldb_module_get_ops(struct ldb_module *module) +{ + return module->ops; +} + +void *ldb_module_get_private(struct ldb_module *module) +{ + return module->private_data; +} + +void ldb_module_set_private(struct ldb_module *module, void *private_data) +{ + module->private_data = private_data; +} + +/* + helper functions to call the next module in chain +*/ + +int ldb_next_request(struct ldb_module *module, struct ldb_request *request) +{ + int ret; + + if (request->callback == NULL) { + ldb_set_errstring(module->ldb, "Requests MUST define callbacks"); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + request->handle->nesting++; + + switch (request->operation) { + case LDB_SEARCH: + FIND_OP(module, search); + ret = module->ops->search(module, request); + break; + case LDB_ADD: + FIND_OP(module, add); + ret = module->ops->add(module, request); + break; + case LDB_MODIFY: + FIND_OP(module, modify); + ret = module->ops->modify(module, request); + break; + case LDB_DELETE: + FIND_OP(module, del); + ret = module->ops->del(module, request); + break; + case LDB_RENAME: + FIND_OP(module, rename); + ret = module->ops->rename(module, request); + break; + case LDB_EXTENDED: + FIND_OP(module, extended); + ret = module->ops->extended(module, request); + break; + default: + FIND_OP(module, request); + ret = module->ops->request(module, request); + break; + } + + request->handle->nesting--; + + if (ret == LDB_SUCCESS) { + return ret; + } + if (!ldb_errstring(module->ldb)) { + const char *op; + switch (request->operation) { + case LDB_SEARCH: + op = "LDB_SEARCH"; + break; + case LDB_ADD: + op = "LDB_ADD"; + break; + case LDB_MODIFY: + op = "LDB_MODIFY"; + break; + case LDB_DELETE: + op = "LDB_DELETE"; + break; + case LDB_RENAME: + op = "LDB_RENAME"; + break; + case LDB_EXTENDED: + op = "LDB_EXTENDED"; + break; + default: + op = "request"; + break; + } + + /* Set a default error string, to place the blame somewhere */ + ldb_asprintf_errstring(module->ldb, "error in module %s: %s during %s (%d)", module->ops->name, ldb_strerror(ret), op, ret); + } + + if (!(request->handle->flags & LDB_HANDLE_FLAG_DONE_CALLED)) { + /* It is _extremely_ common that a module returns a + * failure without calling ldb_module_done(), but that + * guarantees we will end up hanging in + * ldb_wait(). This fixes it without having to rewrite + * all our modules, and leaves us one less sharp + * corner for module developers to cut themselves on + */ + ret = ldb_module_done(request, NULL, NULL, ret); + } + return ret; +} + +int ldb_next_init(struct ldb_module *module) +{ + module = module->next; + + return ldb_module_init_chain(module->ldb, module); +} + +int ldb_next_start_trans(struct ldb_module *module) +{ + int ret; + FIND_OP(module, start_transaction); + ret = module->ops->start_transaction(module); + if (ret == LDB_SUCCESS) { + return ret; + } + if (!ldb_errstring(module->ldb)) { + /* Set a default error string, to place the blame somewhere */ + ldb_asprintf_errstring(module->ldb, "start_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); + } + if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { + ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_start_trans error: %s", + ldb_errstring(module->ldb)); + } + return ret; +} + +int ldb_next_end_trans(struct ldb_module *module) +{ + int ret; + FIND_OP(module, end_transaction); + ret = module->ops->end_transaction(module); + if (ret == LDB_SUCCESS) { + return ret; + } + if (!ldb_errstring(module->ldb)) { + /* Set a default error string, to place the blame somewhere */ + ldb_asprintf_errstring(module->ldb, "end_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); + } + if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { + ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_end_trans error: %s", + ldb_errstring(module->ldb)); + } + return ret; +} + +int ldb_next_read_lock(struct ldb_module *module) +{ + int ret; + FIND_OP(module, read_lock); + ret = module->ops->read_lock(module); + if (ret == LDB_SUCCESS) { + return ret; + } + if (!ldb_errstring(module->ldb)) { + /* Set a default error string, to place the blame somewhere */ + ldb_asprintf_errstring(module->ldb, + "read_lock error in module %s: %s (%d)", + module->ops->name, ldb_strerror(ret), + ret); + } + if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { + ldb_debug(module->ldb, LDB_DEBUG_TRACE, + "ldb_next_read_lock error: %s", + ldb_errstring(module->ldb)); + } + return ret; +} + +int ldb_next_read_unlock(struct ldb_module *module) +{ + int ret; + FIND_OP(module, read_unlock); + ret = module->ops->read_unlock(module); + if (ret == LDB_SUCCESS) { + return ret; + } + if (!ldb_errstring(module->ldb)) { + /* Set a default error string, to place the blame somewhere */ + ldb_asprintf_errstring(module->ldb, + "read_unlock error in module %s: %s (%d)", + module->ops->name, ldb_strerror(ret), + ret); + } + if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { + ldb_debug(module->ldb, LDB_DEBUG_TRACE, + "ldb_next_read_unlock error: %s", + ldb_errstring(module->ldb)); + } + return ret; +} + +int ldb_next_prepare_commit(struct ldb_module *module) +{ + int ret; + FIND_OP_NOERR(module, prepare_commit); + if (module == NULL) { + /* we are allowed to have no prepare commit in + backends */ + return LDB_SUCCESS; + } + ret = module->ops->prepare_commit(module); + if (ret == LDB_SUCCESS) { + return ret; + } + if (!ldb_errstring(module->ldb)) { + /* Set a default error string, to place the blame somewhere */ + ldb_asprintf_errstring(module->ldb, "prepare_commit error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); + } + if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { + ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_prepare_commit error: %s", + ldb_errstring(module->ldb)); + } + return ret; +} + +int ldb_next_del_trans(struct ldb_module *module) +{ + int ret; + FIND_OP(module, del_transaction); + ret = module->ops->del_transaction(module); + if (ret == LDB_SUCCESS) { + return ret; + } + if (!ldb_errstring(module->ldb)) { + /* Set a default error string, to place the blame somewhere */ + ldb_asprintf_errstring(module->ldb, "del_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); + } + if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { + ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_del_trans error: %s", + ldb_errstring(module->ldb)); + } + return ret; +} + +/* calls the request callback to send an entry + * + * params: + * req: the original request passed to your module + * msg: reply message (must be a talloc pointer, and it will be stolen + * on the ldb_reply that is sent to the callback) + * ctrls: controls to send in the reply (must be a talloc pointer, and it will be stolen + * on the ldb_reply that is sent to the callback) + */ + +int ldb_module_send_entry(struct ldb_request *req, + struct ldb_message *msg, + struct ldb_control **ctrls) +{ + struct ldb_reply *ares; + + ares = talloc_zero(req, struct ldb_reply); + if (!ares) { + ldb_oom(req->handle->ldb); + req->callback(req, NULL); + return LDB_ERR_OPERATIONS_ERROR; + } + ares->type = LDB_REPLY_ENTRY; + ares->message = talloc_steal(ares, msg); + ares->controls = talloc_steal(ares, ctrls); + ares->error = LDB_SUCCESS; + + if ((req->handle->ldb->flags & LDB_FLG_ENABLE_TRACING) && + req->handle->nesting == 0) { + char *s; + struct ldb_ldif ldif; + + ldif.changetype = LDB_CHANGETYPE_NONE; + ldif.msg = discard_const_p(struct ldb_message, msg); + + ldb_debug_add(req->handle->ldb, "ldb_trace_response: ENTRY\n"); + + /* + * The choice to call + * ldb_ldif_write_redacted_trace_string() is CRITICAL + * for security. It ensures that we do not output + * passwords into debug logs + */ + + s = ldb_ldif_write_redacted_trace_string(req->handle->ldb, msg, &ldif); + ldb_debug_add(req->handle->ldb, "%s\n", s); + talloc_free(s); + ldb_debug_end(req->handle->ldb, LDB_DEBUG_TRACE); + } + + return req->callback(req, ares); +} + +/* calls the request callback to send an referrals + * + * params: + * req: the original request passed to your module + * ref: referral string (must be a talloc pointer, steal) + */ + +int ldb_module_send_referral(struct ldb_request *req, + char *ref) +{ + struct ldb_reply *ares; + + ares = talloc_zero(req, struct ldb_reply); + if (!ares) { + ldb_oom(req->handle->ldb); + req->callback(req, NULL); + return LDB_ERR_OPERATIONS_ERROR; + } + ares->type = LDB_REPLY_REFERRAL; + ares->referral = talloc_steal(ares, ref); + ares->error = LDB_SUCCESS; + + if ((req->handle->ldb->flags & LDB_FLG_ENABLE_TRACING) && + req->handle->nesting == 0) { + ldb_debug_add(req->handle->ldb, "ldb_trace_response: REFERRAL\n"); + ldb_debug_add(req->handle->ldb, "ref: %s\n", ref); + ldb_debug_end(req->handle->ldb, LDB_DEBUG_TRACE); + } + + return req->callback(req, ares); +} + +/* calls the original request callback + * + * params: + * req: the original request passed to your module + * ctrls: controls to send in the reply (must be a talloc pointer, steal) + * response: results for extended request (steal) + * error: LDB_SUCCESS for a successful return + * any other ldb error otherwise + */ +int ldb_module_done(struct ldb_request *req, + struct ldb_control **ctrls, + struct ldb_extended *response, + int error) +{ + struct ldb_reply *ares; + + ares = talloc_zero(req, struct ldb_reply); + if (!ares) { + ldb_oom(req->handle->ldb); + req->callback(req, NULL); + return LDB_ERR_OPERATIONS_ERROR; + } + ares->type = LDB_REPLY_DONE; + ares->controls = talloc_steal(ares, ctrls); + ares->response = talloc_steal(ares, response); + ares->error = error; + + req->handle->flags |= LDB_HANDLE_FLAG_DONE_CALLED; + + if ((req->handle->ldb->flags & LDB_FLG_ENABLE_TRACING) && + req->handle->nesting == 0) { + ldb_debug_add(req->handle->ldb, "ldb_trace_response: DONE\n"); + ldb_debug_add(req->handle->ldb, "error: %d\n", error); + if (ldb_errstring(req->handle->ldb)) { + ldb_debug_add(req->handle->ldb, "msg: %s\n", + ldb_errstring(req->handle->ldb)); + } + ldb_debug_end(req->handle->ldb, LDB_DEBUG_TRACE); + } + + return req->callback(req, ares); +} + +/* to be used *only* in modules init functions. + * this function is synchronous and will register + * the requested OID in the rootdse module if present + * otherwise it will return an error */ +int ldb_mod_register_control(struct ldb_module *module, const char *oid) +{ + struct ldb_request *req; + int ret; + + req = talloc_zero(module, struct ldb_request); + if (req == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + req->operation = LDB_REQ_REGISTER_CONTROL; + req->op.reg_control.oid = oid; + req->callback = ldb_op_default_callback; + + ldb_set_timeout(module->ldb, req, 0); + + req->handle = ldb_handle_new(req, module->ldb); + if (req->handle == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_request(module->ldb, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + talloc_free(req); + + return ret; +} + +static int ldb_modules_load_dir(const char *modules_dir, const char *version); + + +/* + load one module. A static list of loaded module inode numbers is + used to prevent a module being loaded twice + + dlopen() is used on the module, and dlsym() is then used to look for + a ldb_init_module() function. If present, that function is called + with the ldb version number as an argument. + + The ldb_init_module() function will typically call + ldb_register_module() and ldb_register_backend() to register a + module or backend, but it may also be used to register command line + handling functions, ldif handlers or any other local + modififications. + + The ldb_init_module() function does not get a ldb_context passed in, + as modules will be used for multiple ldb context handles. The call + from the first ldb_init() is just a convenient way to ensure it is + called early enough. + */ +static int ldb_modules_load_path(const char *path, const char *version) +{ + void *handle; + int (*init_fn)(const char *); + int ret; + struct stat st; + static struct loaded { + struct loaded *next, *prev; + ino_t st_ino; + dev_t st_dev; + } *loaded; + struct loaded *le; + int dlopen_flags; + +#ifdef RTLD_DEEPBIND + bool deepbind_enabled = (getenv("LDB_MODULES_DISABLE_DEEPBIND") == NULL); +#endif + + ret = stat(path, &st); + if (ret != 0) { + fprintf(stderr, "ldb: unable to stat module %s : %s\n", path, strerror(errno)); + return LDB_ERR_UNAVAILABLE; + } + + for (le=loaded; le; le=le->next) { + if (le->st_ino == st.st_ino && + le->st_dev == st.st_dev) { + /* its already loaded */ + return LDB_SUCCESS; + } + } + + le = talloc(loaded, struct loaded); + if (le == NULL) { + fprintf(stderr, "ldb: unable to allocated loaded entry\n"); + return LDB_ERR_UNAVAILABLE; + } + + le->st_ino = st.st_ino; + le->st_dev = st.st_dev; + + DLIST_ADD_END(loaded, le); + + /* if it is a directory, recurse */ + if (S_ISDIR(st.st_mode)) { + return ldb_modules_load_dir(path, version); + } + + dlopen_flags = RTLD_NOW; +#ifdef RTLD_DEEPBIND + /* + * use deepbind if possible, to avoid issues with different + * system library variants, for example ldb modules may be linked + * against Heimdal while the application may use MIT kerberos. + * + * See the dlopen manpage for details. + * + * One typical user is the bind_dlz module of Samba, + * but symbol versioning might be enough... + * + * We need a way to disable this in order to allow the + * ldb_*ldap modules to work with a preloaded socket wrapper. + * + * So in future we may remove this completely + * or at least invert the default behavior. + */ + if (deepbind_enabled) { + dlopen_flags |= RTLD_DEEPBIND; + } +#endif + + handle = dlopen(path, dlopen_flags); + if (handle == NULL) { + fprintf(stderr, "ldb: unable to dlopen %s : %s\n", path, dlerror()); + return LDB_SUCCESS; + } + + init_fn = dlsym(handle, "ldb_init_module"); + if (init_fn == NULL) { + /* ignore it, it could be an old-style + * module. Once we've converted all modules we + * could consider this an error */ + dlclose(handle); + return LDB_SUCCESS; + } + + ret = init_fn(version); + if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { + /* the module is already registered - ignore this, as + * it can happen if LDB_MODULES_PATH points at both + * the build and install directory + */ + ret = LDB_SUCCESS; + } + return ret; +} + +static int qsort_string(const char **s1, const char **s2) +{ + return strcmp(*s1, *s2); +} + + +/* + load all modules from the given ldb modules directory. This is run once + during the first ldb_init() call. + + Modules are loaded in alphabetical order to ensure that any module + load ordering dependencies are reproducible. Modules should avoid + relying on load order + */ +static int ldb_modules_load_dir(const char *modules_dir, const char *version) +{ + DIR *dir; + struct dirent *de; + const char **modlist = NULL; + TALLOC_CTX *tmp_ctx = talloc_new(NULL); + unsigned i, num_modules = 0; + + dir = opendir(modules_dir); + if (dir == NULL) { + if (errno == ENOENT) { + talloc_free(tmp_ctx); + /* we don't have any modules */ + return LDB_SUCCESS; + } + talloc_free(tmp_ctx); + fprintf(stderr, "ldb: unable to open modules directory '%s' - %s\n", + modules_dir, strerror(errno)); + return LDB_ERR_UNAVAILABLE; + } + + + while ((de = readdir(dir))) { + if (ISDOT(de->d_name) || ISDOTDOT(de->d_name)) + continue; + + modlist = talloc_realloc(tmp_ctx, modlist, const char *, num_modules+1); + if (modlist == NULL) { + talloc_free(tmp_ctx); + closedir(dir); + fprintf(stderr, "ldb: unable to allocate modules list\n"); + return LDB_ERR_UNAVAILABLE; + } + modlist[num_modules] = talloc_asprintf(modlist, "%s/%s", modules_dir, de->d_name); + if (modlist[num_modules] == NULL) { + talloc_free(tmp_ctx); + closedir(dir); + fprintf(stderr, "ldb: unable to allocate module list entry\n"); + return LDB_ERR_UNAVAILABLE; + } + num_modules++; + } + + closedir(dir); + + /* sort the directory, so we get consistent load ordering */ + TYPESAFE_QSORT(modlist, num_modules, qsort_string); + + for (i=0; ihandle) { + char *s = talloc_asprintf_append_buffer(ret, "req[%u] %p : %s\n", + i++, req, ldb_req_location(req)); + if (s == NULL) { + talloc_free(ret); + return NULL; + } + ret = s; + req = req->handle->parent; + } + return ret; +} + + +/* + return the next module in the chain + */ +struct ldb_module *ldb_module_next(struct ldb_module *module) +{ + return module->next; +} + +/* + set the next module in the module chain + */ +void ldb_module_set_next(struct ldb_module *module, struct ldb_module *next) +{ + module->next = next; +} + + +/* + get the popt_options pointer in the ldb structure. This allows a ldb + module to change the command line parsing + */ +struct poptOption **ldb_module_popt_options(struct ldb_context *ldb) +{ + return &ldb->popt_options; +} + + +/* + return the current ldb flags LDB_FLG_* + */ +uint32_t ldb_module_flags(struct ldb_context *ldb) +{ + return ldb->flags; +} diff --git a/ldb-2.0.8/common/ldb_msg.c b/ldb-2.0.8/common/ldb_msg.c new file mode 100644 index 0000000..2346e66 --- /dev/null +++ b/ldb-2.0.8/common/ldb_msg.c @@ -0,0 +1,1469 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb message component utility functions + * + * Description: functions for manipulating ldb_message structures + * + * Author: Andrew Tridgell + */ + +#include "ldb_private.h" + +/* + create a new ldb_message in a given memory context (NULL for top level) +*/ +struct ldb_message *ldb_msg_new(TALLOC_CTX *mem_ctx) +{ + return talloc_zero(mem_ctx, struct ldb_message); +} + +/* + find an element in a message by attribute name +*/ +struct ldb_message_element *ldb_msg_find_element(const struct ldb_message *msg, + const char *attr_name) +{ + unsigned int i; + for (i=0;inum_elements;i++) { + if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) { + return &msg->elements[i]; + } + } + return NULL; +} + +/* + see if two ldb_val structures contain exactly the same data + return 1 for a match, 0 for a mis-match +*/ +int ldb_val_equal_exact(const struct ldb_val *v1, const struct ldb_val *v2) +{ + if (v1->length != v2->length) return 0; + if (v1->data == v2->data) return 1; + if (v1->length == 0) return 1; + + if (memcmp(v1->data, v2->data, v1->length) == 0) { + return 1; + } + + return 0; +} + +/* + find a value in an element + assumes case sensitive comparison +*/ +struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el, + struct ldb_val *val) +{ + unsigned int i; + for (i=0;inum_values;i++) { + if (ldb_val_equal_exact(val, &el->values[i])) { + return &el->values[i]; + } + } + return NULL; +} + + +static int ldb_val_cmp(const struct ldb_val *v1, const struct ldb_val *v2) +{ + if (v1->length != v2->length) { + return v1->length - v2->length; + } + return memcmp(v1->data, v2->data, v1->length); +} + + +/* + ldb_msg_find_duplicate_val() will set the **duplicate pointer to the first + duplicate value it finds. It does a case sensitive comparison (memcmp). + + LDB_ERR_OPERATIONS_ERROR indicates an allocation failure or an unknown + options flag, otherwise LDB_SUCCESS. +*/ +#define LDB_DUP_QUADRATIC_THRESHOLD 10 + +int ldb_msg_find_duplicate_val(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const struct ldb_message_element *el, + struct ldb_val **duplicate, + uint32_t options) +{ + unsigned int i, j; + struct ldb_val *val; + + if (options != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + *duplicate = NULL; + + /* + If there are not many values, it is best to avoid the talloc + overhead and just do a brute force search. + */ + if (el->num_values < LDB_DUP_QUADRATIC_THRESHOLD) { + for (j = 0; j < el->num_values; j++) { + val = &el->values[j]; + for ( i = j + 1; i < el->num_values; i++) { + if (ldb_val_equal_exact(val, &el->values[i])) { + *duplicate = val; + return LDB_SUCCESS; + } + } + } + } else { + struct ldb_val *values; + values = talloc_array(mem_ctx, struct ldb_val, el->num_values); + if (values == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + memcpy(values, el->values, + el->num_values * sizeof(struct ldb_val)); + TYPESAFE_QSORT(values, el->num_values, ldb_val_cmp); + for (i = 1; i < el->num_values; i++) { + if (ldb_val_equal_exact(&values[i], + &values[i - 1])) { + /* find the original location */ + for (j = 0; j < el->num_values; j++) { + if (ldb_val_equal_exact(&values[i], + &el->values[j]) + ) { + *duplicate = &el->values[j]; + break; + } + } + talloc_free(values); + if (*duplicate == NULL) { + /* how we got here, I don't know */ + return LDB_ERR_OPERATIONS_ERROR; + } + return LDB_SUCCESS; + } + } + talloc_free(values); + } + return LDB_SUCCESS; +} + + +/* + Determine whether the values in an element are also in another element. + + Without any flags, return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS if the elements + share values, or LDB_SUCCESS if they don't. In this case, the function + simply determines the set intersection and it doesn't matter in which order + the elements are provided. + + With the LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES flag, any values in common are + removed from the first element and LDB_SUCCESS is returned. + + LDB_ERR_OPERATIONS_ERROR indicates an allocation failure or an unknown option. + LDB_ERR_INAPPROPRIATE_MATCHING is returned if the elements differ in name. +*/ + +int ldb_msg_find_common_values(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_message_element *el, + struct ldb_message_element *el2, + uint32_t options) +{ + struct ldb_val *values; + struct ldb_val *values2; + unsigned int i, j, k, n_values; + + bool remove_duplicates = options & LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES; + + if ((options & ~LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (strcmp(el->name, el2->name) != 0) { + return LDB_ERR_INAPPROPRIATE_MATCHING; + } + if (el->num_values == 0 || el2->num_values == 0) { + return LDB_SUCCESS; + } + /* + With few values, it is better to do the brute-force search than the + clever search involving tallocs, memcpys, sorts, etc. + */ + if (MIN(el->num_values, el2->num_values) == 1 || + MAX(el->num_values, el2->num_values) < LDB_DUP_QUADRATIC_THRESHOLD) { + for (i = 0; i < el2->num_values; i++) { + for (j = 0; j < el->num_values; j++) { + if (ldb_val_equal_exact(&el->values[j], + &el2->values[i])) { + if (! remove_duplicates) { + return \ + LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + } + /* + With the remove_duplicates flag, we + resolve the intersection by removing + the offending one from el. + */ + el->num_values--; + for (k = j; k < el->num_values; k++) { + el->values[k] = \ + el->values[k + 1]; + } + j--; /* rewind */ + } + } + } + return LDB_SUCCESS; + } + + values = talloc_array(mem_ctx, struct ldb_val, el->num_values); + if (values == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + values2 = talloc_array(mem_ctx, struct ldb_val, + el2->num_values); + if (values2 == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + memcpy(values, el->values, + el->num_values * sizeof(struct ldb_val)); + memcpy(values2, el2->values, + el2->num_values * sizeof(struct ldb_val)); + TYPESAFE_QSORT(values, el->num_values, ldb_val_cmp); + TYPESAFE_QSORT(values2, el2->num_values, ldb_val_cmp); + + /* + el->n_values may diverge from the number of values in the sorted + list when the remove_duplicates flag is used. + */ + n_values = el->num_values; + i = 0; + j = 0; + while (i != n_values && j < el2->num_values) { + int ret = ldb_val_cmp(&values[i], &values2[j]); + if (ret < 0) { + i++; + } else if (ret > 0) { + j++; + } else { + /* we have a collision */ + if (! remove_duplicates) { + TALLOC_FREE(values); + TALLOC_FREE(values2); + return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + } + /* + With the remove_duplicates flag we need to find + this in the original list and remove it, which is + inefficient but hopefully rare. + */ + for (k = 0; k < el->num_values; k++) { + if (ldb_val_equal_exact(&el->values[k], + &values[i])) { + break; + } + } + el->num_values--; + for (; k < el->num_values; k++) { + el->values[k] = el->values[k + 1]; + } + i++; + } + } + TALLOC_FREE(values); + TALLOC_FREE(values2); + + return LDB_SUCCESS; +} + +/* + duplicate a ldb_val structure +*/ +struct ldb_val ldb_val_dup(TALLOC_CTX *mem_ctx, const struct ldb_val *v) +{ + struct ldb_val v2; + v2.length = v->length; + if (v->data == NULL) { + v2.data = NULL; + return v2; + } + + /* the +1 is to cope with buggy C library routines like strndup + that look one byte beyond */ + v2.data = talloc_array(mem_ctx, uint8_t, v->length+1); + if (!v2.data) { + v2.length = 0; + return v2; + } + + memcpy(v2.data, v->data, v->length); + ((char *)v2.data)[v->length] = 0; + return v2; +} + +/** + * Adds new empty element to msg->elements + */ +static int _ldb_msg_add_el(struct ldb_message *msg, + struct ldb_message_element **return_el) +{ + struct ldb_message_element *els; + + /* + * TODO: Find out a way to assert on input parameters. + * msg and return_el must be valid + */ + + els = talloc_realloc(msg, msg->elements, + struct ldb_message_element, msg->num_elements + 1); + if (!els) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ZERO_STRUCT(els[msg->num_elements]); + + msg->elements = els; + msg->num_elements++; + + *return_el = &els[msg->num_elements-1]; + + return LDB_SUCCESS; +} + +/** + * Add an empty element with a given name to a message + */ +int ldb_msg_add_empty(struct ldb_message *msg, + const char *attr_name, + int flags, + struct ldb_message_element **return_el) +{ + int ret; + struct ldb_message_element *el; + + ret = _ldb_msg_add_el(msg, &el); + if (ret != LDB_SUCCESS) { + return ret; + } + + /* initialize newly added element */ + el->flags = flags; + el->name = talloc_strdup(msg->elements, attr_name); + if (!el->name) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (return_el) { + *return_el = el; + } + + return LDB_SUCCESS; +} + +/** + * Adds an element to a message. + * + * NOTE: Ownership of ldb_message_element fields + * is NOT transferred. Thus, if *el pointer + * is invalidated for some reason, this will + * corrupt *msg contents also + */ +int ldb_msg_add(struct ldb_message *msg, + const struct ldb_message_element *el, + int flags) +{ + int ret; + struct ldb_message_element *el_new; + /* We have to copy this, just in case *el is a pointer into + * what ldb_msg_add_empty() is about to realloc() */ + struct ldb_message_element el_copy = *el; + + ret = _ldb_msg_add_el(msg, &el_new); + if (ret != LDB_SUCCESS) { + return ret; + } + + el_new->flags = flags; + el_new->name = el_copy.name; + el_new->num_values = el_copy.num_values; + el_new->values = el_copy.values; + + return LDB_SUCCESS; +} + +/* + add a value to a message +*/ +int ldb_msg_add_value(struct ldb_message *msg, + const char *attr_name, + const struct ldb_val *val, + struct ldb_message_element **return_el) +{ + struct ldb_message_element *el; + struct ldb_val *vals; + int ret; + + el = ldb_msg_find_element(msg, attr_name); + if (!el) { + ret = ldb_msg_add_empty(msg, attr_name, 0, &el); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + vals = talloc_realloc(msg->elements, el->values, struct ldb_val, + el->num_values+1); + if (!vals) { + return LDB_ERR_OPERATIONS_ERROR; + } + el->values = vals; + el->values[el->num_values] = *val; + el->num_values++; + + if (return_el) { + *return_el = el; + } + + return LDB_SUCCESS; +} + + +/* + add a value to a message, stealing it into the 'right' place +*/ +int ldb_msg_add_steal_value(struct ldb_message *msg, + const char *attr_name, + struct ldb_val *val) +{ + int ret; + struct ldb_message_element *el; + + ret = ldb_msg_add_value(msg, attr_name, val, &el); + if (ret == LDB_SUCCESS) { + talloc_steal(el->values, val->data); + } + return ret; +} + + +/* + add a string element to a message +*/ +int ldb_msg_add_string(struct ldb_message *msg, + const char *attr_name, const char *str) +{ + struct ldb_val val; + + val.data = discard_const_p(uint8_t, str); + val.length = strlen(str); + + if (val.length == 0) { + /* allow empty strings as non-existent attributes */ + return LDB_SUCCESS; + } + + return ldb_msg_add_value(msg, attr_name, &val, NULL); +} + +/* + add a string element to a message, stealing it into the 'right' place +*/ +int ldb_msg_add_steal_string(struct ldb_message *msg, + const char *attr_name, char *str) +{ + struct ldb_val val; + + val.data = (uint8_t *)str; + val.length = strlen(str); + + if (val.length == 0) { + /* allow empty strings as non-existent attributes */ + return LDB_SUCCESS; + } + + return ldb_msg_add_steal_value(msg, attr_name, &val); +} + +/* + add a DN element to a message + WARNING: this uses the linearized string from the dn, and does not + copy the string. +*/ +int ldb_msg_add_linearized_dn(struct ldb_message *msg, const char *attr_name, + struct ldb_dn *dn) +{ + char *str = ldb_dn_alloc_linearized(msg, dn); + + if (str == NULL) { + /* we don't want to have unknown DNs added */ + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_msg_add_steal_string(msg, attr_name, str); +} + +/* + add a printf formatted element to a message +*/ +int ldb_msg_add_fmt(struct ldb_message *msg, + const char *attr_name, const char *fmt, ...) +{ + struct ldb_val val; + va_list ap; + char *str; + + va_start(ap, fmt); + str = talloc_vasprintf(msg, fmt, ap); + va_end(ap); + + if (str == NULL) return LDB_ERR_OPERATIONS_ERROR; + + val.data = (uint8_t *)str; + val.length = strlen(str); + + return ldb_msg_add_steal_value(msg, attr_name, &val); +} + +/* + compare two ldb_message_element structures + assumes case sensitive comparison +*/ +int ldb_msg_element_compare(struct ldb_message_element *el1, + struct ldb_message_element *el2) +{ + unsigned int i; + + if (el1->num_values != el2->num_values) { + return el1->num_values - el2->num_values; + } + + for (i=0;inum_values;i++) { + if (!ldb_msg_find_val(el2, &el1->values[i])) { + return -1; + } + } + + return 0; +} + +/* + compare two ldb_message_element structures. + Different ordering is considered a mismatch +*/ +bool ldb_msg_element_equal_ordered(const struct ldb_message_element *el1, + const struct ldb_message_element *el2) +{ + unsigned i; + if (el1->num_values != el2->num_values) { + return false; + } + for (i=0;inum_values;i++) { + if (ldb_val_equal_exact(&el1->values[i], + &el2->values[i]) != 1) { + return false; + } + } + return true; +} + +/* + compare two ldb_message_element structures + comparing by element name +*/ +int ldb_msg_element_compare_name(struct ldb_message_element *el1, + struct ldb_message_element *el2) +{ + return ldb_attr_cmp(el1->name, el2->name); +} + +/* + convenience functions to return common types from a message + these return the first value if the attribute is multi-valued +*/ +const struct ldb_val *ldb_msg_find_ldb_val(const struct ldb_message *msg, + const char *attr_name) +{ + struct ldb_message_element *el = ldb_msg_find_element(msg, attr_name); + if (!el || el->num_values == 0) { + return NULL; + } + return &el->values[0]; +} + +int ldb_msg_find_attr_as_int(const struct ldb_message *msg, + const char *attr_name, + int default_value) +{ + const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + char buf[sizeof("-2147483648")]; + char *end = NULL; + int ret; + + if (!v || !v->data) { + return default_value; + } + + ZERO_STRUCT(buf); + if (v->length >= sizeof(buf)) { + return default_value; + } + + memcpy(buf, v->data, v->length); + errno = 0; + ret = (int) strtoll(buf, &end, 10); + if (errno != 0) { + return default_value; + } + if (end && end[0] != '\0') { + return default_value; + } + return ret; +} + +unsigned int ldb_msg_find_attr_as_uint(const struct ldb_message *msg, + const char *attr_name, + unsigned int default_value) +{ + const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + char buf[sizeof("-2147483648")]; + char *end = NULL; + unsigned int ret; + + if (!v || !v->data) { + return default_value; + } + + ZERO_STRUCT(buf); + if (v->length >= sizeof(buf)) { + return default_value; + } + + memcpy(buf, v->data, v->length); + errno = 0; + ret = (unsigned int) strtoll(buf, &end, 10); + if (errno != 0) { + errno = 0; + ret = (unsigned int) strtoull(buf, &end, 10); + if (errno != 0) { + return default_value; + } + } + if (end && end[0] != '\0') { + return default_value; + } + return ret; +} + +int64_t ldb_msg_find_attr_as_int64(const struct ldb_message *msg, + const char *attr_name, + int64_t default_value) +{ + const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + char buf[sizeof("-9223372036854775808")]; + char *end = NULL; + int64_t ret; + + if (!v || !v->data) { + return default_value; + } + + ZERO_STRUCT(buf); + if (v->length >= sizeof(buf)) { + return default_value; + } + + memcpy(buf, v->data, v->length); + errno = 0; + ret = (int64_t) strtoll(buf, &end, 10); + if (errno != 0) { + return default_value; + } + if (end && end[0] != '\0') { + return default_value; + } + return ret; +} + +uint64_t ldb_msg_find_attr_as_uint64(const struct ldb_message *msg, + const char *attr_name, + uint64_t default_value) +{ + const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + char buf[sizeof("-9223372036854775808")]; + char *end = NULL; + uint64_t ret; + + if (!v || !v->data) { + return default_value; + } + + ZERO_STRUCT(buf); + if (v->length >= sizeof(buf)) { + return default_value; + } + + memcpy(buf, v->data, v->length); + errno = 0; + ret = (uint64_t) strtoll(buf, &end, 10); + if (errno != 0) { + errno = 0; + ret = (uint64_t) strtoull(buf, &end, 10); + if (errno != 0) { + return default_value; + } + } + if (end && end[0] != '\0') { + return default_value; + } + return ret; +} + +double ldb_msg_find_attr_as_double(const struct ldb_message *msg, + const char *attr_name, + double default_value) +{ + const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + char *buf; + char *end = NULL; + double ret; + + if (!v || !v->data) { + return default_value; + } + buf = talloc_strndup(msg, (const char *)v->data, v->length); + if (buf == NULL) { + return default_value; + } + + errno = 0; + ret = strtod(buf, &end); + talloc_free(buf); + if (errno != 0) { + return default_value; + } + if (end && end[0] != '\0') { + return default_value; + } + return ret; +} + +int ldb_msg_find_attr_as_bool(const struct ldb_message *msg, + const char *attr_name, + int default_value) +{ + const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + if (!v || !v->data) { + return default_value; + } + if (v->length == 5 && strncasecmp((const char *)v->data, "FALSE", 5) == 0) { + return 0; + } + if (v->length == 4 && strncasecmp((const char *)v->data, "TRUE", 4) == 0) { + return 1; + } + return default_value; +} + +const char *ldb_msg_find_attr_as_string(const struct ldb_message *msg, + const char *attr_name, + const char *default_value) +{ + const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); + if (!v || !v->data) { + return default_value; + } + if (v->data[v->length] != '\0') { + return default_value; + } + return (const char *)v->data; +} + +struct ldb_dn *ldb_msg_find_attr_as_dn(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const struct ldb_message *msg, + const char *attr_name) +{ + struct ldb_dn *res_dn; + const struct ldb_val *v; + + v = ldb_msg_find_ldb_val(msg, attr_name); + if (!v || !v->data) { + return NULL; + } + res_dn = ldb_dn_from_ldb_val(mem_ctx, ldb, v); + if ( ! ldb_dn_validate(res_dn)) { + talloc_free(res_dn); + return NULL; + } + return res_dn; +} + +/* + sort the elements of a message by name +*/ +void ldb_msg_sort_elements(struct ldb_message *msg) +{ + TYPESAFE_QSORT(msg->elements, msg->num_elements, + ldb_msg_element_compare_name); +} + +/* + shallow copy a message - copying only the elements array so that the caller + can safely add new elements without changing the message +*/ +struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx, + const struct ldb_message *msg) +{ + struct ldb_message *msg2; + unsigned int i; + + msg2 = talloc(mem_ctx, struct ldb_message); + if (msg2 == NULL) return NULL; + + *msg2 = *msg; + + msg2->elements = talloc_array(msg2, struct ldb_message_element, + msg2->num_elements); + if (msg2->elements == NULL) goto failed; + + for (i=0;inum_elements;i++) { + msg2->elements[i] = msg->elements[i]; + } + + return msg2; + +failed: + talloc_free(msg2); + return NULL; +} + + +/* + copy a message, allocating new memory for all parts +*/ +struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, + const struct ldb_message *msg) +{ + struct ldb_message *msg2; + unsigned int i, j; + + msg2 = ldb_msg_copy_shallow(mem_ctx, msg); + if (msg2 == NULL) return NULL; + + msg2->dn = ldb_dn_copy(msg2, msg2->dn); + if (msg2->dn == NULL) goto failed; + + for (i=0;inum_elements;i++) { + struct ldb_message_element *el = &msg2->elements[i]; + struct ldb_val *values = el->values; + el->name = talloc_strdup(msg2->elements, el->name); + if (el->name == NULL) goto failed; + el->values = talloc_array(msg2->elements, struct ldb_val, el->num_values); + if (el->values == NULL) goto failed; + for (j=0;jnum_values;j++) { + el->values[j] = ldb_val_dup(el->values, &values[j]); + if (el->values[j].data == NULL && values[j].length != 0) { + goto failed; + } + } + } + + return msg2; + +failed: + talloc_free(msg2); + return NULL; +} + + +/** + * Canonicalize a message, merging elements of the same name + */ +struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, + const struct ldb_message *msg) +{ + int ret; + struct ldb_message *msg2; + + /* + * Preserve previous behavior and allocate + * *msg2 into *ldb context + */ + ret = ldb_msg_normalize(ldb, ldb, msg, &msg2); + if (ret != LDB_SUCCESS) { + return NULL; + } + + return msg2; +} + +/** + * Canonicalize a message, merging elements of the same name + */ +int ldb_msg_normalize(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const struct ldb_message *msg, + struct ldb_message **_msg_out) +{ + unsigned int i; + struct ldb_message *msg2; + + msg2 = ldb_msg_copy(mem_ctx, msg); + if (msg2 == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ldb_msg_sort_elements(msg2); + + for (i=1; i < msg2->num_elements; i++) { + struct ldb_message_element *el1 = &msg2->elements[i-1]; + struct ldb_message_element *el2 = &msg2->elements[i]; + + if (ldb_msg_element_compare_name(el1, el2) == 0) { + el1->values = talloc_realloc(msg2->elements, + el1->values, struct ldb_val, + el1->num_values + el2->num_values); + if (el1->num_values + el2->num_values > 0 && el1->values == NULL) { + talloc_free(msg2); + return LDB_ERR_OPERATIONS_ERROR; + } + memcpy(el1->values + el1->num_values, + el2->values, + sizeof(struct ldb_val) * el2->num_values); + el1->num_values += el2->num_values; + talloc_free(discard_const_p(char, el2->name)); + if ((i+1) < msg2->num_elements) { + memmove(el2, el2+1, sizeof(struct ldb_message_element) * + (msg2->num_elements - (i+1))); + } + msg2->num_elements--; + i--; + } + } + + *_msg_out = msg2; + return LDB_SUCCESS; +} + + +/** + * return a ldb_message representing the differences between msg1 and msg2. + * If you then use this in a ldb_modify() call, + * it can be used to save edits to a message + */ +struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, + struct ldb_message *msg1, + struct ldb_message *msg2) +{ + int ldb_ret; + struct ldb_message *mod; + + ldb_ret = ldb_msg_difference(ldb, ldb, msg1, msg2, &mod); + if (ldb_ret != LDB_SUCCESS) { + return NULL; + } + + return mod; +} + +/** + * return a ldb_message representing the differences between msg1 and msg2. + * If you then use this in a ldb_modify() call it can be used to save edits to a message + * + * Result message is constructed as follows: + * - LDB_FLAG_MOD_ADD - elements found only in msg2 + * - LDB_FLAG_MOD_REPLACE - elements in msg2 that have different value in msg1 + * Value for msg2 element is used + * - LDB_FLAG_MOD_DELETE - elements found only in msg2 + * + * @return LDB_SUCCESS or LDB_ERR_OPERATIONS_ERROR + */ +int ldb_msg_difference(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_message *msg1, + struct ldb_message *msg2, + struct ldb_message **_msg_out) +{ + int ldb_res; + unsigned int i; + struct ldb_message *mod; + struct ldb_message_element *el; + TALLOC_CTX *temp_ctx; + + temp_ctx = talloc_new(mem_ctx); + if (!temp_ctx) { + return LDB_ERR_OPERATIONS_ERROR; + } + + mod = ldb_msg_new(temp_ctx); + if (mod == NULL) { + goto failed; + } + + mod->dn = msg1->dn; + mod->num_elements = 0; + mod->elements = NULL; + + /* + * Canonicalize *msg2 so we have no repeated elements + * Resulting message is allocated in *mod's mem context, + * as we are going to move some elements from *msg2 to + * *mod object later + */ + ldb_res = ldb_msg_normalize(ldb, mod, msg2, &msg2); + if (ldb_res != LDB_SUCCESS) { + goto failed; + } + + /* look in msg2 to find elements that need to be added or modified */ + for (i=0;inum_elements;i++) { + el = ldb_msg_find_element(msg1, msg2->elements[i].name); + + if (el && ldb_msg_element_compare(el, &msg2->elements[i]) == 0) { + continue; + } + + ldb_res = ldb_msg_add(mod, + &msg2->elements[i], + el ? LDB_FLAG_MOD_REPLACE : LDB_FLAG_MOD_ADD); + if (ldb_res != LDB_SUCCESS) { + goto failed; + } + } + + /* look in msg1 to find elements that need to be deleted */ + for (i=0;inum_elements;i++) { + el = ldb_msg_find_element(msg2, msg1->elements[i].name); + if (el == NULL) { + ldb_res = ldb_msg_add_empty(mod, + msg1->elements[i].name, + LDB_FLAG_MOD_DELETE, NULL); + if (ldb_res != LDB_SUCCESS) { + goto failed; + } + } + } + + /* steal resulting message into supplied context */ + talloc_steal(mem_ctx, mod); + *_msg_out = mod; + + talloc_free(temp_ctx); + return LDB_SUCCESS; + +failed: + talloc_free(temp_ctx); + return LDB_ERR_OPERATIONS_ERROR; +} + + +int ldb_msg_sanity_check(struct ldb_context *ldb, + const struct ldb_message *msg) +{ + unsigned int i, j; + + /* basic check on DN */ + if (msg->dn == NULL) { + ldb_set_errstring(ldb, "ldb message lacks a DN!"); + return LDB_ERR_INVALID_DN_SYNTAX; + } + + /* basic syntax checks */ + for (i = 0; i < msg->num_elements; i++) { + for (j = 0; j < msg->elements[i].num_values; j++) { + if (msg->elements[i].values[j].length == 0) { + /* an attribute cannot be empty */ + ldb_asprintf_errstring(ldb, "Element %s has empty attribute in ldb message (%s)!", + msg->elements[i].name, + ldb_dn_get_linearized(msg->dn)); + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + } + } + + return LDB_SUCCESS; +} + + + + +/* + copy an attribute list. This only copies the array, not the elements + (ie. the elements are left as the same pointers) +*/ +const char **ldb_attr_list_copy(TALLOC_CTX *mem_ctx, const char * const *attrs) +{ + const char **ret; + unsigned int i; + + for (i=0;attrs && attrs[i];i++) /* noop */ ; + ret = talloc_array(mem_ctx, const char *, i+1); + if (ret == NULL) { + return NULL; + } + for (i=0;attrs && attrs[i];i++) { + ret[i] = attrs[i]; + } + ret[i] = attrs[i]; + return ret; +} + + +/* + copy an attribute list. This only copies the array, not the elements + (ie. the elements are left as the same pointers). The new attribute is added to the list. +*/ +const char **ldb_attr_list_copy_add(TALLOC_CTX *mem_ctx, const char * const *attrs, const char *new_attr) +{ + const char **ret; + unsigned int i; + bool found = false; + + for (i=0;attrs && attrs[i];i++) { + if (ldb_attr_cmp(attrs[i], new_attr) == 0) { + found = true; + } + } + if (found) { + return ldb_attr_list_copy(mem_ctx, attrs); + } + ret = talloc_array(mem_ctx, const char *, i+2); + if (ret == NULL) { + return NULL; + } + for (i=0;attrs && attrs[i];i++) { + ret[i] = attrs[i]; + } + ret[i] = new_attr; + ret[i+1] = NULL; + return ret; +} + + +/* + return 1 if an attribute is in a list of attributes, or 0 otherwise +*/ +int ldb_attr_in_list(const char * const *attrs, const char *attr) +{ + unsigned int i; + for (i=0;attrs && attrs[i];i++) { + if (ldb_attr_cmp(attrs[i], attr) == 0) { + return 1; + } + } + return 0; +} + + +/* + rename the specified attribute in a search result +*/ +int ldb_msg_rename_attr(struct ldb_message *msg, const char *attr, const char *replace) +{ + struct ldb_message_element *el = ldb_msg_find_element(msg, attr); + if (el == NULL) { + return LDB_SUCCESS; + } + el->name = talloc_strdup(msg->elements, replace); + if (el->name == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + return LDB_SUCCESS; +} + + +/* + copy the specified attribute in a search result to a new attribute +*/ +int ldb_msg_copy_attr(struct ldb_message *msg, const char *attr, const char *replace) +{ + struct ldb_message_element *el = ldb_msg_find_element(msg, attr); + int ret; + + if (el == NULL) { + return LDB_SUCCESS; + } + ret = ldb_msg_add(msg, el, 0); + if (ret != LDB_SUCCESS) { + return ret; + } + return ldb_msg_rename_attr(msg, attr, replace); +} + +/* + remove the specified element in a search result +*/ +void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el) +{ + ptrdiff_t n = (el - msg->elements); + if (n >= msg->num_elements || n < 0) { + /* the element is not in the list. the caller is crazy. */ + return; + } + msg->num_elements--; + if (n != msg->num_elements) { + memmove(el, el+1, (msg->num_elements - n)*sizeof(*el)); + } +} + + +/* + remove the specified attribute in a search result +*/ +void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr) +{ + struct ldb_message_element *el; + + while ((el = ldb_msg_find_element(msg, attr)) != NULL) { + ldb_msg_remove_element(msg, el); + } +} + +/* + return a LDAP formatted GeneralizedTime string +*/ +char *ldb_timestring(TALLOC_CTX *mem_ctx, time_t t) +{ + struct tm *tm = gmtime(&t); + char *ts; + int r; + + if (!tm) { + return NULL; + } + + /* we now excatly how long this string will be */ + ts = talloc_array(mem_ctx, char, 18); + + /* formatted like: 20040408072012.0Z */ + r = snprintf(ts, 18, + "%04u%02u%02u%02u%02u%02u.0Z", + tm->tm_year+1900, tm->tm_mon+1, + tm->tm_mday, tm->tm_hour, tm->tm_min, + tm->tm_sec); + + if (r != 17) { + talloc_free(ts); + return NULL; + } + + return ts; +} + +/* + convert a LDAP GeneralizedTime string to a time_t. Return 0 if unable to convert +*/ +time_t ldb_string_to_time(const char *s) +{ + struct tm tm; + + if (s == NULL) return 0; + + memset(&tm, 0, sizeof(tm)); + if (sscanf(s, "%04u%02u%02u%02u%02u%02u.0Z", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, + &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { + return 0; + } + tm.tm_year -= 1900; + tm.tm_mon -= 1; + + return timegm(&tm); +} + +/* + convert a LDAP GeneralizedTime string in ldb_val format to a + time_t. +*/ +int ldb_val_to_time(const struct ldb_val *v, time_t *t) +{ + char val[15] = {0}; + struct tm tm = { + .tm_year = 0, + }; + + if (v == NULL) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + + if (v->data == NULL) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + + if (v->length < 16 && v->length != 13) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + + if (v->data[v->length - 1] != 'Z') { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + + if (v->length == 13) { + memcpy(val, v->data, 12); + + if (sscanf(val, "%02u%02u%02u%02u%02u%02u", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, + &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + if (tm.tm_year < 50) { + tm.tm_year += 100; + } + } else { + + /* + * anything between '.' and 'Z' is silently ignored. + */ + if (v->data[14] != '.') { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + + memcpy(val, v->data, 14); + + if (sscanf(val, "%04u%02u%02u%02u%02u%02u", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, + &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + tm.tm_year -= 1900; + } + tm.tm_mon -= 1; + + *t = timegm(&tm); + + return LDB_SUCCESS; +} + +/* + return a LDAP formatted UTCTime string +*/ +char *ldb_timestring_utc(TALLOC_CTX *mem_ctx, time_t t) +{ + struct tm *tm = gmtime(&t); + char *ts; + int r; + + if (!tm) { + return NULL; + } + + /* we now excatly how long this string will be */ + ts = talloc_array(mem_ctx, char, 14); + + /* formatted like: 20040408072012.0Z => 040408072012Z */ + r = snprintf(ts, 14, + "%02u%02u%02u%02u%02u%02uZ", + (tm->tm_year+1900)%100, tm->tm_mon+1, + tm->tm_mday, tm->tm_hour, tm->tm_min, + tm->tm_sec); + + if (r != 13) { + talloc_free(ts); + return NULL; + } + + return ts; +} + +/* + convert a LDAP UTCTime string to a time_t. Return 0 if unable to convert +*/ +time_t ldb_string_utc_to_time(const char *s) +{ + struct tm tm; + + if (s == NULL) return 0; + + memset(&tm, 0, sizeof(tm)); + if (sscanf(s, "%02u%02u%02u%02u%02u%02uZ", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, + &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { + return 0; + } + if (tm.tm_year < 50) { + tm.tm_year += 100; + } + tm.tm_mon -= 1; + + return timegm(&tm); +} + + +/* + dump a set of results to a file. Useful from within gdb +*/ +void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *f) +{ + unsigned int i; + + for (i = 0; i < result->count; i++) { + struct ldb_ldif ldif; + fprintf(f, "# record %d\n", i+1); + ldif.changetype = LDB_CHANGETYPE_NONE; + ldif.msg = result->msgs[i]; + ldb_ldif_write_file(ldb, f, &ldif); + } +} + +/* + checks for a string attribute. Returns "1" on match and otherwise "0". +*/ +int ldb_msg_check_string_attribute(const struct ldb_message *msg, + const char *name, const char *value) +{ + struct ldb_message_element *el; + struct ldb_val val; + + el = ldb_msg_find_element(msg, name); + if (el == NULL) { + return 0; + } + + val.data = discard_const_p(uint8_t, value); + val.length = strlen(value); + + if (ldb_msg_find_val(el, &val)) { + return 1; + } + + return 0; +} + + +/* + compare a ldb_val to a string +*/ +int ldb_val_string_cmp(const struct ldb_val *v, const char *str) +{ + size_t len = strlen(str); + if (len != v->length) { + return len - v->length; + } + return strncmp((const char *)v->data, str, len); +} diff --git a/ldb-2.0.8/common/ldb_options.c b/ldb-2.0.8/common/ldb_options.c new file mode 100644 index 0000000..ee8c728 --- /dev/null +++ b/ldb-2.0.8/common/ldb_options.c @@ -0,0 +1,107 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2010 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb options[] handling + * + * Author: Andrew Tridgell + */ + +#include "ldb_private.h" + +/* + find an option within an options array + + accepts the following forms: + + NAME + NAME:value + NAME=value + + returns a pointer into an element of the options[] array, or NULL is + not found. + + For the NAME form, returns a pointer to an empty string (thus + allowing for boolean options). + */ +const char *ldb_options_find(struct ldb_context *ldb, const char *options[], + const char *option_name) +{ + size_t len = strlen(option_name); + int i; + + if (options == NULL) { + return NULL; + } + + for (i=0; options[i]; i++) { + if (strncmp(option_name, options[i], len) != 0) { + continue; + } + if (options[i][len] == ':' || options[i][len] == '=') { + return &options[i][len+1]; + } + if (options[i][len] == 0) { + return &options[i][len]; + } + } + + return NULL; +} + +const char **ldb_options_copy(TALLOC_CTX *ctx, const char *options[]) +{ + + size_t num_options = 0; + const char **copy = NULL; + size_t i = 0; + + if (options == NULL) { + return copy; + } + + for (i=0; options[i]; i++) { + num_options++; + } + + copy = talloc_zero_array(ctx, const char *, num_options + 1); + if (copy == NULL) { + return copy; + } + + for (i=0; options[i]; i++) { + copy[i] = talloc_strdup(copy, options[i]); + if (copy[i] == NULL) { + TALLOC_FREE(copy); + return copy; + } + } + return copy; +} + +const char **ldb_options_get(struct ldb_context *ldb) +{ + return ldb->options; +} diff --git a/ldb-2.0.8/common/ldb_pack.c b/ldb-2.0.8/common/ldb_pack.c new file mode 100644 index 0000000..e7dd364 --- /dev/null +++ b/ldb-2.0.8/common/ldb_pack.c @@ -0,0 +1,1261 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb pack/unpack + * + * Description: pack/unpack routines for ldb messages as key/value blobs + * + * Author: Andrew Tridgell + */ + +#include "ldb_private.h" + +/* + * These macros are from byte_array.h via libssh + * TODO: This will be replaced with use of the byte_array.h header when it + * becomes available. + * + * Macros for handling integer types in byte arrays + * + * This file is originally from the libssh.org project + * + * Copyright (c) 2018 Andreas Schneider + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#define _DATA_BYTE_CONST(data, pos) \ + ((uint8_t)(((const uint8_t *)(data))[(pos)])) +#define PULL_LE_U8(data, pos) \ + (_DATA_BYTE_CONST(data, pos)) +#define PULL_LE_U16(data, pos) \ + ((uint16_t)PULL_LE_U8(data, pos) |\ + ((uint16_t)(PULL_LE_U8(data, (pos) + 1))) << 8) +#define PULL_LE_U32(data, pos) \ + ((uint32_t)(PULL_LE_U16(data, pos) |\ + ((uint32_t)PULL_LE_U16(data, (pos) + 2)) << 16)) + +#define _DATA_BYTE(data, pos) \ + (((uint8_t *)(data))[(pos)]) +#define PUSH_LE_U8(data, pos, val) \ + (_DATA_BYTE(data, pos) = ((uint8_t)(val))) +#define PUSH_LE_U16(data, pos, val) \ + (PUSH_LE_U8((data), (pos), (uint8_t)((uint16_t)(val) & 0xff)),\ + PUSH_LE_U8((data), (pos) + 1,\ + (uint8_t)((uint16_t)(val) >> 8))) +#define PUSH_LE_U32(data, pos, val) \ + (PUSH_LE_U16((data), (pos), (uint16_t)((uint32_t)(val) & 0xffff)),\ + PUSH_LE_U16((data), (pos) + 2, (uint16_t)((uint32_t)(val) >> 16))) + +#define U32_LEN 4 +#define U16_LEN 2 +#define U8_LEN 1 +#define NULL_PAD_BYTE_LEN 1 + +static int attribute_storable_values(const struct ldb_message_element *el) +{ + if (el->num_values == 0) return 0; + + if (ldb_attr_cmp(el->name, "distinguishedName") == 0) return 0; + + return el->num_values; +} + +static int ldb_pack_data_v1(struct ldb_context *ldb, + const struct ldb_message *message, + struct ldb_val *data) +{ + unsigned int i, j, real_elements=0; + size_t size, dn_len, attr_len, value_len; + const char *dn; + uint8_t *p; + size_t len; + + dn = ldb_dn_get_linearized(message->dn); + if (dn == NULL) { + errno = ENOMEM; + return -1; + } + + /* work out how big it needs to be */ + size = U32_LEN * 2 + NULL_PAD_BYTE_LEN; + + dn_len = strlen(dn); + if (size + dn_len < size) { + errno = ENOMEM; + return -1; + } + size += dn_len; + + /* + * First calcuate the buffer size we need, and check for + * overflows + */ + for (i=0;inum_elements;i++) { + if (attribute_storable_values(&message->elements[i]) == 0) { + continue; + } + + real_elements++; + + if (size + U32_LEN + NULL_PAD_BYTE_LEN < size) { + errno = ENOMEM; + return -1; + } + size += U32_LEN + NULL_PAD_BYTE_LEN; + + attr_len = strlen(message->elements[i].name); + if (size + attr_len < size) { + errno = ENOMEM; + return -1; + } + size += attr_len; + + for (j=0;jelements[i].num_values;j++) { + if (size + U32_LEN + NULL_PAD_BYTE_LEN < size) { + errno = ENOMEM; + return -1; + } + size += U32_LEN + NULL_PAD_BYTE_LEN; + + value_len = message->elements[i].values[j].length; + if (size + value_len < size) { + errno = ENOMEM; + return -1; + } + size += value_len; + } + } + + /* allocate it */ + data->data = talloc_array(ldb, uint8_t, size); + if (!data->data) { + errno = ENOMEM; + return -1; + } + data->length = size; + + p = data->data; + PUSH_LE_U32(p, 0, LDB_PACKING_FORMAT); + p += U32_LEN; + PUSH_LE_U32(p, 0, real_elements); + p += U32_LEN; + + /* the dn needs to be packed so we can be case preserving + while hashing on a case folded dn */ + len = dn_len; + memcpy(p, dn, len+NULL_PAD_BYTE_LEN); + p += len + NULL_PAD_BYTE_LEN; + + for (i=0;inum_elements;i++) { + if (attribute_storable_values(&message->elements[i]) == 0) { + continue; + } + len = strlen(message->elements[i].name); + memcpy(p, message->elements[i].name, len+NULL_PAD_BYTE_LEN); + p += len + NULL_PAD_BYTE_LEN; + PUSH_LE_U32(p, 0, message->elements[i].num_values); + p += U32_LEN; + for (j=0;jelements[i].num_values;j++) { + PUSH_LE_U32(p, 0, + message->elements[i].values[j].length); + p += U32_LEN; + memcpy(p, message->elements[i].values[j].data, + message->elements[i].values[j].length); + p[message->elements[i].values[j].length] = 0; + p += message->elements[i].values[j].length + + NULL_PAD_BYTE_LEN; + } + } + + return 0; +} + +/* + * New pack version designed based on performance profiling of version 1. + * The approach is to separate value data from the rest of the record's data. + * This improves performance because value data is not needed during unpacking + * or filtering of the message's attribute list. During filtering we only copy + * attributes which are present in the attribute list, however at the parse + * stage we need to point to all attributes as they may be referenced in the + * search expression. + * With this new format, we don't lose time loading data (eg via + * talloc_memdup()) that is never needed (for the vast majority of attributes + * are are never found in either the search expression or attribute list). + * Additional changes include adding a canonicalized DN (for later + * optimizations) and variable width length fields for faster unpacking. + * The pack and unpack performance improvement is tested in the torture + * test torture_ldb_pack_format_perf. + * + * Layout: + * + * Version (4 bytes) + * Number of Elements (4 bytes) + * DN length (4 bytes) + * DN with null terminator (DN length + 1 bytes) + * Canonicalized DN length (4 bytes) + * Canonicalized DN with null terminator (Canonicalized DN length + 1 bytes) + * Number of bytes from here to value data section (4 bytes) + * # For each element: + * Element name length (4 bytes) + * Element name with null terminator (Element name length + 1 bytes) + * Number of values (4 bytes) + * Width of value lengths + * # For each value: + * Value data length (#bytes given by width field above) + * # For each element: + * # For each value: + * Value data (#bytes given by corresponding length above) + */ +static int ldb_pack_data_v2(struct ldb_context *ldb, + const struct ldb_message *message, + struct ldb_val *data) +{ + unsigned int i, j, real_elements=0; + size_t size, dn_len, dn_canon_len, attr_len, value_len; + const char *dn, *dn_canon; + uint8_t *p, *q; + size_t len; + size_t max_val_len; + uint8_t val_len_width; + + /* + * First half of this function will calculate required size for + * packed data. Initial size is 20 = 5 * 4. 5 fixed fields are: + * version, num elements, dn len, canon dn len, attr section len + */ + size = U32_LEN * 5; + + /* + * Get linearized and canonicalized form of the DN and add the lengths + * of each to size, plus 1 for null terminator. + */ + dn = ldb_dn_get_linearized(message->dn); + if (dn == NULL) { + errno = ENOMEM; + return -1; + } + + dn_len = strlen(dn) + NULL_PAD_BYTE_LEN; + if (size + dn_len < size) { + errno = ENOMEM; + return -1; + } + size += dn_len; + + if (ldb_dn_is_special(message->dn)) { + dn_canon_len = NULL_PAD_BYTE_LEN; + dn_canon = discard_const_p(char, "\0"); + } else { + dn_canon = ldb_dn_canonical_string(message->dn, message->dn); + if (dn_canon == NULL) { + errno = ENOMEM; + return -1; + } + + dn_canon_len = strlen(dn_canon) + NULL_PAD_BYTE_LEN; + if (size + dn_canon_len < size) { + errno = ENOMEM; + return -1; + } + } + size += dn_canon_len; + + /* Add the size required by each element */ + for (i=0;inum_elements;i++) { + if (attribute_storable_values(&message->elements[i]) == 0) { + continue; + } + + real_elements++; + + /* + * Add length of element name + 9 for: + * 1 for null terminator + * 4 for element name length field + * 4 for number of values field + */ + attr_len = strlen(message->elements[i].name); + if (size + attr_len + U32_LEN * 2 + NULL_PAD_BYTE_LEN < size) { + errno = ENOMEM; + return -1; + } + size += attr_len + U32_LEN * 2 + NULL_PAD_BYTE_LEN; + + /* + * Find the max value length, so we can calculate the width + * required for the value length fields. + */ + max_val_len = 0; + for (j=0;jelements[i].num_values;j++) { + value_len = message->elements[i].values[j].length; + if (value_len > max_val_len) { + max_val_len = value_len; + } + + if (size + value_len + NULL_PAD_BYTE_LEN < size) { + errno = ENOMEM; + return -1; + } + size += value_len + NULL_PAD_BYTE_LEN; + } + + if (max_val_len <= UCHAR_MAX) { + val_len_width = U8_LEN; + } else if (max_val_len <= USHRT_MAX) { + val_len_width = U16_LEN; + } else if (max_val_len <= UINT_MAX) { + val_len_width = U32_LEN; + } else { + errno = EMSGSIZE; + return -1; + } + + /* Total size required for val lengths (re-using variable) */ + max_val_len = (val_len_width*message->elements[i].num_values); + + /* Add one for storing the width */ + max_val_len += U8_LEN; + if (size + max_val_len < size) { + errno = ENOMEM; + return -1; + } + size += max_val_len; + } + + /* Allocate */ + data->data = talloc_array(ldb, uint8_t, size); + if (!data->data) { + errno = ENOMEM; + return -1; + } + data->length = size; + + /* Packing format version and number of element */ + p = data->data; + PUSH_LE_U32(p, 0, LDB_PACKING_FORMAT_V2); + p += U32_LEN; + PUSH_LE_U32(p, 0, real_elements); + p += U32_LEN; + + /* Pack DN and Canonicalized DN */ + PUSH_LE_U32(p, 0, dn_len-NULL_PAD_BYTE_LEN); + p += U32_LEN; + memcpy(p, dn, dn_len); + p += dn_len; + + PUSH_LE_U32(p, 0, dn_canon_len-NULL_PAD_BYTE_LEN); + p += U32_LEN; + memcpy(p, dn_canon, dn_canon_len); + p += dn_canon_len; + + /* + * Save pointer at this point and leave a U32_LEN gap for + * storing the size of the attribute names and value lengths + * section + */ + q = p; + p += U32_LEN; + + for (i=0;inum_elements;i++) { + if (attribute_storable_values(&message->elements[i]) == 0) { + continue; + } + + /* Length of el name */ + len = strlen(message->elements[i].name); + PUSH_LE_U32(p, 0, len); + p += U32_LEN; + + /* + * Even though we have the element name's length, put a null + * terminator at the end so if any code uses the name + * directly, it'll be safe to do things requiring null + * termination like strlen + */ + memcpy(p, message->elements[i].name, len+NULL_PAD_BYTE_LEN); + p += len + NULL_PAD_BYTE_LEN; + /* Num values */ + PUSH_LE_U32(p, 0, message->elements[i].num_values); + p += U32_LEN; + + /* + * Calculate value length width again. It's faster to + * calculate it again than do the array management to + * store the result during size calculation. + */ + max_val_len = 0; + for (j=0;jelements[i].num_values;j++) { + value_len = message->elements[i].values[j].length; + if (value_len > max_val_len) { + max_val_len = value_len; + } + } + + if (max_val_len <= UCHAR_MAX) { + val_len_width = U8_LEN; + } else if (max_val_len <= USHRT_MAX) { + val_len_width = U16_LEN; + } else if (max_val_len <= UINT_MAX) { + val_len_width = U32_LEN; + } else { + errno = EMSGSIZE; + return -1; + } + + /* Pack the width */ + *p = val_len_width & 0xFF; + p += U8_LEN; + + /* + * Pack each value's length using the minimum number of bytes + * required, which we just calculated. We repeat the loop + * for each case here so the compiler can inline code. + */ + if (val_len_width == U8_LEN) { + for (j=0;jelements[i].num_values;j++) { + PUSH_LE_U8(p, 0, + message->elements[i].values[j].length); + p += U8_LEN; + } + } else if (val_len_width == U16_LEN) { + for (j=0;jelements[i].num_values;j++) { + PUSH_LE_U16(p, 0, + message->elements[i].values[j].length); + p += U16_LEN; + } + } else if (val_len_width == U32_LEN) { + for (j=0;jelements[i].num_values;j++) { + PUSH_LE_U32(p, 0, + message->elements[i].values[j].length); + p += U32_LEN; + } + } + } + + /* + * We've finished packing the attr names and value lengths + * section, so store the size in the U32_LEN gap we left + * earlier + */ + PUSH_LE_U32(q, 0, p-q); + + /* Now pack the values */ + for (i=0;inum_elements;i++) { + if (attribute_storable_values(&message->elements[i]) == 0) { + continue; + } + for (j=0;jelements[i].num_values;j++) { + memcpy(p, message->elements[i].values[j].data, + message->elements[i].values[j].length); + + /* + * Even though we have the data length, put a null + * terminator at the end of each value's data so if + * any code uses the data directly, it'll be safe to + * do things requiring null termination like strlen. + */ + p[message->elements[i].values[j].length] = 0; + p += message->elements[i].values[j].length + + NULL_PAD_BYTE_LEN; + } + } + + /* + * If we didn't end up at the end of the data here, something has + * gone very wrong. + */ + if (p != data->data + size) { + errno = ENOMEM; + return -1; + } + + return 0; +} + +/* + pack a ldb message into a linear buffer in a ldb_val + + note that this routine avoids saving elements with zero values, + as these are equivalent to having no element + + caller frees the data buffer after use +*/ +int ldb_pack_data(struct ldb_context *ldb, + const struct ldb_message *message, + struct ldb_val *data, + uint32_t pack_format_version) { + + if (pack_format_version == LDB_PACKING_FORMAT) { + return ldb_pack_data_v1(ldb, message, data); + } else if (pack_format_version == LDB_PACKING_FORMAT_V2) { + return ldb_pack_data_v2(ldb, message, data); + } else { + errno = EINVAL; + return -1; + } +} + +/* + * Unpack a ldb message from a linear buffer in ldb_val + */ +static int ldb_unpack_data_flags_v1(struct ldb_context *ldb, + const struct ldb_val *data, + struct ldb_message *message, + unsigned int flags, + unsigned format) +{ + uint8_t *p; + size_t remaining; + size_t dn_len; + unsigned int i, j; + unsigned int nelem = 0; + size_t len; + struct ldb_val *ldb_val_single_array = NULL; + + message->elements = NULL; + + p = data->data; + + /* Format (U32, already read) + U32 for num_elements */ + if (data->length < U32_LEN * 2) { + errno = EIO; + goto failed; + } + + /* Skip first 4 bytes, format already read */ + p += U32_LEN; + message->num_elements = PULL_LE_U32(p, 0); + p += U32_LEN; + + remaining = data->length - U32_LEN * 2; + + switch (format) { + case LDB_PACKING_FORMAT_NODN: + message->dn = NULL; + break; + + case LDB_PACKING_FORMAT: + /* + * With this check, we know that the DN at p is \0 + * terminated. + */ + dn_len = strnlen((char *)p, remaining); + if (dn_len == remaining) { + errno = EIO; + goto failed; + } + if (flags & LDB_UNPACK_DATA_FLAG_NO_DN) { + message->dn = NULL; + } else { + struct ldb_val blob; + blob.data = discard_const_p(uint8_t, p); + blob.length = dn_len; + message->dn = ldb_dn_from_ldb_val(message, ldb, &blob); + if (message->dn == NULL) { + errno = ENOMEM; + goto failed; + } + } + /* + * Redundant: by definition, remaining must be more + * than one less than dn_len, as otherwise it would be + * == dn_len + */ + if (remaining < dn_len + NULL_PAD_BYTE_LEN) { + errno = EIO; + goto failed; + } + remaining -= dn_len + NULL_PAD_BYTE_LEN; + p += dn_len + NULL_PAD_BYTE_LEN; + break; + + default: + errno = EIO; + goto failed; + } + + if (flags & LDB_UNPACK_DATA_FLAG_NO_ATTRS) { + return 0; + } + + if (message->num_elements == 0) { + return 0; + } + + if (message->num_elements > remaining / 6) { + errno = EIO; + goto failed; + } + + message->elements = talloc_zero_array(message, struct ldb_message_element, + message->num_elements); + if (!message->elements) { + errno = ENOMEM; + goto failed; + } + + /* + * In typical use, most values are single-valued. This makes + * it quite expensive to allocate an array of ldb_val for each + * of these, just to then hold the pointer to the data buffer + * So with LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC we allocate this + * ahead of time and use it for the single values where possible. + * (This is used the the normal search case, but not in the + * index case because of caller requirements). + */ + if (flags & LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC) { + ldb_val_single_array = talloc_array(message->elements, struct ldb_val, + message->num_elements); + if (ldb_val_single_array == NULL) { + errno = ENOMEM; + goto failed; + } + } + + for (i=0;inum_elements;i++) { + const char *attr = NULL; + size_t attr_len; + struct ldb_message_element *element = NULL; + + /* + * Sanity check: Element must be at least the size of empty + * attr name and value and NULL terms for each. + */ + if (remaining < U32_LEN * 2 + NULL_PAD_BYTE_LEN * 2) { + errno = EIO; + goto failed; + } + + /* + * With this check, we know that the attribute name at + * p is \0 terminated. + */ + attr_len = strnlen((char *)p, remaining-6); + if (attr_len == remaining-6) { + errno = EIO; + goto failed; + } + if (attr_len == 0) { + errno = EIO; + goto failed; + } + attr = (char *)p; + + element = &message->elements[nelem]; + element->name = attr; + element->flags = 0; + + if (remaining < (attr_len + NULL_PAD_BYTE_LEN)) { + errno = EIO; + goto failed; + } + remaining -= attr_len + NULL_PAD_BYTE_LEN; + p += attr_len + NULL_PAD_BYTE_LEN; + element->num_values = PULL_LE_U32(p, 0); + element->values = NULL; + if ((flags & LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC) && element->num_values == 1) { + element->values = &ldb_val_single_array[nelem]; + } else if (element->num_values != 0) { + element->values = talloc_array(message->elements, + struct ldb_val, + element->num_values); + if (!element->values) { + errno = ENOMEM; + goto failed; + } + } + p += U32_LEN; + if (remaining < U32_LEN) { + errno = EIO; + goto failed; + } + remaining -= U32_LEN; + for (j = 0; j < element->num_values; j++) { + /* + * Sanity check: Value must be at least the size of + * empty val and NULL terminator. + */ + if (remaining < U32_LEN + NULL_PAD_BYTE_LEN) { + errno = EIO; + goto failed; + } + remaining -= U32_LEN + NULL_PAD_BYTE_LEN; + + len = PULL_LE_U32(p, 0); + if (remaining < len) { + errno = EIO; + goto failed; + } + if (len + NULL_PAD_BYTE_LEN < len) { + errno = EIO; + goto failed; + } + + element->values[j].length = len; + element->values[j].data = p + U32_LEN; + remaining -= len; + p += len + U32_LEN + NULL_PAD_BYTE_LEN; + } + nelem++; + } + /* + * Adapt the number of elements to the real number of unpacked elements, + * it means that we overallocated elements array. + */ + message->num_elements = nelem; + + /* + * Shrink the allocated size. On current talloc behaviour + * this will help if we skipped 32 or more attributes. + */ + message->elements = talloc_realloc(message, message->elements, + struct ldb_message_element, + message->num_elements); + + if (remaining != 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: %zu bytes unread in ldb_unpack_data_flags", + remaining); + } + + return 0; + +failed: + talloc_free(message->elements); + return -1; +} + +/* + * Unpack a ldb message from a linear buffer in ldb_val + */ +static int ldb_unpack_data_flags_v2(struct ldb_context *ldb, + const struct ldb_val *data, + struct ldb_message *message, + unsigned int flags) +{ + uint8_t *p, *q, *end_p, *value_section_p; + unsigned int i, j; + unsigned int nelem = 0; + size_t len; + struct ldb_val *ldb_val_single_array = NULL; + uint8_t val_len_width; + + message->elements = NULL; + + p = data->data; + end_p = p + data->length; + + /* Skip first 4 bytes, format already read */ + p += U32_LEN; + + /* First fields are fixed: num_elements, DN length */ + if (p + U32_LEN * 2 > end_p) { + errno = EIO; + goto failed; + } + + message->num_elements = PULL_LE_U32(p, 0); + p += U32_LEN; + + len = PULL_LE_U32(p, 0); + p += U32_LEN; + + if (p + len + NULL_PAD_BYTE_LEN > end_p) { + errno = EIO; + goto failed; + } + + if (flags & LDB_UNPACK_DATA_FLAG_NO_DN) { + message->dn = NULL; + } else { + struct ldb_val blob; + blob.data = discard_const_p(uint8_t, p); + blob.length = len; + message->dn = ldb_dn_from_ldb_val(message, ldb, &blob); + if (message->dn == NULL) { + errno = ENOMEM; + goto failed; + } + } + + p += len + NULL_PAD_BYTE_LEN; + + if (*(p-NULL_PAD_BYTE_LEN) != '\0') { + errno = EINVAL; + goto failed; + } + + /* Now skip the canonicalized DN and its length */ + len = PULL_LE_U32(p, 0) + NULL_PAD_BYTE_LEN; + p += U32_LEN; + + if (p + len > end_p) { + errno = EIO; + goto failed; + } + + p += len; + + if (*(p-NULL_PAD_BYTE_LEN) != '\0') { + errno = EINVAL; + goto failed; + } + + if (flags & LDB_UNPACK_DATA_FLAG_NO_ATTRS) { + return 0; + } + + if (message->num_elements == 0) { + return 0; + } + + /* + * Sanity check (17 bytes is the minimum element size) + */ + if (message->num_elements > (end_p - p) / 17) { + errno = EIO; + goto failed; + } + + message->elements = talloc_zero_array(message, + struct ldb_message_element, + message->num_elements); + if (!message->elements) { + errno = ENOMEM; + goto failed; + } + + /* + * In typical use, most values are single-valued. This makes + * it quite expensive to allocate an array of ldb_val for each + * of these, just to then hold the pointer to the data buffer. + * So with LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC we allocate this + * ahead of time and use it for the single values where possible. + * (This is used the the normal search case, but not in the + * index case because of caller requirements). + */ + if (flags & LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC) { + ldb_val_single_array = talloc_array(message->elements, + struct ldb_val, + message->num_elements); + if (ldb_val_single_array == NULL) { + errno = ENOMEM; + goto failed; + } + } + + q = p + PULL_LE_U32(p, 0); + value_section_p = q; + p += U32_LEN; + + for (i=0;inum_elements;i++) { + const char *attr = NULL; + size_t attr_len; + struct ldb_message_element *element = NULL; + + /* Sanity check: minimum element size */ + if (p + (U32_LEN * 2) + /* attr name len, num values */ + (U8_LEN * 2) + /* value length width, one val length */ + (NULL_PAD_BYTE_LEN * 2) /* null for attr name + val */ + > value_section_p) { + errno = EIO; + goto failed; + } + + attr_len = PULL_LE_U32(p, 0); + p += U32_LEN; + + if (attr_len == 0) { + errno = EIO; + goto failed; + } + attr = (char *)p; + + p += attr_len + NULL_PAD_BYTE_LEN; + /* + * num_values, val_len_width + * + * val_len_width is the width specifier + * for the variable length encoding + */ + if (p + U32_LEN + U8_LEN > value_section_p) { + errno = EIO; + goto failed; + } + + if (*(p-NULL_PAD_BYTE_LEN) != '\0') { + errno = EINVAL; + goto failed; + } + + element = &message->elements[nelem]; + element->name = attr; + element->flags = 0; + + element->num_values = PULL_LE_U32(p, 0); + element->values = NULL; + if ((flags & LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC) && + element->num_values == 1) { + element->values = &ldb_val_single_array[nelem]; + } else if (element->num_values != 0) { + element->values = talloc_array(message->elements, + struct ldb_val, + element->num_values); + if (!element->values) { + errno = ENOMEM; + goto failed; + } + } + + p += U32_LEN; + + /* + * Here we read how wide the remaining lengths are + * which avoids storing and parsing a lot of leading + * 0s + */ + val_len_width = *p; + p += U8_LEN; + + if (p + val_len_width * element->num_values > + value_section_p) { + errno = EIO; + goto failed; + } + + /* + * This is structured weird for compiler optimization + * purposes, but we need to pull the array of widths + * with different macros depending on how wide the + * biggest one is (specified by val_len_width) + */ + if (val_len_width == U8_LEN) { + for (j = 0; j < element->num_values; j++) { + element->values[j].length = PULL_LE_U8(p, 0); + p += U8_LEN; + } + } else if (val_len_width == U16_LEN) { + for (j = 0; j < element->num_values; j++) { + element->values[j].length = PULL_LE_U16(p, 0); + p += U16_LEN; + } + } else if (val_len_width == U32_LEN) { + for (j = 0; j < element->num_values; j++) { + element->values[j].length = PULL_LE_U32(p, 0); + p += U32_LEN; + } + } else { + errno = ERANGE; + goto failed; + } + + for (j = 0; j < element->num_values; j++) { + len = element->values[j].length; + if (len + NULL_PAD_BYTE_LEN < len) { + errno = EIO; + goto failed; + } + if (q + len + NULL_PAD_BYTE_LEN > end_p) { + errno = EIO; + goto failed; + } + + element->values[j].data = q; + q += len + NULL_PAD_BYTE_LEN; + } + nelem++; + } + + /* + * If p isn't now pointing at the beginning of the value section, + * something went very wrong. + */ + if (p != value_section_p) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: Data corruption in ldb_unpack_data_flags"); + errno = EIO; + goto failed; + } + + /* + * Adapt the number of elements to the real number of unpacked + * elements it means that we overallocated elements array. + */ + message->num_elements = nelem; + + /* + * Shrink the allocated size. On current talloc behaviour + * this will help if we skipped 32 or more attributes. + */ + message->elements = talloc_realloc(message, message->elements, + struct ldb_message_element, + message->num_elements); + + if (q != end_p) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: %zu bytes unread in ldb_unpack_data_flags", + end_p - q); + errno = EIO; + goto failed; + } + + return 0; + +failed: + talloc_free(message->elements); + return -1; +} + +int ldb_unpack_get_format(const struct ldb_val *data, + uint32_t *pack_format_version) +{ + if (data->length < U32_LEN) { + return LDB_ERR_OPERATIONS_ERROR; + } + *pack_format_version = PULL_LE_U32(data->data, 0); + return LDB_SUCCESS; +} + +/* + * Unpack a ldb message from a linear buffer in ldb_val + */ +int ldb_unpack_data_flags(struct ldb_context *ldb, + const struct ldb_val *data, + struct ldb_message *message, + unsigned int flags) +{ + unsigned format; + + if (data->length < U32_LEN) { + errno = EIO; + return -1; + } + + format = PULL_LE_U32(data->data, 0); + if (format == LDB_PACKING_FORMAT_V2) { + return ldb_unpack_data_flags_v2(ldb, data, message, flags); + } + + /* + * The v1 function we're about to call takes either LDB_PACKING_FORMAT + * or LDB_PACKING_FORMAT_NODN packing format versions, and will error + * if given some other version, so we don't need to do any further + * checks on 'format'. + */ + return ldb_unpack_data_flags_v1(ldb, data, message, flags, format); +} + + +/* + * Unpack a ldb message from a linear buffer in ldb_val + * + * Free with ldb_unpack_data_free() + */ +int ldb_unpack_data(struct ldb_context *ldb, + const struct ldb_val *data, + struct ldb_message *message) +{ + return ldb_unpack_data_flags(ldb, data, message, 0); +} + +/* + add the special distinguishedName element +*/ +static int msg_add_distinguished_name(struct ldb_message *msg) +{ + const char *dn_attr = "distinguishedName"; + char *dn = NULL; + + if (ldb_msg_find_element(msg, dn_attr)) { + /* + * This should not happen, but this is + * existing behaviour... + */ + return LDB_SUCCESS; + } + + dn = ldb_dn_alloc_linearized(msg, msg->dn); + if (dn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_msg_add_steal_string(msg, dn_attr, dn); +} + +/* + * filter the specified list of attributes from msg, + * adding requested attributes, and perhaps all for *, + * but not the DN to filtered_msg. + */ +int ldb_filter_attrs(struct ldb_context *ldb, + const struct ldb_message *msg, + const char *const *attrs, + struct ldb_message *filtered_msg) +{ + unsigned int i; + bool keep_all = false; + bool add_dn = false; + uint32_t num_elements; + uint32_t elements_size; + + if (attrs) { + /* check for special attrs */ + for (i = 0; attrs[i]; i++) { + int cmp = strcmp(attrs[i], "*"); + if (cmp == 0) { + keep_all = true; + break; + } + cmp = ldb_attr_cmp(attrs[i], "distinguishedName"); + if (cmp == 0) { + add_dn = true; + } + } + } else { + keep_all = true; + } + + if (keep_all) { + add_dn = true; + elements_size = msg->num_elements + 1; + + /* Shortcuts for the simple cases */ + } else if (add_dn && i == 1) { + if (msg_add_distinguished_name(filtered_msg) != 0) { + goto failed; + } + return 0; + } else if (i == 0) { + return 0; + + /* + * Otherwise we are copying at most as many elements as we + * have attributes + */ + } else { + elements_size = i; + } + + filtered_msg->elements = talloc_array(filtered_msg, + struct ldb_message_element, + elements_size); + if (filtered_msg->elements == NULL) goto failed; + + num_elements = 0; + + for (i = 0; i < msg->num_elements; i++) { + struct ldb_message_element *el = &msg->elements[i]; + + /* + * el2 is assigned after the Pigeonhole principle + * check below for clarity + */ + struct ldb_message_element *el2 = NULL; + unsigned int j; + + if (keep_all == false) { + bool found = false; + for (j = 0; attrs[j]; j++) { + int cmp = ldb_attr_cmp(el->name, attrs[j]); + if (cmp == 0) { + found = true; + break; + } + } + if (found == false) { + continue; + } + } + + /* + * Pigeonhole principle: we can't have more elements + * than the number of attributes if they are unique in + * the DB. + */ + if (num_elements >= elements_size) { + goto failed; + } + + el2 = &filtered_msg->elements[num_elements]; + + *el2 = *el; + el2->name = talloc_strdup(filtered_msg->elements, + el->name); + if (el2->name == NULL) { + goto failed; + } + el2->values = talloc_array(filtered_msg->elements, + struct ldb_val, el->num_values); + if (el2->values == NULL) { + goto failed; + } + for (j=0;jnum_values;j++) { + el2->values[j] = ldb_val_dup(el2->values, &el->values[j]); + if (el2->values[j].data == NULL && el->values[j].length != 0) { + goto failed; + } + } + num_elements++; + } + + filtered_msg->num_elements = num_elements; + + if (add_dn) { + if (msg_add_distinguished_name(filtered_msg) != 0) { + goto failed; + } + } + + if (filtered_msg->num_elements > 0) { + filtered_msg->elements + = talloc_realloc(filtered_msg, + filtered_msg->elements, + struct ldb_message_element, + filtered_msg->num_elements); + if (filtered_msg->elements == NULL) { + goto failed; + } + } else { + TALLOC_FREE(filtered_msg->elements); + } + + return 0; +failed: + TALLOC_FREE(filtered_msg->elements); + return -1; +} diff --git a/ldb-2.0.8/common/ldb_parse.c b/ldb-2.0.8/common/ldb_parse.c new file mode 100644 index 0000000..452c583 --- /dev/null +++ b/ldb-2.0.8/common/ldb_parse.c @@ -0,0 +1,974 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb expression parsing + * + * Description: parse LDAP-like search expressions + * + * Author: Andrew Tridgell + */ + +/* + TODO: + - add RFC2254 binary string handling + - possibly add ~=, <= and >= handling + - expand the test suite + - add better parse error handling + +*/ + +#include "ldb_private.h" +#include "system/locale.h" + +static int ldb_parse_hex2char(const char *x) +{ + if (isxdigit(x[0]) && isxdigit(x[1])) { + const char h1 = x[0], h2 = x[1]; + int c = 0; + + if (h1 >= 'a') c = h1 - (int)'a' + 10; + else if (h1 >= 'A') c = h1 - (int)'A' + 10; + else if (h1 >= '0') c = h1 - (int)'0'; + c = c << 4; + if (h2 >= 'a') c += h2 - (int)'a' + 10; + else if (h2 >= 'A') c += h2 - (int)'A' + 10; + else if (h2 >= '0') c += h2 - (int)'0'; + + return c; + } + + return -1; +} + +/* +a filter is defined by: + ::= '(' ')' + ::= | | | + ::= '&' + ::= '|' + ::= '!' + ::= | + ::= + ::= '=' | '~=' | '<=' | '>=' +*/ + +/* + decode a RFC2254 binary string representation of a buffer. + Used in LDAP filters. +*/ +struct ldb_val ldb_binary_decode(TALLOC_CTX *mem_ctx, const char *str) +{ + size_t i, j; + struct ldb_val ret; + size_t slen = str?strlen(str):0; + + ret.data = (uint8_t *)talloc_size(mem_ctx, slen+1); + ret.length = 0; + if (ret.data == NULL) return ret; + + for (i=j=0;i 0x7E || strchr(" *()\\&|!\"", cval)) { + return true; + } + return false; +} + +/* + encode a blob as a RFC2254 binary string, escaping any + non-printable or '\' characters +*/ +char *ldb_binary_encode(TALLOC_CTX *mem_ctx, struct ldb_val val) +{ + size_t i; + char *ret; + size_t len = val.length; + unsigned char *buf = val.data; + + for (i=0;idata == NULL) return NULL; + + val++; + } + + if (ret != NULL) { + ret[val] = NULL; + } + + return ret; +} + +static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char **s); + + +/* + parse an extended match + + possible forms: + (attr:oid:=value) + (attr:dn:oid:=value) + (attr:dn:=value) + (:dn:oid:=value) + + the ':dn' part sets the dnAttributes boolean if present + the oid sets the rule_id string + +*/ +static struct ldb_parse_tree *ldb_parse_extended(struct ldb_parse_tree *ret, + char *attr, char *value) +{ + char *p1, *p2; + + ret->operation = LDB_OP_EXTENDED; + ret->u.extended.value = ldb_binary_decode(ret, value); + if (ret->u.extended.value.data == NULL) goto failed; + + p1 = strchr(attr, ':'); + if (p1 == NULL) goto failed; + p2 = strchr(p1+1, ':'); + + *p1 = 0; + if (p2) *p2 = 0; + + ret->u.extended.attr = attr; + if (strcmp(p1+1, "dn") == 0) { + ret->u.extended.dnAttributes = 1; + if (p2) { + ret->u.extended.rule_id = talloc_strdup(ret, p2+1); + if (ret->u.extended.rule_id == NULL) goto failed; + } else { + ret->u.extended.rule_id = NULL; + } + } else { + ret->u.extended.dnAttributes = 0; + ret->u.extended.rule_id = talloc_strdup(ret, p1+1); + if (ret->u.extended.rule_id == NULL) goto failed; + } + + return ret; + +failed: + talloc_free(ret); + return NULL; +} + +static enum ldb_parse_op ldb_parse_filtertype(TALLOC_CTX *mem_ctx, char **type, char **value, const char **s) +{ + enum ldb_parse_op filter = 0; + char *name, *val, *k; + const char *p = *s; + const char *t, *t1; + + /* retrieve attributetype name */ + t = p; + + if (*p == '@') { /* for internal attributes the first char can be @ */ + p++; + } + + while ((isascii(*p) && isalnum((unsigned char)*p)) || (*p == '-') || (*p == '.')) { + /* attribute names can only be alphanums */ + p++; + } + + if (*p == ':') { /* but extended searches have : and . chars too */ + p = strstr(p, ":="); + if (p == NULL) { /* malformed attribute name */ + return 0; + } + } + + t1 = p; + + while (isspace((unsigned char)*p)) p++; + + if (!strchr("=<>~:", *p)) { + return 0; + } + + /* save name */ + name = (char *)talloc_memdup(mem_ctx, t, t1 - t + 1); + if (name == NULL) return 0; + name[t1 - t] = '\0'; + + /* retrieve filtertype */ + + if (*p == '=') { + filter = LDB_OP_EQUALITY; + } else if (*p != '\0' && *(p + 1) == '=') { + switch (*p) { + case '<': + filter = LDB_OP_LESS; + p++; + break; + case '>': + filter = LDB_OP_GREATER; + p++; + break; + case '~': + filter = LDB_OP_APPROX; + p++; + break; + case ':': + filter = LDB_OP_EXTENDED; + p++; + break; + } + } + if (!filter) { + talloc_free(name); + return 0; + } + p++; + + while (isspace((unsigned char)*p)) p++; + + /* retrieve value */ + t = p; + + while (*p && ((*p != ')') || ((*p == ')') && (*(p - 1) == '\\')))) p++; + + val = (char *)talloc_memdup(mem_ctx, t, p - t + 1); + if (val == NULL) { + talloc_free(name); + return 0; + } + val[p - t] = '\0'; + + k = &(val[p - t]); + + /* remove trailing spaces from value */ + while ((k > val) && (isspace((unsigned char)*(k - 1)))) k--; + *k = '\0'; + + *type = name; + *value = val; + *s = p; + return filter; +} + +/* + ::= +*/ +static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, const char **s) +{ + char *attr, *value; + struct ldb_parse_tree *ret; + enum ldb_parse_op filtertype; + + ret = talloc_zero(mem_ctx, struct ldb_parse_tree); + if (!ret) { + errno = ENOMEM; + return NULL; + } + + filtertype = ldb_parse_filtertype(ret, &attr, &value, s); + if (!filtertype) { + talloc_free(ret); + return NULL; + } + + switch (filtertype) { + + case LDB_OP_PRESENT: + ret->operation = LDB_OP_PRESENT; + ret->u.present.attr = attr; + break; + + case LDB_OP_EQUALITY: + + if (strcmp(value, "*") == 0) { + ret->operation = LDB_OP_PRESENT; + ret->u.present.attr = attr; + break; + } + + if (ldb_parse_find_wildcard(value) != NULL) { + ret->operation = LDB_OP_SUBSTRING; + ret->u.substring.attr = attr; + ret->u.substring.start_with_wildcard = 0; + ret->u.substring.end_with_wildcard = 0; + ret->u.substring.chunks = ldb_wildcard_decode(ret, value); + if (ret->u.substring.chunks == NULL){ + talloc_free(ret); + return NULL; + } + if (value[0] == '*') + ret->u.substring.start_with_wildcard = 1; + if (value[strlen(value) - 1] == '*') + ret->u.substring.end_with_wildcard = 1; + talloc_free(value); + + break; + } + + ret->operation = LDB_OP_EQUALITY; + ret->u.equality.attr = attr; + ret->u.equality.value = ldb_binary_decode(ret, value); + if (ret->u.equality.value.data == NULL) { + talloc_free(ret); + return NULL; + } + talloc_free(value); + break; + + case LDB_OP_GREATER: + ret->operation = LDB_OP_GREATER; + ret->u.comparison.attr = attr; + ret->u.comparison.value = ldb_binary_decode(ret, value); + if (ret->u.comparison.value.data == NULL) { + talloc_free(ret); + return NULL; + } + talloc_free(value); + break; + + case LDB_OP_LESS: + ret->operation = LDB_OP_LESS; + ret->u.comparison.attr = attr; + ret->u.comparison.value = ldb_binary_decode(ret, value); + if (ret->u.comparison.value.data == NULL) { + talloc_free(ret); + return NULL; + } + talloc_free(value); + break; + + case LDB_OP_APPROX: + ret->operation = LDB_OP_APPROX; + ret->u.comparison.attr = attr; + ret->u.comparison.value = ldb_binary_decode(ret, value); + if (ret->u.comparison.value.data == NULL) { + talloc_free(ret); + return NULL; + } + talloc_free(value); + break; + + case LDB_OP_EXTENDED: + + ret = ldb_parse_extended(ret, attr, value); + break; + + default: + talloc_free(ret); + return NULL; + } + + return ret; +} + + +/* + parse a filterlist + ::= '&' + ::= '|' + ::= | +*/ +static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, const char **s) +{ + struct ldb_parse_tree *ret, *next; + enum ldb_parse_op op; + const char *p = *s; + + switch (*p) { + case '&': + op = LDB_OP_AND; + break; + case '|': + op = LDB_OP_OR; + break; + default: + return NULL; + } + p++; + + while (isspace((unsigned char)*p)) p++; + + ret = talloc(mem_ctx, struct ldb_parse_tree); + if (!ret) { + errno = ENOMEM; + return NULL; + } + + ret->operation = op; + ret->u.list.num_elements = 1; + ret->u.list.elements = talloc(ret, struct ldb_parse_tree *); + if (!ret->u.list.elements) { + errno = ENOMEM; + talloc_free(ret); + return NULL; + } + + ret->u.list.elements[0] = ldb_parse_filter(ret->u.list.elements, &p); + if (!ret->u.list.elements[0]) { + talloc_free(ret); + return NULL; + } + + while (isspace((unsigned char)*p)) p++; + + while (*p) { + struct ldb_parse_tree **e; + if (*p == ')') { + break; + } + + next = ldb_parse_filter(ret->u.list.elements, &p); + if (next == NULL) { + /* an invalid filter element */ + talloc_free(ret); + return NULL; + } + e = talloc_realloc(ret, ret->u.list.elements, + struct ldb_parse_tree *, + ret->u.list.num_elements + 1); + if (!e) { + errno = ENOMEM; + talloc_free(ret); + return NULL; + } + ret->u.list.elements = e; + ret->u.list.elements[ret->u.list.num_elements] = next; + ret->u.list.num_elements++; + while (isspace((unsigned char)*p)) p++; + } + + *s = p; + + return ret; +} + + +/* + ::= '!' +*/ +static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char **s) +{ + struct ldb_parse_tree *ret; + const char *p = *s; + + if (*p != '!') { + return NULL; + } + p++; + + ret = talloc(mem_ctx, struct ldb_parse_tree); + if (!ret) { + errno = ENOMEM; + return NULL; + } + + ret->operation = LDB_OP_NOT; + ret->u.isnot.child = ldb_parse_filter(ret, &p); + if (!ret->u.isnot.child) { + talloc_free(ret); + return NULL; + } + + *s = p; + + return ret; +} + +/* + parse a filtercomp + ::= | | | +*/ +static struct ldb_parse_tree *ldb_parse_filtercomp(TALLOC_CTX *mem_ctx, const char **s) +{ + struct ldb_parse_tree *ret; + const char *p = *s; + + while (isspace((unsigned char)*p)) p++; + + switch (*p) { + case '&': + ret = ldb_parse_filterlist(mem_ctx, &p); + break; + + case '|': + ret = ldb_parse_filterlist(mem_ctx, &p); + break; + + case '!': + ret = ldb_parse_not(mem_ctx, &p); + break; + + case '(': + case ')': + return NULL; + + default: + ret = ldb_parse_simple(mem_ctx, &p); + + } + + *s = p; + return ret; +} + + +/* + ::= '(' ')' +*/ +static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char **s) +{ + struct ldb_parse_tree *ret; + const char *p = *s; + + if (*p != '(') { + return NULL; + } + p++; + + ret = ldb_parse_filtercomp(mem_ctx, &p); + + if (*p != ')') { + return NULL; + } + p++; + + while (isspace((unsigned char)*p)) { + p++; + } + + *s = p; + + return ret; +} + + +/* + main parser entry point. Takes a search string and returns a parse tree + + expression ::= | +*/ +struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s) +{ + while (s && isspace((unsigned char)*s)) s++; + + if (s == NULL || *s == 0) { + s = "(|(objectClass=*)(distinguishedName=*))"; + } + + if (*s == '(') { + return ldb_parse_filter(mem_ctx, &s); + } + + return ldb_parse_simple(mem_ctx, &s); +} + + +/* + construct a ldap parse filter given a parse tree +*/ +char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, const struct ldb_parse_tree *tree) +{ + char *s, *s2, *ret; + unsigned int i; + + if (tree == NULL) { + return NULL; + } + + switch (tree->operation) { + case LDB_OP_AND: + case LDB_OP_OR: + ret = talloc_asprintf(mem_ctx, "(%c", tree->operation==LDB_OP_AND?'&':'|'); + if (ret == NULL) return NULL; + for (i=0;iu.list.num_elements;i++) { + s = ldb_filter_from_tree(mem_ctx, tree->u.list.elements[i]); + if (s == NULL) { + talloc_free(ret); + return NULL; + } + s2 = talloc_asprintf_append(ret, "%s", s); + talloc_free(s); + if (s2 == NULL) { + talloc_free(ret); + return NULL; + } + ret = s2; + } + s = talloc_asprintf_append(ret, ")"); + if (s == NULL) { + talloc_free(ret); + return NULL; + } + return s; + case LDB_OP_NOT: + s = ldb_filter_from_tree(mem_ctx, tree->u.isnot.child); + if (s == NULL) return NULL; + + ret = talloc_asprintf(mem_ctx, "(!%s)", s); + talloc_free(s); + return ret; + case LDB_OP_EQUALITY: + s = ldb_binary_encode(mem_ctx, tree->u.equality.value); + if (s == NULL) return NULL; + ret = talloc_asprintf(mem_ctx, "(%s=%s)", + tree->u.equality.attr, s); + talloc_free(s); + return ret; + case LDB_OP_SUBSTRING: + ret = talloc_asprintf(mem_ctx, "(%s=%s", tree->u.substring.attr, + tree->u.substring.start_with_wildcard?"*":""); + if (ret == NULL) return NULL; + for (i = 0; tree->u.substring.chunks && tree->u.substring.chunks[i]; i++) { + s2 = ldb_binary_encode(mem_ctx, *(tree->u.substring.chunks[i])); + if (s2 == NULL) { + talloc_free(ret); + return NULL; + } + if (tree->u.substring.chunks[i+1] || + tree->u.substring.end_with_wildcard) { + s = talloc_asprintf_append(ret, "%s*", s2); + } else { + s = talloc_asprintf_append(ret, "%s", s2); + } + if (s == NULL) { + talloc_free(ret); + return NULL; + } + ret = s; + } + s = talloc_asprintf_append(ret, ")"); + if (s == NULL) { + talloc_free(ret); + return NULL; + } + ret = s; + return ret; + case LDB_OP_GREATER: + s = ldb_binary_encode(mem_ctx, tree->u.equality.value); + if (s == NULL) return NULL; + ret = talloc_asprintf(mem_ctx, "(%s>=%s)", + tree->u.equality.attr, s); + talloc_free(s); + return ret; + case LDB_OP_LESS: + s = ldb_binary_encode(mem_ctx, tree->u.equality.value); + if (s == NULL) return NULL; + ret = talloc_asprintf(mem_ctx, "(%s<=%s)", + tree->u.equality.attr, s); + talloc_free(s); + return ret; + case LDB_OP_PRESENT: + ret = talloc_asprintf(mem_ctx, "(%s=*)", tree->u.present.attr); + return ret; + case LDB_OP_APPROX: + s = ldb_binary_encode(mem_ctx, tree->u.equality.value); + if (s == NULL) return NULL; + ret = talloc_asprintf(mem_ctx, "(%s~=%s)", + tree->u.equality.attr, s); + talloc_free(s); + return ret; + case LDB_OP_EXTENDED: + s = ldb_binary_encode(mem_ctx, tree->u.extended.value); + if (s == NULL) return NULL; + ret = talloc_asprintf(mem_ctx, "(%s%s%s%s:=%s)", + tree->u.extended.attr?tree->u.extended.attr:"", + tree->u.extended.dnAttributes?":dn":"", + tree->u.extended.rule_id?":":"", + tree->u.extended.rule_id?tree->u.extended.rule_id:"", + s); + talloc_free(s); + return ret; + } + + return NULL; +} + + +/* + walk a parse tree, calling the provided callback on each node +*/ +int ldb_parse_tree_walk(struct ldb_parse_tree *tree, + int (*callback)(struct ldb_parse_tree *tree, void *), + void *private_context) +{ + unsigned int i; + int ret; + + ret = callback(tree, private_context); + if (ret != LDB_SUCCESS) { + return ret; + } + + switch (tree->operation) { + case LDB_OP_AND: + case LDB_OP_OR: + for (i=0;iu.list.num_elements;i++) { + ret = ldb_parse_tree_walk(tree->u.list.elements[i], callback, private_context); + if (ret != LDB_SUCCESS) { + return ret; + } + } + break; + case LDB_OP_NOT: + ret = ldb_parse_tree_walk(tree->u.isnot.child, callback, private_context); + if (ret != LDB_SUCCESS) { + return ret; + } + break; + case LDB_OP_EQUALITY: + case LDB_OP_GREATER: + case LDB_OP_LESS: + case LDB_OP_APPROX: + case LDB_OP_SUBSTRING: + case LDB_OP_PRESENT: + case LDB_OP_EXTENDED: + break; + } + return LDB_SUCCESS; +} + +struct parse_tree_attr_replace_ctx { + const char *attr; + const char *replace; +}; + +/* + callback for ldb_parse_tree_attr_replace() + */ +static int parse_tree_attr_replace(struct ldb_parse_tree *tree, void *private_context) +{ + struct parse_tree_attr_replace_ctx *ctx = private_context; + switch (tree->operation) { + case LDB_OP_EQUALITY: + case LDB_OP_GREATER: + case LDB_OP_LESS: + case LDB_OP_APPROX: + if (ldb_attr_cmp(tree->u.equality.attr, ctx->attr) == 0) { + tree->u.equality.attr = ctx->replace; + } + break; + case LDB_OP_SUBSTRING: + if (ldb_attr_cmp(tree->u.substring.attr, ctx->attr) == 0) { + tree->u.substring.attr = ctx->replace; + } + break; + case LDB_OP_PRESENT: + if (ldb_attr_cmp(tree->u.present.attr, ctx->attr) == 0) { + tree->u.present.attr = ctx->replace; + } + break; + case LDB_OP_EXTENDED: + if (tree->u.extended.attr && + ldb_attr_cmp(tree->u.extended.attr, ctx->attr) == 0) { + tree->u.extended.attr = ctx->replace; + } + break; + default: + break; + } + return LDB_SUCCESS; +} + +/* + replace any occurrences of an attribute name in the parse tree with a + new name +*/ +void ldb_parse_tree_attr_replace(struct ldb_parse_tree *tree, + const char *attr, + const char *replace) +{ + struct parse_tree_attr_replace_ctx ctx; + + ctx.attr = attr; + ctx.replace = replace; + + ldb_parse_tree_walk(tree, parse_tree_attr_replace, &ctx); +} + +/* + shallow copy a tree - copying only the elements array so that the caller + can safely add new elements without changing the message +*/ +struct ldb_parse_tree *ldb_parse_tree_copy_shallow(TALLOC_CTX *mem_ctx, + const struct ldb_parse_tree *ot) +{ + unsigned int i; + struct ldb_parse_tree *nt; + + nt = talloc(mem_ctx, struct ldb_parse_tree); + if (!nt) { + return NULL; + } + + *nt = *ot; + + switch (ot->operation) { + case LDB_OP_AND: + case LDB_OP_OR: + nt->u.list.elements = talloc_array(nt, struct ldb_parse_tree *, + ot->u.list.num_elements); + if (!nt->u.list.elements) { + talloc_free(nt); + return NULL; + } + + for (i=0;iu.list.num_elements;i++) { + nt->u.list.elements[i] = + ldb_parse_tree_copy_shallow(nt->u.list.elements, + ot->u.list.elements[i]); + if (!nt->u.list.elements[i]) { + talloc_free(nt); + return NULL; + } + } + break; + case LDB_OP_NOT: + nt->u.isnot.child = ldb_parse_tree_copy_shallow(nt, + ot->u.isnot.child); + if (!nt->u.isnot.child) { + talloc_free(nt); + return NULL; + } + break; + case LDB_OP_EQUALITY: + case LDB_OP_GREATER: + case LDB_OP_LESS: + case LDB_OP_APPROX: + case LDB_OP_SUBSTRING: + case LDB_OP_PRESENT: + case LDB_OP_EXTENDED: + break; + } + + return nt; +} diff --git a/ldb-2.0.8/common/ldb_utf8.c b/ldb-2.0.8/common/ldb_utf8.c new file mode 100644 index 0000000..55d8f90 --- /dev/null +++ b/ldb-2.0.8/common/ldb_utf8.c @@ -0,0 +1,136 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb utf8 handling + * + * Description: case folding and case comparison for UTF8 strings + * + * Author: Andrew Tridgell + */ + +#include "ldb_private.h" +#include "system/locale.h" + + +/* + this allow the user to pass in a caseless comparison + function to handle utf8 caseless comparisons + */ +void ldb_set_utf8_fns(struct ldb_context *ldb, + void *context, + char *(*casefold)(void *, void *, const char *, size_t)) +{ + if (context) + ldb->utf8_fns.context = context; + if (casefold) + ldb->utf8_fns.casefold = casefold; +} + +/* + a simple case folding function + NOTE: does not handle UTF8 +*/ +char *ldb_casefold_default(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n) +{ + size_t i; + char *ret = talloc_strndup(mem_ctx, s, n); + if (!s) { + errno = ENOMEM; + return NULL; + } + for (i=0;ret[i];i++) { + ret[i] = toupper((unsigned char)ret[i]); + } + return ret; +} + +void ldb_set_utf8_default(struct ldb_context *ldb) +{ + ldb_set_utf8_fns(ldb, NULL, ldb_casefold_default); +} + +char *ldb_casefold(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *s, size_t n) +{ + return ldb->utf8_fns.casefold(ldb->utf8_fns.context, mem_ctx, s, n); +} + +/* + check the attribute name is valid according to rfc2251 + returns 1 if the name is ok + */ + +int ldb_valid_attr_name(const char *s) +{ + size_t i; + + if (!s || !s[0]) + return 0; + + /* handle special ldb_tdb wildcard */ + if (strcmp(s, "*") == 0) return 1; + + for (i = 0; s[i]; i++) { + if (! isascii(s[i])) { + return 0; + } + if (i == 0) { /* first char must be an alpha (or our special '@' identifier) */ + if (! (isalpha(s[i]) || (s[i] == '@'))) { + return 0; + } + } else { + if (! (isalnum(s[i]) || (s[i] == '-'))) { + return 0; + } + } + } + return 1; +} + +char *ldb_attr_casefold(TALLOC_CTX *mem_ctx, const char *s) +{ + size_t i; + char *ret = talloc_strdup(mem_ctx, s); + if (!ret) { + errno = ENOMEM; + return NULL; + } + for (i = 0; ret[i]; i++) { + ret[i] = toupper((unsigned char)ret[i]); + } + return ret; +} + +/* + we accept either 'dn' or 'distinguishedName' for a distinguishedName +*/ +int ldb_attr_dn(const char *attr) +{ + if (ldb_attr_cmp(attr, "dn") == 0 || + ldb_attr_cmp(attr, "distinguishedName") == 0) { + return 0; + } + return -1; +} diff --git a/ldb-2.0.8/common/qsort.c b/ldb-2.0.8/common/qsort.c new file mode 100644 index 0000000..012aaf3 --- /dev/null +++ b/ldb-2.0.8/common/qsort.c @@ -0,0 +1,251 @@ +/* Copyright (C) 1991,1992,1996,1997,1999,2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Douglas C. Schmidt (schmidt@ics.uci.edu). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see . */ + +/* If you consider tuning this algorithm, you should consult first: + Engineering a sort function; Jon Bentley and M. Douglas McIlroy; + Software - Practice and Experience; Vol. 23 (11), 1249-1265, 1993. */ + +/* Modified to be used in samba4 by + * Simo Sorce 2005 + */ + +#include "ldb_private.h" + +/* Byte-wise swap two items of size SIZE. */ +#define SWAP(a, b, size) \ + do \ + { \ + register size_t __size = (size); \ + register char *__a = (a), *__b = (b); \ + do \ + { \ + char __tmp = *__a; \ + *__a++ = *__b; \ + *__b++ = __tmp; \ + } while (--__size > 0); \ + } while (0) + +/* Discontinue quicksort algorithm when partition gets below this size. + This particular magic number was chosen to work best on a Sun 4/260. */ +#define MAX_THRESH 4 + +/* Stack node declarations used to store unfulfilled partition obligations. */ +typedef struct + { + char *lo; + char *hi; + } stack_node; + +/* The next 4 #defines implement a very fast in-line stack abstraction. */ +/* The stack needs log (total_elements) entries (we could even subtract + log(MAX_THRESH)). Since total_elements has type size_t, we get as + upper bound for log (total_elements): + bits per byte (CHAR_BIT) * sizeof(size_t). */ +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif +#define STACK_SIZE (CHAR_BIT * sizeof(size_t)) +#define PUSH(low, high) ((void) ((stack[i].lo = (low)), (stack[i].hi = (high)), i++)) +#define POP(low, high) ((void) (i--, (low = stack[i].lo), (high = stack[i].hi))) + + +/* Order size using quicksort. This implementation incorporates + four optimizations discussed in Sedgewick: + + 1. Non-recursive, using an explicit stack of pointer that store the + next array partition to sort. To save time, this maximum amount + of space required to store an array of SIZE_MAX is allocated on the + stack. Assuming a 32-bit (64 bit) integer for size_t, this needs + only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes). + Pretty cheap, actually. + + 2. Chose the pivot element using a median-of-three decision tree. + This reduces the probability of selecting a bad pivot value and + eliminates certain extraneous comparisons. + + 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving + insertion sort to order the MAX_THRESH items within each partition. + This is a big win, since insertion sort is faster for small, mostly + sorted array segments. + + 4. The larger of the two sub-partitions is always pushed onto the + stack first, with the algorithm then concentrating on the + smaller partition. This *guarantees* no more than log (total_elems) + stack size is needed (actually O(1) in this case)! */ + +void ldb_qsort (void *const pbase, size_t total_elems, size_t size, + void *opaque, ldb_qsort_cmp_fn_t cmp) +{ + register char *base_ptr = (char *) pbase; + + const size_t max_thresh = MAX_THRESH * size; + + if (total_elems == 0) + /* Avoid lossage with unsigned arithmetic below. */ + return; + + if (total_elems > MAX_THRESH) + { + char *lo = base_ptr; + char *hi = &lo[size * (total_elems - 1)]; + stack_node stack[STACK_SIZE]; + size_t i = 0; + + PUSH (NULL, NULL); + + do + { + char *left_ptr; + char *right_ptr; + + /* Select median value from among LO, MID, and HI. Rearrange + LO and HI so the three values are sorted. This lowers the + probability of picking a pathological pivot value and + skips a comparison for both the LEFT_PTR and RIGHT_PTR in + the while loops. */ + + char *mid = lo + size * ((hi - lo) / size >> 1); + + if ((*cmp) ((void *) mid, (void *) lo, opaque) < 0) + SWAP (mid, lo, size); + if ((*cmp) ((void *) hi, (void *) mid, opaque) < 0) + SWAP (mid, hi, size); + else + goto jump_over; + if ((*cmp) ((void *) mid, (void *) lo, opaque) < 0) + SWAP (mid, lo, size); + jump_over:; + + left_ptr = lo + size; + right_ptr = hi - size; + + /* Here's the famous ``collapse the walls'' section of quicksort. + Gotta like those tight inner loops! They are the main reason + that this algorithm runs much faster than others. */ + do + { + while ((*cmp) ((void *) left_ptr, (void *) mid, opaque) < 0) + left_ptr += size; + + while ((*cmp) ((void *) mid, (void *) right_ptr, opaque) < 0) + right_ptr -= size; + + if (left_ptr < right_ptr) + { + SWAP (left_ptr, right_ptr, size); + if (mid == left_ptr) + mid = right_ptr; + else if (mid == right_ptr) + mid = left_ptr; + left_ptr += size; + right_ptr -= size; + } + else if (left_ptr == right_ptr) + { + left_ptr += size; + right_ptr -= size; + break; + } + } + while (left_ptr <= right_ptr); + + /* Set up pointers for next iteration. First determine whether + left and right partitions are below the threshold size. If so, + ignore one or both. Otherwise, push the larger partition's + bounds on the stack and continue sorting the smaller one. */ + + if ((size_t) (right_ptr - lo) <= max_thresh) + { + if ((size_t) (hi - left_ptr) <= max_thresh) + /* Ignore both small partitions. */ + POP (lo, hi); + else + /* Ignore small left partition. */ + lo = left_ptr; + } + else if ((size_t) (hi - left_ptr) <= max_thresh) + /* Ignore small right partition. */ + hi = right_ptr; + else if ((right_ptr - lo) > (hi - left_ptr)) + { + /* Push larger left partition indices. */ + PUSH (lo, right_ptr); + lo = left_ptr; + } + else + { + /* Push larger right partition indices. */ + PUSH (left_ptr, hi); + hi = right_ptr; + } + } + while (i > 0 && i < STACK_SIZE); + } + + /* Once the BASE_PTR array is partially sorted by quicksort the rest + is completely sorted using insertion sort, since this is efficient + for partitions below MAX_THRESH size. BASE_PTR points to the beginning + of the array to sort, and END_PTR points at the very last element in + the array (*not* one beyond it!). */ + +#define min(x, y) ((x) < (y) ? (x) : (y)) + + { + char *const end_ptr = &base_ptr[size * (total_elems - 1)]; + char *tmp_ptr = base_ptr; + char *thresh = min(end_ptr, base_ptr + max_thresh); + register char *run_ptr; + + /* Find smallest element in first threshold and place it at the + array's beginning. This is the smallest array element, + and the operation speeds up insertion sort's inner loop. */ + + for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size) + if ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, opaque) < 0) + tmp_ptr = run_ptr; + + if (tmp_ptr != base_ptr) + SWAP (tmp_ptr, base_ptr, size); + + /* Insertion sort, running from left-hand-side up to right-hand-side. */ + + run_ptr = base_ptr + size; + while ((run_ptr += size) <= end_ptr) + { + tmp_ptr = run_ptr - size; + while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, opaque) < 0) + tmp_ptr -= size; + + tmp_ptr += size; + if (tmp_ptr != run_ptr) + { + char *trav; + + trav = run_ptr + size; + while (--trav >= run_ptr) + { + char c = *trav; + char *hi, *lo; + + for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo) + *hi = *lo; + *hi = c; + } + } + } + } +} diff --git a/ldb-2.0.8/configure b/ldb-2.0.8/configure new file mode 100755 index 0000000..6c931bf --- /dev/null +++ b/ldb-2.0.8/configure @@ -0,0 +1,21 @@ +#!/bin/sh + +PREVPATH=`dirname $0` + +if [ -f $PREVPATH/../../buildtools/bin/waf ]; then + WAF=../../buildtools/bin/waf +elif [ -f $PREVPATH/buildtools/bin/waf ]; then + WAF=./buildtools/bin/waf +else + echo "ldb: Unable to find waf" + exit 1 +fi + +# using JOBS=1 gives maximum compatibility with +# systems like AIX which have broken threading in python +JOBS=1 +export JOBS + +cd . || exit 1 +$PYTHON $WAF configure "$@" || exit 1 +cd $PREVPATH diff --git a/ldb-2.0.8/docs/builddocs.sh b/ldb-2.0.8/docs/builddocs.sh new file mode 100755 index 0000000..449dcb2 --- /dev/null +++ b/ldb-2.0.8/docs/builddocs.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# build ldb docs +# tridge@samba.org August 2006 + +XSLTPROC="$1" +SRCDIR="$2" + +if [ -z "$XSLTPROC" ] || [ ! -x "$XSLTPROC" ]; then + echo "xsltproc not installed" + exit 0 +fi + +MANXSL="http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl" +HTMLXSL="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl" + +mkdir -p man + +for f in $SRCDIR/man/*.xml; do + base=`basename $f .xml` + out=man/"`basename $base`" + if [ ! -f "$out" ] || [ "$f" -nt "$out" ]; then + echo Processing manpage $f + $XSLTPROC --nonet -o "$out" "$MANXSL" $f + ret=$? + if [ "$ret" = "4" ]; then + echo "ignoring stylesheet error 4 for $MANXSL" + exit 0 + fi + if [ "$ret" != "0" ]; then + echo "xsltproc failed with error $ret" + exit $ret + fi + fi +done + +for f in $SRCDIR/man/*.xml; do + base=`basename $f .xml` + out=man/"`basename $base`".html + if [ ! -f "$out" ] || [ "$f" -nt "$out" ]; then + echo Processing html $f + $XSLTPROC --nonet -o "$out" "$HTMLXSL" $f + ret=$? + if [ "$ret" = "4" ]; then + echo "ignoring stylesheet error 4 for $HTMLXSL" + exit 0 + fi + if [ "$ret" != "0" ]; then + echo "xsltproc failed with error $ret" + exit $ret + fi + fi +done diff --git a/ldb-2.0.8/docs/design.txt b/ldb-2.0.8/docs/design.txt new file mode 100644 index 0000000..0bb278b --- /dev/null +++ b/ldb-2.0.8/docs/design.txt @@ -0,0 +1,41 @@ +The list of indexed fields +-------------------------- + +dn=@INDEXLIST + list of field names that are indexed + + contains fields of type @IDXATTR which contain attriute names + of indexed fields + + +Data records +------------ + +for each user record in the db there is: + main record + key: DN=dn + data: packed attribute/value list + + a index record for each indexed field in the record + + +Index Records +------------- + +The index records contain the list of dn's that contain records +matching the index key + +All index records are of the form: + dn=@INDEX:field:value + +and contain fields of type @IDX which are the dns of the records +that have that value for some attribute + + +Search Expressions +------------------ + +Very similar to LDAP search expressions, but does not allow ~=, <= or >= + + attrib0 := (field=value) + attrib := attrib0 | (attrib&&attrib) | (attrib||attrib) | !attrib diff --git a/ldb-2.0.8/docs/installdocs.sh b/ldb-2.0.8/docs/installdocs.sh new file mode 100755 index 0000000..6cc7b74 --- /dev/null +++ b/ldb-2.0.8/docs/installdocs.sh @@ -0,0 +1,17 @@ +#!/bin/sh +# install ldb docs +# tridge@samba.org August 2006 + +MANDIR="$1" + +MAN1="`/bin/ls man/*.1`" +MAN3="`/bin/ls man/*.3`" + +if [ -z "$MAN1" ] && [ -z "$MAN3" ]; then + echo "No manpages have been built" + exit 0 +fi + +mkdir -p "$MANDIR/man1" "$MANDIR/man3" +cp $MAN1 "$MANDIR/man1/" || exit 1 +cp $MAN3 "$MANDIR/man3/" || exit 1 diff --git a/ldb-2.0.8/examples.dox b/ldb-2.0.8/examples.dox new file mode 100644 index 0000000..ef4b4f0 --- /dev/null +++ b/ldb-2.0.8/examples.dox @@ -0,0 +1,16 @@ +/** \example ldbreader.c + +The code below shows a simple LDB application. + +It lists / dumps the records in a LDB database to standard output. + +*/ + + +/** \example ldifreader.c + +The code below shows a simple LDB application. + +It lists / dumps the entries in an LDIF file to standard output. + +*/ diff --git a/ldb-2.0.8/examples/ldbreader.c b/ldb-2.0.8/examples/ldbreader.c new file mode 100644 index 0000000..3496baf --- /dev/null +++ b/ldb-2.0.8/examples/ldbreader.c @@ -0,0 +1,122 @@ +/* + example code for the ldb database library + + Copyright (C) Brad Hards (bradh@frogmouth.net) 2005-2006 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/** \example ldbreader.c + +The code below shows a simple LDB application. + +It lists / dumps the records in a LDB database to standard output. + +*/ + +#include "ldb.h" + +/* + ldb_ldif_write takes a function pointer to a custom output + function. This version is about as simple as the output function can + be. In a more complex example, you'd likely be doing something with + the private data function (e.g. holding a file handle). +*/ +static int vprintf_fn(void *private_data, const char *fmt, ...) +{ + int retval; + va_list ap; + + va_start(ap, fmt); + /* We just write to standard output */ + retval = vprintf(fmt, ap); + va_end(ap); + /* Note that the function should return the number of + bytes written, or a negative error code */ + return retval; +} + +int main(int argc, const char **argv) +{ + struct ldb_context *ldb; + const char *expression = "(dn=*)"; + struct ldb_result *resultMsg; + int i; + + /* + This is the always the first thing you want to do in an LDB + application - initialise up the context structure. + + Note that you can use the context structure as a parent + for talloc allocations as well + */ + ldb = ldb_init(NULL, NULL); + + /* + We now open the database. In this example we just hard code the connection path. + + Also note that the database is being opened read-only. This means that the + call will fail unless the database already exists. + */ + if (LDB_SUCCESS != ldb_connect(ldb, "tdb://tdbtest.ldb", LDB_FLG_RDONLY, NULL) ){ + printf("Problem on connection\n"); + exit(-1); + } + + /* + At this stage we have an open database, and can start using it. It is opened + read-only, so a query is possible. + + We construct a search that just returns all the (sensible) contents. You can do + quite fine grained results with the LDAP search syntax, however it is a bit + confusing to start with. See RFC2254. + */ + if (LDB_SUCCESS != ldb_search(ldb, ldb, &resultMsg, + NULL, LDB_SCOPE_DEFAULT, NULL, + "%s", expression)) { + printf("Problem in search\n"); + exit(-1); + } + + printf("%i records returned\n", resultMsg->count); + + /* + We can now iterate through the results, writing them out + (to standard output) with our custom output routine as defined + at the top of this file + */ + for (i = 0; i < resultMsg->count; ++i) { + struct ldb_ldif ldifMsg; + + printf("Message: %i\n", i+1); + + ldifMsg.changetype = LDB_CHANGETYPE_NONE; + ldifMsg.msg = resultMsg->msgs[i]; + ldb_ldif_write(ldb, vprintf_fn, NULL, &ldifMsg); + } + + /* + There are two objects to clean up - the result from the + ldb_search() query, and the original ldb context. + */ + talloc_free(resultMsg); + + talloc_free(ldb); + + return 0; +} diff --git a/ldb-2.0.8/examples/ldifreader.c b/ldb-2.0.8/examples/ldifreader.c new file mode 100644 index 0000000..dcd9daf --- /dev/null +++ b/ldb-2.0.8/examples/ldifreader.c @@ -0,0 +1,125 @@ +/* + example code for the ldb database library + + Copyright (C) Brad Hards (bradh@frogmouth.net) 2005-2006 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/** \example ldifreader.c + +The code below shows a simple LDB application. + +It lists / dumps the entries in an LDIF file to standard output. + +*/ + +#include "ldb.h" + +/* + ldb_ldif_write takes a function pointer to a custom output + function. This version is about as simple as the output function can + be. In a more complex example, you'd likely be doing something with + the private data function (e.g. holding a file handle). +*/ +static int vprintf_fn(void *private_data, const char *fmt, ...) +{ + int retval; + va_list ap; + + va_start(ap, fmt); + /* We just write to standard output */ + retval = vprintf(fmt, ap); + va_end(ap); + /* Note that the function should return the number of + bytes written, or a negative error code */ + return retval; +} + +int main(int argc, const char **argv) +{ + struct ldb_context *ldb; + FILE *fileStream; + struct ldb_ldif *ldifMsg; + + if (argc != 2) { + printf("Usage %s filename.ldif\n", argv[0]); + exit(1); + } + + /* + This is the always the first thing you want to do in an LDB + application - initialise up the context structure. + + Note that you can use the context structure as a parent + for talloc allocations as well + */ + ldb = ldb_init(NULL, NULL); + + fileStream = fopen(argv[1], "r"); + if (0 == fileStream) { + perror(argv[1]); + exit(1); + } + + /* + We now work through the filestream to get each entry. + */ + while ( (ldifMsg = ldb_ldif_read_file(ldb, fileStream)) ) { + /* + Each message has a particular change type. For Add, + Modify and Delete, this will also appear in the + output listing (as changetype: add, changetype: + modify or changetype:delete, respectively). + */ + switch (ldifMsg->changetype) { + case LDB_CHANGETYPE_NONE: + printf("ChangeType: None\n"); + break; + case LDB_CHANGETYPE_ADD: + printf("ChangeType: Add\n"); + break; + case LDB_CHANGETYPE_MODIFY: + printf("ChangeType: Modify\n"); + break; + case LDB_CHANGETYPE_DELETE: + printf("ChangeType: Delete\n"); + break; + default: + printf("ChangeType: Unknown\n"); + } + + /* + We can now write out the results, using our custom + output routine as defined at the top of this file. + */ + ldb_ldif_write(ldb, vprintf_fn, NULL, ldifMsg); + + /* + Clean up the message + */ + ldb_ldif_read_free(ldb, ldifMsg); + } + + /* + Clean up the context + */ + talloc_free(ldb); + + return 0; +} diff --git a/ldb-2.0.8/include/dlinklist.h b/ldb-2.0.8/include/dlinklist.h new file mode 100644 index 0000000..822a826 --- /dev/null +++ b/ldb-2.0.8/include/dlinklist.h @@ -0,0 +1,178 @@ +/* + Unix SMB/CIFS implementation. + some simple double linked list macros + + Copyright (C) Andrew Tridgell 1998-2010 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* To use these macros you must have a structure containing a next and + prev pointer */ + +#ifndef _DLINKLIST_H +#define _DLINKLIST_H + +/* + February 2010 - changed list format to have a prev pointer from the + list head. This makes DLIST_ADD_END() O(1) even though we only have + one list pointer. + + The scheme is as follows: + + 1) with no entries in the list: + list_head == NULL + + 2) with 1 entry in the list: + list_head->next == NULL + list_head->prev == list_head + + 3) with 2 entries in the list: + list_head->next == element2 + list_head->prev == element2 + element2->prev == list_head + element2->next == NULL + + 4) with N entries in the list: + list_head->next == element2 + list_head->prev == elementN + elementN->prev == element{N-1} + elementN->next == NULL + + This allows us to find the tail of the list by using + list_head->prev, which means we can add to the end of the list in + O(1) time + */ + + +/* + add an element at the front of a list +*/ +#define DLIST_ADD(list, p) \ +do { \ + if (!(list)) { \ + (p)->prev = (list) = (p); \ + (p)->next = NULL; \ + } else { \ + (p)->prev = (list)->prev; \ + (list)->prev = (p); \ + (p)->next = (list); \ + (list) = (p); \ + } \ +} while (0) + +/* + remove an element from a list + Note that the element doesn't have to be in the list. If it + isn't then this is a no-op +*/ +#define DLIST_REMOVE(list, p) \ +do { \ + if ((p) == (list)) { \ + if ((p)->next) (p)->next->prev = (p)->prev; \ + (list) = (p)->next; \ + } else if ((p)->prev && (list) && (p) == (list)->prev) { \ + (p)->prev->next = NULL; \ + (list)->prev = (p)->prev; \ + } else { \ + if ((p)->prev) (p)->prev->next = (p)->next; \ + if ((p)->next) (p)->next->prev = (p)->prev; \ + } \ + if ((p) != (list)) (p)->next = (p)->prev = NULL; \ +} while (0) + +/* + find the head of the list given any element in it. + Note that this costs O(N), so you should avoid this macro + if at all possible! +*/ +#define DLIST_HEAD(p, result_head) \ +do { \ + (result_head) = (p); \ + while (DLIST_PREV(result_head)) (result_head) = (result_head)->prev; \ +} while(0) + +/* return the last element in the list */ +#define DLIST_TAIL(list) ((list)?(list)->prev:NULL) + +/* return the previous element in the list. */ +#define DLIST_PREV(p) (((p)->prev && (p)->prev->next != NULL)?(p)->prev:NULL) + +/* insert 'p' after the given element 'el' in a list. If el is NULL then + this is the same as a DLIST_ADD() */ +#define DLIST_ADD_AFTER(list, p, el) \ +do { \ + if (!(list) || !(el)) { \ + DLIST_ADD(list, p); \ + } else { \ + (p)->prev = (el); \ + (p)->next = (el)->next; \ + (el)->next = (p); \ + if ((p)->next) (p)->next->prev = (p); \ + if ((list)->prev == (el)) (list)->prev = (p); \ + }\ +} while (0) + + +/* + add to the end of a list. +*/ +#define DLIST_ADD_END(list, p) \ +do { \ + if (!(list)) { \ + DLIST_ADD(list, p); \ + } else { \ + DLIST_ADD_AFTER(list, p, (list)->prev); \ + } \ +} while (0) + +/* promote an element to the front of a list */ +#define DLIST_PROMOTE(list, p) \ +do { \ + DLIST_REMOVE(list, p); \ + DLIST_ADD(list, p); \ +} while (0) + +/* + demote an element to the end of a list. +*/ +#define DLIST_DEMOTE(list, p) \ +do { \ + DLIST_REMOVE(list, p); \ + DLIST_ADD_END(list, p); \ +} while (0) + +/* + concatenate two lists - putting all elements of the 2nd list at the + end of the first list. +*/ +#define DLIST_CONCATENATE(list1, list2) \ +do { \ + if (!(list1)) { \ + (list1) = (list2); \ + } else { \ + (list1)->prev->next = (list2); \ + if (list2) { \ + void *_tmplist = (void *)(list1)->prev; \ + (list1)->prev = (list2)->prev; \ + (list2)->prev = _tmplist; \ + } \ + } \ +} while (0) + +#endif /* _DLINKLIST_H */ diff --git a/ldb-2.0.8/include/ldb.h b/ldb-2.0.8/include/ldb.h new file mode 100644 index 0000000..3cba0f4 --- /dev/null +++ b/ldb-2.0.8/include/ldb.h @@ -0,0 +1,2365 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 2005-2006 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb header + * + * Description: defines for base ldb API + * + * Author: Andrew Tridgell + * Author: Stefan Metzmacher + */ + +/** + \file ldb.h Samba's ldb database + + This header file provides the main API for ldb. +*/ + +#ifndef _LDB_H_ + +/*! \cond DOXYGEN_IGNORE */ +#define _LDB_H_ 1 +/*! \endcond */ + +#include +#include +#include +#include +#include + +/* + major restrictions as compared to normal LDAP: + + - each record must have a unique key field + - the key must be representable as a NULL terminated C string and may not + contain a comma or braces + + major restrictions as compared to tdb: + + - no explicit locking calls, but we have transactions when using ldb_tdb + +*/ + +#ifndef ldb_val +/** + Result value + + An individual lump of data in a result comes in this format. The + pointer will usually be to a UTF-8 string if the application is + sensible, but it can be to anything you like, including binary data + blobs of arbitrary size. + + \note the data is null (0x00) terminated, but the length does not + include the terminator. +*/ +struct ldb_val { + uint8_t *data; /*!< result data */ + size_t length; /*!< length of data */ +}; +#endif + +/*! \cond DOXYGEN_IGNORE */ +#ifndef PRINTF_ATTRIBUTE +#define PRINTF_ATTRIBUTE(a,b) +#endif + +#ifndef _DEPRECATED_ +#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) +#define _DEPRECATED_ __attribute__ ((deprecated)) +#else +#define _DEPRECATED_ +#endif +#endif +/*! \endcond */ + +/* opaque ldb_dn structures, see ldb_dn.c for internals */ +struct ldb_dn_component; +struct ldb_dn; + +/** + There are a number of flags that are used with ldap_modify() in + ldb_message_element.flags fields. The LDB_FLAG_MOD_ADD, + LDB_FLAG_MOD_DELETE and LDB_FLAG_MOD_REPLACE are better thought of as + an enumeration, not flags, and are used in ldap_modify() calls to + specify whether attributes are being added, deleted or modified + respectively. +*/ +#define LDB_FLAG_MOD_MASK 0x3 + +/** + use this to extract the mod type (enum) from the operation + */ +#define LDB_FLAG_MOD_TYPE(flags) ((flags) & LDB_FLAG_MOD_MASK) + +/** + Value used in ldap_modify() to indicate that attributes are + being added. + + \sa LDB_FLAG_MOD_MASK +*/ +#define LDB_FLAG_MOD_ADD 1 + +/** + Value used in ldap_modify() to indicate that attributes are + being replaced. + + \sa LDB_FLAG_MOD_MASK +*/ +#define LDB_FLAG_MOD_REPLACE 2 + +/** + Value used in ldap_modify() to indicate that attributes are + being deleted. + + \sa LDB_FLAG_MOD_MASK +*/ +#define LDB_FLAG_MOD_DELETE 3 + +/** + Flag value used in ldb_ldif_write_trace() to enforce binary encoded + attribute values per attribute. + + This is a genuine flag, being outside LDB_FLAG_MOD_MASK and also + outside LDB_FLAG_INTERNAL_MASK +*/ +#define LDB_FLAG_FORCE_NO_BASE64_LDIF 4 + +/** + flag bits on an element usable only by the internal implementation +*/ +#define LDB_FLAG_INTERNAL_MASK 0xFFFFFFF0 + +/** + OID for logic AND comaprison. + + This is the well known object ID for a logical AND comparitor. +*/ +#define LDB_OID_COMPARATOR_AND "1.2.840.113556.1.4.803" + +/** + OID for logic OR comparison. + + This is the well known object ID for a logical OR comparitor. +*/ +#define LDB_OID_COMPARATOR_OR "1.2.840.113556.1.4.804" + +/** + results are given back as arrays of ldb_message_element +*/ +struct ldb_message_element { + unsigned int flags; + const char *name; + unsigned int num_values; + struct ldb_val *values; +}; + + +/** + a ldb_message represents all or part of a record. It can contain an arbitrary + number of elements. +*/ +struct ldb_message { + struct ldb_dn *dn; + unsigned int num_elements; + struct ldb_message_element *elements; +}; + +enum ldb_changetype { + LDB_CHANGETYPE_NONE=0, + LDB_CHANGETYPE_ADD, + LDB_CHANGETYPE_DELETE, + LDB_CHANGETYPE_MODIFY, + LDB_CHANGETYPE_MODRDN +}; + +/** + LDIF record + + This structure contains a LDIF record, as returned from ldif_read() + and equivalent functions. +*/ +struct ldb_ldif { + enum ldb_changetype changetype; /*!< The type of change */ + struct ldb_message *msg; /*!< The changes */ +}; + +enum ldb_scope {LDB_SCOPE_DEFAULT=-1, + LDB_SCOPE_BASE=0, + LDB_SCOPE_ONELEVEL=1, + LDB_SCOPE_SUBTREE=2}; + +struct ldb_context; +struct tevent_context; + +/* debugging uses one of the following levels */ +enum ldb_debug_level {LDB_DEBUG_FATAL, LDB_DEBUG_ERROR, + LDB_DEBUG_WARNING, LDB_DEBUG_TRACE}; + +/* alias for something that's not a fatal error but we really want to log */ +#define LDB_DEBUG_ALWAYS_LOG LDB_DEBUG_FATAL + +/** + the user can optionally supply a debug function. The function + is based on the vfprintf() style of interface, but with the addition + of a severity level +*/ +struct ldb_debug_ops { + void (*debug)(void *context, enum ldb_debug_level level, + const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); + void *context; +}; + +/** + The user can optionally supply a custom utf8 functions, + to handle comparisons and casefolding. +*/ +struct ldb_utf8_fns { + void *context; + char *(*casefold)(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n); +}; + +/** + Flag value for database connection mode. + + If LDB_FLG_RDONLY is used in ldb_connect, then the database will be + opened read-only, if possible. +*/ +#define LDB_FLG_RDONLY 1 + +/** + Flag value for database connection mode. + + If LDB_FLG_NOSYNC is used in ldb_connect, then the database will be + opened without synchronous operations, if possible. +*/ +#define LDB_FLG_NOSYNC 2 + +/** + Flag value to specify autoreconnect mode. + + If LDB_FLG_RECONNECT is used in ldb_connect, then the backend will + be opened in a way that makes it try to auto reconnect if the + connection is dropped (actually make sense only with ldap). +*/ +#define LDB_FLG_RECONNECT 4 + +/** + Flag to tell backends not to use mmap +*/ +#define LDB_FLG_NOMMAP 8 + +/** + Flag to tell ldif handlers not to force encoding of binary + structures in base64 +*/ +#define LDB_FLG_SHOW_BINARY 16 + +/** + Flags to enable ldb tracing +*/ +#define LDB_FLG_ENABLE_TRACING 32 + +/** + Flags to tell LDB not to create a new database file: + + Without this flag ldb_tdb (for example) will create a blank file + during an invocation of ldb_connect(), even when the caller only + wanted read operations, for example in ldbsearch. +*/ +#define LDB_FLG_DONT_CREATE_DB 64 + +/* + structures for ldb_parse_tree handling code +*/ +enum ldb_parse_op { LDB_OP_AND=1, LDB_OP_OR=2, LDB_OP_NOT=3, + LDB_OP_EQUALITY=4, LDB_OP_SUBSTRING=5, + LDB_OP_GREATER=6, LDB_OP_LESS=7, LDB_OP_PRESENT=8, + LDB_OP_APPROX=9, LDB_OP_EXTENDED=10 }; + +struct ldb_parse_tree { + enum ldb_parse_op operation; + union { + struct { + struct ldb_parse_tree *child; + } isnot; + struct { + const char *attr; + struct ldb_val value; + } equality; + struct { + const char *attr; + int start_with_wildcard; + int end_with_wildcard; + struct ldb_val **chunks; + } substring; + struct { + const char *attr; + } present; + struct { + const char *attr; + struct ldb_val value; + } comparison; + struct { + const char *attr; + int dnAttributes; + const char *rule_id; + struct ldb_val value; + } extended; + struct { + unsigned int num_elements; + struct ldb_parse_tree **elements; + } list; + } u; +}; + +struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s); +char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, const struct ldb_parse_tree *tree); + +/** + Encode a binary blob + + This function encodes a binary blob using the encoding rules in RFC + 2254 (Section 4). This function also escapes any non-printable + characters. + + \param mem_ctx the memory context to allocate the return string in. + \param val the (potentially) binary data to be encoded + + \return the encoded data as a null terminated string + + \sa RFC 2252. +*/ +char *ldb_binary_encode(TALLOC_CTX *mem_ctx, struct ldb_val val); + +/** + Encode a string + + This function encodes a string using the encoding rules in RFC 2254 + (Section 4). This function also escapes any non-printable + characters. + + \param mem_ctx the memory context to allocate the return string in. + \param string the string to be encoded + + \return the encoded data as a null terminated string + + \sa RFC 2252. +*/ +char *ldb_binary_encode_string(TALLOC_CTX *mem_ctx, const char *string); + +/* + functions for controlling attribute handling +*/ +typedef int (*ldb_attr_handler_t)(struct ldb_context *, TALLOC_CTX *mem_ctx, const struct ldb_val *, struct ldb_val *); +typedef int (*ldb_attr_comparison_t)(struct ldb_context *, TALLOC_CTX *mem_ctx, const struct ldb_val *, const struct ldb_val *); +struct ldb_schema_attribute; +typedef int (*ldb_attr_operator_t)(struct ldb_context *, enum ldb_parse_op operation, + const struct ldb_schema_attribute *a, + const struct ldb_val *, const struct ldb_val *, bool *matched); + +/* + attribute handler structure + + attr -> The attribute name + ldif_read_fn -> convert from ldif to binary format + ldif_write_fn -> convert from binary to ldif format + canonicalise_fn -> canonicalise a value, for use by indexing and dn construction + index_form_fn -> get lexicographically sorted format for index + comparison_fn -> compare two values + operator_fn -> override function for optimizing out unnecessary + calls to canonicalise_fn and comparison_fn +*/ + +struct ldb_schema_syntax { + const char *name; + ldb_attr_handler_t ldif_read_fn; + ldb_attr_handler_t ldif_write_fn; + ldb_attr_handler_t canonicalise_fn; + ldb_attr_handler_t index_format_fn; + ldb_attr_comparison_t comparison_fn; + ldb_attr_operator_t operator_fn; +}; + +struct ldb_schema_attribute { + const char *name; + unsigned flags; + const struct ldb_schema_syntax *syntax; +}; + +const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_context *ldb, + const char *name); + +struct ldb_dn_extended_syntax { + const char *name; + ldb_attr_handler_t read_fn; + ldb_attr_handler_t write_clear_fn; + ldb_attr_handler_t write_hex_fn; +}; + +const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb, + const char *name); + +/** + The attribute is not returned by default +*/ +#define LDB_ATTR_FLAG_HIDDEN (1<<0) + +/* the attribute handler name should be freed when released */ +#define LDB_ATTR_FLAG_ALLOCATED (1<<1) + +/** + The attribute is supplied by the application and should not be removed +*/ +#define LDB_ATTR_FLAG_FIXED (1<<2) + +/* + when this is set, attempts to create two records which have the same + value for this attribute will return LDB_ERR_ENTRY_ALREADY_EXISTS + */ +#define LDB_ATTR_FLAG_UNIQUE_INDEX (1<<3) + +/* + when this is set, attempts to create two attribute values for this attribute on a single DN will return LDB_ERR_CONSTRAINT_VIOLATION + */ +#define LDB_ATTR_FLAG_SINGLE_VALUE (1<<4) + +/* + * The values should always be base64 encoded + */ +#define LDB_ATTR_FLAG_FORCE_BASE64_LDIF (1<<5) + +/* + * The attribute was loaded from a DB, rather than via the C API + */ +#define LDB_ATTR_FLAG_FROM_DB (1<<6) + +/* + * The attribute is indexed + */ +#define LDB_ATTR_FLAG_INDEXED (1<<7) + +/** + LDAP attribute syntax for a DN + + This is the well-known LDAP attribute syntax for a DN. + + See RFC 2252, Section 4.3.2 +*/ +#define LDB_SYNTAX_DN "1.3.6.1.4.1.1466.115.121.1.12" + +/** + LDAP attribute syntax for a Directory String + + This is the well-known LDAP attribute syntax for a Directory String. + + \sa RFC 2252, Section 4.3.2 +*/ +#define LDB_SYNTAX_DIRECTORY_STRING "1.3.6.1.4.1.1466.115.121.1.15" + +/** + LDAP attribute syntax for an integer + + This is the well-known LDAP attribute syntax for an integer. + + See RFC 2252, Section 4.3.2 +*/ +#define LDB_SYNTAX_INTEGER "1.3.6.1.4.1.1466.115.121.1.27" + +/** + Custom attribute syntax for an integer whose index is lexicographically + ordered by attribute value in the database. +*/ +#define LDB_SYNTAX_ORDERED_INTEGER "LDB_SYNTAX_ORDERED_INTEGER" + +/** + LDAP attribute syntax for a boolean + + This is the well-known LDAP attribute syntax for a boolean. + + See RFC 2252, Section 4.3.2 +*/ +#define LDB_SYNTAX_BOOLEAN "1.3.6.1.4.1.1466.115.121.1.7" + +/** + LDAP attribute syntax for an octet string + + This is the well-known LDAP attribute syntax for an octet string. + + See RFC 2252, Section 4.3.2 +*/ +#define LDB_SYNTAX_OCTET_STRING "1.3.6.1.4.1.1466.115.121.1.40" + +/** + LDAP attribute syntax for UTC time. + + This is the well-known LDAP attribute syntax for a UTC time. + + See RFC 2252, Section 4.3.2 +*/ +#define LDB_SYNTAX_UTC_TIME "1.3.6.1.4.1.1466.115.121.1.53" +#define LDB_SYNTAX_GENERALIZED_TIME "1.3.6.1.4.1.1466.115.121.1.24" + +#define LDB_SYNTAX_OBJECTCLASS "LDB_SYNTAX_OBJECTCLASS" + +/* sorting helpers */ +typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque); + +/* Individual controls */ + +/** + OID for getting and manipulating attributes from the ldb + without interception in the operational module. + It can be used to access attribute that used to be stored in the sam + and that are now calculated. +*/ +#define LDB_CONTROL_BYPASS_OPERATIONAL_OID "1.3.6.1.4.1.7165.4.3.13" +#define LDB_CONTROL_BYPASS_OPERATIONAL_NAME "bypassoperational" + +/** + OID for recalculate RDN (rdn attribute and 'name') control. This control forces + the rdn_name module to the recalculate the rdn and name attributes as if the + object was just created. +*/ +#define LDB_CONTROL_RECALCULATE_RDN_OID "1.3.6.1.4.1.7165.4.3.30" + +/** + OID for recalculate SD control. This control force the + dsdb code to recalculate the SD of the object as if the + object was just created. + +*/ +#define LDB_CONTROL_RECALCULATE_SD_OID "1.3.6.1.4.1.7165.4.3.5" +#define LDB_CONTROL_RECALCULATE_SD_NAME "recalculate_sd" + +/** + REVEAL_INTERNALS is used to reveal internal attributes and DN + components which are not normally shown to the user +*/ +#define LDB_CONTROL_REVEAL_INTERNALS "1.3.6.1.4.1.7165.4.3.6" +#define LDB_CONTROL_REVEAL_INTERNALS_NAME "reveal_internals" + +/** + LDB_CONTROL_AS_SYSTEM is used to skip access checks on operations + that are performed by the system, but with a user's credentials, e.g. + updating prefix map +*/ +#define LDB_CONTROL_AS_SYSTEM_OID "1.3.6.1.4.1.7165.4.3.7" + +/** + LDB_CONTROL_PROVISION_OID is used to skip some constraint checks. It's is + mainly thought to be used for the provisioning. +*/ +#define LDB_CONTROL_PROVISION_OID "1.3.6.1.4.1.7165.4.3.16" +#define LDB_CONTROL_PROVISION_NAME "provision" + +/* AD controls */ + +/** + OID for the paged results control. This control is included in the + searchRequest and searchResultDone messages as part of the controls + field of the LDAPMessage, as defined in Section 4.1.12 of + LDAP v3. + + \sa RFC 2696. +*/ +#define LDB_CONTROL_PAGED_RESULTS_OID "1.2.840.113556.1.4.319" +#define LDB_CONTROL_PAGED_RESULTS_NAME "paged_results" + +/** + OID for specifying the returned elements of the ntSecurityDescriptor + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_SD_FLAGS_OID "1.2.840.113556.1.4.801" +#define LDB_CONTROL_SD_FLAGS_NAME "sd_flags" + +/** + OID for specifying an advanced scope for the search (one partition) + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_DOMAIN_SCOPE_OID "1.2.840.113556.1.4.1339" +#define LDB_CONTROL_DOMAIN_SCOPE_NAME "domain_scope" + +/** + OID for specifying an advanced scope for a search + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_SEARCH_OPTIONS_OID "1.2.840.113556.1.4.1340" +#define LDB_CONTROL_SEARCH_OPTIONS_NAME "search_options" + +/** + OID for notification + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_NOTIFICATION_OID "1.2.840.113556.1.4.528" +#define LDB_CONTROL_NOTIFICATION_NAME "notification" + +/** + OID for performing subtree deletes + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_TREE_DELETE_OID "1.2.840.113556.1.4.805" +#define LDB_CONTROL_TREE_DELETE_NAME "tree_delete" + +/** + OID for getting deleted objects + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_SHOW_DELETED_OID "1.2.840.113556.1.4.417" +#define LDB_CONTROL_SHOW_DELETED_NAME "show_deleted" + +/** + OID for getting recycled objects + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_SHOW_RECYCLED_OID "1.2.840.113556.1.4.2064" +#define LDB_CONTROL_SHOW_RECYCLED_NAME "show_recycled" + +/** + OID for getting deactivated linked attributes + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID "1.2.840.113556.1.4.2065" +#define LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME "show_deactivated_link" + +/** + OID for extended DN + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_EXTENDED_DN_OID "1.2.840.113556.1.4.529" +#define LDB_CONTROL_EXTENDED_DN_NAME "extended_dn" + +/** + OID for LDAP server sort result extension. + + This control is included in the searchRequest message as part of + the controls field of the LDAPMessage, as defined in Section 4.1.12 + of LDAP v3. The controlType is set to + "1.2.840.113556.1.4.473". The criticality MAY be either TRUE or + FALSE (where absent is also equivalent to FALSE) at the client's + option. + + \sa RFC 2891. +*/ +#define LDB_CONTROL_SERVER_SORT_OID "1.2.840.113556.1.4.473" +#define LDB_CONTROL_SERVER_SORT_NAME "server_sort" + +/** + OID for LDAP server sort result response extension. + + This control is included in the searchResultDone message as part of + the controls field of the LDAPMessage, as defined in Section 4.1.12 of + LDAP v3. + + \sa RFC 2891. +*/ +#define LDB_CONTROL_SORT_RESP_OID "1.2.840.113556.1.4.474" +#define LDB_CONTROL_SORT_RESP_NAME "server_sort_resp" + +/** + OID for LDAP Attribute Scoped Query extension. + + This control is included in SearchRequest or SearchResponse + messages as part of the controls field of the LDAPMessage. +*/ +#define LDB_CONTROL_ASQ_OID "1.2.840.113556.1.4.1504" +#define LDB_CONTROL_ASQ_NAME "asq" + +/** + OID for LDAP Directory Sync extension. + + This control is included in SearchRequest or SearchResponse + messages as part of the controls field of the LDAPMessage. +*/ +#define LDB_CONTROL_DIRSYNC_OID "1.2.840.113556.1.4.841" +#define LDB_CONTROL_DIRSYNC_NAME "dirsync" +#define LDB_CONTROL_DIRSYNC_EX_OID "1.2.840.113556.1.4.2090" +#define LDB_CONTROL_DIRSYNC_EX_NAME "dirsync_ex" + + +/** + OID for LDAP Virtual List View Request extension. + + This control is included in SearchRequest messages + as part of the controls field of the LDAPMessage. +*/ +#define LDB_CONTROL_VLV_REQ_OID "2.16.840.1.113730.3.4.9" +#define LDB_CONTROL_VLV_REQ_NAME "vlv" + +/** + OID for LDAP Virtual List View Response extension. + + This control is included in SearchResponse messages + as part of the controls field of the LDAPMessage. +*/ +#define LDB_CONTROL_VLV_RESP_OID "2.16.840.1.113730.3.4.10" +#define LDB_CONTROL_VLV_RESP_NAME "vlv_resp" + +/** + OID to let modifies don't give an error when adding an existing + attribute with the same value or deleting an nonexisting one attribute + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_PERMISSIVE_MODIFY_OID "1.2.840.113556.1.4.1413" +#define LDB_CONTROL_PERMISSIVE_MODIFY_NAME "permissive_modify" + +/** + OID to allow the server to be more 'fast and loose' with the data being added. + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_SERVER_LAZY_COMMIT "1.2.840.113556.1.4.619" + +/** + Control for RODC join -see [MS-ADTS] section 3.1.1.3.4.1.23 + + \sa Microsoft documentation of this OID +*/ +#define LDB_CONTROL_RODC_DCPROMO_OID "1.2.840.113556.1.4.1341" +#define LDB_CONTROL_RODC_DCPROMO_NAME "rodc_join" + +/* Other standardised controls */ + +/** + OID for the allowing client to request temporary relaxed + enforcement of constraints of the x.500 model. + + Mainly used for the OpenLDAP backend. + + \sa draft managedit. +*/ +#define LDB_CONTROL_RELAX_OID "1.3.6.1.4.1.4203.666.5.12" +#define LDB_CONTROL_RELAX_NAME "relax" + +/** + OID for the allowing some kind of relax check for attributes with DNs + + + \sa 3.1.1.3.4.1.16 in [MS-ADTS].pdf +*/ +#define LDB_CONTROL_VERIFY_NAME_OID "1.2.840.113556.1.4.1338" +#define LDB_CONTROL_VERIFY_NAME_NAME "verify_name" + +/* Extended operations */ + +/** + OID for LDAP Extended Operation SEQUENCE_NUMBER + + This extended operation is used to retrieve the extended sequence number. +*/ +#define LDB_EXTENDED_SEQUENCE_NUMBER "1.3.6.1.4.1.7165.4.4.3" + +/** + OID for LDAP Extended Operation PASSWORD_CHANGE. + + This Extended operation is used to allow user password changes by the user + itself. +*/ +#define LDB_EXTENDED_PASSWORD_CHANGE_OID "1.3.6.1.4.1.4203.1.11.1" + + +/** + OID for LDAP Extended Operation FAST_BIND + + This Extended operations is used to perform a fast bind. +*/ +#define LDB_EXTENDED_FAST_BIND_OID "1.2.840.113556.1.4.1781" + +/** + OID for LDAP Extended Operation START_TLS. + + This Extended operation is used to start a new TLS channel on top of a clear + text channel. +*/ +#define LDB_EXTENDED_START_TLS_OID "1.3.6.1.4.1.1466.20037" + +/** + OID for LDAP Extended Operation DYNAMIC_REFRESH. + + This Extended operation is used to create and maintain objects which exist + only a specific time, e.g. when a certain client or a certain person is + logged in. Data refreshes have to be periodically sent in a specific + interval. Otherwise the entry is going to be removed. +*/ +#define LDB_EXTENDED_DYNAMIC_OID "1.3.6.1.4.1.1466.101.119.1" + +struct ldb_sd_flags_control { + /* + * request the owner 0x00000001 + * request the group 0x00000002 + * request the DACL 0x00000004 + * request the SACL 0x00000008 + */ + unsigned secinfo_flags; +}; + +/* + * DOMAIN_SCOPE 0x00000001 + * this limits the search to one partition, + * and no referrals will be returned. + * (Note this doesn't limit the entries by there + * objectSid belonging to a domain! Builtin and Foreign Sids + * are still returned) + * + * PHANTOM_ROOT 0x00000002 + * this search on the whole tree on a domain controller + * over multiple partitions without referrals. + * (This is the default behavior on the Global Catalog Port) + */ + +#define LDB_SEARCH_OPTION_DOMAIN_SCOPE 0x00000001 +#define LDB_SEARCH_OPTION_PHANTOM_ROOT 0x00000002 + +struct ldb_search_options_control { + unsigned search_options; +}; + +struct ldb_paged_control { + int size; + int cookie_len; + char *cookie; +}; + +struct ldb_extended_dn_control { + int type; +}; + +struct ldb_server_sort_control { + const char *attributeName; + const char *orderingRule; + int reverse; +}; + +struct ldb_sort_resp_control { + int result; + char *attr_desc; +}; + +struct ldb_asq_control { + int request; + char *source_attribute; + int src_attr_len; + int result; +}; + +struct ldb_dirsync_control { + int flags; + int max_attributes; + int cookie_len; + char *cookie; +}; + +struct ldb_vlv_req_control { + int beforeCount; + int afterCount; + int type; + union { + struct { + int offset; + int contentCount; + } byOffset; + struct { + int value_len; + char *value; + } gtOrEq; + } match; + int ctxid_len; + uint8_t *contextId; +}; + +struct ldb_vlv_resp_control { + int targetPosition; + int contentCount; + int vlv_result; + int ctxid_len; + uint8_t *contextId; +}; + +struct ldb_verify_name_control { + int flags; + size_t gc_len; + char *gc; +}; + +struct ldb_control { + const char *oid; + int critical; + void *data; +}; + +enum ldb_request_type { + LDB_SEARCH, + LDB_ADD, + LDB_MODIFY, + LDB_DELETE, + LDB_RENAME, + LDB_EXTENDED, + LDB_REQ_REGISTER_CONTROL, + LDB_REQ_REGISTER_PARTITION +}; + +enum ldb_reply_type { + LDB_REPLY_ENTRY, + LDB_REPLY_REFERRAL, + LDB_REPLY_DONE +}; + +enum ldb_wait_type { + LDB_WAIT_ALL, + LDB_WAIT_NONE +}; + +enum ldb_state { + LDB_ASYNC_INIT, + LDB_ASYNC_PENDING, + LDB_ASYNC_DONE +}; + +struct ldb_extended { + const char *oid; + void *data; /* NULL or a valid talloc pointer! talloc_get_type() will be used on it */ +}; + +enum ldb_sequence_type { + LDB_SEQ_HIGHEST_SEQ, + LDB_SEQ_HIGHEST_TIMESTAMP, + LDB_SEQ_NEXT +}; + +#define LDB_SEQ_GLOBAL_SEQUENCE 0x01 +#define LDB_SEQ_TIMESTAMP_SEQUENCE 0x02 + +struct ldb_seqnum_request { + enum ldb_sequence_type type; +}; + +struct ldb_seqnum_result { + uint64_t seq_num; + uint32_t flags; +}; + +struct ldb_result { + unsigned int count; + struct ldb_message **msgs; + struct ldb_extended *extended; + struct ldb_control **controls; + char **refs; +}; + +struct ldb_reply { + int error; + enum ldb_reply_type type; + struct ldb_message *message; + struct ldb_extended *response; + struct ldb_control **controls; + char *referral; +}; + +struct ldb_request; +struct ldb_handle; + +struct ldb_search { + struct ldb_dn *base; + enum ldb_scope scope; + struct ldb_parse_tree *tree; + const char * const *attrs; + struct ldb_result *res; +}; + +struct ldb_add { + const struct ldb_message *message; +}; + +struct ldb_modify { + const struct ldb_message *message; +}; + +struct ldb_delete { + struct ldb_dn *dn; +}; + +struct ldb_rename { + struct ldb_dn *olddn; + struct ldb_dn *newdn; +}; + +struct ldb_register_control { + const char *oid; +}; + +struct ldb_register_partition { + struct ldb_dn *dn; +}; + +typedef int (*ldb_request_callback_t)(struct ldb_request *, struct ldb_reply *); + +struct ldb_request { + + enum ldb_request_type operation; + + union { + struct ldb_search search; + struct ldb_add add; + struct ldb_modify mod; + struct ldb_delete del; + struct ldb_rename rename; + struct ldb_extended extended; + struct ldb_register_control reg_control; + struct ldb_register_partition reg_partition; + } op; + + struct ldb_control **controls; + + void *context; + ldb_request_callback_t callback; + + int timeout; + time_t starttime; + struct ldb_handle *handle; +}; + +int ldb_request(struct ldb_context *ldb, struct ldb_request *request); +int ldb_request_done(struct ldb_request *req, int status); +bool ldb_request_is_done(struct ldb_request *req); + +int ldb_modules_wait(struct ldb_handle *handle); +int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type); + +int ldb_set_timeout(struct ldb_context *ldb, struct ldb_request *req, int timeout); +int ldb_set_timeout_from_prev_req(struct ldb_context *ldb, struct ldb_request *oldreq, struct ldb_request *newreq); +void ldb_set_create_perms(struct ldb_context *ldb, unsigned int perms); +void ldb_set_modules_dir(struct ldb_context *ldb, const char *path); +struct tevent_context; +void ldb_set_event_context(struct ldb_context *ldb, struct tevent_context *ev); +struct tevent_context * ldb_get_event_context(struct ldb_context *ldb); + +/** + Initialise ldbs' global information + + This is required before any other LDB call + + \return 0 if initialisation succeeded, -1 otherwise +*/ +int ldb_global_init(void); + +/** + Initialise an ldb context + + This is required before any other LDB call. + + \param mem_ctx pointer to a talloc memory context. Pass NULL if there is + no suitable context available. + + \note The LDB modules will be loaded from directory specified by the environment + variable LDB_MODULES_PATH. If the variable is not specified, the compiled-in default + is used. + + \return pointer to ldb_context that should be free'd (using talloc_free()) + at the end of the program. +*/ +struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx); + +typedef void (*ldb_async_timeout_fn) (void *); +typedef bool (*ldb_async_callback_fn) (void *); +typedef int (*ldb_async_ctx_add_op_fn)(void *, time_t, void *, ldb_async_timeout_fn, ldb_async_callback_fn); +typedef int (*ldb_async_ctx_wait_op_fn)(void *); + +void ldb_async_ctx_set_private_data(struct ldb_context *ldb, + void *private_data); +void ldb_async_ctx_set_add_op(struct ldb_context *ldb, + ldb_async_ctx_add_op_fn add_op); +void ldb_async_ctx_set_wait_op(struct ldb_context *ldb, + ldb_async_ctx_wait_op_fn wait_op); + +/** + Connect to a database. + + This is typically called soon after ldb_init(), and is required prior to + any search or database modification operations. + + The URL can be one of the following forms: + - tdb://path + - ldapi://path + - ldap://host + - sqlite://path + + \param ldb the context associated with the database (from ldb_init()) + \param url the URL of the database to connect to, as noted above + \param flags a combination of LDB_FLG_* to modify the connection behaviour + \param options backend specific options - passed uninterpreted to the backend + + \return result code (LDB_SUCCESS on success, or a failure code) + + \note It is an error to connect to a database that does not exist in readonly mode + (that is, with LDB_FLG_RDONLY). However in read-write mode, the database will be + created if it does not exist. +*/ +int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[]); + +/* + return an automatic basedn from the rootDomainNamingContext of the rootDSE + This value have been set in an opaque pointer at connection time +*/ +struct ldb_dn *ldb_get_root_basedn(struct ldb_context *ldb); + +/* + return an automatic basedn from the configurationNamingContext of the rootDSE + This value have been set in an opaque pointer at connection time +*/ +struct ldb_dn *ldb_get_config_basedn(struct ldb_context *ldb); + +/* + return an automatic basedn from the schemaNamingContext of the rootDSE + This value have been set in an opaque pointer at connection time +*/ +struct ldb_dn *ldb_get_schema_basedn(struct ldb_context *ldb); + +/* + return an automatic baseDN from the defaultNamingContext of the rootDSE + This value have been set in an opaque pointer at connection time +*/ +struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb); + +/** + The default async search callback function + + \param req the request we are callback of + \param ares a single reply from the async core + + \return result code (LDB_SUCCESS on success, or a failure code) + + \note this function expects req->context to always be an struct ldb_result pointer + AND a talloc context, this function will steal on the context each message + from the ares reply passed on by the async core so that in the end all the + messages will be in the context (ldb_result) memory tree. + Freeing the passed context (ldb_result tree) will free all the resources + (the request need to be freed separately and the result doe not depend on the + request that can be freed as sson as the search request is finished) +*/ + +int ldb_search_default_callback(struct ldb_request *req, struct ldb_reply *ares); + +/** + The default async extended operation callback function + + \param req the request we are callback of + \param ares a single reply from the async core + + \return result code (LDB_SUCCESS on success, or a failure code) +*/ +int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares); + +int ldb_modify_default_callback(struct ldb_request *req, struct ldb_reply *ares); + +/** + Helper function to build a search request + + \param ret_req the request structure is returned here (talloced on mem_ctx) + \param ldb the context associated with the database (from ldb_init()) + \param mem_ctx a talloc memory context (used as parent of ret_req) + \param base the Base Distinguished Name for the query (use ldb_dn_new() for an empty one) + \param scope the search scope for the query + \param expression the search expression to use for this query + \param attrs the search attributes for the query (pass NULL if none required) + \param controls an array of controls + \param context the callback function context + \param the callback function to handle the async replies + \param the parent request if any + + \return result code (LDB_SUCCESS on success, or a failure code) +*/ + +int ldb_build_search_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *base, + enum ldb_scope scope, + const char *expression, + const char * const *attrs, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent); + +int ldb_build_search_req_ex(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *base, + enum ldb_scope scope, + struct ldb_parse_tree *tree, + const char * const *attrs, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent); + +/** + Helper function to build an add request + + \param ret_req the request structure is returned here (talloced on mem_ctx) + \param ldb the context associated with the database (from ldb_init()) + \param mem_ctx a talloc memory context (used as parent of ret_req) + \param message contains the entry to be added + \param controls an array of controls + \param context the callback function context + \param the callback function to handle the async replies + \param the parent request if any + + \return result code (LDB_SUCCESS on success, or a failure code) +*/ + +int ldb_build_add_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const struct ldb_message *message, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent); + +/** + Helper function to build a modify request + + \param ret_req the request structure is returned here (talloced on mem_ctx) + \param ldb the context associated with the database (from ldb_init()) + \param mem_ctx a talloc memory context (used as parent of ret_req) + \param message contains the entry to be modified + \param controls an array of controls + \param context the callback function context + \param the callback function to handle the async replies + \param the parent request if any + + \return result code (LDB_SUCCESS on success, or a failure code) +*/ + +int ldb_build_mod_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const struct ldb_message *message, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent); + +/** + Helper function to build a delete request + + \param ret_req the request structure is returned here (talloced on mem_ctx) + \param ldb the context associated with the database (from ldb_init()) + \param mem_ctx a talloc memory context (used as parent of ret_req) + \param dn the DN to be deleted + \param controls an array of controls + \param context the callback function context + \param the callback function to handle the async replies + \param the parent request if any + + \return result code (LDB_SUCCESS on success, or a failure code) +*/ + +int ldb_build_del_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *dn, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent); + +/** + Helper function to build a rename request + + \param ret_req the request structure is returned here (talloced on mem_ctx) + \param ldb the context associated with the database (from ldb_init()) + \param mem_ctx a talloc memory context (used as parent of ret_req) + \param olddn the old DN + \param newdn the new DN + \param controls an array of controls + \param context the callback function context + \param the callback function to handle the async replies + \param the parent request if any + + \return result code (LDB_SUCCESS on success, or a failure code) +*/ + +int ldb_build_rename_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *olddn, + struct ldb_dn *newdn, + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent); + +/** + Add a ldb_control to a ldb_request + + \param req the request struct where to add the control + \param oid the object identifier of the control as string + \param critical whether the control should be critical or not + \param data a talloc pointer to the control specific data + + \return result code (LDB_SUCCESS on success, or a failure code) +*/ +int ldb_request_add_control(struct ldb_request *req, const char *oid, bool critical, void *data); + +/** + replace a ldb_control in a ldb_request + + \param req the request struct where to add the control + \param oid the object identifier of the control as string + \param critical whether the control should be critical or not + \param data a talloc pointer to the control specific data + + \return result code (LDB_SUCCESS on success, or a failure code) +*/ +int ldb_request_replace_control(struct ldb_request *req, const char *oid, bool critical, void *data); + +/** + check if a control with the specified "oid" exist and return it + \param req the request struct where to add the control + \param oid the object identifier of the control as string + + \return the control, NULL if not found +*/ +struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid); + +/** + check if a control with the specified "oid" exist and return it + \param rep the reply struct where to add the control + \param oid the object identifier of the control as string + + \return the control, NULL if not found +*/ +struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid); + +/** + Search the database + + This function searches the database, and returns + records that match an LDAP-like search expression + + \param ldb the context associated with the database (from ldb_init()) + \param mem_ctx the memory context to use for the request and the results + \param result the return result + \param base the Base Distinguished Name for the query (use ldb_dn_new() for an empty one) + \param scope the search scope for the query + \param attrs the search attributes for the query (pass NULL if none required) + \param exp_fmt the search expression to use for this query (printf like) + + \return result code (LDB_SUCCESS on success, or a failure code) + + \note use talloc_free() to free the ldb_result returned +*/ +int ldb_search(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + struct ldb_result **result, struct ldb_dn *base, + enum ldb_scope scope, const char * const *attrs, + const char *exp_fmt, ...) PRINTF_ATTRIBUTE(7,8); + +/** + Add a record to the database. + + This function adds a record to the database. This function will fail + if a record with the specified class and key already exists in the + database. + + \param ldb the context associated with the database (from + ldb_init()) + \param message the message containing the record to add. + + \return result code (LDB_SUCCESS if the record was added, otherwise + a failure code) +*/ +int ldb_add(struct ldb_context *ldb, + const struct ldb_message *message); + +/** + Modify the specified attributes of a record + + This function modifies a record that is in the database. + + \param ldb the context associated with the database (from + ldb_init()) + \param message the message containing the changes required. + + \return result code (LDB_SUCCESS if the record was modified as + requested, otherwise a failure code) +*/ +int ldb_modify(struct ldb_context *ldb, + const struct ldb_message *message); + +/** + Rename a record in the database + + This function renames a record in the database. + + \param ldb the context associated with the database (from + ldb_init()) + \param olddn the DN for the record to be renamed. + \param newdn the new DN + + \return result code (LDB_SUCCESS if the record was renamed as + requested, otherwise a failure code) +*/ +int ldb_rename(struct ldb_context *ldb, struct ldb_dn *olddn, struct ldb_dn *newdn); + +/** + Delete a record from the database + + This function deletes a record from the database. + + \param ldb the context associated with the database (from + ldb_init()) + \param dn the DN for the record to be deleted. + + \return result code (LDB_SUCCESS if the record was deleted, + otherwise a failure code) +*/ +int ldb_delete(struct ldb_context *ldb, struct ldb_dn *dn); + +/** + The default async extended operation callback function + + \param req the request we are callback of + \param ares a single reply from the async core + + \return result code (LDB_SUCCESS on success, or a failure code) + + \note this function expects req->context to always be an struct ldb_result pointer + AND a talloc context, this function will steal on the context each message + from the ares reply passed on by the async core so that in the end all the + messages will be in the context (ldb_result) memory tree. + Freeing the passed context (ldb_result tree) will free all the resources + (the request need to be freed separately and the result doe not depend on the + request that can be freed as sson as the search request is finished) +*/ + +int ldb_extended_default_callback(struct ldb_request *req, struct ldb_reply *ares); + + +/** + Helper function to build a extended request + + \param ret_req the request structure is returned here (talloced on mem_ctx) + \param ldb the context associated with the database (from ldb_init()) + \param mem_ctx a talloc memory context (used as parent of ret_req) + \param oid the OID of the extended operation. + \param data a void pointer a the extended operation specific parameters, + it needs to be NULL or a valid talloc pointer! talloc_get_type() will be used on it + \param controls an array of controls + \param context the callback function context + \param the callback function to handle the async replies + \param the parent request if any + + \return result code (LDB_SUCCESS on success, or a failure code) +*/ +int ldb_build_extended_req(struct ldb_request **ret_req, + struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const char *oid, + void *data,/* NULL or a valid talloc pointer! talloc_get_type() will be used on it */ + struct ldb_control **controls, + void *context, + ldb_request_callback_t callback, + struct ldb_request *parent); + +/** + call an extended operation + + \param ldb the context associated with the database (from ldb_init()) + \param oid the OID of the extended operation. + \param data a void pointer a the extended operation specific parameters, + it needs to be NULL or a valid talloc pointer! talloc_get_type() will be used on it + \param res the result of the extended operation + + \return result code (LDB_SUCCESS if the extended operation returned fine, + otherwise a failure code) +*/ +int ldb_extended(struct ldb_context *ldb, + const char *oid, + void *data,/* NULL or a valid talloc pointer! talloc_get_type() will be used on it */ + struct ldb_result **res); + +/** + Obtain current/next database sequence number +*/ +int ldb_sequence_number(struct ldb_context *ldb, enum ldb_sequence_type type, uint64_t *seq_num); + +/** + start a transaction +*/ +int ldb_transaction_start(struct ldb_context *ldb); + +/** + first phase of two phase commit + */ +int ldb_transaction_prepare_commit(struct ldb_context *ldb); + +/** + commit a transaction +*/ +int ldb_transaction_commit(struct ldb_context *ldb); + +/** + cancel a transaction +*/ +int ldb_transaction_cancel(struct ldb_context *ldb); + +/* + cancel a transaction with no error if no transaction is pending + used when we fork() to clear any parent transactions +*/ +int ldb_transaction_cancel_noerr(struct ldb_context *ldb); + + +/** + return extended error information from the last call +*/ +const char *ldb_errstring(struct ldb_context *ldb); + +/** + return a string explaining what a ldb error constant means +*/ +const char *ldb_strerror(int ldb_err); + +/** + setup the default utf8 functions + FIXME: these functions do not yet handle utf8 +*/ +void ldb_set_utf8_default(struct ldb_context *ldb); + +/** + Casefold a string + + \param ldb the ldb context + \param mem_ctx the memory context to allocate the result string + memory from. + \param s the string that is to be folded + \return a copy of the string, converted to upper case + + \note The default function is not yet UTF8 aware. Provide your own + set of functions through ldb_set_utf8_fns() +*/ +char *ldb_casefold(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *s, size_t n); + +/** + Check the attribute name is valid according to rfc2251 + \param s the string to check + + \return 1 if the name is ok +*/ +int ldb_valid_attr_name(const char *s); + +/* + ldif manipulation functions +*/ + +/** + Write an LDIF message + + This function writes an LDIF message using a caller supplied write + function. + + \param ldb the ldb context (from ldb_init()) + \param fprintf_fn a function pointer for the write function. This must take + a private data pointer, followed by a format string, and then a variable argument + list. + \param private_data pointer that will be provided back to the write + function. This is useful for maintaining state or context. + \param ldif the message to write out + + \return the total number of bytes written, or an error code as returned + from the write function. + + \sa ldb_ldif_write_file for a more convenient way to write to a + file stream. + + \sa ldb_ldif_read for the reader equivalent to this function. +*/ +int ldb_ldif_write(struct ldb_context *ldb, + int (*fprintf_fn)(void *, const char *, ...) PRINTF_ATTRIBUTE(2,3), + void *private_data, + const struct ldb_ldif *ldif); + +/** + Clean up an LDIF message + + This function cleans up a LDIF message read using ldb_ldif_read() + or related functions (such as ldb_ldif_read_string() and + ldb_ldif_read_file(). + + \param ldb the ldb context (from ldb_init()) + \param msg the message to clean up and free + +*/ +void ldb_ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *msg); + +/** + Read an LDIF message + + This function creates an LDIF message using a caller supplied read + function. + + \param ldb the ldb context (from ldb_init()) + \param fgetc_fn a function pointer for the read function. This must + take a private data pointer, and must return a pointer to an + integer corresponding to the next byte read (or EOF if there is no + more data to be read). + \param private_data pointer that will be provided back to the read + function. This is udeful for maintaining state or context. + + \return the LDIF message that has been read in + + \note You must free the LDIF message when no longer required, using + ldb_ldif_read_free(). + + \sa ldb_ldif_read_file for a more convenient way to read from a + file stream. + + \sa ldb_ldif_read_string for a more convenient way to read from a + string (char array). + + \sa ldb_ldif_write for the writer equivalent to this function. +*/ +struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, + int (*fgetc_fn)(void *), void *private_data); + +/** + Read an LDIF message from a file + + This function reads the next LDIF message from the contents of a + file stream. If you want to get all of the LDIF messages, you will + need to repeatedly call this function, until it returns NULL. + + \param ldb the ldb context (from ldb_init()) + \param f the file stream to read from (typically from fdopen()) + + \sa ldb_ldif_read_string for an equivalent function that will read + from a string (char array). + + \sa ldb_ldif_write_file for the writer equivalent to this function. + +*/ +struct ldb_ldif *ldb_ldif_read_file(struct ldb_context *ldb, FILE *f); + +/** + Read an LDIF message from a string + + This function reads the next LDIF message from the contents of a char + array. If you want to get all of the LDIF messages, you will need + to repeatedly call this function, until it returns NULL. + + \param ldb the ldb context (from ldb_init()) + \param s pointer to the char array to read from + + \sa ldb_ldif_read_file for an equivalent function that will read + from a file stream. + + \sa ldb_ldif_write for a more general (arbitrary read function) + version of this function. +*/ +struct ldb_ldif *ldb_ldif_read_string(struct ldb_context *ldb, const char **s); + +/** + Parse a modrdn LDIF message from a struct ldb_message + + \param ldb the ldb context (from ldb_init()) + \param ldif the preparsed LDIF chunk (from ldb_ldif_read()) + + \param mem_ctx the memory context that's used for return values + + \param olddn the old dn as struct ldb_dn, if not needed pass NULL + \param newrdn the new rdn as struct ldb_dn, if not needed pass NULL + \param deleteoldrdn the deleteoldrdn value as bool, if not needed pass NULL + \param newsuperior the newsuperior dn as struct ldb_dn, if not needed pass NULL + *newsuperior can be NULL as it is optional in the LDIF + \param newdn the full constructed new dn as struct ldb_dn, if not needed pass NULL + +*/ +int ldb_ldif_parse_modrdn(struct ldb_context *ldb, + const struct ldb_ldif *ldif, + TALLOC_CTX *mem_ctx, + struct ldb_dn **olddn, + struct ldb_dn **newrdn, + bool *deleteoldrdn, + struct ldb_dn **newsuperior, + struct ldb_dn **newdn); + +/** + Write an LDIF message to a file + + \param ldb the ldb context (from ldb_init()) + \param f the file stream to write to (typically from fdopen()) + \param msg the message to write out + + \return the total number of bytes written, or a negative error code + + \sa ldb_ldif_read_file for the reader equivalent to this function. +*/ +int ldb_ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif *msg); + +/** + Write an LDIF message to a string + + \param ldb the ldb context (from ldb_init()) + \param mem_ctx the talloc context on which to attach the string) + \param msg the message to write out + + \return the string containing the LDIF, or NULL on error + + \sa ldb_ldif_read_string for the reader equivalent to this function. +*/ +char * ldb_ldif_write_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + const struct ldb_ldif *msg); + + +/** + Write an LDB message to a string + + \param ldb the ldb context (from ldb_init()) + \param mem_ctx the talloc context on which to attach the string) + \param changetype LDB_CHANGETYPE_ADD or LDB_CHANGETYPE_MODIFY + \param msg the message to write out + + \return the string containing the LDIF, or NULL on error + + \sa ldb_ldif_message_redacted_string for a safer version of this + function +*/ +char *ldb_ldif_message_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + enum ldb_changetype changetype, + const struct ldb_message *msg); + +/** + Write an LDB message to a string + + \param ldb the ldb context (from ldb_init()) + \param mem_ctx the talloc context on which to attach the string) + \param changetype LDB_CHANGETYPE_ADD or LDB_CHANGETYPE_MODIFY + \param msg the message to write out + + \return the string containing the LDIF, or NULL on error, but + with secret attributes redacted + + \note The secret attributes are specified in a + 'const char * const *' within the LDB_SECRET_ATTRIBUTE_LIST + opaque set on the ldb + + \sa ldb_ldif_message_string for an exact representiation of the + message as LDIF +*/ +char *ldb_ldif_message_redacted_string(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + enum ldb_changetype changetype, + const struct ldb_message *msg); + + +/** + Base64 encode a buffer + + \param mem_ctx the memory context that the result is allocated + from. + \param buf pointer to the array that is to be encoded + \param len the number of elements in the array to be encoded + + \return pointer to an array containing the encoded data + + \note The caller is responsible for freeing the result +*/ +char *ldb_base64_encode(TALLOC_CTX *mem_ctx, const char *buf, int len); + +/** + Base64 decode a buffer + + This function decodes a base64 encoded string in place. + + \param s the string to decode. + + \return the length of the returned (decoded) string. + + \note the string is null terminated, but the null terminator is not + included in the length. +*/ +int ldb_base64_decode(char *s); + +/* The following definitions come from lib/ldb/common/ldb_dn.c */ + +/** + Get the linear form of a DN (without any extended components) + + \param dn The DN to linearize +*/ + +const char *ldb_dn_get_linearized(struct ldb_dn *dn); + +/** + Allocate a copy of the linear form of a DN (without any extended components) onto the supplied memory context + + \param dn The DN to linearize + \param mem_ctx TALLOC context to return result on +*/ + +char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); + +/** + Get the linear form of a DN (with any extended components) + + \param mem_ctx TALLOC context to return result on + \param dn The DN to linearize + \param mode Style of extended DN to return (0 is HEX representation of binary form, 1 is a string form) +*/ +char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode); +const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, const char *name); +int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const struct ldb_val *val); +void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list); +void ldb_dn_remove_extended_components(struct ldb_dn *dn); +bool ldb_dn_has_extended(struct ldb_dn *dn); + +int ldb_dn_extended_add_syntax(struct ldb_context *ldb, + unsigned flags, + const struct ldb_dn_extended_syntax *syntax); + +/** + Allocate a new DN from a string + + \param mem_ctx TALLOC context to return resulting ldb_dn structure on + \param dn The new DN + + \note The DN will not be parsed at this time. Use ldb_dn_validate to tell if the DN is syntacticly correct +*/ + +struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *dn); +/** + Allocate a new DN from a printf style format string and arguments + + \param mem_ctx TALLOC context to return resulting ldb_dn structure on + \param new_fms The new DN as a format string (plus arguments) + + \note The DN will not be parsed at this time. Use ldb_dn_validate to tell if the DN is syntacticly correct +*/ + +struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...) PRINTF_ATTRIBUTE(3,4); +/** + Allocate a new DN from a struct ldb_val (useful to avoid buffer overrun) + + \param mem_ctx TALLOC context to return resulting ldb_dn structure on + \param dn The new DN + + \note The DN will not be parsed at this time. Use ldb_dn_validate to tell if the DN is syntacticly correct +*/ + +struct ldb_dn *ldb_dn_from_ldb_val(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const struct ldb_val *strdn); + +/** + Determine if this DN is syntactically valid + + \param dn The DN to validate +*/ + +bool ldb_dn_validate(struct ldb_dn *dn); + +char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value); +const char *ldb_dn_get_casefold(struct ldb_dn *dn); +char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); + +int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn); +int ldb_dn_compare(struct ldb_dn *edn0, struct ldb_dn *edn1); + +bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base); +bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...) PRINTF_ATTRIBUTE(2,3); +bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child); +bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...) PRINTF_ATTRIBUTE(2,3); +bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num); +bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num); +bool ldb_dn_add_child_val(struct ldb_dn *dn, + const char *rdn, + struct ldb_val value); + +struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); +struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); +char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); +char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); +int ldb_dn_get_comp_num(struct ldb_dn *dn); +int ldb_dn_get_extended_comp_num(struct ldb_dn *dn); +const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num); +const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, unsigned int num); +const char *ldb_dn_get_rdn_name(struct ldb_dn *dn); +const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn); +int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val); + +bool ldb_dn_is_valid(struct ldb_dn *dn); +bool ldb_dn_is_special(struct ldb_dn *dn); +bool ldb_dn_check_special(struct ldb_dn *dn, const char *check); +bool ldb_dn_is_null(struct ldb_dn *dn); +int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn); + + +/** + Compare two attributes + + This function compares to attribute names. Note that this is a + case-insensitive comparison. + + \param a the first attribute name to compare + \param b the second attribute name to compare + + \return 0 if the attribute names are the same, or only differ in + case; non-zero if there are any differences + + attribute names are restricted by rfc2251 so using + strcasecmp and toupper here is ok. + return 0 for match +*/ +#define ldb_attr_cmp(a, b) strcasecmp(a, b) +char *ldb_attr_casefold(TALLOC_CTX *mem_ctx, const char *s); +int ldb_attr_dn(const char *attr); + +/** + Create an empty message + + \param mem_ctx the memory context to create in. You can pass NULL + to get the top level context, however the ldb context (from + ldb_init()) may be a better choice +*/ +struct ldb_message *ldb_msg_new(TALLOC_CTX *mem_ctx); + +/** + Find an element within an message +*/ +struct ldb_message_element *ldb_msg_find_element(const struct ldb_message *msg, + const char *attr_name); + +/** + Compare two ldb_val values + + \param v1 first ldb_val structure to be tested + \param v2 second ldb_val structure to be tested + + \return 1 for a match, 0 if there is any difference +*/ +int ldb_val_equal_exact(const struct ldb_val *v1, const struct ldb_val *v2); + +/** + find a value within an ldb_message_element + + \param el the element to search + \param val the value to search for + + \note This search is case sensitive +*/ +struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el, + struct ldb_val *val); + +/** + add a new empty element to a ldb_message +*/ +int ldb_msg_add_empty(struct ldb_message *msg, + const char *attr_name, + int flags, + struct ldb_message_element **return_el); + +/** + add a element to a ldb_message +*/ +int ldb_msg_add(struct ldb_message *msg, + const struct ldb_message_element *el, + int flags); +int ldb_msg_add_value(struct ldb_message *msg, + const char *attr_name, + const struct ldb_val *val, + struct ldb_message_element **return_el); +int ldb_msg_add_steal_value(struct ldb_message *msg, + const char *attr_name, + struct ldb_val *val); +int ldb_msg_add_steal_string(struct ldb_message *msg, + const char *attr_name, char *str); +int ldb_msg_add_string(struct ldb_message *msg, + const char *attr_name, const char *str); +int ldb_msg_add_linearized_dn(struct ldb_message *msg, const char *attr_name, + struct ldb_dn *dn); +int ldb_msg_add_fmt(struct ldb_message *msg, + const char *attr_name, const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); + +/** + compare two message elements - return 0 on match +*/ +int ldb_msg_element_compare(struct ldb_message_element *el1, + struct ldb_message_element *el2); +int ldb_msg_element_compare_name(struct ldb_message_element *el1, + struct ldb_message_element *el2); + +/** + Find elements in a message. + + This function finds elements and converts to a specific type, with + a give default value if not found. Assumes that elements are + single valued. +*/ +const struct ldb_val *ldb_msg_find_ldb_val(const struct ldb_message *msg, const char *attr_name); +int ldb_msg_find_attr_as_int(const struct ldb_message *msg, + const char *attr_name, + int default_value); +unsigned int ldb_msg_find_attr_as_uint(const struct ldb_message *msg, + const char *attr_name, + unsigned int default_value); +int64_t ldb_msg_find_attr_as_int64(const struct ldb_message *msg, + const char *attr_name, + int64_t default_value); +uint64_t ldb_msg_find_attr_as_uint64(const struct ldb_message *msg, + const char *attr_name, + uint64_t default_value); +double ldb_msg_find_attr_as_double(const struct ldb_message *msg, + const char *attr_name, + double default_value); +int ldb_msg_find_attr_as_bool(const struct ldb_message *msg, + const char *attr_name, + int default_value); +const char *ldb_msg_find_attr_as_string(const struct ldb_message *msg, + const char *attr_name, + const char *default_value); + +struct ldb_dn *ldb_msg_find_attr_as_dn(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const struct ldb_message *msg, + const char *attr_name); + +void ldb_msg_sort_elements(struct ldb_message *msg); + +struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx, + const struct ldb_message *msg); +struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, + const struct ldb_message *msg); + +/* + * ldb_msg_canonicalize() is now depreciated + * Please use ldb_msg_normalize() instead + * + * NOTE: Returned ldb_message object is allocated + * into *ldb's context. Callers are recommended + * to steal the returned object into a TALLOC_CTX + * with short lifetime. + */ +struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, + const struct ldb_message *msg) _DEPRECATED_; + +int ldb_msg_normalize(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const struct ldb_message *msg, + struct ldb_message **_msg_out); + + +/* + * ldb_msg_diff() is now depreciated + * Please use ldb_msg_difference() instead + * + * NOTE: Returned ldb_message object is allocated + * into *ldb's context. Callers are recommended + * to steal the returned object into a TALLOC_CTX + * with short lifetime. + */ +struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, + struct ldb_message *msg1, + struct ldb_message *msg2) _DEPRECATED_; + +/** + * return a ldb_message representing the differences between msg1 and msg2. + * If you then use this in a ldb_modify() call, + * it can be used to save edits to a message + * + * Result message is constructed as follows: + * - LDB_FLAG_MOD_ADD - elements found only in msg2 + * - LDB_FLAG_MOD_REPLACE - elements in msg2 that have + * different value in msg1 + * Value for msg2 element is used + * - LDB_FLAG_MOD_DELETE - elements found only in msg2 + * + * @return LDB_SUCCESS or LDB_ERR_OPERATIONS_ERROR + */ +int ldb_msg_difference(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_message *msg1, + struct ldb_message *msg2, + struct ldb_message **_msg_out); + +/** + Tries to find a certain string attribute in a message + + \param msg the message to check + \param name attribute name + \param value attribute value + + \return 1 on match and 0 otherwise. +*/ +int ldb_msg_check_string_attribute(const struct ldb_message *msg, + const char *name, + const char *value); + +/** + Integrity check an ldb_message + + This function performs basic sanity / integrity checks on an + ldb_message. + + \param ldb context in which to perform the checks + \param msg the message to check + + \return LDB_SUCCESS if the message is OK, or a non-zero error code + (one of LDB_ERR_INVALID_DN_SYNTAX, LDB_ERR_ENTRY_ALREADY_EXISTS or + LDB_ERR_INVALID_ATTRIBUTE_SYNTAX) if there is a problem with a + message. +*/ +int ldb_msg_sanity_check(struct ldb_context *ldb, + const struct ldb_message *msg); + +/** + Duplicate an ldb_val structure + + This function copies an ldb value structure. + + \param mem_ctx the memory context that the duplicated value will be + allocated from + \param v the ldb_val to be duplicated. + + \return the duplicated ldb_val structure. +*/ +struct ldb_val ldb_val_dup(TALLOC_CTX *mem_ctx, const struct ldb_val *v); + +/** + this allows the user to set a debug function for error reporting +*/ +int ldb_set_debug(struct ldb_context *ldb, + void (*debug)(void *context, enum ldb_debug_level level, + const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0), + void *context); + +/** + this allows the user to set custom utf8 function for error reporting +*/ +void ldb_set_utf8_fns(struct ldb_context *ldb, + void *context, + char *(*casefold)(void *, void *, const char *, size_t n)); + +/** + this sets up debug to print messages on stderr +*/ +int ldb_set_debug_stderr(struct ldb_context *ldb); + +/* control backend specific opaque values */ +int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value); +void *ldb_get_opaque(struct ldb_context *ldb, const char *name); + +const char **ldb_attr_list_copy(TALLOC_CTX *mem_ctx, const char * const *attrs); +const char **ldb_attr_list_copy_add(TALLOC_CTX *mem_ctx, const char * const *attrs, const char *new_attr); +int ldb_attr_in_list(const char * const *attrs, const char *attr); + +int ldb_msg_rename_attr(struct ldb_message *msg, const char *attr, const char *replace); +int ldb_msg_copy_attr(struct ldb_message *msg, const char *attr, const char *replace); +void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr); +void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el); + + +void ldb_parse_tree_attr_replace(struct ldb_parse_tree *tree, + const char *attr, + const char *replace); + +/* + shallow copy a tree - copying only the elements array so that the caller + can safely add new elements without changing the message +*/ +struct ldb_parse_tree *ldb_parse_tree_copy_shallow(TALLOC_CTX *mem_ctx, + const struct ldb_parse_tree *ot); + +/** + Convert a time structure to a string + + This function converts a time_t structure to an LDAP formatted + GeneralizedTime string. + + \param mem_ctx the memory context to allocate the return string in + \param t the time structure to convert + + \return the formatted string, or NULL if the time structure could + not be converted +*/ +char *ldb_timestring(TALLOC_CTX *mem_ctx, time_t t); + +/** + Convert a string to a time structure + + This function converts an LDAP formatted GeneralizedTime string + to a time_t structure. + + \param s the string to convert + + \return the time structure, or 0 if the string cannot be converted +*/ +time_t ldb_string_to_time(const char *s); + +/** + convert a LDAP GeneralizedTime string in ldb_val format to a + time_t. +*/ +int ldb_val_to_time(const struct ldb_val *v, time_t *t); + +/** + Convert a time structure to a string + + This function converts a time_t structure to an LDAP formatted + UTCTime string. + + \param mem_ctx the memory context to allocate the return string in + \param t the time structure to convert + + \return the formatted string, or NULL if the time structure could + not be converted +*/ +char *ldb_timestring_utc(TALLOC_CTX *mem_ctx, time_t t); + +/** + Convert a string to a time structure + + This function converts an LDAP formatted UTCTime string + to a time_t structure. + + \param s the string to convert + + \return the time structure, or 0 if the string cannot be converted +*/ +time_t ldb_string_utc_to_time(const char *s); + + +void ldb_qsort (void *const pbase, size_t total_elems, size_t size, void *opaque, ldb_qsort_cmp_fn_t cmp); + +#ifndef discard_const +#define discard_const(ptr) ((void *)((uintptr_t)(ptr))) +#endif + +/* + a wrapper around ldb_qsort() that ensures the comparison function is + type safe. This will produce a compilation warning if the types + don't match + */ +#define LDB_TYPESAFE_QSORT(base, numel, opaque, comparison) \ +do { \ + if (numel > 1) { \ + ldb_qsort(base, numel, sizeof((base)[0]), discard_const(opaque), (ldb_qsort_cmp_fn_t)comparison); \ + comparison(&((base)[0]), &((base)[1]), opaque); \ + } \ +} while (0) + +/* allow ldb to also call TYPESAFE_QSORT() */ +#ifndef TYPESAFE_QSORT +#define TYPESAFE_QSORT(base, numel, comparison) \ +do { \ + if (numel > 1) { \ + qsort(base, numel, sizeof((base)[0]), (int (*)(const void *, const void *))comparison); \ + comparison(&((base)[0]), &((base)[1])); \ + } \ +} while (0) +#endif + + + +/** + Convert a control into its string representation. + + \param mem_ctx TALLOC context to return result on, and to allocate error_string on + \param control A struct ldb_control to convert + + \return string representation of the control +*/ +char* ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *control); +/** + Convert a string representing a control into a ldb_control structure + + \param ldb LDB context + \param mem_ctx TALLOC context to return result on, and to allocate error_string on + \param control_strings A string-formatted control + + \return a ldb_control element +*/ +struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *control_strings); +/** + Convert an array of string represention of a control into an array of ldb_control structures + + \param ldb LDB context + \param mem_ctx TALLOC context to return result on, and to allocate error_string on + \param control_strings Array of string-formatted controls + + \return array of ldb_control elements +*/ +struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char **control_strings); + +/** + return the ldb flags +*/ +unsigned int ldb_get_flags(struct ldb_context *ldb); + +/* set the ldb flags */ +void ldb_set_flags(struct ldb_context *ldb, unsigned flags); + + +struct ldb_dn *ldb_dn_binary_from_ldb_val(TALLOC_CTX *mem_ctx, + struct ldb_context *ldb, + const struct ldb_val *strdn); + +int ldb_dn_get_binary(struct ldb_dn *dn, struct ldb_val *val); +int ldb_dn_set_binary(struct ldb_dn *dn, struct ldb_val *val); + +/* debugging functions for ldb requests */ +void ldb_req_set_location(struct ldb_request *req, const char *location); +const char *ldb_req_location(struct ldb_request *req); + +/* set the location marker on a request handle - used for debugging */ +#define LDB_REQ_SET_LOCATION(req) ldb_req_set_location(req, __location__) + +/* + minimise a DN. The caller must pass in a validated DN. + + If the DN has an extended component then only the first extended + component is kept, the DN string is stripped. + + The existing dn is modified + */ +bool ldb_dn_minimise(struct ldb_dn *dn); + +/* + compare a ldb_val to a string +*/ +int ldb_val_string_cmp(const struct ldb_val *v, const char *str); + +#endif diff --git a/ldb-2.0.8/include/ldb_errors.h b/ldb-2.0.8/include/ldb_errors.h new file mode 100644 index 0000000..b247fbe --- /dev/null +++ b/ldb-2.0.8/include/ldb_errors.h @@ -0,0 +1,312 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2005 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb header + * + * Description: defines error codes following RFC 2251 ldap error codes + * + * Author: Simo Sorce + */ + +#ifndef _LDB_ERRORS_H_ + +/*! \cond DOXYGEN_IGNORE */ +#define _LDB_ERRORS_H_ 1 +/*! \endcond */ + +/** + \file ldb_errors.h + + This header provides a set of result codes for LDB function calls. + + Many LDB function calls return an integer value (int). As shown in + the function documentation, those return values may indicate + whether the function call worked correctly (in which case it + returns LDB_SUCCESS) or some problem occurred (in which case some + other value will be returned). As a special case, + LDB_ERR_COMPARE_FALSE or LDB_ERR_COMPARE_TRUE may be returned, + which does not indicate an error. + + \note Not all error codes make sense for LDB, however they are + based on the LDAP error codes, and are kept for reference and to + avoid overlap. + + \note Some of this documentation is based on information in + the OpenLDAP documentation, as developed and maintained by the + The OpenLDAP Project. + */ + +/** + The function call succeeded. + + If a function returns LDB_SUCCESS, then that function, and the + underlying transactions that may have been required, completed + successfully. +*/ +#define LDB_SUCCESS 0 + +/** + The function call failed for some non-specific reason. +*/ +#define LDB_ERR_OPERATIONS_ERROR 1 + +/** + The function call failed because of a protocol violation. +*/ +#define LDB_ERR_PROTOCOL_ERROR 2 + +/** + The function call failed because a time limit was exceeded. +*/ +#define LDB_ERR_TIME_LIMIT_EXCEEDED 3 + +/** + The function call failed because a size limit was exceeded. +*/ +#define LDB_ERR_SIZE_LIMIT_EXCEEDED 4 + +/** + The function was for value comparison, and the comparison operation + returned false. + + \note This is a status value, and doesn't normally indicate an + error. +*/ +#define LDB_ERR_COMPARE_FALSE 5 + +/** + The function was for value comparison, and the comparison operation + returned true. + + \note This is a status value, and doesn't normally indicate an + error. +*/ +#define LDB_ERR_COMPARE_TRUE 6 + +/** + The function used an authentication method that is not supported by + the database. +*/ +#define LDB_ERR_AUTH_METHOD_NOT_SUPPORTED 7 + +/** + The function call required a underlying operation that required + strong authentication. + + This will normally only occur if you are using LDB with a LDAP + backend. +*/ +#define LDB_ERR_STRONG_AUTH_REQUIRED 8 + +/* 9 RESERVED */ + +/** + The function resulted in a referral to another server. +*/ +#define LDB_ERR_REFERRAL 10 + +/** + The function failed because an administrative / policy limit was + exceeded. +*/ +#define LDB_ERR_ADMIN_LIMIT_EXCEEDED 11 + +/** + The function required an extension or capability that the + database cannot provide. +*/ +#define LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION 12 + +/** + The function involved a transaction or database operation that + could not be performed without a secure link. +*/ +#define LDB_ERR_CONFIDENTIALITY_REQUIRED 13 + +/** + This is an intermediate result code for SASL bind operations that + have more than one step. + + \note This is a result code that does not normally indicate an + error has occurred. +*/ +#define LDB_ERR_SASL_BIND_IN_PROGRESS 14 + +/** + The function referred to an attribute type that is not present in + the entry. +*/ +#define LDB_ERR_NO_SUCH_ATTRIBUTE 16 + +/** + The function referred to an attribute type that is invalid +*/ +#define LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE 17 + +/** + The function required a filter type that is not available for the + specified attribute. +*/ +#define LDB_ERR_INAPPROPRIATE_MATCHING 18 + +/** + The function would have violated an attribute constraint. +*/ +#define LDB_ERR_CONSTRAINT_VIOLATION 19 + +/** + The function involved an attribute type or attribute value that + already exists in the entry. +*/ +#define LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS 20 + +/** + The function used an invalid (incorrect syntax) attribute value. +*/ +#define LDB_ERR_INVALID_ATTRIBUTE_SYNTAX 21 + +/* 22-31 unused */ + +/** + The function referred to an object that does not exist in the + database. +*/ +#define LDB_ERR_NO_SUCH_OBJECT 32 + +/** + The function referred to an alias which points to a non-existent + object in the database. +*/ +#define LDB_ERR_ALIAS_PROBLEM 33 + +/** + The function used a DN which was invalid (incorrect syntax). +*/ +#define LDB_ERR_INVALID_DN_SYNTAX 34 + +/* 35 RESERVED */ + +/** + The function required dereferencing of an alias, and something went + wrong during the dereferencing process. +*/ +#define LDB_ERR_ALIAS_DEREFERENCING_PROBLEM 36 + +/* 37-47 unused */ + +/** + The function passed in the wrong authentication method. +*/ +#define LDB_ERR_INAPPROPRIATE_AUTHENTICATION 48 + +/** + The function passed in or referenced incorrect credentials during + authentication. +*/ +#define LDB_ERR_INVALID_CREDENTIALS 49 + +/** + The function required access permissions that the user does not + possess. +*/ +#define LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS 50 + +/** + The function required a transaction or call that the database could + not perform because it is busy. +*/ +#define LDB_ERR_BUSY 51 + +/** + The function required a transaction or call to a database that is + not available. +*/ +#define LDB_ERR_UNAVAILABLE 52 + +/** + The function required a transaction or call to a database that the + database declined to perform. +*/ +#define LDB_ERR_UNWILLING_TO_PERFORM 53 + +/** + The function failed because it resulted in a loop being detected. +*/ +#define LDB_ERR_LOOP_DETECT 54 + +/* 55-63 unused */ + +/** + The function failed because it would have violated a naming rule. +*/ +#define LDB_ERR_NAMING_VIOLATION 64 + +/** + The function failed because it would have violated the schema. +*/ +#define LDB_ERR_OBJECT_CLASS_VIOLATION 65 + +/** + The function required an operation that is only allowed on leaf + objects, but the object is not a leaf. +*/ +#define LDB_ERR_NOT_ALLOWED_ON_NON_LEAF 66 + +/** + The function required an operation that cannot be performed on a + Relative DN, but the object is a Relative DN. +*/ +#define LDB_ERR_NOT_ALLOWED_ON_RDN 67 + +/** + The function failed because the entry already exists. +*/ +#define LDB_ERR_ENTRY_ALREADY_EXISTS 68 + +/** + The function failed because modifications to an object class are + not allowable. +*/ +#define LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED 69 + +/* 70 RESERVED FOR CLDAP */ + +/** + The function failed because it needed to be applied to multiple + databases. +*/ +#define LDB_ERR_AFFECTS_MULTIPLE_DSAS 71 + +/* 72-79 unused */ + +/** + The function failed for unknown reasons. +*/ +#define LDB_ERR_OTHER 80 + +/* 81-90 RESERVED for APIs */ + +#endif /* _LDB_ERRORS_H_ */ diff --git a/ldb-2.0.8/include/ldb_handlers.h b/ldb-2.0.8/include/ldb_handlers.h new file mode 100644 index 0000000..79d8bb6 --- /dev/null +++ b/ldb-2.0.8/include/ldb_handlers.h @@ -0,0 +1,45 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2005 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb header + * + * Description: defines attribute handlers + * + * Author: Simo Sorce + */ +#ifndef __LDB_HANDLERS_H__ +#define __LDB_HANDLERS_H__ + +int ldb_handler_copy(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out); +int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out); +int ldb_comparison_binary(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, const struct ldb_val *v2); +int ldb_comparison_fold(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *v1, const struct ldb_val *v2); + +#endif /* __LDB_HANDLERS_H__ */ diff --git a/ldb-2.0.8/include/ldb_module.h b/ldb-2.0.8/include/ldb_module.h new file mode 100644 index 0000000..8c1e5ee --- /dev/null +++ b/ldb-2.0.8/include/ldb_module.h @@ -0,0 +1,595 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2008 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb module header + * + * Description: defines ldb modules structures and helpers + * + */ + +#ifndef _LDB_MODULE_H_ +#define _LDB_MODULE_H_ + +#include + +#if defined(_SAMBA_BUILD_) && defined(USING_SYSTEM_LDB) + +/* + * Versions before 1.2.0 doesn't define these values + * so we assime 1.1.29 (which was used in Samba 4.6) + * + * See https://bugzilla.samba.org/show_bug.cgi?id=12859 + */ +#ifndef EXPECTED_SYSTEM_LDB_VERSION_MAJOR +#define EXPECTED_SYSTEM_LDB_VERSION_MAJOR 1 +#endif +#ifndef EXPECTED_SYSTEM_LDB_VERSION_MINOR +#define EXPECTED_SYSTEM_LDB_VERSION_MINOR 1 +#endif +#ifndef EXPECTED_SYSTEM_LDB_VERSION_MINOR +#define EXPECTED_SYSTEM_LDB_VERSION_MINOR 29 +#endif + +/* + * Only Samba versions which expect ldb >= 1.4.0 + * reopen the ldb after each fork(). + * + * See https://bugzilla.samba.org/show_bug.cgi?id=13519 + */ +#if EXPECTED_SYSTEM_LDB_VERSION_MAJOR > 1 +#define __LDB_FORK_COMPATIBLE__ 1 +#elif EXPECTED_SYSTEM_LDB_VERSION_MINOR > 3 +#define __LDB_FORK_COMPATIBLE__ 1 +#endif +#ifndef __LDB_FORK_COMPATIBLE__ +#error "Samba < 4.9 is not compatible with this version of ldb due to assumptions around fork() behaviour" +#endif + +#endif /* defined(_SAMBA_BUILD_) && defined(USING_SYSTEM_LDB) */ + +struct ldb_context; +struct ldb_module; + +/** + internal flag bits on message elements. Must be within LDB_FLAG_INTERNAL_MASK + */ +#define LDB_FLAG_INTERNAL_DISABLE_VALIDATION 0x10 + +/* disable any single value checking on this attribute */ +#define LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK 0x20 + +/* attribute has failed access check and must not be exposed */ +#define LDB_FLAG_INTERNAL_INACCESSIBLE_ATTRIBUTE 0x40 + +/* force single value checking on this attribute */ +#define LDB_FLAG_INTERNAL_FORCE_SINGLE_VALUE_CHECK 0x80 + +/* + * ensure that this value is unique on an index + * (despite the index not otherwise being configured as UNIQUE). + * For example, all words starting with 'a' must be unique, but duplicates of + * words starting with b are allowed. This is specifically for Samba's + * objectSid index which is unique in the primary domain only. + */ +#define LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX 0x100 + +/* an extended match rule that always fails to match */ +#define SAMBA_LDAP_MATCH_ALWAYS_FALSE "1.3.6.1.4.1.7165.4.5.1" + +/* The const char * const * pointer to a list of secret (password) + * attributes, not to be printed in trace messages */ +#define LDB_SECRET_ATTRIBUTE_LIST_OPAQUE "LDB_SECRET_ATTRIBUTE_LIST" + +/* + * The scheme to be used for referral entries, i.e. ldap or ldaps + */ +#define LDAP_REFERRAL_SCHEME_OPAQUE "LDAP_REFERRAL_SCHEME" + +/* + these function pointers define the operations that a ldb module can intercept +*/ +struct ldb_module_ops { + const char *name; + int (*init_context) (struct ldb_module *); + int (*search)(struct ldb_module *, struct ldb_request *); /* search */ + int (*add)(struct ldb_module *, struct ldb_request *); /* add */ + int (*modify)(struct ldb_module *, struct ldb_request *); /* modify */ + int (*del)(struct ldb_module *, struct ldb_request *); /* delete */ + int (*rename)(struct ldb_module *, struct ldb_request *); /* rename */ + int (*request)(struct ldb_module *, struct ldb_request *); /* match any other operation */ + int (*extended)(struct ldb_module *, struct ldb_request *); /* extended operations */ + int (*start_transaction)(struct ldb_module *); + int (*prepare_commit)(struct ldb_module *); + int (*end_transaction)(struct ldb_module *); + int (*del_transaction)(struct ldb_module *); + int (*sequence_number)(struct ldb_module *, struct ldb_request *); + int (*read_lock)(struct ldb_module *); + int (*read_unlock)(struct ldb_module *); + void *private_data; +}; + + +/* The following definitions come from lib/ldb/common/ldb_debug.c */ +void ldb_debug(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); +void ldb_debug_set(struct ldb_context *ldb, enum ldb_debug_level level, + const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); +void ldb_debug_add(struct ldb_context *ldb, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); +void ldb_debug_end(struct ldb_context *ldb, enum ldb_debug_level level); +void ldb_vdebug(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0); + +#define ldb_error(ldb, ecode, reason) ldb_error_at(ldb, ecode, reason, __FILE__, __LINE__) +#define ldb_module_error(module, ecode, reason) ldb_error_at(ldb_module_get_ctx(module), ecode, reason, __FILE__, __LINE__) + +#define ldb_oom(ldb) ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "ldb out of memory") +#define ldb_module_oom(module) ldb_oom(ldb_module_get_ctx(module)) +#define ldb_operr(ldb) ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "operations error") +#define ldb_module_operr(module) ldb_error(ldb_module_get_ctx(module), LDB_ERR_OPERATIONS_ERROR, "operations error") + +/* The following definitions come from lib/ldb/common/ldb.c */ + +void ldb_request_set_state(struct ldb_request *req, int state); +int ldb_request_get_status(struct ldb_request *req); + +unsigned int ldb_get_create_perms(struct ldb_context *ldb); + +const struct ldb_schema_syntax *ldb_standard_syntax_by_name(struct ldb_context *ldb, + const char *syntax); + +/* The following definitions come from lib/ldb/common/ldb_attributes.c */ + +int ldb_schema_attribute_add_with_syntax(struct ldb_context *ldb, + const char *name, + unsigned flags, + const struct ldb_schema_syntax *syntax); +int ldb_schema_attribute_add(struct ldb_context *ldb, + const char *name, + unsigned flags, + const char *syntax); +void ldb_schema_attribute_remove(struct ldb_context *ldb, const char *name); + +/* we allow external code to override the name -> schema_attribute function */ +typedef const struct ldb_schema_attribute *(*ldb_attribute_handler_override_fn_t)(struct ldb_context *, void *, const char *); + +/** + Allow the caller to define a callback for the attribute handler + + \param ldb The ldb context + \param override The callback to be used for attribute lookups + \param private_data Private data for the callback + +*/ +void ldb_schema_attribute_set_override_handler(struct ldb_context *ldb, + ldb_attribute_handler_override_fn_t override, + void *private_data); + +/** + Allow the caller to define that the callback for the attribute handler + also overrides the index list + + \param ldb The ldb context + \param one_level_indexes Indicates that the index for SCOPE_ONELEVEL + should also be maintained + +*/ +void ldb_schema_set_override_indexlist(struct ldb_context *ldb, + bool one_level_indexes); + +/** + + \param ldb The ldb context + \param GUID_index_attribute The globally attribute (eg objectGUID) + on each entry + \param GUID_index_attribute The DN component matching the + globally attribute on each entry (eg GUID) + + The caller must ensure the supplied strings do not go out of + scope (they are typically constant memory). + +*/ +void ldb_schema_set_override_GUID_index(struct ldb_context *ldb, + const char *GUID_index_attribute, + const char *GUID_index_dn_component); + +/* A useful function to build comparison functions with */ +int ldb_any_comparison(struct ldb_context *ldb, void *mem_ctx, + ldb_attr_handler_t canonicalise_fn, + const struct ldb_val *v1, + const struct ldb_val *v2); + +/* The following definitions come from lib/ldb/common/ldb_controls.c */ +int ldb_save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver); +/* Returns a list of controls, except the one specified. Included + * controls become a child of returned list if they were children of + * controls_in */ +struct ldb_control **ldb_controls_except_specified(struct ldb_control **controls_in, + TALLOC_CTX *mem_ctx, + struct ldb_control *exclude); +int ldb_check_critical_controls(struct ldb_control **controls); + +/* The following definitions come from lib/ldb/common/ldb_ldif.c */ +int ldb_should_b64_encode(struct ldb_context *ldb, const struct ldb_val *val); + +/* The following definitions come from lib/ldb/common/ldb_match.c */ +int ldb_match_msg(struct ldb_context *ldb, + const struct ldb_message *msg, + const struct ldb_parse_tree *tree, + struct ldb_dn *base, + enum ldb_scope scope); + +int ldb_match_msg_error(struct ldb_context *ldb, + const struct ldb_message *msg, + const struct ldb_parse_tree *tree, + struct ldb_dn *base, + enum ldb_scope scope, + bool *matched); + +int ldb_match_msg_objectclass(const struct ldb_message *msg, + const char *objectclass); + +int ldb_register_extended_match_rules(struct ldb_context *ldb); + +/* The following definitions come from lib/ldb/common/ldb_modules.c */ + +struct ldb_module *ldb_module_new(TALLOC_CTX *memctx, + struct ldb_context *ldb, + const char *module_name, + const struct ldb_module_ops *ops); + +const char * ldb_module_get_name(struct ldb_module *module); +struct ldb_context *ldb_module_get_ctx(struct ldb_module *module); +void *ldb_module_get_private(struct ldb_module *module); +void ldb_module_set_private(struct ldb_module *module, void *private_data); +const struct ldb_module_ops *ldb_module_get_ops(struct ldb_module *module); + +int ldb_next_request(struct ldb_module *module, struct ldb_request *request); +int ldb_next_start_trans(struct ldb_module *module); +int ldb_next_end_trans(struct ldb_module *module); +int ldb_next_del_trans(struct ldb_module *module); +int ldb_next_prepare_commit(struct ldb_module *module); +int ldb_next_init(struct ldb_module *module); +int ldb_next_read_lock(struct ldb_module *module); +int ldb_next_read_unlock(struct ldb_module *module); + +void ldb_set_errstring(struct ldb_context *ldb, const char *err_string); +void ldb_asprintf_errstring(struct ldb_context *ldb, const char *format, ...) PRINTF_ATTRIBUTE(2,3); +void ldb_reset_err_string(struct ldb_context *ldb); +int ldb_error_at(struct ldb_context *ldb, int ecode, const char *reason, const char *file, int line); + +const char *ldb_default_modules_dir(void); + +int ldb_register_module(const struct ldb_module_ops *); + +typedef int (*ldb_connect_fn)(struct ldb_context *ldb, const char *url, + unsigned int flags, const char *options[], + struct ldb_module **module); + +/** + Require that LDB use a private event context for each request + + A private event context may need to be created to avoid nested event + loops during ldb_tdb with the locks held. This indicates that a + backend is in use that requires this to hold locks safely. + + \param handle The ldb handle to set the flag on + */ +void ldb_set_require_private_event_context(struct ldb_context *ldb); + +struct ldb_backend_ops { + const char *name; + ldb_connect_fn connect_fn; +}; + +const char *ldb_default_modules_dir(void); + +int ldb_register_backend(const char *url_prefix, ldb_connect_fn, bool); + +struct ldb_handle *ldb_handle_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb); + +/** + Obtains the private event context for the handle, + + A private event context may have been created to avoid nested event + loops during ldb_tdb with the locks held. Otherwise return the + global one. + + \param handle The ldb handle to obtain the event context for + \return the tevent event context for this handle (private or global) + */ +struct tevent_context *ldb_handle_get_event_context(struct ldb_handle *handle); + +int ldb_module_send_entry(struct ldb_request *req, + struct ldb_message *msg, + struct ldb_control **ctrls); + +int ldb_module_send_referral(struct ldb_request *req, + char *ref); + +int ldb_module_done(struct ldb_request *req, + struct ldb_control **ctrls, + struct ldb_extended *response, + int error); + +int ldb_mod_register_control(struct ldb_module *module, const char *oid); + +void ldb_set_default_dns(struct ldb_context *ldb); +/** + Add a ldb_control to a ldb_reply + + \param ares the reply struct where to add the control + \param oid the object identifier of the control as string + \param critical whether the control should be critical or not + \param data a talloc pointer to the control specific data + + \return result code (LDB_SUCCESS on success, or a failure code) +*/ +int ldb_reply_add_control(struct ldb_reply *ares, const char *oid, bool critical, void *data); + +/** + mark a request as untrusted. + + This tells the rootdse module to remove unregistered controls + + \param req the request to mark as untrusted +*/ +void ldb_req_mark_untrusted(struct ldb_request *req); + +/** + mark a request as trusted. + + This tells the rootdse module to allow unregistered controls + + \param req the request to mark as trusted +*/ +void ldb_req_mark_trusted(struct ldb_request *req); + +/** + return true is a request is untrusted + + This indicates the request came across a trust boundary + for example over LDAP + + \param req the request check + \return is req trusted +*/ +bool ldb_req_is_untrusted(struct ldb_request *req); + +/** + set custom flags. Those flags are set by applications using ldb, + they are application dependent and the same bit can have different + meaning in different application. + */ +void ldb_req_set_custom_flags(struct ldb_request *req, uint32_t flags); + +/** + get custom flags. Those flags are set by applications using ldb, + they are application dependent and the same bit can have different + meaning in different application. + */ +uint32_t ldb_req_get_custom_flags(struct ldb_request *req); + +/* load all modules from the given directory */ +int ldb_modules_load(const char *modules_path, const char *version); + +/* init functions prototype */ +typedef int (*ldb_module_init_fn)(const char *); + +/* + general ldb hook function + */ +enum ldb_module_hook_type { LDB_MODULE_HOOK_CMDLINE_OPTIONS = 1, + LDB_MODULE_HOOK_CMDLINE_PRECONNECT = 2, + LDB_MODULE_HOOK_CMDLINE_POSTCONNECT = 3 }; + +typedef int (*ldb_hook_fn)(struct ldb_context *, enum ldb_module_hook_type ); + +/* + register a ldb hook function + */ +int ldb_register_hook(ldb_hook_fn hook_fn); + +/* + call ldb hooks of a given type + */ +int ldb_modules_hook(struct ldb_context *ldb, enum ldb_module_hook_type t); + +#define LDB_MODULE_CHECK_VERSION(version) do { \ + if (strcmp(version, LDB_VERSION) != 0) { \ + fprintf(stderr, "ldb: module version mismatch in %s : ldb_version=%s module_version=%s\n", \ + __FILE__, version, LDB_VERSION); \ + return LDB_ERR_UNAVAILABLE; \ + }} while (0) + + +/* + return a string representation of the calling chain for the given + ldb request + */ +char *ldb_module_call_chain(struct ldb_request *req, TALLOC_CTX *mem_ctx); + +/* + return the next module in the chain + */ +struct ldb_module *ldb_module_next(struct ldb_module *module); + +/* + set the next module in the module chain + */ +void ldb_module_set_next(struct ldb_module *module, struct ldb_module *next); + +/* + load a list of modules + */ +int ldb_module_load_list(struct ldb_context *ldb, const char **module_list, + struct ldb_module *backend, struct ldb_module **out); + +/* + get the popt_options pointer in the ldb structure. This allows a ldb + module to change the command line parsing + */ +struct poptOption **ldb_module_popt_options(struct ldb_context *ldb); + +/* modules are called in inverse order on the stack. + Lets place them as an admin would think the right order is. + Modules order is important */ +const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string); + +/* + return the current ldb flags LDB_FLG_* + */ +uint32_t ldb_module_flags(struct ldb_context *ldb); + +int ldb_module_connect_backend(struct ldb_context *ldb, + const char *url, + const char *options[], + struct ldb_module **backend_module); + +/* + initialise a chain of modules + */ +int ldb_module_init_chain(struct ldb_context *ldb, struct ldb_module *module); + +/* + * prototype for the init function defined by dynamically loaded modules + */ +int ldb_init_module(const char *version); + +/* replace the components of a DN with those from another DN, without + * touching the extended components + * + * return true if successful and false if not + * if false is returned the dn may be marked invalid + */ +bool ldb_dn_replace_components(struct ldb_dn *dn, struct ldb_dn *new_dn); + +/* + walk a parse tree, calling the provided callback on each node +*/ +int ldb_parse_tree_walk(struct ldb_parse_tree *tree, + int (*callback)(struct ldb_parse_tree *tree, void *), + void *private_context); + +/* compare two message elements with ordering - used by modify */ +bool ldb_msg_element_equal_ordered(const struct ldb_message_element *el1, + const struct ldb_message_element *el2); + + +struct ldb_extended_match_rule +{ + const char *oid; + int (*callback)(struct ldb_context *, const char *oid, + const struct ldb_message *, const char *, + const struct ldb_val *, bool *); +}; + +int ldb_register_extended_match_rule(struct ldb_context *ldb, + const struct ldb_extended_match_rule *rule); + +/* + * these pack/unpack functions are exposed in the library for use by + * ldb tools like ldbdump and for use in tests, + * but are not part of the public API + */ +int ldb_pack_data(struct ldb_context *ldb, + const struct ldb_message *message, + struct ldb_val *data, + uint32_t pack_format_version); +/* + * Unpack a ldb message from a linear buffer in ldb_val + */ +int ldb_unpack_data(struct ldb_context *ldb, + const struct ldb_val *data, + struct ldb_message *message); + +/* + * filter the specified list of attributes from msg, + * adding requested attributes, and perhaps all for *, + * but not the DN to filtered_msg. + */ +int ldb_filter_attrs(struct ldb_context *ldb, + const struct ldb_message *msg, + const char *const *attrs, + struct ldb_message *filtered_msg); +/* + * Unpack a ldb message from a linear buffer in ldb_val + * + * If LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC is specified, then values + * array are not allocated individually (for single-valued + * attributes), instead they point into a single buffer per message. + * + * Likewise if LDB_UNPACK_DATA_FLAG_NO_DN is specified, the DN is omitted. + * + * If LDB_UNPACK_DATA_FLAG_NO_ATTRS is specified, then no attributes + * are unpacked or returned. + * + */ +int ldb_unpack_data_flags(struct ldb_context *ldb, + const struct ldb_val *data, + struct ldb_message *message, + unsigned int flags); + +int ldb_unpack_get_format(const struct ldb_val *data, + uint32_t *pack_format_version); + +/* currently unused (was NO_DATA_ALLOC) 0x0001 */ +#define LDB_UNPACK_DATA_FLAG_NO_DN 0x0002 +#define LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC 0x0004 +#define LDB_UNPACK_DATA_FLAG_NO_ATTRS 0x0008 +#define LDB_UNPACK_DATA_FLAG_READ_LOCKED 0x0010 + +enum ldb_pack_format { + + /* Old packing format (based on a somewhat arbitrary date) */ + LDB_PACKING_FORMAT_NODN = 0x26011966, + + /* In-use packing formats */ + LDB_PACKING_FORMAT, + LDB_PACKING_FORMAT_V2 +}; + +/** + Forces a specific ldb handle to use the global event context. + + This allows a nested event loop to operate, so any open + transaction also needs to be aborted. + + Any events on this event context will be lost. + + This is used in Samba when sending an IRPC to another part of the + same process instead of making a local DB modification. + + \param handle The ldb handle to force to use the global context + + */ +void ldb_handle_use_global_event_context(struct ldb_handle *handle); + +/** + * Get the options passed to ldb_connect. + * + * This allows the options to be inspected by elements in the module stack + * + */ +const char **ldb_options_get(struct ldb_context *ldb); +#endif diff --git a/ldb-2.0.8/include/ldb_private.h b/ldb-2.0.8/include/ldb_private.h new file mode 100644 index 0000000..4deb246 --- /dev/null +++ b/ldb-2.0.8/include/ldb_private.h @@ -0,0 +1,320 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 2004-2005 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb private header + * + * Description: defines internal ldb structures used by the subsystem and modules + * + * Author: Andrew Tridgell + * Author: Stefan Metzmacher + */ + +#ifndef _LDB_PRIVATE_H_ +#define _LDB_PRIVATE_H_ 1 + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb.h" +#include "ldb_module.h" + +struct ldb_context; + +struct ldb_module_ops; + +struct ldb_backend_ops; + +#define LDB_HANDLE_FLAG_DONE_CALLED 1 +/* call is from an untrusted source - eg. over ldap:// */ +#define LDB_HANDLE_FLAG_UNTRUSTED 2 + +struct ldb_handle { + int status; + enum ldb_state state; + struct ldb_context *ldb; + unsigned flags; + /* flags dedicated to be set by application using ldb */ + uint32_t custom_flags; + unsigned nesting; + + /* Private event context (if not NULL) */ + struct tevent_context *event_context; + + /* used for debugging */ + struct ldb_request *parent; + const char *location; +}; + +/* basic module structure */ +struct ldb_module { + struct ldb_module *prev, *next; + struct ldb_context *ldb; + void *private_data; + const struct ldb_module_ops *ops; +}; + +/* + schema related information needed for matching rules +*/ +struct ldb_schema { + void *attribute_handler_override_private; + ldb_attribute_handler_override_fn_t attribute_handler_override; + + /* attribute handling table */ + unsigned num_attributes; + struct ldb_schema_attribute *attributes; + + unsigned num_dn_extended_syntax; + struct ldb_dn_extended_syntax *dn_extended_syntax; + + /* + * If set, the attribute_handler_override has the details of + * what attributes have an index + */ + bool index_handler_override; + bool one_level_indexes; + + const char *GUID_index_attribute; + const char *GUID_index_dn_component; +}; + +/* + every ldb connection is started by establishing a ldb_context +*/ +struct ldb_context { + /* the operations provided by the backend */ + struct ldb_module *modules; + + /* debugging operations */ + struct ldb_debug_ops debug_ops; + + /* extended matching rules */ + struct ldb_extended_match_entry { + const struct ldb_extended_match_rule *rule; + struct ldb_extended_match_entry *prev, *next; + } *extended_match_rules; + + /* custom utf8 functions */ + struct ldb_utf8_fns utf8_fns; + + /* backend specific opaque parameters */ + struct ldb_opaque { + struct ldb_opaque *next; + const char *name; + void *value; + } *opaque; + + struct ldb_schema schema; + + char *err_string; + + int transaction_active; + + int default_timeout; + + unsigned int flags; + + unsigned int create_perms; + + struct tevent_context *ev_ctx; + + /* + * If the backend holds locks, we must not use a global event + * context, so this flag will be set and ldb_handle_new() will + * build a new event context + */ + bool require_private_event_context; + + bool prepare_commit_done; + + char *partial_debug; + + struct poptOption *popt_options; + + /* + * The ldb options passed to ldb_connect + * A NULL terminated array of zero terminated strings + */ + const char **options; +}; + +/* The following definitions come from lib/ldb/common/ldb.c */ + +extern const struct ldb_module_ops ldb_objectclass_module_ops; +extern const struct ldb_module_ops ldb_paged_results_module_ops; +extern const struct ldb_module_ops ldb_rdn_name_module_ops; +extern const struct ldb_module_ops ldb_schema_module_ops; +extern const struct ldb_module_ops ldb_asq_module_ops; +extern const struct ldb_module_ops ldb_server_sort_module_ops; +extern const struct ldb_module_ops ldb_ldap_module_ops; +extern const struct ldb_module_ops ldb_ildap_module_ops; +extern const struct ldb_module_ops ldb_paged_searches_module_ops; +extern const struct ldb_module_ops ldb_tdb_module_ops; +extern const struct ldb_module_ops ldb_skel_module_ops; +extern const struct ldb_module_ops ldb_subtree_rename_module_ops; +extern const struct ldb_module_ops ldb_subtree_delete_module_ops; +extern const struct ldb_module_ops ldb_sqlite3_module_ops; +extern const struct ldb_module_ops ldb_wins_ldb_module_ops; +extern const struct ldb_module_ops ldb_ranged_results_module_ops; + +extern const struct ldb_backend_ops ldb_tdb_backend_ops; +extern const struct ldb_backend_ops ldb_sqlite3_backend_ops; +extern const struct ldb_backend_ops ldb_ldap_backend_ops; +extern const struct ldb_backend_ops ldb_ldapi_backend_ops; +extern const struct ldb_backend_ops ldb_ldaps_backend_ops; + +int ldb_setup_wellknown_attributes(struct ldb_context *ldb); +/* + remove attributes with a specified flag (eg LDB_ATTR_FLAG_FROM_DB) for this ldb context + + This is to permit correct reloads +*/ +void ldb_schema_attribute_remove_flagged(struct ldb_context *ldb, unsigned int flag); +int ldb_schema_attribute_fill_with_syntax(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const char *attribute, + unsigned flags, + const struct ldb_schema_syntax *syntax, + struct ldb_schema_attribute *a); + +const char **ldb_subclass_list(struct ldb_context *ldb, const char *classname); +void ldb_subclass_remove(struct ldb_context *ldb, const char *classname); +int ldb_subclass_add(struct ldb_context *ldb, const char *classname, const char *subclass); + +/* The following definitions come from lib/ldb/common/ldb_utf8.c */ +char *ldb_casefold_default(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n); + +void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *f); + + +/* The following definitions come from lib/ldb/common/ldb_modules.c */ + +const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string); +int ldb_load_modules(struct ldb_context *ldb, const char *options[]); + +struct ldb_val ldb_binary_decode(TALLOC_CTX *mem_ctx, const char *str); + + +/* The following definitions come from lib/ldb/common/ldb_options.c */ + +const char *ldb_options_find(struct ldb_context *ldb, const char *options[], + const char *option_name); +const char **ldb_options_copy(TALLOC_CTX *ctx, const char *options[]); + +/* The following definitions come from lib/ldb/common/ldb_ldif.c */ + +struct ldif_read_file_state { + FILE *f; + size_t line_no; +}; + +struct ldb_ldif *ldb_ldif_read_file_state(struct ldb_context *ldb, + struct ldif_read_file_state *state); + +char *ldb_ldif_write_redacted_trace_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + const struct ldb_ldif *ldif); + +/* + * Get the LDB context in use on an LDB DN. + * + * This is helpful to the python LDB code, which may use as part of + * adding base and child components to an existing DN. + */ +struct ldb_context *ldb_dn_get_ldb_context(struct ldb_dn *dn); + +#define LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES 1 + +/** + Determine whether any values in an element are also in another element, + and optionally fix that. + + \param ldb an ldb context + \param mem_ctx a talloc context + \param el an element + \param other_el another element + \param options flags controlling the function behaviour + + Without the LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES flag, return + LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS if the elements share values, and + LDB_SUCCESS if they don't. That is, determine whether there is an + intersection without changing anything. + + With the LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES flag, any values in common + are removed from the first element and LDB_SUCCESS is returned. + + LDB_ERR_OPERATIONS_ERROR indicates an allocation failure or an unknown option. + LDB_ERR_INAPPROPRIATE_MATCHING means the elements differ in name. +*/ + +int ldb_msg_find_common_values(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_message_element *el, + struct ldb_message_element *other_el, + uint32_t options); + +/** + Detect whether an element contains duplicate values + + \param ldb a currently unused ldb_context struct + \param mem_ctx a talloc context + \param el the element to search + \param duplicate will point to a duplicate value if there are duplicates, + or NULL otherwise. + \param options is a flags field. All values are reserved. + + \return an ldb error code. LDB_ERR_OPERATIONS_ERROR indicates an allocation + failure or an unknown option flag. Otherwise LDB_SUCCESS. + + \note This search is case sensitive +*/ +int ldb_msg_find_duplicate_val(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + const struct ldb_message_element *el, + struct ldb_val **duplicate, + uint32_t options); +/** + Check if a particular message will match the given filter + + \param ldb an ldb context + \param msg the message to be checked + \param tree the filter tree to check against + \param scope the scope to match against + (to avoid matching special DNs except on a base search) + \param matched a pointer to a boolean set true if it matches, + false otherwise + + returns LDB_SUCCESS or an error + + \note this is a recursive function, and does short-circuit evaluation + */ +int ldb_match_message(struct ldb_context *ldb, + const struct ldb_message *msg, + const struct ldb_parse_tree *tree, + enum ldb_scope scope, bool *matched); + +#endif diff --git a/ldb-2.0.8/ldb.pc.in b/ldb-2.0.8/ldb.pc.in new file mode 100644 index 0000000..aeba17a --- /dev/null +++ b/ldb-2.0.8/ldb.pc.in @@ -0,0 +1,16 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +modulesdir=@LDB_MODULESDIR@ + +Name: ldb +Description: An LDAP-like embedded database +Version: @PACKAGE_VERSION@ +Requires.private: tdb +Requires: talloc +Libs: @LIB_RPATH@ -L${libdir} -lldb +Libs.private: @LDAP_LIBS@ +Cflags: -I${includedir} +Modulesdir: ${modulesdir} +URL: http://ldb.samba.org/ diff --git a/ldb-2.0.8/ldb_key_value/ldb_kv.c b/ldb-2.0.8/ldb_key_value/ldb_kv.c new file mode 100644 index 0000000..4e7b8a1 --- /dev/null +++ b/ldb-2.0.8/ldb_key_value/ldb_kv.c @@ -0,0 +1,2292 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 2006-2008 + Copyright (C) Matthias Dieter Wallnöfer 2009-2010 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb_kv + * + * Component: ldb key value backend + * + * Description: core functions for ldb key value backend + * + * Author: Andrew Tridgell + * Author: Stefan Metzmacher + * + * Modifications: + * + * - description: make the module use asynchronous calls + * date: Feb 2006 + * Author: Simo Sorce + * + * - description: make it possible to use event contexts + * date: Jan 2008 + * Author: Simo Sorce + * + * - description: fix up memory leaks and small bugs + * date: Oct 2009 + * Author: Matthias Dieter Wallnöfer + */ + +#include "ldb_kv.h" +#include "ldb_private.h" +#include "lib/util/attr.h" + +/* + prevent memory errors on callbacks +*/ +struct ldb_kv_req_spy { + struct ldb_kv_context *ctx; +}; + +/* + * Determine if this key could hold a record. We allow the new GUID + * index, the old DN index and a possible future ID= + */ +bool ldb_kv_key_is_normal_record(struct ldb_val key) +{ + if (key.length < 4) { + return false; + } + + /* + * @ records are not normal records, we don't want to index + * them nor search on them + */ + if (key.length > 4 && + memcmp(key.data, "DN=@", 4) == 0) { + return false; + } + + /* All other DN= records are however */ + if (memcmp(key.data, "DN=", 3) == 0) { + return true; + } + + if (memcmp(key.data, "ID=", 3) == 0) { + return true; + } + + if (key.length < sizeof(LDB_KV_GUID_KEY_PREFIX)) { + return false; + } + + if (memcmp(key.data, LDB_KV_GUID_KEY_PREFIX, + sizeof(LDB_KV_GUID_KEY_PREFIX) - 1) == 0) { + return true; + } + + return false; +} + +/* + form a ldb_val for a record key + caller frees + + note that the key for a record can depend on whether the + dn refers to a case sensitive index record or not +*/ +struct ldb_val ldb_kv_key_dn(TALLOC_CTX *mem_ctx, + struct ldb_dn *dn) +{ + struct ldb_val key; + char *key_str = NULL; + const char *dn_folded = NULL; + + /* + most DNs are case insensitive. The exception is index DNs for + case sensitive attributes + + there are 3 cases dealt with in this code: + + 1) if the dn doesn't start with @ then uppercase the attribute + names and the attributes values of case insensitive attributes + 2) if the dn starts with @ then leave it alone - + the indexing code handles the rest + */ + + dn_folded = ldb_dn_get_casefold(dn); + if (!dn_folded) { + goto failed; + } + + key_str = talloc_strdup(mem_ctx, "DN="); + if (!key_str) { + goto failed; + } + + key_str = talloc_strdup_append_buffer(key_str, dn_folded); + if (!key_str) { + goto failed; + } + + key.data = (uint8_t *)key_str; + key.length = strlen(key_str) + 1; + + return key; + +failed: + errno = ENOMEM; + key.data = NULL; + key.length = 0; + return key; +} + +/* The caller is to provide a correctly sized key */ +int ldb_kv_guid_to_key(const struct ldb_val *GUID_val, + struct ldb_val *key) +{ + const char *GUID_prefix = LDB_KV_GUID_KEY_PREFIX; + const int GUID_prefix_len = sizeof(LDB_KV_GUID_KEY_PREFIX) - 1; + + if (key->length != (GUID_val->length+GUID_prefix_len)) { + return LDB_ERR_OPERATIONS_ERROR; + } + + memcpy(key->data, GUID_prefix, GUID_prefix_len); + memcpy(&key->data[GUID_prefix_len], + GUID_val->data, GUID_val->length); + return LDB_SUCCESS; +} + +/* + * The caller is to provide a correctly sized key, used only in + * the GUID index mode + */ +int ldb_kv_idx_to_key(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + TALLOC_CTX *mem_ctx, + const struct ldb_val *idx_val, + struct ldb_val *key) +{ + struct ldb_context *ldb = ldb_module_get_ctx(module); + struct ldb_dn *dn; + + if (ldb_kv->cache->GUID_index_attribute != NULL) { + return ldb_kv_guid_to_key(idx_val, key); + } + + dn = ldb_dn_from_ldb_val(mem_ctx, ldb, idx_val); + if (dn == NULL) { + /* + * LDB_ERR_INVALID_DN_SYNTAX would just be confusing + * to the caller, as this in an invalid index value + */ + return LDB_ERR_OPERATIONS_ERROR; + } + /* form the key */ + *key = ldb_kv_key_dn(mem_ctx, dn); + TALLOC_FREE(dn); + if (!key->data) { + return ldb_module_oom(module); + } + return LDB_SUCCESS; +} + +/* + form a TDB_DATA for a record key + caller frees mem_ctx, which may or may not have the key + as a child. + + note that the key for a record can depend on whether a + GUID index is in use, or the DN is used as the key +*/ +struct ldb_val ldb_kv_key_msg(struct ldb_module *module, + TALLOC_CTX *mem_ctx, + const struct ldb_message *msg) +{ + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + struct ldb_val key; + const struct ldb_val *guid_val; + int ret; + + if (ldb_kv->cache->GUID_index_attribute == NULL) { + return ldb_kv_key_dn(mem_ctx, msg->dn); + } + + if (ldb_dn_is_special(msg->dn)) { + return ldb_kv_key_dn(mem_ctx, msg->dn); + } + + guid_val = + ldb_msg_find_ldb_val(msg, ldb_kv->cache->GUID_index_attribute); + if (guid_val == NULL) { + ldb_asprintf_errstring(ldb_module_get_ctx(module), + "Did not find GUID attribute %s " + "in %s, required for TDB record " + "key in " LDB_KV_IDXGUID " mode.", + ldb_kv->cache->GUID_index_attribute, + ldb_dn_get_linearized(msg->dn)); + errno = EINVAL; + key.data = NULL; + key.length = 0; + return key; + } + + /* In this case, allocate with talloc */ + key.data = talloc_size(mem_ctx, LDB_KV_GUID_KEY_SIZE); + if (key.data == NULL) { + errno = ENOMEM; + key.data = NULL; + key.length = 0; + return key; + } + key.length = talloc_get_size(key.data); + + ret = ldb_kv_guid_to_key(guid_val, &key); + + if (ret != LDB_SUCCESS) { + errno = EINVAL; + key.data = NULL; + key.length = 0; + return key; + } + return key; +} + +/* + check special dn's have valid attributes + currently only @ATTRIBUTES is checked +*/ +static int ldb_kv_check_special_dn(struct ldb_module *module, + const struct ldb_message *msg) +{ + struct ldb_context *ldb = ldb_module_get_ctx(module); + unsigned int i, j; + + if (! ldb_dn_is_special(msg->dn) || + ! ldb_dn_check_special(msg->dn, LDB_KV_ATTRIBUTES)) { + return LDB_SUCCESS; + } + + /* we have @ATTRIBUTES, let's check attributes are fine */ + /* should we check that we deny multivalued attributes ? */ + for (i = 0; i < msg->num_elements; i++) { + if (ldb_attr_cmp(msg->elements[i].name, "distinguishedName") == 0) continue; + + for (j = 0; j < msg->elements[i].num_values; j++) { + if (ldb_kv_check_at_attributes_values( + &msg->elements[i].values[j]) != 0) { + ldb_set_errstring(ldb, "Invalid attribute value in an @ATTRIBUTES entry"); + return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; + } + } + } + + return LDB_SUCCESS; +} + +/* + * Called after modifies and when starting a transaction. Checks target pack + * format version and current pack format version, which are set by cache_load, + * and repacks if necessary. + */ +static int ldb_kv_maybe_repack(struct ldb_kv_private *ldb_kv) { + /* Override option taken from ldb options */ + if (ldb_kv->pack_format_override != 0) { + ldb_kv->target_pack_format_version = + ldb_kv->pack_format_override; + } + + if (ldb_kv->pack_format_version != + ldb_kv->target_pack_format_version) { + int r; + struct ldb_context *ldb = ldb_module_get_ctx(ldb_kv->module); + r = ldb_kv_repack(ldb_kv->module); + if (r != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Database repack failed."); + } + return r; + } + + return LDB_SUCCESS; +} + +/* + we've made a modification to a dn - possibly reindex and + update sequence number +*/ +static int ldb_kv_modified(struct ldb_module *module, struct ldb_dn *dn) +{ + int ret = LDB_SUCCESS; + struct ldb_kv_private *ldb_kv = talloc_get_type( + ldb_module_get_private(module), struct ldb_kv_private); + + /* only allow modifies inside a transaction, otherwise the + * ldb is unsafe */ + if (ldb_kv->kv_ops->transaction_active(ldb_kv) == false) { + ldb_set_errstring(ldb_module_get_ctx(module), "ltdb modify without transaction"); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (ldb_dn_is_special(dn) && + (ldb_dn_check_special(dn, LDB_KV_INDEXLIST) || + ldb_dn_check_special(dn, LDB_KV_ATTRIBUTES)) ) + { + if (ldb_kv->warn_reindex) { + ldb_debug(ldb_module_get_ctx(module), + LDB_DEBUG_ERROR, + "Reindexing %s due to modification on %s", + ldb_kv->kv_ops->name(ldb_kv), + ldb_dn_get_linearized(dn)); + } + ret = ldb_kv_reindex(module); + } + + /* If the modify was to a normal record, or any special except @BASEINFO, update the seq number */ + if (ret == LDB_SUCCESS && + !(ldb_dn_is_special(dn) && + ldb_dn_check_special(dn, LDB_KV_BASEINFO)) ) { + ret = ldb_kv_increase_sequence_number(module); + } + + /* If the modify was to @OPTIONS, reload the cache */ + if (ret == LDB_SUCCESS && + ldb_dn_is_special(dn) && + (ldb_dn_check_special(dn, LDB_KV_OPTIONS)) ) { + ret = ldb_kv_cache_reload(module); + } + + if (ret != LDB_SUCCESS) { + ldb_kv->reindex_failed = true; + } + + return ret; +} +/* + store a record into the db +*/ +int ldb_kv_store(struct ldb_module *module, + const struct ldb_message *msg, + int flgs) +{ + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + struct ldb_val key; + struct ldb_val ldb_data; + int ret = LDB_SUCCESS; + TALLOC_CTX *key_ctx = talloc_new(module); + + if (key_ctx == NULL) { + return ldb_module_oom(module); + } + + if (ldb_kv->read_only) { + talloc_free(key_ctx); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + key = ldb_kv_key_msg(module, key_ctx, msg); + if (key.data == NULL) { + TALLOC_FREE(key_ctx); + return LDB_ERR_OTHER; + } + + ret = ldb_pack_data(ldb_module_get_ctx(module), + msg, &ldb_data, + ldb_kv->pack_format_version); + if (ret == -1) { + TALLOC_FREE(key_ctx); + return LDB_ERR_OTHER; + } + + ret = ldb_kv->kv_ops->store(ldb_kv, key, ldb_data, flgs); + if (ret != 0) { + bool is_special = ldb_dn_is_special(msg->dn); + ret = ldb_kv->kv_ops->error(ldb_kv); + + /* + * LDB_ERR_ENTRY_ALREADY_EXISTS means the DN, not + * the GUID, so re-map + */ + if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS && !is_special && + ldb_kv->cache->GUID_index_attribute != NULL) { + ret = LDB_ERR_CONSTRAINT_VIOLATION; + } + goto done; + } + +done: + TALLOC_FREE(key_ctx); + talloc_free(ldb_data.data); + + return ret; +} + + +/* + check if a attribute is a single valued, for a given element + */ +static bool ldb_kv_single_valued(const struct ldb_schema_attribute *a, + struct ldb_message_element *el) +{ + if (!a) return false; + if (el != NULL) { + if (el->flags & LDB_FLAG_INTERNAL_FORCE_SINGLE_VALUE_CHECK) { + /* override from a ldb module, for example + used for the description field, which is + marked multi-valued in the schema but which + should not actually accept multiple + values */ + return true; + } + if (el->flags & LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK) { + /* override from a ldb module, for example used for + deleted linked attribute entries */ + return false; + } + } + if (a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) { + return true; + } + return false; +} + +/* + * Starts a sub transaction if they are supported by the backend + * and the ldb connection has not been opened in batch mode. + */ +static int ldb_kv_sub_transaction_start(struct ldb_kv_private *ldb_kv) +{ + int ret = LDB_SUCCESS; + + if (ldb_kv->batch_mode) { + return ret; + } + + ret = ldb_kv->kv_ops->begin_nested_write(ldb_kv); + if (ret == LDB_SUCCESS) { + ret = ldb_kv_index_sub_transaction_start(ldb_kv); + } + return ret; +} + +/* + * Commits a sub transaction if they are supported by the backend + * and the ldb connection has not been opened in batch mode. + */ +static int ldb_kv_sub_transaction_commit(struct ldb_kv_private *ldb_kv) +{ + int ret = LDB_SUCCESS; + + if (ldb_kv->batch_mode) { + return ret; + } + + ret = ldb_kv_index_sub_transaction_commit(ldb_kv); + if (ret != LDB_SUCCESS) { + return ret; + } + ret = ldb_kv->kv_ops->finish_nested_write(ldb_kv); + return ret; +} + +/* + * Cancels a sub transaction if they are supported by the backend + * and the ldb connection has not been opened in batch mode. + */ +static int ldb_kv_sub_transaction_cancel(struct ldb_kv_private *ldb_kv) +{ + int ret = LDB_SUCCESS; + + if (ldb_kv->batch_mode) { + return ret; + } + + ret = ldb_kv_index_sub_transaction_cancel(ldb_kv); + if (ret != LDB_SUCCESS) { + struct ldb_context *ldb = ldb_module_get_ctx(ldb_kv->module); + /* + * In the event of a failure we log the failure and continue + * as we need to cancel the database transaction. + */ + ldb_debug(ldb, + LDB_DEBUG_ERROR, + __location__": ldb_kv_index_sub_transaction_cancel " + "failed: %s", + ldb_errstring(ldb)); + } + ret = ldb_kv->kv_ops->abort_nested_write(ldb_kv); + return ret; +} + +static int ldb_kv_add_internal(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_message *msg, + bool check_single_value) +{ + struct ldb_context *ldb = ldb_module_get_ctx(module); + int ret = LDB_SUCCESS; + unsigned int i; + bool valid_dn = false; + + /* Check the new DN is reasonable */ + valid_dn = ldb_dn_validate(msg->dn); + if (valid_dn == false) { + ldb_asprintf_errstring(ldb_module_get_ctx(module), + "Invalid DN in ADD: %s", + ldb_dn_get_linearized(msg->dn)); + return LDB_ERR_INVALID_DN_SYNTAX; + } + + for (i=0;inum_elements;i++) { + struct ldb_message_element *el = &msg->elements[i]; + const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name); + + if (el->num_values == 0) { + ldb_asprintf_errstring(ldb, "attribute '%s' on '%s' specified, but with 0 values (illegal)", + el->name, ldb_dn_get_linearized(msg->dn)); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + if (check_single_value && el->num_values > 1 && + ldb_kv_single_valued(a, el)) { + ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", + el->name, ldb_dn_get_linearized(msg->dn)); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + /* Do not check "@ATTRIBUTES" for duplicated values */ + if (ldb_dn_is_special(msg->dn) && + ldb_dn_check_special(msg->dn, LDB_KV_ATTRIBUTES)) { + continue; + } + + if (check_single_value && + !(el->flags & + LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK)) { + struct ldb_val *duplicate = NULL; + + ret = ldb_msg_find_duplicate_val(ldb, discard_const(msg), + el, &duplicate, 0); + if (ret != LDB_SUCCESS) { + return ret; + } + if (duplicate != NULL) { + ldb_asprintf_errstring( + ldb, + "attribute '%s': value '%.*s' on '%s' " + "provided more than once in ADD object", + el->name, + (int)duplicate->length, + duplicate->data, + ldb_dn_get_linearized(msg->dn)); + return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + } + } + } + + ret = ldb_kv_store(module, msg, TDB_INSERT); + if (ret != LDB_SUCCESS) { + /* + * Try really hard to get the right error code for + * a re-add situation, as this can matter! + */ + if (ret == LDB_ERR_CONSTRAINT_VIOLATION) { + int ret2; + struct ldb_dn *dn2 = NULL; + TALLOC_CTX *mem_ctx = talloc_new(module); + if (mem_ctx == NULL) { + return ldb_module_operr(module); + } + ret2 = + ldb_kv_search_base(module, mem_ctx, msg->dn, &dn2); + TALLOC_FREE(mem_ctx); + if (ret2 == LDB_SUCCESS) { + ret = LDB_ERR_ENTRY_ALREADY_EXISTS; + } + } + if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { + ldb_asprintf_errstring(ldb, + "Entry %s already exists", + ldb_dn_get_linearized(msg->dn)); + } + return ret; + } + + ret = ldb_kv_index_add_new(module, ldb_kv, msg); + if (ret != LDB_SUCCESS) { + /* + * If we failed to index, delete the message again. + * + * This is particularly important for the GUID index + * case, which will only fail for a duplicate DN + * in the index add. + * + * Note that the caller may not cancel the transation + * and this means the above add might really show up! + */ + ldb_kv_delete_noindex(module, msg); + return ret; + } + + ret = ldb_kv_modified(module, msg->dn); + + /* + * To allow testing of the error recovery code in ldb_kv_add + * cmocka tests can define CMOCKA_UNIT_TEST_ADD_INTERNAL_FAIL + * to inject failures at this point. + */ +#ifdef CMOCKA_UNIT_TEST_ADD_INTERNAL_FAIL + CMOCKA_UNIT_TEST_ADD_INTERNAL_FAIL +#endif + + return ret; +} + +/* + add a record to the database +*/ +static int ldb_kv_add(struct ldb_kv_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + int ret = LDB_SUCCESS; + + if (ldb_kv->max_key_length != 0 && + ldb_kv->cache->GUID_index_attribute == NULL && + !ldb_dn_is_special(req->op.add.message->dn)) { + ldb_set_errstring(ldb_module_get_ctx(module), + "Must operate ldb_mdb in GUID " + "index mode, but " LDB_KV_IDXGUID " not set."); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + ret = ldb_kv_check_special_dn(module, req->op.add.message); + if (ret != LDB_SUCCESS) { + return ret; + } + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + if (ldb_kv_cache_load(module) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_kv_sub_transaction_start(ldb_kv); + if (ret != LDB_SUCCESS) { + return ret; + } + ret = ldb_kv_add_internal(module, ldb_kv, req->op.add.message, true); + if (ret != LDB_SUCCESS) { + int r = ldb_kv_sub_transaction_cancel(ldb_kv); + if (r != LDB_SUCCESS) { + ldb_debug( + ldb_module_get_ctx(module), + LDB_DEBUG_FATAL, + __location__ + ": Unable to roll back sub transaction"); + } + ldb_kv->operation_failed = true; + return ret; + } + ret = ldb_kv_sub_transaction_commit(ldb_kv); + + return ret; +} + +/* + delete a record from the database, not updating indexes (used for deleting + index records) +*/ +int ldb_kv_delete_noindex(struct ldb_module *module, + const struct ldb_message *msg) +{ + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + struct ldb_val key; + int ret; + TALLOC_CTX *tdb_key_ctx = talloc_new(module); + + if (tdb_key_ctx == NULL) { + return ldb_module_oom(module); + } + + if (ldb_kv->read_only) { + talloc_free(tdb_key_ctx); + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + key = ldb_kv_key_msg(module, tdb_key_ctx, msg); + if (!key.data) { + TALLOC_FREE(tdb_key_ctx); + return LDB_ERR_OTHER; + } + + ret = ldb_kv->kv_ops->delete(ldb_kv, key); + TALLOC_FREE(tdb_key_ctx); + + if (ret != 0) { + ret = ldb_kv->kv_ops->error(ldb_kv); + } + + return ret; +} + +static int ldb_kv_delete_internal(struct ldb_module *module, struct ldb_dn *dn) +{ + struct ldb_message *msg; + int ret = LDB_SUCCESS; + + msg = ldb_msg_new(module); + if (msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* in case any attribute of the message was indexed, we need + to fetch the old record */ + ret = ldb_kv_search_dn1(module, dn, msg, 0); + if (ret != LDB_SUCCESS) { + /* not finding the old record is an error */ + goto done; + } + + ret = ldb_kv_delete_noindex(module, msg); + if (ret != LDB_SUCCESS) { + goto done; + } + + /* remove any indexed attributes */ + ret = ldb_kv_index_delete(module, msg); + if (ret != LDB_SUCCESS) { + goto done; + } + + ret = ldb_kv_modified(module, dn); + if (ret != LDB_SUCCESS) { + goto done; + } + +done: + talloc_free(msg); + /* + * To allow testing of the error recovery code in ldb_kv_delete + * cmocka tests can define CMOCKA_UNIT_TEST_DELETE_INTERNAL_FAIL + * to inject failures at this point. + */ +#ifdef CMOCKA_UNIT_TEST_DELETE_INTERNAL_FAIL + CMOCKA_UNIT_TEST_DELETE_INTERNAL_FAIL +#endif + return ret; +} + +/* + delete a record from the database +*/ +static int ldb_kv_delete(struct ldb_kv_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + int ret = LDB_SUCCESS; + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + if (ldb_kv_cache_load(module) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_kv_sub_transaction_start(ldb_kv); + if (ret != LDB_SUCCESS) { + return ret; + } + ret = ldb_kv_delete_internal(module, req->op.del.dn); + if (ret != LDB_SUCCESS) { + int r = ldb_kv_sub_transaction_cancel(ldb_kv); + if (r != LDB_SUCCESS) { + ldb_debug( + ldb_module_get_ctx(module), + LDB_DEBUG_FATAL, + __location__ + ": Unable to roll back sub transaction"); + } + if (ret != LDB_ERR_NO_SUCH_OBJECT) { + ldb_kv->operation_failed = true; + } + return ret; + } + ret = ldb_kv_sub_transaction_commit(ldb_kv); + + return ret; +} + +/* + find an element by attribute name. At the moment this does a linear search, + it should be re-coded to use a binary search once all places that modify + records guarantee sorted order + + return the index of the first matching element if found, otherwise -1 +*/ +static int ldb_kv_find_element(const struct ldb_message *msg, const char *name) +{ + unsigned int i; + for (i=0;inum_elements;i++) { + if (ldb_attr_cmp(msg->elements[i].name, name) == 0) { + return i; + } + } + return -1; +} + + +/* + add an element to an existing record. Assumes a elements array that we + can call re-alloc on, and assumed that we can re-use the data pointers from + the passed in additional values. Use with care! + + returns 0 on success, -1 on failure (and sets errno) +*/ +static int ldb_kv_msg_add_element(struct ldb_message *msg, + struct ldb_message_element *el) +{ + struct ldb_message_element *e2; + unsigned int i; + + if (el->num_values == 0) { + /* nothing to do here - we don't add empty elements */ + return 0; + } + + e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element, + msg->num_elements+1); + if (!e2) { + errno = ENOMEM; + return -1; + } + + msg->elements = e2; + + e2 = &msg->elements[msg->num_elements]; + + e2->name = el->name; + e2->flags = el->flags; + e2->values = talloc_array(msg->elements, + struct ldb_val, el->num_values); + if (!e2->values) { + errno = ENOMEM; + return -1; + } + for (i=0;inum_values;i++) { + e2->values[i] = el->values[i]; + } + e2->num_values = el->num_values; + + ++msg->num_elements; + + return 0; +} + +/* + delete all elements having a specified attribute name +*/ +static int ldb_kv_msg_delete_attribute(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + struct ldb_message *msg, + const char *name) +{ + int ret; + struct ldb_message_element *el; + bool is_special = ldb_dn_is_special(msg->dn); + + if (!is_special && ldb_kv->cache->GUID_index_attribute != NULL && + ldb_attr_cmp(name, ldb_kv->cache->GUID_index_attribute) == 0) { + struct ldb_context *ldb = ldb_module_get_ctx(module); + ldb_asprintf_errstring(ldb, + "Must not modify GUID " + "attribute %s (used as DB index)", + ldb_kv->cache->GUID_index_attribute); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + el = ldb_msg_find_element(msg, name); + if (el == NULL) { + return LDB_ERR_NO_SUCH_ATTRIBUTE; + } + + ret = ldb_kv_index_del_element(module, ldb_kv, msg, el); + if (ret != LDB_SUCCESS) { + return ret; + } + + talloc_free(el->values); + ldb_msg_remove_element(msg, el); + msg->elements = talloc_realloc(msg, msg->elements, + struct ldb_message_element, + msg->num_elements); + return LDB_SUCCESS; +} + +/* + delete all elements matching an attribute name/value + + return LDB Error on failure +*/ +static int ldb_kv_msg_delete_element(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + struct ldb_message *msg, + const char *name, + const struct ldb_val *val) +{ + struct ldb_context *ldb = ldb_module_get_ctx(module); + unsigned int i; + int found, ret; + struct ldb_message_element *el; + const struct ldb_schema_attribute *a; + + found = ldb_kv_find_element(msg, name); + if (found == -1) { + return LDB_ERR_NO_SUCH_ATTRIBUTE; + } + + i = (unsigned int) found; + el = &(msg->elements[i]); + + a = ldb_schema_attribute_by_name(ldb, el->name); + + for (i=0;inum_values;i++) { + bool matched; + if (a->syntax->operator_fn) { + ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a, + &el->values[i], val, &matched); + if (ret != LDB_SUCCESS) return ret; + } else { + matched = (a->syntax->comparison_fn(ldb, ldb, + &el->values[i], val) == 0); + } + if (matched) { + if (el->num_values == 1) { + return ldb_kv_msg_delete_attribute( + module, ldb_kv, msg, name); + } + + ret = + ldb_kv_index_del_value(module, ldb_kv, msg, el, i); + if (ret != LDB_SUCCESS) { + return ret; + } + + if (inum_values-1) { + memmove(&el->values[i], &el->values[i+1], + sizeof(el->values[i])* + (el->num_values-(i+1))); + } + el->num_values--; + + /* per definition we find in a canonicalised message an + attribute value only once. So we are finished here */ + return LDB_SUCCESS; + } + } + + /* Not found */ + return LDB_ERR_NO_SUCH_ATTRIBUTE; +} + +/* + modify a record - internal interface + + yuck - this is O(n^2). Luckily n is usually small so we probably + get away with it, but if we ever have really large attribute lists + then we'll need to look at this again + + 'req' is optional, and is used to specify controls if supplied +*/ +int ldb_kv_modify_internal(struct ldb_module *module, + const struct ldb_message *msg, + struct ldb_request *req) +{ + struct ldb_context *ldb = ldb_module_get_ctx(module); + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + struct ldb_message *msg2; + unsigned int i, j; + int ret = LDB_SUCCESS, idx; + struct ldb_control *control_permissive = NULL; + TALLOC_CTX *mem_ctx = talloc_new(req); + + if (mem_ctx == NULL) { + return ldb_module_oom(module); + } + + if (req) { + control_permissive = ldb_request_get_control(req, + LDB_CONTROL_PERMISSIVE_MODIFY_OID); + } + + msg2 = ldb_msg_new(mem_ctx); + if (msg2 == NULL) { + ret = LDB_ERR_OTHER; + goto done; + } + + ret = ldb_kv_search_dn1(module, msg->dn, msg2, 0); + if (ret != LDB_SUCCESS) { + goto done; + } + + for (i=0; inum_elements; i++) { + struct ldb_message_element *el = &msg->elements[i], *el2; + struct ldb_val *vals; + const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name); + const char *dn; + uint32_t options = 0; + if (control_permissive != NULL) { + options |= LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES; + } + + switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) { + case LDB_FLAG_MOD_ADD: + + if (el->num_values == 0) { + ldb_asprintf_errstring(ldb, + "attribute '%s': attribute on '%s' specified, but with 0 values (illegal)", + el->name, ldb_dn_get_linearized(msg2->dn)); + ret = LDB_ERR_CONSTRAINT_VIOLATION; + goto done; + } + + /* make a copy of the array so that a permissive + * control can remove duplicates without changing the + * original values, but do not copy data as we do not + * need to keep it around once the operation is + * finished */ + if (control_permissive) { + el = talloc(msg2, struct ldb_message_element); + if (!el) { + ret = LDB_ERR_OTHER; + goto done; + } + *el = msg->elements[i]; + el->values = talloc_array(el, struct ldb_val, el->num_values); + if (el->values == NULL) { + ret = LDB_ERR_OTHER; + goto done; + } + for (j = 0; j < el->num_values; j++) { + el->values[j] = msg->elements[i].values[j]; + } + } + + if (el->num_values > 1 && ldb_kv_single_valued(a, el)) { + ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", + el->name, ldb_dn_get_linearized(msg2->dn)); + ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + goto done; + } + + /* Checks if element already exists */ + idx = ldb_kv_find_element(msg2, el->name); + if (idx == -1) { + if (ldb_kv_msg_add_element(msg2, el) != 0) { + ret = LDB_ERR_OTHER; + goto done; + } + ret = ldb_kv_index_add_element( + module, ldb_kv, msg2, el); + if (ret != LDB_SUCCESS) { + goto done; + } + } else { + j = (unsigned int) idx; + el2 = &(msg2->elements[j]); + + /* We cannot add another value on a existing one + if the attribute is single-valued */ + if (ldb_kv_single_valued(a, el)) { + ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", + el->name, ldb_dn_get_linearized(msg2->dn)); + ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + goto done; + } + + /* Check that values don't exist yet on multi- + valued attributes or aren't provided twice */ + if (!(el->flags & + LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK)) { + struct ldb_val *duplicate = NULL; + ret = ldb_msg_find_common_values(ldb, + msg2, + el, + el2, + options); + + if (ret == + LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) { + ldb_asprintf_errstring(ldb, + "attribute '%s': value " + "#%u on '%s' already " + "exists", el->name, j, + ldb_dn_get_linearized(msg2->dn)); + goto done; + } else if (ret != LDB_SUCCESS) { + goto done; + } + + ret = ldb_msg_find_duplicate_val( + ldb, msg2, el, &duplicate, 0); + if (ret != LDB_SUCCESS) { + goto done; + } + if (duplicate != NULL) { + ldb_asprintf_errstring( + ldb, + "attribute '%s': value " + "'%.*s' on '%s' " + "provided more than " + "once in ADD", + el->name, + (int)duplicate->length, + duplicate->data, + ldb_dn_get_linearized(msg->dn)); + ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + goto done; + } + } + + /* Now combine existing and new values to a new + attribute record */ + vals = talloc_realloc(msg2->elements, + el2->values, struct ldb_val, + el2->num_values + el->num_values); + if (vals == NULL) { + ldb_oom(ldb); + ret = LDB_ERR_OTHER; + goto done; + } + + for (j=0; jnum_values; j++) { + vals[el2->num_values + j] = + ldb_val_dup(vals, &el->values[j]); + } + + el2->values = vals; + el2->num_values += el->num_values; + + ret = ldb_kv_index_add_element( + module, ldb_kv, msg2, el); + if (ret != LDB_SUCCESS) { + goto done; + } + } + + break; + + case LDB_FLAG_MOD_REPLACE: + + if (el->num_values > 1 && ldb_kv_single_valued(a, el)) { + ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", + el->name, ldb_dn_get_linearized(msg2->dn)); + ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + goto done; + } + + /* + * We don't need to check this if we have been + * pre-screened by the repl_meta_data module + * in Samba, or someone else who can claim to + * know what they are doing. + */ + if (!(el->flags & LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK)) { + struct ldb_val *duplicate = NULL; + + ret = ldb_msg_find_duplicate_val(ldb, msg2, el, + &duplicate, 0); + if (ret != LDB_SUCCESS) { + goto done; + } + if (duplicate != NULL) { + ldb_asprintf_errstring( + ldb, + "attribute '%s': value '%.*s' " + "on '%s' provided more than " + "once in REPLACE", + el->name, + (int)duplicate->length, + duplicate->data, + ldb_dn_get_linearized(msg2->dn)); + ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + goto done; + } + } + + /* Checks if element already exists */ + idx = ldb_kv_find_element(msg2, el->name); + if (idx != -1) { + j = (unsigned int) idx; + el2 = &(msg2->elements[j]); + + /* we consider two elements to be + * equal only if the order + * matches. This allows dbcheck to + * fix the ordering on attributes + * where order matters, such as + * objectClass + */ + if (ldb_msg_element_equal_ordered(el, el2)) { + continue; + } + + /* Delete the attribute if it exists in the DB */ + if (ldb_kv_msg_delete_attribute( + module, ldb_kv, msg2, el->name) != 0) { + ret = LDB_ERR_OTHER; + goto done; + } + } + + /* Recreate it with the new values */ + if (ldb_kv_msg_add_element(msg2, el) != 0) { + ret = LDB_ERR_OTHER; + goto done; + } + + ret = + ldb_kv_index_add_element(module, ldb_kv, msg2, el); + if (ret != LDB_SUCCESS) { + goto done; + } + + break; + + case LDB_FLAG_MOD_DELETE: + dn = ldb_dn_get_linearized(msg2->dn); + if (dn == NULL) { + ret = LDB_ERR_OTHER; + goto done; + } + + if (msg->elements[i].num_values == 0) { + /* Delete the whole attribute */ + ret = ldb_kv_msg_delete_attribute( + module, + ldb_kv, + msg2, + msg->elements[i].name); + if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE && + control_permissive) { + ret = LDB_SUCCESS; + } else { + ldb_asprintf_errstring(ldb, + "attribute '%s': no such attribute for delete on '%s'", + msg->elements[i].name, dn); + } + if (ret != LDB_SUCCESS) { + goto done; + } + } else { + /* Delete specified values from an attribute */ + for (j=0; j < msg->elements[i].num_values; j++) { + ret = ldb_kv_msg_delete_element( + module, + ldb_kv, + msg2, + msg->elements[i].name, + &msg->elements[i].values[j]); + if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE && + control_permissive) { + ret = LDB_SUCCESS; + } else if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { + ldb_asprintf_errstring(ldb, + "attribute '%s': no matching attribute value while deleting attribute on '%s'", + msg->elements[i].name, dn); + } + if (ret != LDB_SUCCESS) { + goto done; + } + } + } + break; + default: + ldb_asprintf_errstring(ldb, + "attribute '%s': invalid modify flags on '%s': 0x%x", + msg->elements[i].name, ldb_dn_get_linearized(msg->dn), + msg->elements[i].flags & LDB_FLAG_MOD_MASK); + ret = LDB_ERR_PROTOCOL_ERROR; + goto done; + } + } + + ret = ldb_kv_store(module, msg2, TDB_MODIFY); + if (ret != LDB_SUCCESS) { + goto done; + } + + ret = ldb_kv_modified(module, msg2->dn); + if (ret != LDB_SUCCESS) { + goto done; + } + +done: + TALLOC_FREE(mem_ctx); + /* + * To allow testing of the error recovery code in ldb_kv_modify + * cmocka tests can define CMOCKA_UNIT_TEST_MODIFY_INTERNAL_FAIL + * to inject failures at this point. + */ +#ifdef CMOCKA_UNIT_TEST_MODIFY_INTERNAL_FAIL + CMOCKA_UNIT_TEST_MODIFY_INTERNAL_FAIL +#endif + return ret; +} + +/* + modify a record +*/ +static int ldb_kv_modify(struct ldb_kv_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + int ret = LDB_SUCCESS; + + ret = ldb_kv_check_special_dn(module, req->op.mod.message); + if (ret != LDB_SUCCESS) { + return ret; + } + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + if (ldb_kv_cache_load(module) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_kv_sub_transaction_start(ldb_kv); + if (ret != LDB_SUCCESS) { + return ret; + } + ret = ldb_kv_modify_internal(module, req->op.mod.message, req); + if (ret != LDB_SUCCESS) { + int r = ldb_kv_sub_transaction_cancel(ldb_kv); + if (r != LDB_SUCCESS) { + ldb_debug( + ldb_module_get_ctx(module), + LDB_DEBUG_FATAL, + __location__ + ": Unable to roll back sub transaction"); + } + if (ret != LDB_ERR_NO_SUCH_OBJECT) { + ldb_kv->operation_failed = true; + } + return ret; + } + ret = ldb_kv_sub_transaction_commit(ldb_kv); + + + return ret; +} + +static int ldb_kv_rename_internal(struct ldb_module *module, + struct ldb_request *req, + struct ldb_message *msg) +{ + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + int ret = LDB_SUCCESS; + + /* Always delete first then add, to avoid conflicts with + * unique indexes. We rely on the transaction to make this + * atomic + */ + ret = ldb_kv_delete_internal(module, msg->dn); + if (ret != LDB_SUCCESS) { + return ret; + } + + msg->dn = ldb_dn_copy(msg, req->op.rename.newdn); + if (msg->dn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* We don't check single value as we can have more than 1 with + * deleted attributes. We could go through all elements but that's + * maybe not the most efficient way + */ + ret = ldb_kv_add_internal(module, ldb_kv, msg, false); + + /* + * To allow testing of the error recovery code in ldb_kv_rename + * cmocka tests can define CMOCKA_UNIT_TEST_RENAME_INTERNAL_FAIL + * to inject failures at this point. + */ +#ifdef CMOCKA_UNIT_TEST_RENAME_INTERNAL_FAIL + CMOCKA_UNIT_TEST_RENAME_INTERNAL_FAIL +#endif + return ret; +} + +/* + rename a record +*/ +static int ldb_kv_rename(struct ldb_kv_context *ctx) +{ + struct ldb_module *module = ctx->module; + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + struct ldb_request *req = ctx->req; + struct ldb_message *msg; + int ret = LDB_SUCCESS; + struct ldb_val key, key_old; + struct ldb_dn *db_dn; + bool valid_dn = false; + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + if (ldb_kv_cache_load(ctx->module) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + msg = ldb_msg_new(ctx); + if (msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Check the new DN is reasonable */ + valid_dn = ldb_dn_validate(req->op.rename.newdn); + if (valid_dn == false) { + ldb_asprintf_errstring(ldb_module_get_ctx(module), + "Invalid New DN: %s", + ldb_dn_get_linearized(req->op.rename.newdn)); + return LDB_ERR_INVALID_DN_SYNTAX; + } + + /* we need to fetch the old record to re-add under the new name */ + ret = ldb_kv_search_dn1(module, req->op.rename.olddn, msg, 0); + if (ret == LDB_ERR_INVALID_DN_SYNTAX) { + ldb_asprintf_errstring(ldb_module_get_ctx(module), + "Invalid Old DN: %s", + ldb_dn_get_linearized(req->op.rename.newdn)); + return ret; + } else if (ret != LDB_SUCCESS) { + /* not finding the old record is an error */ + return ret; + } + + /* We need to, before changing the DB, check if the new DN + * exists, so we can return this error to the caller with an + * unmodified DB + * + * Even in GUID index mode we use ltdb_key_dn() as we are + * trying to figure out if this is just a case rename + */ + key = ldb_kv_key_dn(msg, req->op.rename.newdn); + if (!key.data) { + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + key_old = ldb_kv_key_dn(msg, req->op.rename.olddn); + if (!key_old.data) { + talloc_free(msg); + talloc_free(key.data); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* + * Only declare a conflict if the new DN already exists, + * and it isn't a case change on the old DN + */ + if (key_old.length != key.length + || memcmp(key.data, key_old.data, key.length) != 0) { + ret = ldb_kv_search_base( + module, msg, req->op.rename.newdn, &db_dn); + if (ret == LDB_SUCCESS) { + ret = LDB_ERR_ENTRY_ALREADY_EXISTS; + } else if (ret == LDB_ERR_NO_SUCH_OBJECT) { + ret = LDB_SUCCESS; + } + } + + /* finding the new record already in the DB is an error */ + + if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { + ldb_asprintf_errstring(ldb_module_get_ctx(module), + "Entry %s already exists", + ldb_dn_get_linearized(req->op.rename.newdn)); + } + if (ret != LDB_SUCCESS) { + talloc_free(key_old.data); + talloc_free(key.data); + talloc_free(msg); + return ret; + } + + talloc_free(key_old.data); + talloc_free(key.data); + + + ret = ldb_kv_sub_transaction_start(ldb_kv); + if (ret != LDB_SUCCESS) { + talloc_free(msg); + return ret; + } + ret = ldb_kv_rename_internal(module, req, msg); + if (ret != LDB_SUCCESS) { + int r = ldb_kv_sub_transaction_cancel(ldb_kv); + if (r != LDB_SUCCESS) { + ldb_debug( + ldb_module_get_ctx(module), + LDB_DEBUG_FATAL, + __location__ + ": Unable to roll back sub transaction"); + } + talloc_free(msg); + ldb_kv->operation_failed = true; + return ret; + } + ret = ldb_kv_sub_transaction_commit(ldb_kv); + talloc_free(msg); + + return ret; +} + +static int ldb_kv_start_trans(struct ldb_module *module) +{ + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + + pid_t pid = getpid(); + + if (ldb_kv->pid != pid) { + ldb_asprintf_errstring(ldb_module_get_ctx(ldb_kv->module), + __location__ + ": Reusing ldb opend by pid %d in " + "process %d\n", + ldb_kv->pid, + pid); + return LDB_ERR_PROTOCOL_ERROR; + } + + /* Do not take out the transaction lock on a read-only DB */ + if (ldb_kv->read_only) { + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + if (ldb_kv->kv_ops->begin_write(ldb_kv) != 0) { + return ldb_kv->kv_ops->error(ldb_kv); + } + + ldb_kv_index_transaction_start( + module, + ldb_kv->index_transaction_cache_size); + + ldb_kv->reindex_failed = false; + ldb_kv->operation_failed = false; + + return LDB_SUCCESS; +} + +/* + * Forward declaration to allow prepare_commit to in fact abort the + * transaction + */ +static int ldb_kv_del_trans(struct ldb_module *module); + +static int ldb_kv_prepare_commit(struct ldb_module *module) +{ + int ret; + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + pid_t pid = getpid(); + + if (ldb_kv->pid != pid) { + ldb_asprintf_errstring(ldb_module_get_ctx(module), + __location__ + ": Reusing ldb opend by pid %d in " + "process %d\n", + ldb_kv->pid, + pid); + return LDB_ERR_PROTOCOL_ERROR; + } + + if (!ldb_kv->kv_ops->transaction_active(ldb_kv)) { + ldb_set_errstring(ldb_module_get_ctx(module), + "ltdb_prepare_commit() called " + "without transaction active"); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* + * Check if the last re-index failed. + * + * This can happen if for example a duplicate value was marked + * unique. We must not write a partial re-index into the DB. + */ + if (ldb_kv->reindex_failed) { + /* + * We must instead abort the transaction so we get the + * old values and old index back + */ + ldb_kv_del_trans(module); + ldb_set_errstring(ldb_module_get_ctx(module), + "Failure during re-index, so " + "transaction must be aborted."); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_kv_index_transaction_commit(module); + if (ret != LDB_SUCCESS) { + ldb_kv->kv_ops->abort_write(ldb_kv); + return ret; + } + + /* + * If GUID indexing was toggled in this transaction, we repack at + * format version 2 if GUID indexing was enabled, or version 1 if + * it was disabled. + */ + ret = ldb_kv_maybe_repack(ldb_kv); + if (ret != LDB_SUCCESS) { + ldb_kv_del_trans(module); + ldb_set_errstring(ldb_module_get_ctx(module), + "Failure during re-pack, so " + "transaction must be aborted."); + return ret; + } + + if (ldb_kv->kv_ops->prepare_write(ldb_kv) != 0) { + ret = ldb_kv->kv_ops->error(ldb_kv); + ldb_debug_set(ldb_module_get_ctx(module), + LDB_DEBUG_FATAL, + "Failure during " + "prepare_write): %s -> %s", + ldb_kv->kv_ops->errorstr(ldb_kv), + ldb_strerror(ret)); + return ret; + } + + ldb_kv->prepared_commit = true; + + return LDB_SUCCESS; +} + +static int ldb_kv_end_trans(struct ldb_module *module) +{ + int ret; + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + + /* + * If in batch mode and there has been an operation failure + * rollback the transaction rather than committing it to avoid + * any possible corruption + */ + if (ldb_kv->batch_mode && ldb_kv->operation_failed) { + ret = ldb_kv_del_trans( module); + if (ret != LDB_SUCCESS) { + ldb_debug_set(ldb_module_get_ctx(module), + LDB_DEBUG_FATAL, + "An operation failed during a batch mode " + "transaction. The transaction could not" + "be rolled back, ldb_kv_del_trans " + "returned (%s, %s)", + ldb_kv->kv_ops->errorstr(ldb_kv), + ldb_strerror(ret)); + } else { + ldb_debug_set(ldb_module_get_ctx(module), + LDB_DEBUG_FATAL, + "An operation failed during a batch mode " + "transaction, the transaction was " + "rolled back"); + } + return LDB_ERR_OPERATIONS_ERROR; + } + + if (!ldb_kv->prepared_commit) { + ret = ldb_kv_prepare_commit(module); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + ldb_kv->prepared_commit = false; + + if (ldb_kv->kv_ops->finish_write(ldb_kv) != 0) { + ret = ldb_kv->kv_ops->error(ldb_kv); + ldb_asprintf_errstring( + ldb_module_get_ctx(module), + "Failure during tdb_transaction_commit(): %s -> %s", + ldb_kv->kv_ops->errorstr(ldb_kv), + ldb_strerror(ret)); + return ret; + } + + return LDB_SUCCESS; +} + +static int ldb_kv_del_trans(struct ldb_module *module) +{ + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + + if (ldb_kv_index_transaction_cancel(module) != 0) { + ldb_kv->kv_ops->abort_write(ldb_kv); + return ldb_kv->kv_ops->error(ldb_kv); + } + + ldb_kv->kv_ops->abort_write(ldb_kv); + return LDB_SUCCESS; +} + +/* + return sequenceNumber from @BASEINFO +*/ +static int ldb_kv_sequence_number(struct ldb_kv_context *ctx, + struct ldb_extended **ext) +{ + struct ldb_context *ldb; + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + TALLOC_CTX *tmp_ctx = NULL; + struct ldb_seqnum_request *seq; + struct ldb_seqnum_result *res; + struct ldb_message *msg = NULL; + struct ldb_dn *dn; + const char *date; + int ret = LDB_SUCCESS; + + ldb = ldb_module_get_ctx(module); + + seq = talloc_get_type(req->op.extended.data, + struct ldb_seqnum_request); + if (seq == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + if (ldb_kv->kv_ops->lock_read(module) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + res = talloc_zero(req, struct ldb_seqnum_result); + if (res == NULL) { + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + + tmp_ctx = talloc_new(req); + if (tmp_ctx == NULL) { + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + + dn = ldb_dn_new(tmp_ctx, ldb, LDB_KV_BASEINFO); + if (dn == NULL) { + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + + msg = ldb_msg_new(tmp_ctx); + if (msg == NULL) { + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + + ret = ldb_kv_search_dn1(module, dn, msg, 0); + if (ret != LDB_SUCCESS) { + goto done; + } + + switch (seq->type) { + case LDB_SEQ_HIGHEST_SEQ: + res->seq_num = ldb_msg_find_attr_as_uint64(msg, LDB_KV_SEQUENCE_NUMBER, 0); + break; + case LDB_SEQ_NEXT: + res->seq_num = ldb_msg_find_attr_as_uint64(msg, LDB_KV_SEQUENCE_NUMBER, 0); + res->seq_num++; + break; + case LDB_SEQ_HIGHEST_TIMESTAMP: + date = ldb_msg_find_attr_as_string(msg, LDB_KV_MOD_TIMESTAMP, NULL); + if (date) { + res->seq_num = ldb_string_to_time(date); + } else { + res->seq_num = 0; + /* zero is as good as anything when we don't know */ + } + break; + } + + *ext = talloc_zero(req, struct ldb_extended); + if (*ext == NULL) { + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } + (*ext)->oid = LDB_EXTENDED_SEQUENCE_NUMBER; + (*ext)->data = talloc_steal(*ext, res); + +done: + talloc_free(tmp_ctx); + + ldb_kv->kv_ops->unlock_read(module); + return ret; +} + +static void ldb_kv_request_done(struct ldb_kv_context *ctx, int error) +{ + struct ldb_context *ldb; + struct ldb_request *req; + struct ldb_reply *ares; + + ldb = ldb_module_get_ctx(ctx->module); + req = ctx->req; + + /* if we already returned an error just return */ + if (ldb_request_get_status(req) != LDB_SUCCESS) { + return; + } + + ares = talloc_zero(req, struct ldb_reply); + if (!ares) { + ldb_oom(ldb); + req->callback(req, NULL); + return; + } + ares->type = LDB_REPLY_DONE; + ares->error = error; + + req->callback(req, ares); +} + +static void ldb_kv_timeout(_UNUSED_ struct tevent_context *ev, + _UNUSED_ struct tevent_timer *te, + _UNUSED_ struct timeval t, + void *private_data) +{ + struct ldb_kv_context *ctx; + ctx = talloc_get_type(private_data, struct ldb_kv_context); + + if (!ctx->request_terminated) { + /* request is done now */ + ldb_kv_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED); + } + + if (ctx->spy) { + /* neutralize the spy */ + ctx->spy->ctx = NULL; + ctx->spy = NULL; + } + talloc_free(ctx); +} + +static void ldb_kv_request_extended_done(struct ldb_kv_context *ctx, + struct ldb_extended *ext, + int error) +{ + struct ldb_context *ldb; + struct ldb_request *req; + struct ldb_reply *ares; + + ldb = ldb_module_get_ctx(ctx->module); + req = ctx->req; + + /* if we already returned an error just return */ + if (ldb_request_get_status(req) != LDB_SUCCESS) { + return; + } + + ares = talloc_zero(req, struct ldb_reply); + if (!ares) { + ldb_oom(ldb); + req->callback(req, NULL); + return; + } + ares->type = LDB_REPLY_DONE; + ares->response = ext; + ares->error = error; + + req->callback(req, ares); +} + +static void ldb_kv_handle_extended(struct ldb_kv_context *ctx) +{ + struct ldb_extended *ext = NULL; + int ret; + + if (strcmp(ctx->req->op.extended.oid, + LDB_EXTENDED_SEQUENCE_NUMBER) == 0) { + /* get sequence number */ + ret = ldb_kv_sequence_number(ctx, &ext); + } else { + /* not recognized */ + ret = LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; + } + + ldb_kv_request_extended_done(ctx, ext, ret); +} + +static void ldb_kv_callback(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval t, + void *private_data) +{ + struct ldb_kv_context *ctx; + int ret; + + ctx = talloc_get_type(private_data, struct ldb_kv_context); + + if (ctx->request_terminated) { + goto done; + } + + switch (ctx->req->operation) { + case LDB_SEARCH: + ret = ldb_kv_search(ctx); + break; + case LDB_ADD: + ret = ldb_kv_add(ctx); + break; + case LDB_MODIFY: + ret = ldb_kv_modify(ctx); + break; + case LDB_DELETE: + ret = ldb_kv_delete(ctx); + break; + case LDB_RENAME: + ret = ldb_kv_rename(ctx); + break; + case LDB_EXTENDED: + ldb_kv_handle_extended(ctx); + goto done; + default: + /* no other op supported */ + ret = LDB_ERR_PROTOCOL_ERROR; + } + + if (!ctx->request_terminated) { + /* request is done now */ + ldb_kv_request_done(ctx, ret); + } + +done: + if (ctx->spy) { + /* neutralize the spy */ + ctx->spy->ctx = NULL; + ctx->spy = NULL; + } + talloc_free(ctx); +} + +static int ldb_kv_request_destructor(void *ptr) +{ + struct ldb_kv_req_spy *spy = + talloc_get_type(ptr, struct ldb_kv_req_spy); + + if (spy->ctx != NULL) { + spy->ctx->spy = NULL; + spy->ctx->request_terminated = true; + spy->ctx = NULL; + } + + return 0; +} + +static int ldb_kv_handle_request(struct ldb_module *module, + struct ldb_request *req) +{ + struct ldb_control *control_permissive; + struct ldb_context *ldb; + struct tevent_context *ev; + struct ldb_kv_context *ac; + struct tevent_timer *te; + struct timeval tv; + unsigned int i; + + ldb = ldb_module_get_ctx(module); + + control_permissive = ldb_request_get_control(req, + LDB_CONTROL_PERMISSIVE_MODIFY_OID); + + for (i = 0; req->controls && req->controls[i]; i++) { + if (req->controls[i]->critical && + req->controls[i] != control_permissive) { + ldb_asprintf_errstring(ldb, "Unsupported critical extension %s", + req->controls[i]->oid); + return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; + } + } + + if (req->starttime == 0 || req->timeout == 0) { + ldb_set_errstring(ldb, "Invalid timeout settings"); + return LDB_ERR_TIME_LIMIT_EXCEEDED; + } + + ev = ldb_handle_get_event_context(req->handle); + + ac = talloc_zero(ldb, struct ldb_kv_context); + if (ac == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->module = module; + ac->req = req; + + tv.tv_sec = 0; + tv.tv_usec = 0; + te = tevent_add_timer(ev, ac, tv, ldb_kv_callback, ac); + if (NULL == te) { + talloc_free(ac); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (req->timeout > 0) { + tv.tv_sec = req->starttime + req->timeout; + tv.tv_usec = 0; + ac->timeout_event = + tevent_add_timer(ev, ac, tv, ldb_kv_timeout, ac); + if (NULL == ac->timeout_event) { + talloc_free(ac); + return LDB_ERR_OPERATIONS_ERROR; + } + } + + /* set a spy so that we do not try to use the request context + * if it is freed before ltdb_callback fires */ + ac->spy = talloc(req, struct ldb_kv_req_spy); + if (NULL == ac->spy) { + talloc_free(ac); + return LDB_ERR_OPERATIONS_ERROR; + } + ac->spy->ctx = ac; + + talloc_set_destructor((TALLOC_CTX *)ac->spy, ldb_kv_request_destructor); + + return LDB_SUCCESS; +} + +static int ldb_kv_init_rootdse(struct ldb_module *module) +{ + /* ignore errors on this - we expect it for non-sam databases */ + ldb_mod_register_control(module, LDB_CONTROL_PERMISSIVE_MODIFY_OID); + + /* there can be no module beyond the backend, just return */ + return LDB_SUCCESS; +} + +static int ldb_kv_lock_read(struct ldb_module *module) +{ + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + return ldb_kv->kv_ops->lock_read(module); +} + +static int ldb_kv_unlock_read(struct ldb_module *module) +{ + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + return ldb_kv->kv_ops->unlock_read(module); +} + +static const struct ldb_module_ops ldb_kv_ops = { + .name = "tdb", + .init_context = ldb_kv_init_rootdse, + .search = ldb_kv_handle_request, + .add = ldb_kv_handle_request, + .modify = ldb_kv_handle_request, + .del = ldb_kv_handle_request, + .rename = ldb_kv_handle_request, + .extended = ldb_kv_handle_request, + .start_transaction = ldb_kv_start_trans, + .end_transaction = ldb_kv_end_trans, + .prepare_commit = ldb_kv_prepare_commit, + .del_transaction = ldb_kv_del_trans, + .read_lock = ldb_kv_lock_read, + .read_unlock = ldb_kv_unlock_read, +}; + +int ldb_kv_init_store(struct ldb_kv_private *ldb_kv, + const char *name, + struct ldb_context *ldb, + const char *options[], + struct ldb_module **_module) +{ + if (getenv("LDB_WARN_UNINDEXED")) { + ldb_kv->warn_unindexed = true; + } + + if (getenv("LDB_WARN_REINDEX")) { + ldb_kv->warn_reindex = true; + } + + ldb_kv->sequence_number = 0; + + ldb_kv->pid = getpid(); + + ldb_kv->pack_format_override = 0; + + ldb_kv->module = ldb_module_new(ldb, ldb, name, &ldb_kv_ops); + if (!ldb_kv->module) { + ldb_oom(ldb); + talloc_free(ldb_kv); + return LDB_ERR_OPERATIONS_ERROR; + } + ldb_module_set_private(ldb_kv->module, ldb_kv); + talloc_steal(ldb_kv->module, ldb_kv); + + if (ldb_kv_cache_load(ldb_kv->module) != 0) { + ldb_asprintf_errstring(ldb, "Unable to load ltdb cache " + "records for backend '%s'", name); + talloc_free(ldb_kv->module); + return LDB_ERR_OPERATIONS_ERROR; + } + + *_module = ldb_kv->module; + /* + * Set or override the maximum key length + * + * The ldb_mdb code will have set this to 511, but our tests + * set this even smaller (to make the tests more practical). + * + * This must only be used for the selftest as the length + * becomes encoded in the index keys. + */ + { + const char *len_str = + ldb_options_find(ldb, options, + "max_key_len_for_self_test"); + if (len_str != NULL) { + unsigned len = strtoul(len_str, NULL, 0); + ldb_kv->max_key_length = len; + } + } + + /* + * Usually the presence of GUID indexing determines the pack format + * we use but in certain circumstances such as downgrading an + * MDB-backed database, we want to override the target pack format. + * + * We set/get opaques here because in the Samba partitions module, + * 'options' are not passed correctly so sub-databases can't see + * the options they need. + */ + { + const char *pack_format_override = + ldb_options_find(ldb, options, "pack_format_override"); + if (pack_format_override != NULL) { + int ret; + ldb_kv->pack_format_override = + strtoul(pack_format_override, NULL, 0); + ret = ldb_set_opaque(ldb, + "pack_format_override", + (void *)(intptr_t)ldb_kv->pack_format_override); + if (ret != LDB_SUCCESS) { + talloc_free(ldb_kv->module); + return ldb_module_operr(ldb_kv->module); + } + } else { + /* + * NULL -> 0 is fine, otherwise we get back + * the number we needed + */ + ldb_kv->pack_format_override + = (intptr_t)ldb_get_opaque(ldb, + "pack_format_override"); + } + } + + /* + * Override full DB scans + * + * A full DB scan is expensive on a large database. This + * option is for testing to show that the full DB scan is not + * triggered. + */ + { + const char *len_str = + ldb_options_find(ldb, options, + "disable_full_db_scan_for_self_test"); + if (len_str != NULL) { + ldb_kv->disable_full_db_scan = true; + } + } + + /* + * Set the size of the transaction index cache. + * If the ldb option "transaction_index_cache_size" is set use that + * otherwise use DEFAULT_INDEX_CACHE_SIZE + */ + ldb_kv->index_transaction_cache_size = DEFAULT_INDEX_CACHE_SIZE; + { + const char *size = ldb_options_find( + ldb, + options, + "transaction_index_cache_size"); + if (size != NULL) { + size_t cache_size = 0; + errno = 0; + + cache_size = strtoul( size, NULL, 0); + if (cache_size == 0 || errno == ERANGE) { + ldb_debug( + ldb, + LDB_DEBUG_WARNING, + "Invalid transaction_index_cache_size " + "value [%s], using default(%d)\n", + size, + DEFAULT_INDEX_CACHE_SIZE); + } else { + ldb_kv->index_transaction_cache_size = + cache_size; + } + } + } + /* + * Set batch mode operation. + * This disables the nested sub transactions, and increases the + * chance of index corruption. If using this mode the transaction + * commit will be aborted if any operation fails. + */ + { + const char *batch_mode = ldb_options_find( + ldb, options, "batch_mode"); + if (batch_mode != NULL) { + ldb_kv->batch_mode = true; + } + } + + return LDB_SUCCESS; +} diff --git a/ldb-2.0.8/ldb_key_value/ldb_kv.h b/ldb-2.0.8/ldb_key_value/ldb_kv.h new file mode 100644 index 0000000..f9dffae --- /dev/null +++ b/ldb-2.0.8/ldb_key_value/ldb_kv.h @@ -0,0 +1,336 @@ +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "tdb.h" +#include "ldb_module.h" + +#ifndef __LDB_KV_H__ +#define __LDB_KV_H__ +struct ldb_kv_private; +typedef int (*ldb_kv_traverse_fn)(struct ldb_kv_private *ldb_kv, + struct ldb_val key, + struct ldb_val data, + void *ctx); + +struct kv_db_ops { + uint32_t options; + + int (*store)(struct ldb_kv_private *ldb_kv, + struct ldb_val key, + struct ldb_val data, + int flags); + int (*delete)(struct ldb_kv_private *ldb_kv, struct ldb_val key); + int (*iterate)(struct ldb_kv_private *ldb_kv, + ldb_kv_traverse_fn fn, + void *ctx); + int (*update_in_iterate)(struct ldb_kv_private *ldb_kv, + struct ldb_val key, + struct ldb_val key2, + struct ldb_val data, + void *ctx); + int (*fetch_and_parse)(struct ldb_kv_private *ldb_kv, + struct ldb_val key, + int (*parser)(struct ldb_val key, + struct ldb_val data, + void *private_data), + void *ctx); + int (*iterate_range)(struct ldb_kv_private *ldb_kv, + struct ldb_val start_key, + struct ldb_val end_key, + ldb_kv_traverse_fn fn, + void *ctx); + int (*lock_read)(struct ldb_module *); + int (*unlock_read)(struct ldb_module *); + int (*begin_write)(struct ldb_kv_private *); + int (*prepare_write)(struct ldb_kv_private *); + int (*abort_write)(struct ldb_kv_private *); + int (*finish_write)(struct ldb_kv_private *); + int (*error)(struct ldb_kv_private *ldb_kv); + const char *(*errorstr)(struct ldb_kv_private *ldb_kv); + const char *(*name)(struct ldb_kv_private *ldb_kv); + bool (*has_changed)(struct ldb_kv_private *ldb_kv); + bool (*transaction_active)(struct ldb_kv_private *ldb_kv); + size_t (*get_size)(struct ldb_kv_private *ldb_kv); + int (*begin_nested_write)(struct ldb_kv_private *); + int (*finish_nested_write)(struct ldb_kv_private *); + int (*abort_nested_write)(struct ldb_kv_private *); +}; + +/* this private structure is used by the key value backends in the + ldb_context */ +struct ldb_kv_private { + const struct kv_db_ops *kv_ops; + struct ldb_module *module; + TDB_CONTEXT *tdb; + struct lmdb_private *lmdb_private; + unsigned int connect_flags; + + unsigned long long sequence_number; + uint32_t pack_format_version; + uint32_t target_pack_format_version; + uint32_t pack_format_override; + + /* the low level tdb seqnum - used to avoid loading BASEINFO when + possible */ + int tdb_seqnum; + + struct ldb_kv_cache { + struct ldb_message *indexlist; + bool one_level_indexes; + bool attribute_indexes; + const char *GUID_index_attribute; + const char *GUID_index_dn_component; + } *cache; + + + bool check_base; + bool disallow_dn_filter; + /* + * To improve the performance of batch operations we maintain a cache + * of index records, these entries get written to disk in the + * prepare_commit phase. + */ + struct ldb_kv_idxptr *idxptr; + /* + * To ensure that the indexes in idxptr are consistent we cache any + * index updates during an operation, i.e. ldb_kv_add, ldb_kv_delete ... + * Once the changes to the data record have been commited to disk + * the contents of this cache are copied to idxptr + */ + struct ldb_kv_idxptr *nested_idx_ptr; + /* + * If batch mode is set the sub transactions and index caching + * wrapping individual operations is disabled. + * This is to improve the performance of large batch operations + * i.e. domain joins. + */ + bool batch_mode; + /* + * Has an operation failed, if true and we're in batch_mode + * the transaction commit will fail. + */ + bool operation_failed; + + bool prepared_commit; + int read_lock_count; + + bool warn_unindexed; + bool warn_reindex; + + bool read_only; + + bool reindex_failed; + + const struct ldb_schema_syntax *GUID_index_syntax; + + /* + * Maximum index key length. If non zero keys longer than this length + * will be truncated for non unique indexes. Keys for unique indexes + * greater than this length will be rejected. + */ + unsigned max_key_length; + + /* + * To allow testing that ensures the DB does not fall back + * to a full scan + */ + bool disable_full_db_scan; + + /* + * The PID that opened this database so we don't work in a + * fork()ed child. + */ + pid_t pid; + + /* + * The size to be used for the index transaction cache + */ + size_t index_transaction_cache_size; +}; + +struct ldb_kv_context { + struct ldb_module *module; + struct ldb_request *req; + + bool request_terminated; + struct ldb_kv_req_spy *spy; + + /* search stuff */ + const struct ldb_parse_tree *tree; + struct ldb_dn *base; + enum ldb_scope scope; + const char * const *attrs; + struct tevent_timer *timeout_event; + + /* error handling */ + int error; +}; + +struct ldb_kv_reindex_context { + int error; + uint32_t count; +}; + +struct ldb_kv_repack_context { + int error; + uint32_t count; + bool normal_record_seen; + uint32_t old_version; +}; + + +/* special record types */ +#define LDB_KV_INDEX "@INDEX" +#define LDB_KV_INDEXLIST "@INDEXLIST" +#define LDB_KV_IDX "@IDX" +#define LDB_KV_IDXVERSION "@IDXVERSION" +#define LDB_KV_IDXATTR "@IDXATTR" +#define LDB_KV_IDXONE "@IDXONE" +#define LDB_KV_IDXDN "@IDXDN" +#define LDB_KV_IDXGUID "@IDXGUID" +#define LDB_KV_IDX_DN_GUID "@IDX_DN_GUID" + +/* + * This will be used to indicate when a new, yet to be developed + * sub-database version of the indicies are in use, to ensure we do + * not load future databases unintentionally. + */ + +#define LDB_KV_IDX_LMDB_SUBDB "@IDX_LMDB_SUBDB" + +#define LDB_KV_BASEINFO "@BASEINFO" +#define LDB_KV_OPTIONS "@OPTIONS" +#define LDB_KV_ATTRIBUTES "@ATTRIBUTES" + +/* special attribute types */ +#define LDB_KV_SEQUENCE_NUMBER "sequenceNumber" +#define LDB_KV_CHECK_BASE "checkBaseOnSearch" +#define LDB_KV_DISALLOW_DN_FILTER "disallowDNFilter" +#define LDB_KV_MOD_TIMESTAMP "whenChanged" +#define LDB_KV_OBJECTCLASS "objectClass" + +/* DB keys */ +#define LDB_KV_GUID_KEY_PREFIX "GUID=" +#define LDB_KV_GUID_SIZE 16 +#define LDB_KV_GUID_KEY_SIZE (LDB_KV_GUID_SIZE + sizeof(LDB_KV_GUID_KEY_PREFIX) - 1) + +/* LDB KV options */ +/* + * This allows pointers to be referenced after the callback to any variant of + * iterate or fetch_and_parse -- as long as an overall read lock is held. + */ +#define LDB_KV_OPTION_STABLE_READ_LOCK 0x00000001 + +/* + * The following definitions come from lib/ldb/ldb_key_value/ldb_kv_cache.c + */ + +int ldb_kv_cache_reload(struct ldb_module *module); +int ldb_kv_cache_load(struct ldb_module *module); +int ldb_kv_increase_sequence_number(struct ldb_module *module); +int ldb_kv_check_at_attributes_values(const struct ldb_val *value); + +/* + * The following definitions come from lib/ldb/ldb_key_value/ldb_kv_index.c + */ + +/* + * The default size of the in memory TDB used to cache index records + * The value chosen gives a prime modulo for the hash table and keeps the + * tdb memory overhead under 4 kB + */ +#define DEFAULT_INDEX_CACHE_SIZE 491 + +struct ldb_parse_tree; + +int ldb_kv_search_indexed(struct ldb_kv_context *ctx, uint32_t *); +int ldb_kv_index_add_new(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_message *msg); +int ldb_kv_index_delete(struct ldb_module *module, + const struct ldb_message *msg); +int ldb_kv_index_del_element(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_message *msg, + struct ldb_message_element *el); +int ldb_kv_index_add_element(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_message *msg, + struct ldb_message_element *el); +int ldb_kv_index_del_value(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_message *msg, + struct ldb_message_element *el, + unsigned int v_idx); +int ldb_kv_reindex(struct ldb_module *module); +int ldb_kv_repack(struct ldb_module *module); +int ldb_kv_index_transaction_start( + struct ldb_module *module, + size_t cache_size); +int ldb_kv_index_transaction_commit(struct ldb_module *module); +int ldb_kv_index_transaction_cancel(struct ldb_module *module); +int ldb_kv_key_dn_from_idx(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + TALLOC_CTX *mem_ctx, + struct ldb_dn *dn, + struct ldb_val *key); + +/* + * The following definitions come from lib/ldb/ldb_key_value/ldb_kv_search.c + */ +int ldb_kv_search_dn1(struct ldb_module *module, + struct ldb_dn *dn, + struct ldb_message *msg, + unsigned int unpack_flags); +int ldb_kv_search_base(struct ldb_module *module, + TALLOC_CTX *mem_ctx, + struct ldb_dn *dn, + struct ldb_dn **ret_dn); +int ldb_kv_search_key(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_val ldb_key, + struct ldb_message *msg, + unsigned int unpack_flags); +int ldb_kv_filter_attrs(struct ldb_context *ldb, + const struct ldb_message *msg, + const char *const *attrs, + struct ldb_message *filtered_msg); +int ldb_kv_search(struct ldb_kv_context *ctx); + +/* + * The following definitions come from lib/ldb/ldb_key_value/ldb_kv.c */ +/* + * Determine if this key could hold a normal record. We allow the new + * GUID index, the old DN index and a possible future ID= but not + * DN=@. + */ +bool ldb_kv_key_is_normal_record(struct ldb_val key); +struct ldb_val ldb_kv_key_dn(TALLOC_CTX *mem_ctx, + struct ldb_dn *dn); +struct ldb_val ldb_kv_key_msg(struct ldb_module *module, + TALLOC_CTX *mem_ctx, + const struct ldb_message *msg); +int ldb_kv_guid_to_key(const struct ldb_val *GUID_val, + struct ldb_val *key); +int ldb_kv_idx_to_key(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + TALLOC_CTX *mem_ctx, + const struct ldb_val *idx_val, + struct ldb_val *key); +int ldb_kv_store(struct ldb_module *module, + const struct ldb_message *msg, + int flgs); +int ldb_kv_modify_internal(struct ldb_module *module, + const struct ldb_message *msg, + struct ldb_request *req); +int ldb_kv_delete_noindex(struct ldb_module *module, + const struct ldb_message *msg); +int ldb_kv_init_store(struct ldb_kv_private *ldb_kv, + const char *name, + struct ldb_context *ldb, + const char *options[], + struct ldb_module **_module); +int ldb_kv_index_sub_transaction_start(struct ldb_kv_private *ldb_kv); +int ldb_kv_index_sub_transaction_cancel(struct ldb_kv_private *ldb_kv); +int ldb_kv_index_sub_transaction_commit(struct ldb_kv_private *ldb_kv); +#endif /* __LDB_KV_H__ */ diff --git a/ldb-2.0.8/ldb_key_value/ldb_kv_cache.c b/ldb-2.0.8/ldb_key_value/ldb_kv_cache.c new file mode 100644 index 0000000..4a3c9f2 --- /dev/null +++ b/ldb-2.0.8/ldb_key_value/ldb_kv_cache.c @@ -0,0 +1,697 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb key value cache functions + * + * Description: cache special records in a ldb/tdb + * + * Author: Andrew Tridgell + */ + +#include "ldb_kv.h" +#include "ldb_private.h" + +#define LDB_KV_FLAG_CASE_INSENSITIVE (1<<0) +#define LDB_KV_FLAG_INTEGER (1<<1) +#define LDB_KV_FLAG_UNIQUE_INDEX (1<<2) +#define LDB_KV_FLAG_ORDERED_INTEGER (1<<3) + +/* valid attribute flags */ +static const struct { + const char *name; + int value; +} ldb_kv_valid_attr_flags[] = { + { "CASE_INSENSITIVE", LDB_KV_FLAG_CASE_INSENSITIVE }, + { "INTEGER", LDB_KV_FLAG_INTEGER }, + { "ORDERED_INTEGER", LDB_KV_FLAG_ORDERED_INTEGER }, + { "HIDDEN", 0 }, + { "UNIQUE_INDEX", LDB_KV_FLAG_UNIQUE_INDEX}, + { "NONE", 0 }, + { NULL, 0 } +}; + +/* + de-register any special handlers for @ATTRIBUTES +*/ +static void ldb_kv_attributes_unload(struct ldb_module *module) +{ + struct ldb_context *ldb = ldb_module_get_ctx(module); + + ldb_schema_attribute_remove_flagged(ldb, LDB_ATTR_FLAG_FROM_DB); + +} + +/* + add up the attrib flags for a @ATTRIBUTES element +*/ +static int ldb_kv_attributes_flags(struct ldb_message_element *el, unsigned *v) +{ + unsigned int i; + unsigned value = 0; + for (i=0;inum_values;i++) { + unsigned int j; + for (j = 0; ldb_kv_valid_attr_flags[j].name; j++) { + if (strcmp(ldb_kv_valid_attr_flags[j].name, + (char *)el->values[i].data) == 0) { + value |= ldb_kv_valid_attr_flags[j].value; + break; + } + } + if (ldb_kv_valid_attr_flags[j].name == NULL) { + return -1; + } + } + *v = value; + return 0; +} + +static int ldb_schema_attribute_compare(const void *p1, const void *p2) +{ + const struct ldb_schema_attribute *sa1 = (const struct ldb_schema_attribute *)p1; + const struct ldb_schema_attribute *sa2 = (const struct ldb_schema_attribute *)p2; + return ldb_attr_cmp(sa1->name, sa2->name); +} + +/* + register any special handlers from @ATTRIBUTES +*/ +static int ldb_kv_attributes_load(struct ldb_module *module) +{ + struct ldb_schema_attribute *attrs; + struct ldb_context *ldb; + struct ldb_message *attrs_msg = NULL; + struct ldb_dn *dn; + unsigned int i; + unsigned int num_loaded_attrs = 0; + int r; + + ldb = ldb_module_get_ctx(module); + + if (ldb->schema.attribute_handler_override) { + /* we skip loading the @ATTRIBUTES record when a module is supplying + its own attribute handling */ + return 0; + } + + attrs_msg = ldb_msg_new(module); + if (attrs_msg == NULL) { + goto failed; + } + + dn = ldb_dn_new(module, ldb, LDB_KV_ATTRIBUTES); + if (dn == NULL) goto failed; + + r = ldb_kv_search_dn1(module, + dn, + attrs_msg, + LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC | + LDB_UNPACK_DATA_FLAG_NO_DN); + talloc_free(dn); + if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) { + goto failed; + } + if (r == LDB_ERR_NO_SUCH_OBJECT || attrs_msg->num_elements == 0) { + TALLOC_FREE(attrs_msg); + return 0; + } + + attrs = talloc_array(attrs_msg, + struct ldb_schema_attribute, + attrs_msg->num_elements + + ldb->schema.num_attributes); + if (attrs == NULL) { + goto failed; + } + + memcpy(attrs, + ldb->schema.attributes, + sizeof(ldb->schema.attributes[0]) * ldb->schema.num_attributes); + + /* mapping these flags onto ldap 'syntaxes' isn't strictly correct, + but its close enough for now */ + for (i=0;inum_elements;i++) { + unsigned flags = 0, attr_flags = 0; + const char *syntax; + const struct ldb_schema_syntax *s; + const struct ldb_schema_attribute *a = + ldb_schema_attribute_by_name(ldb, + attrs_msg->elements[i].name); + if (a != NULL && a->flags & LDB_ATTR_FLAG_FIXED) { + /* Must already be set in the array, and kept */ + continue; + } + + if (ldb_kv_attributes_flags(&attrs_msg->elements[i], &flags) != + 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Invalid @ATTRIBUTES element for '%s'", + attrs_msg->elements[i].name); + goto failed; + } + + if (flags & LDB_KV_FLAG_UNIQUE_INDEX) { + attr_flags = LDB_ATTR_FLAG_UNIQUE_INDEX; + } + flags &= ~LDB_KV_FLAG_UNIQUE_INDEX; + + /* These are not currently flags, each is exclusive */ + if (flags == LDB_KV_FLAG_CASE_INSENSITIVE) { + syntax = LDB_SYNTAX_DIRECTORY_STRING; + } else if (flags == LDB_KV_FLAG_INTEGER) { + syntax = LDB_SYNTAX_INTEGER; + } else if (flags == LDB_KV_FLAG_ORDERED_INTEGER) { + syntax = LDB_SYNTAX_ORDERED_INTEGER; + } else if (flags == 0) { + syntax = LDB_SYNTAX_OCTET_STRING; + } else { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Invalid flag combination 0x%x for '%s' " + "in @ATTRIBUTES", + flags, attrs_msg->elements[i].name); + goto failed; + } + + s = ldb_standard_syntax_by_name(ldb, syntax); + if (s == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Invalid attribute syntax '%s' for '%s' " + "in @ATTRIBUTES", + syntax, attrs_msg->elements[i].name); + goto failed; + } + + attr_flags |= LDB_ATTR_FLAG_ALLOCATED | LDB_ATTR_FLAG_FROM_DB; + + r = ldb_schema_attribute_fill_with_syntax(ldb, + attrs, + attrs_msg->elements[i].name, + attr_flags, s, + &attrs[num_loaded_attrs + ldb->schema.num_attributes]); + if (r != 0) { + goto failed; + } + num_loaded_attrs++; + } + + attrs = talloc_realloc(attrs_msg, + attrs, struct ldb_schema_attribute, + num_loaded_attrs + ldb->schema.num_attributes); + if (attrs == NULL) { + goto failed; + } + TYPESAFE_QSORT(attrs, num_loaded_attrs + ldb->schema.num_attributes, + ldb_schema_attribute_compare); + talloc_unlink(ldb, ldb->schema.attributes); + ldb->schema.attributes = talloc_steal(ldb, attrs); + ldb->schema.num_attributes = num_loaded_attrs + ldb->schema.num_attributes; + TALLOC_FREE(attrs_msg); + + return 0; +failed: + TALLOC_FREE(attrs_msg); + return -1; +} + +/* + register any index records we find for the DB +*/ +static int ldb_kv_index_load(struct ldb_module *module, + struct ldb_kv_private *ldb_kv) +{ + struct ldb_context *ldb = ldb_module_get_ctx(module); + struct ldb_dn *indexlist_dn; + int r, lmdb_subdb_version; + + if (ldb->schema.index_handler_override) { + /* + * we skip loading the @INDEXLIST record when a module is + * supplying its own attribute handling + */ + ldb_kv->cache->attribute_indexes = true; + ldb_kv->cache->one_level_indexes = + ldb->schema.one_level_indexes; + ldb_kv->cache->GUID_index_attribute = + ldb->schema.GUID_index_attribute; + ldb_kv->cache->GUID_index_dn_component = + ldb->schema.GUID_index_dn_component; + return 0; + } + + talloc_free(ldb_kv->cache->indexlist); + + ldb_kv->cache->indexlist = ldb_msg_new(ldb_kv->cache); + if (ldb_kv->cache->indexlist == NULL) { + return -1; + } + ldb_kv->cache->one_level_indexes = false; + ldb_kv->cache->attribute_indexes = false; + + indexlist_dn = ldb_dn_new(ldb_kv, ldb, LDB_KV_INDEXLIST); + if (indexlist_dn == NULL) { + return -1; + } + + r = ldb_kv_search_dn1(module, + indexlist_dn, + ldb_kv->cache->indexlist, + LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC | + LDB_UNPACK_DATA_FLAG_NO_DN); + TALLOC_FREE(indexlist_dn); + + if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) { + return -1; + } + + if (ldb_msg_find_element(ldb_kv->cache->indexlist, LDB_KV_IDXONE) != + NULL) { + ldb_kv->cache->one_level_indexes = true; + } + if (ldb_msg_find_element(ldb_kv->cache->indexlist, LDB_KV_IDXATTR) != + NULL) { + ldb_kv->cache->attribute_indexes = true; + } + ldb_kv->cache->GUID_index_attribute = ldb_msg_find_attr_as_string( + ldb_kv->cache->indexlist, LDB_KV_IDXGUID, NULL); + ldb_kv->cache->GUID_index_dn_component = ldb_msg_find_attr_as_string( + ldb_kv->cache->indexlist, LDB_KV_IDX_DN_GUID, NULL); + + lmdb_subdb_version = ldb_msg_find_attr_as_int( + ldb_kv->cache->indexlist, LDB_KV_IDX_LMDB_SUBDB, 0); + + if (lmdb_subdb_version != 0) { + ldb_set_errstring(ldb, + "FATAL: This ldb_mdb database has " + "been written in a new version of LDB " + "using a sub-database index that " + "is not understood by ldb " + LDB_VERSION); + return -1; + } + + return 0; +} + +/* + initialise the baseinfo record +*/ +static int ldb_kv_baseinfo_init(struct ldb_module *module) +{ + struct ldb_context *ldb; + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + struct ldb_message *msg; + struct ldb_message_element el; + struct ldb_val val; + int ret; + /* the initial sequence number must be different from the one + set in ltdb_cache_free(). Thanks to Jon for pointing this + out. */ + const char *initial_sequence_number = "1"; + + ldb = ldb_module_get_ctx(module); + + ldb_kv->sequence_number = atof(initial_sequence_number); + + msg = ldb_msg_new(ldb_kv); + if (msg == NULL) { + goto failed; + } + + msg->num_elements = 1; + msg->elements = ⪙ + msg->dn = ldb_dn_new(msg, ldb, LDB_KV_BASEINFO); + if (!msg->dn) { + goto failed; + } + el.name = talloc_strdup(msg, LDB_KV_SEQUENCE_NUMBER); + if (!el.name) { + goto failed; + } + el.values = &val; + el.num_values = 1; + el.flags = 0; + val.data = (uint8_t *)talloc_strdup(msg, initial_sequence_number); + if (!val.data) { + goto failed; + } + val.length = 1; + + ret = ldb_kv_store(module, msg, TDB_INSERT); + + talloc_free(msg); + + return ret; + +failed: + talloc_free(msg); + errno = ENOMEM; + return LDB_ERR_OPERATIONS_ERROR; +} + +/* + free any cache records + */ +static void ldb_kv_cache_free(struct ldb_module *module) +{ + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + + ldb_kv->sequence_number = 0; + talloc_free(ldb_kv->cache); + ldb_kv->cache = NULL; +} + +/* + force a cache reload +*/ +int ldb_kv_cache_reload(struct ldb_module *module) +{ + ldb_kv_attributes_unload(module); + ldb_kv_cache_free(module); + return ldb_kv_cache_load(module); +} +static int get_pack_format_version(struct ldb_val key, + struct ldb_val data, + void *private_data) +{ + uint32_t *v = (uint32_t *) private_data; + return ldb_unpack_get_format(&data, v); +} + +/* + load the cache records +*/ +int ldb_kv_cache_load(struct ldb_module *module) +{ + struct ldb_context *ldb; + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + struct ldb_dn *baseinfo_dn = NULL, *options_dn = NULL; + uint64_t seq; + struct ldb_message *baseinfo = NULL, *options = NULL; + const struct ldb_schema_attribute *a; + bool have_write_txn = false; + int r; + struct ldb_val key; + + ldb = ldb_module_get_ctx(module); + + /* a very fast check to avoid extra database reads */ + if (ldb_kv->cache != NULL && !ldb_kv->kv_ops->has_changed(ldb_kv)) { + return 0; + } + + if (ldb_kv->cache == NULL) { + ldb_kv->cache = talloc_zero(ldb_kv, struct ldb_kv_cache); + if (ldb_kv->cache == NULL) + goto failed; + } + + baseinfo = ldb_msg_new(ldb_kv->cache); + if (baseinfo == NULL) goto failed; + + baseinfo_dn = ldb_dn_new(baseinfo, ldb, LDB_KV_BASEINFO); + if (baseinfo_dn == NULL) goto failed; + + r = ldb_kv->kv_ops->lock_read(module); + if (r != LDB_SUCCESS) { + goto failed; + } + + key = ldb_kv_key_dn(baseinfo, baseinfo_dn); + if (!key.data) { + goto failed_and_unlock; + } + + /* Read packing format from first 4 bytes of @BASEINFO record */ + r = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, + get_pack_format_version, + &ldb_kv->pack_format_version); + + /* possibly initialise the baseinfo */ + if (r == LDB_ERR_NO_SUCH_OBJECT) { + + /* Give up the read lock, try again with a write lock */ + r = ldb_kv->kv_ops->unlock_read(module); + if (r != LDB_SUCCESS) { + goto failed; + } + + if (ldb_kv->kv_ops->begin_write(ldb_kv) != 0) { + goto failed; + } + + have_write_txn = true; + + /* + * We need to write but haven't figured out packing format yet. + * Just go with version 1 and we'll repack if we got it wrong. + */ + ldb_kv->pack_format_version = LDB_PACKING_FORMAT; + ldb_kv->target_pack_format_version = LDB_PACKING_FORMAT; + + /* error handling for ltdb_baseinfo_init() is by + looking for the record again. */ + ldb_kv_baseinfo_init(module); + + } else if (r != LDB_SUCCESS) { + goto failed_and_unlock; + } + + /* OK now we definitely have a @BASEINFO record so fetch it */ + r = ldb_kv_search_dn1(module, baseinfo_dn, baseinfo, 0); + if (r != LDB_SUCCESS) { + goto failed_and_unlock; + } + + /* Ignore the result, and update the sequence number */ + ldb_kv->kv_ops->has_changed(ldb_kv); + + /* if the current internal sequence number is the same as the one + in the database then assume the rest of the cache is OK */ + seq = ldb_msg_find_attr_as_uint64(baseinfo, LDB_KV_SEQUENCE_NUMBER, 0); + if (seq == ldb_kv->sequence_number) { + goto done; + } + ldb_kv->sequence_number = seq; + + /* Read an interpret database options */ + + options = ldb_msg_new(ldb_kv->cache); + if (options == NULL) goto failed_and_unlock; + + options_dn = ldb_dn_new(options, ldb, LDB_KV_OPTIONS); + if (options_dn == NULL) goto failed_and_unlock; + + r = ldb_kv_search_dn1(module, options_dn, options, 0); + talloc_free(options_dn); + if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) { + goto failed_and_unlock; + } + + /* set flags if they do exist */ + if (r == LDB_SUCCESS) { + ldb_kv->check_base = + ldb_msg_find_attr_as_bool(options, LDB_KV_CHECK_BASE, false); + ldb_kv->disallow_dn_filter = ldb_msg_find_attr_as_bool( + options, LDB_KV_DISALLOW_DN_FILTER, false); + } else { + ldb_kv->check_base = false; + ldb_kv->disallow_dn_filter = false; + } + + /* + * ltdb_attributes_unload() calls internally talloc_free() on + * any non-fixed elemnts in ldb->schema.attributes. + * + * NOTE WELL: This is per-ldb, not per module, so overwrites + * the handlers across all databases when used under Samba's + * partition module. + */ + ldb_kv_attributes_unload(module); + + if (ldb_kv_index_load(module, ldb_kv) == -1) { + goto failed_and_unlock; + } + + /* + * NOTE WELL: This is per-ldb, not per module, so overwrites + * the handlers across all databases when used under Samba's + * partition module. + */ + if (ldb_kv_attributes_load(module) == -1) { + goto failed_and_unlock; + } + + /* + * Initialise packing version and GUID index syntax, and force the + * two to travel together, ie a GUID indexed database must use V2 + * packing format and a DN indexed database must use V1. + */ + ldb_kv->GUID_index_syntax = NULL; + if (ldb_kv->cache->GUID_index_attribute != NULL) { + ldb_kv->target_pack_format_version = LDB_PACKING_FORMAT_V2; + + /* + * Now the attributes are loaded, set the guid_index_syntax. + * This can't fail, it will return a default at worst + */ + a = ldb_schema_attribute_by_name( + ldb, ldb_kv->cache->GUID_index_attribute); + ldb_kv->GUID_index_syntax = a->syntax; + } else { + ldb_kv->target_pack_format_version = LDB_PACKING_FORMAT; + } + +done: + if (have_write_txn) { + if (ldb_kv->kv_ops->finish_write(ldb_kv) != 0) { + goto failed; + } + } else { + ldb_kv->kv_ops->unlock_read(module); + } + + talloc_free(options); + talloc_free(baseinfo); + return 0; + +failed_and_unlock: + if (have_write_txn) { + ldb_kv->kv_ops->abort_write(ldb_kv); + } else { + ldb_kv->kv_ops->unlock_read(module); + } + +failed: + talloc_free(options); + talloc_free(baseinfo); + return -1; +} + + +/* + increase the sequence number to indicate a database change +*/ +int ldb_kv_increase_sequence_number(struct ldb_module *module) +{ + struct ldb_context *ldb; + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + struct ldb_message *msg; + struct ldb_message_element el[2]; + struct ldb_val val; + struct ldb_val val_time; + time_t t = time(NULL); + char *s = NULL; + int ret; + + ldb = ldb_module_get_ctx(module); + + msg = ldb_msg_new(ldb_kv); + if (msg == NULL) { + errno = ENOMEM; + return LDB_ERR_OPERATIONS_ERROR; + } + + s = talloc_asprintf(msg, "%llu", ldb_kv->sequence_number + 1); + if (!s) { + talloc_free(msg); + errno = ENOMEM; + return LDB_ERR_OPERATIONS_ERROR; + } + + msg->num_elements = ARRAY_SIZE(el); + msg->elements = el; + msg->dn = ldb_dn_new(msg, ldb, LDB_KV_BASEINFO); + if (msg->dn == NULL) { + talloc_free(msg); + errno = ENOMEM; + return LDB_ERR_OPERATIONS_ERROR; + } + el[0].name = talloc_strdup(msg, LDB_KV_SEQUENCE_NUMBER); + if (el[0].name == NULL) { + talloc_free(msg); + errno = ENOMEM; + return LDB_ERR_OPERATIONS_ERROR; + } + el[0].values = &val; + el[0].num_values = 1; + el[0].flags = LDB_FLAG_MOD_REPLACE; + val.data = (uint8_t *)s; + val.length = strlen(s); + + el[1].name = talloc_strdup(msg, LDB_KV_MOD_TIMESTAMP); + if (el[1].name == NULL) { + talloc_free(msg); + errno = ENOMEM; + return LDB_ERR_OPERATIONS_ERROR; + } + el[1].values = &val_time; + el[1].num_values = 1; + el[1].flags = LDB_FLAG_MOD_REPLACE; + + s = ldb_timestring(msg, t); + if (s == NULL) { + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + val_time.data = (uint8_t *)s; + val_time.length = strlen(s); + + ret = ldb_kv_modify_internal(module, msg, NULL); + + talloc_free(msg); + + if (ret == LDB_SUCCESS) { + ldb_kv->sequence_number += 1; + } + + /* updating the tdb_seqnum here avoids us reloading the cache + records due to our own modification */ + ldb_kv->kv_ops->has_changed(ldb_kv); + + return ret; +} + +int ldb_kv_check_at_attributes_values(const struct ldb_val *value) +{ + unsigned int i; + + for (i = 0; ldb_kv_valid_attr_flags[i].name != NULL; i++) { + if ((strcmp(ldb_kv_valid_attr_flags[i].name, + (char *)value->data) == 0)) { + return 0; + } + } + + return -1; +} diff --git a/ldb-2.0.8/ldb_key_value/ldb_kv_index.c b/ldb-2.0.8/ldb_key_value/ldb_kv_index.c new file mode 100644 index 0000000..0853b28 --- /dev/null +++ b/ldb-2.0.8/ldb_key_value/ldb_kv_index.c @@ -0,0 +1,3917 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004-2009 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb key value backend - indexing + * + * Description: indexing routines for ldb key value backend + * + * Author: Andrew Tridgell + */ + +/* + +LDB Index design and choice of key: +======================================= + +LDB has index records held as LDB objects with a special record like: + +dn: @INDEX:attr:value + +value may be base64 encoded, if it is deemed not printable: + +dn: @INDEX:attr::base64-value + +In each record, there is two possible formats: + +The original format is: +----------------------- + +dn: @INDEX:NAME:DNSUPDATEPROXY +@IDXVERSION: 2 +@IDX: CN=DnsUpdateProxy,CN=Users,DC=addom,DC=samba,DC=example,DC=com + +In this format, @IDX is multi-valued, one entry for each match + +The corrosponding entry is stored in a TDB record with key: + +DN=CN=DNSUPDATEPROXY,CN=USERS,DC=ADDOM,DC=SAMBA,DC=EXAMPLE,DC=COM + +(This allows a scope BASE search to directly find the record via +a simple casefold of the DN). + +The original mixed-case DN is stored in the entry iself. + + +The new 'GUID index' format is: +------------------------------- + +dn: @INDEX:NAME:DNSUPDATEPROXY +@IDXVERSION: 3 +@IDX: [[...]] + +The binary guid is 16 bytes, as bytes and not expanded as hexidecimal +or pretty-printed. The GUID is chosen from the message to be stored +by the @IDXGUID attribute on @INDEXLIST. + +If there are multiple values the @IDX value simply becomes longer, +in multiples of 16. + +The corrosponding entry is stored in a TDB record with key: + +GUID= + +This allows a very quick translation between the fixed-length index +values and the TDB key, while seperating entries from other data +in the TDB, should they be unlucky enough to start with the bytes of +the 'DN=' prefix. + +Additionally, this allows a scope BASE search to directly find the +record via a simple match on a GUID= extended DN, controlled via +@IDX_DN_GUID on @INDEXLIST + +Exception for special @ DNs: + +@BASEINFO, @INDEXLIST and all other special DNs are stored as per the +original format, as they are never referenced in an index and are used +to bootstrap the database. + + +Control points for choice of index mode +--------------------------------------- + +The choice of index and TDB key mode is made based (for example, from +Samba) on entries in the @INDEXLIST DN: + +dn: @INDEXLIST +@IDXGUID: objectGUID +@IDX_DN_GUID: GUID + +By default, the original DN format is used. + + +Control points for choosing indexed attributes +---------------------------------------------- + +@IDXATTR controls if an attribute is indexed + +dn: @INDEXLIST +@IDXATTR: samAccountName +@IDXATTR: nETBIOSName + + +C Override functions +-------------------- + +void ldb_schema_set_override_GUID_index(struct ldb_context *ldb, + const char *GUID_index_attribute, + const char *GUID_index_dn_component) + +This is used, particularly in combination with the below, instead of +the @IDXGUID and @IDX_DN_GUID values in @INDEXLIST. + +void ldb_schema_set_override_indexlist(struct ldb_context *ldb, + bool one_level_indexes); +void ldb_schema_attribute_set_override_handler(struct ldb_context *ldb, + ldb_attribute_handler_override_fn_t override, + void *private_data); + +When the above two functions are called in combination, the @INDEXLIST +values are not read from the DB, so +ldb_schema_set_override_GUID_index() must be called. + +*/ + +#include "ldb_kv.h" +#include "../ldb_tdb/ldb_tdb.h" +#include "ldb_private.h" +#include "lib/util/binsearch.h" +#include "lib/util/attr.h" + +struct dn_list { + unsigned int count; + struct ldb_val *dn; + /* + * Do not optimise the intersection of this list, + * we must never return an entry not in this + * list. This allows the index for + * SCOPE_ONELEVEL to be trusted. + */ + bool strict; +}; + +struct ldb_kv_idxptr { + /* + * In memory tdb to cache the index updates performed during a + * transaction. This improves the performance of operations like + * re-index and join + */ + struct tdb_context *itdb; + int error; +}; + +enum key_truncation { + KEY_NOT_TRUNCATED, + KEY_TRUNCATED, +}; + +static int ldb_kv_write_index_dn_guid(struct ldb_module *module, + const struct ldb_message *msg, + int add); +static int ldb_kv_index_dn_base_dn(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + struct ldb_dn *base_dn, + struct dn_list *dn_list, + enum key_truncation *truncation); + +static void ldb_kv_dn_list_sort(struct ldb_kv_private *ldb_kv, + struct dn_list *list); + +/* we put a @IDXVERSION attribute on index entries. This + allows us to tell if it was written by an older version +*/ +#define LDB_KV_INDEXING_VERSION 2 + +#define LDB_KV_GUID_INDEXING_VERSION 3 + +static unsigned ldb_kv_max_key_length(struct ldb_kv_private *ldb_kv) +{ + if (ldb_kv->max_key_length == 0) { + return UINT_MAX; + } + return ldb_kv->max_key_length; +} + +/* enable the idxptr mode when transactions start */ +int ldb_kv_index_transaction_start( + struct ldb_module *module, + size_t cache_size) +{ + struct ldb_kv_private *ldb_kv = talloc_get_type( + ldb_module_get_private(module), struct ldb_kv_private); + ldb_kv->idxptr = talloc_zero(ldb_kv, struct ldb_kv_idxptr); + if (ldb_kv->idxptr == NULL) { + return ldb_oom(ldb_module_get_ctx(module)); + } + + ldb_kv->idxptr->itdb = tdb_open( + NULL, + cache_size, + TDB_INTERNAL, + O_RDWR, + 0); + if (ldb_kv->idxptr->itdb == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return LDB_SUCCESS; +} + +/* + see if two ldb_val structures contain exactly the same data + return -1 or 1 for a mismatch, 0 for match +*/ +static int ldb_val_equal_exact_for_qsort(const struct ldb_val *v1, + const struct ldb_val *v2) +{ + if (v1->length > v2->length) { + return -1; + } + if (v1->length < v2->length) { + return 1; + } + return memcmp(v1->data, v2->data, v1->length); +} + +/* + see if two ldb_val structures contain exactly the same data + return -1 or 1 for a mismatch, 0 for match +*/ +static int ldb_val_equal_exact_ordered(const struct ldb_val v1, + const struct ldb_val *v2) +{ + if (v1.length > v2->length) { + return -1; + } + if (v1.length < v2->length) { + return 1; + } + return memcmp(v1.data, v2->data, v1.length); +} + + +/* + find a entry in a dn_list, using a ldb_val. Uses a case sensitive + binary-safe comparison for the 'dn' returns -1 if not found + + This is therefore safe when the value is a GUID in the future + */ +static int ldb_kv_dn_list_find_val(struct ldb_kv_private *ldb_kv, + const struct dn_list *list, + const struct ldb_val *v) +{ + unsigned int i; + struct ldb_val *exact = NULL, *next = NULL; + + if (ldb_kv->cache->GUID_index_attribute == NULL) { + for (i=0; icount; i++) { + if (ldb_val_equal_exact(&list->dn[i], v) == 1) { + return i; + } + } + return -1; + } + + BINARY_ARRAY_SEARCH_GTE(list->dn, list->count, + *v, ldb_val_equal_exact_ordered, + exact, next); + if (exact == NULL) { + return -1; + } + /* Not required, but keeps the compiler quiet */ + if (next != NULL) { + return -1; + } + + i = exact - list->dn; + return i; +} + +/* + find a entry in a dn_list. Uses a case sensitive comparison with the dn + returns -1 if not found + */ +static int ldb_kv_dn_list_find_msg(struct ldb_kv_private *ldb_kv, + struct dn_list *list, + const struct ldb_message *msg) +{ + struct ldb_val v; + const struct ldb_val *key_val; + if (ldb_kv->cache->GUID_index_attribute == NULL) { + const char *dn_str = ldb_dn_get_linearized(msg->dn); + v.data = discard_const_p(unsigned char, dn_str); + v.length = strlen(dn_str); + } else { + key_val = ldb_msg_find_ldb_val( + msg, ldb_kv->cache->GUID_index_attribute); + if (key_val == NULL) { + return -1; + } + v = *key_val; + } + return ldb_kv_dn_list_find_val(ldb_kv, list, &v); +} + +/* + this is effectively a cast function, but with lots of paranoia + checks and also copes with CPUs that are fussy about pointer + alignment + */ +static struct dn_list *ldb_kv_index_idxptr(struct ldb_module *module, + TDB_DATA rec) +{ + struct dn_list *list; + if (rec.dsize != sizeof(void *)) { + ldb_asprintf_errstring(ldb_module_get_ctx(module), + "Bad data size for idxptr %u", (unsigned)rec.dsize); + return NULL; + } + /* note that we can't just use a cast here, as rec.dptr may + not be aligned sufficiently for a pointer. A cast would cause + platforms like some ARM CPUs to crash */ + memcpy(&list, rec.dptr, sizeof(void *)); + list = talloc_get_type(list, struct dn_list); + if (list == NULL) { + ldb_asprintf_errstring(ldb_module_get_ctx(module), + "Bad type '%s' for idxptr", + talloc_get_name(list)); + return NULL; + } + return list; +} + +enum dn_list_will_be_read_only { + DN_LIST_MUTABLE = 0, + DN_LIST_WILL_BE_READ_ONLY = 1, +}; + +/* + return the @IDX list in an index entry for a dn as a + struct dn_list + */ +static int ldb_kv_dn_list_load(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + struct ldb_dn *dn, + struct dn_list *list, + enum dn_list_will_be_read_only read_only) +{ + struct ldb_message *msg; + int ret, version; + struct ldb_message_element *el; + TDB_DATA rec = {0}; + struct dn_list *list2; + bool from_primary_cache = false; + TDB_DATA key = {0}; + + list->dn = NULL; + list->count = 0; + list->strict = false; + + /* + * See if we have an in memory index cache + */ + if (ldb_kv->idxptr == NULL) { + goto normal_index; + } + + key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn)); + key.dsize = strlen((char *)key.dptr); + + /* + * Have we cached this index record? + * If we have a nested transaction cache try that first. + * then try the transaction cache. + * if the record is not cached it will need to be read from disk. + */ + if (ldb_kv->nested_idx_ptr != NULL) { + rec = tdb_fetch(ldb_kv->nested_idx_ptr->itdb, key); + } + if (rec.dptr == NULL) { + from_primary_cache = true; + rec = tdb_fetch(ldb_kv->idxptr->itdb, key); + } + if (rec.dptr == NULL) { + goto normal_index; + } + + /* we've found an in-memory index entry */ + list2 = ldb_kv_index_idxptr(module, rec); + if (list2 == NULL) { + free(rec.dptr); + return LDB_ERR_OPERATIONS_ERROR; + } + free(rec.dptr); + + /* + * If this is a read only transaction the indexes will not be + * changed so we don't need a copy in the event of a rollback + * + * In this case make an early return + */ + if (read_only == DN_LIST_WILL_BE_READ_ONLY) { + *list = *list2; + return LDB_SUCCESS; + } + + /* + * record was read from the sub transaction cache, so we have + * already copied the primary cache record + */ + if (!from_primary_cache) { + *list = *list2; + return LDB_SUCCESS; + } + + /* + * No index sub transaction active, so no need to cache a copy + */ + if (ldb_kv->nested_idx_ptr == NULL) { + *list = *list2; + return LDB_SUCCESS; + } + + /* + * There is an active index sub transaction, and the record was + * found in the primary index transaction cache. A copy of the + * record needs be taken to prevent the original entry being + * altered, until the index sub transaction is committed. + */ + + { + struct ldb_val *dns = NULL; + size_t x = 0; + + dns = talloc_array( + list, + struct ldb_val, + list2->count); + if (dns == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + for (x = 0; x < list2->count; x++) { + dns[x].length = list2->dn[x].length; + dns[x].data = talloc_memdup( + dns, + list2->dn[x].data, + list2->dn[x].length); + if (dns[x].data == NULL) { + TALLOC_FREE(dns); + return LDB_ERR_OPERATIONS_ERROR; + } + } + list->dn = dns; + list->count = list2->count; + } + return LDB_SUCCESS; + + /* + * Index record not found in the caches, read it from the + * database. + */ +normal_index: + msg = ldb_msg_new(list); + if (msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_kv_search_dn1(module, + dn, + msg, + LDB_UNPACK_DATA_FLAG_NO_DN | + /* + * The entry point ldb_kv_search_indexed is + * only called from the read-locked + * ldb_kv_search. + */ + LDB_UNPACK_DATA_FLAG_READ_LOCKED); + if (ret != LDB_SUCCESS) { + talloc_free(msg); + return ret; + } + + el = ldb_msg_find_element(msg, LDB_KV_IDX); + if (!el) { + talloc_free(msg); + return LDB_SUCCESS; + } + + version = ldb_msg_find_attr_as_int(msg, LDB_KV_IDXVERSION, 0); + + /* + * we avoid copying the strings by stealing the list. We have + * to steal msg onto el->values (which looks odd) because + * the memory is allocated on msg, not on each value. + */ + if (ldb_kv->cache->GUID_index_attribute == NULL) { + /* check indexing version number */ + if (version != LDB_KV_INDEXING_VERSION) { + ldb_debug_set(ldb_module_get_ctx(module), + LDB_DEBUG_ERROR, + "Wrong DN index version %d " + "expected %d for %s", + version, LDB_KV_INDEXING_VERSION, + ldb_dn_get_linearized(dn)); + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + talloc_steal(el->values, msg); + list->dn = talloc_steal(list, el->values); + list->count = el->num_values; + } else { + unsigned int i; + if (version != LDB_KV_GUID_INDEXING_VERSION) { + /* This is quite likely during the DB startup + on first upgrade to using a GUID index */ + ldb_debug_set(ldb_module_get_ctx(module), + LDB_DEBUG_ERROR, + "Wrong GUID index version %d " + "expected %d for %s", + version, LDB_KV_GUID_INDEXING_VERSION, + ldb_dn_get_linearized(dn)); + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (el->num_values == 0) { + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + if ((el->values[0].length % LDB_KV_GUID_SIZE) != 0) { + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + list->count = el->values[0].length / LDB_KV_GUID_SIZE; + list->dn = talloc_array(list, struct ldb_val, list->count); + if (list->dn == NULL) { + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* + * The actual data is on msg. + */ + talloc_steal(list->dn, msg); + for (i = 0; i < list->count; i++) { + list->dn[i].data + = &el->values[0].data[i * LDB_KV_GUID_SIZE]; + list->dn[i].length = LDB_KV_GUID_SIZE; + } + } + + /* We don't need msg->elements any more */ + talloc_free(msg->elements); + return LDB_SUCCESS; +} + +int ldb_kv_key_dn_from_idx(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + TALLOC_CTX *mem_ctx, + struct ldb_dn *dn, + struct ldb_val *ldb_key) +{ + struct ldb_context *ldb = ldb_module_get_ctx(module); + int ret; + int index = 0; + enum key_truncation truncation = KEY_NOT_TRUNCATED; + struct dn_list *list = talloc(mem_ctx, struct dn_list); + if (list == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_kv_index_dn_base_dn(module, ldb_kv, dn, list, &truncation); + if (ret != LDB_SUCCESS) { + TALLOC_FREE(list); + return ret; + } + + if (list->count == 0) { + TALLOC_FREE(list); + return LDB_ERR_NO_SUCH_OBJECT; + } + + if (list->count > 1 && truncation == KEY_NOT_TRUNCATED) { + const char *dn_str = ldb_dn_get_linearized(dn); + ldb_asprintf_errstring(ldb_module_get_ctx(module), + __location__ + ": Failed to read DN index " + "against %s for %s: too many " + "values (%u > 1)", + ldb_kv->cache->GUID_index_attribute, + dn_str, + list->count); + TALLOC_FREE(list); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + if (list->count > 0 && truncation == KEY_TRUNCATED) { + /* + * DN key has been truncated, need to inspect the actual + * records to locate the actual DN + */ + unsigned int i; + index = -1; + for (i=0; i < list->count; i++) { + uint8_t guid_key[LDB_KV_GUID_KEY_SIZE]; + struct ldb_val key = { + .data = guid_key, + .length = sizeof(guid_key) + }; + const int flags = LDB_UNPACK_DATA_FLAG_NO_ATTRS; + struct ldb_message *rec = ldb_msg_new(ldb); + if (rec == NULL) { + TALLOC_FREE(list); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_kv_idx_to_key( + module, ldb_kv, ldb, &list->dn[i], &key); + if (ret != LDB_SUCCESS) { + TALLOC_FREE(list); + TALLOC_FREE(rec); + return ret; + } + + ret = + ldb_kv_search_key(module, ldb_kv, key, rec, flags); + if (key.data != guid_key) { + TALLOC_FREE(key.data); + } + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + /* + * the record has disappeared? + * yes, this can happen + */ + TALLOC_FREE(rec); + continue; + } + + if (ret != LDB_SUCCESS) { + /* an internal error */ + TALLOC_FREE(rec); + TALLOC_FREE(list); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* + * We found the actual DN that we wanted from in the + * multiple values that matched the index + * (due to truncation), so return that. + * + */ + if (ldb_dn_compare(dn, rec->dn) == 0) { + index = i; + TALLOC_FREE(rec); + break; + } + } + + /* + * We matched the index but the actual DN we wanted + * was not here. + */ + if (index == -1) { + TALLOC_FREE(list); + return LDB_ERR_NO_SUCH_OBJECT; + } + } + + /* The ldb_key memory is allocated by the caller */ + ret = ldb_kv_guid_to_key(&list->dn[index], ldb_key); + TALLOC_FREE(list); + + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return LDB_SUCCESS; +} + + + +/* + save a dn_list into a full @IDX style record + */ +static int ldb_kv_dn_list_store_full(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + struct ldb_dn *dn, + struct dn_list *list) +{ + struct ldb_message *msg; + int ret; + + msg = ldb_msg_new(module); + if (!msg) { + return ldb_module_oom(module); + } + + msg->dn = dn; + + if (list->count == 0) { + ret = ldb_kv_delete_noindex(module, msg); + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + ret = LDB_SUCCESS; + } + TALLOC_FREE(msg); + return ret; + } + + if (ldb_kv->cache->GUID_index_attribute == NULL) { + ret = ldb_msg_add_fmt(msg, LDB_KV_IDXVERSION, "%u", + LDB_KV_INDEXING_VERSION); + if (ret != LDB_SUCCESS) { + TALLOC_FREE(msg); + return ldb_module_oom(module); + } + } else { + ret = ldb_msg_add_fmt(msg, LDB_KV_IDXVERSION, "%u", + LDB_KV_GUID_INDEXING_VERSION); + if (ret != LDB_SUCCESS) { + TALLOC_FREE(msg); + return ldb_module_oom(module); + } + } + + if (list->count > 0) { + struct ldb_message_element *el; + + ret = ldb_msg_add_empty(msg, LDB_KV_IDX, LDB_FLAG_MOD_ADD, &el); + if (ret != LDB_SUCCESS) { + TALLOC_FREE(msg); + return ldb_module_oom(module); + } + + if (ldb_kv->cache->GUID_index_attribute == NULL) { + el->values = list->dn; + el->num_values = list->count; + } else { + struct ldb_val v; + unsigned int i; + el->values = talloc_array(msg, + struct ldb_val, 1); + if (el->values == NULL) { + TALLOC_FREE(msg); + return ldb_module_oom(module); + } + + v.data = talloc_array_size(el->values, + list->count, + LDB_KV_GUID_SIZE); + if (v.data == NULL) { + TALLOC_FREE(msg); + return ldb_module_oom(module); + } + + v.length = talloc_get_size(v.data); + + for (i = 0; i < list->count; i++) { + if (list->dn[i].length != + LDB_KV_GUID_SIZE) { + TALLOC_FREE(msg); + return ldb_module_operr(module); + } + memcpy(&v.data[LDB_KV_GUID_SIZE*i], + list->dn[i].data, + LDB_KV_GUID_SIZE); + } + el->values[0] = v; + el->num_values = 1; + } + } + + ret = ldb_kv_store(module, msg, TDB_REPLACE); + TALLOC_FREE(msg); + return ret; +} + +/* + save a dn_list into the database, in either @IDX or internal format + */ +static int ldb_kv_dn_list_store(struct ldb_module *module, + struct ldb_dn *dn, + struct dn_list *list) +{ + struct ldb_kv_private *ldb_kv = talloc_get_type( + ldb_module_get_private(module), struct ldb_kv_private); + TDB_DATA rec = {0}; + TDB_DATA key = {0}; + + int ret = LDB_SUCCESS; + struct dn_list *list2 = NULL; + struct ldb_kv_idxptr *idxptr = NULL; + + key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn)); + if (key.dptr == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + key.dsize = strlen((char *)key.dptr); + + /* + * If there is an index sub transaction active, update the + * sub transaction index cache. Otherwise update the + * primary index cache + */ + if (ldb_kv->nested_idx_ptr != NULL) { + idxptr = ldb_kv->nested_idx_ptr; + } else { + idxptr = ldb_kv->idxptr; + } + /* + * Get the cache entry for the index + * + * As the value in the cache is a pointer to a dn_list we update + * the dn_list directly. + * + */ + rec = tdb_fetch(idxptr->itdb, key); + if (rec.dptr != NULL) { + list2 = ldb_kv_index_idxptr(module, rec); + if (list2 == NULL) { + free(rec.dptr); + return LDB_ERR_OPERATIONS_ERROR; + } + free(rec.dptr); + /* Now put the updated pointer back in the cache */ + if (list->dn == NULL) { + list2->dn = NULL; + list2->count = 0; + } else { + list2->dn = talloc_steal(list2, list->dn); + list2->count = list->count; + } + return LDB_SUCCESS; + } + + list2 = talloc(idxptr, struct dn_list); + if (list2 == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + list2->dn = talloc_steal(list2, list->dn); + list2->count = list->count; + + rec.dptr = (uint8_t *)&list2; + rec.dsize = sizeof(void *); + + + /* + * This is not a store into the main DB, but into an in-memory + * TDB, so we don't need a guard on ltdb->read_only + * + * Also as we directly update the in memory dn_list for existing + * cache entries we must be adding a new entry to the cache. + */ + ret = tdb_store(idxptr->itdb, key, rec, TDB_INSERT); + if (ret != 0) { + return ltdb_err_map( tdb_error(idxptr->itdb)); + } + return LDB_SUCCESS; +} + +/* + traverse function for storing the in-memory index entries on disk + */ +static int ldb_kv_index_traverse_store(_UNUSED_ struct tdb_context *tdb, + TDB_DATA key, + TDB_DATA data, + void *state) +{ + struct ldb_module *module = state; + struct ldb_kv_private *ldb_kv = talloc_get_type( + ldb_module_get_private(module), struct ldb_kv_private); + struct ldb_dn *dn; + struct ldb_context *ldb = ldb_module_get_ctx(module); + struct ldb_val v; + struct dn_list *list; + + list = ldb_kv_index_idxptr(module, data); + if (list == NULL) { + ldb_kv->idxptr->error = LDB_ERR_OPERATIONS_ERROR; + return -1; + } + + v.data = key.dptr; + v.length = strnlen((char *)key.dptr, key.dsize); + + dn = ldb_dn_from_ldb_val(module, ldb, &v); + if (dn == NULL) { + ldb_asprintf_errstring(ldb, "Failed to parse index key %*.*s as an LDB DN", (int)v.length, (int)v.length, (const char *)v.data); + ldb_kv->idxptr->error = LDB_ERR_OPERATIONS_ERROR; + return -1; + } + + ldb_kv->idxptr->error = + ldb_kv_dn_list_store_full(module, ldb_kv, dn, list); + talloc_free(dn); + if (ldb_kv->idxptr->error != 0) { + return -1; + } + return 0; +} + +/* cleanup the idxptr mode when transaction commits */ +int ldb_kv_index_transaction_commit(struct ldb_module *module) +{ + struct ldb_kv_private *ldb_kv = talloc_get_type( + ldb_module_get_private(module), struct ldb_kv_private); + int ret; + + struct ldb_context *ldb = ldb_module_get_ctx(module); + + ldb_reset_err_string(ldb); + + if (ldb_kv->idxptr->itdb) { + tdb_traverse( + ldb_kv->idxptr->itdb, ldb_kv_index_traverse_store, module); + tdb_close(ldb_kv->idxptr->itdb); + } + + ret = ldb_kv->idxptr->error; + if (ret != LDB_SUCCESS) { + if (!ldb_errstring(ldb)) { + ldb_set_errstring(ldb, ldb_strerror(ret)); + } + ldb_asprintf_errstring(ldb, "Failed to store index records in transaction commit: %s", ldb_errstring(ldb)); + } + + talloc_free(ldb_kv->idxptr); + ldb_kv->idxptr = NULL; + return ret; +} + +/* cleanup the idxptr mode when transaction cancels */ +int ldb_kv_index_transaction_cancel(struct ldb_module *module) +{ + struct ldb_kv_private *ldb_kv = talloc_get_type( + ldb_module_get_private(module), struct ldb_kv_private); + if (ldb_kv->idxptr && ldb_kv->idxptr->itdb) { + tdb_close(ldb_kv->idxptr->itdb); + } + TALLOC_FREE(ldb_kv->idxptr); + if (ldb_kv->nested_idx_ptr && ldb_kv->nested_idx_ptr->itdb) { + tdb_close(ldb_kv->nested_idx_ptr->itdb); + } + TALLOC_FREE(ldb_kv->nested_idx_ptr); + return LDB_SUCCESS; +} + + +/* + return the dn key to be used for an index + the caller is responsible for freeing +*/ +static struct ldb_dn *ldb_kv_index_key(struct ldb_context *ldb, + struct ldb_kv_private *ldb_kv, + const char *attr, + const struct ldb_val *value, + const struct ldb_schema_attribute **ap, + enum key_truncation *truncation) +{ + struct ldb_dn *ret; + struct ldb_val v; + const struct ldb_schema_attribute *a = NULL; + char *attr_folded = NULL; + const char *attr_for_dn = NULL; + int r; + bool should_b64_encode; + + unsigned int max_key_length = ldb_kv_max_key_length(ldb_kv); + size_t key_len = 0; + size_t attr_len = 0; + const size_t indx_len = sizeof(LDB_KV_INDEX) - 1; + unsigned frmt_len = 0; + const size_t additional_key_length = 4; + unsigned int num_separators = 3; /* Estimate for overflow check */ + const size_t min_data = 1; + const size_t min_key_length = additional_key_length + + indx_len + num_separators + min_data; + struct ldb_val empty; + + /* + * Accept a NULL value as a request for a key with no value. This is + * different from passing an empty value, which might be given + * significance by some canonicalise functions. + */ + bool empty_val = value == NULL; + if (empty_val) { + empty.length = 0; + empty.data = discard_const_p(unsigned char, ""); + value = ∅ + } + + if (attr[0] == '@') { + attr_for_dn = attr; + v = *value; + if (ap != NULL) { + *ap = NULL; + } + } else { + attr_folded = ldb_attr_casefold(ldb, attr); + if (!attr_folded) { + return NULL; + } + + attr_for_dn = attr_folded; + + a = ldb_schema_attribute_by_name(ldb, attr); + if (ap) { + *ap = a; + } + + if (empty_val) { + v = *value; + } else { + ldb_attr_handler_t fn; + if (a->syntax->index_format_fn && + ldb_kv->cache->GUID_index_attribute != NULL) { + fn = a->syntax->index_format_fn; + } else { + fn = a->syntax->canonicalise_fn; + } + r = fn(ldb, ldb, value, &v); + if (r != LDB_SUCCESS) { + const char *errstr = ldb_errstring(ldb); + /* canonicalisation can be refused. For + example, a attribute that takes wildcards + will refuse to canonicalise if the value + contains a wildcard */ + ldb_asprintf_errstring(ldb, + "Failed to create " + "index key for " + "attribute '%s':%s%s%s", + attr, ldb_strerror(r), + (errstr?":":""), + (errstr?errstr:"")); + talloc_free(attr_folded); + return NULL; + } + } + } + attr_len = strlen(attr_for_dn); + + /* + * Check if there is any hope this will fit into the DB. + * Overflow here is not actually critical the code below + * checks again to make the printf and the DB does another + * check for too long keys + */ + if (max_key_length - attr_len < min_key_length) { + ldb_asprintf_errstring( + ldb, + __location__ ": max_key_length " + "is too small (%u) < (%u)", + max_key_length, + (unsigned)(min_key_length + attr_len)); + talloc_free(attr_folded); + return NULL; + } + + /* + * ltdb_key_dn() makes something 4 bytes longer, it adds a leading + * "DN=" and a trailing string terminator + */ + max_key_length -= additional_key_length; + + /* + * We do not base 64 encode a DN in a key, it has already been + * casefold and lineraized, that is good enough. That already + * avoids embedded NUL etc. + */ + if (ldb_kv->cache->GUID_index_attribute != NULL) { + if (strcmp(attr, LDB_KV_IDXDN) == 0) { + should_b64_encode = false; + } else if (strcmp(attr, LDB_KV_IDXONE) == 0) { + /* + * We can only change the behaviour for IDXONE + * when the GUID index is enabled + */ + should_b64_encode = false; + } else { + should_b64_encode + = ldb_should_b64_encode(ldb, &v); + } + } else { + should_b64_encode = ldb_should_b64_encode(ldb, &v); + } + + if (should_b64_encode) { + size_t vstr_len = 0; + char *vstr = ldb_base64_encode(ldb, (char *)v.data, v.length); + if (!vstr) { + talloc_free(attr_folded); + return NULL; + } + vstr_len = strlen(vstr); + /* + * Overflow here is not critical as we only use this + * to choose the printf truncation + */ + key_len = num_separators + indx_len + attr_len + vstr_len; + if (key_len > max_key_length) { + size_t excess = key_len - max_key_length; + frmt_len = vstr_len - excess; + *truncation = KEY_TRUNCATED; + /* + * Truncated keys are placed in a separate key space + * from the non truncated keys + * Note: the double hash "##" is not a typo and + * indicates that the following value is base64 encoded + */ + ret = ldb_dn_new_fmt(ldb, ldb, "%s#%s##%.*s", + LDB_KV_INDEX, attr_for_dn, + frmt_len, vstr); + } else { + frmt_len = vstr_len; + *truncation = KEY_NOT_TRUNCATED; + /* + * Note: the double colon "::" is not a typo and + * indicates that the following value is base64 encoded + */ + ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s::%.*s", + LDB_KV_INDEX, attr_for_dn, + frmt_len, vstr); + } + talloc_free(vstr); + } else { + /* Only need two seperators */ + num_separators = 2; + + /* + * Overflow here is not critical as we only use this + * to choose the printf truncation + */ + key_len = num_separators + indx_len + attr_len + (int)v.length; + if (key_len > max_key_length) { + size_t excess = key_len - max_key_length; + frmt_len = v.length - excess; + *truncation = KEY_TRUNCATED; + /* + * Truncated keys are placed in a separate key space + * from the non truncated keys + */ + ret = ldb_dn_new_fmt(ldb, ldb, "%s#%s#%.*s", + LDB_KV_INDEX, attr_for_dn, + frmt_len, (char *)v.data); + } else { + frmt_len = v.length; + *truncation = KEY_NOT_TRUNCATED; + ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s:%.*s", + LDB_KV_INDEX, attr_for_dn, + frmt_len, (char *)v.data); + } + } + + if (v.data != value->data && !empty_val) { + talloc_free(v.data); + } + talloc_free(attr_folded); + + return ret; +} + +/* + see if a attribute value is in the list of indexed attributes +*/ +static bool ldb_kv_is_indexed(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const char *attr) +{ + struct ldb_context *ldb = ldb_module_get_ctx(module); + unsigned int i; + struct ldb_message_element *el; + + if ((ldb_kv->cache->GUID_index_attribute != NULL) && + (ldb_attr_cmp(attr, ldb_kv->cache->GUID_index_attribute) == 0)) { + /* Implicity covered, this is the index key */ + return false; + } + if (ldb->schema.index_handler_override) { + const struct ldb_schema_attribute *a + = ldb_schema_attribute_by_name(ldb, attr); + + if (a == NULL) { + return false; + } + + if (a->flags & LDB_ATTR_FLAG_INDEXED) { + return true; + } else { + return false; + } + } + + if (!ldb_kv->cache->attribute_indexes) { + return false; + } + + el = ldb_msg_find_element(ldb_kv->cache->indexlist, LDB_KV_IDXATTR); + if (el == NULL) { + return false; + } + + /* TODO: this is too expensive! At least use a binary search */ + for (i=0; inum_values; i++) { + if (ldb_attr_cmp((char *)el->values[i].data, attr) == 0) { + return true; + } + } + return false; +} + +/* + in the following logic functions, the return value is treated as + follows: + + LDB_SUCCESS: we found some matching index values + + LDB_ERR_NO_SUCH_OBJECT: we know for sure that no object matches + + LDB_ERR_OPERATIONS_ERROR: indexing could not answer the call, + we'll need a full search + */ + +/* + return a list of dn's that might match a simple indexed search (an + equality search only) + */ +static int ldb_kv_index_dn_simple(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_parse_tree *tree, + struct dn_list *list) +{ + struct ldb_context *ldb; + struct ldb_dn *dn; + int ret; + enum key_truncation truncation = KEY_NOT_TRUNCATED; + + ldb = ldb_module_get_ctx(module); + + list->count = 0; + list->dn = NULL; + + /* if the attribute isn't in the list of indexed attributes then + this node needs a full search */ + if (!ldb_kv_is_indexed(module, ldb_kv, tree->u.equality.attr)) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* the attribute is indexed. Pull the list of DNs that match the + search criterion */ + dn = ldb_kv_index_key(ldb, + ldb_kv, + tree->u.equality.attr, + &tree->u.equality.value, + NULL, + &truncation); + /* + * We ignore truncation here and allow multi-valued matches + * as ltdb_search_indexed will filter out the wrong one in + * ltdb_index_filter() which calls ldb_match_message(). + */ + if (!dn) return LDB_ERR_OPERATIONS_ERROR; + + ret = ldb_kv_dn_list_load(module, ldb_kv, dn, list, + DN_LIST_WILL_BE_READ_ONLY); + talloc_free(dn); + return ret; +} + +static bool list_union(struct ldb_context *ldb, + struct ldb_kv_private *ldb_kv, + struct dn_list *list, + struct dn_list *list2); + +/* + return a list of dn's that might match a leaf indexed search + */ +static int ldb_kv_index_dn_leaf(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_parse_tree *tree, + struct dn_list *list) +{ + if (ldb_kv->disallow_dn_filter && + (ldb_attr_cmp(tree->u.equality.attr, "dn") == 0)) { + /* in AD mode we do not support "(dn=...)" search filters */ + list->dn = NULL; + list->count = 0; + return LDB_SUCCESS; + } + if (tree->u.equality.attr[0] == '@') { + /* Do not allow a indexed search against an @ */ + list->dn = NULL; + list->count = 0; + return LDB_SUCCESS; + } + if (ldb_attr_dn(tree->u.equality.attr) == 0) { + enum key_truncation truncation = KEY_NOT_TRUNCATED; + bool valid_dn = false; + struct ldb_dn *dn + = ldb_dn_from_ldb_val(list, + ldb_module_get_ctx(module), + &tree->u.equality.value); + if (dn == NULL) { + /* If we can't parse it, no match */ + list->dn = NULL; + list->count = 0; + return LDB_SUCCESS; + } + + valid_dn = ldb_dn_validate(dn); + if (valid_dn == false) { + /* If we can't parse it, no match */ + list->dn = NULL; + list->count = 0; + return LDB_SUCCESS; + } + + /* + * Re-use the same code we use for a SCOPE_BASE + * search + * + * We can't call TALLOC_FREE(dn) as this must belong + * to list for the memory to remain valid. + */ + return ldb_kv_index_dn_base_dn( + module, ldb_kv, dn, list, &truncation); + /* + * We ignore truncation here and allow multi-valued matches + * as ltdb_search_indexed will filter out the wrong one in + * ltdb_index_filter() which calls ldb_match_message(). + */ + + } else if ((ldb_kv->cache->GUID_index_attribute != NULL) && + (ldb_attr_cmp(tree->u.equality.attr, + ldb_kv->cache->GUID_index_attribute) == 0)) { + int ret; + struct ldb_context *ldb = ldb_module_get_ctx(module); + list->dn = talloc_array(list, struct ldb_val, 1); + if (list->dn == NULL) { + ldb_module_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + /* + * We need to go via the canonicalise_fn() to + * ensure we get the index in binary, rather + * than a string + */ + ret = ldb_kv->GUID_index_syntax->canonicalise_fn( + ldb, list->dn, &tree->u.equality.value, &list->dn[0]); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + list->count = 1; + return LDB_SUCCESS; + } + + return ldb_kv_index_dn_simple(module, ldb_kv, tree, list); +} + + +/* + list intersection + list = list & list2 +*/ +static bool list_intersect(struct ldb_kv_private *ldb_kv, + struct dn_list *list, + const struct dn_list *list2) +{ + const struct dn_list *short_list, *long_list; + struct dn_list *list3; + unsigned int i; + + if (list->count == 0) { + /* 0 & X == 0 */ + return true; + } + if (list2->count == 0) { + /* X & 0 == 0 */ + list->count = 0; + list->dn = NULL; + return true; + } + + /* + * In both of the below we check for strict and in that + * case do not optimise the intersection of this list, + * we must never return an entry not in this + * list. This allows the index for + * SCOPE_ONELEVEL to be trusted. + */ + + /* the indexing code is allowed to return a longer list than + what really matches, as all results are filtered by the + full expression at the end - this shortcut avoids a lot of + work in some cases */ + if (list->count < 2 && list2->count > 10 && list2->strict == false) { + return true; + } + if (list2->count < 2 && list->count > 10 && list->strict == false) { + list->count = list2->count; + list->dn = list2->dn; + /* note that list2 may not be the parent of list2->dn, + as list2->dn may be owned by ltdb->idxptr. In that + case we expect this reparent call to fail, which is + OK */ + talloc_reparent(list2, list, list2->dn); + return true; + } + + if (list->count > list2->count) { + short_list = list2; + long_list = list; + } else { + short_list = list; + long_list = list2; + } + + list3 = talloc_zero(list, struct dn_list); + if (list3 == NULL) { + return false; + } + + list3->dn = talloc_array(list3, struct ldb_val, + MIN(list->count, list2->count)); + if (!list3->dn) { + talloc_free(list3); + return false; + } + list3->count = 0; + + for (i=0;icount;i++) { + /* For the GUID index case, this is a binary search */ + if (ldb_kv_dn_list_find_val( + ldb_kv, long_list, &short_list->dn[i]) != -1) { + list3->dn[list3->count] = short_list->dn[i]; + list3->count++; + } + } + + list->strict |= list2->strict; + list->dn = talloc_steal(list, list3->dn); + list->count = list3->count; + talloc_free(list3); + + return true; +} + + +/* + list union + list = list | list2 +*/ +static bool list_union(struct ldb_context *ldb, + struct ldb_kv_private *ldb_kv, + struct dn_list *list, + struct dn_list *list2) +{ + struct ldb_val *dn3; + unsigned int i = 0, j = 0, k = 0; + + if (list2->count == 0) { + /* X | 0 == X */ + return true; + } + + if (list->count == 0) { + /* 0 | X == X */ + list->count = list2->count; + list->dn = list2->dn; + /* note that list2 may not be the parent of list2->dn, + as list2->dn may be owned by ltdb->idxptr. In that + case we expect this reparent call to fail, which is + OK */ + talloc_reparent(list2, list, list2->dn); + return true; + } + + /* + * Sort the lists (if not in GUID DN mode) so we can do + * the de-duplication during the merge + * + * NOTE: This can sort the in-memory index values, as list or + * list2 might not be a copy! + */ + ldb_kv_dn_list_sort(ldb_kv, list); + ldb_kv_dn_list_sort(ldb_kv, list2); + + dn3 = talloc_array(list, struct ldb_val, list->count + list2->count); + if (!dn3) { + ldb_oom(ldb); + return false; + } + + while (i < list->count || j < list2->count) { + int cmp; + if (i >= list->count) { + cmp = 1; + } else if (j >= list2->count) { + cmp = -1; + } else { + cmp = ldb_val_equal_exact_ordered(list->dn[i], + &list2->dn[j]); + } + + if (cmp < 0) { + /* Take list */ + dn3[k] = list->dn[i]; + i++; + k++; + } else if (cmp > 0) { + /* Take list2 */ + dn3[k] = list2->dn[j]; + j++; + k++; + } else { + /* Equal, take list */ + dn3[k] = list->dn[i]; + i++; + j++; + k++; + } + } + + list->dn = dn3; + list->count = k; + + return true; +} + +static int ldb_kv_index_dn(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_parse_tree *tree, + struct dn_list *list); + +/* + process an OR list (a union) + */ +static int ldb_kv_index_dn_or(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_parse_tree *tree, + struct dn_list *list) +{ + struct ldb_context *ldb; + unsigned int i; + + ldb = ldb_module_get_ctx(module); + + list->dn = NULL; + list->count = 0; + + for (i=0; iu.list.num_elements; i++) { + struct dn_list *list2; + int ret; + + list2 = talloc_zero(list, struct dn_list); + if (list2 == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_kv_index_dn( + module, ldb_kv, tree->u.list.elements[i], list2); + + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + /* X || 0 == X */ + talloc_free(list2); + continue; + } + + if (ret != LDB_SUCCESS) { + /* X || * == * */ + talloc_free(list2); + return ret; + } + + if (!list_union(ldb, ldb_kv, list, list2)) { + talloc_free(list2); + return LDB_ERR_OPERATIONS_ERROR; + } + } + + if (list->count == 0) { + return LDB_ERR_NO_SUCH_OBJECT; + } + + return LDB_SUCCESS; +} + + +/* + NOT an index results + */ +static int ldb_kv_index_dn_not(_UNUSED_ struct ldb_module *module, + _UNUSED_ struct ldb_kv_private *ldb_kv, + _UNUSED_ const struct ldb_parse_tree *tree, + _UNUSED_ struct dn_list *list) +{ + /* the only way to do an indexed not would be if we could + negate the not via another not or if we knew the total + number of database elements so we could know that the + existing expression covered the whole database. + + instead, we just give up, and rely on a full index scan + (unless an outer & manages to reduce the list) + */ + return LDB_ERR_OPERATIONS_ERROR; +} + +/* + * These things are unique, so avoid a full scan if this is a search + * by GUID, DN or a unique attribute + */ +static bool ldb_kv_index_unique(struct ldb_context *ldb, + struct ldb_kv_private *ldb_kv, + const char *attr) +{ + const struct ldb_schema_attribute *a; + if (ldb_kv->cache->GUID_index_attribute != NULL) { + if (ldb_attr_cmp(attr, ldb_kv->cache->GUID_index_attribute) == + 0) { + return true; + } + } + if (ldb_attr_dn(attr) == 0) { + return true; + } + + a = ldb_schema_attribute_by_name(ldb, attr); + if (a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX) { + return true; + } + return false; +} + +/* + process an AND expression (intersection) + */ +static int ldb_kv_index_dn_and(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_parse_tree *tree, + struct dn_list *list) +{ + struct ldb_context *ldb; + unsigned int i; + bool found; + + ldb = ldb_module_get_ctx(module); + + list->dn = NULL; + list->count = 0; + + /* in the first pass we only look for unique simple + equality tests, in the hope of avoiding having to look + at any others */ + for (i=0; iu.list.num_elements; i++) { + const struct ldb_parse_tree *subtree = tree->u.list.elements[i]; + int ret; + + if (subtree->operation != LDB_OP_EQUALITY || + !ldb_kv_index_unique( + ldb, ldb_kv, subtree->u.equality.attr)) { + continue; + } + + ret = ldb_kv_index_dn(module, ldb_kv, subtree, list); + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + /* 0 && X == 0 */ + return LDB_ERR_NO_SUCH_OBJECT; + } + if (ret == LDB_SUCCESS) { + /* a unique index match means we can + * stop. Note that we don't care if we return + * a few too many objects, due to later + * filtering */ + return LDB_SUCCESS; + } + } + + /* now do a full intersection */ + found = false; + + for (i=0; iu.list.num_elements; i++) { + const struct ldb_parse_tree *subtree = tree->u.list.elements[i]; + struct dn_list *list2; + int ret; + + list2 = talloc_zero(list, struct dn_list); + if (list2 == NULL) { + return ldb_module_oom(module); + } + + ret = ldb_kv_index_dn(module, ldb_kv, subtree, list2); + + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + /* X && 0 == 0 */ + list->dn = NULL; + list->count = 0; + talloc_free(list2); + return LDB_ERR_NO_SUCH_OBJECT; + } + + if (ret != LDB_SUCCESS) { + /* this didn't adding anything */ + talloc_free(list2); + continue; + } + + if (!found) { + talloc_reparent(list2, list, list->dn); + list->dn = list2->dn; + list->count = list2->count; + found = true; + } else if (!list_intersect(ldb_kv, list, list2)) { + talloc_free(list2); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (list->count == 0) { + list->dn = NULL; + return LDB_ERR_NO_SUCH_OBJECT; + } + + if (list->count < 2) { + /* it isn't worth loading the next part of the tree */ + return LDB_SUCCESS; + } + } + + if (!found) { + /* none of the attributes were indexed */ + return LDB_ERR_OPERATIONS_ERROR; + } + + return LDB_SUCCESS; +} + +struct ldb_kv_ordered_index_context { + struct ldb_module *module; + int error; + struct dn_list *dn_list; +}; + +static int traverse_range_index(_UNUSED_ struct ldb_kv_private *ldb_kv, + _UNUSED_ struct ldb_val key, + struct ldb_val data, + void *state) +{ + + struct ldb_context *ldb; + struct ldb_kv_ordered_index_context *ctx = + (struct ldb_kv_ordered_index_context *)state; + struct ldb_module *module = ctx->module; + struct ldb_message_element *el = NULL; + struct ldb_message *msg = NULL; + int version; + size_t dn_array_size, additional_length; + unsigned int i; + + ldb = ldb_module_get_ctx(module); + + msg = ldb_msg_new(module); + + ctx->error = ldb_unpack_data_flags(ldb, &data, msg, + LDB_UNPACK_DATA_FLAG_NO_DN); + + if (ctx->error != LDB_SUCCESS) { + talloc_free(msg); + return ctx->error; + } + + el = ldb_msg_find_element(msg, LDB_KV_IDX); + if (!el) { + talloc_free(msg); + return LDB_SUCCESS; + } + + version = ldb_msg_find_attr_as_int(msg, LDB_KV_IDXVERSION, 0); + + /* + * we avoid copying the strings by stealing the list. We have + * to steal msg onto el->values (which looks odd) because + * the memory is allocated on msg, not on each value. + */ + if (version != LDB_KV_GUID_INDEXING_VERSION) { + /* This is quite likely during the DB startup + on first upgrade to using a GUID index */ + ldb_debug_set(ldb_module_get_ctx(module), + LDB_DEBUG_ERROR, __location__ + ": Wrong GUID index version %d expected %d", + version, LDB_KV_GUID_INDEXING_VERSION); + talloc_free(msg); + ctx->error = LDB_ERR_OPERATIONS_ERROR; + return ctx->error; + } + + if (el->num_values == 0) { + talloc_free(msg); + ctx->error = LDB_ERR_OPERATIONS_ERROR; + return ctx->error; + } + + if ((el->values[0].length % LDB_KV_GUID_SIZE) != 0 + || el->values[0].length == 0) { + talloc_free(msg); + ctx->error = LDB_ERR_OPERATIONS_ERROR; + return ctx->error; + } + + dn_array_size = talloc_array_length(ctx->dn_list->dn); + + additional_length = el->values[0].length / LDB_KV_GUID_SIZE; + + if (ctx->dn_list->count + additional_length < ctx->dn_list->count) { + talloc_free(msg); + ctx->error = LDB_ERR_OPERATIONS_ERROR; + return ctx->error; + } + + if ((ctx->dn_list->count + additional_length) >= dn_array_size) { + size_t new_array_length; + + if (dn_array_size * 2 < dn_array_size) { + talloc_free(msg); + ctx->error = LDB_ERR_OPERATIONS_ERROR; + return ctx->error; + } + + new_array_length = MAX(ctx->dn_list->count + additional_length, + dn_array_size * 2); + + ctx->dn_list->dn = talloc_realloc(ctx->dn_list, + ctx->dn_list->dn, + struct ldb_val, + new_array_length); + } + + if (ctx->dn_list->dn == NULL) { + talloc_free(msg); + ctx->error = LDB_ERR_OPERATIONS_ERROR; + return ctx->error; + } + + /* + * The actual data is on msg. + */ + talloc_steal(ctx->dn_list->dn, msg); + for (i = 0; i < additional_length; i++) { + ctx->dn_list->dn[i + ctx->dn_list->count].data + = &el->values[0].data[i * LDB_KV_GUID_SIZE]; + ctx->dn_list->dn[i + ctx->dn_list->count].length = LDB_KV_GUID_SIZE; + + } + + ctx->dn_list->count += additional_length; + + talloc_free(msg->elements); + + return LDB_SUCCESS; +} + +/* + * >= and <= indexing implemented using lexicographically sorted keys + * + * We only run this in GUID indexing mode and when there is no write + * transaction (only implicit read locks are being held). Otherwise, we would + * have to deal with the in-memory index cache. + * + * We rely on the implementation of index_format_fn on a schema syntax which + * will can help us to construct keys which can be ordered correctly, and we + * terminate using schema agnostic start and end keys. + * + * index_format_fn must output values which can be memcmp-able to produce the + * correct ordering as defined by the schema syntax class. + */ +static int ldb_kv_index_dn_ordered(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_parse_tree *tree, + struct dn_list *list, bool ascending) +{ + enum key_truncation truncation = KEY_NOT_TRUNCATED; + struct ldb_context *ldb = ldb_module_get_ctx(module); + + struct ldb_val ldb_key = { 0 }, ldb_key2 = { 0 }; + struct ldb_val start_key, end_key; + struct ldb_dn *key_dn = NULL; + const struct ldb_schema_attribute *a = NULL; + + struct ldb_kv_ordered_index_context ctx; + int ret; + + TALLOC_CTX *tmp_ctx = talloc_new(NULL); + + if (!ldb_kv_is_indexed(module, ldb_kv, tree->u.comparison.attr)) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (ldb_kv->cache->GUID_index_attribute == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* bail out if we're in a transaction, full search instead. */ + if (ldb_kv->kv_ops->transaction_active(ldb_kv)) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (ldb_kv->disallow_dn_filter && + (ldb_attr_cmp(tree->u.comparison.attr, "dn") == 0)) { + /* in AD mode we do not support "(dn=...)" search filters */ + list->dn = NULL; + list->count = 0; + return LDB_SUCCESS; + } + if (tree->u.comparison.attr[0] == '@') { + /* Do not allow a indexed search against an @ */ + list->dn = NULL; + list->count = 0; + return LDB_SUCCESS; + } + + a = ldb_schema_attribute_by_name(ldb, tree->u.comparison.attr); + + /* + * If there's no index format function defined for this attr, then + * the lexicographic order in the database doesn't correspond to the + * attr's ordering, so we can't use the iterate_range op. + */ + if (a->syntax->index_format_fn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + key_dn = ldb_kv_index_key(ldb, ldb_kv, tree->u.comparison.attr, + &tree->u.comparison.value, + NULL, &truncation); + if (!key_dn) { + return LDB_ERR_OPERATIONS_ERROR; + } else if (truncation == KEY_TRUNCATED) { + ldb_debug(ldb, LDB_DEBUG_WARNING, + __location__ + ": ordered index violation: key dn truncated: %s\n", + ldb_dn_get_linearized(key_dn)); + return LDB_ERR_OPERATIONS_ERROR; + } + ldb_key = ldb_kv_key_dn(tmp_ctx, key_dn); + talloc_free(key_dn); + if (ldb_key.data == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + key_dn = ldb_kv_index_key(ldb, ldb_kv, tree->u.comparison.attr, + NULL, NULL, &truncation); + if (!key_dn) { + return LDB_ERR_OPERATIONS_ERROR; + } else if (truncation == KEY_TRUNCATED) { + ldb_debug(ldb, LDB_DEBUG_WARNING, + __location__ + ": ordered index violation: key dn truncated: %s\n", + ldb_dn_get_linearized(key_dn)); + return LDB_ERR_OPERATIONS_ERROR; + } + + ldb_key2 = ldb_kv_key_dn(tmp_ctx, key_dn); + talloc_free(key_dn); + if (ldb_key2.data == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* + * In order to avoid defining a start and end key for the search, we + * notice that each index key is of the form: + * + * DN=@INDEX::\0. + * + * We can simply make our start key DN=@INDEX:: and our end + * key DN=@INDEX:; to return all index entries for a + * particular attribute. + * + * Our LMDB backend uses the default memcmp for key comparison. + */ + + /* Eliminate NUL byte at the end of the empty key */ + ldb_key2.length--; + + if (ascending) { + /* : becomes ; for pseudo end-key */ + ldb_key2.data[ldb_key2.length-1]++; + start_key = ldb_key; + end_key = ldb_key2; + } else { + start_key = ldb_key2; + end_key = ldb_key; + } + + ctx.module = module; + ctx.error = 0; + ctx.dn_list = list; + ctx.dn_list->count = 0; + ctx.dn_list->dn = talloc_zero_array(ctx.dn_list, struct ldb_val, 2); + + ret = ldb_kv->kv_ops->iterate_range(ldb_kv, start_key, end_key, + traverse_range_index, &ctx); + + if (ret != LDB_SUCCESS || ctx.error != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + TYPESAFE_QSORT(ctx.dn_list->dn, ctx.dn_list->count, + ldb_val_equal_exact_for_qsort); + + talloc_free(tmp_ctx); + + return LDB_SUCCESS; +} + +static int ldb_kv_index_dn_greater(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_parse_tree *tree, + struct dn_list *list) +{ + return ldb_kv_index_dn_ordered(module, + ldb_kv, + tree, + list, true); +} + +static int ldb_kv_index_dn_less(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_parse_tree *tree, + struct dn_list *list) +{ + return ldb_kv_index_dn_ordered(module, + ldb_kv, + tree, + list, false); +} + +/* + return a list of matching objects using a one-level index + */ +static int ldb_kv_index_dn_attr(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const char *attr, + struct ldb_dn *dn, + struct dn_list *list, + enum key_truncation *truncation) +{ + struct ldb_context *ldb; + struct ldb_dn *key; + struct ldb_val val; + int ret; + + ldb = ldb_module_get_ctx(module); + + /* work out the index key from the parent DN */ + val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(dn)); + if (val.data == NULL) { + const char *dn_str = ldb_dn_get_linearized(dn); + ldb_asprintf_errstring(ldb_module_get_ctx(module), + __location__ + ": Failed to get casefold DN " + "from: %s", + dn_str); + return LDB_ERR_OPERATIONS_ERROR; + } + val.length = strlen((char *)val.data); + key = ldb_kv_index_key(ldb, ldb_kv, attr, &val, NULL, truncation); + if (!key) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_kv_dn_list_load(module, ldb_kv, key, list, + DN_LIST_WILL_BE_READ_ONLY); + talloc_free(key); + if (ret != LDB_SUCCESS) { + return ret; + } + + if (list->count == 0) { + return LDB_ERR_NO_SUCH_OBJECT; + } + + return LDB_SUCCESS; +} + +/* + return a list of matching objects using a one-level index + */ +static int ldb_kv_index_dn_one(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + struct ldb_dn *parent_dn, + struct dn_list *list, + enum key_truncation *truncation) +{ + /* + * Ensure we do not shortcut on intersection for this list. + * We must never be lazy and return an entry not in this + * list. This allows the index for + * SCOPE_ONELEVEL to be trusted. + */ + + list->strict = true; + return ldb_kv_index_dn_attr( + module, ldb_kv, LDB_KV_IDXONE, parent_dn, list, truncation); +} + +/* + return a list of matching objects using the DN index + */ +static int ldb_kv_index_dn_base_dn(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + struct ldb_dn *base_dn, + struct dn_list *dn_list, + enum key_truncation *truncation) +{ + const struct ldb_val *guid_val = NULL; + if (ldb_kv->cache->GUID_index_attribute == NULL) { + dn_list->dn = talloc_array(dn_list, struct ldb_val, 1); + if (dn_list->dn == NULL) { + return ldb_module_oom(module); + } + dn_list->dn[0].data = discard_const_p(unsigned char, + ldb_dn_get_linearized(base_dn)); + if (dn_list->dn[0].data == NULL) { + talloc_free(dn_list->dn); + return ldb_module_oom(module); + } + dn_list->dn[0].length = strlen((char *)dn_list->dn[0].data); + dn_list->count = 1; + + return LDB_SUCCESS; + } + + if (ldb_kv->cache->GUID_index_dn_component != NULL) { + guid_val = ldb_dn_get_extended_component( + base_dn, ldb_kv->cache->GUID_index_dn_component); + } + + if (guid_val != NULL) { + dn_list->dn = talloc_array(dn_list, struct ldb_val, 1); + if (dn_list->dn == NULL) { + return ldb_module_oom(module); + } + dn_list->dn[0].data = guid_val->data; + dn_list->dn[0].length = guid_val->length; + dn_list->count = 1; + + return LDB_SUCCESS; + } + + return ldb_kv_index_dn_attr( + module, ldb_kv, LDB_KV_IDXDN, base_dn, dn_list, truncation); +} + +/* + return a list of dn's that might match a indexed search or + an error. return LDB_ERR_NO_SUCH_OBJECT for no matches, or LDB_SUCCESS for matches + */ +static int ldb_kv_index_dn(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_parse_tree *tree, + struct dn_list *list) +{ + int ret = LDB_ERR_OPERATIONS_ERROR; + + switch (tree->operation) { + case LDB_OP_AND: + ret = ldb_kv_index_dn_and(module, ldb_kv, tree, list); + break; + + case LDB_OP_OR: + ret = ldb_kv_index_dn_or(module, ldb_kv, tree, list); + break; + + case LDB_OP_NOT: + ret = ldb_kv_index_dn_not(module, ldb_kv, tree, list); + break; + + case LDB_OP_EQUALITY: + ret = ldb_kv_index_dn_leaf(module, ldb_kv, tree, list); + break; + + case LDB_OP_GREATER: + ret = ldb_kv_index_dn_greater(module, ldb_kv, tree, list); + break; + + case LDB_OP_LESS: + ret = ldb_kv_index_dn_less(module, ldb_kv, tree, list); + break; + + case LDB_OP_SUBSTRING: + case LDB_OP_PRESENT: + case LDB_OP_APPROX: + case LDB_OP_EXTENDED: + /* we can't index with fancy bitops yet */ + ret = LDB_ERR_OPERATIONS_ERROR; + break; + } + + return ret; +} + +/* + filter a candidate dn_list from an indexed search into a set of results + extracting just the given attributes +*/ +static int ldb_kv_index_filter(struct ldb_kv_private *ldb_kv, + const struct dn_list *dn_list, + struct ldb_kv_context *ac, + uint32_t *match_count, + enum key_truncation scope_one_truncation) +{ + struct ldb_context *ldb = ldb_module_get_ctx(ac->module); + struct ldb_message *msg; + struct ldb_message *filtered_msg; + unsigned int i; + unsigned int num_keys = 0; + uint8_t previous_guid_key[LDB_KV_GUID_KEY_SIZE] = {}; + struct ldb_val *keys = NULL; + + /* + * We have to allocate the key list (rather than just walk the + * caller supplied list) as the callback could change the list + * (by modifying an indexed attribute hosted in the in-memory + * index cache!) + */ + keys = talloc_array(ac, struct ldb_val, dn_list->count); + if (keys == NULL) { + return ldb_module_oom(ac->module); + } + + if (ldb_kv->cache->GUID_index_attribute != NULL) { + /* + * We speculate that the keys will be GUID based and so + * pre-fill in enough space for a GUID (avoiding a pile of + * small allocations) + */ + struct guid_tdb_key { + uint8_t guid_key[LDB_KV_GUID_KEY_SIZE]; + } *key_values = NULL; + + key_values = talloc_array(keys, + struct guid_tdb_key, + dn_list->count); + + if (key_values == NULL) { + talloc_free(keys); + return ldb_module_oom(ac->module); + } + for (i = 0; i < dn_list->count; i++) { + keys[i].data = key_values[i].guid_key; + keys[i].length = sizeof(key_values[i].guid_key); + } + } else { + for (i = 0; i < dn_list->count; i++) { + keys[i].data = NULL; + keys[i].length = 0; + } + } + + for (i = 0; i < dn_list->count; i++) { + int ret; + + ret = ldb_kv_idx_to_key( + ac->module, ldb_kv, keys, &dn_list->dn[i], &keys[num_keys]); + if (ret != LDB_SUCCESS) { + talloc_free(keys); + return ret; + } + + if (ldb_kv->cache->GUID_index_attribute != NULL) { + /* + * If we are in GUID index mode, then the dn_list is + * sorted. If we got a duplicate, forget about it, as + * otherwise we would send the same entry back more + * than once. + * + * This is needed in the truncated DN case, or if a + * duplicate was forced in via + * LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK + */ + + if (memcmp(previous_guid_key, + keys[num_keys].data, + sizeof(previous_guid_key)) == 0) { + continue; + } + + memcpy(previous_guid_key, + keys[num_keys].data, + sizeof(previous_guid_key)); + } + num_keys++; + } + + + /* + * Now that the list is a safe copy, send the callbacks + */ + for (i = 0; i < num_keys; i++) { + int ret; + bool matched; + msg = ldb_msg_new(ac); + if (!msg) { + talloc_free(keys); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = + ldb_kv_search_key(ac->module, + ldb_kv, + keys[i], + msg, + LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC | + /* + * The entry point ldb_kv_search_indexed is + * only called from the read-locked + * ldb_kv_search. + */ + LDB_UNPACK_DATA_FLAG_READ_LOCKED); + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + /* + * the record has disappeared? yes, this can + * happen if the entry is deleted by something + * operating in the callback (not another + * process, as we have a read lock) + */ + talloc_free(msg); + continue; + } + + if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) { + /* an internal error */ + talloc_free(keys); + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* + * We trust the index for LDB_SCOPE_ONELEVEL + * unless the index key has been truncated. + * + * LDB_SCOPE_BASE is not passed in by our only caller. + */ + if (ac->scope == LDB_SCOPE_ONELEVEL && + ldb_kv->cache->one_level_indexes && + scope_one_truncation == KEY_NOT_TRUNCATED) { + ret = ldb_match_message(ldb, msg, ac->tree, + ac->scope, &matched); + } else { + ret = ldb_match_msg_error(ldb, msg, + ac->tree, ac->base, + ac->scope, &matched); + } + + if (ret != LDB_SUCCESS) { + talloc_free(keys); + talloc_free(msg); + return ret; + } + if (!matched) { + talloc_free(msg); + continue; + } + + filtered_msg = ldb_msg_new(ac); + if (filtered_msg == NULL) { + TALLOC_FREE(keys); + TALLOC_FREE(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + filtered_msg->dn = talloc_steal(filtered_msg, msg->dn); + + /* filter the attributes that the user wants */ + ret = ldb_kv_filter_attrs(ldb, msg, ac->attrs, filtered_msg); + + talloc_free(msg); + + if (ret == -1) { + TALLOC_FREE(filtered_msg); + talloc_free(keys); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_module_send_entry(ac->req, filtered_msg, NULL); + if (ret != LDB_SUCCESS) { + /* Regardless of success or failure, the msg + * is the callbacks responsiblity, and should + * not be talloc_free()'ed */ + ac->request_terminated = true; + talloc_free(keys); + return ret; + } + + (*match_count)++; + } + + TALLOC_FREE(keys); + return LDB_SUCCESS; +} + +/* + sort a DN list + */ +static void ldb_kv_dn_list_sort(struct ldb_kv_private *ltdb, + struct dn_list *list) +{ + if (list->count < 2) { + return; + } + + /* We know the list is sorted when using the GUID index */ + if (ltdb->cache->GUID_index_attribute != NULL) { + return; + } + + TYPESAFE_QSORT(list->dn, list->count, + ldb_val_equal_exact_for_qsort); +} + +/* + search the database with a LDAP-like expression using indexes + returns -1 if an indexed search is not possible, in which + case the caller should call ltdb_search_full() +*/ +int ldb_kv_search_indexed(struct ldb_kv_context *ac, uint32_t *match_count) +{ + struct ldb_context *ldb = ldb_module_get_ctx(ac->module); + struct ldb_kv_private *ldb_kv = talloc_get_type( + ldb_module_get_private(ac->module), struct ldb_kv_private); + struct dn_list *dn_list; + int ret; + enum ldb_scope index_scope; + enum key_truncation scope_one_truncation = KEY_NOT_TRUNCATED; + + /* see if indexing is enabled */ + if (!ldb_kv->cache->attribute_indexes && + !ldb_kv->cache->one_level_indexes && ac->scope != LDB_SCOPE_BASE) { + /* fallback to a full search */ + return LDB_ERR_OPERATIONS_ERROR; + } + + dn_list = talloc_zero(ac, struct dn_list); + if (dn_list == NULL) { + return ldb_module_oom(ac->module); + } + + /* + * For the purposes of selecting the switch arm below, if we + * don't have a one-level index then treat it like a subtree + * search + */ + if (ac->scope == LDB_SCOPE_ONELEVEL && + !ldb_kv->cache->one_level_indexes) { + index_scope = LDB_SCOPE_SUBTREE; + } else { + index_scope = ac->scope; + } + + switch (index_scope) { + case LDB_SCOPE_BASE: + /* + * The only caller will have filtered the operation out + * so we should never get here + */ + return ldb_operr(ldb); + + case LDB_SCOPE_ONELEVEL: + + /* + * First, load all the one-level child objects (regardless of + * whether they match the search filter or not). The database + * maintains a one-level index, so retrieving this is quick. + */ + ret = ldb_kv_index_dn_one(ac->module, + ldb_kv, + ac->base, + dn_list, + &scope_one_truncation); + if (ret != LDB_SUCCESS) { + talloc_free(dn_list); + return ret; + } + + /* + * If we have too many children, running ldb_kv_index_filter() + * over all the child objects can be quite expensive. So next + * we do a separate indexed query using the search filter. + * + * This should be quick, but it may return objects that are not + * the direct one-level child objects we're interested in. + * + * We only do this in the GUID index mode, which is + * O(n*log(m)) otherwise the intersection below will + * be too costly at O(n*m). + * + * We don't set a heuristic for 'too many' but instead + * do it always and rely on the index lookup being + * fast enough in the small case. + */ + if (ldb_kv->cache->GUID_index_attribute != NULL) { + struct dn_list *indexed_search_result + = talloc_zero(ac, struct dn_list); + if (indexed_search_result == NULL) { + talloc_free(dn_list); + return ldb_module_oom(ac->module); + } + + if (!ldb_kv->cache->attribute_indexes) { + talloc_free(indexed_search_result); + talloc_free(dn_list); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* + * Try to do an indexed database search + */ + ret = ldb_kv_index_dn( + ac->module, ldb_kv, ac->tree, + indexed_search_result); + + /* + * We can stop if we're sure the object doesn't exist + */ + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + talloc_free(indexed_search_result); + talloc_free(dn_list); + return LDB_ERR_NO_SUCH_OBJECT; + } + + /* + * Once we have a successful search result, we + * intersect it with the one-level children (dn_list). + * This should give us exactly the result we're after + * (we still need to run ldb_kv_index_filter() to + * handle potential index truncation cases). + * + * The indexed search may fail because we don't support + * indexing on that type of search operation, e.g. + * matching against '*'. In which case we fall through + * and run ldb_kv_index_filter() over all the one-level + * children (which is still better than bailing out here + * and falling back to a full DB scan). + */ + if (ret == LDB_SUCCESS) { + if (!list_intersect(ldb_kv, + dn_list, + indexed_search_result)) { + talloc_free(indexed_search_result); + talloc_free(dn_list); + return LDB_ERR_OPERATIONS_ERROR; + } + } + } + break; + + case LDB_SCOPE_SUBTREE: + case LDB_SCOPE_DEFAULT: + if (!ldb_kv->cache->attribute_indexes) { + talloc_free(dn_list); + return LDB_ERR_OPERATIONS_ERROR; + } + /* + * Here we load the index for the tree. We have no + * index for the subtree. + */ + ret = ldb_kv_index_dn(ac->module, ldb_kv, ac->tree, dn_list); + if (ret != LDB_SUCCESS) { + talloc_free(dn_list); + return ret; + } + break; + } + + /* + * It is critical that this function do the re-filter even + * on things found by the index as the index can over-match + * in cases of truncation (as well as when it decides it is + * not worth further filtering) + * + * If this changes, then the index code above would need to + * pass up a flag to say if any index was truncated during + * processing as the truncation here refers only to the + * SCOPE_ONELEVEL index. + */ + ret = ldb_kv_index_filter( + ldb_kv, dn_list, ac, match_count, scope_one_truncation); + talloc_free(dn_list); + return ret; +} + +/** + * @brief Add a DN in the index list of a given attribute name/value pair + * + * This function will add the DN in the index list for the index for + * the given attribute name and value. + * + * @param[in] module A ldb_module structure + * + * @param[in] dn The string representation of the DN as it + * will be stored in the index entry + * + * @param[in] el A ldb_message_element array, one of the entry + * referred by the v_idx is the attribute name and + * value pair which will be used to construct the + * index name + * + * @param[in] v_idx The index of element in the el array to use + * + * @return An ldb error code + */ +static int ldb_kv_index_add1(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_message *msg, + struct ldb_message_element *el, + int v_idx) +{ + struct ldb_context *ldb; + struct ldb_dn *dn_key; + int ret; + const struct ldb_schema_attribute *a; + struct dn_list *list; + unsigned alloc_len; + enum key_truncation truncation = KEY_TRUNCATED; + + + ldb = ldb_module_get_ctx(module); + + list = talloc_zero(module, struct dn_list); + if (list == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + dn_key = ldb_kv_index_key( + ldb, ldb_kv, el->name, &el->values[v_idx], &a, &truncation); + if (!dn_key) { + talloc_free(list); + return LDB_ERR_OPERATIONS_ERROR; + } + /* + * Samba only maintains unique indexes on the objectSID and objectGUID + * so if a unique index key exceeds the maximum length there is a + * problem. + */ + if ((truncation == KEY_TRUNCATED) && (a != NULL && + (a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX || + (el->flags & LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX)))) { + + ldb_asprintf_errstring( + ldb, + __location__ ": unique index key on %s in %s, " + "exceeds maximum key length of %u (encoded).", + el->name, + ldb_dn_get_linearized(msg->dn), + ldb_kv->max_key_length); + talloc_free(list); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + talloc_steal(list, dn_key); + + ret = ldb_kv_dn_list_load(module, ldb_kv, dn_key, list, + DN_LIST_MUTABLE); + if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) { + talloc_free(list); + return ret; + } + + /* + * Check for duplicates in the @IDXDN DN -> GUID record + * + * This is very normal, it just means a duplicate DN creation + * was attempted, so don't set the error string or print scary + * messages. + */ + if (list->count > 0 && + ldb_attr_cmp(el->name, LDB_KV_IDXDN) == 0 && + truncation == KEY_NOT_TRUNCATED) { + + talloc_free(list); + return LDB_ERR_CONSTRAINT_VIOLATION; + + } else if (list->count > 0 + && ldb_attr_cmp(el->name, LDB_KV_IDXDN) == 0) { + + /* + * At least one existing entry in the DN->GUID index, which + * arises when the DN indexes have been truncated + * + * So need to pull the DN's to check if it's really a duplicate + */ + unsigned int i; + for (i=0; i < list->count; i++) { + uint8_t guid_key[LDB_KV_GUID_KEY_SIZE]; + struct ldb_val key = { + .data = guid_key, + .length = sizeof(guid_key) + }; + const int flags = LDB_UNPACK_DATA_FLAG_NO_ATTRS; + struct ldb_message *rec = ldb_msg_new(ldb); + if (rec == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_kv_idx_to_key( + module, ldb_kv, ldb, &list->dn[i], &key); + if (ret != LDB_SUCCESS) { + TALLOC_FREE(list); + TALLOC_FREE(rec); + return ret; + } + + ret = + ldb_kv_search_key(module, ldb_kv, key, rec, flags); + if (key.data != guid_key) { + TALLOC_FREE(key.data); + } + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + /* + * the record has disappeared? + * yes, this can happen + */ + talloc_free(rec); + continue; + } + + if (ret != LDB_SUCCESS) { + /* an internal error */ + TALLOC_FREE(rec); + TALLOC_FREE(list); + return LDB_ERR_OPERATIONS_ERROR; + } + /* + * The DN we are trying to add to the DB and index + * is already here, so we must deny the addition + */ + if (ldb_dn_compare(msg->dn, rec->dn) == 0) { + TALLOC_FREE(rec); + TALLOC_FREE(list); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + } + } + + /* + * Check for duplicates in unique indexes + * + * We don't need to do a loop test like the @IDXDN case + * above as we have a ban on long unique index values + * at the start of this function. + */ + if (list->count > 0 && + ((a != NULL + && (a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX || + (el->flags & LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX))))) { + /* + * We do not want to print info about a possibly + * confidential DN that the conflict was with in the + * user-visible error string + */ + + if (ldb_kv->cache->GUID_index_attribute == NULL) { + ldb_debug(ldb, LDB_DEBUG_WARNING, + __location__ + ": unique index violation on %s in %s, " + "conflicts with %*.*s in %s", + el->name, ldb_dn_get_linearized(msg->dn), + (int)list->dn[0].length, + (int)list->dn[0].length, + list->dn[0].data, + ldb_dn_get_linearized(dn_key)); + } else { + /* This can't fail, gives a default at worst */ + const struct ldb_schema_attribute *attr = + ldb_schema_attribute_by_name( + ldb, ldb_kv->cache->GUID_index_attribute); + struct ldb_val v; + ret = attr->syntax->ldif_write_fn(ldb, list, + &list->dn[0], &v); + if (ret == LDB_SUCCESS) { + ldb_debug(ldb, + LDB_DEBUG_WARNING, + __location__ + ": unique index violation on %s in " + "%s, conflicts with %s %*.*s in %s", + el->name, + ldb_dn_get_linearized(msg->dn), + ldb_kv->cache->GUID_index_attribute, + (int)v.length, + (int)v.length, + v.data, + ldb_dn_get_linearized(dn_key)); + } + } + ldb_asprintf_errstring(ldb, + __location__ ": unique index violation " + "on %s in %s", + el->name, + ldb_dn_get_linearized(msg->dn)); + talloc_free(list); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + /* overallocate the list a bit, to reduce the number of + * realloc trigered copies */ + alloc_len = ((list->count+1)+7) & ~7; + list->dn = talloc_realloc(list, list->dn, struct ldb_val, alloc_len); + if (list->dn == NULL) { + talloc_free(list); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (ldb_kv->cache->GUID_index_attribute == NULL) { + const char *dn_str = ldb_dn_get_linearized(msg->dn); + list->dn[list->count].data + = (uint8_t *)talloc_strdup(list->dn, dn_str); + if (list->dn[list->count].data == NULL) { + talloc_free(list); + return LDB_ERR_OPERATIONS_ERROR; + } + list->dn[list->count].length = strlen(dn_str); + } else { + const struct ldb_val *key_val; + struct ldb_val *exact = NULL, *next = NULL; + key_val = ldb_msg_find_ldb_val( + msg, ldb_kv->cache->GUID_index_attribute); + if (key_val == NULL) { + talloc_free(list); + return ldb_module_operr(module); + } + + if (key_val->length != LDB_KV_GUID_SIZE) { + talloc_free(list); + return ldb_module_operr(module); + } + + BINARY_ARRAY_SEARCH_GTE(list->dn, list->count, + *key_val, ldb_val_equal_exact_ordered, + exact, next); + + /* + * Give a warning rather than fail, this could be a + * duplicate value in the record allowed by a caller + * forcing in the value with + * LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK + */ + if (exact != NULL && truncation == KEY_NOT_TRUNCATED) { + /* This can't fail, gives a default at worst */ + const struct ldb_schema_attribute *attr = + ldb_schema_attribute_by_name( + ldb, ldb_kv->cache->GUID_index_attribute); + struct ldb_val v; + ret = attr->syntax->ldif_write_fn(ldb, list, + exact, &v); + if (ret == LDB_SUCCESS) { + ldb_debug(ldb, + LDB_DEBUG_WARNING, + __location__ + ": duplicate attribute value in %s " + "for index on %s, " + "duplicate of %s %*.*s in %s", + ldb_dn_get_linearized(msg->dn), + el->name, + ldb_kv->cache->GUID_index_attribute, + (int)v.length, + (int)v.length, + v.data, + ldb_dn_get_linearized(dn_key)); + } + } + + if (next == NULL) { + next = &list->dn[list->count]; + } else { + memmove(&next[1], next, + sizeof(*next) * (list->count - (next - list->dn))); + } + *next = ldb_val_dup(list->dn, key_val); + if (next->data == NULL) { + talloc_free(list); + return ldb_module_operr(module); + } + } + list->count++; + + ret = ldb_kv_dn_list_store(module, dn_key, list); + + talloc_free(list); + + return ret; +} + +/* + add index entries for one elements in a message + */ +static int ldb_kv_index_add_el(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_message *msg, + struct ldb_message_element *el) +{ + unsigned int i; + for (i = 0; i < el->num_values; i++) { + int ret = ldb_kv_index_add1(module, ldb_kv, msg, el, i); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + return LDB_SUCCESS; +} + +/* + add index entries for all elements in a message + */ +static int ldb_kv_index_add_all(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_message *msg) +{ + struct ldb_message_element *elements = msg->elements; + unsigned int i; + const char *dn_str; + int ret; + + if (ldb_dn_is_special(msg->dn)) { + return LDB_SUCCESS; + } + + dn_str = ldb_dn_get_linearized(msg->dn); + if (dn_str == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_kv_write_index_dn_guid(module, msg, 1); + if (ret != LDB_SUCCESS) { + return ret; + } + + if (!ldb_kv->cache->attribute_indexes) { + /* no indexed fields */ + return LDB_SUCCESS; + } + + for (i = 0; i < msg->num_elements; i++) { + if (!ldb_kv_is_indexed(module, ldb_kv, elements[i].name)) { + continue; + } + ret = ldb_kv_index_add_el(module, ldb_kv, msg, &elements[i]); + if (ret != LDB_SUCCESS) { + struct ldb_context *ldb = ldb_module_get_ctx(module); + ldb_asprintf_errstring(ldb, + __location__ ": Failed to re-index %s in %s - %s", + elements[i].name, dn_str, + ldb_errstring(ldb)); + return ret; + } + } + + return LDB_SUCCESS; +} + + +/* + insert a DN index for a message +*/ +static int ldb_kv_modify_index_dn(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_message *msg, + struct ldb_dn *dn, + const char *index, + int add) +{ + struct ldb_message_element el; + struct ldb_val val; + int ret; + + val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(dn)); + if (val.data == NULL) { + const char *dn_str = ldb_dn_get_linearized(dn); + ldb_asprintf_errstring(ldb_module_get_ctx(module), + __location__ ": Failed to modify %s " + "against %s in %s: failed " + "to get casefold DN", + index, + ldb_kv->cache->GUID_index_attribute, + dn_str); + return LDB_ERR_OPERATIONS_ERROR; + } + + val.length = strlen((char *)val.data); + el.name = index; + el.values = &val; + el.num_values = 1; + + if (add) { + ret = ldb_kv_index_add1(module, ldb_kv, msg, &el, 0); + } else { /* delete */ + ret = ldb_kv_index_del_value(module, ldb_kv, msg, &el, 0); + } + + if (ret != LDB_SUCCESS) { + struct ldb_context *ldb = ldb_module_get_ctx(module); + const char *dn_str = ldb_dn_get_linearized(dn); + ldb_asprintf_errstring(ldb, + __location__ ": Failed to modify %s " + "against %s in %s - %s", + index, + ldb_kv->cache->GUID_index_attribute, + dn_str, + ldb_errstring(ldb)); + return ret; + } + return ret; +} + +/* + insert a one level index for a message +*/ +static int ldb_kv_index_onelevel(struct ldb_module *module, + const struct ldb_message *msg, + int add) +{ + struct ldb_kv_private *ldb_kv = talloc_get_type( + ldb_module_get_private(module), struct ldb_kv_private); + struct ldb_dn *pdn; + int ret; + + /* We index for ONE Level only if requested */ + if (!ldb_kv->cache->one_level_indexes) { + return LDB_SUCCESS; + } + + pdn = ldb_dn_get_parent(module, msg->dn); + if (pdn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + ret = + ldb_kv_modify_index_dn(module, ldb_kv, msg, pdn, LDB_KV_IDXONE, add); + + talloc_free(pdn); + + return ret; +} + +/* + insert a one level index for a message +*/ +static int ldb_kv_write_index_dn_guid(struct ldb_module *module, + const struct ldb_message *msg, + int add) +{ + int ret; + struct ldb_kv_private *ldb_kv = talloc_get_type( + ldb_module_get_private(module), struct ldb_kv_private); + + /* We index for DN only if using a GUID index */ + if (ldb_kv->cache->GUID_index_attribute == NULL) { + return LDB_SUCCESS; + } + + ret = ldb_kv_modify_index_dn( + module, ldb_kv, msg, msg->dn, LDB_KV_IDXDN, add); + + if (ret == LDB_ERR_CONSTRAINT_VIOLATION) { + ldb_asprintf_errstring(ldb_module_get_ctx(module), + "Entry %s already exists", + ldb_dn_get_linearized(msg->dn)); + ret = LDB_ERR_ENTRY_ALREADY_EXISTS; + } + return ret; +} + +/* + add the index entries for a new element in a record + The caller guarantees that these element values are not yet indexed +*/ +int ldb_kv_index_add_element(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_message *msg, + struct ldb_message_element *el) +{ + if (ldb_dn_is_special(msg->dn)) { + return LDB_SUCCESS; + } + if (!ldb_kv_is_indexed(module, ldb_kv, el->name)) { + return LDB_SUCCESS; + } + return ldb_kv_index_add_el(module, ldb_kv, msg, el); +} + +/* + add the index entries for a new record +*/ +int ldb_kv_index_add_new(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_message *msg) +{ + int ret; + + if (ldb_dn_is_special(msg->dn)) { + return LDB_SUCCESS; + } + + ret = ldb_kv_index_add_all(module, ldb_kv, msg); + if (ret != LDB_SUCCESS) { + /* + * Because we can't trust the caller to be doing + * transactions properly, clean up any index for this + * entry rather than relying on a transaction + * cleanup + */ + + ldb_kv_index_delete(module, msg); + return ret; + } + + ret = ldb_kv_index_onelevel(module, msg, 1); + if (ret != LDB_SUCCESS) { + /* + * Because we can't trust the caller to be doing + * transactions properly, clean up any index for this + * entry rather than relying on a transaction + * cleanup + */ + ldb_kv_index_delete(module, msg); + return ret; + } + return ret; +} + + +/* + delete an index entry for one message element +*/ +int ldb_kv_index_del_value(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_message *msg, + struct ldb_message_element *el, + unsigned int v_idx) +{ + struct ldb_context *ldb; + struct ldb_dn *dn_key; + const char *dn_str; + int ret, i; + unsigned int j; + struct dn_list *list; + struct ldb_dn *dn = msg->dn; + enum key_truncation truncation = KEY_NOT_TRUNCATED; + + ldb = ldb_module_get_ctx(module); + + dn_str = ldb_dn_get_linearized(dn); + if (dn_str == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (dn_str[0] == '@') { + return LDB_SUCCESS; + } + + dn_key = ldb_kv_index_key( + ldb, ldb_kv, el->name, &el->values[v_idx], NULL, &truncation); + /* + * We ignore key truncation in ltdb_index_add1() so + * match that by ignoring it here as well + * + * Multiple values are legitimate and accepted + */ + if (!dn_key) { + return LDB_ERR_OPERATIONS_ERROR; + } + + list = talloc_zero(dn_key, struct dn_list); + if (list == NULL) { + talloc_free(dn_key); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_kv_dn_list_load(module, ldb_kv, dn_key, list, + DN_LIST_MUTABLE); + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + /* it wasn't indexed. Did we have an earlier error? If we did then + its gone now */ + talloc_free(dn_key); + return LDB_SUCCESS; + } + + if (ret != LDB_SUCCESS) { + talloc_free(dn_key); + return ret; + } + + /* + * Find one of the values matching this message to remove + */ + i = ldb_kv_dn_list_find_msg(ldb_kv, list, msg); + if (i == -1) { + /* nothing to delete */ + talloc_free(dn_key); + return LDB_SUCCESS; + } + + j = (unsigned int) i; + if (j != list->count - 1) { + memmove(&list->dn[j], &list->dn[j+1], sizeof(list->dn[0])*(list->count - (j+1))); + } + list->count--; + if (list->count == 0) { + talloc_free(list->dn); + list->dn = NULL; + } else { + list->dn = talloc_realloc(list, list->dn, struct ldb_val, list->count); + } + + ret = ldb_kv_dn_list_store(module, dn_key, list); + + talloc_free(dn_key); + + return ret; +} + +/* + delete the index entries for a element + return -1 on failure +*/ +int ldb_kv_index_del_element(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_message *msg, + struct ldb_message_element *el) +{ + const char *dn_str; + int ret; + unsigned int i; + + if (!ldb_kv->cache->attribute_indexes) { + /* no indexed fields */ + return LDB_SUCCESS; + } + + dn_str = ldb_dn_get_linearized(msg->dn); + if (dn_str == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (dn_str[0] == '@') { + return LDB_SUCCESS; + } + + if (!ldb_kv_is_indexed(module, ldb_kv, el->name)) { + return LDB_SUCCESS; + } + for (i = 0; i < el->num_values; i++) { + ret = ldb_kv_index_del_value(module, ldb_kv, msg, el, i); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + return LDB_SUCCESS; +} + +/* + delete the index entries for a record + return -1 on failure +*/ +int ldb_kv_index_delete(struct ldb_module *module, + const struct ldb_message *msg) +{ + struct ldb_kv_private *ldb_kv = talloc_get_type( + ldb_module_get_private(module), struct ldb_kv_private); + int ret; + unsigned int i; + + if (ldb_dn_is_special(msg->dn)) { + return LDB_SUCCESS; + } + + ret = ldb_kv_index_onelevel(module, msg, 0); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_kv_write_index_dn_guid(module, msg, 0); + if (ret != LDB_SUCCESS) { + return ret; + } + + if (!ldb_kv->cache->attribute_indexes) { + /* no indexed fields */ + return LDB_SUCCESS; + } + + for (i = 0; i < msg->num_elements; i++) { + ret = ldb_kv_index_del_element( + module, ldb_kv, msg, &msg->elements[i]); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + return LDB_SUCCESS; +} + + +/* + traversal function that deletes all @INDEX records in the in-memory + TDB. + + This does not touch the actual DB, that is done at transaction + commit, which in turn greatly reduces DB churn as we will likely + be able to do a direct update into the old record. +*/ +static int delete_index(struct ldb_kv_private *ldb_kv, + struct ldb_val key, + _UNUSED_ struct ldb_val data, + void *state) +{ + struct ldb_module *module = state; + const char *dnstr = "DN=" LDB_KV_INDEX ":"; + struct dn_list list; + struct ldb_dn *dn; + struct ldb_val v; + int ret; + + if (strncmp((char *)key.data, dnstr, strlen(dnstr)) != 0) { + return 0; + } + /* we need to put a empty list in the internal tdb for this + * index entry */ + list.dn = NULL; + list.count = 0; + + /* the offset of 3 is to remove the DN= prefix. */ + v.data = key.data + 3; + v.length = strnlen((char *)key.data, key.length) - 3; + + dn = ldb_dn_from_ldb_val(ldb_kv, ldb_module_get_ctx(module), &v); + + /* + * This does not actually touch the DB quite yet, just + * the in-memory index cache + */ + ret = ldb_kv_dn_list_store(module, dn, &list); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb_module_get_ctx(module), + "Unable to store null index for %s\n", + ldb_dn_get_linearized(dn)); + talloc_free(dn); + return -1; + } + talloc_free(dn); + return 0; +} + +/* + traversal function that adds @INDEX records during a re index TODO wrong comment +*/ +static int re_key(struct ldb_kv_private *ldb_kv, + struct ldb_val key, + struct ldb_val val, + void *state) +{ + struct ldb_context *ldb; + struct ldb_kv_reindex_context *ctx = + (struct ldb_kv_reindex_context *)state; + struct ldb_module *module = ldb_kv->module; + struct ldb_message *msg; + int ret; + struct ldb_val key2; + bool is_record; + + ldb = ldb_module_get_ctx(module); + + is_record = ldb_kv_key_is_normal_record(key); + if (is_record == false) { + return 0; + } + + msg = ldb_msg_new(module); + if (msg == NULL) { + return -1; + } + + ret = ldb_unpack_data(ldb, &val, msg); + if (ret != 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n", + ldb_dn_get_linearized(msg->dn)); + ctx->error = ret; + talloc_free(msg); + return -1; + } + + if (msg->dn == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Refusing to re-index as GUID " + "key %*.*s with no DN\n", + (int)key.length, (int)key.length, + (char *)key.data); + talloc_free(msg); + return -1; + } + + /* check if the DN key has changed, perhaps due to the case + insensitivity of an element changing, or a change from DN + to GUID keys */ + key2 = ldb_kv_key_msg(module, msg, msg); + if (key2.data == NULL) { + /* probably a corrupt record ... darn */ + ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s", + ldb_dn_get_linearized(msg->dn)); + talloc_free(msg); + return 0; + } + if (key.length != key2.length || + (memcmp(key.data, key2.data, key.length) != 0)) { + ldb_kv->kv_ops->update_in_iterate( + ldb_kv, key, key2, val, ctx); + } + talloc_free(key2.data); + + talloc_free(msg); + + ctx->count++; + if (ctx->count % 10000 == 0) { + ldb_debug(ldb, LDB_DEBUG_WARNING, + "Reindexing: re-keyed %u records so far", + ctx->count); + } + + return 0; +} + +/* + traversal function that adds @INDEX records during a re index +*/ +static int re_index(struct ldb_kv_private *ldb_kv, + struct ldb_val key, + struct ldb_val val, + void *state) +{ + struct ldb_context *ldb; + struct ldb_kv_reindex_context *ctx = + (struct ldb_kv_reindex_context *)state; + struct ldb_module *module = ldb_kv->module; + struct ldb_message *msg; + int ret; + bool is_record; + + ldb = ldb_module_get_ctx(module); + + is_record = ldb_kv_key_is_normal_record(key); + if (is_record == false) { + return 0; + } + + msg = ldb_msg_new(module); + if (msg == NULL) { + return -1; + } + + ret = ldb_unpack_data(ldb, &val, msg); + if (ret != 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n", + ldb_dn_get_linearized(msg->dn)); + ctx->error = ret; + talloc_free(msg); + return -1; + } + + if (msg->dn == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Refusing to re-index as GUID " + "key %*.*s with no DN\n", + (int)key.length, (int)key.length, + (char *)key.data); + talloc_free(msg); + return -1; + } + + ret = ldb_kv_index_onelevel(module, msg, 1); + if (ret != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Adding special ONE LEVEL index failed (%s)!", + ldb_dn_get_linearized(msg->dn)); + talloc_free(msg); + return -1; + } + + ret = ldb_kv_index_add_all(module, ldb_kv, msg); + + if (ret != LDB_SUCCESS) { + ctx->error = ret; + talloc_free(msg); + return -1; + } + + talloc_free(msg); + + ctx->count++; + if (ctx->count % 10000 == 0) { + ldb_debug(ldb, LDB_DEBUG_WARNING, + "Reindexing: re-indexed %u records so far", + ctx->count); + } + + return 0; +} + +/* + * Convert the 4-byte pack format version to a number that's slightly + * more intelligible to a user e.g. version 0, 1, 2, etc. + */ +static uint32_t displayable_pack_version(uint32_t version) { + if (version < LDB_PACKING_FORMAT_NODN) { + return version; /* unknown - can't convert */ + } + + return (version - LDB_PACKING_FORMAT_NODN); +} + +static int re_pack(struct ldb_kv_private *ldb_kv, + _UNUSED_ struct ldb_val key, + struct ldb_val val, + void *state) +{ + struct ldb_context *ldb; + struct ldb_message *msg; + struct ldb_module *module = ldb_kv->module; + struct ldb_kv_repack_context *ctx = + (struct ldb_kv_repack_context *)state; + int ret; + + ldb = ldb_module_get_ctx(module); + + msg = ldb_msg_new(module); + if (msg == NULL) { + return -1; + } + + ret = ldb_unpack_data(ldb, &val, msg); + if (ret != 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Repack: unpack failed: %s\n", + ldb_dn_get_linearized(msg->dn)); + ctx->error = ret; + talloc_free(msg); + return -1; + } + + ret = ldb_kv_store(module, msg, TDB_MODIFY); + if (ret != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Repack: store failed: %s\n", + ldb_dn_get_linearized(msg->dn)); + ctx->error = ret; + talloc_free(msg); + return -1; + } + + /* + * Warn the user that we're repacking the first time we see a normal + * record. This means we never warn if we're repacking a database with + * only @ records. This is because during database initialisation, + * we might repack as initial settings are written out, and we don't + * want to spam the log. + */ + if ((!ctx->normal_record_seen) && (!ldb_dn_is_special(msg->dn))) { + ldb_debug(ldb, LDB_DEBUG_ALWAYS_LOG, + "Repacking database from v%u to v%u format " + "(first record %s)", + displayable_pack_version(ctx->old_version), + displayable_pack_version(ldb_kv->pack_format_version), + ldb_dn_get_linearized(msg->dn)); + ctx->normal_record_seen = true; + } + + ctx->count++; + if (ctx->count % 10000 == 0) { + ldb_debug(ldb, LDB_DEBUG_WARNING, + "Repack: re-packed %u records so far", + ctx->count); + } + + talloc_free(msg); + return 0; +} + +int ldb_kv_repack(struct ldb_module *module) +{ + struct ldb_kv_private *ldb_kv = talloc_get_type( + ldb_module_get_private(module), struct ldb_kv_private); + struct ldb_context *ldb = ldb_module_get_ctx(module); + struct ldb_kv_repack_context ctx; + int ret; + + ctx.old_version = ldb_kv->pack_format_version; + ctx.count = 0; + ctx.error = LDB_SUCCESS; + ctx.normal_record_seen = false; + + ldb_kv->pack_format_version = ldb_kv->target_pack_format_version; + + /* Iterate all database records and repack them in the new format */ + ret = ldb_kv->kv_ops->iterate(ldb_kv, re_pack, &ctx); + if (ret < 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Repack traverse failed: %s", + ldb_errstring(ldb)); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (ctx.error != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Repack failed: %s", + ldb_errstring(ldb)); + return ctx.error; + } + + return LDB_SUCCESS; +} + +/* + force a complete reindex of the database +*/ +int ldb_kv_reindex(struct ldb_module *module) +{ + struct ldb_kv_private *ldb_kv = talloc_get_type( + ldb_module_get_private(module), struct ldb_kv_private); + int ret; + struct ldb_kv_reindex_context ctx; + size_t index_cache_size = 0; + + /* + * Only triggered after a modification, but make clear we do + * not re-index a read-only DB + */ + if (ldb_kv->read_only) { + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + if (ldb_kv_cache_reload(module) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* + * Ensure we read (and so remove) the entries from the real + * DB, no values stored so far are any use as we want to do a + * re-index + */ + ldb_kv_index_transaction_cancel(module); + if (ldb_kv->nested_idx_ptr != NULL) { + ldb_kv_index_sub_transaction_cancel(ldb_kv); + } + + /* + * Calculate the size of the index cache needed for + * the re-index. If specified always use the + * ldb_kv->index_transaction_cache_size otherwise use the maximum + * of the size estimate or the DEFAULT_INDEX_CACHE_SIZE + */ + if (ldb_kv->index_transaction_cache_size > 0) { + index_cache_size = ldb_kv->index_transaction_cache_size; + } else { + index_cache_size = ldb_kv->kv_ops->get_size(ldb_kv); + if (index_cache_size < DEFAULT_INDEX_CACHE_SIZE) { + index_cache_size = DEFAULT_INDEX_CACHE_SIZE; + } + } + + /* + * Note that we don't start an index sub transaction for re-indexing + */ + ret = ldb_kv_index_transaction_start(module, index_cache_size); + if (ret != LDB_SUCCESS) { + return ret; + } + + /* first traverse the database deleting any @INDEX records by + * putting NULL entries in the in-memory tdb + */ + ret = ldb_kv->kv_ops->iterate(ldb_kv, delete_index, module); + if (ret < 0) { + struct ldb_context *ldb = ldb_module_get_ctx(module); + ldb_asprintf_errstring(ldb, "index deletion traverse failed: %s", + ldb_errstring(ldb)); + return LDB_ERR_OPERATIONS_ERROR; + } + + ctx.error = 0; + ctx.count = 0; + + ret = ldb_kv->kv_ops->iterate(ldb_kv, re_key, &ctx); + if (ret < 0) { + struct ldb_context *ldb = ldb_module_get_ctx(module); + ldb_asprintf_errstring(ldb, "key correction traverse failed: %s", + ldb_errstring(ldb)); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (ctx.error != LDB_SUCCESS) { + struct ldb_context *ldb = ldb_module_get_ctx(module); + ldb_asprintf_errstring(ldb, "reindexing failed: %s", ldb_errstring(ldb)); + return ctx.error; + } + + ctx.error = 0; + ctx.count = 0; + + /* now traverse adding any indexes for normal LDB records */ + ret = ldb_kv->kv_ops->iterate(ldb_kv, re_index, &ctx); + if (ret < 0) { + struct ldb_context *ldb = ldb_module_get_ctx(module); + ldb_asprintf_errstring(ldb, "reindexing traverse failed: %s", + ldb_errstring(ldb)); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (ctx.error != LDB_SUCCESS) { + struct ldb_context *ldb = ldb_module_get_ctx(module); + ldb_asprintf_errstring(ldb, "reindexing failed: %s", ldb_errstring(ldb)); + return ctx.error; + } + + if (ctx.count > 10000) { + ldb_debug(ldb_module_get_ctx(module), + LDB_DEBUG_WARNING, + "Reindexing: re_index successful on %s, " + "final index write-out will be in transaction commit", + ldb_kv->kv_ops->name(ldb_kv)); + } + return LDB_SUCCESS; +} + +/* + * Copy the contents of the nested transaction index cache record to the + * transaction index cache. + * + * During this 'commit' of the subtransaction to the main transaction + * (cache), care must be taken to free any existing index at the top + * level because otherwise we would leak memory. + */ +static int ldb_kv_sub_transaction_traverse( + struct tdb_context *tdb, + TDB_DATA key, + TDB_DATA data, + void *state) +{ + struct ldb_module *module = state; + struct ldb_kv_private *ldb_kv = talloc_get_type( + ldb_module_get_private(module), struct ldb_kv_private); + TDB_DATA rec = {0}; + struct dn_list *index_in_subtransaction = NULL; + struct dn_list *index_in_top_level = NULL; + int ret = 0; + + /* + * This unwraps the pointer in the DB into a pointer in + * memory, we are abusing TDB as a hash map, not a linearised + * database store + */ + index_in_subtransaction = ldb_kv_index_idxptr(module, data); + if (index_in_subtransaction == NULL) { + ldb_kv->idxptr->error = LDB_ERR_OPERATIONS_ERROR; + return -1; + } + + /* + * Do we already have an entry in the primary transaction cache + * If so free it's dn_list and replace it with the dn_list from + * the secondary cache + * + * The TDB and so the fetched rec contains NO DATA, just a + * pointer to data held in memory. + */ + rec = tdb_fetch(ldb_kv->idxptr->itdb, key); + if (rec.dptr != NULL) { + index_in_top_level = ldb_kv_index_idxptr(module, rec); + free(rec.dptr); + if (index_in_top_level == NULL) { + abort(); + } + /* + * We had this key at the top level. However we made a copy + * at the sub-transaction level so that we could possibly + * roll back. We have to free the top level index memory + * otherwise we would leak + */ + if (index_in_top_level->count > 0) { + TALLOC_FREE(index_in_top_level->dn); + } + index_in_top_level->dn + = talloc_steal(index_in_top_level, + index_in_subtransaction->dn); + index_in_top_level->count = index_in_subtransaction->count; + return 0; + } + + index_in_top_level = talloc(ldb_kv->idxptr, struct dn_list); + if (index_in_top_level == NULL) { + ldb_kv->idxptr->error = LDB_ERR_OPERATIONS_ERROR; + return -1; + } + index_in_top_level->dn + = talloc_steal(index_in_top_level, + index_in_subtransaction->dn); + index_in_top_level->count = index_in_subtransaction->count; + + rec.dptr = (uint8_t *)&index_in_top_level; + rec.dsize = sizeof(void *); + + + /* + * This is not a store into the main DB, but into an in-memory + * TDB, so we don't need a guard on ltdb->read_only + */ + ret = tdb_store(ldb_kv->idxptr->itdb, key, rec, TDB_INSERT); + if (ret != 0) { + ldb_kv->idxptr->error = ltdb_err_map( + tdb_error(ldb_kv->idxptr->itdb)); + return -1; + } + return 0; +} + +/* + * Initialise the index cache for a sub transaction. + */ +int ldb_kv_index_sub_transaction_start(struct ldb_kv_private *ldb_kv) +{ + ldb_kv->nested_idx_ptr = talloc_zero(ldb_kv, struct ldb_kv_idxptr); + if (ldb_kv->nested_idx_ptr == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* + * We use a tiny hash size for the sub-database (11). + * + * The sub-transaction is only for one record at a time, we + * would use a linked list but that would make the code even + * more complex when manipulating the index, as it would have + * to know if we were in a nested transaction (normal + * operations) or the top one (a reindex). + */ + ldb_kv->nested_idx_ptr->itdb = + tdb_open(NULL, 11, TDB_INTERNAL, O_RDWR, 0); + if (ldb_kv->nested_idx_ptr->itdb == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + return LDB_SUCCESS; +} + +/* + * Clear the contents of the nested transaction index cache when the nested + * transaction is cancelled. + */ +int ldb_kv_index_sub_transaction_cancel(struct ldb_kv_private *ldb_kv) +{ + if (ldb_kv->nested_idx_ptr != NULL) { + tdb_close(ldb_kv->nested_idx_ptr->itdb); + TALLOC_FREE(ldb_kv->nested_idx_ptr); + } + return LDB_SUCCESS; +} + +/* + * Commit a nested transaction, + * Copy the contents of the nested transaction index cache to the + * transaction index cache. + */ +int ldb_kv_index_sub_transaction_commit(struct ldb_kv_private *ldb_kv) +{ + int ret = 0; + + if (ldb_kv->nested_idx_ptr == NULL) { + return LDB_SUCCESS; + } + if (ldb_kv->nested_idx_ptr->itdb == NULL) { + return LDB_SUCCESS; + } + tdb_traverse( + ldb_kv->nested_idx_ptr->itdb, + ldb_kv_sub_transaction_traverse, + ldb_kv->module); + tdb_close(ldb_kv->nested_idx_ptr->itdb); + ldb_kv->nested_idx_ptr->itdb = NULL; + + ret = ldb_kv->nested_idx_ptr->error; + if (ret != LDB_SUCCESS) { + struct ldb_context *ldb = ldb_module_get_ctx(ldb_kv->module); + if (!ldb_errstring(ldb)) { + ldb_set_errstring(ldb, ldb_strerror(ret)); + } + ldb_asprintf_errstring( + ldb, + __location__": Failed to update index records in " + "sub transaction commit: %s", + ldb_errstring(ldb)); + } + TALLOC_FREE(ldb_kv->nested_idx_ptr); + return ret; +} diff --git a/ldb-2.0.8/ldb_key_value/ldb_kv_search.c b/ldb-2.0.8/ldb_key_value/ldb_kv_search.c new file mode 100644 index 0000000..f2d9619 --- /dev/null +++ b/ldb-2.0.8/ldb_key_value/ldb_kv_search.c @@ -0,0 +1,707 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb search functions + * + * Description: functions to search ldb+tdb databases + * + * Author: Andrew Tridgell + */ + +#include "ldb_kv.h" +#include "ldb_private.h" +#include "lib/util/attr.h" +/* + search the database for a single simple dn. + return LDB_ERR_NO_SUCH_OBJECT on record-not-found + and LDB_SUCCESS on success +*/ +int ldb_kv_search_base(struct ldb_module *module, + TALLOC_CTX *mem_ctx, + struct ldb_dn *dn, + struct ldb_dn **ret_dn) +{ + int exists; + int ret; + struct ldb_message *msg = NULL; + + if (ldb_dn_is_null(dn)) { + return LDB_ERR_NO_SUCH_OBJECT; + } + + /* + * We can't use tdb_exists() directly on a key when the TDB + * key is the GUID one, not the DN based one. So we just do a + * normal search and avoid most of the allocation with the + * LDB_UNPACK_DATA_FLAG_NO_ATTRS flag + */ + msg = ldb_msg_new(module); + if (msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_kv_search_dn1(module, dn, msg, LDB_UNPACK_DATA_FLAG_NO_ATTRS); + if (ret == LDB_SUCCESS) { + const char *dn_linearized + = ldb_dn_get_linearized(dn); + const char *msg_dn_linearized + = ldb_dn_get_linearized(msg->dn); + + if (strcmp(dn_linearized, msg_dn_linearized) == 0) { + /* + * Re-use the full incoming DN for + * subtree checks + */ + *ret_dn = dn; + } else { + /* + * Use the string DN from the unpack, so that + * we have a case-exact match of the base + */ + *ret_dn = talloc_steal(mem_ctx, msg->dn); + } + exists = true; + } else if (ret == LDB_ERR_NO_SUCH_OBJECT) { + exists = false; + } else { + talloc_free(msg); + return ret; + } + talloc_free(msg); + if (exists) { + return LDB_SUCCESS; + } + return LDB_ERR_NO_SUCH_OBJECT; +} + +struct ldb_kv_parse_data_unpack_ctx { + struct ldb_message *msg; + struct ldb_module *module; + struct ldb_kv_private *ldb_kv; + unsigned int unpack_flags; +}; + +static int ldb_kv_parse_data_unpack(struct ldb_val key, + struct ldb_val data, + void *private_data) +{ + struct ldb_kv_parse_data_unpack_ctx *ctx = private_data; + int ret; + struct ldb_context *ldb = ldb_module_get_ctx(ctx->module); + struct ldb_val data_parse = data; + + struct ldb_kv_private *ldb_kv = ctx->ldb_kv; + + if ((ldb_kv->kv_ops->options & LDB_KV_OPTION_STABLE_READ_LOCK) && + (ctx->unpack_flags & LDB_UNPACK_DATA_FLAG_READ_LOCKED) && + !ldb_kv->kv_ops->transaction_active(ldb_kv)) { + /* + * In the case where no transactions are active and + * we're in a read-lock, we can point directly into + * database memory. + * + * The database can't be changed underneath us and we + * will duplicate this data in the call to filter. + * + * This is seen in: + * - ldb_kv_index_filter + * - ldb_kv_search_and_return_base + */ + } else { + /* + * In every other case, since unpack doesn't memdup, we need + * to at least do a memdup on the whole data buffer as that + * may change later and the caller needs a stable result. + * + * During transactions, pointers could change and in + * TDB, there just aren't the same guarantees. + */ + data_parse.data = talloc_memdup(ctx->msg, + data.data, + data.length); + if (data_parse.data == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Unable to allocate data(%d) for %*.*s\n", + (int)data.length, + (int)key.length, (int)key.length, key.data); + return LDB_ERR_OPERATIONS_ERROR; + } + } + + ret = ldb_unpack_data_flags(ldb, &data_parse, + ctx->msg, ctx->unpack_flags); + if (ret == -1) { + if (data_parse.data != data.data) { + talloc_free(data_parse.data); + } + + ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %*.*s\n", + (int)key.length, (int)key.length, key.data); + return LDB_ERR_OPERATIONS_ERROR; + } + return ret; +} + +/* + search the database for a single simple dn, returning all attributes + in a single message + + return LDB_ERR_NO_SUCH_OBJECT on record-not-found + and LDB_SUCCESS on success +*/ +int ldb_kv_search_key(struct ldb_module *module, + struct ldb_kv_private *ldb_kv, + const struct ldb_val ldb_key, + struct ldb_message *msg, + unsigned int unpack_flags) +{ + int ret; + struct ldb_kv_parse_data_unpack_ctx ctx = { + .msg = msg, + .module = module, + .unpack_flags = unpack_flags, + .ldb_kv = ldb_kv + }; + + memset(msg, 0, sizeof(*msg)); + + msg->num_elements = 0; + msg->elements = NULL; + + ret = ldb_kv->kv_ops->fetch_and_parse( + ldb_kv, ldb_key, ldb_kv_parse_data_unpack, &ctx); + + if (ret == -1) { + ret = ldb_kv->kv_ops->error(ldb_kv); + if (ret == LDB_SUCCESS) { + /* + * Just to be sure we don't turn errors + * into success + */ + return LDB_ERR_OPERATIONS_ERROR; + } + return ret; + } else if (ret != LDB_SUCCESS) { + return ret; + } + + return LDB_SUCCESS; +} + +/* + search the database for a single simple dn, returning all attributes + in a single message + + return LDB_ERR_NO_SUCH_OBJECT on record-not-found + and LDB_SUCCESS on success +*/ +int ldb_kv_search_dn1(struct ldb_module *module, + struct ldb_dn *dn, + struct ldb_message *msg, + unsigned int unpack_flags) +{ + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + int ret; + uint8_t guid_key[LDB_KV_GUID_KEY_SIZE]; + struct ldb_val key = { + .data = guid_key, + .length = sizeof(guid_key) + }; + TALLOC_CTX *tdb_key_ctx = NULL; + + bool valid_dn = ldb_dn_validate(dn); + if (valid_dn == false) { + ldb_asprintf_errstring(ldb_module_get_ctx(module), + "Invalid Base DN: %s", + ldb_dn_get_linearized(dn)); + return LDB_ERR_INVALID_DN_SYNTAX; + } + + if (ldb_kv->cache->GUID_index_attribute == NULL || + ldb_dn_is_special(dn)) { + + tdb_key_ctx = talloc_new(msg); + if (!tdb_key_ctx) { + return ldb_module_oom(module); + } + + /* form the key */ + key = ldb_kv_key_dn(tdb_key_ctx, dn); + if (!key.data) { + TALLOC_FREE(tdb_key_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + } else { + /* + * Look in the index to find the key for this DN. + * + * the tdb_key memory is allocated above, msg is just + * used for internal memory. + * + */ + ret = ldb_kv_key_dn_from_idx(module, ldb_kv, msg, dn, &key); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + ret = ldb_kv_search_key(module, ldb_kv, key, msg, unpack_flags); + + TALLOC_FREE(tdb_key_ctx); + + if (ret != LDB_SUCCESS) { + return ret; + } + + if ((unpack_flags & LDB_UNPACK_DATA_FLAG_NO_DN) == 0) { + if (!msg->dn) { + msg->dn = ldb_dn_copy(msg, dn); + } + if (!msg->dn) { + return LDB_ERR_OPERATIONS_ERROR; + } + } + + return LDB_SUCCESS; +} + +/* + * filter the specified list of attributes from msg, + * adding requested attributes, and perhaps all for *, + * but not the DN to filtered_msg. + */ +int ldb_kv_filter_attrs(struct ldb_context *ldb, + const struct ldb_message *msg, + const char *const *attrs, + struct ldb_message *filtered_msg) +{ + return ldb_filter_attrs(ldb, msg, attrs, filtered_msg); +} + +/* + search function for a non-indexed search + */ +static int search_func(_UNUSED_ struct ldb_kv_private *ldb_kv, + struct ldb_val key, + struct ldb_val val, + void *state) +{ + struct ldb_context *ldb; + struct ldb_kv_context *ac; + struct ldb_message *msg, *filtered_msg; + int ret; + bool matched; + + ac = talloc_get_type(state, struct ldb_kv_context); + ldb = ldb_module_get_ctx(ac->module); + + /* + * We want to skip @ records early in a search full scan + * + * @ records like @IDXLIST are only available via a base + * search on the specific name but the method by which they + * were excluded was expensive, after the unpack the DN is + * exploded and ldb_match_msg_error() would reject it for + * failing to match the scope. + * + * ldb_kv_key_is_normal_record() uses the fact that @ records + * have the DN=@ prefix on their TDB/LMDB key to quickly + * exclude them from consideration. + * + * (any other non-records are also excluded by the same key + * match) + */ + + if (ldb_kv_key_is_normal_record(key) == false) { + return 0; + } + + msg = ldb_msg_new(ac); + if (!msg) { + ac->error = LDB_ERR_OPERATIONS_ERROR; + return -1; + } + + /* unpack the record */ + ret = ldb_unpack_data_flags(ldb, &val, msg, + LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC); + if (ret == -1) { + talloc_free(msg); + ac->error = LDB_ERR_OPERATIONS_ERROR; + return -1; + } + + if (!msg->dn) { + msg->dn = ldb_dn_new(msg, ldb, + (char *)key.data + 3); + if (msg->dn == NULL) { + talloc_free(msg); + ac->error = LDB_ERR_OPERATIONS_ERROR; + return -1; + } + } + + /* see if it matches the given expression */ + ret = ldb_match_msg_error(ldb, msg, + ac->tree, ac->base, ac->scope, &matched); + if (ret != LDB_SUCCESS) { + talloc_free(msg); + ac->error = LDB_ERR_OPERATIONS_ERROR; + return -1; + } + if (!matched) { + talloc_free(msg); + return 0; + } + + filtered_msg = ldb_msg_new(ac); + if (filtered_msg == NULL) { + TALLOC_FREE(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + filtered_msg->dn = talloc_steal(filtered_msg, msg->dn); + + /* filter the attributes that the user wants */ + ret = ldb_kv_filter_attrs(ldb, msg, ac->attrs, filtered_msg); + talloc_free(msg); + + if (ret == -1) { + TALLOC_FREE(filtered_msg); + ac->error = LDB_ERR_OPERATIONS_ERROR; + return -1; + } + + ret = ldb_module_send_entry(ac->req, filtered_msg, NULL); + if (ret != LDB_SUCCESS) { + ac->request_terminated = true; + /* the callback failed, abort the operation */ + ac->error = LDB_ERR_OPERATIONS_ERROR; + return -1; + } + + return 0; +} + + +/* + search the database with a LDAP-like expression. + this is the "full search" non-indexed variant +*/ +static int ldb_kv_search_full(struct ldb_kv_context *ctx) +{ + void *data = ldb_module_get_private(ctx->module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + int ret; + + ctx->error = LDB_SUCCESS; + ret = ldb_kv->kv_ops->iterate(ldb_kv, search_func, ctx); + + if (ret < 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return ctx->error; +} + +static int ldb_kv_search_and_return_base(struct ldb_kv_private *ldb_kv, + struct ldb_kv_context *ctx) +{ + struct ldb_message *msg, *filtered_msg; + struct ldb_context *ldb = ldb_module_get_ctx(ctx->module); + const char *dn_linearized; + const char *msg_dn_linearized; + int ret; + bool matched; + + msg = ldb_msg_new(ctx); + if (!msg) { + return LDB_ERR_OPERATIONS_ERROR; + } + ret = ldb_kv_search_dn1(ctx->module, + ctx->base, + msg, + LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC | + LDB_UNPACK_DATA_FLAG_READ_LOCKED); + + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + if (ldb_kv->check_base == false) { + /* + * In this case, we are done, as no base + * checking is allowed in this DB + */ + talloc_free(msg); + return LDB_SUCCESS; + } + ldb_asprintf_errstring(ldb, + "No such Base DN: %s", + ldb_dn_get_linearized(ctx->base)); + } + if (ret != LDB_SUCCESS) { + talloc_free(msg); + return ret; + } + + + /* + * We use this, not ldb_match_msg_error() as we know + * we matched on the scope BASE, as we just fetched + * the base DN + */ + + ret = ldb_match_message(ldb, msg, + ctx->tree, + ctx->scope, + &matched); + if (ret != LDB_SUCCESS) { + talloc_free(msg); + return ret; + } + if (!matched) { + talloc_free(msg); + return LDB_SUCCESS; + } + + dn_linearized = ldb_dn_get_linearized(ctx->base); + msg_dn_linearized = ldb_dn_get_linearized(msg->dn); + + filtered_msg = ldb_msg_new(ctx); + if (filtered_msg == NULL) { + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (strcmp(dn_linearized, msg_dn_linearized) == 0) { + /* + * If the DN is exactly the same string, then + * re-use the full incoming DN for the + * returned result, as it has already been + * casefolded + */ + filtered_msg->dn = ldb_dn_copy(filtered_msg, ctx->base); + } + + /* + * If the ldb_dn_copy() failed, or if we did not choose that + * optimisation (filtered_msg is zeroed at allocation), + * steal the one from the unpack + */ + if (filtered_msg->dn == NULL) { + filtered_msg->dn = talloc_steal(filtered_msg, msg->dn); + } + + /* + * filter the attributes that the user wants. + */ + ret = ldb_kv_filter_attrs(ldb, msg, ctx->attrs, filtered_msg); + if (ret == -1) { + talloc_free(msg); + filtered_msg = NULL; + return LDB_ERR_OPERATIONS_ERROR; + } + + /* + * Remove any extended components possibly copied in from + * msg->dn, we just want the casefold components + */ + ldb_dn_remove_extended_components(filtered_msg->dn); + talloc_free(msg); + + ret = ldb_module_send_entry(ctx->req, filtered_msg, NULL); + if (ret != LDB_SUCCESS) { + /* Regardless of success or failure, the msg + * is the callbacks responsiblity, and should + * not be talloc_free()'ed */ + ctx->request_terminated = true; + return ret; + } + + return LDB_SUCCESS; +} + +/* + search the database with a LDAP-like expression. + choses a search method +*/ +int ldb_kv_search(struct ldb_kv_context *ctx) +{ + struct ldb_context *ldb; + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + int ret; + + ldb = ldb_module_get_ctx(module); + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + if (ldb_kv->kv_ops->lock_read(module) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (ldb_kv_cache_load(module) != 0) { + ldb_kv->kv_ops->unlock_read(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (req->op.search.tree == NULL) { + ldb_kv->kv_ops->unlock_read(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + ctx->tree = req->op.search.tree; + ctx->scope = req->op.search.scope; + ctx->base = req->op.search.base; + ctx->attrs = req->op.search.attrs; + + if ((req->op.search.base == NULL) || (ldb_dn_is_null(req->op.search.base) == true)) { + + /* Check what we should do with a NULL dn */ + switch (req->op.search.scope) { + case LDB_SCOPE_BASE: + ldb_asprintf_errstring(ldb, + "NULL Base DN invalid for a base search"); + ret = LDB_ERR_INVALID_DN_SYNTAX; + break; + case LDB_SCOPE_ONELEVEL: + ldb_asprintf_errstring(ldb, + "NULL Base DN invalid for a one-level search"); + ret = LDB_ERR_INVALID_DN_SYNTAX; + break; + case LDB_SCOPE_SUBTREE: + default: + /* We accept subtree searches from a NULL base DN, ie over the whole DB */ + ret = LDB_SUCCESS; + } + } else if (req->op.search.scope == LDB_SCOPE_BASE) { + + /* + * If we are LDB_SCOPE_BASE, do just one search and + * return early. This is critical to ensure we do not + * go into the index code for special DNs, as that + * will try to look up an index record for a special + * record (which doesn't exist). + */ + ret = ldb_kv_search_and_return_base(ldb_kv, ctx); + + ldb_kv->kv_ops->unlock_read(module); + + return ret; + + } else if (ldb_kv->check_base) { + /* + * This database has been marked as + * 'checkBaseOnSearch', so do a spot check of the base + * dn. Also optimise the subsequent filter by filling + * in the ctx->base to be exactly case correct + */ + ret = ldb_kv_search_base( + module, ctx, req->op.search.base, &ctx->base); + + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + ldb_asprintf_errstring(ldb, + "No such Base DN: %s", + ldb_dn_get_linearized(req->op.search.base)); + } + + } else if (ldb_dn_validate(req->op.search.base) == false) { + + /* We don't want invalid base DNs here */ + ldb_asprintf_errstring(ldb, + "Invalid Base DN: %s", + ldb_dn_get_linearized(req->op.search.base)); + ret = LDB_ERR_INVALID_DN_SYNTAX; + + } else { + /* If we are not checking the base DN life is easy */ + ret = LDB_SUCCESS; + } + + if (ret == LDB_SUCCESS) { + uint32_t match_count = 0; + + ret = ldb_kv_search_indexed(ctx, &match_count); + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + /* Not in the index, therefore OK! */ + ret = LDB_SUCCESS; + + } + /* Check if we got just a normal error. + * In that case proceed to a full search unless we got a + * callback error */ + if (!ctx->request_terminated && ret != LDB_SUCCESS) { + /* Not indexed, so we need to do a full scan */ + if (ldb_kv->warn_unindexed || + ldb_kv->disable_full_db_scan) { + /* useful for debugging when slow performance + * is caused by unindexed searches */ + char *expression = ldb_filter_from_tree(ctx, ctx->tree); + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb FULL SEARCH: %s SCOPE: %s DN: %s", + expression, + req->op.search.scope==LDB_SCOPE_BASE?"base": + req->op.search.scope==LDB_SCOPE_ONELEVEL?"one": + req->op.search.scope==LDB_SCOPE_SUBTREE?"sub":"UNKNOWN", + ldb_dn_get_linearized(req->op.search.base)); + + talloc_free(expression); + } + + if (match_count != 0) { + /* the indexing code gave an error + * after having returned at least one + * entry. This means the indexes are + * corrupt or a database record is + * corrupt. We cannot continue with a + * full search or we may return + * duplicate entries + */ + ldb_kv->kv_ops->unlock_read(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (ldb_kv->disable_full_db_scan) { + ldb_set_errstring(ldb, + "ldb FULL SEARCH disabled"); + ldb_kv->kv_ops->unlock_read(module); + return LDB_ERR_INAPPROPRIATE_MATCHING; + } + + ret = ldb_kv_search_full(ctx); + if (ret != LDB_SUCCESS) { + ldb_set_errstring(ldb, "Indexed and full searches both failed!\n"); + } + } + } + + ldb_kv->kv_ops->unlock_read(module); + + return ret; +} diff --git a/ldb-2.0.8/ldb_ldap/ldb_ldap.c b/ldb-2.0.8/ldb_ldap/ldb_ldap.c new file mode 100644 index 0000000..d722299 --- /dev/null +++ b/ldb-2.0.8/ldb_ldap/ldb_ldap.c @@ -0,0 +1,969 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Simo Sorce 2006 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb_ldap + * + * Component: ldb ldap backend + * + * Description: core files for LDAP backend + * + * Author: Andrew Tridgell + * + * Modifications: + * + * - description: make the module use asynchronous calls + * date: Feb 2006 + * author: Simo Sorce + */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb_module.h" +#include "ldb_private.h" + +#define LDAP_DEPRECATED 1 +#include + +struct lldb_private { + LDAP *ldap; +}; + +struct lldb_context { + struct ldb_module *module; + struct ldb_request *req; + + struct lldb_private *lldb; + + struct ldb_control **controls; + int msgid; +}; + +static int lldb_ldap_to_ldb(int err) { + /* Ldap errors and ldb errors are defined to the same values */ + return err; +} + +/* + convert a ldb_message structure to a list of LDAPMod structures + ready for ldap_add() or ldap_modify() +*/ +static LDAPMod **lldb_msg_to_mods(void *mem_ctx, const struct ldb_message *msg, int use_flags) +{ + LDAPMod **mods; + unsigned int i, j; + int num_mods = 0; + + /* allocate maximum number of elements needed */ + mods = talloc_array(mem_ctx, LDAPMod *, msg->num_elements+1); + if (!mods) { + errno = ENOMEM; + return NULL; + } + mods[0] = NULL; + + for (i=0;inum_elements;i++) { + const struct ldb_message_element *el = &msg->elements[i]; + + mods[num_mods] = talloc(mods, LDAPMod); + if (!mods[num_mods]) { + goto failed; + } + mods[num_mods+1] = NULL; + mods[num_mods]->mod_op = LDAP_MOD_BVALUES; + if (use_flags) { + switch (el->flags & LDB_FLAG_MOD_MASK) { + case LDB_FLAG_MOD_ADD: + mods[num_mods]->mod_op |= LDAP_MOD_ADD; + break; + case LDB_FLAG_MOD_DELETE: + mods[num_mods]->mod_op |= LDAP_MOD_DELETE; + break; + case LDB_FLAG_MOD_REPLACE: + mods[num_mods]->mod_op |= LDAP_MOD_REPLACE; + break; + } + } + mods[num_mods]->mod_type = discard_const_p(char, el->name); + mods[num_mods]->mod_vals.modv_bvals = talloc_array(mods[num_mods], + struct berval *, + 1+el->num_values); + if (!mods[num_mods]->mod_vals.modv_bvals) { + goto failed; + } + + for (j=0;jnum_values;j++) { + mods[num_mods]->mod_vals.modv_bvals[j] = talloc(mods[num_mods]->mod_vals.modv_bvals, + struct berval); + if (!mods[num_mods]->mod_vals.modv_bvals[j]) { + goto failed; + } + mods[num_mods]->mod_vals.modv_bvals[j]->bv_val = (char *)el->values[j].data; + mods[num_mods]->mod_vals.modv_bvals[j]->bv_len = el->values[j].length; + } + mods[num_mods]->mod_vals.modv_bvals[j] = NULL; + num_mods++; + } + + return mods; + +failed: + talloc_free(mods); + return NULL; +} + +/* + add a single set of ldap message values to a ldb_message +*/ +static int lldb_add_msg_attr(struct ldb_context *ldb, + struct ldb_message *msg, + const char *attr, struct berval **bval) +{ + int count, i, ret; + struct ldb_message_element *el; + + count = ldap_count_values_len(bval); + + if (count <= 0) { + return -1; + } + + ret = ldb_msg_add_empty(msg, attr, 0, &el); + if (ret != LDB_SUCCESS) { + errno = ENOMEM; + return -1; + } + + el->values = talloc_array(msg->elements, struct ldb_val, count); + if (!el->values) { + errno = ENOMEM; + return -1; + } + + for (i=0;ivalues[i].data = talloc_size(el->values, bval[i]->bv_len+1); + if (!el->values[i].data) { + errno = ENOMEM; + return -1; + } + memcpy(el->values[i].data, bval[i]->bv_val, bval[i]->bv_len); + el->values[i].data[bval[i]->bv_len] = 0; + el->values[i].length = bval[i]->bv_len; + el->num_values++; + } + + msg->num_elements++; + + return 0; +} + +/* + search for matching records +*/ +static int lldb_search(struct lldb_context *lldb_ac) +{ + struct ldb_context *ldb; + struct lldb_private *lldb = lldb_ac->lldb; + struct ldb_module *module = lldb_ac->module; + struct ldb_request *req = lldb_ac->req; + struct timeval tv; + int ldap_scope; + char *search_base; + char *expression; + int ret; + + ldb = ldb_module_get_ctx(module); + + if (!req->callback || !req->context) { + ldb_set_errstring(ldb, "Async interface called with NULL callback function or NULL context"); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (req->op.search.tree == NULL) { + ldb_set_errstring(ldb, "Invalid expression parse tree"); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (req->controls != NULL) { + ldb_debug(ldb, LDB_DEBUG_WARNING, "Controls are not yet supported by ldb_ldap backend!"); + } + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + search_base = ldb_dn_alloc_linearized(lldb_ac, req->op.search.base); + if (req->op.search.base == NULL) { + search_base = talloc_strdup(lldb_ac, ""); + } + if (search_base == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + expression = ldb_filter_from_tree(lldb_ac, req->op.search.tree); + if (expression == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + switch (req->op.search.scope) { + case LDB_SCOPE_BASE: + ldap_scope = LDAP_SCOPE_BASE; + break; + case LDB_SCOPE_ONELEVEL: + ldap_scope = LDAP_SCOPE_ONELEVEL; + break; + default: + ldap_scope = LDAP_SCOPE_SUBTREE; + break; + } + + tv.tv_sec = 0; + tv.tv_usec = 0; + if (req->timeout > 0) { + tv.tv_sec = req->timeout; + } + + ret = ldap_search_ext(lldb->ldap, search_base, ldap_scope, + expression, + discard_const_p(char *, req->op.search.attrs), + 0, + NULL, + NULL, + &tv, + LDAP_NO_LIMIT, + &lldb_ac->msgid); + + if (ret != LDAP_SUCCESS) { + ldb_set_errstring(ldb, ldap_err2string(ret)); + } + + return lldb_ldap_to_ldb(ret); +} + +/* + add a record +*/ +static int lldb_add(struct lldb_context *lldb_ac) +{ + struct ldb_context *ldb; + struct lldb_private *lldb = lldb_ac->lldb; + struct ldb_module *module = lldb_ac->module; + struct ldb_request *req = lldb_ac->req; + LDAPMod **mods; + char *dn; + int ret; + + ldb = ldb_module_get_ctx(module); + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + mods = lldb_msg_to_mods(lldb_ac, req->op.add.message, 0); + if (mods == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + dn = ldb_dn_alloc_linearized(lldb_ac, req->op.add.message->dn); + if (dn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldap_add_ext(lldb->ldap, dn, mods, + NULL, + NULL, + &lldb_ac->msgid); + + if (ret != LDAP_SUCCESS) { + ldb_set_errstring(ldb, ldap_err2string(ret)); + } + + return lldb_ldap_to_ldb(ret); +} + +/* + modify a record +*/ +static int lldb_modify(struct lldb_context *lldb_ac) +{ + struct ldb_context *ldb; + struct lldb_private *lldb = lldb_ac->lldb; + struct ldb_module *module = lldb_ac->module; + struct ldb_request *req = lldb_ac->req; + LDAPMod **mods; + char *dn; + int ret; + + ldb = ldb_module_get_ctx(module); + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + mods = lldb_msg_to_mods(lldb_ac, req->op.mod.message, 1); + if (mods == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + dn = ldb_dn_alloc_linearized(lldb_ac, req->op.mod.message->dn); + if (dn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldap_modify_ext(lldb->ldap, dn, mods, + NULL, + NULL, + &lldb_ac->msgid); + + if (ret != LDAP_SUCCESS) { + ldb_set_errstring(ldb, ldap_err2string(ret)); + } + + return lldb_ldap_to_ldb(ret); +} + +/* + delete a record +*/ +static int lldb_delete(struct lldb_context *lldb_ac) +{ + struct ldb_context *ldb; + struct lldb_private *lldb = lldb_ac->lldb; + struct ldb_module *module = lldb_ac->module; + struct ldb_request *req = lldb_ac->req; + char *dnstr; + int ret; + + ldb = ldb_module_get_ctx(module); + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + dnstr = ldb_dn_alloc_linearized(lldb_ac, req->op.del.dn); + + ret = ldap_delete_ext(lldb->ldap, dnstr, + NULL, + NULL, + &lldb_ac->msgid); + + if (ret != LDAP_SUCCESS) { + ldb_set_errstring(ldb, ldap_err2string(ret)); + } + + return lldb_ldap_to_ldb(ret); +} + +/* + rename a record +*/ +static int lldb_rename(struct lldb_context *lldb_ac) +{ + struct ldb_context *ldb; + struct lldb_private *lldb = lldb_ac->lldb; + struct ldb_module *module = lldb_ac->module; + struct ldb_request *req = lldb_ac->req; + const char *rdn_name; + const struct ldb_val *rdn_val; + char *old_dn; + char *newrdn; + char *parentdn; + int ret; + + ldb = ldb_module_get_ctx(module); + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + old_dn = ldb_dn_alloc_linearized(lldb_ac, req->op.rename.olddn); + if (old_dn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + rdn_name = ldb_dn_get_rdn_name(req->op.rename.newdn); + rdn_val = ldb_dn_get_rdn_val(req->op.rename.newdn); + + if ((rdn_name != NULL) && (rdn_val != NULL)) { + newrdn = talloc_asprintf(lldb_ac, "%s=%s", rdn_name, + rdn_val->length > 0 ? ldb_dn_escape_value(lldb, *rdn_val) : ""); + } else { + newrdn = talloc_strdup(lldb_ac, ""); + } + if (!newrdn) { + return LDB_ERR_OPERATIONS_ERROR; + } + + parentdn = ldb_dn_alloc_linearized(lldb_ac, ldb_dn_get_parent(lldb_ac, req->op.rename.newdn)); + if (!parentdn) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldap_rename(lldb->ldap, old_dn, newrdn, parentdn, + 1, NULL, NULL, + &lldb_ac->msgid); + + if (ret != LDAP_SUCCESS) { + ldb_set_errstring(ldb, ldap_err2string(ret)); + } + + return lldb_ldap_to_ldb(ret); +} + +static int lldb_start_trans(struct ldb_module *module) +{ + /* TODO implement a local transaction mechanism here */ + + return LDB_SUCCESS; +} + +static int lldb_end_trans(struct ldb_module *module) +{ + /* TODO implement a local transaction mechanism here */ + + return LDB_SUCCESS; +} + +static int lldb_del_trans(struct ldb_module *module) +{ + /* TODO implement a local transaction mechanism here */ + + return LDB_SUCCESS; +} + +static void lldb_request_done(struct lldb_context *ac, + struct ldb_control **ctrls, int error) +{ + struct ldb_request *req; + struct ldb_reply *ares; + + req = ac->req; + + ares = talloc_zero(req, struct ldb_reply); + if (!ares) { + ldb_oom(ldb_module_get_ctx(ac->module)); + req->callback(req, NULL); + return; + } + ares->type = LDB_REPLY_DONE; + ares->controls = talloc_steal(ares, ctrls); + ares->error = error; + + req->callback(req, ares); +} + +/* return false if the request is still in progress + * return true if the request is completed + */ +static bool lldb_parse_result(struct lldb_context *ac, LDAPMessage *result) +{ + struct ldb_context *ldb; + struct lldb_private *lldb = ac->lldb; + LDAPControl **serverctrlsp = NULL; + char **referralsp = NULL; + char *matcheddnp = NULL; + char *errmsgp = NULL; + LDAPMessage *msg; + int type; + struct ldb_message *ldbmsg = NULL; + char *referral; + bool callback_failed; + bool request_done; + bool lret; + unsigned int i; + int ret; + + ldb = ldb_module_get_ctx(ac->module); + + type = ldap_msgtype(result); + callback_failed = false; + request_done = false; + + switch (type) { + case LDAP_RES_SEARCH_ENTRY: + + msg = ldap_first_entry(lldb->ldap, result); + if (msg != NULL) { + BerElement *berptr = NULL; + char *attr, *dn; + + ldbmsg = ldb_msg_new(ac); + if (!ldbmsg) { + ldb_oom(ldb); + ret = LDB_ERR_OPERATIONS_ERROR; + break; + } + + dn = ldap_get_dn(lldb->ldap, msg); + if (!dn) { + ldb_oom(ldb); + talloc_free(ldbmsg); + ret = LDB_ERR_OPERATIONS_ERROR; + break; + } + ldbmsg->dn = ldb_dn_new(ldbmsg, ldb, dn); + if ( ! ldb_dn_validate(ldbmsg->dn)) { + ldb_asprintf_errstring(ldb, "Invalid DN '%s' in reply", dn); + talloc_free(ldbmsg); + ret = LDB_ERR_OPERATIONS_ERROR; + ldap_memfree(dn); + break; + } + ldap_memfree(dn); + /* loop over all attributes */ + for (attr=ldap_first_attribute(lldb->ldap, msg, &berptr); + attr; + attr=ldap_next_attribute(lldb->ldap, msg, berptr)) { + struct berval **bval; + bval = ldap_get_values_len(lldb->ldap, msg, attr); + + if (bval) { + lldb_add_msg_attr(ldb, ldbmsg, attr, bval); + ldap_value_free_len(bval); + } + } + if (berptr) ber_free(berptr, 0); + + ret = ldb_module_send_entry(ac->req, ldbmsg, NULL /* controls not yet supported */); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, "entry send failed: %s", + ldb_errstring(ldb)); + callback_failed = true; + } + } else { + ret = LDB_ERR_OPERATIONS_ERROR; + } + break; + + case LDAP_RES_SEARCH_REFERENCE: + + ret = ldap_parse_reference(lldb->ldap, result, + &referralsp, &serverctrlsp, 0); + if (ret != LDAP_SUCCESS) { + ldb_asprintf_errstring(ldb, "ldap reference parse error: %s : %s", + ldap_err2string(ret), errmsgp); + ret = LDB_ERR_OPERATIONS_ERROR; + break; + } + if (referralsp == NULL) { + ldb_asprintf_errstring(ldb, "empty ldap referrals list"); + ret = LDB_ERR_PROTOCOL_ERROR; + break; + } + + for (i = 0; referralsp[i]; i++) { + referral = talloc_strdup(ac, referralsp[i]); + + ret = ldb_module_send_referral(ac->req, referral); + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, "referral send failed: %s", + ldb_errstring(ldb)); + callback_failed = true; + break; + } + } + break; + + case LDAP_RES_SEARCH_RESULT: + case LDAP_RES_MODIFY: + case LDAP_RES_ADD: + case LDAP_RES_DELETE: + case LDAP_RES_MODDN: + + if (ldap_parse_result(lldb->ldap, result, &ret, + &matcheddnp, &errmsgp, + &referralsp, &serverctrlsp, 0) != LDAP_SUCCESS) { + ret = LDB_ERR_OPERATIONS_ERROR; + } + if (ret != LDB_SUCCESS) { + ldb_asprintf_errstring(ldb, "ldap parse error for type %d: %s : %s", + type, ldap_err2string(ret), errmsgp); + break; + } + + if (serverctrlsp != NULL) { + /* FIXME: transform the LDAPControl list into an ldb_control one */ + ac->controls = NULL; + } + + request_done = true; + break; + + default: + ldb_asprintf_errstring(ldb, "unknown ldap return type: %d", type); + ret = LDB_ERR_PROTOCOL_ERROR; + break; + } + + if (ret != LDB_SUCCESS) { + + /* if the callback failed the caller will have freed the + * request. Just return and don't try to use it */ + if (callback_failed) { + + /* tell lldb_wait to remove the request from the + * queue */ + lret = true; + goto free_and_return; + } + + request_done = true; + } + + if (request_done) { + lldb_request_done(ac, ac->controls, ret); + lret = true; + goto free_and_return; + } + + lret = false; + +free_and_return: + + if (matcheddnp) ldap_memfree(matcheddnp); + if (errmsgp && *errmsgp) { + ldb_set_errstring(ldb, errmsgp); + } + if (errmsgp) { + ldap_memfree(errmsgp); + } + if (referralsp) ldap_value_free(referralsp); + if (serverctrlsp) ldap_controls_free(serverctrlsp); + + ldap_msgfree(result); + + return lret; +} + +static void lldb_timeout(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval t, + void *private_data) +{ + struct lldb_context *ac; + ac = talloc_get_type(private_data, struct lldb_context); + + lldb_request_done(ac, NULL, LDB_ERR_TIME_LIMIT_EXCEEDED); +} + +static void lldb_callback(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval t, + void *private_data) +{ + struct lldb_context *ac; + struct tevent_timer *lte; + struct timeval tv; + LDAPMessage *result; + int lret; + + ac = talloc_get_type(private_data, struct lldb_context); + + if (!ac->msgid) { + lldb_request_done(ac, NULL, LDB_ERR_OPERATIONS_ERROR); + return; + } + + tv.tv_sec = 0; + tv.tv_usec = 0; + lret = ldap_result(ac->lldb->ldap, ac->msgid, 0, &tv, &result); + if (lret == 0) { + goto respin; + } + if (lret == -1) { + lldb_request_done(ac, NULL, LDB_ERR_OPERATIONS_ERROR); + return; + } + + if ( ! lldb_parse_result(ac, result)) { + goto respin; + } + + return; + +respin: + tv.tv_sec = 0; + tv.tv_usec = 100; + lte = tevent_add_timer(ev, ac, tv, lldb_callback, ac); + if (NULL == lte) { + lldb_request_done(ac, NULL, LDB_ERR_OPERATIONS_ERROR); + } +} + +static bool lldb_dn_is_special(struct ldb_request *req) +{ + struct ldb_dn *dn = NULL; + + switch (req->operation) { + case LDB_ADD: + dn = req->op.add.message->dn; + break; + case LDB_MODIFY: + dn = req->op.mod.message->dn; + break; + case LDB_DELETE: + dn = req->op.del.dn; + break; + case LDB_RENAME: + dn = req->op.rename.olddn; + break; + default: + break; + } + + if (dn && ldb_dn_is_special(dn)) { + return true; + } + return false; +} + +static void lldb_auto_done_callback(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval t, + void *private_data) +{ + struct lldb_context *ac; + + ac = talloc_get_type(private_data, struct lldb_context); + lldb_request_done(ac, NULL, LDB_SUCCESS); +} + +static int lldb_handle_request(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + struct lldb_private *lldb; + struct lldb_context *ac; + struct tevent_context *ev; + struct tevent_timer *te; + struct timeval tv; + int ret; + + lldb = talloc_get_type(ldb_module_get_private(module), struct lldb_private); + ldb = ldb_module_get_ctx(module); + + if (req->starttime == 0 || req->timeout == 0) { + ldb_set_errstring(ldb, "Invalid timeout settings"); + return LDB_ERR_TIME_LIMIT_EXCEEDED; + } + + ev = ldb_get_event_context(ldb); + if (NULL == ev) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ac = talloc_zero(ldb, struct lldb_context); + if (ac == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->module = module; + ac->req = req; + ac->lldb = lldb; + ac->msgid = 0; + + if (lldb_dn_is_special(req)) { + tv.tv_sec = 0; + tv.tv_usec = 0; + te = tevent_add_timer(ev, ac, tv, + lldb_auto_done_callback, ac); + if (NULL == te) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return LDB_SUCCESS; + } + + switch (ac->req->operation) { + case LDB_SEARCH: + ret = lldb_search(ac); + break; + case LDB_ADD: + ret = lldb_add(ac); + break; + case LDB_MODIFY: + ret = lldb_modify(ac); + break; + case LDB_DELETE: + ret = lldb_delete(ac); + break; + case LDB_RENAME: + ret = lldb_rename(ac); + break; + default: + /* no other op supported */ + ret = LDB_ERR_PROTOCOL_ERROR; + break; + } + + if (ret != LDB_SUCCESS) { + lldb_request_done(ac, NULL, ret); + return ret; + } + + tv.tv_sec = 0; + tv.tv_usec = 0; + te = tevent_add_timer(ev, ac, tv, lldb_callback, ac); + if (NULL == te) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (req->timeout > 0) { + tv.tv_sec = req->starttime + req->timeout; + tv.tv_usec = 0; + te = tevent_add_timer(ev, ac, tv, lldb_timeout, ac); + if (NULL == te) { + return LDB_ERR_OPERATIONS_ERROR; + } + } + + return LDB_SUCCESS; +} + +static const struct ldb_module_ops lldb_ops = { + .name = "ldap", + .search = lldb_handle_request, + .add = lldb_handle_request, + .modify = lldb_handle_request, + .del = lldb_handle_request, + .rename = lldb_handle_request, + .request = lldb_handle_request, + .start_transaction = lldb_start_trans, + .end_transaction = lldb_end_trans, + .del_transaction = lldb_del_trans, +}; + + +static int lldb_destructor(struct lldb_private *lldb) +{ + ldap_unbind(lldb->ldap); + return 0; +} + + +/* + optionally perform a bind + */ +static int lldb_bind(struct ldb_module *module, + const char *options[]) +{ + const char *bind_mechanism; + struct lldb_private *lldb; + struct ldb_context *ldb = ldb_module_get_ctx(module); + int ret; + + bind_mechanism = ldb_options_find(ldb, options, "bindMech"); + if (bind_mechanism == NULL) { + /* no bind wanted */ + return LDB_SUCCESS; + } + + lldb = talloc_get_type(ldb_module_get_private(module), struct lldb_private); + + if (strcmp(bind_mechanism, "simple") == 0) { + const char *bind_id, *bind_secret; + + bind_id = ldb_options_find(ldb, options, "bindID"); + bind_secret = ldb_options_find(ldb, options, "bindSecret"); + if (bind_id == NULL || bind_secret == NULL) { + ldb_asprintf_errstring(ldb, "simple bind requires bindID and bindSecret"); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldap_simple_bind_s(lldb->ldap, bind_id, bind_secret); + if (ret != LDAP_SUCCESS) { + ldb_asprintf_errstring(ldb, "bind failed: %s", ldap_err2string(ret)); + return ret; + } + return LDB_SUCCESS; + } + + ldb_asprintf_errstring(ldb, "bind failed: unknown mechanism %s", bind_mechanism); + return LDB_ERR_INAPPROPRIATE_AUTHENTICATION; +} + +/* + connect to the database +*/ +static int lldb_connect(struct ldb_context *ldb, + const char *url, + unsigned int flags, + const char *options[], + struct ldb_module **_module) +{ + struct ldb_module *module; + struct lldb_private *lldb; + int version = 3; + int ret; + + module = ldb_module_new(ldb, ldb, "ldb_ldap backend", &lldb_ops); + if (!module) return LDB_ERR_OPERATIONS_ERROR; + + lldb = talloc_zero(module, struct lldb_private); + if (!lldb) { + ldb_oom(ldb); + goto failed; + } + ldb_module_set_private(module, lldb); + + ret = ldap_initialize(&lldb->ldap, url); + if (ret != LDAP_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_initialize failed for URL '%s' - %s", + url, ldap_err2string(ret)); + goto failed; + } + + talloc_set_destructor(lldb, lldb_destructor); + + ret = ldap_set_option(lldb->ldap, LDAP_OPT_PROTOCOL_VERSION, &version); + if (ret != LDAP_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_set_option failed - %s", + ldap_err2string(ret)); + goto failed; + } + + *_module = module; + + ret = lldb_bind(module, options); + if (ret != LDB_SUCCESS) { + goto failed; + } + + + return LDB_SUCCESS; + +failed: + talloc_free(module); + return LDB_ERR_OPERATIONS_ERROR; +} + +/* + initialise the module + */ +int ldb_ldap_init(const char *version) +{ + int ret, i; + const char *names[] = { "ldap", "ldaps", "ldapi", NULL }; + LDB_MODULE_CHECK_VERSION(version); + for (i=0; names[i]; i++) { + ret = ldb_register_backend(names[i], lldb_connect, false); + if (ret != LDB_SUCCESS) { + return ret; + } + } + return LDB_SUCCESS; +} diff --git a/ldb-2.0.8/ldb_ldb/ldb_ldb.c b/ldb-2.0.8/ldb_ldb/ldb_ldb.c new file mode 100644 index 0000000..a5a3612 --- /dev/null +++ b/ldb-2.0.8/ldb_ldb/ldb_ldb.c @@ -0,0 +1,80 @@ +/* + * ldb connection and module initialisation + * + * Copyright (C) Andrew Bartlett 2018 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#include "ldb_private.h" +#include "../ldb_tdb/ldb_tdb.h" +#ifdef HAVE_LMDB +#include "../ldb_mdb/ldb_mdb.h" +#endif /* HAVE_LMDB */ + +/* + connect to the database +*/ +static int lldb_connect(struct ldb_context *ldb, + const char *url, + unsigned int flags, + const char *options[], + struct ldb_module **module) +{ + const char *path; + int ret; + + /* + * Check and remove the url prefix + */ + if (strchr(url, ':')) { + if (strncmp(url, "ldb://", 6) != 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Invalid ldb URL '%s'", url); + return LDB_ERR_OPERATIONS_ERROR; + } + path = url+6; + } else { + path = url; + } + + /* + * Don't create the database if it's not there + */ + flags |= LDB_FLG_DONT_CREATE_DB; +#ifdef HAVE_LMDB + /* + * Try opening the database as an lmdb + */ + ret = lmdb_connect(ldb, path, flags, options, module); + if (ret == LDB_SUCCESS) { + return ret; + } + if (ret != LDB_ERR_UNAVAILABLE) { + return ret; + } + + /* + * Not mdb so try as tdb + */ +#endif /* HAVE_LMDB */ + ret = ltdb_connect(ldb, path, flags, options, module); + return ret; +} + +int ldb_ldb_init(const char *version) +{ + LDB_MODULE_CHECK_VERSION(version); + return ldb_register_backend("ldb", lldb_connect, false); +} diff --git a/ldb-2.0.8/ldb_map/ldb_map.c b/ldb-2.0.8/ldb_map/ldb_map.c new file mode 100644 index 0000000..b453dff --- /dev/null +++ b/ldb-2.0.8/ldb_map/ldb_map.c @@ -0,0 +1,1156 @@ +/* + ldb database mapping module + + Copyright (C) Jelmer Vernooij 2005 + Copyright (C) Martin Kuehl 2006 + Copyright (C) Simo Sorce 2008 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +/* + * Name: ldb + * + * Component: ldb ldb_map module + * + * Description: Map portions of data into a different format on a + * remote partition. + * + * Author: Jelmer Vernooij, Martin Kuehl + */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb_map.h" +#include "ldb_map_private.h" + +#ifndef _PUBLIC_ +#define _PUBLIC_ +#endif + +/* Description of the provided ldb requests: + - special attribute 'isMapped' + + - search: + - if parse tree can be split + - search remote records w/ remote attrs and parse tree + - otherwise + - enumerate all remote records + - for each remote result + - map remote result to local message + - search local result + - is present + - merge local into remote result + - run callback on merged result + - otherwise + - run callback on remote result + + - add: + - split message into local and remote part + - if local message is not empty + - add isMapped to local message + - add local message + - add remote message + + - modify: + - split message into local and remote part + - if local message is not empty + - add isMapped to local message + - search for local record + - if present + - modify local record + - otherwise + - add local message + - modify remote record + + - delete: + - search for local record + - if present + - delete local record + - delete remote record + + - rename: + - search for local record + - if present + - rename local record + - modify local isMapped + - rename remote record +*/ + + + +/* Private data structures + * ======================= */ + +/* Global private data */ +/* Extract mappings from private data. */ +const struct ldb_map_context *map_get_context(struct ldb_module *module) +{ + const struct map_private *data = talloc_get_type(ldb_module_get_private(module), struct map_private); + return data->context; +} + +/* Create a generic request context. */ +struct map_context *map_init_context(struct ldb_module *module, + struct ldb_request *req) +{ + struct ldb_context *ldb; + struct map_context *ac; + + ldb = ldb_module_get_ctx(module); + + ac = talloc_zero(req, struct map_context); + if (ac == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return NULL; + } + + ac->module = module; + ac->req = req; + + return ac; +} + +/* Dealing with DNs for different partitions + * ========================================= */ + +/* Check whether any data should be stored in the local partition. */ +bool map_check_local_db(struct ldb_module *module) +{ + const struct ldb_map_context *data = map_get_context(module); + + if (!data->remote_base_dn || !data->local_base_dn) { + return false; + } + + return true; +} + +/* Copy a DN with the base DN of the local partition. */ +static struct ldb_dn *ldb_dn_rebase_local(void *mem_ctx, const struct ldb_map_context *data, struct ldb_dn *dn) +{ + struct ldb_dn *new_dn; + + new_dn = ldb_dn_copy(mem_ctx, dn); + if ( ! ldb_dn_validate(new_dn)) { + talloc_free(new_dn); + return NULL; + } + + /* may be we don't need to rebase at all */ + if ( ! data->remote_base_dn || ! data->local_base_dn) { + return new_dn; + } + + if ( ! ldb_dn_remove_base_components(new_dn, ldb_dn_get_comp_num(data->remote_base_dn))) { + talloc_free(new_dn); + return NULL; + } + + if ( ! ldb_dn_add_base(new_dn, data->local_base_dn)) { + talloc_free(new_dn); + return NULL; + } + + return new_dn; +} + +/* Copy a DN with the base DN of the remote partition. */ +static struct ldb_dn *ldb_dn_rebase_remote(void *mem_ctx, const struct ldb_map_context *data, struct ldb_dn *dn) +{ + struct ldb_dn *new_dn; + + new_dn = ldb_dn_copy(mem_ctx, dn); + if ( ! ldb_dn_validate(new_dn)) { + talloc_free(new_dn); + return NULL; + } + + /* may be we don't need to rebase at all */ + if ( ! data->remote_base_dn || ! data->local_base_dn) { + return new_dn; + } + + if ( ! ldb_dn_remove_base_components(new_dn, ldb_dn_get_comp_num(data->local_base_dn))) { + talloc_free(new_dn); + return NULL; + } + + if ( ! ldb_dn_add_base(new_dn, data->remote_base_dn)) { + talloc_free(new_dn); + return NULL; + } + + return new_dn; +} + +/* Run a request and make sure it targets the remote partition. */ +/* TODO: free old DNs and messages? */ +int ldb_next_remote_request(struct ldb_module *module, struct ldb_request *request) +{ + const struct ldb_map_context *data = map_get_context(module); + struct ldb_context *ldb; + struct ldb_message *msg; + + ldb = ldb_module_get_ctx(module); + + switch (request->operation) { + case LDB_SEARCH: + if (request->op.search.base) { + request->op.search.base = ldb_dn_rebase_remote(request, data, request->op.search.base); + } else { + request->op.search.base = data->remote_base_dn; + /* TODO: adjust scope? */ + } + break; + + case LDB_ADD: + msg = ldb_msg_copy_shallow(request, request->op.add.message); + if (msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + msg->dn = ldb_dn_rebase_remote(msg, data, msg->dn); + request->op.add.message = msg; + break; + + case LDB_MODIFY: + msg = ldb_msg_copy_shallow(request, request->op.mod.message); + if (msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + msg->dn = ldb_dn_rebase_remote(msg, data, msg->dn); + request->op.mod.message = msg; + break; + + case LDB_DELETE: + request->op.del.dn = ldb_dn_rebase_remote(request, data, request->op.del.dn); + break; + + case LDB_RENAME: + request->op.rename.olddn = ldb_dn_rebase_remote(request, data, request->op.rename.olddn); + request->op.rename.newdn = ldb_dn_rebase_remote(request, data, request->op.rename.newdn); + break; + + default: + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " + "Invalid remote request!"); + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_next_request(module, request); +} + + +/* Finding mappings for attributes and objectClasses + * ================================================= */ + +/* Find an objectClass mapping by the local name. */ +static const struct ldb_map_objectclass *map_objectclass_find_local(const struct ldb_map_context *data, const char *name) +{ + unsigned int i; + + for (i = 0; data->objectclass_maps && data->objectclass_maps[i].local_name; i++) { + if (ldb_attr_cmp(data->objectclass_maps[i].local_name, name) == 0) { + return &data->objectclass_maps[i]; + } + } + + return NULL; +} + +/* Find an objectClass mapping by the remote name. */ +static const struct ldb_map_objectclass *map_objectclass_find_remote(const struct ldb_map_context *data, const char *name) +{ + unsigned int i; + + for (i = 0; data->objectclass_maps && data->objectclass_maps[i].remote_name; i++) { + if (ldb_attr_cmp(data->objectclass_maps[i].remote_name, name) == 0) { + return &data->objectclass_maps[i]; + } + } + + return NULL; +} + +/* Find an attribute mapping by the local name. */ +const struct ldb_map_attribute *map_attr_find_local(const struct ldb_map_context *data, const char *name) +{ + unsigned int i; + + for (i = 0; data->attribute_maps[i].local_name; i++) { + if (ldb_attr_cmp(data->attribute_maps[i].local_name, name) == 0) { + return &data->attribute_maps[i]; + } + } + for (i = 0; data->attribute_maps[i].local_name; i++) { + if (ldb_attr_cmp(data->attribute_maps[i].local_name, "*") == 0) { + return &data->attribute_maps[i]; + } + } + + return NULL; +} + +/* Find an attribute mapping by the remote name. */ +const struct ldb_map_attribute *map_attr_find_remote(const struct ldb_map_context *data, const char *name) +{ + const struct ldb_map_attribute *map; + const struct ldb_map_attribute *wildcard = NULL; + unsigned int i, j; + + for (i = 0; data->attribute_maps[i].local_name; i++) { + map = &data->attribute_maps[i]; + if (ldb_attr_cmp(map->local_name, "*") == 0) { + wildcard = &data->attribute_maps[i]; + } + + switch (map->type) { + case LDB_MAP_IGNORE: + break; + + case LDB_MAP_KEEP: + if (ldb_attr_cmp(map->local_name, name) == 0) { + return map; + } + break; + + case LDB_MAP_RENAME: + case LDB_MAP_RENDROP: + case LDB_MAP_CONVERT: + if (ldb_attr_cmp(map->u.rename.remote_name, name) == 0) { + return map; + } + break; + + case LDB_MAP_GENERATE: + for (j = 0; map->u.generate.remote_names[j]; j++) { + if (ldb_attr_cmp(map->u.generate.remote_names[j], name) == 0) { + return map; + } + } + break; + } + } + + /* We didn't find it, so return the wildcard record if one was configured */ + return wildcard; +} + + +/* Mapping attributes + * ================== */ + +/* Check whether an attribute will be mapped into the remote partition. */ +bool map_attr_check_remote(const struct ldb_map_context *data, const char *attr) +{ + const struct ldb_map_attribute *map = map_attr_find_local(data, attr); + + if (map == NULL) { + return false; + } + if (map->type == LDB_MAP_IGNORE) { + return false; + } + + return true; +} + +/* Map an attribute name into the remote partition. */ +const char *map_attr_map_local(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr) +{ + if (map == NULL) { + return talloc_strdup(mem_ctx, attr); + } + + switch (map->type) { + case LDB_MAP_KEEP: + return talloc_strdup(mem_ctx, attr); + + case LDB_MAP_RENAME: + case LDB_MAP_RENDROP: + case LDB_MAP_CONVERT: + return talloc_strdup(mem_ctx, map->u.rename.remote_name); + + default: + return NULL; + } +} + +/* Map an attribute name back into the local partition. */ +const char *map_attr_map_remote(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr) +{ + if (map == NULL) { + return talloc_strdup(mem_ctx, attr); + } + + if (map->type == LDB_MAP_KEEP) { + return talloc_strdup(mem_ctx, attr); + } + + return talloc_strdup(mem_ctx, map->local_name); +} + + +/* Merge two lists of attributes into a single one. */ +int map_attrs_merge(struct ldb_module *module, void *mem_ctx, + const char ***attrs, const char * const *more_attrs) +{ + unsigned int i, j, k; + + for (i = 0; *attrs && (*attrs)[i]; i++) /* noop */ ; + for (j = 0; more_attrs && more_attrs[j]; j++) /* noop */ ; + + *attrs = talloc_realloc(mem_ctx, *attrs, const char *, i+j+1); + if (*attrs == NULL) { + map_oom(module); + return -1; + } + + for (k = 0; k < j; k++) { + (*attrs)[i + k] = more_attrs[k]; + } + + (*attrs)[i+k] = NULL; + + return 0; +} + +/* Mapping ldb values + * ================== */ + +/* Map an ldb value into the remote partition. */ +struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, + const struct ldb_map_attribute *map, const struct ldb_val *val) +{ + if (map && (map->type == LDB_MAP_CONVERT) && (map->u.convert.convert_local)) { + return map->u.convert.convert_local(module, mem_ctx, val); + } + + return ldb_val_dup(mem_ctx, val); +} + +/* Map an ldb value back into the local partition. */ +struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, + const struct ldb_map_attribute *map, const struct ldb_val *val) +{ + if (map && (map->type == LDB_MAP_CONVERT) && (map->u.convert.convert_remote)) { + return map->u.convert.convert_remote(module, mem_ctx, val); + } + + return ldb_val_dup(mem_ctx, val); +} + + +/* Mapping DNs + * =========== */ + +/* Check whether a DN is below the local baseDN. */ +bool ldb_dn_check_local(struct ldb_module *module, struct ldb_dn *dn) +{ + const struct ldb_map_context *data = map_get_context(module); + + if (!data->local_base_dn) { + return true; + } + + return ldb_dn_compare_base(data->local_base_dn, dn) == 0; +} + +/* Map a DN into the remote partition. */ +struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn) +{ + const struct ldb_map_context *data = map_get_context(module); + struct ldb_context *ldb; + struct ldb_dn *newdn; + const struct ldb_map_attribute *map; + enum ldb_map_attr_type map_type; + const char *name; + struct ldb_val value; + int i, ret; + + if (dn == NULL) { + return NULL; + } + + ldb = ldb_module_get_ctx(module); + + newdn = ldb_dn_copy(mem_ctx, dn); + if (newdn == NULL) { + map_oom(module); + return NULL; + } + + /* For each RDN, map the component name and possibly the value */ + for (i = 0; i < ldb_dn_get_comp_num(newdn); i++) { + map = map_attr_find_local(data, ldb_dn_get_component_name(dn, i)); + + /* Unknown attribute - leave this RDN as is and hope the best... */ + if (map == NULL) { + map_type = LDB_MAP_KEEP; + } else { + map_type = map->type; + } + + switch (map_type) { + case LDB_MAP_IGNORE: + case LDB_MAP_GENERATE: + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " + "LDB_MAP_IGNORE/LDB_MAP_GENERATE attribute '%s' " + "used in DN!", ldb_dn_get_component_name(dn, i)); + goto failed; + + case LDB_MAP_CONVERT: + if (map->u.convert.convert_local == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " + "'convert_local' not set for attribute '%s' " + "used in DN!", ldb_dn_get_component_name(dn, i)); + goto failed; + } + + FALL_THROUGH; + case LDB_MAP_KEEP: + case LDB_MAP_RENAME: + case LDB_MAP_RENDROP: + name = map_attr_map_local(newdn, map, ldb_dn_get_component_name(dn, i)); + if (name == NULL) goto failed; + + value = ldb_val_map_local(module, newdn, map, ldb_dn_get_component_val(dn, i)); + if (value.data == NULL) goto failed; + + ret = ldb_dn_set_component(newdn, i, name, value); + if (ret != LDB_SUCCESS) { + goto failed; + } + + break; + } + } + + return newdn; + +failed: + talloc_free(newdn); + return NULL; +} + +/* Map a DN into the local partition. */ +struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn) +{ + const struct ldb_map_context *data = map_get_context(module); + struct ldb_context *ldb; + struct ldb_dn *newdn; + const struct ldb_map_attribute *map; + enum ldb_map_attr_type map_type; + const char *name; + struct ldb_val value; + int i, ret; + + if (dn == NULL) { + return NULL; + } + + ldb = ldb_module_get_ctx(module); + + newdn = ldb_dn_copy(mem_ctx, dn); + if (newdn == NULL) { + map_oom(module); + return NULL; + } + + /* For each RDN, map the component name and possibly the value */ + for (i = 0; i < ldb_dn_get_comp_num(newdn); i++) { + map = map_attr_find_remote(data, ldb_dn_get_component_name(dn, i)); + + /* Unknown attribute - leave this RDN as is and hope the best... */ + if (map == NULL) { + map_type = LDB_MAP_KEEP; + } else { + map_type = map->type; + } + + switch (map_type) { + case LDB_MAP_IGNORE: + case LDB_MAP_GENERATE: + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " + "LDB_MAP_IGNORE/LDB_MAP_GENERATE attribute '%s' " + "used in DN!", ldb_dn_get_component_name(dn, i)); + goto failed; + + case LDB_MAP_CONVERT: + if (map->u.convert.convert_remote == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " + "'convert_remote' not set for attribute '%s' " + "used in DN!", ldb_dn_get_component_name(dn, i)); + goto failed; + } + + FALL_THROUGH; + case LDB_MAP_KEEP: + case LDB_MAP_RENAME: + case LDB_MAP_RENDROP: + name = map_attr_map_remote(newdn, map, ldb_dn_get_component_name(dn, i)); + if (name == NULL) goto failed; + + value = ldb_val_map_remote(module, newdn, map, ldb_dn_get_component_val(dn, i)); + if (value.data == NULL) goto failed; + + ret = ldb_dn_set_component(newdn, i, name, value); + if (ret != LDB_SUCCESS) { + goto failed; + } + + break; + } + } + + return newdn; + +failed: + talloc_free(newdn); + return NULL; +} + +/* Map a DN and its base into the local partition. */ +/* TODO: This should not be required with GUIDs. */ +struct ldb_dn *ldb_dn_map_rebase_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn) +{ + const struct ldb_map_context *data = map_get_context(module); + struct ldb_dn *dn1, *dn2; + + dn1 = ldb_dn_rebase_local(mem_ctx, data, dn); + dn2 = ldb_dn_map_remote(module, mem_ctx, dn1); + + talloc_free(dn1); + return dn2; +} + + +/* Converting DNs and objectClasses (as ldb values) + * ================================================ */ + +/* Map a DN contained in an ldb value into the remote partition. */ +static struct ldb_val ldb_dn_convert_local(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) +{ + struct ldb_context *ldb; + struct ldb_dn *dn, *newdn; + struct ldb_val newval; + + ldb = ldb_module_get_ctx(module); + + dn = ldb_dn_from_ldb_val(mem_ctx, ldb, val); + if (! ldb_dn_validate(dn)) { + newval.length = 0; + newval.data = NULL; + talloc_free(dn); + return newval; + } + newdn = ldb_dn_map_local(module, mem_ctx, dn); + talloc_free(dn); + + newval.length = 0; + newval.data = (uint8_t *)ldb_dn_alloc_linearized(mem_ctx, newdn); + if (newval.data) { + newval.length = strlen((char *)newval.data); + } + talloc_free(newdn); + + return newval; +} + +/* Map a DN contained in an ldb value into the local partition. */ +static struct ldb_val ldb_dn_convert_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) +{ + struct ldb_context *ldb; + struct ldb_dn *dn, *newdn; + struct ldb_val newval; + + ldb = ldb_module_get_ctx(module); + + dn = ldb_dn_from_ldb_val(mem_ctx, ldb, val); + if (! ldb_dn_validate(dn)) { + newval.length = 0; + newval.data = NULL; + talloc_free(dn); + return newval; + } + newdn = ldb_dn_map_remote(module, mem_ctx, dn); + talloc_free(dn); + + newval.length = 0; + newval.data = (uint8_t *)ldb_dn_alloc_linearized(mem_ctx, newdn); + if (newval.data) { + newval.length = strlen((char *)newval.data); + } + talloc_free(newdn); + + return newval; +} + +/* Map an objectClass into the remote partition. */ +static struct ldb_val map_objectclass_convert_local(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) +{ + const struct ldb_map_context *data = map_get_context(module); + const char *name = (char *)val->data; + const struct ldb_map_objectclass *map = map_objectclass_find_local(data, name); + struct ldb_val newval; + + if (map) { + newval.data = (uint8_t*)talloc_strdup(mem_ctx, map->remote_name); + newval.length = strlen((char *)newval.data); + return newval; + } + + return ldb_val_dup(mem_ctx, val); +} + +/* Generate a remote message with a mapped objectClass. */ +static void map_objectclass_generate_remote(struct ldb_module *module, const char *local_attr, const struct ldb_message *old, struct ldb_message *remote, struct ldb_message *local) +{ + const struct ldb_map_context *data = map_get_context(module); + struct ldb_context *ldb; + struct ldb_message_element *el, *oc; + struct ldb_val val; + bool found_extensibleObject = false; + unsigned int i; + int ret; + + ldb = ldb_module_get_ctx(module); + + /* Find old local objectClass */ + oc = ldb_msg_find_element(old, "objectClass"); + if (oc == NULL) { + return; + } + + /* Prepare new element */ + el = talloc_zero(remote, struct ldb_message_element); + if (el == NULL) { + ldb_oom(ldb); + return; /* TODO: fail? */ + } + + /* Copy local objectClass element, reverse space for an extra value */ + el->num_values = oc->num_values + 1; + el->values = talloc_array(el, struct ldb_val, el->num_values); + if (el->values == NULL) { + talloc_free(el); + ldb_oom(ldb); + return; /* TODO: fail? */ + } + + /* Copy local element name "objectClass" */ + el->name = talloc_strdup(el, local_attr); + + /* Convert all local objectClasses */ + for (i = 0; i < el->num_values - 1; i++) { + el->values[i] = map_objectclass_convert_local(module, el->values, &oc->values[i]); + if (ldb_attr_cmp((char *)el->values[i].data, data->add_objectclass) == 0) { + found_extensibleObject = true; + } + } + + if (!found_extensibleObject) { + val.data = (uint8_t *)talloc_strdup(el->values, data->add_objectclass); + val.length = strlen((char *)val.data); + + /* Append additional objectClass data->add_objectclass */ + el->values[i] = val; + } else { + el->num_values--; + } + + /* Add new objectClass to remote message */ + ret = ldb_msg_add(remote, el, 0); + if (ret != LDB_SUCCESS) { + ldb_oom(ldb); + return; + } +} + +/* Map an objectClass into the local partition. */ +static struct ldb_val map_objectclass_convert_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) +{ + const struct ldb_map_context *data = map_get_context(module); + const char *name = (char *)val->data; + const struct ldb_map_objectclass *map = map_objectclass_find_remote(data, name); + struct ldb_val newval; + + if (map) { + newval.data = (uint8_t*)talloc_strdup(mem_ctx, map->local_name); + newval.length = strlen((char *)newval.data); + return newval; + } + + return ldb_val_dup(mem_ctx, val); +} + +/* Generate a local message with a mapped objectClass. */ +static struct ldb_message_element *map_objectclass_generate_local(struct ldb_module *module, void *mem_ctx, const char *local_attr, const struct ldb_message *remote) +{ + const struct ldb_map_context *data = map_get_context(module); + struct ldb_context *ldb; + struct ldb_message_element *el, *oc; + struct ldb_val val; + unsigned int i; + + ldb = ldb_module_get_ctx(module); + + /* Find old remote objectClass */ + oc = ldb_msg_find_element(remote, "objectClass"); + if (oc == NULL) { + return NULL; + } + + /* Prepare new element */ + el = talloc_zero(mem_ctx, struct ldb_message_element); + if (el == NULL) { + ldb_oom(ldb); + return NULL; + } + + /* Copy remote objectClass element */ + el->num_values = oc->num_values; + el->values = talloc_array(el, struct ldb_val, el->num_values); + if (el->values == NULL) { + talloc_free(el); + ldb_oom(ldb); + return NULL; + } + + /* Copy remote element name "objectClass" */ + el->name = talloc_strdup(el, local_attr); + + /* Convert all remote objectClasses */ + for (i = 0; i < el->num_values; i++) { + el->values[i] = map_objectclass_convert_remote(module, el->values, &oc->values[i]); + } + + val.data = (uint8_t *)talloc_strdup(el->values, data->add_objectclass); + val.length = strlen((char *)val.data); + + /* Remove last value if it was the string in data->add_objectclass (eg samba4top, extensibleObject) */ + if (ldb_val_equal_exact(&val, &el->values[i-1])) { + el->num_values--; + el->values = talloc_realloc(el, el->values, struct ldb_val, el->num_values); + if (el->values == NULL) { + talloc_free(el); + ldb_oom(ldb); + return NULL; + } + } + + return el; +} + +static const struct ldb_map_attribute objectclass_convert_map = { + .local_name = "objectClass", + .type = LDB_MAP_CONVERT, + .u = { + .convert = { + .remote_name = "objectClass", + .convert_local = map_objectclass_convert_local, + .convert_remote = map_objectclass_convert_remote, + }, + }, +}; + + +/* Mappings for searches on objectClass= assuming a one-to-one + * mapping. Needed because this is a generate operator for the + * add/modify code */ +static int map_objectclass_convert_operator(struct ldb_module *module, void *mem_ctx, + struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) +{ + + return map_subtree_collect_remote_simple(module, mem_ctx, new, tree, &objectclass_convert_map); +} + +/* Auxiliary request construction + * ============================== */ + +/* Build a request to search a record by its DN. */ +struct ldb_request *map_search_base_req(struct map_context *ac, struct ldb_dn *dn, const char * const *attrs, struct ldb_parse_tree *tree, void *context, ldb_map_callback_t callback) +{ + struct ldb_parse_tree *search_tree; + struct ldb_context *ldb; + struct ldb_request *req; + int ret; + + ldb = ldb_module_get_ctx(ac->module); + + if (tree) { + search_tree = tree; + } else { + search_tree = ldb_parse_tree(ac, NULL); + if (search_tree == NULL) { + return NULL; + } + } + + ret = ldb_build_search_req_ex(&req, ldb, ac, + dn, LDB_SCOPE_BASE, + search_tree, attrs, + NULL, + context, callback, + ac->req); + LDB_REQ_SET_LOCATION(req); + if (ret != LDB_SUCCESS) { + return NULL; + } + + return req; +} + +/* Build a request to update the 'IS_MAPPED' attribute */ +struct ldb_request *map_build_fixup_req(struct map_context *ac, + struct ldb_dn *olddn, + struct ldb_dn *newdn, + void *context, + ldb_map_callback_t callback) +{ + struct ldb_context *ldb; + struct ldb_request *req; + struct ldb_message *msg; + const char *dn; + int ret; + + ldb = ldb_module_get_ctx(ac->module); + + /* Prepare message */ + msg = ldb_msg_new(ac); + if (msg == NULL) { + map_oom(ac->module); + return NULL; + } + + /* Update local 'IS_MAPPED' to the new remote DN */ + msg->dn = ldb_dn_copy(msg, olddn); + dn = ldb_dn_alloc_linearized(msg, newdn); + if ( ! dn || ! ldb_dn_validate(msg->dn)) { + goto failed; + } + if (ldb_msg_add_empty(msg, IS_MAPPED, LDB_FLAG_MOD_REPLACE, NULL) != 0) { + goto failed; + } + if (ldb_msg_add_string(msg, IS_MAPPED, dn) != 0) { + goto failed; + } + + /* Prepare request */ + ret = ldb_build_mod_req(&req, ldb, + ac, msg, NULL, + context, callback, + ac->req); + LDB_REQ_SET_LOCATION(req); + if (ret != LDB_SUCCESS) { + goto failed; + } + talloc_steal(req, msg); + + return req; +failed: + talloc_free(msg); + return NULL; +} + +/* Module initialization + * ===================== */ + + +/* Builtin mappings for DNs and objectClasses */ +static const struct ldb_map_attribute builtin_attribute_maps[] = { + { + .local_name = "dn", + .type = LDB_MAP_CONVERT, + .u = { + .convert = { + .remote_name = "dn", + .convert_local = ldb_dn_convert_local, + .convert_remote = ldb_dn_convert_remote, + }, + }, + }, + { + .local_name = NULL, + } +}; + +static const struct ldb_map_attribute objectclass_attribute_map = { + .local_name = "objectClass", + .type = LDB_MAP_GENERATE, + .convert_operator = map_objectclass_convert_operator, + .u = { + .generate = { + .remote_names = { "objectClass", NULL }, + .generate_local = map_objectclass_generate_local, + .generate_remote = map_objectclass_generate_remote, + }, + }, +}; + + +/* Find the special 'MAP_DN_NAME' record and store local and remote + * base DNs in private data. */ +static int map_init_dns(struct ldb_module *module, struct ldb_map_context *data, const char *name) +{ + static const char * const attrs[] = { MAP_DN_FROM, MAP_DN_TO, NULL }; + struct ldb_context *ldb; + struct ldb_dn *dn; + struct ldb_message *msg; + struct ldb_result *res; + int ret; + + if (!name) { + data->local_base_dn = NULL; + data->remote_base_dn = NULL; + return LDB_SUCCESS; + } + + ldb = ldb_module_get_ctx(module); + + dn = ldb_dn_new_fmt(data, ldb, "%s=%s", MAP_DN_NAME, name); + if ( ! ldb_dn_validate(dn)) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " + "Failed to construct '%s' DN!", MAP_DN_NAME); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_search(ldb, data, &res, dn, LDB_SCOPE_BASE, attrs, NULL); + talloc_free(dn); + if (ret != LDB_SUCCESS) { + return ret; + } + if (res->count == 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " + "No results for '%s=%s'!", MAP_DN_NAME, name); + talloc_free(res); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + if (res->count > 1) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " + "Too many results for '%s=%s'!", MAP_DN_NAME, name); + talloc_free(res); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + msg = res->msgs[0]; + data->local_base_dn = ldb_msg_find_attr_as_dn(ldb, data, msg, MAP_DN_FROM); + data->remote_base_dn = ldb_msg_find_attr_as_dn(ldb, data, msg, MAP_DN_TO); + talloc_free(res); + + return LDB_SUCCESS; +} + +/* Store attribute maps and objectClass maps in private data. */ +static int map_init_maps(struct ldb_module *module, struct ldb_map_context *data, + const struct ldb_map_attribute *attrs, + const struct ldb_map_objectclass *ocls, + const char * const *wildcard_attributes) +{ + unsigned int i, j, last; + last = 0; + + /* Count specified attribute maps */ + for (i = 0; attrs[i].local_name; i++) /* noop */ ; + /* Count built-in attribute maps */ + for (j = 0; builtin_attribute_maps[j].local_name; j++) /* noop */ ; + + /* Store list of attribute maps */ + data->attribute_maps = talloc_array(data, struct ldb_map_attribute, i+j+2); + if (data->attribute_maps == NULL) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Specified ones go first */ + for (i = 0; attrs[i].local_name; i++) { + data->attribute_maps[last] = attrs[i]; + last++; + } + + /* Built-in ones go last */ + for (i = 0; builtin_attribute_maps[i].local_name; i++) { + data->attribute_maps[last] = builtin_attribute_maps[i]; + last++; + } + + if (data->add_objectclass) { + /* ObjectClass one is very last, if required */ + data->attribute_maps[last] = objectclass_attribute_map; + last++; + } else if (ocls) { + data->attribute_maps[last] = objectclass_convert_map; + last++; + } + + /* Ensure 'local_name == NULL' for the last entry */ + memset(&data->attribute_maps[last], 0, sizeof(struct ldb_map_attribute)); + + /* Store list of objectClass maps */ + data->objectclass_maps = ocls; + + data->wildcard_attributes = wildcard_attributes; + + return LDB_SUCCESS; +} + +/* Initialize global private data. */ +_PUBLIC_ int ldb_map_init(struct ldb_module *module, const struct ldb_map_attribute *attrs, + const struct ldb_map_objectclass *ocls, + const char * const *wildcard_attributes, + const char *add_objectclass, + const char *name) +{ + struct map_private *data; + int ret; + + /* Prepare private data */ + data = talloc_zero(module, struct map_private); + if (data == NULL) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + ldb_module_set_private(module, data); + + data->context = talloc_zero(data, struct ldb_map_context); + if (!data->context) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Store local and remote baseDNs */ + ret = map_init_dns(module, data->context, name); + if (ret != LDB_SUCCESS) { + talloc_free(data); + return ret; + } + + data->context->add_objectclass = add_objectclass; + + /* Store list of attribute and objectClass maps */ + ret = map_init_maps(module, data->context, attrs, ocls, wildcard_attributes); + if (ret != LDB_SUCCESS) { + talloc_free(data); + return ret; + } + + return LDB_SUCCESS; +} diff --git a/ldb-2.0.8/ldb_map/ldb_map.h b/ldb-2.0.8/ldb_map/ldb_map.h new file mode 100644 index 0000000..46ef3cc --- /dev/null +++ b/ldb-2.0.8/ldb_map/ldb_map.h @@ -0,0 +1,174 @@ +/* + ldb database mapping module + + Copyright (C) Jelmer Vernooij 2005 + Copyright (C) Martin Kuehl 2006 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifndef __LDB_MAP_H__ +#define __LDB_MAP_H__ + +#include "ldb_module.h" + +/* ldb_map is a skeleton LDB module that can be used for any other modules + * that need to map attributes. + * + * The term 'remote' in this header refers to the connection where the + * original schema is used on while 'local' means the local connection + * that any upper layers will use. + * + * All local attributes will have to have a definition. Not all remote + * attributes need a definition as LDB is a lot less strict than LDAP + * (in other words, sending unknown attributes to an LDAP server hurts us, + * while returning too many attributes in ldb_search() doesn't) + */ + + +/* Name of the internal attribute pointing from the local to the + * remote part of a record */ +#define IS_MAPPED "isMapped" + + +struct ldb_map_context; + +/* convert a local ldb_val to a remote ldb_val */ +typedef struct ldb_val (*ldb_map_convert_func) (struct ldb_module *module, void *mem_ctx, const struct ldb_val *val); + +#define LDB_MAP_MAX_REMOTE_NAMES 10 + +/* map from local to remote attribute */ +struct ldb_map_attribute { + const char *local_name; /* local name */ + + enum ldb_map_attr_type { + LDB_MAP_IGNORE, /* Ignore this local attribute. Doesn't exist remotely. */ + LDB_MAP_KEEP, /* Keep as is. Same name locally and remotely. */ + LDB_MAP_RENAME, /* Simply rename the attribute. Name changes, data is the same */ + LDB_MAP_CONVERT, /* Rename + convert data */ + LDB_MAP_GENERATE, /* Use generate function for generating new name/data. + Used for generating attributes based on + multiple remote attributes. */ + LDB_MAP_RENDROP /* Rename the attribute. Strip from Add requests. */ + } type; + + /* if set, will be called for search expressions that contain this attribute */ + int (*convert_operator)(struct ldb_module *, TALLOC_CTX *ctx, struct ldb_parse_tree **ntree, const struct ldb_parse_tree *otree); + + union { + struct { + const char *remote_name; + } rename; + + struct { + const char *remote_name; + + /* Convert local to remote data */ + ldb_map_convert_func convert_local; + + /* Convert remote to local data */ + /* an entry can have convert_remote set to NULL, as long as there as an entry with the same local_name + * that is non-NULL before it. */ + ldb_map_convert_func convert_remote; + } convert; + + struct { + /* Generate the local attribute from remote message */ + struct ldb_message_element *(*generate_local)(struct ldb_module *, TALLOC_CTX *mem_ctx, const char *remote_attr, const struct ldb_message *remote); + + /* Update remote message with information from local message */ + void (*generate_remote)(struct ldb_module *, const char *local_attr, const struct ldb_message *old, struct ldb_message *remote, struct ldb_message *local); + + /* Name(s) for this attribute on the remote server. This is an array since + * one local attribute's data can be split up into several attributes + * remotely */ + const char *remote_names[LDB_MAP_MAX_REMOTE_NAMES]; + + /* Names of additional remote attributes + * required for the generation. NULL + * indicates that `local_attr' suffices. */ + /* +#define LDB_MAP_MAX_SELF_ATTRIBUTES 10 + const char *self_attrs[LDB_MAP_MAX_SELF_ATTRIBUTES]; + */ + } generate; + } u; +}; + + +#define LDB_MAP_MAX_SUBCLASSES 10 +#define LDB_MAP_MAX_MUSTS 10 +#define LDB_MAP_MAX_MAYS 50 + +/* map from local to remote objectClass */ +struct ldb_map_objectclass { + const char *local_name; + const char *remote_name; + const char *base_classes[LDB_MAP_MAX_SUBCLASSES]; + const char *musts[LDB_MAP_MAX_MUSTS]; + const char *mays[LDB_MAP_MAX_MAYS]; +}; + + +/* private context data */ +struct ldb_map_context { + struct ldb_map_attribute *attribute_maps; + /* NOTE: Always declare base classes first here */ + const struct ldb_map_objectclass *objectclass_maps; + + /* Remote (often operational) attributes that should be added + * to any wildcard search */ + const char * const *wildcard_attributes; + + /* ObjectClass (if any) to be added to remote attributes on add */ + const char *add_objectclass; + + /* struct ldb_context *mapped_ldb; */ + struct ldb_dn *local_base_dn; + struct ldb_dn *remote_base_dn; +}; + +/* Global private data */ +struct map_private { + void *caller_private; + struct ldb_map_context *context; +}; + +/* Initialize global private data. */ +int ldb_map_init(struct ldb_module *module, const struct ldb_map_attribute *attrs, + const struct ldb_map_objectclass *ocls, + const char * const *wildcard_attributes, + const char *add_objectclass, + const char *name); + +int ldb_map_add(struct ldb_module *module, struct ldb_request *req); +int ldb_map_search(struct ldb_module *module, struct ldb_request *req); +int ldb_map_rename(struct ldb_module *module, struct ldb_request *req); +int ldb_map_delete(struct ldb_module *module, struct ldb_request *req); +int ldb_map_modify(struct ldb_module *module, struct ldb_request *req); + +#define LDB_MAP_OPS \ + .add = ldb_map_add, \ + .modify = ldb_map_modify, \ + .del = ldb_map_delete, \ + .rename = ldb_map_rename, \ + .search = ldb_map_search, + +#endif /* __LDB_MAP_H__ */ diff --git a/ldb-2.0.8/ldb_map/ldb_map_inbound.c b/ldb-2.0.8/ldb_map/ldb_map_inbound.c new file mode 100644 index 0000000..861c4c1 --- /dev/null +++ b/ldb-2.0.8/ldb_map/ldb_map_inbound.c @@ -0,0 +1,846 @@ +/* + ldb database mapping module + + Copyright (C) Jelmer Vernooij 2005 + Copyright (C) Martin Kuehl 2006 + Copyright (C) Simo Sorce 2008 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb_map.h" +#include "ldb_map_private.h" + + +/* Mapping message elements + * ======================== */ + +/* Map a message element into the remote partition. */ +static struct ldb_message_element *ldb_msg_el_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_message_element *old) +{ + struct ldb_message_element *el; + unsigned int i; + + el = talloc_zero(mem_ctx, struct ldb_message_element); + if (el == NULL) { + map_oom(module); + return NULL; + } + + el->num_values = old->num_values; + el->values = talloc_array(el, struct ldb_val, el->num_values); + if (el->values == NULL) { + talloc_free(el); + map_oom(module); + return NULL; + } + + el->name = map_attr_map_local(el, map, old->name); + + for (i = 0; i < el->num_values; i++) { + el->values[i] = ldb_val_map_local(module, el->values, map, &old->values[i]); + } + + return el; +} + +/* Add a message element either to a local or to a remote message, + * depending on whether it goes into the local or remote partition. */ +static int ldb_msg_el_partition(struct ldb_module *module, enum ldb_request_type optype, struct ldb_message *local, struct ldb_message *remote, const struct ldb_message *msg, const char *attr_name, /* const char * const names[], */ const struct ldb_message_element *old) +{ + const struct ldb_map_context *data = map_get_context(module); + const struct ldb_map_attribute *map = map_attr_find_local(data, attr_name); + struct ldb_message_element *el=NULL; + struct ldb_context *ldb = ldb_module_get_ctx(module); + + /* Unknown attribute: ignore */ + if (map == NULL) { + ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " + "Not mapping attribute '%s': no mapping found", + old->name); + goto local; + } + + switch (map->type) { + case LDB_MAP_RENDROP: + if (optype != LDB_ADD) { + /* do the same as LDB_MAP_RENAME */ + el = ldb_msg_el_map_local(module, remote, map, old); + break; + } + + FALL_THROUGH; + case LDB_MAP_IGNORE: + goto local; + + case LDB_MAP_CONVERT: + if (map->u.convert.convert_local == NULL) { + ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " + "Not mapping attribute '%s': " + "'convert_local' not set", + map->local_name); + goto local; + } + + FALL_THROUGH; + case LDB_MAP_KEEP: + case LDB_MAP_RENAME: + el = ldb_msg_el_map_local(module, remote, map, old); + break; + + case LDB_MAP_GENERATE: + if (map->u.generate.generate_remote == NULL) { + ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " + "Not mapping attribute '%s': " + "'generate_remote' not set", + map->local_name); + goto local; + } + + /* TODO: if this attr requires context: + * make sure all context attrs are mappable (in 'names') + * make sure all context attrs have already been mapped? + * maybe postpone generation until they have been mapped? + */ + + map->u.generate.generate_remote(module, map->local_name, msg, remote, local); + return 0; + } + + if (el == NULL) { + return -1; + } + + return ldb_msg_add(remote, el, old->flags); + +local: + el = talloc(local, struct ldb_message_element); + if (el == NULL) { + map_oom(module); + return -1; + } + + *el = *old; /* copy the old element */ + + return ldb_msg_add(local, el, old->flags); +} + +/* Mapping messages + * ================ */ + +/* Check whether a message will be (partially) mapped into the remote partition. */ +static bool ldb_msg_check_remote(struct ldb_module *module, const struct ldb_message *msg) +{ + const struct ldb_map_context *data = map_get_context(module); + bool ret; + unsigned int i; + + for (i = 0; i < msg->num_elements; i++) { + ret = map_attr_check_remote(data, msg->elements[i].name); + if (ret) { + return ret; + } + } + + return false; +} + +/* Split message elements that stay in the local partition from those + * that are mapped into the remote partition. */ +static int ldb_msg_partition(struct ldb_module *module, enum ldb_request_type optype, struct ldb_message *local, struct ldb_message *remote, const struct ldb_message *msg) +{ + /* const char * const names[]; */ + struct ldb_context *ldb; + unsigned int i; + int ret; + + ldb = ldb_module_get_ctx(module); + + for (i = 0; i < msg->num_elements; i++) { + /* Skip 'IS_MAPPED' */ + if (ldb_attr_cmp(msg->elements[i].name, IS_MAPPED) == 0) { + ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " + "Skipping attribute '%s'", + msg->elements[i].name); + continue; + } + + ret = ldb_msg_el_partition(module, optype, local, remote, msg, msg->elements[i].name, &msg->elements[i]); + if (ret) { + return ret; + } + } + + return 0; +} + + +static int map_add_do_local(struct map_context *ac); +static int map_modify_do_local(struct map_context *ac); +static int map_delete_do_local(struct map_context *ac); +static int map_rename_do_local(struct map_context *ac); +static int map_rename_do_fixup(struct map_context *ac); +static int map_rename_local_callback(struct ldb_request *req, + struct ldb_reply *ares); + + +/***************************************************************************** + * COMMON INBOUND functions +*****************************************************************************/ + +/* Store the DN of a single search result in context. */ +static int map_search_self_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct ldb_context *ldb; + struct map_context *ac; + int ret; + + ac = talloc_get_type(req->context, struct map_context); + ldb = ldb_module_get_ctx(ac->module); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + /* We are interested only in the single reply */ + switch(ares->type) { + case LDB_REPLY_ENTRY: + /* We have already found a remote DN */ + if (ac->local_dn) { + ldb_set_errstring(ldb, + "Too many results!"); + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + /* Store local DN */ + ac->local_dn = talloc_steal(ac, ares->message->dn); + break; + + case LDB_REPLY_DONE: + + switch (ac->req->operation) { + case LDB_MODIFY: + ret = map_modify_do_local(ac); + break; + case LDB_DELETE: + ret = map_delete_do_local(ac); + break; + case LDB_RENAME: + ret = map_rename_do_local(ac); + break; + default: + /* if we get here we have definitely a problem */ + ret = LDB_ERR_OPERATIONS_ERROR; + } + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + default: + /* ignore referrals */ + break; + } + + talloc_free(ares); + return LDB_SUCCESS; +} + +/* Build a request to search the local record by its DN. */ +static int map_search_self_req(struct ldb_request **req, + struct map_context *ac, + struct ldb_dn *dn) +{ + /* attrs[] is returned from this function in + * ac->search_req->op.search.attrs, so it must be static, as + * otherwise the compiler can put it on the stack */ + static const char * const attrs[] = { IS_MAPPED, NULL }; + struct ldb_parse_tree *tree; + + /* Limit search to records with 'IS_MAPPED' present */ + tree = ldb_parse_tree(ac, "(" IS_MAPPED "=*)"); + if (tree == NULL) { + map_oom(ac->module); + return LDB_ERR_OPERATIONS_ERROR; + } + + *req = map_search_base_req(ac, dn, attrs, tree, + ac, map_search_self_callback); + if (*req == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return LDB_SUCCESS; +} + +static int map_op_local_callback(struct ldb_request *req, + struct ldb_reply *ares) +{ + struct ldb_context *ldb; + struct map_context *ac; + int ret; + + ac = talloc_get_type(req->context, struct map_context); + ldb = ldb_module_get_ctx(ac->module); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + if (ares->type != LDB_REPLY_DONE) { + ldb_asprintf_errstring(ldb, "Invalid LDB reply type %d", ares->type); + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + /* Do the remote request. */ + ret = ldb_next_remote_request(ac->module, ac->remote_req); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + return LDB_SUCCESS; +} + +static int map_op_remote_callback(struct ldb_request *req, + struct ldb_reply *ares) +{ + struct ldb_context *ldb; + struct map_context *ac; + + ac = talloc_get_type(req->context, struct map_context); + ldb = ldb_module_get_ctx(ac->module); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + if (ares->type != LDB_REPLY_DONE) { + ldb_asprintf_errstring(ldb, "Invalid LDB reply type %d", ares->type); + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); +} + + +/***************************************************************************** + * ADD operations +*****************************************************************************/ + + +/* Add a record. */ +int ldb_map_add(struct ldb_module *module, struct ldb_request *req) +{ + const struct ldb_message *msg = req->op.add.message; + struct ldb_context *ldb; + struct map_context *ac; + struct ldb_message *remote_msg; + int ret; + + ldb = ldb_module_get_ctx(module); + + /* Do not manipulate our control entries */ + if (ldb_dn_is_special(msg->dn)) { + return ldb_next_request(module, req); + } + + /* No mapping requested (perhaps no DN mapping specified), skip to next module */ + if (!ldb_dn_check_local(module, msg->dn)) { + return ldb_next_request(module, req); + } + + /* No mapping needed, fail */ + if (!ldb_msg_check_remote(module, msg)) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Prepare context and handle */ + ac = map_init_context(module, req); + if (ac == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + + /* Prepare the local message */ + ac->local_msg = ldb_msg_new(ac); + if (ac->local_msg == NULL) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + ac->local_msg->dn = msg->dn; + + /* Prepare the remote message */ + remote_msg = ldb_msg_new(ac); + if (remote_msg == NULL) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + remote_msg->dn = ldb_dn_map_local(ac->module, remote_msg, msg->dn); + + /* Split local from remote message */ + ldb_msg_partition(module, req->operation, ac->local_msg, remote_msg, msg); + + /* Prepare the remote operation */ + ret = ldb_build_add_req(&ac->remote_req, ldb, + ac, remote_msg, + req->controls, + ac, map_op_remote_callback, + req); + LDB_REQ_SET_LOCATION(ac->remote_req); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if ((ac->local_msg->num_elements == 0) || + ( ! map_check_local_db(ac->module))) { + /* No local data or db, just run the remote request */ + return ldb_next_remote_request(ac->module, ac->remote_req); + } + + /* Store remote DN in 'IS_MAPPED' */ + /* TODO: use GUIDs here instead */ + ret = ldb_msg_add_linearized_dn(ac->local_msg, IS_MAPPED, + remote_msg->dn); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return map_add_do_local(ac); +} + +/* Add the local record. */ +static int map_add_do_local(struct map_context *ac) +{ + struct ldb_request *local_req; + struct ldb_context *ldb; + int ret; + + ldb = ldb_module_get_ctx(ac->module); + + /* Prepare the local operation */ + ret = ldb_build_add_req(&local_req, ldb, ac, + ac->local_msg, + ac->req->controls, + ac, + map_op_local_callback, + ac->req); + LDB_REQ_SET_LOCATION(local_req); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + return ldb_next_request(ac->module, local_req); +} + +/***************************************************************************** + * MODIFY operations +*****************************************************************************/ + +/* Modify a record. */ +int ldb_map_modify(struct ldb_module *module, struct ldb_request *req) +{ + const struct ldb_message *msg = req->op.mod.message; + struct ldb_request *search_req = NULL; + struct ldb_message *remote_msg; + struct ldb_context *ldb; + struct map_context *ac; + int ret; + + ldb = ldb_module_get_ctx(module); + + /* Do not manipulate our control entries */ + if (ldb_dn_is_special(msg->dn)) { + return ldb_next_request(module, req); + } + + /* No mapping requested (perhaps no DN mapping specified), skip to next module */ + if (!ldb_dn_check_local(module, msg->dn)) { + return ldb_next_request(module, req); + } + + /* No mapping needed, skip to next module */ + /* TODO: What if the remote part exists, the local doesn't, + * and this request wants to modify local data and thus + * add the local record? */ + if (!ldb_msg_check_remote(module, msg)) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Prepare context and handle */ + ac = map_init_context(module, req); + if (ac == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Prepare the local message */ + ac->local_msg = ldb_msg_new(ac); + if (ac->local_msg == NULL) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + ac->local_msg->dn = msg->dn; + + /* Prepare the remote message */ + remote_msg = ldb_msg_new(ac->remote_req); + if (remote_msg == NULL) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + remote_msg->dn = ldb_dn_map_local(ac->module, remote_msg, msg->dn); + + /* Split local from remote message */ + ldb_msg_partition(module, req->operation, ac->local_msg, remote_msg, msg); + + /* Prepare the remote operation */ + ret = ldb_build_mod_req(&ac->remote_req, ldb, + ac, remote_msg, + req->controls, + ac, map_op_remote_callback, + req); + LDB_REQ_SET_LOCATION(ac->remote_req); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if ((ac->local_msg->num_elements == 0) || + ( ! map_check_local_db(ac->module))) { + /* No local data or db, just run the remote request */ + return ldb_next_remote_request(ac->module, ac->remote_req); + } + + /* prepare the search operation */ + ret = map_search_self_req(&search_req, ac, msg->dn); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_next_request(module, search_req); +} + +/* Modify the local record. */ +static int map_modify_do_local(struct map_context *ac) +{ + struct ldb_request *local_req; + struct ldb_context *ldb; + int ret; + + ldb = ldb_module_get_ctx(ac->module); + + if (ac->local_dn == NULL) { + /* No local record present, add it instead */ + /* Add local 'IS_MAPPED' */ + /* TODO: use GUIDs here instead */ + if (ldb_msg_add_empty(ac->local_msg, IS_MAPPED, + LDB_FLAG_MOD_ADD, NULL) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + ret = ldb_msg_add_linearized_dn(ac->local_msg, IS_MAPPED, + ac->remote_req->op.mod.message->dn); + if (ret != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Prepare the local operation */ + ret = ldb_build_add_req(&local_req, ldb, ac, + ac->local_msg, + ac->req->controls, + ac, + map_op_local_callback, + ac->req); + LDB_REQ_SET_LOCATION(local_req); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + } else { + /* Prepare the local operation */ + ret = ldb_build_mod_req(&local_req, ldb, ac, + ac->local_msg, + ac->req->controls, + ac, + map_op_local_callback, + ac->req); + LDB_REQ_SET_LOCATION(local_req); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + } + + return ldb_next_request(ac->module, local_req); +} + +/***************************************************************************** + * DELETE operations +*****************************************************************************/ + +/* Delete a record. */ +int ldb_map_delete(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_request *search_req; + struct ldb_context *ldb; + struct map_context *ac; + int ret; + + ldb = ldb_module_get_ctx(module); + + /* Do not manipulate our control entries */ + if (ldb_dn_is_special(req->op.del.dn)) { + return ldb_next_request(module, req); + } + + /* No mapping requested (perhaps no DN mapping specified). + * Skip to next module */ + if (!ldb_dn_check_local(module, req->op.del.dn)) { + return ldb_next_request(module, req); + } + + /* Prepare context and handle */ + ac = map_init_context(module, req); + if (ac == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Prepare the remote operation */ + ret = ldb_build_del_req(&ac->remote_req, ldb, ac, + ldb_dn_map_local(module, ac, req->op.del.dn), + req->controls, + ac, + map_op_remote_callback, + req); + LDB_REQ_SET_LOCATION(ac->remote_req); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* No local db, just run the remote request */ + if (!map_check_local_db(ac->module)) { + /* Do the remote request. */ + return ldb_next_remote_request(ac->module, ac->remote_req); + } + + /* Prepare the search operation */ + ret = map_search_self_req(&search_req, ac, req->op.del.dn); + if (ret != LDB_SUCCESS) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_next_request(module, search_req); +} + +/* Delete the local record. */ +static int map_delete_do_local(struct map_context *ac) +{ + struct ldb_request *local_req; + struct ldb_context *ldb; + int ret; + + ldb = ldb_module_get_ctx(ac->module); + + /* No local record, continue remotely */ + if (ac->local_dn == NULL) { + /* Do the remote request. */ + return ldb_next_remote_request(ac->module, ac->remote_req); + } + + /* Prepare the local operation */ + ret = ldb_build_del_req(&local_req, ldb, ac, + ac->req->op.del.dn, + ac->req->controls, + ac, + map_op_local_callback, + ac->req); + LDB_REQ_SET_LOCATION(local_req); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + return ldb_next_request(ac->module, local_req); +} + +/***************************************************************************** + * RENAME operations +*****************************************************************************/ + +/* Rename a record. */ +int ldb_map_rename(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_request *search_req = NULL; + struct ldb_context *ldb; + struct map_context *ac; + int ret; + + ldb = ldb_module_get_ctx(module); + + /* Do not manipulate our control entries */ + if (ldb_dn_is_special(req->op.rename.olddn)) { + return ldb_next_request(module, req); + } + + /* No mapping requested (perhaps no DN mapping specified). + * Skip to next module */ + if ((!ldb_dn_check_local(module, req->op.rename.olddn)) && + (!ldb_dn_check_local(module, req->op.rename.newdn))) { + return ldb_next_request(module, req); + } + + /* Rename into/out of the mapped partition requested, bail out */ + if (!ldb_dn_check_local(module, req->op.rename.olddn) || + !ldb_dn_check_local(module, req->op.rename.newdn)) { + return LDB_ERR_AFFECTS_MULTIPLE_DSAS; + } + + /* Prepare context and handle */ + ac = map_init_context(module, req); + if (ac == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Prepare the remote operation */ + ret = ldb_build_rename_req(&ac->remote_req, ldb, ac, + ldb_dn_map_local(module, ac, req->op.rename.olddn), + ldb_dn_map_local(module, ac, req->op.rename.newdn), + req->controls, + ac, map_op_remote_callback, + req); + LDB_REQ_SET_LOCATION(ac->remote_req); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* No local db, just run the remote request */ + if (!map_check_local_db(ac->module)) { + /* Do the remote request. */ + return ldb_next_remote_request(ac->module, ac->remote_req); + } + + /* Prepare the search operation */ + ret = map_search_self_req(&search_req, ac, req->op.rename.olddn); + if (ret != LDB_SUCCESS) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_next_request(module, search_req); +} + +/* Rename the local record. */ +static int map_rename_do_local(struct map_context *ac) +{ + struct ldb_request *local_req; + struct ldb_context *ldb; + int ret; + + ldb = ldb_module_get_ctx(ac->module); + + /* No local record, continue remotely */ + if (ac->local_dn == NULL) { + /* Do the remote request. */ + return ldb_next_remote_request(ac->module, ac->remote_req); + } + + /* Prepare the local operation */ + ret = ldb_build_rename_req(&local_req, ldb, ac, + ac->req->op.rename.olddn, + ac->req->op.rename.newdn, + ac->req->controls, + ac, + map_rename_local_callback, + ac->req); + LDB_REQ_SET_LOCATION(local_req); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_next_request(ac->module, local_req); +} + +static int map_rename_local_callback(struct ldb_request *req, + struct ldb_reply *ares) +{ + struct ldb_context *ldb; + struct map_context *ac; + int ret; + + ac = talloc_get_type(req->context, struct map_context); + ldb = ldb_module_get_ctx(ac->module); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + if (ares->type != LDB_REPLY_DONE) { + ldb_asprintf_errstring(ldb, "Invalid LDB reply type %d", ares->type); + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + /* proceed with next step */ + ret = map_rename_do_fixup(ac); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + return LDB_SUCCESS; +} + +/* Update the local 'IS_MAPPED' attribute. */ +static int map_rename_do_fixup(struct map_context *ac) +{ + struct ldb_request *local_req; + + /* Prepare the fixup operation */ + /* TODO: use GUIDs here instead -- or skip it when GUIDs are used. */ + local_req = map_build_fixup_req(ac, + ac->req->op.rename.newdn, + ac->remote_req->op.rename.newdn, + ac, + map_op_local_callback); + if (local_req == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_next_request(ac->module, local_req); +} diff --git a/ldb-2.0.8/ldb_map/ldb_map_outbound.c b/ldb-2.0.8/ldb_map/ldb_map_outbound.c new file mode 100644 index 0000000..c823ba4 --- /dev/null +++ b/ldb-2.0.8/ldb_map/ldb_map_outbound.c @@ -0,0 +1,1417 @@ +/* + ldb database mapping module + + Copyright (C) Jelmer Vernooij 2005 + Copyright (C) Martin Kuehl 2006 + Copyright (C) Andrew Bartlett 2006 + Copyright (C) Simo Sorce 2008 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb_map.h" +#include "ldb_map_private.h" + + +/* Mapping attributes + * ================== */ + +/* Select attributes that stay in the local partition. */ +static const char **map_attrs_select_local(struct ldb_module *module, void *mem_ctx, const char * const *attrs) +{ + const struct ldb_map_context *data = map_get_context(module); + const char **result; + unsigned int i, last; + + if (attrs == NULL) + return NULL; + + last = 0; + result = talloc_array(mem_ctx, const char *, 1); + if (result == NULL) { + goto failed; + } + result[0] = NULL; + + for (i = 0; attrs[i]; i++) { + /* Wildcards and ignored attributes are kept locally */ + if ((ldb_attr_cmp(attrs[i], "*") == 0) || + (!map_attr_check_remote(data, attrs[i]))) { + result = talloc_realloc(mem_ctx, result, const char *, last+2); + if (result == NULL) { + goto failed; + } + + result[last] = talloc_strdup(result, attrs[i]); + result[last+1] = NULL; + last++; + } + } + + return result; + +failed: + talloc_free(result); + map_oom(module); + return NULL; +} + +/* Collect attributes that are mapped into the remote partition. */ +static const char **map_attrs_collect_remote(struct ldb_module *module, void *mem_ctx, + const char * const *attrs) +{ + const struct ldb_map_context *data = map_get_context(module); + const char **result; + const struct ldb_map_attribute *map; + const char *name=NULL; + unsigned int i, j, last; + int ret; + + last = 0; + result = talloc_array(mem_ctx, const char *, 1); + if (result == NULL) { + goto failed; + } + result[0] = NULL; + + for (i = 0; attrs[i]; i++) { + /* Wildcards are kept remotely, too */ + if (ldb_attr_cmp(attrs[i], "*") == 0) { + const char **new_attrs = NULL; + ret = map_attrs_merge(module, mem_ctx, &new_attrs, attrs); + if (ret != LDB_SUCCESS) { + goto failed; + } + ret = map_attrs_merge(module, mem_ctx, &new_attrs, data->wildcard_attributes); + if (ret != LDB_SUCCESS) { + goto failed; + } + + attrs = new_attrs; + break; + } + } + + for (i = 0; attrs[i]; i++) { + /* Wildcards are kept remotely, too */ + if (ldb_attr_cmp(attrs[i], "*") == 0) { + /* Add all 'include in wildcard' attributes */ + name = attrs[i]; + goto named; + } + + /* Add remote names of mapped attrs */ + map = map_attr_find_local(data, attrs[i]); + if (map == NULL) { + continue; + } + + switch (map->type) { + case LDB_MAP_IGNORE: + continue; + + case LDB_MAP_KEEP: + name = attrs[i]; + goto named; + + case LDB_MAP_RENAME: + case LDB_MAP_RENDROP: + case LDB_MAP_CONVERT: + name = map->u.rename.remote_name; + goto named; + + case LDB_MAP_GENERATE: + /* Add all remote names of "generate" attrs */ + for (j = 0; map->u.generate.remote_names[j]; j++) { + result = talloc_realloc(mem_ctx, result, const char *, last+2); + if (result == NULL) { + goto failed; + } + + result[last] = talloc_strdup(result, map->u.generate.remote_names[j]); + result[last+1] = NULL; + last++; + } + continue; + } + + named: /* We found a single remote name, add that */ + result = talloc_realloc(mem_ctx, result, const char *, last+2); + if (result == NULL) { + goto failed; + } + + result[last] = talloc_strdup(result, name); + result[last+1] = NULL; + last++; + } + + return result; + +failed: + talloc_free(result); + map_oom(module); + return NULL; +} + +/* Split attributes that stay in the local partition from those that + * are mapped into the remote partition. */ +static int map_attrs_partition(struct ldb_module *module, void *mem_ctx, const char ***local_attrs, const char ***remote_attrs, const char * const *attrs) +{ + *local_attrs = map_attrs_select_local(module, mem_ctx, attrs); + *remote_attrs = map_attrs_collect_remote(module, mem_ctx, attrs); + + return 0; +} + +/* Mapping message elements + * ======================== */ + +/* Add an element to a message, overwriting any old identically named elements. */ +static int ldb_msg_replace(struct ldb_message *msg, const struct ldb_message_element *el) +{ + struct ldb_message_element *old; + unsigned j; + old = ldb_msg_find_element(msg, el->name); + + /* no local result, add as new element */ + if (old == NULL) { + if (ldb_msg_add_empty(msg, el->name, 0, &old) != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + } + else { + talloc_free(old->values); + } + + old->values = talloc_array(msg->elements, struct ldb_val, el->num_values); + old->num_values = el->num_values; + if (old->values == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + /* copy the values into the element */ + for (j=0;jnum_values;j++) { + old->values[j] = ldb_val_dup(old->values, &el->values[j]); + if (old->values[j].data == NULL && el->values[j].length != 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + } + + return 0; +} + +/* Map a message element back into the local partition. */ +static struct ldb_message_element *ldb_msg_el_map_remote(struct ldb_module *module, + void *mem_ctx, + const struct ldb_map_attribute *map, + const char *attr_name, + const struct ldb_message_element *old) +{ + const struct ldb_map_context *data = map_get_context(module); + const char *local_attr_name = attr_name; + struct ldb_message_element *el; + unsigned int i; + + el = talloc_zero(mem_ctx, struct ldb_message_element); + if (el == NULL) { + map_oom(module); + return NULL; + } + + el->values = talloc_array(el, struct ldb_val, old->num_values); + if (el->values == NULL) { + talloc_free(el); + map_oom(module); + return NULL; + } + + for (i = 0; data->attribute_maps[i].local_name; i++) { + struct ldb_map_attribute *am = &data->attribute_maps[i]; + if (((am->type == LDB_MAP_RENAME || am->type == LDB_MAP_RENDROP) && + !strcmp(am->u.rename.remote_name, attr_name)) + || (am->type == LDB_MAP_CONVERT && + !strcmp(am->u.convert.remote_name, attr_name))) { + + local_attr_name = am->local_name; + break; + } + } + + el->name = talloc_strdup(el, local_attr_name); + if (el->name == NULL) { + talloc_free(el); + map_oom(module); + return NULL; + } + + for (i = 0; i < old->num_values; i++) { + el->values[i] = ldb_val_map_remote(module, el->values, map, &old->values[i]); + /* Conversions might fail, in which case bail */ + if (!el->values[i].data) { + talloc_free(el); + return NULL; + } + el->num_values++; + } + + return el; +} + +/* Merge a remote message element into a local message. */ +static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local, + struct ldb_message *remote, const char *attr_name) +{ + const struct ldb_map_context *data = map_get_context(module); + const struct ldb_map_attribute *map; + struct ldb_message_element *old, *el=NULL; + const char *remote_name = NULL; + struct ldb_context *ldb; + + ldb = ldb_module_get_ctx(module); + + /* We handle wildcards in ldb_msg_el_merge_wildcard */ + if (ldb_attr_cmp(attr_name, "*") == 0) { + return LDB_SUCCESS; + } + + map = map_attr_find_local(data, attr_name); + + /* Unknown attribute in remote message: + * skip, attribute was probably auto-generated */ + if (map == NULL) { + return LDB_SUCCESS; + } + + switch (map->type) { + case LDB_MAP_IGNORE: + break; + case LDB_MAP_CONVERT: + remote_name = map->u.convert.remote_name; + break; + case LDB_MAP_KEEP: + remote_name = attr_name; + break; + case LDB_MAP_RENAME: + case LDB_MAP_RENDROP: + remote_name = map->u.rename.remote_name; + break; + case LDB_MAP_GENERATE: + break; + } + + switch (map->type) { + case LDB_MAP_IGNORE: + return LDB_SUCCESS; + + case LDB_MAP_CONVERT: + if (map->u.convert.convert_remote == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " + "Skipping attribute '%s': " + "'convert_remote' not set", + attr_name); + return LDB_SUCCESS; + } + + FALL_THROUGH; + case LDB_MAP_KEEP: + case LDB_MAP_RENAME: + case LDB_MAP_RENDROP: + old = ldb_msg_find_element(remote, remote_name); + if (old) { + el = ldb_msg_el_map_remote(module, local, map, attr_name, old); + } else { + return LDB_ERR_NO_SUCH_ATTRIBUTE; + } + break; + + case LDB_MAP_GENERATE: + if (map->u.generate.generate_local == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " + "Skipping attribute '%s': " + "'generate_local' not set", + attr_name); + return LDB_SUCCESS; + } + + el = map->u.generate.generate_local(module, local, attr_name, remote); + if (!el) { + /* Generation failure is probably due to lack of source attributes */ + return LDB_ERR_NO_SUCH_ATTRIBUTE; + } + break; + } + + if (el == NULL) { + return LDB_ERR_NO_SUCH_ATTRIBUTE; + } + + return ldb_msg_replace(local, el); +} + +/* Handle wildcard parts of merging a remote message element into a local message. */ +static int ldb_msg_el_merge_wildcard(struct ldb_module *module, struct ldb_message *local, + struct ldb_message *remote) +{ + const struct ldb_map_context *data = map_get_context(module); + const struct ldb_map_attribute *map = map_attr_find_local(data, "*"); + struct ldb_message_element *el=NULL; + unsigned int i; + int ret; + + /* Perhaps we have a mapping for "*" */ + if (map && map->type == LDB_MAP_KEEP) { + /* We copy everything over, and hope that anything with a + more specific rule is overwritten */ + for (i = 0; i < remote->num_elements; i++) { + el = ldb_msg_el_map_remote(module, local, map, remote->elements[i].name, + &remote->elements[i]); + if (el == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_msg_replace(local, el); + if (ret) { + return ret; + } + } + } + + /* Now walk the list of possible mappings, and apply each */ + for (i = 0; data->attribute_maps[i].local_name; i++) { + ret = ldb_msg_el_merge(module, local, remote, + data->attribute_maps[i].local_name); + if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { + continue; + } else if (ret) { + return ret; + } else { + continue; + } + } + + return LDB_SUCCESS; +} + +/* Mapping messages + * ================ */ + +/* Merge two local messages into a single one. */ +static int ldb_msg_merge_local(struct ldb_module *module, struct ldb_message *msg1, struct ldb_message *msg2) +{ + unsigned int i; + int ret; + + for (i = 0; i < msg2->num_elements; i++) { + ret = ldb_msg_replace(msg1, &msg2->elements[i]); + if (ret) { + return ret; + } + } + + return LDB_SUCCESS; +} + +/* Merge a local and a remote message into a single local one. */ +static int ldb_msg_merge_remote(struct map_context *ac, struct ldb_message *local, + struct ldb_message *remote) +{ + unsigned int i; + int ret; + const char * const *attrs = ac->all_attrs; + if (!attrs) { + ret = ldb_msg_el_merge_wildcard(ac->module, local, remote); + if (ret) { + return ret; + } + } + + for (i = 0; attrs && attrs[i]; i++) { + if (ldb_attr_cmp(attrs[i], "*") == 0) { + ret = ldb_msg_el_merge_wildcard(ac->module, local, remote); + if (ret) { + return ret; + } + break; + } + } + + /* Try to map each attribute back; + * Add to local message is possible, + * Overwrite old local attribute if necessary */ + for (i = 0; attrs && attrs[i]; i++) { + ret = ldb_msg_el_merge(ac->module, local, remote, + attrs[i]); + if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { + } else if (ret) { + return ret; + } + } + + return LDB_SUCCESS; +} + +/* Mapping search results + * ====================== */ + +/* Map a search result back into the local partition. */ +static int map_reply_remote(struct map_context *ac, struct ldb_reply *ares) +{ + struct ldb_message *msg; + struct ldb_dn *dn; + int ret; + + /* There is no result message, skip */ + if (ares->type != LDB_REPLY_ENTRY) { + return 0; + } + + /* Create a new result message */ + msg = ldb_msg_new(ares); + if (msg == NULL) { + map_oom(ac->module); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Merge remote message into new message */ + ret = ldb_msg_merge_remote(ac, msg, ares->message); + if (ret) { + talloc_free(msg); + return ret; + } + + /* Create corresponding local DN */ + dn = ldb_dn_map_rebase_remote(ac->module, msg, ares->message->dn); + if (dn == NULL) { + talloc_free(msg); + return LDB_ERR_OPERATIONS_ERROR; + } + msg->dn = dn; + + /* Store new message with new DN as the result */ + talloc_free(ares->message); + ares->message = msg; + + return 0; +} + +/* Mapping parse trees + * =================== */ + +/* Check whether a parse tree can safely be split in two. */ +static bool ldb_parse_tree_check_splittable(const struct ldb_parse_tree *tree) +{ + const struct ldb_parse_tree *subtree = tree; + bool negate = false; + + while (subtree) { + switch (subtree->operation) { + case LDB_OP_NOT: + negate = !negate; + subtree = subtree->u.isnot.child; + continue; + + case LDB_OP_AND: + return !negate; /* if negate: False */ + + case LDB_OP_OR: + return negate; /* if negate: True */ + + default: + return true; /* simple parse tree */ + } + } + + return true; /* no parse tree */ +} + +/* Collect a list of attributes required to match a given parse tree. */ +static int ldb_parse_tree_collect_attrs(struct ldb_module *module, void *mem_ctx, const char ***attrs, const struct ldb_parse_tree *tree) +{ + const char **new_attrs; + unsigned int i; + int ret; + + if (tree == NULL) { + return 0; + } + + switch (tree->operation) { + case LDB_OP_OR: + case LDB_OP_AND: /* attributes stored in list of subtrees */ + for (i = 0; i < tree->u.list.num_elements; i++) { + ret = ldb_parse_tree_collect_attrs(module, mem_ctx, + attrs, tree->u.list.elements[i]); + if (ret) { + return ret; + } + } + return 0; + + case LDB_OP_NOT: /* attributes stored in single subtree */ + return ldb_parse_tree_collect_attrs(module, mem_ctx, attrs, tree->u.isnot.child); + + default: /* single attribute in tree */ + new_attrs = ldb_attr_list_copy_add(mem_ctx, *attrs, tree->u.equality.attr); + talloc_free(*attrs); + *attrs = new_attrs; + return 0; + } +} + +static int map_subtree_select_local(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree); + +/* Select a negated subtree that queries attributes in the local partition */ +static int map_subtree_select_local_not(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) +{ + struct ldb_parse_tree *child; + int ret; + + /* Prepare new tree */ + *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); + if (*new == NULL) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Generate new subtree */ + ret = map_subtree_select_local(module, *new, &child, tree->u.isnot.child); + if (ret) { + talloc_free(*new); + return ret; + } + + /* Prune tree without subtree */ + if (child == NULL) { + talloc_free(*new); + *new = NULL; + return 0; + } + + (*new)->u.isnot.child = child; + + return ret; +} + +/* Select a list of subtrees that query attributes in the local partition */ +static int map_subtree_select_local_list(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) +{ + unsigned int i, j; + int ret=0; + + /* Prepare new tree */ + *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); + if (*new == NULL) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Prepare list of subtrees */ + (*new)->u.list.num_elements = 0; + (*new)->u.list.elements = talloc_array(*new, struct ldb_parse_tree *, tree->u.list.num_elements); + if ((*new)->u.list.elements == NULL) { + map_oom(module); + talloc_free(*new); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Generate new list of subtrees */ + j = 0; + for (i = 0; i < tree->u.list.num_elements; i++) { + struct ldb_parse_tree *child = NULL; + ret = map_subtree_select_local(module, *new, &child, tree->u.list.elements[i]); + if (ret) { + talloc_free(*new); + return ret; + } + + if (child) { + (*new)->u.list.elements[j] = child; + j++; + } + } + + /* Prune tree without subtrees */ + if (j == 0) { + talloc_free(*new); + *new = NULL; + return 0; + } + + /* Fix subtree list size */ + (*new)->u.list.num_elements = j; + (*new)->u.list.elements = talloc_realloc(*new, (*new)->u.list.elements, struct ldb_parse_tree *, (*new)->u.list.num_elements); + + return ret; +} + +/* Select a simple subtree that queries attributes in the local partition */ +static int map_subtree_select_local_simple(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) +{ + /* Prepare new tree */ + *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); + if (*new == NULL) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + return 0; +} + +/* Select subtrees that query attributes in the local partition */ +static int map_subtree_select_local(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) +{ + const struct ldb_map_context *data = map_get_context(module); + + if (tree == NULL) { + return 0; + } + + if (tree->operation == LDB_OP_NOT) { + return map_subtree_select_local_not(module, mem_ctx, new, tree); + } + + if (tree->operation == LDB_OP_AND || tree->operation == LDB_OP_OR) { + return map_subtree_select_local_list(module, mem_ctx, new, tree); + } + + if (map_attr_check_remote(data, tree->u.equality.attr)) { + *new = NULL; + return 0; + } + + return map_subtree_select_local_simple(module, mem_ctx, new, tree); +} + +static int map_subtree_collect_remote(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree); + +/* Collect a negated subtree that queries attributes in the remote partition */ +static int map_subtree_collect_remote_not(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) +{ + struct ldb_parse_tree *child; + int ret; + + /* Prepare new tree */ + *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); + if (*new == NULL) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Generate new subtree */ + ret = map_subtree_collect_remote(module, *new, &child, tree->u.isnot.child); + if (ret) { + talloc_free(*new); + return ret; + } + + /* Prune tree without subtree */ + if (child == NULL) { + talloc_free(*new); + *new = NULL; + return 0; + } + + (*new)->u.isnot.child = child; + + return ret; +} + +/* Collect a list of subtrees that query attributes in the remote partition */ +static int map_subtree_collect_remote_list(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) +{ + unsigned int i, j; + int ret=0; + + /* Prepare new tree */ + *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); + if (*new == NULL) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Prepare list of subtrees */ + (*new)->u.list.num_elements = 0; + (*new)->u.list.elements = talloc_array(*new, struct ldb_parse_tree *, tree->u.list.num_elements); + if ((*new)->u.list.elements == NULL) { + map_oom(module); + talloc_free(*new); + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Generate new list of subtrees */ + j = 0; + for (i = 0; i < tree->u.list.num_elements; i++) { + struct ldb_parse_tree *child; + ret = map_subtree_collect_remote(module, *new, &child, tree->u.list.elements[i]); + if (ret) { + talloc_free(*new); + return ret; + } + + if (child) { + (*new)->u.list.elements[j] = child; + j++; + } + } + + /* Prune tree without subtrees */ + if (j == 0) { + talloc_free(*new); + *new = NULL; + return 0; + } + + /* Fix subtree list size */ + (*new)->u.list.num_elements = j; + (*new)->u.list.elements = talloc_realloc(*new, (*new)->u.list.elements, struct ldb_parse_tree *, (*new)->u.list.num_elements); + + return ret; +} + +/* Collect a simple subtree that queries attributes in the remote partition */ +int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree, const struct ldb_map_attribute *map) +{ + const char *attr; + + /* Prepare new tree */ + *new = talloc(mem_ctx, struct ldb_parse_tree); + if (*new == NULL) { + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; + } + **new = *tree; + + if (map->type == LDB_MAP_KEEP) { + /* Nothing to do here */ + return 0; + } + + /* Store attribute and value in new tree */ + switch (tree->operation) { + case LDB_OP_PRESENT: + attr = map_attr_map_local(*new, map, tree->u.present.attr); + (*new)->u.present.attr = attr; + break; + case LDB_OP_SUBSTRING: + { + attr = map_attr_map_local(*new, map, tree->u.substring.attr); + (*new)->u.substring.attr = attr; + break; + } + case LDB_OP_EQUALITY: + attr = map_attr_map_local(*new, map, tree->u.equality.attr); + (*new)->u.equality.attr = attr; + break; + case LDB_OP_LESS: + case LDB_OP_GREATER: + case LDB_OP_APPROX: + attr = map_attr_map_local(*new, map, tree->u.comparison.attr); + (*new)->u.comparison.attr = attr; + break; + case LDB_OP_EXTENDED: + attr = map_attr_map_local(*new, map, tree->u.extended.attr); + (*new)->u.extended.attr = attr; + break; + default: /* unknown kind of simple subtree */ + talloc_free(*new); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (attr == NULL) { + talloc_free(*new); + *new = NULL; + return 0; + } + + if (map->type == LDB_MAP_RENAME || map->type == LDB_MAP_RENDROP) { + /* Nothing more to do here, the attribute has been renamed */ + return 0; + } + + /* Store attribute and value in new tree */ + switch (tree->operation) { + case LDB_OP_PRESENT: + break; + case LDB_OP_SUBSTRING: + { + int i; + /* Map value */ + (*new)->u.substring.chunks = NULL; + for (i=0; tree->u.substring.chunks && tree->u.substring.chunks[i]; i++) { + (*new)->u.substring.chunks = talloc_realloc(*new, (*new)->u.substring.chunks, struct ldb_val *, i+2); + if (!(*new)->u.substring.chunks) { + talloc_free(*new); + *new = NULL; + return 0; + } + (*new)->u.substring.chunks[i] = talloc(*new, struct ldb_val); + if (!(*new)->u.substring.chunks[i]) { + talloc_free(*new); + *new = NULL; + return 0; + } + *(*new)->u.substring.chunks[i] = ldb_val_map_local(module, *new, map, tree->u.substring.chunks[i]); + (*new)->u.substring.chunks[i+1] = NULL; + } + break; + } + case LDB_OP_EQUALITY: + (*new)->u.equality.value = ldb_val_map_local(module, *new, map, &tree->u.equality.value); + break; + case LDB_OP_LESS: + case LDB_OP_GREATER: + case LDB_OP_APPROX: + (*new)->u.comparison.value = ldb_val_map_local(module, *new, map, &tree->u.comparison.value); + break; + case LDB_OP_EXTENDED: + (*new)->u.extended.value = ldb_val_map_local(module, *new, map, &tree->u.extended.value); + (*new)->u.extended.rule_id = talloc_strdup(*new, tree->u.extended.rule_id); + break; + default: /* unknown kind of simple subtree */ + talloc_free(*new); + return LDB_ERR_OPERATIONS_ERROR; + } + + return 0; +} + +/* Collect subtrees that query attributes in the remote partition */ +static int map_subtree_collect_remote(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) +{ + const struct ldb_map_context *data = map_get_context(module); + const struct ldb_map_attribute *map; + struct ldb_context *ldb; + + ldb = ldb_module_get_ctx(module); + + if (tree == NULL) { + return 0; + } + + if (tree->operation == LDB_OP_NOT) { + return map_subtree_collect_remote_not(module, mem_ctx, new, tree); + } + + if ((tree->operation == LDB_OP_AND) || (tree->operation == LDB_OP_OR)) { + return map_subtree_collect_remote_list(module, mem_ctx, new, tree); + } + + if (!map_attr_check_remote(data, tree->u.equality.attr)) { + *new = NULL; + return 0; + } + + map = map_attr_find_local(data, tree->u.equality.attr); + if (map == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + if (map->convert_operator) { + return map->convert_operator(module, mem_ctx, new, tree); + } + + if (map->type == LDB_MAP_GENERATE) { + ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " + "Skipping attribute '%s': " + "'convert_operator' not set", + tree->u.equality.attr); + *new = NULL; + return 0; + } + + return map_subtree_collect_remote_simple(module, mem_ctx, new, tree, map); +} + +/* Split subtrees that query attributes in the local partition from + * those that query the remote partition. */ +static int ldb_parse_tree_partition(struct ldb_module *module, + void *mem_ctx, + struct ldb_parse_tree **local_tree, + struct ldb_parse_tree **remote_tree, + const struct ldb_parse_tree *tree) +{ + int ret; + + *local_tree = NULL; + *remote_tree = NULL; + + /* No original tree */ + if (tree == NULL) { + return 0; + } + + /* Generate local tree */ + ret = map_subtree_select_local(module, mem_ctx, local_tree, tree); + if (ret) { + return ret; + } + + /* Generate remote tree */ + ret = map_subtree_collect_remote(module, mem_ctx, remote_tree, tree); + if (ret) { + talloc_free(*local_tree); + return ret; + } + + return 0; +} + +/* Collect a list of attributes required either explicitly from a + * given list or implicitly from a given parse tree; split the + * collected list into local and remote parts. */ +static int map_attrs_collect_and_partition(struct ldb_module *module, struct map_context *ac, + const char * const *search_attrs, + const struct ldb_parse_tree *tree) +{ + void *tmp_ctx; + const char **tree_attrs; + const char **remote_attrs; + const char **local_attrs; + int ret; + + /* There is no tree, just partition the searched attributes */ + if (tree == NULL) { + ret = map_attrs_partition(module, ac, + &local_attrs, &remote_attrs, search_attrs); + if (ret == 0) { + ac->local_attrs = local_attrs; + ac->remote_attrs = remote_attrs; + ac->all_attrs = search_attrs; + } + return ret; + } + + /* Create context for temporary memory */ + tmp_ctx = talloc_new(ac); + if (tmp_ctx == NULL) { + goto oom; + } + + /* Prepare list of attributes from tree */ + tree_attrs = talloc_array(tmp_ctx, const char *, 1); + if (tree_attrs == NULL) { + talloc_free(tmp_ctx); + goto oom; + } + tree_attrs[0] = NULL; + + /* Collect attributes from tree */ + ret = ldb_parse_tree_collect_attrs(module, tmp_ctx, &tree_attrs, tree); + if (ret) { + goto done; + } + + /* Merge attributes from search operation */ + ret = map_attrs_merge(module, tmp_ctx, &tree_attrs, search_attrs); + if (ret) { + goto done; + } + + /* Split local from remote attributes */ + ret = map_attrs_partition(module, ac, &local_attrs, + &remote_attrs, tree_attrs); + + if (ret == 0) { + ac->local_attrs = local_attrs; + ac->remote_attrs = remote_attrs; + talloc_steal(ac, tree_attrs); + ac->all_attrs = tree_attrs; + } +done: + /* Free temporary memory */ + talloc_free(tmp_ctx); + return ret; + +oom: + map_oom(module); + return LDB_ERR_OPERATIONS_ERROR; +} + + +/* Outbound requests: search + * ========================= */ + +static int map_remote_search_callback(struct ldb_request *req, + struct ldb_reply *ares); +static int map_local_merge_callback(struct ldb_request *req, + struct ldb_reply *ares); +static int map_search_local(struct map_context *ac); + +static int map_save_entry(struct map_context *ac, struct ldb_reply *ares) +{ + struct map_reply *mr; + + mr = talloc_zero(ac, struct map_reply); + if (mr == NULL) { + map_oom(ac->module); + return LDB_ERR_OPERATIONS_ERROR; + } + mr->remote = talloc_steal(mr, ares); + if (ac->r_current) { + ac->r_current->next = mr; + } else { + /* first entry */ + ac->r_list = mr; + } + ac->r_current = mr; + + return LDB_SUCCESS; +} + +/* Pass a merged search result up the callback chain. */ +int map_return_entry(struct map_context *ac, struct ldb_reply *ares) +{ + struct ldb_message_element *el; + const char * const *attrs; + struct ldb_context *ldb; + unsigned int i; + int ret; + bool matched; + + ldb = ldb_module_get_ctx(ac->module); + + /* Merged result doesn't match original query, skip */ + ret = ldb_match_msg_error(ldb, ares->message, + ac->req->op.search.tree, + ac->req->op.search.base, + ac->req->op.search.scope, + &matched); + if (ret != LDB_SUCCESS) return ret; + if (!matched) { + ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_map: " + "Skipping record '%s': " + "doesn't match original search", + ldb_dn_get_linearized(ares->message->dn)); + return LDB_SUCCESS; + } + + /* Limit result to requested attrs */ + if (ac->req->op.search.attrs && + (! ldb_attr_in_list(ac->req->op.search.attrs, "*"))) { + + attrs = ac->req->op.search.attrs; + i = 0; + + while (i < ares->message->num_elements) { + + el = &ares->message->elements[i]; + if ( ! ldb_attr_in_list(attrs, el->name)) { + ldb_msg_remove_element(ares->message, el); + } else { + i++; + } + } + } + + return ldb_module_send_entry(ac->req, ares->message, ares->controls); +} + +/* Search a record. */ +int ldb_map_search(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_parse_tree *remote_tree; + struct ldb_parse_tree *local_tree; + struct ldb_request *remote_req; + struct ldb_context *ldb; + struct map_context *ac; + int ret; + + const char *wildcard[] = { "*", NULL }; + const char * const *attrs; + + ldb = ldb_module_get_ctx(module); + + /* if we're not yet initialized, go to the next module */ + if (!ldb_module_get_private(module)) + return ldb_next_request(module, req); + + /* Do not manipulate our control entries */ + if (ldb_dn_is_special(req->op.search.base)) { + return ldb_next_request(module, req); + } + + /* No mapping requested, skip to next module */ + if ((req->op.search.base) && (!ldb_dn_check_local(module, req->op.search.base))) { + return ldb_next_request(module, req); + } + + /* TODO: How can we be sure about which partition we are + * targetting when there is no search base? */ + + /* Prepare context and handle */ + ac = map_init_context(module, req); + if (ac == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* It is easier to deal with the two different ways of + * expressing the wildcard in the same codepath */ + attrs = req->op.search.attrs; + if (attrs == NULL) { + attrs = wildcard; + } + + /* Split local from remote attrs */ + ret = map_attrs_collect_and_partition(module, ac, + attrs, req->op.search.tree); + if (ret) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Split local from remote tree */ + ret = ldb_parse_tree_partition(module, ac, + &local_tree, &remote_tree, + req->op.search.tree); + if (ret) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (((local_tree != NULL) && (remote_tree != NULL)) && + (!ldb_parse_tree_check_splittable(req->op.search.tree))) { + /* The query can't safely be split, enumerate the remote partition */ + local_tree = NULL; + remote_tree = NULL; + } + + if (local_tree == NULL) { + /* Construct default local parse tree */ + local_tree = talloc_zero(ac, struct ldb_parse_tree); + if (local_tree == NULL) { + map_oom(ac->module); + return LDB_ERR_OPERATIONS_ERROR; + } + + local_tree->operation = LDB_OP_PRESENT; + local_tree->u.present.attr = talloc_strdup(local_tree, IS_MAPPED); + } + if (remote_tree == NULL) { + /* Construct default remote parse tree */ + remote_tree = ldb_parse_tree(ac, NULL); + if (remote_tree == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + } + + ac->local_tree = local_tree; + + /* Prepare the remote operation */ + ret = ldb_build_search_req_ex(&remote_req, ldb, ac, + req->op.search.base, + req->op.search.scope, + remote_tree, + ac->remote_attrs, + req->controls, + ac, map_remote_search_callback, + req); + LDB_REQ_SET_LOCATION(remote_req); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_next_remote_request(module, remote_req); +} + +/* Now, search the local part of a remote search result. */ +static int map_remote_search_callback(struct ldb_request *req, + struct ldb_reply *ares) +{ + struct map_context *ac; + int ret; + + ac = talloc_get_type(req->context, struct map_context); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + switch (ares->type) { + case LDB_REPLY_REFERRAL: + + /* ignore referrals */ + talloc_free(ares); + return LDB_SUCCESS; + + case LDB_REPLY_ENTRY: + + /* Map result record into a local message */ + ret = map_reply_remote(ac, ares); + if (ret) { + talloc_free(ares); + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + /* if we have no local db, then we can just return the reply to + * the upper layer, otherwise we must save it and process it + * when all replies ahve been gathered */ + if ( ! map_check_local_db(ac->module)) { + ret = map_return_entry(ac, ares); + } else { + ret = map_save_entry(ac,ares); + } + + if (ret != LDB_SUCCESS) { + talloc_free(ares); + return ldb_module_done(ac->req, NULL, NULL, ret); + } + break; + + case LDB_REPLY_DONE: + + if ( ! map_check_local_db(ac->module)) { + return ldb_module_done(ac->req, ares->controls, + ares->response, LDB_SUCCESS); + } + + /* reset the pointer to the start of the list */ + ac->r_current = ac->r_list; + + /* no entry just return */ + if (ac->r_current == NULL) { + ret = ldb_module_done(ac->req, ares->controls, + ares->response, LDB_SUCCESS); + talloc_free(ares); + return ret; + } + + ac->remote_done_ares = talloc_steal(ac, ares); + + ret = map_search_local(ac); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, ret); + } + } + + return LDB_SUCCESS; +} + +static int map_search_local(struct map_context *ac) +{ + struct ldb_request *search_req; + + if (ac->r_current == NULL || ac->r_current->remote == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* Prepare local search request */ + /* TODO: use GUIDs here instead? */ + search_req = map_search_base_req(ac, + ac->r_current->remote->message->dn, + NULL, NULL, + ac, map_local_merge_callback); + if (search_req == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_next_request(ac->module, search_req); +} + +/* Merge the remote and local parts of a search result. */ +int map_local_merge_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct ldb_context *ldb; + struct map_context *ac; + int ret; + + ac = talloc_get_type(req->context, struct map_context); + ldb = ldb_module_get_ctx(ac->module); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + switch (ares->type) { + case LDB_REPLY_ENTRY: + /* We have already found a local record */ + if (ac->r_current->local) { + talloc_free(ares); + ldb_set_errstring(ldb, "ldb_map: Too many results!"); + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + /* Store local result */ + ac->r_current->local = talloc_steal(ac->r_current, ares); + + break; + + case LDB_REPLY_REFERRAL: + /* ignore referrals */ + talloc_free(ares); + break; + + case LDB_REPLY_DONE: + /* We don't need the local 'ares', but we will use the remote one from below */ + talloc_free(ares); + + /* No local record found, map and send remote record */ + if (ac->r_current->local != NULL) { + /* Merge remote into local message */ + ret = ldb_msg_merge_local(ac->module, + ac->r_current->local->message, + ac->r_current->remote->message); + if (ret == LDB_SUCCESS) { + ret = map_return_entry(ac, ac->r_current->local); + } + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + } else { + ret = map_return_entry(ac, ac->r_current->remote); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, + NULL, NULL, ret); + } + } + + if (ac->r_current->next != NULL) { + ac->r_current = ac->r_current->next; + if (ac->r_current->remote->type == LDB_REPLY_ENTRY) { + ret = map_search_local(ac); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, + NULL, NULL, ret); + } + break; + } + } + + /* ok we are done with all search, finally it is time to + * finish operations for this module */ + return ldb_module_done(ac->req, + ac->remote_done_ares->controls, + ac->remote_done_ares->response, + ac->remote_done_ares->error); + } + + return LDB_SUCCESS; +} diff --git a/ldb-2.0.8/ldb_map/ldb_map_private.h b/ldb-2.0.8/ldb_map/ldb_map_private.h new file mode 100644 index 0000000..6e4a9dd --- /dev/null +++ b/ldb-2.0.8/ldb_map/ldb_map_private.h @@ -0,0 +1,96 @@ +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" + +/* A handy macro to report Out of Memory conditions */ +#define map_oom(module) ldb_set_errstring(ldb_module_get_ctx(module), talloc_asprintf(module, "Out of Memory")); + +/* The type of search callback functions */ +typedef int (*ldb_map_callback_t)(struct ldb_request *, struct ldb_reply *); + +/* The special DN from which the local and remote base DNs are fetched */ +#define MAP_DN_NAME "@MAP" +#define MAP_DN_FROM "@FROM" +#define MAP_DN_TO "@TO" + +/* Private data structures + * ======================= */ + +struct map_reply { + struct map_reply *next; + struct ldb_reply *remote; + struct ldb_reply *local; +}; + +/* Context data for mapped requests */ +struct map_context { + + struct ldb_module *module; + struct ldb_request *req; + + struct ldb_dn *local_dn; + const struct ldb_parse_tree *local_tree; + const char * const *local_attrs; + const char * const *remote_attrs; + const char * const *all_attrs; + + struct ldb_message *local_msg; + struct ldb_request *remote_req; + + struct map_reply *r_list; + struct map_reply *r_current; + + /* The response continaing any controls the remote server gave */ + struct ldb_reply *remote_done_ares; +}; + +/* Common operations + * ================= */ + +/* The following definitions come from lib/ldb/modules/ldb_map.c */ +const struct ldb_map_context *map_get_context(struct ldb_module *module); +struct map_context *map_init_context(struct ldb_module *module, + struct ldb_request *req); + +int ldb_next_remote_request(struct ldb_module *module, struct ldb_request *request); + +bool map_check_local_db(struct ldb_module *module); +bool map_attr_check_remote(const struct ldb_map_context *data, const char *attr); +bool ldb_dn_check_local(struct ldb_module *module, struct ldb_dn *dn); + +const struct ldb_map_attribute *map_attr_find_local(const struct ldb_map_context *data, const char *name); +const struct ldb_map_attribute *map_attr_find_remote(const struct ldb_map_context *data, const char *name); + +const char *map_attr_map_local(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr); +const char *map_attr_map_remote(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr); +int map_attrs_merge(struct ldb_module *module, void *mem_ctx, const char ***attrs, const char * const *more_attrs); + +struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val); +struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val); + +struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn); +struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn); +struct ldb_dn *ldb_dn_map_rebase_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn); + +struct ldb_request *map_search_base_req(struct map_context *ac, + struct ldb_dn *dn, + const char * const *attrs, + struct ldb_parse_tree *tree, + void *context, + ldb_map_callback_t callback); +struct ldb_request *map_build_fixup_req(struct map_context *ac, + struct ldb_dn *olddn, + struct ldb_dn *newdn, + void *context, + ldb_map_callback_t callback); +int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx, + struct ldb_parse_tree **new, + const struct ldb_parse_tree *tree, + const struct ldb_map_attribute *map); +int map_return_fatal_error(struct ldb_request *req, + struct ldb_reply *ares); +int map_return_normal_error(struct ldb_request *req, + struct ldb_reply *ares, + int error); + +int map_return_entry(struct map_context *ac, struct ldb_reply *ares); diff --git a/ldb-2.0.8/ldb_mdb/ldb_mdb.c b/ldb-2.0.8/ldb_mdb/ldb_mdb.c new file mode 100644 index 0000000..6c679c2 --- /dev/null +++ b/ldb-2.0.8/ldb_mdb/ldb_mdb.c @@ -0,0 +1,1126 @@ +/* + ldb database library using mdb back end + + Copyright (C) Jakub Hrozek 2014 + Copyright (C) Catalyst.Net Ltd 2017 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "ldb_mdb.h" +#include "../ldb_key_value/ldb_kv.h" +#include "include/dlinklist.h" + +#define MDB_URL_PREFIX "mdb://" +#define MDB_URL_PREFIX_SIZE (sizeof(MDB_URL_PREFIX)-1) + +#define LDB_MDB_MAX_KEY_LENGTH 511 + +#define GIGABYTE (1024*1024*1024) + +int ldb_mdb_err_map(int lmdb_err) +{ + switch (lmdb_err) { + case MDB_SUCCESS: + return LDB_SUCCESS; + case EIO: + return LDB_ERR_OPERATIONS_ERROR; +#ifdef EBADE + case EBADE: +#endif + case MDB_INCOMPATIBLE: + case MDB_CORRUPTED: + case MDB_INVALID: + return LDB_ERR_UNAVAILABLE; + case MDB_BAD_TXN: + case MDB_BAD_VALSIZE: +#ifdef MDB_BAD_DBI + case MDB_BAD_DBI: +#endif + case MDB_PANIC: + case EINVAL: + return LDB_ERR_PROTOCOL_ERROR; + case MDB_MAP_FULL: + case MDB_DBS_FULL: + case MDB_READERS_FULL: + case MDB_TLS_FULL: + case MDB_TXN_FULL: + case EAGAIN: + return LDB_ERR_BUSY; + case MDB_KEYEXIST: + return LDB_ERR_ENTRY_ALREADY_EXISTS; + case MDB_NOTFOUND: + case ENOENT: + return LDB_ERR_NO_SUCH_OBJECT; + case EACCES: + return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; + default: + break; + } + return LDB_ERR_OTHER; +} + +#define ldb_mdb_error(ldb, ecode) lmdb_error_at(ldb, ecode, __FILE__, __LINE__) +static int lmdb_error_at(struct ldb_context *ldb, + int ecode, + const char *file, + int line) +{ + int ldb_err = ldb_mdb_err_map(ecode); + char *reason = mdb_strerror(ecode); + ldb_asprintf_errstring(ldb, + "(%d) - %s at %s:%d", + ecode, + reason, + file, + line); + return ldb_err; +} + +static bool lmdb_transaction_active(struct ldb_kv_private *ldb_kv) +{ + return ldb_kv->lmdb_private->txlist != NULL; +} + +static MDB_txn *lmdb_trans_get_tx(struct lmdb_trans *ltx) +{ + if (ltx == NULL) { + return NULL; + } + + return ltx->tx; +} + +static void trans_push(struct lmdb_private *lmdb, struct lmdb_trans *ltx) +{ + if (lmdb->txlist) { + talloc_steal(lmdb->txlist, ltx); + } + + DLIST_ADD(lmdb->txlist, ltx); +} + +static void trans_finished(struct lmdb_private *lmdb, struct lmdb_trans *ltx) +{ + DLIST_REMOVE(lmdb->txlist, ltx); + talloc_free(ltx); +} + + +static struct lmdb_trans *lmdb_private_trans_head(struct lmdb_private *lmdb) +{ + struct lmdb_trans *ltx; + + ltx = lmdb->txlist; + return ltx; +} + + +static MDB_txn *get_current_txn(struct lmdb_private *lmdb) +{ + MDB_txn *txn = NULL; + + txn = lmdb_trans_get_tx(lmdb_private_trans_head(lmdb)); + if (txn != NULL) { + return txn; + } + if (lmdb->read_txn != NULL) { + return lmdb->read_txn; + } + lmdb->error = MDB_BAD_TXN; + ldb_set_errstring(lmdb->ldb, __location__":No active transaction\n"); + return NULL; +} + +static int lmdb_store(struct ldb_kv_private *ldb_kv, + struct ldb_val key, + struct ldb_val data, + int flags) +{ + struct lmdb_private *lmdb = ldb_kv->lmdb_private; + MDB_val mdb_key; + MDB_val mdb_data; + int mdb_flags; + MDB_txn *txn = NULL; + MDB_dbi dbi = 0; + + if (ldb_kv->read_only) { + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + txn = lmdb_trans_get_tx(lmdb_private_trans_head(lmdb)); + if (txn == NULL) { + ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction"); + lmdb->error = MDB_PANIC; + return ldb_mdb_error(lmdb->ldb, lmdb->error); + } + + lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi); + if (lmdb->error != MDB_SUCCESS) { + return ldb_mdb_error(lmdb->ldb, lmdb->error); + } + + mdb_key.mv_size = key.length; + mdb_key.mv_data = key.data; + + mdb_data.mv_size = data.length; + mdb_data.mv_data = data.data; + + if (flags == TDB_INSERT) { + mdb_flags = MDB_NOOVERWRITE; + } else if ((flags == TDB_MODIFY)) { + /* + * Modifying a record, ensure that it exists. + * This mimics the TDB semantics + */ + MDB_val value; + lmdb->error = mdb_get(txn, dbi, &mdb_key, &value); + if (lmdb->error != MDB_SUCCESS) { + return ldb_mdb_error(lmdb->ldb, lmdb->error); + } + mdb_flags = 0; + } else { + mdb_flags = 0; + } + + lmdb->error = mdb_put(txn, dbi, &mdb_key, &mdb_data, mdb_flags); + if (lmdb->error != MDB_SUCCESS) { + return ldb_mdb_error(lmdb->ldb, lmdb->error); + } + + return ldb_mdb_err_map(lmdb->error); +} + +static int lmdb_delete(struct ldb_kv_private *ldb_kv, struct ldb_val key) +{ + struct lmdb_private *lmdb = ldb_kv->lmdb_private; + MDB_val mdb_key; + MDB_txn *txn = NULL; + MDB_dbi dbi = 0; + + if (ldb_kv->read_only) { + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + txn = lmdb_trans_get_tx(lmdb_private_trans_head(lmdb)); + if (txn == NULL) { + ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction"); + lmdb->error = MDB_PANIC; + return ldb_mdb_error(lmdb->ldb, lmdb->error); + } + + lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi); + if (lmdb->error != MDB_SUCCESS) { + return ldb_mdb_error(lmdb->ldb, lmdb->error); + } + + mdb_key.mv_size = key.length; + mdb_key.mv_data = key.data; + + lmdb->error = mdb_del(txn, dbi, &mdb_key, NULL); + if (lmdb->error != MDB_SUCCESS) { + return ldb_mdb_error(lmdb->ldb, lmdb->error); + } + return ldb_mdb_err_map(lmdb->error); +} + +static int lmdb_traverse_fn(struct ldb_kv_private *ldb_kv, + ldb_kv_traverse_fn fn, + void *ctx) +{ + struct lmdb_private *lmdb = ldb_kv->lmdb_private; + MDB_val mdb_key; + MDB_val mdb_data; + MDB_txn *txn = NULL; + MDB_dbi dbi = 0; + MDB_cursor *cursor = NULL; + int ret; + + txn = get_current_txn(lmdb); + if (txn == NULL) { + ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction"); + lmdb->error = MDB_PANIC; + return ldb_mdb_error(lmdb->ldb, lmdb->error); + } + + lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi); + if (lmdb->error != MDB_SUCCESS) { + return ldb_mdb_error(lmdb->ldb, lmdb->error); + } + + lmdb->error = mdb_cursor_open(txn, dbi, &cursor); + if (lmdb->error != MDB_SUCCESS) { + goto done; + } + + while ((lmdb->error = mdb_cursor_get( + cursor, &mdb_key, + &mdb_data, MDB_NEXT)) == MDB_SUCCESS) { + + struct ldb_val key = { + .length = mdb_key.mv_size, + .data = mdb_key.mv_data, + }; + struct ldb_val data = { + .length = mdb_data.mv_size, + .data = mdb_data.mv_data, + }; + + ret = fn(ldb_kv, key, data, ctx); + if (ret != 0) { + /* + * NOTE: This DOES NOT set lmdb->error! + * + * This means that the caller will get success. + * This matches TDB traverse behaviour, where callbacks + * may terminate the traverse, but do not change the + * return code from success. + * + * Callers SHOULD store their own error codes. + */ + goto done; + } + } + if (lmdb->error == MDB_NOTFOUND) { + lmdb->error = MDB_SUCCESS; + } +done: + if (cursor != NULL) { + mdb_cursor_close(cursor); + } + + if (lmdb->error != MDB_SUCCESS) { + return ldb_mdb_error(lmdb->ldb, lmdb->error); + } + return ldb_mdb_err_map(lmdb->error); +} + +static int lmdb_update_in_iterate(struct ldb_kv_private *ldb_kv, + struct ldb_val key, + struct ldb_val key2, + struct ldb_val data, + void *state) +{ + struct lmdb_private *lmdb = ldb_kv->lmdb_private; + struct ldb_val copy; + int ret = LDB_SUCCESS; + + /* + * Need to take a copy of the data as the delete operation alters the + * data, as it is in private lmdb memory. + */ + copy.length = data.length; + copy.data = talloc_memdup(ldb_kv, data.data, data.length); + if (copy.data == NULL) { + lmdb->error = MDB_PANIC; + return ldb_oom(lmdb->ldb); + } + + lmdb->error = lmdb_delete(ldb_kv, key); + if (lmdb->error != MDB_SUCCESS) { + ldb_debug( + lmdb->ldb, + LDB_DEBUG_ERROR, + "Failed to delete %*.*s " + "for rekey as %*.*s: %s", + (int)key.length, (int)key.length, + (const char *)key.data, + (int)key2.length, (int)key2.length, + (const char *)key.data, + mdb_strerror(lmdb->error)); + ret = ldb_mdb_error(lmdb->ldb, lmdb->error); + goto done; + } + + lmdb->error = lmdb_store(ldb_kv, key2, copy, 0); + if (lmdb->error != MDB_SUCCESS) { + ldb_debug( + lmdb->ldb, + LDB_DEBUG_ERROR, + "Failed to rekey %*.*s as %*.*s: %s", + (int)key.length, (int)key.length, + (const char *)key.data, + (int)key2.length, (int)key2.length, + (const char *)key.data, + mdb_strerror(lmdb->error)); + ret = ldb_mdb_error(lmdb->ldb, lmdb->error); + goto done; + } + +done: + if (copy.data != NULL) { + TALLOC_FREE(copy.data); + copy.length = 0; + } + + /* + * Explicity invalidate the data, as the delete has done this + */ + data.length = 0; + data.data = NULL; + + return ret; +} + +/* Handles only a single record */ +static int lmdb_parse_record(struct ldb_kv_private *ldb_kv, + struct ldb_val key, + int (*parser)(struct ldb_val key, + struct ldb_val data, + void *private_data), + void *ctx) +{ + struct lmdb_private *lmdb = ldb_kv->lmdb_private; + MDB_val mdb_key; + MDB_val mdb_data; + MDB_txn *txn = NULL; + MDB_dbi dbi; + struct ldb_val data; + + txn = get_current_txn(lmdb); + if (txn == NULL) { + ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction active"); + lmdb->error = MDB_PANIC; + return ldb_mdb_error(lmdb->ldb, lmdb->error); + } + + lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi); + if (lmdb->error != MDB_SUCCESS) { + return ldb_mdb_error(lmdb->ldb, lmdb->error); + } + + mdb_key.mv_size = key.length; + mdb_key.mv_data = key.data; + + lmdb->error = mdb_get(txn, dbi, &mdb_key, &mdb_data); + if (lmdb->error != MDB_SUCCESS) { + /* TODO closing a handle should not even be necessary */ + mdb_dbi_close(lmdb->env, dbi); + if (lmdb->error == MDB_NOTFOUND) { + return LDB_ERR_NO_SUCH_OBJECT; + } + return ldb_mdb_error(lmdb->ldb, lmdb->error); + } + data.data = mdb_data.mv_data; + data.length = mdb_data.mv_size; + + /* TODO closing a handle should not even be necessary */ + mdb_dbi_close(lmdb->env, dbi); + + return parser(key, data, ctx); +} + +/* + * Exactly the same as iterate, except we have a start key and an end key + * (which are both included in the results if present). + * + * If start > end, return MDB_PANIC. + */ +static int lmdb_iterate_range(struct ldb_kv_private *ldb_kv, + struct ldb_val start_key, + struct ldb_val end_key, + ldb_kv_traverse_fn fn, + void *ctx) +{ + struct lmdb_private *lmdb = ldb_kv->lmdb_private; + MDB_val mdb_key; + MDB_val mdb_data; + MDB_txn *txn = NULL; + MDB_dbi dbi = 0; + MDB_cursor *cursor = NULL; + int ret; + + MDB_val mdb_s_key; + MDB_val mdb_e_key; + + txn = get_current_txn(lmdb); + if (txn == NULL) { + ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction"); + lmdb->error = MDB_PANIC; + return ldb_mdb_error(lmdb->ldb, lmdb->error); + } + + lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi); + if (lmdb->error != MDB_SUCCESS) { + return ldb_mdb_error(lmdb->ldb, lmdb->error); + } + + mdb_s_key.mv_size = start_key.length; + mdb_s_key.mv_data = start_key.data; + + mdb_e_key.mv_size = end_key.length; + mdb_e_key.mv_data = end_key.data; + + if (mdb_cmp(txn, dbi, &mdb_s_key, &mdb_e_key) > 0) { + lmdb->error = MDB_PANIC; + return ldb_mdb_error(lmdb->ldb, lmdb->error); + } + + lmdb->error = mdb_cursor_open(txn, dbi, &cursor); + if (lmdb->error != MDB_SUCCESS) { + goto done; + } + + lmdb->error = mdb_cursor_get(cursor, &mdb_s_key, &mdb_data, MDB_SET_RANGE); + + if (lmdb->error != MDB_SUCCESS) { + if (lmdb->error == MDB_NOTFOUND) { + lmdb->error = MDB_SUCCESS; + } + goto done; + } else { + struct ldb_val key = { + .length = mdb_s_key.mv_size, + .data = mdb_s_key.mv_data, + }; + struct ldb_val data = { + .length = mdb_data.mv_size, + .data = mdb_data.mv_data, + }; + + if (mdb_cmp(txn, dbi, &mdb_s_key, &mdb_e_key) > 0) { + goto done; + } + + ret = fn(ldb_kv, key, data, ctx); + if (ret != 0) { + /* + * NOTE: This DOES NOT set lmdb->error! + * + * This means that the caller will get success. + * This matches TDB traverse behaviour, where callbacks + * may terminate the traverse, but do not change the + * return code from success. + * + * Callers SHOULD store their own error codes. + */ + goto done; + } + } + + while ((lmdb->error = mdb_cursor_get( + cursor, &mdb_key, + &mdb_data, MDB_NEXT)) == MDB_SUCCESS) { + + struct ldb_val key = { + .length = mdb_key.mv_size, + .data = mdb_key.mv_data, + }; + struct ldb_val data = { + .length = mdb_data.mv_size, + .data = mdb_data.mv_data, + }; + + if (mdb_cmp(txn, dbi, &mdb_key, &mdb_e_key) > 0) { + goto done; + } + + ret = fn(ldb_kv, key, data, ctx); + if (ret != 0) { + /* + * NOTE: This DOES NOT set lmdb->error! + * + * This means that the caller will get success. + * This matches TDB traverse behaviour, where callbacks + * may terminate the traverse, but do not change the + * return code from success. + * + * Callers SHOULD store their own error codes. + */ + goto done; + } + } + if (lmdb->error == MDB_NOTFOUND) { + lmdb->error = MDB_SUCCESS; + } +done: + if (cursor != NULL) { + mdb_cursor_close(cursor); + } + + if (lmdb->error != MDB_SUCCESS) { + return ldb_mdb_error(lmdb->ldb, lmdb->error); + } + return ldb_mdb_err_map(lmdb->error); +} + +static int lmdb_lock_read(struct ldb_module *module) +{ + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + struct lmdb_private *lmdb = ldb_kv->lmdb_private; + pid_t pid = getpid(); + + if (pid != lmdb->pid) { + ldb_asprintf_errstring( + lmdb->ldb, + __location__": Reusing ldb opened by pid %d in " + "process %d\n", + lmdb->pid, + pid); + lmdb->error = MDB_BAD_TXN; + return LDB_ERR_PROTOCOL_ERROR; + } + + lmdb->error = MDB_SUCCESS; + if (lmdb_transaction_active(ldb_kv) == false && + ldb_kv->read_lock_count == 0) { + lmdb->error = mdb_txn_begin(lmdb->env, + NULL, + MDB_RDONLY, + &lmdb->read_txn); + } + if (lmdb->error != MDB_SUCCESS) { + return ldb_mdb_error(lmdb->ldb, lmdb->error); + } + + ldb_kv->read_lock_count++; + return ldb_mdb_err_map(lmdb->error); +} + +static int lmdb_unlock_read(struct ldb_module *module) +{ + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + + if (lmdb_transaction_active(ldb_kv) == false && + ldb_kv->read_lock_count == 1) { + struct lmdb_private *lmdb = ldb_kv->lmdb_private; + mdb_txn_commit(lmdb->read_txn); + lmdb->read_txn = NULL; + ldb_kv->read_lock_count--; + return LDB_SUCCESS; + } + ldb_kv->read_lock_count--; + return LDB_SUCCESS; +} + +static int lmdb_transaction_start(struct ldb_kv_private *ldb_kv) +{ + struct lmdb_private *lmdb = ldb_kv->lmdb_private; + struct lmdb_trans *ltx; + struct lmdb_trans *ltx_head; + MDB_txn *tx_parent; + pid_t pid = getpid(); + + /* Do not take out the transaction lock on a read-only DB */ + if (ldb_kv->read_only) { + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + ltx = talloc_zero(lmdb, struct lmdb_trans); + if (ltx == NULL) { + return ldb_oom(lmdb->ldb); + } + + if (pid != lmdb->pid) { + ldb_asprintf_errstring( + lmdb->ldb, + __location__": Reusing ldb opened by pid %d in " + "process %d\n", + lmdb->pid, + pid); + lmdb->error = MDB_BAD_TXN; + return LDB_ERR_PROTOCOL_ERROR; + } + + ltx_head = lmdb_private_trans_head(lmdb); + + tx_parent = lmdb_trans_get_tx(ltx_head); + + lmdb->error = mdb_txn_begin(lmdb->env, tx_parent, 0, <x->tx); + if (lmdb->error != MDB_SUCCESS) { + return ldb_mdb_error(lmdb->ldb, lmdb->error); + } + + trans_push(lmdb, ltx); + + return ldb_mdb_err_map(lmdb->error); +} + +static int lmdb_transaction_cancel(struct ldb_kv_private *ldb_kv) +{ + struct lmdb_trans *ltx; + struct lmdb_private *lmdb = ldb_kv->lmdb_private; + + ltx = lmdb_private_trans_head(lmdb); + if (ltx == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + mdb_txn_abort(ltx->tx); + trans_finished(lmdb, ltx); + return LDB_SUCCESS; +} + +static int lmdb_transaction_prepare_commit(struct ldb_kv_private *ldb_kv) +{ + /* No need to prepare a commit */ + return LDB_SUCCESS; +} + +static int lmdb_transaction_commit(struct ldb_kv_private *ldb_kv) +{ + struct lmdb_trans *ltx; + struct lmdb_private *lmdb = ldb_kv->lmdb_private; + + ltx = lmdb_private_trans_head(lmdb); + if (ltx == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + lmdb->error = mdb_txn_commit(ltx->tx); + trans_finished(lmdb, ltx); + + return lmdb->error; +} + +static int lmdb_error(struct ldb_kv_private *ldb_kv) +{ + return ldb_mdb_err_map(ldb_kv->lmdb_private->error); +} + +static const char *lmdb_errorstr(struct ldb_kv_private *ldb_kv) +{ + return mdb_strerror(ldb_kv->lmdb_private->error); +} + +static const char *lmdb_name(struct ldb_kv_private *ldb_kv) +{ + return "lmdb"; +} + +static bool lmdb_changed(struct ldb_kv_private *ldb_kv) +{ + /* + * lmdb does no provide a quick way to determine if the database + * has changed. This function always returns true. + * + * Note that tdb uses a sequence number that allows this function + * to be implemented efficiently. + */ + return true; +} + +/* + * Get the number of records in the database. + * + * The mdb_env_stat call returns an accurate count, so we return the actual + * number of records in the database rather than an estimate. + */ +static size_t lmdb_get_size(struct ldb_kv_private *ldb_kv) +{ + + struct MDB_stat stats = {0}; + struct lmdb_private *lmdb = ldb_kv->lmdb_private; + int ret = 0; + + ret = mdb_env_stat(lmdb->env, &stats); + if (ret != 0) { + return 0; + } + return stats.ms_entries; +} + +/* + * Start a sub transaction + * As lmdb supports nested transactions we can start a new transaction + */ +static int lmdb_nested_transaction_start(struct ldb_kv_private *ldb_kv) +{ + int ret = lmdb_transaction_start(ldb_kv); + return ret; +} + +/* + * Commit a sub transaction + * As lmdb supports nested transactions we can commit the nested transaction + */ +static int lmdb_nested_transaction_commit(struct ldb_kv_private *ldb_kv) +{ + int ret = lmdb_transaction_commit(ldb_kv); + return ret; +} + +/* + * Cancel a sub transaction + * As lmdb supports nested transactions we can cancel the nested transaction + */ +static int lmdb_nested_transaction_cancel(struct ldb_kv_private *ldb_kv) +{ + int ret = lmdb_transaction_cancel(ldb_kv); + return ret; +} + +static struct kv_db_ops lmdb_key_value_ops = { + .options = LDB_KV_OPTION_STABLE_READ_LOCK, + + .store = lmdb_store, + .delete = lmdb_delete, + .iterate = lmdb_traverse_fn, + .update_in_iterate = lmdb_update_in_iterate, + .fetch_and_parse = lmdb_parse_record, + .iterate_range = lmdb_iterate_range, + .lock_read = lmdb_lock_read, + .unlock_read = lmdb_unlock_read, + .begin_write = lmdb_transaction_start, + .prepare_write = lmdb_transaction_prepare_commit, + .finish_write = lmdb_transaction_commit, + .abort_write = lmdb_transaction_cancel, + .error = lmdb_error, + .errorstr = lmdb_errorstr, + .name = lmdb_name, + .has_changed = lmdb_changed, + .transaction_active = lmdb_transaction_active, + .get_size = lmdb_get_size, + .begin_nested_write = lmdb_nested_transaction_start, + .finish_nested_write = lmdb_nested_transaction_commit, + .abort_nested_write = lmdb_nested_transaction_cancel, +}; + +static const char *lmdb_get_path(const char *url) +{ + const char *path; + + /* parse the url */ + if (strchr(url, ':')) { + if (strncmp(url, MDB_URL_PREFIX, MDB_URL_PREFIX_SIZE) != 0) { + return NULL; + } + path = url + MDB_URL_PREFIX_SIZE; + } else { + path = url; + } + + return path; +} + +static int lmdb_pvt_destructor(struct lmdb_private *lmdb) +{ + struct lmdb_trans *ltx = NULL; + + /* Check if this is a forked child */ + if (getpid() != lmdb->pid) { + int fd = 0; + /* + * We cannot call mdb_env_close or commit any transactions, + * otherwise they might appear finished in the parent. + * + */ + + if (mdb_env_get_fd(lmdb->env, &fd) == 0) { + close(fd); + } + + /* Remove the pointer, so that no access should occur */ + lmdb->env = NULL; + + return 0; + } + + /* + * Close the read transaction if it's open + */ + if (lmdb->read_txn != NULL) { + mdb_txn_abort(lmdb->read_txn); + } + + if (lmdb->env == NULL) { + return 0; + } + + /* + * Abort any currently active transactions + */ + ltx = lmdb_private_trans_head(lmdb); + while (ltx != NULL) { + mdb_txn_abort(ltx->tx); + trans_finished(lmdb, ltx); + ltx = lmdb_private_trans_head(lmdb); + } + lmdb->env = NULL; + + return 0; +} + +struct mdb_env_wrap { + struct mdb_env_wrap *next, *prev; + dev_t device; + ino_t inode; + MDB_env *env; + pid_t pid; +}; + +static struct mdb_env_wrap *mdb_list; + +/* destroy the last connection to an mdb */ +static int mdb_env_wrap_destructor(struct mdb_env_wrap *w) +{ + mdb_env_close(w->env); + DLIST_REMOVE(mdb_list, w); + return 0; +} + +static int lmdb_open_env(TALLOC_CTX *mem_ctx, + MDB_env **env, + struct ldb_context *ldb, + const char *path, + const size_t env_map_size, + unsigned int flags) +{ + int ret; + unsigned int mdb_flags = MDB_NOSUBDIR|MDB_NOTLS; + /* + * MDB_NOSUBDIR implies there is a separate file called path and a + * separate lockfile called path-lock + */ + + struct mdb_env_wrap *w; + struct stat st; + pid_t pid = getpid(); + int fd = 0; + unsigned v; + + if (stat(path, &st) == 0) { + for (w=mdb_list;w;w=w->next) { + if (st.st_dev == w->device && + st.st_ino == w->inode && + pid == w->pid) { + /* + * We must have only one MDB_env per process + */ + if (!talloc_reference(mem_ctx, w)) { + return ldb_oom(ldb); + } + *env = w->env; + return LDB_SUCCESS; + } + } + } + + w = talloc(mem_ctx, struct mdb_env_wrap); + if (w == NULL) { + return ldb_oom(ldb); + } + + ret = mdb_env_create(env); + if (ret != 0) { + ldb_asprintf_errstring( + ldb, + "Could not create MDB environment %s: %s\n", + path, + mdb_strerror(ret)); + return ldb_mdb_err_map(ret); + } + + if (env_map_size > 0) { + ret = mdb_env_set_mapsize(*env, env_map_size); + if (ret != 0) { + ldb_asprintf_errstring( + ldb, + "Could not set MDB mmap() size to %llu " + "on %s: %s\n", + (unsigned long long)(env_map_size), + path, + mdb_strerror(ret)); + TALLOC_FREE(w); + return ldb_mdb_err_map(ret); + } + } + + mdb_env_set_maxreaders(*env, 100000); + /* + * As we ensure that there is only one MDB_env open per database per + * process. We can not use the MDB_RDONLY flag, as another ldb may be + * opened in read write mode + */ + if (flags & LDB_FLG_NOSYNC) { + mdb_flags |= MDB_NOSYNC; + } + ret = mdb_env_open(*env, path, mdb_flags, 0644); + if (ret != 0) { + ldb_asprintf_errstring(ldb, + "Could not open DB %s: %s\n", + path, mdb_strerror(ret)); + TALLOC_FREE(w); + return ldb_mdb_err_map(ret); + } + + { + MDB_envinfo stat = {0}; + ret = mdb_env_info (*env, &stat); + if (ret != 0) { + ldb_asprintf_errstring( + ldb, + "Could not get MDB environment stats %s: %s\n", + path, + mdb_strerror(ret)); + return ldb_mdb_err_map(ret); + } + } + + ret = mdb_env_get_fd(*env, &fd); + if (ret != 0) { + ldb_asprintf_errstring(ldb, + "Could not obtain DB FD %s: %s\n", + path, mdb_strerror(ret)); + TALLOC_FREE(w); + return ldb_mdb_err_map(ret); + } + + /* Just as for TDB: on exec, don't inherit the fd */ + v = fcntl(fd, F_GETFD, 0); + if (v == -1) { + TALLOC_FREE(w); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = fcntl(fd, F_SETFD, v | FD_CLOEXEC); + if (ret == -1) { + TALLOC_FREE(w); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (fstat(fd, &st) != 0) { + ldb_asprintf_errstring( + ldb, + "Could not stat %s:\n", + path); + TALLOC_FREE(w); + return LDB_ERR_OPERATIONS_ERROR; + } + w->env = *env; + w->device = st.st_dev; + w->inode = st.st_ino; + w->pid = pid; + + talloc_set_destructor(w, mdb_env_wrap_destructor); + + DLIST_ADD(mdb_list, w); + + return LDB_SUCCESS; + +} + +static int lmdb_pvt_open(struct lmdb_private *lmdb, + struct ldb_context *ldb, + const char *path, + const size_t env_map_size, + unsigned int flags) +{ + int ret; + int lmdb_max_key_length; + + if (flags & LDB_FLG_DONT_CREATE_DB) { + struct stat st; + if (stat(path, &st) != 0) { + return LDB_ERR_UNAVAILABLE; + } + } + + ret = lmdb_open_env(lmdb, &lmdb->env, ldb, path, env_map_size, flags); + if (ret != 0) { + return ret; + } + + /* Close when lmdb is released */ + talloc_set_destructor(lmdb, lmdb_pvt_destructor); + + /* Store the original pid during the LMDB open */ + lmdb->pid = getpid(); + + lmdb_max_key_length = mdb_env_get_maxkeysize(lmdb->env); + + /* This will never happen, but if it does make sure to freak out */ + if (lmdb_max_key_length < LDB_MDB_MAX_KEY_LENGTH) { + return ldb_operr(ldb); + } + + return LDB_SUCCESS; +} + +int lmdb_connect(struct ldb_context *ldb, + const char *url, + unsigned int flags, + const char *options[], + struct ldb_module **_module) +{ + const char *path = NULL; + struct lmdb_private *lmdb = NULL; + struct ldb_kv_private *ldb_kv = NULL; + int ret; + size_t env_map_size = 0; + + /* + * We hold locks, so we must use a private event context + * on each returned handle + */ + ldb_set_require_private_event_context(ldb); + + path = lmdb_get_path(url); + if (path == NULL) { + ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid mdb URL '%s'", url); + return LDB_ERR_OPERATIONS_ERROR; + } + + ldb_kv = talloc_zero(ldb, struct ldb_kv_private); + if (!ldb_kv) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + lmdb = talloc_zero(ldb_kv, struct lmdb_private); + if (lmdb == NULL) { + TALLOC_FREE(ldb_kv); + return ldb_oom(ldb); + } + lmdb->ldb = ldb; + ldb_kv->kv_ops = &lmdb_key_value_ops; + + { + const char *size = ldb_options_find( + ldb, ldb->options, "lmdb_env_size"); + if (size != NULL) { + env_map_size = strtoull(size, NULL, 0); + } + } + + ret = lmdb_pvt_open(lmdb, ldb, path, env_map_size, flags); + if (ret != LDB_SUCCESS) { + TALLOC_FREE(ldb_kv); + return ret; + } + + ldb_kv->lmdb_private = lmdb; + if (flags & LDB_FLG_RDONLY) { + ldb_kv->read_only = true; + } + + /* + * This maximum length becomes encoded in the index values so + * must never change even if LMDB starts to allow longer keys. + * The override option is max_key_len_for_self_test, and is + * used for testing only. + */ + ldb_kv->max_key_length = LDB_MDB_MAX_KEY_LENGTH; + + return ldb_kv_init_store( + ldb_kv, "ldb_mdb backend", ldb, options, _module); +} diff --git a/ldb-2.0.8/ldb_mdb/ldb_mdb.h b/ldb-2.0.8/ldb_mdb/ldb_mdb.h new file mode 100644 index 0000000..8f21493 --- /dev/null +++ b/ldb-2.0.8/ldb_mdb/ldb_mdb.h @@ -0,0 +1,60 @@ +/* + ldb database library using mdb back end - transaction operations + + Copyright (C) Jakub Hrozek 2015 + Copyright (C) Catalyst.Net Ltd 2017 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#ifndef _LDB_MDB_H_ +#define _LDB_MDB_H_ + +#include "ldb_private.h" +#include + +struct lmdb_private { + struct ldb_context *ldb; + MDB_env *env; + + struct lmdb_trans *txlist; + + struct ldb_mdb_metadata { + struct ldb_message *attributes; + unsigned seqnum; + } *meta; + int error; + MDB_txn *read_txn; + + pid_t pid; + +}; + +struct lmdb_trans { + struct lmdb_trans *next; + struct lmdb_trans *prev; + + MDB_txn *tx; +}; + +int ldb_mdb_err_map(int lmdb_err); +int lmdb_connect(struct ldb_context *ldb, const char *url, + unsigned int flags, const char *options[], + struct ldb_module **_module); + +#endif /* _LDB_MDB_H_ */ diff --git a/ldb-2.0.8/ldb_mdb/ldb_mdb_init.c b/ldb-2.0.8/ldb_mdb/ldb_mdb_init.c new file mode 100644 index 0000000..339c3f2 --- /dev/null +++ b/ldb-2.0.8/ldb_mdb/ldb_mdb_init.c @@ -0,0 +1,31 @@ +/* + ldb database library using mdb back end + + Copyright (C) Jakub Hrozek 2014 + Copyright (C) Catalyst.Net Ltd 2017 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "ldb_mdb.h" + +int ldb_mdb_init(const char *version) +{ + LDB_MODULE_CHECK_VERSION(version); + return ldb_register_backend("mdb", lmdb_connect, false); +} diff --git a/ldb-2.0.8/ldb_sqlite3/README b/ldb-2.0.8/ldb_sqlite3/README new file mode 100644 index 0000000..6cda0a7 --- /dev/null +++ b/ldb-2.0.8/ldb_sqlite3/README @@ -0,0 +1,7 @@ +trees.ps contains an explanation of the Genealogical Representation of Trees +in Databases which is being used in ldb_sqlite3. Note that we use fgID +representation with 4 bytes per level, so we can represent 6.5E+08 subclasses +of any object class. This should be adequate for our purposes. :-) + +The following document is the primary basis for the schema currently being +used here: http://www.research.ibm.com/journal/sj/392/shi.html diff --git a/ldb-2.0.8/ldb_sqlite3/base160.c b/ldb-2.0.8/ldb_sqlite3/base160.c new file mode 100644 index 0000000..7ad39f7 --- /dev/null +++ b/ldb-2.0.8/ldb_sqlite3/base160.c @@ -0,0 +1,154 @@ +/* + base160 code used by ldb_sqlite3 + + Copyright (C) 2004 Derrell Lipman + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + + +/* + * ldb_sqlite3_base160() + * + * Convert an integer value to a string containing the base 160 representation + * of the integer. We always convert to a string representation that is 4 + * bytes in length, and we always null terminate. + * + * Parameters: + * val -- + * The value to be converted + * + * result -- + * Buffer in which the result is to be placed + * + * Returns: + * nothing + */ +static unsigned char base160tab[161] = +{ + 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , /* 0-9 */ + 58 , 59 , 65 , 66 , 67 , 68 , 69 , 70 , 71 , 72 , /* : ; A-H */ + 73 , 74 , 75 , 76 , 77 , 78 , 79 , 80 , 81 , 82 , /* I-R */ + 83 , 84 , 85 , 86 , 87 , 88 , 89 , 90 , 97 , 98 , /* S-Z , a-b */ + 99 , 100, 101, 102, 103, 104, 105, 106, 107, 108, /* c-l */ + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, /* m-v */ + 119, 120, 121, 122, 160, 161, 162, 163, 164, 165, /* w-z, latin1 */ + 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, /* latin1 */ + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, /* latin1 */ + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, /* latin1 */ + 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, /* latin1 */ + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, /* latin1 */ + 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, /* latin1 */ + 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, /* latin1 */ + 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, /* latin1 */ + 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, /* latin1 */ + '\0' +}; + + +/* + * lsqlite3_base160() + * + * Convert an unsigned long integer into a base160 representation of the + * number. + * + * Parameters: + * val -- + * value to be converted + * + * result -- + * character array, 5 bytes long, into which the base160 representation + * will be placed. The result will be a four-digit representation of the + * number (with leading zeros prepended as necessary), and null + * terminated. + * + * Returns: + * Nothing + */ +void +lsqlite3_base160(unsigned long val, + unsigned char result[5]) +{ + int i; + + for (i = 3; i >= 0; i--) { + + result[i] = base160tab[val % 160]; + val /= 160; + } + + result[4] = '\0'; +} + + +/* + * lsqlite3_base160Next() + * + * Retrieve the next-greater number in the base160 sequence for the terminal + * tree node (the last four digits). Only one tree level (four digits) are + * operated on. + * + * Parameters: + * base160 -- a character array containing either an empty string (in which + * case no operation is performed), or a string of base160 digits + * with a length of a multiple of four digits. + * + * Upon return, the trailing four digits (one tree level) will + * have been incremented by 1. + * + * Returns: + * base160 -- the modified array + */ +char * +lsqlite3_base160Next(char base160[]) +{ + int i; + int len; + unsigned char * pTab; + char * pBase160 = base160; + + /* + * We need a minimum of four digits, and we will always get a multiple of + * four digits. + */ + if ((len = strlen(pBase160)) >= 4) + { + pBase160 += strlen(pBase160) - 1; + + /* We only carry through four digits: one level in the tree */ + for (i = 0; i < 4; i++) { + + /* What base160 value does this digit have? */ + pTab = strchr(base160tab, *pBase160); + + /* Is there a carry? */ + if (pTab < base160tab + sizeof(base160tab) - 1) { + + /* Nope. Just increment this value and we're done. */ + *pBase160 = *++pTab; + break; + } else { + + /* + * There's a carry. This value gets base160tab[0], we + * decrement the buffer pointer to get the next higher-order + * digit, and continue in the loop. + */ + *pBase160-- = base160tab[0]; + } + } + } + + return base160; +} diff --git a/ldb-2.0.8/ldb_sqlite3/ldb_sqlite3.c b/ldb-2.0.8/ldb_sqlite3/ldb_sqlite3.c new file mode 100644 index 0000000..0f5abf8 --- /dev/null +++ b/ldb-2.0.8/ldb_sqlite3/ldb_sqlite3.c @@ -0,0 +1,1958 @@ +/* + ldb database library + + Copyright (C) Derrell Lipman 2005 + Copyright (C) Simo Sorce 2005-2009 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb sqlite3 backend + * + * Description: core files for SQLITE3 backend + * + * Author: Derrell Lipman (based on Andrew Tridgell's LDAP backend) + */ + +#include "ldb_module.h" + +#include + +struct lsqlite3_private { + int trans_count; + char **options; + sqlite3 *sqlite; +}; + +struct lsql_context { + struct ldb_module *module; + struct ldb_request *req; + + /* search stuff */ + long long current_eid; + const char * const * attrs; + struct ldb_reply *ares; + + bool callback_failed; + struct tevent_timer *timeout_event; +}; + +/* + * Macros used throughout + */ + +#ifndef FALSE +# define FALSE (0) +# define TRUE (! FALSE) +#endif + +#define RESULT_ATTR_TABLE "temp_result_attrs" + + +/* for testing, define to nothing, (create non-temporary table) */ +#define TEMPTAB "TEMPORARY" + +/* + * Static variables + */ +sqlite3_stmt * stmtGetEID = NULL; + +static char *lsqlite3_tprintf(TALLOC_CTX *mem_ctx, const char *fmt, ...) +{ + char *str, *ret; + va_list ap; + + va_start(ap, fmt); + str = sqlite3_vmprintf(fmt, ap); + va_end(ap); + + if (str == NULL) return NULL; + + ret = talloc_strdup(mem_ctx, str); + if (ret == NULL) { + sqlite3_free(str); + return NULL; + } + + sqlite3_free(str); + return ret; +} + +static char base160tab[161] = { + 48 ,49 ,50 ,51 ,52 ,53 ,54 ,55 ,56 ,57 , /* 0-9 */ + 58 ,59 ,65 ,66 ,67 ,68 ,69 ,70 ,71 ,72 , /* : ; A-H */ + 73 ,74 ,75 ,76 ,77 ,78 ,79 ,80 ,81 ,82 , /* I-R */ + 83 ,84 ,85 ,86 ,87 ,88 ,89 ,90 ,97 ,98 , /* S-Z , a-b */ + 99 ,100,101,102,103,104,105,106,107,108, /* c-l */ + 109,110,111,112,113,114,115,116,117,118, /* m-v */ + 119,120,121,122,160,161,162,163,164,165, /* w-z, latin1 */ + 166,167,168,169,170,171,172,173,174,175, /* latin1 */ + 176,177,178,179,180,181,182,183,184,185, /* latin1 */ + 186,187,188,189,190,191,192,193,194,195, /* latin1 */ + 196,197,198,199,200,201,202,203,204,205, /* latin1 */ + 206,207,208,209,210,211,212,213,214,215, /* latin1 */ + 216,217,218,219,220,221,222,223,224,225, /* latin1 */ + 226,227,228,229,230,231,232,233,234,235, /* latin1 */ + 236,237,238,239,240,241,242,243,244,245, /* latin1 */ + 246,247,248,249,250,251,252,253,254,255, /* latin1 */ + '\0' +}; + + +/* + * base160() + * + * Convert an unsigned long integer into a base160 representation of the + * number. + * + * Parameters: + * val -- + * value to be converted + * + * result -- + * character array, 5 bytes long, into which the base160 representation + * will be placed. The result will be a four-digit representation of the + * number (with leading zeros prepended as necessary), and null + * terminated. + * + * Returns: + * Nothing + */ +static void +base160_sql(sqlite3_context * hContext, + int argc, + sqlite3_value ** argv) +{ + int i; + long long val; + char result[5]; + + val = sqlite3_value_int64(argv[0]); + + for (i = 3; i >= 0; i--) { + + result[i] = base160tab[val % 160]; + val /= 160; + } + + result[4] = '\0'; + + sqlite3_result_text(hContext, result, -1, SQLITE_TRANSIENT); +} + + +/* + * base160next_sql() + * + * This function enhances sqlite by adding a "base160_next()" function which is + * accessible via queries. + * + * Retrieve the next-greater number in the base160 sequence for the terminal + * tree node (the last four digits). Only one tree level (four digits) is + * operated on. + * + * Input: + * A character string: either an empty string (in which case no operation is + * performed), or a string of base160 digits with a length of a multiple of + * four digits. + * + * Output: + * Upon return, the trailing four digits (one tree level) will have been + * incremented by 1. + */ +static void +base160next_sql(sqlite3_context * hContext, + int argc, + sqlite3_value ** argv) +{ + int i; + int len; + char * pTab; + char * pBase160 = strdup((const char *)sqlite3_value_text(argv[0])); + char * pStart = pBase160; + + /* + * We need a minimum of four digits, and we will always get a multiple + * of four digits. + */ + if (pBase160 != NULL && + (len = strlen(pBase160)) >= 4 && + len % 4 == 0) { + + if (pBase160 == NULL) { + + sqlite3_result_null(hContext); + return; + } + + pBase160 += strlen(pBase160) - 1; + + /* We only carry through four digits: one level in the tree */ + for (i = 0; i < 4; i++) { + + /* What base160 value does this digit have? */ + pTab = strchr(base160tab, *pBase160); + + /* Is there a carry? */ + if (pTab < base160tab + sizeof(base160tab) - 1) { + + /* + * Nope. Just increment this value and we're + * done. + */ + *pBase160 = *++pTab; + break; + } else { + + /* + * There's a carry. This value gets + * base160tab[0], we decrement the buffer + * pointer to get the next higher-order digit, + * and continue in the loop. + */ + *pBase160-- = base160tab[0]; + } + } + + sqlite3_result_text(hContext, + pStart, + strlen(pStart), + free); + } else { + sqlite3_result_value(hContext, argv[0]); + if (pBase160 != NULL) { + free(pBase160); + } + } +} + +static char *parsetree_to_sql(struct ldb_module *module, + void *mem_ctx, + const struct ldb_parse_tree *t) +{ + struct ldb_context *ldb; + const struct ldb_schema_attribute *a; + struct ldb_val value, subval; + char *wild_card_string; + char *child, *tmp; + char *ret = NULL; + char *attr; + unsigned int i; + + ldb = ldb_module_get_ctx(module); + + switch(t->operation) { + case LDB_OP_AND: + + tmp = parsetree_to_sql(module, mem_ctx, t->u.list.elements[0]); + if (tmp == NULL) return NULL; + + for (i = 1; i < t->u.list.num_elements; i++) { + + child = parsetree_to_sql(module, mem_ctx, t->u.list.elements[i]); + if (child == NULL) return NULL; + + tmp = talloc_asprintf_append(tmp, " INTERSECT %s ", child); + if (tmp == NULL) return NULL; + } + + ret = talloc_asprintf(mem_ctx, "SELECT * FROM ( %s )\n", tmp); + + return ret; + + case LDB_OP_OR: + + tmp = parsetree_to_sql(module, mem_ctx, t->u.list.elements[0]); + if (tmp == NULL) return NULL; + + for (i = 1; i < t->u.list.num_elements; i++) { + + child = parsetree_to_sql(module, mem_ctx, t->u.list.elements[i]); + if (child == NULL) return NULL; + + tmp = talloc_asprintf_append(tmp, " UNION %s ", child); + if (tmp == NULL) return NULL; + } + + return talloc_asprintf(mem_ctx, "SELECT * FROM ( %s ) ", tmp); + + case LDB_OP_NOT: + + child = parsetree_to_sql(module, mem_ctx, t->u.isnot.child); + if (child == NULL) return NULL; + + return talloc_asprintf(mem_ctx, + "SELECT eid FROM ldb_entry " + "WHERE eid NOT IN ( %s ) ", child); + + case LDB_OP_EQUALITY: + /* + * For simple searches, we want to retrieve the list of EIDs that + * match the criteria. + */ + attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); + if (attr == NULL) return NULL; + a = ldb_schema_attribute_by_name(ldb, attr); + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.equality.value), &value); + if (value.data == NULL) { + return NULL; + } + + if (strcasecmp(t->u.equality.attr, "dn") == 0) { + /* DN query is a special ldb case */ + const char *cdn = ldb_dn_get_casefold( + ldb_dn_new(mem_ctx, ldb, + (const char *)value.data)); + if (cdn == NULL) { + return NULL; + } + + return lsqlite3_tprintf(mem_ctx, + "SELECT eid FROM ldb_entry " + "WHERE norm_dn = '%q'", cdn); + + } else { + /* A normal query. */ + return lsqlite3_tprintf(mem_ctx, + "SELECT eid FROM ldb_attribute_values " + "WHERE norm_attr_name = '%q' " + "AND norm_attr_value = '%q'", + attr, + value.data); + + } + + case LDB_OP_SUBSTRING: + + wild_card_string = talloc_strdup(mem_ctx, + (t->u.substring.start_with_wildcard)?"*":""); + if (wild_card_string == NULL) return NULL; + + for (i = 0; t->u.substring.chunks[i]; i++) { + wild_card_string = talloc_asprintf_append(wild_card_string, "%s*", + t->u.substring.chunks[i]->data); + if (wild_card_string == NULL) return NULL; + } + + if ( ! t->u.substring.end_with_wildcard ) { + /* remove last wildcard */ + wild_card_string[strlen(wild_card_string) - 1] = '\0'; + } + + attr = ldb_attr_casefold(mem_ctx, t->u.substring.attr); + if (attr == NULL) return NULL; + a = ldb_schema_attribute_by_name(ldb, attr); + + subval.data = (void *)wild_card_string; + subval.length = strlen(wild_card_string) + 1; + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, mem_ctx, &(subval), &value); + if (value.data == NULL) { + return NULL; + } + + return lsqlite3_tprintf(mem_ctx, + "SELECT eid FROM ldb_attribute_values " + "WHERE norm_attr_name = '%q' " + "AND norm_attr_value GLOB '%q'", + attr, + value.data); + + case LDB_OP_GREATER: + attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); + if (attr == NULL) return NULL; + a = ldb_schema_attribute_by_name(ldb, attr); + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.equality.value), &value); + if (value.data == NULL) { + return NULL; + } + + return lsqlite3_tprintf(mem_ctx, + "SELECT eid FROM ldb_attribute_values " + "WHERE norm_attr_name = '%q' " + "AND ldap_compare(norm_attr_value, '>=', '%q', '%q') ", + attr, + value.data, + attr); + + case LDB_OP_LESS: + attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); + if (attr == NULL) return NULL; + a = ldb_schema_attribute_by_name(ldb, attr); + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.equality.value), &value); + if (value.data == NULL) { + return NULL; + } + + return lsqlite3_tprintf(mem_ctx, + "SELECT eid FROM ldb_attribute_values " + "WHERE norm_attr_name = '%q' " + "AND ldap_compare(norm_attr_value, '<=', '%q', '%q') ", + attr, + value.data, + attr); + + case LDB_OP_PRESENT: + if (strcasecmp(t->u.present.attr, "dn") == 0) { + return talloc_strdup(mem_ctx, "SELECT eid FROM ldb_entry"); + } + + attr = ldb_attr_casefold(mem_ctx, t->u.present.attr); + if (attr == NULL) return NULL; + + return lsqlite3_tprintf(mem_ctx, + "SELECT eid FROM ldb_attribute_values " + "WHERE norm_attr_name = '%q' ", + attr); + + case LDB_OP_APPROX: + attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); + if (attr == NULL) return NULL; + a = ldb_schema_attribute_by_name(ldb, attr); + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.equality.value), &value); + if (value.data == NULL) { + return NULL; + } + + return lsqlite3_tprintf(mem_ctx, + "SELECT eid FROM ldb_attribute_values " + "WHERE norm_attr_name = '%q' " + "AND ldap_compare(norm_attr_value, '~%', 'q', '%q') ", + attr, + value.data, + attr); + + case LDB_OP_EXTENDED: +#warning "work out how to handle bitops" + return NULL; + + default: + break; + }; + + /* should never occur */ + abort(); + return NULL; +} + +/* + * query_int() + * + * This function is used for the common case of queries that return a single + * integer value. + * + * NOTE: If more than one value is returned by the query, all but the first + * one will be ignored. + */ +static int +query_int(const struct lsqlite3_private * lsqlite3, + long long * pRet, + const char * pSql, + ...) +{ + int ret; + int bLoop; + char * p; + sqlite3_stmt * pStmt; + va_list args; + + /* Begin access to variable argument list */ + va_start(args, pSql); + + /* Format the query */ + if ((p = sqlite3_vmprintf(pSql, args)) == NULL) { + va_end(args); + return SQLITE_NOMEM; + } + + /* + * Prepare and execute the SQL statement. Loop allows retrying on + * certain errors, e.g. SQLITE_SCHEMA occurs if the schema changes, + * requiring retrying the operation. + */ + for (bLoop = TRUE; bLoop; ) { + + /* Compile the SQL statement into sqlite virtual machine */ + if ((ret = sqlite3_prepare(lsqlite3->sqlite, + p, + -1, + &pStmt, + NULL)) == SQLITE_SCHEMA) { + if (stmtGetEID != NULL) { + sqlite3_finalize(stmtGetEID); + stmtGetEID = NULL; + } + continue; + } else if (ret != SQLITE_OK) { + break; + } + + /* One row expected */ + if ((ret = sqlite3_step(pStmt)) == SQLITE_SCHEMA) { + if (stmtGetEID != NULL) { + sqlite3_finalize(stmtGetEID); + stmtGetEID = NULL; + } + (void) sqlite3_finalize(pStmt); + continue; + } else if (ret != SQLITE_ROW) { + (void) sqlite3_finalize(pStmt); + break; + } + + /* Get the value to be returned */ + *pRet = sqlite3_column_int64(pStmt, 0); + + /* Free the virtual machine */ + if ((ret = sqlite3_finalize(pStmt)) == SQLITE_SCHEMA) { + if (stmtGetEID != NULL) { + sqlite3_finalize(stmtGetEID); + stmtGetEID = NULL; + } + continue; + } else if (ret != SQLITE_OK) { + (void) sqlite3_finalize(pStmt); + break; + } + + /* + * Normal condition is only one time through loop. Loop is + * rerun in error conditions, via "continue", above. + */ + bLoop = FALSE; + } + + /* All done with variable argument list */ + va_end(args); + + + /* Free the memory we allocated for our query string */ + sqlite3_free(p); + + return ret; +} + +/* + * This is a bad hack to support ldap style comparisons within sqlite. + * val is the attribute in the row currently under test + * func is the desired test "<=" ">=" "~" ":" + * cmp is the value to compare against (eg: "test") + * attr is the attribute name the value of which we want to test + */ + +static void lsqlite3_compare(sqlite3_context *ctx, int argc, + sqlite3_value **argv) +{ + struct ldb_context *ldb = (struct ldb_context *)sqlite3_user_data(ctx); + const char *val = (const char *)sqlite3_value_text(argv[0]); + const char *func = (const char *)sqlite3_value_text(argv[1]); + const char *cmp = (const char *)sqlite3_value_text(argv[2]); + const char *attr = (const char *)sqlite3_value_text(argv[3]); + const struct ldb_schema_attribute *a; + struct ldb_val valX; + struct ldb_val valY; + int ret; + + switch (func[0]) { + /* greater */ + case '>': /* >= */ + a = ldb_schema_attribute_by_name(ldb, attr); + valX.data = (uint8_t *)cmp; + valX.length = strlen(cmp); + valY.data = (uint8_t *)val; + valY.length = strlen(val); + ret = a->syntax->comparison_fn(ldb, ldb, &valY, &valX); + if (ret >= 0) + sqlite3_result_int(ctx, 1); + else + sqlite3_result_int(ctx, 0); + return; + + /* lesser */ + case '<': /* <= */ + a = ldb_schema_attribute_by_name(ldb, attr); + valX.data = (uint8_t *)cmp; + valX.length = strlen(cmp); + valY.data = (uint8_t *)val; + valY.length = strlen(val); + ret = a->syntax->comparison_fn(ldb, ldb, &valY, &valX); + if (ret <= 0) + sqlite3_result_int(ctx, 1); + else + sqlite3_result_int(ctx, 0); + return; + + /* approx */ + case '~': + /* TODO */ + sqlite3_result_int(ctx, 0); + return; + + /* bitops */ + case ':': + /* TODO */ + sqlite3_result_int(ctx, 0); + return; + + default: + break; + } + + sqlite3_result_error(ctx, "Value must start with a special operation char (<>~:)!", -1); + return; +} + + +/* rename a record */ +static int lsqlite3_safe_rollback(sqlite3 *sqlite) +{ + char *errmsg; + int ret; + + /* execute */ + ret = sqlite3_exec(sqlite, "ROLLBACK;", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3_safe_rollback: Error: %s\n", errmsg); + free(errmsg); + } + return -1; + } + + return 0; +} + +/* return an eid as result */ +static int lsqlite3_eid_callback(void *result, int col_num, char **cols, char **names) +{ + long long *eid = (long long *)result; + + if (col_num != 1) return SQLITE_ABORT; + if (strcasecmp(names[0], "eid") != 0) return SQLITE_ABORT; + + *eid = atoll(cols[0]); + return SQLITE_OK; +} + +/* + * add a single set of ldap message values to a ldb_message + */ +static int lsqlite3_search_callback(void *result, int col_num, char **cols, char **names) +{ + struct ldb_context *ldb; + struct lsql_context *ac; + struct ldb_message *msg; + long long eid; + unsigned int i; + int ret; + + ac = talloc_get_type(result, struct lsql_context); + ldb = ldb_module_get_ctx(ac->module); + + /* eid, dn, attr_name, attr_value */ + if (col_num != 4) return SQLITE_ABORT; + + eid = atoll(cols[0]); + + if (ac->ares) { + msg = ac->ares->message; + } + + if (eid != ac->current_eid) { /* here begin a new entry */ + + /* call the async callback for the last entry + * except the first time */ + if (ac->current_eid != 0) { + ret = ldb_msg_normalize(ldb, ac->req, msg, &msg); + if (ret != LDB_SUCCESS) { + return SQLITE_ABORT; + } + + ret = ldb_module_send_entry(ac->req, msg, NULL); + if (ret != LDB_SUCCESS) { + ac->callback_failed = true; + /* free msg object */ + TALLOC_FREE(msg); + return SQLITE_ABORT; + } + + /* free msg object */ + TALLOC_FREE(msg); + } + + /* start over */ + ac->ares = talloc_zero(ac, struct ldb_reply); + if (!ac->ares) return SQLITE_ABORT; + + msg = ldb_msg_new(ac->ares); + if (!msg) return SQLITE_ABORT; + + ac->ares->type = LDB_REPLY_ENTRY; + ac->current_eid = eid; + } + + if (msg->dn == NULL) { + msg->dn = ldb_dn_new(msg, ldb, cols[1]); + if (msg->dn == NULL) + return SQLITE_ABORT; + } + + if (ac->attrs) { + int found = 0; + for (i = 0; ac->attrs[i]; i++) { + if (strcasecmp(cols[2], ac->attrs[i]) == 0) { + found = 1; + break; + } + } + if (!found) goto done; + } + + if (ldb_msg_add_string(msg, cols[2], cols[3]) != 0) { + return SQLITE_ABORT; + } + +done: + ac->ares->message = msg; + return SQLITE_OK; +} + + +/* + * lsqlite3_get_eid() + * lsqlite3_get_eid_ndn() + * + * These functions are used for the very common case of retrieving an EID value + * given a (normalized) DN. + */ + +static long long lsqlite3_get_eid_ndn(sqlite3 *sqlite, void *mem_ctx, const char *norm_dn) +{ + char *errmsg; + char *query; + long long eid = -1; + long long ret; + + /* get object eid */ + query = lsqlite3_tprintf(mem_ctx, "SELECT eid " + "FROM ldb_entry " + "WHERE norm_dn = '%q';", norm_dn); + if (query == NULL) return -1; + + ret = sqlite3_exec(sqlite, query, lsqlite3_eid_callback, &eid, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3_get_eid: Fatal Error: %s\n", errmsg); + free(errmsg); + } + return -1; + } + + return eid; +} + +static long long lsqlite3_get_eid(struct lsqlite3_private *lsqlite3, + struct ldb_dn *dn) +{ + TALLOC_CTX *local_ctx; + long long eid = -1; + char *cdn; + + /* ignore ltdb specials */ + if (ldb_dn_is_special(dn)) { + return -1; + } + + /* create a local ctx */ + local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_get_eid local context"); + if (local_ctx == NULL) { + return -1; + } + + cdn = ldb_dn_alloc_casefold(local_ctx, dn); + if (!cdn) goto done; + + eid = lsqlite3_get_eid_ndn(lsqlite3->sqlite, local_ctx, cdn); + +done: + talloc_free(local_ctx); + return eid; +} + +/* + * Interface functions referenced by lsqlite3_ops + */ + +/* search for matching records, by tree */ +int lsql_search(struct lsql_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + struct lsqlite3_private *lsqlite3; + struct ldb_context *ldb; + char *norm_basedn; + char *sqlfilter; + char *errmsg; + char *query = NULL; + int ret; + + ldb = ldb_module_get_ctx(module); + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + if ((( ! ldb_dn_is_valid(req->op.search.base)) || + ldb_dn_is_null(req->op.search.base)) && + (req->op.search.scope == LDB_SCOPE_BASE || + req->op.search.scope == LDB_SCOPE_ONELEVEL)) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (req->op.search.base) { + norm_basedn = ldb_dn_alloc_casefold(ctx, req->op.search.base); + if (norm_basedn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + } else norm_basedn = talloc_strdup(ctx, ""); + + /* Convert filter into a series of SQL conditions (constraints) */ + sqlfilter = parsetree_to_sql(module, ctx, req->op.search.tree); + + switch(req->op.search.scope) { + case LDB_SCOPE_DEFAULT: + case LDB_SCOPE_SUBTREE: + if (*norm_basedn != '\0') { + query = lsqlite3_tprintf(ctx, + "SELECT entry.eid,\n" + " entry.dn,\n" + " av.attr_name,\n" + " av.attr_value\n" + " FROM ldb_entry AS entry\n" + + " LEFT OUTER JOIN ldb_attribute_values AS av\n" + " ON av.eid = entry.eid\n" + + " WHERE entry.eid IN\n" + " (SELECT DISTINCT ldb_entry.eid\n" + " FROM ldb_entry\n" + " WHERE (ldb_entry.norm_dn GLOB('*,%q')\n" + " OR ldb_entry.norm_dn = '%q')\n" + " AND ldb_entry.eid IN\n" + " (%s)\n" + " )\n" + + " ORDER BY entry.eid ASC;", + norm_basedn, + norm_basedn, + sqlfilter); + } else { + query = lsqlite3_tprintf(ctx, + "SELECT entry.eid,\n" + " entry.dn,\n" + " av.attr_name,\n" + " av.attr_value\n" + " FROM ldb_entry AS entry\n" + + " LEFT OUTER JOIN ldb_attribute_values AS av\n" + " ON av.eid = entry.eid\n" + + " WHERE entry.eid IN\n" + " (SELECT DISTINCT ldb_entry.eid\n" + " FROM ldb_entry\n" + " WHERE ldb_entry.eid IN\n" + " (%s)\n" + " )\n" + + " ORDER BY entry.eid ASC;", + sqlfilter); + } + + break; + + case LDB_SCOPE_BASE: + query = lsqlite3_tprintf(ctx, + "SELECT entry.eid,\n" + " entry.dn,\n" + " av.attr_name,\n" + " av.attr_value\n" + " FROM ldb_entry AS entry\n" + + " LEFT OUTER JOIN ldb_attribute_values AS av\n" + " ON av.eid = entry.eid\n" + + " WHERE entry.eid IN\n" + " (SELECT DISTINCT ldb_entry.eid\n" + " FROM ldb_entry\n" + " WHERE ldb_entry.norm_dn = '%q'\n" + " AND ldb_entry.eid IN\n" + " (%s)\n" + " )\n" + + " ORDER BY entry.eid ASC;", + norm_basedn, + sqlfilter); + break; + + case LDB_SCOPE_ONELEVEL: + query = lsqlite3_tprintf(ctx, + "SELECT entry.eid,\n" + " entry.dn,\n" + " av.attr_name,\n" + " av.attr_value\n" + " FROM ldb_entry AS entry\n" + + " LEFT OUTER JOIN ldb_attribute_values AS av\n" + " ON av.eid = entry.eid\n" + + " WHERE entry.eid IN\n" + " (SELECT DISTINCT ldb_entry.eid\n" + " FROM ldb_entry\n" + " WHERE norm_dn GLOB('*,%q')\n" + " AND NOT norm_dn GLOB('*,*,%q')\n" + " AND ldb_entry.eid IN\n(%s)\n" + " )\n" + + " ORDER BY entry.eid ASC;", + norm_basedn, + norm_basedn, + sqlfilter); + break; + } + + if (query == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* * / + printf ("%s\n", query); + / * */ + + ctx->current_eid = 0; + ctx->attrs = req->op.search.attrs; + ctx->ares = NULL; + + ldb_request_set_state(req, LDB_ASYNC_PENDING); + + ret = sqlite3_exec(lsqlite3->sqlite, query, lsqlite3_search_callback, ctx, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + + /* complete the last message if any */ + if (ctx->ares) { + ret = ldb_msg_normalize(ldb, ctx->ares, + ctx->ares->message, + &ctx->ares->message); + if (ret != LDB_SUCCESS) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_module_send_entry(req, ctx->ares->message, NULL); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + + return LDB_SUCCESS; +} + +/* add a record */ +static int lsql_add(struct lsql_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + struct lsqlite3_private *lsqlite3; + struct ldb_context *ldb; + struct ldb_message *msg = req->op.add.message; + long long eid; + char *dn, *ndn; + char *errmsg; + char *query; + unsigned int i; + int ret; + + ldb = ldb_module_get_ctx(module); + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + /* See if this is an ltdb special */ + if (ldb_dn_is_special(msg->dn)) { +/* + struct ldb_dn *c; + c = ldb_dn_new(local_ctx, ldb, "@INDEXLIST"); + if (ldb_dn_compare(ldb, msg->dn, c) == 0) { +#warning "should we handle indexes somehow ?" + ret = LDB_ERR_UNWILLING_TO_PERFORM; + goto done; + } +*/ + /* Others return an error */ + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + /* create linearized and normalized dns */ + dn = ldb_dn_alloc_linearized(ctx, msg->dn); + ndn = ldb_dn_alloc_casefold(ctx, msg->dn); + if (dn == NULL || ndn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + query = lsqlite3_tprintf(ctx, + /* Add new entry */ + "INSERT OR ABORT INTO ldb_entry " + "('dn', 'norm_dn') " + "VALUES ('%q', '%q');", + dn, ndn); + if (query == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + + eid = lsqlite3_get_eid_ndn(lsqlite3->sqlite, ctx, ndn); + if (eid == -1) { + return LDB_ERR_OPERATIONS_ERROR; + } + + for (i = 0; i < msg->num_elements; i++) { + const struct ldb_message_element *el = &msg->elements[i]; + const struct ldb_schema_attribute *a; + char *attr; + unsigned int j; + + /* Get a case-folded copy of the attribute name */ + attr = ldb_attr_casefold(ctx, el->name); + if (attr == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + a = ldb_schema_attribute_by_name(ldb, el->name); + + if (el->num_value == 0) { + ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illegal)", + el->name, ldb_dn_get_linearized(msg->dn)); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + /* For each value of the specified attribute name... */ + for (j = 0; j < el->num_values; j++) { + struct ldb_val value; + char *insert; + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, ctx, &(el->values[j]), &value); + if (value.data == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + insert = lsqlite3_tprintf(ctx, + "INSERT OR ROLLBACK INTO ldb_attribute_values " + "('eid', 'attr_name', 'norm_attr_name'," + " 'attr_value', 'norm_attr_value') " + "VALUES ('%lld', '%q', '%q', '%q', '%q');", + eid, el->name, attr, + el->values[j].data, value.data); + if (insert == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = sqlite3_exec(lsqlite3->sqlite, insert, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + } + } + + return LDB_SUCCESS; +} + +/* modify a record */ +static int lsql_modify(struct lsql_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + struct lsqlite3_private *lsqlite3; + struct ldb_context *ldb; + struct ldb_message *msg = req->op.mod.message; + long long eid; + char *errmsg; + unsigned int i; + int ret; + + ldb = ldb_module_get_ctx(module); + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + /* See if this is an ltdb special */ + if (ldb_dn_is_special(msg->dn)) { + /* Others return an error */ + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + eid = lsqlite3_get_eid(lsqlite3, msg->dn); + if (eid == -1) { + return LDB_ERR_OPERATIONS_ERROR; + } + + for (i = 0; i < msg->num_elements; i++) { + const struct ldb_message_element *el = &msg->elements[i]; + const struct ldb_schema_attribute *a; + unsigned int flags = el->flags & LDB_FLAG_MOD_MASK; + char *attr; + char *mod; + unsigned int j; + + /* Get a case-folded copy of the attribute name */ + attr = ldb_attr_casefold(ctx, el->name); + if (attr == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + a = ldb_schema_attribute_by_name(ldb, el->name); + + switch (flags) { + + case LDB_FLAG_MOD_REPLACE: + struct ldb_val *duplicate = NULL; + + ret = ldb_msg_find_duplicate_val(ldb, el, el, + &duplicate, 0); + if (ret != LDB_SUCCESS) { + return ret; + } + if (duplicate != NULL) { + ldb_asprintf_errstring( + ldb, + "attribute '%s': value '%.*s' " + "on '%s' provided more than " + "once in REPLACE", + el->name, + (int)duplicate->length, + duplicate->data, + ldb_dn_get_linearized(msg2->dn)); + return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; + } + + /* remove all attributes before adding the replacements */ + mod = lsqlite3_tprintf(ctx, + "DELETE FROM ldb_attribute_values " + "WHERE eid = '%lld' " + "AND norm_attr_name = '%q';", + eid, attr); + if (mod == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + + /* MISSING break is INTENTIONAL */ + + case LDB_FLAG_MOD_ADD: + + if (el->num_values == 0) { + ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illigal)", + el->name, ldb_dn_get_linearized(msg->dn)); + return LDB_ERR_CONSTRAINT_VIOLATION; + } + + /* For each value of the specified attribute name... */ + for (j = 0; j < el->num_values; j++) { + struct ldb_val value; + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, ctx, &(el->values[j]), &value); + if (value.data == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + mod = lsqlite3_tprintf(ctx, + "INSERT OR ROLLBACK INTO ldb_attribute_values " + "('eid', 'attr_name', 'norm_attr_name'," + " 'attr_value', 'norm_attr_value') " + "VALUES ('%lld', '%q', '%q', '%q', '%q');", + eid, el->name, attr, + el->values[j].data, value.data); + + if (mod == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + } + + break; + + case LDB_FLAG_MOD_DELETE: +#warning "We should throw an error if the attribute we are trying to delete does not exist!" + if (el->num_values == 0) { + mod = lsqlite3_tprintf(ctx, + "DELETE FROM ldb_attribute_values " + "WHERE eid = '%lld' " + "AND norm_attr_name = '%q';", + eid, attr); + if (mod == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + } + + /* For each value of the specified attribute name... */ + for (j = 0; j < el->num_values; j++) { + struct ldb_val value; + + /* Get a canonicalised copy of the data */ + a->syntax->canonicalise_fn(ldb, ctx, &(el->values[j]), &value); + if (value.data == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + mod = lsqlite3_tprintf(ctx, + "DELETE FROM ldb_attribute_values " + "WHERE eid = '%lld' " + "AND norm_attr_name = '%q' " + "AND norm_attr_value = '%q';", + eid, attr, value.data); + + if (mod == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + } + + break; + } + } + + return LDB_SUCCESS; +} + +/* delete a record */ +static int lsql_delete(struct lsql_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + struct lsqlite3_private *lsqlite3; + struct ldb_context *ldb; + long long eid; + char *errmsg; + char *query; + int ret; + + ldb = ldb_module_get_ctx(module); + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + eid = lsqlite3_get_eid(lsqlite3, req->op.del.dn); + if (eid == -1) { + return LDB_ERR_OPERATIONS_ERROR; + } + + query = lsqlite3_tprintf(ctx, + /* Delete entry */ + "DELETE FROM ldb_entry WHERE eid = %lld; " + /* Delete attributes */ + "DELETE FROM ldb_attribute_values WHERE eid = %lld; ", + eid, eid); + if (query == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + + return LDB_SUCCESS; +} + +/* rename a record */ +static int lsql_rename(struct lsql_context *ctx) +{ + struct ldb_module *module = ctx->module; + struct ldb_request *req = ctx->req; + struct lsqlite3_private *lsqlite3; + struct ldb_context *ldb; + char *new_dn, *new_cdn, *old_cdn; + char *errmsg; + char *query; + int ret; + + ldb = ldb_module_get_ctx(module); + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + /* create linearized and normalized dns */ + old_cdn = ldb_dn_alloc_casefold(ctx, req->op.rename.olddn); + new_cdn = ldb_dn_alloc_casefold(ctx, req->op.rename.newdn); + new_dn = ldb_dn_alloc_linearized(ctx, req->op.rename.newdn); + if (old_cdn == NULL || new_cdn == NULL || new_dn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* build the SQL query */ + query = lsqlite3_tprintf(ctx, + "UPDATE ldb_entry SET dn = '%q', norm_dn = '%q' " + "WHERE norm_dn = '%q';", + new_dn, new_cdn, old_cdn); + if (query == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* execute */ + ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + ldb_set_errstring(ldb, errmsg); + free(errmsg); + } + return LDB_ERR_OPERATIONS_ERROR; + } + + return LDB_SUCCESS; +} + +static int lsql_start_trans(struct ldb_module * module) +{ + int ret; + char *errmsg; + struct lsqlite3_private *lsqlite3; + + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + if (lsqlite3->trans_count == 0) { + ret = sqlite3_exec(lsqlite3->sqlite, "BEGIN IMMEDIATE;", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3_start_trans: error: %s\n", errmsg); + free(errmsg); + } + return -1; + } + }; + + lsqlite3->trans_count++; + + return 0; +} + +static int lsql_end_trans(struct ldb_module *module) +{ + int ret; + char *errmsg; + struct lsqlite3_private *lsqlite3; + + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + if (lsqlite3->trans_count > 0) { + lsqlite3->trans_count--; + } else return -1; + + if (lsqlite3->trans_count == 0) { + ret = sqlite3_exec(lsqlite3->sqlite, "COMMIT;", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3_end_trans: error: %s\n", errmsg); + free(errmsg); + } + return -1; + } + } + + return 0; +} + +static int lsql_del_trans(struct ldb_module *module) +{ + struct lsqlite3_private *lsqlite3; + + lsqlite3 = talloc_get_type(ldb_module_get_private(module), + struct lsqlite3_private); + + if (lsqlite3->trans_count > 0) { + lsqlite3->trans_count--; + } else return -1; + + if (lsqlite3->trans_count == 0) { + return lsqlite3_safe_rollback(lsqlite3->sqlite); + } + + return -1; +} + +static int destructor(struct lsqlite3_private *lsqlite3) +{ + if (lsqlite3->sqlite) { + sqlite3_close(lsqlite3->sqlite); + } + return 0; +} + +static void lsql_request_done(struct lsql_context *ctx, int error) +{ + struct ldb_context *ldb; + struct ldb_request *req; + struct ldb_reply *ares; + + ldb = ldb_module_get_ctx(ctx->module); + req = ctx->req; + + /* if we already returned an error just return */ + if (ldb_request_get_status(req) != LDB_SUCCESS) { + return; + } + + ares = talloc_zero(req, struct ldb_reply); + if (!ares) { + ldb_oom(ldb); + req->callback(req, NULL); + return; + } + ares->type = LDB_REPLY_DONE; + ares->error = error; + + req->callback(req, ares); +} + +static void lsql_timeout(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval t, + void *private_data) +{ + struct lsql_context *ctx; + ctx = talloc_get_type(private_data, struct lsql_context); + + lsql_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED); +} + +static void lsql_callback(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval t, + void *private_data) +{ + struct lsql_context *ctx; + int ret; + + ctx = talloc_get_type(private_data, struct lsql_context); + + switch (ctx->req->operation) { + case LDB_SEARCH: + ret = lsql_search(ctx); + break; + case LDB_ADD: + ret = lsql_add(ctx); + break; + case LDB_MODIFY: + ret = lsql_modify(ctx); + break; + case LDB_DELETE: + ret = lsql_delete(ctx); + break; + case LDB_RENAME: + ret = lsql_rename(ctx); + break; +/* TODO: + case LDB_EXTENDED: + ret = lsql_extended(ctx); + break; + */ + default: + /* no other op supported */ + ret = LDB_ERR_PROTOCOL_ERROR; + } + + if (!ctx->callback_failed) { + /* Once we are done, we do not need timeout events */ + talloc_free(ctx->timeout_event); + lsql_request_done(ctx, ret); + } +} + +static int lsql_handle_request(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + struct tevent_context *ev; + struct lsql_context *ac; + struct tevent_timer *te; + struct timeval tv; + + if (ldb_check_critical_controls(req->controls)) { + return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; + } + + if (req->starttime == 0 || req->timeout == 0) { + ldb_set_errstring(ldb, "Invalid timeout settings"); + return LDB_ERR_TIME_LIMIT_EXCEEDED; + } + + ldb = ldb_module_get_ctx(module); + ev = ldb_get_event_context(ldb); + + ac = talloc_zero(req, struct lsql_context); + if (ac == NULL) { + ldb_set_errstring(ldb, "Out of Memory"); + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->module = module; + ac->req = req; + + tv.tv_sec = 0; + tv.tv_usec = 0; + te = tevent_add_timer(ev, ac, tv, lsql_callback, ac); + if (NULL == te) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (req->timeout > 0) { + tv.tv_sec = req->starttime + req->timeout; + tv.tv_usec = 0; + ac->timeout_event = tevent_add_timer(ev, ac, tv, lsql_timeout, ac); + if (NULL == ac->timeout_event) { + return LDB_ERR_OPERATIONS_ERROR; + } + } + + return LDB_SUCCESS; +} + +/* + * Table of operations for the sqlite3 backend + */ +static const struct ldb_module_ops lsqlite3_ops = { + .name = "sqlite", + .search = lsql_handle_request, + .add = lsql_handle_request, + .modify = lsql_handle_request, + .del = lsql_handle_request, + .rename = lsql_handle_request, + .extended = lsql_handle_request, + .start_transaction = lsql_start_trans, + .end_transaction = lsql_end_trans, + .del_transaction = lsql_del_trans, +}; + +/* + * Static functions + */ + +static int initialize(struct lsqlite3_private *lsqlite3, + struct ldb_context *ldb, const char *url, + unsigned int flags) +{ + TALLOC_CTX *local_ctx; + long long queryInt; + int rollback = 0; + char *errmsg; + char *schema; + int ret; + + /* create a local ctx */ + local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_rename local context"); + if (local_ctx == NULL) { + return -1; + } + + schema = lsqlite3_tprintf(local_ctx, + + + "CREATE TABLE ldb_info AS " + " SELECT 'LDB' AS database_type," + " '1.0' AS version;" + + /* + * The entry table holds the information about an entry. + * This table is used to obtain the EID of the entry and to + * support scope=one and scope=base. The parent and child + * table is included in the entry table since all the other + * attributes are dependent on EID. + */ + "CREATE TABLE ldb_entry " + "(" + " eid INTEGER PRIMARY KEY AUTOINCREMENT," + " dn TEXT UNIQUE NOT NULL," + " norm_dn TEXT UNIQUE NOT NULL" + ");" + + + "CREATE TABLE ldb_object_classes" + "(" + " class_name TEXT PRIMARY KEY," + " parent_class_name TEXT," + " tree_key TEXT UNIQUE," + " max_child_num INTEGER DEFAULT 0" + ");" + + /* + * We keep a full listing of attribute/value pairs here + */ + "CREATE TABLE ldb_attribute_values" + "(" + " eid INTEGER REFERENCES ldb_entry," + " attr_name TEXT," + " norm_attr_name TEXT," + " attr_value TEXT," + " norm_attr_value TEXT " + ");" + + + /* + * Indexes + */ + "CREATE INDEX ldb_attribute_values_eid_idx " + " ON ldb_attribute_values (eid);" + + "CREATE INDEX ldb_attribute_values_name_value_idx " + " ON ldb_attribute_values (attr_name, norm_attr_value);" + + + + /* + * Triggers + */ + + "CREATE TRIGGER ldb_object_classes_insert_tr" + " AFTER INSERT" + " ON ldb_object_classes" + " FOR EACH ROW" + " BEGIN" + " UPDATE ldb_object_classes" + " SET tree_key = COALESCE(tree_key, " + " (" + " SELECT tree_key || " + " (SELECT base160(max_child_num + 1)" + " FROM ldb_object_classes" + " WHERE class_name = " + " new.parent_class_name)" + " FROM ldb_object_classes " + " WHERE class_name = new.parent_class_name " + " ));" + " UPDATE ldb_object_classes " + " SET max_child_num = max_child_num + 1" + " WHERE class_name = new.parent_class_name;" + " END;" + + /* + * Table initialization + */ + + "INSERT INTO ldb_object_classes " + " (class_name, tree_key) " + " VALUES " + " ('TOP', '0001');"); + + /* Skip protocol indicator of url */ + if (strncmp(url, "sqlite3://", 10) != 0) { + return SQLITE_MISUSE; + } + + /* Update pointer to just after the protocol indicator */ + url += 10; + + /* Try to open the (possibly empty/non-existent) database */ + if ((ret = sqlite3_open(url, &lsqlite3->sqlite)) != SQLITE_OK) { + return ret; + } + + /* In case this is a new database, enable auto_vacuum */ + ret = sqlite3_exec(lsqlite3->sqlite, "PRAGMA auto_vacuum = 1;", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3 initializaion error: %s\n", errmsg); + free(errmsg); + } + goto failed; + } + + if (flags & LDB_FLG_NOSYNC) { + /* DANGEROUS */ + ret = sqlite3_exec(lsqlite3->sqlite, "PRAGMA synchronous = OFF;", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3 initializaion error: %s\n", errmsg); + free(errmsg); + } + goto failed; + } + } + + /* */ + + /* Establish a busy timeout of 30 seconds */ + if ((ret = sqlite3_busy_timeout(lsqlite3->sqlite, + 30000)) != SQLITE_OK) { + return ret; + } + + /* Create a function, callable from sql, to increment a tree_key */ + if ((ret = + sqlite3_create_function(lsqlite3->sqlite,/* handle */ + "base160_next", /* function name */ + 1, /* number of args */ + SQLITE_ANY, /* preferred text type */ + NULL, /* user data */ + base160next_sql, /* called func */ + NULL, /* step func */ + NULL /* final func */ + )) != SQLITE_OK) { + return ret; + } + + /* Create a function, callable from sql, to convert int to base160 */ + if ((ret = + sqlite3_create_function(lsqlite3->sqlite,/* handle */ + "base160", /* function name */ + 1, /* number of args */ + SQLITE_ANY, /* preferred text type */ + NULL, /* user data */ + base160_sql, /* called func */ + NULL, /* step func */ + NULL /* final func */ + )) != SQLITE_OK) { + return ret; + } + + /* Create a function, callable from sql, to perform various comparisons */ + if ((ret = + sqlite3_create_function(lsqlite3->sqlite, /* handle */ + "ldap_compare", /* function name */ + 4, /* number of args */ + SQLITE_ANY, /* preferred text type */ + ldb , /* user data */ + lsqlite3_compare, /* called func */ + NULL, /* step func */ + NULL /* final func */ + )) != SQLITE_OK) { + return ret; + } + + /* Begin a transaction */ + ret = sqlite3_exec(lsqlite3->sqlite, "BEGIN EXCLUSIVE;", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3: initialization error: %s\n", errmsg); + free(errmsg); + } + goto failed; + } + rollback = 1; + + /* Determine if this is a new database. No tables means it is. */ + if (query_int(lsqlite3, + &queryInt, + "SELECT COUNT(*)\n" + " FROM sqlite_master\n" + " WHERE type = 'table';") != 0) { + goto failed; + } + + if (queryInt == 0) { + /* + * Create the database schema + */ + ret = sqlite3_exec(lsqlite3->sqlite, schema, NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3 initializaion error: %s\n", errmsg); + free(errmsg); + } + goto failed; + } + } else { + /* + * Ensure that the database we opened is one of ours + */ + if (query_int(lsqlite3, + &queryInt, + "SELECT " + " (SELECT COUNT(*) = 2" + " FROM sqlite_master " + " WHERE type = 'table' " + " AND name IN " + " (" + " 'ldb_entry', " + " 'ldb_object_classes' " + " ) " + " ) " + " AND " + " (SELECT 1 " + " FROM ldb_info " + " WHERE database_type = 'LDB' " + " AND version = '1.0'" + " );") != 0 || + queryInt != 1) { + + /* It's not one that we created. See ya! */ + goto failed; + } + } + + /* Commit the transaction */ + ret = sqlite3_exec(lsqlite3->sqlite, "COMMIT;", NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + if (errmsg) { + printf("lsqlite3: iniialization error: %s\n", errmsg); + free(errmsg); + } + goto failed; + } + + return SQLITE_OK; + +failed: + if (rollback) lsqlite3_safe_rollback(lsqlite3->sqlite); + sqlite3_close(lsqlite3->sqlite); + return -1; +} + +/* + * connect to the database + */ +static int lsqlite3_connect(struct ldb_context *ldb, + const char *url, + unsigned int flags, + const char *options[], + struct ldb_module **_module) +{ + struct ldb_module *module; + struct lsqlite3_private *lsqlite3; + unsigned int i; + int ret; + + module = ldb_module_new(ldb, ldb, "ldb_sqlite3 backend", &lsqlite3_ops); + if (!module) return LDB_ERR_OPERATIONS_ERROR; + + lsqlite3 = talloc(module, struct lsqlite3_private); + if (!lsqlite3) { + goto failed; + } + + lsqlite3->sqlite = NULL; + lsqlite3->options = NULL; + lsqlite3->trans_count = 0; + + ret = initialize(lsqlite3, ldb, url, flags); + if (ret != SQLITE_OK) { + goto failed; + } + + talloc_set_destructor(lsqlite3, destructor); + + ldb_module_set_private(module, lsqlite3); + + if (options) { + /* + * take a copy of the options array, so we don't have to rely + * on the caller keeping it around (it might be dynamic) + */ + for (i=0;options[i];i++) ; + + lsqlite3->options = talloc_array(lsqlite3, char *, i+1); + if (!lsqlite3->options) { + goto failed; + } + + for (i=0;options[i];i++) { + + lsqlite3->options[i+1] = NULL; + lsqlite3->options[i] = + talloc_strdup(lsqlite3->options, options[i]); + if (!lsqlite3->options[i]) { + goto failed; + } + } + } + + *_module = module; + return LDB_SUCCESS; + +failed: + if (lsqlite3 && lsqlite3->sqlite != NULL) { + (void) sqlite3_close(lsqlite3->sqlite); + } + talloc_free(lsqlite3); + return LDB_ERR_OPERATIONS_ERROR; +} + +int ldb_sqlite3_init(const char *version) +{ + LDB_MODULE_CHECK_VERSION(version); + return ldb_register_backend("sqlite3", lsqlite3_connect, false); +} diff --git a/ldb-2.0.8/ldb_sqlite3/schema b/ldb-2.0.8/ldb_sqlite3/schema new file mode 100644 index 0000000..ab7c5cc --- /dev/null +++ b/ldb-2.0.8/ldb_sqlite3/schema @@ -0,0 +1,328 @@ + -- ------------------------------------------------------ + + PRAGMA auto_vacuum=1; + + -- ------------------------------------------------------ + + BEGIN EXCLUSIVE; + + -- ------------------------------------------------------ + + CREATE TABLE ldb_info AS + SELECT 'LDB' AS database_type, + '1.0' AS version; + + /* + * Get the next USN value with: + * BEGIN EXCLUSIVE; + * UPDATE usn SET value = value + 1; + * SELECT value FROM usn; + * COMMIT; + */ + CREATE TABLE usn + ( + value INTEGER + ); + + CREATE TABLE ldb_object + ( + /* tree_key is auto-generated by the insert trigger */ + tree_key TEXT PRIMARY KEY, + + parent_tree_key TEXT, + dn TEXT, + + attr_name TEXT REFERENCES ldb_attributes, + attr_value TEXT, + + /* + * object_type can take on these values (to date): + * 1: object is a node of a DN + * 2: object is an attribute/value pair of its parent DN + */ + object_type INTEGER, + + /* + * if object_type is 1, the node can have children. + * this tracks the maximum previously assigned child + * number so we can generate a new unique tree key for + * a new child object. note that this is always incremented, + * so if children are deleted, this will not represent + * the _number_ of children. + */ + max_child_num INTEGER, + + /* + * Automatically maintained meta-data (a gift for metze) + */ + object_guid TEXT UNIQUE, + timestamp INTEGER, -- originating_time + invoke_id TEXT, -- GUID: originating_invocation_id + usn INTEGER, -- hyper: originating_usn + + /* do not allow duplicate name/value pairs */ + UNIQUE (parent_tree_key, attr_name, attr_value, object_type) + ); + + CREATE TABLE ldb_attributes + ( + attr_name TEXT PRIMARY KEY, + parent_tree_key TEXT, + + objectclass_p BOOLEAN DEFAULT 0, + + case_insensitive_p BOOLEAN DEFAULT 0, + wildcard_p BOOLEAN DEFAULT 0, + hidden_p BOOLEAN DEFAULT 0, + integer_p BOOLEAN DEFAULT 0, + + /* tree_key is auto-generated by the insert trigger */ + tree_key TEXT, -- null if not a object/sub class + -- level 1 if an objectclass + -- level 1-n if a subclass + max_child_num INTEGER + ); + + -- ------------------------------------------------------ + + CREATE INDEX ldb_object_dn_idx + ON ldb_object (dn); + + CREATE INDEX ldb_attributes_tree_key_ids + ON ldb_attributes (tree_key); + + -- ------------------------------------------------------ + + /* Gifts for metze. Automatically updated meta-data */ + CREATE TRIGGER ldb_object_insert_tr + AFTER INSERT + ON ldb_object + FOR EACH ROW + BEGIN + UPDATE ldb_object + SET max_child_num = max_child_num + 1 + WHERE tree_key = new.parent_tree_key; + UPDATE usn SET value = value + 1; + UPDATE ldb_object + SET tree_key = + (SELECT + new.tree_key || + base160(SELECT max_child_num + FROM ldb_object + WHERE tree_key = + new.parent_tree_key)); + max_child_num = 0, + object_guid = random_guid(), + timestamp = strftime('%s', 'now'), + usn = (SELECT value FROM usn); + WHERE tree_key = new.tree_key; + END; + + CREATE TRIGGER ldb_object_update_tr + AFTER UPDATE + ON ldb_object + FOR EACH ROW + BEGIN + UPDATE usn SET value = value + 1; + UPDATE ldb_object + SET timestamp = strftime('%s', 'now'), + usn = (SELECT value FROM usn); + WHERE tree_key = new.tree_key; + END; + + CREATE TRIGGER ldb_attributes_insert_tr + AFTER INSERT + ON ldb_attributes + FOR EACH ROW + BEGIN + UPDATE ldb_attributes + SET max_child_num = max_child_num + 1 + WHERE tree_key = new.parent_tree_key; + UPDATE ldb_attributes + SET tree_key = + (SELECT + new.tree_key || + base160(SELECT max_child_num + FROM ldb_attributes + WHERE tree_key = + new.parent_tree_key)); + max_child_num = 0 + WHERE tree_key = new.tree_key; + END; + + + -- ------------------------------------------------------ + + /* Initialize usn */ + INSERT INTO usn (value) VALUES (0); + + /* Create root object */ + INSERT INTO ldb_object + (tree_key, parent_tree_key, + dn, + object_type, max_child_num) + VALUES ('', NULL, + '', + 1, 0); + + /* We need an implicit "top" level object class */ + INSERT INTO ldb_attributes (attr_name, + parent_tree_key) + SELECT 'top', ''; + + -- ------------------------------------------------------ + + COMMIT; + + -- ------------------------------------------------------ + +/* + * dn: o=University of Michigan,c=US + * objectclass: organization + * objectclass: domainRelatedObject + */ +-- newDN +BEGIN; + +INSERT OR IGNORE INTO ldb_object + (parent_tree_key + dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('', + 'c=US', + 'c', 'US', 1, 0); + +INSERT INTO ldb_object + (parent_tree_key, + dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('0001', + 'o=University of Michigan,c=US', + 'o', 'University of Michigan', 1, 0); + +-- newObjectClass +INSERT OR IGNORE INTO ldb_attributes + (attr_name, parent_tree_key, objectclass_p) + VALUES + ('objectclass', '', 1); + +INSERT INTO ldb_object + (parent_tree_key, + dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', + NULL, + 'objectclass', 'organization', 2, 0); + +INSERT OR IGNORE INTO ldb_attributes + (attr_name, parent_tree_key, objectclass_p) + VALUES + ('objectclass', '', 1); + +INSERT INTO ldb_object + (parent_tree_key, + dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', + NULL, + 'objectclass', 'domainRelatedObject', 2, 0); + +COMMIT; + + +/* + * dn: o=University of Michigan,c=US + * l: Ann Arbor, Michigan + * st: Michigan + * o: University of Michigan + * o: UMICH + * seeAlso: + * telephonenumber: +1 313 764-1817 + */ +-- addAttrValuePair +BEGIN; + +INSERT INTO ldb_object + (parent_tree_key, dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', NULL, + 'l', 'Ann Arbor, Michigan', 2, 0); + +INSERT INTO ldb_object + (parent_tree_key, dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', NULL, + 'st', 'Michigan', 2, 0); + +INSERT INTO ldb_object + (parent_tree_key, dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', NULL, + 'o', 'University of Michigan', 2, 0); + +INSERT INTO ldb_object + (parent_tree_key, dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', NULL, + 'o', 'UMICH', 2, 0); + +INSERT INTO ldb_object + (parent_tree_key, dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', NULL, + 'seeAlso', '', 2, 0); + +INSERT INTO ldb_object + (parent_tree_key, dn, + attr_name, attr_value, object_type, max_child_num) + VALUES ('00010001', NULL, + 'telephonenumber', '+1 313 764-1817', 2, 0); + +COMMIT; + +-- ---------------------------------------------------------------------- + +/* + * dn: @ATTRIBUTES + * uid: CASE_INSENSITIVE WILDCARD + * cn: CASE_INSENSITIVE + * ou: CASE_INSENSITIVE + * dn: CASE_INSENSITIVE + */ +-- newAttribute + +BEGIN; + +INSERT OR IGNORE INTO ldb_attributes + (attr_name, parent_tree_key, objectclass_p) + VALUES + ('uid', '', 0); + +UPDATE ldb_attributes + SET case_insensitive_p = 1, + wildcard_p = 1, + hidden_p = 0, + integer_p = 0 + WHERE attr_name = 'uid' + +UPDATE ldb_attributes + SET case_insensitive_p = 1, + wildcard_p = 0, + hidden_p = 0, + integer_p = 0 + WHERE attr_name = 'cn' + +UPDATE ldb_attributes + SET case_insensitive_p = 1, + wildcard_p = 0, + hidden_p = 0, + integer_p = 0 + WHERE attr_name = 'ou' + +UPDATE ldb_attributes + SET case_insensitive_p = 1, + wildcard_p = 0, + hidden_p = 0, + integer_p = 0 + WHERE attr_name = 'dn' + diff --git a/ldb-2.0.8/ldb_sqlite3/trees.ps b/ldb-2.0.8/ldb_sqlite3/trees.ps new file mode 100644 index 0000000..433a064 --- /dev/null +++ b/ldb-2.0.8/ldb_sqlite3/trees.ps @@ -0,0 +1,1760 @@ +%!PS-Adobe-2.0 +%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software +%%Title: trees.dvi +%%Pages: 7 +%%PageOrder: Ascend +%%BoundingBox: 0 0 596 842 +%%EndComments +%DVIPSWebPage: (www.radicaleye.com) +%DVIPSCommandLine: dvips -f trees.dvi +%DVIPSParameters: dpi=600, compressed +%DVIPSSource: TeX output 2000.05.06:2055 +%%BeginProcSet: texc.pro +%! +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr +1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 +1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx +0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx +sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ +rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp +gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B +/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ +/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ +A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy +get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} +ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp +fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 +{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add +chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ +1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} +forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N +/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ +/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) +(LaserWriter 16/600)]{A length product length le{A length product exch 0 +exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse +end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask +grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} +imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round +exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto +fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p +delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} +B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ +p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S +rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + +%%EndProcSet +TeXDict begin 39158280 55380996 1000 600 600 (trees.dvi) +@start +%DVIPSBitmapFont: Fa cmr10 10 6 +/Fa 6 55 df<146014E0EB01C0EB0380EB0700130E131E5B5BA25B485AA2485AA212075B +120F90C7FCA25A121EA2123EA35AA65AB2127CA67EA3121EA2121F7EA27F12077F1203A2 +6C7EA26C7E1378A27F7F130E7FEB0380EB01C0EB00E01460135278BD20>40 +D<12C07E12707E7E7E120F6C7E6C7EA26C7E6C7EA21378A2137C133C133E131EA2131F7F +A21480A3EB07C0A6EB03E0B2EB07C0A6EB0F80A31400A25B131EA2133E133C137C1378A2 +5BA2485A485AA2485A48C7FC120E5A5A5A5A5A13527CBD20>I<15301578B3A6007FB812 +F8B912FCA26C17F8C80078C8FCB3A6153036367BAF41>43 D48 DI54 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fb cmr7 7 3 +/Fb 3 55 df48 D<13381378EA01F8121F12FE12E01200B3AB487EB512F8A2 +15267BA521>I54 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fc cmmi10 10 1 +/Fc 1 69 df<0103B7FC4916E018F8903B0007F80007FE4BEB00FFF03F80020FED1FC018 +0F4B15E0F007F0021F1503A24B15F81801143F19FC5DA2147FA292C8FCA25C18035CA213 +0119F84A1507A2130319F04A150FA2010717E0181F4A16C0A2010FEE3F80A24AED7F0018 +7E011F16FE4D5A4A5D4D5A013F4B5A4D5A4A4A5A057FC7FC017F15FEEE03FC91C7EA0FF0 +49EC7FC0B8C8FC16FC16C03E397DB845>68 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fd ectt1000 10 73 +/Fd 73 126 df37 +D39 +D<143814FC13011303EB07F8EB0FF0EB1FC0EB3F80EB7F0013FE485A485A5B12075B120F +5B485AA2123F90C7FCA25A127EA312FE5AAC7E127EA3127F7EA27F121FA26C7E7F12077F +12037F6C7E6C7E137FEB3F80EB1FC0EB0FF0EB07F8EB03FC130113001438164272B92C> +I<127012FC7E7E6C7E6C7EEA0FE06C7E6C7E6C7E6C7E137F7F1480131F14C0130FEB07E0 +A214F01303A214F81301A314FC1300AC130114F8A3130314F0A2130714E0A2EB0FC0131F +1480133F14005B13FE485A485A485A485AEA3FC0485A48C7FC5A5A1270164279B92C>I< +EB0380497EA60020140800F8143E00FE14FE00FF13C1EBC7C7EBE7CF003FB512F8000F14 +E0000314806C140038007FFCA248B5FC481480000F14E0003F14F839FFE7CFFEEBC7C7EB +07C100FE13C000F8143E0020140800001400A66D5A1F247AAA2C>I<147014F8AF003FB6 +12E0B712F8A4C700F8C7FCB0147025267DAB2C>II<121FEA3F80EA7FC0EAFFE0A5EA7FC0EA3F80EA1F000B0B708A2C>46 +D<1507ED0F80A2151F16005D153E157E157CA215FC5D14015D14035D14075D140F5D141F +92C7FC5C143EA2147E147C14FC5C13015C13035C13075C130F5C131F91C8FC5B133EA213 +7E137C13FC5B12015B12035B12075B120F5B121F90C9FCA25A123E127E127C12FC5AA212 +7021417BB92C>II<1307497EA2131F +A2133F137F13FF5A1207127FB5FC13DF139FEA7C1F1200B3AE007FB512E0B612F0A36C14 +E01C3477B32C>II<000FB512FE4880A35D0180C8FCADEB83FE90389FFF8090B512E015F881 +9038FE03FE9038F000FF01C07F49EB3F8090C7121F6C15C0C8120FA2ED07E0A4123C127E +B4FC150F16C0A248141F007EEC3F80007FEC7F006C6C5B6D485A391FF80FFC6CB55A6C5C +000114C06C6C90C7FCEB0FF823347CB22C>53 DI<1278B712C016E0A316C000FCC7EA3F80ED7F0015FE00785CC712014A +5A4A5A5D140F5D4A5A143F92C7FC5C147E14FE5C13015CA2495AA213075CA3495AA4495A +A5133F91C8FCAA131E23357CB32C>I59 D<1502ED0F80151F157F15 +FF913803FE00EC0FFCEC1FF0EC7FE0ECFF80D903FEC7FC495AEB1FF0495AEBFF80000390 +C8FCEA07FCEA1FF8EA3FE0EAFF8090C9FCA27FEA3FE0EA1FF8EA07FC6CB4FCC67FEB3FE0 +6D7EEB07FC6D7E903800FF80EC7FE0EC1FF0EC0FFCEC03FE913800FF80157F151F150FED +0200212A7BAD2C>I<007FB612F0B712F8A36C15F0CAFCA8007FB612F0B712F8A36C15F0 +25127DA12C>I<122012F87EB4FC7FEA3FE0EA1FF8EA07FC6CB4FCC67FEB3FE06D7EEB07 +FC6D7E903800FF80EC7FE0EC1FF0EC0FFCEC03FE913800FF80157FA215FF913803FE00EC +0FFCEC1FF0EC7FE0ECFF80D903FEC7FC495AEB1FF0495AEBFF80000390C8FCEA07FCEA1F +F8EA3FE0EAFF8090C9FC12FC5A1220212A7BAD2C>I<14FE497EA4497FA214EFA2130781 +A214C7A2010F7FA314C390381F83F0A590383F01F8A490387E00FCA549137E90B512FEA3 +4880A29038F8003FA34848EB1F80A4000715C049130FD87FFEEBFFFC6D5AB514FE6C15FC +497E27347EB32C>65 D<007FB512E015F8B612FE6C8016C03903F0003FED0FE0ED07F015 +03A2ED01F8A6ED03F0A21507ED0FE0ED1FC0EDFF8090B612005D5D15FF16C09039F0001F +E0ED07F0ED03F81501ED00FCA216FE167EA616FE16FC1501ED03F8150FED3FF0007FB612 +E016C0B712806CECFE0015F027337FB22C>I<02FF13700107EBE0F84913F9013F13FD49 +13FFEBFF813901FE007F4848131FD807F0130F1507485A491303485A150148C7FCA25A00 +7EEC00F01600A212FE5AAB7E127EA3007F15F06CEC01F8A26C7EA26C6C13036D14F06C6C +130716E0D803FC131F6C6CEB3FC03A00FF81FF806DB512006D5B010F5B6D13F001001380 +25357DB32C>I<007FB5FCB612C015F0816C803907E003FEEC00FFED7F80153FED1FC0ED +0FE0A2150716F0150316F81501A4ED00FCACED01F8A3150316F0A2150716E0150FED1FC0 +153FED7F80EDFF00EC03FE007FB55AB65A5D15C06C91C7FC26337EB22C>I<007FB612F0 +B712F8A37E3903F00001A7ED00F01600A4EC01E04A7EA490B5FCA5EBF003A46E5A91C8FC +A5163C167EA8007FB612FEB7FCA36C15FC27337EB22C>I<007FB612F8B712FCA37ED803 +F0C7FCA716781600A515F04A7EA490B5FCA5EBF001A46E5A92C7FCAD387FFFE0B5FC805C +7E26337EB22C>I<903901FC038090390FFF87C04913EF017F13FF90B6FC4813073803FC +01497E4848137F4848133F49131F121F5B003F140F90C7FCA2127EED078092C7FCA212FE +5AA8913803FFF84A13FCA27E007E6D13F89138000FC0A36C141FA27F121F6D133F120F6D +137F6C7E6C6C13FF6D5A3801FF076C90B5FC6D13EF011F13CF6DEB0780D901FCC7FC2635 +7DB32C>II<007FB512F8B612FCA36C14 +F839000FC000B3B3A5007FB512F8B612FCA36C14F81E3379B22C>I75 D<387FFFE0B57EA36C5BD803F0C8FCB3AE16F0 +ED01F8A8007FB6FCB7FCA36C15F025337DB22C>IIII<007FB512C0B612 +F88115FF6C15802603F00013C0153FED0FE0ED07F0A2150316F81501A6150316F01507A2 +ED0FE0ED3FC015FF90B61280160015FC5D15C001F0C8FCB0387FFF80B57EA36C5B25337E +B22C>II<387FFFFCB67E15E015F86C803907E007FE1401EC007F6F7E151FA2 +6F7EA64B5AA2153F4BC7FCEC01FE140790B55A5D15E081819038E007FCEC01FE1400157F +81A8160FEE1F80A5D87FFEEB1FBFB5ECFF00815E6C486D5AC8EA01F029347EB22C>I<90 +381FF80790B5EA0F804814CF000714FF5A381FF01F383FC003497E48C7FC007E147F00FE +143F5A151FA46CEC0F00007E91C7FC127F7FEA3FE0EA1FFCEBFFC06C13FC0003EBFFC06C +14F06C6C7F01077F9038007FFEEC07FF02001380153FED1FC0A2ED0FE0A20078140712FC +A56CEC0FC0A26CEC1F806D133F01E0EB7F009038FE01FF90B55A5D00F914F0D8F83F13C0 +D8700790C7FC23357CB32C>I<007FB612FCB712FEA43AFC007E007EA70078153CC71400 +B3AF90383FFFFCA2497F6D5BA227337EB22C>I<3B7FFF803FFFC0B56C4813E0A36C496C +13C03B03F00001F800B3AF6D130300015DA26D130700005D6D130F017F495A6D6C485AEC +E0FF6DB5C7FC6D5B010313F86D5B9038003F802B3480B22C>III<3A3FFF03FFE0484913F0148714076C6D13E03A01 +F800FE007F0000495A13FE017E5BEB7F03013F5B1487011F5B14CF010F5B14FF6D5BA26D +90C7FCA26D5AA26D5AA2497EA2497EA2497F81EB0FCF81EB1FC7EC87F0EB3F83EC03F8EB +7F01017E7FEBFE00497F0001147E49137F000380491480151FD87FFEEBFFFC6D5AB514FE +6C15FC497E27337EB22C>II<387FFFFCB512FEA314FC00FCC7FCB3B3B3B512FC14FEA36C13FC +17416FB92C>91 D<127012F8A27E127C127E123E123F7EA27F120F7F12077F12037F1201 +7F12007F137C137E133EA2133F7F80130F80130780130380130180130080147C147E143E +A2143F8081140F81140781140381140181140081157CA2157E153E153F811680150FA2ED +070021417BB92C>I<387FFFFCB512FEA37EC7127EB3B3B3387FFFFEB5FCA36C13FC1741 +7DB92C>II<007FB6FCB71280A46C150021067B7D +2C>I<1338137CEA01FC1203EA07F813F0EA0FC0EA1F80A2EA3F00123E127E127CA212FC +5AA3EAFFC013E013F013F8A2127FA2123F13F0EA1FE0EA07C00E1D72B82C>I<3801FFF0 +000713FE001F6D7E15E048809038C01FF81407EC01FC381F80000006C77EC8127EA3ECFF +FE131F90B5FC1203120F48EB807E383FF800EA7FC090C7FC12FE5AA47E007F14FEEB8003 +383FE01F6CB612FC6C15FE6C14BF0001EBFE1F3A003FF007FC27247CA32C>II<90 +3803FFE0011F13F8017F13FE48B5FC48804848C6FCEA0FF0485A49137E4848131890C9FC +5A127EA25AA8127EA2127F6C140F6DEB1F806C7E6D133F6C6CEB7F003907FE03FF6CB55A +6C5C6C6C5B011F13E0010390C7FC21247AA32C>III103 +DI< +1307EB1FC0A2497EA36D5AA20107C7FC90C8FCA7387FFFC080B5FC7EA2EA0007B3A8007F +B512FCB612FEA36C14FC1F3479B32C>I107 D<387FFFE0B57EA37EEA0003B3B3A5007F +B61280B712C0A36C158022337BB22C>I<3A7F83F007E09039CFFC1FF83AFFDFFE3FFCD8 +7FFF13FF91B57E3A07FE1FFC3E01FCEBF83F496C487E01F013E001E013C0A301C01380B3 +3B7FFC3FF87FF0027F13FFD8FFFE6D13F8D87FFC4913F0023F137F2D2481A32C>I<397F +F01FE039FFF87FFC9038F9FFFE01FB7F6CB6FC00019038F03F80ECC01F02807FEC000F5B +5BA25BB3267FFFE0B5FCB500F11480A36C01E0140029247FA32C>II<397FF01FE0 +39FFF8FFF801FB13FE90B6FC6C158000019038F07FC09138801FE091380007F049EB03F8 +5BED01FC491300A216FE167EA816FE6D14FCA2ED01F86D13036DEB07F0150F9138801FE0 +9138E07FC091B51280160001FB5B01F813F8EC3FC091C8FCAD387FFFE0B57EA36C5B2736 +7FA32C>I<903903FC078090391FFF0FC0017F13CF48B512EF4814FF3807FE07380FF001 +48487E49137F4848133F90C7FC48141F127E150F5AA87E007E141FA26C143F7F6C6C137F +6D13FF380FF0033807FC0F6CB6FC6C14EF6C6C138F6D130FEB07F890C7FCAD0203B5FC4A +1480A36E140029367DA32C>II<90387FF8700003B512F8120F5A5A387FC00F387E00034813015AA36CEB +00F0007F140013F0383FFFC06C13FE6CEBFF80000314E0C66C13F8010113FCEB0007EC00 +FE0078147F00FC143F151F7EA26C143F6D133E6D13FE9038F007FC90B5FC15F815E000F8 +148039701FFC0020247AA32C>I<131E133FA9007FB6FCB71280A36C1500D8003FC8FCB1 +ED03C0ED07E0A5EC800F011FEB1FC0ECE07F6DB51280160001035B6D13F89038003FE023 +2E7EAD2C>I<3A7FF003FF80486C487FA3007F7F0001EB000FB3A3151FA2153F6D137F39 +00FE03FF90B7FC6D15807F6D13CF902603FE07130029247FA32C>I<3A3FFF03FFF04801 +8713F8A36C010313F03A00FC007E005D90387E01F8013F5BEB1F83EC87E090380FCFC090 +3807EF80EB03FF6D90C7FC5C6D5A147C14FE130180903803EF80903807CFC0EB0FC7EC83 +E090381F01F0013F7FEB7E00017C137C49137E0001803A7FFF01FFFC1483B514FE6C15FC +140127247EA32C>120 D<3A7FFF01FFFCB5008113FE148314816C010113FC3A03E0000F +806C7E151F6D140012005D6D133E137C017E137E013E137CA2013F13FC6D5BA2EB0F815D +A2EB07C1ECC3E0A2EB03E3ECE7C0130114F75DEB00FFA292C7FC80A2143EA2147E147CA2 +14FC5CA2EA0C01003F5BEA7F83EB87E0EA7E0F495A387FFF806C90C8FC6C5A6C5AEA07E0 +27367EA32C>I<15FF02071380141F147F91B512004913C04AC7FCEB03F85CB31307EB1F +E013FF007F5BB55A49C8FC6D7E6C7FC67F131FEB07F01303B380EB01FEECFFC06D13FF6E +1380141F14070200130021417BB92C>123 D<127812FCB3B3B3A9127806416DB92C>II E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fe ecti1000 10 33 +/Fe 33 122 df28 D<150C151C153815F0EC01E0EC03C0EC0780EC0F00141E5C147C5C5C495A1303 +495A5C130F49C7FCA2133EA25BA25BA2485AA212035B12075BA2120F5BA2121FA290C8FC +A25AA2123EA2127EA2127CA412FC5AAD1278A57EA3121C121EA2120E7EA26C7E6C7EA212 +001E5274BD22>40 D<140C140E80EC0380A2EC01C015E0A2140015F0A21578A4157C153C +AB157CA715FCA215F8A21401A215F0A21403A215E0A21407A215C0140F1580A2141F1500 +A2143EA25CA25CA2495AA2495A5C1307495A91C7FC5B133E133C5B5B485A12035B48C8FC +120E5A12785A12C01E527FBD22>I<4B7EA3150393C8FCA35D1506A3150E150CA3151C15 +18A315381530A31570B912E0A2C80060C8FC15E05DA314015DA3140392C9FCA35C1406A3 +140E140CA3141C1418A2333275AD40>43 DI<120E +EA3F80127F12FFA31300127E123C0909778819>46 D<0103B612FEEFFFC018F0903B0007 +F8000FF84BEB03FCEF00FE020F157FF03F804B141F19C0021F150F19E05D1807143F19F0 +5DA2147FA292C8FCA25C180F5CA2130119E04A151FA2130319C04A153FA201071780187F +4A1600A2010F16FEA24A4A5A60011F15034D5A4A5D4D5A013F4B5A173F4A4AC7FC17FC01 +7FEC03F84C5A91C7EA1FC04949B45A007F90B548C8FCB712F016803C397CB83F>68 +D<0103B512F8A390390007F8005DA2140FA25DA2141FA25DA2143FA25DA2147FA292C7FC +A25CA25CA21301A25CA21303A25CA21307A25CA2130FA25CA2131FA25CA2133FA25CA213 +7FA291C8FC497EB6FCA25C25397CB820>73 D<0107B512FCA25E9026000FF8C7FC5D5D14 +1FA25DA2143FA25DA2147FA292C8FCA25CA25CA21301A25CA21303A25CA21307A25CA213 +0F170C4A141CA2011F153C17384A1478A2013F157017F04A14E01601017F140317C091C7 +1207160F49EC1F80163F4914FF000102071300B8FCA25E2E397BB834>76 +D79 +D81 D<92383FC00E913901FFF01C020713FC91 +391FC07E3C91393F001F7C027CEB0FF84A130749481303495A4948EB01F0A2495AA2011F +15E091C7FCA34915C0A36E90C7FCA2806D7E14FCECFF806D13F015FE6D6D7E6D14E00100 +80023F7F14079138007FFC150F15031501A21500A2167C120EA3001E15FC5EA3003E4A5A +A24B5AA2007F4A5A4B5A6D49C7FC6D133ED8F9F013FC39F8FC03F839F07FFFE0D8E01F13 +8026C003FCC8FC2F3D7ABA2F>83 D<0007B812E0A25AD9F800EB001F01C049EB07C0485A +D900011403121E001C5C003C17801403123800785C00701607140700F01700485CA2140F +C792C7FC5DA2141FA25DA2143FA25DA2147FA292C9FCA25CA25CA21301A25CA21303A25C +A21307A25CA2130FA25CEB3FF0007FB512F8B6FCA2333971B83B>I<14F8EB07FE90381F +871C90383E03FE137CEBF801120148486C5A485A120FEBC001001F5CA2EA3F801403007F +5C1300A21407485C5AA2140F5D48ECC1C0A2141F15831680143F1587007C017F1300ECFF +076C485B9038038F8E391F0F079E3907FE03FC3901F000F0222677A42A>97 +D<133FEA1FFFA3C67E137EA313FE5BA312015BA312035BA31207EBE0F8EBE7FE9038EF0F +80390FFC07C013F89038F003E013E0D81FC013F0A21380A2123F1300A214075A127EA214 +0F12FE4814E0A2141F15C05AEC3F80A215005C147E5C387801F8007C5B383C03E0383E07 +C0381E1F80D80FFEC7FCEA01F01C3B77B926>I<147F903803FFC090380FC1E090381F00 +70017E13784913383901F801F83803F003120713E0120FD81FC013F091C7FC485AA2127F +90C8FCA35A5AA45AA3153015381578007C14F0007EEB01E0003EEB03C0EC0F806CEB3E00 +380F81F83803FFE0C690C7FC1D2677A426>II<147F903803FFC090380FC1E09038 +3F00F0017E13785B485A485A485A120F4913F8001F14F0383F8001EC07E0EC1F80397F81 +FF00EBFFF8148090C8FC5A5AA55AA21530007C14381578007E14F0003EEB01E0EC03C06C +EB0F806CEB3E00380781F83803FFE0C690C7FC1D2677A426>IIIII108 +DII<147F903803FFC090380FC1F090381F00F8 +017E137C5B4848137E4848133E0007143F5B120F485AA2485A157F127F90C7FCA215FF5A +4814FEA2140115FC5AEC03F8A2EC07F015E0140F007C14C0007EEB1F80003EEB3F00147E +6C13F8380F83F03803FFC0C648C7FC202677A42A>I<9039078007C090391FE03FF09039 +3CF0787C903938F8E03E9038787FC00170497EECFF00D9F0FE148013E05CEA01E113C15C +A2D80003143FA25CA20107147FA24A1400A2010F5C5E5C4B5A131F5EEC80035E013F495A +6E485A5E6E48C7FC017F133EEC70FC90387E3FF0EC0F8001FEC9FCA25BA21201A25BA212 +03A25B1207B512C0A3293580A42A>I<3903C003F0390FF01FFC391E783C0F381C7C703A +3C3EE03F8038383FC0EB7F800078150000701300151CD8F07E90C7FCEAE0FE5BA2120012 +015BA312035BA312075BA3120F5BA3121F5BA3123F90C9FC120E212679A423>114 +D<14FE903807FF8090380F83C090383E00E04913F00178137001F813F00001130313F0A2 +15E00003EB01C06DC7FC7FEBFFC06C13F814FE6C7F6D13807F010F13C01300143F141F14 +0F123E127E00FE1480A348EB1F0012E06C133E00705B6C5B381E03E06CB45AD801FEC7FC +1C267AA422>II<01F013 +0ED803FC133FD8071EEB7F80EA0E1F121C123C0038143F49131F0070140FA25BD8F07E14 +0000E08013FEC6485B150E12015B151E0003141C5BA2153C000714385B5DA35DA24A5A14 +0300035C6D48C7FC0001130E3800F83CEB7FF8EB0FC0212679A426>118 +D<903907E007C090391FF81FF89039787C383C9038F03E703A01E01EE0FE3803C01F0180 +13C0D8070014FC481480000E1570023F1300001E91C7FC121CA2C75AA2147EA214FEA25C +A21301A24A1370A2010314F016E0001C5B007E1401010714C000FEEC0380010F1307010E +EB0F0039781CF81E9038387C3C393FF03FF03907C00FC027267CA427>120 +D<13F0D803FCEB01C0D8071EEB03E0D80E1F1307121C123C0038140F4914C01270A24913 +1FD8F07E148012E013FEC648133F160012015B5D0003147E5BA215FE00075C5BA214015D +A314035D14070003130FEBF01F3901F87FE038007FF7EB1FC7EB000F5DA2141F003F5C48 +133F92C7FC147E147C007E13FC387001F8EB03E06C485A383C1F80D80FFEC8FCEA03F023 +3679A428>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Ff cmsy10 10 1 +/Ff 1 16 df15 +D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fg ecbx1000 10 36 +/Fg 36 119 df<913803FFC0027F13F00103B512FC010FEB00FED93FF8133FD97FE0EBFF +8049485A5A1480484A13C04A6C1380A36F1300167E93C7FCA592383FFFC0B8FCA4000390 +C7FCB3ABB5D8FC3F13FFA4303A7EB935>28 D45 +DI<141E143E +14FE1307137FB5FCA3138FEA000FB3B3A5007FB61280A4213679B530>49 +DI54 D58 D66 DII73 +D76 DII< +EDFFF8020FEBFF80027F14F0903A01FFC01FFC010790380007FFD91FFC010113C0D93FF0 +6D6C7E49486E7E49486E7E48496E7E48834890C86C7EA248486F1380A248486F13C0A200 +3F18E0A348486F13F0A400FF18F8AC007F18F06D5DA3003F18E0A26D5D001F18C0A26C6C +4B13806C18006E5C6C6D4A5A6C5F6C6D4A5A6D6C4A5AD93FFC49485A6DB401075B0107D9 +C01F90C7FC010190B512FC6D6C14F0020F1480020001F8C8FC3D3B7BB948>III83 D85 DII<13 +FFB5FCA412077EAF4AB47E020F13F0023F13FC9138FE03FFDAF00013804AEB7FC00280EB +3FE091C713F0EE1FF8A217FC160FA217FEAA17FCA3EE1FF8A217F06E133F6EEB7FE06E14 +C0903AFDF001FF80903AF8FC07FE009039F03FFFF8D9E00F13E0D9C00390C7FC2F3A7EB9 +35>98 D100 +D<903803FF80011F13F0017F13FC3901FF83FE3A03FE007F804848133F484814C0001FEC +1FE05B003FEC0FF0A2485A16F8150712FFA290B6FCA301E0C8FCA4127FA36C7E1678121F +6C6C14F86D14F000071403D801FFEB0FE06C9038C07FC06DB51200010F13FC010113E025 +257DA42C>II<161FD907FEEBFFC090387FFFE348B6EAEFE02607FE07138F260FF801131F48486C13 +8F003F15CF4990387FC7C0EEC000007F81A6003F5DA26D13FF001F5D6C6C4890C7FC3907 +FE07FE48B512F86D13E0261E07FEC8FC90CAFCA2123E123F7F6C7E90B512F8EDFF8016E0 +6C15F86C816C815A001F81393FC0000F48C8138048157F5A163FA36C157F6C16006D5C6C +6C495AD81FF0EB07FCD807FEEB3FF00001B612C06C6C91C7FC010713F02B377DA530>I< +EA01F0EA07FC487EA2487EA56C5AA26C5AEA01F0C8FCA913FF127FA412077EB3A9B512F8 +A4153B7DBA1B>105 D<13FFB5FCA412077EAF92380FFFE0A4923803FC0016F0ED0FE0ED +1F804BC7FC157E5DEC03F8EC07E04A5A141FEC7FE04A7E8181A2ECCFFEEC0FFF496C7F80 +6E7F6E7F82157F6F7E6F7E82150F82B5D8F83F13F8A42D3A7EB932>107 +D<13FFB5FCA412077EB3B3ACB512FCA4163A7DB91B>I<01FED97FE0EB0FFC00FF902601 +FFFC90383FFF80020701FF90B512E0DA1F81903983F03FF0DA3C00903887801F000749DA +CF007F00034914DE6D48D97FFC6D7E4A5CA24A5CA291C75BB3A3B5D8FC1FB50083B512F0 +A44C257DA451>I<01FEEB7FC000FF903803FFF8020F13FE91381F03FFDA3C0113800007 +13780003497E6D4814C05CA25CA291C7FCB3A3B5D8FC3F13FFA430257DA435>I<903801 +FFC0010F13F8017F13FFD9FF807F3A03FE003FE048486D7E48486D7E48486D7EA2003F81 +491303007F81A300FF1680A9007F1600A3003F5D6D1307001F5DA26C6C495A6C6C495A6C +6C495A6C6C6CB45A6C6CB5C7FC011F13FC010113C029257DA430>I<9038FE03F000FFEB +0FFEEC3FFF91387C7F809138F8FFC000075B6C6C5A5CA29138807F80ED3F00150C92C7FC +91C8FCB3A2B512FEA422257EA427>114 D<90383FF0383903FFFEF8000F13FF381FC00F +383F0003007E1301007C130012FC15787E7E6D130013FCEBFFE06C13FCECFF806C14C06C +14F06C14F81203C614FC131F9038007FFE140700F0130114007E157E7E157C6C14FC6C14 +F8EB80019038F007F090B512C000F8140038E01FF81F257DA426>I<130FA55BA45BA25B +5BA25A1207001FEBFFE0B6FCA3000390C7FCB21578A815F86CEB80F014816CEBC3E09038 +3FFFC06D1380903803FE001D357EB425>I118 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fh ecrm1000 10 89 +/Fh 89 126 df<486C1360000314E039070001C0000EEB038048EB070000181306003813 +0E0030130C0070131C00601318A200E01338481330A400CEEB338039FF803FE001C013F0 +A3007F131FA2393F800FE0390E0003801C1981B91C>16 D<001C1307007FEB1FC039FF80 +3FE0A201C013F0A3007F131F001CEB073000001300A400011470491360A2000314E090C7 +12C048130100061480000E130348EB070048130E485B006013181C1980B91C>I21 D27 +DI30 D36 D<141FEC7FC0903801F0 +E0903803C0600107137090380F803090381F00381518A25BA2133E133F15381530A21570 +5D5D140190381F838092CAFC1487148E02DC49B51280EB0FF85C4A9039003FF8000107ED +0FC06E5D71C7FC6E140E010F150CD91DFC141C01391518D970FE143801E015302601C07F +1470D803805D00076D6C5BD80F00EBC00148011F5C4890380FE003003E6E48C8FC007E90 +3807F8060203130E00FE6E5A6E6C5A1400ED7F706C4B13036F5A6F7E6C6C6D6C5B701306 +6C6C496C130E6DD979FE5B281FF001F07F133C3C07F80FE03FC0F86CB539800FFFF0C690 +26FE000313C0D91FF0D9007FC7FC393E7DBB41>38 D<121C127FEAFF80A213C0A3127F12 +1C1200A412011380A2120313005A1206120E5A5A5A12600A1979B917>I<146014E0EB01 +C0EB0380EB0700130E131E5B5BA25B485AA2485AA212075B120F90C7FCA25A121EA2123E +A35AA65AB2127CA67EA3121EA2121F7EA27F12077F1203A26C7EA26C7E1378A27F7F130E +7FEB0380EB01C0EB00E01460135278BD20>I<12C07E12707E7E7E120F6C7E6C7EA26C7E +6C7EA21378A2137C133C133E131EA2131F7FA21480A3EB07C0A6EB03E0B2EB07C0A6EB0F +80A31400A25B131EA2133E133C137C1378A25BA2485A485AA2485A48C7FC120E5A5A5A5A +5A13527CBD20>I<1530B3A8B912FCA2C80030C8FCB3A836367BAF41>43 +D<121C127FEAFF80A213C0A3127F121C1200A412011380A2120313005A1206120E5A5A5A +12600A19798817>II<121C127FEAFF80A5EA7F00121C09097988 +17>I<1506A2150E150CA2151C151815381530A215701560A215E015C0A214011580A214 +0315005C1406A2140E140CA2141C1418A214381430A21470146014E05CA213015CA21303 +91C7FCA25B1306A2130E130C131C1318A213381330A213701360A213E05BA212015B1203 +90C8FCA25A1206A2120E120CA2121C1218A21238123012701260A212E05AA21F537BBD2A +>II +III<1538A2157815F8A214011403 +1407A2140F141F141B14331473146314C313011483EB030313071306130C131C13181330 +1370136013C01201EA038013005A120E120C5A123812305A12E0B712F8A3C73803F800AA +4A7E0103B512F8A325387EB72A>I<0006140CD80780133C9038F003F890B5FC5D5D1580 +92C7FC14FC38067FE090C9FCAAEB07F8EB1FFE9038780F809038E007E03907C003F0496C +7E130000066D7E81C8FC8181A21680A4121C127F5A7FA390C713005D12FC00605C12704A +5A6C5C6C1303001E495A6C6C485A3907E03F800001B5C7FC38007FFCEB1FE021397CB62A +>II<12301238123E003FB612E0A316C05A168016 +000070C712060060140E5D5D00E014304814705D5DC712014A5A4AC7FC1406140E5CA25C +1478147014F05C1301A213035C1307A2130FA3131F5CA2133FA5137FA96DC8FC131E233A +7BB72A>III<121C127FEAFF80A5 +EA7F00121CC7FCB2121C127FEAFF80A5EA7F00121C092479A317>I<121C127FEAFF80A5 +EA7F00121CC7FCB2121C127FEAFF80A213C0A3127F121C1200A412011380A2120313005A +1206120E5A5A5A12600A3479A317>II<007FB812F8B912FCCCFCB0B912FC6C17F836147B9E41>I<12E01278121EEA07C0 +EA01F0EA003C130FEB03C0EB00F0143C140FEC03E0EC00F8151EED0780ED01E0ED007816 +1EEE07C0EE01F0EE003C170FEF03C0A2EF0F00173CEE01F0EE07C0041EC7FC1678ED01E0 +ED0780031EC8FC15F8EC03E0020FC9FC143C14F0EB03C0010FCAFC133CEA01F0EA07C000 +1ECBFC127812E0322E79AB41>II<1538A3157CA315FEA34A7EA34A6C7EA202077FEC063FA202 +0E7FEC0C1FA2021C7FEC180FA202387FEC3007A202707FEC6003A202C07F1501A2D90180 +7F81A249C77F167FA20106810107B6FCA24981010CC7121FA2496E7EA3496E7EA3496E7E +A213E0707E1201486C81D80FFC02071380B56C90B512FEA3373C7DBB3E>65 +DI<913A01FF800180020FEBE003027F13F8903A01FF807E07903A03 +FC000F0FD90FF0EB039F4948EB01DFD93F80EB00FF49C8127F01FE153F12014848151F48 +48150FA248481507A2485A1703123F5B007F1601A35B00FF93C7FCAD127F6DED0180A312 +3F7F001F160318006C7E5F6C7E17066C6C150E6C6C5D00001618017F15386D6C5CD91FE0 +5C6D6CEB03C0D903FCEB0F80902701FF803FC7FC9039007FFFFC020F13F002011380313D +7BBA3C>IIIIIII<013FB512 +E0A39039001FFC00EC07F8B3B3A3123FEA7F80EAFFC0A44A5A1380D87F005B0070131F6C +5C6C495A6C49C7FC380781FC3801FFF038007F80233B7DB82B>IIIIIIIII< +D90FF813C090383FFE0190B512813903F807E33907E000F74848137F4848133F48C7121F +003E140F007E1407A2007C140312FC1501A36C1400A37E6D14006C7E7F13F86CB47E6C13 +F8ECFF806C14E06C14F86C14FEC680013F1480010714C0EB007F020713E0EC007FED3FF0 +151F150FED07F8A200C01403A21501A37EA216F07E15036C15E06C14076C15C06C140F6D +EB1F80D8FBF0EB3F00D8F0FE13FE39E03FFFF8010F13E0D8C00190C7FC253D7CBA2E>I< +003FB812E0A3D9C003EB001F273E0001FE130348EE01F00078160000701770A300601730 +A400E01738481718A4C71600B3B0913807FF80011FB612E0A335397DB83C>IIII89 D<003FB7FCA39039FC0001FE +01C0130349495A003EC7FC003C4A5A5E0038141F00784A5A12704B5A5E006014FF4A90C7 +FCA24A5A5DC712074A5AA24A5A5D143F4A5AA24A5A92C8FC5B495AA2495A5C130F4948EB +0180A2495A5C137F495A16034890C7FC5B1203485AEE0700485A495C001F5D48485C5E48 +48495A49130FB8FCA329397BB833>II93 D<007FB81280B912C0A26C17 +803204797041>95 D97 DIIII<147E903803FF8090 +380FC1E0EB1F8790383F0FF0137EA213FCA23901F803C091C7FCADB512FCA3D801F8C7FC +B3AB487E387FFFF8A31C3B7FBA19>IIIIIII<2703F00FF0EB1FE000FFD93FFCEB +7FF8913AF03F01E07E903BF1C01F83803F3D0FF3800FC7001F802603F70013CE01FE14DC +49D907F8EB0FC0A2495CA3495CB3A3486C496CEB1FE0B500C1B50083B5FCA340257EA445 +>I<3903F00FF000FFEB3FFCECF03F9039F1C01F803A0FF3800FC03803F70013FE496D7E +A25BA35BB3A3486C497EB500C1B51280A329257EA42E>II<3903F01F +E000FFEB7FF89038F1E07E9039F3801F803A07F7000FC0D803FEEB07E049EB03F04914F8 +49130116FC150016FEA3167FAA16FEA3ED01FCA26DEB03F816F06D13076DEB0FE001F614 +C09039F7803F009038F1E07E9038F0FFF8EC1FC091C8FCAB487EB512C0A328357EA42E> +II<3807E01F00FFEB7FC09038E1E3E09038E387F0380FE707EA03E613EE9038EC03E0 +9038FC0080491300A45BB3A2487EB512F0A31C257EA421>II<1318A51338A31378A313F812011203 +1207001FB5FCB6FCA2D801F8C7FCB215C0A93800FC011580EB7C03017E13006D5AEB0FFE +EB01F81A347FB220>IIIIII<003FB512FCA2EB8003D83E0013F8003CEB07F00038 +EB0FE012300070EB1FC0EC3F800060137F150014FE495AA2C6485A495AA2495A495A495A +A290387F000613FEA2485A485A0007140E5B4848130C4848131CA24848133C48C7127C48 +EB03FC90B5FCA21F247EA325>II<126012F0B3B3B3 +B3A91260045377BD17>I<12FCEAFFC0EA07F0EA01FCEA007E7F80131F80130FB3A78013 +07806D7E6D7EEB007EEC1FF0EC07F8EC1FF0EC7E00495A495A495A5C130F5CB3A7131F5C +133F91C7FC137E485AEA07F0EAFFC000FCC8FC1D537ABD2A>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fi ecbx1440 14.4 34 +/Fi 34 118 df28 D45 D<151E153E15FE1403140F147FEB07FF00 +03B5FCB6FCA3EBF87FEAFC00C7FCB3B3B3A6007FB712FCA52E4E76CD42>49 +DI<913807FFC0027F13FC0103B67E010F15E090 +261FF80313F890267FC0007F01FEC7EA3FFE48488148486E138013FE486C6C6D13C08048 +17E080A66C5B18C06C5B6C90C75AD80038168090C8FC4C1300A24C5A5F4C5A4B5B4B13C0 +030F5BDB7FFEC7FC91387FFFF816C016FCEEFF80DA000313E09238007FF8EE3FFE707E70 +138018C07013E018F07013F8A218FC82A218FEA3EA03C0EA0FF0EA3FFC487EA2B5FCA218 +FCA25E18F8A26C4816F0495C4916E0D83FE04A13C06C485CD80FF04A1380D807FE91387F +FE003B03FFE003FFFC6C90B65A6C6C15E0010F92C7FC010114FCD9001F1380374F7BCD42 +>I<17FC1601A216031607160FA2161F163F167FA216FF5D5DA25D5D5D167F153E157E15 +FC15F8EC01F01403EC07E015C0EC0F80141FEC3F00143E5C14FC495A5C495A1307495A5C +49C7FC5B137E137C5B1201485A5B485A120F485A90C8FC123E127E5ABA1280A5C901FCC7 +FCAF021FB71280A5394F7CCE42>I<486C150601F0153E01FEEC01FED9FFF0133F91B65A +5F5F5F5F5F94C7FC16FC5E16E093C8FC15FC01F0138091CAFCAC913807FF80023F13F891 +B512FE01F36E7E9026FFFC0113E09139E0007FF891C76C7E496E7E01F86E7E5B70138049 +16C0C9FC18E08218F0A418F8A31203EA0FE0EA3FF8487EA212FF7FA218F0A25B5E6C4816 +E05B01C016C06CC85A18806C6C4A13007FD80FF04A5A6C6CECFFFCD803FE4913F02701FF +E00F5B6C6CB612806D92C7FC010F14F8010114C09026003FFCC8FC354F7ACD42>I58 +D<932603FFF01407047F01FF5C0307B600E05B033F03F85B92B700FE5B02039126C003FF +5B020F01F8C7EA3FC1023F01C0EC0FE391B5C80003B5FC4901FC814949814901E082011F +498249498292CA7E4948834948835A4A83485B4885A2484984A2485B87A2485B87A25AA2 +98C8FC91CFFCA2B5FCAE7E067FB7128080A37E95C76C90C7FC807EA36C7FA26C7FA26C7F +7E806C7F137F6D7E816D6D93B5FC01077F6D01F85D6D7F6D01FF5D023F01E0EC0FEF020F +01FCEC3FE30203903AFFE001FF81020091B6C6FC033F03FC133F030703F0130FDB007F02 +801303040301F8CAFC595479D267>71 D73 D76 +D78 D80 D<93381FFF800303B512FC033FECFFC0 +92B712F00207D9F80113FE021F903AC0003FFF804A48C700077FDAFFF8020113F049496E +7F49496F7E49496F7E49496F7E4990C96C7F4948707F4948707F01FF854849707F4A8248 +86A24849717E48864A83A2481B80A248497113C0A4481BE0A291CB7EA3B51AF0AF6C1BE0 +A36E5FA26C1BC0A36C1B806E5FA26C1B006E5F6C62A26C6DD903FC4A5A6CDB0FFF5D6E49 +EBC0016C4B01E05C6D6C90277E07F0035B6E9039F801F807902A3FFF01F000780F5B6D04 +7C5C6DD981E06D4890C7FC6D01E191381F7FFE010101F1EDFFF86DD9F9F06D5BDA3FFF16 +C06E6D013F5B02079027FE01FFFEC8FC020190B612F8DA003F4B141003071838DB001FEB +83F893C7EA03FC1C7885726C14F8F2C003F2F01F97B512F084A31CE085A27314C01C8085 +1C00735B735B735B735B9638003FC0556A79D263>III<003FBB12FCA59126C0007FEB000301FCC7ED003FD87FF0F00FFE491807 +49180349180190C81600A2007E1A7EA3007C1A3EA500FC1A3F481A1FA6C91700B3B3AC49 +B912C0A550517BD05B>I97 D<913803FFE0023F13FE91B67E010315E0010F9038003FF8D93FFCEB +07FC4948497E4948131F4849497E485B485BA24890C7FC5A5B003F6F5A705A705A007F92 +C8FC5BA312FFAD127F7FA3123F7F6CEE0F80A26C6D141F18006C6D5C6C6D143E6C6D147E +6C6D5C6D6C495A6DB4EB07F0010F9038C01FE06D90B5128001014AC7FCD9003F13F80203 +138031387CB63A>99 D<943803FF80040FB5FCA5EE003F170FB3A4913803FF80023F13F8 +49B512FE0107ECFF8F011F9038C03FEF90273FFE0007B5FCD97FF8130149487F48498048 +4980484980488291C8FC5A5B123FA2127F5BA312FFAD127FA37F123FA3121F7F6C5E6C6D +5C5F6C6D91B5FC6C6D5B6C6D4914E0D97FFCD90FEFEBFF80D91FFFEB7F8F010790B5120F +010114FC6D6C13E00207010049C7FC41547CD249>I<913807FF80027F13F849B512FE01 +076E7E011F010313E0903A3FFC007FF0D97FF06D7E49486D7E4849130F48496D7E488248 +90C77E1880485A82003F17C0A3485A18E082A212FFA290B8FCA401FCCAFCA6127FA37F12 +3FA2EF03E06C7E17076C17C06C6D140F18806C6D141F6C6DEC3F006C6D147ED97FFC495A +D91FFFEB07F86D9038E03FF0010390B512C001005D023F01FCC7FC020113E033387CB63C +>IIII<133FEBFFC0 +487F487FA2487FA66C5BA26C5B6C5B013FC7FC90C8FCAEEB1FF8B5FCA512017EB3B3A6B6 +12F0A51C547CD324>I108 +DII<913801FFC0023F13FE91B67E010315E001 +0F018013F8903A3FFC001FFED97FF0EB07FF49486D7F48496D7F48496D7F91C8127F4883 +488349153F001F83A2003F8349151FA2007F83A400FF1880AC007F1800A3003F5F6D153F +A2001F5FA26C6C4B5AA26C6D4A5A6C5F6C6D495B6C6D495B6D6C4990C7FCD93FFCEB1FFE +6DB46CB45A010790B512F0010115C0D9003F49C8FC020313E039387CB642>II<90393FF001FCB590 +380FFF804B13E0037F13F09238FE1FF89138F1F83F00019138F07FFC6CEBF3E015C0ECF7 +80A2ECFF00EE3FF84AEB1FF0EE0FE093C7FC5CA45CB3ABB612FEA52E367DB535>114 +D<903903FFC00E011FEBFC1E90B6127E000315FE3907FE003FD80FF0130F484813034848 +1301491300127F90C8127EA248153EA27FA27F01F091C7FC13FCEBFF806C13FEECFFF06C +14FE6F7E6C15E06C816C15FC6C81C681133F010F15801301D9000F14C0EC003F030713E0 +150100F880167F6C153FA2161F7EA217C07E6D143F17807F6DEC7F0001F85C6DEB03FE90 +39FF801FFC486CB512F0D8F81F14C0D8F00791C7FC39E0007FF02B387CB634>I<147CA6 +14FCA41301A31303A21307A2130F131F133F137F13FF1203000F90B512FEB7FCA426007F +FCC8FCB3A9EE0F80ABEE1F006D7EA2011F143E806D6D5A6DEBC1F86DEBFFF001005C023F +1380DA03FEC7FC294D7ECB33>II E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fj ecrm0900 9 5 +/Fj 5 109 df<123C127E12FFA4127E123C08087A8715>46 D97 DI104 +D108 +D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fk ecbx0900 9 7 +/Fk 7 117 df65 D97 DI<903807FF80013F13F090B512FC3903FE01FE4848487EEA0FF8EA1FF0EA3FE0 +A2007F6D5A496C5A153000FF91C7FCA9127F7FA2003FEC07807F6C6C130F000FEC1F00D8 +07FE133E3903FF80FCC6EBFFF8013F13E0010790C7FC21217DA027>I<3901F81F8000FF +EB7FF0ECFFF89038F9E3FC9038FBC7FE380FFF876C1307A213FEEC03FCEC01F8EC006049 +1300B1B512F0A41F217EA024>114 D<9038FFE1C0000713FF5A383F803F387E000F1407 +5A14037EA26C6CC7FC13FCEBFFE06C13FC806CEBFF80000F14C06C14E0C6FC010F13F0EB +007F140F00F0130714037EA26C14E06C13076CEB0FC09038C01F8090B5120000F913FC38 +E03FE01C217DA023>I<133CA5137CA313FCA21201A212031207001FB51280B6FCA3D807 +FCC7FCB0EC03C0A79038FE078012033901FF0F006C13FEEB3FFCEB0FF01A2F7EAE22>I +E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fl ecrm1200 12 25 +/Fl 25 122 df<121EEA7F8012FF13C0A213E0A3127FEA1E601200A413E013C0A3120113 +80120313005A1206120E5A5A5A12600B1D78891B>44 D<14FF010713E090381F81F89038 +3E007C01FC133F4848EB1F8049130F4848EB07C04848EB03E0A2000F15F0491301001F15 +F8A2003F15FCA390C8FC4815FEA54815FFB3A46C15FEA56D1301003F15FCA3001F15F8A2 +6C6CEB03F0A36C6CEB07E0000315C06D130F6C6CEB1F806C6CEB3F00013E137C90381F81 +F8903807FFE0010090C7FC28447CC131>48 D50 D54 D<16C04B7EA34B7EA34B7EA34B7EA3ED +19FEA3ED30FFA203707FED607FA203E07FEDC03FA2020180ED801FA2DA03007F160FA202 +06801607A24A6D7EA34A6D7EA34A6D7EA20270810260147FA202E08191B7FCA249820280 +C7121FA249C87F170FA20106821707A2496F7EA3496F7EA3496F7EA201788313F8486C83 +D80FFF03037FB500E0027FEBFFC0A342477DC649>65 DI68 D77 +D<003FB912F8A3903BF0001FF8001F01806D481303003EC7150048187C0078183CA20070 +181CA30060180CA5481806A5C81600B3B3A54B7EED7FFE49B77EA33F447DC346>84 +D +I97 +D99 D<167FED3FFFA315018182B3EC7F80903803 +FFF090380FC07C90383F000E017E1307496D5AD803F87F48487F5B000F81485AA2485AA2 +127FA290C8FC5AAB7E7FA2123FA26C7EA2000F5D7F6C6C5B00035C6C6C9038077F806C6C +010E13C0013F011C13FE90380FC0F8903803FFE09026007F0013002F467DC436>II103 D105 D108 D<3901FC01FE00FF903807FFC091381E +07F091383801F8000701707F0003EBE0002601FDC07F5C01FF147F91C7FCA25BA35BB3A8 +486CECFF80B5D8F83F13FEA32F2C7DAB36>110 DI<3903F803F000FFEB1FFCEC3C3EEC707F0007EBE0FF3803F9C000015B13FBEC00 +7E153C01FF13005BA45BB3A748B4FCB512FEA3202C7DAB26>114 +D<90383FE0183901FFFC383907E01F78390F0003F8001E1301481300007C1478127800F8 +1438A21518A27EA27E6C6C13006C7E13FC383FFFE06C13FC6C13FF6C14C06C14E0C614F0 +011F13F81300EC0FFC140300C0EB01FE1400157E7E153EA27EA36C143C6C147C15786C14 +F86CEB01F039F38003E039F1F00F8039E07FFE0038C00FF01F2E7DAC26>I<1306A5130E +A4131EA3133E137EA213FE12011207001FB512F0B6FCA2C648C7FCB3A4150CAA017E131C +017F1318A26D133890381F8030ECC070903807E0E0903801FFC09038007F001E3E7EBC26 +>III< +B539F001FFFCA3000790C7EA7FE06C48EC1F8000011600160E0000150C6D141C6D1418A2 +6E1338013F1430A26D6C5BA26E13E0010F5CA26D6C485AA2ECF803010391C7FCA2903801 +FC06A2ECFE0E0100130CA2EC7F18A215B8EC3FB0A2EC1FE0A36E5AA26E5AA36EC8FCA214 +06A35CA25CA2123C007E5BB4FC5CA25CEAFE01387C0380D87007C9FCEA3C1EEA0FFCEA03 +F02E3F7EAA33>121 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fm ecbx1200 12 47 +/Fm 47 123 df<0118140C017C143E01FC147E48485C4848495A495C4848495A4848495A +001F140F90C75B003E4AC7FCA2003C141E007C143E0078143CA200F8147CA2481478D8F1 +F014F8D8F7FCEB7BFEB46CEB7FFF6D1580028014C0A36C80A36C806C496C13806C486D13 +006C486D5AD801F0EB00F82A2283C427>16 DI28 D46 D48 DIII<163FA25E5E5D5DA25D5D5D5DA25D92B5FCEC01F7EC03E7140715 +C7EC0F87EC1F07143E147E147C14F8EB01F0EB03E0130714C0EB0F80EB1F00133E5BA25B +485A485A485A120F5B48C7FC123E5A12FCB91280A5C8000F90C7FCAC027FB61280A53141 +7DC038>I<0007150301E0143F01FFEB07FF91B6FC5E5E5E5E5E16804BC7FC5D15E092C8 +FC01C0C9FCAAEC3FF001C1B5FC01C714C001DF14F09039FFE03FFC9138000FFE01FC6D7E +01F06D13804915C0497F6C4815E0C8FC6F13F0A317F8A4EA0F80EA3FE0487E12FF7FA317 +F05B5D6C4815E05B007EC74813C0123E003F4A1380D81FC0491300D80FF0495AD807FEEB +FFFC6CB612F0C65D013F1480010F01FCC7FC010113C02D427BC038>I<4AB47E021F13F0 +027F13FC49B6FC01079038807F8090390FFC001FD93FF014C04948137F4948EBFFE04849 +5A5A1400485A120FA248486D13C0EE7F80EE1E00003F92C7FCA25B127FA2EC07FC91381F +FF8000FF017F13E091B512F89039F9F01FFC9039FBC007FE9039FF8003FF17804A6C13C0 +5B6F13E0A24915F0A317F85BA4127FA5123FA217F07F121FA2000F4A13E0A26C6C15C06D +4913806C018014006C6D485A6C9038E01FFC6DB55A011F5C010714C0010191C7FC903800 +3FF02D427BC038>I<121E121F13FC90B712FEA45A17FC17F817F017E017C0A248168000 +7EC8EA3F00007C157E5E00785D15014B5A00F84A5A484A5A5E151FC848C7FC157E5DA24A +5A14035D14074A5AA2141F5D143FA2147F5D14FFA25BA35B92C8FCA35BA55BAA6D5A6D5A +6D5A2F447AC238>I58 D<1A60F101F01907191FF17FC0953801FF00F007FCF01FF0F07FC04D48C7FCEF07 +FCEF3FF0EFFFC0040390C8FCEE0FFCEE3FE0EEFF80DB03FEC9FCED0FF8ED3FE0EDFF80DA +07FECAFCEC1FF8EC7FE0903801FF80D907FCCBFCEB1FF0EB7FC04848CCFCEA07FCEA1FF0 +EA7FC048CDFCA2EA7FC0EA1FF0EA07FCEA01FF38007FC0EB1FF0EB07FC903801FF809038 +007FE0EC1FF8EC07FE913800FF80ED3FE0ED0FF8ED03FE923800FF80EE3FE0EE0FFCEE03 +FF040013C0EF3FF0EF07FCEF01FF9438007FC0F01FF0F007FCF001FF9538007FC0F11FF0 +19071901F10060444277B957>60 D<126012F812FE6C7EEA3FE0EA0FF8EA03FEC66C7EEB +3FE0EB0FF8EB03FE903800FFC0EC3FF0EC0FFCEC03FF9138007FC0ED1FF0ED07FCED01FF +9238007FC0EE1FF0EE07FE933801FF809338007FE0EF1FF8EF03FE943800FF80F03FE0F0 +0FF8F003FE953800FF80F13FE0F10FF0A2F13FE0F1FF80953803FE00F00FF8F03FE0F0FF +80DD03FEC7FCEF1FF8EF7FE0933801FF80DC07FEC8FCEE1FF0EE7FC04B48C9FCED07FCED +1FF0ED7FC0DA03FFCAFCEC0FFCEC3FF0ECFFC0D903FECBFCEB0FF8EB3FE0EBFF80D803FE +CCFCEA0FF8EA3FE0EAFF8048CDFC12F81260444277B957>62 D<923803FFF0037FEBFF80 +0203B612F0020F15FC913A3FFC000FFFDAFFC0010013C0D903FEC8EA1FF0D907F0ED03F8 +D91FC0ED00FE4948167F017ECAEA1F8049717E4848717E49DAFF8013034848010F01F06D +7E4848013F01FC6D7E92B6FC4848489026C07F80137C49489026001FC0133C484948D907 +E0133E001E49486D6C131E003E49480101141F023F913800FFE0003C4A82007C017F1880 +007819074A5AA300F81AC04848491603AB6C6C7F12781B801A076E7E127C003C133F003E +6E1700021F4A5C001E6D6C5B001F6D6C49EBF01E6C6D6C011F143E6D6CD9C07F6D5A6C6C +6C90B5383FFFF8033FD9FC0F5B6C6C010FD9F0035B6C6C0100903980007F806D91CBFC6C +7E137E6D7E6D6CEF7FC0D907F0EE03FFD903FE043F1300902600FFC0913803FFF8DA3FFC +49B512C0020FB748C7FC020316E0DA007F02FCC8FC030349C9FC4A477AC557>64 +DIIII73 D77 D<923807FFC092B512FE0207ECFFC0021F15F0 +91267FFE0013FC902601FFF0EB1FFF01070180010313C04990C76C7FD91FFC6E6C7E4948 +6F7E49486F7E01FF8348496F7E48496F1380A248496F13C0A24890C96C13E0A24819F049 +82003F19F8A3007F19FC49177FA400FF19FEAD007F19FC6D17FFA3003F19F8A26D5E6C19 +F0A26E5D6C19E0A26C6D4B13C06C19806E5D6C6D4B13006C6D4B5A6D6C4B5A6D6C4B5A6D +6C4A5B6D01C001075B6D01F0011F5B010101FE90B5C7FC6D90B65A023F15F8020715C002 +004AC8FC030713C047467AC454>79 D83 D<007FBA12E0BB12F0A46C19E04406776757>95 D<903801FFE0011F13FE017F6D +7E48B612E03A03FE007FF84848EB1FFC6D6D7E486C6D7EA26F7FA36F7F6C5A6C5AEA00F0 +90C7FCA40203B5FC91B6FC1307013F13F19038FFFC01000313E0481380381FFE00485A5B +127F5B12FF5BA35DA26D5B6C6C5B4B13F0D83FFE013EEBFFC03A1FFF80FC7F0007EBFFF8 +6CECE01FC66CEB8007D90FFCC9FC322F7DAD36>97 DIIIIIII<137C48B4FC4813804813C0A24813E0A56C13 +C0A26C13806C1300EA007C90C7FCAAEB7FC0EA7FFFA512037EB3AFB6FCA518467CC520> +I108 D<90277F8007FEEC0FFC +B590263FFFC090387FFF8092B5D8F001B512E002816E4880913D87F01FFC0FE03FF8913D +8FC00FFE1F801FFC0003D99F009026FF3E007F6C019E6D013C130F02BC5D02F86D496D7E +A24A5D4A5DA34A5DB3A7B60081B60003B512FEA5572D7CAC5E>I<90397F8007FEB59038 +3FFF8092B512E0028114F8913987F03FFC91388F801F000390399F000FFE6C139E14BC02 +F86D7E5CA25CA35CB3A7B60083B512FEA5372D7CAC3E>II<90397FC00FF8B590B57E02C314E002CF14F89139DFC03F +FC9139FF001FFE000301FCEB07FF6C496D13804A15C04A6D13E05C7013F0A2EF7FF8A4EF +3FFCACEF7FF8A318F017FFA24C13E06E15C06E5B6E4913806E4913006E495A9139DFC07F +FC02CFB512F002C314C002C091C7FCED1FF092C9FCADB67EA536407DAC3E>II<90387F807FB53881FFE002 +8313F0028F13F8ED8FFC91389F1FFE000313BE6C13BC14F8A214F0ED0FFC9138E007F8ED +01E092C7FCA35CB3A5B612E0A5272D7DAC2E>I<90391FFC038090B51287000314FF120F +381FF003383FC00049133F48C7121F127E00FE140FA215077EA27F01E090C7FC13FE387F +FFF014FF6C14C015F06C14FC6C800003806C15806C7E010F14C0EB003F020313E0140000 +F0143FA26C141F150FA27EA26C15C06C141FA26DEB3F8001E0EB7F009038F803FE90B55A +00FC5CD8F03F13E026E007FEC7FC232F7CAD2C>II< +D97FC049B4FCB50103B5FCA50003EC000F6C81B3A85EA25EA25E7E6E491380017FD901F7 +13FE9138F807E76DB512C7010F1407010313FE9026007FF0EBFC00372E7CAC3E>I +I120 +D<001FB71280A49026FC001F130001E0495A5B49495A90C7485A48495B123E4A5B4A5B00 +3C495BA24A90C7FC4A5A4A5AC7FC4A5A495B495BA2495B499038800780491300A2495A49 +48130F49481400A2485B48495B485BA248495B4890C75A48485C15034848EB1FFEB7FCA4 +292C7DAB32>122 D E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fn ecrm1728 17.28 8 +/Fn 8 117 df68 D70 D97 D102 D<1378EA01FE487E487FA66C +90C7FC6C5AEA007890C8FCB3A2EB0780EA0FFFB5FCA41203C6FCA2137FB3B3AC497E487F +B61280A4195F7BDE25>105 D<010FEB07F8D80FFFEB1FFEB590387FFF809238F81FC091 +3801E03F913903C07FE00003EB0780C6EB0F00140E6D5A0218EB3FC00238EB1F800230EB +0600027090C7FCA2146014E0A25CA55CB3B0497E4813F0B612F8A42B3F7BBE34>114 +D<9138FFC003010FEBF807017FEBFE0F3A01FF003F9FD803F0EB07DF48486DB4FCD80F80 +1300001F8148C8FC003E81007E81127C00FC81A4827EA27E7F6C7E6D91C7FC13F8EA3FFE +381FFFE06C13FF15F0000314FE6C6E7E6C6C14E0011F14F801078001008002077FDA003F +13801507030113C0ED007F00E0ED3FE0161F17F06C150F1607A36C1503A37EA26C16E016 +077E17C06D140F6D15806D141FD8FDF0EC3F00D8F8F8147E017C495A3AF01F801FF06DB5 +12C0D8E00391C7FC39C0007FF02C417CBF35>I<1470A714F0A51301A31303A21307A213 +0FA2131F133F137F13FF1203000F90B6FCB8FCA326000FF0C8FCB3AEEE01C0AE6D6CEB03 +80A316076D6C14005E6D6C130E6D6C131E6E6C5A91383FE0F86EB45A020713C0020090C7 +FC2A597ED734>I E +%EndDVIPSBitmapFont +%DVIPSBitmapFont: Fo ecbx1728 17.28 18 +/Fo 18 117 df68 D<942603FFF8151C94B66C +143C040F03F0147C047F03FC14FC0303B81301030FDAC00113C0033F01F8C7381FF00392 +B500C0913807F807020349C83801FE0F020F01F89238007F1F4A01E0EE3FBF4A49EE0FFF +91B5CA7E494983494983494983495B4949187F4B183F491A1F495B90B5CC120FA2484919 +075A4A19035A4A19015AA24A19005AA348491A7CA35A9AC8FCA35CA2B5FCB07EA26E043F +B81280A47E96C7000701FCC7FCA26C7FA37E80A27E807E807E6C7FA26D7F6D7F7F816D7F +6D6D5F6D7F6D6D5F6D6D7E023F6D5E6E01F05E6E6DEEFE7F020301FF923801FC3F020002 +C0913807F80F033F01FC91381FF007030F903BFFE001FFC001030391B6EA8000DB007F4B +C7123C040F03F8140C040003C091C8FC050301F8CBFC696677E37A>71 +D82 D<001FBD12F0A59126F8000191C7123F4801C0 +060713F849C71700491A7F01F01A1F491A0F491A07A2491A03A290C81801A2007EF300FC +A4007C1C7CA7481C3EA5C91900B3B3B3A5023FB912F8A55F617AE06C>84 +D<913803FFF0027F13FF0103B612E0010F15F890263FFC0013FED97FC090381FFF8049C7 +6C7F4801C06D7F486D6D7F6E6D7F48836E7F84177F84A36C496E7FA26C5B6C5B013FC8FC +90C9FCA75F0307B6FC4AB7FC141F91B5EAF03F0103EBFE00010F13F0013F1380D9FFFEC7 +FC485B485B485B485B485B485BA24890C8FC1A7CA2485AA35FA394B5FC7F6C5D6EEB03DF +6CDB07CFEBC0F86C6DEB0F8F6C6DD91F07EBF3F06C01F8017E14FF6C9027FE01FC0314E0 +C690B5D8F00114C0013F9126C0007F1380010791C7383FFE009026003FF8EC07F846437B +C14D>97 D<903807FF80B6FCA5C6FC7F7FB3A9933801FFE0041F13FE047FEBFFC00381B6 +12F0922687FC0113FC923A9FE0003FFEDBBF8090380FFF8003FEC76C7F4B6E7F4B6E7F4B +6E7F4B824B157F4B82737EA21B80851BC0A31BE085A41BF0AE1BE0A44F13C0A31B80A24F +1300A262197F6F5E6F4B5A4E5B6F4A5BDAFCF84A5BDAF87E4A5B4A6C4A90C7FC9126E01F +C0EB7FFC913BC00FF803FFF8DA8003B612E091C71580013E023F01FCC8FC90C800031380 +4C657CE356>II101 DII105 D<903807FF80B6FCA5C6FC7F7FB3B3B3B3AFB7 +12E0A523647CE32A>108 D110 D<92381FFF804AB512F8020F +14FF023F15C09126FFFC0313F001039039E0007FFC490180EB1FFED91FFEC73807FF8049 +486E7F49486E7F49486E7F48496F7EA248496F7E4884A248496F7EA2481980A24819C091 +C97EA24819E0A5B518F0AD6C19E0A46C6D4B13C0A36C1980A26C6D4B1300A26C606E157F +6C606C6D4B5A6C606D6C4A5B6D6C4A5B6D6C4A5B6D6C6C011F90C7FC010301E0EB7FFC6D +9039FC03FFF86D6CB612E0020F92C8FC020114F8DA001F138044437CC14D>I<903B07FF +8001FFE0B6011F13FE047FEBFFC00381B612F0922687FC0313FC923A9FE0007FFEC6DABF +806D6C7E6D01FEC7000F7F6D496E7F4B824B6E7F4B6E7F4B804B82737EA21B80851BC0A2 +851BE0A4851BF0AE4F13E0A41BC061A21B80A24F1300A24F5AA26F4A5B6F4A5B626F4A5B +6F4A5B03FE4A5B03BF027F90C7FCDB9FC0EBFFFC92268FF8075B0383B612E00380158004 +3F01FCC8FC0403138093CBFCB3A4B712E0A54C5D7CC056>I114 DII E +%EndDVIPSBitmapFont +end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 600dpi +TeXDict begin +%%PaperSize: A4 + +%%EndSetup +%%Page: 1 1 +1 0 bop 290 639 a Fo(Genealogical)56 b(Represen)l(tation)e(of)f(T)-13 +b(rees)52 b(in)g(Databases)1686 822 y Fn(First)46 b(Draft)1247 +1063 y Fm(Miguel)36 b(Sofer)i()1359 1179 +y Fl(Univ)m(ersidad)33 b(T)-8 b(orcuato)33 b(Di)f(T)-8 +b(ella)1728 1295 y(Buenos)33 b(Aires)1797 1411 y(Argen)m(tina)1746 +1606 y(Ma)m(y)h(6,)e(2000)1839 1905 y Fk(Abstract)441 +2035 y Fj(blah)25 b(blah)h(.)13 b(.)g(.)118 2310 y Fi(1)131 +b(In)l(tro)t(duction)118 2491 y Fh(T)-7 b(rees)28 b(are)h(a)g(v)n(ery)f +(frequen)n(t)h(data)f(structure.)41 b(They)30 b(are)e(the)h(natural)g +(represen)n(tation)e(for)i(instance)g(for)f(organiza-)118 +2591 y(tional)f(c)n(harts,)g(threaded)g(discussion)g(groups,)f(some)h +(bills)g(of)h(materials,)e(.)14 b(.)g(.)243 2691 y(A)n(t)28 +b(least)f(t)n(w)n(o)f(alternativ)n(e)h(represen)n(tations)e(for)i +(trees)g(in)h(RDBMs)g(are)e(kno)n(wn)h(and)h(used:)220 +2857 y(1.)41 b Fg(P)m(oin)m(ters:)k Fh(a)31 b(\034eld)h(in)h(the)f(c)n +(hild)g(record)e(references)h(the)h(paren)n(t)f(no)r(de.)50 +b(This)32 b(seems)g(to)f(b)r(e)i(the)f(canonical)326 +2956 y(represen)n(tation.)38 b(Some)29 b(DB)g(engines)f(pro)n(vide)g +(sp)r(ecial)g(SQL)g(extensions)g(to)h(simplify)g(tree)g(searc)n(hes;)e +(Oracle)326 3056 y(tree)d(extensions)g(are)g(an)h(example)f(\(see)h +(for)f(instance)g([1]\);)i(DB2's)f(WITH)g(can)f(b)r(e)i(used)e(for)h +(this)g(purp)r(ose)f(to)r(o)326 3156 y(\(see)j([3],)g(pp)h(139-162\).) +220 3322 y(2.)41 b Fg(Nested)35 b(Sets:)43 b Fh(t)n(w)n(o)30 +b(n)n(umeric)h(\034elds)g(in)g(ev)n(ery)f(no)r(de)h(record)f(co)r(de)h +(the)g(tree)g(structure.)47 b(I)31 b(can't)g(pro)n(vide)f(a)326 +3421 y(b)r(etter)e(or)e(briefer)h(description)g(of)h(this)g(metho)r(d)g +(than)f(the)h(four)f(articles)g([2].)118 3587 y(These)g(t)n(w)n(o)g +(metho)r(ds)h(o\033er)f(di\033eren)n(t)h(adv)-5 b(an)n(tages)25 +b(and)j(disadv)-5 b(an)n(tages:)243 3753 y Ff(\017)41 +b Fh(P)n(oin)n(ters)30 b(are)g(extremely)g(e\036cien)n(t)h(for)f(no)r +(de)h(insertion)f(and/or)g(deletion,)h(but)h(require)e(recursiv)n(e)f +(table)i(ac-)326 3853 y(cesses)e(to)h(searc)n(h)f(the)h(tree)g(\(I)h +(do)f(not)g(kno)n(w)f(the)i(implemen)n(tation)f(details)g(of)g(the)h +(Oracle)e(tree)g(extensions,)326 3953 y(whic)n(h)e(as)g(far)g(as)g(I)g +(kno)n(w)g(ma)n(y)g(solv)n(e)f(this)i(problem)f(in)n(ternally;)g(they)g +(de\034nitely)h(solv)n(e)f(it)g(for)g(the)h(end)g(user\).)243 +4119 y Ff(\017)41 b Fh(Nested)30 b(sets)g(are)f(v)n(ery)f(e\036cien)n +(t)i(for)g(tree)f(searc)n(hes,)g(but)i(are)e(rather)f(exp)r(ensiv)n(e)i +(for)f(no)r(de)h(insertion)f(and/or)326 4218 y(deletion:)37 +b(they)27 b(require)g(up)r(dating)g(p)r(oten)n(tially)h(man)n(y)f(no)r +(des.)243 4384 y(W)-7 b(e)30 b(prop)r(ose)f(here)h(a)g(di\033eren)n(t)h +(represen)n(tation,)e(based)g(on)i(no)r(de)f(iden)n(ti\034ers)g(whic)n +(h)g(are)f(\020genealogical)f(iden)n(ti-)118 4484 y(\034ers\021:)44 +b(they)32 b(con)n(tain)f(the)h(complete)f(genealogy)f(of)h(the)h(no)r +(de,)h(i.e.,)g(the)f(list)g(of)g(ancestors)d(up)j(to)g(the)g(ro)r(ot)f +(of)g(the)118 4584 y(tree.)243 4683 y(This)j(allo)n(ws)f(to)i(replace)e +(man)n(y)h(searc)n(hes)f(in)h(database)g(tables)g(with)h(string)f(op)r +(erations)f(on)h(the)h(index.)58 b(The)118 4783 y(result,)24 +b(as)f(explained)h(in)g(Section)g(3)f(is)h(that)g(tree)f(searc)n(hes)f +(pro)r(ceed)h(at)h(\020nested)f(sets\021)30 b(sp)r(eed,)25 +b(while)f(no)r(de)g(insertions)118 4882 y(and)k(deletions)f(are)f(as)h +(fast)h(as)f(with)h(p)r(oin)n(ters.)243 4982 y(The)i(ob)n(vious)f(do)n +(wnside)h(of)h(the)g(metho)r(d)g(is)f(that)h(the)g(primary)f(k)n(ey)f +(in)i(the)g(tree)f(needs)h(to)f(b)r(e)h(a)g(v)-5 b(ariable)29 +b(size)118 5082 y(text)j(\034eld,)h(and)f(that)g(the)g(iden)n +(ti\034ers)f(ma)n(y)g(b)r(e)i(extremelly)e(long)g(for)g(deep)h(trees.) +49 b(W)-7 b(e)32 b(will)g(pro)n(vide)e(estimates)i(of)118 +5181 y(the)c(size)f(required)g(as)g(a)g(function)h(of)g(the)f +(magnitude)h(of)f(the)h(tree.)1987 5653 y(1)p eop +%%Page: 2 2 +2 1 bop 118 291 a Fi(2)131 b(Genealogical)45 b(iden)l(ti\034ers)g(for)f +(trees)118 489 y Fm(2.1)112 b(De\034nition)118 642 y +Fh(W)-7 b(e)28 b(de\034ne)g Fe(gene)l(alo)l(gic)l(al)k(identi\034ers)j +Fh(recursiv)n(ely)25 b(as)i(follo)n(ws:)326 808 y Fg(De\034nition:)59 +b Fe(The)42 b(gene)l(alo)l(gic)l(al)h(identi\034er)f(\(gID\))e(of)i(a)f +(no)l(de)h(is)f(obtaine)l(d)h(by)g(app)l(ending)g(a)f(child)326 +908 y(identi\034er)30 b(to)g(the)g(gene)l(alo)l(gic)l(al)h +(identi\034er)g(of)f(the)g(p)l(ar)l(ent)f(no)l(de.)243 +1074 y Fh(Remark)40 b(that)h(genealogical)e(iden)n(ti\034ers)i(are)f +(rather)g(w)n(ell)h(kno)n(wn)f(and)h(used;)48 b(common)41 +b(examples)f(are)g(the)118 1174 y(\020path+\034le-name\021)33 +b(in)28 b(a)f(computer)g(\034le)h(system)f(and)h(the)f(URLs)h(within)g +(a)f(WWW.)243 1273 y(The)d(name)g(\020genealogical)e(iden)n +(ti\034er\021)30 b(is)24 b(suggested)g(b)n(y)g(the)g(fact)h(that)f(the) +h(v)-5 b(alue)24 b(of)g(the)h(iden)n(ti\034er)f(con)n(tains)f(the)118 +1373 y(complete)30 b(genealogy)d(of)j(the)g(no)r(de:)41 +b(it)30 b(con)n(tains)e(as)h(a)h(substring)f(the)h(gID)f(of)h(its)g +(father,)g(whic)n(h)f(in)h(turn)g(con)n(tains)118 1472 +y(as)d(a)g(substring)g(the)h(gID)g(of)f(the)h(grandfather,)e(.)14 +b(.)g(.)243 1572 y(The)27 b(ro)r(ot)g(no)r(de)h(of)f(the)h(tree)f(has)g +(a)h(gID)f(with)h(v)-5 b(alue)28 b(\021)34 b(\(the)28 +b(empt)n(y)g(string\),)f(as)g(it)h(has)f(no)g(paren)n(t.)118 +1804 y Fm(2.2)112 b(Child)36 b(iden)m(ti\034ers)118 1958 +y Fh(The)26 b(ob)n(vious)e(c)n(hild)i(iden)n(ti\034er)g(is)f(a)h +(zero-based)d(coun)n(ter:)35 b(iden)n(tify)26 b(the)h(c)n(hild)e(b)n(y) +h(the)g(n)n(um)n(b)r(er)f(of)h(older)f(brethren)g(it)118 +2057 y(has.)243 2157 y(W)-7 b(e)25 b(could)f(represen)n(t)g(the)h(coun) +n(ter)f(in)h(base)f(10;)h(this)g(ho)n(w)n(ev)n(er)e(is)i(extremely)f(w) +n(asteful)g(of)h(resources.)34 b(It)25 b(is)g(m)n(uc)n(h)118 +2257 y(b)r(etter)33 b(to)f(represen)n(t)f(the)h(coun)n(ter)g(in)g(as)g +(large)e(a)i(base)g(as)f(p)r(ossible:)46 b(in)n(terpret)32 +b(as)f(n)n(um)n(b)r(ers)h(a)g(set)g(of)g(c)n(haracters)118 +2356 y(larger)26 b(than)h({0,1,.)14 b(.)g(.)g(9}.)243 +2456 y(As)26 b(tree)f(op)r(erations)f(will)i(in)n(v)n(olv)n(e)f(string) +g(op)r(erations)f(on)i(the)g(indices,)g(in)g(order)f(to)g(a)n(v)n(oid)g +(a)g(\020quoting)g(hell\021)33 b(it)26 b(is)118 2555 +y(desirable)d(to)h(a)n(v)n(oid)e(using)h(an)n(y)g(c)n(haracter)f(with)i +(a)g(sp)r(ecial)f(meaning)h(in)g(LIKE)g(expressions)e(or)g(regular)g +(expressions;)118 2655 y(i.e.,)28 b(w)n(e)f(will)h(not)f(use)h(an)n(y)f +(of)g(the)h(sym)n(b)r(ols)70 b Fd(.)44 b(*)f(^)g(\\)g([)g(])g({)h(})f +(\()g(\))g(<)g(>)71 b Fh(?)37 b(|)28 b(&)f($)243 2755 +y(W)-7 b(e)28 b(prop)r(ose)e(to)h(reserv)n(e)f(also)g(/)i(as)f(a)g +(separator)e(\(see)i(\020V)-7 b(ariable)27 b(Sized)g(gID\021)34 +b(b)r(elo)n(w\).)243 2854 y(If)g(w)n(e)f(limit)i(ourselv)n(es)d(to)i +(ascii)f(c)n(haracters,)g(and)h(a)n(v)n(oid)e(to)i(b)r(e)g(safe)f(a)h +(lot)g(of)g(other)f(c)n(haracters,)g(w)n(e)g(can)h(use)118 +2954 y(n)n(um)n(b)r(ers)27 b(in)h(base)f(64)g(b)n(y)g(represen)n(ting) +243 3120 y Ff(\017)41 b Fh(0-9)26 b(with)i('0'-'9')f(\(dec)g(ascii)g +(co)r(de)h(48-57\))243 3286 y Ff(\017)41 b Fh(10)26 b(with)i(':')37 +b(\(dec)28 b(ascii)f(co)r(de)h(58\))243 3452 y Ff(\017)41 +b Fh(11)26 b(with)i(';')g(\(dec)g(ascii)f(co)r(de)g(59\))243 +3618 y Ff(\017)41 b Fh(12-37)25 b(with)j('A'-'Z')g(\(dec)f(ascii)g(co)r +(de)h(65-90\))243 3784 y Ff(\017)41 b Fh(38-63)25 b(with)j('a'-'z')f +(\(dec)h(ascii)f(co)r(de)g(97-122\))118 3950 y(By)g(using)g(base)f(64,) +h(up)g(to)h(4096)d(c)n(hildren)i(can)f(b)r(e)i(represen)n(ted)e(using)h +(t)n(w)n(o)f(suc)n(h)h(digits,)g(up)h(to)f(262144)d(with)k(three)118 +4050 y(digits,)g(and)f(up)h(to)f(16777216)d(with)k(four)f(digits.)243 +4149 y(If)37 b(the)g(RDBMs)g(supp)r(orts)f(in)n(ternational)g(c)n +(haracters,)h(it)g(is)g(p)r(ossible)f(to)h(further)f(increase)g(the)h +(base;)k(as)36 b(an)118 4249 y(example,)30 b(b)n(y)f(using)g(the)h(95)f +(additional)g(c)n(haracters)e(of)i(the)h(latin-1)f(c)n(haracter)e(set,) +k(w)n(e)e(could)g(co)r(de)g(n)n(um)n(b)r(ers)g(in)h(a)118 +4349 y(base)f(up)g(to)g(160)f(\025)g(remark)g(that)h(ev)n(ery)f(single) +h(digit)g(is)g(still)h(one)e(b)n(yte)h(in)h(this)f(represen)n(tation.) +40 b(This)29 b(means)f(that)118 4448 y(w)n(e)f(expand)h(the)f(sym)n(b)r +(ols)g(ab)r(o)n(v)n(e)f(b)n(y)i(represen)n(ting)243 4614 +y Ff(\017)41 b Fh(64-159)25 b(with)j(dec)f(latin1)g(co)r(de)h(160-255) +243 4780 y(In)23 b(base)g(160,)g(up)g(to)h(25600)d(c)n(hildren)i(can)f +(b)r(e)i(represen)n(ted)e(using)h(t)n(w)n(o)g(digits,)h(up)g(to)f +(4096000)d(with)k(three)f(digits,)118 4880 y(and)28 b(up)f(to)h +(6.5E+08)e(with)i(four)f(digits.)243 4980 y(Remark)g(that)h(base)f(con) +n(v)n(ersions)f(only)h(need)i(to)e(b)r(e)i(p)r(erformed)e(at)h +(insertion)g(time,)g(when)h(the)f(index)g(of)g(a)g(new)118 +5079 y(no)r(de)g(is)f(computed.)37 b(They)28 b(will)f(therefore)g(only) +g(ha)n(v)n(e)f(an)i(impact)f(on)h(insertion)f(timings.)1987 +5653 y(2)p eop +%%Page: 3 3 +3 2 bop 118 291 a Fm(2.3)112 b(Coun)m(ters:)50 b(\020delimited\021)44 +b(vs.)51 b(\020\034xed)38 b(size\021)118 444 y Fh(The)33 +b(standard)g(represen)n(tation)e(of)i(gID)h(uses)e(a)h(v)-5 +b(ariable)32 b(size)h(c)n(hild)h(iden)n(ti\034er,)g(and)f(delimiters)g +(to)h(separate)d(the)118 543 y(gID)f(of)g(the)h(c)n(hild)f(no)r(de)g +(from)f(the)i(gID)f(of)g(its)g(paren)n(t.)43 b(F)-7 b(or)30 +b(example,)g(w)n(e)g(can)f(represen)n(t)g(the)i(\034fth)g(c)n(hild)f +(of)g(no)r(de)118 643 y('/23/27/1')24 b(as)j('/23/27/1/4'.)32 +b(Let)c(us)f(call)g(this)h(a)f Fg(vgID)h Fh(represen)n(tation)e(\(V)-7 +b(ariable)27 b(Size)h(Genealogical)d(ID\).)243 743 y(This)30 +b(represen)n(tation)f(allo)n(ws)f(for)i(an)n(y)g(n)n(um)n(b)r(er)g(of)g +(c)n(hildren)g(of)h(a)f(no)r(de,)h(sub)5 b(ject)30 b(only)g(to)g(the)h +(limitations)f(the)118 842 y(RDBMS)e(ma)n(y)f(ha)n(v)n(e)f(as)h(to)h +(the)g(length)f(of)h(a)f(v)-5 b(ariable)27 b(sized)g(string.)243 +942 y(Alternativ)n(ely)-7 b(,)24 b(w)n(e)f(could)h(c)n(ho)r(ose)f(to)h +(limit)g(from)g(the)g(outset)g(the)g(quan)n(tit)n(y)g(of)f(c)n(hildren) +h(that)g(a)g(no)r(de)g(ma)n(y)f(ha)n(v)n(e;)118 1042 +y(this)28 b(limit)g(w)n(ould)f(dep)r(end)i(of)e(course)f(on)i(the)g +(application.)36 b(Let)27 b(us)h(call)f(this)h(a)f Fg(fgID)h +Fh(represen)n(tation.)243 1141 y(F)-7 b(or)25 b(example,)h(if)g(no)g +(no)r(de)f(is)h(allo)n(w)n(ed)f(to)g(ha)n(v)n(e)g(more)g(than)h(25600)d +(c)n(hildren,)j(w)n(e)g(could)f(represen)n(t)g(the)h(coun)n(ters)118 +1241 y(alw)n(a)n(ys)36 b(with)i(2)f(digits.)67 b(The)38 +b(no)r(de)f(whic)n(h)h(w)n(as)f(previously)f('/23/27/1/4')d(is)k(no)n +(w)g('23270104'.)64 b(If)38 b(w)n(e)f(require)118 1340 +y(a)g(three)g(digit)h(represen)n(tation)d(of)i(no)r(des)g(\(up)h(to)f +(ab)r(out)h(4)f(million)g(c)n(hildren\),)j(then)d(it)h(will)g(b)r(e)f +(represen)n(ted)f(as)118 1440 y('023027001004'.)118 1672 +y Fm(2.4)112 b(Ordering)37 b(of)h(no)s(des)118 1825 y +Fh(F)-7 b(or)35 b(some)g(applications)g(it)h(is)f(necessary)f(to)i +(obtain)f(subtrees)g(ordered)f(according)g(to)i(some)f(sp)r(ecial)g +(rules.)60 b(F)-7 b(or)118 1925 y(instance:)220 2090 +y(1.)41 b(the)34 b(complete)g(subtree)f(starting)g(at)h(a)f(no)r(de)h +(is)g(listed)g(immediately)g(after)f(the)i(no)r(de)f(in)g(question)f +(\(\020depth)326 2189 y(\034rst\021\))220 2354 y(2.)41 +b(no)r(des)27 b(with)h(a)f(common)g(paren)n(t)g(are)g(listed)g(c)n +(hronologically)243 2519 y(F)-7 b(or)39 b(instance,)k(the)d(displa)n(y) +f(of)h(an)f(organization)f(c)n(hart)h(is)g(usually)h(required)e(to)i +(satisfy)g(at)f(least)h(the)g(\034rst)118 2619 y(condition.)h(In)29 +b(a)g(threaded)f(discussion)h(group)e(one)i(wishes)g(to)f(satisfy)h(b)r +(oth)h(conditions)e(to)h(displa)n(y)f(the)h(messages)118 +2718 y(in)20 b(a)g(thread)g(\025)f(the)i(threads)e(themselv)n(es)h +(\(i.e.,)i(c)n(hildren)e(of)g(the)g(ro)r(ot)f(no)r(de\))i(are)e +(usually)g(listed)i(in)f(in)n(v)n(erse)f(c)n(hronolical)118 +2818 y(order.)243 2917 y(T)-7 b(o)35 b(mak)n(e)f(a)h(particular)f +(ordering)g(e\036cien)n(t,)j(it)f(w)n(ould)f(b)r(e)h(a)f(nice)g +(feature)g(if)h(it)g(could)f(b)r(e)h(made)f(to)g(coincide)118 +3017 y(with)28 b(a)f(lexicographic)f(ordering)f(of)j(the)g(indices)f +(\025i.e.,)g(as)g(pro)r(duced)g(b)n(y)h(an)f(\020ORDER)h(BY)f(id)h +(ASC\021)35 b(in)27 b(SQL.)h(The)118 3117 y(lexicographic)d(ordering)h +(of)h(fgID)h(satis\034es)e(b)r(oth)i(conditions.)36 b(The)27 +b(lexicographic)f(ordering)f(of)i(vgID)g(as)g(describ)r(ed)118 +3216 y(ab)r(o)n(v)n(e)34 b(satis\034es)g(the)h(\034rst)g(requisite)f +(if)i(the)f(separator)d(has)j(the)g(minimal)g(binary)g(represen)n +(tation)e(of)i(all)f(allo)n(w)n(ed)118 3316 y(sym)n(b)r(ols)c(in)h(an)f +(index)h(\025)f(this)h(is)g(wh)n(y)f(w)n(e)g(reserv)n(ed)f(/)h(for)g +(the)i(separator.)43 b(But)31 b(the)g(second)f(prop)r(ert)n(y)g(is)g +(missing:)118 3416 y(for)d(instance,)g(the)h(index)g('/1/10')d(is)j +(lexicographically)d(b)r(efore)i('/1/2'.)243 3515 y(If)c(the)h(second)e +(prop)r(ert)n(y)g(is)i(also)e(required)g(for)h(vgID,)g(w)n(e)f(can)h +(sp)r(ecify)h(the)f(c)n(hild)h(iden)n(ti\034ers)e(with)i(coun)n(ters)e +(built)118 3615 y(in)28 b(the)g(follo)n(wing)e(w)n(a)n(y:)36 +b(represen)n(t)26 b(a)h(n)n(um)n(b)r(er)h(b)n(y)f(a)g(string)g(of)g +(digits,)h(where)243 3779 y Ff(\017)41 b Fh(the)25 b(\034rst)g(digit)h +Fc(D)896 3791 y Fb(0)958 3779 y Fh(represen)n(ts)e(the)i(length)f(in)h +(digits)f(of)g(the)h(decimal)f(expansion)f(of)i(the)f(n)n(um)n(b)r(er,) +h(min)n(us)f(one)243 3945 y Ff(\017)41 b Fh(the)28 b(follo)n(wing)e +Fa(\()p Fc(D)920 3957 y Fb(0)976 3945 y Fa(+)18 b(1\))27 +b Fh(digits)h(are)e(the)i(decimal)g(expansion)e(of)i(the)g(n)n(um)n(b)r +(er)118 4109 y(Let)g(us)f(call)h(these)f(iden)n(ti\034ers)g +Fg(m-vgID)p Fh(,)g(\020m\021)34 b(for)27 b(mo)r(di\034ed.)243 +4209 y(As)e(an)f(example,)h(the)g(no)r(de)g(whic)n(h)g(w)n(as)f +(previously)f(represen)n(ted)h(b)n(y)g(/15/3/182)d(will,)k(after)g +(this)g(mo)r(di\034cation,)118 4309 y(ha)n(v)n(e)h(the)i(index)g +(/115/03/2182.)243 4408 y(The)37 b(lexicographic)f(ordering)g(of)i +(m-vgID)f(is)h(the)g(desired)f(ordering)f(of)h(the)h(tree)g(no)r(des.) +67 b(The)38 b(cost)f(of)g(this)118 4508 y(prop)r(ert)n(y)31 +b(is)i(that)f(\(a\))h(the)g(ID)f(are)g(no)n(w)g(longer,)g(\(b\))h(no)f +(no)r(de)g(can)g(ha)n(v)n(e)g(more)f(than)i Fa(160)3106 +4478 y Fb(160)3240 4508 y Fh(c)n(hildren)f(\(actually)-7 +b(,)118 4607 y(this)32 b(is)g(a)f(non-issue\),)h(and)f(\(c\))h(the)g +(index)g(structure)f(is)h(redundan)n(t,)g(some)f(formally)f(correct)h +(indices)g(are)g(in)n(v)-5 b(alid)118 4707 y(\025e.g.,)24 +b(/316/013/11.)30 b(The)24 b(third)g(issue)g(can)g(b)r(e)g(addressed)f +(b)n(y)g(k)n(eeping)g(a)h(strict)g(con)n(trol)e(on)i(the)g(generation)f +(of)h(new)118 4807 y(indices)k(to)f(insure)g(that)h(all)f(indices)h +(are)e(formally)h(correct.)243 4906 y(The)32 b(issue)f(of)h(the)g(rev)n +(erse)e(c)n(hronological)f(indexing)j(of)f(threads)h(in)g(threaded)f +(discussion)g(groups)g(can)g(b)r(e)h(ad-)118 5006 y(dressed)d(easily)f +(enough)h(in)h(fgID:)f(coun)n(t)g(\020do)n(wn\021)36 +b(instead)29 b(of)g(\020up\021)36 b(the)30 b(c)n(hildren)f(of)g(the)h +(ro)r(ot)e(no)r(de)i(\025)f(this)h(implies)118 5106 y(only)e(an)g +(inconsequen)n(tial)f(mo)r(di\034cation)h(of)g(the)g(no)r(de)h +(insertion)e(routine,)h(as)g(sho)n(wn)f(b)r(elo)n(w.)38 +b(The)29 b(problem)e(is)h(less)118 5205 y(trivial)i(with)g(vgID;)h(in)f +(this)h(case,)f(ma)n(yb)r(e)f(a)h(thread)g(iden)n(ti\034er)g(should)g +(b)r(e)h(k)n(ept)f(in)g(a)g(di\033eren)n(t)g(\034eld)h(-)f(i.e.,)h +(repre-)118 5305 y(sen)n(ting)h(the)h(structure)f(as)g(a)h(forest)f +(rather)f(than)i(a)f(tree,)i(where)e(the)h(thread_id)f(\034eld)h +(selects)f(the)h(\020tree\021)38 b(in)33 b(the)118 5404 +y(forest.)1987 5653 y(3)p eop +%%Page: 4 4 +4 3 bop 118 291 a Fi(3)131 b(T)-11 b(ree)45 b(op)t(erations)e(using)h +(genealogical)g(indices)118 472 y Fh(In)32 b(this)f(section)g(w)n(e)g +(sho)n(w)g(ho)n(w)g(to)g(implemen)n(t)h(v)-5 b(arious)30 +b(tree)h(op)r(erations)f(using)h(gID)g(as)g(the)h(primary)e(k)n(ey)h +(in)g(the)118 572 y(no)r(de)d(table.)243 672 y(Some)h(implemen)n +(tation)h(issues)g(are)f(relev)-5 b(an)n(t)29 b(here,)h(esp)r(ecially)f +(concerning)g(the)h(utilisation)g(of)g(indices)g(b)n(y)f(the)118 +771 y(DB)f(engine.)243 871 y(W)-7 b(e)28 b(discuss)f(a)g(tree)g +(represen)n(ted)f(in)i(a)f(table)h(of)f(the)h(form)326 +1034 y Fd(CREATE)41 b(TABLE)g(tree)h(\()456 1134 y(gid)304 +b(text)42 b(PRIMARY)f(KEY,)456 1234 y(nchildren)f(integer)h(DEFAULT)f +(0,)456 1333 y(\\ldots)h(the)i(actual)e(node)h(data)326 +1433 y(\);)118 1597 y Fh(The)26 b(\034eld)g(\020nc)n(hildren\021)32 +b(is)26 b(a)f(coun)n(ter)g(for)g(the)i(n)n(um)n(b)r(er)e(of)h(c)n +(hildren)f(that)h(the)h(no)r(de)f(has)f Fe(ever)35 b +Fh(had;)27 b(w)n(e)e(assume)g(here)118 1696 y(it)j(is)g(not)f(up)r +(dated)h(when)g(no)r(des)f(or)g(subtrees)g(are)f(deleted.)243 +1796 y(Section)h(4)g(pro)n(vides)f(a)i(complete)f(implemen)n(tation)h +(of)f(these)h(op)r(erations)e(for)h(fgID)h(in)g(P)n(ostgreSQL.)118 +2028 y Fm(3.1)112 b(Computing)37 b(the)g(lev)m(el)f(of)h(a)h(no)s(de) +118 2181 y Fg(Cost:)f Fe(string)30 b(op)l(er)l(ations)g(\(no)g(table)g +(ac)l(c)l(ess\))243 2280 y Fh(This)d(is)h(a)f(pure)g(string)g(op)r +(eration,)f(no)i(table)f(access)g(is)g(required.)243 +2460 y Ff(\017)41 b Fg(vgID:)27 b Fh(coun)n(t)h(the)g(n)n(um)n(b)r(er)f +(of)g(separators)e(\('/'\))j(in)g(the)g(PK)243 2625 y +Ff(\017)41 b Fg(fgID:)27 b Fh(coun)n(t)g(the)h(n)n(um)n(b)r(er)g(of)f +(c)n(haracters)e(in)j(the)g(PK,)g(divide)g(b)n(y)f(the)h(\034xed)f +(size)h(of)f(the)h(coun)n(ters.)118 2857 y Fm(3.2)112 +b(Selecting)36 b(or)h(deleting)f(a)i(subtree)118 3010 +y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l(e)l(e)243 +3173 y Ff(\017)41 b Fg(vgID:)27 b Fh(The)h(subtree)f(ro)r(oted)g(at)g +(/26/5/7)e(is)i(selected)g(b)n(y)508 3338 y Fd(...)43 +b(WHERE)e(id)i(LIKE)f('/26/5/7\045')d(AND)j(id)h(<)g('/26/5/70')243 +3503 y Ff(\017)e Fg(m-vgID:)26 b Fh(The)h(subtree)h(ro)r(oted)e(at)i +(/126/05/07)22 b(is)28 b(selected)f(b)n(y)508 3668 y +Fd(...)43 b(WHERE)e(id)i(LIKE)f('/126/06/07\045')243 +3833 y Ff(\017)f Fg(fgID:)27 b Fh(The)h(subtree)f(ro)r(oted)g(at)g +(260507)e(is)i(selected)h(b)n(y)508 3997 y Fd(...)43 +b(WHERE)e(id)i(LIKE)f('260507\045')118 4229 y Fm(3.3)112 +b(Selecting)36 b(the)h(direct)f(c)m(hildren)g(of)i(a)g(no)s(de)118 +4382 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l(e)l(e)243 +4562 y Ff(\017)41 b Fg(vgID:)27 b Fh(The)h(direct)f(c)n(hildren)g(of)h +(/26/5/7)c(are)j(selected)g(b)n(y)508 4727 y Fd(...)43 +b(WHERE)e(id)i(LIKE)f('/26/5/7/\045')d(AND)j(id)h(NOT)f(LIKE)g +('26/5/7/\045/\045')243 4892 y Ff(\017)f Fg(m-vgID:)26 +b Fh(The)h(direct)h(c)n(hildren)f(of)g(/26/5/7)e(are)h(selected)i(b)n +(y)508 5056 y Fd(...)43 b(WHERE)e(id)i(LIKE)f('/126/06/07/\045')37 +b(AND)43 b(id)f(NOT)h(LIKE)f('/126/05/07/\045/\045)o(')243 +5221 y Ff(\017)f Fg(fgID:)27 b Fh(The)h(direct)f(c)n(hildren)g(of)h +(260507)c(are)j(selected)g(b)n(y)508 5386 y Fd(...)43 +b(WHERE)e(id)i(LIKE)f('260507\045')d(AND)k(char_length\(id\))37 +b(=)43 b(\(char_length\('26)o(05)o(07')o(\)+)o(2\))1987 +5653 y Fh(4)p eop +%%Page: 5 5 +5 4 bop 118 291 a Fm(3.4)112 b(Inserting)37 b(a)h(no)s(de)g(or)f(a)h +(subtree)118 444 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l +(e)l(e)f(+)h(string)f(and)h(math)g(op)l(er)l(ations)243 +543 y Fh(Insertion)f(is)g(a)h(pro)r(cedural)e(op)r(eration.)42 +b(As)30 b(eac)n(h)f(RDBMS)h(has)f(a)h(di\033eren)n(t)f(w)n(a)n(y)g(of)g +(de\034ning)h(pro)r(cedures,)f(w)n(e)118 643 y(will)f(just)g(describ)r +(e)f(here)g(the)h(necessary)e(steps.)37 b(Examples)27 +b(for)g(P)n(ostgreSQL)f(are)h(pro)n(vided)f(in)i(4.)243 +743 y(In)22 b(order)f(to)h(insert)g(a)g(new)g(c)n(hild)h(of)f +(\020daddy\021)28 b(\(either)23 b(one)f(of)g(/26/5/7,)e(/126/05/07)d +(or)22 b(260507)d(in)k(the)f(examples)118 842 y(ab)r(o)n(v)n(e\))27 +b(y)n(ou)f(ha)n(v)n(e)h(to)220 1008 y(1.)41 b(add)27 +b(one)g(to)h(the)g(n)n(um)n(b)r(er)f(of)g(c)n(hildren)h(of)f +(\020daddy\021)508 1174 y Fd(UPDATE)41 b(tree)h(SET)h(nchildren)c(=)k +(\(nchildren)d(+)j(1\))g(WHERE)e(ID)i(=)g(``daddy'';)220 +1340 y Fh(2.)e(enco)r(de)27 b(the)h(n)n(um)n(b)r(er)f(of)g(c)n(hildren) +g(of)h(\020daddy\021)33 b(in)28 b(base)f(160,)f(bring)h(it)h(to)f(the)h +(correct)e(format)h(dep)r(ending)h(on)326 1440 y(the)c(v)-5 +b(arian)n(t)23 b(of)h(gID)g(\(pad)g(with)h(0)e(or)g(not,)i(prep)r(end)f +(a)g(digit)g(coun)n(ter)f(or)g(not,)i(prep)r(end)f(/)g(or)f(not,)i +(coun)n(t)e(do)n(wn)326 1540 y(or)j(up,)i(.)14 b(.)g(.)g(\))37 +b(and)28 b(app)r(end)f(it)h(to)g(daddy's)f(gID)g(to)h(obtain)f(the)h +(new)g(no)r(de's)f(gID.)220 1706 y(3.)41 b(insert)27 +b(the)h(new)f(no)r(de)243 1872 y(When)35 b(inserting)g(a)f(subtree,)j +(the)e(index)g(of)g(the)h(ro)r(ot)e(of)h(the)g(subtree)g(has)f(to)h(b)r +(e)h(computed)f(as)f(ab)r(o)n(v)n(e,)i(and)118 1971 y(prep)r(ended)28 +b(to)f(the)h(index)g(of)f(eac)n(h)g(no)r(de)h(of)f(the)h(subtree)f(b)r +(efore)h(insertion.)243 2071 y(Remark)e(that)i(only)f(the)h(paren)n(t)f +(no)r(de)h(has)f(to)g(b)r(e)h(up)r(dated)g(on)f(insertion.)118 +2303 y Fm(3.5)112 b(Selecting)36 b(the)h(ancestors)h(of)g(a)g(no)s(de) +118 2457 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l(e)l(e)243 +2556 y Fh(Y)-7 b(ou)27 b(can)g(sp)r(ecify)h(all)g(ancestors)d(of)j(a)f +(no)r(de)h(in)f(a)h(single)f(SQL)g(statemen)n(t;)g(for)g(instance)h +(for)f(vgID)326 2722 y Fd(...)42 b(WHERE)f('/25/6/7')f(LIKE)i(\(id)g +(||)h('/\045'\))f(AND)g(id)h(<)g('/25/6/7')118 2888 y +Fh(The)31 b(second)e(part)h(of)h(the)g(clause,)f(while)h(logically)e +(redundan)n(t,)h(is)h(a)f(\020hin)n(t\021)37 b(to)30 +b(the)h(optimizer.)45 b(A)n(t)31 b(least)f(in)g(P)n(ost-)118 +2988 y(greSQL,)c(without)i(it)g(the)g(optimizer)f(will)h(c)n(ho)r(ose)e +(a)i(sequen)n(tial)e(scan)h(of)h(the)g(table)f(and)h(disregard)d(the)j +(index.)118 3220 y Fm(3.6)112 b(Selecting)36 b(all)g(lea)m(v)m(es)118 +3374 y Fg(Cost:)h Fe(sc)l(an)30 b(of)g(the)g(tr)l(e)l(e)243 +3473 y Fh(A)e(leaf)f(is)g(a)h(no)r(de)f(without)h(descendan)n(ts:)36 +b(it)28 b(has)f(0)g(c)n(hildren.)37 b(Hence)326 3639 +y Fd(...)42 b(WHERE)f(nchildren)f(=)j(0)118 3805 y Fh(If)28 +b(this)g(t)n(yp)r(e)g(of)f(query)g(is)h(often)f(necessary)-7 +b(,)26 b(y)n(ou)h(ma)n(y)g(b)r(e)h(w)n(ell)f(advised)g(to)g(k)n(eep)g +(an)h(index)f(on)h(tree\(nc)n(hildren\).)118 4038 y Fm(3.7)112 +b(Determining)35 b(if)i(A)g(is)g(a)h(descendan)m(t)g(of)g(B)118 +4191 y Fg(Cost:)f Fe(string)30 b(op)l(er)l(ations,)h(no)f(table)g(ac)l +(c)l(ess)243 4291 y Fh(This)d(is)h(a)f(pure)g(string)g(op)r(eration)f +(on)i(the)g(indices,)f(no)g(table)h(access)e(is)i(necessary)-7 +b(.)118 4565 y Fi(4)131 b(Putting)45 b(it)f(all)h(together:)57 +b(a)44 b(P)l(ostgreSQL)f(implemen)l(tation)118 4747 y +Fh(h)n(ttp://www.p)r(ostgresql.org/mhonarc/pgsq)o(l-sql/)o(20)o(00)o +(-0)o(4/)o(msg0)o(02)o(67)o(.h)n(tml)243 4847 y(W)-7 +b(e)30 b(describ)r(e)g(here)g(a)g(small)f(pac)n(k)-5 +b(age)29 b(that)i(can)e(b)r(e)i(used)f(for)g(implemen)n(ting)g(gID)g +(on)g(P)n(ostgreSQL.)f(It)i(can)e(b)r(e)118 4946 y(found)f(at)f()243 5046 y(The)21 b(pac)n(k)-5 b(age)21 b(uses)g(the)h(pro) +r(cedural)e(language)h(PL/PGsql.)35 b(A)22 b(b)r(etter)g(implemen)n +(tation)g(w)n(ould)f(probably)g(de\034ne)118 5145 y(the)28 +b(gID)g(as)f(new)g(P)n(ostgres)f(t)n(yp)r(es,)i(and)f(co)r(de)g(all)h +(this)g(in)f(C.)243 5245 y(The)g(\034les)h(should)f(b)r(e)h(loaded)f +(in)h(alphab)r(etical)f(order.)1987 5653 y(5)p eop +%%Page: 6 6 +6 5 bop 118 291 a Fm(4.1)112 b(tree0_enco)s(ding.sql)118 +444 y Fh(This)28 b(\034le)f(de\034nes)h(and)f(p)r(opulates)h(the)f +(table)h(_b160_digits)d(of)j(\020digits\021)33 b(in)28 +b(base)f(160,)326 604 y Fd(CREATE)41 b(TABLE)g(\\_b160\\_digits)d +(\(deci)j(integer,)f(code)i(char\);)118 764 y Fh(and)28 +b(the)f(t)n(w)n(o)g(functions)326 924 y Fd(CREATE)41 +b(FUNCTION)f(\\_b160\\_encode\(i)o(nt)o(eg)o(er\))d(RETURNS)j(string) +413 1024 y(AS)j('....')e(LANGUAGE)f('plpgsql';)326 1124 +y(CREATE)h(FUNCTION)f(\\_b160\\_encode\(i)o(nt)o(eg)o(er,)o(in)o(te)o +(ger)o(\))d(RETURNS)k(string)413 1223 y(AS)i('....')e(LANGUAGE)f +('plpgsql';)118 1384 y Fh(The)22 b(\034rst)h(function)f(returns)g(a)g +(v)-5 b(ariable)21 b(size)h(enco)r(ding;)i(the)f(second)e(a)h(\034xed)h +(size)f(enco)r(ding)g(\(the)h(second)e(parameter)118 +1483 y(is)g(the)h(size\),)g(and)f(raises)e(an)i(exception)g(if)h(the)f +(n)n(um)n(b)r(er)g(is)g(to)r(o)g(large)e(to)i(b)r(e)h(represen)n(ted)e +(with)h(the)h(requested)e(n)n(um)n(b)r(er)118 1583 y(of)28 +b(digits.)118 1814 y Fm(4.2)112 b(tree1_de\034ne.sql)118 +1967 y Fh(This)28 b(\034le)f(pro)n(vides)f(a)i(function)326 +2127 y Fd(CREATE)41 b(FUNCTION)f(_tree_create\(tex)o(t,)o(in)o(teg)o +(er)o(,t)o(ext)o(,t)o(ex)o(t\))d(RETURNS)k(bpchar)413 +2227 y(AS)i('....')e(LANGUAGE)f('plpgsql';)118 2387 y +Fh(that)e(creates)f(a)h(tree)f(infrastructure)g(of)h(either)g(fgID)g +(or)f(vgID.)h(Assuming)f(y)n(ou)g(ha)n(v)n(e)g(a)h(table)f(\020m)n +(ytable\021)44 b(with)118 2487 y(primary)26 b(k)n(ey)h(\020m)n +(yid\021,)g(then)h(calling)326 2647 y Fd(SELECT)41 b(_tree_create\('m)o +(yt)o(ree)o(',)o(2,')o(my)o(ta)o(ble)o(',)o('m)o(yid)o('\))o(;)118 +2807 y Fh(will)28 b(cause:)220 2967 y(1.)41 b(the)28 +b(creation)e(of)i(a)f(table)508 3131 y Fd(CREATE)41 b(TABLE)h +(mytree_bkg\()683 3230 y(gid)g(text)g(PRIMARY)e(KEY,)683 +3330 y(nchildren)f(int,)683 3429 y(sid)j(integer)f(REFERENCES)e +(mytable\(myid\))508 3529 y(\);)508 3629 y(CREATE)i(UNIQUE)g(INDEX)h +(mytree_bkg_sid)37 b(ON)43 b(mytree_bkg\(sid\);)326 3792 +y Fh(for)27 b(the)h(tree)f(structure.)220 3955 y(2.)41 +b(the)28 b(creation)e(of)i(a)f(view)508 4118 y Fd(CREATE)41 +b(VIEW)h(mytree)f(AS)639 4218 y(SELECT)g(t.gid,n.*)900 +4317 y(FROM)h(mytable)f(n,)i(mytree_bkg)c(t)900 4417 +y(WHERE)j(t.sid=n.myid;)326 4580 y Fh(with:)35 b(a)23 +b(trigger)e(on)i(UPD)n(A)-7 b(TE)25 b(that)e(blo)r(c)n(ks)g(up)r +(dating)g(the)h(gid)f(and)g(allo)n(ws)f(up)r(dating)h(the)g(no)r(de)h +(data,)f(a)g(rule)326 4680 y(on)k(DELETE)i(that)f(deletes)f(the)h +(corresp)r(onding)e(en)n(try)h(b)r(oth)h(in)g(m)n(ytree_bkg)d(and)j(m)n +(ytable,)f(and)g(a)g(trigger)326 4779 y(ON)h(INSER)-7 +b(T)30 b(that)f(raises)e(an)h(exception)g(and)g(informs)h(the)f(user)g +(to)h(use)f(the)h(insertion)f(function)h(describ)r(ed)326 +4879 y(b)r(elo)n(w.)220 5042 y(3.)41 b(t)n(w)n(o)26 b(insertion)h +(functions)h(that)g(compute)g(automatically)e(the)i(gID)g(of)f(the)h +(new)g(no)r(de:)425 5205 y Ff(\017)41 b Fh(a)27 b(function)i(m)n +(ytree_insert\(text,text,in)n(teger,text\))d(for)h(insertion)g(sim)n +(ultaneosly)f(in)i(b)r(oth)g(tables:)508 5305 y(m)n +(ytree_insert\('2201','hello',0,'not)15 b(m)n(uc)n(h'\))j(inserts)g(a)g +(new)g(c)n(hild)h(of)f(2201)f(with)h(data1='hello',)h(data2=0)508 +5404 y(and)28 b(data3='not)e(m)n(uc)n(h')1987 5653 y(6)p +eop +%%Page: 7 7 +7 6 bop 425 291 a Ff(\017)41 b Fh(a)27 b(function)i(m)n +(ytree_insert_no)r(de\(text,in)n(teger\))c(for)i(insertion)g(in)h(m)n +(ytree_bkg)508 390 y(m)n(ytree_insert\('2201',25\))c(inserts)j(in)h(m)n +(ytree_bkg)e(a)h(new)h(c)n(hild)f(of)h(2201)d(with)j(sid=25)220 +556 y(4.)41 b(a)27 b(function)h(m)n(ytree_mo)n(v)n(e\(text,text\))e +(that)i(mo)n(v)n(es)e(subtrees:)326 656 y(m)n(ytree_mo)n(v)n +(e\('2201','23'\))d(mo)n(v)n(es)j(the)i(subtree)f(ro)r(oted)g(at)g +(2201)f(to)h(a)h(place)f(b)r(elo)n(w)g(23)f(\(ma)n(yb)r(e)i(2307\))220 +822 y(5.)41 b(a)c(function)g(m)n(ytree_len\(\))g(that)h(returns)e(the)i +(length)f(of)g(the)h(enco)r(dings)f(used)g(in)h(the)f(gID)g(\(2)h +(here;)j(0)c(if)326 922 y(v)-5 b(ariable)26 b(size\).)118 +1196 y Fi(5)131 b(Non-tree)44 b(hierarc)l(hies)118 1378 +y Fh(sequence)22 b(as)f(id,)j(table)e(with)h(\(id,g-index\))f(with)g(p) +r(ossibly)g(man)n(y)g(g-indices)f(for)h(eac)n(h)f(id)h(\(if)h(TOO)f +(man)n(y)-7 b(,)23 b(bad)f(mo)r(del:)118 1478 y(list)28 +b(all)f(genealogies,)f(i.e.,)h(paths)h(from)f(the)h(ro)r(ot\))118 +1752 y Fi(References)160 1934 y Fh([1])41 b(Philip)28 +b(Greenspun,)g Fe(T)-6 b(r)l(e)l(es)29 b(in)h(Or)l(acle)g(SQL)p +Fh(,)d(in)h Fg(SQL)k(for)g(W)-8 b(eb)31 b(Nerds)289 2033 +y Fh()160 2200 +y([2])41 b(Jo)r(e)27 b(Celk)n(o,)f Fe(SQL)j(for)i(Smarties)p +Fh(,)d(in)g Fg(DBMS)j(Online)p Fh(,)26 b(Marc)n(h)h(to)g(June)h(1996) +289 2299 y()289 +2399 y()289 +2498 y()289 +2598 y()160 +2764 y([3])41 b(Graeme)26 b(Birc)n(hall,)h Fg(DB2)32 +b(UDB)g(V6.1)f(SQL)h(Co)s(okb)s(o)s(ok)p Fh(,)289 2864 +y()1987 5653 +y(7)p eop +%%Trailer +end +userdict /end-hook known{end-hook}if +%%EOF diff --git a/ldb-2.0.8/ldb_tdb/ldb_tdb.c b/ldb-2.0.8/ldb_tdb/ldb_tdb.c new file mode 100644 index 0000000..77cd5e9 --- /dev/null +++ b/ldb-2.0.8/ldb_tdb/ldb_tdb.c @@ -0,0 +1,593 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 2006-2008 + Copyright (C) Matthias Dieter Wallnöfer 2009-2010 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb_tdb + * + * Component: ldb tdb backend + * + * Description: core functions for tdb backend + * + * Author: Andrew Tridgell + * Author: Stefan Metzmacher + * + * Modifications: + * + * - description: make the module use asynchronous calls + * date: Feb 2006 + * Author: Simo Sorce + * + * - description: make it possible to use event contexts + * date: Jan 2008 + * Author: Simo Sorce + * + * - description: fix up memory leaks and small bugs + * date: Oct 2009 + * Author: Matthias Dieter Wallnöfer + */ + +#include "ldb_tdb.h" +#include "ldb_private.h" +#include "../ldb_key_value/ldb_kv.h" +#include + +/* + lock the database for read - use by ltdb_search and ltdb_sequence_number +*/ +static int ltdb_lock_read(struct ldb_module *module) +{ + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + int tdb_ret = 0; + int ret; + pid_t pid = getpid(); + + if (ldb_kv->pid != pid) { + ldb_asprintf_errstring(ldb_module_get_ctx(module), + __location__ + ": Reusing ldb opend by pid %d in " + "process %d\n", + ldb_kv->pid, + pid); + return LDB_ERR_PROTOCOL_ERROR; + } + + if (tdb_transaction_active(ldb_kv->tdb) == false && + ldb_kv->read_lock_count == 0) { + tdb_ret = tdb_lockall_read(ldb_kv->tdb); + } + if (tdb_ret == 0) { + ldb_kv->read_lock_count++; + return LDB_SUCCESS; + } + ret = ltdb_err_map(tdb_error(ldb_kv->tdb)); + if (ret == LDB_SUCCESS) { + ret = LDB_ERR_OPERATIONS_ERROR; + } + ldb_debug_set(ldb_module_get_ctx(module), + LDB_DEBUG_FATAL, + "Failure during ltdb_lock_read(): %s -> %s", + tdb_errorstr(ldb_kv->tdb), + ldb_strerror(ret)); + return ret; +} + +/* + unlock the database after a ltdb_lock_read() +*/ +static int ltdb_unlock_read(struct ldb_module *module) +{ + void *data = ldb_module_get_private(module); + struct ldb_kv_private *ldb_kv = + talloc_get_type(data, struct ldb_kv_private); + pid_t pid = getpid(); + + if (ldb_kv->pid != pid) { + ldb_asprintf_errstring(ldb_module_get_ctx(module), + __location__ + ": Reusing ldb opend by pid %d in " + "process %d\n", + ldb_kv->pid, + pid); + return LDB_ERR_PROTOCOL_ERROR; + } + if (!tdb_transaction_active(ldb_kv->tdb) && + ldb_kv->read_lock_count == 1) { + tdb_unlockall_read(ldb_kv->tdb); + ldb_kv->read_lock_count--; + return 0; + } + ldb_kv->read_lock_count--; + return 0; +} + +static int ltdb_store(struct ldb_kv_private *ldb_kv, + struct ldb_val ldb_key, + struct ldb_val ldb_data, + int flags) +{ + TDB_DATA key = { + .dptr = ldb_key.data, + .dsize = ldb_key.length + }; + TDB_DATA data = { + .dptr = ldb_data.data, + .dsize = ldb_data.length + }; + bool transaction_active = tdb_transaction_active(ldb_kv->tdb); + if (transaction_active == false){ + return LDB_ERR_PROTOCOL_ERROR; + } + return tdb_store(ldb_kv->tdb, key, data, flags); +} + +static int ltdb_error(struct ldb_kv_private *ldb_kv) +{ + return ltdb_err_map(tdb_error(ldb_kv->tdb)); +} + +static const char *ltdb_errorstr(struct ldb_kv_private *ldb_kv) +{ + return tdb_errorstr(ldb_kv->tdb); +} + +static int ltdb_delete(struct ldb_kv_private *ldb_kv, struct ldb_val ldb_key) +{ + TDB_DATA tdb_key = { + .dptr = ldb_key.data, + .dsize = ldb_key.length + }; + bool transaction_active = tdb_transaction_active(ldb_kv->tdb); + if (transaction_active == false){ + return LDB_ERR_PROTOCOL_ERROR; + } + return tdb_delete(ldb_kv->tdb, tdb_key); +} + +static int ltdb_transaction_start(struct ldb_kv_private *ldb_kv) +{ + pid_t pid = getpid(); + + if (ldb_kv->pid != pid) { + ldb_asprintf_errstring(ldb_module_get_ctx(ldb_kv->module), + __location__ + ": Reusing ldb opend by pid %d in " + "process %d\n", + ldb_kv->pid, + pid); + return LDB_ERR_PROTOCOL_ERROR; + } + + return tdb_transaction_start(ldb_kv->tdb); +} + +static int ltdb_transaction_cancel(struct ldb_kv_private *ldb_kv) +{ + pid_t pid = getpid(); + + if (ldb_kv->pid != pid) { + ldb_asprintf_errstring(ldb_module_get_ctx(ldb_kv->module), + __location__ + ": Reusing ldb opend by pid %d in " + "process %d\n", + ldb_kv->pid, + pid); + return LDB_ERR_PROTOCOL_ERROR; + } + + return tdb_transaction_cancel(ldb_kv->tdb); +} + +static int ltdb_transaction_prepare_commit(struct ldb_kv_private *ldb_kv) +{ + pid_t pid = getpid(); + + if (ldb_kv->pid != pid) { + ldb_asprintf_errstring(ldb_module_get_ctx(ldb_kv->module), + __location__ + ": Reusing ldb opend by pid %d in " + "process %d\n", + ldb_kv->pid, + pid); + return LDB_ERR_PROTOCOL_ERROR; + } + + return tdb_transaction_prepare_commit(ldb_kv->tdb); +} + +static int ltdb_transaction_commit(struct ldb_kv_private *ldb_kv) +{ + pid_t pid = getpid(); + + if (ldb_kv->pid != pid) { + ldb_asprintf_errstring(ldb_module_get_ctx(ldb_kv->module), + __location__ + ": Reusing ldb opend by pid %d in " + "process %d\n", + ldb_kv->pid, + pid); + return LDB_ERR_PROTOCOL_ERROR; + } + + return tdb_transaction_commit(ldb_kv->tdb); +} +struct kv_ctx { + ldb_kv_traverse_fn kv_traverse_fn; + void *ctx; + struct ldb_kv_private *ldb_kv; + int (*parser)(struct ldb_val key, + struct ldb_val data, + void *private_data); + int parser_ret; +}; + +static int ltdb_traverse_fn_wrapper(struct tdb_context *tdb, + TDB_DATA tdb_key, + TDB_DATA tdb_data, + void *ctx) +{ + struct kv_ctx *kv_ctx = ctx; + struct ldb_val key = { + .length = tdb_key.dsize, + .data = tdb_key.dptr, + }; + struct ldb_val data = { + .length = tdb_data.dsize, + .data = tdb_data.dptr, + }; + return kv_ctx->kv_traverse_fn(kv_ctx->ldb_kv, key, data, kv_ctx->ctx); +} + +static int ltdb_traverse_fn(struct ldb_kv_private *ldb_kv, + ldb_kv_traverse_fn fn, + void *ctx) +{ + struct kv_ctx kv_ctx = { + .kv_traverse_fn = fn, .ctx = ctx, .ldb_kv = ldb_kv}; + if (tdb_transaction_active(ldb_kv->tdb)) { + return tdb_traverse( + ldb_kv->tdb, ltdb_traverse_fn_wrapper, &kv_ctx); + } else { + return tdb_traverse_read( + ldb_kv->tdb, ltdb_traverse_fn_wrapper, &kv_ctx); + } +} + +static int ltdb_update_in_iterate(struct ldb_kv_private *ldb_kv, + struct ldb_val ldb_key, + struct ldb_val ldb_key2, + struct ldb_val ldb_data, + void *state) +{ + int tdb_ret; + struct ldb_context *ldb; + struct ldb_kv_reindex_context *ctx = + (struct ldb_kv_reindex_context *)state; + struct ldb_module *module = ldb_kv->module; + TDB_DATA key = { + .dptr = ldb_key.data, + .dsize = ldb_key.length + }; + TDB_DATA key2 = { + .dptr = ldb_key2.data, + .dsize = ldb_key2.length + }; + TDB_DATA data = { + .dptr = ldb_data.data, + .dsize = ldb_data.length + }; + + ldb = ldb_module_get_ctx(module); + + tdb_ret = tdb_delete(ldb_kv->tdb, key); + if (tdb_ret != 0) { + ldb_debug(ldb, + LDB_DEBUG_ERROR, + "Failed to delete %*.*s " + "for rekey as %*.*s: %s", + (int)key.dsize, + (int)key.dsize, + (const char *)key.dptr, + (int)key2.dsize, + (int)key2.dsize, + (const char *)key.dptr, + tdb_errorstr(ldb_kv->tdb)); + ctx->error = ltdb_err_map(tdb_error(ldb_kv->tdb)); + return -1; + } + tdb_ret = tdb_store(ldb_kv->tdb, key2, data, 0); + if (tdb_ret != 0) { + ldb_debug(ldb, + LDB_DEBUG_ERROR, + "Failed to rekey %*.*s as %*.*s: %s", + (int)key.dsize, + (int)key.dsize, + (const char *)key.dptr, + (int)key2.dsize, + (int)key2.dsize, + (const char *)key.dptr, + tdb_errorstr(ldb_kv->tdb)); + ctx->error = ltdb_err_map(tdb_error(ldb_kv->tdb)); + return -1; + } + return tdb_ret; +} + +static int ltdb_parse_record_wrapper(TDB_DATA tdb_key, + TDB_DATA tdb_data, + void *ctx) +{ + struct kv_ctx *kv_ctx = ctx; + struct ldb_val key = { + .length = tdb_key.dsize, + .data = tdb_key.dptr, + }; + struct ldb_val data = { + .length = tdb_data.dsize, + .data = tdb_data.dptr, + }; + + kv_ctx->parser_ret = kv_ctx->parser(key, data, kv_ctx->ctx); + return kv_ctx->parser_ret; +} + +static int ltdb_parse_record(struct ldb_kv_private *ldb_kv, + struct ldb_val ldb_key, + int (*parser)(struct ldb_val key, + struct ldb_val data, + void *private_data), + void *ctx) +{ + struct kv_ctx kv_ctx = {.parser = parser, .ctx = ctx, .ldb_kv = ldb_kv}; + TDB_DATA key = { + .dptr = ldb_key.data, + .dsize = ldb_key.length + }; + int ret; + + if (tdb_transaction_active(ldb_kv->tdb) == false && + ldb_kv->read_lock_count == 0) { + return LDB_ERR_PROTOCOL_ERROR; + } + + ret = tdb_parse_record( + ldb_kv->tdb, key, ltdb_parse_record_wrapper, &kv_ctx); + if (kv_ctx.parser_ret != LDB_SUCCESS) { + return kv_ctx.parser_ret; + } else if (ret == 0) { + return LDB_SUCCESS; + } + return ltdb_err_map(tdb_error(ldb_kv->tdb)); +} + +static int ltdb_iterate_range(struct ldb_kv_private *ldb_kv, + struct ldb_val start_key, + struct ldb_val end_key, + ldb_kv_traverse_fn fn, + void *ctx) +{ + /* + * We do not implement this operation because we do not know how to + * iterate from one key to the next (in a sorted fashion). + * + * We could mimic it potentially, but it would violate boundaries of + * knowledge (data type representation). + */ + return LDB_ERR_OPERATIONS_ERROR; +} + +static const char *ltdb_name(struct ldb_kv_private *ldb_kv) +{ + return tdb_name(ldb_kv->tdb); +} + +static bool ltdb_changed(struct ldb_kv_private *ldb_kv) +{ + int seq = tdb_get_seqnum(ldb_kv->tdb); + bool has_changed = (seq != ldb_kv->tdb_seqnum); + + ldb_kv->tdb_seqnum = seq; + + return has_changed; +} + +static bool ltdb_transaction_active(struct ldb_kv_private *ldb_kv) +{ + return tdb_transaction_active(ldb_kv->tdb); +} + +/* + * Get an estimate of the number of records in a tdb database. + * + * This implementation will overestimate the number of records in a sparsely + * populated database. The size estimate is only used for allocating + * an in memory tdb to cache index records during a reindex, overestimating + * the contents is acceptable, and preferable to underestimating + */ +#define RECORD_SIZE 500 +static size_t ltdb_get_size(struct ldb_kv_private *ldb_kv) +{ + size_t map_size = tdb_map_size(ldb_kv->tdb); + size_t size = map_size / RECORD_SIZE; + + return size; +} + +/* + * Start a sub transaction + * As TDB does not currently support nested transactions, we do nothing and + * return LDB_SUCCESS + */ +static int ltdb_nested_transaction_start(struct ldb_kv_private *ldb_kv) +{ + return LDB_SUCCESS; +} + +/* + * Commit a sub transaction + * As TDB does not currently support nested transactions, we do nothing and + * return LDB_SUCCESS + */ +static int ltdb_nested_transaction_commit(struct ldb_kv_private *ldb_kv) +{ + return LDB_SUCCESS; +} + +/* + * Cancel a sub transaction + * As TDB does not currently support nested transactions, we do nothing and + * return LDB_SUCCESS + */ +static int ltdb_nested_transaction_cancel(struct ldb_kv_private *ldb_kv) +{ + return LDB_SUCCESS; +} + +static const struct kv_db_ops key_value_ops = { + /* No support for any additional features */ + .options = 0, + + .store = ltdb_store, + .delete = ltdb_delete, + .iterate = ltdb_traverse_fn, + .update_in_iterate = ltdb_update_in_iterate, + .fetch_and_parse = ltdb_parse_record, + .iterate_range = ltdb_iterate_range, + .lock_read = ltdb_lock_read, + .unlock_read = ltdb_unlock_read, + .begin_write = ltdb_transaction_start, + .prepare_write = ltdb_transaction_prepare_commit, + .finish_write = ltdb_transaction_commit, + .abort_write = ltdb_transaction_cancel, + .error = ltdb_error, + .errorstr = ltdb_errorstr, + .name = ltdb_name, + .has_changed = ltdb_changed, + .transaction_active = ltdb_transaction_active, + .get_size = ltdb_get_size, + .begin_nested_write = ltdb_nested_transaction_start, + .finish_nested_write = ltdb_nested_transaction_commit, + .abort_nested_write = ltdb_nested_transaction_cancel, +}; + +/* + connect to the database +*/ +int ltdb_connect(struct ldb_context *ldb, const char *url, + unsigned int flags, const char *options[], + struct ldb_module **_module) +{ + const char *path; + int tdb_flags, open_flags; + struct ldb_kv_private *ldb_kv; + + /* + * We hold locks, so we must use a private event context + * on each returned handle + */ + ldb_set_require_private_event_context(ldb); + + /* parse the url */ + if (strchr(url, ':')) { + if (strncmp(url, "tdb://", 6) != 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Invalid tdb URL '%s'", url); + return LDB_ERR_OPERATIONS_ERROR; + } + path = url+6; + } else { + path = url; + } + + tdb_flags = TDB_DEFAULT | TDB_SEQNUM | TDB_DISALLOW_NESTING; + + /* check for the 'nosync' option */ + if (flags & LDB_FLG_NOSYNC) { + tdb_flags |= TDB_NOSYNC; + } + + /* and nommap option */ + if (flags & LDB_FLG_NOMMAP) { + tdb_flags |= TDB_NOMMAP; + } + + ldb_kv = talloc_zero(ldb, struct ldb_kv_private); + if (!ldb_kv) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + if (flags & LDB_FLG_RDONLY) { + /* + * This is weird, but because we can only have one tdb + * in this process, and the other one could be + * read-write, we can't use the tdb readonly. Plus a + * read only tdb prohibits the all-record lock. + */ + open_flags = O_RDWR; + + ldb_kv->read_only = true; + + } else if (flags & LDB_FLG_DONT_CREATE_DB) { + /* + * This is used by ldbsearch to prevent creation of the database + * if the name is wrong + */ + open_flags = O_RDWR; + } else { + /* + * This is the normal case + */ + open_flags = O_CREAT | O_RDWR; + } + + ldb_kv->kv_ops = &key_value_ops; + + errno = 0; + /* note that we use quite a large default hash size */ + ldb_kv->tdb = ltdb_wrap_open(ldb_kv, + path, + 10000, + tdb_flags, + open_flags, + ldb_get_create_perms(ldb), + ldb); + if (!ldb_kv->tdb) { + ldb_asprintf_errstring(ldb, + "Unable to open tdb '%s': %s", path, strerror(errno)); + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Unable to open tdb '%s': %s", path, strerror(errno)); + talloc_free(ldb_kv); + if (errno == EACCES || errno == EPERM) { + return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; + } + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_kv_init_store( + ldb_kv, "ldb_tdb backend", ldb, options, _module); +} diff --git a/ldb-2.0.8/ldb_tdb/ldb_tdb.h b/ldb-2.0.8/ldb_tdb/ldb_tdb.h new file mode 100644 index 0000000..5395d42 --- /dev/null +++ b/ldb-2.0.8/ldb_tdb/ldb_tdb.h @@ -0,0 +1,16 @@ +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "tdb.h" +#include "ldb_module.h" + +TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn); +int ltdb_err_map(enum TDB_ERROR tdb_code); + +struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, + const char *path, int hash_size, int tdb_flags, + int open_flags, mode_t mode, + struct ldb_context *ldb); +int ltdb_connect(struct ldb_context *ldb, const char *url, + unsigned int flags, const char *options[], + struct ldb_module **_module); diff --git a/ldb-2.0.8/ldb_tdb/ldb_tdb_err_map.c b/ldb-2.0.8/ldb_tdb/ldb_tdb_err_map.c new file mode 100644 index 0000000..41e5318 --- /dev/null +++ b/ldb-2.0.8/ldb_tdb/ldb_tdb_err_map.c @@ -0,0 +1,84 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 2006-2008 + Copyright (C) Matthias Dieter Wallnöfer 2009-2010 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb_tdb + * + * Component: ldb tdb backend + * + * Description: core functions for tdb backend + * + * Author: Andrew Tridgell + * Author: Stefan Metzmacher + * + * Modifications: + * + * - description: make the module use asynchronous calls + * date: Feb 2006 + * Author: Simo Sorce + * + * - description: make it possible to use event contexts + * date: Jan 2008 + * Author: Simo Sorce + * + * - description: fix up memory leaks and small bugs + * date: Oct 2009 + * Author: Matthias Dieter Wallnöfer + */ + +#include "ldb_tdb.h" +#include + +/* + map a tdb error code to a ldb error code +*/ +int ltdb_err_map(enum TDB_ERROR tdb_code) +{ + switch (tdb_code) { + case TDB_SUCCESS: + return LDB_SUCCESS; + case TDB_ERR_CORRUPT: + case TDB_ERR_OOM: + case TDB_ERR_EINVAL: + return LDB_ERR_OPERATIONS_ERROR; + case TDB_ERR_IO: + return LDB_ERR_PROTOCOL_ERROR; + case TDB_ERR_LOCK: + case TDB_ERR_NOLOCK: + return LDB_ERR_BUSY; + case TDB_ERR_LOCK_TIMEOUT: + return LDB_ERR_TIME_LIMIT_EXCEEDED; + case TDB_ERR_EXISTS: + return LDB_ERR_ENTRY_ALREADY_EXISTS; + case TDB_ERR_NOEXIST: + return LDB_ERR_NO_SUCH_OBJECT; + case TDB_ERR_RDONLY: + return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; + default: + break; + } + return LDB_ERR_OTHER; +} diff --git a/ldb-2.0.8/ldb_tdb/ldb_tdb_init.c b/ldb-2.0.8/ldb_tdb/ldb_tdb_init.c new file mode 100644 index 0000000..b18c98a --- /dev/null +++ b/ldb-2.0.8/ldb_tdb/ldb_tdb_init.c @@ -0,0 +1,59 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 2006-2008 + Copyright (C) Matthias Dieter Wallnöfer 2009-2010 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb_tdb + * + * Component: ldb tdb backend + * + * Description: core functions for tdb backend + * + * Author: Andrew Tridgell + * Author: Stefan Metzmacher + * + * Modifications: + * + * - description: make the module use asynchronous calls + * date: Feb 2006 + * Author: Simo Sorce + * + * - description: make it possible to use event contexts + * date: Jan 2008 + * Author: Simo Sorce + * + * - description: fix up memory leaks and small bugs + * date: Oct 2009 + * Author: Matthias Dieter Wallnöfer + */ + +#include "ldb_tdb.h" +#include "ldb_private.h" + +int ldb_tdb_init(const char *version) +{ + LDB_MODULE_CHECK_VERSION(version); + return ldb_register_backend("tdb", ltdb_connect, false); +} diff --git a/ldb-2.0.8/ldb_tdb/ldb_tdb_wrap.c b/ldb-2.0.8/ldb_tdb/ldb_tdb_wrap.c new file mode 100644 index 0000000..bc702a2 --- /dev/null +++ b/ldb-2.0.8/ldb_tdb/ldb_tdb_wrap.c @@ -0,0 +1,162 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2005 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "ldb_tdb.h" +#include "dlinklist.h" + +static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); +static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) +{ + va_list ap; + const char *name = tdb_name(tdb); + struct ldb_context *ldb = talloc_get_type(tdb_get_logging_private(tdb), struct ldb_context); + enum ldb_debug_level ldb_level; + char *message; + + if (ldb == NULL) + return; + + va_start(ap, fmt); + message = talloc_vasprintf(ldb, fmt, ap); + va_end(ap); + + switch (level) { + case TDB_DEBUG_FATAL: + ldb_level = LDB_DEBUG_FATAL; + break; + case TDB_DEBUG_ERROR: + ldb_level = LDB_DEBUG_ERROR; + break; + case TDB_DEBUG_WARNING: + ldb_level = LDB_DEBUG_WARNING; + break; + case TDB_DEBUG_TRACE: + ldb_level = LDB_DEBUG_TRACE; + break; + default: + ldb_level = LDB_DEBUG_FATAL; + } + + ldb_debug(ldb, ldb_level, "ltdb: tdb(%s): %s", name, message); + talloc_free(message); +} + +/* + the purpose of this code is to work around the braindead posix locking + rules, to allow us to have a ldb open more than once while allowing + locking to work + + TDB2 handles multiple opens, so we don't have this problem there. +*/ + +struct ltdb_wrap { + struct ltdb_wrap *next, *prev; + struct tdb_context *tdb; + dev_t device; + ino_t inode; + pid_t pid; +}; + +static struct ltdb_wrap *tdb_list; + +/* destroy the last connection to a tdb */ +static int ltdb_wrap_destructor(struct ltdb_wrap *w) +{ + tdb_close(w->tdb); + DLIST_REMOVE(tdb_list, w); + return 0; +} + +/* + wrapped connection to a tdb database. The caller should _not_ free + this as it is not a talloc structure (as tdb does not use talloc + yet). It will auto-close when the caller frees the mem_ctx that is + passed to this call + */ +struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, + const char *path, int hash_size, + int tdb_flags, + int open_flags, mode_t mode, + struct ldb_context *ldb) +{ + struct ltdb_wrap *w; + struct tdb_logging_context lctx; + struct stat st; + + if (stat(path, &st) == 0) { + for (w=tdb_list;w;w=w->next) { + if (st.st_dev == w->device && st.st_ino == w->inode) { + pid_t pid = getpid(); + int ret; + if (!talloc_reference(mem_ctx, w)) { + return NULL; + } + if (w->pid != pid) { + ret = tdb_reopen(w->tdb); + if (ret != 0) { + /* + * Avoid use-after-free: + * on fail the TDB + * is closed! + */ + DLIST_REMOVE(tdb_list, + w); + return NULL; + } + w->pid = pid; + } + return w->tdb; + } + } + } + + w = talloc(mem_ctx, struct ltdb_wrap); + if (w == NULL) { + return NULL; + } + + lctx.log_fn = ltdb_log_fn; + lctx.log_private = ldb; + w->tdb = tdb_open_ex(path, hash_size, tdb_flags, open_flags, mode, + &lctx, NULL); + if (w->tdb == NULL) { + talloc_free(w); + return NULL; + } + + if (fstat(tdb_fd(w->tdb), &st) != 0) { + tdb_close(w->tdb); + talloc_free(w); + return NULL; + } + + w->device = st.st_dev; + w->inode = st.st_ino; + w->pid = getpid(); + + talloc_set_destructor(w, ltdb_wrap_destructor); + + DLIST_ADD(tdb_list, w); + + return w->tdb; +} diff --git a/ldb-2.0.8/lib/replace/.checker_innocent b/ldb-2.0.8/lib/replace/.checker_innocent new file mode 100644 index 0000000..e619176 --- /dev/null +++ b/ldb-2.0.8/lib/replace/.checker_innocent @@ -0,0 +1,4 @@ +>>>MISTAKE21_create_files_6a9e68ada99a97cb +>>>MISTAKE21_os2_delete_9b2bfa7f38711d09 +>>>MISTAKE21_os2_delete_2fcc29aaa99a97cb +>>>SECURITY2_os2_delete_9b2bfa7f1c9396ca diff --git a/ldb-2.0.8/lib/replace/Makefile b/ldb-2.0.8/lib/replace/Makefile new file mode 100644 index 0000000..a123a37 --- /dev/null +++ b/ldb-2.0.8/lib/replace/Makefile @@ -0,0 +1,64 @@ +# simple makefile wrapper to run waf + +WAF_BINARY=$(PYTHON) ../../buildtools/bin/waf +WAF=PYTHONHASHSEED=1 WAF_MAKE=1 $(WAF_BINARY) + +all: + $(WAF) build + +install: + $(WAF) install + +uninstall: + $(WAF) uninstall + +test: + $(WAF) test $(TEST_OPTIONS) + +testenv: + $(WAF) test --testenv $(TEST_OPTIONS) + +quicktest: + $(WAF) test --quick $(TEST_OPTIONS) + +dist: + touch .tmplock + WAFLOCK=.tmplock $(WAF) dist + +distcheck: + touch .tmplock + WAFLOCK=.tmplock $(WAF) distcheck + +clean: + $(WAF) clean + +distclean: + $(WAF) distclean + +reconfigure: configure + $(WAF) reconfigure + +show_waf_options: + $(WAF) --help + +# some compatibility make targets +everything: all + +testsuite: all + +check: test + +torture: all + +# this should do an install as well, once install is finished +installcheck: test + +etags: + $(WAF) etags + +ctags: + $(WAF) ctags + +bin/%:: FORCE + $(WAF) --targets=`basename $@` +FORCE: diff --git a/ldb-2.0.8/lib/replace/README b/ldb-2.0.8/lib/replace/README new file mode 100644 index 0000000..6612eab --- /dev/null +++ b/ldb-2.0.8/lib/replace/README @@ -0,0 +1,128 @@ +This subsystem ensures that we can always use a certain core set of +functions and types, that are either provided by the OS or by replacement +functions / definitions in this subsystem. The aim is to try to stick +to POSIX functions in here as much as possible. Convenience functions +that are available on no platform at all belong in other subsystems +(such as LIBUTIL). + +The following functions are guaranteed: + +ftruncate +strlcpy +strlcat +mktime +rename +initgroups +memmove +strdup +setlinebuf +vsyslog +timegm +setenv +unsetenv +strndup +strnlen +waitpid +seteuid +setegid +asprintf +snprintf +vasprintf +vsnprintf +opendir +readdir +telldir +seekdir +clock_gettime +closedir +dlopen +dlclose +dlsym +dlerror +chroot +bzero +strerror +errno +mkdtemp +mkstemp (a secure one!) +pread +pwrite +chown +lchown +readline (the library) +inet_ntoa +inet_ntop +inet_pton +inet_aton +strtoll +strtoull +socketpair +strptime +getaddrinfo +freeaddrinfo +getnameinfo +gai_strerror +getifaddrs +freeifaddrs +utime +utimes +dup2 +link +readlink +symlink +realpath +poll +setproctitle +memset_s + +Types: +bool +socklen_t +uint{8,16,32,64}_t +int{8,16,32,64}_t +intptr_t +sig_atomic_t +blksize_t +blkcnt_t + +Constants: +PATH_NAME_MAX +UINT{16,32,64}_MAX +INT32_MAX +RTLD_LAZY +HOST_NAME_MAX +UINT16_MAX +UINT32_MAX +UINT64_MAX +CHAR_BIT + +Macros: +va_copy +__FUNCTION__ +__FILE__ +__LINE__ +__LINESTR__ +__location__ +__STRING +__STRINGSTRING +MIN +MAX +QSORT_CAST +ZERO_STRUCT +ZERO_STRUCTP +ZERO_STRUCTPN +ZERO_ARRAY +ARRAY_SIZE +PTR_DIFF + +Headers: +stdint.h +stdbool.h + +Optional C keywords: +volatile + +Prerequisites: +memset (for bzero) +syslog (for vsyslog) +mktemp (for mkstemp and mkdtemp) diff --git a/ldb-2.0.8/lib/replace/closefrom.c b/ldb-2.0.8/lib/replace/closefrom.c new file mode 100644 index 0000000..a61a80f --- /dev/null +++ b/ldb-2.0.8/lib/replace/closefrom.c @@ -0,0 +1,138 @@ +/* + * Unix SMB/CIFS implementation. + * Samba utility functions + * Copyright (C) Volker Lendecke 2016 + * + * ** NOTE! The following LGPL license applies to the replace + * ** library. This does NOT imply that all of Samba is released + * ** under the LGPL + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "replace.h" +#include +#include +#include + +static int closefrom_sysconf(int lower) +{ + long max_files, fd; + + max_files = sysconf(_SC_OPEN_MAX); + if (max_files == -1) { + max_files = 65536; + } + + for (fd=lower; fdd_name, &endptr, 10); + if ((fd == 0) && (errno == EINVAL)) { + continue; + } + if ((fd == ULLONG_MAX) && (errno == ERANGE)) { + continue; + } + if (*endptr != '\0') { + continue; + } + if (fd == dir_fd) { + continue; + } + if (fd > INT_MAX) { + continue; + } + if (fd < lower) { + continue; + } + + if (num_fds >= (fd_array_size / sizeof(int))) { + void *tmp; + + if (fd_array_size == 0) { + fd_array_size = 16 * sizeof(int); + } else { + if (fd_array_size + fd_array_size < + fd_array_size) { + /* overflow */ + goto fail; + } + fd_array_size = fd_array_size + fd_array_size; + } + + tmp = realloc(fds, fd_array_size); + if (tmp == NULL) { + goto fail; + } + fds = tmp; + } + + fds[num_fds++] = fd; + } + + for (i=0; i + that this crypt routine may sometimes get the wrong answer. Only + use UFC_CRYT if you really need it. + +*/ + +#include "replace.h" + +#ifndef HAVE_CRYPT + +/* + * UFC-crypt: ultra fast crypt(3) implementation + * + * Copyright (C) 1991-1998, Free Software Foundation, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + * @(#)crypt_util.c 2.31 02/08/92 + * + * Support routines + * + */ + + +#ifndef long32 +#define long32 int32_t +#endif + +#ifndef long64 +#define long64 int64_t +#endif + +#ifndef ufc_long +#define ufc_long unsigned +#endif + +#ifndef _UFC_64_ +#define _UFC_32_ +#endif + +/* + * Permutation done once on the 56 bit + * key derived from the original 8 byte ASCII key. + */ +static int pc1[56] = { + 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, + 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 +}; + +/* + * How much to rotate each 28 bit half of the pc1 permutated + * 56 bit key before using pc2 to give the i' key + */ +static int rots[16] = { + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 +}; + +/* + * Permutation giving the key + * of the i' DES round + */ +static int pc2[48] = { + 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 +}; + +/* + * The E expansion table which selects + * bits from the 32 bit intermediate result. + */ +static int esel[48] = { + 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1 +}; +static int e_inverse[64]; + +/* + * Permutation done on the + * result of sbox lookups + */ +static int perm32[32] = { + 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, + 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 +}; + +/* + * The sboxes + */ +static int sbox[8][4][16]= { + { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 }, + { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 }, + { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 }, + { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 } + }, + + { { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 }, + { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 }, + { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 }, + { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 } + }, + + { { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 }, + { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 }, + { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 }, + { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 } + }, + + { { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 }, + { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 }, + { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 }, + { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 } + }, + + { { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 }, + { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 }, + { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 }, + { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 } + }, + + { { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 }, + { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 }, + { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 }, + { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 } + }, + + { { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 }, + { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 }, + { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 }, + { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 } + }, + + { { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 }, + { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 }, + { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 }, + { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } + } +}; + +/* + * This is the final + * permutation matrix + */ +static int final_perm[64] = { + 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25 +}; + +/* + * The 16 DES keys in BITMASK format + */ +#ifdef _UFC_32_ +long32 _ufc_keytab[16][2]; +#endif + +#ifdef _UFC_64_ +long64 _ufc_keytab[16]; +#endif + + +#define ascii_to_bin(c) ((c)>='a'?(c-59):(c)>='A'?((c)-53):(c)-'.') +#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.') + +/* Macro to set a bit (0..23) */ +#define BITMASK(i) ( (1<<(11-(i)%12+3)) << ((i)<12?16:0) ) + +/* + * sb arrays: + * + * Workhorses of the inner loop of the DES implementation. + * They do sbox lookup, shifting of this value, 32 bit + * permutation and E permutation for the next round. + * + * Kept in 'BITMASK' format. + */ + +#ifdef _UFC_32_ +long32 _ufc_sb0[8192], _ufc_sb1[8192], _ufc_sb2[8192], _ufc_sb3[8192]; +static long32 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3}; +#endif + +#ifdef _UFC_64_ +long64 _ufc_sb0[4096], _ufc_sb1[4096], _ufc_sb2[4096], _ufc_sb3[4096]; +static long64 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3}; +#endif + +/* + * eperm32tab: do 32 bit permutation and E selection + * + * The first index is the byte number in the 32 bit value to be permuted + * - second - is the value of this byte + * - third - selects the two 32 bit values + * + * The table is used and generated internally in init_des to speed it up + */ +static ufc_long eperm32tab[4][256][2]; + +/* + * do_pc1: permform pc1 permutation in the key schedule generation. + * + * The first index is the byte number in the 8 byte ASCII key + * - second - - the two 28 bits halfs of the result + * - third - selects the 7 bits actually used of each byte + * + * The result is kept with 28 bit per 32 bit with the 4 most significant + * bits zero. + */ +static ufc_long do_pc1[8][2][128]; + +/* + * do_pc2: permform pc2 permutation in the key schedule generation. + * + * The first index is the septet number in the two 28 bit intermediate values + * - second - - - septet values + * + * Knowledge of the structure of the pc2 permutation is used. + * + * The result is kept with 28 bit per 32 bit with the 4 most significant + * bits zero. + */ +static ufc_long do_pc2[8][128]; + +/* + * efp: undo an extra e selection and do final + * permutation giving the DES result. + * + * Invoked 6 bit a time on two 48 bit values + * giving two 32 bit longs. + */ +static ufc_long efp[16][64][2]; + +static unsigned char bytemask[8] = { + 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 +}; + +static ufc_long longmask[32] = { + 0x80000000, 0x40000000, 0x20000000, 0x10000000, + 0x08000000, 0x04000000, 0x02000000, 0x01000000, + 0x00800000, 0x00400000, 0x00200000, 0x00100000, + 0x00080000, 0x00040000, 0x00020000, 0x00010000, + 0x00008000, 0x00004000, 0x00002000, 0x00001000, + 0x00000800, 0x00000400, 0x00000200, 0x00000100, + 0x00000080, 0x00000040, 0x00000020, 0x00000010, + 0x00000008, 0x00000004, 0x00000002, 0x00000001 +}; + + +/* + * Silly rewrite of 'bzero'. I do so + * because some machines don't have + * bzero and some don't have memset. + */ + +static void clearmem(char *start, int cnt) + { while(cnt--) + *start++ = '\0'; + } + +static int initialized = 0; + +/* lookup a 6 bit value in sbox */ + +#define s_lookup(i,s) sbox[(i)][(((s)>>4) & 0x2)|((s) & 0x1)][((s)>>1) & 0xf]; + +/* + * Initialize unit - may be invoked directly + * by fcrypt users. + */ + +static void ufc_init_des(void) + { int comes_from_bit; + int bit, sg; + ufc_long j; + ufc_long mask1, mask2; + + /* + * Create the do_pc1 table used + * to affect pc1 permutation + * when generating keys + */ + for(bit = 0; bit < 56; bit++) { + comes_from_bit = pc1[bit] - 1; + mask1 = bytemask[comes_from_bit % 8 + 1]; + mask2 = longmask[bit % 28 + 4]; + for(j = 0; j < 128; j++) { + if(j & mask1) + do_pc1[comes_from_bit / 8][bit / 28][j] |= mask2; + } + } + + /* + * Create the do_pc2 table used + * to affect pc2 permutation when + * generating keys + */ + for(bit = 0; bit < 48; bit++) { + comes_from_bit = pc2[bit] - 1; + mask1 = bytemask[comes_from_bit % 7 + 1]; + mask2 = BITMASK(bit % 24); + for(j = 0; j < 128; j++) { + if(j & mask1) + do_pc2[comes_from_bit / 7][j] |= mask2; + } + } + + /* + * Now generate the table used to do combined + * 32 bit permutation and e expansion + * + * We use it because we have to permute 16384 32 bit + * longs into 48 bit in order to initialize sb. + * + * Looping 48 rounds per permutation becomes + * just too slow... + * + */ + + clearmem((char*)eperm32tab, sizeof(eperm32tab)); + + for(bit = 0; bit < 48; bit++) { + ufc_long inner_mask1,comes_from; + + comes_from = perm32[esel[bit]-1]-1; + inner_mask1 = bytemask[comes_from % 8]; + + for(j = 256; j--;) { + if(j & inner_mask1) + eperm32tab[comes_from / 8][j][bit / 24] |= BITMASK(bit % 24); + } + } + + /* + * Create the sb tables: + * + * For each 12 bit segment of an 48 bit intermediate + * result, the sb table precomputes the two 4 bit + * values of the sbox lookups done with the two 6 + * bit halves, shifts them to their proper place, + * sends them through perm32 and finally E expands + * them so that they are ready for the next + * DES round. + * + */ + for(sg = 0; sg < 4; sg++) { + int j1, j2; + int s1, s2; + + for(j1 = 0; j1 < 64; j1++) { + s1 = s_lookup(2 * sg, j1); + for(j2 = 0; j2 < 64; j2++) { + ufc_long to_permute, inx; + + s2 = s_lookup(2 * sg + 1, j2); + to_permute = ((s1 << 4) | s2) << (24 - 8 * sg); + +#ifdef _UFC_32_ + inx = ((j1 << 6) | j2) << 1; + sb[sg][inx ] = eperm32tab[0][(to_permute >> 24) & 0xff][0]; + sb[sg][inx+1] = eperm32tab[0][(to_permute >> 24) & 0xff][1]; + sb[sg][inx ] |= eperm32tab[1][(to_permute >> 16) & 0xff][0]; + sb[sg][inx+1] |= eperm32tab[1][(to_permute >> 16) & 0xff][1]; + sb[sg][inx ] |= eperm32tab[2][(to_permute >> 8) & 0xff][0]; + sb[sg][inx+1] |= eperm32tab[2][(to_permute >> 8) & 0xff][1]; + sb[sg][inx ] |= eperm32tab[3][(to_permute) & 0xff][0]; + sb[sg][inx+1] |= eperm32tab[3][(to_permute) & 0xff][1]; +#endif +#ifdef _UFC_64_ + inx = ((j1 << 6) | j2); + sb[sg][inx] = + ((long64)eperm32tab[0][(to_permute >> 24) & 0xff][0] << 32) | + (long64)eperm32tab[0][(to_permute >> 24) & 0xff][1]; + sb[sg][inx] |= + ((long64)eperm32tab[1][(to_permute >> 16) & 0xff][0] << 32) | + (long64)eperm32tab[1][(to_permute >> 16) & 0xff][1]; + sb[sg][inx] |= + ((long64)eperm32tab[2][(to_permute >> 8) & 0xff][0] << 32) | + (long64)eperm32tab[2][(to_permute >> 8) & 0xff][1]; + sb[sg][inx] |= + ((long64)eperm32tab[3][(to_permute) & 0xff][0] << 32) | + (long64)eperm32tab[3][(to_permute) & 0xff][1]; +#endif + } + } + } + + /* + * Create an inverse matrix for esel telling + * where to plug out bits if undoing it + */ + for(bit=48; bit--;) { + e_inverse[esel[bit] - 1 ] = bit; + e_inverse[esel[bit] - 1 + 32] = bit + 48; + } + + /* + * create efp: the matrix used to + * undo the E expansion and effect final permutation + */ + clearmem((char*)efp, sizeof efp); + for(bit = 0; bit < 64; bit++) { + int o_bit, o_long; + ufc_long word_value, inner_mask1, inner_mask2; + int comes_from_f_bit, comes_from_e_bit; + int comes_from_word, bit_within_word; + + /* See where bit i belongs in the two 32 bit long's */ + o_long = bit / 32; /* 0..1 */ + o_bit = bit % 32; /* 0..31 */ + + /* + * And find a bit in the e permutated value setting this bit. + * + * Note: the e selection may have selected the same bit several + * times. By the initialization of e_inverse, we only look + * for one specific instance. + */ + comes_from_f_bit = final_perm[bit] - 1; /* 0..63 */ + comes_from_e_bit = e_inverse[comes_from_f_bit]; /* 0..95 */ + comes_from_word = comes_from_e_bit / 6; /* 0..15 */ + bit_within_word = comes_from_e_bit % 6; /* 0..5 */ + + inner_mask1 = longmask[bit_within_word + 26]; + inner_mask2 = longmask[o_bit]; + + for(word_value = 64; word_value--;) { + if(word_value & inner_mask1) + efp[comes_from_word][word_value][o_long] |= inner_mask2; + } + } + initialized++; + } + +/* + * Process the elements of the sb table permuting the + * bits swapped in the expansion by the current salt. + */ + +#ifdef _UFC_32_ +static void shuffle_sb(long32 *k, ufc_long saltbits) + { ufc_long j; + long32 x; + for(j=4096; j--;) { + x = (k[0] ^ k[1]) & (long32)saltbits; + *k++ ^= x; + *k++ ^= x; + } + } +#endif + +#ifdef _UFC_64_ +static void shuffle_sb(long64 *k, ufc_long saltbits) + { ufc_long j; + long64 x; + for(j=4096; j--;) { + x = ((*k >> 32) ^ *k) & (long64)saltbits; + *k++ ^= (x << 32) | x; + } + } +#endif + +/* + * Setup the unit for a new salt + * Hopefully we'll not see a new salt in each crypt call. + */ + +static unsigned char current_salt[3] = "&&"; /* invalid value */ +static ufc_long current_saltbits = 0; +static int direction = 0; + +static void setup_salt(const char *s1) + { ufc_long i, j, saltbits; + const unsigned char *s2 = (const unsigned char *)s1; + + if(!initialized) + ufc_init_des(); + + if(s2[0] == current_salt[0] && s2[1] == current_salt[1]) + return; + current_salt[0] = s2[0]; current_salt[1] = s2[1]; + + /* + * This is the only crypt change to DES: + * entries are swapped in the expansion table + * according to the bits set in the salt. + */ + saltbits = 0; + for(i = 0; i < 2; i++) { + long c=ascii_to_bin(s2[i]); + if(c < 0 || c > 63) + c = 0; + for(j = 0; j < 6; j++) { + if((c >> j) & 0x1) + saltbits |= BITMASK(6 * i + j); + } + } + + /* + * Permute the sb table values + * to reflect the changed e + * selection table + */ + shuffle_sb(_ufc_sb0, current_saltbits ^ saltbits); + shuffle_sb(_ufc_sb1, current_saltbits ^ saltbits); + shuffle_sb(_ufc_sb2, current_saltbits ^ saltbits); + shuffle_sb(_ufc_sb3, current_saltbits ^ saltbits); + + current_saltbits = saltbits; + } + +static void ufc_mk_keytab(char *key) + { ufc_long v1, v2, *k1; + int i; +#ifdef _UFC_32_ + long32 v, *k2 = &_ufc_keytab[0][0]; +#endif +#ifdef _UFC_64_ + long64 v, *k2 = &_ufc_keytab[0]; +#endif + + v1 = v2 = 0; k1 = &do_pc1[0][0][0]; + for(i = 8; i--;) { + v1 |= k1[*key & 0x7f]; k1 += 128; + v2 |= k1[*key++ & 0x7f]; k1 += 128; + } + + for(i = 0; i < 16; i++) { + k1 = &do_pc2[0][0]; + + v1 = (v1 << rots[i]) | (v1 >> (28 - rots[i])); + v = k1[(v1 >> 21) & 0x7f]; k1 += 128; + v |= k1[(v1 >> 14) & 0x7f]; k1 += 128; + v |= k1[(v1 >> 7) & 0x7f]; k1 += 128; + v |= k1[(v1 ) & 0x7f]; k1 += 128; + +#ifdef _UFC_32_ + *k2++ = v; + v = 0; +#endif +#ifdef _UFC_64_ + v <<= 32; +#endif + + v2 = (v2 << rots[i]) | (v2 >> (28 - rots[i])); + v |= k1[(v2 >> 21) & 0x7f]; k1 += 128; + v |= k1[(v2 >> 14) & 0x7f]; k1 += 128; + v |= k1[(v2 >> 7) & 0x7f]; k1 += 128; + v |= k1[(v2 ) & 0x7f]; + + *k2++ = v; + } + + direction = 0; + } + +/* + * Undo an extra E selection and do final permutations + */ + +ufc_long *_ufc_dofinalperm(ufc_long l1, ufc_long l2, ufc_long r1, ufc_long r2) + { ufc_long v1, v2, x; + static ufc_long ary[2]; + + x = (l1 ^ l2) & current_saltbits; l1 ^= x; l2 ^= x; + x = (r1 ^ r2) & current_saltbits; r1 ^= x; r2 ^= x; + + v1=v2=0; l1 >>= 3; l2 >>= 3; r1 >>= 3; r2 >>= 3; + + v1 |= efp[15][ r2 & 0x3f][0]; v2 |= efp[15][ r2 & 0x3f][1]; + v1 |= efp[14][(r2 >>= 6) & 0x3f][0]; v2 |= efp[14][ r2 & 0x3f][1]; + v1 |= efp[13][(r2 >>= 10) & 0x3f][0]; v2 |= efp[13][ r2 & 0x3f][1]; + v1 |= efp[12][(r2 >>= 6) & 0x3f][0]; v2 |= efp[12][ r2 & 0x3f][1]; + + v1 |= efp[11][ r1 & 0x3f][0]; v2 |= efp[11][ r1 & 0x3f][1]; + v1 |= efp[10][(r1 >>= 6) & 0x3f][0]; v2 |= efp[10][ r1 & 0x3f][1]; + v1 |= efp[ 9][(r1 >>= 10) & 0x3f][0]; v2 |= efp[ 9][ r1 & 0x3f][1]; + v1 |= efp[ 8][(r1 >>= 6) & 0x3f][0]; v2 |= efp[ 8][ r1 & 0x3f][1]; + + v1 |= efp[ 7][ l2 & 0x3f][0]; v2 |= efp[ 7][ l2 & 0x3f][1]; + v1 |= efp[ 6][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 6][ l2 & 0x3f][1]; + v1 |= efp[ 5][(l2 >>= 10) & 0x3f][0]; v2 |= efp[ 5][ l2 & 0x3f][1]; + v1 |= efp[ 4][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 4][ l2 & 0x3f][1]; + + v1 |= efp[ 3][ l1 & 0x3f][0]; v2 |= efp[ 3][ l1 & 0x3f][1]; + v1 |= efp[ 2][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 2][ l1 & 0x3f][1]; + v1 |= efp[ 1][(l1 >>= 10) & 0x3f][0]; v2 |= efp[ 1][ l1 & 0x3f][1]; + v1 |= efp[ 0][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 0][ l1 & 0x3f][1]; + + ary[0] = v1; ary[1] = v2; + return ary; + } + +/* + * crypt only: convert from 64 bit to 11 bit ASCII + * prefixing with the salt + */ + +static char *output_conversion(ufc_long v1, ufc_long v2, const char *salt) + { static char outbuf[14]; + int i, s; + + outbuf[0] = salt[0]; + outbuf[1] = salt[1] ? salt[1] : salt[0]; + + for(i = 0; i < 5; i++) + outbuf[i + 2] = bin_to_ascii((v1 >> (26 - 6 * i)) & 0x3f); + + s = (v2 & 0xf) << 2; + v2 = (v2 >> 2) | ((v1 & 0x3) << 30); + + for(i = 5; i < 10; i++) + outbuf[i + 2] = bin_to_ascii((v2 >> (56 - 6 * i)) & 0x3f); + + outbuf[12] = bin_to_ascii(s); + outbuf[13] = 0; + + return outbuf; + } + +/* + * UNIX crypt function + */ + +static ufc_long *_ufc_doit(ufc_long , ufc_long, ufc_long, ufc_long, ufc_long); + +char *ufc_crypt(const char *key,const char *salt) + { ufc_long *s; + char ktab[9]; + + /* + * Hack DES tables according to salt + */ + setup_salt(salt); + + /* + * Setup key schedule + */ + clearmem(ktab, sizeof ktab); + strncpy(ktab, key, 8); + ufc_mk_keytab(ktab); + + /* + * Go for the 25 DES encryptions + */ + s = _ufc_doit((ufc_long)0, (ufc_long)0, + (ufc_long)0, (ufc_long)0, (ufc_long)25); + + /* + * And convert back to 6 bit ASCII + */ + return output_conversion(s[0], s[1], salt); + } + + +#ifdef _UFC_32_ + +/* + * 32 bit version + */ + +extern long32 _ufc_keytab[16][2]; +extern long32 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[]; + +#define SBA(sb, v) (*(long32*)((char*)(sb)+(v))) + +static ufc_long *_ufc_doit(ufc_long l1, ufc_long l2, ufc_long r1, ufc_long r2, ufc_long itr) + { int i; + long32 s, *k; + + while(itr--) { + k = &_ufc_keytab[0][0]; + for(i=8; i--; ) { + s = *k++ ^ r1; + l1 ^= SBA(_ufc_sb1, s & 0xffff); l2 ^= SBA(_ufc_sb1, (s & 0xffff)+4); + l1 ^= SBA(_ufc_sb0, s >>= 16); l2 ^= SBA(_ufc_sb0, (s) +4); + s = *k++ ^ r2; + l1 ^= SBA(_ufc_sb3, s & 0xffff); l2 ^= SBA(_ufc_sb3, (s & 0xffff)+4); + l1 ^= SBA(_ufc_sb2, s >>= 16); l2 ^= SBA(_ufc_sb2, (s) +4); + + s = *k++ ^ l1; + r1 ^= SBA(_ufc_sb1, s & 0xffff); r2 ^= SBA(_ufc_sb1, (s & 0xffff)+4); + r1 ^= SBA(_ufc_sb0, s >>= 16); r2 ^= SBA(_ufc_sb0, (s) +4); + s = *k++ ^ l2; + r1 ^= SBA(_ufc_sb3, s & 0xffff); r2 ^= SBA(_ufc_sb3, (s & 0xffff)+4); + r1 ^= SBA(_ufc_sb2, s >>= 16); r2 ^= SBA(_ufc_sb2, (s) +4); + } + s=l1; l1=r1; r1=s; s=l2; l2=r2; r2=s; + } + return _ufc_dofinalperm(l1, l2, r1, r2); + } + +#endif + +#ifdef _UFC_64_ + +/* + * 64 bit version + */ + +extern long64 _ufc_keytab[16]; +extern long64 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[]; + +#define SBA(sb, v) (*(long64*)((char*)(sb)+(v))) + +static ufc_long *_ufc_doit(ufc_long l1, ufc_long l2, ufc_long r1, ufc_long r2, ufc_long itr) + { int i; + long64 l, r, s, *k; + + l = (((long64)l1) << 32) | ((long64)l2); + r = (((long64)r1) << 32) | ((long64)r2); + + while(itr--) { + k = &_ufc_keytab[0]; + for(i=8; i--; ) { + s = *k++ ^ r; + l ^= SBA(_ufc_sb3, (s >> 0) & 0xffff); + l ^= SBA(_ufc_sb2, (s >> 16) & 0xffff); + l ^= SBA(_ufc_sb1, (s >> 32) & 0xffff); + l ^= SBA(_ufc_sb0, (s >> 48) & 0xffff); + + s = *k++ ^ l; + r ^= SBA(_ufc_sb3, (s >> 0) & 0xffff); + r ^= SBA(_ufc_sb2, (s >> 16) & 0xffff); + r ^= SBA(_ufc_sb1, (s >> 32) & 0xffff); + r ^= SBA(_ufc_sb0, (s >> 48) & 0xffff); + } + s=l; l=r; r=s; + } + + l1 = l >> 32; l2 = l & 0xffffffff; + r1 = r >> 32; r2 = r & 0xffffffff; + return _ufc_dofinalperm(l1, l2, r1, r2); + } + +#endif + + +#else + int ufc_dummy_procedure(void); + int ufc_dummy_procedure(void) {return 0;} +#endif diff --git a/ldb-2.0.8/lib/replace/cwrap.c b/ldb-2.0.8/lib/replace/cwrap.c new file mode 100644 index 0000000..adc5c1e --- /dev/null +++ b/ldb-2.0.8/lib/replace/cwrap.c @@ -0,0 +1,46 @@ +/* + * Unix SMB/CIFS implementation. + * + * Replaceable functions by cwrap + * + * Copyright (c) 2014 Andreas Schneider + * + * ** NOTE! The following LGPL license applies to the replace + * ** library. This does NOT imply that all of Samba is released + * ** under the LGPL + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "replace.h" + +bool nss_wrapper_enabled(void) +{ + return false; +} + +bool nss_wrapper_hosts_enabled(void) +{ + return false; +} + +bool socket_wrapper_enabled(void) +{ + return false; +} + +bool uid_wrapper_enabled(void) +{ + return false; +} diff --git a/ldb-2.0.8/lib/replace/dlfcn.c b/ldb-2.0.8/lib/replace/dlfcn.c new file mode 100644 index 0000000..88431ed --- /dev/null +++ b/ldb-2.0.8/lib/replace/dlfcn.c @@ -0,0 +1,76 @@ +/* + Unix SMB/CIFS implementation. + Samba system utilities + Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Jeremy Allison 1998-2002 + Copyright (C) Jelmer Vernooij 2006 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#ifdef HAVE_DL_H +#include +#endif + +#ifndef HAVE_DLOPEN +#ifdef DLOPEN_TAKES_UNSIGNED_FLAGS +void *rep_dlopen(const char *name, unsigned int flags) +#else +void *rep_dlopen(const char *name, int flags) +#endif +{ +#ifdef HAVE_SHL_LOAD + if (name == NULL) + return PROG_HANDLE; + return (void *)shl_load(name, flags, 0); +#else + return NULL; +#endif +} +#endif + +#ifndef HAVE_DLSYM +void *rep_dlsym(void *handle, const char *symbol) +{ +#ifdef HAVE_SHL_FINDSYM + void *sym_addr; + if (!shl_findsym((shl_t *)&handle, symbol, TYPE_UNDEFINED, &sym_addr)) + return sym_addr; +#endif + return NULL; +} +#endif + +#ifndef HAVE_DLERROR +char *rep_dlerror(void) +{ + return "dynamic loading of objects not supported on this platform"; +} +#endif + +#ifndef HAVE_DLCLOSE +int rep_dlclose(void *handle) +{ +#ifdef HAVE_SHL_CLOSE + return shl_unload((shl_t)handle); +#else + return 0; +#endif +} +#endif diff --git a/ldb-2.0.8/lib/replace/getaddrinfo.c b/ldb-2.0.8/lib/replace/getaddrinfo.c new file mode 100644 index 0000000..8440d8e --- /dev/null +++ b/ldb-2.0.8/lib/replace/getaddrinfo.c @@ -0,0 +1,493 @@ +/* +PostgreSQL Database Management System +(formerly known as Postgres, then as Postgres95) + +Portions Copyright (c) 1996-2005, The PostgreSQL Global Development Group + +Portions Copyright (c) 1994, The Regents of the University of California + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose, without fee, and without a written agreement +is hereby granted, provided that the above copyright notice and this paragraph +and the following two paragraphs appear in all copies. + +IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR +DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING +LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, +EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +*/ + +/*------------------------------------------------------------------------- + * + * getaddrinfo.c + * Support getaddrinfo() on platforms that don't have it. + * + * We also supply getnameinfo() here, assuming that the platform will have + * it if and only if it has getaddrinfo(). If this proves false on some + * platform, we'll need to split this file and provide a separate configure + * test for getnameinfo(). + * + * Copyright (c) 2003-2007, PostgreSQL Global Development Group + * + * Copyright (C) 2007 Jeremy Allison. + * Modified to return multiple IPv4 addresses for Samba. + * + *------------------------------------------------------------------------- + */ + +#include "replace.h" +#include "system/network.h" + +#ifndef SMB_MALLOC +#define SMB_MALLOC(s) malloc(s) +#endif + +#ifndef SMB_STRDUP +#define SMB_STRDUP(s) strdup(s) +#endif + +static int check_hostent_err(struct hostent *hp) +{ + if (!hp) { + switch (h_errno) { + case HOST_NOT_FOUND: + case NO_DATA: + return EAI_NONAME; + case TRY_AGAIN: + return EAI_AGAIN; + case NO_RECOVERY: + default: + return EAI_FAIL; + } + } + if (!hp->h_name || hp->h_addrtype != AF_INET) { + return EAI_FAIL; + } + return 0; +} + +static char *canon_name_from_hostent(struct hostent *hp, + int *perr) +{ + char *ret = NULL; + + *perr = check_hostent_err(hp); + if (*perr) { + return NULL; + } + ret = SMB_STRDUP(hp->h_name); + if (!ret) { + *perr = EAI_MEMORY; + } + return ret; +} + +static char *get_my_canon_name(int *perr) +{ + char name[HOST_NAME_MAX+1]; + + if (gethostname(name, HOST_NAME_MAX) == -1) { + *perr = EAI_FAIL; + return NULL; + } + /* Ensure null termination. */ + name[HOST_NAME_MAX] = '\0'; + return canon_name_from_hostent(gethostbyname(name), perr); +} + +static char *get_canon_name_from_addr(struct in_addr ip, + int *perr) +{ + return canon_name_from_hostent( + gethostbyaddr(&ip, sizeof(ip), AF_INET), + perr); +} + +static struct addrinfo *alloc_entry(const struct addrinfo *hints, + struct in_addr ip, + unsigned short port) +{ + struct sockaddr_in *psin = NULL; + struct addrinfo *ai = SMB_MALLOC(sizeof(*ai)); + + if (!ai) { + return NULL; + } + memset(ai, '\0', sizeof(*ai)); + + psin = SMB_MALLOC(sizeof(*psin)); + if (!psin) { + free(ai); + return NULL; + } + + memset(psin, '\0', sizeof(*psin)); + + psin->sin_family = AF_INET; + psin->sin_port = htons(port); + psin->sin_addr = ip; + + ai->ai_flags = 0; + ai->ai_family = AF_INET; + ai->ai_socktype = hints->ai_socktype; + ai->ai_protocol = hints->ai_protocol; + ai->ai_addrlen = sizeof(*psin); + ai->ai_addr = (struct sockaddr *) psin; + ai->ai_canonname = NULL; + ai->ai_next = NULL; + + return ai; +} + +/* + * get address info for a single ipv4 address. + * + * Bugs: - servname can only be a number, not text. + */ + +static int getaddr_info_single_addr(const char *service, + uint32_t addr, + const struct addrinfo *hints, + struct addrinfo **res) +{ + + struct addrinfo *ai = NULL; + struct in_addr ip; + unsigned short port = 0; + + if (service) { + port = (unsigned short)atoi(service); + } + ip.s_addr = htonl(addr); + + ai = alloc_entry(hints, ip, port); + if (!ai) { + return EAI_MEMORY; + } + + /* If we're asked for the canonical name, + * make sure it returns correctly. */ + if (!(hints->ai_flags & AI_NUMERICSERV) && + hints->ai_flags & AI_CANONNAME) { + int err; + if (addr == INADDR_LOOPBACK || addr == INADDR_ANY) { + ai->ai_canonname = get_my_canon_name(&err); + } else { + ai->ai_canonname = + get_canon_name_from_addr(ip,&err); + } + if (ai->ai_canonname == NULL) { + freeaddrinfo(ai); + return err; + } + } + + *res = ai; + return 0; +} + +/* + * get address info for multiple ipv4 addresses. + * + * Bugs: - servname can only be a number, not text. + */ + +static int getaddr_info_name(const char *node, + const char *service, + const struct addrinfo *hints, + struct addrinfo **res) +{ + struct addrinfo *listp = NULL, *prevp = NULL; + char **pptr = NULL; + int err; + struct hostent *hp = NULL; + unsigned short port = 0; + + if (service) { + port = (unsigned short)atoi(service); + } + + hp = gethostbyname(node); + err = check_hostent_err(hp); + if (err) { + return err; + } + + for(pptr = hp->h_addr_list; *pptr; pptr++) { + struct in_addr ip = *(struct in_addr *)*pptr; + struct addrinfo *ai = alloc_entry(hints, ip, port); + + if (!ai) { + freeaddrinfo(listp); + return EAI_MEMORY; + } + + if (!listp) { + listp = ai; + prevp = ai; + ai->ai_canonname = SMB_STRDUP(hp->h_name); + if (!ai->ai_canonname) { + freeaddrinfo(listp); + return EAI_MEMORY; + } + } else { + prevp->ai_next = ai; + prevp = ai; + } + } + *res = listp; + return 0; +} + +/* + * get address info for ipv4 sockets. + * + * Bugs: - servname can only be a number, not text. + */ + +int rep_getaddrinfo(const char *node, + const char *service, + const struct addrinfo * hintp, + struct addrinfo ** res) +{ + struct addrinfo hints; + + /* Setup the hints struct. */ + if (hintp == NULL) { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + } else { + memcpy(&hints, hintp, sizeof(hints)); + } + + if (hints.ai_family != AF_INET && hints.ai_family != AF_UNSPEC) { + return EAI_FAMILY; + } + + if (hints.ai_socktype == 0) { + hints.ai_socktype = SOCK_STREAM; + } + + if (!node && !service) { + return EAI_NONAME; + } + + if (node) { + if (node[0] == '\0') { + return getaddr_info_single_addr(service, + INADDR_ANY, + &hints, + res); + } else if (hints.ai_flags & AI_NUMERICHOST) { + struct in_addr ip; + if (!inet_aton(node, &ip)) { + return EAI_FAIL; + } + return getaddr_info_single_addr(service, + ntohl(ip.s_addr), + &hints, + res); + } else { + return getaddr_info_name(node, + service, + &hints, + res); + } + } else if (hints.ai_flags & AI_PASSIVE) { + return getaddr_info_single_addr(service, + INADDR_ANY, + &hints, + res); + } + return getaddr_info_single_addr(service, + INADDR_LOOPBACK, + &hints, + res); +} + + +void rep_freeaddrinfo(struct addrinfo *res) +{ + struct addrinfo *next = NULL; + + for (;res; res = next) { + next = res->ai_next; + free(res->ai_canonname); + free(res->ai_addr); + free(res); + } +} + + +const char *rep_gai_strerror(int errcode) +{ +#ifdef HAVE_HSTRERROR + int hcode; + + switch (errcode) + { + case EAI_NONAME: + hcode = HOST_NOT_FOUND; + break; + case EAI_AGAIN: + hcode = TRY_AGAIN; + break; + case EAI_FAIL: + default: + hcode = NO_RECOVERY; + break; + } + + return hstrerror(hcode); +#else /* !HAVE_HSTRERROR */ + + switch (errcode) + { + case EAI_NONAME: + return "Unknown host"; + case EAI_AGAIN: + return "Host name lookup failure"; +#ifdef EAI_BADFLAGS + case EAI_BADFLAGS: + return "Invalid argument"; +#endif +#ifdef EAI_FAMILY + case EAI_FAMILY: + return "Address family not supported"; +#endif +#ifdef EAI_MEMORY + case EAI_MEMORY: + return "Not enough memory"; +#endif +#ifdef EAI_NODATA + case EAI_NODATA: + return "No host data of that type was found"; +#endif +#ifdef EAI_SERVICE + case EAI_SERVICE: + return "Class type not found"; +#endif +#ifdef EAI_SOCKTYPE + case EAI_SOCKTYPE: + return "Socket type not supported"; +#endif + default: + return "Unknown server error"; + } +#endif /* HAVE_HSTRERROR */ +} + +static int gethostnameinfo(const struct sockaddr *sa, + char *node, + size_t nodelen, + int flags) +{ + int ret = -1; + char *p = NULL; + + if (!(flags & NI_NUMERICHOST)) { + struct hostent *hp = gethostbyaddr( + &((struct sockaddr_in *)sa)->sin_addr, + sizeof(struct in_addr), + sa->sa_family); + ret = check_hostent_err(hp); + if (ret == 0) { + /* Name looked up successfully. */ + ret = snprintf(node, nodelen, "%s", hp->h_name); + if (ret < 0 || (size_t)ret >= nodelen) { + return EAI_MEMORY; + } + if (flags & NI_NOFQDN) { + p = strchr(node,'.'); + if (p) { + *p = '\0'; + } + } + return 0; + } + + if (flags & NI_NAMEREQD) { + /* If we require a name and didn't get one, + * automatically fail. */ + return ret; + } + /* Otherwise just fall into the numeric host code... */ + } + p = inet_ntoa(((struct sockaddr_in *)sa)->sin_addr); + ret = snprintf(node, nodelen, "%s", p); + if (ret < 0 || (size_t)ret >= nodelen) { + return EAI_MEMORY; + } + return 0; +} + +static int getservicenameinfo(const struct sockaddr *sa, + char *service, + size_t servicelen, + int flags) +{ + int ret = -1; + int port = ntohs(((struct sockaddr_in *)sa)->sin_port); + + if (!(flags & NI_NUMERICSERV)) { + struct servent *se = getservbyport( + port, + (flags & NI_DGRAM) ? "udp" : "tcp"); + if (se && se->s_name) { + /* Service name looked up successfully. */ + ret = snprintf(service, servicelen, "%s", se->s_name); + if (ret < 0 || (size_t)ret >= servicelen) { + return EAI_MEMORY; + } + return 0; + } + /* Otherwise just fall into the numeric service code... */ + } + ret = snprintf(service, servicelen, "%d", port); + if (ret < 0 || (size_t)ret >= servicelen) { + return EAI_MEMORY; + } + return 0; +} + +/* + * Convert an ipv4 address to a hostname. + * + * Bugs: - No IPv6 support. + */ +int rep_getnameinfo(const struct sockaddr *sa, socklen_t salen, + char *node, size_t nodelen, + char *service, size_t servicelen, int flags) +{ + + /* Invalid arguments. */ + if (sa == NULL || (node == NULL && service == NULL)) { + return EAI_FAIL; + } + + if (sa->sa_family != AF_INET) { + return EAI_FAIL; + } + + if (salen < sizeof(struct sockaddr_in)) { + return EAI_FAIL; + } + + if (node) { + return gethostnameinfo(sa, node, nodelen, flags); + } + + if (service) { + return getservicenameinfo(sa, service, servicelen, flags); + } + return 0; +} diff --git a/ldb-2.0.8/lib/replace/getaddrinfo.h b/ldb-2.0.8/lib/replace/getaddrinfo.h new file mode 100644 index 0000000..cf040da --- /dev/null +++ b/ldb-2.0.8/lib/replace/getaddrinfo.h @@ -0,0 +1,91 @@ +/* +PostgreSQL Database Management System +(formerly known as Postgres, then as Postgres95) + +Portions Copyright (c) 1996-2005, The PostgreSQL Global Development Group + +Portions Copyright (c) 1994, The Regents of the University of California + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose, without fee, and without a written agreement +is hereby granted, provided that the above copyright notice and this paragraph +and the following two paragraphs appear in all copies. + +IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR +DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING +LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, +EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +*/ + +/*------------------------------------------------------------------------- + * + * getaddrinfo.h + * Support getaddrinfo() on platforms that don't have it. + * + * Note: we use our own routines on platforms that don't HAVE_STRUCT_ADDRINFO, + * whether or not the library routine getaddrinfo() can be found. This + * policy is needed because on some platforms a manually installed libbind.a + * may provide getaddrinfo(), yet the system headers may not provide the + * struct definitions needed to call it. To avoid conflict with the libbind + * definition in such cases, we rename our routines to pg_xxx() via macros. + * + +in lib/replace we use rep_xxx() + + * This code will also work on platforms where struct addrinfo is defined + * in the system headers but no getaddrinfo() can be located. + * + * Copyright (c) 2003-2007, PostgreSQL Global Development Group + * + *------------------------------------------------------------------------- + */ +#ifndef GETADDRINFO_H +#define GETADDRINFO_H + +#ifndef HAVE_GETADDRINFO + +/* Rename private copies per comments above */ +#ifdef getaddrinfo +#undef getaddrinfo +#endif +#define getaddrinfo rep_getaddrinfo +#define HAVE_GETADDRINFO + +#ifdef freeaddrinfo +#undef freeaddrinfo +#endif +#define freeaddrinfo rep_freeaddrinfo +#define HAVE_FREEADDRINFO + +#ifdef gai_strerror +#undef gai_strerror +#endif +#define gai_strerror rep_gai_strerror +#define HAVE_GAI_STRERROR + +#ifdef getnameinfo +#undef getnameinfo +#endif +#define getnameinfo rep_getnameinfo +#ifndef HAVE_GETNAMEINFO +#define HAVE_GETNAMEINFO +#endif + +extern int rep_getaddrinfo(const char *node, const char *service, + const struct addrinfo * hints, struct addrinfo ** res); +extern void rep_freeaddrinfo(struct addrinfo * res); +extern const char *rep_gai_strerror(int errcode); +extern int rep_getnameinfo(const struct sockaddr * sa, socklen_t salen, + char *node, size_t nodelen, + char *service, size_t servicelen, int flags); +#endif /* HAVE_GETADDRINFO */ + +#endif /* GETADDRINFO_H */ diff --git a/ldb-2.0.8/lib/replace/getifaddrs.c b/ldb-2.0.8/lib/replace/getifaddrs.c new file mode 100644 index 0000000..a55ef7e --- /dev/null +++ b/ldb-2.0.8/lib/replace/getifaddrs.c @@ -0,0 +1,383 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Jeremy Allison 2007 + Copyright (C) Jelmer Vernooij 2007 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#include "system/network.h" + +#include +#include +#include + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#ifndef SIOCGIFCONF +#ifdef HAVE_SYS_SOCKIO_H +#include +#endif +#endif + +#ifdef HAVE_IFACE_GETIFADDRS +#define _FOUND_IFACE_ANY +#else + +void rep_freeifaddrs(struct ifaddrs *ifp) +{ + if (ifp != NULL) { + free(ifp->ifa_name); + free(ifp->ifa_addr); + free(ifp->ifa_netmask); + free(ifp->ifa_dstaddr); + freeifaddrs(ifp->ifa_next); + free(ifp); + } +} + +static struct sockaddr *sockaddr_dup(struct sockaddr *sa) +{ + struct sockaddr *ret; + socklen_t socklen; +#ifdef HAVE_SOCKADDR_SA_LEN + socklen = sa->sa_len; +#else + socklen = sizeof(struct sockaddr_storage); +#endif + ret = calloc(1, socklen); + if (ret == NULL) + return NULL; + memcpy(ret, sa, socklen); + return ret; +} +#endif + +#ifdef HAVE_IFACE_IFCONF + +/* this works for Linux 2.2, Solaris 2.5, SunOS4, HPUX 10.20, OSF1 + V4.0, Ultrix 4.4, SCO Unix 3.2, IRIX 6.4 and FreeBSD 3.2. + + It probably also works on any BSD style system. */ + +int rep_getifaddrs(struct ifaddrs **ifap) +{ + struct ifconf ifc; + char buff[8192]; + int fd, i, n; + struct ifreq *ifr=NULL; + struct ifaddrs *curif; + struct ifaddrs *lastif = NULL; + + *ifap = NULL; + + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + return -1; + } + + ifc.ifc_len = sizeof(buff); + ifc.ifc_buf = buff; + + if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) { + close(fd); + return -1; + } + + ifr = ifc.ifc_req; + + n = ifc.ifc_len / sizeof(struct ifreq); + + /* Loop through interfaces, looking for given IP address */ + for (i=n-1; i>=0; i--) { + if (ioctl(fd, SIOCGIFFLAGS, &ifr[i]) == -1) { + freeifaddrs(*ifap); + close(fd); + return -1; + } + + curif = calloc(1, sizeof(struct ifaddrs)); + if (curif == NULL) { + freeifaddrs(*ifap); + close(fd); + return -1; + } + curif->ifa_name = strdup(ifr[i].ifr_name); + if (curif->ifa_name == NULL) { + free(curif); + freeifaddrs(*ifap); + close(fd); + return -1; + } + curif->ifa_flags = ifr[i].ifr_flags; + curif->ifa_dstaddr = NULL; + curif->ifa_data = NULL; + curif->ifa_next = NULL; + + curif->ifa_addr = NULL; + if (ioctl(fd, SIOCGIFADDR, &ifr[i]) != -1) { + curif->ifa_addr = sockaddr_dup(&ifr[i].ifr_addr); + if (curif->ifa_addr == NULL) { + free(curif->ifa_name); + free(curif); + freeifaddrs(*ifap); + close(fd); + return -1; + } + } + + curif->ifa_netmask = NULL; + if (ioctl(fd, SIOCGIFNETMASK, &ifr[i]) != -1) { + curif->ifa_netmask = sockaddr_dup(&ifr[i].ifr_addr); + if (curif->ifa_netmask == NULL) { + if (curif->ifa_addr != NULL) { + free(curif->ifa_addr); + } + free(curif->ifa_name); + free(curif); + freeifaddrs(*ifap); + close(fd); + return -1; + } + } + + if (lastif == NULL) { + *ifap = curif; + } else { + lastif->ifa_next = curif; + } + lastif = curif; + } + + close(fd); + + return 0; +} + +#define _FOUND_IFACE_ANY +#endif /* HAVE_IFACE_IFCONF */ +#ifdef HAVE_IFACE_IFREQ + +#ifndef I_STR +#include +#endif + +/**************************************************************************** +this should cover most of the streams based systems +Thanks to Andrej.Borsenkow@mow.siemens.ru for several ideas in this code +****************************************************************************/ +int rep_getifaddrs(struct ifaddrs **ifap) +{ + struct ifreq ifreq; + struct strioctl strioctl; + char buff[8192]; + int fd, i, n; + struct ifreq *ifr=NULL; + struct ifaddrs *curif; + struct ifaddrs *lastif = NULL; + + *ifap = NULL; + + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + return -1; + } + + strioctl.ic_cmd = SIOCGIFCONF; + strioctl.ic_dp = buff; + strioctl.ic_len = sizeof(buff); + if (ioctl(fd, I_STR, &strioctl) < 0) { + close(fd); + return -1; + } + + /* we can ignore the possible sizeof(int) here as the resulting + number of interface structures won't change */ + n = strioctl.ic_len / sizeof(struct ifreq); + + /* we will assume that the kernel returns the length as an int + at the start of the buffer if the offered size is a + multiple of the structure size plus an int */ + if (n*sizeof(struct ifreq) + sizeof(int) == strioctl.ic_len) { + ifr = (struct ifreq *)(buff + sizeof(int)); + } else { + ifr = (struct ifreq *)buff; + } + + /* Loop through interfaces */ + + for (i = 0; iifa_next = curif; + } + + strioctl.ic_cmd = SIOCGIFFLAGS; + strioctl.ic_dp = (char *)&ifreq; + strioctl.ic_len = sizeof(struct ifreq); + if (ioctl(fd, I_STR, &strioctl) != 0) { + freeifaddrs(*ifap); + return -1; + } + + curif->ifa_flags = ifreq.ifr_flags; + + strioctl.ic_cmd = SIOCGIFADDR; + strioctl.ic_dp = (char *)&ifreq; + strioctl.ic_len = sizeof(struct ifreq); + if (ioctl(fd, I_STR, &strioctl) != 0) { + freeifaddrs(*ifap); + return -1; + } + + curif->ifa_name = strdup(ifreq.ifr_name); + curif->ifa_addr = sockaddr_dup(&ifreq.ifr_addr); + curif->ifa_dstaddr = NULL; + curif->ifa_data = NULL; + curif->ifa_next = NULL; + curif->ifa_netmask = NULL; + + strioctl.ic_cmd = SIOCGIFNETMASK; + strioctl.ic_dp = (char *)&ifreq; + strioctl.ic_len = sizeof(struct ifreq); + if (ioctl(fd, I_STR, &strioctl) != 0) { + freeifaddrs(*ifap); + return -1; + } + + curif->ifa_netmask = sockaddr_dup(&ifreq.ifr_addr); + + lastif = curif; + } + + close(fd); + + return 0; +} + +#define _FOUND_IFACE_ANY +#endif /* HAVE_IFACE_IFREQ */ +#ifdef HAVE_IFACE_AIX + +/**************************************************************************** +this one is for AIX (tested on 4.2) +****************************************************************************/ +int rep_getifaddrs(struct ifaddrs **ifap) +{ + char buff[8192]; + int fd, i; + struct ifconf ifc; + struct ifreq *ifr=NULL; + struct ifaddrs *curif; + struct ifaddrs *lastif = NULL; + + *ifap = NULL; + + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + return -1; + } + + ifc.ifc_len = sizeof(buff); + ifc.ifc_buf = buff; + + if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) { + close(fd); + return -1; + } + + ifr = ifc.ifc_req; + + /* Loop through interfaces */ + i = ifc.ifc_len; + + while (i > 0) { + unsigned int inc; + + inc = ifr->ifr_addr.sa_len; + + if (ioctl(fd, SIOCGIFADDR, ifr) != 0) { + freeaddrinfo(*ifap); + return -1; + } + + curif = calloc(1, sizeof(struct ifaddrs)); + if (lastif == NULL) { + *ifap = curif; + } else { + lastif->ifa_next = curif; + } + + curif->ifa_name = strdup(ifr->ifr_name); + curif->ifa_addr = sockaddr_dup(&ifr->ifr_addr); + curif->ifa_dstaddr = NULL; + curif->ifa_data = NULL; + curif->ifa_netmask = NULL; + curif->ifa_next = NULL; + + if (ioctl(fd, SIOCGIFFLAGS, ifr) != 0) { + freeaddrinfo(*ifap); + return -1; + } + + curif->ifa_flags = ifr->ifr_flags; + + if (ioctl(fd, SIOCGIFNETMASK, ifr) != 0) { + freeaddrinfo(*ifap); + return -1; + } + + curif->ifa_netmask = sockaddr_dup(&ifr->ifr_addr); + + lastif = curif; + + next: + /* + * Patch from Archie Cobbs (archie@whistle.com). The + * addresses in the SIOCGIFCONF interface list have a + * minimum size. Usually this doesn't matter, but if + * your machine has tunnel interfaces, etc. that have + * a zero length "link address", this does matter. */ + + if (inc < sizeof(ifr->ifr_addr)) + inc = sizeof(ifr->ifr_addr); + inc += IFNAMSIZ; + + ifr = (struct ifreq*) (((char*) ifr) + inc); + i -= inc; + } + + close(fd); + return 0; +} + +#define _FOUND_IFACE_ANY +#endif /* HAVE_IFACE_AIX */ +#ifndef _FOUND_IFACE_ANY +int rep_getifaddrs(struct ifaddrs **ifap) +{ + errno = ENOSYS; + return -1; +} +#endif diff --git a/ldb-2.0.8/lib/replace/hdr_replace.h b/ldb-2.0.8/lib/replace/hdr_replace.h new file mode 100644 index 0000000..6cfa50f --- /dev/null +++ b/ldb-2.0.8/lib/replace/hdr_replace.h @@ -0,0 +1,2 @@ +/* this is a replacement header for a missing system header */ +#include "replace.h" diff --git a/ldb-2.0.8/lib/replace/inet_aton.c b/ldb-2.0.8/lib/replace/inet_aton.c new file mode 100644 index 0000000..c6b3bb1 --- /dev/null +++ b/ldb-2.0.8/lib/replace/inet_aton.c @@ -0,0 +1,33 @@ +/* + * Unix SMB/CIFS implementation. + * replacement functions + * Copyright (C) Michael Adam 2008 + * + * ** NOTE! The following LGPL license applies to the replace + * ** library. This does NOT imply that all of Samba is released + * ** under the LGPL + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "replace.h" +#include "system/network.h" + +/** + * We know that we have inet_pton from earlier libreplace checks. + */ +int rep_inet_aton(const char *src, struct in_addr *dst) +{ + return (inet_pton(AF_INET, src, dst) > 0) ? 1 : 0; +} diff --git a/ldb-2.0.8/lib/replace/inet_ntoa.c b/ldb-2.0.8/lib/replace/inet_ntoa.c new file mode 100644 index 0000000..e3b80eb --- /dev/null +++ b/ldb-2.0.8/lib/replace/inet_ntoa.c @@ -0,0 +1,39 @@ +/* + * Unix SMB/CIFS implementation. + * replacement routines for broken systems + * Copyright (C) Andrew Tridgell 2003 + * Copyright (C) Michael Adam 2008 + * + * ** NOTE! The following LGPL license applies to the replace + * ** library. This does NOT imply that all of Samba is released + * ** under the LGPL + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "replace.h" +#include "system/network.h" + +/** + * NOTE: this is not thread safe, but it can't be, either + * since it returns a pointer to static memory. + */ +char *rep_inet_ntoa(struct in_addr ip) +{ + uint8_t *p = (uint8_t *)&ip.s_addr; + static char buf[18]; + slprintf(buf, 17, "%d.%d.%d.%d", + (int)p[0], (int)p[1], (int)p[2], (int)p[3]); + return buf; +} diff --git a/ldb-2.0.8/lib/replace/inet_ntop.c b/ldb-2.0.8/lib/replace/inet_ntop.c new file mode 100644 index 0000000..fb3d8e9 --- /dev/null +++ b/ldb-2.0.8/lib/replace/inet_ntop.c @@ -0,0 +1,191 @@ +/* + * Copyright (C) 1996-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +#include "replace.h" +#include "system/network.h" + +#define NS_INT16SZ 2 +#define NS_IN6ADDRSZ 16 + +/* + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static const char *inet_ntop4(const unsigned char *src, char *dst, + socklen_t size); + +#ifdef AF_INET6 +static const char *inet_ntop6(const unsigned char *src, char *dst, + socklen_t size); +#endif + +/* char * + * isc_net_ntop(af, src, dst, size) + * convert a network format address to presentation format. + * return: + * pointer to presentation format address (`dst'), or NULL (see errno). + * author: + * Paul Vixie, 1996. + */ +const char * +rep_inet_ntop(int af, const void *src, char *dst, socklen_t size) +{ + switch (af) { + case AF_INET: + return (inet_ntop4(src, dst, size)); +#ifdef AF_INET6 + case AF_INET6: + return (inet_ntop6(src, dst, size)); +#endif + default: + errno = EAFNOSUPPORT; + return (NULL); + } + /* NOTREACHED */ +} + +/* const char * + * inet_ntop4(src, dst, size) + * format an IPv4 address + * return: + * `dst' (as a const) + * notes: + * (1) uses no statics + * (2) takes a unsigned char* not an in_addr as input + * author: + * Paul Vixie, 1996. + */ +static const char * +inet_ntop4(const unsigned char *src, char *dst, socklen_t size) +{ + static const char *fmt = "%u.%u.%u.%u"; + char tmp[sizeof "255.255.255.255"]; + size_t len; + + len = snprintf(tmp, sizeof tmp, fmt, src[0], src[1], src[2], src[3]); + if (len >= size) { + errno = ENOSPC; + return (NULL); + } + memcpy(dst, tmp, len + 1); + + return (dst); +} + +/* const char * + * isc_inet_ntop6(src, dst, size) + * convert IPv6 binary address into presentation (printable) format + * author: + * Paul Vixie, 1996. + */ +#ifdef AF_INET6 +static const char * +inet_ntop6(const unsigned char *src, char *dst, socklen_t size) +{ + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; + struct { int base, len; } best, cur; + unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ]; + int i, inc; + + /* + * Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, '\0', sizeof words); + for (i = 0; i < NS_IN6ADDRSZ; i++) + words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + best.base = -1; + best.len = 0; + cur.base = -1; + cur.len = 0; + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { + if (words[i] == 0) { + if (cur.base == -1) + cur.base = i, cur.len = 1; + else + cur.len++; + } else { + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + } + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + } + if (best.base != -1 && best.len < 2) + best.base = -1; + + /* + * Format the result. + */ + tp = tmp; + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { + /* Are we inside the best run of 0x00's? */ + if (best.base != -1 && i >= best.base && + i < (best.base + best.len)) { + if (i == best.base) + *tp++ = ':'; + continue; + } + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) + *tp++ = ':'; + /* Is this address an encapsulated IPv4? */ + if (i == 6 && best.base == 0 && + (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { + if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) + return (NULL); + tp += strlen(tp); + break; + } + inc = snprintf(tp, 5, "%x", words[i]); + if (inc >= 5) { + abort(); + } + tp += inc; + } + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && (best.base + best.len) == + (NS_IN6ADDRSZ / NS_INT16SZ)) + *tp++ = ':'; + *tp++ = '\0'; + + /* + * Check for overflow, copy, and we're done. + */ + if ((size_t)(tp - tmp) > size) { + errno = ENOSPC; + return (NULL); + } + memcpy(dst, tmp, tp - tmp); + return (dst); +} +#endif /* AF_INET6 */ diff --git a/ldb-2.0.8/lib/replace/inet_pton.c b/ldb-2.0.8/lib/replace/inet_pton.c new file mode 100644 index 0000000..80e4865 --- /dev/null +++ b/ldb-2.0.8/lib/replace/inet_pton.c @@ -0,0 +1,213 @@ +/* + * Copyright (C) 1996-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "replace.h" +#include "system/network.h" + +#define NS_INT16SZ 2 +#define NS_INADDRSZ 4 +#define NS_IN6ADDRSZ 16 + +/* + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static int inet_pton4(const char *src, unsigned char *dst); +#ifdef AF_INET6 +static int inet_pton6(const char *src, unsigned char *dst); +#endif + +/* int + * inet_pton(af, src, dst) + * convert from presentation format (which usually means ASCII printable) + * to network format (which is usually some kind of binary format). + * return: + * 1 if the address was valid for the specified address family + * 0 if the address wasn't valid (`dst' is untouched in this case) + * -1 if some other error occurred (`dst' is untouched in this case, too) + * author: + * Paul Vixie, 1996. + */ +int +rep_inet_pton(int af, + const char *src, + void *dst) +{ + switch (af) { + case AF_INET: + return (inet_pton4(src, dst)); +#ifdef AF_INET6 + case AF_INET6: + return (inet_pton6(src, dst)); +#endif + default: + errno = EAFNOSUPPORT; + return (-1); + } + /* NOTREACHED */ +} + +/* int + * inet_pton4(src, dst) + * like inet_aton() but without all the hexadecimal and shorthand. + * return: + * 1 if `src' is a valid dotted quad, else 0. + * notice: + * does not touch `dst' unless it's returning 1. + * author: + * Paul Vixie, 1996. + */ +static int +inet_pton4(src, dst) + const char *src; + unsigned char *dst; +{ + static const char digits[] = "0123456789"; + int saw_digit, octets, ch; + unsigned char tmp[NS_INADDRSZ], *tp; + + saw_digit = 0; + octets = 0; + *(tp = tmp) = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr(digits, ch)) != NULL) { + unsigned int new = *tp * 10 + (pch - digits); + + if (new > 255) + return (0); + *tp = new; + if (! saw_digit) { + if (++octets > 4) + return (0); + saw_digit = 1; + } + } else if (ch == '.' && saw_digit) { + if (octets == 4) + return (0); + *++tp = 0; + saw_digit = 0; + } else + return (0); + } + if (octets < 4) + return (0); + memcpy(dst, tmp, NS_INADDRSZ); + return (1); +} + +/* int + * inet_pton6(src, dst) + * convert presentation level address to network order binary form. + * return: + * 1 if `src' is a valid [RFC1884 2.2] address, else 0. + * notice: + * (1) does not touch `dst' unless it's returning 1. + * (2) :: in a full address is silently ignored. + * credit: + * inspired by Mark Andrews. + * author: + * Paul Vixie, 1996. + */ +#ifdef AF_INET6 +static int +inet_pton6(src, dst) + const char *src; + unsigned char *dst; +{ + static const char xdigits_l[] = "0123456789abcdef", + xdigits_u[] = "0123456789ABCDEF"; + unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; + const char *xdigits, *curtok; + int ch, saw_xdigit; + unsigned int val; + + memset((tp = tmp), '\0', NS_IN6ADDRSZ); + endp = tp + NS_IN6ADDRSZ; + colonp = NULL; + /* Leading :: requires some special handling. */ + if (*src == ':') + if (*++src != ':') + return (0); + curtok = src; + saw_xdigit = 0; + val = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) + pch = strchr((xdigits = xdigits_u), ch); + if (pch != NULL) { + val <<= 4; + val |= (pch - xdigits); + if (val > 0xffff) + return (0); + saw_xdigit = 1; + continue; + } + if (ch == ':') { + curtok = src; + if (!saw_xdigit) { + if (colonp) + return (0); + colonp = tp; + continue; + } + if (tp + NS_INT16SZ > endp) + return (0); + *tp++ = (unsigned char) (val >> 8) & 0xff; + *tp++ = (unsigned char) val & 0xff; + saw_xdigit = 0; + val = 0; + continue; + } + if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && + inet_pton4(curtok, tp) > 0) { + tp += NS_INADDRSZ; + saw_xdigit = 0; + break; /* '\0' was seen by inet_pton4(). */ + } + return (0); + } + if (saw_xdigit) { + if (tp + NS_INT16SZ > endp) + return (0); + *tp++ = (unsigned char) (val >> 8) & 0xff; + *tp++ = (unsigned char) val & 0xff; + } + if (colonp != NULL) { + /* + * Since some memmove()'s erroneously fail to handle + * overlapping regions, we'll do the shift by hand. + */ + const int n = tp - colonp; + int i; + + for (i = 1; i <= n; i++) { + endp[- i] = colonp[n - i]; + colonp[n - i] = 0; + } + tp = endp; + } + if (tp != endp) + return (0); + memcpy(dst, tmp, NS_IN6ADDRSZ); + return (1); +} +#endif diff --git a/ldb-2.0.8/lib/replace/poll.c b/ldb-2.0.8/lib/replace/poll.c new file mode 100644 index 0000000..1105617 --- /dev/null +++ b/ldb-2.0.8/lib/replace/poll.c @@ -0,0 +1,139 @@ +/* + Unix SMB/CIFS implementation. + poll.c - poll wrapper + + This file is based on code from libssh (LGPLv2.1+ at the time it + was downloaded), thus the following copyrights: + + Copyright (c) 2009-2010 by Andreas Schneider + Copyright (c) 2003-2009 by Aris Adamantiadis + Copyright (c) 2009 Aleksandar Kanchev + Copyright (C) Volker Lendecke 2011 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + */ + +#include "replace.h" +#include "system/select.h" +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_SYS_IOCTL_H +#include +#endif + + +int rep_poll(struct pollfd *fds, nfds_t nfds, int timeout) +{ + fd_set rfds, wfds, efds; + struct timeval tv, *ptv; + int max_fd; + int rc; + nfds_t i; + + if ((fds == NULL) && (nfds != 0)) { + errno = EFAULT; + return -1; + } + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&efds); + + rc = 0; + max_fd = 0; + + /* compute fd_sets and find largest descriptor */ + for (i = 0; i < nfds; i++) { + if ((fds[i].fd < 0) || (fds[i].fd >= FD_SETSIZE)) { + fds[i].revents = POLLNVAL; + continue; + } + + if (fds[i].events & (POLLIN | POLLRDNORM)) { + FD_SET(fds[i].fd, &rfds); + } + if (fds[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND)) { + FD_SET(fds[i].fd, &wfds); + } + if (fds[i].events & (POLLPRI | POLLRDBAND)) { + FD_SET(fds[i].fd, &efds); + } + if (fds[i].fd > max_fd && + (fds[i].events & (POLLIN | POLLOUT | POLLPRI | + POLLRDNORM | POLLRDBAND | + POLLWRNORM | POLLWRBAND))) { + max_fd = fds[i].fd; + } + } + + if (timeout < 0) { + ptv = NULL; + } else { + ptv = &tv; + if (timeout == 0) { + tv.tv_sec = 0; + tv.tv_usec = 0; + } else { + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + } + } + + rc = select(max_fd + 1, &rfds, &wfds, &efds, ptv); + if (rc < 0) { + return -1; + } + + for (rc = 0, i = 0; i < nfds; i++) { + if ((fds[i].fd < 0) || (fds[i].fd >= FD_SETSIZE)) { + continue; + } + + fds[i].revents = 0; + + if (FD_ISSET(fds[i].fd, &rfds)) { + int err = errno; + int available = 0; + int ret; + + /* support for POLLHUP */ + ret = ioctl(fds[i].fd, FIONREAD, &available); + if ((ret == -1) || (available == 0)) { + fds[i].revents |= POLLHUP; + } else { + fds[i].revents |= fds[i].events + & (POLLIN | POLLRDNORM); + } + + errno = err; + } + if (FD_ISSET(fds[i].fd, &wfds)) { + fds[i].revents |= fds[i].events + & (POLLOUT | POLLWRNORM | POLLWRBAND); + } + if (FD_ISSET(fds[i].fd, &efds)) { + fds[i].revents |= fds[i].events + & (POLLPRI | POLLRDBAND); + } + if (fds[i].revents & ~POLLHUP) { + rc++; + } + } + return rc; +} diff --git a/ldb-2.0.8/lib/replace/replace-test.h b/ldb-2.0.8/lib/replace/replace-test.h new file mode 100644 index 0000000..ed8e75e --- /dev/null +++ b/ldb-2.0.8/lib/replace/replace-test.h @@ -0,0 +1,9 @@ +#ifndef __LIB_REPLACE_REPLACE_TEST_H__ +#define __LIB_REPLACE_REPLACE_TEST_H__ + +int libreplace_test_strptime(void); +int test_readdir_os2_delete(void); +int getifaddrs_test(void); + +#endif /* __LIB_REPLACE_REPLACE_TEST_H__ */ + diff --git a/ldb-2.0.8/lib/replace/replace-testsuite.h b/ldb-2.0.8/lib/replace/replace-testsuite.h new file mode 100644 index 0000000..b28dbec --- /dev/null +++ b/ldb-2.0.8/lib/replace/replace-testsuite.h @@ -0,0 +1,10 @@ +#ifndef __LIB_REPLACE_REPLACE_TESTSUITE_H__ +#define __LIB_REPLACE_REPLACE_TESTSUITE_H__ + +#include +struct torture_context; + +bool torture_local_replace(struct torture_context *ctx); + +#endif /* __LIB_REPLACE_REPLACE_TESTSUITE_H__ */ + diff --git a/ldb-2.0.8/lib/replace/replace.c b/ldb-2.0.8/lib/replace/replace.c new file mode 100644 index 0000000..a14322b --- /dev/null +++ b/ldb-2.0.8/lib/replace/replace.c @@ -0,0 +1,1058 @@ +/* + Unix SMB/CIFS implementation. + replacement routines for broken systems + Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Jelmer Vernooij 2005-2008 + Copyright (C) Matthieu Patou 2010 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" + +#include "system/filesys.h" +#include "system/time.h" +#include "system/network.h" +#include "system/passwd.h" +#include "system/syslog.h" +#include "system/locale.h" +#include "system/wait.h" + +#ifdef _WIN32 +#define mkdir(d,m) _mkdir(d) +#endif + +void replace_dummy(void); +void replace_dummy(void) {} + +#ifndef HAVE_FTRUNCATE + /******************************************************************* +ftruncate for operating systems that don't have it +********************************************************************/ +int rep_ftruncate(int f, off_t l) +{ +#ifdef HAVE_CHSIZE + return chsize(f,l); +#elif defined(F_FREESP) + struct flock fl; + + fl.l_whence = 0; + fl.l_len = 0; + fl.l_start = l; + fl.l_type = F_WRLCK; + return fcntl(f, F_FREESP, &fl); +#else +#error "you must have a ftruncate function" +#endif +} +#endif /* HAVE_FTRUNCATE */ + + +#ifndef HAVE_STRLCPY +/* + * Like strncpy but does not 0 fill the buffer and always null + * terminates. bufsize is the size of the destination buffer. + * Returns the length of s. + */ +size_t rep_strlcpy(char *d, const char *s, size_t bufsize) +{ + size_t len = strlen(s); + size_t ret = len; + + if (bufsize <= 0) { + return 0; + } + if (len >= bufsize) { + len = bufsize - 1; + } + memcpy(d, s, len); + d[len] = 0; + return ret; +} +#endif + +#ifndef HAVE_STRLCAT +/* like strncat but does not 0 fill the buffer and always null + terminates. bufsize is the length of the buffer, which should + be one more than the maximum resulting string length */ +size_t rep_strlcat(char *d, const char *s, size_t bufsize) +{ + size_t len1 = strnlen(d, bufsize); + size_t len2 = strlen(s); + size_t ret = len1 + len2; + + if (len1+len2 >= bufsize) { + if (bufsize < (len1+1)) { + return ret; + } + len2 = bufsize - (len1+1); + } + if (len2 > 0) { + memcpy(d+len1, s, len2); + d[len1+len2] = 0; + } + return ret; +} +#endif + +#ifndef HAVE_MKTIME +/******************************************************************* +a mktime() replacement for those who don't have it - contributed by +C.A. Lademann +Corrections by richard.kettlewell@kewill.com +********************************************************************/ + +#define MINUTE 60 +#define HOUR 60*MINUTE +#define DAY 24*HOUR +#define YEAR 365*DAY +time_t rep_mktime(struct tm *t) +{ + struct tm *u; + time_t epoch = 0; + int n; + int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + y, m, i; + + if(t->tm_year < 70) + return((time_t)-1); + + n = t->tm_year + 1900 - 1; + epoch = (t->tm_year - 70) * YEAR + + ((n / 4 - n / 100 + n / 400) - (1969 / 4 - 1969 / 100 + 1969 / 400)) * DAY; + + y = t->tm_year + 1900; + m = 0; + + for(i = 0; i < t->tm_mon; i++) { + epoch += mon [m] * DAY; + if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) + epoch += DAY; + + if(++m > 11) { + m = 0; + y++; + } + } + + epoch += (t->tm_mday - 1) * DAY; + epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec; + + if((u = localtime(&epoch)) != NULL) { + t->tm_sec = u->tm_sec; + t->tm_min = u->tm_min; + t->tm_hour = u->tm_hour; + t->tm_mday = u->tm_mday; + t->tm_mon = u->tm_mon; + t->tm_year = u->tm_year; + t->tm_wday = u->tm_wday; + t->tm_yday = u->tm_yday; + t->tm_isdst = u->tm_isdst; + } + + return(epoch); +} +#endif /* !HAVE_MKTIME */ + + +#ifndef HAVE_INITGROUPS +/**************************************************************************** + some systems don't have an initgroups call +****************************************************************************/ +int rep_initgroups(char *name, gid_t id) +{ +#ifndef HAVE_SETGROUPS + /* yikes! no SETGROUPS or INITGROUPS? how can this work? */ + errno = ENOSYS; + return -1; +#else /* HAVE_SETGROUPS */ + +#include + + gid_t *grouplst = NULL; + int max_gr = NGROUPS_MAX; + int ret; + int i,j; + struct group *g; + char *gr; + + if((grouplst = malloc(sizeof(gid_t) * max_gr)) == NULL) { + errno = ENOMEM; + return -1; + } + + grouplst[0] = id; + i = 1; + while (i < max_gr && ((g = (struct group *)getgrent()) != (struct group *)NULL)) { + if (g->gr_gid == id) + continue; + j = 0; + gr = g->gr_mem[0]; + while (gr && (*gr != (char)NULL)) { + if (strcmp(name,gr) == 0) { + grouplst[i] = g->gr_gid; + i++; + gr = (char *)NULL; + break; + } + gr = g->gr_mem[++j]; + } + } + endgrent(); + ret = setgroups(i, grouplst); + free(grouplst); + return ret; +#endif /* HAVE_SETGROUPS */ +} +#endif /* HAVE_INITGROUPS */ + + +#ifndef HAVE_MEMMOVE +/******************************************************************* +safely copies memory, ensuring no overlap problems. +this is only used if the machine does not have its own memmove(). +this is not the fastest algorithm in town, but it will do for our +needs. +********************************************************************/ +void *rep_memmove(void *dest,const void *src,int size) +{ + unsigned long d,s; + int i; + if (dest==src || !size) return(dest); + + d = (unsigned long)dest; + s = (unsigned long)src; + + if ((d >= (s+size)) || (s >= (d+size))) { + /* no overlap */ + memcpy(dest,src,size); + return(dest); + } + + if (d < s) { + /* we can forward copy */ + if (s-d >= sizeof(int) && + !(s%sizeof(int)) && + !(d%sizeof(int)) && + !(size%sizeof(int))) { + /* do it all as words */ + int *idest = (int *)dest; + int *isrc = (int *)src; + size /= sizeof(int); + for (i=0;i= sizeof(int) && + !(s%sizeof(int)) && + !(d%sizeof(int)) && + !(size%sizeof(int))) { + /* do it all as words */ + int *idest = (int *)dest; + int *isrc = (int *)src; + size /= sizeof(int); + for (i=size-1;i>=0;i--) idest[i] = isrc[i]; + } else { + /* simplest */ + char *cdest = (char *)dest; + char *csrc = (char *)src; + for (i=size-1;i>=0;i--) cdest[i] = csrc[i]; + } + } + return(dest); +} +#endif /* HAVE_MEMMOVE */ + +#ifndef HAVE_STRDUP +/**************************************************************************** +duplicate a string +****************************************************************************/ +char *rep_strdup(const char *s) +{ + size_t len; + char *ret; + + if (!s) return(NULL); + + len = strlen(s)+1; + ret = (char *)malloc(len); + if (!ret) return(NULL); + memcpy(ret,s,len); + return(ret); +} +#endif /* HAVE_STRDUP */ + +#ifndef HAVE_SETLINEBUF +void rep_setlinebuf(FILE *stream) +{ + setvbuf(stream, (char *)NULL, _IOLBF, 0); +} +#endif /* HAVE_SETLINEBUF */ + +#ifndef HAVE_VSYSLOG +#ifdef HAVE_SYSLOG +void rep_vsyslog (int facility_priority, const char *format, va_list arglist) +{ + char *msg = NULL; + vasprintf(&msg, format, arglist); + if (!msg) + return; + syslog(facility_priority, "%s", msg); + free(msg); +} +#endif /* HAVE_SYSLOG */ +#endif /* HAVE_VSYSLOG */ + +#ifndef HAVE_STRNLEN +/** + Some platforms don't have strnlen +**/ + size_t rep_strnlen(const char *s, size_t max) +{ + size_t len; + + for (len = 0; len < max; len++) { + if (s[len] == '\0') { + break; + } + } + return len; +} +#endif + +#ifndef HAVE_STRNDUP +/** + Some platforms don't have strndup. +**/ +char *rep_strndup(const char *s, size_t n) +{ + char *ret; + + n = strnlen(s, n); + ret = malloc(n+1); + if (!ret) + return NULL; + memcpy(ret, s, n); + ret[n] = 0; + + return ret; +} +#endif + +#if !defined(HAVE_WAITPID) && defined(HAVE_WAIT4) +int rep_waitpid(pid_t pid,int *status,int options) +{ + return wait4(pid, status, options, NULL); +} +#endif + +#ifndef HAVE_SETEUID +int rep_seteuid(uid_t euid) +{ +#ifdef HAVE_SETRESUID + return setresuid(-1, euid, -1); +#else + errno = ENOSYS; + return -1; +#endif +} +#endif + +#ifndef HAVE_SETEGID +int rep_setegid(gid_t egid) +{ +#ifdef HAVE_SETRESGID + return setresgid(-1, egid, -1); +#else + errno = ENOSYS; + return -1; +#endif +} +#endif + +/******************************************************************* +os/2 also doesn't have chroot +********************************************************************/ +#ifndef HAVE_CHROOT +int rep_chroot(const char *dname) +{ + errno = ENOSYS; + return -1; +} +#endif + +/***************************************************************** + Possibly replace mkstemp if it is broken. +*****************************************************************/ + +#ifndef HAVE_SECURE_MKSTEMP +int rep_mkstemp(char *template) +{ + /* have a reasonable go at emulating it. Hope that + the system mktemp() isn't completely hopeless */ + mktemp(template); + if (template[0] == 0) + return -1; + return open(template, O_CREAT|O_EXCL|O_RDWR, 0600); +} +#endif + +#ifndef HAVE_MKDTEMP +char *rep_mkdtemp(char *template) +{ + char *dname; + + if ((dname = mktemp(template))) { + if (mkdir(dname, 0700) >= 0) { + return dname; + } + } + + return NULL; +} +#endif + +/***************************************************************** + Watch out: this is not thread safe. +*****************************************************************/ + +#ifndef HAVE_PREAD +ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset) +{ + if (lseek(__fd, __offset, SEEK_SET) != __offset) { + return -1; + } + return read(__fd, __buf, __nbytes); +} +#endif + +/***************************************************************** + Watch out: this is not thread safe. +*****************************************************************/ + +#ifndef HAVE_PWRITE +ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset) +{ + if (lseek(__fd, __offset, SEEK_SET) != __offset) { + return -1; + } + return write(__fd, __buf, __nbytes); +} +#endif + +#ifndef HAVE_STRCASESTR +char *rep_strcasestr(const char *haystack, const char *needle) +{ + const char *s; + size_t nlen = strlen(needle); + for (s=haystack;*s;s++) { + if (toupper(*needle) == toupper(*s) && + strncasecmp(s, needle, nlen) == 0) { + return (char *)((uintptr_t)s); + } + } + return NULL; +} +#endif + +#ifndef HAVE_STRSEP +char *rep_strsep(char **pps, const char *delim) +{ + char *ret = *pps; + char *p = *pps; + + if (p == NULL) { + return NULL; + } + p += strcspn(p, delim); + if (*p == '\0') { + *pps = NULL; + } else { + *p = '\0'; + *pps = p + 1; + } + return ret; +} +#endif + +#ifndef HAVE_STRTOK_R +/* based on GLIBC version, copyright Free Software Foundation */ +char *rep_strtok_r(char *s, const char *delim, char **save_ptr) +{ + char *token; + + if (s == NULL) s = *save_ptr; + + s += strspn(s, delim); + if (*s == '\0') { + *save_ptr = s; + return NULL; + } + + token = s; + s = strpbrk(token, delim); + if (s == NULL) { + *save_ptr = token + strlen(token); + } else { + *s = '\0'; + *save_ptr = s + 1; + } + + return token; +} +#endif + + +#ifndef HAVE_STRTOLL +long long int rep_strtoll(const char *str, char **endptr, int base) +{ +#ifdef HAVE_STRTOQ + return strtoq(str, endptr, base); +#elif defined(HAVE___STRTOLL) + return __strtoll(str, endptr, base); +#elif SIZEOF_LONG == SIZEOF_LONG_LONG + return (long long int) strtol(str, endptr, base); +#else +# error "You need a strtoll function" +#endif +} +#else +#ifdef HAVE_BSD_STRTOLL +#undef strtoll +long long int rep_strtoll(const char *str, char **endptr, int base) +{ + int saved_errno = errno; + long long int nb = strtoll(str, endptr, base); + /* With glibc EINVAL is only returned if base is not ok */ + if (errno == EINVAL) { + if (base == 0 || (base >1 && base <37)) { + /* Base was ok so it's because we were not + * able to make the convertion. + * Let's reset errno. + */ + errno = saved_errno; + } + } + return nb; +} +#endif /* HAVE_BSD_STRTOLL */ +#endif /* HAVE_STRTOLL */ + + +#ifndef HAVE_STRTOULL +unsigned long long int rep_strtoull(const char *str, char **endptr, int base) +{ +#ifdef HAVE_STRTOUQ + return strtouq(str, endptr, base); +#elif defined(HAVE___STRTOULL) + return __strtoull(str, endptr, base); +#elif SIZEOF_LONG == SIZEOF_LONG_LONG + return (unsigned long long int) strtoul(str, endptr, base); +#else +# error "You need a strtoull function" +#endif +} +#else +#ifdef HAVE_BSD_STRTOLL +#undef strtoull +unsigned long long int rep_strtoull(const char *str, char **endptr, int base) +{ + int saved_errno = errno; + unsigned long long int nb = strtoull(str, endptr, base); + /* With glibc EINVAL is only returned if base is not ok */ + if (errno == EINVAL) { + if (base == 0 || (base >1 && base <37)) { + /* Base was ok so it's because we were not + * able to make the convertion. + * Let's reset errno. + */ + errno = saved_errno; + } + } + return nb; +} +#endif /* HAVE_BSD_STRTOLL */ +#endif /* HAVE_STRTOULL */ + +#ifndef HAVE_SETENV +int rep_setenv(const char *name, const char *value, int overwrite) +{ + char *p; + size_t l1, l2; + int ret; + + if (!overwrite && getenv(name)) { + return 0; + } + + l1 = strlen(name); + l2 = strlen(value); + + p = malloc(l1+l2+2); + if (p == NULL) { + return -1; + } + memcpy(p, name, l1); + p[l1] = '='; + memcpy(p+l1+1, value, l2); + p[l1+l2+1] = 0; + + ret = putenv(p); + if (ret != 0) { + free(p); + } + + return ret; +} +#endif + +#ifndef HAVE_UNSETENV +int rep_unsetenv(const char *name) +{ + extern char **environ; + size_t len = strlen(name); + size_t i, count; + + if (environ == NULL || getenv(name) == NULL) { + return 0; + } + + for (i=0;environ[i];i++) /* noop */ ; + + count=i; + + for (i=0;i= needlelen) { + char *p = (char *)memchr(haystack, *(const char *)needle, + haystacklen-(needlelen-1)); + if (!p) return NULL; + if (memcmp(p, needle, needlelen) == 0) { + return p; + } + haystack = p+1; + haystacklen -= (p - (const char *)haystack) + 1; + } + return NULL; +} +#endif + +#if !defined(HAVE_VDPRINTF) || !defined(HAVE_C99_VSNPRINTF) +int rep_vdprintf(int fd, const char *format, va_list ap) +{ + char *s = NULL; + int ret; + + vasprintf(&s, format, ap); + if (s == NULL) { + errno = ENOMEM; + return -1; + } + ret = write(fd, s, strlen(s)); + free(s); + return ret; +} +#endif + +#if !defined(HAVE_DPRINTF) || !defined(HAVE_C99_VSNPRINTF) +int rep_dprintf(int fd, const char *format, ...) +{ + int ret; + va_list ap; + + va_start(ap, format); + ret = vdprintf(fd, format, ap); + va_end(ap); + + return ret; +} +#endif + +#ifndef HAVE_GET_CURRENT_DIR_NAME +char *rep_get_current_dir_name(void) +{ + char buf[PATH_MAX+1]; + char *p; + p = getcwd(buf, sizeof(buf)); + if (p == NULL) { + return NULL; + } + return strdup(p); +} +#endif + +#ifndef HAVE_STRERROR_R +int rep_strerror_r(int errnum, char *buf, size_t buflen) +{ + char *s = strerror(errnum); + if (strlen(s)+1 > buflen) { + errno = ERANGE; + return -1; + } + strncpy(buf, s, buflen); + return 0; +} +#elif (!defined(STRERROR_R_XSI_NOT_GNU)) +#undef strerror_r +int rep_strerror_r(int errnum, char *buf, size_t buflen) +{ + char *s = strerror_r(errnum, buf, buflen); + if (s == NULL) { + /* Shouldn't happen, should always get a string */ + return EINVAL; + } + if (s != buf) { + strlcpy(buf, s, buflen); + if (strlen(s) > buflen - 1) { + return ERANGE; + } + } + return 0; + +} +#endif + +#ifndef HAVE_CLOCK_GETTIME +int rep_clock_gettime(clockid_t clk_id, struct timespec *tp) +{ + struct timeval tval; + switch (clk_id) { + case 0: /* CLOCK_REALTIME :*/ +#if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID) + gettimeofday(&tval,NULL); +#else + gettimeofday(&tval); +#endif + tp->tv_sec = tval.tv_sec; + tp->tv_nsec = tval.tv_usec * 1000; + break; + default: + errno = EINVAL; + return -1; + } + return 0; +} +#endif + +#ifndef HAVE_MEMALIGN +void *rep_memalign( size_t align, size_t size ) +{ +#if defined(HAVE_POSIX_MEMALIGN) + void *p = NULL; + int ret = posix_memalign( &p, align, size ); + if ( ret == 0 ) + return p; + + return NULL; +#else + /* On *BSD systems memaligns doesn't exist, but memory will + * be aligned on allocations of > pagesize. */ +#if defined(SYSCONF_SC_PAGESIZE) + size_t pagesize = (size_t)sysconf(_SC_PAGESIZE); +#elif defined(HAVE_GETPAGESIZE) + size_t pagesize = (size_t)getpagesize(); +#else + size_t pagesize = (size_t)-1; +#endif + if (pagesize == (size_t)-1) { + errno = ENOSYS; + return NULL; + } + if (size < pagesize) { + size = pagesize; + } + return malloc(size); +#endif +} +#endif + +#ifndef HAVE_GETPEEREID +int rep_getpeereid(int s, uid_t *uid, gid_t *gid) +{ +#if defined(HAVE_PEERCRED) + struct ucred cred; + socklen_t cred_len = sizeof(struct ucred); + int ret; + +#undef getsockopt + ret = getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void *)&cred, &cred_len); + if (ret != 0) { + return -1; + } + + if (cred_len != sizeof(struct ucred)) { + errno = EINVAL; + return -1; + } + + *uid = cred.uid; + *gid = cred.gid; + return 0; +#else + errno = ENOSYS; + return -1; +#endif +} +#endif + +#ifndef HAVE_USLEEP +int rep_usleep(useconds_t sec) +{ + struct timeval tval; + /* + * Fake it with select... + */ + tval.tv_sec = 0; + tval.tv_usec = usecs/1000; + select(0,NULL,NULL,NULL,&tval); + return 0; +} +#endif /* HAVE_USLEEP */ + +#ifndef HAVE_SETPROCTITLE +void rep_setproctitle(const char *fmt, ...) +{ +} +#endif +#ifndef HAVE_SETPROCTITLE_INIT +void rep_setproctitle_init(int argc, char *argv[], char *envp[]) +{ +} +#endif + +#ifndef HAVE_MEMSET_S +# ifndef RSIZE_MAX +# define RSIZE_MAX (SIZE_MAX >> 1) +# endif + +int rep_memset_s(void *dest, size_t destsz, int ch, size_t count) +{ + if (dest == NULL) { + return EINVAL; + } + + if (destsz > RSIZE_MAX || + count > RSIZE_MAX || + count > destsz) { + return ERANGE; + } + +#if defined(HAVE_MEMSET_EXPLICIT) + memset_explicit(dest, destsz, ch, count); +#else /* HAVE_MEMSET_EXPLICIT */ + memset(dest, ch, count); +# if defined(HAVE_GCC_VOLATILE_MEMORY_PROTECTION) + /* See http://llvm.org/bugs/show_bug.cgi?id=15495 */ + __asm__ volatile("" : : "g"(dest) : "memory"); +# endif /* HAVE_GCC_VOLATILE_MEMORY_PROTECTION */ +#endif /* HAVE_MEMSET_EXPLICIT */ + + return 0; +} +#endif /* HAVE_MEMSET_S */ + +#ifndef HAVE_GETPROGNAME +# ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME +# define PROGNAME_SIZE 32 +static char rep_progname[PROGNAME_SIZE]; +# endif /* HAVE_PROGRAM_INVOCATION_SHORT_NAME */ + +const char *rep_getprogname(void) +{ +#ifdef HAVE_PROGRAM_INVOCATION_SHORT_NAME + return program_invocation_short_name; +#else /* HAVE_PROGRAM_INVOCATION_SHORT_NAME */ + FILE *fp = NULL; + char cmdline[4096] = {0}; + char *p = NULL; + pid_t pid; + size_t nread; + int len; + int rc; + + if (rep_progname[0] != '\0') { + return rep_progname; + } + + len = snprintf(rep_progname, sizeof(rep_progname), "%s", ""); + if (len <= 0) { + return NULL; + } + + pid = getpid(); + if (pid <= 1 || pid == (pid_t)-1) { + return NULL; + } + + len = snprintf(cmdline, + sizeof(cmdline), + "/proc/%u/cmdline", + (unsigned int)pid); + if (len <= 0 || len == sizeof(cmdline)) { + return NULL; + } + + fp = fopen(cmdline, "r"); + if (fp == NULL) { + return NULL; + } + + nread = fread(cmdline, 1, sizeof(cmdline) - 1, fp); + + rc = fclose(fp); + if (rc != 0) { + return NULL; + } + + if (nread == 0) { + return NULL; + } + + cmdline[nread] = '\0'; + + p = strrchr(cmdline, '/'); + if (p != NULL) { + p++; + } else { + p = cmdline; + } + + len = strlen(p); + if (len > PROGNAME_SIZE) { + p[PROGNAME_SIZE - 1] = '\0'; + } + + (void)snprintf(rep_progname, sizeof(rep_progname), "%s", p); + + return rep_progname; +#endif /* HAVE_PROGRAM_INVOCATION_SHORT_NAME */ +} +#endif /* HAVE_GETPROGNAME */ diff --git a/ldb-2.0.8/lib/replace/replace.h b/ldb-2.0.8/lib/replace/replace.h new file mode 100644 index 0000000..1658465 --- /dev/null +++ b/ldb-2.0.8/lib/replace/replace.h @@ -0,0 +1,976 @@ +/* + Unix SMB/CIFS implementation. + + macros to go along with the lib/replace/ portability layer code + + Copyright (C) Andrew Tridgell 2005 + Copyright (C) Jelmer Vernooij 2006-2008 + Copyright (C) Jeremy Allison 2007. + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#ifndef _LIBREPLACE_REPLACE_H +#define _LIBREPLACE_REPLACE_H + +#ifndef NO_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_STANDARDS_H +#include +#endif + +/* + * Needs to be defined before std*.h and string*.h are included + * As it's also needed when Python.h is the first header we + * require a global -D__STDC_WANT_LIB_EXT1__=1 + */ +#ifndef __STDC_WANT_LIB_EXT1__ +#error -D__STDC_WANT_LIB_EXT1__=1 required +#endif + +#include +#include +#include +#include + +#ifndef HAVE_DECL_EWOULDBLOCK +#define EWOULDBLOCK EAGAIN +#endif + +#if defined(_MSC_VER) || defined(__MINGW32__) +#include "win32_replace.h" +#endif + + +#ifdef HAVE_INTTYPES_H +#define __STDC_FORMAT_MACROS +#include +#elif defined(HAVE_STDINT_H) +#include +/* force off HAVE_INTTYPES_H so that roken doesn't try to include both, + which causes a warning storm on irix */ +#undef HAVE_INTTYPES_H +#endif + +#ifdef HAVE_MALLOC_H +#include +#endif + +#ifndef __PRI64_PREFIX +# if __WORDSIZE == 64 && ! defined __APPLE__ +# define __PRI64_PREFIX "l" +# else +# define __PRI64_PREFIX "ll" +# endif +#endif + +/* Decimal notation. */ +#ifndef PRId8 +# define PRId8 "d" +#endif +#ifndef PRId16 +# define PRId16 "d" +#endif +#ifndef PRId32 +# define PRId32 "d" +#endif +#ifndef PRId64 +# define PRId64 __PRI64_PREFIX "d" +#endif + +#ifndef PRIi8 +# define PRIi8 "i" +#endif +#ifndef PRIi16 +# define PRIi16 "i" +#endif +#ifndef PRIi32 +# define PRIi32 "i" +#endif +#ifndef PRIi64 +# define PRIi64 __PRI64_PREFIX "i" +#endif + +#ifndef PRIu8 +# define PRIu8 "u" +#endif +#ifndef PRIu16 +# define PRIu16 "u" +#endif +#ifndef PRIu32 +# define PRIu32 "u" +#endif +#ifndef PRIu64 +# define PRIu64 __PRI64_PREFIX "u" +#endif + +#ifndef SCNd8 +# define SCNd8 "hhd" +#endif +#ifndef SCNd16 +# define SCNd16 "hd" +#endif +#ifndef SCNd32 +# define SCNd32 "d" +#endif +#ifndef SCNd64 +# define SCNd64 __PRI64_PREFIX "d" +#endif + +#ifndef SCNi8 +# define SCNi8 "hhi" +#endif +#ifndef SCNi16 +# define SCNi16 "hi" +#endif +#ifndef SCNi32 +# define SCNi32 "i" +#endif +#ifndef SCNi64 +# define SCNi64 __PRI64_PREFIX "i" +#endif + +#ifndef SCNu8 +# define SCNu8 "hhu" +#endif +#ifndef SCNu16 +# define SCNu16 "hu" +#endif +#ifndef SCNu32 +# define SCNu32 "u" +#endif +#ifndef SCNu64 +# define SCNu64 __PRI64_PREFIX "u" +#endif + +#ifdef HAVE_BSD_STRING_H +#include +#endif + +#ifdef HAVE_BSD_UNISTD_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#endif + +#ifdef HAVE_STRINGS_H +#include +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#ifdef HAVE_SYS_SYSMACROS_H +#include +#endif + +#ifdef HAVE_SETPROCTITLE_H +#include +#endif + +#if STDC_HEADERS +#include +#include +#endif + +#ifdef HAVE_LINUX_TYPES_H +/* + * This is needed as some broken header files require this to be included early + */ +#include +#endif + +#ifndef HAVE_STRERROR +extern char *sys_errlist[]; +#define strerror(i) sys_errlist[i] +#endif + +#ifndef HAVE_ERRNO_DECL +extern int errno; +#endif + +#ifndef HAVE_STRDUP +#define strdup rep_strdup +char *rep_strdup(const char *s); +#endif + +#ifndef HAVE_MEMMOVE +#define memmove rep_memmove +void *rep_memmove(void *dest,const void *src,int size); +#endif + +#ifndef HAVE_MEMMEM +#define memmem rep_memmem +void *rep_memmem(const void *haystack, size_t haystacklen, + const void *needle, size_t needlelen); +#endif + +#ifndef HAVE_MEMALIGN +#define memalign rep_memalign +void *rep_memalign(size_t boundary, size_t size); +#endif + +#ifndef HAVE_MKTIME +#define mktime rep_mktime +/* prototype is in "system/time.h" */ +#endif + +#ifndef HAVE_TIMEGM +#define timegm rep_timegm +/* prototype is in "system/time.h" */ +#endif + +#ifndef HAVE_UTIME +#define utime rep_utime +/* prototype is in "system/time.h" */ +#endif + +#ifndef HAVE_UTIMES +#define utimes rep_utimes +/* prototype is in "system/time.h" */ +#endif + +#ifndef HAVE_STRLCPY +#define strlcpy rep_strlcpy +size_t rep_strlcpy(char *d, const char *s, size_t bufsize); +#endif + +#ifndef HAVE_STRLCAT +#define strlcat rep_strlcat +size_t rep_strlcat(char *d, const char *s, size_t bufsize); +#endif + +#ifndef HAVE_CLOSEFROM +#define closefrom rep_closefrom +int rep_closefrom(int lower); +#endif + + +#if (defined(BROKEN_STRNDUP) || !defined(HAVE_STRNDUP)) +#undef HAVE_STRNDUP +#define strndup rep_strndup +char *rep_strndup(const char *s, size_t n); +#endif + +#if (defined(BROKEN_STRNLEN) || !defined(HAVE_STRNLEN)) +#undef HAVE_STRNLEN +#define strnlen rep_strnlen +size_t rep_strnlen(const char *s, size_t n); +#endif + +#if !defined(HAVE_DECL_ENVIRON) +# ifdef __APPLE__ +# include +# define environ (*_NSGetEnviron()) +# else /* __APPLE__ */ +extern char **environ; +# endif /* __APPLE */ +#endif /* !defined(HAVE_DECL_ENVIRON) */ + +#ifndef HAVE_SETENV +#define setenv rep_setenv +int rep_setenv(const char *name, const char *value, int overwrite); +#else +#ifndef HAVE_SETENV_DECL +int setenv(const char *name, const char *value, int overwrite); +#endif +#endif + +#ifndef HAVE_UNSETENV +#define unsetenv rep_unsetenv +int rep_unsetenv(const char *name); +#endif + +#ifndef HAVE_SETEUID +#define seteuid rep_seteuid +int rep_seteuid(uid_t); +#endif + +#ifndef HAVE_SETEGID +#define setegid rep_setegid +int rep_setegid(gid_t); +#endif + +#if (defined(USE_SETRESUID) && !defined(HAVE_SETRESUID_DECL)) +/* stupid glibc */ +int setresuid(uid_t ruid, uid_t euid, uid_t suid); +#endif +#if (defined(USE_SETRESUID) && !defined(HAVE_SETRESGID_DECL)) +int setresgid(gid_t rgid, gid_t egid, gid_t sgid); +#endif + +#ifndef HAVE_CHOWN +#define chown rep_chown +int rep_chown(const char *path, uid_t uid, gid_t gid); +#endif + +#ifndef HAVE_CHROOT +#define chroot rep_chroot +int rep_chroot(const char *dirname); +#endif + +#ifndef HAVE_LINK +#define link rep_link +int rep_link(const char *oldpath, const char *newpath); +#endif + +#ifndef HAVE_READLINK +#define readlink rep_readlink +ssize_t rep_readlink(const char *path, char *buf, size_t bufsize); +#endif + +#ifndef HAVE_SYMLINK +#define symlink rep_symlink +int rep_symlink(const char *oldpath, const char *newpath); +#endif + +#ifndef HAVE_REALPATH +#define realpath rep_realpath +char *rep_realpath(const char *path, char *resolved_path); +#endif + +#ifndef HAVE_LCHOWN +#define lchown rep_lchown +int rep_lchown(const char *fname,uid_t uid,gid_t gid); +#endif + +#ifdef HAVE_UNIX_H +#include +#endif + +#ifndef HAVE_SETLINEBUF +#define setlinebuf rep_setlinebuf +void rep_setlinebuf(FILE *); +#endif + +#ifndef HAVE_STRCASESTR +#define strcasestr rep_strcasestr +char *rep_strcasestr(const char *haystack, const char *needle); +#endif + +#ifndef HAVE_STRSEP +#define strsep rep_strsep +char *rep_strsep(char **pps, const char *delim); +#endif + +#ifndef HAVE_STRTOK_R +#define strtok_r rep_strtok_r +char *rep_strtok_r(char *s, const char *delim, char **save_ptr); +#endif + + + +#ifndef HAVE_STRTOLL +#define strtoll rep_strtoll +long long int rep_strtoll(const char *str, char **endptr, int base); +#else +#ifdef HAVE_BSD_STRTOLL +#define strtoll rep_strtoll +long long int rep_strtoll(const char *str, char **endptr, int base); +#endif +#endif + +#ifndef HAVE_STRTOULL +#define strtoull rep_strtoull +unsigned long long int rep_strtoull(const char *str, char **endptr, int base); +#else +#ifdef HAVE_BSD_STRTOLL /* yes, it's not HAVE_BSD_STRTOULL */ +#define strtoull rep_strtoull +unsigned long long int rep_strtoull(const char *str, char **endptr, int base); +#endif +#endif + +#ifndef HAVE_FTRUNCATE +#define ftruncate rep_ftruncate +int rep_ftruncate(int,off_t); +#endif + +#ifndef HAVE_INITGROUPS +#define initgroups rep_initgroups +int rep_initgroups(char *name, gid_t id); +#endif + +#if !defined(HAVE_BZERO) && defined(HAVE_MEMSET) +#define bzero(a,b) memset((a),'\0',(b)) +#endif + +#ifndef HAVE_DLERROR +#define dlerror rep_dlerror +char *rep_dlerror(void); +#endif + +#ifndef HAVE_DLOPEN +#define dlopen rep_dlopen +#ifdef DLOPEN_TAKES_UNSIGNED_FLAGS +void *rep_dlopen(const char *name, unsigned int flags); +#else +void *rep_dlopen(const char *name, int flags); +#endif +#endif + +#ifndef HAVE_DLSYM +#define dlsym rep_dlsym +void *rep_dlsym(void *handle, const char *symbol); +#endif + +#ifndef HAVE_DLCLOSE +#define dlclose rep_dlclose +int rep_dlclose(void *handle); +#endif + +#ifndef HAVE_SOCKETPAIR +#define socketpair rep_socketpair +/* prototype is in system/network.h */ +#endif + +#ifndef PRINTF_ATTRIBUTE +#ifdef HAVE___ATTRIBUTE__ +/** Use gcc attribute to check printf fns. a1 is the 1-based index of + * the parameter containing the format, and a2 the index of the first + * argument. Note that some gcc 2.x versions don't handle this + * properly **/ +#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) +#else +#define PRINTF_ATTRIBUTE(a1, a2) +#endif +#endif + +#ifndef _DEPRECATED_ +#ifdef HAVE___ATTRIBUTE__ +#define _DEPRECATED_ __attribute__ ((deprecated)) +#else +#define _DEPRECATED_ +#endif +#endif + +#if !defined(HAVE_VDPRINTF) || !defined(HAVE_C99_VSNPRINTF) +#define vdprintf rep_vdprintf +int rep_vdprintf(int fd, const char *format, va_list ap) PRINTF_ATTRIBUTE(2,0); +#endif + +#if !defined(HAVE_DPRINTF) || !defined(HAVE_C99_VSNPRINTF) +#define dprintf rep_dprintf +int rep_dprintf(int fd, const char *format, ...) PRINTF_ATTRIBUTE(2,3); +#endif + +#if !defined(HAVE_VASPRINTF) || !defined(HAVE_C99_VSNPRINTF) +#define vasprintf rep_vasprintf +int rep_vasprintf(char **ptr, const char *format, va_list ap) PRINTF_ATTRIBUTE(2,0); +#endif + +#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF) +#define snprintf rep_snprintf +int rep_snprintf(char *,size_t ,const char *, ...) PRINTF_ATTRIBUTE(3,4); +#endif + +#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF) +#define vsnprintf rep_vsnprintf +int rep_vsnprintf(char *,size_t ,const char *, va_list ap) PRINTF_ATTRIBUTE(3,0); +#endif + +#if !defined(HAVE_ASPRINTF) || !defined(HAVE_C99_VSNPRINTF) +#define asprintf rep_asprintf +int rep_asprintf(char **,const char *, ...) PRINTF_ATTRIBUTE(2,3); +#endif + +#if !defined(HAVE_C99_VSNPRINTF) +#ifdef REPLACE_BROKEN_PRINTF +/* + * We do not redefine printf by default + * as it breaks the build if system headers + * use __attribute__((format(printf, 3, 0))) + * instead of __attribute__((format(__printf__, 3, 0))) + */ +#define printf rep_printf +#endif +int rep_printf(const char *, ...) PRINTF_ATTRIBUTE(1,2); +#endif + +#if !defined(HAVE_C99_VSNPRINTF) +#define fprintf rep_fprintf +int rep_fprintf(FILE *stream, const char *, ...) PRINTF_ATTRIBUTE(2,3); +#endif + +#ifndef HAVE_VSYSLOG +#ifdef HAVE_SYSLOG +#define vsyslog rep_vsyslog +void rep_vsyslog (int facility_priority, const char *format, va_list arglist) PRINTF_ATTRIBUTE(2,0); +#endif +#endif + +/* we used to use these fns, but now we have good replacements + for snprintf and vsnprintf */ +#define slprintf snprintf + + +#ifndef HAVE_VA_COPY +#undef va_copy +#ifdef HAVE___VA_COPY +#define va_copy(dest, src) __va_copy(dest, src) +#else +#define va_copy(dest, src) (dest) = (src) +#endif +#endif + +#ifndef HAVE_VOLATILE +#define volatile +#endif + +#ifndef HAVE_COMPARISON_FN_T +typedef int (*comparison_fn_t)(const void *, const void *); +#endif + +#ifndef HAVE_WORKING_STRPTIME +#define strptime rep_strptime +struct tm; +char *rep_strptime(const char *buf, const char *format, struct tm *tm); +#endif + +#ifndef HAVE_DUP2 +#define dup2 rep_dup2 +int rep_dup2(int oldfd, int newfd); +#endif + +/* Load header file for dynamic linking stuff */ +#ifdef HAVE_DLFCN_H +#include +#endif + +#ifndef RTLD_LAZY +#define RTLD_LAZY 0 +#endif +#ifndef RTLD_NOW +#define RTLD_NOW 0 +#endif +#ifndef RTLD_GLOBAL +#define RTLD_GLOBAL 0 +#endif + +#ifndef HAVE_SECURE_MKSTEMP +#define mkstemp(path) rep_mkstemp(path) +int rep_mkstemp(char *temp); +#endif + +#ifndef HAVE_MKDTEMP +#define mkdtemp rep_mkdtemp +char *rep_mkdtemp(char *template); +#endif + +#ifndef HAVE_PREAD +#define pread rep_pread +ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset); +#define LIBREPLACE_PREAD_REPLACED 1 +#else +#define LIBREPLACE_PREAD_NOT_REPLACED 1 +#endif + +#ifndef HAVE_PWRITE +#define pwrite rep_pwrite +ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset); +#define LIBREPLACE_PWRITE_REPLACED 1 +#else +#define LIBREPLACE_PWRITE_NOT_REPLACED 1 +#endif + +#if !defined(HAVE_INET_NTOA) || defined(REPLACE_INET_NTOA) +#define inet_ntoa rep_inet_ntoa +/* prototype is in "system/network.h" */ +#endif + +#ifndef HAVE_INET_PTON +#define inet_pton rep_inet_pton +/* prototype is in "system/network.h" */ +#endif + +#ifndef HAVE_INET_NTOP +#define inet_ntop rep_inet_ntop +/* prototype is in "system/network.h" */ +#endif + +#ifndef HAVE_INET_ATON +#define inet_aton rep_inet_aton +/* prototype is in "system/network.h" */ +#endif + +#ifndef HAVE_CONNECT +#define connect rep_connect +/* prototype is in "system/network.h" */ +#endif + +#ifndef HAVE_GETHOSTBYNAME +#define gethostbyname rep_gethostbyname +/* prototype is in "system/network.h" */ +#endif + +#ifndef HAVE_GETIFADDRS +#define getifaddrs rep_getifaddrs +/* prototype is in "system/network.h" */ +#endif + +#ifndef HAVE_FREEIFADDRS +#define freeifaddrs rep_freeifaddrs +/* prototype is in "system/network.h" */ +#endif + +#ifndef HAVE_GET_CURRENT_DIR_NAME +#define get_current_dir_name rep_get_current_dir_name +char *rep_get_current_dir_name(void); +#endif + +#if (!defined(HAVE_STRERROR_R) || !defined(STRERROR_R_XSI_NOT_GNU)) +#define strerror_r rep_strerror_r +int rep_strerror_r(int errnum, char *buf, size_t buflen); +#endif + +#if !defined(HAVE_CLOCK_GETTIME) +#define clock_gettime rep_clock_gettime +#endif + +#ifdef HAVE_LIMITS_H +#include +#endif + +#ifdef HAVE_SYS_PARAM_H +#include +#endif + +/* The extra casts work around common compiler bugs. */ +#define _TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) +/* The outer cast is needed to work around a bug in Cray C 5.0.3.0. + It is necessary at least when t == time_t. */ +#define _TYPE_MINIMUM(t) ((t) (_TYPE_SIGNED (t) \ + ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0)) +#define _TYPE_MAXIMUM(t) ((t) (~ (t) 0 - _TYPE_MINIMUM (t))) + +#ifndef UINT16_MAX +#define UINT16_MAX 65535 +#endif + +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef UINT64_MAX +#define UINT64_MAX ((uint64_t)-1) +#endif + +#ifndef INT64_MAX +#define INT64_MAX 9223372036854775807LL +#endif + +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif + +#ifndef INT32_MAX +#define INT32_MAX _TYPE_MAXIMUM(int32_t) +#endif + +#ifdef HAVE_STDBOOL_H +#include +#endif + +#if !defined(HAVE_BOOL) +#ifdef HAVE__Bool +#define bool _Bool +#else +typedef int bool; +#endif +#endif + +#if !defined(HAVE_INTPTR_T) +typedef long long intptr_t ; +#define __intptr_t_defined +#endif + +#if !defined(HAVE_UINTPTR_T) +typedef unsigned long long uintptr_t ; +#define __uintptr_t_defined +#endif + +#if !defined(HAVE_PTRDIFF_T) +typedef unsigned long long ptrdiff_t ; +#endif + +/* + * to prevent from doing a redefine of 'bool' + * + * IRIX, HPUX, MacOS 10 and Solaris need BOOL_DEFINED + * Tru64 needs _BOOL_EXISTS + * AIX needs _BOOL,_TRUE,_FALSE + */ +#ifndef BOOL_DEFINED +#define BOOL_DEFINED +#endif +#ifndef _BOOL_EXISTS +#define _BOOL_EXISTS +#endif +#ifndef _BOOL +#define _BOOL +#endif + +#ifndef __bool_true_false_are_defined +#define __bool_true_false_are_defined +#endif + +#ifndef true +#define true (1) +#endif +#ifndef false +#define false (0) +#endif + +#ifndef _TRUE +#define _TRUE true +#endif +#ifndef _FALSE +#define _FALSE false +#endif + +#ifndef HAVE_FUNCTION_MACRO +#ifdef HAVE_func_MACRO +#define __FUNCTION__ __func__ +#else +#define __FUNCTION__ ("") +#endif +#endif + + +#ifndef MIN +#define MIN(a,b) ((a)<(b)?(a):(b)) +#endif + +#ifndef MAX +#define MAX(a,b) ((a)>(b)?(a):(b)) +#endif + +#if !defined(HAVE_VOLATILE) +#define volatile +#endif + +/** + this is a warning hack. The idea is to use this everywhere that we + get the "discarding const" warning from gcc. That doesn't actually + fix the problem of course, but it means that when we do get to + cleaning them up we can do it by searching the code for + discard_const. + + It also means that other error types aren't as swamped by the noise + of hundreds of const warnings, so we are more likely to notice when + we get new errors. + + Please only add more uses of this macro when you find it + _really_ hard to fix const warnings. Our aim is to eventually use + this function in only a very few places. + + Also, please call this via the discard_const_p() macro interface, as that + makes the return type safe. +*/ +#define discard_const(ptr) ((void *)((uintptr_t)(ptr))) + +/** Type-safe version of discard_const */ +#define discard_const_p(type, ptr) ((type *)discard_const(ptr)) + +#ifndef __STRING +#define __STRING(x) #x +#endif + +#ifndef __STRINGSTRING +#define __STRINGSTRING(x) __STRING(x) +#endif + +#ifndef __LINESTR__ +#define __LINESTR__ __STRINGSTRING(__LINE__) +#endif + +#ifndef __location__ +#define __location__ __FILE__ ":" __LINESTR__ +#endif + +/** + * Zero a structure. + */ +#define ZERO_STRUCT(x) memset_s((char *)&(x), sizeof(x), 0, sizeof(x)) + +/** + * Zero a structure given a pointer to the structure. + */ +#define ZERO_STRUCTP(x) do { \ + if ((x) != NULL) { \ + memset_s((char *)(x), sizeof(*(x)), 0, sizeof(*(x))); \ + } \ +} while(0) + +/** + * Zero a structure given a pointer to the structure - no zero check + */ +#define ZERO_STRUCTPN(x) memset_s((char *)(x), sizeof(*(x)), 0, sizeof(*(x))) + +/** + * Zero an array - note that sizeof(array) must work - ie. it must not be a + * pointer + */ +#define ZERO_ARRAY(x) memset_s((char *)(x), sizeof(x), 0, sizeof(x)) + +/** + * Zero a given len of an array + */ +#define ZERO_ARRAY_LEN(x, l) memset_s((char *)(x), (l), 0, (l)) + +/** + * Work out how many elements there are in a static array. + */ +#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) + +/** + * Pointer difference macro + */ +#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((const char *)(p1)) - (const char *)(p2))) + +#ifdef __COMPAR_FN_T +#define QSORT_CAST (__compar_fn_t) +#endif + +#ifndef QSORT_CAST +#define QSORT_CAST (int (*)(const void *, const void *)) +#endif + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +#ifndef MAX_DNS_NAME_LENGTH +#define MAX_DNS_NAME_LENGTH 256 /* Actually 255 but +1 for terminating null. */ +#endif + +#ifndef HAVE_CRYPT +char *ufc_crypt(const char *key, const char *salt); +#define crypt ufc_crypt +#else +#ifdef HAVE_CRYPT_H +#include +#endif +#endif + +/* these macros gain us a few percent of speed on gcc */ +#if (__GNUC__ >= 3) +/* the strange !! is to ensure that __builtin_expect() takes either 0 or 1 + as its first argument */ +#ifndef likely +#define likely(x) __builtin_expect(!!(x), 1) +#endif +#ifndef unlikely +#define unlikely(x) __builtin_expect(!!(x), 0) +#endif +#else +#ifndef likely +#define likely(x) (x) +#endif +#ifndef unlikely +#define unlikely(x) (x) +#endif +#endif + +#ifndef HAVE_FDATASYNC +#define fdatasync(fd) fsync(fd) +#elif !defined(HAVE_DECL_FDATASYNC) +int fdatasync(int ); +#endif + +/* these are used to mark symbols as local to a shared lib, or + * publicly available via the shared lib API */ +#ifndef _PUBLIC_ +#ifdef HAVE_VISIBILITY_ATTR +#define _PUBLIC_ __attribute__((visibility("default"))) +#else +#define _PUBLIC_ +#endif +#endif + +#ifndef _PRIVATE_ +#ifdef HAVE_VISIBILITY_ATTR +# define _PRIVATE_ __attribute__((visibility("hidden"))) +#else +# define _PRIVATE_ +#endif +#endif + +#ifndef HAVE_POLL +#define poll rep_poll +/* prototype is in "system/network.h" */ +#endif + +#ifndef HAVE_GETPEEREID +#define getpeereid rep_getpeereid +int rep_getpeereid(int s, uid_t *uid, gid_t *gid); +#endif + +#ifndef HAVE_USLEEP +#define usleep rep_usleep +typedef long useconds_t; +int usleep(useconds_t); +#endif + +#ifndef HAVE_SETPROCTITLE +#define setproctitle rep_setproctitle +void rep_setproctitle(const char *fmt, ...) PRINTF_ATTRIBUTE(1, 2); +#endif + +#ifndef HAVE_SETPROCTITLE_INIT +#define setproctitle_init rep_setproctitle_init +void rep_setproctitle_init(int argc, char *argv[], char *envp[]); +#endif + +#ifndef HAVE_MEMSET_S +#define memset_s rep_memset_s +int rep_memset_s(void *dest, size_t destsz, int ch, size_t count); +#endif + +#ifndef HAVE_GETPROGNAME +#define getprogname rep_getprogname +const char *rep_getprogname(void); +#endif + +#ifndef FALL_THROUGH +# ifdef HAVE_FALLTHROUGH_ATTRIBUTE +# define FALL_THROUGH __attribute__ ((fallthrough)) +# else /* HAVE_FALLTHROUGH_ATTRIBUTE */ +# define FALL_THROUGH ((void)0) +# endif /* HAVE_FALLTHROUGH_ATTRIBUTE */ +#endif /* FALL_THROUGH */ + +bool nss_wrapper_enabled(void); +bool nss_wrapper_hosts_enabled(void); +bool socket_wrapper_enabled(void); +bool uid_wrapper_enabled(void); + +/* Needed for Solaris atomic_add_XX functions. */ +#if defined(HAVE_SYS_ATOMIC_H) +#include +#endif + +#endif /* _LIBREPLACE_REPLACE_H */ diff --git a/ldb-2.0.8/lib/replace/snprintf.c b/ldb-2.0.8/lib/replace/snprintf.c new file mode 100644 index 0000000..6e4424b --- /dev/null +++ b/ldb-2.0.8/lib/replace/snprintf.c @@ -0,0 +1,1534 @@ +/* + * NOTE: If you change this file, please merge it into rsync, samba, etc. + */ + +/* + * Copyright Patrick Powell 1995 + * This code is based on code written by Patrick Powell (papowell@astart.com) + * It may be used for any purpose as long as this notice remains intact + * on all source code distributions + */ + +/************************************************************** + * Original: + * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 + * A bombproof version of doprnt (dopr) included. + * Sigh. This sort of thing is always nasty do deal with. Note that + * the version here does not include floating point... + * + * snprintf() is used instead of sprintf() as it does limit checks + * for string length. This covers a nasty loophole. + * + * The other functions are there to prevent NULL pointers from + * causing nast effects. + * + * More Recently: + * Brandon Long 9/15/96 for mutt 0.43 + * This was ugly. It is still ugly. I opted out of floating point + * numbers, but the formatter understands just about everything + * from the normal C string format, at least as far as I can tell from + * the Solaris 2.5 printf(3S) man page. + * + * Brandon Long 10/22/97 for mutt 0.87.1 + * Ok, added some minimal floating point support, which means this + * probably requires libm on most operating systems. Don't yet + * support the exponent (e,E) and sigfig (g,G). Also, fmtint() + * was pretty badly broken, it just wasn't being exercised in ways + * which showed it, so that's been fixed. Also, formatted the code + * to mutt conventions, and removed dead code left over from the + * original. Also, there is now a builtin-test, just compile with: + * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm + * and run snprintf for results. + * + * Thomas Roessler 01/27/98 for mutt 0.89i + * The PGP code was using unsigned hexadecimal formats. + * Unfortunately, unsigned formats simply didn't work. + * + * Michael Elkins 03/05/98 for mutt 0.90.8 + * The original code assumed that both snprintf() and vsnprintf() were + * missing. Some systems only have snprintf() but not vsnprintf(), so + * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. + * + * Andrew Tridgell (tridge@samba.org) Oct 1998 + * fixed handling of %.0f + * added test for HAVE_LONG_DOUBLE + * + * tridge@samba.org, idra@samba.org, April 2001 + * got rid of fcvt code (twas buggy and made testing harder) + * added C99 semantics + * + * date: 2002/12/19 19:56:31; author: herb; state: Exp; lines: +2 -0 + * actually print args for %g and %e + * + * date: 2002/06/03 13:37:52; author: jmcd; state: Exp; lines: +8 -0 + * Since includes.h isn't included here, VA_COPY has to be defined here. I don't + * see any include file that is guaranteed to be here, so I'm defining it + * locally. Fixes AIX and Solaris builds. + * + * date: 2002/06/03 03:07:24; author: tridge; state: Exp; lines: +5 -13 + * put the ifdef for HAVE_VA_COPY in one place rather than in lots of + * functions + * + * date: 2002/05/17 14:51:22; author: jmcd; state: Exp; lines: +21 -4 + * Fix usage of va_list passed as an arg. Use __va_copy before using it + * when it exists. + * + * date: 2002/04/16 22:38:04; author: idra; state: Exp; lines: +20 -14 + * Fix incorrect zpadlen handling in fmtfp. + * Thanks to Ollie Oldham for spotting it. + * few mods to make it easier to compile the tests. + * addedd the "Ollie" test to the floating point ones. + * + * Martin Pool (mbp@samba.org) April 2003 + * Remove NO_CONFIG_H so that the test case can be built within a source + * tree with less trouble. + * Remove unnecessary SAFE_FREE() definition. + * + * Martin Pool (mbp@samba.org) May 2003 + * Put in a prototype for dummy_snprintf() to quiet compiler warnings. + * + * Move #endif to make sure VA_COPY, LDOUBLE, etc are defined even + * if the C library has some snprintf functions already. + * + * Darren Tucker (dtucker@zip.com.au) 2005 + * Fix bug allowing read overruns of the source string with "%.*s" + * Usually harmless unless the read runs outside the process' allocation + * (eg if your malloc does guard pages) in which case it will segfault. + * From OpenSSH. Also added test for same. + * + * Simo Sorce (idra@samba.org) Jan 2006 + * + * Add support for position independent parameters + * fix fmtstr now it conforms to sprintf wrt min.max + * + **************************************************************/ + +#include "replace.h" +#include "system/locale.h" + +#ifdef TEST_SNPRINTF /* need math library headers for testing */ + +/* In test mode, we pretend that this system doesn't have any snprintf + * functions, regardless of what config.h says. */ +# undef HAVE_SNPRINTF +# undef HAVE_VSNPRINTF +# undef HAVE_C99_VSNPRINTF +# undef HAVE_ASPRINTF +# undef HAVE_VASPRINTF +# include +#endif /* TEST_SNPRINTF */ + +#if defined(HAVE_SNPRINTF) && defined(HAVE_VSNPRINTF) && defined(HAVE_C99_VSNPRINTF) +/* only include stdio.h if we are not re-defining snprintf or vsnprintf */ +#include + /* make the compiler happy with an empty file */ + void dummy_snprintf(void); + void dummy_snprintf(void) {} +#endif /* HAVE_SNPRINTF, etc */ + +/* yes this really must be a ||. Don't muck with this (tridge) */ +#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF) + +#ifdef HAVE_LONG_DOUBLE +#define LDOUBLE long double +#else +#define LDOUBLE double +#endif + +#ifdef HAVE_LONG_LONG +#define LLONG long long +#else +#define LLONG long +#endif + +#ifndef VA_COPY +#ifdef HAVE_VA_COPY +#define VA_COPY(dest, src) va_copy(dest, src) +#else +#ifdef HAVE___VA_COPY +#define VA_COPY(dest, src) __va_copy(dest, src) +#else +#define VA_COPY(dest, src) (dest) = (src) +#endif +#endif + +/* + * dopr(): poor man's version of doprintf + */ + +/* format read states */ +#define DP_S_DEFAULT 0 +#define DP_S_FLAGS 1 +#define DP_S_MIN 2 +#define DP_S_DOT 3 +#define DP_S_MAX 4 +#define DP_S_MOD 5 +#define DP_S_CONV 6 +#define DP_S_DONE 7 + +/* format flags - Bits */ +#define DP_F_MINUS (1 << 0) +#define DP_F_PLUS (1 << 1) +#define DP_F_SPACE (1 << 2) +#define DP_F_NUM (1 << 3) +#define DP_F_ZERO (1 << 4) +#define DP_F_UP (1 << 5) +#define DP_F_UNSIGNED (1 << 6) + +/* Conversion Flags */ +#define DP_C_CHAR 1 +#define DP_C_SHORT 2 +#define DP_C_LONG 3 +#define DP_C_LDOUBLE 4 +#define DP_C_LLONG 5 +#define DP_C_SIZET 6 + +/* Chunk types */ +#define CNK_FMT_STR 0 +#define CNK_INT 1 +#define CNK_OCTAL 2 +#define CNK_UINT 3 +#define CNK_HEX 4 +#define CNK_FLOAT 5 +#define CNK_CHAR 6 +#define CNK_STRING 7 +#define CNK_PTR 8 +#define CNK_NUM 9 +#define CNK_PRCNT 10 + +#define char_to_int(p) ((p)- '0') +#ifndef MAX +#define MAX(p,q) (((p) >= (q)) ? (p) : (q)) +#endif + +struct pr_chunk { + int type; /* chunk type */ + int num; /* parameter number */ + int min; + int max; + int flags; + int cflags; + int start; + int len; + LLONG value; + LDOUBLE fvalue; + char *strvalue; + void *pnum; + struct pr_chunk *min_star; + struct pr_chunk *max_star; + struct pr_chunk *next; +}; + +struct pr_chunk_x { + struct pr_chunk **chunks; + int num; +}; + +static int dopr(char *buffer, size_t maxlen, const char *format, + va_list args_in); +static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, + char *value, int flags, int min, int max); +static void fmtint(char *buffer, size_t *currlen, size_t maxlen, + LLONG value, int base, int min, int max, int flags); +static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, + LDOUBLE fvalue, int min, int max, int flags); +static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); +static struct pr_chunk *new_chunk(void); +static int add_cnk_list_entry(struct pr_chunk_x **list, + int max_num, struct pr_chunk *chunk); + +static int dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) +{ + char ch; + int state; + int pflag; + int pnum; + int pfirst; + size_t currlen; + va_list args; + const char *base; + struct pr_chunk *chunks = NULL; + struct pr_chunk *cnk = NULL; + struct pr_chunk_x *clist = NULL; + int max_pos; + int ret = -1; + + VA_COPY(args, args_in); + + state = DP_S_DEFAULT; + pfirst = 1; + pflag = 0; + pnum = 0; + + max_pos = 0; + base = format; + ch = *format++; + + /* retrieve the string structure as chunks */ + while (state != DP_S_DONE) { + if (ch == '\0') + state = DP_S_DONE; + + switch(state) { + case DP_S_DEFAULT: + + if (cnk) { + cnk->next = new_chunk(); + cnk = cnk->next; + } else { + cnk = new_chunk(); + } + if (!cnk) goto done; + if (!chunks) chunks = cnk; + + if (ch == '%') { + state = DP_S_FLAGS; + ch = *format++; + } else { + cnk->type = CNK_FMT_STR; + cnk->start = format - base -1; + while ((ch != '\0') && (ch != '%')) ch = *format++; + cnk->len = format - base - cnk->start -1; + } + break; + case DP_S_FLAGS: + switch (ch) { + case '-': + cnk->flags |= DP_F_MINUS; + ch = *format++; + break; + case '+': + cnk->flags |= DP_F_PLUS; + ch = *format++; + break; + case ' ': + cnk->flags |= DP_F_SPACE; + ch = *format++; + break; + case '#': + cnk->flags |= DP_F_NUM; + ch = *format++; + break; + case '0': + cnk->flags |= DP_F_ZERO; + ch = *format++; + break; + case 'I': + /* internationalization not supported yet */ + ch = *format++; + break; + default: + state = DP_S_MIN; + break; + } + break; + case DP_S_MIN: + if (isdigit((unsigned char)ch)) { + cnk->min = 10 * cnk->min + char_to_int (ch); + ch = *format++; + } else if (ch == '$') { + if (!pfirst && !pflag) { + /* parameters must be all positioned or none */ + goto done; + } + if (pfirst) { + pfirst = 0; + pflag = 1; + } + if (cnk->min == 0) /* what ?? */ + goto done; + cnk->num = cnk->min; + cnk->min = 0; + ch = *format++; + } else if (ch == '*') { + if (pfirst) pfirst = 0; + cnk->min_star = new_chunk(); + if (!cnk->min_star) /* out of memory :-( */ + goto done; + cnk->min_star->type = CNK_INT; + if (pflag) { + int num; + ch = *format++; + if (!isdigit((unsigned char)ch)) { + /* parameters must be all positioned or none */ + goto done; + } + for (num = 0; isdigit((unsigned char)ch); ch = *format++) { + num = 10 * num + char_to_int(ch); + } + cnk->min_star->num = num; + if (ch != '$') /* what ?? */ + goto done; + } else { + cnk->min_star->num = ++pnum; + } + max_pos = add_cnk_list_entry(&clist, max_pos, cnk->min_star); + if (max_pos == 0) /* out of memory :-( */ + goto done; + ch = *format++; + state = DP_S_DOT; + } else { + if (pfirst) pfirst = 0; + state = DP_S_DOT; + } + break; + case DP_S_DOT: + if (ch == '.') { + state = DP_S_MAX; + ch = *format++; + } else { + state = DP_S_MOD; + } + break; + case DP_S_MAX: + if (isdigit((unsigned char)ch)) { + if (cnk->max < 0) + cnk->max = 0; + cnk->max = 10 * cnk->max + char_to_int (ch); + ch = *format++; + } else if (ch == '$') { + if (!pfirst && !pflag) { + /* parameters must be all positioned or none */ + goto done; + } + if (cnk->max <= 0) /* what ?? */ + goto done; + cnk->num = cnk->max; + cnk->max = -1; + ch = *format++; + } else if (ch == '*') { + cnk->max_star = new_chunk(); + if (!cnk->max_star) /* out of memory :-( */ + goto done; + cnk->max_star->type = CNK_INT; + if (pflag) { + int num; + ch = *format++; + if (!isdigit((unsigned char)ch)) { + /* parameters must be all positioned or none */ + goto done; + } + for (num = 0; isdigit((unsigned char)ch); ch = *format++) { + num = 10 * num + char_to_int(ch); + } + cnk->max_star->num = num; + if (ch != '$') /* what ?? */ + goto done; + } else { + cnk->max_star->num = ++pnum; + } + max_pos = add_cnk_list_entry(&clist, max_pos, cnk->max_star); + if (max_pos == 0) /* out of memory :-( */ + goto done; + + ch = *format++; + state = DP_S_MOD; + } else { + state = DP_S_MOD; + } + break; + case DP_S_MOD: + switch (ch) { + case 'h': + cnk->cflags = DP_C_SHORT; + ch = *format++; + if (ch == 'h') { + cnk->cflags = DP_C_CHAR; + ch = *format++; + } + break; + case 'l': + cnk->cflags = DP_C_LONG; + ch = *format++; + if (ch == 'l') { /* It's a long long */ + cnk->cflags = DP_C_LLONG; + ch = *format++; + } + break; + case 'j': + cnk->cflags = DP_C_LLONG; + ch = *format++; + break; + case 'L': + cnk->cflags = DP_C_LDOUBLE; + ch = *format++; + break; + case 'z': + cnk->cflags = DP_C_SIZET; + ch = *format++; + break; + default: + break; + } + state = DP_S_CONV; + break; + case DP_S_CONV: + if (cnk->num == 0) cnk->num = ++pnum; + max_pos = add_cnk_list_entry(&clist, max_pos, cnk); + if (max_pos == 0) /* out of memory :-( */ + goto done; + + switch (ch) { + case 'd': + case 'i': + cnk->type = CNK_INT; + break; + case 'o': + cnk->type = CNK_OCTAL; + cnk->flags |= DP_F_UNSIGNED; + break; + case 'u': + cnk->type = CNK_UINT; + cnk->flags |= DP_F_UNSIGNED; + break; + case 'X': + cnk->flags |= DP_F_UP; + case 'x': + cnk->type = CNK_HEX; + cnk->flags |= DP_F_UNSIGNED; + break; + case 'A': + /* hex float not supported yet */ + case 'E': + case 'G': + case 'F': + cnk->flags |= DP_F_UP; + case 'a': + /* hex float not supported yet */ + case 'e': + case 'f': + case 'g': + cnk->type = CNK_FLOAT; + break; + case 'c': + cnk->type = CNK_CHAR; + break; + case 's': + cnk->type = CNK_STRING; + break; + case 'p': + cnk->type = CNK_PTR; + cnk->flags |= DP_F_UNSIGNED; + break; + case 'n': + cnk->type = CNK_NUM; + break; + case '%': + cnk->type = CNK_PRCNT; + break; + default: + /* Unknown, bail out*/ + goto done; + } + ch = *format++; + state = DP_S_DEFAULT; + break; + case DP_S_DONE: + break; + default: + /* hmm? */ + break; /* some picky compilers need this */ + } + } + + /* retrieve the format arguments */ + for (pnum = 0; pnum < max_pos; pnum++) { + int i; + + if (clist[pnum].num == 0) { + /* ignoring a parameter should not be permitted + * all parameters must be matched at least once + * BUT seem some system ignore this rule ... + * at least my glibc based system does --SSS + */ +#ifdef DEBUG_SNPRINTF + printf("parameter at position %d not used\n", pnum+1); +#endif + /* eat the parameter */ + va_arg (args, int); + continue; + } + for (i = 1; i < clist[pnum].num; i++) { + if (clist[pnum].chunks[0]->type != clist[pnum].chunks[i]->type) { + /* nooo noo no! + * all the references to a parameter + * must be of the same type + */ + goto done; + } + } + cnk = clist[pnum].chunks[0]; + switch (cnk->type) { + case CNK_INT: + if (cnk->cflags == DP_C_SHORT) + cnk->value = va_arg (args, int); + else if (cnk->cflags == DP_C_LONG) + cnk->value = va_arg (args, long int); + else if (cnk->cflags == DP_C_LLONG) + cnk->value = va_arg (args, LLONG); + else if (cnk->cflags == DP_C_SIZET) + cnk->value = va_arg (args, ssize_t); + else + cnk->value = va_arg (args, int); + + for (i = 1; i < clist[pnum].num; i++) { + clist[pnum].chunks[i]->value = cnk->value; + } + break; + + case CNK_OCTAL: + case CNK_UINT: + case CNK_HEX: + if (cnk->cflags == DP_C_SHORT) + cnk->value = va_arg (args, unsigned int); + else if (cnk->cflags == DP_C_LONG) + cnk->value = (unsigned long int)va_arg (args, unsigned long int); + else if (cnk->cflags == DP_C_LLONG) + cnk->value = (LLONG)va_arg (args, unsigned LLONG); + else if (cnk->cflags == DP_C_SIZET) + cnk->value = (size_t)va_arg (args, size_t); + else + cnk->value = (unsigned int)va_arg (args, unsigned int); + + for (i = 1; i < clist[pnum].num; i++) { + clist[pnum].chunks[i]->value = cnk->value; + } + break; + + case CNK_FLOAT: + if (cnk->cflags == DP_C_LDOUBLE) + cnk->fvalue = va_arg (args, LDOUBLE); + else + cnk->fvalue = va_arg (args, double); + + for (i = 1; i < clist[pnum].num; i++) { + clist[pnum].chunks[i]->fvalue = cnk->fvalue; + } + break; + + case CNK_CHAR: + cnk->value = va_arg (args, int); + + for (i = 1; i < clist[pnum].num; i++) { + clist[pnum].chunks[i]->value = cnk->value; + } + break; + + case CNK_STRING: + cnk->strvalue = va_arg (args, char *); + if (!cnk->strvalue) cnk->strvalue = "(NULL)"; + + for (i = 1; i < clist[pnum].num; i++) { + clist[pnum].chunks[i]->strvalue = cnk->strvalue; + } + break; + + case CNK_PTR: + cnk->strvalue = va_arg (args, void *); + for (i = 1; i < clist[pnum].num; i++) { + clist[pnum].chunks[i]->strvalue = cnk->strvalue; + } + break; + + case CNK_NUM: + if (cnk->cflags == DP_C_CHAR) + cnk->pnum = va_arg (args, char *); + else if (cnk->cflags == DP_C_SHORT) + cnk->pnum = va_arg (args, short int *); + else if (cnk->cflags == DP_C_LONG) + cnk->pnum = va_arg (args, long int *); + else if (cnk->cflags == DP_C_LLONG) + cnk->pnum = va_arg (args, LLONG *); + else if (cnk->cflags == DP_C_SIZET) + cnk->pnum = va_arg (args, ssize_t *); + else + cnk->pnum = va_arg (args, int *); + + for (i = 1; i < clist[pnum].num; i++) { + clist[pnum].chunks[i]->pnum = cnk->pnum; + } + break; + + case CNK_PRCNT: + break; + + default: + /* what ?? */ + goto done; + } + } + /* print out the actual string from chunks */ + currlen = 0; + cnk = chunks; + while (cnk) { + int len, min, max; + + if (cnk->min_star) min = cnk->min_star->value; + else min = cnk->min; + if (cnk->max_star) max = cnk->max_star->value; + else max = cnk->max; + + switch (cnk->type) { + + case CNK_FMT_STR: + if (maxlen != 0 && maxlen > currlen) { + if (maxlen > (currlen + cnk->len)) len = cnk->len; + else len = maxlen - currlen; + + memcpy(&(buffer[currlen]), &(base[cnk->start]), len); + } + currlen += cnk->len; + + break; + + case CNK_INT: + case CNK_UINT: + fmtint (buffer, &currlen, maxlen, cnk->value, 10, min, max, cnk->flags); + break; + + case CNK_OCTAL: + fmtint (buffer, &currlen, maxlen, cnk->value, 8, min, max, cnk->flags); + break; + + case CNK_HEX: + fmtint (buffer, &currlen, maxlen, cnk->value, 16, min, max, cnk->flags); + break; + + case CNK_FLOAT: + fmtfp (buffer, &currlen, maxlen, cnk->fvalue, min, max, cnk->flags); + break; + + case CNK_CHAR: + dopr_outch (buffer, &currlen, maxlen, cnk->value); + break; + + case CNK_STRING: + if (max == -1) { + max = strlen(cnk->strvalue); + } + fmtstr (buffer, &currlen, maxlen, cnk->strvalue, cnk->flags, min, max); + break; + + case CNK_PTR: + fmtint (buffer, &currlen, maxlen, (long)(cnk->strvalue), 16, min, max, cnk->flags); + break; + + case CNK_NUM: + if (cnk->cflags == DP_C_CHAR) + *((char *)(cnk->pnum)) = (char)currlen; + else if (cnk->cflags == DP_C_SHORT) + *((short int *)(cnk->pnum)) = (short int)currlen; + else if (cnk->cflags == DP_C_LONG) + *((long int *)(cnk->pnum)) = (long int)currlen; + else if (cnk->cflags == DP_C_LLONG) + *((LLONG *)(cnk->pnum)) = (LLONG)currlen; + else if (cnk->cflags == DP_C_SIZET) + *((ssize_t *)(cnk->pnum)) = (ssize_t)currlen; + else + *((int *)(cnk->pnum)) = (int)currlen; + break; + + case CNK_PRCNT: + dopr_outch (buffer, &currlen, maxlen, '%'); + break; + + default: + /* what ?? */ + goto done; + } + cnk = cnk->next; + } + if (maxlen != 0) { + if (currlen < maxlen - 1) + buffer[currlen] = '\0'; + else if (maxlen > 0) + buffer[maxlen - 1] = '\0'; + } + ret = currlen; + +done: + va_end(args); + + while (chunks) { + cnk = chunks->next; + free(chunks); + chunks = cnk; + } + if (clist) { + for (pnum = 0; pnum < max_pos; pnum++) { + if (clist[pnum].chunks) free(clist[pnum].chunks); + } + free(clist); + } + return ret; +} + +static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, + char *value, int flags, int min, int max) +{ + int padlen, strln; /* amount to pad */ + int cnt = 0; + +#ifdef DEBUG_SNPRINTF + printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value); +#endif + if (value == 0) { + value = ""; + } + + for (strln = 0; strln < max && value[strln]; ++strln); /* strlen */ + padlen = min - strln; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justify */ + + while (padlen > 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + --padlen; + } + while (*value && (cnt < max)) { + dopr_outch (buffer, currlen, maxlen, *value++); + ++cnt; + } + while (padlen < 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + ++padlen; + } +} + +/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ + +static void fmtint(char *buffer, size_t *currlen, size_t maxlen, + LLONG value, int base, int min, int max, int flags) +{ + int signvalue = 0; + unsigned LLONG uvalue; + char convert[22+1]; /* 64-bit value in octal: 22 digits + \0 */ + int place = 0; + int spadlen = 0; /* amount to space pad */ + int zpadlen = 0; /* amount to zero pad */ + int caps = 0; + + if (max < 0) + max = 0; + + uvalue = value; + + if(!(flags & DP_F_UNSIGNED)) { + if( value < 0 ) { + signvalue = '-'; + uvalue = -value; + } else { + if (flags & DP_F_PLUS) /* Do a sign (+/i) */ + signvalue = '+'; + else if (flags & DP_F_SPACE) + signvalue = ' '; + } + } + + if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ + + do { + convert[place++] = + (caps? "0123456789ABCDEF":"0123456789abcdef") + [uvalue % (unsigned)base ]; + uvalue = (uvalue / (unsigned)base ); + } while(uvalue && (place < sizeof(convert))); + if (place == sizeof(convert)) place--; + convert[place] = 0; + + zpadlen = max - place; + spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); + if (zpadlen < 0) zpadlen = 0; + if (spadlen < 0) spadlen = 0; + if (flags & DP_F_ZERO) { + zpadlen = MAX(zpadlen, spadlen); + spadlen = 0; + } + if (flags & DP_F_MINUS) + spadlen = -spadlen; /* Left Justifty */ + +#ifdef DEBUG_SNPRINTF + printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", + zpadlen, spadlen, min, max, place); +#endif + + /* Spaces */ + while (spadlen > 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + --spadlen; + } + + /* Sign */ + if (signvalue) + dopr_outch (buffer, currlen, maxlen, signvalue); + + /* Zeros */ + if (zpadlen > 0) { + while (zpadlen > 0) { + dopr_outch (buffer, currlen, maxlen, '0'); + --zpadlen; + } + } + + /* Digits */ + while (place > 0) + dopr_outch (buffer, currlen, maxlen, convert[--place]); + + /* Left Justified spaces */ + while (spadlen < 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + ++spadlen; + } +} + +static LDOUBLE abs_val(LDOUBLE value) +{ + LDOUBLE result = value; + + if (value < 0) + result = -value; + + return result; +} + +static LDOUBLE POW10(int exp) +{ + LDOUBLE result = 1; + + while (exp) { + result *= 10; + exp--; + } + + return result; +} + +static LLONG ROUND(LDOUBLE value) +{ + LLONG intpart; + + intpart = (LLONG)value; + value = value - intpart; + if (value >= 0.5) intpart++; + + return intpart; +} + +/* a replacement for modf that doesn't need the math library. Should + be portable, but slow */ +static double my_modf(double x0, double *iptr) +{ + int i; + LLONG l=0; + double x = x0; + double f = 1.0; + + for (i=0;i<100;i++) { + l = (long)x; + if (l <= (x+1) && l >= (x-1)) break; + x *= 0.1; + f *= 10.0; + } + + if (i == 100) { + /* yikes! the number is beyond what we can handle. What do we do? */ + (*iptr) = 0; + return 0; + } + + if (i != 0) { + double i2; + double ret; + + ret = my_modf(x0-l*f, &i2); + (*iptr) = l*f + i2; + return ret; + } + + (*iptr) = l; + return x - (*iptr); +} + + +static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, + LDOUBLE fvalue, int min, int max, int flags) +{ + int signvalue = 0; + double ufvalue; + char iconvert[311]; + char fconvert[311]; + int iplace = 0; + int fplace = 0; + int padlen = 0; /* amount to pad */ + int zpadlen = 0; + int caps = 0; + int idx; + double intpart; + double fracpart; + double temp; + + /* + * AIX manpage says the default is 0, but Solaris says the default + * is 6, and sprintf on AIX defaults to 6 + */ + if (max < 0) + max = 6; + + ufvalue = abs_val (fvalue); + + if (fvalue < 0) { + signvalue = '-'; + } else { + if (flags & DP_F_PLUS) { /* Do a sign (+/i) */ + signvalue = '+'; + } else { + if (flags & DP_F_SPACE) + signvalue = ' '; + } + } + +#if 0 + if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ +#endif + +#if 0 + if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */ +#endif + + /* + * Sorry, we only support 9 digits past the decimal because of our + * conversion method + */ + if (max > 9) + max = 9; + + /* We "cheat" by converting the fractional part to integer by + * multiplying by a factor of 10 + */ + + temp = ufvalue; + my_modf(temp, &intpart); + + fracpart = ROUND((POW10(max)) * (ufvalue - intpart)); + + if (fracpart >= POW10(max)) { + intpart++; + fracpart -= POW10(max); + } + + + /* Convert integer part */ + do { + temp = intpart*0.1; + my_modf(temp, &intpart); + idx = (int) ((temp -intpart +0.05)* 10.0); + /* idx = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */ + /* printf ("%llf, %f, %x\n", temp, intpart, idx); */ + iconvert[iplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[idx]; + } while (intpart && (iplace < 311)); + if (iplace == 311) iplace--; + iconvert[iplace] = 0; + + /* Convert fractional part */ + if (fracpart) + { + do { + temp = fracpart*0.1; + my_modf(temp, &fracpart); + idx = (int) ((temp -fracpart +0.05)* 10.0); + /* idx = (int) ((((temp/10) -fracpart) +0.05) *10); */ + /* printf ("%lf, %lf, %ld\n", temp, fracpart, idx ); */ + fconvert[fplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[idx]; + } while(fracpart && (fplace < 311)); + if (fplace == 311) fplace--; + } + fconvert[fplace] = 0; + + /* -1 for decimal point, another -1 if we are printing a sign */ + padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); + zpadlen = max - fplace; + if (zpadlen < 0) zpadlen = 0; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justifty */ + + if ((flags & DP_F_ZERO) && (padlen > 0)) { + if (signvalue) { + dopr_outch (buffer, currlen, maxlen, signvalue); + --padlen; + signvalue = 0; + } + while (padlen > 0) { + dopr_outch (buffer, currlen, maxlen, '0'); + --padlen; + } + } + while (padlen > 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + --padlen; + } + if (signvalue) + dopr_outch (buffer, currlen, maxlen, signvalue); + + while (iplace > 0) + dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); + +#ifdef DEBUG_SNPRINTF + printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); +#endif + + /* + * Decimal point. This should probably use locale to find the correct + * char to print out. + */ + if (max > 0) { + dopr_outch (buffer, currlen, maxlen, '.'); + + while (zpadlen > 0) { + dopr_outch (buffer, currlen, maxlen, '0'); + --zpadlen; + } + + while (fplace > 0) + dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); + } + + while (padlen < 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + ++padlen; + } +} + +static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) +{ + if (*currlen < maxlen) { + buffer[(*currlen)] = c; + } + (*currlen)++; +} + +static struct pr_chunk *new_chunk(void) { + struct pr_chunk *new_c = (struct pr_chunk *)malloc(sizeof(struct pr_chunk)); + + if (!new_c) + return NULL; + + new_c->type = 0; + new_c->num = 0; + new_c->min = 0; + new_c->min_star = NULL; + new_c->max = -1; + new_c->max_star = NULL; + new_c->flags = 0; + new_c->cflags = 0; + new_c->start = 0; + new_c->len = 0; + new_c->value = 0; + new_c->fvalue = 0; + new_c->strvalue = NULL; + new_c->pnum = NULL; + new_c->next = NULL; + + return new_c; +} + +static int add_cnk_list_entry(struct pr_chunk_x **list, + int max_num, struct pr_chunk *chunk) { + struct pr_chunk_x *l; + struct pr_chunk **c; + int max; + int cnum; + int i, pos; + + if (chunk->num > max_num) { + max = chunk->num; + + if (*list == NULL) { + l = (struct pr_chunk_x *)malloc(sizeof(struct pr_chunk_x) * max); + pos = 0; + } else { + l = (struct pr_chunk_x *)realloc(*list, sizeof(struct pr_chunk_x) * max); + pos = max_num; + } + if (l == NULL) { + for (i = 0; i < max; i++) { + if ((*list)[i].chunks) free((*list)[i].chunks); + } + return 0; + } + for (i = pos; i < max; i++) { + l[i].chunks = NULL; + l[i].num = 0; + } + } else { + l = *list; + max = max_num; + } + + i = chunk->num - 1; + cnum = l[i].num + 1; + if (l[i].chunks == NULL) { + c = (struct pr_chunk **)malloc(sizeof(struct pr_chunk *) * cnum); + } else { + c = (struct pr_chunk **)realloc(l[i].chunks, sizeof(struct pr_chunk *) * cnum); + } + if (c == NULL) { + for (i = 0; i < max; i++) { + if (l[i].chunks) free(l[i].chunks); + } + return 0; + } + c[l[i].num] = chunk; + l[i].chunks = c; + l[i].num = cnum; + + *list = l; + return max; +} + + int rep_vsnprintf (char *str, size_t count, const char *fmt, va_list args) +{ + return dopr(str, count, fmt, args); +} +#endif + +/* yes this really must be a ||. Don't muck with this (tridge) + * + * The logic for these two is that we need our own definition if the + * OS *either* has no definition of *sprintf, or if it does have one + * that doesn't work properly according to the autoconf test. + */ +#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF) + int rep_snprintf(char *str,size_t count,const char *fmt,...) +{ + size_t ret; + va_list ap; + + va_start(ap, fmt); + ret = vsnprintf(str, count, fmt, ap); + va_end(ap); + return ret; +} +#endif + +#ifndef HAVE_C99_VSNPRINTF + int rep_printf(const char *fmt, ...) +{ + va_list ap; + int ret; + char *s; + + s = NULL; + va_start(ap, fmt); + ret = vasprintf(&s, fmt, ap); + va_end(ap); + + if (s) { + fwrite(s, 1, strlen(s), stdout); + } + free(s); + + return ret; +} +#endif + +#ifndef HAVE_C99_VSNPRINTF + int rep_fprintf(FILE *stream, const char *fmt, ...) +{ + va_list ap; + int ret; + char *s; + + s = NULL; + va_start(ap, fmt); + ret = vasprintf(&s, fmt, ap); + va_end(ap); + + if (s) { + fwrite(s, 1, strlen(s), stream); + } + free(s); + + return ret; +} +#endif + +#endif + +#if !defined(HAVE_VASPRINTF) || !defined(HAVE_C99_VSNPRINTF) + int rep_vasprintf(char **ptr, const char *format, va_list ap) +{ + int ret; + va_list ap2; + + VA_COPY(ap2, ap); + ret = vsnprintf(NULL, 0, format, ap2); + va_end(ap2); + if (ret < 0) return ret; + + (*ptr) = (char *)malloc(ret+1); + if (!*ptr) return -1; + + VA_COPY(ap2, ap); + ret = vsnprintf(*ptr, ret+1, format, ap2); + va_end(ap2); + + return ret; +} +#endif + +#if !defined(HAVE_ASPRINTF) || !defined(HAVE_C99_VSNPRINTF) + int rep_asprintf(char **ptr, const char *format, ...) +{ + va_list ap; + int ret; + + *ptr = NULL; + va_start(ap, format); + ret = vasprintf(ptr, format, ap); + va_end(ap); + + return ret; +} +#endif + +#ifdef TEST_SNPRINTF + + int sprintf(char *str,const char *fmt,...); + int printf(const char *fmt,...); + + int main (void) +{ + char buf1[1024]; + char buf2[1024]; + char *buf3; + char *fp_fmt[] = { + "%1.1f", + "%-1.5f", + "%1.5f", + "%123.9f", + "%10.5f", + "% 10.5f", + "%+22.9f", + "%+4.9f", + "%01.3f", + "%4f", + "%3.1f", + "%3.2f", + "%.0f", + "%f", + "%-8.8f", + "%-9.9f", + NULL + }; + double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 203.9, 0.96, 0.996, + 0.9996, 1.996, 4.136, 5.030201, 0.00205, + /* END LIST */ 0}; + char *int_fmt[] = { + "%-1.5d", + "%1.5d", + "%123.9d", + "%5.5d", + "%10.5d", + "% 10.5d", + "%+22.33d", + "%01.3d", + "%4d", + "%d", + NULL + }; + long int_nums[] = { -1, 134, 91340, 341, 0203, 1234567890, 0}; + char *str_fmt[] = { + "%10.5s", + "%-10.5s", + "%5.10s", + "%-5.10s", + "%10.1s", + "%0.10s", + "%10.0s", + "%1.10s", + "%s", + "%.1s", + "%.10s", + "%10s", + NULL + }; + char *str_vals[] = {"hello", "a", "", "a longer string", NULL}; +#ifdef HAVE_LONG_LONG + char *ll_fmt[] = { + "%llu", + NULL + }; + LLONG ll_nums[] = { 134, 91340, 341, 0203, 1234567890, 128006186140000000LL, 0}; +#endif + int x, y; + int fail = 0; + int num = 0; + int l1, l2; + char *ss_fmt[] = { + "%zd", + "%zu", + NULL + }; + size_t ss_nums[] = {134, 91340, 123456789, 0203, 1234567890, 0}; + + printf ("Testing snprintf format codes against system sprintf...\n"); + + for (x = 0; fp_fmt[x] ; x++) { + for (y = 0; fp_nums[y] != 0 ; y++) { + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]); + l2 = sprintf (buf2, fp_fmt[x], fp_nums[y]); + buf1[1023] = buf2[1023] = '\0'; + if (strcmp (buf1, buf2) || (l1 != l2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + fp_fmt[x], l1, buf1, l2, buf2); + fail++; + } + num++; + } + } + + for (x = 0; int_fmt[x] ; x++) { + for (y = 0; int_nums[y] != 0 ; y++) { + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), int_fmt[x], int_nums[y]); + l2 = sprintf (buf2, int_fmt[x], int_nums[y]); + buf1[1023] = buf2[1023] = '\0'; + if (strcmp (buf1, buf2) || (l1 != l2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + int_fmt[x], l1, buf1, l2, buf2); + fail++; + } + num++; + } + } + + for (x = 0; str_fmt[x] ; x++) { + for (y = 0; str_vals[y] != 0 ; y++) { + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), str_fmt[x], str_vals[y]); + l2 = sprintf (buf2, str_fmt[x], str_vals[y]); + buf1[1023] = buf2[1023] = '\0'; + if (strcmp (buf1, buf2) || (l1 != l2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + str_fmt[x], l1, buf1, l2, buf2); + fail++; + } + num++; + } + } + +#ifdef HAVE_LONG_LONG + for (x = 0; ll_fmt[x] ; x++) { + for (y = 0; ll_nums[y] != 0 ; y++) { + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), ll_fmt[x], ll_nums[y]); + l2 = sprintf (buf2, ll_fmt[x], ll_nums[y]); + buf1[1023] = buf2[1023] = '\0'; + if (strcmp (buf1, buf2) || (l1 != l2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + ll_fmt[x], l1, buf1, l2, buf2); + fail++; + } + num++; + } + } +#endif + +#define BUFSZ 2048 + + buf1[0] = buf2[0] = '\0'; + if ((buf3 = malloc(BUFSZ)) == NULL) { + fail++; + } else { + num++; + memset(buf3, 'a', BUFSZ); + snprintf(buf1, sizeof(buf1), "%.*s", 1, buf3); + buf1[1023] = '\0'; + if (strcmp(buf1, "a") != 0) { + printf("length limit buf1 '%s' expected 'a'\n", buf1); + fail++; + } + } + + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), "%4$*1$d %2$s %3$*1$.*1$f", 3, "pos test", 12.3456, 9); + l2 = sprintf(buf2, "%4$*1$d %2$s %3$*1$.*1$f", 3, "pos test", 12.3456, 9); + buf1[1023] = buf2[1023] = '\0'; + if (strcmp(buf1, buf2) || (l1 != l2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + "%4$*1$d %2$s %3$*1$.*1$f", l1, buf1, l2, buf2); + fail++; + } + + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), "%4$*4$d %2$s %3$*4$.*4$f", 3, "pos test", 12.3456, 9); + l2 = sprintf(buf2, "%4$*4$d %2$s %3$*4$.*4$f", 3, "pos test", 12.3456, 9); + buf1[1023] = buf2[1023] = '\0'; + if (strcmp(buf1, buf2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + "%4$*1$d %2$s %3$*1$.*1$f", l1, buf1, l2, buf2); + fail++; + } + + for (x = 0; ss_fmt[x] ; x++) { + for (y = 0; ss_nums[y] != 0 ; y++) { + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), ss_fmt[x], ss_nums[y]); + l2 = sprintf (buf2, ss_fmt[x], ss_nums[y]); + buf1[1023] = buf2[1023] = '\0'; + if (strcmp (buf1, buf2) || (l1 != l2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + ss_fmt[x], l1, buf1, l2, buf2); + fail++; + } + num++; + } + } +#if 0 + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), "%lld", (LLONG)1234567890); + l2 = sprintf(buf2, "%lld", (LLONG)1234567890); + buf1[1023] = buf2[1023] = '\0'; + if (strcmp(buf1, buf2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + "%lld", l1, buf1, l2, buf2); + fail++; + } + + buf1[0] = buf2[0] = '\0'; + l1 = snprintf(buf1, sizeof(buf1), "%Lf", (LDOUBLE)890.1234567890123); + l2 = sprintf(buf2, "%Lf", (LDOUBLE)890.1234567890123); + buf1[1023] = buf2[1023] = '\0'; + if (strcmp(buf1, buf2)) { + printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", + "%Lf", l1, buf1, l2, buf2); + fail++; + } +#endif + printf ("%d tests failed out of %d.\n", fail, num); + + printf("seeing how many digits we support\n"); + { + double v0 = 0.12345678901234567890123456789012345678901; + for (x=0; x<100; x++) { + double p = pow(10, x); + double r = v0*p; + snprintf(buf1, sizeof(buf1), "%1.1f", r); + sprintf(buf2, "%1.1f", r); + if (strcmp(buf1, buf2)) { + printf("we seem to support %d digits\n", x-1); + break; + } + } + } + + return 0; +} +#endif /* TEST_SNPRINTF */ diff --git a/ldb-2.0.8/lib/replace/socket.c b/ldb-2.0.8/lib/replace/socket.c new file mode 100644 index 0000000..4cd9d2e --- /dev/null +++ b/ldb-2.0.8/lib/replace/socket.c @@ -0,0 +1,39 @@ +/* + * Unix SMB/CIFS implementation. + * + * Dummy replacements for socket functions. + * + * Copyright (C) Michael Adam 2008 + * + * ** NOTE! The following LGPL license applies to the replace + * ** library. This does NOT imply that all of Samba is released + * ** under the LGPL + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "replace.h" +#include "system/network.h" + +int rep_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen) +{ + errno = ENOSYS; + return -1; +} + +struct hostent *rep_gethostbyname(const char *name) +{ + errno = ENOSYS; + return NULL; +} diff --git a/ldb-2.0.8/lib/replace/socketpair.c b/ldb-2.0.8/lib/replace/socketpair.c new file mode 100644 index 0000000..c775730 --- /dev/null +++ b/ldb-2.0.8/lib/replace/socketpair.c @@ -0,0 +1,46 @@ +/* + * Unix SMB/CIFS implementation. + * replacement routines for broken systems + * Copyright (C) Jelmer Vernooij 2006 + * Copyright (C) Michael Adam 2008 + * + * ** NOTE! The following LGPL license applies to the replace + * ** library. This does NOT imply that all of Samba is released + * ** under the LGPL + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "replace.h" +#include "system/network.h" + +int rep_socketpair(int d, int type, int protocol, int sv[2]) +{ + if (d != AF_UNIX) { + errno = EAFNOSUPPORT; + return -1; + } + + if (protocol != 0) { + errno = EPROTONOSUPPORT; + return -1; + } + + if (type != SOCK_STREAM) { + errno = EOPNOTSUPP; + return -1; + } + + return pipe(sv); +} diff --git a/ldb-2.0.8/lib/replace/strptime.c b/ldb-2.0.8/lib/replace/strptime.c new file mode 100644 index 0000000..bbc7422 --- /dev/null +++ b/ldb-2.0.8/lib/replace/strptime.c @@ -0,0 +1,995 @@ +/* Convert a string representation of time to a time value. + Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1996. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 3 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + see . */ + +/* XXX This version of the implementation is not really complete. + Some of the fields cannot add information alone. But if seeing + some of them in the same format (such as year, week and weekday) + this is enough information for determining the date. */ + +#include "replace.h" +#include "system/locale.h" +#include "system/time.h" + +#ifndef __P +# if defined (__GNUC__) || (defined (__STDC__) && __STDC__) +# define __P(args) args +# else +# define __P(args) () +# endif /* GCC. */ +#endif /* Not __P. */ + +#if ! HAVE_LOCALTIME_R && ! defined localtime_r +# ifdef _LIBC +# define localtime_r __localtime_r +# else +/* Approximate localtime_r as best we can in its absence. */ +# define localtime_r my_localtime_r +static struct tm *localtime_r __P ((const time_t *, struct tm *)); +static struct tm * +localtime_r (t, tp) + const time_t *t; + struct tm *tp; +{ + struct tm *l = localtime (t); + if (! l) + return 0; + *tp = *l; + return tp; +} +# endif /* ! _LIBC */ +#endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */ + + +#define match_char(ch1, ch2) if (ch1 != ch2) return NULL +#if defined __GNUC__ && __GNUC__ >= 2 +# define match_string(cs1, s2) \ + ({ size_t len = strlen (cs1); \ + int result = strncasecmp ((cs1), (s2), len) == 0; \ + if (result) (s2) += len; \ + result; }) +#else +/* Oh come on. Get a reasonable compiler. */ +# define match_string(cs1, s2) \ + (strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1)) +#endif +/* We intentionally do not use isdigit() for testing because this will + lead to problems with the wide character version. */ +#define get_number(from, to, n) \ + do { \ + int __n = n; \ + val = 0; \ + while (*rp == ' ') \ + ++rp; \ + if (*rp < '0' || *rp > '9') \ + return NULL; \ + do { \ + val *= 10; \ + val += *rp++ - '0'; \ + } while (--__n > 0 && val * 10 <= to && *rp >= '0' && *rp <= '9'); \ + if (val < from || val > to) \ + return NULL; \ + } while (0) +#ifdef _NL_CURRENT +# define get_alt_number(from, to, n) \ + ({ \ + __label__ do_normal; \ + if (*decided != raw) \ + { \ + const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \ + int __n = n; \ + int any = 0; \ + while (*rp == ' ') \ + ++rp; \ + val = 0; \ + do { \ + val *= 10; \ + while (*alts != '\0') \ + { \ + size_t len = strlen (alts); \ + if (strncasecmp (alts, rp, len) == 0) \ + break; \ + alts += len + 1; \ + ++val; \ + } \ + if (*alts == '\0') \ + { \ + if (*decided == not && ! any) \ + goto do_normal; \ + /* If we haven't read anything it's an error. */ \ + if (! any) \ + return NULL; \ + /* Correct the premature multiplication. */ \ + val /= 10; \ + break; \ + } \ + else \ + *decided = loc; \ + } while (--__n > 0 && val * 10 <= to); \ + if (val < from || val > to) \ + return NULL; \ + } \ + else \ + { \ + do_normal: \ + get_number (from, to, n); \ + } \ + 0; \ + }) +#else +# define get_alt_number(from, to, n) \ + /* We don't have the alternate representation. */ \ + get_number(from, to, n) +#endif +#define recursive(new_fmt) \ + (*(new_fmt) != '\0' \ + && (rp = strptime_internal (rp, (new_fmt), tm, decided, era_cnt)) != NULL) + + +#ifdef _LIBC +/* This is defined in locale/C-time.c in the GNU libc. */ +extern const struct locale_data _nl_C_LC_TIME; +extern const unsigned short int __mon_yday[2][13]; + +# define weekday_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (DAY_1)].string) +# define ab_weekday_name \ + (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string) +# define month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string) +# define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string) +# define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string) +# define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_FMT)].string) +# define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string) +# define HERE_PM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (PM_STR)].string) +# define HERE_T_FMT_AMPM \ + (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT_AMPM)].string) +# define HERE_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT)].string) + +# define strncasecmp(s1, s2, n) __strncasecmp (s1, s2, n) +#else +static char const weekday_name[][10] = + { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" + }; +static char const ab_weekday_name[][4] = + { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; +static char const month_name[][10] = + { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" + }; +static char const ab_month_name[][4] = + { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; +# define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y" +# define HERE_D_FMT "%m/%d/%y" +# define HERE_AM_STR "AM" +# define HERE_PM_STR "PM" +# define HERE_T_FMT_AMPM "%I:%M:%S %p" +# define HERE_T_FMT "%H:%M:%S" + +static const unsigned short int __mon_yday[2][13] = + { + /* Normal years. */ + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + /* Leap years. */ + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } + }; +#endif + +/* Status of lookup: do we use the locale data or the raw data? */ +enum locale_status { not, loc, raw }; + + +#ifndef __isleap +/* Nonzero if YEAR is a leap year (every 4 years, + except every 100th isn't, and every 400th is). */ +# define __isleap(year) \ + ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) +#endif + +/* Compute the day of the week. */ +static void +day_of_the_week (struct tm *tm) +{ + /* We know that January 1st 1970 was a Thursday (= 4). Compute the + the difference between this data in the one on TM and so determine + the weekday. */ + int corr_year = 1900 + tm->tm_year - (tm->tm_mon < 2); + int wday = (-473 + + (365 * (tm->tm_year - 70)) + + (corr_year / 4) + - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0) + + (((corr_year / 4) / 25) / 4) + + __mon_yday[0][tm->tm_mon] + + tm->tm_mday - 1); + tm->tm_wday = ((wday % 7) + 7) % 7; +} + +/* Compute the day of the year. */ +static void +day_of_the_year (struct tm *tm) +{ + tm->tm_yday = (__mon_yday[__isleap (1900 + tm->tm_year)][tm->tm_mon] + + (tm->tm_mday - 1)); +} + +static char * +#ifdef _LIBC +internal_function +#endif +strptime_internal __P ((const char *rp, const char *fmt, struct tm *tm, + enum locale_status *decided, int era_cnt)); + +static char * +#ifdef _LIBC +internal_function +#endif +strptime_internal (rp, fmt, tm, decided, era_cnt) + const char *rp; + const char *fmt; + struct tm *tm; + enum locale_status *decided; + int era_cnt; +{ + int cnt; + size_t val; + int have_I, is_pm; + int century, want_century; + int want_era; + int have_wday, want_xday; + int have_yday; + int have_mon, have_mday; +#ifdef _NL_CURRENT + const char *rp_backup; + size_t num_eras; + struct era_entry *era; + + era = NULL; +#endif + + have_I = is_pm = 0; + century = -1; + want_century = 0; + want_era = 0; + + have_wday = want_xday = have_yday = have_mon = have_mday = 0; + + while (*fmt != '\0') + { + /* A white space in the format string matches 0 more or white + space in the input string. */ + if (isspace (*fmt)) + { + while (isspace (*rp)) + ++rp; + ++fmt; + continue; + } + + /* Any character but `%' must be matched by the same character + in the iput string. */ + if (*fmt != '%') + { + match_char (*fmt++, *rp++); + continue; + } + + ++fmt; +#ifndef _NL_CURRENT + /* We need this for handling the `E' modifier. */ + start_over: +#endif + +#ifdef _NL_CURRENT + /* Make back up of current processing pointer. */ + rp_backup = rp; +#endif + + switch (*fmt++) + { + case '%': + /* Match the `%' character itself. */ + match_char ('%', *rp++); + break; + case 'a': + case 'A': + /* Match day of week. */ + for (cnt = 0; cnt < 7; ++cnt) + { +#ifdef _NL_CURRENT + if (*decided !=raw) + { + if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp)) + { + if (*decided == not + && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt), + weekday_name[cnt])) + *decided = loc; + break; + } + if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp)) + { + if (*decided == not + && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), + ab_weekday_name[cnt])) + *decided = loc; + break; + } + } +#endif + if (*decided != loc + && (match_string (weekday_name[cnt], rp) + || match_string (ab_weekday_name[cnt], rp))) + { + *decided = raw; + break; + } + } + if (cnt == 7) + /* Does not match a weekday name. */ + return NULL; + tm->tm_wday = cnt; + have_wday = 1; + break; + case 'b': + case 'B': + case 'h': + /* Match month name. */ + for (cnt = 0; cnt < 12; ++cnt) + { +#ifdef _NL_CURRENT + if (*decided !=raw) + { + if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp)) + { + if (*decided == not + && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt), + month_name[cnt])) + *decided = loc; + break; + } + if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp)) + { + if (*decided == not + && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), + ab_month_name[cnt])) + *decided = loc; + break; + } + } +#endif + if (match_string (month_name[cnt], rp) + || match_string (ab_month_name[cnt], rp)) + { + *decided = raw; + break; + } + } + if (cnt == 12) + /* Does not match a month name. */ + return NULL; + tm->tm_mon = cnt; + want_xday = 1; + break; + case 'c': + /* Match locale's date and time format. */ +#ifdef _NL_CURRENT + if (*decided != raw) + { + if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT))) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (*decided == not && + strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT)) + *decided = loc; + want_xday = 1; + break; + } + *decided = raw; + } +#endif + if (!recursive (HERE_D_T_FMT)) + return NULL; + want_xday = 1; + break; + case 'C': + /* Match century number. */ +#ifdef _NL_CURRENT + match_century: +#endif + get_number (0, 99, 2); + century = val; + want_xday = 1; + break; + case 'd': + case 'e': + /* Match day of month. */ + get_number (1, 31, 2); + tm->tm_mday = val; + have_mday = 1; + want_xday = 1; + break; + case 'F': + if (!recursive ("%Y-%m-%d")) + return NULL; + want_xday = 1; + break; + case 'x': +#ifdef _NL_CURRENT + if (*decided != raw) + { + if (!recursive (_NL_CURRENT (LC_TIME, D_FMT))) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (*decided == not + && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT)) + *decided = loc; + want_xday = 1; + break; + } + *decided = raw; + } +#endif + + FALL_THROUGH; + case 'D': + /* Match standard day format. */ + if (!recursive (HERE_D_FMT)) + return NULL; + want_xday = 1; + break; + case 'k': + case 'H': + /* Match hour in 24-hour clock. */ + get_number (0, 23, 2); + tm->tm_hour = val; + have_I = 0; + break; + case 'I': + /* Match hour in 12-hour clock. */ + get_number (1, 12, 2); + tm->tm_hour = val % 12; + have_I = 1; + break; + case 'j': + /* Match day number of year. */ + get_number (1, 366, 3); + tm->tm_yday = val - 1; + have_yday = 1; + break; + case 'm': + /* Match number of month. */ + get_number (1, 12, 2); + tm->tm_mon = val - 1; + have_mon = 1; + want_xday = 1; + break; + case 'M': + /* Match minute. */ + get_number (0, 59, 2); + tm->tm_min = val; + break; + case 'n': + case 't': + /* Match any white space. */ + while (isspace (*rp)) + ++rp; + break; + case 'p': + /* Match locale's equivalent of AM/PM. */ +#ifdef _NL_CURRENT + if (*decided != raw) + { + if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp)) + { + if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR)) + *decided = loc; + break; + } + if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp)) + { + if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR)) + *decided = loc; + is_pm = 1; + break; + } + *decided = raw; + } +#endif + if (!match_string (HERE_AM_STR, rp)) { + if (match_string (HERE_PM_STR, rp)) { + is_pm = 1; + } else { + return NULL; + } + } + break; + case 'r': +#ifdef _NL_CURRENT + if (*decided != raw) + { + if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM))) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (*decided == not && + strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM), + HERE_T_FMT_AMPM)) + *decided = loc; + break; + } + *decided = raw; + } +#endif + if (!recursive (HERE_T_FMT_AMPM)) + return NULL; + break; + case 'R': + if (!recursive ("%H:%M")) + return NULL; + break; + case 's': + { + /* The number of seconds may be very high so we cannot use + the `get_number' macro. Instead read the number + character for character and construct the result while + doing this. */ + time_t secs = 0; + if (*rp < '0' || *rp > '9') + /* We need at least one digit. */ + return NULL; + + do + { + secs *= 10; + secs += *rp++ - '0'; + } + while (*rp >= '0' && *rp <= '9'); + + if (localtime_r (&secs, tm) == NULL) + /* Error in function. */ + return NULL; + } + break; + case 'S': + get_number (0, 61, 2); + tm->tm_sec = val; + break; + case 'X': +#ifdef _NL_CURRENT + if (*decided != raw) + { + if (!recursive (_NL_CURRENT (LC_TIME, T_FMT))) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT)) + *decided = loc; + break; + } + *decided = raw; + } +#endif + + FALL_THROUGH; + case 'T': + if (!recursive (HERE_T_FMT)) + return NULL; + break; + case 'u': + get_number (1, 7, 1); + tm->tm_wday = val % 7; + have_wday = 1; + break; + case 'g': + get_number (0, 99, 2); + /* XXX This cannot determine any field in TM. */ + break; + case 'G': + if (*rp < '0' || *rp > '9') + return NULL; + /* XXX Ignore the number since we would need some more + information to compute a real date. */ + do + ++rp; + while (*rp >= '0' && *rp <= '9'); + break; + case 'U': + case 'V': + case 'W': + get_number (0, 53, 2); + /* XXX This cannot determine any field in TM without some + information. */ + break; + case 'w': + /* Match number of weekday. */ + get_number (0, 6, 1); + tm->tm_wday = val; + have_wday = 1; + break; + case 'y': +#ifdef _NL_CURRENT + match_year_in_century: +#endif + /* Match year within century. */ + get_number (0, 99, 2); + /* The "Year 2000: The Millennium Rollover" paper suggests that + values in the range 69-99 refer to the twentieth century. */ + tm->tm_year = val >= 69 ? val : val + 100; + /* Indicate that we want to use the century, if specified. */ + want_century = 1; + want_xday = 1; + break; + case 'Y': + /* Match year including century number. */ + get_number (0, 9999, 4); + tm->tm_year = val - 1900; + want_century = 0; + want_xday = 1; + break; + case 'Z': + /* XXX How to handle this? */ + break; + case 'E': +#ifdef _NL_CURRENT + switch (*fmt++) + { + case 'c': + /* Match locale's alternate date and time format. */ + if (*decided != raw) + { + const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT); + + if (*fmt == '\0') + fmt = _NL_CURRENT (LC_TIME, D_T_FMT); + + if (!recursive (fmt)) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (strcmp (fmt, HERE_D_T_FMT)) + *decided = loc; + want_xday = 1; + break; + } + *decided = raw; + } + /* The C locale has no era information, so use the + normal representation. */ + if (!recursive (HERE_D_T_FMT)) + return NULL; + want_xday = 1; + break; + case 'C': + if (*decided != raw) + { + if (era_cnt >= 0) + { + era = _nl_select_era_entry (era_cnt); + if (match_string (era->era_name, rp)) + { + *decided = loc; + break; + } + else + return NULL; + } + else + { + num_eras = _NL_CURRENT_WORD (LC_TIME, + _NL_TIME_ERA_NUM_ENTRIES); + for (era_cnt = 0; era_cnt < (int) num_eras; + ++era_cnt, rp = rp_backup) + { + era = _nl_select_era_entry (era_cnt); + if (match_string (era->era_name, rp)) + { + *decided = loc; + break; + } + } + if (era_cnt == (int) num_eras) + { + era_cnt = -1; + if (*decided == loc) + return NULL; + } + else + break; + } + + *decided = raw; + } + /* The C locale has no era information, so use the + normal representation. */ + goto match_century; + case 'y': + if (*decided == raw) + goto match_year_in_century; + + get_number(0, 9999, 4); + tm->tm_year = val; + want_era = 1; + want_xday = 1; + break; + case 'Y': + if (*decided != raw) + { + num_eras = _NL_CURRENT_WORD (LC_TIME, + _NL_TIME_ERA_NUM_ENTRIES); + for (era_cnt = 0; era_cnt < (int) num_eras; + ++era_cnt, rp = rp_backup) + { + era = _nl_select_era_entry (era_cnt); + if (recursive (era->era_format)) + break; + } + if (era_cnt == (int) num_eras) + { + era_cnt = -1; + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + *decided = loc; + era_cnt = -1; + break; + } + + *decided = raw; + } + get_number (0, 9999, 4); + tm->tm_year = val - 1900; + want_century = 0; + want_xday = 1; + break; + case 'x': + if (*decided != raw) + { + const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT); + + if (*fmt == '\0') + fmt = _NL_CURRENT (LC_TIME, D_FMT); + + if (!recursive (fmt)) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (strcmp (fmt, HERE_D_FMT)) + *decided = loc; + break; + } + *decided = raw; + } + if (!recursive (HERE_D_FMT)) + return NULL; + break; + case 'X': + if (*decided != raw) + { + const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT); + + if (*fmt == '\0') + fmt = _NL_CURRENT (LC_TIME, T_FMT); + + if (!recursive (fmt)) + { + if (*decided == loc) + return NULL; + else + rp = rp_backup; + } + else + { + if (strcmp (fmt, HERE_T_FMT)) + *decided = loc; + break; + } + *decided = raw; + } + if (!recursive (HERE_T_FMT)) + return NULL; + break; + default: + return NULL; + } + break; +#else + /* We have no information about the era format. Just use + the normal format. */ + if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y' + && *fmt != 'x' && *fmt != 'X') + /* This is an illegal format. */ + return NULL; + + goto start_over; +#endif + case 'O': + switch (*fmt++) + { + case 'd': + case 'e': + /* Match day of month using alternate numeric symbols. */ + get_alt_number (1, 31, 2); + tm->tm_mday = val; + have_mday = 1; + want_xday = 1; + break; + case 'H': + /* Match hour in 24-hour clock using alternate numeric + symbols. */ + get_alt_number (0, 23, 2); + tm->tm_hour = val; + have_I = 0; + break; + case 'I': + /* Match hour in 12-hour clock using alternate numeric + symbols. */ + get_alt_number (1, 12, 2); + tm->tm_hour = val - 1; + have_I = 1; + break; + case 'm': + /* Match month using alternate numeric symbols. */ + get_alt_number (1, 12, 2); + tm->tm_mon = val - 1; + have_mon = 1; + want_xday = 1; + break; + case 'M': + /* Match minutes using alternate numeric symbols. */ + get_alt_number (0, 59, 2); + tm->tm_min = val; + break; + case 'S': + /* Match seconds using alternate numeric symbols. */ + get_alt_number (0, 61, 2); + tm->tm_sec = val; + break; + case 'U': + case 'V': + case 'W': + get_alt_number (0, 53, 2); + /* XXX This cannot determine any field in TM without + further information. */ + break; + case 'w': + /* Match number of weekday using alternate numeric symbols. */ + get_alt_number (0, 6, 1); + tm->tm_wday = val; + have_wday = 1; + break; + case 'y': + /* Match year within century using alternate numeric symbols. */ + get_alt_number (0, 99, 2); + tm->tm_year = val >= 69 ? val : val + 100; + want_xday = 1; + break; + default: + return NULL; + } + break; + default: + return NULL; + } + } + + if (have_I && is_pm) + tm->tm_hour += 12; + + if (century != -1) + { + if (want_century) + tm->tm_year = tm->tm_year % 100 + (century - 19) * 100; + else + /* Only the century, but not the year. Strange, but so be it. */ + tm->tm_year = (century - 19) * 100; + } + +#ifdef _NL_CURRENT + if (era_cnt != -1) + { + era = _nl_select_era_entry(era_cnt); + if (want_era) + tm->tm_year = (era->start_date[0] + + ((tm->tm_year - era->offset) + * era->absolute_direction)); + else + /* Era start year assumed. */ + tm->tm_year = era->start_date[0]; + } + else +#endif + if (want_era) + return NULL; + + if (want_xday && !have_wday) + { + if ( !(have_mon && have_mday) && have_yday) + { + /* We don't have tm_mon and/or tm_mday, compute them. */ + int t_mon = 0; + while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday) + t_mon++; + if (!have_mon) + tm->tm_mon = t_mon - 1; + if (!have_mday) + tm->tm_mday = + (tm->tm_yday + - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1); + } + day_of_the_week (tm); + } + if (want_xday && !have_yday) + day_of_the_year (tm); + + return discard_const_p(char, rp); +} + + +char *rep_strptime(const char *buf, const char *format, struct tm *tm) +{ + enum locale_status decided; + +#ifdef _NL_CURRENT + decided = not; +#else + decided = raw; +#endif + return strptime_internal (buf, format, tm, &decided, -1); +} diff --git a/ldb-2.0.8/lib/replace/system/README b/ldb-2.0.8/lib/replace/system/README new file mode 100644 index 0000000..69a2b80 --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/README @@ -0,0 +1,4 @@ +This directory contains wrappers around logical groups of system +include files. The idea is to avoid #ifdef blocks in the main code, +and instead put all the necessary conditional includes in subsystem +specific header files in this directory. diff --git a/ldb-2.0.8/lib/replace/system/aio.h b/ldb-2.0.8/lib/replace/system/aio.h new file mode 100644 index 0000000..784d77f --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/aio.h @@ -0,0 +1,32 @@ +#ifndef _system_aio_h +#define _system_aio_h +/* + Unix SMB/CIFS implementation. + + AIO system include wrappers + + Copyright (C) Andrew Tridgell 2006 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#ifdef HAVE_LIBAIO_H +#include +#endif + +#endif diff --git a/ldb-2.0.8/lib/replace/system/capability.h b/ldb-2.0.8/lib/replace/system/capability.h new file mode 100644 index 0000000..44b8d51 --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/capability.h @@ -0,0 +1,57 @@ +#ifndef _system_capability_h +#define _system_capability_h +/* + Unix SMB/CIFS implementation. + + capability system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#ifdef HAVE_SYS_CAPABILITY_H + +#if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H) && !defined(_PPC_STATFS_H) +#define _I386_STATFS_H +#define _PPC_STATFS_H +#define BROKEN_REDHAT_7_STATFS_WORKAROUND +#endif + +#if defined(BROKEN_RHEL5_SYS_CAP_HEADER) && !defined(_LINUX_TYPES_H) +#define BROKEN_RHEL5_SYS_CAP_HEADER_WORKAROUND +#endif + +#ifdef HAVE_POSIX_CAPABILITIES +#include +#endif + +#ifdef BROKEN_RHEL5_SYS_CAP_HEADER_WORKAROUND +#undef _LINUX_TYPES_H +#undef BROKEN_RHEL5_SYS_CAP_HEADER_WORKAROUND +#endif + +#ifdef BROKEN_REDHAT_7_STATFS_WORKAROUND +#undef _PPC_STATFS_H +#undef _I386_STATFS_H +#undef BROKEN_REDHAT_7_STATFS_WORKAROUND +#endif + +#endif + +#endif diff --git a/ldb-2.0.8/lib/replace/system/dir.h b/ldb-2.0.8/lib/replace/system/dir.h new file mode 100644 index 0000000..497b5a7 --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/dir.h @@ -0,0 +1,71 @@ +#ifndef _system_dir_h +#define _system_dir_h +/* + Unix SMB/CIFS implementation. + + directory system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#ifdef HAVE_DIRENT_H +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# if HAVE_SYS_NDIR_H +# include +# endif +# if HAVE_SYS_DIR_H +# include +# endif +# if HAVE_NDIR_H +# include +# endif +#endif + +#ifndef HAVE_MKDIR_MODE +#define mkdir(dir, mode) mkdir(dir) +#endif + +#ifdef HAVE_LIBGEN_H +# include +#endif + +/* Test whether a file name is the "." or ".." directory entries. + * These really should be inline functions. + */ +#ifndef ISDOT +#define ISDOT(path) ( \ + *((const char *)(path)) == '.' && \ + *(((const char *)(path)) + 1) == '\0' \ + ) +#endif + +#ifndef ISDOTDOT +#define ISDOTDOT(path) ( \ + *((const char *)(path)) == '.' && \ + *(((const char *)(path)) + 1) == '.' && \ + *(((const char *)(path)) + 2) == '\0' \ + ) +#endif + +#endif diff --git a/ldb-2.0.8/lib/replace/system/filesys.h b/ldb-2.0.8/lib/replace/system/filesys.h new file mode 100644 index 0000000..1a8cb68 --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/filesys.h @@ -0,0 +1,242 @@ +#ifndef _system_filesys_h +#define _system_filesys_h +/* + Unix SMB/CIFS implementation. + + filesystem system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include + +#ifdef HAVE_SYS_PARAM_H +#include +#endif + +#ifdef HAVE_SYS_MOUNT_H +#include +#endif + +#ifdef HAVE_MNTENT_H +#include +#endif + +#ifdef HAVE_SYS_VFS_H +#include +#endif + +#ifdef HAVE_SYS_ACL_H +#include +#endif + +#ifdef HAVE_ACL_LIBACL_H +#include +#endif + +#ifdef HAVE_SYS_FS_S5PARAM_H +#include +#endif + +#if defined (HAVE_SYS_FILSYS_H) && !defined (_CRAY) +#include +#endif + +#ifdef HAVE_SYS_STATFS_H +# include +#endif + +#ifdef HAVE_DUSTAT_H +#include +#endif + +#ifdef HAVE_SYS_STATVFS_H +#include +#endif + +#ifdef HAVE_SYS_FILIO_H +#include +#endif + +#ifdef HAVE_SYS_FILE_H +#include +#endif + +#ifdef HAVE_FCNTL_H +#include +#else +#ifdef HAVE_SYS_FCNTL_H +#include +#endif +#endif + +#ifdef HAVE_SYS_MODE_H +/* apparently AIX needs this for S_ISLNK */ +#ifndef S_ISLNK +#include +#endif +#endif + +#ifdef HAVE_SYS_IOCTL_H +#include +#endif + +#ifdef HAVE_SYS_UIO_H +#include +#endif + +#if defined(HAVE_SYS_ATTRIBUTES_H) +#include +#elif defined(HAVE_ATTR_ATTRIBUTES_H) +#include +#endif + +/* mutually exclusive (SuSE 8.2) */ +#if defined(HAVE_ATTR_XATTR_H) +#include +#elif defined(HAVE_SYS_XATTR_H) +#include +#endif + +#ifdef HAVE_SYS_EA_H +#include +#endif + +#ifdef HAVE_SYS_EXTATTR_H +#include +#endif + +#ifdef HAVE_SYS_RESOURCE_H +#include +#endif + +#ifndef XATTR_CREATE +#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */ +#endif + +#ifndef XATTR_REPLACE +#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */ +#endif + +/* Some POSIX definitions for those without */ + +#ifndef S_IFDIR +#define S_IFDIR 0x4000 +#endif +#ifndef S_ISDIR +#define S_ISDIR(mode) ((mode & 0xF000) == S_IFDIR) +#endif +#ifndef S_IRWXU +#define S_IRWXU 00700 /* read, write, execute: owner */ +#endif +#ifndef S_IRUSR +#define S_IRUSR 00400 /* read permission: owner */ +#endif +#ifndef S_IWUSR +#define S_IWUSR 00200 /* write permission: owner */ +#endif +#ifndef S_IXUSR +#define S_IXUSR 00100 /* execute permission: owner */ +#endif +#ifndef S_IRWXG +#define S_IRWXG 00070 /* read, write, execute: group */ +#endif +#ifndef S_IRGRP +#define S_IRGRP 00040 /* read permission: group */ +#endif +#ifndef S_IWGRP +#define S_IWGRP 00020 /* write permission: group */ +#endif +#ifndef S_IXGRP +#define S_IXGRP 00010 /* execute permission: group */ +#endif +#ifndef S_IRWXO +#define S_IRWXO 00007 /* read, write, execute: other */ +#endif +#ifndef S_IROTH +#define S_IROTH 00004 /* read permission: other */ +#endif +#ifndef S_IWOTH +#define S_IWOTH 00002 /* write permission: other */ +#endif +#ifndef S_IXOTH +#define S_IXOTH 00001 /* execute permission: other */ +#endif + +#ifndef O_ACCMODE +#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR) +#endif + +#ifndef MAXPATHLEN +#define MAXPATHLEN 256 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +#ifdef _WIN32 +#define mkdir(d,m) _mkdir(d) +#endif + +/* + this allows us to use a uniform error handling for our xattr + wrappers +*/ +#ifndef ENOATTR +#define ENOATTR ENODATA +#endif + + +#if !defined(HAVE_XATTR_XATTR) || defined(XATTR_ADDITIONAL_OPTIONS) + +ssize_t rep_getxattr (const char *path, const char *name, void *value, size_t size); +#define getxattr(path, name, value, size) rep_getxattr(path, name, value, size) +/* define is in "replace.h" */ +ssize_t rep_fgetxattr (int filedes, const char *name, void *value, size_t size); +#define fgetxattr(filedes, name, value, size) rep_fgetxattr(filedes, name, value, size) +/* define is in "replace.h" */ +ssize_t rep_listxattr (const char *path, char *list, size_t size); +#define listxattr(path, list, size) rep_listxattr(path, list, size) +/* define is in "replace.h" */ +ssize_t rep_flistxattr (int filedes, char *list, size_t size); +#define flistxattr(filedes, value, size) rep_flistxattr(filedes, value, size) +/* define is in "replace.h" */ +int rep_removexattr (const char *path, const char *name); +#define removexattr(path, name) rep_removexattr(path, name) +/* define is in "replace.h" */ +int rep_fremovexattr (int filedes, const char *name); +#define fremovexattr(filedes, name) rep_fremovexattr(filedes, name) +/* define is in "replace.h" */ +int rep_setxattr (const char *path, const char *name, const void *value, size_t size, int flags); +#define setxattr(path, name, value, size, flags) rep_setxattr(path, name, value, size, flags) +/* define is in "replace.h" */ +int rep_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags); +#define fsetxattr(filedes, name, value, size, flags) rep_fsetxattr(filedes, name, value, size, flags) +/* define is in "replace.h" */ + +#endif /* !defined(HAVE_XATTR_XATTR) || defined(XATTR_ADDITIONAL_OPTIONS) */ + +#endif diff --git a/ldb-2.0.8/lib/replace/system/glob.h b/ldb-2.0.8/lib/replace/system/glob.h new file mode 100644 index 0000000..3e23db6 --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/glob.h @@ -0,0 +1,37 @@ +#ifndef _system_glob_h +#define _system_glob_h +/* + Unix SMB/CIFS implementation. + + glob system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifdef HAVE_GLOB_H +#include +#endif + +#ifdef HAVE_FNMATCH_H +#include +#endif + +#endif diff --git a/ldb-2.0.8/lib/replace/system/gssapi.h b/ldb-2.0.8/lib/replace/system/gssapi.h new file mode 100644 index 0000000..d8632d7 --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/gssapi.h @@ -0,0 +1,53 @@ +#ifndef _system_gssapi_h +#define _system_gssapi_h + +/* + Unix SMB/CIFS implementation. + + GSSAPI system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifdef HAVE_GSSAPI + +#ifdef HAVE_GSSAPI_GSSAPI_EXT_H +#include +#elif defined(HAVE_GSSAPI_GSSAPI_H) +#include +#elif defined(HAVE_GSSAPI_GSSAPI_GENERIC_H) +#include +#elif defined(HAVE_GSSAPI_H) +#include +#endif + +#ifdef HAVE_GSSAPI_GSSAPI_KRB5_H +#include +#endif + +#ifdef HAVE_GSSAPI_GSSAPI_SPNEGO_H +#include +#elif defined(HAVE_GSSAPI_SPNEGO_H) +#include +#endif + +#endif +#endif diff --git a/ldb-2.0.8/lib/replace/system/iconv.h b/ldb-2.0.8/lib/replace/system/iconv.h new file mode 100644 index 0000000..3c8a71f --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/iconv.h @@ -0,0 +1,57 @@ +#ifndef _system_iconv_h +#define _system_iconv_h +/* + Unix SMB/CIFS implementation. + + iconv memory system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#if !defined(HAVE_ICONV) && defined(HAVE_ICONV_H) +#define HAVE_ICONV +#endif + +#if !defined(HAVE_GICONV) && defined(HAVE_GICONV_H) +#define HAVE_GICONV +#endif + +#if !defined(HAVE_BICONV) && defined(HAVE_BICONV_H) +#define HAVE_BICONV +#endif + +#ifdef HAVE_NATIVE_ICONV +#if defined(HAVE_ICONV) +#include +#elif defined(HAVE_GICONV) +#include +#elif defined(HAVE_BICONV) +#include +#endif +#endif /* HAVE_NATIVE_ICONV */ + +/* needed for some systems without iconv. Doesn't really matter + what error code we use */ +#ifndef EILSEQ +#define EILSEQ EIO +#endif + +#endif diff --git a/ldb-2.0.8/lib/replace/system/kerberos.h b/ldb-2.0.8/lib/replace/system/kerberos.h new file mode 100644 index 0000000..ebd8657 --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/kerberos.h @@ -0,0 +1,41 @@ +#ifndef _system_kerberos_h +#define _system_kerberos_h + +/* + Unix SMB/CIFS implementation. + + kerberos system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifdef HAVE_KRB5 + +#ifdef HAVE_KRB5_H +#include +#endif + +#ifdef HAVE_COM_ERR_H +#include +#endif + +#endif +#endif diff --git a/ldb-2.0.8/lib/replace/system/locale.h b/ldb-2.0.8/lib/replace/system/locale.h new file mode 100644 index 0000000..504a3bb --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/locale.h @@ -0,0 +1,42 @@ +#ifndef _system_locale_h +#define _system_locale_h + +/* + Unix SMB/CIFS implementation. + + locale include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifdef HAVE_CTYPE_H +#include +#endif + +#ifdef HAVE_LOCALE_H +#include +#endif + +#ifdef HAVE_LANGINFO_H +#include +#endif + +#endif diff --git a/ldb-2.0.8/lib/replace/system/network.h b/ldb-2.0.8/lib/replace/system/network.h new file mode 100644 index 0000000..8254551 --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/network.h @@ -0,0 +1,372 @@ +#ifndef _system_network_h +#define _system_network_h +/* + Unix SMB/CIFS implementation. + + networking system include wrappers + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Jelmer Vernooij 2007 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifndef LIBREPLACE_NETWORK_CHECKS +#error "AC_LIBREPLACE_NETWORK_CHECKS missing in configure" +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +#ifdef HAVE_UNIXSOCKET +#include +#endif + +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif + +#ifdef HAVE_NETDB_H +#include +#endif + +#ifdef HAVE_NETINET_TCP_H +#include +#endif + +/* + * The next three defines are needed to access the IPTOS_* options + * on some systems. + */ + +#ifdef HAVE_NETINET_IN_SYSTM_H +#include +#endif + +#ifdef HAVE_NETINET_IN_IP_H +#include +#endif + +#ifdef HAVE_NETINET_IP_H +#include +#endif + +#ifdef HAVE_NET_IF_H +#include +#endif + +#ifdef HAVE_SYS_IOCTL_H +#include +#endif + +#ifdef HAVE_SYS_UIO_H +#include +#endif + +#ifdef HAVE_STROPTS_H +#include +#endif + +#ifndef HAVE_SOCKLEN_T +#define HAVE_SOCKLEN_T +typedef int socklen_t; +#endif + +#if !defined (HAVE_INET_NTOA) || defined(REPLACE_INET_NTOA) +/* define is in "replace.h" */ +char *rep_inet_ntoa(struct in_addr ip); +#endif + +#ifndef HAVE_INET_PTON +/* define is in "replace.h" */ +int rep_inet_pton(int af, const char *src, void *dst); +#endif + +#ifndef HAVE_INET_NTOP +/* define is in "replace.h" */ +const char *rep_inet_ntop(int af, const void *src, char *dst, socklen_t size); +#endif + +#ifndef HAVE_INET_ATON +/* define is in "replace.h" */ +int rep_inet_aton(const char *src, struct in_addr *dst); +#endif + +#ifndef HAVE_CONNECT +/* define is in "replace.h" */ +int rep_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); +#endif + +#ifndef HAVE_GETHOSTBYNAME +/* define is in "replace.h" */ +struct hostent *rep_gethostbyname(const char *name); +#endif + +#ifdef HAVE_IFADDRS_H +#include +#endif + +#ifndef HAVE_STRUCT_IFADDRS +struct ifaddrs { + struct ifaddrs *ifa_next; /* Pointer to next struct */ + char *ifa_name; /* Interface name */ + unsigned int ifa_flags; /* Interface flags */ + struct sockaddr *ifa_addr; /* Interface address */ + struct sockaddr *ifa_netmask; /* Interface netmask */ +#undef ifa_dstaddr + struct sockaddr *ifa_dstaddr; /* P2P interface destination */ + void *ifa_data; /* Address specific data */ +}; +#endif + +#ifndef HAVE_GETIFADDRS +int rep_getifaddrs(struct ifaddrs **); +#endif + +#ifndef HAVE_FREEIFADDRS +void rep_freeifaddrs(struct ifaddrs *); +#endif + +#ifndef HAVE_SOCKETPAIR +/* define is in "replace.h" */ +int rep_socketpair(int d, int type, int protocol, int sv[2]); +#endif + +/* + * Some systems have getaddrinfo but not the + * defines needed to use it. + */ + +/* Various macros that ought to be in , but might not be */ + +#ifndef EAI_FAIL +#define EAI_BADFLAGS (-1) +#define EAI_NONAME (-2) +#define EAI_AGAIN (-3) +#define EAI_FAIL (-4) +#define EAI_FAMILY (-6) +#define EAI_SOCKTYPE (-7) +#define EAI_SERVICE (-8) +#define EAI_MEMORY (-10) +#define EAI_SYSTEM (-11) +#endif /* !EAI_FAIL */ + +#ifndef AI_PASSIVE +#define AI_PASSIVE 0x0001 +#endif + +#ifndef AI_CANONNAME +#define AI_CANONNAME 0x0002 +#endif + +#ifndef AI_NUMERICHOST +/* + * some platforms don't support AI_NUMERICHOST; define as zero if using + * the system version of getaddrinfo... + */ +#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO) +#define AI_NUMERICHOST 0 +#else +#define AI_NUMERICHOST 0x0004 +#endif +#endif + +/* + * Some of the functions in source3/lib/util_sock.c use AI_ADDRCONFIG. On QNX + * 6.3.0, this macro is defined but, if it's used, getaddrinfo will fail. This + * prevents smbd from opening any sockets. + * + * If I undefine AI_ADDRCONFIG on such systems and define it to be 0, + * this works around the issue. + */ +#ifdef __QNX__ +#include +#if _NTO_VERSION == 630 +#undef AI_ADDRCONFIG +#endif +#endif +#ifndef AI_ADDRCONFIG +/* + * logic copied from AI_NUMERICHOST + */ +#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO) +#define AI_ADDRCONFIG 0 +#else +#define AI_ADDRCONFIG 0x0020 +#endif +#endif + +#ifndef AI_NUMERICSERV +/* + * logic copied from AI_NUMERICHOST + */ +#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO) +#define AI_NUMERICSERV 0 +#else +#define AI_NUMERICSERV 0x0400 +#endif +#endif + +#ifndef NI_NUMERICHOST +#define NI_NUMERICHOST 1 +#endif + +#ifndef NI_NUMERICSERV +#define NI_NUMERICSERV 2 +#endif + +#ifndef NI_NOFQDN +#define NI_NOFQDN 4 +#endif + +#ifndef NI_NAMEREQD +#define NI_NAMEREQD 8 +#endif + +#ifndef NI_DGRAM +#define NI_DGRAM 16 +#endif + + +#ifndef NI_MAXHOST +#define NI_MAXHOST 1025 +#endif + +#ifndef NI_MAXSERV +#define NI_MAXSERV 32 +#endif + +/* + * glibc on linux doesn't seem to have MSG_WAITALL + * defined. I think the kernel has it though.. + */ +#ifndef MSG_WAITALL +#define MSG_WAITALL 0 +#endif + +#ifndef INADDR_LOOPBACK +#define INADDR_LOOPBACK 0x7f000001 +#endif + +#ifndef INADDR_NONE +#define INADDR_NONE 0xffffffff +#endif + +#ifndef EAFNOSUPPORT +#define EAFNOSUPPORT EINVAL +#endif + +#ifndef INET_ADDRSTRLEN +#define INET_ADDRSTRLEN 16 +#endif + +#ifndef INET6_ADDRSTRLEN +#define INET6_ADDRSTRLEN 46 +#endif + +#ifndef HOST_NAME_MAX +#define HOST_NAME_MAX 255 +#endif + +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN HOST_NAME_MAX +#endif + +#ifndef HAVE_SA_FAMILY_T +#define HAVE_SA_FAMILY_T +typedef unsigned short int sa_family_t; +#endif + +#ifndef HAVE_STRUCT_SOCKADDR_STORAGE +#define HAVE_STRUCT_SOCKADDR_STORAGE +#ifdef HAVE_STRUCT_SOCKADDR_IN6 +#define sockaddr_storage sockaddr_in6 +#define ss_family sin6_family +#define HAVE_SS_FAMILY 1 +#else /*HAVE_STRUCT_SOCKADDR_IN6*/ +#define sockaddr_storage sockaddr_in +#define ss_family sin_family +#define HAVE_SS_FAMILY 1 +#endif /*HAVE_STRUCT_SOCKADDR_IN6*/ +#endif /*HAVE_STRUCT_SOCKADDR_STORAGE*/ + +#ifndef HAVE_SS_FAMILY +#ifdef HAVE___SS_FAMILY +#define ss_family __ss_family +#define HAVE_SS_FAMILY 1 +#endif +#endif + +#ifndef IOV_MAX +# ifdef UIO_MAXIOV +# define IOV_MAX UIO_MAXIOV +# else +# ifdef __sgi + /* + * IRIX 6.5 has sysconf(_SC_IOV_MAX) + * which might return 512 or bigger + */ +# define IOV_MAX 512 +# endif +# endif +#endif + +#ifndef HAVE_STRUCT_ADDRINFO +#define HAVE_STRUCT_ADDRINFO +struct addrinfo { + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + socklen_t ai_addrlen; + struct sockaddr *ai_addr; + char *ai_canonname; + struct addrinfo *ai_next; +}; +#endif /* HAVE_STRUCT_ADDRINFO */ + +#if !defined(HAVE_GETADDRINFO) +#include "getaddrinfo.h" +#endif + +/* Needed for some systems that don't define it (Solaris). */ +#ifndef ifr_netmask +#define ifr_netmask ifr_addr +#endif + +/* Some old Linux systems have broken header files */ +#ifdef HAVE_IPV6 +#ifdef HAVE_LINUX_IPV6_V6ONLY_26 +#define IPV6_V6ONLY 26 +#endif /* HAVE_LINUX_IPV6_V6ONLY_26 */ +#endif /* HAVE_IPV6 */ + +#ifndef SCOPE_DELIMITER +#define SCOPE_DELIMITER '%' +#endif + +#endif diff --git a/ldb-2.0.8/lib/replace/system/nis.h b/ldb-2.0.8/lib/replace/system/nis.h new file mode 100644 index 0000000..7213b15 --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/nis.h @@ -0,0 +1,55 @@ +/* + Unix SMB/CIFS implementation. + + nis system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#ifndef _nis_passwd_h +#define _nis_passwd_h + +#if defined(HAVE_RPC_RPC_H) +/* + * Check for AUTH_ERROR define conflict with rpc/rpc.h in prot.h. + */ +#if defined(HAVE_SYS_SECURITY_H) && defined(HAVE_RPC_AUTH_ERROR_CONFLICT) +#undef AUTH_ERROR +#endif /* HAVE_SYS_SECURITY_H && HAVE_RPC_AUTH_ERROR_CONFLICT */ + +#include +#endif /* HAVE_RPC_RPC_H */ + + +#if defined (HAVE_NETGROUP) + +#if defined(HAVE_RPCSVC_YP_PROT_H) + +#include + +#endif /* HAVE_RPCSVC_YP_PROT_H */ + +#if defined(HAVE_RPCSVC_YPCLNT_H) +#include +#endif /* HAVE_RPCSVC_YPCLNT_H */ + +#endif /* HAVE_NETGROUP */ + +#endif /* _nis_passwd_h */ diff --git a/ldb-2.0.8/lib/replace/system/passwd.h b/ldb-2.0.8/lib/replace/system/passwd.h new file mode 100644 index 0000000..ecc9f60 --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/passwd.h @@ -0,0 +1,92 @@ +#ifndef _system_passwd_h +#define _system_passwd_h + +/* + Unix SMB/CIFS implementation. + + passwd system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_PWD_H +#include +#endif +#ifdef HAVE_GRP_H +#include +#endif +#ifdef HAVE_SYS_PRIV_H +#include +#endif +#ifdef HAVE_SYS_ID_H +#include +#endif + +#ifdef HAVE_CRYPT_H +#include +#endif + +#ifdef HAVE_SHADOW_H +#include +#endif + +#ifdef HAVE_SYS_SECURITY_H +#include +#include +#define PASSWORD_LENGTH 16 +#endif /* HAVE_SYS_SECURITY_H */ + +#ifdef HAVE_GETPWANAM +#include +#include +#include +#endif + +#ifdef HAVE_COMPAT_H +#include +#endif + +#ifndef NGROUPS_MAX +#define NGROUPS_MAX 32 /* Guess... */ +#endif + +/* what is the longest significant password available on your system? + Knowing this speeds up password searches a lot */ +#ifndef PASSWORD_LENGTH +#define PASSWORD_LENGTH 8 +#endif + + +#ifndef ALLOW_CHANGE_PASSWORD +#if (defined(HAVE_TERMIOS_H) && defined(HAVE_DUP2) && defined(HAVE_SETSID)) +#define ALLOW_CHANGE_PASSWORD 1 +#endif +#endif + +#if defined(HAVE_CRYPT16) && defined(HAVE_GETAUTHUID) +#define ULTRIX_AUTH 1 +#endif + +#endif diff --git a/ldb-2.0.8/lib/replace/system/readline.h b/ldb-2.0.8/lib/replace/system/readline.h new file mode 100644 index 0000000..2937962 --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/readline.h @@ -0,0 +1,61 @@ +#ifndef _system_readline_h +#define _system_readline_h +/* + Unix SMB/CIFS implementation. + + Readline wrappers + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifdef HAVE_LIBREADLINE +# ifdef HAVE_READLINE_READLINE_H +# ifdef HAVE_READLINE_READLINE_WORKAROUND +# define _FUNCTION_DEF +# endif +# include +# ifdef HAVE_READLINE_HISTORY_H +# include +# endif +# else +# ifdef HAVE_READLINE_H +# include +# ifdef HAVE_HISTORY_H +# include +# endif +# else +# undef HAVE_LIBREADLINE +# endif +# endif +#endif + +#ifdef HAVE_NEW_LIBREADLINE +#ifdef HAVE_CPPFUNCTION +# define RL_COMPLETION_CAST (CPPFunction *) +#elif defined(HAVE_RL_COMPLETION_T) +# define RL_COMPLETION_CAST (rl_completion_t *) +#else +# define RL_COMPLETION_CAST +#endif +#else +/* This type is missing from libreadline<4.0 (approximately) */ +# define RL_COMPLETION_CAST +#endif /* HAVE_NEW_LIBREADLINE */ + +#endif diff --git a/ldb-2.0.8/lib/replace/system/select.h b/ldb-2.0.8/lib/replace/system/select.h new file mode 100644 index 0000000..9e945c3 --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/select.h @@ -0,0 +1,81 @@ +#ifndef _system_select_h +#define _system_select_h +/* + Unix SMB/CIFS implementation. + + select system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifdef HAVE_SYS_SELECT_H +#include +#endif + +#ifdef HAVE_SYS_EPOLL_H +#include +#endif + +#ifdef HAVE_SOLARIS_PORTS +#include +#endif + +#ifndef SELECT_CAST +#define SELECT_CAST +#endif + +#ifdef HAVE_POLL + +#include + +#else + +/* Type used for the number of file descriptors. */ +typedef unsigned long int nfds_t; + +/* Data structure describing a polling request. */ +struct pollfd +{ + int fd; /* File descriptor to poll. */ + short int events; /* Types of events poller cares about. */ + short int revents; /* Types of events that actually occurred. */ +}; + +/* Event types that can be polled for. These bits may be set in `events' + to indicate the interesting event types; they will appear in `revents' + to indicate the status of the file descriptor. */ +#define POLLIN 0x001 /* There is data to read. */ +#define POLLPRI 0x002 /* There is urgent data to read. */ +#define POLLOUT 0x004 /* Writing now will not block. */ +#define POLLRDNORM 0x040 /* Normal data may be read. */ +#define POLLRDBAND 0x080 /* Priority data may be read. */ +#define POLLWRNORM 0x100 /* Writing now will not block. */ +#define POLLWRBAND 0x200 /* Priority data may be written. */ +#define POLLERR 0x008 /* Error condition. */ +#define POLLHUP 0x010 /* Hung up. */ +#define POLLNVAL 0x020 /* Invalid polling request. */ + +/* define is in "replace.h" */ +int rep_poll(struct pollfd *fds, nfds_t nfds, int timeout); + +#endif + +#endif diff --git a/ldb-2.0.8/lib/replace/system/shmem.h b/ldb-2.0.8/lib/replace/system/shmem.h new file mode 100644 index 0000000..64fe39b --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/shmem.h @@ -0,0 +1,59 @@ +#ifndef _system_shmem_h +#define _system_shmem_h +/* + Unix SMB/CIFS implementation. + + shared memory system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#if defined(HAVE_SYS_IPC_H) +#include +#endif /* HAVE_SYS_IPC_H */ + +#if defined(HAVE_SYS_SHM_H) +#include +#endif /* HAVE_SYS_SHM_H */ + +#ifdef HAVE_SYS_MMAN_H +#include +#endif + +/* NetBSD doesn't have these */ +#ifndef SHM_R +#define SHM_R 0400 +#endif + +#ifndef SHM_W +#define SHM_W 0200 +#endif + + +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif + +#ifndef MAP_FAILED +#define MAP_FAILED ((void *)-1) +#endif + +#endif diff --git a/ldb-2.0.8/lib/replace/system/syslog.h b/ldb-2.0.8/lib/replace/system/syslog.h new file mode 100644 index 0000000..104be1d --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/syslog.h @@ -0,0 +1,70 @@ +#ifndef _system_syslog_h +#define _system_syslog_h +/* + Unix SMB/CIFS implementation. + + syslog system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifdef HAVE_SYSLOG_H +#include +#else +#ifdef HAVE_SYS_SYSLOG_H +#include +#endif +#endif + +/* For sys_adminlog(). */ +#ifndef LOG_EMERG +#define LOG_EMERG 0 /* system is unusable */ +#endif + +#ifndef LOG_ALERT +#define LOG_ALERT 1 /* action must be taken immediately */ +#endif + +#ifndef LOG_CRIT +#define LOG_CRIT 2 /* critical conditions */ +#endif + +#ifndef LOG_ERR +#define LOG_ERR 3 /* error conditions */ +#endif + +#ifndef LOG_WARNING +#define LOG_WARNING 4 /* warning conditions */ +#endif + +#ifndef LOG_NOTICE +#define LOG_NOTICE 5 /* normal but significant condition */ +#endif + +#ifndef LOG_INFO +#define LOG_INFO 6 /* informational */ +#endif + +#ifndef LOG_DEBUG +#define LOG_DEBUG 7 /* debug-level messages */ +#endif + +#endif diff --git a/ldb-2.0.8/lib/replace/system/terminal.h b/ldb-2.0.8/lib/replace/system/terminal.h new file mode 100644 index 0000000..9ad601a --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/terminal.h @@ -0,0 +1,46 @@ +#ifndef _system_terminal_h +#define _system_terminal_h +/* + Unix SMB/CIFS implementation. + + terminal system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifdef SUNOS4 +/* on SUNOS4 termios.h conflicts with sys/ioctl.h */ +#undef HAVE_TERMIOS_H +#endif + + +#if defined(HAVE_TERMIOS_H) +/* POSIX terminal handling. */ +#include +#elif defined(HAVE_TERMIO_H) +/* Older SYSV terminal handling - don't use if we can avoid it. */ +#include +#elif defined(HAVE_SYS_TERMIO_H) +/* Older SYSV terminal handling - don't use if we can avoid it. */ +#include +#endif + +#endif diff --git a/ldb-2.0.8/lib/replace/system/threads.h b/ldb-2.0.8/lib/replace/system/threads.h new file mode 100644 index 0000000..d189ed6 --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/threads.h @@ -0,0 +1,72 @@ +#ifndef _system_threads_h +#define _system_threads_h +/* + Unix SMB/CIFS implementation. + + macros to go along with the lib/replace/ portability layer code + + Copyright (C) Volker Lendecke 2012 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include + +#if defined(HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP) && \ + !defined(HAVE_PTHREAD_MUTEXATTR_SETROBUST) +#define pthread_mutexattr_setrobust pthread_mutexattr_setrobust_np +#endif + +#if defined(HAVE_DECL_PTHREAD_MUTEX_ROBUST_NP) && \ + !defined(HAVE_DECL_PTHREAD_MUTEX_ROBUST) +#define PTHREAD_MUTEX_ROBUST PTHREAD_MUTEX_ROBUST_NP +#endif + +#if defined(HAVE_PTHREAD_MUTEX_CONSISTENT_NP) && \ + !defined(HAVE_PTHREAD_MUTEX_CONSISTENT) +#define pthread_mutex_consistent pthread_mutex_consistent_np +#endif + +#ifdef HAVE_STDATOMIC_H +#include +#endif + +#ifndef HAVE_ATOMIC_THREAD_FENCE +#ifdef HAVE___ATOMIC_THREAD_FENCE +#define atomic_thread_fence(__ignore_order) __atomic_thread_fence(__ATOMIC_SEQ_CST) +#define HAVE_ATOMIC_THREAD_FENCE 1 +#endif /* HAVE___ATOMIC_THREAD_FENCE */ +#endif /* not HAVE_ATOMIC_THREAD_FENCE */ + +#ifndef HAVE_ATOMIC_THREAD_FENCE +#ifdef HAVE___SYNC_SYNCHRONIZE +#define atomic_thread_fence(__ignore_order) __sync_synchronize() +#define HAVE_ATOMIC_THREAD_FENCE 1 +#endif /* HAVE___SYNC_SYNCHRONIZE */ +#endif /* not HAVE_ATOMIC_THREAD_FENCE */ + +#ifndef HAVE_ATOMIC_THREAD_FENCE +#ifdef HAVE_ATOMIC_THREAD_FENCE_SUPPORT +#error mismatch_error_between_configure_test_and_header +#endif +/* make sure the build fails if someone uses it without checking the define */ +#define atomic_thread_fence(__order) \ + __function__atomic_thread_fence_not_available_on_this_platform__() +#endif /* not HAVE_ATOMIC_THREAD_FENCE */ + +#endif diff --git a/ldb-2.0.8/lib/replace/system/time.h b/ldb-2.0.8/lib/replace/system/time.h new file mode 100644 index 0000000..00f0d7f --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/time.h @@ -0,0 +1,99 @@ +#ifndef _system_time_h +#define _system_time_h +/* + Unix SMB/CIFS implementation. + + time system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifdef TIME_WITH_SYS_TIME +#include +#include +#else +#ifdef HAVE_SYS_TIME_H +#include +#else +#include +#endif +#endif + +#ifdef HAVE_UTIME_H +#include +#else +struct utimbuf { + time_t actime; /* access time */ + time_t modtime; /* modification time */ +}; +#endif + +#ifndef HAVE_STRUCT_TIMESPEC +struct timespec { + time_t tv_sec; /* Seconds. */ + long tv_nsec; /* Nanoseconds. */ +}; +#endif + +#ifndef HAVE_MKTIME +/* define is in "replace.h" */ +time_t rep_mktime(struct tm *t); +#endif + +#ifndef HAVE_TIMEGM +/* define is in "replace.h" */ +time_t rep_timegm(struct tm *tm); +#endif + +#ifndef HAVE_UTIME +/* define is in "replace.h" */ +int rep_utime(const char *filename, const struct utimbuf *buf); +#endif + +#ifndef HAVE_UTIMES +/* define is in "replace.h" */ +int rep_utimes(const char *filename, const struct timeval tv[2]); +#endif + +#ifndef HAVE_CLOCK_GETTIME +/* CLOCK_REALTIME is required by POSIX */ +#define CLOCK_REALTIME 0 +typedef int clockid_t; +int rep_clock_gettime(clockid_t clk_id, struct timespec *tp); +#endif +/* make sure we have a best effort CUSTOM_CLOCK_MONOTONIC we can rely on. + * + * on AIX the values of CLOCK_* are cast expressions, not integer constants, + * this prevents them from being compared against in a preprocessor directive. + * The following ...IS_* macros can be used to check which clock is in use. + */ +#if defined(CLOCK_MONOTONIC) +#define CUSTOM_CLOCK_MONOTONIC CLOCK_MONOTONIC +#define CUSTOM_CLOCK_MONOTONIC_IS_MONOTONIC +#elif defined(CLOCK_HIGHRES) +#define CUSTOM_CLOCK_MONOTONIC CLOCK_HIGHRES +#define CUSTOM_CLOCK_MONOTONIC_IS_HIGHRES +#else +#define CUSTOM_CLOCK_MONOTONIC CLOCK_REALTIME +#define CUSTOM_CLOCK_MONOTONIC_IS_REALTIME +#endif + +#endif diff --git a/ldb-2.0.8/lib/replace/system/wait.h b/ldb-2.0.8/lib/replace/system/wait.h new file mode 100644 index 0000000..1f5fcd9 --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/wait.h @@ -0,0 +1,55 @@ +#ifndef _system_wait_h +#define _system_wait_h +/* + Unix SMB/CIFS implementation. + + waitpid system include wrappers + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . + +*/ + +#ifdef HAVE_SYS_WAIT_H +#include +#endif + +#include + +#ifndef SIGCLD +#define SIGCLD SIGCHLD +#endif + +#ifdef HAVE_SETJMP_H +#include +#endif + +#ifdef HAVE_SYS_UCONTEXT_H +#include +#endif + +#if !defined(HAVE_SIG_ATOMIC_T_TYPE) +typedef int sig_atomic_t; +#endif + +#if !defined(HAVE_WAITPID) && defined(HAVE_WAIT4) +int rep_waitpid(pid_t pid,int *status,int options); +#endif + +#endif diff --git a/ldb-2.0.8/lib/replace/system/wscript_configure b/ldb-2.0.8/lib/replace/system/wscript_configure new file mode 100644 index 0000000..ecd9964 --- /dev/null +++ b/ldb-2.0.8/lib/replace/system/wscript_configure @@ -0,0 +1,18 @@ +#!/usr/bin/env python + +# solaris varients of getXXent_r +conf.CHECK_C_PROTOTYPE('getpwent_r', + 'struct passwd *getpwent_r(struct passwd *src, char *buf, int buflen)', + define='SOLARIS_GETPWENT_R', headers='pwd.h') +conf.CHECK_C_PROTOTYPE('getgrent_r', + 'struct group *getgrent_r(struct group *src, char *buf, int buflen)', + define='SOLARIS_GETGRENT_R', headers='grp.h') + +# the irix varients +conf.CHECK_C_PROTOTYPE('getpwent_r', + 'struct passwd *getpwent_r(struct passwd *src, char *buf, size_t buflen)', + define='SOLARIS_GETPWENT_R', headers='pwd.h') +conf.CHECK_C_PROTOTYPE('getgrent_r', + 'struct group *getgrent_r(struct group *src, char *buf, size_t buflen)', + define='SOLARIS_GETGRENT_R', headers='grp.h') + diff --git a/ldb-2.0.8/lib/replace/tests/getifaddrs.c b/ldb-2.0.8/lib/replace/tests/getifaddrs.c new file mode 100644 index 0000000..8d575af --- /dev/null +++ b/ldb-2.0.8/lib/replace/tests/getifaddrs.c @@ -0,0 +1,105 @@ +/* + * Unix SMB/CIFS implementation. + * + * libreplace getifaddrs test + * + * Copyright (C) Michael Adam 2008 + * + * ** NOTE! The following LGPL license applies to the replace + * ** library. This does NOT imply that all of Samba is released + * ** under the LGPL + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef AUTOCONF_TEST +#include "replace.h" +#include "system/network.h" +#include "replace-test.h" +#endif + +#ifdef HAVE_INET_NTOP +#define rep_inet_ntop inet_ntop +#endif + +static const char *format_sockaddr(struct sockaddr *addr, + char *addrstring, + socklen_t addrlen) +{ + const char *result = NULL; + + if (addr->sa_family == AF_INET) { + result = rep_inet_ntop(AF_INET, + &((struct sockaddr_in *)addr)->sin_addr, + addrstring, + addrlen); +#ifdef HAVE_STRUCT_SOCKADDR_IN6 + } else if (addr->sa_family == AF_INET6) { + result = rep_inet_ntop(AF_INET6, + &((struct sockaddr_in6 *)addr)->sin6_addr, + addrstring, + addrlen); +#endif + } + return result; +} + +int getifaddrs_test(void) +{ + struct ifaddrs *ifs = NULL; + struct ifaddrs *ifs_head = NULL; + int ret; + + ret = getifaddrs(&ifs); + ifs_head = ifs; + if (ret != 0) { + fprintf(stderr, "getifaddrs() failed: %s\n", strerror(errno)); + return 1; + } + + while (ifs) { + printf("%-10s ", ifs->ifa_name); + if (ifs->ifa_addr != NULL) { + char addrstring[INET6_ADDRSTRLEN]; + const char *result; + + result = format_sockaddr(ifs->ifa_addr, + addrstring, + sizeof(addrstring)); + if (result != NULL) { + printf("IP=%s ", addrstring); + } + + if (ifs->ifa_netmask != NULL) { + result = format_sockaddr(ifs->ifa_netmask, + addrstring, + sizeof(addrstring)); + if (result != NULL) { + printf("NETMASK=%s", addrstring); + } + } else { + printf("AF=%d ", ifs->ifa_addr->sa_family); + } + } else { + printf(""); + } + + printf("\n"); + ifs = ifs->ifa_next; + } + + freeifaddrs(ifs_head); + + return 0; +} diff --git a/ldb-2.0.8/lib/replace/tests/incoherent_mmap.c b/ldb-2.0.8/lib/replace/tests/incoherent_mmap.c new file mode 100644 index 0000000..ee288fd --- /dev/null +++ b/ldb-2.0.8/lib/replace/tests/incoherent_mmap.c @@ -0,0 +1,83 @@ +/* In OpenBSD, if you write to a file, another process doesn't see it + * in its mmap. Returns with exit status 0 if that is the case, 1 if + * it's coherent, and other if there's a problem. */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DATA "coherent.mmap" + +int main(int argc, char *argv[]) +{ + int tochild[2], toparent[2]; + int fd; + volatile unsigned char *map; + unsigned char *page; + const char *fname = argv[1]; + char c = 0; + + if (pipe(tochild) != 0 || pipe(toparent) != 0) + err(2, "Creating pipe"); + + if (!fname) + fname = DATA; + + fd = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0600); + if (fd < 0) + err(2, "opening %s", fname); + unlink(fname); + + switch (fork()) { + case -1: + err(2, "Fork"); + case 0: + close(tochild[1]); + close(toparent[0]); + + /* Wait for parent to create file. */ + if (read(tochild[0], &c, 1) != 1) + err(2, "reading from parent"); + + /* Alter first byte. */ + pwrite(fd, &c, 1, 0); + + if (write(toparent[1], &c, 1) != 1) + err(2, "writing to parent"); + exit(0); + + default: + close(tochild[0]); + close(toparent[1]); + + /* Create a file and mmap it. */ + page = malloc(getpagesize()); + memset(page, 0x42, getpagesize()); + if (write(fd, page, getpagesize()) != getpagesize()) + err(2, "writing first page"); + map = mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE, + MAP_SHARED, fd, 0); + if (map == MAP_FAILED) + err(2, "mapping file"); + + if (*map != 0x42) + errx(2, "first byte isn't 0x42!"); + + /* Tell child to alter file. */ + if (write(tochild[1], &c, 1) != 1) + err(2, "writing to child"); + + if (read(toparent[0], &c, 1) != 1) + err(2, "reading from child"); + + if (*map) + errx(0, "mmap incoherent: first byte isn't 0."); + + exit(1); + } +} diff --git a/ldb-2.0.8/lib/replace/tests/main.c b/ldb-2.0.8/lib/replace/tests/main.c new file mode 100644 index 0000000..94264d7 --- /dev/null +++ b/ldb-2.0.8/lib/replace/tests/main.c @@ -0,0 +1,35 @@ +/* + Unix SMB/CIFS implementation. + + libreplace tests + + Copyright (C) Jelmer Vernooij 2006 + + ** NOTE! The following LGPL license applies to the talloc + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#include "replace-testsuite.h" + +int main(void) +{ + bool ret = torture_local_replace(NULL); + if (ret) + return 0; + return -1; +} diff --git a/ldb-2.0.8/lib/replace/tests/os2_delete.c b/ldb-2.0.8/lib/replace/tests/os2_delete.c new file mode 100644 index 0000000..4b99ccf --- /dev/null +++ b/ldb-2.0.8/lib/replace/tests/os2_delete.c @@ -0,0 +1,134 @@ +/* + test readdir/unlink pattern that OS/2 uses + tridge@samba.org July 2005 +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "replace-test.h" + +#define NUM_FILES 700 +#define READDIR_SIZE 100 +#define DELETE_SIZE 4 + +#define TESTDIR "test.dir" + +static int test_readdir_os2_delete_ret; + +#define FAILED(d) (printf("failure: readdir [\nFailed for %s - %d = %s\n]\n", d, errno, strerror(errno)), test_readdir_os2_delete_ret = 1) + +#ifndef MIN +#define MIN(a,b) ((a)<(b)?(a):(b)) +#endif + +#ifdef _WIN32 +#define mkdir(d,m) _mkdir(d) +#endif + +static void cleanup(void) +{ + /* I'm a lazy bastard */ + if (system("rm -rf " TESTDIR)) { + FAILED("system"); + } + mkdir(TESTDIR, 0700) == 0 || FAILED("mkdir"); +} + +static void create_files(void) +{ + int i; + for (i=0;id_name); + } + + if (i == 0) { + return 0; + } + + /* delete the first few */ + for (j=0; jd_name, ".") == 0 || FAILED("match ."); + de = readdir(d); + strcmp(de->d_name, "..") == 0 || FAILED("match .."); + + while (1) { + int n = os2_delete(d); + if (n == 0) break; + total_deleted += n; + } + closedir(d); + + fprintf(stderr, "Deleted %d files of %d\n", total_deleted, NUM_FILES); + + rmdir(TESTDIR) == 0 || FAILED("rmdir"); + + if (system("rm -rf " TESTDIR) == -1) { + FAILED("system"); + } + + return test_readdir_os2_delete_ret; +} diff --git a/ldb-2.0.8/lib/replace/tests/shared_mmap.c b/ldb-2.0.8/lib/replace/tests/shared_mmap.c new file mode 100644 index 0000000..9d6e3fc --- /dev/null +++ b/ldb-2.0.8/lib/replace/tests/shared_mmap.c @@ -0,0 +1,71 @@ +/* this tests whether we can use a shared writeable mmap on a file - + as needed for the mmap variant of FAST_SHARE_MODES */ + +#if defined(HAVE_UNISTD_H) +#include +#endif +#ifdef HAVE_STDLIB_H +#include +#endif +#include +#include +#include +#include + +#define DATA "conftest.mmap" + +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif + +int main(void) +{ + int *buf; + int i; + int fd = open(DATA,O_RDWR|O_CREAT|O_TRUNC,0666); + int count=7; + + if (fd == -1) exit(1); + + for (i=0;i<10000;i++) { + write(fd,&i,sizeof(i)); + } + + close(fd); + + if (fork() == 0) { + fd = open(DATA,O_RDWR); + if (fd == -1) exit(1); + + buf = (int *)mmap(NULL, 10000*sizeof(int), + (PROT_READ | PROT_WRITE), + MAP_FILE | MAP_SHARED, + fd, 0); + + while (count-- && buf[9124] != 55732) sleep(1); + + if (count <= 0) exit(1); + + buf[1763] = 7268; + exit(0); + } + + fd = open(DATA,O_RDWR); + if (fd == -1) exit(1); + + buf = (int *)mmap(NULL, 10000*sizeof(int), + (PROT_READ | PROT_WRITE), + MAP_FILE | MAP_SHARED, + fd, 0); + + if (buf == (int *)-1) exit(1); + + buf[9124] = 55732; + + while (count-- && buf[1763] != 7268) sleep(1); + + unlink(DATA); + + if (count > 0) exit(0); + exit(1); +} diff --git a/ldb-2.0.8/lib/replace/tests/shared_mremap.c b/ldb-2.0.8/lib/replace/tests/shared_mremap.c new file mode 100644 index 0000000..08040e2 --- /dev/null +++ b/ldb-2.0.8/lib/replace/tests/shared_mremap.c @@ -0,0 +1,51 @@ +/* this tests whether we can use mremap */ + +#if defined(HAVE_UNISTD_H) +#include +#endif +#ifdef HAVE_STDLIB_H +#include +#endif +#include +#include +#include +#include + +#define DATA "conftest.mmap" + +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif + +#ifndef MAP_FAILED +#define MAP_FAILED (int *)-1 +#endif + +int main(void) +{ + int *buf; + int fd; + int err = 1; + + fd = open(DATA, O_RDWR|O_CREAT|O_TRUNC, 0666); + if (fd == -1) { + exit(1); + } + + buf = (int *)mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, + MAP_FILE | MAP_SHARED, fd, 0); + if (buf == MAP_FAILED) { + goto done; + } + + buf = mremap(buf, 0x1000, 0x2000, MREMAP_MAYMOVE); + if (buf == MAP_FAILED) { + goto done; + } + + err = 0; +done: + close(fd); + unlink(DATA); + exit(err); +} diff --git a/ldb-2.0.8/lib/replace/tests/snprintf.c b/ldb-2.0.8/lib/replace/tests/snprintf.c new file mode 100644 index 0000000..77473f0 --- /dev/null +++ b/ldb-2.0.8/lib/replace/tests/snprintf.c @@ -0,0 +1,29 @@ +void foo(const char *format, ...) +{ + va_list ap; + int len; + char buf[20]; + long long l = 1234567890; + l *= 100; + + va_start(ap, format); + len = vsnprintf(buf, 0, format, ap); + va_end(ap); + if (len != 5) exit(1); + + va_start(ap, format); + len = vsnprintf(0, 0, format, ap); + va_end(ap); + if (len != 5) exit(2); + + if (snprintf(buf, 3, "hello") != 5 || strcmp(buf, "he") != 0) exit(3); + + if (snprintf(buf, 20, "%lld", l) != 12 || strcmp(buf, "123456789000") != 0) exit(4); + if (snprintf(buf, 20, "%zu", 123456789) != 9 || strcmp(buf, "123456789") != 0) exit(5); + if (snprintf(buf, 20, "%2\$d %1\$d", 3, 4) != 3 || strcmp(buf, "4 3") != 0) exit(6); + if (snprintf(buf, 20, "%s", 0) < 3) exit(7); + + printf("1"); + exit(0); +} +int main(void) { foo("hello"); } diff --git a/ldb-2.0.8/lib/replace/tests/strptime.c b/ldb-2.0.8/lib/replace/tests/strptime.c new file mode 100644 index 0000000..5bf03f5 --- /dev/null +++ b/ldb-2.0.8/lib/replace/tests/strptime.c @@ -0,0 +1,173 @@ + +#ifdef LIBREPLACE_CONFIGURE_TEST_STRPTIME + +#include +#include +#include + +#define true 1 +#define false 0 + +#ifndef __STRING +#define __STRING(x) #x +#endif + +/* make printf a no-op */ +#define printf if(0) printf + +#else /* LIBREPLACE_CONFIGURE_TEST_STRPTIME */ + +#include "replace.h" +#include "system/time.h" +#include "replace-test.h" + +#endif /* LIBREPLACE_CONFIGURE_TEST_STRPTIME */ + +int libreplace_test_strptime(void) +{ + const char *s = "20070414101546Z"; + char *ret; + struct tm t, t2; + + memset(&t, 0, sizeof(t)); + memset(&t2, 0, sizeof(t2)); + + printf("test: strptime\n"); + + ret = strptime(s, "%Y%m%d%H%M%S", &t); + if ( ret == NULL ) { + printf("failure: strptime [\n" + "returned NULL\n" + "]\n"); + return false; + } + + if ( *ret != 'Z' ) { + printf("failure: strptime [\n" + "ret doesn't point to 'Z'\n" + "]\n"); + return false; + } + + ret = strptime(s, "%Y%m%d%H%M%SZ", &t2); + if ( ret == NULL ) { + printf("failure: strptime [\n" + "returned NULL with Z\n" + "]\n"); + return false; + } + + if ( *ret != '\0' ) { + printf("failure: strptime [\n" + "ret doesn't point to '\\0'\n" + "]\n"); + return false; + } + +#define CMP_TM_ELEMENT(t1,t2,elem) \ + if (t1.elem != t2.elem) { \ + printf("failure: strptime [\n" \ + "result differs if the format string has a 'Z' at the end\n" \ + "element: %s %d != %d\n" \ + "]\n", \ + __STRING(elen), t1.elem, t2.elem); \ + return false; \ + } + + CMP_TM_ELEMENT(t,t2,tm_sec); + CMP_TM_ELEMENT(t,t2,tm_min); + CMP_TM_ELEMENT(t,t2,tm_hour); + CMP_TM_ELEMENT(t,t2,tm_mday); + CMP_TM_ELEMENT(t,t2,tm_mon); + CMP_TM_ELEMENT(t,t2,tm_year); + CMP_TM_ELEMENT(t,t2,tm_wday); + CMP_TM_ELEMENT(t,t2,tm_yday); + CMP_TM_ELEMENT(t,t2,tm_isdst); + + if (t.tm_sec != 46) { + printf("failure: strptime [\n" + "tm_sec: expected: 46, got: %d\n" + "]\n", + t.tm_sec); + return false; + } + + if (t.tm_min != 15) { + printf("failure: strptime [\n" + "tm_min: expected: 15, got: %d\n" + "]\n", + t.tm_min); + return false; + } + + if (t.tm_hour != 10) { + printf("failure: strptime [\n" + "tm_hour: expected: 10, got: %d\n" + "]\n", + t.tm_hour); + return false; + } + + if (t.tm_mday != 14) { + printf("failure: strptime [\n" + "tm_mday: expected: 14, got: %d\n" + "]\n", + t.tm_mday); + return false; + } + + if (t.tm_mon != 3) { + printf("failure: strptime [\n" + "tm_mon: expected: 3, got: %d\n" + "]\n", + t.tm_mon); + return false; + } + + if (t.tm_year != 107) { + printf("failure: strptime [\n" + "tm_year: expected: 107, got: %d\n" + "]\n", + t.tm_year); + return false; + } + + if (t.tm_wday != 6) { /* saturday */ + printf("failure: strptime [\n" + "tm_wday: expected: 6, got: %d\n" + "]\n", + t.tm_wday); + return false; + } + + if (t.tm_yday != 103) { + printf("failure: strptime [\n" + "tm_yday: expected: 103, got: %d\n" + "]\n", + t.tm_yday); + return false; + } + + /* we don't test this as it depends on the host configuration + if (t.tm_isdst != 0) { + printf("failure: strptime [\n" + "tm_isdst: expected: 0, got: %d\n" + "]\n", + t.tm_isdst); + return false; + }*/ + + printf("success: strptime\n"); + + return true; +} + +#ifdef LIBREPLACE_CONFIGURE_TEST_STRPTIME +int main (void) +{ + int ret; + ret = libreplace_test_strptime(); + if (ret == false) return 1; + return 0; +} +#endif diff --git a/ldb-2.0.8/lib/replace/tests/testsuite.c b/ldb-2.0.8/lib/replace/tests/testsuite.c new file mode 100644 index 0000000..dba545e --- /dev/null +++ b/ldb-2.0.8/lib/replace/tests/testsuite.c @@ -0,0 +1,1151 @@ +/* + Unix SMB/CIFS implementation. + + libreplace tests + + Copyright (C) Jelmer Vernooij 2006 + + ** NOTE! The following LGPL license applies to the talloc + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#include "replace-test.h" +#include "replace-testsuite.h" + +/* + we include all the system/ include files here so that libreplace tests + them in the build farm +*/ +#include "system/capability.h" +#include "system/dir.h" +#include "system/filesys.h" +#include "system/glob.h" +#include "system/iconv.h" +#include "system/locale.h" +#include "system/network.h" +#include "system/passwd.h" +#include "system/readline.h" +#include "system/select.h" +#include "system/shmem.h" +#include "system/syslog.h" +#include "system/terminal.h" +#include "system/time.h" +#include "system/wait.h" +#include "system/aio.h" + +#define TESTFILE "testfile.dat" + + +/* + test ftruncate() function + */ +static int test_ftruncate(void) +{ + struct stat st; + int fd; + const int size = 1234; + printf("test: ftruncate\n"); + unlink(TESTFILE); + fd = open(TESTFILE, O_RDWR|O_CREAT, 0600); + if (fd == -1) { + printf("failure: ftruncate [\n" + "creating '%s' failed - %s\n]\n", TESTFILE, strerror(errno)); + return false; + } + if (ftruncate(fd, size) != 0) { + printf("failure: ftruncate [\n%s\n]\n", strerror(errno)); + close(fd); + return false; + } + if (fstat(fd, &st) != 0) { + printf("failure: ftruncate [\nfstat failed - %s\n]\n", strerror(errno)); + close(fd); + return false; + } + if (st.st_size != size) { + printf("failure: ftruncate [\ngave wrong size %d - expected %d\n]\n", + (int)st.st_size, size); + close(fd); + return false; + } + unlink(TESTFILE); + printf("success: ftruncate\n"); + close(fd); + return true; +} + +/* + test strlcpy() function. + see http://www.gratisoft.us/todd/papers/strlcpy.html + */ +static int test_strlcpy(void) +{ + char buf[4]; + const struct { + const char *src; + size_t result; + } tests[] = { + { "abc", 3 }, + { "abcdef", 6 }, + { "abcd", 4 }, + { "", 0 }, + { NULL, 0 } + }; + int i; + printf("test: strlcpy\n"); + for (i=0;tests[i].src;i++) { + if (strlcpy(buf, tests[i].src, sizeof(buf)) != tests[i].result) { + printf("failure: strlcpy [\ntest %d failed\n]\n", i); + return false; + } + } + printf("success: strlcpy\n"); + return true; +} + +static int test_strlcat(void) +{ + char tmp[10]; + printf("test: strlcat\n"); + strlcpy(tmp, "", sizeof(tmp)); + if (strlcat(tmp, "bla", 3) != 3) { + printf("failure: strlcat [\ninvalid return code\n]\n"); + return false; + } + if (strcmp(tmp, "bl") != 0) { + printf("failure: strlcat [\nexpected \"bl\", got \"%s\"\n]\n", + tmp); + return false; + } + + strlcpy(tmp, "da", sizeof(tmp)); + if (strlcat(tmp, "me", 4) != 4) { + printf("failure: strlcat [\nexpected \"dam\", got \"%s\"\n]\n", + tmp); + return false; + } + + printf("success: strlcat\n"); + return true; +} + +static int test_mktime(void) +{ + /* FIXME */ + return true; +} + +static int test_initgroups(void) +{ + /* FIXME */ + return true; +} + +static int test_memmove(void) +{ + /* FIXME */ + return true; +} + +static int test_strdup(void) +{ + char *x; + printf("test: strdup\n"); + x = strdup("bla"); + if (strcmp("bla", x) != 0) { + printf("failure: strdup [\nfailed: expected \"bla\", got \"%s\"\n]\n", + x); + return false; + } + free(x); + printf("success: strdup\n"); + return true; +} + +static int test_setlinebuf(void) +{ + printf("test: setlinebuf\n"); + setlinebuf(stdout); + printf("success: setlinebuf\n"); + return true; +} + +static int test_vsyslog(void) +{ + /* FIXME */ + return true; +} + +static int test_timegm(void) +{ + /* FIXME */ + return true; +} + +static int test_setenv(void) +{ +#define TEST_SETENV(key, value, overwrite, result) do { \ + int _ret; \ + char *_v; \ + _ret = setenv(key, value, overwrite); \ + if (_ret != 0) { \ + printf("failure: setenv [\n" \ + "setenv(%s, %s, %d) failed\n" \ + "]\n", \ + key, value, overwrite); \ + return false; \ + } \ + _v=getenv(key); \ + if (!_v) { \ + printf("failure: setenv [\n" \ + "getenv(%s) returned NULL\n" \ + "]\n", \ + key); \ + return false; \ + } \ + if (strcmp(result, _v) != 0) { \ + printf("failure: setenv [\n" \ + "getenv(%s): '%s' != '%s'\n" \ + "]\n", \ + key, result, _v); \ + return false; \ + } \ +} while(0) + +#define TEST_UNSETENV(key) do { \ + char *_v; \ + unsetenv(key); \ + _v=getenv(key); \ + if (_v) { \ + printf("failure: setenv [\n" \ + "getenv(%s): NULL != '%s'\n" \ + "]\n", \ + SETENVTEST_KEY, _v); \ + return false; \ + } \ +} while (0) + +#define SETENVTEST_KEY "SETENVTESTKEY" +#define SETENVTEST_VAL "SETENVTESTVAL" + + printf("test: setenv\n"); + TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"1", 0, SETENVTEST_VAL"1"); + TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"2", 0, SETENVTEST_VAL"1"); + TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"3", 1, SETENVTEST_VAL"3"); + TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"4", 1, SETENVTEST_VAL"4"); + TEST_UNSETENV(SETENVTEST_KEY); + TEST_UNSETENV(SETENVTEST_KEY); + TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"5", 0, SETENVTEST_VAL"5"); + TEST_UNSETENV(SETENVTEST_KEY); + TEST_UNSETENV(SETENVTEST_KEY); + printf("success: setenv\n"); + return true; +} + +static int test_strndup(void) +{ + char *x; + printf("test: strndup\n"); + x = strndup("bla", 0); + if (strcmp(x, "") != 0) { + printf("failure: strndup [\ninvalid\n]\n"); + return false; + } + free(x); + x = strndup("bla", 2); + if (strcmp(x, "bl") != 0) { + printf("failure: strndup [\ninvalid\n]\n"); + return false; + } + free(x); + x = strndup("bla", 10); + if (strcmp(x, "bla") != 0) { + printf("failure: strndup [\ninvalid\n]\n"); + free(x); + return false; + } + free(x); + printf("success: strndup\n"); + return true; +} + +static int test_strnlen(void) +{ + printf("test: strnlen\n"); + if (strnlen("bla", 2) != 2) { + printf("failure: strnlen [\nunexpected length\n]\n"); + return false; + } + + if (strnlen("some text\n", 0) != 0) { + printf("failure: strnlen [\nunexpected length\n]\n"); + return false; + } + + if (strnlen("some text", 20) != 9) { + printf("failure: strnlen [\nunexpected length\n]\n"); + return false; + } + + printf("success: strnlen\n"); + return true; +} + +static int test_waitpid(void) +{ + /* FIXME */ + return true; +} + +static int test_seteuid(void) +{ + /* FIXME */ + return true; +} + +static int test_setegid(void) +{ + /* FIXME */ + return true; +} + +static int test_asprintf(void) +{ + char *x; + printf("test: asprintf\n"); + if (asprintf(&x, "%d", 9) != 1) { + printf("failure: asprintf [\ngenerate asprintf\n]\n"); + return false; + } + if (strcmp(x, "9") != 0) { + printf("failure: asprintf [\ngenerate asprintf\n]\n"); + return false; + } + if (asprintf(&x, "dat%s", "a") != 4) { + printf("failure: asprintf [\ngenerate asprintf\n]\n"); + return false; + } + if (strcmp(x, "data") != 0) { + printf("failure: asprintf [\ngenerate asprintf\n]\n"); + return false; + } + printf("success: asprintf\n"); + return true; +} + +static int test_snprintf(void) +{ + char tmp[10]; + printf("test: snprintf\n"); + if (snprintf(tmp, 3, "foo%d", 9) != 4) { + printf("failure: snprintf [\nsnprintf return code failed\n]\n"); + return false; + } + + if (strcmp(tmp, "fo") != 0) { + printf("failure: snprintf [\nsnprintf failed\n]\n"); + return false; + } + + printf("success: snprintf\n"); + return true; +} + +static int test_vasprintf(void) +{ + /* FIXME */ + return true; +} + +static int test_vsnprintf(void) +{ + /* FIXME */ + return true; +} + +static int test_opendir(void) +{ + /* FIXME */ + return true; +} + +static int test_readdir(void) +{ + printf("test: readdir\n"); + if (test_readdir_os2_delete() != 0) { + return false; + } + printf("success: readdir\n"); + return true; +} + +static int test_telldir(void) +{ + /* FIXME */ + return true; +} + +static int test_seekdir(void) +{ + /* FIXME */ + return true; +} + +static int test_dlopen(void) +{ + /* FIXME: test dlopen, dlsym, dlclose, dlerror */ + return true; +} + + +static int test_chroot(void) +{ + /* FIXME: chroot() */ + return true; +} + +static int test_bzero(void) +{ + /* FIXME: bzero */ + return true; +} + +static int test_strerror(void) +{ + /* FIXME */ + return true; +} + +static int test_errno(void) +{ + printf("test: errno\n"); + errno = 3; + if (errno != 3) { + printf("failure: errno [\nerrno failed\n]\n"); + return false; + } + + printf("success: errno\n"); + return true; +} + +static int test_mkdtemp(void) +{ + /* FIXME */ + return true; +} + +static int test_mkstemp(void) +{ + /* FIXME */ + return true; +} + +static int test_pread(void) +{ + /* FIXME */ + return true; +} + +static int test_pwrite(void) +{ + /* FIXME */ + return true; +} + +static int test_inet_ntoa(void) +{ + /* FIXME */ + return true; +} + +#define TEST_STRTO_X(type,fmt,func,str,base,res,diff,rrnoo) do {\ + type _v; \ + char _s[64]; \ + char *_p = NULL;\ + char *_ep = NULL; \ + strlcpy(_s, str, sizeof(_s));\ + if (diff >= 0) { \ + _ep = &_s[diff]; \ + } \ + errno = 0; \ + _v = func(_s, &_p, base); \ + if (errno != rrnoo) { \ + printf("failure: %s [\n" \ + "\t%s\n" \ + "\t%s(\"%s\",%d,%d): " fmt " (=/!)= " fmt "\n" \ + "\terrno: %d != %d\n" \ + "]\n", \ + __STRING(func), __location__, __STRING(func), \ + str, diff, base, res, _v, rrnoo, errno); \ + return false; \ + } else if (_v != res) { \ + printf("failure: %s [\n" \ + "\t%s\n" \ + "\t%s(\"%s\",%d,%d): " fmt " != " fmt "\n" \ + "]\n", \ + __STRING(func), __location__, __STRING(func), \ + str, diff, base, res, _v); \ + return false; \ + } else if (_p != _ep) { \ + printf("failure: %s [\n" \ + "\t%s\n" \ + "\t%s(\"%s\",%d,%d): " fmt " (=/!)= " fmt "\n" \ + "\tptr: %p - %p = %d != %d\n" \ + "]\n", \ + __STRING(func), __location__, __STRING(func), \ + str, diff, base, res, _v, _ep, _p, (int)(diff - (_ep - _p)), diff); \ + return false; \ + } \ +} while (0) + +static int test_strtoll(void) +{ + printf("test: strtoll\n"); + +#define TEST_STRTOLL(str,base,res,diff,errnoo) TEST_STRTO_X(long long int, "%lld", strtoll,str,base,res,diff,errnoo) + + TEST_STRTOLL("15", 10, 15LL, 2, 0); + TEST_STRTOLL(" 15", 10, 15LL, 4, 0); + TEST_STRTOLL("15", 0, 15LL, 2, 0); + TEST_STRTOLL(" 15 ", 0, 15LL, 3, 0); + TEST_STRTOLL("+15", 10, 15LL, 3, 0); + TEST_STRTOLL(" +15", 10, 15LL, 5, 0); + TEST_STRTOLL("+15", 0, 15LL, 3, 0); + TEST_STRTOLL(" +15 ", 0, 15LL, 4, 0); + TEST_STRTOLL("-15", 10, -15LL, 3, 0); + TEST_STRTOLL(" -15", 10, -15LL, 5, 0); + TEST_STRTOLL("-15", 0, -15LL, 3, 0); + TEST_STRTOLL(" -15 ", 0, -15LL, 4, 0); + TEST_STRTOLL("015", 10, 15LL, 3, 0); + TEST_STRTOLL(" 015", 10, 15LL, 5, 0); + TEST_STRTOLL("015", 0, 13LL, 3, 0); + TEST_STRTOLL(" 015", 0, 13LL, 5, 0); + TEST_STRTOLL("0x15", 10, 0LL, 1, 0); + TEST_STRTOLL(" 0x15", 10, 0LL, 3, 0); + TEST_STRTOLL("0x15", 0, 21LL, 4, 0); + TEST_STRTOLL(" 0x15", 0, 21LL, 6, 0); + + TEST_STRTOLL("10", 16, 16LL, 2, 0); + TEST_STRTOLL(" 10 ", 16, 16LL, 4, 0); + TEST_STRTOLL("0x10", 16, 16LL, 4, 0); + TEST_STRTOLL("0x10", 0, 16LL, 4, 0); + TEST_STRTOLL(" 0x10 ", 0, 16LL, 5, 0); + TEST_STRTOLL("+10", 16, 16LL, 3, 0); + TEST_STRTOLL(" +10 ", 16, 16LL, 5, 0); + TEST_STRTOLL("+0x10", 16, 16LL, 5, 0); + TEST_STRTOLL("+0x10", 0, 16LL, 5, 0); + TEST_STRTOLL(" +0x10 ", 0, 16LL, 6, 0); + TEST_STRTOLL("-10", 16, -16LL, 3, 0); + TEST_STRTOLL(" -10 ", 16, -16LL, 5, 0); + TEST_STRTOLL("-0x10", 16, -16LL, 5, 0); + TEST_STRTOLL("-0x10", 0, -16LL, 5, 0); + TEST_STRTOLL(" -0x10 ", 0, -16LL, 6, 0); + TEST_STRTOLL("010", 16, 16LL, 3, 0); + TEST_STRTOLL(" 010 ", 16, 16LL, 5, 0); + TEST_STRTOLL("-010", 16, -16LL, 4, 0); + + TEST_STRTOLL("11", 8, 9LL, 2, 0); + TEST_STRTOLL("011", 8, 9LL, 3, 0); + TEST_STRTOLL("011", 0, 9LL, 3, 0); + TEST_STRTOLL("-11", 8, -9LL, 3, 0); + TEST_STRTOLL("-011", 8, -9LL, 4, 0); + TEST_STRTOLL("-011", 0, -9LL, 4, 0); + + TEST_STRTOLL("011", 8, 9LL, 3, 0); + TEST_STRTOLL("011", 0, 9LL, 3, 0); + TEST_STRTOLL("-11", 8, -9LL, 3, 0); + TEST_STRTOLL("-011", 8, -9LL, 4, 0); + TEST_STRTOLL("-011", 0, -9LL, 4, 0); + + TEST_STRTOLL("Text", 0, 0LL, 0, 0); + + TEST_STRTOLL("9223372036854775807", 10, 9223372036854775807LL, 19, 0); + TEST_STRTOLL("9223372036854775807", 0, 9223372036854775807LL, 19, 0); + TEST_STRTOLL("9223372036854775808", 0, 9223372036854775807LL, 19, ERANGE); + TEST_STRTOLL("9223372036854775808", 10, 9223372036854775807LL, 19, ERANGE); + TEST_STRTOLL("0x7FFFFFFFFFFFFFFF", 0, 9223372036854775807LL, 18, 0); + TEST_STRTOLL("0x7FFFFFFFFFFFFFFF", 16, 9223372036854775807LL, 18, 0); + TEST_STRTOLL("7FFFFFFFFFFFFFFF", 16, 9223372036854775807LL, 16, 0); + TEST_STRTOLL("0x8000000000000000", 0, 9223372036854775807LL, 18, ERANGE); + TEST_STRTOLL("0x8000000000000000", 16, 9223372036854775807LL, 18, ERANGE); + TEST_STRTOLL("80000000000000000", 16, 9223372036854775807LL, 17, ERANGE); + TEST_STRTOLL("0777777777777777777777", 0, 9223372036854775807LL, 22, 0); + TEST_STRTOLL("0777777777777777777777", 8, 9223372036854775807LL, 22, 0); + TEST_STRTOLL("777777777777777777777", 8, 9223372036854775807LL, 21, 0); + TEST_STRTOLL("01000000000000000000000", 0, 9223372036854775807LL, 23, ERANGE); + TEST_STRTOLL("01000000000000000000000", 8, 9223372036854775807LL, 23, ERANGE); + TEST_STRTOLL("1000000000000000000000", 8, 9223372036854775807LL, 22, ERANGE); + + TEST_STRTOLL("-9223372036854775808", 10, -9223372036854775807LL -1, 20, 0); + TEST_STRTOLL("-9223372036854775808", 0, -9223372036854775807LL -1, 20, 0); + TEST_STRTOLL("-9223372036854775809", 0, -9223372036854775807LL -1, 20, ERANGE); + TEST_STRTOLL("-9223372036854775809", 10, -9223372036854775807LL -1, 20, ERANGE); + TEST_STRTOLL("-0x8000000000000000", 0, -9223372036854775807LL -1, 19, 0); + TEST_STRTOLL("-0x8000000000000000", 16, -9223372036854775807LL -1, 19, 0); + TEST_STRTOLL("-8000000000000000", 16, -9223372036854775807LL -1, 17, 0); + TEST_STRTOLL("-0x8000000000000001", 0, -9223372036854775807LL -1, 19, ERANGE); + TEST_STRTOLL("-0x8000000000000001", 16, -9223372036854775807LL -1, 19, ERANGE); + TEST_STRTOLL("-80000000000000001", 16, -9223372036854775807LL -1, 18, ERANGE); + TEST_STRTOLL("-01000000000000000000000",0, -9223372036854775807LL -1, 24, 0); + TEST_STRTOLL("-01000000000000000000000",8, -9223372036854775807LL -1, 24, 0); + TEST_STRTOLL("-1000000000000000000000", 8, -9223372036854775807LL -1, 23, 0); + TEST_STRTOLL("-01000000000000000000001",0, -9223372036854775807LL -1, 24, ERANGE); + TEST_STRTOLL("-01000000000000000000001",8, -9223372036854775807LL -1, 24, ERANGE); + TEST_STRTOLL("-1000000000000000000001", 8, -9223372036854775807LL -1, 23, ERANGE); + + printf("success: strtoll\n"); + return true; +} + +static int test_strtoull(void) +{ + printf("test: strtoull\n"); + +#define TEST_STRTOULL(str,base,res,diff,errnoo) TEST_STRTO_X(long long unsigned int,"%llu",strtoull,str,base,res,diff,errnoo) + + TEST_STRTOULL("15", 10, 15LLU, 2, 0); + TEST_STRTOULL(" 15", 10, 15LLU, 4, 0); + TEST_STRTOULL("15", 0, 15LLU, 2, 0); + TEST_STRTOULL(" 15 ", 0, 15LLU, 3, 0); + TEST_STRTOULL("+15", 10, 15LLU, 3, 0); + TEST_STRTOULL(" +15", 10, 15LLU, 5, 0); + TEST_STRTOULL("+15", 0, 15LLU, 3, 0); + TEST_STRTOULL(" +15 ", 0, 15LLU, 4, 0); + TEST_STRTOULL("-15", 10, 18446744073709551601LLU, 3, 0); + TEST_STRTOULL(" -15", 10, 18446744073709551601LLU, 5, 0); + TEST_STRTOULL("-15", 0, 18446744073709551601LLU, 3, 0); + TEST_STRTOULL(" -15 ", 0, 18446744073709551601LLU, 4, 0); + TEST_STRTOULL("015", 10, 15LLU, 3, 0); + TEST_STRTOULL(" 015", 10, 15LLU, 5, 0); + TEST_STRTOULL("015", 0, 13LLU, 3, 0); + TEST_STRTOULL(" 015", 0, 13LLU, 5, 0); + TEST_STRTOULL("0x15", 10, 0LLU, 1, 0); + TEST_STRTOULL(" 0x15", 10, 0LLU, 3, 0); + TEST_STRTOULL("0x15", 0, 21LLU, 4, 0); + TEST_STRTOULL(" 0x15", 0, 21LLU, 6, 0); + + TEST_STRTOULL("10", 16, 16LLU, 2, 0); + TEST_STRTOULL(" 10 ", 16, 16LLU, 4, 0); + TEST_STRTOULL("0x10", 16, 16LLU, 4, 0); + TEST_STRTOULL("0x10", 0, 16LLU, 4, 0); + TEST_STRTOULL(" 0x10 ", 0, 16LLU, 5, 0); + TEST_STRTOULL("+10", 16, 16LLU, 3, 0); + TEST_STRTOULL(" +10 ", 16, 16LLU, 5, 0); + TEST_STRTOULL("+0x10", 16, 16LLU, 5, 0); + TEST_STRTOULL("+0x10", 0, 16LLU, 5, 0); + TEST_STRTOULL(" +0x10 ", 0, 16LLU, 6, 0); + TEST_STRTOULL("-10", 16, -16LLU, 3, 0); + TEST_STRTOULL(" -10 ", 16, -16LLU, 5, 0); + TEST_STRTOULL("-0x10", 16, -16LLU, 5, 0); + TEST_STRTOULL("-0x10", 0, -16LLU, 5, 0); + TEST_STRTOULL(" -0x10 ", 0, -16LLU, 6, 0); + TEST_STRTOULL("010", 16, 16LLU, 3, 0); + TEST_STRTOULL(" 010 ", 16, 16LLU, 5, 0); + TEST_STRTOULL("-010", 16, -16LLU, 4, 0); + + TEST_STRTOULL("11", 8, 9LLU, 2, 0); + TEST_STRTOULL("011", 8, 9LLU, 3, 0); + TEST_STRTOULL("011", 0, 9LLU, 3, 0); + TEST_STRTOULL("-11", 8, -9LLU, 3, 0); + TEST_STRTOULL("-011", 8, -9LLU, 4, 0); + TEST_STRTOULL("-011", 0, -9LLU, 4, 0); + + TEST_STRTOULL("011", 8, 9LLU, 3, 0); + TEST_STRTOULL("011", 0, 9LLU, 3, 0); + TEST_STRTOULL("-11", 8, -9LLU, 3, 0); + TEST_STRTOULL("-011", 8, -9LLU, 4, 0); + TEST_STRTOULL("-011", 0, -9LLU, 4, 0); + + TEST_STRTOULL("Text", 0, 0LLU, 0, 0); + + TEST_STRTOULL("9223372036854775807", 10, 9223372036854775807LLU, 19, 0); + TEST_STRTOULL("9223372036854775807", 0, 9223372036854775807LLU, 19, 0); + TEST_STRTOULL("9223372036854775808", 0, 9223372036854775808LLU, 19, 0); + TEST_STRTOULL("9223372036854775808", 10, 9223372036854775808LLU, 19, 0); + TEST_STRTOULL("0x7FFFFFFFFFFFFFFF", 0, 9223372036854775807LLU, 18, 0); + TEST_STRTOULL("0x7FFFFFFFFFFFFFFF", 16, 9223372036854775807LLU, 18, 0); + TEST_STRTOULL("7FFFFFFFFFFFFFFF", 16, 9223372036854775807LLU, 16, 0); + TEST_STRTOULL("0x8000000000000000", 0, 9223372036854775808LLU, 18, 0); + TEST_STRTOULL("0x8000000000000000", 16, 9223372036854775808LLU, 18, 0); + TEST_STRTOULL("8000000000000000", 16, 9223372036854775808LLU, 16, 0); + TEST_STRTOULL("0777777777777777777777", 0, 9223372036854775807LLU, 22, 0); + TEST_STRTOULL("0777777777777777777777", 8, 9223372036854775807LLU, 22, 0); + TEST_STRTOULL("777777777777777777777", 8, 9223372036854775807LLU, 21, 0); + TEST_STRTOULL("01000000000000000000000",0, 9223372036854775808LLU, 23, 0); + TEST_STRTOULL("01000000000000000000000",8, 9223372036854775808LLU, 23, 0); + TEST_STRTOULL("1000000000000000000000", 8, 9223372036854775808LLU, 22, 0); + + TEST_STRTOULL("-9223372036854775808", 10, 9223372036854775808LLU, 20, 0); + TEST_STRTOULL("-9223372036854775808", 0, 9223372036854775808LLU, 20, 0); + TEST_STRTOULL("-9223372036854775809", 0, 9223372036854775807LLU, 20, 0); + TEST_STRTOULL("-9223372036854775809", 10, 9223372036854775807LLU, 20, 0); + TEST_STRTOULL("-0x8000000000000000", 0, 9223372036854775808LLU, 19, 0); + TEST_STRTOULL("-0x8000000000000000", 16, 9223372036854775808LLU, 19, 0); + TEST_STRTOULL("-8000000000000000", 16, 9223372036854775808LLU, 17, 0); + TEST_STRTOULL("-0x8000000000000001", 0, 9223372036854775807LLU, 19, 0); + TEST_STRTOULL("-0x8000000000000001", 16, 9223372036854775807LLU, 19, 0); + TEST_STRTOULL("-8000000000000001", 16, 9223372036854775807LLU, 17, 0); + TEST_STRTOULL("-01000000000000000000000",0, 9223372036854775808LLU, 24, 0); + TEST_STRTOULL("-01000000000000000000000",8, 9223372036854775808LLU, 24, 0); + TEST_STRTOULL("-1000000000000000000000",8, 9223372036854775808LLU, 23, 0); + TEST_STRTOULL("-01000000000000000000001",0, 9223372036854775807LLU, 24, 0); + TEST_STRTOULL("-01000000000000000000001",8, 9223372036854775807LLU, 24, 0); + TEST_STRTOULL("-1000000000000000000001",8, 9223372036854775807LLU, 23, 0); + + TEST_STRTOULL("18446744073709551615", 0, 18446744073709551615LLU, 20, 0); + TEST_STRTOULL("18446744073709551615", 10, 18446744073709551615LLU, 20, 0); + TEST_STRTOULL("18446744073709551616", 0, 18446744073709551615LLU, 20, ERANGE); + TEST_STRTOULL("18446744073709551616", 10, 18446744073709551615LLU, 20, ERANGE); + TEST_STRTOULL("0xFFFFFFFFFFFFFFFF", 0, 18446744073709551615LLU, 18, 0); + TEST_STRTOULL("0xFFFFFFFFFFFFFFFF", 16, 18446744073709551615LLU, 18, 0); + TEST_STRTOULL("FFFFFFFFFFFFFFFF", 16, 18446744073709551615LLU, 16, 0); + TEST_STRTOULL("0x10000000000000000", 0, 18446744073709551615LLU, 19, ERANGE); + TEST_STRTOULL("0x10000000000000000", 16, 18446744073709551615LLU, 19, ERANGE); + TEST_STRTOULL("10000000000000000", 16, 18446744073709551615LLU, 17, ERANGE); + TEST_STRTOULL("01777777777777777777777",0, 18446744073709551615LLU, 23, 0); + TEST_STRTOULL("01777777777777777777777",8, 18446744073709551615LLU, 23, 0); + TEST_STRTOULL("1777777777777777777777", 8, 18446744073709551615LLU, 22, 0); + TEST_STRTOULL("02000000000000000000000",0, 18446744073709551615LLU, 23, ERANGE); + TEST_STRTOULL("02000000000000000000000",8, 18446744073709551615LLU, 23, ERANGE); + TEST_STRTOULL("2000000000000000000000", 8, 18446744073709551615LLU, 22, ERANGE); + + TEST_STRTOULL("-18446744073709551615", 0, 1LLU, 21, 0); + TEST_STRTOULL("-18446744073709551615", 10, 1LLU, 21, 0); + TEST_STRTOULL("-18446744073709551616", 0, 18446744073709551615LLU, 21, ERANGE); + TEST_STRTOULL("-18446744073709551616", 10, 18446744073709551615LLU, 21, ERANGE); + TEST_STRTOULL("-0xFFFFFFFFFFFFFFFF", 0, 1LLU, 19, 0); + TEST_STRTOULL("-0xFFFFFFFFFFFFFFFF", 16, 1LLU, 19, 0); + TEST_STRTOULL("-FFFFFFFFFFFFFFFF", 16, 1LLU, 17, 0); + TEST_STRTOULL("-0x10000000000000000", 0, 18446744073709551615LLU, 20, ERANGE); + TEST_STRTOULL("-0x10000000000000000", 16, 18446744073709551615LLU, 20, ERANGE); + TEST_STRTOULL("-10000000000000000", 16, 18446744073709551615LLU, 18, ERANGE); + TEST_STRTOULL("-01777777777777777777777",0, 1LLU, 24, 0); + TEST_STRTOULL("-01777777777777777777777",8, 1LLU, 24, 0); + TEST_STRTOULL("-1777777777777777777777",8, 1LLU, 23, 0); + TEST_STRTOULL("-02000000000000000000000",0, 18446744073709551615LLU, 24, ERANGE); + TEST_STRTOULL("-02000000000000000000000",8, 18446744073709551615LLU, 24, ERANGE); + TEST_STRTOULL("-2000000000000000000000",8, 18446744073709551615LLU, 23, ERANGE); + + printf("success: strtoull\n"); + return true; +} + +/* +FIXME: +Types: +bool +socklen_t +uint{8,16,32,64}_t +int{8,16,32,64}_t +intptr_t + +Constants: +PATH_NAME_MAX +UINT{16,32,64}_MAX +INT32_MAX +*/ + +static int test_va_copy(void) +{ + /* FIXME */ + return true; +} + +static int test_FUNCTION(void) +{ + printf("test: FUNCTION\n"); + if (strcmp(__FUNCTION__, "test_FUNCTION") != 0) { + printf("failure: FUNCTION [\nFUNCTION invalid\n]\n"); + return false; + } + printf("success: FUNCTION\n"); + return true; +} + +static int test_MIN(void) +{ + printf("test: MIN\n"); + if (MIN(20, 1) != 1) { + printf("failure: MIN [\nMIN invalid\n]\n"); + return false; + } + if (MIN(1, 20) != 1) { + printf("failure: MIN [\nMIN invalid\n]\n"); + return false; + } + printf("success: MIN\n"); + return true; +} + +static int test_MAX(void) +{ + printf("test: MAX\n"); + if (MAX(20, 1) != 20) { + printf("failure: MAX [\nMAX invalid\n]\n"); + return false; + } + if (MAX(1, 20) != 20) { + printf("failure: MAX [\nMAX invalid\n]\n"); + return false; + } + printf("success: MAX\n"); + return true; +} + +static int test_socketpair(void) +{ + int sock[2]; + char buf[20]; + + printf("test: socketpair\n"); + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sock) == -1) { + printf("failure: socketpair [\n" + "socketpair() failed\n" + "]\n"); + return false; + } + + if (write(sock[1], "automatisch", 12) == -1) { + printf("failure: socketpair [\n" + "write() failed: %s\n" + "]\n", strerror(errno)); + return false; + } + + if (read(sock[0], buf, 12) == -1) { + printf("failure: socketpair [\n" + "read() failed: %s\n" + "]\n", strerror(errno)); + return false; + } + + if (strcmp(buf, "automatisch") != 0) { + printf("failure: socketpair [\n" + "expected: automatisch, got: %s\n" + "]\n", buf); + return false; + } + + printf("success: socketpair\n"); + + return true; +} + +extern int libreplace_test_strptime(void); + +static int test_strptime(void) +{ + return libreplace_test_strptime(); +} + +extern int getifaddrs_test(void); + +static int test_getifaddrs(void) +{ + + printf("test: getifaddrs\n"); + + if (getifaddrs_test() != 0) { + printf("failure: getifaddrs\n"); + return false; + } + + printf("success: getifaddrs\n"); + return true; +} + +static int test_utime(void) +{ + struct utimbuf u; + struct stat st1, st2, st3; + int fd; + + printf("test: utime\n"); + unlink(TESTFILE); + + fd = open(TESTFILE, O_RDWR|O_CREAT, 0600); + if (fd == -1) { + printf("failure: utime [\n" + "creating '%s' failed - %s\n]\n", + TESTFILE, strerror(errno)); + return false; + } + + if (fstat(fd, &st1) != 0) { + printf("failure: utime [\n" + "fstat (1) failed - %s\n]\n", + strerror(errno)); + close(fd); + return false; + } + + u.actime = st1.st_atime + 300; + u.modtime = st1.st_mtime - 300; + if (utime(TESTFILE, &u) != 0) { + printf("failure: utime [\n" + "utime(&u) failed - %s\n]\n", + strerror(errno)); + close(fd); + return false; + } + + if (fstat(fd, &st2) != 0) { + printf("failure: utime [\n" + "fstat (2) failed - %s\n]\n", + strerror(errno)); + close(fd); + return false; + } + + if (utime(TESTFILE, NULL) != 0) { + printf("failure: utime [\n" + "utime(NULL) failed - %s\n]\n", + strerror(errno)); + close(fd); + return false; + } + + if (fstat(fd, &st3) != 0) { + printf("failure: utime [\n" + "fstat (3) failed - %s\n]\n", + strerror(errno)); + close(fd); + return false; + } + +#define CMP_VAL(a,c,b) do { \ + if (a c b) { \ + printf("failure: utime [\n" \ + "%s: %s(%d) %s %s(%d)\n]\n", \ + __location__, \ + #a, (int)a, #c, #b, (int)b); \ + close(fd); \ + return false; \ + } \ +} while(0) +#define EQUAL_VAL(a,b) CMP_VAL(a,!=,b) +#define GREATER_VAL(a,b) CMP_VAL(a,<=,b) +#define LESSER_VAL(a,b) CMP_VAL(a,>=,b) + + EQUAL_VAL(st2.st_atime, st1.st_atime + 300); + EQUAL_VAL(st2.st_mtime, st1.st_mtime - 300); + LESSER_VAL(st3.st_atime, st2.st_atime); + GREATER_VAL(st3.st_mtime, st2.st_mtime); + +#undef CMP_VAL +#undef EQUAL_VAL +#undef GREATER_VAL +#undef LESSER_VAL + + unlink(TESTFILE); + printf("success: utime\n"); + close(fd); + return true; +} + +static int test_utimes(void) +{ + struct timeval tv[2]; + struct stat st1, st2; + int fd; + + printf("test: utimes\n"); + unlink(TESTFILE); + + fd = open(TESTFILE, O_RDWR|O_CREAT, 0600); + if (fd == -1) { + printf("failure: utimes [\n" + "creating '%s' failed - %s\n]\n", + TESTFILE, strerror(errno)); + return false; + } + + if (fstat(fd, &st1) != 0) { + printf("failure: utimes [\n" + "fstat (1) failed - %s\n]\n", + strerror(errno)); + close(fd); + return false; + } + + ZERO_STRUCT(tv); + tv[0].tv_sec = st1.st_atime + 300; + tv[1].tv_sec = st1.st_mtime - 300; + if (utimes(TESTFILE, tv) != 0) { + printf("failure: utimes [\n" + "utimes(tv) failed - %s\n]\n", + strerror(errno)); + close(fd); + return false; + } + + if (fstat(fd, &st2) != 0) { + printf("failure: utimes [\n" + "fstat (2) failed - %s\n]\n", + strerror(errno)); + close(fd); + return false; + } + +#define EQUAL_VAL(a,b) do { \ + if (a != b) { \ + printf("failure: utimes [\n" \ + "%s: %s(%d) != %s(%d)\n]\n", \ + __location__, \ + #a, (int)a, #b, (int)b); \ + close(fd); \ + return false; \ + } \ +} while(0) + + EQUAL_VAL(st2.st_atime, st1.st_atime + 300); + EQUAL_VAL(st2.st_mtime, st1.st_mtime - 300); + +#undef EQUAL_VAL + + unlink(TESTFILE); + printf("success: utimes\n"); + close(fd); + return true; +} + +static int test_memmem(void) +{ + char *s; + + printf("test: memmem\n"); + + s = (char *)memmem("foo", 3, "fo", 2); + if (strcmp(s, "foo") != 0) { + printf(__location__ ": Failed memmem\n"); + return false; + } + + s = (char *)memmem("foo", 3, "", 0); + /* it is allowable for this to return NULL (as happens on + FreeBSD) */ + if (s && strcmp(s, "foo") != 0) { + printf(__location__ ": Failed memmem\n"); + return false; + } + + s = (char *)memmem("foo", 4, "o", 1); + if (strcmp(s, "oo") != 0) { + printf(__location__ ": Failed memmem\n"); + return false; + } + + s = (char *)memmem("foobarfodx", 11, "fod", 3); + if (strcmp(s, "fodx") != 0) { + printf(__location__ ": Failed memmem\n"); + return false; + } + + printf("success: memmem\n"); + + return true; +} + +static bool test_closefrom(void) +{ + int i, fd; + + for (i=0; i<100; i++) { + fd = dup(0); + if (fd == -1) { + perror("dup failed"); + return false; + } + + /* 1000 is just an arbitrarily chosen upper bound */ + + if (fd >= 1000) { + printf("fd=%d\n", fd); + return false; + } + } + + closefrom(3); + + for (i=3; i<=fd; i++) { + off_t off; + off = lseek(i, 0, SEEK_CUR); + if ((off != (off_t)-1) || (errno != EBADF)) { + printf("fd %d not closed\n", i); + return false; + } + } + + return true; +} + +bool torture_local_replace(struct torture_context *ctx) +{ + bool ret = true; + ret &= test_ftruncate(); + ret &= test_strlcpy(); + ret &= test_strlcat(); + ret &= test_mktime(); + ret &= test_initgroups(); + ret &= test_memmove(); + ret &= test_strdup(); + ret &= test_setlinebuf(); + ret &= test_vsyslog(); + ret &= test_timegm(); + ret &= test_setenv(); + ret &= test_strndup(); + ret &= test_strnlen(); + ret &= test_waitpid(); + ret &= test_seteuid(); + ret &= test_setegid(); + ret &= test_asprintf(); + ret &= test_snprintf(); + ret &= test_vasprintf(); + ret &= test_vsnprintf(); + ret &= test_opendir(); + ret &= test_readdir(); + ret &= test_telldir(); + ret &= test_seekdir(); + ret &= test_dlopen(); + ret &= test_chroot(); + ret &= test_bzero(); + ret &= test_strerror(); + ret &= test_errno(); + ret &= test_mkdtemp(); + ret &= test_mkstemp(); + ret &= test_pread(); + ret &= test_pwrite(); + ret &= test_inet_ntoa(); + ret &= test_strtoll(); + ret &= test_strtoull(); + ret &= test_va_copy(); + ret &= test_FUNCTION(); + ret &= test_MIN(); + ret &= test_MAX(); + ret &= test_socketpair(); + ret &= test_strptime(); + ret &= test_getifaddrs(); + ret &= test_utime(); + ret &= test_utimes(); + ret &= test_memmem(); + ret &= test_closefrom(); + + return ret; +} diff --git a/ldb-2.0.8/lib/replace/timegm.c b/ldb-2.0.8/lib/replace/timegm.c new file mode 100644 index 0000000..395c684 --- /dev/null +++ b/ldb-2.0.8/lib/replace/timegm.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 1997 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + adapted for Samba4 by Andrew Tridgell +*/ + +#include "replace.h" +#include "system/time.h" + +static int is_leap(unsigned y) +{ + y += 1900; + return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0); +} + +time_t rep_timegm(struct tm *tm) +{ + static const unsigned ndays[2][12] ={ + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; + time_t res = 0; + unsigned i; + + if (tm->tm_mon > 12 || + tm->tm_mon < 0 || + tm->tm_mday > 31 || + tm->tm_min > 60 || + tm->tm_sec > 60 || + tm->tm_hour > 24) { + /* invalid tm structure */ + return 0; + } + + for (i = 70; i < tm->tm_year; ++i) + res += is_leap(i) ? 366 : 365; + + for (i = 0; i < tm->tm_mon; ++i) + res += ndays[is_leap(tm->tm_year)][i]; + res += tm->tm_mday - 1; + res *= 24; + res += tm->tm_hour; + res *= 60; + res += tm->tm_min; + res *= 60; + res += tm->tm_sec; + return res; +} diff --git a/ldb-2.0.8/lib/replace/win32_replace.h b/ldb-2.0.8/lib/replace/win32_replace.h new file mode 100644 index 0000000..9901e72 --- /dev/null +++ b/ldb-2.0.8/lib/replace/win32_replace.h @@ -0,0 +1,159 @@ +#ifndef _WIN32_REPLACE_H +#define _WIN32_REPLACE_H + +#ifdef HAVE_WINSOCK2_H +#include +#endif + +#ifdef HAVE_WS2TCPIP_H +#include +#endif + +#ifdef HAVE_WINDOWS_H +#include +#endif + +/* Map BSD Socket errorcodes to the WSA errorcodes (if possible) */ + +#define EAFNOSUPPORT WSAEAFNOSUPPORT +#define ECONNREFUSED WSAECONNREFUSED +#define EINPROGRESS WSAEINPROGRESS +#define EMSGSIZE WSAEMSGSIZE +#define ENOBUFS WSAENOBUFS +#define ENOTSOCK WSAENOTSOCK +#define ENETUNREACH WSAENETUNREACH +#define ENOPROTOOPT WSAENOPROTOOPT +#define ENOTCONN WSAENOTCONN +#define ENOTSUP 134 + +/* We undefine the following constants due to conflicts with the w32api headers + * and the Windows Platform SDK/DDK. + */ + +#undef interface + +#undef ERROR_INVALID_PARAMETER +#undef ERROR_INSUFFICIENT_BUFFER +#undef ERROR_INVALID_DATATYPE + +#undef FILE_GENERIC_READ +#undef FILE_GENERIC_WRITE +#undef FILE_GENERIC_EXECUTE +#undef FILE_ATTRIBUTE_READONLY +#undef FILE_ATTRIBUTE_HIDDEN +#undef FILE_ATTRIBUTE_SYSTEM +#undef FILE_ATTRIBUTE_DIRECTORY +#undef FILE_ATTRIBUTE_ARCHIVE +#undef FILE_ATTRIBUTE_DEVICE +#undef FILE_ATTRIBUTE_NORMAL +#undef FILE_ATTRIBUTE_TEMPORARY +#undef FILE_ATTRIBUTE_REPARSE_POINT +#undef FILE_ATTRIBUTE_COMPRESSED +#undef FILE_ATTRIBUTE_OFFLINE +#undef FILE_ATTRIBUTE_ENCRYPTED +#undef FILE_FLAG_WRITE_THROUGH +#undef FILE_FLAG_NO_BUFFERING +#undef FILE_FLAG_RANDOM_ACCESS +#undef FILE_FLAG_SEQUENTIAL_SCAN +#undef FILE_FLAG_DELETE_ON_CLOSE +#undef FILE_FLAG_BACKUP_SEMANTICS +#undef FILE_FLAG_POSIX_SEMANTICS +#undef FILE_TYPE_DISK +#undef FILE_TYPE_UNKNOWN +#undef FILE_CASE_SENSITIVE_SEARCH +#undef FILE_CASE_PRESERVED_NAMES +#undef FILE_UNICODE_ON_DISK +#undef FILE_PERSISTENT_ACLS +#undef FILE_FILE_COMPRESSION +#undef FILE_VOLUME_QUOTAS +#undef FILE_VOLUME_IS_COMPRESSED +#undef FILE_NOTIFY_CHANGE_FILE_NAME +#undef FILE_NOTIFY_CHANGE_DIR_NAME +#undef FILE_NOTIFY_CHANGE_ATTRIBUTES +#undef FILE_NOTIFY_CHANGE_SIZE +#undef FILE_NOTIFY_CHANGE_LAST_WRITE +#undef FILE_NOTIFY_CHANGE_LAST_ACCESS +#undef FILE_NOTIFY_CHANGE_CREATION +#undef FILE_NOTIFY_CHANGE_EA +#undef FILE_NOTIFY_CHANGE_SECURITY +#undef FILE_NOTIFY_CHANGE_STREAM_NAME +#undef FILE_NOTIFY_CHANGE_STREAM_SIZE +#undef FILE_NOTIFY_CHANGE_STREAM_WRITE +#undef FILE_NOTIFY_CHANGE_NAME + +#undef PRINTER_ATTRIBUTE_QUEUED +#undef PRINTER_ATTRIBUTE_DIRECT +#undef PRINTER_ATTRIBUTE_DEFAULT +#undef PRINTER_ATTRIBUTE_SHARED +#undef PRINTER_ATTRIBUTE_NETWORK +#undef PRINTER_ATTRIBUTE_HIDDEN +#undef PRINTER_ATTRIBUTE_LOCAL +#undef PRINTER_ATTRIBUTE_ENABLE_DEVQ +#undef PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS +#undef PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST +#undef PRINTER_ATTRIBUTE_WORK_OFFLINE +#undef PRINTER_ATTRIBUTE_ENABLE_BIDI +#undef PRINTER_ATTRIBUTE_RAW_ONLY +#undef PRINTER_ATTRIBUTE_PUBLISHED +#undef PRINTER_ENUM_DEFAULT +#undef PRINTER_ENUM_LOCAL +#undef PRINTER_ENUM_CONNECTIONS +#undef PRINTER_ENUM_FAVORITE +#undef PRINTER_ENUM_NAME +#undef PRINTER_ENUM_REMOTE +#undef PRINTER_ENUM_SHARED +#undef PRINTER_ENUM_NETWORK +#undef PRINTER_ENUM_EXPAND +#undef PRINTER_ENUM_CONTAINER +#undef PRINTER_ENUM_ICON1 +#undef PRINTER_ENUM_ICON2 +#undef PRINTER_ENUM_ICON3 +#undef PRINTER_ENUM_ICON4 +#undef PRINTER_ENUM_ICON5 +#undef PRINTER_ENUM_ICON6 +#undef PRINTER_ENUM_ICON7 +#undef PRINTER_ENUM_ICON8 +#undef PRINTER_STATUS_PAUSED +#undef PRINTER_STATUS_ERROR +#undef PRINTER_STATUS_PENDING_DELETION +#undef PRINTER_STATUS_PAPER_JAM +#undef PRINTER_STATUS_PAPER_OUT +#undef PRINTER_STATUS_MANUAL_FEED +#undef PRINTER_STATUS_PAPER_PROBLEM +#undef PRINTER_STATUS_OFFLINE +#undef PRINTER_STATUS_IO_ACTIVE +#undef PRINTER_STATUS_BUSY +#undef PRINTER_STATUS_PRINTING +#undef PRINTER_STATUS_OUTPUT_BIN_FULL +#undef PRINTER_STATUS_NOT_AVAILABLE +#undef PRINTER_STATUS_WAITING +#undef PRINTER_STATUS_PROCESSING +#undef PRINTER_STATUS_INITIALIZING +#undef PRINTER_STATUS_WARMING_UP +#undef PRINTER_STATUS_TONER_LOW +#undef PRINTER_STATUS_NO_TONER +#undef PRINTER_STATUS_PAGE_PUNT +#undef PRINTER_STATUS_USER_INTERVENTION +#undef PRINTER_STATUS_OUT_OF_MEMORY +#undef PRINTER_STATUS_DOOR_OPEN +#undef PRINTER_STATUS_SERVER_UNKNOWN +#undef PRINTER_STATUS_POWER_SAVE + +#undef DWORD +#undef HKEY_CLASSES_ROOT +#undef HKEY_CURRENT_USER +#undef HKEY_LOCAL_MACHINE +#undef HKEY_USERS +#undef HKEY_PERFORMANCE_DATA +#undef HKEY_CURRENT_CONFIG +#undef HKEY_DYN_DATA +#undef REG_DWORD +#undef REG_QWORD + +#undef SERVICE_STATE_ALL + +#undef SE_GROUP_MANDATORY +#undef SE_GROUP_ENABLED_BY_DEFAULT +#undef SE_GROUP_ENABLED + +#endif /* _WIN32_REPLACE_H */ diff --git a/ldb-2.0.8/lib/replace/wscript b/ldb-2.0.8/lib/replace/wscript new file mode 100644 index 0000000..56e2a22 --- /dev/null +++ b/ldb-2.0.8/lib/replace/wscript @@ -0,0 +1,955 @@ +#!/usr/bin/env python + +APPNAME = 'libreplace' +VERSION = '1.2.1' + +import sys +import os + +# find the buildtools directory +top = '.' +while not os.path.exists(top+'/buildtools') and len(top.split('/')) < 5: + top = top + '/..' +sys.path.insert(0, top + '/buildtools/wafsamba') + +out = 'bin' + +import wafsamba +from wafsamba import samba_dist +from waflib import Options, Utils, Logs, Context + +samba_dist.DIST_DIRS('lib/replace buildtools:buildtools third_party/waf:third_party/waf') + +def options(opt): + opt.BUILTIN_DEFAULT('NONE') + opt.PRIVATE_EXTENSION_DEFAULT('') + opt.RECURSE('buildtools/wafsamba') + +@Utils.run_once +def configure(conf): + conf.RECURSE('buildtools/wafsamba') + + conf.env.standalone_replace = conf.IN_LAUNCH_DIR() + + conf.DEFINE('HAVE_LIBREPLACE', 1) + conf.DEFINE('LIBREPLACE_NETWORK_CHECKS', 1) + + conf.CHECK_HEADERS('linux/types.h crypt.h locale.h acl/libacl.h compat.h') + conf.CHECK_HEADERS('acl/libacl.h attr/xattr.h compat.h ctype.h dustat.h') + conf.CHECK_HEADERS('fcntl.h fnmatch.h glob.h history.h krb5.h langinfo.h') + conf.CHECK_HEADERS('libaio.h locale.h ndir.h pwd.h') + conf.CHECK_HEADERS('shadow.h sys/acl.h') + conf.CHECK_HEADERS('sys/attributes.h attr/attributes.h sys/capability.h sys/dir.h sys/epoll.h') + conf.CHECK_HEADERS('port.h') + conf.CHECK_HEADERS('sys/fcntl.h sys/filio.h sys/filsys.h sys/fs/s5param.h') + conf.CHECK_HEADERS('sys/id.h sys/ioctl.h sys/ipc.h sys/mman.h sys/mode.h sys/ndir.h sys/priv.h') + conf.CHECK_HEADERS('sys/resource.h sys/security.h sys/shm.h sys/statfs.h sys/statvfs.h sys/termio.h') + conf.CHECK_HEADERS('sys/vfs.h sys/xattr.h termio.h termios.h sys/file.h') + conf.CHECK_HEADERS('sys/ucontext.h sys/wait.h sys/stat.h') + + if not conf.CHECK_DECLS('malloc', headers='stdlib.h'): + conf.CHECK_HEADERS('malloc.h') + + conf.CHECK_HEADERS('grp.h') + conf.CHECK_HEADERS('sys/select.h setjmp.h utime.h sys/syslog.h syslog.h') + conf.CHECK_HEADERS('stdarg.h vararg.h sys/mount.h mntent.h') + conf.CHECK_HEADERS('stropts.h unix.h string.h strings.h sys/param.h limits.h') + conf.CHECK_HEADERS('''sys/socket.h netinet/in.h netdb.h arpa/inet.h netinet/in_systm.h + netinet/ip.h netinet/tcp.h netinet/in_ip.h + sys/sockio.h sys/un.h''', together=True) + conf.CHECK_HEADERS('sys/uio.h ifaddrs.h direct.h dirent.h') + conf.CHECK_HEADERS('windows.h winsock2.h ws2tcpip.h') + conf.CHECK_HEADERS('errno.h') + conf.CHECK_HEADERS('getopt.h iconv.h') + conf.CHECK_HEADERS('memory.h nss.h sasl/sasl.h') + + conf.CHECK_FUNCS_IN('inotify_init', 'inotify', checklibc=True, + headers='sys/inotify.h') + + conf.CHECK_HEADERS('security/pam_appl.h zlib.h asm/unistd.h') + conf.CHECK_HEADERS('aio.h sys/unistd.h alloca.h float.h') + + conf.SET_TARGET_TYPE('tirpc', 'EMPTY') + + if conf.CHECK_CODE( + '\n#ifndef _TIRPC_RPC_H\n#error "no tirpc headers in system path"\n#endif\n', + 'HAVE_RPC_RPC_HEADERS', + headers=['rpc/rpc.h', 'rpc/nettype.h'], + msg='Checking for tirpc rpc headers in default system path'): + if conf.CONFIG_SET('HAVE_RPC_RPC_H'): + conf.undefine('HAVE_RPC_RPC_H') + + if not conf.CONFIG_SET('HAVE_RPC_RPC_H'): + if conf.CHECK_CFG(package='libtirpc', args='--cflags --libs', + msg='Checking for libtirpc headers', + uselib_store='TIRPC'): + conf.CHECK_HEADERS('rpc/rpc.h rpc/nettype.h', lib='tirpc', together=True) + conf.SET_TARGET_TYPE('tirpc', 'SYSLIB') + if not conf.CONFIG_SET('HAVE_RPC_RPC_H'): + if conf.CHECK_CFG(package='libntirpc', args='--cflags', + msg='Checking for libntirpc headers', + uselib_store='TIRPC'): + conf.CHECK_HEADERS('rpc/rpc.h rpc/nettype.h', lib='tirpc', together=True) + conf.SET_TARGET_TYPE('tirpc', 'SYSLIB') + if not conf.CONFIG_SET('HAVE_RPC_RPC_H'): + Logs.warn('No rpc/rpc.h header found, tirpc or libntirpc missing?') + + conf.SET_TARGET_TYPE('nsl', 'EMPTY') + conf.CHECK_HEADERS('rpc/rpc.h rpcsvc/yp_prot.h', lib='tirpc') + if not conf.CONFIG_SET('HAVE_RPCSVC_YP_PROT_H'): + if conf.CHECK_CFG(package='libnsl', args='--cflags --libs', + msg='Checking for libnsl', + uselib_store='NSL'): + conf.SET_TARGET_TYPE('nsl', 'SYSLIB') + conf.CHECK_HEADERS('rpc/rpc.h rpcsvc/yp_prot.h', lib='tirpc nsl') + else: + conf.SET_TARGET_TYPE('nsl', 'SYSLIB') + conf.CHECK_HEADERS('rpcsvc/nis.h rpcsvc/ypclnt.h', lib='tirpc nsl') + + conf.CHECK_HEADERS('sys/sysctl.h') + conf.CHECK_HEADERS('sys/fileio.h sys/filesys.h sys/dustat.h sys/sysmacros.h') + conf.CHECK_HEADERS('xfs/libxfs.h netgroup.h') + + conf.CHECK_HEADERS('valgrind.h valgrind/valgrind.h') + conf.CHECK_HEADERS('valgrind/memcheck.h valgrind/helgrind.h') + conf.CHECK_HEADERS('nss_common.h nsswitch.h ns_api.h') + conf.CHECK_HEADERS('sys/extattr.h sys/ea.h sys/proplist.h sys/cdefs.h') + conf.CHECK_HEADERS('utmp.h utmpx.h lastlog.h') + conf.CHECK_HEADERS('syscall.h sys/syscall.h inttypes.h') + conf.CHECK_HEADERS('sys/atomic.h stdatomic.h') + conf.CHECK_HEADERS('libgen.h') + + if conf.CHECK_CFLAGS('-Wno-format-truncation'): + conf.define('HAVE_WNO_FORMAT_TRUNCATION', '1') + + if conf.CHECK_CFLAGS('-Wno-unused-function'): + conf.define('HAVE_WNO_UNUSED_FUNCTION', '1') + + if conf.CHECK_CFLAGS('-Wno-strict-overflow'): + conf.define('HAVE_WNO_STRICT_OVERFLOW', '1') + + # Check for process set name support + conf.CHECK_CODE(''' + #include + int main(void) { + prctl(0); + return 0; + } + ''', + 'HAVE_PRCTL', + headers='sys/prctl.h', + msg='Checking for prctl syscall') + + conf.CHECK_CODE(''' + #include + #ifdef HAVE_FCNTL_H + #include + #endif + int main(void) { int fd = open("/dev/null", O_DIRECT); } + ''', + define='HAVE_OPEN_O_DIRECT', + addmain=False, + msg='Checking for O_DIRECT flag to open(2)') + + conf.CHECK_TYPES('"long long" intptr_t uintptr_t ptrdiff_t comparison_fn_t') + conf.CHECK_TYPE('_Bool', define='HAVE__Bool') + conf.CHECK_TYPE('bool', define='HAVE_BOOL') + + conf.CHECK_TYPE('int8_t', 'char') + conf.CHECK_TYPE('uint8_t', 'unsigned char') + conf.CHECK_TYPE('int16_t', 'short') + conf.CHECK_TYPE('uint16_t', 'unsigned short') + conf.CHECK_TYPE('int32_t', 'int') + conf.CHECK_TYPE('uint32_t', 'unsigned') + conf.CHECK_TYPE('int64_t', 'long long') + conf.CHECK_TYPE('uint64_t', 'unsigned long long') + conf.CHECK_TYPE('size_t', 'unsigned int') + conf.CHECK_TYPE('ssize_t', 'int') + conf.CHECK_TYPE('ino_t', 'unsigned') + conf.CHECK_TYPE('loff_t', 'off_t') + conf.CHECK_TYPE('offset_t', 'loff_t') + conf.CHECK_TYPE('volatile int', define='HAVE_VOLATILE') + conf.CHECK_TYPE('uint_t', 'unsigned int') + conf.CHECK_TYPE('blksize_t', 'long', headers='sys/types.h sys/stat.h unistd.h') + conf.CHECK_TYPE('blkcnt_t', 'long', headers='sys/types.h sys/stat.h unistd.h') + + conf.CHECK_SIZEOF('bool char int "long long" long short size_t ssize_t') + conf.CHECK_SIZEOF('int8_t uint8_t int16_t uint16_t int32_t uint32_t int64_t uint64_t') + conf.CHECK_SIZEOF('void*', define='SIZEOF_VOID_P') + conf.CHECK_SIZEOF('off_t dev_t ino_t time_t') + + conf.CHECK_TYPES('socklen_t', headers='sys/socket.h') + conf.CHECK_TYPE_IN('struct ifaddrs', 'ifaddrs.h') + conf.CHECK_TYPE_IN('struct addrinfo', 'netdb.h') + conf.CHECK_TYPE_IN('struct sockaddr', 'sys/socket.h') + conf.CHECK_CODE('struct sockaddr_in6 x', define='HAVE_STRUCT_SOCKADDR_IN6', + headers='sys/socket.h netdb.h netinet/in.h') + conf.CHECK_TYPE_IN('struct sockaddr_storage', 'sys/socket.h') + conf.CHECK_TYPE_IN('sa_family_t', 'sys/socket.h') + + conf.CHECK_TYPE_IN('sig_atomic_t', 'signal.h', define='HAVE_SIG_ATOMIC_T_TYPE') + conf.CHECK_FUNCS('sigsetmask siggetmask sigprocmask sigblock sigaction sigset') + + # Those functions are normally available in libc + if not conf.CHECK_FUNCS(''' + inet_ntoa + inet_aton + inet_ntop + inet_pton + connect + gethostbyname + getaddrinfo + getnameinfo + freeaddrinfo + gai_strerror + socketpair''', + headers='sys/socket.h netinet/in.h arpa/inet.h netdb.h'): + conf.CHECK_FUNCS_IN(''' + inet_ntoa + inet_aton + inet_ntop + inet_pton + connect + gethostbyname + getaddrinfo + getnameinfo + freeaddrinfo + gai_strerror + socketpair''', + 'socket nsl', + headers='sys/socket.h netinet/in.h arpa/inet.h netdb.h') + conf.DEFINE('REPLACE_REQUIRES_LIBSOCKET_LIBNSL', 1) + + conf.CHECK_FUNCS('memset_s memset_explicit') + + conf.CHECK_CODE(''' + #include + + int main(void) + { + char buf[] = "This is some content"; + memset(buf, '\0', sizeof(buf)); __asm__ volatile("" : : "g"(&buf) : "memory"); + return 0; + } + ''', + define='HAVE_GCC_VOLATILE_MEMORY_PROTECTION', + addmain=False, + msg='Checking for volatile memory protection', + local_include=False) + + # Some old Linux systems have broken header files and + # miss the IPV6_V6ONLY define in netinet/in.h, + # but have it in linux/in6.h. + # We can't include both files so we just check if the value + # if defined and do the replacement in system/network.h + if not conf.CHECK_VARIABLE('IPV6_V6ONLY', + headers='sys/socket.h netdb.h netinet/in.h'): + conf.CHECK_CODE(''' + #include + #if (IPV6_V6ONLY != 26) + #error no IPV6_V6ONLY support on linux + #endif + int main(void) { return IPV6_V6ONLY; } + ''', + define='HAVE_LINUX_IPV6_V6ONLY_26', + addmain=False, + msg='Checking for IPV6_V6ONLY in linux/in6.h', + local_include=False) + + conf.CHECK_CODE(''' + struct sockaddr_storage sa_store; + struct addrinfo *ai = NULL; + struct in6_addr in6addr; + int idx = if_nametoindex("iface1"); + int s = socket(AF_INET6, SOCK_STREAM, 0); + int ret = getaddrinfo(NULL, NULL, NULL, &ai); + if (ret != 0) { + const char *es = gai_strerror(ret); + } + freeaddrinfo(ai); + { + int val = 1; + #ifdef HAVE_LINUX_IPV6_V6ONLY_26 + #define IPV6_V6ONLY 26 + #endif + ret = setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, + (const void *)&val, sizeof(val)); + } + ''', + define='HAVE_IPV6', + lib='nsl socket', + headers='sys/socket.h netdb.h netinet/in.h net/if.h') + + if conf.CONFIG_SET('HAVE_SYS_UCONTEXT_H') and conf.CONFIG_SET('HAVE_SIGNAL_H'): + conf.CHECK_CODE(''' + ucontext_t uc; + sigaddset(&uc.uc_sigmask, SIGUSR1); + ''', + 'HAVE_UCONTEXT_T', + msg="Checking whether we have ucontext_t", + headers='signal.h sys/ucontext.h') + + # Check for atomic builtins. */ + conf.CHECK_CODE(''' + int i; + (void)__sync_fetch_and_add(&i, 1); + ''', + 'HAVE___SYNC_FETCH_AND_ADD', + msg='Checking for __sync_fetch_and_add compiler builtin') + + conf.CHECK_CODE(''' + int32_t i; + atomic_add_32(&i, 1); + ''', + 'HAVE_ATOMIC_ADD_32', + headers='stdint.h sys/atomic.h', + msg='Checking for atomic_add_32 compiler builtin') + + # Check for thread fence. */ + tf = conf.CHECK_CODE('atomic_thread_fence(memory_order_seq_cst);', + 'HAVE_ATOMIC_THREAD_FENCE', + headers='stdatomic.h', + msg='Checking for atomic_thread_fence(memory_order_seq_cst) in stdatomic.h') + if not tf: + tf = conf.CHECK_CODE('__atomic_thread_fence(__ATOMIC_SEQ_CST);', + 'HAVE___ATOMIC_THREAD_FENCE', + msg='Checking for __atomic_thread_fence(__ATOMIC_SEQ_CST)') + if not tf: + # __sync_synchronize() is available since 2005 in gcc. + tf = conf.CHECK_CODE('__sync_synchronize();', + 'HAVE___SYNC_SYNCHRONIZE', + msg='Checking for __sync_synchronize') + if tf: + conf.DEFINE('HAVE_ATOMIC_THREAD_FENCE_SUPPORT', 1) + + conf.CHECK_CODE(''' + #define FALL_THROUGH __attribute__((fallthrough)) + + enum direction_e { + UP = 0, + DOWN, + }; + + int main(void) { + enum direction_e key = UP; + int i = 10; + int j = 0; + + switch (key) { + case UP: + i = 5; + FALL_THROUGH; + case DOWN: + j = i * 2; + break; + default: + break; + } + + if (j < i) { + return 1; + } + + return 0; + } + ''', + 'HAVE_FALLTHROUGH_ATTRIBUTE', + addmain=False, + strict=True, + cflags=['-Werror=missing-declarations'], + msg='Checking for fallthrough attribute') + + # these may be builtins, so we need the link=False strategy + conf.CHECK_FUNCS('strdup memmem printf memset memcpy memmove strcpy strncpy bzero', link=False) + + # See https://bugzilla.samba.org/show_bug.cgi?id=1097 + # + # Ported in from autoconf where it was added with this commit: + # commit 804cfb20a067b4b687089dc72a8271b3abf20f31 + # Author: Simo Sorce + # Date: Wed Aug 25 14:24:16 2004 +0000 + # r2070: Let's try to overload srnlen and strndup for AIX where they are natly broken. + + host_os = sys.platform + if host_os.rfind('aix') > -1: + conf.DEFINE('BROKEN_STRNLEN', 1) + conf.DEFINE('BROKEN_STRNDUP', 1) + + conf.CHECK_FUNCS('shl_load shl_unload shl_findsym') + conf.CHECK_FUNCS('pipe strftime srandom random srand rand usleep setbuffer') + conf.CHECK_FUNCS('lstat getpgrp utime utimes setuid seteuid setreuid setresuid setgid setegid') + conf.CHECK_FUNCS('setregid setresgid chroot strerror vsyslog setlinebuf mktime') + conf.CHECK_FUNCS('ftruncate chsize rename waitpid wait4') + conf.CHECK_FUNCS('initgroups pread pwrite strndup strcasestr strsep') + conf.CHECK_FUNCS('strtok_r mkdtemp dup2 dprintf vdprintf isatty chown lchown') + conf.CHECK_FUNCS('link readlink symlink realpath snprintf vsnprintf') + conf.CHECK_FUNCS('asprintf vasprintf setenv unsetenv strnlen strtoull __strtoull') + conf.CHECK_FUNCS('strtouq strtoll __strtoll strtoq memalign posix_memalign') + conf.CHECK_FUNCS('fmemopen') + + if conf.CONFIG_SET('HAVE_MEMALIGN'): + conf.CHECK_DECLS('memalign', headers='malloc.h') + + # glibc up to 2.3.6 had dangerously broken posix_fallocate(). DON'T USE IT. + if conf.CHECK_CODE(''' +#define _XOPEN_SOURCE 600 +#include +#if defined(__GLIBC__) && ((__GLIBC__ < 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 4)) +#error probably broken posix_fallocate +#endif +''', + '_POSIX_FALLOCATE_CAPABLE_LIBC', + msg='Checking for posix_fallocate-capable libc'): + conf.CHECK_FUNCS('posix_fallocate') + + conf.CHECK_FUNCS('prctl dirname basename') + + strlcpy_in_bsd = False + + # libbsd on some platforms provides strlcpy and strlcat + if not conf.CHECK_FUNCS('strlcpy strlcat'): + if conf.CHECK_FUNCS_IN('strlcpy strlcat', 'bsd', headers='bsd/string.h', + checklibc=True): + strlcpy_in_bsd = True + if not conf.CHECK_FUNCS('getpeereid'): + conf.CHECK_FUNCS_IN('getpeereid', 'bsd', headers='sys/types.h bsd/unistd.h') + if not conf.CHECK_FUNCS_IN('setproctitle', 'setproctitle', headers='setproctitle.h'): + conf.CHECK_FUNCS_IN('setproctitle', 'bsd', headers='sys/types.h bsd/unistd.h') + if not conf.CHECK_FUNCS('setproctitle_init'): + conf.CHECK_FUNCS_IN('setproctitle_init', 'bsd', headers='sys/types.h bsd/unistd.h') + + if not conf.CHECK_FUNCS('closefrom'): + conf.CHECK_FUNCS_IN('closefrom', 'bsd', headers='bsd/unistd.h') + + conf.CHECK_CODE(''' + struct ucred cred; + socklen_t cred_len; + int ret = getsockopt(0, SOL_SOCKET, SO_PEERCRED, &cred, &cred_len);''', + 'HAVE_PEERCRED', + msg="Checking whether we can use SO_PEERCRED to get socket credentials", + headers='sys/types.h sys/socket.h') + + #Some OS (ie. freebsd) return EINVAL if the convertion could not be done, it's not what we expect + #Let's detect those cases + if conf.CONFIG_SET('HAVE_STRTOLL'): + conf.CHECK_CODE(''' + long long nb = strtoll("Text", NULL, 0); + if (errno == EINVAL) { + return 0; + } else { + return 1; + } + ''', + msg="Checking correct behavior of strtoll", + headers = 'errno.h', + execute = True, + define = 'HAVE_BSD_STRTOLL', + ) + conf.CHECK_FUNCS('if_nametoindex strerror_r') + conf.CHECK_FUNCS('getdirentries getdents syslog') + conf.CHECK_FUNCS('gai_strerror get_current_dir_name') + conf.CHECK_FUNCS('timegm getifaddrs freeifaddrs mmap setgroups syscall setsid') + conf.CHECK_FUNCS('getgrent_r getgrgid_r getgrnam_r getgrouplist getpagesize') + conf.CHECK_FUNCS('getpwent_r getpwnam_r getpwuid_r epoll_create') + conf.CHECK_FUNCS('port_create') + conf.CHECK_FUNCS('getprogname') + + conf.SET_TARGET_TYPE('attr', 'EMPTY') + + xattr_headers='sys/attributes.h attr/xattr.h sys/xattr.h' + + # default to 1, we set it to 0 if we don't find any EA implementation below: + conf.DEFINE('HAVE_XATTR_SUPPORT', 1) + if conf.CHECK_FUNCS_IN('getxattr', 'attr', checklibc=True, headers=xattr_headers): + conf.DEFINE('HAVE_XATTR_XATTR', 1) + # Darwin has extra options to xattr-family functions + conf.CHECK_CODE('getxattr(NULL, NULL, NULL, 0, 0, 0)', + headers=xattr_headers, local_include=False, + define='XATTR_ADDITIONAL_OPTIONS', + msg="Checking whether xattr interface takes additional options") + elif conf.CHECK_FUNCS_IN('attr_listf', 'attr', checklibc=True, headers=xattr_headers): + conf.DEFINE('HAVE_XATTR_ATTR', 1) + elif conf.CHECK_FUNCS('extattr_list_fd'): + conf.DEFINE('HAVE_XATTR_EXTATTR', 1) + elif conf.CHECK_FUNCS('flistea'): + conf.DEFINE('HAVE_XATTR_EA', 1) + elif not conf.CHECK_FUNCS('attropen'): + conf.DEFINE('HAVE_XATTR_SUPPORT', 0) + + + conf.CHECK_FUNCS_IN('dlopen dlsym dlerror dlclose', 'dl', + checklibc=True, headers='dlfcn.h dl.h') + + conf.CHECK_C_PROTOTYPE('dlopen', 'void *dlopen(const char* filename, unsigned int flags)', + define='DLOPEN_TAKES_UNSIGNED_FLAGS', headers='dlfcn.h dl.h') + + # + # Check for clock_gettime and fdatasync + # + # First check libc to avoid linking libreplace against librt. + # + if conf.CHECK_FUNCS('fdatasync'): + # some systems are missing the declaration + conf.CHECK_DECLS('fdatasync') + else: + if conf.CHECK_FUNCS_IN('fdatasync', 'rt'): + # some systems are missing the declaration + conf.CHECK_DECLS('fdatasync') + + has_clock_gettime = False + if conf.CHECK_FUNCS('clock_gettime'): + has_clock_gettime = True + + if not has_clock_gettime: + if conf.CHECK_FUNCS_IN('clock_gettime', 'rt', checklibc=True): + has_clock_gettime = True + + if has_clock_gettime: + for c in ['CLOCK_MONOTONIC', 'CLOCK_PROCESS_CPUTIME_ID', 'CLOCK_REALTIME']: + conf.CHECK_CODE(''' + #if TIME_WITH_SYS_TIME + # include + # include + #else + # if HAVE_SYS_TIME_H + # include + # else + # include + # endif + #endif + clockid_t clk = %s''' % c, + 'HAVE_%s' % c, + msg='Checking whether the clock_gettime clock ID %s is available' % c) + + conf.CHECK_TYPE('struct timespec', headers='sys/time.h time.h') + + # these headers need to be tested as a group on freebsd + conf.CHECK_HEADERS(headers='sys/socket.h net/if.h', together=True) + conf.CHECK_HEADERS(headers='netinet/in.h arpa/nameser.h resolv.h', together=True) + conf.CHECK_FUNCS_IN('res_search', 'resolv', checklibc=True, + headers='netinet/in.h arpa/nameser.h resolv.h') + + + # try to find libintl (if --without-gettext is not given) + conf.env.intl_libs='' + if not Options.options.disable_gettext: + conf.CHECK_HEADERS('libintl.h') + conf.CHECK_LIB('intl') + conf.CHECK_DECLS('dgettext gettext bindtextdomain textdomain bind_textdomain_codeset', headers="libintl.h") + # *textdomain functions are not strictly necessary + conf.CHECK_FUNCS_IN('bindtextdomain textdomain bind_textdomain_codeset', + '', checklibc=True, headers='libintl.h') + # gettext and dgettext must exist + # on some systems (the ones with glibc, those are in libc) + if conf.CHECK_FUNCS_IN('dgettext gettext', '', checklibc=True, headers='libintl.h'): + # save for dependency definitions + conf.env.intl_libs='' + # others (e.g. FreeBSD) have separate libintl + elif conf.CHECK_FUNCS_IN('dgettext gettext', 'intl', checklibc=False, headers='libintl.h'): + # save for dependency definitions + conf.env.intl_libs='intl' + # recheck with libintl + conf.CHECK_FUNCS_IN('bindtextdomain textdomain bind_textdomain_codeset', + 'intl', checklibc=False, headers='libintl.h') + else: + # Some hosts need lib iconv for linking with lib intl + # So we try with flags just in case it helps. + oldflags = list(conf.env['EXTRA_LDFLAGS']); + conf.env['EXTRA_LDFLAGS'].extend(["-liconv"]) + conf.CHECK_FUNCS_IN('dgettext gettext bindtextdomain textdomain bind_textdomain_codeset', + 'intl', checklibc=False, headers='libintl.h') + conf.env['EXTRA_LDFLAGS'] = oldflags + if conf.env['HAVE_GETTEXT'] and conf.env['HAVE_DGETTEXT']: + # save for dependency definitions + conf.env.intl_libs='iconv intl' + + # did we find both prototypes and a library to link against? + # if not, unset the detected values (see Bug #9911) + if not (conf.env['HAVE_GETTEXT'] and conf.env['HAVE_DECL_GETTEXT']): + conf.undefine('HAVE_GETTEXT') + conf.undefine('HAVE_DECL_GETTEXT') + if not (conf.env['HAVE_DGETTEXT'] and conf.env['HAVE_DECL_DGETTEXT']): + conf.undefine('HAVE_DGETTEXT') + conf.undefine('HAVE_DECL_DGETTEXT') + + conf.CHECK_FUNCS_IN('pthread_create', 'pthread', checklibc=True, headers='pthread.h') + + PTHREAD_CFLAGS='error' + PTHREAD_LDFLAGS='error' + + if PTHREAD_LDFLAGS == 'error': + # Check if pthread_attr_init() is provided by libc first! + if conf.CHECK_FUNCS('pthread_attr_init'): + PTHREAD_CFLAGS='-D_REENTRANT' + PTHREAD_LDFLAGS='' + if PTHREAD_LDFLAGS == 'error': + if conf.CHECK_FUNCS_IN('pthread_attr_init', 'pthread'): + PTHREAD_CFLAGS='-D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS' + PTHREAD_LDFLAGS='-lpthread' + if PTHREAD_LDFLAGS == 'error': + if conf.CHECK_FUNCS_IN('pthread_attr_init', 'pthreads'): + PTHREAD_CFLAGS='-D_THREAD_SAFE' + PTHREAD_LDFLAGS='-lpthreads' + if PTHREAD_LDFLAGS == 'error': + if conf.CHECK_FUNCS_IN('pthread_attr_init', 'c_r'): + PTHREAD_CFLAGS='-D_THREAD_SAFE -pthread' + PTHREAD_LDFLAGS='-pthread' + + # especially for HP-UX, where the CHECK_FUNC macro fails to test for + # pthread_attr_init. On pthread_mutex_lock it works there... + if PTHREAD_LDFLAGS == 'error': + if conf.CHECK_FUNCS_IN('pthread_mutex_lock', 'pthread'): + PTHREAD_CFLAGS='-D_REENTRANT' + PTHREAD_LDFLAGS='-lpthread' + + if PTHREAD_CFLAGS != 'error' and PTHREAD_LDFLAGS != 'error': + if conf.CONFIG_SET('replace_add_global_pthread'): + conf.ADD_CFLAGS(PTHREAD_CFLAGS) + conf.ADD_LDFLAGS(PTHREAD_LDFLAGS) + conf.CHECK_HEADERS('pthread.h') + conf.DEFINE('HAVE_PTHREAD', '1') + + if conf.CONFIG_SET('HAVE_PTHREAD'): + + conf.CHECK_FUNCS_IN('pthread_mutexattr_setrobust', 'pthread', + checklibc=True, headers='pthread.h') + if not conf.CONFIG_SET('HAVE_PTHREAD_MUTEXATTR_SETROBUST'): + conf.CHECK_FUNCS_IN('pthread_mutexattr_setrobust_np', 'pthread', + checklibc=True, headers='pthread.h') + + conf.CHECK_DECLS('PTHREAD_MUTEX_ROBUST', headers='pthread.h') + if not conf.CONFIG_SET('HAVE_DECL_PTHREAD_MUTEX_ROBUST'): + conf.CHECK_DECLS('PTHREAD_MUTEX_ROBUST_NP', headers='pthread.h') + + conf.CHECK_FUNCS_IN('pthread_mutex_consistent', 'pthread', + checklibc=True, headers='pthread.h') + if not conf.CONFIG_SET('HAVE_PTHREAD_MUTEX_CONSISTENT'): + conf.CHECK_FUNCS_IN('pthread_mutex_consistent_np', 'pthread', + checklibc=True, headers='pthread.h') + + if ((conf.CONFIG_SET('HAVE_PTHREAD_MUTEXATTR_SETROBUST') or + conf.CONFIG_SET('HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP')) and + (conf.CONFIG_SET('HAVE_DECL_PTHREAD_MUTEX_ROBUST') or + conf.CONFIG_SET('HAVE_DECL_PTHREAD_MUTEX_ROBUST_NP')) and + (conf.CONFIG_SET('HAVE_PTHREAD_MUTEX_CONSISTENT') or + conf.CONFIG_SET('HAVE_PTHREAD_MUTEX_CONSISTENT_NP'))): + conf.DEFINE('HAVE_ROBUST_MUTEXES', 1) + + # __thread is available since 2002 in gcc. + conf.CHECK_CODE(''' + __thread int tls; + + int main(void) { + return 0; + } + ''', + 'HAVE___THREAD', + addmain=False, + msg='Checking for __thread local storage') + + conf.CHECK_FUNCS_IN('crypt', 'crypt', checklibc=True) + conf.CHECK_FUNCS_IN('crypt_r', 'crypt', checklibc=True) + + conf.CHECK_VARIABLE('rl_event_hook', define='HAVE_DECL_RL_EVENT_HOOK', always=True, + headers='readline.h readline/readline.h readline/history.h') + conf.CHECK_VARIABLE('program_invocation_short_name', headers='errno.h') + + conf.CHECK_DECLS('snprintf vsnprintf asprintf vasprintf') + + conf.CHECK_DECLS('errno', headers='errno.h', reverse=True) + conf.CHECK_DECLS('EWOULDBLOCK', headers='errno.h') + conf.CHECK_DECLS('environ', reverse=True, headers='unistd.h') + conf.CHECK_DECLS('getgrent_r getpwent_r', reverse=True, headers='pwd.h grp.h') + conf.CHECK_DECLS('pread pwrite setenv setresgid setresuid', reverse=True) + + if conf.CONFIG_SET('HAVE_EPOLL_CREATE') and conf.CONFIG_SET('HAVE_SYS_EPOLL_H'): + conf.DEFINE('HAVE_EPOLL', 1) + + if conf.CONFIG_SET('HAVE_PORT_CREATE') and conf.CONFIG_SET('HAVE_PORT_H'): + conf.DEFINE('HAVE_SOLARIS_PORTS', 1) + + if conf.CHECK_FUNCS('eventfd', headers='sys/eventfd.h'): + conf.DEFINE('HAVE_EVENTFD', 1) + + conf.CHECK_HEADERS('poll.h') + conf.CHECK_FUNCS('poll') + + conf.CHECK_FUNCS('strptime') + conf.CHECK_DECLS('strptime', headers='time.h') + conf.CHECK_CODE('''#define LIBREPLACE_CONFIGURE_TEST_STRPTIME + #include "tests/strptime.c"''', + define='HAVE_WORKING_STRPTIME', + execute=True, + addmain=False, + msg='Checking for working strptime') + + conf.CHECK_C_PROTOTYPE('gettimeofday', + 'int gettimeofday(struct timeval *tv, struct timezone *tz)', + define='HAVE_GETTIMEOFDAY_TZ', headers='sys/time.h') + + conf.CHECK_C_PROTOTYPE('gettimeofday', + 'int gettimeofday(struct timeval *tv, void *tz)', + define='HAVE_GETTIMEOFDAY_TZ_VOID', + headers='sys/time.h') + + conf.CHECK_CODE('#include "tests/snprintf.c"', + define="HAVE_C99_VSNPRINTF", + execute=True, + addmain=False, + msg="Checking for C99 vsnprintf") + + conf.CHECK_CODE('#include "tests/shared_mmap.c"', + addmain=False, add_headers=False, execute=True, + define='HAVE_SHARED_MMAP', + msg="Checking for HAVE_SHARED_MMAP") + + conf.CHECK_CODE('#include "tests/shared_mremap.c"', + addmain=False, add_headers=False, execute=True, + define='HAVE_MREMAP', + msg="Checking for HAVE_MREMAP") + + # OpenBSD (and I've heard HPUX) doesn't sync between mmap and write. + # FIXME: Anything other than a 0 or 1 exit code should abort configure! + conf.CHECK_CODE('#include "tests/incoherent_mmap.c"', + addmain=False, add_headers=False, execute=True, + define='HAVE_INCOHERENT_MMAP', + msg="Checking for HAVE_INCOHERENT_MMAP") + + conf.SAMBA_BUILD_ENV() + + conf.CHECK_CODE(''' + typedef struct {unsigned x;} FOOBAR; + #define X_FOOBAR(x) ((FOOBAR) { x }) + #define FOO_ONE X_FOOBAR(1) + FOOBAR f = FOO_ONE; + static const struct { + FOOBAR y; + } f2[] = { + {FOO_ONE} + }; + static const FOOBAR f3[] = {FOO_ONE}; + ''', + define='HAVE_IMMEDIATE_STRUCTURES') + + conf.CHECK_CODE('mkdir("foo",0777)', define='HAVE_MKDIR_MODE', headers='sys/stat.h') + + conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_mtim.tv_nsec', define='HAVE_STAT_TV_NSEC', + headers='sys/stat.h') + # we need the st_rdev test under two names + conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_rdev', + define='HAVE_STRUCT_STAT_ST_RDEV', + headers='sys/stat.h') + conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_rdev', define='HAVE_ST_RDEV', + headers='sys/stat.h') + conf.CHECK_STRUCTURE_MEMBER('struct sockaddr_storage', 'ss_family', + headers='sys/socket.h netinet/in.h') + conf.CHECK_STRUCTURE_MEMBER('struct sockaddr_storage', '__ss_family', + headers='sys/socket.h netinet/in.h') + + + if conf.CHECK_STRUCTURE_MEMBER('struct sockaddr', 'sa_len', + headers='sys/socket.h netinet/in.h', + define='HAVE_SOCKADDR_SA_LEN'): + # the old build system produced both defines + conf.DEFINE('HAVE_STRUCT_SOCKADDR_SA_LEN', 1) + + conf.CHECK_STRUCTURE_MEMBER('struct sockaddr_in', 'sin_len', + headers='sys/socket.h netinet/in.h', + define='HAVE_SOCK_SIN_LEN') + + conf.CHECK_STRUCTURE_MEMBER('struct sockaddr_in6', 'sin6_len', + headers='sys/socket.h netinet/in.h', + define='HAVE_SOCK_SIN6_LEN') + + conf.CHECK_CODE('struct sockaddr_un sunaddr; sunaddr.sun_family = AF_UNIX;', + define='HAVE_UNIXSOCKET', headers='sys/socket.h sys/un.h') + + + conf.CHECK_CODE(''' + struct stat st; + char tpl[20]="/tmp/test.XXXXXX"; + char tpl2[20]="/tmp/test.XXXXXX"; + int fd = mkstemp(tpl); + int fd2 = mkstemp(tpl2); + if (fd == -1) { + if (fd2 != -1) { + unlink(tpl2); + } + exit(1); + } + if (fd2 == -1) exit(1); + unlink(tpl); + unlink(tpl2); + if (fstat(fd, &st) != 0) exit(1); + if ((st.st_mode & 0777) != 0600) exit(1); + if (strcmp(tpl, "/tmp/test.XXXXXX") == 0) { + exit(1); + } + if (strcmp(tpl, tpl2) == 0) { + exit(1); + } + exit(0); + ''', + define='HAVE_SECURE_MKSTEMP', + execute=True, + mandatory=True) # lets see if we get a mandatory failure for this one + + # look for a method of finding the list of network interfaces + for method in ['HAVE_IFACE_GETIFADDRS', 'HAVE_IFACE_AIX', 'HAVE_IFACE_IFCONF', 'HAVE_IFACE_IFREQ']: + bsd_for_strlcpy = '' + if strlcpy_in_bsd: + bsd_for_strlcpy = ' bsd' + if conf.CHECK_CODE(''' + #define %s 1 + #define NO_CONFIG_H 1 + #define AUTOCONF_TEST 1 + #include "replace.c" + #include "inet_ntop.c" + #include "snprintf.c" + #include "getifaddrs.c" + #define getifaddrs_test main + #include "tests/getifaddrs.c" + ''' % method, + method, + lib='nsl socket' + bsd_for_strlcpy, + addmain=False, + execute=True): + break + + conf.RECURSE('system') + conf.SAMBA_CONFIG_H() + if conf.CHECK_FUNCS('strerror_r'): + # Check if strerror_r is XSI-Compatable, the default GNU implementation + # is not + conf.CHECK_CODE('int strerror_r(int errnum, char *buf, size_t buflen);', + 'STRERROR_R_XSI_NOT_GNU', + headers='string.h', addmain=False, link=False, + msg="Checking for XSI (rather than GNU) prototype for strerror_r") + + +REPLACEMENT_FUNCTIONS = { + 'replace.c': ['ftruncate', 'strlcpy', 'strlcat', 'mktime', 'initgroups', + 'memmove', 'strdup', 'setlinebuf', 'vsyslog', 'strnlen', + 'strndup', 'waitpid', 'seteuid', 'setegid', 'chroot', + 'mkstemp', 'mkdtemp', 'pread', 'pwrite', 'strcasestr', + 'strsep', 'strtok_r', 'strtoll', 'strtoull', 'setenv', 'unsetenv', + 'utime', 'utimes', 'dup2', 'chown', 'link', 'readlink', + 'symlink', 'lchown', 'realpath', 'memmem', 'vdprintf', + 'dprintf', 'get_current_dir_name', + 'strerror_r', 'clock_gettime', 'memset_s'], + 'timegm.c': ['timegm'], + # Note: C99_VSNPRINTF is not a function, but a special condition + # for replacement + 'snprintf.c': ['C99_VSNPRINTF', 'snprintf', 'vsnprintf', 'asprintf', 'vasprintf'], + # Note: WORKING_STRPTIME is not a function, but a special condition + # for replacement + 'strptime.c': ['WORKING_STRPTIME', 'strptime'], + } + + +def build(bld): + bld.RECURSE('buildtools/wafsamba') + + REPLACE_HOSTCC_SOURCE = '' + + for filename in REPLACEMENT_FUNCTIONS.keys(): + for function in REPLACEMENT_FUNCTIONS[filename]: + if not bld.CONFIG_SET('HAVE_%s' % function.upper()): + REPLACE_HOSTCC_SOURCE += ' %s' % filename + break + + extra_libs = '' + if bld.CONFIG_SET('HAVE_LIBBSD'): extra_libs += ' bsd' + if bld.CONFIG_SET('HAVE_LIBRT'): extra_libs += ' rt' + if bld.CONFIG_SET('REPLACE_REQUIRES_LIBSOCKET_LIBNSL'): extra_libs += ' socket nsl' + + bld.SAMBA_SUBSYSTEM('LIBREPLACE_HOSTCC', + REPLACE_HOSTCC_SOURCE, + use_hostcc=True, + use_global_deps=False, + cflags='-D_SAMBA_HOSTCC_', + group='compiler_libraries', + deps = extra_libs + ) + + REPLACE_SOURCE = REPLACE_HOSTCC_SOURCE + REPLACE_SOURCE += ' cwrap.c' + + if not bld.CONFIG_SET('HAVE_CRYPT'): REPLACE_SOURCE += ' crypt.c' + if not bld.CONFIG_SET('HAVE_DLOPEN'): REPLACE_SOURCE += ' dlfcn.c' + if not bld.CONFIG_SET('HAVE_POLL'): REPLACE_SOURCE += ' poll.c' + + if not bld.CONFIG_SET('HAVE_SOCKETPAIR'): REPLACE_SOURCE += ' socketpair.c' + if not bld.CONFIG_SET('HAVE_CONNECT'): REPLACE_SOURCE += ' socket.c' + if not bld.CONFIG_SET('HAVE_GETIFADDRS'): REPLACE_SOURCE += ' getifaddrs.c' + if not bld.CONFIG_SET('HAVE_GETADDRINFO'): REPLACE_SOURCE += ' getaddrinfo.c' + if not bld.CONFIG_SET('HAVE_INET_NTOA'): REPLACE_SOURCE += ' inet_ntoa.c' + if not bld.CONFIG_SET('HAVE_INET_ATON'): REPLACE_SOURCE += ' inet_aton.c' + if not bld.CONFIG_SET('HAVE_INET_NTOP'): REPLACE_SOURCE += ' inet_ntop.c' + if not bld.CONFIG_SET('HAVE_INET_PTON'): REPLACE_SOURCE += ' inet_pton.c' + if not bld.CONFIG_SET('HAVE_GETXATTR') or bld.CONFIG_SET('XATTR_ADDITIONAL_OPTIONS'): + REPLACE_SOURCE += ' xattr.c' + + if not bld.CONFIG_SET('HAVE_CLOSEFROM'): + REPLACE_SOURCE += ' closefrom.c' + + bld.SAMBA_LIBRARY('replace', + source=REPLACE_SOURCE, + group='base_libraries', + # FIXME: Ideally symbols should be hidden here so they + # don't appear in the global namespace when Samba + # libraries are loaded, but this doesn't appear to work + # at the moment: + # hide_symbols=bld.BUILTIN_LIBRARY('replace'), + private_library=True, + deps='crypt dl attr' + extra_libs) + + replace_test_cflags = '' + if bld.CONFIG_SET('HAVE_WNO_FORMAT_TRUNCATION'): + replace_test_cflags += " -Wno-format-truncation" + bld.SAMBA_SUBSYSTEM('replace-test', + source='''tests/testsuite.c tests/strptime.c + tests/os2_delete.c tests/getifaddrs.c''', + deps='replace', + cflags=replace_test_cflags) + + bld.SAMBA_BINARY('replace_testsuite', + source='tests/main.c', + deps='replace replace-test', + install=False) + + # build replacements for stdint.h and stdbool.h if needed + bld.SAMBA_GENERATOR('replace_stdint_h', + rule='cp ${SRC} ${TGT}', + source='hdr_replace.h', + target='stdint.h', + enabled = not bld.CONFIG_SET('HAVE_STDINT_H')) + bld.SAMBA_GENERATOR('replace_stdbool_h', + rule='cp ${SRC} ${TGT}', + source='hdr_replace.h', + target='stdbool.h', + enabled = not bld.CONFIG_SET('HAVE_STDBOOL_H')) + + bld.SAMBA_SUBSYSTEM('samba_intl', source='', use_global_deps=False,deps=bld.env.intl_libs) + +def testonly(ctx): + '''run talloc testsuite''' + import samba_utils + + samba_utils.ADD_LD_LIBRARY_PATH('bin/shared') + samba_utils.ADD_LD_LIBRARY_PATH('bin/shared/private') + + cmd = os.path.join(Context.g_module.out, 'replace_testsuite') + ret = samba_utils.RUN_COMMAND(cmd) + print("testsuite returned %d" % ret) + sys.exit(ret) + +# WAF doesn't build the unit tests for this, maybe because they don't link with talloc? +# This forces it +def test(ctx): + Options.commands.append('build') + Options.commands.append('testonly') + +def dist(): + '''makes a tarball for distribution''' + samba_dist.dist() diff --git a/ldb-2.0.8/lib/replace/xattr.c b/ldb-2.0.8/lib/replace/xattr.c new file mode 100644 index 0000000..2420ee1 --- /dev/null +++ b/ldb-2.0.8/lib/replace/xattr.c @@ -0,0 +1,785 @@ +/* + Unix SMB/CIFS implementation. + replacement routines for xattr implementations + Copyright (C) Jeremy Allison 1998-2005 + Copyright (C) Timur Bakeyev 2005 + Copyright (C) Bjoern Jacke 2006-2007 + Copyright (C) Herb Lewis 2003 + Copyright (C) Andrew Bartlett 2012 + + ** NOTE! The following LGPL license applies to the replace + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#define UID_WRAPPER_NOT_REPLACE +#include "replace.h" +#include "system/filesys.h" +#include "system/dir.h" + +/******** Solaris EA helper function prototypes ********/ +#ifdef HAVE_ATTROPEN +#define SOLARIS_ATTRMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP +static int solaris_write_xattr(int attrfd, const char *value, size_t size); +static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size); +static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size); +static int solaris_unlinkat(int attrdirfd, const char *name); +static int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode); +static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode); +#endif + +/************************************************************************** + Wrappers for extented attribute calls. Based on the Linux package with + support for IRIX and (Net|Free)BSD also. Expand as other systems have them. +****************************************************************************/ + +ssize_t rep_getxattr (const char *path, const char *name, void *value, size_t size) +{ +#if defined(HAVE_XATTR_XATTR) +#ifndef XATTR_ADDITIONAL_OPTIONS + return getxattr(path, name, value, size); +#else + +/* So that we do not recursivly call this function */ +#undef getxattr + int options = 0; + return getxattr(path, name, value, size, 0, options); +#endif +#elif defined(HAVE_XATTR_EA) + return getea(path, name, value, size); +#elif defined(HAVE_XATTR_EXTATTR) + ssize_t retval; + int attrnamespace; + const char *attrname; + + if (strncmp(name, "system.", 7) == 0) { + attrnamespace = EXTATTR_NAMESPACE_SYSTEM; + attrname = name + 7; + } else if (strncmp(name, "user.", 5) == 0) { + attrnamespace = EXTATTR_NAMESPACE_USER; + attrname = name + 5; + } else { + errno = EINVAL; + return -1; + } + + /* + * The BSD implementation has a nasty habit of silently truncating + * the returned value to the size of the buffer, so we have to check + * that the buffer is large enough to fit the returned value. + */ + if((retval=extattr_get_file(path, attrnamespace, attrname, NULL, 0)) >= 0) { + if (size == 0) { + return retval; + } else if (retval > size) { + errno = ERANGE; + return -1; + } + if((retval=extattr_get_file(path, attrnamespace, attrname, value, size)) >= 0) + return retval; + } + + return -1; +#elif defined(HAVE_XATTR_ATTR) + int retval, flags = 0; + int valuelength = (int)size; + char *attrname = strchr(name,'.') + 1; + + if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; + + retval = attr_get(path, attrname, (char *)value, &valuelength, flags); + if (size == 0 && retval == -1 && errno == E2BIG) { + return valuelength; + } + + return retval ? retval : valuelength; +#elif defined(HAVE_ATTROPEN) + ssize_t ret = -1; + int attrfd = solaris_attropen(path, name, O_RDONLY, 0); + if (attrfd >= 0) { + ret = solaris_read_xattr(attrfd, value, size); + close(attrfd); + } + return ret; +#else + errno = ENOSYS; + return -1; +#endif +} + +ssize_t rep_fgetxattr (int filedes, const char *name, void *value, size_t size) +{ +#if defined(HAVE_XATTR_XATTR) +#ifndef XATTR_ADDITIONAL_OPTIONS + return fgetxattr(filedes, name, value, size); +#else + +/* So that we do not recursivly call this function */ +#undef fgetxattr + int options = 0; + return fgetxattr(filedes, name, value, size, 0, options); +#endif +#elif defined(HAVE_XATTR_EA) + return fgetea(filedes, name, value, size); +#elif defined(HAVE_XATTR_EXTATTR) + ssize_t retval; + int attrnamespace; + const char *attrname; + + if (strncmp(name, "system.", 7) == 0) { + attrnamespace = EXTATTR_NAMESPACE_SYSTEM; + attrname = name + 7; + } else if (strncmp(name, "user.", 5) == 0) { + attrnamespace = EXTATTR_NAMESPACE_USER; + attrname = name + 5; + } else { + errno = EINVAL; + return -1; + } + + if((retval=extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0)) >= 0) { + if (size == 0) { + return retval; + } else if (retval > size) { + errno = ERANGE; + return -1; + } + if((retval=extattr_get_fd(filedes, attrnamespace, attrname, value, size)) >= 0) + return retval; + } + + return -1; +#elif defined(HAVE_XATTR_ATTR) + int retval, flags = 0; + int valuelength = (int)size; + char *attrname = strchr(name,'.') + 1; + + if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; + + retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags); + if (size == 0 && retval == -1 && errno == E2BIG) { + return valuelength; + } + return retval ? retval : valuelength; +#elif defined(HAVE_ATTROPEN) + ssize_t ret = -1; + int attrfd = solaris_openat(filedes, name, O_RDONLY|O_XATTR, 0); + if (attrfd >= 0) { + ret = solaris_read_xattr(attrfd, value, size); + close(attrfd); + } + return ret; +#else + errno = ENOSYS; + return -1; +#endif +} + +#if defined(HAVE_XATTR_EXTATTR) + +#define EXTATTR_PREFIX(s) (s), (sizeof((s))-1) + +static struct { + int space; + const char *name; + size_t len; +} +extattr[] = { + { EXTATTR_NAMESPACE_SYSTEM, EXTATTR_PREFIX("system.") }, + { EXTATTR_NAMESPACE_USER, EXTATTR_PREFIX("user.") }, +}; + +typedef union { + const char *path; + int filedes; +} extattr_arg; + +static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size) +{ + ssize_t list_size, total_size = 0; + int i, t, len; + char *buf; + /* Iterate through extattr(2) namespaces */ + for(t = 0; t < ARRAY_SIZE(extattr); t++) { + if (t != EXTATTR_NAMESPACE_USER && geteuid() != 0) { + /* ignore all but user namespace when we are not root, see bug 10247 */ + continue; + } + switch(type) { + case 0: + list_size = extattr_list_file(arg.path, extattr[t].space, list, size); + break; + case 1: + list_size = extattr_list_link(arg.path, extattr[t].space, list, size); + break; + case 2: + list_size = extattr_list_fd(arg.filedes, extattr[t].space, list, size); + break; + default: + errno = ENOSYS; + return -1; + } + /* Some error happend. Errno should be set by the previous call */ + if(list_size < 0) + return -1; + /* No attributes */ + if(list_size == 0) + continue; + /* XXX: Call with an empty buffer may be used to calculate + necessary buffer size. Unfortunately, we can't say, how + many attributes were returned, so here is the potential + problem with the emulation. + */ + if(list == NULL) { + /* Take the worse case of one char attribute names - + two bytes per name plus one more for sanity. + */ + total_size += list_size + (list_size/2 + 1)*extattr[t].len; + continue; + } + /* Count necessary offset to fit namespace prefixes */ + len = 0; + for(i = 0; i < list_size; i += list[i] + 1) + len += extattr[t].len; + + total_size += list_size + len; + /* Buffer is too small to fit the results */ + if(total_size > size) { + errno = ERANGE; + return -1; + } + /* Shift results back, so we can prepend prefixes */ + buf = (char *)memmove(list + len, list, list_size); + + for(i = 0; i < list_size; i += len + 1) { + len = buf[i]; + strncpy(list, extattr[t].name, extattr[t].len + 1); + list += extattr[t].len; + strncpy(list, buf + i + 1, len); + list[len] = '\0'; + list += len + 1; + } + size -= total_size; + } + return total_size; +} + +#endif + +#if defined(HAVE_XATTR_ATTR) && (defined(HAVE_SYS_ATTRIBUTES_H) || defined(HAVE_ATTR_ATTRIBUTES_H)) +static char attr_buffer[ATTR_MAX_VALUELEN]; + +static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t size, int flags) +{ + int retval = 0, index; + attrlist_cursor_t *cursor = 0; + int total_size = 0; + attrlist_t * al = (attrlist_t *)attr_buffer; + attrlist_ent_t *ae; + size_t ent_size, left = size; + char *bp = list; + + while (true) { + if (filedes) + retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor); + else + retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor); + if (retval) break; + for (index = 0; index < al->al_count; index++) { + ae = ATTR_ENTRY(attr_buffer, index); + ent_size = strlen(ae->a_name) + sizeof("user."); + if (left >= ent_size) { + strncpy(bp, "user.", sizeof("user.")); + strncat(bp, ae->a_name, ent_size - sizeof("user.")); + bp += ent_size; + left -= ent_size; + } else if (size) { + errno = ERANGE; + retval = -1; + break; + } + total_size += ent_size; + } + if (al->al_more == 0) break; + } + if (retval == 0) { + flags |= ATTR_ROOT; + cursor = 0; + while (true) { + if (filedes) + retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor); + else + retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor); + if (retval) break; + for (index = 0; index < al->al_count; index++) { + ae = ATTR_ENTRY(attr_buffer, index); + ent_size = strlen(ae->a_name) + sizeof("system."); + if (left >= ent_size) { + strncpy(bp, "system.", sizeof("system.")); + strncat(bp, ae->a_name, ent_size - sizeof("system.")); + bp += ent_size; + left -= ent_size; + } else if (size) { + errno = ERANGE; + retval = -1; + break; + } + total_size += ent_size; + } + if (al->al_more == 0) break; + } + } + return (ssize_t)(retval ? retval : total_size); +} + +#endif + +ssize_t rep_listxattr (const char *path, char *list, size_t size) +{ +#if defined(HAVE_XATTR_XATTR) +#ifndef XATTR_ADDITIONAL_OPTIONS + return listxattr(path, list, size); +#else +/* So that we do not recursivly call this function */ +#undef listxattr + int options = 0; + return listxattr(path, list, size, options); +#endif +#elif defined(HAVE_XATTR_EA) + return listea(path, list, size); +#elif defined(HAVE_XATTR_EXTATTR) + extattr_arg arg; + arg.path = path; + return bsd_attr_list(0, arg, list, size); +#elif defined(HAVE_XATTR_ATTR) && defined(HAVE_SYS_ATTRIBUTES_H) + return irix_attr_list(path, 0, list, size, 0); +#elif defined(HAVE_ATTROPEN) + ssize_t ret = -1; + int attrdirfd = solaris_attropen(path, ".", O_RDONLY, 0); + if (attrdirfd >= 0) { + ret = solaris_list_xattr(attrdirfd, list, size); + close(attrdirfd); + } + return ret; +#else + errno = ENOSYS; + return -1; +#endif +} + +ssize_t rep_flistxattr (int filedes, char *list, size_t size) +{ +#if defined(HAVE_XATTR_XATTR) +#ifndef XATTR_ADDITIONAL_OPTIONS + return flistxattr(filedes, list, size); +#else +/* So that we do not recursivly call this function */ +#undef flistxattr + int options = 0; + return flistxattr(filedes, list, size, options); +#endif +#elif defined(HAVE_XATTR_EA) + return flistea(filedes, list, size); +#elif defined(HAVE_XATTR_EXTATTR) + extattr_arg arg; + arg.filedes = filedes; + return bsd_attr_list(2, arg, list, size); +#elif defined(HAVE_XATTR_ATTR) + return irix_attr_list(NULL, filedes, list, size, 0); +#elif defined(HAVE_ATTROPEN) + ssize_t ret = -1; + int attrdirfd = solaris_openat(filedes, ".", O_RDONLY|O_XATTR, 0); + if (attrdirfd >= 0) { + ret = solaris_list_xattr(attrdirfd, list, size); + close(attrdirfd); + } + return ret; +#else + errno = ENOSYS; + return -1; +#endif +} + +int rep_removexattr (const char *path, const char *name) +{ +#if defined(HAVE_XATTR_XATTR) +#ifndef XATTR_ADDITIONAL_OPTIONS + return removexattr(path, name); +#else +/* So that we do not recursivly call this function */ +#undef removexattr + int options = 0; + return removexattr(path, name, options); +#endif +#elif defined(HAVE_XATTR_EA) + return removeea(path, name); +#elif defined(HAVE_XATTR_EXTATTR) + int attrnamespace; + const char *attrname; + + if (strncmp(name, "system.", 7) == 0) { + attrnamespace = EXTATTR_NAMESPACE_SYSTEM; + attrname = name + 7; + } else if (strncmp(name, "user.", 5) == 0) { + attrnamespace = EXTATTR_NAMESPACE_USER; + attrname = name + 5; + } else { + errno = EINVAL; + return -1; + } + + return extattr_delete_file(path, attrnamespace, attrname); +#elif defined(HAVE_XATTR_ATTR) + int flags = 0; + char *attrname = strchr(name,'.') + 1; + + if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; + + return attr_remove(path, attrname, flags); +#elif defined(HAVE_ATTROPEN) + int ret = -1; + int attrdirfd = solaris_attropen(path, ".", O_RDONLY, 0); + if (attrdirfd >= 0) { + ret = solaris_unlinkat(attrdirfd, name); + close(attrdirfd); + } + return ret; +#else + errno = ENOSYS; + return -1; +#endif +} + +int rep_fremovexattr (int filedes, const char *name) +{ +#if defined(HAVE_XATTR_XATTR) +#ifndef XATTR_ADDITIONAL_OPTIONS + return fremovexattr(filedes, name); +#else +/* So that we do not recursivly call this function */ +#undef fremovexattr + int options = 0; + return fremovexattr(filedes, name, options); +#endif +#elif defined(HAVE_XATTR_EA) + return fremoveea(filedes, name); +#elif defined(HAVE_XATTR_EXTATTR) + int attrnamespace; + const char *attrname; + + if (strncmp(name, "system.", 7) == 0) { + attrnamespace = EXTATTR_NAMESPACE_SYSTEM; + attrname = name + 7; + } else if (strncmp(name, "user.", 5) == 0) { + attrnamespace = EXTATTR_NAMESPACE_USER; + attrname = name + 5; + } else { + errno = EINVAL; + return -1; + } + + return extattr_delete_fd(filedes, attrnamespace, attrname); +#elif defined(HAVE_XATTR_ATTR) + int flags = 0; + char *attrname = strchr(name,'.') + 1; + + if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; + + return attr_removef(filedes, attrname, flags); +#elif defined(HAVE_ATTROPEN) + int ret = -1; + int attrdirfd = solaris_openat(filedes, ".", O_RDONLY|O_XATTR, 0); + if (attrdirfd >= 0) { + ret = solaris_unlinkat(attrdirfd, name); + close(attrdirfd); + } + return ret; +#else + errno = ENOSYS; + return -1; +#endif +} + +int rep_setxattr (const char *path, const char *name, const void *value, size_t size, int flags) +{ +#if defined(HAVE_XATTR_XATTR) +#ifndef XATTR_ADDITIONAL_OPTIONS + return setxattr(path, name, value, size, flags); +#else +/* So that we do not recursivly call this function */ +#undef setxattr + int options = 0; + return setxattr(path, name, value, size, 0, options); +#endif +#elif defined(HAVE_XATTR_EA) + return setea(path, name, value, size, flags); +#elif defined(HAVE_XATTR_EXTATTR) + int retval = 0; + int attrnamespace; + const char *attrname; + + if (strncmp(name, "system.", 7) == 0) { + attrnamespace = EXTATTR_NAMESPACE_SYSTEM; + attrname = name + 7; + } else if (strncmp(name, "user.", 5) == 0) { + attrnamespace = EXTATTR_NAMESPACE_USER; + attrname = name + 5; + } else { + errno = EINVAL; + return -1; + } + + if (flags) { + /* Check attribute existence */ + retval = extattr_get_file(path, attrnamespace, attrname, NULL, 0); + if (retval < 0) { + /* REPLACE attribute, that doesn't exist */ + if (flags & XATTR_REPLACE && errno == ENOATTR) { + errno = ENOATTR; + return -1; + } + /* Ignore other errors */ + } + else { + /* CREATE attribute, that already exists */ + if (flags & XATTR_CREATE) { + errno = EEXIST; + return -1; + } + } + } + retval = extattr_set_file(path, attrnamespace, attrname, value, size); + return (retval < 0) ? -1 : 0; +#elif defined(HAVE_XATTR_ATTR) + int myflags = 0; + char *attrname = strchr(name,'.') + 1; + + if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT; + if (flags & XATTR_CREATE) myflags |= ATTR_CREATE; + if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE; + + return attr_set(path, attrname, (const char *)value, size, myflags); +#elif defined(HAVE_ATTROPEN) + int ret = -1; + int myflags = O_RDWR; + int attrfd; + if (flags & XATTR_CREATE) myflags |= O_EXCL; + if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT; + attrfd = solaris_attropen(path, name, myflags, (mode_t) SOLARIS_ATTRMODE); + if (attrfd >= 0) { + ret = solaris_write_xattr(attrfd, value, size); + close(attrfd); + } + return ret; +#else + errno = ENOSYS; + return -1; +#endif +} + +int rep_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags) +{ +#if defined(HAVE_XATTR_XATTR) +#ifndef XATTR_ADDITIONAL_OPTIONS + return fsetxattr(filedes, name, value, size, flags); +#else +/* So that we do not recursivly call this function */ +#undef fsetxattr + int options = 0; + return fsetxattr(filedes, name, value, size, 0, options); +#endif +#elif defined(HAVE_XATTR_EA) + return fsetea(filedes, name, value, size, flags); +#elif defined(HAVE_XATTR_EXTATTR) + int retval = 0; + int attrnamespace; + const char *attrname; + + if (strncmp(name, "system.", 7) == 0) { + attrnamespace = EXTATTR_NAMESPACE_SYSTEM; + attrname = name + 7; + } else if (strncmp(name, "user.", 5) == 0) { + attrnamespace = EXTATTR_NAMESPACE_USER; + attrname = name + 5; + } else { + errno = EINVAL; + return -1; + } + + if (flags) { + /* Check attribute existence */ + retval = extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0); + if (retval < 0) { + /* REPLACE attribute, that doesn't exist */ + if (flags & XATTR_REPLACE && errno == ENOATTR) { + errno = ENOATTR; + return -1; + } + /* Ignore other errors */ + } + else { + /* CREATE attribute, that already exists */ + if (flags & XATTR_CREATE) { + errno = EEXIST; + return -1; + } + } + } + retval = extattr_set_fd(filedes, attrnamespace, attrname, value, size); + return (retval < 0) ? -1 : 0; +#elif defined(HAVE_XATTR_ATTR) + int myflags = 0; + char *attrname = strchr(name,'.') + 1; + + if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT; + if (flags & XATTR_CREATE) myflags |= ATTR_CREATE; + if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE; + + return attr_setf(filedes, attrname, (const char *)value, size, myflags); +#elif defined(HAVE_ATTROPEN) + int ret = -1; + int myflags = O_RDWR | O_XATTR; + int attrfd; + if (flags & XATTR_CREATE) myflags |= O_EXCL; + if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT; + attrfd = solaris_openat(filedes, name, myflags, (mode_t) SOLARIS_ATTRMODE); + if (attrfd >= 0) { + ret = solaris_write_xattr(attrfd, value, size); + close(attrfd); + } + return ret; +#else + errno = ENOSYS; + return -1; +#endif +} + +/************************************************************************** + helper functions for Solaris' EA support +****************************************************************************/ +#ifdef HAVE_ATTROPEN +static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size) +{ + struct stat sbuf; + + if (fstat(attrfd, &sbuf) == -1) { + errno = ENOATTR; + return -1; + } + + /* This is to return the current size of the named extended attribute */ + if (size == 0) { + return sbuf.st_size; + } + + /* check size and read xattr */ + if (sbuf.st_size > size) { + errno = ERANGE; + return -1; + } + + return read(attrfd, value, sbuf.st_size); +} + +static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size) +{ + ssize_t len = 0; + DIR *dirp; + struct dirent *de; + int newfd = dup(attrdirfd); + /* CAUTION: The originating file descriptor should not be + used again following the call to fdopendir(). + For that reason we dup() the file descriptor + here to make things more clear. */ + dirp = fdopendir(newfd); + + while ((de = readdir(dirp))) { + size_t listlen = strlen(de->d_name) + 1; + if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) { + /* we don't want "." and ".." here: */ + continue; + } + + if (size == 0) { + /* return the current size of the list of extended attribute names*/ + len += listlen; + } else { + /* check size and copy entrieÑ• + nul into list. */ + if ((len + listlen) > size) { + errno = ERANGE; + len = -1; + break; + } else { + strlcpy(list + len, de->d_name, listlen); + len += listlen; + } + } + } + + if (closedir(dirp) == -1) { + return -1; + } + return len; +} + +static int solaris_unlinkat(int attrdirfd, const char *name) +{ + if (unlinkat(attrdirfd, name, 0) == -1) { + if (errno == ENOENT) { + errno = ENOATTR; + } + return -1; + } + return 0; +} + +static int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode) +{ + int filedes = attropen(path, attrpath, oflag, mode); + if (filedes == -1) { + if (errno == EINVAL) { + errno = ENOTSUP; + } else { + errno = ENOATTR; + } + } + return filedes; +} + +static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode) +{ + int filedes = openat(fildes, path, oflag, mode); + if (filedes == -1) { + if (errno == EINVAL) { + errno = ENOTSUP; + } else { + errno = ENOATTR; + } + } + return filedes; +} + +static int solaris_write_xattr(int attrfd, const char *value, size_t size) +{ + if ((ftruncate(attrfd, 0) == 0) && (write(attrfd, value, size) == size)) { + return 0; + } else { + return -1; + } +} +#endif /*HAVE_ATTROPEN*/ + + diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.6.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.6.sigs new file mode 100644 index 0000000..961c1a8 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.6.sigs @@ -0,0 +1,6 @@ +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.7.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.7.sigs new file mode 100644 index 0000000..961c1a8 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.7.sigs @@ -0,0 +1,6 @@ +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.8.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.8.sigs new file mode 100644 index 0000000..961c1a8 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.8.sigs @@ -0,0 +1,6 @@ +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.0.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.0.sigs new file mode 100644 index 0000000..961c1a8 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.0.sigs @@ -0,0 +1,6 @@ +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.1.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.1.sigs new file mode 100644 index 0000000..961c1a8 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.1.sigs @@ -0,0 +1,6 @@ +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.10.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.10.sigs new file mode 100644 index 0000000..9d4d4d1 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.10.sigs @@ -0,0 +1,16 @@ +_pytalloc_check_type: int (PyObject *, const char *) +_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) +_pytalloc_get_ptr: void *(PyObject *) +_pytalloc_get_type: void *(PyObject *, const char *) +pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) +pytalloc_BaseObject_check: int (PyObject *) +pytalloc_BaseObject_size: size_t (void) +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *) +pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *) +pytalloc_GetBaseObjectType: PyTypeObject *(void) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.11.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.11.sigs new file mode 100644 index 0000000..9d4d4d1 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.11.sigs @@ -0,0 +1,16 @@ +_pytalloc_check_type: int (PyObject *, const char *) +_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) +_pytalloc_get_ptr: void *(PyObject *) +_pytalloc_get_type: void *(PyObject *, const char *) +pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) +pytalloc_BaseObject_check: int (PyObject *) +pytalloc_BaseObject_size: size_t (void) +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *) +pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *) +pytalloc_GetBaseObjectType: PyTypeObject *(void) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.12.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.12.sigs new file mode 100644 index 0000000..9d4d4d1 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.12.sigs @@ -0,0 +1,16 @@ +_pytalloc_check_type: int (PyObject *, const char *) +_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) +_pytalloc_get_ptr: void *(PyObject *) +_pytalloc_get_type: void *(PyObject *, const char *) +pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) +pytalloc_BaseObject_check: int (PyObject *) +pytalloc_BaseObject_size: size_t (void) +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *) +pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *) +pytalloc_GetBaseObjectType: PyTypeObject *(void) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.13.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.13.sigs new file mode 100644 index 0000000..9d4d4d1 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.13.sigs @@ -0,0 +1,16 @@ +_pytalloc_check_type: int (PyObject *, const char *) +_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) +_pytalloc_get_ptr: void *(PyObject *) +_pytalloc_get_type: void *(PyObject *, const char *) +pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) +pytalloc_BaseObject_check: int (PyObject *) +pytalloc_BaseObject_size: size_t (void) +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *) +pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *) +pytalloc_GetBaseObjectType: PyTypeObject *(void) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.14.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.14.sigs new file mode 100644 index 0000000..9d4d4d1 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.14.sigs @@ -0,0 +1,16 @@ +_pytalloc_check_type: int (PyObject *, const char *) +_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) +_pytalloc_get_ptr: void *(PyObject *) +_pytalloc_get_type: void *(PyObject *, const char *) +pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) +pytalloc_BaseObject_check: int (PyObject *) +pytalloc_BaseObject_size: size_t (void) +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *) +pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *) +pytalloc_GetBaseObjectType: PyTypeObject *(void) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.15.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.15.sigs new file mode 100644 index 0000000..9d4d4d1 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.15.sigs @@ -0,0 +1,16 @@ +_pytalloc_check_type: int (PyObject *, const char *) +_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) +_pytalloc_get_ptr: void *(PyObject *) +_pytalloc_get_type: void *(PyObject *, const char *) +pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) +pytalloc_BaseObject_check: int (PyObject *) +pytalloc_BaseObject_size: size_t (void) +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *) +pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *) +pytalloc_GetBaseObjectType: PyTypeObject *(void) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.16.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.16.sigs new file mode 100644 index 0000000..9d4d4d1 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.16.sigs @@ -0,0 +1,16 @@ +_pytalloc_check_type: int (PyObject *, const char *) +_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) +_pytalloc_get_ptr: void *(PyObject *) +_pytalloc_get_type: void *(PyObject *, const char *) +pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) +pytalloc_BaseObject_check: int (PyObject *) +pytalloc_BaseObject_size: size_t (void) +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *) +pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *) +pytalloc_GetBaseObjectType: PyTypeObject *(void) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.2.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.2.sigs new file mode 100644 index 0000000..961c1a8 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.2.sigs @@ -0,0 +1,6 @@ +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.3.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.3.sigs new file mode 100644 index 0000000..961c1a8 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.3.sigs @@ -0,0 +1,6 @@ +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.4.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.4.sigs new file mode 100644 index 0000000..961c1a8 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.4.sigs @@ -0,0 +1,6 @@ +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.5.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.5.sigs new file mode 100644 index 0000000..961c1a8 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.5.sigs @@ -0,0 +1,6 @@ +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.6.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.6.sigs new file mode 100644 index 0000000..666fec0 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.6.sigs @@ -0,0 +1,13 @@ +_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) +_pytalloc_get_ptr: void *(PyObject *) +_pytalloc_get_type: void *(PyObject *, const char *) +pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) +pytalloc_BaseObject_check: int (PyObject *) +pytalloc_BaseObject_size: size_t (void) +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GetBaseObjectType: PyTypeObject *(void) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.7.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.7.sigs new file mode 100644 index 0000000..666fec0 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.7.sigs @@ -0,0 +1,13 @@ +_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) +_pytalloc_get_ptr: void *(PyObject *) +_pytalloc_get_type: void *(PyObject *, const char *) +pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) +pytalloc_BaseObject_check: int (PyObject *) +pytalloc_BaseObject_size: size_t (void) +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GetBaseObjectType: PyTypeObject *(void) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.8.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.8.sigs new file mode 100644 index 0000000..666fec0 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.8.sigs @@ -0,0 +1,13 @@ +_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) +_pytalloc_get_ptr: void *(PyObject *) +_pytalloc_get_type: void *(PyObject *, const char *) +pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) +pytalloc_BaseObject_check: int (PyObject *) +pytalloc_BaseObject_size: size_t (void) +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GetBaseObjectType: PyTypeObject *(void) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.9.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.9.sigs new file mode 100644 index 0000000..9d4d4d1 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.9.sigs @@ -0,0 +1,16 @@ +_pytalloc_check_type: int (PyObject *, const char *) +_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) +_pytalloc_get_ptr: void *(PyObject *) +_pytalloc_get_type: void *(PyObject *, const char *) +pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) +pytalloc_BaseObject_check: int (PyObject *) +pytalloc_BaseObject_size: size_t (void) +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *) +pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *) +pytalloc_GetBaseObjectType: PyTypeObject *(void) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.2.0.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.2.0.sigs new file mode 100644 index 0000000..62f066f --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.2.0.sigs @@ -0,0 +1,15 @@ +_pytalloc_check_type: int (PyObject *, const char *) +_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) +_pytalloc_get_ptr: void *(PyObject *) +_pytalloc_get_type: void *(PyObject *, const char *) +pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) +pytalloc_BaseObject_check: int (PyObject *) +pytalloc_BaseObject_size: size_t (void) +pytalloc_Check: int (PyObject *) +pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *) +pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *) +pytalloc_GetBaseObjectType: PyTypeObject *(void) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.2.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.2.sigs new file mode 100644 index 0000000..6e236d5 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.2.sigs @@ -0,0 +1,62 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.3.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.3.sigs new file mode 100644 index 0000000..6e236d5 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.3.sigs @@ -0,0 +1,62 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.4.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.4.sigs new file mode 100644 index 0000000..6e236d5 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.4.sigs @@ -0,0 +1,62 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.5.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.5.sigs new file mode 100644 index 0000000..6e236d5 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.5.sigs @@ -0,0 +1,62 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.6.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.6.sigs new file mode 100644 index 0000000..6e236d5 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.6.sigs @@ -0,0 +1,62 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.7.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.7.sigs new file mode 100644 index 0000000..6e236d5 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.7.sigs @@ -0,0 +1,62 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.8.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.8.sigs new file mode 100644 index 0000000..15a9e95 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.8.sigs @@ -0,0 +1,63 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.0.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.0.sigs new file mode 100644 index 0000000..eae12cc --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.0.sigs @@ -0,0 +1,64 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.1.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.1.sigs new file mode 100644 index 0000000..eae12cc --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.1.sigs @@ -0,0 +1,64 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.10.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.10.sigs new file mode 100644 index 0000000..9969ce3 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.10.sigs @@ -0,0 +1,65 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_test_get_magic: int (void) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.11.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.11.sigs new file mode 100644 index 0000000..9969ce3 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.11.sigs @@ -0,0 +1,65 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_test_get_magic: int (void) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.12.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.12.sigs new file mode 100644 index 0000000..9969ce3 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.12.sigs @@ -0,0 +1,65 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_test_get_magic: int (void) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.13.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.13.sigs new file mode 100644 index 0000000..9969ce3 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.13.sigs @@ -0,0 +1,65 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_test_get_magic: int (void) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.14.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.14.sigs new file mode 100644 index 0000000..9969ce3 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.14.sigs @@ -0,0 +1,65 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_test_get_magic: int (void) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.15.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.15.sigs new file mode 100644 index 0000000..9969ce3 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.15.sigs @@ -0,0 +1,65 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_test_get_magic: int (void) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.16.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.16.sigs new file mode 100644 index 0000000..9969ce3 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.16.sigs @@ -0,0 +1,65 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_test_get_magic: int (void) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.2.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.2.sigs new file mode 100644 index 0000000..eae12cc --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.2.sigs @@ -0,0 +1,64 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.3.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.3.sigs new file mode 100644 index 0000000..eae12cc --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.3.sigs @@ -0,0 +1,64 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.4.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.4.sigs new file mode 100644 index 0000000..9969ce3 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.4.sigs @@ -0,0 +1,65 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_test_get_magic: int (void) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.5.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.5.sigs new file mode 100644 index 0000000..9969ce3 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.5.sigs @@ -0,0 +1,65 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_test_get_magic: int (void) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.6.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.6.sigs new file mode 100644 index 0000000..9969ce3 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.6.sigs @@ -0,0 +1,65 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_test_get_magic: int (void) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.7.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.7.sigs new file mode 100644 index 0000000..9969ce3 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.7.sigs @@ -0,0 +1,65 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_test_get_magic: int (void) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.8.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.8.sigs new file mode 100644 index 0000000..9969ce3 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.8.sigs @@ -0,0 +1,65 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_test_get_magic: int (void) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.9.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.9.sigs new file mode 100644 index 0000000..9969ce3 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.9.sigs @@ -0,0 +1,65 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_test_get_magic: int (void) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.2.0.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.2.0.sigs new file mode 100644 index 0000000..9969ce3 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/ABI/talloc-2.2.0.sigs @@ -0,0 +1,65 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_test_get_magic: int (void) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/Makefile b/ldb-2.0.8/lib/talloc/Makefile new file mode 100644 index 0000000..db2275c --- /dev/null +++ b/ldb-2.0.8/lib/talloc/Makefile @@ -0,0 +1,68 @@ +# simple makefile wrapper to run waf + +WAF_BIN=`PATH=buildtools/bin:../../buildtools/bin:$$PATH which waf` +WAF_BINARY=$(PYTHON) $(WAF_BIN) +WAF=PYTHONHASHSEED=1 WAF_MAKE=1 $(WAF_BINARY) + +all: + $(WAF) build + +install: + $(WAF) install + +uninstall: + $(WAF) uninstall + +test: + $(WAF) test $(TEST_OPTIONS) + +testenv: + $(WAF) test --testenv $(TEST_OPTIONS) + +quicktest: + $(WAF) test --quick $(TEST_OPTIONS) + +dist: + touch .tmplock + WAFLOCK=.tmplock $(WAF) dist + +distcheck: + touch .tmplock + WAFLOCK=.tmplock $(WAF) distcheck + +clean: + $(WAF) clean + +distclean: + $(WAF) distclean + +reconfigure: configure + $(WAF) reconfigure + +show_waf_options: + $(WAF) --help + +# some compatibility make targets +everything: all + +testsuite: all + +check: test + +torture: all + +# this should do an install as well, once install is finished +installcheck: test + +etags: + $(WAF) etags + +ctags: + $(WAF) ctags + +pydoctor: + $(WAF) pydoctor + +bin/%:: FORCE + $(WAF) --targets=`basename $@` +FORCE: diff --git a/ldb-2.0.8/lib/talloc/NEWS b/ldb-2.0.8/lib/talloc/NEWS new file mode 100644 index 0000000..e5b3aa0 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/NEWS @@ -0,0 +1,13 @@ +1.0.1 26 May 2007 + + BUGS + + * Set name of correctly when using talloc_append_string() (metze) + + LICENSE + + * Change license of files in lib/replace to LGPL (was GPL). (jelmer) + +1.0.0 30 April 2007 + + Initial release. diff --git a/ldb-2.0.8/lib/talloc/compat/talloc_compat1.c b/ldb-2.0.8/lib/talloc/compat/talloc_compat1.c new file mode 100644 index 0000000..519e8c3 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/compat/talloc_compat1.c @@ -0,0 +1,51 @@ +/* + Samba trivial allocation library - compat functions + + Copyright (C) Stefan Metzmacher 2009 + + ** NOTE! The following LGPL license applies to the talloc + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * This file contains only function to build a + * compat talloc.so.1 library on top of talloc.so.2 + */ + +#include "replace.h" +#include "talloc.h" + +void *_talloc_reference(const void *context, const void *ptr); +void *_talloc_reference(const void *context, const void *ptr) { + return _talloc_reference_loc(context, ptr, + "Called from talloc compat1 " + "_talloc_reference"); +} + +void *_talloc_steal(const void *new_ctx, const void *ptr); +void *_talloc_steal(const void *new_ctx, const void *ptr) +{ + return talloc_reparent(talloc_parent(ptr), new_ctx, ptr); +} + +#undef talloc_free +int talloc_free(void *ptr); +int talloc_free(void *ptr) +{ + return talloc_unlink(talloc_parent(ptr), ptr); +} + diff --git a/ldb-2.0.8/lib/talloc/compat/talloc_compat1.mk b/ldb-2.0.8/lib/talloc/compat/talloc_compat1.mk new file mode 100644 index 0000000..d1817f0 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/compat/talloc_compat1.mk @@ -0,0 +1,21 @@ +talloccompatdir := $(tallocdir)/compat + +TALLOC_COMPAT1_VERSION_MAJOR = 1 +TALLOC_COMPAT1_OBJ = $(talloccompatdir)/talloc_compat1.o + +TALLOC_COMPAT1_SOLIB = libtalloc-compat1-$(TALLOC_VERSION).$(SHLIBEXT) +TALLOC_COMPAT1_SONAME = libtalloc.$(SHLIBEXT).$(TALLOC_COMPAT1_VERSION_MAJOR) + +$(TALLOC_COMPAT1_SOLIB): $(TALLOC_COMPAT1_OBJ) $(TALLOC_SOLIB) + $(SHLD) $(SHLD_FLAGS) -o $@ $(TALLOC_COMPAT1_OBJ) \ + $(TALLOC_SOLIB) $(SONAMEFLAG)$(TALLOC_COMPAT1_SONAME) + +all:: $(TALLOC_COMPAT1_SOLIB) + +install:: + ${INSTALLCMD} -d $(DESTDIR)$(libdir) + ${INSTALLCMD} -m 755 $(TALLOC_COMPAT1_SOLIB) $(DESTDIR)$(libdir) + +clean:: + rm -f $(TALLOC_COMPAT1_OBJ) $(TALLOC_COMPAT1_SOLIB) + diff --git a/ldb-2.0.8/lib/talloc/configure b/ldb-2.0.8/lib/talloc/configure new file mode 100755 index 0000000..d8a8d2a --- /dev/null +++ b/ldb-2.0.8/lib/talloc/configure @@ -0,0 +1,21 @@ +#!/bin/sh + +PREVPATH=`dirname $0` + +if [ -f $PREVPATH/../../buildtools/bin/waf ]; then + WAF=../../buildtools/bin/waf +elif [ -f $PREVPATH/buildtools/bin/waf ]; then + WAF=./buildtools/bin/waf +else + echo "replace: Unable to find waf" + exit 1 +fi + +# using JOBS=1 gives maximum compatibility with +# systems like AIX which have broken threading in python +JOBS=1 +export JOBS + +cd . || exit 1 +$PYTHON $WAF configure "$@" || exit 1 +cd $PREVPATH diff --git a/ldb-2.0.8/lib/talloc/doc/context.png b/ldb-2.0.8/lib/talloc/doc/context.png new file mode 100644 index 0000000000000000000000000000000000000000..48a6ca0e6a0ecce971f1867a960681a3b157cc3c GIT binary patch literal 4715 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 literal 0 HcmV?d00001 diff --git a/ldb-2.0.8/lib/talloc/doc/mainpage.dox b/ldb-2.0.8/lib/talloc/doc/mainpage.dox new file mode 100644 index 0000000..ece6ccb --- /dev/null +++ b/ldb-2.0.8/lib/talloc/doc/mainpage.dox @@ -0,0 +1,111 @@ +/** + * @mainpage + * + * talloc is a hierarchical, reference counted memory pool system with + * destructors. It is the core memory allocator used in Samba. + * + * @section talloc_download Download + * + * You can download the latest releases of talloc from the + * talloc directory + * on the samba public source archive. + * + * @section main-tutorial Tutorial + * + * You should start by reading @subpage libtalloc_tutorial, then reading the documentation of + * the interesting functions as you go. + + * @section talloc_bugs Discussion and bug reports + * + * talloc does not currently have its own mailing list or bug tracking system. + * For now, please use the + * samba-technical + * mailing list, and the + * Samba bugzilla + * bug tracking system. + * + * @section talloc_devel Development + * You can download the latest code either via git or rsync. + * + * To fetch via git see the following guide: + * + * Using Git for Samba Development + * + * Once you have cloned the tree switch to the master branch and cd into the + * lib/tevent directory. + * + * To fetch via rsync use this command: + * + * rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/talloc . + * + * @section talloc_preample Preamble + * + * talloc is a hierarchical, reference counted memory pool system with + * destructors. + * + * Perhaps the biggest difference from other memory pool systems is that there + * is no distinction between a "talloc context" and a "talloc pointer". Any + * pointer returned from talloc() is itself a valid talloc context. This means + * you can do this: + * + * @code + * struct foo *X = talloc(mem_ctx, struct foo); + * X->name = talloc_strdup(X, "foo"); + * @endcode + * + * The pointer X->name would be a "child" of the talloc context "X" which is + * itself a child of mem_ctx. So if you do talloc_free(mem_ctx) then it is all + * destroyed, whereas if you do talloc_free(X) then just X and X->name are + * destroyed, and if you do talloc_free(X->name) then just the name element of + * X is destroyed. + * + * If you think about this, then what this effectively gives you is an n-ary + * tree, where you can free any part of the tree with talloc_free(). + * + * If you find this confusing, then run the testsuite to watch talloc in + * action. You may also like to add your own tests to testsuite.c to clarify + * how some particular situation is handled. + * + * @section talloc_performance Performance + * + * All the additional features of talloc() over malloc() do come at a price. We + * have a simple performance test in Samba4 that measures talloc() versus + * malloc() performance, and it seems that talloc() is about 4% slower than + * malloc() on my x86 Debian Linux box. For Samba, the great reduction in code + * complexity that we get by using talloc makes this worthwhile, especially as + * the total overhead of talloc/malloc in Samba is already quite small. + * + * @section talloc_named Named blocks + * + * Every talloc chunk has a name that can be used as a dynamic type-checking + * system. If for some reason like a callback function you had to cast a + * "struct foo *" to a "void *" variable, later you can safely reassign the + * "void *" pointer to a "struct foo *" by using the talloc_get_type() or + * talloc_get_type_abort() macros. + * + * @code + * struct foo *X = talloc_get_type_abort(ptr, struct foo); + * @endcode + * + * This will abort if "ptr" does not contain a pointer that has been created + * with talloc(mem_ctx, struct foo). + * + * @section talloc_threading Multi-threading + * + * talloc itself does not deal with threads. It is thread-safe (assuming the + * underlying "malloc" is), as long as each thread uses different memory + * contexts. + * + * If two threads uses the same context then they need to synchronize in order + * to be safe. In particular: + * + * - when using talloc_enable_leak_report(), giving directly NULL as a parent + * context implicitly refers to a hidden "null context" global variable, so + * this should not be used in a multi-threaded environment without proper + * synchronization. In threaded code turn off null tracking using + * talloc_disable_null_tracking(). + * - the context returned by talloc_autofree_context() is also global so + * shouldn't be used by several threads simultaneously without + * synchronization. + * + */ diff --git a/ldb-2.0.8/lib/talloc/doc/stealing.png b/ldb-2.0.8/lib/talloc/doc/stealing.png new file mode 100644 index 0000000000000000000000000000000000000000..8833e06a187709fe650ed436e8da8c02eaa68134 GIT binary patch literal 6994 zcmbW6bx@V>*7rApz)=JVL1_Vz?h@$+>F(}Ex&@S01W{UAYE#l7h?IbIBOzT}N{Fg^O>L!lYpZEpb~uUA zV1}E-V&-Su;HZs`$F0dSyX~mnB07(7Lr9vS>8w5yyzou^X;n7%n}wmmUy*X1 zon(^v7Iz0t&_V)EC+gNz9Hr+|h)SW_VoBCsMvGA07?<%Q^^(%8U&vaasw>7m_8&*jCLua{SC zZ7thT3nsG}kyRn^oiICRw22~v8c z#zpZpa+{h0&W^T(goNhj=l>LmY2?EM<>ga(9Hzd#y3PJp1f#OD^7lk}>*%O^d*nU0 z`a;(|cX#&&k1b+O%O9UDdIrJ<+P3MLn9e(eFUuW%R=0#;6uF!xaaz^tJL>DFPS+ta z9(DKh9RHrI@ZPtyva;enuDz(!RlL>EoTb z(t4xqtiq+GC8y?#5B!28?xuGy6qqfU|>m-sjA$%5}A`H-*>ExqLqQ0jHP1EF5g)CUJ)7(bmrz z#~FT3PEG}lwXH1&Tiet0t8)zhX9@?|5#HY3t)X{ZpFbb6uQKvK9G$zm^u%HqAXr{r zcH{RS$yZ4(=3!vCRY5V(cFgDTTU$cnWk(S=CnpK75-9($lO zRaI3|!v<3L^F9M@-Q98+7#R0(K6IIDXlMu)25yWL=;-LEZ(7IEw43e)p<-lkhl;tl z?5z!ER}tk01O#-r6n(u#+LA#oEq}vwN0v4Ridk0<);Fuzq6v{8vi|qgF{`N{W@axrC(T zp2?r;q>ljkUDDc8vUjD~amEHcIKS$d$XT7|0Zb!9cvrf^2%&tK;n% zYFSm-jU%_kR zrE|eIZ<7o9Kw_t*rM-)bdnxuXO;O8>o%Y=mSO#I#Vb|mIUxfUvByc4R&;VDk&+cDCpSO*eFr5s+bfH#d_j%kpHklE({Hh4)Q}^Q&Uq!<_L-o~-Y$ z_Uq~BfY?8xr4{n~TUJ5)QY;hQGtc&JtPD-ME-j`QRjj#%#l$tkQ z%E)|=r&l|_xL90VynXvN>Wv$qJf7=AkBDDa`=1?2MiE}@w&KW@)9K1GzNt*dpnsTuKcAkS9zyIK+^XUA=;zNIyu7?-8|>5(&NE6T9qsMhJUkvpju1&; zaEy$M_a1R`bBkq`U9fW`$=okBzB1qw7-MmB}5dudj#WI9fhDJcQ5E z$liJ-79m0PUT*mcc1$jB)g?xf_xI15(yXj3-k>RWWWe!^CkS1KTTDA2l|IgyHX*aF z+xB!_->kcvTPnZ1?b#teXbl;;qkQ%txW#)RjT9PL@|ZkrdMWxJKYoCmBa4eM?hubO zrM8=P1#X0QnRDF70{c7(ypM&>{TSsG6Escud{^A*M%AV^Gb1AjyXi~z!$dd@axRx2 ziR@E)O@U`e4uOGzOPp(hii(O50K-F{Hz3U*@G;ZmMGy9oY{J6A4gz!$G+jLjto{u<&%Ffmn60A}MB8l^cmK7f# zACqq78n~q0c*&N(gIK0Bh!42kzrE_xe>FZn9>69nH1tUIF0aE>rCBHT)2B~2B;;*u z3O!0TdUqtk;nhBB(Fld$NPgdHzlc7=FIe>U$GHN;pNA#~a z#TnHrcl^;|zzD{`8&g?aOu| zBc$P%Dewa61hU6UADLKKguHf*$NSCE)J6Jd>%J88!Bc<#i$aYeeSQ6Uq1xi&Eg+es zq@?t~%agVUeD+8YD;b(N24X zE-l@eC^x&OmnReFcetTpXlUr+QLWAZDb2!zD}v80Vqsz7;o%`GD{E$!eIC)tMcmuo zZZTc!0!sY#8;c0;U%vo&-^Inn-~WrB36pGGUtgbD=bOX5y%Xmm3NGB_e3WXZIdT$` zsI+EaS9b(i_Duw0KmvhyK@0rOh5P@)+yC#6P=^MwAnNmKYyWnAOmJt{6P=HcOqM9opPfjk9^KC4JhN!j1uzj*_N|E}_biyx22Mn;xaSBt#LL?|KP z$wM-Sq^l|`Q@L#LIy8J60V)BXdOk2Svas~^_6ma9RoRV$G8#4c!J(gk0q5lAvfqzp zH|s#^*Ks_2*aCb>72DR$K6Qoez%t_Z1Y6XgRj zI3h{OSCJS|?F)J}js;%3yYsC;gp)NT_`qy@q;DcI&d$z?=)%!NNd;a-dJDUAYp4-^01MKnuoZ5{cM~k#N+uFWsFtM>Y!z#du zKsdhyUIjP_i2yJ`{@L2v0zmh4ce7EQW=YraSoM+Ki?O$}dnPNp?m8ZUCVIZ@*?b0` z%5As>X@!f_wE+Br&;bHNK|z6SC7b=?xnpQ%X6EPTcXfF|LQJg9L@0V!o_2V0@(De? zEFHnnx|>k?TuM}1eLa7BPhlYgfI3h`bksIGH}~QG{;*e-YQe#LYnZZp}3}7Z!E{h3z>S7|fKJv{pOLOkKt!kw}dq&6zsauwKj6l@$idhod4? zv2ST6o0eu8JgKFkzt$pJkNUnkKY70N9il`FsqM1ZaR&nq($9wQ&0`nb=-tlTnhskTw7av;<_T> zf6B$c5ZP;qk2b%vLqS1dq^<3>^gR|_L-rl*tI*Ko#KhXVI%cD$>HdCJIyyQKO-jnI zgM;kU)FEBw;FlHJNT_3u+-_Oy{%Yy}D5%y*BOBK`@8#{?B8qBFHGm3*lkerZH-x>p zc@FS!BO5&`?~L`A0sNtk0kSz==TKzTb>*ZVr@`l!RIY1Zkl?N!G$a!q0^V_y z;gc0s)Majnu-1a&V(!nZkKT0w0fu6eZT$XiZ)zH>B1K4Ym3vPofH*r~L)IpZ?-o1G@lszOEy=ZPn%Ex`DO){r$nX zW#i;!W!X77)pWx}(8#Q9Z04WWL7gM5wZUlCixaks+DSyok zlLq_0d9%HZQmkGCRMb`wY$HjN zCt_jr^6DxhkME#$B>)192A!m3V^hBTP9IDePZ->U9@ANbME+K`c5v8QUoSY#<_XgL z-|@J)zKyB>Tv{EAF$SVMW8ffuSBf zf(X7V0Sy)ZalYnNxBFO1N=leiFKC0C!a?#QB(|P`A@7E>U4Mc=O>Oun;iVhDK~oMY zLLsxpmkA2-CXX%MvpC>Aa={*n^*wzSq7d7*0qe?#;-QTJ7rK|v+rn{c2a&A0y1J%j zW*S}Hydis2Cu`^r-ae$fL-|W7r3H>GF)e@bG6#$eQ zL5SqPS0&zXOF)2)w5EWI)1Brka%^IR;AhuW#X}Z5%wVX&uNwe$u8+A?{Ku!sA#wPu z5my-R`aSsaWyn;^IZ=$Hi;U!7I*RST|j$^?+G8-%lpIBd5XQ3N#l5!!?w~`B1 zG7d8$lHIRwbidy2Q+&u+2(9fjcPk8DD@o$V)*VmIfAr5_(FV&6KI=5wtRwyF!J*s9 z^a~m8g%P^{J2*IGERFWlr%zyb{6i9TcGy^0Ba=iSA?RQ48dS`Z zRlea;vHIsT;-0;y?gRA$5@ZdQ*Gr$`-W(UTGr)J>NuJL@VRIWtN@EneD~v?hg~H$g zgNi27N)K+8nE!mi>GJ{I5s8cXe+JKRZ?=otso)=O|7Wl-MlrKOPWV5AGYl%W$tpFu zVmlXSngi2s{d0>dgMB!xf?vr``PLwnZAL}yB(L|~&}~8XAGH%J}+~6kaFQVQx?70U&xi8=K6^>#ajaLsK5R-u;Y7yEid0 zd6%moX@M7;Mi3VTMG+&O|30X(ppZ|oGzDHNnwlO^Tplv`9Q}Tf(o4=}{Nj8$@*X2} zEE@zFA3t7&+F)i(z_bmM{|m{-0;^c90u8o&DnWQqZWnx^K;_V(-{yQ8CH;NMmX zb(_7PPR;LA1d`-C=A8j6^Jb6J_*@nsQ_rwpMIW(((=>j$zI>lBSoNjO@1GP}FTkxJ zg^H0#pUJF^Y83@JvN^gqqoT;g4R%G(ujnN{I z{iCLK07SQJfF>*`hM_f-z?_tlQWU@z)lSUkY|N_11;*n~oONvUmJ$=PC5Iw|vOZ=P zGSDVR687?53=jvgjY@%Z4s|GWkFOiX{~_uZEL`PTSz-z4Rn^rW`d4d=1acgRNl2h@ zcAum|@ORW!Xul@Vlm>%q^gZ5=d-N>y4#}q!R!su~L9-4lPft%kA9}S<>RMWM4U*;B zq~zq=&%ry%G;}#!Tjxz&b$I);%4Axcw$)U+qmdP7F@oTE?ER7-r(rr53 zD8hfN2)%oiO~P;+sMWdV4_jQ<`)+$Tw8b+b{?s4Kx0nMOZ6ad4{k0lx1XkVc16l`P_O?X zgr7W?D8xnW?U@RQq1ctit~LN>jBB{ z+D+*#+3&rIT)k(z$R12lJ<%K(*xmq=M(m`%?gp2qfKq6}KAR zJLFMczFe#i=Z#)IQM(Bko*r;oz#xrHAtdndq3Gezj--~>IL>VwFJlG-;_Fk?|MNBf^%D{C$`xWyyU%e|E^-Fu OgOHU}lqeB14*nm1k&3YZ literal 0 HcmV?d00001 diff --git a/ldb-2.0.8/lib/talloc/doc/tutorial_bestpractices.dox b/ldb-2.0.8/lib/talloc/doc/tutorial_bestpractices.dox new file mode 100644 index 0000000..3634446 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/doc/tutorial_bestpractices.dox @@ -0,0 +1,192 @@ +/** +@page libtalloc_bestpractices Chapter 7: Best practises + +The following sections contain several best practices and good manners that were +found by the Samba and +SSSD developers over the years. +These will help you to write code which is better, easier to debug and with as +few (hopefully none) memory leaks as possible. + +@section bp-hierarchy Keep the context hierarchy steady + +The talloc is a hierarchy memory allocator. The hierarchy nature is what makes +the programming more error proof. It makes the memory easier to manage and to +free. Therefore, the first thing we should have on our mind is: always project +your data structures into the talloc context hierarchy. + +That means if we have a structure, we should always use it as a parent context +for its elements. This way we will not encounter any troubles when freeing the +structure or when changing its parent. The same rule applies for arrays. + +For example, the structure user from section @ref context-hierarchy +should be created with the context hierarchy illustrated on the next image. + +@image html context_tree.png + +@section bp-tmpctx Every function should use its own context + +It is a good practice to create a temporary talloc context at the function +beginning and free the context just before the return statement. All the data +must be allocated on this context or on its children. This ensures that no +memory leaks are created as long as we do not forget to free the temporary +context. + +This pattern applies to both situations - when a function does not return any +dynamically allocated value and when it does. However, it needs a little +extension for the latter case. + +@subsection bp-tmpctx-1 Functions that do not return any dynamically allocated +value + +If the function does not return any value created on the heap, we will just obey +the aforementioned pattern. + +@code +int bar() +{ + int ret; + TALLOC_CTX *tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + ret = ENOMEM; + goto done; + } + /* allocate data on tmp_ctx or on its descendants */ + ret = EOK; +done: + talloc_free(tmp_ctx); + return ret; +} +@endcode + +@subsection bp-tmpctx-2 Functions returning dynamically allocated values + +If our function returns any dynamically allocated data, its first parameter +should always be the destination talloc context. This context serves as a parent +for the output values. But again, we will create the output values as the +descendants of the temporary context. If everything goes well, we will change +the parent of the output values from the temporary to the destination talloc +context. + +This pattern ensures that if an error occurs (e.g. I/O error or insufficient +amount of the memory), all allocated data is freed and no garbage appears on +the destination context. + +@code +int struct_foo_init(TALLOC_CTX *mem_ctx, struct foo **_foo) +{ + int ret; + struct foo *foo = NULL; + TALLOC_CTX *tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + ret = ENOMEM; + goto done; + } + foo = talloc_zero(tmp_ctx, struct foo); + /* ... */ + *_foo = talloc_steal(mem_ctx, foo); + ret = EOK; +done: + talloc_free(tmp_ctx); + return ret; +} +@endcode + +@section bp-null Allocate temporary contexts on NULL + +As it can be seen on the previous listing, instead of allocating the temporary +context directly on mem_ctx, we created a new top level context +using NULL as the parameter for talloc_new() function. +Take a look at the following example: + +@code +char *create_user_filter(TALLOC_CTX *mem_ctx, + uid_t uid, const char *username) +{ + char *filter = NULL; + char *sanitized_username = NULL; + /* tmp_ctx is a child of mem_ctx */ + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + if (tmp_ctx == NULL) { + return NULL; + } + + sanitized_username = sanitize_string(tmp_ctx, username); + if (sanitized_username == NULL) { + talloc_free(tmp_ctx); + return NULL; + } + + filter = talloc_aprintf(tmp_ctx,"(|(uid=%llu)(uname=%s))", + uid, sanitized_username); + if (filter == NULL) { + return NULL; /* tmp_ctx is not freed */ (*@\label{lst:tmp-ctx-3:leak}@*) + } + + /* filter becomes a child of mem_ctx */ + filter = talloc_steal(mem_ctx, filter); + talloc_free(tmp_ctx); + return filter; +} +@endcode + +We forgot to free tmp_ctx before the return statement +in the filter == NULL condition. However, it is created as a child +of mem_ctx context and as such it will be freed as soon as the +mem_ctx is freed. Therefore, no detectable memory leak is created. + +On the other hand, we do not have any way to access the allocated data +and for all we know mem_ctx may exist for the lifetime of our +application. For these reasons this should be considered as a memory leak. How +can we detect if it is unreferenced but still attached to its parent context? +The only way is to notice the mistake in the source code. + +But if we create the temporary context as a top level context, it will not be +freed and memory diagnostic tools +(e.g. valgrind) are able to do their job. + +@section bp-pool Temporary contexts and the talloc pool + +If we want to take the advantage of the talloc pool but also keep to the +pattern introduced in the previous section, we are unable to do it directly. The +best thing to do is to create a conditional build where we can decide how do we +want to create the temporary context. For example, we can create the following +macros: + +@code +#ifdef USE_POOL_CONTEXT + #define CREATE_POOL_CTX(ctx, size) talloc_pool(ctx, size) + #define CREATE_TMP_CTX(ctx) talloc_new(ctx) +#else + #define CREATE_POOL_CTX(ctx, size) talloc_new(ctx) + #define CREATE_TMP_CTX(ctx) talloc_new(NULL) +#endif +@endcode + +Now if our application is under development, we will build it with macro +USE_POOL_CONTEXT undefined. This way, we can use memory diagnostic +utilities to detect memory leaks. + +The release version will be compiled with the macro defined. This will enable +pool contexts and therefore reduce the malloc() calls, which will +end up in a little bit faster processing. + +@code +int struct_foo_init(TALLOC_CTX *mem_ctx, struct foo **_foo) +{ + int ret; + struct foo *foo = NULL; + TALLOC_CTX *tmp_ctx = CREATE_TMP_CTX(mem_ctx); + /* ... */ +} + +errno_t handle_request(TALLOC_CTX mem_ctx) +{ + int ret; + struct foo *foo = NULL; + TALLOC_CTX *pool_ctx = CREATE_POOL_CTX(NULL, 1024); + ret = struct_foo_init(mem_ctx, &foo); + /* ... */ +} +@endcode + +*/ diff --git a/ldb-2.0.8/lib/talloc/doc/tutorial_context.dox b/ldb-2.0.8/lib/talloc/doc/tutorial_context.dox new file mode 100644 index 0000000..b8bfe26 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/doc/tutorial_context.dox @@ -0,0 +1,198 @@ +/** +@page libtalloc_context Chapter 1: Talloc context +@section context Talloc context + +The talloc context is the most important part of this library and is +responsible for every single feature of this memory allocator. It is a logical +unit which represents a memory space managed by talloc. + +From the programmer's point of view, the talloc context is completely +equivalent to a pointer that would be returned by the memory routines from the +C standard library. This means that every context that is returned from the +talloc library can be used directly in functions that do not use talloc +internally. For example we can do the following: + +@code +char *str1 = strdup("I am NOT a talloc context"); +char *str2 = talloc_strdup(NULL, "I AM a talloc context"); + +printf("%d\n", strcmp(str1, str2) == 0); + +free(str1); +talloc_free(str2); /* we can not use free() on str2 */ +@endcode + +This is possible because the context is internally handled as a special +fixed-length structure called talloc chunk. Each chunk stores context metadata +followed by the memory space requested by the programmer. When a talloc +function returns a context (pointer), it will in fact return a pointer to the user +space portion of the talloc chunk. If we to manipulate this context using +talloc functions, the talloc library transforms the user-space pointer back to +the starting address of the chunk. This is also the reason why we were unable +to use free(str2) in the previous example - because +str2 does not point at the beginning of the allocated block of +memory. This is illustrated on the next image: + +@image html context.png + +The type TALLOC_CTX is defined in talloc.h to identify a talloc context in +function parameters. However, this type is just an alias for void +and exists only for semantical reasons - thus we can differentiate between +void * (arbitrary data) and TALLOC_CTX * (talloc +context). + +@subsection metadata Context meta data + +Every talloc context carries several pieces of internal information along with +the allocated memory: + + - name - which is used in reports of context hierarchy and to simulate + a dynamic type system, + - size of the requested memory in bytes - this can be used to determine + the number of elements in arrays, + - attached destructor - which is executed just before the memory block is + about to be freed, + - references to the context + - children and parent contexts - create the hierarchical view on the + memory. + +@section context-hierarchy Hierarchy of talloc context + +Every talloc context contains information about its parent and children. Talloc +uses this information to create a hierarchical model of memory or to be more +precise, it creates an n-ary tree where each node represents a single talloc +context. The root node of the tree is referred to as a top level context - a +context without any parent. + +This approach has several advantages: + + - as a consequence of freeing a talloc context, all of its children + will be properly deallocated as well, + - the parent of a context can be changed at any time, which + results in moving the whole subtree under another node, + - it creates a more natural way of managing data structures. + +@subsection Example + +We have a structure that stores basic information about a user - his/her name, +identification number and groups he/she is a member of: + +@code +struct user { + uid_t uid; + char *username; + size_t num_groups; + char **groups; +}; +@endcode + +We will allocate this structure using talloc. The result will be the following +context tree: + +@image html context_tree.png + +@code +/* create new top level context */ +struct user *user = talloc(NULL, struct user); + +user->uid = 1000; +user->num_groups = N; + +/* make user the parent of following contexts */ +user->username = talloc_strdup(user, "Test user"); +user->groups = talloc_array(user, char*, user->num_groups); + +for (i = 0; i < user->num_groups; i++) { + /* make user->groups the parent of following context */ + user->groups[i] = talloc_asprintf(user->groups, + "Test group %d", i); +} +@endcode + +This way, we have gained a lot of additional capabilities, one of which is +very simple deallocation of the structure and all of its elements. + +With the C standard library we need first to iterate over the array of groups +and free every element separately. Then we must deallocate the array that stores +them. Next we deallocate the username and as the last step free the structure +itself. But with talloc, the only operation we need to execute is freeing the +structure context. Its descendants will be freed automatically. + +@code +talloc_free(user); +@endcode + +@section keep-hierarchy Always keep the hieararchy steady! + +The talloc is a hierarchy memory allocator. The hierarchy nature is what makes +the programming more error proof. It makes the memory easier to manage and to +free. Therefore, the first thing we should have on our mind is: always +project our data structures into the talloc context hierarchy. + +That means if we have a structure, we should always use it as a parent context +for its elements. This way we will not encounter any troubles when freeing this +structure or when changing its parent. The same rule applies for arrays. + +@section creating-context Creating a talloc context + +Here are the most important functions that create a new talloc context. + +@subsection type-safe Type-safe functions + +It allocates the size that is necessary for the given type and returns a new, +properly-casted pointer. This is the preferred way to create a new context as +we can rely on the compiler to detect type mismatches. + +The name of the context is automatically set to the name of the data type which +is used to simulate a dynamic type system. + +@code +struct user *user = talloc(ctx, struct user); + +/* initialize to default values */ +user->uid = 0; +user->name = NULL; +user->num_groups = 0; +user->groups = NULL; + +/* or we can achieve the same result with */ +struct user *user_zero = talloc_zero(ctx, struct user); +@endcode + +@subsection zero-length Zero-length contexts + +The zero-length context is basically a context without any special semantical +meaning. We can use it the same way as any other context. The only difference +is that it consists only of the meta data about the context. Therefore, it is +strictly of type TALLOC_CTX*. It is often used in cases where we +want to aggregate several data structures under one parent (zero-length) +context, such as a temporary context to contain memory needed within a single +function that is not interesting to the caller. Allocating on a zero-length +temporary context will make clean-up of the function simpler. + +@code +TALLOC_CTX *tmp_ctx = NULL; +struct foo *foo = NULL; +struct bar *bar = NULL; + +/* new zero-length top level context */ +tmp_ctx = talloc_new(NULL); +if (tmp_ctx == NULL) { + return ENOMEM; +} + +foo = talloc(tmp_ctx, struct foo); +bar = talloc(tmp_ctx, struct bar); + +/* free everything at once */ +talloc_free(tmp_ctx); +@endcode + +@subsection context-see-also See also + +- talloc_size() +- talloc_named() +- @ref talloc_array +- @ref talloc_string + +*/ diff --git a/ldb-2.0.8/lib/talloc/doc/tutorial_debugging.dox b/ldb-2.0.8/lib/talloc/doc/tutorial_debugging.dox new file mode 100644 index 0000000..aadbb0d --- /dev/null +++ b/ldb-2.0.8/lib/talloc/doc/tutorial_debugging.dox @@ -0,0 +1,116 @@ +/** +@page libtalloc_debugging Chapter 6: Debugging + +Although talloc makes memory management significantly easier than the C standard +library, developers are still only humans and can make mistakes. Therefore, it +can be handy to know some tools for the inspection of talloc memory usage. + +@section log-abort Talloc log and abort + +We have already encountered the abort function in section @ref dts. +In that case it was used when a type mismatch was detected. However, talloc +calls this abort function in several more situations: + +- when the provided pointer is not a valid talloc context, +- when the meta data is invalid - probably due to memory corruption, +- and when an access after free is detected. + +The third one is probably the most interesting. It can help us with detecting +an attempt to double-free a context or any other manipulation with it via +talloc functions (using it as a parent, stealing it, etc.). + +Before the context is freed talloc sets a flag in the meta data. This is then +used to detect the access after free. It basically works on the assumption that +the memory stays unchanged (at least for a while) even when it is properly +deallocated. This will work even if the memory is filled with the value +specified in TALLOC_FREE_FILL environment variable, because it +fills only the data part and leaves the meta data intact. + +Apart from the abort function, talloc uses a log function to provide additional +information to the aforementioned violations. To enable logging we shall set the +log function with one of: + +- talloc_set_log_fn() +- talloc_set_log_stderr() + +The following code is a sample output of accessing a context after it has been +freed: + +@code +talloc_set_log_stderr(); +TALLOC_CTX *ctx = talloc_new(NULL); + +talloc_free(ctx); +talloc_free(ctx); + +results in: +talloc: access after free error - first free may be at ../src/main.c:55 +Bad talloc magic value - access after free +@endcode + +Another example is an invalid context: + +@code +talloc_set_log_stderr(); +TALLOC_CTX *ctx = talloc_new(NULL); +char *str = strdup("not a talloc context"); +talloc_steal(ctx, str); + +results in: +Bad talloc magic value - unknown value +@endcode + +@section reports Memory usage reports + +Talloc can print reports of memory usage of a specified talloc context to a +file (to stdout or stderr). The report can be +simple or full. The simple report provides information only about the context +itself and its direct descendants. The full report goes recursively through the +entire context tree. See: + +- talloc_report() +- talloc_report_full() + +We will use the following code to retrieve the sample report: + +@code +struct foo { + char *str; +}; + +TALLOC_CTX *ctx = talloc_new(NULL); +char *str = talloc_strdup(ctx, "my string"); +struct foo *foo = talloc_zero(ctx, struct foo); +foo->str = talloc_strdup(foo, "I am Foo"); +char *str2 = talloc_strdup(foo, "Foo is my parent"); + +/* print full report */ +talloc_report_full(ctx, stdout); +@endcode + +It will print a full report of ctx to the standard output. +The message should be similar to: + +@code +full talloc report on 'talloc_new: ../src/main.c:82' (total 46 bytes in 5 blocks) + struct foo contains 34 bytes in 3 blocks (ref 0) 0x1495130 + Foo is my parent contains 17 bytes in 1 blocks (ref 0) 0x1495200 + I am Foo contains 9 bytes in 1 blocks (ref 0) 0x1495190 + my string contains 10 bytes in 1 blocks (ref 0) 0x14950c0 +@endcode + +We can notice in this report that something is wrong with the context containing +struct foo. We know that the structure has only one string element. +However, we can see in the report that it has two children. This indicates that +we have either violated the memory hierarchy or forgotten to free it as +temporary data. Looking into the code, we can see that "Foo is my parent" + should be attached to ctx. + +See also: + +- talloc_enable_null_tracking() +- talloc_disable_null_tracking() +- talloc_enable_leak_report() +- talloc_enable_leak_report_full() + +*/ diff --git a/ldb-2.0.8/lib/talloc/doc/tutorial_destructors.dox b/ldb-2.0.8/lib/talloc/doc/tutorial_destructors.dox new file mode 100644 index 0000000..ed06387 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/doc/tutorial_destructors.dox @@ -0,0 +1,82 @@ +/** +@page libtalloc_destructors Chapter 4: Using destructors + +@section destructors Using destructors + +Destructors are well known methods in the world of object oriented programming. +A destructor is a method of an object that is automatically run when the object +is destroyed. It is usually used to return resources taken by the object back to +the system (e.g. closing file descriptors, terminating connection to a database, +deallocating memory). + +With talloc we can take the advantage of destructors even in C. We can easily +attach our own destructor to a talloc context. When the context is freed, the +destructor will run automatically. + +To attach/detach a destructor to a talloc context use: talloc_set_destructor(). + +@section destructors-example Example + +Imagine that we have a dynamically created linked list. Before we deallocate an +element of the list, we need to make sure that we have successfully removed it +from the list. Normally, this would be done by two commands in the exact order: +remove it from the list and then free the element. With talloc, we can do this +at once by setting a destructor on the element which will remove it from the +list and talloc_free() will do the rest. + +The destructor would be: + +@code +int list_remove(void *ctx) +{ + struct list_el *el = NULL; + el = talloc_get_type_abort(ctx, struct list_el); + /* remove element from the list */ +} +@endcode + +GCC version 3 and newer can check for the types during the compilation. So if +it is our major compiler, we can use a more advanced destructor: + +@code +int list_remove(struct list_el *el) +{ + /* remove element from the list */ +} +@endcode + +Now we will assign the destructor to the list element. We can do this directly +in the function that inserts it. + +@code +struct list_el* list_insert(TALLOC_CTX *mem_ctx, + struct list_el *where, + void *ptr) +{ + struct list_el *el = talloc(mem_ctx, struct list_el); + el->data = ptr; + /* insert into list */ + + talloc_set_destructor(el, list_remove); + return el; +} +@endcode + +Because talloc is a hierarchical memory allocator, we can go a step further and +free the data with the element as well: + +@code +struct list_el* list_insert_free(TALLOC_CTX *mem_ctx, + struct list_el *where, + void *ptr) +{ + struct list_el *el = NULL; + el = list_insert(mem_ctx, where, ptr); + + talloc_steal(el, ptr); + + return el; +} +@endcode + +*/ diff --git a/ldb-2.0.8/lib/talloc/doc/tutorial_dts.dox b/ldb-2.0.8/lib/talloc/doc/tutorial_dts.dox new file mode 100644 index 0000000..75b5172 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/doc/tutorial_dts.dox @@ -0,0 +1,109 @@ +/** +@page libtalloc_dts Chapter 3: Dynamic type system + +@section dts Dynamic type system + +Generic programming in the C language is very difficult. There is no inheritance +nor templates known from object oriented languages. There is no dynamic type +system. Therefore, generic programming in this language is usually done by +type-casting a variable to void* and transferring it through +a generic function to a specialized callback as illustrated on the next listing. + +@code +void generic_function(callback_fn cb, void *pvt) +{ + /* do some stuff and call the callback */ + cb(pvt); +} + +void specific_callback(void *pvt) +{ + struct specific_struct *data; + data = (struct specific_struct*)pvt; + /* ... */ +} + +void specific_function() +{ + struct specific_struct data; + generic_function(callback, &data); +} +@endcode + +Unfortunately, the type information is lost as a result of this type cast. The +compiler cannot check the type during the compilation nor are we able to do it +at runtime. Providing an invalid data type to the callback will result in +unexpected behaviour (not necessarily a crash) of the application. This mistake +is usually hard to detect because it is not the first thing which comes the +mind. + +As we already know, every talloc context contains a name. This name is available +at any time and it can be used to determine the type of a context even if we +lose the type of a variable. + +Although the name of the context can be set to any arbitrary string, the best +way of using it to simulate the dynamic type system is to set it directly to the +type of the variable. + +It is recommended to use one of talloc() and talloc_array() (or its +variants) to create the context as they set its name to the name of the +given type automatically. + +If we have a context with such as a name, we can use two similar functions that +do both the type check and the type cast for us: + +- talloc_get_type() +- talloc_get_type_abort() + +@section dts-examples Examples + +The following example will show how generic programming with talloc is handled - +if we provide invalid data to the callback, the program will be aborted. This +is a sufficient reaction for such an error in most applications. + +@code +void foo_callback(void *pvt) +{ + struct foo *data = talloc_get_type_abort(pvt, struct foo); + /* ... */ +} + +int do_foo() +{ + struct foo *data = talloc_zero(NULL, struct foo); + /* ... */ + return generic_function(foo_callback, data); +} +@endcode + +But what if we are creating a service application that should be running for the +uptime of a server, we may want to abort the application during the development +process (to make sure the error is not overlooked) and try to recover from the +error in the customer release. This can be achieved by creating a custom abort +function with a conditional build. + +@code +void my_abort(const char *reason) +{ + fprintf(stderr, "talloc abort: %s\n", reason); +#ifdef ABORT_ON_TYPE_MISMATCH + abort(); +#endif +} +@endcode + +The usage of talloc_get_type_abort() would be then: + +@code +talloc_set_abort_fn(my_abort); + +TALLOC_CTX *ctx = talloc_new(NULL); +char *str = talloc_get_type_abort(ctx, char); +if (str == NULL) { + /* recovery code */ +} +/* talloc abort: ../src/main.c:25: Type mismatch: + name[talloc_new: ../src/main.c:24] expected[char] */ +@endcode + +*/ diff --git a/ldb-2.0.8/lib/talloc/doc/tutorial_introduction.dox b/ldb-2.0.8/lib/talloc/doc/tutorial_introduction.dox new file mode 100644 index 0000000..418c38b --- /dev/null +++ b/ldb-2.0.8/lib/talloc/doc/tutorial_introduction.dox @@ -0,0 +1,45 @@ +/** +@page libtalloc_tutorial The Tutorial +@section introduction Introduction + +Talloc is a hierarchical, reference counted memory pool system with destructors. +It is built atop the C standard library and it defines a set of utility +functions that altogether simplifies allocation and deallocation of data, +especially for complex structures that contain many dynamically allocated +elements such as strings and arrays. + +The main goals of this library are: removing the needs for creating a cleanup +function for every complex structure, providing a logical organization of +allocated memory blocks and reducing the likelihood of creating memory leaks in +long-running applications. All of this is achieved by allocating memory in a +hierarchical structure of talloc contexts such that deallocating one context +recursively frees all of its descendants as well. + +@section main-features Main features +- An open source project +- A hierarchical memory model +- Natural projection of data structures into the memory space +- Simplifies memory management of large data structures +- Automatic execution of a destructor before the memory is freed +- Simulates a dynamic type system +- Implements a transparent memory pool + +@section toc Table of contents: + +@subpage libtalloc_context + +@subpage libtalloc_stealing + +@subpage libtalloc_dts + +@subpage libtalloc_destructors + +@subpage libtalloc_pools + +@subpage libtalloc_debugging + +@subpage libtalloc_bestpractices + +@subpage libtalloc_threads + +*/ diff --git a/ldb-2.0.8/lib/talloc/doc/tutorial_pools.dox b/ldb-2.0.8/lib/talloc/doc/tutorial_pools.dox new file mode 100644 index 0000000..a0d1e1a --- /dev/null +++ b/ldb-2.0.8/lib/talloc/doc/tutorial_pools.dox @@ -0,0 +1,93 @@ +/** +@page libtalloc_pools Chapter 5: Memory pools + +@section pools Memory pools + +Allocation of a new memory is an expensive operation and large programs can +contain thousands of calls of malloc() for a single computation, where every +call allocates only a very small amount of the memory. This can result in an +undesirable slowdown of the application. We can avoid this slowdown by +decreasing the number of malloc() calls by using a memory pool. + +A memory pool is a preallocated memory space with a fixed size. If we need to +allocate new data we will take the desired amount of the memory from the pool +instead of requesting a new memory from the system. This is done by creating a +pointer that points inside the preallocated memory. Such a pool must not be +reallocated as it would change its location - pointers that were pointing +inside the pool would become invalid. Therefore, a memory pool requires a very +good estimate of the required memory space. + +The talloc library contains its own implementation of a memory pool. It is +highly transparent for the programmer. The only thing that needs to be done is +an initialization of a new pool context using talloc_pool() - +which can be used in the same way as any other context. + +Refactoring of existing code (that uses talloc) to take the advantage of a +memory pool is quite simple due to the following properties of the pool context: + +- if we are allocating data on a pool context, it takes the desired + amount of memory from the pool, +- if the context is a descendant of the pool context, it takes the space + from the pool as well, +- if the pool does not have sufficient portion of memory left, it will + create a new non-pool context, leaving the pool intact + +@code +/* allocate 1KiB in a pool */ +TALLOC_CTX *pool_ctx = talloc_pool(NULL, 1024); + +/* Take 512B from the pool, 512B is left there */ +void *ptr = talloc_size(pool_ctx, 512); + +/* 1024B > 512B, this will create new talloc chunk outside + the pool */ +void *ptr2 = talloc_size(ptr, 1024); + +/* The pool still contains 512 free bytes + * this will take 200B from them. */ +void *ptr3 = talloc_size(ptr, 200); + +/* This will destroy context 'ptr3' but the memory + * is not freed, the available space in the pool + * will increase to 512B. */ +talloc_free(ptr3); + +/* This will free memory taken by 'pool_ctx' + * and 'ptr2' as well. */ +talloc_free(pool_ctx); +@endcode + +The above given is very convenient, but there is one big issue to be kept in +mind. If the parent of a talloc pool child is changed to a parent that is +outside of this pool, the whole pool memory will not be freed until the child is +freed. For this reason we must be very careful when stealing a descendant of a +pool context. + +@code +TALLOC_CTX *mem_ctx = talloc_new(NULL); +TALLOC_CTX *pool_ctx = talloc_pool(NULL, 1024); +struct foo *foo = talloc(pool_ctx, struct foo); + +/* mem_ctx is not in the pool */ +talloc_steal(mem_ctx, foo); + +/* pool_ctx is marked as freed but the memory is not + deallocated, accessing the pool_ctx again will cause + an error */ +talloc_free(pool_ctx); + +/* This deallocates the pool_ctx. */ +talloc_free(mem_ctx); +@endcode + +It may often be better to copy the memory we want instead of stealing it to +avoid this problem. If we do not need to retain the context name (to keep the +type information), we can use talloc_memdup() to do this. + +Copying the memory out of the pool may, however, discard all the performance +boost given by the pool, depending on the size of the copied memory. Therefore, +the code should be well profiled before taking this path. In general, the +golden rule is: if we need to steal from the pool context, we should not +use a pool context. + +*/ diff --git a/ldb-2.0.8/lib/talloc/doc/tutorial_stealing.dox b/ldb-2.0.8/lib/talloc/doc/tutorial_stealing.dox new file mode 100644 index 0000000..67eae1d --- /dev/null +++ b/ldb-2.0.8/lib/talloc/doc/tutorial_stealing.dox @@ -0,0 +1,55 @@ +/** +@page libtalloc_stealing Chapter 2: Stealing a context + +@section stealing Stealing a context + +Talloc has the ability to change the parent of a talloc context to another +one. This operation is commonly referred to as stealing and it is one of +the most important actions performed with talloc contexts. + +Stealing a context is necessary if we want the pointer to outlive the context it +is created on. This has many possible use cases, for instance stealing a result +of a database search to an in-memory cache context, changing the parent of a +field of a generic structure to a more specific one or vice-versa. The most +common scenario, at least in Samba, is to steal output data from a function-specific +context to the output context given as an argument of that function. + +@code +struct foo { + char *a1; + char *a2; + char *a3; +}; + +struct bar { + char *wurst; + struct foo *foo; +}; + +struct foo *foo = talloc_zero(ctx, struct foo); +foo->a1 = talloc_strdup(foo, "a1"); +foo->a2 = talloc_strdup(foo, "a2"); +foo->a3 = talloc_strdup(foo, "a3"); + +struct bar *bar = talloc_zero(NULL, struct bar); +/* change parent of foo from ctx to bar */ +bar->foo = talloc_steal(bar, foo); + +/* or do the same but assign foo = NULL */ +bar->foo = talloc_move(bar, &foo); +@endcode + +The talloc_move() function is similar to the talloc_steal() function but +additionally sets the source pointer to NULL. + +In general, the source pointer itself is not changed (it only replaces the +parent in the meta data). But the common usage is that the result is +assigned to another variable, thus further accessing the pointer from the +original variable should be avoided unless it is necessary. In this case +talloc_move() is the preferred way of stealing a context. Additionally sets the +source pointer to NULL, thus.protects the pointer from being accidentally freed +and accessed using the old variable after its parent has been changed. + +@image html stealing.png + +*/ diff --git a/ldb-2.0.8/lib/talloc/doc/tutorial_threads.dox b/ldb-2.0.8/lib/talloc/doc/tutorial_threads.dox new file mode 100644 index 0000000..111bbf5 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/doc/tutorial_threads.dox @@ -0,0 +1,203 @@ +/** +@page libtalloc_threads Chapter 8: Using threads with talloc + +@section Talloc and thread safety + +The talloc library is not internally thread-safe, in that accesses +to variables on a talloc context are not controlled by mutexes or +other thread-safe primitives. + +However, so long as talloc_disable_null_tracking() is called from +the main thread to disable global variable access within talloc, +then each thread can safely use its own top level talloc context +allocated off the NULL context. + +For example: + +@code +static void *thread_fn(void *arg) +{ + const char *ctx_name = (const char *)arg; + /* + * Create a new top level talloc hierarchy in + * this thread. + */ + void *top_ctx = talloc_named_const(NULL, 0, "top"); + if (top_ctx == NULL) { + return NULL; + } + sub_ctx = talloc_named_const(top_ctx, 100, ctx_name); + if (sub_ctx == NULL) { + return NULL; + } + + /* + * Do more processing/talloc calls on top_ctx + * and its children. + */ + ...... + + talloc_free(top_ctx); + return value; +} +@endcode + +is a perfectly safe use of talloc within a thread. + +The problem comes when one thread wishes to move some +memory allocated on its local top level talloc context +to another thread. Care must be taken to add data access +exclusion to prevent memory corruption. One method would +be to lock a mutex before any talloc call on each thread, +but this would push the burden of total talloc thread-safety +on the poor user of the library. + +A much easier way to transfer talloced memory between +threads is by the use of an intermediate, mutex locked, +intermediate variable. + +An example of this is below - taken from test code inside +the talloc testsuite. + +The main thread creates 1000 sub-threads, and then accepts +the transfer of some thread-talloc'ed memory onto its top +level context from each thread in turn. + +A pthread mutex and condition variable are used to +synchronize the transfer via the intermediate_ptr +variable. + +@code +/* Required sync variables. */ +static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t condvar = PTHREAD_COND_INITIALIZER; + +/* Intermediate talloc pointer for transfer. */ +static void *intermediate_ptr; + +/* Subthread. */ +static void *thread_fn(void *arg) +{ + int ret; + const char *ctx_name = (const char *)arg; + void *sub_ctx = NULL; + /* + * Do stuff that creates a new talloc hierarchy in + * this thread. + */ + void *top_ctx = talloc_named_const(NULL, 0, "top"); + if (top_ctx == NULL) { + return NULL; + } + sub_ctx = talloc_named_const(top_ctx, 100, ctx_name); + if (sub_ctx == NULL) { + return NULL; + } + + /* + * Now transfer a pointer from our hierarchy + * onto the intermediate ptr. + */ + ret = pthread_mutex_lock(&mtx); + if (ret != 0) { + talloc_free(top_ctx); + return NULL; + } + + /* Wait for intermediate_ptr to be free. */ + while (intermediate_ptr != NULL) { + ret = pthread_cond_wait(&condvar, &mtx); + if (ret != 0) { + talloc_free(top_ctx); + return NULL; + } + } + + /* and move our memory onto it from our toplevel hierarchy. */ + intermediate_ptr = talloc_move(NULL, &sub_ctx); + + /* Tell the main thread it's ready for pickup. */ + pthread_cond_broadcast(&condvar); + pthread_mutex_unlock(&mtx); + + talloc_free(top_ctx); + return NULL; +} + +/* Main thread. */ + +#define NUM_THREADS 1000 + +static bool test_pthread_talloc_passing(void) +{ + int i; + int ret; + char str_array[NUM_THREADS][20]; + pthread_t thread_id; + void *mem_ctx; + + /* + * Important ! Null tracking breaks threaded talloc. + * It *must* be turned off. + */ + talloc_disable_null_tracking(); + + /* Main thread toplevel context. */ + mem_ctx = talloc_named_const(NULL, 0, "toplevel"); + if (mem_ctx == NULL) { + return false; + } + + /* + * Spin off NUM_THREADS threads. + * They will use their own toplevel contexts. + */ + for (i = 0; i < NUM_THREADS; i++) { + (void)snprintf(str_array[i], + 20, + "thread:%d", + i); + if (str_array[i] == NULL) { + return false; + } + ret = pthread_create(&thread_id, + NULL, + thread_fn, + str_array[i]); + if (ret != 0) { + return false; + } + } + + /* Now wait for NUM_THREADS transfers of the talloc'ed memory. */ + for (i = 0; i < NUM_THREADS; i++) { + ret = pthread_mutex_lock(&mtx); + if (ret != 0) { + talloc_free(mem_ctx); + return false; + } + + /* Wait for intermediate_ptr to have our data. */ + while (intermediate_ptr == NULL) { + ret = pthread_cond_wait(&condvar, &mtx); + if (ret != 0) { + talloc_free(mem_ctx); + return false; + } + } + + /* and move it onto our toplevel hierarchy. */ + (void)talloc_move(mem_ctx, &intermediate_ptr); + + /* Tell the sub-threads we're ready for another. */ + pthread_cond_broadcast(&condvar); + pthread_mutex_unlock(&mtx); + } + + /* Dump the hierarchy. */ + talloc_report(mem_ctx, stdout); + talloc_free(mem_ctx); + return true; +} +@endcode +*/ diff --git a/ldb-2.0.8/lib/talloc/doxy.config b/ldb-2.0.8/lib/talloc/doxy.config new file mode 100644 index 0000000..0e27d61 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/doxy.config @@ -0,0 +1,1807 @@ +# Doxyfile 1.8.0 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = talloc + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 2.0 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields will be shown inline in the documentation +# of the scope in which they are defined (i.e. file, namespace, or group +# documentation), provided this scope is documented. If set to NO (the default), +# structs, classes, and unions are shown on a separate page (for HTML and Man +# pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +SYMBOL_CACHE_SIZE = 0 + +# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be +# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given +# their name and scope. Since this can be an expensive process and often the +# same symbol appear multiple times in the code, doxygen keeps a cache of +# pre-resolved symbols. If the cache is too small doxygen will become slower. +# If the cache is too large, memory is wasted. The cache size is given by this +# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = NO + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = YES + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = . \ + doc + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.cpp \ + *.cc \ + *.c \ + *.h \ + *.hh \ + *.hpp \ + *.dox + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = */.git/* + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = doc + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# style sheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = NO + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = NONE + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. +# However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = NO + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = YES + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = YES + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = DOXYGEN \ + PRINTF_ATTRIBUTE(x,y)= + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# managable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = YES + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/ldb-2.0.8/lib/talloc/man/talloc.3.xml b/ldb-2.0.8/lib/talloc/man/talloc.3.xml new file mode 100644 index 0000000..c51061f --- /dev/null +++ b/ldb-2.0.8/lib/talloc/man/talloc.3.xml @@ -0,0 +1,814 @@ + + + + 2015-04-10 + + talloc + 3 + Samba + System Administration tools + 4.0 + + + talloc +hierarchical reference counted memory pool system with destructors + + +#include <talloc.h> + + DESCRIPTION + + If you are used to talloc from Samba3 then please read this + carefully, as talloc has changed a lot. + + + The new talloc is a hierarchical, reference counted memory pool + system with destructors. Quite a mouthful really, but not too bad + once you get used to it. + + + Perhaps the biggest change from Samba3 is that there is no + distinction between a "talloc context" and a "talloc pointer". Any + pointer returned from talloc() is itself a valid talloc context. + This means you can do this: + + + struct foo *X = talloc(mem_ctx, struct foo); + X->name = talloc_strdup(X, "foo"); + + + and the pointer X->name + would be a "child" of the talloc context X which is itself a child of + mem_ctx. So if you do + talloc_free(mem_ctx) then + it is all destroyed, whereas if you do talloc_free(X) then just X and X->name are destroyed, and if + you do talloc_free(X->name) then just + the name element of X is + destroyed. + + + If you think about this, then what this effectively gives you is an + n-ary tree, where you can free any part of the tree with + talloc_free(). + + + If you find this confusing, then I suggest you run the testsuite program to watch talloc + in action. You may also like to add your own tests to testsuite.c to clarify how some + particular situation is handled. + + + TALLOC API + + The following is a complete guide to the talloc API. Read it all at + least twice. + + (type *)talloc(const void *ctx, type); + + The talloc() macro is the core of the talloc library. It takes a + memory ctx and a type, and returns a pointer to a new + area of memory of the given type. + + + The returned pointer is itself a talloc context, so you can use + it as the ctx argument to more + calls to talloc() if you wish. + + + The returned pointer is a "child" of the supplied context. This + means that if you talloc_free() the ctx then the new child disappears as + well. Alternatively you can free just the child. + + + The ctx argument to talloc() + can be NULL, in which case a new top level context is created. + + + void *talloc_size(const void *ctx, size_t size); + + The function talloc_size() should be used when you don't have a + convenient type to pass to talloc(). Unlike talloc(), it is not + type safe (as it returns a void *), so you are on your own for + type checking. + + + (typeof(ptr)) talloc_ptrtype(const void *ctx, ptr); + + The talloc_ptrtype() macro should be used when you have a pointer and + want to allocate memory to point at with this pointer. When compiling + with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size() + and talloc_get_name() will return the current location in the source file. + and not the type. + + + int talloc_free(void *ptr); + + The talloc_free() function frees a piece of talloc memory, and + all its children. You can call talloc_free() on any pointer + returned by talloc(). + + + The return value of talloc_free() indicates success or failure, + with 0 returned for success and -1 for failure. The only + possible failure condition is if ptr had a destructor attached to it and + the destructor returned -1. See talloc_set_destructor() + for details on destructors. + + + If this pointer has an additional parent when talloc_free() is + called then the memory is not actually released, but instead the + most recently established parent is destroyed. See talloc_reference() + for details on establishing additional parents. + + + For more control on which parent is removed, see talloc_unlink(). + + + talloc_free() operates recursively on its children. + + + From the 2.0 version of talloc, as a special case, + talloc_free() is refused on pointers that have more than one + parent, as talloc would have no way of knowing which parent + should be removed. To free a pointer that has more than one + parent please use talloc_unlink(). + + + To help you find problems in your code caused by this behaviour, if + you do try and free a pointer with more than one parent then the + talloc logging function will be called to give output like this: + + + + ERROR: talloc_free with references at some_dir/source/foo.c:123 + reference at some_dir/source/other.c:325 + reference at some_dir/source/third.c:121 + + + + Please see the documentation for talloc_set_log_fn() and + talloc_set_log_stderr() for more information on talloc logging + functions. + + + void *talloc_reference(const void *ctx, const void *ptr); + + The talloc_reference() function makes ctx an additional parent of ptr. + + + The return value of talloc_reference() is always the original + pointer ptr, unless talloc ran + out of memory in creating the reference in which case it will + return NULL (each additional reference consumes around 48 bytes + of memory on intel x86 platforms). + + + If ptr is NULL, then the + function is a no-op, and simply returns NULL. + + + After creating a reference you can free it in one of the + following ways: + + + + + + you can talloc_free() any parent of the original pointer. + That will reduce the number of parents of this pointer by 1, + and will cause this pointer to be freed if it runs out of + parents. + + + + + you can talloc_free() the pointer itself if it has at maximum one + parent. This behaviour has been changed since the release of version + 2.0. Further information in the description of "talloc_free". + + + + + + For more control on which parent to remove, see talloc_unlink(). + + + int talloc_unlink(const void *ctx, void *ptr); + + The talloc_unlink() function removes a specific parent from + ptr. The ctx passed must either be a context used + in talloc_reference() with this pointer, or must be a direct + parent of ptr. + + + Note that if the parent has already been removed using + talloc_free() then this function will fail and will return -1. + Likewise, if ptr is NULL, then + the function will make no modifications and return -1. + + + Usually you can just use talloc_free() instead of + talloc_unlink(), but sometimes it is useful to have the + additional control on which parent is removed. + + + void talloc_set_destructor(const void *ptr, int (*destructor)(void *)); + + The function talloc_set_destructor() sets the destructor for the pointer ptr. A destructor is a function that is called + when the memory used by a pointer is about to be released. The + destructor receives ptr as an + argument, and should return 0 for success and -1 for failure. + + + The destructor can do anything + it wants to, including freeing other pieces of memory. A common + use for destructors is to clean up operating system resources + (such as open file descriptors) contained in the structure the + destructor is placed on. + + + You can only place one destructor on a pointer. If you need more + than one destructor then you can create a zero-length child of + the pointer and place an additional destructor on that. + + + To remove a destructor call talloc_set_destructor() with NULL for + the destructor. + + + If your destructor attempts to talloc_free() the pointer that it + is the destructor for then talloc_free() will return -1 and the + free will be ignored. This would be a pointless operation + anyway, as the destructor is only called when the memory is just + about to go away. + + + int talloc_increase_ref_count(const void *<emphasis role="italic">ptr</emphasis>); + + The talloc_increase_ref_count(ptr) function is exactly equivalent to: + + talloc_reference(NULL, ptr); + + You can use either syntax, depending on which you think is + clearer in your code. + + + It returns 0 on success and -1 on failure. + + + size_t talloc_reference_count(const void *<emphasis role="italic">ptr</emphasis>); + + Return the number of references to the pointer. + + + void talloc_set_name(const void *ptr, const char *fmt, ...); + + Each talloc pointer has a "name". The name is used principally + for debugging purposes, although it is also possible to set and + get the name on a pointer in as a way of "marking" pointers in + your code. + + + The main use for names on pointer is for "talloc reports". See + talloc_report_depth_cb(), + talloc_report_depth_file(), + talloc_report() + talloc_report() + and talloc_report_full() + for details. Also see talloc_enable_leak_report() + and talloc_enable_leak_report_full(). + + + The talloc_set_name() function allocates memory as a child of the + pointer. It is logically equivalent to: + + talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...)); + + Note that multiple calls to talloc_set_name() will allocate more + memory without releasing the name. All of the memory is released + when the ptr is freed using talloc_free(). + + + void talloc_set_name_const(const void *<emphasis role="italic">ptr</emphasis>, const char *<emphasis role="italic">name</emphasis>); + + The function talloc_set_name_const() is just like + talloc_set_name(), but it takes a string constant, and is much + faster. It is extensively used by the "auto naming" macros, such + as talloc_p(). + + + This function does not allocate any memory. It just copies the + supplied pointer into the internal representation of the talloc + ptr. This means you must not pass a name pointer to memory that will + disappear before ptr is freed + with talloc_free(). + + + void *talloc_named(const void *<emphasis role="italic">ctx</emphasis>, size_t <emphasis role="italic">size</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, ...); + + The talloc_named() function creates a named talloc pointer. It + is equivalent to: + + ptr = talloc_size(ctx, size); +talloc_set_name(ptr, fmt, ....); + + void *talloc_named_const(const void *<emphasis role="italic">ctx</emphasis>, size_t <emphasis role="italic">size</emphasis>, const char *<emphasis role="italic">name</emphasis>); + + This is equivalent to: + + ptr = talloc_size(ctx, size); +talloc_set_name_const(ptr, name); + + const char *talloc_get_name(const void *<emphasis role="italic">ptr</emphasis>); + + This returns the current name for the given talloc pointer, + ptr. See talloc_set_name() + for details. + + + void *talloc_init(const char *<emphasis role="italic">fmt</emphasis>, ...); + + This function creates a zero length named talloc context as a top + level context. It is equivalent to: + + talloc_named(NULL, 0, fmt, ...); + + void *talloc_new(void *<emphasis role="italic">ctx</emphasis>); + + This is a utility macro that creates a new memory context hanging + off an existing context, automatically naming it "talloc_new: + __location__" where __location__ is the source line it is called + from. It is particularly useful for creating a new temporary + working context. + + + (<emphasis role="italic">type</emphasis> *)talloc_realloc(const void *<emphasis role="italic">ctx</emphasis>, void *<emphasis role="italic">ptr</emphasis>, <emphasis role="italic">type</emphasis>, <emphasis role="italic">count</emphasis>); + + The talloc_realloc() macro changes the size of a talloc pointer. + It has the following equivalences: + + talloc_realloc(ctx, NULL, type, 1) ==> talloc(ctx, type); +talloc_realloc(ctx, ptr, type, 0) ==> talloc_free(ptr); + + The ctx argument is only used + if ptr is not NULL, otherwise + it is ignored. + + + talloc_realloc() returns the new pointer, or NULL on failure. + The call will fail either due to a lack of memory, or because the + pointer has more than one parent (see talloc_reference()). + + + void *talloc_realloc_size(const void *ctx, void *ptr, size_t size); + + the talloc_realloc_size() function is useful when the type is not + known so the type-safe talloc_realloc() cannot be used. + + + TYPE *talloc_steal(const void *<emphasis role="italic">new_ctx</emphasis>, const TYPE *<emphasis role="italic">ptr</emphasis>); + + The talloc_steal() function changes the parent context of a + talloc pointer. It is typically used when the context that the + pointer is currently a child of is going to be freed and you wish + to keep the memory for a longer time. + + + The talloc_steal() function returns the pointer that you pass it. + It does not have any failure modes. + + + It is possible to produce loops in the parent/child + relationship if you are not careful with talloc_steal(). No + guarantees are provided as to your sanity or the safety of your + data if you do this. + + + Note that if you try and call talloc_steal() on a pointer that has + more than one parent then the result is ambiguous. Talloc will choose + to remove the parent that is currently indicated by talloc_parent() + and replace it with the chosen parent. You will also get a message + like this via the talloc logging functions: + + + + WARNING: talloc_steal with references at some_dir/source/foo.c:123 + reference at some_dir/source/other.c:325 + reference at some_dir/source/third.c:121 + + + + To unambiguously change the parent of a pointer please see + the + function talloc_reparent(). See + the talloc_set_log_fn() documentation for more information + on talloc logging. + + + TYPE *talloc_reparent(const void *<emphasis role="italic">old_parent</emphasis>, const void *<emphasis role="italic">new_parent</emphasis>, const TYPE *<emphasis role="italic">ptr</emphasis>); + + The talloc_reparent() function changes the parent context of a talloc + pointer. It is typically used when the context that the pointer is + currently a child of is going to be freed and you wish to keep the + memory for a longer time. + + + The talloc_reparent() function returns the pointer that you pass it. It + does not have any failure modes. + + + The difference between talloc_reparent() and talloc_steal() is that + talloc_reparent() can specify which parent you wish to change. This is + useful when a pointer has multiple parents via references. + + + TYPE *talloc_move(const void *<emphasis role="italic">new_ctx</emphasis>, TYPE **<emphasis role="italic">ptr</emphasis>); + + The talloc_move() function is a wrapper around + talloc_steal() which zeros the source pointer after the + move. This avoids a potential source of bugs where a + programmer leaves a pointer in two structures, and uses the + pointer from the old structure after it has been moved to a + new one. + + + size_t talloc_total_size(const void *<emphasis role="italic">ptr</emphasis>); + + The talloc_total_size() function returns the total size in bytes + used by this pointer and all child pointers. Mostly useful for + debugging. + + + Passing NULL is allowed, but it will only give a meaningful + result if talloc_enable_leak_report() or + talloc_enable_leak_report_full() has been called. + + + size_t talloc_total_blocks(const void *<emphasis role="italic">ptr</emphasis>); + + The talloc_total_blocks() function returns the total memory block + count used by this pointer and all child pointers. Mostly useful + for debugging. + + + Passing NULL is allowed, but it will only give a meaningful + result if talloc_enable_leak_report() or + talloc_enable_leak_report_full() has been called. + + + void talloc_report(const void *ptr, FILE *f); + + The talloc_report() function prints a summary report of all + memory used by ptr. One line + of report is printed for each immediate child of ptr, showing the + total memory and number of blocks used by that child. + + + You can pass NULL for the pointer, in which case a report is + printed for the top level memory context, but only if + talloc_enable_leak_report() or talloc_enable_leak_report_full() + has been called. + + + void talloc_report_full(const void *<emphasis role="italic">ptr</emphasis>, FILE *<emphasis role="italic">f</emphasis>); + + This provides a more detailed report than talloc_report(). It + will recursively print the entire tree of memory referenced by + the pointer. References in the tree are shown by giving the name + of the pointer that is referenced. + + + You can pass NULL for the pointer, in which case a report is + printed for the top level memory context, but only if + talloc_enable_leak_report() or talloc_enable_leak_report_full() + has been called. + + + + + void talloc_report_depth_cb + const void *ptr + int depth + int max_depth + void (*callback)(const void *ptr, int depth, int max_depth, int is_ref, void *priv) + void *priv + + + This provides a more flexible reports than talloc_report(). It + will recursively call the callback for the entire tree of memory + referenced by the pointer. References in the tree are passed with + is_ref = 1 and the pointer that is referenced. + + + You can pass NULL for the pointer, in which case a report is + printed for the top level memory context, but only if + talloc_enable_leak_report() or talloc_enable_leak_report_full() + has been called. + + + The recursion is stopped when depth >= max_depth. + max_depth = -1 means only stop at leaf nodes. + + + + + void talloc_report_depth_file + const void *ptr + int depth + int max_depth + FILE *f + + + This provides a more flexible reports than talloc_report(). It + will let you specify the depth and max_depth. + + + void talloc_enable_leak_report(void); + + This enables calling of talloc_report(NULL, stderr) when the + program exits. In Samba4 this is enabled by using the + --leak-report command line option. + + + For it to be useful, this function must be called before any + other talloc function as it establishes a "null context" that + acts as the top of the tree. If you don't call this function + first then passing NULL to talloc_report() or + talloc_report_full() won't give you the full tree printout. + + + Here is a typical talloc report: + + talloc report on 'null_context' (total 267 bytes in 15 blocks) +libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks +libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks +iconv(UTF8,CP850) contains 42 bytes in 2 blocks +libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks +iconv(CP850,UTF8) contains 42 bytes in 2 blocks +iconv(UTF8,UTF-16LE) contains 45 bytes in 2 blocks +iconv(UTF-16LE,UTF8) contains 45 bytes in 2 blocks + + + void talloc_enable_leak_report_full(void); + + This enables calling of talloc_report_full(NULL, stderr) when the + program exits. In Samba4 this is enabled by using the + --leak-report-full command line option. + + + For it to be useful, this function must be called before any + other talloc function as it establishes a "null context" that + acts as the top of the tree. If you don't call this function + first then passing NULL to talloc_report() or + talloc_report_full() won't give you the full tree printout. + + + Here is a typical full report: + + full talloc report on 'root' (total 18 bytes in 8 blocks) +p1 contains 18 bytes in 7 blocks (ref 0) + r1 contains 13 bytes in 2 blocks (ref 0) + reference to: p2 + p2 contains 1 bytes in 1 blocks (ref 1) + x3 contains 1 bytes in 1 blocks (ref 0) + x2 contains 1 bytes in 1 blocks (ref 0) + x1 contains 1 bytes in 1 blocks (ref 0) + + + (<emphasis role="italic">type</emphasis> *)talloc_zero(const void *<emphasis role="italic">ctx</emphasis>, <emphasis role="italic">type</emphasis>); + + The talloc_zero() macro is equivalent to: + + ptr = talloc(ctx, type); +if (ptr) memset(ptr, 0, sizeof(type)); + + void *talloc_zero_size(const void *<emphasis role="italic">ctx</emphasis>, size_t <emphasis role="italic">size</emphasis>) + + The talloc_zero_size() function is useful when you don't have a + known type. + + + void *talloc_memdup(const void *<emphasis role="italic">ctx</emphasis>, const void *<emphasis role="italic">p</emphasis>, size_t size); + + The talloc_memdup() function is equivalent to: + + ptr = talloc_size(ctx, size); +if (ptr) memcpy(ptr, p, size); + + char *talloc_strdup(const void *<emphasis role="italic">ctx</emphasis>, const char *<emphasis role="italic">p</emphasis>); + + The talloc_strdup() function is equivalent to: + + ptr = talloc_size(ctx, strlen(p)+1); +if (ptr) memcpy(ptr, p, strlen(p)+1); + + This function sets the name of the new pointer to the passed + string. This is equivalent to: + + talloc_set_name_const(ptr, ptr) + + char *talloc_strndup(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">p</emphasis>, size_t <emphasis role="italic">n</emphasis>); + + The talloc_strndup() function is the talloc equivalent of the C + library function strndup(3). + + + This function sets the name of the new pointer to the passed + string. This is equivalent to: + + talloc_set_name_const(ptr, ptr) + + char *talloc_vasprintf(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, va_list <emphasis role="italic">ap</emphasis>); + + The talloc_vasprintf() function is the talloc equivalent of the C + library function vasprintf(3). + + + This function sets the name of the new pointer to the new + string. This is equivalent to: + + talloc_set_name_const(ptr, ptr) + + char *talloc_asprintf(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, ...); + + The talloc_asprintf() function is the talloc equivalent of the C + library function asprintf(3). + + + This function sets the name of the new pointer to the passed + string. This is equivalent to: + + talloc_set_name_const(ptr, ptr) + + char *talloc_asprintf_append(char *s, const char *fmt, ...); + + The talloc_asprintf_append() function appends the given formatted + string to the given string. + + + This function sets the name of the new pointer to the new + string. This is equivalent to: + + talloc_set_name_const(ptr, ptr) + + (type *)talloc_array(const void *ctx, type, unsigned int count); + + The talloc_array() macro is equivalent to: + + (type *)talloc_size(ctx, sizeof(type) * count); + + except that it provides integer overflow protection for the + multiply, returning NULL if the multiply overflows. + + + void *talloc_array_size(const void *ctx, size_t size, unsigned int count); + + The talloc_array_size() function is useful when the type is not + known. It operates in the same way as talloc_array(), but takes a + size instead of a type. + + + (typeof(ptr)) talloc_array_ptrtype(const void *ctx, ptr, unsigned int count); + + The talloc_ptrtype() macro should be used when you have a pointer to an array + and want to allocate memory of an array to point at with this pointer. When compiling + with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_array_size() + and talloc_get_name() will return the current location in the source file. + and not the type. + + + void *talloc_realloc_fn(const void *ctx, void *ptr, size_t size) + + This is a non-macro version of talloc_realloc(), which is useful + as libraries sometimes want a realloc function pointer. A + realloc(3) implementation encapsulates the functionality of + malloc(3), free(3) and realloc(3) in one call, which is why it is + useful to be able to pass around a single function pointer. + + + void *talloc_autofree_context(void); + + This is a handy utility function that returns a talloc context + which will be automatically freed on program exit. This can be + used to reduce the noise in memory leak reports. + + + void *talloc_check_name(const void *ptr, const char *name); + + This function checks if a pointer has the specified name. If it does then the pointer is + returned. It it doesn't then NULL is returned. + + + (type *)talloc_get_type(const void *ptr, type); + + This macro allows you to do type checking on talloc pointers. It + is particularly useful for void* private pointers. It is + equivalent to this: + + (type *)talloc_check_name(ptr, #type) + + talloc_set_type(const void *ptr, type); + + This macro allows you to force the name of a pointer to be a + particular type. This can be + used in conjunction with talloc_get_type() to do type checking on + void* pointers. + + + It is equivalent to this: + + talloc_set_name_const(ptr, #type) + + talloc_set_log_fn(void (*log_fn)(const char *message)); + + This function sets a logging function that talloc will use for + warnings and errors. By default talloc will not print any warnings or + errors. + + + talloc_set_log_stderr(void); + + This sets the talloc log function to write log messages to stderr + + + + PERFORMANCE + + All the additional features of talloc(3) over malloc(3) do come at a + price. We have a simple performance test in Samba4 that measures + talloc() versus malloc() performance, and it seems that talloc() is + about 10% slower than malloc() on my x86 Debian Linux box. For + Samba, the great reduction in code complexity that we get by using + talloc makes this worthwhile, especially as the total overhead of + talloc/malloc in Samba is already quite small. + + + SEE ALSO + + malloc(3), strndup(3), vasprintf(3), asprintf(3), + + + + + AUTHOR + The original Samba software and related utilities were + created by Andrew Tridgell. Samba is now developed by the + Samba Team as an Open Source project similar to the way the + Linux kernel is developed. + + + + COPYRIGHT/LICENSE + + Copyright (C) Andrew Tridgell 2004 + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 3 of the + License, or (at your option) any later version. + + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + + You should have received a copy of the GNU General Public License + along with this program; if not, see http://www.gnu.org/licenses/. + + + diff --git a/ldb-2.0.8/lib/talloc/pytalloc-util.pc.in b/ldb-2.0.8/lib/talloc/pytalloc-util.pc.in new file mode 100644 index 0000000..06f83e2 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/pytalloc-util.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: pytalloc-util@PYTHON_SO_ABI_FLAG@ +Description: Utility functions for using talloc objects with Python +Version: @TALLOC_VERSION@ +Libs: @LIB_RPATH@ -L${libdir} -lpytalloc-util@PYTHON_LIBNAME_SO_ABI_FLAG@ +Cflags: -I${includedir} +URL: http://talloc.samba.org/ diff --git a/ldb-2.0.8/lib/talloc/pytalloc.c b/ldb-2.0.8/lib/talloc/pytalloc.c new file mode 100644 index 0000000..12c7325 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/pytalloc.c @@ -0,0 +1,309 @@ +/* + Unix SMB/CIFS implementation. + Python Talloc Module + Copyright (C) Jelmer Vernooij 2010-2011 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include "pytalloc_private.h" + +static PyTypeObject TallocObject_Type; + +/* print a talloc tree report for a talloc python object */ +static PyObject *pytalloc_report_full(PyObject *self, PyObject *args) +{ + PyObject *py_obj = Py_None; + + if (!PyArg_ParseTuple(args, "|O", &py_obj)) + return NULL; + + if (py_obj == Py_None) { + talloc_report_full(NULL, stdout); + } else { + talloc_report_full(pytalloc_get_mem_ctx(py_obj), stdout); + } + return Py_None; +} + +/* enable null tracking */ +static PyObject *pytalloc_enable_null_tracking(PyObject *self, + PyObject *Py_UNUSED(ignored)) +{ + talloc_enable_null_tracking(); + return Py_None; +} + +/* return the number of talloc blocks */ +static PyObject *pytalloc_total_blocks(PyObject *self, PyObject *args) +{ + PyObject *py_obj = Py_None; + + if (!PyArg_ParseTuple(args, "|O", &py_obj)) + return NULL; + + if (py_obj == Py_None) { + return PyLong_FromLong(talloc_total_blocks(NULL)); + } + + return PyLong_FromLong(talloc_total_blocks(pytalloc_get_mem_ctx(py_obj))); +} + +static PyMethodDef talloc_methods[] = { + { "report_full", (PyCFunction)pytalloc_report_full, METH_VARARGS, + "show a talloc tree for an object"}, + { "enable_null_tracking", (PyCFunction)pytalloc_enable_null_tracking, METH_NOARGS, + "enable tracking of the NULL object"}, + { "total_blocks", (PyCFunction)pytalloc_total_blocks, METH_VARARGS, + "return talloc block count"}, + { NULL } +}; + +/** + * Default (but only slightly more useful than the default) implementation of Repr(). + */ +static PyObject *pytalloc_default_repr(PyObject *obj) +{ + pytalloc_Object *talloc_obj = (pytalloc_Object *)obj; + PyTypeObject *type = (PyTypeObject*)PyObject_Type(obj); + + return PyUnicode_FromFormat("<%s talloc object at %p>", + type->tp_name, talloc_obj->ptr); +} + +/** + * Simple dealloc for talloc-wrapping PyObjects + */ +static void pytalloc_dealloc(PyObject* self) +{ + pytalloc_Object *obj = (pytalloc_Object *)self; + assert(talloc_unlink(NULL, obj->talloc_ctx) != -1); + obj->talloc_ctx = NULL; + self->ob_type->tp_free(self); +} + +/** + * Default (but only slightly more useful than the default) implementation of cmp. + */ +#if PY_MAJOR_VERSION >= 3 +static PyObject *pytalloc_default_richcmp(PyObject *obj1, PyObject *obj2, int op) +{ + void *ptr1; + void *ptr2; + if (Py_TYPE(obj1) == Py_TYPE(obj2)) { + /* When types match, compare pointers */ + ptr1 = pytalloc_get_ptr(obj1); + ptr2 = pytalloc_get_ptr(obj2); + } else if (PyObject_TypeCheck(obj2, &TallocObject_Type)) { + /* Otherwise, compare types */ + ptr1 = Py_TYPE(obj1); + ptr2 = Py_TYPE(obj2); + } else { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + switch (op) { + case Py_EQ: return PyBool_FromLong(ptr1 == ptr2); + case Py_NE: return PyBool_FromLong(ptr1 != ptr2); + case Py_LT: return PyBool_FromLong(ptr1 < ptr2); + case Py_GT: return PyBool_FromLong(ptr1 > ptr2); + case Py_LE: return PyBool_FromLong(ptr1 <= ptr2); + case Py_GE: return PyBool_FromLong(ptr1 >= ptr2); + } + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; +} +#else +static int pytalloc_default_cmp(PyObject *_obj1, PyObject *_obj2) +{ + pytalloc_Object *obj1 = (pytalloc_Object *)_obj1, + *obj2 = (pytalloc_Object *)_obj2; + if (obj1->ob_type != obj2->ob_type) + return ((char *)obj1->ob_type - (char *)obj2->ob_type); + + return ((char *)pytalloc_get_ptr(obj1) - (char *)pytalloc_get_ptr(obj2)); +} +#endif + +static PyTypeObject TallocObject_Type = { + .tp_name = "talloc.Object", + .tp_doc = "Python wrapper for a talloc-maintained object.", + .tp_basicsize = sizeof(pytalloc_Object), + .tp_dealloc = (destructor)pytalloc_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_repr = pytalloc_default_repr, +#if PY_MAJOR_VERSION >= 3 + .tp_richcompare = pytalloc_default_richcmp, +#else + .tp_compare = pytalloc_default_cmp, +#endif +}; + +/** + * Default (but only slightly more useful than the default) implementation of Repr(). + */ +static PyObject *pytalloc_base_default_repr(PyObject *obj) +{ + pytalloc_BaseObject *talloc_obj = (pytalloc_BaseObject *)obj; + PyTypeObject *type = (PyTypeObject*)PyObject_Type(obj); + + return PyUnicode_FromFormat("<%s talloc based object at %p>", + type->tp_name, talloc_obj->ptr); +} + +/** + * Simple dealloc for talloc-wrapping PyObjects + */ +static void pytalloc_base_dealloc(PyObject* self) +{ + pytalloc_BaseObject *obj = (pytalloc_BaseObject *)self; + assert(talloc_unlink(NULL, obj->talloc_ctx) != -1); + obj->talloc_ctx = NULL; + self->ob_type->tp_free(self); +} + +/** + * Default (but only slightly more useful than the default) implementation of cmp. + */ +#if PY_MAJOR_VERSION >= 3 +static PyObject *pytalloc_base_default_richcmp(PyObject *obj1, PyObject *obj2, int op) +{ + void *ptr1; + void *ptr2; + if (Py_TYPE(obj1) == Py_TYPE(obj2)) { + /* When types match, compare pointers */ + ptr1 = pytalloc_get_ptr(obj1); + ptr2 = pytalloc_get_ptr(obj2); + } else if (PyObject_TypeCheck(obj2, &TallocObject_Type)) { + /* Otherwise, compare types */ + ptr1 = Py_TYPE(obj1); + ptr2 = Py_TYPE(obj2); + } else { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + switch (op) { + case Py_EQ: return PyBool_FromLong(ptr1 == ptr2); + case Py_NE: return PyBool_FromLong(ptr1 != ptr2); + case Py_LT: return PyBool_FromLong(ptr1 < ptr2); + case Py_GT: return PyBool_FromLong(ptr1 > ptr2); + case Py_LE: return PyBool_FromLong(ptr1 <= ptr2); + case Py_GE: return PyBool_FromLong(ptr1 >= ptr2); + } + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; +} +#else +static int pytalloc_base_default_cmp(PyObject *_obj1, PyObject *_obj2) +{ + pytalloc_BaseObject *obj1 = (pytalloc_BaseObject *)_obj1, + *obj2 = (pytalloc_BaseObject *)_obj2; + if (obj1->ob_type != obj2->ob_type) + return ((char *)obj1->ob_type - (char *)obj2->ob_type); + + return ((char *)pytalloc_get_ptr(obj1) - (char *)pytalloc_get_ptr(obj2)); +} +#endif + +static PyTypeObject TallocBaseObject_Type = { + .tp_name = "talloc.BaseObject", + .tp_doc = "Python wrapper for a talloc-maintained object.", + .tp_basicsize = sizeof(pytalloc_BaseObject), + .tp_dealloc = (destructor)pytalloc_base_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_repr = pytalloc_base_default_repr, +#if PY_MAJOR_VERSION >= 3 + .tp_richcompare = pytalloc_base_default_richcmp, +#else + .tp_compare = pytalloc_base_default_cmp, +#endif +}; + +static PyTypeObject TallocGenericObject_Type = { + .tp_name = "talloc.GenericObject", + .tp_doc = "Python wrapper for a talloc-maintained object.", + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_base = &TallocBaseObject_Type, + .tp_basicsize = sizeof(pytalloc_BaseObject), +}; + +#define MODULE_DOC PyDoc_STR("Python wrapping of talloc-maintained objects.") + +#if PY_MAJOR_VERSION >= 3 +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + .m_name = "talloc", + .m_doc = MODULE_DOC, + .m_size = -1, + .m_methods = talloc_methods, +}; +#endif + +static PyObject *module_init(void); +static PyObject *module_init(void) +{ + PyObject *m; + + if (PyType_Ready(&TallocObject_Type) < 0) + return NULL; + + if (PyType_Ready(&TallocBaseObject_Type) < 0) + return NULL; + + if (PyType_Ready(&TallocGenericObject_Type) < 0) + return NULL; + +#if PY_MAJOR_VERSION >= 3 + m = PyModule_Create(&moduledef); +#else + m = Py_InitModule3("talloc", talloc_methods, MODULE_DOC); +#endif + if (m == NULL) + return NULL; + + Py_INCREF(&TallocObject_Type); + if (PyModule_AddObject(m, "Object", (PyObject *)&TallocObject_Type)) { + goto err; + } + Py_INCREF(&TallocBaseObject_Type); + if (PyModule_AddObject(m, "BaseObject", (PyObject *)&TallocBaseObject_Type)) { + goto err; + } + Py_INCREF(&TallocGenericObject_Type); + if (PyModule_AddObject(m, "GenericObject", (PyObject *)&TallocGenericObject_Type)) { + goto err; + } + return m; + +err: + Py_DECREF(m); + return NULL; +} + +#if PY_MAJOR_VERSION >= 3 +PyMODINIT_FUNC PyInit_talloc(void); +PyMODINIT_FUNC PyInit_talloc(void) +{ + return module_init(); +} +#else +void inittalloc(void); +void inittalloc(void) +{ + module_init(); +} +#endif diff --git a/ldb-2.0.8/lib/talloc/pytalloc.h b/ldb-2.0.8/lib/talloc/pytalloc.h new file mode 100644 index 0000000..7db6c33 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/pytalloc.h @@ -0,0 +1,79 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jelmer Vernooij 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _PYTALLOC_H_ +#define _PYTALLOC_H_ + +#include +#include + +typedef struct { + PyObject_HEAD + TALLOC_CTX *talloc_ctx; + void *ptr; /* eg the array element */ +} pytalloc_Object; + +/* Return the PyTypeObject for pytalloc_Object. Returns a borrowed reference. */ +PyTypeObject *pytalloc_GetObjectType(void); + +/* Return the PyTypeObject for pytalloc_BaseObject. Returns a borrowed reference. */ +PyTypeObject *pytalloc_GetBaseObjectType(void); + +/* Check whether a specific object is a talloc Object. */ +int pytalloc_Check(PyObject *); + +int pytalloc_BaseObject_check(PyObject *); + +int _pytalloc_check_type(PyObject *py_obj, const char *type_name); +#define pytalloc_check_type(py_obj, type) \ + _pytalloc_check_type((PyObject *)(py_obj), #type) + +/* Retrieve the pointer for a pytalloc_object. Like talloc_get_type() + * but for pytalloc_Objects. */ +void *_pytalloc_get_type(PyObject *py_obj, const char *type_name); +#define pytalloc_get_type(py_obj, type) ((type *)_pytalloc_get_type((PyObject *)(py_obj), #type)) + +void *_pytalloc_get_ptr(PyObject *py_obj); +#define pytalloc_get_ptr(py_obj) _pytalloc_get_ptr((PyObject *)(py_obj)) +TALLOC_CTX *_pytalloc_get_mem_ctx(PyObject *py_obj); +#define pytalloc_get_mem_ctx(py_obj) _pytalloc_get_mem_ctx((PyObject *)(py_obj)) + +PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr); +PyObject *pytalloc_steal(PyTypeObject *py_type, void *ptr); +PyObject *pytalloc_reference_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr); +#define pytalloc_reference(py_type, talloc_ptr) pytalloc_reference_ex(py_type, talloc_ptr, talloc_ptr) + +#define pytalloc_new(type, typeobj) pytalloc_steal(typeobj, talloc_zero(NULL, type)) + +/* + * Wrap a generic talloc pointer into a talloc.GenericObject, + * this is a subclass of talloc.BaseObject. + */ +PyObject *pytalloc_GenericObject_steal_ex(TALLOC_CTX *mem_ctx, void *ptr); +#define pytalloc_GenericObject_steal(talloc_ptr) \ + pytalloc_GenericObject_steal_ex(talloc_ptr, talloc_ptr) +PyObject *pytalloc_GenericObject_reference_ex(TALLOC_CTX *mem_ctx, void *ptr); +#define pytalloc_GenericObject_reference(talloc_ptr) \ + pytalloc_GenericObject_reference_ex(talloc_ptr, talloc_ptr) + +size_t pytalloc_BaseObject_size(void); + +int pytalloc_BaseObject_PyType_Ready(PyTypeObject *type); + +#endif /* _PYTALLOC_H_ */ diff --git a/ldb-2.0.8/lib/talloc/pytalloc_guide.txt b/ldb-2.0.8/lib/talloc/pytalloc_guide.txt new file mode 100644 index 0000000..bd2b68c --- /dev/null +++ b/ldb-2.0.8/lib/talloc/pytalloc_guide.txt @@ -0,0 +1,252 @@ +Using talloc in Samba4 +====================== + +.. contents:: + +Jelmer Vernooij +August 2013 + +The most current version of this document is available at + http://samba.org/ftp/unpacked/talloc/pytalloc_guide.txt + +pytalloc is a small library that provides glue for wrapping +talloc-allocated objects from C in Python objects. + +What is pytalloc, and what is it not? +------------------------------------- + +pytalloc is merely a helper library - it provides a convenient base type object +for objects that wrap talloc-maintained memory in C. It won't write your +bindings for you but it will make it easier to write C bindings that involve +talloc, and take away some of the boiler plate. + +Python 3 +-------- + +pytalloc can be used with Python 3. Usage from Python extension remains +the same, but for the C utilities, the library to link to is tagged with +Python's PEP3149 ABI tag, for example "pytalloc.cpython34m". +To make a build for Python 3, configure with PYTHON=/usr/bin/python3. +. +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +pytalloc_Object / pytalloc_BaseObject + +This is the new base class that all Python objects that wrap talloc pointers +derive from. It is itself a subclass of the "Object" type that all objects +in Python derive from. + +Note that you will almost never create objects of the pytalloc_Object type +itself, as they are just opaque pointers that can not be accessed from +Python. A common pattern is other objects that subclass pytalloc_Object and +rely on it for their memory management. + +Each `pytalloc_Object` wraps two core of information - a talloc context +and a pointer. The pointer is the actual data that is wrapped. The talloc +context is used for memory management purposes only; when the wrapping Python object +goes away, it unlinks the talloc context. The talloc context pointer and the ptr +can (and often do) have the same value. + +Each pytalloc_Object has a custom __repr__ implementation that +describes that it is a talloc object and the location of the +pointer it is wrapping. it also has a custom __cmp__/__eq__/__neq__ method that +compares the pointers the object is wrapping rather than the objects +themselves (since there can be multiple objects that wrap the same talloc +pointer). + +It is preferred to use pytalloc_BaseObject as this implementation +exposes less in the C ABI and correctly supports pointers in C arrays +in the way needed by PIDL. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +PyTypeObject *pytalloc_GetObjectType(void) + +Obtain a pointer to the PyTypeObject for `pytalloc_Object`. The +reference counter for the object will be NOT incremented, so the +caller MUST NOT decrement it when it no longer needs it (eg by using +`Py_DECREF`). + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +PyTypeObject *pytalloc_GetBaseObjectType(void) + +Obtain a pointer to the PyTypeObject for `pytalloc_BaseObject`. The +reference counter for the object will be NOT incremented, so the +caller MUST NOT decrement it when it no longer needs it (eg by using +`Py_DECREF`). + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +int pytalloc_BaseObject_PyType_Ready(PyTypeObject *type); + +Wrapper for PyType_Ready() that will set the correct values into +the PyTypeObject to create a BaseObject + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=- +int pytalloc_Check(PyObject *) + +Check whether a specific object is a talloc Object. Returns non-zero if it is +a pytalloc_Object and zero otherwise. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=- +int pytalloc_BaseObject_Check(PyObject *) + +Check whether a specific object is a talloc BaseObject. Returns non-zero if it is +a pytalloc_BaseObject and zero otherwise. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +int pytalloc_check_type(PyObject *py_obj, type) + +Check if the object based on `pytalloc_*Object` py_obj. type should be a +C type, similar to a type passed to `talloc_get_type`. +This can be used as a check before using pytalloc_get_type() +or an alternative codepath. Returns non-zero if it is +an object of the expected type and zero otherwise. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +type *pytalloc_get_type(PyObject *py_obj, type) + +Retrieve the pointer from a `pytalloc_Object` py_obj. type should be a +C type, similar to a type passed to `talloc_get_type`. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +pytalloc_get_ptr(PyObject *py_obj) + +Retrieve the pointer from a `pytalloc_Object` or `pytalloc_BaseObject` +py_obj. There is no type checking - use `pytalloc_get_type` if +possible. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +TALLOC_CTX *pytalloc_get_mem_ctx(PyObject *py_obj) + +Retrieve the talloc context associated with a pytalloc_Object or pytalloc_BaseObject. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr) + +Create a new Python wrapping object for a talloc pointer and context, with +py_type as associated Python sub type object. This typically used +when `mem_ctx` and `ptr` differ, e.g. a pointer to an array element. +`pytalloc_get_ptr()` can be used to get the pointer out of the object again. + +This will *not* increment the reference counter for the talloc context, +so the caller should make sure such an increment has happened. When the Python +object goes away, it will unreference the talloc context. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +PyObject *pytalloc_steal(PyTypeObject *py_type, void *ptr) + +Create a new Python wrapping object for a talloc pointer and context, with +py_type as associated Python sub type object. The pointer will also be used +as the talloc context. `pytalloc_get_type()` can be used to get +the pointer out of the object again. + +This will *not* increment the reference counter for the talloc context, +so the caller should make sure such an increment has happened. When the Python +object goes away, it will unreference the talloc context. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +PyObject *pytalloc_reference_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr) + +Create a new Python wrapping object for a talloc pointer and context, with +py_type as associated Python sub type object. This typically used +when `mem_ctx` and `ptr` differ, e.g. a pointer to an array element. +`pytalloc_get_ptr()` can be used to get the pointer out of the object again. + +This will increment the reference counter for the talloc context. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +PyObject *pytalloc_reference(PyTypeObject *py_type, void *talloc_ptr) + +Create a new Python wrapping object for a talloc pointer, with +py_type as associated Python sub type object. The pointer will also be used +as the talloc context. `pytalloc_get_type()` can be used to get +the pointer out of the object again. + +This will increment the reference counter for the talloc context. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +PyObject *pytalloc_new(type, PyTypeObject *typeobj) + +Create a new, empty pytalloc_Object with the specified Python type object. type +should be a C type, similar to talloc_new(). + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +PyObject *pytalloc_GenericObject_steal_ex(void *ptr) + +Create a new Python wrapping object for a generic talloc pointer, +as sub type of `pytalloc_BaseObject`. This typically used +when `mem_ctx` and `ptr` differ, e.g. a pointer to an array element. +`pytalloc_get_ptr()` can be used to get the pointer out of the object again. + +This will *not* increment the reference counter for the talloc context, +so the caller should make sure such an increment has happened. When the Python +object goes away, it will unreference the talloc context. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +PyObject *pytalloc_GenericObject_steal(void *ptr) + +Create a new Python wrapping object for a generic talloc pointer, +as sub type of `pytalloc_BaseObject`. The pointer will also be used +as the talloc context. `pytalloc_get_type()` can be used to get +the pointer out of the object again. + +This will *not* increment the reference counter for the talloc context, +so the caller should make sure such an increment has happened. When the Python +object goes away, it will unreference the talloc context. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +PyObject *pytalloc_GenericObject_reference_ex(void *ptr) + +Create a new Python wrapping object for a generic talloc pointer, +as sub type of `pytalloc_BaseObject`. This typically used +when `mem_ctx` and `ptr` differ, e.g. a pointer to an array element. +`pytalloc_get_ptr()` can be used to get the pointer out of the object again. + +This will increment the reference counter for the talloc context. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +PyObject *pytalloc_GenericObject_reference(void *ptr) + +Create a new Python wrapping object for a generic talloc pointer, +as sub type of `pytalloc_BaseObject`. The pointer will also be used +as the talloc context. `pytalloc_get_type()` can be used to get +the pointer out of the object again. + +This will increment the reference counter for the talloc context. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +DEPRECATED! PyObject *pytalloc_CObject_FromTallocPtr(void *); + +Create a new pytalloc_Object for an abitrary talloc-maintained C pointer. This will +use a generic VoidPtr Python type, which just provides an opaque object in +Python. The caller is responsible for incrementing the talloc reference count before calling +this function - it will dereference the talloc pointer when it is garbage collected. + +This function is deprecated and only available on Python 2. +Use pytalloc_GenericObject_{reference,steal}[_ex]() instead. + +Debug function for talloc in Python +----------------------------------- + +The "talloc" module in Python provides a couple of functions that can be used +to debug issues with objects wrapped by pytalloc. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +report_full(obj?) + +Print a full report on a specific object or on all allocated objects by Python. +Same behaviour as the `talloc_report_full()` function that is provided by +C talloc. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +enable_null_tracking() + +This enables tracking of the NULL memory context without enabling leak +reporting on exit. Useful for when you want to do your own leak +reporting call via talloc_report_null_full(). + +This must be done in the top level script, not an imported module. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +pytalloc_total_blocks(obj?) + +Return the talloc block count for all allocated objects or a specific object if +specified. diff --git a/ldb-2.0.8/lib/talloc/pytalloc_private.h b/ldb-2.0.8/lib/talloc/pytalloc_private.h new file mode 100644 index 0000000..b23cdfc --- /dev/null +++ b/ldb-2.0.8/lib/talloc/pytalloc_private.h @@ -0,0 +1,26 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jelmer Vernooij 2008 + Copyright (C) Andrew Bartlett 2016 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +typedef struct { + PyObject_HEAD + TALLOC_CTX *talloc_ctx; + TALLOC_CTX *talloc_ptr_ctx; /* eg the start of the array */ + void *ptr; /* eg the array element */ +} pytalloc_BaseObject; diff --git a/ldb-2.0.8/lib/talloc/pytalloc_util.c b/ldb-2.0.8/lib/talloc/pytalloc_util.c new file mode 100644 index 0000000..7a426d6 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/pytalloc_util.c @@ -0,0 +1,333 @@ +/* + Unix SMB/CIFS implementation. + Python/Talloc glue + Copyright (C) Jelmer Vernooij 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include "replace.h" +#include +#include "pytalloc.h" +#include +#include "pytalloc_private.h" + +static PyObject *pytalloc_steal_or_reference(PyTypeObject *py_type, + TALLOC_CTX *mem_ctx, void *ptr, bool steal); + +_PUBLIC_ PyTypeObject *pytalloc_GetObjectType(void) +{ + static PyTypeObject *type = NULL; + PyObject *mod; + + if (type != NULL) { + return type; + } + + mod = PyImport_ImportModule("talloc"); + if (mod == NULL) { + return NULL; + } + + type = (PyTypeObject *)PyObject_GetAttrString(mod, "Object"); + Py_DECREF(mod); + + return type; +} + +_PUBLIC_ PyTypeObject *pytalloc_GetBaseObjectType(void) +{ + static PyTypeObject *type = NULL; + PyObject *mod; + + if (type != NULL) { + return type; + } + + mod = PyImport_ImportModule("talloc"); + if (mod == NULL) { + return NULL; + } + + type = (PyTypeObject *)PyObject_GetAttrString(mod, "BaseObject"); + Py_DECREF(mod); + + return type; +} + +static PyTypeObject *pytalloc_GetGenericObjectType(void) +{ + static PyTypeObject *type = NULL; + PyObject *mod; + + if (type != NULL) { + return type; + } + + mod = PyImport_ImportModule("talloc"); + if (mod == NULL) { + return NULL; + } + + type = (PyTypeObject *)PyObject_GetAttrString(mod, "GenericObject"); + Py_DECREF(mod); + + return type; +} + +/** + * Import an existing talloc pointer into a Python object. + */ +_PUBLIC_ PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, + void *ptr) +{ + return pytalloc_steal_or_reference(py_type, mem_ctx, ptr, true); +} + +/** + * Import an existing talloc pointer into a Python object. + */ +_PUBLIC_ PyObject *pytalloc_steal(PyTypeObject *py_type, void *ptr) +{ + return pytalloc_steal_or_reference(py_type, ptr, ptr, true); +} + + +/** + * Import an existing talloc pointer into a Python object, leaving the + * original parent, and creating a reference to the object in the python + * object. + * + * We remember the object we hold the reference to (a + * possibly-non-talloc pointer), the existing parent (typically the + * start of the array) and the new referenced parent. That way we can + * cope with the fact that we will have multiple parents, one per time + * python sees the object. + */ +_PUBLIC_ PyObject *pytalloc_reference_ex(PyTypeObject *py_type, + TALLOC_CTX *mem_ctx, void *ptr) +{ + return pytalloc_steal_or_reference(py_type, mem_ctx, ptr, false); +} + + +/** + * Internal function that either steals or referecences the talloc + * pointer into a new talloc context. + */ +static PyObject *pytalloc_steal_or_reference(PyTypeObject *py_type, + TALLOC_CTX *mem_ctx, void *ptr, bool steal) +{ + bool ok = false; + TALLOC_CTX *talloc_ctx = NULL; + bool is_baseobject = false; + PyObject *obj = NULL; + PyTypeObject *BaseObjectType = NULL, *ObjectType = NULL; + + BaseObjectType = pytalloc_GetBaseObjectType(); + if (BaseObjectType == NULL) { + goto err; + } + ObjectType = pytalloc_GetObjectType(); + if (ObjectType == NULL) { + goto err; + } + + /* this should have been tested by caller */ + if (mem_ctx == NULL) { + return PyErr_NoMemory(); + } + + is_baseobject = PyType_IsSubtype(py_type, BaseObjectType); + if (!is_baseobject) { + if (!PyType_IsSubtype(py_type, ObjectType)) { + PyErr_SetString(PyExc_TypeError, + "Expected type based on talloc"); + return NULL; + } + } + + obj = py_type->tp_alloc(py_type, 0); + if (obj == NULL) { + goto err; + } + + talloc_ctx = talloc_new(NULL); + if (talloc_ctx == NULL) { + PyErr_NoMemory(); + goto err; + } + + if (steal) { + ok = (talloc_steal(talloc_ctx, mem_ctx) != NULL); + } else { + ok = (talloc_reference(talloc_ctx, mem_ctx) != NULL); + } + if (!ok) { + goto err; + } + talloc_set_name_const(talloc_ctx, py_type->tp_name); + + if (is_baseobject) { + pytalloc_BaseObject *ret = (pytalloc_BaseObject*)obj; + ret->talloc_ctx = talloc_ctx; + ret->talloc_ptr_ctx = mem_ctx; + ret->ptr = ptr; + } else { + pytalloc_Object *ret = (pytalloc_Object*)obj; + ret->talloc_ctx = talloc_ctx; + ret->ptr = ptr; + } + return obj; + +err: + TALLOC_FREE(talloc_ctx); + Py_XDECREF(obj); + return NULL; +} + +/* + * Wrap a generic talloc pointer into a talloc.GenericObject, + * this is a subclass of talloc.BaseObject. + */ +_PUBLIC_ PyObject *pytalloc_GenericObject_steal_ex(TALLOC_CTX *mem_ctx, void *ptr) +{ + PyTypeObject *tp = pytalloc_GetGenericObjectType(); + return pytalloc_steal_ex(tp, mem_ctx, ptr); +} + +/* + * Wrap a generic talloc pointer into a talloc.GenericObject, + * this is a subclass of talloc.BaseObject. + */ +_PUBLIC_ PyObject *pytalloc_GenericObject_reference_ex(TALLOC_CTX *mem_ctx, void *ptr) +{ + PyTypeObject *tp = pytalloc_GetGenericObjectType(); + return pytalloc_reference_ex(tp, mem_ctx, ptr); +} + +_PUBLIC_ int pytalloc_Check(PyObject *obj) +{ + PyTypeObject *tp = pytalloc_GetObjectType(); + + return PyObject_TypeCheck(obj, tp); +} + +_PUBLIC_ int pytalloc_BaseObject_check(PyObject *obj) +{ + PyTypeObject *tp = pytalloc_GetBaseObjectType(); + + return PyObject_TypeCheck(obj, tp); +} + +_PUBLIC_ size_t pytalloc_BaseObject_size(void) +{ + return sizeof(pytalloc_BaseObject); +} + +static void *_pytalloc_get_checked_type(PyObject *py_obj, const char *type_name, + bool check_only, const char *function) +{ + TALLOC_CTX *mem_ctx; + void *ptr = NULL; + void *type_obj = talloc_check_name(ptr, type_name); + + mem_ctx = _pytalloc_get_mem_ctx(py_obj); + ptr = _pytalloc_get_ptr(py_obj); + + if (mem_ctx != ptr) { + if (check_only) { + return NULL; + } + + PyErr_Format(PyExc_TypeError, "%s: expected %s, " + "but the pointer is no talloc pointer, " + "pytalloc_get_ptr() would get the raw pointer.", + function, type_name); + return NULL; + } + + type_obj = talloc_check_name(ptr, type_name); + if (type_obj == NULL) { + const char *name = NULL; + + if (check_only) { + return NULL; + } + + name = talloc_get_name(ptr); + PyErr_Format(PyExc_TypeError, "%s: expected %s, got %s", + function, type_name, name); + return NULL; + } + + return ptr; +} + +_PUBLIC_ int _pytalloc_check_type(PyObject *py_obj, const char *type_name) +{ + void *ptr = NULL; + + ptr = _pytalloc_get_checked_type(py_obj, type_name, + true, /* check_only */ + "pytalloc_check_type"); + if (ptr == NULL) { + return 0; + } + + return 1; +} + +_PUBLIC_ void *_pytalloc_get_type(PyObject *py_obj, const char *type_name) +{ + return _pytalloc_get_checked_type(py_obj, type_name, + false, /* not check_only */ + "pytalloc_get_type"); +} + +_PUBLIC_ void *_pytalloc_get_ptr(PyObject *py_obj) +{ + if (pytalloc_BaseObject_check(py_obj)) { + return ((pytalloc_BaseObject *)py_obj)->ptr; + } + if (pytalloc_Check(py_obj)) { + return ((pytalloc_Object *)py_obj)->ptr; + } + return NULL; +} + +_PUBLIC_ TALLOC_CTX *_pytalloc_get_mem_ctx(PyObject *py_obj) +{ + if (pytalloc_BaseObject_check(py_obj)) { + return ((pytalloc_BaseObject *)py_obj)->talloc_ptr_ctx; + } + if (pytalloc_Check(py_obj)) { + return ((pytalloc_Object *)py_obj)->talloc_ctx; + } + return NULL; +} + +_PUBLIC_ int pytalloc_BaseObject_PyType_Ready(PyTypeObject *type) +{ + PyTypeObject *talloc_type = pytalloc_GetBaseObjectType(); + if (talloc_type == NULL) { + return -1; + } + + type->tp_base = talloc_type; + type->tp_basicsize = pytalloc_BaseObject_size(); + + return PyType_Ready(type); +} diff --git a/ldb-2.0.8/lib/talloc/talloc.c b/ldb-2.0.8/lib/talloc/talloc.c new file mode 100644 index 0000000..518ffbd --- /dev/null +++ b/ldb-2.0.8/lib/talloc/talloc.c @@ -0,0 +1,3050 @@ +/* + Samba Unix SMB/CIFS implementation. + + Samba trivial allocation library - new interface + + NOTE: Please read talloc_guide.txt for full documentation + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Stefan Metzmacher 2006 + + ** NOTE! The following LGPL license applies to the talloc + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + inspired by http://swapped.cc/halloc/ +*/ + +#include "replace.h" +#include "talloc.h" + +#ifdef HAVE_SYS_AUXV_H +#include +#endif + +#if (TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR) +#error "TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR" +#endif + +#if (TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR) +#error "TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR" +#endif + +/* Special macros that are no-ops except when run under Valgrind on + * x86. They've moved a little bit from valgrind 1.0.4 to 1.9.4 */ +#ifdef HAVE_VALGRIND_MEMCHECK_H + /* memcheck.h includes valgrind.h */ +#include +#elif defined(HAVE_VALGRIND_H) +#include +#endif + +/* use this to force every realloc to change the pointer, to stress test + code that might not cope */ +#define ALWAYS_REALLOC 0 + + +#define MAX_TALLOC_SIZE 0x10000000 + +#define TALLOC_FLAG_FREE 0x01 +#define TALLOC_FLAG_LOOP 0x02 +#define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */ +#define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */ + +/* + * Bits above this are random, used to make it harder to fake talloc + * headers during an attack. Try not to change this without good reason. + */ +#define TALLOC_FLAG_MASK 0x0F + +#define TALLOC_MAGIC_REFERENCE ((const char *)1) + +#define TALLOC_MAGIC_BASE 0xe814ec70 +#define TALLOC_MAGIC_NON_RANDOM ( \ + ~TALLOC_FLAG_MASK & ( \ + TALLOC_MAGIC_BASE + \ + (TALLOC_BUILD_VERSION_MAJOR << 24) + \ + (TALLOC_BUILD_VERSION_MINOR << 16) + \ + (TALLOC_BUILD_VERSION_RELEASE << 8))) +static unsigned int talloc_magic = TALLOC_MAGIC_NON_RANDOM; + +/* by default we abort when given a bad pointer (such as when talloc_free() is called + on a pointer that came from malloc() */ +#ifndef TALLOC_ABORT +#define TALLOC_ABORT(reason) abort() +#endif + +#ifndef discard_const_p +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) +# define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr))) +#else +# define discard_const_p(type, ptr) ((type *)(ptr)) +#endif +#endif + +/* these macros gain us a few percent of speed on gcc */ +#if (__GNUC__ >= 3) +/* the strange !! is to ensure that __builtin_expect() takes either 0 or 1 + as its first argument */ +#ifndef likely +#define likely(x) __builtin_expect(!!(x), 1) +#endif +#ifndef unlikely +#define unlikely(x) __builtin_expect(!!(x), 0) +#endif +#else +#ifndef likely +#define likely(x) (x) +#endif +#ifndef unlikely +#define unlikely(x) (x) +#endif +#endif + +/* this null_context is only used if talloc_enable_leak_report() or + talloc_enable_leak_report_full() is called, otherwise it remains + NULL +*/ +static void *null_context; +static bool talloc_report_null; +static bool talloc_report_null_full; +static void *autofree_context; + +static void talloc_setup_atexit(void); + +/* used to enable fill of memory on free, which can be useful for + * catching use after free errors when valgrind is too slow + */ +static struct { + bool initialised; + bool enabled; + uint8_t fill_value; +} talloc_fill; + +#define TALLOC_FILL_ENV "TALLOC_FREE_FILL" + +/* + * do not wipe the header, to allow the + * double-free logic to still work + */ +#define TC_INVALIDATE_FULL_FILL_CHUNK(_tc) do { \ + if (unlikely(talloc_fill.enabled)) { \ + size_t _flen = (_tc)->size; \ + char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \ + memset(_fptr, talloc_fill.fill_value, _flen); \ + } \ +} while (0) + +#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) +/* Mark the whole chunk as not accessable */ +#define TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc) do { \ + size_t _flen = TC_HDR_SIZE + (_tc)->size; \ + char *_fptr = (char *)(_tc); \ + VALGRIND_MAKE_MEM_NOACCESS(_fptr, _flen); \ +} while(0) +#else +#define TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc) do { } while (0) +#endif + +#define TC_INVALIDATE_FULL_CHUNK(_tc) do { \ + TC_INVALIDATE_FULL_FILL_CHUNK(_tc); \ + TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc); \ +} while (0) + +#define TC_INVALIDATE_SHRINK_FILL_CHUNK(_tc, _new_size) do { \ + if (unlikely(talloc_fill.enabled)) { \ + size_t _flen = (_tc)->size - (_new_size); \ + char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \ + _fptr += (_new_size); \ + memset(_fptr, talloc_fill.fill_value, _flen); \ + } \ +} while (0) + +#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) +/* Mark the unused bytes not accessable */ +#define TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { \ + size_t _flen = (_tc)->size - (_new_size); \ + char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \ + _fptr += (_new_size); \ + VALGRIND_MAKE_MEM_NOACCESS(_fptr, _flen); \ +} while (0) +#else +#define TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { } while (0) +#endif + +#define TC_INVALIDATE_SHRINK_CHUNK(_tc, _new_size) do { \ + TC_INVALIDATE_SHRINK_FILL_CHUNK(_tc, _new_size); \ + TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size); \ +} while (0) + +#define TC_UNDEFINE_SHRINK_FILL_CHUNK(_tc, _new_size) do { \ + if (unlikely(talloc_fill.enabled)) { \ + size_t _flen = (_tc)->size - (_new_size); \ + char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \ + _fptr += (_new_size); \ + memset(_fptr, talloc_fill.fill_value, _flen); \ + } \ +} while (0) + +#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) +/* Mark the unused bytes as undefined */ +#define TC_UNDEFINE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { \ + size_t _flen = (_tc)->size - (_new_size); \ + char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \ + _fptr += (_new_size); \ + VALGRIND_MAKE_MEM_UNDEFINED(_fptr, _flen); \ +} while (0) +#else +#define TC_UNDEFINE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { } while (0) +#endif + +#define TC_UNDEFINE_SHRINK_CHUNK(_tc, _new_size) do { \ + TC_UNDEFINE_SHRINK_FILL_CHUNK(_tc, _new_size); \ + TC_UNDEFINE_SHRINK_VALGRIND_CHUNK(_tc, _new_size); \ +} while (0) + +#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) +/* Mark the new bytes as undefined */ +#define TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size) do { \ + size_t _old_used = TC_HDR_SIZE + (_tc)->size; \ + size_t _new_used = TC_HDR_SIZE + (_new_size); \ + size_t _flen = _new_used - _old_used; \ + char *_fptr = _old_used + (char *)(_tc); \ + VALGRIND_MAKE_MEM_UNDEFINED(_fptr, _flen); \ +} while (0) +#else +#define TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size) do { } while (0) +#endif + +#define TC_UNDEFINE_GROW_CHUNK(_tc, _new_size) do { \ + TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size); \ +} while (0) + +struct talloc_reference_handle { + struct talloc_reference_handle *next, *prev; + void *ptr; + const char *location; +}; + +struct talloc_memlimit { + struct talloc_chunk *parent; + struct talloc_memlimit *upper; + size_t max_size; + size_t cur_size; +}; + +static inline bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size); +static inline void talloc_memlimit_grow(struct talloc_memlimit *limit, + size_t size); +static inline void talloc_memlimit_shrink(struct talloc_memlimit *limit, + size_t size); +static inline void tc_memlimit_update_on_free(struct talloc_chunk *tc); + +static inline void _tc_set_name_const(struct talloc_chunk *tc, + const char *name); +static struct talloc_chunk *_vasprintf_tc(const void *t, + const char *fmt, + va_list ap); + +typedef int (*talloc_destructor_t)(void *); + +struct talloc_pool_hdr; + +struct talloc_chunk { + /* + * flags includes the talloc magic, which is randomised to + * make overwrite attacks harder + */ + unsigned flags; + + /* + * If you have a logical tree like: + * + * + * / | \ + * / | \ + * / | \ + * + * + * The actual talloc tree is: + * + * + * | + * - - + * + * The children are linked with next/prev pointers, and + * child 1 is linked to the parent with parent/child + * pointers. + */ + + struct talloc_chunk *next, *prev; + struct talloc_chunk *parent, *child; + struct talloc_reference_handle *refs; + talloc_destructor_t destructor; + const char *name; + size_t size; + + /* + * limit semantics: + * if 'limit' is set it means all *new* children of the context will + * be limited to a total aggregate size ox max_size for memory + * allocations. + * cur_size is used to keep track of the current use + */ + struct talloc_memlimit *limit; + + /* + * For members of a pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool" + * is a pointer to the struct talloc_chunk of the pool that it was + * allocated from. This way children can quickly find the pool to chew + * from. + */ + struct talloc_pool_hdr *pool; +}; + +union talloc_chunk_cast_u { + uint8_t *ptr; + struct talloc_chunk *chunk; +}; + +/* 16 byte alignment seems to keep everyone happy */ +#define TC_ALIGN16(s) (((s)+15)&~15) +#define TC_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_chunk)) +#define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc)) + +_PUBLIC_ int talloc_version_major(void) +{ + return TALLOC_VERSION_MAJOR; +} + +_PUBLIC_ int talloc_version_minor(void) +{ + return TALLOC_VERSION_MINOR; +} + +_PUBLIC_ int talloc_test_get_magic(void) +{ + return talloc_magic; +} + +static inline void _talloc_chunk_set_free(struct talloc_chunk *tc, + const char *location) +{ + /* + * Mark this memory as free, and also over-stamp the talloc + * magic with the old-style magic. + * + * Why? This tries to avoid a memory read use-after-free from + * disclosing our talloc magic, which would then allow an + * attacker to prepare a valid header and so run a destructor. + * + */ + tc->flags = TALLOC_MAGIC_NON_RANDOM | TALLOC_FLAG_FREE + | (tc->flags & TALLOC_FLAG_MASK); + + /* we mark the freed memory with where we called the free + * from. This means on a double free error we can report where + * the first free came from + */ + if (location) { + tc->name = location; + } +} + +static inline void _talloc_chunk_set_not_free(struct talloc_chunk *tc) +{ + /* + * Mark this memory as not free. + * + * Why? This is memory either in a pool (and so available for + * talloc's re-use or after the realloc(). We need to mark + * the memory as free() before any realloc() call as we can't + * write to the memory after that. + * + * We put back the normal magic instead of the 'not random' + * magic. + */ + + tc->flags = talloc_magic | + ((tc->flags & TALLOC_FLAG_MASK) & ~TALLOC_FLAG_FREE); +} + +static void (*talloc_log_fn)(const char *message); + +_PUBLIC_ void talloc_set_log_fn(void (*log_fn)(const char *message)) +{ + talloc_log_fn = log_fn; +} + +#ifdef HAVE_CONSTRUCTOR_ATTRIBUTE +void talloc_lib_init(void) __attribute__((constructor)); +void talloc_lib_init(void) +{ + uint32_t random_value; +#if defined(HAVE_GETAUXVAL) && defined(AT_RANDOM) + uint8_t *p; + /* + * Use the kernel-provided random values used for + * ASLR. This won't change per-exec, which is ideal for us + */ + p = (uint8_t *) getauxval(AT_RANDOM); + if (p) { + /* + * We get 16 bytes from getauxval. By calling rand(), + * a totally insecure PRNG, but one that will + * deterministically have a different value when called + * twice, we ensure that if two talloc-like libraries + * are somehow loaded in the same address space, that + * because we choose different bytes, we will keep the + * protection against collision of multiple talloc + * libs. + * + * This protection is important because the effects of + * passing a talloc pointer from one to the other may + * be very hard to determine. + */ + int offset = rand() % (16 - sizeof(random_value)); + memcpy(&random_value, p + offset, sizeof(random_value)); + } else +#endif + { + /* + * Otherwise, hope the location we are loaded in + * memory is randomised by someone else + */ + random_value = ((uintptr_t)talloc_lib_init & 0xFFFFFFFF); + } + talloc_magic = random_value & ~TALLOC_FLAG_MASK; +} +#else +#warning "No __attribute__((constructor)) support found on this platform, additional talloc security measures not available" +#endif + +static void talloc_lib_atexit(void) +{ + TALLOC_FREE(autofree_context); + + if (talloc_total_size(null_context) == 0) { + return; + } + + if (talloc_report_null_full) { + talloc_report_full(null_context, stderr); + } else if (talloc_report_null) { + talloc_report(null_context, stderr); + } +} + +static void talloc_setup_atexit(void) +{ + static bool done; + + if (done) { + return; + } + + atexit(talloc_lib_atexit); + done = true; +} + +static void talloc_log(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2); +static void talloc_log(const char *fmt, ...) +{ + va_list ap; + char *message; + + if (!talloc_log_fn) { + return; + } + + va_start(ap, fmt); + message = talloc_vasprintf(NULL, fmt, ap); + va_end(ap); + + talloc_log_fn(message); + talloc_free(message); +} + +static void talloc_log_stderr(const char *message) +{ + fprintf(stderr, "%s", message); +} + +_PUBLIC_ void talloc_set_log_stderr(void) +{ + talloc_set_log_fn(talloc_log_stderr); +} + +static void (*talloc_abort_fn)(const char *reason); + +_PUBLIC_ void talloc_set_abort_fn(void (*abort_fn)(const char *reason)) +{ + talloc_abort_fn = abort_fn; +} + +static void talloc_abort(const char *reason) +{ + talloc_log("%s\n", reason); + + if (!talloc_abort_fn) { + TALLOC_ABORT(reason); + } + + talloc_abort_fn(reason); +} + +static void talloc_abort_access_after_free(void) +{ + talloc_abort("Bad talloc magic value - access after free"); +} + +static void talloc_abort_unknown_value(void) +{ + talloc_abort("Bad talloc magic value - unknown value"); +} + +/* panic if we get a bad magic value */ +static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr) +{ + const char *pp = (const char *)ptr; + struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE); + if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~TALLOC_FLAG_MASK)) != talloc_magic)) { + if ((tc->flags & (TALLOC_FLAG_FREE | ~TALLOC_FLAG_MASK)) + == (TALLOC_MAGIC_NON_RANDOM | TALLOC_FLAG_FREE)) { + talloc_log("talloc: access after free error - first free may be at %s\n", tc->name); + talloc_abort_access_after_free(); + return NULL; + } + + talloc_abort_unknown_value(); + return NULL; + } + return tc; +} + +/* hook into the front of the list */ +#define _TLIST_ADD(list, p) \ +do { \ + if (!(list)) { \ + (list) = (p); \ + (p)->next = (p)->prev = NULL; \ + } else { \ + (list)->prev = (p); \ + (p)->next = (list); \ + (p)->prev = NULL; \ + (list) = (p); \ + }\ +} while (0) + +/* remove an element from a list - element doesn't have to be in list. */ +#define _TLIST_REMOVE(list, p) \ +do { \ + if ((p) == (list)) { \ + (list) = (p)->next; \ + if (list) (list)->prev = NULL; \ + } else { \ + if ((p)->prev) (p)->prev->next = (p)->next; \ + if ((p)->next) (p)->next->prev = (p)->prev; \ + } \ + if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \ +} while (0) + + +/* + return the parent chunk of a pointer +*/ +static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr) +{ + struct talloc_chunk *tc; + + if (unlikely(ptr == NULL)) { + return NULL; + } + + tc = talloc_chunk_from_ptr(ptr); + while (tc->prev) tc=tc->prev; + + return tc->parent; +} + +_PUBLIC_ void *talloc_parent(const void *ptr) +{ + struct talloc_chunk *tc = talloc_parent_chunk(ptr); + return tc? TC_PTR_FROM_CHUNK(tc) : NULL; +} + +/* + find parents name +*/ +_PUBLIC_ const char *talloc_parent_name(const void *ptr) +{ + struct talloc_chunk *tc = talloc_parent_chunk(ptr); + return tc? tc->name : NULL; +} + +/* + A pool carries an in-pool object count count in the first 16 bytes. + bytes. This is done to support talloc_steal() to a parent outside of the + pool. The count includes the pool itself, so a talloc_free() on a pool will + only destroy the pool if the count has dropped to zero. A talloc_free() of a + pool member will reduce the count, and eventually also call free(3) on the + pool memory. + + The object count is not put into "struct talloc_chunk" because it is only + relevant for talloc pools and the alignment to 16 bytes would increase the + memory footprint of each talloc chunk by those 16 bytes. +*/ + +struct talloc_pool_hdr { + void *end; + unsigned int object_count; + size_t poolsize; +}; + +union talloc_pool_hdr_cast_u { + uint8_t *ptr; + struct talloc_pool_hdr *hdr; +}; + +#define TP_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_pool_hdr)) + +static inline struct talloc_pool_hdr *talloc_pool_from_chunk(struct talloc_chunk *c) +{ + union talloc_chunk_cast_u tcc = { .chunk = c }; + union talloc_pool_hdr_cast_u tphc = { tcc.ptr - TP_HDR_SIZE }; + return tphc.hdr; +} + +static inline struct talloc_chunk *talloc_chunk_from_pool(struct talloc_pool_hdr *h) +{ + union talloc_pool_hdr_cast_u tphc = { .hdr = h }; + union talloc_chunk_cast_u tcc = { .ptr = tphc.ptr + TP_HDR_SIZE }; + return tcc.chunk; +} + +static inline void *tc_pool_end(struct talloc_pool_hdr *pool_hdr) +{ + struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr); + return (char *)tc + TC_HDR_SIZE + pool_hdr->poolsize; +} + +static inline size_t tc_pool_space_left(struct talloc_pool_hdr *pool_hdr) +{ + return (char *)tc_pool_end(pool_hdr) - (char *)pool_hdr->end; +} + +/* If tc is inside a pool, this gives the next neighbour. */ +static inline void *tc_next_chunk(struct talloc_chunk *tc) +{ + return (char *)tc + TC_ALIGN16(TC_HDR_SIZE + tc->size); +} + +static inline void *tc_pool_first_chunk(struct talloc_pool_hdr *pool_hdr) +{ + struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr); + return tc_next_chunk(tc); +} + +/* Mark the whole remaining pool as not accessable */ +static inline void tc_invalidate_pool(struct talloc_pool_hdr *pool_hdr) +{ + size_t flen = tc_pool_space_left(pool_hdr); + + if (unlikely(talloc_fill.enabled)) { + memset(pool_hdr->end, talloc_fill.fill_value, flen); + } + +#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) + VALGRIND_MAKE_MEM_NOACCESS(pool_hdr->end, flen); +#endif +} + +/* + Allocate from a pool +*/ + +static inline struct talloc_chunk *tc_alloc_pool(struct talloc_chunk *parent, + size_t size, size_t prefix_len) +{ + struct talloc_pool_hdr *pool_hdr = NULL; + union talloc_chunk_cast_u tcc; + size_t space_left; + struct talloc_chunk *result; + size_t chunk_size; + + if (parent == NULL) { + return NULL; + } + + if (parent->flags & TALLOC_FLAG_POOL) { + pool_hdr = talloc_pool_from_chunk(parent); + } + else if (parent->flags & TALLOC_FLAG_POOLMEM) { + pool_hdr = parent->pool; + } + + if (pool_hdr == NULL) { + return NULL; + } + + space_left = tc_pool_space_left(pool_hdr); + + /* + * Align size to 16 bytes + */ + chunk_size = TC_ALIGN16(size + prefix_len); + + if (space_left < chunk_size) { + return NULL; + } + + tcc = (union talloc_chunk_cast_u) { + .ptr = ((uint8_t *)pool_hdr->end) + prefix_len + }; + result = tcc.chunk; + +#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) + VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, chunk_size); +#endif + + pool_hdr->end = (void *)((char *)pool_hdr->end + chunk_size); + + result->flags = talloc_magic | TALLOC_FLAG_POOLMEM; + result->pool = pool_hdr; + + pool_hdr->object_count++; + + return result; +} + +/* + Allocate a bit of memory as a child of an existing pointer +*/ +static inline void *__talloc_with_prefix(const void *context, + size_t size, + size_t prefix_len, + struct talloc_chunk **tc_ret) +{ + struct talloc_chunk *tc = NULL; + struct talloc_memlimit *limit = NULL; + size_t total_len = TC_HDR_SIZE + size + prefix_len; + struct talloc_chunk *parent = NULL; + + if (unlikely(context == NULL)) { + context = null_context; + } + + if (unlikely(size >= MAX_TALLOC_SIZE)) { + return NULL; + } + + if (unlikely(total_len < TC_HDR_SIZE)) { + return NULL; + } + + if (likely(context != NULL)) { + parent = talloc_chunk_from_ptr(context); + + if (parent->limit != NULL) { + limit = parent->limit; + } + + tc = tc_alloc_pool(parent, TC_HDR_SIZE+size, prefix_len); + } + + if (tc == NULL) { + uint8_t *ptr = NULL; + union talloc_chunk_cast_u tcc; + + /* + * Only do the memlimit check/update on actual allocation. + */ + if (!talloc_memlimit_check(limit, total_len)) { + errno = ENOMEM; + return NULL; + } + + ptr = malloc(total_len); + if (unlikely(ptr == NULL)) { + return NULL; + } + tcc = (union talloc_chunk_cast_u) { .ptr = ptr + prefix_len }; + tc = tcc.chunk; + tc->flags = talloc_magic; + tc->pool = NULL; + + talloc_memlimit_grow(limit, total_len); + } + + tc->limit = limit; + tc->size = size; + tc->destructor = NULL; + tc->child = NULL; + tc->name = NULL; + tc->refs = NULL; + + if (likely(context != NULL)) { + if (parent->child) { + parent->child->parent = NULL; + tc->next = parent->child; + tc->next->prev = tc; + } else { + tc->next = NULL; + } + tc->parent = parent; + tc->prev = NULL; + parent->child = tc; + } else { + tc->next = tc->prev = tc->parent = NULL; + } + + *tc_ret = tc; + return TC_PTR_FROM_CHUNK(tc); +} + +static inline void *__talloc(const void *context, + size_t size, + struct talloc_chunk **tc) +{ + return __talloc_with_prefix(context, size, 0, tc); +} + +/* + * Create a talloc pool + */ + +static inline void *_talloc_pool(const void *context, size_t size) +{ + struct talloc_chunk *tc; + struct talloc_pool_hdr *pool_hdr; + void *result; + + result = __talloc_with_prefix(context, size, TP_HDR_SIZE, &tc); + + if (unlikely(result == NULL)) { + return NULL; + } + + pool_hdr = talloc_pool_from_chunk(tc); + + tc->flags |= TALLOC_FLAG_POOL; + tc->size = 0; + + pool_hdr->object_count = 1; + pool_hdr->end = result; + pool_hdr->poolsize = size; + + tc_invalidate_pool(pool_hdr); + + return result; +} + +_PUBLIC_ void *talloc_pool(const void *context, size_t size) +{ + return _talloc_pool(context, size); +} + +/* + * Create a talloc pool correctly sized for a basic size plus + * a number of subobjects whose total size is given. Essentially + * a custom allocator for talloc to reduce fragmentation. + */ + +_PUBLIC_ void *_talloc_pooled_object(const void *ctx, + size_t type_size, + const char *type_name, + unsigned num_subobjects, + size_t total_subobjects_size) +{ + size_t poolsize, subobjects_slack, tmp; + struct talloc_chunk *tc; + struct talloc_pool_hdr *pool_hdr; + void *ret; + + poolsize = type_size + total_subobjects_size; + + if ((poolsize < type_size) || (poolsize < total_subobjects_size)) { + goto overflow; + } + + if (num_subobjects == UINT_MAX) { + goto overflow; + } + num_subobjects += 1; /* the object body itself */ + + /* + * Alignment can increase the pool size by at most 15 bytes per object + * plus alignment for the object itself + */ + subobjects_slack = (TC_HDR_SIZE + TP_HDR_SIZE + 15) * num_subobjects; + if (subobjects_slack < num_subobjects) { + goto overflow; + } + + tmp = poolsize + subobjects_slack; + if ((tmp < poolsize) || (tmp < subobjects_slack)) { + goto overflow; + } + poolsize = tmp; + + ret = _talloc_pool(ctx, poolsize); + if (ret == NULL) { + return NULL; + } + + tc = talloc_chunk_from_ptr(ret); + tc->size = type_size; + + pool_hdr = talloc_pool_from_chunk(tc); + +#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) + VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, type_size); +#endif + + pool_hdr->end = ((char *)pool_hdr->end + TC_ALIGN16(type_size)); + + _tc_set_name_const(tc, type_name); + return ret; + +overflow: + return NULL; +} + +/* + setup a destructor to be called on free of a pointer + the destructor should return 0 on success, or -1 on failure. + if the destructor fails then the free is failed, and the memory can + be continued to be used +*/ +_PUBLIC_ void _talloc_set_destructor(const void *ptr, int (*destructor)(void *)) +{ + struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); + tc->destructor = destructor; +} + +/* + increase the reference count on a piece of memory. +*/ +_PUBLIC_ int talloc_increase_ref_count(const void *ptr) +{ + if (unlikely(!talloc_reference(null_context, ptr))) { + return -1; + } + return 0; +} + +/* + helper for talloc_reference() + + this is referenced by a function pointer and should not be inline +*/ +static int talloc_reference_destructor(struct talloc_reference_handle *handle) +{ + struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr); + _TLIST_REMOVE(ptr_tc->refs, handle); + return 0; +} + +/* + more efficient way to add a name to a pointer - the name must point to a + true string constant +*/ +static inline void _tc_set_name_const(struct talloc_chunk *tc, + const char *name) +{ + tc->name = name; +} + +/* + internal talloc_named_const() +*/ +static inline void *_talloc_named_const(const void *context, size_t size, const char *name) +{ + void *ptr; + struct talloc_chunk *tc; + + ptr = __talloc(context, size, &tc); + if (unlikely(ptr == NULL)) { + return NULL; + } + + _tc_set_name_const(tc, name); + + return ptr; +} + +/* + make a secondary reference to a pointer, hanging off the given context. + the pointer remains valid until both the original caller and this given + context are freed. + + the major use for this is when two different structures need to reference the + same underlying data, and you want to be able to free the two instances separately, + and in either order +*/ +_PUBLIC_ void *_talloc_reference_loc(const void *context, const void *ptr, const char *location) +{ + struct talloc_chunk *tc; + struct talloc_reference_handle *handle; + if (unlikely(ptr == NULL)) return NULL; + + tc = talloc_chunk_from_ptr(ptr); + handle = (struct talloc_reference_handle *)_talloc_named_const(context, + sizeof(struct talloc_reference_handle), + TALLOC_MAGIC_REFERENCE); + if (unlikely(handle == NULL)) return NULL; + + /* note that we hang the destructor off the handle, not the + main context as that allows the caller to still setup their + own destructor on the context if they want to */ + talloc_set_destructor(handle, talloc_reference_destructor); + handle->ptr = discard_const_p(void, ptr); + handle->location = location; + _TLIST_ADD(tc->refs, handle); + return handle->ptr; +} + +static void *_talloc_steal_internal(const void *new_ctx, const void *ptr); + +static inline void _tc_free_poolmem(struct talloc_chunk *tc, + const char *location) +{ + struct talloc_pool_hdr *pool; + struct talloc_chunk *pool_tc; + void *next_tc; + + pool = tc->pool; + pool_tc = talloc_chunk_from_pool(pool); + next_tc = tc_next_chunk(tc); + + _talloc_chunk_set_free(tc, location); + + TC_INVALIDATE_FULL_CHUNK(tc); + + if (unlikely(pool->object_count == 0)) { + talloc_abort("Pool object count zero!"); + return; + } + + pool->object_count--; + + if (unlikely(pool->object_count == 1 + && !(pool_tc->flags & TALLOC_FLAG_FREE))) { + /* + * if there is just one object left in the pool + * and pool->flags does not have TALLOC_FLAG_FREE, + * it means this is the pool itself and + * the rest is available for new objects + * again. + */ + pool->end = tc_pool_first_chunk(pool); + tc_invalidate_pool(pool); + return; + } + + if (unlikely(pool->object_count == 0)) { + /* + * we mark the freed memory with where we called the free + * from. This means on a double free error we can report where + * the first free came from + */ + pool_tc->name = location; + + if (pool_tc->flags & TALLOC_FLAG_POOLMEM) { + _tc_free_poolmem(pool_tc, location); + } else { + /* + * The tc_memlimit_update_on_free() + * call takes into account the + * prefix TP_HDR_SIZE allocated before + * the pool talloc_chunk. + */ + tc_memlimit_update_on_free(pool_tc); + TC_INVALIDATE_FULL_CHUNK(pool_tc); + free(pool); + } + return; + } + + if (pool->end == next_tc) { + /* + * if pool->pool still points to end of + * 'tc' (which is stored in the 'next_tc' variable), + * we can reclaim the memory of 'tc'. + */ + pool->end = tc; + return; + } + + /* + * Do nothing. The memory is just "wasted", waiting for the pool + * itself to be freed. + */ +} + +static inline void _tc_free_children_internal(struct talloc_chunk *tc, + void *ptr, + const char *location); + +static inline int _talloc_free_internal(void *ptr, const char *location); + +/* + internal free call that takes a struct talloc_chunk *. +*/ +static inline int _tc_free_internal(struct talloc_chunk *tc, + const char *location) +{ + void *ptr_to_free; + void *ptr = TC_PTR_FROM_CHUNK(tc); + + if (unlikely(tc->refs)) { + int is_child; + /* check if this is a reference from a child or + * grandchild back to it's parent or grandparent + * + * in that case we need to remove the reference and + * call another instance of talloc_free() on the current + * pointer. + */ + is_child = talloc_is_parent(tc->refs, ptr); + _talloc_free_internal(tc->refs, location); + if (is_child) { + return _talloc_free_internal(ptr, location); + } + return -1; + } + + if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) { + /* we have a free loop - stop looping */ + return 0; + } + + if (unlikely(tc->destructor)) { + talloc_destructor_t d = tc->destructor; + + /* + * Protect the destructor against some overwrite + * attacks, by explicitly checking it has the right + * magic here. + */ + if (talloc_chunk_from_ptr(ptr) != tc) { + /* + * This can't actually happen, the + * call itself will panic. + */ + TALLOC_ABORT("talloc_chunk_from_ptr failed!"); + } + + if (d == (talloc_destructor_t)-1) { + return -1; + } + tc->destructor = (talloc_destructor_t)-1; + if (d(ptr) == -1) { + /* + * Only replace the destructor pointer if + * calling the destructor didn't modify it. + */ + if (tc->destructor == (talloc_destructor_t)-1) { + tc->destructor = d; + } + return -1; + } + tc->destructor = NULL; + } + + if (tc->parent) { + _TLIST_REMOVE(tc->parent->child, tc); + if (tc->parent->child) { + tc->parent->child->parent = tc->parent; + } + } else { + if (tc->prev) tc->prev->next = tc->next; + if (tc->next) tc->next->prev = tc->prev; + tc->prev = tc->next = NULL; + } + + tc->flags |= TALLOC_FLAG_LOOP; + + _tc_free_children_internal(tc, ptr, location); + + _talloc_chunk_set_free(tc, location); + + if (tc->flags & TALLOC_FLAG_POOL) { + struct talloc_pool_hdr *pool; + + pool = talloc_pool_from_chunk(tc); + + if (unlikely(pool->object_count == 0)) { + talloc_abort("Pool object count zero!"); + return 0; + } + + pool->object_count--; + + if (likely(pool->object_count != 0)) { + return 0; + } + + /* + * With object_count==0, a pool becomes a normal piece of + * memory to free. If it's allocated inside a pool, it needs + * to be freed as poolmem, else it needs to be just freed. + */ + ptr_to_free = pool; + } else { + ptr_to_free = tc; + } + + if (tc->flags & TALLOC_FLAG_POOLMEM) { + _tc_free_poolmem(tc, location); + return 0; + } + + tc_memlimit_update_on_free(tc); + + TC_INVALIDATE_FULL_CHUNK(tc); + free(ptr_to_free); + return 0; +} + +/* + internal talloc_free call +*/ +static inline int _talloc_free_internal(void *ptr, const char *location) +{ + struct talloc_chunk *tc; + + if (unlikely(ptr == NULL)) { + return -1; + } + + /* possibly initialised the talloc fill value */ + if (unlikely(!talloc_fill.initialised)) { + const char *fill = getenv(TALLOC_FILL_ENV); + if (fill != NULL) { + talloc_fill.enabled = true; + talloc_fill.fill_value = strtoul(fill, NULL, 0); + } + talloc_fill.initialised = true; + } + + tc = talloc_chunk_from_ptr(ptr); + return _tc_free_internal(tc, location); +} + +static inline size_t _talloc_total_limit_size(const void *ptr, + struct talloc_memlimit *old_limit, + struct talloc_memlimit *new_limit); + +/* + move a lump of memory from one talloc context to another return the + ptr on success, or NULL if it could not be transferred. + passing NULL as ptr will always return NULL with no side effects. +*/ +static void *_talloc_steal_internal(const void *new_ctx, const void *ptr) +{ + struct talloc_chunk *tc, *new_tc; + size_t ctx_size = 0; + + if (unlikely(!ptr)) { + return NULL; + } + + if (unlikely(new_ctx == NULL)) { + new_ctx = null_context; + } + + tc = talloc_chunk_from_ptr(ptr); + + if (tc->limit != NULL) { + + ctx_size = _talloc_total_limit_size(ptr, NULL, NULL); + + /* Decrement the memory limit from the source .. */ + talloc_memlimit_shrink(tc->limit->upper, ctx_size); + + if (tc->limit->parent == tc) { + tc->limit->upper = NULL; + } else { + tc->limit = NULL; + } + } + + if (unlikely(new_ctx == NULL)) { + if (tc->parent) { + _TLIST_REMOVE(tc->parent->child, tc); + if (tc->parent->child) { + tc->parent->child->parent = tc->parent; + } + } else { + if (tc->prev) tc->prev->next = tc->next; + if (tc->next) tc->next->prev = tc->prev; + } + + tc->parent = tc->next = tc->prev = NULL; + return discard_const_p(void, ptr); + } + + new_tc = talloc_chunk_from_ptr(new_ctx); + + if (unlikely(tc == new_tc || tc->parent == new_tc)) { + return discard_const_p(void, ptr); + } + + if (tc->parent) { + _TLIST_REMOVE(tc->parent->child, tc); + if (tc->parent->child) { + tc->parent->child->parent = tc->parent; + } + } else { + if (tc->prev) tc->prev->next = tc->next; + if (tc->next) tc->next->prev = tc->prev; + tc->prev = tc->next = NULL; + } + + tc->parent = new_tc; + if (new_tc->child) new_tc->child->parent = NULL; + _TLIST_ADD(new_tc->child, tc); + + if (tc->limit || new_tc->limit) { + ctx_size = _talloc_total_limit_size(ptr, tc->limit, + new_tc->limit); + /* .. and increment it in the destination. */ + if (new_tc->limit) { + talloc_memlimit_grow(new_tc->limit, ctx_size); + } + } + + return discard_const_p(void, ptr); +} + +/* + move a lump of memory from one talloc context to another return the + ptr on success, or NULL if it could not be transferred. + passing NULL as ptr will always return NULL with no side effects. +*/ +_PUBLIC_ void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const char *location) +{ + struct talloc_chunk *tc; + + if (unlikely(ptr == NULL)) { + return NULL; + } + + tc = talloc_chunk_from_ptr(ptr); + + if (unlikely(tc->refs != NULL) && talloc_parent(ptr) != new_ctx) { + struct talloc_reference_handle *h; + + talloc_log("WARNING: talloc_steal with references at %s\n", + location); + + for (h=tc->refs; h; h=h->next) { + talloc_log("\treference at %s\n", + h->location); + } + } + +#if 0 + /* this test is probably too expensive to have on in the + normal build, but it useful for debugging */ + if (talloc_is_parent(new_ctx, ptr)) { + talloc_log("WARNING: stealing into talloc child at %s\n", location); + } +#endif + + return _talloc_steal_internal(new_ctx, ptr); +} + +/* + this is like a talloc_steal(), but you must supply the old + parent. This resolves the ambiguity in a talloc_steal() which is + called on a context that has more than one parent (via references) + + The old parent can be either a reference or a parent +*/ +_PUBLIC_ void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr) +{ + struct talloc_chunk *tc; + struct talloc_reference_handle *h; + + if (unlikely(ptr == NULL)) { + return NULL; + } + + if (old_parent == talloc_parent(ptr)) { + return _talloc_steal_internal(new_parent, ptr); + } + + tc = talloc_chunk_from_ptr(ptr); + for (h=tc->refs;h;h=h->next) { + if (talloc_parent(h) == old_parent) { + if (_talloc_steal_internal(new_parent, h) != h) { + return NULL; + } + return discard_const_p(void, ptr); + } + } + + /* it wasn't a parent */ + return NULL; +} + +/* + remove a secondary reference to a pointer. This undo's what + talloc_reference() has done. The context and pointer arguments + must match those given to a talloc_reference() +*/ +static inline int talloc_unreference(const void *context, const void *ptr) +{ + struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); + struct talloc_reference_handle *h; + + if (unlikely(context == NULL)) { + context = null_context; + } + + for (h=tc->refs;h;h=h->next) { + struct talloc_chunk *p = talloc_parent_chunk(h); + if (p == NULL) { + if (context == NULL) break; + } else if (TC_PTR_FROM_CHUNK(p) == context) { + break; + } + } + if (h == NULL) { + return -1; + } + + return _talloc_free_internal(h, __location__); +} + +/* + remove a specific parent context from a pointer. This is a more + controlled variant of talloc_free() +*/ +_PUBLIC_ int talloc_unlink(const void *context, void *ptr) +{ + struct talloc_chunk *tc_p, *new_p, *tc_c; + void *new_parent; + + if (ptr == NULL) { + return -1; + } + + if (context == NULL) { + context = null_context; + } + + if (talloc_unreference(context, ptr) == 0) { + return 0; + } + + if (context != NULL) { + tc_c = talloc_chunk_from_ptr(context); + } else { + tc_c = NULL; + } + if (tc_c != talloc_parent_chunk(ptr)) { + return -1; + } + + tc_p = talloc_chunk_from_ptr(ptr); + + if (tc_p->refs == NULL) { + return _talloc_free_internal(ptr, __location__); + } + + new_p = talloc_parent_chunk(tc_p->refs); + if (new_p) { + new_parent = TC_PTR_FROM_CHUNK(new_p); + } else { + new_parent = NULL; + } + + if (talloc_unreference(new_parent, ptr) != 0) { + return -1; + } + + _talloc_steal_internal(new_parent, ptr); + + return 0; +} + +/* + add a name to an existing pointer - va_list version +*/ +static inline const char *tc_set_name_v(struct talloc_chunk *tc, + const char *fmt, + va_list ap) PRINTF_ATTRIBUTE(2,0); + +static inline const char *tc_set_name_v(struct talloc_chunk *tc, + const char *fmt, + va_list ap) +{ + struct talloc_chunk *name_tc = _vasprintf_tc(TC_PTR_FROM_CHUNK(tc), + fmt, + ap); + if (likely(name_tc)) { + tc->name = TC_PTR_FROM_CHUNK(name_tc); + _tc_set_name_const(name_tc, ".name"); + } else { + tc->name = NULL; + } + return tc->name; +} + +/* + add a name to an existing pointer +*/ +_PUBLIC_ const char *talloc_set_name(const void *ptr, const char *fmt, ...) +{ + struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); + const char *name; + va_list ap; + va_start(ap, fmt); + name = tc_set_name_v(tc, fmt, ap); + va_end(ap); + return name; +} + + +/* + create a named talloc pointer. Any talloc pointer can be named, and + talloc_named() operates just like talloc() except that it allows you + to name the pointer. +*/ +_PUBLIC_ void *talloc_named(const void *context, size_t size, const char *fmt, ...) +{ + va_list ap; + void *ptr; + const char *name; + struct talloc_chunk *tc; + + ptr = __talloc(context, size, &tc); + if (unlikely(ptr == NULL)) return NULL; + + va_start(ap, fmt); + name = tc_set_name_v(tc, fmt, ap); + va_end(ap); + + if (unlikely(name == NULL)) { + _talloc_free_internal(ptr, __location__); + return NULL; + } + + return ptr; +} + +/* + return the name of a talloc ptr, or "UNNAMED" +*/ +static inline const char *__talloc_get_name(const void *ptr) +{ + struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); + if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) { + return ".reference"; + } + if (likely(tc->name)) { + return tc->name; + } + return "UNNAMED"; +} + +_PUBLIC_ const char *talloc_get_name(const void *ptr) +{ + return __talloc_get_name(ptr); +} + +/* + check if a pointer has the given name. If it does, return the pointer, + otherwise return NULL +*/ +_PUBLIC_ void *talloc_check_name(const void *ptr, const char *name) +{ + const char *pname; + if (unlikely(ptr == NULL)) return NULL; + pname = __talloc_get_name(ptr); + if (likely(pname == name || strcmp(pname, name) == 0)) { + return discard_const_p(void, ptr); + } + return NULL; +} + +static void talloc_abort_type_mismatch(const char *location, + const char *name, + const char *expected) +{ + const char *reason; + + reason = talloc_asprintf(NULL, + "%s: Type mismatch: name[%s] expected[%s]", + location, + name?name:"NULL", + expected); + if (!reason) { + reason = "Type mismatch"; + } + + talloc_abort(reason); +} + +_PUBLIC_ void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location) +{ + const char *pname; + + if (unlikely(ptr == NULL)) { + talloc_abort_type_mismatch(location, NULL, name); + return NULL; + } + + pname = __talloc_get_name(ptr); + if (likely(pname == name || strcmp(pname, name) == 0)) { + return discard_const_p(void, ptr); + } + + talloc_abort_type_mismatch(location, pname, name); + return NULL; +} + +/* + this is for compatibility with older versions of talloc +*/ +_PUBLIC_ void *talloc_init(const char *fmt, ...) +{ + va_list ap; + void *ptr; + const char *name; + struct talloc_chunk *tc; + + ptr = __talloc(NULL, 0, &tc); + if (unlikely(ptr == NULL)) return NULL; + + va_start(ap, fmt); + name = tc_set_name_v(tc, fmt, ap); + va_end(ap); + + if (unlikely(name == NULL)) { + _talloc_free_internal(ptr, __location__); + return NULL; + } + + return ptr; +} + +static inline void _tc_free_children_internal(struct talloc_chunk *tc, + void *ptr, + const char *location) +{ + while (tc->child) { + /* we need to work out who will own an abandoned child + if it cannot be freed. In priority order, the first + choice is owner of any remaining reference to this + pointer, the second choice is our parent, and the + final choice is the null context. */ + void *child = TC_PTR_FROM_CHUNK(tc->child); + const void *new_parent = null_context; + if (unlikely(tc->child->refs)) { + struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs); + if (p) new_parent = TC_PTR_FROM_CHUNK(p); + } + if (unlikely(_tc_free_internal(tc->child, location) == -1)) { + if (talloc_parent_chunk(child) != tc) { + /* + * Destructor already reparented this child. + * No further reparenting needed. + */ + continue; + } + if (new_parent == null_context) { + struct talloc_chunk *p = talloc_parent_chunk(ptr); + if (p) new_parent = TC_PTR_FROM_CHUNK(p); + } + _talloc_steal_internal(new_parent, child); + } + } +} + +/* + this is a replacement for the Samba3 talloc_destroy_pool functionality. It + should probably not be used in new code. It's in here to keep the talloc + code consistent across Samba 3 and 4. +*/ +_PUBLIC_ void talloc_free_children(void *ptr) +{ + struct talloc_chunk *tc_name = NULL; + struct talloc_chunk *tc; + + if (unlikely(ptr == NULL)) { + return; + } + + tc = talloc_chunk_from_ptr(ptr); + + /* we do not want to free the context name if it is a child .. */ + if (likely(tc->child)) { + for (tc_name = tc->child; tc_name; tc_name = tc_name->next) { + if (tc->name == TC_PTR_FROM_CHUNK(tc_name)) break; + } + if (tc_name) { + _TLIST_REMOVE(tc->child, tc_name); + if (tc->child) { + tc->child->parent = tc; + } + } + } + + _tc_free_children_internal(tc, ptr, __location__); + + /* .. so we put it back after all other children have been freed */ + if (tc_name) { + if (tc->child) { + tc->child->parent = NULL; + } + tc_name->parent = tc; + _TLIST_ADD(tc->child, tc_name); + } +} + +/* + Allocate a bit of memory as a child of an existing pointer +*/ +_PUBLIC_ void *_talloc(const void *context, size_t size) +{ + struct talloc_chunk *tc; + return __talloc(context, size, &tc); +} + +/* + externally callable talloc_set_name_const() +*/ +_PUBLIC_ void talloc_set_name_const(const void *ptr, const char *name) +{ + _tc_set_name_const(talloc_chunk_from_ptr(ptr), name); +} + +/* + create a named talloc pointer. Any talloc pointer can be named, and + talloc_named() operates just like talloc() except that it allows you + to name the pointer. +*/ +_PUBLIC_ void *talloc_named_const(const void *context, size_t size, const char *name) +{ + return _talloc_named_const(context, size, name); +} + +/* + free a talloc pointer. This also frees all child pointers of this + pointer recursively + + return 0 if the memory is actually freed, otherwise -1. The memory + will not be freed if the ref_count is > 1 or the destructor (if + any) returns non-zero +*/ +_PUBLIC_ int _talloc_free(void *ptr, const char *location) +{ + struct talloc_chunk *tc; + + if (unlikely(ptr == NULL)) { + return -1; + } + + tc = talloc_chunk_from_ptr(ptr); + + if (unlikely(tc->refs != NULL)) { + struct talloc_reference_handle *h; + + if (talloc_parent(ptr) == null_context && tc->refs->next == NULL) { + /* in this case we do know which parent should + get this pointer, as there is really only + one parent */ + return talloc_unlink(null_context, ptr); + } + + talloc_log("ERROR: talloc_free with references at %s\n", + location); + + for (h=tc->refs; h; h=h->next) { + talloc_log("\treference at %s\n", + h->location); + } + return -1; + } + + return _talloc_free_internal(ptr, location); +} + + + +/* + A talloc version of realloc. The context argument is only used if + ptr is NULL +*/ +_PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name) +{ + struct talloc_chunk *tc; + void *new_ptr; + bool malloced = false; + struct talloc_pool_hdr *pool_hdr = NULL; + size_t old_size = 0; + size_t new_size = 0; + + /* size zero is equivalent to free() */ + if (unlikely(size == 0)) { + talloc_unlink(context, ptr); + return NULL; + } + + if (unlikely(size >= MAX_TALLOC_SIZE)) { + return NULL; + } + + /* realloc(NULL) is equivalent to malloc() */ + if (ptr == NULL) { + return _talloc_named_const(context, size, name); + } + + tc = talloc_chunk_from_ptr(ptr); + + /* don't allow realloc on referenced pointers */ + if (unlikely(tc->refs)) { + return NULL; + } + + /* don't let anybody try to realloc a talloc_pool */ + if (unlikely(tc->flags & TALLOC_FLAG_POOL)) { + return NULL; + } + + if (tc->limit && (size > tc->size)) { + if (!talloc_memlimit_check(tc->limit, (size - tc->size))) { + errno = ENOMEM; + return NULL; + } + } + + /* handle realloc inside a talloc_pool */ + if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) { + pool_hdr = tc->pool; + } + +#if (ALWAYS_REALLOC == 0) + /* don't shrink if we have less than 1k to gain */ + if (size < tc->size && tc->limit == NULL) { + if (pool_hdr) { + void *next_tc = tc_next_chunk(tc); + TC_INVALIDATE_SHRINK_CHUNK(tc, size); + tc->size = size; + if (next_tc == pool_hdr->end) { + /* note: tc->size has changed, so this works */ + pool_hdr->end = tc_next_chunk(tc); + } + return ptr; + } else if ((tc->size - size) < 1024) { + /* + * if we call TC_INVALIDATE_SHRINK_CHUNK() here + * we would need to call TC_UNDEFINE_GROW_CHUNK() + * after each realloc call, which slows down + * testing a lot :-(. + * + * That is why we only mark memory as undefined here. + */ + TC_UNDEFINE_SHRINK_CHUNK(tc, size); + + /* do not shrink if we have less than 1k to gain */ + tc->size = size; + return ptr; + } + } else if (tc->size == size) { + /* + * do not change the pointer if it is exactly + * the same size. + */ + return ptr; + } +#endif + + /* + * by resetting magic we catch users of the old memory + * + * We mark this memory as free, and also over-stamp the talloc + * magic with the old-style magic. + * + * Why? This tries to avoid a memory read use-after-free from + * disclosing our talloc magic, which would then allow an + * attacker to prepare a valid header and so run a destructor. + * + * What else? We have to re-stamp back a valid normal magic + * on this memory once realloc() is done, as it will have done + * a memcpy() into the new valid memory. We can't do this in + * reverse as that would be a real use-after-free. + */ + _talloc_chunk_set_free(tc, NULL); + +#if ALWAYS_REALLOC + if (pool_hdr) { + new_ptr = tc_alloc_pool(tc, size + TC_HDR_SIZE, 0); + pool_hdr->object_count--; + + if (new_ptr == NULL) { + new_ptr = malloc(TC_HDR_SIZE+size); + malloced = true; + new_size = size; + } + + if (new_ptr) { + memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE); + TC_INVALIDATE_FULL_CHUNK(tc); + } + } else { + /* We're doing malloc then free here, so record the difference. */ + old_size = tc->size; + new_size = size; + new_ptr = malloc(size + TC_HDR_SIZE); + if (new_ptr) { + memcpy(new_ptr, tc, MIN(tc->size, size) + TC_HDR_SIZE); + free(tc); + } + } +#else + if (pool_hdr) { + struct talloc_chunk *pool_tc; + void *next_tc = tc_next_chunk(tc); + size_t old_chunk_size = TC_ALIGN16(TC_HDR_SIZE + tc->size); + size_t new_chunk_size = TC_ALIGN16(TC_HDR_SIZE + size); + size_t space_needed; + size_t space_left; + unsigned int chunk_count = pool_hdr->object_count; + + pool_tc = talloc_chunk_from_pool(pool_hdr); + if (!(pool_tc->flags & TALLOC_FLAG_FREE)) { + chunk_count -= 1; + } + + if (chunk_count == 1) { + /* + * optimize for the case where 'tc' is the only + * chunk in the pool. + */ + char *start = tc_pool_first_chunk(pool_hdr); + space_needed = new_chunk_size; + space_left = (char *)tc_pool_end(pool_hdr) - start; + + if (space_left >= space_needed) { + size_t old_used = TC_HDR_SIZE + tc->size; + size_t new_used = TC_HDR_SIZE + size; + new_ptr = start; + +#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) + { + /* + * The area from + * start -> tc may have + * been freed and thus been marked as + * VALGRIND_MEM_NOACCESS. Set it to + * VALGRIND_MEM_UNDEFINED so we can + * copy into it without valgrind errors. + * We can't just mark + * new_ptr -> new_ptr + old_used + * as this may overlap on top of tc, + * (which is why we use memmove, not + * memcpy below) hence the MIN. + */ + size_t undef_len = MIN((((char *)tc) - ((char *)new_ptr)),old_used); + VALGRIND_MAKE_MEM_UNDEFINED(new_ptr, undef_len); + } +#endif + + memmove(new_ptr, tc, old_used); + + tc = (struct talloc_chunk *)new_ptr; + TC_UNDEFINE_GROW_CHUNK(tc, size); + + /* + * first we do not align the pool pointer + * because we want to invalidate the padding + * too. + */ + pool_hdr->end = new_used + (char *)new_ptr; + tc_invalidate_pool(pool_hdr); + + /* now the aligned pointer */ + pool_hdr->end = new_chunk_size + (char *)new_ptr; + goto got_new_ptr; + } + + next_tc = NULL; + } + + if (new_chunk_size == old_chunk_size) { + TC_UNDEFINE_GROW_CHUNK(tc, size); + _talloc_chunk_set_not_free(tc); + tc->size = size; + return ptr; + } + + if (next_tc == pool_hdr->end) { + /* + * optimize for the case where 'tc' is the last + * chunk in the pool. + */ + space_needed = new_chunk_size - old_chunk_size; + space_left = tc_pool_space_left(pool_hdr); + + if (space_left >= space_needed) { + TC_UNDEFINE_GROW_CHUNK(tc, size); + _talloc_chunk_set_not_free(tc); + tc->size = size; + pool_hdr->end = tc_next_chunk(tc); + return ptr; + } + } + + new_ptr = tc_alloc_pool(tc, size + TC_HDR_SIZE, 0); + + if (new_ptr == NULL) { + new_ptr = malloc(TC_HDR_SIZE+size); + malloced = true; + new_size = size; + } + + if (new_ptr) { + memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE); + + _tc_free_poolmem(tc, __location__ "_talloc_realloc"); + } + } + else { + /* We're doing realloc here, so record the difference. */ + old_size = tc->size; + new_size = size; + new_ptr = realloc(tc, size + TC_HDR_SIZE); + } +got_new_ptr: +#endif + if (unlikely(!new_ptr)) { + /* + * Ok, this is a strange spot. We have to put back + * the old talloc_magic and any flags, except the + * TALLOC_FLAG_FREE as this was not free'ed by the + * realloc() call after all + */ + _talloc_chunk_set_not_free(tc); + return NULL; + } + + /* + * tc is now the new value from realloc(), the old memory we + * can't access any more and was preemptively marked as + * TALLOC_FLAG_FREE before the call. Now we mark it as not + * free again + */ + tc = (struct talloc_chunk *)new_ptr; + _talloc_chunk_set_not_free(tc); + if (malloced) { + tc->flags &= ~TALLOC_FLAG_POOLMEM; + } + if (tc->parent) { + tc->parent->child = tc; + } + if (tc->child) { + tc->child->parent = tc; + } + + if (tc->prev) { + tc->prev->next = tc; + } + if (tc->next) { + tc->next->prev = tc; + } + + if (new_size > old_size) { + talloc_memlimit_grow(tc->limit, new_size - old_size); + } else if (new_size < old_size) { + talloc_memlimit_shrink(tc->limit, old_size - new_size); + } + + tc->size = size; + _tc_set_name_const(tc, name); + + return TC_PTR_FROM_CHUNK(tc); +} + +/* + a wrapper around talloc_steal() for situations where you are moving a pointer + between two structures, and want the old pointer to be set to NULL +*/ +_PUBLIC_ void *_talloc_move(const void *new_ctx, const void *_pptr) +{ + const void **pptr = discard_const_p(const void *,_pptr); + void *ret = talloc_steal(new_ctx, discard_const_p(void, *pptr)); + (*pptr) = NULL; + return ret; +} + +enum talloc_mem_count_type { + TOTAL_MEM_SIZE, + TOTAL_MEM_BLOCKS, + TOTAL_MEM_LIMIT, +}; + +static inline size_t _talloc_total_mem_internal(const void *ptr, + enum talloc_mem_count_type type, + struct talloc_memlimit *old_limit, + struct talloc_memlimit *new_limit) +{ + size_t total = 0; + struct talloc_chunk *c, *tc; + + if (ptr == NULL) { + ptr = null_context; + } + if (ptr == NULL) { + return 0; + } + + tc = talloc_chunk_from_ptr(ptr); + + if (old_limit || new_limit) { + if (tc->limit && tc->limit->upper == old_limit) { + tc->limit->upper = new_limit; + } + } + + /* optimize in the memlimits case */ + if (type == TOTAL_MEM_LIMIT && + tc->limit != NULL && + tc->limit != old_limit && + tc->limit->parent == tc) { + return tc->limit->cur_size; + } + + if (tc->flags & TALLOC_FLAG_LOOP) { + return 0; + } + + tc->flags |= TALLOC_FLAG_LOOP; + + if (old_limit || new_limit) { + if (old_limit == tc->limit) { + tc->limit = new_limit; + } + } + + switch (type) { + case TOTAL_MEM_SIZE: + if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) { + total = tc->size; + } + break; + case TOTAL_MEM_BLOCKS: + total++; + break; + case TOTAL_MEM_LIMIT: + if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) { + /* + * Don't count memory allocated from a pool + * when calculating limits. Only count the + * pool itself. + */ + if (!(tc->flags & TALLOC_FLAG_POOLMEM)) { + if (tc->flags & TALLOC_FLAG_POOL) { + /* + * If this is a pool, the allocated + * size is in the pool header, and + * remember to add in the prefix + * length. + */ + struct talloc_pool_hdr *pool_hdr + = talloc_pool_from_chunk(tc); + total = pool_hdr->poolsize + + TC_HDR_SIZE + + TP_HDR_SIZE; + } else { + total = tc->size + TC_HDR_SIZE; + } + } + } + break; + } + for (c = tc->child; c; c = c->next) { + total += _talloc_total_mem_internal(TC_PTR_FROM_CHUNK(c), type, + old_limit, new_limit); + } + + tc->flags &= ~TALLOC_FLAG_LOOP; + + return total; +} + +/* + return the total size of a talloc pool (subtree) +*/ +_PUBLIC_ size_t talloc_total_size(const void *ptr) +{ + return _talloc_total_mem_internal(ptr, TOTAL_MEM_SIZE, NULL, NULL); +} + +/* + return the total number of blocks in a talloc pool (subtree) +*/ +_PUBLIC_ size_t talloc_total_blocks(const void *ptr) +{ + return _talloc_total_mem_internal(ptr, TOTAL_MEM_BLOCKS, NULL, NULL); +} + +/* + return the number of external references to a pointer +*/ +_PUBLIC_ size_t talloc_reference_count(const void *ptr) +{ + struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); + struct talloc_reference_handle *h; + size_t ret = 0; + + for (h=tc->refs;h;h=h->next) { + ret++; + } + return ret; +} + +/* + report on memory usage by all children of a pointer, giving a full tree view +*/ +_PUBLIC_ void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, + void (*callback)(const void *ptr, + int depth, int max_depth, + int is_ref, + void *private_data), + void *private_data) +{ + struct talloc_chunk *c, *tc; + + if (ptr == NULL) { + ptr = null_context; + } + if (ptr == NULL) return; + + tc = talloc_chunk_from_ptr(ptr); + + if (tc->flags & TALLOC_FLAG_LOOP) { + return; + } + + callback(ptr, depth, max_depth, 0, private_data); + + if (max_depth >= 0 && depth >= max_depth) { + return; + } + + tc->flags |= TALLOC_FLAG_LOOP; + for (c=tc->child;c;c=c->next) { + if (c->name == TALLOC_MAGIC_REFERENCE) { + struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c); + callback(h->ptr, depth + 1, max_depth, 1, private_data); + } else { + talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data); + } + } + tc->flags &= ~TALLOC_FLAG_LOOP; +} + +static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f) +{ + const char *name = __talloc_get_name(ptr); + struct talloc_chunk *tc; + FILE *f = (FILE *)_f; + + if (is_ref) { + fprintf(f, "%*sreference to: %s\n", depth*4, "", name); + return; + } + + tc = talloc_chunk_from_ptr(ptr); + if (tc->limit && tc->limit->parent == tc) { + fprintf(f, "%*s%-30s is a memlimit context" + " (max_size = %lu bytes, cur_size = %lu bytes)\n", + depth*4, "", + name, + (unsigned long)tc->limit->max_size, + (unsigned long)tc->limit->cur_size); + } + + if (depth == 0) { + fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", + (max_depth < 0 ? "full " :""), name, + (unsigned long)talloc_total_size(ptr), + (unsigned long)talloc_total_blocks(ptr)); + return; + } + + fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n", + depth*4, "", + name, + (unsigned long)talloc_total_size(ptr), + (unsigned long)talloc_total_blocks(ptr), + (int)talloc_reference_count(ptr), ptr); + +#if 0 + fprintf(f, "content: "); + if (talloc_total_size(ptr)) { + int tot = talloc_total_size(ptr); + int i; + + for (i = 0; i < tot; i++) { + if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) { + fprintf(f, "%c", ((char *)ptr)[i]); + } else { + fprintf(f, "~%02x", ((char *)ptr)[i]); + } + } + } + fprintf(f, "\n"); +#endif +} + +/* + report on memory usage by all children of a pointer, giving a full tree view +*/ +_PUBLIC_ void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f) +{ + if (f) { + talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f); + fflush(f); + } +} + +/* + report on memory usage by all children of a pointer, giving a full tree view +*/ +_PUBLIC_ void talloc_report_full(const void *ptr, FILE *f) +{ + talloc_report_depth_file(ptr, 0, -1, f); +} + +/* + report on memory usage by all children of a pointer +*/ +_PUBLIC_ void talloc_report(const void *ptr, FILE *f) +{ + talloc_report_depth_file(ptr, 0, 1, f); +} + +/* + enable tracking of the NULL context +*/ +_PUBLIC_ void talloc_enable_null_tracking(void) +{ + if (null_context == NULL) { + null_context = _talloc_named_const(NULL, 0, "null_context"); + if (autofree_context != NULL) { + talloc_reparent(NULL, null_context, autofree_context); + } + } +} + +/* + enable tracking of the NULL context, not moving the autofree context + into the NULL context. This is needed for the talloc testsuite +*/ +_PUBLIC_ void talloc_enable_null_tracking_no_autofree(void) +{ + if (null_context == NULL) { + null_context = _talloc_named_const(NULL, 0, "null_context"); + } +} + +/* + disable tracking of the NULL context +*/ +_PUBLIC_ void talloc_disable_null_tracking(void) +{ + if (null_context != NULL) { + /* we have to move any children onto the real NULL + context */ + struct talloc_chunk *tc, *tc2; + tc = talloc_chunk_from_ptr(null_context); + for (tc2 = tc->child; tc2; tc2=tc2->next) { + if (tc2->parent == tc) tc2->parent = NULL; + if (tc2->prev == tc) tc2->prev = NULL; + } + for (tc2 = tc->next; tc2; tc2=tc2->next) { + if (tc2->parent == tc) tc2->parent = NULL; + if (tc2->prev == tc) tc2->prev = NULL; + } + tc->child = NULL; + tc->next = NULL; + } + talloc_free(null_context); + null_context = NULL; +} + +/* + enable leak reporting on exit +*/ +_PUBLIC_ void talloc_enable_leak_report(void) +{ + talloc_enable_null_tracking(); + talloc_report_null = true; + talloc_setup_atexit(); +} + +/* + enable full leak reporting on exit +*/ +_PUBLIC_ void talloc_enable_leak_report_full(void) +{ + talloc_enable_null_tracking(); + talloc_report_null_full = true; + talloc_setup_atexit(); +} + +/* + talloc and zero memory. +*/ +_PUBLIC_ void *_talloc_zero(const void *ctx, size_t size, const char *name) +{ + void *p = _talloc_named_const(ctx, size, name); + + if (p) { + memset(p, '\0', size); + } + + return p; +} + +/* + memdup with a talloc. +*/ +_PUBLIC_ void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name) +{ + void *newp = NULL; + + if (likely(size > 0) && unlikely(p == NULL)) { + return NULL; + } + + newp = _talloc_named_const(t, size, name); + if (likely(newp != NULL) && likely(size > 0)) { + memcpy(newp, p, size); + } + + return newp; +} + +static inline char *__talloc_strlendup(const void *t, const char *p, size_t len) +{ + char *ret; + struct talloc_chunk *tc; + + ret = (char *)__talloc(t, len + 1, &tc); + if (unlikely(!ret)) return NULL; + + memcpy(ret, p, len); + ret[len] = 0; + + _tc_set_name_const(tc, ret); + return ret; +} + +/* + strdup with a talloc +*/ +_PUBLIC_ char *talloc_strdup(const void *t, const char *p) +{ + if (unlikely(!p)) return NULL; + return __talloc_strlendup(t, p, strlen(p)); +} + +/* + strndup with a talloc +*/ +_PUBLIC_ char *talloc_strndup(const void *t, const char *p, size_t n) +{ + if (unlikely(!p)) return NULL; + return __talloc_strlendup(t, p, strnlen(p, n)); +} + +static inline char *__talloc_strlendup_append(char *s, size_t slen, + const char *a, size_t alen) +{ + char *ret; + + ret = talloc_realloc(NULL, s, char, slen + alen + 1); + if (unlikely(!ret)) return NULL; + + /* append the string and the trailing \0 */ + memcpy(&ret[slen], a, alen); + ret[slen+alen] = 0; + + _tc_set_name_const(talloc_chunk_from_ptr(ret), ret); + return ret; +} + +/* + * Appends at the end of the string. + */ +_PUBLIC_ char *talloc_strdup_append(char *s, const char *a) +{ + if (unlikely(!s)) { + return talloc_strdup(NULL, a); + } + + if (unlikely(!a)) { + return s; + } + + return __talloc_strlendup_append(s, strlen(s), a, strlen(a)); +} + +/* + * Appends at the end of the talloc'ed buffer, + * not the end of the string. + */ +_PUBLIC_ char *talloc_strdup_append_buffer(char *s, const char *a) +{ + size_t slen; + + if (unlikely(!s)) { + return talloc_strdup(NULL, a); + } + + if (unlikely(!a)) { + return s; + } + + slen = talloc_get_size(s); + if (likely(slen > 0)) { + slen--; + } + + return __talloc_strlendup_append(s, slen, a, strlen(a)); +} + +/* + * Appends at the end of the string. + */ +_PUBLIC_ char *talloc_strndup_append(char *s, const char *a, size_t n) +{ + if (unlikely(!s)) { + return talloc_strndup(NULL, a, n); + } + + if (unlikely(!a)) { + return s; + } + + return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n)); +} + +/* + * Appends at the end of the talloc'ed buffer, + * not the end of the string. + */ +_PUBLIC_ char *talloc_strndup_append_buffer(char *s, const char *a, size_t n) +{ + size_t slen; + + if (unlikely(!s)) { + return talloc_strndup(NULL, a, n); + } + + if (unlikely(!a)) { + return s; + } + + slen = talloc_get_size(s); + if (likely(slen > 0)) { + slen--; + } + + return __talloc_strlendup_append(s, slen, a, strnlen(a, n)); +} + +#ifndef HAVE_VA_COPY +#ifdef HAVE___VA_COPY +#define va_copy(dest, src) __va_copy(dest, src) +#else +#define va_copy(dest, src) (dest) = (src) +#endif +#endif + +static struct talloc_chunk *_vasprintf_tc(const void *t, + const char *fmt, + va_list ap) PRINTF_ATTRIBUTE(2,0); + +static struct talloc_chunk *_vasprintf_tc(const void *t, + const char *fmt, + va_list ap) +{ + int vlen; + size_t len; + char *ret; + va_list ap2; + struct talloc_chunk *tc; + char buf[1024]; + + /* this call looks strange, but it makes it work on older solaris boxes */ + va_copy(ap2, ap); + vlen = vsnprintf(buf, sizeof(buf), fmt, ap2); + va_end(ap2); + if (unlikely(vlen < 0)) { + return NULL; + } + len = vlen; + if (unlikely(len + 1 < len)) { + return NULL; + } + + ret = (char *)__talloc(t, len+1, &tc); + if (unlikely(!ret)) return NULL; + + if (len < sizeof(buf)) { + memcpy(ret, buf, len+1); + } else { + va_copy(ap2, ap); + vsnprintf(ret, len+1, fmt, ap2); + va_end(ap2); + } + + _tc_set_name_const(tc, ret); + return tc; +} + +_PUBLIC_ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) +{ + struct talloc_chunk *tc = _vasprintf_tc(t, fmt, ap); + if (tc == NULL) { + return NULL; + } + return TC_PTR_FROM_CHUNK(tc); +} + + +/* + Perform string formatting, and return a pointer to newly allocated + memory holding the result, inside a memory pool. + */ +_PUBLIC_ char *talloc_asprintf(const void *t, const char *fmt, ...) +{ + va_list ap; + char *ret; + + va_start(ap, fmt); + ret = talloc_vasprintf(t, fmt, ap); + va_end(ap); + return ret; +} + +static inline char *__talloc_vaslenprintf_append(char *s, size_t slen, + const char *fmt, va_list ap) + PRINTF_ATTRIBUTE(3,0); + +static inline char *__talloc_vaslenprintf_append(char *s, size_t slen, + const char *fmt, va_list ap) +{ + ssize_t alen; + va_list ap2; + char c; + + va_copy(ap2, ap); + alen = vsnprintf(&c, 1, fmt, ap2); + va_end(ap2); + + if (alen <= 0) { + /* Either the vsnprintf failed or the format resulted in + * no characters being formatted. In the former case, we + * ought to return NULL, in the latter we ought to return + * the original string. Most current callers of this + * function expect it to never return NULL. + */ + return s; + } + + s = talloc_realloc(NULL, s, char, slen + alen + 1); + if (!s) return NULL; + + va_copy(ap2, ap); + vsnprintf(s + slen, alen + 1, fmt, ap2); + va_end(ap2); + + _tc_set_name_const(talloc_chunk_from_ptr(s), s); + return s; +} + +/** + * Realloc @p s to append the formatted result of @p fmt and @p ap, + * and return @p s, which may have moved. Good for gradually + * accumulating output into a string buffer. Appends at the end + * of the string. + **/ +_PUBLIC_ char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) +{ + if (unlikely(!s)) { + return talloc_vasprintf(NULL, fmt, ap); + } + + return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap); +} + +/** + * Realloc @p s to append the formatted result of @p fmt and @p ap, + * and return @p s, which may have moved. Always appends at the + * end of the talloc'ed buffer, not the end of the string. + **/ +_PUBLIC_ char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) +{ + size_t slen; + + if (unlikely(!s)) { + return talloc_vasprintf(NULL, fmt, ap); + } + + slen = talloc_get_size(s); + if (likely(slen > 0)) { + slen--; + } + + return __talloc_vaslenprintf_append(s, slen, fmt, ap); +} + +/* + Realloc @p s to append the formatted result of @p fmt and return @p + s, which may have moved. Good for gradually accumulating output + into a string buffer. + */ +_PUBLIC_ char *talloc_asprintf_append(char *s, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + s = talloc_vasprintf_append(s, fmt, ap); + va_end(ap); + return s; +} + +/* + Realloc @p s to append the formatted result of @p fmt and return @p + s, which may have moved. Good for gradually accumulating output + into a buffer. + */ +_PUBLIC_ char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + s = talloc_vasprintf_append_buffer(s, fmt, ap); + va_end(ap); + return s; +} + +/* + alloc an array, checking for integer overflow in the array size +*/ +_PUBLIC_ void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name) +{ + if (count >= MAX_TALLOC_SIZE/el_size) { + return NULL; + } + return _talloc_named_const(ctx, el_size * count, name); +} + +/* + alloc an zero array, checking for integer overflow in the array size +*/ +_PUBLIC_ void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name) +{ + if (count >= MAX_TALLOC_SIZE/el_size) { + return NULL; + } + return _talloc_zero(ctx, el_size * count, name); +} + +/* + realloc an array, checking for integer overflow in the array size +*/ +_PUBLIC_ void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name) +{ + if (count >= MAX_TALLOC_SIZE/el_size) { + return NULL; + } + return _talloc_realloc(ctx, ptr, el_size * count, name); +} + +/* + a function version of talloc_realloc(), so it can be passed as a function pointer + to libraries that want a realloc function (a realloc function encapsulates + all the basic capabilities of an allocation library, which is why this is useful) +*/ +_PUBLIC_ void *talloc_realloc_fn(const void *context, void *ptr, size_t size) +{ + return _talloc_realloc(context, ptr, size, NULL); +} + + +static int talloc_autofree_destructor(void *ptr) +{ + autofree_context = NULL; + return 0; +} + +/* + return a context which will be auto-freed on exit + this is useful for reducing the noise in leak reports +*/ +_PUBLIC_ void *talloc_autofree_context(void) +{ + if (autofree_context == NULL) { + autofree_context = _talloc_named_const(NULL, 0, "autofree_context"); + talloc_set_destructor(autofree_context, talloc_autofree_destructor); + talloc_setup_atexit(); + } + return autofree_context; +} + +_PUBLIC_ size_t talloc_get_size(const void *context) +{ + struct talloc_chunk *tc; + + if (context == NULL) { + return 0; + } + + tc = talloc_chunk_from_ptr(context); + + return tc->size; +} + +/* + find a parent of this context that has the given name, if any +*/ +_PUBLIC_ void *talloc_find_parent_byname(const void *context, const char *name) +{ + struct talloc_chunk *tc; + + if (context == NULL) { + return NULL; + } + + tc = talloc_chunk_from_ptr(context); + while (tc) { + if (tc->name && strcmp(tc->name, name) == 0) { + return TC_PTR_FROM_CHUNK(tc); + } + while (tc && tc->prev) tc = tc->prev; + if (tc) { + tc = tc->parent; + } + } + return NULL; +} + +/* + show the parentage of a context +*/ +_PUBLIC_ void talloc_show_parents(const void *context, FILE *file) +{ + struct talloc_chunk *tc; + + if (context == NULL) { + fprintf(file, "talloc no parents for NULL\n"); + return; + } + + tc = talloc_chunk_from_ptr(context); + fprintf(file, "talloc parents of '%s'\n", __talloc_get_name(context)); + while (tc) { + fprintf(file, "\t'%s'\n", __talloc_get_name(TC_PTR_FROM_CHUNK(tc))); + while (tc && tc->prev) tc = tc->prev; + if (tc) { + tc = tc->parent; + } + } + fflush(file); +} + +/* + return 1 if ptr is a parent of context +*/ +static int _talloc_is_parent(const void *context, const void *ptr, int depth) +{ + struct talloc_chunk *tc; + + if (context == NULL) { + return 0; + } + + tc = talloc_chunk_from_ptr(context); + while (tc) { + if (depth <= 0) { + return 0; + } + if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1; + while (tc && tc->prev) tc = tc->prev; + if (tc) { + tc = tc->parent; + depth--; + } + } + return 0; +} + +/* + return 1 if ptr is a parent of context +*/ +_PUBLIC_ int talloc_is_parent(const void *context, const void *ptr) +{ + return _talloc_is_parent(context, ptr, TALLOC_MAX_DEPTH); +} + +/* + return the total size of memory used by this context and all children +*/ +static inline size_t _talloc_total_limit_size(const void *ptr, + struct talloc_memlimit *old_limit, + struct talloc_memlimit *new_limit) +{ + return _talloc_total_mem_internal(ptr, TOTAL_MEM_LIMIT, + old_limit, new_limit); +} + +static inline bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size) +{ + struct talloc_memlimit *l; + + for (l = limit; l != NULL; l = l->upper) { + if (l->max_size != 0 && + ((l->max_size <= l->cur_size) || + (l->max_size - l->cur_size < size))) { + return false; + } + } + + return true; +} + +/* + Update memory limits when freeing a talloc_chunk. +*/ +static void tc_memlimit_update_on_free(struct talloc_chunk *tc) +{ + size_t limit_shrink_size; + + if (!tc->limit) { + return; + } + + /* + * Pool entries don't count. Only the pools + * themselves are counted as part of the memory + * limits. Note that this also takes care of + * nested pools which have both flags + * TALLOC_FLAG_POOLMEM|TALLOC_FLAG_POOL set. + */ + if (tc->flags & TALLOC_FLAG_POOLMEM) { + return; + } + + /* + * If we are part of a memory limited context hierarchy + * we need to subtract the memory used from the counters + */ + + limit_shrink_size = tc->size+TC_HDR_SIZE; + + /* + * If we're deallocating a pool, take into + * account the prefix size added for the pool. + */ + + if (tc->flags & TALLOC_FLAG_POOL) { + limit_shrink_size += TP_HDR_SIZE; + } + + talloc_memlimit_shrink(tc->limit, limit_shrink_size); + + if (tc->limit->parent == tc) { + free(tc->limit); + } + + tc->limit = NULL; +} + +/* + Increase memory limit accounting after a malloc/realloc. +*/ +static void talloc_memlimit_grow(struct talloc_memlimit *limit, + size_t size) +{ + struct talloc_memlimit *l; + + for (l = limit; l != NULL; l = l->upper) { + size_t new_cur_size = l->cur_size + size; + if (new_cur_size < l->cur_size) { + talloc_abort("logic error in talloc_memlimit_grow\n"); + return; + } + l->cur_size = new_cur_size; + } +} + +/* + Decrease memory limit accounting after a free/realloc. +*/ +static void talloc_memlimit_shrink(struct talloc_memlimit *limit, + size_t size) +{ + struct talloc_memlimit *l; + + for (l = limit; l != NULL; l = l->upper) { + if (l->cur_size < size) { + talloc_abort("logic error in talloc_memlimit_shrink\n"); + return; + } + l->cur_size = l->cur_size - size; + } +} + +_PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size) +{ + struct talloc_chunk *tc = talloc_chunk_from_ptr(ctx); + struct talloc_memlimit *orig_limit; + struct talloc_memlimit *limit = NULL; + + if (tc->limit && tc->limit->parent == tc) { + tc->limit->max_size = max_size; + return 0; + } + orig_limit = tc->limit; + + limit = malloc(sizeof(struct talloc_memlimit)); + if (limit == NULL) { + return 1; + } + limit->parent = tc; + limit->max_size = max_size; + limit->cur_size = _talloc_total_limit_size(ctx, tc->limit, limit); + + if (orig_limit) { + limit->upper = orig_limit; + } else { + limit->upper = NULL; + } + + return 0; +} diff --git a/ldb-2.0.8/lib/talloc/talloc.h b/ldb-2.0.8/lib/talloc/talloc.h new file mode 100644 index 0000000..34fe772 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/talloc.h @@ -0,0 +1,1945 @@ +#ifndef _TALLOC_H_ +#define _TALLOC_H_ +/* + Unix SMB/CIFS implementation. + Samba temporary memory allocation functions + + Copyright (C) Andrew Tridgell 2004-2005 + Copyright (C) Stefan Metzmacher 2006 + + ** NOTE! The following LGPL license applies to the talloc + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup talloc The talloc API + * + * talloc is a hierarchical, reference counted memory pool system with + * destructors. It is the core memory allocator used in Samba. + * + * @{ + */ + +#define TALLOC_VERSION_MAJOR 2 +#define TALLOC_VERSION_MINOR 2 + +int talloc_version_major(void); +int talloc_version_minor(void); +/* This is mostly useful only for testing */ +int talloc_test_get_magic(void); + +/** + * @brief Define a talloc parent type + * + * As talloc is a hierarchial memory allocator, every talloc chunk is a + * potential parent to other talloc chunks. So defining a separate type for a + * talloc chunk is not strictly necessary. TALLOC_CTX is defined nevertheless, + * as it provides an indicator for function arguments. You will frequently + * write code like + * + * @code + * struct foo *foo_create(TALLOC_CTX *mem_ctx) + * { + * struct foo *result; + * result = talloc(mem_ctx, struct foo); + * if (result == NULL) return NULL; + * ... initialize foo ... + * return result; + * } + * @endcode + * + * In this type of allocating functions it is handy to have a general + * TALLOC_CTX type to indicate which parent to put allocated structures on. + */ +typedef void TALLOC_CTX; + +/* + this uses a little trick to allow __LINE__ to be stringified +*/ +#ifndef __location__ +#define __TALLOC_STRING_LINE1__(s) #s +#define __TALLOC_STRING_LINE2__(s) __TALLOC_STRING_LINE1__(s) +#define __TALLOC_STRING_LINE3__ __TALLOC_STRING_LINE2__(__LINE__) +#define __location__ __FILE__ ":" __TALLOC_STRING_LINE3__ +#endif + +#ifndef TALLOC_DEPRECATED +#define TALLOC_DEPRECATED 0 +#endif + +#ifndef PRINTF_ATTRIBUTE +#if (__GNUC__ >= 3) +/** Use gcc attribute to check printf fns. a1 is the 1-based index of + * the parameter containing the format, and a2 the index of the first + * argument. Note that some gcc 2.x versions don't handle this + * properly **/ +#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) +#else +#define PRINTF_ATTRIBUTE(a1, a2) +#endif +#endif + +#ifndef _DEPRECATED_ +#ifdef HAVE___ATTRIBUTE__ +#define _DEPRECATED_ __attribute__ ((deprecated)) +#else +#define _DEPRECATED_ +#endif +#endif +#ifdef DOXYGEN + +/** + * @brief Create a new talloc context. + * + * The talloc() macro is the core of the talloc library. It takes a memory + * context and a type, and returns a pointer to a new area of memory of the + * given type. + * + * The returned pointer is itself a talloc context, so you can use it as the + * context argument to more calls to talloc if you wish. + * + * The returned pointer is a "child" of the supplied context. This means that if + * you talloc_free() the context then the new child disappears as well. + * Alternatively you can free just the child. + * + * @param[in] ctx A talloc context to create a new reference on or NULL to + * create a new top level context. + * + * @param[in] type The type of memory to allocate. + * + * @return A type casted talloc context or NULL on error. + * + * @code + * unsigned int *a, *b; + * + * a = talloc(NULL, unsigned int); + * b = talloc(a, unsigned int); + * @endcode + * + * @see talloc_zero + * @see talloc_array + * @see talloc_steal + * @see talloc_free + */ +void *talloc(const void *ctx, #type); +#else +#define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type) +void *_talloc(const void *context, size_t size); +#endif + +/** + * @brief Create a new top level talloc context. + * + * This function creates a zero length named talloc context as a top level + * context. It is equivalent to: + * + * @code + * talloc_named(NULL, 0, fmt, ...); + * @endcode + * @param[in] fmt Format string for the name. + * + * @param[in] ... Additional printf-style arguments. + * + * @return The allocated memory chunk, NULL on error. + * + * @see talloc_named() + */ +void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2); + +#ifdef DOXYGEN +/** + * @brief Free a chunk of talloc memory. + * + * The talloc_free() function frees a piece of talloc memory, and all its + * children. You can call talloc_free() on any pointer returned by + * talloc(). + * + * The return value of talloc_free() indicates success or failure, with 0 + * returned for success and -1 for failure. A possible failure condition + * is if the pointer had a destructor attached to it and the destructor + * returned -1. See talloc_set_destructor() for details on + * destructors. Likewise, if "ptr" is NULL, then the function will make + * no modifications and return -1. + * + * From version 2.0 and onwards, as a special case, talloc_free() is + * refused on pointers that have more than one parent associated, as talloc + * would have no way of knowing which parent should be removed. This is + * different from older versions in the sense that always the reference to + * the most recently established parent has been destroyed. Hence to free a + * pointer that has more than one parent please use talloc_unlink(). + * + * To help you find problems in your code caused by this behaviour, if + * you do try and free a pointer with more than one parent then the + * talloc logging function will be called to give output like this: + * + * @code + * ERROR: talloc_free with references at some_dir/source/foo.c:123 + * reference at some_dir/source/other.c:325 + * reference at some_dir/source/third.c:121 + * @endcode + * + * Please see the documentation for talloc_set_log_fn() and + * talloc_set_log_stderr() for more information on talloc logging + * functions. + * + * If TALLOC_FREE_FILL environment variable is set, + * the memory occupied by the context is filled with the value of this variable. + * The value should be a numeric representation of the character you want to + * use. + * + * talloc_free() operates recursively on its children. + * + * @param[in] ptr The chunk to be freed. + * + * @return Returns 0 on success and -1 on error. A possible + * failure condition is if the pointer had a destructor + * attached to it and the destructor returned -1. Likewise, + * if "ptr" is NULL, then the function will make no + * modifications and returns -1. + * + * Example: + * @code + * unsigned int *a, *b; + * a = talloc(NULL, unsigned int); + * b = talloc(a, unsigned int); + * + * talloc_free(a); // Frees a and b + * @endcode + * + * @see talloc_set_destructor() + * @see talloc_unlink() + */ +int talloc_free(void *ptr); +#else +#define talloc_free(ctx) _talloc_free(ctx, __location__) +int _talloc_free(void *ptr, const char *location); +#endif + +/** + * @brief Free a talloc chunk's children. + * + * The function walks along the list of all children of a talloc context and + * talloc_free()s only the children, not the context itself. + * + * A NULL argument is handled as no-op. + * + * @param[in] ptr The chunk that you want to free the children of + * (NULL is allowed too) + */ +void talloc_free_children(void *ptr); + +#ifdef DOXYGEN +/** + * @brief Assign a destructor function to be called when a chunk is freed. + * + * The function talloc_set_destructor() sets the "destructor" for the pointer + * "ptr". A destructor is a function that is called when the memory used by a + * pointer is about to be released. The destructor receives the pointer as an + * argument, and should return 0 for success and -1 for failure. + * + * The destructor can do anything it wants to, including freeing other pieces + * of memory. A common use for destructors is to clean up operating system + * resources (such as open file descriptors) contained in the structure the + * destructor is placed on. + * + * You can only place one destructor on a pointer. If you need more than one + * destructor then you can create a zero-length child of the pointer and place + * an additional destructor on that. + * + * To remove a destructor call talloc_set_destructor() with NULL for the + * destructor. + * + * If your destructor attempts to talloc_free() the pointer that it is the + * destructor for then talloc_free() will return -1 and the free will be + * ignored. This would be a pointless operation anyway, as the destructor is + * only called when the memory is just about to go away. + * + * @param[in] ptr The talloc chunk to add a destructor to. + * + * @param[in] destructor The destructor function to be called. NULL to remove + * it. + * + * Example: + * @code + * static int destroy_fd(int *fd) { + * close(*fd); + * return 0; + * } + * + * int *open_file(const char *filename) { + * int *fd = talloc(NULL, int); + * *fd = open(filename, O_RDONLY); + * if (*fd < 0) { + * talloc_free(fd); + * return NULL; + * } + * // Whenever they free this, we close the file. + * talloc_set_destructor(fd, destroy_fd); + * return fd; + * } + * @endcode + * + * @see talloc() + * @see talloc_free() + */ +void talloc_set_destructor(const void *ptr, int (*destructor)(void *)); + +/** + * @brief Change a talloc chunk's parent. + * + * The talloc_steal() function changes the parent context of a talloc + * pointer. It is typically used when the context that the pointer is + * currently a child of is going to be freed and you wish to keep the + * memory for a longer time. + * + * To make the changed hierarchy less error-prone, you might consider to use + * talloc_move(). + * + * If you try and call talloc_steal() on a pointer that has more than one + * parent then the result is ambiguous. Talloc will choose to remove the + * parent that is currently indicated by talloc_parent() and replace it with + * the chosen parent. You will also get a message like this via the talloc + * logging functions: + * + * @code + * WARNING: talloc_steal with references at some_dir/source/foo.c:123 + * reference at some_dir/source/other.c:325 + * reference at some_dir/source/third.c:121 + * @endcode + * + * To unambiguously change the parent of a pointer please see the function + * talloc_reparent(). See the talloc_set_log_fn() documentation for more + * information on talloc logging. + * + * @param[in] new_ctx The new parent context. + * + * @param[in] ptr The talloc chunk to move. + * + * @return Returns the pointer that you pass it. It does not have + * any failure modes. + * + * @note It is possible to produce loops in the parent/child relationship + * if you are not careful with talloc_steal(). No guarantees are provided + * as to your sanity or the safety of your data if you do this. + */ +void *talloc_steal(const void *new_ctx, const void *ptr); +#else /* DOXYGEN */ +/* try to make talloc_set_destructor() and talloc_steal() type safe, + if we have a recent gcc */ +#if (__GNUC__ >= 3) +#define _TALLOC_TYPEOF(ptr) __typeof__(ptr) +#define talloc_set_destructor(ptr, function) \ + do { \ + int (*_talloc_destructor_fn)(_TALLOC_TYPEOF(ptr)) = (function); \ + _talloc_set_destructor((ptr), (int (*)(void *))_talloc_destructor_fn); \ + } while(0) +/* this extremely strange macro is to avoid some braindamaged warning + stupidity in gcc 4.1.x */ +#define talloc_steal(ctx, ptr) ({ _TALLOC_TYPEOF(ptr) __talloc_steal_ret = (_TALLOC_TYPEOF(ptr))_talloc_steal_loc((ctx),(ptr), __location__); __talloc_steal_ret; }) +#else /* __GNUC__ >= 3 */ +#define talloc_set_destructor(ptr, function) \ + _talloc_set_destructor((ptr), (int (*)(void *))(function)) +#define _TALLOC_TYPEOF(ptr) void * +#define talloc_steal(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_steal_loc((ctx),(ptr), __location__) +#endif /* __GNUC__ >= 3 */ +void _talloc_set_destructor(const void *ptr, int (*_destructor)(void *)); +void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const char *location); +#endif /* DOXYGEN */ + +/** + * @brief Assign a name to a talloc chunk. + * + * Each talloc pointer has a "name". The name is used principally for + * debugging purposes, although it is also possible to set and get the name on + * a pointer in as a way of "marking" pointers in your code. + * + * The main use for names on pointer is for "talloc reports". See + * talloc_report() and talloc_report_full() for details. Also see + * talloc_enable_leak_report() and talloc_enable_leak_report_full(). + * + * The talloc_set_name() function allocates memory as a child of the + * pointer. It is logically equivalent to: + * + * @code + * talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...)); + * @endcode + * + * @param[in] ptr The talloc chunk to assign a name to. + * + * @param[in] fmt Format string for the name. + * + * @param[in] ... Add printf-style additional arguments. + * + * @return The assigned name, NULL on error. + * + * @note Multiple calls to talloc_set_name() will allocate more memory without + * releasing the name. All of the memory is released when the ptr is freed + * using talloc_free(). + */ +const char *talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); + +#ifdef DOXYGEN +/** + * @brief Change a talloc chunk's parent. + * + * This function has the same effect as talloc_steal(), and additionally sets + * the source pointer to NULL. You would use it like this: + * + * @code + * struct foo *X = talloc(tmp_ctx, struct foo); + * struct foo *Y; + * Y = talloc_move(new_ctx, &X); + * @endcode + * + * @param[in] new_ctx The new parent context. + * + * @param[in] pptr Pointer to a pointer to the talloc chunk to move. + * + * @return The pointer to the talloc chunk that moved. + * It does not have any failure modes. + * + */ +void *talloc_move(const void *new_ctx, void **pptr); +#else +#define talloc_move(ctx, pptr) (_TALLOC_TYPEOF(*(pptr)))_talloc_move((ctx),(void *)(pptr)) +void *_talloc_move(const void *new_ctx, const void *pptr); +#endif + +/** + * @brief Assign a name to a talloc chunk. + * + * The function is just like talloc_set_name(), but it takes a string constant, + * and is much faster. It is extensively used by the "auto naming" macros, such + * as talloc_p(). + * + * This function does not allocate any memory. It just copies the supplied + * pointer into the internal representation of the talloc ptr. This means you + * must not pass a name pointer to memory that will disappear before the ptr + * is freed with talloc_free(). + * + * @param[in] ptr The talloc chunk to assign a name to. + * + * @param[in] name Format string for the name. + */ +void talloc_set_name_const(const void *ptr, const char *name); + +/** + * @brief Create a named talloc chunk. + * + * The talloc_named() function creates a named talloc pointer. It is + * equivalent to: + * + * @code + * ptr = talloc_size(context, size); + * talloc_set_name(ptr, fmt, ....); + * @endcode + * + * @param[in] context The talloc context to hang the result off. + * + * @param[in] size Number of char's that you want to allocate. + * + * @param[in] fmt Format string for the name. + * + * @param[in] ... Additional printf-style arguments. + * + * @return The allocated memory chunk, NULL on error. + * + * @see talloc_set_name() + */ +void *talloc_named(const void *context, size_t size, + const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); + +/** + * @brief Basic routine to allocate a chunk of memory. + * + * This is equivalent to: + * + * @code + * ptr = talloc_size(context, size); + * talloc_set_name_const(ptr, name); + * @endcode + * + * @param[in] context The parent context. + * + * @param[in] size The number of char's that we want to allocate. + * + * @param[in] name The name the talloc block has. + * + * @return The allocated memory chunk, NULL on error. + */ +void *talloc_named_const(const void *context, size_t size, const char *name); + +#ifdef DOXYGEN +/** + * @brief Untyped allocation. + * + * The function should be used when you don't have a convenient type to pass to + * talloc(). Unlike talloc(), it is not type safe (as it returns a void *), so + * you are on your own for type checking. + * + * Best to use talloc() or talloc_array() instead. + * + * @param[in] ctx The talloc context to hang the result off. + * + * @param[in] size Number of char's that you want to allocate. + * + * @return The allocated memory chunk, NULL on error. + * + * Example: + * @code + * void *mem = talloc_size(NULL, 100); + * @endcode + */ +void *talloc_size(const void *ctx, size_t size); +#else +#define talloc_size(ctx, size) talloc_named_const(ctx, size, __location__) +#endif + +#ifdef DOXYGEN +/** + * @brief Allocate into a typed pointer. + * + * The talloc_ptrtype() macro should be used when you have a pointer and want + * to allocate memory to point at with this pointer. When compiling with + * gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size() and + * talloc_get_name() will return the current location in the source file and + * not the type. + * + * @param[in] ctx The talloc context to hang the result off. + * + * @param[in] type The pointer you want to assign the result to. + * + * @return The properly casted allocated memory chunk, NULL on + * error. + * + * Example: + * @code + * unsigned int *a = talloc_ptrtype(NULL, a); + * @endcode + */ +void *talloc_ptrtype(const void *ctx, #type); +#else +#define talloc_ptrtype(ctx, ptr) (_TALLOC_TYPEOF(ptr))talloc_size(ctx, sizeof(*(ptr))) +#endif + +#ifdef DOXYGEN +/** + * @brief Allocate a new 0-sized talloc chunk. + * + * This is a utility macro that creates a new memory context hanging off an + * existing context, automatically naming it "talloc_new: __location__" where + * __location__ is the source line it is called from. It is particularly + * useful for creating a new temporary working context. + * + * @param[in] ctx The talloc parent context. + * + * @return A new talloc chunk, NULL on error. + */ +void *talloc_new(const void *ctx); +#else +#define talloc_new(ctx) talloc_named_const(ctx, 0, "talloc_new: " __location__) +#endif + +#ifdef DOXYGEN +/** + * @brief Allocate a 0-initizialized structure. + * + * The macro is equivalent to: + * + * @code + * ptr = talloc(ctx, type); + * if (ptr) memset(ptr, 0, sizeof(type)); + * @endcode + * + * @param[in] ctx The talloc context to hang the result off. + * + * @param[in] type The type that we want to allocate. + * + * @return Pointer to a piece of memory, properly cast to 'type *', + * NULL on error. + * + * Example: + * @code + * unsigned int *a, *b; + * a = talloc_zero(NULL, unsigned int); + * b = talloc_zero(a, unsigned int); + * @endcode + * + * @see talloc() + * @see talloc_zero_size() + * @see talloc_zero_array() + */ +void *talloc_zero(const void *ctx, #type); + +/** + * @brief Allocate untyped, 0-initialized memory. + * + * @param[in] ctx The talloc context to hang the result off. + * + * @param[in] size Number of char's that you want to allocate. + * + * @return The allocated memory chunk. + */ +void *talloc_zero_size(const void *ctx, size_t size); +#else +#define talloc_zero(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type) +#define talloc_zero_size(ctx, size) _talloc_zero(ctx, size, __location__) +void *_talloc_zero(const void *ctx, size_t size, const char *name); +#endif + +/** + * @brief Return the name of a talloc chunk. + * + * @param[in] ptr The talloc chunk. + * + * @return The current name for the given talloc pointer. + * + * @see talloc_set_name() + */ +const char *talloc_get_name(const void *ptr); + +/** + * @brief Verify that a talloc chunk carries a specified name. + * + * This function checks if a pointer has the specified name. If it does + * then the pointer is returned. + * + * @param[in] ptr The talloc chunk to check. + * + * @param[in] name The name to check against. + * + * @return The pointer if the name matches, NULL if it doesn't. + */ +void *talloc_check_name(const void *ptr, const char *name); + +/** + * @brief Get the parent chunk of a pointer. + * + * @param[in] ptr The talloc pointer to inspect. + * + * @return The talloc parent of ptr, NULL on error. + */ +void *talloc_parent(const void *ptr); + +/** + * @brief Get a talloc chunk's parent name. + * + * @param[in] ptr The talloc pointer to inspect. + * + * @return The name of ptr's parent chunk. + */ +const char *talloc_parent_name(const void *ptr); + +/** + * @brief Get the total size of a talloc chunk including its children. + * + * The function returns the total size in bytes used by this pointer and all + * child pointers. Mostly useful for debugging. + * + * Passing NULL is allowed, but it will only give a meaningful result if + * talloc_enable_leak_report() or talloc_enable_leak_report_full() has + * been called. + * + * @param[in] ptr The talloc chunk. + * + * @return The total size. + */ +size_t talloc_total_size(const void *ptr); + +/** + * @brief Get the number of talloc chunks hanging off a chunk. + * + * The talloc_total_blocks() function returns the total memory block + * count used by this pointer and all child pointers. Mostly useful for + * debugging. + * + * Passing NULL is allowed, but it will only give a meaningful result if + * talloc_enable_leak_report() or talloc_enable_leak_report_full() has + * been called. + * + * @param[in] ptr The talloc chunk. + * + * @return The total size. + */ +size_t talloc_total_blocks(const void *ptr); + +#ifdef DOXYGEN +/** + * @brief Duplicate a memory area into a talloc chunk. + * + * The function is equivalent to: + * + * @code + * ptr = talloc_size(ctx, size); + * if (ptr) memcpy(ptr, p, size); + * @endcode + * + * @param[in] t The talloc context to hang the result off. + * + * @param[in] p The memory chunk you want to duplicate. + * + * @param[in] size Number of char's that you want copy. + * + * @return The allocated memory chunk. + * + * @see talloc_size() + */ +void *talloc_memdup(const void *t, const void *p, size_t size); +#else +#define talloc_memdup(t, p, size) _talloc_memdup(t, p, size, __location__) +void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name); +#endif + +#ifdef DOXYGEN +/** + * @brief Assign a type to a talloc chunk. + * + * This macro allows you to force the name of a pointer to be of a particular + * type. This can be used in conjunction with talloc_get_type() to do type + * checking on void* pointers. + * + * It is equivalent to this: + * + * @code + * talloc_set_name_const(ptr, #type) + * @endcode + * + * @param[in] ptr The talloc chunk to assign the type to. + * + * @param[in] type The type to assign. + */ +void talloc_set_type(const char *ptr, #type); + +/** + * @brief Get a typed pointer out of a talloc pointer. + * + * This macro allows you to do type checking on talloc pointers. It is + * particularly useful for void* private pointers. It is equivalent to + * this: + * + * @code + * (type *)talloc_check_name(ptr, #type) + * @endcode + * + * @param[in] ptr The talloc pointer to check. + * + * @param[in] type The type to check against. + * + * @return The properly casted pointer given by ptr, NULL on error. + */ +type *talloc_get_type(const void *ptr, #type); +#else +#define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type) +#define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type) +#endif + +#ifdef DOXYGEN +/** + * @brief Safely turn a void pointer into a typed pointer. + * + * This macro is used together with talloc(mem_ctx, struct foo). If you had to + * assign the talloc chunk pointer to some void pointer variable, + * talloc_get_type_abort() is the recommended way to get the convert the void + * pointer back to a typed pointer. + * + * @param[in] ptr The void pointer to convert. + * + * @param[in] type The type that this chunk contains + * + * @return The same value as ptr, type-checked and properly cast. + */ +void *talloc_get_type_abort(const void *ptr, #type); +#else +#ifdef TALLOC_GET_TYPE_ABORT_NOOP +#define talloc_get_type_abort(ptr, type) (type *)(ptr) +#else +#define talloc_get_type_abort(ptr, type) (type *)_talloc_get_type_abort(ptr, #type, __location__) +#endif +void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location); +#endif + +/** + * @brief Find a parent context by name. + * + * Find a parent memory context of the current context that has the given + * name. This can be very useful in complex programs where it may be + * difficult to pass all information down to the level you need, but you + * know the structure you want is a parent of another context. + * + * @param[in] ctx The talloc chunk to start from. + * + * @param[in] name The name of the parent we look for. + * + * @return The memory context we are looking for, NULL if not + * found. + */ +void *talloc_find_parent_byname(const void *ctx, const char *name); + +#ifdef DOXYGEN +/** + * @brief Find a parent context by type. + * + * Find a parent memory context of the current context that has the given + * name. This can be very useful in complex programs where it may be + * difficult to pass all information down to the level you need, but you + * know the structure you want is a parent of another context. + * + * Like talloc_find_parent_byname() but takes a type, making it typesafe. + * + * @param[in] ptr The talloc chunk to start from. + * + * @param[in] type The type of the parent to look for. + * + * @return The memory context we are looking for, NULL if not + * found. + */ +void *talloc_find_parent_bytype(const void *ptr, #type); +#else +#define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type) +#endif + +/** + * @brief Allocate a talloc pool. + * + * A talloc pool is a pure optimization for specific situations. In the + * release process for Samba 3.2 we found out that we had become considerably + * slower than Samba 3.0 was. Profiling showed that malloc(3) was a large CPU + * consumer in benchmarks. For Samba 3.2 we have internally converted many + * static buffers to dynamically allocated ones, so malloc(3) being beaten + * more was no surprise. But it made us slower. + * + * talloc_pool() is an optimization to call malloc(3) a lot less for the use + * pattern Samba has: The SMB protocol is mainly a request/response protocol + * where we have to allocate a certain amount of memory per request and free + * that after the SMB reply is sent to the client. + * + * talloc_pool() creates a talloc chunk that you can use as a talloc parent + * exactly as you would use any other ::TALLOC_CTX. The difference is that + * when you talloc a child of this pool, no malloc(3) is done. Instead, talloc + * just increments a pointer inside the talloc_pool. This also works + * recursively. If you use the child of the talloc pool as a parent for + * grand-children, their memory is also taken from the talloc pool. + * + * If there is not enough memory in the pool to allocate the new child, + * it will create a new talloc chunk as if the parent was a normal talloc + * context. + * + * If you talloc_free() children of a talloc pool, the memory is not given + * back to the system. Instead, free(3) is only called if the talloc_pool() + * itself is released with talloc_free(). + * + * The downside of a talloc pool is that if you talloc_move() a child of a + * talloc pool to a talloc parent outside the pool, the whole pool memory is + * not free(3)'ed until that moved chunk is also talloc_free()ed. + * + * @param[in] context The talloc context to hang the result off. + * + * @param[in] size Size of the talloc pool. + * + * @return The allocated talloc pool, NULL on error. + */ +void *talloc_pool(const void *context, size_t size); + +#ifdef DOXYGEN +/** + * @brief Allocate a talloc object as/with an additional pool. + * + * This is like talloc_pool(), but's it's more flexible + * and allows an object to be a pool for its children. + * + * @param[in] ctx The talloc context to hang the result off. + * + * @param[in] type The type that we want to allocate. + * + * @param[in] num_subobjects The expected number of subobjects, which will + * be allocated within the pool. This allocates + * space for talloc_chunk headers. + * + * @param[in] total_subobjects_size The size that all subobjects can use in total. + * + * + * @return The allocated talloc object, NULL on error. + */ +void *talloc_pooled_object(const void *ctx, #type, + unsigned num_subobjects, + size_t total_subobjects_size); +#else +#define talloc_pooled_object(_ctx, _type, \ + _num_subobjects, \ + _total_subobjects_size) \ + (_type *)_talloc_pooled_object((_ctx), sizeof(_type), #_type, \ + (_num_subobjects), \ + (_total_subobjects_size)) +void *_talloc_pooled_object(const void *ctx, + size_t type_size, + const char *type_name, + unsigned num_subobjects, + size_t total_subobjects_size); +#endif + +/** + * @brief Free a talloc chunk and NULL out the pointer. + * + * TALLOC_FREE() frees a pointer and sets it to NULL. Use this if you want + * immediate feedback (i.e. crash) if you use a pointer after having free'ed + * it. + * + * @param[in] ctx The chunk to be freed. + */ +#define TALLOC_FREE(ctx) do { if (ctx != NULL) { talloc_free(ctx); ctx=NULL; } } while(0) + +/* @} ******************************************************************/ + +/** + * \defgroup talloc_ref The talloc reference function. + * @ingroup talloc + * + * This module contains the definitions around talloc references + * + * @{ + */ + +/** + * @brief Increase the reference count of a talloc chunk. + * + * The talloc_increase_ref_count(ptr) function is exactly equivalent to: + * + * @code + * talloc_reference(NULL, ptr); + * @endcode + * + * You can use either syntax, depending on which you think is clearer in + * your code. + * + * @param[in] ptr The pointer to increase the reference count. + * + * @return 0 on success, -1 on error. + */ +int talloc_increase_ref_count(const void *ptr); + +/** + * @brief Get the number of references to a talloc chunk. + * + * @param[in] ptr The pointer to retrieve the reference count from. + * + * @return The number of references. + */ +size_t talloc_reference_count(const void *ptr); + +#ifdef DOXYGEN +/** + * @brief Create an additional talloc parent to a pointer. + * + * The talloc_reference() function makes "context" an additional parent of + * ptr. Each additional reference consumes around 48 bytes of memory on intel + * x86 platforms. + * + * If ptr is NULL, then the function is a no-op, and simply returns NULL. + * + * After creating a reference you can free it in one of the following ways: + * + * - you can talloc_free() any parent of the original pointer. That + * will reduce the number of parents of this pointer by 1, and will + * cause this pointer to be freed if it runs out of parents. + * + * - you can talloc_free() the pointer itself if it has at maximum one + * parent. This behaviour has been changed since the release of version + * 2.0. Further information in the description of "talloc_free". + * + * For more control on which parent to remove, see talloc_unlink() + * @param[in] ctx The additional parent. + * + * @param[in] ptr The pointer you want to create an additional parent for. + * + * @return The original pointer 'ptr', NULL if talloc ran out of + * memory in creating the reference. + * + * @warning You should try to avoid using this interface. It turns a beautiful + * talloc-tree into a graph. It is often really hard to debug if you + * screw something up by accident. + * + * Example: + * @code + * unsigned int *a, *b, *c; + * a = talloc(NULL, unsigned int); + * b = talloc(NULL, unsigned int); + * c = talloc(a, unsigned int); + * // b also serves as a parent of c. + * talloc_reference(b, c); + * @endcode + * + * @see talloc_unlink() + */ +void *talloc_reference(const void *ctx, const void *ptr); +#else +#define talloc_reference(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_reference_loc((ctx),(ptr), __location__) +void *_talloc_reference_loc(const void *context, const void *ptr, const char *location); +#endif + +/** + * @brief Remove a specific parent from a talloc chunk. + * + * The function removes a specific parent from ptr. The context passed must + * either be a context used in talloc_reference() with this pointer, or must be + * a direct parent of ptr. + * + * You can just use talloc_free() instead of talloc_unlink() if there + * is at maximum one parent. This behaviour has been changed since the + * release of version 2.0. Further information in the description of + * "talloc_free". + * + * @param[in] context The talloc parent to remove. + * + * @param[in] ptr The talloc ptr you want to remove the parent from. + * + * @return 0 on success, -1 on error. + * + * @note If the parent has already been removed using talloc_free() then + * this function will fail and will return -1. Likewise, if ptr is NULL, + * then the function will make no modifications and return -1. + * + * @warning You should try to avoid using this interface. It turns a beautiful + * talloc-tree into a graph. It is often really hard to debug if you + * screw something up by accident. + * + * Example: + * @code + * unsigned int *a, *b, *c; + * a = talloc(NULL, unsigned int); + * b = talloc(NULL, unsigned int); + * c = talloc(a, unsigned int); + * // b also serves as a parent of c. + * talloc_reference(b, c); + * talloc_unlink(b, c); + * @endcode + */ +int talloc_unlink(const void *context, void *ptr); + +/** + * @brief Provide a talloc context that is freed at program exit. + * + * This is a handy utility function that returns a talloc context + * which will be automatically freed on program exit. This can be used + * to reduce the noise in memory leak reports. + * + * Never use this in code that might be used in objects loaded with + * dlopen and unloaded with dlclose. talloc_autofree_context() + * internally uses atexit(3). Some platforms like modern Linux handles + * this fine, but for example FreeBSD does not deal well with dlopen() + * and atexit() used simultaneously: dlclose() does not clean up the + * list of atexit-handlers, so when the program exits the code that + * was registered from within talloc_autofree_context() is gone, the + * program crashes at exit. + * + * @return A talloc context, NULL on error. + */ +void *talloc_autofree_context(void) _DEPRECATED_; + +/** + * @brief Get the size of a talloc chunk. + * + * This function lets you know the amount of memory allocated so far by + * this context. It does NOT account for subcontext memory. + * This can be used to calculate the size of an array. + * + * @param[in] ctx The talloc chunk. + * + * @return The size of the talloc chunk. + */ +size_t talloc_get_size(const void *ctx); + +/** + * @brief Show the parentage of a context. + * + * @param[in] context The talloc context to look at. + * + * @param[in] file The output to use, a file, stdout or stderr. + */ +void talloc_show_parents(const void *context, FILE *file); + +/** + * @brief Check if a context is parent of a talloc chunk. + * + * This checks if context is referenced in the talloc hierarchy above ptr. + * + * @param[in] context The assumed talloc context. + * + * @param[in] ptr The talloc chunk to check. + * + * @return Return 1 if this is the case, 0 if not. + */ +int talloc_is_parent(const void *context, const void *ptr); + +/** + * @brief Change the parent context of a talloc pointer. + * + * The function changes the parent context of a talloc pointer. It is typically + * used when the context that the pointer is currently a child of is going to be + * freed and you wish to keep the memory for a longer time. + * + * The difference between talloc_reparent() and talloc_steal() is that + * talloc_reparent() can specify which parent you wish to change. This is + * useful when a pointer has multiple parents via references. + * + * @param[in] old_parent + * @param[in] new_parent + * @param[in] ptr + * + * @return Return the pointer you passed. It does not have any + * failure modes. + */ +void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr); + +/* @} ******************************************************************/ + +/** + * @defgroup talloc_array The talloc array functions + * @ingroup talloc + * + * Talloc contains some handy helpers for handling Arrays conveniently + * + * @{ + */ + +#ifdef DOXYGEN +/** + * @brief Allocate an array. + * + * The macro is equivalent to: + * + * @code + * (type *)talloc_size(ctx, sizeof(type) * count); + * @endcode + * + * except that it provides integer overflow protection for the multiply, + * returning NULL if the multiply overflows. + * + * @param[in] ctx The talloc context to hang the result off. + * + * @param[in] type The type that we want to allocate. + * + * @param[in] count The number of 'type' elements you want to allocate. + * + * @return The allocated result, properly cast to 'type *', NULL on + * error. + * + * Example: + * @code + * unsigned int *a, *b; + * a = talloc_zero(NULL, unsigned int); + * b = talloc_array(a, unsigned int, 100); + * @endcode + * + * @see talloc() + * @see talloc_zero_array() + */ +void *talloc_array(const void *ctx, #type, unsigned count); +#else +#define talloc_array(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type) +void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name); +#endif + +#ifdef DOXYGEN +/** + * @brief Allocate an array. + * + * @param[in] ctx The talloc context to hang the result off. + * + * @param[in] size The size of an array element. + * + * @param[in] count The number of elements you want to allocate. + * + * @return The allocated result, NULL on error. + */ +void *talloc_array_size(const void *ctx, size_t size, unsigned count); +#else +#define talloc_array_size(ctx, size, count) _talloc_array(ctx, size, count, __location__) +#endif + +#ifdef DOXYGEN +/** + * @brief Allocate an array into a typed pointer. + * + * The macro should be used when you have a pointer to an array and want to + * allocate memory of an array to point at with this pointer. When compiling + * with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_array_size() + * and talloc_get_name() will return the current location in the source file + * and not the type. + * + * @param[in] ctx The talloc context to hang the result off. + * + * @param[in] ptr The pointer you want to assign the result to. + * + * @param[in] count The number of elements you want to allocate. + * + * @return The allocated memory chunk, properly casted. NULL on + * error. + */ +void *talloc_array_ptrtype(const void *ctx, const void *ptr, unsigned count); +#else +#define talloc_array_ptrtype(ctx, ptr, count) (_TALLOC_TYPEOF(ptr))talloc_array_size(ctx, sizeof(*(ptr)), count) +#endif + +#ifdef DOXYGEN +/** + * @brief Get the number of elements in a talloc'ed array. + * + * A talloc chunk carries its own size, so for talloc'ed arrays it is not + * necessary to store the number of elements explicitly. + * + * @param[in] ctx The allocated array. + * + * @return The number of elements in ctx. + */ +size_t talloc_array_length(const void *ctx); +#else +#define talloc_array_length(ctx) (talloc_get_size(ctx)/sizeof(*ctx)) +#endif + +#ifdef DOXYGEN +/** + * @brief Allocate a zero-initialized array + * + * @param[in] ctx The talloc context to hang the result off. + * + * @param[in] type The type that we want to allocate. + * + * @param[in] count The number of "type" elements you want to allocate. + * + * @return The allocated result casted to "type *", NULL on error. + * + * The talloc_zero_array() macro is equivalent to: + * + * @code + * ptr = talloc_array(ctx, type, count); + * if (ptr) memset(ptr, 0, sizeof(type) * count); + * @endcode + */ +void *talloc_zero_array(const void *ctx, #type, unsigned count); +#else +#define talloc_zero_array(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type) +void *_talloc_zero_array(const void *ctx, + size_t el_size, + unsigned count, + const char *name); +#endif + +#ifdef DOXYGEN +/** + * @brief Change the size of a talloc array. + * + * The macro changes the size of a talloc pointer. The 'count' argument is the + * number of elements of type 'type' that you want the resulting pointer to + * hold. + * + * talloc_realloc() has the following equivalences: + * + * @code + * talloc_realloc(ctx, NULL, type, 1) ==> talloc(ctx, type); + * talloc_realloc(ctx, NULL, type, N) ==> talloc_array(ctx, type, N); + * talloc_realloc(ctx, ptr, type, 0) ==> talloc_free(ptr); + * @endcode + * + * The "context" argument is only used if "ptr" is NULL, otherwise it is + * ignored. + * + * @param[in] ctx The parent context used if ptr is NULL. + * + * @param[in] ptr The chunk to be resized. + * + * @param[in] type The type of the array element inside ptr. + * + * @param[in] count The intended number of array elements. + * + * @return The new array, NULL on error. The call will fail either + * due to a lack of memory, or because the pointer has more + * than one parent (see talloc_reference()). + */ +void *talloc_realloc(const void *ctx, void *ptr, #type, size_t count); +#else +#define talloc_realloc(ctx, p, type, count) (type *)_talloc_realloc_array(ctx, p, sizeof(type), count, #type) +void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name); +#endif + +#ifdef DOXYGEN +/** + * @brief Untyped realloc to change the size of a talloc array. + * + * The macro is useful when the type is not known so the typesafe + * talloc_realloc() cannot be used. + * + * @param[in] ctx The parent context used if 'ptr' is NULL. + * + * @param[in] ptr The chunk to be resized. + * + * @param[in] size The new chunk size. + * + * @return The new array, NULL on error. + */ +void *talloc_realloc_size(const void *ctx, void *ptr, size_t size); +#else +#define talloc_realloc_size(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__) +void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name); +#endif + +/** + * @brief Provide a function version of talloc_realloc_size. + * + * This is a non-macro version of talloc_realloc(), which is useful as + * libraries sometimes want a ralloc function pointer. A realloc() + * implementation encapsulates the functionality of malloc(), free() and + * realloc() in one call, which is why it is useful to be able to pass around + * a single function pointer. + * + * @param[in] context The parent context used if ptr is NULL. + * + * @param[in] ptr The chunk to be resized. + * + * @param[in] size The new chunk size. + * + * @return The new chunk, NULL on error. + */ +void *talloc_realloc_fn(const void *context, void *ptr, size_t size); + +/* @} ******************************************************************/ + +/** + * @defgroup talloc_string The talloc string functions. + * @ingroup talloc + * + * talloc string allocation and manipulation functions. + * @{ + */ + +/** + * @brief Duplicate a string into a talloc chunk. + * + * This function is equivalent to: + * + * @code + * ptr = talloc_size(ctx, strlen(p)+1); + * if (ptr) memcpy(ptr, p, strlen(p)+1); + * @endcode + * + * This functions sets the name of the new pointer to the passed + * string. This is equivalent to: + * + * @code + * talloc_set_name_const(ptr, ptr) + * @endcode + * + * @param[in] t The talloc context to hang the result off. + * + * @param[in] p The string you want to duplicate. + * + * @return The duplicated string, NULL on error. + */ +char *talloc_strdup(const void *t, const char *p); + +/** + * @brief Append a string to given string. + * + * The destination string is reallocated to take + * strlen(s) + strlen(a) + 1 characters. + * + * This functions sets the name of the new pointer to the new + * string. This is equivalent to: + * + * @code + * talloc_set_name_const(ptr, ptr) + * @endcode + * + * If s == NULL then new context is created. + * + * @param[in] s The destination to append to. + * + * @param[in] a The string you want to append. + * + * @return The concatenated strings, NULL on error. + * + * @see talloc_strdup() + * @see talloc_strdup_append_buffer() + */ +char *talloc_strdup_append(char *s, const char *a); + +/** + * @brief Append a string to a given buffer. + * + * This is a more efficient version of talloc_strdup_append(). It determines the + * length of the destination string by the size of the talloc context. + * + * Use this very carefully as it produces a different result than + * talloc_strdup_append() when a zero character is in the middle of the + * destination string. + * + * @code + * char *str_a = talloc_strdup(NULL, "hello world"); + * char *str_b = talloc_strdup(NULL, "hello world"); + * str_a[5] = str_b[5] = '\0' + * + * char *app = talloc_strdup_append(str_a, ", hello"); + * char *buf = talloc_strdup_append_buffer(str_b, ", hello"); + * + * printf("%s\n", app); // hello, hello (app = "hello, hello") + * printf("%s\n", buf); // hello (buf = "hello\0world, hello") + * @endcode + * + * If s == NULL then new context is created. + * + * @param[in] s The destination buffer to append to. + * + * @param[in] a The string you want to append. + * + * @return The concatenated strings, NULL on error. + * + * @see talloc_strdup() + * @see talloc_strdup_append() + * @see talloc_array_length() + */ +char *talloc_strdup_append_buffer(char *s, const char *a); + +/** + * @brief Duplicate a length-limited string into a talloc chunk. + * + * This function is the talloc equivalent of the C library function strndup(3). + * + * This functions sets the name of the new pointer to the passed string. This is + * equivalent to: + * + * @code + * talloc_set_name_const(ptr, ptr) + * @endcode + * + * @param[in] t The talloc context to hang the result off. + * + * @param[in] p The string you want to duplicate. + * + * @param[in] n The maximum string length to duplicate. + * + * @return The duplicated string, NULL on error. + */ +char *talloc_strndup(const void *t, const char *p, size_t n); + +/** + * @brief Append at most n characters of a string to given string. + * + * The destination string is reallocated to take + * strlen(s) + strnlen(a, n) + 1 characters. + * + * This functions sets the name of the new pointer to the new + * string. This is equivalent to: + * + * @code + * talloc_set_name_const(ptr, ptr) + * @endcode + * + * If s == NULL then new context is created. + * + * @param[in] s The destination string to append to. + * + * @param[in] a The source string you want to append. + * + * @param[in] n The number of characters you want to append from the + * string. + * + * @return The concatenated strings, NULL on error. + * + * @see talloc_strndup() + * @see talloc_strndup_append_buffer() + */ +char *talloc_strndup_append(char *s, const char *a, size_t n); + +/** + * @brief Append at most n characters of a string to given buffer + * + * This is a more efficient version of talloc_strndup_append(). It determines + * the length of the destination string by the size of the talloc context. + * + * Use this very carefully as it produces a different result than + * talloc_strndup_append() when a zero character is in the middle of the + * destination string. + * + * @code + * char *str_a = talloc_strdup(NULL, "hello world"); + * char *str_b = talloc_strdup(NULL, "hello world"); + * str_a[5] = str_b[5] = '\0' + * + * char *app = talloc_strndup_append(str_a, ", hello", 7); + * char *buf = talloc_strndup_append_buffer(str_b, ", hello", 7); + * + * printf("%s\n", app); // hello, hello (app = "hello, hello") + * printf("%s\n", buf); // hello (buf = "hello\0world, hello") + * @endcode + * + * If s == NULL then new context is created. + * + * @param[in] s The destination buffer to append to. + * + * @param[in] a The source string you want to append. + * + * @param[in] n The number of characters you want to append from the + * string. + * + * @return The concatenated strings, NULL on error. + * + * @see talloc_strndup() + * @see talloc_strndup_append() + * @see talloc_array_length() + */ +char *talloc_strndup_append_buffer(char *s, const char *a, size_t n); + +/** + * @brief Format a string given a va_list. + * + * This function is the talloc equivalent of the C library function + * vasprintf(3). + * + * This functions sets the name of the new pointer to the new string. This is + * equivalent to: + * + * @code + * talloc_set_name_const(ptr, ptr) + * @endcode + * + * @param[in] t The talloc context to hang the result off. + * + * @param[in] fmt The format string. + * + * @param[in] ap The parameters used to fill fmt. + * + * @return The formatted string, NULL on error. + */ +char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); + +/** + * @brief Format a string given a va_list and append it to the given destination + * string. + * + * @param[in] s The destination string to append to. + * + * @param[in] fmt The format string. + * + * @param[in] ap The parameters used to fill fmt. + * + * @return The formatted string, NULL on error. + * + * @see talloc_vasprintf() + */ +char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); + +/** + * @brief Format a string given a va_list and append it to the given destination + * buffer. + * + * @param[in] s The destination buffer to append to. + * + * @param[in] fmt The format string. + * + * @param[in] ap The parameters used to fill fmt. + * + * @return The formatted string, NULL on error. + * + * @see talloc_vasprintf() + */ +char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); + +/** + * @brief Format a string. + * + * This function is the talloc equivalent of the C library function asprintf(3). + * + * This functions sets the name of the new pointer to the new string. This is + * equivalent to: + * + * @code + * talloc_set_name_const(ptr, ptr) + * @endcode + * + * @param[in] t The talloc context to hang the result off. + * + * @param[in] fmt The format string. + * + * @param[in] ... The parameters used to fill fmt. + * + * @return The formatted string, NULL on error. + */ +char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); + +/** + * @brief Append a formatted string to another string. + * + * This function appends the given formatted string to the given string. Use + * this variant when the string in the current talloc buffer may have been + * truncated in length. + * + * This functions sets the name of the new pointer to the new + * string. This is equivalent to: + * + * @code + * talloc_set_name_const(ptr, ptr) + * @endcode + * + * If s == NULL then new context is created. + * + * @param[in] s The string to append to. + * + * @param[in] fmt The format string. + * + * @param[in] ... The parameters used to fill fmt. + * + * @return The formatted string, NULL on error. + */ +char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); + +/** + * @brief Append a formatted string to another string. + * + * This is a more efficient version of talloc_asprintf_append(). It determines + * the length of the destination string by the size of the talloc context. + * + * Use this very carefully as it produces a different result than + * talloc_asprintf_append() when a zero character is in the middle of the + * destination string. + * + * @code + * char *str_a = talloc_strdup(NULL, "hello world"); + * char *str_b = talloc_strdup(NULL, "hello world"); + * str_a[5] = str_b[5] = '\0' + * + * char *app = talloc_asprintf_append(str_a, "%s", ", hello"); + * char *buf = talloc_strdup_append_buffer(str_b, "%s", ", hello"); + * + * printf("%s\n", app); // hello, hello (app = "hello, hello") + * printf("%s\n", buf); // hello (buf = "hello\0world, hello") + * @endcode + * + * If s == NULL then new context is created. + * + * @param[in] s The string to append to + * + * @param[in] fmt The format string. + * + * @param[in] ... The parameters used to fill fmt. + * + * @return The formatted string, NULL on error. + * + * @see talloc_asprintf() + * @see talloc_asprintf_append() + */ +char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); + +/* @} ******************************************************************/ + +/** + * @defgroup talloc_debug The talloc debugging support functions + * @ingroup talloc + * + * To aid memory debugging, talloc contains routines to inspect the currently + * allocated memory hierarchy. + * + * @{ + */ + +/** + * @brief Walk a complete talloc hierarchy. + * + * This provides a more flexible reports than talloc_report(). It + * will recursively call the callback for the entire tree of memory + * referenced by the pointer. References in the tree are passed with + * is_ref = 1 and the pointer that is referenced. + * + * You can pass NULL for the pointer, in which case a report is + * printed for the top level memory context, but only if + * talloc_enable_leak_report() or talloc_enable_leak_report_full() + * has been called. + * + * The recursion is stopped when depth >= max_depth. + * max_depth = -1 means only stop at leaf nodes. + * + * @param[in] ptr The talloc chunk. + * + * @param[in] depth Internal parameter to control recursion. Call with 0. + * + * @param[in] max_depth Maximum recursion level. + * + * @param[in] callback Function to be called on every chunk. + * + * @param[in] private_data Private pointer passed to callback. + */ +void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, + void (*callback)(const void *ptr, + int depth, int max_depth, + int is_ref, + void *private_data), + void *private_data); + +/** + * @brief Print a talloc hierarchy. + * + * This provides a more flexible reports than talloc_report(). It + * will let you specify the depth and max_depth. + * + * @param[in] ptr The talloc chunk. + * + * @param[in] depth Internal parameter to control recursion. Call with 0. + * + * @param[in] max_depth Maximum recursion level. + * + * @param[in] f The file handle to print to. + */ +void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f); + +/** + * @brief Print a summary report of all memory used by ptr. + * + * This provides a more detailed report than talloc_report(). It will + * recursively print the entire tree of memory referenced by the + * pointer. References in the tree are shown by giving the name of the + * pointer that is referenced. + * + * You can pass NULL for the pointer, in which case a report is printed + * for the top level memory context, but only if + * talloc_enable_leak_report() or talloc_enable_leak_report_full() has + * been called. + * + * @param[in] ptr The talloc chunk. + * + * @param[in] f The file handle to print to. + * + * Example: + * @code + * unsigned int *a, *b; + * a = talloc(NULL, unsigned int); + * b = talloc(a, unsigned int); + * fprintf(stderr, "Dumping memory tree for a:\n"); + * talloc_report_full(a, stderr); + * @endcode + * + * @see talloc_report() + */ +void talloc_report_full(const void *ptr, FILE *f); + +/** + * @brief Print a summary report of all memory used by ptr. + * + * This function prints a summary report of all memory used by ptr. One line of + * report is printed for each immediate child of ptr, showing the total memory + * and number of blocks used by that child. + * + * You can pass NULL for the pointer, in which case a report is printed + * for the top level memory context, but only if talloc_enable_leak_report() + * or talloc_enable_leak_report_full() has been called. + * + * @param[in] ptr The talloc chunk. + * + * @param[in] f The file handle to print to. + * + * Example: + * @code + * unsigned int *a, *b; + * a = talloc(NULL, unsigned int); + * b = talloc(a, unsigned int); + * fprintf(stderr, "Summary of memory tree for a:\n"); + * talloc_report(a, stderr); + * @endcode + * + * @see talloc_report_full() + */ +void talloc_report(const void *ptr, FILE *f); + +/** + * @brief Enable tracking the use of NULL memory contexts. + * + * This enables tracking of the NULL memory context without enabling leak + * reporting on exit. Useful for when you want to do your own leak + * reporting call via talloc_report_null_full(); + */ +void talloc_enable_null_tracking(void); + +/** + * @brief Enable tracking the use of NULL memory contexts. + * + * This enables tracking of the NULL memory context without enabling leak + * reporting on exit. Useful for when you want to do your own leak + * reporting call via talloc_report_null_full(); + */ +void talloc_enable_null_tracking_no_autofree(void); + +/** + * @brief Disable tracking of the NULL memory context. + * + * This disables tracking of the NULL memory context. + */ +void talloc_disable_null_tracking(void); + +/** + * @brief Enable leak report when a program exits. + * + * This enables calling of talloc_report(NULL, stderr) when the program + * exits. In Samba4 this is enabled by using the --leak-report command + * line option. + * + * For it to be useful, this function must be called before any other + * talloc function as it establishes a "null context" that acts as the + * top of the tree. If you don't call this function first then passing + * NULL to talloc_report() or talloc_report_full() won't give you the + * full tree printout. + * + * Here is a typical talloc report: + * + * @code + * talloc report on 'null_context' (total 267 bytes in 15 blocks) + * libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks + * libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks + * iconv(UTF8,CP850) contains 42 bytes in 2 blocks + * libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks + * iconv(CP850,UTF8) contains 42 bytes in 2 blocks + * iconv(UTF8,UTF-16LE) contains 45 bytes in 2 blocks + * iconv(UTF-16LE,UTF8) contains 45 bytes in 2 blocks + * @endcode + */ +void talloc_enable_leak_report(void); + +/** + * @brief Enable full leak report when a program exits. + * + * This enables calling of talloc_report_full(NULL, stderr) when the + * program exits. In Samba4 this is enabled by using the + * --leak-report-full command line option. + * + * For it to be useful, this function must be called before any other + * talloc function as it establishes a "null context" that acts as the + * top of the tree. If you don't call this function first then passing + * NULL to talloc_report() or talloc_report_full() won't give you the + * full tree printout. + * + * Here is a typical full report: + * + * @code + * full talloc report on 'root' (total 18 bytes in 8 blocks) + * p1 contains 18 bytes in 7 blocks (ref 0) + * r1 contains 13 bytes in 2 blocks (ref 0) + * reference to: p2 + * p2 contains 1 bytes in 1 blocks (ref 1) + * x3 contains 1 bytes in 1 blocks (ref 0) + * x2 contains 1 bytes in 1 blocks (ref 0) + * x1 contains 1 bytes in 1 blocks (ref 0) + * @endcode + */ +void talloc_enable_leak_report_full(void); + +/** + * @brief Set a custom "abort" function that is called on serious error. + * + * The default "abort" function is abort(). + * + * The "abort" function is called when: + * + *
        + *
      • talloc_get_type_abort() fails
      • + *
      • the provided pointer is not a valid talloc context
      • + *
      • when the context meta data are invalid
      • + *
      • when access after free is detected
      • + *
      + * + * Example: + * + * @code + * void my_abort(const char *reason) + * { + * fprintf(stderr, "talloc abort: %s\n", reason); + * abort(); + * } + * + * talloc_set_abort_fn(my_abort); + * @endcode + * + * @param[in] abort_fn The new "abort" function. + * + * @see talloc_set_log_fn() + * @see talloc_get_type() + */ +void talloc_set_abort_fn(void (*abort_fn)(const char *reason)); + +/** + * @brief Set a logging function. + * + * @param[in] log_fn The logging function. + * + * @see talloc_set_log_stderr() + * @see talloc_set_abort_fn() + */ +void talloc_set_log_fn(void (*log_fn)(const char *message)); + +/** + * @brief Set stderr as the output for logs. + * + * @see talloc_set_log_fn() + * @see talloc_set_abort_fn() + */ +void talloc_set_log_stderr(void); + +/** + * @brief Set a max memory limit for the current context hierarchy + * This affects all children of this context and constrain any + * allocation in the hierarchy to never exceed the limit set. + * The limit can be removed by setting 0 (unlimited) as the + * max_size by calling the function again on the same context. + * Memory limits can also be nested, meaning a child can have + * a stricter memory limit than a parent. + * Memory limits are enforced only at memory allocation time. + * Stealing a context into a 'limited' hierarchy properly + * updates memory usage but does *not* cause failure if the + * move causes the new parent to exceed its limits. However + * any further allocation on that hierarchy will then fail. + * + * @warning talloc memlimit functionality is deprecated. Please + * consider using cgroup memory limits instead. + * + * @param[in] ctx The talloc context to set the limit on + * @param[in] max_size The (new) max_size + */ +int talloc_set_memlimit(const void *ctx, size_t max_size) _DEPRECATED_; + +/* @} ******************************************************************/ + +#if TALLOC_DEPRECATED +#define talloc_zero_p(ctx, type) talloc_zero(ctx, type) +#define talloc_p(ctx, type) talloc(ctx, type) +#define talloc_array_p(ctx, type, count) talloc_array(ctx, type, count) +#define talloc_realloc_p(ctx, p, type, count) talloc_realloc(ctx, p, type, count) +#define talloc_destroy(ctx) talloc_free(ctx) +#define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a)) +#endif + +#ifndef TALLOC_MAX_DEPTH +#define TALLOC_MAX_DEPTH 10000 +#endif + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif diff --git a/ldb-2.0.8/lib/talloc/talloc.pc.in b/ldb-2.0.8/lib/talloc/talloc.pc.in new file mode 100644 index 0000000..437281a --- /dev/null +++ b/ldb-2.0.8/lib/talloc/talloc.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: talloc +Description: A hierarchical pool based memory system with destructors +Version: @TALLOC_VERSION@ +Libs: @LIB_RPATH@ -L${libdir} -ltalloc +Cflags: -I${includedir} +URL: http://talloc.samba.org/ diff --git a/ldb-2.0.8/lib/talloc/talloc_guide.txt b/ldb-2.0.8/lib/talloc/talloc_guide.txt new file mode 100644 index 0000000..dedda6c --- /dev/null +++ b/ldb-2.0.8/lib/talloc/talloc_guide.txt @@ -0,0 +1,768 @@ +Using talloc in Samba4 +====================== + +.. contents:: + +Andrew Tridgell +August 2009 + +The most current version of this document is available at + http://samba.org/ftp/unpacked/talloc/talloc_guide.txt + +If you are used to the "old" talloc from Samba3 before 3.0.20 then please read +this carefully, as talloc has changed a lot. With 3.0.20 (or 3.0.14?) the +Samba4 talloc has been ported back to Samba3, so this guide applies to both. + +The new talloc is a hierarchical, reference counted memory pool system +with destructors. Quite a mouthful really, but not too bad once you +get used to it. + +Perhaps the biggest change from Samba3 is that there is no distinction +between a "talloc context" and a "talloc pointer". Any pointer +returned from talloc() is itself a valid talloc context. This means +you can do this:: + + struct foo *X = talloc(mem_ctx, struct foo); + X->name = talloc_strdup(X, "foo"); + +and the pointer X->name would be a "child" of the talloc context "X" +which is itself a child of "mem_ctx". So if you do talloc_free(mem_ctx) +then it is all destroyed, whereas if you do talloc_free(X) then just X +and X->name are destroyed, and if you do talloc_free(X->name) then +just the name element of X is destroyed. + +If you think about this, then what this effectively gives you is an +n-ary tree, where you can free any part of the tree with +talloc_free(). + +If you find this confusing, then I suggest you run the testsuite to +watch talloc in action. You may also like to add your own tests to +testsuite.c to clarify how some particular situation is handled. + + +Performance +----------- + +All the additional features of talloc() over malloc() do come at a +price. We have a simple performance test in Samba4 that measures +talloc() versus malloc() performance, and it seems that talloc() is +about 4% slower than malloc() on my x86 Debian Linux box. For Samba, +the great reduction in code complexity that we get by using talloc +makes this worthwhile, especially as the total overhead of +talloc/malloc in Samba is already quite small. + + +talloc API +---------- + +The following is a complete guide to the talloc API. Read it all at +least twice. + +Multi-threading +--------------- + +talloc itself does not deal with threads. It is thread-safe (assuming +the underlying "malloc" is), as long as each thread uses different +memory contexts. +If two threads use the same context then they need to synchronize in +order to be safe. In particular: +- when using talloc_enable_leak_report(), giving directly NULL as a +parent context implicitly refers to a hidden "null context" global +variable, so this should not be used in a multi-threaded environment +without proper synchronization. In threaded code turn off null tracking using +talloc_disable_null_tracking(). ; +- the context returned by talloc_autofree_context() is also global so +shouldn't be used by several threads simultaneously without +synchronization. + +talloc and shared objects +------------------------- + +talloc can be used in shared objects. Special care needs to be taken +to never use talloc_autofree_context() in code that might be loaded +with dlopen() and unloaded with dlclose(), as talloc_autofree_context() +internally uses atexit(3). Some platforms like modern Linux handles +this fine, but for example FreeBSD does not deal well with dlopen() +and atexit() used simultaneously: dlclose() does not clean up the list +of atexit-handlers, so when the program exits the code that was +registered from within talloc_autofree_context() is gone, the program +crashes at exit. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(type *)talloc(const void *context, type); + +The talloc() macro is the core of the talloc library. It takes a +memory context and a type, and returns a pointer to a new area of +memory of the given type. + +The returned pointer is itself a talloc context, so you can use it as +the context argument to more calls to talloc if you wish. + +The returned pointer is a "child" of the supplied context. This means +that if you talloc_free() the context then the new child disappears as +well. Alternatively you can free just the child. + +The context argument to talloc() can be NULL, in which case a new top +level context is created. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_size(const void *context, size_t size); + +The function talloc_size() should be used when you don't have a +convenient type to pass to talloc(). Unlike talloc(), it is not type +safe (as it returns a void *), so you are on your own for type checking. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(typeof(ptr)) talloc_ptrtype(const void *ctx, ptr); + +The talloc_ptrtype() macro should be used when you have a pointer and +want to allocate memory to point at with this pointer. When compiling +with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size() +and talloc_get_name() will return the current location in the source file. +and not the type. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +int talloc_free(void *ptr); + +The talloc_free() function frees a piece of talloc memory, and all its +children. You can call talloc_free() on any pointer returned by +talloc(). + +The return value of talloc_free() indicates success or failure, with 0 +returned for success and -1 for failure. A possible failure condition +is if the pointer had a destructor attached to it and the destructor +returned -1. See talloc_set_destructor() for details on +destructors. Likewise, if "ptr" is NULL, then the function will make +no modifications and returns -1. + +From version 2.0 and onwards, as a special case, talloc_free() is +refused on pointers that have more than one parent associated, as talloc +would have no way of knowing which parent should be removed. This is +different from older versions in the sense that always the reference to +the most recently established parent has been destroyed. Hence to free a +pointer that has more than one parent please use talloc_unlink(). + +To help you find problems in your code caused by this behaviour, if +you do try and free a pointer with more than one parent then the +talloc logging function will be called to give output like this: + + ERROR: talloc_free with references at some_dir/source/foo.c:123 + reference at some_dir/source/other.c:325 + reference at some_dir/source/third.c:121 + +Please see the documentation for talloc_set_log_fn() and +talloc_set_log_stderr() for more information on talloc logging +functions. + +talloc_free() operates recursively on its children. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_free_children(void *ptr); + +The talloc_free_children() walks along the list of all children of a +talloc context and talloc_free()s only the children, not the context +itself. + +A NULL argument is handled as no-op. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_reference(const void *context, const void *ptr); + +The talloc_reference() function makes "context" an additional parent +of "ptr". + +The return value of talloc_reference() is always the original pointer +"ptr", unless talloc ran out of memory in creating the reference in +which case it will return NULL (each additional reference consumes +around 48 bytes of memory on intel x86 platforms). + +If "ptr" is NULL, then the function is a no-op, and simply returns NULL. + +After creating a reference you can free it in one of the following +ways: + + - you can talloc_free() any parent of the original pointer. That + will reduce the number of parents of this pointer by 1, and will + cause this pointer to be freed if it runs out of parents. + + - you can talloc_free() the pointer itself if it has at maximum one + parent. This behaviour has been changed since the release of version + 2.0. Further information in the description of "talloc_free". + +For more control on which parent to remove, see talloc_unlink() + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +int talloc_unlink(const void *context, void *ptr); + +The talloc_unlink() function removes a specific parent from ptr. The +context passed must either be a context used in talloc_reference() +with this pointer, or must be a direct parent of ptr. + +Note that if the parent has already been removed using talloc_free() +then this function will fail and will return -1. Likewise, if "ptr" +is NULL, then the function will make no modifications and return -1. + +You can just use talloc_free() instead of talloc_unlink() if there +is at maximum one parent. This behaviour has been changed since the +release of version 2.0. Further information in the description of +"talloc_free". + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_set_destructor(const void *ptr, int (*destructor)(void *)); + +The function talloc_set_destructor() sets the "destructor" for the +pointer "ptr". A destructor is a function that is called when the +memory used by a pointer is about to be released. The destructor +receives the pointer as an argument, and should return 0 for success +and -1 for failure. + +The destructor can do anything it wants to, including freeing other +pieces of memory. A common use for destructors is to clean up +operating system resources (such as open file descriptors) contained +in the structure the destructor is placed on. + +You can only place one destructor on a pointer. If you need more than +one destructor then you can create a zero-length child of the pointer +and place an additional destructor on that. + +To remove a destructor call talloc_set_destructor() with NULL for the +destructor. + +If your destructor attempts to talloc_free() the pointer that it is +the destructor for then talloc_free() will return -1 and the free will +be ignored. This would be a pointless operation anyway, as the +destructor is only called when the memory is just about to go away. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +int talloc_increase_ref_count(const void *ptr); + +The talloc_increase_ref_count(ptr) function is exactly equivalent to: + + talloc_reference(NULL, ptr); + +You can use either syntax, depending on which you think is clearer in +your code. + +It returns 0 on success and -1 on failure. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +size_t talloc_reference_count(const void *ptr); + +Return the number of references to the pointer. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_set_name(const void *ptr, const char *fmt, ...); + +Each talloc pointer has a "name". The name is used principally for +debugging purposes, although it is also possible to set and get the +name on a pointer in as a way of "marking" pointers in your code. + +The main use for names on pointer is for "talloc reports". See +talloc_report() and talloc_report_full() for details. Also see +talloc_enable_leak_report() and talloc_enable_leak_report_full(). + +The talloc_set_name() function allocates memory as a child of the +pointer. It is logically equivalent to: + talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...)); + +Note that multiple calls to talloc_set_name() will allocate more +memory without releasing the name. All of the memory is released when +the ptr is freed using talloc_free(). + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_set_name_const(const void *ptr, const char *name); + +The function talloc_set_name_const() is just like talloc_set_name(), +but it takes a string constant, and is much faster. It is extensively +used by the "auto naming" macros, such as talloc_p(). + +This function does not allocate any memory. It just copies the +supplied pointer into the internal representation of the talloc +ptr. This means you must not pass a name pointer to memory that will +disappear before the ptr is freed with talloc_free(). + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_named(const void *context, size_t size, const char *fmt, ...); + +The talloc_named() function creates a named talloc pointer. It is +equivalent to: + + ptr = talloc_size(context, size); + talloc_set_name(ptr, fmt, ....); + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_named_const(const void *context, size_t size, const char *name); + +This is equivalent to:: + + ptr = talloc_size(context, size); + talloc_set_name_const(ptr, name); + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +const char *talloc_get_name(const void *ptr); + +This returns the current name for the given talloc pointer. See +talloc_set_name() for details. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_init(const char *fmt, ...); + +This function creates a zero length named talloc context as a top +level context. It is equivalent to:: + + talloc_named(NULL, 0, fmt, ...); + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_new(void *ctx); + +This is a utility macro that creates a new memory context hanging +off an exiting context, automatically naming it "talloc_new: __location__" +where __location__ is the source line it is called from. It is +particularly useful for creating a new temporary working context. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(type *)talloc_realloc(const void *context, void *ptr, type, count); + +The talloc_realloc() macro changes the size of a talloc +pointer. The "count" argument is the number of elements of type "type" +that you want the resulting pointer to hold. + +talloc_realloc() has the following equivalences:: + + talloc_realloc(context, NULL, type, 1) ==> talloc(context, type); + talloc_realloc(context, NULL, type, N) ==> talloc_array(context, type, N); + talloc_realloc(context, ptr, type, 0) ==> talloc_free(ptr); + +The "context" argument is only used if "ptr" is NULL, otherwise it is +ignored. + +talloc_realloc() returns the new pointer, or NULL on failure. The call +will fail either due to a lack of memory, or because the pointer has +more than one parent (see talloc_reference()). + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_realloc_size(const void *context, void *ptr, size_t size); + +the talloc_realloc_size() function is useful when the type is not +known so the typesafe talloc_realloc() cannot be used. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_steal(const void *new_ctx, const void *ptr); + +The talloc_steal() function changes the parent context of a talloc +pointer. It is typically used when the context that the pointer is +currently a child of is going to be freed and you wish to keep the +memory for a longer time. + +The talloc_steal() function returns the pointer that you pass it. It +does not have any failure modes. + +NOTE: It is possible to produce loops in the parent/child relationship +if you are not careful with talloc_steal(). No guarantees are provided +as to your sanity or the safety of your data if you do this. + +talloc_steal (new_ctx, NULL) will return NULL with no sideeffects. + +Note that if you try and call talloc_steal() on a pointer that has +more than one parent then the result is ambiguous. Talloc will choose +to remove the parent that is currently indicated by talloc_parent() +and replace it with the chosen parent. You will also get a message +like this via the talloc logging functions: + + WARNING: talloc_steal with references at some_dir/source/foo.c:123 + reference at some_dir/source/other.c:325 + reference at some_dir/source/third.c:121 + +To unambiguously change the parent of a pointer please see the +function talloc_reparent(). See the talloc_set_log_fn() documentation +for more information on talloc logging. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr); + +The talloc_reparent() function changes the parent context of a talloc +pointer. It is typically used when the context that the pointer is +currently a child of is going to be freed and you wish to keep the +memory for a longer time. + +The talloc_reparent() function returns the pointer that you pass it. It +does not have any failure modes. + +The difference between talloc_reparent() and talloc_steal() is that +talloc_reparent() can specify which parent you wish to change. This is +useful when a pointer has multiple parents via references. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_parent(const void *ptr); + +The talloc_parent() function returns the current talloc parent. This +is usually the pointer under which this memory was originally created, +but it may have changed due to a talloc_steal() or talloc_reparent() + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +size_t talloc_total_size(const void *ptr); + +The talloc_total_size() function returns the total size in bytes used +by this pointer and all child pointers. Mostly useful for debugging. + +Passing NULL is allowed, but it will only give a meaningful result if +talloc_enable_leak_report() or talloc_enable_leak_report_full() has +been called. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +size_t talloc_total_blocks(const void *ptr); + +The talloc_total_blocks() function returns the total memory block +count used by this pointer and all child pointers. Mostly useful for +debugging. + +Passing NULL is allowed, but it will only give a meaningful result if +talloc_enable_leak_report() or talloc_enable_leak_report_full() has +been called. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, + void (*callback)(const void *ptr, + int depth, int max_depth, + int is_ref, + void *priv), + void *priv); + +This provides a more flexible reports than talloc_report(). It +will recursively call the callback for the entire tree of memory +referenced by the pointer. References in the tree are passed with +is_ref = 1 and the pointer that is referenced. + +You can pass NULL for the pointer, in which case a report is +printed for the top level memory context, but only if +talloc_enable_leak_report() or talloc_enable_leak_report_full() +has been called. + +The recursion is stopped when depth >= max_depth. +max_depth = -1 means only stop at leaf nodes. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f); + +This provides a more flexible reports than talloc_report(). It +will let you specify the depth and max_depth. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_report(const void *ptr, FILE *f); + +The talloc_report() function prints a summary report of all memory +used by ptr. One line of report is printed for each immediate child of +ptr, showing the total memory and number of blocks used by that child. + +You can pass NULL for the pointer, in which case a report is printed +for the top level memory context, but only if +talloc_enable_leak_report() or talloc_enable_leak_report_full() has +been called. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_report_full(const void *ptr, FILE *f); + +This provides a more detailed report than talloc_report(). It will +recursively print the entire tree of memory referenced by the +pointer. References in the tree are shown by giving the name of the +pointer that is referenced. + +You can pass NULL for the pointer, in which case a report is printed +for the top level memory context, but only if +talloc_enable_leak_report() or talloc_enable_leak_report_full() has +been called. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_enable_leak_report(void); + +This enables calling of talloc_report(NULL, stderr) when the program +exits. In Samba4 this is enabled by using the --leak-report command +line option. + +For it to be useful, this function must be called before any other +talloc function as it establishes a "null context" that acts as the +top of the tree. If you don't call this function first then passing +NULL to talloc_report() or talloc_report_full() won't give you the +full tree printout. + +Here is a typical talloc report: + +talloc report on 'null_context' (total 267 bytes in 15 blocks) + libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks + libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks + iconv(UTF8,CP850) contains 42 bytes in 2 blocks + libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks + iconv(CP850,UTF8) contains 42 bytes in 2 blocks + iconv(UTF8,UTF-16LE) contains 45 bytes in 2 blocks + iconv(UTF-16LE,UTF8) contains 45 bytes in 2 blocks + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_enable_leak_report_full(void); + +This enables calling of talloc_report_full(NULL, stderr) when the +program exits. In Samba4 this is enabled by using the +--leak-report-full command line option. + +For it to be useful, this function must be called before any other +talloc function as it establishes a "null context" that acts as the +top of the tree. If you don't call this function first then passing +NULL to talloc_report() or talloc_report_full() won't give you the +full tree printout. + +Here is a typical full report: + +full talloc report on 'root' (total 18 bytes in 8 blocks) + p1 contains 18 bytes in 7 blocks (ref 0) + r1 contains 13 bytes in 2 blocks (ref 0) + reference to: p2 + p2 contains 1 bytes in 1 blocks (ref 1) + x3 contains 1 bytes in 1 blocks (ref 0) + x2 contains 1 bytes in 1 blocks (ref 0) + x1 contains 1 bytes in 1 blocks (ref 0) + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_enable_null_tracking(void); + +This enables tracking of the NULL memory context without enabling leak +reporting on exit. Useful for when you want to do your own leak +reporting call via talloc_report_null_full(); + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_disable_null_tracking(void); + +This disables tracking of the NULL memory context. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(type *)talloc_zero(const void *ctx, type); + +The talloc_zero() macro is equivalent to:: + + ptr = talloc(ctx, type); + if (ptr) memset(ptr, 0, sizeof(type)); + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_zero_size(const void *ctx, size_t size) + +The talloc_zero_size() function is useful when you don't have a known type + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_memdup(const void *ctx, const void *p, size_t size); + +The talloc_memdup() function is equivalent to:: + + ptr = talloc_size(ctx, size); + if (ptr) memcpy(ptr, p, size); + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_strdup(const void *ctx, const char *p); + +The talloc_strdup() function is equivalent to:: + + ptr = talloc_size(ctx, strlen(p)+1); + if (ptr) memcpy(ptr, p, strlen(p)+1); + +This functions sets the name of the new pointer to the passed +string. This is equivalent to:: + + talloc_set_name_const(ptr, ptr) + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_strndup(const void *t, const char *p, size_t n); + +The talloc_strndup() function is the talloc equivalent of the C +library function strndup() + +This functions sets the name of the new pointer to the passed +string. This is equivalent to: + talloc_set_name_const(ptr, ptr) + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_append_string(const void *t, char *orig, const char *append); + +The talloc_append_string() function appends the given formatted +string to the given string. + +This function sets the name of the new pointer to the new +string. This is equivalent to:: + + talloc_set_name_const(ptr, ptr) + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_vasprintf(const void *t, const char *fmt, va_list ap); + +The talloc_vasprintf() function is the talloc equivalent of the C +library function vasprintf() + +This functions sets the name of the new pointer to the new +string. This is equivalent to:: + + talloc_set_name_const(ptr, ptr) + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_asprintf(const void *t, const char *fmt, ...); + +The talloc_asprintf() function is the talloc equivalent of the C +library function asprintf() + +This functions sets the name of the new pointer to the new +string. This is equivalent to:: + + talloc_set_name_const(ptr, ptr) + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_asprintf_append(char *s, const char *fmt, ...); + +The talloc_asprintf_append() function appends the given formatted +string to the given string. +Use this variant when the string in the current talloc buffer may +have been truncated in length. + +This functions sets the name of the new pointer to the new +string. This is equivalent to:: + + talloc_set_name_const(ptr, ptr) + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...); + +The talloc_asprintf_append() function appends the given formatted +string to the end of the currently allocated talloc buffer. +Use this variant when the string in the current talloc buffer has +not been changed. + +This functions sets the name of the new pointer to the new +string. This is equivalent to:: + + talloc_set_name_const(ptr, ptr) + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +((type *)talloc_array(const void *ctx, type, unsigned int count); + +The talloc_array() macro is equivalent to:: + + (type *)talloc_size(ctx, sizeof(type) * count); + +except that it provides integer overflow protection for the multiply, +returning NULL if the multiply overflows. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_array_size(const void *ctx, size_t size, unsigned int count); + +The talloc_array_size() function is useful when the type is not +known. It operates in the same way as talloc_array(), but takes a size +instead of a type. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(typeof(ptr)) talloc_array_ptrtype(const void *ctx, ptr, unsigned int count); + +The talloc_ptrtype() macro should be used when you have a pointer to an array +and want to allocate memory of an array to point at with this pointer. When compiling +with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_array_size() +and talloc_get_name() will return the current location in the source file. +and not the type. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_realloc_fn(const void *ctx, void *ptr, size_t size); + +This is a non-macro version of talloc_realloc(), which is useful +as libraries sometimes want a ralloc function pointer. A realloc() +implementation encapsulates the functionality of malloc(), free() and +realloc() in one call, which is why it is useful to be able to pass +around a single function pointer. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_autofree_context(void); + +This is a handy utility function that returns a talloc context +which will be automatically freed on program exit. This can be used +to reduce the noise in memory leak reports. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_check_name(const void *ptr, const char *name); + +This function checks if a pointer has the specified name. If it does +then the pointer is returned. It it doesn't then NULL is returned. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(type *)talloc_get_type(const void *ptr, type); + +This macro allows you to do type checking on talloc pointers. It is +particularly useful for void* private pointers. It is equivalent to +this:: + + (type *)talloc_check_name(ptr, #type) + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +talloc_set_type(const void *ptr, type); + +This macro allows you to force the name of a pointer to be of a +particular type. This can be used in conjunction with +talloc_get_type() to do type checking on void* pointers. + +It is equivalent to this:: + + talloc_set_name_const(ptr, #type) + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +talloc_get_size(const void *ctx); + +This function lets you know the amount of memory allocated so far by +this context. It does NOT account for subcontext memory. +This can be used to calculate the size of an array. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void *talloc_find_parent_byname(const void *ctx, const char *name); + +Find a parent memory context of the current context that has the given +name. This can be very useful in complex programs where it may be +difficult to pass all information down to the level you need, but you +know the structure you want is a parent of another context. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +(type *)talloc_find_parent_bytype(ctx, type); + +Like talloc_find_parent_byname() but takes a type, making it typesafe. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_set_log_fn(void (*log_fn)(const char *message)); + +This function sets a logging function that talloc will use for +warnings and errors. By default talloc will not print any warnings or +errors. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +void talloc_set_log_stderr(void) + +This sets the talloc log function to write log messages to stderr. diff --git a/ldb-2.0.8/lib/talloc/talloc_testsuite.h b/ldb-2.0.8/lib/talloc/talloc_testsuite.h new file mode 100644 index 0000000..acb9701 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/talloc_testsuite.h @@ -0,0 +1,7 @@ +#ifndef __LIB_TALLOC_TALLOC_TESTSUITE_H__ +#define __LIB_TALLOC_TALLOC_TESTSUITE_H__ + +struct torture_context; +bool torture_local_talloc(struct torture_context *tctx); + +#endif diff --git a/ldb-2.0.8/lib/talloc/test_magic_differs.sh b/ldb-2.0.8/lib/talloc/test_magic_differs.sh new file mode 100755 index 0000000..1b6ba2e --- /dev/null +++ b/ldb-2.0.8/lib/talloc/test_magic_differs.sh @@ -0,0 +1,16 @@ +#!/bin/sh +# This test ensures that two different talloc processes do not use the same +# magic value to lessen the opportunity for transferrable attacks. + +echo "test: magic differs" + +helper=$1 +m1=$($helper) +m2=$($helper) + +if [ $m1 -eq $m2 ]; then + echo "failure: magic remained the same between executions ($m1 vs $m2)" + exit 1 +fi + +echo "success: magic differs" diff --git a/ldb-2.0.8/lib/talloc/test_magic_differs_helper.c b/ldb-2.0.8/lib/talloc/test_magic_differs_helper.c new file mode 100644 index 0000000..6798827 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/test_magic_differs_helper.c @@ -0,0 +1,12 @@ +#include +#include "talloc.h" + +/* + * This program is called by a testing shell script in order to ensure that + * if the library is loaded into different processes it uses different magic + * values in order to thwart security attacks. + */ +int main(int argc, char *argv[]) { + printf("%i\n", talloc_test_get_magic()); + return 0; +} diff --git a/ldb-2.0.8/lib/talloc/test_pytalloc.c b/ldb-2.0.8/lib/talloc/test_pytalloc.c new file mode 100644 index 0000000..6797b98 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/test_pytalloc.c @@ -0,0 +1,244 @@ +/* + Samba Unix SMB/CIFS implementation. + + C utilities for the pytalloc test suite. + Provides the "_test_pytalloc" Python module. + + NOTE: Please read talloc_guide.txt for full documentation + + Copyright (C) Petr Viktorin 2015 + + ** NOTE! The following LGPL license applies to the talloc + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include +#include +#include + +static PyObject *testpytalloc_new(PyTypeObject *mod, + PyObject *Py_UNUSED(ignored)) +{ + char *obj = talloc_strdup(NULL, "This is a test string");; + return pytalloc_steal(pytalloc_GetObjectType(), obj); +} + +static PyObject *testpytalloc_get_object_type(PyObject *mod, + PyObject *Py_UNUSED(ignored)) +{ + PyObject *type = (PyObject *)pytalloc_GetObjectType(); + Py_INCREF(type); + return type; +} + +static PyObject *testpytalloc_base_new(PyTypeObject *mod, + PyObject *Py_UNUSED(ignored)) +{ + char *obj = talloc_strdup(NULL, "This is a test string for a BaseObject");; + return pytalloc_steal(pytalloc_GetBaseObjectType(), obj); +} + +static PyObject *testpytalloc_base_get_object_type(PyObject *mod, + PyObject *Py_UNUSED(ignored)) +{ + PyObject *type = (PyObject *)pytalloc_GetBaseObjectType(); + Py_INCREF(type); + return type; +} + +static PyObject *testpytalloc_reference(PyObject *mod, PyObject *args) { + PyObject *source = NULL; + void *ptr; + + if (!PyArg_ParseTuple(args, "O!", pytalloc_GetObjectType(), &source)) + return NULL; + + ptr = pytalloc_get_ptr(source); + return pytalloc_reference_ex(pytalloc_GetObjectType(), ptr, ptr); +} + +static PyObject *testpytalloc_base_reference(PyObject *mod, PyObject *args) { + PyObject *source = NULL; + void *mem_ctx; + + if (!PyArg_ParseTuple(args, "O!", pytalloc_GetBaseObjectType(), &source)) { + return NULL; + } + mem_ctx = pytalloc_get_mem_ctx(source); + return pytalloc_reference_ex(pytalloc_GetBaseObjectType(), mem_ctx, mem_ctx); +} + +static PyMethodDef test_talloc_methods[] = { + { "new", (PyCFunction)testpytalloc_new, METH_NOARGS, + "create a talloc Object with a testing string"}, + { "get_object_type", (PyCFunction)testpytalloc_get_object_type, METH_NOARGS, + "call pytalloc_GetObjectType"}, + { "base_new", (PyCFunction)testpytalloc_base_new, METH_NOARGS, + "create a talloc BaseObject with a testing string"}, + { "base_get_object_type", (PyCFunction)testpytalloc_base_get_object_type, METH_NOARGS, + "call pytalloc_GetBaseObjectType"}, + { "reference", (PyCFunction)testpytalloc_reference, METH_VARARGS, + "call pytalloc_reference_ex"}, + { "base_reference", (PyCFunction)testpytalloc_base_reference, METH_VARARGS, + "call pytalloc_reference_ex"}, + { NULL } +}; + +static PyTypeObject DObject_Type; + +static int dobject_destructor(void *ptr) +{ + PyObject *destructor_func = *talloc_get_type(ptr, PyObject*); + PyObject *ret; + ret = PyObject_CallObject(destructor_func, NULL); + Py_DECREF(destructor_func); + if (ret == NULL) { + PyErr_Print(); + } else { + Py_DECREF(ret); + } + return 0; +} + +static PyObject *dobject_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *destructor_func = NULL; + PyObject **obj; + + if (!PyArg_ParseTuple(args, "O", &destructor_func)) + return NULL; + Py_INCREF(destructor_func); + + obj = talloc(NULL, PyObject*); + *obj = destructor_func; + + talloc_set_destructor((void*)obj, dobject_destructor); + return pytalloc_steal(&DObject_Type, obj); +} + +static PyTypeObject DObject_Type = { + .tp_name = "_test_pytalloc.DObject", + .tp_basicsize = sizeof(pytalloc_Object), + .tp_methods = NULL, + .tp_new = dobject_new, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_doc = "test talloc object that calls a function when underlying data is freed\n", +}; + +static PyTypeObject DBaseObject_Type; + +static int d_base_object_destructor(void *ptr) +{ + PyObject *destructor_func = *talloc_get_type(ptr, PyObject*); + PyObject *ret; + ret = PyObject_CallObject(destructor_func, NULL); + Py_DECREF(destructor_func); + if (ret == NULL) { + PyErr_Print(); + } else { + Py_DECREF(ret); + } + return 0; +} + +static PyObject *d_base_object_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *destructor_func = NULL; + PyObject **obj; + + if (!PyArg_ParseTuple(args, "O", &destructor_func)) + return NULL; + Py_INCREF(destructor_func); + + obj = talloc(NULL, PyObject*); + *obj = destructor_func; + + talloc_set_destructor((void*)obj, d_base_object_destructor); + return pytalloc_steal(&DBaseObject_Type, obj); +} + +static PyTypeObject DBaseObject_Type = { + .tp_name = "_test_pytalloc.DBaseObject", + .tp_methods = NULL, + .tp_new = d_base_object_new, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_doc = "test talloc object that calls a function when underlying data is freed\n", +}; + +#define MODULE_DOC PyDoc_STR("Test utility module for pytalloc") + +#if PY_MAJOR_VERSION >= 3 +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + .m_name = "_test_pytalloc", + .m_doc = PyDoc_STR("Test utility module for pytalloc"), + .m_size = -1, + .m_methods = test_talloc_methods, +}; +#endif + +static PyObject *module_init(void); +static PyObject *module_init(void) +{ + PyObject *m; + + DObject_Type.tp_base = pytalloc_GetObjectType(); + if (PyType_Ready(&DObject_Type) < 0) { + return NULL; + } + + DBaseObject_Type.tp_basicsize = pytalloc_BaseObject_size(); + DBaseObject_Type.tp_base = pytalloc_GetBaseObjectType(); + if (PyType_Ready(&DBaseObject_Type) < 0) { + return NULL; + } + +#if PY_MAJOR_VERSION >= 3 + m = PyModule_Create(&moduledef); +#else + m = Py_InitModule3("_test_pytalloc", test_talloc_methods, MODULE_DOC); +#endif + + if (m == NULL) { + return NULL; + } + + Py_INCREF(&DObject_Type); + Py_INCREF(DObject_Type.tp_base); + PyModule_AddObject(m, "DObject", (PyObject *)&DObject_Type); + + Py_INCREF(&DBaseObject_Type); + Py_INCREF(DBaseObject_Type.tp_base); + PyModule_AddObject(m, "DBaseObject", (PyObject *)&DBaseObject_Type); + + return m; +} + + +#if PY_MAJOR_VERSION >= 3 +PyMODINIT_FUNC PyInit__test_pytalloc(void); +PyMODINIT_FUNC PyInit__test_pytalloc(void) +{ + return module_init(); +} +#else +void init_test_pytalloc(void); +void init_test_pytalloc(void) +{ + module_init(); +} +#endif diff --git a/ldb-2.0.8/lib/talloc/test_pytalloc.py b/ldb-2.0.8/lib/talloc/test_pytalloc.py new file mode 100644 index 0000000..809510f --- /dev/null +++ b/ldb-2.0.8/lib/talloc/test_pytalloc.py @@ -0,0 +1,189 @@ +#!/usr/bin/env python3 +# Simple tests for the talloc python bindings. +# Copyright (C) 2015 Petr Viktorin + +import unittest +import subprocess +import sys +import gc + +import talloc +import _test_pytalloc + + +def dummy_func(): + pass + + +class TallocTests(unittest.TestCase): + + def test_report_full(self): + # report_full is hardcoded to print to stdout, so use a subprocess + process = subprocess.Popen([ + sys.executable, '-c', + """if True: + import talloc, _test_pytalloc + obj = _test_pytalloc.new() + talloc.report_full(obj) + """ + ], stdout=subprocess.PIPE) + output, stderr = process.communicate() + output = str(output) + self.assertTrue("full talloc report on 'talloc.Object" in output) + self.assertTrue("This is a test string" in output) + + def test_totalblocks(self): + obj = _test_pytalloc.new() + # Two blocks: the string, and the name + self.assertEqual(talloc.total_blocks(obj), 2) + + def test_repr(self): + obj = _test_pytalloc.new() + prefix = '= obj1) + self.assertFalse(obj1 > obj1) + + def test_compare_different(self): + # object comparison is consistent + obj1, obj2 = sorted([ + _test_pytalloc.new(), + _test_pytalloc.new()]) + self.assertFalse(obj1 == obj2) + self.assertTrue(obj1 != obj2) + self.assertTrue(obj1 <= obj2) + self.assertTrue(obj1 < obj2) + self.assertFalse(obj1 >= obj2) + self.assertFalse(obj1 > obj2) + + def test_compare_different_types(self): + # object comparison falls back to comparing types + if sys.version_info >= (3, 0): + # In Python 3, types are unorderable -- nothing to test + return + if talloc.Object < _test_pytalloc.DObject: + obj1 = _test_pytalloc.new() + obj2 = _test_pytalloc.DObject(dummy_func) + else: + obj2 = _test_pytalloc.new() + obj1 = _test_pytalloc.DObject(dummy_func) + self.assertFalse(obj1 == obj2) + self.assertTrue(obj1 != obj2) + self.assertTrue(obj1 <= obj2) + self.assertTrue(obj1 < obj2) + self.assertFalse(obj1 >= obj2) + self.assertFalse(obj1 > obj2) + + +class TallocBaseComparisonTests(unittest.TestCase): + + def test_compare_same(self): + obj1 = _test_pytalloc.base_new() + self.assertTrue(obj1 == obj1) + self.assertFalse(obj1 != obj1) + self.assertTrue(obj1 <= obj1) + self.assertFalse(obj1 < obj1) + self.assertTrue(obj1 >= obj1) + self.assertFalse(obj1 > obj1) + + def test_compare_different(self): + # object comparison is consistent + obj1, obj2 = sorted([ + _test_pytalloc.base_new(), + _test_pytalloc.base_new()]) + self.assertFalse(obj1 == obj2) + self.assertTrue(obj1 != obj2) + self.assertTrue(obj1 <= obj2) + self.assertTrue(obj1 < obj2) + self.assertFalse(obj1 >= obj2) + self.assertFalse(obj1 > obj2) + + def test_compare_different_types(self): + # object comparison falls back to comparing types + if sys.version_info >= (3, 0): + # In Python 3, types are unorderable -- nothing to test + return + if talloc.BaseObject < _test_pytalloc.DBaseObject: + obj1 = _test_pytalloc.base_new() + obj2 = _test_pytalloc.DBaseObject(dummy_func) + else: + obj2 = _test_pytalloc.base_new() + obj1 = _test_pytalloc.DBaseObject(dummy_func) + self.assertFalse(obj1 == obj2) + self.assertTrue(obj1 != obj2) + self.assertTrue(obj1 <= obj2) + self.assertTrue(obj1 < obj2) + self.assertFalse(obj1 >= obj2) + self.assertFalse(obj1 > obj2) + + +class TallocUtilTests(unittest.TestCase): + + def test_get_type(self): + self.assertTrue(talloc.Object is _test_pytalloc.get_object_type()) + + def test_reference(self): + # Check correct lifetime of the talloc'd data with multiple references + lst = [] + obj = _test_pytalloc.DObject(lambda: lst.append('dead')) + ref = _test_pytalloc.reference(obj) + del obj + gc.collect() + self.assertEqual(lst, []) + del ref + gc.collect() + self.assertEqual(lst, ['dead']) + + def test_get_base_type(self): + self.assertTrue(talloc.BaseObject is _test_pytalloc.base_get_object_type()) + + def test_base_reference(self): + # Check correct lifetime of the talloc'd data with multiple references + lst = [] + obj = _test_pytalloc.DBaseObject(lambda: lst.append('dead')) + ref = _test_pytalloc.base_reference(obj) + del obj + gc.collect() + self.assertEqual(lst, []) + del ref + gc.collect() + self.assertEqual(lst, ['dead']) + + +if __name__ == '__main__': + unittest.TestProgram() diff --git a/ldb-2.0.8/lib/talloc/testsuite.c b/ldb-2.0.8/lib/talloc/testsuite.c new file mode 100644 index 0000000..a76a647 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/testsuite.c @@ -0,0 +1,2169 @@ +/* + Unix SMB/CIFS implementation. + + local testing of talloc routines. + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the talloc + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#include "system/time.h" +#include + +#ifdef HAVE_PTHREAD +#include +#endif + +#include +#include + +#ifdef NDEBUG +#undef NDEBUG +#endif + +#include + +#include "talloc_testsuite.h" + +static struct timeval private_timeval_current(void) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return tv; +} + +static double private_timeval_elapsed(struct timeval *tv) +{ + struct timeval tv2 = private_timeval_current(); + return (tv2.tv_sec - tv->tv_sec) + + (tv2.tv_usec - tv->tv_usec)*1.0e-6; +} + +#define torture_assert(test, expr, str) if (!(expr)) { \ + printf("failure: %s [\n%s: Expression %s failed: %s\n]\n", \ + test, __location__, #expr, str); \ + return false; \ +} + +#define torture_assert_str_equal(test, arg1, arg2, desc) \ + if (arg1 == NULL && arg2 == NULL) { /* OK, both NULL == equal */ \ + } else if (arg1 == NULL || arg2 == NULL) { \ + return false; \ + } else if (strcmp(arg1, arg2)) { \ + printf("failure: %s [\n%s: Expected %s, got %s: %s\n]\n", \ + test, __location__, arg1, arg2, desc); \ + return false; \ + } + +#define CHECK_SIZE(test, ptr, tsize) do { \ + if (talloc_total_size(ptr) != (tsize)) { \ + printf("failed: %s [\n%s: wrong '%s' tree size: got %u expected %u\n]\n", \ + test, __location__, #ptr, \ + (unsigned)talloc_total_size(ptr), \ + (unsigned)tsize); \ + talloc_report_full(ptr, stdout); \ + return false; \ + } \ +} while (0) + +#define CHECK_BLOCKS(test, ptr, tblocks) do { \ + if (talloc_total_blocks(ptr) != (tblocks)) { \ + printf("failed: %s [\n%s: wrong '%s' tree blocks: got %u expected %u\n]\n", \ + test, __location__, #ptr, \ + (unsigned)talloc_total_blocks(ptr), \ + (unsigned)tblocks); \ + talloc_report_full(ptr, stdout); \ + return false; \ + } \ +} while (0) + +#define CHECK_PARENT(test, ptr, parent) do { \ + if (talloc_parent(ptr) != (parent)) { \ + printf("failed: %s [\n%s: '%s' has wrong parent: got %p expected %p\n]\n", \ + test, __location__, #ptr, \ + talloc_parent(ptr), \ + (parent)); \ + talloc_report_full(ptr, stdout); \ + talloc_report_full(parent, stdout); \ + talloc_report_full(NULL, stdout); \ + return false; \ + } \ +} while (0) + +static unsigned int test_abort_count; + +#if 0 +static void test_abort_fn(const char *reason) +{ + printf("# test_abort_fn(%s)\n", reason); + test_abort_count++; +} + +static void test_abort_start(void) +{ + test_abort_count = 0; + talloc_set_abort_fn(test_abort_fn); +} +#endif + +static void test_abort_stop(void) +{ + test_abort_count = 0; + talloc_set_abort_fn(NULL); +} + +static void test_log_stdout(const char *message) +{ + fprintf(stdout, "%s", message); +} + +/* + test references +*/ +static bool test_ref1(void) +{ + void *root, *p1, *p2, *ref, *r1; + + printf("test: ref1\n# SINGLE REFERENCE FREE\n"); + + root = talloc_named_const(NULL, 0, "root"); + p1 = talloc_named_const(root, 1, "p1"); + p2 = talloc_named_const(p1, 1, "p2"); + talloc_named_const(p1, 1, "x1"); + talloc_named_const(p1, 2, "x2"); + talloc_named_const(p1, 3, "x3"); + + r1 = talloc_named_const(root, 1, "r1"); + ref = talloc_reference(r1, p2); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref1", p1, 5); + CHECK_BLOCKS("ref1", p2, 1); + CHECK_BLOCKS("ref1", ref, 1); + CHECK_BLOCKS("ref1", r1, 2); + + fprintf(stderr, "Freeing p2\n"); + talloc_unlink(r1, p2); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref1", p1, 5); + CHECK_BLOCKS("ref1", p2, 1); + CHECK_BLOCKS("ref1", r1, 1); + + fprintf(stderr, "Freeing p1\n"); + talloc_free(p1); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref1", r1, 1); + + fprintf(stderr, "Freeing r1\n"); + talloc_free(r1); + talloc_report_full(NULL, stderr); + + fprintf(stderr, "Testing NULL\n"); + if (talloc_reference(root, NULL)) { + return false; + } + + CHECK_BLOCKS("ref1", root, 1); + + CHECK_SIZE("ref1", root, 0); + + talloc_free(root); + printf("success: ref1\n"); + return true; +} + +/* + test references +*/ +static bool test_ref2(void) +{ + void *root, *p1, *p2, *ref, *r1; + + printf("test: ref2\n# DOUBLE REFERENCE FREE\n"); + root = talloc_named_const(NULL, 0, "root"); + p1 = talloc_named_const(root, 1, "p1"); + talloc_named_const(p1, 1, "x1"); + talloc_named_const(p1, 1, "x2"); + talloc_named_const(p1, 1, "x3"); + p2 = talloc_named_const(p1, 1, "p2"); + + r1 = talloc_named_const(root, 1, "r1"); + ref = talloc_reference(r1, p2); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref2", p1, 5); + CHECK_BLOCKS("ref2", p2, 1); + CHECK_BLOCKS("ref2", r1, 2); + + fprintf(stderr, "Freeing ref\n"); + talloc_unlink(r1, ref); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref2", p1, 5); + CHECK_BLOCKS("ref2", p2, 1); + CHECK_BLOCKS("ref2", r1, 1); + + fprintf(stderr, "Freeing p2\n"); + talloc_free(p2); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref2", p1, 4); + CHECK_BLOCKS("ref2", r1, 1); + + fprintf(stderr, "Freeing p1\n"); + talloc_free(p1); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref2", r1, 1); + + fprintf(stderr, "Freeing r1\n"); + talloc_free(r1); + talloc_report_full(root, stderr); + + CHECK_SIZE("ref2", root, 0); + + talloc_free(root); + printf("success: ref2\n"); + return true; +} + +/* + test references +*/ +static bool test_ref3(void) +{ + void *root, *p1, *p2, *ref, *r1; + + printf("test: ref3\n# PARENT REFERENCE FREE\n"); + + root = talloc_named_const(NULL, 0, "root"); + p1 = talloc_named_const(root, 1, "p1"); + p2 = talloc_named_const(root, 1, "p2"); + r1 = talloc_named_const(p1, 1, "r1"); + ref = talloc_reference(p2, r1); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref3", p1, 2); + CHECK_BLOCKS("ref3", p2, 2); + CHECK_BLOCKS("ref3", r1, 1); + CHECK_BLOCKS("ref3", ref, 1); + + fprintf(stderr, "Freeing p1\n"); + talloc_free(p1); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref3", p2, 2); + CHECK_BLOCKS("ref3", r1, 1); + + fprintf(stderr, "Freeing p2\n"); + talloc_free(p2); + talloc_report_full(root, stderr); + + CHECK_SIZE("ref3", root, 0); + + talloc_free(root); + + printf("success: ref3\n"); + return true; +} + +/* + test references +*/ +static bool test_ref4(void) +{ + void *root, *p1, *p2, *ref, *r1; + + printf("test: ref4\n# REFERRER REFERENCE FREE\n"); + + root = talloc_named_const(NULL, 0, "root"); + p1 = talloc_named_const(root, 1, "p1"); + talloc_named_const(p1, 1, "x1"); + talloc_named_const(p1, 1, "x2"); + talloc_named_const(p1, 1, "x3"); + p2 = talloc_named_const(p1, 1, "p2"); + + r1 = talloc_named_const(root, 1, "r1"); + ref = talloc_reference(r1, p2); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref4", p1, 5); + CHECK_BLOCKS("ref4", p2, 1); + CHECK_BLOCKS("ref4", ref, 1); + CHECK_BLOCKS("ref4", r1, 2); + + fprintf(stderr, "Freeing r1\n"); + talloc_free(r1); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref4", p1, 5); + CHECK_BLOCKS("ref4", p2, 1); + + fprintf(stderr, "Freeing p2\n"); + talloc_free(p2); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("ref4", p1, 4); + + fprintf(stderr, "Freeing p1\n"); + talloc_free(p1); + talloc_report_full(root, stderr); + + CHECK_SIZE("ref4", root, 0); + + talloc_free(root); + + printf("success: ref4\n"); + return true; +} + + +/* + test references +*/ +static bool test_unlink1(void) +{ + void *root, *p1, *p2, *ref, *r1; + + printf("test: unlink\n# UNLINK\n"); + + root = talloc_named_const(NULL, 0, "root"); + p1 = talloc_named_const(root, 1, "p1"); + talloc_named_const(p1, 1, "x1"); + talloc_named_const(p1, 1, "x2"); + talloc_named_const(p1, 1, "x3"); + p2 = talloc_named_const(p1, 1, "p2"); + + r1 = talloc_named_const(p1, 1, "r1"); + ref = talloc_reference(r1, p2); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("unlink", p1, 7); + CHECK_BLOCKS("unlink", p2, 1); + CHECK_BLOCKS("unlink", ref, 1); + CHECK_BLOCKS("unlink", r1, 2); + + fprintf(stderr, "Unreferencing r1\n"); + talloc_unlink(r1, p2); + talloc_report_full(root, stderr); + + CHECK_BLOCKS("unlink", p1, 6); + CHECK_BLOCKS("unlink", p2, 1); + CHECK_BLOCKS("unlink", r1, 1); + + fprintf(stderr, "Freeing p1\n"); + talloc_free(p1); + talloc_report_full(root, stderr); + + CHECK_SIZE("unlink", root, 0); + + talloc_free(root); + + printf("success: unlink\n"); + return true; +} + +static int fail_destructor(void *ptr) +{ + return -1; +} + +/* + miscellaneous tests to try to get a higher test coverage percentage +*/ +static bool test_misc(void) +{ + void *root, *p1; + char *p2; + double *d; + const char *name; + + printf("test: misc\n# MISCELLANEOUS\n"); + + root = talloc_new(NULL); + + p1 = talloc_size(root, 0x7fffffff); + torture_assert("misc", !p1, "failed: large talloc allowed\n"); + + p1 = talloc_strdup(root, "foo"); + talloc_increase_ref_count(p1); + talloc_increase_ref_count(p1); + talloc_increase_ref_count(p1); + CHECK_BLOCKS("misc", p1, 1); + CHECK_BLOCKS("misc", root, 2); + talloc_unlink(NULL, p1); + CHECK_BLOCKS("misc", p1, 1); + CHECK_BLOCKS("misc", root, 2); + talloc_unlink(NULL, p1); + CHECK_BLOCKS("misc", p1, 1); + CHECK_BLOCKS("misc", root, 2); + p2 = talloc_strdup(p1, "foo"); + torture_assert("misc", talloc_unlink(root, p2) == -1, + "failed: talloc_unlink() of non-reference context should return -1\n"); + torture_assert("misc", talloc_unlink(p1, p2) == 0, + "failed: talloc_unlink() of parent should succeed\n"); + talloc_unlink(NULL, p1); + CHECK_BLOCKS("misc", p1, 1); + CHECK_BLOCKS("misc", root, 2); + + name = talloc_set_name(p1, "my name is %s", "foo"); + torture_assert_str_equal("misc", talloc_get_name(p1), "my name is foo", + "failed: wrong name after talloc_set_name(my name is foo)"); + torture_assert_str_equal("misc", talloc_get_name(p1), name, + "failed: wrong name after talloc_set_name(my name is foo)"); + CHECK_BLOCKS("misc", p1, 2); + CHECK_BLOCKS("misc", root, 3); + + talloc_set_name_const(p1, NULL); + torture_assert_str_equal ("misc", talloc_get_name(p1), "UNNAMED", + "failed: wrong name after talloc_set_name(NULL)"); + CHECK_BLOCKS("misc", p1, 2); + CHECK_BLOCKS("misc", root, 3); + + torture_assert("misc", talloc_free(NULL) == -1, + "talloc_free(NULL) should give -1\n"); + + talloc_set_destructor(p1, fail_destructor); + torture_assert("misc", talloc_free(p1) == -1, + "Failed destructor should cause talloc_free to fail\n"); + talloc_set_destructor(p1, NULL); + + talloc_report(root, stderr); + + + p2 = (char *)talloc_zero_size(p1, 20); + torture_assert("misc", p2[19] == 0, "Failed to give zero memory\n"); + talloc_free(p2); + + torture_assert("misc", talloc_strdup(root, NULL) == NULL, + "failed: strdup on NULL should give NULL\n"); + + p2 = talloc_strndup(p1, "foo", 2); + torture_assert("misc", strcmp("fo", p2) == 0, + "strndup doesn't work\n"); + p2 = talloc_asprintf_append_buffer(p2, "o%c", 'd'); + torture_assert("misc", strcmp("food", p2) == 0, + "talloc_asprintf_append_buffer doesn't work\n"); + CHECK_BLOCKS("misc", p2, 1); + CHECK_BLOCKS("misc", p1, 3); + + p2 = talloc_asprintf_append_buffer(NULL, "hello %s", "world"); + torture_assert("misc", strcmp("hello world", p2) == 0, + "talloc_asprintf_append_buffer doesn't work\n"); + CHECK_BLOCKS("misc", p2, 1); + CHECK_BLOCKS("misc", p1, 3); + talloc_free(p2); + + d = talloc_array(p1, double, 0x20000000); + torture_assert("misc", !d, "failed: integer overflow not detected\n"); + + d = talloc_realloc(p1, d, double, 0x20000000); + torture_assert("misc", !d, "failed: integer overflow not detected\n"); + + talloc_free(p1); + CHECK_BLOCKS("misc", root, 1); + + p1 = talloc_named(root, 100, "%d bytes", 100); + CHECK_BLOCKS("misc", p1, 2); + CHECK_BLOCKS("misc", root, 3); + talloc_unlink(root, p1); + + p1 = talloc_init("%d bytes", 200); + p2 = talloc_asprintf(p1, "my test '%s'", "string"); + torture_assert_str_equal("misc", p2, "my test 'string'", + "failed: talloc_asprintf(\"my test '%%s'\", \"string\") gave: \"%s\""); + CHECK_BLOCKS("misc", p1, 3); + CHECK_SIZE("misc", p2, 17); + CHECK_BLOCKS("misc", root, 1); + talloc_unlink(NULL, p1); + + p1 = talloc_named_const(root, 10, "p1"); + p2 = (char *)talloc_named_const(root, 20, "p2"); + (void)talloc_reference(p1, p2); + talloc_report_full(root, stderr); + talloc_unlink(root, p2); + talloc_report_full(root, stderr); + CHECK_BLOCKS("misc", p2, 1); + CHECK_BLOCKS("misc", p1, 2); + CHECK_BLOCKS("misc", root, 3); + talloc_unlink(p1, p2); + talloc_unlink(root, p1); + + p1 = talloc_named_const(root, 10, "p1"); + p2 = (char *)talloc_named_const(root, 20, "p2"); + (void)talloc_reference(NULL, p2); + talloc_report_full(root, stderr); + talloc_unlink(root, p2); + talloc_report_full(root, stderr); + CHECK_BLOCKS("misc", p2, 1); + CHECK_BLOCKS("misc", p1, 1); + CHECK_BLOCKS("misc", root, 2); + talloc_unlink(NULL, p2); + talloc_unlink(root, p1); + + /* Test that talloc_unlink is a no-op */ + + torture_assert("misc", talloc_unlink(root, NULL) == -1, + "failed: talloc_unlink(root, NULL) == -1\n"); + + talloc_report(root, stderr); + talloc_report(NULL, stderr); + + CHECK_SIZE("misc", root, 0); + + talloc_free(root); + + CHECK_SIZE("misc", NULL, 0); + + talloc_enable_null_tracking_no_autofree(); + talloc_enable_leak_report(); + talloc_enable_leak_report_full(); + + printf("success: misc\n"); + + return true; +} + + +/* + test realloc +*/ +static bool test_realloc(void) +{ + void *root, *p1, *p2; + + printf("test: realloc\n# REALLOC\n"); + + root = talloc_new(NULL); + + p1 = talloc_size(root, 10); + CHECK_SIZE("realloc", p1, 10); + + p1 = talloc_realloc_size(NULL, p1, 20); + CHECK_SIZE("realloc", p1, 20); + + talloc_new(p1); + + p2 = talloc_realloc_size(p1, NULL, 30); + + talloc_new(p1); + + p2 = talloc_realloc_size(p1, p2, 40); + + CHECK_SIZE("realloc", p2, 40); + CHECK_SIZE("realloc", root, 60); + CHECK_BLOCKS("realloc", p1, 4); + + p1 = talloc_realloc_size(NULL, p1, 20); + CHECK_SIZE("realloc", p1, 60); + + talloc_increase_ref_count(p2); + torture_assert("realloc", talloc_realloc_size(NULL, p2, 5) == NULL, + "failed: talloc_realloc() on a referenced pointer should fail\n"); + CHECK_BLOCKS("realloc", p1, 4); + + talloc_realloc_size(NULL, p2, 0); + talloc_realloc_size(NULL, p2, 0); + CHECK_BLOCKS("realloc", p1, 4); + talloc_realloc_size(p1, p2, 0); + CHECK_BLOCKS("realloc", p1, 3); + + torture_assert("realloc", talloc_realloc_size(NULL, p1, 0x7fffffff) == NULL, + "failed: oversize talloc should fail\n"); + + talloc_realloc_size(NULL, p1, 0); + CHECK_BLOCKS("realloc", root, 4); + talloc_realloc_size(root, p1, 0); + CHECK_BLOCKS("realloc", root, 1); + + CHECK_SIZE("realloc", root, 0); + + talloc_free(root); + + printf("success: realloc\n"); + + return true; +} + +/* + test realloc with a child +*/ +static bool test_realloc_child(void) +{ + void *root; + struct el2 { + const char *name; + } *el2, *el2_2, *el2_3, **el_list_save; + struct el1 { + int count; + struct el2 **list, **list2, **list3; + } *el1; + + printf("test: REALLOC WITH CHILD\n"); + + root = talloc_new(NULL); + + el1 = talloc(root, struct el1); + el1->list = talloc(el1, struct el2 *); + el1->list[0] = talloc(el1->list, struct el2); + el1->list[0]->name = talloc_strdup(el1->list[0], "testing"); + + el1->list2 = talloc(el1, struct el2 *); + el1->list2[0] = talloc(el1->list2, struct el2); + el1->list2[0]->name = talloc_strdup(el1->list2[0], "testing2"); + + el1->list3 = talloc(el1, struct el2 *); + el1->list3[0] = talloc(el1->list3, struct el2); + el1->list3[0]->name = talloc_strdup(el1->list3[0], "testing2"); + + el2 = talloc(el1->list, struct el2); + CHECK_PARENT("el2", el2, el1->list); + el2_2 = talloc(el1->list2, struct el2); + CHECK_PARENT("el2", el2_2, el1->list2); + el2_3 = talloc(el1->list3, struct el2); + CHECK_PARENT("el2", el2_3, el1->list3); + + el_list_save = el1->list; + el1->list = talloc_realloc(el1, el1->list, struct el2 *, 100); + if (el1->list == el_list_save) { + printf("failure: talloc_realloc didn't move pointer"); + return false; + } + + CHECK_PARENT("el1_after_realloc", el1->list, el1); + el1->list2 = talloc_realloc(el1, el1->list2, struct el2 *, 200); + CHECK_PARENT("el1_after_realloc", el1->list2, el1); + el1->list3 = talloc_realloc(el1, el1->list3, struct el2 *, 300); + CHECK_PARENT("el1_after_realloc", el1->list3, el1); + + CHECK_PARENT("el2", el2, el1->list); + CHECK_PARENT("el2", el2_2, el1->list2); + CHECK_PARENT("el2", el2_3, el1->list3); + + /* Finally check realloc with multiple children */ + el1 = talloc_realloc(root, el1, struct el1, 100); + CHECK_PARENT("el1->list", el1->list, el1); + CHECK_PARENT("el1->list2", el1->list2, el1); + CHECK_PARENT("el1->list3", el1->list3, el1); + + talloc_free(root); + + printf("success: REALLOC WITH CHILD\n"); + return true; +} + +/* + test type checking +*/ +static bool test_type(void) +{ + void *root; + struct el1 { + int count; + }; + struct el2 { + int count; + }; + struct el1 *el1; + + printf("test: type\n# talloc type checking\n"); + + root = talloc_new(NULL); + + el1 = talloc(root, struct el1); + + el1->count = 1; + + torture_assert("type", talloc_get_type(el1, struct el1) == el1, + "type check failed on el1\n"); + torture_assert("type", talloc_get_type(el1, struct el2) == NULL, + "type check failed on el1 with el2\n"); + talloc_set_type(el1, struct el2); + torture_assert("type", talloc_get_type(el1, struct el2) == (struct el2 *)el1, + "type set failed on el1 with el2\n"); + + talloc_free(root); + + printf("success: type\n"); + return true; +} + +/* + test steal +*/ +static bool test_steal(void) +{ + void *root, *p1, *p2; + + printf("test: steal\n# STEAL\n"); + + root = talloc_new(NULL); + + p1 = talloc_array(root, char, 10); + CHECK_SIZE("steal", p1, 10); + + p2 = talloc_realloc(root, NULL, char, 20); + CHECK_SIZE("steal", p1, 10); + CHECK_SIZE("steal", root, 30); + + torture_assert("steal", talloc_steal(p1, NULL) == NULL, + "failed: stealing NULL should give NULL\n"); + + torture_assert("steal", talloc_steal(p1, p1) == p1, + "failed: stealing to ourselves is a nop\n"); + CHECK_BLOCKS("steal", root, 3); + CHECK_SIZE("steal", root, 30); + + talloc_steal(NULL, p1); + talloc_steal(NULL, p2); + CHECK_BLOCKS("steal", root, 1); + CHECK_SIZE("steal", root, 0); + + talloc_free(p1); + talloc_steal(root, p2); + CHECK_BLOCKS("steal", root, 2); + CHECK_SIZE("steal", root, 20); + + talloc_free(p2); + + CHECK_BLOCKS("steal", root, 1); + CHECK_SIZE("steal", root, 0); + + talloc_free(root); + + p1 = talloc_size(NULL, 3); + talloc_report_full(NULL, stderr); + CHECK_SIZE("steal", NULL, 3); + talloc_free(p1); + + printf("success: steal\n"); + return true; +} + +/* + test move +*/ +static bool test_move(void) +{ + void *root; + struct t_move { + char *p; + int *x; + } *t1, *t2; + + printf("test: move\n# MOVE\n"); + + root = talloc_new(NULL); + + t1 = talloc(root, struct t_move); + t2 = talloc(root, struct t_move); + t1->p = talloc_strdup(t1, "foo"); + t1->x = talloc(t1, int); + *t1->x = 42; + + t2->p = talloc_move(t2, &t1->p); + t2->x = talloc_move(t2, &t1->x); + torture_assert("move", t1->p == NULL && t1->x == NULL && + strcmp(t2->p, "foo") == 0 && *t2->x == 42, + "talloc move failed"); + + talloc_free(root); + + printf("success: move\n"); + + return true; +} + +/* + test talloc_realloc_fn +*/ +static bool test_realloc_fn(void) +{ + void *root, *p1; + + printf("test: realloc_fn\n# talloc_realloc_fn\n"); + + root = talloc_new(NULL); + + p1 = talloc_realloc_fn(root, NULL, 10); + CHECK_BLOCKS("realloc_fn", root, 2); + CHECK_SIZE("realloc_fn", root, 10); + p1 = talloc_realloc_fn(root, p1, 20); + CHECK_BLOCKS("realloc_fn", root, 2); + CHECK_SIZE("realloc_fn", root, 20); + p1 = talloc_realloc_fn(root, p1, 0); + CHECK_BLOCKS("realloc_fn", root, 1); + CHECK_SIZE("realloc_fn", root, 0); + + talloc_free(root); + + printf("success: realloc_fn\n"); + return true; +} + + +static bool test_unref_reparent(void) +{ + void *root, *p1, *p2, *c1; + + printf("test: unref_reparent\n# UNREFERENCE AFTER PARENT FREED\n"); + + root = talloc_named_const(NULL, 0, "root"); + p1 = talloc_named_const(root, 1, "orig parent"); + p2 = talloc_named_const(root, 1, "parent by reference"); + + c1 = talloc_named_const(p1, 1, "child"); + talloc_reference(p2, c1); + + CHECK_PARENT("unref_reparent", c1, p1); + + talloc_free(p1); + + CHECK_PARENT("unref_reparent", c1, p2); + + talloc_unlink(p2, c1); + + CHECK_SIZE("unref_reparent", root, 1); + + talloc_free(p2); + talloc_free(root); + + printf("success: unref_reparent\n"); + return true; +} + +/* + measure the speed of talloc versus malloc +*/ +static bool test_speed(void) +{ + void *ctx = talloc_new(NULL); + unsigned count; + const int loop = 1000; + int i; + struct timeval tv; + + printf("test: speed\n# TALLOC VS MALLOC SPEED\n"); + + tv = private_timeval_current(); + count = 0; + do { + void *p1, *p2, *p3; + for (i=0;ireq2 = talloc_strdup(req1, "req2"); + talloc_set_destructor(req1->req2, test_loop_destructor); + req1->req3 = talloc_strdup(req1, "req3"); + (void)talloc_reference(req1->req3, req1); + talloc_report_full(top, stderr); + talloc_free(parent); + talloc_report_full(top, stderr); + talloc_report_full(NULL, stderr); + talloc_free(top); + + torture_assert("loop", loop_destructor_count == 1, + "FAILED TO FIRE LOOP DESTRUCTOR\n"); + loop_destructor_count = 0; + + printf("success: loop\n"); + return true; +} + +static int realloc_parent_destructor_count; + +static int test_realloc_parent_destructor(char *ptr) +{ + realloc_parent_destructor_count++; + return 0; +} + +static bool test_realloc_on_destructor_parent(void) +{ + void *top = talloc_new(NULL); + char *parent; + char *a, *b, *C, *D; + realloc_parent_destructor_count = 0; + + printf("test: free_for_exit\n# TALLOC FREE FOR EXIT\n"); + + parent = talloc_strdup(top, "parent"); + a = talloc_strdup(parent, "a"); + b = talloc_strdup(a, "b"); + C = talloc_strdup(a, "C"); + D = talloc_strdup(b, "D"); + talloc_set_destructor(D, test_realloc_parent_destructor); + /* Capitalised ones have destructors. + * + * parent --> a -> b -> D + * -> c + */ + + a = talloc_realloc(parent, a, char, 2048); + + torture_assert("check talloc_realloc", a != NULL, "talloc_realloc failed"); + + talloc_set_destructor(C, test_realloc_parent_destructor); + /* + * parent --> a[2048] -> b -> D + * -> C + * + */ + + talloc_free(parent); + + torture_assert("check destructor realloc_parent_destructor", + realloc_parent_destructor_count == 2, + "FAILED TO FIRE free_for_exit_destructor\n"); + + + printf("success: free_for_exit\n"); + return true; +} + +static int fail_destructor_str(char *ptr) +{ + return -1; +} + +static bool test_free_parent_deny_child(void) +{ + void *top = talloc_new(NULL); + char *level1; + char *level2; + char *level3; + + printf("test: free_parent_deny_child\n# TALLOC FREE PARENT DENY CHILD\n"); + + level1 = talloc_strdup(top, "level1"); + level2 = talloc_strdup(level1, "level2"); + level3 = talloc_strdup(level2, "level3"); + + talloc_set_destructor(level3, fail_destructor_str); + talloc_free(level1); + talloc_set_destructor(level3, NULL); + + CHECK_PARENT("free_parent_deny_child", level3, top); + + talloc_free(top); + + printf("success: free_parent_deny_child\n"); + return true; +} + +struct new_parent { + void *new_parent; + char val[20]; +}; + +static int reparenting_destructor(struct new_parent *np) +{ + talloc_set_destructor(np, NULL); + (void)talloc_move(np->new_parent, &np); + return -1; +} + +static bool test_free_parent_reparent_child(void) +{ + void *top = talloc_new(NULL); + char *level1; + char *alternate_level1; + char *level2; + struct new_parent *level3; + + printf("test: free_parent_reparent_child\n# " + "TALLOC FREE PARENT REPARENT CHILD\n"); + + level1 = talloc_strdup(top, "level1"); + alternate_level1 = talloc_strdup(top, "alternate_level1"); + level2 = talloc_strdup(level1, "level2"); + level3 = talloc(level2, struct new_parent); + level3->new_parent = alternate_level1; + memset(level3->val, 'x', sizeof(level3->val)); + + talloc_set_destructor(level3, reparenting_destructor); + talloc_free(level1); + + CHECK_PARENT("free_parent_reparent_child", + level3, alternate_level1); + + talloc_free(top); + + printf("success: free_parent_reparent_child\n"); + return true; +} + +static bool test_free_parent_reparent_child_in_pool(void) +{ + void *top = talloc_new(NULL); + char *level1; + char *alternate_level1; + char *level2; + void *pool; + struct new_parent *level3; + + printf("test: free_parent_reparent_child_in_pool\n# " + "TALLOC FREE PARENT REPARENT CHILD IN POOL\n"); + + pool = talloc_pool(top, 1024); + level1 = talloc_strdup(pool, "level1"); + alternate_level1 = talloc_strdup(top, "alternate_level1"); + level2 = talloc_strdup(level1, "level2"); + level3 = talloc(level2, struct new_parent); + level3->new_parent = alternate_level1; + memset(level3->val, 'x', sizeof(level3->val)); + + talloc_set_destructor(level3, reparenting_destructor); + talloc_free(level1); + talloc_set_destructor(level3, NULL); + + CHECK_PARENT("free_parent_reparent_child_in_pool", + level3, alternate_level1); + + /* Even freeing alternate_level1 should leave pool alone. */ + talloc_free(alternate_level1); + talloc_free(top); + + printf("success: free_parent_reparent_child_in_pool\n"); + return true; +} + + +static bool test_talloc_ptrtype(void) +{ + void *top = talloc_new(NULL); + struct struct1 { + int foo; + int bar; + } *s1, *s2, **s3, ***s4; + const char *location1; + const char *location2; + const char *location3; + const char *location4; + + printf("test: ptrtype\n# TALLOC PTRTYPE\n"); + + s1 = talloc_ptrtype(top, s1);location1 = __location__; + + if (talloc_get_size(s1) != sizeof(struct struct1)) { + printf("failure: ptrtype [\n" + "talloc_ptrtype() allocated the wrong size %lu (should be %lu)\n" + "]\n", (unsigned long)talloc_get_size(s1), + (unsigned long)sizeof(struct struct1)); + return false; + } + + if (strcmp(location1, talloc_get_name(s1)) != 0) { + printf("failure: ptrtype [\n" + "talloc_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n", + talloc_get_name(s1), location1); + return false; + } + + s2 = talloc_array_ptrtype(top, s2, 10);location2 = __location__; + + if (talloc_get_size(s2) != (sizeof(struct struct1) * 10)) { + printf("failure: ptrtype [\n" + "talloc_array_ptrtype() allocated the wrong size " + "%lu (should be %lu)\n]\n", + (unsigned long)talloc_get_size(s2), + (unsigned long)(sizeof(struct struct1)*10)); + return false; + } + + if (strcmp(location2, talloc_get_name(s2)) != 0) { + printf("failure: ptrtype [\n" + "talloc_array_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n", + talloc_get_name(s2), location2); + return false; + } + + s3 = talloc_array_ptrtype(top, s3, 10);location3 = __location__; + + if (talloc_get_size(s3) != (sizeof(struct struct1 *) * 10)) { + printf("failure: ptrtype [\n" + "talloc_array_ptrtype() allocated the wrong size " + "%lu (should be %lu)\n]\n", + (unsigned long)talloc_get_size(s3), + (unsigned long)(sizeof(struct struct1 *)*10)); + return false; + } + + torture_assert_str_equal("ptrtype", location3, talloc_get_name(s3), + "talloc_array_ptrtype() sets the wrong name"); + + s4 = talloc_array_ptrtype(top, s4, 10);location4 = __location__; + + if (talloc_get_size(s4) != (sizeof(struct struct1 **) * 10)) { + printf("failure: ptrtype [\n" + "talloc_array_ptrtype() allocated the wrong size " + "%lu (should be %lu)\n]\n", + (unsigned long)talloc_get_size(s4), + (unsigned long)(sizeof(struct struct1 **)*10)); + return false; + } + + torture_assert_str_equal("ptrtype", location4, talloc_get_name(s4), + "talloc_array_ptrtype() sets the wrong name"); + + talloc_free(top); + + printf("success: ptrtype\n"); + return true; +} + +static int _test_talloc_free_in_destructor(void **ptr) +{ + talloc_free(*ptr); + return 0; +} + +static bool test_talloc_free_in_destructor(void) +{ + void *level0; + void *level1; + void *level2; + void *level3; + void *level4; + void **level5; + + printf("test: free_in_destructor\n# TALLOC FREE IN DESTRUCTOR\n"); + + level0 = talloc_new(NULL); + level1 = talloc_new(level0); + level2 = talloc_new(level1); + level3 = talloc_new(level2); + level4 = talloc_new(level3); + level5 = talloc(level4, void *); + + *level5 = level3; + (void)talloc_reference(level0, level3); + (void)talloc_reference(level3, level3); + (void)talloc_reference(level5, level3); + + talloc_set_destructor(level5, _test_talloc_free_in_destructor); + + talloc_free(level1); + + talloc_free(level0); + + printf("success: free_in_destructor\n"); + return true; +} + +static bool test_autofree(void) +{ +#if _SAMBA_BUILD_ < 4 + /* autofree test would kill smbtorture */ + void *p; + printf("test: autofree\n# TALLOC AUTOFREE CONTEXT\n"); + + p = talloc_autofree_context(); + talloc_free(p); + + p = talloc_autofree_context(); + talloc_free(p); + + printf("success: autofree\n"); +#endif + return true; +} + +static bool test_pool(void) +{ + void *pool; + void *p1, *p2, *p3, *p4; + void *p2_2; + + pool = talloc_pool(NULL, 1024); + + p1 = talloc_size(pool, 80); + memset(p1, 0x11, talloc_get_size(p1)); + p2 = talloc_size(pool, 20); + memset(p2, 0x11, talloc_get_size(p2)); + p3 = talloc_size(p1, 50); + memset(p3, 0x11, talloc_get_size(p3)); + p4 = talloc_size(p3, 1000); + memset(p4, 0x11, talloc_get_size(p4)); + +#if 1 /* this relies on ALWAYS_REALLOC == 0 in talloc.c */ + p2_2 = talloc_realloc_size(pool, p2, 20+1); + torture_assert("pool realloc 20+1", p2_2 == p2, "failed: pointer changed"); + memset(p2, 0x11, talloc_get_size(p2)); + p2_2 = talloc_realloc_size(pool, p2, 20-1); + torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed"); + memset(p2, 0x11, talloc_get_size(p2)); + p2_2 = talloc_realloc_size(pool, p2, 20-1); + torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed"); + memset(p2, 0x11, talloc_get_size(p2)); + + talloc_free(p3); + + /* this should reclaim the memory of p4 and p3 */ + p2_2 = talloc_realloc_size(pool, p2, 400); + torture_assert("pool realloc 400", p2_2 == p2, "failed: pointer changed"); + memset(p2, 0x11, talloc_get_size(p2)); + + talloc_free(p1); + + /* this should reclaim the memory of p1 */ + p2_2 = talloc_realloc_size(pool, p2, 800); + torture_assert("pool realloc 800", p2_2 == p1, "failed: pointer not changed"); + p2 = p2_2; + memset(p2, 0x11, talloc_get_size(p2)); + + /* this should do a malloc */ + p2_2 = talloc_realloc_size(pool, p2, 1800); + torture_assert("pool realloc 1800", p2_2 != p2, "failed: pointer not changed"); + p2 = p2_2; + memset(p2, 0x11, talloc_get_size(p2)); + + /* this should reclaim the memory from the pool */ + p3 = talloc_size(pool, 80); + torture_assert("pool alloc 80", p3 == p1, "failed: pointer changed"); + memset(p3, 0x11, talloc_get_size(p3)); + + talloc_free(p2); + talloc_free(p3); + + p1 = talloc_size(pool, 80); + memset(p1, 0x11, talloc_get_size(p1)); + p2 = talloc_size(pool, 20); + memset(p2, 0x11, talloc_get_size(p2)); + + talloc_free(p1); + + p2_2 = talloc_realloc_size(pool, p2, 20-1); + torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed"); + memset(p2, 0x11, talloc_get_size(p2)); + p2_2 = talloc_realloc_size(pool, p2, 20-1); + torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed"); + memset(p2, 0x11, talloc_get_size(p2)); + + /* this should do a malloc */ + p2_2 = talloc_realloc_size(pool, p2, 1800); + torture_assert("pool realloc 1800", p2_2 != p2, "failed: pointer not changed"); + p2 = p2_2; + memset(p2, 0x11, talloc_get_size(p2)); + + /* this should reclaim the memory from the pool */ + p3 = talloc_size(pool, 800); + torture_assert("pool alloc 800", p3 == p1, "failed: pointer changed"); + memset(p3, 0x11, talloc_get_size(p3)); + +#endif /* this relies on ALWAYS_REALLOC == 0 in talloc.c */ + + talloc_free(pool); + + return true; +} + +static bool test_pool_steal(void) +{ + void *root; + void *pool; + void *p1, *p2; + void *p1_2, *p2_2; + size_t hdr; + size_t ofs1, ofs2; + + root = talloc_new(NULL); + pool = talloc_pool(root, 1024); + + p1 = talloc_size(pool, 4 * 16); + torture_assert("pool allocate 4 * 16", p1 != NULL, "failed "); + memset(p1, 0x11, talloc_get_size(p1)); + p2 = talloc_size(pool, 4 * 16); + torture_assert("pool allocate 4 * 16", p2 > p1, "failed: !(p2 > p1) "); + memset(p2, 0x11, talloc_get_size(p2)); + + ofs1 = PTR_DIFF(p2, p1); + hdr = ofs1 - talloc_get_size(p1); + + talloc_steal(root, p1); + talloc_steal(root, p2); + + talloc_free(pool); + + p1_2 = p1; + +#if 1 /* this relies on ALWAYS_REALLOC == 0 in talloc.c */ + p1_2 = talloc_realloc_size(root, p1, 5 * 16); + torture_assert("pool realloc 5 * 16", p1_2 > p2, "failed: pointer not changed"); + memset(p1_2, 0x11, talloc_get_size(p1_2)); + ofs1 = PTR_DIFF(p1_2, p2); + ofs2 = talloc_get_size(p2) + hdr; + + torture_assert("pool realloc ", ofs1 == ofs2, "failed: pointer offset unexpected"); + + p2_2 = talloc_realloc_size(root, p2, 3 * 16); + torture_assert("pool realloc 5 * 16", p2_2 == p2, "failed: pointer changed"); + memset(p2_2, 0x11, talloc_get_size(p2_2)); +#endif /* this relies on ALWAYS_REALLOC == 0 in talloc.c */ + + talloc_free(p1_2); + + p2_2 = p2; + +#if 1 /* this relies on ALWAYS_REALLOC == 0 in talloc.c */ + /* now we should reclaim the full pool */ + p2_2 = talloc_realloc_size(root, p2, 8 * 16); + torture_assert("pool realloc 8 * 16", p2_2 == p1, "failed: pointer not expected"); + p2 = p2_2; + memset(p2_2, 0x11, talloc_get_size(p2_2)); + + /* now we malloc and free the full pool space */ + p2_2 = talloc_realloc_size(root, p2, 2 * 1024); + torture_assert("pool realloc 2 * 1024", p2_2 != p1, "failed: pointer not expected"); + memset(p2_2, 0x11, talloc_get_size(p2_2)); + +#endif /* this relies on ALWAYS_REALLOC == 0 in talloc.c */ + + talloc_free(p2_2); + + talloc_free(root); + + return true; +} + +static bool test_pool_nest(void) +{ + void *p1, *p2, *p3; + void *e = talloc_new(NULL); + + p1 = talloc_pool(NULL, 1024); + torture_assert("talloc_pool", p1 != NULL, "failed"); + + p2 = talloc_pool(p1, 500); + torture_assert("talloc_pool", p2 != NULL, "failed"); + + p3 = talloc_size(p2, 10); + + talloc_steal(e, p3); + + talloc_free(p2); + + talloc_free(p3); + + talloc_free(p1); + + return true; +} + +struct pooled { + char *s1; + char *s2; + char *s3; +}; + +static bool test_pooled_object(void) +{ + struct pooled *p; + const char *s1 = "hello"; + const char *s2 = "world"; + const char *s3 = ""; + + p = talloc_pooled_object(NULL, struct pooled, 3, + strlen(s1)+strlen(s2)+strlen(s3)+3); + + if (talloc_get_size(p) != sizeof(struct pooled)) { + return false; + } + + p->s1 = talloc_strdup(p, s1); + + TALLOC_FREE(p->s1); + p->s1 = talloc_strdup(p, s2); + TALLOC_FREE(p->s1); + + p->s1 = talloc_strdup(p, s1); + p->s2 = talloc_strdup(p, s2); + p->s3 = talloc_strdup(p, s3); + + TALLOC_FREE(p); + return true; +} + +static bool test_free_ref_null_context(void) +{ + void *p1, *p2, *p3; + int ret; + + talloc_disable_null_tracking(); + p1 = talloc_new(NULL); + p2 = talloc_new(NULL); + + p3 = talloc_reference(p2, p1); + torture_assert("reference", p3 == p1, "failed: reference on null"); + + ret = talloc_free(p1); + torture_assert("ref free with null parent", ret == 0, "failed: free with null parent"); + talloc_free(p2); + + talloc_enable_null_tracking_no_autofree(); + p1 = talloc_new(NULL); + p2 = talloc_new(NULL); + + p3 = talloc_reference(p2, p1); + torture_assert("reference", p3 == p1, "failed: reference on null"); + + ret = talloc_free(p1); + torture_assert("ref free with null tracked parent", ret == 0, "failed: free with null parent"); + talloc_free(p2); + + return true; +} + +static bool test_rusty(void) +{ + void *root; + const char *p1; + + talloc_enable_null_tracking(); + root = talloc_new(NULL); + p1 = talloc_strdup(root, "foo"); + talloc_increase_ref_count(p1); + talloc_report_full(root, stdout); + talloc_free(root); + CHECK_BLOCKS("null_context", NULL, 2); + return true; +} + +static bool test_free_children(void) +{ + void *root; + char *p1, *p2; + const char *name, *name2; + + talloc_enable_null_tracking(); + root = talloc_new(NULL); + p1 = talloc_strdup(root, "foo1"); + p2 = talloc_strdup(p1, "foo2"); + (void)p2; + + talloc_set_name(p1, "%s", "testname"); + talloc_free_children(p1); + /* check its still a valid talloc ptr */ + talloc_get_size(talloc_get_name(p1)); + if (strcmp(talloc_get_name(p1), "testname") != 0) { + return false; + } + + talloc_set_name(p1, "%s", "testname"); + name = talloc_get_name(p1); + talloc_free_children(p1); + /* check its still a valid talloc ptr */ + talloc_get_size(talloc_get_name(p1)); + torture_assert("name", name == talloc_get_name(p1), "name ptr changed"); + torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname") == 0, + "wrong name"); + CHECK_BLOCKS("name1", p1, 2); + + /* note that this does not free the old child name */ + talloc_set_name_const(p1, "testname2"); + name2 = talloc_get_name(p1); + /* but this does */ + talloc_free_children(p1); + (void)name2; + torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname2") == 0, + "wrong name"); + CHECK_BLOCKS("name1", p1, 1); + + talloc_report_full(root, stdout); + talloc_free(root); + return true; +} + +static bool test_memlimit(void) +{ + void *root; + char *l1, *l2, *l3, *l4, *l5, *t; + char *pool; + int i; + + printf("test: memlimit\n# MEMORY LIMITS\n"); + + printf("==== talloc_new(NULL)\n"); + root = talloc_new(NULL); + + talloc_report_full(root, stdout); + + printf("==== talloc_size(root, 2048)\n"); + l1 = talloc_size(root, 2048); + torture_assert("memlimit", l1 != NULL, + "failed: alloc should not fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_free(l1)\n"); + talloc_free(l1); + + talloc_report_full(root, stdout); + + printf("==== talloc_strdup(root, level 1)\n"); + l1 = talloc_strdup(root, "level 1"); + torture_assert("memlimit", l1 != NULL, + "failed: alloc should not fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_set_memlimit(l1, 2048)\n"); + torture_assert("memlimit", talloc_set_memlimit(l1, 2048) == 0, + "failed: setting memlimit should never fail\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_size(root, 2048)\n"); + l2 = talloc_size(l1, 2048); + torture_assert("memlimit", l2 == NULL, + "failed: alloc should fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_strdup(l1, level 2)\n"); + l2 = talloc_strdup(l1, "level 2"); + torture_assert("memlimit", l2 != NULL, + "failed: alloc should not fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_free(l2)\n"); + talloc_free(l2); + + talloc_report_full(root, stdout); + + printf("==== talloc_size(NULL, 2048)\n"); + l2 = talloc_size(NULL, 2048); + + talloc_report_full(root, stdout); + + printf("==== talloc_steal(l1, l2)\n"); + talloc_steal(l1, l2); + + talloc_report_full(root, stdout); + + printf("==== talloc_strdup(l2, level 3)\n"); + l3 = talloc_strdup(l2, "level 3"); + torture_assert("memlimit", l3 == NULL, + "failed: alloc should fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_free(l2)\n"); + talloc_free(l2); + + talloc_report_full(root, stdout); + + printf("==== talloc_strdup(NULL, level 2)\n"); + l2 = talloc_strdup(NULL, "level 2"); + talloc_steal(l1, l2); + + talloc_report_full(root, stdout); + + printf("==== talloc_strdup(l2, level 3)\n"); + l3 = talloc_strdup(l2, "level 3"); + torture_assert("memlimit", l3 != NULL, + "failed: alloc should not fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_set_memlimit(l3, 1024)\n"); + torture_assert("memlimit", talloc_set_memlimit(l3, 1024) == 0, + "failed: setting memlimit should never fail\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_strdup(l3, level 4)\n"); + l4 = talloc_strdup(l3, "level 4"); + torture_assert("memlimit", l4 != NULL, + "failed: alloc should not fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_set_memlimit(l4, 512)\n"); + torture_assert("memlimit", talloc_set_memlimit(l4, 512) == 0, + "failed: setting memlimit should never fail\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_strdup(l4, level 5)\n"); + l5 = talloc_strdup(l4, "level 5"); + torture_assert("memlimit", l5 != NULL, + "failed: alloc should not fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_realloc(NULL, l5, char, 600)\n"); + t = talloc_realloc(NULL, l5, char, 600); + torture_assert("memlimit", t == NULL, + "failed: alloc should fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_realloc(NULL, l5, char, 5)\n"); + l5 = talloc_realloc(NULL, l5, char, 5); + torture_assert("memlimit", l5 != NULL, + "failed: alloc should not fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_strdup(l3, level 4)\n"); + l4 = talloc_strdup(l3, "level 4"); + torture_assert("memlimit", l4 != NULL, + "failed: alloc should not fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_set_memlimit(l4, 512)\n"); + torture_assert("memlimit", talloc_set_memlimit(l4, 512) == 0, + "failed: setting memlimit should never fail\n"); + + talloc_report_full(root, stdout); + + printf("==== talloc_strdup(l4, level 5)\n"); + l5 = talloc_strdup(l4, "level 5"); + torture_assert("memlimit", l5 != NULL, + "failed: alloc should not fail due to memory limit\n"); + + talloc_report_full(root, stdout); + + printf("==== Make new temp context and steal l5\n"); + t = talloc_new(root); + talloc_steal(t, l5); + + talloc_report_full(root, stdout); + + printf("==== talloc_size(t, 2048)\n"); + l1 = talloc_size(t, 2048); + torture_assert("memlimit", l1 != NULL, + "failed: alloc should not fail due to memory limit\n"); + + talloc_report_full(root, stdout); + talloc_free(root); + + /* Test memlimits with pools. */ + pool = talloc_pool(NULL, 10*1024); + torture_assert("memlimit", pool != NULL, + "failed: alloc should not fail due to memory limit\n"); + talloc_set_memlimit(pool, 10*1024); + for (i = 0; i < 9; i++) { + l1 = talloc_size(pool, 1024); + torture_assert("memlimit", l1 != NULL, + "failed: alloc should not fail due to memory limit\n"); + } + /* The next alloc should fail. */ + l2 = talloc_size(pool, 1024); + torture_assert("memlimit", l2 == NULL, + "failed: alloc should fail due to memory limit\n"); + + /* Moving one of the children shouldn't change the limit, + as it's still inside the pool. */ + root = talloc_new(NULL); + talloc_steal(root, l1); + l2 = talloc_size(pool, 1024); + torture_assert("memlimit", l2 == NULL, + "failed: alloc should fail due to memory limit\n"); + + talloc_free(pool); + talloc_free(root); + printf("success: memlimit\n"); + + return true; +} + +#ifdef HAVE_PTHREAD + +#define NUM_THREADS 100 + +/* Sync variables. */ +static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t condvar = PTHREAD_COND_INITIALIZER; +static void *intermediate_ptr; + +/* Subthread. */ +static void *thread_fn(void *arg) +{ + int ret; + const char *ctx_name = (const char *)arg; + void *sub_ctx = NULL; + /* + * Do stuff that creates a new talloc hierarchy in + * this thread. + */ + void *top_ctx = talloc_named_const(NULL, 0, "top"); + if (top_ctx == NULL) { + return NULL; + } + sub_ctx = talloc_named_const(top_ctx, 100, ctx_name); + if (sub_ctx == NULL) { + return NULL; + } + + /* + * Now transfer a pointer from our hierarchy + * onto the intermediate ptr. + */ + ret = pthread_mutex_lock(&mtx); + if (ret != 0) { + talloc_free(top_ctx); + return NULL; + } + /* Wait for intermediate_ptr to be free. */ + while (intermediate_ptr != NULL) { + ret = pthread_cond_wait(&condvar, &mtx); + if (ret != 0) { + talloc_free(top_ctx); + ret = pthread_mutex_unlock(&mtx); + assert(ret == 0); + return NULL; + } + } + + /* and move our memory onto it from our toplevel hierarchy. */ + intermediate_ptr = talloc_move(NULL, &sub_ctx); + + /* Tell the main thread it's ready for pickup. */ + pthread_cond_broadcast(&condvar); + ret = pthread_mutex_unlock(&mtx); + assert(ret == 0); + + talloc_free(top_ctx); + return NULL; +} + +/* Main thread. */ +static bool test_pthread_talloc_passing(void) +{ + int i; + int ret; + char str_array[NUM_THREADS][20]; + pthread_t thread_id; + void *mem_ctx; + + /* + * Important ! Null tracking breaks threaded talloc. + * It *must* be turned off. + */ + talloc_disable_null_tracking(); + + printf("test: pthread_talloc_passing\n# PTHREAD TALLOC PASSING\n"); + + /* Main thread toplevel context. */ + mem_ctx = talloc_named_const(NULL, 0, "toplevel"); + if (mem_ctx == NULL) { + printf("failed to create toplevel context\n"); + return false; + } + + /* + * Spin off NUM_THREADS threads. + * They will use their own toplevel contexts. + */ + for (i = 0; i < NUM_THREADS; i++) { + ret = snprintf(str_array[i], + 20, + "thread:%d", + i); + if (ret < 0) { + printf("snprintf %d failed\n", i); + return false; + } + ret = pthread_create(&thread_id, + NULL, + thread_fn, + str_array[i]); + if (ret != 0) { + printf("failed to create thread %d (%d)\n", i, ret); + return false; + } + } + + printf("Created %d threads\n", NUM_THREADS); + + /* Now wait for NUM_THREADS transfers of the talloc'ed memory. */ + for (i = 0; i < NUM_THREADS; i++) { + ret = pthread_mutex_lock(&mtx); + if (ret != 0) { + printf("pthread_mutex_lock %d failed (%d)\n", i, ret); + talloc_free(mem_ctx); + return false; + } + + /* Wait for intermediate_ptr to have our data. */ + while (intermediate_ptr == NULL) { + ret = pthread_cond_wait(&condvar, &mtx); + if (ret != 0) { + printf("pthread_cond_wait %d failed (%d)\n", i, + ret); + talloc_free(mem_ctx); + ret = pthread_mutex_unlock(&mtx); + assert(ret == 0); + } + } + + /* and move it onto our toplevel hierarchy. */ + (void)talloc_move(mem_ctx, &intermediate_ptr); + + /* Tell the sub-threads we're ready for another. */ + pthread_cond_broadcast(&condvar); + ret = pthread_mutex_unlock(&mtx); + assert(ret == 0); + } + + CHECK_SIZE("pthread_talloc_passing", mem_ctx, NUM_THREADS * 100); +#if 1 + /* Dump the hierarchy. */ + talloc_report(mem_ctx, stdout); +#endif + talloc_free(mem_ctx); + printf("success: pthread_talloc_passing\n"); + return true; +} +#endif + +static void test_magic_protection_abort(const char *reason) +{ + /* exit with errcode 42 to communicate successful test to the parent process */ + if (strcmp(reason, "Bad talloc magic value - unknown value") == 0) { + _exit(42); + } else { + printf("talloc aborted for an unexpected reason\n"); + } +} + +static int test_magic_protection_destructor(int *ptr) +{ + _exit(404); /* Not 42 */ +} + +static bool test_magic_protection(void) +{ + void *pool = talloc_pool(NULL, 1024); + int *p1, *p2; + pid_t pid; + int exit_status; + + printf("test: magic_protection\n"); + p1 = talloc(pool, int); + p2 = talloc(pool, int); + + /* To avoid complaints from the compiler assign values to the p1 & p2. */ + *p1 = 6; + *p2 = 9; + + pid = fork(); + if (pid == 0) { + talloc_set_abort_fn(test_magic_protection_abort); + talloc_set_destructor(p2, test_magic_protection_destructor); + + /* + * Simulate a security attack + * by triggering a buffer overflow in memset to overwrite the + * constructor in the next pool chunk. + * + * Real attacks would attempt to set a real destructor. + */ + memset(p1, '\0', 32); + + /* Then the attack takes effect when the memory's freed. */ + talloc_free(pool); + + /* Never reached. Make compilers happy */ + return true; + } + + while (wait(&exit_status) != pid); + + if (!WIFEXITED(exit_status)) { + printf("Child exited through unexpected abnormal means\n"); + return false; + } + if (WEXITSTATUS(exit_status) != 42) { + printf("Child exited with wrong exit status\n"); + return false; + } + if (WIFSIGNALED(exit_status)) { + printf("Child recieved unexpected signal\n"); + return false; + } + + printf("success: magic_protection\n"); + return true; +} + +static void test_magic_free_protection_abort(const char *reason) +{ + /* exit with errcode 42 to communicate successful test to the parent process */ + if (strcmp(reason, "Bad talloc magic value - access after free") == 0) { + _exit(42); + } + /* not 42 */ + _exit(404); +} + +static bool test_magic_free_protection(void) +{ + void *pool = talloc_pool(NULL, 1024); + int *p1, *p2, *p3; + pid_t pid; + int exit_status; + + printf("test: magic_free_protection\n"); + p1 = talloc(pool, int); + p2 = talloc(pool, int); + + /* To avoid complaints from the compiler assign values to the p1 & p2. */ + *p1 = 6; + *p2 = 9; + + p3 = talloc_realloc(pool, p2, int, 2048); + torture_assert("pool realloc 2048", + p3 != p2, + "failed: pointer not changed"); + + /* + * Now access the memory in the pool after the realloc(). It + * should be marked as free, so use of the old pointer should + * trigger the abort function + */ + pid = fork(); + if (pid == 0) { + talloc_set_abort_fn(test_magic_free_protection_abort); + + talloc_get_name(p2); + + /* Never reached. Make compilers happy */ + return true; + } + + while (wait(&exit_status) != pid); + + if (!WIFEXITED(exit_status)) { + printf("Child exited through unexpected abnormal means\n"); + return false; + } + if (WEXITSTATUS(exit_status) != 42) { + printf("Child exited with wrong exit status\n"); + return false; + } + if (WIFSIGNALED(exit_status)) { + printf("Child recieved unexpected signal\n"); + return false; + } + + talloc_free(pool); + + printf("success: magic_free_protection\n"); + return true; +} + +static void test_reset(void) +{ + talloc_set_log_fn(test_log_stdout); + test_abort_stop(); + talloc_disable_null_tracking(); + talloc_enable_null_tracking_no_autofree(); +} + +bool torture_local_talloc(struct torture_context *tctx) +{ + bool ret = true; + + setlinebuf(stdout); + + test_reset(); + ret &= test_pooled_object(); + test_reset(); + ret &= test_pool_nest(); + test_reset(); + ret &= test_ref1(); + test_reset(); + ret &= test_ref2(); + test_reset(); + ret &= test_ref3(); + test_reset(); + ret &= test_ref4(); + test_reset(); + ret &= test_unlink1(); + test_reset(); + ret &= test_misc(); + test_reset(); + ret &= test_realloc(); + test_reset(); + ret &= test_realloc_child(); + test_reset(); + ret &= test_steal(); + test_reset(); + ret &= test_move(); + test_reset(); + ret &= test_unref_reparent(); + test_reset(); + ret &= test_realloc_fn(); + test_reset(); + ret &= test_type(); + test_reset(); + ret &= test_lifeless(); + test_reset(); + ret &= test_loop(); + test_reset(); + ret &= test_free_parent_deny_child(); + test_reset(); + ret &= test_realloc_on_destructor_parent(); + test_reset(); + ret &= test_free_parent_reparent_child(); + test_reset(); + ret &= test_free_parent_reparent_child_in_pool(); + test_reset(); + ret &= test_talloc_ptrtype(); + test_reset(); + ret &= test_talloc_free_in_destructor(); + test_reset(); + ret &= test_pool(); + test_reset(); + ret &= test_pool_steal(); + test_reset(); + ret &= test_free_ref_null_context(); + test_reset(); + ret &= test_rusty(); + test_reset(); + ret &= test_free_children(); + test_reset(); + ret &= test_memlimit(); +#ifdef HAVE_PTHREAD + test_reset(); + ret &= test_pthread_talloc_passing(); +#endif + + + if (ret) { + test_reset(); + ret &= test_speed(); + } + test_reset(); + ret &= test_autofree(); + test_reset(); + ret &= test_magic_protection(); + test_reset(); + ret &= test_magic_free_protection(); + + test_reset(); + talloc_disable_null_tracking(); + return ret; +} diff --git a/ldb-2.0.8/lib/talloc/testsuite_main.c b/ldb-2.0.8/lib/talloc/testsuite_main.c new file mode 100644 index 0000000..50ce0f8 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/testsuite_main.c @@ -0,0 +1,36 @@ +/* + Unix SMB/CIFS implementation. + + local testing of talloc routines. + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the talloc + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" + +#include "talloc_testsuite.h" + +int main(void) +{ + bool ret = torture_local_talloc(NULL); + if (!ret) + return -1; + return 0; +} diff --git a/ldb-2.0.8/lib/talloc/web/index.html b/ldb-2.0.8/lib/talloc/web/index.html new file mode 100644 index 0000000..388ec2c --- /dev/null +++ b/ldb-2.0.8/lib/talloc/web/index.html @@ -0,0 +1,51 @@ + + + +talloc + + + +

      talloc

      + +talloc is a hierarchical pool based memory allocator with +destructors. It is the core memory allocator used in Samba, and has +made a huge difference in many aspects of Samba4 development.

      + +To get started with talloc, I would recommend you read the talloc guide. + +

      Download

      +You can download the latest releases of talloc from the talloc directory on the samba public +source archive. + +

      Discussion and bug reports

      + +talloc does not currently have its own mailing list or bug tracking +system. For now, please use the samba-technical +mailing list, and the Samba +bugzilla bug tracking system. + +

      Development

      + +You can download the latest code either via git or rsync.
      +
      +To fetch via git see the following guide:
      +Using Git for Samba Development
      +Once you have cloned the tree switch to the master branch and cd into the lib/talloc directory.
      +
      +To fetch via rsync use this command: + +
      +  rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/talloc .
      +
      + +
      + +Andrew Tridgell
      +talloc AT tridgell.net +
      + + + diff --git a/ldb-2.0.8/lib/talloc/wscript b/ldb-2.0.8/lib/talloc/wscript new file mode 100644 index 0000000..eda62d1 --- /dev/null +++ b/ldb-2.0.8/lib/talloc/wscript @@ -0,0 +1,198 @@ +#!/usr/bin/env python + +APPNAME = 'talloc' +VERSION = '2.2.0' + +import os +import sys + +# find the buildtools directory +top = '.' +while not os.path.exists(top+'/buildtools') and len(top.split('/')) < 5: + top = top + '/..' +sys.path.insert(0, top + '/buildtools/wafsamba') + +out = 'bin' + +import wafsamba +from wafsamba import samba_dist, samba_utils +from waflib import Logs, Options, Context + +# setup what directories to put in a tarball +samba_dist.DIST_DIRS("""lib/talloc:. lib/replace:lib/replace +buildtools:buildtools third_party/waf:third_party/waf""") + + +def options(opt): + opt.BUILTIN_DEFAULT('replace') + opt.PRIVATE_EXTENSION_DEFAULT('talloc', noextension='talloc') + opt.RECURSE('lib/replace') + if opt.IN_LAUNCH_DIR(): + opt.add_option('--enable-talloc-compat1', + help=("Build talloc 1.x.x compat library [False]"), + action="store_true", dest='TALLOC_COMPAT1', default=False) + + +def configure(conf): + conf.RECURSE('lib/replace') + + conf.env.standalone_talloc = conf.IN_LAUNCH_DIR() + + conf.define('TALLOC_BUILD_VERSION_MAJOR', int(VERSION.split('.')[0])) + conf.define('TALLOC_BUILD_VERSION_MINOR', int(VERSION.split('.')[1])) + conf.define('TALLOC_BUILD_VERSION_RELEASE', int(VERSION.split('.')[2])) + + conf.env.TALLOC_COMPAT1 = False + if conf.env.standalone_talloc: + conf.env.TALLOC_COMPAT1 = Options.options.TALLOC_COMPAT1 + conf.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig' + conf.env.TALLOC_VERSION = VERSION + + conf.CHECK_XSLTPROC_MANPAGES() + + conf.CHECK_HEADERS('sys/auxv.h') + conf.CHECK_FUNCS('getauxval') + + conf.SAMBA_CONFIG_H() + + conf.SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS() + + conf.SAMBA_CHECK_PYTHON() + conf.SAMBA_CHECK_PYTHON_HEADERS() + + if not conf.env.standalone_talloc: + if conf.CHECK_BUNDLED_SYSTEM_PKG('talloc', minversion=VERSION, + implied_deps='replace'): + conf.define('USING_SYSTEM_TALLOC', 1) + + if conf.env.disable_python: + using_system_pytalloc_util = False + else: + using_system_pytalloc_util = True + name = 'pytalloc-util' + conf.all_envs['default']['PYTHON_SO_ABI_FLAG'] + if not conf.CHECK_BUNDLED_SYSTEM_PKG(name, minversion=VERSION, + implied_deps='talloc replace'): + using_system_pytalloc_util = False + + if using_system_pytalloc_util: + conf.define('USING_SYSTEM_PYTALLOC_UTIL', 1) + + +def build(bld): + bld.RECURSE('lib/replace') + + if bld.env.standalone_talloc: + private_library = False + + # should we also install the symlink to libtalloc1.so here? + bld.SAMBA_LIBRARY('talloc-compat1-%s' % (VERSION), + 'compat/talloc_compat1.c', + public_deps='talloc', + soname='libtalloc.so.1', + pc_files=[], + public_headers=[], + enabled=bld.env.TALLOC_COMPAT1) + + testsuite_deps = 'talloc' + if bld.CONFIG_SET('HAVE_PTHREAD'): + testsuite_deps += ' pthread' + + bld.SAMBA_BINARY('talloc_testsuite', + 'testsuite_main.c testsuite.c', + testsuite_deps, + install=False) + + bld.SAMBA_BINARY('talloc_test_magic_differs_helper', + 'test_magic_differs_helper.c', + 'talloc', install=False) + + else: + private_library = True + + if not bld.CONFIG_SET('USING_SYSTEM_TALLOC'): + + bld.SAMBA_LIBRARY('talloc', + 'talloc.c', + deps='replace', + abi_directory='ABI', + abi_match='talloc* _talloc*', + hide_symbols=True, + vnum=VERSION, + public_headers=('' if private_library else 'talloc.h'), + pc_files='talloc.pc', + public_headers_install=not private_library, + private_library=private_library, + manpages='man/talloc.3') + + if not bld.CONFIG_SET('USING_SYSTEM_PYTALLOC_UTIL'): + name = bld.pyembed_libname('pytalloc-util') + + bld.SAMBA_LIBRARY(name, + source='pytalloc_util.c', + public_deps='talloc', + pyembed=True, + vnum=VERSION, + hide_symbols=True, + abi_directory='ABI', + abi_match='pytalloc_* _pytalloc_*', + private_library=private_library, + public_headers=('' if private_library else 'pytalloc.h'), + pc_files='pytalloc-util.pc', + enabled=bld.PYTHON_BUILD_IS_ENABLED() + ) + bld.SAMBA_PYTHON('pytalloc', + 'pytalloc.c', + deps='talloc ' + name, + enabled=bld.PYTHON_BUILD_IS_ENABLED(), + realname='talloc.so') + + bld.SAMBA_PYTHON('test_pytalloc', + 'test_pytalloc.c', + deps=name, + enabled=bld.PYTHON_BUILD_IS_ENABLED(), + realname='_test_pytalloc.so', + install=False) + + +def testonly(ctx): + '''run talloc testsuite''' + import samba_utils + + samba_utils.ADD_LD_LIBRARY_PATH('bin/shared') + samba_utils.ADD_LD_LIBRARY_PATH('bin/shared/private') + + cmd = os.path.join(Context.g_module.out, 'talloc_testsuite') + ret = samba_utils.RUN_COMMAND(cmd) + print("testsuite returned %d" % ret) + magic_helper_cmd = os.path.join(Context.g_module.out, 'talloc_test_magic_differs_helper') + magic_cmd = os.path.join(Context.g_module.top, 'lib', 'talloc', + 'test_magic_differs.sh') + if not os.path.exists(magic_cmd): + magic_cmd = os.path.join(Context.g_module.top, 'test_magic_differs.sh') + + magic_ret = samba_utils.RUN_COMMAND(magic_cmd + " " + magic_helper_cmd) + print("magic differs test returned %d" % magic_ret) + pyret = samba_utils.RUN_PYTHON_TESTS(['test_pytalloc.py']) + print("python testsuite returned %d" % pyret) + sys.exit(ret or magic_ret or pyret) + +# WAF doesn't build the unit tests for this, maybe because they don't link with talloc? +# This forces it +def test(ctx): + Options.commands.append('build') + Options.commands.append('testonly') + +def dist(): + '''makes a tarball for distribution''' + samba_dist.dist() + +def reconfigure(ctx): + '''reconfigure if config scripts have changed''' + samba_utils.reconfigure(ctx) + + +def pydoctor(ctx): + '''build python apidocs''' + cmd='PYTHONPATH=bin/python pydoctor --project-name=talloc --project-url=http://talloc.samba.org/ --make-html --docformat=restructuredtext --introspect-c-modules --add-module bin/python/talloc.*' + print("Running: %s" % cmd) + os.system(cmd) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.1.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.1.sigs new file mode 100644 index 0000000..84f2007 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.1.sigs @@ -0,0 +1,95 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_alloc_read: unsigned char *(struct tdb_context *, tdb_off_t, tdb_len_t) +tdb_allocate: tdb_off_t (struct tdb_context *, tdb_len_t, struct tdb_record *) +tdb_allrecord_lock: int (struct tdb_context *, int, enum tdb_lock_flags, bool) +tdb_allrecord_unlock: int (struct tdb_context *, int, bool) +tdb_allrecord_upgrade: int (struct tdb_context *) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_brlock: int (struct tdb_context *, int, tdb_off_t, size_t, enum tdb_lock_flags) +tdb_brunlock: int (struct tdb_context *, int, tdb_off_t, size_t) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_convert: void *(void *, uint32_t) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_do_delete: int (struct tdb_context *, tdb_off_t, struct tdb_record *) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_expand: int (struct tdb_context *, tdb_off_t) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_find_lock_hash: tdb_off_t (struct tdb_context *, TDB_DATA, uint32_t, int, struct tdb_record *) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_free: int (struct tdb_context *, tdb_off_t, struct tdb_record *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_have_extra_locks: bool (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_io_init: void (struct tdb_context *) +tdb_lock: int (struct tdb_context *, int, int) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lock_record: int (struct tdb_context *, tdb_off_t) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_mmap: void (struct tdb_context *) +tdb_munmap: int (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_needs_recovery: bool (struct tdb_context *) +tdb_nest_lock: int (struct tdb_context *, uint32_t, int, enum tdb_lock_flags) +tdb_nest_unlock: int (struct tdb_context *, uint32_t, int, bool) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_ofs_read: int (struct tdb_context *, tdb_off_t, tdb_off_t *) +tdb_ofs_write: int (struct tdb_context *, tdb_off_t, tdb_off_t *) +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_data: int (struct tdb_context *, TDB_DATA, tdb_off_t, tdb_len_t, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_rec_free_read: int (struct tdb_context *, tdb_off_t, struct tdb_record *) +tdb_rec_read: int (struct tdb_context *, tdb_off_t, struct tdb_record *) +tdb_rec_write: int (struct tdb_context *, tdb_off_t, struct tdb_record *) +tdb_release_transaction_locks: void (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_lock: int (struct tdb_context *, int, enum tdb_lock_flags) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_recover: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_unlock: int (struct tdb_context *, int) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlock_record: int (struct tdb_context *, tdb_off_t) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) +tdb_write_lock_record: int (struct tdb_context *, tdb_off_t) +tdb_write_unlock_record: int (struct tdb_context *, tdb_off_t) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.10.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.10.sigs new file mode 100644 index 0000000..61f6c19 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.10.sigs @@ -0,0 +1,66 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.11.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.11.sigs new file mode 100644 index 0000000..d727f21 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.11.sigs @@ -0,0 +1,67 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.12.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.12.sigs new file mode 100644 index 0000000..d727f21 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.12.sigs @@ -0,0 +1,67 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.13.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.13.sigs new file mode 100644 index 0000000..d727f21 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.13.sigs @@ -0,0 +1,67 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.2.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.2.sigs new file mode 100644 index 0000000..043790d --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.2.sigs @@ -0,0 +1,60 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.3.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.3.sigs new file mode 100644 index 0000000..043790d --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.3.sigs @@ -0,0 +1,60 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.4.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.4.sigs new file mode 100644 index 0000000..043790d --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.4.sigs @@ -0,0 +1,60 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.5.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.5.sigs new file mode 100644 index 0000000..1e01f3b --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.5.sigs @@ -0,0 +1,61 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.6.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.6.sigs new file mode 100644 index 0000000..1e01f3b --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.6.sigs @@ -0,0 +1,61 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.7.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.7.sigs new file mode 100644 index 0000000..1e01f3b --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.7.sigs @@ -0,0 +1,61 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.8.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.8.sigs new file mode 100644 index 0000000..1e01f3b --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.8.sigs @@ -0,0 +1,61 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.9.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.9.sigs new file mode 100644 index 0000000..9e4149b --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.9.sigs @@ -0,0 +1,62 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.0.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.0.sigs new file mode 100644 index 0000000..7d3e469 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.0.sigs @@ -0,0 +1,68 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.1.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.1.sigs new file mode 100644 index 0000000..7d3e469 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.1.sigs @@ -0,0 +1,68 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.10.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.10.sigs new file mode 100644 index 0000000..2545c99 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.10.sigs @@ -0,0 +1,69 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.11.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.11.sigs new file mode 100644 index 0000000..48f4278 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.11.sigs @@ -0,0 +1,70 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.12.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.12.sigs new file mode 100644 index 0000000..48f4278 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.12.sigs @@ -0,0 +1,70 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.13.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.13.sigs new file mode 100644 index 0000000..48f4278 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.13.sigs @@ -0,0 +1,70 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.14.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.14.sigs new file mode 100644 index 0000000..61ce5e6 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.14.sigs @@ -0,0 +1,71 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_active: bool (struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.15.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.15.sigs new file mode 100644 index 0000000..61ce5e6 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.15.sigs @@ -0,0 +1,71 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_active: bool (struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.16.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.16.sigs new file mode 100644 index 0000000..61ce5e6 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.16.sigs @@ -0,0 +1,71 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_active: bool (struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.17.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.17.sigs new file mode 100644 index 0000000..e2b0427 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.17.sigs @@ -0,0 +1,73 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_active: bool (struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_chain: int (struct tdb_context *, unsigned int, tdb_traverse_func, void *) +tdb_traverse_key_chain: int (struct tdb_context *, TDB_DATA, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.18.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.18.sigs new file mode 100644 index 0000000..e2b0427 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.18.sigs @@ -0,0 +1,73 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_active: bool (struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_chain: int (struct tdb_context *, unsigned int, tdb_traverse_func, void *) +tdb_traverse_key_chain: int (struct tdb_context *, TDB_DATA, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.2.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.2.sigs new file mode 100644 index 0000000..7d3e469 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.2.sigs @@ -0,0 +1,68 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.3.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.3.sigs new file mode 100644 index 0000000..7d3e469 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.3.sigs @@ -0,0 +1,68 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.4.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.4.sigs new file mode 100644 index 0000000..7d3e469 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.4.sigs @@ -0,0 +1,68 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.5.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.5.sigs new file mode 100644 index 0000000..2545c99 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.5.sigs @@ -0,0 +1,69 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.6.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.6.sigs new file mode 100644 index 0000000..2545c99 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.6.sigs @@ -0,0 +1,69 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.7.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.7.sigs new file mode 100644 index 0000000..2545c99 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.7.sigs @@ -0,0 +1,69 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.8.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.8.sigs new file mode 100644 index 0000000..2545c99 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.8.sigs @@ -0,0 +1,69 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.9.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.9.sigs new file mode 100644 index 0000000..2545c99 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.9.sigs @@ -0,0 +1,69 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.4.0.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.4.0.sigs new file mode 100644 index 0000000..e2b0427 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.4.0.sigs @@ -0,0 +1,73 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_active: bool (struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_chain: int (struct tdb_context *, unsigned int, tdb_traverse_func, void *) +tdb_traverse_key_chain: int (struct tdb_context *, TDB_DATA, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.4.1.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.4.1.sigs new file mode 100644 index 0000000..e2b0427 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.4.1.sigs @@ -0,0 +1,73 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_active: bool (struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_chain: int (struct tdb_context *, unsigned int, tdb_traverse_func, void *) +tdb_traverse_key_chain: int (struct tdb_context *, TDB_DATA, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.4.2.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.4.2.sigs new file mode 100644 index 0000000..e2b0427 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/ABI/tdb-1.4.2.sigs @@ -0,0 +1,73 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_active: bool (struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_chain: int (struct tdb_context *, unsigned int, tdb_traverse_func, void *) +tdb_traverse_key_chain: int (struct tdb_context *, TDB_DATA, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/Makefile b/ldb-2.0.8/lib/tdb/Makefile new file mode 100644 index 0000000..8fd56c8 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/Makefile @@ -0,0 +1,68 @@ +# simple makefile wrapper to run waf + +WAF_BIN=`PATH=buildtools/bin:../../buildtools/bin:$$PATH which waf` +WAF_BINARY=$(PYTHON) $(WAF_BIN) +WAF=PYTHONHASHSEED=1 WAF_MAKE=1 $(WAF_BINARY) + +all: + $(WAF) build + +install: + $(WAF) install + +uninstall: + $(WAF) uninstall + +test: FORCE + $(WAF) test $(TEST_OPTIONS) + +testenv: + $(WAF) test --testenv $(TEST_OPTIONS) + +quicktest: + $(WAF) test --quick $(TEST_OPTIONS) + +dist: + touch .tmplock + WAFLOCK=.tmplock $(WAF) dist + +distcheck: + touch .tmplock + WAFLOCK=.tmplock $(WAF) distcheck + +clean: + $(WAF) clean + +distclean: + $(WAF) distclean + +reconfigure: configure + $(WAF) reconfigure + +show_waf_options: + $(WAF) --help + +# some compatibility make targets +everything: all + +testsuite: all + +check: test + +torture: all + +# this should do an install as well, once install is finished +installcheck: test + +etags: + $(WAF) etags + +ctags: + $(WAF) ctags + +pydoctor: + $(WAF) pydoctor + +bin/%:: FORCE + $(WAF) --targets=`basename $@` +FORCE: diff --git a/ldb-2.0.8/lib/tdb/_tdb_text.py b/ldb-2.0.8/lib/tdb/_tdb_text.py new file mode 100644 index 0000000..f3caa53 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/_tdb_text.py @@ -0,0 +1,137 @@ +# Text wrapper for tdb bindings +# +# Copyright (C) 2015 Petr Viktorin +# Published under the GNU LGPLv3 or later + +import sys + +import tdb + + +class TdbTextWrapper(object): + """Text interface for a TDB file""" + + def __init__(self, tdb): + self._tdb = tdb + + @property + def raw(self): + return self._tdb + + def get(self, key): + key = key.encode('utf-8') + result = self._tdb.get(key) + if result is not None: + return result.decode('utf-8') + + def append(self, key, value): + key = key.encode('utf-8') + value = value.encode('utf-8') + self._tdb.append(key, value) + + def firstkey(self): + result = self._tdb.firstkey() + if result: + return result.decode('utf-8') + + def nextkey(self, key): + key = key.encode('utf-8') + result = self._tdb.nextkey(key) + if result is not None: + return result.decode('utf-8') + + def delete(self, key): + key = key.encode('utf-8') + self._tdb.delete(key) + + def store(self, key, value): + key = key.encode('utf-8') + value = value.encode('utf-8') + self._tdb.store(key, value) + + def __iter__(self): + for key in iter(self._tdb): + yield key.decode('utf-8') + + def __getitem__(self, key): + key = key.encode('utf-8') + result = self._tdb[key] + return result.decode('utf-8') + + def __contains__(self, key): + key = key.encode('utf-8') + return key in self._tdb + + def __repr__(self): + return '' % self._tdb + + def __setitem__(self, key, value): + key = key.encode('utf-8') + value = value.encode('utf-8') + self._tdb[key] = value + + def __delitem__(self, key): + key = key.encode('utf-8') + del self._tdb[key] + + if sys.version_info > (3, 0): + keys = __iter__ + else: + iterkeys = __iter__ + has_key = __contains__ + + +## Add wrappers for functions and getters that don't deal with text + +def _add_wrapper(name): + orig = getattr(tdb.Tdb, name) + + def wrapper(self, *args, **kwargs): + return orig(self._tdb, *args, **kwargs) + wrapper.__name__ = orig.__name__ + wrapper.__doc__ = orig.__doc__ + + setattr(TdbTextWrapper, name, wrapper) + +for name in ("transaction_cancel", + "transaction_commit", + "transaction_prepare_commit", + "transaction_start", + "reopen", + "lock_all", + "unlock_all", + "read_lock_all", + "read_unlock_all", + "close", + "add_flags", + "remove_flags", + "clear", + "repack", + "enable_seqnum", + "increment_seqnum_nonblock", + ): + _add_wrapper(name) + + +def _add_getter(name): + orig = getattr(tdb.Tdb, name) + doc = orig.__doc__ + + def getter(self): + return getattr(self._tdb, name) + + def setter(self, value): + return setattr(self._tdb, name, value) + + setattr(TdbTextWrapper, name, property(getter, setter, doc=doc)) + +for name in ("hash_size", + "map_size", + "freelist_size", + "flags", + "max_dead", + "filename", + "seqnum", + "text", + ): + _add_getter(name) diff --git a/ldb-2.0.8/lib/tdb/common/check.c b/ldb-2.0.8/lib/tdb/common/check.c new file mode 100644 index 0000000..d7741f6 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/common/check.c @@ -0,0 +1,489 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Rusty Russell 2009 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ +#include "tdb_private.h" + +/* Since we opened it, these shouldn't fail unless it's recent corruption. */ +static bool tdb_check_header(struct tdb_context *tdb, tdb_off_t *recovery) +{ + struct tdb_header hdr; + uint32_t h1, h2; + + if (tdb->methods->tdb_read(tdb, 0, &hdr, sizeof(hdr), 0) == -1) + return false; + if (strcmp(hdr.magic_food, TDB_MAGIC_FOOD) != 0) + goto corrupt; + + CONVERT(hdr); + if (hdr.version != TDB_VERSION) + goto corrupt; + + if (hdr.rwlocks != 0 && + hdr.rwlocks != TDB_FEATURE_FLAG_MAGIC && + hdr.rwlocks != TDB_HASH_RWLOCK_MAGIC) + goto corrupt; + + tdb_header_hash(tdb, &h1, &h2); + if (hdr.magic1_hash && hdr.magic2_hash && + (hdr.magic1_hash != h1 || hdr.magic2_hash != h2)) + goto corrupt; + + if (hdr.hash_size == 0) + goto corrupt; + + if (hdr.hash_size != tdb->hash_size) + goto corrupt; + + if (hdr.recovery_start != 0 && + hdr.recovery_start < TDB_DATA_START(tdb->hash_size)) + goto corrupt; + + *recovery = hdr.recovery_start; + return true; + +corrupt: + tdb->ecode = TDB_ERR_CORRUPT; + TDB_LOG((tdb, TDB_DEBUG_ERROR, "Header is corrupt\n")); + return false; +} + +/* Generic record header check. */ +static bool tdb_check_record(struct tdb_context *tdb, + tdb_off_t off, + const struct tdb_record *rec) +{ + tdb_off_t tailer; + + /* Check rec->next: 0 or points to record offset, aligned. */ + if (rec->next > 0 && rec->next < TDB_DATA_START(tdb->hash_size)){ + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "Record offset %u too small next %u\n", + off, rec->next)); + goto corrupt; + } + if (rec->next + sizeof(*rec) < rec->next) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "Record offset %u too large next %u\n", + off, rec->next)); + goto corrupt; + } + if ((rec->next % TDB_ALIGNMENT) != 0) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "Record offset %u misaligned next %u\n", + off, rec->next)); + goto corrupt; + } + if (tdb_oob(tdb, rec->next, sizeof(*rec), 0)) + goto corrupt; + + /* Check rec_len: similar to rec->next, implies next record. */ + if ((rec->rec_len % TDB_ALIGNMENT) != 0) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "Record offset %u misaligned length %u\n", + off, rec->rec_len)); + goto corrupt; + } + /* Must fit tailer. */ + if (rec->rec_len < sizeof(tailer)) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "Record offset %u too short length %u\n", + off, rec->rec_len)); + goto corrupt; + } + /* OOB allows "right at the end" access, so this works for last rec. */ + if (tdb_oob(tdb, off, sizeof(*rec)+rec->rec_len, 0)) + goto corrupt; + + /* Check tailer. */ + if (tdb_ofs_read(tdb, off+sizeof(*rec)+rec->rec_len-sizeof(tailer), + &tailer) == -1) + goto corrupt; + if (tailer != sizeof(*rec) + rec->rec_len) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "Record offset %u invalid tailer\n", off)); + goto corrupt; + } + + return true; + +corrupt: + tdb->ecode = TDB_ERR_CORRUPT; + return false; +} + +/* Grab some bytes: may copy if can't use mmap. + Caller has already done bounds check. */ +static TDB_DATA get_bytes(struct tdb_context *tdb, + tdb_off_t off, tdb_len_t len) +{ + TDB_DATA d; + + d.dsize = len; + + if (tdb->transaction == NULL && tdb->map_ptr != NULL) + d.dptr = (unsigned char *)tdb->map_ptr + off; + else + d.dptr = tdb_alloc_read(tdb, off, d.dsize); + return d; +} + +/* Frees data if we're not able to simply use mmap. */ +static void put_bytes(struct tdb_context *tdb, TDB_DATA d) +{ + if (tdb->transaction == NULL && tdb->map_ptr != NULL) + return; + free(d.dptr); +} + +/* We use the excellent Jenkins lookup3 hash; this is based on hash_word2. + * See: http://burtleburtle.net/bob/c/lookup3.c + */ +#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) +static void hash(uint32_t key, uint32_t *pc, uint32_t *pb) +{ + uint32_t a,b,c; + + /* Set up the internal state */ + a = b = c = 0xdeadbeef + *pc; + c += *pb; + a += key; + c ^= b; c -= rot(b,14); + a ^= c; a -= rot(c,11); + b ^= a; b -= rot(a,25); + c ^= b; c -= rot(b,16); + a ^= c; a -= rot(c,4); + b ^= a; b -= rot(a,14); + c ^= b; c -= rot(b,24); + *pc=c; *pb=b; +} + +/* + We want to check that all free records are in the free list + (only once), and all free list entries are free records. Similarly + for each hash chain of used records. + + Doing that naively (without walking hash chains, since we want to be + linear) means keeping a list of records which have been seen in each + hash chain, and another of records pointed to (ie. next pointers + from records and the initial hash chain heads). These two lists + should be equal. This will take 8 bytes per record, and require + sorting at the end. + + So instead, we record each offset in a bitmap such a way that + recording it twice will cancel out. Since each offset should appear + exactly twice, the bitmap should be zero at the end. + + The approach was inspired by Bloom Filters (see Wikipedia). For + each value, we flip K bits in a bitmap of size N. The number of + distinct arrangements is: + + N! / (K! * (N-K)!) + + Of course, not all arrangements are actually distinct, but testing + shows this formula to be close enough. + + So, if K == 8 and N == 256, the probability of two things flipping the same + bits is 1 in 409,663,695,276,000. + + Given that ldb uses a hash size of 10000, using 32 bytes per hash chain + (320k) seems reasonable. +*/ +#define NUM_HASHES 8 +#define BITMAP_BITS 256 + +static void bit_flip(unsigned char bits[], unsigned int idx) +{ + bits[idx / CHAR_BIT] ^= (1 << (idx % CHAR_BIT)); +} + +/* We record offsets in a bitmap for the particular chain it should be in. */ +static void record_offset(unsigned char bits[], tdb_off_t off) +{ + uint32_t h1 = off, h2 = 0; + unsigned int i; + + /* We get two good hash values out of jhash2, so we use both. Then + * we keep going to produce further hash values. */ + for (i = 0; i < NUM_HASHES / 2; i++) { + hash(off, &h1, &h2); + bit_flip(bits, h1 % BITMAP_BITS); + bit_flip(bits, h2 % BITMAP_BITS); + h2++; + } +} + +/* Check that an in-use record is valid. */ +static bool tdb_check_used_record(struct tdb_context *tdb, + tdb_off_t off, + const struct tdb_record *rec, + unsigned char **hashes, + int (*check)(TDB_DATA, TDB_DATA, void *), + void *private_data) +{ + TDB_DATA key, data; + tdb_len_t len; + + if (!tdb_check_record(tdb, off, rec)) + return false; + + /* key + data + tailer must fit in record */ + len = rec->key_len; + len += rec->data_len; + if (len < rec->data_len) { + /* overflow */ + TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record lengths overflow\n")); + return false; + } + len += sizeof(tdb_off_t); + if (len < sizeof(tdb_off_t)) { + /* overflow */ + TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record lengths overflow\n")); + return false; + } + + if (len > rec->rec_len) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "Record offset %u too short for contents\n", off)); + return false; + } + + key = get_bytes(tdb, off + sizeof(*rec), rec->key_len); + if (!key.dptr) + return false; + + if (tdb->hash_fn(&key) != rec->full_hash) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "Record offset %u has incorrect hash\n", off)); + goto fail_put_key; + } + + /* Mark this offset as a known value for this hash bucket. */ + record_offset(hashes[BUCKET(rec->full_hash)+1], off); + /* And similarly if the next pointer is valid. */ + if (rec->next) + record_offset(hashes[BUCKET(rec->full_hash)+1], rec->next); + + /* If they supply a check function and this record isn't dead, + get data and feed it. */ + if (check && rec->magic != TDB_DEAD_MAGIC) { + data = get_bytes(tdb, off + sizeof(*rec) + rec->key_len, + rec->data_len); + if (!data.dptr) + goto fail_put_key; + + if (check(key, data, private_data) == -1) + goto fail_put_data; + put_bytes(tdb, data); + } + + put_bytes(tdb, key); + return true; + +fail_put_data: + put_bytes(tdb, data); +fail_put_key: + put_bytes(tdb, key); + return false; +} + +/* Check that an unused record is valid. */ +static bool tdb_check_free_record(struct tdb_context *tdb, + tdb_off_t off, + const struct tdb_record *rec, + unsigned char **hashes) +{ + if (!tdb_check_record(tdb, off, rec)) + return false; + + /* Mark this offset as a known value for the free list. */ + record_offset(hashes[0], off); + /* And similarly if the next pointer is valid. */ + if (rec->next) + record_offset(hashes[0], rec->next); + return true; +} + +/* Slow, but should be very rare. */ +size_t tdb_dead_space(struct tdb_context *tdb, tdb_off_t off) +{ + size_t len; + + for (len = 0; off + len < tdb->map_size; len++) { + char c; + if (tdb->methods->tdb_read(tdb, off, &c, 1, 0)) + return 0; + if (c != 0 && c != 0x42) + break; + } + return len; +} + +_PUBLIC_ int tdb_check(struct tdb_context *tdb, + int (*check)(TDB_DATA key, TDB_DATA data, void *private_data), + void *private_data) +{ + unsigned int h; + unsigned char **hashes; + tdb_off_t off, recovery_start; + struct tdb_record rec; + bool found_recovery = false; + tdb_len_t dead; + bool locked; + + /* Read-only databases use no locking at all: it's best-effort. + * We may have a write lock already, so skip that case too. */ + if (tdb->read_only || tdb->allrecord_lock.count != 0) { + locked = false; + } else { + if (tdb_lockall_read(tdb) == -1) + return -1; + locked = true; + } + + /* Make sure we know true size of the underlying file. */ + tdb_oob(tdb, tdb->map_size, 1, 1); + + /* Header must be OK: also gets us the recovery ptr, if any. */ + if (!tdb_check_header(tdb, &recovery_start)) + goto unlock; + + /* We should have the whole header, too. */ + if (tdb->map_size < TDB_DATA_START(tdb->hash_size)) { + tdb->ecode = TDB_ERR_CORRUPT; + TDB_LOG((tdb, TDB_DEBUG_ERROR, "File too short for hashes\n")); + goto unlock; + } + + /* One big malloc: pointers then bit arrays. */ + hashes = (unsigned char **)calloc( + 1, sizeof(hashes[0]) * (1+tdb->hash_size) + + BITMAP_BITS / CHAR_BIT * (1+tdb->hash_size)); + if (!hashes) { + tdb->ecode = TDB_ERR_OOM; + goto unlock; + } + + /* Initialize pointers */ + hashes[0] = (unsigned char *)(&hashes[1+tdb->hash_size]); + for (h = 1; h < 1+tdb->hash_size; h++) + hashes[h] = hashes[h-1] + BITMAP_BITS / CHAR_BIT; + + /* Freelist and hash headers are all in a row: read them. */ + for (h = 0; h < 1+tdb->hash_size; h++) { + if (tdb_ofs_read(tdb, FREELIST_TOP + h*sizeof(tdb_off_t), + &off) == -1) + goto free; + if (off) + record_offset(hashes[h], off); + } + + /* For each record, read it in and check it's ok. */ + for (off = TDB_DATA_START(tdb->hash_size); + off < tdb->map_size; + off += sizeof(rec) + rec.rec_len) { + if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), + DOCONV()) == -1) + goto free; + switch (rec.magic) { + case TDB_MAGIC: + case TDB_DEAD_MAGIC: + if (!tdb_check_used_record(tdb, off, &rec, hashes, + check, private_data)) + goto free; + break; + case TDB_FREE_MAGIC: + if (!tdb_check_free_record(tdb, off, &rec, hashes)) + goto free; + break; + /* If we crash after ftruncate, we can get zeroes or fill. */ + case TDB_RECOVERY_INVALID_MAGIC: + case 0x42424242: + if (recovery_start == off) { + found_recovery = true; + break; + } + dead = tdb_dead_space(tdb, off); + if (dead < sizeof(rec)) + goto corrupt; + + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "Dead space at %u-%u (of %u)\n", + off, off + dead, tdb->map_size)); + rec.rec_len = dead - sizeof(rec); + break; + case TDB_RECOVERY_MAGIC: + if (recovery_start != off) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "Unexpected recovery record at offset %u\n", + off)); + goto free; + } + found_recovery = true; + break; + default: ; + corrupt: + tdb->ecode = TDB_ERR_CORRUPT; + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "Bad magic 0x%x at offset %u\n", + rec.magic, off)); + goto free; + } + } + + /* Now, hashes should all be empty: each record exists and is referred + * to by one other. */ + for (h = 0; h < 1+tdb->hash_size; h++) { + unsigned int i; + for (i = 0; i < BITMAP_BITS / CHAR_BIT; i++) { + if (hashes[h][i] != 0) { + tdb->ecode = TDB_ERR_CORRUPT; + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "Hashes do not match records\n")); + goto free; + } + } + } + + /* We must have found recovery area if there was one. */ + if (recovery_start != 0 && !found_recovery) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "Expected a recovery area at %u\n", + recovery_start)); + goto free; + } + + free(hashes); + if (locked) { + tdb_unlockall_read(tdb); + } + return 0; + +free: + free(hashes); +unlock: + if (locked) { + tdb_unlockall_read(tdb); + } + return -1; +} diff --git a/ldb-2.0.8/lib/tdb/common/dump.c b/ldb-2.0.8/lib/tdb/common/dump.c new file mode 100644 index 0000000..adcf591 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/common/dump.c @@ -0,0 +1,149 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2005 + Copyright (C) Paul `Rusty' Russell 2000 + Copyright (C) Jeremy Allison 2000-2003 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "tdb_private.h" + +static tdb_off_t tdb_dump_record(struct tdb_context *tdb, int hash, + tdb_off_t offset) +{ + struct tdb_record rec; + tdb_off_t tailer_ofs, tailer; + + if (tdb->methods->tdb_read(tdb, offset, (char *)&rec, + sizeof(rec), DOCONV()) == -1) { + printf("ERROR: failed to read record at %u\n", offset); + return 0; + } + + printf(" rec: hash=%d offset=0x%08x next=0x%08x rec_len=%u " + "key_len=%u data_len=%u full_hash=0x%08x magic=0x%08x\n", + hash, offset, rec.next, rec.rec_len, rec.key_len, rec.data_len, + rec.full_hash, rec.magic); + + tailer_ofs = offset + sizeof(rec) + rec.rec_len - sizeof(tdb_off_t); + + if (tdb_ofs_read(tdb, tailer_ofs, &tailer) == -1) { + printf("ERROR: failed to read tailer at %u\n", tailer_ofs); + return rec.next; + } + + if (tailer != rec.rec_len + sizeof(rec)) { + printf("ERROR: tailer does not match record! tailer=%u totalsize=%u\n", + (unsigned int)tailer, (unsigned int)(rec.rec_len + sizeof(rec))); + } + return rec.next; +} + +static int tdb_dump_chain(struct tdb_context *tdb, int i) +{ + struct tdb_chainwalk_ctx chainwalk; + tdb_off_t rec_ptr, top; + + if (i == -1) { + top = FREELIST_TOP; + } else { + top = TDB_HASH_TOP(i); + } + + if (tdb_lock(tdb, i, F_WRLCK) != 0) + return -1; + + if (tdb_ofs_read(tdb, top, &rec_ptr) == -1) + return tdb_unlock(tdb, i, F_WRLCK); + + tdb_chainwalk_init(&chainwalk, rec_ptr); + + if (rec_ptr) + printf("hash=%d\n", i); + + while (rec_ptr) { + bool ok; + rec_ptr = tdb_dump_record(tdb, i, rec_ptr); + ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); + if (!ok) { + printf("circular hash chain %d\n", i); + break; + } + } + + return tdb_unlock(tdb, i, F_WRLCK); +} + +_PUBLIC_ void tdb_dump_all(struct tdb_context *tdb) +{ + uint32_t i; + for (i=0;ihash_size;i++) { + tdb_dump_chain(tdb, i); + } + printf("freelist:\n"); + tdb_dump_chain(tdb, -1); +} + +_PUBLIC_ int tdb_printfreelist(struct tdb_context *tdb) +{ + int ret; + long total_free = 0; + tdb_off_t offset, rec_ptr; + struct tdb_record rec; + + if ((ret = tdb_lock(tdb, -1, F_WRLCK)) != 0) + return ret; + + offset = FREELIST_TOP; + + /* read in the freelist top */ + if (tdb_ofs_read(tdb, offset, &rec_ptr) == -1) { + tdb_unlock(tdb, -1, F_WRLCK); + return 0; + } + + printf("freelist top=[0x%08x]\n", rec_ptr ); + while (rec_ptr) { + if (tdb->methods->tdb_read(tdb, rec_ptr, (char *)&rec, + sizeof(rec), DOCONV()) == -1) { + tdb_unlock(tdb, -1, F_WRLCK); + return -1; + } + + if (rec.magic != TDB_FREE_MAGIC) { + printf("bad magic 0x%08x in free list\n", rec.magic); + tdb_unlock(tdb, -1, F_WRLCK); + return -1; + } + + printf("entry offset=[0x%08x], rec.rec_len = [0x%08x (%u)] (end = 0x%08x)\n", + rec_ptr, rec.rec_len, rec.rec_len, rec_ptr + rec.rec_len); + total_free += rec.rec_len; + + /* move to the next record */ + rec_ptr = rec.next; + } + printf("total rec_len = [0x%08lx (%lu)]\n", total_free, total_free); + + return tdb_unlock(tdb, -1, F_WRLCK); +} + diff --git a/ldb-2.0.8/lib/tdb/common/error.c b/ldb-2.0.8/lib/tdb/common/error.c new file mode 100644 index 0000000..478eb88 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/common/error.c @@ -0,0 +1,57 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2005 + Copyright (C) Paul `Rusty' Russell 2000 + Copyright (C) Jeremy Allison 2000-2003 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "tdb_private.h" + +_PUBLIC_ enum TDB_ERROR tdb_error(struct tdb_context *tdb) +{ + return tdb->ecode; +} + +static struct tdb_errname { + enum TDB_ERROR ecode; const char *estring; +} emap[] = { {TDB_SUCCESS, "Success"}, + {TDB_ERR_CORRUPT, "Corrupt database"}, + {TDB_ERR_IO, "IO Error"}, + {TDB_ERR_LOCK, "Locking error"}, + {TDB_ERR_OOM, "Out of memory"}, + {TDB_ERR_EXISTS, "Record exists"}, + {TDB_ERR_NOLOCK, "Lock exists on other keys"}, + {TDB_ERR_EINVAL, "Invalid parameter"}, + {TDB_ERR_NOEXIST, "Record does not exist"}, + {TDB_ERR_RDONLY, "write not permitted"} }; + +/* Error string for the last tdb error */ +_PUBLIC_ const char *tdb_errorstr(struct tdb_context *tdb) +{ + uint32_t i; + for (i = 0; i < sizeof(emap) / sizeof(struct tdb_errname); i++) + if (tdb->ecode == emap[i].ecode) + return emap[i].estring; + return "Invalid error code"; +} + diff --git a/ldb-2.0.8/lib/tdb/common/freelist.c b/ldb-2.0.8/lib/tdb/common/freelist.c new file mode 100644 index 0000000..046c747 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/common/freelist.c @@ -0,0 +1,747 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2005 + Copyright (C) Paul `Rusty' Russell 2000 + Copyright (C) Jeremy Allison 2000-2003 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "tdb_private.h" + +/* read a freelist record and check for simple errors */ +int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, struct tdb_record *rec) +{ + if (tdb->methods->tdb_read(tdb, off, rec, sizeof(*rec),DOCONV()) == -1) + return -1; + + if (rec->magic == TDB_MAGIC) { + /* this happens when a app is showdown while deleting a record - we should + not completely fail when this happens */ + TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read non-free magic 0x%x at offset=%u - fixing\n", + rec->magic, off)); + rec->magic = TDB_FREE_MAGIC; + if (tdb_rec_write(tdb, off, rec) == -1) + return -1; + } + + if (rec->magic != TDB_FREE_MAGIC) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_CORRUPT; + TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read bad magic 0x%x at offset=%u\n", + rec->magic, off)); + return -1; + } + if (tdb_oob(tdb, rec->next, sizeof(*rec), 0) != 0) + return -1; + return 0; +} + +/* update a record tailer (must hold allocation lock) */ +static int update_tailer(struct tdb_context *tdb, tdb_off_t offset, + const struct tdb_record *rec) +{ + tdb_off_t totalsize; + + /* Offset of tailer from record header */ + totalsize = sizeof(*rec) + rec->rec_len; + return tdb_ofs_write(tdb, offset + totalsize - sizeof(tdb_off_t), + &totalsize); +} + +/** + * Read the record directly on the left. + * Fail if there is no record on the left. + */ +static int read_record_on_left(struct tdb_context *tdb, tdb_off_t rec_ptr, + tdb_off_t *left_p, + struct tdb_record *left_r) +{ + tdb_off_t left_ptr; + tdb_off_t left_size; + struct tdb_record left_rec; + int ret; + + left_ptr = rec_ptr - sizeof(tdb_off_t); + + if (left_ptr <= TDB_DATA_START(tdb->hash_size)) { + /* no record on the left */ + return -1; + } + + /* Read in tailer and jump back to header */ + ret = tdb_ofs_read(tdb, left_ptr, &left_size); + if (ret == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, + "tdb_free: left offset read failed at %u\n", left_ptr)); + return -1; + } + + /* it could be uninitialised data */ + if (left_size == 0 || left_size == TDB_PAD_U32) { + return -1; + } + + if (left_size > rec_ptr) { + return -1; + } + + left_ptr = rec_ptr - left_size; + + if (left_ptr < TDB_DATA_START(tdb->hash_size)) { + return -1; + } + + /* Now read in the left record */ + ret = tdb->methods->tdb_read(tdb, left_ptr, &left_rec, + sizeof(left_rec), DOCONV()); + if (ret == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, + "tdb_free: left read failed at %u (%u)\n", + left_ptr, left_size)); + return -1; + } + + *left_p = left_ptr; + *left_r = left_rec; + + return 0; +} + +/** + * Merge new freelist record with the direct left neighbour. + * This assumes that left_rec represents the record + * directly to the left of right_rec and that this is + * a freelist record. + */ +static int merge_with_left_record(struct tdb_context *tdb, + tdb_off_t left_ptr, + struct tdb_record *left_rec, + struct tdb_record *right_rec) +{ + int ret; + + left_rec->rec_len += sizeof(*right_rec) + right_rec->rec_len; + + ret = tdb_rec_write(tdb, left_ptr, left_rec); + if (ret == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, + "merge_with_left_record: update_left failed at %u\n", + left_ptr)); + return -1; + } + + ret = update_tailer(tdb, left_ptr, left_rec); + if (ret == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, + "merge_with_left_record: update_tailer failed at %u\n", + left_ptr)); + return -1; + } + + return 0; +} + +/** + * Check whether the record left of a given freelist record is + * also a freelist record, and if so, merge the two records. + * + * Return code: + * -1 upon error + * 0 if left was not a free record + * 1 if left was free and successfully merged. + * + * The current record is handed in with pointer and fully read record. + * + * The left record pointer and struct can be retrieved as result + * in lp and lr; + */ +static int check_merge_with_left_record(struct tdb_context *tdb, + tdb_off_t rec_ptr, + struct tdb_record *rec, + tdb_off_t *lp, + struct tdb_record *lr) +{ + tdb_off_t left_ptr; + struct tdb_record left_rec; + int ret; + + ret = read_record_on_left(tdb, rec_ptr, &left_ptr, &left_rec); + if (ret != 0) { + return 0; + } + + if (left_rec.magic != TDB_FREE_MAGIC) { + return 0; + } + + /* It's free - expand to include it. */ + ret = merge_with_left_record(tdb, left_ptr, &left_rec, rec); + if (ret != 0) { + return -1; + } + + if (lp != NULL) { + *lp = left_ptr; + } + + if (lr != NULL) { + *lr = left_rec; + } + + return 1; +} + +/** + * Check whether the record left of a given freelist record is + * also a freelist record, and if so, merge the two records. + * + * Return code: + * -1 upon error + * 0 if left was not a free record + * 1 if left was free and successfully merged. + * + * In this variant, the input record is specified just as the pointer + * and is read from the database if needed. + * + * next_ptr will contain the original record's next pointer after + * successful merging (which will be lost after merging), so that + * the caller can update the last pointer. + */ +static int check_merge_ptr_with_left_record(struct tdb_context *tdb, + tdb_off_t rec_ptr, + tdb_off_t *next_ptr) +{ + tdb_off_t left_ptr; + struct tdb_record rec, left_rec; + int ret; + + ret = read_record_on_left(tdb, rec_ptr, &left_ptr, &left_rec); + if (ret != 0) { + return 0; + } + + if (left_rec.magic != TDB_FREE_MAGIC) { + return 0; + } + + /* It's free - expand to include it. */ + + ret = tdb->methods->tdb_read(tdb, rec_ptr, &rec, + sizeof(rec), DOCONV()); + if (ret != 0) { + return -1; + } + + ret = merge_with_left_record(tdb, left_ptr, &left_rec, &rec); + if (ret != 0) { + return -1; + } + + if (next_ptr != NULL) { + *next_ptr = rec.next; + } + + return 1; +} + +/** + * Add an element into the freelist. + * + * We merge the new record into the left record if it is also a + * free record, but not with the right one. This makes the + * operation O(1) instead of O(n): merging with the right record + * requires a traverse of the freelist to find the previous + * record in the free list. + * + * This prevents db traverses from being O(n^2) after a lot of deletes. + */ +int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec) +{ + int ret; + + /* Allocation and tailer lock */ + if (tdb_lock(tdb, -1, F_WRLCK) != 0) + return -1; + + /* set an initial tailer, so if we fail we don't leave a bogus record */ + if (update_tailer(tdb, offset, rec) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed!\n")); + goto fail; + } + + ret = check_merge_with_left_record(tdb, offset, rec, NULL, NULL); + if (ret == -1) { + goto fail; + } + if (ret == 1) { + /* merged */ + goto done; + } + + /* Nothing to merge, prepend to free list */ + + rec->magic = TDB_FREE_MAGIC; + + if (tdb_ofs_read(tdb, FREELIST_TOP, &rec->next) == -1 || + tdb_rec_write(tdb, offset, rec) == -1 || + tdb_ofs_write(tdb, FREELIST_TOP, &offset) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free record write failed at offset=%u\n", offset)); + goto fail; + } + +done: + /* And we're done. */ + tdb_unlock(tdb, -1, F_WRLCK); + return 0; + + fail: + tdb_unlock(tdb, -1, F_WRLCK); + return -1; +} + + + +/* + the core of tdb_allocate - called when we have decided which + free list entry to use + + Note that we try to allocate by grabbing data from the end of an existing record, + not the beginning. This is so the left merge in a free is more likely to be + able to free up the record without fragmentation + */ +static tdb_off_t tdb_allocate_ofs(struct tdb_context *tdb, + tdb_len_t length, tdb_off_t rec_ptr, + struct tdb_record *rec, tdb_off_t last_ptr) +{ +#define MIN_REC_SIZE (sizeof(struct tdb_record) + sizeof(tdb_off_t) + 8) + + if (rec->rec_len < length + MIN_REC_SIZE) { + /* we have to grab the whole record */ + + /* unlink it from the previous record */ + if (tdb_ofs_write(tdb, last_ptr, &rec->next) == -1) { + return 0; + } + + /* mark it not free */ + rec->magic = TDB_MAGIC; + if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { + return 0; + } + return rec_ptr; + } + + /* we're going to just shorten the existing record */ + rec->rec_len -= (length + sizeof(*rec)); + if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { + return 0; + } + if (update_tailer(tdb, rec_ptr, rec) == -1) { + return 0; + } + + /* and setup the new record */ + rec_ptr += sizeof(*rec) + rec->rec_len; + + memset(rec, '\0', sizeof(*rec)); + rec->rec_len = length; + rec->magic = TDB_MAGIC; + + if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { + return 0; + } + + if (update_tailer(tdb, rec_ptr, rec) == -1) { + return 0; + } + + return rec_ptr; +} + +/* allocate some space from the free list. The offset returned points + to a unconnected tdb_record within the database with room for at + least length bytes of total data + + 0 is returned if the space could not be allocated + */ +static tdb_off_t tdb_allocate_from_freelist( + struct tdb_context *tdb, tdb_len_t length, struct tdb_record *rec) +{ + tdb_off_t rec_ptr, last_ptr, newrec_ptr; + struct tdb_chainwalk_ctx chainwalk; + bool modified; + struct { + tdb_off_t rec_ptr, last_ptr; + tdb_len_t rec_len; + } bestfit; + float multiplier = 1.0; + bool merge_created_candidate; + + /* over-allocate to reduce fragmentation */ + length *= 1.25; + + /* Extra bytes required for tailer */ + length += sizeof(tdb_off_t); + length = TDB_ALIGN(length, TDB_ALIGNMENT); + + again: + merge_created_candidate = false; + last_ptr = FREELIST_TOP; + + /* read in the freelist top */ + if (tdb_ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) + return 0; + + modified = false; + tdb_chainwalk_init(&chainwalk, rec_ptr); + + bestfit.rec_ptr = 0; + bestfit.last_ptr = 0; + bestfit.rec_len = 0; + + /* + this is a best fit allocation strategy. Originally we used + a first fit strategy, but it suffered from massive fragmentation + issues when faced with a slowly increasing record size. + */ + while (rec_ptr) { + int ret; + tdb_off_t left_ptr; + struct tdb_record left_rec; + + if (tdb_rec_free_read(tdb, rec_ptr, rec) == -1) { + return 0; + } + + ret = check_merge_with_left_record(tdb, rec_ptr, rec, + &left_ptr, &left_rec); + if (ret == -1) { + return 0; + } + if (ret == 1) { + /* merged */ + rec_ptr = rec->next; + ret = tdb_ofs_write(tdb, last_ptr, &rec->next); + if (ret == -1) { + return 0; + } + + /* + * We have merged the current record into the left + * neighbour. So our traverse of the freelist will + * skip it and consider the next record in the chain. + * + * But the enlarged left neighbour may be a candidate. + * If it is, we can not directly use it, though. + * The only thing we can do and have to do here is to + * update the current best fit size in the chain if the + * current best fit is the left record. (By that we may + * worsen the best fit we already had, bit this is not a + * problem.) + * + * If the current best fit is not the left record, + * all we can do is remember the fact that a merge + * created a new candidate so that we can trigger + * a second walk of the freelist if at the end of + * the first walk we have not found any fit. + * This way we can avoid expanding the database. + */ + + if (bestfit.rec_ptr == left_ptr) { + bestfit.rec_len = left_rec.rec_len; + } + + if (left_rec.rec_len > length) { + merge_created_candidate = true; + } + + modified = true; + + continue; + } + + if (rec->rec_len >= length) { + if (bestfit.rec_ptr == 0 || + rec->rec_len < bestfit.rec_len) { + bestfit.rec_len = rec->rec_len; + bestfit.rec_ptr = rec_ptr; + bestfit.last_ptr = last_ptr; + } + } + + /* move to the next record */ + last_ptr = rec_ptr; + rec_ptr = rec->next; + + if (!modified) { + bool ok; + ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); + if (!ok) { + return 0; + } + } + + /* if we've found a record that is big enough, then + stop searching if its also not too big. The + definition of 'too big' changes as we scan + through */ + if (bestfit.rec_len > 0 && + bestfit.rec_len < length * multiplier) { + break; + } + + /* this multiplier means we only extremely rarely + search more than 50 or so records. At 50 records we + accept records up to 11 times larger than what we + want */ + multiplier *= 1.05; + } + + if (bestfit.rec_ptr != 0) { + if (tdb_rec_free_read(tdb, bestfit.rec_ptr, rec) == -1) { + return 0; + } + + newrec_ptr = tdb_allocate_ofs(tdb, length, bestfit.rec_ptr, + rec, bestfit.last_ptr); + return newrec_ptr; + } + + if (merge_created_candidate) { + goto again; + } + + /* we didn't find enough space. See if we can expand the + database and if we can then try again */ + if (tdb_expand(tdb, length + sizeof(*rec)) == 0) + goto again; + + return 0; +} + +static bool tdb_alloc_dead( + struct tdb_context *tdb, int hash, tdb_len_t length, + tdb_off_t *rec_ptr, struct tdb_record *rec) +{ + tdb_off_t last_ptr; + + *rec_ptr = tdb_find_dead(tdb, hash, rec, length, &last_ptr); + if (*rec_ptr == 0) { + return false; + } + /* + * Unlink the record from the hash chain, it's about to be moved into + * another one. + */ + return (tdb_ofs_write(tdb, last_ptr, &rec->next) == 0); +} + +static void tdb_purge_dead(struct tdb_context *tdb, uint32_t hash) +{ + int max_dead_records = tdb->max_dead_records; + + tdb->max_dead_records = 0; + + tdb_trim_dead(tdb, hash); + + tdb->max_dead_records = max_dead_records; +} + +/* + * Chain "hash" is assumed to be locked + */ + +tdb_off_t tdb_allocate(struct tdb_context *tdb, int hash, tdb_len_t length, + struct tdb_record *rec) +{ + tdb_off_t ret; + uint32_t i; + + if (tdb->max_dead_records == 0) { + /* + * No dead records to expect anywhere. Do the blocking + * freelist lock without trying to steal from others + */ + goto blocking_freelist_allocate; + } + + /* + * The following loop tries to get the freelist lock nonblocking. If + * it gets the lock, allocate from there. If the freelist is busy, + * instead of waiting we try to steal dead records from other hash + * chains. + * + * Be aware that we do nonblocking locks on the other hash chains as + * well and fail gracefully. This way we avoid deadlocks (we block two + * hash chains, something which is pretty bad normally) + */ + + for (i=0; ihash_size; i++) { + + int list; + + list = BUCKET(hash+i); + + if (tdb_lock_nonblock(tdb, list, F_WRLCK) == 0) { + bool got_dead; + + got_dead = tdb_alloc_dead(tdb, list, length, &ret, rec); + tdb_unlock(tdb, list, F_WRLCK); + + if (got_dead) { + return ret; + } + } + + if (tdb_lock_nonblock(tdb, -1, F_WRLCK) == 0) { + /* + * Under the freelist lock take the chance to give + * back our dead records. + */ + tdb_purge_dead(tdb, hash); + + ret = tdb_allocate_from_freelist(tdb, length, rec); + tdb_unlock(tdb, -1, F_WRLCK); + return ret; + } + } + +blocking_freelist_allocate: + + if (tdb_lock(tdb, -1, F_WRLCK) == -1) { + return 0; + } + /* + * Dead records can happen even if max_dead_records==0, they + * are older than the max_dead_records concept: They happen if + * tdb_delete happens concurrently with a traverse. + */ + tdb_purge_dead(tdb, hash); + ret = tdb_allocate_from_freelist(tdb, length, rec); + tdb_unlock(tdb, -1, F_WRLCK); + return ret; +} + +/** + * Merge adjacent records in the freelist. + */ +static int tdb_freelist_merge_adjacent(struct tdb_context *tdb, + int *count_records, int *count_merged) +{ + tdb_off_t cur, next; + int count = 0; + int merged = 0; + int ret; + + ret = tdb_lock(tdb, -1, F_RDLCK); + if (ret == -1) { + return -1; + } + + cur = FREELIST_TOP; + while (tdb_ofs_read(tdb, cur, &next) == 0 && next != 0) { + tdb_off_t next2; + + count++; + + ret = check_merge_ptr_with_left_record(tdb, next, &next2); + if (ret == -1) { + goto done; + } + if (ret == 1) { + /* + * merged: + * now let cur->next point to next2 instead of next + */ + + ret = tdb_ofs_write(tdb, cur, &next2); + if (ret != 0) { + goto done; + } + + next = next2; + merged++; + } + + cur = next; + } + + if (count_records != NULL) { + *count_records = count; + } + + if (count_merged != NULL) { + *count_merged = merged; + } + + ret = 0; + +done: + tdb_unlock(tdb, -1, F_RDLCK); + return ret; +} + +/** + * return the size of the freelist - no merging done + */ +static int tdb_freelist_size_no_merge(struct tdb_context *tdb) +{ + tdb_off_t ptr; + int count=0; + + if (tdb_lock(tdb, -1, F_RDLCK) == -1) { + return -1; + } + + ptr = FREELIST_TOP; + while (tdb_ofs_read(tdb, ptr, &ptr) == 0 && ptr != 0) { + count++; + } + + tdb_unlock(tdb, -1, F_RDLCK); + return count; +} + +/** + * return the size of the freelist - used to decide if we should repack + * + * As a side effect, adjacent records are merged unless the + * database is read-only, in order to reduce the fragmentation + * without repacking. + */ +_PUBLIC_ int tdb_freelist_size(struct tdb_context *tdb) +{ + + int count = 0; + + if (tdb->read_only) { + count = tdb_freelist_size_no_merge(tdb); + } else { + int ret; + ret = tdb_freelist_merge_adjacent(tdb, &count, NULL); + if (ret != 0) { + return -1; + } + } + + return count; +} diff --git a/ldb-2.0.8/lib/tdb/common/freelistcheck.c b/ldb-2.0.8/lib/tdb/common/freelistcheck.c new file mode 100644 index 0000000..2f1e6eb --- /dev/null +++ b/ldb-2.0.8/lib/tdb/common/freelistcheck.c @@ -0,0 +1,107 @@ +/* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Jeremy Allison 2006 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "tdb_private.h" + +/* Check the freelist is good and contains no loops. + Very memory intensive - only do this as a consistency + checker. Heh heh - uses an in memory tdb as the storage + for the "seen" record list. For some reason this strikes + me as extremely clever as I don't have to write another tree + data structure implementation :-). + */ + +static int seen_insert(struct tdb_context *mem_tdb, tdb_off_t rec_ptr) +{ + TDB_DATA key; + + key.dptr = (unsigned char *)&rec_ptr; + key.dsize = sizeof(rec_ptr); + return tdb_store(mem_tdb, key, tdb_null, TDB_INSERT); +} + +_PUBLIC_ int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries) +{ + struct tdb_context *mem_tdb = NULL; + struct tdb_record rec; + tdb_off_t rec_ptr, last_ptr; + int ret = -1; + + *pnum_entries = 0; + + mem_tdb = tdb_open("flval", tdb->hash_size, + TDB_INTERNAL, O_RDWR, 0600); + if (!mem_tdb) { + return -1; + } + + if (tdb_lock(tdb, -1, F_WRLCK) == -1) { + tdb_close(mem_tdb); + return 0; + } + + last_ptr = FREELIST_TOP; + + /* Store the FREELIST_TOP record. */ + if (seen_insert(mem_tdb, last_ptr) == -1) { + tdb->ecode = TDB_ERR_CORRUPT; + ret = -1; + goto fail; + } + + /* read in the freelist top */ + if (tdb_ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) { + goto fail; + } + + while (rec_ptr) { + + /* If we can't store this record (we've seen it + before) then the free list has a loop and must + be corrupt. */ + + if (seen_insert(mem_tdb, rec_ptr)) { + tdb->ecode = TDB_ERR_CORRUPT; + ret = -1; + goto fail; + } + + if (tdb_rec_free_read(tdb, rec_ptr, &rec) == -1) { + goto fail; + } + + /* move to the next record */ + rec_ptr = rec.next; + *pnum_entries += 1; + } + + ret = 0; + + fail: + + tdb_close(mem_tdb); + tdb_unlock(tdb, -1, F_WRLCK); + return ret; +} diff --git a/ldb-2.0.8/lib/tdb/common/hash.c b/ldb-2.0.8/lib/tdb/common/hash.c new file mode 100644 index 0000000..4de7ba9 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/common/hash.c @@ -0,0 +1,345 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Rusty Russell 2010 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ +#include "tdb_private.h" + +/* This is based on the hash algorithm from gdbm */ +unsigned int tdb_old_hash(TDB_DATA *key) +{ + uint32_t value; /* Used to compute the hash value. */ + uint32_t i; /* Used to cycle through random values. */ + + /* Set the initial value from the key size. */ + for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++) + value = (value + (key->dptr[i] << (i*5 % 24))); + + return (1103515243 * value + 12345); +} + +#ifndef WORDS_BIGENDIAN +# define HASH_LITTLE_ENDIAN 1 +# define HASH_BIG_ENDIAN 0 +#else +# define HASH_LITTLE_ENDIAN 0 +# define HASH_BIG_ENDIAN 1 +#endif + +/* +------------------------------------------------------------------------------- +lookup3.c, by Bob Jenkins, May 2006, Public Domain. + +These are functions for producing 32-bit hashes for hash table lookup. +hash_word(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() +are externally useful functions. Routines to test the hash are included +if SELF_TEST is defined. You can use this free for any purpose. It's in +the public domain. It has no warranty. + +You probably want to use hashlittle(). hashlittle() and hashbig() +hash byte arrays. hashlittle() is is faster than hashbig() on +little-endian machines. Intel and AMD are little-endian machines. +On second thought, you probably want hashlittle2(), which is identical to +hashlittle() except it returns two 32-bit hashes for the price of one. +You could implement hashbig2() if you wanted but I haven't bothered here. + +If you want to find a hash of, say, exactly 7 integers, do + a = i1; b = i2; c = i3; + mix(a,b,c); + a += i4; b += i5; c += i6; + mix(a,b,c); + a += i7; + final(a,b,c); +then use c as the hash value. If you have a variable length array of +4-byte integers to hash, use hash_word(). If you have a byte array (like +a character string), use hashlittle(). If you have several byte arrays, or +a mix of things, see the comments above hashlittle(). + +Why is this so big? I read 12 bytes at a time into 3 4-byte integers, +then mix those integers. This is fast (you can do a lot more thorough +mixing with 12*3 instructions on 3 integers than you can with 3 instructions +on 1 byte), but shoehorning those bytes into integers efficiently is messy. +*/ + +#define hashsize(n) ((uint32_t)1<<(n)) +#define hashmask(n) (hashsize(n)-1) +#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) + +/* +------------------------------------------------------------------------------- +mix -- mix 3 32-bit values reversibly. + +This is reversible, so any information in (a,b,c) before mix() is +still in (a,b,c) after mix(). + +If four pairs of (a,b,c) inputs are run through mix(), or through +mix() in reverse, there are at least 32 bits of the output that +are sometimes the same for one pair and different for another pair. +This was tested for: +* pairs that differed by one bit, by two bits, in any combination + of top bits of (a,b,c), or in any combination of bottom bits of + (a,b,c). +* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed + the output delta to a Gray code (a^(a>>1)) so a string of 1's (as + is commonly produced by subtraction) look like a single 1-bit + difference. +* the base values were pseudorandom, all zero but one bit set, or + all zero plus a counter that starts at zero. + +Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that +satisfy this are + 4 6 8 16 19 4 + 9 15 3 18 27 15 + 14 9 3 7 17 3 +Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing +for "differ" defined as + with a one-bit base and a two-bit delta. I +used http://burtleburtle.net/bob/hash/avalanche.html to choose +the operations, constants, and arrangements of the variables. + +This does not achieve avalanche. There are input bits of (a,b,c) +that fail to affect some output bits of (a,b,c), especially of a. The +most thoroughly mixed value is c, but it doesn't really even achieve +avalanche in c. + +This allows some parallelism. Read-after-writes are good at doubling +the number of bits affected, so the goal of mixing pulls in the opposite +direction as the goal of parallelism. I did what I could. Rotates +seem to cost as much as shifts on every machine I could lay my hands +on, and rotates are much kinder to the top and bottom bits, so I used +rotates. +------------------------------------------------------------------------------- +*/ +#define mix(a,b,c) \ +{ \ + a -= c; a ^= rot(c, 4); c += b; \ + b -= a; b ^= rot(a, 6); a += c; \ + c -= b; c ^= rot(b, 8); b += a; \ + a -= c; a ^= rot(c,16); c += b; \ + b -= a; b ^= rot(a,19); a += c; \ + c -= b; c ^= rot(b, 4); b += a; \ +} + +/* +------------------------------------------------------------------------------- +final -- final mixing of 3 32-bit values (a,b,c) into c + +Pairs of (a,b,c) values differing in only a few bits will usually +produce values of c that look totally different. This was tested for +* pairs that differed by one bit, by two bits, in any combination + of top bits of (a,b,c), or in any combination of bottom bits of + (a,b,c). +* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed + the output delta to a Gray code (a^(a>>1)) so a string of 1's (as + is commonly produced by subtraction) look like a single 1-bit + difference. +* the base values were pseudorandom, all zero but one bit set, or + all zero plus a counter that starts at zero. + +These constants passed: + 14 11 25 16 4 14 24 + 12 14 25 16 4 14 24 +and these came close: + 4 8 15 26 3 22 24 + 10 8 15 26 3 22 24 + 11 8 15 26 3 22 24 +------------------------------------------------------------------------------- +*/ +#define final(a,b,c) \ +{ \ + c ^= b; c -= rot(b,14); \ + a ^= c; a -= rot(c,11); \ + b ^= a; b -= rot(a,25); \ + c ^= b; c -= rot(b,16); \ + a ^= c; a -= rot(c,4); \ + b ^= a; b -= rot(a,14); \ + c ^= b; c -= rot(b,24); \ +} + + +/* +------------------------------------------------------------------------------- +hashlittle() -- hash a variable-length key into a 32-bit value + k : the key (the unaligned variable-length array of bytes) + length : the length of the key, counting by bytes + val2 : IN: can be any 4-byte value OUT: second 32 bit hash. +Returns a 32-bit value. Every bit of the key affects every bit of +the return value. Two keys differing by one or two bits will have +totally different hash values. Note that the return value is better +mixed than val2, so use that first. + +The best hash table sizes are powers of 2. There is no need to do +mod a prime (mod is sooo slow!). If you need less than 32 bits, +use a bitmask. For example, if you need only 10 bits, do + h = (h & hashmask(10)); +In which case, the hash table should have hashsize(10) elements. + +If you are hashing n strings (uint8_t **)k, do it like this: + for (i=0, h=0; i 12) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 12; + k += 3; + } + + /*----------------------------- handle the last (probably partial) block */ + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=((uint32_t)k8[10])<<16; FALL_THROUGH; + case 10: c+=((uint32_t)k8[9])<<8; FALL_THROUGH; + case 9 : c+=k8[8]; FALL_THROUGH; + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=((uint32_t)k8[6])<<16; FALL_THROUGH; + case 6 : b+=((uint32_t)k8[5])<<8; FALL_THROUGH; + case 5 : b+=k8[4]; FALL_THROUGH; + case 4 : a+=k[0]; break; + case 3 : a+=((uint32_t)k8[2])<<16; FALL_THROUGH; + case 2 : a+=((uint32_t)k8[1])<<8; FALL_THROUGH; + case 1 : a+=k8[0]; break; + case 0 : return c; + } + } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { + const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ + const uint8_t *k8; + + /*--------------- all but last block: aligned reads and different mixing */ + while (length > 12) + { + a += k[0] + (((uint32_t)k[1])<<16); + b += k[2] + (((uint32_t)k[3])<<16); + c += k[4] + (((uint32_t)k[5])<<16); + mix(a,b,c); + length -= 12; + k += 6; + } + + /*----------------------------- handle the last (probably partial) block */ + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[4]+(((uint32_t)k[5])<<16); + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 11: c+=((uint32_t)k8[10])<<16; FALL_THROUGH; + case 10: c+=k[4]; + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 9 : c+=k8[8]; FALL_THROUGH; + case 8 : b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 7 : b+=((uint32_t)k8[6])<<16; FALL_THROUGH; + case 6 : b+=k[2]; + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 5 : b+=k8[4]; FALL_THROUGH; + case 4 : a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 3 : a+=((uint32_t)k8[2])<<16; FALL_THROUGH; + case 2 : a+=k[0]; + break; + case 1 : a+=k8[0]; + break; + case 0 : return c; /* zero length requires no mixing */ + } + + } else { /* need to read the key one byte at a time */ + const uint8_t *k = (const uint8_t *)key; + + /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + a += ((uint32_t)k[1])<<8; + a += ((uint32_t)k[2])<<16; + a += ((uint32_t)k[3])<<24; + b += k[4]; + b += ((uint32_t)k[5])<<8; + b += ((uint32_t)k[6])<<16; + b += ((uint32_t)k[7])<<24; + c += k[8]; + c += ((uint32_t)k[9])<<8; + c += ((uint32_t)k[10])<<16; + c += ((uint32_t)k[11])<<24; + mix(a,b,c); + length -= 12; + k += 12; + } + + /*-------------------------------- last block: affect all 32 bits of (c) */ + switch(length) + { + case 12: c+=((uint32_t)k[11])<<24; FALL_THROUGH; + case 11: c+=((uint32_t)k[10])<<16; FALL_THROUGH; + case 10: c+=((uint32_t)k[9])<<8; FALL_THROUGH; + case 9 : c+=k[8]; FALL_THROUGH; + case 8 : b+=((uint32_t)k[7])<<24; FALL_THROUGH; + case 7 : b+=((uint32_t)k[6])<<16; FALL_THROUGH; + case 6 : b+=((uint32_t)k[5])<<8; FALL_THROUGH; + case 5 : b+=k[4]; FALL_THROUGH; + case 4 : a+=((uint32_t)k[3])<<24; FALL_THROUGH; + case 3 : a+=((uint32_t)k[2])<<16; FALL_THROUGH; + case 2 : a+=((uint32_t)k[1])<<8; FALL_THROUGH; + case 1 : a+=k[0]; + break; + case 0 : return c; + } + } + + final(a,b,c); + return c; +} + +_PUBLIC_ unsigned int tdb_jenkins_hash(TDB_DATA *key) +{ + return hashlittle(key->dptr, key->dsize); +} diff --git a/ldb-2.0.8/lib/tdb/common/io.c b/ldb-2.0.8/lib/tdb/common/io.c new file mode 100644 index 0000000..0de0dab --- /dev/null +++ b/ldb-2.0.8/lib/tdb/common/io.c @@ -0,0 +1,806 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2005 + Copyright (C) Paul `Rusty' Russell 2000 + Copyright (C) Jeremy Allison 2000-2003 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + + +#include "tdb_private.h" + +/* + * We prepend the mutex area, so fixup offsets. See mutex.c for details. + * tdb->hdr_ofs is 0 or header.mutex_size. + * + * Note: that we only have the 4GB limit of tdb_off_t for + * tdb->map_size. The file size on disk can be 4GB + tdb->hdr_ofs! + */ + +static bool tdb_adjust_offset(struct tdb_context *tdb, off_t *off) +{ + off_t tmp = tdb->hdr_ofs + *off; + + if ((tmp < tdb->hdr_ofs) || (tmp < *off)) { + errno = EIO; + return false; + } + + *off = tmp; + return true; +} + +static ssize_t tdb_pwrite(struct tdb_context *tdb, const void *buf, + size_t count, off_t offset) +{ + ssize_t ret; + + if (!tdb_adjust_offset(tdb, &offset)) { + return -1; + } + + do { + ret = pwrite(tdb->fd, buf, count, offset); + } while ((ret == -1) && (errno == EINTR)); + + return ret; +} + +static ssize_t tdb_pread(struct tdb_context *tdb, void *buf, + size_t count, off_t offset) +{ + ssize_t ret; + + if (!tdb_adjust_offset(tdb, &offset)) { + return -1; + } + + do { + ret = pread(tdb->fd, buf, count, offset); + } while ((ret == -1) && (errno == EINTR)); + + return ret; +} + +static int tdb_ftruncate(struct tdb_context *tdb, off_t length) +{ + ssize_t ret; + + if (!tdb_adjust_offset(tdb, &length)) { + return -1; + } + + do { + ret = ftruncate(tdb->fd, length); + } while ((ret == -1) && (errno == EINTR)); + + return ret; +} + +#ifdef HAVE_POSIX_FALLOCATE +static int tdb_posix_fallocate(struct tdb_context *tdb, off_t offset, + off_t len) +{ + ssize_t ret; + + if (!tdb_adjust_offset(tdb, &offset)) { + return -1; + } + + do { + ret = posix_fallocate(tdb->fd, offset, len); + } while ((ret == -1) && (errno == EINTR)); + + return ret; +} +#endif + +static int tdb_fstat(struct tdb_context *tdb, struct stat *buf) +{ + int ret; + + ret = fstat(tdb->fd, buf); + if (ret == -1) { + return -1; + } + + if (buf->st_size < tdb->hdr_ofs) { + errno = EIO; + return -1; + } + buf->st_size -= tdb->hdr_ofs; + + return ret; +} + +/* check for an out of bounds access - if it is out of bounds then + see if the database has been expanded by someone else and expand + if necessary +*/ +static int tdb_notrans_oob( + struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe) +{ + struct stat st; + if (len + off < len) { + if (!probe) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob off %u len %u wrap\n", + off, len)); + } + return -1; + } + + /* + * This duplicates functionality from tdb_oob(). Don't remove: + * we still have direct callers of tdb->methods->tdb_oob() + * inside transaction.c. + */ + if (off + len <= tdb->map_size) + return 0; + if (tdb->flags & TDB_INTERNAL) { + if (!probe) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %u beyond internal malloc size %u\n", + (int)(off + len), (int)tdb->map_size)); + } + return -1; + } + + if (tdb_fstat(tdb, &st) == -1) { + tdb->ecode = TDB_ERR_IO; + return -1; + } + + /* Beware >4G files! */ + if ((tdb_off_t)st.st_size != st.st_size) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_oob len %llu too large!\n", + (long long)st.st_size)); + return -1; + } + + /* Unmap, update size, remap. We do this unconditionally, to handle + * the unusual case where the db is truncated. + * + * This can happen to a child using tdb_reopen_all(true) on a + * TDB_CLEAR_IF_FIRST tdb whose parent crashes: the next + * opener will truncate the database. */ + if (tdb_munmap(tdb) == -1) { + tdb->ecode = TDB_ERR_IO; + return -1; + } + tdb->map_size = st.st_size; + if (tdb_mmap(tdb) != 0) { + return -1; + } + + if (st.st_size < (size_t)off + len) { + if (!probe) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %u beyond eof at %u\n", + (int)(off + len), (int)st.st_size)); + } + return -1; + } + return 0; +} + +/* write a lump of data at a specified offset */ +static int tdb_write(struct tdb_context *tdb, tdb_off_t off, + const void *buf, tdb_len_t len) +{ + if (len == 0) { + return 0; + } + + if (tdb->read_only || tdb->traverse_read) { + tdb->ecode = TDB_ERR_RDONLY; + return -1; + } + + if (tdb_oob(tdb, off, len, 0) != 0) + return -1; + + if (tdb->map_ptr) { + memcpy(off + (char *)tdb->map_ptr, buf, len); + } else { +#ifdef HAVE_INCOHERENT_MMAP + tdb->ecode = TDB_ERR_IO; + return -1; +#else + ssize_t written; + + written = tdb_pwrite(tdb, buf, len, off); + + if ((written != (ssize_t)len) && (written != -1)) { + /* try once more */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_write: wrote only " + "%zi of %u bytes at %u, trying once more\n", + written, len, off)); + written = tdb_pwrite(tdb, (const char *)buf+written, + len-written, off+written); + } + if (written == -1) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_write failed at %u " + "len=%u (%s)\n", off, len, strerror(errno))); + return -1; + } else if (written != (ssize_t)len) { + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_write: failed to " + "write %u bytes at %u in two attempts\n", + len, off)); + return -1; + } +#endif + } + return 0; +} + +/* Endian conversion: we only ever deal with 4 byte quantities */ +void *tdb_convert(void *buf, uint32_t size) +{ + uint32_t i, *p = (uint32_t *)buf; + for (i = 0; i < size / 4; i++) + p[i] = TDB_BYTEREV(p[i]); + return buf; +} + + +/* read a lump of data at a specified offset, maybe convert */ +static int tdb_read(struct tdb_context *tdb, tdb_off_t off, void *buf, + tdb_len_t len, int cv) +{ + if (tdb_oob(tdb, off, len, 0) != 0) { + return -1; + } + + if (tdb->map_ptr) { + memcpy(buf, off + (char *)tdb->map_ptr, len); + } else { +#ifdef HAVE_INCOHERENT_MMAP + tdb->ecode = TDB_ERR_IO; + return -1; +#else + ssize_t ret; + + ret = tdb_pread(tdb, buf, len, off); + if (ret != (ssize_t)len) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_read failed at %u " + "len=%u ret=%zi (%s) map_size=%u\n", + off, len, ret, strerror(errno), + tdb->map_size)); + return -1; + } +#endif + } + if (cv) { + tdb_convert(buf, len); + } + return 0; +} + + + +/* + do an unlocked scan of the hash table heads to find the next non-zero head. The value + will then be confirmed with the lock held +*/ +static void tdb_next_hash_chain(struct tdb_context *tdb, uint32_t *chain) +{ + uint32_t h = *chain; + if (tdb->map_ptr) { + for (;h < tdb->hash_size;h++) { + if (0 != *(uint32_t *)(TDB_HASH_TOP(h) + (unsigned char *)tdb->map_ptr)) { + break; + } + } + } else { + uint32_t off=0; + for (;h < tdb->hash_size;h++) { + if (tdb_ofs_read(tdb, TDB_HASH_TOP(h), &off) != 0 || off != 0) { + break; + } + } + } + (*chain) = h; +} + + +int tdb_munmap(struct tdb_context *tdb) +{ + if (tdb->flags & TDB_INTERNAL) + return 0; + +#ifdef HAVE_MMAP + if (tdb->map_ptr) { + int ret; + + ret = munmap(tdb->map_ptr, tdb->map_size); + if (ret != 0) + return ret; + } +#endif + tdb->map_ptr = NULL; + return 0; +} + +/* If mmap isn't coherent, *everyone* must always mmap. */ +static bool should_mmap(const struct tdb_context *tdb) +{ +#ifdef HAVE_INCOHERENT_MMAP + return true; +#else + return !(tdb->flags & TDB_NOMMAP); +#endif +} + +int tdb_mmap(struct tdb_context *tdb) +{ + if (tdb->flags & TDB_INTERNAL) + return 0; + +#ifdef HAVE_MMAP + if (should_mmap(tdb)) { + tdb->map_ptr = mmap(NULL, tdb->map_size, + PROT_READ|(tdb->read_only? 0:PROT_WRITE), + MAP_SHARED|MAP_FILE, tdb->fd, + tdb->hdr_ofs); + + /* + * NB. When mmap fails it returns MAP_FAILED *NOT* NULL !!!! + */ + + if (tdb->map_ptr == MAP_FAILED) { + tdb->map_ptr = NULL; + TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_mmap failed for size %u (%s)\n", + tdb->map_size, strerror(errno))); +#ifdef HAVE_INCOHERENT_MMAP + tdb->ecode = TDB_ERR_IO; + return -1; +#endif + } + } else { + tdb->map_ptr = NULL; + } +#else + tdb->map_ptr = NULL; +#endif + return 0; +} + +/* expand a file. we prefer to use ftruncate, as that is what posix + says to use for mmap expansion */ +static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t addition) +{ + char buf[8192]; + tdb_off_t new_size; + int ret; + + if (tdb->read_only || tdb->traverse_read) { + tdb->ecode = TDB_ERR_RDONLY; + return -1; + } + + if (!tdb_add_off_t(size, addition, &new_size)) { + tdb->ecode = TDB_ERR_OOM; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write " + "overflow detected current size[%u] addition[%u]!\n", + (unsigned)size, (unsigned)addition)); + errno = ENOSPC; + return -1; + } + +#ifdef HAVE_POSIX_FALLOCATE + ret = tdb_posix_fallocate(tdb, size, addition); + if (ret == 0) { + return 0; + } + if (ret == ENOSPC) { + /* + * The Linux glibc (at least as of 2.24) fallback if + * the file system does not support fallocate does not + * reset the file size back to where it was. Also, to + * me it is unclear from the posix spec of + * posix_fallocate whether this is allowed or + * not. Better be safe than sorry and "goto fail" but + * "return -1" here, leaving the EOF pointer too + * large. + */ + goto fail; + } + + /* + * Retry the "old" way. Possibly unnecessary, but looking at + * our configure script there seem to be weird failure modes + * for posix_fallocate. See commit 3264a98ff16de, which + * probably refers to + * https://sourceware.org/bugzilla/show_bug.cgi?id=1083. + */ +#endif + + ret = tdb_ftruncate(tdb, new_size); + if (ret == -1) { + char b = 0; + ssize_t written = tdb_pwrite(tdb, &b, 1, new_size - 1); + if (written == 0) { + /* try once more, potentially revealing errno */ + written = tdb_pwrite(tdb, &b, 1, new_size - 1); + } + if (written == 0) { + /* again - give up, guessing errno */ + errno = ENOSPC; + } + if (written != 1) { + tdb->ecode = TDB_ERR_OOM; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file to %u failed (%s)\n", + (unsigned)new_size, strerror(errno))); + return -1; + } + } + + /* now fill the file with something. This ensures that the + file isn't sparse, which would be very bad if we ran out of + disk. This must be done with write, not via mmap */ + memset(buf, TDB_PAD_BYTE, sizeof(buf)); + while (addition) { + size_t n = addition>sizeof(buf)?sizeof(buf):addition; + ssize_t written = tdb_pwrite(tdb, buf, n, size); + if (written == 0) { + /* prevent infinite loops: try _once_ more */ + written = tdb_pwrite(tdb, buf, n, size); + } + if (written == 0) { + /* give up, trying to provide a useful errno */ + tdb->ecode = TDB_ERR_OOM; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write " + "returned 0 twice: giving up!\n")); + errno = ENOSPC; + goto fail; + } + if (written == -1) { + tdb->ecode = TDB_ERR_OOM; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write of " + "%u bytes failed (%s)\n", (int)n, + strerror(errno))); + goto fail; + } + if (written != n) { + TDB_LOG((tdb, TDB_DEBUG_WARNING, "expand_file: wrote " + "only %zu of %zi bytes - retrying\n", written, + n)); + } + addition -= written; + size += written; + } + return 0; + +fail: + { + int err = errno; + + /* + * We're holding the freelist lock or are inside a + * transaction. Cutting the file is safe, the space we + * tried to allocate can't have been used anywhere in + * the meantime. + */ + + ret = tdb_ftruncate(tdb, size); + if (ret == -1) { + TDB_LOG((tdb, TDB_DEBUG_WARNING, "expand_file: " + "retruncate to %ju failed\n", + (uintmax_t)size)); + } + errno = err; + } + + return -1; +} + + +/* You need 'size', this tells you how much you should expand by. */ +tdb_off_t tdb_expand_adjust(tdb_off_t map_size, tdb_off_t size, int page_size) +{ + tdb_off_t new_size, top_size, increment; + tdb_off_t max_size = UINT32_MAX - map_size; + + if (size > max_size) { + /* + * We can't round up anymore, just give back + * what we're asked for. + * + * The caller has to take care of the ENOSPC handling. + */ + return size; + } + + /* limit size in order to avoid using up huge amounts of memory for + * in memory tdbs if an oddball huge record creeps in */ + if (size > 100 * 1024) { + increment = size * 2; + } else { + increment = size * 100; + } + if (increment < size) { + goto overflow; + } + + if (!tdb_add_off_t(map_size, increment, &top_size)) { + goto overflow; + } + + /* always make room for at least top_size more records, and at + least 25% more space. if the DB is smaller than 100MiB, + otherwise grow it by 10% only. */ + if (map_size > 100 * 1024 * 1024) { + new_size = map_size * 1.10; + } else { + new_size = map_size * 1.25; + } + if (new_size < map_size) { + goto overflow; + } + + /* Round the database up to a multiple of the page size */ + new_size = MAX(top_size, new_size); + + if (new_size + page_size < new_size) { + /* There's a "+" in TDB_ALIGN that might overflow... */ + goto overflow; + } + + return TDB_ALIGN(new_size, page_size) - map_size; + +overflow: + /* + * Somewhere in between we went over 4GB. Make one big jump to + * exactly 4GB database size. + */ + return max_size; +} + +/* expand the database at least size bytes by expanding the underlying + file and doing the mmap again if necessary */ +int tdb_expand(struct tdb_context *tdb, tdb_off_t size) +{ + struct tdb_record rec; + tdb_off_t offset; + tdb_off_t new_size; + + if (tdb_lock(tdb, -1, F_WRLCK) == -1) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "lock failed in tdb_expand\n")); + return -1; + } + + /* must know about any previous expansions by another process */ + tdb_oob(tdb, tdb->map_size, 1, 1); + + /* + * Note: that we don't care about tdb->hdr_ofs != 0 here + * + * The 4GB limitation is just related to tdb->map_size + * and the offset calculation in the records. + * + * The file on disk can be up to 4GB + tdb->hdr_ofs + */ + size = tdb_expand_adjust(tdb->map_size, size, tdb->page_size); + + if (!tdb_add_off_t(tdb->map_size, size, &new_size)) { + tdb->ecode = TDB_ERR_OOM; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_expand " + "overflow detected current map_size[%u] size[%u]!\n", + (unsigned)tdb->map_size, (unsigned)size)); + goto fail; + } + + /* form a new freelist record */ + offset = tdb->map_size; + memset(&rec,'\0',sizeof(rec)); + rec.rec_len = size - sizeof(rec); + + if (tdb->flags & TDB_INTERNAL) { + char *new_map_ptr; + + new_map_ptr = (char *)realloc(tdb->map_ptr, new_size); + if (!new_map_ptr) { + tdb->ecode = TDB_ERR_OOM; + goto fail; + } + tdb->map_ptr = new_map_ptr; + tdb->map_size = new_size; + } else { + int ret; + + /* + * expand the file itself + */ + ret = tdb->methods->tdb_expand_file(tdb, tdb->map_size, size); + if (ret != 0) { + goto fail; + } + + /* Explicitly remap: if we're in a transaction, this won't + * happen automatically! */ + tdb_munmap(tdb); + tdb->map_size = new_size; + if (tdb_mmap(tdb) != 0) { + goto fail; + } + } + + /* link it into the free list */ + if (tdb_free(tdb, offset, &rec) == -1) + goto fail; + + tdb_unlock(tdb, -1, F_WRLCK); + return 0; + fail: + tdb_unlock(tdb, -1, F_WRLCK); + return -1; +} + +int _tdb_oob(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe) +{ + int ret = tdb->methods->tdb_oob(tdb, off, len, probe); + return ret; +} + +/* read/write a tdb_off_t */ +int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d) +{ + return tdb->methods->tdb_read(tdb, offset, (char*)d, sizeof(*d), DOCONV()); +} + +int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d) +{ + tdb_off_t off = *d; + return tdb->methods->tdb_write(tdb, offset, CONVERT(off), sizeof(*d)); +} + + +/* read a lump of data, allocating the space for it */ +unsigned char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len) +{ + unsigned char *buf; + + /* some systems don't like zero length malloc */ + + if (!(buf = (unsigned char *)malloc(len ? len : 1))) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_OOM; + TDB_LOG((tdb, TDB_DEBUG_ERROR,"tdb_alloc_read malloc failed len=%u (%s)\n", + len, strerror(errno))); + return NULL; + } + if (tdb->methods->tdb_read(tdb, offset, buf, len, 0) == -1) { + SAFE_FREE(buf); + return NULL; + } + return buf; +} + +/* Give a piece of tdb data to a parser */ + +int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key, + tdb_off_t offset, tdb_len_t len, + int (*parser)(TDB_DATA key, TDB_DATA data, + void *private_data), + void *private_data) +{ + TDB_DATA data; + int result; + + data.dsize = len; + + if ((tdb->transaction == NULL) && (tdb->map_ptr != NULL)) { + /* + * Optimize by avoiding the malloc/memcpy/free, point the + * parser directly at the mmap area. + */ + if (tdb_oob(tdb, offset, len, 0) != 0) { + return -1; + } + data.dptr = offset + (unsigned char *)tdb->map_ptr; + return parser(key, data, private_data); + } + + if (!(data.dptr = tdb_alloc_read(tdb, offset, len))) { + return -1; + } + + result = parser(key, data, private_data); + free(data.dptr); + return result; +} + +/* read/write a record */ +int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec) +{ + int ret; + tdb_len_t overall_len; + + if (tdb->methods->tdb_read(tdb, offset, rec, sizeof(*rec),DOCONV()) == -1) + return -1; + if (TDB_BAD_MAGIC(rec)) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_CORRUPT; + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_rec_read bad magic 0x%x at offset=%u\n", rec->magic, offset)); + return -1; + } + + overall_len = rec->key_len + rec->data_len; + if (overall_len < rec->data_len) { + /* overflow */ + return -1; + } + + if (overall_len > rec->rec_len) { + /* invalid record */ + return -1; + } + + ret = tdb_oob(tdb, offset, rec->key_len, 1); + if (ret == -1) { + return -1; + } + ret = tdb_oob(tdb, offset, rec->data_len, 1); + if (ret == -1) { + return -1; + } + ret = tdb_oob(tdb, offset, rec->rec_len, 1); + if (ret == -1) { + return -1; + } + + return tdb_oob(tdb, rec->next, sizeof(*rec), 0); +} + +int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec) +{ + struct tdb_record r = *rec; + return tdb->methods->tdb_write(tdb, offset, CONVERT(r), sizeof(r)); +} + +static const struct tdb_methods io_methods = { + tdb_read, + tdb_write, + tdb_next_hash_chain, + tdb_notrans_oob, + tdb_expand_file, +}; + +/* + initialise the default methods table +*/ +void tdb_io_init(struct tdb_context *tdb) +{ + tdb->methods = &io_methods; +} diff --git a/ldb-2.0.8/lib/tdb/common/lock.c b/ldb-2.0.8/lib/tdb/common/lock.c new file mode 100644 index 0000000..5fba02f --- /dev/null +++ b/ldb-2.0.8/lib/tdb/common/lock.c @@ -0,0 +1,1031 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2005 + Copyright (C) Paul `Rusty' Russell 2000 + Copyright (C) Jeremy Allison 2000-2003 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "tdb_private.h" + +_PUBLIC_ void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *ptr) +{ + tdb->interrupt_sig_ptr = ptr; +} + +static int fcntl_lock(struct tdb_context *tdb, + int rw, off_t off, off_t len, bool waitflag) +{ + struct flock fl; + int cmd; + +#ifdef USE_TDB_MUTEX_LOCKING + { + int ret; + if (tdb_mutex_lock(tdb, rw, off, len, waitflag, &ret)) { + return ret; + } + } +#endif + + fl.l_type = rw; + fl.l_whence = SEEK_SET; + fl.l_start = off; + fl.l_len = len; + fl.l_pid = 0; + + cmd = waitflag ? F_SETLKW : F_SETLK; + + return fcntl(tdb->fd, cmd, &fl); +} + +static int fcntl_unlock(struct tdb_context *tdb, int rw, off_t off, off_t len) +{ + struct flock fl; +#if 0 /* Check they matched up locks and unlocks correctly. */ + char line[80]; + FILE *locks; + bool found = false; + + locks = fopen("/proc/locks", "r"); + + while (fgets(line, 80, locks)) { + char *p; + int type, start, l; + + /* eg. 1: FLOCK ADVISORY WRITE 2440 08:01:2180826 0 EOF */ + p = strchr(line, ':') + 1; + if (strncmp(p, " POSIX ADVISORY ", strlen(" POSIX ADVISORY "))) + continue; + p += strlen(" FLOCK ADVISORY "); + if (strncmp(p, "READ ", strlen("READ ")) == 0) + type = F_RDLCK; + else if (strncmp(p, "WRITE ", strlen("WRITE ")) == 0) + type = F_WRLCK; + else + abort(); + p += 6; + if (atoi(p) != getpid()) + continue; + p = strchr(strchr(p, ' ') + 1, ' ') + 1; + start = atoi(p); + p = strchr(p, ' ') + 1; + if (strncmp(p, "EOF", 3) == 0) + l = 0; + else + l = atoi(p) - start + 1; + + if (off == start) { + if (len != l) { + fprintf(stderr, "Len %u should be %u: %s", + (int)len, l, line); + abort(); + } + if (type != rw) { + fprintf(stderr, "Type %s wrong: %s", + rw == F_RDLCK ? "READ" : "WRITE", line); + abort(); + } + found = true; + break; + } + } + + if (!found) { + fprintf(stderr, "Unlock on %u@%u not found!\n", + (int)off, (int)len); + abort(); + } + + fclose(locks); +#endif + +#ifdef USE_TDB_MUTEX_LOCKING + { + int ret; + if (tdb_mutex_unlock(tdb, rw, off, len, &ret)) { + return ret; + } + } +#endif + + fl.l_type = F_UNLCK; + fl.l_whence = SEEK_SET; + fl.l_start = off; + fl.l_len = len; + fl.l_pid = 0; + + return fcntl(tdb->fd, F_SETLKW, &fl); +} + +/* + * Calculate the lock offset for a list + * + * list -1 is the freelist, otherwise a hash chain. + * + * Note that we consistently (but without real reason) lock hash chains at an + * offset that is 4 bytes below the real offset of the corresponding list head + * in the db. + * + * This is the memory layout of the hashchain array: + * + * FREELIST_TOP + 0 = freelist + * FREELIST_TOP + 4 = hashtable list 0 + * FREELIST_TOP + 8 = hashtable list 1 + * ... + * + * Otoh lock_offset computes: + * + * freelist = FREELIST_TOP - 4 + * list 0 = FREELIST_TOP + 0 + * list 1 = FREELIST_TOP + 4 + * ... + * + * Unfortunately we can't change this calculation in order to align the locking + * offset with the memory layout, as that would make the locking incompatible + * between different tdb versions. + */ +static tdb_off_t lock_offset(int list) +{ + return FREELIST_TOP + 4*list; +} + +/* a byte range locking function - return 0 on success + this functions locks/unlocks "len" byte at the specified offset. + + On error, errno is also set so that errors are passed back properly + through tdb_open(). + + note that a len of zero means lock to end of file +*/ +int tdb_brlock(struct tdb_context *tdb, + int rw_type, tdb_off_t offset, size_t len, + enum tdb_lock_flags flags) +{ + int ret; + + if (tdb->flags & TDB_NOLOCK) { + return 0; + } + + if (flags & TDB_LOCK_MARK_ONLY) { + return 0; + } + + if ((rw_type == F_WRLCK) && (tdb->read_only || tdb->traverse_read)) { + tdb->ecode = TDB_ERR_RDONLY; + return -1; + } + + do { + ret = fcntl_lock(tdb, rw_type, offset, len, + flags & TDB_LOCK_WAIT); + /* Check for a sigalarm break. */ + if (ret == -1 && errno == EINTR && + tdb->interrupt_sig_ptr && + *tdb->interrupt_sig_ptr) { + break; + } + } while (ret == -1 && errno == EINTR); + + if (ret == -1) { + tdb->ecode = TDB_ERR_LOCK; + /* Generic lock error. errno set by fcntl. + * EAGAIN is an expected return from non-blocking + * locks. */ + if (!(flags & TDB_LOCK_PROBE) && errno != EAGAIN) { + TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock failed (fd=%d) at offset %u rw_type=%d flags=%d len=%zu\n", + tdb->fd, offset, rw_type, flags, len)); + } + return -1; + } + return 0; +} + +int tdb_brunlock(struct tdb_context *tdb, + int rw_type, tdb_off_t offset, size_t len) +{ + int ret; + + if (tdb->flags & TDB_NOLOCK) { + return 0; + } + + do { + ret = fcntl_unlock(tdb, rw_type, offset, len); + } while (ret == -1 && errno == EINTR); + + if (ret == -1) { + TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brunlock failed (fd=%d) at offset %u rw_type=%u len=%zu\n", + tdb->fd, offset, rw_type, len)); + } + return ret; +} + +/* + * Do a tdb_brlock in a loop. Some OSes (such as solaris) have too + * conservative deadlock detection and claim a deadlock when progress can be + * made. For those OSes we may loop for a while. + */ + +static int tdb_brlock_retry(struct tdb_context *tdb, + int rw_type, tdb_off_t offset, size_t len, + enum tdb_lock_flags flags) +{ + int count = 1000; + + while (count--) { + struct timeval tv; + int ret; + + ret = tdb_brlock(tdb, rw_type, offset, len, flags); + if (ret == 0) { + return 0; + } + if (errno != EDEADLK) { + break; + } + /* sleep for as short a time as we can - more portable than usleep() */ + tv.tv_sec = 0; + tv.tv_usec = 1; + select(0, NULL, NULL, NULL, &tv); + } + return -1; +} + +/* + upgrade a read lock to a write lock. +*/ +int tdb_allrecord_upgrade(struct tdb_context *tdb) +{ + int ret; + + if (tdb->allrecord_lock.count != 1) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "tdb_allrecord_upgrade failed: count %u too high\n", + tdb->allrecord_lock.count)); + tdb->ecode = TDB_ERR_LOCK; + return -1; + } + + if (tdb->allrecord_lock.off != 1) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "tdb_allrecord_upgrade failed: already upgraded?\n")); + tdb->ecode = TDB_ERR_LOCK; + return -1; + } + + if (tdb_have_mutexes(tdb)) { + ret = tdb_mutex_allrecord_upgrade(tdb); + if (ret == -1) { + goto fail; + } + ret = tdb_brlock_retry(tdb, F_WRLCK, lock_offset(tdb->hash_size), + 0, TDB_LOCK_WAIT|TDB_LOCK_PROBE); + if (ret == -1) { + tdb_mutex_allrecord_downgrade(tdb); + } + } else { + ret = tdb_brlock_retry(tdb, F_WRLCK, FREELIST_TOP, 0, + TDB_LOCK_WAIT|TDB_LOCK_PROBE); + } + + if (ret == 0) { + tdb->allrecord_lock.ltype = F_WRLCK; + tdb->allrecord_lock.off = 0; + return 0; + } +fail: + TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_allrecord_upgrade failed\n")); + return -1; +} + +static struct tdb_lock_type *find_nestlock(struct tdb_context *tdb, + tdb_off_t offset) +{ + int i; + + for (i=0; inum_lockrecs; i++) { + if (tdb->lockrecs[i].off == offset) { + return &tdb->lockrecs[i]; + } + } + return NULL; +} + +/* lock an offset in the database. */ +int tdb_nest_lock(struct tdb_context *tdb, uint32_t offset, int ltype, + enum tdb_lock_flags flags) +{ + struct tdb_lock_type *new_lck; + + if (offset >= lock_offset(tdb->hash_size)) { + tdb->ecode = TDB_ERR_LOCK; + TDB_LOG((tdb, TDB_DEBUG_ERROR,"tdb_lock: invalid offset %u for ltype=%d\n", + offset, ltype)); + return -1; + } + if (tdb->flags & TDB_NOLOCK) + return 0; + + new_lck = find_nestlock(tdb, offset); + if (new_lck) { + if ((new_lck->ltype == F_RDLCK) && (ltype == F_WRLCK)) { + if (!tdb_have_mutexes(tdb)) { + int ret; + /* + * Upgrade the underlying fcntl + * lock. Mutexes don't do readlocks, + * so this only applies to fcntl + * locking. + */ + ret = tdb_brlock(tdb, ltype, offset, 1, flags); + if (ret != 0) { + return ret; + } + } + new_lck->ltype = F_WRLCK; + } + /* + * Just increment the in-memory struct, posix locks + * don't stack. + */ + new_lck->count++; + return 0; + } + + if (tdb->num_lockrecs == tdb->lockrecs_array_length) { + new_lck = (struct tdb_lock_type *)realloc( + tdb->lockrecs, + sizeof(*tdb->lockrecs) * (tdb->num_lockrecs+1)); + if (new_lck == NULL) { + errno = ENOMEM; + return -1; + } + tdb->lockrecs_array_length = tdb->num_lockrecs+1; + tdb->lockrecs = new_lck; + } + + /* Since fcntl locks don't nest, we do a lock for the first one, + and simply bump the count for future ones */ + if (tdb_brlock(tdb, ltype, offset, 1, flags)) { + return -1; + } + + new_lck = &tdb->lockrecs[tdb->num_lockrecs]; + + new_lck->off = offset; + new_lck->count = 1; + new_lck->ltype = ltype; + tdb->num_lockrecs++; + + return 0; +} + +static int tdb_lock_and_recover(struct tdb_context *tdb) +{ + int ret; + + /* We need to match locking order in transaction commit. */ + if (tdb_brlock(tdb, F_WRLCK, FREELIST_TOP, 0, TDB_LOCK_WAIT)) { + return -1; + } + + if (tdb_brlock(tdb, F_WRLCK, OPEN_LOCK, 1, TDB_LOCK_WAIT)) { + tdb_brunlock(tdb, F_WRLCK, FREELIST_TOP, 0); + return -1; + } + + ret = tdb_transaction_recover(tdb); + + tdb_brunlock(tdb, F_WRLCK, OPEN_LOCK, 1); + tdb_brunlock(tdb, F_WRLCK, FREELIST_TOP, 0); + + return ret; +} + +static bool have_data_locks(const struct tdb_context *tdb) +{ + int i; + + for (i = 0; i < tdb->num_lockrecs; i++) { + if (tdb->lockrecs[i].off >= lock_offset(-1)) + return true; + } + return false; +} + +/* + * A allrecord lock allows us to avoid per chain locks. Check if the allrecord + * lock is strong enough. + */ +static int tdb_lock_covered_by_allrecord_lock(struct tdb_context *tdb, + int ltype) +{ + if (ltype == F_RDLCK) { + /* + * The allrecord_lock is equal (F_RDLCK) or stronger + * (F_WRLCK). Pass. + */ + return 0; + } + + if (tdb->allrecord_lock.ltype == F_RDLCK) { + /* + * We ask for ltype==F_WRLCK, but the allrecord_lock + * is too weak. We can't upgrade here, so fail. + */ + tdb->ecode = TDB_ERR_LOCK; + return -1; + } + + /* + * Asking for F_WRLCK, allrecord is F_WRLCK as well. Pass. + */ + return 0; +} + +static int tdb_lock_list(struct tdb_context *tdb, int list, int ltype, + enum tdb_lock_flags waitflag) +{ + int ret; + bool check = false; + + if (tdb->allrecord_lock.count) { + return tdb_lock_covered_by_allrecord_lock(tdb, ltype); + } + + /* + * Check for recoveries: Someone might have kill -9'ed a process + * during a commit. + */ + check = !have_data_locks(tdb); + ret = tdb_nest_lock(tdb, lock_offset(list), ltype, waitflag); + + if (ret == 0 && check && tdb_needs_recovery(tdb)) { + tdb_nest_unlock(tdb, lock_offset(list), ltype, false); + + if (tdb_lock_and_recover(tdb) == -1) { + return -1; + } + return tdb_lock_list(tdb, list, ltype, waitflag); + } + return ret; +} + +/* lock a list in the database. list -1 is the alloc list */ +int tdb_lock(struct tdb_context *tdb, int list, int ltype) +{ + int ret; + + ret = tdb_lock_list(tdb, list, ltype, TDB_LOCK_WAIT); + if (ret) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lock failed on list %d " + "ltype=%d (%s)\n", list, ltype, strerror(errno))); + } + return ret; +} + +/* lock a list in the database. list -1 is the alloc list. non-blocking lock */ +_PUBLIC_ int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype) +{ + return tdb_lock_list(tdb, list, ltype, TDB_LOCK_NOWAIT); +} + + +int tdb_nest_unlock(struct tdb_context *tdb, uint32_t offset, int ltype, + bool mark_lock) +{ + int ret = -1; + struct tdb_lock_type *lck; + + if (tdb->flags & TDB_NOLOCK) + return 0; + + /* Sanity checks */ + if (offset >= lock_offset(tdb->hash_size)) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: offset %u invalid (%d)\n", offset, tdb->hash_size)); + return ret; + } + + lck = find_nestlock(tdb, offset); + if ((lck == NULL) || (lck->count == 0)) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: count is 0\n")); + return -1; + } + + if (lck->count > 1) { + lck->count--; + return 0; + } + + /* + * This lock has count==1 left, so we need to unlock it in the + * kernel. We don't bother with decrementing the in-memory array + * element, we're about to overwrite it with the last array element + * anyway. + */ + + if (mark_lock) { + ret = 0; + } else { + ret = tdb_brunlock(tdb, ltype, offset, 1); + } + + /* + * Shrink the array by overwriting the element just unlocked with the + * last array element. + */ + *lck = tdb->lockrecs[--tdb->num_lockrecs]; + + /* + * We don't bother with realloc when the array shrinks, but if we have + * a completely idle tdb we should get rid of the locked array. + */ + + if (ret) + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: An error occurred unlocking!\n")); + return ret; +} + +_PUBLIC_ int tdb_unlock(struct tdb_context *tdb, int list, int ltype) +{ + /* a global lock allows us to avoid per chain locks */ + if (tdb->allrecord_lock.count) { + return tdb_lock_covered_by_allrecord_lock(tdb, ltype); + } + + return tdb_nest_unlock(tdb, lock_offset(list), ltype, false); +} + +/* + get the transaction lock + */ +int tdb_transaction_lock(struct tdb_context *tdb, int ltype, + enum tdb_lock_flags lockflags) +{ + return tdb_nest_lock(tdb, TRANSACTION_LOCK, ltype, lockflags); +} + +/* + release the transaction lock + */ +int tdb_transaction_unlock(struct tdb_context *tdb, int ltype) +{ + return tdb_nest_unlock(tdb, TRANSACTION_LOCK, ltype, false); +} + +/* Returns 0 if all done, -1 if error, 1 if ok. */ +static int tdb_allrecord_check(struct tdb_context *tdb, int ltype, + enum tdb_lock_flags flags, bool upgradable) +{ + /* There are no locks on read-only dbs */ + if (tdb->read_only || tdb->traverse_read) { + tdb->ecode = TDB_ERR_LOCK; + return -1; + } + + if (tdb->allrecord_lock.count && + tdb->allrecord_lock.ltype == (uint32_t)ltype) { + tdb->allrecord_lock.count++; + return 0; + } + + if (tdb->allrecord_lock.count) { + /* a global lock of a different type exists */ + tdb->ecode = TDB_ERR_LOCK; + return -1; + } + + if (tdb_have_extra_locks(tdb)) { + /* can't combine global and chain locks */ + tdb->ecode = TDB_ERR_LOCK; + return -1; + } + + if (upgradable && ltype != F_RDLCK) { + /* tdb error: you can't upgrade a write lock! */ + tdb->ecode = TDB_ERR_LOCK; + return -1; + } + return 1; +} + +/* We only need to lock individual bytes, but Linux merges consecutive locks + * so we lock in contiguous ranges. */ +static int tdb_chainlock_gradual(struct tdb_context *tdb, + int ltype, enum tdb_lock_flags flags, + size_t off, size_t len) +{ + int ret; + enum tdb_lock_flags nb_flags = (flags & ~TDB_LOCK_WAIT); + + if (len <= 4) { + /* Single record. Just do blocking lock. */ + return tdb_brlock(tdb, ltype, off, len, flags); + } + + /* First we try non-blocking. */ + ret = tdb_brlock(tdb, ltype, off, len, nb_flags); + if (ret == 0) { + return 0; + } + + /* Try locking first half, then second. */ + ret = tdb_chainlock_gradual(tdb, ltype, flags, off, len / 2); + if (ret == -1) + return -1; + + ret = tdb_chainlock_gradual(tdb, ltype, flags, + off + len / 2, len - len / 2); + if (ret == -1) { + tdb_brunlock(tdb, ltype, off, len / 2); + return -1; + } + return 0; +} + +/* lock/unlock entire database. It can only be upgradable if you have some + * other way of guaranteeing exclusivity (ie. transaction write lock). + * We do the locking gradually to avoid being starved by smaller locks. */ +int tdb_allrecord_lock(struct tdb_context *tdb, int ltype, + enum tdb_lock_flags flags, bool upgradable) +{ + int ret; + + switch (tdb_allrecord_check(tdb, ltype, flags, upgradable)) { + case -1: + return -1; + case 0: + return 0; + } + + /* We cover two kinds of locks: + * 1) Normal chain locks. Taken for almost all operations. + * 2) Individual records locks. Taken after normal or free + * chain locks. + * + * It is (1) which cause the starvation problem, so we're only + * gradual for that. */ + + if (tdb_have_mutexes(tdb)) { + ret = tdb_mutex_allrecord_lock(tdb, ltype, flags); + } else { + ret = tdb_chainlock_gradual(tdb, ltype, flags, FREELIST_TOP, + tdb->hash_size * 4); + } + + if (ret == -1) { + return -1; + } + + /* Grab individual record locks. */ + if (tdb_brlock(tdb, ltype, lock_offset(tdb->hash_size), 0, + flags) == -1) { + if (tdb_have_mutexes(tdb)) { + tdb_mutex_allrecord_unlock(tdb); + } else { + tdb_brunlock(tdb, ltype, FREELIST_TOP, + tdb->hash_size * 4); + } + return -1; + } + + tdb->allrecord_lock.count = 1; + /* If it's upgradable, it's actually exclusive so we can treat + * it as a write lock. */ + tdb->allrecord_lock.ltype = upgradable ? F_WRLCK : ltype; + tdb->allrecord_lock.off = upgradable; + + if (tdb_needs_recovery(tdb)) { + bool mark = flags & TDB_LOCK_MARK_ONLY; + tdb_allrecord_unlock(tdb, ltype, mark); + if (mark) { + tdb->ecode = TDB_ERR_LOCK; + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "tdb_lockall_mark cannot do recovery\n")); + return -1; + } + if (tdb_lock_and_recover(tdb) == -1) { + return -1; + } + return tdb_allrecord_lock(tdb, ltype, flags, upgradable); + } + + return 0; +} + + + +/* unlock entire db */ +int tdb_allrecord_unlock(struct tdb_context *tdb, int ltype, bool mark_lock) +{ + /* There are no locks on read-only dbs */ + if (tdb->read_only || tdb->traverse_read) { + tdb->ecode = TDB_ERR_LOCK; + return -1; + } + + if (tdb->allrecord_lock.count == 0) { + tdb->ecode = TDB_ERR_LOCK; + return -1; + } + + /* Upgradable locks are marked as write locks. */ + if (tdb->allrecord_lock.ltype != (uint32_t)ltype + && (!tdb->allrecord_lock.off || ltype != F_RDLCK)) { + tdb->ecode = TDB_ERR_LOCK; + return -1; + } + + if (tdb->allrecord_lock.count > 1) { + tdb->allrecord_lock.count--; + return 0; + } + + if (!mark_lock) { + int ret; + + if (tdb_have_mutexes(tdb)) { + ret = tdb_mutex_allrecord_unlock(tdb); + if (ret == 0) { + ret = tdb_brunlock(tdb, ltype, + lock_offset(tdb->hash_size), + 0); + } + } else { + ret = tdb_brunlock(tdb, ltype, FREELIST_TOP, 0); + } + + if (ret != 0) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlockall failed " + "(%s)\n", strerror(errno))); + return -1; + } + } + + tdb->allrecord_lock.count = 0; + tdb->allrecord_lock.ltype = 0; + + return 0; +} + +/* lock entire database with write lock */ +_PUBLIC_ int tdb_lockall(struct tdb_context *tdb) +{ + tdb_trace(tdb, "tdb_lockall"); + return tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); +} + +/* lock entire database with write lock - mark only */ +_PUBLIC_ int tdb_lockall_mark(struct tdb_context *tdb) +{ + tdb_trace(tdb, "tdb_lockall_mark"); + return tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_MARK_ONLY, false); +} + +/* unlock entire database with write lock - unmark only */ +_PUBLIC_ int tdb_lockall_unmark(struct tdb_context *tdb) +{ + tdb_trace(tdb, "tdb_lockall_unmark"); + return tdb_allrecord_unlock(tdb, F_WRLCK, true); +} + +/* lock entire database with write lock - nonblocking varient */ +_PUBLIC_ int tdb_lockall_nonblock(struct tdb_context *tdb) +{ + int ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_NOWAIT, false); + tdb_trace_ret(tdb, "tdb_lockall_nonblock", ret); + return ret; +} + +/* unlock entire database with write lock */ +_PUBLIC_ int tdb_unlockall(struct tdb_context *tdb) +{ + tdb_trace(tdb, "tdb_unlockall"); + return tdb_allrecord_unlock(tdb, F_WRLCK, false); +} + +/* lock entire database with read lock */ +_PUBLIC_ int tdb_lockall_read(struct tdb_context *tdb) +{ + tdb_trace(tdb, "tdb_lockall_read"); + return tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, false); +} + +/* lock entire database with read lock - nonblock varient */ +_PUBLIC_ int tdb_lockall_read_nonblock(struct tdb_context *tdb) +{ + int ret = tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_NOWAIT, false); + tdb_trace_ret(tdb, "tdb_lockall_read_nonblock", ret); + return ret; +} + +/* unlock entire database with read lock */ +_PUBLIC_ int tdb_unlockall_read(struct tdb_context *tdb) +{ + tdb_trace(tdb, "tdb_unlockall_read"); + return tdb_allrecord_unlock(tdb, F_RDLCK, false); +} + +/* lock/unlock one hash chain. This is meant to be used to reduce + contention - it cannot guarantee how many records will be locked */ +_PUBLIC_ int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key) +{ + int ret = tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); + tdb_trace_1rec(tdb, "tdb_chainlock", key); + return ret; +} + +/* lock/unlock one hash chain, non-blocking. This is meant to be used + to reduce contention - it cannot guarantee how many records will be + locked */ +_PUBLIC_ int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key) +{ + int ret = tdb_lock_nonblock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); + tdb_trace_1rec_ret(tdb, "tdb_chainlock_nonblock", key, ret); + return ret; +} + +/* mark a chain as locked without actually locking it. Warning! use with great caution! */ +_PUBLIC_ int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key) +{ + int ret = tdb_nest_lock(tdb, lock_offset(BUCKET(tdb->hash_fn(&key))), + F_WRLCK, TDB_LOCK_MARK_ONLY); + tdb_trace_1rec(tdb, "tdb_chainlock_mark", key); + return ret; +} + +/* unmark a chain as locked without actually locking it. Warning! use with great caution! */ +_PUBLIC_ int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key) +{ + tdb_trace_1rec(tdb, "tdb_chainlock_unmark", key); + return tdb_nest_unlock(tdb, lock_offset(BUCKET(tdb->hash_fn(&key))), + F_WRLCK, true); +} + +_PUBLIC_ int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key) +{ + tdb_trace_1rec(tdb, "tdb_chainunlock", key); + return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); +} + +_PUBLIC_ int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key) +{ + int ret; + ret = tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); + tdb_trace_1rec(tdb, "tdb_chainlock_read", key); + return ret; +} + +_PUBLIC_ int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key) +{ + tdb_trace_1rec(tdb, "tdb_chainunlock_read", key); + return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); +} + +_PUBLIC_ int tdb_chainlock_read_nonblock(struct tdb_context *tdb, TDB_DATA key) +{ + int ret = tdb_lock_nonblock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); + tdb_trace_1rec_ret(tdb, "tdb_chainlock_read_nonblock", key, ret); + return ret; +} + +/* record lock stops delete underneath */ +int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off) +{ + if (tdb->allrecord_lock.count) { + return 0; + } + return off ? tdb_brlock(tdb, F_RDLCK, off, 1, TDB_LOCK_WAIT) : 0; +} + +/* + Write locks override our own fcntl readlocks, so check it here. + Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not + an error to fail to get the lock here. +*/ +int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off) +{ + struct tdb_traverse_lock *i; + if (tdb == NULL) { + return -1; + } + for (i = &tdb->travlocks; i; i = i->next) + if (i->off == off) + return -1; + if (tdb->allrecord_lock.count) { + if (tdb->allrecord_lock.ltype == F_WRLCK) { + return 0; + } + return -1; + } + return tdb_brlock(tdb, F_WRLCK, off, 1, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE); +} + +int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off) +{ + if (tdb->allrecord_lock.count) { + return 0; + } + return tdb_brunlock(tdb, F_WRLCK, off, 1); +} + +/* fcntl locks don't stack: avoid unlocking someone else's */ +int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off) +{ + struct tdb_traverse_lock *i; + uint32_t count = 0; + + if (tdb->allrecord_lock.count) { + return 0; + } + + if (off == 0) + return 0; + for (i = &tdb->travlocks; i; i = i->next) + if (i->off == off) + count++; + return (count == 1 ? tdb_brunlock(tdb, F_RDLCK, off, 1) : 0); +} + +bool tdb_have_extra_locks(struct tdb_context *tdb) +{ + unsigned int extra = tdb->num_lockrecs; + + /* A transaction holds the lock for all records. */ + if (!tdb->transaction && tdb->allrecord_lock.count) { + return true; + } + + /* We always hold the active lock if CLEAR_IF_FIRST. */ + if (find_nestlock(tdb, ACTIVE_LOCK)) { + extra--; + } + + /* In a transaction, we expect to hold the transaction lock */ + if (tdb->transaction && find_nestlock(tdb, TRANSACTION_LOCK)) { + extra--; + } + + return extra; +} + +/* The transaction code uses this to remove all locks. */ +void tdb_release_transaction_locks(struct tdb_context *tdb) +{ + int i; + unsigned int active = 0; + + if (tdb->allrecord_lock.count != 0) { + tdb_allrecord_unlock(tdb, tdb->allrecord_lock.ltype, false); + tdb->allrecord_lock.count = 0; + } + + for (i=0;inum_lockrecs;i++) { + struct tdb_lock_type *lck = &tdb->lockrecs[i]; + + /* Don't release the active lock! Copy it to first entry. */ + if (lck->off == ACTIVE_LOCK) { + tdb->lockrecs[active++] = *lck; + } else { + tdb_brunlock(tdb, lck->ltype, lck->off, 1); + } + } + tdb->num_lockrecs = active; +} + +/* Following functions are added specifically to support CTDB. */ + +/* Don't do actual fcntl locking, just mark tdb locked */ +int tdb_transaction_write_lock_mark(struct tdb_context *tdb); +_PUBLIC_ int tdb_transaction_write_lock_mark(struct tdb_context *tdb) +{ + return tdb_transaction_lock(tdb, F_WRLCK, TDB_LOCK_MARK_ONLY); +} + +/* Don't do actual fcntl unlocking, just mark tdb unlocked */ +int tdb_transaction_write_lock_unmark(struct tdb_context *tdb); +_PUBLIC_ int tdb_transaction_write_lock_unmark(struct tdb_context *tdb) +{ + return tdb_nest_unlock(tdb, TRANSACTION_LOCK, F_WRLCK, true); +} diff --git a/ldb-2.0.8/lib/tdb/common/mutex.c b/ldb-2.0.8/lib/tdb/common/mutex.c new file mode 100644 index 0000000..8a122d5 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/common/mutex.c @@ -0,0 +1,1077 @@ +/* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Volker Lendecke 2012,2013 + Copyright (C) Stefan Metzmacher 2013,2014 + Copyright (C) Michael Adam 2014 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ +#include "tdb_private.h" +#include "system/threads.h" + +#ifdef USE_TDB_MUTEX_LOCKING + +/* + * If we run with mutexes, we store the "struct tdb_mutexes" at the + * beginning of the file. We store an additional tdb_header right + * beyond the mutex area, page aligned. All the offsets within the tdb + * are relative to the area behind the mutex area. tdb->map_ptr points + * behind the mmap area as well, so the read and write path in the + * mutex case can remain unchanged. + * + * Early in the mutex development the mutexes were placed between the hash + * chain pointers and the real tdb data. This had two drawbacks: First, it + * made pointer calculations more complex. Second, we had to mmap the mutex + * area twice. One was the normal map_ptr in the tdb. This frequently changed + * from within tdb_oob. At least the Linux glibc robust mutex code assumes + * constant pointers in memory, so a constantly changing mmap area destroys + * the mutex list. So we had to mmap the first bytes of the file with a second + * mmap call. With that scheme, very weird errors happened that could be + * easily fixed by doing the mutex mmap in a second file. It seemed that + * mapping the same memory area twice does not end up in accessing the same + * physical page, looking at the mutexes in gdb it seemed that old data showed + * up after some re-mapping. To avoid a separate mutex file, the code now puts + * the real content of the tdb file after the mutex area. This way we do not + * have overlapping mmap areas, the mutex area is mmapped once and not + * changed, the tdb data area's mmap is constantly changed but does not + * overlap. + */ + +struct tdb_mutexes { + struct tdb_header hdr; + + /* protect allrecord_lock */ + pthread_mutex_t allrecord_mutex; + + /* + * F_UNLCK: free, + * F_RDLCK: shared, + * F_WRLCK: exclusive + */ + short int allrecord_lock; + + /* + * Index 0 is the freelist mutex, followed by + * one mutex per hashchain. + */ + pthread_mutex_t hashchains[1]; +}; + +bool tdb_have_mutexes(struct tdb_context *tdb) +{ + return ((tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) != 0); +} + +size_t tdb_mutex_size(struct tdb_context *tdb) +{ + size_t mutex_size; + + if (!tdb_have_mutexes(tdb)) { + return 0; + } + + mutex_size = sizeof(struct tdb_mutexes); + mutex_size += tdb->hash_size * sizeof(pthread_mutex_t); + + return TDB_ALIGN(mutex_size, tdb->page_size); +} + +/* + * Get the index for a chain mutex + */ +static bool tdb_mutex_index(struct tdb_context *tdb, off_t off, off_t len, + unsigned *idx) +{ + /* + * Weird but true: We fcntl lock 1 byte at an offset 4 bytes before + * the 4 bytes of the freelist start and the hash chain that is about + * to be locked. See lock_offset() where the freelist is -1 vs the + * "+1" in TDB_HASH_TOP(). Because the mutex array is represented in + * the tdb file itself as data, we need to adjust the offset here. + */ + const off_t freelist_lock_ofs = FREELIST_TOP - sizeof(tdb_off_t); + + if (!tdb_have_mutexes(tdb)) { + return false; + } + if (len != 1) { + /* Possibly the allrecord lock */ + return false; + } + if (off < freelist_lock_ofs) { + /* One of the special locks */ + return false; + } + if (tdb->hash_size == 0) { + /* tdb not initialized yet, called from tdb_open_ex() */ + return false; + } + if (off >= TDB_DATA_START(tdb->hash_size)) { + /* Single record lock from traverses */ + return false; + } + + /* + * Now we know it's a freelist or hash chain lock. Those are always 4 + * byte aligned. Paranoia check. + */ + if ((off % sizeof(tdb_off_t)) != 0) { + abort(); + } + + /* + * Re-index the fcntl offset into an offset into the mutex array + */ + off -= freelist_lock_ofs; /* rebase to index 0 */ + off /= sizeof(tdb_off_t); /* 0 for freelist 1-n for hashchain */ + + *idx = off; + return true; +} + +static bool tdb_have_mutex_chainlocks(struct tdb_context *tdb) +{ + size_t i; + + for (i=0; i < tdb->num_lockrecs; i++) { + bool ret; + unsigned idx; + + ret = tdb_mutex_index(tdb, + tdb->lockrecs[i].off, + tdb->lockrecs[i].count, + &idx); + if (!ret) { + continue; + } + + if (idx == 0) { + /* this is the freelist mutex */ + continue; + } + + return true; + } + + return false; +} + +static int chain_mutex_lock(pthread_mutex_t *m, bool waitflag) +{ + int ret; + + if (waitflag) { + ret = pthread_mutex_lock(m); + } else { + ret = pthread_mutex_trylock(m); + } + if (ret != EOWNERDEAD) { + return ret; + } + + /* + * For chainlocks, we don't do any cleanup (yet?) + */ + return pthread_mutex_consistent(m); +} + +static int allrecord_mutex_lock(struct tdb_mutexes *m, bool waitflag) +{ + int ret; + + if (waitflag) { + ret = pthread_mutex_lock(&m->allrecord_mutex); + } else { + ret = pthread_mutex_trylock(&m->allrecord_mutex); + } + if (ret != EOWNERDEAD) { + return ret; + } + + /* + * The allrecord lock holder died. We need to reset the allrecord_lock + * to F_UNLCK. This should also be the indication for + * tdb_needs_recovery. + */ + m->allrecord_lock = F_UNLCK; + + return pthread_mutex_consistent(&m->allrecord_mutex); +} + +bool tdb_mutex_lock(struct tdb_context *tdb, int rw, off_t off, off_t len, + bool waitflag, int *pret) +{ + struct tdb_mutexes *m = tdb->mutexes; + pthread_mutex_t *chain; + int ret; + unsigned idx; + bool allrecord_ok; + + if (!tdb_mutex_index(tdb, off, len, &idx)) { + return false; + } + chain = &m->hashchains[idx]; + +again: + ret = chain_mutex_lock(chain, waitflag); + if (ret == EBUSY) { + ret = EAGAIN; + } + if (ret != 0) { + errno = ret; + goto fail; + } + + if (idx == 0) { + /* + * This is a freelist lock, which is independent to + * the allrecord lock. So we're done once we got the + * freelist mutex. + */ + *pret = 0; + return true; + } + + if (tdb_have_mutex_chainlocks(tdb)) { + /* + * We can only check the allrecord lock once. If we do it with + * one chain mutex locked, we will deadlock with the allrecord + * locker process in the following way: We lock the first hash + * chain, we check for the allrecord lock. We keep the hash + * chain locked. Then the allrecord locker locks the + * allrecord_mutex. It walks the list of chain mutexes, + * locking them all in sequence. Meanwhile, we have the chain + * mutex locked, so the allrecord locker blocks trying to lock + * our chain mutex. Then we come in and try to lock the second + * chain lock, which in most cases will be the freelist. We + * see that the allrecord lock is locked and put ourselves on + * the allrecord_mutex. This will never be signalled though + * because the allrecord locker waits for us to give up the + * chain lock. + */ + + *pret = 0; + return true; + } + + /* + * Check if someone is has the allrecord lock: queue if so. + */ + + allrecord_ok = false; + + if (m->allrecord_lock == F_UNLCK) { + /* + * allrecord lock not taken + */ + allrecord_ok = true; + } + + if ((m->allrecord_lock == F_RDLCK) && (rw == F_RDLCK)) { + /* + * allrecord shared lock taken, but we only want to read + */ + allrecord_ok = true; + } + + if (allrecord_ok) { + *pret = 0; + return true; + } + + ret = pthread_mutex_unlock(chain); + if (ret != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" + "(chain_mutex) failed: %s\n", strerror(ret))); + errno = ret; + goto fail; + } + ret = allrecord_mutex_lock(m, waitflag); + if (ret == EBUSY) { + ret = EAGAIN; + } + if (ret != 0) { + if (waitflag || (ret != EAGAIN)) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_%slock" + "(allrecord_mutex) failed: %s\n", + waitflag ? "" : "try_", strerror(ret))); + } + errno = ret; + goto fail; + } + ret = pthread_mutex_unlock(&m->allrecord_mutex); + if (ret != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" + "(allrecord_mutex) failed: %s\n", strerror(ret))); + errno = ret; + goto fail; + } + goto again; + +fail: + *pret = -1; + return true; +} + +bool tdb_mutex_unlock(struct tdb_context *tdb, int rw, off_t off, off_t len, + int *pret) +{ + struct tdb_mutexes *m = tdb->mutexes; + pthread_mutex_t *chain; + int ret; + unsigned idx; + + if (!tdb_mutex_index(tdb, off, len, &idx)) { + return false; + } + chain = &m->hashchains[idx]; + + ret = pthread_mutex_unlock(chain); + if (ret == 0) { + *pret = 0; + return true; + } + errno = ret; + *pret = -1; + return true; +} + +int tdb_mutex_allrecord_lock(struct tdb_context *tdb, int ltype, + enum tdb_lock_flags flags) +{ + struct tdb_mutexes *m = tdb->mutexes; + int ret; + uint32_t i; + bool waitflag = (flags & TDB_LOCK_WAIT); + int saved_errno; + + if (tdb->flags & TDB_NOLOCK) { + return 0; + } + + if (flags & TDB_LOCK_MARK_ONLY) { + return 0; + } + + ret = allrecord_mutex_lock(m, waitflag); + if (!waitflag && (ret == EBUSY)) { + errno = EAGAIN; + tdb->ecode = TDB_ERR_LOCK; + return -1; + } + if (ret != 0) { + if (!(flags & TDB_LOCK_PROBE)) { + TDB_LOG((tdb, TDB_DEBUG_TRACE, + "allrecord_mutex_lock() failed: %s\n", + strerror(ret))); + } + tdb->ecode = TDB_ERR_LOCK; + return -1; + } + + if (m->allrecord_lock != F_UNLCK) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "allrecord_lock == %d\n", + (int)m->allrecord_lock)); + goto fail_unlock_allrecord_mutex; + } + m->allrecord_lock = (ltype == F_RDLCK) ? F_RDLCK : F_WRLCK; + + for (i=0; ihash_size; i++) { + + /* ignore hashchains[0], the freelist */ + pthread_mutex_t *chain = &m->hashchains[i+1]; + + ret = chain_mutex_lock(chain, waitflag); + if (!waitflag && (ret == EBUSY)) { + errno = EAGAIN; + goto fail_unroll_allrecord_lock; + } + if (ret != 0) { + if (!(flags & TDB_LOCK_PROBE)) { + TDB_LOG((tdb, TDB_DEBUG_TRACE, + "chain_mutex_lock() failed: %s\n", + strerror(ret))); + } + errno = ret; + goto fail_unroll_allrecord_lock; + } + + ret = pthread_mutex_unlock(chain); + if (ret != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" + "(chainlock) failed: %s\n", strerror(ret))); + errno = ret; + goto fail_unroll_allrecord_lock; + } + } + /* + * We leave this routine with m->allrecord_mutex locked + */ + return 0; + +fail_unroll_allrecord_lock: + m->allrecord_lock = F_UNLCK; + +fail_unlock_allrecord_mutex: + saved_errno = errno; + ret = pthread_mutex_unlock(&m->allrecord_mutex); + if (ret != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" + "(allrecord_mutex) failed: %s\n", strerror(ret))); + } + errno = saved_errno; + tdb->ecode = TDB_ERR_LOCK; + return -1; +} + +int tdb_mutex_allrecord_upgrade(struct tdb_context *tdb) +{ + struct tdb_mutexes *m = tdb->mutexes; + int ret; + uint32_t i; + + if (tdb->flags & TDB_NOLOCK) { + return 0; + } + + /* + * Our only caller tdb_allrecord_upgrade() + * garantees that we already own the allrecord lock. + * + * Which means m->allrecord_mutex is still locked by us. + */ + + if (m->allrecord_lock != F_RDLCK) { + tdb->ecode = TDB_ERR_LOCK; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "allrecord_lock == %d\n", + (int)m->allrecord_lock)); + return -1; + } + + m->allrecord_lock = F_WRLCK; + + for (i=0; ihash_size; i++) { + + /* ignore hashchains[0], the freelist */ + pthread_mutex_t *chain = &m->hashchains[i+1]; + + ret = chain_mutex_lock(chain, true); + if (ret != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_lock" + "(chainlock) failed: %s\n", strerror(ret))); + goto fail_unroll_allrecord_lock; + } + + ret = pthread_mutex_unlock(chain); + if (ret != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" + "(chainlock) failed: %s\n", strerror(ret))); + goto fail_unroll_allrecord_lock; + } + } + + return 0; + +fail_unroll_allrecord_lock: + m->allrecord_lock = F_RDLCK; + tdb->ecode = TDB_ERR_LOCK; + return -1; +} + +void tdb_mutex_allrecord_downgrade(struct tdb_context *tdb) +{ + struct tdb_mutexes *m = tdb->mutexes; + + /* + * Our only caller tdb_allrecord_upgrade() (in the error case) + * garantees that we already own the allrecord lock. + * + * Which means m->allrecord_mutex is still locked by us. + */ + + if (m->allrecord_lock != F_WRLCK) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "allrecord_lock == %d\n", + (int)m->allrecord_lock)); + return; + } + + m->allrecord_lock = F_RDLCK; + return; +} + + +int tdb_mutex_allrecord_unlock(struct tdb_context *tdb) +{ + struct tdb_mutexes *m = tdb->mutexes; + short old; + int ret; + + if (tdb->flags & TDB_NOLOCK) { + return 0; + } + + /* + * Our only callers tdb_allrecord_unlock() and + * tdb_allrecord_lock() (in the error path) + * garantee that we already own the allrecord lock. + * + * Which means m->allrecord_mutex is still locked by us. + */ + + if ((m->allrecord_lock != F_RDLCK) && (m->allrecord_lock != F_WRLCK)) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "allrecord_lock == %d\n", + (int)m->allrecord_lock)); + return -1; + } + + old = m->allrecord_lock; + m->allrecord_lock = F_UNLCK; + + ret = pthread_mutex_unlock(&m->allrecord_mutex); + if (ret != 0) { + m->allrecord_lock = old; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" + "(allrecord_mutex) failed: %s\n", strerror(ret))); + return -1; + } + return 0; +} + +int tdb_mutex_init(struct tdb_context *tdb) +{ + struct tdb_mutexes *m; + pthread_mutexattr_t ma; + int i, ret; + + ret = tdb_mutex_mmap(tdb); + if (ret == -1) { + return -1; + } + m = tdb->mutexes; + + ret = pthread_mutexattr_init(&ma); + if (ret != 0) { + goto fail_munmap; + } + ret = pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK); + if (ret != 0) { + goto fail; + } + ret = pthread_mutexattr_setpshared(&ma, PTHREAD_PROCESS_SHARED); + if (ret != 0) { + goto fail; + } + ret = pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST); + if (ret != 0) { + goto fail; + } + + for (i=0; ihash_size+1; i++) { + pthread_mutex_t *chain = &m->hashchains[i]; + + ret = pthread_mutex_init(chain, &ma); + if (ret != 0) { + goto fail; + } + } + + m->allrecord_lock = F_UNLCK; + + ret = pthread_mutex_init(&m->allrecord_mutex, &ma); + if (ret != 0) { + goto fail; + } + ret = 0; +fail: + pthread_mutexattr_destroy(&ma); +fail_munmap: + + if (ret == 0) { + return 0; + } + + tdb_mutex_munmap(tdb); + + errno = ret; + return -1; +} + +int tdb_mutex_mmap(struct tdb_context *tdb) +{ + size_t len; + void *ptr; + + len = tdb_mutex_size(tdb); + if (len == 0) { + return 0; + } + + if (tdb->mutexes != NULL) { + return 0; + } + + ptr = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FILE, + tdb->fd, 0); + if (ptr == MAP_FAILED) { + return -1; + } + tdb->mutexes = (struct tdb_mutexes *)ptr; + + return 0; +} + +int tdb_mutex_munmap(struct tdb_context *tdb) +{ + size_t len; + int ret; + + len = tdb_mutex_size(tdb); + if (len == 0) { + return 0; + } + + ret = munmap(tdb->mutexes, len); + if (ret == -1) { + return -1; + } + tdb->mutexes = NULL; + + return 0; +} + +static bool tdb_mutex_locking_cached; + +static bool tdb_mutex_locking_supported(void) +{ + pthread_mutexattr_t ma; + pthread_mutex_t m; + int ret; + static bool initialized; + + if (initialized) { + return tdb_mutex_locking_cached; + } + + initialized = true; + + ret = pthread_mutexattr_init(&ma); + if (ret != 0) { + return false; + } + ret = pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK); + if (ret != 0) { + goto cleanup_ma; + } + ret = pthread_mutexattr_setpshared(&ma, PTHREAD_PROCESS_SHARED); + if (ret != 0) { + goto cleanup_ma; + } + ret = pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST); + if (ret != 0) { + goto cleanup_ma; + } + ret = pthread_mutex_init(&m, &ma); + if (ret != 0) { + goto cleanup_ma; + } + ret = pthread_mutex_lock(&m); + if (ret != 0) { + goto cleanup_m; + } + /* + * This makes sure we have real mutexes + * from a threading library instead of just + * stubs from libc. + */ + ret = pthread_mutex_lock(&m); + if (ret != EDEADLK) { + goto cleanup_lock; + } + ret = pthread_mutex_unlock(&m); + if (ret != 0) { + goto cleanup_m; + } + + tdb_mutex_locking_cached = true; + goto cleanup_m; + +cleanup_lock: + pthread_mutex_unlock(&m); +cleanup_m: + pthread_mutex_destroy(&m); +cleanup_ma: + pthread_mutexattr_destroy(&ma); + return tdb_mutex_locking_cached; +} + +static void (*tdb_robust_mutext_old_handler)(int) = SIG_ERR; +static pid_t tdb_robust_mutex_pid = -1; + +static bool tdb_robust_mutex_setup_sigchild(void (*handler)(int), + void (**p_old_handler)(int)) +{ +#ifdef HAVE_SIGACTION + struct sigaction act; + struct sigaction oldact; + + memset(&act, '\0', sizeof(act)); + + act.sa_handler = handler; +#ifdef SA_RESTART + act.sa_flags = SA_RESTART; +#endif + sigemptyset(&act.sa_mask); + sigaddset(&act.sa_mask, SIGCHLD); + sigaction(SIGCHLD, &act, &oldact); + if (p_old_handler) { + *p_old_handler = oldact.sa_handler; + } + return true; +#else /* !HAVE_SIGACTION */ + return false; +#endif +} + +static void tdb_robust_mutex_handler(int sig) +{ + pid_t child_pid = tdb_robust_mutex_pid; + + if (child_pid != -1) { + pid_t pid; + + pid = waitpid(child_pid, NULL, WNOHANG); + if (pid == -1) { + switch (errno) { + case ECHILD: + tdb_robust_mutex_pid = -1; + return; + + default: + return; + } + } + if (pid == child_pid) { + tdb_robust_mutex_pid = -1; + return; + } + } + + if (tdb_robust_mutext_old_handler == SIG_DFL) { + return; + } + if (tdb_robust_mutext_old_handler == SIG_IGN) { + return; + } + if (tdb_robust_mutext_old_handler == SIG_ERR) { + return; + } + + tdb_robust_mutext_old_handler(sig); +} + +static void tdb_robust_mutex_wait_for_child(pid_t *child_pid) +{ + int options = WNOHANG; + + if (*child_pid == -1) { + return; + } + + while (tdb_robust_mutex_pid > 0) { + pid_t pid; + + /* + * First we try with WNOHANG, as the process might not exist + * anymore. Once we've sent SIGKILL we block waiting for the + * exit. + */ + pid = waitpid(*child_pid, NULL, options); + if (pid == -1) { + if (errno == EINTR) { + continue; + } else if (errno == ECHILD) { + break; + } else { + abort(); + } + } + if (pid == *child_pid) { + break; + } + + kill(*child_pid, SIGKILL); + options = 0; + } + + tdb_robust_mutex_pid = -1; + *child_pid = -1; +} + +_PUBLIC_ bool tdb_runtime_check_for_robust_mutexes(void) +{ + void *ptr = NULL; + pthread_mutex_t *m = NULL; + pthread_mutexattr_t ma; + int ret = 1; + int pipe_down[2] = { -1, -1 }; + int pipe_up[2] = { -1, -1 }; + ssize_t nread; + char c = 0; + bool ok; + static bool initialized; + pid_t saved_child_pid = -1; + bool cleanup_ma = false; + + if (initialized) { + return tdb_mutex_locking_cached; + } + + initialized = true; + + ok = tdb_mutex_locking_supported(); + if (!ok) { + return false; + } + + tdb_mutex_locking_cached = false; + + ptr = mmap(NULL, sizeof(pthread_mutex_t), PROT_READ|PROT_WRITE, + MAP_SHARED|MAP_ANON, -1 /* fd */, 0); + if (ptr == MAP_FAILED) { + return false; + } + + ret = pipe(pipe_down); + if (ret != 0) { + goto cleanup; + } + ret = pipe(pipe_up); + if (ret != 0) { + goto cleanup; + } + + ret = pthread_mutexattr_init(&ma); + if (ret != 0) { + goto cleanup; + } + cleanup_ma = true; + ret = pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK); + if (ret != 0) { + goto cleanup; + } + ret = pthread_mutexattr_setpshared(&ma, PTHREAD_PROCESS_SHARED); + if (ret != 0) { + goto cleanup; + } + ret = pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST); + if (ret != 0) { + goto cleanup; + } + ret = pthread_mutex_init(ptr, &ma); + if (ret != 0) { + goto cleanup; + } + m = (pthread_mutex_t *)ptr; + + if (tdb_robust_mutex_setup_sigchild(tdb_robust_mutex_handler, + &tdb_robust_mutext_old_handler) == false) { + goto cleanup; + } + + tdb_robust_mutex_pid = fork(); + saved_child_pid = tdb_robust_mutex_pid; + if (tdb_robust_mutex_pid == 0) { + size_t nwritten; + close(pipe_down[1]); + close(pipe_up[0]); + ret = pthread_mutex_lock(m); + nwritten = write(pipe_up[1], &ret, sizeof(ret)); + if (nwritten != sizeof(ret)) { + _exit(1); + } + if (ret != 0) { + _exit(1); + } + nread = read(pipe_down[0], &c, 1); + if (nread != 1) { + _exit(1); + } + /* leave locked */ + _exit(0); + } + if (tdb_robust_mutex_pid == -1) { + goto cleanup; + } + close(pipe_down[0]); + pipe_down[0] = -1; + close(pipe_up[1]); + pipe_up[1] = -1; + + nread = read(pipe_up[0], &ret, sizeof(ret)); + if (nread != sizeof(ret)) { + goto cleanup; + } + + ret = pthread_mutex_trylock(m); + if (ret != EBUSY) { + if (ret == 0) { + pthread_mutex_unlock(m); + } + goto cleanup; + } + + if (write(pipe_down[1], &c, 1) != 1) { + goto cleanup; + } + + nread = read(pipe_up[0], &c, 1); + if (nread != 0) { + goto cleanup; + } + + tdb_robust_mutex_wait_for_child(&saved_child_pid); + + ret = pthread_mutex_trylock(m); + if (ret != EOWNERDEAD) { + if (ret == 0) { + pthread_mutex_unlock(m); + } + goto cleanup; + } + + ret = pthread_mutex_consistent(m); + if (ret != 0) { + goto cleanup; + } + + ret = pthread_mutex_trylock(m); + if (ret != EDEADLK && ret != EBUSY) { + pthread_mutex_unlock(m); + goto cleanup; + } + + ret = pthread_mutex_unlock(m); + if (ret != 0) { + goto cleanup; + } + + tdb_mutex_locking_cached = true; + +cleanup: + /* + * Note that we don't reset the signal handler we just reset + * tdb_robust_mutex_pid to -1. This is ok as this code path is only + * called once per process. + * + * Leaving our signal handler avoids races with other threads potentialy + * setting up their SIGCHLD handlers. + * + * The worst thing that can happen is that the other newer signal + * handler will get the SIGCHLD signal for our child and/or reap the + * child with a wait() function. tdb_robust_mutex_wait_for_child() + * handles the case where waitpid returns ECHILD. + */ + tdb_robust_mutex_wait_for_child(&saved_child_pid); + + if (m != NULL) { + pthread_mutex_destroy(m); + } + if (cleanup_ma) { + pthread_mutexattr_destroy(&ma); + } + if (pipe_down[0] != -1) { + close(pipe_down[0]); + } + if (pipe_down[1] != -1) { + close(pipe_down[1]); + } + if (pipe_up[0] != -1) { + close(pipe_up[0]); + } + if (pipe_up[1] != -1) { + close(pipe_up[1]); + } + if (ptr != NULL) { + munmap(ptr, sizeof(pthread_mutex_t)); + } + + return tdb_mutex_locking_cached; +} + +#else + +size_t tdb_mutex_size(struct tdb_context *tdb) +{ + return 0; +} + +bool tdb_have_mutexes(struct tdb_context *tdb) +{ + return false; +} + +int tdb_mutex_allrecord_lock(struct tdb_context *tdb, int ltype, + enum tdb_lock_flags flags) +{ + tdb->ecode = TDB_ERR_LOCK; + return -1; +} + +int tdb_mutex_allrecord_unlock(struct tdb_context *tdb) +{ + return -1; +} + +int tdb_mutex_allrecord_upgrade(struct tdb_context *tdb) +{ + tdb->ecode = TDB_ERR_LOCK; + return -1; +} + +void tdb_mutex_allrecord_downgrade(struct tdb_context *tdb) +{ + return; +} + +int tdb_mutex_mmap(struct tdb_context *tdb) +{ + errno = ENOSYS; + return -1; +} + +int tdb_mutex_munmap(struct tdb_context *tdb) +{ + errno = ENOSYS; + return -1; +} + +int tdb_mutex_init(struct tdb_context *tdb) +{ + errno = ENOSYS; + return -1; +} + +_PUBLIC_ bool tdb_runtime_check_for_robust_mutexes(void) +{ + return false; +} + +#endif diff --git a/ldb-2.0.8/lib/tdb/common/open.c b/ldb-2.0.8/lib/tdb/common/open.c new file mode 100644 index 0000000..f7f65b0 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/common/open.c @@ -0,0 +1,962 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2005 + Copyright (C) Paul `Rusty' Russell 2000 + Copyright (C) Jeremy Allison 2000-2003 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "tdb_private.h" + +/* all contexts, to ensure no double-opens (fcntl locks don't nest!) */ +static struct tdb_context *tdbs = NULL; + +/* We use two hashes to double-check they're using the right hash function. */ +void tdb_header_hash(struct tdb_context *tdb, + uint32_t *magic1_hash, uint32_t *magic2_hash) +{ + TDB_DATA hash_key; + uint32_t tdb_magic = TDB_MAGIC; + + hash_key.dptr = discard_const_p(unsigned char, TDB_MAGIC_FOOD); + hash_key.dsize = sizeof(TDB_MAGIC_FOOD); + *magic1_hash = tdb->hash_fn(&hash_key); + + hash_key.dptr = (unsigned char *)CONVERT(tdb_magic); + hash_key.dsize = sizeof(tdb_magic); + *magic2_hash = tdb->hash_fn(&hash_key); + + /* Make sure at least one hash is non-zero! */ + if (*magic1_hash == 0 && *magic2_hash == 0) + *magic1_hash = 1; +} + +/* initialise a new database with a specified hash size */ +static int tdb_new_database(struct tdb_context *tdb, struct tdb_header *header, + int hash_size) +{ + struct tdb_header *newdb; + size_t size; + int ret = -1; + + /* We make it up in memory, then write it out if not internal */ + size = sizeof(struct tdb_header) + (hash_size+1)*sizeof(tdb_off_t); + if (!(newdb = (struct tdb_header *)calloc(size, 1))) { + tdb->ecode = TDB_ERR_OOM; + return -1; + } + + /* Fill in the header */ + newdb->version = TDB_VERSION; + newdb->hash_size = hash_size; + + tdb_header_hash(tdb, &newdb->magic1_hash, &newdb->magic2_hash); + + /* Make sure older tdbs (which don't check the magic hash fields) + * will refuse to open this TDB. */ + if (tdb->flags & TDB_INCOMPATIBLE_HASH) + newdb->rwlocks = TDB_HASH_RWLOCK_MAGIC; + + /* + * We create a tdb with TDB_FEATURE_FLAG_MUTEX support, + * the flag combination and runtime feature checks + * are done by the caller already. + */ + if (tdb->flags & TDB_MUTEX_LOCKING) { + newdb->feature_flags |= TDB_FEATURE_FLAG_MUTEX; + } + + /* + * If we have any features we add the FEATURE_FLAG_MAGIC, overwriting the + * TDB_HASH_RWLOCK_MAGIC above. + */ + if (newdb->feature_flags != 0) { + newdb->rwlocks = TDB_FEATURE_FLAG_MAGIC; + } + + /* + * It's required for some following code pathes + * to have the fields on 'tdb' up-to-date. + * + * E.g. tdb_mutex_size() requires it + */ + tdb->feature_flags = newdb->feature_flags; + tdb->hash_size = newdb->hash_size; + + if (tdb->flags & TDB_INTERNAL) { + tdb->map_size = size; + tdb->map_ptr = (char *)newdb; + memcpy(header, newdb, sizeof(*header)); + /* Convert the `ondisk' version if asked. */ + CONVERT(*newdb); + return 0; + } + if (lseek(tdb->fd, 0, SEEK_SET) == -1) + goto fail; + + if (ftruncate(tdb->fd, 0) == -1) + goto fail; + + if (newdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) { + newdb->mutex_size = tdb_mutex_size(tdb); + tdb->hdr_ofs = newdb->mutex_size; + } + + /* This creates an endian-converted header, as if read from disk */ + CONVERT(*newdb); + memcpy(header, newdb, sizeof(*header)); + /* Don't endian-convert the magic food! */ + memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1); + + if (!tdb_write_all(tdb->fd, newdb, size)) + goto fail; + + if (newdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) { + + /* + * Now we init the mutex area + * followed by a second header. + */ + + ret = ftruncate( + tdb->fd, + newdb->mutex_size + sizeof(struct tdb_header)); + if (ret == -1) { + goto fail; + } + ret = tdb_mutex_init(tdb); + if (ret == -1) { + goto fail; + } + + /* + * Write a second header behind the mutexes. That's the area + * that will be mmapp'ed. + */ + ret = lseek(tdb->fd, newdb->mutex_size, SEEK_SET); + if (ret == -1) { + goto fail; + } + if (!tdb_write_all(tdb->fd, newdb, size)) { + goto fail; + } + } + + ret = 0; + fail: + SAFE_FREE(newdb); + return ret; +} + + + +static int tdb_already_open(dev_t device, + ino_t ino) +{ + struct tdb_context *i; + + for (i = tdbs; i; i = i->next) { + if (i->device == device && i->inode == ino) { + return 1; + } + } + + return 0; +} + +/* open the database, creating it if necessary + + The open_flags and mode are passed straight to the open call on the + database file. A flags value of O_WRONLY is invalid. The hash size + is advisory, use zero for a default value. + + Return is NULL on error, in which case errno is also set. Don't + try to call tdb_error or tdb_errname, just do strerror(errno). + + @param name may be NULL for internal databases. */ +_PUBLIC_ struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode) +{ + return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL, NULL); +} + +/* a default logging function */ +static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); +static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) +{ +} + +static bool check_header_hash(struct tdb_context *tdb, + struct tdb_header *header, + bool default_hash, uint32_t *m1, uint32_t *m2) +{ + tdb_header_hash(tdb, m1, m2); + if (header->magic1_hash == *m1 && + header->magic2_hash == *m2) { + return true; + } + + /* If they explicitly set a hash, always respect it. */ + if (!default_hash) + return false; + + /* Otherwise, try the other inbuilt hash. */ + if (tdb->hash_fn == tdb_old_hash) + tdb->hash_fn = tdb_jenkins_hash; + else + tdb->hash_fn = tdb_old_hash; + return check_header_hash(tdb, header, false, m1, m2); +} + +static bool tdb_mutex_open_ok(struct tdb_context *tdb, + const struct tdb_header *header) +{ + if (tdb->flags & TDB_NOLOCK) { + /* + * We don't look at locks, so it does not matter to have a + * compatible mutex implementation. Allow the open. + */ + return true; + } + + if (!(tdb->flags & TDB_MUTEX_LOCKING)) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_mutex_open_ok[%s]: " + "Can use mutexes only with " + "MUTEX_LOCKING or NOLOCK\n", + tdb->name)); + return false; + } + + if (tdb_mutex_size(tdb) != header->mutex_size) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_mutex_open_ok[%s]: " + "Mutex size changed from %"PRIu32" to %zu\n.", + tdb->name, + header->mutex_size, + tdb_mutex_size(tdb))); + return false; + } + + return true; +} + +_PUBLIC_ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode, + const struct tdb_logging_context *log_ctx, + tdb_hash_func hash_fn) +{ + int orig_errno = errno; + struct tdb_header header = { + .version = 0, + }; + struct tdb_context *tdb; + struct stat st; + int rev = 0; + bool locked = false; + unsigned char *vp; + uint32_t vertest; + unsigned v; + const char *hash_alg; + uint32_t magic1, magic2; + int ret; + + if (!(tdb = (struct tdb_context *)calloc(1, sizeof *tdb))) { + /* Can't log this */ + errno = ENOMEM; + goto fail; + } + tdb_io_init(tdb); + + if (tdb_flags & TDB_INTERNAL) { + tdb_flags |= TDB_INCOMPATIBLE_HASH; + } + if (tdb_flags & TDB_MUTEX_LOCKING) { + tdb_flags |= TDB_INCOMPATIBLE_HASH; + } + + tdb->fd = -1; +#ifdef TDB_TRACE + tdb->tracefd = -1; +#endif + tdb->name = NULL; + tdb->map_ptr = NULL; + tdb->flags = tdb_flags; + tdb->open_flags = open_flags; + if (log_ctx) { + tdb->log = *log_ctx; + } else { + tdb->log.log_fn = null_log_fn; + tdb->log.log_private = NULL; + } + + if (name == NULL && (tdb_flags & TDB_INTERNAL)) { + name = "__TDB_INTERNAL__"; + } + + if (name == NULL) { + tdb->name = discard_const_p(char, "__NULL__"); + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: called with name == NULL\n")); + tdb->name = NULL; + errno = EINVAL; + goto fail; + } + + /* now make a copy of the name, as the caller memory might go away */ + if (!(tdb->name = (char *)strdup(name))) { + /* + * set the name as the given string, so that tdb_name() will + * work in case of an error. + */ + tdb->name = discard_const_p(char, name); + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't strdup(%s)\n", + name)); + tdb->name = NULL; + errno = ENOMEM; + goto fail; + } + + if (hash_fn) { + tdb->hash_fn = hash_fn; + hash_alg = "the user defined"; + } else { + /* This controls what we use when creating a tdb. */ + if (tdb->flags & TDB_INCOMPATIBLE_HASH) { + tdb->hash_fn = tdb_jenkins_hash; + } else { + tdb->hash_fn = tdb_old_hash; + } + hash_alg = "either default"; + } + + /* cache the page size */ + tdb->page_size = getpagesize(); + if (tdb->page_size <= 0) { + tdb->page_size = 0x2000; + } + + tdb->max_dead_records = (tdb_flags & TDB_VOLATILE) ? 5 : 0; + + if ((open_flags & O_ACCMODE) == O_WRONLY) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't open tdb %s write-only\n", + name)); + errno = EINVAL; + goto fail; + } + + if (hash_size == 0) + hash_size = DEFAULT_HASH_SIZE; + if ((open_flags & O_ACCMODE) == O_RDONLY) { + tdb->read_only = 1; + /* read only databases don't do locking or clear if first */ + tdb->flags |= TDB_NOLOCK; + tdb->flags &= ~(TDB_CLEAR_IF_FIRST|TDB_MUTEX_LOCKING); + } + + if ((tdb->flags & TDB_ALLOW_NESTING) && + (tdb->flags & TDB_DISALLOW_NESTING)) { + tdb->ecode = TDB_ERR_NESTING; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " + "allow_nesting and disallow_nesting are not allowed together!")); + errno = EINVAL; + goto fail; + } + + if (tdb->flags & TDB_MUTEX_LOCKING) { + /* + * Here we catch bugs in the callers, + * the runtime check for existing tdb's comes later. + */ + + if (tdb->flags & TDB_INTERNAL) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " + "invalid flags for %s - TDB_MUTEX_LOCKING and " + "TDB_INTERNAL are not allowed together\n", name)); + errno = EINVAL; + goto fail; + } + + if (tdb->flags & TDB_NOMMAP) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " + "invalid flags for %s - TDB_MUTEX_LOCKING and " + "TDB_NOMMAP are not allowed together\n", name)); + errno = EINVAL; + goto fail; + } + + if (tdb->read_only) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " + "invalid flags for %s - TDB_MUTEX_LOCKING " + "not allowed read only\n", name)); + errno = EINVAL; + goto fail; + } + + /* + * The callers should have called + * tdb_runtime_check_for_robust_mutexes() + * before using TDB_MUTEX_LOCKING! + * + * This makes sure the caller understands + * that the locking may behave a bit differently + * than with pure fcntl locking. E.g. multiple + * read locks are not supported. + */ + if (!tdb_runtime_check_for_robust_mutexes()) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " + "invalid flags for %s - TDB_MUTEX_LOCKING " + "requires support for robust_mutexes\n", + name)); + errno = ENOSYS; + goto fail; + } + } + + if (getenv("TDB_NO_FSYNC")) { + tdb->flags |= TDB_NOSYNC; + } + + /* + * TDB_ALLOW_NESTING is the default behavior. + * Note: this may change in future versions! + */ + if (!(tdb->flags & TDB_DISALLOW_NESTING)) { + tdb->flags |= TDB_ALLOW_NESTING; + } + + /* internal databases don't mmap or lock, and start off cleared */ + if (tdb->flags & TDB_INTERNAL) { + tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP); + tdb->flags &= ~TDB_CLEAR_IF_FIRST; + if (tdb_new_database(tdb, &header, hash_size) != 0) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: tdb_new_database failed!")); + goto fail; + } + tdb->hash_size = hash_size; + goto internal; + } + + if ((tdb->fd = open(name, open_flags, mode)) == -1) { + TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_open_ex: could not open file %s: %s\n", + name, strerror(errno))); + goto fail; /* errno set by open(2) */ + } + + /* on exec, don't inherit the fd */ + v = fcntl(tdb->fd, F_GETFD, 0); + fcntl(tdb->fd, F_SETFD, v | FD_CLOEXEC); + + /* ensure there is only one process initialising at once */ + if (tdb_nest_lock(tdb, OPEN_LOCK, F_WRLCK, TDB_LOCK_WAIT) == -1) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to get open lock on %s: %s\n", + name, strerror(errno))); + goto fail; /* errno set by tdb_brlock */ + } + + /* we need to zero database if we are the only one with it open */ + if ((tdb_flags & TDB_CLEAR_IF_FIRST) && + (!tdb->read_only)) { + ret = tdb_nest_lock(tdb, ACTIVE_LOCK, F_WRLCK, + TDB_LOCK_NOWAIT|TDB_LOCK_PROBE); + locked = (ret == 0); + + if (locked) { + ret = tdb_brlock(tdb, F_WRLCK, FREELIST_TOP, 0, + TDB_LOCK_WAIT); + if (ret == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " + "tdb_brlock failed for %s: %s\n", + name, strerror(errno))); + goto fail; + } + ret = tdb_new_database(tdb, &header, hash_size); + if (ret == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " + "tdb_new_database failed for " + "%s: %s\n", name, strerror(errno))); + tdb_unlockall(tdb); + goto fail; + } + ret = tdb_brunlock(tdb, F_WRLCK, FREELIST_TOP, 0); + if (ret == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " + "tdb_unlockall failed for %s: %s\n", + name, strerror(errno))); + goto fail; + } + ret = lseek(tdb->fd, 0, SEEK_SET); + if (ret == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " + "lseek failed for %s: %s\n", + name, strerror(errno))); + goto fail; + } + } + } + + errno = 0; + if (read(tdb->fd, &header, sizeof(header)) != sizeof(header) + || strcmp(header.magic_food, TDB_MAGIC_FOOD) != 0) { + if (!(open_flags & O_CREAT) || + tdb_new_database(tdb, &header, hash_size) == -1) { + if (errno == 0) { + errno = EIO; /* ie bad format or something */ + } + goto fail; + } + rev = (tdb->flags & TDB_CONVERT); + } else if (header.version != TDB_VERSION + && !(rev = (header.version==TDB_BYTEREV(TDB_VERSION)))) { + /* wrong version */ + errno = EIO; + goto fail; + } + vp = (unsigned char *)&header.version; + vertest = (((uint32_t)vp[0]) << 24) | (((uint32_t)vp[1]) << 16) | + (((uint32_t)vp[2]) << 8) | (uint32_t)vp[3]; + tdb->flags |= (vertest==TDB_VERSION) ? TDB_BIGENDIAN : 0; + if (!rev) + tdb->flags &= ~TDB_CONVERT; + else { + tdb->flags |= TDB_CONVERT; + tdb_convert(&header, sizeof(header)); + } + + /* + * We only use st.st_dev and st.st_ino from the raw fstat() + * call, everything else needs to use tdb_fstat() in order + * to skip tdb->hdr_ofs! + */ + if (fstat(tdb->fd, &st) == -1) { + goto fail; + } + tdb->device = st.st_dev; + tdb->inode = st.st_ino; + ZERO_STRUCT(st); + + if (header.rwlocks != 0 && + header.rwlocks != TDB_FEATURE_FLAG_MAGIC && + header.rwlocks != TDB_HASH_RWLOCK_MAGIC) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: spinlocks no longer supported\n")); + errno = ENOSYS; + goto fail; + } + + if (header.hash_size == 0) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: invalid database: 0 hash_size\n")); + errno = ENOSYS; + goto fail; + } + + tdb->hash_size = header.hash_size; + + if (header.rwlocks == TDB_FEATURE_FLAG_MAGIC) { + tdb->feature_flags = header.feature_flags; + } + + if (tdb->feature_flags & ~TDB_SUPPORTED_FEATURE_FLAGS) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: unsupported " + "features in tdb %s: 0x%08x (supported: 0x%08x)\n", + name, (unsigned)tdb->feature_flags, + (unsigned)TDB_SUPPORTED_FEATURE_FLAGS)); + errno = ENOSYS; + goto fail; + } + + if (tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) { + if (!tdb_mutex_open_ok(tdb, &header)) { + errno = EINVAL; + goto fail; + } + + /* + * We need to remember the hdr_ofs + * also for the TDB_NOLOCK case + * if the current library doesn't support + * mutex locking. + */ + tdb->hdr_ofs = header.mutex_size; + + if ((!(tdb_flags & TDB_CLEAR_IF_FIRST)) && (!tdb->read_only)) { + /* + * Open an existing mutexed tdb, but without + * CLEAR_IF_FIRST. We need to initialize the + * mutex array and keep the CLEAR_IF_FIRST + * lock locked. + */ + ret = tdb_nest_lock(tdb, ACTIVE_LOCK, F_WRLCK, + TDB_LOCK_NOWAIT|TDB_LOCK_PROBE); + locked = (ret == 0); + + if (locked) { + ret = tdb_mutex_init(tdb); + if (ret == -1) { + TDB_LOG((tdb, + TDB_DEBUG_FATAL, + "tdb_open_ex: tdb_mutex_init " + "failed for ""%s: %s\n", + name, strerror(errno))); + goto fail; + } + } + } + } + + if ((header.magic1_hash == 0) && (header.magic2_hash == 0)) { + /* older TDB without magic hash references */ + tdb->hash_fn = tdb_old_hash; + } else if (!check_header_hash(tdb, &header, !hash_fn, + &magic1, &magic2)) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " + "%s was not created with %s hash function we are using\n" + "magic1_hash[0x%08X %s 0x%08X] " + "magic2_hash[0x%08X %s 0x%08X]\n", + name, hash_alg, + header.magic1_hash, + (header.magic1_hash == magic1) ? "==" : "!=", + magic1, + header.magic2_hash, + (header.magic2_hash == magic2) ? "==" : "!=", + magic2)); + errno = EINVAL; + goto fail; + } + + /* Is it already in the open list? If so, fail. */ + if (tdb_already_open(tdb->device, tdb->inode)) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " + "%s (%d,%d) is already open in this process\n", + name, (int)tdb->device, (int)tdb->inode)); + errno = EBUSY; + goto fail; + } + + /* + * We had tdb_mmap(tdb) here before, + * but we need to use tdb_fstat(), + * which is triggered from tdb_oob() before calling tdb_mmap(). + * As this skips tdb->hdr_ofs. + */ + tdb->map_size = 0; + ret = tdb_oob(tdb, 0, 1, 0); + if (ret == -1) { + errno = EIO; + goto fail; + } + + if (tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) { + if (!(tdb->flags & TDB_NOLOCK)) { + ret = tdb_mutex_mmap(tdb); + if (ret != 0) { + goto fail; + } + } + } + + if (tdb->hash_size > UINT32_MAX/4) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " + "hash size %"PRIu32" too large\n", tdb->hash_size)); + errno = EINVAL; + goto fail; + } + + ret = tdb_oob(tdb, FREELIST_TOP, 4*tdb->hash_size, 1); + if (ret == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " + "hash size %"PRIu32" does not fit\n", tdb->hash_size)); + errno = EINVAL; + goto fail; + } + + if (locked) { + if (tdb_nest_unlock(tdb, ACTIVE_LOCK, F_WRLCK, false) == -1) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " + "failed to release ACTIVE_LOCK on %s: %s\n", + name, strerror(errno))); + goto fail; + } + + + } + + if (locked || (tdb_flags & TDB_CLEAR_IF_FIRST)) { + /* + * We always need to do this if the CLEAR_IF_FIRST + * flag is set, even if we didn't get the initial + * exclusive lock as we need to let all other users + * know we're using it. + */ + + ret = tdb_nest_lock(tdb, ACTIVE_LOCK, F_RDLCK, TDB_LOCK_WAIT); + if (ret == -1) { + goto fail; + } + } + + /* if needed, run recovery */ + if (tdb_transaction_recover(tdb) == -1) { + goto fail; + } + +#ifdef TDB_TRACE + { + char tracefile[strlen(name) + 32]; + + snprintf(tracefile, sizeof(tracefile), + "%s.trace.%li", name, (long)getpid()); + tdb->tracefd = open(tracefile, O_WRONLY|O_CREAT|O_EXCL, 0600); + if (tdb->tracefd >= 0) { + tdb_enable_seqnum(tdb); + tdb_trace_open(tdb, "tdb_open", hash_size, tdb_flags, + open_flags); + } else + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to open trace file %s!\n", tracefile)); + } +#endif + + internal: + /* Internal (memory-only) databases skip all the code above to + * do with disk files, and resume here by releasing their + * open lock and hooking into the active list. */ + if (tdb_nest_unlock(tdb, OPEN_LOCK, F_WRLCK, false) == -1) { + goto fail; + } + tdb->next = tdbs; + tdbs = tdb; + errno = orig_errno; + return tdb; + + fail: + { int save_errno = errno; + + if (!tdb) + return NULL; + +#ifdef TDB_TRACE + close(tdb->tracefd); +#endif + if (tdb->map_ptr) { + if (tdb->flags & TDB_INTERNAL) + SAFE_FREE(tdb->map_ptr); + else + tdb_munmap(tdb); + } + if (tdb->fd != -1) + if (close(tdb->fd) != 0) + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to close tdb->fd on error!\n")); + SAFE_FREE(tdb->lockrecs); + SAFE_FREE(tdb->name); + SAFE_FREE(tdb); + errno = save_errno; + return NULL; + } +} + +/* + * Set the maximum number of dead records per hash chain + */ + +_PUBLIC_ void tdb_set_max_dead(struct tdb_context *tdb, int max_dead) +{ + tdb->max_dead_records = max_dead; +} + +/** + * Close a database. + * + * @returns -1 for error; 0 for success. + **/ +_PUBLIC_ int tdb_close(struct tdb_context *tdb) +{ + struct tdb_context **i; + int ret = 0; + + if (tdb->transaction) { + tdb_transaction_cancel(tdb); + } + tdb_trace(tdb, "tdb_close"); + + if (tdb->map_ptr) { + if (tdb->flags & TDB_INTERNAL) + SAFE_FREE(tdb->map_ptr); + else + tdb_munmap(tdb); + } + + tdb_mutex_munmap(tdb); + + SAFE_FREE(tdb->name); + if (tdb->fd != -1) { + ret = close(tdb->fd); + tdb->fd = -1; + } + SAFE_FREE(tdb->lockrecs); + + /* Remove from contexts list */ + for (i = &tdbs; *i; i = &(*i)->next) { + if (*i == tdb) { + *i = tdb->next; + break; + } + } + +#ifdef TDB_TRACE + close(tdb->tracefd); +#endif + memset(tdb, 0, sizeof(*tdb)); + SAFE_FREE(tdb); + + return ret; +} + +/* register a loging function */ +_PUBLIC_ void tdb_set_logging_function(struct tdb_context *tdb, + const struct tdb_logging_context *log_ctx) +{ + tdb->log = *log_ctx; +} + +_PUBLIC_ void *tdb_get_logging_private(struct tdb_context *tdb) +{ + return tdb->log.log_private; +} + +static int tdb_reopen_internal(struct tdb_context *tdb, bool active_lock) +{ +#if !defined(LIBREPLACE_PREAD_NOT_REPLACED) || \ + !defined(LIBREPLACE_PWRITE_NOT_REPLACED) + struct stat st; +#endif + + if (tdb->flags & TDB_INTERNAL) { + return 0; /* Nothing to do. */ + } + + if (tdb_have_extra_locks(tdb)) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed with locks held\n")); + goto fail; + } + + if (tdb->transaction != 0) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed inside a transaction\n")); + goto fail; + } + +/* If we have real pread & pwrite, we can skip reopen. */ +#if !defined(LIBREPLACE_PREAD_NOT_REPLACED) || \ + !defined(LIBREPLACE_PWRITE_NOT_REPLACED) + if (tdb_munmap(tdb) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: munmap failed (%s)\n", strerror(errno))); + goto fail; + } + if (close(tdb->fd) != 0) + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: WARNING closing tdb->fd failed!\n")); + tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0); + if (tdb->fd == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: open failed (%s)\n", strerror(errno))); + goto fail; + } + /* + * We only use st.st_dev and st.st_ino from the raw fstat() + * call, everything else needs to use tdb_fstat() in order + * to skip tdb->hdr_ofs! + */ + if (fstat(tdb->fd, &st) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: fstat failed (%s)\n", strerror(errno))); + goto fail; + } + if (st.st_ino != tdb->inode || st.st_dev != tdb->device) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: file dev/inode has changed!\n")); + goto fail; + } + ZERO_STRUCT(st); + + /* + * We had tdb_mmap(tdb) here before, + * but we need to use tdb_fstat(), + * which is triggered from tdb_oob() before calling tdb_mmap(). + * As this skips tdb->hdr_ofs. + */ + tdb->map_size = 0; + if (tdb_oob(tdb, 0, 1, 0) != 0) { + goto fail; + } +#endif /* fake pread or pwrite */ + + /* We may still think we hold the active lock. */ + tdb->num_lockrecs = 0; + SAFE_FREE(tdb->lockrecs); + tdb->lockrecs_array_length = 0; + + if (active_lock && tdb_nest_lock(tdb, ACTIVE_LOCK, F_RDLCK, TDB_LOCK_WAIT) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: failed to obtain active lock\n")); + goto fail; + } + + return 0; + +fail: + tdb_close(tdb); + return -1; +} + +/* reopen a tdb - this can be used after a fork to ensure that we have an independent + seek pointer from our parent and to re-establish locks */ +_PUBLIC_ int tdb_reopen(struct tdb_context *tdb) +{ + bool active_lock; + active_lock = (tdb->flags & (TDB_CLEAR_IF_FIRST|TDB_MUTEX_LOCKING)); + + return tdb_reopen_internal(tdb, active_lock); +} + +/* reopen all tdb's */ +_PUBLIC_ int tdb_reopen_all(int parent_longlived) +{ + struct tdb_context *tdb; + + for (tdb=tdbs; tdb; tdb = tdb->next) { + bool active_lock; + + active_lock = + (tdb->flags & (TDB_CLEAR_IF_FIRST|TDB_MUTEX_LOCKING)); + + /* + * If the parent is longlived (ie. a + * parent daemon architecture), we know + * it will keep it's active lock on a + * tdb opened with CLEAR_IF_FIRST. Thus + * for child processes we don't have to + * add an active lock. This is essential + * to improve performance on systems that + * keep POSIX locks as a non-scalable data + * structure in the kernel. + */ + if (parent_longlived) { + /* Ensure no clear-if-first. */ + active_lock = false; + } + + if (tdb_reopen_internal(tdb, active_lock) != 0) + return -1; + } + + return 0; +} diff --git a/ldb-2.0.8/lib/tdb/common/rescue.c b/ldb-2.0.8/lib/tdb/common/rescue.c new file mode 100644 index 0000000..7a85ebc --- /dev/null +++ b/ldb-2.0.8/lib/tdb/common/rescue.c @@ -0,0 +1,351 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library, rescue attempt code. + + Copyright (C) Rusty Russell 2012 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ +#include "tdb_private.h" +#include + + +struct found { + tdb_off_t head; /* 0 -> invalid. */ + struct tdb_record rec; + TDB_DATA key; + bool in_hash; + bool in_free; +}; + +struct found_table { + /* As an ordered array (by head offset). */ + struct found *arr; + unsigned int num, max; +}; + +static bool looks_like_valid_record(struct tdb_context *tdb, + tdb_off_t off, + const struct tdb_record *rec, + TDB_DATA *key) +{ + unsigned int hval; + + if (rec->magic != TDB_MAGIC) + return false; + + if (rec->key_len + rec->data_len > rec->rec_len) + return false; + + if (rec->rec_len % TDB_ALIGNMENT) + return false; + + /* Next pointer must make some sense. */ + if (rec->next > 0 && rec->next < TDB_DATA_START(tdb->hash_size)) + return false; + + if (tdb_oob(tdb, rec->next, sizeof(*rec), 1)) + return false; + + key->dsize = rec->key_len; + key->dptr = tdb_alloc_read(tdb, off + sizeof(*rec), key->dsize); + if (!key->dptr) + return false; + + hval = tdb->hash_fn(key); + if (hval != rec->full_hash) { + free(key->dptr); + return false; + } + + /* Caller frees up key->dptr */ + return true; +} + +static bool add_to_table(struct found_table *found, + tdb_off_t off, + struct tdb_record *rec, + TDB_DATA key) +{ + if (found->num + 1 > found->max) { + struct found *new; + found->max = (found->max ? found->max * 2 : 128); + new = realloc(found->arr, found->max * sizeof(found->arr[0])); + if (!new) + return false; + found->arr = new; + } + + found->arr[found->num].head = off; + found->arr[found->num].rec = *rec; + found->arr[found->num].key = key; + found->arr[found->num].in_hash = false; + found->arr[found->num].in_free = false; + + found->num++; + return true; +} + +static bool walk_record(struct tdb_context *tdb, + const struct found *f, + void (*walk)(TDB_DATA, TDB_DATA, void *private_data), + void *private_data) +{ + TDB_DATA data; + + data.dsize = f->rec.data_len; + data.dptr = tdb_alloc_read(tdb, + f->head + sizeof(f->rec) + f->rec.key_len, + data.dsize); + if (!data.dptr) { + if (tdb->ecode == TDB_ERR_OOM) + return false; + /* I/O errors are expected. */ + return true; + } + + walk(f->key, data, private_data); + free(data.dptr); + return true; +} + +/* First entry which has offset >= this one. */ +static unsigned int find_entry(struct found_table *found, tdb_off_t off) +{ + unsigned int start = 0, end = found->num; + + while (start < end) { + /* We can't overflow here. */ + unsigned int mid = (start + end) / 2; + + if (off < found->arr[mid].head) { + end = mid; + } else if (off > found->arr[mid].head) { + start = mid + 1; + } else { + return mid; + } + } + + assert(start == end); + return end; +} + +static void found_in_hashchain(struct found_table *found, tdb_off_t head) +{ + unsigned int match; + + match = find_entry(found, head); + if (match < found->num && found->arr[match].head == head) { + found->arr[match].in_hash = true; + } +} + +static void mark_free_area(struct found_table *found, tdb_off_t head, + tdb_len_t len) +{ + unsigned int match; + + match = find_entry(found, head); + /* Mark everything within this free entry. */ + while (match < found->num) { + if (found->arr[match].head >= head + len) { + break; + } + found->arr[match].in_free = true; + match++; + } +} + +static int cmp_key(const void *a, const void *b) +{ + const struct found *fa = a, *fb = b; + + if (fa->key.dsize < fb->key.dsize) { + return -1; + } else if (fa->key.dsize > fb->key.dsize) { + return 1; + } + return memcmp(fa->key.dptr, fb->key.dptr, fa->key.dsize); +} + +static bool key_eq(TDB_DATA a, TDB_DATA b) +{ + return a.dsize == b.dsize + && memcmp(a.dptr, b.dptr, a.dsize) == 0; +} + +static void free_table(struct found_table *found) +{ + unsigned int i; + + for (i = 0; i < found->num; i++) { + free(found->arr[i].key.dptr); + } + free(found->arr); +} + +static void logging_suppressed(struct tdb_context *tdb, + enum tdb_debug_level level, const char *fmt, ...) +{ +} + +_PUBLIC_ int tdb_rescue(struct tdb_context *tdb, + void (*walk)(TDB_DATA, TDB_DATA, void *private_data), + void *private_data) +{ + struct found_table found = { NULL, 0, 0 }; + tdb_off_t h, off, i; + tdb_log_func oldlog = tdb->log.log_fn; + struct tdb_record rec; + TDB_DATA key; + bool locked; + + /* Read-only databases use no locking at all: it's best-effort. + * We may have a write lock already, so skip that case too. */ + if (tdb->read_only || tdb->allrecord_lock.count != 0) { + locked = false; + } else { + if (tdb_lockall_read(tdb) == -1) + return -1; + locked = true; + } + + /* Make sure we know true size of the underlying file. */ + tdb_oob(tdb, tdb->map_size, 1, 1); + + /* Suppress logging, since we anticipate errors. */ + tdb->log.log_fn = logging_suppressed; + + /* Now walk entire db looking for records. */ + for (off = TDB_DATA_START(tdb->hash_size); + off < tdb->map_size; + off += TDB_ALIGNMENT) { + if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), + DOCONV()) == -1) + continue; + + if (looks_like_valid_record(tdb, off, &rec, &key)) { + if (!add_to_table(&found, off, &rec, key)) { + goto oom; + } + } + } + + /* Walk hash chains to positive vet. */ + for (h = 0; h < 1+tdb->hash_size; h++) { + bool slow_chase = false; + tdb_off_t slow_off = FREELIST_TOP + h*sizeof(tdb_off_t); + + if (tdb_ofs_read(tdb, FREELIST_TOP + h*sizeof(tdb_off_t), + &off) == -1) + continue; + + while (off && off != slow_off) { + if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), + DOCONV()) != 0) { + break; + } + + /* 0 is the free list, rest are hash chains. */ + if (h == 0) { + /* Don't mark garbage as free. */ + if (rec.magic != TDB_FREE_MAGIC) { + break; + } + mark_free_area(&found, off, + sizeof(rec) + rec.rec_len); + } else { + found_in_hashchain(&found, off); + } + + off = rec.next; + + /* Loop detection using second pointer at half-speed */ + if (slow_chase) { + /* First entry happens to be next ptr */ + tdb_ofs_read(tdb, slow_off, &slow_off); + } + slow_chase = !slow_chase; + } + } + + /* Recovery area: must be marked as free, since it often has old + * records in there! */ + if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &off) == 0 && off != 0) { + if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), + DOCONV()) == 0) { + mark_free_area(&found, off, sizeof(rec) + rec.rec_len); + } + } + + /* Now sort by key! */ + if (found.arr != NULL) { + qsort(found.arr, found.num, sizeof(found.arr[0]), cmp_key); + } + + for (i = 0; (found.arr != NULL) && i < found.num; ) { + unsigned int num, num_in_hash = 0; + + /* How many are identical? */ + for (num = 0; num < found.num - i; num++) { + if (!key_eq(found.arr[i].key, found.arr[i+num].key)) { + break; + } + if (found.arr[i+num].in_hash) { + if (!walk_record(tdb, &found.arr[i+num], + walk, private_data)) + goto oom; + num_in_hash++; + } + } + assert(num); + + /* If none were in the hash, we print any not in free list. */ + if (num_in_hash == 0) { + unsigned int j; + + for (j = i; j < i + num; j++) { + if (!found.arr[j].in_free) { + if (!walk_record(tdb, &found.arr[j], + walk, private_data)) + goto oom; + } + } + } + + i += num; + } + + tdb->log.log_fn = oldlog; + if (locked) { + tdb_unlockall_read(tdb); + } + return 0; + +oom: + tdb->log.log_fn = oldlog; + tdb->ecode = TDB_ERR_OOM; + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_rescue: failed allocating\n")); + free_table(&found); + if (locked) { + tdb_unlockall_read(tdb); + } + return -1; +} diff --git a/ldb-2.0.8/lib/tdb/common/summary.c b/ldb-2.0.8/lib/tdb/common/summary.c new file mode 100644 index 0000000..a93eb93 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/common/summary.c @@ -0,0 +1,219 @@ + /* + Trivial Database: human-readable summary code + Copyright (C) Rusty Russell 2010 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ +#include "tdb_private.h" + +#define SUMMARY_FORMAT \ + "Size of file/data: %llu/%zu\n" \ + "Header offset/logical size: %zu/%zu\n" \ + "Number of records: %zu\n" \ + "Incompatible hash: %s\n" \ + "Active/supported feature flags: 0x%08x/0x%08x\n" \ + "Robust mutexes locking: %s\n" \ + "Smallest/average/largest keys: %zu/%zu/%zu\n" \ + "Smallest/average/largest data: %zu/%zu/%zu\n" \ + "Smallest/average/largest padding: %zu/%zu/%zu\n" \ + "Number of dead records: %zu\n" \ + "Smallest/average/largest dead records: %zu/%zu/%zu\n" \ + "Number of free records: %zu\n" \ + "Smallest/average/largest free records: %zu/%zu/%zu\n" \ + "Number of hash chains: %zu\n" \ + "Smallest/average/largest hash chains: %zu/%zu/%zu\n" \ + "Number of uncoalesced records: %zu\n" \ + "Smallest/average/largest uncoalesced runs: %zu/%zu/%zu\n" \ + "Percentage keys/data/padding/free/dead/rechdrs&tailers/hashes: %.0f/%.0f/%.0f/%.0f/%.0f/%.0f/%.0f\n" + +/* We don't use tally module, to keep upstream happy. */ +struct tally { + size_t min, max, total; + size_t num; +}; + +static void tally_init(struct tally *tally) +{ + tally->total = 0; + tally->num = 0; + tally->min = tally->max = 0; +} + +static void tally_add(struct tally *tally, size_t len) +{ + if (tally->num == 0) + tally->max = tally->min = len; + else if (len > tally->max) + tally->max = len; + else if (len < tally->min) + tally->min = len; + tally->num++; + tally->total += len; +} + +static size_t tally_mean(const struct tally *tally) +{ + if (!tally->num) + return 0; + return tally->total / tally->num; +} + +static size_t get_hash_length(struct tdb_context *tdb, unsigned int i) +{ + tdb_off_t rec_ptr; + struct tdb_chainwalk_ctx chainwalk; + size_t count = 0; + + if (tdb_ofs_read(tdb, TDB_HASH_TOP(i), &rec_ptr) == -1) + return 0; + + tdb_chainwalk_init(&chainwalk, rec_ptr); + + /* keep looking until we find the right record */ + while (rec_ptr) { + struct tdb_record r; + bool ok; + ++count; + if (tdb_rec_read(tdb, rec_ptr, &r) == -1) + return 0; + rec_ptr = r.next; + ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); + if (!ok) { + return SIZE_MAX; + } + } + return count; +} + +_PUBLIC_ char *tdb_summary(struct tdb_context *tdb) +{ + off_t file_size; + tdb_off_t off, rec_off; + struct tally freet, keys, data, dead, extra, hashval, uncoal; + struct tdb_record rec; + char *ret = NULL; + bool locked; + size_t unc = 0; + int len; + struct tdb_record recovery; + + /* Read-only databases use no locking at all: it's best-effort. + * We may have a write lock already, so skip that case too. */ + if (tdb->read_only || tdb->allrecord_lock.count != 0) { + locked = false; + } else { + if (tdb_lockall_read(tdb) == -1) + return NULL; + locked = true; + } + + if (tdb_recovery_area(tdb, tdb->methods, &rec_off, &recovery) != 0) { + goto unlock; + } + + tally_init(&freet); + tally_init(&keys); + tally_init(&data); + tally_init(&dead); + tally_init(&extra); + tally_init(&hashval); + tally_init(&uncoal); + + for (off = TDB_DATA_START(tdb->hash_size); + off < tdb->map_size - 1; + off += sizeof(rec) + rec.rec_len) { + if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), + DOCONV()) == -1) + goto unlock; + switch (rec.magic) { + case TDB_MAGIC: + tally_add(&keys, rec.key_len); + tally_add(&data, rec.data_len); + tally_add(&extra, rec.rec_len - (rec.key_len + + rec.data_len)); + if (unc > 1) + tally_add(&uncoal, unc - 1); + unc = 0; + break; + case TDB_FREE_MAGIC: + tally_add(&freet, rec.rec_len); + unc++; + break; + /* If we crash after ftruncate, we can get zeroes or fill. */ + case TDB_RECOVERY_INVALID_MAGIC: + case 0x42424242: + unc++; + /* If it's a valid recovery, we can trust rec_len. */ + if (off != rec_off) { + rec.rec_len = tdb_dead_space(tdb, off) + - sizeof(rec); + } + + FALL_THROUGH; + case TDB_DEAD_MAGIC: + tally_add(&dead, rec.rec_len); + break; + default: + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "Unexpected record magic 0x%x at offset %u\n", + rec.magic, off)); + goto unlock; + } + } + if (unc > 1) + tally_add(&uncoal, unc - 1); + + for (off = 0; off < tdb->hash_size; off++) + tally_add(&hashval, get_hash_length(tdb, off)); + + file_size = tdb->hdr_ofs + tdb->map_size; + + len = asprintf(&ret, SUMMARY_FORMAT, + (unsigned long long)file_size, keys.total+data.total, + (size_t)tdb->hdr_ofs, (size_t)tdb->map_size, + keys.num, + (tdb->hash_fn == tdb_jenkins_hash)?"yes":"no", + (unsigned)tdb->feature_flags, TDB_SUPPORTED_FEATURE_FLAGS, + (tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX)?"yes":"no", + keys.min, tally_mean(&keys), keys.max, + data.min, tally_mean(&data), data.max, + extra.min, tally_mean(&extra), extra.max, + dead.num, + dead.min, tally_mean(&dead), dead.max, + freet.num, + freet.min, tally_mean(&freet), freet.max, + hashval.num, + hashval.min, tally_mean(&hashval), hashval.max, + uncoal.total, + uncoal.min, tally_mean(&uncoal), uncoal.max, + keys.total * 100.0 / file_size, + data.total * 100.0 / file_size, + extra.total * 100.0 / file_size, + freet.total * 100.0 / file_size, + dead.total * 100.0 / file_size, + (keys.num + freet.num + dead.num) + * (sizeof(struct tdb_record) + sizeof(uint32_t)) + * 100.0 / file_size, + tdb->hash_size * sizeof(tdb_off_t) + * 100.0 / file_size); + if (len == -1) { + goto unlock; + } + +unlock: + if (locked) { + tdb_unlockall_read(tdb); + } + return ret; +} diff --git a/ldb-2.0.8/lib/tdb/common/tdb.c b/ldb-2.0.8/lib/tdb/common/tdb.c new file mode 100644 index 0000000..c56b37b --- /dev/null +++ b/ldb-2.0.8/lib/tdb/common/tdb.c @@ -0,0 +1,1324 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2005 + Copyright (C) Paul `Rusty' Russell 2000 + Copyright (C) Jeremy Allison 2000-2003 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "tdb_private.h" + +_PUBLIC_ TDB_DATA tdb_null; + +/* + non-blocking increment of the tdb sequence number if the tdb has been opened using + the TDB_SEQNUM flag +*/ +_PUBLIC_ void tdb_increment_seqnum_nonblock(struct tdb_context *tdb) +{ + tdb_off_t seqnum=0; + + if (!(tdb->flags & TDB_SEQNUM)) { + return; + } + + /* we ignore errors from this, as we have no sane way of + dealing with them. + */ + tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum); + seqnum++; + tdb_ofs_write(tdb, TDB_SEQNUM_OFS, &seqnum); +} + +/* + increment the tdb sequence number if the tdb has been opened using + the TDB_SEQNUM flag +*/ +static void tdb_increment_seqnum(struct tdb_context *tdb) +{ + if (!(tdb->flags & TDB_SEQNUM)) { + return; + } + + if (tdb->transaction != NULL) { + tdb_increment_seqnum_nonblock(tdb); + return; + } + + if (tdb_nest_lock(tdb, TDB_SEQNUM_OFS, F_WRLCK, + TDB_LOCK_WAIT|TDB_LOCK_PROBE) != 0) { + return; + } + + tdb_increment_seqnum_nonblock(tdb); + + tdb_nest_unlock(tdb, TDB_SEQNUM_OFS, F_WRLCK, false); +} + +static int tdb_key_compare(TDB_DATA key, TDB_DATA data, void *private_data) +{ + return memcmp(data.dptr, key.dptr, data.dsize); +} + +void tdb_chainwalk_init(struct tdb_chainwalk_ctx *ctx, tdb_off_t ptr) +{ + *ctx = (struct tdb_chainwalk_ctx) { .slow_ptr = ptr }; +} + +bool tdb_chainwalk_check(struct tdb_context *tdb, + struct tdb_chainwalk_ctx *ctx, + tdb_off_t next_ptr) +{ + int ret; + + if (ctx->slow_chase) { + ret = tdb_ofs_read(tdb, ctx->slow_ptr, &ctx->slow_ptr); + if (ret == -1) { + return false; + } + } + ctx->slow_chase = !ctx->slow_chase; + + if (next_ptr == ctx->slow_ptr) { + tdb->ecode = TDB_ERR_CORRUPT; + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "tdb_chainwalk_check: circular chain\n")); + return false; + } + + return true; +} + +/* Returns 0 on fail. On success, return offset of record, and fills + in rec */ +static tdb_off_t tdb_find(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, + struct tdb_record *r) +{ + tdb_off_t rec_ptr; + struct tdb_chainwalk_ctx chainwalk; + + /* read in the hash top */ + if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) + return 0; + + tdb_chainwalk_init(&chainwalk, rec_ptr); + + /* keep looking until we find the right record */ + while (rec_ptr) { + bool ok; + + if (tdb_rec_read(tdb, rec_ptr, r) == -1) + return 0; + + if (!TDB_DEAD(r) && hash==r->full_hash + && key.dsize==r->key_len + && tdb_parse_data(tdb, key, rec_ptr + sizeof(*r), + r->key_len, tdb_key_compare, + NULL) == 0) { + return rec_ptr; + } + rec_ptr = r->next; + + ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); + if (!ok) { + return 0; + } + } + tdb->ecode = TDB_ERR_NOEXIST; + return 0; +} + +/* As tdb_find, but if you succeed, keep the lock */ +tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype, + struct tdb_record *rec) +{ + uint32_t rec_ptr; + + if (tdb_lock(tdb, BUCKET(hash), locktype) == -1) + return 0; + if (!(rec_ptr = tdb_find(tdb, key, hash, rec))) + tdb_unlock(tdb, BUCKET(hash), locktype); + return rec_ptr; +} + +static TDB_DATA _tdb_fetch(struct tdb_context *tdb, TDB_DATA key); + +struct tdb_update_hash_state { + const TDB_DATA *dbufs; + int num_dbufs; + tdb_len_t dbufs_len; +}; + +static int tdb_update_hash_cmp(TDB_DATA key, TDB_DATA data, void *private_data) +{ + struct tdb_update_hash_state *state = private_data; + unsigned char *dptr = data.dptr; + int i; + + if (state->dbufs_len != data.dsize) { + return -1; + } + + for (i=0; inum_dbufs; i++) { + TDB_DATA dbuf = state->dbufs[i]; + if( dbuf.dsize > 0) { + int ret; + ret = memcmp(dptr, dbuf.dptr, dbuf.dsize); + if (ret != 0) { + return -1; + } + dptr += dbuf.dsize; + } + } + + return 0; +} + +/* update an entry in place - this only works if the new data size + is <= the old data size and the key exists. + on failure return -1. +*/ +static int tdb_update_hash(struct tdb_context *tdb, TDB_DATA key, + uint32_t hash, + const TDB_DATA *dbufs, int num_dbufs, + tdb_len_t dbufs_len) +{ + struct tdb_record rec; + tdb_off_t rec_ptr, ofs; + int i; + + /* find entry */ + if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) + return -1; + + /* it could be an exact duplicate of what is there - this is + * surprisingly common (eg. with a ldb re-index). */ + if (rec.data_len == dbufs_len) { + struct tdb_update_hash_state state = { + .dbufs = dbufs, .num_dbufs = num_dbufs, + .dbufs_len = dbufs_len + }; + int ret; + + ret = tdb_parse_record(tdb, key, tdb_update_hash_cmp, &state); + if (ret == 0) { + return 0; + } + } + + /* must be long enough key, data and tailer */ + if (rec.rec_len < key.dsize + dbufs_len + sizeof(tdb_off_t)) { + tdb->ecode = TDB_SUCCESS; /* Not really an error */ + return -1; + } + + ofs = rec_ptr + sizeof(rec) + rec.key_len; + + for (i=0; imethods->tdb_write(tdb, ofs, dbuf.dptr, dbuf.dsize); + if (ret == -1) { + return -1; + } + ofs += dbuf.dsize; + } + + if (dbufs_len != rec.data_len) { + /* update size */ + rec.data_len = dbufs_len; + return tdb_rec_write(tdb, rec_ptr, &rec); + } + + return 0; +} + +/* find an entry in the database given a key */ +/* If an entry doesn't exist tdb_err will be set to + * TDB_ERR_NOEXIST. If a key has no data attached + * then the TDB_DATA will have zero length but + * a non-zero pointer + */ +static TDB_DATA _tdb_fetch(struct tdb_context *tdb, TDB_DATA key) +{ + tdb_off_t rec_ptr; + struct tdb_record rec; + TDB_DATA ret; + uint32_t hash; + + /* find which hash bucket it is in */ + hash = tdb->hash_fn(&key); + if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) + return tdb_null; + + ret.dptr = tdb_alloc_read(tdb, rec_ptr + sizeof(rec) + rec.key_len, + rec.data_len); + ret.dsize = rec.data_len; + tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); + return ret; +} + +_PUBLIC_ TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key) +{ + TDB_DATA ret = _tdb_fetch(tdb, key); + + tdb_trace_1rec_retrec(tdb, "tdb_fetch", key, ret); + return ret; +} + +/* + * Find an entry in the database and hand the record's data to a parsing + * function. The parsing function is executed under the chain read lock, so it + * should be fast and should not block on other syscalls. + * + * DON'T CALL OTHER TDB CALLS FROM THE PARSER, THIS MIGHT LEAD TO SEGFAULTS. + * + * For mmapped tdb's that do not have a transaction open it points the parsing + * function directly at the mmap area, it avoids the malloc/memcpy in this + * case. If a transaction is open or no mmap is available, it has to do + * malloc/read/parse/free. + * + * This is interesting for all readers of potentially large data structures in + * the tdb records, ldb indexes being one example. + * + * Return -1 if the record was not found. + */ + +_PUBLIC_ int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, + int (*parser)(TDB_DATA key, TDB_DATA data, + void *private_data), + void *private_data) +{ + tdb_off_t rec_ptr; + struct tdb_record rec; + int ret; + uint32_t hash; + + /* find which hash bucket it is in */ + hash = tdb->hash_fn(&key); + + if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) { + /* record not found */ + tdb_trace_1rec_ret(tdb, "tdb_parse_record", key, -1); + tdb->ecode = TDB_ERR_NOEXIST; + return -1; + } + tdb_trace_1rec_ret(tdb, "tdb_parse_record", key, 0); + + ret = tdb_parse_data(tdb, key, rec_ptr + sizeof(rec) + rec.key_len, + rec.data_len, parser, private_data); + + tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); + + return ret; +} + +/* check if an entry in the database exists + + note that 1 is returned if the key is found and 0 is returned if not found + this doesn't match the conventions in the rest of this module, but is + compatible with gdbm +*/ +static int tdb_exists_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash) +{ + struct tdb_record rec; + + if (tdb_find_lock_hash(tdb, key, hash, F_RDLCK, &rec) == 0) + return 0; + tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); + return 1; +} + +_PUBLIC_ int tdb_exists(struct tdb_context *tdb, TDB_DATA key) +{ + uint32_t hash = tdb->hash_fn(&key); + int ret; + + ret = tdb_exists_hash(tdb, key, hash); + tdb_trace_1rec_ret(tdb, "tdb_exists", key, ret); + return ret; +} + +/* + * Move a dead record to the freelist. The hash chain and freelist + * must be locked. + */ +static int tdb_del_dead(struct tdb_context *tdb, + uint32_t last_ptr, + uint32_t rec_ptr, + struct tdb_record *rec, + bool *deleted) +{ + int ret; + + ret = tdb_write_lock_record(tdb, rec_ptr); + if (ret == -1) { + /* Someone traversing here: Just leave it dead */ + return 0; + } + ret = tdb_write_unlock_record(tdb, rec_ptr); + if (ret == -1) { + return -1; + } + ret = tdb_ofs_write(tdb, last_ptr, &rec->next); + if (ret == -1) { + return -1; + } + + *deleted = true; + + ret = tdb_free(tdb, rec_ptr, rec); + return ret; +} + +/* + * Walk the hash chain and leave tdb->max_dead_records around. Move + * the rest of dead records to the freelist. + */ +int tdb_trim_dead(struct tdb_context *tdb, uint32_t hash) +{ + struct tdb_chainwalk_ctx chainwalk; + struct tdb_record rec; + tdb_off_t last_ptr, rec_ptr; + bool locked_freelist = false; + int num_dead = 0; + int ret; + + last_ptr = TDB_HASH_TOP(hash); + + /* + * Init chainwalk with the pointer to the hash top. It might + * be that the very first record in the chain is a dead one + * that we have to delete. + */ + tdb_chainwalk_init(&chainwalk, last_ptr); + + ret = tdb_ofs_read(tdb, last_ptr, &rec_ptr); + if (ret == -1) { + return -1; + } + + while (rec_ptr != 0) { + bool deleted = false; + uint32_t next; + + ret = tdb_rec_read(tdb, rec_ptr, &rec); + if (ret == -1) { + goto fail; + } + + /* + * Make a copy of rec.next: Further down we might + * delete and put the record on the freelist. Make + * sure that modifications in that code path can't + * break the chainwalk here. + */ + next = rec.next; + + if (rec.magic == TDB_DEAD_MAGIC) { + num_dead += 1; + + if (num_dead > tdb->max_dead_records) { + + if (!locked_freelist) { + /* + * Lock the freelist only if + * it's really required. + */ + ret = tdb_lock(tdb, -1, F_WRLCK); + if (ret == -1) { + goto fail; + }; + locked_freelist = true; + } + + ret = tdb_del_dead( + tdb, + last_ptr, + rec_ptr, + &rec, + &deleted); + + if (ret == -1) { + goto fail; + } + } + } + + /* + * Don't do the chainwalk check if "rec_ptr" was + * deleted. We reduced the chain, and the chainwalk + * check might catch up early. Imagine a valid chain + * with just dead records: We never can bump the + * "slow" pointer in chainwalk_check, as there isn't + * anything left to jump to and compare. + */ + if (!deleted) { + bool ok; + + last_ptr = rec_ptr; + + ok = tdb_chainwalk_check(tdb, &chainwalk, next); + if (!ok) { + ret = -1; + goto fail; + } + } + rec_ptr = next; + } + ret = 0; +fail: + if (locked_freelist) { + tdb_unlock(tdb, -1, F_WRLCK); + } + return ret; +} + +/* delete an entry in the database given a key */ +static int tdb_delete_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash) +{ + tdb_off_t rec_ptr; + struct tdb_record rec; + int ret; + + if (tdb->read_only || tdb->traverse_read) { + tdb->ecode = TDB_ERR_RDONLY; + return -1; + } + + rec_ptr = tdb_find_lock_hash(tdb, key, hash, F_WRLCK, &rec); + if (rec_ptr == 0) { + return -1; + } + + /* + * Mark the record dead + */ + rec.magic = TDB_DEAD_MAGIC; + ret = tdb_rec_write(tdb, rec_ptr, &rec); + if (ret == -1) { + goto done; + } + + tdb_increment_seqnum(tdb); + + ret = tdb_trim_dead(tdb, hash); +done: + if (tdb_unlock(tdb, BUCKET(hash), F_WRLCK) != 0) + TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_delete: WARNING tdb_unlock failed!\n")); + return ret; +} + +_PUBLIC_ int tdb_delete(struct tdb_context *tdb, TDB_DATA key) +{ + uint32_t hash = tdb->hash_fn(&key); + int ret; + + ret = tdb_delete_hash(tdb, key, hash); + tdb_trace_1rec_ret(tdb, "tdb_delete", key, ret); + return ret; +} + +/* + * See if we have a dead record around with enough space + */ +tdb_off_t tdb_find_dead(struct tdb_context *tdb, uint32_t hash, + struct tdb_record *r, tdb_len_t length, + tdb_off_t *p_last_ptr) +{ + tdb_off_t rec_ptr, last_ptr; + struct tdb_chainwalk_ctx chainwalk; + tdb_off_t best_rec_ptr = 0; + tdb_off_t best_last_ptr = 0; + struct tdb_record best = { .rec_len = UINT32_MAX }; + + length += sizeof(tdb_off_t); /* tailer */ + + last_ptr = TDB_HASH_TOP(hash); + + /* read in the hash top */ + if (tdb_ofs_read(tdb, last_ptr, &rec_ptr) == -1) + return 0; + + tdb_chainwalk_init(&chainwalk, rec_ptr); + + /* keep looking until we find the right record */ + while (rec_ptr) { + bool ok; + + if (tdb_rec_read(tdb, rec_ptr, r) == -1) + return 0; + + if (TDB_DEAD(r) && (r->rec_len >= length) && + (r->rec_len < best.rec_len)) { + best_rec_ptr = rec_ptr; + best_last_ptr = last_ptr; + best = *r; + } + last_ptr = rec_ptr; + rec_ptr = r->next; + + ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); + if (!ok) { + return 0; + } + } + + if (best.rec_len == UINT32_MAX) { + return 0; + } + + *r = best; + *p_last_ptr = best_last_ptr; + return best_rec_ptr; +} + +static int _tdb_storev(struct tdb_context *tdb, TDB_DATA key, + const TDB_DATA *dbufs, int num_dbufs, + int flag, uint32_t hash) +{ + struct tdb_record rec; + tdb_off_t rec_ptr, ofs; + tdb_len_t rec_len, dbufs_len; + int i; + int ret = -1; + + dbufs_len = 0; + + for (i=0; iecode = TDB_ERR_EINVAL; + goto fail; + } + + dbufs_len += dsize; + if (dbufs_len < dsize) { + tdb->ecode = TDB_ERR_OOM; + goto fail; + } + } + + rec_len = key.dsize + dbufs_len; + if ((rec_len < key.dsize) || (rec_len < dbufs_len)) { + tdb->ecode = TDB_ERR_OOM; + goto fail; + } + + /* check for it existing, on insert. */ + if (flag == TDB_INSERT) { + if (tdb_exists_hash(tdb, key, hash)) { + tdb->ecode = TDB_ERR_EXISTS; + goto fail; + } + } else { + /* first try in-place update, on modify or replace. */ + if (tdb_update_hash(tdb, key, hash, dbufs, num_dbufs, + dbufs_len) == 0) { + goto done; + } + if (tdb->ecode == TDB_ERR_NOEXIST && + flag == TDB_MODIFY) { + /* if the record doesn't exist and we are in TDB_MODIFY mode then + we should fail the store */ + goto fail; + } + } + /* reset the error code potentially set by the tdb_update_hash() */ + tdb->ecode = TDB_SUCCESS; + + /* delete any existing record - if it doesn't exist we don't + care. Doing this first reduces fragmentation, and avoids + coalescing with `allocated' block before it's updated. */ + if (flag != TDB_INSERT) + tdb_delete_hash(tdb, key, hash); + + /* we have to allocate some space */ + rec_ptr = tdb_allocate(tdb, hash, rec_len, &rec); + + if (rec_ptr == 0) { + goto fail; + } + + /* Read hash top into next ptr */ + if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1) + goto fail; + + rec.key_len = key.dsize; + rec.data_len = dbufs_len; + rec.full_hash = hash; + rec.magic = TDB_MAGIC; + + ofs = rec_ptr; + + /* write out and point the top of the hash chain at it */ + ret = tdb_rec_write(tdb, ofs, &rec); + if (ret == -1) { + goto fail; + } + ofs += sizeof(rec); + + ret = tdb->methods->tdb_write(tdb, ofs, key.dptr, key.dsize); + if (ret == -1) { + goto fail; + } + ofs += key.dsize; + + for (i=0; imethods->tdb_write(tdb, ofs, dbufs[i].dptr, + dbufs[i].dsize); + if (ret == -1) { + goto fail; + } + ofs += dbufs[i].dsize; + } + + ret = tdb_ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr); + if (ret == -1) { + /* Need to tdb_unallocate() here */ + goto fail; + } + + done: + ret = 0; + fail: + if (ret == 0) { + tdb_increment_seqnum(tdb); + } + return ret; +} + +static int _tdb_store(struct tdb_context *tdb, TDB_DATA key, + TDB_DATA dbuf, int flag, uint32_t hash) +{ + return _tdb_storev(tdb, key, &dbuf, 1, flag, hash); +} + +/* store an element in the database, replacing any existing element + with the same key + + return 0 on success, -1 on failure +*/ +_PUBLIC_ int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) +{ + uint32_t hash; + int ret; + + if (tdb->read_only || tdb->traverse_read) { + tdb->ecode = TDB_ERR_RDONLY; + tdb_trace_2rec_flag_ret(tdb, "tdb_store", key, dbuf, flag, -1); + return -1; + } + + /* find which hash bucket it is in */ + hash = tdb->hash_fn(&key); + if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) + return -1; + + ret = _tdb_store(tdb, key, dbuf, flag, hash); + tdb_trace_2rec_flag_ret(tdb, "tdb_store", key, dbuf, flag, ret); + tdb_unlock(tdb, BUCKET(hash), F_WRLCK); + return ret; +} + +_PUBLIC_ int tdb_storev(struct tdb_context *tdb, TDB_DATA key, + const TDB_DATA *dbufs, int num_dbufs, int flag) +{ + uint32_t hash; + int ret; + + if (tdb->read_only || tdb->traverse_read) { + tdb->ecode = TDB_ERR_RDONLY; + tdb_trace_1plusn_rec_flag_ret(tdb, "tdb_storev", key, + dbufs, num_dbufs, flag, -1); + return -1; + } + + /* find which hash bucket it is in */ + hash = tdb->hash_fn(&key); + if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) + return -1; + + ret = _tdb_storev(tdb, key, dbufs, num_dbufs, flag, hash); + tdb_trace_1plusn_rec_flag_ret(tdb, "tdb_storev", key, + dbufs, num_dbufs, flag, -1); + tdb_unlock(tdb, BUCKET(hash), F_WRLCK); + return ret; +} + +/* Append to an entry. Create if not exist. */ +_PUBLIC_ int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf) +{ + uint32_t hash; + TDB_DATA dbufs[2]; + int ret = -1; + + /* find which hash bucket it is in */ + hash = tdb->hash_fn(&key); + if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) + return -1; + + dbufs[0] = _tdb_fetch(tdb, key); + dbufs[1] = new_dbuf; + + ret = _tdb_storev(tdb, key, dbufs, 2, 0, hash); + tdb_trace_2rec_retrec(tdb, "tdb_append", key, dbufs[0], dbufs[1]); + + tdb_unlock(tdb, BUCKET(hash), F_WRLCK); + SAFE_FREE(dbufs[0].dptr); + return ret; +} + + +/* + return the name of the current tdb file + useful for external logging functions +*/ +_PUBLIC_ const char *tdb_name(struct tdb_context *tdb) +{ + return tdb->name; +} + +/* + return the underlying file descriptor being used by tdb, or -1 + useful for external routines that want to check the device/inode + of the fd +*/ +_PUBLIC_ int tdb_fd(struct tdb_context *tdb) +{ + return tdb->fd; +} + +/* + return the current logging function + useful for external tdb routines that wish to log tdb errors +*/ +_PUBLIC_ tdb_log_func tdb_log_fn(struct tdb_context *tdb) +{ + return tdb->log.log_fn; +} + + +/* + get the tdb sequence number. Only makes sense if the writers opened + with TDB_SEQNUM set. Note that this sequence number will wrap quite + quickly, so it should only be used for a 'has something changed' + test, not for code that relies on the count of the number of changes + made. If you want a counter then use a tdb record. + + The aim of this sequence number is to allow for a very lightweight + test of a possible tdb change. +*/ +_PUBLIC_ int tdb_get_seqnum(struct tdb_context *tdb) +{ + tdb_off_t seqnum=0; + + tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum); + return seqnum; +} + +_PUBLIC_ int tdb_hash_size(struct tdb_context *tdb) +{ + return tdb->hash_size; +} + +_PUBLIC_ size_t tdb_map_size(struct tdb_context *tdb) +{ + return tdb->map_size; +} + +_PUBLIC_ int tdb_get_flags(struct tdb_context *tdb) +{ + return tdb->flags; +} + +_PUBLIC_ void tdb_add_flags(struct tdb_context *tdb, unsigned flags) +{ + if ((flags & TDB_ALLOW_NESTING) && + (flags & TDB_DISALLOW_NESTING)) { + tdb->ecode = TDB_ERR_NESTING; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_add_flags: " + "allow_nesting and disallow_nesting are not allowed together!")); + return; + } + + if (flags & TDB_ALLOW_NESTING) { + tdb->flags &= ~TDB_DISALLOW_NESTING; + } + if (flags & TDB_DISALLOW_NESTING) { + tdb->flags &= ~TDB_ALLOW_NESTING; + } + + tdb->flags |= flags; +} + +_PUBLIC_ void tdb_remove_flags(struct tdb_context *tdb, unsigned flags) +{ + if ((flags & TDB_ALLOW_NESTING) && + (flags & TDB_DISALLOW_NESTING)) { + tdb->ecode = TDB_ERR_NESTING; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_remove_flags: " + "allow_nesting and disallow_nesting are not allowed together!")); + return; + } + + if ((flags & TDB_NOLOCK) && + (tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) && + (tdb->mutexes == NULL)) { + tdb->ecode = TDB_ERR_LOCK; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_remove_flags: " + "Can not remove NOLOCK flag on mutexed databases")); + return; + } + + if (flags & TDB_ALLOW_NESTING) { + tdb->flags |= TDB_DISALLOW_NESTING; + } + if (flags & TDB_DISALLOW_NESTING) { + tdb->flags |= TDB_ALLOW_NESTING; + } + + tdb->flags &= ~flags; +} + + +/* + enable sequence number handling on an open tdb +*/ +_PUBLIC_ void tdb_enable_seqnum(struct tdb_context *tdb) +{ + tdb->flags |= TDB_SEQNUM; +} + + +/* + add a region of the file to the freelist. Length is the size of the region in bytes, + which includes the free list header that needs to be added + */ +static int tdb_free_region(struct tdb_context *tdb, tdb_off_t offset, ssize_t length) +{ + struct tdb_record rec; + if (length <= sizeof(rec)) { + /* the region is not worth adding */ + return 0; + } + if (length + offset > tdb->map_size) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_free_region: adding region beyond end of file\n")); + return -1; + } + memset(&rec,'\0',sizeof(rec)); + rec.rec_len = length - sizeof(rec); + if (tdb_free(tdb, offset, &rec) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_free_region: failed to add free record\n")); + return -1; + } + return 0; +} + +/* + wipe the entire database, deleting all records. This can be done + very fast by using a allrecord lock. The entire data portion of the + file becomes a single entry in the freelist. + + This code carefully steps around the recovery area, leaving it alone + */ +_PUBLIC_ int tdb_wipe_all(struct tdb_context *tdb) +{ + uint32_t i; + tdb_off_t offset = 0; + ssize_t data_len; + tdb_off_t recovery_head; + tdb_len_t recovery_size = 0; + + if (tdb_lockall(tdb) != 0) { + return -1; + } + + tdb_trace(tdb, "tdb_wipe_all"); + + /* see if the tdb has a recovery area, and remember its size + if so. We don't want to lose this as otherwise each + tdb_wipe_all() in a transaction will increase the size of + the tdb by the size of the recovery area */ + if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_wipe_all: failed to read recovery head\n")); + goto failed; + } + + if (recovery_head != 0) { + struct tdb_record rec; + if (tdb->methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_wipe_all: failed to read recovery record\n")); + return -1; + } + recovery_size = rec.rec_len + sizeof(rec); + } + + /* wipe the hashes */ + for (i=0;ihash_size;i++) { + if (tdb_ofs_write(tdb, TDB_HASH_TOP(i), &offset) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write hash %d\n", i)); + goto failed; + } + } + + /* wipe the freelist */ + if (tdb_ofs_write(tdb, FREELIST_TOP, &offset) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write freelist\n")); + goto failed; + } + + /* add all the rest of the file to the freelist, possibly leaving a gap + for the recovery area */ + if (recovery_size == 0) { + /* the simple case - the whole file can be used as a freelist */ + data_len = (tdb->map_size - TDB_DATA_START(tdb->hash_size)); + if (tdb_free_region(tdb, TDB_DATA_START(tdb->hash_size), data_len) != 0) { + goto failed; + } + } else { + /* we need to add two freelist entries - one on either + side of the recovery area + + Note that we cannot shift the recovery area during + this operation. Only the transaction.c code may + move the recovery area or we risk subtle data + corruption + */ + data_len = (recovery_head - TDB_DATA_START(tdb->hash_size)); + if (tdb_free_region(tdb, TDB_DATA_START(tdb->hash_size), data_len) != 0) { + goto failed; + } + /* and the 2nd free list entry after the recovery area - if any */ + data_len = tdb->map_size - (recovery_head+recovery_size); + if (tdb_free_region(tdb, recovery_head+recovery_size, data_len) != 0) { + goto failed; + } + } + + tdb_increment_seqnum_nonblock(tdb); + + if (tdb_unlockall(tdb) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to unlock\n")); + goto failed; + } + + return 0; + +failed: + tdb_unlockall(tdb); + return -1; +} + +struct traverse_state { + bool error; + struct tdb_context *dest_db; +}; + +/* + traverse function for repacking + */ +static int repack_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private_data) +{ + struct traverse_state *state = (struct traverse_state *)private_data; + if (tdb_store(state->dest_db, key, data, TDB_INSERT) != 0) { + state->error = true; + return -1; + } + return 0; +} + +/* + repack a tdb + */ +_PUBLIC_ int tdb_repack(struct tdb_context *tdb) +{ + struct tdb_context *tmp_db; + struct traverse_state state; + + tdb_trace(tdb, "tdb_repack"); + + if (tdb_transaction_start(tdb) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to start transaction\n")); + return -1; + } + + tmp_db = tdb_open("tmpdb", tdb_hash_size(tdb), TDB_INTERNAL, O_RDWR|O_CREAT, 0); + if (tmp_db == NULL) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to create tmp_db\n")); + tdb_transaction_cancel(tdb); + return -1; + } + + state.error = false; + state.dest_db = tmp_db; + + if (tdb_traverse_read(tdb, repack_traverse, &state) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to traverse copying out\n")); + tdb_transaction_cancel(tdb); + tdb_close(tmp_db); + return -1; + } + + if (state.error) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Error during traversal\n")); + tdb_transaction_cancel(tdb); + tdb_close(tmp_db); + return -1; + } + + if (tdb_wipe_all(tdb) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to wipe database\n")); + tdb_transaction_cancel(tdb); + tdb_close(tmp_db); + return -1; + } + + state.error = false; + state.dest_db = tdb; + + if (tdb_traverse_read(tmp_db, repack_traverse, &state) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to traverse copying back\n")); + tdb_transaction_cancel(tdb); + tdb_close(tmp_db); + return -1; + } + + if (state.error) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Error during second traversal\n")); + tdb_transaction_cancel(tdb); + tdb_close(tmp_db); + return -1; + } + + tdb_close(tmp_db); + + if (tdb_transaction_commit(tdb) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to commit\n")); + return -1; + } + + return 0; +} + +/* Even on files, we can get partial writes due to signals. */ +bool tdb_write_all(int fd, const void *buf, size_t count) +{ + while (count) { + ssize_t ret; + ret = write(fd, buf, count); + if (ret < 0) + return false; + buf = (const char *)buf + ret; + count -= ret; + } + return true; +} + +bool tdb_add_off_t(tdb_off_t a, tdb_off_t b, tdb_off_t *pret) +{ + tdb_off_t ret = a + b; + + if ((ret < a) || (ret < b)) { + return false; + } + *pret = ret; + return true; +} + +#ifdef TDB_TRACE +static void tdb_trace_write(struct tdb_context *tdb, const char *str) +{ + if (!tdb_write_all(tdb->tracefd, str, strlen(str))) { + close(tdb->tracefd); + tdb->tracefd = -1; + } +} + +static void tdb_trace_start(struct tdb_context *tdb) +{ + tdb_off_t seqnum=0; + char msg[sizeof(tdb_off_t) * 4 + 1]; + + tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum); + snprintf(msg, sizeof(msg), "%u ", seqnum); + tdb_trace_write(tdb, msg); +} + +static void tdb_trace_end(struct tdb_context *tdb) +{ + tdb_trace_write(tdb, "\n"); +} + +static void tdb_trace_end_ret(struct tdb_context *tdb, int ret) +{ + char msg[sizeof(ret) * 4 + 4]; + snprintf(msg, sizeof(msg), " = %i\n", ret); + tdb_trace_write(tdb, msg); +} + +static void tdb_trace_record(struct tdb_context *tdb, TDB_DATA rec) +{ + char msg[20 + rec.dsize*2], *p; + unsigned int i; + + /* We differentiate zero-length records from non-existent ones. */ + if (rec.dptr == NULL) { + tdb_trace_write(tdb, " NULL"); + return; + } + + /* snprintf here is purely cargo-cult programming. */ + p = msg; + p += snprintf(p, sizeof(msg), " %zu:", rec.dsize); + for (i = 0; i < rec.dsize; i++) + p += snprintf(p, 2, "%02x", rec.dptr[i]); + + tdb_trace_write(tdb, msg); +} + +void tdb_trace(struct tdb_context *tdb, const char *op) +{ + tdb_trace_start(tdb); + tdb_trace_write(tdb, op); + tdb_trace_end(tdb); +} + +void tdb_trace_seqnum(struct tdb_context *tdb, uint32_t seqnum, const char *op) +{ + char msg[sizeof(tdb_off_t) * 4 + 1]; + + snprintf(msg, sizeof(msg), "%u ", seqnum); + tdb_trace_write(tdb, msg); + tdb_trace_write(tdb, op); + tdb_trace_end(tdb); +} + +void tdb_trace_open(struct tdb_context *tdb, const char *op, + unsigned hash_size, unsigned tdb_flags, unsigned open_flags) +{ + char msg[128]; + + snprintf(msg, sizeof(msg), + "%s %u 0x%x 0x%x", op, hash_size, tdb_flags, open_flags); + tdb_trace_start(tdb); + tdb_trace_write(tdb, msg); + tdb_trace_end(tdb); +} + +void tdb_trace_ret(struct tdb_context *tdb, const char *op, int ret) +{ + tdb_trace_start(tdb); + tdb_trace_write(tdb, op); + tdb_trace_end_ret(tdb, ret); +} + +void tdb_trace_retrec(struct tdb_context *tdb, const char *op, TDB_DATA ret) +{ + tdb_trace_start(tdb); + tdb_trace_write(tdb, op); + tdb_trace_write(tdb, " ="); + tdb_trace_record(tdb, ret); + tdb_trace_end(tdb); +} + +void tdb_trace_1rec(struct tdb_context *tdb, const char *op, + TDB_DATA rec) +{ + tdb_trace_start(tdb); + tdb_trace_write(tdb, op); + tdb_trace_record(tdb, rec); + tdb_trace_end(tdb); +} + +void tdb_trace_1rec_ret(struct tdb_context *tdb, const char *op, + TDB_DATA rec, int ret) +{ + tdb_trace_start(tdb); + tdb_trace_write(tdb, op); + tdb_trace_record(tdb, rec); + tdb_trace_end_ret(tdb, ret); +} + +void tdb_trace_1rec_retrec(struct tdb_context *tdb, const char *op, + TDB_DATA rec, TDB_DATA ret) +{ + tdb_trace_start(tdb); + tdb_trace_write(tdb, op); + tdb_trace_record(tdb, rec); + tdb_trace_write(tdb, " ="); + tdb_trace_record(tdb, ret); + tdb_trace_end(tdb); +} + +void tdb_trace_2rec_flag_ret(struct tdb_context *tdb, const char *op, + TDB_DATA rec1, TDB_DATA rec2, unsigned flag, + int ret) +{ + char msg[1 + sizeof(ret) * 4]; + + snprintf(msg, sizeof(msg), " %#x", flag); + tdb_trace_start(tdb); + tdb_trace_write(tdb, op); + tdb_trace_record(tdb, rec1); + tdb_trace_record(tdb, rec2); + tdb_trace_write(tdb, msg); + tdb_trace_end_ret(tdb, ret); +} + +void tdb_trace_1plusn_rec_flag_ret(struct tdb_context *tdb, const char *op, + TDB_DATA rec, + const TDB_DATA *recs, int num_recs, + unsigned flag, int ret) +{ + char msg[1 + sizeof(ret) * 4]; + int i; + + snprintf(msg, sizeof(msg), " %#x", flag); + tdb_trace_start(tdb); + tdb_trace_write(tdb, op); + tdb_trace_record(tdb, rec); + for (i=0; if) +#endif + +#define TDB_MAGIC_FOOD "TDB file\n" +#define TDB_VERSION (0x26011967 + 6) +#define TDB_MAGIC (0x26011999U) +#define TDB_FREE_MAGIC (~TDB_MAGIC) +#define TDB_DEAD_MAGIC (0xFEE1DEAD) +#define TDB_RECOVERY_MAGIC (0xf53bc0e7U) +#define TDB_RECOVERY_INVALID_MAGIC (0x0) +#define TDB_HASH_RWLOCK_MAGIC (0xbad1a51U) +#define TDB_FEATURE_FLAG_MAGIC (0xbad1a52U) +#define TDB_ALIGNMENT 4 +#define DEFAULT_HASH_SIZE 131 +#define FREELIST_TOP (sizeof(struct tdb_header)) +#define TDB_ALIGN(x,a) (((x) + (a)-1) & ~((a)-1)) +#define TDB_BYTEREV(x) (((((x)&0xff)<<24)|((x)&0xFF00)<<8)|(((x)>>8)&0xFF00)|((x)>>24)) +#define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC) +#define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r)) +#define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off_t)) +#define TDB_HASHTABLE_SIZE(tdb) ((tdb->hash_size+1)*sizeof(tdb_off_t)) +#define TDB_DATA_START(hash_size) (TDB_HASH_TOP(hash_size-1) + sizeof(tdb_off_t)) +#define TDB_RECOVERY_HEAD offsetof(struct tdb_header, recovery_start) +#define TDB_SEQNUM_OFS offsetof(struct tdb_header, sequence_number) +#define TDB_PAD_BYTE 0x42 +#define TDB_PAD_U32 0x42424242 + +#define TDB_FEATURE_FLAG_MUTEX 0x00000001 + +#define TDB_SUPPORTED_FEATURE_FLAGS ( \ + TDB_FEATURE_FLAG_MUTEX | \ + 0) + +/* NB assumes there is a local variable called "tdb" that is the + * current context, also takes doubly-parenthesized print-style + * argument. */ +#define TDB_LOG(x) tdb->log.log_fn x + +#ifdef TDB_TRACE +void tdb_trace(struct tdb_context *tdb, const char *op); +void tdb_trace_seqnum(struct tdb_context *tdb, uint32_t seqnum, const char *op); +void tdb_trace_open(struct tdb_context *tdb, const char *op, + unsigned hash_size, unsigned tdb_flags, unsigned open_flags); +void tdb_trace_ret(struct tdb_context *tdb, const char *op, int ret); +void tdb_trace_retrec(struct tdb_context *tdb, const char *op, TDB_DATA ret); +void tdb_trace_1rec(struct tdb_context *tdb, const char *op, + TDB_DATA rec); +void tdb_trace_1rec_ret(struct tdb_context *tdb, const char *op, + TDB_DATA rec, int ret); +void tdb_trace_1rec_retrec(struct tdb_context *tdb, const char *op, + TDB_DATA rec, TDB_DATA ret); +void tdb_trace_2rec_flag_ret(struct tdb_context *tdb, const char *op, + TDB_DATA rec1, TDB_DATA rec2, unsigned flag, + int ret); +void tdb_trace_1plusn_rec_flag_ret(struct tdb_context *tdb, const char *op, + TDB_DATA rec, + const TDB_DATA *recs, int num_recs, + unsigned flag, int ret); +void tdb_trace_2rec_retrec(struct tdb_context *tdb, const char *op, + TDB_DATA rec1, TDB_DATA rec2, TDB_DATA ret); +#else +#define tdb_trace(tdb, op) +#define tdb_trace_seqnum(tdb, seqnum, op) +#define tdb_trace_open(tdb, op, hash_size, tdb_flags, open_flags) +#define tdb_trace_ret(tdb, op, ret) +#define tdb_trace_retrec(tdb, op, ret) +#define tdb_trace_1rec(tdb, op, rec) +#define tdb_trace_1rec_ret(tdb, op, rec, ret) +#define tdb_trace_1rec_retrec(tdb, op, rec, ret) +#define tdb_trace_2rec_flag_ret(tdb, op, rec1, rec2, flag, ret) +#define tdb_trace_1plusn_rec_flag_ret(tdb, op, rec, recs, num_recs, flag, ret); +#define tdb_trace_2rec_retrec(tdb, op, rec1, rec2, ret) +#endif /* !TDB_TRACE */ + +/* lock offsets */ +#define OPEN_LOCK 0 +#define ACTIVE_LOCK 4 +#define TRANSACTION_LOCK 8 + +/* free memory if the pointer is valid and zero the pointer */ +#ifndef SAFE_FREE +#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0) +#endif + +/* + * Note: the BUCKET macro is broken as it returns an unexpected result when + * called as BUCKET(-1) for the freelist: + * + * -1 is sign converted to an unsigned int 4294967295 and then the modulo + * tdb->hashtable_size is computed. So with a hashtable_size of 10 the result + * is + * + * 4294967295 % hashtable_size = 5. + * + * where it should be -1 (C uses symmetric modulo). + * + * As all callers will lock the same wrong list consistently locking is still + * consistent. We can not change this without an incompatible on-disk format + * change, otherwise different tdb versions would use incompatible locking. + */ +#define BUCKET(hash) ((hash) % tdb->hash_size) + +#define DOCONV() (tdb->flags & TDB_CONVERT) +#define CONVERT(x) (DOCONV() ? tdb_convert(&x, sizeof(x)) : &x) + + +/* the body of the database is made of one tdb_record for the free space + plus a separate data list for each hash value */ +struct tdb_record { + tdb_off_t next; /* offset of the next record in the list */ + tdb_len_t rec_len; /* total byte length of record */ + tdb_len_t key_len; /* byte length of key */ + tdb_len_t data_len; /* byte length of data */ + uint32_t full_hash; /* the full 32 bit hash of the key */ + uint32_t magic; /* try to catch errors */ + /* the following union is implied: + union { + char record[rec_len]; + struct { + char key[key_len]; + char data[data_len]; + } + uint32_t totalsize; (tailer) + } + */ +}; + + +/* this is stored at the front of every database */ +struct tdb_header { + char magic_food[32]; /* for /etc/magic */ + uint32_t version; /* version of the code */ + uint32_t hash_size; /* number of hash entries */ + tdb_off_t rwlocks; /* obsolete - kept to detect old formats */ + tdb_off_t recovery_start; /* offset of transaction recovery region */ + tdb_off_t sequence_number; /* used when TDB_SEQNUM is set */ + uint32_t magic1_hash; /* hash of TDB_MAGIC_FOOD. */ + uint32_t magic2_hash; /* hash of TDB_MAGIC. */ + uint32_t feature_flags; + tdb_len_t mutex_size; /* set if TDB_FEATURE_FLAG_MUTEX is set */ + tdb_off_t reserved[25]; +}; + +struct tdb_lock_type { + uint32_t off; + uint32_t count; + uint32_t ltype; +}; + +struct tdb_chainwalk_ctx { + tdb_off_t slow_ptr; + bool slow_chase; +}; + +struct tdb_traverse_lock { + struct tdb_traverse_lock *next; + uint32_t off; + uint32_t list; + int lock_rw; +}; + +void tdb_chainwalk_init(struct tdb_chainwalk_ctx *ctx, tdb_off_t ptr); +bool tdb_chainwalk_check(struct tdb_context *tdb, + struct tdb_chainwalk_ctx *ctx, + tdb_off_t next_ptr); + +enum tdb_lock_flags { + /* WAIT == F_SETLKW, NOWAIT == F_SETLK */ + TDB_LOCK_NOWAIT = 0, + TDB_LOCK_WAIT = 1, + /* If set, don't log an error on failure. */ + TDB_LOCK_PROBE = 2, + /* If set, don't actually lock at all. */ + TDB_LOCK_MARK_ONLY = 4, +}; + +struct tdb_methods { + int (*tdb_read)(struct tdb_context *, tdb_off_t , void *, tdb_len_t , int ); + int (*tdb_write)(struct tdb_context *, tdb_off_t, const void *, tdb_len_t); + void (*next_hash_chain)(struct tdb_context *, uint32_t *); + int (*tdb_oob)(struct tdb_context *, tdb_off_t , tdb_len_t, int ); + int (*tdb_expand_file)(struct tdb_context *, tdb_off_t , tdb_off_t ); +}; + +struct tdb_mutexes; + +struct tdb_context { + char *name; /* the name of the database */ + void *map_ptr; /* where it is currently mapped */ + int fd; /* open file descriptor for the database */ + tdb_len_t map_size; /* how much space has been mapped */ + int read_only; /* opened read-only */ + int traverse_read; /* read-only traversal */ + int traverse_write; /* read-write traversal */ + struct tdb_lock_type allrecord_lock; /* .offset == upgradable */ + int num_lockrecs; + struct tdb_lock_type *lockrecs; /* only real locks, all with count>0 */ + int lockrecs_array_length; + + tdb_off_t hdr_ofs; /* this is 0 or header.mutex_size */ + struct tdb_mutexes *mutexes; /* mmap of the mutex area */ + + enum TDB_ERROR ecode; /* error code for last tdb error */ + uint32_t hash_size; + uint32_t feature_flags; + uint32_t flags; /* the flags passed to tdb_open */ + struct tdb_traverse_lock travlocks; /* current traversal locks */ + struct tdb_context *next; /* all tdbs to avoid multiple opens */ + dev_t device; /* uniquely identifies this tdb */ + ino_t inode; /* uniquely identifies this tdb */ + struct tdb_logging_context log; + unsigned int (*hash_fn)(TDB_DATA *key); + int open_flags; /* flags used in the open - needed by reopen */ + const struct tdb_methods *methods; + struct tdb_transaction *transaction; + int page_size; + int max_dead_records; +#ifdef TDB_TRACE + int tracefd; +#endif + volatile sig_atomic_t *interrupt_sig_ptr; +}; + + +/* + internal prototypes +*/ +int tdb_munmap(struct tdb_context *tdb); +int tdb_mmap(struct tdb_context *tdb); +int tdb_lock(struct tdb_context *tdb, int list, int ltype); +int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype); +int tdb_nest_lock(struct tdb_context *tdb, uint32_t offset, int ltype, + enum tdb_lock_flags flags); +int tdb_nest_unlock(struct tdb_context *tdb, uint32_t offset, int ltype, + bool mark_lock); +int tdb_unlock(struct tdb_context *tdb, int list, int ltype); +int tdb_brlock(struct tdb_context *tdb, + int rw_type, tdb_off_t offset, size_t len, + enum tdb_lock_flags flags); +int tdb_brunlock(struct tdb_context *tdb, + int rw_type, tdb_off_t offset, size_t len); +bool tdb_have_extra_locks(struct tdb_context *tdb); +void tdb_release_transaction_locks(struct tdb_context *tdb); +int tdb_transaction_lock(struct tdb_context *tdb, int ltype, + enum tdb_lock_flags lockflags); +int tdb_transaction_unlock(struct tdb_context *tdb, int ltype); +int tdb_recovery_area(struct tdb_context *tdb, + const struct tdb_methods *methods, + tdb_off_t *recovery_offset, + struct tdb_record *rec); +int tdb_allrecord_lock(struct tdb_context *tdb, int ltype, + enum tdb_lock_flags flags, bool upgradable); +int tdb_allrecord_unlock(struct tdb_context *tdb, int ltype, bool mark_lock); +int tdb_allrecord_upgrade(struct tdb_context *tdb); +int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off); +int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off); +int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); +int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); +void *tdb_convert(void *buf, uint32_t size); +int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec); +tdb_off_t tdb_allocate(struct tdb_context *tdb, int hash, tdb_len_t length, + struct tdb_record *rec); + +int _tdb_oob(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe); + +static inline int tdb_oob( + struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe) +{ + if (likely((off + len >= off) && (off + len <= tdb->map_size))) { + return 0; + } + return _tdb_oob(tdb, off, len, probe); +} + + +int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); +int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); +int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off); +int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off); +bool tdb_needs_recovery(struct tdb_context *tdb); +int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec); +int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec); +unsigned char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len); +int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key, + tdb_off_t offset, tdb_len_t len, + int (*parser)(TDB_DATA key, TDB_DATA data, + void *private_data), + void *private_data); +tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype, + struct tdb_record *rec); +tdb_off_t tdb_find_dead(struct tdb_context *tdb, uint32_t hash, + struct tdb_record *r, tdb_len_t length, + tdb_off_t *p_last_ptr); +int tdb_trim_dead(struct tdb_context *tdb, uint32_t hash); +void tdb_io_init(struct tdb_context *tdb); +int tdb_expand(struct tdb_context *tdb, tdb_off_t size); +tdb_off_t tdb_expand_adjust(tdb_off_t map_size, tdb_off_t size, int page_size); +int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, + struct tdb_record *rec); +bool tdb_write_all(int fd, const void *buf, size_t count); +int tdb_transaction_recover(struct tdb_context *tdb); +void tdb_header_hash(struct tdb_context *tdb, + uint32_t *magic1_hash, uint32_t *magic2_hash); +unsigned int tdb_old_hash(TDB_DATA *key); +size_t tdb_dead_space(struct tdb_context *tdb, tdb_off_t off); +bool tdb_add_off_t(tdb_off_t a, tdb_off_t b, tdb_off_t *pret); + +/* tdb_off_t and tdb_len_t right now are both uint32_t */ +#define tdb_add_len_t tdb_add_off_t + +size_t tdb_mutex_size(struct tdb_context *tdb); +bool tdb_have_mutexes(struct tdb_context *tdb); +int tdb_mutex_init(struct tdb_context *tdb); +int tdb_mutex_mmap(struct tdb_context *tdb); +int tdb_mutex_munmap(struct tdb_context *tdb); +bool tdb_mutex_lock(struct tdb_context *tdb, int rw, off_t off, off_t len, + bool waitflag, int *pret); +bool tdb_mutex_unlock(struct tdb_context *tdb, int rw, off_t off, off_t len, + int *pret); +int tdb_mutex_allrecord_lock(struct tdb_context *tdb, int ltype, + enum tdb_lock_flags flags); +int tdb_mutex_allrecord_unlock(struct tdb_context *tdb); +int tdb_mutex_allrecord_upgrade(struct tdb_context *tdb); +void tdb_mutex_allrecord_downgrade(struct tdb_context *tdb); + +#endif /* TDB_PRIVATE_H */ diff --git a/ldb-2.0.8/lib/tdb/common/transaction.c b/ldb-2.0.8/lib/tdb/common/transaction.c new file mode 100644 index 0000000..4f8d1f8 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/common/transaction.c @@ -0,0 +1,1387 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 2005 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "tdb_private.h" + +/* + transaction design: + + - only allow a single transaction at a time per database. This makes + using the transaction API simpler, as otherwise the caller would + have to cope with temporary failures in transactions that conflict + with other current transactions + + - keep the transaction recovery information in the same file as the + database, using a special 'transaction recovery' record pointed at + by the header. This removes the need for extra journal files as + used by some other databases + + - dynamically allocated the transaction recover record, re-using it + for subsequent transactions. If a larger record is needed then + tdb_free() the old record to place it on the normal tdb freelist + before allocating the new record + + - during transactions, keep a linked list of all writes that have + been performed by intercepting all tdb_write() calls. The hooked + transaction versions of tdb_read() and tdb_write() check this + linked list and try to use the elements of the list in preference + to the real database. + + - don't allow any locks to be held when a transaction starts, + otherwise we can end up with deadlock (plus lack of lock nesting + in posix locks would mean the lock is lost) + + - if the caller gains a lock during the transaction but doesn't + release it then fail the commit + + - allow for nested calls to tdb_transaction_start(), re-using the + existing transaction record. If the inner transaction is cancelled + then a subsequent commit will fail + + - keep a mirrored copy of the tdb hash chain heads to allow for the + fast hash heads scan on traverse, updating the mirrored copy in + the transaction version of tdb_write + + - allow callers to mix transaction and non-transaction use of tdb, + although once a transaction is started then an exclusive lock is + gained until the transaction is committed or cancelled + + - the commit stategy involves first saving away all modified data + into a linearised buffer in the transaction recovery area, then + marking the transaction recovery area with a magic value to + indicate a valid recovery record. In total 4 fsync/msync calls are + needed per commit to prevent race conditions. It might be possible + to reduce this to 3 or even 2 with some more work. + + - check for a valid recovery record on open of the tdb, while the + open lock is held. Automatically recover from the transaction + recovery area if needed, then continue with the open as + usual. This allows for smooth crash recovery with no administrator + intervention. + + - if TDB_NOSYNC is passed to flags in tdb_open then transactions are + still available, but no fsync/msync calls are made. This means we + are still proof against a process dying during transaction commit, + but not against machine reboot. + + - if TDB_ALLOW_NESTING is passed to flags in tdb open, or added using + tdb_add_flags() transaction nesting is enabled. + It resets the TDB_DISALLOW_NESTING flag, as both cannot be used together. + The default is that transaction nesting is allowed. + Note: this default may change in future versions of tdb. + + Beware. when transactions are nested a transaction successfully + completed with tdb_transaction_commit() can be silently unrolled later. + + - if TDB_DISALLOW_NESTING is passed to flags in tdb open, or added using + tdb_add_flags() transaction nesting is disabled. + It resets the TDB_ALLOW_NESTING flag, as both cannot be used together. + An attempt create a nested transaction will fail with TDB_ERR_NESTING. + The default is that transaction nesting is allowed. + Note: this default may change in future versions of tdb. +*/ + + +/* + hold the context of any current transaction +*/ +struct tdb_transaction { + /* we keep a mirrored copy of the tdb hash heads here so + tdb_next_hash_chain() can operate efficiently */ + uint32_t *hash_heads; + + /* the original io methods - used to do IOs to the real db */ + const struct tdb_methods *io_methods; + + /* the list of transaction blocks. When a block is first + written to, it gets created in this list */ + uint8_t **blocks; + uint32_t num_blocks; + uint32_t block_size; /* bytes in each block */ + uint32_t last_block_size; /* number of valid bytes in the last block */ + + /* non-zero when an internal transaction error has + occurred. All write operations will then fail until the + transaction is ended */ + int transaction_error; + + /* when inside a transaction we need to keep track of any + nested tdb_transaction_start() calls, as these are allowed, + but don't create a new transaction */ + int nesting; + + /* set when a prepare has already occurred */ + bool prepared; + tdb_off_t magic_offset; + + /* old file size before transaction */ + tdb_len_t old_map_size; + + /* did we expand in this transaction */ + bool expanded; +}; + + +/* + read while in a transaction. We need to check first if the data is in our list + of transaction elements, then if not do a real read +*/ +static int transaction_read(struct tdb_context *tdb, tdb_off_t off, void *buf, + tdb_len_t len, int cv) +{ + uint32_t blk; + + /* break it down into block sized ops */ + while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { + tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); + if (transaction_read(tdb, off, buf, len2, cv) != 0) { + return -1; + } + len -= len2; + off += len2; + buf = (void *)(len2 + (char *)buf); + } + + if (len == 0) { + return 0; + } + + blk = off / tdb->transaction->block_size; + + /* see if we have it in the block list */ + if (tdb->transaction->num_blocks <= blk || + tdb->transaction->blocks[blk] == NULL) { + /* nope, do a real read */ + if (tdb->transaction->io_methods->tdb_read(tdb, off, buf, len, cv) != 0) { + goto fail; + } + return 0; + } + + /* it is in the block list. Now check for the last block */ + if (blk == tdb->transaction->num_blocks-1) { + if (len > tdb->transaction->last_block_size) { + goto fail; + } + } + + /* now copy it out of this block */ + memcpy(buf, tdb->transaction->blocks[blk] + (off % tdb->transaction->block_size), len); + if (cv) { + tdb_convert(buf, len); + } + return 0; + +fail: + TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_read: failed at off=%u len=%u\n", off, len)); + tdb->ecode = TDB_ERR_IO; + tdb->transaction->transaction_error = 1; + return -1; +} + + +/* + write while in a transaction +*/ +static int transaction_write(struct tdb_context *tdb, tdb_off_t off, + const void *buf, tdb_len_t len) +{ + uint32_t blk; + + if (buf == NULL) { + return -1; + } + + /* Only a commit is allowed on a prepared transaction */ + if (tdb->transaction->prepared) { + tdb->ecode = TDB_ERR_EINVAL; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: transaction already prepared, write not allowed\n")); + tdb->transaction->transaction_error = 1; + return -1; + } + + /* if the write is to a hash head, then update the transaction + hash heads */ + if (len == sizeof(tdb_off_t) && off >= FREELIST_TOP && + off < FREELIST_TOP+TDB_HASHTABLE_SIZE(tdb)) { + uint32_t chain = (off-FREELIST_TOP) / sizeof(tdb_off_t); + memcpy(&tdb->transaction->hash_heads[chain], buf, len); + } + + /* break it up into block sized chunks */ + while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { + tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); + if (transaction_write(tdb, off, buf, len2) != 0) { + return -1; + } + len -= len2; + off += len2; + buf = (const void *)(len2 + (const char *)buf); + } + + if (len == 0) { + return 0; + } + + blk = off / tdb->transaction->block_size; + off = off % tdb->transaction->block_size; + + if (tdb->transaction->num_blocks <= blk) { + uint8_t **new_blocks; + /* expand the blocks array */ + new_blocks = (uint8_t **)realloc(tdb->transaction->blocks, + (blk+1)*sizeof(uint8_t *)); + if (new_blocks == NULL) { + tdb->ecode = TDB_ERR_OOM; + goto fail; + } + memset(&new_blocks[tdb->transaction->num_blocks], 0, + (1+(blk - tdb->transaction->num_blocks))*sizeof(uint8_t *)); + tdb->transaction->blocks = new_blocks; + tdb->transaction->num_blocks = blk+1; + tdb->transaction->last_block_size = 0; + } + + /* allocate and fill a block? */ + if (tdb->transaction->blocks[blk] == NULL) { + tdb->transaction->blocks[blk] = (uint8_t *)calloc(tdb->transaction->block_size, 1); + if (tdb->transaction->blocks[blk] == NULL) { + tdb->ecode = TDB_ERR_OOM; + tdb->transaction->transaction_error = 1; + return -1; + } + if (tdb->transaction->old_map_size > blk * tdb->transaction->block_size) { + tdb_len_t len2 = tdb->transaction->block_size; + if (len2 + (blk * tdb->transaction->block_size) > tdb->transaction->old_map_size) { + len2 = tdb->transaction->old_map_size - (blk * tdb->transaction->block_size); + } + if (tdb->transaction->io_methods->tdb_read(tdb, blk * tdb->transaction->block_size, + tdb->transaction->blocks[blk], + len2, 0) != 0) { + SAFE_FREE(tdb->transaction->blocks[blk]); + tdb->ecode = TDB_ERR_IO; + goto fail; + } + if (blk == tdb->transaction->num_blocks-1) { + tdb->transaction->last_block_size = len2; + } + } + } + + /* overwrite part of an existing block */ + memcpy(tdb->transaction->blocks[blk] + off, buf, len); + if (blk == tdb->transaction->num_blocks-1) { + if (len + off > tdb->transaction->last_block_size) { + tdb->transaction->last_block_size = len + off; + } + } + + return 0; + +fail: + TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%u len=%u\n", + (blk*tdb->transaction->block_size) + off, len)); + tdb->transaction->transaction_error = 1; + return -1; +} + + +/* + write while in a transaction - this variant never expands the transaction blocks, it only + updates existing blocks. This means it cannot change the recovery size +*/ +static int transaction_write_existing(struct tdb_context *tdb, tdb_off_t off, + const void *buf, tdb_len_t len) +{ + uint32_t blk; + + /* break it up into block sized chunks */ + while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { + tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); + if (transaction_write_existing(tdb, off, buf, len2) != 0) { + return -1; + } + len -= len2; + off += len2; + if (buf != NULL) { + buf = (const void *)(len2 + (const char *)buf); + } + } + + if (len == 0 || buf == NULL) { + return 0; + } + + blk = off / tdb->transaction->block_size; + off = off % tdb->transaction->block_size; + + if (tdb->transaction->num_blocks <= blk || + tdb->transaction->blocks[blk] == NULL) { + return 0; + } + + if (blk == tdb->transaction->num_blocks-1 && + off + len > tdb->transaction->last_block_size) { + if (off >= tdb->transaction->last_block_size) { + return 0; + } + len = tdb->transaction->last_block_size - off; + } + + /* overwrite part of an existing block */ + memcpy(tdb->transaction->blocks[blk] + off, buf, len); + + return 0; +} + + +/* + accelerated hash chain head search, using the cached hash heads +*/ +static void transaction_next_hash_chain(struct tdb_context *tdb, uint32_t *chain) +{ + uint32_t h = *chain; + for (;h < tdb->hash_size;h++) { + /* the +1 takes account of the freelist */ + if (0 != tdb->transaction->hash_heads[h+1]) { + break; + } + } + (*chain) = h; +} + +/* + out of bounds check during a transaction +*/ +static int transaction_oob(struct tdb_context *tdb, tdb_off_t off, + tdb_len_t len, int probe) +{ + /* + * This duplicates functionality from tdb_oob(). Don't remove: + * we still have direct callers of tdb->methods->tdb_oob() + * inside transaction.c. + */ + if (off + len >= off && off + len <= tdb->map_size) { + return 0; + } + tdb->ecode = TDB_ERR_IO; + return -1; +} + +/* + transaction version of tdb_expand(). +*/ +static int transaction_expand_file(struct tdb_context *tdb, tdb_off_t size, + tdb_off_t addition) +{ + const char buf_zero[8192] = {0}; + size_t buf_len = sizeof(buf_zero); + + while (addition > 0) { + size_t n = MIN(addition, buf_len); + int ret; + + ret = transaction_write(tdb, size, buf_zero, n); + if (ret != 0) { + return ret; + } + + addition -= n; + size += n; + } + + tdb->transaction->expanded = true; + + return 0; +} + +static const struct tdb_methods transaction_methods = { + transaction_read, + transaction_write, + transaction_next_hash_chain, + transaction_oob, + transaction_expand_file, +}; + +/* + * Is a transaction currently active on this context? + * + */ +_PUBLIC_ bool tdb_transaction_active(struct tdb_context *tdb) +{ + return (tdb->transaction != NULL); +} + +/* + start a tdb transaction. No token is returned, as only a single + transaction is allowed to be pending per tdb_context +*/ +static int _tdb_transaction_start(struct tdb_context *tdb, + enum tdb_lock_flags lockflags) +{ + /* some sanity checks */ + if (tdb->read_only || (tdb->flags & TDB_INTERNAL) + || tdb->traverse_read) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction on a read-only or internal db\n")); + tdb->ecode = TDB_ERR_EINVAL; + return -1; + } + + /* cope with nested tdb_transaction_start() calls */ + if (tdb->transaction != NULL) { + if (!(tdb->flags & TDB_ALLOW_NESTING)) { + tdb->ecode = TDB_ERR_NESTING; + return -1; + } + tdb->transaction->nesting++; + TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_start: nesting %d\n", + tdb->transaction->nesting)); + return 0; + } + + if (tdb_have_extra_locks(tdb)) { + /* the caller must not have any locks when starting a + transaction as otherwise we'll be screwed by lack + of nested locks in posix */ + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction with locks held\n")); + tdb->ecode = TDB_ERR_LOCK; + return -1; + } + + if (tdb->travlocks.next != NULL) { + /* you cannot use transactions inside a traverse (although you can use + traverse inside a transaction) as otherwise you can end up with + deadlock */ + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction within a traverse\n")); + tdb->ecode = TDB_ERR_LOCK; + return -1; + } + + tdb->transaction = (struct tdb_transaction *) + calloc(sizeof(struct tdb_transaction), 1); + if (tdb->transaction == NULL) { + tdb->ecode = TDB_ERR_OOM; + return -1; + } + + /* a page at a time seems like a reasonable compromise between compactness and efficiency */ + tdb->transaction->block_size = tdb->page_size; + + /* get the transaction write lock. This is a blocking lock. As + discussed with Volker, there are a number of ways we could + make this async, which we will probably do in the future */ + if (tdb_transaction_lock(tdb, F_WRLCK, lockflags) == -1) { + SAFE_FREE(tdb->transaction->blocks); + SAFE_FREE(tdb->transaction); + if ((lockflags & TDB_LOCK_WAIT) == 0) { + tdb->ecode = TDB_ERR_NOLOCK; + } else { + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "tdb_transaction_start: " + "failed to get transaction lock\n")); + } + return -1; + } + + /* get a read lock from the freelist to the end of file. This + is upgraded to a write lock during the commit */ + if (tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, true) == -1) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to get hash locks\n")); + goto fail_allrecord_lock; + } + + /* setup a copy of the hash table heads so the hash scan in + traverse can be fast */ + tdb->transaction->hash_heads = (uint32_t *) + calloc(tdb->hash_size+1, sizeof(uint32_t)); + if (tdb->transaction->hash_heads == NULL) { + tdb->ecode = TDB_ERR_OOM; + goto fail; + } + if (tdb->methods->tdb_read(tdb, FREELIST_TOP, tdb->transaction->hash_heads, + TDB_HASHTABLE_SIZE(tdb), 0) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_start: failed to read hash heads\n")); + tdb->ecode = TDB_ERR_IO; + goto fail; + } + + /* make sure we know about any file expansions already done by + anyone else */ + tdb_oob(tdb, tdb->map_size, 1, 1); + tdb->transaction->old_map_size = tdb->map_size; + + /* finally hook the io methods, replacing them with + transaction specific methods */ + tdb->transaction->io_methods = tdb->methods; + tdb->methods = &transaction_methods; + + /* Trace at the end, so we get sequence number correct. */ + tdb_trace(tdb, "tdb_transaction_start"); + return 0; + +fail: + tdb_allrecord_unlock(tdb, F_RDLCK, false); +fail_allrecord_lock: + tdb_transaction_unlock(tdb, F_WRLCK); + SAFE_FREE(tdb->transaction->blocks); + SAFE_FREE(tdb->transaction->hash_heads); + SAFE_FREE(tdb->transaction); + return -1; +} + +_PUBLIC_ int tdb_transaction_start(struct tdb_context *tdb) +{ + return _tdb_transaction_start(tdb, TDB_LOCK_WAIT); +} + +_PUBLIC_ int tdb_transaction_start_nonblock(struct tdb_context *tdb) +{ + return _tdb_transaction_start(tdb, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE); +} + +/* + sync to disk +*/ +static int transaction_sync(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t length) +{ + if (tdb->flags & TDB_NOSYNC) { + return 0; + } + +#ifdef HAVE_FDATASYNC + if (fdatasync(tdb->fd) != 0) { +#else + if (fsync(tdb->fd) != 0) { +#endif + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction: fsync failed\n")); + return -1; + } +#ifdef HAVE_MMAP + if (tdb->map_ptr) { + tdb_off_t moffset = offset & ~(tdb->page_size-1); + if (msync(moffset + (char *)tdb->map_ptr, + length + (offset - moffset), MS_SYNC) != 0) { + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction: msync failed - %s\n", + strerror(errno))); + return -1; + } + } +#endif + return 0; +} + + +static int _tdb_transaction_cancel(struct tdb_context *tdb) +{ + uint32_t i; + int ret = 0; + + if (tdb->transaction == NULL) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_cancel: no transaction\n")); + return -1; + } + + if (tdb->transaction->nesting != 0) { + tdb->transaction->transaction_error = 1; + tdb->transaction->nesting--; + return 0; + } + + tdb->map_size = tdb->transaction->old_map_size; + + /* free all the transaction blocks */ + for (i=0;itransaction->num_blocks;i++) { + if ((tdb->transaction->blocks != NULL) && + tdb->transaction->blocks[i] != NULL) { + free(tdb->transaction->blocks[i]); + } + } + SAFE_FREE(tdb->transaction->blocks); + + if (tdb->transaction->magic_offset) { + const struct tdb_methods *methods = tdb->transaction->io_methods; + const uint32_t invalid = TDB_RECOVERY_INVALID_MAGIC; + + /* remove the recovery marker */ + if (methods->tdb_write(tdb, tdb->transaction->magic_offset, &invalid, 4) == -1 || + transaction_sync(tdb, tdb->transaction->magic_offset, 4) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_cancel: failed to remove recovery magic\n")); + ret = -1; + } + } + + /* This also removes the OPEN_LOCK, if we have it. */ + tdb_release_transaction_locks(tdb); + + /* restore the normal io methods */ + tdb->methods = tdb->transaction->io_methods; + + SAFE_FREE(tdb->transaction->hash_heads); + SAFE_FREE(tdb->transaction); + + return ret; +} + +/* + cancel the current transaction +*/ +_PUBLIC_ int tdb_transaction_cancel(struct tdb_context *tdb) +{ + tdb_trace(tdb, "tdb_transaction_cancel"); + return _tdb_transaction_cancel(tdb); +} + +/* + work out how much space the linearised recovery data will consume +*/ +static bool tdb_recovery_size(struct tdb_context *tdb, tdb_len_t *result) +{ + tdb_len_t recovery_size = 0; + uint32_t i; + + recovery_size = sizeof(uint32_t); + for (i=0;itransaction->num_blocks;i++) { + tdb_len_t block_size; + if (i * tdb->transaction->block_size >= tdb->transaction->old_map_size) { + break; + } + if (tdb->transaction->blocks[i] == NULL) { + continue; + } + if (!tdb_add_len_t(recovery_size, 2*sizeof(tdb_off_t), + &recovery_size)) { + return false; + } + if (i == tdb->transaction->num_blocks-1) { + block_size = tdb->transaction->last_block_size; + } else { + block_size = tdb->transaction->block_size; + } + if (!tdb_add_len_t(recovery_size, block_size, + &recovery_size)) { + return false; + } + } + + *result = recovery_size; + return true; +} + +int tdb_recovery_area(struct tdb_context *tdb, + const struct tdb_methods *methods, + tdb_off_t *recovery_offset, + struct tdb_record *rec) +{ + int ret; + + if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, recovery_offset) == -1) { + return -1; + } + + if (*recovery_offset == 0) { + rec->rec_len = 0; + return 0; + } + + if (methods->tdb_read(tdb, *recovery_offset, rec, sizeof(*rec), + DOCONV()) == -1) { + return -1; + } + + /* ignore invalid recovery regions: can happen in crash */ + if (rec->magic != TDB_RECOVERY_MAGIC && + rec->magic != TDB_RECOVERY_INVALID_MAGIC) { + *recovery_offset = 0; + rec->rec_len = 0; + } + + ret = methods->tdb_oob(tdb, *recovery_offset, rec->rec_len, 1); + if (ret == -1) { + *recovery_offset = 0; + rec->rec_len = 0; + } + + return 0; +} + +/* + allocate the recovery area, or use an existing recovery area if it is + large enough +*/ +static int tdb_recovery_allocate(struct tdb_context *tdb, + tdb_len_t *recovery_size, + tdb_off_t *recovery_offset, + tdb_len_t *recovery_max_size) +{ + struct tdb_record rec; + const struct tdb_methods *methods = tdb->transaction->io_methods; + tdb_off_t recovery_head, new_end; + + if (tdb_recovery_area(tdb, methods, &recovery_head, &rec) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to read recovery head\n")); + return -1; + } + + if (!tdb_recovery_size(tdb, recovery_size)) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: " + "overflow recovery size\n")); + return -1; + } + + /* Existing recovery area? */ + if (recovery_head != 0 && *recovery_size <= rec.rec_len) { + /* it fits in the existing area */ + *recovery_max_size = rec.rec_len; + *recovery_offset = recovery_head; + return 0; + } + + /* If recovery area in middle of file, we need a new one. */ + if (recovery_head == 0 + || recovery_head + sizeof(rec) + rec.rec_len != tdb->map_size) { + /* we need to free up the old recovery area, then allocate a + new one at the end of the file. Note that we cannot use + tdb_allocate() to allocate the new one as that might return + us an area that is being currently used (as of the start of + the transaction) */ + if (recovery_head) { + if (tdb_free(tdb, recovery_head, &rec) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, + "tdb_recovery_allocate: failed to" + " free previous recovery area\n")); + return -1; + } + + /* the tdb_free() call might have increased + * the recovery size */ + if (!tdb_recovery_size(tdb, recovery_size)) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, + "tdb_recovery_allocate: " + "overflow recovery size\n")); + return -1; + } + } + + /* New head will be at end of file. */ + recovery_head = tdb->map_size; + } + + /* Now we know where it will be. */ + *recovery_offset = recovery_head; + + /* Expand by more than we need, so we don't do it often. */ + *recovery_max_size = tdb_expand_adjust(tdb->map_size, + *recovery_size, + tdb->page_size) + - sizeof(rec); + + if (!tdb_add_off_t(recovery_head, sizeof(rec), &new_end) || + !tdb_add_off_t(new_end, *recovery_max_size, &new_end)) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: " + "overflow recovery area\n")); + return -1; + } + + if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size, + new_end - tdb->transaction->old_map_size) + == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to create recovery area\n")); + return -1; + } + + /* remap the file (if using mmap) */ + methods->tdb_oob(tdb, tdb->map_size, 1, 1); + + /* we have to reset the old map size so that we don't try to expand the file + again in the transaction commit, which would destroy the recovery area */ + tdb->transaction->old_map_size = tdb->map_size; + + /* write the recovery header offset and sync - we can sync without a race here + as the magic ptr in the recovery record has not been set */ + CONVERT(recovery_head); + if (methods->tdb_write(tdb, TDB_RECOVERY_HEAD, + &recovery_head, sizeof(tdb_off_t)) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n")); + return -1; + } + if (transaction_write_existing(tdb, TDB_RECOVERY_HEAD, &recovery_head, sizeof(tdb_off_t)) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n")); + return -1; + } + + return 0; +} + + +/* + setup the recovery data that will be used on a crash during commit +*/ +static int transaction_setup_recovery(struct tdb_context *tdb, + tdb_off_t *magic_offset) +{ + tdb_len_t recovery_size; + unsigned char *data, *p; + const struct tdb_methods *methods = tdb->transaction->io_methods; + struct tdb_record *rec; + tdb_off_t recovery_offset, recovery_max_size; + tdb_off_t old_map_size = tdb->transaction->old_map_size; + uint32_t magic, tailer; + uint32_t i; + + /* + check that the recovery area has enough space + */ + if (tdb_recovery_allocate(tdb, &recovery_size, + &recovery_offset, &recovery_max_size) == -1) { + return -1; + } + + rec = malloc(recovery_size + sizeof(*rec)); + if (rec == NULL) { + tdb->ecode = TDB_ERR_OOM; + return -1; + } + + memset(rec, 0, sizeof(*rec)); + + rec->magic = TDB_RECOVERY_INVALID_MAGIC; + rec->data_len = recovery_size; + rec->rec_len = recovery_max_size; + rec->key_len = old_map_size; + CONVERT(*rec); + + data = (unsigned char *)rec; + + /* build the recovery data into a single blob to allow us to do a single + large write, which should be more efficient */ + p = data + sizeof(*rec); + for (i=0;itransaction->num_blocks;i++) { + tdb_off_t offset; + tdb_len_t length; + + if (tdb->transaction->blocks[i] == NULL) { + continue; + } + + offset = i * tdb->transaction->block_size; + length = tdb->transaction->block_size; + if (i == tdb->transaction->num_blocks-1) { + length = tdb->transaction->last_block_size; + } + + if (offset >= old_map_size) { + continue; + } + if (offset + length > tdb->transaction->old_map_size) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: transaction data over new region boundary\n")); + free(data); + tdb->ecode = TDB_ERR_CORRUPT; + return -1; + } + memcpy(p, &offset, 4); + memcpy(p+4, &length, 4); + if (DOCONV()) { + tdb_convert(p, 8); + } + /* the recovery area contains the old data, not the + new data, so we have to call the original tdb_read + method to get it */ + if (methods->tdb_read(tdb, offset, p + 8, length, 0) != 0) { + free(data); + tdb->ecode = TDB_ERR_IO; + return -1; + } + p += 8 + length; + } + + /* and the tailer */ + tailer = sizeof(*rec) + recovery_max_size; + memcpy(p, &tailer, 4); + if (DOCONV()) { + tdb_convert(p, 4); + } + + /* write the recovery data to the recovery area */ + if (methods->tdb_write(tdb, recovery_offset, data, sizeof(*rec) + recovery_size) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write recovery data\n")); + free(data); + tdb->ecode = TDB_ERR_IO; + return -1; + } + if (transaction_write_existing(tdb, recovery_offset, data, sizeof(*rec) + recovery_size) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write secondary recovery data\n")); + free(data); + tdb->ecode = TDB_ERR_IO; + return -1; + } + + /* as we don't have ordered writes, we have to sync the recovery + data before we update the magic to indicate that the recovery + data is present */ + if (transaction_sync(tdb, recovery_offset, sizeof(*rec) + recovery_size) == -1) { + free(data); + return -1; + } + + free(data); + + magic = TDB_RECOVERY_MAGIC; + CONVERT(magic); + + *magic_offset = recovery_offset + offsetof(struct tdb_record, magic); + + if (methods->tdb_write(tdb, *magic_offset, &magic, sizeof(magic)) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write recovery magic\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } + if (transaction_write_existing(tdb, *magic_offset, &magic, sizeof(magic)) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write secondary recovery magic\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } + + /* ensure the recovery magic marker is on disk */ + if (transaction_sync(tdb, *magic_offset, sizeof(magic)) == -1) { + return -1; + } + + return 0; +} + +static int _tdb_transaction_prepare_commit(struct tdb_context *tdb) +{ + const struct tdb_methods *methods; + + if (tdb->transaction == NULL) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: no transaction\n")); + return -1; + } + + if (tdb->transaction->prepared) { + tdb->ecode = TDB_ERR_EINVAL; + _tdb_transaction_cancel(tdb); + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: transaction already prepared\n")); + return -1; + } + + if (tdb->transaction->transaction_error) { + tdb->ecode = TDB_ERR_IO; + _tdb_transaction_cancel(tdb); + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: transaction error pending\n")); + return -1; + } + + + if (tdb->transaction->nesting != 0) { + return 0; + } + + /* check for a null transaction */ + if (tdb->transaction->blocks == NULL) { + return 0; + } + + methods = tdb->transaction->io_methods; + + /* if there are any locks pending then the caller has not + nested their locks properly, so fail the transaction */ + if (tdb_have_extra_locks(tdb)) { + tdb->ecode = TDB_ERR_LOCK; + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: locks pending on commit\n")); + _tdb_transaction_cancel(tdb); + return -1; + } + + /* upgrade the main transaction lock region to a write lock */ + if (tdb_allrecord_upgrade(tdb) == -1) { + if (tdb->ecode == TDB_ERR_RDONLY && tdb->read_only) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "tdb_transaction_prepare_commit: " + "failed to upgrade hash locks: " + "database is read only\n")); + } else if (tdb->ecode == TDB_ERR_RDONLY + && tdb->traverse_read) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "tdb_transaction_prepare_commit: " + "failed to upgrade hash locks: " + "a database traverse is in progress\n")); + } else { + TDB_LOG((tdb, TDB_DEBUG_ERROR, + "tdb_transaction_prepare_commit: " + "failed to upgrade hash locks: %s\n", + tdb_errorstr(tdb))); + } + _tdb_transaction_cancel(tdb); + return -1; + } + + /* get the open lock - this prevents new users attaching to the database + during the commit */ + if (tdb_nest_lock(tdb, OPEN_LOCK, F_WRLCK, TDB_LOCK_WAIT) == -1) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: failed to get open lock\n")); + _tdb_transaction_cancel(tdb); + return -1; + } + + /* write the recovery data to the end of the file */ + if (transaction_setup_recovery(tdb, &tdb->transaction->magic_offset) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_prepare_commit: failed to setup recovery data\n")); + _tdb_transaction_cancel(tdb); + return -1; + } + + tdb->transaction->prepared = true; + + /* expand the file to the new size if needed */ + if (tdb->map_size != tdb->transaction->old_map_size) { + if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size, + tdb->map_size - + tdb->transaction->old_map_size) == -1) { + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_prepare_commit: expansion failed\n")); + _tdb_transaction_cancel(tdb); + return -1; + } + tdb->map_size = tdb->transaction->old_map_size; + methods->tdb_oob(tdb, tdb->map_size, 1, 1); + } + + /* Keep the open lock until the actual commit */ + + return 0; +} + +/* + prepare to commit the current transaction +*/ +_PUBLIC_ int tdb_transaction_prepare_commit(struct tdb_context *tdb) +{ + tdb_trace(tdb, "tdb_transaction_prepare_commit"); + return _tdb_transaction_prepare_commit(tdb); +} + +/* A repack is worthwhile if the largest is less than half total free. */ +static bool repack_worthwhile(struct tdb_context *tdb) +{ + tdb_off_t ptr; + struct tdb_record rec; + tdb_len_t total = 0, largest = 0; + + if (tdb_ofs_read(tdb, FREELIST_TOP, &ptr) == -1) { + return false; + } + + while (ptr != 0 && tdb_rec_free_read(tdb, ptr, &rec) == 0) { + total += rec.rec_len; + if (rec.rec_len > largest) { + largest = rec.rec_len; + } + ptr = rec.next; + } + + return total > largest * 2; +} + +/* + commit the current transaction +*/ +_PUBLIC_ int tdb_transaction_commit(struct tdb_context *tdb) +{ + const struct tdb_methods *methods; + uint32_t i; + bool need_repack = false; + + if (tdb->transaction == NULL) { + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: no transaction\n")); + return -1; + } + + tdb_trace(tdb, "tdb_transaction_commit"); + + if (tdb->transaction->transaction_error) { + tdb->ecode = TDB_ERR_IO; + _tdb_transaction_cancel(tdb); + TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: transaction error pending\n")); + return -1; + } + + + if (tdb->transaction->nesting != 0) { + tdb->transaction->nesting--; + return 0; + } + + /* check for a null transaction */ + if (tdb->transaction->blocks == NULL) { + _tdb_transaction_cancel(tdb); + return 0; + } + + if (!tdb->transaction->prepared) { + int ret = _tdb_transaction_prepare_commit(tdb); + if (ret) + return ret; + } + + methods = tdb->transaction->io_methods; + + /* perform all the writes */ + for (i=0;itransaction->num_blocks;i++) { + tdb_off_t offset; + tdb_len_t length; + + if (tdb->transaction->blocks[i] == NULL) { + continue; + } + + offset = i * tdb->transaction->block_size; + length = tdb->transaction->block_size; + if (i == tdb->transaction->num_blocks-1) { + length = tdb->transaction->last_block_size; + } + + if (methods->tdb_write(tdb, offset, tdb->transaction->blocks[i], length) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed during commit\n")); + + /* we've overwritten part of the data and + possibly expanded the file, so we need to + run the crash recovery code */ + tdb->methods = methods; + tdb_transaction_recover(tdb); + + _tdb_transaction_cancel(tdb); + + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed\n")); + return -1; + } + SAFE_FREE(tdb->transaction->blocks[i]); + } + + /* Do this before we drop lock or blocks. */ + if (tdb->transaction->expanded) { + need_repack = repack_worthwhile(tdb); + } + + SAFE_FREE(tdb->transaction->blocks); + tdb->transaction->num_blocks = 0; + + /* ensure the new data is on disk */ + if (transaction_sync(tdb, 0, tdb->map_size) == -1) { + return -1; + } + + /* + TODO: maybe write to some dummy hdr field, or write to magic + offset without mmap, before the last sync, instead of the + utime() call + */ + + /* on some systems (like Linux 2.6.x) changes via mmap/msync + don't change the mtime of the file, this means the file may + not be backed up (as tdb rounding to block sizes means that + file size changes are quite rare too). The following forces + mtime changes when a transaction completes */ +#ifdef HAVE_UTIME + utime(tdb->name, NULL); +#endif + + /* use a transaction cancel to free memory and remove the + transaction locks */ + _tdb_transaction_cancel(tdb); + + if (need_repack) { + int ret = tdb_repack(tdb); + if (ret != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, + __location__ " Failed to repack database (not fatal)\n")); + } + /* + * Ignore the error. + * + * Why? + * + * We just committed to the DB above, so anything + * written during the transaction is committed, the + * caller needs to know that the long-term state was + * successfully modified. + * + * tdb_repack is an optimization that can fail for + * reasons like lock ordering and we cannot recover + * the transaction lock at this point, having released + * it above. + * + * If we return a failure the caller thinks the + * transaction was rolled back. + */ + } + + return 0; +} + + +/* + recover from an aborted transaction. Must be called with exclusive + database write access already established (including the open + lock to prevent new processes attaching) +*/ +int tdb_transaction_recover(struct tdb_context *tdb) +{ + tdb_off_t recovery_head, recovery_eof; + unsigned char *data, *p; + uint32_t zero = 0; + struct tdb_record rec; + + /* find the recovery area */ + if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery head\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } + + if (recovery_head == 0) { + /* we have never allocated a recovery record */ + return 0; + } + + /* read the recovery record */ + if (tdb->methods->tdb_read(tdb, recovery_head, &rec, + sizeof(rec), DOCONV()) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery record\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } + + if (rec.magic != TDB_RECOVERY_MAGIC) { + /* there is no valid recovery data */ + return 0; + } + + if (tdb->read_only) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: attempt to recover read only database\n")); + tdb->ecode = TDB_ERR_CORRUPT; + return -1; + } + + recovery_eof = rec.key_len; + + data = (unsigned char *)malloc(rec.data_len); + if (data == NULL) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to allocate recovery data\n")); + tdb->ecode = TDB_ERR_OOM; + return -1; + } + + /* read the full recovery data */ + if (tdb->methods->tdb_read(tdb, recovery_head + sizeof(rec), data, + rec.data_len, 0) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery data\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } + + /* recover the file data */ + p = data; + while (p+8 < data + rec.data_len) { + uint32_t ofs, len; + if (DOCONV()) { + tdb_convert(p, 8); + } + memcpy(&ofs, p, 4); + memcpy(&len, p+4, 4); + + if (tdb->methods->tdb_write(tdb, ofs, p+8, len) == -1) { + free(data); + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to recover %u bytes at offset %u\n", len, ofs)); + tdb->ecode = TDB_ERR_IO; + return -1; + } + p += 8 + len; + } + + free(data); + + if (transaction_sync(tdb, 0, tdb->map_size) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to sync recovery\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } + + /* if the recovery area is after the recovered eof then remove it */ + if (recovery_eof <= recovery_head) { + if (tdb_ofs_write(tdb, TDB_RECOVERY_HEAD, &zero) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to remove recovery head\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } + } + + /* remove the recovery magic */ + if (tdb_ofs_write(tdb, recovery_head + offsetof(struct tdb_record, magic), + &zero) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to remove recovery magic\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } + + if (transaction_sync(tdb, 0, recovery_eof) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to sync2 recovery\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } + + TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_recover: recovered %u byte database\n", + recovery_eof)); + + /* all done */ + return 0; +} + +/* Any I/O failures we say "needs recovery". */ +bool tdb_needs_recovery(struct tdb_context *tdb) +{ + tdb_off_t recovery_head; + struct tdb_record rec; + + /* find the recovery area */ + if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { + return true; + } + + if (recovery_head == 0) { + /* we have never allocated a recovery record */ + return false; + } + + /* read the recovery record */ + if (tdb->methods->tdb_read(tdb, recovery_head, &rec, + sizeof(rec), DOCONV()) == -1) { + return true; + } + + return (rec.magic == TDB_RECOVERY_MAGIC); +} diff --git a/ldb-2.0.8/lib/tdb/common/traverse.c b/ldb-2.0.8/lib/tdb/common/traverse.c new file mode 100644 index 0000000..d69e7df --- /dev/null +++ b/ldb-2.0.8/lib/tdb/common/traverse.c @@ -0,0 +1,510 @@ + /* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2005 + Copyright (C) Paul `Rusty' Russell 2000 + Copyright (C) Jeremy Allison 2000-2003 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "tdb_private.h" + +#define TDB_NEXT_LOCK_ERR ((tdb_off_t)-1) + +/* Uses traverse lock: 0 = finish, TDB_NEXT_LOCK_ERR = error, + other = record offset */ +static tdb_off_t tdb_next_lock(struct tdb_context *tdb, struct tdb_traverse_lock *tlock, + struct tdb_record *rec) +{ + int want_next = (tlock->off != 0); + + /* Lock each chain from the start one. */ + for (; tlock->list < tdb->hash_size; tlock->list++) { + if (!tlock->off && tlock->list != 0) { + /* this is an optimisation for the common case where + the hash chain is empty, which is particularly + common for the use of tdb with ldb, where large + hashes are used. In that case we spend most of our + time in tdb_brlock(), locking empty hash chains. + + To avoid this, we do an unlocked pre-check to see + if the hash chain is empty before starting to look + inside it. If it is empty then we can avoid that + hash chain. If it isn't empty then we can't believe + the value we get back, as we read it without a + lock, so instead we get the lock and re-fetch the + value below. + + Notice that not doing this optimisation on the + first hash chain is critical. We must guarantee + that we have done at least one fcntl lock at the + start of a search to guarantee that memory is + coherent on SMP systems. If records are added by + others during the search then thats OK, and we + could possibly miss those with this trick, but we + could miss them anyway without this trick, so the + semantics don't change. + + With a non-indexed ldb search this trick gains us a + factor of around 80 in speed on a linux 2.6.x + system (testing using ldbtest). + */ + tdb->methods->next_hash_chain(tdb, &tlock->list); + if (tlock->list == tdb->hash_size) { + continue; + } + } + + if (tdb_lock(tdb, tlock->list, tlock->lock_rw) == -1) + return TDB_NEXT_LOCK_ERR; + + /* No previous record? Start at top of chain. */ + if (!tlock->off) { + if (tdb_ofs_read(tdb, TDB_HASH_TOP(tlock->list), + &tlock->off) == -1) + goto fail; + } else { + /* Otherwise unlock the previous record. */ + if (tdb_unlock_record(tdb, tlock->off) != 0) + goto fail; + } + + if (want_next) { + /* We have offset of old record: grab next */ + if (tdb_rec_read(tdb, tlock->off, rec) == -1) + goto fail; + tlock->off = rec->next; + } + + /* Iterate through chain */ + while( tlock->off) { + if (tdb_rec_read(tdb, tlock->off, rec) == -1) + goto fail; + + /* Detect infinite loops. From "Shlomi Yaakobovich" . */ + if (tlock->off == rec->next) { + tdb->ecode = TDB_ERR_CORRUPT; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_next_lock: loop detected.\n")); + goto fail; + } + + if (!TDB_DEAD(rec)) { + /* Woohoo: we found one! */ + if (tdb_lock_record(tdb, tlock->off) != 0) + goto fail; + return tlock->off; + } + + tlock->off = rec->next; + } + tdb_unlock(tdb, tlock->list, tlock->lock_rw); + want_next = 0; + } + /* We finished iteration without finding anything */ + tdb->ecode = TDB_SUCCESS; + return 0; + + fail: + tlock->off = 0; + if (tdb_unlock(tdb, tlock->list, tlock->lock_rw) != 0) + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_next_lock: On error unlock failed!\n")); + return TDB_NEXT_LOCK_ERR; +} + +/* traverse the entire database - calling fn(tdb, key, data) on each element. + return -1 on error or the record count traversed + if fn is NULL then it is not called + a non-zero return value from fn() indicates that the traversal should stop + */ +static int tdb_traverse_internal(struct tdb_context *tdb, + tdb_traverse_func fn, void *private_data, + struct tdb_traverse_lock *tl) +{ + TDB_DATA key, dbuf; + struct tdb_record rec; + int ret = 0, count = 0; + tdb_off_t off; + size_t recbuf_len; + + recbuf_len = 4096; + key.dptr = malloc(recbuf_len); + if (key.dptr == NULL) { + return -1; + } + + /* This was in the initialization, above, but the IRIX compiler + * did not like it. crh + */ + tl->next = tdb->travlocks.next; + + /* fcntl locks don't stack: beware traverse inside traverse */ + tdb->travlocks.next = tl; + + /* tdb_next_lock places locks on the record returned, and its chain */ + while ((off = tdb_next_lock(tdb, tl, &rec)) != 0) { + tdb_len_t full_len; + int nread; + + if (off == TDB_NEXT_LOCK_ERR) { + ret = -1; + goto out; + } + + full_len = rec.key_len + rec.data_len; + + if (full_len > recbuf_len) { + recbuf_len = full_len; + + /* + * No realloc, we don't need the old data and thus can + * do without the memcpy + */ + free(key.dptr); + key.dptr = malloc(recbuf_len); + + if (key.dptr == NULL) { + ret = -1; + if (tdb_unlock(tdb, tl->list, tl->lock_rw) + != 0) { + goto out; + } + if (tdb_unlock_record(tdb, tl->off) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, + "tdb_traverse: malloc " + "failed and unlock_record " + "failed!\n")); + } + goto out; + } + } + + count++; + /* now read the full record */ + nread = tdb->methods->tdb_read(tdb, tl->off + sizeof(rec), + key.dptr, full_len, 0); + if (nread == -1) { + ret = -1; + if (tdb_unlock(tdb, tl->list, tl->lock_rw) != 0) + goto out; + if (tdb_unlock_record(tdb, tl->off) != 0) + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_traverse: key.dptr == NULL and unlock_record failed!\n")); + goto out; + } + key.dsize = rec.key_len; + dbuf.dptr = key.dptr + rec.key_len; + dbuf.dsize = rec.data_len; + + tdb_trace_1rec_retrec(tdb, "traverse", key, dbuf); + + /* Drop chain lock, call out */ + if (tdb_unlock(tdb, tl->list, tl->lock_rw) != 0) { + ret = -1; + goto out; + } + if (fn && fn(tdb, key, dbuf, private_data)) { + /* They want us to terminate traversal */ + tdb_trace_ret(tdb, "tdb_traverse_end", count); + if (tdb_unlock_record(tdb, tl->off) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_traverse: unlock_record failed!\n"));; + ret = -1; + } + goto out; + } + } + tdb_trace(tdb, "tdb_traverse_end"); +out: + SAFE_FREE(key.dptr); + tdb->travlocks.next = tl->next; + if (ret < 0) + return -1; + else + return count; +} + + +/* + a read style traverse - temporarily marks each record read only +*/ +_PUBLIC_ int tdb_traverse_read(struct tdb_context *tdb, + tdb_traverse_func fn, void *private_data) +{ + struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK }; + int ret; + + tdb->traverse_read++; + tdb_trace(tdb, "tdb_traverse_read_start"); + ret = tdb_traverse_internal(tdb, fn, private_data, &tl); + tdb->traverse_read--; + + return ret; +} + +/* + a write style traverse - needs to get the transaction lock to + prevent deadlocks + + WARNING: The data buffer given to the callback fn does NOT meet the + alignment guarantees malloc gives you. +*/ +_PUBLIC_ int tdb_traverse(struct tdb_context *tdb, + tdb_traverse_func fn, void *private_data) +{ + struct tdb_traverse_lock tl = { NULL, 0, 0, F_WRLCK }; + enum tdb_lock_flags lock_flags; + int ret; + + if (tdb->read_only || tdb->traverse_read) { + return tdb_traverse_read(tdb, fn, private_data); + } + + lock_flags = TDB_LOCK_WAIT; + + if (tdb->allrecord_lock.count != 0) { + /* + * This avoids a deadlock between tdb_lockall() and + * tdb_traverse(). See + * https://bugzilla.samba.org/show_bug.cgi?id=11381 + */ + lock_flags = TDB_LOCK_NOWAIT; + } + + if (tdb_transaction_lock(tdb, F_WRLCK, lock_flags)) { + return -1; + } + + tdb->traverse_write++; + tdb_trace(tdb, "tdb_traverse_start"); + ret = tdb_traverse_internal(tdb, fn, private_data, &tl); + tdb->traverse_write--; + + tdb_transaction_unlock(tdb, F_WRLCK); + + return ret; +} + + +/* find the first entry in the database and return its key */ +_PUBLIC_ TDB_DATA tdb_firstkey(struct tdb_context *tdb) +{ + TDB_DATA key; + struct tdb_record rec; + tdb_off_t off; + + /* release any old lock */ + if (tdb_unlock_record(tdb, tdb->travlocks.off) != 0) + return tdb_null; + tdb->travlocks.off = tdb->travlocks.list = 0; + tdb->travlocks.lock_rw = F_RDLCK; + + /* Grab first record: locks chain and returned record. */ + off = tdb_next_lock(tdb, &tdb->travlocks, &rec); + if (off == 0 || off == TDB_NEXT_LOCK_ERR) { + tdb_trace_retrec(tdb, "tdb_firstkey", tdb_null); + return tdb_null; + } + /* now read the key */ + key.dsize = rec.key_len; + key.dptr =tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),key.dsize); + + tdb_trace_retrec(tdb, "tdb_firstkey", key); + + /* Unlock the hash chain of the record we just read. */ + if (tdb_unlock(tdb, tdb->travlocks.list, tdb->travlocks.lock_rw) != 0) + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_firstkey: error occurred while tdb_unlocking!\n")); + return key; +} + +/* find the next entry in the database, returning its key */ +_PUBLIC_ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey) +{ + uint32_t oldlist; + TDB_DATA key = tdb_null; + struct tdb_record rec; + unsigned char *k = NULL; + tdb_off_t off; + + /* Is locked key the old key? If so, traverse will be reliable. */ + if (tdb->travlocks.off) { + if (tdb_lock(tdb,tdb->travlocks.list,tdb->travlocks.lock_rw)) + return tdb_null; + if (tdb_rec_read(tdb, tdb->travlocks.off, &rec) == -1 + || !(k = tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec), + rec.key_len)) + || memcmp(k, oldkey.dptr, oldkey.dsize) != 0) { + /* No, it wasn't: unlock it and start from scratch */ + if (tdb_unlock_record(tdb, tdb->travlocks.off) != 0) { + tdb_trace_1rec_retrec(tdb, "tdb_nextkey", + oldkey, tdb_null); + SAFE_FREE(k); + return tdb_null; + } + if (tdb_unlock(tdb, tdb->travlocks.list, tdb->travlocks.lock_rw) != 0) { + SAFE_FREE(k); + return tdb_null; + } + tdb->travlocks.off = 0; + } + + SAFE_FREE(k); + } + + if (!tdb->travlocks.off) { + /* No previous element: do normal find, and lock record */ + tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb->hash_fn(&oldkey), tdb->travlocks.lock_rw, &rec); + if (!tdb->travlocks.off) { + tdb_trace_1rec_retrec(tdb, "tdb_nextkey", oldkey, tdb_null); + return tdb_null; + } + tdb->travlocks.list = BUCKET(rec.full_hash); + if (tdb_lock_record(tdb, tdb->travlocks.off) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: lock_record failed (%s)!\n", strerror(errno))); + return tdb_null; + } + } + oldlist = tdb->travlocks.list; + + /* Grab next record: locks chain and returned record, + unlocks old record */ + off = tdb_next_lock(tdb, &tdb->travlocks, &rec); + if (off != TDB_NEXT_LOCK_ERR && off != 0) { + key.dsize = rec.key_len; + key.dptr = tdb_alloc_read(tdb, tdb->travlocks.off+sizeof(rec), + key.dsize); + /* Unlock the chain of this new record */ + if (tdb_unlock(tdb, tdb->travlocks.list, tdb->travlocks.lock_rw) != 0) + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n")); + } + /* Unlock the chain of old record */ + if (tdb_unlock(tdb, oldlist, tdb->travlocks.lock_rw) != 0) + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n")); + tdb_trace_1rec_retrec(tdb, "tdb_nextkey", oldkey, key); + return key; +} + +_PUBLIC_ int tdb_traverse_chain(struct tdb_context *tdb, + unsigned chain, + tdb_traverse_func fn, + void *private_data) +{ + tdb_off_t rec_ptr; + struct tdb_chainwalk_ctx chainwalk; + int count = 0; + int ret; + + if (chain >= tdb->hash_size) { + tdb->ecode = TDB_ERR_EINVAL; + return -1; + } + + if (tdb->traverse_read != 0) { + tdb->ecode = TDB_ERR_LOCK; + return -1; + } + + ret = tdb_lock(tdb, chain, F_RDLCK); + if (ret == -1) { + return -1; + } + + tdb->traverse_read += 1; + + ret = tdb_ofs_read(tdb, TDB_HASH_TOP(chain), &rec_ptr); + if (ret == -1) { + goto fail; + } + + tdb_chainwalk_init(&chainwalk, rec_ptr); + + while (rec_ptr != 0) { + struct tdb_record rec; + bool ok; + + ret = tdb_rec_read(tdb, rec_ptr, &rec); + if (ret == -1) { + goto fail; + } + + if (!TDB_DEAD(&rec)) { + /* no overflow checks, tdb_rec_read checked it */ + tdb_off_t key_ofs = rec_ptr + sizeof(rec); + size_t full_len = rec.key_len + rec.data_len; + uint8_t *buf = NULL; + + TDB_DATA key = { .dsize = rec.key_len }; + TDB_DATA data = { .dsize = rec.data_len }; + + if ((tdb->transaction == NULL) && + (tdb->map_ptr != NULL)) { + ret = tdb_oob(tdb, key_ofs, full_len, 0); + if (ret == -1) { + goto fail; + } + key.dptr = (uint8_t *)tdb->map_ptr + key_ofs; + } else { + buf = tdb_alloc_read(tdb, key_ofs, full_len); + if (buf == NULL) { + goto fail; + } + key.dptr = buf; + } + data.dptr = key.dptr + key.dsize; + + ret = fn(tdb, key, data, private_data); + free(buf); + + count += 1; + + if (ret != 0) { + break; + } + } + + rec_ptr = rec.next; + + ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); + if (!ok) { + goto fail; + } + } + tdb->traverse_read -= 1; + tdb_unlock(tdb, chain, F_RDLCK); + return count; + +fail: + tdb->traverse_read -= 1; + tdb_unlock(tdb, chain, F_RDLCK); + return -1; +} + +_PUBLIC_ int tdb_traverse_key_chain(struct tdb_context *tdb, + TDB_DATA key, + tdb_traverse_func fn, + void *private_data) +{ + uint32_t hash, chain; + int ret; + + hash = tdb->hash_fn(&key); + chain = BUCKET(hash); + ret = tdb_traverse_chain(tdb, chain, fn, private_data); + + return ret; +} diff --git a/ldb-2.0.8/lib/tdb/configure b/ldb-2.0.8/lib/tdb/configure new file mode 100755 index 0000000..d8a8d2a --- /dev/null +++ b/ldb-2.0.8/lib/tdb/configure @@ -0,0 +1,21 @@ +#!/bin/sh + +PREVPATH=`dirname $0` + +if [ -f $PREVPATH/../../buildtools/bin/waf ]; then + WAF=../../buildtools/bin/waf +elif [ -f $PREVPATH/buildtools/bin/waf ]; then + WAF=./buildtools/bin/waf +else + echo "replace: Unable to find waf" + exit 1 +fi + +# using JOBS=1 gives maximum compatibility with +# systems like AIX which have broken threading in python +JOBS=1 +export JOBS + +cd . || exit 1 +$PYTHON $WAF configure "$@" || exit 1 +cd $PREVPATH diff --git a/ldb-2.0.8/lib/tdb/docs/README b/ldb-2.0.8/lib/tdb/docs/README new file mode 100644 index 0000000..86d46a3 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/docs/README @@ -0,0 +1,273 @@ +tdb - a trivial database system +tridge@linuxcare.com December 1999 +================================== + +This is a simple database API. It was inspired by the realisation that +in Samba we have several ad-hoc bits of code that essentially +implement small databases for sharing structures between parts of +Samba. As I was about to add another I realised that a generic +database module was called for to replace all the ad-hoc bits. + +I based the interface on gdbm. I couldn't use gdbm as we need to be +able to have multiple writers to the databases at one time. + +Compilation +----------- + +add HAVE_MMAP=1 to use mmap instead of read/write +add NOLOCK=1 to disable locking code + +Testing +------- + +Compile tdbtest.c and link with gdbm for testing. tdbtest will perform +identical operations via tdb and gdbm then make sure the result is the +same + +Also included is tdbtool, which allows simple database manipulation +on the commandline. + +tdbtest and tdbtool are not built as part of Samba, but are included +for completeness. + +Interface +--------- + +The interface is very similar to gdbm except for the following: + +- different open interface. The tdb_open call is more similar to a + traditional open() +- no tdbm_reorganise() function +- no tdbm_sync() function. No operations are cached in the library anyway +- added a tdb_traverse() function for traversing the whole database +- added transactions support + +A general rule for using tdb is that the caller frees any returned +TDB_DATA structures. Just call free(p.dptr) to free a TDB_DATA +return value called p. This is the same as gdbm. + +here is a full list of tdb functions with brief descriptions. + + +---------------------------------------------------------------------- +TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode) + + open the database, creating it if necessary + + The open_flags and mode are passed straight to the open call on the database + file. A flags value of O_WRONLY is invalid + + The hash size is advisory, use zero for a default value. + + return is NULL on error + + possible tdb_flags are: + TDB_CLEAR_IF_FIRST - clear database if we are the only one with it open + TDB_INTERNAL - don't use a file, instead store the data in + memory. The filename is ignored in this case. + TDB_NOLOCK - don't do any locking + TDB_NOMMAP - don't use mmap + TDB_NOSYNC - don't synchronise transactions to disk + TDB_SEQNUM - maintain a sequence number + TDB_VOLATILE - activate the per-hashchain freelist, default 5 + TDB_ALLOW_NESTING - allow transactions to nest + TDB_DISALLOW_NESTING - disallow transactions to nest + +---------------------------------------------------------------------- +TDB_CONTEXT *tdb_open_ex(char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode, + const struct tdb_logging_context *log_ctx, + tdb_hash_func hash_fn) + +This is like tdb_open(), but allows you to pass an initial logging and +hash function. Be careful when passing a hash function - all users of +the database must use the same hash function or you will get data +corruption. + + +---------------------------------------------------------------------- +char *tdb_error(TDB_CONTEXT *tdb); + + return a error string for the last tdb error + +---------------------------------------------------------------------- +int tdb_close(TDB_CONTEXT *tdb); + + close a database + +---------------------------------------------------------------------- +TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key); + + fetch an entry in the database given a key + if the return value has a null dptr then a error occurred + + caller must free the resulting data + +---------------------------------------------------------------------- +int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, + int (*parser)(TDB_DATA key, TDB_DATA data, + void *private_data), + void *private_data); + + Hand a record to a parser function without allocating it. + + This function is meant as a fast tdb_fetch alternative for large records + that are frequently read. The "key" and "data" arguments point directly + into the tdb shared memory, they are not aligned at any boundary. + + WARNING: The parser is called while tdb holds a lock on the record. DO NOT + call other tdb routines from within the parser. Also, for good performance + you should make the parser fast to allow parallel operations. + + tdb_parse_record returns -1 if the record was not found. If the record was + found, the return value of "parser" is passed up to the caller. + +---------------------------------------------------------------------- +int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key); + + check if an entry in the database exists + + note that 1 is returned if the key is found and 0 is returned if not found + this doesn't match the conventions in the rest of this module, but is + compatible with gdbm + +---------------------------------------------------------------------- +int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, + TDB_DATA key, TDB_DATA dbuf, void *state), void *state); + + traverse the entire database - calling fn(tdb, key, data, state) on each + element. + + return -1 on error or the record count traversed + + if fn is NULL then it is not called + + a non-zero return value from fn() indicates that the traversal + should stop. Traversal callbacks may not start transactions. + + WARNING: The data buffer given to the callback fn does NOT meet the + alignment restrictions malloc gives you. + +---------------------------------------------------------------------- +int tdb_traverse_read(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, + TDB_DATA key, TDB_DATA dbuf, void *state), void *state); + + traverse the entire database - calling fn(tdb, key, data, state) on + each element, but marking the database read only during the + traversal, so any write operations will fail. This allows tdb to + use read locks, which increases the parallelism possible during the + traversal. + + return -1 on error or the record count traversed + + if fn is NULL then it is not called + + a non-zero return value from fn() indicates that the traversal + should stop. Traversal callbacks may not start transactions. + +---------------------------------------------------------------------- +TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb); + + find the first entry in the database and return its key + + the caller must free the returned data + +---------------------------------------------------------------------- +TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key); + + find the next entry in the database, returning its key + + the caller must free the returned data + +---------------------------------------------------------------------- +int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key); + + delete an entry in the database given a key + +---------------------------------------------------------------------- +int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); + + store an element in the database, replacing any existing element + with the same key + + If flag==TDB_INSERT then don't overwrite an existing entry + If flag==TDB_MODIFY then don't create a new entry + + return 0 on success, -1 on failure + +---------------------------------------------------------------------- +int tdb_writelock(TDB_CONTEXT *tdb); + + lock the database. If we already have it locked then don't do anything + +---------------------------------------------------------------------- +int tdb_writeunlock(TDB_CONTEXT *tdb); + unlock the database + +---------------------------------------------------------------------- +int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key); + + lock one hash chain. This is meant to be used to reduce locking + contention - it cannot guarantee how many records will be locked + +---------------------------------------------------------------------- +int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key); + + unlock one hash chain + +---------------------------------------------------------------------- +int tdb_transaction_start(TDB_CONTEXT *tdb) + + start a transaction. All operations after the transaction start can + either be committed with tdb_transaction_commit() or cancelled with + tdb_transaction_cancel(). + + If you call tdb_transaction_start() again on the same tdb context + while a transaction is in progress, then the same transaction + buffer is re-used. The number of tdb_transaction_{commit,cancel} + operations must match the number of successful + tdb_transaction_start() calls. + + Note that transactions are by default disk synchronous, and use a + recover area in the database to automatically recover the database + on the next open if the system crashes during a transaction. You + can disable the synchronous transaction recovery setup using the + TDB_NOSYNC flag, which will greatly speed up operations at the risk + of corrupting your database if the system crashes. + + Operations made within a transaction are not visible to other users + of the database until a successful commit. + +---------------------------------------------------------------------- +int tdb_transaction_cancel(TDB_CONTEXT *tdb) + + cancel a current transaction, discarding all write and lock + operations that have been made since the transaction started. + + +---------------------------------------------------------------------- +int tdb_transaction_commit(TDB_CONTEXT *tdb) + + commit a current transaction, updating the database and releasing + the transaction locks. + +---------------------------------------------------------------------- +int tdb_transaction_prepare_commit(TDB_CONTEXT *tdb) + + prepare to commit a current transaction, for two-phase commits. + Once prepared for commit, the only allowed calls are + tdb_transaction_commit() or tdb_transaction_cancel(). Preparing + allocates disk space for the pending updates, so a subsequent + commit should succeed (barring any hardware failures). + +---------------------------------------------------------------------- +int tdb_check(TDB_CONTEXT *tdb, + int (*check)(TDB_DATA key, TDB_DATA data, void *private_data), + void *private_data);) + + check the consistency of the database, calling back the check function + (if non-NULL) with each record. If some consistency check fails, or + the supplied check function returns -1, tdb_check returns -1, otherwise + 0. Note that logging function (if set) will be called with additional + information on the corruption found. diff --git a/ldb-2.0.8/lib/tdb/docs/mainpage.dox b/ldb-2.0.8/lib/tdb/docs/mainpage.dox new file mode 100644 index 0000000..d130769 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/docs/mainpage.dox @@ -0,0 +1,61 @@ +/** + +@mainpage + +This is a simple database API. It was inspired by the realisation that in Samba +we have several ad-hoc bits of code that essentially implement small databases +for sharing structures between parts of Samba. + +The interface is based on gdbm. gdbm couldn't be use as we needed to be able to +have multiple writers to the databases at one time. + +@section tdb_download Download + +You can download the latest releases of tdb from the +tdb directory on the samba public source +archive. + +You can download the latest code either via git or rsync. + +To fetch via git see the following guide: + +Using Git for Samba Development +Once you have cloned the tree switch to the master branch and cd into the source/lib/tdb directory. + +To fetch via rsync use these commands: + +
      +  rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/tdb .
      +  rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/replace .
      +
      + +and build in tdb. It will find the replace library in the directory above +automatically. + +@section tdb_bugs Discussion and bug reports + +tdb does not currently have its own mailing list or bug tracking system. For now, +please use the +samba-technical +mailing list, and the Samba bugzilla bug +tracking system. + + +@section tdb_compilation Compilation + +add HAVE_MMAP=1 to use mmap instead of read/write +add NOLOCK=1 to disable locking code + +@section tdb_testing Testing + +Compile tdbtest.c and link with gdbm for testing. tdbtest will perform +identical operations via tdb and gdbm then make sure the result is the +same + +Also included is tdbtool, which allows simple database manipulation +on the commandline. + +tdbtest and tdbtool are not built as part of Samba, but are included +for completeness. + +*/ diff --git a/ldb-2.0.8/lib/tdb/docs/mutex.txt b/ldb-2.0.8/lib/tdb/docs/mutex.txt new file mode 100644 index 0000000..a5a7542 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/docs/mutex.txt @@ -0,0 +1,136 @@ +Tdb is a hashtable database with multiple concurrent writer and external +record lock support. For speed reasons, wherever possible tdb uses a shared +memory mapped area for data access. In its currently released form, it uses +fcntl byte-range locks to coordinate access to the data itself. + +The tdb data is organized as a hashtable. Hash collisions are dealt with by +forming a linked list of records that share a hash value. The individual +linked lists are protected across processes with 1-byte fcntl locks on the +starting pointer of the linked list representing a hash value. + +The external locking API of tdb allows one to lock individual records. Instead of +really locking individual records, the tdb API locks a complete linked list +with a fcntl lock. + +The external locking API of tdb also allows one to lock the complete database, and +ctdb uses this facility to freeze databases during a recovery. While the +so-called allrecord lock is held, all linked lists and all individual records +are frozen alltogether. Tdb achieves this by locking the complete file range +with a single fcntl lock. Individual 1-byte locks for the linked lists +conflict with this. Access to records is prevented by the one large fnctl byte +range lock. + +Fcntl locks have been chosen for tdb for two reasons: First they are portable +across all current unixes. Secondly they provide auto-cleanup. If a process +dies while holding a fcntl lock, the lock is given up as if it was explicitly +unlocked. Thus fcntl locks provide a very robust locking scheme, if a process +dies for any reason the database will not stay blocked until reboot. This +robustness is very important for long-running services, a reboot is not an +option for most users of tdb. + +Unfortunately, during stress testing, fcntl locks have turned out to be a major +problem for performance. The particular problem that was seen happens when +ctdb on a busy server does a recovery. A recovery means that ctdb has to +freeze all tdb databases for some time, usually a few seconds. This is done +with the allrecord lock. During the recovery phase on a busy server many smbd +processes try to access the tdb file with blocking fcntl calls. The specific +test in question easily reproduces 7,000 processes piling up waiting for +1-byte fcntl locks. When ctdb is done with the recovery, it gives up the +allrecord lock, covering the whole file range. All 7,000 processes waiting for +1-byte fcntl locks are woken up, trying to acquire their lock. The special +implementation of fcntl locks in Linux (up to 2013-02-12 at least) protects +all fcntl lock operations with a single system-wide spinlock. If 7,000 process +waiting for the allrecord lock to become released this leads to a thundering +herd condition, all CPUs are spinning on that single spinlock. + +Functionally the kernel is fine, eventually the thundering herd slows down and +every process correctly gets his share and locking range, but the performance +of the system while the herd is active is worse than expected. + +The thundering herd is only the worst case scenario for fcntl lock use. The +single spinlock for fcntl operations is also a performance penalty for normal +operations. In the cluster case, every read and write SMB request has to do +two fcntl calls to provide correct SMB mandatory locks. The single spinlock +is one source of serialization for the SMB read/write requests, limiting the +parallelism that can be achieved in a multi-core system. + +While trying to tune his servers, Ira Cooper, Samba Team member, found fcntl +locks to be a problem on Solaris as well. Ira pointed out that there is a +potential alternative locking mechanism that might be more scalable: Process +shared robust mutexes, as defined by Posix 2008 for example via + +http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_setpshared.html +http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_setrobust.html + +Pthread mutexes provide one of the core mechanisms in posix threads to protect +in-process data structures from concurrent access by multiple threads. In the +Linux implementation, a pthread_mutex_t is represented by a data structure in +user space that requires no kernel calls in the uncontended case for locking +and unlocking. Locking and unlocking in the uncontended case is implemented +purely in user space with atomic CPU instructions and thus are very fast. + +The setpshared functions indicate to the kernel that the mutex is about to be +shared between processes in a common shared memory area. + +The process shared posix mutexes have the potential to replace fcntl locking +to coordinate mmap access for tdbs. However, they are missing the criticial +auto-cleanup property that fcntl provides when a process dies. A process that +dies hard while holding a shared mutex has no chance to clean up the protected +data structures and unlock the shared mutex. Thus with a pure process shared +mutex the mutex will remain locked forever until the data structures are +re-initialized from scratch. + +With the robust mutexes defined by Posix the process shared mutexes have been +extended with a limited auto-cleanup property. If a mutex has been declared +robust, when a process exits while holding that mutex, the next process trying +to lock the mutex will get the special error message EOWNERDEAD. This informs +the caller that the data structures the mutex protects are potentially corrupt +and need to be cleaned up. + +The error message EOWNERDEAD when trying to lock a mutex is an extension over +the fcntl functionality. A process that does a blocking fcntl lock call is not +informed about whether the lock was explicitly freed by a process still alive +or due to an unplanned process exit. At the time of this writing (February +2013), at least Linux and OpenSolaris also implement the robustness feature of +process-shared mutexes. + +Converting the tdb locking mechanism from fcntl to mutexes has to take care of +both types of locks that are used on tdb files. + +The easy part is to use mutexes to replace the 1-byte linked list locks +covering the individual hashes. Those can be represented by a mutex each. + +Covering the allrecord lock is more difficult. The allrecord lock uses a fcntl +lock spanning all hash list locks simultaneously. This basic functionality is +not easily possible with mutexes. A mutex carries 1 bit of information, a +fcntl lock can carry an arbitrary amount of information. + +In order to support the allrecord lock, we have an allrecord_lock variable +protected by an allrecord_mutex. The coordination between the allrecord lock +and the chainlocks works like this: + +- Getting a chain lock works like this: + + 1. get chain mutex + 2. return success if allrecord_lock is F_UNLCK (not locked) + 3. return success if allrecord_lock is F_RDLCK (locked readonly) + and we only need a read lock. + 4. release chain mutex + 5. wait for allrecord_mutex + 6. unlock allrecord_mutex + 7. goto 1. + +- Getting the allrecord lock: + + 1. get the allrecord mutex + 2. return error if allrecord_lock is not F_UNLCK (it's locked) + 3. set allrecord_lock to the desired value. + 4. in a loop: lock(blocking) / unlock each chain mutex. + 5. return success. + +- allrecord lock upgrade: + + 1. check we already have the allrecord lock with F_RDLCK. + 3. set allrecord_lock to F_WRLCK + 4. in a loop: lock(blocking) / unlock each chain mutex. + 5. return success. diff --git a/ldb-2.0.8/lib/tdb/docs/tdb.magic b/ldb-2.0.8/lib/tdb/docs/tdb.magic new file mode 100644 index 0000000..f5619e7 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/docs/tdb.magic @@ -0,0 +1,10 @@ +# Magic file(1) information about tdb files. +# +# Install this into /etc/magic or the corresponding location for your +# system, or pass as a -m argument to file(1). + +# You may use and redistribute this file without restriction. + +0 string TDB\ file TDB database +>32 lelong =0x2601196D version 6, little-endian +>>36 lelong x hash size %d bytes diff --git a/ldb-2.0.8/lib/tdb/docs/tracing.txt b/ldb-2.0.8/lib/tdb/docs/tracing.txt new file mode 100644 index 0000000..98c5db9 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/docs/tracing.txt @@ -0,0 +1,46 @@ +How And Why To Use TDB Tracing +============================== + +You can trace all TDB operations, using TDB_TRACE. It is not complete +(error conditions which expect to the logged will not always be traced +correctly, so you should set up a logging function too), but is designed +to collect benchmark-style traces to allow us to optimize TDB. + +Note: tracing is not efficient, and the trace files are huge: a +traverse of the database is particularly large! But they compress very +well with rzip (http://rzip.samba.org) + +How to gather trace files: +-------------------------- +1) Uncomment /* #define TDB_TRACE 1 */ in tdb_private.h. +2) Rebuild TDB, and everything that uses it. +3) Run something. + +Your trace files will be called .trace.. These files +will not be overwritten: if the same process reopens the same TDB, an +error will be logged and tracing will be disabled. + +How to replay trace files: +-------------------------- +1) For benchmarking, remember to rebuild tdb with #define TDB_TRACE commented + out again! +2) Grab the latest "replace_trace.c" from CCAN's tdb module (tools/ dir): + http://ccan.ozlabs.org/tarballs/tdb.tar.bz2 +3) Compile up replay_trace, munging as necessary. +4) Run replay_trace ... + +If given more than one trace file (presumably from the same tdb) +replay_trace will try to figure out the dependencies between the operations +and fire off a child to run each trace. Occasionally it gets stuck, in +which case it will add another dependency and retry. Eventually it will +give a speed value. + +replay_trace can intuit the existence of previous data in the tdb (ie. +activity prior to the trace(s) supplied) and will prepopulate as +neccessary. + +You can run --quiet for straight benchmark results, and -n to run multiple +times (this saves time, since it need only calculate dependencies once). + +Good luck! +Rusty Russell diff --git a/ldb-2.0.8/lib/tdb/doxy.config b/ldb-2.0.8/lib/tdb/doxy.config new file mode 100644 index 0000000..f55e9c3 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/doxy.config @@ -0,0 +1,1697 @@ +# Doxyfile 1.7.3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = tdb + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1.2.9 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description for a project that appears at the top of each page and should give viewer a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = docs + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = NO + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = YES + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even if there is only one candidate or it is obvious which candidate to choose by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = include \ + docs + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.cpp \ + *.cc \ + *.c \ + *.h \ + *.hh \ + *.hpp \ + *.dox + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = */.git/* + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = NO + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [0,1..20]) +# that doxygen will group on one line in the generated HTML documentation. +# Note that a value of 0 will completely suppress the enum values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NONE + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the mathjax.org site, so you can quickly see the result without installing +# MathJax, but it is strongly recommended to install a local copy of MathJax +# before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = NO + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = YES + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = YES + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = DOXYGEN \ + PRINTF_ATTRIBUTE(x,y)= + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will write a font called Helvetica to the output +# directory and reference it in all dot files that doxygen generates. +# When you want a differently looking font you can specify the font name +# using DOT_FONTNAME. You need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, svg, gif or svg. +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = YES + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/ldb-2.0.8/lib/tdb/include/tdb.h b/ldb-2.0.8/lib/tdb/include/tdb.h new file mode 100644 index 0000000..825ceed --- /dev/null +++ b/ldb-2.0.8/lib/tdb/include/tdb.h @@ -0,0 +1,1025 @@ +#ifndef __TDB_H__ +#define __TDB_H__ + +/* + Unix SMB/CIFS implementation. + + trivial database library + + Copyright (C) Andrew Tridgell 1999-2004 + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * @defgroup tdb The tdb API + * + * tdb is a Trivial database. In concept, it is very much like GDBM, and BSD's + * DB except that it allows multiple simultaneous writers and uses locking + * internally to keep writers from trampling on each other. tdb is also + * extremely small. + * + * @section tdb_interface Interface + * + * The interface is very similar to gdbm except for the following: + * + *
        + *
      • different open interface. The tdb_open call is more similar to a + * traditional open()
      • + *
      • no tdbm_reorganise() function
      • + *
      • no tdbm_sync() function. No operations are cached in the library + * anyway
      • + *
      • added a tdb_traverse() function for traversing the whole database
      • + *
      • added transactions support
      • + *
      + * + * A general rule for using tdb is that the caller frees any returned TDB_DATA + * structures. Just call free(p.dptr) to free a TDB_DATA return value called p. + * This is the same as gdbm. + * + * @{ + */ + +/** Flags to tdb_store() */ +#define TDB_REPLACE 1 /** Unused */ +#define TDB_INSERT 2 /** Don't overwrite an existing entry */ +#define TDB_MODIFY 3 /** Don't create an existing entry */ + +/** Flags for tdb_open() */ +#define TDB_DEFAULT 0 /** just a readability place holder */ +#define TDB_CLEAR_IF_FIRST 1 /** If this is the first open, wipe the db */ +#define TDB_INTERNAL 2 /** Don't store on disk */ +#define TDB_NOLOCK 4 /** Don't do any locking */ +#define TDB_NOMMAP 8 /** Don't use mmap */ +#define TDB_CONVERT 16 /** Convert endian (internal use) */ +#define TDB_BIGENDIAN 32 /** Header is big-endian (internal use) */ +#define TDB_NOSYNC 64 /** Don't use synchronous transactions */ +#define TDB_SEQNUM 128 /** Maintain a sequence number */ +#define TDB_VOLATILE 256 /** Activate the per-hashchain freelist, default 5 */ +#define TDB_ALLOW_NESTING 512 /** Allow transactions to nest */ +#define TDB_DISALLOW_NESTING 1024 /** Disallow transactions to nest */ +#define TDB_INCOMPATIBLE_HASH 2048 /** Better hashing: can't be opened by tdb < 1.2.6. */ +#define TDB_MUTEX_LOCKING 4096 /** optimized locking using robust mutexes if supported, + only with tdb >= 1.3.0 and TDB_CLEAR_IF_FIRST + after checking tdb_runtime_check_for_robust_mutexes() */ + +/** The tdb error codes */ +enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK, + TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT, + TDB_ERR_NOEXIST, TDB_ERR_EINVAL, TDB_ERR_RDONLY, + TDB_ERR_NESTING}; + +/** Debugging uses one of the following levels */ +enum tdb_debug_level {TDB_DEBUG_FATAL = 0, TDB_DEBUG_ERROR, + TDB_DEBUG_WARNING, TDB_DEBUG_TRACE}; + +/** The tdb data structure */ +typedef struct TDB_DATA { + unsigned char *dptr; + size_t dsize; +} TDB_DATA; + +#ifndef PRINTF_ATTRIBUTE +#if (__GNUC__ >= 3) +/** Use gcc attribute to check printf fns. a1 is the 1-based index of + * the parameter containing the format, and a2 the index of the first + * argument. Note that some gcc 2.x versions don't handle this + * properly **/ +#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) +#else +#define PRINTF_ATTRIBUTE(a1, a2) +#endif +#endif + +/** This is the context structure that is returned from a db open. */ +typedef struct tdb_context TDB_CONTEXT; + +typedef int (*tdb_traverse_func)(struct tdb_context *, TDB_DATA, TDB_DATA, void *); +typedef void (*tdb_log_func)(struct tdb_context *, enum tdb_debug_level, const char *, ...) PRINTF_ATTRIBUTE(3, 4); +typedef unsigned int (*tdb_hash_func)(TDB_DATA *key); + +struct tdb_logging_context { + tdb_log_func log_fn; + void *log_private; +}; + +/** + * @brief Open the database and creating it if necessary. + * + * @param[in] name The name of the db to open. + * + * @param[in] hash_size The hash size is advisory, use zero for a default + * value. + * + * @param[in] tdb_flags The flags to use to open the db:\n\n + * TDB_CLEAR_IF_FIRST - Clear database if we are the + * only one with it open\n + * TDB_INTERNAL - Don't use a file, instead store the + * data in memory. The filename is + * ignored in this case.\n + * TDB_NOLOCK - Don't do any locking\n + * TDB_NOMMAP - Don't use mmap\n + * TDB_NOSYNC - Don't synchronise transactions to disk\n + * TDB_SEQNUM - Maintain a sequence number\n + * TDB_VOLATILE - activate the per-hashchain freelist, + * default 5.\n + * TDB_ALLOW_NESTING - Allow transactions to nest.\n + * TDB_DISALLOW_NESTING - Disallow transactions to nest.\n + * TDB_INCOMPATIBLE_HASH - Better hashing: can't be opened by tdb < 1.2.6.\n + * TDB_MUTEX_LOCKING - Optimized locking using robust mutexes if supported, + * can't be opened by tdb < 1.3.0. + * Only valid in combination with TDB_CLEAR_IF_FIRST + * after checking tdb_runtime_check_for_robust_mutexes()\n + * + * @param[in] open_flags Flags for the open(2) function. + * + * @param[in] mode The mode for the open(2) function. + * + * @return A tdb context structure, NULL on error. + */ +struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode); + +/** + * @brief Open the database and creating it if necessary. + * + * This is like tdb_open(), but allows you to pass an initial logging and + * hash function. Be careful when passing a hash function - all users of the + * database must use the same hash function or you will get data corruption. + * + * @param[in] name The name of the db to open. + * + * @param[in] hash_size The hash size is advisory, use zero for a default + * value. + * + * @param[in] tdb_flags The flags to use to open the db:\n\n + * TDB_CLEAR_IF_FIRST - Clear database if we are the + * only one with it open\n + * TDB_INTERNAL - Don't use a file, instead store the + * data in memory. The filename is + * ignored in this case.\n + * TDB_NOLOCK - Don't do any locking\n + * TDB_NOMMAP - Don't use mmap\n + * TDB_NOSYNC - Don't synchronise transactions to disk\n + * TDB_SEQNUM - Maintain a sequence number\n + * TDB_VOLATILE - activate the per-hashchain freelist, + * default 5.\n + * TDB_ALLOW_NESTING - Allow transactions to nest.\n + * TDB_DISALLOW_NESTING - Disallow transactions to nest.\n + * TDB_INCOMPATIBLE_HASH - Better hashing: can't be opened by tdb < 1.2.6.\n + * TDB_MUTEX_LOCKING - Optimized locking using robust mutexes if supported, + * can't be opened by tdb < 1.3.0. + * Only valid in combination with TDB_CLEAR_IF_FIRST + * after checking tdb_runtime_check_for_robust_mutexes()\n + * + * @param[in] open_flags Flags for the open(2) function. + * + * @param[in] mode The mode for the open(2) function. + * + * @param[in] log_ctx The logging function to use. + * + * @param[in] hash_fn The hash function you want to use. + * + * @return A tdb context structure, NULL on error. + * + * @see tdb_open() + */ +struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode, + const struct tdb_logging_context *log_ctx, + tdb_hash_func hash_fn); + +/** + * @brief Set the maximum number of dead records per hash chain. + * + * @param[in] tdb The database handle to set the maximum. + * + * @param[in] max_dead The maximum number of dead records per hash chain. + */ +void tdb_set_max_dead(struct tdb_context *tdb, int max_dead); + +/** + * @brief Reopen a tdb. + * + * This can be used after a fork to ensure that we have an independent seek + * pointer from our parent and to re-establish locks. + * + * @param[in] tdb The database to reopen. It will be free'd on error! + * + * @return 0 on success, -1 on error. + * + * @note Don't call tdb_error() after this function cause the tdb context will + * be freed on error. + */ +int tdb_reopen(struct tdb_context *tdb); + +/** + * @brief Reopen all tdb's + * + * If the parent is longlived (ie. a parent daemon architecture), we know it + * will keep it's active lock on a tdb opened with CLEAR_IF_FIRST. Thus for + * child processes we don't have to add an active lock. This is essential to + * improve performance on systems that keep POSIX locks as a non-scalable data + * structure in the kernel. + * + * @param[in] parent_longlived Whether the parent is longlived or not. + * + * @return 0 on success, -1 on error. + */ +int tdb_reopen_all(int parent_longlived); + +/** + * @brief Set a different tdb logging function. + * + * @param[in] tdb The tdb to set the logging function. + * + * @param[in] log_ctx The logging function to set. + */ +void tdb_set_logging_function(struct tdb_context *tdb, const struct tdb_logging_context *log_ctx); + +/** + * @brief Get the tdb last error code. + * + * @param[in] tdb The tdb to get the error code from. + * + * @return A TDB_ERROR code. + * + * @see TDB_ERROR + */ +enum TDB_ERROR tdb_error(struct tdb_context *tdb); + +/** + * @brief Get a error string for the last tdb error + * + * @param[in] tdb The tdb to get the error code from. + * + * @return An error string. + */ +const char *tdb_errorstr(struct tdb_context *tdb); + +/** + * @brief Fetch an entry in the database given a key. + * + * The caller must free the resulting data. + * + * @param[in] tdb The tdb to fetch the key. + * + * @param[in] key The key to fetch. + * + * @return The key entry found in the database, NULL on error with + * TDB_ERROR set. + * + * @see tdb_error() + * @see tdb_errorstr() + */ +TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key); + +/** + * @brief Hand a record to a parser function without allocating it. + * + * This function is meant as a fast tdb_fetch alternative for large records + * that are frequently read. The "key" and "data" arguments point directly + * into the tdb shared memory, they are not aligned at any boundary. + * + * @warning The parser is called while tdb holds a lock on the record. DO NOT + * call other tdb routines from within the parser. Also, for good performance + * you should make the parser fast to allow parallel operations. + * + * @param[in] tdb The tdb to parse the record. + * + * @param[in] key The key to parse. + * + * @param[in] parser The parser to use to parse the data. + * + * @param[in] private_data A private data pointer which is passed to the parser + * function. + * + * @return -1 if the record was not found. If the record was found, + * the return value of "parser" is passed up to the caller. + */ +int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, + int (*parser)(TDB_DATA key, TDB_DATA data, + void *private_data), + void *private_data); + +/** + * @brief Delete an entry in the database given a key. + * + * @param[in] tdb The tdb to delete the key. + * + * @param[in] key The key to delete. + * + * @return 0 on success, -1 if the key doesn't exist. + */ +int tdb_delete(struct tdb_context *tdb, TDB_DATA key); + +/** + * @brief Store an element in the database. + * + * This replaces any existing element with the same key. + * + * @param[in] tdb The tdb to store the entry. + * + * @param[in] key The key to use to store the entry. + * + * @param[in] dbuf The data to store under the key. + * + * @param[in] flag The flags to store the key:\n\n + * TDB_INSERT: Don't overwrite an existing entry.\n + * TDB_MODIFY: Don't create a new entry\n + * + * @return 0 on success, -1 on error with error code set. + * + * @see tdb_error() + * @see tdb_errorstr() + */ +int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); + + +/** + * @brief Store an element in the database. + * + * This replaces any existing element with the same key. + * + * @param[in] tdb The tdb to store the entry. + * + * @param[in] key The key to use to store the entry. + * + * @param[in] dbufs A vector of memory chunks to write + * + * @param[in] num_dbufs Length of the dbufs vector + * + * @param[in] flag The flags to store the key:\n\n + * TDB_INSERT: Don't overwrite an existing entry.\n + * TDB_MODIFY: Don't create a new entry\n + * + * @return 0 on success, -1 on error with error code set. + * + * @see tdb_error() + * @see tdb_errorstr() + */ +int tdb_storev(struct tdb_context *tdb, TDB_DATA key, + const TDB_DATA *dbufs, int num_dbufs, int flag); + +/** + * @brief Append data to an entry. + * + * If the entry doesn't exist, it will create a new one. + * + * @param[in] tdb The database to use. + * + * @param[in] key The key to append the data. + * + * @param[in] new_dbuf The data to append to the key. + * + * @return 0 on success, -1 on error with error code set. + * + * @see tdb_error() + * @see tdb_errorstr() + */ +int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf); + +/** + * @brief Close a database. + * + * @param[in] tdb The database to close. The context will be free'd. + * + * @return 0 for success, -1 on error. + * + * @note Don't call tdb_error() after this function cause the tdb context will + * be freed on error. + */ +int tdb_close(struct tdb_context *tdb); + +/** + * @brief Find the first entry in the database and return its key. + * + * The caller must free the returned data. + * + * @param[in] tdb The database to use. + * + * @return The first entry of the database, an empty TDB_DATA entry + * if the database is empty. + */ +TDB_DATA tdb_firstkey(struct tdb_context *tdb); + +/** + * @brief Find the next entry in the database, returning its key. + * + * The caller must free the returned data. + * + * @param[in] tdb The database to use. + * + * @param[in] key The key from which you want the next key. + * + * @return The next entry of the current key, an empty TDB_DATA + * entry if there is no entry. + */ +TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA key); + +/** + * @brief Traverse the entire database. + * + * While traversing the function fn(tdb, key, data, state) is called on each + * element. If fn is NULL then it is not called. A non-zero return value from + * fn() indicates that the traversal should stop. Traversal callbacks may not + * start transactions. + * + * @warning The data buffer given to the callback fn does NOT meet the alignment + * restrictions malloc gives you. + * + * @param[in] tdb The database to traverse. + * + * @param[in] fn The function to call on each entry. + * + * @param[in] private_data The private data which should be passed to the + * traversing function. + * + * @return The record count traversed, -1 on error. + */ +int tdb_traverse(struct tdb_context *tdb, tdb_traverse_func fn, void *private_data); + +/** + * @brief Traverse the entire database. + * + * While traversing the database the function fn(tdb, key, data, state) is + * called on each element, but marking the database read only during the + * traversal, so any write operations will fail. This allows tdb to use read + * locks, which increases the parallelism possible during the traversal. + * + * @param[in] tdb The database to traverse. + * + * @param[in] fn The function to call on each entry. + * + * @param[in] private_data The private data which should be passed to the + * traversing function. + * + * @return The record count traversed, -1 on error. + */ +int tdb_traverse_read(struct tdb_context *tdb, tdb_traverse_func fn, void *private_data); + +/** + * @brief Traverse a single hash chain + * + * Traverse a single hash chain under a single lock operation. No + * database modification is possible in the callback. + * + * This exists for background cleanup of databases. In normal + * operations, traversing a complete database can be much too + * expensive. Databases can have many chains, which will all have to + * be looked at before tdb_traverse finishes. Also tdb_traverse does a + * lot of fcntl activity to protect against concurrent record deletes. + * + * With this you can walk a fraction of the whole tdb, collect the + * entries you want to prune, leave the traverse, and then modify or + * delete the records in a subsequent step. + * + * To walk the entire database, call this function tdb_hash_size() + * times, with 0<=chain + + +2015-04-25 + + + tdbbackup + 8 + Samba + System Administration tools + 3.6 + + + + + tdbbackup + tool for backing up and for validating the integrity of samba .tdb files + + + + + tdbbackup + -s suffix + -v + -h + -n hashsize + -l + + + + + DESCRIPTION + + This tool is part of the samba + 1 suite. + + tdbbackup is a tool that may be used to backup samba .tdb + files. This tool may also be used to verify the integrity of the .tdb files prior + to samba startup or during normal operation. If it finds file damage and it finds + a prior backup the backup file will be restored. + + + + + + OPTIONS + + + + + -h + + Get help information. + + + + + -s suffix + + The -s option allows the administrator to specify a file + backup extension. This way it is possible to keep a history of tdb backup + files by using a new suffix for each backup. + + + + + -v + + The -v will check the database for damages (corrupt data) + which if detected causes the backup to be restored. + + + + + -n hashsize + + The -n option sets the hash size for the new backup tdb. + + + + + -l + + This options disables any locking, by passing TDB_NOLOCK + to tdb_open_ex(). Only use this for database files which + are not used by any other process! And also only if it is otherwise not + possible to open the database, e.g. databases which were created with + mutex locking. + + + + + + + + + COMMANDS + + GENERAL INFORMATION + + + The tdbbackup utility can safely be run at any time. It was designed so + that it can be used at any time to validate the integrity of tdb files, even during Samba + operation. Typical usage for the command will be: + + + tdbbackup [-s suffix] *.tdb + + + Before restarting samba the following command may be run to validate .tdb files: + + + tdbbackup -v [-s suffix] *.tdb + + + Samba .tdb files are stored in various locations, be sure to run backup all + .tdb file on the system. Important files includes: + + + + + secrets.tdb - usual location is in the /usr/local/samba/private + directory, or on some systems in /etc/samba. + + + + passdb.tdb - usual location is in the /usr/local/samba/private + directory, or on some systems in /etc/samba. + + + + *.tdb located in the /usr/local/samba/var directory or on some + systems in the /var/cache or /var/lib/samba directories. + + + + + + + VERSION + + This man page is correct for version 3 of the Samba suite. + + + + AUTHOR + + + The original Samba software and related utilities were created by Andrew Tridgell. + Samba is now developed by the Samba Team as an Open Source project similar to the way + the Linux kernel is developed. + + + The tdbbackup man page was written by John H Terpstra. + + + diff --git a/ldb-2.0.8/lib/tdb/man/tdbdump.8.xml b/ldb-2.0.8/lib/tdb/man/tdbdump.8.xml new file mode 100644 index 0000000..31e6888 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/man/tdbdump.8.xml @@ -0,0 +1,93 @@ + + + +2015-04-25 + + + tdbdump + 8 + Samba + System Administration tools + 3.6 + + + + + tdbdump + tool for printing the contents of a TDB file + + + + + tdbdump + -k keyname + -e + -h + filename + + + + + DESCRIPTION + + This tool is part of the samba + 1 suite. + + tdbdump is a very simple utility that 'dumps' the + contents of a TDB (Trivial DataBase) file to standard output in a + human-readable format. + + + This tool can be used when debugging problems with TDB files. It is + intended for those who are somewhat familiar with Samba internals. + + + + + OPTIONS + + + + + -h + + Get help information. + + + + + -k keyname + + The -k option restricts dumping to a single key, if found. + + + + + -e + + The -e tries to dump out from a corrupt database. Naturally, such a dump is unreliable, at best. + + + + + + + + VERSION + + This man page is correct for version 3 of the Samba suite. + + + + AUTHOR + + + The original Samba software and related utilities were created by Andrew Tridgell. + Samba is now developed by the Samba Team as an Open Source project similar to the way + the Linux kernel is developed. + + + The tdbdump man page was written by Jelmer Vernooij. + + + diff --git a/ldb-2.0.8/lib/tdb/man/tdbrestore.8.xml b/ldb-2.0.8/lib/tdb/man/tdbrestore.8.xml new file mode 100644 index 0000000..034db53 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/man/tdbrestore.8.xml @@ -0,0 +1,67 @@ + + + +2015-04-25 + + + tdbrestore + 8 + Samba + System Administration tools + 3.6 + + + + + tdbrestore + tool for creating a TDB file out of a tdbdump output + + + + + tdbrestore + tdbfilename + + + + + DESCRIPTION + + This tool is part of the samba + 1 suite. + + tdbrestore is a very simple utility that 'restores' the + contents of dump file into TDB (Trivial DataBase) file. The dump file is obtained from the tdbdump + command. + + + This tool wait on the standard input for the content of the dump and will write the tdb in the tdbfilename + parameter. + + This tool can be used for unpacking the content of tdb as backup mean. + + + + + + VERSION + + This man page is correct for version 3 of the Samba suite. + + + + AUTHOR + + + The original Samba software and related utilities were created by Andrew Tridgell. + Samba is now developed by the Samba Team as an Open Source project similar to the way + the Linux kernel is developed. + + This tool was initially written by Volker Lendecke based on an + idea by Simon McVittie. + + + The tdbrestore man page was written by Matthieu Patou. + + + diff --git a/ldb-2.0.8/lib/tdb/man/tdbtool.8.xml b/ldb-2.0.8/lib/tdb/man/tdbtool.8.xml new file mode 100644 index 0000000..045cbde --- /dev/null +++ b/ldb-2.0.8/lib/tdb/man/tdbtool.8.xml @@ -0,0 +1,275 @@ + + + +2015-04-25 + + + tdbtool + 8 + Samba + System Administration tools + 4.0 + + + + + tdbtool + manipulate the contents TDB files + + + + + + tdbtool + + + + tdbtool + -l + + TDBFILE + + + COMMANDS + + + + + + + DESCRIPTION + + This tool is part of the + samba + 1 suite. + + tdbtool a tool for displaying and + altering the contents of Samba TDB (Trivial DataBase) files. Each + of the commands listed below can be entered interactively or + provided on the command line. + + + + + OPTIONS + + + + + -l + + This options disables any locking, by passing TDB_NOLOCK + to tdb_open_ex(). Only use this for database files which + are not used by any other process! And also only if it is otherwise not + possible to open the database, e.g. databases which were created with + mutex locking. + + + + + + + + + + COMMANDS + + + + + + TDBFILE + Create a new database named + TDBFILE. + + + + + + TDBFILE + Open an existing database named + TDBFILE. + + + + + + Erase the current database. + + + + + + Dump the current database as strings. + + + + + + Dump the current database as connection records. + + + + + + Dump the current database keys as strings. + + + + + + Dump the current database keys as hex values. + + + + + + Print summary information about the + current database. + + + + + + KEY + DATA + + Insert a record into the + current database. + + + + + + KEY + TDBFILE + + Move a record from the + current database into TDBFILE. + + + + + + KEY + DATA + + Store (replace) a record in the + current database. + + + + + + KEY + DATA + + Store (replace) a record in the + current database where key and data are in hex format. + + + + + + KEY + + Show a record by key. + + + + + + KEY + + Delete a record by key. + + + + + + + Print the current database hash table and free list. + + + + + + + Print the current database and free list. + + + + + + COMMAND + + Execute the given system command. + + + + + + + + Print the first record in the current database. + + + + + + + + Print the next record in the current database. + + + + + + + + Check the integrity of the current database. + + + + + + + + Repack a database using a temporary file to remove fragmentation. + + + + + + + + Exit tdbtool. + + + + + + + + CAVEATS + The contents of the Samba TDB files are private + to the implementation and should not be altered with + tdbtool. + + + + + VERSION + This man page is correct for version 3.6 of the Samba suite. + + + + AUTHOR + + The original Samba software and related utilities were + created by Andrew Tridgell. Samba is now developed by the + Samba Team as an Open Source project similar to the way the + Linux kernel is developed. + + + diff --git a/ldb-2.0.8/lib/tdb/pytdb.c b/ldb-2.0.8/lib/tdb/pytdb.c new file mode 100644 index 0000000..74e80f9 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/pytdb.c @@ -0,0 +1,830 @@ +/* + Unix SMB/CIFS implementation. + + Python interface to tdb. + + Copyright (C) 2004-2006 Tim Potter + Copyright (C) 2007-2008 Jelmer Vernooij + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include +#include "replace.h" +#include "system/filesys.h" + +/* Include tdb headers */ +#include + +#if PY_MAJOR_VERSION >= 3 +#define PyInt_FromLong PyLong_FromLong +#define PyInt_Check PyLong_Check +#define PyInt_AsLong PyLong_AsLong +#define Py_TPFLAGS_HAVE_ITER 0 +#endif + +/* discard signature of 'func' in favour of 'target_sig' */ +#define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func + +typedef struct { + PyObject_HEAD + TDB_CONTEXT *ctx; + bool closed; +} PyTdbObject; + +static PyTypeObject PyTdb; + +static void PyErr_SetTDBError(TDB_CONTEXT *tdb) +{ + PyErr_SetObject(PyExc_RuntimeError, + Py_BuildValue("(i,s)", tdb_error(tdb), tdb_errorstr(tdb))); +} + +static TDB_DATA PyBytes_AsTDB_DATA(PyObject *data) +{ + TDB_DATA ret; + ret.dptr = (unsigned char *)PyBytes_AsString(data); + ret.dsize = PyBytes_Size(data); + return ret; +} + +static PyObject *PyBytes_FromTDB_DATA(TDB_DATA data) +{ + if (data.dptr == NULL && data.dsize == 0) { + Py_RETURN_NONE; + } else { + PyObject *ret = PyBytes_FromStringAndSize((const char *)data.dptr, + data.dsize); + free(data.dptr); + return ret; + } +} + +#define PyErr_TDB_ERROR_IS_ERR_RAISE(ret, tdb) \ + if (ret != 0) { \ + PyErr_SetTDBError(tdb); \ + return NULL; \ + } + +#define PyErr_TDB_RAISE_IF_CLOSED(self) \ + if (self->closed) { \ + PyErr_SetObject(PyExc_RuntimeError, \ + Py_BuildValue("(i,s)", TDB_ERR_IO, "Database is already closed")); \ + return NULL; \ + } + +#define PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED(self) \ + if (self->closed) { \ + PyErr_SetObject(PyExc_RuntimeError, \ + Py_BuildValue("(i,s)", TDB_ERR_IO, "Database is already closed")); \ + return -1; \ + } + +static PyObject *py_tdb_open(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + char *name = NULL; + int hash_size = 0, tdb_flags = TDB_DEFAULT, flags = O_RDWR, mode = 0600; + TDB_CONTEXT *ctx; + PyTdbObject *ret; + const char *_kwnames[] = { "name", "hash_size", "tdb_flags", "flags", "mode", NULL }; + char **kwnames = discard_const_p(char *, _kwnames); + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|siiii", kwnames, &name, &hash_size, &tdb_flags, &flags, &mode)) + return NULL; + + if (name == NULL) { + tdb_flags |= TDB_INTERNAL; + } + + ctx = tdb_open(name, hash_size, tdb_flags, flags, mode); + if (ctx == NULL) { + PyErr_SetFromErrno(PyExc_IOError); + return NULL; + } + + ret = PyObject_New(PyTdbObject, &PyTdb); + if (!ret) { + tdb_close(ctx); + return NULL; + } + + ret->ctx = ctx; + ret->closed = false; + return (PyObject *)ret; +} + +static PyObject *obj_transaction_cancel(PyTdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + int ret; + + PyErr_TDB_RAISE_IF_CLOSED(self); + + ret = tdb_transaction_cancel(self->ctx); + PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); + Py_RETURN_NONE; +} + +static PyObject *obj_transaction_commit(PyTdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + int ret; + PyErr_TDB_RAISE_IF_CLOSED(self); + ret = tdb_transaction_commit(self->ctx); + PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); + Py_RETURN_NONE; +} + +static PyObject *obj_transaction_prepare_commit(PyTdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + int ret; + PyErr_TDB_RAISE_IF_CLOSED(self); + ret = tdb_transaction_prepare_commit(self->ctx); + PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); + Py_RETURN_NONE; +} + +static PyObject *obj_transaction_start(PyTdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + int ret; + PyErr_TDB_RAISE_IF_CLOSED(self); + ret = tdb_transaction_start(self->ctx); + PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); + Py_RETURN_NONE; +} + +static PyObject *obj_reopen(PyTdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + int ret; + PyErr_TDB_RAISE_IF_CLOSED(self); + ret = tdb_reopen(self->ctx); + if (ret != 0) { + self->closed = true; + PyErr_SetObject(PyExc_RuntimeError, + Py_BuildValue("(i,s)", + TDB_ERR_IO, + "Failed to reopen database")); + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject *obj_lockall(PyTdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + int ret; + PyErr_TDB_RAISE_IF_CLOSED(self); + ret = tdb_lockall(self->ctx); + PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); + Py_RETURN_NONE; +} + +static PyObject *obj_unlockall(PyTdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + int ret; + PyErr_TDB_RAISE_IF_CLOSED(self); + ret = tdb_unlockall(self->ctx); + PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); + Py_RETURN_NONE; +} + +static PyObject *obj_lockall_read(PyTdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + int ret; + PyErr_TDB_RAISE_IF_CLOSED(self); + ret = tdb_lockall_read(self->ctx); + PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); + Py_RETURN_NONE; +} + +static PyObject *obj_unlockall_read(PyTdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + int ret = tdb_unlockall_read(self->ctx); + PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); + Py_RETURN_NONE; +} + +static PyObject *obj_close(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) +{ + int ret; + if (self->closed) + Py_RETURN_NONE; + ret = tdb_close(self->ctx); + self->closed = true; + if (ret != 0) { + PyErr_SetObject(PyExc_RuntimeError, + Py_BuildValue("(i,s)", + TDB_ERR_IO, + "Failed to close database")); + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject *obj_get(PyTdbObject *self, PyObject *args) +{ + TDB_DATA key; + PyObject *py_key; + + PyErr_TDB_RAISE_IF_CLOSED(self); + + if (!PyArg_ParseTuple(args, "O", &py_key)) + return NULL; + + key = PyBytes_AsTDB_DATA(py_key); + if (!key.dptr) + return NULL; + + return PyBytes_FromTDB_DATA(tdb_fetch(self->ctx, key)); +} + +static PyObject *obj_append(PyTdbObject *self, PyObject *args) +{ + TDB_DATA key, data; + PyObject *py_key, *py_data; + int ret; + + PyErr_TDB_RAISE_IF_CLOSED(self); + + if (!PyArg_ParseTuple(args, "OO", &py_key, &py_data)) + return NULL; + + key = PyBytes_AsTDB_DATA(py_key); + if (!key.dptr) + return NULL; + data = PyBytes_AsTDB_DATA(py_data); + if (!data.dptr) + return NULL; + + ret = tdb_append(self->ctx, key, data); + PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); + Py_RETURN_NONE; +} + +static PyObject *obj_firstkey(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyErr_TDB_RAISE_IF_CLOSED(self); + + return PyBytes_FromTDB_DATA(tdb_firstkey(self->ctx)); +} + +static PyObject *obj_nextkey(PyTdbObject *self, PyObject *args) +{ + TDB_DATA key; + PyObject *py_key; + PyErr_TDB_RAISE_IF_CLOSED(self); + + if (!PyArg_ParseTuple(args, "O", &py_key)) + return NULL; + + key = PyBytes_AsTDB_DATA(py_key); + if (!key.dptr) + return NULL; + + return PyBytes_FromTDB_DATA(tdb_nextkey(self->ctx, key)); +} + +static PyObject *obj_delete(PyTdbObject *self, PyObject *args) +{ + TDB_DATA key; + PyObject *py_key; + int ret; + PyErr_TDB_RAISE_IF_CLOSED(self); + + if (!PyArg_ParseTuple(args, "O", &py_key)) + return NULL; + + key = PyBytes_AsTDB_DATA(py_key); + if (!key.dptr) + return NULL; + ret = tdb_delete(self->ctx, key); + PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); + Py_RETURN_NONE; +} + +static int obj_contains(PyTdbObject *self, PyObject *py_key) +{ + TDB_DATA key; + int ret; + PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED(self); + + key = PyBytes_AsTDB_DATA(py_key); + if (!key.dptr) { + PyErr_BadArgument(); + return -1; + } + ret = tdb_exists(self->ctx, key); + if (ret) + return 1; + return 0; +} + +#if PY_MAJOR_VERSION < 3 +static PyObject *obj_has_key(PyTdbObject *self, PyObject *args) +{ + int ret; + PyObject *py_key; + PyErr_TDB_RAISE_IF_CLOSED(self); + + if (!PyArg_ParseTuple(args, "O", &py_key)) + return NULL; + + ret = obj_contains(self, py_key); + if (ret == -1) + return NULL; + if (ret) + Py_RETURN_TRUE; + Py_RETURN_FALSE; + +} +#endif + +static PyObject *obj_store(PyTdbObject *self, PyObject *args) +{ + TDB_DATA key, value; + int ret; + int flag = TDB_REPLACE; + PyObject *py_key, *py_value; + + PyErr_TDB_RAISE_IF_CLOSED(self); + + if (!PyArg_ParseTuple(args, "OO|i", &py_key, &py_value, &flag)) + return NULL; + + key = PyBytes_AsTDB_DATA(py_key); + if (!key.dptr) + return NULL; + value = PyBytes_AsTDB_DATA(py_value); + if (!value.dptr) + return NULL; + + ret = tdb_store(self->ctx, key, value, flag); + PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); + Py_RETURN_NONE; +} + +static PyObject *obj_add_flags(PyTdbObject *self, PyObject *args) +{ + unsigned flags; + + PyErr_TDB_RAISE_IF_CLOSED(self); + + if (!PyArg_ParseTuple(args, "I", &flags)) + return NULL; + + tdb_add_flags(self->ctx, flags); + Py_RETURN_NONE; +} + +static PyObject *obj_remove_flags(PyTdbObject *self, PyObject *args) +{ + unsigned flags; + + PyErr_TDB_RAISE_IF_CLOSED(self); + + if (!PyArg_ParseTuple(args, "I", &flags)) + return NULL; + + tdb_remove_flags(self->ctx, flags); + Py_RETURN_NONE; +} + +typedef struct { + PyObject_HEAD + TDB_DATA current; + PyTdbObject *iteratee; +} PyTdbIteratorObject; + +static PyObject *tdb_iter_next(PyTdbIteratorObject *self) +{ + TDB_DATA current; + PyObject *ret; + if (self->current.dptr == NULL && self->current.dsize == 0) + return NULL; + current = self->current; + self->current = tdb_nextkey(self->iteratee->ctx, self->current); + ret = PyBytes_FromTDB_DATA(current); + return ret; +} + +static void tdb_iter_dealloc(PyTdbIteratorObject *self) +{ + Py_DECREF(self->iteratee); + PyObject_Del(self); +} + +PyTypeObject PyTdbIterator = { + .tp_name = "Iterator", + .tp_basicsize = sizeof(PyTdbIteratorObject), + .tp_iternext = (iternextfunc)tdb_iter_next, + .tp_dealloc = (destructor)tdb_iter_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_iter = PyObject_SelfIter, +}; + +static PyObject *tdb_object_iter(PyTdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + PyTdbIteratorObject *ret; + + PyErr_TDB_RAISE_IF_CLOSED(self); + + ret = PyObject_New(PyTdbIteratorObject, &PyTdbIterator); + if (!ret) + return NULL; + ret->current = tdb_firstkey(self->ctx); + ret->iteratee = self; + Py_INCREF(self); + return (PyObject *)ret; +} + +static PyObject *obj_clear(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) +{ + int ret; + PyErr_TDB_RAISE_IF_CLOSED(self); + ret = tdb_wipe_all(self->ctx); + PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); + Py_RETURN_NONE; +} + +static PyObject *obj_repack(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) +{ + int ret; + PyErr_TDB_RAISE_IF_CLOSED(self); + ret = tdb_repack(self->ctx); + PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); + Py_RETURN_NONE; +} + +static PyObject *obj_enable_seqnum(PyTdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + PyErr_TDB_RAISE_IF_CLOSED(self); + tdb_enable_seqnum(self->ctx); + Py_RETURN_NONE; +} + +static PyObject *obj_increment_seqnum_nonblock(PyTdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + PyErr_TDB_RAISE_IF_CLOSED(self); + tdb_increment_seqnum_nonblock(self->ctx); + Py_RETURN_NONE; +} + +static PyMethodDef tdb_object_methods[] = { + { "transaction_cancel", (PyCFunction)obj_transaction_cancel, METH_NOARGS, + "S.transaction_cancel() -> None\n" + "Cancel the currently active transaction." }, + { "transaction_commit", (PyCFunction)obj_transaction_commit, METH_NOARGS, + "S.transaction_commit() -> None\n" + "Commit the currently active transaction." }, + { "transaction_prepare_commit", (PyCFunction)obj_transaction_prepare_commit, METH_NOARGS, + "S.transaction_prepare_commit() -> None\n" + "Prepare to commit the currently active transaction" }, + { "transaction_start", (PyCFunction)obj_transaction_start, METH_NOARGS, + "S.transaction_start() -> None\n" + "Start a new transaction." }, + { "reopen", (PyCFunction)obj_reopen, METH_NOARGS, "Reopen this file." }, + { "lock_all", (PyCFunction)obj_lockall, METH_NOARGS, NULL }, + { "unlock_all", (PyCFunction)obj_unlockall, METH_NOARGS, NULL }, + { "read_lock_all", (PyCFunction)obj_lockall_read, METH_NOARGS, NULL }, + { "read_unlock_all", (PyCFunction)obj_unlockall_read, METH_NOARGS, NULL }, + { "close", (PyCFunction)obj_close, METH_NOARGS, NULL }, + { "get", (PyCFunction)obj_get, METH_VARARGS, "S.get(key) -> value\n" + "Fetch a value." }, + { "append", (PyCFunction)obj_append, METH_VARARGS, "S.append(key, value) -> None\n" + "Append data to an existing key." }, + { "firstkey", (PyCFunction)obj_firstkey, METH_NOARGS, "S.firstkey() -> data\n" + "Return the first key in this database." }, + { "nextkey", (PyCFunction)obj_nextkey, METH_VARARGS, "S.nextkey(key) -> data\n" + "Return the next key in this database." }, + { "delete", (PyCFunction)obj_delete, METH_VARARGS, "S.delete(key) -> None\n" + "Delete an entry." }, +#if PY_MAJOR_VERSION < 3 + { "has_key", (PyCFunction)obj_has_key, METH_VARARGS, "S.has_key(key) -> None\n" + "Check whether key exists in this database." }, +#endif + { "store", (PyCFunction)obj_store, METH_VARARGS, "S.store(key, data, flag=REPLACE) -> None" + "Store data." }, + { "add_flags", (PyCFunction)obj_add_flags, METH_VARARGS, "S.add_flags(flags) -> None" }, + { "remove_flags", (PyCFunction)obj_remove_flags, METH_VARARGS, "S.remove_flags(flags) -> None" }, +#if PY_MAJOR_VERSION >= 3 + { "keys", (PyCFunction)tdb_object_iter, METH_NOARGS, "S.iterkeys() -> iterator" }, +#else + { "iterkeys", (PyCFunction)tdb_object_iter, METH_NOARGS, "S.iterkeys() -> iterator" }, +#endif + { "clear", (PyCFunction)obj_clear, METH_NOARGS, "S.clear() -> None\n" + "Wipe the entire database." }, + { "repack", (PyCFunction)obj_repack, METH_NOARGS, "S.repack() -> None\n" + "Repack the entire database." }, + { "enable_seqnum", (PyCFunction)obj_enable_seqnum, METH_NOARGS, + "S.enable_seqnum() -> None" }, + { "increment_seqnum_nonblock", (PyCFunction)obj_increment_seqnum_nonblock, METH_NOARGS, + "S.increment_seqnum_nonblock() -> None" }, + { NULL } +}; + +static PyObject *obj_get_hash_size(PyTdbObject *self, void *closure) +{ + PyErr_TDB_RAISE_IF_CLOSED(self); + return PyInt_FromLong(tdb_hash_size(self->ctx)); +} + +static int obj_set_max_dead(PyTdbObject *self, PyObject *max_dead, void *closure) +{ + PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED(self); + if (!PyInt_Check(max_dead)) + return -1; + tdb_set_max_dead(self->ctx, PyInt_AsLong(max_dead)); + return 0; +} + +static PyObject *obj_get_map_size(PyTdbObject *self, void *closure) +{ + PyErr_TDB_RAISE_IF_CLOSED(self); + return PyInt_FromLong(tdb_map_size(self->ctx)); +} + +static PyObject *obj_get_freelist_size(PyTdbObject *self, void *closure) +{ + PyErr_TDB_RAISE_IF_CLOSED(self); + return PyInt_FromLong(tdb_freelist_size(self->ctx)); +} + +static PyObject *obj_get_flags(PyTdbObject *self, void *closure) +{ + PyErr_TDB_RAISE_IF_CLOSED(self); + return PyInt_FromLong(tdb_get_flags(self->ctx)); +} + +static PyObject *obj_get_filename(PyTdbObject *self, void *closure) +{ + PyErr_TDB_RAISE_IF_CLOSED(self); + return PyBytes_FromString(tdb_name(self->ctx)); +} + +static PyObject *obj_get_seqnum(PyTdbObject *self, void *closure) +{ + PyErr_TDB_RAISE_IF_CLOSED(self); + return PyInt_FromLong(tdb_get_seqnum(self->ctx)); +} + +static PyObject *obj_get_text(PyTdbObject *self, void *closure) +{ + PyObject *mod, *cls, *inst; + mod = PyImport_ImportModule("_tdb_text"); + if (mod == NULL) + return NULL; + cls = PyObject_GetAttrString(mod, "TdbTextWrapper"); + if (cls == NULL) { + Py_DECREF(mod); + return NULL; + } + inst = PyObject_CallFunction(cls, discard_const_p(char, "O"), self); + Py_DECREF(mod); + Py_DECREF(cls); + return inst; +} + +static PyGetSetDef tdb_object_getsetters[] = { + { + .name = discard_const_p(char, "hash_size"), + .get = (getter)obj_get_hash_size, + }, + { + .name = discard_const_p(char, "map_size"), + .get = (getter)obj_get_map_size, + }, + { + .name = discard_const_p(char, "freelist_size"), + .get = (getter)obj_get_freelist_size, + }, + { + .name = discard_const_p(char, "flags"), + .get = (getter)obj_get_flags, + }, + { + .name = discard_const_p(char, "max_dead"), + .set = (setter)obj_set_max_dead, + }, + { + .name = discard_const_p(char, "filename"), + .get = (getter)obj_get_filename, + .doc = discard_const_p(char, "The filename of this TDB file."), + }, + { + .name = discard_const_p(char, "seqnum"), + .get = (getter)obj_get_seqnum, + }, + { + .name = discard_const_p(char, "text"), + .get = (getter)obj_get_text, + }, + { .name = NULL } +}; + +static PyObject *tdb_object_repr(PyTdbObject *self) +{ + PyErr_TDB_RAISE_IF_CLOSED(self); + if (tdb_get_flags(self->ctx) & TDB_INTERNAL) { + return PyUnicode_FromString("Tdb()"); + } else { + return PyUnicode_FromFormat("Tdb('%s')", tdb_name(self->ctx)); + } +} + +static void tdb_object_dealloc(PyTdbObject *self) +{ + if (!self->closed) + tdb_close(self->ctx); + Py_TYPE(self)->tp_free(self); +} + +static PyObject *obj_getitem(PyTdbObject *self, PyObject *key) +{ + TDB_DATA tkey, val; + PyErr_TDB_RAISE_IF_CLOSED(self); + if (!PyBytes_Check(key)) { + PyErr_SetString(PyExc_TypeError, "Expected bytestring as key"); + return NULL; + } + + tkey.dptr = (unsigned char *)PyBytes_AsString(key); + tkey.dsize = PyBytes_Size(key); + + val = tdb_fetch(self->ctx, tkey); + if (val.dptr == NULL) { + /* + * if the key doesn't exist raise KeyError(key) to be + * consistent with python dict + */ + PyErr_SetObject(PyExc_KeyError, key); + return NULL; + } else { + return PyBytes_FromTDB_DATA(val); + } +} + +static int obj_setitem(PyTdbObject *self, PyObject *key, PyObject *value) +{ + TDB_DATA tkey, tval; + int ret; + PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED(self); + if (!PyBytes_Check(key)) { + PyErr_SetString(PyExc_TypeError, "Expected bytestring as key"); + return -1; + } + + tkey = PyBytes_AsTDB_DATA(key); + + if (value == NULL) { + ret = tdb_delete(self->ctx, tkey); + } else { + if (!PyBytes_Check(value)) { + PyErr_SetString(PyExc_TypeError, "Expected string as value"); + return -1; + } + + tval = PyBytes_AsTDB_DATA(value); + + ret = tdb_store(self->ctx, tkey, tval, TDB_REPLACE); + } + + if (ret != 0) { + PyErr_SetTDBError(self->ctx); + return -1; + } + + return ret; +} + +static PyMappingMethods tdb_object_mapping = { + .mp_subscript = (binaryfunc)obj_getitem, + .mp_ass_subscript = (objobjargproc)obj_setitem, +}; +static PySequenceMethods tdb_object_seq = { + .sq_contains = (objobjproc)obj_contains, +}; +static PyTypeObject PyTdb = { + .tp_name = "tdb.Tdb", + .tp_basicsize = sizeof(PyTdbObject), + .tp_methods = tdb_object_methods, + .tp_getset = tdb_object_getsetters, + .tp_new = py_tdb_open, + .tp_doc = "A TDB file", + .tp_repr = (reprfunc)tdb_object_repr, + .tp_dealloc = (destructor)tdb_object_dealloc, + .tp_as_mapping = &tdb_object_mapping, + .tp_as_sequence = &tdb_object_seq, + .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_ITER, + .tp_iter = PY_DISCARD_FUNC_SIG(getiterfunc,tdb_object_iter), +}; + +static PyMethodDef tdb_methods[] = { + { + .ml_name = "open", + .ml_meth = PY_DISCARD_FUNC_SIG(PyCFunction, py_tdb_open), + .ml_flags = METH_VARARGS|METH_KEYWORDS, + .ml_doc = "open(name, hash_size=0, tdb_flags=TDB_DEFAULT, " + "flags=O_RDWR, mode=0600)\nOpen a TDB file." + }, + { .ml_name = NULL } +}; + +#define MODULE_DOC "simple key-value database that supports multiple writers." + +#if PY_MAJOR_VERSION >= 3 +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + .m_name = "tdb", + .m_doc = MODULE_DOC, + .m_size = -1, + .m_methods = tdb_methods, +}; +#endif + +PyObject* module_init(void); +PyObject* module_init(void) +{ + PyObject *m; + + if (PyType_Ready(&PyTdb) < 0) + return NULL; + + if (PyType_Ready(&PyTdbIterator) < 0) + return NULL; + +#if PY_MAJOR_VERSION >= 3 + m = PyModule_Create(&moduledef); +#else + m = Py_InitModule3("tdb", tdb_methods, MODULE_DOC); +#endif + if (m == NULL) + return NULL; + + PyModule_AddIntConstant(m, "REPLACE", TDB_REPLACE); + PyModule_AddIntConstant(m, "INSERT", TDB_INSERT); + PyModule_AddIntConstant(m, "MODIFY", TDB_MODIFY); + + PyModule_AddIntConstant(m, "DEFAULT", TDB_DEFAULT); + PyModule_AddIntConstant(m, "CLEAR_IF_FIRST", TDB_CLEAR_IF_FIRST); + PyModule_AddIntConstant(m, "INTERNAL", TDB_INTERNAL); + PyModule_AddIntConstant(m, "NOLOCK", TDB_NOLOCK); + PyModule_AddIntConstant(m, "NOMMAP", TDB_NOMMAP); + PyModule_AddIntConstant(m, "CONVERT", TDB_CONVERT); + PyModule_AddIntConstant(m, "BIGENDIAN", TDB_BIGENDIAN); + PyModule_AddIntConstant(m, "NOSYNC", TDB_NOSYNC); + PyModule_AddIntConstant(m, "SEQNUM", TDB_SEQNUM); + PyModule_AddIntConstant(m, "VOLATILE", TDB_VOLATILE); + PyModule_AddIntConstant(m, "ALLOW_NESTING", TDB_ALLOW_NESTING); + PyModule_AddIntConstant(m, "DISALLOW_NESTING", TDB_DISALLOW_NESTING); + PyModule_AddIntConstant(m, "INCOMPATIBLE_HASH", TDB_INCOMPATIBLE_HASH); + + PyModule_AddStringConstant(m, "__docformat__", "restructuredText"); + + PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION); + + Py_INCREF(&PyTdb); + PyModule_AddObject(m, "Tdb", (PyObject *)&PyTdb); + + Py_INCREF(&PyTdbIterator); + + return m; +} + + +#if PY_MAJOR_VERSION >= 3 +PyMODINIT_FUNC PyInit_tdb(void); +PyMODINIT_FUNC PyInit_tdb(void) +{ + return module_init(); +} +#else +void inittdb(void); +void inittdb(void) +{ + module_init(); +} +#endif diff --git a/ldb-2.0.8/lib/tdb/python/tdbdump.py b/ldb-2.0.8/lib/tdb/python/tdbdump.py new file mode 100644 index 0000000..306a950 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/python/tdbdump.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 +# Trivial reimplementation of tdbdump in Python + +from __future__ import print_function +import tdb, sys + +if len(sys.argv) < 2: + print("Usage: tdbdump.py ") + sys.exit(1) + +db = tdb.Tdb(sys.argv[1]) +for (k, v) in db.items(): + print("{\nkey(%d) = %r\ndata(%d) = %r\n}" % (len(k), k, len(v), v)) diff --git a/ldb-2.0.8/lib/tdb/python/tests/simple.py b/ldb-2.0.8/lib/tdb/python/tests/simple.py new file mode 100644 index 0000000..312d587 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/python/tests/simple.py @@ -0,0 +1,311 @@ +#!/usr/bin/env python3 +# Some simple tests for the Python bindings for TDB +# Note that this tests the interface of the Python bindings +# It does not test tdb itself. +# +# Copyright (C) 2007-2008 Jelmer Vernooij +# Published under the GNU LGPLv3 or later + +import sys +import os +import tempfile +from unittest import TestCase + +import tdb + + +class OpenTdbTests(TestCase): + + def test_nonexistent_read(self): + self.assertRaises(IOError, tdb.Tdb, "/some/nonexistent/file", 0, + tdb.DEFAULT, os.O_RDWR) + +class CloseTdbTests(TestCase): + + def test_double_close(self): + self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, + os.O_CREAT|os.O_RDWR) + self.assertNotEqual(None, self.tdb) + + # ensure that double close does not crash python + self.tdb.close() + self.tdb.close() + + # Check that further operations do not crash python + self.assertRaises(RuntimeError, lambda: self.tdb.transaction_start()) + + self.assertRaises(RuntimeError, lambda: self.tdb["bar"]) + + +class InternalTdbTests(TestCase): + + def test_repr(self): + self.tdb = tdb.Tdb() + + # repr used to crash on internal db + self.assertEqual(repr(self.tdb), "Tdb()") + + +class CommonTdbTests(TestCase): + """Tests common to both the text & bytes interfaces""" + + use_text = False + + def setUp(self): + super(CommonTdbTests, self).setUp() + self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, + os.O_CREAT|os.O_RDWR) + self.assertNotEqual(None, self.tdb) + if self.use_text: + self.tdb = self.tdb.text + + def test_lockall(self): + self.tdb.lock_all() + + def test_max_dead(self): + self.tdb.max_dead = 20 + + def test_unlockall(self): + self.tdb.lock_all() + self.tdb.unlock_all() + + def test_lockall_read(self): + self.tdb.read_lock_all() + self.tdb.read_unlock_all() + + def test_reopen(self): + self.tdb.reopen() + + def test_hash_size(self): + self.tdb.hash_size + + def test_map_size(self): + self.tdb.map_size + + def test_freelist_size(self): + self.tdb.freelist_size + + def test_name(self): + self.tdb.filename + + def test_add_flags(self): + self.tdb.add_flags(tdb.NOMMAP) + self.tdb.remove_flags(tdb.NOMMAP) + + +class TextCommonTdbTests(CommonTdbTests): + + use_text = True + + +class SimpleTdbTests(TestCase): + + def setUp(self): + super(SimpleTdbTests, self).setUp() + self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, + os.O_CREAT|os.O_RDWR) + self.assertNotEqual(None, self.tdb) + + def test_repr(self): + self.assertTrue(repr(self.tdb).startswith("Tdb('")) + + def test_store(self): + self.tdb.store(b"bar", b"bla") + self.assertEqual(b"bla", self.tdb.get(b"bar")) + + def test_getitem(self): + self.tdb[b"bar"] = b"foo" + self.tdb.reopen() + self.assertEqual(b"foo", self.tdb[b"bar"]) + + def test_delete(self): + self.tdb[b"bar"] = b"foo" + del self.tdb[b"bar"] + self.assertRaises(KeyError, lambda: self.tdb[b"bar"]) + + def test_contains(self): + self.tdb[b"bla"] = b"bloe" + self.assertTrue(b"bla" in self.tdb) + self.assertFalse(b"qwertyuiop" in self.tdb) + if sys.version_info < (3, 0): + self.assertTrue(self.tdb.has_key(b"bla")) + self.assertFalse(self.tdb.has_key(b"qwertyuiop")) + + def test_keyerror(self): + self.assertRaises(KeyError, lambda: self.tdb[b"bla"]) + + def test_iterator(self): + self.tdb[b"bla"] = b"1" + self.tdb[b"brainslug"] = b"2" + l = list(self.tdb) + l.sort() + self.assertEqual([b"bla", b"brainslug"], l) + + def test_transaction_cancel(self): + self.tdb[b"bloe"] = b"2" + self.tdb.transaction_start() + self.tdb[b"bloe"] = b"1" + self.tdb.transaction_cancel() + self.assertEqual(b"2", self.tdb[b"bloe"]) + + def test_transaction_commit(self): + self.tdb[b"bloe"] = b"2" + self.tdb.transaction_start() + self.tdb[b"bloe"] = b"1" + self.tdb.transaction_commit() + self.assertEqual(b"1", self.tdb[b"bloe"]) + + def test_transaction_prepare_commit(self): + self.tdb[b"bloe"] = b"2" + self.tdb.transaction_start() + self.tdb[b"bloe"] = b"1" + self.tdb.transaction_prepare_commit() + self.tdb.transaction_commit() + self.assertEqual(b"1", self.tdb[b"bloe"]) + + def test_iterkeys(self): + self.tdb[b"bloe"] = b"2" + self.tdb[b"bla"] = b"25" + if sys.version_info >= (3, 0): + i = self.tdb.keys() + else: + i = self.tdb.iterkeys() + self.assertEqual(set([b"bloe", b"bla"]), set([next(i), next(i)])) + + def test_clear(self): + self.tdb[b"bloe"] = b"2" + self.tdb[b"bla"] = b"25" + self.assertEqual(2, len(list(self.tdb))) + self.tdb.clear() + self.assertEqual(0, len(list(self.tdb))) + + def test_repack(self): + self.tdb[b"foo"] = b"abc" + self.tdb[b"bar"] = b"def" + del self.tdb[b"foo"] + self.tdb.repack() + + def test_seqnum(self): + self.tdb.enable_seqnum() + seq1 = self.tdb.seqnum + self.tdb.increment_seqnum_nonblock() + seq2 = self.tdb.seqnum + self.assertEqual(seq2-seq1, 1) + + def test_len(self): + self.assertEqual(0, len(list(self.tdb))) + self.tdb[b"entry"] = b"value" + self.assertEqual(1, len(list(self.tdb))) + + +class TdbTextTests(TestCase): + + def setUp(self): + super(TdbTextTests, self).setUp() + self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, + os.O_CREAT|os.O_RDWR) + self.assertNotEqual(None, self.tdb) + + def test_repr(self): + self.assertTrue(repr(self.tdb).startswith("Tdb('")) + + def test_store(self): + self.tdb.text.store("bar", "bla") + self.assertEqual("bla", self.tdb.text.get("bar")) + + def test_getitem(self): + self.tdb.text["bar"] = "foo" + self.tdb.reopen() + self.assertEqual("foo", self.tdb.text["bar"]) + + def test_delete(self): + self.tdb.text["bar"] = "foo" + del self.tdb.text["bar"] + self.assertRaises(KeyError, lambda: self.tdb.text["bar"]) + + def test_contains(self): + self.tdb.text["bla"] = "bloe" + self.assertTrue("bla" in self.tdb.text) + self.assertFalse("qwertyuiop" in self.tdb.text) + if sys.version_info < (3, 0): + self.assertTrue(self.tdb.text.has_key("bla")) + self.assertFalse(self.tdb.text.has_key("qwertyuiop")) + + def test_keyerror(self): + self.assertRaises(KeyError, lambda: self.tdb.text["bla"]) + + def test_iterator(self): + self.tdb.text["bla"] = "1" + self.tdb.text["brainslug"] = "2" + l = list(self.tdb.text) + l.sort() + self.assertEqual(["bla", "brainslug"], l) + + def test_transaction_cancel(self): + self.tdb.text["bloe"] = "2" + self.tdb.transaction_start() + self.tdb.text["bloe"] = "1" + self.tdb.transaction_cancel() + self.assertEqual("2", self.tdb.text["bloe"]) + + def test_transaction_commit(self): + self.tdb.text["bloe"] = "2" + self.tdb.transaction_start() + self.tdb.text["bloe"] = "1" + self.tdb.transaction_commit() + self.assertEqual("1", self.tdb.text["bloe"]) + + def test_transaction_prepare_commit(self): + self.tdb.text["bloe"] = "2" + self.tdb.transaction_start() + self.tdb.text["bloe"] = "1" + self.tdb.transaction_prepare_commit() + self.tdb.transaction_commit() + self.assertEqual("1", self.tdb.text["bloe"]) + + def test_iterkeys(self): + self.tdb.text["bloe"] = "2" + self.tdb.text["bla"] = "25" + if sys.version_info >= (3, 0): + i = self.tdb.text.keys() + else: + i = self.tdb.text.iterkeys() + self.assertEqual(set(["bloe", "bla"]), set([next(i), next(i)])) + + def test_clear(self): + self.tdb.text["bloe"] = "2" + self.tdb.text["bla"] = "25" + self.assertEqual(2, len(list(self.tdb))) + self.tdb.clear() + self.assertEqual(0, len(list(self.tdb))) + + def test_repack(self): + self.tdb.text["foo"] = "abc" + self.tdb.text["bar"] = "def" + del self.tdb.text["foo"] + self.tdb.repack() + + def test_len(self): + self.assertEqual(0, len(list(self.tdb.text))) + self.tdb.text["entry"] = "value" + self.assertEqual(1, len(list(self.tdb.text))) + + def test_text_and_binary(self): + text = u'\xfa\u0148\xef\xe7\xf8\xf0\xea' + bytestr = text.encode('utf-8') + self.tdb[b"entry"] = bytestr + self.tdb.text[u"entry2"] = text + self.assertEqual(self.tdb.text["entry"], text) + self.assertEqual(self.tdb[b"entry2"], bytestr) + assert self.tdb.text.raw == self.tdb + + +class VersionTests(TestCase): + + def test_present(self): + self.assertTrue(isinstance(tdb.__version__, str)) + + +if __name__ == '__main__': + import unittest + unittest.TestProgram() diff --git a/ldb-2.0.8/lib/tdb/tdb.pc.in b/ldb-2.0.8/lib/tdb/tdb.pc.in new file mode 100644 index 0000000..b78419e --- /dev/null +++ b/ldb-2.0.8/lib/tdb/tdb.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: tdb +Description: A trivial database +Version: @PACKAGE_VERSION@ +Libs: @LIB_RPATH@ -L${libdir} -ltdb +Cflags: -I${includedir} +URL: http://tdb.samba.org/ diff --git a/ldb-2.0.8/lib/tdb/test/circular_chain.tdb b/ldb-2.0.8/lib/tdb/test/circular_chain.tdb new file mode 100644 index 0000000000000000000000000000000000000000..1e143d347af21eb3cf717ae6b4b67502a2d4eca8 GIT binary patch literal 272 zcmWG>aZ*Uj%t_^9zz%XH8PyokqaZ*Uj%t_^9zz%XH8Pyokq(k>3DRgDk(F|9THde{wQJ{sNl3R@~fkApI#R u5cv;i@>AC&3xM>erb6Te(ClaUtr-N;pOyxZH$aom_WUpzq(40!A`bw1o-39B literal 0 HcmV?d00001 diff --git a/ldb-2.0.8/lib/tdb/test/external-agent.c b/ldb-2.0.8/lib/tdb/test/external-agent.c new file mode 100644 index 0000000..3c59c06 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/external-agent.c @@ -0,0 +1,224 @@ +#include "external-agent.h" +#include "lock-tracking.h" +#include "logging.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "../common/tdb_private.h" +#include "tap-interface.h" +#include +#include + +static struct tdb_context *tdb; + +static enum agent_return do_operation(enum operation op, const char *name) +{ + TDB_DATA k; + enum agent_return ret; + TDB_DATA data; + + if (op != OPEN && op != OPEN_WITH_CLEAR_IF_FIRST && !tdb) { + diag("external: No tdb open!"); + return OTHER_FAILURE; + } + + k.dptr = discard_const_p(uint8_t, name); + k.dsize = strlen(name); + + locking_would_block = 0; + switch (op) { + case OPEN: + if (tdb) { + diag("Already have tdb %s open", tdb_name(tdb)); + return OTHER_FAILURE; + } + tdb = tdb_open_ex(name, 0, TDB_DEFAULT, O_RDWR, 0, + &taplogctx, NULL); + if (!tdb) { + if (!locking_would_block) + diag("Opening tdb gave %s", strerror(errno)); + ret = OTHER_FAILURE; + } else + ret = SUCCESS; + break; + case OPEN_WITH_CLEAR_IF_FIRST: + if (tdb) + return OTHER_FAILURE; + tdb = tdb_open_ex(name, 0, TDB_CLEAR_IF_FIRST, O_RDWR, 0, + &taplogctx, NULL); + ret = tdb ? SUCCESS : OTHER_FAILURE; + break; + case TRANSACTION_START: + ret = tdb_transaction_start(tdb) == 0 ? SUCCESS : OTHER_FAILURE; + break; + case FETCH: + data = tdb_fetch(tdb, k); + if (data.dptr == NULL) { + if (tdb_error(tdb) == TDB_ERR_NOEXIST) + ret = FAILED; + else + ret = OTHER_FAILURE; + } else if (data.dsize != k.dsize + || memcmp(data.dptr, k.dptr, k.dsize) != 0) { + ret = OTHER_FAILURE; + } else { + ret = SUCCESS; + } + free(data.dptr); + break; + case STORE: + ret = tdb_store(tdb, k, k, 0) == 0 ? SUCCESS : OTHER_FAILURE; + break; + case TRANSACTION_COMMIT: + ret = tdb_transaction_commit(tdb)==0 ? SUCCESS : OTHER_FAILURE; + break; + case CHECK: + ret = tdb_check(tdb, NULL, NULL) == 0 ? SUCCESS : OTHER_FAILURE; + break; + case NEEDS_RECOVERY: + ret = tdb_needs_recovery(tdb) ? SUCCESS : FAILED; + break; + case CLOSE: + ret = tdb_close(tdb) == 0 ? SUCCESS : OTHER_FAILURE; + tdb = NULL; + break; + case PING: + ret = SUCCESS; + break; + case UNMAP: + ret = tdb_munmap(tdb) == 0 ? SUCCESS : OTHER_FAILURE; + if (ret == SUCCESS) { + tdb->flags |= TDB_NOMMAP; + } + break; + default: + ret = OTHER_FAILURE; + } + + if (locking_would_block) + ret = WOULD_HAVE_BLOCKED; + + return ret; +} + +struct agent { + int cmdfd, responsefd; + pid_t pid; +}; + +/* Do this before doing any tdb stuff. Return handle, or NULL. */ +struct agent *prepare_external_agent(void) +{ + int ret; + int command[2], response[2]; + char name[1+PATH_MAX]; + struct agent *agent = malloc(sizeof(*agent)); + + if (pipe(command) != 0 || pipe(response) != 0) { + fprintf(stderr, "pipe failed: %s\n", strerror(errno)); + exit(1); + } + + agent->pid = fork(); + if (agent->pid < 0) { + fprintf(stderr, "fork failed: %s\n", strerror(errno)); + exit(1); + } + + if (agent->pid != 0) { + close(command[0]); + close(response[1]); + agent->cmdfd = command[1]; + agent->responsefd = response[0]; + return agent; + } + + close(command[1]); + close(response[0]); + + /* We want to fail, not block. */ + nonblocking_locks = true; + log_prefix = "external: "; + while ((ret = read(command[0], name, sizeof(name))) > 0) { + enum agent_return result; + + result = do_operation(name[0], name+1); + if (write(response[1], &result, sizeof(result)) + != sizeof(result)) + abort(); + } + exit(0); +} + +void shutdown_agent(struct agent *agent) +{ + pid_t p; + + close(agent->cmdfd); + close(agent->responsefd); + p = waitpid(agent->pid, NULL, WNOHANG); + if (p == 0) { + kill(agent->pid, SIGKILL); + } + waitpid(agent->pid, NULL, 0); + free(agent); +} + +/* Ask the external agent to try to do an operation. */ +enum agent_return external_agent_operation(struct agent *agent, + enum operation op, + const char *name) +{ + enum agent_return res; + unsigned int len; + char *string; + + if (!name) + name = ""; + len = 1 + strlen(name) + 1; + string = malloc(len); + + string[0] = op; + strncpy(string+1, name, len - 1); + string[len-1] = '\0'; + + if (write(agent->cmdfd, string, len) != len + || read(agent->responsefd, &res, sizeof(res)) != sizeof(res)) + res = AGENT_DIED; + + free(string); + return res; +} + +const char *agent_return_name(enum agent_return ret) +{ + return ret == SUCCESS ? "SUCCESS" + : ret == WOULD_HAVE_BLOCKED ? "WOULD_HAVE_BLOCKED" + : ret == AGENT_DIED ? "AGENT_DIED" + : ret == FAILED ? "FAILED" + : ret == OTHER_FAILURE ? "OTHER_FAILURE" + : "**INVALID**"; +} + +const char *operation_name(enum operation op) +{ + switch (op) { + case OPEN: return "OPEN"; + case OPEN_WITH_CLEAR_IF_FIRST: return "OPEN_WITH_CLEAR_IF_FIRST"; + case TRANSACTION_START: return "TRANSACTION_START"; + case FETCH: return "FETCH"; + case STORE: return "STORE"; + case TRANSACTION_COMMIT: return "TRANSACTION_COMMIT"; + case CHECK: return "CHECK"; + case NEEDS_RECOVERY: return "NEEDS_RECOVERY"; + case CLOSE: return "CLOSE"; + case PING: return "PING"; + case UNMAP: return "UNMAP"; + } + return "**INVALID**"; +} diff --git a/ldb-2.0.8/lib/tdb/test/external-agent.h b/ldb-2.0.8/lib/tdb/test/external-agent.h new file mode 100644 index 0000000..de9d0ac --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/external-agent.h @@ -0,0 +1,44 @@ +#ifndef TDB_TEST_EXTERNAL_AGENT_H +#define TDB_TEST_EXTERNAL_AGENT_H + +/* For locking tests, we need a different process to try things at + * various times. */ +enum operation { + OPEN, + OPEN_WITH_CLEAR_IF_FIRST, + TRANSACTION_START, + FETCH, + STORE, + TRANSACTION_COMMIT, + CHECK, + NEEDS_RECOVERY, + CLOSE, + PING, + UNMAP, +}; + +/* Do this before doing any tdb stuff. Return handle, or -1. */ +struct agent *prepare_external_agent(void); +void shutdown_agent(struct agent *agent); + +enum agent_return { + SUCCESS, + WOULD_HAVE_BLOCKED, + AGENT_DIED, + FAILED, /* For fetch, or NEEDS_RECOVERY */ + OTHER_FAILURE, +}; + +/* Ask the external agent to try to do an operation. + * name == tdb name for OPEN/OPEN_WITH_CLEAR_IF_FIRST, + * record name for FETCH/STORE (store stores name as data too) + */ +enum agent_return external_agent_operation(struct agent *handle, + enum operation op, + const char *name); + +/* Mapping enum -> string. */ +const char *agent_return_name(enum agent_return ret); +const char *operation_name(enum operation op); + +#endif /* TDB_TEST_EXTERNAL_AGENT_H */ diff --git a/ldb-2.0.8/lib/tdb/test/jenkins-be-hash.tdb b/ldb-2.0.8/lib/tdb/test/jenkins-be-hash.tdb new file mode 100644 index 0000000000000000000000000000000000000000..b652840414857969987a986c848ede159804166e GIT binary patch literal 696 ucmWG>aZ*Uj%t_^9zz)aZ*Uj%t_^9zz%XH8P%H6q@GUMcAd{ +#include +#include +#include +#include "tap-interface.h" +#include "lock-tracking.h" + +struct testlock { + struct testlock *next; + unsigned int off; + unsigned int len; + int type; +}; +static struct testlock *testlocks; +int locking_errors = 0; +bool suppress_lockcheck = false; +bool nonblocking_locks; +int locking_would_block = 0; +void (*unlock_callback)(int fd); + +int fcntl_with_lockcheck(int fd, int cmd, ... /* arg */ ) +{ + va_list ap; + int ret, arg3; + struct flock *fl; + bool may_block = false; + + if (cmd != F_SETLK && cmd != F_SETLKW) { + /* This may be totally bogus, but we don't know in general. */ + va_start(ap, cmd); + arg3 = va_arg(ap, int); + va_end(ap); + + return fcntl(fd, cmd, arg3); + } + + va_start(ap, cmd); + fl = va_arg(ap, struct flock *); + va_end(ap); + + if (cmd == F_SETLKW && nonblocking_locks) { + cmd = F_SETLK; + may_block = true; + } + ret = fcntl(fd, cmd, fl); + + /* Detect when we failed, but might have been OK if we waited. */ + if (may_block && ret == -1 && (errno == EAGAIN || errno == EACCES)) { + locking_would_block++; + } + + if (fl->l_type == F_UNLCK) { + struct testlock **l; + struct testlock *old = NULL; + + for (l = &testlocks; *l; l = &(*l)->next) { + if ((*l)->off == fl->l_start + && (*l)->len == fl->l_len) { + if (ret == 0) { + old = *l; + *l = (*l)->next; + free(old); + } + break; + } + if (((*l)->off == fl->l_start) + && ((*l)->len == 0) + && (ret == 0)) { + /* + * Remove a piece from the start of the + * allrecord_lock + */ + old = *l; + (*l)->off += fl->l_len; + break; + } + } + if (!old && !suppress_lockcheck) { + diag("Unknown unlock %u@%u - %i", + (int)fl->l_len, (int)fl->l_start, ret); + locking_errors++; + } + } else { + struct testlock *new, *i; + unsigned int fl_end = fl->l_start + fl->l_len; + if (fl->l_len == 0) + fl_end = (unsigned int)-1; + + /* Check for overlaps: we shouldn't do this. */ + for (i = testlocks; i; i = i->next) { + unsigned int i_end = i->off + i->len; + if (i->len == 0) + i_end = (unsigned int)-1; + + if (fl->l_start >= i->off && fl->l_start < i_end) + break; + if (fl_end >= i->off && fl_end < i_end) + break; + + /* tdb_allrecord_lock does this, handle adjacent: */ + if (fl->l_start == i_end && fl->l_type == i->type) { + if (ret == 0) { + i->len = fl->l_len + ? i->len + fl->l_len + : 0; + } + goto done; + } + } + if (i) { + /* Special case: upgrade of allrecord lock. */ + if (i->type == F_RDLCK && fl->l_type == F_WRLCK + && i->off == FREELIST_TOP + && fl->l_start == FREELIST_TOP + && i->len == 0 + && fl->l_len == 0) { + if (ret == 0) + i->type = F_WRLCK; + goto done; + } + if (!suppress_lockcheck) { + diag("%s testlock %u@%u overlaps %u@%u", + fl->l_type == F_WRLCK ? "write" : "read", + (int)fl->l_len, (int)fl->l_start, + i->len, (int)i->off); + locking_errors++; + } + } + + if (ret == 0) { + new = malloc(sizeof *new); + new->off = fl->l_start; + new->len = fl->l_len; + new->type = fl->l_type; + new->next = testlocks; + testlocks = new; + } + } +done: + if (ret == 0 && fl->l_type == F_UNLCK && unlock_callback) + unlock_callback(fd); + return ret; +} + +unsigned int forget_locking(void) +{ + unsigned int num = 0; + while (testlocks) { + struct testlock *next = testlocks->next; + free(testlocks); + testlocks = next; + num++; + } + return num; +} diff --git a/ldb-2.0.8/lib/tdb/test/lock-tracking.h b/ldb-2.0.8/lib/tdb/test/lock-tracking.h new file mode 100644 index 0000000..f2c9c44 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/lock-tracking.h @@ -0,0 +1,25 @@ +#ifndef LOCK_TRACKING_H +#define LOCK_TRACKING_H +#include + +/* Set this if you want a callback after fnctl unlock. */ +extern void (*unlock_callback)(int fd); + +/* Replacement fcntl. */ +int fcntl_with_lockcheck(int fd, int cmd, ... /* arg */ ); + +/* Discard locking info: returns number of locks outstanding. */ +unsigned int forget_locking(void); + +/* Number of errors in locking. */ +extern int locking_errors; + +/* Suppress lock checking. */ +extern bool suppress_lockcheck; + +/* Make all locks non-blocking. */ +extern bool nonblocking_locks; + +/* Number of times we failed a lock because we made it non-blocking. */ +extern int locking_would_block; +#endif /* LOCK_TRACKING_H */ diff --git a/ldb-2.0.8/lib/tdb/test/logging.c b/ldb-2.0.8/lib/tdb/test/logging.c new file mode 100644 index 0000000..dfab486 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/logging.c @@ -0,0 +1,33 @@ +#include "logging.h" +#include "tap-interface.h" +#include +#include +#include +#include + +bool suppress_logging = false; +const char *log_prefix = ""; + +/* Turn log messages into tap diag messages. */ +static void taplog(struct tdb_context *tdb, + enum tdb_debug_level level, + const char *fmt, ...) +{ + va_list ap; + char line[200]; + + if (suppress_logging) + return; + + va_start(ap, fmt); + vsprintf(line, fmt, ap); + va_end(ap); + + /* Strip trailing \n: diag adds it. */ + if (line[0] && line[strlen(line)-1] == '\n') + diag("%s%.*s", log_prefix, (unsigned)strlen(line)-1, line); + else + diag("%s%s", log_prefix, line); +} + +struct tdb_logging_context taplogctx = { taplog, NULL }; diff --git a/ldb-2.0.8/lib/tdb/test/logging.h b/ldb-2.0.8/lib/tdb/test/logging.h new file mode 100644 index 0000000..89e77b2 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/logging.h @@ -0,0 +1,11 @@ +#ifndef TDB_TEST_LOGGING_H +#define TDB_TEST_LOGGING_H +#include "replace.h" +#include "../include/tdb.h" +#include + +extern bool suppress_logging; +extern const char *log_prefix; +extern struct tdb_logging_context taplogctx; + +#endif /* TDB_TEST_LOGGING_H */ diff --git a/ldb-2.0.8/lib/tdb/test/old-nohash-be.tdb b/ldb-2.0.8/lib/tdb/test/old-nohash-be.tdb new file mode 100644 index 0000000000000000000000000000000000000000..1c49116c1d94ba64c90e6b36651fc5bb41e9b16c GIT binary patch literal 696 jcmWG>aZ*Uj%t_^9zz)aZ*Uj%t_^9zz%XH8P%GxOO1+-hQNS@0020x1JwWk literal 0 HcmV?d00001 diff --git a/ldb-2.0.8/lib/tdb/test/run-3G-file.c b/ldb-2.0.8/lib/tdb/test/run-3G-file.c new file mode 100644 index 0000000..79e291b --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-3G-file.c @@ -0,0 +1,145 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include "logging.h" + +static int tdb_expand_file_sparse(struct tdb_context *tdb, + tdb_off_t size, + tdb_off_t addition) +{ + if (tdb->read_only || tdb->traverse_read) { + tdb->ecode = TDB_ERR_RDONLY; + return -1; + } + + if (tdb_ftruncate(tdb, size+addition) == -1) { + char b = 0; + ssize_t written = tdb_pwrite(tdb, &b, 1, (size+addition) - 1); + if (written == 0) { + /* try once more, potentially revealing errno */ + written = tdb_pwrite(tdb, &b, 1, (size+addition) - 1); + } + if (written == 0) { + /* again - give up, guessing errno */ + errno = ENOSPC; + } + if (written != 1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file to %d failed (%s)\n", + size+addition, strerror(errno))); + return -1; + } + } + + return 0; +} + +static const struct tdb_methods large_io_methods = { + tdb_read, + tdb_write, + tdb_next_hash_chain, + tdb_notrans_oob, + tdb_expand_file_sparse +}; + +static int test_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, + void *_data) +{ + TDB_DATA *expect = _data; + ok1(key.dsize == strlen("hi")); + ok1(memcmp(key.dptr, "hi", strlen("hi")) == 0); + ok1(data.dsize == expect->dsize); + ok1(memcmp(data.dptr, expect->dptr, data.dsize) == 0); + return 0; +} + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + TDB_DATA key, orig_data, data; + uint32_t hashval; + tdb_off_t rec_ptr; + struct tdb_record rec; + int ret; + + plan_tests(24); + tdb = tdb_open_ex("run-36-file.tdb", 1024, TDB_CLEAR_IF_FIRST, + O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); + + ok1(tdb); + tdb->methods = &large_io_methods; + + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + orig_data.dsize = strlen("world"); + orig_data.dptr = discard_const_p(uint8_t, "world"); + + /* Enlarge the file (internally multiplies by 2). */ + ret = tdb_expand(tdb, 1500000000); +#ifdef HAVE_INCOHERENT_MMAP + /* This can fail due to mmap failure on 32 bit systems. */ + if (ret == -1) { + /* These should now fail. */ + ok1(tdb_store(tdb, key, orig_data, TDB_INSERT) == -1); + data = tdb_fetch(tdb, key); + ok1(data.dptr == NULL); + ok1(tdb_traverse(tdb, test_traverse, &orig_data) == -1); + ok1(tdb_delete(tdb, key) == -1); + ok1(tdb_traverse(tdb, test_traverse, NULL) == -1); + /* Skip the rest... */ + for (ret = 0; ret < 24 - 6; ret++) + ok1(1); + tdb_close(tdb); + return exit_status(); + } +#endif + ok1(ret == 0); + + /* Put an entry in, and check it. */ + ok1(tdb_store(tdb, key, orig_data, TDB_INSERT) == 0); + + data = tdb_fetch(tdb, key); + ok1(data.dsize == strlen("world")); + ok1(memcmp(data.dptr, "world", strlen("world")) == 0); + free(data.dptr); + + /* That currently fills at the end, make sure that's true. */ + hashval = tdb->hash_fn(&key); + rec_ptr = tdb_find_lock_hash(tdb, key, hashval, F_RDLCK, &rec); + ok1(rec_ptr); + ok1(rec_ptr > 2U*1024*1024*1024); + tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); + + /* Traverse must work. */ + ok1(tdb_traverse(tdb, test_traverse, &orig_data) == 1); + + /* Delete should work. */ + ok1(tdb_delete(tdb, key) == 0); + + ok1(tdb_traverse(tdb, test_traverse, NULL) == 0); + + /* Transactions should work. */ + ok1(tdb_transaction_start(tdb) == 0); + ok1(tdb_store(tdb, key, orig_data, TDB_INSERT) == 0); + + data = tdb_fetch(tdb, key); + ok1(data.dsize == strlen("world")); + ok1(memcmp(data.dptr, "world", strlen("world")) == 0); + free(data.dptr); + ok1(tdb_transaction_commit(tdb) == 0); + + ok1(tdb_traverse(tdb, test_traverse, &orig_data) == 1); + tdb_close(tdb); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-allrecord-traverse-deadlock.c b/ldb-2.0.8/lib/tdb/test/run-allrecord-traverse-deadlock.c new file mode 100644 index 0000000..2c58206 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-allrecord-traverse-deadlock.c @@ -0,0 +1,203 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include +#include +#include +#include "logging.h" + +static void do_allrecord_lock(const char *name, int tdb_flags, int up, + int down) +{ + struct tdb_context *tdb; + int ret; + ssize_t nread, nwritten; + char c = 0; + + tdb = tdb_open_ex(name, 3, tdb_flags, + O_RDWR|O_CREAT, 0755, &taplogctx, NULL); + ok(tdb, "tdb_open_ex should succeed"); + + ret = tdb_lockall(tdb); + ok(ret == 0, "tdb_lockall should succeed"); + + nwritten = write(up, &c, sizeof(c)); + ok(nwritten == sizeof(c), "write should succeed"); + + nread = read(down, &c, sizeof(c)); + ok(nread == sizeof(c), "read should succeed"); + + ret = tdb_traverse(tdb, NULL, NULL); + ok(ret == -1, "do_allrecord_lock: traverse should fail"); + + nwritten = write(up, &c, sizeof(c)); + ok(nwritten == sizeof(c), "write should succeed"); + + exit(0); +} + +static void do_traverse(const char *name, int tdb_flags, int up, int down) +{ + struct tdb_context *tdb; + int ret; + ssize_t nread, nwritten; + char c = 0; + + tdb = tdb_open_ex(name, 3, tdb_flags, + O_RDWR|O_CREAT, 0755, &taplogctx, NULL); + ok(tdb, "tdb_open_ex should succeed"); + + ret = tdb_traverse(tdb, NULL, NULL); + ok(ret == 1, "do_traverse: tdb_traverse should return 1 record"); + + nwritten = write(up, &c, sizeof(c)); + ok(nwritten == sizeof(c), "write should succeed"); + + nread = read(down, &c, sizeof(c)); + ok(nread == sizeof(c), "read should succeed"); + + exit(0); +} + +/* + * Process 1: get the allrecord_lock on a tdb. + * Process 2: start a traverse, this will stall waiting for the + * first chainlock: That is taken by the allrecord_lock + * Process 1: start a traverse: This will get EDEADLK in trying to + * get the TRANSACTION_LOCK. It will deadlock for mutexes, + * which don't have built-in deadlock detection. + */ + +static int do_tests(const char *name, int tdb_flags) +{ + struct tdb_context *tdb; + int ret; + pid_t traverse_child, allrecord_child; + int traverse_down[2]; + int traverse_up[2]; + int allrecord_down[2]; + int allrecord_up[2]; + char c; + ssize_t nread, nwritten; + TDB_DATA key, data; + + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + data.dsize = strlen("world"); + data.dptr = discard_const_p(uint8_t, "world"); + + tdb = tdb_open_ex(name, 3, tdb_flags, + O_RDWR|O_CREAT, 0755, &taplogctx, NULL); + ok(tdb, "tdb_open_ex should succeed"); + + ret = tdb_store(tdb, key, data, TDB_INSERT); + ok(ret == 0, "tdb_store should succeed"); + + ret = pipe(traverse_down); + ok(ret == 0, "pipe should succeed"); + + ret = pipe(traverse_up); + ok(ret == 0, "pipe should succeed"); + + ret = pipe(allrecord_down); + ok(ret == 0, "pipe should succeed"); + + ret = pipe(allrecord_up); + ok(ret == 0, "pipe should succeed"); + + allrecord_child = fork(); + ok(allrecord_child != -1, "fork should succeed"); + + if (allrecord_child == 0) { + tdb_close(tdb); + close(traverse_up[0]); + close(traverse_up[1]); + close(traverse_down[0]); + close(traverse_down[1]); + close(allrecord_up[0]); + close(allrecord_down[1]); + do_allrecord_lock(name, tdb_flags, + allrecord_up[1], allrecord_down[0]); + exit(0); + } + close(allrecord_up[1]); + close(allrecord_down[0]); + + nread = read(allrecord_up[0], &c, sizeof(c)); + ok(nread == sizeof(c), "read should succeed"); + + traverse_child = fork(); + ok(traverse_child != -1, "fork should succeed"); + + if (traverse_child == 0) { + tdb_close(tdb); + close(traverse_up[0]); + close(traverse_down[1]); + close(allrecord_up[0]); + close(allrecord_down[1]); + do_traverse(name, tdb_flags, + traverse_up[1], traverse_down[0]); + exit(0); + } + close(traverse_up[1]); + close(traverse_down[0]); + + poll(NULL, 0, 1000); + + nwritten = write(allrecord_down[1], &c, sizeof(c)); + ok(nwritten == sizeof(c), "write should succeed"); + + nread = read(traverse_up[0], &c, sizeof(c)); + ok(nread == sizeof(c), "read should succeed"); + + nwritten = write(traverse_down[1], &c, sizeof(c)); + ok(nwritten == sizeof(c), "write should succeed"); + + nread = read(allrecord_up[0], &c, sizeof(c)); + ok(nread == sizeof(c), "ret should succeed"); + + close(traverse_up[0]); + close(traverse_down[1]); + close(allrecord_up[0]); + close(allrecord_down[1]); + diag("%s tests done", name); + return exit_status(); +} + +int main(int argc, char *argv[]) +{ + int ret; + bool mutex_support; + + mutex_support = tdb_runtime_check_for_robust_mutexes(); + + ret = do_tests("marklock-deadlock-fcntl.tdb", + TDB_CLEAR_IF_FIRST | + TDB_INCOMPATIBLE_HASH); + ok(ret == 0, "marklock-deadlock-fcntl.tdb tests should succeed"); + + if (!mutex_support) { + skip(1, "No robust mutex support, " + "skipping marklock-deadlock-mutex.tdb tests"); + return exit_status(); + } + + ret = do_tests("marklock-deadlock-mutex.tdb", + TDB_CLEAR_IF_FIRST | + TDB_MUTEX_LOCKING | + TDB_INCOMPATIBLE_HASH); + ok(ret == 0, "marklock-deadlock-mutex.tdb tests should succeed"); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-bad-tdb-header.c b/ldb-2.0.8/lib/tdb/test/run-bad-tdb-header.c new file mode 100644 index 0000000..9d29fdf --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-bad-tdb-header.c @@ -0,0 +1,59 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include "logging.h" + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + struct tdb_header hdr; + int fd; + + plan_tests(11); + /* Can open fine if complete crap, as long as O_CREAT. */ + fd = open("run-bad-tdb-header.tdb", O_RDWR|O_CREAT|O_TRUNC, 0600); + ok1(fd >= 0); + ok1(write(fd, "hello world", 11) == 11); + close(fd); + tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, O_RDWR, 0, + &taplogctx, NULL); + ok1(!tdb); + tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, O_CREAT|O_RDWR, + 0600, &taplogctx, NULL); + ok1(tdb); + tdb_close(tdb); + + /* Now, with wrong version it should *not* overwrite. */ + fd = open("run-bad-tdb-header.tdb", O_RDWR); + ok1(fd >= 0); + ok1(read(fd, &hdr, sizeof(hdr)) == sizeof(hdr)); + ok1(hdr.version == TDB_VERSION); + hdr.version++; + lseek(fd, 0, SEEK_SET); + ok1(write(fd, &hdr, sizeof(hdr)) == sizeof(hdr)); + close(fd); + + tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, O_RDWR|O_CREAT, + 0600, &taplogctx, NULL); + ok1(errno == EIO); + ok1(!tdb); + + /* With truncate, will be fine. */ + tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, + O_RDWR|O_CREAT|O_TRUNC, 0600, &taplogctx, NULL); + ok1(tdb); + tdb_close(tdb); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-check.c b/ldb-2.0.8/lib/tdb/test/run-check.c new file mode 100644 index 0000000..ce389a2 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-check.c @@ -0,0 +1,65 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include "logging.h" + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + TDB_DATA key, data; + + plan_tests(13); + tdb = tdb_open_ex("run-check.tdb", 1, TDB_CLEAR_IF_FIRST, + O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); + + ok1(tdb); + ok1(tdb_check(tdb, NULL, NULL) == 0); + + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + data.dsize = strlen("world"); + data.dptr = discard_const_p(uint8_t, "world"); + + ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); + ok1(tdb_check(tdb, NULL, NULL) == 0); + tdb_close(tdb); + + tdb = tdb_open_ex("run-check.tdb", 1024, 0, O_RDWR, 0, + &taplogctx, NULL); + ok1(tdb); + ok1(tdb_check(tdb, NULL, NULL) == 0); + tdb_close(tdb); + + tdb = tdb_open_ex("test/tdb.corrupt", 1024, 0, O_RDWR, 0, + &taplogctx, NULL); + ok1(tdb); + ok1(tdb_check(tdb, NULL, NULL) == -1); + ok1(tdb_error(tdb) == TDB_ERR_CORRUPT); + tdb_close(tdb); + + /* Big and little endian should work! */ + tdb = tdb_open_ex("test/old-nohash-le.tdb", 1024, 0, O_RDWR, 0, + &taplogctx, NULL); + ok1(tdb); + ok1(tdb_check(tdb, NULL, NULL) == 0); + tdb_close(tdb); + + tdb = tdb_open_ex("test/old-nohash-be.tdb", 1024, 0, O_RDWR, 0, + &taplogctx, NULL); + ok1(tdb); + ok1(tdb_check(tdb, NULL, NULL) == 0); + tdb_close(tdb); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-circular-chain.c b/ldb-2.0.8/lib/tdb/test/run-circular-chain.c new file mode 100644 index 0000000..4fb32a2 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-circular-chain.c @@ -0,0 +1,42 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include "logging.h" + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + TDB_DATA key; + + plan_tests(3); + tdb = tdb_open_ex( + "test/circular_chain.tdb", + 0, + TDB_DEFAULT, + O_RDONLY, + 0600, + &taplogctx, + NULL); + + ok1(tdb); + key.dsize = strlen("x"); + key.dptr = discard_const_p(uint8_t, "x"); + + ok1(tdb_exists(tdb, key) == 0); + ok1(tdb_error(tdb) == TDB_ERR_CORRUPT); + + tdb_close(tdb); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-circular-freelist.c b/ldb-2.0.8/lib/tdb/test/run-circular-freelist.c new file mode 100644 index 0000000..f1bec87 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-circular-freelist.c @@ -0,0 +1,50 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include "logging.h" + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + TDB_DATA key, data; + + plan_tests(3); + tdb = tdb_open_ex( + "test/circular_freelist.tdb", + 0, + TDB_DEFAULT, + O_RDWR, + 0600, + &taplogctx, + NULL); + + ok1(tdb); + + /* + * All freelist records are just 1 byte key and value. Insert + * something that will walk the whole freelist and hit the + * circle. + */ + key.dsize = strlen("x"); + key.dptr = discard_const_p(uint8_t, "x"); + data.dsize = strlen("too long"); + data.dptr = discard_const_p(uint8_t, "too long"); + + ok1(tdb_store(tdb, key, data, TDB_INSERT) == -1); + ok1(tdb_error(tdb) == TDB_ERR_CORRUPT); + + tdb_close(tdb); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-corrupt.c b/ldb-2.0.8/lib/tdb/test/run-corrupt.c new file mode 100644 index 0000000..e6fc751 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-corrupt.c @@ -0,0 +1,132 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include "logging.h" + +static int check(TDB_DATA key, TDB_DATA data, void *private) +{ + unsigned int *sizes = private; + + if (key.dsize > strlen("hello")) + return -1; + if (memcmp(key.dptr, "hello", key.dsize) != 0) + return -1; + + if (data.dsize != strlen("world")) + return -1; + if (memcmp(data.dptr, "world", data.dsize) != 0) + return -1; + + sizes[0] += key.dsize; + sizes[1] += data.dsize; + return 0; +} + +static void tdb_flip_bit(struct tdb_context *tdb, unsigned int bit) +{ + unsigned int off = bit / CHAR_BIT; + unsigned char mask = (1 << (bit % CHAR_BIT)); + + if (tdb->map_ptr) + ((unsigned char *)tdb->map_ptr)[off] ^= mask; + else { + unsigned char c; + if (pread(tdb->fd, &c, 1, off) != 1) { + fprintf(stderr, "pread: %s\n", strerror(errno)); + exit(1); + } + c ^= mask; + if (pwrite(tdb->fd, &c, 1, off) != 1) { + fprintf(stderr, "pwrite: %s\n", strerror(errno)); + exit(1); + } + } +} + +static void check_test(struct tdb_context *tdb) +{ + TDB_DATA key, data; + unsigned int i, verifiable, corrupt, sizes[2], dsize, ksize; + + ok1(tdb_check(tdb, NULL, NULL) == 0); + + key.dptr = discard_const_p(uint8_t, "hello"); + data.dsize = strlen("world"); + data.dptr = discard_const_p(uint8_t, "world"); + + /* Key and data size respectively. */ + dsize = ksize = 0; + + /* 5 keys in hash size 2 means we'll have multichains. */ + for (key.dsize = 1; key.dsize <= 5; key.dsize++) { + ksize += key.dsize; + dsize += data.dsize; + if (tdb_store(tdb, key, data, TDB_INSERT) != 0) + abort(); + } + + /* This is how many bytes we expect to be verifiable. */ + /* From the file header. */ + verifiable = strlen(TDB_MAGIC_FOOD) + 1 + + 2 * sizeof(uint32_t) + 2 * sizeof(tdb_off_t) + + 2 * sizeof(uint32_t); + /* From the free list chain and hash chains. */ + verifiable += 3 * sizeof(tdb_off_t); + /* From the record headers & tailer */ + verifiable += 5 * (sizeof(struct tdb_record) + sizeof(uint32_t)); + /* The free block: we ignore datalen, keylen, full_hash. */ + verifiable += sizeof(struct tdb_record) - 3*sizeof(uint32_t) + + sizeof(uint32_t); + /* Our check function verifies the key and data. */ + verifiable += ksize + dsize; + + /* Flip one bit at a time, make sure it detects verifiable bytes. */ + for (i = 0, corrupt = 0; i < tdb->map_size * CHAR_BIT; i++) { + tdb_flip_bit(tdb, i); + memset(sizes, 0, sizeof(sizes)); + if (tdb_check(tdb, check, sizes) != 0) + corrupt++; + else if (sizes[0] != ksize || sizes[1] != dsize) + corrupt++; + tdb_flip_bit(tdb, i); + } + ok(corrupt == verifiable * CHAR_BIT, "corrupt %u should be %u", + corrupt, verifiable * CHAR_BIT); +} + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + + plan_tests(4); + /* This should use mmap. */ + tdb = tdb_open_ex("run-corrupt.tdb", 2, TDB_CLEAR_IF_FIRST, + O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); + + if (!tdb) + abort(); + check_test(tdb); + tdb_close(tdb); + + /* This should not. */ + tdb = tdb_open_ex("run-corrupt.tdb", 2, TDB_CLEAR_IF_FIRST|TDB_NOMMAP, + O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); + + if (!tdb) + abort(); + check_test(tdb); + tdb_close(tdb); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-die-during-transaction.c b/ldb-2.0.8/lib/tdb/test/run-die-during-transaction.c new file mode 100644 index 0000000..c636d87 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-die-during-transaction.c @@ -0,0 +1,232 @@ +#include "../common/tdb_private.h" +#include "lock-tracking.h" +static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset); +static ssize_t write_check(int fd, const void *buf, size_t count); +static int ftruncate_check(int fd, off_t length); + +#define pwrite pwrite_check +#define write write_check +#define fcntl fcntl_with_lockcheck +#define ftruncate ftruncate_check + +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include +#include +#include +#include "external-agent.h" +#include "logging.h" + +#undef write +#undef pwrite +#undef fcntl +#undef ftruncate + +static bool in_transaction; +static int target, current; +static jmp_buf jmpbuf; +#define TEST_DBNAME "run-die-during-transaction.tdb" +#define KEY_STRING "helloworld" + +static void maybe_die(int fd) +{ + if (in_transaction && current++ == target) { + longjmp(jmpbuf, 1); + } +} + +static ssize_t pwrite_check(int fd, + const void *buf, size_t count, off_t offset) +{ + ssize_t ret; + + maybe_die(fd); + + ret = pwrite(fd, buf, count, offset); + if (ret != count) + return ret; + + maybe_die(fd); + return ret; +} + +static ssize_t write_check(int fd, const void *buf, size_t count) +{ + ssize_t ret; + + maybe_die(fd); + + ret = write(fd, buf, count); + if (ret != count) + return ret; + + maybe_die(fd); + return ret; +} + +static int ftruncate_check(int fd, off_t length) +{ + int ret; + + maybe_die(fd); + + ret = ftruncate(fd, length); + + maybe_die(fd); + return ret; +} + +static bool test_death(enum operation op, struct agent *agent) +{ + struct tdb_context *tdb = NULL; + TDB_DATA key; + enum agent_return ret; + int needed_recovery = 0; + + current = target = 0; +reset: + unlink(TEST_DBNAME); + tdb = tdb_open_ex(TEST_DBNAME, 1024, TDB_NOMMAP, + O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); + + if (setjmp(jmpbuf) != 0) { + /* We're partway through. Simulate our death. */ + close(tdb->fd); + forget_locking(); + in_transaction = false; + + ret = external_agent_operation(agent, NEEDS_RECOVERY, ""); + if (ret == SUCCESS) + needed_recovery++; + else if (ret != FAILED) { + diag("Step %u agent NEEDS_RECOVERY = %s", current, + agent_return_name(ret)); + return false; + } + + ret = external_agent_operation(agent, op, KEY_STRING); + if (ret != SUCCESS) { + diag("Step %u op %s failed = %s", current, + operation_name(op), + agent_return_name(ret)); + return false; + } + + ret = external_agent_operation(agent, NEEDS_RECOVERY, ""); + if (ret != FAILED) { + diag("Still needs recovery after step %u = %s", + current, agent_return_name(ret)); + return false; + } + + ret = external_agent_operation(agent, CHECK, ""); + if (ret != SUCCESS) { + diag("Step %u check failed = %s", current, + agent_return_name(ret)); + return false; + } + + ret = external_agent_operation(agent, CLOSE, ""); + if (ret != SUCCESS) { + diag("Step %u close failed = %s", current, + agent_return_name(ret)); + return false; + } + + /* Suppress logging as this tries to use closed fd. */ + suppress_logging = true; + suppress_lockcheck = true; + tdb_close(tdb); + suppress_logging = false; + suppress_lockcheck = false; + target++; + current = 0; + goto reset; + } + + /* Put key for agent to fetch. */ + key.dsize = strlen(KEY_STRING); + key.dptr = discard_const_p(uint8_t, KEY_STRING); + if (tdb_store(tdb, key, key, TDB_INSERT) != 0) + return false; + + /* This is the key we insert in transaction. */ + key.dsize--; + + ret = external_agent_operation(agent, OPEN, TEST_DBNAME); + if (ret != SUCCESS) { + fprintf(stderr, "Agent failed to open: %s\n", + agent_return_name(ret)); + exit(1); + } + + ret = external_agent_operation(agent, FETCH, KEY_STRING); + if (ret != SUCCESS) { + fprintf(stderr, "Agent failed find key: %s\n", + agent_return_name(ret)); + exit(1); + } + + in_transaction = true; + if (tdb_transaction_start(tdb) != 0) + return false; + + if (tdb_store(tdb, key, key, TDB_INSERT) != 0) + return false; + + if (tdb_transaction_commit(tdb) != 0) + return false; + + in_transaction = false; + + /* We made it! */ + diag("Completed %u runs", current); + tdb_close(tdb); + ret = external_agent_operation(agent, CLOSE, ""); + if (ret != SUCCESS) { + diag("Step %u close failed = %s", current, + agent_return_name(ret)); + return false; + } + +#ifdef HAVE_INCOHERENT_MMAP + /* This means we always mmap, which makes this test a noop. */ + ok1(1); +#else + ok1(needed_recovery); +#endif + ok1(locking_errors == 0); + ok1(forget_locking() == 0); + locking_errors = 0; + return true; +} + +int main(int argc, char *argv[]) +{ + enum operation ops[] = { FETCH, STORE, TRANSACTION_START }; + struct agent *agent; + int i; + + plan_tests(12); + unlock_callback = maybe_die; + + agent = prepare_external_agent(); + + for (i = 0; i < sizeof(ops)/sizeof(ops[0]); i++) { + diag("Testing %s after death", operation_name(ops[i])); + ok1(test_death(ops[i], agent)); + } + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-endian.c b/ldb-2.0.8/lib/tdb/test/run-endian.c new file mode 100644 index 0000000..9d4d5f5 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-endian.c @@ -0,0 +1,64 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include "logging.h" + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + TDB_DATA key, data; + + plan_tests(13); + tdb = tdb_open_ex("run-endian.tdb", 1024, + TDB_CLEAR_IF_FIRST|TDB_CONVERT, + O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); + + ok1(tdb); + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + data.dsize = strlen("world"); + data.dptr = discard_const_p(uint8_t, "world"); + + ok1(tdb_store(tdb, key, data, TDB_MODIFY) < 0); + ok1(tdb_error(tdb) == TDB_ERR_NOEXIST); + ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); + ok1(tdb_store(tdb, key, data, TDB_INSERT) < 0); + ok1(tdb_error(tdb) == TDB_ERR_EXISTS); + ok1(tdb_store(tdb, key, data, TDB_MODIFY) == 0); + + data = tdb_fetch(tdb, key); + ok1(data.dsize == strlen("world")); + ok1(memcmp(data.dptr, "world", strlen("world")) == 0); + free(data.dptr); + + key.dsize++; + data = tdb_fetch(tdb, key); + ok1(data.dptr == NULL); + tdb_close(tdb); + + /* Reopen: should read it */ + tdb = tdb_open_ex("run-endian.tdb", 1024, 0, O_RDWR, 0, + &taplogctx, NULL); + ok1(tdb); + + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + data = tdb_fetch(tdb, key); + ok1(data.dsize == strlen("world")); + ok1(memcmp(data.dptr, "world", strlen("world")) == 0); + free(data.dptr); + tdb_close(tdb); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-fcntl-deadlock.c b/ldb-2.0.8/lib/tdb/test/run-fcntl-deadlock.c new file mode 100644 index 0000000..0a328af --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-fcntl-deadlock.c @@ -0,0 +1,202 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include +#include "tap-interface.h" + +/* + * This tests the low level locking requirement + * for the allrecord lock/prepare_commit and traverse_read interaction. + * + * The pattern with the traverse_read and prepare_commit interaction is + * the following: + * + * 1. transaction_start got the allrecord lock with F_RDLCK. + * + * 2. the traverse_read code walks the database in a sequence like this + * (per chain): + * 2.1 chainlock(chainX, F_RDLCK) + * 2.2 recordlock(chainX.record1, F_RDLCK) + * 2.3 chainunlock(chainX, F_RDLCK) + * 2.4 callback(chainX.record1) + * 2.5 chainlock(chainX, F_RDLCK) + * 2.6 recordunlock(chainX.record1, F_RDLCK) + * 2.7 recordlock(chainX.record2, F_RDLCK) + * 2.8 chainunlock(chainX, F_RDLCK) + * 2.9 callback(chainX.record2) + * 2.10 chainlock(chainX, F_RDLCK) + * 2.11 recordunlock(chainX.record2, F_RDLCK) + * 2.12 chainunlock(chainX, F_RDLCK) + * 2.13 goto next chain + * + * So it has always one record locked in F_RDLCK mode and tries to + * get the 2nd one before it releases the first one. + * + * 3. prepare_commit tries to upgrade the allrecord lock to F_RWLCK + * If that happens at the time of 2.4, the operation of + * 2.5 may deadlock with the allrecord lock upgrade. + * On Linux step 2.5 works in order to make some progress with the + * locking, but on solaris it might fail because the kernel + * wants to satisfy the 1st lock requester before the 2nd one. + * + * I think the first step is a standalone test that does this: + * + * process1: F_RDLCK for ofs=0 len=2 + * process2: F_RDLCK for ofs=0 len=1 + * process1: upgrade ofs=0 len=2 to F_RWLCK (in blocking mode) + * process2: F_RDLCK for ofs=1 len=1 + * process2: unlock ofs=0 len=2 + * process1: should continue at that point + * + * Such a test follows here... + */ + +static int raw_fcntl_lock(int fd, int rw, off_t off, off_t len, bool waitflag) +{ + struct flock fl; + int cmd; + fl.l_type = rw; + fl.l_whence = SEEK_SET; + fl.l_start = off; + fl.l_len = len; + fl.l_pid = 0; + + cmd = waitflag ? F_SETLKW : F_SETLK; + + return fcntl(fd, cmd, &fl); +} + +static int raw_fcntl_unlock(int fd, off_t off, off_t len) +{ + struct flock fl; + fl.l_type = F_UNLCK; + fl.l_whence = SEEK_SET; + fl.l_start = off; + fl.l_len = len; + fl.l_pid = 0; + + return fcntl(fd, F_SETLKW, &fl); +} + + +int pipe_r; +int pipe_w; +char buf[2]; + +static void expect_char(char c) +{ + read(pipe_r, buf, 1); + if (*buf != c) { + fail("We were expecting %c, but got %c", c, buf[0]); + } +} + +static void send_char(char c) +{ + write(pipe_w, &c, 1); +} + + +int main(int argc, char *argv[]) +{ + int process; + int fd; + const char *filename = "run-fcntl-deadlock.lck"; + int pid; + int pipes_1_2[2]; + int pipes_2_1[2]; + int ret; + + pipe(pipes_1_2); + pipe(pipes_2_1); + fd = open(filename, O_RDWR | O_CREAT, 0755); + + pid = fork(); + if (pid == 0) { + pipe_r = pipes_1_2[0]; + pipe_w = pipes_2_1[1]; + process = 2; + alarm(15); + } else { + pipe_r = pipes_2_1[0]; + pipe_w = pipes_1_2[1]; + process = 1; + alarm(15); + } + + /* a: process1: F_RDLCK for ofs=0 len=2 */ + if (process == 1) { + ret = raw_fcntl_lock(fd, F_RDLCK, 0, 2, true); + ok(ret == 0, + "process 1 lock ofs=0 len=2: %d - %s", + ret, strerror(errno)); + diag("process 1 took read lock on range 0,2"); + send_char('a'); + } + + /* process2: F_RDLCK for ofs=0 len=1 */ + if (process == 2) { + expect_char('a'); + ret = raw_fcntl_lock(fd, F_RDLCK, 0, 1, true); + ok(ret == 0, + "process 2 lock ofs=0 len=1: %d - %s", + ret, strerror(errno));; + diag("process 2 took read lock on range 0,1"); + send_char('b'); + } + + /* process1: upgrade ofs=0 len=2 to F_RWLCK (in blocking mode) */ + if (process == 1) { + expect_char('b'); + send_char('c'); + diag("process 1 starts upgrade on range 0,2"); + ret = raw_fcntl_lock(fd, F_WRLCK, 0, 2, true); + ok(ret == 0, + "process 1 RW lock ofs=0 len=2: %d - %s", + ret, strerror(errno)); + diag("process 1 got read upgrade done"); + /* at this point process 1 is blocked on 2 releasing the + read lock */ + } + + /* + * process2: F_RDLCK for ofs=1 len=1 + * process2: unlock ofs=0 len=2 + */ + if (process == 2) { + expect_char('c'); /* we know process 1 is *about* to lock */ + sleep(1); + ret = raw_fcntl_lock(fd, F_RDLCK, 1, 1, true); + ok(ret == 0, + "process 2 lock ofs=1 len=1: %d - %s", + ret, strerror(errno)); + diag("process 2 got read lock on 1,1\n"); + ret = raw_fcntl_unlock(fd, 0, 2); + ok(ret == 0, + "process 2 unlock ofs=0 len=2: %d - %s", + ret, strerror(errno)); + diag("process 2 released read lock on 0,2\n"); + sleep(1); + send_char('d'); + } + + if (process == 1) { + expect_char('d'); + } + + diag("process %d has got to the end\n", process); + + return 0; +} diff --git a/ldb-2.0.8/lib/tdb/test/run-incompatible.c b/ldb-2.0.8/lib/tdb/test/run-incompatible.c new file mode 100644 index 0000000..5f1b586 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-incompatible.c @@ -0,0 +1,188 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include + +static unsigned int tdb_dumb_hash(TDB_DATA *key) +{ + return key->dsize; +} + +static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) +{ + unsigned int *count = tdb_get_logging_private(tdb); + if (strstr(fmt, "hash")) + (*count)++; +} + +static unsigned int hdr_rwlocks(const char *fname) +{ + struct tdb_header hdr; + ssize_t nread; + + int fd = open(fname, O_RDONLY); + if (fd == -1) + return -1; + + nread = read(fd, &hdr, sizeof(hdr)); + close(fd); + if (nread != sizeof(hdr)) { + return -1; + } + return hdr.rwlocks; +} + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + unsigned int log_count, flags; + TDB_DATA d, r; + struct tdb_logging_context log_ctx = { log_fn, &log_count }; + + plan_tests(38 * 2); + + for (flags = 0; flags <= TDB_CONVERT; flags += TDB_CONVERT) { + unsigned int rwmagic = TDB_HASH_RWLOCK_MAGIC; + + if (flags & TDB_CONVERT) + tdb_convert(&rwmagic, sizeof(rwmagic)); + + /* Create an old-style hash. */ + log_count = 0; + tdb = tdb_open_ex("run-incompatible.tdb", 0, flags, + O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx, + NULL); + ok1(tdb); + ok1(log_count == 0); + d.dptr = discard_const_p(uint8_t, "Hello"); + d.dsize = 5; + ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0); + tdb_close(tdb); + + /* Should not have marked rwlocks field. */ + ok1(hdr_rwlocks("run-incompatible.tdb") == 0); + + /* We can still open any old-style with incompat flag. */ + log_count = 0; + tdb = tdb_open_ex("run-incompatible.tdb", 0, + TDB_INCOMPATIBLE_HASH, + O_RDWR, 0600, &log_ctx, NULL); + ok1(tdb); + ok1(log_count == 0); + r = tdb_fetch(tdb, d); + ok1(r.dsize == 5); + free(r.dptr); + ok1(tdb_check(tdb, NULL, NULL) == 0); + tdb_close(tdb); + + log_count = 0; + tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDONLY, + 0, &log_ctx, tdb_jenkins_hash); + ok1(tdb); + ok1(log_count == 0); + ok1(tdb_check(tdb, NULL, NULL) == 0); + tdb_close(tdb); + + log_count = 0; + tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDONLY, + 0, &log_ctx, tdb_jenkins_hash); + ok1(tdb); + ok1(log_count == 0); + ok1(tdb_check(tdb, NULL, NULL) == 0); + tdb_close(tdb); + + /* OK, now create with incompatible flag, default hash. */ + log_count = 0; + tdb = tdb_open_ex("run-incompatible.tdb", 0, + flags|TDB_INCOMPATIBLE_HASH, + O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx, + NULL); + ok1(tdb); + ok1(log_count == 0); + d.dptr = discard_const_p(uint8_t, "Hello"); + d.dsize = 5; + ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0); + tdb_close(tdb); + + /* Should have marked rwlocks field. */ + ok1(hdr_rwlocks("run-incompatible.tdb") == rwmagic); + + /* Cannot open with old hash. */ + log_count = 0; + tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, + O_RDWR, 0600, &log_ctx, tdb_old_hash); + ok1(!tdb); + ok1(log_count == 1); + + /* Can open with jenkins hash. */ + log_count = 0; + tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, + O_RDWR, 0600, &log_ctx, tdb_jenkins_hash); + ok1(tdb); + ok1(log_count == 0); + r = tdb_fetch(tdb, d); + ok1(r.dsize == 5); + free(r.dptr); + ok1(tdb_check(tdb, NULL, NULL) == 0); + tdb_close(tdb); + + /* Can open by letting it figure it out itself. */ + log_count = 0; + tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, + O_RDWR, 0600, &log_ctx, NULL); + ok1(tdb); + ok1(log_count == 0); + r = tdb_fetch(tdb, d); + ok1(r.dsize == 5); + free(r.dptr); + ok1(tdb_check(tdb, NULL, NULL) == 0); + tdb_close(tdb); + + /* We can also use incompatible hash with other hashes. */ + log_count = 0; + tdb = tdb_open_ex("run-incompatible.tdb", 0, + flags|TDB_INCOMPATIBLE_HASH, + O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx, + tdb_dumb_hash); + ok1(tdb); + ok1(log_count == 0); + d.dptr = discard_const_p(uint8_t, "Hello"); + d.dsize = 5; + ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0); + tdb_close(tdb); + + /* Should have marked rwlocks field. */ + ok1(hdr_rwlocks("run-incompatible.tdb") == rwmagic); + + /* It should not open if we don't specify. */ + log_count = 0; + tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0, + &log_ctx, NULL); + ok1(!tdb); + ok1(log_count == 1); + + /* Should reopen with correct hash. */ + log_count = 0; + tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0, + &log_ctx, tdb_dumb_hash); + ok1(tdb); + ok1(log_count == 0); + r = tdb_fetch(tdb, d); + ok1(r.dsize == 5); + free(r.dptr); + ok1(tdb_check(tdb, NULL, NULL) == 0); + tdb_close(tdb); + } + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-marklock-deadlock.c b/ldb-2.0.8/lib/tdb/test/run-marklock-deadlock.c new file mode 100644 index 0000000..37e959f --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-marklock-deadlock.c @@ -0,0 +1,278 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include +#include +#include +#include "logging.h" + +static TDB_DATA key, data; + +static void do_chainlock(const char *name, int tdb_flags, int up, int down) +{ + struct tdb_context *tdb; + int ret; + ssize_t nread, nwritten; + char c = 0; + + tdb = tdb_open_ex(name, 3, tdb_flags, + O_RDWR|O_CREAT, 0755, &taplogctx, NULL); + ok(tdb, "tdb_open_ex should succeed"); + + ret = tdb_chainlock(tdb, key); + ok(ret == 0, "tdb_chainlock should succeed"); + + nwritten = write(up, &c, sizeof(c)); + ok(nwritten == sizeof(c), "write should succeed"); + + nread = read(down, &c, sizeof(c)); + ok(nread == sizeof(c), "read should succeed"); + + exit(0); +} + +static void do_allrecord_lock(const char *name, int tdb_flags, int up, int down) +{ + struct tdb_context *tdb; + int ret; + ssize_t nread, nwritten; + char c = 0; + + tdb = tdb_open_ex(name, 3, tdb_flags, + O_RDWR|O_CREAT, 0755, &taplogctx, NULL); + ok(tdb, "tdb_open_ex should succeed"); + + ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); + ok(ret == 0, "tdb_allrecord_lock should succeed"); + + nwritten = write(up, &c, sizeof(c)); + ok(nwritten == sizeof(c), "write should succeed"); + + nread = read(down, &c, sizeof(c)); + ok(nread == sizeof(c), "read should succeed"); + + exit(0); +} + +/* The code should barf on TDBs created with rwlocks. */ +static int do_tests(const char *name, int tdb_flags) +{ + struct tdb_context *tdb; + int ret; + pid_t chainlock_child, allrecord_child; + int chainlock_down[2]; + int chainlock_up[2]; + int allrecord_down[2]; + int allrecord_up[2]; + char c; + ssize_t nread, nwritten; + + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + data.dsize = strlen("world"); + data.dptr = discard_const_p(uint8_t, "world"); + + ret = pipe(chainlock_down); + ok(ret == 0, "pipe should succeed"); + + ret = pipe(chainlock_up); + ok(ret == 0, "pipe should succeed"); + + ret = pipe(allrecord_down); + ok(ret == 0, "pipe should succeed"); + + ret = pipe(allrecord_up); + ok(ret == 0, "pipe should succeed"); + + chainlock_child = fork(); + ok(chainlock_child != -1, "fork should succeed"); + + if (chainlock_child == 0) { + close(chainlock_up[0]); + close(chainlock_down[1]); + close(allrecord_up[0]); + close(allrecord_up[1]); + close(allrecord_down[0]); + close(allrecord_down[1]); + do_chainlock(name, tdb_flags, + chainlock_up[1], chainlock_down[0]); + exit(0); + } + close(chainlock_up[1]); + close(chainlock_down[0]); + + nread = read(chainlock_up[0], &c, sizeof(c)); + ok(nread == sizeof(c), "read should succeed"); + + /* + * Now we have a process holding a chainlock. Start another process + * trying the allrecord lock. This will block. + */ + + allrecord_child = fork(); + ok(allrecord_child != -1, "fork should succeed"); + + if (allrecord_child == 0) { + close(chainlock_up[0]); + close(chainlock_up[1]); + close(chainlock_down[0]); + close(chainlock_down[1]); + close(allrecord_up[0]); + close(allrecord_down[1]); + do_allrecord_lock(name, tdb_flags, + allrecord_up[1], allrecord_down[0]); + exit(0); + } + close(allrecord_up[1]); + close(allrecord_down[0]); + + poll(NULL, 0, 500); + + tdb = tdb_open_ex(name, 3, tdb_flags, + O_RDWR|O_CREAT, 0755, &taplogctx, NULL); + ok(tdb, "tdb_open_ex should succeed"); + + /* + * Someone already holds a chainlock, but we're able to get the + * freelist lock. + * + * The freelist lock/mutex is independent from the allrecord lock/mutex. + */ + + ret = tdb_chainlock_nonblock(tdb, key); + ok(ret == -1, "tdb_chainlock_nonblock should not succeed"); + + ret = tdb_lock_nonblock(tdb, -1, F_WRLCK); + ok(ret == 0, "tdb_lock_nonblock should succeed"); + + ret = tdb_unlock(tdb, -1, F_WRLCK); + ok(ret == 0, "tdb_unlock should succeed"); + + /* + * We have someone else having done the lock for us. Just mark it. + */ + + ret = tdb_chainlock_mark(tdb, key); + ok(ret == 0, "tdb_chainlock_mark should succeed"); + + /* + * The tdb_store below will block the freelist. In one version of the + * mutex patches, the freelist was already blocked here by the + * allrecord child, which was waiting for the chainlock child to give + * up its chainlock. Make sure that we don't run into this + * deadlock. To exercise the deadlock, just comment out the "ok" + * line. + * + * The freelist lock/mutex is independent from the allrecord lock/mutex. + */ + + ret = tdb_lock_nonblock(tdb, -1, F_WRLCK); + ok(ret == 0, "tdb_lock_nonblock should succeed"); + + ret = tdb_unlock(tdb, -1, F_WRLCK); + ok(ret == 0, "tdb_unlock should succeed"); + + ret = tdb_store(tdb, key, data, TDB_INSERT); + ok(ret == 0, "tdb_store should succeed"); + + ret = tdb_chainlock_unmark(tdb, key); + ok(ret == 0, "tdb_chainlock_unmark should succeed"); + + nwritten = write(chainlock_down[1], &c, sizeof(c)); + ok(nwritten == sizeof(c), "write should succeed"); + + nread = read(chainlock_up[0], &c, sizeof(c)); + ok(nread == 0, "read should succeed"); + + nread = read(allrecord_up[0], &c, sizeof(c)); + ok(nread == sizeof(c), "read should succeed"); + + /* + * Someone already holds the allrecord lock, but we're able to get the + * freelist lock. + * + * The freelist lock/mutex is independent from the allrecord lock/mutex. + */ + + ret = tdb_chainlock_nonblock(tdb, key); + ok(ret == -1, "tdb_chainlock_nonblock should not succeed"); + + ret = tdb_lockall_nonblock(tdb); + ok(ret == -1, "tdb_lockall_nonblock should not succeed"); + + ret = tdb_lock_nonblock(tdb, -1, F_WRLCK); + ok(ret == 0, "tdb_lock_nonblock should succeed"); + + ret = tdb_unlock(tdb, -1, F_WRLCK); + ok(ret == 0, "tdb_unlock should succeed"); + + /* + * We have someone else having done the lock for us. Just mark it. + */ + + ret = tdb_lockall_mark(tdb); + ok(ret == 0, "tdb_lockall_mark should succeed"); + + ret = tdb_lock_nonblock(tdb, -1, F_WRLCK); + ok(ret == 0, "tdb_lock_nonblock should succeed"); + + ret = tdb_unlock(tdb, -1, F_WRLCK); + ok(ret == 0, "tdb_unlock should succeed"); + + ret = tdb_store(tdb, key, data, TDB_REPLACE); + ok(ret == 0, "tdb_store should succeed"); + + ret = tdb_lockall_unmark(tdb); + ok(ret == 0, "tdb_lockall_unmark should succeed"); + + nwritten = write(allrecord_down[1], &c, sizeof(c)); + ok(nwritten == sizeof(c), "write should succeed"); + + nread = read(allrecord_up[0], &c, sizeof(c)); + ok(nread == 0, "read should succeed"); + + close(chainlock_up[0]); + close(chainlock_down[1]); + close(allrecord_up[0]); + close(allrecord_down[1]); + diag("%s tests done", name); + return exit_status(); +} + +int main(int argc, char *argv[]) +{ + int ret; + bool mutex_support; + + mutex_support = tdb_runtime_check_for_robust_mutexes(); + + ret = do_tests("marklock-deadlock-fcntl.tdb", + TDB_CLEAR_IF_FIRST | + TDB_INCOMPATIBLE_HASH); + ok(ret == 0, "marklock-deadlock-fcntl.tdb tests should succeed"); + + if (!mutex_support) { + skip(1, "No robust mutex support, " + "skipping marklock-deadlock-mutex.tdb tests"); + return exit_status(); + } + + ret = do_tests("marklock-deadlock-mutex.tdb", + TDB_CLEAR_IF_FIRST | + TDB_MUTEX_LOCKING | + TDB_INCOMPATIBLE_HASH); + ok(ret == 0, "marklock-deadlock-mutex.tdb tests should succeed"); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-bench.c b/ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-bench.c new file mode 100644 index 0000000..b81e597 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-bench.c @@ -0,0 +1,82 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include +#include +#include + +static TDB_DATA key, data; + +static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, + const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + +static double timeval_elapsed2(const struct timeval *tv1, const struct timeval *tv2) +{ + return (tv2->tv_sec - tv1->tv_sec) + + (tv2->tv_usec - tv1->tv_usec)*1.0e-6; +} + +static double timeval_elapsed(const struct timeval *tv) +{ + struct timeval tv2; + gettimeofday(&tv2, NULL); + return timeval_elapsed2(tv, &tv2); +} + +/* The code should barf on TDBs created with rwlocks. */ +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + unsigned int log_count; + struct tdb_logging_context log_ctx = { log_fn, &log_count }; + int ret; + struct timeval start; + double elapsed; + bool runtime_support; + + runtime_support = tdb_runtime_check_for_robust_mutexes(); + + if (!runtime_support) { + skip(1, "No robust mutex support"); + return exit_status(); + } + + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + data.dsize = strlen("world"); + data.dptr = discard_const_p(uint8_t, "world"); + + tdb = tdb_open_ex("mutex-allrecord-bench.tdb", 1000000, + TDB_INCOMPATIBLE_HASH| + TDB_MUTEX_LOCKING| + TDB_CLEAR_IF_FIRST, + O_RDWR|O_CREAT, 0755, &log_ctx, NULL); + ok(tdb, "tdb_open_ex should succeed"); + + gettimeofday(&start, NULL); + ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); + elapsed = timeval_elapsed(&start); + + ok(ret == 0, "tdb_allrecord_lock should succeed"); + + diag("allrecord_lock took %f seconds", elapsed); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-block.c b/ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-block.c new file mode 100644 index 0000000..fcd3b4f --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-block.c @@ -0,0 +1,120 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include +#include +#include + +static TDB_DATA key, data; + +static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, + const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + +static int do_child(int tdb_flags, int to, int from) +{ + struct tdb_context *tdb; + unsigned int log_count; + struct tdb_logging_context log_ctx = { log_fn, &log_count }; + int ret; + char c = 0; + + tdb = tdb_open_ex("mutex-allrecord-block.tdb", 3, tdb_flags, + O_RDWR|O_CREAT, 0755, &log_ctx, NULL); + ok(tdb, "tdb_open_ex should succeed"); + + ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); + ok(ret == 0, "tdb_allrecord_lock should succeed"); + + write(to, &c, sizeof(c)); + + read(from, &c, sizeof(c)); + + ret = tdb_allrecord_unlock(tdb, F_WRLCK, false); + ok(ret == 0, "tdb_allrecord_unlock should succeed"); + + return 0; +} + +/* The code should barf on TDBs created with rwlocks. */ +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + unsigned int log_count; + struct tdb_logging_context log_ctx = { log_fn, &log_count }; + int ret, status; + pid_t child, wait_ret; + int fromchild[2]; + int tochild[2]; + char c; + int tdb_flags; + bool runtime_support; + + runtime_support = tdb_runtime_check_for_robust_mutexes(); + + if (!runtime_support) { + skip(1, "No robust mutex support"); + return exit_status(); + } + + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + data.dsize = strlen("world"); + data.dptr = discard_const_p(uint8_t, "world"); + + pipe(fromchild); + pipe(tochild); + + tdb_flags = TDB_INCOMPATIBLE_HASH| + TDB_MUTEX_LOCKING| + TDB_CLEAR_IF_FIRST; + + child = fork(); + if (child == 0) { + close(fromchild[0]); + close(tochild[1]); + return do_child(tdb_flags, fromchild[1], tochild[0]); + } + close(fromchild[1]); + close(tochild[0]); + + read(fromchild[0], &c, sizeof(c)); + + tdb = tdb_open_ex("mutex-allrecord-block.tdb", 0, + tdb_flags, O_RDWR|O_CREAT, 0755, + &log_ctx, NULL); + ok(tdb, "tdb_open_ex should succeed"); + + ret = tdb_chainlock_nonblock(tdb, key); + ok(ret == -1, "tdb_chainlock_nonblock should not succeed"); + + write(tochild[1], &c, sizeof(c)); + + ret = tdb_chainlock(tdb, key); + ok(ret == 0, "tdb_chainlock should not succeed"); + + ret = tdb_chainunlock(tdb, key); + ok(ret == 0, "tdb_chainunlock should succeed"); + + wait_ret = wait(&status); + ok(wait_ret == child, "child should have exited correctly"); + + diag("done"); + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-trylock.c b/ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-trylock.c new file mode 100644 index 0000000..4b683db --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-trylock.c @@ -0,0 +1,113 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include +#include +#include + +static TDB_DATA key, data; + +static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, + const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + +static int do_child(int tdb_flags, int to, int from) +{ + struct tdb_context *tdb; + unsigned int log_count; + struct tdb_logging_context log_ctx = { log_fn, &log_count }; + int ret; + char c = 0; + + tdb = tdb_open_ex("mutex-allrecord-trylock.tdb", 3, tdb_flags, + O_RDWR|O_CREAT, 0755, &log_ctx, NULL); + ok(tdb, "tdb_open_ex should succeed"); + + ret = tdb_chainlock(tdb, key); + ok(ret == 0, "tdb_chainlock should succeed"); + + write(to, &c, sizeof(c)); + + read(from, &c, sizeof(c)); + + ret = tdb_chainunlock(tdb, key); + ok(ret == 0, "tdb_chainunlock should succeed"); + + return 0; +} + +/* The code should barf on TDBs created with rwlocks. */ +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + unsigned int log_count; + struct tdb_logging_context log_ctx = { log_fn, &log_count }; + int ret, status; + pid_t child, wait_ret; + int fromchild[2]; + int tochild[2]; + char c; + int tdb_flags; + bool runtime_support; + + runtime_support = tdb_runtime_check_for_robust_mutexes(); + + if (!runtime_support) { + skip(1, "No robust mutex support"); + return exit_status(); + } + + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + data.dsize = strlen("world"); + data.dptr = discard_const_p(uint8_t, "world"); + + pipe(fromchild); + pipe(tochild); + + tdb_flags = TDB_INCOMPATIBLE_HASH| + TDB_MUTEX_LOCKING| + TDB_CLEAR_IF_FIRST; + + child = fork(); + if (child == 0) { + close(fromchild[0]); + close(tochild[1]); + return do_child(tdb_flags, fromchild[1], tochild[0]); + } + close(fromchild[1]); + close(tochild[0]); + + read(fromchild[0], &c, sizeof(c)); + + tdb = tdb_open_ex("mutex-allrecord-trylock.tdb", 0, tdb_flags, + O_RDWR|O_CREAT, 0755, &log_ctx, NULL); + ok(tdb, "tdb_open_ex should succeed"); + + ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_NOWAIT, false); + ok(ret == -1, "tdb_allrecord_lock (nowait) should not succeed"); + + write(tochild[1], &c, sizeof(c)); + + wait_ret = wait(&status); + ok(wait_ret == child, "child should have exited correctly"); + + diag("done"); + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-mutex-die.c b/ldb-2.0.8/lib/tdb/test/run-mutex-die.c new file mode 100644 index 0000000..4b8eac1 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-mutex-die.c @@ -0,0 +1,269 @@ +#include "../common/tdb_private.h" +#include "lock-tracking.h" +static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset); +static ssize_t write_check(int fd, const void *buf, size_t count); +static int ftruncate_check(int fd, off_t length); + +#define pwrite pwrite_check +#define write write_check +#define fcntl fcntl_with_lockcheck +#define ftruncate ftruncate_check + +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include +#include +#include "external-agent.h" +#include "logging.h" + +#undef write +#undef pwrite +#undef fcntl +#undef ftruncate + +static int target, current; +#define TEST_DBNAME "run-mutex-die.tdb" +#define KEY_STRING "helloworld" + +static void maybe_die(int fd) +{ + if (target == 0) { + return; + } + current += 1; + if (current == target) { + _exit(1); + } +} + +static ssize_t pwrite_check(int fd, + const void *buf, size_t count, off_t offset) +{ + ssize_t ret; + + maybe_die(fd); + + ret = pwrite(fd, buf, count, offset); + if (ret != count) + return ret; + + maybe_die(fd); + return ret; +} + +static ssize_t write_check(int fd, const void *buf, size_t count) +{ + ssize_t ret; + + maybe_die(fd); + + ret = write(fd, buf, count); + if (ret != count) + return ret; + + maybe_die(fd); + return ret; +} + +static int ftruncate_check(int fd, off_t length) +{ + int ret; + + maybe_die(fd); + + ret = ftruncate(fd, length); + + maybe_die(fd); + return ret; +} + +static enum agent_return flakey_ops(struct agent *a) +{ + enum agent_return ret; + + /* + * Run in the external agent child + */ + + ret = external_agent_operation(a, OPEN_WITH_CLEAR_IF_FIRST, TEST_DBNAME); + if (ret != SUCCESS) { + fprintf(stderr, "Agent failed to open: %s\n", + agent_return_name(ret)); + return ret; + } + ret = external_agent_operation(a, UNMAP, ""); + if (ret != SUCCESS) { + fprintf(stderr, "Agent failed to unmap: %s\n", + agent_return_name(ret)); + return ret; + } + ret = external_agent_operation(a, STORE, "xyz"); + if (ret != SUCCESS) { + fprintf(stderr, "Agent failed to store: %s\n", + agent_return_name(ret)); + return ret; + } + ret = external_agent_operation(a, STORE, KEY_STRING); + if (ret != SUCCESS) { + fprintf(stderr, "Agent failed store: %s\n", + agent_return_name(ret)); + return ret; + } + ret = external_agent_operation(a, FETCH, KEY_STRING); + if (ret != SUCCESS) { + fprintf(stderr, "Agent failed find key: %s\n", + agent_return_name(ret)); + return ret; + } + ret = external_agent_operation(a, PING, ""); + if (ret != SUCCESS) { + fprintf(stderr, "Agent failed ping: %s\n", + agent_return_name(ret)); + return ret; + } + return ret; +} + +static bool prep_db(void) { + struct tdb_context *tdb; + TDB_DATA key; + TDB_DATA data; + + key.dptr = discard_const_p(uint8_t, KEY_STRING); + key.dsize = strlen((char *)key.dptr); + data.dptr = discard_const_p(uint8_t, "foo"); + data.dsize = strlen((char *)data.dptr); + + unlink(TEST_DBNAME); + + tdb = tdb_open_ex( + TEST_DBNAME, 2, + TDB_INCOMPATIBLE_HASH|TDB_MUTEX_LOCKING|TDB_CLEAR_IF_FIRST, + O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); + if (tdb == NULL) { + return false; + } + + if (tdb_store(tdb, key, data, TDB_INSERT) != 0) { + return false; + } + + tdb_close(tdb); + tdb = NULL; + + forget_locking(); + + return true; +} + +static bool test_db(void) { + struct tdb_context *tdb; + int ret; + + tdb = tdb_open_ex( + TEST_DBNAME, 1024, TDB_INCOMPATIBLE_HASH, + O_RDWR, 0600, &taplogctx, NULL); + + if (tdb == NULL) { + perror("tdb_open_ex failed"); + return false; + } + + ret = tdb_traverse(tdb, NULL, NULL); + if (ret == -1) { + perror("traverse failed"); + goto fail; + } + + tdb_close(tdb); + + forget_locking(); + + return true; + +fail: + tdb_close(tdb); + return false; +} + +static bool test_one(void) +{ + enum agent_return ret; + + ret = AGENT_DIED; + target = 19; + + while (ret != SUCCESS) { + struct agent *agent; + + { + int child_target = target; + bool pret; + target = 0; + pret = prep_db(); + ok1(pret); + target = child_target; + } + + agent = prepare_external_agent(); + + ret = flakey_ops(agent); + + diag("Agent (target=%d) returns %s", + target, agent_return_name(ret)); + + if (ret == SUCCESS) { + ok((target > 19), "At least one AGENT_DIED expected"); + } else { + ok(ret == AGENT_DIED, "AGENT_DIED expected"); + } + + shutdown_agent(agent); + + { + int child_target = target; + bool tret; + target = 0; + tret = test_db(); + ok1(tret); + target = child_target; + } + + target += 1; + } + + return true; +} + +int main(int argc, char *argv[]) +{ + bool ret; + bool runtime_support; + + runtime_support = tdb_runtime_check_for_robust_mutexes(); + + if (!runtime_support) { + skip(1, "No robust mutex support"); + return exit_status(); + } + + plan_tests(12); + unlock_callback = maybe_die; + + ret = test_one(); + ok1(ret); + + diag("done"); + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-mutex-openflags2.c b/ldb-2.0.8/lib/tdb/test/run-mutex-openflags2.c new file mode 100644 index 0000000..89603e6 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-mutex-openflags2.c @@ -0,0 +1,146 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include +#include +#include +#include + +static TDB_DATA key, data; + +static void log_void(struct tdb_context *tdb, enum tdb_debug_level level, + const char *fmt, ...) +{ +} + +static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, + const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + +static int do_child(int fd) +{ + struct tdb_context *tdb; + unsigned int log_count; + struct tdb_logging_context log_ctx = { log_fn, &log_count }; + struct tdb_logging_context nolog_ctx = { log_void, NULL }; + char c; + + read(fd, &c, 1); + + tdb = tdb_open_ex("mutex-openflags2.tdb", 0, + TDB_DEFAULT, + O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL); + ok((tdb == NULL) && (errno == EINVAL), "TDB_DEFAULT without " + "TDB_MUTEX_LOCKING should fail with EINVAL - %d", errno); + + tdb = tdb_open_ex("mutex-openflags2.tdb", 0, + TDB_CLEAR_IF_FIRST, + O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL); + ok((tdb == NULL) && (errno == EINVAL), "TDB_CLEAR_IF_FIRST without " + "TDB_MUTEX_LOCKING should fail with EINVAL - %d", errno); + + tdb = tdb_open_ex("mutex-openflags2.tdb", 0, + TDB_CLEAR_IF_FIRST | + TDB_MUTEX_LOCKING | + TDB_INTERNAL, + O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL); + ok((tdb == NULL) && (errno == EINVAL), "TDB_MUTEX_LOCKING with " + "TDB_INTERNAL should fail with EINVAL - %d", errno); + + tdb = tdb_open_ex("mutex-openflags2.tdb", 0, + TDB_CLEAR_IF_FIRST | + TDB_MUTEX_LOCKING | + TDB_NOMMAP, + O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL); + ok((tdb == NULL) && (errno == EINVAL), "TDB_MUTEX_LOCKING with " + "TDB_NOMMAP should fail with EINVAL - %d", errno); + + tdb = tdb_open_ex("mutex-openflags2.tdb", 0, + TDB_CLEAR_IF_FIRST | + TDB_MUTEX_LOCKING, + O_RDONLY, 0755, &nolog_ctx, NULL); + ok((tdb != NULL), "TDB_MUTEX_LOCKING with " + "O_RDONLY should work - %d", errno); + tdb_close(tdb); + + tdb = tdb_open_ex("mutex-openflags2.tdb", 0, + TDB_CLEAR_IF_FIRST | + TDB_MUTEX_LOCKING, + O_RDWR|O_CREAT, 0755, &log_ctx, NULL); + ok((tdb != NULL), "TDB_MUTEX_LOCKING with TDB_CLEAR_IF_FIRST" + "TDB_NOMMAP should work - %d", errno); + + return 0; +} + +/* The code should barf on TDBs created with rwlocks. */ +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + unsigned int log_count; + struct tdb_logging_context log_ctx = { log_fn, &log_count }; + struct tdb_logging_context nolog_ctx = { log_void, NULL }; + int ret, status; + pid_t child, wait_ret; + int pipefd[2]; + char c = 0; + bool runtime_support; + + runtime_support = tdb_runtime_check_for_robust_mutexes(); + + ret = pipe(pipefd); + ok1(ret == 0); + + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + data.dsize = strlen("world"); + data.dptr = discard_const_p(uint8_t, "world"); + + if (!runtime_support) { + tdb = tdb_open_ex("mutex-openflags2.tdb", 0, + TDB_CLEAR_IF_FIRST| + TDB_MUTEX_LOCKING, + O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL); + ok((tdb == NULL) && (errno == ENOSYS), "TDB_MUTEX_LOCKING without " + "runtime support should fail with ENOSYS - %d", errno); + + skip(1, "No robust mutex support"); + return exit_status(); + } + + child = fork(); + if (child == 0) { + return do_child(pipefd[0]); + } + + tdb = tdb_open_ex("mutex-openflags2.tdb", 0, + TDB_CLEAR_IF_FIRST| + TDB_MUTEX_LOCKING, + O_RDWR|O_CREAT, 0755, &log_ctx, NULL); + ok((tdb != NULL), "tdb_open_ex with mutexes should succeed"); + + write(pipefd[1], &c, 1); + + wait_ret = wait(&status); + ok((wait_ret == child) && (status == 0), + "child should have exited correctly"); + + diag("done"); + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-mutex-transaction1.c b/ldb-2.0.8/lib/tdb/test/run-mutex-transaction1.c new file mode 100644 index 0000000..7b9f7b1 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-mutex-transaction1.c @@ -0,0 +1,236 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include +#include +#include + +static TDB_DATA key, data; + +static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, + const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + +static int do_child(int tdb_flags, int to, int from) +{ + struct tdb_context *tdb; + unsigned int log_count; + struct tdb_logging_context log_ctx = { log_fn, &log_count }; + int ret; + char c = 0; + + tdb = tdb_open_ex("mutex-transaction1.tdb", 3, tdb_flags, + O_RDWR|O_CREAT, 0755, &log_ctx, NULL); + ok(tdb, "tdb_open_ex should succeed"); + + ret = tdb_transaction_start(tdb); + ok(ret == 0, "tdb_transaction_start should succeed"); + + ret = tdb_store(tdb, key, data, TDB_INSERT); + ok(ret == 0, "tdb_store(tdb, key, data, TDB_INSERT) should succeed"); + + write(to, &c, sizeof(c)); + read(from, &c, sizeof(c)); + + ret = tdb_transaction_cancel(tdb); + ok(ret == 0, "tdb_transaction_cancel should succeed"); + + write(to, &c, sizeof(c)); + read(from, &c, sizeof(c)); + + ret = tdb_transaction_start(tdb); + ok(ret == 0, "tdb_transaction_start should succeed"); + + ret = tdb_store(tdb, key, data, TDB_INSERT); + ok(ret == 0, "tdb_store(tdb, key, data, TDB_INSERT) should succeed"); + + write(to, &c, sizeof(c)); + read(from, &c, sizeof(c)); + + ret = tdb_transaction_commit(tdb); + ok(ret == 0, "tdb_transaction_commit should succeed"); + + write(to, &c, sizeof(c)); + read(from, &c, sizeof(c)); + + ret = tdb_transaction_start(tdb); + ok(ret == 0, "tdb_transaction_start should succeed"); + + ret = tdb_store(tdb, key, key, TDB_REPLACE); + ok(ret == 0, "tdb_store(tdb, key, data, TDB_REPLACE) should succeed"); + + write(to, &c, sizeof(c)); + read(from, &c, sizeof(c)); + + ret = tdb_transaction_commit(tdb); + ok(ret == 0, "tdb_transaction_commit should succeed"); + + write(to, &c, sizeof(c)); + read(from, &c, sizeof(c)); + + return 0; +} + +/* The code should barf on TDBs created with rwlocks. */ +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + unsigned int log_count; + struct tdb_logging_context log_ctx = { log_fn, &log_count }; + int ret, status; + pid_t child, wait_ret; + int fromchild[2]; + int tochild[2]; + TDB_DATA val; + char c; + int tdb_flags; + bool runtime_support; + + runtime_support = tdb_runtime_check_for_robust_mutexes(); + + if (!runtime_support) { + skip(1, "No robust mutex support"); + return exit_status(); + } + + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + data.dsize = strlen("world"); + data.dptr = discard_const_p(uint8_t, "world"); + + pipe(fromchild); + pipe(tochild); + + tdb_flags = TDB_INCOMPATIBLE_HASH| + TDB_MUTEX_LOCKING| + TDB_CLEAR_IF_FIRST; + + child = fork(); + if (child == 0) { + close(fromchild[0]); + close(tochild[1]); + return do_child(tdb_flags, fromchild[1], tochild[0]); + } + close(fromchild[1]); + close(tochild[0]); + + read(fromchild[0], &c, sizeof(c)); + + tdb = tdb_open_ex("mutex-transaction1.tdb", 0, + tdb_flags, O_RDWR|O_CREAT, 0755, + &log_ctx, NULL); + ok(tdb, "tdb_open_ex should succeed"); + + /* + * The child has the transaction running + */ + ret = tdb_transaction_start_nonblock(tdb); + ok(ret == -1, "tdb_transaction_start_nonblock not succeed"); + + ret = tdb_chainlock_nonblock(tdb, key); + ok(ret == -1, "tdb_chainlock_nonblock should not succeed"); + + /* + * We can still read + */ + ret = tdb_exists(tdb, key); + ok(ret == 0, "tdb_exists(tdb, key) should return 0"); + + val = tdb_fetch(tdb, key); + ok(val.dsize == 0, "tdb_fetch(tdb, key) should return an empty value"); + + write(tochild[1], &c, sizeof(c)); + + /* + * When the child canceled we can start... + */ + ret = tdb_transaction_start(tdb); + ok(ret == 0, "tdb_transaction_start should succeed"); + + read(fromchild[0], &c, sizeof(c)); + write(tochild[1], &c, sizeof(c)); + + ret = tdb_transaction_cancel(tdb); + ok(ret == 0, "tdb_transaction_cancel should succeed"); + + /* + * When we canceled the child can start and store... + */ + read(fromchild[0], &c, sizeof(c)); + + /* + * We still see the old values before the child commits... + */ + ret = tdb_exists(tdb, key); + ok(ret == 0, "tdb_exists(tdb, key) should return 0"); + + val = tdb_fetch(tdb, key); + ok(val.dsize == 0, "tdb_fetch(tdb, key) should return an empty value"); + + write(tochild[1], &c, sizeof(c)); + read(fromchild[0], &c, sizeof(c)); + + /* + * We see the new values after the commit... + */ + ret = tdb_exists(tdb, key); + ok(ret == 1, "tdb_exists(tdb, key) should return 1"); + + val = tdb_fetch(tdb, key); + ok(val.dsize != 0, "tdb_fetch(tdb, key) should return a value"); + ok(val.dsize == data.dsize, "tdb_fetch(tdb, key) should return a value"); + ok(memcmp(val.dptr, data.dptr, data.dsize) == 0, "tdb_fetch(tdb, key) should return a value"); + + write(tochild[1], &c, sizeof(c)); + read(fromchild[0], &c, sizeof(c)); + + /* + * The child started a new transaction and replaces the value, + * but we still see the old values before the child commits... + */ + ret = tdb_exists(tdb, key); + ok(ret == 1, "tdb_exists(tdb, key) should return 1"); + + val = tdb_fetch(tdb, key); + ok(val.dsize != 0, "tdb_fetch(tdb, key) should return a value"); + ok(val.dsize == data.dsize, "tdb_fetch(tdb, key) should return a value"); + ok(memcmp(val.dptr, data.dptr, data.dsize) == 0, "tdb_fetch(tdb, key) should return a value"); + + write(tochild[1], &c, sizeof(c)); + read(fromchild[0], &c, sizeof(c)); + + /* + * We see the new values after the commit... + */ + ret = tdb_exists(tdb, key); + ok(ret == 1, "tdb_exists(tdb, key) should return 1"); + + val = tdb_fetch(tdb, key); + ok(val.dsize != 0, "tdb_fetch(tdb, key) should return a value"); + ok(val.dsize == key.dsize, "tdb_fetch(tdb, key) should return a value"); + ok(memcmp(val.dptr, key.dptr, key.dsize) == 0, "tdb_fetch(tdb, key) should return a value"); + + write(tochild[1], &c, sizeof(c)); + + wait_ret = wait(&status); + ok(wait_ret == child, "child should have exited correctly"); + + diag("done"); + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-mutex-trylock.c b/ldb-2.0.8/lib/tdb/test/run-mutex-trylock.c new file mode 100644 index 0000000..c96b635 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-mutex-trylock.c @@ -0,0 +1,122 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include +#include +#include + +static TDB_DATA key, data; + +static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, + const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + +static int do_child(int tdb_flags, int to, int from) +{ + struct tdb_context *tdb; + unsigned int log_count; + struct tdb_logging_context log_ctx = { log_fn, &log_count }; + int ret; + char c = 0; + + tdb = tdb_open_ex("mutex-trylock.tdb", 0, tdb_flags, + O_RDWR|O_CREAT, 0755, &log_ctx, NULL); + ok(tdb, "tdb_open_ex should succeed"); + + ret = tdb_chainlock(tdb, key); + ok(ret == 0, "tdb_chainlock should succeed"); + + write(to, &c, sizeof(c)); + + read(from, &c, sizeof(c)); + + ret = tdb_chainunlock(tdb, key); + ok(ret == 0, "tdb_chainunlock should succeed"); + + write(to, &c, sizeof(c)); + + return 0; +} + +/* The code should barf on TDBs created with rwlocks. */ +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + unsigned int log_count; + struct tdb_logging_context log_ctx = { log_fn, &log_count }; + int ret, status; + pid_t child, wait_ret; + int fromchild[2]; + int tochild[2]; + char c; + int tdb_flags; + bool runtime_support; + + runtime_support = tdb_runtime_check_for_robust_mutexes(); + + if (!runtime_support) { + skip(1, "No robust mutex support"); + return exit_status(); + } + + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + data.dsize = strlen("world"); + data.dptr = discard_const_p(uint8_t, "world"); + + pipe(fromchild); + pipe(tochild); + + tdb_flags = TDB_INCOMPATIBLE_HASH| + TDB_MUTEX_LOCKING| + TDB_CLEAR_IF_FIRST; + + child = fork(); + if (child == 0) { + close(fromchild[0]); + close(tochild[1]); + return do_child(tdb_flags, fromchild[1], tochild[0]); + } + close(fromchild[1]); + close(tochild[0]); + + read(fromchild[0], &c, sizeof(c)); + + tdb = tdb_open_ex("mutex-trylock.tdb", 0, tdb_flags, + O_RDWR|O_CREAT, 0755, &log_ctx, NULL); + ok(tdb, "tdb_open_ex should succeed"); + + ret = tdb_chainlock_nonblock(tdb, key); + ok(ret == -1, "tdb_chainlock_nonblock should not succeed"); + + write(tochild[1], &c, sizeof(c)); + + read(fromchild[0], &c, sizeof(c)); + + ret = tdb_chainlock_nonblock(tdb, key); + ok(ret == 0, "tdb_chainlock_nonblock should succeed"); + ret = tdb_chainunlock(tdb, key); + ok(ret == 0, "tdb_chainunlock should succeed"); + + wait_ret = wait(&status); + ok(wait_ret == child, "child should have exited correctly"); + + diag("done"); + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-mutex1.c b/ldb-2.0.8/lib/tdb/test/run-mutex1.c new file mode 100644 index 0000000..eb75946 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-mutex1.c @@ -0,0 +1,138 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include +#include +#include + +static TDB_DATA key, data; + +static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, + const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + +static int do_child(int tdb_flags, int to, int from) +{ + struct tdb_context *tdb; + unsigned int log_count; + struct tdb_logging_context log_ctx = { log_fn, &log_count }; + int ret; + char c = 0; + + tdb = tdb_open_ex("mutex1.tdb", 0, tdb_flags, + O_RDWR|O_CREAT, 0755, &log_ctx, NULL); + ok(tdb, "tdb_open_ex should succeed"); + + ret = tdb_chainlock(tdb, key); + ok(ret == 0, "tdb_chainlock should succeed"); + + write(to, &c, sizeof(c)); + read(from, &c, sizeof(c)); + + ret = tdb_chainunlock(tdb, key); + ok(ret == 0, "tdb_chainunlock should succeed"); + + write(to, &c, sizeof(c)); + read(from, &c, sizeof(c)); + + ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); + ok(ret == 0, "tdb_allrecord_lock should succeed"); + + write(to, &c, sizeof(c)); + read(from, &c, sizeof(c)); + + ret = tdb_allrecord_unlock(tdb, F_WRLCK, false); + ok(ret == 0, "tdb_allrecord_lock should succeed"); + + return 0; +} + +/* The code should barf on TDBs created with rwlocks. */ +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + unsigned int log_count; + struct tdb_logging_context log_ctx = { log_fn, &log_count }; + int ret, status; + pid_t child, wait_ret; + int fromchild[2]; + int tochild[2]; + char c; + int tdb_flags; + bool runtime_support; + + runtime_support = tdb_runtime_check_for_robust_mutexes(); + + if (!runtime_support) { + skip(1, "No robust mutex support"); + return exit_status(); + } + + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + data.dsize = strlen("world"); + data.dptr = discard_const_p(uint8_t, "world"); + + pipe(fromchild); + pipe(tochild); + + tdb_flags = TDB_INCOMPATIBLE_HASH| + TDB_MUTEX_LOCKING| + TDB_CLEAR_IF_FIRST; + + child = fork(); + if (child == 0) { + close(fromchild[0]); + close(tochild[1]); + return do_child(tdb_flags, fromchild[1], tochild[0]); + } + close(fromchild[1]); + close(tochild[0]); + + read(fromchild[0], &c, sizeof(c)); + + tdb = tdb_open_ex("mutex1.tdb", 0, tdb_flags, + O_RDWR|O_CREAT, 0755, &log_ctx, NULL); + ok(tdb, "tdb_open_ex should succeed"); + + write(tochild[1], &c, sizeof(c)); + read(fromchild[0], &c, sizeof(c)); + + ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); + ok(ret == 0, "tdb_allrecord_lock should succeed"); + + ret = tdb_store(tdb, key, data, 0); + ok(ret == 0, "tdb_store should succeed"); + + ret = tdb_allrecord_unlock(tdb, F_WRLCK, false); + ok(ret == 0, "tdb_allrecord_unlock should succeed"); + + write(tochild[1], &c, sizeof(c)); + read(fromchild[0], &c, sizeof(c)); + write(tochild[1], &c, sizeof(c)); + + ret = tdb_delete(tdb, key); + ok(ret == 0, "tdb_delete should succeed"); + + wait_ret = wait(&status); + ok(wait_ret == child, "child should have exited correctly"); + + diag("done"); + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-nested-transactions.c b/ldb-2.0.8/lib/tdb/test/run-nested-transactions.c new file mode 100644 index 0000000..864adf2 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-nested-transactions.c @@ -0,0 +1,79 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include +#include "logging.h" + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + TDB_DATA key, data; + + plan_tests(27); + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + + tdb = tdb_open_ex("run-nested-transactions.tdb", + 1024, TDB_CLEAR_IF_FIRST|TDB_DISALLOW_NESTING, + O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); + ok1(tdb); + + /* Nesting disallowed. */ + ok1(tdb_transaction_start(tdb) == 0); + data.dptr = discard_const_p(uint8_t, "world"); + data.dsize = strlen("world"); + ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); + data = tdb_fetch(tdb, key); + ok1(data.dsize == strlen("world")); + ok1(memcmp(data.dptr, "world", strlen("world")) == 0); + free(data.dptr); + ok1(tdb_transaction_start(tdb) != 0); + ok1(tdb_error(tdb) == TDB_ERR_NESTING); + + data = tdb_fetch(tdb, key); + ok1(data.dsize == strlen("world")); + ok1(memcmp(data.dptr, "world", strlen("world")) == 0); + free(data.dptr); + ok1(tdb_transaction_commit(tdb) == 0); + data = tdb_fetch(tdb, key); + ok1(data.dsize == strlen("world")); + ok1(memcmp(data.dptr, "world", strlen("world")) == 0); + free(data.dptr); + tdb_close(tdb); + + /* Nesting allowed by default */ + tdb = tdb_open_ex("run-nested-transactions.tdb", + 1024, TDB_DEFAULT, O_RDWR, 0, &taplogctx, NULL); + ok1(tdb); + + ok1(tdb_transaction_start(tdb) == 0); + ok1(tdb_transaction_start(tdb) == 0); + ok1(tdb_delete(tdb, key) == 0); + ok1(tdb_transaction_commit(tdb) == 0); + ok1(!tdb_exists(tdb, key)); + ok1(tdb_transaction_cancel(tdb) == 0); + /* Surprise! Kills inner "committed" transaction. */ + ok1(tdb_exists(tdb, key)); + + ok1(tdb_transaction_start(tdb) == 0); + ok1(tdb_transaction_start(tdb) == 0); + ok1(tdb_delete(tdb, key) == 0); + ok1(tdb_transaction_commit(tdb) == 0); + ok1(!tdb_exists(tdb, key)); + ok1(tdb_transaction_commit(tdb) == 0); + ok1(!tdb_exists(tdb, key)); + tdb_close(tdb); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-nested-traverse.c b/ldb-2.0.8/lib/tdb/test/run-nested-traverse.c new file mode 100644 index 0000000..aeaa085 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-nested-traverse.c @@ -0,0 +1,111 @@ +#include "../common/tdb_private.h" +#include "lock-tracking.h" +#define fcntl fcntl_with_lockcheck +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#undef fcntl +#include +#include +#include "external-agent.h" +#include "logging.h" + +static struct agent *agent; + +static bool correct_key(TDB_DATA key) +{ + return key.dsize == strlen("hi") + && memcmp(key.dptr, "hi", key.dsize) == 0; +} + +static bool correct_data(TDB_DATA data) +{ + return data.dsize == strlen("world") + && memcmp(data.dptr, "world", data.dsize) == 0; +} + +static int traverse2(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, + void *p) +{ + ok1(correct_key(key)); + ok1(correct_data(data)); + return 0; +} + +static int traverse1r(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, + void *p) +{ + ok1(correct_key(key)); + ok1(correct_data(data)); + ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) + == SUCCESS); + ok1(external_agent_operation(agent, STORE, tdb_name(tdb)) + == SUCCESS); + ok1(external_agent_operation(agent, TRANSACTION_COMMIT, tdb_name(tdb)) + == WOULD_HAVE_BLOCKED); + tdb_traverse(tdb, traverse2, NULL); + + /* That should *not* release the all-records lock! */ + ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) + == SUCCESS); + ok1(external_agent_operation(agent, STORE, tdb_name(tdb)) + == SUCCESS); + ok1(external_agent_operation(agent, TRANSACTION_COMMIT, tdb_name(tdb)) + == WOULD_HAVE_BLOCKED); + return 0; +} + +static int traverse1w(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, + void *p) +{ + ok1(correct_key(key)); + ok1(correct_data(data)); + ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) + == WOULD_HAVE_BLOCKED); + tdb_traverse(tdb, traverse2, NULL); + + /* That should *not* release the all-records lock! */ + ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) + == WOULD_HAVE_BLOCKED); + return 0; +} + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + TDB_DATA key, data; + + plan_tests(17); + agent = prepare_external_agent(); + + tdb = tdb_open_ex("run-nested-traverse.tdb", 1024, TDB_CLEAR_IF_FIRST, + O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); + ok1(tdb); + + ok1(external_agent_operation(agent, OPEN, tdb_name(tdb)) == SUCCESS); + ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) + == SUCCESS); + ok1(external_agent_operation(agent, TRANSACTION_COMMIT, tdb_name(tdb)) + == SUCCESS); + + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + data.dptr = discard_const_p(uint8_t, "world"); + data.dsize = strlen("world"); + + ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); + tdb_traverse(tdb, traverse1w, NULL); + tdb_traverse_read(tdb, traverse1r, NULL); + tdb_close(tdb); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-no-lock-during-traverse.c b/ldb-2.0.8/lib/tdb/test/run-no-lock-during-traverse.c new file mode 100644 index 0000000..737a32f --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-no-lock-during-traverse.c @@ -0,0 +1,114 @@ +#include "../common/tdb_private.h" +#include "lock-tracking.h" + +#define fcntl fcntl_with_lockcheck + +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include "logging.h" + +#undef fcntl + +#define NUM_ENTRIES 10 + +static bool prepare_entries(struct tdb_context *tdb) +{ + unsigned int i; + TDB_DATA key, data; + + for (i = 0; i < NUM_ENTRIES; i++) { + key.dsize = sizeof(i); + key.dptr = (void *)&i; + data.dsize = strlen("world"); + data.dptr = discard_const_p(uint8_t, "world"); + + if (tdb_store(tdb, key, data, 0) != 0) + return false; + } + return true; +} + +static void delete_entries(struct tdb_context *tdb) +{ + unsigned int i; + TDB_DATA key; + + for (i = 0; i < NUM_ENTRIES; i++) { + key.dsize = sizeof(i); + key.dptr = (void *)&i; + + ok1(tdb_delete(tdb, key) == 0); + } +} + +/* We don't know how many times this will run. */ +static int delete_other(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, + void *private_data) +{ + unsigned int i; + memcpy(&i, key.dptr, 4); + i = (i + 1) % NUM_ENTRIES; + key.dptr = (void *)&i; + if (tdb_delete(tdb, key) != 0) + (*(int *)private_data)++; + return 0; +} + +static int delete_self(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, + void *private_data) +{ + ok1(tdb_delete(tdb, key) == 0); + return 0; +} + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + int errors = 0; + + plan_tests(41); + tdb = tdb_open_ex("run-no-lock-during-traverse.tdb", + 1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, + 0600, &taplogctx, NULL); + + ok1(tdb); + ok1(prepare_entries(tdb)); + ok1(locking_errors == 0); + ok1(tdb_lockall(tdb) == 0); + ok1(locking_errors == 0); + tdb_traverse(tdb, delete_other, &errors); + ok1(errors == 0); + ok1(locking_errors == 0); + ok1(tdb_unlockall(tdb) == 0); + + ok1(prepare_entries(tdb)); + ok1(locking_errors == 0); + ok1(tdb_lockall(tdb) == 0); + ok1(locking_errors == 0); + tdb_traverse(tdb, delete_self, NULL); + ok1(locking_errors == 0); + ok1(tdb_unlockall(tdb) == 0); + + ok1(prepare_entries(tdb)); + ok1(locking_errors == 0); + ok1(tdb_lockall(tdb) == 0); + ok1(locking_errors == 0); + delete_entries(tdb); + ok1(locking_errors == 0); + ok1(tdb_unlockall(tdb) == 0); + + ok1(tdb_close(tdb) == 0); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-oldhash.c b/ldb-2.0.8/lib/tdb/test/run-oldhash.c new file mode 100644 index 0000000..aaee6f6 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-oldhash.c @@ -0,0 +1,50 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include "logging.h" + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + + plan_tests(8); + + /* Old format (with zeroes in the hash magic fields) should + * open with any hash (since we don't know what hash they used). */ + tdb = tdb_open_ex("test/old-nohash-le.tdb", 0, 0, O_RDWR, 0, + &taplogctx, NULL); + ok1(tdb); + ok1(tdb_check(tdb, NULL, NULL) == 0); + tdb_close(tdb); + + tdb = tdb_open_ex("test/old-nohash-be.tdb", 0, 0, O_RDWR, 0, + &taplogctx, NULL); + ok1(tdb); + ok1(tdb_check(tdb, NULL, NULL) == 0); + tdb_close(tdb); + + tdb = tdb_open_ex("test/old-nohash-le.tdb", 0, 0, O_RDWR, 0, + &taplogctx, tdb_jenkins_hash); + ok1(tdb); + ok1(tdb_check(tdb, NULL, NULL) == 0); + tdb_close(tdb); + + tdb = tdb_open_ex("test/old-nohash-be.tdb", 0, 0, O_RDWR, 0, + &taplogctx, tdb_jenkins_hash); + ok1(tdb); + ok1(tdb_check(tdb, NULL, NULL) == 0); + tdb_close(tdb); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-open-during-transaction.c b/ldb-2.0.8/lib/tdb/test/run-open-during-transaction.c new file mode 100644 index 0000000..9a6c6c1 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-open-during-transaction.c @@ -0,0 +1,183 @@ +#include "../common/tdb_private.h" +#include "lock-tracking.h" + +static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset); +static ssize_t write_check(int fd, const void *buf, size_t count); +static int ftruncate_check(int fd, off_t length); + +#define pwrite pwrite_check +#define write write_check +#define fcntl fcntl_with_lockcheck +#define ftruncate ftruncate_check + +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include +#include +#include "external-agent.h" +#include "logging.h" + +static struct agent *agent; +static bool opened; +static int errors = 0; +static bool clear_if_first; +#define TEST_DBNAME "run-open-during-transaction.tdb" + +#undef write +#undef pwrite +#undef fcntl +#undef ftruncate + +static bool is_same(const char *snapshot, const char *latest, off_t len) +{ + unsigned i; + + for (i = 0; i < len; i++) { + if (snapshot[i] != latest[i]) + return false; + } + return true; +} + +static bool compare_file(int fd, const char *snapshot, off_t snapshot_len) +{ + char *contents; + bool same; + + /* over-length read serves as length check. */ + contents = malloc(snapshot_len+1); + same = pread(fd, contents, snapshot_len+1, 0) == snapshot_len + && is_same(snapshot, contents, snapshot_len); + free(contents); + return same; +} + +static void check_file_intact(int fd) +{ + enum agent_return ret; + struct stat st; + char *contents; + + fstat(fd, &st); + contents = malloc(st.st_size); + if (pread(fd, contents, st.st_size, 0) != st.st_size) { + diag("Read fail"); + errors++; + free(contents); + return; + } + + /* Ask agent to open file. */ + ret = external_agent_operation(agent, clear_if_first ? + OPEN_WITH_CLEAR_IF_FIRST : + OPEN, + TEST_DBNAME); + + /* It's OK to open it, but it must not have changed! */ + if (!compare_file(fd, contents, st.st_size)) { + diag("Agent changed file after opening %s", + agent_return_name(ret)); + errors++; + } + + if (ret == SUCCESS) { + ret = external_agent_operation(agent, CLOSE, NULL); + if (ret != SUCCESS) { + diag("Agent failed to close tdb: %s", + agent_return_name(ret)); + errors++; + } + } else if (ret != WOULD_HAVE_BLOCKED) { + diag("Agent opening file gave %s", + agent_return_name(ret)); + errors++; + } + + free(contents); +} + +static void after_unlock(int fd) +{ + if (opened) + check_file_intact(fd); +} + +static ssize_t pwrite_check(int fd, + const void *buf, size_t count, off_t offset) +{ + if (opened) + check_file_intact(fd); + + return pwrite(fd, buf, count, offset); +} + +static ssize_t write_check(int fd, const void *buf, size_t count) +{ + if (opened) + check_file_intact(fd); + + return write(fd, buf, count); +} + +static int ftruncate_check(int fd, off_t length) +{ + if (opened) + check_file_intact(fd); + + return ftruncate(fd, length); + +} + +int main(int argc, char *argv[]) +{ + const int flags[] = { TDB_DEFAULT, + TDB_CLEAR_IF_FIRST, + TDB_NOMMAP, + TDB_CLEAR_IF_FIRST | TDB_NOMMAP }; + int i; + struct tdb_context *tdb; + TDB_DATA key, data; + + plan_tests(20); + agent = prepare_external_agent(); + + unlock_callback = after_unlock; + for (i = 0; i < sizeof(flags)/sizeof(flags[0]); i++) { + clear_if_first = (flags[i] & TDB_CLEAR_IF_FIRST); + diag("Test with %s and %s", + clear_if_first ? "CLEAR" : "DEFAULT", + (flags[i] & TDB_NOMMAP) ? "no mmap" : "mmap"); + unlink(TEST_DBNAME); + tdb = tdb_open_ex(TEST_DBNAME, 1024, flags[i], + O_CREAT|O_TRUNC|O_RDWR, 0600, + &taplogctx, NULL); + ok1(tdb); + + opened = true; + ok1(tdb_transaction_start(tdb) == 0); + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + data.dptr = discard_const_p(uint8_t, "world"); + data.dsize = strlen("world"); + + ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); + ok1(tdb_transaction_commit(tdb) == 0); + ok(!errors, "We had %u open errors", errors); + + opened = false; + tdb_close(tdb); + } + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-rdlock-upgrade.c b/ldb-2.0.8/lib/tdb/test/run-rdlock-upgrade.c new file mode 100644 index 0000000..042001b --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-rdlock-upgrade.c @@ -0,0 +1,166 @@ +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include +#include +#include +#include "logging.h" + +static TDB_DATA key, data; + +static void do_chainlock(const char *name, int tdb_flags, int up, int down) +{ + struct tdb_context *tdb; + int ret; + ssize_t nread, nwritten; + char c = 0; + + tdb = tdb_open_ex(name, 3, tdb_flags, + O_RDWR|O_CREAT, 0755, &taplogctx, NULL); + ok(tdb, "tdb_open_ex should succeed"); + + ret = tdb_chainlock_read(tdb, key); + ok(ret == 0, "tdb_chainlock_read should succeed"); + + nwritten = write(up, &c, sizeof(c)); + ok(nwritten == sizeof(c), "write should succeed"); + + nread = read(down, &c, sizeof(c)); + ok(nread == 0, "read should succeed"); + + exit(0); +} + +static void do_trylock(const char *name, int tdb_flags, int up, int down) +{ + struct tdb_context *tdb; + int ret; + ssize_t nread, nwritten; + char c = 0; + + tdb = tdb_open_ex(name, 3, tdb_flags, + O_RDWR|O_CREAT, 0755, &taplogctx, NULL); + ok(tdb, "tdb_open_ex should succeed"); + + /* + * tdb used to have a bug where with fcntl locks an upgrade + * from a readlock to writelock did not check for the + * underlying fcntl lock. Mutexes don't distinguish between + * readlocks and writelocks, so that bug does not apply here. + */ + + ret = tdb_chainlock_read(tdb, key); + ok(ret == 0, "tdb_chainlock_read should succeed"); + + ret = tdb_chainlock_nonblock(tdb, key); + ok(ret == -1, "tdb_chainlock_nonblock should fail"); + + nwritten = write(up, &c, sizeof(c)); + ok(nwritten == sizeof(c), "write should succeed"); + + nread = read(down, &c, sizeof(c)); + ok(nread == 0, "read should succeed"); + + exit(0); +} + +static int do_tests(const char *name, int tdb_flags) +{ + int ret; + pid_t chainlock_child, store_child; + int chainlock_down[2]; + int chainlock_up[2]; + int store_down[2]; + int store_up[2]; + char c; + ssize_t nread; + + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + data.dsize = strlen("world"); + data.dptr = discard_const_p(uint8_t, "world"); + + ret = pipe(chainlock_down); + ok(ret == 0, "pipe should succeed"); + + ret = pipe(chainlock_up); + ok(ret == 0, "pipe should succeed"); + + ret = pipe(store_down); + ok(ret == 0, "pipe should succeed"); + + ret = pipe(store_up); + ok(ret == 0, "pipe should succeed"); + + chainlock_child = fork(); + ok(chainlock_child != -1, "fork should succeed"); + + if (chainlock_child == 0) { + close(chainlock_up[0]); + close(chainlock_down[1]); + close(store_up[0]); + close(store_up[1]); + close(store_down[0]); + close(store_down[1]); + do_chainlock(name, tdb_flags, + chainlock_up[1], chainlock_down[0]); + exit(0); + } + close(chainlock_up[1]); + close(chainlock_down[0]); + + nread = read(chainlock_up[0], &c, sizeof(c)); + ok(nread == sizeof(c), "read should succeed"); + + /* + * Now we have a process holding a chain read lock. Start + * another process trying to write lock. This should fail. + */ + + store_child = fork(); + ok(store_child != -1, "fork should succeed"); + + if (store_child == 0) { + close(chainlock_up[0]); + close(chainlock_down[1]); + close(store_up[0]); + close(store_down[1]); + do_trylock(name, tdb_flags, + store_up[1], store_down[0]); + exit(0); + } + close(store_up[1]); + close(store_down[0]); + + nread = read(store_up[0], &c, sizeof(c)); + ok(nread == sizeof(c), "read should succeed"); + + close(chainlock_up[0]); + close(chainlock_down[1]); + close(store_up[0]); + close(store_down[1]); + diag("%s tests done", name); + return exit_status(); +} + +int main(int argc, char *argv[]) +{ + int ret; + + ret = do_tests("rdlock-upgrade.tdb", + TDB_CLEAR_IF_FIRST | + TDB_INCOMPATIBLE_HASH); + ok(ret == 0, "rdlock-upgrade.tdb tests should succeed"); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-readonly-check.c b/ldb-2.0.8/lib/tdb/test/run-readonly-check.c new file mode 100644 index 0000000..c5e0f7d --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-readonly-check.c @@ -0,0 +1,53 @@ +/* We should be able to tdb_check a O_RDONLY tdb, and we were previously allowed + * to tdb_check() inside a transaction (though that's paranoia!). */ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include "logging.h" + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + TDB_DATA key, data; + + plan_tests(11); + tdb = tdb_open_ex("run-readonly-check.tdb", 1024, + TDB_DEFAULT, + O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); + + ok1(tdb); + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + data.dsize = strlen("world"); + data.dptr = discard_const_p(uint8_t, "world"); + + ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); + ok1(tdb_check(tdb, NULL, NULL) == 0); + + /* We are also allowed to do a check inside a transaction. */ + ok1(tdb_transaction_start(tdb) == 0); + ok1(tdb_check(tdb, NULL, NULL) == 0); + ok1(tdb_close(tdb) == 0); + + tdb = tdb_open_ex("run-readonly-check.tdb", 1024, + TDB_DEFAULT, O_RDONLY, 0, &taplogctx, NULL); + + ok1(tdb); + ok1(tdb_store(tdb, key, data, TDB_MODIFY) == -1); + ok1(tdb_error(tdb) == TDB_ERR_RDONLY); + ok1(tdb_check(tdb, NULL, NULL) == 0); + ok1(tdb_close(tdb) == 0); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-rescue-find_entry.c b/ldb-2.0.8/lib/tdb/test/run-rescue-find_entry.c new file mode 100644 index 0000000..5d6f8f7 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-rescue-find_entry.c @@ -0,0 +1,51 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/rescue.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include "logging.h" + +#define NUM 20 + +/* Binary searches are deceptively simple: easy to screw up! */ +int main(int argc, char *argv[]) +{ + unsigned int i, j, n; + struct found f[NUM+1]; + struct found_table table; + + /* Set up array for searching. */ + for (i = 0; i < NUM+1; i++) { + f[i].head = i * 3; + } + table.arr = f; + + for (i = 0; i < NUM; i++) { + table.num = i; + for (j = 0; j < (i + 2) * 3; j++) { + n = find_entry(&table, j); + ok1(n <= i); + + /* If we were searching for something too large... */ + if (j > i*3) + ok1(n == i); + else { + /* It must give us something after j */ + ok1(f[n].head >= j); + ok1(n == 0 || f[n-1].head < j); + } + } + } + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-rescue.c b/ldb-2.0.8/lib/tdb/test/run-rescue.c new file mode 100644 index 0000000..e43f53b --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-rescue.c @@ -0,0 +1,127 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/rescue.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include "logging.h" + +struct walk_data { + TDB_DATA key; + TDB_DATA data; + bool fail; + unsigned count; +}; + +static inline bool tdb_deq(TDB_DATA a, TDB_DATA b) +{ + return a.dsize == b.dsize && memcmp(a.dptr, b.dptr, a.dsize) == 0; +} + +static inline TDB_DATA tdb_mkdata(const void *p, size_t len) +{ + TDB_DATA d; + d.dptr = discard_const_p(uint8_t, p); + d.dsize = len; + return d; +} + +static void walk(TDB_DATA key, TDB_DATA data, void *_wd) +{ + struct walk_data *wd = _wd; + + if (!tdb_deq(key, wd->key)) { + wd->fail = true; + } + + if (!tdb_deq(data, wd->data)) { + wd->fail = true; + } + wd->count++; +} + +static void count_records(TDB_DATA key, TDB_DATA data, void *_wd) +{ + struct walk_data *wd = _wd; + + if (!tdb_deq(key, wd->key) || !tdb_deq(data, wd->data)) + diag("%.*s::%.*s", + (int)key.dsize, key.dptr, (int)data.dsize, data.dptr); + wd->count++; +} + +static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) +{ + unsigned int *count = tdb_get_logging_private(tdb); + (*count)++; +} + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + struct walk_data wd; + unsigned int i, size, log_count = 0; + struct tdb_logging_context log_ctx = { log_fn, &log_count }; + + plan_tests(8); + tdb = tdb_open_ex("run-rescue.tdb", 1, TDB_CLEAR_IF_FIRST, + O_CREAT|O_TRUNC|O_RDWR, 0600, &log_ctx, NULL); + + wd.key.dsize = strlen("hi"); + wd.key.dptr = discard_const_p(uint8_t, "hi"); + wd.data.dsize = strlen("world"); + wd.data.dptr = discard_const_p(uint8_t, "world"); + wd.count = 0; + wd.fail = false; + + ok1(tdb_store(tdb, wd.key, wd.data, TDB_INSERT) == 0); + + ok1(tdb_rescue(tdb, walk, &wd) == 0); + ok1(!wd.fail); + ok1(wd.count == 1); + + /* Corrupt the database, walk should either get it or not. */ + size = tdb->map_size; + for (i = sizeof(struct tdb_header); i < size; i++) { + char c; + if (tdb->methods->tdb_read(tdb, i, &c, 1, false) != 0) + fail("Reading offset %i", i); + if (tdb->methods->tdb_write(tdb, i, "X", 1) != 0) + fail("Writing X at offset %i", i); + + wd.count = 0; + if (tdb_rescue(tdb, count_records, &wd) != 0) { + wd.fail = true; + break; + } + /* Could be 0 or 1. */ + if (wd.count > 1) { + wd.fail = true; + break; + } + if (tdb->methods->tdb_write(tdb, i, &c, 1) != 0) + fail("Restoring offset %i", i); + } + ok1(log_count == 0); + ok1(!wd.fail); + tdb_close(tdb); + + /* Now try our known-corrupt db. */ + tdb = tdb_open_ex("test/tdb.corrupt", 1024, 0, O_RDWR, 0, + &taplogctx, NULL); + wd.count = 0; + ok1(tdb_rescue(tdb, count_records, &wd) == 0); + ok1(wd.count == 1627); + tdb_close(tdb); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-rwlock-check.c b/ldb-2.0.8/lib/tdb/test/run-rwlock-check.c new file mode 100644 index 0000000..2ac9dc3 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-rwlock-check.c @@ -0,0 +1,46 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include + +static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) +{ + unsigned int *count = tdb_get_logging_private(tdb); + if (strstr(fmt, "spinlocks")) + (*count)++; +} + +/* The code should barf on TDBs created with rwlocks. */ +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + unsigned int log_count; + struct tdb_logging_context log_ctx = { log_fn, &log_count }; + + plan_tests(4); + + /* We should fail to open rwlock-using tdbs of either endian. */ + log_count = 0; + tdb = tdb_open_ex("test/rwlock-le.tdb", 0, 0, O_RDWR, 0, + &log_ctx, NULL); + ok1(!tdb); + ok1(log_count == 1); + + log_count = 0; + tdb = tdb_open_ex("test/rwlock-be.tdb", 0, 0, O_RDWR, 0, + &log_ctx, NULL); + ok1(!tdb); + ok1(log_count == 1); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-summary.c b/ldb-2.0.8/lib/tdb/test/run-summary.c new file mode 100644 index 0000000..8b9a1a0 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-summary.c @@ -0,0 +1,65 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/summary.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include + +int main(int argc, char *argv[]) +{ + unsigned int i, j; + struct tdb_context *tdb; + int flags[] = { TDB_INTERNAL, TDB_DEFAULT, TDB_NOMMAP, + TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT, + TDB_NOMMAP|TDB_CONVERT }; + TDB_DATA key = { (unsigned char *)&j, sizeof(j) }; + TDB_DATA data = { (unsigned char *)&j, sizeof(j) }; + char *summary; + + plan_tests(sizeof(flags) / sizeof(flags[0]) * 14); + for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { + tdb = tdb_open("run-summary.tdb", 131, flags[i], + O_RDWR|O_CREAT|O_TRUNC, 0600); + ok1(tdb); + if (!tdb) + continue; + + /* Put some stuff in there. */ + for (j = 0; j < 500; j++) { + /* Make sure padding varies to we get some graphs! */ + data.dsize = j % (sizeof(j) + 1); + if (tdb_store(tdb, key, data, TDB_REPLACE) != 0) + fail("Storing in tdb"); + } + + summary = tdb_summary(tdb); + diag("%s", summary); + ok1(strstr(summary, "Size of file/data: ")); + ok1(strstr(summary, "Number of records: 500\n")); + ok1(strstr(summary, "Smallest/average/largest keys: 4/4/4\n")); + ok1(strstr(summary, "Smallest/average/largest data: 0/2/4\n")); + ok1(strstr(summary, "Smallest/average/largest padding: ")); + ok1(strstr(summary, "Number of dead records: 0\n")); + ok1(strstr(summary, "Number of free records: 1\n")); + ok1(strstr(summary, "Smallest/average/largest free records: ")); + ok1(strstr(summary, "Number of hash chains: 131\n")); + ok1(strstr(summary, "Smallest/average/largest hash chains: ")); + ok1(strstr(summary, "Number of uncoalesced records: 0\n")); + ok1(strstr(summary, "Smallest/average/largest uncoalesced runs: 0/0/0\n")); + ok1(strstr(summary, "Percentage keys/data/padding/free/dead/rechdrs&tailers/hashes: ")); + + free(summary); + tdb_close(tdb); + } + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-transaction-expand.c b/ldb-2.0.8/lib/tdb/test/run-transaction-expand.c new file mode 100644 index 0000000..d36b894 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-transaction-expand.c @@ -0,0 +1,125 @@ +#include "../common/tdb_private.h" + +/* Speed up the tests, but do the actual sync tests. */ +static unsigned int sync_counts = 0; +static inline int fake_fsync(int fd) +{ + sync_counts++; + return 0; +} +#define fsync fake_fsync + +#ifdef MS_SYNC +static inline int fake_msync(void *addr, size_t length, int flags) +{ + sync_counts++; + return 0; +} +#define msync fake_msync +#endif + +#ifdef HAVE_FDATASYNC +static inline int fake_fdatasync(int fd) +{ + sync_counts++; + return 0; +} +#define fdatasync fake_fdatasync +#endif + +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include "logging.h" + +static void write_record(struct tdb_context *tdb, size_t extra_len, + TDB_DATA *data) +{ + TDB_DATA key; + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + + data->dsize += extra_len; + tdb_transaction_start(tdb); + tdb_store(tdb, key, *data, TDB_REPLACE); + tdb_transaction_commit(tdb); +} + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + size_t i; + TDB_DATA data; + struct tdb_record rec; + tdb_off_t off; + + /* Do *not* suppress sync for this test; we do it ourselves. */ + unsetenv("TDB_NO_FSYNC"); + + plan_tests(5); + tdb = tdb_open_ex("run-transaction-expand.tdb", + 1024, TDB_CLEAR_IF_FIRST, + O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); + ok1(tdb); + + data.dsize = 0; + data.dptr = calloc(1000, getpagesize()); + if (data.dptr == NULL) { + diag("Unable to allocate memory for data.dptr"); + tdb_close(tdb); + exit(1); + } + + /* Simulate a slowly growing record. */ + for (i = 0; i < 1000; i++) + write_record(tdb, getpagesize(), &data); + + tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &off); + tdb_read(tdb, off, &rec, sizeof(rec), DOCONV()); + diag("TDB size = %zu, recovery = %llu-%llu", + (size_t)tdb->map_size, (unsigned long long)off, (unsigned long long)(off + sizeof(rec) + rec.rec_len)); + + /* We should only be about 5 times larger than largest record. */ + ok1(tdb->map_size < 6 * i * getpagesize()); + tdb_close(tdb); + + tdb = tdb_open_ex("run-transaction-expand.tdb", + 1024, TDB_CLEAR_IF_FIRST, + O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); + ok1(tdb); + + data.dsize = 0; + + /* Simulate a slowly growing record, repacking to keep + * recovery area at end. */ + for (i = 0; i < 1000; i++) { + write_record(tdb, getpagesize(), &data); + if (i % 10 == 0) + tdb_repack(tdb); + } + + tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &off); + tdb_read(tdb, off, &rec, sizeof(rec), DOCONV()); + diag("TDB size = %zu, recovery = %llu-%llu", + (size_t)tdb->map_size, (unsigned long long)off, (unsigned long long)(off + sizeof(rec) + rec.rec_len)); + + /* We should only be about 4 times larger than largest record. */ + ok1(tdb->map_size < 5 * i * getpagesize()); + + /* We should have synchronized multiple times. */ + ok1(sync_counts); + tdb_close(tdb); + free(data.dptr); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-traverse-chain.c b/ldb-2.0.8/lib/tdb/test/run-traverse-chain.c new file mode 100644 index 0000000..2a25bec --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-traverse-chain.c @@ -0,0 +1,94 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include "logging.h" + +static char keystr0[] = "x"; +static TDB_DATA key0 = { .dptr = (uint8_t *)keystr0, + .dsize = sizeof(keystr0) }; +static char valuestr0[] = "y"; +static TDB_DATA value0 = { .dptr = (uint8_t *)valuestr0, + .dsize = sizeof(valuestr0) }; + +static char keystr1[] = "aaa"; +static TDB_DATA key1 = { .dptr = (uint8_t *)keystr1, + .dsize = sizeof(keystr1) }; +static char valuestr1[] = "bbbbb"; +static TDB_DATA value1 = { .dptr = (uint8_t *)valuestr1, + .dsize = sizeof(valuestr1) }; + +static TDB_DATA *keys[] = { &key0, &key1 }; +static TDB_DATA *values[] = { &value0, &value1 }; + +static bool tdb_data_same(TDB_DATA d1, TDB_DATA d2) +{ + if (d1.dsize != d2.dsize) { + return false; + } + return (memcmp(d1.dptr, d2.dptr, d1.dsize) == 0); +} + +struct traverse_chain_state { + size_t idx; + bool ok; +}; + +static int traverse_chain_fn(struct tdb_context *tdb, + TDB_DATA key, + TDB_DATA data, + void *private_data) +{ + struct traverse_chain_state *state = private_data; + + state->ok &= tdb_data_same(key, *keys[state->idx]); + state->ok &= tdb_data_same(data, *values[state->idx]); + state->idx += 1; + + return 0; +} + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + struct traverse_chain_state state = { .ok = true }; + int ret; + + plan_tests(4); + + tdb = tdb_open_ex( + "traverse_chain.tdb", + 1, + TDB_CLEAR_IF_FIRST, + O_RDWR|O_CREAT, + 0600, + &taplogctx, + NULL); + ok1(tdb); + + /* add in reverse order, tdb_store adds to the front of the list */ + ret = tdb_store(tdb, key1, value1, TDB_INSERT); + ok1(ret == 0); + ret = tdb_store(tdb, key0, value0, TDB_INSERT); + ok1(ret == 0); + + ret = tdb_traverse_key_chain(tdb, key0, traverse_chain_fn, &state); + ok1(ret == 2); + ok1(state.ok); + + unlink(tdb_name(tdb)); + + tdb_close(tdb); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-traverse-in-transaction.c b/ldb-2.0.8/lib/tdb/test/run-traverse-in-transaction.c new file mode 100644 index 0000000..d187b9b --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-traverse-in-transaction.c @@ -0,0 +1,90 @@ +#include "lock-tracking.h" +#include "../common/tdb_private.h" +#define fcntl fcntl_with_lockcheck +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#undef fcntl_with_lockcheck +#include +#include +#include "external-agent.h" +#include "logging.h" + +static struct agent *agent; + +static bool correct_key(TDB_DATA key) +{ + return key.dsize == strlen("hi") + && memcmp(key.dptr, "hi", key.dsize) == 0; +} + +static bool correct_data(TDB_DATA data) +{ + return data.dsize == strlen("world") + && memcmp(data.dptr, "world", data.dsize) == 0; +} + +static int traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, + void *p) +{ + ok1(correct_key(key)); + ok1(correct_data(data)); + return 0; +} + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + TDB_DATA key, data; + + plan_tests(13); + agent = prepare_external_agent(); + + tdb = tdb_open_ex("run-traverse-in-transaction.tdb", + 1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, + 0600, &taplogctx, NULL); + ok1(tdb); + + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + data.dptr = discard_const_p(uint8_t, "world"); + data.dsize = strlen("world"); + + ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); + + ok1(external_agent_operation(agent, OPEN, tdb_name(tdb)) == SUCCESS); + + ok1(tdb_transaction_active(tdb) == 0); + ok1(tdb_transaction_start(tdb) == 0); + ok1(tdb_transaction_active(tdb) == 1); + ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) + == WOULD_HAVE_BLOCKED); + tdb_traverse(tdb, traverse, NULL); + + /* That should *not* release the transaction lock! */ + ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) + == WOULD_HAVE_BLOCKED); + tdb_traverse_read(tdb, traverse, NULL); + + /* That should *not* release the transaction lock! */ + ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) + == WOULD_HAVE_BLOCKED); + ok1(tdb_transaction_commit(tdb) == 0); + ok1(tdb_transaction_active(tdb) == 0); + /* Now we should be fine. */ + ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) + == SUCCESS); + + tdb_close(tdb); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-wronghash-fail.c b/ldb-2.0.8/lib/tdb/test/run-wronghash-fail.c new file mode 100644 index 0000000..c44b0f5 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-wronghash-fail.c @@ -0,0 +1,121 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include + +static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) +{ + unsigned int *count = tdb_get_logging_private(tdb); + if (strstr(fmt, "hash")) + (*count)++; +} + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + unsigned int log_count; + TDB_DATA d; + struct tdb_logging_context log_ctx = { log_fn, &log_count }; + + plan_tests(28); + + /* Create with default hash. */ + log_count = 0; + tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, + O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx, NULL); + ok1(tdb); + ok1(log_count == 0); + d.dptr = discard_const_p(uint8_t, "Hello"); + d.dsize = 5; + ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0); + tdb_close(tdb); + + /* Fail to open with different hash. */ + tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_RDWR, 0, + &log_ctx, tdb_jenkins_hash); + ok1(!tdb); + ok1(log_count == 1); + + /* Create with different hash. */ + log_count = 0; + tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, + O_CREAT|O_RDWR|O_TRUNC, + 0600, &log_ctx, tdb_jenkins_hash); + ok1(tdb); + ok1(log_count == 0); + tdb_close(tdb); + + /* Endian should be no problem. */ + log_count = 0; + tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDWR, 0, + &log_ctx, tdb_old_hash); + ok1(!tdb); + ok1(log_count == 1); + + log_count = 0; + tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDWR, 0, + &log_ctx, tdb_old_hash); + ok1(!tdb); + ok1(log_count == 1); + + log_count = 0; + /* Fail to open with old default hash. */ + tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_RDWR, 0, + &log_ctx, tdb_old_hash); + ok1(!tdb); + ok1(log_count == 1); + + log_count = 0; + tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDONLY, + 0, &log_ctx, tdb_jenkins_hash); + ok1(tdb); + ok1(log_count == 0); + ok1(tdb_check(tdb, NULL, NULL) == 0); + tdb_close(tdb); + + log_count = 0; + tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDONLY, + 0, &log_ctx, tdb_jenkins_hash); + ok1(tdb); + ok1(log_count == 0); + ok1(tdb_check(tdb, NULL, NULL) == 0); + tdb_close(tdb); + + /* It should open with jenkins hash if we don't specify. */ + log_count = 0; + tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDWR, 0, + &log_ctx, NULL); + ok1(tdb); + ok1(log_count == 0); + ok1(tdb_check(tdb, NULL, NULL) == 0); + tdb_close(tdb); + + log_count = 0; + tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDWR, 0, + &log_ctx, NULL); + ok1(tdb); + ok1(log_count == 0); + ok1(tdb_check(tdb, NULL, NULL) == 0); + tdb_close(tdb); + + log_count = 0; + tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_RDONLY, + 0, &log_ctx, NULL); + ok1(tdb); + ok1(log_count == 0); + ok1(tdb_check(tdb, NULL, NULL) == 0); + tdb_close(tdb); + + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run-zero-append.c b/ldb-2.0.8/lib/tdb/test/run-zero-append.c new file mode 100644 index 0000000..f9eba1b --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run-zero-append.c @@ -0,0 +1,41 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include "logging.h" + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + TDB_DATA key, data; + + plan_tests(4); + tdb = tdb_open_ex(NULL, 1024, TDB_INTERNAL, O_CREAT|O_TRUNC|O_RDWR, + 0600, &taplogctx, NULL); + ok1(tdb); + + /* Tickle bug on appending zero length buffer to zero length buffer. */ + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + data.dptr = discard_const_p(uint8_t, "world"); + data.dsize = 0; + + ok1(tdb_append(tdb, key, data) == 0); + ok1(tdb_append(tdb, key, data) == 0); + data = tdb_fetch(tdb, key); + ok1(data.dsize == 0); + tdb_close(tdb); + free(data.dptr); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/run.c b/ldb-2.0.8/lib/tdb/test/run.c new file mode 100644 index 0000000..c744c4d --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/run.c @@ -0,0 +1,50 @@ +#include "../common/tdb_private.h" +#include "../common/io.c" +#include "../common/tdb.c" +#include "../common/lock.c" +#include "../common/freelist.c" +#include "../common/traverse.c" +#include "../common/transaction.c" +#include "../common/error.c" +#include "../common/open.c" +#include "../common/check.c" +#include "../common/hash.c" +#include "../common/mutex.c" +#include "tap-interface.h" +#include +#include "logging.h" + +int main(int argc, char *argv[]) +{ + struct tdb_context *tdb; + TDB_DATA key, data; + + plan_tests(10); + tdb = tdb_open_ex("run.tdb", 1024, TDB_CLEAR_IF_FIRST, + O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); + + ok1(tdb); + key.dsize = strlen("hi"); + key.dptr = discard_const_p(uint8_t, "hi"); + data.dsize = strlen("world"); + data.dptr = discard_const_p(uint8_t, "world"); + + ok1(tdb_store(tdb, key, data, TDB_MODIFY) < 0); + ok1(tdb_error(tdb) == TDB_ERR_NOEXIST); + ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); + ok1(tdb_store(tdb, key, data, TDB_INSERT) < 0); + ok1(tdb_error(tdb) == TDB_ERR_EXISTS); + ok1(tdb_store(tdb, key, data, TDB_MODIFY) == 0); + + data = tdb_fetch(tdb, key); + ok1(data.dsize == strlen("world")); + ok1(memcmp(data.dptr, "world", strlen("world")) == 0); + free(data.dptr); + + key.dsize++; + data = tdb_fetch(tdb, key); + ok1(data.dptr == NULL); + tdb_close(tdb); + + return exit_status(); +} diff --git a/ldb-2.0.8/lib/tdb/test/rwlock-be.tdb b/ldb-2.0.8/lib/tdb/test/rwlock-be.tdb new file mode 100644 index 0000000000000000000000000000000000000000..45b5f09a1b619b4f79201057dd811781d4151d33 GIT binary patch literal 696 ncmWG>aZ*Uj%t_^9zz%XH8P%GBQt3za#j&dx6&(!$`iB4j>yiaW literal 0 HcmV?d00001 diff --git a/ldb-2.0.8/lib/tdb/test/rwlock-le.tdb b/ldb-2.0.8/lib/tdb/test/rwlock-le.tdb new file mode 100644 index 0000000000000000000000000000000000000000..45b5f09a1b619b4f79201057dd811781d4151d33 GIT binary patch literal 696 ncmWG>aZ*Uj%t_^9zz%XH8P%GBQt3za#j&dx6&(!$`iB4j>yiaW literal 0 HcmV?d00001 diff --git a/ldb-2.0.8/lib/tdb/test/sample_tdb.tdb b/ldb-2.0.8/lib/tdb/test/sample_tdb.tdb new file mode 100644 index 0000000000000000000000000000000000000000..a40e50c4f9a1984b7d7ddcf7914e829c53484025 GIT binary patch literal 8192 zcmeI1&1(}u7{;f9@w?WG+WHBic+u|H?9PZtC>1<-Q1MX3Dx2L62_~D6jVZ-~1$!4n zpO6@qLq>HcKZ>t*!Jh18?5hncZif{q4*Ib}kMM z9L(km!Db>a#on$Xx1sBN-^>4zr(sze~2LBSk9KoL*`6ahs*5l{pa0YyL&Py`eK zMPO+J#&$N(`vM6!L=HiOmnNnjz&=T(>|Kk3N-d}m?ij}n-Eu5u+LqI=Ym7RYZR)1O zY=={m8;w(ROPaRtRL^J|3p{{k`D3 zWf=sz*n={utHeFU!5CCF!d}f3WaNJr0{P>;*EE0diKX87CB%Z<4Y3>IYw1@C$4^+Q z=Ch;6d^aeTLc+PxZ<~xm7$$|G#7&!W7GIC)Y+T2-?GU{X>)#)Kjano5Fq04c`Bwph z&|rp5EyK~N#vR6)r8%)eGo6F=_Pxai2 zP}gfa@#M<^Tsl{NfNl=xqcmjU_sZywI{F. +*/ +#include + +#ifndef __location__ +#define __TAP_STRING_LINE1__(s) #s +#define __TAP_STRING_LINE2__(s) __TAP_STRING_LINE1__(s) +#define __TAP_STRING_LINE3__ __TAP_STRING_LINE2__(__LINE__) +#define __location__ __FILE__ ":" __TAP_STRING_LINE3__ +#endif + +#define plan_tests(num) +#define fail(...) do { \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, "\n"); \ + fflush(stderr); \ + exit(1); \ +} while(0) +#define diag(...) do { \ + fprintf(stdout, __VA_ARGS__); \ + fprintf(stdout, "\n"); \ + fflush(stdout); \ +} while(0) +#define pass(...) do { \ + fprintf(stdout, "."); \ + fflush(stdout); \ +} while(0) +#define ok(e, ...) do { \ + if (e) { \ + pass(); \ + } else { \ + fail(__VA_ARGS__); \ + } \ +} while(0) +#define ok1(e) ok((e), "%s:%s", __location__, #e) +#define skip(n, ...) diag(__VA_ARGS__) +#define exit_status() 0 diff --git a/ldb-2.0.8/lib/tdb/test/tap-to-subunit.h b/ldb-2.0.8/lib/tdb/test/tap-to-subunit.h new file mode 100644 index 0000000..a5cf74f --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/tap-to-subunit.h @@ -0,0 +1,155 @@ +#ifndef TAP_TO_SUBUNIT_H +#define TAP_TO_SUBUNIT_H +/* + * tap-style wrapper for subunit. + * + * Copyright (c) 2011 Rusty Russell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "replace.h" + +/** + * plan_tests - announce the number of tests you plan to run + * @tests: the number of tests + * + * This should be the first call in your test program: it allows tracing + * of failures which mean that not all tests are run. + * + * If you don't know how many tests will actually be run, assume all of them + * and use skip() if you don't actually run some tests. + * + * Example: + * plan_tests(13); + */ +void plan_tests(unsigned int tests); + +/** + * ok1 - Simple conditional test + * @e: the expression which we expect to be true. + * + * This is the simplest kind of test: if the expression is true, the + * test passes. The name of the test which is printed will simply be + * file name, line number, and the expression itself. + * + * Example: + * ok1(somefunc() == 1); + */ +# define ok1(e) ((e) ? \ + _gen_result(1, __func__, __FILE__, __LINE__, "%s", #e) : \ + _gen_result(0, __func__, __FILE__, __LINE__, "%s", #e)) + +/** + * ok - Conditional test with a name + * @e: the expression which we expect to be true. + * @...: the printf-style name of the test. + * + * If the expression is true, the test passes. The name of the test will be + * the filename, line number, and the printf-style string. This can be clearer + * than simply the expression itself. + * + * Example: + * ok1(somefunc() == 1); + * ok(somefunc() == 0, "Second somefunc() should fail"); + */ +# define ok(e, ...) ((e) ? \ + _gen_result(1, __func__, __FILE__, __LINE__, \ + __VA_ARGS__) : \ + _gen_result(0, __func__, __FILE__, __LINE__, \ + __VA_ARGS__)) + +/** + * pass - Note that a test passed + * @...: the printf-style name of the test. + * + * For complicated code paths, it can be easiest to simply call pass() in one + * branch and fail() in another. + * + * Example: + * int x = somefunc(); + * if (x > 0) + * pass("somefunc() returned a valid value"); + * else + * fail("somefunc() returned an invalid value"); + */ +# define pass(...) ok(1, __VA_ARGS__) + +/** + * fail - Note that a test failed + * @...: the printf-style name of the test. + * + * For complicated code paths, it can be easiest to simply call pass() in one + * branch and fail() in another. + */ +# define fail(...) ok(0, __VA_ARGS__) + +unsigned int _gen_result(int, const char *, const char *, unsigned int, + const char *, ...) PRINTF_ATTRIBUTE(5, 6); + +/** + * diag - print a diagnostic message (use instead of printf/fprintf) + * @fmt: the format of the printf-style message + * + * diag ensures that the output will not be considered to be a test + * result by the TAP test harness. It will append '\n' for you. + * + * Example: + * diag("Now running complex tests"); + */ +void diag(const char *fmt, ...) PRINTF_ATTRIBUTE(1, 2); + +/** + * skip - print a diagnostic message (use instead of printf/fprintf) + * @n: number of tests you're skipping. + * @fmt: the format of the reason you're skipping the tests. + * + * Sometimes tests cannot be run because the test system lacks some feature: + * you should explicitly document that you're skipping tests using skip(). + * + * From the Test::More documentation: + * If it's something the user might not be able to do, use SKIP. This + * includes optional modules that aren't installed, running under an OS that + * doesn't have some feature (like fork() or symlinks), or maybe you need an + * Internet connection and one isn't available. + * + * Example: + * #ifdef HAVE_SOME_FEATURE + * ok1(somefunc()); + * #else + * skip(1, "Don't have SOME_FEATURE"); + * #endif + */ +void skip(unsigned int n, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); + +/** + * exit_status - the value that main should return. + * + * For maximum compatibility your test program should return a particular exit + * code (ie. 0 if all tests were run, and every test which was expected to + * succeed succeeded). + * + * Example: + * exit(exit_status()); + */ +int exit_status(void); +#endif /* CCAN_TAP_H */ diff --git a/ldb-2.0.8/lib/tdb/test/tdb.corrupt b/ldb-2.0.8/lib/tdb/test/tdb.corrupt new file mode 100644 index 0000000000000000000000000000000000000000..83d6677454300a5173f80dcbcfec15fc636aed24 GIT binary patch literal 192512 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
    1. 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%0D;B{e9TTu0g|3*k?HPjWZaHd%ZIR!~gXDzVJoq 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 OTV%~k$Hy(v-~S&FX3gOM literal 0 HcmV?d00001 diff --git a/ldb-2.0.8/lib/tdb/test/test_tdbbackup.sh b/ldb-2.0.8/lib/tdb/test/test_tdbbackup.sh new file mode 100755 index 0000000..cf87921 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/test/test_tdbbackup.sh @@ -0,0 +1,54 @@ +#!/bin/sh +# Blackbox test for tdbbackup of given ldb or tdb database +# Copyright (C) 2018 Andrew Bartlett + +if [ $# -lt 1 ]; then + echo "Usage: $0 LDBFILE" + exit 1; +fi + +LDBFILE=$1 + +timestamp() { + date -u +'time: %Y-%m-%d %H:%M:%S.%6NZ' | sed 's/\..*NZ$/.000000Z/' +} + +subunit_fail_test () { + timestamp + printf 'failure: %s [\n' "$1" + cat - + echo "]" +} + +testit () { + name="$1" + shift + cmdline="$@" + timestamp + printf 'test: %s\n' "$1" + output=`$cmdline 2>&1` + status=$? + if [ x$status = x0 ]; then + timestamp + printf 'success: %s\n' "$name" + else + echo "$output" | subunit_fail_test "$name" + fi + return $status +} + +$BINDIR/tdbdump $LDBFILE | sort > orig_dump + +testit "normal tdbbackup on tdb file" $BINDIR/tdbbackup $LDBFILE -s .bak +$BINDIR/tdbdump $LDBFILE.bak | sort > bak_dump +testit "cmp between tdbdumps of original and backup" cmp orig_dump bak_dump +rm $LDBFILE.bak +rm bak_dump + +testit "readonly tdbbackup on tdb file" $BINDIR/tdbbackup $LDBFILE -s .bak -r +$BINDIR/tdbdump $LDBFILE.bak | sort > bak_dump +testit "cmp between tdbdumps of original and back dbs" cmp orig_dump bak_dump +rm $LDBFILE.bak +rm bak_dump + +rm orig_dump diff --git a/ldb-2.0.8/lib/tdb/tools/tdbbackup.c b/ldb-2.0.8/lib/tdb/tools/tdbbackup.c new file mode 100644 index 0000000..1125987 --- /dev/null +++ b/ldb-2.0.8/lib/tdb/tools/tdbbackup.c @@ -0,0 +1,370 @@ +/* + Unix SMB/CIFS implementation. + low level tdb backup and restore utility + Copyright (C) Andrew Tridgell 2002 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* + + This program is meant for backup/restore of tdb databases. Typical usage would be: + tdbbackup *.tdb + when Samba shuts down cleanly, which will make a backup of all the local databases + to *.bak files. Then on Samba startup you would use: + tdbbackup -v *.tdb + and this will check the databases for corruption and if corruption is detected then + the backup will be restored. + + You may also like to do a backup on a regular basis while Samba is + running, perhaps using cron. + + The reason this program is needed is to cope with power failures + while Samba is running. A power failure could lead to database + corruption and Samba will then not start correctly. + + Note that many of the databases in Samba are transient and thus + don't need to be backed up, so you can optimise the above a little + by only running the backup on the critical databases. + + */ + +#include "replace.h" +#include "system/locale.h" +#include "system/time.h" +#include "system/filesys.h" +#include "system/wait.h" +#include "tdb.h" + +#ifdef HAVE_GETOPT_H +#include +#endif + +static int failed; + +static struct tdb_logging_context log_ctx; + +#ifdef PRINTF_ATTRIBUTE +static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); +#endif +static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + vfprintf(stdout, format, ap); + va_end(ap); + fflush(stdout); +} + +static char *add_suffix(const char *name, const char *suffix) +{ + char *ret; + int len = strlen(name) + strlen(suffix) + 1; + ret = (char *)malloc(len); + if (!ret) { + fprintf(stderr,"Out of memory!\n"); + exit(1); + } + snprintf(ret, len, "%s%s", name, suffix); + return ret; +} + +static int copy_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + TDB_CONTEXT *tdb_new = (TDB_CONTEXT *)state; + + if (tdb_store(tdb_new, key, dbuf, TDB_INSERT) != 0) { + fprintf(stderr,"Failed to insert into %s\n", tdb_name(tdb_new)); + failed = 1; + return 1; + } + return 0; +} + + +static int test_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + return 0; +} + +/* + carefully backup a tdb, validating the contents and + only doing the backup if its OK + this function is also used for restore +*/ +static int backup_tdb(const char *old_name, const char *new_name, + int hash_size, int nolock, bool readonly) +{ + TDB_CONTEXT *tdb; + TDB_CONTEXT *tdb_new; + char *tmp_name; + struct stat st; + int count1, count2; + + tmp_name = add_suffix(new_name, ".tmp"); + + /* stat the old tdb to find its permissions */ + if (stat(old_name, &st) != 0) { + perror(old_name); + free(tmp_name); + return 1; + } + + /* open the old tdb */ + tdb = tdb_open_ex(old_name, 0, + TDB_DEFAULT | (nolock ? TDB_NOLOCK : 0), + O_RDWR, 0, &log_ctx, NULL); + if (!tdb) { + printf("Failed to open %s\n", old_name); + free(tmp_name); + return 1; + } + + /* create the new tdb */ + unlink(tmp_name); + tdb_new = tdb_open_ex(tmp_name, + hash_size ? hash_size : tdb_hash_size(tdb), + TDB_DEFAULT, + O_RDWR|O_CREAT|O_EXCL, st.st_mode & 0777, + &log_ctx, NULL); + if (!tdb_new) { + perror(tmp_name); + free(tmp_name); + return 1; + } + + if (readonly) { + if (tdb_lockall_read(tdb) != 0) { + printf("Failed to obtain read only lock on old tdb\n"); + tdb_close(tdb); + tdb_close(tdb_new); + unlink(tmp_name); + free(tmp_name); + return 1; + } + } else if (tdb_transaction_start(tdb) != 0) { + printf("Failed to start transaction on db\n"); + tdb_close(tdb); + tdb_close(tdb_new); + unlink(tmp_name); + free(tmp_name); + return 1; + } + + /* lock the backup tdb so that nobody else can change it */ + if (tdb_lockall(tdb_new) != 0) { + printf("Failed to lock backup tdb\n"); + tdb_close(tdb); + tdb_close(tdb_new); + unlink(tmp_name); + free(tmp_name); + return 1; + } + + failed = 0; + + /* traverse and copy */ + if (readonly) { + count1 = tdb_traverse_read(tdb, + copy_fn, + (void *)tdb_new); + } else { + count1 = tdb_traverse(tdb, + copy_fn, + (void *)tdb_new); + } + if (count1 < 0 || failed) { + fprintf(stderr,"failed to copy %s\n", old_name); + tdb_close(tdb); + tdb_close(tdb_new); + unlink(tmp_name); + free(tmp_name); + return 1; + } + + /* close the old tdb */ + tdb_close(tdb); + + /* copy done, unlock the backup tdb */ + tdb_unlockall(tdb_new); + +#ifdef HAVE_FDATASYNC + if (fdatasync(tdb_fd(tdb_new)) != 0) { +#else + if (fsync(tdb_fd(tdb_new)) != 0) { +#endif + /* not fatal */ + fprintf(stderr, "failed to fsync backup file\n"); + } + + /* close the new tdb and re-open read-only */ + tdb_close(tdb_new); + tdb_new = tdb_open_ex(tmp_name, + 0, + TDB_DEFAULT, + O_RDONLY, 0, + &log_ctx, NULL); + if (!tdb_new) { + fprintf(stderr,"failed to reopen %s\n", tmp_name); + unlink(tmp_name); + perror(tmp_name); + free(tmp_name); + return 1; + } + + /* traverse the new tdb to confirm */ + count2 = tdb_traverse(tdb_new, test_fn, NULL); + if (count2 != count1) { + fprintf(stderr,"failed to copy %s\n", old_name); + tdb_close(tdb_new); + unlink(tmp_name); + free(tmp_name); + return 1; + } + + /* close the new tdb and rename it to .bak */ + tdb_close(tdb_new); + if (rename(tmp_name, new_name) != 0) { + perror(new_name); + free(tmp_name); + return 1; + } + + free(tmp_name); + + return 0; +} + +/* + verify a tdb and if it is corrupt then restore from *.bak +*/ +static int verify_tdb(const char *fname, const char *bak_name) +{ + TDB_CONTEXT *tdb; + int count = -1; + + /* open the tdb */ + tdb = tdb_open_ex(fname, 0, 0, + O_RDONLY, 0, &log_ctx, NULL); + + /* traverse the tdb, then close it */ + if (tdb) { + count = tdb_traverse(tdb, test_fn, NULL); + tdb_close(tdb); + } + + /* count is < 0 means an error */ + if (count < 0) { + printf("restoring %s\n", fname); + return backup_tdb(bak_name, fname, 0, 0, 0); + } + + printf("%s : %d records\n", fname, count); + + return 0; +} + +/* + see if one file is newer than another +*/ +static int file_newer(const char *fname1, const char *fname2) +{ + struct stat st1, st2; + if (stat(fname1, &st1) != 0) { + return 0; + } + if (stat(fname2, &st2) != 0) { + return 1; + } + return (st1.st_mtime > st2.st_mtime); +} + +static void usage(void) +{ + printf("Usage: tdbbackup [options] \n\n"); + printf(" -h this help message\n"); + printf(" -s suffix set the backup suffix\n"); + printf(" -v verify mode (restore if corrupt)\n"); + printf(" -n hashsize set the new hash size for the backup\n"); + printf(" -l open without locking to back up mutex dbs\n"); + printf(" -r open with read only locking\n"); +} + + int main(int argc, char *argv[]) +{ + int i; + int ret = 0; + int c; + int verify = 0; + int hashsize = 0; + int nolock = 0; + bool readonly = false; + const char *suffix = ".bak"; + + log_ctx.log_fn = tdb_log; + + while ((c = getopt(argc, argv, "vhs:n:lr")) != -1) { + switch (c) { + case 'h': + usage(); + exit(0); + case 'v': + verify = 1; + break; + case 's': + suffix = optarg; + break; + case 'n': + hashsize = atoi(optarg); + break; + case 'l': + nolock = 1; + break; + case 'r': + readonly = true; + } + } + + argc -= optind; + argv += optind; + + if (argc < 1) { + usage(); + exit(1); + } + + for (i=0; i. +*/ + +#include "replace.h" +#include "system/locale.h" +#include "system/time.h" +#include "system/filesys.h" +#include "system/wait.h" +#include "tdb.h" + +static void print_data(TDB_DATA d) +{ + unsigned char *p = (unsigned char *)d.dptr; + int len = d.dsize; + while (len--) { + if (isprint(*p) && !strchr("\"\\", *p)) { + fputc(*p, stdout); + } else { + printf("\\%02X", *p); + } + p++; + } +} + +static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + printf("{\n"); + printf("key(%zu) = \"", key.dsize); + print_data(key); + printf("\"\n"); + printf("data(%zu) = \"", dbuf.dsize); + print_data(dbuf); + printf("\"\n"); + printf("}\n"); + return 0; +} + +static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level, + const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); + +static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level, + const char *fmt, ...) +{ + va_list ap; + const char *name = tdb_name(tdb); + const char *prefix = ""; + + if (!name) + name = "unnamed"; + + switch (level) { + case TDB_DEBUG_ERROR: + prefix = "ERROR: "; + break; + case TDB_DEBUG_WARNING: + prefix = "WARNING: "; + break; + case TDB_DEBUG_TRACE: + return; + + default: + case TDB_DEBUG_FATAL: + prefix = "FATAL: "; + break; + } + + va_start(ap, fmt); + fprintf(stderr, "tdb(%s): %s", name, prefix); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + +static void emergency_walk(TDB_DATA key, TDB_DATA dbuf, void *keyname) +{ + if (keyname) { + if (key.dsize != strlen(keyname)) + return; + if (memcmp(key.dptr, keyname, key.dsize) != 0) + return; + } + traverse_fn(NULL, key, dbuf, NULL); +} + +static int dump_tdb(const char *fname, const char *keyname, bool emergency) +{ + TDB_CONTEXT *tdb; + TDB_DATA key, value; + struct tdb_logging_context logfn = { + .log_fn = log_stderr, + }; + int tdb_flags = TDB_DEFAULT; + + /* + * Note: that O_RDONLY implies TDB_NOLOCK, but we want to make it + * explicit as it's important when working on databases which were + * created with mutex locking. + */ + tdb_flags |= TDB_NOLOCK; + + tdb = tdb_open_ex(fname, 0, tdb_flags, O_RDONLY, 0, &logfn, NULL); + if (!tdb) { + printf("Failed to open %s\n", fname); + return 1; + } + + if (emergency) { + return tdb_rescue(tdb, emergency_walk, discard_const(keyname)) == 0; + } + if (!keyname) { + return tdb_traverse(tdb, traverse_fn, NULL) == -1 ? 1 : 0; + } else { + key.dptr = discard_const_p(uint8_t, keyname); + key.dsize = strlen(keyname); + value = tdb_fetch(tdb, key); + if (!value.dptr) { + return 1; + } else { + print_data(value); + free(value.dptr); + } + } + + return 0; +} + +static void usage( void) +{ + printf( "Usage: tdbdump [options] \n\n"); + printf( " -h this help message\n"); + printf( " -k keyname dumps value of keyname\n"); + printf( " -e emergency dump, for corrupt databases\n"); +} + + int main(int argc, char *argv[]) +{ + char *fname, *keyname=NULL; + bool emergency = false; + int c; + + if (argc < 2) { + printf("Usage: tdbdump \n"); + exit(1); + } + + while ((c = getopt( argc, argv, "hk:e")) != -1) { + switch (c) { + case 'h': + usage(); + exit( 0); + case 'k': + keyname = optarg; + break; + case 'e': + emergency = true; + break; + default: + usage(); + exit( 1); + } + } + + fname = argv[optind]; + + return dump_tdb(fname, keyname, emergency); +} diff --git a/ldb-2.0.8/lib/tdb/tools/tdbrestore.c b/ldb-2.0.8/lib/tdb/tools/tdbrestore.c new file mode 100644 index 0000000..81c986c --- /dev/null +++ b/ldb-2.0.8/lib/tdb/tools/tdbrestore.c @@ -0,0 +1,222 @@ +/* + tdbrestore -- construct a tdb from tdbdump output. + Copyright (C) Volker Lendecke 2010 + Copyright (C) Simon McVittie 2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "replace.h" +#include +#include "system/locale.h" +#include "system/time.h" +#include "system/filesys.h" +#include "system/wait.h" +#include "tdb.h" + +static int read_linehead(FILE *f) +{ + int i, c; + int num_bytes; + char prefix[128]; + + while (1) { + c = getc(f); + if (c == EOF) { + return -1; + } + if (c == '(') { + break; + } + } + for (i=0; idptr = (unsigned char *)malloc(size); + if (d->dptr == NULL) { + return -1; + } + d->dsize = size; + + for (i=0; idptr[i] = (low|high); + } else { + d->dptr[i] = c; + } + } + return 0; +} + +static int swallow(FILE *f, const char *s, int *eof) +{ + char line[128]; + + if (fgets(line, sizeof(line), f) == NULL) { + if (eof != NULL) { + *eof = 1; + } + return -1; + } + if (strcmp(line, s) != 0) { + return -1; + } + return 0; +} + +static int read_rec(FILE *f, TDB_CONTEXT *tdb, int *eof) +{ + int length; + TDB_DATA key, data; + int ret = -1; + + key.dptr = NULL; + data.dptr = NULL; + + if (swallow(f, "{\n", eof) == -1) { + goto fail; + } + length = read_linehead(f); + if (length == -1) { + goto fail; + } + if (read_data(f, &key, length) == -1) { + goto fail; + } + if (swallow(f, "\"\n", NULL) == -1) { + goto fail; + } + length = read_linehead(f); + if (length == -1) { + goto fail; + } + if (read_data(f, &data, length) == -1) { + goto fail; + } + if ((swallow(f, "\"\n", NULL) == -1) + || (swallow(f, "}\n", NULL) == -1)) { + goto fail; + } + if (tdb_store(tdb, key, data, TDB_INSERT) != 0) { + fprintf(stderr, "TDB error: %s\n", tdb_errorstr(tdb)); + goto fail; + } + + ret = 0; +fail: + free(key.dptr); + free(data.dptr); + return ret; +} + +static int restore_tdb(const char *fname) +{ + TDB_CONTEXT *tdb; + + tdb = tdb_open(fname, 0, 0, O_RDWR|O_CREAT|O_EXCL, 0666); + if (!tdb) { + perror("tdb_open"); + fprintf(stderr, "Failed to open %s\n", fname); + return 1; + } + + while (1) { + int eof = 0; + if (read_rec(stdin, tdb, &eof) == -1) { + if (eof) { + break; + } + return 1; + } + } + if (tdb_close(tdb)) { + fprintf(stderr, "Error closing tdb\n"); + return 1; + } + return 0; +} + +int main(int argc, char *argv[]) +{ + char *fname; + + if (argc < 2) { + printf("Usage: %s dbname < tdbdump_output\n", argv[0]); + exit(1); + } + + fname = argv[1]; + + return restore_tdb(fname); +} diff --git a/ldb-2.0.8/lib/tdb/tools/tdbtest.c b/ldb-2.0.8/lib/tdb/tools/tdbtest.c new file mode 100644 index 0000000..0be35dc --- /dev/null +++ b/ldb-2.0.8/lib/tdb/tools/tdbtest.c @@ -0,0 +1,290 @@ +/* a test program for tdb - the trivial database */ + +#include "replace.h" +#include "tdb.h" +#include "system/filesys.h" +#include "system/time.h" + +#include + + +#define DELETE_PROB 7 +#define STORE_PROB 5 + +static struct tdb_context *db; +static GDBM_FILE gdbm; + +struct timeval tp1,tp2; + +static void _start_timer(void) +{ + gettimeofday(&tp1,NULL); +} + +static double _end_timer(void) +{ + gettimeofday(&tp2,NULL); + return((tp2.tv_sec - tp1.tv_sec) + + (tp2.tv_usec - tp1.tv_usec)*1.0e-6); +} + +static void fatal(const char *why) +{ + perror(why); + exit(1); +} + +#ifdef PRINTF_ATTRIBUTE +static void tdb_log(struct tdb_context *tdb, int level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); +#endif +static void tdb_log(struct tdb_context *tdb, int level, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + vfprintf(stdout, format, ap); + va_end(ap); + fflush(stdout); +} + +static void compare_db(void) +{ + TDB_DATA d, key, nextkey; + datum gd, gkey, gnextkey; + + key = tdb_firstkey(db); + while (key.dptr) { + d = tdb_fetch(db, key); + gkey.dptr = key.dptr; + gkey.dsize = key.dsize; + + gd = gdbm_fetch(gdbm, gkey); + + if (!gd.dptr) fatal("key not in gdbm"); + if (gd.dsize != d.dsize) fatal("data sizes differ"); + if (memcmp(gd.dptr, d.dptr, d.dsize)) { + fatal("data differs"); + } + + nextkey = tdb_nextkey(db, key); + free(key.dptr); + free(d.dptr); + free(gd.dptr); + key = nextkey; + } + + gkey = gdbm_firstkey(gdbm); + while (gkey.dptr) { + gd = gdbm_fetch(gdbm, gkey); + key.dptr = gkey.dptr; + key.dsize = gkey.dsize; + + d = tdb_fetch(db, key); + + if (!d.dptr) fatal("key not in db"); + if (d.dsize != gd.dsize) fatal("data sizes differ"); + if (memcmp(d.dptr, gd.dptr, gd.dsize)) { + fatal("data differs"); + } + + gnextkey = gdbm_nextkey(gdbm, gkey); + free(gkey.dptr); + free(gd.dptr); + free(d.dptr); + gkey = gnextkey; + } +} + +static char *randbuf(int len) +{ + char *buf; + int i; + buf = (char *)malloc(len+1); + + for (i=0;i. +*/ + +#include "replace.h" +#include "system/locale.h" +#include "system/time.h" +#include "system/filesys.h" +#include "system/wait.h" +#include "tdb.h" + +static int do_command(void); +const char *cmdname; +char *arg1, *arg2; +size_t arg1len, arg2len; +int bIterate = 0; +char *line; +TDB_DATA iterate_kbuf; +char cmdline[1024]; +static int disable_mmap; +static int _disable_lock; + +enum commands { + CMD_CREATE_TDB, + CMD_OPEN_TDB, + CMD_TRANSACTION_START, + CMD_TRANSACTION_COMMIT, + CMD_TRANSACTION_CANCEL, + CMD_ERASE, + CMD_DUMP, + CMD_INSERT, + CMD_MOVE, + CMD_STOREHEX, + CMD_STORE, + CMD_SHOW, + CMD_KEYS, + CMD_HEXKEYS, + CMD_DELETE, + CMD_LIST_HASH_FREE, + CMD_LIST_FREE, + CMD_FREELIST_SIZE, + CMD_INFO, + CMD_MMAP, + CMD_SPEED, + CMD_FIRST, + CMD_NEXT, + CMD_SYSTEM, + CMD_CHECK, + CMD_REPACK, + CMD_QUIT, + CMD_HELP +}; + +typedef struct { + const char *name; + enum commands cmd; +} COMMAND_TABLE; + +COMMAND_TABLE cmd_table[] = { + {"create", CMD_CREATE_TDB}, + {"open", CMD_OPEN_TDB}, + {"transaction_start", CMD_TRANSACTION_START}, + {"transaction_commit", CMD_TRANSACTION_COMMIT}, + {"transaction_cancel", CMD_TRANSACTION_CANCEL}, + {"erase", CMD_ERASE}, + {"dump", CMD_DUMP}, + {"insert", CMD_INSERT}, + {"move", CMD_MOVE}, + {"storehex", CMD_STOREHEX}, + {"store", CMD_STORE}, + {"show", CMD_SHOW}, + {"keys", CMD_KEYS}, + {"hexkeys", CMD_HEXKEYS}, + {"delete", CMD_DELETE}, + {"list", CMD_LIST_HASH_FREE}, + {"free", CMD_LIST_FREE}, + {"freelist_size", CMD_FREELIST_SIZE}, + {"info", CMD_INFO}, + {"speed", CMD_SPEED}, + {"mmap", CMD_MMAP}, + {"first", CMD_FIRST}, + {"1", CMD_FIRST}, + {"next", CMD_NEXT}, + {"n", CMD_NEXT}, + {"check", CMD_CHECK}, + {"quit", CMD_QUIT}, + {"q", CMD_QUIT}, + {"!", CMD_SYSTEM}, + {"repack", CMD_REPACK}, + {NULL, CMD_HELP} +}; + +struct timeval tp1,tp2; + +static void _start_timer(void) +{ + gettimeofday(&tp1,NULL); +} + +static double _end_timer(void) +{ + gettimeofday(&tp2,NULL); + return((tp2.tv_sec - tp1.tv_sec) + + (tp2.tv_usec - tp1.tv_usec)*1.0e-6); +} + +#ifdef PRINTF_ATTRIBUTE +static void tdb_log_open(struct tdb_context *tdb, enum tdb_debug_level level, + const char *format, ...) PRINTF_ATTRIBUTE(3,4); +#endif +static void tdb_log_open(struct tdb_context *tdb, enum tdb_debug_level level, + const char *format, ...) +{ + const char *mutex_msg = + "Can use mutexes only with MUTEX_LOCKING or NOLOCK\n"; + char *p; + va_list ap; + + p = strstr(format, mutex_msg); + if (p != NULL) { + /* + * Yes, this is a hack, but we don't want to see this + * message on first open, but we want to see + * everything else. + */ + return; + } + + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); +} + +#ifdef PRINTF_ATTRIBUTE +static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); +#endif +static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); +} + +/* a tdb tool for manipulating a tdb database */ + +static TDB_CONTEXT *tdb; + +static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); +static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); +static int print_hexkey(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); + +static void print_asc(const char *buf,int len) +{ + int i; + + /* We're probably printing ASCII strings so don't try to display + the trailing NULL character. */ + + if (buf[len - 1] == 0) + len--; + + for (i=0;i8) printf(" "); + while (n--) printf(" "); + + n = i%16; + if (n > 8) n = 8; + print_asc(&buf[i-(i%16)],n); printf(" "); + n = (i%16) - n; + if (n>0) print_asc(&buf[i-n],n); + printf("\n"); + } +} + +static void help(void) +{ + printf("\n" +"tdbtool: \n" +" create dbname : create a database\n" +" open dbname : open an existing database\n" +" transaction_start : start a transaction\n" +" transaction_commit : commit a transaction\n" +" transaction_cancel : cancel a transaction\n" +" erase : erase the database\n" +" dump : dump the database as strings\n" +" keys : dump the database keys as strings\n" +" hexkeys : dump the database keys as hex values\n" +" info : print summary info about the database\n" +" insert key data : insert a record\n" +" move key file : move a record to a destination tdb\n" +" storehex key data : store a record (replace), key/value in hex format\n" +" store key data : store a record (replace)\n" +" show key : show a record by key\n" +" delete key : delete a record by key\n" +" list : print the database hash table and freelist\n" +" free : print the database freelist\n" +" freelist_size : print the number of records in the freelist\n" +" check : check the integrity of an opened database\n" +" repack : repack the database\n" +" speed : perform speed tests on the database\n" +" ! command : execute system command\n" +" 1 | first : print the first record\n" +" n | next : print the next record\n" +" q | quit : terminate\n" +" \\n : repeat 'next' command\n" +"\n"); +} + +static void terror(const char *why) +{ + printf("%s\n", why); +} + +static void create_tdb(const char *tdbname) +{ + struct tdb_logging_context log_ctx = { NULL, NULL}; + log_ctx.log_fn = tdb_log; + + if (tdb) tdb_close(tdb); + tdb = tdb_open_ex(tdbname, 0, + TDB_CLEAR_IF_FIRST | + (disable_mmap?TDB_NOMMAP:0) | + (_disable_lock?TDB_NOLOCK:0), + O_RDWR | O_CREAT | O_TRUNC, 0600, &log_ctx, NULL); + if (!tdb) { + printf("Could not create %s: %s\n", tdbname, strerror(errno)); + } +} + +static void open_tdb(const char *tdbname) +{ + struct tdb_logging_context log_ctx = { NULL, NULL }; + log_ctx.log_fn = tdb_log_open; + + if (tdb) tdb_close(tdb); + tdb = tdb_open_ex(tdbname, 0, + (disable_mmap?TDB_NOMMAP:0) | + (_disable_lock?TDB_NOLOCK:0), + O_RDWR, 0600, + &log_ctx, NULL); + + log_ctx.log_fn = tdb_log; + if (tdb != NULL) { + tdb_set_logging_function(tdb, &log_ctx); + } + + if ((tdb == NULL) && (errno == EINVAL)) { + /* + * Retry NOLOCK and readonly. There we want to see all + * error messages. + */ + tdb = tdb_open_ex(tdbname, 0, + (disable_mmap?TDB_NOMMAP:0) |TDB_NOLOCK, + O_RDONLY, 0600, + &log_ctx, NULL); + } + + if (!tdb) { + printf("Could not open %s: %s\n", tdbname, strerror(errno)); + } +} + +static void insert_tdb(char *keyname, size_t keylen, char* data, size_t datalen) +{ + TDB_DATA key, dbuf; + + if ((keyname == NULL) || (keylen == 0)) { + terror("need key"); + return; + } + + key.dptr = (unsigned char *)keyname; + key.dsize = keylen; + dbuf.dptr = (unsigned char *)data; + dbuf.dsize = datalen; + + if (tdb_store(tdb, key, dbuf, TDB_INSERT) != 0) { + terror("insert failed"); + } +} + +static void store_tdb(char *keyname, size_t keylen, char* data, size_t datalen) +{ + TDB_DATA key, dbuf; + + if ((keyname == NULL) || (keylen == 0)) { + terror("need key"); + return; + } + + if ((data == NULL) || (datalen == 0)) { + terror("need data"); + return; + } + + key.dptr = (unsigned char *)keyname; + key.dsize = keylen; + dbuf.dptr = (unsigned char *)data; + dbuf.dsize = datalen; + + printf("Storing key:\n"); + print_rec(tdb, key, dbuf, NULL); + + if (tdb_store(tdb, key, dbuf, TDB_REPLACE) != 0) { + terror("store failed"); + } +} + +static bool hexchar(char c, uint8_t *v) +{ + if ((c >= '0') && (c <= '9')) { + *v = (c - '0'); + return true; + } + if ((c >= 'A') && (c <= 'F')) { + *v = (c - 'A' + 10); + return true; + } + if ((c >= 'a') && (c <= 'f')) { + *v = (c - 'a' + 10); + return true; + } + return false; +} + +static bool parse_hex(const char *src, size_t srclen, uint8_t *dst) +{ + size_t i=0; + + if ((srclen % 2) != 0) { + return false; + } + + while (iname) { + cmd_len = strlen(ctp->name); + if (strncmp(ctp->name,cmdname,cmd_len) == 0) { + mycmd = ctp->cmd; + break; + } + ctp++; + } + } + } + + switch (mycmd) { + case CMD_CREATE_TDB: + bIterate = 0; + create_tdb(arg1); + return 0; + case CMD_OPEN_TDB: + bIterate = 0; + open_tdb(arg1); + return 0; + case CMD_SYSTEM: + /* Shell command */ + if (system(arg1) == -1) { + terror("system() call failed\n"); + } + return 0; + case CMD_QUIT: + return 1; + default: + /* all the rest require a open database */ + if (!tdb) { + bIterate = 0; + terror("database not open"); + help(); + return 0; + } + switch (mycmd) { + case CMD_TRANSACTION_START: + bIterate = 0; + tdb_transaction_start(tdb); + return 0; + case CMD_TRANSACTION_COMMIT: + bIterate = 0; + tdb_transaction_commit(tdb); + return 0; + case CMD_REPACK: + bIterate = 0; + tdb_repack(tdb); + return 0; + case CMD_TRANSACTION_CANCEL: + bIterate = 0; + tdb_transaction_cancel(tdb); + return 0; + case CMD_ERASE: + bIterate = 0; + tdb_wipe_all(tdb); + return 0; + case CMD_DUMP: + bIterate = 0; + tdb_traverse(tdb, print_rec, NULL); + return 0; + case CMD_INSERT: + bIterate = 0; + insert_tdb(arg1, arg1len,arg2,arg2len); + return 0; + case CMD_MOVE: + bIterate = 0; + move_rec(arg1,arg1len,arg2); + return 0; + case CMD_STORE: + bIterate = 0; + store_tdb(arg1,arg1len,arg2,arg2len); + return 0; + case CMD_STOREHEX: + bIterate = 0; + store_hex_tdb(arg1,arg1len,arg2,arg2len); + return 0; + case CMD_SHOW: + bIterate = 0; + show_tdb(arg1, arg1len); + return 0; + case CMD_KEYS: + tdb_traverse(tdb, print_key, NULL); + return 0; + case CMD_HEXKEYS: + tdb_traverse(tdb, print_hexkey, NULL); + return 0; + case CMD_DELETE: + bIterate = 0; + delete_tdb(arg1,arg1len); + return 0; + case CMD_LIST_HASH_FREE: + tdb_dump_all(tdb); + return 0; + case CMD_LIST_FREE: + tdb_printfreelist(tdb); + return 0; + case CMD_FREELIST_SIZE: { + int size; + + size = tdb_freelist_size(tdb); + if (size < 0) { + printf("Error getting freelist size.\n"); + } else { + printf("freelist size: %d\n", size); + } + + return 0; + } + case CMD_INFO: + info_tdb(); + return 0; + case CMD_SPEED: + speed_tdb(arg1); + return 0; + case CMD_MMAP: + toggle_mmap(); + return 0; + case CMD_FIRST: + bIterate = 1; + first_record(tdb, &iterate_kbuf); + return 0; + case CMD_NEXT: + if (bIterate) + next_record(tdb, &iterate_kbuf); + return 0; + case CMD_CHECK: + check_db(tdb); + return 0; + case CMD_HELP: + help(); + return 0; + case CMD_CREATE_TDB: + case CMD_OPEN_TDB: + case CMD_SYSTEM: + case CMD_QUIT: + /* + * unhandled commands. cases included here to avoid compiler + * warnings. + */ + return 0; + } + } + + return 0; +} + +static char *tdb_convert_string(char *instring, size_t *sizep) +{ + size_t length = 0; + char *outp, *inp; + char temp[3]; + + outp = inp = instring; + + while (*inp) { + if (*inp == '\\') { + inp++; + if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) { + temp[0] = *inp++; + temp[1] = '\0'; + if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) { + temp[1] = *inp++; + temp[2] = '\0'; + } + *outp++ = (char)strtol((const char *)temp,NULL,16); + } else { + *outp++ = *inp++; + } + } else { + *outp++ = *inp++; + } + length++; + } + *sizep = length; + return instring; +} + +int main(int argc, char *argv[]) +{ + cmdname = ""; + arg1 = NULL; + arg1len = 0; + arg2 = NULL; + arg2len = 0; + + if (argv[1] && (strcmp(argv[1], "-l") == 0)) { + _disable_lock = 1; + argv[1] = argv[0]; + argv += 1; + argc -= 1; + } + + if (argv[1]) { + cmdname = "open"; + arg1 = argv[1]; + do_command(); + cmdname = ""; + arg1 = NULL; + } + + switch (argc) { + case 1: + case 2: + /* Interactive mode */ + while ((cmdname = tdb_getline("tdb> "))) { + arg2 = arg1 = NULL; + if ((arg1 = strchr((const char *)cmdname,' ')) != NULL) { + arg1++; + arg2 = arg1; + while (*arg2) { + if (*arg2 == ' ') { + *arg2++ = '\0'; + break; + } + if ((*arg2++ == '\\') && (*arg2 == ' ')) { + arg2++; + } + } + } + if (arg1) arg1 = tdb_convert_string(arg1,&arg1len); + if (arg2) arg2 = tdb_convert_string(arg2,&arg2len); + if (do_command()) break; + } + break; + case 5: + arg2 = tdb_convert_string(argv[4],&arg2len); + FALL_THROUGH; + case 4: + arg1 = tdb_convert_string(argv[3],&arg1len); + FALL_THROUGH; + case 3: + cmdname = argv[2]; + FALL_THROUGH; + default: + do_command(); + break; + } + + if (tdb) tdb_close(tdb); + + return 0; +} diff --git a/ldb-2.0.8/lib/tdb/tools/tdbtorture.c b/ldb-2.0.8/lib/tdb/tools/tdbtorture.c new file mode 100644 index 0000000..7d08d4f --- /dev/null +++ b/ldb-2.0.8/lib/tdb/tools/tdbtorture.c @@ -0,0 +1,501 @@ +/* this tests tdb by doing lots of ops from several simultaneous + writers - that stresses the locking code. +*/ + +#include "replace.h" +#include "system/time.h" +#include "system/wait.h" +#include "system/filesys.h" +#include "tdb.h" + +#ifdef HAVE_GETOPT_H +#include +#endif + + +#define REOPEN_PROB 30 +#define DELETE_PROB 8 +#define STORE_PROB 4 +#define APPEND_PROB 6 +#define TRANSACTION_PROB 10 +#define TRANSACTION_PREPARE_PROB 2 +#define LOCKSTORE_PROB 5 +#define TRAVERSE_PROB 20 +#define TRAVERSE_READ_PROB 20 +#define CULL_PROB 100 +#define KEYLEN 3 +#define DATALEN 100 + +static struct tdb_context *db; +static int in_transaction; +static int error_count; +static int always_transaction = 0; +static int hash_size = 2; +static unsigned loopnum; +static int count_pipe; +static bool mutex = false; +static struct tdb_logging_context log_ctx; + +#ifdef PRINTF_ATTRIBUTE +static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); +#endif +static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) +{ + va_list ap; + + /* trace level messages do not indicate an error */ + if (level != TDB_DEBUG_TRACE) { + error_count++; + } + + va_start(ap, format); + vfprintf(stdout, format, ap); + va_end(ap); + fflush(stdout); +#if 0 + if (level != TDB_DEBUG_TRACE) { + char *ptr; + signal(SIGUSR1, SIG_IGN); + asprintf(&ptr,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid()); + system(ptr); + free(ptr); + } +#endif +} + +static void fatal(const char *why) +{ + perror(why); + error_count++; +} + +static char *randbuf(int len) +{ + char *buf; + int i; + buf = (char *)malloc(len+1); + + for (i=0;i + + +ldb + + + +

      tdb

      + +TDB is a Trivial Database. In concept, it is very much like GDBM, and BSD's DB +except that it allows multiple simultaneous writers and uses locking +internally to keep writers from trampling on each other. TDB is also extremely +small. + +

      Download

      +You can download the latest releases of tdb from the
      tdb directory on the samba public +source archive. + + +

      Discussion and bug reports

      + +tdb does not currently have its own mailing list or bug tracking +system. For now, please use the samba-technical +mailing list, and the Samba +bugzilla bug tracking system. + +

      Download

      + +You can download the latest code either via git or rsync.
      +
      +To fetch via git see the following guide:
      +Using Git for Samba Development
      +Once you have cloned the tree switch to the master branch and cd into the source/lib/tdb directory.
      +
      +To fetch via rsync use these commands: + +
      +  rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/tdb .
      +  rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/replace .
      +
      + +and build in tdb. It will find the replace library in the directory +above automatically. + + + diff --git a/ldb-2.0.8/lib/tdb/wscript b/ldb-2.0.8/lib/tdb/wscript new file mode 100644 index 0000000..1ab0e8d --- /dev/null +++ b/ldb-2.0.8/lib/tdb/wscript @@ -0,0 +1,259 @@ +#!/usr/bin/env python + +APPNAME = 'tdb' +VERSION = '1.4.2' + +import sys, os + +# find the buildtools directory +top = '.' +while not os.path.exists(top+'/buildtools') and len(top.split('/')) < 5: + top = top + '/..' +sys.path.insert(0, top + '/buildtools/wafsamba') + +out = 'bin' + +import wafsamba +from wafsamba import samba_dist, samba_utils +from waflib import Options, Logs, Context +import shutil + +samba_dist.DIST_DIRS('lib/tdb:. lib/replace:lib/replace buildtools:buildtools third_party/waf:third_party/waf') + +tdb1_unit_tests = [ + 'run-3G-file', + 'run-bad-tdb-header', + 'run', + 'run-check', + 'run-corrupt', + 'run-die-during-transaction', + 'run-endian', + 'run-incompatible', + 'run-nested-transactions', + 'run-nested-traverse', + 'run-no-lock-during-traverse', + 'run-oldhash', + 'run-open-during-transaction', + 'run-readonly-check', + 'run-rescue', + 'run-rescue-find_entry', + 'run-rdlock-upgrade', + 'run-rwlock-check', + 'run-summary', + 'run-transaction-expand', + 'run-traverse-in-transaction', + 'run-wronghash-fail', + 'run-zero-append', + 'run-fcntl-deadlock', + 'run-marklock-deadlock', + 'run-allrecord-traverse-deadlock', + 'run-mutex-openflags2', + 'run-mutex-trylock', + 'run-mutex-allrecord-bench', + 'run-mutex-allrecord-trylock', + 'run-mutex-allrecord-block', + 'run-mutex-transaction1', + 'run-mutex-die', + 'run-mutex1', + 'run-circular-chain', + 'run-circular-freelist', + 'run-traverse-chain', +] + +def options(opt): + opt.BUILTIN_DEFAULT('replace') + opt.PRIVATE_EXTENSION_DEFAULT('tdb', noextension='tdb') + opt.RECURSE('lib/replace') + opt.add_option('--disable-tdb-mutex-locking', + help=("Disable the use of pthread robust mutexes"), + action="store_true", dest='disable_tdb_mutex_locking', + default=False) + + +def configure(conf): + conf.env.disable_tdb_mutex_locking = getattr(Options.options, + 'disable_tdb_mutex_locking', + False) + if not conf.env.disable_tdb_mutex_locking: + conf.env.replace_add_global_pthread = True + conf.RECURSE('lib/replace') + + conf.env.standalone_tdb = conf.IN_LAUNCH_DIR() + conf.env.building_tdb = True + + if not conf.env.standalone_tdb: + if conf.CHECK_BUNDLED_SYSTEM_PKG('tdb', minversion=VERSION, + implied_deps='replace'): + conf.define('USING_SYSTEM_TDB', 1) + conf.env.building_tdb = False + if not conf.env.disable_python and \ + conf.CHECK_BUNDLED_SYSTEM_PYTHON('pytdb', 'tdb', minversion=VERSION): + conf.define('USING_SYSTEM_PYTDB', 1) + + if (conf.CONFIG_SET('HAVE_ROBUST_MUTEXES') and + conf.env.building_tdb and + not conf.env.disable_tdb_mutex_locking): + conf.define('USE_TDB_MUTEX_LOCKING', 1) + + conf.CHECK_XSLTPROC_MANPAGES() + + conf.SAMBA_CHECK_PYTHON() + conf.SAMBA_CHECK_PYTHON_HEADERS() + + conf.SAMBA_CONFIG_H() + + conf.SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS() + +def build(bld): + bld.RECURSE('lib/replace') + + COMMON_FILES='''check.c error.c tdb.c traverse.c + freelistcheck.c lock.c dump.c freelist.c + io.c open.c transaction.c hash.c summary.c rescue.c + mutex.c''' + + COMMON_SRC = bld.SUBDIR('common', COMMON_FILES) + + if bld.env.standalone_tdb: + bld.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig' + private_library = False + else: + private_library = True + + if not bld.CONFIG_SET('USING_SYSTEM_TDB'): + + tdb_deps = 'replace' + + if bld.CONFIG_SET('USE_TDB_MUTEX_LOCKING'): + tdb_deps += ' pthread' + + bld.SAMBA_LIBRARY('tdb', + COMMON_SRC, + deps=tdb_deps, + includes='include', + abi_directory='ABI', + abi_match='tdb_*', + hide_symbols=True, + vnum=VERSION, + public_headers=('' if private_library else 'include/tdb.h'), + public_headers_install=not private_library, + pc_files='tdb.pc', + private_library=private_library) + + bld.SAMBA_BINARY('tdbtorture', + 'tools/tdbtorture.c', + 'tdb', + install=False) + + bld.SAMBA_BINARY('tdbrestore', + 'tools/tdbrestore.c', + 'tdb', manpages='man/tdbrestore.8') + + bld.SAMBA_BINARY('tdbdump', + 'tools/tdbdump.c', + 'tdb', manpages='man/tdbdump.8') + + bld.SAMBA_BINARY('tdbbackup', + 'tools/tdbbackup.c', + 'tdb', + manpages='man/tdbbackup.8') + + bld.SAMBA_BINARY('tdbtool', + 'tools/tdbtool.c', + 'tdb', manpages='man/tdbtool.8') + + if bld.env.standalone_tdb: + # FIXME: This hardcoded list is stupid, stupid, stupid. + bld.SAMBA_SUBSYSTEM('tdb-test-helpers', + 'test/external-agent.c test/lock-tracking.c test/logging.c', + tdb_deps, + includes='include') + + for t in tdb1_unit_tests: + b = "tdb1-" + t + s = "test/" + t + ".c" + bld.SAMBA_BINARY(b, s, 'replace tdb-test-helpers', + includes='include', install=False) + + if not bld.CONFIG_SET('USING_SYSTEM_PYTDB'): + bld.SAMBA_PYTHON('pytdb', + 'pytdb.c', + deps='tdb', + enabled=not bld.env.disable_python, + realname='tdb.so', + cflags='-DPACKAGE_VERSION=\"%s\"' % VERSION) + + if not bld.env.disable_python: + bld.SAMBA_SCRIPT('_tdb_text.py', + pattern='_tdb_text.py', + installdir='python') + + bld.INSTALL_FILES('${PYTHONARCHDIR}', '_tdb_text.py') + +def testonly(ctx): + '''run tdb testsuite''' + ecode = 0 + + blddir = Context.g_module.out + test_prefix = "%s/st" % (blddir) + shutil.rmtree(test_prefix, ignore_errors=True) + os.makedirs(test_prefix) + os.environ['TEST_DATA_PREFIX'] = test_prefix + + env = samba_utils.LOAD_ENVIRONMENT() + # FIXME: This is horrible :( + if env.building_tdb: + # Create scratch directory for tests. + testdir = os.path.join(test_prefix, 'tdb-tests') + samba_utils.mkdir_p(testdir) + # Symlink back to source dir so it can find tests in test/ + link = os.path.join(testdir, 'test') + if not os.path.exists(link): + os.symlink(ctx.path.make_node('test').abspath(), link) + + sh_tests = ["test/test_tdbbackup.sh test/jenkins-be-hash.tdb"] + + for sh_test in sh_tests: + cmd = "BINDIR=%s %s" % (blddir, sh_test) + print("shell test: " + cmd) + ret = samba_utils.RUN_COMMAND(cmd) + if ret != 0: + print("%s sh test failed" % cmd) + ecode = ret + break + + for t in tdb1_unit_tests: + f = "tdb1-" + t + cmd = "cd " + testdir + " && " + os.path.abspath(os.path.join(blddir, f)) + " > test-output 2>&1" + print("..." + f) + ret = samba_utils.RUN_COMMAND(cmd) + if ret != 0: + print("%s failed:" % f) + samba_utils.RUN_COMMAND("cat " + os.path.join(testdir, 'test-output')) + ecode = ret + break + + if ecode == 0: + cmd = os.path.join(blddir, 'tdbtorture') + ret = samba_utils.RUN_COMMAND(cmd) + print("testsuite returned %d" % ret) + if ret != 0: + ecode = ret + + pyret = samba_utils.RUN_PYTHON_TESTS(['python/tests/simple.py']) + print("python testsuite returned %d" % pyret) + sys.exit(ecode or pyret) + +# WAF doesn't build the unit tests for this, maybe because they don't link with tdb? +# This forces it +def test(ctx): + Options.commands.append('build') + Options.commands.append('testonly') + +def dist(): + '''makes a tarball for distribution''' + samba_dist.dist() + +def reconfigure(ctx): + '''reconfigure if config scripts have changed''' + samba_utils.reconfigure(ctx) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.10.0.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.10.0.sigs new file mode 100644 index 0000000..f6227db --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.10.0.sigs @@ -0,0 +1,126 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_context_pop_use: void (struct tevent_context *, const char *) +_tevent_context_push_use: bool (struct tevent_context *, const char *) +_tevent_context_wrapper_create: struct tevent_context *(struct tevent_context *, TALLOC_CTX *, const struct tevent_wrapper_ops *, void *, size_t, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_abort: void (struct tevent_context *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_double_free: void (TALLOC_CTX *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_have_events: bool (struct tevent_context *) +tevent_common_invoke_fd_handler: int (struct tevent_fd *, uint16_t, bool *) +tevent_common_invoke_immediate_handler: int (struct tevent_immediate *, bool *) +tevent_common_invoke_signal_handler: int (struct tevent_signal *, int, int, void *, bool *) +tevent_common_invoke_timer_handler: int (struct tevent_timer *, struct timeval, bool *) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_common_threaded_activate_immediate: void (struct tevent_context *) +tevent_common_wakeup: int (struct tevent_context *) +tevent_common_wakeup_fd: int (int) +tevent_common_wakeup_init: int (struct tevent_context *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_context_is_wrapper: bool (struct tevent_context *) +tevent_context_same_loop: bool (struct tevent_context *, struct tevent_context *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_entry_untrigger: void (struct tevent_queue_entry *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_get_profile: const struct tevent_req_profile *(struct tevent_req *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_move_profile: struct tevent_req_profile *(struct tevent_req *, TALLOC_CTX *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_profile_append_sub: void (struct tevent_req_profile *, struct tevent_req_profile **) +tevent_req_profile_create: struct tevent_req_profile *(TALLOC_CTX *) +tevent_req_profile_get_name: void (const struct tevent_req_profile *, const char **) +tevent_req_profile_get_start: void (const struct tevent_req_profile *, const char **, struct timeval *) +tevent_req_profile_get_status: void (const struct tevent_req_profile *, pid_t *, enum tevent_req_state *, uint64_t *) +tevent_req_profile_get_stop: void (const struct tevent_req_profile *, const char **, struct timeval *) +tevent_req_profile_get_subprofiles: const struct tevent_req_profile *(const struct tevent_req_profile *) +tevent_req_profile_next: const struct tevent_req_profile *(const struct tevent_req_profile *) +tevent_req_profile_set_name: bool (struct tevent_req_profile *, const char *) +tevent_req_profile_set_start: bool (struct tevent_req_profile *, const char *, struct timeval) +tevent_req_profile_set_status: void (struct tevent_req_profile *, pid_t, enum tevent_req_state, uint64_t) +tevent_req_profile_set_stop: bool (struct tevent_req_profile *, const char *, struct timeval) +tevent_req_received: void (struct tevent_req *) +tevent_req_reset_endtime: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_req_set_profile: bool (struct tevent_req *) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) +tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) +tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_update_timer: void (struct tevent_timer *, struct timeval) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.10.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.10.sigs new file mode 100644 index 0000000..9adaba5 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.10.sigs @@ -0,0 +1,73 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_signal_support: bool (struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.11.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.11.sigs new file mode 100644 index 0000000..9adaba5 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.11.sigs @@ -0,0 +1,73 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_signal_support: bool (struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.12.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.12.sigs new file mode 100644 index 0000000..df9b08d --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.12.sigs @@ -0,0 +1,74 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_signal_support: bool (struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.13.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.13.sigs new file mode 100644 index 0000000..888ca0e --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.13.sigs @@ -0,0 +1,75 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_signal_support: bool (struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.14.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.14.sigs new file mode 100644 index 0000000..13c461c --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.14.sigs @@ -0,0 +1,78 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_signal_support: bool (struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.15.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.15.sigs new file mode 100644 index 0000000..13c461c --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.15.sigs @@ -0,0 +1,78 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_signal_support: bool (struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.16.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.16.sigs new file mode 100644 index 0000000..ea7f944 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.16.sigs @@ -0,0 +1,82 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.17.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.17.sigs new file mode 100644 index 0000000..ea7f944 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.17.sigs @@ -0,0 +1,82 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.18.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.18.sigs new file mode 100644 index 0000000..70d20b6 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.18.sigs @@ -0,0 +1,83 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.19.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.19.sigs new file mode 100644 index 0000000..70d20b6 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.19.sigs @@ -0,0 +1,83 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.20.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.20.sigs new file mode 100644 index 0000000..7b9c77d --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.20.sigs @@ -0,0 +1,87 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.21.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.21.sigs new file mode 100644 index 0000000..d8b9f4b --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.21.sigs @@ -0,0 +1,88 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.22.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.22.sigs new file mode 100644 index 0000000..d8b9f4b --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.22.sigs @@ -0,0 +1,88 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.23.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.23.sigs new file mode 100644 index 0000000..d8b9f4b --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.23.sigs @@ -0,0 +1,88 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.24.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.24.sigs new file mode 100644 index 0000000..d8b9f4b --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.24.sigs @@ -0,0 +1,88 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.25.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.25.sigs new file mode 100644 index 0000000..d8b9f4b --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.25.sigs @@ -0,0 +1,88 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.26.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.26.sigs new file mode 100644 index 0000000..1357751 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.26.sigs @@ -0,0 +1,90 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) +tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.27.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.27.sigs new file mode 100644 index 0000000..1357751 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.27.sigs @@ -0,0 +1,90 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) +tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.28.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.28.sigs new file mode 100644 index 0000000..1357751 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.28.sigs @@ -0,0 +1,90 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) +tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.29.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.29.sigs new file mode 100644 index 0000000..1357751 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.29.sigs @@ -0,0 +1,90 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) +tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.30.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.30.sigs new file mode 100644 index 0000000..9b8bfa1 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.30.sigs @@ -0,0 +1,96 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_have_events: bool (struct tevent_context *) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_common_threaded_activate_immediate: void (struct tevent_context *) +tevent_common_wakeup: int (struct tevent_context *) +tevent_common_wakeup_init: int (struct tevent_context *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) +tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) +tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.31.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.31.sigs new file mode 100644 index 0000000..7a6a236 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.31.sigs @@ -0,0 +1,99 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_have_events: bool (struct tevent_context *) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_common_threaded_activate_immediate: void (struct tevent_context *) +tevent_common_wakeup: int (struct tevent_context *) +tevent_common_wakeup_fd: int (int) +tevent_common_wakeup_init: int (struct tevent_context *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_reset_endtime: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) +tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) +tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_update_timer: void (struct tevent_timer *, struct timeval) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.32.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.32.sigs new file mode 100644 index 0000000..7a6a236 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.32.sigs @@ -0,0 +1,99 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_have_events: bool (struct tevent_context *) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_common_threaded_activate_immediate: void (struct tevent_context *) +tevent_common_wakeup: int (struct tevent_context *) +tevent_common_wakeup_fd: int (int) +tevent_common_wakeup_init: int (struct tevent_context *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_reset_endtime: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) +tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) +tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_update_timer: void (struct tevent_timer *, struct timeval) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.33.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.33.sigs new file mode 100644 index 0000000..7a6a236 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.33.sigs @@ -0,0 +1,99 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_have_events: bool (struct tevent_context *) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_common_threaded_activate_immediate: void (struct tevent_context *) +tevent_common_wakeup: int (struct tevent_context *) +tevent_common_wakeup_fd: int (int) +tevent_common_wakeup_init: int (struct tevent_context *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_reset_endtime: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) +tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) +tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_update_timer: void (struct tevent_timer *, struct timeval) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.34.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.34.sigs new file mode 100644 index 0000000..7a6a236 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.34.sigs @@ -0,0 +1,99 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_have_events: bool (struct tevent_context *) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_common_threaded_activate_immediate: void (struct tevent_context *) +tevent_common_wakeup: int (struct tevent_context *) +tevent_common_wakeup_fd: int (int) +tevent_common_wakeup_init: int (struct tevent_context *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_reset_endtime: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) +tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) +tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_update_timer: void (struct tevent_timer *, struct timeval) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.35.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.35.sigs new file mode 100644 index 0000000..7a6a236 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.35.sigs @@ -0,0 +1,99 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_have_events: bool (struct tevent_context *) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_common_threaded_activate_immediate: void (struct tevent_context *) +tevent_common_wakeup: int (struct tevent_context *) +tevent_common_wakeup_fd: int (int) +tevent_common_wakeup_init: int (struct tevent_context *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_reset_endtime: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) +tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) +tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_update_timer: void (struct tevent_timer *, struct timeval) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.36.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.36.sigs new file mode 100644 index 0000000..8a579c8 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.36.sigs @@ -0,0 +1,100 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_have_events: bool (struct tevent_context *) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_common_threaded_activate_immediate: void (struct tevent_context *) +tevent_common_wakeup: int (struct tevent_context *) +tevent_common_wakeup_fd: int (int) +tevent_common_wakeup_init: int (struct tevent_context *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_entry_untrigger: void (struct tevent_queue_entry *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_reset_endtime: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) +tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) +tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_update_timer: void (struct tevent_timer *, struct timeval) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.37.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.37.sigs new file mode 100644 index 0000000..f6227db --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.37.sigs @@ -0,0 +1,126 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_context_pop_use: void (struct tevent_context *, const char *) +_tevent_context_push_use: bool (struct tevent_context *, const char *) +_tevent_context_wrapper_create: struct tevent_context *(struct tevent_context *, TALLOC_CTX *, const struct tevent_wrapper_ops *, void *, size_t, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_abort: void (struct tevent_context *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_double_free: void (TALLOC_CTX *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_have_events: bool (struct tevent_context *) +tevent_common_invoke_fd_handler: int (struct tevent_fd *, uint16_t, bool *) +tevent_common_invoke_immediate_handler: int (struct tevent_immediate *, bool *) +tevent_common_invoke_signal_handler: int (struct tevent_signal *, int, int, void *, bool *) +tevent_common_invoke_timer_handler: int (struct tevent_timer *, struct timeval, bool *) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_common_threaded_activate_immediate: void (struct tevent_context *) +tevent_common_wakeup: int (struct tevent_context *) +tevent_common_wakeup_fd: int (int) +tevent_common_wakeup_init: int (struct tevent_context *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_context_is_wrapper: bool (struct tevent_context *) +tevent_context_same_loop: bool (struct tevent_context *, struct tevent_context *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_entry_untrigger: void (struct tevent_queue_entry *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_get_profile: const struct tevent_req_profile *(struct tevent_req *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_move_profile: struct tevent_req_profile *(struct tevent_req *, TALLOC_CTX *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_profile_append_sub: void (struct tevent_req_profile *, struct tevent_req_profile **) +tevent_req_profile_create: struct tevent_req_profile *(TALLOC_CTX *) +tevent_req_profile_get_name: void (const struct tevent_req_profile *, const char **) +tevent_req_profile_get_start: void (const struct tevent_req_profile *, const char **, struct timeval *) +tevent_req_profile_get_status: void (const struct tevent_req_profile *, pid_t *, enum tevent_req_state *, uint64_t *) +tevent_req_profile_get_stop: void (const struct tevent_req_profile *, const char **, struct timeval *) +tevent_req_profile_get_subprofiles: const struct tevent_req_profile *(const struct tevent_req_profile *) +tevent_req_profile_next: const struct tevent_req_profile *(const struct tevent_req_profile *) +tevent_req_profile_set_name: bool (struct tevent_req_profile *, const char *) +tevent_req_profile_set_start: bool (struct tevent_req_profile *, const char *, struct timeval) +tevent_req_profile_set_status: void (struct tevent_req_profile *, pid_t, enum tevent_req_state, uint64_t) +tevent_req_profile_set_stop: bool (struct tevent_req_profile *, const char *, struct timeval) +tevent_req_received: void (struct tevent_req *) +tevent_req_reset_endtime: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_req_set_profile: bool (struct tevent_req *) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) +tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) +tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_update_timer: void (struct tevent_timer *, struct timeval) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.38.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.38.sigs new file mode 100644 index 0000000..f6227db --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.38.sigs @@ -0,0 +1,126 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_context_pop_use: void (struct tevent_context *, const char *) +_tevent_context_push_use: bool (struct tevent_context *, const char *) +_tevent_context_wrapper_create: struct tevent_context *(struct tevent_context *, TALLOC_CTX *, const struct tevent_wrapper_ops *, void *, size_t, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_abort: void (struct tevent_context *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_double_free: void (TALLOC_CTX *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_have_events: bool (struct tevent_context *) +tevent_common_invoke_fd_handler: int (struct tevent_fd *, uint16_t, bool *) +tevent_common_invoke_immediate_handler: int (struct tevent_immediate *, bool *) +tevent_common_invoke_signal_handler: int (struct tevent_signal *, int, int, void *, bool *) +tevent_common_invoke_timer_handler: int (struct tevent_timer *, struct timeval, bool *) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_common_threaded_activate_immediate: void (struct tevent_context *) +tevent_common_wakeup: int (struct tevent_context *) +tevent_common_wakeup_fd: int (int) +tevent_common_wakeup_init: int (struct tevent_context *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_context_is_wrapper: bool (struct tevent_context *) +tevent_context_same_loop: bool (struct tevent_context *, struct tevent_context *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_entry_untrigger: void (struct tevent_queue_entry *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_get_profile: const struct tevent_req_profile *(struct tevent_req *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_move_profile: struct tevent_req_profile *(struct tevent_req *, TALLOC_CTX *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_profile_append_sub: void (struct tevent_req_profile *, struct tevent_req_profile **) +tevent_req_profile_create: struct tevent_req_profile *(TALLOC_CTX *) +tevent_req_profile_get_name: void (const struct tevent_req_profile *, const char **) +tevent_req_profile_get_start: void (const struct tevent_req_profile *, const char **, struct timeval *) +tevent_req_profile_get_status: void (const struct tevent_req_profile *, pid_t *, enum tevent_req_state *, uint64_t *) +tevent_req_profile_get_stop: void (const struct tevent_req_profile *, const char **, struct timeval *) +tevent_req_profile_get_subprofiles: const struct tevent_req_profile *(const struct tevent_req_profile *) +tevent_req_profile_next: const struct tevent_req_profile *(const struct tevent_req_profile *) +tevent_req_profile_set_name: bool (struct tevent_req_profile *, const char *) +tevent_req_profile_set_start: bool (struct tevent_req_profile *, const char *, struct timeval) +tevent_req_profile_set_status: void (struct tevent_req_profile *, pid_t, enum tevent_req_state, uint64_t) +tevent_req_profile_set_stop: bool (struct tevent_req_profile *, const char *, struct timeval) +tevent_req_received: void (struct tevent_req *) +tevent_req_reset_endtime: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_req_set_profile: bool (struct tevent_req *) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) +tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) +tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_update_timer: void (struct tevent_timer *, struct timeval) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.39.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.39.sigs new file mode 100644 index 0000000..f6227db --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.39.sigs @@ -0,0 +1,126 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_context_pop_use: void (struct tevent_context *, const char *) +_tevent_context_push_use: bool (struct tevent_context *, const char *) +_tevent_context_wrapper_create: struct tevent_context *(struct tevent_context *, TALLOC_CTX *, const struct tevent_wrapper_ops *, void *, size_t, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_abort: void (struct tevent_context *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_double_free: void (TALLOC_CTX *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_have_events: bool (struct tevent_context *) +tevent_common_invoke_fd_handler: int (struct tevent_fd *, uint16_t, bool *) +tevent_common_invoke_immediate_handler: int (struct tevent_immediate *, bool *) +tevent_common_invoke_signal_handler: int (struct tevent_signal *, int, int, void *, bool *) +tevent_common_invoke_timer_handler: int (struct tevent_timer *, struct timeval, bool *) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_common_threaded_activate_immediate: void (struct tevent_context *) +tevent_common_wakeup: int (struct tevent_context *) +tevent_common_wakeup_fd: int (int) +tevent_common_wakeup_init: int (struct tevent_context *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_context_is_wrapper: bool (struct tevent_context *) +tevent_context_same_loop: bool (struct tevent_context *, struct tevent_context *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_entry_untrigger: void (struct tevent_queue_entry *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_get_profile: const struct tevent_req_profile *(struct tevent_req *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_move_profile: struct tevent_req_profile *(struct tevent_req *, TALLOC_CTX *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_profile_append_sub: void (struct tevent_req_profile *, struct tevent_req_profile **) +tevent_req_profile_create: struct tevent_req_profile *(TALLOC_CTX *) +tevent_req_profile_get_name: void (const struct tevent_req_profile *, const char **) +tevent_req_profile_get_start: void (const struct tevent_req_profile *, const char **, struct timeval *) +tevent_req_profile_get_status: void (const struct tevent_req_profile *, pid_t *, enum tevent_req_state *, uint64_t *) +tevent_req_profile_get_stop: void (const struct tevent_req_profile *, const char **, struct timeval *) +tevent_req_profile_get_subprofiles: const struct tevent_req_profile *(const struct tevent_req_profile *) +tevent_req_profile_next: const struct tevent_req_profile *(const struct tevent_req_profile *) +tevent_req_profile_set_name: bool (struct tevent_req_profile *, const char *) +tevent_req_profile_set_start: bool (struct tevent_req_profile *, const char *, struct timeval) +tevent_req_profile_set_status: void (struct tevent_req_profile *, pid_t, enum tevent_req_state, uint64_t) +tevent_req_profile_set_stop: bool (struct tevent_req_profile *, const char *, struct timeval) +tevent_req_received: void (struct tevent_req *) +tevent_req_reset_endtime: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_req_set_profile: bool (struct tevent_req *) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_signal_support: bool (struct tevent_context *) +tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) +tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) +tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_update_timer: void (struct tevent_timer *, struct timeval) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.9.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.9.sigs new file mode 100644 index 0000000..9adaba5 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.9.sigs @@ -0,0 +1,73 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_received: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_signal_support: bool (struct tevent_context *) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/Makefile b/ldb-2.0.8/lib/tevent/Makefile new file mode 100644 index 0000000..6a3aab0 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/Makefile @@ -0,0 +1,52 @@ +# simple makefile wrapper to run waf +WAF_BIN=`PATH=buildtools/bin:../../buildtools/bin:$$PATH which waf` +WAF_BINARY=$(PYTHON) $(WAF_BIN) +WAF=PYTHONHASHSEED=1 WAF_MAKE=1 $(WAF_BINARY) + +all: + $(WAF) build + +install: + $(WAF) install + +uninstall: + $(WAF) uninstall + +test: + $(WAF) test $(TEST_OPTIONS) + +dist: + touch .tmplock + WAFLOCK=.tmplock $(WAF) dist + +distcheck: + touch .tmplock + WAFLOCK=.tmplock $(WAF) distcheck + +clean: + $(WAF) clean + +distclean: + $(WAF) distclean + +reconfigure: configure + $(WAF) reconfigure + +show_waf_options: + $(WAF) --help + +# some compatibility make targets +everything: all + +testsuite: all + +check: test + +# this should do an install as well, once install is finished +installcheck: test + +etags: + $(WAF) etags + +ctags: + $(WAF) ctags diff --git a/ldb-2.0.8/lib/tevent/bindings.py b/ldb-2.0.8/lib/tevent/bindings.py new file mode 100644 index 0000000..f5e1499 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/bindings.py @@ -0,0 +1,116 @@ +#!/usr/bin/python +# +# Python integration for tevent - tests +# +# Copyright (C) Jelmer Vernooij 2010 +# +# ** NOTE! The following LGPL license applies to the tevent +# ** library. This does NOT imply that all of Samba is released +# ** under the LGPL +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 3 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, see . + +import signal +from unittest import TestCase, TestProgram +import gc + +import _tevent + + +class BackendListTests(TestCase): + + def test_backend_list(self): + self.assertTrue(isinstance(_tevent.backend_list(), list)) + + +class CreateContextTests(TestCase): + + def test_by_name(self): + ctx = _tevent.Context(_tevent.backend_list()[0]) + self.assertTrue(ctx is not None) + + def test_no_name(self): + ctx = _tevent.Context() + self.assertTrue(ctx is not None) + + +class ContextTests(TestCase): + + def setUp(self): + super(ContextTests, self).setUp() + self.ctx = _tevent.Context() + + def test_signal_support(self): + self.assertTrue(type(self.ctx.signal_support) is bool) + + def test_reinitialise(self): + self.ctx.reinitialise() + + def test_loop_wait(self): + self.ctx.loop_wait() + + def test_add_signal(self): + sig = self.ctx.add_signal(signal.SIGINT, 0, lambda callback: None) + self.assertTrue(isinstance(sig, _tevent.Signal)) + + def test_timer(self): + """Test a timer is can be scheduled""" + collecting_list = [] + # time "0" has already passed, callback will be scheduled immediately + timer = self.ctx.add_timer(0, lambda t: collecting_list.append(True)) + self.assertTrue(timer.active) + self.assertEqual(collecting_list, []) + self.ctx.loop_once() + self.assertFalse(timer.active) + self.assertEqual(collecting_list, [True]) + + def test_timer_deallocate_timer(self): + """Test timer is scheduled even if reference to it isn't held""" + collecting_list = [] + + def callback(t): + collecting_list.append(True) + timer = self.ctx.add_timer(0, lambda t: collecting_list.append(True)) + gc.collect() + self.assertEqual(collecting_list, []) + self.ctx.loop_once() + self.assertEqual(collecting_list, [True]) + + def test_timer_deallocate_context(self): + """Test timer is unscheduled when context is freed""" + collecting_list = [] + + def callback(t): + collecting_list.append(True) + timer = self.ctx.add_timer(0, lambda t: collecting_list.append(True)) + self.assertTrue(timer.active) + del self.ctx + gc.collect() + self.assertEqual(collecting_list, []) + self.assertFalse(timer.active) + + def test_timer_offset(self): + """Test scheduling timer with an offset""" + collecting_list = [] + self.ctx.add_timer_offset(0.2, lambda t: collecting_list.append(2)) + self.ctx.add_timer_offset(0.1, lambda t: collecting_list.append(1)) + self.assertEqual(collecting_list, []) + self.ctx.loop_once() + self.assertEqual(collecting_list, [1]) + self.ctx.loop_once() + self.assertEqual(collecting_list, [1, 2]) + + +if __name__ == '__main__': + TestProgram() diff --git a/ldb-2.0.8/lib/tevent/configure b/ldb-2.0.8/lib/tevent/configure new file mode 100755 index 0000000..c3c4447 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/configure @@ -0,0 +1,21 @@ +#!/bin/sh + +PREVPATH=`dirname $0` + +if [ -f $PREVPATH/../../buildtools/bin/waf ]; then + WAF=../../buildtools/bin/waf +elif [ -f $PREVPATH/buildtools/bin/waf ]; then + WAF=./buildtools/bin/waf +else + echo "tevent: Unable to find waf" + exit 1 +fi + +# using JOBS=1 gives maximum compatibility with +# systems like AIX which have broken threading in python +JOBS=1 +export JOBS + +cd . || exit 1 +$PYTHON $WAF configure "$@" || exit 1 +cd $PREVPATH diff --git a/ldb-2.0.8/lib/tevent/doc/img/tevent_context_stucture.png b/ldb-2.0.8/lib/tevent/doc/img/tevent_context_stucture.png new file mode 100644 index 0000000000000000000000000000000000000000..fba8161572d5af6b18e266e88cc2eb20ac76c495 GIT binary patch literal 21888 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 literal 0 HcmV?d00001 diff --git a/ldb-2.0.8/lib/tevent/doc/img/tevent_subrequest.png b/ldb-2.0.8/lib/tevent/doc/img/tevent_subrequest.png new file mode 100644 index 0000000000000000000000000000000000000000..ea79223d4dc1f6c524d40b566e9895003ec4df34 GIT binary patch literal 22453 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 directory + * on the samba public source archive. + * + * @section main_tevent_bugs Discussion and bug reports + * + * tevent does not currently have its own mailing list or bug tracking system. + * For now, please use the + * samba-technical + * mailing list, and the + * Samba bugzilla + * bug tracking system. + * + * @section main_tevent_devel Development + * You can download the latest code either via git or rsync. + * + * To fetch via git see the following guide: + * + * Using Git for Samba Development + * + * Once you have cloned the tree switch to the master branch and cd into the + * lib/tevent directory. + * + * To fetch via rsync use this command: + * + * rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/tevent . + * + */ diff --git a/ldb-2.0.8/lib/tevent/doc/tevent_context.dox b/ldb-2.0.8/lib/tevent/doc/tevent_context.dox new file mode 100644 index 0000000..39eb85e --- /dev/null +++ b/ldb-2.0.8/lib/tevent/doc/tevent_context.dox @@ -0,0 +1,75 @@ +/** +@page tevent_context Chapter 1: Tevent context + +@section context Tevent context + +Tevent context is an essential logical unit of tevent library. For working with +events at least one such context has to be created - allocated, initialized. +Then, events which are meant to be caught and handled have to be registered +within this specific context. Reason for subordinating events to a tevent +context structure rises from the fact that several context can be created and +each of them is processed at different time. So, there can be 1 context +containing just file descriptor events, another one taking care of signal and +time events and the third one which keeps information about the rest. + +Tevent loops are the part of the library which represents the mechanism where +noticing events and triggering handlers actually happens. They accept just one +argument - tevent context structure. Therefore if theoretically an infinity +loop (tevent_loop_wait) was called, only those arguments which belong to the +passed tevent context structure can be caught and invoked within this call. +Although some more signal events were registered (but within some other +context) they will not be noticed. + +@subsection Example + +First lines which handle mem_ctx belong to talloc library +knowledge but because of the fact that tevent uses the talloc library for its +mechanisms it is necessary to understand a bit talloc as well. For more +information about working with talloc, please visit talloc website where tutorial and +documentation are located. + +Tevent context structure *event_ctx represents the unit which will +further contain information about registered events. It is created via calling +tevent_context_init(). + +@code +TALLOC_CTX *mem_ctx = talloc_new(NULL); +if (mem_ctx == NULL) { + // error handling +} + +struct tevent_context *ev_ctx = tevent_context_init(mem_ctx); +if(ev_ctx == NULL) { + // error handling +} +@endcode + +Tevent context has a structure containing lots of information. It include lists +of all events which are divided according their type and are in order showing +the sequence as they came. + +@image html tevent_context_stucture.png + +In addition to the lists shown in the diagram, the tevent context also contains +many other data (e.g. information about the available system mechanism for +triggering callbacks). + +@section tevent_loops Tevent loops + +Tevent loops are the dispatcher for events. They catch them and trigger the +handlers. In the case of longer processes, the program spends most of its time +at this point waiting for events, invoking handlers and waiting for another +event again. There are 2 types of loop available for use in tevent library: + +
        +
      • int tevent_loop_wait()
      • +
      • int tevent_loop_once()
      • +
      + +Both of functions accept just one parameter (tevent context) and the only +difference lies in the fact that the first loop can theoretically last for ever +but the second one will wait just for a single one event to catch and then the +loop breaks and the program continue. + +*/ diff --git a/ldb-2.0.8/lib/tevent/doc/tevent_data.dox b/ldb-2.0.8/lib/tevent/doc/tevent_data.dox new file mode 100644 index 0000000..dbe7a04 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/doc/tevent_data.dox @@ -0,0 +1,137 @@ +/** +@page tevent_data Chapter 3: Accessing data +@section data Accessing data with tevent + +A tevent request is (usually) created together with a structure for storing the +data necessary for an asynchronous computation. For these private data, tevent +library uses void (generic) pointers, therefore any data type can be very +simply pointed at. However, this attitude requires clear and guaranteed +knowledge of the data type that will be handled, in advance. Private data can +be of 2 types: connected with a request itself or given as an individual +argument to a callback. It is necessary to differentiate these types, because +there is a slightly different method of data access for each. There are two +possibilities how to access data that is given as an argument directly to a +callback. The difference lies in the pointer that is returned. In one case it +is the data type specified in the function’s argument, in another void* is +returned. + +@code +void tevent_req_callback_data (struct tevent_req *req, #type) +void tevent_req_callback_data_void (struct tevent_req *req) +@endcode + + +To obtain data that are strictly bound to a request, this function is the only +direct procedure. + +@code +void *tevent_req_data (struct tevent_req *req, #type) +@endcode + +Example with both calls which differs between private data within tevent +request and data handed over as an argument. + +@code +#include +#include +#include + +struct foo_state { + int x; +}; + +struct testA { + int y; +}; + + +static void foo_done(struct tevent_req *req) { + // a->x contains 10 since it came from foo_send + struct foo_state *a = tevent_req_data(req, struct foo_state); + + // b->y contains 9 since it came from run + struct testA *b = tevent_req_callback_data(req, struct testA); + + // c->y contains 9 since it came from run we just used a different way + // of getting it. + struct testA *c = (struct testA *)tevent_req_callback_data_void(req); + + printf("a->x: %d\n", a->x); + printf("b->y: %d\n", b->y); + printf("c->y: %d\n", c->y); +} + + +struct tevent_req * foo_send(TALLOC_CTX *mem_ctx, struct tevent_context *event_ctx) { + +printf("_send\n"); +struct tevent_req *req; +struct foo_state *state; + +req = tevent_req_create(event_ctx, &state, struct foo_state); +state->x = 10; + +return req; +} + +static void run(struct tevent_context *ev, struct tevent_timer *te, + struct timeval current_time, void *private_data) { + struct tevent_req *req; + struct testA *tmp = talloc(ev, struct testA); + + // Note that we did not use the private data passed in + + tmp->y = 9; + req = foo_send(ev, ev); + + tevent_req_set_callback(req, foo_done, tmp); + tevent_req_done(req); + +} + +int main (int argc, char **argv) { + + struct tevent_context *event_ctx; + struct testA *data; + TALLOC_CTX *mem_ctx; + struct tevent_timer *time_event; + + mem_ctx = talloc_new(NULL); //parent + if (mem_ctx == NULL) + return EXIT_FAILURE; + + event_ctx = tevent_context_init(mem_ctx); + if (event_ctx == NULL) + return EXIT_FAILURE; + + data = talloc(mem_ctx, struct testA); + data->y = 11; + + time_event = tevent_add_timer(event_ctx, + mem_ctx, + tevent_timeval_current(), + run, + data); + if (time_event == NULL) { + fprintf(stderr, " FAILED\n"); + return EXIT_FAILURE; + } + + tevent_loop_once(event_ctx); + + talloc_free(mem_ctx); + + printf("Quit\n"); + return EXIT_SUCCESS; +} +@endcode + +Output of this example is: + +@code +a->x: 10 +b->y: 9 +c->y: 9 +@endcode + +*/ diff --git a/ldb-2.0.8/lib/tevent/doc/tevent_events.dox b/ldb-2.0.8/lib/tevent/doc/tevent_events.dox new file mode 100644 index 0000000..d56af25 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/doc/tevent_events.dox @@ -0,0 +1,341 @@ +/** +@page tevent_events Chapter 2: Tevent events +@section pools Tevent events + +Ok, after reading previous chapter we can start doing something useful. So, the +way of creating events is similar for all types - signals, file descriptors, +time or immediate events. At the beginning it is good to know about some +typedefs which are set in tevent library and which specify the arguments for +each callback. These callbacks are: + +- tevent_timer_handler_t() + +- tevent_immediate_handler_t() + +- tevent_signal_handler_t() + +- tevent_fd_handler_t() + +According their names it is obvious that for creating callback for e.g. time +event, tevent_timer_handler_t will be used. + +The best way how to introduce registering an event and setting up a callback +would be example, so examples describing all the types of events follow. + +@subsection Time Time event + +This example shows how to set up an event which will be repeated for a minute +with interval of 2 seconds (will be triggered 30 times). After exceeding this +limit, the event loop will finish and all the memory resources will be freed. +This is just example describing repeated activity, nothing usefull is done +within foo function + +@code +#include +#include +#include +#include + +struct state { + struct timeval endtime; + int counter; + TALLOC_CTX *ctx; +}; + +static void callback(struct tevent_context *ev, struct tevent_timer *tim, + struct timeval current_time, void *private_data) +{ + struct state *data = talloc_get_type_abort(private_data, struct state); + struct tevent_timer *time_event; + struct timeval schedule; + + printf("Data value: %d\n", data->counter); + data->counter += 1; // increase counter + + // if time has not reached its limit, set another event + if (tevent_timeval_compare(¤t_time, &(data->endtime)) < 0) { + // do something + // set repeat with delay 2 seconds + schedule = tevent_timeval_current_ofs(2, 0); + time_event = tevent_add_timer(ev, data->ctx, schedule, callback, data); + if (time_event == NULL) { // error ... + fprintf(stderr, "MEMORY PROBLEM\n"); + return; + } + } else { + // time limit exceeded + } +} + +int main(void) { + struct tevent_context *event_ctx; + TALLOC_CTX *mem_ctx; + struct tevent_timer *time_event; + struct timeval schedule; + + mem_ctx = talloc_new(NULL); // parent + event_ctx = tevent_context_init(mem_ctx); + + struct state *data = talloc(mem_ctx, struct state); + + schedule = tevent_timeval_current_ofs(2, 0); // +2 second time value + data->endtime = tevent_timeval_add(&schedule, 60, 0); // one minute time limit + data->ctx = mem_ctx; + data->counter = 0; + + // add time event + time_event = tevent_add_timer(event_ctx, mem_ctx, schedule, callback, data); + if (time_event == NULL) { + fprintf(stderr, "FAILED\n"); + return EXIT_FAILURE; + } + + tevent_loop_wait(event_ctx); + talloc_free(mem_ctx); + return EXIT_SUCCESS; +} +@endcode + +Variable counter is only used for counting the number of triggered +functions. List of all available functions which tevent offers for working with +time are listed +here together +with their description. More detailed view at these functions is unnecessary +because their purpose and usage is quite simple and clear. + +@subsection Immediate Immediate event + +These events are, as their name indicates, activated and performed immediately. +It means that this kind of events have priority over others (except signal +events). So if there is a bulk of events registered and after that a +tevent loop is launched, then all the immediate events will be triggered before +the other events. Except other immediate events (and signal events) because +they are also processed sequentially - according the order they were scheduled. +Signals have the highest priority and therefore they are processed +preferentially. Therefore the expression immediate may not correspond exactly +to the dictionary definition of "something without delay" but rather "as soon +as possible" after all preceding immediate events. + +For creating an immediate event there is a small different which lies in the +fact that the creation of such event is done in 2 steps. One represents the +creation (memory allocation), the second one represents registering as the +event within some tevent context. + +@code +struct tevent_immediate *run(TALLOC_CTX* mem_ctx, + struct tevent_context event_ctx, + void * data) +{ + struct tevent_immediate *im; + + im = tevent_create_immediate(mem_ctx); + if (im == NULL) { + return NULL; + } + tevent_schedule_immediate(im, event_ctx, foo, data); + + return im; +} +@endcode + +Example which may be compiled and run representing the creation of immediate event. + +@code + +#include +#include +#include + +struct info_struct { + int counter; +}; + +static void foo(struct tevent_context *ev, struct tevent_immediate *im, + void *private_data) +{ + struct info_struct *data = talloc_get_type_abort(private_data, struct info_struct); + printf("Data value: %d\n", data->counter); +} + +int main (void) { + struct tevent_context *event_ctx; + TALLOC_CTX *mem_ctx; + struct tevent_immediate *im; + + printf("INIT\n"); + + mem_ctx = talloc_new(NULL); + event_ctx = tevent_context_init(mem_ctx); + + struct info_struct *data = talloc(mem_ctx, struct info_struct); + + // setting up private data + data->counter = 1; + + // first immediate event + im = tevent_create_immediate(mem_ctx); + if (im == NULL) { + fprintf(stderr, "FAILED\n"); + return EXIT_FAILURE; + } + tevent_schedule_immediate(im, event_ctx, foo, data); + + tevent_loop_wait(event_ctx); + talloc_free(mem_ctx); + + return 0; +} +@endcode + +@subsection Signal Signal event + +This is an alternative to standard C library functions signal() or sigaction(). +The main difference that distinguishes these ways of treating signals is their +setting up of handlers for different time intervals of the running program. + +While standard C library methods for dealing with signals offer sufficient +tools for most cases, they are inadequate for handling signals within the +tevent loop. It could be necessary to finish certain tevent requests within the +tevent loop without interruption. If a signal was sent to a program at a moment +when the tevent loop is in progress, a standard signal handler would not return +processing to the application at the very same place and it would quit the +tevent loop for ever. In such cases, tevent signal handlers offer the +possibility of dealing with these signals by masking them from the rest of +application and not quitting the loop, so the other events can still be +processed. + +Tevent offers also a control function, which enables us to verify whether it is +possible to handle signals via tevent, is defined within tevent library and it +returns a boolean value revealing the result of the verification. + +@code +bool tevent_signal_support (struct tevent_context *ev) +@endcode + +Checking for signal support is not necessary, but if it is not guaranteed, this +is a good and easy control to prevent unexpected behaviour or failure of the +program occurring. Such a test of course does not have to be run every single +time you wish to create a signal handler, but simply at the beginning - during +the initialization procedures of the program. Afterthat, simply adapt to each +situation that arises. + +@code + +#include +#include +#include + +static void handler(struct tevent_context *ev, + struct tevent_signal *se, + int signum, + int count, + void *siginfo, + void *private_data) +{ + + // Do something usefull + + printf("handling signal...\n"); + exit(EXIT_SUCCESS); +} + +int main (void) +{ + struct tevent_context *event_ctx; + TALLOC_CTX *mem_ctx; + struct tevent_signal *sig; + + mem_ctx = talloc_new(NULL); //parent + if (mem_ctx == NULL) { + fprintf(stderr, "FAILED\n"); + return EXIT_FAILURE; + } + + event_ctx = tevent_context_init(mem_ctx); + if (event_ctx == NULL) { + fprintf(stderr, "FAILED\n"); + return EXIT_FAILURE; + } + + if (tevent_signal_support(event_ctx)) { + // create signal event + sig = tevent_add_signal(event_ctx, mem_ctx, SIGINT, 0, handler, NULL); + if (sig == NULL) { + fprintf(stderr, "FAILED\n"); + return EXIT_FAILURE; + } + tevent_loop_wait(event_ctx); + } + + talloc_free(mem_ctx); + return EXIT_SUCCESS; +} +@endcode + + +@subsection File File descriptor event + +Support of events on file descriptors is mainly useful for socket communication +but it certainly works flawlessly with standard streams (stdin, stdout, stderr) + as well. Working asynchronously with file descriptors enables switching + within processing I/O operations. This ability may rise with a greater + number of I/O operations and such overlapping leads to enhancement of the + throughput. + +There are several other functions included in tevent API related to handling +file descriptors (there are too many functions defined within tevent therefore +just some of them are fully described within this thesis. The +declaration of the rest can be easily found on the library’s website or +directly from the source code): + +
        +
      • tevent_fd_set_close_fn() - can add another function to be called at the + moment when a structure tevent fd is freed.
      • +
      • tevent_fd_set_auto_close() - calling this function can simplify the + maintenance of file descriptors, because it instructs tevent to close the + appropriate file descriptor when the tevent fd structure is about to be + freed.
      • +
      • tevent_fd_get_flags() - returns flags which are set on the file descriptor + connected with this tevent fd structure.
      • +
      • tevent_fd_set_flags() - sets specified flags on the event’s file + descriptor.
      • +
      + +@code + +static void close_fd(struct tevent_context *ev, struct tevent_fd *fd_event, + int fd, void *private_data) +{ + // processing when fd_event is freed +} + +struct static void handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, + void *private_data) +{ + // handling event; reading from a file descriptor + tevent_fd_set_close_fn (fd_event, close_fd); +} + +int run(TALLOC_CTX *mem_ctx, struct tevent_context *event_ctx, + int fd, uint16_t flags, char *buffer) +{ + struct tevent_fd* fd_event = NULL; + + if (flags & TEVENT_FD_READ) { + fd_event = tevent_add_fd(event_ctx, + mem_ctx, + fd, + flags, + handler, + buffer); + } + if (fd_event == NULL) { + // error handling + } + return tevent_loop_once(); +} +@endcode + +*/ diff --git a/ldb-2.0.8/lib/tevent/doc/tevent_queue.dox b/ldb-2.0.8/lib/tevent/doc/tevent_queue.dox new file mode 100644 index 0000000..9c247e5 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/doc/tevent_queue.dox @@ -0,0 +1,275 @@ +/** +@page tevent_queue Chapter 5: Tevent queue +@section queue Tevent queue + +There is a possibility that the dispatcher and its handlers may not be able to +handle all the incoming events as quickly as they arrive. One way to deal with +this situation is to buffer the received events by introducing an event queue +into the events stream, between the events generator and the dispatcher. Events +are added to the queue as they arrive, and the dispatcher pops them off the +beginning of the queue as fast as possible. In tevent library it is +similar, but the queue is not automatically set for any event. The queue has to +be created on purpose, and events which should follow the order of the FIFO +queue have to be explicitly pinpointed. Creating such a queue is crucial in +situations when sequential processing is absolutely essential for the +successful +completion of a task, e.g. for a large quantity of data that are about to be +written from a buffer into a socket. The tevent library has its own queue +structure that is ready to use after it has been initialized and started up +once. + +@subsection cr_queue Creation of Queues + +The first and most important step is the creation of the tevent queue +(represented by struct tevent_queue), which will then be in running mode. + +@code +struct tevent_queue* tevent_queue_create (TALLOC_CTX *mem_ctx, const char *name) +@endcode + +When the program returns from this function, the allocated memory, set +destructor and labeled queue as running has been done and the structure is +ready to be filled with entries. Stopping and starting queues on the run. If +you need to stop a queue from processing its entries, and then turn it on +again, a couple of functions which serve this purpose are: + +- bool tevent_queue_stop() +- bool tevent_queue_start() + +These functions actually only provide for the simple setting of a variable, +which indicates that the queue has been stopped/started. Returned value +indicates result. + +@subsection add_queue Adding Requests to a Queue + +Tevent in fact offers 3 possible ways of inserting a request into a queue. +There are no vast differences between them, but still there might be situations +where one of them is more suitable and desired than another. + +@code +bool tevent_queue_add(struct tevent_queue *queue, + struct tevent_context *ev, + struct tevent_req *req, + tevent_queue_trigger_fn_t trigger, + void *private_data) +@endcode + +This call is the simplest of all three. It offers only boolean verification of +whether the operation of adding the request into a queue was successful or not. +No additional deletion of an item from the queue is possible, i.e. it is only +possible to deallocate the whole tevent request, which would cause triggering +of destructor handling and also dropping the request from the queue. + +Extended Options + +Both of the following functions have a feature in common - they return tevent +queue entry structure representing the item in a queue. There is no further +possible handling with this structure except the use of the structure’s pointer +for its deallocation (which leads also its removal from the queue). The +difference lies in the possibility that with the following functions it is +possible to remove the tevent request from a queue without its deallocation. +The previous function can only deallocate the tevent request as it was from +memory, and thereby logically cause its removal from the queue as well. There +is no other utilization of this structure via API at this stage of tevent +library. The possibility of easier debugging while developing with tevent could +be considered to be an advantage of this returned pointer. + +@code +struct tevent_queue_entry *tevent_queue_add_entry(struct tevent_queue *queue, + struct tevent_context *ev, + struct tevent_req *req, + tevent_queue_trigger_fn_t trigger, + void *private_data) +@endcode + +The feature that allows for the optimized addition of entries to a queue is +that a check for an empty queue with no items is first of all carried out. If +it is found that the queue is empty, then the request for inserting the entry +into a queue will be omitted and directly triggered. + +@code +struct tevent_queue_entry *tevent_queue_add_optimize_empty(struct tevent_queue *queue, + struct tevent_context *ev, + struct tevent_req *req, + tevent_queue_trigger_fn_t trigger, + void *private_data) +@endcode + +When calling any of the functions serving for inserting an item into a queue, +it is possible to leave out the fourth argument (trigger) and instead of a +function pass a NULL pointer. This usage sets so-called blocking entries. +These entries, since they do not have any trigger operation to be activated, +just sit in their position until they are labeled as a done by another +function. Their purpose is to block other items in the queue from being +triggered. + +@subsection example_q Example of tevent queue + +@code +#include +#include +#include + +struct foo_state { + int local_var; + int x; +}; + +struct juststruct { + TALLOC_CTX * ctx; + struct tevent_context *ev; + int y; +}; + +int created = 0; + +static void timer_handler(struct tevent_context *ev, struct tevent_timer *te, + struct timeval current_time, void *private_data) +{ + // time event which after all sets request as done. Following item from + // the queue may be invoked. + struct tevent_req *req = private_data; + struct foo_state *stateX = tevent_req_data(req, struct foo_state); + + // processing some stuff + + printf("time_handler\n"); + + tevent_req_done(req); + talloc_free(req); + + printf("Request #%d set as done.\n", stateX->x); +} + +static void trigger(struct tevent_req *req, void *private_data) +{ + struct juststruct *priv = tevent_req_callback_data (req, struct juststruct); + struct foo_state *in = tevent_req_data(req, struct foo_state); + struct timeval schedule; + struct tevent_timer *tim; + schedule = tevent_timeval_current_ofs(1, 0); + printf("Processing request #%d\n", in->x); + + if (in->x % 3 == 0) { // just example; third request does not contain + // any further operation and will be finished right + // away. + tim = NULL; + } else { + tim = tevent_add_timer(priv->ev, req, schedule, timer_handler, req); + } + + if (tim == NULL) { + tevent_req_done(req); + talloc_free(req); + printf("Request #%d set as done.\n", in->x); + } +} + +struct tevent_req *foo_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + const char *name, int num) +{ + struct tevent_req *req; + struct foo_state *state; + struct foo_state *in; + struct tevent_timer *tim; + + printf("foo_send\n"); + req = tevent_req_create(mem_ctx, &state, struct foo_state); + if (req == NULL) { // check for appropriate allocation + tevent_req_error(req, 1); + return NULL; + } + + // exemplary filling of variables + state->local_var = 1; + state->x = num; + + return req; +} + +static void foo_done(struct tevent_req *req) { + + enum tevent_req_state state; + uint64_t err; + + if (tevent_req_is_error(req, &state, &err)) { + printf("ERROR WAS SET %d\n", state); + return; + } else { + // processing some stuff + printf("Callback is done...\n"); + } +} + +int main (int argc, char **argv) +{ + TALLOC_CTX *mem_ctx; + struct tevent_req* req[6]; + struct tevent_req* tmp; + struct tevent_context *ev; + struct tevent_queue *fronta = NULL; + struct juststruct *data; + int ret; + int i = 0; + + const char * const names[] = { + "first", "second", "third", "fourth", "fifth" + }; + + printf("INIT\n"); + + mem_ctx = talloc_new(NULL); //parent + talloc_parent(mem_ctx); + ev = tevent_context_init(mem_ctx); + if (ev == NULL) { + fprintf(stderr, "MEMORY ERROR\n"); + return EXIT_FAILURE; + } + + // setting up queue + fronta = tevent_queue_create(mem_ctx, "test_queue"); + tevent_queue_stop(fronta); + tevent_queue_start(fronta); + if (tevent_queue_running(fronta)) { + printf ("Queue is runnning (length: %d)\n", tevent_queue_length(fronta)); + } else { + printf ("Queue is not runnning\n"); + } + + data = talloc(ev, struct juststruct); + data->ctx = mem_ctx; + data->ev = ev; + + + // create 4 requests + for (i = 1; i < 5; i++) { + req[i] = foo_send(mem_ctx, ev, names[i], i); + tmp = req[i]; + if (req[i] == NULL) { + fprintf(stderr, "Request error! %d \n", ret); + break; + } + tevent_req_set_callback(req[i], foo_done, data); + created++; + } + + // add item to a queue + tevent_queue_add(fronta, ev, req[1], trigger, data); + tevent_queue_add(fronta, ev, req[2], trigger, data); + tevent_queue_add(fronta, ev, req[3], trigger, data); + tevent_queue_add(fronta, ev, req[4], trigger, data); + + printf("Queue length: %d\n", tevent_queue_length(fronta)); + while(tevent_queue_length(fronta) > 0) { + tevent_loop_once(ev); + printf("Queue: %d items left\n", tevent_queue_length(fronta)); + } + + talloc_free(mem_ctx); + printf("FINISH\n"); + + return EXIT_SUCCESS; +} +@endcode + +*/ diff --git a/ldb-2.0.8/lib/tevent/doc/tevent_request.dox b/ldb-2.0.8/lib/tevent/doc/tevent_request.dox new file mode 100644 index 0000000..e1e45b1 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/doc/tevent_request.dox @@ -0,0 +1,189 @@ +/** +@page tevent_request Chapter 4: Tevent request +@section request Tevent request + +A specific feature of the library is the tevent request API that provides for +asynchronous computation and allows much more interconnected working and +cooperation among functions and events. When working with tevent request it +is possible to nest one event under another and handle them bit by bit. This +enables the creation of sequences of steps, and provides an opportunity to +prepare for all problems which may unexpectedly happen within the different +phases. One way or another, subrequests split bigger tasks into smaller ones +which allow a clearer view of each task as a whole. + +@subsection name Naming conventions + +There is a naming convention which is not obligatory but it is followed in this +tutorial: + +- Functions triggered before the event happens. These establish a request. +- \b foo_send(...) - this function is called first and it includes the + creation of tevent request - tevent req structure. It does not block + anything, it simply creates a request, sets a callback (foo done) and lets + the program continue +- Functions as a result of event. +- \b foo_done(...) - this function contains code providing for handling itself + and based upon its results, the request is set either as a done or, if an + error occurs, the request is set as a failure. +- \b foo_recv(...) - this function contains code which should, if demanded, + access the result data and make them further visible. The foo state should + be deallocated from memory when the request’s processing is over and + therefore all computed data up to this point would be lost. + +As was already mentioned, specific naming subsumes not only functions but also +the data themselves: + +- \b foo_state - this is a structure. It contains all the data necessary for + the asynchronous task. + +@subsection cr_req Creating a New Asynchronous Request + +The first step for working asynchronously is the allocation of memory +requirements. As in previous cases, the talloc context is required, upon which +the asynchronous request will be tied. The next step is the creation of the +request itself. + +@code +struct tevent_req* tevent_req_create (TALLOC_CTX *mem_ctx, void **pstate, #type) +@endcode + +The pstate is the pointer to the private data. The necessary amount of memory +(based on data type) is allocated during this call. Within this same memory +area all the data from the asynchronous request that need to be preserved for +some time should be kept. + +Dealing with a lack of memory + +The verification of the returned pointer against NULL is necessary in order to +identify a potential lack of memory. There is a special function which helps +with this check tevent_req_nomem(). + +It handles verification both of the talloc memory allocation and of the +associated tevent request, and is therefore a very useful function for avoiding +unexpected situations. It can easily be used when checking the availability of +further memory resources that are required for a tevent request. Imagine an +example where additional memory needs arise although no memory resources are +currently available. + +@code +bar = talloc(mem_ctx, struct foo); +if(tevent_req_nomem (bar, req)) { + // handling a problem +} +@endcode + +This code ensures that the variable bar, which contains NULL as a result of the +unsuccessful satisfaction of its memory requirements, is noticed, and also that +the tevent request req declares it exceeds memory capacity, which implies the +impossibility of finishing the request as originally programmed. + + +@subsection fini_req Finishing a Request + +Marking each request as finished is an essential principle of the tevent +library. Without marking the request as completed - either successfully or with +an error - the tevent loop could not let the appropriate callback be triggered. +It is important to understand that this would be a significant threat, because +it is not usually a question of one single function which prints some text on a +screen, but rather the request is itself probably just a link in a series of +other requests. Stopping one request would stop the others, memory resources +would not be freed, file descriptors might remain open, communication via +socket could be interrupted, and so on. Therefore it is important to think +about finishing requests, either successfully or not, and also to prepare +functions for all possible scenarios, so that the the callbacks do not process +data that are actually invalid or, even worse, in fact non-existent meaning +that a segmentation fault may arise. + +
        +
      • \b Manually - This is the most common type of finishing request. Calling +this function sets the request as a TEVENT_REQ_DONE. This is the only purpose +of this function and it should be used when everything went well. Typically it +is used within the done functions. + +@code +void tevent_req_done (struct tevent_req *req) +@endcode +Alternatively, the request can end up being unsuccessful. +@code +bool tevent_req_error (struct tevent_req *req, uint64_t error) +@endcode + +The second argument takes the number of an error (declared by the programmer, +for example in an enumerated variable). The function tevent_req_error() sets +the status of the request as a TEVENT_REQ_USER_ERROR and also stores the code +of error within the structure so it can be used, for example for debugging. The +function returns true, if marking the request as an error was processed with no +problem - value error passed to this function is not equal to 1.
      • + +
      • +Setting up a timeout for request - A request can be finished virtually, +or if the process takes too much time, it can be timed out. This is considered +as an error of the request and it leads to calling callback. In the +background, this timeout is set through a time event (described in +@subpage tevent_events ) which eventually triggers an operation marking the +request as a TEVENT_REQ_TIMED_OUT (can not be considered as successfully +finished). In case a time out was already set, this operation will overwrite it +with a new time value (so the timeout may be lengthened) and if everything is +set properly, it returns true. + +@code +bool tevent_req_set_endtime(struct tevent_req *req, + struct tevent_context *ev, + struct timeval endtime); +@endcode +
      • + + +
      • Premature Triggering - Imagine a situation in which some part of a +nested subrequest ended up with a failure and it is still required to trigger a +callback. Such as example might result from lack of memory leading to the +impossibility of allocating enough memory requirements for the event to start +processing another subrequest, or from a clear intention to skip other +procedures and trigger the callback regardless of other progress. In these +cases, the function tevent_req_post() is very handy and offers this option. + +@code +struct tevent_req* tevent_req_post (struct tevent_req *req, + struct tevent_context *ev); +@endcode + +A request finished in this way does not behave as a time event nor as a file +descriptor event but as a immediately scheduled event, and therefore it will be +treated according the description laid down in @subpage tevent_events . +
      • +
      + + +@section nested Subrequests - Nested Requests + +To create more complex and interconnected asynchronous operations, it is +possible to submerge a request into another and thus create a so-called +subrequest. Subrequests are not represented by any other special structure but +they are created from tevent_req_create(). This diagram shows the nesting and +life time of each request. The table below describes the same in words, and +shows the triggering of functions during the application run. + +Wrapper represents the trigger of the whole cascade of (sub)requests. It +may be e.g. a time or file descriptor event, or another request that was +created at a specific time by the function tevent_wakeup_send() which is a +slightly exceptional method of creating + +@code +struct tevent_req *tevent_wakeup_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct timeval wakeup_time); +@endcode + +By calling this function, it is possible to create a tevent request which is +actually the return value of this function. In summary, it sets the time value +of the tevent request’s creation. While using this function it is necessary to +use another function in the subrequest’s callback to check for any problems +tevent_wakeup_recv() ) + +@image html tevent_subrequest.png + +A comprehensive example of nested subrequests can be found in the file +echo_server.c. It implements a complete, self-contained echo server with no +dependencies but libevent and libtalloc. + +*/ diff --git a/ldb-2.0.8/lib/tevent/doc/tevent_thread.dox b/ldb-2.0.8/lib/tevent/doc/tevent_thread.dox new file mode 100644 index 0000000..875dae8 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/doc/tevent_thread.dox @@ -0,0 +1,322 @@ +/** +@page tevent_thread Chapter 6: Tevent with threads + +@section threads Tevent with threads + +In order to use tevent with threads, you must first understand +how to use the talloc library in threaded programs. For more +information about working with talloc, please visit talloc website where tutorial and +documentation are located. + +If a tevent context structure is talloced from a NULL, thread-safe talloc +context, then it can be safe to use in a threaded program. The function +talloc_disable_null_tracking() must be called from the initial +program thread before any talloc calls are made to ensure talloc is thread-safe. + +Each thread must create it's own tevent context structure as follows +tevent_context_init(NULL) and no talloc memory contexts +can be shared between threads. + +Separate threads using tevent in this way can communicate +by writing data into file descriptors that are being monitored +by a tevent context on another thread. For example (simplified +with no error handling): + +@code +Main thread: + +main() +{ + talloc_disable_null_tracking(); + + struct tevent_context *master_ev = tevent_context_init(NULL); + void *mem_ctx = talloc_new(master_ev); + + // Create file descriptor to monitor. + int pipefds[2]; + + pipe(pipefds); + + struct tevent_fd *fde = tevent_add_fd(master_ev, + mem_ctx, + pipefds[0], // read side of pipe + TEVENT_FD_READ, + pipe_read_handler, // callback function + private_data_pointer); + + // Create sub thread, pass pipefds[1] write side of pipe to it. + // The above code not shown here.. + + // Process events. + tevent_loop_wait(master_ev); + + // Cleanup if loop exits. + talloc_free(master_ev); +} + +@endcode + +When the subthread writes to pipefds[1], the function +pipe_read_handler() will be called in the main thread. + +@subsection More sophisticated use + +A popular way to use an event library within threaded programs +is to allow a sub-thread to asynchronously schedule a tevent_immediate +function call from the event loop of another thread. This can be built +out of the basic functions and isolation mechanisms of tevent, +but tevent also comes with some utility functions that make +this easier, so long as you understand the limitations that +using threads with talloc and tevent impose. + +To allow a tevent context to receive an asynchronous tevent_immediate +function callback from another thread, create a struct tevent_thread_proxy * +by calling @code + +struct tevent_thread_proxy *tevent_thread_proxy_create( + struct tevent_context *dest_ev_ctx); + +@endcode + +This function allocates the internal data structures to +allow asynchronous callbacks as a talloc child of the +struct tevent_context *, and returns a struct tevent_thread_proxy * +that can be passed to another thread. + +When you have finished receiving asynchronous callbacks, simply +talloc_free the struct tevent_thread_proxy *, or talloc_free +the struct tevent_context *, which will deallocate the resources +used. + +To schedule an asynchronous tevent_immediate function call from one +thread on the tevent loop of another thread, use +@code + +void tevent_thread_proxy_schedule(struct tevent_thread_proxy *tp, + struct tevent_immediate **pp_im, + tevent_immediate_handler_t handler, + void **pp_private_data); + +@endcode + +This function causes the function handler() +to be invoked as a tevent_immediate callback from the event loop +of the thread that created the struct tevent_thread_proxy * +(so the owning struct tevent_context * should be +long-lived and not in the process of being torn down). + +The struct tevent_thread_proxy object being +used here is a child of the event context of the target +thread. So external synchronization mechanisms must be +used to ensure that the target object is still in use +at the time of the tevent_thread_proxy_schedule() +call. In the example below, the request/response nature +of the communication ensures this. + +The struct tevent_immediate **pp_im passed into this function +should be a struct tevent_immediate * allocated on a talloc context +local to this thread, and will be reparented via talloc_move +to be owned by struct tevent_thread_proxy *tp. +*pp_im will be set to NULL on successful scheduling +of the tevent_immediate call. + +handler() will be called as a normal tevent_immediate +callback from the struct tevent_context * of the destination +event loop that created the struct tevent_thread_proxy * + +Returning from this functions does not mean that the handler +has been invoked, merely that it has been scheduled to be called in the +destination event loop. + +Because the calling thread does not wait for the +callback to be scheduled and run on the destination +thread, this is a fire-and-forget call. If you wish +confirmation of the handler() being +successfully invoked, you must ensure it replies to the +caller in some way. + +Because of asynchronous nature of this call, the nature +of the parameter passed to the destination thread has some +restructions. If you don't need parameters, merely pass +NULL as the value of +void **pp_private_data. + +If you wish to pass a pointer to data between the threads, +it MUST be a pointer to a talloced pointer, which is +not part of a talloc-pool, and it must not have a destructor +attached. The ownership of the memory pointed to will +be passed from the calling thread to the tevent library, +and if the receiving thread does not talloc-reparent +it to its own contexts, it will be freed once the +handler is called. + +On success, *pp_private will be NULL +to signify the talloc memory ownership has been moved. + +In practice for message passing between threads in +event loops these restrictions are not very onerous. + +The easiest way to to a request-reply pair between +tevent loops on different threads is to pass the +parameter block of memory back and forth using +a reply tevent_thread_proxy_schedule() +call. + +Here is an example (without error checking for +simplicity): + +@code +------------------------------------------------ +// Master thread. + +main() +{ + // Make talloc thread-safe. + + talloc_disable_null_tracking(); + + // Create the master event context. + + struct tevent_context *master_ev = tevent_context_init(NULL); + + // Create the master thread proxy to allow it to receive + // async callbacks from other threads. + + struct tevent_thread_proxy *master_tp = + tevent_thread_proxy_create(master_ev); + + // Create sub-threads, passing master_tp in + // some way to them. + // This code not shown.. + + // Process events. + // Function master_callback() below + // will be invoked on this thread on + // master_ev event context. + + tevent_loop_wait(master_ev); + + // Cleanup if loop exits. + + talloc_free(master_ev); +} + +// Data passed between threads. +struct reply_state { + struct tevent_thread_proxy *reply_tp; + pthread_t thread_id; + bool *p_finished; +}; + +// Callback Called in child thread context. + +static void thread_callback(struct tevent_context *ev, + struct tevent_immediate *im, + void *private_ptr) +{ + // Move the ownership of what private_ptr + // points to from the tevent library back to this thread. + + struct reply_state *rsp = + talloc_get_type_abort(private_ptr, struct reply_state); + + talloc_steal(ev, rsp); + + *rsp->p_finished = true; + + // im will be talloc_freed on return from this call. + // but rsp will not. +} + +// Callback Called in master thread context. + +static void master_callback(struct tevent_context *ev, + struct tevent_immediate *im, + void *private_ptr) +{ + // Move the ownership of what private_ptr + // points to from the tevent library to this thread. + + struct reply_state *rsp = + talloc_get_type_abort(private_ptr, struct reply_state); + + talloc_steal(ev, rsp); + + printf("Callback from thread %s\n", thread_id_to_string(rsp->thread_id)); + + /* Now reply to the thread ! */ + tevent_thread_proxy_schedule(rsp->reply_tp, + &im, + thread_callback, + &rsp); + + // Note - rsp and im are now NULL as the tevent library + // owns the memory. +} + +// Child thread. + +static void *thread_fn(void *private_ptr) +{ + struct tevent_thread_proxy *master_tp = + talloc_get_type_abort(private_ptr, struct tevent_thread_proxy); + bool finished = false; + int ret; + + // Create our own event context. + + struct tevent_context *ev = tevent_context_init(NULL); + + // Create the local thread proxy to allow us to receive + // async callbacks from other threads. + + struct tevent_thread_proxy *local_tp = + tevent_thread_proxy_create(master_ev); + + // Setup the data to send. + + struct reply_state *rsp = talloc(ev, struct reply_state); + + rsp->reply_tp = local_tp; + rsp->thread_id = pthread_self(); + rsp->p_finished = &finished; + + // Create the immediate event to use. + + struct tevent_immediate *im = tevent_create_immediate(ev); + + // Call the master thread. + + tevent_thread_proxy_schedule(master_tp, + &im, + master_callback, + &rsp); + + // Note - rsp and im are now NULL as the tevent library + // owns the memory. + + // Wait for the reply. + + while (!finished) { + tevent_loop_once(ev); + } + + // Cleanup. + + talloc_free(ev); + return NULL; +} + +@endcode + +Note this doesn't have to be a master-subthread communication. +Any thread that has access to the struct tevent_thread_proxy * +pointer of another thread that has called tevent_thread_proxy_create() + can send an async tevent_immediate request. + +But remember the caveat that external synchronization must be used +to ensure the target struct tevent_thread_proxy * object +exists at the time of the tevent_thread_proxy_schedule() +call or unreproducible crashes will result. +*/ diff --git a/ldb-2.0.8/lib/tevent/doc/tevent_tutorial.dox b/ldb-2.0.8/lib/tevent/doc/tevent_tutorial.dox new file mode 100644 index 0000000..207a244 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/doc/tevent_tutorial.dox @@ -0,0 +1,22 @@ +/** +@page tevent_tutorial The Tutorial + +@section tevent_tutorial_introduction Introduction + +Tutorial describing working with tevent library. + +@section tevent_tutorial_toc Table of contents + +@subpage tevent_context + +@subpage tevent_events + +@subpage tevent_data + +@subpage tevent_request + +@subpage tevent_queue + +@subpage tevent_thread + +*/ diff --git a/ldb-2.0.8/lib/tevent/doc/tutorials.dox b/ldb-2.0.8/lib/tevent/doc/tutorials.dox new file mode 100644 index 0000000..e8beed7 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/doc/tutorials.dox @@ -0,0 +1,43 @@ +/** + * @page tevent_queue_tutorial The tevent_queue tutorial + * + * @section Introduction + * + * A tevent_queue is used to queue up async requests that must be + * serialized. For example writing buffers into a socket must be + * serialized. Writing a large lump of data into a socket can require + * multiple write(2) or send(2) system calls. If more than one async + * request is outstanding to write large buffers into a socket, every + * request must individually be completed before the next one begins, + * even if multiple syscalls are required. + * + * To do this, every socket gets assigned a tevent_queue struct. + * + * Creating a serialized async request follows the usual convention to + * return a tevent_req structure with an embedded state structure. To + * serialize the work the requests is about to so, instead of directly + * starting or doing that work, tevent_queue_add must be called. When it + * is time for the serialized async request to do its work, the trigger + * callback function tevent_queue_add was given is called. In the example + * of writing to a socket, the trigger is called when the write request + * can begin accessing the socket. + * + * How does this engine work behind the scenes? When the queue is empty, + * tevent_queue_add schedules an immediate call to the trigger + * callback. The trigger callback starts its work, likely by starting + * other async subrequests. While these async subrequests are working, + * more requests can accumulate in the queue by tevent_queue_add. While + * there is no function to explicitly trigger the next waiter in line, it + * still works: When the active request in the queue is done, it will be + * destroyed by talloc_free. Talloc_free of an serialized async request + * that had been added to a queue will trigger the next request in the + * queue via a talloc destructor attached to a child of the serialized + * request. This way the queue will be kept busy when an async request + * finishes. + * + * @section Example + * + * @code + * Metze: Please add a code example here. + * @endcode + */ diff --git a/ldb-2.0.8/lib/tevent/doxy.config b/ldb-2.0.8/lib/tevent/doxy.config new file mode 100644 index 0000000..76d8b4c --- /dev/null +++ b/ldb-2.0.8/lib/tevent/doxy.config @@ -0,0 +1,1908 @@ +# Doxyfile 1.8.4 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed +# in front of the TAG it is preceding . +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = tevent + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 0.9.8 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian, +# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, +# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. Note that you specify absolute paths here, but also +# relative paths, which will be relative from the directory where doxygen is +# started. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, +# and language is one of the parsers supported by doxygen: IDL, Java, +# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, +# C++. For instance to make doxygen treat .inc files as Fortran files (default +# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note +# that for custom extensions you also need to set FILE_PATTERNS otherwise the +# files are not read by doxygen. + +EXTENSION_MAPPING = + +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES (the +# default) will make doxygen replace the get and set methods by a property in +# the documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields or simple typedef fields will be shown +# inline in the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO (the default), structs, classes, and unions are shown on a separate +# page (for HTML and Man pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can +# be an expensive process and often the same symbol appear multiple times in +# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too +# small doxygen will become slower. If the cache is too large, memory is wasted. +# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid +# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536 +# symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = NO + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = YES + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if section-label ... \endif +# and \cond section-label ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. Do not use +# file names with spaces, bibtex cannot handle them. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = . \ + doc + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.cpp \ + *.cc \ + *.c \ + *.h \ + *.hh \ + *.hpp \ + *.dox + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = */.git/* + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = doc/img + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be ignored. +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C, C++ and Fortran comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If left blank doxygen will +# generate a default style sheet. Note that it is recommended to use +# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this +# tag will in the future become obsolete. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional +# user-defined cascading style sheet that is included after the standard +# style sheets created by doxygen. Using this option one can overrule +# certain style aspects. This is preferred over using HTML_STYLESHEET +# since it does not replace the standard style sheet and is therefor more +# robust against future updates. Doxygen will copy the style sheet file to +# the output directory. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely +# identify the documentation publisher. This should be a reverse domain-name +# style string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = NONE + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and +# SVG. The default value is HTML-CSS, which is slower, but has the best +# compatibility. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. +# However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript +# pieces of code that will be used on startup of the MathJax code. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = NO + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using Javascript. +# There are two flavours of web server based search depending on the +# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for +# searching and an index file used by the script. When EXTERNAL_SEARCH is +# enabled the indexing and searching needs to be provided by external tools. +# See the manual for details. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain +# the search results. Doxygen ships with an example indexer (doxyindexer) and +# search engine (doxysearch.cgi) which are based on the open source search +# engine library Xapian. See the manual for configuration details. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will returned the search results when EXTERNAL_SEARCH is enabled. +# Doxygen ships with an example search engine (doxysearch) which is based on +# the open source search engine library Xapian. See the manual for configuration +# details. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id +# of to a relative location where the documentation can be found. +# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... + +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4 will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images +# or other source files which should be copied to the LaTeX output directory. +# Note that the files will be copied as-is; there are no commands or markers +# available. + +LATEX_EXTRA_FILES = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = YES + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +# If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files +# that can be used to generate PDF. + +GENERATE_DOCBOOK = NO + +# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in +# front of it. If left blank docbook will be used as the default path. + +DOCBOOK_OUTPUT = docbook + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = YES + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = DOXYGEN \ + PRINTF_ATTRIBUTE(x,y)= + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed +# in the related pages index. If set to NO, only the current project's +# pages will be listed. + +EXTERNAL_PAGES = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# manageable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = YES + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/ldb-2.0.8/lib/tevent/echo_server.c b/ldb-2.0.8/lib/tevent/echo_server.c new file mode 100644 index 0000000..f93d8bc --- /dev/null +++ b/ldb-2.0.8/lib/tevent/echo_server.c @@ -0,0 +1,667 @@ +/** + ** NOTE! The following liberal license applies to this sample file only. + ** This does NOT imply that all of Samba is released under this license. + ** + ** This file is meant as a starting point for libtevent users to be used + ** in any program linking against the LGPL licensed libtevent. + **/ + +/* + * This file is being made available by the Samba Team under the following + * license: + * + * Permission to use, copy, modify, and distribute this sample file for any + * purpose is hereby granted without fee. + * + * This work is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "tevent.h" +#include "talloc.h" + +/** + * @brief Helper function to get a useful unix error from tevent_req + */ + +static bool tevent_req_is_unix_error(struct tevent_req *req, int *perrno) +{ + enum tevent_req_state state; + uint64_t err; + + if (!tevent_req_is_error(req, &state, &err)) { + return false; + } + switch (state) { + case TEVENT_REQ_TIMED_OUT: + *perrno = ETIMEDOUT; + break; + case TEVENT_REQ_NO_MEMORY: + *perrno = ENOMEM; + break; + case TEVENT_REQ_USER_ERROR: + *perrno = err; + break; + default: + *perrno = EINVAL; + break; + } + return true; +} + +/** + * @brief Wrapper around accept(2) + */ + +struct accept_state { + struct tevent_fd *fde; + int listen_sock; + socklen_t addrlen; + struct sockaddr_storage addr; + int sock; +}; + +static void accept_handler(struct tevent_context *ev, struct tevent_fd *fde, + uint16_t flags, void *private_data); + +static struct tevent_req *accept_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int listen_sock) +{ + struct tevent_req *req; + struct accept_state *state; + + req = tevent_req_create(mem_ctx, &state, struct accept_state); + if (req == NULL) { + return NULL; + } + + state->listen_sock = listen_sock; + + state->fde = tevent_add_fd(ev, state, listen_sock, TEVENT_FD_READ, + accept_handler, req); + if (tevent_req_nomem(state->fde, req)) { + return tevent_req_post(req, ev); + } + return req; +} + +static void accept_handler(struct tevent_context *ev, struct tevent_fd *fde, + uint16_t flags, void *private_data) +{ + struct tevent_req *req = talloc_get_type_abort( + private_data, struct tevent_req); + struct accept_state *state = tevent_req_data(req, struct accept_state); + int ret; + + TALLOC_FREE(state->fde); + + if ((flags & TEVENT_FD_READ) == 0) { + tevent_req_error(req, EIO); + return; + } + state->addrlen = sizeof(state->addr); + + ret = accept(state->listen_sock, + (struct sockaddr *)&state->addr, + &state->addrlen); + if (ret == -1) { + tevent_req_error(req, errno); + return; + } + smb_set_close_on_exec(ret); + state->sock = ret; + tevent_req_done(req); +} + +static int accept_recv(struct tevent_req *req, struct sockaddr *paddr, + socklen_t *paddrlen, int *perr) +{ + struct accept_state *state = tevent_req_data(req, struct accept_state); + int err; + + if (tevent_req_is_unix_error(req, &err)) { + if (perr != NULL) { + *perr = err; + } + return -1; + } + if (paddr != NULL) { + memcpy(paddr, &state->addr, state->addrlen); + } + if (paddrlen != NULL) { + *paddrlen = state->addrlen; + } + return state->sock; +} + +/** + * @brief Wrapper around read(2) + */ + +struct read_state { + struct tevent_fd *fde; + int fd; + void *buf; + size_t count; + + ssize_t nread; +}; + +static void read_handler(struct tevent_context *ev, struct tevent_fd *fde, + uint16_t flags, void *private_data); + +static struct tevent_req *read_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, void *buf, size_t count) +{ + struct tevent_req *req; + struct read_state *state; + + req = tevent_req_create(mem_ctx, &state, struct read_state); + if (req == NULL) { + return NULL; + } + + state->fd = fd; + state->buf = buf; + state->count = count; + + state->fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, + read_handler, req); + if (tevent_req_nomem(state->fde, req)) { + return tevent_req_post(req, ev); + } + return req; +} + +static void read_handler(struct tevent_context *ev, struct tevent_fd *fde, + uint16_t flags, void *private_data) +{ + struct tevent_req *req = talloc_get_type_abort( + private_data, struct tevent_req); + struct read_state *state = tevent_req_data(req, struct read_state); + ssize_t ret; + + TALLOC_FREE(state->fde); + + if ((flags & TEVENT_FD_READ) == 0) { + tevent_req_error(req, EIO); + return; + } + + ret = read(state->fd, state->buf, state->count); + if (ret == -1) { + tevent_req_error(req, errno); + return; + } + state->nread = ret; + tevent_req_done(req); +} + +static ssize_t read_recv(struct tevent_req *req, int *perr) +{ + struct read_state *state = tevent_req_data(req, struct read_state); + int err; + + if (tevent_req_is_unix_error(req, &err)) { + if (perr != NULL) { + *perr = err; + } + return -1; + } + return state->nread; +} + +/** + * @brief Wrapper around write(2) + */ + +struct write_state { + struct tevent_fd *fde; + int fd; + const void *buf; + size_t count; + + ssize_t nwritten; +}; + +static void write_handler(struct tevent_context *ev, struct tevent_fd *fde, + uint16_t flags, void *private_data); + +static struct tevent_req *write_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, const void *buf, size_t count) +{ + struct tevent_req *req; + struct write_state *state; + + req = tevent_req_create(mem_ctx, &state, struct write_state); + if (req == NULL) { + return NULL; + } + + state->fd = fd; + state->buf = buf; + state->count = count; + + state->fde = tevent_add_fd(ev, state, fd, TEVENT_FD_WRITE, + write_handler, req); + if (tevent_req_nomem(state->fde, req)) { + return tevent_req_post(req, ev); + } + return req; +} + +static void write_handler(struct tevent_context *ev, struct tevent_fd *fde, + uint16_t flags, void *private_data) +{ + struct tevent_req *req = talloc_get_type_abort( + private_data, struct tevent_req); + struct write_state *state = tevent_req_data(req, struct write_state); + ssize_t ret; + + TALLOC_FREE(state->fde); + + if ((flags & TEVENT_FD_WRITE) == 0) { + tevent_req_error(req, EIO); + return; + } + + ret = write(state->fd, state->buf, state->count); + if (ret == -1) { + tevent_req_error(req, errno); + return; + } + state->nwritten = ret; + tevent_req_done(req); +} + +static ssize_t write_recv(struct tevent_req *req, int *perr) +{ + struct write_state *state = tevent_req_data(req, struct write_state); + int err; + + if (tevent_req_is_unix_error(req, &err)) { + if (perr != NULL) { + *perr = err; + } + return -1; + } + return state->nwritten; +} + +/** + * @brief Wrapper function that deals with short writes + */ + +struct writeall_state { + struct tevent_context *ev; + int fd; + const void *buf; + size_t count; + size_t nwritten; +}; + +static void writeall_done(struct tevent_req *subreq); + +static struct tevent_req *writeall_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, const void *buf, size_t count) +{ + struct tevent_req *req, *subreq; + struct writeall_state *state; + + req = tevent_req_create(mem_ctx, &state, struct writeall_state); + if (req == NULL) { + return NULL; + } + state->ev = ev; + state->fd = fd; + state->buf = buf; + state->count = count; + state->nwritten = 0; + + subreq = write_send(state, state->ev, state->fd, + ((char *)state->buf)+state->nwritten, + state->count - state->nwritten); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, writeall_done, req); + return req; +} + +static void writeall_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct writeall_state *state = tevent_req_data( + req, struct writeall_state); + ssize_t nwritten; + int err = 0; + + nwritten = write_recv(subreq, &err); + TALLOC_FREE(subreq); + if (nwritten == -1) { + tevent_req_error(req, err); + return; + } + + state->nwritten += nwritten; + + if (state->nwritten < state->count) { + subreq = write_send(state, state->ev, state->fd, + ((char *)state->buf)+state->nwritten, + state->count - state->nwritten); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, writeall_done, req); + return; + } + tevent_req_done(req); +} + +static ssize_t writeall_recv(struct tevent_req *req, int *perr) +{ + struct writeall_state *state = tevent_req_data( + req, struct writeall_state); + int err; + + if (tevent_req_is_unix_error(req, &err)) { + if (perr != NULL) { + *perr = err; + } + return -1; + } + return state->nwritten; +} + +/** + * @brief Async echo handler code dealing with one client + */ + +struct echo_state { + struct tevent_context *ev; + int fd; + uint8_t *buf; +}; + +static int echo_state_destructor(struct echo_state *s); +static void echo_read_done(struct tevent_req *subreq); +static void echo_writeall_done(struct tevent_req *subreq); + +static struct tevent_req *echo_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int fd, size_t bufsize) +{ + struct tevent_req *req, *subreq; + struct echo_state *state; + + req = tevent_req_create(mem_ctx, &state, struct echo_state); + if (req == NULL) { + return NULL; + } + state->ev = ev; + state->fd = fd; + + talloc_set_destructor(state, echo_state_destructor); + + state->buf = talloc_array(state, uint8_t, bufsize); + if (tevent_req_nomem(state->buf, req)) { + return tevent_req_post(req, ev); + } + + subreq = read_send(state, state->ev, state->fd, + state->buf, talloc_get_size(state->buf)); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, echo_read_done, req); + return req; +} + +static int echo_state_destructor(struct echo_state *s) +{ + if (s->fd != -1) { + printf("Closing client fd %d\n", s->fd); + close(s->fd); + s->fd = -1; + } + return 0; +} + +static void echo_read_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct echo_state *state = tevent_req_data( + req, struct echo_state); + ssize_t nread; + int err; + + nread = read_recv(subreq, &err); + TALLOC_FREE(subreq); + if (nread == -1) { + tevent_req_error(req, err); + return; + } + if (nread == 0) { + tevent_req_done(req); + return; + } + + subreq = writeall_send(state, state->ev, state->fd, state->buf, nread); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, echo_writeall_done, req); +} + +static void echo_writeall_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct echo_state *state = tevent_req_data( + req, struct echo_state); + ssize_t nwritten; + int err; + + nwritten = writeall_recv(subreq, &err); + TALLOC_FREE(subreq); + if (nwritten == -1) { + if (err == EPIPE) { + tevent_req_done(req); + return; + } + tevent_req_error(req, err); + return; + } + + subreq = read_send(state, state->ev, state->fd, + state->buf, talloc_get_size(state->buf)); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, echo_read_done, req); +} + +static bool echo_recv(struct tevent_req *req, int *perr) +{ + int err; + + if (tevent_req_is_unix_error(req, &err)) { + *perr = err; + return false; + } + return true; +} + +/** + * @brief Full echo handler code accepting and handling clients + */ + +struct echo_server_state { + struct tevent_context *ev; + int listen_sock; +}; + +static void echo_server_accepted(struct tevent_req *subreq); +static void echo_server_client_done(struct tevent_req *subreq); + +static struct tevent_req *echo_server_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + int listen_sock) +{ + struct tevent_req *req, *subreq; + struct echo_server_state *state; + + req = tevent_req_create(mem_ctx, &state, + struct echo_server_state); + if (req == NULL) { + return NULL; + } + state->ev = ev; + state->listen_sock = listen_sock; + + subreq = accept_send(state, state->ev, state->listen_sock); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, echo_server_accepted, req); + return req; +} + +static void echo_server_accepted(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct echo_server_state *state = tevent_req_data( + req, struct echo_server_state); + int sock, err; + + sock = accept_recv(subreq, NULL, NULL, &err); + TALLOC_FREE(subreq); + if (sock == -1) { + tevent_req_error(req, err); + return; + } + + printf("new client fd %d\n", sock); + + subreq = echo_send(state, state->ev, sock, 100); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, echo_server_client_done, req); + + subreq = accept_send(state, state->ev, state->listen_sock); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, echo_server_accepted, req); +} + +static void echo_server_client_done(struct tevent_req *subreq) +{ + bool ret; + int err; + + ret = echo_recv(subreq, &err); + TALLOC_FREE(subreq); + + if (ret) { + printf("Client done\n"); + } else { + printf("Client failed: %s\n", strerror(err)); + } +} + +static bool echo_server_recv(struct tevent_req *req, int *perr) +{ + int err; + + if (tevent_req_is_unix_error(req, &err)) { + *perr = err; + return false; + } + return true; +} + +int main(int argc, const char **argv) +{ + int ret, port, listen_sock, err; + struct tevent_context *ev; + struct sockaddr_in addr; + struct tevent_req *req; + bool result; + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + + port = atoi(argv[1]); + + printf("listening on port %d\n", port); + + listen_sock = socket(AF_INET, SOCK_STREAM, 0); + + if (listen_sock == -1) { + perror("socket() failed"); + exit(1); + } + + addr = (struct sockaddr_in) { + .sin_family = AF_INET, + .sin_port = htons(port) + }; + + ret = bind(listen_sock, (struct sockaddr *)&addr, sizeof(addr)); + if (ret == -1) { + perror("bind() failed"); + exit(1); + } + + ret = listen(listen_sock, 5); + if (ret == -1) { + perror("listen() failed"); + exit(1); + } + + ev = tevent_context_init(NULL); + if (ev == NULL) { + fprintf(stderr, "tevent_context_init failed\n"); + exit(1); + } + + req = echo_server_send(ev, ev, listen_sock); + if (req == NULL) { + fprintf(stderr, "echo_server_send failed\n"); + exit(1); + } + + if (!tevent_req_poll(req, ev)) { + perror("tevent_req_poll() failed"); + exit(1); + } + + result = echo_server_recv(req, &err); + TALLOC_FREE(req); + if (!result) { + fprintf(stderr, "echo_server failed: %s\n", strerror(err)); + exit(1); + } + + return 0; +} diff --git a/ldb-2.0.8/lib/tevent/pytevent.c b/ldb-2.0.8/lib/tevent/pytevent.c new file mode 100644 index 0000000..73a9bd7 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/pytevent.c @@ -0,0 +1,945 @@ +/* + Unix SMB/CIFS implementation. + Python bindings for tevent + + Copyright (C) Jelmer Vernooij 2010 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include +#include "replace.h" +#include + +#if PY_MAJOR_VERSION >= 3 +#define PyInt_FromLong PyLong_FromLong +#endif + +/* discard signature of 'func' in favour of 'target_sig' */ +#define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func + +void init_tevent(void); + +typedef struct { + PyObject_HEAD + struct tevent_context *ev; +} TeventContext_Object; + +typedef struct { + PyObject_HEAD + struct tevent_queue *queue; +} TeventQueue_Object; + +typedef struct { + PyObject_HEAD + struct tevent_req *req; +} TeventReq_Object; + +typedef struct { + PyObject_HEAD + struct tevent_signal *signal; +} TeventSignal_Object; + +typedef struct { + PyObject_HEAD + struct tevent_timer *timer; + PyObject *callback; +} TeventTimer_Object; + +typedef struct { + PyObject_HEAD + struct tevent_fd *fd; +} TeventFd_Object; + +static PyTypeObject TeventContext_Type; +static PyTypeObject TeventReq_Type; +static PyTypeObject TeventQueue_Type; +static PyTypeObject TeventSignal_Type; +static PyTypeObject TeventTimer_Type; +static PyTypeObject TeventFd_Type; + +static int py_context_init(struct tevent_context *ev) +{ + /* FIXME */ + return 0; +} + +static struct tevent_fd *py_add_fd(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + int fd, uint16_t flags, + tevent_fd_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + /* FIXME */ + return NULL; +} + +static void py_set_fd_close_fn(struct tevent_fd *fde, + tevent_fd_close_fn_t close_fn) +{ + /* FIXME */ +} + +static uint16_t py_get_fd_flags(struct tevent_fd *fde) +{ + /* FIXME */ + return 0; +} + +static void py_set_fd_flags(struct tevent_fd *fde, uint16_t flags) +{ + /* FIXME */ +} + +/* timed_event functions */ +static struct tevent_timer *py_add_timer(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + struct timeval next_event, + tevent_timer_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + /* FIXME */ + return NULL; +} + +/* immediate event functions */ +static void py_schedule_immediate(struct tevent_immediate *im, + struct tevent_context *ev, + tevent_immediate_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + /* FIXME */ +} + +/* signal functions */ +static struct tevent_signal *py_add_signal(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + int signum, int sa_flags, + tevent_signal_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + /* FIXME */ + return NULL; +} + +/* loop functions */ +static int py_loop_once(struct tevent_context *ev, const char *location) +{ + /* FIXME */ + return 0; +} + +static int py_loop_wait(struct tevent_context *ev, const char *location) +{ + /* FIXME */ + return 0; +} + +const static struct tevent_ops py_tevent_ops = { + .context_init = py_context_init, + .add_fd = py_add_fd, + .set_fd_close_fn = py_set_fd_close_fn, + .get_fd_flags = py_get_fd_flags, + .set_fd_flags = py_set_fd_flags, + .add_timer = py_add_timer, + .schedule_immediate = py_schedule_immediate, + .add_signal = py_add_signal, + .loop_wait = py_loop_wait, + .loop_once = py_loop_once, +}; + +static PyObject *py_register_backend(PyObject *self, PyObject *args) +{ + PyObject *name, *py_backend; + + if (!PyArg_ParseTuple(args, "O", &py_backend)) + return NULL; + + name = PyObject_GetAttrString(py_backend, "name"); + if (name == NULL) { + PyErr_SetNone(PyExc_AttributeError); + return NULL; + } + + if (!PyUnicode_Check(name)) { + PyErr_SetNone(PyExc_TypeError); + Py_DECREF(name); + return NULL; + } + + if (!tevent_register_backend(PyUnicode_AsUTF8(name), &py_tevent_ops)) { /* FIXME: What to do with backend */ + PyErr_SetNone(PyExc_RuntimeError); + Py_DECREF(name); + return NULL; + } + + Py_DECREF(name); + + Py_RETURN_NONE; +} + +static PyObject *py_tevent_context_reinitialise(TeventContext_Object *self, + PyObject *Py_UNUSED(ignored)) +{ + int ret = tevent_re_initialise(self->ev); + if (ret != 0) { + PyErr_SetNone(PyExc_RuntimeError); + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject *py_tevent_queue_stop(TeventQueue_Object *self, + PyObject *Py_UNUSED(ignored)) +{ + tevent_queue_stop(self->queue); + Py_RETURN_NONE; +} + +static PyObject *py_tevent_queue_start(TeventQueue_Object *self, + PyObject *Py_UNUSED(ignored)) +{ + tevent_queue_start(self->queue); + Py_RETURN_NONE; +} + +static void py_queue_trigger(struct tevent_req *req, void *private_data) +{ + PyObject *callback = private_data, *ret; + + ret = PyObject_CallFunction(callback, discard_const_p(char, "")); + Py_XDECREF(ret); +} + +static PyObject *py_tevent_queue_add(TeventQueue_Object *self, PyObject *args) +{ + TeventContext_Object *py_ev; + TeventReq_Object *py_req; + PyObject *trigger; + bool ret; + + if (!PyArg_ParseTuple(args, "O!O!O", + &TeventContext_Type, &py_ev, + &TeventReq_Type, &py_req, + &trigger)) + return NULL; + + Py_INCREF(trigger); + + ret = tevent_queue_add(self->queue, py_ev->ev, py_req->req, + py_queue_trigger, trigger); + if (!ret) { + PyErr_SetString(PyExc_RuntimeError, "queue add failed"); + Py_DECREF(trigger); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyMethodDef py_tevent_queue_methods[] = { + { "stop", (PyCFunction)py_tevent_queue_stop, + METH_NOARGS, + "S.stop()" }, + { "start", (PyCFunction)py_tevent_queue_start, + METH_NOARGS, + "S.start()" }, + { "add", (PyCFunction)py_tevent_queue_add, METH_VARARGS, + "S.add(ctx, req, trigger, baton)" }, + { NULL }, +}; + +static PyObject *py_tevent_context_wakeup_send(PyObject *self, PyObject *args) +{ + /* FIXME */ + + Py_RETURN_NONE; +} + +static PyObject *py_tevent_context_loop_wait(TeventContext_Object *self, + PyObject *Py_UNUSED(ignored)) +{ + if (tevent_loop_wait(self->ev) != 0) { + PyErr_SetNone(PyExc_RuntimeError); + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject *py_tevent_context_loop_once(TeventContext_Object *self, + PyObject *Py_UNUSED(ignored)) +{ + if (tevent_loop_once(self->ev) != 0) { + PyErr_SetNone(PyExc_RuntimeError); + return NULL; + } + Py_RETURN_NONE; +} + +static void py_tevent_signal_handler(struct tevent_context *ev, + struct tevent_signal *se, + int signum, + int count, + void *siginfo, + void *private_data) +{ + PyObject *callback = (PyObject *)private_data, *ret; + + ret = PyObject_CallFunction(callback, discard_const_p(char, "ii"), signum, count); + Py_XDECREF(ret); +} + +static void py_tevent_signal_dealloc(TeventSignal_Object *self) +{ + talloc_free(self->signal); + PyObject_Del(self); +} + +static PyTypeObject TeventSignal_Type = { + .tp_name = "tevent.Signal", + .tp_basicsize = sizeof(TeventSignal_Object), + .tp_dealloc = (destructor)py_tevent_signal_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT, +}; + +static PyObject *py_tevent_context_add_signal(TeventContext_Object *self, PyObject *args) +{ + int signum, sa_flags; + PyObject *handler; + struct tevent_signal *sig; + TeventSignal_Object *ret; + + if (!PyArg_ParseTuple(args, "iiO", &signum, &sa_flags, &handler)) + return NULL; + + Py_INCREF(handler); + sig = tevent_add_signal(self->ev, NULL, signum, sa_flags, + py_tevent_signal_handler, handler); + + ret = PyObject_New(TeventSignal_Object, &TeventSignal_Type); + if (ret == NULL) { + PyErr_NoMemory(); + talloc_free(sig); + return NULL; + } + + ret->signal = sig; + + return (PyObject *)ret; +} + +static void py_timer_handler(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval current_time, + void *private_data) +{ + TeventTimer_Object *self = private_data; + PyObject *ret; + + ret = PyObject_CallFunction(self->callback, discard_const_p(char, "l"), te); + if (ret == NULL) { + /* No Python stack to propagate exception to; just print traceback */ + PyErr_PrintEx(0); + } + Py_XDECREF(ret); +} + +static void py_tevent_timer_dealloc(TeventTimer_Object *self) +{ + if (self->timer) { + talloc_free(self->timer); + } + Py_DECREF(self->callback); + PyObject_Del(self); +} + +static int py_tevent_timer_traverse(TeventTimer_Object *self, visitproc visit, void *arg) +{ + Py_VISIT(self->callback); + return 0; +} + +static PyObject* py_tevent_timer_get_active(TeventTimer_Object *self, + PyObject *Py_UNUSED(ignored)) +{ + return PyBool_FromLong(self->timer != NULL); +} + +struct PyGetSetDef py_tevent_timer_getset[] = { + { + .name = discard_const_p(char, "active"), + .get = (getter)py_tevent_timer_get_active, + .doc = discard_const_p(char, "true if the timer is scheduled to run"), + }, + {NULL}, +}; + +static PyTypeObject TeventTimer_Type = { + .tp_name = "tevent.Timer", + .tp_basicsize = sizeof(TeventTimer_Object), + .tp_dealloc = (destructor)py_tevent_timer_dealloc, + .tp_traverse = (traverseproc)py_tevent_timer_traverse, + .tp_getset = py_tevent_timer_getset, + .tp_flags = Py_TPFLAGS_DEFAULT, +}; + +struct TeventTimer_Object_ref { + TeventTimer_Object *obj; +}; + +static int TeventTimer_Object_ref_destructor(struct TeventTimer_Object_ref *ref) +{ + ref->obj->timer = NULL; + Py_DECREF(ref->obj); + return 0; +} + +static PyObject *py_tevent_context_add_timer_internal(TeventContext_Object *self, + struct timeval next_event, + PyObject *callback) +{ + /* Ownership notes: + * + * There are 5 pieces in play; two tevent contexts and 3 Python objects: + * - The tevent timer + * - The tevent context + * - The Python context -- "self" + * - The Python timer (TeventTimer_Object) -- "ret" + * - The Python callback function -- "callback" + * + * We only use the Python context for getting the tevent context, + * afterwards it can be destroyed. + * + * The tevent context owns the tevent timer. + * + * The tevent timer holds a reference to the Python timer, so the Python + * timer must always outlive the tevent timer. + * The Python timer has a pointer to the tevent timer; a destructor is + * used to set this to NULL when the tevent timer is deallocated. + * + * The tevent timer can be deallocated in these cases: + * 1) when the context is destroyed + * 2) after the event fires + * Posssibly, API might be added to cancel (free the tevent timer). + * + * The Python timer holds a reference to the callback. + */ + TeventTimer_Object *ret; + struct TeventTimer_Object_ref *ref; + + ret = PyObject_New(TeventTimer_Object, &TeventTimer_Type); + if (ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + Py_INCREF(callback); + ret->callback = callback; + ret->timer = tevent_add_timer(self->ev, NULL, next_event, py_timer_handler, + ret); + if (ret->timer == NULL) { + Py_DECREF(ret); + PyErr_SetString(PyExc_RuntimeError, "Could not initialize timer"); + return NULL; + } + ref = talloc(ret->timer, struct TeventTimer_Object_ref); + if (ref == NULL) { + talloc_free(ret->timer); + Py_DECREF(ret); + PyErr_SetString(PyExc_RuntimeError, "Could not initialize timer"); + return NULL; + } + Py_INCREF(ret); + ref->obj = ret; + + talloc_set_destructor(ref, TeventTimer_Object_ref_destructor); + + return (PyObject *)ret; +} + +static PyObject *py_tevent_context_add_timer(TeventContext_Object *self, PyObject *args) +{ + struct timeval next_event; + PyObject *callback; + double secs, usecs; + if (!PyArg_ParseTuple(args, "dO", &secs, &callback)){ + return NULL; + } + next_event.tv_sec = secs; + usecs = (secs - next_event.tv_sec) * 1000000.0; + next_event.tv_usec = usecs; + return py_tevent_context_add_timer_internal(self, next_event, callback); +} + +static PyObject *py_tevent_context_add_timer_offset(TeventContext_Object *self, PyObject *args) +{ + struct timeval next_event; + double offset; + int seconds; + PyObject *callback; + if (!PyArg_ParseTuple(args, "dO", &offset, &callback)) + return NULL; + + seconds = offset; + offset -= seconds; + next_event = tevent_timeval_current_ofs(seconds, (int)(offset*1000000)); + return py_tevent_context_add_timer_internal(self, next_event, callback); +} + +static void py_fd_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, + void *private_data) +{ + PyObject *callback = private_data, *ret; + + ret = PyObject_CallFunction(callback, discard_const_p(char, "i"), flags); + Py_XDECREF(ret); +} + +static void py_tevent_fp_dealloc(TeventFd_Object *self) +{ + talloc_free(self->fd); + PyObject_Del(self); +} + +static PyTypeObject TeventFd_Type = { + .tp_name = "tevent.Fd", + .tp_basicsize = sizeof(TeventFd_Object), + .tp_dealloc = (destructor)py_tevent_fp_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT, +}; + +static PyObject *py_tevent_context_add_fd(TeventContext_Object *self, PyObject *args) +{ + int fd, flags; + PyObject *handler; + struct tevent_fd *tfd; + TeventFd_Object *ret; + + if (!PyArg_ParseTuple(args, "iiO", &fd, &flags, &handler)) + return NULL; + + tfd = tevent_add_fd(self->ev, NULL, fd, flags, py_fd_handler, handler); + if (tfd == NULL) { + PyErr_SetNone(PyExc_RuntimeError); + return NULL; + } + + ret = PyObject_New(TeventFd_Object, &TeventFd_Type); + if (ret == NULL) { + talloc_free(tfd); + return NULL; + } + ret->fd = tfd; + + return (PyObject *)ret; +} + +static PyMethodDef py_tevent_context_methods[] = { + { "reinitialise", (PyCFunction)py_tevent_context_reinitialise, + METH_NOARGS, + "S.reinitialise()" }, + { "wakeup_send", (PyCFunction)py_tevent_context_wakeup_send, + METH_VARARGS, "S.wakeup_send(wakeup_time) -> req" }, + { "loop_wait", (PyCFunction)py_tevent_context_loop_wait, + METH_NOARGS, "S.loop_wait()" }, + { "loop_once", (PyCFunction)py_tevent_context_loop_once, + METH_NOARGS, "S.loop_once()" }, + { "add_signal", (PyCFunction)py_tevent_context_add_signal, + METH_VARARGS, "S.add_signal(signum, sa_flags, handler) -> signal" }, + { "add_timer", (PyCFunction)py_tevent_context_add_timer, + METH_VARARGS, "S.add_timer(next_event, handler) -> timer" }, + { "add_timer_offset", (PyCFunction)py_tevent_context_add_timer_offset, + METH_VARARGS, "S.add_timer(offset_seconds, handler) -> timer" }, + { "add_fd", (PyCFunction)py_tevent_context_add_fd, + METH_VARARGS, "S.add_fd(fd, flags, handler) -> fd" }, + { NULL }, +}; + +static PyObject *py_tevent_req_wakeup_recv(PyObject *self, + PyObject *Py_UNUSED(ignored)) +{ + /* FIXME */ + Py_RETURN_NONE; +} + +static PyObject *py_tevent_req_received(PyObject *self, + PyObject *Py_UNUSED(ignored)) +{ + /* FIXME */ + Py_RETURN_NONE; +} + +static PyObject *py_tevent_req_is_error(PyObject *self, + PyObject *Py_UNUSED(ignored)) +{ + /* FIXME */ + Py_RETURN_NONE; +} + +static PyObject *py_tevent_req_poll(PyObject *self, + PyObject *Py_UNUSED(ignored)) +{ + /* FIXME */ + Py_RETURN_NONE; +} + +static PyObject *py_tevent_req_is_in_progress(PyObject *self, + PyObject *Py_UNUSED(ignored)) +{ + /* FIXME */ + Py_RETURN_NONE; +} + +static PyGetSetDef py_tevent_req_getsetters[] = { + { + .name = discard_const_p(char, "in_progress"), + .get = (getter)py_tevent_req_is_in_progress, + .doc = discard_const_p(char, "Whether the request is in progress"), + }, + { NULL } +}; + +static PyObject *py_tevent_req_post(PyObject *self, PyObject *args) +{ + /* FIXME */ + Py_RETURN_NONE; +} + +static PyObject *py_tevent_req_set_error(PyObject *self, PyObject *args) +{ + /* FIXME */ + Py_RETURN_NONE; +} + +static PyObject *py_tevent_req_done(PyObject *self, + PyObject *Py_UNUSED(ignored)) +{ + /* FIXME */ + Py_RETURN_NONE; +} + +static PyObject *py_tevent_req_notify_callback(PyObject *self, + PyObject *Py_UNUSED(ignored)) +{ + /* FIXME */ + Py_RETURN_NONE; +} + +static PyObject *py_tevent_req_set_endtime(PyObject *self, PyObject *args) +{ + /* FIXME */ + Py_RETURN_NONE; +} + +static PyObject *py_tevent_req_cancel(TeventReq_Object *self, + PyObject *Py_UNUSED(ignored)) +{ + if (!tevent_req_cancel(self->req)) { + PyErr_SetNone(PyExc_RuntimeError); + return NULL; + } + Py_RETURN_NONE; +} + +static PyMethodDef py_tevent_req_methods[] = { + { "wakeup_recv", (PyCFunction)py_tevent_req_wakeup_recv, + METH_NOARGS, + "Wakeup received" }, + { "received", (PyCFunction)py_tevent_req_received, + METH_NOARGS, + "Receive finished" }, + { "is_error", (PyCFunction)py_tevent_req_is_error, METH_NOARGS, + "is_error() -> (error, state)" }, + { "poll", (PyCFunction)py_tevent_req_poll, METH_VARARGS, + "poll(ctx)" }, + { "post", (PyCFunction)py_tevent_req_post, METH_VARARGS, + "post(ctx) -> req" }, + { "set_error", (PyCFunction)py_tevent_req_set_error, METH_VARARGS, + "set_error(error)" }, + { "done", (PyCFunction)py_tevent_req_done, METH_NOARGS, + "done()" }, + { "notify_callback", (PyCFunction)py_tevent_req_notify_callback, + METH_NOARGS, "notify_callback()" }, + { "set_endtime", (PyCFunction)py_tevent_req_set_endtime, + METH_VARARGS, "set_endtime(ctx, endtime)" }, + { "cancel", (PyCFunction)py_tevent_req_cancel, + METH_NOARGS, "cancel()" }, + { NULL } +}; + +static void py_tevent_req_dealloc(TeventReq_Object *self) +{ + talloc_free(self->req); + PyObject_DEL(self); +} + +static PyTypeObject TeventReq_Type = { + .tp_name = "tevent.Request", + .tp_basicsize = sizeof(TeventReq_Object), + .tp_methods = py_tevent_req_methods, + .tp_dealloc = (destructor)py_tevent_req_dealloc, + .tp_getset = py_tevent_req_getsetters, + /* FIXME: .tp_new = py_tevent_req_new, */ +}; + +static PyObject *py_tevent_queue_get_length(TeventQueue_Object *self, + PyObject *Py_UNUSED(ignored)) +{ + return PyInt_FromLong(tevent_queue_length(self->queue)); +} + +static PyGetSetDef py_tevent_queue_getsetters[] = { + { + .name = discard_const_p(char, "length"), + .get = (getter)py_tevent_queue_get_length, + .doc = discard_const_p(char, "The number of elements in the queue."), + }, + { NULL }, +}; + +static void py_tevent_queue_dealloc(TeventQueue_Object *self) +{ + talloc_free(self->queue); + PyObject_Del(self); +} + +static PyTypeObject TeventQueue_Type = { + .tp_name = "tevent.Queue", + .tp_basicsize = sizeof(TeventQueue_Object), + .tp_dealloc = (destructor)py_tevent_queue_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_getset = py_tevent_queue_getsetters, + .tp_methods = py_tevent_queue_methods, +}; + +static PyObject *py_tevent_context_signal_support(PyObject *_self, + PyObject *Py_UNUSED(ignored)) +{ + TeventContext_Object *self = (TeventContext_Object *)_self; + return PyBool_FromLong(tevent_signal_support(self->ev)); +} + +static PyGetSetDef py_tevent_context_getsetters[] = { + { + .name = discard_const_p(char, "signal_support"), + .get = PY_DISCARD_FUNC_SIG(getter, + py_tevent_context_signal_support), + .doc = discard_const_p(char, "if this platform and tevent context support signal handling"), + }, + { NULL } +}; + +static void py_tevent_context_dealloc(TeventContext_Object *self) +{ + talloc_free(self->ev); + PyObject_Del(self); +} + +static PyObject *py_tevent_context_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + const char * const kwnames[] = { "name", NULL }; + char *name = NULL; + struct tevent_context *ev; + TeventContext_Object *ret; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", discard_const_p(char *, kwnames), &name)) + return NULL; + + if (name == NULL) { + ev = tevent_context_init(NULL); + } else { + ev = tevent_context_init_byname(NULL, name); + } + + if (ev == NULL) { + PyErr_SetNone(PyExc_RuntimeError); + return NULL; + } + + ret = PyObject_New(TeventContext_Object, type); + if (ret == NULL) { + PyErr_NoMemory(); + talloc_free(ev); + return NULL; + } + + ret->ev = ev; + return (PyObject *)ret; +} + +static PyTypeObject TeventContext_Type = { + .tp_name = "tevent.Context", + .tp_new = py_tevent_context_new, + .tp_basicsize = sizeof(TeventContext_Object), + .tp_dealloc = (destructor)py_tevent_context_dealloc, + .tp_methods = py_tevent_context_methods, + .tp_getset = py_tevent_context_getsetters, + .tp_flags = Py_TPFLAGS_DEFAULT, +}; + +static PyObject *py_set_default_backend(PyObject *self, PyObject *args) +{ + char *backend_name; + if (!PyArg_ParseTuple(args, "s", &backend_name)) + return NULL; + + tevent_set_default_backend(backend_name); + + Py_RETURN_NONE; +} + +static PyObject *py_backend_list(PyObject *self, + PyObject *Py_UNUSED(ignored)) +{ + PyObject *ret = NULL; + PyObject *string = NULL; + int i, result; + const char **backends = NULL; + + ret = PyList_New(0); + if (ret == NULL) { + return NULL; + } + + backends = tevent_backend_list(NULL); + if (backends == NULL) { + PyErr_SetNone(PyExc_RuntimeError); + goto err; + } + for (i = 0; backends[i]; i++) { + string = PyUnicode_FromString(backends[i]); + if (!string) { + goto err; + } + result = PyList_Append(ret, string); + if (result) { + goto err; + } + Py_DECREF(string); + string = NULL; + } + + talloc_free(backends); + + return ret; + +err: + Py_XDECREF(ret); + Py_XDECREF(string); + talloc_free(backends); + return NULL; +} + +static PyMethodDef tevent_methods[] = { + { "register_backend", (PyCFunction)py_register_backend, METH_VARARGS, + "register_backend(backend)" }, + { "set_default_backend", (PyCFunction)py_set_default_backend, + METH_VARARGS, "set_default_backend(backend)" }, + { "backend_list", (PyCFunction)py_backend_list, + METH_NOARGS, "backend_list() -> list" }, + { NULL }, +}; + +#define MODULE_DOC PyDoc_STR("Python wrapping of talloc-maintained objects.") + +#if PY_MAJOR_VERSION >= 3 +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + .m_name = "_tevent", + .m_doc = MODULE_DOC, + .m_size = -1, + .m_methods = tevent_methods, +}; +#endif + +PyObject * module_init(void); +PyObject * module_init(void) +{ + PyObject *m; + + if (PyType_Ready(&TeventContext_Type) < 0) + return NULL; + + if (PyType_Ready(&TeventQueue_Type) < 0) + return NULL; + + if (PyType_Ready(&TeventReq_Type) < 0) + return NULL; + + if (PyType_Ready(&TeventSignal_Type) < 0) + return NULL; + + if (PyType_Ready(&TeventTimer_Type) < 0) + return NULL; + + if (PyType_Ready(&TeventFd_Type) < 0) + return NULL; + +#if PY_MAJOR_VERSION >= 3 + m = PyModule_Create(&moduledef); +#else + m = Py_InitModule3("_tevent", tevent_methods, MODULE_DOC); +#endif + if (m == NULL) + return NULL; + + Py_INCREF(&TeventContext_Type); + PyModule_AddObject(m, "Context", (PyObject *)&TeventContext_Type); + + Py_INCREF(&TeventQueue_Type); + PyModule_AddObject(m, "Queue", (PyObject *)&TeventQueue_Type); + + Py_INCREF(&TeventReq_Type); + PyModule_AddObject(m, "Request", (PyObject *)&TeventReq_Type); + + Py_INCREF(&TeventSignal_Type); + PyModule_AddObject(m, "Signal", (PyObject *)&TeventSignal_Type); + + Py_INCREF(&TeventTimer_Type); + PyModule_AddObject(m, "Timer", (PyObject *)&TeventTimer_Type); + + Py_INCREF(&TeventFd_Type); + PyModule_AddObject(m, "Fd", (PyObject *)&TeventFd_Type); + + PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION); + + return m; +} + +#if PY_MAJOR_VERSION >= 3 +PyMODINIT_FUNC PyInit__tevent(void); +PyMODINIT_FUNC PyInit__tevent(void) +{ + return module_init(); +} +#else +void init_tevent(void); +void init_tevent(void) +{ + module_init(); +} +#endif diff --git a/ldb-2.0.8/lib/tevent/test_req.c b/ldb-2.0.8/lib/tevent/test_req.c new file mode 100644 index 0000000..2274a8c --- /dev/null +++ b/ldb-2.0.8/lib/tevent/test_req.c @@ -0,0 +1,288 @@ +/* + * Unix SMB/CIFS implementation. + * + * testing of some tevent_req aspects + * + * Copyright (C) Volker Lendecke 2018 + * + * ** NOTE! The following LGPL license applies to the tevent + * ** library. This does NOT imply that all of Samba is released + * ** under the LGPL + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "includes.h" +#include "tevent.h" +#include "torture/torture.h" +#include "torture/local/proto.h" +#include "lib/util/tevent_unix.h" +#include "lib/util/tevent_req_profile.h" +#include "lib/util/time_basic.h" + +struct tevent_req_create_state { + uint8_t val; +}; + +static bool test_tevent_req_create(struct torture_context *tctx, + const void *test_data) +{ + struct tevent_req *req; + struct tevent_req_create_state *state; + + req = tevent_req_create(tctx, &state, + struct tevent_req_create_state); + torture_assert_not_null(tctx, req, "tevent_req_create failed\n"); + torture_assert_int_equal(tctx, state->val, 0, "state not initialized\n"); + + TALLOC_FREE(req); + + return true; +} + +struct profile1_state { + uint8_t dummy; +}; + +static bool test_tevent_req_profile1(struct torture_context *tctx, + const void *test_data) +{ + struct tevent_req *req; + struct profile1_state *state; + const struct tevent_req_profile *p1; + struct tevent_req_profile *p2; + struct timeval start, stop; + bool ok; + int cmp; + + req = tevent_req_create(tctx, &state, struct profile1_state); + torture_assert_not_null(tctx, req, "tevent_req_create failed\n"); + + p1 = tevent_req_get_profile(req); + torture_assert(tctx, p1 == NULL, "profile not initialized to NULL\n"); + + ok = tevent_req_set_profile(req); + torture_assert(tctx, ok, "set_profile failed\n"); + + tevent_req_done(req); + + p2 = tevent_req_move_profile(req, tctx); + torture_assert_not_null(tctx, p2, "get_profile failed\n"); + + /* Demonstrate sure "p2" outlives req */ + TALLOC_FREE(req); + + tevent_req_profile_get_start(p2, NULL, &start); + tevent_req_profile_get_stop(p2, NULL, &stop); + + cmp = tevent_timeval_compare(&start, &stop); + torture_assert(tctx, cmp <= 0, "stop before start\n"); + + TALLOC_FREE(p2); + + return true; +} + +struct profile2_state { + uint8_t dummy; +}; + +static void profile2_done(struct tevent_req *subreq); + +static struct tevent_req *profile2_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev) +{ + struct tevent_req *req, *subreq; + struct profile2_state *state; + bool ok; + + req = tevent_req_create(mem_ctx, &state, struct profile2_state); + if (req == NULL) { + return NULL; + } + + ok = tevent_req_set_profile(req); + if (!ok) { + return tevent_req_post(req, ev); + } + + subreq = tevent_wakeup_send( + state, + ev, + tevent_timeval_current_ofs(0, 1)); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, profile2_done, req); + + return req; +} + +static void profile2_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + bool ok; + + ok = tevent_wakeup_recv(subreq); + if (!ok) { + tevent_req_oom(req); + return; + } + tevent_req_done(req); +} + +static int profile2_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + struct tevent_req_profile **profile) +{ + int err; + + if (tevent_req_is_unix_error(req, &err)) { + return err; + } + + *profile = tevent_req_move_profile(req, mem_ctx); + + return 0; +} + +static bool test_tevent_req_profile2(struct torture_context *tctx, + const void *test_data) +{ + struct tevent_context *ev; + struct tevent_req *req; + struct tevent_req_profile *p1 = NULL; + struct tevent_req_profile *p2 = NULL; + const char *str1, *str2; + struct timeval tv1, tv2; + pid_t pid1, pid2; + enum tevent_req_state state1, state2; + uint64_t err1, err2; + char *printstring; + ssize_t pack_len; + int err; + bool ok; + + ev = samba_tevent_context_init(tctx); + torture_assert_not_null(tctx, ev, "samba_tevent_context_init failed\n"); + + req = profile2_send(tctx, ev); + torture_assert_not_null(tctx, req, "profile2_send failed\n"); + + ok = tevent_req_poll_unix(req, ev, &err); + torture_assert(tctx, ok, "tevent_req_poll_unix failed\n"); + + err = profile2_recv(req, tctx, &p1); + torture_assert_int_equal(tctx, err, 0, "profile2_recv failed\n"); + + TALLOC_FREE(req); + TALLOC_FREE(ev); + + printstring = tevent_req_profile_string(tctx, p1, 0, UINT_MAX); + torture_assert_not_null( + tctx, + printstring, + "tevent_req_profile_string failed\n"); + printf("%s\n", printstring); + + pack_len = tevent_req_profile_pack(p1, NULL, 0); + torture_assert(tctx, pack_len>0, "profile_pack failed\n"); + + { + uint8_t buf[pack_len]; + ssize_t unpack_len; + + tevent_req_profile_pack(p1, buf, sizeof(buf)); + dump_data(10, buf, sizeof(buf)); + + unpack_len = tevent_req_profile_unpack( + buf, + pack_len, + tctx, + &p2); + torture_assert_int_equal(tctx, + pack_len, + unpack_len, + "profile_unpack failed\n"); + } + + printstring = tevent_req_profile_string(tctx, p2, 0, UINT_MAX); + torture_assert_not_null( + tctx, + printstring, + "tevent_req_profile_string failed\n"); + printf("%s\n", printstring); + + tevent_req_profile_get_name(p1, &str1); + tevent_req_profile_get_name(p2, &str2); + torture_assert_str_equal(tctx, str1, str2, "names differ\n"); + + tevent_req_profile_get_start(p1, &str1, &tv1); + tevent_req_profile_get_start(p2, &str2, &tv2); + torture_assert_str_equal(tctx, str1, str2, "start strings differ\n"); + torture_assert(tctx, + tevent_timeval_compare(&tv1, &tv2) == 0, + "start times differ\n"); + + tevent_req_profile_get_stop(p1, &str1, &tv1); + tevent_req_profile_get_stop(p2, &str2, &tv2); + torture_assert_str_equal(tctx, str1, str2, "stop strings differ\n"); + torture_assert(tctx, + tevent_timeval_compare(&tv1, &tv2) == 0, + "stop times differ\n"); + + tevent_req_profile_get_status(p1, &pid1, &state1, &err1); + tevent_req_profile_get_status(p2, &pid2, &state2, &err2); + torture_assert_int_equal(tctx, pid1, pid2, "pids differ\n"); + torture_assert_int_equal(tctx, state1, state2, "states differ\n"); + torture_assert_int_equal(tctx, err1, err2, "user errors differ\n"); + + str1 = tevent_req_profile_string(p1, p1, 0, UINT_MAX); + torture_assert_not_null(tctx, str1, "profile_string failed\n"); + str2 = tevent_req_profile_string(p2, p2, 0, UINT_MAX); + torture_assert_not_null(tctx, str2, "profile_string failed\n"); + + torture_assert_str_equal(tctx, str1, str2, "result strings differ\n"); + + TALLOC_FREE(p1); + TALLOC_FREE(p2); + + return true; +} + +struct torture_suite *torture_local_tevent_req(TALLOC_CTX *mem_ctx) +{ + struct torture_suite *suite; + + suite = torture_suite_create(mem_ctx, "tevent_req"); + + torture_suite_add_simple_tcase_const( + suite, + "create", + test_tevent_req_create, + NULL); + torture_suite_add_simple_tcase_const( + suite, + "profile1", + test_tevent_req_profile1, + NULL); + torture_suite_add_simple_tcase_const( + suite, + "profile2", + test_tevent_req_profile2, + NULL); + + return suite; +} diff --git a/ldb-2.0.8/lib/tevent/testsuite.c b/ldb-2.0.8/lib/tevent/testsuite.c new file mode 100644 index 0000000..ee4c285 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/testsuite.c @@ -0,0 +1,1821 @@ +/* + Unix SMB/CIFS implementation. + + testing of the events subsystem + + Copyright (C) Stefan Metzmacher 2006-2009 + Copyright (C) Jeremy Allison 2013 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "includes.h" +#define TEVENT_DEPRECATED 1 +#include "tevent.h" +#include "system/filesys.h" +#include "system/select.h" +#include "system/network.h" +#include "torture/torture.h" +#include "torture/local/proto.h" +#ifdef HAVE_PTHREAD +#include "system/threads.h" +#include +#endif + +static int fde_count; + +static void do_read(int fd, void *buf, size_t count) +{ + ssize_t ret; + + do { + ret = read(fd, buf, count); + } while (ret == -1 && errno == EINTR); +} + +static void fde_handler_read(struct tevent_context *ev_ctx, struct tevent_fd *f, + uint16_t flags, void *private_data) +{ + int *fd = (int *)private_data; + char c; +#ifdef SA_SIGINFO + kill(getpid(), SIGUSR1); +#endif + kill(getpid(), SIGALRM); + + do_read(fd[0], &c, 1); + fde_count++; +} + +static void do_write(int fd, void *buf, size_t count) +{ + ssize_t ret; + + do { + ret = write(fd, buf, count); + } while (ret == -1 && errno == EINTR); +} + +static void fde_handler_write(struct tevent_context *ev_ctx, struct tevent_fd *f, + uint16_t flags, void *private_data) +{ + int *fd = (int *)private_data; + char c = 0; + + do_write(fd[1], &c, 1); +} + + +/* This will only fire if the fd's returned from pipe() are bi-directional. */ +static void fde_handler_read_1(struct tevent_context *ev_ctx, struct tevent_fd *f, + uint16_t flags, void *private_data) +{ + int *fd = (int *)private_data; + char c; +#ifdef SA_SIGINFO + kill(getpid(), SIGUSR1); +#endif + kill(getpid(), SIGALRM); + + do_read(fd[1], &c, 1); + fde_count++; +} + +/* This will only fire if the fd's returned from pipe() are bi-directional. */ +static void fde_handler_write_1(struct tevent_context *ev_ctx, struct tevent_fd *f, + uint16_t flags, void *private_data) +{ + int *fd = (int *)private_data; + char c = 0; + do_write(fd[0], &c, 1); +} + +static void finished_handler(struct tevent_context *ev_ctx, struct tevent_timer *te, + struct timeval tval, void *private_data) +{ + int *finished = (int *)private_data; + (*finished) = 1; +} + +static void count_handler(struct tevent_context *ev_ctx, struct tevent_signal *te, + int signum, int count, void *info, void *private_data) +{ + int *countp = (int *)private_data; + (*countp) += count; +} + +static bool test_event_context(struct torture_context *test, + const void *test_data) +{ + struct tevent_context *ev_ctx; + int fd[2] = { -1, -1 }; + const char *backend = (const char *)test_data; + int alarm_count=0, info_count=0; + struct tevent_fd *fde_read; + struct tevent_fd *fde_read_1; + struct tevent_fd *fde_write; + struct tevent_fd *fde_write_1; +#ifdef SA_RESTART + struct tevent_signal *se1 = NULL; +#endif +#ifdef SA_RESETHAND + struct tevent_signal *se2 = NULL; +#endif +#ifdef SA_SIGINFO + struct tevent_signal *se3 = NULL; +#endif + int finished=0; + struct timeval t; + int ret; + + ev_ctx = tevent_context_init_byname(test, backend); + if (ev_ctx == NULL) { + torture_comment(test, "event backend '%s' not supported\n", backend); + return true; + } + + torture_comment(test, "backend '%s' - %s\n", + backend, __FUNCTION__); + + /* reset globals */ + fde_count = 0; + + /* create a pipe */ + ret = pipe(fd); + torture_assert_int_equal(test, ret, 0, "pipe failed"); + + fde_read = tevent_add_fd(ev_ctx, ev_ctx, fd[0], TEVENT_FD_READ, + fde_handler_read, fd); + fde_write_1 = tevent_add_fd(ev_ctx, ev_ctx, fd[0], TEVENT_FD_WRITE, + fde_handler_write_1, fd); + + fde_write = tevent_add_fd(ev_ctx, ev_ctx, fd[1], TEVENT_FD_WRITE, + fde_handler_write, fd); + fde_read_1 = tevent_add_fd(ev_ctx, ev_ctx, fd[1], TEVENT_FD_READ, + fde_handler_read_1, fd); + + tevent_fd_set_auto_close(fde_read); + tevent_fd_set_auto_close(fde_write); + + tevent_add_timer(ev_ctx, ev_ctx, timeval_current_ofs(2,0), + finished_handler, &finished); + +#ifdef SA_RESTART + se1 = tevent_add_signal(ev_ctx, ev_ctx, SIGALRM, SA_RESTART, count_handler, &alarm_count); + torture_assert(test, se1 != NULL, "failed to setup se1"); +#endif +#ifdef SA_RESETHAND + se2 = tevent_add_signal(ev_ctx, ev_ctx, SIGALRM, SA_RESETHAND, count_handler, &alarm_count); + torture_assert(test, se2 != NULL, "failed to setup se2"); +#endif +#ifdef SA_SIGINFO + se3 = tevent_add_signal(ev_ctx, ev_ctx, SIGUSR1, SA_SIGINFO, count_handler, &info_count); + torture_assert(test, se3 != NULL, "failed to setup se3"); +#endif + + t = timeval_current(); + while (!finished) { + errno = 0; + if (tevent_loop_once(ev_ctx) == -1) { + TALLOC_FREE(ev_ctx); + torture_fail(test, talloc_asprintf(test, "Failed event loop %s\n", strerror(errno))); + return false; + } + } + + talloc_free(fde_read_1); + talloc_free(fde_write_1); + talloc_free(fde_read); + talloc_free(fde_write); + + while (alarm_count < fde_count+1) { + if (tevent_loop_once(ev_ctx) == -1) { + break; + } + } + + torture_comment(test, "Got %.2f pipe events/sec\n", fde_count/timeval_elapsed(&t)); + +#ifdef SA_RESTART + talloc_free(se1); +#endif + + torture_assert_int_equal(test, alarm_count, 1+fde_count, "alarm count mismatch"); + +#ifdef SA_RESETHAND + /* + * we do not call talloc_free(se2) + * because it is already gone, + * after triggering the event handler. + */ +#endif + +#ifdef SA_SIGINFO + talloc_free(se3); + torture_assert_int_equal(test, info_count, fde_count, "info count mismatch"); +#endif + + talloc_free(ev_ctx); + + return true; +} + +struct test_event_fd1_state { + struct torture_context *tctx; + const char *backend; + struct tevent_context *ev; + int sock[2]; + struct tevent_timer *te; + struct tevent_fd *fde0; + struct tevent_fd *fde1; + bool got_write; + bool got_read; + bool drain; + bool drain_done; + unsigned loop_count; + bool finished; + const char *error; +}; + +static void test_event_fd1_fde_handler(struct tevent_context *ev_ctx, + struct tevent_fd *fde, + uint16_t flags, + void *private_data) +{ + struct test_event_fd1_state *state = + (struct test_event_fd1_state *)private_data; + + if (state->drain_done) { + state->finished = true; + state->error = __location__; + return; + } + + if (state->drain) { + ssize_t ret; + uint8_t c = 0; + + if (!(flags & TEVENT_FD_READ)) { + state->finished = true; + state->error = __location__; + return; + } + + ret = read(state->sock[0], &c, 1); + if (ret == 1) { + return; + } + + /* + * end of test... + */ + tevent_fd_set_flags(fde, 0); + state->drain_done = true; + return; + } + + if (!state->got_write) { + uint8_t c = 0; + + if (flags != TEVENT_FD_WRITE) { + state->finished = true; + state->error = __location__; + return; + } + state->got_write = true; + + /* + * we write to the other socket... + */ + do_write(state->sock[1], &c, 1); + TEVENT_FD_NOT_WRITEABLE(fde); + TEVENT_FD_READABLE(fde); + return; + } + + if (!state->got_read) { + if (flags != TEVENT_FD_READ) { + state->finished = true; + state->error = __location__; + return; + } + state->got_read = true; + + TEVENT_FD_NOT_READABLE(fde); + return; + } + + state->finished = true; + state->error = __location__; + return; +} + +static void test_event_fd1_finished(struct tevent_context *ev_ctx, + struct tevent_timer *te, + struct timeval tval, + void *private_data) +{ + struct test_event_fd1_state *state = + (struct test_event_fd1_state *)private_data; + + if (state->drain_done) { + state->finished = true; + return; + } + + if (!state->got_write) { + state->finished = true; + state->error = __location__; + return; + } + + if (!state->got_read) { + state->finished = true; + state->error = __location__; + return; + } + + state->loop_count++; + if (state->loop_count > 3) { + state->finished = true; + state->error = __location__; + return; + } + + state->got_write = false; + state->got_read = false; + + tevent_fd_set_flags(state->fde0, TEVENT_FD_WRITE); + + if (state->loop_count > 2) { + state->drain = true; + TALLOC_FREE(state->fde1); + TEVENT_FD_READABLE(state->fde0); + } + + state->te = tevent_add_timer(state->ev, state->ev, + timeval_current_ofs(0,2000), + test_event_fd1_finished, state); +} + +static bool test_event_fd1(struct torture_context *tctx, + const void *test_data) +{ + struct test_event_fd1_state state; + int ret; + + ZERO_STRUCT(state); + state.tctx = tctx; + state.backend = (const char *)test_data; + + state.ev = tevent_context_init_byname(tctx, state.backend); + if (state.ev == NULL) { + torture_skip(tctx, talloc_asprintf(tctx, + "event backend '%s' not supported\n", + state.backend)); + return true; + } + + tevent_set_debug_stderr(state.ev); + torture_comment(tctx, "backend '%s' - %s\n", + state.backend, __FUNCTION__); + + /* + * This tests the following: + * + * It monitors the state of state.sock[0] + * with tevent_fd, but we never read/write on state.sock[0] + * while state.sock[1] * is only used to write a few bytes. + * + * We have a loop: + * - we wait only for TEVENT_FD_WRITE on state.sock[0] + * - we write 1 byte to state.sock[1] + * - we wait only for TEVENT_FD_READ on state.sock[0] + * - we disable events on state.sock[0] + * - the timer event restarts the loop + * Then we close state.sock[1] + * We have a loop: + * - we wait for TEVENT_FD_READ/WRITE on state.sock[0] + * - we try to read 1 byte + * - if the read gets an error of returns 0 + * we disable the event handler + * - the timer finishes the test + */ + state.sock[0] = -1; + state.sock[1] = -1; + + ret = socketpair(AF_UNIX, SOCK_STREAM, 0, state.sock); + torture_assert(tctx, ret == 0, "socketpair() failed"); + + state.te = tevent_add_timer(state.ev, state.ev, + timeval_current_ofs(0,1000), + test_event_fd1_finished, &state); + state.fde0 = tevent_add_fd(state.ev, state.ev, + state.sock[0], TEVENT_FD_WRITE, + test_event_fd1_fde_handler, &state); + /* state.fde1 is only used to auto close */ + state.fde1 = tevent_add_fd(state.ev, state.ev, + state.sock[1], 0, + test_event_fd1_fde_handler, &state); + + tevent_fd_set_auto_close(state.fde0); + tevent_fd_set_auto_close(state.fde1); + + while (!state.finished) { + errno = 0; + if (tevent_loop_once(state.ev) == -1) { + talloc_free(state.ev); + torture_fail(tctx, talloc_asprintf(tctx, + "Failed event loop %s\n", + strerror(errno))); + } + } + + talloc_free(state.ev); + + torture_assert(tctx, state.error == NULL, talloc_asprintf(tctx, + "%s", state.error)); + + return true; +} + +struct test_event_fd2_state { + struct torture_context *tctx; + const char *backend; + struct tevent_context *ev; + struct tevent_timer *te; + struct test_event_fd2_sock { + struct test_event_fd2_state *state; + int fd; + struct tevent_fd *fde; + size_t num_written; + size_t num_read; + bool got_full; + } sock0, sock1; + bool finished; + const char *error; +}; + +static void test_event_fd2_sock_handler(struct tevent_context *ev_ctx, + struct tevent_fd *fde, + uint16_t flags, + void *private_data) +{ + struct test_event_fd2_sock *cur_sock = + (struct test_event_fd2_sock *)private_data; + struct test_event_fd2_state *state = cur_sock->state; + struct test_event_fd2_sock *oth_sock = NULL; + uint8_t v = 0, c; + ssize_t ret; + + if (cur_sock == &state->sock0) { + oth_sock = &state->sock1; + } else { + oth_sock = &state->sock0; + } + + if (oth_sock->num_written == 1) { + if (flags != (TEVENT_FD_READ | TEVENT_FD_WRITE)) { + state->finished = true; + state->error = __location__; + return; + } + } + + if (cur_sock->num_read == oth_sock->num_written) { + state->finished = true; + state->error = __location__; + return; + } + + if (!(flags & TEVENT_FD_READ)) { + state->finished = true; + state->error = __location__; + return; + } + + if (oth_sock->num_read >= PIPE_BUF) { + /* + * On Linux we become writable once we've read + * one byte. On Solaris we only become writable + * again once we've read 4096 bytes. PIPE_BUF + * is probably a safe bet to test against. + * + * There should be room to write a byte again + */ + if (!(flags & TEVENT_FD_WRITE)) { + state->finished = true; + state->error = __location__; + return; + } + } + + if ((flags & TEVENT_FD_WRITE) && !cur_sock->got_full) { + v = (uint8_t)cur_sock->num_written; + ret = write(cur_sock->fd, &v, 1); + if (ret != 1) { + state->finished = true; + state->error = __location__; + return; + } + cur_sock->num_written++; + if (cur_sock->num_written > 0x80000000) { + state->finished = true; + state->error = __location__; + return; + } + return; + } + + if (!cur_sock->got_full) { + cur_sock->got_full = true; + + if (!oth_sock->got_full) { + /* + * cur_sock is full, + * lets wait for oth_sock + * to be filled + */ + tevent_fd_set_flags(cur_sock->fde, 0); + return; + } + + /* + * oth_sock waited for cur_sock, + * lets restart it + */ + tevent_fd_set_flags(oth_sock->fde, + TEVENT_FD_READ|TEVENT_FD_WRITE); + } + + ret = read(cur_sock->fd, &v, 1); + if (ret != 1) { + state->finished = true; + state->error = __location__; + return; + } + c = (uint8_t)cur_sock->num_read; + if (c != v) { + state->finished = true; + state->error = __location__; + return; + } + cur_sock->num_read++; + + if (cur_sock->num_read < oth_sock->num_written) { + /* there is more to read */ + return; + } + /* + * we read everything, we need to remove TEVENT_FD_WRITE + * to avoid spinning + */ + TEVENT_FD_NOT_WRITEABLE(cur_sock->fde); + + if (oth_sock->num_read == cur_sock->num_written) { + /* + * both directions are finished + */ + state->finished = true; + } + + return; +} + +static void test_event_fd2_finished(struct tevent_context *ev_ctx, + struct tevent_timer *te, + struct timeval tval, + void *private_data) +{ + struct test_event_fd2_state *state = + (struct test_event_fd2_state *)private_data; + + /* + * this should never be triggered + */ + state->finished = true; + state->error = __location__; +} + +static bool test_event_fd2(struct torture_context *tctx, + const void *test_data) +{ + struct test_event_fd2_state state; + int sock[2]; + uint8_t c = 0; + + ZERO_STRUCT(state); + state.tctx = tctx; + state.backend = (const char *)test_data; + + state.ev = tevent_context_init_byname(tctx, state.backend); + if (state.ev == NULL) { + torture_skip(tctx, talloc_asprintf(tctx, + "event backend '%s' not supported\n", + state.backend)); + return true; + } + + tevent_set_debug_stderr(state.ev); + torture_comment(tctx, "backend '%s' - %s\n", + state.backend, __FUNCTION__); + + /* + * This tests the following + * + * - We write 1 byte to each socket + * - We wait for TEVENT_FD_READ/WRITE on both sockets + * - When we get TEVENT_FD_WRITE we write 1 byte + * until both socket buffers are full, which + * means both sockets only get TEVENT_FD_READ. + * - Then we read 1 byte until we have consumed + * all bytes the other end has written. + */ + sock[0] = -1; + sock[1] = -1; + socketpair(AF_UNIX, SOCK_STREAM, 0, sock); + + /* + * the timer should never expire + */ + state.te = tevent_add_timer(state.ev, state.ev, + timeval_current_ofs(600, 0), + test_event_fd2_finished, &state); + state.sock0.state = &state; + state.sock0.fd = sock[0]; + state.sock0.fde = tevent_add_fd(state.ev, state.ev, + state.sock0.fd, + TEVENT_FD_READ | TEVENT_FD_WRITE, + test_event_fd2_sock_handler, + &state.sock0); + state.sock1.state = &state; + state.sock1.fd = sock[1]; + state.sock1.fde = tevent_add_fd(state.ev, state.ev, + state.sock1.fd, + TEVENT_FD_READ | TEVENT_FD_WRITE, + test_event_fd2_sock_handler, + &state.sock1); + + tevent_fd_set_auto_close(state.sock0.fde); + tevent_fd_set_auto_close(state.sock1.fde); + + do_write(state.sock0.fd, &c, 1); + state.sock0.num_written++; + do_write(state.sock1.fd, &c, 1); + state.sock1.num_written++; + + while (!state.finished) { + errno = 0; + if (tevent_loop_once(state.ev) == -1) { + talloc_free(state.ev); + torture_fail(tctx, talloc_asprintf(tctx, + "Failed event loop %s\n", + strerror(errno))); + } + } + + talloc_free(state.ev); + + torture_assert(tctx, state.error == NULL, talloc_asprintf(tctx, + "%s", state.error)); + + return true; +} + +struct test_wrapper_state { + struct torture_context *tctx; + int num_events; + int num_wrap_handlers; +}; + +static bool test_wrapper_before_use(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + const char *location) +{ + struct test_wrapper_state *state = + talloc_get_type_abort(private_data, + struct test_wrapper_state); + + torture_comment(state->tctx, "%s\n", __func__); + state->num_wrap_handlers++; + return true; +} + +static void test_wrapper_after_use(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + const char *location) +{ + struct test_wrapper_state *state = + talloc_get_type_abort(private_data, + struct test_wrapper_state); + + torture_comment(state->tctx, "%s\n", __func__); + state->num_wrap_handlers++; +} + +static void test_wrapper_before_fd_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_fd *fde, + uint16_t flags, + const char *handler_name, + const char *location) +{ + struct test_wrapper_state *state = + talloc_get_type_abort(private_data, + struct test_wrapper_state); + + torture_comment(state->tctx, "%s\n", __func__); + state->num_wrap_handlers++; +} + +static void test_wrapper_after_fd_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_fd *fde, + uint16_t flags, + const char *handler_name, + const char *location) +{ + struct test_wrapper_state *state = + talloc_get_type_abort(private_data, + struct test_wrapper_state); + + torture_comment(state->tctx, "%s\n", __func__); + state->num_wrap_handlers++; +} + +static void test_wrapper_before_timer_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_timer *te, + struct timeval requested_time, + struct timeval trigger_time, + const char *handler_name, + const char *location) +{ + struct test_wrapper_state *state = + talloc_get_type_abort(private_data, + struct test_wrapper_state); + + torture_comment(state->tctx, "%s\n", __func__); + state->num_wrap_handlers++; +} + +static void test_wrapper_after_timer_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_timer *te, + struct timeval requested_time, + struct timeval trigger_time, + const char *handler_name, + const char *location) +{ + struct test_wrapper_state *state = + talloc_get_type_abort(private_data, + struct test_wrapper_state); + + torture_comment(state->tctx, "%s\n", __func__); + state->num_wrap_handlers++; +} + +static void test_wrapper_before_immediate_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_immediate *im, + const char *handler_name, + const char *location) +{ + struct test_wrapper_state *state = + talloc_get_type_abort(private_data, + struct test_wrapper_state); + + torture_comment(state->tctx, "%s\n", __func__); + state->num_wrap_handlers++; +} + +static void test_wrapper_after_immediate_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_immediate *im, + const char *handler_name, + const char *location) +{ + struct test_wrapper_state *state = + talloc_get_type_abort(private_data, + struct test_wrapper_state); + + torture_comment(state->tctx, "%s\n", __func__); + state->num_wrap_handlers++; +} + +static void test_wrapper_before_signal_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_signal *se, + int signum, + int count, + void *siginfo, + const char *handler_name, + const char *location) +{ + struct test_wrapper_state *state = + talloc_get_type_abort(private_data, + struct test_wrapper_state); + + torture_comment(state->tctx, "%s\n", __func__); + state->num_wrap_handlers++; +} + +static void test_wrapper_after_signal_handler(struct tevent_context *wrap_ev, + void *private_data, + struct tevent_context *main_ev, + struct tevent_signal *se, + int signum, + int count, + void *siginfo, + const char *handler_name, + const char *location) +{ + struct test_wrapper_state *state = + talloc_get_type_abort(private_data, + struct test_wrapper_state); + + torture_comment(state->tctx, "%s\n", __func__); + state->num_wrap_handlers++; +} + +static const struct tevent_wrapper_ops test_wrapper_ops = { + .name = "test_wrapper", + .before_use = test_wrapper_before_use, + .after_use = test_wrapper_after_use, + .before_fd_handler = test_wrapper_before_fd_handler, + .after_fd_handler = test_wrapper_after_fd_handler, + .before_timer_handler = test_wrapper_before_timer_handler, + .after_timer_handler = test_wrapper_after_timer_handler, + .before_immediate_handler = test_wrapper_before_immediate_handler, + .after_immediate_handler = test_wrapper_after_immediate_handler, + .before_signal_handler = test_wrapper_before_signal_handler, + .after_signal_handler = test_wrapper_after_signal_handler, +}; + +static void test_wrapper_timer_handler(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data) +{ + struct test_wrapper_state *state = + (struct test_wrapper_state *)private_data; + + + torture_comment(state->tctx, "timer handler\n"); + + state->num_events++; + talloc_free(te); + return; +} + +static void test_wrapper_fd_handler(struct tevent_context *ev, + struct tevent_fd *fde, + unsigned short fd_flags, + void *private_data) +{ + struct test_wrapper_state *state = + (struct test_wrapper_state *)private_data; + + torture_comment(state->tctx, "fd handler\n"); + + state->num_events++; + talloc_free(fde); + return; +} + +static void test_wrapper_immediate_handler(struct tevent_context *ev, + struct tevent_immediate *im, + void *private_data) +{ + struct test_wrapper_state *state = + (struct test_wrapper_state *)private_data; + + state->num_events++; + talloc_free(im); + + torture_comment(state->tctx, "immediate handler\n"); + return; +} + +static void test_wrapper_signal_handler(struct tevent_context *ev, + struct tevent_signal *se, + int signum, + int count, + void *siginfo, + void *private_data) +{ + struct test_wrapper_state *state = + (struct test_wrapper_state *)private_data; + + torture_comment(state->tctx, "signal handler\n"); + + state->num_events++; + talloc_free(se); + return; +} + +static bool test_wrapper(struct torture_context *tctx, + const void *test_data) +{ + struct test_wrapper_state *state = NULL; + int sock[2] = { -1, -1}; + uint8_t c = 0; + const int num_events = 4; + const char *backend = (const char *)test_data; + struct tevent_context *ev = NULL; + struct tevent_context *wrap_ev = NULL; + struct tevent_fd *fde = NULL; + struct tevent_timer *te = NULL; + struct tevent_signal *se = NULL; + struct tevent_immediate *im = NULL; + int ret; + bool ok = false; + bool ret2; + + ev = tevent_context_init_byname(tctx, backend); + if (ev == NULL) { + torture_skip(tctx, talloc_asprintf(tctx, + "event backend '%s' not supported\n", + backend)); + return true; + } + + tevent_set_debug_stderr(ev); + torture_comment(tctx, "tevent backend '%s'\n", backend); + + wrap_ev = tevent_context_wrapper_create( + ev, ev, &test_wrapper_ops, &state, struct test_wrapper_state); + torture_assert_not_null_goto(tctx, wrap_ev, ok, done, + "tevent_context_wrapper_create failed\n"); + *state = (struct test_wrapper_state) { + .tctx = tctx, + }; + + ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sock); + torture_assert_goto(tctx, ret == 0, ok, done, "socketpair failed\n"); + + te = tevent_add_timer(wrap_ev, wrap_ev, + timeval_current_ofs(0, 0), + test_wrapper_timer_handler, state); + torture_assert_not_null_goto(tctx, te, ok, done, + "tevent_add_timer failed\n"); + + fde = tevent_add_fd(wrap_ev, wrap_ev, + sock[1], + TEVENT_FD_READ, + test_wrapper_fd_handler, + state); + torture_assert_not_null_goto(tctx, fde, ok, done, + "tevent_add_fd failed\n"); + + im = tevent_create_immediate(wrap_ev); + torture_assert_not_null_goto(tctx, im, ok, done, + "tevent_create_immediate failed\n"); + + se = tevent_add_signal(wrap_ev, wrap_ev, + SIGUSR1, + 0, + test_wrapper_signal_handler, + state); + torture_assert_not_null_goto(tctx, se, ok, done, + "tevent_add_signal failed\n"); + + do_write(sock[0], &c, 1); + kill(getpid(), SIGUSR1); + tevent_schedule_immediate(im, + wrap_ev, + test_wrapper_immediate_handler, + state); + + ret2 = tevent_context_push_use(wrap_ev); + torture_assert_goto(tctx, ret2, ok, done, "tevent_context_push_use(wrap_ev) failed\n"); + ret2 = tevent_context_push_use(ev); + torture_assert_goto(tctx, ret2, ok, pop_use, "tevent_context_push_use(ev) failed\n"); + tevent_context_pop_use(ev); + tevent_context_pop_use(wrap_ev); + + ret = tevent_loop_wait(ev); + torture_assert_int_equal_goto(tctx, ret, 0, ok, done, "tevent_loop_wait failed\n"); + + torture_comment(tctx, "Num events: %d\n", state->num_events); + torture_comment(tctx, "Num wrap handlers: %d\n", + state->num_wrap_handlers); + + torture_assert_int_equal_goto(tctx, state->num_events, num_events, ok, done, + "Wrong event count\n"); + torture_assert_int_equal_goto(tctx, state->num_wrap_handlers, + num_events*2+2, + ok, done, "Wrong wrapper count\n"); + + ok = true; + +done: + TALLOC_FREE(wrap_ev); + TALLOC_FREE(ev); + + if (sock[0] != -1) { + close(sock[0]); + } + if (sock[1] != -1) { + close(sock[1]); + } + return ok; +pop_use: + tevent_context_pop_use(wrap_ev); + goto done; +} + +static void test_free_wrapper_signal_handler(struct tevent_context *ev, + struct tevent_signal *se, + int signum, + int count, + void *siginfo, + void *private_data) +{ + struct torture_context *tctx = + talloc_get_type_abort(private_data, + struct torture_context); + + torture_comment(tctx, "signal handler\n"); + + talloc_free(se); + + /* + * signal handlers have highest priority in tevent, so this signal + * handler will always be started before the other handlers + * below. Freeing the (wrapper) event context here tests that the + * wrapper implementation correclty handles the wrapper ev going away + * with pending events. + */ + talloc_free(ev); + return; +} + +static void test_free_wrapper_fd_handler(struct tevent_context *ev, + struct tevent_fd *fde, + unsigned short fd_flags, + void *private_data) +{ + /* + * This should never be called as + * test_free_wrapper_signal_handler() + * already destroyed the wrapper tevent_context. + */ + abort(); +} + +static void test_free_wrapper_immediate_handler(struct tevent_context *ev, + struct tevent_immediate *im, + void *private_data) +{ + /* + * This should never be called as + * test_free_wrapper_signal_handler() + * already destroyed the wrapper tevent_context. + */ + abort(); +} + +static void test_free_wrapper_timer_handler(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, + void *private_data) +{ + /* + * This should never be called as + * test_free_wrapper_signal_handler() + * already destroyed the wrapper tevent_context. + */ + abort(); +} + +static bool test_free_wrapper(struct torture_context *tctx, + const void *test_data) +{ + struct test_wrapper_state *state = NULL; + int sock[2] = { -1, -1}; + uint8_t c = 0; + const char *backend = (const char *)test_data; + TALLOC_CTX *frame = talloc_stackframe(); + struct tevent_context *ev = NULL; + struct tevent_context *wrap_ev = NULL; + struct tevent_fd *fde = NULL; + struct tevent_timer *te = NULL; + struct tevent_signal *se = NULL; + struct tevent_immediate *im = NULL; + int ret; + bool ok = false; + + ev = tevent_context_init_byname(frame, backend); + if (ev == NULL) { + torture_skip(tctx, talloc_asprintf(tctx, + "event backend '%s' not supported\n", + backend)); + return true; + } + + tevent_set_debug_stderr(ev); + torture_comment(tctx, "tevent backend '%s'\n", backend); + + wrap_ev = tevent_context_wrapper_create( + ev, ev, &test_wrapper_ops, &state, struct test_wrapper_state); + torture_assert_not_null_goto(tctx, wrap_ev, ok, done, + "tevent_context_wrapper_create failed\n"); + *state = (struct test_wrapper_state) { + .tctx = tctx, + }; + + ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sock); + torture_assert_goto(tctx, ret == 0, ok, done, "socketpair failed\n"); + + fde = tevent_add_fd(wrap_ev, frame, + sock[1], + TEVENT_FD_READ, + test_free_wrapper_fd_handler, + NULL); + torture_assert_not_null_goto(tctx, fde, ok, done, + "tevent_add_fd failed\n"); + + te = tevent_add_timer(wrap_ev, frame, + timeval_current_ofs(0, 0), + test_free_wrapper_timer_handler, NULL); + torture_assert_not_null_goto(tctx, te, ok, done, + "tevent_add_timer failed\n"); + + im = tevent_create_immediate(frame); + torture_assert_not_null_goto(tctx, im, ok, done, + "tevent_create_immediate failed\n"); + + se = tevent_add_signal(wrap_ev, frame, + SIGUSR1, + 0, + test_free_wrapper_signal_handler, + tctx); + torture_assert_not_null_goto(tctx, se, ok, done, + "tevent_add_signal failed\n"); + + do_write(sock[0], &c, 1); + kill(getpid(), SIGUSR1); + tevent_schedule_immediate(im, + wrap_ev, + test_free_wrapper_immediate_handler, + NULL); + + ret = tevent_loop_wait(ev); + torture_assert_goto(tctx, ret == 0, ok, done, "tevent_loop_wait failed\n"); + + ok = true; + +done: + TALLOC_FREE(frame); + + if (sock[0] != -1) { + close(sock[0]); + } + if (sock[1] != -1) { + close(sock[1]); + } + return ok; +} + +#ifdef HAVE_PTHREAD + +static pthread_mutex_t threaded_mutex = PTHREAD_MUTEX_INITIALIZER; +static bool do_shutdown = false; + +static void test_event_threaded_lock(void) +{ + int ret; + ret = pthread_mutex_lock(&threaded_mutex); + assert(ret == 0); +} + +static void test_event_threaded_unlock(void) +{ + int ret; + ret = pthread_mutex_unlock(&threaded_mutex); + assert(ret == 0); +} + +static void test_event_threaded_trace(enum tevent_trace_point point, + void *private_data) +{ + switch (point) { + case TEVENT_TRACE_BEFORE_WAIT: + test_event_threaded_unlock(); + break; + case TEVENT_TRACE_AFTER_WAIT: + test_event_threaded_lock(); + break; + case TEVENT_TRACE_BEFORE_LOOP_ONCE: + case TEVENT_TRACE_AFTER_LOOP_ONCE: + break; + } +} + +static void test_event_threaded_timer(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval current_time, + void *private_data) +{ + return; +} + +static void *test_event_poll_thread(void *private_data) +{ + struct tevent_context *ev = (struct tevent_context *)private_data; + + test_event_threaded_lock(); + + while (true) { + int ret; + ret = tevent_loop_once(ev); + assert(ret == 0); + if (do_shutdown) { + test_event_threaded_unlock(); + return NULL; + } + } + +} + +static void test_event_threaded_read_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, + void *private_data) +{ + int *pfd = (int *)private_data; + char c; + ssize_t nread; + + if ((flags & TEVENT_FD_READ) == 0) { + return; + } + + do { + nread = read(*pfd, &c, 1); + } while ((nread == -1) && (errno == EINTR)); + + assert(nread == 1); +} + +static bool test_event_context_threaded(struct torture_context *test, + const void *test_data) +{ + struct tevent_context *ev; + struct tevent_timer *te; + struct tevent_fd *fde; + pthread_t poll_thread; + int fds[2]; + int ret; + char c = 0; + + ev = tevent_context_init_byname(test, "poll_mt"); + torture_assert(test, ev != NULL, "poll_mt not supported"); + + tevent_set_trace_callback(ev, test_event_threaded_trace, NULL); + + te = tevent_add_timer(ev, ev, timeval_current_ofs(5, 0), + test_event_threaded_timer, NULL); + torture_assert(test, te != NULL, "Could not add timer"); + + ret = pthread_create(&poll_thread, NULL, test_event_poll_thread, ev); + torture_assert(test, ret == 0, "Could not create poll thread"); + + ret = pipe(fds); + torture_assert(test, ret == 0, "Could not create pipe"); + + poll(NULL, 0, 100); + + test_event_threaded_lock(); + + fde = tevent_add_fd(ev, ev, fds[0], TEVENT_FD_READ, + test_event_threaded_read_handler, &fds[0]); + torture_assert(test, fde != NULL, "Could not add fd event"); + + test_event_threaded_unlock(); + + poll(NULL, 0, 100); + + do_write(fds[1], &c, 1); + + poll(NULL, 0, 100); + + test_event_threaded_lock(); + do_shutdown = true; + test_event_threaded_unlock(); + + do_write(fds[1], &c, 1); + + ret = pthread_join(poll_thread, NULL); + torture_assert(test, ret == 0, "pthread_join failed"); + + return true; +} + +#define NUM_TEVENT_THREADS 100 + +/* Ugly, but needed for torture_comment... */ +static struct torture_context *thread_test_ctx; +static pthread_t thread_map[NUM_TEVENT_THREADS]; +static unsigned thread_counter; + +/* Called in master thread context */ +static void callback_nowait(struct tevent_context *ev, + struct tevent_immediate *im, + void *private_ptr) +{ + pthread_t *thread_id_ptr = + talloc_get_type_abort(private_ptr, pthread_t); + unsigned i; + + for (i = 0; i < NUM_TEVENT_THREADS; i++) { + if (pthread_equal(*thread_id_ptr, + thread_map[i])) { + break; + } + } + torture_comment(thread_test_ctx, + "Callback %u from thread %u\n", + thread_counter, + i); + thread_counter++; +} + +/* Blast the master tevent_context with a callback, no waiting. */ +static void *thread_fn_nowait(void *private_ptr) +{ + struct tevent_thread_proxy *master_tp = + talloc_get_type_abort(private_ptr, struct tevent_thread_proxy); + struct tevent_immediate *im; + pthread_t *thread_id_ptr; + + im = tevent_create_immediate(NULL); + if (im == NULL) { + return NULL; + } + thread_id_ptr = talloc(NULL, pthread_t); + if (thread_id_ptr == NULL) { + return NULL; + } + *thread_id_ptr = pthread_self(); + + tevent_thread_proxy_schedule(master_tp, + &im, + callback_nowait, + &thread_id_ptr); + return NULL; +} + +static void timeout_fn(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, void *p) +{ + thread_counter = NUM_TEVENT_THREADS * 10; +} + +static bool test_multi_tevent_threaded(struct torture_context *test, + const void *test_data) +{ + unsigned i; + struct tevent_context *master_ev; + struct tevent_thread_proxy *tp; + + talloc_disable_null_tracking(); + + /* Ugly global stuff. */ + thread_test_ctx = test; + thread_counter = 0; + + master_ev = tevent_context_init(NULL); + if (master_ev == NULL) { + return false; + } + tevent_set_debug_stderr(master_ev); + + tp = tevent_thread_proxy_create(master_ev); + if (tp == NULL) { + torture_fail(test, + talloc_asprintf(test, + "tevent_thread_proxy_create failed\n")); + talloc_free(master_ev); + return false; + } + + for (i = 0; i < NUM_TEVENT_THREADS; i++) { + int ret = pthread_create(&thread_map[i], + NULL, + thread_fn_nowait, + tp); + if (ret != 0) { + torture_fail(test, + talloc_asprintf(test, + "Failed to create thread %i, %d\n", + i, ret)); + return false; + } + } + + /* Ensure we don't wait more than 10 seconds. */ + tevent_add_timer(master_ev, + master_ev, + timeval_current_ofs(10,0), + timeout_fn, + NULL); + + while (thread_counter < NUM_TEVENT_THREADS) { + int ret = tevent_loop_once(master_ev); + torture_assert(test, ret == 0, "tevent_loop_once failed"); + } + + torture_assert(test, thread_counter == NUM_TEVENT_THREADS, + "thread_counter fail\n"); + + talloc_free(master_ev); + return true; +} + +struct reply_state { + struct tevent_thread_proxy *reply_tp; + pthread_t thread_id; + int *p_finished; +}; + +static void thread_timeout_fn(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval tv, void *p) +{ + int *p_finished = (int *)p; + + *p_finished = 2; +} + +/* Called in child-thread context */ +static void thread_callback(struct tevent_context *ev, + struct tevent_immediate *im, + void *private_ptr) +{ + struct reply_state *rsp = + talloc_get_type_abort(private_ptr, struct reply_state); + + talloc_steal(ev, rsp); + *rsp->p_finished = 1; +} + +/* Called in master thread context */ +static void master_callback(struct tevent_context *ev, + struct tevent_immediate *im, + void *private_ptr) +{ + struct reply_state *rsp = + talloc_get_type_abort(private_ptr, struct reply_state); + unsigned i; + + talloc_steal(ev, rsp); + + for (i = 0; i < NUM_TEVENT_THREADS; i++) { + if (pthread_equal(rsp->thread_id, + thread_map[i])) { + break; + } + } + torture_comment(thread_test_ctx, + "Callback %u from thread %u\n", + thread_counter, + i); + /* Now reply to the thread ! */ + tevent_thread_proxy_schedule(rsp->reply_tp, + &im, + thread_callback, + &rsp); + + thread_counter++; +} + +static void *thread_fn_1(void *private_ptr) +{ + struct tevent_thread_proxy *master_tp = + talloc_get_type_abort(private_ptr, struct tevent_thread_proxy); + struct tevent_thread_proxy *tp; + struct tevent_immediate *im; + struct tevent_context *ev; + struct reply_state *rsp; + int finished = 0; + int ret; + + ev = tevent_context_init(NULL); + if (ev == NULL) { + return NULL; + } + + tp = tevent_thread_proxy_create(ev); + if (tp == NULL) { + talloc_free(ev); + return NULL; + } + + im = tevent_create_immediate(ev); + if (im == NULL) { + talloc_free(ev); + return NULL; + } + + rsp = talloc(ev, struct reply_state); + if (rsp == NULL) { + talloc_free(ev); + return NULL; + } + + rsp->thread_id = pthread_self(); + rsp->reply_tp = tp; + rsp->p_finished = &finished; + + /* Introduce a little randomness into the mix.. */ + usleep(random() % 7000); + + tevent_thread_proxy_schedule(master_tp, + &im, + master_callback, + &rsp); + + /* Ensure we don't wait more than 10 seconds. */ + tevent_add_timer(ev, + ev, + timeval_current_ofs(10,0), + thread_timeout_fn, + &finished); + + while (finished == 0) { + ret = tevent_loop_once(ev); + assert(ret == 0); + } + + if (finished > 1) { + /* Timeout ! */ + abort(); + } + + /* + * NB. We should talloc_free(ev) here, but if we do + * we currently get hit by helgrind Fix #323432 + * "When calling pthread_cond_destroy or pthread_mutex_destroy + * with initializers as argument Helgrind (incorrectly) reports errors." + * + * http://valgrind.10908.n7.nabble.com/Helgrind-3-9-0-false-positive- + * with-pthread-mutex-destroy-td47757.html + * + * Helgrind doesn't understand that the request/reply + * messages provide synchronization between the lock/unlock + * in tevent_thread_proxy_schedule(), and the pthread_destroy() + * when the struct tevent_thread_proxy object is talloc_free'd. + * + * As a work-around for now return ev for the parent thread to free. + */ + return ev; +} + +static bool test_multi_tevent_threaded_1(struct torture_context *test, + const void *test_data) +{ + unsigned i; + struct tevent_context *master_ev; + struct tevent_thread_proxy *master_tp; + int ret; + + talloc_disable_null_tracking(); + + /* Ugly global stuff. */ + thread_test_ctx = test; + thread_counter = 0; + + master_ev = tevent_context_init(NULL); + if (master_ev == NULL) { + return false; + } + tevent_set_debug_stderr(master_ev); + + master_tp = tevent_thread_proxy_create(master_ev); + if (master_tp == NULL) { + torture_fail(test, + talloc_asprintf(test, + "tevent_thread_proxy_create failed\n")); + talloc_free(master_ev); + return false; + } + + for (i = 0; i < NUM_TEVENT_THREADS; i++) { + ret = pthread_create(&thread_map[i], + NULL, + thread_fn_1, + master_tp); + if (ret != 0) { + torture_fail(test, + talloc_asprintf(test, + "Failed to create thread %i, %d\n", + i, ret)); + return false; + } + } + + while (thread_counter < NUM_TEVENT_THREADS) { + ret = tevent_loop_once(master_ev); + torture_assert(test, ret == 0, "tevent_loop_once failed"); + } + + /* Wait for all the threads to finish - join 'em. */ + for (i = 0; i < NUM_TEVENT_THREADS; i++) { + void *retval; + ret = pthread_join(thread_map[i], &retval); + torture_assert(test, ret == 0, "pthread_join failed"); + /* Free the child thread event context. */ + talloc_free(retval); + } + + talloc_free(master_ev); + return true; +} + +struct threaded_test_2 { + struct tevent_threaded_context *tctx; + struct tevent_immediate *im; + pthread_t thread_id; +}; + +static void master_callback_2(struct tevent_context *ev, + struct tevent_immediate *im, + void *private_data); + +static void *thread_fn_2(void *private_data) +{ + struct threaded_test_2 *state = private_data; + + state->thread_id = pthread_self(); + + usleep(random() % 7000); + + tevent_threaded_schedule_immediate( + state->tctx, state->im, master_callback_2, state); + + return NULL; +} + +static void master_callback_2(struct tevent_context *ev, + struct tevent_immediate *im, + void *private_data) +{ + struct threaded_test_2 *state = private_data; + int i; + + for (i = 0; i < NUM_TEVENT_THREADS; i++) { + if (pthread_equal(state->thread_id, thread_map[i])) { + break; + } + } + torture_comment(thread_test_ctx, + "Callback_2 %u from thread %u\n", + thread_counter, + i); + thread_counter++; +} + +static bool test_multi_tevent_threaded_2(struct torture_context *test, + const void *test_data) +{ + unsigned i; + + struct tevent_context *ev; + struct tevent_threaded_context *tctx; + int ret; + + thread_test_ctx = test; + thread_counter = 0; + + ev = tevent_context_init(test); + torture_assert(test, ev != NULL, "tevent_context_init failed"); + + /* + * tevent_re_initialise used to have a bug where it did not + * re-initialise the thread support after taking it + * down. Exercise that code path. + */ + ret = tevent_re_initialise(ev); + torture_assert(test, ret == 0, "tevent_re_initialise failed"); + + tctx = tevent_threaded_context_create(ev, ev); + torture_assert(test, tctx != NULL, + "tevent_threaded_context_create failed"); + + for (i=0; itctx = tctx; + state->im = tevent_create_immediate(state); + torture_assert(test, state->im != NULL, + "tevent_create_immediate failed"); + + ret = pthread_create(&thread_map[i], NULL, thread_fn_2, state); + torture_assert(test, ret == 0, "pthread_create failed"); + } + + while (thread_counter < NUM_TEVENT_THREADS) { + ret = tevent_loop_once(ev); + torture_assert(test, ret == 0, "tevent_loop_once failed"); + } + + /* Wait for all the threads to finish - join 'em. */ + for (i = 0; i < NUM_TEVENT_THREADS; i++) { + void *retval; + ret = pthread_join(thread_map[i], &retval); + torture_assert(test, ret == 0, "pthread_join failed"); + /* Free the child thread event context. */ + } + + talloc_free(tctx); + talloc_free(ev); + return true; +} +#endif + +struct torture_suite *torture_local_event(TALLOC_CTX *mem_ctx) +{ + struct torture_suite *suite = torture_suite_create(mem_ctx, "event"); + const char **list = tevent_backend_list(suite); + int i; + + for (i=0;list && list[i];i++) { + struct torture_suite *backend_suite; + + backend_suite = torture_suite_create(mem_ctx, list[i]); + + torture_suite_add_simple_tcase_const(backend_suite, + "context", + test_event_context, + (const void *)list[i]); + torture_suite_add_simple_tcase_const(backend_suite, + "fd1", + test_event_fd1, + (const void *)list[i]); + torture_suite_add_simple_tcase_const(backend_suite, + "fd2", + test_event_fd2, + (const void *)list[i]); + torture_suite_add_simple_tcase_const(backend_suite, + "wrapper", + test_wrapper, + (const void *)list[i]); + torture_suite_add_simple_tcase_const(backend_suite, + "free_wrapper", + test_free_wrapper, + (const void *)list[i]); + + torture_suite_add_suite(suite, backend_suite); + } + +#ifdef HAVE_PTHREAD + torture_suite_add_simple_tcase_const(suite, "threaded_poll_mt", + test_event_context_threaded, + NULL); + + torture_suite_add_simple_tcase_const(suite, "multi_tevent_threaded", + test_multi_tevent_threaded, + NULL); + + torture_suite_add_simple_tcase_const(suite, "multi_tevent_threaded_1", + test_multi_tevent_threaded_1, + NULL); + + torture_suite_add_simple_tcase_const(suite, "multi_tevent_threaded_2", + test_multi_tevent_threaded_2, + NULL); + +#endif + + return suite; +} diff --git a/ldb-2.0.8/lib/tevent/tevent.c b/ldb-2.0.8/lib/tevent/tevent.c new file mode 100644 index 0000000..dbec182 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent.c @@ -0,0 +1,1037 @@ +/* + Unix SMB/CIFS implementation. + main select loop and event handling + Copyright (C) Andrew Tridgell 2003 + Copyright (C) Stefan Metzmacher 2009 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + PLEASE READ THIS BEFORE MODIFYING! + + This module is a general abstraction for the main select loop and + event handling. Do not ever put any localised hacks in here, instead + register one of the possible event types and implement that event + somewhere else. + + There are 2 types of event handling that are handled in this module: + + 1) a file descriptor becoming readable or writeable. This is mostly + used for network sockets, but can be used for any type of file + descriptor. You may only register one handler for each file + descriptor/io combination or you will get unpredictable results + (this means that you can have a handler for read events, and a + separate handler for write events, but not two handlers that are + both handling read events) + + 2) a timed event. You can register an event that happens at a + specific time. You can register as many of these as you + like. They are single shot - add a new timed event in the event + handler to get another event. + + To setup a set of events you first need to create a event_context + structure using the function tevent_context_init(); This returns a + 'struct tevent_context' that you use in all subsequent calls. + + After that you can add/remove events that you are interested in + using tevent_add_*() and talloc_free() + + Finally, you call tevent_loop_wait_once() to block waiting for one of the + events to occor or tevent_loop_wait() which will loop + forever. + +*/ +#include "replace.h" +#include "system/filesys.h" +#ifdef HAVE_PTHREAD +#include "system/threads.h" +#endif +#define TEVENT_DEPRECATED 1 +#include "tevent.h" +#include "tevent_internal.h" +#include "tevent_util.h" +#ifdef HAVE_EVENTFD +#include +#endif + +struct tevent_ops_list { + struct tevent_ops_list *next, *prev; + const char *name; + const struct tevent_ops *ops; +}; + +/* list of registered event backends */ +static struct tevent_ops_list *tevent_backends = NULL; +static char *tevent_default_backend = NULL; + +/* + register an events backend +*/ +bool tevent_register_backend(const char *name, const struct tevent_ops *ops) +{ + struct tevent_ops_list *e; + + for (e = tevent_backends; e != NULL; e = e->next) { + if (0 == strcmp(e->name, name)) { + /* already registered, skip it */ + return true; + } + } + + e = talloc(NULL, struct tevent_ops_list); + if (e == NULL) return false; + + e->name = name; + e->ops = ops; + DLIST_ADD(tevent_backends, e); + + return true; +} + +/* + set the default event backend + */ +void tevent_set_default_backend(const char *backend) +{ + talloc_free(tevent_default_backend); + tevent_default_backend = talloc_strdup(NULL, backend); +} + +/* + initialise backends if not already done +*/ +static void tevent_backend_init(void) +{ + static bool done; + + if (done) { + return; + } + + done = true; + + tevent_poll_init(); + tevent_poll_mt_init(); +#if defined(HAVE_EPOLL) + tevent_epoll_init(); +#elif defined(HAVE_SOLARIS_PORTS) + tevent_port_init(); +#endif + + tevent_standard_init(); +} + +_PRIVATE_ const struct tevent_ops *tevent_find_ops_byname(const char *name) +{ + struct tevent_ops_list *e; + + tevent_backend_init(); + + if (name == NULL) { + name = tevent_default_backend; + } + if (name == NULL) { + name = "standard"; + } + + for (e = tevent_backends; e != NULL; e = e->next) { + if (0 == strcmp(e->name, name)) { + return e->ops; + } + } + + return NULL; +} + +/* + list available backends +*/ +const char **tevent_backend_list(TALLOC_CTX *mem_ctx) +{ + const char **list = NULL; + struct tevent_ops_list *e; + + tevent_backend_init(); + + for (e=tevent_backends;e;e=e->next) { + list = ev_str_list_add(list, e->name); + } + + talloc_steal(mem_ctx, list); + + return list; +} + +static void tevent_common_wakeup_fini(struct tevent_context *ev); + +#ifdef HAVE_PTHREAD + +static pthread_mutex_t tevent_contexts_mutex = PTHREAD_MUTEX_INITIALIZER; +static struct tevent_context *tevent_contexts = NULL; +static pthread_once_t tevent_atfork_initialized = PTHREAD_ONCE_INIT; + +static void tevent_atfork_prepare(void) +{ + struct tevent_context *ev; + int ret; + + ret = pthread_mutex_lock(&tevent_contexts_mutex); + if (ret != 0) { + abort(); + } + + for (ev = tevent_contexts; ev != NULL; ev = ev->next) { + struct tevent_threaded_context *tctx; + + for (tctx = ev->threaded_contexts; tctx != NULL; + tctx = tctx->next) { + ret = pthread_mutex_lock(&tctx->event_ctx_mutex); + if (ret != 0) { + tevent_abort(ev, "pthread_mutex_lock failed"); + } + } + + ret = pthread_mutex_lock(&ev->scheduled_mutex); + if (ret != 0) { + tevent_abort(ev, "pthread_mutex_lock failed"); + } + } +} + +static void tevent_atfork_parent(void) +{ + struct tevent_context *ev; + int ret; + + for (ev = DLIST_TAIL(tevent_contexts); ev != NULL; + ev = DLIST_PREV(ev)) { + struct tevent_threaded_context *tctx; + + ret = pthread_mutex_unlock(&ev->scheduled_mutex); + if (ret != 0) { + tevent_abort(ev, "pthread_mutex_unlock failed"); + } + + for (tctx = DLIST_TAIL(ev->threaded_contexts); tctx != NULL; + tctx = DLIST_PREV(tctx)) { + ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); + if (ret != 0) { + tevent_abort( + ev, "pthread_mutex_unlock failed"); + } + } + } + + ret = pthread_mutex_unlock(&tevent_contexts_mutex); + if (ret != 0) { + abort(); + } +} + +static void tevent_atfork_child(void) +{ + struct tevent_context *ev; + int ret; + + for (ev = DLIST_TAIL(tevent_contexts); ev != NULL; + ev = DLIST_PREV(ev)) { + struct tevent_threaded_context *tctx; + + for (tctx = DLIST_TAIL(ev->threaded_contexts); tctx != NULL; + tctx = DLIST_PREV(tctx)) { + tctx->event_ctx = NULL; + + ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); + if (ret != 0) { + tevent_abort( + ev, "pthread_mutex_unlock failed"); + } + } + + ev->threaded_contexts = NULL; + + ret = pthread_mutex_unlock(&ev->scheduled_mutex); + if (ret != 0) { + tevent_abort(ev, "pthread_mutex_unlock failed"); + } + } + + ret = pthread_mutex_unlock(&tevent_contexts_mutex); + if (ret != 0) { + abort(); + } +} + +static void tevent_prep_atfork(void) +{ + int ret; + + ret = pthread_atfork(tevent_atfork_prepare, + tevent_atfork_parent, + tevent_atfork_child); + if (ret != 0) { + abort(); + } +} + +#endif + +int tevent_common_context_destructor(struct tevent_context *ev) +{ + struct tevent_fd *fd, *fn; + struct tevent_timer *te, *tn; + struct tevent_immediate *ie, *in; + struct tevent_signal *se, *sn; + struct tevent_wrapper_glue *gl, *gn; +#ifdef HAVE_PTHREAD + int ret; +#endif + + if (ev->wrapper.glue != NULL) { + tevent_abort(ev, + "tevent_common_context_destructor() active on wrapper"); + } + +#ifdef HAVE_PTHREAD + ret = pthread_mutex_lock(&tevent_contexts_mutex); + if (ret != 0) { + abort(); + } + + DLIST_REMOVE(tevent_contexts, ev); + + ret = pthread_mutex_unlock(&tevent_contexts_mutex); + if (ret != 0) { + abort(); + } + + while (ev->threaded_contexts != NULL) { + struct tevent_threaded_context *tctx = ev->threaded_contexts; + + ret = pthread_mutex_lock(&tctx->event_ctx_mutex); + if (ret != 0) { + abort(); + } + + /* + * Indicate to the thread that the tevent_context is + * gone. The counterpart of this is in + * _tevent_threaded_schedule_immediate, there we read + * this under the threaded_context's mutex. + */ + + tctx->event_ctx = NULL; + + ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); + if (ret != 0) { + abort(); + } + + DLIST_REMOVE(ev->threaded_contexts, tctx); + } + + ret = pthread_mutex_destroy(&ev->scheduled_mutex); + if (ret != 0) { + abort(); + } +#endif + + for (gl = ev->wrapper.list; gl; gl = gn) { + gn = gl->next; + + gl->main_ev = NULL; + DLIST_REMOVE(ev->wrapper.list, gl); + } + + tevent_common_wakeup_fini(ev); + + for (fd = ev->fd_events; fd; fd = fn) { + fn = fd->next; + fd->wrapper = NULL; + fd->event_ctx = NULL; + DLIST_REMOVE(ev->fd_events, fd); + } + + ev->last_zero_timer = NULL; + for (te = ev->timer_events; te; te = tn) { + tn = te->next; + te->wrapper = NULL; + te->event_ctx = NULL; + DLIST_REMOVE(ev->timer_events, te); + } + + for (ie = ev->immediate_events; ie; ie = in) { + in = ie->next; + ie->wrapper = NULL; + ie->event_ctx = NULL; + ie->cancel_fn = NULL; + DLIST_REMOVE(ev->immediate_events, ie); + } + + for (se = ev->signal_events; se; se = sn) { + sn = se->next; + se->wrapper = NULL; + se->event_ctx = NULL; + DLIST_REMOVE(ev->signal_events, se); + /* + * This is important, Otherwise signals + * are handled twice in child. eg, SIGHUP. + * one added in parent, and another one in + * the child. -- BoYang + */ + tevent_cleanup_pending_signal_handlers(se); + } + + /* removing nesting hook or we get an abort when nesting is + * not allowed. -- SSS + * Note that we need to leave the allowed flag at its current + * value, otherwise the use in tevent_re_initialise() will + * leave the event context with allowed forced to false, which + * will break users that expect nesting to be allowed + */ + ev->nesting.level = 0; + ev->nesting.hook_fn = NULL; + ev->nesting.hook_private = NULL; + + return 0; +} + +static int tevent_common_context_constructor(struct tevent_context *ev) +{ + int ret; + +#ifdef HAVE_PTHREAD + + ret = pthread_once(&tevent_atfork_initialized, tevent_prep_atfork); + if (ret != 0) { + return ret; + } + + ret = pthread_mutex_init(&ev->scheduled_mutex, NULL); + if (ret != 0) { + return ret; + } + + ret = pthread_mutex_lock(&tevent_contexts_mutex); + if (ret != 0) { + pthread_mutex_destroy(&ev->scheduled_mutex); + return ret; + } + + DLIST_ADD(tevent_contexts, ev); + + ret = pthread_mutex_unlock(&tevent_contexts_mutex); + if (ret != 0) { + abort(); + } +#endif + + talloc_set_destructor(ev, tevent_common_context_destructor); + + return 0; +} + +void tevent_common_check_double_free(TALLOC_CTX *ptr, const char *reason) +{ + void *parent_ptr = talloc_parent(ptr); + size_t parent_blocks = talloc_total_blocks(parent_ptr); + + if (parent_ptr != NULL && parent_blocks == 0) { + /* + * This is an implicit talloc free, as we still have a parent + * but it's already being destroyed. Note that + * talloc_total_blocks(ptr) also just returns 0 if a + * talloc_free(ptr) is still in progress of freeing all + * children. + */ + return; + } + + tevent_abort(NULL, reason); +} + +/* + create a event_context structure for a specific implemementation. + This must be the first events call, and all subsequent calls pass + this event_context as the first element. Event handlers also + receive this as their first argument. + + This function is for allowing third-party-applications to hook in gluecode + to their own event loop code, so that they can make async usage of our client libs + + NOTE: use tevent_context_init() inside of samba! +*/ +struct tevent_context *tevent_context_init_ops(TALLOC_CTX *mem_ctx, + const struct tevent_ops *ops, + void *additional_data) +{ + struct tevent_context *ev; + int ret; + + ev = talloc_zero(mem_ctx, struct tevent_context); + if (!ev) return NULL; + + ret = tevent_common_context_constructor(ev); + if (ret != 0) { + talloc_free(ev); + return NULL; + } + + ev->ops = ops; + ev->additional_data = additional_data; + + ret = ev->ops->context_init(ev); + if (ret != 0) { + talloc_free(ev); + return NULL; + } + + return ev; +} + +/* + create a event_context structure. This must be the first events + call, and all subsequent calls pass this event_context as the first + element. Event handlers also receive this as their first argument. +*/ +struct tevent_context *tevent_context_init_byname(TALLOC_CTX *mem_ctx, + const char *name) +{ + const struct tevent_ops *ops; + + ops = tevent_find_ops_byname(name); + if (ops == NULL) { + return NULL; + } + + return tevent_context_init_ops(mem_ctx, ops, NULL); +} + + +/* + create a event_context structure. This must be the first events + call, and all subsequent calls pass this event_context as the first + element. Event handlers also receive this as their first argument. +*/ +struct tevent_context *tevent_context_init(TALLOC_CTX *mem_ctx) +{ + return tevent_context_init_byname(mem_ctx, NULL); +} + +/* + add a fd based event + return NULL on failure (memory allocation error) +*/ +struct tevent_fd *_tevent_add_fd(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + int fd, + uint16_t flags, + tevent_fd_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + return ev->ops->add_fd(ev, mem_ctx, fd, flags, handler, private_data, + handler_name, location); +} + +/* + set a close function on the fd event +*/ +void tevent_fd_set_close_fn(struct tevent_fd *fde, + tevent_fd_close_fn_t close_fn) +{ + if (!fde) return; + if (!fde->event_ctx) return; + fde->event_ctx->ops->set_fd_close_fn(fde, close_fn); +} + +static void tevent_fd_auto_close_fn(struct tevent_context *ev, + struct tevent_fd *fde, + int fd, + void *private_data) +{ + close(fd); +} + +void tevent_fd_set_auto_close(struct tevent_fd *fde) +{ + tevent_fd_set_close_fn(fde, tevent_fd_auto_close_fn); +} + +/* + return the fd event flags +*/ +uint16_t tevent_fd_get_flags(struct tevent_fd *fde) +{ + if (!fde) return 0; + if (!fde->event_ctx) return 0; + return fde->event_ctx->ops->get_fd_flags(fde); +} + +/* + set the fd event flags +*/ +void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags) +{ + if (!fde) return; + if (!fde->event_ctx) return; + fde->event_ctx->ops->set_fd_flags(fde, flags); +} + +bool tevent_signal_support(struct tevent_context *ev) +{ + if (ev->ops->add_signal) { + return true; + } + return false; +} + +static void (*tevent_abort_fn)(const char *reason); + +void tevent_set_abort_fn(void (*abort_fn)(const char *reason)) +{ + tevent_abort_fn = abort_fn; +} + +void tevent_abort(struct tevent_context *ev, const char *reason) +{ + if (ev != NULL) { + tevent_debug(ev, TEVENT_DEBUG_FATAL, + "abort: %s\n", reason); + } + + if (!tevent_abort_fn) { + abort(); + } + + tevent_abort_fn(reason); +} + +/* + add a timer event + return NULL on failure +*/ +struct tevent_timer *_tevent_add_timer(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + struct timeval next_event, + tevent_timer_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + return ev->ops->add_timer(ev, mem_ctx, next_event, handler, private_data, + handler_name, location); +} + +/* + allocate an immediate event + return NULL on failure (memory allocation error) +*/ +struct tevent_immediate *_tevent_create_immediate(TALLOC_CTX *mem_ctx, + const char *location) +{ + struct tevent_immediate *im; + + im = talloc(mem_ctx, struct tevent_immediate); + if (im == NULL) return NULL; + + *im = (struct tevent_immediate) { .create_location = location }; + + return im; +} + +/* + schedule an immediate event +*/ +void _tevent_schedule_immediate(struct tevent_immediate *im, + struct tevent_context *ev, + tevent_immediate_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + ev->ops->schedule_immediate(im, ev, handler, private_data, + handler_name, location); +} + +/* + add a signal event + + sa_flags are flags to sigaction(2) + + return NULL on failure +*/ +struct tevent_signal *_tevent_add_signal(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + int signum, + int sa_flags, + tevent_signal_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + return ev->ops->add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data, + handler_name, location); +} + +void tevent_loop_allow_nesting(struct tevent_context *ev) +{ + if (ev->wrapper.glue != NULL) { + tevent_abort(ev, "tevent_loop_allow_nesting() on wrapper"); + return; + } + + if (ev->wrapper.list != NULL) { + tevent_abort(ev, "tevent_loop_allow_nesting() with wrapper"); + return; + } + + ev->nesting.allowed = true; +} + +void tevent_loop_set_nesting_hook(struct tevent_context *ev, + tevent_nesting_hook hook, + void *private_data) +{ + if (ev->nesting.hook_fn && + (ev->nesting.hook_fn != hook || + ev->nesting.hook_private != private_data)) { + /* the way the nesting hook code is currently written + we cannot support two different nesting hooks at the + same time. */ + tevent_abort(ev, "tevent: Violation of nesting hook rules\n"); + } + ev->nesting.hook_fn = hook; + ev->nesting.hook_private = private_data; +} + +static void tevent_abort_nesting(struct tevent_context *ev, const char *location) +{ + const char *reason; + + reason = talloc_asprintf(NULL, "tevent_loop_once() nesting at %s", + location); + if (!reason) { + reason = "tevent_loop_once() nesting"; + } + + tevent_abort(ev, reason); +} + +/* + do a single event loop using the events defined in ev +*/ +int _tevent_loop_once(struct tevent_context *ev, const char *location) +{ + int ret; + void *nesting_stack_ptr = NULL; + + ev->nesting.level++; + + if (ev->nesting.level > 1) { + if (!ev->nesting.allowed) { + tevent_abort_nesting(ev, location); + errno = ELOOP; + return -1; + } + } + if (ev->nesting.level > 0) { + if (ev->nesting.hook_fn) { + int ret2; + ret2 = ev->nesting.hook_fn(ev, + ev->nesting.hook_private, + ev->nesting.level, + true, + (void *)&nesting_stack_ptr, + location); + if (ret2 != 0) { + ret = ret2; + goto done; + } + } + } + + tevent_trace_point_callback(ev, TEVENT_TRACE_BEFORE_LOOP_ONCE); + ret = ev->ops->loop_once(ev, location); + tevent_trace_point_callback(ev, TEVENT_TRACE_AFTER_LOOP_ONCE); + + if (ev->nesting.level > 0) { + if (ev->nesting.hook_fn) { + int ret2; + ret2 = ev->nesting.hook_fn(ev, + ev->nesting.hook_private, + ev->nesting.level, + false, + (void *)&nesting_stack_ptr, + location); + if (ret2 != 0) { + ret = ret2; + goto done; + } + } + } + +done: + ev->nesting.level--; + return ret; +} + +/* + this is a performance optimization for the samba4 nested event loop problems +*/ +int _tevent_loop_until(struct tevent_context *ev, + bool (*finished)(void *private_data), + void *private_data, + const char *location) +{ + int ret = 0; + void *nesting_stack_ptr = NULL; + + ev->nesting.level++; + + if (ev->nesting.level > 1) { + if (!ev->nesting.allowed) { + tevent_abort_nesting(ev, location); + errno = ELOOP; + return -1; + } + } + if (ev->nesting.level > 0) { + if (ev->nesting.hook_fn) { + int ret2; + ret2 = ev->nesting.hook_fn(ev, + ev->nesting.hook_private, + ev->nesting.level, + true, + (void *)&nesting_stack_ptr, + location); + if (ret2 != 0) { + ret = ret2; + goto done; + } + } + } + + while (!finished(private_data)) { + tevent_trace_point_callback(ev, TEVENT_TRACE_BEFORE_LOOP_ONCE); + ret = ev->ops->loop_once(ev, location); + tevent_trace_point_callback(ev, TEVENT_TRACE_AFTER_LOOP_ONCE); + if (ret != 0) { + break; + } + } + + if (ev->nesting.level > 0) { + if (ev->nesting.hook_fn) { + int ret2; + ret2 = ev->nesting.hook_fn(ev, + ev->nesting.hook_private, + ev->nesting.level, + false, + (void *)&nesting_stack_ptr, + location); + if (ret2 != 0) { + ret = ret2; + goto done; + } + } + } + +done: + ev->nesting.level--; + return ret; +} + +bool tevent_common_have_events(struct tevent_context *ev) +{ + if (ev->fd_events != NULL) { + if (ev->fd_events != ev->wakeup_fde) { + return true; + } + if (ev->fd_events->next != NULL) { + return true; + } + + /* + * At this point we just have the wakeup pipe event as + * the only fd_event. That one does not count as a + * regular event, so look at the other event types. + */ + } + + return ((ev->timer_events != NULL) || + (ev->immediate_events != NULL) || + (ev->signal_events != NULL)); +} + +/* + return on failure or (with 0) if all fd events are removed +*/ +int tevent_common_loop_wait(struct tevent_context *ev, + const char *location) +{ + /* + * loop as long as we have events pending + */ + while (tevent_common_have_events(ev)) { + int ret; + ret = _tevent_loop_once(ev, location); + if (ret != 0) { + tevent_debug(ev, TEVENT_DEBUG_FATAL, + "_tevent_loop_once() failed: %d - %s\n", + ret, strerror(errno)); + return ret; + } + } + + tevent_debug(ev, TEVENT_DEBUG_WARNING, + "tevent_common_loop_wait() out of events\n"); + return 0; +} + +/* + return on failure or (with 0) if all fd events are removed +*/ +int _tevent_loop_wait(struct tevent_context *ev, const char *location) +{ + return ev->ops->loop_wait(ev, location); +} + + +/* + re-initialise a tevent context. This leaves you with the same + event context, but all events are wiped and the structure is + re-initialised. This is most useful after a fork() + + zero is returned on success, non-zero on failure +*/ +int tevent_re_initialise(struct tevent_context *ev) +{ + tevent_common_context_destructor(ev); + + tevent_common_context_constructor(ev); + + return ev->ops->context_init(ev); +} + +static void wakeup_pipe_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *_private) +{ + ssize_t ret; + + do { + /* + * This is the boilerplate for eventfd, but it works + * for pipes too. And as we don't care about the data + * we read, we're fine. + */ + uint64_t val; + ret = read(fde->fd, &val, sizeof(val)); + } while (ret == -1 && errno == EINTR); +} + +/* + * Initialize the wakeup pipe and pipe fde + */ + +int tevent_common_wakeup_init(struct tevent_context *ev) +{ + int ret, read_fd; + + if (ev->wakeup_fde != NULL) { + return 0; + } + +#ifdef HAVE_EVENTFD + ret = eventfd(0, EFD_NONBLOCK); + if (ret == -1) { + return errno; + } + read_fd = ev->wakeup_fd = ret; +#else + { + int pipe_fds[2]; + ret = pipe(pipe_fds); + if (ret == -1) { + return errno; + } + ev->wakeup_fd = pipe_fds[1]; + ev->wakeup_read_fd = pipe_fds[0]; + + ev_set_blocking(ev->wakeup_fd, false); + ev_set_blocking(ev->wakeup_read_fd, false); + + read_fd = ev->wakeup_read_fd; + } +#endif + + ev->wakeup_fde = tevent_add_fd(ev, ev, read_fd, TEVENT_FD_READ, + wakeup_pipe_handler, NULL); + if (ev->wakeup_fde == NULL) { + close(ev->wakeup_fd); +#ifndef HAVE_EVENTFD + close(ev->wakeup_read_fd); +#endif + return ENOMEM; + } + + return 0; +} + +int tevent_common_wakeup_fd(int fd) +{ + ssize_t ret; + + do { +#ifdef HAVE_EVENTFD + uint64_t val = 1; + ret = write(fd, &val, sizeof(val)); +#else + char c = '\0'; + ret = write(fd, &c, 1); +#endif + } while ((ret == -1) && (errno == EINTR)); + + return 0; +} + +int tevent_common_wakeup(struct tevent_context *ev) +{ + if (ev->wakeup_fde == NULL) { + return ENOTCONN; + } + + return tevent_common_wakeup_fd(ev->wakeup_fd); +} + +static void tevent_common_wakeup_fini(struct tevent_context *ev) +{ + if (ev->wakeup_fde == NULL) { + return; + } + + TALLOC_FREE(ev->wakeup_fde); + + close(ev->wakeup_fd); +#ifndef HAVE_EVENTFD + close(ev->wakeup_read_fd); +#endif +} diff --git a/ldb-2.0.8/lib/tevent/tevent.h b/ldb-2.0.8/lib/tevent/tevent.h new file mode 100644 index 0000000..3c3e3cc --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent.h @@ -0,0 +1,2511 @@ +/* + Unix SMB/CIFS implementation. + + generalised event loop handling + + Copyright (C) Andrew Tridgell 2005 + Copyright (C) Stefan Metzmacher 2005-2009 + Copyright (C) Volker Lendecke 2008 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#ifndef __TEVENT_H__ +#define __TEVENT_H__ + +#include +#include +#include +#include + +struct tevent_context; +struct tevent_ops; +struct tevent_fd; +struct tevent_timer; +struct tevent_immediate; +struct tevent_signal; +struct tevent_thread_proxy; +struct tevent_threaded_context; + +/** + * @defgroup tevent The tevent API + * + * The tevent low-level API + * + * This API provides the public interface to manage events in the tevent + * mainloop. Functions are provided for managing low-level events such + * as timer events, fd events and signal handling. + * + * @{ + */ + +/* event handler types */ +/** + * Called when a file descriptor monitored by tevent has + * data to be read or written on it. + */ +typedef void (*tevent_fd_handler_t)(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, + void *private_data); + +/** + * Called when tevent is ceasing the monitoring of a file descriptor. + */ +typedef void (*tevent_fd_close_fn_t)(struct tevent_context *ev, + struct tevent_fd *fde, + int fd, + void *private_data); + +/** + * Called when a tevent timer has fired. + */ +typedef void (*tevent_timer_handler_t)(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval current_time, + void *private_data); + +/** + * Called when a tevent immediate event is invoked. + */ +typedef void (*tevent_immediate_handler_t)(struct tevent_context *ctx, + struct tevent_immediate *im, + void *private_data); + +/** + * Called after tevent detects the specified signal. + */ +typedef void (*tevent_signal_handler_t)(struct tevent_context *ev, + struct tevent_signal *se, + int signum, + int count, + void *siginfo, + void *private_data); + +/** + * @brief Create a event_context structure. + * + * This must be the first events call, and all subsequent calls pass this + * event_context as the first element. Event handlers also receive this as + * their first argument. + * + * @param[in] mem_ctx The memory context to use. + * + * @return An allocated tevent context, NULL on error. + * + * @see tevent_context_init() + */ +struct tevent_context *tevent_context_init(TALLOC_CTX *mem_ctx); + +/** + * @brief Create a event_context structure and select a specific backend. + * + * This must be the first events call, and all subsequent calls pass this + * event_context as the first element. Event handlers also receive this as + * their first argument. + * + * @param[in] mem_ctx The memory context to use. + * + * @param[in] name The name of the backend to use. + * + * @return An allocated tevent context, NULL on error. + */ +struct tevent_context *tevent_context_init_byname(TALLOC_CTX *mem_ctx, const char *name); + +/** + * @brief Create a custom event context + * + * @param[in] mem_ctx The memory context to use. + * @param[in] ops The function pointer table of the backend. + * @param[in] additional_data The additional/private data to this instance + * + * @return An allocated tevent context, NULL on error. + * + */ +struct tevent_context *tevent_context_init_ops(TALLOC_CTX *mem_ctx, + const struct tevent_ops *ops, + void *additional_data); + +/** + * @brief List available backends. + * + * @param[in] mem_ctx The memory context to use. + * + * @return A string vector with a terminating NULL element, NULL + * on error. + */ +const char **tevent_backend_list(TALLOC_CTX *mem_ctx); + +/** + * @brief Set the default tevent backend. + * + * @param[in] backend The name of the backend to set. + */ +void tevent_set_default_backend(const char *backend); + +#ifdef DOXYGEN +/** + * @brief Add a file descriptor based event. + * + * @param[in] ev The event context to work on. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] fd The file descriptor to base the event on. + * + * @param[in] flags #TEVENT_FD_READ or #TEVENT_FD_WRITE + * + * @param[in] handler The callback handler for the event. + * + * @param[in] private_data The private data passed to the callback handler. + * + * @return The file descriptor based event, NULL on error. + * + * @note To cancel the monitoring of a file descriptor, call talloc_free() + * on the object returned by this function. + * + * @note The caller should avoid closing the file descriptor before + * calling talloc_free()! Otherwise the behaviour is undefined which + * might result in crashes. See https://bugzilla.samba.org/show_bug.cgi?id=11141 + * for an example. + */ +struct tevent_fd *tevent_add_fd(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + int fd, + uint16_t flags, + tevent_fd_handler_t handler, + void *private_data); +#else +struct tevent_fd *_tevent_add_fd(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + int fd, + uint16_t flags, + tevent_fd_handler_t handler, + void *private_data, + const char *handler_name, + const char *location); +#define tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data) \ + _tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data, \ + #handler, __location__) +#endif + +#ifdef DOXYGEN +/** + * @brief Add a timed event + * + * @param[in] ev The event context to work on. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] next_event Timeval specifying the absolute time to fire this + * event. This is not an offset. + * + * @param[in] handler The callback handler for the event. + * + * @param[in] private_data The private data passed to the callback handler. + * + * @return The newly-created timer event, or NULL on error. + * + * @note To cancel a timer event before it fires, call talloc_free() on the + * event returned from this function. This event is automatically + * talloc_free()-ed after its event handler files, if it hasn't been freed yet. + * + * @note Unlike some mainloops, tevent timers are one-time events. To set up + * a recurring event, it is necessary to call tevent_add_timer() again during + * the handler processing. + * + * @note Due to the internal mainloop processing, a timer set to run + * immediately will do so after any other pending timers fire, but before + * any further file descriptor or signal handling events fire. Callers should + * not rely on this behavior! + */ +struct tevent_timer *tevent_add_timer(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + struct timeval next_event, + tevent_timer_handler_t handler, + void *private_data); +#else +struct tevent_timer *_tevent_add_timer(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + struct timeval next_event, + tevent_timer_handler_t handler, + void *private_data, + const char *handler_name, + const char *location); +#define tevent_add_timer(ev, mem_ctx, next_event, handler, private_data) \ + _tevent_add_timer(ev, mem_ctx, next_event, handler, private_data, \ + #handler, __location__) +#endif + +/** + * @brief Set the time a tevent_timer fires + * + * @param[in] te The timer event to reset + * + * @param[in] next_event Timeval specifying the absolute time to fire this + * event. This is not an offset. + */ +void tevent_update_timer(struct tevent_timer *te, struct timeval next_event); + +#ifdef DOXYGEN +/** + * Initialize an immediate event object + * + * This object can be used to trigger an event to occur immediately after + * returning from the current event (before any other event occurs) + * + * @param[in] mem_ctx The talloc memory context to use as the parent + * + * @return An empty tevent_immediate object. Use tevent_schedule_immediate + * to populate and use it. + * + * @note Available as of tevent 0.9.8 + */ +struct tevent_immediate *tevent_create_immediate(TALLOC_CTX *mem_ctx); +#else +struct tevent_immediate *_tevent_create_immediate(TALLOC_CTX *mem_ctx, + const char *location); +#define tevent_create_immediate(mem_ctx) \ + _tevent_create_immediate(mem_ctx, __location__) +#endif + +#ifdef DOXYGEN + +/** + * Schedule an event for immediate execution. This event will occur + * immediately after returning from the current event (before any other + * event occurs) + * + * @param[in] im The tevent_immediate object to populate and use + * @param[in] ctx The tevent_context to run this event + * @param[in] handler The event handler to run when this event fires + * @param[in] private_data Data to pass to the event handler + */ +void tevent_schedule_immediate(struct tevent_immediate *im, + struct tevent_context *ctx, + tevent_immediate_handler_t handler, + void *private_data); +#else +void _tevent_schedule_immediate(struct tevent_immediate *im, + struct tevent_context *ctx, + tevent_immediate_handler_t handler, + void *private_data, + const char *handler_name, + const char *location); +#define tevent_schedule_immediate(im, ctx, handler, private_data) \ + _tevent_schedule_immediate(im, ctx, handler, private_data, \ + #handler, __location__); +#endif + +#ifdef DOXYGEN +/** + * @brief Add a tevent signal handler + * + * tevent_add_signal() creates a new event for handling a signal the next + * time through the mainloop. It implements a very simple traditional signal + * handler whose only purpose is to add the handler event into the mainloop. + * + * @param[in] ev The event context to work on. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] signum The signal to trap + * + * @param[in] handler The callback handler for the signal. + * + * @param[in] sa_flags sigaction flags for this signal handler. + * + * @param[in] private_data The private data passed to the callback handler. + * + * @return The newly-created signal handler event, or NULL on error. + * + * @note To cancel a signal handler, call talloc_free() on the event returned + * from this function. + * + * @see tevent_num_signals, tevent_sa_info_queue_count + */ +struct tevent_signal *tevent_add_signal(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + int signum, + int sa_flags, + tevent_signal_handler_t handler, + void *private_data); +#else +struct tevent_signal *_tevent_add_signal(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + int signum, + int sa_flags, + tevent_signal_handler_t handler, + void *private_data, + const char *handler_name, + const char *location); +#define tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data) \ + _tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data, \ + #handler, __location__) +#endif + +/** + * @brief the number of supported signals + * + * This returns value of the configure time TEVENT_NUM_SIGNALS constant. + * + * The 'signum' argument of tevent_add_signal() must be less than + * TEVENT_NUM_SIGNALS. + * + * @see tevent_add_signal + */ +size_t tevent_num_signals(void); + +/** + * @brief the number of pending realtime signals + * + * This returns value of TEVENT_SA_INFO_QUEUE_COUNT. + * + * The tevent internals remember the last TEVENT_SA_INFO_QUEUE_COUNT + * siginfo_t structures for SA_SIGINFO signals. If the system generates + * more some signals get lost. + * + * @see tevent_add_signal + */ +size_t tevent_sa_info_queue_count(void); + +#ifdef DOXYGEN +/** + * @brief Pass a single time through the mainloop + * + * This will process any appropriate signal, immediate, fd and timer events + * + * @param[in] ev The event context to process + * + * @return Zero on success, nonzero if an internal error occurred + */ +int tevent_loop_once(struct tevent_context *ev); +#else +int _tevent_loop_once(struct tevent_context *ev, const char *location); +#define tevent_loop_once(ev) \ + _tevent_loop_once(ev, __location__) +#endif + +#ifdef DOXYGEN +/** + * @brief Run the mainloop + * + * The mainloop will run until there are no events remaining to be processed + * + * @param[in] ev The event context to process + * + * @return Zero if all events have been processed. Nonzero if an internal + * error occurred. + */ +int tevent_loop_wait(struct tevent_context *ev); +#else +int _tevent_loop_wait(struct tevent_context *ev, const char *location); +#define tevent_loop_wait(ev) \ + _tevent_loop_wait(ev, __location__) +#endif + + +/** + * Assign a function to run when a tevent_fd is freed + * + * This function is a destructor for the tevent_fd. It does not automatically + * close the file descriptor. If this is the desired behavior, then it must be + * performed by the close_fn. + * + * @param[in] fde File descriptor event on which to set the destructor + * @param[in] close_fn Destructor to execute when fde is freed + * + * @note That the close_fn() on tevent_fd is *NOT* wrapped on contexts + * created by tevent_context_wrapper_create()! + * + * @see tevent_fd_set_close_fn + * @see tevent_context_wrapper_create + */ +void tevent_fd_set_close_fn(struct tevent_fd *fde, + tevent_fd_close_fn_t close_fn); + +/** + * Automatically close the file descriptor when the tevent_fd is freed + * + * This function calls close(fd) internally. + * + * @param[in] fde File descriptor event to auto-close + * + * @see tevent_fd_set_close_fn + */ +void tevent_fd_set_auto_close(struct tevent_fd *fde); + +/** + * Return the flags set on this file descriptor event + * + * @param[in] fde File descriptor event to query + * + * @return The flags set on the event. See #TEVENT_FD_READ and + * #TEVENT_FD_WRITE + */ +uint16_t tevent_fd_get_flags(struct tevent_fd *fde); + +/** + * Set flags on a file descriptor event + * + * @param[in] fde File descriptor event to set + * @param[in] flags Flags to set on the event. See #TEVENT_FD_READ and + * #TEVENT_FD_WRITE + */ +void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags); + +/** + * Query whether tevent supports signal handling + * + * @param[in] ev An initialized tevent context + * + * @return True if this platform and tevent context support signal handling + */ +bool tevent_signal_support(struct tevent_context *ev); + +void tevent_set_abort_fn(void (*abort_fn)(const char *reason)); + +/* bits for file descriptor event flags */ + +/** + * Monitor a file descriptor for data to be read + */ +#define TEVENT_FD_READ 1 +/** + * Monitor a file descriptor for writeability + */ +#define TEVENT_FD_WRITE 2 + +/** + * Convenience function for declaring a tevent_fd writable + */ +#define TEVENT_FD_WRITEABLE(fde) \ + tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) | TEVENT_FD_WRITE) + +/** + * Convenience function for declaring a tevent_fd readable + */ +#define TEVENT_FD_READABLE(fde) \ + tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) | TEVENT_FD_READ) + +/** + * Convenience function for declaring a tevent_fd non-writable + */ +#define TEVENT_FD_NOT_WRITEABLE(fde) \ + tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) & ~TEVENT_FD_WRITE) + +/** + * Convenience function for declaring a tevent_fd non-readable + */ +#define TEVENT_FD_NOT_READABLE(fde) \ + tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) & ~TEVENT_FD_READ) + +/** + * Debug level of tevent + */ +enum tevent_debug_level { + TEVENT_DEBUG_FATAL, + TEVENT_DEBUG_ERROR, + TEVENT_DEBUG_WARNING, + TEVENT_DEBUG_TRACE +}; + +/** + * @brief The tevent debug callbac. + * + * @param[in] context The memory context to use. + * + * @param[in] level The debug level. + * + * @param[in] fmt The format string. + * + * @param[in] ap The arguments for the format string. + */ +typedef void (*tevent_debug_fn)(void *context, + enum tevent_debug_level level, + const char *fmt, + va_list ap) PRINTF_ATTRIBUTE(3,0); + +/** + * Set destination for tevent debug messages + * + * @param[in] ev Event context to debug + * @param[in] debug Function to handle output printing + * @param[in] context The context to pass to the debug function. + * + * @return Always returns 0 as of version 0.9.8 + * + * @note Default is to emit no debug messages + */ +int tevent_set_debug(struct tevent_context *ev, + tevent_debug_fn debug, + void *context); + +/** + * Designate stderr for debug message output + * + * @param[in] ev Event context to debug + * + * @note This function will only output TEVENT_DEBUG_FATAL, TEVENT_DEBUG_ERROR + * and TEVENT_DEBUG_WARNING messages. For TEVENT_DEBUG_TRACE, please define a + * function for tevent_set_debug() + */ +int tevent_set_debug_stderr(struct tevent_context *ev); + +enum tevent_trace_point { + /** + * Corresponds to a trace point just before waiting + */ + TEVENT_TRACE_BEFORE_WAIT, + /** + * Corresponds to a trace point just after waiting + */ + TEVENT_TRACE_AFTER_WAIT, +#define TEVENT_HAS_LOOP_ONCE_TRACE_POINTS 1 + /** + * Corresponds to a trace point just before calling + * the loop_once() backend function. + */ + TEVENT_TRACE_BEFORE_LOOP_ONCE, + /** + * Corresponds to a trace point right after the + * loop_once() backend function has returned. + */ + TEVENT_TRACE_AFTER_LOOP_ONCE, +}; + +typedef void (*tevent_trace_callback_t)(enum tevent_trace_point, + void *private_data); + +/** + * Register a callback to be called at certain trace points + * + * @param[in] ev Event context + * @param[in] cb Trace callback + * @param[in] private_data Data to be passed to callback + * + * @note The callback will be called at trace points defined by + * tevent_trace_point. Call with NULL to reset. + */ +void tevent_set_trace_callback(struct tevent_context *ev, + tevent_trace_callback_t cb, + void *private_data); + +/** + * Retrieve the current trace callback + * + * @param[in] ev Event context + * @param[out] cb Registered trace callback + * @param[out] private_data Registered data to be passed to callback + * + * @note This can be used to allow one component that wants to + * register a callback to respect the callback that another component + * has already registered. + */ +void tevent_get_trace_callback(struct tevent_context *ev, + tevent_trace_callback_t *cb, + void *private_data); + +/** + * @} + */ + +/** + * @defgroup tevent_request The tevent request functions. + * @ingroup tevent + * + * A tevent_req represents an asynchronous computation. + * + * The tevent_req group of API calls is the recommended way of + * programming async computations within tevent. In particular the + * file descriptor (tevent_add_fd) and timer (tevent_add_timed) events + * are considered too low-level to be used in larger computations. To + * read and write from and to sockets, Samba provides two calls on top + * of tevent_add_fd: tstream_read_packet_send/recv and tstream_writev_send/recv. + * These requests are much easier to compose than the low-level event + * handlers called from tevent_add_fd. + * + * A lot of the simplicity tevent_req has brought to the notoriously + * hairy async programming came via a set of conventions that every + * async computation programmed should follow. One central piece of + * these conventions is the naming of routines and variables. + * + * Every async computation needs a name (sensibly called "computation" + * down from here). From this name quite a few naming conventions are + * derived. + * + * Every computation that requires local state needs a + * @code + * struct computation_state { + * int local_var; + * }; + * @endcode + * Even if no local variables are required, such a state struct should + * be created containing a dummy variable. Quite a few helper + * functions and macros (for example tevent_req_create()) assume such + * a state struct. + * + * An async computation is started by a computation_send + * function. When it is finished, its result can be received by a + * computation_recv function. For an example how to set up an async + * computation, see the code example in the documentation for + * tevent_req_create() and tevent_req_post(). The prototypes for _send + * and _recv functions should follow some conventions: + * + * @code + * struct tevent_req *computation_send(TALLOC_CTX *mem_ctx, + * struct tevent_req *ev, + * ... further args); + * int computation_recv(struct tevent_req *req, ... further output args); + * @endcode + * + * The "int" result of computation_recv() depends on the result the + * sync version of the function would have, "int" is just an example + * here. + * + * Another important piece of the conventions is that the program flow + * is interrupted as little as possible. Because a blocking + * sub-computation requires that the flow needs to continue in a + * separate function that is the logical sequel of some computation, + * it should lexically follow sending off the blocking + * sub-computation. Setting the callback function via + * tevent_req_set_callback() requires referencing a function lexically + * below the call to tevent_req_set_callback(), forward declarations + * are required. A lot of the async computations thus begin with a + * sequence of declarations such as + * + * @code + * static void computation_step1_done(struct tevent_req *subreq); + * static void computation_step2_done(struct tevent_req *subreq); + * static void computation_step3_done(struct tevent_req *subreq); + * @endcode + * + * It really helps readability a lot to do these forward declarations, + * because the lexically sequential program flow makes the async + * computations almost as clear to read as a normal, sync program + * flow. + * + * It is up to the user of the async computation to talloc_free it + * after it has finished. If an async computation should be aborted, + * the tevent_req structure can be talloc_free'ed. After it has + * finished, it should talloc_free'ed by the API user. + * + * tevent_req variable naming conventions: + * + * The name of the variable pointing to the tevent_req structure + * returned by a _send() function SHOULD be named differently between + * implementation and caller. + * + * From the point of view of the implementation (of the _send() and + * _recv() functions) the variable returned by tevent_req_create() is + * always called @em req. + * + * While the caller of the _send() function should use @em subreq to + * hold the result. + * + * @see tevent_req_create() + * @see tevent_req_fn() + * + * @{ + */ + +/** + * An async request moves from TEVENT_REQ_INIT to + * TEVENT_REQ_IN_PROGRESS. All other states are valid after a request + * has finished. + */ +enum tevent_req_state { + /** + * We are creating the request + */ + TEVENT_REQ_INIT, + /** + * We are waiting the request to complete + */ + TEVENT_REQ_IN_PROGRESS, + /** + * The request is finished successfully + */ + TEVENT_REQ_DONE, + /** + * A user error has occurred. The user error has been + * indicated by tevent_req_error(), it can be retrieved via + * tevent_req_is_error(). + */ + TEVENT_REQ_USER_ERROR, + /** + * Request timed out after the timeout set by tevent_req_set_endtime. + */ + TEVENT_REQ_TIMED_OUT, + /** + * An internal allocation has failed, or tevent_req_nomem has + * been given a NULL pointer as the first argument. + */ + TEVENT_REQ_NO_MEMORY, + /** + * The request has been received by the caller. No further + * action is valid. + */ + TEVENT_REQ_RECEIVED +}; + +/** + * @brief An async request + */ +struct tevent_req; + +/** + * @brief A tevent request callback function. + * + * @param[in] subreq The tevent async request which executed this callback. + */ +typedef void (*tevent_req_fn)(struct tevent_req *subreq); + +/** + * @brief Set an async request callback. + * + * See the documentation of tevent_req_post() for an example how this + * is supposed to be used. + * + * @param[in] req The async request to set the callback. + * + * @param[in] fn The callback function to set. + * + * @param[in] pvt A pointer to private data to pass to the async request + * callback. + */ +void tevent_req_set_callback(struct tevent_req *req, tevent_req_fn fn, void *pvt); + +#ifdef DOXYGEN +/** + * @brief Get the private data cast to the given type for a callback from + * a tevent request structure. + * + * @code + * static void computation_done(struct tevent_req *subreq) { + * struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); + * struct computation_state *state = tevent_req_data(req, struct computation_state); + * .... more things, eventually maybe call tevent_req_done(req); + * } + * @endcode + * + * @param[in] req The structure to get the callback data from. + * + * @param[in] type The type of the private callback data to get. + * + * @return The type casted private data set NULL if not set. + */ +void *tevent_req_callback_data(struct tevent_req *req, #type); +#else +void *_tevent_req_callback_data(struct tevent_req *req); +#define tevent_req_callback_data(_req, _type) \ + talloc_get_type_abort(_tevent_req_callback_data(_req), _type) +#endif + +#ifdef DOXYGEN +/** + * @brief Get the private data for a callback from a tevent request structure. + * + * @param[in] req The structure to get the callback data from. + * + * @return The private data or NULL if not set. + */ +void *tevent_req_callback_data_void(struct tevent_req *req); +#else +#define tevent_req_callback_data_void(_req) \ + _tevent_req_callback_data(_req) +#endif + +#ifdef DOXYGEN +/** + * @brief Get the private data from a tevent request structure. + * + * When the tevent_req has been created by tevent_req_create, the + * result of tevent_req_data() is the state variable created by + * tevent_req_create() as a child of the req. + * + * @param[in] req The structure to get the private data from. + * + * @param[in] type The type of the private data + * + * @return The private data or NULL if not set. + */ +void *tevent_req_data(struct tevent_req *req, #type); +#else +void *_tevent_req_data(struct tevent_req *req); +#define tevent_req_data(_req, _type) \ + talloc_get_type_abort(_tevent_req_data(_req), _type) +#endif + +/** + * @brief The print function which can be set for a tevent async request. + * + * @param[in] req The tevent async request. + * + * @param[in] ctx A talloc memory context which can be uses to allocate + * memory. + * + * @return An allocated string buffer to print. + * + * Example: + * @code + * static char *my_print(struct tevent_req *req, TALLOC_CTX *mem_ctx) + * { + * struct my_data *data = tevent_req_data(req, struct my_data); + * char *result; + * + * result = tevent_req_default_print(mem_ctx, req); + * if (result == NULL) { + * return NULL; + * } + * + * return talloc_asprintf_append_buffer(result, "foo=%d, bar=%d", + * data->foo, data->bar); + * } + * @endcode + */ +typedef char *(*tevent_req_print_fn)(struct tevent_req *req, TALLOC_CTX *ctx); + +/** + * @brief This function sets a print function for the given request. + * + * This function can be used to setup a print function for the given request. + * This will be triggered if the tevent_req_print() function was + * called on the given request. + * + * @param[in] req The request to use. + * + * @param[in] fn A pointer to the print function + * + * @note This function should only be used for debugging. + */ +void tevent_req_set_print_fn(struct tevent_req *req, tevent_req_print_fn fn); + +/** + * @brief The default print function for creating debug messages. + * + * The function should not be used by users of the async API, + * but custom print function can use it and append custom text + * to the string. + * + * @param[in] req The request to be printed. + * + * @param[in] mem_ctx The memory context for the result. + * + * @return Text representation of request. + * + */ +char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx); + +/** + * @brief Print an tevent_req structure in debug messages. + * + * This function should be used by callers of the async API. + * + * @param[in] mem_ctx The memory context for the result. + * + * @param[in] req The request to be printed. + * + * @return Text representation of request. + */ +char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req); + +/** + * @brief A typedef for a cancel function for a tevent request. + * + * @param[in] req The tevent request calling this function. + * + * @return True if the request could be canceled, false if not. + */ +typedef bool (*tevent_req_cancel_fn)(struct tevent_req *req); + +/** + * @brief This function sets a cancel function for the given tevent request. + * + * This function can be used to setup a cancel function for the given request. + * This will be triggered if the tevent_req_cancel() function was + * called on the given request. + * + * @param[in] req The request to use. + * + * @param[in] fn A pointer to the cancel function. + */ +void tevent_req_set_cancel_fn(struct tevent_req *req, tevent_req_cancel_fn fn); + +#ifdef DOXYGEN +/** + * @brief Try to cancel the given tevent request. + * + * This function can be used to cancel the given request. + * + * It is only possible to cancel a request when the implementation + * has registered a cancel function via the tevent_req_set_cancel_fn(). + * + * @param[in] req The request to use. + * + * @return This function returns true if the request is + * cancelable, otherwise false is returned. + * + * @note Even if the function returns true, the caller need to wait + * for the function to complete normally. + * Only the _recv() function of the given request indicates + * if the request was really canceled. + */ +bool tevent_req_cancel(struct tevent_req *req); +#else +bool _tevent_req_cancel(struct tevent_req *req, const char *location); +#define tevent_req_cancel(req) \ + _tevent_req_cancel(req, __location__) +#endif + +/** + * @brief A typedef for a cleanup function for a tevent request. + * + * @param[in] req The tevent request calling this function. + * + * @param[in] req_state The current tevent_req_state. + * + */ +typedef void (*tevent_req_cleanup_fn)(struct tevent_req *req, + enum tevent_req_state req_state); + +/** + * @brief This function sets a cleanup function for the given tevent request. + * + * This function can be used to setup a cleanup function for the given request. + * This will be triggered when the tevent_req_done() or tevent_req_error() + * function was called, before notifying the callers callback function, + * and also before scheduling the deferred trigger. + * + * This might be useful if more than one tevent_req belong together + * and need to finish both requests at the same time. + * + * The cleanup function is able to call tevent_req_done() or tevent_req_error() + * recursively, the cleanup function is only triggered the first time. + * + * The cleanup function is also called by tevent_req_received() + * (possibly triggered from tevent_req_destructor()) before destroying + * the private data of the tevent_req. + * + * @param[in] req The request to use. + * + * @param[in] fn A pointer to the cancel function. + */ +void tevent_req_set_cleanup_fn(struct tevent_req *req, tevent_req_cleanup_fn fn); + +#ifdef DOXYGEN +/** + * @brief Create an async tevent request. + * + * The new async request will be initialized in state TEVENT_REQ_IN_PROGRESS. + * + * @code + * struct tevent_req *req; + * struct computation_state *state; + * req = tevent_req_create(mem_ctx, &state, struct computation_state); + * @endcode + * + * Tevent_req_create() allocates and zeros the state variable as a talloc + * child of its result. The state variable should be used as the talloc + * parent for all temporary variables that are allocated during the async + * computation. This way, when the user of the async computation frees + * the request, the state as a talloc child will be free'd along with + * all the temporary variables hanging off the state. + * + * @param[in] mem_ctx The memory context for the result. + * @param[in] pstate Pointer to the private request state. + * @param[in] type The name of the request. + * + * @return A new async request. NULL on error. + */ +struct tevent_req *tevent_req_create(TALLOC_CTX *mem_ctx, + void **pstate, #type); +#else +struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, + void *pstate, + size_t state_size, + const char *type, + const char *location); + +#define tevent_req_create(_mem_ctx, _pstate, _type) \ + _tevent_req_create((_mem_ctx), (_pstate), sizeof(_type), \ + #_type, __location__) +#endif + +/** + * @brief Set a timeout for an async request. On failure, "req" is already + * set to state TEVENT_REQ_NO_MEMORY. + * + * @param[in] req The request to set the timeout for. + * + * @param[in] ev The event context to use for the timer. + * + * @param[in] endtime The endtime of the request. + * + * @return True if succeeded, false if not. + */ +bool tevent_req_set_endtime(struct tevent_req *req, + struct tevent_context *ev, + struct timeval endtime); + +/** + * @brief Reset the timer set by tevent_req_set_endtime. + * + * @param[in] req The request to reset the timeout for + */ +void tevent_req_reset_endtime(struct tevent_req *req); + +#ifdef DOXYGEN +/** + * @brief Call the notify callback of the given tevent request manually. + * + * @param[in] req The tevent request to call the notify function from. + * + * @see tevent_req_set_callback() + */ +void tevent_req_notify_callback(struct tevent_req *req); +#else +void _tevent_req_notify_callback(struct tevent_req *req, const char *location); +#define tevent_req_notify_callback(req) \ + _tevent_req_notify_callback(req, __location__) +#endif + +#ifdef DOXYGEN +/** + * @brief An async request has successfully finished. + * + * This function is to be used by implementors of async requests. When a + * request is successfully finished, this function calls the user's completion + * function. + * + * @param[in] req The finished request. + */ +void tevent_req_done(struct tevent_req *req); +#else +void _tevent_req_done(struct tevent_req *req, + const char *location); +#define tevent_req_done(req) \ + _tevent_req_done(req, __location__) +#endif + +#ifdef DOXYGEN +/** + * @brief An async request has seen an error. + * + * This function is to be used by implementors of async requests. When a + * request can not successfully completed, the implementation should call this + * function with the appropriate status code. + * + * If error is 0 the function returns false and does nothing more. + * + * @param[in] req The request with an error. + * + * @param[in] error The error code. + * + * @return On success true is returned, false if error is 0. + * + * @code + * int error = first_function(); + * if (tevent_req_error(req, error)) { + * return; + * } + * + * error = second_function(); + * if (tevent_req_error(req, error)) { + * return; + * } + * + * tevent_req_done(req); + * return; + * @endcode + */ +bool tevent_req_error(struct tevent_req *req, + uint64_t error); +#else +bool _tevent_req_error(struct tevent_req *req, + uint64_t error, + const char *location); +#define tevent_req_error(req, error) \ + _tevent_req_error(req, error, __location__) +#endif + +#ifdef DOXYGEN +/** + * @brief Helper function for nomem check. + * + * Convenience helper to easily check alloc failure within a callback + * implementing the next step of an async request. + * + * @param[in] p The pointer to be checked. + * + * @param[in] req The request being processed. + * + * @code + * p = talloc(mem_ctx, bla); + * if (tevent_req_nomem(p, req)) { + * return; + * } + * @endcode + */ +bool tevent_req_nomem(const void *p, + struct tevent_req *req); +#else +bool _tevent_req_nomem(const void *p, + struct tevent_req *req, + const char *location); +#define tevent_req_nomem(p, req) \ + _tevent_req_nomem(p, req, __location__) +#endif + +#ifdef DOXYGEN +/** + * @brief Indicate out of memory to a request + * + * @param[in] req The request being processed. + */ +void tevent_req_oom(struct tevent_req *req); +#else +void _tevent_req_oom(struct tevent_req *req, + const char *location); +#define tevent_req_oom(req) \ + _tevent_req_oom(req, __location__) +#endif + +/** + * @brief Finish a request before the caller had a chance to set the callback. + * + * An implementation of an async request might find that it can either finish + * the request without waiting for an external event, or it can not even start + * the engine. To present the illusion of a callback to the user of the API, + * the implementation can call this helper function which triggers an + * immediate event. This way the caller can use the same calling + * conventions, independent of whether the request was actually deferred. + * + * @code + * struct tevent_req *computation_send(TALLOC_CTX *mem_ctx, + * struct tevent_context *ev) + * { + * struct tevent_req *req, *subreq; + * struct computation_state *state; + * req = tevent_req_create(mem_ctx, &state, struct computation_state); + * if (req == NULL) { + * return NULL; + * } + * subreq = subcomputation_send(state, ev); + * if (tevent_req_nomem(subreq, req)) { + * return tevent_req_post(req, ev); + * } + * tevent_req_set_callback(subreq, computation_done, req); + * return req; + * } + * @endcode + * + * @param[in] req The finished request. + * + * @param[in] ev The tevent_context for the immediate event. + * + * @return The given request will be returned. + */ +struct tevent_req *tevent_req_post(struct tevent_req *req, + struct tevent_context *ev); + +/** + * @brief Finish multiple requests within one function + * + * Normally tevent_req_notify_callback() and all wrappers + * (e.g. tevent_req_done() and tevent_req_error()) + * need to be the last thing an event handler should call. + * This is because the callback is likely to destroy the + * context of the current function. + * + * If a function wants to notify more than one caller, + * it is dangerous if it just triggers multiple callbacks + * in a row. With tevent_req_defer_callback() it is possible + * to set an event context that will be used to defer the callback + * via an immediate event (similar to tevent_req_post()). + * + * @code + * struct complete_state { + * struct tevent_context *ev; + * + * struct tevent_req **reqs; + * }; + * + * void complete(struct complete_state *state) + * { + * size_t i, c = talloc_array_length(state->reqs); + * + * for (i=0; i < c; i++) { + * tevent_req_defer_callback(state->reqs[i], state->ev); + * tevent_req_done(state->reqs[i]); + * } + * } + * @endcode + * + * @param[in] req The finished request. + * + * @param[in] ev The tevent_context for the immediate event. + * + * @return The given request will be returned. + */ +void tevent_req_defer_callback(struct tevent_req *req, + struct tevent_context *ev); + +/** + * @brief Check if the given request is still in progress. + * + * It is typically used by sync wrapper functions. + * + * @param[in] req The request to poll. + * + * @return The boolean form of "is in progress". + */ +bool tevent_req_is_in_progress(struct tevent_req *req); + +/** + * @brief Actively poll for the given request to finish. + * + * This function is typically used by sync wrapper functions. + * + * @param[in] req The request to poll. + * + * @param[in] ev The tevent_context to be used. + * + * @return On success true is returned. If a critical error has + * happened in the tevent loop layer false is returned. + * This is not the return value of the given request! + * + * @note This should only be used if the given tevent context was created by the + * caller, to avoid event loop nesting. + * + * @code + * req = tstream_writev_queue_send(mem_ctx, + * ev_ctx, + * tstream, + * send_queue, + * iov, 2); + * ok = tevent_req_poll(req, tctx->ev); + * rc = tstream_writev_queue_recv(req, &sys_errno); + * TALLOC_FREE(req); + * @endcode + */ +bool tevent_req_poll(struct tevent_req *req, + struct tevent_context *ev); + +/** + * @brief Get the tevent request state and the actual error set by + * tevent_req_error. + * + * @code + * int computation_recv(struct tevent_req *req, uint64_t *perr) + * { + * enum tevent_req_state state; + * uint64_t err; + * if (tevent_req_is_error(req, &state, &err)) { + * *perr = err; + * return -1; + * } + * return 0; + * } + * @endcode + * + * @param[in] req The tevent request to get the error from. + * + * @param[out] state A pointer to store the tevent request error state. + * + * @param[out] error A pointer to store the error set by tevent_req_error(). + * + * @return True if the function could set error and state, false + * otherwise. + * + * @see tevent_req_error() + */ +bool tevent_req_is_error(struct tevent_req *req, + enum tevent_req_state *state, + uint64_t *error); + +/** + * @brief Use as the last action of a _recv() function. + * + * This function destroys the attached private data. + * + * @param[in] req The finished request. + */ +void tevent_req_received(struct tevent_req *req); + +/** + * @brief Mark a tevent_req for profiling + * + * This will turn on profiling for this tevent_req an all subreqs that + * are directly started as helper requests off this + * tevent_req. subreqs are chained by walking up the talloc_parent + * hierarchy at a subreq's tevent_req_create. This means to get the + * profiling chain right the subreq that needs to be profiled as part + * of this tevent_req's profile must be a talloc child of the requests + * state variable. + * + * @param[in] req The request to do tracing for + * + * @return False if the profile could not be activated + */ +bool tevent_req_set_profile(struct tevent_req *req); + +struct tevent_req_profile; + +/** + * @brief Get the a request's profile for inspection + * + * @param[in] req The request to get the profile from + * + * @return The request's profile + */ +const struct tevent_req_profile *tevent_req_get_profile( + struct tevent_req *req); + +/** + * @brief Move the profile out of a request + * + * This function detaches the request's profile from the request, so + * that the profile can outlive the request in a _recv function. + * + * @param[in] req The request to move the profile out of + * @param[in] mem_ctx The new talloc context for the profile + * + * @return The moved profile + */ + +struct tevent_req_profile *tevent_req_move_profile(struct tevent_req *req, + TALLOC_CTX *mem_ctx); + +/** + * @brief Get a profile description + * + * @param[in] profile The profile to be queried + * @param[in] req_name The name of the request (state's name) + * + * "req_name" after this call is still in talloc-posession of "profile" + */ +void tevent_req_profile_get_name(const struct tevent_req_profile *profile, + const char **req_name); + +/** + * @brief Get a profile's start event data + * + * @param[in] profile The profile to be queried + * @param[in] start_location The location where this event started + * @param[in] start_time The time this event started + * + * "start_location" after this call is still in talloc-posession of "profile" + */ +void tevent_req_profile_get_start(const struct tevent_req_profile *profile, + const char **start_location, + struct timeval *start_time); + +/** + * @brief Get a profile's stop event data + * + * @param[in] profile The profile to be queried + * @param[in] stop_location The location where this event stopped + * @param[in] stop_time The time this event stopped + * + * "stop_location" after this call is still in talloc-posession of "profile" + */ +void tevent_req_profile_get_stop(const struct tevent_req_profile *profile, + const char **stop_location, + struct timeval *stop_time); + +/** + * @brief Get a profile's result data + * + * @param[in] pid The process where this profile was taken + * @param[in] state The status the profile's tevent_req finished with + * @param[in] user_error The user error of the profile's tevent_req + */ +void tevent_req_profile_get_status(const struct tevent_req_profile *profile, + pid_t *pid, + enum tevent_req_state *state, + uint64_t *user_error); + +/** + * @brief Retrieve the first subreq's profile from a profile + * + * @param[in] profile The profile to query + * + * @return The first tevent subreq's profile + */ +const struct tevent_req_profile *tevent_req_profile_get_subprofiles( + const struct tevent_req_profile *profile); + +/** + * @brief Walk the chain of subreqs + * + * @param[in] profile The subreq's profile to walk + * + * @return The next subprofile in the list + */ +const struct tevent_req_profile *tevent_req_profile_next( + const struct tevent_req_profile *profile); + +/** + * @brief Create a fresh tevent_req_profile + * + * @param[in] mem_ctx The talloc context to hang the fresh struct off + * + * @return The fresh struct + */ +struct tevent_req_profile *tevent_req_profile_create(TALLOC_CTX *mem_ctx); + +/** + * @brief Set a profile's name + * + * @param[in] profile The profile to set the name for + * @param[in] name The new name for the profile + * + * @return True if the internal talloc_strdup succeeded + */ +bool tevent_req_profile_set_name(struct tevent_req_profile *profile, + const char *name); + +/** + * @brief Set a profile's start event + * + * @param[in] profile The profile to set the start data for + * @param[in] start_location The new start location + * @param[in] start_time The new start time + * + * @return True if the internal talloc_strdup succeeded + */ +bool tevent_req_profile_set_start(struct tevent_req_profile *profile, + const char *start_location, + struct timeval start_time); + +/** + * @brief Set a profile's stop event + * + * @param[in] profile The profile to set the stop data for + * @param[in] stop_location The new stop location + * @param[in] stop_time The new stop time + * + * @return True if the internal talloc_strdup succeeded + */ +bool tevent_req_profile_set_stop(struct tevent_req_profile *profile, + const char *stop_location, + struct timeval stop_time); + +/** + * @brief Set a profile's exit status + * + * @param[in] profile The profile to set the exit status for + * @param[in] pid The process where this profile was taken + * @param[in] state The status the profile's tevent_req finished with + * @param[in] user_error The user error of the profile's tevent_req + */ +void tevent_req_profile_set_status(struct tevent_req_profile *profile, + pid_t pid, + enum tevent_req_state state, + uint64_t user_error); + +/** + * @brief Add a subprofile to a profile + * + * @param[in] parent_profile The profile to be modified + * @param[in] sub_profile The subreqs profile profile to be added + * + * "subreq" is talloc_move'ed into "parent_profile", so the talloc + * ownership of "sub_profile" changes + */ + +void tevent_req_profile_append_sub(struct tevent_req_profile *parent_profile, + struct tevent_req_profile **sub_profile); + +/** + * @brief Create a tevent subrequest at a given time. + * + * The idea is that always the same syntax for tevent requests. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] ev The event handle to setup the request. + * + * @param[in] wakeup_time The time to wakeup and execute the request. + * + * @return The new subrequest, NULL on error. + * + * Example: + * @code + * static void my_callback_wakeup_done(tevent_req *subreq) + * { + * struct tevent_req *req = tevent_req_callback_data(subreq, + * struct tevent_req); + * bool ok; + * + * ok = tevent_wakeup_recv(subreq); + * TALLOC_FREE(subreq); + * if (!ok) { + * tevent_req_error(req, -1); + * return; + * } + * ... + * } + * @endcode + * + * @code + * subreq = tevent_wakeup_send(mem_ctx, ev, wakeup_time); + * if (tevent_req_nomem(subreq, req)) { + * return false; + * } + * tevent_set_callback(subreq, my_callback_wakeup_done, req); + * @endcode + * + * @see tevent_wakeup_recv() + */ +struct tevent_req *tevent_wakeup_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct timeval wakeup_time); + +/** + * @brief Check if the wakeup has been correctly executed. + * + * This function needs to be called in the callback function set after calling + * tevent_wakeup_send(). + * + * @param[in] req The tevent request to check. + * + * @return True on success, false otherwise. + * + * @see tevent_wakeup_recv() + */ +bool tevent_wakeup_recv(struct tevent_req *req); + +/* @} */ + +/** + * @defgroup tevent_helpers The tevent helper functions + * @ingroup tevent + * + * @todo description + * + * @{ + */ + +/** + * @brief Compare two timeval values. + * + * @param[in] tv1 The first timeval value to compare. + * + * @param[in] tv2 The second timeval value to compare. + * + * @return 0 if they are equal. + * 1 if the first time is greater than the second. + * -1 if the first time is smaller than the second. + */ +int tevent_timeval_compare(const struct timeval *tv1, + const struct timeval *tv2); + +/** + * @brief Get a zero timeval value. + * + * @return A zero timeval value. + */ +struct timeval tevent_timeval_zero(void); + +/** + * @brief Get a timeval value for the current time. + * + * @return A timeval value with the current time. + */ +struct timeval tevent_timeval_current(void); + +/** + * @brief Get a timeval structure with the given values. + * + * @param[in] secs The seconds to set. + * + * @param[in] usecs The microseconds to set. + * + * @return A timeval structure with the given values. + */ +struct timeval tevent_timeval_set(uint32_t secs, uint32_t usecs); + +/** + * @brief Get the difference between two timeval values. + * + * @param[in] tv1 The first timeval. + * + * @param[in] tv2 The second timeval. + * + * @return A timeval structure with the difference between the + * first and the second value. + */ +struct timeval tevent_timeval_until(const struct timeval *tv1, + const struct timeval *tv2); + +/** + * @brief Check if a given timeval structure is zero. + * + * @param[in] tv The timeval to check if it is zero. + * + * @return True if it is zero, false otherwise. + */ +bool tevent_timeval_is_zero(const struct timeval *tv); + +/** + * @brief Add the given amount of time to a timeval structure. + * + * @param[in] tv The timeval structure to add the time. + * + * @param[in] secs The seconds to add to the timeval. + * + * @param[in] usecs The microseconds to add to the timeval. + * + * @return The timeval structure with the new time. + */ +struct timeval tevent_timeval_add(const struct timeval *tv, uint32_t secs, + uint32_t usecs); + +/** + * @brief Get a timeval in the future with a specified offset from now. + * + * @param[in] secs The seconds of the offset from now. + * + * @param[in] usecs The microseconds of the offset from now. + * + * @return A timeval with the given offset in the future. + */ +struct timeval tevent_timeval_current_ofs(uint32_t secs, uint32_t usecs); + +/* @} */ + + +/** + * @defgroup tevent_queue The tevent queue functions + * @ingroup tevent + * + * A tevent_queue is used to queue up async requests that must be + * serialized. For example writing buffers into a socket must be + * serialized. Writing a large lump of data into a socket can require + * multiple write(2) or send(2) system calls. If more than one async + * request is outstanding to write large buffers into a socket, every + * request must individually be completed before the next one begins, + * even if multiple syscalls are required. + * + * Take a look at @ref tevent_queue_tutorial for more details. + * @{ + */ + +struct tevent_queue; +struct tevent_queue_entry; + +#ifdef DOXYGEN +/** + * @brief Create and start a tevent queue. + * + * @param[in] mem_ctx The talloc memory context to allocate the queue. + * + * @param[in] name The name to use to identify the queue. + * + * @return An allocated tevent queue on success, NULL on error. + * + * @see tevent_queue_start() + * @see tevent_queue_stop() + */ +struct tevent_queue *tevent_queue_create(TALLOC_CTX *mem_ctx, + const char *name); +#else +struct tevent_queue *_tevent_queue_create(TALLOC_CTX *mem_ctx, + const char *name, + const char *location); + +#define tevent_queue_create(_mem_ctx, _name) \ + _tevent_queue_create((_mem_ctx), (_name), __location__) +#endif + +/** + * @brief A callback trigger function run by the queue. + * + * @param[in] req The tevent request the trigger function is executed on. + * + * @param[in] private_data The private data pointer specified by + * tevent_queue_add(). + * + * @see tevent_queue_add() + * @see tevent_queue_add_entry() + * @see tevent_queue_add_optimize_empty() + */ +typedef void (*tevent_queue_trigger_fn_t)(struct tevent_req *req, + void *private_data); + +/** + * @brief Add a tevent request to the queue. + * + * @param[in] queue The queue to add the request. + * + * @param[in] ev The event handle to use for the request. + * + * @param[in] req The tevent request to add to the queue. + * + * @param[in] trigger The function triggered by the queue when the request + * is called. Since tevent 0.9.14 it's possible to + * pass NULL, in order to just add a "blocker" to the + * queue. + * + * @param[in] private_data The private data passed to the trigger function. + * + * @return True if the request has been successfully added, false + * otherwise. + */ +bool tevent_queue_add(struct tevent_queue *queue, + struct tevent_context *ev, + struct tevent_req *req, + tevent_queue_trigger_fn_t trigger, + void *private_data); + +/** + * @brief Add a tevent request to the queue. + * + * The request can be removed from the queue by calling talloc_free() + * (or a similar function) on the returned queue entry. This + * is the only difference to tevent_queue_add(). + * + * @param[in] queue The queue to add the request. + * + * @param[in] ev The event handle to use for the request. + * + * @param[in] req The tevent request to add to the queue. + * + * @param[in] trigger The function triggered by the queue when the request + * is called. Since tevent 0.9.14 it's possible to + * pass NULL, in order to just add a "blocker" to the + * queue. + * + * @param[in] private_data The private data passed to the trigger function. + * + * @return a pointer to the tevent_queue_entry if the request + * has been successfully added, NULL otherwise. + * + * @see tevent_queue_add() + * @see tevent_queue_add_optimize_empty() + */ +struct tevent_queue_entry *tevent_queue_add_entry( + struct tevent_queue *queue, + struct tevent_context *ev, + struct tevent_req *req, + tevent_queue_trigger_fn_t trigger, + void *private_data); + +/** + * @brief Add a tevent request to the queue using a possible optimization. + * + * This tries to optimize for the empty queue case and may calls + * the trigger function directly. This is the only difference compared + * to tevent_queue_add_entry(). + * + * The caller needs to be prepared that the trigger function has + * already called tevent_req_notify_callback(), tevent_req_error(), + * tevent_req_done() or a similar function. + * + * The trigger function has no chance to see the returned + * queue_entry in the optimized case. + * + * The request can be removed from the queue by calling talloc_free() + * (or a similar function) on the returned queue entry. + * + * @param[in] queue The queue to add the request. + * + * @param[in] ev The event handle to use for the request. + * + * @param[in] req The tevent request to add to the queue. + * + * @param[in] trigger The function triggered by the queue when the request + * is called. Since tevent 0.9.14 it's possible to + * pass NULL, in order to just add a "blocker" to the + * queue. + * + * @param[in] private_data The private data passed to the trigger function. + * + * @return a pointer to the tevent_queue_entry if the request + * has been successfully added, NULL otherwise. + * + * @see tevent_queue_add() + * @see tevent_queue_add_entry() + */ +struct tevent_queue_entry *tevent_queue_add_optimize_empty( + struct tevent_queue *queue, + struct tevent_context *ev, + struct tevent_req *req, + tevent_queue_trigger_fn_t trigger, + void *private_data); + +/** + * @brief Untrigger an already triggered queue entry. + * + * If a trigger function detects that it needs to remain + * in the queue, it needs to call tevent_queue_stop() + * followed by tevent_queue_entry_untrigger(). + * + * @note In order to call tevent_queue_entry_untrigger() + * the queue must be already stopped and the given queue_entry + * must be the first one in the queue! Otherwise it calls abort(). + * + * @note You can't use this together with tevent_queue_add_optimize_empty() + * because the trigger function don't have access to the quene entry + * in the case of an empty queue. + * + * @param[in] queue_entry The queue entry to rearm. + * + * @see tevent_queue_add_entry() + * @see tevent_queue_stop() + */ +void tevent_queue_entry_untrigger(struct tevent_queue_entry *entry); + +/** + * @brief Start a tevent queue. + * + * The queue is started by default. + * + * @param[in] queue The queue to start. + */ +void tevent_queue_start(struct tevent_queue *queue); + +/** + * @brief Stop a tevent queue. + * + * The queue is started by default. + * + * @param[in] queue The queue to stop. + */ +void tevent_queue_stop(struct tevent_queue *queue); + +/** + * @brief Get the length of the queue. + * + * @param[in] queue The queue to get the length from. + * + * @return The number of elements. + */ +size_t tevent_queue_length(struct tevent_queue *queue); + +/** + * @brief Is the tevent queue running. + * + * The queue is started by default. + * + * @param[in] queue The queue. + * + * @return Whether the queue is running or not.. + */ +bool tevent_queue_running(struct tevent_queue *queue); + +/** + * @brief Create a tevent subrequest that waits in a tevent_queue + * + * The idea is that always the same syntax for tevent requests. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] ev The event handle to setup the request. + * + * @param[in] queue The queue to wait in. + * + * @return The new subrequest, NULL on error. + * + * @see tevent_queue_wait_recv() + */ +struct tevent_req *tevent_queue_wait_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tevent_queue *queue); + +/** + * @brief Check if we no longer need to wait in the queue. + * + * This function needs to be called in the callback function set after calling + * tevent_queue_wait_send(). + * + * @param[in] req The tevent request to check. + * + * @return True on success, false otherwise. + * + * @see tevent_queue_wait_send() + */ +bool tevent_queue_wait_recv(struct tevent_req *req); + +typedef int (*tevent_nesting_hook)(struct tevent_context *ev, + void *private_data, + uint32_t level, + bool begin, + void *stack_ptr, + const char *location); + +/** + * @brief Create a tevent_thread_proxy for message passing between threads. + * + * The tevent_context must have been allocated on the NULL + * talloc context, and talloc_disable_null_tracking() must + * have been called. + * + * @param[in] dest_ev_ctx The tevent_context to receive events. + * + * @return An allocated tevent_thread_proxy, NULL on error. + * If tevent was compiled without PTHREAD support + * NULL is always returned and errno set to ENOSYS. + * + * @see tevent_thread_proxy_schedule() + */ +struct tevent_thread_proxy *tevent_thread_proxy_create( + struct tevent_context *dest_ev_ctx); + +/** + * @brief Schedule an immediate event on an event context from another thread. + * + * Causes dest_ev_ctx, being run by another thread, to receive an + * immediate event calling the handler with the *pp_private parameter. + * + * *pp_im must be a pointer to an immediate event talloced on a context owned + * by the calling thread, or the NULL context. Ownership will + * be transferred to the tevent_thread_proxy and *pp_im will be returned as NULL. + * + * *pp_private_data must be a talloced area of memory with no destructors. + * Ownership of this memory will be transferred to the tevent library and + * *pp_private_data will be set to NULL on successful completion of + * the call. Set pp_private to NULL if no parameter transfer + * needed (a pure callback). This is an asynchronous request, caller + * does not wait for callback to be completed before returning. + * + * @param[in] tp The tevent_thread_proxy to use. + * + * @param[in] pp_im Pointer to immediate event pointer. + * + * @param[in] handler The function that will be called. + * + * @param[in] pp_private_data The talloced memory to transfer. + * + * @see tevent_thread_proxy_create() + */ +void tevent_thread_proxy_schedule(struct tevent_thread_proxy *tp, + struct tevent_immediate **pp_im, + tevent_immediate_handler_t handler, + void *pp_private_data); + +/* + * @brief Create a context for threaded activation of immediates + * + * A tevent_treaded_context provides a link into an event + * context. Using tevent_threaded_schedule_immediate, it is possible + * to activate an immediate event from within a thread. + * + * It is the duty of the caller of tevent_threaded_context_create() to + * keep the event context around longer than any + * tevent_threaded_context. tevent will abort if ev is talloc_free'ed + * with an active tevent_threaded_context. + * + * If tevent is build without pthread support, this always returns + * NULL with errno=ENOSYS. + * + * @param[in] mem_ctx The talloc memory context to use. + * @param[in] ev The event context to link this to. + * @return The threaded context, or NULL with errno set. + * + * @see tevent_threaded_schedule_immediate() + * + * @note Available as of tevent 0.9.30 + */ +struct tevent_threaded_context *tevent_threaded_context_create( + TALLOC_CTX *mem_ctx, struct tevent_context *ev); + +#ifdef DOXYGEN +/* + * @brief Activate an immediate from a thread + * + * Activate an immediate from within a thread. + * + * This routine does not watch out for talloc hierarchies. This means + * that it is highly recommended to create the tevent_immediate in the + * thread owning tctx, allocate a threaded job description for the + * thread, hand over both pointers to a helper thread and not touch it + * in the main thread at all anymore. + * + * tevent_threaded_schedule_immediate is intended as a job completion + * indicator for simple threaded helpers. + * + * Please be aware that tevent_threaded_schedule_immediate is very + * picky about its arguments: An immediate may not already be + * activated and the handler must exist. With + * tevent_threaded_schedule_immediate memory ownership is transferred + * to the main thread holding the tevent context behind tctx, the + * helper thread can't access it anymore. + * + * @param[in] tctx The threaded context to go through + * @param[in] im The immediate event to activate + * @param[in] handler The immediate handler to call in the main thread + * @param[in] private_data Pointer for the immediate handler + * + * @see tevent_threaded_context_create() + * + * @note Available as of tevent 0.9.30 + */ +void tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx, + struct tevent_immediate *im, + tevent_immediate_handler_t handler, + void *private_data); +#else +void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx, + struct tevent_immediate *im, + tevent_immediate_handler_t handler, + void *private_data, + const char *handler_name, + const char *location); +#define tevent_threaded_schedule_immediate(tctx, im, handler, private_data) \ + _tevent_threaded_schedule_immediate(tctx, im, handler, private_data, \ + #handler, __location__); +#endif + +#ifdef TEVENT_DEPRECATED +#ifndef _DEPRECATED_ +#ifdef HAVE___ATTRIBUTE__ +#define _DEPRECATED_ __attribute__ ((deprecated)) +#else +#define _DEPRECATED_ +#endif +#endif +void tevent_loop_allow_nesting(struct tevent_context *ev) _DEPRECATED_; +void tevent_loop_set_nesting_hook(struct tevent_context *ev, + tevent_nesting_hook hook, + void *private_data) _DEPRECATED_; +int _tevent_loop_until(struct tevent_context *ev, + bool (*finished)(void *private_data), + void *private_data, + const char *location) _DEPRECATED_; +#define tevent_loop_until(ev, finished, private_data) \ + _tevent_loop_until(ev, finished, private_data, __location__) +#endif + +int tevent_re_initialise(struct tevent_context *ev); + +/* @} */ + +/** + * @defgroup tevent_ops The tevent operation functions + * @ingroup tevent + * + * The following structure and registration functions are exclusively + * needed for people writing and pluggin a different event engine. + * There is nothing useful for normal tevent user in here. + * @{ + */ + +struct tevent_ops { + /* context init */ + int (*context_init)(struct tevent_context *ev); + + /* fd_event functions */ + struct tevent_fd *(*add_fd)(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + int fd, uint16_t flags, + tevent_fd_handler_t handler, + void *private_data, + const char *handler_name, + const char *location); + void (*set_fd_close_fn)(struct tevent_fd *fde, + tevent_fd_close_fn_t close_fn); + uint16_t (*get_fd_flags)(struct tevent_fd *fde); + void (*set_fd_flags)(struct tevent_fd *fde, uint16_t flags); + + /* timed_event functions */ + struct tevent_timer *(*add_timer)(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + struct timeval next_event, + tevent_timer_handler_t handler, + void *private_data, + const char *handler_name, + const char *location); + + /* immediate event functions */ + void (*schedule_immediate)(struct tevent_immediate *im, + struct tevent_context *ev, + tevent_immediate_handler_t handler, + void *private_data, + const char *handler_name, + const char *location); + + /* signal functions */ + struct tevent_signal *(*add_signal)(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + int signum, int sa_flags, + tevent_signal_handler_t handler, + void *private_data, + const char *handler_name, + const char *location); + + /* loop functions */ + int (*loop_once)(struct tevent_context *ev, const char *location); + int (*loop_wait)(struct tevent_context *ev, const char *location); +}; + +bool tevent_register_backend(const char *name, const struct tevent_ops *ops); + +/* @} */ + +#ifdef TEVENT_DEPRECATED +/** + * @defgroup tevent_wrapper_ops The tevent wrapper operation functions + * @ingroup tevent + * + * The following structure and registration functions are exclusively + * needed for people writing wrapper functions for event handlers + * e.g. wrappers can be used for debugging/profiling or impersonation. + * + * There is nothing useful for normal tevent user in here. + * + * @note That the close_fn() on tevent_fd is *NOT* wrapped! + * + * @see tevent_context_wrapper_create + * @see tevent_fd_set_auto_close + * @{ + */ + +struct tevent_wrapper_ops { + const char *name; + + bool (*before_use)(struct tevent_context *wrap_ev, + void *private_state, + struct tevent_context *main_ev, + const char *location); + void (*after_use)(struct tevent_context *wrap_ev, + void *private_state, + struct tevent_context *main_ev, + const char *location); + + void (*before_fd_handler)(struct tevent_context *wrap_ev, + void *private_state, + struct tevent_context *main_ev, + struct tevent_fd *fde, + uint16_t flags, + const char *handler_name, + const char *location); + void (*after_fd_handler)(struct tevent_context *wrap_ev, + void *private_state, + struct tevent_context *main_ev, + struct tevent_fd *fde, + uint16_t flags, + const char *handler_name, + const char *location); + + void (*before_timer_handler)(struct tevent_context *wrap_ev, + void *private_state, + struct tevent_context *main_ev, + struct tevent_timer *te, + struct timeval requested_time, + struct timeval trigger_time, + const char *handler_name, + const char *location); + void (*after_timer_handler)(struct tevent_context *wrap_ev, + void *private_state, + struct tevent_context *main_ev, + struct tevent_timer *te, + struct timeval requested_time, + struct timeval trigger_time, + const char *handler_name, + const char *location); + + void (*before_immediate_handler)(struct tevent_context *wrap_ev, + void *private_state, + struct tevent_context *main_ev, + struct tevent_immediate *im, + const char *handler_name, + const char *location); + void (*after_immediate_handler)(struct tevent_context *wrap_ev, + void *private_state, + struct tevent_context *main_ev, + struct tevent_immediate *im, + const char *handler_name, + const char *location); + + void (*before_signal_handler)(struct tevent_context *wrap_ev, + void *private_state, + struct tevent_context *main_ev, + struct tevent_signal *se, + int signum, + int count, + void *siginfo, + const char *handler_name, + const char *location); + void (*after_signal_handler)(struct tevent_context *wrap_ev, + void *private_state, + struct tevent_context *main_ev, + struct tevent_signal *se, + int signum, + int count, + void *siginfo, + const char *handler_name, + const char *location); +}; + +#ifdef DOXYGEN +/** + * @brief Create a wrapper tevent_context. + * + * @param[in] main_ev The main event context to work on. + * + * @param[in] mem_ctx The talloc memory context to use. + * + * @param[in] ops The tevent_wrapper_ops function table. + * + * @param[out] private_state The private state use by the wrapper functions. + * + * @param[in] private_type The talloc type of the private_state. + * + * @return The wrapper event context, NULL on error. + * + * @note Available as of tevent 0.9.37 + * @note Deprecated as of tevent 0.9.38 + */ +struct tevent_context *tevent_context_wrapper_create(struct tevent_context *main_ev, + TALLOC_CTX *mem_ctx, + const struct tevent_wrapper_ops *ops, + void **private_state, + const char *private_type); +#else +struct tevent_context *_tevent_context_wrapper_create(struct tevent_context *main_ev, + TALLOC_CTX *mem_ctx, + const struct tevent_wrapper_ops *ops, + void *pstate, + size_t psize, + const char *type, + const char *location) _DEPRECATED_; +#define tevent_context_wrapper_create(main_ev, mem_ctx, ops, state, type) \ + _tevent_context_wrapper_create(main_ev, mem_ctx, ops, \ + state, sizeof(type), #type, __location__) +#endif + +/** + * @brief Check if the event context is a wrapper event context. + * + * @param[in] ev The event context to work on. + * + * @return Is a wrapper (true), otherwise (false). + * + * @see tevent_context_wrapper_create() + * + * @note Available as of tevent 0.9.37 + * @note Deprecated as of tevent 0.9.38 + */ +bool tevent_context_is_wrapper(struct tevent_context *ev) _DEPRECATED_; + +#ifdef DOXYGEN +/** + * @brief Prepare the environment of a (wrapper) event context. + * + * A caller might call this before passing a wrapper event context + * to a tevent_req based *_send() function. + * + * The wrapper event context might do something like impersonation. + * + * tevent_context_push_use() must always be used in combination + * with tevent_context_pop_use(). + * + * There is a global stack of currently active/busy wrapper event contexts. + * Each wrapper can only appear once on that global stack! + * The stack size is limited to 32 elements, which should be enough + * for all useful scenarios. + * + * In addition to an explicit tevent_context_push_use() also + * the invocation of an immediate, timer or fd handler implicitly + * pushes the wrapper on the stack. + * + * Therefore there are some strict constraints for the usage of + * tevent_context_push_use(): + * - It must not be called from within an event handler + * that already acts on the wrapper. + * - tevent_context_pop_use() must be called before + * leaving the code block that called tevent_context_push_use(). + * - The caller is responsible ensure the correct stack ordering + * - Any violation of these constraints results in calling + * the abort handler of the given tevent context. + * + * Calling tevent_context_push_use() on a raw event context + * still consumes an element on the stack, but it's otherwise + * a no-op. + * + * If tevent_context_push_use() returns false, it means + * that the wrapper's before_use() hook returned this failure, + * in that case you must not call tevent_context_pop_use() as + * the wrapper is not pushed onto the stack. + * + * @param[in] ev The event context to work on. + * + * @return Success (true) or failure (false). + * + * @note This is only needed if wrapper event contexts are in use. + * + * @see tevent_context_pop_use + * + * @note Available as of tevent 0.9.37 + * @note Deprecated as of tevent 0.9.38 + */ +bool tevent_context_push_use(struct tevent_context *ev); +#else +bool _tevent_context_push_use(struct tevent_context *ev, + const char *location) _DEPRECATED_; +#define tevent_context_push_use(ev) \ + _tevent_context_push_use(ev, __location__) +#endif + +#ifdef DOXYGEN +/** + * @brief Release the environment of a (wrapper) event context. + * + * The wrapper event context might undo something like impersonation. + * + * This must be called after a succesful tevent_context_push_use(). + * Any ordering violation results in calling + * the abort handler of the given tevent context. + * + * This basically calls the wrapper's after_use() hook. + * + * @param[in] ev The event context to work on. + * + * @note This is only needed if wrapper event contexts are in use. + * + * @see tevent_context_push_use + * + * @note Available as of tevent 0.9.37 + * @note Deprecated as of tevent 0.9.38 + */ +void tevent_context_pop_use(struct tevent_context *ev); +#else +void _tevent_context_pop_use(struct tevent_context *ev, + const char *location) _DEPRECATED_; +#define tevent_context_pop_use(ev) \ + _tevent_context_pop_use(ev, __location__) +#endif + +/** + * @brief Check is the two context pointers belong to the same low level loop + * + * With the introduction of wrapper contexts it's not trivial + * to check if two context pointers belong to the same low level + * event loop. Some code may need to know this in order + * to make some caching decisions. + * + * @param[in] ev1 The first event context. + * @param[in] ev2 The second event context. + * + * @return true if both contexts belong to the same (still existing) context + * loop, false otherwise. + * + * @see tevent_context_wrapper_create + * + * @note Available as of tevent 0.9.37 + * @note Deprecated as of tevent 0.9.38 + */ +bool tevent_context_same_loop(struct tevent_context *ev1, + struct tevent_context *ev2) _DEPRECATED_; + +/* @} */ +#endif /* TEVENT_DEPRECATED */ + +/** + * @defgroup tevent_compat The tevent compatibility functions + * @ingroup tevent + * + * The following definitions are usueful only for compatibility with the + * implementation originally developed within the samba4 code and will be + * soon removed. Please NEVER use in new code. + * + * @todo Ignore it? + * + * @{ + */ + +#ifdef TEVENT_COMPAT_DEFINES + +#define event_context tevent_context +#define event_ops tevent_ops +#define fd_event tevent_fd +#define timed_event tevent_timer +#define signal_event tevent_signal + +#define event_fd_handler_t tevent_fd_handler_t +#define event_timed_handler_t tevent_timer_handler_t +#define event_signal_handler_t tevent_signal_handler_t + +#define event_context_init(mem_ctx) \ + tevent_context_init(mem_ctx) + +#define event_context_init_byname(mem_ctx, name) \ + tevent_context_init_byname(mem_ctx, name) + +#define event_backend_list(mem_ctx) \ + tevent_backend_list(mem_ctx) + +#define event_set_default_backend(backend) \ + tevent_set_default_backend(backend) + +#define event_add_fd(ev, mem_ctx, fd, flags, handler, private_data) \ + tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data) + +#define event_add_timed(ev, mem_ctx, next_event, handler, private_data) \ + tevent_add_timer(ev, mem_ctx, next_event, handler, private_data) + +#define event_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data) \ + tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data) + +#define event_loop_once(ev) \ + tevent_loop_once(ev) + +#define event_loop_wait(ev) \ + tevent_loop_wait(ev) + +#define event_get_fd_flags(fde) \ + tevent_fd_get_flags(fde) + +#define event_set_fd_flags(fde, flags) \ + tevent_fd_set_flags(fde, flags) + +#define EVENT_FD_READ TEVENT_FD_READ +#define EVENT_FD_WRITE TEVENT_FD_WRITE + +#define EVENT_FD_WRITEABLE(fde) \ + TEVENT_FD_WRITEABLE(fde) + +#define EVENT_FD_READABLE(fde) \ + TEVENT_FD_READABLE(fde) + +#define EVENT_FD_NOT_WRITEABLE(fde) \ + TEVENT_FD_NOT_WRITEABLE(fde) + +#define EVENT_FD_NOT_READABLE(fde) \ + TEVENT_FD_NOT_READABLE(fde) + +#define ev_debug_level tevent_debug_level + +#define EV_DEBUG_FATAL TEVENT_DEBUG_FATAL +#define EV_DEBUG_ERROR TEVENT_DEBUG_ERROR +#define EV_DEBUG_WARNING TEVENT_DEBUG_WARNING +#define EV_DEBUG_TRACE TEVENT_DEBUG_TRACE + +#define ev_set_debug(ev, debug, context) \ + tevent_set_debug(ev, debug, context) + +#define ev_set_debug_stderr(_ev) tevent_set_debug_stderr(ev) + +#endif /* TEVENT_COMPAT_DEFINES */ + +/* @} */ + +#endif /* __TEVENT_H__ */ diff --git a/ldb-2.0.8/lib/tevent/tevent.pc.in b/ldb-2.0.8/lib/tevent/tevent.pc.in new file mode 100644 index 0000000..eb0e564 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: tevent +Description: An event system library +Version: @PACKAGE_VERSION@ +Requires: talloc +Libs: @LIB_RPATH@ -L${libdir} -ltevent +Cflags: -I${includedir} +URL: http://samba.org/ diff --git a/ldb-2.0.8/lib/tevent/tevent.py b/ldb-2.0.8/lib/tevent/tevent.py new file mode 100644 index 0000000..14aa27d --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent.py @@ -0,0 +1,28 @@ +# +# Python integration for tevent +# +# Copyright (C) Jelmer Vernooij 2011 +# +# ** NOTE! The following LGPL license applies to the tevent +# ** library. This does NOT imply that all of Samba is released +# ** under the LGPL +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 3 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, see . + +from _tevent import ( + __version__, + backend_list, + Context, + Signal, +) diff --git a/ldb-2.0.8/lib/tevent/tevent_debug.c b/ldb-2.0.8/lib/tevent/tevent_debug.c new file mode 100644 index 0000000..0a57639 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent_debug.c @@ -0,0 +1,135 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2005 + Copyright (C) Jelmer Vernooij 2005 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#include "tevent.h" +#include "tevent_internal.h" + +/******************************************************************** + * Debug wrapper functions, modeled (with lot's of code copied as is) + * after the ev debug wrapper functions + ********************************************************************/ + +/* + this allows the user to choose their own debug function +*/ +int tevent_set_debug(struct tevent_context *ev, + void (*debug)(void *context, + enum tevent_debug_level level, + const char *fmt, + va_list ap) PRINTF_ATTRIBUTE(3,0), + void *context) +{ + if (ev->wrapper.glue != NULL) { + ev = tevent_wrapper_main_ev(ev); + tevent_abort(ev, "tevent_set_debug() on wrapper"); + errno = EINVAL; + return -1; + } + + ev->debug_ops.debug = debug; + ev->debug_ops.context = context; + return 0; +} + +/* + debug function for ev_set_debug_stderr +*/ +static void tevent_debug_stderr(void *private_data, + enum tevent_debug_level level, + const char *fmt, + va_list ap) PRINTF_ATTRIBUTE(3,0); +static void tevent_debug_stderr(void *private_data, + enum tevent_debug_level level, + const char *fmt, va_list ap) +{ + if (level <= TEVENT_DEBUG_WARNING) { + vfprintf(stderr, fmt, ap); + } +} + +/* + convenience function to setup debug messages on stderr + messages of level TEVENT_DEBUG_WARNING and higher are printed +*/ +int tevent_set_debug_stderr(struct tevent_context *ev) +{ + return tevent_set_debug(ev, tevent_debug_stderr, ev); +} + +/* + * log a message + * + * The default debug action is to ignore debugging messages. + * This is the most appropriate action for a library. + * Applications using the library must decide where to + * redirect debugging messages +*/ +void tevent_debug(struct tevent_context *ev, enum tevent_debug_level level, + const char *fmt, ...) +{ + va_list ap; + if (!ev) { + return; + } + if (ev->wrapper.glue != NULL) { + ev = tevent_wrapper_main_ev(ev); + } + if (ev->debug_ops.debug == NULL) { + return; + } + va_start(ap, fmt); + ev->debug_ops.debug(ev->debug_ops.context, level, fmt, ap); + va_end(ap); +} + +void tevent_set_trace_callback(struct tevent_context *ev, + tevent_trace_callback_t cb, + void *private_data) +{ + if (ev->wrapper.glue != NULL) { + ev = tevent_wrapper_main_ev(ev); + tevent_abort(ev, "tevent_set_trace_callback() on wrapper"); + return; + } + + ev->tracing.callback = cb; + ev->tracing.private_data = private_data; +} + +void tevent_get_trace_callback(struct tevent_context *ev, + tevent_trace_callback_t *cb, + void *private_data) +{ + *cb = ev->tracing.callback; + *(void**)private_data = ev->tracing.private_data; +} + +void tevent_trace_point_callback(struct tevent_context *ev, + enum tevent_trace_point tp) +{ + if (ev->tracing.callback != NULL) { + ev->tracing.callback(tp, ev->tracing.private_data); + } +} diff --git a/ldb-2.0.8/lib/tevent/tevent_epoll.c b/ldb-2.0.8/lib/tevent/tevent_epoll.c new file mode 100644 index 0000000..9cbe505 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent_epoll.c @@ -0,0 +1,956 @@ +/* + Unix SMB/CIFS implementation. + + main select loop and event handling - epoll implementation + + Copyright (C) Andrew Tridgell 2003-2005 + Copyright (C) Stefan Metzmacher 2005-2013 + Copyright (C) Jeremy Allison 2013 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#include "system/filesys.h" +#include "system/select.h" +#include "tevent.h" +#include "tevent_internal.h" +#include "tevent_util.h" + +struct epoll_event_context { + /* a pointer back to the generic event_context */ + struct tevent_context *ev; + + /* when using epoll this is the handle from epoll_create */ + int epoll_fd; + + pid_t pid; + + bool panic_force_replay; + bool *panic_state; + bool (*panic_fallback)(struct tevent_context *ev, bool replay); +}; + +#define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT (1<<0) +#define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1) +#define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2) +#define EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX (1<<3) + +#ifdef TEST_PANIC_FALLBACK + +static int epoll_create_panic_fallback(struct epoll_event_context *epoll_ev, + int size) +{ + if (epoll_ev->panic_fallback == NULL) { + return epoll_create(size); + } + + /* 50% of the time, fail... */ + if ((random() % 2) == 0) { + errno = EINVAL; + return -1; + } + + return epoll_create(size); +} + +static int epoll_ctl_panic_fallback(struct epoll_event_context *epoll_ev, + int epfd, int op, int fd, + struct epoll_event *event) +{ + if (epoll_ev->panic_fallback == NULL) { + return epoll_ctl(epfd, op, fd, event); + } + + /* 50% of the time, fail... */ + if ((random() % 2) == 0) { + errno = EINVAL; + return -1; + } + + return epoll_ctl(epfd, op, fd, event); +} + +static int epoll_wait_panic_fallback(struct epoll_event_context *epoll_ev, + int epfd, + struct epoll_event *events, + int maxevents, + int timeout) +{ + if (epoll_ev->panic_fallback == NULL) { + return epoll_wait(epfd, events, maxevents, timeout); + } + + /* 50% of the time, fail... */ + if ((random() % 2) == 0) { + errno = EINVAL; + return -1; + } + + return epoll_wait(epfd, events, maxevents, timeout); +} + +#define epoll_create(_size) \ + epoll_create_panic_fallback(epoll_ev, _size) +#define epoll_ctl(_epfd, _op, _fd, _event) \ + epoll_ctl_panic_fallback(epoll_ev,_epfd, _op, _fd, _event) +#define epoll_wait(_epfd, _events, _maxevents, _timeout) \ + epoll_wait_panic_fallback(epoll_ev, _epfd, _events, _maxevents, _timeout) +#endif + +/* + called to set the panic fallback function. +*/ +_PRIVATE_ void tevent_epoll_set_panic_fallback(struct tevent_context *ev, + bool (*panic_fallback)(struct tevent_context *ev, + bool replay)) +{ + struct epoll_event_context *epoll_ev = + talloc_get_type_abort(ev->additional_data, + struct epoll_event_context); + + epoll_ev->panic_fallback = panic_fallback; +} + +/* + called when a epoll call fails +*/ +static void epoll_panic(struct epoll_event_context *epoll_ev, + const char *reason, bool replay) +{ + struct tevent_context *ev = epoll_ev->ev; + bool (*panic_fallback)(struct tevent_context *ev, bool replay); + + panic_fallback = epoll_ev->panic_fallback; + + if (epoll_ev->panic_state != NULL) { + *epoll_ev->panic_state = true; + } + + if (epoll_ev->panic_force_replay) { + replay = true; + } + + TALLOC_FREE(ev->additional_data); + + if (panic_fallback == NULL) { + tevent_debug(ev, TEVENT_DEBUG_FATAL, + "%s (%s) replay[%u] - calling abort()\n", + reason, strerror(errno), (unsigned)replay); + abort(); + } + + tevent_debug(ev, TEVENT_DEBUG_ERROR, + "%s (%s) replay[%u] - calling panic_fallback\n", + reason, strerror(errno), (unsigned)replay); + + if (!panic_fallback(ev, replay)) { + /* Fallback failed. */ + tevent_debug(ev, TEVENT_DEBUG_FATAL, + "%s (%s) replay[%u] - calling abort()\n", + reason, strerror(errno), (unsigned)replay); + abort(); + } +} + +/* + map from TEVENT_FD_* to EPOLLIN/EPOLLOUT +*/ +static uint32_t epoll_map_flags(uint16_t flags) +{ + uint32_t ret = 0; + if (flags & TEVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP); + if (flags & TEVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP); + return ret; +} + +/* + free the epoll fd +*/ +static int epoll_ctx_destructor(struct epoll_event_context *epoll_ev) +{ + close(epoll_ev->epoll_fd); + epoll_ev->epoll_fd = -1; + return 0; +} + +/* + init the epoll fd +*/ +static int epoll_init_ctx(struct epoll_event_context *epoll_ev) +{ + epoll_ev->epoll_fd = epoll_create(64); + if (epoll_ev->epoll_fd == -1) { + tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL, + "Failed to create epoll handle.\n"); + return -1; + } + + if (!ev_set_close_on_exec(epoll_ev->epoll_fd)) { + tevent_debug(epoll_ev->ev, TEVENT_DEBUG_WARNING, + "Failed to set close-on-exec, file descriptor may be leaked to children.\n"); + } + + epoll_ev->pid = getpid(); + talloc_set_destructor(epoll_ev, epoll_ctx_destructor); + + return 0; +} + +static void epoll_update_event(struct epoll_event_context *epoll_ev, struct tevent_fd *fde); + +/* + reopen the epoll handle when our pid changes + see http://junkcode.samba.org/ftp/unpacked/junkcode/epoll_fork.c for an + demonstration of why this is needed + */ +static void epoll_check_reopen(struct epoll_event_context *epoll_ev) +{ + struct tevent_fd *fde; + bool *caller_panic_state = epoll_ev->panic_state; + bool panic_triggered = false; + + if (epoll_ev->pid == getpid()) { + return; + } + + close(epoll_ev->epoll_fd); + epoll_ev->epoll_fd = epoll_create(64); + if (epoll_ev->epoll_fd == -1) { + epoll_panic(epoll_ev, "epoll_create() failed", false); + return; + } + + if (!ev_set_close_on_exec(epoll_ev->epoll_fd)) { + tevent_debug(epoll_ev->ev, TEVENT_DEBUG_WARNING, + "Failed to set close-on-exec, file descriptor may be leaked to children.\n"); + } + + epoll_ev->pid = getpid(); + epoll_ev->panic_state = &panic_triggered; + for (fde=epoll_ev->ev->fd_events;fde;fde=fde->next) { + fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; + epoll_update_event(epoll_ev, fde); + + if (panic_triggered) { + if (caller_panic_state != NULL) { + *caller_panic_state = true; + } + return; + } + } + epoll_ev->panic_state = NULL; +} + +/* + epoll cannot add the same file descriptor twice, once + with read, once with write which is allowed by the + tevent backend. Multiplex the existing fde, flag it + as such so we can search for the correct fde on + event triggering. +*/ + +static int epoll_add_multiplex_fd(struct epoll_event_context *epoll_ev, + struct tevent_fd *add_fde) +{ + struct epoll_event event; + struct tevent_fd *mpx_fde; + int ret; + + /* Find the existing fde that caused the EEXIST error. */ + for (mpx_fde = epoll_ev->ev->fd_events; mpx_fde; mpx_fde = mpx_fde->next) { + if (mpx_fde->fd != add_fde->fd) { + continue; + } + + if (mpx_fde == add_fde) { + continue; + } + + break; + } + if (mpx_fde == NULL) { + tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL, + "can't find multiplex fde for fd[%d]", + add_fde->fd); + return -1; + } + + if (mpx_fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) { + /* Logic error. Can't have more than 2 multiplexed fde's. */ + tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL, + "multiplex fde for fd[%d] is already multiplexed\n", + mpx_fde->fd); + return -1; + } + + /* + * The multiplex fde must have the same fd, and also + * already have an epoll event attached. + */ + if (!(mpx_fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT)) { + /* Logic error. Can't have more than 2 multiplexed fde's. */ + tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL, + "multiplex fde for fd[%d] has no event\n", + mpx_fde->fd); + return -1; + } + + /* Modify the mpx_fde to add in the new flags. */ + ZERO_STRUCT(event); + event.events = epoll_map_flags(mpx_fde->flags); + event.events |= epoll_map_flags(add_fde->flags); + event.data.ptr = mpx_fde; + ret = epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_MOD, mpx_fde->fd, &event); + if (ret != 0 && errno == EBADF) { + tevent_debug(epoll_ev->ev, TEVENT_DEBUG_ERROR, + "EPOLL_CTL_MOD EBADF for " + "add_fde[%p] mpx_fde[%p] fd[%d] - disabling\n", + add_fde, mpx_fde, add_fde->fd); + DLIST_REMOVE(epoll_ev->ev->fd_events, mpx_fde); + mpx_fde->wrapper = NULL; + mpx_fde->event_ctx = NULL; + DLIST_REMOVE(epoll_ev->ev->fd_events, add_fde); + add_fde->wrapper = NULL; + add_fde->event_ctx = NULL; + return 0; + } else if (ret != 0) { + return ret; + } + + /* + * Make each fde->additional_data pointers point at each other + * so we can look them up from each other. They are now paired. + */ + mpx_fde->additional_data = (struct tevent_fd *)add_fde; + add_fde->additional_data = (struct tevent_fd *)mpx_fde; + + /* Now flag both fde's as being multiplexed. */ + mpx_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX; + add_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX; + + /* we need to keep the GOT_ERROR flag */ + if (mpx_fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR) { + add_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR; + } + + return 0; +} + +/* + add the epoll event to the given fd_event +*/ +static void epoll_add_event(struct epoll_event_context *epoll_ev, struct tevent_fd *fde) +{ + struct epoll_event event; + int ret; + struct tevent_fd *mpx_fde = NULL; + + fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; + fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; + + if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) { + /* + * This is a multiplexed fde, we need to include both + * flags in the modified event. + */ + mpx_fde = talloc_get_type_abort(fde->additional_data, + struct tevent_fd); + + mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; + mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; + } + + ZERO_STRUCT(event); + event.events = epoll_map_flags(fde->flags); + if (mpx_fde != NULL) { + event.events |= epoll_map_flags(mpx_fde->flags); + } + event.data.ptr = fde; + ret = epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_ADD, fde->fd, &event); + if (ret != 0 && errno == EBADF) { + tevent_debug(epoll_ev->ev, TEVENT_DEBUG_ERROR, + "EPOLL_CTL_ADD EBADF for " + "fde[%p] mpx_fde[%p] fd[%d] - disabling\n", + fde, mpx_fde, fde->fd); + DLIST_REMOVE(epoll_ev->ev->fd_events, fde); + fde->wrapper = NULL; + fde->event_ctx = NULL; + if (mpx_fde != NULL) { + DLIST_REMOVE(epoll_ev->ev->fd_events, mpx_fde); + mpx_fde->wrapper = NULL; + mpx_fde->event_ctx = NULL; + } + return; + } else if (ret != 0 && errno == EEXIST && mpx_fde == NULL) { + ret = epoll_add_multiplex_fd(epoll_ev, fde); + if (ret != 0) { + epoll_panic(epoll_ev, "epoll_add_multiplex_fd failed", + false); + return; + } + } else if (ret != 0) { + epoll_panic(epoll_ev, "EPOLL_CTL_ADD failed", false); + return; + } + + fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; + /* only if we want to read we want to tell the event handler about errors */ + if (fde->flags & TEVENT_FD_READ) { + fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; + } + + if (mpx_fde == NULL) { + return; + } + + mpx_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; + /* only if we want to read we want to tell the event handler about errors */ + if (mpx_fde->flags & TEVENT_FD_READ) { + mpx_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; + } +} + +/* + delete the epoll event for given fd_event +*/ +static void epoll_del_event(struct epoll_event_context *epoll_ev, struct tevent_fd *fde) +{ + struct epoll_event event; + int ret; + struct tevent_fd *mpx_fde = NULL; + + fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; + fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; + + if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) { + /* + * This is a multiplexed fde, we need to modify both events. + */ + mpx_fde = talloc_get_type_abort(fde->additional_data, + struct tevent_fd); + + mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; + mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; + } + + ZERO_STRUCT(event); + ret = epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_DEL, fde->fd, &event); + if (ret != 0 && errno == ENOENT) { + /* + * This can happen after a epoll_check_reopen + * within epoll_event_fd_destructor. + */ + tevent_debug(epoll_ev->ev, TEVENT_DEBUG_TRACE, + "EPOLL_CTL_DEL ignoring ENOENT for fd[%d]\n", + fde->fd); + return; + } else if (ret != 0 && errno == EBADF) { + tevent_debug(epoll_ev->ev, TEVENT_DEBUG_WARNING, + "EPOLL_CTL_DEL EBADF for " + "fde[%p] mpx_fde[%p] fd[%d] - disabling\n", + fde, mpx_fde, fde->fd); + DLIST_REMOVE(epoll_ev->ev->fd_events, fde); + fde->wrapper = NULL; + fde->event_ctx = NULL; + if (mpx_fde != NULL) { + DLIST_REMOVE(epoll_ev->ev->fd_events, mpx_fde); + mpx_fde->wrapper = NULL; + mpx_fde->event_ctx = NULL; + } + return; + } else if (ret != 0) { + epoll_panic(epoll_ev, "EPOLL_CTL_DEL failed", false); + return; + } +} + +/* + change the epoll event to the given fd_event +*/ +static void epoll_mod_event(struct epoll_event_context *epoll_ev, struct tevent_fd *fde) +{ + struct tevent_fd *mpx_fde = NULL; + struct epoll_event event; + int ret; + + fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; + fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; + + if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) { + /* + * This is a multiplexed fde, we need to include both + * flags in the modified event. + */ + mpx_fde = talloc_get_type_abort(fde->additional_data, + struct tevent_fd); + + mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; + mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; + } + + ZERO_STRUCT(event); + event.events = epoll_map_flags(fde->flags); + if (mpx_fde != NULL) { + event.events |= epoll_map_flags(mpx_fde->flags); + } + event.data.ptr = fde; + ret = epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_MOD, fde->fd, &event); + if (ret != 0 && errno == EBADF) { + tevent_debug(epoll_ev->ev, TEVENT_DEBUG_ERROR, + "EPOLL_CTL_MOD EBADF for " + "fde[%p] mpx_fde[%p] fd[%d] - disabling\n", + fde, mpx_fde, fde->fd); + DLIST_REMOVE(epoll_ev->ev->fd_events, fde); + fde->wrapper = NULL; + fde->event_ctx = NULL; + if (mpx_fde != NULL) { + DLIST_REMOVE(epoll_ev->ev->fd_events, mpx_fde); + mpx_fde->wrapper = NULL; + mpx_fde->event_ctx = NULL; + } + return; + } else if (ret != 0) { + epoll_panic(epoll_ev, "EPOLL_CTL_MOD failed", false); + return; + } + + fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; + /* only if we want to read we want to tell the event handler about errors */ + if (fde->flags & TEVENT_FD_READ) { + fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; + } + + if (mpx_fde == NULL) { + return; + } + + mpx_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; + /* only if we want to read we want to tell the event handler about errors */ + if (mpx_fde->flags & TEVENT_FD_READ) { + mpx_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; + } +} + +static void epoll_update_event(struct epoll_event_context *epoll_ev, struct tevent_fd *fde) +{ + bool got_error = (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR); + bool want_read = (fde->flags & TEVENT_FD_READ); + bool want_write= (fde->flags & TEVENT_FD_WRITE); + struct tevent_fd *mpx_fde = NULL; + + if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) { + /* + * work out what the multiplexed fde wants. + */ + mpx_fde = talloc_get_type_abort(fde->additional_data, + struct tevent_fd); + + if (mpx_fde->flags & TEVENT_FD_READ) { + want_read = true; + } + + if (mpx_fde->flags & TEVENT_FD_WRITE) { + want_write = true; + } + } + + /* there's already an event */ + if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT) { + if (want_read || (want_write && !got_error)) { + epoll_mod_event(epoll_ev, fde); + return; + } + /* + * if we want to match the select behavior, we need to remove the epoll_event + * when the caller isn't interested in events. + * + * this is because epoll reports EPOLLERR and EPOLLHUP, even without asking for them + */ + epoll_del_event(epoll_ev, fde); + return; + } + + /* there's no epoll_event attached to the fde */ + if (want_read || (want_write && !got_error)) { + epoll_add_event(epoll_ev, fde); + return; + } +} + +/* + Cope with epoll returning EPOLLHUP|EPOLLERR on an event. + Return true if there's nothing else to do, false if + this event needs further handling. +*/ +static bool epoll_handle_hup_or_err(struct epoll_event_context *epoll_ev, + struct tevent_fd *fde) +{ + if (fde == NULL) { + /* Nothing to do if no event. */ + return true; + } + + fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR; + /* + * if we only wait for TEVENT_FD_WRITE, we should not tell the + * event handler about it, and remove the epoll_event, + * as we only report errors when waiting for read events, + * to match the select() behavior + */ + if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR)) { + /* + * Do the same as the poll backend and + * remove the writeable flag. + */ + fde->flags &= ~TEVENT_FD_WRITE; + return true; + } + /* This has TEVENT_FD_READ set, we're not finished. */ + return false; +} + +/* + event loop handling using epoll +*/ +static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval *tvalp) +{ + int ret, i; +#define MAXEVENTS 1 + struct epoll_event events[MAXEVENTS]; + int timeout = -1; + int wait_errno; + + if (tvalp) { + /* it's better to trigger timed events a bit later than too early */ + timeout = ((tvalp->tv_usec+999) / 1000) + (tvalp->tv_sec*1000); + } + + if (epoll_ev->ev->signal_events && + tevent_common_check_signal(epoll_ev->ev)) { + return 0; + } + + tevent_trace_point_callback(epoll_ev->ev, TEVENT_TRACE_BEFORE_WAIT); + ret = epoll_wait(epoll_ev->epoll_fd, events, MAXEVENTS, timeout); + wait_errno = errno; + tevent_trace_point_callback(epoll_ev->ev, TEVENT_TRACE_AFTER_WAIT); + + if (ret == -1 && wait_errno == EINTR && epoll_ev->ev->signal_events) { + if (tevent_common_check_signal(epoll_ev->ev)) { + return 0; + } + } + + if (ret == -1 && wait_errno != EINTR) { + epoll_panic(epoll_ev, "epoll_wait() failed", true); + return -1; + } + + if (ret == 0 && tvalp) { + /* we don't care about a possible delay here */ + tevent_common_loop_timer_delay(epoll_ev->ev); + return 0; + } + + for (i=0;iadditional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) { + /* + * Save off the multiplexed event in case we need + * to use it to call the handler function. + */ + mpx_fde = talloc_get_type_abort(fde->additional_data, + struct tevent_fd); + } + if (events[i].events & (EPOLLHUP|EPOLLERR)) { + bool handled_fde = epoll_handle_hup_or_err(epoll_ev, fde); + bool handled_mpx = epoll_handle_hup_or_err(epoll_ev, mpx_fde); + + if (handled_fde && handled_mpx) { + epoll_update_event(epoll_ev, fde); + continue; + } + + if (!handled_mpx) { + /* + * If the mpx event was the one that needs + * further handling, it's the TEVENT_FD_READ + * event so switch over and call that handler. + */ + fde = mpx_fde; + mpx_fde = NULL; + } + flags |= TEVENT_FD_READ; + } + if (events[i].events & EPOLLIN) flags |= TEVENT_FD_READ; + if (events[i].events & EPOLLOUT) flags |= TEVENT_FD_WRITE; + + if (flags & TEVENT_FD_WRITE) { + if (fde->flags & TEVENT_FD_WRITE) { + mpx_fde = NULL; + } + if (mpx_fde && mpx_fde->flags & TEVENT_FD_WRITE) { + fde = mpx_fde; + mpx_fde = NULL; + } + } + + if (mpx_fde) { + /* Ensure we got the right fde. */ + if ((flags & fde->flags) == 0) { + fde = mpx_fde; + mpx_fde = NULL; + } + } + + /* + * make sure we only pass the flags + * the handler is expecting. + */ + flags &= fde->flags; + if (flags) { + return tevent_common_invoke_fd_handler(fde, flags, NULL); + } + } + + return 0; +} + +/* + create a epoll_event_context structure. +*/ +static int epoll_event_context_init(struct tevent_context *ev) +{ + int ret; + struct epoll_event_context *epoll_ev; + + /* + * We might be called during tevent_re_initialise() + * which means we need to free our old additional_data. + */ + TALLOC_FREE(ev->additional_data); + + epoll_ev = talloc_zero(ev, struct epoll_event_context); + if (!epoll_ev) return -1; + epoll_ev->ev = ev; + epoll_ev->epoll_fd = -1; + + ret = epoll_init_ctx(epoll_ev); + if (ret != 0) { + talloc_free(epoll_ev); + return ret; + } + + ev->additional_data = epoll_ev; + return 0; +} + +/* + destroy an fd_event +*/ +static int epoll_event_fd_destructor(struct tevent_fd *fde) +{ + struct tevent_context *ev = fde->event_ctx; + struct epoll_event_context *epoll_ev = NULL; + bool panic_triggered = false; + struct tevent_fd *mpx_fde = NULL; + int flags = fde->flags; + + if (ev == NULL) { + return tevent_common_fd_destructor(fde); + } + + epoll_ev = talloc_get_type_abort(ev->additional_data, + struct epoll_event_context); + + /* + * we must remove the event from the list + * otherwise a panic fallback handler may + * reuse invalid memory + */ + DLIST_REMOVE(ev->fd_events, fde); + + if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) { + mpx_fde = talloc_get_type_abort(fde->additional_data, + struct tevent_fd); + + fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX; + mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX; + + fde->additional_data = NULL; + mpx_fde->additional_data = NULL; + + fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; + } + + epoll_ev->panic_state = &panic_triggered; + epoll_check_reopen(epoll_ev); + if (panic_triggered) { + return tevent_common_fd_destructor(fde); + } + + if (mpx_fde != NULL) { + epoll_update_event(epoll_ev, mpx_fde); + if (panic_triggered) { + return tevent_common_fd_destructor(fde); + } + } + + fde->flags = 0; + epoll_update_event(epoll_ev, fde); + fde->flags = flags; + if (panic_triggered) { + return tevent_common_fd_destructor(fde); + } + epoll_ev->panic_state = NULL; + + return tevent_common_fd_destructor(fde); +} + +/* + add a fd based event + return NULL on failure (memory allocation error) +*/ +static struct tevent_fd *epoll_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx, + int fd, uint16_t flags, + tevent_fd_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + struct epoll_event_context *epoll_ev = + talloc_get_type_abort(ev->additional_data, + struct epoll_event_context); + struct tevent_fd *fde; + bool panic_triggered = false; + + fde = tevent_common_add_fd(ev, mem_ctx, fd, flags, + handler, private_data, + handler_name, location); + if (!fde) return NULL; + + talloc_set_destructor(fde, epoll_event_fd_destructor); + + epoll_ev->panic_state = &panic_triggered; + epoll_check_reopen(epoll_ev); + if (panic_triggered) { + return fde; + } + epoll_ev->panic_state = NULL; + + epoll_update_event(epoll_ev, fde); + + return fde; +} + +/* + set the fd event flags +*/ +static void epoll_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags) +{ + struct tevent_context *ev; + struct epoll_event_context *epoll_ev; + bool panic_triggered = false; + + if (fde->flags == flags) return; + + ev = fde->event_ctx; + epoll_ev = talloc_get_type_abort(ev->additional_data, + struct epoll_event_context); + + fde->flags = flags; + + epoll_ev->panic_state = &panic_triggered; + epoll_check_reopen(epoll_ev); + if (panic_triggered) { + return; + } + epoll_ev->panic_state = NULL; + + epoll_update_event(epoll_ev, fde); +} + +/* + do a single event loop using the events defined in ev +*/ +static int epoll_event_loop_once(struct tevent_context *ev, const char *location) +{ + struct epoll_event_context *epoll_ev = + talloc_get_type_abort(ev->additional_data, + struct epoll_event_context); + struct timeval tval; + bool panic_triggered = false; + + if (ev->signal_events && + tevent_common_check_signal(ev)) { + return 0; + } + + if (ev->threaded_contexts != NULL) { + tevent_common_threaded_activate_immediate(ev); + } + + if (ev->immediate_events && + tevent_common_loop_immediate(ev)) { + return 0; + } + + tval = tevent_common_loop_timer_delay(ev); + if (tevent_timeval_is_zero(&tval)) { + return 0; + } + + epoll_ev->panic_state = &panic_triggered; + epoll_ev->panic_force_replay = true; + epoll_check_reopen(epoll_ev); + if (panic_triggered) { + errno = EINVAL; + return -1; + } + epoll_ev->panic_force_replay = false; + epoll_ev->panic_state = NULL; + + return epoll_event_loop(epoll_ev, &tval); +} + +static const struct tevent_ops epoll_event_ops = { + .context_init = epoll_event_context_init, + .add_fd = epoll_event_add_fd, + .set_fd_close_fn = tevent_common_fd_set_close_fn, + .get_fd_flags = tevent_common_fd_get_flags, + .set_fd_flags = epoll_event_set_fd_flags, + .add_timer = tevent_common_add_timer_v2, + .schedule_immediate = tevent_common_schedule_immediate, + .add_signal = tevent_common_add_signal, + .loop_once = epoll_event_loop_once, + .loop_wait = tevent_common_loop_wait, +}; + +_PRIVATE_ bool tevent_epoll_init(void) +{ + return tevent_register_backend("epoll", &epoll_event_ops); +} diff --git a/ldb-2.0.8/lib/tevent/tevent_fd.c b/ldb-2.0.8/lib/tevent/tevent_fd.c new file mode 100644 index 0000000..a0557fe --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent_fd.c @@ -0,0 +1,161 @@ +/* + Unix SMB/CIFS implementation. + + common events code for fd events + + Copyright (C) Stefan Metzmacher 2009 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#define TEVENT_DEPRECATED 1 +#include "tevent.h" +#include "tevent_internal.h" +#include "tevent_util.h" + +int tevent_common_fd_destructor(struct tevent_fd *fde) +{ + if (fde->destroyed) { + tevent_common_check_double_free(fde, "tevent_fd double free"); + goto done; + } + fde->destroyed = true; + + if (fde->event_ctx) { + DLIST_REMOVE(fde->event_ctx->fd_events, fde); + } + + if (fde->close_fn) { + fde->close_fn(fde->event_ctx, fde, fde->fd, fde->private_data); + fde->fd = -1; + fde->close_fn = NULL; + } + + fde->event_ctx = NULL; +done: + if (fde->busy) { + return -1; + } + fde->wrapper = NULL; + + return 0; +} + +struct tevent_fd *tevent_common_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx, + int fd, uint16_t flags, + tevent_fd_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + struct tevent_fd *fde; + + /* tevent will crash later on select() if we save + * a negative file descriptor. Better to fail here + * so that consumers will be able to debug it + */ + if (fd < 0) return NULL; + + fde = talloc(mem_ctx?mem_ctx:ev, struct tevent_fd); + if (!fde) return NULL; + + *fde = (struct tevent_fd) { + .event_ctx = ev, + .fd = fd, + .flags = flags, + .handler = handler, + .private_data = private_data, + .handler_name = handler_name, + .location = location, + }; + + DLIST_ADD(ev->fd_events, fde); + + talloc_set_destructor(fde, tevent_common_fd_destructor); + + return fde; +} +uint16_t tevent_common_fd_get_flags(struct tevent_fd *fde) +{ + return fde->flags; +} + +void tevent_common_fd_set_flags(struct tevent_fd *fde, uint16_t flags) +{ + if (fde->flags == flags) return; + fde->flags = flags; +} + +void tevent_common_fd_set_close_fn(struct tevent_fd *fde, + tevent_fd_close_fn_t close_fn) +{ + fde->close_fn = close_fn; +} + +int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags, + bool *removed) +{ + struct tevent_context *handler_ev = fde->event_ctx; + + if (removed != NULL) { + *removed = false; + } + + if (fde->event_ctx == NULL) { + return 0; + } + + fde->busy = true; + if (fde->wrapper != NULL) { + handler_ev = fde->wrapper->wrap_ev; + + tevent_wrapper_push_use_internal(handler_ev, fde->wrapper); + fde->wrapper->ops->before_fd_handler( + fde->wrapper->wrap_ev, + fde->wrapper->private_state, + fde->wrapper->main_ev, + fde, + flags, + fde->handler_name, + fde->location); + } + fde->handler(handler_ev, fde, flags, fde->private_data); + if (fde->wrapper != NULL) { + fde->wrapper->ops->after_fd_handler( + fde->wrapper->wrap_ev, + fde->wrapper->private_state, + fde->wrapper->main_ev, + fde, + flags, + fde->handler_name, + fde->location); + tevent_wrapper_pop_use_internal(handler_ev, fde->wrapper); + } + fde->busy = false; + + if (fde->destroyed) { + talloc_set_destructor(fde, NULL); + TALLOC_FREE(fde); + if (removed != NULL) { + *removed = true; + } + } + + return 0; +} diff --git a/ldb-2.0.8/lib/tevent/tevent_immediate.c b/ldb-2.0.8/lib/tevent/tevent_immediate.c new file mode 100644 index 0000000..d7f8dcc --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent_immediate.c @@ -0,0 +1,210 @@ +/* + Unix SMB/CIFS implementation. + + common events code for immediate events + + Copyright (C) Stefan Metzmacher 2009 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#define TEVENT_DEPRECATED 1 +#include "tevent.h" +#include "tevent_internal.h" +#include "tevent_util.h" + +static void tevent_common_immediate_cancel(struct tevent_immediate *im) +{ + const char *create_location = im->create_location; + bool busy = im->busy; + + if (im->destroyed) { + tevent_abort(im->event_ctx, "tevent_immediate use after free"); + return; + } + + if (!im->event_ctx) { + return; + } + + if (im->handler_name != NULL) { + tevent_debug(im->event_ctx, TEVENT_DEBUG_TRACE, + "Cancel immediate event %p \"%s\"\n", + im, im->handler_name); + } + + /* let the backend free im->additional_data */ + if (im->cancel_fn) { + im->cancel_fn(im); + } + + DLIST_REMOVE(im->event_ctx->immediate_events, im); + + *im = (struct tevent_immediate) { + .create_location = create_location, + .busy = busy, + }; + + if (!busy) { + talloc_set_destructor(im, NULL); + } +} + +/* + destroy an immediate event +*/ +static int tevent_common_immediate_destructor(struct tevent_immediate *im) +{ + if (im->destroyed) { + tevent_common_check_double_free(im, + "tevent_immediate double free"); + goto done; + } + + tevent_common_immediate_cancel(im); + + im->destroyed = true; + +done: + if (im->busy) { + return -1; + } + + return 0; +} + +/* + * schedule an immediate event on + */ +void tevent_common_schedule_immediate(struct tevent_immediate *im, + struct tevent_context *ev, + tevent_immediate_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + const char *create_location = im->create_location; + bool busy = im->busy; + struct tevent_wrapper_glue *glue = im->wrapper; + + tevent_common_immediate_cancel(im); + + if (!handler) { + return; + } + + *im = (struct tevent_immediate) { + .event_ctx = ev, + .wrapper = glue, + .handler = handler, + .private_data = private_data, + .handler_name = handler_name, + .create_location = create_location, + .schedule_location = location, + .busy = busy, + }; + + DLIST_ADD_END(ev->immediate_events, im); + talloc_set_destructor(im, tevent_common_immediate_destructor); + + tevent_debug(ev, TEVENT_DEBUG_TRACE, + "Schedule immediate event \"%s\": %p\n", + handler_name, im); +} + +int tevent_common_invoke_immediate_handler(struct tevent_immediate *im, + bool *removed) +{ + struct tevent_context *handler_ev = im->event_ctx; + struct tevent_context *ev = im->event_ctx; + struct tevent_immediate cur = *im; + + if (removed != NULL) { + *removed = false; + } + + tevent_debug(ev, TEVENT_DEBUG_TRACE, + "Run immediate event \"%s\": %p\n", + im->handler_name, im); + + /* + * remember the handler and then clear the event + * the handler might reschedule the event + */ + + im->busy = true; + im->handler_name = NULL; + tevent_common_immediate_cancel(im); + if (cur.wrapper != NULL) { + handler_ev = cur.wrapper->wrap_ev; + + tevent_wrapper_push_use_internal(handler_ev, cur.wrapper); + cur.wrapper->ops->before_immediate_handler( + cur.wrapper->wrap_ev, + cur.wrapper->private_state, + cur.wrapper->main_ev, + im, + cur.handler_name, + cur.schedule_location); + } + cur.handler(handler_ev, im, cur.private_data); + if (cur.wrapper != NULL) { + cur.wrapper->ops->after_immediate_handler( + cur.wrapper->wrap_ev, + cur.wrapper->private_state, + cur.wrapper->main_ev, + im, + cur.handler_name, + cur.schedule_location); + tevent_wrapper_pop_use_internal(handler_ev, cur.wrapper); + } + im->busy = false; + + if (im->destroyed) { + talloc_set_destructor(im, NULL); + TALLOC_FREE(im); + if (removed != NULL) { + *removed = true; + } + } + + return 0; +} + +/* + trigger the first immediate event and return true + if no event was triggered return false +*/ +bool tevent_common_loop_immediate(struct tevent_context *ev) +{ + struct tevent_immediate *im = ev->immediate_events; + int ret; + + if (!im) { + return false; + } + + ret = tevent_common_invoke_immediate_handler(im, NULL); + if (ret != 0) { + tevent_abort(ev, "tevent_common_invoke_immediate_handler() failed"); + } + + return true; +} + diff --git a/ldb-2.0.8/lib/tevent/tevent_internal.h b/ldb-2.0.8/lib/tevent/tevent_internal.h new file mode 100644 index 0000000..5365fce --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent_internal.h @@ -0,0 +1,471 @@ +/* + Unix SMB/CIFS implementation. + + generalised event loop handling + + INTERNAL STRUCTS. THERE ARE NO API GUARANTEES. + External users should only ever have to include this header when + implementing new tevent backends. + + Copyright (C) Stefan Metzmacher 2005-2009 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +struct tevent_req { + /** + * @brief What to do on completion + * + * This is used for the user of an async request, fn is called when + * the request completes, either successfully or with an error. + */ + struct { + /** + * @brief Completion function + * Completion function, to be filled by the API user + */ + tevent_req_fn fn; + /** + * @brief Private data for the completion function + */ + void *private_data; + } async; + + /** + * @brief Private state pointer for the actual implementation + * + * The implementation doing the work for the async request needs to + * keep around current data like for example a fd event. The user of + * an async request should not touch this. + */ + void *data; + + /** + * @brief A function to overwrite the default print function + * + * The implementation doing the work may want to implement a + * custom function to print the text representation of the async + * request. + */ + tevent_req_print_fn private_print; + + /** + * @brief A function to cancel the request + * + * The implementation might want to set a function + * that is called when the tevent_req_cancel() function + * was called. + */ + tevent_req_cancel_fn private_cancel; + + /** + * @brief A function to cleanup the request + * + * The implementation might want to set a function + * that is called before the tevent_req_done() and tevent_req_error() + * trigger the callers callback function. + */ + struct { + tevent_req_cleanup_fn fn; + enum tevent_req_state state; + } private_cleanup; + + /** + * @brief Internal state of the request + * + * Callers should only access this via functions and never directly. + */ + struct { + /** + * @brief The talloc type of the data pointer + * + * This is filled by the tevent_req_create() macro. + * + * This for debugging only. + */ + const char *private_type; + + /** + * @brief The location where the request was created + * + * This uses the __location__ macro via the tevent_req_create() + * macro. + * + * This for debugging only. + */ + const char *create_location; + + /** + * @brief The location where the request was finished + * + * This uses the __location__ macro via the tevent_req_done(), + * tevent_req_error() or tevent_req_nomem() macro. + * + * This for debugging only. + */ + const char *finish_location; + + /** + * @brief The location where the request was canceled + * + * This uses the __location__ macro via the + * tevent_req_cancel() macro. + * + * This for debugging only. + */ + const char *cancel_location; + + /** + * @brief The external state - will be queried by the caller + * + * While the async request is being processed, state will remain in + * TEVENT_REQ_IN_PROGRESS. A request is finished if + * req->state>=TEVENT_REQ_DONE. + */ + enum tevent_req_state state; + + /** + * @brief status code when finished + * + * This status can be queried in the async completion function. It + * will be set to 0 when everything went fine. + */ + uint64_t error; + + /** + * @brief the immediate event used by tevent_req_post + * + */ + struct tevent_immediate *trigger; + + /** + * @brief An event context which will be used to + * defer the _tevent_req_notify_callback(). + */ + struct tevent_context *defer_callback_ev; + + /** + * @brief the timer event if tevent_req_set_endtime was used + * + */ + struct tevent_timer *timer; + + /** + * @brief The place where profiling data is kept + */ + struct tevent_req_profile *profile; + } internal; +}; + +struct tevent_req_profile { + struct tevent_req_profile *prev, *next; + struct tevent_req_profile *parent; + const char *req_name; + pid_t pid; + const char *start_location; + struct timeval start_time; + const char *stop_location; + struct timeval stop_time; + enum tevent_req_state state; + uint64_t user_error; + struct tevent_req_profile *subprofiles; +}; + +struct tevent_fd { + struct tevent_fd *prev, *next; + struct tevent_context *event_ctx; + struct tevent_wrapper_glue *wrapper; + bool busy; + bool destroyed; + int fd; + uint16_t flags; /* see TEVENT_FD_* flags */ + tevent_fd_handler_t handler; + tevent_fd_close_fn_t close_fn; + /* this is private for the specific handler */ + void *private_data; + /* this is for debugging only! */ + const char *handler_name; + const char *location; + /* this is private for the events_ops implementation */ + uint64_t additional_flags; + void *additional_data; +}; + +struct tevent_timer { + struct tevent_timer *prev, *next; + struct tevent_context *event_ctx; + struct tevent_wrapper_glue *wrapper; + bool busy; + bool destroyed; + struct timeval next_event; + tevent_timer_handler_t handler; + /* this is private for the specific handler */ + void *private_data; + /* this is for debugging only! */ + const char *handler_name; + const char *location; + /* this is private for the events_ops implementation */ + void *additional_data; +}; + +struct tevent_immediate { + struct tevent_immediate *prev, *next; + struct tevent_context *event_ctx; + struct tevent_wrapper_glue *wrapper; + bool busy; + bool destroyed; + tevent_immediate_handler_t handler; + /* this is private for the specific handler */ + void *private_data; + /* this is for debugging only! */ + const char *handler_name; + const char *create_location; + const char *schedule_location; + /* this is private for the events_ops implementation */ + void (*cancel_fn)(struct tevent_immediate *im); + void *additional_data; +}; + +struct tevent_signal { + struct tevent_signal *prev, *next; + struct tevent_context *event_ctx; + struct tevent_wrapper_glue *wrapper; + bool busy; + bool destroyed; + int signum; + int sa_flags; + tevent_signal_handler_t handler; + /* this is private for the specific handler */ + void *private_data; + /* this is for debugging only! */ + const char *handler_name; + const char *location; + /* this is private for the events_ops implementation */ + void *additional_data; +}; + +struct tevent_threaded_context { + struct tevent_threaded_context *next, *prev; + +#ifdef HAVE_PTHREAD + pthread_mutex_t event_ctx_mutex; +#endif + struct tevent_context *event_ctx; +}; + +struct tevent_debug_ops { + void (*debug)(void *context, enum tevent_debug_level level, + const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); + void *context; +}; + +void tevent_debug(struct tevent_context *ev, enum tevent_debug_level level, + const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); + +void tevent_abort(struct tevent_context *ev, const char *reason); + +void tevent_common_check_double_free(TALLOC_CTX *ptr, const char *reason); + +struct tevent_context { + /* the specific events implementation */ + const struct tevent_ops *ops; + + /* + * The following three pointers are queried on every loop_once + * in the order in which they appear here. Not measured, but + * hopefully putting them at the top together with "ops" + * should make tevent a *bit* more cache-friendly than before. + */ + + /* list of signal events - used by common code */ + struct tevent_signal *signal_events; + + /* List of threaded job indicators */ + struct tevent_threaded_context *threaded_contexts; + + /* list of immediate events - used by common code */ + struct tevent_immediate *immediate_events; + + /* list of fd events - used by common code */ + struct tevent_fd *fd_events; + + /* list of timed events - used by common code */ + struct tevent_timer *timer_events; + + /* List of scheduled immediates */ + pthread_mutex_t scheduled_mutex; + struct tevent_immediate *scheduled_immediates; + + /* this is private for the events_ops implementation */ + void *additional_data; + + /* pipe hack used with signal handlers */ + struct tevent_fd *wakeup_fde; + int wakeup_fd; /* fd to write into */ +#ifndef HAVE_EVENT_FD + int wakeup_read_fd; +#endif + + /* debugging operations */ + struct tevent_debug_ops debug_ops; + + /* info about the nesting status */ + struct { + bool allowed; + uint32_t level; + tevent_nesting_hook hook_fn; + void *hook_private; + } nesting; + + struct { + tevent_trace_callback_t callback; + void *private_data; + } tracing; + + struct { + /* + * This is used on the main event context + */ + struct tevent_wrapper_glue *list; + + /* + * This is used on the wrapper event context + */ + struct tevent_wrapper_glue *glue; + } wrapper; + + /* + * an optimization pointer into timer_events + * used by used by common code via + * tevent_common_add_timer_v2() + */ + struct tevent_timer *last_zero_timer; + +#ifdef HAVE_PTHREAD + struct tevent_context *prev, *next; +#endif +}; + +const struct tevent_ops *tevent_find_ops_byname(const char *name); + +int tevent_common_context_destructor(struct tevent_context *ev); +int tevent_common_loop_wait(struct tevent_context *ev, + const char *location); + +int tevent_common_fd_destructor(struct tevent_fd *fde); +struct tevent_fd *tevent_common_add_fd(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + int fd, + uint16_t flags, + tevent_fd_handler_t handler, + void *private_data, + const char *handler_name, + const char *location); +void tevent_common_fd_set_close_fn(struct tevent_fd *fde, + tevent_fd_close_fn_t close_fn); +uint16_t tevent_common_fd_get_flags(struct tevent_fd *fde); +void tevent_common_fd_set_flags(struct tevent_fd *fde, uint16_t flags); +int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags, + bool *removed); + +struct tevent_timer *tevent_common_add_timer(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + struct timeval next_event, + tevent_timer_handler_t handler, + void *private_data, + const char *handler_name, + const char *location); +struct tevent_timer *tevent_common_add_timer_v2(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + struct timeval next_event, + tevent_timer_handler_t handler, + void *private_data, + const char *handler_name, + const char *location); +struct timeval tevent_common_loop_timer_delay(struct tevent_context *); +int tevent_common_invoke_timer_handler(struct tevent_timer *te, + struct timeval current_time, + bool *removed); + +void tevent_common_schedule_immediate(struct tevent_immediate *im, + struct tevent_context *ev, + tevent_immediate_handler_t handler, + void *private_data, + const char *handler_name, + const char *location); +int tevent_common_invoke_immediate_handler(struct tevent_immediate *im, + bool *removed); +bool tevent_common_loop_immediate(struct tevent_context *ev); +void tevent_common_threaded_activate_immediate(struct tevent_context *ev); + +bool tevent_common_have_events(struct tevent_context *ev); +int tevent_common_wakeup_init(struct tevent_context *ev); +int tevent_common_wakeup_fd(int fd); +int tevent_common_wakeup(struct tevent_context *ev); + +struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + int signum, + int sa_flags, + tevent_signal_handler_t handler, + void *private_data, + const char *handler_name, + const char *location); +int tevent_common_check_signal(struct tevent_context *ev); +void tevent_cleanup_pending_signal_handlers(struct tevent_signal *se); +int tevent_common_invoke_signal_handler(struct tevent_signal *se, + int signum, int count, void *siginfo, + bool *removed); + +struct tevent_context *tevent_wrapper_main_ev(struct tevent_context *ev); + +struct tevent_wrapper_ops; + +struct tevent_wrapper_glue { + struct tevent_wrapper_glue *prev, *next; + struct tevent_context *wrap_ev; + struct tevent_context *main_ev; + bool busy; + bool destroyed; + const struct tevent_wrapper_ops *ops; + void *private_state; +}; + +void tevent_wrapper_push_use_internal(struct tevent_context *ev, + struct tevent_wrapper_glue *wrapper); +void tevent_wrapper_pop_use_internal(const struct tevent_context *__ev_ptr, + struct tevent_wrapper_glue *wrapper); + +bool tevent_standard_init(void); +bool tevent_poll_init(void); +bool tevent_poll_event_add_fd_internal(struct tevent_context *ev, + struct tevent_fd *fde); +bool tevent_poll_mt_init(void); +#ifdef HAVE_EPOLL +bool tevent_epoll_init(void); +void tevent_epoll_set_panic_fallback(struct tevent_context *ev, + bool (*panic_fallback)(struct tevent_context *ev, + bool replay)); +#endif +#ifdef HAVE_SOLARIS_PORTS +bool tevent_port_init(void); +#endif + + +void tevent_trace_point_callback(struct tevent_context *ev, + enum tevent_trace_point); diff --git a/ldb-2.0.8/lib/tevent/tevent_liboop.c b/ldb-2.0.8/lib/tevent/tevent_liboop.c new file mode 100644 index 0000000..68be76b --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent_liboop.c @@ -0,0 +1,292 @@ +/* + Unix SMB/CIFS implementation. + main select loop and event handling + wrapper for http://git.lysator.liu.se/liboop/ + + Copyright (C) Stefan Metzmacher 2005 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "events.h" +#include "events_internal.h" + +#include + +/* + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + NOTE: this code compiles fine, but is completely *UNTESTED* + and is only committed as an example + + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +*/ + +static int oop_event_context_destructor(struct tevent_context *ev) +{ + oop_source_sys *oop_sys = ev->additional_data; + + oop_sys_delete(oop_sys); + + return 0; +} + +/* + create a oop_event_context structure. +*/ +static int oop_event_context_init(struct tevent_context *ev, void *private_data) +{ + oop_source_sys *oop_sys = private_data; + + if (!oop_sys) { + oop_sys = oop_sys_new(); + if (!oop_sys) { + return -1; + } + + talloc_set_destructor(ev, oop_event_context_destructor); + } + + ev->additional_data = oop_sys; + + return 0; +} + +static void *oop_event_fd_handler(oop_source *oop, int fd, oop_event oop_type, void *ptr) +{ + struct tevent_fd *fde = ptr; + + if (fd != fde->fd) return OOP_ERROR; + + switch(oop_type) { + case OOP_READ: + fde->handler(fde->event_ctx, fde, EVENT_FD_READ, fde->private_data); + return OOP_CONTINUE; + case OOP_WRITE: + fde->handler(fde->event_ctx, fde, EVENT_FD_WRITE, fde->private_data); + return OOP_CONTINUE; + case OOP_EXCEPTION: + return OOP_ERROR; + case OOP_NUM_EVENTS: + return OOP_ERROR; + } + + return OOP_ERROR; +} + +/* + destroy an fd_event +*/ +static int oop_event_fd_destructor(struct tevent_fd *fde) +{ + struct tevent_context *ev = fde->event_ctx; + oop_source_sys *oop_sys = ev->additional_data; + oop_source *oop = oop_sys_source(oop_sys); + + if (fde->flags & EVENT_FD_READ) + oop->cancel_fd(oop, fde->fd, OOP_READ); + if (fde->flags & EVENT_FD_WRITE) + oop->cancel_fd(oop, fde->fd, OOP_WRITE); + + if (fde->flags & EVENT_FD_AUTOCLOSE) { + close(fde->fd); + fde->fd = -1; + } + + return 0; +} + +/* + add a fd based event + return NULL on failure (memory allocation error) +*/ +static struct tevent_fd *oop_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx, + int fd, uint16_t flags, + event_fd_handler_t handler, + void *private_data) +{ + struct tevent_fd *fde; + oop_source_sys *oop_sys = ev->additional_data; + oop_source *oop = oop_sys_source(oop_sys); + + fde = talloc(mem_ctx?mem_ctx:ev, struct tevent_fd); + if (!fde) return NULL; + + fde->event_ctx = ev; + fde->fd = fd; + fde->flags = flags; + fde->handler = handler; + fde->private_data = private_data; + fde->additional_flags = 0; + fde->additional_data = NULL; + + if (fde->flags & EVENT_FD_READ) + oop->on_fd(oop, fde->fd, OOP_READ, oop_event_fd_handler, fde); + if (fde->flags & EVENT_FD_WRITE) + oop->on_fd(oop, fde->fd, OOP_WRITE, oop_event_fd_handler, fde); + + talloc_set_destructor(fde, oop_event_fd_destructor); + + return fde; +} + +/* + return the fd event flags +*/ +static uint16_t oop_event_get_fd_flags(struct tevent_fd *fde) +{ + return fde->flags; +} + +/* + set the fd event flags +*/ +static void oop_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags) +{ + oop_source_sys *oop_sys; + oop_source *oop; + + oop_sys = fde->event_ctx->additional_data; + oop = oop_sys_source(oop_sys); + + if ((fde->flags & EVENT_FD_READ)&&(!(flags & EVENT_FD_READ))) + oop->cancel_fd(oop, fde->fd, OOP_READ); + + if ((!(fde->flags & EVENT_FD_READ))&&(flags & EVENT_FD_READ)) + oop->on_fd(oop, fde->fd, OOP_READ, oop_event_fd_handler, fde); + + if ((fde->flags & EVENT_FD_WRITE)&&(!(flags & EVENT_FD_WRITE))) + oop->cancel_fd(oop, fde->fd, OOP_WRITE); + + if ((!(fde->flags & EVENT_FD_WRITE))&&(flags & EVENT_FD_WRITE)) + oop->on_fd(oop, fde->fd, OOP_WRITE, oop_event_fd_handler, fde); + + fde->flags = flags; +} + +static int oop_event_timed_destructor(struct tevent_timer *te); + +static int oop_event_timed_deny_destructor(struct tevent_timer *te) +{ + return -1; +} + +static void *oop_event_timed_handler(oop_source *oop, struct timeval t, void *ptr) +{ + struct tevent_timer *te = ptr; + + /* deny the handler to free the event */ + talloc_set_destructor(te, oop_event_timed_deny_destructor); + te->handler(te->event_ctx, te, t, te->private_data); + + talloc_set_destructor(te, oop_event_timed_destructor); + talloc_free(te); + + return OOP_CONTINUE; +} + +/* + destroy a timed event +*/ +static int oop_event_timed_destructor(struct tevent_timer *te) +{ + struct tevent_context *ev = te->event_ctx; + oop_source_sys *oop_sys = ev->additional_data; + oop_source *oop = oop_sys_source(oop_sys); + + oop->cancel_time(oop, te->next_event, oop_event_timed_handler, te); + + return 0; +} + +/* + add a timed event + return NULL on failure (memory allocation error) +*/ +static struct tevent_timer *oop_event_add_timed(struct tevent_context *ev, TALLOC_CTX *mem_ctx, + struct timeval next_event, + event_timed_handler_t handler, + void *private_data) +{ + oop_source_sys *oop_sys = ev->additional_data; + oop_source *oop = oop_sys_source(oop_sys); + struct tevent_timer *te; + + te = talloc(mem_ctx?mem_ctx:ev, struct tevent_timer); + if (te == NULL) return NULL; + + te->event_ctx = ev; + te->next_event = next_event; + te->handler = handler; + te->private_data = private_data; + te->additional_data = NULL; + + oop->on_time(oop, te->next_event, oop_event_timed_handler, te); + + talloc_set_destructor(te, oop_event_timed_destructor); + + return te; +} + +/* + do a single event loop using the events defined in ev +*/ +static int oop_event_loop_once(struct tevent_context *ev) +{ + void *oop_ret; + oop_source_sys *oop_sys = ev->additional_data; + + oop_ret = oop_sys_run_once(oop_sys); + if (oop_ret == OOP_CONTINUE) { + return 0; + } + + return -1; +} + +/* + return on failure or (with 0) if all fd events are removed +*/ +static int oop_event_loop_wait(struct tevent_context *ev) +{ + void *oop_ret; + oop_source_sys *oop_sys = ev->additional_data; + + oop_ret = oop_sys_run(oop_sys); + if (oop_ret == OOP_CONTINUE) { + return 0; + } + + return -1; +} + +static const struct event_ops event_oop_ops = { + .context_init = oop_event_context_init, + .add_fd = oop_event_add_fd, + .get_fd_flags = oop_event_get_fd_flags, + .set_fd_flags = oop_event_set_fd_flags, + .add_timer = oop_event_add_timed, + .add_signal = common_event_add_signal, + .loop_once = oop_event_loop_once, + .loop_wait = oop_event_loop_wait, +}; + +const struct event_ops *event_liboop_get_ops(void) +{ + return &event_oop_ops; +} diff --git a/ldb-2.0.8/lib/tevent/tevent_poll.c b/ldb-2.0.8/lib/tevent/tevent_poll.c new file mode 100644 index 0000000..f4c6c2d --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent_poll.c @@ -0,0 +1,663 @@ +/* + Unix SMB/CIFS implementation. + main select loop and event handling + Copyright (C) Andrew Tridgell 2003-2005 + Copyright (C) Stefan Metzmacher 2005-2009 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#include "system/filesys.h" +#include "system/select.h" +#include "tevent.h" +#include "tevent_util.h" +#include "tevent_internal.h" + +struct poll_event_context { + /* a pointer back to the generic event_context */ + struct tevent_context *ev; + + /* + * one or more events were deleted or disabled + */ + bool deleted; + + /* + * These two arrays are maintained together. + * + * The following is always true: + * num_fds <= num_fdes + * + * new 'fresh' elements are added at the end + * of the 'fdes' array and picked up later + * to the 'fds' array in poll_event_sync_arrays() + * before the poll() syscall. + */ + struct pollfd *fds; + size_t num_fds; + struct tevent_fd **fdes; + size_t num_fdes; + + /* + * use tevent_common_wakeup(ev) to wake the poll() thread + */ + bool use_mt_mode; +}; + +/* + create a poll_event_context structure. +*/ +static int poll_event_context_init(struct tevent_context *ev) +{ + struct poll_event_context *poll_ev; + + /* + * we might be called during tevent_re_initialise() + * which means we need to free our old additional_data + * in order to detach old fd events from the + * poll_ev->fresh list + */ + TALLOC_FREE(ev->additional_data); + + poll_ev = talloc_zero(ev, struct poll_event_context); + if (poll_ev == NULL) { + return -1; + } + poll_ev->ev = ev; + ev->additional_data = poll_ev; + return 0; +} + +static int poll_event_context_init_mt(struct tevent_context *ev) +{ + struct poll_event_context *poll_ev; + int ret; + + ret = poll_event_context_init(ev); + if (ret == -1) { + return ret; + } + + poll_ev = talloc_get_type_abort( + ev->additional_data, struct poll_event_context); + + ret = tevent_common_wakeup_init(ev); + if (ret != 0) { + return ret; + } + + poll_ev->use_mt_mode = true; + + return 0; +} + +static void poll_event_wake_pollthread(struct poll_event_context *poll_ev) +{ + if (!poll_ev->use_mt_mode) { + return; + } + tevent_common_wakeup(poll_ev->ev); +} + +/* + destroy an fd_event +*/ +static int poll_event_fd_destructor(struct tevent_fd *fde) +{ + struct tevent_context *ev = fde->event_ctx; + struct poll_event_context *poll_ev; + uint64_t del_idx = fde->additional_flags; + + if (ev == NULL) { + goto done; + } + + poll_ev = talloc_get_type_abort( + ev->additional_data, struct poll_event_context); + + if (del_idx == UINT64_MAX) { + goto done; + } + + poll_ev->fdes[del_idx] = NULL; + poll_ev->deleted = true; + poll_event_wake_pollthread(poll_ev); +done: + return tevent_common_fd_destructor(fde); +} + +static void poll_event_schedule_immediate(struct tevent_immediate *im, + struct tevent_context *ev, + tevent_immediate_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + struct poll_event_context *poll_ev = talloc_get_type_abort( + ev->additional_data, struct poll_event_context); + + tevent_common_schedule_immediate(im, ev, handler, private_data, + handler_name, location); + poll_event_wake_pollthread(poll_ev); +} + +/* + Private function called by "standard" backend fallback. + Note this only allows fallback to "poll" backend, not "poll-mt". +*/ +_PRIVATE_ bool tevent_poll_event_add_fd_internal(struct tevent_context *ev, + struct tevent_fd *fde) +{ + struct poll_event_context *poll_ev = talloc_get_type_abort( + ev->additional_data, struct poll_event_context); + uint64_t fde_idx = UINT64_MAX; + size_t num_fdes; + + fde->additional_flags = UINT64_MAX; + talloc_set_destructor(fde, poll_event_fd_destructor); + + if (fde->flags == 0) { + /* + * Nothing more to do... + */ + return true; + } + + /* + * We need to add it to the end of the 'fdes' array. + */ + num_fdes = poll_ev->num_fdes + 1; + if (num_fdes > talloc_array_length(poll_ev->fdes)) { + struct tevent_fd **tmp_fdes = NULL; + size_t array_length; + + array_length = (num_fdes + 15) & ~15; /* round up to 16 */ + + tmp_fdes = talloc_realloc(poll_ev, + poll_ev->fdes, + struct tevent_fd *, + array_length); + if (tmp_fdes == NULL) { + return false; + } + poll_ev->fdes = tmp_fdes; + } + + fde_idx = poll_ev->num_fdes; + fde->additional_flags = fde_idx; + poll_ev->fdes[fde_idx] = fde; + poll_ev->num_fdes++; + + return true; +} + +/* + add a fd based event + return NULL on failure (memory allocation error) +*/ +static struct tevent_fd *poll_event_add_fd(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + int fd, uint16_t flags, + tevent_fd_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + struct poll_event_context *poll_ev = talloc_get_type_abort( + ev->additional_data, struct poll_event_context); + struct tevent_fd *fde; + bool ok; + + if (fd < 0) { + return NULL; + } + + fde = tevent_common_add_fd(ev, + mem_ctx, + fd, + flags, + handler, + private_data, + handler_name, + location); + if (fde == NULL) { + return NULL; + } + + ok = tevent_poll_event_add_fd_internal(ev, fde); + if (!ok) { + TALLOC_FREE(fde); + return NULL; + } + poll_event_wake_pollthread(poll_ev); + + /* + * poll_event_loop_poll will take care of the rest in + * poll_event_setup_fresh + */ + return fde; +} + +/* + set the fd event flags +*/ +static void poll_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags) +{ + struct tevent_context *ev = fde->event_ctx; + struct poll_event_context *poll_ev; + uint64_t idx = fde->additional_flags; + uint16_t pollflags; + + if (ev == NULL) { + return; + } + + if (fde->flags == flags) { + return; + } + + poll_ev = talloc_get_type_abort( + ev->additional_data, struct poll_event_context); + + fde->flags = flags; + + if (idx == UINT64_MAX) { + /* + * We move it between the fresh and disabled lists. + */ + tevent_poll_event_add_fd_internal(ev, fde); + poll_event_wake_pollthread(poll_ev); + return; + } + + if (fde->flags == 0) { + /* + * We need to remove it from the array + * and move it to the disabled list. + */ + poll_ev->fdes[idx] = NULL; + poll_ev->deleted = true; + fde->additional_flags = UINT64_MAX; + poll_event_wake_pollthread(poll_ev); + return; + } + + if (idx >= poll_ev->num_fds) { + /* + * Not yet added to the + * poll_ev->fds array. + */ + poll_event_wake_pollthread(poll_ev); + return; + } + + pollflags = 0; + + if (flags & TEVENT_FD_READ) { + pollflags |= (POLLIN|POLLHUP); + } + if (flags & TEVENT_FD_WRITE) { + pollflags |= (POLLOUT); + } + poll_ev->fds[idx].events = pollflags; + + poll_event_wake_pollthread(poll_ev); +} + +static bool poll_event_sync_arrays(struct tevent_context *ev, + struct poll_event_context *poll_ev) +{ + size_t i; + size_t array_length; + + if (poll_ev->deleted) { + + for (i=0; i < poll_ev->num_fds;) { + struct tevent_fd *fde = poll_ev->fdes[i]; + size_t ci; + + if (fde != NULL) { + i++; + continue; + } + + /* + * This fde was talloc_free()'ed. Delete it + * from the arrays + */ + poll_ev->num_fds -= 1; + ci = poll_ev->num_fds; + if (ci > i) { + poll_ev->fds[i] = poll_ev->fds[ci]; + poll_ev->fdes[i] = poll_ev->fdes[ci]; + if (poll_ev->fdes[i] != NULL) { + poll_ev->fdes[i]->additional_flags = i; + } + } + poll_ev->fds[ci] = (struct pollfd) { .fd = -1 }; + poll_ev->fdes[ci] = NULL; + } + poll_ev->deleted = false; + } + + if (poll_ev->num_fds == poll_ev->num_fdes) { + return true; + } + + /* + * Recheck the size of both arrays and make sure + * poll_fd->fds array has at least the size of the + * in use poll_ev->fdes array. + */ + if (poll_ev->num_fdes > talloc_array_length(poll_ev->fds)) { + struct pollfd *tmp_fds = NULL; + + /* + * Make sure both allocated the same length. + */ + array_length = talloc_array_length(poll_ev->fdes); + + tmp_fds = talloc_realloc(poll_ev, + poll_ev->fds, + struct pollfd, + array_length); + if (tmp_fds == NULL) { + return false; + } + poll_ev->fds = tmp_fds; + } + + /* + * Now setup the new elements. + */ + for (i = poll_ev->num_fds; i < poll_ev->num_fdes; i++) { + struct tevent_fd *fde = poll_ev->fdes[i]; + struct pollfd *pfd = &poll_ev->fds[poll_ev->num_fds]; + + if (fde == NULL) { + continue; + } + + if (i > poll_ev->num_fds) { + poll_ev->fdes[poll_ev->num_fds] = fde; + fde->additional_flags = poll_ev->num_fds; + poll_ev->fdes[i] = NULL; + } + + pfd->fd = fde->fd; + pfd->events = 0; + pfd->revents = 0; + + if (fde->flags & TEVENT_FD_READ) { + pfd->events |= (POLLIN|POLLHUP); + } + if (fde->flags & TEVENT_FD_WRITE) { + pfd->events |= (POLLOUT); + } + + poll_ev->num_fds += 1; + } + /* Both are in sync again */ + poll_ev->num_fdes = poll_ev->num_fds; + + /* + * Check if we should shrink the arrays + * But keep at least 16 elements. + */ + + array_length = (poll_ev->num_fds + 15) & ~15; /* round up to 16 */ + array_length = MAX(array_length, 16); + if (array_length < talloc_array_length(poll_ev->fdes)) { + struct tevent_fd **tmp_fdes = NULL; + struct pollfd *tmp_fds = NULL; + + tmp_fdes = talloc_realloc(poll_ev, + poll_ev->fdes, + struct tevent_fd *, + array_length); + if (tmp_fdes == NULL) { + return false; + } + poll_ev->fdes = tmp_fdes; + + tmp_fds = talloc_realloc(poll_ev, + poll_ev->fds, + struct pollfd, + array_length); + if (tmp_fds == NULL) { + return false; + } + poll_ev->fds = tmp_fds; + } + + return true; +} + +/* + event loop handling using poll() +*/ +static int poll_event_loop_poll(struct tevent_context *ev, + struct timeval *tvalp) +{ + struct poll_event_context *poll_ev = talloc_get_type_abort( + ev->additional_data, struct poll_event_context); + int pollrtn; + int timeout = -1; + int poll_errno; + struct tevent_fd *fde = NULL; + struct tevent_fd *next = NULL; + unsigned i; + bool ok; + + if (ev->signal_events && tevent_common_check_signal(ev)) { + return 0; + } + + if (tvalp != NULL) { + timeout = tvalp->tv_sec * 1000; + timeout += (tvalp->tv_usec + 999) / 1000; + } + + ok = poll_event_sync_arrays(ev, poll_ev); + if (!ok) { + return -1; + } + + tevent_trace_point_callback(poll_ev->ev, TEVENT_TRACE_BEFORE_WAIT); + pollrtn = poll(poll_ev->fds, poll_ev->num_fds, timeout); + poll_errno = errno; + tevent_trace_point_callback(poll_ev->ev, TEVENT_TRACE_AFTER_WAIT); + + if (pollrtn == -1 && poll_errno == EINTR && ev->signal_events) { + tevent_common_check_signal(ev); + return 0; + } + + if (pollrtn == 0 && tvalp) { + /* we don't care about a possible delay here */ + tevent_common_loop_timer_delay(ev); + return 0; + } + + if (pollrtn <= 0) { + /* + * No fd's ready + */ + return 0; + } + + /* at least one file descriptor is ready - check + which ones and call the handler, being careful to allow + the handler to remove itself when called */ + + for (fde = ev->fd_events; fde; fde = next) { + uint64_t idx = fde->additional_flags; + struct pollfd *pfd; + uint16_t flags = 0; + + next = fde->next; + + if (idx == UINT64_MAX) { + continue; + } + + pfd = &poll_ev->fds[idx]; + + if (pfd->revents & POLLNVAL) { + /* + * the socket is dead! this should never + * happen as the socket should have first been + * made readable and that should have removed + * the event, so this must be a bug. + * + * We ignore it here to match the epoll + * behavior. + */ + tevent_debug(ev, TEVENT_DEBUG_ERROR, + "POLLNVAL on fde[%p] fd[%d] - disabling\n", + fde, pfd->fd); + poll_ev->fdes[idx] = NULL; + poll_ev->deleted = true; + DLIST_REMOVE(ev->fd_events, fde); + fde->wrapper = NULL; + fde->event_ctx = NULL; + continue; + } + + if (pfd->revents & (POLLHUP|POLLERR)) { + /* If we only wait for TEVENT_FD_WRITE, we + should not tell the event handler about it, + and remove the writable flag, as we only + report errors when waiting for read events + to match the select behavior. */ + if (!(fde->flags & TEVENT_FD_READ)) { + TEVENT_FD_NOT_WRITEABLE(fde); + continue; + } + flags |= TEVENT_FD_READ; + } + if (pfd->revents & POLLIN) { + flags |= TEVENT_FD_READ; + } + if (pfd->revents & POLLOUT) { + flags |= TEVENT_FD_WRITE; + } + /* + * Note that fde->flags could be changed when using + * the poll_mt backend together with threads, + * that why we need to check pfd->revents and fde->flags + */ + flags &= fde->flags; + if (flags != 0) { + DLIST_DEMOTE(ev->fd_events, fde); + return tevent_common_invoke_fd_handler(fde, flags, NULL); + } + } + + for (i = 0; i < poll_ev->num_fds; i++) { + if (poll_ev->fds[i].revents & POLLNVAL) { + /* + * the socket is dead! this should never + * happen as the socket should have first been + * made readable and that should have removed + * the event, so this must be a bug or + * a race in the poll_mt usage. + */ + fde = poll_ev->fdes[i]; + tevent_debug(ev, TEVENT_DEBUG_WARNING, + "POLLNVAL on dangling fd[%d] fde[%p] - disabling\n", + poll_ev->fds[i].fd, fde); + poll_ev->fdes[i] = NULL; + poll_ev->deleted = true; + if (fde != NULL) { + DLIST_REMOVE(ev->fd_events, fde); + fde->wrapper = NULL; + fde->event_ctx = NULL; + } + } + } + + return 0; +} + +/* + do a single event loop using the events defined in ev +*/ +static int poll_event_loop_once(struct tevent_context *ev, + const char *location) +{ + struct timeval tval; + + if (ev->signal_events && + tevent_common_check_signal(ev)) { + return 0; + } + + if (ev->threaded_contexts != NULL) { + tevent_common_threaded_activate_immediate(ev); + } + + if (ev->immediate_events && + tevent_common_loop_immediate(ev)) { + return 0; + } + + tval = tevent_common_loop_timer_delay(ev); + if (tevent_timeval_is_zero(&tval)) { + return 0; + } + + return poll_event_loop_poll(ev, &tval); +} + +static const struct tevent_ops poll_event_ops = { + .context_init = poll_event_context_init, + .add_fd = poll_event_add_fd, + .set_fd_close_fn = tevent_common_fd_set_close_fn, + .get_fd_flags = tevent_common_fd_get_flags, + .set_fd_flags = poll_event_set_fd_flags, + .add_timer = tevent_common_add_timer_v2, + .schedule_immediate = tevent_common_schedule_immediate, + .add_signal = tevent_common_add_signal, + .loop_once = poll_event_loop_once, + .loop_wait = tevent_common_loop_wait, +}; + +_PRIVATE_ bool tevent_poll_init(void) +{ + return tevent_register_backend("poll", &poll_event_ops); +} + +static const struct tevent_ops poll_event_mt_ops = { + .context_init = poll_event_context_init_mt, + .add_fd = poll_event_add_fd, + .set_fd_close_fn = tevent_common_fd_set_close_fn, + .get_fd_flags = tevent_common_fd_get_flags, + .set_fd_flags = poll_event_set_fd_flags, + .add_timer = tevent_common_add_timer_v2, + .schedule_immediate = poll_event_schedule_immediate, + .add_signal = tevent_common_add_signal, + .loop_once = poll_event_loop_once, + .loop_wait = tevent_common_loop_wait, +}; + +_PRIVATE_ bool tevent_poll_mt_init(void) +{ + return tevent_register_backend("poll_mt", &poll_event_mt_ops); +} diff --git a/ldb-2.0.8/lib/tevent/tevent_port.c b/ldb-2.0.8/lib/tevent/tevent_port.c new file mode 100644 index 0000000..e91d442 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent_port.c @@ -0,0 +1,803 @@ +/* + Unix SMB/CIFS implementation. + + Main select loop and event handling - Solaris port implementation. + Losely based on the Linux epoll backend. + + Copyright (C) Jeremy Allison 2013 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#include "system/filesys.h" +#include "system/select.h" +#include "tevent.h" +#include "tevent_internal.h" +#include "tevent_util.h" + +struct port_associate_vals { + struct port_associate_vals *prev, *next; + struct port_event_context *port_ev; + int events; + struct tevent_fd *fde; + bool associated_event; +}; + +struct port_event_context { + /* a pointer back to the generic event_context */ + struct tevent_context *ev; + + /* This is the handle from port_create */ + int port_fd; + + pid_t pid; + + /* List of associations. */ + struct port_associate_vals *po_vals; +}; + +#define PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION (1<<0) +#define PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1) +#define PORT_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2) +#define PORT_ADDITIONAL_FD_FLAG_HAS_MPX (1<<3) + +/* + Map from TEVENT_FD_* to POLLIN/POLLOUT +*/ +static int port_map_flags(uint16_t flags) +{ + int ret = 0; + if (flags & TEVENT_FD_READ) ret |= (POLLIN | POLLERR | POLLHUP); + if (flags & TEVENT_FD_WRITE) ret |= (POLLOUT | POLLERR | POLLHUP); + return ret; +} + +/* + Free the port fd +*/ +static int port_ctx_destructor(struct port_event_context *port_ev) +{ + close(port_ev->port_fd); + port_ev->port_fd = -1; + return 0; +} + +/* + Init the port fd +*/ +static int port_init_ctx(struct port_event_context *port_ev) +{ + port_ev->port_fd = port_create(); + if (port_ev->port_fd == -1) { + tevent_debug(port_ev->ev, TEVENT_DEBUG_FATAL, + "Failed to create port handle.\n"); + return -1; + } + + if (!ev_set_close_on_exec(port_ev->port_fd)) { + tevent_debug(port_ev->ev, TEVENT_DEBUG_WARNING, + "Failed to set close-on-exec, file descriptor may be leaked to children.\n"); + } + + port_ev->pid = getpid(); + talloc_set_destructor(port_ev, port_ctx_destructor); + + return 0; +} + +/* + Functions to manage the lower level cache of associated events on the port_fd. +*/ + +static int port_associate_vals_destructor(struct port_associate_vals *val) +{ + DLIST_REMOVE(val->port_ev->po_vals, val); + memset(val, '\0', sizeof(struct port_associate_vals)); + return 0; +} + +/* + * TODO: As the port_association is per-fde, it should be possible to store it + * directly in fde->additional_data, alongside any multiplexed-fde. That way the + * lookup on store and delete would be avoided, and associate_all_events() could + * walk the ev->fd_events list. + */ +static bool store_port_association(struct port_event_context *port_ev, + struct tevent_fd *fde, + int events) +{ + struct port_associate_vals *val; + + for (val = port_ev->po_vals; val; val = val->next) { + if (val->fde->fd == fde->fd) { + /* Association already attached to fd. */ + if (val->events != events) { + val->events = events; + val->associated_event = false; + } + return true; + } + } + + val = talloc_zero(port_ev, struct port_associate_vals); + if (val == NULL) { + return false; + } + + val->port_ev = port_ev; + val->fde = fde; + val->events = events; + val->associated_event = false; + + DLIST_ADD(port_ev->po_vals, val); + talloc_set_destructor(val, port_associate_vals_destructor); + + return true; +} + +static void delete_port_association(struct port_event_context *port_ev, + struct tevent_fd *fde) +{ + struct port_associate_vals *val; + + for (val = port_ev->po_vals; val; val = val->next) { + if (val->fde == fde) { + if (val->associated_event) { + (void)port_dissociate(port_ev->port_fd, + PORT_SOURCE_FD, + fde->fd); + } + talloc_free(val); + return; + } + } +} + +static int associate_all_events(struct port_event_context *port_ev) +{ + struct port_associate_vals *val; + + for (val = port_ev->po_vals; val; val = val->next) { + int ret; + if (val->associated_event) { + continue; + } + ret = port_associate(port_ev->port_fd, + PORT_SOURCE_FD, + (uintptr_t)val->fde->fd, + val->events, + (void *)val); + if (ret != 0) { + return -1; + } + val->associated_event = true; + } + return 0; +} + +static int port_update_event(struct port_event_context *port_ev, struct tevent_fd *fde); + +/* + Reopen the port handle when our pid changes. + */ +static int port_check_reopen(struct port_event_context *port_ev) +{ + struct tevent_fd *fde; + + if (port_ev->pid == getpid()) { + return 0; + } + + close(port_ev->port_fd); + port_ev->port_fd = port_create(); + if (port_ev->port_fd == -1) { + tevent_debug(port_ev->ev, TEVENT_DEBUG_FATAL, + "port_create() failed"); + return -1; + } + + if (!ev_set_close_on_exec(port_ev->port_fd)) { + tevent_debug(port_ev->ev, TEVENT_DEBUG_WARNING, + "Failed to set close-on-exec, file descriptor may be leaked to children.\n"); + } + + port_ev->pid = getpid(); + for (fde=port_ev->ev->fd_events;fde;fde=fde->next) { + fde->additional_flags &= PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; + if (port_update_event(port_ev, fde) != 0) { + return -1; + } + } + return 0; +} + +/* + * Solaris ports cannot add the same file descriptor twice, once + * with read, once with write which is allowed by the tevent backend. + * Multiplex the existing fde, flag it as such so we can search for the + * correct fde on event triggering. + */ + +static void port_setup_multiplex_fd(struct port_event_context *port_ev, + struct tevent_fd *add_fde, + struct tevent_fd *mpx_fde) +{ + /* + * Make each fde->additional_data pointers point at each other + * so we can look them up from each other. They are now paired. + */ + mpx_fde->additional_data = add_fde; + add_fde->additional_data = mpx_fde; + + /* Now flag both fde's as being multiplexed. */ + mpx_fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_HAS_MPX; + add_fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_HAS_MPX; + + /* We need to keep the GOT_ERROR flag. */ + if (mpx_fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_GOT_ERROR) { + add_fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_GOT_ERROR; + } +} + +/* + Add the port event to the given fd_event, + Or modify an existing event. +*/ + +static int port_add_event(struct port_event_context *port_ev, struct tevent_fd *fde) +{ + int flags = port_map_flags(fde->flags); + struct tevent_fd *mpx_fde = NULL; + + fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; + fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; + + if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { + /* + * This is already a multiplexed fde, we need to include both + * flags in the modified event. + */ + mpx_fde = talloc_get_type_abort(fde->additional_data, + struct tevent_fd); + + mpx_fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; + mpx_fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; + + flags |= port_map_flags(mpx_fde->flags); + } else { + /* + * Not (yet) a multiplexed event. See if there + * is already an event with the same fd. + */ + for (mpx_fde = port_ev->ev->fd_events; mpx_fde; mpx_fde = mpx_fde->next) { + if (mpx_fde->fd != fde->fd) { + continue; + } + if (mpx_fde == fde) { + continue; + } + /* Same fd. */ + break; + } + if (mpx_fde) { + if (mpx_fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { + /* Logic error. Can't have more then 2 multiplexed fde's. */ + tevent_debug(port_ev->ev, TEVENT_DEBUG_FATAL, + "multiplex fde for fd[%d] is already multiplexed\n", + mpx_fde->fd); + return -1; + } + flags |= port_map_flags(mpx_fde->flags); + } + } + + if (!store_port_association(port_ev, + fde, + flags)) { + tevent_debug(port_ev->ev, TEVENT_DEBUG_FATAL, + "store_port_association failed for fd[%d]\n", + fde->fd); + return -1; + } + + /* Note we have an association now. */ + fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; + /* Only if we want to read do we tell the event handler about errors. */ + if (fde->flags & TEVENT_FD_READ) { + fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; + } + if (mpx_fde == NULL) { + return 0; + } + /* Set up the multiplex pointer. Does no harm if already multiplexed. */ + port_setup_multiplex_fd(port_ev, + fde, + mpx_fde); + + mpx_fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; + /* Only if we want to read do we tell the event handler about errors. */ + if (mpx_fde->flags & TEVENT_FD_READ) { + mpx_fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; + } + + return 0; +} + +/* + Delete the port association for the given fd_event. +*/ + +static void port_del_event(struct port_event_context *port_ev, struct tevent_fd *fde) +{ + struct tevent_fd *mpx_fde = NULL; + + fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; + fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; + + if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { + /* + * This is a multiplexed fde, we need to remove + * both associations. + */ + mpx_fde = talloc_get_type_abort(fde->additional_data, + struct tevent_fd); + + mpx_fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; + mpx_fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; + mpx_fde->additional_data = NULL; + + fde->additional_data = NULL; + } + delete_port_association(port_ev, fde); +} + +/* + Add or remove the port event from the given fd_event +*/ +static int port_update_event(struct port_event_context *port_ev, struct tevent_fd *fde) +{ + bool got_error = (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_GOT_ERROR); + bool want_read = (fde->flags & TEVENT_FD_READ); + bool want_write = (fde->flags & TEVENT_FD_WRITE); + struct tevent_fd *mpx_fde = NULL; + + if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { + /* + * work out what the multiplexed fde wants. + */ + mpx_fde = talloc_get_type_abort(fde->additional_data, + struct tevent_fd); + if (mpx_fde->flags & TEVENT_FD_READ) { + want_read = true; + } + if (mpx_fde->flags & TEVENT_FD_WRITE) { + want_write = true; + } + } + + if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION) { + /* There's already an association. */ + if (want_read || (want_write && !got_error)) { + return port_add_event(port_ev, fde); + } + /* + * If we want to match the select behavior, we need to remove the port event + * when the caller isn't interested in events. + */ + port_del_event(port_ev, fde); + return 0; + } + + /* There's no port event attached to the fde. */ + if (want_read || (want_write && !got_error)) { + return port_add_event(port_ev, fde); + } + return 0; +} + +/* + Cope with port_get returning EPOLLHP|EPOLLERR on an association. + Return true if there's nothing else to do, false if this event + needs further handling. +*/ + +static bool port_handle_hup_or_err(struct port_event_context *port_ev, + struct tevent_fd *fde) +{ + if (fde == NULL) { + return true; + } + + fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_GOT_ERROR; + /* + * If we only wait for TEVENT_FD_WRITE, we should not tell the + * event handler about it, and remove the port association, + * as we only report error when waiting for read events, + * to match the select() behavior. + */ + if (!(fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR)) { + /* + * Do the same as the poll backend and + * remove the writable flag. + */ + fde->flags &= ~TEVENT_FD_WRITE; + return true; + } + /* This has TEVENT_FD_READ set, we're not finished. */ + return false; +} + +/* + Event loop handling using Solaris ports. +*/ +static int port_event_loop(struct port_event_context *port_ev, struct timeval *tvalp) +{ + int ret; +#define MAXEVENTS 1 + port_event_t events[MAXEVENTS]; + uint_t nget = 1; + uint_t max_events = MAXEVENTS; + uint_t i; + int port_errno; + struct timespec ts; + struct tevent_context *ev = port_ev->ev; + + if (tvalp) { + ts.tv_sec = tvalp->tv_sec; + ts.tv_nsec = tvalp->tv_usec * 1000; + } + + if (port_ev->ev->signal_events && + tevent_common_check_signal(ev)) { + return 0; + } + + /* + * Solaris triggers sending the event to the port + * at the time the port association is done. Postpone + * associating fd's until just before we get the events, + * otherwise we can deadlock. + */ + + if (associate_all_events(port_ev) != 0) { + return -1; + } + + tevent_trace_point_callback(ev, TEVENT_TRACE_BEFORE_WAIT); + ret = port_getn(port_ev->port_fd, events, max_events, &nget, &ts); + port_errno = errno; + tevent_trace_point_callback(ev, TEVENT_TRACE_AFTER_WAIT); + + if (ret == -1 && port_errno == EINTR) { + if (ev->signal_events) { + tevent_common_check_signal(ev); + } + /* + * If no signal handlers we got an unsolicited + * signal wakeup. This can happen with epoll + * too. Just return and ignore. + */ + return 0; + } + + if (ret == -1 && port_errno == ETIME) { + /* + * If errno is set to ETIME it is possible that we still got an event. + * In that case we need to go through the processing loop so that we + * reassociate the received event with the port or the association will + * be lost so check the value of nget is 0 before returning. + */ + if (nget == 0) { + /* we don't care about a possible delay here */ + tevent_common_loop_timer_delay(ev); + return 0; + } + /* + * Set the return value to 0 since we do not actually have an error and we + * do have events that need to be processed. This keeps us from getting + * caught in the generic error test. + */ + ret = 0; + } + + if (ret == -1) { + tevent_debug(ev, TEVENT_DEBUG_ERROR, + "port_get failed (%s)\n", + strerror(errno)); + return -1; + } + + for (i = 0; i < nget; i++) { + struct tevent_fd *mpx_fde = NULL; + struct tevent_fd *fde = NULL; + uint16_t flags = 0; + struct port_associate_vals *val = talloc_get_type(events[i].portev_user, + struct port_associate_vals); + if (val == NULL) { + tevent_debug(ev, TEVENT_DEBUG_ERROR, + "port_getn() gave bad data"); + return -1; + } + + /* Mark this event as needing to be re-associated. */ + val->associated_event = false; + + fde = val->fde; + + if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { + /* + * Save off the multiplexed event in case we need + * to use it to call the handler function. + */ + mpx_fde = talloc_get_type_abort(fde->additional_data, + struct tevent_fd); + } + + if (events[i].portev_events & (POLLHUP|POLLERR)) { + bool handled_fde = port_handle_hup_or_err(port_ev, fde); + bool handled_mpx = port_handle_hup_or_err(port_ev, mpx_fde); + + if (handled_fde && handled_mpx) { + return port_update_event(port_ev, fde); + } + + if (!handled_mpx) { + /* + * If the mpx event was the one that needs + * further handling, it's the TEVENT_FD_READ + * event so switch over and call that handler. + */ + fde = mpx_fde; + mpx_fde = NULL; + } + flags |= TEVENT_FD_READ; + } + + if (events[i].portev_events & POLLIN) { + flags |= TEVENT_FD_READ; + } + if (events[i].portev_events & POLLOUT) { + flags |= TEVENT_FD_WRITE; + } + + if (flags & TEVENT_FD_WRITE) { + if (fde->flags & TEVENT_FD_WRITE) { + mpx_fde = NULL; + } + if (mpx_fde && (mpx_fde->flags & TEVENT_FD_WRITE)) { + fde = mpx_fde; + mpx_fde = NULL; + } + + if (mpx_fde) { + /* Ensure we got the right fde. */ + if ((flags & fde->flags) == 0) { + fde = mpx_fde; + mpx_fde = NULL; + } + } + } + + /* + * Make sure we only pass the flags + * the handler is expecting. + */ + flags &= fde->flags; + if (flags) { + return tevent_common_invoke_fd_handler(fde, flags, NULL); + } + } + + return 0; +} + + +/* + create a port_event_context structure. +*/ +static int port_event_context_init(struct tevent_context *ev) +{ + int ret; + struct port_event_context *port_ev; + + /* + * We might be called during tevent_re_initialise() + * which means we need to free our old additional_data. + */ + TALLOC_FREE(ev->additional_data); + + port_ev = talloc_zero(ev, struct port_event_context); + if (!port_ev) { + return -1; + } + port_ev->ev = ev; + port_ev->port_fd = -1; + port_ev->pid = (pid_t)-1; + + ret = port_init_ctx(port_ev); + if (ret != 0) { + talloc_free(port_ev); + return ret; + } + + ev->additional_data = port_ev; + return 0; +} + +/* + destroy an fd_event +*/ +static int port_event_fd_destructor(struct tevent_fd *fde) +{ + struct tevent_context *ev = fde->event_ctx; + struct port_event_context *port_ev = NULL; + struct tevent_fd *mpx_fde = NULL; + int flags = (int)fde->flags; + + if (ev == NULL) { + return tevent_common_fd_destructor(fde); + } + + port_ev = talloc_get_type_abort(ev->additional_data, + struct port_event_context); + + DLIST_REMOVE(ev->fd_events, fde); + + if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { + mpx_fde = talloc_get_type_abort(fde->additional_data, + struct tevent_fd); + + fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_MPX; + mpx_fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_MPX; + + fde->additional_data = NULL; + mpx_fde->additional_data = NULL; + + fde->additional_flags &= PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; + } + + (void)port_check_reopen(port_ev); + + if (mpx_fde != NULL) { + (void)port_update_event(port_ev, mpx_fde); + } + + fde->flags = 0; + (void)port_update_event(port_ev, fde); + fde->flags = flags; + + return tevent_common_fd_destructor(fde); +} + +/* + add a fd based event + return NULL on failure (memory allocation error) +*/ +static struct tevent_fd *port_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx, + int fd, uint16_t flags, + tevent_fd_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + struct port_event_context *port_ev = + talloc_get_type_abort(ev->additional_data, + struct port_event_context); + struct tevent_fd *fde; + + fde = tevent_common_add_fd(ev, mem_ctx, fd, flags, + handler, private_data, + handler_name, location); + if (!fde) { + return NULL; + } + + talloc_set_destructor(fde, port_event_fd_destructor); + + if (port_check_reopen(port_ev) != 0) { + TALLOC_FREE(fde); + return NULL; + } + + if (port_update_event(port_ev, fde) != 0) { + TALLOC_FREE(fde); + return NULL; + } + + return fde; +} + +/* + set the fd event flags +*/ +static void port_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags) +{ + struct tevent_context *ev; + struct port_event_context *port_ev; + + if (fde->flags == flags) { + return; + } + + ev = fde->event_ctx; + port_ev = talloc_get_type_abort(ev->additional_data, + struct port_event_context); + + fde->flags = flags; + + (void)port_check_reopen(port_ev); + (void)port_update_event(port_ev, fde); +} + +/* + do a single event loop using the events defined in ev +*/ +static int port_event_loop_once(struct tevent_context *ev, const char *location) +{ + struct port_event_context *port_ev = talloc_get_type(ev->additional_data, + struct port_event_context); + struct timeval tval; + + if (ev->signal_events && + tevent_common_check_signal(ev)) { + return 0; + } + + if (ev->threaded_contexts != NULL) { + tevent_common_threaded_activate_immediate(ev); + } + + if (ev->immediate_events && + tevent_common_loop_immediate(ev)) { + return 0; + } + + tval = tevent_common_loop_timer_delay(ev); + if (tevent_timeval_is_zero(&tval)) { + return 0; + } + + if (port_check_reopen(port_ev) != 0) { + errno = EINVAL; + return -1; + } + return port_event_loop(port_ev, &tval); +} + +static const struct tevent_ops port_event_ops = { + .context_init = port_event_context_init, + .add_fd = port_event_add_fd, + .set_fd_close_fn = tevent_common_fd_set_close_fn, + .get_fd_flags = tevent_common_fd_get_flags, + .set_fd_flags = port_event_set_fd_flags, + .add_timer = tevent_common_add_timer_v2, + .schedule_immediate = tevent_common_schedule_immediate, + .add_signal = tevent_common_add_signal, + .loop_once = port_event_loop_once, + .loop_wait = tevent_common_loop_wait, +}; + +_PRIVATE_ bool tevent_port_init(void) +{ + if (!tevent_register_backend("port", &port_event_ops)) { + return false; + } + tevent_set_default_backend("port"); + return true; +} diff --git a/ldb-2.0.8/lib/tevent/tevent_queue.c b/ldb-2.0.8/lib/tevent/tevent_queue.c new file mode 100644 index 0000000..9c3973b --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent_queue.c @@ -0,0 +1,370 @@ +/* + Unix SMB/CIFS implementation. + Infrastructure for async requests + Copyright (C) Volker Lendecke 2008 + Copyright (C) Stefan Metzmacher 2009 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#include "tevent.h" +#include "tevent_internal.h" +#include "tevent_util.h" + +struct tevent_queue_entry { + struct tevent_queue_entry *prev, *next; + struct tevent_queue *queue; + + bool triggered; + + struct tevent_req *req; + struct tevent_context *ev; + + tevent_queue_trigger_fn_t trigger; + void *private_data; +}; + +struct tevent_queue { + const char *name; + const char *location; + + bool running; + struct tevent_immediate *immediate; + + size_t length; + struct tevent_queue_entry *list; +}; + +static void tevent_queue_immediate_trigger(struct tevent_context *ev, + struct tevent_immediate *im, + void *private_data); + +static int tevent_queue_entry_destructor(struct tevent_queue_entry *e) +{ + struct tevent_queue *q = e->queue; + + if (!q) { + return 0; + } + + DLIST_REMOVE(q->list, e); + q->length--; + + if (!q->running) { + return 0; + } + + if (!q->list) { + return 0; + } + + if (q->list->triggered) { + return 0; + } + + tevent_schedule_immediate(q->immediate, + q->list->ev, + tevent_queue_immediate_trigger, + q); + + return 0; +} + +static int tevent_queue_destructor(struct tevent_queue *q) +{ + q->running = false; + + while (q->list) { + struct tevent_queue_entry *e = q->list; + talloc_free(e); + } + + return 0; +} + +struct tevent_queue *_tevent_queue_create(TALLOC_CTX *mem_ctx, + const char *name, + const char *location) +{ + struct tevent_queue *queue; + + queue = talloc_zero(mem_ctx, struct tevent_queue); + if (!queue) { + return NULL; + } + + queue->name = talloc_strdup(queue, name); + if (!queue->name) { + talloc_free(queue); + return NULL; + } + queue->immediate = tevent_create_immediate(queue); + if (!queue->immediate) { + talloc_free(queue); + return NULL; + } + + queue->location = location; + + /* queue is running by default */ + queue->running = true; + + talloc_set_destructor(queue, tevent_queue_destructor); + return queue; +} + +static void tevent_queue_immediate_trigger(struct tevent_context *ev, + struct tevent_immediate *im, + void *private_data) +{ + struct tevent_queue *q = + talloc_get_type_abort(private_data, + struct tevent_queue); + + if (!q->running) { + return; + } + + if (!q->list) { + return; + } + + q->list->triggered = true; + q->list->trigger(q->list->req, q->list->private_data); +} + +static struct tevent_queue_entry *tevent_queue_add_internal( + struct tevent_queue *queue, + struct tevent_context *ev, + struct tevent_req *req, + tevent_queue_trigger_fn_t trigger, + void *private_data, + bool allow_direct) +{ + struct tevent_queue_entry *e; + + e = talloc_zero(req, struct tevent_queue_entry); + if (e == NULL) { + return NULL; + } + + e->queue = queue; + e->req = req; + e->ev = ev; + e->trigger = trigger; + e->private_data = private_data; + + /* + * if there is no trigger, it is just a blocker + */ + if (trigger == NULL) { + e->triggered = true; + } + + if (queue->length > 0) { + /* + * if there are already entries in the + * queue do not optimize. + */ + allow_direct = false; + } + + if (req->async.fn != NULL) { + /* + * If the caller wants to optimize for the + * empty queue case, call the trigger only + * if there is no callback defined for the + * request yet. + */ + allow_direct = false; + } + + DLIST_ADD_END(queue->list, e); + queue->length++; + talloc_set_destructor(e, tevent_queue_entry_destructor); + + if (!queue->running) { + return e; + } + + if (queue->list->triggered) { + return e; + } + + /* + * If allowed we directly call the trigger + * avoiding possible delays caused by + * an immediate event. + */ + if (allow_direct) { + queue->list->triggered = true; + queue->list->trigger(queue->list->req, + queue->list->private_data); + return e; + } + + tevent_schedule_immediate(queue->immediate, + queue->list->ev, + tevent_queue_immediate_trigger, + queue); + + return e; +} + +bool tevent_queue_add(struct tevent_queue *queue, + struct tevent_context *ev, + struct tevent_req *req, + tevent_queue_trigger_fn_t trigger, + void *private_data) +{ + struct tevent_queue_entry *e; + + e = tevent_queue_add_internal(queue, ev, req, + trigger, private_data, false); + if (e == NULL) { + return false; + } + + return true; +} + +struct tevent_queue_entry *tevent_queue_add_entry( + struct tevent_queue *queue, + struct tevent_context *ev, + struct tevent_req *req, + tevent_queue_trigger_fn_t trigger, + void *private_data) +{ + return tevent_queue_add_internal(queue, ev, req, + trigger, private_data, false); +} + +struct tevent_queue_entry *tevent_queue_add_optimize_empty( + struct tevent_queue *queue, + struct tevent_context *ev, + struct tevent_req *req, + tevent_queue_trigger_fn_t trigger, + void *private_data) +{ + return tevent_queue_add_internal(queue, ev, req, + trigger, private_data, true); +} + +void tevent_queue_entry_untrigger(struct tevent_queue_entry *entry) +{ + if (entry->queue->running) { + abort(); + } + + if (entry->queue->list != entry) { + abort(); + } + + entry->triggered = false; +} + +void tevent_queue_start(struct tevent_queue *queue) +{ + if (queue->running) { + /* already started */ + return; + } + + queue->running = true; + + if (!queue->list) { + return; + } + + if (queue->list->triggered) { + return; + } + + tevent_schedule_immediate(queue->immediate, + queue->list->ev, + tevent_queue_immediate_trigger, + queue); +} + +void tevent_queue_stop(struct tevent_queue *queue) +{ + queue->running = false; +} + +size_t tevent_queue_length(struct tevent_queue *queue) +{ + return queue->length; +} + +bool tevent_queue_running(struct tevent_queue *queue) +{ + return queue->running; +} + +struct tevent_queue_wait_state { + uint8_t dummy; +}; + +static void tevent_queue_wait_trigger(struct tevent_req *req, + void *private_data); + +struct tevent_req *tevent_queue_wait_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tevent_queue *queue) +{ + struct tevent_req *req; + struct tevent_queue_wait_state *state; + bool ok; + + req = tevent_req_create(mem_ctx, &state, + struct tevent_queue_wait_state); + if (req == NULL) { + return NULL; + } + + ok = tevent_queue_add(queue, ev, req, + tevent_queue_wait_trigger, + NULL); + if (!ok) { + tevent_req_oom(req); + return tevent_req_post(req, ev); + } + + return req; +} + +static void tevent_queue_wait_trigger(struct tevent_req *req, + void *private_data) +{ + tevent_req_done(req); +} + +bool tevent_queue_wait_recv(struct tevent_req *req) +{ + enum tevent_req_state state; + uint64_t err; + + if (tevent_req_is_error(req, &state, &err)) { + tevent_req_received(req); + return false; + } + + tevent_req_received(req); + return true; +} diff --git a/ldb-2.0.8/lib/tevent/tevent_req.c b/ldb-2.0.8/lib/tevent/tevent_req.c new file mode 100644 index 0000000..7821d9a --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent_req.c @@ -0,0 +1,570 @@ +/* + Unix SMB/CIFS implementation. + Infrastructure for async requests + Copyright (C) Volker Lendecke 2008 + Copyright (C) Stefan Metzmacher 2009 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#include "tevent.h" +#include "tevent_internal.h" +#include "tevent_util.h" + +char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx) +{ + return talloc_asprintf(mem_ctx, + "tevent_req[%p/%s]: state[%d] error[%lld (0x%llX)] " + " state[%s (%p)] timer[%p] finish[%s]", + req, req->internal.create_location, + req->internal.state, + (unsigned long long)req->internal.error, + (unsigned long long)req->internal.error, + req->internal.private_type, + req->data, + req->internal.timer, + req->internal.finish_location + ); +} + +char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req) +{ + if (req == NULL) { + return talloc_strdup(mem_ctx, "tevent_req[NULL]"); + } + + if (!req->private_print) { + return tevent_req_default_print(req, mem_ctx); + } + + return req->private_print(req, mem_ctx); +} + +static int tevent_req_destructor(struct tevent_req *req); + +struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, + void *pdata, + size_t data_size, + const char *type, + const char *location) +{ + struct tevent_req *req; + struct tevent_req *parent; + void **ppdata = (void **)pdata; + void *data; + size_t payload; + + payload = sizeof(struct tevent_immediate) + data_size; + if (payload < sizeof(struct tevent_immediate)) { + /* overflow */ + return NULL; + } + + req = talloc_pooled_object( + mem_ctx, struct tevent_req, 2, + sizeof(struct tevent_immediate) + data_size); + if (req == NULL) { + return NULL; + } + + *req = (struct tevent_req) { + .internal = { + .private_type = type, + .create_location = location, + .state = TEVENT_REQ_IN_PROGRESS, + .trigger = tevent_create_immediate(req), + }, + }; + + data = talloc_zero_size(req, data_size); + + /* + * No need to check for req->internal.trigger!=NULL or + * data!=NULL, this can't fail: talloc_pooled_object has + * already allocated sufficient memory. + */ + + talloc_set_name_const(data, type); + + req->data = data; + + talloc_set_destructor(req, tevent_req_destructor); + + parent = talloc_get_type(talloc_parent(mem_ctx), struct tevent_req); + if ((parent != NULL) && (parent->internal.profile != NULL)) { + bool ok = tevent_req_set_profile(req); + + if (!ok) { + TALLOC_FREE(req); + return NULL; + } + req->internal.profile->parent = parent->internal.profile; + DLIST_ADD_END(parent->internal.profile->subprofiles, + req->internal.profile); + } + + *ppdata = data; + return req; +} + +static int tevent_req_destructor(struct tevent_req *req) +{ + tevent_req_received(req); + return 0; +} + +void _tevent_req_notify_callback(struct tevent_req *req, const char *location) +{ + req->internal.finish_location = location; + if (req->internal.defer_callback_ev) { + (void)tevent_req_post(req, req->internal.defer_callback_ev); + req->internal.defer_callback_ev = NULL; + return; + } + if (req->async.fn != NULL) { + req->async.fn(req); + } +} + +static void tevent_req_cleanup(struct tevent_req *req) +{ + if (req->private_cleanup.fn == NULL) { + return; + } + + if (req->private_cleanup.state >= req->internal.state) { + /* + * Don't call the cleanup_function multiple times for the same + * state recursively + */ + return; + } + + req->private_cleanup.state = req->internal.state; + req->private_cleanup.fn(req, req->internal.state); +} + +static void tevent_req_finish(struct tevent_req *req, + enum tevent_req_state state, + const char *location) +{ + struct tevent_req_profile *p; + /* + * make sure we do not timeout after + * the request was already finished + */ + TALLOC_FREE(req->internal.timer); + + req->internal.state = state; + req->internal.finish_location = location; + + tevent_req_cleanup(req); + + p = req->internal.profile; + + if (p != NULL) { + p->stop_location = location; + p->stop_time = tevent_timeval_current(); + p->state = state; + p->user_error = req->internal.error; + + if (p->parent != NULL) { + talloc_steal(p->parent, p); + req->internal.profile = NULL; + } + } + + _tevent_req_notify_callback(req, location); +} + +void _tevent_req_done(struct tevent_req *req, + const char *location) +{ + tevent_req_finish(req, TEVENT_REQ_DONE, location); +} + +bool _tevent_req_error(struct tevent_req *req, + uint64_t error, + const char *location) +{ + if (error == 0) { + return false; + } + + req->internal.error = error; + tevent_req_finish(req, TEVENT_REQ_USER_ERROR, location); + return true; +} + +void _tevent_req_oom(struct tevent_req *req, const char *location) +{ + tevent_req_finish(req, TEVENT_REQ_NO_MEMORY, location); +} + +bool _tevent_req_nomem(const void *p, + struct tevent_req *req, + const char *location) +{ + if (p != NULL) { + return false; + } + _tevent_req_oom(req, location); + return true; +} + +/** + * @internal + * + * @brief Immediate event callback. + * + * @param[in] ev The event context to use. + * + * @param[in] im The immediate event. + * + * @param[in] priv The async request to be finished. + */ +static void tevent_req_trigger(struct tevent_context *ev, + struct tevent_immediate *im, + void *private_data) +{ + struct tevent_req *req = + talloc_get_type_abort(private_data, + struct tevent_req); + + tevent_req_finish(req, req->internal.state, + req->internal.finish_location); +} + +struct tevent_req *tevent_req_post(struct tevent_req *req, + struct tevent_context *ev) +{ + tevent_schedule_immediate(req->internal.trigger, + ev, tevent_req_trigger, req); + return req; +} + +void tevent_req_defer_callback(struct tevent_req *req, + struct tevent_context *ev) +{ + req->internal.defer_callback_ev = ev; +} + +bool tevent_req_is_in_progress(struct tevent_req *req) +{ + if (req->internal.state == TEVENT_REQ_IN_PROGRESS) { + return true; + } + + return false; +} + +void tevent_req_received(struct tevent_req *req) +{ + talloc_set_destructor(req, NULL); + + req->private_print = NULL; + req->private_cancel = NULL; + + TALLOC_FREE(req->internal.trigger); + TALLOC_FREE(req->internal.timer); + + req->internal.state = TEVENT_REQ_RECEIVED; + + tevent_req_cleanup(req); + + TALLOC_FREE(req->data); +} + +bool tevent_req_poll(struct tevent_req *req, + struct tevent_context *ev) +{ + while (tevent_req_is_in_progress(req)) { + int ret; + + ret = tevent_loop_once(ev); + if (ret != 0) { + return false; + } + } + + return true; +} + +bool tevent_req_is_error(struct tevent_req *req, enum tevent_req_state *state, + uint64_t *error) +{ + if (req->internal.state == TEVENT_REQ_DONE) { + return false; + } + if (req->internal.state == TEVENT_REQ_USER_ERROR) { + *error = req->internal.error; + } + *state = req->internal.state; + return true; +} + +static void tevent_req_timedout(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval now, + void *private_data) +{ + struct tevent_req *req = + talloc_get_type_abort(private_data, + struct tevent_req); + + TALLOC_FREE(req->internal.timer); + + tevent_req_finish(req, TEVENT_REQ_TIMED_OUT, __FUNCTION__); +} + +bool tevent_req_set_endtime(struct tevent_req *req, + struct tevent_context *ev, + struct timeval endtime) +{ + TALLOC_FREE(req->internal.timer); + + req->internal.timer = tevent_add_timer(ev, req, endtime, + tevent_req_timedout, + req); + if (tevent_req_nomem(req->internal.timer, req)) { + return false; + } + + return true; +} + +void tevent_req_reset_endtime(struct tevent_req *req) +{ + TALLOC_FREE(req->internal.timer); +} + +void tevent_req_set_callback(struct tevent_req *req, tevent_req_fn fn, void *pvt) +{ + req->async.fn = fn; + req->async.private_data = pvt; +} + +void *_tevent_req_callback_data(struct tevent_req *req) +{ + return req->async.private_data; +} + +void *_tevent_req_data(struct tevent_req *req) +{ + return req->data; +} + +void tevent_req_set_print_fn(struct tevent_req *req, tevent_req_print_fn fn) +{ + req->private_print = fn; +} + +void tevent_req_set_cancel_fn(struct tevent_req *req, tevent_req_cancel_fn fn) +{ + req->private_cancel = fn; +} + +bool _tevent_req_cancel(struct tevent_req *req, const char *location) +{ + if (req->private_cancel == NULL) { + return false; + } + + return req->private_cancel(req); +} + +void tevent_req_set_cleanup_fn(struct tevent_req *req, tevent_req_cleanup_fn fn) +{ + req->private_cleanup.state = req->internal.state; + req->private_cleanup.fn = fn; +} + +static int tevent_req_profile_destructor(struct tevent_req_profile *p); + +bool tevent_req_set_profile(struct tevent_req *req) +{ + struct tevent_req_profile *p; + + if (req->internal.profile != NULL) { + tevent_req_error(req, EINVAL); + return false; + } + + p = tevent_req_profile_create(req); + + if (tevent_req_nomem(p, req)) { + return false; + } + + p->req_name = talloc_get_name(req->data); + p->start_location = req->internal.create_location; + p->start_time = tevent_timeval_current(); + + req->internal.profile = p; + + return true; +} + +static int tevent_req_profile_destructor(struct tevent_req_profile *p) +{ + if (p->parent != NULL) { + DLIST_REMOVE(p->parent->subprofiles, p); + p->parent = NULL; + } + + while (p->subprofiles != NULL) { + p->subprofiles->parent = NULL; + DLIST_REMOVE(p->subprofiles, p->subprofiles); + } + + return 0; +} + +struct tevent_req_profile *tevent_req_move_profile(struct tevent_req *req, + TALLOC_CTX *mem_ctx) +{ + return talloc_move(mem_ctx, &req->internal.profile); +} + +const struct tevent_req_profile *tevent_req_get_profile( + struct tevent_req *req) +{ + return req->internal.profile; +} + +void tevent_req_profile_get_name(const struct tevent_req_profile *profile, + const char **req_name) +{ + if (req_name != NULL) { + *req_name = profile->req_name; + } +} + +void tevent_req_profile_get_start(const struct tevent_req_profile *profile, + const char **start_location, + struct timeval *start_time) +{ + if (start_location != NULL) { + *start_location = profile->start_location; + } + if (start_time != NULL) { + *start_time = profile->start_time; + } +} + +void tevent_req_profile_get_stop(const struct tevent_req_profile *profile, + const char **stop_location, + struct timeval *stop_time) +{ + if (stop_location != NULL) { + *stop_location = profile->stop_location; + } + if (stop_time != NULL) { + *stop_time = profile->stop_time; + } +} + +void tevent_req_profile_get_status(const struct tevent_req_profile *profile, + pid_t *pid, + enum tevent_req_state *state, + uint64_t *user_error) +{ + if (pid != NULL) { + *pid = profile->pid; + } + if (state != NULL) { + *state = profile->state; + } + if (user_error != NULL) { + *user_error = profile->user_error; + } +} + +const struct tevent_req_profile *tevent_req_profile_get_subprofiles( + const struct tevent_req_profile *profile) +{ + return profile->subprofiles; +} + +const struct tevent_req_profile *tevent_req_profile_next( + const struct tevent_req_profile *profile) +{ + return profile->next; +} + +struct tevent_req_profile *tevent_req_profile_create(TALLOC_CTX *mem_ctx) +{ + struct tevent_req_profile *result; + + result = talloc_zero(mem_ctx, struct tevent_req_profile); + if (result == NULL) { + return NULL; + } + talloc_set_destructor(result, tevent_req_profile_destructor); + + return result; +} + +bool tevent_req_profile_set_name(struct tevent_req_profile *profile, + const char *req_name) +{ + profile->req_name = talloc_strdup(profile, req_name); + return (profile->req_name != NULL); +} + +bool tevent_req_profile_set_start(struct tevent_req_profile *profile, + const char *start_location, + struct timeval start_time) +{ + profile->start_time = start_time; + + profile->start_location = talloc_strdup(profile, start_location); + return (profile->start_location != NULL); +} + +bool tevent_req_profile_set_stop(struct tevent_req_profile *profile, + const char *stop_location, + struct timeval stop_time) +{ + profile->stop_time = stop_time; + + profile->stop_location = talloc_strdup(profile, stop_location); + return (profile->stop_location != NULL); +} + +void tevent_req_profile_set_status(struct tevent_req_profile *profile, + pid_t pid, + enum tevent_req_state state, + uint64_t user_error) +{ + profile->pid = pid; + profile->state = state; + profile->user_error = user_error; +} + +void tevent_req_profile_append_sub(struct tevent_req_profile *parent_profile, + struct tevent_req_profile **sub_profile) +{ + struct tevent_req_profile *sub; + + sub = talloc_move(parent_profile, sub_profile); + + sub->parent = parent_profile; + DLIST_ADD_END(parent_profile->subprofiles, sub); +} diff --git a/ldb-2.0.8/lib/tevent/tevent_signal.c b/ldb-2.0.8/lib/tevent/tevent_signal.c new file mode 100644 index 0000000..7ebb13d --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent_signal.c @@ -0,0 +1,518 @@ +/* + Unix SMB/CIFS implementation. + + common events code for signal events + + Copyright (C) Andrew Tridgell 2007 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#include "system/filesys.h" +#include "system/wait.h" +#define TEVENT_DEPRECATED 1 +#include "tevent.h" +#include "tevent_internal.h" +#include "tevent_util.h" + +/* maximum number of SA_SIGINFO signals to hold in the queue. + NB. This *MUST* be a power of 2, in order for the ring buffer + wrap to work correctly. Thanks to Petr Vandrovec + for this. */ + +#define TEVENT_SA_INFO_QUEUE_COUNT 256 + +size_t tevent_num_signals(void) +{ + return TEVENT_NUM_SIGNALS; +} + +size_t tevent_sa_info_queue_count(void) +{ + return TEVENT_SA_INFO_QUEUE_COUNT; +} + +struct tevent_sigcounter { + uint32_t count; + uint32_t seen; +}; + +#if defined(HAVE___SYNC_FETCH_AND_ADD) +#define TEVENT_SIG_INCREMENT(s) __sync_fetch_and_add(&((s).count), 1) +#elif defined(HAVE_ATOMIC_ADD_32) +#define TEVENT_SIG_INCREMENT(s) atomic_add_32(&((s).count), 1) +#else +#define TEVENT_SIG_INCREMENT(s) (s).count++ +#endif +#define TEVENT_SIG_SEEN(s, n) (s).seen += (n) +#define TEVENT_SIG_PENDING(s) ((s).seen != (s).count) + +struct tevent_common_signal_list { + struct tevent_common_signal_list *prev, *next; + struct tevent_signal *se; +}; + +/* + the poor design of signals means that this table must be static global +*/ +static struct tevent_sig_state { + struct tevent_common_signal_list *sig_handlers[TEVENT_NUM_SIGNALS+1]; + struct sigaction *oldact[TEVENT_NUM_SIGNALS+1]; + struct tevent_sigcounter signal_count[TEVENT_NUM_SIGNALS+1]; + struct tevent_sigcounter got_signal; +#ifdef SA_SIGINFO + /* with SA_SIGINFO we get quite a lot of info per signal */ + siginfo_t *sig_info[TEVENT_NUM_SIGNALS+1]; + struct tevent_sigcounter sig_blocked[TEVENT_NUM_SIGNALS+1]; +#endif +} *sig_state; + +/* + return number of sigcounter events not processed yet +*/ +static uint32_t tevent_sig_count(struct tevent_sigcounter s) +{ + return s.count - s.seen; +} + +/* + signal handler - redirects to registered signals +*/ +static void tevent_common_signal_handler(int signum) +{ + struct tevent_common_signal_list *sl; + struct tevent_context *ev = NULL; + int saved_errno = errno; + + TEVENT_SIG_INCREMENT(sig_state->signal_count[signum]); + TEVENT_SIG_INCREMENT(sig_state->got_signal); + + /* Write to each unique event context. */ + for (sl = sig_state->sig_handlers[signum]; sl; sl = sl->next) { + if (sl->se->event_ctx && sl->se->event_ctx != ev) { + ev = sl->se->event_ctx; + tevent_common_wakeup(ev); + } + } + + errno = saved_errno; +} + +#ifdef SA_SIGINFO +/* + signal handler with SA_SIGINFO - redirects to registered signals +*/ +static void tevent_common_signal_handler_info(int signum, siginfo_t *info, + void *uctx) +{ + uint32_t count = tevent_sig_count(sig_state->signal_count[signum]); + /* sig_state->signal_count[signum].seen % TEVENT_SA_INFO_QUEUE_COUNT + * is the base of the unprocessed signals in the ringbuffer. */ + uint32_t ofs = (sig_state->signal_count[signum].seen + count) % + TEVENT_SA_INFO_QUEUE_COUNT; + sig_state->sig_info[signum][ofs] = *info; + + tevent_common_signal_handler(signum); + + /* handle SA_SIGINFO */ + if (count+1 == TEVENT_SA_INFO_QUEUE_COUNT) { + /* we've filled the info array - block this signal until + these ones are delivered */ +#ifdef HAVE_UCONTEXT_T + /* + * This is the only way for this to work. + * By default signum is blocked inside this + * signal handler using a temporary mask, + * but what we really need to do now is + * block it in the callers mask, so it + * stays blocked when the temporary signal + * handler mask is replaced when we return + * from here. The callers mask can be found + * in the ucontext_t passed in as the + * void *uctx argument. + */ + ucontext_t *ucp = (ucontext_t *)uctx; + sigaddset(&ucp->uc_sigmask, signum); +#else + /* + * WARNING !!! WARNING !!!! + * + * This code doesn't work. + * By default signum is blocked inside this + * signal handler, but calling sigprocmask + * modifies the temporary signal mask being + * used *inside* this handler, which will be + * replaced by the callers signal mask once + * we return from here. See Samba + * bug #9550 for details. + */ + sigset_t set; + sigemptyset(&set); + sigaddset(&set, signum); + sigprocmask(SIG_BLOCK, &set, NULL); +#endif + TEVENT_SIG_INCREMENT(sig_state->sig_blocked[signum]); + } +} +#endif + +static int tevent_common_signal_list_destructor(struct tevent_common_signal_list *sl) +{ + if (sig_state->sig_handlers[sl->se->signum]) { + DLIST_REMOVE(sig_state->sig_handlers[sl->se->signum], sl); + } + return 0; +} + +/* + destroy a signal event +*/ +static int tevent_signal_destructor(struct tevent_signal *se) +{ + if (se->destroyed) { + tevent_common_check_double_free(se, "tevent_signal double free"); + goto done; + } + se->destroyed = true; + + TALLOC_FREE(se->additional_data); + + if (se->event_ctx != NULL) { + DLIST_REMOVE(se->event_ctx->signal_events, se); + } + + if (sig_state->sig_handlers[se->signum] == NULL) { + /* restore old handler, if any */ + if (sig_state->oldact[se->signum]) { + sigaction(se->signum, sig_state->oldact[se->signum], NULL); + TALLOC_FREE(sig_state->oldact[se->signum]); + } +#ifdef SA_SIGINFO + if (se->sa_flags & SA_SIGINFO) { + if (sig_state->sig_info[se->signum]) { + TALLOC_FREE(sig_state->sig_info[se->signum]); + } + } +#endif + } + + se->event_ctx = NULL; +done: + if (se->busy) { + return -1; + } + se->wrapper = NULL; + + return 0; +} + +/* + add a signal event + return NULL on failure (memory allocation error) +*/ +struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + int signum, + int sa_flags, + tevent_signal_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + struct tevent_signal *se; + struct tevent_common_signal_list *sl; + sigset_t set, oldset; + int ret; + + ret = tevent_common_wakeup_init(ev); + if (ret != 0) { + errno = ret; + return NULL; + } + + if (signum >= TEVENT_NUM_SIGNALS) { + errno = EINVAL; + return NULL; + } + + /* the sig_state needs to be on a global context as it can last across + multiple event contexts */ + if (sig_state == NULL) { + sig_state = talloc_zero(NULL, struct tevent_sig_state); + if (sig_state == NULL) { + return NULL; + } + } + + se = talloc_zero(mem_ctx?mem_ctx:ev, struct tevent_signal); + if (se == NULL) return NULL; + + sl = talloc_zero(se, struct tevent_common_signal_list); + if (!sl) { + talloc_free(se); + return NULL; + } + sl->se = se; + + *se = (struct tevent_signal) { + .event_ctx = ev, + .signum = signum, + .sa_flags = sa_flags, + .handler = handler, + .private_data = private_data, + .handler_name = handler_name, + .location = location, + .additional_data= sl, + }; + + /* Ensure, no matter the destruction order, that we always have a handle on the global sig_state */ + if (!talloc_reference(se, sig_state)) { + talloc_free(se); + return NULL; + } + + /* only install a signal handler if not already installed */ + if (sig_state->sig_handlers[signum] == NULL) { + struct sigaction act; + ZERO_STRUCT(act); + act.sa_handler = tevent_common_signal_handler; + act.sa_flags = sa_flags; +#ifdef SA_SIGINFO + if (sa_flags & SA_SIGINFO) { + act.sa_handler = NULL; + act.sa_sigaction = tevent_common_signal_handler_info; + if (sig_state->sig_info[signum] == NULL) { + sig_state->sig_info[signum] = + talloc_zero_array(sig_state, siginfo_t, + TEVENT_SA_INFO_QUEUE_COUNT); + if (sig_state->sig_info[signum] == NULL) { + talloc_free(se); + return NULL; + } + } + } +#endif + sig_state->oldact[signum] = talloc_zero(sig_state, struct sigaction); + if (sig_state->oldact[signum] == NULL) { + talloc_free(se); + return NULL; + } + if (sigaction(signum, &act, sig_state->oldact[signum]) == -1) { + talloc_free(sig_state->oldact[signum]); + sig_state->oldact[signum] = NULL; + talloc_free(se); + return NULL; + } + } + + DLIST_ADD(se->event_ctx->signal_events, se); + + /* Make sure the signal doesn't come in while we're mangling list. */ + sigemptyset(&set); + sigaddset(&set, signum); + sigprocmask(SIG_BLOCK, &set, &oldset); + DLIST_ADD(sig_state->sig_handlers[signum], sl); + sigprocmask(SIG_SETMASK, &oldset, NULL); + + talloc_set_destructor(se, tevent_signal_destructor); + talloc_set_destructor(sl, tevent_common_signal_list_destructor); + + return se; +} + +int tevent_common_invoke_signal_handler(struct tevent_signal *se, + int signum, int count, void *siginfo, + bool *removed) +{ + struct tevent_context *handler_ev = se->event_ctx; + bool remove = false; + + if (removed != NULL) { + *removed = false; + } + + if (se->event_ctx == NULL) { + return 0; + } + + se->busy = true; + if (se->wrapper != NULL) { + handler_ev = se->wrapper->wrap_ev; + + tevent_wrapper_push_use_internal(handler_ev, se->wrapper); + se->wrapper->ops->before_signal_handler( + se->wrapper->wrap_ev, + se->wrapper->private_state, + se->wrapper->main_ev, + se, + signum, + count, + siginfo, + se->handler_name, + se->location); + } + se->handler(handler_ev, se, signum, count, siginfo, se->private_data); + if (se->wrapper != NULL) { + se->wrapper->ops->after_signal_handler( + se->wrapper->wrap_ev, + se->wrapper->private_state, + se->wrapper->main_ev, + se, + signum, + count, + siginfo, + se->handler_name, + se->location); + tevent_wrapper_pop_use_internal(handler_ev, se->wrapper); + } + se->busy = false; + +#ifdef SA_RESETHAND + if (se->sa_flags & SA_RESETHAND) { + remove = true; + } +#endif + + if (se->destroyed) { + talloc_set_destructor(se, NULL); + remove = true; + } + + if (remove) { + TALLOC_FREE(se); + if (removed != NULL) { + *removed = true; + } + } + + return 0; +} + +/* + check if a signal is pending + return != 0 if a signal was pending +*/ +int tevent_common_check_signal(struct tevent_context *ev) +{ + int i; + + if (!sig_state || !TEVENT_SIG_PENDING(sig_state->got_signal)) { + return 0; + } + + for (i=0;isignal_count[i]; + uint32_t count = tevent_sig_count(counter); + int ret; +#ifdef SA_SIGINFO + /* Ensure we null out any stored siginfo_t entries + * after processing for debugging purposes. */ + bool clear_processed_siginfo = false; +#endif + + if (count == 0) { + continue; + } + for (sl=sig_state->sig_handlers[i];sl;sl=next) { + struct tevent_signal *se = sl->se; + + next = sl->next; + +#ifdef SA_SIGINFO + if (se->sa_flags & SA_SIGINFO) { + uint32_t j; + + clear_processed_siginfo = true; + + for (j=0;jsignal_count[i].seen + * % TEVENT_SA_INFO_QUEUE_COUNT is + * the base position of the unprocessed + * signals in the ringbuffer. */ + uint32_t ofs = (counter.seen + j) + % TEVENT_SA_INFO_QUEUE_COUNT; + bool removed = false; + + ret = tevent_common_invoke_signal_handler( + se, i, 1, + (void*)&sig_state->sig_info[i][ofs], + &removed); + if (ret != 0) { + tevent_abort(ev, "tevent_common_invoke_signal_handler() failed"); + } + if (removed) { + break; + } + } + continue; + } +#endif + + ret = tevent_common_invoke_signal_handler(se, i, count, + NULL, NULL); + if (ret != 0) { + tevent_abort(ev, "tevent_common_invoke_signal_handler() failed"); + } + } + +#ifdef SA_SIGINFO + if (clear_processed_siginfo && sig_state->sig_info[i] != NULL) { + uint32_t j; + for (j=0;jsig_info[i][ofs], + '\0', + sizeof(siginfo_t)); + } + } +#endif + + TEVENT_SIG_SEEN(sig_state->signal_count[i], count); + TEVENT_SIG_SEEN(sig_state->got_signal, count); + +#ifdef SA_SIGINFO + if (TEVENT_SIG_PENDING(sig_state->sig_blocked[i])) { + /* We'd filled the queue, unblock the + signal now the queue is empty again. + Note we MUST do this after the + TEVENT_SIG_SEEN(sig_state->signal_count[i], count) + call to prevent a new signal running + out of room in the sig_state->sig_info[i][] + ring buffer. */ + sigset_t set; + sigemptyset(&set); + sigaddset(&set, i); + TEVENT_SIG_SEEN(sig_state->sig_blocked[i], + tevent_sig_count(sig_state->sig_blocked[i])); + sigprocmask(SIG_UNBLOCK, &set, NULL); + } +#endif + } + + return 1; +} + +void tevent_cleanup_pending_signal_handlers(struct tevent_signal *se) +{ + tevent_signal_destructor(se); + talloc_set_destructor(se, NULL); + return; +} diff --git a/ldb-2.0.8/lib/tevent/tevent_standard.c b/ldb-2.0.8/lib/tevent/tevent_standard.c new file mode 100644 index 0000000..3872020 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent_standard.c @@ -0,0 +1,238 @@ +/* + Unix SMB/CIFS implementation. + main select loop and event handling + Copyright (C) Stefan Metzmacher 2013 + Copyright (C) Jeremy Allison 2013 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + This is SAMBA's default event loop code + + - we try to use epoll if configure detected support for it + otherwise we use poll() + - if epoll is broken on the system or the kernel doesn't support it + at runtime we fallback to poll() +*/ + +#include "replace.h" +#include "tevent.h" +#include "tevent_util.h" +#include "tevent_internal.h" + +struct std_event_glue { + const struct tevent_ops *epoll_ops; + const struct tevent_ops *poll_ops; + struct tevent_ops *glue_ops; + bool fallback_replay; +}; + +static int std_event_context_init(struct tevent_context *ev); + +static const struct tevent_ops std_event_ops = { + .context_init = std_event_context_init, +}; + +/* + If this function gets called. epoll failed at runtime. + Move us to using poll instead. If we return false here, + caller should abort(). +*/ +#ifdef HAVE_EPOLL +static bool std_fallback_to_poll(struct tevent_context *ev, bool replay) +{ + void *glue_ptr = talloc_parent(ev->ops); + struct std_event_glue *glue = + talloc_get_type_abort(glue_ptr, + struct std_event_glue); + int ret; + struct tevent_fd *fde; + + glue->fallback_replay = replay; + + /* First switch all the ops to poll. */ + glue->epoll_ops = NULL; + + /* + * Set custom_ops the same as poll. + */ + *glue->glue_ops = *glue->poll_ops; + glue->glue_ops->context_init = std_event_context_init; + + /* Next initialize the poll backend. */ + ret = glue->poll_ops->context_init(ev); + if (ret != 0) { + return false; + } + + /* + * Now we have to change all the existing file descriptor + * events from the epoll backend to the poll backend. + */ + for (fde = ev->fd_events; fde; fde = fde->next) { + bool ok; + + /* Re-add this event as a poll backend event. */ + ok = tevent_poll_event_add_fd_internal(ev, fde); + if (!ok) { + return false; + } + } + + return true; +} +#endif + +static int std_event_loop_once(struct tevent_context *ev, const char *location) +{ + void *glue_ptr = talloc_parent(ev->ops); + struct std_event_glue *glue = + talloc_get_type_abort(glue_ptr, + struct std_event_glue); + int ret; + + ret = glue->epoll_ops->loop_once(ev, location); + /* + * If the above hasn't panicked due to an epoll interface failure, + * std_fallback_to_poll() wasn't called, and hasn't cleared epoll_ops to + * signify fallback to poll_ops. + */ + if (glue->epoll_ops != NULL) { + /* No fallback */ + return ret; + } + + if (!glue->fallback_replay) { + /* + * The problem happened while modifying an event. + * An event handler was triggered in this case + * and there is no need to call loop_once() again. + */ + return ret; + } + + return glue->poll_ops->loop_once(ev, location); +} + +static int std_event_loop_wait(struct tevent_context *ev, const char *location) +{ + void *glue_ptr = talloc_parent(ev->ops); + struct std_event_glue *glue = + talloc_get_type_abort(glue_ptr, + struct std_event_glue); + int ret; + + ret = glue->epoll_ops->loop_wait(ev, location); + /* + * If the above hasn't panicked due to an epoll interface failure, + * std_fallback_to_poll() wasn't called, and hasn't cleared epoll_ops to + * signify fallback to poll_ops. + */ + if (glue->epoll_ops != NULL) { + /* No fallback */ + return ret; + } + + return glue->poll_ops->loop_wait(ev, location); +} +/* + Initialize the epoll backend and allow it to call a + switch function if epoll fails at runtime. +*/ +static int std_event_context_init(struct tevent_context *ev) +{ + struct std_event_glue *glue; + int ret; + + /* + * If this is the first initialization + * we need to set up the allocated ops + * pointers. + */ + + if (ev->ops == &std_event_ops) { + glue = talloc_zero(ev, struct std_event_glue); + if (glue == NULL) { + return -1; + } + + glue->epoll_ops = tevent_find_ops_byname("epoll"); + + glue->poll_ops = tevent_find_ops_byname("poll"); + if (glue->poll_ops == NULL) { + return -1; + } + + /* + * Allocate space for our custom ops. + * Allocate as a child of our epoll_ops pointer + * so we can easily get to it using talloc_parent. + */ + glue->glue_ops = talloc_zero(glue, struct tevent_ops); + if (glue->glue_ops == NULL) { + talloc_free(glue); + return -1; + } + + ev->ops = glue->glue_ops; + } else { + void *glue_ptr = talloc_parent(ev->ops); + glue = talloc_get_type_abort(glue_ptr, struct std_event_glue); + } + + if (glue->epoll_ops != NULL) { + /* + * Set custom_ops the same as epoll, + * except re-init using std_event_context_init() + * and use std_event_loop_once() to add the + * ability to fallback to a poll backend on + * epoll runtime error. + */ + *glue->glue_ops = *glue->epoll_ops; + glue->glue_ops->context_init = std_event_context_init; + glue->glue_ops->loop_once = std_event_loop_once; + glue->glue_ops->loop_wait = std_event_loop_wait; + + ret = glue->epoll_ops->context_init(ev); + if (ret == -1) { + goto fallback; + } +#ifdef HAVE_EPOLL + tevent_epoll_set_panic_fallback(ev, std_fallback_to_poll); +#endif + + return ret; + } + +fallback: + glue->epoll_ops = NULL; + + /* + * Set custom_ops the same as poll. + */ + *glue->glue_ops = *glue->poll_ops; + glue->glue_ops->context_init = std_event_context_init; + + return glue->poll_ops->context_init(ev); +} + +_PRIVATE_ bool tevent_standard_init(void) +{ + return tevent_register_backend("standard", &std_event_ops); +} diff --git a/ldb-2.0.8/lib/tevent/tevent_threads.c b/ldb-2.0.8/lib/tevent/tevent_threads.c new file mode 100644 index 0000000..a89990f --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent_threads.c @@ -0,0 +1,601 @@ +/* + tevent event library. + + Copyright (C) Jeremy Allison 2015 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#include "system/filesys.h" +#include "talloc.h" +#include "tevent.h" +#include "tevent_internal.h" +#include "tevent_util.h" + +#ifdef HAVE_PTHREAD +#include "system/threads.h" + +struct tevent_immediate_list { + struct tevent_immediate_list *next, *prev; + tevent_immediate_handler_t handler; + struct tevent_immediate *im; + void *private_ptr; +}; + +struct tevent_thread_proxy { + pthread_mutex_t mutex; + struct tevent_context *dest_ev_ctx; + int read_fd; + int write_fd; + struct tevent_fd *pipe_read_fde; + /* Pending events list. */ + struct tevent_immediate_list *im_list; + /* Completed events list. */ + struct tevent_immediate_list *tofree_im_list; + struct tevent_immediate *free_im; +}; + +static void free_im_list(struct tevent_immediate_list **pp_list_head) +{ + struct tevent_immediate_list *im_entry = NULL; + struct tevent_immediate_list *im_next = NULL; + + for (im_entry = *pp_list_head; im_entry; im_entry = im_next) { + im_next = im_entry->next; + DLIST_REMOVE(*pp_list_head, im_entry); + TALLOC_FREE(im_entry); + } +} + +static void free_list_handler(struct tevent_context *ev, + struct tevent_immediate *im, + void *private_ptr) +{ + struct tevent_thread_proxy *tp = + talloc_get_type_abort(private_ptr, struct tevent_thread_proxy); + int ret; + + ret = pthread_mutex_lock(&tp->mutex); + if (ret != 0) { + abort(); + /* Notreached. */ + return; + } + + free_im_list(&tp->tofree_im_list); + + ret = pthread_mutex_unlock(&tp->mutex); + if (ret != 0) { + abort(); + /* Notreached. */ + return; + } +} + +static void schedule_immediate_functions(struct tevent_thread_proxy *tp) +{ + struct tevent_immediate_list *im_entry = NULL; + struct tevent_immediate_list *im_next = NULL; + + for (im_entry = tp->im_list; im_entry; im_entry = im_next) { + im_next = im_entry->next; + DLIST_REMOVE(tp->im_list, im_entry); + + tevent_schedule_immediate(im_entry->im, + tp->dest_ev_ctx, + im_entry->handler, + im_entry->private_ptr); + + /* Move from pending list to free list. */ + DLIST_ADD(tp->tofree_im_list, im_entry); + } + if (tp->tofree_im_list != NULL) { + /* + * Once the current immediate events + * are processed, we need to reschedule + * ourselves to free them. This works + * as tevent_schedule_immediate() + * always adds events to the *END* of + * the immediate events list. + */ + tevent_schedule_immediate(tp->free_im, + tp->dest_ev_ctx, + free_list_handler, + tp); + } +} + +static void pipe_read_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, + void *private_ptr) +{ + struct tevent_thread_proxy *tp = + talloc_get_type_abort(private_ptr, struct tevent_thread_proxy); + ssize_t len = 64; + int ret; + + ret = pthread_mutex_lock(&tp->mutex); + if (ret != 0) { + abort(); + /* Notreached. */ + return; + } + + /* + * Clear out all data in the pipe. We + * don't really care if this returns -1. + */ + while (len == 64) { + char buf[64]; + len = read(tp->read_fd, buf, 64); + }; + + schedule_immediate_functions(tp); + + ret = pthread_mutex_unlock(&tp->mutex); + if (ret != 0) { + abort(); + /* Notreached. */ + return; + } +} + +static int tevent_thread_proxy_destructor(struct tevent_thread_proxy *tp) +{ + int ret; + + ret = pthread_mutex_lock(&tp->mutex); + if (ret != 0) { + abort(); + /* Notreached. */ + return 0; + } + + TALLOC_FREE(tp->pipe_read_fde); + + if (tp->read_fd != -1) { + (void)close(tp->read_fd); + tp->read_fd = -1; + } + if (tp->write_fd != -1) { + (void)close(tp->write_fd); + tp->write_fd = -1; + } + + /* Hmmm. It's probably an error if we get here with + any non-NULL immediate entries.. */ + + free_im_list(&tp->im_list); + free_im_list(&tp->tofree_im_list); + + TALLOC_FREE(tp->free_im); + + ret = pthread_mutex_unlock(&tp->mutex); + if (ret != 0) { + abort(); + /* Notreached. */ + return 0; + } + + ret = pthread_mutex_destroy(&tp->mutex); + if (ret != 0) { + abort(); + /* Notreached. */ + return 0; + } + + return 0; +} + +/* + * Create a struct that can be passed to other threads + * to allow them to signal the struct tevent_context * + * passed in. + */ + +struct tevent_thread_proxy *tevent_thread_proxy_create( + struct tevent_context *dest_ev_ctx) +{ + int ret; + int pipefds[2]; + struct tevent_thread_proxy *tp; + + if (dest_ev_ctx->wrapper.glue != NULL) { + /* + * stacking of wrappers is not supported + */ + tevent_debug(dest_ev_ctx->wrapper.glue->main_ev, + TEVENT_DEBUG_FATAL, + "%s() not allowed on a wrapper context\n", + __func__); + errno = EINVAL; + return NULL; + } + + tp = talloc_zero(dest_ev_ctx, struct tevent_thread_proxy); + if (tp == NULL) { + return NULL; + } + + ret = pthread_mutex_init(&tp->mutex, NULL); + if (ret != 0) { + goto fail; + } + + tp->dest_ev_ctx = dest_ev_ctx; + tp->read_fd = -1; + tp->write_fd = -1; + + talloc_set_destructor(tp, tevent_thread_proxy_destructor); + + ret = pipe(pipefds); + if (ret == -1) { + goto fail; + } + + tp->read_fd = pipefds[0]; + tp->write_fd = pipefds[1]; + + ret = ev_set_blocking(pipefds[0], false); + if (ret != 0) { + goto fail; + } + ret = ev_set_blocking(pipefds[1], false); + if (ret != 0) { + goto fail; + } + if (!ev_set_close_on_exec(pipefds[0])) { + goto fail; + } + if (!ev_set_close_on_exec(pipefds[1])) { + goto fail; + } + + tp->pipe_read_fde = tevent_add_fd(dest_ev_ctx, + tp, + tp->read_fd, + TEVENT_FD_READ, + pipe_read_handler, + tp); + if (tp->pipe_read_fde == NULL) { + goto fail; + } + + /* + * Create an immediate event to free + * completed lists. + */ + tp->free_im = tevent_create_immediate(tp); + if (tp->free_im == NULL) { + goto fail; + } + + return tp; + + fail: + + TALLOC_FREE(tp); + return NULL; +} + +/* + * This function schedules an immediate event to be called with argument + * *pp_private in the thread context of dest_ev_ctx. Caller doesn't + * wait for activation to take place, this is simply fire-and-forget. + * + * pp_im must be a pointer to an immediate event talloced on + * a context owned by the calling thread, or the NULL context. + * Ownership of *pp_im will be transfered to the tevent library. + * + * pp_private can be null, or contents of *pp_private must be + * talloc'ed memory on a context owned by the calling thread + * or the NULL context. If non-null, ownership of *pp_private will + * be transfered to the tevent library. + * + * If you want to return a message, have the destination use the + * same function call to send back to the caller. + */ + + +void tevent_thread_proxy_schedule(struct tevent_thread_proxy *tp, + struct tevent_immediate **pp_im, + tevent_immediate_handler_t handler, + void *pp_private_data) +{ + struct tevent_immediate_list *im_entry; + int ret; + char c; + ssize_t written; + + ret = pthread_mutex_lock(&tp->mutex); + if (ret != 0) { + abort(); + /* Notreached. */ + return; + } + + if (tp->write_fd == -1) { + /* In the process of being destroyed. Ignore. */ + goto end; + } + + /* Create a new immediate_list entry. MUST BE ON THE NULL CONTEXT */ + im_entry = talloc_zero(NULL, struct tevent_immediate_list); + if (im_entry == NULL) { + goto end; + } + + im_entry->handler = handler; + im_entry->im = talloc_move(im_entry, pp_im); + + if (pp_private_data != NULL) { + void **pptr = (void **)pp_private_data; + im_entry->private_ptr = talloc_move(im_entry, pptr); + } + + DLIST_ADD(tp->im_list, im_entry); + + /* And notify the dest_ev_ctx to wake up. */ + c = '\0'; + do { + written = write(tp->write_fd, &c, 1); + } while (written == -1 && errno == EINTR); + + end: + + ret = pthread_mutex_unlock(&tp->mutex); + if (ret != 0) { + abort(); + /* Notreached. */ + } +} +#else +/* !HAVE_PTHREAD */ +struct tevent_thread_proxy *tevent_thread_proxy_create( + struct tevent_context *dest_ev_ctx) +{ + errno = ENOSYS; + return NULL; +} + +void tevent_thread_proxy_schedule(struct tevent_thread_proxy *tp, + struct tevent_immediate **pp_im, + tevent_immediate_handler_t handler, + void *pp_private_data) +{ + ; +} +#endif + +static int tevent_threaded_context_destructor( + struct tevent_threaded_context *tctx) +{ + struct tevent_context *main_ev = tevent_wrapper_main_ev(tctx->event_ctx); + int ret; + + if (main_ev != NULL) { + DLIST_REMOVE(main_ev->threaded_contexts, tctx); + } + + /* + * We have to coordinate with _tevent_threaded_schedule_immediate's + * unlock of the event_ctx_mutex. We're in the main thread here, + * and we can be scheduled before the helper thread finalizes its + * call _tevent_threaded_schedule_immediate. This means we would + * pthreadpool_destroy a locked mutex, which is illegal. + */ + ret = pthread_mutex_lock(&tctx->event_ctx_mutex); + if (ret != 0) { + abort(); + } + + ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); + if (ret != 0) { + abort(); + } + + ret = pthread_mutex_destroy(&tctx->event_ctx_mutex); + if (ret != 0) { + abort(); + } + + return 0; +} + +struct tevent_threaded_context *tevent_threaded_context_create( + TALLOC_CTX *mem_ctx, struct tevent_context *ev) +{ +#ifdef HAVE_PTHREAD + struct tevent_context *main_ev = tevent_wrapper_main_ev(ev); + struct tevent_threaded_context *tctx; + int ret; + + ret = tevent_common_wakeup_init(main_ev); + if (ret != 0) { + errno = ret; + return NULL; + } + + tctx = talloc(mem_ctx, struct tevent_threaded_context); + if (tctx == NULL) { + return NULL; + } + tctx->event_ctx = ev; + + ret = pthread_mutex_init(&tctx->event_ctx_mutex, NULL); + if (ret != 0) { + TALLOC_FREE(tctx); + return NULL; + } + + DLIST_ADD(main_ev->threaded_contexts, tctx); + talloc_set_destructor(tctx, tevent_threaded_context_destructor); + + return tctx; +#else + errno = ENOSYS; + return NULL; +#endif +} + +static int tevent_threaded_schedule_immediate_destructor(struct tevent_immediate *im) +{ + if (im->event_ctx != NULL) { + abort(); + } + return 0; +} + +void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx, + struct tevent_immediate *im, + tevent_immediate_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ +#ifdef HAVE_PTHREAD + const char *create_location = im->create_location; + struct tevent_context *main_ev = NULL; + struct tevent_wrapper_glue *glue = NULL; + int ret, wakeup_fd; + + ret = pthread_mutex_lock(&tctx->event_ctx_mutex); + if (ret != 0) { + abort(); + } + + if (tctx->event_ctx == NULL) { + /* + * Our event context is already gone. + */ + ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); + if (ret != 0) { + abort(); + } + return; + } + + glue = tctx->event_ctx->wrapper.glue; + + if ((im->event_ctx != NULL) || (handler == NULL)) { + abort(); + } + if (im->destroyed) { + abort(); + } + if (im->busy) { + abort(); + } + + main_ev = tevent_wrapper_main_ev(tctx->event_ctx); + + *im = (struct tevent_immediate) { + .event_ctx = tctx->event_ctx, + .wrapper = glue, + .handler = handler, + .private_data = private_data, + .handler_name = handler_name, + .create_location = create_location, + .schedule_location = location, + }; + + /* + * Make sure the event won't be destroyed while + * it's part of the ev->scheduled_immediates list. + * _tevent_schedule_immediate() will reset the destructor + * in tevent_common_threaded_activate_immediate(). + */ + talloc_set_destructor(im, tevent_threaded_schedule_immediate_destructor); + + ret = pthread_mutex_lock(&main_ev->scheduled_mutex); + if (ret != 0) { + abort(); + } + + DLIST_ADD_END(main_ev->scheduled_immediates, im); + wakeup_fd = main_ev->wakeup_fd; + + ret = pthread_mutex_unlock(&main_ev->scheduled_mutex); + if (ret != 0) { + abort(); + } + + ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); + if (ret != 0) { + abort(); + } + + /* + * We might want to wake up the main thread under the lock. We + * had a slightly similar situation in pthreadpool, changed + * with 1c4284c7395f23. This is not exactly the same, as the + * wakeup is only a last-resort thing in case the main thread + * is sleeping. Doing the wakeup under the lock can easily + * lead to a contended mutex, which is much more expensive + * than a noncontended one. So I'd opt for the lower footprint + * initially. Maybe we have to change that later. + */ + tevent_common_wakeup_fd(wakeup_fd); +#else + /* + * tevent_threaded_context_create() returned NULL with ENOSYS... + */ + abort(); +#endif +} + +void tevent_common_threaded_activate_immediate(struct tevent_context *ev) +{ +#ifdef HAVE_PTHREAD + int ret; + ret = pthread_mutex_lock(&ev->scheduled_mutex); + if (ret != 0) { + abort(); + } + + while (ev->scheduled_immediates != NULL) { + struct tevent_immediate *im = ev->scheduled_immediates; + struct tevent_immediate copy = *im; + + DLIST_REMOVE(ev->scheduled_immediates, im); + + tevent_debug(ev, TEVENT_DEBUG_TRACE, + "Schedule immediate event \"%s\": %p from thread into main\n", + im->handler_name, im); + im->handler_name = NULL; + _tevent_schedule_immediate(im, + ev, + copy.handler, + copy.private_data, + copy.handler_name, + copy.schedule_location); + } + + ret = pthread_mutex_unlock(&ev->scheduled_mutex); + if (ret != 0) { + abort(); + } +#else + /* + * tevent_threaded_context_create() returned NULL with ENOSYS... + */ + abort(); +#endif +} diff --git a/ldb-2.0.8/lib/tevent/tevent_timed.c b/ldb-2.0.8/lib/tevent/tevent_timed.c new file mode 100644 index 0000000..a78d286 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent_timed.c @@ -0,0 +1,449 @@ +/* + Unix SMB/CIFS implementation. + + common events code for timed events + + Copyright (C) Andrew Tridgell 2003-2006 + Copyright (C) Stefan Metzmacher 2005-2009 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#include "system/time.h" +#define TEVENT_DEPRECATED 1 +#include "tevent.h" +#include "tevent_internal.h" +#include "tevent_util.h" + +/** + compare two timeval structures. + Return -1 if tv1 < tv2 + Return 0 if tv1 == tv2 + Return 1 if tv1 > tv2 +*/ +int tevent_timeval_compare(const struct timeval *tv1, const struct timeval *tv2) +{ + if (tv1->tv_sec > tv2->tv_sec) return 1; + if (tv1->tv_sec < tv2->tv_sec) return -1; + if (tv1->tv_usec > tv2->tv_usec) return 1; + if (tv1->tv_usec < tv2->tv_usec) return -1; + return 0; +} + +/** + return a zero timeval +*/ +struct timeval tevent_timeval_zero(void) +{ + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 0; + return tv; +} + +/** + return a timeval for the current time +*/ +struct timeval tevent_timeval_current(void) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return tv; +} + +/** + return a timeval struct with the given elements +*/ +struct timeval tevent_timeval_set(uint32_t secs, uint32_t usecs) +{ + struct timeval tv; + tv.tv_sec = secs; + tv.tv_usec = usecs; + return tv; +} + +/** + return the difference between two timevals as a timeval + if tv1 comes after tv2, then return a zero timeval + (this is *tv2 - *tv1) +*/ +struct timeval tevent_timeval_until(const struct timeval *tv1, + const struct timeval *tv2) +{ + struct timeval t; + if (tevent_timeval_compare(tv1, tv2) >= 0) { + return tevent_timeval_zero(); + } + t.tv_sec = tv2->tv_sec - tv1->tv_sec; + if (tv1->tv_usec > tv2->tv_usec) { + t.tv_sec--; + t.tv_usec = 1000000 - (tv1->tv_usec - tv2->tv_usec); + } else { + t.tv_usec = tv2->tv_usec - tv1->tv_usec; + } + return t; +} + +/** + return true if a timeval is zero +*/ +bool tevent_timeval_is_zero(const struct timeval *tv) +{ + return tv->tv_sec == 0 && tv->tv_usec == 0; +} + +struct timeval tevent_timeval_add(const struct timeval *tv, uint32_t secs, + uint32_t usecs) +{ + struct timeval tv2 = *tv; + tv2.tv_sec += secs; + tv2.tv_usec += usecs; + tv2.tv_sec += tv2.tv_usec / 1000000; + tv2.tv_usec = tv2.tv_usec % 1000000; + + return tv2; +} + +/** + return a timeval in the future with a specified offset +*/ +struct timeval tevent_timeval_current_ofs(uint32_t secs, uint32_t usecs) +{ + struct timeval tv = tevent_timeval_current(); + return tevent_timeval_add(&tv, secs, usecs); +} + +/* + destroy a timed event +*/ +static int tevent_common_timed_destructor(struct tevent_timer *te) +{ + if (te->destroyed) { + tevent_common_check_double_free(te, "tevent_timer double free"); + goto done; + } + te->destroyed = true; + + if (te->event_ctx == NULL) { + return 0; + } + + tevent_debug(te->event_ctx, TEVENT_DEBUG_TRACE, + "Destroying timer event %p \"%s\"\n", + te, te->handler_name); + + if (te->event_ctx->last_zero_timer == te) { + te->event_ctx->last_zero_timer = DLIST_PREV(te); + } + DLIST_REMOVE(te->event_ctx->timer_events, te); + + te->event_ctx = NULL; +done: + if (te->busy) { + return -1; + } + te->wrapper = NULL; + + return 0; +} + +static void tevent_common_insert_timer(struct tevent_context *ev, + struct tevent_timer *te, + bool optimize_zero) +{ + struct tevent_timer *prev_te = NULL; + + if (te->destroyed) { + tevent_abort(ev, "tevent_timer use after free"); + return; + } + + /* keep the list ordered */ + if (optimize_zero && tevent_timeval_is_zero(&te->next_event)) { + /* + * Some callers use zero tevent_timer + * instead of tevent_immediate events. + * + * As these can happen very often, + * we remember the last zero timer + * in the list. + */ + prev_te = ev->last_zero_timer; + ev->last_zero_timer = te; + } else { + struct tevent_timer *cur_te; + + /* + * we traverse the list from the tail + * because it's much more likely that + * timers are added at the end of the list + */ + for (cur_te = DLIST_TAIL(ev->timer_events); + cur_te != NULL; + cur_te = DLIST_PREV(cur_te)) + { + int ret; + + /* + * if the new event comes before the current + * we continue searching + */ + ret = tevent_timeval_compare(&te->next_event, + &cur_te->next_event); + if (ret < 0) { + continue; + } + + break; + } + + prev_te = cur_te; + } + + DLIST_ADD_AFTER(ev->timer_events, te, prev_te); +} + +/* + add a timed event + return NULL on failure (memory allocation error) +*/ +static struct tevent_timer *tevent_common_add_timer_internal( + struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + struct timeval next_event, + tevent_timer_handler_t handler, + void *private_data, + const char *handler_name, + const char *location, + bool optimize_zero) +{ + struct tevent_timer *te; + + te = talloc(mem_ctx?mem_ctx:ev, struct tevent_timer); + if (te == NULL) return NULL; + + *te = (struct tevent_timer) { + .event_ctx = ev, + .next_event = next_event, + .handler = handler, + .private_data = private_data, + .handler_name = handler_name, + .location = location, + }; + + if (ev->timer_events == NULL) { + ev->last_zero_timer = NULL; + } + + tevent_common_insert_timer(ev, te, optimize_zero); + + talloc_set_destructor(te, tevent_common_timed_destructor); + + tevent_debug(ev, TEVENT_DEBUG_TRACE, + "Added timed event \"%s\": %p\n", + handler_name, te); + return te; +} + +struct tevent_timer *tevent_common_add_timer(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + struct timeval next_event, + tevent_timer_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + /* + * do not use optimization, there are broken Samba + * versions which use tevent_common_add_timer() + * without using tevent_common_loop_timer_delay(), + * it just uses DLIST_REMOVE(ev->timer_events, te) + * and would leave ev->last_zero_timer behind. + */ + return tevent_common_add_timer_internal(ev, mem_ctx, next_event, + handler, private_data, + handler_name, location, + false); +} + +struct tevent_timer *tevent_common_add_timer_v2(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + struct timeval next_event, + tevent_timer_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + /* + * Here we turn on last_zero_timer optimization + */ + return tevent_common_add_timer_internal(ev, mem_ctx, next_event, + handler, private_data, + handler_name, location, + true); +} + +void tevent_update_timer(struct tevent_timer *te, struct timeval next_event) +{ + struct tevent_context *ev = te->event_ctx; + + if (ev->last_zero_timer == te) { + te->event_ctx->last_zero_timer = DLIST_PREV(te); + } + DLIST_REMOVE(ev->timer_events, te); + + te->next_event = next_event; + + /* + * Not doing the zero_timer optimization. This is for new code + * that should know about immediates. + */ + tevent_common_insert_timer(ev, te, false); +} + +int tevent_common_invoke_timer_handler(struct tevent_timer *te, + struct timeval current_time, + bool *removed) +{ + struct tevent_context *handler_ev = te->event_ctx; + + if (removed != NULL) { + *removed = false; + } + + if (te->event_ctx == NULL) { + return 0; + } + + /* + * We need to remove the timer from the list before calling the + * handler because in a semi-async inner event loop called from the + * handler we don't want to come across this event again -- vl + */ + if (te->event_ctx->last_zero_timer == te) { + te->event_ctx->last_zero_timer = DLIST_PREV(te); + } + DLIST_REMOVE(te->event_ctx->timer_events, te); + + tevent_debug(te->event_ctx, TEVENT_DEBUG_TRACE, + "Running timer event %p \"%s\"\n", + te, te->handler_name); + + /* + * If the timed event was registered for a zero current_time, + * then we pass a zero timeval here too! To avoid the + * overhead of gettimeofday() calls. + * + * otherwise we pass the current time + */ + te->busy = true; + if (te->wrapper != NULL) { + handler_ev = te->wrapper->wrap_ev; + + tevent_wrapper_push_use_internal(handler_ev, te->wrapper); + te->wrapper->ops->before_timer_handler( + te->wrapper->wrap_ev, + te->wrapper->private_state, + te->wrapper->main_ev, + te, + te->next_event, + current_time, + te->handler_name, + te->location); + } + te->handler(handler_ev, te, current_time, te->private_data); + if (te->wrapper != NULL) { + te->wrapper->ops->after_timer_handler( + te->wrapper->wrap_ev, + te->wrapper->private_state, + te->wrapper->main_ev, + te, + te->next_event, + current_time, + te->handler_name, + te->location); + tevent_wrapper_pop_use_internal(handler_ev, te->wrapper); + } + te->busy = false; + + tevent_debug(te->event_ctx, TEVENT_DEBUG_TRACE, + "Ending timer event %p \"%s\"\n", + te, te->handler_name); + + te->wrapper = NULL; + te->event_ctx = NULL; + talloc_set_destructor(te, NULL); + TALLOC_FREE(te); + + if (removed != NULL) { + *removed = true; + } + + return 0; +} +/* + do a single event loop using the events defined in ev + + return the delay until the next timed event, + or zero if a timed event was triggered +*/ +struct timeval tevent_common_loop_timer_delay(struct tevent_context *ev) +{ + struct timeval current_time = tevent_timeval_zero(); + struct tevent_timer *te = ev->timer_events; + int ret; + + if (!te) { + /* have a default tick time of 30 seconds. This guarantees + that code that uses its own timeout checking will be + able to proceed eventually */ + return tevent_timeval_set(30, 0); + } + + /* + * work out the right timeout for the next timed event + * + * avoid the syscall to gettimeofday() if the timed event should + * be triggered directly + * + * if there's a delay till the next timed event, we're done + * with just returning the delay + */ + if (!tevent_timeval_is_zero(&te->next_event)) { + struct timeval delay; + + current_time = tevent_timeval_current(); + + delay = tevent_timeval_until(¤t_time, &te->next_event); + if (!tevent_timeval_is_zero(&delay)) { + return delay; + } + } + + /* + * ok, we have a timed event that we'll process ... + */ + ret = tevent_common_invoke_timer_handler(te, current_time, NULL); + if (ret != 0) { + tevent_abort(ev, "tevent_common_invoke_timer_handler() failed"); + } + + return tevent_timeval_zero(); +} + diff --git a/ldb-2.0.8/lib/tevent/tevent_util.c b/ldb-2.0.8/lib/tevent/tevent_util.c new file mode 100644 index 0000000..16af8f3 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent_util.c @@ -0,0 +1,107 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2005 + Copyright (C) Jelmer Vernooij 2005 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#include "talloc.h" +#include "tevent.h" +#include "tevent_internal.h" +#include "tevent_util.h" +#include + +/** + return the number of elements in a string list +*/ +size_t ev_str_list_length(const char **list) +{ + size_t ret; + for (ret=0;list && list[ret];ret++) /* noop */ ; + return ret; +} + +/** + add an entry to a string list +*/ +const char **ev_str_list_add(const char **list, const char *s) +{ + size_t len = ev_str_list_length(list); + const char **ret; + + ret = talloc_realloc(NULL, list, const char *, len+2); + if (ret == NULL) return NULL; + + ret[len] = talloc_strdup(ret, s); + if (ret[len] == NULL) return NULL; + + ret[len+1] = NULL; + + return ret; +} + + +/** + Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available, + else + if SYSV use O_NDELAY + if BSD use FNDELAY +**/ + +int ev_set_blocking(int fd, bool set) +{ + int val; +#ifdef O_NONBLOCK +#define FLAG_TO_SET O_NONBLOCK +#else +#ifdef SYSV +#define FLAG_TO_SET O_NDELAY +#else /* BSD */ +#define FLAG_TO_SET FNDELAY +#endif +#endif + + if((val = fcntl(fd, F_GETFL, 0)) == -1) + return -1; + if(set) /* Turn blocking on - ie. clear nonblock flag */ + val &= ~FLAG_TO_SET; + else + val |= FLAG_TO_SET; + return fcntl( fd, F_SETFL, val); +#undef FLAG_TO_SET +} + +bool ev_set_close_on_exec(int fd) +{ +#ifdef FD_CLOEXEC + int val; + + val = fcntl(fd, F_GETFD, 0); + if (val >= 0) { + val |= FD_CLOEXEC; + val = fcntl(fd, F_SETFD, val); + if (val != -1) { + return true; + } + } +#endif + return false; +} diff --git a/ldb-2.0.8/lib/tevent/tevent_util.h b/ldb-2.0.8/lib/tevent/tevent_util.h new file mode 100644 index 0000000..eef4a00 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent_util.h @@ -0,0 +1,185 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 1998-2010 + Copyright (C) Jelmer Vernooij 2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* To use these macros you must have a structure containing a next and + prev pointer */ + +#ifndef _DLINKLIST_H +#define _DLINKLIST_H + +/* + February 2010 - changed list format to have a prev pointer from the + list head. This makes DLIST_ADD_END() O(1) even though we only have + one list pointer. + + The scheme is as follows: + + 1) with no entries in the list: + list_head == NULL + + 2) with 1 entry in the list: + list_head->next == NULL + list_head->prev == list_head + + 3) with 2 entries in the list: + list_head->next == element2 + list_head->prev == element2 + element2->prev == list_head + element2->next == NULL + + 4) with N entries in the list: + list_head->next == element2 + list_head->prev == elementN + elementN->prev == element{N-1} + elementN->next == NULL + + This allows us to find the tail of the list by using + list_head->prev, which means we can add to the end of the list in + O(1) time + */ + + +/* + add an element at the front of a list +*/ +#define DLIST_ADD(list, p) \ +do { \ + if (!(list)) { \ + (p)->prev = (list) = (p); \ + (p)->next = NULL; \ + } else { \ + (p)->prev = (list)->prev; \ + (list)->prev = (p); \ + (p)->next = (list); \ + (list) = (p); \ + } \ +} while (0) + +/* + remove an element from a list + Note that the element doesn't have to be in the list. If it + isn't then this is a no-op +*/ +#define DLIST_REMOVE(list, p) \ +do { \ + if ((p) == (list)) { \ + if ((p)->next) (p)->next->prev = (p)->prev; \ + (list) = (p)->next; \ + } else if ((p)->prev && (list) && (p) == (list)->prev) { \ + (p)->prev->next = NULL; \ + (list)->prev = (p)->prev; \ + } else { \ + if ((p)->prev) (p)->prev->next = (p)->next; \ + if ((p)->next) (p)->next->prev = (p)->prev; \ + } \ + if ((p) != (list)) (p)->next = (p)->prev = NULL; \ +} while (0) + +/* + find the head of the list given any element in it. + Note that this costs O(N), so you should avoid this macro + if at all possible! +*/ +#define DLIST_HEAD(p, result_head) \ +do { \ + (result_head) = (p); \ + while (DLIST_PREV(result_head)) (result_head) = (result_head)->prev; \ +} while(0) + +/* return the last element in the list */ +#define DLIST_TAIL(list) ((list)?(list)->prev:NULL) + +/* return the previous element in the list. */ +#define DLIST_PREV(p) (((p)->prev && (p)->prev->next != NULL)?(p)->prev:NULL) + +/* insert 'p' after the given element 'el' in a list. If el is NULL then + this is the same as a DLIST_ADD() */ +#define DLIST_ADD_AFTER(list, p, el) \ +do { \ + if (!(list) || !(el)) { \ + DLIST_ADD(list, p); \ + } else { \ + (p)->prev = (el); \ + (p)->next = (el)->next; \ + (el)->next = (p); \ + if ((p)->next) (p)->next->prev = (p); \ + if ((list)->prev == (el)) (list)->prev = (p); \ + }\ +} while (0) + + +/* + add to the end of a list. +*/ +#define DLIST_ADD_END(list, p) \ +do { \ + if (!(list)) { \ + DLIST_ADD(list, p); \ + } else { \ + DLIST_ADD_AFTER(list, p, (list)->prev); \ + } \ +} while (0) + +/* promote an element to the front of a list */ +#define DLIST_PROMOTE(list, p) \ +do { \ + DLIST_REMOVE(list, p); \ + DLIST_ADD(list, p); \ +} while (0) + +/* + demote an element to the end of a list. +*/ +#define DLIST_DEMOTE(list, p) \ +do { \ + DLIST_REMOVE(list, p); \ + DLIST_ADD_END(list, p); \ +} while (0) + +/* + concatenate two lists - putting all elements of the 2nd list at the + end of the first list. +*/ +#define DLIST_CONCATENATE(list1, list2) \ +do { \ + if (!(list1)) { \ + (list1) = (list2); \ + } else { \ + (list1)->prev->next = (list2); \ + if (list2) { \ + void *_tmplist = (void *)(list1)->prev; \ + (list1)->prev = (list2)->prev; \ + (list2)->prev = _tmplist; \ + } \ + } \ +} while (0) + +#endif /* _DLINKLIST_H */ + +const char **ev_str_list_add(const char **list, const char *s); +int ev_set_blocking(int fd, bool set); +size_t ev_str_list_length(const char **list); +bool ev_set_close_on_exec(int fd); + +/* Defined here so we can build against older talloc versions that don't + * have this define yet. */ +#ifndef TALLOC_FREE +#define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0) +#endif diff --git a/ldb-2.0.8/lib/tevent/tevent_wakeup.c b/ldb-2.0.8/lib/tevent/tevent_wakeup.c new file mode 100644 index 0000000..e217f33 --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent_wakeup.c @@ -0,0 +1,67 @@ +/* + Unix SMB/CIFS implementation. + Infrastructure for async requests + Copyright (C) Volker Lendecke 2008 + Copyright (C) Stefan Metzmacher 2009 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#include "tevent.h" +#include "tevent_internal.h" +#include "tevent_util.h" + +struct tevent_wakeup_state { + struct timeval wakeup_time; +}; + +struct tevent_req *tevent_wakeup_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct timeval wakeup_time) +{ + struct tevent_req *req; + struct tevent_wakeup_state *state; + + req = tevent_req_create(mem_ctx, &state, + struct tevent_wakeup_state); + if (!req) { + return NULL; + } + state->wakeup_time = wakeup_time; + + if (!tevent_req_set_endtime(req, ev, wakeup_time)) { + return tevent_req_post(req, ev); + } + return req; +} + +bool tevent_wakeup_recv(struct tevent_req *req) +{ + enum tevent_req_state state; + uint64_t error; + + if (tevent_req_is_error(req, &state, &error)) { + if (state == TEVENT_REQ_TIMED_OUT) { + return true; + } + } + + return false; +} + diff --git a/ldb-2.0.8/lib/tevent/tevent_wrapper.c b/ldb-2.0.8/lib/tevent/tevent_wrapper.c new file mode 100644 index 0000000..a0e915f --- /dev/null +++ b/ldb-2.0.8/lib/tevent/tevent_wrapper.c @@ -0,0 +1,571 @@ +/* + Infrastructure for event context wrappers + + Copyright (C) Stefan Metzmacher 2014 + + ** NOTE! The following LGPL license applies to the tevent + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#ifdef HAVE_PTHREAD +#include "system/threads.h" +#endif +#define TEVENT_DEPRECATED 1 +#include "tevent.h" +#include "tevent_internal.h" +#include "tevent_util.h" + +static int tevent_wrapper_glue_context_init(struct tevent_context *ev) +{ + tevent_abort(ev, "tevent_wrapper_glue_context_init() called"); + errno = ENOSYS; + return -1; +} + +static struct tevent_fd *tevent_wrapper_glue_add_fd(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + int fd, uint16_t flags, + tevent_fd_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + struct tevent_wrapper_glue *glue = ev->wrapper.glue; + struct tevent_fd *fde = NULL; + + if (glue->destroyed) { + tevent_abort(ev, "add_fd wrapper use after free"); + return NULL; + } + + if (glue->main_ev == NULL) { + errno = EINVAL; + return NULL; + } + + fde = _tevent_add_fd(glue->main_ev, mem_ctx, fd, flags, + handler, private_data, + handler_name, location); + if (fde == NULL) { + return NULL; + } + + fde->wrapper = glue; + + return fde; +} + +static struct tevent_timer *tevent_wrapper_glue_add_timer(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + struct timeval next_event, + tevent_timer_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + struct tevent_wrapper_glue *glue = ev->wrapper.glue; + struct tevent_timer *te = NULL; + + if (glue->destroyed) { + tevent_abort(ev, "add_timer wrapper use after free"); + return NULL; + } + + if (glue->main_ev == NULL) { + errno = EINVAL; + return NULL; + } + + te = _tevent_add_timer(glue->main_ev, mem_ctx, next_event, + handler, private_data, + handler_name, location); + if (te == NULL) { + return NULL; + } + + te->wrapper = glue; + + return te; +} + +static void tevent_wrapper_glue_schedule_immediate(struct tevent_immediate *im, + struct tevent_context *ev, + tevent_immediate_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + struct tevent_wrapper_glue *glue = ev->wrapper.glue; + + if (glue->destroyed) { + tevent_abort(ev, "scheduke_immediate wrapper use after free"); + return; + } + + if (glue->main_ev == NULL) { + tevent_abort(ev, location); + errno = EINVAL; + return; + } + + _tevent_schedule_immediate(im, glue->main_ev, + handler, private_data, + handler_name, location); + + im->wrapper = glue; + + return; +} + +static struct tevent_signal *tevent_wrapper_glue_add_signal(struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + int signum, int sa_flags, + tevent_signal_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ + struct tevent_wrapper_glue *glue = ev->wrapper.glue; + struct tevent_signal *se = NULL; + + if (glue->destroyed) { + tevent_abort(ev, "add_signal wrapper use after free"); + return NULL; + } + + if (glue->main_ev == NULL) { + errno = EINVAL; + return NULL; + } + + se = _tevent_add_signal(glue->main_ev, mem_ctx, + signum, sa_flags, + handler, private_data, + handler_name, location); + if (se == NULL) { + return NULL; + } + + se->wrapper = glue; + + return se; +} + +static int tevent_wrapper_glue_loop_once(struct tevent_context *ev, const char *location) +{ + tevent_abort(ev, "tevent_wrapper_glue_loop_once() called"); + errno = ENOSYS; + return -1; +} + +static int tevent_wrapper_glue_loop_wait(struct tevent_context *ev, const char *location) +{ + tevent_abort(ev, "tevent_wrapper_glue_loop_wait() called"); + errno = ENOSYS; + return -1; +} + +static const struct tevent_ops tevent_wrapper_glue_ops = { + .context_init = tevent_wrapper_glue_context_init, + .add_fd = tevent_wrapper_glue_add_fd, + .set_fd_close_fn = tevent_common_fd_set_close_fn, + .get_fd_flags = tevent_common_fd_get_flags, + .set_fd_flags = tevent_common_fd_set_flags, + .add_timer = tevent_wrapper_glue_add_timer, + .schedule_immediate = tevent_wrapper_glue_schedule_immediate, + .add_signal = tevent_wrapper_glue_add_signal, + .loop_once = tevent_wrapper_glue_loop_once, + .loop_wait = tevent_wrapper_glue_loop_wait, +}; + +static int tevent_wrapper_context_destructor(struct tevent_context *wrap_ev) +{ + struct tevent_wrapper_glue *glue = wrap_ev->wrapper.glue; + struct tevent_context *main_ev = NULL; + struct tevent_fd *fd = NULL, *fn = NULL; + struct tevent_timer *te = NULL, *tn = NULL; + struct tevent_immediate *ie = NULL, *in = NULL; + struct tevent_signal *se = NULL, *sn = NULL; +#ifdef HAVE_PTHREAD + struct tevent_threaded_context *tctx = NULL, *tctxn = NULL; +#endif + + if (glue == NULL) { + tevent_abort(wrap_ev, + "tevent_wrapper_context_destructor() active on main"); + /* static checker support, return below is never reached */ + return -1; + } + + if (glue->destroyed && glue->busy) { + tevent_common_check_double_free(wrap_ev, + "tevent_context wrapper double free"); + } + glue->destroyed = true; + + if (glue->busy) { + return -1; + } + + main_ev = glue->main_ev; + if (main_ev == NULL) { + return 0; + } + + tevent_debug(wrap_ev, TEVENT_DEBUG_TRACE, + "Destroying wrapper context %p \"%s\"\n", + wrap_ev, talloc_get_name(glue->private_state)); + + glue->main_ev = NULL; + DLIST_REMOVE(main_ev->wrapper.list, glue); + +#ifdef HAVE_PTHREAD + for (tctx = main_ev->threaded_contexts; tctx != NULL; tctx = tctxn) { + int ret; + + tctxn = tctx->next; + + if (tctx->event_ctx != glue->wrap_ev) { + continue; + } + + ret = pthread_mutex_lock(&tctx->event_ctx_mutex); + if (ret != 0) { + abort(); + } + + /* + * Indicate to the thread that the tevent_context is + * gone. The counterpart of this is in + * _tevent_threaded_schedule_immediate, there we read + * this under the threaded_context's mutex. + */ + + tctx->event_ctx = NULL; + + ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); + if (ret != 0) { + abort(); + } + + DLIST_REMOVE(main_ev->threaded_contexts, tctx); + } +#endif + + for (fd = main_ev->fd_events; fd; fd = fn) { + fn = fd->next; + + if (fd->wrapper != glue) { + continue; + } + + tevent_fd_set_flags(fd, 0); + + fd->wrapper = NULL; + fd->event_ctx = NULL; + DLIST_REMOVE(main_ev->fd_events, fd); + } + + for (te = main_ev->timer_events; te; te = tn) { + tn = te->next; + + if (te->wrapper != glue) { + continue; + } + + te->wrapper = NULL; + te->event_ctx = NULL; + + if (main_ev->last_zero_timer == te) { + main_ev->last_zero_timer = DLIST_PREV(te); + } + DLIST_REMOVE(main_ev->timer_events, te); + } + + for (ie = main_ev->immediate_events; ie; ie = in) { + in = ie->next; + + if (ie->wrapper != glue) { + continue; + } + + ie->wrapper = NULL; + ie->event_ctx = NULL; + ie->cancel_fn = NULL; + DLIST_REMOVE(main_ev->immediate_events, ie); + } + + for (se = main_ev->signal_events; se; se = sn) { + sn = se->next; + + if (se->wrapper != glue) { + continue; + } + + se->wrapper = NULL; + tevent_cleanup_pending_signal_handlers(se); + } + + return 0; +} + +struct tevent_context *_tevent_context_wrapper_create(struct tevent_context *main_ev, + TALLOC_CTX *mem_ctx, + const struct tevent_wrapper_ops *ops, + void *pstate, + size_t psize, + const char *type, + const char *location) +{ + void **ppstate = (void **)pstate; + struct tevent_context *ev = NULL; + + if (main_ev->wrapper.glue != NULL) { + /* + * stacking of wrappers is not supported + */ + tevent_debug(main_ev->wrapper.glue->main_ev, TEVENT_DEBUG_FATAL, + "%s: %s() stacking not allowed\n", + __func__, location); + errno = EINVAL; + return NULL; + } + + if (main_ev->nesting.allowed) { + /* + * wrappers conflict with nesting + */ + tevent_debug(main_ev, TEVENT_DEBUG_FATAL, + "%s: %s() conflicts with nesting\n", + __func__, location); + errno = EINVAL; + return NULL; + } + + ev = talloc_zero(mem_ctx, struct tevent_context); + if (ev == NULL) { + return NULL; + } + ev->ops = &tevent_wrapper_glue_ops; + + ev->wrapper.glue = talloc_zero(ev, struct tevent_wrapper_glue); + if (ev->wrapper.glue == NULL) { + talloc_free(ev); + return NULL; + } + + talloc_set_destructor(ev, tevent_wrapper_context_destructor); + + ev->wrapper.glue->wrap_ev = ev; + ev->wrapper.glue->main_ev = main_ev; + ev->wrapper.glue->ops = ops; + ev->wrapper.glue->private_state = talloc_zero_size(ev->wrapper.glue, psize); + if (ev->wrapper.glue->private_state == NULL) { + talloc_free(ev); + return NULL; + } + talloc_set_name_const(ev->wrapper.glue->private_state, type); + + DLIST_ADD_END(main_ev->wrapper.list, ev->wrapper.glue); + + *ppstate = ev->wrapper.glue->private_state; + return ev; +} + +bool tevent_context_is_wrapper(struct tevent_context *ev) +{ + if (ev->wrapper.glue != NULL) { + return true; + } + + return false; +} + +_PRIVATE_ +struct tevent_context *tevent_wrapper_main_ev(struct tevent_context *ev) +{ + if (ev == NULL) { + return NULL; + } + + if (ev->wrapper.glue == NULL) { + return ev; + } + + return ev->wrapper.glue->main_ev; +} + +/* + * 32 stack elements should be more than enough + * + * e.g. Samba uses just 8 elements for [un]become_{root,user}() + */ +#define TEVENT_WRAPPER_STACK_SIZE 32 + +static struct tevent_wrapper_stack { + const void *ev_ptr; + const struct tevent_wrapper_glue *wrapper; +} wrapper_stack[TEVENT_WRAPPER_STACK_SIZE]; + +static size_t wrapper_stack_idx; + +_PRIVATE_ +void tevent_wrapper_push_use_internal(struct tevent_context *ev, + struct tevent_wrapper_glue *wrapper) +{ + /* + * ev and wrapper need to belong together! + * It's also fine to only have a raw ev + * without a wrapper. + */ + if (unlikely(ev->wrapper.glue != wrapper)) { + tevent_abort(ev, "tevent_wrapper_push_use_internal() invalid arguments"); + return; + } + + if (wrapper != NULL) { + if (unlikely(wrapper->busy)) { + tevent_abort(ev, "wrapper already busy!"); + return; + } + wrapper->busy = true; + } + + if (unlikely(wrapper_stack_idx >= TEVENT_WRAPPER_STACK_SIZE)) { + tevent_abort(ev, "TEVENT_WRAPPER_STACK_SIZE overflow"); + return; + } + + wrapper_stack[wrapper_stack_idx] = (struct tevent_wrapper_stack) { + .ev_ptr = ev, + .wrapper = wrapper, + }; + wrapper_stack_idx++; +} + +_PRIVATE_ +void tevent_wrapper_pop_use_internal(const struct tevent_context *__ev_ptr, + struct tevent_wrapper_glue *wrapper) +{ + struct tevent_context *main_ev = NULL; + + /* + * Note that __ev_ptr might a a stale pointer and should not + * be touched, we just compare the pointer value in order + * to enforce the stack order. + */ + + if (wrapper != NULL) { + main_ev = wrapper->main_ev; + } + + if (unlikely(wrapper_stack_idx == 0)) { + tevent_abort(main_ev, "tevent_wrapper stack already empty"); + return; + } + wrapper_stack_idx--; + + if (wrapper != NULL) { + wrapper->busy = false; + } + + if (wrapper_stack[wrapper_stack_idx].ev_ptr != __ev_ptr) { + tevent_abort(main_ev, "tevent_wrapper_pop_use mismatch ev!"); + return; + } + if (wrapper_stack[wrapper_stack_idx].wrapper != wrapper) { + tevent_abort(main_ev, "tevent_wrapper_pop_use mismatch wrap!"); + return; + } + + if (wrapper == NULL) { + return; + } + + if (wrapper->destroyed) { + /* + * Notice that we can't use TALLOC_FREE() + * here because wrapper is a talloc child + * of wrapper->wrap_ev. + */ + talloc_free(wrapper->wrap_ev); + } +} + +bool _tevent_context_push_use(struct tevent_context *ev, + const char *location) +{ + bool ok; + + if (ev->wrapper.glue == NULL) { + tevent_wrapper_push_use_internal(ev, NULL); + return true; + } + + if (ev->wrapper.glue->main_ev == NULL) { + return false; + } + + tevent_wrapper_push_use_internal(ev, ev->wrapper.glue); + ok = ev->wrapper.glue->ops->before_use(ev->wrapper.glue->wrap_ev, + ev->wrapper.glue->private_state, + ev->wrapper.glue->main_ev, + location); + if (!ok) { + tevent_wrapper_pop_use_internal(ev, ev->wrapper.glue); + return false; + } + + return true; +} + +void _tevent_context_pop_use(struct tevent_context *ev, + const char *location) +{ + tevent_wrapper_pop_use_internal(ev, ev->wrapper.glue); + + if (ev->wrapper.glue == NULL) { + return; + } + + if (ev->wrapper.glue->main_ev == NULL) { + return; + } + + ev->wrapper.glue->ops->after_use(ev->wrapper.glue->wrap_ev, + ev->wrapper.glue->private_state, + ev->wrapper.glue->main_ev, + location); +} + +bool tevent_context_same_loop(struct tevent_context *ev1, + struct tevent_context *ev2) +{ + struct tevent_context *main_ev1 = tevent_wrapper_main_ev(ev1); + struct tevent_context *main_ev2 = tevent_wrapper_main_ev(ev2); + + if (main_ev1 == NULL) { + return false; + } + + if (main_ev1 == main_ev2) { + return true; + } + + return false; +} diff --git a/ldb-2.0.8/lib/tevent/wscript b/ldb-2.0.8/lib/tevent/wscript new file mode 100644 index 0000000..ded182a --- /dev/null +++ b/ldb-2.0.8/lib/tevent/wscript @@ -0,0 +1,142 @@ +#!/usr/bin/env python + +APPNAME = 'tevent' +VERSION = '0.10.0' + +import sys, os + +# find the buildtools directory +top = '.' +while not os.path.exists(top+'/buildtools') and len(top.split('/')) < 5: + top = top + '/..' +sys.path.insert(0, top + '/buildtools/wafsamba') + +out = 'bin' + +import wafsamba +from wafsamba import samba_dist, samba_utils +from waflib import Options, Logs, Context + +samba_dist.DIST_DIRS('lib/tevent:. lib/replace:lib/replace lib/talloc:lib/talloc buildtools:buildtools third_party/waf:third_party/waf') + +def options(opt): + opt.BUILTIN_DEFAULT('replace') + opt.PRIVATE_EXTENSION_DEFAULT('tevent', noextension='tevent') + opt.RECURSE('lib/replace') + opt.RECURSE('lib/talloc') + + +def configure(conf): + conf.RECURSE('lib/replace') + conf.RECURSE('lib/talloc') + + conf.env.standalone_tevent = conf.IN_LAUNCH_DIR() + + if not conf.env.standalone_tevent: + if conf.CHECK_BUNDLED_SYSTEM_PKG('tevent', minversion=VERSION, + onlyif='talloc', implied_deps='replace talloc'): + conf.define('USING_SYSTEM_TEVENT', 1) + if not conf.env.disable_python and \ + conf.CHECK_BUNDLED_SYSTEM_PYTHON('pytevent', 'tevent', minversion=VERSION): + conf.define('USING_SYSTEM_PYTEVENT', 1) + + if conf.CHECK_FUNCS('epoll_create', headers='sys/epoll.h'): + conf.DEFINE('HAVE_EPOLL', 1) + + tevent_num_signals = 64 + v = conf.CHECK_VALUEOF('NSIG', headers='signal.h') + if v is not None: + tevent_num_signals = max(tevent_num_signals, v) + v = conf.CHECK_VALUEOF('_NSIG', headers='signal.h') + if v is not None: + tevent_num_signals = max(tevent_num_signals, v) + v = conf.CHECK_VALUEOF('SIGRTMAX', headers='signal.h') + if v is not None: + tevent_num_signals = max(tevent_num_signals, v) + v = conf.CHECK_VALUEOF('SIGRTMIN', headers='signal.h') + if v is not None: + tevent_num_signals = max(tevent_num_signals, v*2) + + if not conf.CONFIG_SET('USING_SYSTEM_TEVENT'): + conf.DEFINE('TEVENT_NUM_SIGNALS', tevent_num_signals) + + conf.SAMBA_CHECK_PYTHON() + conf.SAMBA_CHECK_PYTHON_HEADERS() + + conf.SAMBA_CONFIG_H() + + conf.SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS() + +def build(bld): + bld.RECURSE('lib/replace') + bld.RECURSE('lib/talloc') + + SRC = '''tevent.c tevent_debug.c tevent_fd.c tevent_immediate.c + tevent_queue.c tevent_req.c tevent_wrapper.c + tevent_poll.c tevent_threads.c + tevent_signal.c tevent_standard.c tevent_timed.c tevent_util.c tevent_wakeup.c''' + + if bld.CONFIG_SET('HAVE_EPOLL'): + SRC += ' tevent_epoll.c' + + if bld.CONFIG_SET('HAVE_SOLARIS_PORTS'): + SRC += ' tevent_port.c' + + if bld.env.standalone_tevent: + bld.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig' + private_library = False + else: + private_library = True + + if not bld.CONFIG_SET('USING_SYSTEM_TEVENT'): + tevent_deps = 'replace talloc' + if bld.CONFIG_SET('HAVE_PTHREAD'): + tevent_deps += ' pthread' + + bld.SAMBA_LIBRARY('tevent', + SRC, + deps=tevent_deps, + enabled= not bld.CONFIG_SET('USING_SYSTEM_TEVENT'), + includes='.', + abi_directory='ABI', + abi_match='tevent_* _tevent_*', + vnum=VERSION, + public_headers=('' if private_library else 'tevent.h'), + public_headers_install=not private_library, + pc_files='tevent.pc', + private_library=private_library) + + if not bld.CONFIG_SET('USING_SYSTEM_PYTEVENT') and not bld.env.disable_python: + bld.SAMBA_PYTHON('_tevent', + 'pytevent.c', + deps='tevent', + realname='_tevent.so', + cflags='-DPACKAGE_VERSION=\"%s\"' % VERSION) + + + bld.INSTALL_WILDCARD('${PYTHONARCHDIR}', 'tevent.py', flat=False) + + # install out various python scripts for use by make test + bld.SAMBA_SCRIPT('tevent_python', + pattern='tevent.py', + installdir='python') + + +def test(ctx): + '''test tevent''' + print("The tevent testsuite is part of smbtorture in samba4") + + samba_utils.ADD_LD_LIBRARY_PATH('bin/shared') + samba_utils.ADD_LD_LIBRARY_PATH('bin/shared/private') + + pyret = samba_utils.RUN_PYTHON_TESTS(['bindings.py']) + sys.exit(pyret) + + +def dist(): + '''makes a tarball for distribution''' + samba_dist.dist() + +def reconfigure(ctx): + '''reconfigure if config scripts have changed''' + samba_utils.reconfigure(ctx) diff --git a/ldb-2.0.8/lib/util/attr.h b/ldb-2.0.8/lib/util/attr.h new file mode 100644 index 0000000..8e542c1 --- /dev/null +++ b/ldb-2.0.8/lib/util/attr.h @@ -0,0 +1,101 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jelmer Vernooij 2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef __UTIL_ATTR_H__ +#define __UTIL_ATTR_H__ + +#ifndef _UNUSED_ +#ifdef __GNUC__ +/** gcc attribute used on function parameters so that it does not emit + * warnings about them being unused. **/ +# define _UNUSED_ __attribute__ ((unused)) +#else +# define _UNUSED_ +/** Feel free to add definitions for other compilers here. */ +#endif +#endif +#ifndef UNUSED +#define UNUSED(param) param _UNUSED_ +#endif + +#ifndef _DEPRECATED_ +#ifdef HAVE___ATTRIBUTE__ +#define _DEPRECATED_ __attribute__ ((deprecated)) +#else +#define _DEPRECATED_ +#endif +#endif + +#ifndef _WARN_UNUSED_RESULT_ +#ifdef HAVE___ATTRIBUTE__ +#define _WARN_UNUSED_RESULT_ __attribute__ ((warn_unused_result)) +#else +#define _WARN_UNUSED_RESULT_ +#endif +#endif + +#ifndef _NORETURN_ +#ifdef HAVE___ATTRIBUTE__ +#define _NORETURN_ __attribute__ ((noreturn)) +#else +#define _NORETURN_ +#endif +#endif + +#ifndef _PURE_ +#ifdef HAVE___ATTRIBUTE__ +#define _PURE_ __attribute__((pure)) +#else +#define _PURE_ +#endif +#endif + +#ifndef NONNULL +#ifdef HAVE___ATTRIBUTE__ +#define NONNULL(param) param __attribute__((nonnull)) +#else +#define NONNULL(param) param +#endif +#endif + +#ifndef PRINTF_ATTRIBUTE +#ifdef HAVE___ATTRIBUTE__ +/** Use gcc attribute to check printf fns. a1 is the 1-based index of + * the parameter containing the format, and a2 the index of the first + * argument. Note that some gcc 2.x versions don't handle this + * properly **/ +#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) +#else +#define PRINTF_ATTRIBUTE(a1, a2) +#endif +#endif + +#ifndef FORMAT_ATTRIBUTE +#ifdef HAVE___ATTRIBUTE__ +/** Use gcc attribute to check printf fns. a1 is argument to format() + * in the above macro. This is needed to support Heimdal's printf + * decorations. Note that some gcc 2.x versions don't handle this + * properly. **/ +#define FORMAT_ATTRIBUTE(a) __attribute__ ((format a)) +#else +#define FORMAT_ATTRIBUTE(a) +#endif +#endif + +#endif /* __UTIL_ATTR_H__ */ diff --git a/ldb-2.0.8/lib/util/binsearch.h b/ldb-2.0.8/lib/util/binsearch.h new file mode 100644 index 0000000..8ae9da2 --- /dev/null +++ b/ldb-2.0.8/lib/util/binsearch.h @@ -0,0 +1,121 @@ +/* + Unix SMB/CIFS implementation. + + a generic binary search macro + + Copyright (C) Andrew Tridgell 2009 + + ** NOTE! The following LGPL license applies to the binsearch.h + ** header. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#ifndef _BINSEARCH_H +#define _BINSEARCH_H + +/* a binary array search, where the array is an array of pointers to structures, + and we want to find a match for 'target' on 'field' in those structures. + + Inputs: + array: base pointer to an array of structures + arrray_size: number of elements in the array + field: the name of the field in the structure we are keying off + target: the field value we are looking for + comparison_fn: the comparison function + result: where the result of the search is put + + if the element is found, then 'result' is set to point to the found array element. If not, + then 'result' is set to NULL. + + The array is assumed to be sorted by the same comparison_fn as the + search (with, for example, qsort) + */ +#define BINARY_ARRAY_SEARCH_P(array, array_size, field, target, comparison_fn, result) do { \ + int32_t _b, _e; \ + (result) = NULL; \ + if (array_size) { for (_b = 0, _e = (array_size)-1; _b <= _e; ) { \ + int32_t _i = (_b+_e)/2; \ + int _r = comparison_fn(target, array[_i]->field); \ + if (_r == 0) { (result) = array[_i]; break; } \ + if (_r < 0) _e = _i - 1; else _b = _i + 1; \ + }} } while (0) + +/* + like BINARY_ARRAY_SEARCH_P, but assumes that the array is an array + of structures, rather than pointers to structures + + result points to the found structure, or NULL + */ +#define BINARY_ARRAY_SEARCH(array, array_size, field, target, comparison_fn, result) do { \ + int32_t _b, _e; \ + (result) = NULL; \ + if (array_size) { for (_b = 0, _e = (array_size)-1; _b <= _e; ) { \ + int32_t _i = (_b+_e)/2; \ + int _r = comparison_fn(target, array[_i].field); \ + if (_r == 0) { (result) = &array[_i]; break; } \ + if (_r < 0) _e = _i - 1; else _b = _i + 1; \ + }} } while (0) + +/* + like BINARY_ARRAY_SEARCH_P, but assumes that the array is an array + of elements, rather than pointers to structures + + result points to the found structure, or NULL + */ +#define BINARY_ARRAY_SEARCH_V(array, array_size, target, comparison_fn, result) do { \ + int32_t _b, _e; \ + (result) = NULL; \ + if (array_size) { for (_b = 0, _e = (array_size)-1; _b <= _e; ) { \ + int32_t _i = (_b+_e)/2; \ + int _r = comparison_fn(target, array[_i]); \ + if (_r == 0) { (result) = &array[_i]; break; } \ + if (_r < 0) _e = _i - 1; else _b = _i + 1; \ + }} } while (0) + + +/* + like BINARY_ARRAY_SEARCH_V, but if an exact result is not found, the 'next' + argument will point to the element after the place where the exact result + would have been. If an exact result is found, 'next' will be NULL. If the + target is beyond the end of the list, both 'exact' and 'next' will be NULL. + Unlike other binsearch macros, where there are several elements that compare + the same, the exact result will always point to the first one. + + If you don't care to distinguish between the 'greater than' and 'equals' + cases, you can use the same pointer for both 'exact' and 'next'. + + As with all the binsearch macros, the comparison function is always called + with the search term first. + */ +#define BINARY_ARRAY_SEARCH_GTE(array, array_size, target, comparison_fn, \ + exact, next) do { \ + int32_t _b, _e; \ + (exact) = NULL; (next) = NULL; \ + if ((array_size) > 0) { \ + for (_b = 0, _e = (array_size)-1; _b <= _e; ) { \ + int32_t _i = (_b + _e) / 2; \ + int _r = comparison_fn(target, &array[_i]); \ + if (_r == 0) { \ + (exact) = &array[_i]; \ + _e = _i - 1; \ + } else if (_r < 0) { _e = _i - 1; \ + } else { _b = _i + 1; } \ + } \ + if ((exact) == NULL &&_b < (array_size)) { \ + (next) = &array[_b]; \ + } } } while (0) + +#endif diff --git a/ldb-2.0.8/mainpage.dox b/ldb-2.0.8/mainpage.dox new file mode 100644 index 0000000..bbd8d9c --- /dev/null +++ b/ldb-2.0.8/mainpage.dox @@ -0,0 +1,80 @@ +/** + +\mainpage ldb + +\section Overview + +ldb is a LDAP-like embedded database. It is not at all LDAP standards +compliant, so if you want a standards compliant database then please +see the excellent OpenLDAP +project.

      + +What ldb does is provide a fast database with an LDAP-like API +designed to be used within an application. In some ways it can be seen +as a intermediate solution between key-value pair databases and a real +LDAP database.

      + +ldb is the database engine used in Samba4. + +\section Features + +The main features that separate ldb from other solutions are: + - Safe multi-reader, multi-writer, using byte range locking + - LDAP-like API + - fast operation + - choice of local tdb, local sqlite3 or remote LDAP backends + - integration with talloc + - schema-less operation, for trivial setup + - modules for extensions (such as schema support) + - easy setup of indexes and attribute properties + - ldbedit tool for database editing (reminiscent of 'vipw') + - ldif for import/export + +\section Documentation + +ldb has limited programmer and administrator documentation: + - a list of functions + - a list of examples + - a list of data structures + - a list of constants + +If you need more information than is presented in this document, you +may wish to look at the source code, especially the source code in the +tools directory. + +ldb makes use of the LDAP Data Interchange Format (LDIF), which is +documented in RFC +2849. + +\section Support + +ldb does not currently have its own mailing list or bug tracking +system. For now, please use the samba-technical +mailing list, and the Samba +bugzilla bug tracking system. + +\section Download + +You can download the latest release either via rsync or anonymous +svn. To fetch via svn use the following commands: + +\verbatim + svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/ldb ldb + svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/tdb tdb + svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/talloc talloc +\endverbatim + +To fetch via rsync use these commands: + +\verbatim + rsync -Pavz samba.org::ftp/unpacked/samba4/source/lib/ldb . + rsync -Pavz samba.org::ftp/unpacked/samba4/source/lib/tdb . + rsync -Pavz samba.org::ftp/unpacked/samba4/source/lib/talloc . +\endverbatim + +\section Credits + +ldb is another product of the prolific Andrew Tridgell. + +*/ diff --git a/ldb-2.0.8/man/ldb.3.xml b/ldb-2.0.8/man/ldb.3.xml new file mode 100644 index 0000000..b832d0c --- /dev/null +++ b/ldb-2.0.8/man/ldb.3.xml @@ -0,0 +1,265 @@ + + + + + + ldb + 3 + LDB + System Administration tools + 1.1 + + + + ldb + The Samba Project + A light-weight database library + + + + #include <ldb.h> + + + + description + + +ldb is a light weight embedded database library and API. With a +programming interface that is very similar to LDAP, ldb can store its +data either in a tdb(3) database or in a real LDAP database. + + + +When used with the tdb backend ldb does not require any database +daemon. Instead, ldb function calls are processed immediately by the +ldb library, which does IO directly on the database, while allowing +multiple readers/writers using operating system byte range locks. This +leads to an API with very low overheads, often resulting in speeds of +more than 10x what can be achieved with a more traditional LDAP +architecture. + + + +In a taxonomy of databases ldb would sit half way between key/value +pair databases (such as berkley db or tdb) and a full LDAP +database. With a structured attribute oriented API like LDAP and good +indexing capabilities, ldb can be used for quite sophisticated +applications that need a light weight database, without the +administrative overhead of a full LDAP installation. + + + +Included with ldb are a number of useful command line tools for +manipulating a ldb database. These tools are similar in style to the +equivalent ldap command line tools. + + + +In its default mode of operation with a tdb backend, ldb can also be +seen as a "schema-less LDAP". By default ldb does not require a +schema, which greatly reduces the complexity of getting started with +ldb databases. As the complexity of you application grows you can take +advantage of some of the optional schema-like attributes that ldb +offers, or you can migrate to using the full LDAP api while keeping +your exiting ldb code. + + + +If you are new to ldb, then I suggest starting with the manual pages +for ldbsearch(1) and ldbedit(1), and experimenting with a local +database. Then I suggest you look at the ldb_connect(3) and +ldb_search(3) manual pages. + + + + + TOOLS + + + + ldbsearch(1) + - command line ldb search utility + + + + ldbedit(1) + - edit all or part of a ldb database using your favourite editor + + + + ldbadd(1) + - add records to a ldb database using LDIF formatted input + + + + ldbdel(1) + - delete records from a ldb database + + + + ldbmodify(1) + - modify records in a ldb database using LDIF formatted input + + + + + + FUNCTIONS + + + + ldb_connect(3) + - connect to a ldb backend + + + + ldb_search(3) + - perform a database search + + + + ldb_add(3) + - add a record to the database + + + + ldb_delete(3) + - delete a record from the database + + + + ldb_modify(3) + - modify a record in the database + + + + ldb_errstring(3) + - retrieve extended error information from the last operation + + + + ldb_ldif_write(3) + - write a LDIF formatted message + + + + ldb_ldif_write_file(3) + - write a LDIF formatted message to a file + + + + ldb_ldif_read(3) + - read a LDIF formatted message + + + + ldb_ldif_read_free(3) + - free the result of a ldb_ldif_read() + + + + ldb_ldif_read_file(3) + - read a LDIF message from a file + + + + ldb_ldif_read_string(3) + - read a LDIF message from a string + + + + ldb_msg_find_element(3) + - find an element in a ldb_message + + + + ldb_val_equal_exact(3) + - compare two ldb_val structures + + + + ldb_msg_find_val(3) + - find an element by value + + + + ldb_msg_add_empty(3) + - add an empty message element to a ldb_message + + + + + ldb_msg_add(3) + - add a non-empty message element to a ldb_message + + + + + ldb_msg_element_compare(3) + - compare two ldb_message_element structures + + + + + ldb_msg_find_int(3) + - return an integer value from a ldb_message + + + + + ldb_msg_find_uint(3) + - return an unsigned integer value from a ldb_message + + + + + ldb_msg_find_double(3) + - return a double value from a ldb_message + + + + + ldb_msg_find_string(3) + - return a string value from a ldb_message + + + + + ldb_set_alloc(3) + - set the memory allocation function to be used by ldb + + + + + ldb_set_debug(3) + - set a debug handler to be used by ldb + + + + + ldb_set_debug_stderr(3) + - set a debug handler for stderr output + + + + + + Author + + + ldb was written by + Andrew Tridgell. + + + +If you wish to report a problem or make a suggestion then please see +the web site for +current contact and maintainer information. + + + +ldb is released under the GNU Lesser General Public License version 2 +or later. Please see the file COPYING for license details. + + + diff --git a/ldb-2.0.8/man/ldbadd.1.xml b/ldb-2.0.8/man/ldbadd.1.xml new file mode 100644 index 0000000..4736b3b --- /dev/null +++ b/ldb-2.0.8/man/ldbadd.1.xml @@ -0,0 +1,108 @@ + + + + + + ldbadd + 1 + LDB + System Administration tools + 1.1 + + + + + ldbadd + Command-line utility for adding records to an LDB + + + + + ldbadd + -h + -H LDB-URL + ldif-file1 + ldif-file2 + ... + + + + + DESCRIPTION + + ldbadd adds records to an ldb(3) database. It reads + the ldif(5) files specified on the command line and adds + the records from these files to the LDB database, which is specified + by the -H option or the LDB_URL environment variable. + + + If - is specified as a ldb file, the ldif input is read from + standard input. + + + + + + OPTIONS + + + + -h + + Show list of available options. + + + + -H <ldb-url> + + LDB URL to connect to. See ldb(3) for details. + + + + + + + + + ENVIRONMENT + + + LDB_URL + LDB URL to connect to (can be overridden by using the + -H command-line option.) + + + + + + + VERSION + + This man page is correct for version 1.1 of LDB. + + + + SEE ALSO + + ldb(3), ldbmodify, ldbdel, ldif(5) + + + + + AUTHOR + + ldb was written by + Andrew Tridgell. + + + +If you wish to report a problem or make a suggestion then please see +the web site for +current contact and maintainer information. + + + This manpage was written by Jelmer Vernooij. + + + + diff --git a/ldb-2.0.8/man/ldbdel.1.xml b/ldb-2.0.8/man/ldbdel.1.xml new file mode 100644 index 0000000..c4cd450 --- /dev/null +++ b/ldb-2.0.8/man/ldbdel.1.xml @@ -0,0 +1,108 @@ + + + + + + ldbdel + 1 + LDB + System Administration tools + 1.1 + + + + + ldbdel + Command-line program for deleting LDB records + + + + + ldbdel + -h + -H LDB-URL + dn + ... + + + + + DESCRIPTION + + ldbdel deletes records from an ldb(3) database. + It deletes the records identified by the dn's specified + on the command-line. + + ldbdel uses either the database that is specified with + the -H option or the database specified by the LDB_URL environment + variable. + + + + + + OPTIONS + + + + -h + + Show list of available options. + + + + -H <ldb-url> + + LDB URL to connect to. See ldb(3) for details. + + + + + + + + + ENVIRONMENT + + + LDB_URL + LDB URL to connect to (can be overridden by using the + -H command-line option.) + + + + + + + VERSION + + This man page is correct for version 1.1 of LDB. + + + + SEE ALSO + + ldb(3), ldbmodify, ldbadd, ldif(5) + + + + + AUTHOR + + ldb was written by + Andrew Tridgell. + + + +If you wish to report a problem or make a suggestion then please see +the web site for +current contact and maintainer information. + + + ldbdel was written by Andrew Tridgell. + + This manpage was written by Jelmer Vernooij. + + + + diff --git a/ldb-2.0.8/man/ldbedit.1.xml b/ldb-2.0.8/man/ldbedit.1.xml new file mode 100644 index 0000000..627d20c --- /dev/null +++ b/ldb-2.0.8/man/ldbedit.1.xml @@ -0,0 +1,203 @@ + + + + + + ldbedit + 1 + LDB + System Administration tools + 1.1 + + + + + ldbedit + Edit LDB databases using your preferred editor + + + + + ldbedit + -? + --usage + -s base|one|sub + -b basedn + -a + -e editor + -H LDB-URL + expression + attributes + + + + + DESCRIPTION + + ldbedit is a utility that allows you to edit LDB entries (in + tdb files, sqlite files or LDAP servers) using your preferred editor. + ldbedit generates an LDIF file based on your query, allows you to edit + the LDIF, and then merges that LDIF back into the LDB backend. + + + + + + + OPTIONS + + + + -? + --help + + + Show list of available options, and a phrase describing what that option + does. + + + + + + --usage + + + Show list of available options. This is similar to the help option, + however it does not provide any description, and is hence shorter. + + + + + + -H <ldb-url> + + + LDB URL to connect to. For a tdb database, + this will be of the form + tdb://filename. + For a LDAP connection over unix domain + sockets, this will be of the form + ldapi://socket. For + a (potentially remote) LDAP connection over + TCP, this will be of the form + ldap://hostname. For + an SQLite database, this will be of the form + sqlite://filename. + + + + + + -s one|sub|base + Search scope to use. One-level, subtree or base. + + + + -a + -all + + Edit all records. This allows you to + apply the same change to a number of records + at once. You probably want to combine this + with an expression of the form + "objectclass=*". + + + + + + -e editor + --editor editor + + Specify the editor that should be used (overrides + the VISUAL and EDITOR environment + variables). If this option is not used, and + neither VISUAL nor EDITOR environment variables + are set, then the vi editor will be used. + + + + + + -b basedn + Specify Base Distinguished Name to use. + + + + -v + --verbose + + Make ldbedit more verbose about the + operations that are being performed. Without + this option, ldbedit will only provide a + summary change line. + + + + + + + + + + ENVIRONMENT + + + + LDB_URL + + LDB URL to connect to. This can be + overridden by using the -H command-line option.) + + + + + VISUAL and EDITOR + + + Environment variables used to determine what + editor to use. VISUAL takes precedence over + EDITOR, and both are overridden by the + -e command-line option. + + + + + + + + + VERSION + + This man page is correct for version 1.1 of LDB. + + + + SEE ALSO + + ldb(3), ldbmodify(1), ldbdel(1), ldif(5), vi(1) + + + + + AUTHOR + + + ldb was written by + Andrew Tridgell. + + + + If you wish to report a problem or make a suggestion then please see + the web site for + current contact and maintainer information. + + + + This manpage was written by Jelmer Vernooij and updated + by Brad Hards. + + + + + diff --git a/ldb-2.0.8/man/ldbmodify.1.xml b/ldb-2.0.8/man/ldbmodify.1.xml new file mode 100644 index 0000000..ddeeee7 --- /dev/null +++ b/ldb-2.0.8/man/ldbmodify.1.xml @@ -0,0 +1,96 @@ + + + + + + ldbmodify + 1 + LDB + System Administration tools + 1.1 + + + + + ldbmodify + Modify records in a LDB database + + + + + ldbmodify + -H LDB-URL + ldif-file + + + + + DESCRIPTION + + + ldbmodify changes, adds and deletes records in a LDB database. + The changes that should be made to the LDB database are read from + the specified LDIF-file. If - is specified as the filename, input is read from stdin. + + + For now, see ldapmodify(1) for details on the LDIF file format. + + + + + + OPTIONS + + + + -H <ldb-url> + + LDB URL to connect to. See ldb(3) for details. + + + + + + + ENVIRONMENT + + + LDB_URL + LDB URL to connect to (can be overridden by using the + -H command-line option.) + + + + + + + VERSION + + This man page is correct for version 1.1 of LDB. + + + + SEE ALSO + + ldb(3), ldbedit + + + + + AUTHOR + + ldb was written by + Andrew Tridgell. + + + +If you wish to report a problem or make a suggestion then please see +the web site for +current contact and maintainer information. + + + This manpage was written by Jelmer Vernooij. + + + + diff --git a/ldb-2.0.8/man/ldbrename.1.xml b/ldb-2.0.8/man/ldbrename.1.xml new file mode 100644 index 0000000..897c40e --- /dev/null +++ b/ldb-2.0.8/man/ldbrename.1.xml @@ -0,0 +1,110 @@ + + + + + + ldbrename + 1 + LDB + System Administration tools + 1.1 + + + + + ldbrename + Edit LDB databases using your favorite editor + + + + + ldbrename + -h + -o options + olddn + newdn + + + + + DESCRIPTION + + ldbrename is a utility that allows you to rename trees in + an LDB database based by DN. This utility takes + two arguments: the original + DN name of the top element and the DN to change it to. + + + + + + + OPTIONS + + + + -h + + Show list of available options. + + + + -H <ldb-url> + + LDB URL to connect to. See ldb(3) for details. + + + + + -o options + Extra ldb options, such as + modules. + + + + + + + + ENVIRONMENT + + + LDB_URL + LDB URL to connect to (can be overridden by using the + -H command-line option.) + + + + + + + VERSION + + This man page is correct for version 1.1 of LDB. + + + + SEE ALSO + + ldb(3), ldbmodify, ldbdel, ldif(5) + + + + + AUTHOR + + ldb was written by + Andrew Tridgell. + + + +If you wish to report a problem or make a suggestion then please see +the web site for +current contact and maintainer information. + + + This manpage was written by Jelmer Vernooij. + + + + diff --git a/ldb-2.0.8/man/ldbsearch.1.xml b/ldb-2.0.8/man/ldbsearch.1.xml new file mode 100644 index 0000000..b853992 --- /dev/null +++ b/ldb-2.0.8/man/ldbsearch.1.xml @@ -0,0 +1,122 @@ + + + + + + ldbsearch + 1 + LDB + System Administration tools + 1.1 + + + + + ldbsearch + Search for records in a LDB database + + + + + ldbsearch + -h + -s base|one|sub + -b basedn + -i + -H LDB-URL + expression + attributes + + + + + DESCRIPTION + + ldbsearch searches a LDB database for records matching the + specified expression (see the ldapsearch(1) manpage for + a description of the expression format). For each + record, the specified attributes are printed. + + + + + + + OPTIONS + + + + -h + + Show list of available options. + + + + -H <ldb-url> + + LDB URL to connect to. See ldb(3) for details. + + + + + -s one|sub|base + Search scope to use. One-level, subtree or base. + + + + -i + Read search expressions from stdin. + + + + -b basedn + Specify Base DN to use. + + + + + + + + ENVIRONMENT + + + LDB_URL + LDB URL to connect to (can be overridden by using the + -H command-line option.) + + + + + + + VERSION + + This man page is correct for version 1.1 of LDB. + + + + SEE ALSO + + ldb(3), ldbedit(1) + + + + + AUTHOR + + ldb was written by + Andrew Tridgell. + + + +If you wish to report a problem or make a suggestion then please see +the web site for +current contact and maintainer information. + + + This manpage was written by Jelmer Vernooij. + + + + diff --git a/ldb-2.0.8/modules/asq.c b/ldb-2.0.8/modules/asq.c new file mode 100644 index 0000000..7482de8 --- /dev/null +++ b/ldb-2.0.8/modules/asq.c @@ -0,0 +1,416 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2005-2008 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb attribute scoped query control module + * + * Description: this module searches all the objects pointed by + * the DNs contained in the references attribute + * + * Author: Simo Sorce + */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb_module.h" + +struct asq_context { + + enum {ASQ_SEARCH_BASE, ASQ_SEARCH_MULTI} step; + + struct ldb_module *module; + struct ldb_request *req; + + struct ldb_asq_control *asq_ctrl; + + const char * const *req_attrs; + char *req_attribute; + enum { + ASQ_CTRL_SUCCESS = 0, + ASQ_CTRL_INVALID_ATTRIBUTE_SYNTAX = 21, + ASQ_CTRL_UNWILLING_TO_PERFORM = 53, + ASQ_CTRL_AFFECTS_MULTIPLE_DSA = 71 + } asq_ret; + + struct ldb_reply *base_res; + + struct ldb_request **reqs; + unsigned int num_reqs; + unsigned int cur_req; + + struct ldb_control **controls; +}; + +static struct asq_context *asq_context_init(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + struct asq_context *ac; + + ldb = ldb_module_get_ctx(module); + + ac = talloc_zero(req, struct asq_context); + if (ac == NULL) { + ldb_oom(ldb); + return NULL; + } + + ac->module = module; + ac->req = req; + + return ac; +} + +static int asq_search_continue(struct asq_context *ac); + +static int asq_search_terminate(struct asq_context *ac) +{ + struct ldb_asq_control *asq; + unsigned int i; + + if (ac->controls) { + for (i = 0; ac->controls[i]; i++) /* count em */ ; + } else { + i = 0; + } + + ac->controls = talloc_realloc(ac, ac->controls, struct ldb_control *, i + 2); + + if (ac->controls == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->controls[i] = talloc(ac->controls, struct ldb_control); + if (ac->controls[i] == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->controls[i]->oid = LDB_CONTROL_ASQ_OID; + ac->controls[i]->critical = 0; + + asq = talloc_zero(ac->controls[i], struct ldb_asq_control); + if (asq == NULL) + return LDB_ERR_OPERATIONS_ERROR; + + asq->result = ac->asq_ret; + + ac->controls[i]->data = asq; + + ac->controls[i + 1] = NULL; + + return ldb_module_done(ac->req, ac->controls, NULL, LDB_SUCCESS); +} + +static int asq_base_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct asq_context *ac; + int ret; + + ac = talloc_get_type(req->context, struct asq_context); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + switch (ares->type) { + case LDB_REPLY_ENTRY: + ac->base_res = talloc_move(ac, &ares); + break; + + case LDB_REPLY_REFERRAL: + /* ignore referrals */ + talloc_free(ares); + break; + + case LDB_REPLY_DONE: + + talloc_free(ares); + + /* next step */ + ret = asq_search_continue(ac); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, ret); + } + break; + + } + return LDB_SUCCESS; +} + +static int asq_reqs_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct asq_context *ac; + int ret; + + ac = talloc_get_type(req->context, struct asq_context); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + switch (ares->type) { + case LDB_REPLY_ENTRY: + /* pass the message up to the original callback as we + * do not have to elaborate on it any further */ + ret = ldb_module_send_entry(ac->req, ares->message, ares->controls); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, ret); + } + talloc_free(ares); + break; + + case LDB_REPLY_REFERRAL: + /* ignore referrals */ + talloc_free(ares); + break; + + case LDB_REPLY_DONE: + + talloc_free(ares); + + ret = asq_search_continue(ac); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, ret); + } + break; + } + + return LDB_SUCCESS; +} + +static int asq_build_first_request(struct asq_context *ac, struct ldb_request **base_req) +{ + struct ldb_context *ldb; + const char **base_attrs; + int ret; + + ldb = ldb_module_get_ctx(ac->module); + + ac->req_attrs = ac->req->op.search.attrs; + ac->req_attribute = talloc_strdup(ac, ac->asq_ctrl->source_attribute); + if (ac->req_attribute == NULL) + return LDB_ERR_OPERATIONS_ERROR; + + base_attrs = talloc_array(ac, const char *, 2); + if (base_attrs == NULL) return LDB_ERR_OPERATIONS_ERROR; + + base_attrs[0] = talloc_strdup(base_attrs, ac->asq_ctrl->source_attribute); + if (base_attrs[0] == NULL) return LDB_ERR_OPERATIONS_ERROR; + + base_attrs[1] = NULL; + + ret = ldb_build_search_req(base_req, ldb, ac, + ac->req->op.search.base, + LDB_SCOPE_BASE, + NULL, + (const char * const *)base_attrs, + NULL, + ac, asq_base_callback, + ac->req); + if (ret != LDB_SUCCESS) { + return ret; + } + + return LDB_SUCCESS; +} + +static int asq_build_multiple_requests(struct asq_context *ac, bool *terminated) +{ + struct ldb_context *ldb; + struct ldb_control **saved_controls; + struct ldb_control *control; + struct ldb_dn *dn; + struct ldb_message_element *el; + unsigned int i; + int ret; + + if (ac->base_res == NULL) { + return LDB_ERR_NO_SUCH_OBJECT; + } + + ldb = ldb_module_get_ctx(ac->module); + + el = ldb_msg_find_element(ac->base_res->message, ac->req_attribute); + /* no values found */ + if (el == NULL) { + ac->asq_ret = ASQ_CTRL_SUCCESS; + *terminated = true; + return asq_search_terminate(ac); + } + + ac->num_reqs = el->num_values; + ac->cur_req = 0; + ac->reqs = talloc_array(ac, struct ldb_request *, ac->num_reqs); + if (ac->reqs == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + for (i = 0; i < el->num_values; i++) { + + dn = ldb_dn_new(ac, ldb, + (const char *)el->values[i].data); + if ( ! ldb_dn_validate(dn)) { + ac->asq_ret = ASQ_CTRL_INVALID_ATTRIBUTE_SYNTAX; + *terminated = true; + return asq_search_terminate(ac); + } + + ret = ldb_build_search_req_ex(&ac->reqs[i], + ldb, ac, + dn, LDB_SCOPE_BASE, + ac->req->op.search.tree, + ac->req_attrs, + ac->req->controls, + ac, asq_reqs_callback, + ac->req); + if (ret != LDB_SUCCESS) { + return ret; + } + + /* remove the ASQ control itself */ + control = ldb_request_get_control(ac->req, LDB_CONTROL_ASQ_OID); + if (!ldb_save_controls(control, ac->reqs[i], &saved_controls)) { + return LDB_ERR_OPERATIONS_ERROR; + } + } + + return LDB_SUCCESS; +} + +static int asq_search_continue(struct asq_context *ac) +{ + struct ldb_context *ldb; + bool terminated = false; + int ret; + + ldb = ldb_module_get_ctx(ac->module); + + switch (ac->step) { + case ASQ_SEARCH_BASE: + + /* build up the requests call chain */ + ret = asq_build_multiple_requests(ac, &terminated); + if (ret != LDB_SUCCESS || terminated) { + return ret; + } + + ac->step = ASQ_SEARCH_MULTI; + + return ldb_request(ldb, ac->reqs[ac->cur_req]); + + case ASQ_SEARCH_MULTI: + + ac->cur_req++; + + if (ac->cur_req == ac->num_reqs) { + /* done */ + return asq_search_terminate(ac); + } + + return ldb_request(ldb, ac->reqs[ac->cur_req]); + } + + return LDB_ERR_OPERATIONS_ERROR; +} + +static int asq_search(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + struct ldb_request *base_req; + struct ldb_control *control; + struct asq_context *ac; + int ret; + + ldb = ldb_module_get_ctx(module); + + /* check if there's an ASQ control */ + control = ldb_request_get_control(req, LDB_CONTROL_ASQ_OID); + if (control == NULL) { + /* not found go on */ + return ldb_next_request(module, req); + } + + ac = asq_context_init(module, req); + if (!ac) { + return LDB_ERR_OPERATIONS_ERROR; + } + + /* check the search is well formed */ + if (req->op.search.scope != LDB_SCOPE_BASE) { + ac->asq_ret = ASQ_CTRL_UNWILLING_TO_PERFORM; + return asq_search_terminate(ac); + } + + ac->asq_ctrl = talloc_get_type(control->data, struct ldb_asq_control); + if (!ac->asq_ctrl) { + return LDB_ERR_PROTOCOL_ERROR; + } + + ret = asq_build_first_request(ac, &base_req); + if (ret != LDB_SUCCESS) { + return ret; + } + + ac->step = ASQ_SEARCH_BASE; + + return ldb_request(ldb, base_req); +} + +static int asq_init(struct ldb_module *module) +{ + struct ldb_context *ldb; + int ret; + + ldb = ldb_module_get_ctx(module); + + ret = ldb_mod_register_control(module, LDB_CONTROL_ASQ_OID); + if (ret != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_WARNING, "asq: Unable to register control with rootdse!"); + } + + return ldb_next_init(module); +} + +static const struct ldb_module_ops ldb_asq_module_ops = { + .name = "asq", + .search = asq_search, + .init_context = asq_init +}; + +int ldb_asq_init(const char *version) +{ + LDB_MODULE_CHECK_VERSION(version); + return ldb_register_module(&ldb_asq_module_ops); +} diff --git a/ldb-2.0.8/modules/paged_searches.c b/ldb-2.0.8/modules/paged_searches.c new file mode 100644 index 0000000..f8f3895 --- /dev/null +++ b/ldb-2.0.8/modules/paged_searches.c @@ -0,0 +1,391 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2005-2008 + Copyright (C) Andrew Bartlett 2009 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: paged_searches + * + * Component: ldb paged searches module + * + * Description: this module detects if the remote ldap server supports + * paged results and use them to transparently access all objects + * + * Author: Simo Sorce + */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb_module.h" + +#define PS_DEFAULT_PAGE_SIZE 500 +/* 500 objects per query seem to be a decent compromise + * the default AD limit per request is 1000 entries */ + +struct private_data { + + bool paged_supported; +}; + +struct ps_context { + struct ldb_module *module; + struct ldb_request *req; + + bool pending; + + char **saved_referrals; + unsigned int num_referrals; + + struct ldb_request *down_req; +}; + +static int check_ps_continuation(struct ps_context *ac, struct ldb_request *req, struct ldb_reply *ares) +{ + struct ldb_context *ldb; + struct ldb_control *rep_control, *req_control; + struct ldb_paged_control *paged_rep_control = NULL, *paged_req_control = NULL; + ldb = ldb_module_get_ctx(ac->module); + + rep_control = ldb_reply_get_control(ares, LDB_CONTROL_PAGED_RESULTS_OID); + if (rep_control) { + paged_rep_control = talloc_get_type(rep_control->data, struct ldb_paged_control); + } + + req_control = ldb_request_get_control(req, LDB_CONTROL_PAGED_RESULTS_OID); + if (req_control == NULL) { + ldb_set_errstring(ldb, "paged_searches: control is missing"); + return LDB_ERR_OPERATIONS_ERROR; + } + + paged_req_control = talloc_get_type(req_control->data, struct ldb_paged_control); + + if (!rep_control || !paged_rep_control) { + if (paged_req_control->cookie) { + /* something wrong here - why give us a control back befre, but not one now? */ + ldb_set_errstring(ldb, "paged_searches: ERROR: We got back a control from a previous page, but this time no control was returned!"); + return LDB_ERR_OPERATIONS_ERROR; + } else { + /* No cookie received yet, valid to just return the full data set */ + + /* we are done */ + ac->pending = false; + return LDB_SUCCESS; + } + } + + if (paged_rep_control->cookie_len == 0) { + /* we are done */ + ac->pending = false; + return LDB_SUCCESS; + } + + /* more processing required */ + /* let's fill in the request control with the new cookie */ + /* if there's a reply control we must find a request + * control matching it */ + + if (paged_req_control->cookie) { + talloc_free(paged_req_control->cookie); + } + + paged_req_control->cookie = talloc_memdup(req_control, + paged_rep_control->cookie, + paged_rep_control->cookie_len); + paged_req_control->cookie_len = paged_rep_control->cookie_len; + + ac->pending = true; + return LDB_SUCCESS; +} + +static int store_referral(struct ps_context *ac, char *referral) +{ + ac->saved_referrals = talloc_realloc(ac, ac->saved_referrals, char *, ac->num_referrals + 2); + if (!ac->saved_referrals) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->saved_referrals[ac->num_referrals] = talloc_strdup(ac->saved_referrals, referral); + if (!ac->saved_referrals[ac->num_referrals]) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->num_referrals++; + ac->saved_referrals[ac->num_referrals] = NULL; + + return LDB_SUCCESS; +} + +static int send_referrals(struct ps_context *ac) +{ + struct ldb_reply *ares; + int ret; + unsigned int i; + + for (i = 0; i < ac->num_referrals; i++) { + ares = talloc_zero(ac->req, struct ldb_reply); + if (!ares) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ares->type = LDB_REPLY_REFERRAL; + ares->referral = ac->saved_referrals[i]; + + ret = ldb_module_send_referral(ac->req, ares->referral); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + return LDB_SUCCESS; +} + +static int ps_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct ps_context *ac; + int ret; + + ac = talloc_get_type(req->context, struct ps_context); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + switch (ares->type) { + case LDB_REPLY_ENTRY: + ret = ldb_module_send_entry(ac->req, ares->message, ares->controls); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, ret); + } + break; + + case LDB_REPLY_REFERRAL: + ret = store_referral(ac, ares->referral); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, ret); + } + break; + + case LDB_REPLY_DONE: + + ret = check_ps_continuation(ac, req, ares); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, ret); + } + + if (ac->pending) { + + ret = ldb_next_request(ac->module, ac->down_req); + + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, + NULL, NULL, ret); + } + + } else { + + /* send referrals */ + ret = send_referrals(ac); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, + NULL, NULL, ret); + } + + /* send REPLY_DONE */ + return ldb_module_done(ac->req, ares->controls, + ares->response, LDB_SUCCESS); + } + break; + } + + talloc_free(ares); + return LDB_SUCCESS; +} + +static int ps_search(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + struct private_data *private_data; + struct ps_context *ac; + struct ldb_paged_control *control; + int ret; + + private_data = talloc_get_type(ldb_module_get_private(module), struct private_data); + ldb = ldb_module_get_ctx(module); + + /* check if paging is supported */ + if (!private_data || !private_data->paged_supported) { + /* do not touch this request paged controls not + * supported or we + * are just not setup yet */ + return ldb_next_request(module, req); + } + + ac = talloc_zero(req, struct ps_context); + if (ac == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->module = module; + ac->req = req; + ac->pending = false; + ac->saved_referrals = NULL; + ac->num_referrals = 0; + + ldb = ldb_module_get_ctx(ac->module); + + control = talloc(ac, struct ldb_paged_control); + if (!control) { + return LDB_ERR_OPERATIONS_ERROR; + } + + control->size = PS_DEFAULT_PAGE_SIZE; + control->cookie = NULL; + control->cookie_len = 0; + + ret = ldb_build_search_req_ex(&ac->down_req, ldb, ac, + ac->req->op.search.base, + ac->req->op.search.scope, + ac->req->op.search.tree, + ac->req->op.search.attrs, + ac->req->controls, + ac, + ps_callback, + ac->req); + LDB_REQ_SET_LOCATION(ac->down_req); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_request_add_control(ac->down_req, LDB_CONTROL_PAGED_RESULTS_OID, + true, control); + if (ret != LDB_SUCCESS) { + return ret; + } + + talloc_steal(ac->down_req, control); + + return ldb_next_request(ac->module, ac->down_req); +} + +static int check_supported_paged(struct ldb_request *req, + struct ldb_reply *ares) +{ + struct private_data *data; + + data = talloc_get_type(req->context, struct private_data); + + if (!ares) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + + switch (ares->type) { + case LDB_REPLY_ENTRY: + if (ldb_msg_check_string_attribute(ares->message, + "supportedControl", + LDB_CONTROL_PAGED_RESULTS_OID)) { + data->paged_supported = true; + } + break; + + case LDB_REPLY_REFERRAL: + /* ignore */ + break; + + case LDB_REPLY_DONE: + return ldb_request_done(req, LDB_SUCCESS); + } + + talloc_free(ares); + return LDB_SUCCESS; +} + +static int ps_init(struct ldb_module *module) +{ + struct ldb_context *ldb; + static const char *attrs[] = { "supportedControl", NULL }; + struct private_data *data; + struct ldb_dn *base; + int ret; + struct ldb_request *req; + + ldb = ldb_module_get_ctx(module); + + data = talloc(module, struct private_data); + if (data == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + data->paged_supported = false; + + ldb_module_set_private(module, data); + + base = ldb_dn_new(module, ldb, ""); + if (base == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + ret = ldb_build_search_req(&req, ldb, module, + base, LDB_SCOPE_BASE, + "(objectClass=*)", + attrs, NULL, + data, check_supported_paged, + NULL); + LDB_REQ_SET_LOCATION(req); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_next_request(module, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + if (ret != LDB_SUCCESS) { + return ret; + } + + talloc_free(base); + talloc_free(req); + + return ldb_next_init(module); +} + +static const struct ldb_module_ops ldb_paged_searches_module_ops = { + .name = "paged_searches", + .search = ps_search, + .init_context = ps_init +}; + +int ldb_paged_searches_init(const char *version) +{ + LDB_MODULE_CHECK_VERSION(version); + return ldb_register_module(&ldb_paged_searches_module_ops); +} diff --git a/ldb-2.0.8/modules/rdn_name.c b/ldb-2.0.8/modules/rdn_name.c new file mode 100644 index 0000000..e69ad93 --- /dev/null +++ b/ldb-2.0.8/modules/rdn_name.c @@ -0,0 +1,610 @@ +/* + ldb database library + + Copyright (C) Andrew Bartlett 2005-2009 + Copyright (C) Simo Sorce 2006-2008 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: rdn_name + * + * Component: ldb rdn name module + * + * Description: keep a consistent name attribute on objects manpulations + * + * Author: Andrew Bartlett + * + * Modifications: + * - made the module async + * Simo Sorce Mar 2006 + */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb_module.h" + +struct rename_context { + struct ldb_module *module; + struct ldb_request *req; + + struct ldb_reply *ares; +}; + +static int rdn_name_add_callback(struct ldb_request *req, + struct ldb_reply *ares) +{ + struct rename_context *ac; + + ac = talloc_get_type(req->context, struct rename_context); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + if (ares->type == LDB_REPLY_REFERRAL) { + return ldb_module_send_referral(ac->req, ares->referral); + } + + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + if (ares->type != LDB_REPLY_DONE) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + return ldb_module_done(ac->req, ares->controls, + ares->response, LDB_SUCCESS); +} + +static int rdn_name_add(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + struct ldb_request *down_req; + struct rename_context *ac; + struct ldb_message *msg; + struct ldb_message_element *attribute; + const struct ldb_schema_attribute *a; + const char *rdn_name; + const struct ldb_val *rdn_val_p; + struct ldb_val rdn_val; + unsigned int i; + int ret; + + ldb = ldb_module_get_ctx(module); + + /* do not manipulate our control entries */ + if (ldb_dn_is_special(req->op.add.message->dn)) { + return ldb_next_request(module, req); + } + + ac = talloc_zero(req, struct rename_context); + if (ac == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->module = module; + ac->req = req; + + msg = ldb_msg_copy_shallow(req, req->op.add.message); + if (msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + rdn_name = ldb_dn_get_rdn_name(msg->dn); + if (rdn_name == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + rdn_val_p = ldb_dn_get_rdn_val(msg->dn); + if (rdn_val_p == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + if (rdn_val_p->length == 0) { + ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", + ldb_dn_get_linearized(req->op.add.message->dn)); + return LDB_ERR_INVALID_DN_SYNTAX; + } + rdn_val = ldb_val_dup(msg, rdn_val_p); + + /* Perhaps someone above us tried to set this? Then ignore it */ + ldb_msg_remove_attr(msg, "name"); + + ret = ldb_msg_add_value(msg, "name", &rdn_val, NULL); + if (ret != LDB_SUCCESS) { + return ret; + } + + a = ldb_schema_attribute_by_name(ldb, rdn_name); + if (a == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + attribute = ldb_msg_find_element(msg, rdn_name); + if (!attribute) { + /* add entry with normalised RDN information if possible */ + if (a->name != NULL && strcmp(a->name, "*") != 0) { + ret = ldb_msg_add_value(msg, a->name, &rdn_val, NULL); + } else { + ret = ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL); + } + if (ret != LDB_SUCCESS) { + return ret; + } + } else { + /* normalise attribute name if possible */ + if (a->name != NULL && strcmp(a->name, "*") != 0) { + attribute->name = a->name; + } + /* normalise attribute value */ + for (i = 0; i < attribute->num_values; i++) { + bool matched; + if (a->syntax->operator_fn) { + ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a, + &rdn_val, &attribute->values[i], &matched); + if (ret != LDB_SUCCESS) return ret; + } else { + matched = (a->syntax->comparison_fn(ldb, msg, + &rdn_val, &attribute->values[i]) == 0); + } + if (matched) { + /* overwrite so it matches in case */ + attribute->values[i] = rdn_val; + break; + } + } + if (i == attribute->num_values) { + char *rdn_errstring = talloc_asprintf(ac, + "RDN mismatch on %s: %s (%.*s) should match one of:", + ldb_dn_get_linearized(msg->dn), rdn_name, + (int)rdn_val.length, (const char *)rdn_val.data); + for (i = 0; i < attribute->num_values; i++) { + rdn_errstring = talloc_asprintf_append( + rdn_errstring, " (%.*s)", + (int)attribute->values[i].length, + (const char *)attribute->values[i].data); + } + ldb_set_errstring(ldb, rdn_errstring); + /* Match AD's error here */ + return LDB_ERR_INVALID_DN_SYNTAX; + } + } + + ret = ldb_build_add_req(&down_req, ldb, req, + msg, + req->controls, + ac, rdn_name_add_callback, + req); + if (ret != LDB_SUCCESS) { + return ret; + } + + talloc_steal(down_req, msg); + + /* go on with the call chain */ + return ldb_next_request(module, down_req); +} + +static int rdn_modify_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct rename_context *ac; + + ac = talloc_get_type(req->context, struct rename_context); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + if (ares->type == LDB_REPLY_REFERRAL) { + return ldb_module_send_referral(ac->req, ares->referral); + } + + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + /* the only supported reply right now is a LDB_REPLY_DONE */ + if (ares->type != LDB_REPLY_DONE) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + /* send saved controls eventually */ + return ldb_module_done(ac->req, ac->ares->controls, + ac->ares->response, LDB_SUCCESS); +} + +static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct ldb_context *ldb; + struct rename_context *ac; + struct ldb_request *mod_req; + const char *rdn_name; + const struct ldb_schema_attribute *a = NULL; + const struct ldb_val *rdn_val_p; + struct ldb_val rdn_val; + struct ldb_message *msg; + int ret; + + ac = talloc_get_type(req->context, struct rename_context); + ldb = ldb_module_get_ctx(ac->module); + + if (!ares) { + goto error; + } + + if (ares->type == LDB_REPLY_REFERRAL) { + return ldb_module_send_referral(ac->req, ares->referral); + } + + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + /* the only supported reply right now is a LDB_REPLY_DONE */ + if (ares->type != LDB_REPLY_DONE) { + goto error; + } + + /* save reply for caller */ + ac->ares = talloc_steal(ac, ares); + + msg = ldb_msg_new(ac); + if (msg == NULL) { + goto error; + } + msg->dn = ldb_dn_copy(msg, ac->req->op.rename.newdn); + if (msg->dn == NULL) { + goto error; + } + + rdn_name = ldb_dn_get_rdn_name(ac->req->op.rename.newdn); + if (rdn_name == NULL) { + goto error; + } + + a = ldb_schema_attribute_by_name(ldb, rdn_name); + if (a == NULL) { + goto error; + } + + if (a->name != NULL && strcmp(a->name, "*") != 0) { + rdn_name = a->name; + } + + rdn_val_p = ldb_dn_get_rdn_val(msg->dn); + if (rdn_val_p == NULL) { + goto error; + } + if (rdn_val_p->length == 0) { + ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", + ldb_dn_get_linearized(req->op.rename.olddn)); + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_NAMING_VIOLATION); + } + rdn_val = ldb_val_dup(msg, rdn_val_p); + + if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) { + goto error; + } + if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) { + goto error; + } + if (ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_REPLACE, NULL) != 0) { + goto error; + } + if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) { + goto error; + } + + ret = ldb_build_mod_req(&mod_req, ldb, + ac, msg, NULL, + ac, rdn_modify_callback, + req); + if (ret != LDB_SUCCESS) { + return ldb_module_done(ac->req, NULL, NULL, ret); + } + talloc_steal(mod_req, msg); + + /* go on with the call chain */ + return ldb_next_request(ac->module, mod_req); + +error: + return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); +} + +static int rdn_name_rename(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + struct rename_context *ac; + struct ldb_request *down_req; + int ret; + + ldb = ldb_module_get_ctx(module); + + /* do not manipulate our control entries */ + if (ldb_dn_is_special(req->op.rename.newdn)) { + return ldb_next_request(module, req); + } + + ac = talloc_zero(req, struct rename_context); + if (ac == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->module = module; + ac->req = req; + + ret = ldb_build_rename_req(&down_req, + ldb, + ac, + req->op.rename.olddn, + req->op.rename.newdn, + req->controls, + ac, + rdn_rename_callback, + req); + + if (ret != LDB_SUCCESS) { + return ret; + } + + /* rename first, modify "name" if rename is ok */ + return ldb_next_request(module, down_req); +} + +static int rdn_recalculate_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct ldb_request *up_req = talloc_get_type(req->context, struct ldb_request); + + talloc_steal(up_req, req); + return up_req->callback(up_req, ares); +} + +static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + const struct ldb_val *rdn_val_p; + struct ldb_message_element *e = NULL; + struct ldb_control *recalculate_rdn_control = NULL; + + ldb = ldb_module_get_ctx(module); + + /* do not manipulate our control entries */ + if (ldb_dn_is_special(req->op.mod.message->dn)) { + return ldb_next_request(module, req); + } + + recalculate_rdn_control = ldb_request_get_control(req, + LDB_CONTROL_RECALCULATE_RDN_OID); + if (recalculate_rdn_control != NULL) { + struct ldb_message *msg = NULL; + const char *rdn_name = NULL; + struct ldb_val rdn_val; + const struct ldb_schema_attribute *a = NULL; + struct ldb_request *mod_req = NULL; + int ret; + struct ldb_message_element *rdn_del = NULL; + struct ldb_message_element *name_del = NULL; + + recalculate_rdn_control->critical = false; + + msg = ldb_msg_copy_shallow(req, req->op.mod.message); + if (msg == NULL) { + return ldb_module_oom(module); + } + + /* + * The caller must pass a dummy 'name' attribute + * in order to bypass some high level checks. + * + * We just remove it and check nothing is left. + */ + ldb_msg_remove_attr(msg, "name"); + + if (msg->num_elements != 0) { + return ldb_module_operr(module); + } + + rdn_name = ldb_dn_get_rdn_name(msg->dn); + if (rdn_name == NULL) { + return ldb_module_oom(module); + } + + a = ldb_schema_attribute_by_name(ldb, rdn_name); + if (a == NULL) { + return ldb_module_operr(module); + } + + if (a->name != NULL && strcmp(a->name, "*") != 0) { + rdn_name = a->name; + } + + rdn_val_p = ldb_dn_get_rdn_val(msg->dn); + if (rdn_val_p == NULL) { + return ldb_module_oom(module); + } + rdn_val = ldb_val_dup(msg, rdn_val_p); + if (rdn_val.length == 0) { + return ldb_module_oom(module); + } + + /* + * This is a bit tricky: + * + * We want _DELETE elements (as "rdn_del" and "name_del" without + * values) first, followed by _ADD (with the real names) + * elements (with values). Then we fix up the "rdn_del" and + * "name_del" attributes. + */ + + ret = ldb_msg_add_empty(msg, "rdn_del", LDB_FLAG_MOD_DELETE, NULL); + if (ret != 0) { + return ldb_module_oom(module); + } + ret = ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_ADD, NULL); + if (ret != 0) { + return ldb_module_oom(module); + } + ret = ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL); + if (ret != 0) { + return ldb_module_oom(module); + } + + ret = ldb_msg_add_empty(msg, "name_del", LDB_FLAG_MOD_DELETE, NULL); + if (ret != 0) { + return ldb_module_oom(module); + } + ret = ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_ADD, NULL); + if (ret != 0) { + return ldb_module_oom(module); + } + ret = ldb_msg_add_value(msg, "name", &rdn_val, NULL); + if (ret != 0) { + return ldb_module_oom(module); + } + + rdn_del = ldb_msg_find_element(msg, "rdn_del"); + if (rdn_del == NULL) { + return ldb_module_operr(module); + } + rdn_del->name = talloc_strdup(msg->elements, rdn_name); + if (rdn_del->name == NULL) { + return ldb_module_oom(module); + } + name_del = ldb_msg_find_element(msg, "name_del"); + if (name_del == NULL) { + return ldb_module_operr(module); + } + name_del->name = talloc_strdup(msg->elements, "name"); + if (name_del->name == NULL) { + return ldb_module_oom(module); + } + + ret = ldb_build_mod_req(&mod_req, ldb, + req, msg, NULL, + req, rdn_recalculate_callback, + req); + if (ret != LDB_SUCCESS) { + return ldb_module_done(req, NULL, NULL, ret); + } + talloc_steal(mod_req, msg); + + ret = ldb_request_add_control(mod_req, + LDB_CONTROL_RECALCULATE_RDN_OID, + false, NULL); + if (ret != LDB_SUCCESS) { + return ldb_module_done(req, NULL, NULL, ret); + } + ret = ldb_request_add_control(mod_req, + LDB_CONTROL_PERMISSIVE_MODIFY_OID, + false, NULL); + if (ret != LDB_SUCCESS) { + return ldb_module_done(req, NULL, NULL, ret); + } + + /* go on with the call chain */ + return ldb_next_request(module, mod_req); + } + + rdn_val_p = ldb_dn_get_rdn_val(req->op.mod.message->dn); + if (rdn_val_p == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + if (rdn_val_p->length == 0) { + ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", + ldb_dn_get_linearized(req->op.mod.message->dn)); + return LDB_ERR_INVALID_DN_SYNTAX; + } + + e = ldb_msg_find_element(req->op.mod.message, "distinguishedName"); + if (e != NULL) { + ldb_asprintf_errstring(ldb, "Modify of 'distinguishedName' on %s not permitted, must use 'rename' operation instead", + ldb_dn_get_linearized(req->op.mod.message->dn)); + if (e->flags == LDB_FLAG_MOD_REPLACE) { + return LDB_ERR_CONSTRAINT_VIOLATION; + } else { + return LDB_ERR_UNWILLING_TO_PERFORM; + } + } + + if (ldb_msg_find_element(req->op.mod.message, "name")) { + ldb_asprintf_errstring(ldb, "Modify of 'name' on %s not permitted, must use 'rename' operation instead", + ldb_dn_get_linearized(req->op.mod.message->dn)); + return LDB_ERR_NOT_ALLOWED_ON_RDN; + } + + if (ldb_msg_find_element(req->op.mod.message, ldb_dn_get_rdn_name(req->op.mod.message->dn))) { + ldb_asprintf_errstring(ldb, "Modify of RDN '%s' on %s not permitted, must use 'rename' operation instead", + ldb_dn_get_rdn_name(req->op.mod.message->dn), ldb_dn_get_linearized(req->op.mod.message->dn)); + return LDB_ERR_NOT_ALLOWED_ON_RDN; + } + + /* All OK, they kept their fingers out of the special attributes */ + return ldb_next_request(module, req); +} + +static int rdn_name_search(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + const char *rdn_name; + const struct ldb_val *rdn_val_p; + + ldb = ldb_module_get_ctx(module); + + /* do not manipulate our control entries */ + if (ldb_dn_is_special(req->op.search.base)) { + return ldb_next_request(module, req); + } + + rdn_name = ldb_dn_get_rdn_name(req->op.search.base); + rdn_val_p = ldb_dn_get_rdn_val(req->op.search.base); + if ((rdn_name != NULL) && (rdn_val_p == NULL)) { + return LDB_ERR_OPERATIONS_ERROR; + } + if ((rdn_val_p != NULL) && (rdn_val_p->length == 0)) { + ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", + ldb_dn_get_linearized(req->op.search.base)); + return LDB_ERR_INVALID_DN_SYNTAX; + } + + return ldb_next_request(module, req); +} + +static const struct ldb_module_ops ldb_rdn_name_module_ops = { + .name = "rdn_name", + .add = rdn_name_add, + .modify = rdn_name_modify, + .rename = rdn_name_rename, + .search = rdn_name_search +}; + +int ldb_rdn_name_init(const char *version) +{ + LDB_MODULE_CHECK_VERSION(version); + return ldb_register_module(&ldb_rdn_name_module_ops); +} diff --git a/ldb-2.0.8/modules/skel.c b/ldb-2.0.8/modules/skel.c new file mode 100644 index 0000000..1ce3ec1 --- /dev/null +++ b/ldb-2.0.8/modules/skel.c @@ -0,0 +1,147 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb skel module + * + * Description: example module + * + * Author: Simo Sorce + */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb_module.h" + +struct private_data { + + char *some_private_data; +}; + +/* search */ +static int skel_search(struct ldb_module *module, struct ldb_request *req) +{ + return ldb_next_request(module, req); +} + +/* add */ +static int skel_add(struct ldb_module *module, struct ldb_request *req){ + return ldb_next_request(module, req); +} + +/* modify */ +static int skel_modify(struct ldb_module *module, struct ldb_request *req) +{ + return ldb_next_request(module, req); +} + +/* delete */ +static int skel_delete(struct ldb_module *module, struct ldb_request *req) +{ + return ldb_next_request(module, req); +} + +/* rename */ +static int skel_rename(struct ldb_module *module, struct ldb_request *req) +{ + return ldb_next_request(module, req); +} + +/* start a transaction */ +static int skel_start_trans(struct ldb_module *module) +{ + return ldb_next_start_trans(module); +} + +/* end a transaction */ +static int skel_end_trans(struct ldb_module *module) +{ + return ldb_next_end_trans(module); +} + +/* delete a transaction */ +static int skel_del_trans(struct ldb_module *module) +{ + return ldb_next_del_trans(module); +} + +static int skel_destructor(struct ldb_module *ctx) +{ + struct private_data *data; + + data = talloc_get_type(ldb_module_get_private(ctx), struct private_data); + + /* put your clean-up functions here */ + if (data->some_private_data) talloc_free(data->some_private_data); + + return 0; +} + +static int skel_request(struct ldb_module *module, struct ldb_request *req) +{ + return ldb_next_request(module, req); +} + +static int skel_init(struct ldb_module *module) +{ + struct ldb_context *ldb; + struct private_data *data; + + ldb = ldb_module_get_ctx(module); + + data = talloc(module, struct private_data); + if (data == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + data->some_private_data = NULL; + ldb_module_set_private(module, data); + + talloc_set_destructor (module, skel_destructor); + + return ldb_next_init(module); +} + +static const struct ldb_module_ops ldb_skel_module_ops = { + .name = "skel", + .init_context = skel_init, + .search = skel_search, + .add = skel_add, + .modify = skel_modify, + .del = skel_delete, + .rename = skel_rename, + .request = skel_request, + .start_transaction = skel_start_trans, + .end_transaction = skel_end_trans, + .del_transaction = skel_del_trans, +}; + +int ldb_skel_init(const char *version) +{ + LDB_MODULE_CHECK_VERSION(version); + return ldb_register_module(&ldb_skel_module_ops); +} diff --git a/ldb-2.0.8/modules/sort.c b/ldb-2.0.8/modules/sort.c new file mode 100644 index 0000000..cb6f8df --- /dev/null +++ b/ldb-2.0.8/modules/sort.c @@ -0,0 +1,402 @@ +/* + ldb database library + + Copyright (C) Simo Sorce 2005-2008 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldb server side sort control module + * + * Description: this module sorts the results of a search + * + * Author: Simo Sorce + */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb_module.h" + +struct opaque { + struct ldb_context *ldb; + const struct ldb_attrib_handler *h; + const char *attribute; + int reverse; + int result; +}; + +struct sort_context { + struct ldb_module *module; + + const char *attributeName; + const char *orderingRule; + int reverse; + + struct ldb_request *req; + struct ldb_message **msgs; + char **referrals; + unsigned int num_msgs; + unsigned int num_refs; + const char *extra_sort_key; + + const struct ldb_schema_attribute *a; + int sort_result; +}; + +static int build_response(void *mem_ctx, struct ldb_control ***ctrls, int result, const char *desc) +{ + struct ldb_control **controls; + struct ldb_sort_resp_control *resp; + unsigned int i; + + if (*ctrls) { + controls = *ctrls; + for (i = 0; controls[i]; i++); + controls = talloc_realloc(mem_ctx, controls, struct ldb_control *, i + 2); + } else { + i = 0; + controls = talloc_array(mem_ctx, struct ldb_control *, 2); + } + if (! controls ) + return LDB_ERR_OPERATIONS_ERROR; + + *ctrls = controls; + + controls[i+1] = NULL; + controls[i] = talloc(controls, struct ldb_control); + if (! controls[i] ) + return LDB_ERR_OPERATIONS_ERROR; + + controls[i]->oid = LDB_CONTROL_SORT_RESP_OID; + controls[i]->critical = 0; + + resp = talloc(controls[i], struct ldb_sort_resp_control); + if (! resp ) + return LDB_ERR_OPERATIONS_ERROR; + + resp->result = result; + resp->attr_desc = talloc_strdup(resp, desc); + + if (! resp->attr_desc ) + return LDB_ERR_OPERATIONS_ERROR; + + controls[i]->data = resp; + + return LDB_SUCCESS; +} + +static int sort_compare(struct ldb_message **msg1, struct ldb_message **msg2, void *opaque) +{ + struct sort_context *ac = talloc_get_type(opaque, struct sort_context); + struct ldb_message_element *el1, *el2; + struct ldb_context *ldb; + + ldb = ldb_module_get_ctx(ac->module); + + if (ac->sort_result != 0) { + /* an error occurred previously, + * let's exit the sorting by returning always 0 */ + return 0; + } + + el1 = ldb_msg_find_element(*msg1, ac->attributeName); + el2 = ldb_msg_find_element(*msg2, ac->attributeName); + + if (!el1 && el2) { + return 1; + } + if (el1 && !el2) { + return -1; + } + if (!el1 && !el2) { + return 0; + } + + if (ac->reverse) + return ac->a->syntax->comparison_fn(ldb, ac, &el2->values[0], &el1->values[0]); + + return ac->a->syntax->comparison_fn(ldb, ac, &el1->values[0], &el2->values[0]); +} + +static int server_sort_results(struct sort_context *ac) +{ + struct ldb_context *ldb; + struct ldb_reply *ares; + unsigned int i; + int ret; + + ldb = ldb_module_get_ctx(ac->module); + + ac->a = ldb_schema_attribute_by_name(ldb, ac->attributeName); + ac->sort_result = 0; + + LDB_TYPESAFE_QSORT(ac->msgs, ac->num_msgs, ac, sort_compare); + + if (ac->sort_result != LDB_SUCCESS) { + return ac->sort_result; + } + + for (i = 0; i < ac->num_msgs; i++) { + ares = talloc_zero(ac, struct ldb_reply); + if (!ares) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ares->type = LDB_REPLY_ENTRY; + ares->message = talloc_move(ares, &ac->msgs[i]); + if (ac->extra_sort_key) { + ldb_msg_remove_attr(ares->message, ac->extra_sort_key); + } + ret = ldb_module_send_entry(ac->req, ares->message, ares->controls); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + for (i = 0; i < ac->num_refs; i++) { + ares = talloc_zero(ac, struct ldb_reply); + if (!ares) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ares->type = LDB_REPLY_REFERRAL; + ares->referral = talloc_move(ares, &ac->referrals[i]); + + ret = ldb_module_send_referral(ac->req, ares->referral); + if (ret != LDB_SUCCESS) { + return ret; + } + } + + return LDB_SUCCESS; +} + +static int server_sort_search_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct sort_context *ac; + struct ldb_context *ldb; + int ret; + + ac = talloc_get_type(req->context, struct sort_context); + ldb = ldb_module_get_ctx(ac->module); + + if (!ares) { + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(ac->req, ares->controls, + ares->response, ares->error); + } + + switch (ares->type) { + case LDB_REPLY_ENTRY: + ac->msgs = talloc_realloc(ac, ac->msgs, struct ldb_message *, ac->num_msgs + 2); + if (! ac->msgs) { + talloc_free(ares); + ldb_oom(ldb); + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + ac->msgs[ac->num_msgs] = talloc_steal(ac->msgs, ares->message); + ac->num_msgs++; + ac->msgs[ac->num_msgs] = NULL; + + break; + + case LDB_REPLY_REFERRAL: + ac->referrals = talloc_realloc(ac, ac->referrals, char *, ac->num_refs + 2); + if (! ac->referrals) { + talloc_free(ares); + ldb_oom(ldb); + return ldb_module_done(ac->req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + ac->referrals[ac->num_refs] = talloc_steal(ac->referrals, ares->referral); + ac->num_refs++; + ac->referrals[ac->num_refs] = NULL; + + break; + + case LDB_REPLY_DONE: + + ret = server_sort_results(ac); + return ldb_module_done(ac->req, ares->controls, + ares->response, ret); + } + + talloc_free(ares); + return LDB_SUCCESS; +} + +static int server_sort_search(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_control *control; + struct ldb_server_sort_control **sort_ctrls; + struct ldb_control **saved_controls; + struct ldb_request *down_req; + struct sort_context *ac; + struct ldb_context *ldb; + int ret; + const char * const *attrs; + size_t n_attrs, i; + const char *sort_attr; + + ldb = ldb_module_get_ctx(module); + + /* check if there's a server sort control */ + control = ldb_request_get_control(req, LDB_CONTROL_SERVER_SORT_OID); + if (control == NULL) { + /* not found go on */ + return ldb_next_request(module, req); + } + + ac = talloc_zero(req, struct sort_context); + if (ac == NULL) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + + ac->module = module; + ac->req = req; + + sort_ctrls = talloc_get_type(control->data, struct ldb_server_sort_control *); + if (!sort_ctrls) { + return LDB_ERR_PROTOCOL_ERROR; + } + + /* FIXME: we do not support more than one attribute for sorting right now */ + /* FIXME: we need to check if the attribute type exist or return an error */ + + if (sort_ctrls[1] != NULL) { + if (control->critical) { + struct ldb_control **controls = NULL; + + /* callback immediately */ + ret = build_response(req, &controls, + LDB_ERR_UNWILLING_TO_PERFORM, + "sort control is not complete yet"); + if (ret != LDB_SUCCESS) { + return ldb_module_done(req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + return ldb_module_done(req, controls, NULL, ret); + } else { + /* just pass the call down and don't do any sorting */ + return ldb_next_request(module, req); + } + } + + control->critical = 0; + + /* We are asked to sort on an attribute, and if that attribute is not + already in the search attributes we need to add it (and later + remove it on the return journey). + */ + sort_attr = sort_ctrls[0]->attributeName; + if (req->op.search.attrs == NULL) { + /* This means all non-operational attributes, which means + there's nothing to add. */ + attrs = NULL; + } else { + n_attrs = 0; + while (req->op.search.attrs[n_attrs] != NULL) { + if (sort_attr && + strcmp(req->op.search.attrs[n_attrs], sort_attr) == 0) { + sort_attr = NULL; + } + n_attrs++; + } + + if (sort_attr == NULL) { + attrs = req->op.search.attrs; + } else { + const char **tmp = talloc_array(ac, const char *, n_attrs + 2); + + for (i = 0; i < n_attrs; i++) { + tmp[i] = req->op.search.attrs[i]; + } + ac->extra_sort_key = sort_attr; + tmp[n_attrs] = sort_attr; + tmp[n_attrs + 1] = NULL; + attrs = tmp; + } + } + + ac->attributeName = sort_ctrls[0]->attributeName; + ac->orderingRule = sort_ctrls[0]->orderingRule; + ac->reverse = sort_ctrls[0]->reverse; + + ret = ldb_build_search_req_ex(&down_req, ldb, ac, + req->op.search.base, + req->op.search.scope, + req->op.search.tree, + attrs, + req->controls, + ac, + server_sort_search_callback, + req); + if (ret != LDB_SUCCESS) { + return ret; + } + + /* save it locally and remove it from the list */ + /* we do not need to replace them later as we + * are keeping the original req intact */ + if (!ldb_save_controls(control, down_req, &saved_controls)) { + return LDB_ERR_OPERATIONS_ERROR; + } + + return ldb_next_request(module, down_req); +} + +static int server_sort_init(struct ldb_module *module) +{ + struct ldb_context *ldb; + int ret; + + ldb = ldb_module_get_ctx(module); + + ret = ldb_mod_register_control(module, LDB_CONTROL_SERVER_SORT_OID); + if (ret != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_WARNING, + "server_sort:" + "Unable to register control with rootdse!"); + } + + return ldb_next_init(module); +} + +static const struct ldb_module_ops ldb_server_sort_module_ops = { + .name = "server_sort", + .search = server_sort_search, + .init_context = server_sort_init +}; + +int ldb_server_sort_init(const char *version) +{ + LDB_MODULE_CHECK_VERSION(version); + return ldb_register_module(&ldb_server_sort_module_ops); +} diff --git a/ldb-2.0.8/nssldb/README.txt b/ldb-2.0.8/nssldb/README.txt new file mode 100644 index 0000000..ddba62b --- /dev/null +++ b/ldb-2.0.8/nssldb/README.txt @@ -0,0 +1,34 @@ + +This test code requires a tdb that is configured for to use the asq module. +You can do that adding the following record to a tdb: + +dn: @MODULES +@LIST: asq + +Other modules can be used as well (like rdn_name for example) + +The uidNumber 0 and the gidNumber 0 are considered invalid. + +The user records should contain the followin attributes: +uid (required) the user name +userPassword (optional) the user password (if not present "LDB" is + returned in the password field) +uidNumber (required) the user uid +gidNumber (required) the user primary gid +gecos (optional) the GECOS +homeDirectory (required) the home directory +loginShell (required) the login shell +memberOf (required) all the groups the user is member of should + be reported here using their DNs. The + primary group as well. + +The group accounts should contain the following attributes: +cn (required) the group name +uesrPassword (optional) the group password (if not present "LDB" is + returned in the password field) +gidNumber (required) the group gid +member (optional) the DNs of the member users, also the ones + that have this group as primary + + +SSS diff --git a/ldb-2.0.8/nssldb/ldb-grp.c b/ldb-2.0.8/nssldb/ldb-grp.c new file mode 100644 index 0000000..5e7556d --- /dev/null +++ b/ldb-2.0.8/nssldb/ldb-grp.c @@ -0,0 +1,429 @@ +/* + LDB nsswitch module + + Copyright (C) Simo Sorce 2006 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#include "ldb-nss.h" + +extern struct _ldb_nss_context *_ldb_nss_ctx; + +const char *_ldb_nss_gr_attrs[] = { + "cn", + "userPassword", + "gidNumber", + NULL +}; + +const char *_ldb_nss_mem_attrs[] = { + "uid", + NULL +}; + +#define _NSS_LDB_ENOMEM(amem) \ + do { \ + if ( ! amem) { \ + errno = ENOMEM; \ + talloc_free(memctx); \ + return NSS_STATUS_UNAVAIL; \ + } \ + } while(0) + +/* This setgrent, getgrent, endgrent is not very efficient */ + +NSS_STATUS _nss_ldb_setgrent(void) +{ + int ret; + + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + _ldb_nss_ctx->gr_cur = 0; + if (_ldb_nss_ctx->gr_res != NULL) { + talloc_free(_ldb_nss_ctx->gr_res); + _ldb_nss_ctx->gr_res = NULL; + } + + ret = ldb_search(_ldb_nss_ctx->ldb, + _ldb_nss_ctx->ldb, + &_ldb_nss_ctx->gr_res, + _ldb_nss_ctx->base, + LDB_SCOPE_SUBTREE, + _ldb_nss_gr_attrs, + _LDB_NSS_GRENT_FILTER); + if (ret != LDB_SUCCESS) { + return NSS_STATUS_UNAVAIL; + } + + return NSS_STATUS_SUCCESS; +} + +NSS_STATUS _nss_ldb_endgrent(void) +{ + int ret; + + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + _ldb_nss_ctx->gr_cur = 0; + if (_ldb_nss_ctx->gr_res) { + talloc_free(_ldb_nss_ctx->gr_res); + _ldb_nss_ctx->gr_res = NULL; + } + + return NSS_STATUS_SUCCESS; +} + +NSS_STATUS _nss_ldb_getgrent_r(struct group *result_buf, char *buffer, size_t buflen, int *errnop) +{ + int ret; + struct ldb_result *res; + + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + *errnop = 0; + + if (_ldb_nss_ctx->gr_cur >= _ldb_nss_ctx->gr_res->count) { + /* already returned all entries */ + return NSS_STATUS_NOTFOUND; + } + + res = talloc_zero(_ldb_nss_ctx->gr_res, struct ldb_result); + if ( ! res) { + errno = *errnop = ENOMEM; + _ldb_nss_ctx->gr_cur++; /* skip this entry */ + return NSS_STATUS_UNAVAIL; + } + + ret = _ldb_nss_group_request(&res, + _ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur]->dn, + _ldb_nss_mem_attrs, + "member"); + + if (ret != NSS_STATUS_SUCCESS) { + *errnop = errno; + talloc_free(res); + _ldb_nss_ctx->gr_cur++; /* skip this entry */ + return ret; + } + + ret = _ldb_nss_fill_group(result_buf, + buffer, + buflen, + errnop, + _ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur], + res); + + talloc_free(res); + + if (ret != NSS_STATUS_SUCCESS) { + if (ret != NSS_STATUS_TRYAGAIN) { + _ldb_nss_ctx->gr_cur++; /* skip this entry */ + } + return ret; + } + + /* this entry is ok, increment counter to nex entry */ + _ldb_nss_ctx->gr_cur++; + + return NSS_STATUS_SUCCESS; +} + +NSS_STATUS _nss_ldb_getgrnam_r(const char *name, struct group *result_buf, char *buffer, size_t buflen, int *errnop) +{ + int ret; + char *filter; + TALLOC_CTX *ctx; + struct ldb_result *gr_res; + struct ldb_result *mem_res; + + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + ctx = talloc_new(_ldb_nss_ctx->ldb); + if ( ! ctx) { + *errnop = errno = ENOMEM; + return NSS_STATUS_UNAVAIL; + } + + /* build the filter for this uid */ + filter = talloc_asprintf(ctx, _LDB_NSS_GRNAM_FILTER, name); + if (filter == NULL) { + /* this is a fatal error */ + *errnop = errno = ENOMEM; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + /* search the entry */ + ret = ldb_search(_ldb_nss_ctx->ldb, + _ldb_nss_ctx->ldb, + &gr_res, + _ldb_nss_ctx->base, + LDB_SCOPE_SUBTREE, + _ldb_nss_gr_attrs, + filter); + if (ret != LDB_SUCCESS) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + talloc_steal(ctx, gr_res); + + /* if none found return */ + if (gr_res->count == 0) { + *errnop = errno = ENOENT; + ret = NSS_STATUS_NOTFOUND; + goto done; + } + + if (gr_res->count != 1) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + mem_res = talloc_zero(ctx, struct ldb_result); + if ( ! mem_res) { + errno = *errnop = ENOMEM; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + ret = _ldb_nss_group_request(&mem_res, + gr_res->msgs[0]->dn, + _ldb_nss_mem_attrs, + "member"); + + if (ret != NSS_STATUS_SUCCESS) { + *errnop = errno; + goto done; + } + + ret = _ldb_nss_fill_group(result_buf, + buffer, + buflen, + errnop, + gr_res->msgs[0], + mem_res); + + if (ret != NSS_STATUS_SUCCESS) { + goto done; + } + + ret = NSS_STATUS_SUCCESS; +done: + talloc_free(ctx); + return ret; +} + +NSS_STATUS _nss_ldb_getgrgid_r(gid_t gid, struct group *result_buf, char *buffer, size_t buflen, int *errnop) +{ + int ret; + char *filter; + TALLOC_CTX *ctx; + struct ldb_result *gr_res; + struct ldb_result *mem_res; + + if (gid == 0) { /* we don't serve root gid by policy */ + *errnop = errno = ENOENT; + return NSS_STATUS_NOTFOUND; + } + + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + ctx = talloc_new(_ldb_nss_ctx->ldb); + if ( ! ctx) { + *errnop = errno = ENOMEM; + return NSS_STATUS_UNAVAIL; + } + + /* build the filter for this uid */ + filter = talloc_asprintf(ctx, _LDB_NSS_GRGID_FILTER, gid); + if (filter == NULL) { + /* this is a fatal error */ + *errnop = errno = ENOMEM; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + /* search the entry */ + ret = ldb_search(_ldb_nss_ctx->ldb, + _ldb_nss_ctx->ldb, + &gr_res, + _ldb_nss_ctx->base, + LDB_SCOPE_SUBTREE, + _ldb_nss_gr_attrs, + filter); + if (ret != LDB_SUCCESS) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + talloc_steal(ctx, gr_res); + + /* if none found return */ + if (gr_res->count == 0) { + *errnop = errno = ENOENT; + ret = NSS_STATUS_NOTFOUND; + goto done; + } + + if (gr_res->count != 1) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + mem_res = talloc_zero(ctx, struct ldb_result); + if ( ! mem_res) { + errno = *errnop = ENOMEM; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + ret = _ldb_nss_group_request(&mem_res, + gr_res->msgs[0]->dn, + _ldb_nss_mem_attrs, + "member"); + + if (ret != NSS_STATUS_SUCCESS) { + *errnop = errno; + goto done; + } + + ret = _ldb_nss_fill_group(result_buf, + buffer, + buflen, + errnop, + gr_res->msgs[0], + mem_res); + + if (ret != NSS_STATUS_SUCCESS) { + goto done; + } + + ret = NSS_STATUS_SUCCESS; +done: + talloc_free(ctx); + return ret; +} + +NSS_STATUS _nss_ldb_initgroups_dyn(const char *user, gid_t group, long int *start, long int *size, gid_t **groups, long int limit, int *errnop) +{ + int ret; + char *filter; + const char * attrs[] = { "uidNumber", "gidNumber", NULL }; + struct ldb_result *uid_res; + struct ldb_result *mem_res; + + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + mem_res = talloc_zero(_ldb_nss_ctx, struct ldb_result); + if ( ! mem_res) { + errno = *errnop = ENOMEM; + return NSS_STATUS_UNAVAIL; + } + + /* build the filter for this name */ + filter = talloc_asprintf(mem_res, _LDB_NSS_PWNAM_FILTER, user); + if (filter == NULL) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + /* search the entry */ + ret = ldb_search(_ldb_nss_ctx->ldb, + _ldb_nss_ctx->ldb, + &uid_res, + _ldb_nss_ctx->base, + LDB_SCOPE_SUBTREE, + attrs, + filter); + if (ret != LDB_SUCCESS) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + talloc_steal(mem_res, uid_res); + + /* if none found return */ + if (uid_res->count == 0) { + *errnop = errno = ENOENT; + ret = NSS_STATUS_NOTFOUND; + goto done; + } + + if (uid_res->count != 1) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + ret = _ldb_nss_group_request(&mem_res, + uid_res->msgs[0]->dn, + attrs, + "memberOf"); + + if (ret != NSS_STATUS_SUCCESS) { + *errnop = errno; + goto done; + } + + ret = _ldb_nss_fill_initgr(group, + limit, + start, + size, + groups, + errnop, + mem_res); + + if (ret != NSS_STATUS_SUCCESS) { + goto done; + } + + ret = NSS_STATUS_SUCCESS; + +done: + talloc_free(mem_res); + return ret; +} diff --git a/ldb-2.0.8/nssldb/ldb-nss.c b/ldb-2.0.8/nssldb/ldb-nss.c new file mode 100644 index 0000000..92b0635 --- /dev/null +++ b/ldb-2.0.8/nssldb/ldb-nss.c @@ -0,0 +1,395 @@ +/* + LDB nsswitch module + + Copyright (C) Simo Sorce 2006 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#include "ldb-nss.h" + +struct _ldb_nss_context *_ldb_nss_ctx = NULL; + +NSS_STATUS _ldb_nss_init(void) +{ + int ret; + + pid_t mypid = getpid(); + + if (_ldb_nss_ctx != NULL) { + if (_ldb_nss_ctx->pid == mypid) { + /* already initialized */ + return NSS_STATUS_SUCCESS; + } else { + /* we are in a forked child now, reinitialize */ + talloc_free(_ldb_nss_ctx); + _ldb_nss_ctx = NULL; + } + } + + _ldb_nss_ctx = talloc_named(NULL, 0, "_ldb_nss_ctx(%u)", mypid); + if (_ldb_nss_ctx == NULL) { + return NSS_STATUS_UNAVAIL; + } + + _ldb_nss_ctx->pid = mypid; + + _ldb_nss_ctx->ldb = ldb_init(_ldb_nss_ctx, NULL); + if (_ldb_nss_ctx->ldb == NULL) { + goto failed; + } + + ret = ldb_connect(_ldb_nss_ctx->ldb, _LDB_NSS_URL, LDB_FLG_RDONLY, NULL); + if (ret != LDB_SUCCESS) { + goto failed; + } + + _ldb_nss_ctx->base = ldb_dn_new(_ldb_nss_ctx, _ldb_nss_ctx->ldb, _LDB_NSS_BASEDN); + if ( ! ldb_dn_validate(_ldb_nss_ctx->base)) { + goto failed; + } + + _ldb_nss_ctx->pw_cur = 0; + _ldb_nss_ctx->pw_res = NULL; + _ldb_nss_ctx->gr_cur = 0; + _ldb_nss_ctx->gr_res = NULL; + + return NSS_STATUS_SUCCESS; + +failed: + /* talloc_free(_ldb_nss_ctx); */ + _ldb_nss_ctx = NULL; + return NSS_STATUS_UNAVAIL; +} + +NSS_STATUS _ldb_nss_fill_passwd(struct passwd *result, + char *buffer, + int buflen, + int *errnop, + struct ldb_message *msg) +{ + int len; + int bufpos; + const char *tmp; + + bufpos = 0; + + /* get username */ + tmp = ldb_msg_find_attr_as_string(msg, "uid", NULL); + if (tmp == NULL) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + return NSS_STATUS_UNAVAIL; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->pw_name = &buffer[bufpos]; + bufpos += len; + + /* get userPassword */ + tmp = ldb_msg_find_attr_as_string(msg, "userPassword", NULL); + if (tmp == NULL) { + tmp = "LDB"; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->pw_passwd = &buffer[bufpos]; + bufpos += len; + + /* this backend never serves an uid 0 user */ + result->pw_uid = ldb_msg_find_attr_as_int(msg, "uidNumber", 0); + if (result->pw_uid == 0) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + return NSS_STATUS_UNAVAIL; + } + + result->pw_gid = ldb_msg_find_attr_as_int(msg, "gidNumber", 0); + if (result->pw_gid == 0) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + return NSS_STATUS_UNAVAIL; + } + + /* get gecos */ + tmp = ldb_msg_find_attr_as_string(msg, "gecos", NULL); + if (tmp == NULL) { + tmp = ""; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->pw_gecos = &buffer[bufpos]; + bufpos += len; + + /* get homeDirectory */ + tmp = ldb_msg_find_attr_as_string(msg, "homeDirectory", NULL); + if (tmp == NULL) { + tmp = ""; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->pw_dir = &buffer[bufpos]; + bufpos += len; + + /* get shell */ + tmp = ldb_msg_find_attr_as_string(msg, "loginShell", NULL); + if (tmp == NULL) { + tmp = ""; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->pw_shell = &buffer[bufpos]; + bufpos += len; + + return NSS_STATUS_SUCCESS; +} + +NSS_STATUS _ldb_nss_fill_group(struct group *result, + char *buffer, + int buflen, + int *errnop, + struct ldb_message *group, + struct ldb_result *members) +{ + const char *tmp; + size_t len; + size_t bufpos; + size_t lsize; + unsigned int i; + + bufpos = 0; + + /* get group name */ + tmp = ldb_msg_find_attr_as_string(group, "cn", NULL); + if (tmp == NULL) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + return NSS_STATUS_UNAVAIL; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->gr_name = &buffer[bufpos]; + bufpos += len; + + /* get userPassword */ + tmp = ldb_msg_find_attr_as_string(group, "userPassword", NULL); + if (tmp == NULL) { + tmp = "LDB"; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->gr_passwd = &buffer[bufpos]; + bufpos += len; + + result->gr_gid = ldb_msg_find_attr_as_int(group, "gidNumber", 0); + if (result->gr_gid == 0) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + return NSS_STATUS_UNAVAIL; + } + + /* check if there is enough memory for the list of pointers */ + lsize = (members->count + 1) * sizeof(char *); + + /* align buffer on pointer boundary */ + bufpos += (sizeof(char*) - ((unsigned long)(buffer) % sizeof(char*))); + if ((buflen - bufpos) < lsize) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + + result->gr_mem = (char **)&buffer[bufpos]; + bufpos += lsize; + + for (i = 0; i < members->count; i++) { + tmp = ldb_msg_find_attr_as_string(members->msgs[i], "uid", NULL); + if (tmp == NULL) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + return NSS_STATUS_UNAVAIL; + } + len = strlen(tmp)+1; + if (bufpos + len > buflen) { + /* buffer too small */ + *errnop = errno = EAGAIN; + return NSS_STATUS_TRYAGAIN; + } + memcpy(&buffer[bufpos], tmp, len); + result->gr_mem[i] = &buffer[bufpos]; + bufpos += len; + } + + result->gr_mem[i] = NULL; + + return NSS_STATUS_SUCCESS; +} + +NSS_STATUS _ldb_nss_fill_initgr(gid_t group, + long int limit, + long int *start, + long int *size, + gid_t **groups, + int *errnop, + struct ldb_result *grlist) +{ + NSS_STATUS ret; + unsigned int i; + + for (i = 0; i < grlist->count; i++) { + + if (limit && (*start > limit)) { + /* TODO: warn no all groups were reported */ + *errnop = 0; + ret = NSS_STATUS_SUCCESS; + goto done; + } + + if (*start == *size) { + /* buffer full, enlarge it */ + long int gs; + gid_t *gm; + + gs = (*size) + 32; + if (limit && (gs > limit)) { + gs = limit; + } + + gm = (gid_t *)realloc((*groups), gs * sizeof(gid_t)); + if ( ! gm) { + *errnop = ENOMEM; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + *groups = gm; + *size = gs; + } + + (*groups)[*start] = ldb_msg_find_attr_as_int(grlist->msgs[i], "gidNumber", 0); + if ((*groups)[*start] == 0 || (*groups)[*start] == group) { + /* skip root group or primary group */ + continue; + } + (*start)++; + + } + + *errnop = 0; + ret = NSS_STATUS_SUCCESS; +done: + return ret; +} + +#define _LDB_NSS_ALLOC_CHECK(mem) do { if (!mem) { errno = ENOMEM; return NSS_STATUS_UNAVAIL; } } while(0) + +NSS_STATUS _ldb_nss_group_request(struct ldb_result **_res, + struct ldb_dn *group_dn, + const char * const *attrs, + const char *mattr) +{ + struct ldb_control **ctrls; + struct ldb_control *ctrl; + struct ldb_asq_control *asqc; + struct ldb_request *req; + int ret; + struct ldb_result *res = *_res; + + ctrls = talloc_array(res, struct ldb_control *, 2); + _LDB_NSS_ALLOC_CHECK(ctrls); + + ctrl = talloc(ctrls, struct ldb_control); + _LDB_NSS_ALLOC_CHECK(ctrl); + + asqc = talloc(ctrl, struct ldb_asq_control); + _LDB_NSS_ALLOC_CHECK(asqc); + + asqc->source_attribute = talloc_strdup(asqc, mattr); + _LDB_NSS_ALLOC_CHECK(asqc->source_attribute); + + asqc->request = 1; + asqc->src_attr_len = strlen(asqc->source_attribute); + ctrl->oid = LDB_CONTROL_ASQ_OID; + ctrl->critical = 1; + ctrl->data = asqc; + ctrls[0] = ctrl; + ctrls[1] = NULL; + + ret = ldb_build_search_req( + &req, + _ldb_nss_ctx->ldb, + res, + group_dn, + LDB_SCOPE_BASE, + "(objectClass=*)", + attrs, + ctrls, + res, + ldb_search_default_callback); + + if (ret != LDB_SUCCESS) { + errno = ENOENT; + return NSS_STATUS_UNAVAIL; + } + + ldb_set_timeout(_ldb_nss_ctx->ldb, req, 0); + + ret = ldb_request(_ldb_nss_ctx->ldb, req); + + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } else { + talloc_free(req); + return NSS_STATUS_UNAVAIL; + } + + talloc_free(req); + return NSS_STATUS_SUCCESS; +} + diff --git a/ldb-2.0.8/nssldb/ldb-nss.h b/ldb-2.0.8/nssldb/ldb-nss.h new file mode 100644 index 0000000..583876f --- /dev/null +++ b/ldb-2.0.8/nssldb/ldb-nss.h @@ -0,0 +1,84 @@ +/* + LDB nsswitch module + + Copyright (C) Simo Sorce 2006 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#ifndef _LDB_NSS +#define _LDB_NSS + +#include "includes.h" +#include "ldb/include/includes.h" + +#include +#include +#include + +#define _LDB_NSS_URL "etc/users.ldb" +#define _LDB_NSS_BASEDN "CN=Users,CN=System" +#define _LDB_NSS_PWENT_FILTER "(&(objectClass=posixAccount)(!(uidNumber=0))(!(gidNumber=0)))" +#define _LDB_NSS_PWUID_FILTER "(&(objectClass=posixAccount)(uidNumber=%d)(!(gidNumber=0)))" +#define _LDB_NSS_PWNAM_FILTER "(&(objectClass=posixAccount)(uid=%s)(!(uidNumber=0))(!(gidNumber=0)))" + +#define _LDB_NSS_GRENT_FILTER "(&(objectClass=posixGroup)(!(gidNumber=0)))" +#define _LDB_NSS_GRGID_FILTER "(&(objectClass=posixGroup)(gidNumber=%d)))" +#define _LDB_NSS_GRNAM_FILTER "(&(objectClass=posixGroup)(cn=%s)(!(gidNumber=0)))" + +typedef enum nss_status NSS_STATUS; + +struct _ldb_nss_context { + + pid_t pid; + + struct ldb_context *ldb; + struct ldb_dn *base; + + int pw_cur; + struct ldb_result *pw_res; + + int gr_cur; + struct ldb_result *gr_res; +}; + +NSS_STATUS _ldb_nss_init(void); + +NSS_STATUS _ldb_nss_fill_passwd(struct passwd *result, + char *buffer, + int buflen, + int *errnop, + struct ldb_message *msg); + +NSS_STATUS _ldb_nss_fill_group(struct group *result, + char *buffer, + int buflen, + int *errnop, + struct ldb_message *group, + struct ldb_result *members); + +NSS_STATUS _ldb_nss_fill_initgr(gid_t group, + long int limit, + long int *start, + long int *size, + gid_t **groups, + int *errnop, + struct ldb_result *grlist); + +NSS_STATUS _ldb_nss_group_request(struct ldb_result **res, + struct ldb_dn *group_dn, + const char * const *attrs, + const char *mattr); + +#endif /* _LDB_NSS */ diff --git a/ldb-2.0.8/nssldb/ldb-pwd.c b/ldb-2.0.8/nssldb/ldb-pwd.c new file mode 100644 index 0000000..6ab103a --- /dev/null +++ b/ldb-2.0.8/nssldb/ldb-pwd.c @@ -0,0 +1,242 @@ +/* + LDB nsswitch module + + Copyright (C) Simo Sorce 2006 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#include "ldb-nss.h" + +extern struct _ldb_nss_context *_ldb_nss_ctx; + +const char *_ldb_nss_pw_attrs[] = { + "uid", + "userPassword", + "uidNumber", + "gidNumber", + "gecos", + "homeDirectory", + "loginShell", + NULL +}; + +NSS_STATUS _nss_ldb_setpwent(void) +{ + int ret; + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + _ldb_nss_ctx->pw_cur = 0; + if (_ldb_nss_ctx->pw_res != NULL) { + talloc_free(_ldb_nss_ctx->pw_res); + _ldb_nss_ctx->pw_res = NULL; + } + + ret = ldb_search(_ldb_nss_ctx->ldb, + _ldb_nss_ctx->ldb, + &_ldb_nss_ctx->pw_res, + _ldb_nss_ctx->base, + LDB_SCOPE_SUBTREE, + _ldb_nss_pw_attrs, + _LDB_NSS_PWENT_FILTER); + if (ret != LDB_SUCCESS) { + return NSS_STATUS_UNAVAIL; + } + + return NSS_STATUS_SUCCESS; +} + +NSS_STATUS _nss_ldb_endpwent(void) +{ + int ret; + + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + _ldb_nss_ctx->pw_cur = 0; + if (_ldb_nss_ctx->pw_res) { + talloc_free(_ldb_nss_ctx->pw_res); + _ldb_nss_ctx->pw_res = NULL; + } + + return NSS_STATUS_SUCCESS; +} + +NSS_STATUS _nss_ldb_getpwent_r(struct passwd *result_buf, + char *buffer, + int buflen, + int *errnop) +{ + int ret; + + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + *errnop = 0; + + if (_ldb_nss_ctx->pw_cur >= _ldb_nss_ctx->pw_res->count) { + /* already returned all entries */ + return NSS_STATUS_NOTFOUND; + } + + ret = _ldb_nss_fill_passwd(result_buf, + buffer, + buflen, + errnop, + _ldb_nss_ctx->pw_res->msgs[_ldb_nss_ctx->pw_cur]); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + _ldb_nss_ctx->pw_cur++; + + return NSS_STATUS_SUCCESS; +} + +NSS_STATUS _nss_ldb_getpwuid_r(uid_t uid, struct passwd *result_buf, char *buffer, size_t buflen, int *errnop) +{ + int ret; + char *filter; + struct ldb_result *res; + + if (uid == 0) { /* we don't serve root uid by policy */ + *errnop = errno = ENOENT; + return NSS_STATUS_NOTFOUND; + } + + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + /* build the filter for this uid */ + filter = talloc_asprintf(_ldb_nss_ctx, _LDB_NSS_PWUID_FILTER, uid); + if (filter == NULL) { + /* this is a fatal error */ + *errnop = errno = ENOMEM; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + /* search the entry */ + ret = ldb_search(_ldb_nss_ctx->ldb, + _ldb_nss_ctx->ldb, + &res, + _ldb_nss_ctx->base, + LDB_SCOPE_SUBTREE, + _ldb_nss_pw_attrs, + filter); + if (ret != LDB_SUCCESS) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + /* if none found return */ + if (res->count == 0) { + *errnop = errno = ENOENT; + ret = NSS_STATUS_NOTFOUND; + goto done; + } + + if (res->count != 1) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + /* fill in the passwd struct */ + ret = _ldb_nss_fill_passwd(result_buf, + buffer, + buflen, + errnop, + res->msgs[0]); + +done: + talloc_free(filter); + talloc_free(res); + return ret; +} + +NSS_STATUS _nss_ldb_getpwnam_r(const char *name, struct passwd *result_buf, char *buffer, size_t buflen, int *errnop) +{ + int ret; + char *filter; + struct ldb_result *res; + + ret = _ldb_nss_init(); + if (ret != NSS_STATUS_SUCCESS) { + return ret; + } + + /* build the filter for this name */ + filter = talloc_asprintf(_ldb_nss_ctx, _LDB_NSS_PWNAM_FILTER, name); + if (filter == NULL) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + /* search the entry */ + ret = ldb_search(_ldb_nss_ctx->ldb, + _ldb_nss_ctx->ldb, + &res, + _ldb_nss_ctx->base, + LDB_SCOPE_SUBTREE, + _ldb_nss_pw_attrs, + filter); + if (ret != LDB_SUCCESS) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + /* if none found return */ + if (res->count == 0) { + *errnop = errno = ENOENT; + ret = NSS_STATUS_NOTFOUND; + goto done; + } + + if (res->count != 1) { + /* this is a fatal error */ + *errnop = errno = ENOENT; + ret = NSS_STATUS_UNAVAIL; + goto done; + } + + /* fill in the passwd struct */ + ret = _ldb_nss_fill_passwd(result_buf, + buffer, + buflen, + errnop, + res->msgs[0]); + +done: + talloc_free(filter); + talloc_free(res); + return ret; +} + diff --git a/ldb-2.0.8/pyldb-util.pc.in b/ldb-2.0.8/pyldb-util.pc.in new file mode 100644 index 0000000..60ec702 --- /dev/null +++ b/ldb-2.0.8/pyldb-util.pc.in @@ -0,0 +1,13 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +modulesdir=@LDB_MODULESDIR@ + +Name: pyldb-util@PYTHON_SO_ABI_FLAG@ +Description: Python bindings for LDB +Version: @PACKAGE_VERSION@ +Requires: ldb +Libs: @LIB_RPATH@ -L${libdir} -lpyldb-util@PYTHON_LIBNAME_SO_ABI_FLAG@ +Cflags: -I${includedir} +URL: http://ldb.samba.org/ diff --git a/ldb-2.0.8/pyldb.c b/ldb-2.0.8/pyldb.c new file mode 100644 index 0000000..868e366 --- /dev/null +++ b/ldb-2.0.8/pyldb.c @@ -0,0 +1,4470 @@ +/* + Unix SMB/CIFS implementation. + + Python interface to ldb. + + Copyright (C) 2005,2006 Tim Potter + Copyright (C) 2006 Simo Sorce + Copyright (C) 2007-2010 Jelmer Vernooij + Copyright (C) 2009-2010 Matthias Dieter Wallnöfer + Copyright (C) 2009-2011 Andrew Tridgell + Copyright (C) 2009-2011 Andrew Bartlett + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include +#include "ldb_private.h" +#include "ldb_handlers.h" +#include "pyldb.h" +#include "dlinklist.h" + +/* discard signature of 'func' in favour of 'target_sig' */ +#define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func + +struct py_ldb_search_iterator_reply; + +typedef struct { + PyObject_HEAD + TALLOC_CTX *mem_ctx; + PyLdbObject *ldb; + struct { + struct ldb_request *req; + struct py_ldb_search_iterator_reply *next; + struct py_ldb_search_iterator_reply *result; + PyObject *exception; + } state; +} PyLdbSearchIteratorObject; + +struct py_ldb_search_iterator_reply { + struct py_ldb_search_iterator_reply *prev, *next; + PyLdbSearchIteratorObject *py_iter; + PyObject *obj; +}; + +void initldb(void); +static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg); +static PyObject *PyExc_LdbError; + +static PyTypeObject PyLdbControl; +static PyTypeObject PyLdbResult; +static PyTypeObject PyLdbSearchIterator; +static PyTypeObject PyLdbMessage; +#define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage) +static PyTypeObject PyLdbModule; +static PyTypeObject PyLdbDn; +#define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn) +static PyTypeObject PyLdb; +#define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb) +static PyTypeObject PyLdbMessageElement; +#define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement) + +static PyTypeObject PyLdbTree; +static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx); +static PyObject *PyLdbModule_FromModule(struct ldb_module *mod); +static struct ldb_message_element *PyObject_AsMessageElement( + TALLOC_CTX *mem_ctx, + PyObject *set_obj, + unsigned int flags, + const char *attr_name); +static PyTypeObject PyLdbBytesType; + +#if PY_MAJOR_VERSION >= 3 +#define PyInt_FromLong PyLong_FromLong + +#define PYARG_STR_UNI "es" + +static PyObject *PyLdbBytes_FromStringAndSize(const char *msg, int size) +{ + PyObject* result = NULL; + PyObject* args = NULL; + args = Py_BuildValue("(y#)", msg, size); + result = PyLdbBytesType.tp_new(&PyLdbBytesType, args, NULL); + Py_DECREF(args); + return result; +} +#else +#define PyLdbBytes_FromStringAndSize PyString_FromStringAndSize + +#define PYARG_STR_UNI "et" + +#endif + +static PyObject *richcmp(int cmp_val, int op) +{ + int ret; + switch (op) { + case Py_LT: ret = cmp_val < 0; break; + case Py_LE: ret = cmp_val <= 0; break; + case Py_EQ: ret = cmp_val == 0; break; + case Py_NE: ret = cmp_val != 0; break; + case Py_GT: ret = cmp_val > 0; break; + case Py_GE: ret = cmp_val >= 0; break; + default: + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + return PyBool_FromLong(ret); +} + + +static PyObject *py_ldb_control_str(PyLdbControlObject *self) +{ + if (self->data != NULL) { + char* control = ldb_control_to_string(self->mem_ctx, self->data); + if (control == NULL) { + PyErr_NoMemory(); + return NULL; + } + return PyUnicode_FromString(control); + } else { + return PyUnicode_FromString("ldb control"); + } +} + +static void py_ldb_control_dealloc(PyLdbControlObject *self) +{ + if (self->mem_ctx != NULL) { + talloc_free(self->mem_ctx); + } + self->data = NULL; + Py_TYPE(self)->tp_free(self); +} + +/* Create a text (rather than bytes) interface for a LDB result object */ +static PyObject *wrap_text(const char *type, PyObject *wrapped) +{ + PyObject *mod, *cls, *constructor, *inst; + mod = PyImport_ImportModule("_ldb_text"); + if (mod == NULL) + return NULL; + cls = PyObject_GetAttrString(mod, type); + Py_DECREF(mod); + if (cls == NULL) { + Py_DECREF(mod); + return NULL; + } + constructor = PyObject_GetAttrString(cls, "_wrap"); + Py_DECREF(cls); + if (constructor == NULL) { + return NULL; + } + inst = PyObject_CallFunction(constructor, discard_const_p(char, "O"), wrapped); + Py_DECREF(constructor); + return inst; +} + +static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self, + PyObject *Py_UNUSED(ignored)) +{ + return PyUnicode_FromString(self->data->oid); +} + +static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self, + PyObject *Py_UNUSED(ignored)) +{ + return PyBool_FromLong(self->data->critical); +} + +static int py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure) +{ + if (PyObject_IsTrue(value)) { + self->data->critical = true; + } else { + self->data->critical = false; + } + return 0; +} + +static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + char *data = NULL; + const char * const kwnames[] = { "ldb", "data", NULL }; + struct ldb_control *parsed_controls; + PyLdbControlObject *ret; + PyObject *py_ldb; + TALLOC_CTX *mem_ctx; + struct ldb_context *ldb_ctx; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!s", + discard_const_p(char *, kwnames), + &PyLdb, &py_ldb, &data)) + return NULL; + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb); + parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data); + + if (!parsed_controls) { + talloc_free(mem_ctx); + PyErr_SetString(PyExc_ValueError, "unable to parse control string"); + return NULL; + } + + ret = PyObject_New(PyLdbControlObject, type); + if (ret == NULL) { + PyErr_NoMemory(); + talloc_free(mem_ctx); + return NULL; + } + + ret->mem_ctx = mem_ctx; + + ret->data = talloc_move(mem_ctx, &parsed_controls); + if (ret->data == NULL) { + Py_DECREF(ret); + PyErr_NoMemory(); + talloc_free(mem_ctx); + return NULL; + } + + return (PyObject *)ret; +} + +static PyGetSetDef py_ldb_control_getset[] = { + { + .name = discard_const_p(char, "oid"), + .get = (getter)py_ldb_control_get_oid, + }, + { + .name = discard_const_p(char, "critical"), + .get = (getter)py_ldb_control_get_critical, + .set = (setter)py_ldb_control_set_critical, + }, + { .name = NULL }, +}; + +static PyTypeObject PyLdbControl = { + .tp_name = "ldb.control", + .tp_dealloc = (destructor)py_ldb_control_dealloc, + .tp_getattro = PyObject_GenericGetAttr, + .tp_basicsize = sizeof(PyLdbControlObject), + .tp_getset = py_ldb_control_getset, + .tp_doc = "LDB control.", + .tp_str = (reprfunc)py_ldb_control_str, + .tp_new = py_ldb_control_new, + .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, +}; + +static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx) +{ + if (ret == LDB_ERR_PYTHON_EXCEPTION) + return; /* Python exception should already be set, just keep that */ + + PyErr_SetObject(error, + Py_BuildValue(discard_const_p(char, "(i,s)"), ret, + ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx))); +} +static PyObject *py_ldb_bytes_str(PyBytesObject *self) +{ + char *msg = NULL; + Py_ssize_t size; + int result = 0; + if (!PyBytes_Check(self)) { + PyErr_Format(PyExc_TypeError,"Unexpected type"); + return NULL; + } + result = PyBytes_AsStringAndSize((PyObject *)self, &msg, &size); + if (result != 0) { + PyErr_Format(PyExc_TypeError, "Failed to extract bytes"); + return NULL; + } + return PyUnicode_FromStringAndSize(msg, size); +} + +static PyTypeObject PyLdbBytesType = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "ldb.bytes", + .tp_doc = "str/bytes (with custom str)", + .tp_str = (reprfunc)py_ldb_bytes_str, + .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, +}; + +static PyObject *PyObject_FromLdbValue(const struct ldb_val *val) +{ + return PyLdbBytes_FromStringAndSize((const char *)val->data, val->length); +} + +static PyObject *PyStr_FromLdbValue(const struct ldb_val *val) +{ + return PyUnicode_FromStringAndSize((const char *)val->data, val->length); +} + +/** + * Create a Python object from a ldb_result. + * + * @param result LDB result to convert + * @return Python object with converted result (a list object) + */ +static PyObject *PyLdbControl_FromControl(struct ldb_control *control) +{ + TALLOC_CTX *ctl_ctx = talloc_new(NULL); + PyLdbControlObject *ctrl; + if (ctl_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0); + if (ctrl == NULL) { + talloc_free(ctl_ctx); + PyErr_NoMemory(); + return NULL; + } + ctrl->mem_ctx = ctl_ctx; + ctrl->data = talloc_steal(ctrl->mem_ctx, control); + if (ctrl->data == NULL) { + Py_DECREF(ctrl); + PyErr_NoMemory(); + return NULL; + } + return (PyObject*) ctrl; +} + +/** + * Create a Python object from a ldb_result. + * + * @param result LDB result to convert + * @return Python object with converted result (a list object) + */ +static PyObject *PyLdbResult_FromResult(struct ldb_result *result) +{ + PyLdbResultObject *ret; + PyObject *list, *controls, *referals; + Py_ssize_t i; + + if (result == NULL) { + Py_RETURN_NONE; + } + + ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0); + if (ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + + list = PyList_New(result->count); + if (list == NULL) { + PyErr_NoMemory(); + Py_DECREF(ret); + return NULL; + } + + for (i = 0; i < result->count; i++) { + PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i])); + } + + ret->mem_ctx = talloc_new(NULL); + if (ret->mem_ctx == NULL) { + Py_DECREF(list); + Py_DECREF(ret); + PyErr_NoMemory(); + return NULL; + } + + ret->msgs = list; + + if (result->controls) { + i = 0; + while (result->controls[i]) { + i++; + } + controls = PyList_New(i); + if (controls == NULL) { + Py_DECREF(ret); + PyErr_NoMemory(); + return NULL; + } + for (i=0; result->controls[i]; i++) { + PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]); + if (ctrl == NULL) { + Py_DECREF(ret); + Py_DECREF(controls); + PyErr_NoMemory(); + return NULL; + } + PyList_SetItem(controls, i, ctrl); + } + } else { + /* + * No controls so we keep an empty list + */ + controls = PyList_New(0); + if (controls == NULL) { + Py_DECREF(ret); + PyErr_NoMemory(); + return NULL; + } + } + + ret->controls = controls; + + i = 0; + + while (result->refs && result->refs[i]) { + i++; + } + + referals = PyList_New(i); + if (referals == NULL) { + Py_DECREF(ret); + PyErr_NoMemory(); + return NULL; + } + + for (i = 0;result->refs && result->refs[i]; i++) { + PyList_SetItem(referals, i, PyUnicode_FromString(result->refs[i])); + } + ret->referals = referals; + return (PyObject *)ret; +} + +/** + * Create a LDB Result from a Python object. + * If conversion fails, NULL will be returned and a Python exception set. + * + * Note: the result object only includes the messages at the moment; extended + * result, controls and referrals are ignored. + * + * @param mem_ctx Memory context in which to allocate the LDB Result + * @param obj Python object to convert + * @return a ldb_result, or NULL if the conversion failed + */ +static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx, + PyObject *obj) +{ + struct ldb_result *res; + Py_ssize_t i; + + if (obj == Py_None) + return NULL; + + res = talloc_zero(mem_ctx, struct ldb_result); + res->count = PyList_Size(obj); + res->msgs = talloc_array(res, struct ldb_message *, res->count); + for (i = 0; i < res->count; i++) { + PyObject *item = PyList_GetItem(obj, i); + res->msgs[i] = pyldb_Message_AsMessage(item); + } + return res; +} + +static PyObject *py_ldb_dn_validate(PyLdbDnObject *self, + PyObject *Py_UNUSED(ignored)) +{ + return PyBool_FromLong(ldb_dn_validate(self->dn)); +} + +static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self, + PyObject *Py_UNUSED(ignored)) +{ + return PyBool_FromLong(ldb_dn_is_valid(self->dn)); +} + +static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self, + PyObject *Py_UNUSED(ignored)) +{ + return PyBool_FromLong(ldb_dn_is_special(self->dn)); +} + +static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self, + PyObject *Py_UNUSED(ignored)) +{ + return PyBool_FromLong(ldb_dn_is_null(self->dn)); +} + +static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self, + PyObject *Py_UNUSED(ignored)) +{ + return PyUnicode_FromString(ldb_dn_get_casefold(self->dn)); +} + +static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self) +{ + return PyUnicode_FromString(ldb_dn_get_linearized(self->dn)); +} + +static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self, + PyObject *Py_UNUSED(ignored)) +{ + return PyUnicode_FromString(ldb_dn_canonical_string(self->dn, self->dn)); +} + +static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self, + PyObject *Py_UNUSED(ignored)) +{ + return PyUnicode_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn)); +} + +static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs) +{ + const char * const kwnames[] = { "mode", NULL }; + int mode = 1; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", + discard_const_p(char *, kwnames), + &mode)) + return NULL; + return PyUnicode_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode)); +} + +static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args) +{ + char *name; + const struct ldb_val *val; + + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + val = ldb_dn_get_extended_component(self->dn, name); + if (val == NULL) { + Py_RETURN_NONE; + } + + return PyBytes_FromStringAndSize((const char *)val->data, val->length); +} + +static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args) +{ + char *name; + int err; + uint8_t *value = NULL; + Py_ssize_t size = 0; + + if (!PyArg_ParseTuple(args, "sz#", &name, (char **)&value, &size)) + return NULL; + + if (value == NULL) { + err = ldb_dn_set_extended_component(self->dn, name, NULL); + } else { + struct ldb_val val; + val.data = (uint8_t *)value; + val.length = size; + err = ldb_dn_set_extended_component(self->dn, name, &val); + } + + if (err != LDB_SUCCESS) { + PyErr_SetString(PyExc_TypeError, "Failed to set extended component"); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_dn_repr(PyLdbDnObject *self) +{ + PyObject *str = PyUnicode_FromString(ldb_dn_get_linearized(self->dn)); + PyObject *repr, *result; + if (str == NULL) + return NULL; + repr = PyObject_Repr(str); + if (repr == NULL) { + Py_DECREF(str); + return NULL; + } + result = PyUnicode_FromFormat("Dn(%s)", PyUnicode_AsUTF8(repr)); + Py_DECREF(str); + Py_DECREF(repr); + return result; +} + +static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args) +{ + char *name; + + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + + return PyBool_FromLong(ldb_dn_check_special(self->dn, name)); +} + +static PyObject *py_ldb_dn_richcmp(PyObject *dn1, PyObject *dn2, int op) +{ + int ret; + if (!pyldb_Dn_Check(dn2)) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + ret = ldb_dn_compare(pyldb_Dn_AsDn(dn1), pyldb_Dn_AsDn(dn2)); + return richcmp(ret, op); +} + +static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self, + PyObject *Py_UNUSED(ignored)) +{ + struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self); + struct ldb_dn *parent; + PyLdbDnObject *py_ret; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + + parent = ldb_dn_get_parent(mem_ctx, dn); + if (parent == NULL) { + talloc_free(mem_ctx); + Py_RETURN_NONE; + } + + py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0); + if (py_ret == NULL) { + PyErr_NoMemory(); + talloc_free(mem_ctx); + return NULL; + } + py_ret->mem_ctx = mem_ctx; + py_ret->dn = parent; + return (PyObject *)py_ret; +} + +static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args) +{ + PyObject *py_other; + struct ldb_dn *dn, *other; + if (!PyArg_ParseTuple(args, "O", &py_other)) + return NULL; + + dn = pyldb_Dn_AsDn((PyObject *)self); + + if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other)) + return NULL; + + return PyBool_FromLong(ldb_dn_add_child(dn, other)); +} + +static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args) +{ + PyObject *py_other; + struct ldb_dn *other, *dn; + if (!PyArg_ParseTuple(args, "O", &py_other)) + return NULL; + + dn = pyldb_Dn_AsDn((PyObject *)self); + + if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other)) + return NULL; + + return PyBool_FromLong(ldb_dn_add_base(dn, other)); +} + +static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args) +{ + struct ldb_dn *dn; + int i; + if (!PyArg_ParseTuple(args, "i", &i)) + return NULL; + + dn = pyldb_Dn_AsDn((PyObject *)self); + + return PyBool_FromLong(ldb_dn_remove_base_components(dn, i)); +} + +static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args) +{ + PyObject *py_base; + struct ldb_dn *dn, *base; + if (!PyArg_ParseTuple(args, "O", &py_base)) + return NULL; + + dn = pyldb_Dn_AsDn((PyObject *)self); + + if (!pyldb_Object_AsDn(NULL, py_base, ldb_dn_get_ldb_context(dn), &base)) + return NULL; + + return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0); +} + +static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args) +{ + struct ldb_dn *dn; + const char *name; + unsigned int num = 0; + + if (!PyArg_ParseTuple(args, "I", &num)) + return NULL; + + dn = pyldb_Dn_AsDn((PyObject *)self); + + name = ldb_dn_get_component_name(dn, num); + if (name == NULL) { + Py_RETURN_NONE; + } + + return PyUnicode_FromString(name); +} + +static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args) +{ + struct ldb_dn *dn; + const struct ldb_val *val; + unsigned int num = 0; + + if (!PyArg_ParseTuple(args, "I", &num)) + return NULL; + + dn = pyldb_Dn_AsDn((PyObject *)self); + + val = ldb_dn_get_component_val(dn, num); + if (val == NULL) { + Py_RETURN_NONE; + } + + return PyStr_FromLdbValue(val); +} + +static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args) +{ + unsigned int num = 0; + char *name = NULL, *value = NULL; + struct ldb_val val = { NULL, }; + int err; + Py_ssize_t size = 0; + + if (!PyArg_ParseTuple(args, "Iss#", &num, &name, &value, &size)) + return NULL; + + val.data = (unsigned char*) value; + val.length = size; + + err = ldb_dn_set_component(self->dn, num, name, val); + if (err != LDB_SUCCESS) { + PyErr_SetString(PyExc_TypeError, "Failed to set component"); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self, + PyObject *Py_UNUSED(ignored)) +{ + struct ldb_dn *dn; + const char *name; + + dn = pyldb_Dn_AsDn((PyObject *)self); + + name = ldb_dn_get_rdn_name(dn); + if (name == NULL) { + Py_RETURN_NONE; + } + + return PyUnicode_FromString(name); +} + +static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self, + PyObject *Py_UNUSED(ignored)) +{ + struct ldb_dn *dn; + const struct ldb_val *val; + + dn = pyldb_Dn_AsDn((PyObject *)self); + + val = ldb_dn_get_rdn_val(dn); + if (val == NULL) { + Py_RETURN_NONE; + } + + return PyStr_FromLdbValue(val); +} + +static PyMethodDef py_ldb_dn_methods[] = { + { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS, + "S.validate() -> bool\n" + "Validate DN is correct." }, + { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS, + "S.is_valid() -> bool\n" }, + { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS, + "S.is_special() -> bool\n" + "Check whether this is a special LDB DN." }, + { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS, + "Check whether this is a null DN." }, + { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS, + NULL }, + { "get_linearized", PY_DISCARD_FUNC_SIG(PyCFunction, + py_ldb_dn_get_linearized), + METH_NOARGS, + NULL }, + { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS, + "S.canonical_str() -> string\n" + "Canonical version of this DN (like a posix path)." }, + { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS, + "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"}, + { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS, + "S.canonical_ex_str() -> string\n" + "Canonical version of this DN (like a posix path, with terminating newline)." }, + { "extended_str", PY_DISCARD_FUNC_SIG(PyCFunction, + py_ldb_dn_extended_str), + METH_VARARGS | METH_KEYWORDS, + "S.extended_str(mode=1) -> string\n" + "Extended version of this DN" }, + { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS, + "S.parent() -> dn\n" + "Get the parent for this DN." }, + { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS, + "S.add_child(dn) -> None\n" + "Add a child DN to this DN." }, + { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS, + "S.add_base(dn) -> None\n" + "Add a base DN to this DN." }, + { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS, + "S.remove_base_components(int) -> bool\n" + "Remove a number of DN components from the base of this DN." }, + { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS, + "S.check_special(name) -> bool\n\n" + "Check if name is a special DN name"}, + { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS, + "S.get_extended_component(name) -> string\n\n" + "returns a DN extended component as a binary string"}, + { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS, + "S.set_extended_component(name, value) -> None\n\n" + "set a DN extended component as a binary string"}, + { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS, + "S.get_component_name(num) -> string\n" + "get the attribute name of the specified component" }, + { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS, + "S.get_component_value(num) -> string\n" + "get the attribute value of the specified component as a binary string" }, + { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS, + "S.get_component_value(num, name, value) -> None\n" + "set the attribute name and value of the specified component" }, + { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS, + "S.get_rdn_name() -> string\n" + "get the RDN attribute name" }, + { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS, + "S.get_rdn_value() -> string\n" + "get the RDN attribute value as a binary string" }, + { NULL } +}; + +static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self) +{ + return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self)); +} + +/* + copy a DN as a python object + */ +static PyObject *py_ldb_dn_copy(struct ldb_dn *dn) +{ + PyLdbDnObject *py_ret; + + py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0); + if (py_ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + py_ret->mem_ctx = talloc_new(NULL); + py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn); + return (PyObject *)py_ret; +} + +static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other) +{ + struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self), + *other; + PyLdbDnObject *py_ret; + + if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other)) + return NULL; + + py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0); + if (py_ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + py_ret->mem_ctx = talloc_new(NULL); + py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn); + ldb_dn_add_base(py_ret->dn, other); + return (PyObject *)py_ret; +} + +static PySequenceMethods py_ldb_dn_seq = { + .sq_length = (lenfunc)py_ldb_dn_len, + .sq_concat = (binaryfunc)py_ldb_dn_concat, +}; + +static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + struct ldb_dn *ret = NULL; + char *str = NULL; + PyObject *py_ldb = NULL; + struct ldb_context *ldb_ctx = NULL; + TALLOC_CTX *mem_ctx = NULL; + PyLdbDnObject *py_ret = NULL; + const char * const kwnames[] = { "ldb", "dn", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O"PYARG_STR_UNI, + discard_const_p(char *, kwnames), + &py_ldb, "utf8", &str)) + goto out; + + if (!PyLdb_Check(py_ldb)) { + PyErr_SetString(PyExc_TypeError, "Expected Ldb"); + goto out; + } + + ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb); + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + goto out; + } + + ret = ldb_dn_new(mem_ctx, ldb_ctx, str); + if (!ldb_dn_validate(ret)) { + talloc_free(mem_ctx); + PyErr_SetString(PyExc_ValueError, "unable to parse dn string"); + goto out; + } + + py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0); + if (py_ret == NULL) { + talloc_free(mem_ctx); + PyErr_NoMemory(); + goto out; + } + py_ret->mem_ctx = mem_ctx; + py_ret->dn = ret; +out: + if (str != NULL) { + PyMem_Free(discard_const_p(char, str)); + } + return (PyObject *)py_ret; +} + +static void py_ldb_dn_dealloc(PyLdbDnObject *self) +{ + talloc_free(self->mem_ctx); + PyObject_Del(self); +} + +static PyTypeObject PyLdbDn = { + .tp_name = "ldb.Dn", + .tp_methods = py_ldb_dn_methods, + .tp_str = (reprfunc)py_ldb_dn_get_linearized, + .tp_repr = (reprfunc)py_ldb_dn_repr, + .tp_richcompare = (richcmpfunc)py_ldb_dn_richcmp, + .tp_as_sequence = &py_ldb_dn_seq, + .tp_doc = "A LDB distinguished name.", + .tp_new = py_ldb_dn_new, + .tp_dealloc = (destructor)py_ldb_dn_dealloc, + .tp_basicsize = sizeof(PyLdbDnObject), + .tp_flags = Py_TPFLAGS_DEFAULT, +}; + +/* Debug */ +static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0); +static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) +{ + PyObject *fn = (PyObject *)context; + PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyUnicode_FromFormatV(fmt, ap)); +} + +static PyObject *py_ldb_debug_func; + +static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args) +{ + PyObject *cb; + struct ldb_context *ldb_ctx; + + if (!PyArg_ParseTuple(args, "O", &cb)) + return NULL; + + if (py_ldb_debug_func != NULL) { + Py_DECREF(py_ldb_debug_func); + } + + Py_INCREF(cb); + /* FIXME: DECREF cb when exiting program */ + py_ldb_debug_func = cb; + ldb_ctx = pyldb_Ldb_AsLdbContext(self); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, + ldb_set_debug(ldb_ctx, py_ldb_debug, cb), + ldb_ctx); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args) +{ + unsigned int perms; + if (!PyArg_ParseTuple(args, "I", &perms)) + return NULL; + + ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args) +{ + char *modules_dir; + if (!PyArg_ParseTuple(args, "s", &modules_dir)) + return NULL; + + ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_transaction_start(PyLdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); + int ldb_err; + ldb_err = ldb_transaction_start(ldb_ctx); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx); + Py_RETURN_NONE; +} + +static PyObject *py_ldb_transaction_commit(PyLdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); + int ldb_err; + ldb_err = ldb_transaction_commit(ldb_ctx); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx); + Py_RETURN_NONE; +} + +static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); + int ldb_err; + ldb_err = ldb_transaction_prepare_commit(ldb_ctx); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx); + Py_RETURN_NONE; +} + +static PyObject *py_ldb_transaction_cancel(PyLdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); + int ldb_err; + ldb_err = ldb_transaction_cancel(ldb_ctx); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx); + Py_RETURN_NONE; +} + +static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); + int ldb_err; + ldb_err = ldb_setup_wellknown_attributes(ldb_ctx); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx); + Py_RETURN_NONE; +} + +static PyObject *py_ldb_repr(PyLdbObject *self) +{ + return PyUnicode_FromString(""); +} + +static PyObject *py_ldb_get_root_basedn(PyLdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self)); + if (dn == NULL) + Py_RETURN_NONE; + return py_ldb_dn_copy(dn); +} + + +static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self)); + if (dn == NULL) + Py_RETURN_NONE; + return py_ldb_dn_copy(dn); +} + +static PyObject *py_ldb_get_config_basedn(PyLdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self)); + if (dn == NULL) + Py_RETURN_NONE; + return py_ldb_dn_copy(dn); +} + +static PyObject *py_ldb_get_default_basedn(PyLdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self)); + if (dn == NULL) + Py_RETURN_NONE; + return py_ldb_dn_copy(dn); +} + +static const char **PyList_AsStrList(TALLOC_CTX *mem_ctx, PyObject *list, + const char *paramname) +{ + const char **ret; + Py_ssize_t i; + if (!PyList_Check(list)) { + PyErr_Format(PyExc_TypeError, "%s is not a list", paramname); + return NULL; + } + ret = talloc_array(NULL, const char *, PyList_Size(list)+1); + if (ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + + for (i = 0; i < PyList_Size(list); i++) { + const char *str = NULL; + Py_ssize_t size; + PyObject *item = PyList_GetItem(list, i); + if (!PyUnicode_Check(item)) { + PyErr_Format(PyExc_TypeError, "%s should be strings", paramname); + talloc_free(ret); + return NULL; + } + str = PyUnicode_AsUTF8AndSize(item, &size); + if (str == NULL) { + talloc_free(ret); + return NULL; + } + ret[i] = talloc_strndup(ret, str, size); + } + ret[i] = NULL; + return ret; +} + +static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs) +{ + const char * const kwnames[] = { "url", "flags", "options", NULL }; + char *url = NULL; + PyObject *py_options = Py_None; + const char **options; + unsigned int flags = 0; + int ret; + struct ldb_context *ldb; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__", + discard_const_p(char *, kwnames), + &url, &flags, &py_options)) + return -1; + + ldb = pyldb_Ldb_AsLdbContext(self); + + if (py_options == Py_None) { + options = NULL; + } else { + options = PyList_AsStrList(ldb, py_options, "options"); + if (options == NULL) + return -1; + } + + if (url != NULL) { + ret = ldb_connect(ldb, url, flags, options); + if (ret != LDB_SUCCESS) { + PyErr_SetLdbError(PyExc_LdbError, ret, ldb); + return -1; + } + } else { + ldb_set_flags(ldb, flags); + } + + talloc_free(options); + return 0; +} + +static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyLdbObject *ret; + struct ldb_context *ldb; + ret = (PyLdbObject *)type->tp_alloc(type, 0); + if (ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + ret->mem_ctx = talloc_new(NULL); + ldb = ldb_init(ret->mem_ctx, NULL); + + if (ldb == NULL) { + PyErr_NoMemory(); + return NULL; + } + + ret->ldb_ctx = ldb; + return (PyObject *)ret; +} + +static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs) +{ + char *url = NULL; + unsigned int flags = 0; + PyObject *py_options = Py_None; + int ret; + const char **options; + const char * const kwnames[] = { "url", "flags", "options", NULL }; + struct ldb_context *ldb_ctx; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|IO", + discard_const_p(char *, kwnames), + &url, &flags, &py_options)) + return NULL; + + if (py_options == Py_None) { + options = NULL; + } else { + options = PyList_AsStrList(NULL, py_options, "options"); + if (options == NULL) + return NULL; + } + + ldb_ctx = pyldb_Ldb_AsLdbContext(self); + ret = ldb_connect(ldb_ctx, url, flags, options); + talloc_free(options); + + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *py_msg; + PyObject *py_controls = Py_None; + struct ldb_context *ldb_ctx; + struct ldb_request *req; + struct ldb_control **parsed_controls; + struct ldb_message *msg; + int ret; + TALLOC_CTX *mem_ctx; + bool validate=true; + const char * const kwnames[] = { "message", "controls", "validate", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob", + discard_const_p(char *, kwnames), + &py_msg, &py_controls, &validate)) + return NULL; + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + ldb_ctx = pyldb_Ldb_AsLdbContext(self); + + if (py_controls == Py_None) { + parsed_controls = NULL; + } else { + const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls"); + if (controls == NULL) { + talloc_free(mem_ctx); + return NULL; + } + parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); + talloc_free(controls); + } + + if (!PyLdbMessage_Check(py_msg)) { + PyErr_SetString(PyExc_TypeError, "Expected Ldb Message"); + talloc_free(mem_ctx); + return NULL; + } + msg = pyldb_Message_AsMessage(py_msg); + + if (validate) { + ret = ldb_msg_sanity_check(ldb_ctx, msg); + if (ret != LDB_SUCCESS) { + PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); + talloc_free(mem_ctx); + return NULL; + } + } + + ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls, + NULL, ldb_op_default_callback, NULL); + if (ret != LDB_SUCCESS) { + PyErr_SetString(PyExc_TypeError, "failed to build request"); + talloc_free(mem_ctx); + return NULL; + } + + /* do request and autostart a transaction */ + /* Then let's LDB handle the message error in case of pb as they are meaningful */ + + ret = ldb_transaction_start(ldb_ctx); + if (ret != LDB_SUCCESS) { + talloc_free(mem_ctx); + PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); + return NULL; + } + + ret = ldb_request(ldb_ctx, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + if (ret == LDB_SUCCESS) { + ret = ldb_transaction_commit(ldb_ctx); + } else { + ldb_transaction_cancel(ldb_ctx); + } + + talloc_free(mem_ctx); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); + + Py_RETURN_NONE; +} + + +/** + * Obtain a ldb message from a Python Dictionary object. + * + * @param mem_ctx Memory context + * @param py_obj Python Dictionary object + * @param ldb_ctx LDB context + * @param mod_flags Flags to be set on every message element + * @return ldb_message on success or NULL on failure + */ +static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx, + PyObject *py_obj, + struct ldb_context *ldb_ctx, + unsigned int mod_flags) +{ + struct ldb_message *msg; + unsigned int msg_pos = 0; + Py_ssize_t dict_pos = 0; + PyObject *key, *value; + struct ldb_message_element *msg_el; + PyObject *dn_value = PyDict_GetItemString(py_obj, "dn"); + + msg = ldb_msg_new(mem_ctx); + if (msg == NULL) { + PyErr_NoMemory(); + return NULL; + } + msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj)); + + if (dn_value) { + if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) { + PyErr_SetString(PyExc_TypeError, "unable to import dn object"); + return NULL; + } + if (msg->dn == NULL) { + PyErr_SetString(PyExc_TypeError, "dn set but not found"); + return NULL; + } + } else { + PyErr_SetString(PyExc_TypeError, "no dn set"); + return NULL; + } + + while (PyDict_Next(py_obj, &dict_pos, &key, &value)) { + const char *key_str = PyUnicode_AsUTF8(key); + if (ldb_attr_cmp(key_str, "dn") != 0) { + msg_el = PyObject_AsMessageElement(msg->elements, value, + mod_flags, key_str); + if (msg_el == NULL) { + PyErr_Format(PyExc_TypeError, "unable to import element '%s'", key_str); + return NULL; + } + memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el)); + msg_pos++; + } + } + + msg->num_elements = msg_pos; + + return msg; +} + +static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *py_obj; + int ret; + struct ldb_context *ldb_ctx; + struct ldb_request *req; + struct ldb_message *msg = NULL; + PyObject *py_controls = Py_None; + TALLOC_CTX *mem_ctx; + struct ldb_control **parsed_controls; + const char * const kwnames[] = { "message", "controls", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", + discard_const_p(char *, kwnames), + &py_obj, &py_controls)) + return NULL; + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + ldb_ctx = pyldb_Ldb_AsLdbContext(self); + + if (py_controls == Py_None) { + parsed_controls = NULL; + } else { + const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls"); + if (controls == NULL) { + talloc_free(mem_ctx); + return NULL; + } + parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); + talloc_free(controls); + } + + if (PyLdbMessage_Check(py_obj)) { + msg = pyldb_Message_AsMessage(py_obj); + } else if (PyDict_Check(py_obj)) { + msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD); + } else { + PyErr_SetString(PyExc_TypeError, + "Dictionary or LdbMessage object expected!"); + } + + if (!msg) { + /* we should have a PyErr already set */ + talloc_free(mem_ctx); + return NULL; + } + + ret = ldb_msg_sanity_check(ldb_ctx, msg); + if (ret != LDB_SUCCESS) { + PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); + talloc_free(mem_ctx); + return NULL; + } + + ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls, + NULL, ldb_op_default_callback, NULL); + if (ret != LDB_SUCCESS) { + PyErr_SetString(PyExc_TypeError, "failed to build request"); + talloc_free(mem_ctx); + return NULL; + } + + /* do request and autostart a transaction */ + /* Then let's LDB handle the message error in case of pb as they are meaningful */ + + ret = ldb_transaction_start(ldb_ctx); + if (ret != LDB_SUCCESS) { + talloc_free(mem_ctx); + PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); + return NULL; + } + + ret = ldb_request(ldb_ctx, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + if (ret == LDB_SUCCESS) { + ret = ldb_transaction_commit(ldb_ctx); + } else { + ldb_transaction_cancel(ldb_ctx); + } + + talloc_free(mem_ctx); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *py_dn; + struct ldb_dn *dn; + int ret; + struct ldb_context *ldb_ctx; + struct ldb_request *req; + PyObject *py_controls = Py_None; + TALLOC_CTX *mem_ctx; + struct ldb_control **parsed_controls; + const char * const kwnames[] = { "dn", "controls", NULL }; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", + discard_const_p(char *, kwnames), + &py_dn, &py_controls)) + return NULL; + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + ldb_ctx = pyldb_Ldb_AsLdbContext(self); + + if (py_controls == Py_None) { + parsed_controls = NULL; + } else { + const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls"); + if (controls == NULL) { + talloc_free(mem_ctx); + return NULL; + } + parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); + talloc_free(controls); + } + + if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) { + talloc_free(mem_ctx); + return NULL; + } + + ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls, + NULL, ldb_op_default_callback, NULL); + if (ret != LDB_SUCCESS) { + PyErr_SetString(PyExc_TypeError, "failed to build request"); + talloc_free(mem_ctx); + return NULL; + } + + /* do request and autostart a transaction */ + /* Then let's LDB handle the message error in case of pb as they are meaningful */ + + ret = ldb_transaction_start(ldb_ctx); + if (ret != LDB_SUCCESS) { + talloc_free(mem_ctx); + PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); + return NULL; + } + + ret = ldb_request(ldb_ctx, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + if (ret == LDB_SUCCESS) { + ret = ldb_transaction_commit(ldb_ctx); + } else { + ldb_transaction_cancel(ldb_ctx); + } + + talloc_free(mem_ctx); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *py_dn1, *py_dn2; + struct ldb_dn *dn1, *dn2; + int ret; + TALLOC_CTX *mem_ctx; + PyObject *py_controls = Py_None; + struct ldb_control **parsed_controls; + struct ldb_context *ldb_ctx; + struct ldb_request *req; + const char * const kwnames[] = { "dn1", "dn2", "controls", NULL }; + + ldb_ctx = pyldb_Ldb_AsLdbContext(self); + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O", + discard_const_p(char *, kwnames), + &py_dn1, &py_dn2, &py_controls)) + return NULL; + + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + if (py_controls == Py_None) { + parsed_controls = NULL; + } else { + const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls"); + if (controls == NULL) { + talloc_free(mem_ctx); + return NULL; + } + parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); + talloc_free(controls); + } + + + if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) { + talloc_free(mem_ctx); + return NULL; + } + + if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) { + talloc_free(mem_ctx); + return NULL; + } + + ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls, + NULL, ldb_op_default_callback, NULL); + if (ret != LDB_SUCCESS) { + PyErr_SetString(PyExc_TypeError, "failed to build request"); + talloc_free(mem_ctx); + return NULL; + } + + /* do request and autostart a transaction */ + /* Then let's LDB handle the message error in case of pb as they are meaningful */ + + ret = ldb_transaction_start(ldb_ctx); + if (ret != LDB_SUCCESS) { + talloc_free(mem_ctx); + PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); + return NULL; + } + + ret = ldb_request(ldb_ctx, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + if (ret == LDB_SUCCESS) { + ret = ldb_transaction_commit(ldb_ctx); + } else { + ldb_transaction_cancel(ldb_ctx); + } + + talloc_free(mem_ctx); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args) +{ + char *name; + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + + ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args) +{ + char *attribute, *syntax; + unsigned int flags; + int ret; + struct ldb_context *ldb_ctx; + + if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax)) + return NULL; + + ldb_ctx = pyldb_Ldb_AsLdbContext(self); + ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax); + + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); + + Py_RETURN_NONE; +} + +static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif) +{ + if (ldif == NULL) { + Py_RETURN_NONE; + } else { + /* We don't want this attached to the 'ldb' any more */ + PyObject *obj = PyLdbMessage_FromMessage(ldif->msg); + PyObject *result = + Py_BuildValue(discard_const_p(char, "(iO)"), + ldif->changetype, + obj); + Py_CLEAR(obj); + return result; + } +} + + +static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args) +{ + int changetype; + PyObject *py_msg; + struct ldb_ldif ldif; + PyObject *ret; + char *string; + TALLOC_CTX *mem_ctx; + + if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype)) + return NULL; + + if (!PyLdbMessage_Check(py_msg)) { + PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg"); + return NULL; + } + + ldif.msg = pyldb_Message_AsMessage(py_msg); + ldif.changetype = changetype; + + mem_ctx = talloc_new(NULL); + + string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif); + if (!string) { + PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF"); + return NULL; + } + + ret = PyUnicode_FromString(string); + + talloc_free(mem_ctx); + + return ret; +} + +static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args) +{ + PyObject *list, *ret; + struct ldb_ldif *ldif; + const char *s; + struct ldb_dn *last_dn = NULL; + + TALLOC_CTX *mem_ctx; + + if (!PyArg_ParseTuple(args, "s", &s)) + return NULL; + + mem_ctx = talloc_new(NULL); + if (!mem_ctx) { + Py_RETURN_NONE; + } + + list = PyList_New(0); + while (s && *s != '\0') { + ldif = ldb_ldif_read_string(self->ldb_ctx, &s); + talloc_steal(mem_ctx, ldif); + if (ldif) { + int res = 0; + PyObject *py_ldif = ldb_ldif_to_pyobject(ldif); + if (py_ldif == NULL) { + Py_CLEAR(list); + PyErr_BadArgument(); + talloc_free(mem_ctx); + return NULL; + } + res = PyList_Append(list, py_ldif); + Py_CLEAR(py_ldif); + if (res == -1) { + Py_CLEAR(list); + talloc_free(mem_ctx); + return NULL; + } + last_dn = ldif->msg->dn; + } else { + const char *last_dn_str = NULL; + const char *err_string = NULL; + if (last_dn == NULL) { + PyErr_SetString(PyExc_ValueError, + "unable to parse LDIF " + "string at first chunk"); + Py_CLEAR(list); + talloc_free(mem_ctx); + return NULL; + } + + last_dn_str + = ldb_dn_get_linearized(last_dn); + + err_string + = talloc_asprintf(mem_ctx, + "unable to parse ldif " + "string AFTER %s", + last_dn_str); + + PyErr_SetString(PyExc_ValueError, + err_string); + talloc_free(mem_ctx); + Py_CLEAR(list); + return NULL; + } + } + talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */ + ret = PyObject_GetIter(list); + Py_DECREF(list); + return ret; +} + +static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args) +{ + int ldb_ret; + PyObject *py_msg_old; + PyObject *py_msg_new; + struct ldb_message *diff; + struct ldb_context *ldb; + PyObject *py_ret; + + if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new)) + return NULL; + + if (!PyLdbMessage_Check(py_msg_old)) { + PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message"); + return NULL; + } + + if (!PyLdbMessage_Check(py_msg_new)) { + PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message"); + return NULL; + } + + ldb = pyldb_Ldb_AsLdbContext(self); + ldb_ret = ldb_msg_difference(ldb, ldb, + pyldb_Message_AsMessage(py_msg_old), + pyldb_Message_AsMessage(py_msg_new), + &diff); + if (ldb_ret != LDB_SUCCESS) { + PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff"); + return NULL; + } + + py_ret = PyLdbMessage_FromMessage(diff); + + talloc_unlink(ldb, diff); + + return py_ret; +} + +static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args) +{ + const struct ldb_schema_attribute *a; + struct ldb_val old_val; + struct ldb_val new_val; + TALLOC_CTX *mem_ctx; + PyObject *ret; + char *element_name; + PyObject *val; + Py_ssize_t size; + int result; + + if (!PyArg_ParseTuple(args, "sO", &element_name, &val)) + return NULL; + + result = PyBytes_AsStringAndSize(val, (char **)&old_val.data, &size); + old_val.length = size; + + if (result != 0) { + PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String"); + return NULL; + } + + a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name); + + if (a == NULL) { + Py_RETURN_NONE; + } + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) { + talloc_free(mem_ctx); + Py_RETURN_NONE; + } + + ret = PyBytes_FromStringAndSize((const char *)new_val.data, new_val.length); + + talloc_free(mem_ctx); + + return ret; +} + +static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *py_base = Py_None; + int scope = LDB_SCOPE_DEFAULT; + char *expr = NULL; + PyObject *py_attrs = Py_None; + PyObject *py_controls = Py_None; + const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL }; + int ret; + struct ldb_result *res; + struct ldb_request *req; + const char **attrs; + struct ldb_context *ldb_ctx; + struct ldb_control **parsed_controls; + struct ldb_dn *base; + PyObject *py_ret; + TALLOC_CTX *mem_ctx; + + /* type "int" rather than "enum" for "scope" is intentional */ + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO", + discard_const_p(char *, kwnames), + &py_base, &scope, &expr, &py_attrs, &py_controls)) + return NULL; + + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + ldb_ctx = pyldb_Ldb_AsLdbContext(self); + + if (py_attrs == Py_None) { + attrs = NULL; + } else { + attrs = PyList_AsStrList(mem_ctx, py_attrs, "attrs"); + if (attrs == NULL) { + talloc_free(mem_ctx); + return NULL; + } + } + + if (py_base == Py_None) { + base = ldb_get_default_basedn(ldb_ctx); + } else { + if (!pyldb_Object_AsDn(mem_ctx, py_base, ldb_ctx, &base)) { + talloc_free(mem_ctx); + return NULL; + } + } + + if (py_controls == Py_None) { + parsed_controls = NULL; + } else { + const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls"); + if (controls == NULL) { + talloc_free(mem_ctx); + return NULL; + } + parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); + talloc_free(controls); + } + + res = talloc_zero(mem_ctx, struct ldb_result); + if (res == NULL) { + PyErr_NoMemory(); + talloc_free(mem_ctx); + return NULL; + } + + ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx, + base, + scope, + expr, + attrs, + parsed_controls, + res, + ldb_search_default_callback, + NULL); + + if (ret != LDB_SUCCESS) { + talloc_free(mem_ctx); + PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); + return NULL; + } + + talloc_steal(req, attrs); + + ret = ldb_request(ldb_ctx, req); + + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + if (ret != LDB_SUCCESS) { + talloc_free(mem_ctx); + PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); + return NULL; + } + + py_ret = PyLdbResult_FromResult(res); + + talloc_free(mem_ctx); + + return py_ret; +} + +static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply *reply) +{ + if (reply->py_iter != NULL) { + DLIST_REMOVE(reply->py_iter->state.next, reply); + if (reply->py_iter->state.result == reply) { + reply->py_iter->state.result = NULL; + } + reply->py_iter = NULL; + } + + if (reply->obj != NULL) { + Py_DECREF(reply->obj); + reply->obj = NULL; + } + + return 0; +} + +static int py_ldb_search_iterator_callback(struct ldb_request *req, + struct ldb_reply *ares) +{ + PyLdbSearchIteratorObject *py_iter = (PyLdbSearchIteratorObject *)req->context; + struct ldb_result result = { .msgs = NULL }; + struct py_ldb_search_iterator_reply *reply = NULL; + + if (ares == NULL) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + + if (ares->error != LDB_SUCCESS) { + int ret = ares->error; + TALLOC_FREE(ares); + return ldb_request_done(req, ret); + } + + reply = talloc_zero(py_iter->mem_ctx, + struct py_ldb_search_iterator_reply); + if (reply == NULL) { + TALLOC_FREE(ares); + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + reply->py_iter = py_iter; + talloc_set_destructor(reply, py_ldb_search_iterator_reply_destructor); + + switch (ares->type) { + case LDB_REPLY_ENTRY: + reply->obj = PyLdbMessage_FromMessage(ares->message); + if (reply->obj == NULL) { + TALLOC_FREE(ares); + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + DLIST_ADD_END(py_iter->state.next, reply); + TALLOC_FREE(ares); + return LDB_SUCCESS; + + case LDB_REPLY_REFERRAL: + reply->obj = PyUnicode_FromString(ares->referral); + if (reply->obj == NULL) { + TALLOC_FREE(ares); + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + DLIST_ADD_END(py_iter->state.next, reply); + TALLOC_FREE(ares); + return LDB_SUCCESS; + + case LDB_REPLY_DONE: + result = (struct ldb_result) { .controls = ares->controls }; + reply->obj = PyLdbResult_FromResult(&result); + if (reply->obj == NULL) { + TALLOC_FREE(ares); + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + py_iter->state.result = reply; + TALLOC_FREE(ares); + return ldb_request_done(req, LDB_SUCCESS); + } + + TALLOC_FREE(ares); + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); +} + +static PyObject *py_ldb_search_iterator(PyLdbObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *py_base = Py_None; + int scope = LDB_SCOPE_DEFAULT; + int timeout = 0; + char *expr = NULL; + PyObject *py_attrs = Py_None; + PyObject *py_controls = Py_None; + const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL }; + int ret; + const char **attrs; + struct ldb_context *ldb_ctx; + struct ldb_control **parsed_controls; + struct ldb_dn *base; + PyLdbSearchIteratorObject *py_iter; + + /* type "int" rather than "enum" for "scope" is intentional */ + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOOi", + discard_const_p(char *, kwnames), + &py_base, &scope, &expr, &py_attrs, &py_controls, &timeout)) + return NULL; + + py_iter = (PyLdbSearchIteratorObject *)PyLdbSearchIterator.tp_alloc(&PyLdbSearchIterator, 0); + if (py_iter == NULL) { + PyErr_NoMemory(); + return NULL; + } + py_iter->ldb = self; + Py_INCREF(self); + ZERO_STRUCT(py_iter->state); + py_iter->mem_ctx = talloc_new(NULL); + if (py_iter->mem_ctx == NULL) { + Py_DECREF(py_iter); + PyErr_NoMemory(); + return NULL; + } + + ldb_ctx = pyldb_Ldb_AsLdbContext(self); + + if (py_attrs == Py_None) { + attrs = NULL; + } else { + attrs = PyList_AsStrList(py_iter->mem_ctx, py_attrs, "attrs"); + if (attrs == NULL) { + Py_DECREF(py_iter); + PyErr_NoMemory(); + return NULL; + } + } + + if (py_base == Py_None) { + base = ldb_get_default_basedn(ldb_ctx); + } else { + if (!pyldb_Object_AsDn(py_iter->mem_ctx, py_base, ldb_ctx, &base)) { + Py_DECREF(py_iter); + PyErr_NoMemory(); + return NULL; + } + } + + if (py_controls == Py_None) { + parsed_controls = NULL; + } else { + const char **controls = NULL; + + controls = PyList_AsStrList(py_iter->mem_ctx, + py_controls, "controls"); + if (controls == NULL) { + Py_DECREF(py_iter); + PyErr_NoMemory(); + return NULL; + } + + parsed_controls = ldb_parse_control_strings(ldb_ctx, + py_iter->mem_ctx, + controls); + if (controls[0] != NULL && parsed_controls == NULL) { + Py_DECREF(py_iter); + PyErr_NoMemory(); + return NULL; + } + talloc_free(controls); + } + + ret = ldb_build_search_req(&py_iter->state.req, + ldb_ctx, + py_iter->mem_ctx, + base, + scope, + expr, + attrs, + parsed_controls, + py_iter, + py_ldb_search_iterator_callback, + NULL); + if (ret != LDB_SUCCESS) { + Py_DECREF(py_iter); + PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); + return NULL; + } + + ldb_set_timeout(ldb_ctx, py_iter->state.req, timeout); + + ret = ldb_request(ldb_ctx, py_iter->state.req); + if (ret != LDB_SUCCESS) { + Py_DECREF(py_iter); + PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); + return NULL; + } + + return (PyObject *)py_iter; +} + +static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args) +{ + char *name; + void *data; + + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + + data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name); + + if (data == NULL) + Py_RETURN_NONE; + + /* FIXME: More interpretation */ + + Py_RETURN_TRUE; +} + +static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args) +{ + char *name; + PyObject *data; + + if (!PyArg_ParseTuple(args, "sO", &name, &data)) + return NULL; + + /* FIXME: More interpretation */ + + ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_modules(PyLdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self); + PyObject *ret = PyList_New(0); + struct ldb_module *mod; + + if (ret == NULL) { + return PyErr_NoMemory(); + } + for (mod = ldb->modules; mod; mod = mod->next) { + PyObject *item = PyLdbModule_FromModule(mod); + int res = 0; + if (item == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "Failed to load LdbModule"); + Py_CLEAR(ret); + return NULL; + } + res = PyList_Append(ret, item); + Py_CLEAR(item); + if (res == -1) { + Py_CLEAR(ret); + return NULL; + } + } + + return ret; +} + +static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args) +{ + struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self); + int type, ret; + uint64_t value; + + if (!PyArg_ParseTuple(args, "i", &type)) + return NULL; + + /* FIXME: More interpretation */ + + ret = ldb_sequence_number(ldb, type, &value); + + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb); + + return PyLong_FromLongLong(value); +} + + +static const struct ldb_dn_extended_syntax test_dn_syntax = { + .name = "TEST", + .read_fn = ldb_handler_copy, + .write_clear_fn = ldb_handler_copy, + .write_hex_fn = ldb_handler_copy, +}; + +static PyObject *py_ldb_register_test_extensions(PyLdbObject *self, + PyObject *Py_UNUSED(ignored)) +{ + struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self); + int ret; + + ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &test_dn_syntax); + + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb); + + Py_RETURN_NONE; +} + + +static PyMethodDef py_ldb_methods[] = { + { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS, + "S.set_debug(callback) -> None\n" + "Set callback for LDB debug messages.\n" + "The callback should accept a debug level and debug text." }, + { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS, + "S.set_create_perms(mode) -> None\n" + "Set mode to use when creating new LDB files." }, + { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS, + "S.set_modules_dir(path) -> None\n" + "Set path LDB should search for modules" }, + { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS, + "S.transaction_start() -> None\n" + "Start a new transaction." }, + { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS, + "S.transaction_prepare_commit() -> None\n" + "prepare to commit a new transaction (2-stage commit)." }, + { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS, + "S.transaction_commit() -> None\n" + "commit a new transaction." }, + { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS, + "S.transaction_cancel() -> None\n" + "cancel a new transaction." }, + { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS, + NULL }, + { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS, + NULL }, + { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS, + NULL }, + { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS, + NULL }, + { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS, + NULL }, + { "connect", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_connect), + METH_VARARGS|METH_KEYWORDS, + "S.connect(url, flags=0, options=None) -> None\n" + "Connect to a LDB URL." }, + { "modify", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_modify), + METH_VARARGS|METH_KEYWORDS, + "S.modify(message, controls=None, validate=False) -> None\n" + "Modify an entry." }, + { "add", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_add), + METH_VARARGS|METH_KEYWORDS, + "S.add(message, controls=None) -> None\n" + "Add an entry." }, + { "delete", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_delete), + METH_VARARGS|METH_KEYWORDS, + "S.delete(dn, controls=None) -> None\n" + "Remove an entry." }, + { "rename", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_rename), + METH_VARARGS|METH_KEYWORDS, + "S.rename(old_dn, new_dn, controls=None) -> None\n" + "Rename an entry." }, + { "search", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_search), + METH_VARARGS|METH_KEYWORDS, + "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n" + "Search in a database.\n" + "\n" + ":param base: Optional base DN to search\n" + ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n" + ":param expression: Optional search expression\n" + ":param attrs: Attributes to return (defaults to all)\n" + ":param controls: Optional list of controls\n" + ":return: ldb.Result object\n" + }, + { "search_iterator", PY_DISCARD_FUNC_SIG(PyCFunction, + py_ldb_search_iterator), + METH_VARARGS|METH_KEYWORDS, + "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n" + "Search in a database.\n" + "\n" + ":param base: Optional base DN to search\n" + ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n" + ":param expression: Optional search expression\n" + ":param attrs: Attributes to return (defaults to all)\n" + ":param controls: Optional list of controls\n" + ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n" + ":return: ldb.SearchIterator object that provides results when they arrive\n" + }, + { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS, + NULL }, + { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS, + NULL }, + { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS, + NULL }, + { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS, + "S.parse_ldif(ldif) -> iter(messages)\n" + "Parse a string formatted using LDIF." }, + { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS, + "S.write_ldif(message, changetype) -> ldif\n" + "Print the message as a string formatted using LDIF." }, + { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS, + "S.msg_diff(Message) -> Message\n" + "Return an LDB Message of the difference between two Message objects." }, + { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS, + "S.get_opaque(name) -> value\n" + "Get an opaque value set on this LDB connection. \n" + ":note: The returned value may not be useful in Python." + }, + { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS, + "S.set_opaque(name, value) -> None\n" + "Set an opaque value on this LDB connection. \n" + ":note: Passing incorrect values may cause crashes." }, + { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS, + "S.modules() -> list\n" + "Return the list of modules on this LDB connection " }, + { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS, + "S.sequence_number(type) -> value\n" + "Return the value of the sequence according to the requested type" }, + { "_register_test_extensions", (PyCFunction)py_ldb_register_test_extensions, METH_NOARGS, + "S._register_test_extensions() -> None\n" + "Register internal extensions used in testing" }, + { NULL }, +}; + +static PyObject *PyLdbModule_FromModule(struct ldb_module *mod) +{ + PyLdbModuleObject *ret; + + ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0); + if (ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + ret->mem_ctx = talloc_new(NULL); + ret->mod = talloc_reference(ret->mem_ctx, mod); + return (PyObject *)ret; +} + +static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure) +{ + struct ldb_module *mod = pyldb_Ldb_AsLdbContext(self)->modules; + if (mod == NULL) { + Py_RETURN_NONE; + } + return PyLdbModule_FromModule(mod); +} + +static PyGetSetDef py_ldb_getset[] = { + { + .name = discard_const_p(char, "firstmodule"), + .get = (getter)py_ldb_get_firstmodule, + }, + { .name = NULL }, +}; + +static int py_ldb_contains(PyLdbObject *self, PyObject *obj) +{ + struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); + struct ldb_dn *dn; + struct ldb_result *result; + unsigned int count; + int ret; + + if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) { + return -1; + } + + ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL, + NULL); + if (ret != LDB_SUCCESS) { + PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); + return -1; + } + + count = result->count; + + talloc_free(result); + + if (count > 1) { + PyErr_Format(PyExc_RuntimeError, + "Searching for [%s] dn gave %u results!", + ldb_dn_get_linearized(dn), + count); + return -1; + } + + return count; +} + +static PySequenceMethods py_ldb_seq = { + .sq_contains = (objobjproc)py_ldb_contains, +}; + +static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx) +{ + PyLdbObject *ret; + + ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0); + if (ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + ret->mem_ctx = talloc_new(NULL); + ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx); + return (PyObject *)ret; +} + +static void py_ldb_dealloc(PyLdbObject *self) +{ + talloc_free(self->mem_ctx); + Py_TYPE(self)->tp_free(self); +} + +static PyTypeObject PyLdb = { + .tp_name = "ldb.Ldb", + .tp_methods = py_ldb_methods, + .tp_repr = (reprfunc)py_ldb_repr, + .tp_new = py_ldb_new, + .tp_init = (initproc)py_ldb_init, + .tp_dealloc = (destructor)py_ldb_dealloc, + .tp_getset = py_ldb_getset, + .tp_getattro = PyObject_GenericGetAttr, + .tp_basicsize = sizeof(PyLdbObject), + .tp_doc = "Connection to a LDB database.", + .tp_as_sequence = &py_ldb_seq, + .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, +}; + +static void py_ldb_result_dealloc(PyLdbResultObject *self) +{ + talloc_free(self->mem_ctx); + Py_DECREF(self->msgs); + Py_DECREF(self->referals); + Py_DECREF(self->controls); + Py_TYPE(self)->tp_free(self); +} + +static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure) +{ + Py_INCREF(self->msgs); + return self->msgs; +} + +static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure) +{ + Py_INCREF(self->controls); + return self->controls; +} + +static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure) +{ + Py_INCREF(self->referals); + return self->referals; +} + +static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure) +{ + Py_ssize_t size; + if (self->msgs == NULL) { + PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context"); + return NULL; + } + size = PyList_Size(self->msgs); + return PyInt_FromLong(size); +} + +static PyGetSetDef py_ldb_result_getset[] = { + { + .name = discard_const_p(char, "controls"), + .get = (getter)py_ldb_result_get_controls, + }, + { + .name = discard_const_p(char, "msgs"), + .get = (getter)py_ldb_result_get_msgs, + }, + { + .name = discard_const_p(char, "referals"), + .get = (getter)py_ldb_result_get_referals, + }, + { + .name = discard_const_p(char, "count"), + .get = (getter)py_ldb_result_get_count, + }, + { .name = NULL }, +}; + +static PyObject *py_ldb_result_iter(PyLdbResultObject *self) +{ + return PyObject_GetIter(self->msgs); +} + +static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self) +{ + return PySequence_Size(self->msgs); +} + +static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx) +{ + return PySequence_GetItem(self->msgs, idx); +} + +static PySequenceMethods py_ldb_result_seq = { + .sq_length = (lenfunc)py_ldb_result_len, + .sq_item = (ssizeargfunc)py_ldb_result_find, +}; + +static PyObject *py_ldb_result_repr(PyLdbObject *self) +{ + return PyUnicode_FromString(""); +} + + +static PyTypeObject PyLdbResult = { + .tp_name = "ldb.Result", + .tp_repr = (reprfunc)py_ldb_result_repr, + .tp_dealloc = (destructor)py_ldb_result_dealloc, + .tp_iter = (getiterfunc)py_ldb_result_iter, + .tp_getset = py_ldb_result_getset, + .tp_getattro = PyObject_GenericGetAttr, + .tp_basicsize = sizeof(PyLdbResultObject), + .tp_as_sequence = &py_ldb_result_seq, + .tp_doc = "LDB result.", + .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, +}; + +static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject *self) +{ + Py_XDECREF(self->state.exception); + TALLOC_FREE(self->mem_ctx); + ZERO_STRUCT(self->state); + Py_DECREF(self->ldb); + Py_TYPE(self)->tp_free(self); +} + +static PyObject *py_ldb_search_iterator_next(PyLdbSearchIteratorObject *self) +{ + PyObject *py_ret = NULL; + + if (self->state.req == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "ldb.SearchIterator request already finished"); + return NULL; + } + + /* + * TODO: do we want a non-blocking mode? + * In future we may add an optional 'nonblocking' + * argument to search_iterator(). + * + * For now we keep it simple and wait for at + * least one reply. + */ + + while (self->state.next == NULL) { + int ret; + + if (self->state.result != NULL) { + /* + * We (already) got a final result from the server. + * + * We stop the iteration and let + * py_ldb_search_iterator_result() will deliver + * the result details. + */ + TALLOC_FREE(self->state.req); + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + + ret = ldb_wait(self->state.req->handle, LDB_WAIT_NONE); + if (ret != LDB_SUCCESS) { + struct ldb_context *ldb_ctx; + TALLOC_FREE(self->state.req); + ldb_ctx = pyldb_Ldb_AsLdbContext(self->ldb); + /* + * We stop the iteration and let + * py_ldb_search_iterator_result() will deliver + * the exception. + */ + self->state.exception = Py_BuildValue(discard_const_p(char, "(i,s)"), + ret, ldb_errstring(ldb_ctx)); + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + } + + py_ret = self->state.next->obj; + self->state.next->obj = NULL; + /* no TALLOC_FREE() as self->state.next is a list */ + talloc_free(self->state.next); + return py_ret; +} + +static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self, + PyObject *Py_UNUSED(ignored)) +{ + PyObject *py_ret = NULL; + + if (self->state.req != NULL) { + PyErr_SetString(PyExc_RuntimeError, + "ldb.SearchIterator request running"); + return NULL; + } + + if (self->state.next != NULL) { + PyErr_SetString(PyExc_RuntimeError, + "ldb.SearchIterator not fully consumed."); + return NULL; + } + + if (self->state.exception != NULL) { + PyErr_SetObject(PyExc_LdbError, self->state.exception); + self->state.exception = NULL; + return NULL; + } + + if (self->state.result == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "ldb.SearchIterator result already consumed"); + return NULL; + } + + py_ret = self->state.result->obj; + self->state.result->obj = NULL; + TALLOC_FREE(self->state.result); + return py_ret; +} + +static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self, + PyObject *Py_UNUSED(ignored)) +{ + if (self->state.req == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "ldb.SearchIterator request already finished"); + return NULL; + } + + Py_XDECREF(self->state.exception); + TALLOC_FREE(self->mem_ctx); + ZERO_STRUCT(self->state); + Py_RETURN_NONE; +} + +static PyMethodDef py_ldb_search_iterator_methods[] = { + { "result", (PyCFunction)py_ldb_search_iterator_result, METH_NOARGS, + "S.result() -> ldb.Result (without msgs and referrals)\n" }, + { "abandon", (PyCFunction)py_ldb_search_iterator_abandon, METH_NOARGS, + "S.abandon()\n" }, + { NULL } +}; + +static PyObject *py_ldb_search_iterator_repr(PyLdbSearchIteratorObject *self) +{ + return PyUnicode_FromString(""); +} + +static PyTypeObject PyLdbSearchIterator = { + .tp_name = "ldb.SearchIterator", + .tp_repr = (reprfunc)py_ldb_search_iterator_repr, + .tp_dealloc = (destructor)py_ldb_search_iterator_dealloc, + .tp_iter = PyObject_SelfIter, + .tp_iternext = (iternextfunc)py_ldb_search_iterator_next, + .tp_methods = py_ldb_search_iterator_methods, + .tp_basicsize = sizeof(PyLdbSearchIteratorObject), + .tp_doc = "LDB search_iterator.", + .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, +}; + +static PyObject *py_ldb_module_repr(PyLdbModuleObject *self) +{ + return PyUnicode_FromFormat("", + pyldb_Module_AsModule(self)->ops->name); +} + +static PyObject *py_ldb_module_str(PyLdbModuleObject *self) +{ + return PyUnicode_FromString(pyldb_Module_AsModule(self)->ops->name); +} + +static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self, + PyObject *Py_UNUSED(ignored)) +{ + pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self)); + Py_RETURN_NONE; +} + +static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self, + PyObject *Py_UNUSED(ignored)) +{ + pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self)); + Py_RETURN_NONE; +} + +static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self, + PyObject *Py_UNUSED(ignored)) +{ + pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self)); + Py_RETURN_NONE; +} + +static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *py_base, *py_tree, *py_attrs, *py_ret; + int ret, scope; + struct ldb_request *req; + const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL }; + struct ldb_module *mod; + const char * const*attrs; + + /* type "int" rather than "enum" for "scope" is intentional */ + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO", + discard_const_p(char *, kwnames), + &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs)) + return NULL; + + mod = self->mod; + + if (py_attrs == Py_None) { + attrs = NULL; + } else { + attrs = PyList_AsStrList(NULL, py_attrs, "attrs"); + if (attrs == NULL) + return NULL; + } + + ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base), + scope, NULL /* expr */, attrs, + NULL /* controls */, NULL, NULL, NULL); + + talloc_steal(req, attrs); + + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb); + + req->op.search.res = NULL; + + ret = mod->ops->search(mod, req); + + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb); + + py_ret = PyLdbResult_FromResult(req->op.search.res); + + talloc_free(req); + + return py_ret; +} + + +static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args) +{ + struct ldb_request *req; + PyObject *py_message; + int ret; + struct ldb_module *mod; + + if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message)) + return NULL; + + req = talloc_zero(NULL, struct ldb_request); + req->operation = LDB_ADD; + req->op.add.message = pyldb_Message_AsMessage(py_message); + + mod = pyldb_Module_AsModule(self); + ret = mod->ops->add(mod, req); + + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args) +{ + int ret; + struct ldb_request *req; + PyObject *py_message; + struct ldb_module *mod; + + if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message)) + return NULL; + + req = talloc_zero(NULL, struct ldb_request); + req->operation = LDB_MODIFY; + req->op.mod.message = pyldb_Message_AsMessage(py_message); + + mod = pyldb_Module_AsModule(self); + ret = mod->ops->modify(mod, req); + + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args) +{ + int ret; + struct ldb_request *req; + PyObject *py_dn; + + if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn)) + return NULL; + + req = talloc_zero(NULL, struct ldb_request); + req->operation = LDB_DELETE; + req->op.del.dn = pyldb_Dn_AsDn(py_dn); + + ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req); + + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args) +{ + int ret; + struct ldb_request *req; + PyObject *py_dn1, *py_dn2; + + if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2)) + return NULL; + + req = talloc_zero(NULL, struct ldb_request); + + req->operation = LDB_RENAME; + req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1); + req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2); + + ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req); + + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); + + Py_RETURN_NONE; +} + +static PyMethodDef py_ldb_module_methods[] = { + { "search", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_module_search), + METH_VARARGS|METH_KEYWORDS, NULL }, + { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL }, + { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL }, + { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL }, + { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL }, + { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL }, + { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL }, + { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL }, + { NULL }, +}; + +static void py_ldb_module_dealloc(PyLdbModuleObject *self) +{ + talloc_free(self->mem_ctx); + PyObject_Del(self); +} + +static PyTypeObject PyLdbModule = { + .tp_name = "ldb.LdbModule", + .tp_methods = py_ldb_module_methods, + .tp_repr = (reprfunc)py_ldb_module_repr, + .tp_str = (reprfunc)py_ldb_module_str, + .tp_basicsize = sizeof(PyLdbModuleObject), + .tp_dealloc = (destructor)py_ldb_module_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_doc = "LDB module (extension)", +}; + + +/** + * Create a ldb_message_element from a Python object. + * + * This will accept any sequence objects that contains strings, or + * a string object. + * + * A reference to set_obj will be borrowed. + * + * @param mem_ctx Memory context + * @param set_obj Python object to convert + * @param flags ldb_message_element flags to set + * @param attr_name Name of the attribute + * @return New ldb_message_element, allocated as child of mem_ctx + */ +static struct ldb_message_element *PyObject_AsMessageElement( + TALLOC_CTX *mem_ctx, + PyObject *set_obj, + unsigned int flags, + const char *attr_name) +{ + struct ldb_message_element *me; + const char *msg = NULL; + Py_ssize_t size; + int result; + + if (pyldb_MessageElement_Check(set_obj)) { + PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj; + /* We have to talloc_reference() the memory context, not the pointer + * which may not actually be it's own context */ + if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) { + return pyldb_MessageElement_AsMessageElement(set_obj); + } + return NULL; + } + + me = talloc(mem_ctx, struct ldb_message_element); + if (me == NULL) { + PyErr_NoMemory(); + return NULL; + } + + me->name = talloc_strdup(me, attr_name); + me->flags = flags; + if (PyBytes_Check(set_obj) || PyUnicode_Check(set_obj)) { + me->num_values = 1; + me->values = talloc_array(me, struct ldb_val, me->num_values); + if (PyBytes_Check(set_obj)) { + char *_msg = NULL; + result = PyBytes_AsStringAndSize(set_obj, &_msg, &size); + if (result != 0) { + talloc_free(me); + return NULL; + } + msg = _msg; + } else { + msg = PyUnicode_AsUTF8AndSize(set_obj, &size); + if (msg == NULL) { + talloc_free(me); + return NULL; + } + } + me->values[0].data = talloc_memdup(me, + (const uint8_t *)msg, + size+1); + me->values[0].length = size; + } else if (PySequence_Check(set_obj)) { + Py_ssize_t i; + me->num_values = PySequence_Size(set_obj); + me->values = talloc_array(me, struct ldb_val, me->num_values); + for (i = 0; i < me->num_values; i++) { + PyObject *obj = PySequence_GetItem(set_obj, i); + if (PyBytes_Check(obj)) { + char *_msg = NULL; + result = PyBytes_AsStringAndSize(obj, &_msg, &size); + if (result != 0) { + talloc_free(me); + return NULL; + } + msg = _msg; + } else if (PyUnicode_Check(obj)) { + msg = PyUnicode_AsUTF8AndSize(obj, &size); + if (msg == NULL) { + talloc_free(me); + return NULL; + } + } else { + PyErr_Format(PyExc_TypeError, + "Expected string as element %zd in list", i); + talloc_free(me); + return NULL; + } + me->values[i].data = talloc_memdup(me, + (const uint8_t *)msg, + size+1); + me->values[i].length = size; + } + } else { + PyErr_Format(PyExc_TypeError, + "String or List type expected for '%s' attribute", attr_name); + talloc_free(me); + me = NULL; + } + + return me; +} + + +static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx, + struct ldb_message_element *me) +{ + Py_ssize_t i; + PyObject *result; + + /* Python << 2.5 doesn't have PySet_New and PySet_Add. */ + result = PyList_New(me->num_values); + + for (i = 0; i < me->num_values; i++) { + PyList_SetItem(result, i, + PyObject_FromLdbValue(&me->values[i])); + } + + return result; +} + +static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args) +{ + unsigned int i; + if (!PyArg_ParseTuple(args, "I", &i)) + return NULL; + if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values) + Py_RETURN_NONE; + + return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i])); +} + +static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args) +{ + struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self); + return PyInt_FromLong(el->flags); +} + +static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args) +{ + unsigned int flags; + struct ldb_message_element *el; + if (!PyArg_ParseTuple(args, "I", &flags)) + return NULL; + + el = pyldb_MessageElement_AsMessageElement(self); + el->flags = flags; + Py_RETURN_NONE; +} + +static PyMethodDef py_ldb_msg_element_methods[] = { + { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL }, + { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL }, + { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL }, + { NULL }, +}; + +static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self) +{ + return pyldb_MessageElement_AsMessageElement(self)->num_values; +} + +static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx) +{ + struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self); + if (idx < 0 || idx >= el->num_values) { + PyErr_SetString(PyExc_IndexError, "Out of range"); + return NULL; + } + return PyLdbBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length); +} + +static PySequenceMethods py_ldb_msg_element_seq = { + .sq_length = (lenfunc)py_ldb_msg_element_len, + .sq_item = (ssizeargfunc)py_ldb_msg_element_find, +}; + +static PyObject *py_ldb_msg_element_richcmp(PyObject *self, PyObject *other, int op) +{ + int ret; + if (!pyldb_MessageElement_Check(other)) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self), + pyldb_MessageElement_AsMessageElement(other)); + return richcmp(ret, op); +} + +static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self) +{ + PyObject *el = ldb_msg_element_to_set(NULL, + pyldb_MessageElement_AsMessageElement(self)); + PyObject *ret = PyObject_GetIter(el); + Py_DECREF(el); + return ret; +} + +static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx) +{ + PyLdbMessageElementObject *ret; + ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement); + if (ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + ret->mem_ctx = talloc_new(NULL); + if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) { + PyErr_NoMemory(); + return NULL; + } + ret->el = el; + return (PyObject *)ret; +} + +static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *py_elements = NULL; + struct ldb_message_element *el; + unsigned int flags = 0; + char *name = NULL; + const char * const kwnames[] = { "elements", "flags", "name", NULL }; + PyLdbMessageElementObject *ret; + TALLOC_CTX *mem_ctx; + const char *msg = NULL; + Py_ssize_t size; + int result; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs", + discard_const_p(char *, kwnames), + &py_elements, &flags, &name)) + return NULL; + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + el = talloc_zero(mem_ctx, struct ldb_message_element); + if (el == NULL) { + PyErr_NoMemory(); + talloc_free(mem_ctx); + return NULL; + } + + if (py_elements != NULL) { + Py_ssize_t i; + if (PyBytes_Check(py_elements) || PyUnicode_Check(py_elements)) { + char *_msg = NULL; + el->num_values = 1; + el->values = talloc_array(el, struct ldb_val, 1); + if (el->values == NULL) { + talloc_free(mem_ctx); + PyErr_NoMemory(); + return NULL; + } + if (PyBytes_Check(py_elements)) { + result = PyBytes_AsStringAndSize(py_elements, &_msg, &size); + msg = _msg; + } else { + msg = PyUnicode_AsUTF8AndSize(py_elements, &size); + result = (msg == NULL) ? -1 : 0; + } + if (result != 0) { + talloc_free(mem_ctx); + return NULL; + } + el->values[0].data = talloc_memdup(el->values, + (const uint8_t *)msg, size + 1); + el->values[0].length = size; + } else if (PySequence_Check(py_elements)) { + el->num_values = PySequence_Size(py_elements); + el->values = talloc_array(el, struct ldb_val, el->num_values); + if (el->values == NULL) { + talloc_free(mem_ctx); + PyErr_NoMemory(); + return NULL; + } + for (i = 0; i < el->num_values; i++) { + PyObject *item = PySequence_GetItem(py_elements, i); + if (item == NULL) { + talloc_free(mem_ctx); + return NULL; + } + if (PyBytes_Check(item)) { + char *_msg = NULL; + result = PyBytes_AsStringAndSize(item, &_msg, &size); + msg = _msg; + } else if (PyUnicode_Check(item)) { + msg = PyUnicode_AsUTF8AndSize(item, &size); + result = (msg == NULL) ? -1 : 0; + } else { + PyErr_Format(PyExc_TypeError, + "Expected string as element %zd in list", i); + result = -1; + } + if (result != 0) { + talloc_free(mem_ctx); + return NULL; + } + el->values[i].data = talloc_memdup(el, + (const uint8_t *)msg, size+1); + el->values[i].length = size; + } + } else { + PyErr_SetString(PyExc_TypeError, + "Expected string or list"); + talloc_free(mem_ctx); + return NULL; + } + } + + el->flags = flags; + el->name = talloc_strdup(el, name); + + ret = PyObject_New(PyLdbMessageElementObject, type); + if (ret == NULL) { + talloc_free(mem_ctx); + return NULL; + } + + ret->mem_ctx = mem_ctx; + ret->el = el; + return (PyObject *)ret; +} + +static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self) +{ + char *element_str = NULL; + Py_ssize_t i; + struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self); + PyObject *ret, *repr; + + for (i = 0; i < el->num_values; i++) { + PyObject *o = py_ldb_msg_element_find(self, i); + repr = PyObject_Repr(o); + if (element_str == NULL) + element_str = talloc_strdup(NULL, PyUnicode_AsUTF8(repr)); + else + element_str = talloc_asprintf_append(element_str, ",%s", PyUnicode_AsUTF8(repr)); + Py_DECREF(repr); + } + + if (element_str != NULL) { + ret = PyUnicode_FromFormat("MessageElement([%s])", element_str); + talloc_free(element_str); + } else { + ret = PyUnicode_FromString("MessageElement([])"); + } + + return ret; +} + +static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self) +{ + struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self); + + if (el->num_values == 1) + return PyUnicode_FromStringAndSize((char *)el->values[0].data, el->values[0].length); + else + Py_RETURN_NONE; +} + +static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self) +{ + talloc_free(self->mem_ctx); + PyObject_Del(self); +} + +static PyObject *py_ldb_msg_element_get_text(PyObject *self, void *closure) +{ + return wrap_text("MessageElementTextWrapper", self); +} + +static PyGetSetDef py_ldb_msg_element_getset[] = { + { + .name = discard_const_p(char, "text"), + .get = (getter)py_ldb_msg_element_get_text, + }, + { .name = NULL } +}; + +static PyTypeObject PyLdbMessageElement = { + .tp_name = "ldb.MessageElement", + .tp_basicsize = sizeof(PyLdbMessageElementObject), + .tp_dealloc = (destructor)py_ldb_msg_element_dealloc, + .tp_repr = (reprfunc)py_ldb_msg_element_repr, + .tp_str = (reprfunc)py_ldb_msg_element_str, + .tp_methods = py_ldb_msg_element_methods, + .tp_getset = py_ldb_msg_element_getset, + .tp_richcompare = (richcmpfunc)py_ldb_msg_element_richcmp, + .tp_iter = (getiterfunc)py_ldb_msg_element_iter, + .tp_as_sequence = &py_ldb_msg_element_seq, + .tp_new = py_ldb_msg_element_new, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_doc = "An element of a Message", +}; + + +static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args) +{ + PyObject *py_ldb; + PyObject *py_dict; + PyObject *py_ret; + struct ldb_message *msg; + struct ldb_context *ldb_ctx; + unsigned int mod_flags = LDB_FLAG_MOD_REPLACE; + + if (!PyArg_ParseTuple(args, "O!O!|I", + &PyLdb, &py_ldb, &PyDict_Type, &py_dict, + &mod_flags)) { + return NULL; + } + + if (!PyLdb_Check(py_ldb)) { + PyErr_SetString(PyExc_TypeError, "Expected Ldb"); + return NULL; + } + + /* mask only flags we are going to use */ + mod_flags = LDB_FLAG_MOD_TYPE(mod_flags); + if (!mod_flags) { + PyErr_SetString(PyExc_ValueError, + "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE" + " expected as mod_flag value"); + return NULL; + } + + ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb); + + msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags); + if (!msg) { + return NULL; + } + + py_ret = PyLdbMessage_FromMessage(msg); + + talloc_unlink(ldb_ctx, msg); + + return py_ret; +} + +static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args) +{ + char *name; + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + + ldb_msg_remove_attr(self->msg, name); + + Py_RETURN_NONE; +} + +static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self, + PyObject *Py_UNUSED(ignored)) +{ + struct ldb_message *msg = pyldb_Message_AsMessage(self); + Py_ssize_t i, j = 0; + PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0)); + if (msg->dn != NULL) { + PyList_SetItem(obj, j, PyUnicode_FromString("dn")); + j++; + } + for (i = 0; i < msg->num_elements; i++) { + PyList_SetItem(obj, j, PyUnicode_FromString(msg->elements[i].name)); + j++; + } + return obj; +} + +static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name) +{ + struct ldb_message_element *el; + const char *name; + struct ldb_message *msg = pyldb_Message_AsMessage(self); + name = PyUnicode_AsUTF8(py_name); + if (name == NULL) { + PyErr_SetNone(PyExc_TypeError); + return NULL; + } + if (!ldb_attr_cmp(name, "dn")) + return pyldb_Dn_FromDn(msg->dn); + el = ldb_msg_find_element(msg, name); + if (el == NULL) { + return NULL; + } + return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements); +} + +static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name) +{ + PyObject *ret = py_ldb_msg_getitem_helper(self, py_name); + if (ret == NULL) { + PyErr_SetString(PyExc_KeyError, "No such element"); + return NULL; + } + return ret; +} + +static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *def = NULL; + const char *kwnames[] = { "name", "default", "idx", NULL }; + const char *name = NULL; + int idx = -1; + struct ldb_message *msg = pyldb_Message_AsMessage(self); + struct ldb_message_element *el; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg", + discard_const_p(char *, kwnames), &name, &def, &idx)) { + return NULL; + } + + if (strcasecmp(name, "dn") == 0) { + return pyldb_Dn_FromDn(msg->dn); + } + + el = ldb_msg_find_element(msg, name); + + if (el == NULL || (idx != -1 && el->num_values <= idx)) { + if (def != NULL) { + Py_INCREF(def); + return def; + } + Py_RETURN_NONE; + } + + if (idx == -1) { + return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements); + } + + return PyObject_FromLdbValue(&el->values[idx]); +} + +static PyObject *py_ldb_msg_items(PyLdbMessageObject *self, + PyObject *Py_UNUSED(ignored)) +{ + struct ldb_message *msg = pyldb_Message_AsMessage(self); + Py_ssize_t i, j = 0; + PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1)); + if (l == NULL) { + return PyErr_NoMemory(); + } + if (msg->dn != NULL) { + PyObject *value = NULL; + PyObject *obj = pyldb_Dn_FromDn(msg->dn); + int res = 0; + value = Py_BuildValue("(sO)", "dn", obj); + Py_CLEAR(obj); + if (value == NULL) { + Py_CLEAR(l); + return NULL; + } + res = PyList_SetItem(l, 0, value); + if (res == -1) { + Py_CLEAR(l); + return NULL; + } + j++; + } + for (i = 0; i < msg->num_elements; i++, j++) { + PyObject *value = NULL; + PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements); + int res = 0; + Py_CLEAR(py_el); + value = Py_BuildValue("(sO)", msg->elements[i].name, py_el); + if (value == NULL ) { + Py_CLEAR(l); + return NULL; + } + res = PyList_SetItem(l, 0, value); + if (res == -1) { + Py_CLEAR(l); + return NULL; + } + } + return l; +} + +static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self, + PyObject *Py_UNUSED(ignored)) +{ + struct ldb_message *msg = pyldb_Message_AsMessage(self); + Py_ssize_t i = 0; + PyObject *l = PyList_New(msg->num_elements); + for (i = 0; i < msg->num_elements; i++) { + PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements)); + } + return l; +} + +static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args) +{ + struct ldb_message *msg = pyldb_Message_AsMessage(self); + PyLdbMessageElementObject *py_element; + int i, ret; + struct ldb_message_element *el; + struct ldb_message_element *el_new; + + if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element)) + return NULL; + + el = py_element->el; + if (el == NULL) { + PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object"); + return NULL; + } + if (el->name == NULL) { + PyErr_SetString(PyExc_ValueError, + "The element has no name"); + return NULL; + } + ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); + + /* now deep copy all attribute values */ + el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values); + if (el_new->values == NULL) { + PyErr_NoMemory(); + return NULL; + } + el_new->num_values = el->num_values; + + for (i = 0; i < el->num_values; i++) { + el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]); + if (el_new->values[i].data == NULL + && el->values[i].length != 0) { + PyErr_NoMemory(); + return NULL; + } + } + + Py_RETURN_NONE; +} + +static PyMethodDef py_ldb_msg_methods[] = { + { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS, + "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n" + "Class method to create ldb.Message object from Dictionary.\n" + "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."}, + { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, + "S.keys() -> list\n\n" + "Return sequence of all attribute names." }, + { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, + "S.remove(name)\n\n" + "Remove all entries for attributes with the specified name."}, + { "get", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_msg_get), + METH_VARARGS | METH_KEYWORDS, + "msg.get(name,default=None,idx=None) -> string\n" + "idx is the index into the values array\n" + "if idx is None, then a list is returned\n" + "if idx is not None, then the element with that index is returned\n" + "if you pass the special name 'dn' then the DN object is returned\n"}, + { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL }, + { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL }, + { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS, + "S.add(element)\n\n" + "Add an element to this message." }, + { NULL }, +}; + +static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self) +{ + PyObject *list, *iter; + + list = py_ldb_msg_keys(self, NULL); + iter = PyObject_GetIter(list); + Py_DECREF(list); + return iter; +} + +static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value) +{ + const char *attr_name; + + attr_name = PyUnicode_AsUTF8(name); + if (attr_name == NULL) { + PyErr_SetNone(PyExc_TypeError); + return -1; + } + + if (value == NULL) { + /* delitem */ + ldb_msg_remove_attr(self->msg, attr_name); + } else { + int ret; + struct ldb_message_element *el = PyObject_AsMessageElement(self->msg, + value, 0, attr_name); + if (el == NULL) { + return -1; + } + ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name); + ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags); + if (ret != LDB_SUCCESS) { + PyErr_SetLdbError(PyExc_LdbError, ret, NULL); + return -1; + } + } + return 0; +} + +static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self) +{ + return pyldb_Message_AsMessage(self)->num_elements; +} + +static PyMappingMethods py_ldb_msg_mapping = { + .mp_length = (lenfunc)py_ldb_msg_length, + .mp_subscript = (binaryfunc)py_ldb_msg_getitem, + .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem, +}; + +static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + const char * const kwnames[] = { "dn", NULL }; + struct ldb_message *ret; + TALLOC_CTX *mem_ctx; + PyObject *pydn = NULL; + PyLdbMessageObject *py_ret; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", + discard_const_p(char *, kwnames), + &pydn)) + return NULL; + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + ret = ldb_msg_new(mem_ctx); + if (ret == NULL) { + talloc_free(mem_ctx); + PyErr_NoMemory(); + return NULL; + } + + if (pydn != NULL) { + struct ldb_dn *dn; + if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) { + talloc_free(mem_ctx); + return NULL; + } + ret->dn = talloc_reference(ret, dn); + } + + py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0); + if (py_ret == NULL) { + PyErr_NoMemory(); + talloc_free(mem_ctx); + return NULL; + } + + py_ret->mem_ctx = mem_ctx; + py_ret->msg = ret; + return (PyObject *)py_ret; +} + +static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg) +{ + PyLdbMessageObject *ret; + + ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0); + if (ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + ret->mem_ctx = talloc_new(NULL); + ret->msg = talloc_reference(ret->mem_ctx, msg); + return (PyObject *)ret; +} + +static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure) +{ + struct ldb_message *msg = pyldb_Message_AsMessage(self); + return pyldb_Dn_FromDn(msg->dn); +} + +static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure) +{ + struct ldb_message *msg = pyldb_Message_AsMessage(self); + if (!pyldb_Dn_Check(value)) { + PyErr_SetString(PyExc_TypeError, "expected dn"); + return -1; + } + + msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value)); + return 0; +} + +static PyObject *py_ldb_msg_get_text(PyObject *self, void *closure) +{ + return wrap_text("MessageTextWrapper", self); +} + +static PyGetSetDef py_ldb_msg_getset[] = { + { + .name = discard_const_p(char, "dn"), + .get = (getter)py_ldb_msg_get_dn, + .set = (setter)py_ldb_msg_set_dn, + }, + { + .name = discard_const_p(char, "text"), + .get = (getter)py_ldb_msg_get_text, + }, + { .name = NULL }, +}; + +static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self) +{ + PyObject *dict = PyDict_New(), *ret, *repr; + if (PyDict_Update(dict, (PyObject *)self) != 0) + return NULL; + repr = PyObject_Repr(dict); + if (repr == NULL) { + Py_DECREF(dict); + return NULL; + } + ret = PyUnicode_FromFormat("Message(%s)", PyUnicode_AsUTF8(repr)); + Py_DECREF(repr); + Py_DECREF(dict); + return ret; +} + +static void py_ldb_msg_dealloc(PyLdbMessageObject *self) +{ + talloc_free(self->mem_ctx); + PyObject_Del(self); +} + +static PyObject *py_ldb_msg_richcmp(PyLdbMessageObject *py_msg1, + PyLdbMessageObject *py_msg2, int op) +{ + struct ldb_message *msg1, *msg2; + unsigned int i; + int ret; + + if (!PyLdbMessage_Check(py_msg2)) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + + msg1 = pyldb_Message_AsMessage(py_msg1), + msg2 = pyldb_Message_AsMessage(py_msg2); + + if ((msg1->dn != NULL) || (msg2->dn != NULL)) { + ret = ldb_dn_compare(msg1->dn, msg2->dn); + if (ret != 0) { + return richcmp(ret, op); + } + } + + ret = msg1->num_elements - msg2->num_elements; + if (ret != 0) { + return richcmp(ret, op); + } + + for (i = 0; i < msg1->num_elements; i++) { + ret = ldb_msg_element_compare_name(&msg1->elements[i], + &msg2->elements[i]); + if (ret != 0) { + return richcmp(ret, op); + } + + ret = ldb_msg_element_compare(&msg1->elements[i], + &msg2->elements[i]); + if (ret != 0) { + return richcmp(ret, op); + } + } + + return richcmp(0, op); +} + +static PyTypeObject PyLdbMessage = { + .tp_name = "ldb.Message", + .tp_methods = py_ldb_msg_methods, + .tp_getset = py_ldb_msg_getset, + .tp_as_mapping = &py_ldb_msg_mapping, + .tp_basicsize = sizeof(PyLdbMessageObject), + .tp_dealloc = (destructor)py_ldb_msg_dealloc, + .tp_new = py_ldb_msg_new, + .tp_repr = (reprfunc)py_ldb_msg_repr, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_iter = (getiterfunc)py_ldb_msg_iter, + .tp_richcompare = (richcmpfunc)py_ldb_msg_richcmp, + .tp_doc = "A LDB Message", +}; + +static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree) +{ + PyLdbTreeObject *ret; + + ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0); + if (ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + + ret->mem_ctx = talloc_new(NULL); + ret->tree = talloc_reference(ret->mem_ctx, tree); + return (PyObject *)ret; +} + +static void py_ldb_tree_dealloc(PyLdbTreeObject *self) +{ + talloc_free(self->mem_ctx); + PyObject_Del(self); +} + +static PyTypeObject PyLdbTree = { + .tp_name = "ldb.Tree", + .tp_basicsize = sizeof(PyLdbTreeObject), + .tp_dealloc = (destructor)py_ldb_tree_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_doc = "A search tree", +}; + +/* Ldb_module */ +static int py_module_search(struct ldb_module *mod, struct ldb_request *req) +{ + PyObject *py_ldb = (PyObject *)mod->private_data; + PyObject *py_result, *py_base, *py_attrs, *py_tree; + + py_base = pyldb_Dn_FromDn(req->op.search.base); + + if (py_base == NULL) + return LDB_ERR_OPERATIONS_ERROR; + + py_tree = PyLdbTree_FromTree(req->op.search.tree); + + if (py_tree == NULL) + return LDB_ERR_OPERATIONS_ERROR; + + if (req->op.search.attrs == NULL) { + py_attrs = Py_None; + } else { + int i, len; + for (len = 0; req->op.search.attrs[len]; len++); + py_attrs = PyList_New(len); + for (i = 0; i < len; i++) + PyList_SetItem(py_attrs, i, PyUnicode_FromString(req->op.search.attrs[i])); + } + + py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"), + discard_const_p(char, "OiOO"), + py_base, req->op.search.scope, py_tree, py_attrs); + + Py_DECREF(py_attrs); + Py_DECREF(py_tree); + Py_DECREF(py_base); + + if (py_result == NULL) { + return LDB_ERR_PYTHON_EXCEPTION; + } + + req->op.search.res = PyLdbResult_AsResult(NULL, py_result); + if (req->op.search.res == NULL) { + return LDB_ERR_PYTHON_EXCEPTION; + } + + Py_DECREF(py_result); + + return LDB_SUCCESS; +} + +static int py_module_add(struct ldb_module *mod, struct ldb_request *req) +{ + PyObject *py_ldb = (PyObject *)mod->private_data; + PyObject *py_result, *py_msg; + + py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message)); + + if (py_msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"), + discard_const_p(char, "O"), + py_msg); + + Py_DECREF(py_msg); + + if (py_result == NULL) { + return LDB_ERR_PYTHON_EXCEPTION; + } + + Py_DECREF(py_result); + + return LDB_SUCCESS; +} + +static int py_module_modify(struct ldb_module *mod, struct ldb_request *req) +{ + PyObject *py_ldb = (PyObject *)mod->private_data; + PyObject *py_result, *py_msg; + + py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message)); + + if (py_msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"), + discard_const_p(char, "O"), + py_msg); + + Py_DECREF(py_msg); + + if (py_result == NULL) { + return LDB_ERR_PYTHON_EXCEPTION; + } + + Py_DECREF(py_result); + + return LDB_SUCCESS; +} + +static int py_module_del(struct ldb_module *mod, struct ldb_request *req) +{ + PyObject *py_ldb = (PyObject *)mod->private_data; + PyObject *py_result, *py_dn; + + py_dn = pyldb_Dn_FromDn(req->op.del.dn); + + if (py_dn == NULL) + return LDB_ERR_OPERATIONS_ERROR; + + py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"), + discard_const_p(char, "O"), + py_dn); + + if (py_result == NULL) { + return LDB_ERR_PYTHON_EXCEPTION; + } + + Py_DECREF(py_result); + + return LDB_SUCCESS; +} + +static int py_module_rename(struct ldb_module *mod, struct ldb_request *req) +{ + PyObject *py_ldb = (PyObject *)mod->private_data; + PyObject *py_result, *py_olddn, *py_newdn; + + py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn); + + if (py_olddn == NULL) + return LDB_ERR_OPERATIONS_ERROR; + + py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn); + + if (py_newdn == NULL) + return LDB_ERR_OPERATIONS_ERROR; + + py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"), + discard_const_p(char, "OO"), + py_olddn, py_newdn); + + Py_DECREF(py_olddn); + Py_DECREF(py_newdn); + + if (py_result == NULL) { + return LDB_ERR_PYTHON_EXCEPTION; + } + + Py_DECREF(py_result); + + return LDB_SUCCESS; +} + +static int py_module_request(struct ldb_module *mod, struct ldb_request *req) +{ + PyObject *py_ldb = (PyObject *)mod->private_data; + PyObject *py_result; + + py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"), + discard_const_p(char, "")); + + Py_XDECREF(py_result); + + return LDB_ERR_OPERATIONS_ERROR; +} + +static int py_module_extended(struct ldb_module *mod, struct ldb_request *req) +{ + PyObject *py_ldb = (PyObject *)mod->private_data; + PyObject *py_result; + + py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"), + discard_const_p(char, "")); + + Py_XDECREF(py_result); + + return LDB_ERR_OPERATIONS_ERROR; +} + +static int py_module_start_transaction(struct ldb_module *mod) +{ + PyObject *py_ldb = (PyObject *)mod->private_data; + PyObject *py_result; + + py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"), + discard_const_p(char, "")); + + if (py_result == NULL) { + return LDB_ERR_PYTHON_EXCEPTION; + } + + Py_DECREF(py_result); + + return LDB_SUCCESS; +} + +static int py_module_end_transaction(struct ldb_module *mod) +{ + PyObject *py_ldb = (PyObject *)mod->private_data; + PyObject *py_result; + + py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"), + discard_const_p(char, "")); + + if (py_result == NULL) { + return LDB_ERR_PYTHON_EXCEPTION; + } + + Py_DECREF(py_result); + + return LDB_SUCCESS; +} + +static int py_module_del_transaction(struct ldb_module *mod) +{ + PyObject *py_ldb = (PyObject *)mod->private_data; + PyObject *py_result; + + py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"), + discard_const_p(char, "")); + + if (py_result == NULL) { + return LDB_ERR_PYTHON_EXCEPTION; + } + + Py_DECREF(py_result); + + return LDB_SUCCESS; +} + +static int py_module_destructor(struct ldb_module *mod) +{ + Py_DECREF((PyObject *)mod->private_data); + return 0; +} + +static int py_module_init(struct ldb_module *mod) +{ + PyObject *py_class = (PyObject *)mod->ops->private_data; + PyObject *py_result, *py_next, *py_ldb; + + py_ldb = PyLdb_FromLdbContext(mod->ldb); + + if (py_ldb == NULL) + return LDB_ERR_OPERATIONS_ERROR; + + py_next = PyLdbModule_FromModule(mod->next); + + if (py_next == NULL) + return LDB_ERR_OPERATIONS_ERROR; + + py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"), + py_ldb, py_next); + + if (py_result == NULL) { + return LDB_ERR_PYTHON_EXCEPTION; + } + + mod->private_data = py_result; + + talloc_set_destructor(mod, py_module_destructor); + + return ldb_next_init(mod); +} + +static PyObject *py_register_module(PyObject *module, PyObject *args) +{ + int ret; + struct ldb_module_ops *ops; + PyObject *input; + PyObject *tmp; + + if (!PyArg_ParseTuple(args, "O", &input)) + return NULL; + + ops = talloc_zero(NULL, struct ldb_module_ops); + if (ops == NULL) { + PyErr_NoMemory(); + return NULL; + } + + tmp = PyObject_GetAttrString(input, discard_const_p(char, "name")); + ops->name = talloc_strdup(ops, PyUnicode_AsUTF8(tmp)); + + Py_XDECREF(tmp); + Py_INCREF(input); + ops->private_data = input; + ops->init_context = py_module_init; + ops->search = py_module_search; + ops->add = py_module_add; + ops->modify = py_module_modify; + ops->del = py_module_del; + ops->rename = py_module_rename; + ops->request = py_module_request; + ops->extended = py_module_extended; + ops->start_transaction = py_module_start_transaction; + ops->end_transaction = py_module_end_transaction; + ops->del_transaction = py_module_del_transaction; + + ret = ldb_register_module(ops); + if (ret != LDB_SUCCESS) { + TALLOC_FREE(ops); + } + + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); + + Py_RETURN_NONE; +} + +static PyObject *py_timestring(PyObject *module, PyObject *args) +{ + /* most times "time_t" is a signed integer type with 32 or 64 bit: + * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */ + long int t_val; + char *tresult; + PyObject *ret; + if (!PyArg_ParseTuple(args, "l", &t_val)) + return NULL; + tresult = ldb_timestring(NULL, (time_t) t_val); + ret = PyUnicode_FromString(tresult); + talloc_free(tresult); + return ret; +} + +static PyObject *py_string_to_time(PyObject *module, PyObject *args) +{ + char *str; + if (!PyArg_ParseTuple(args, "s", &str)) + return NULL; + + return PyInt_FromLong(ldb_string_to_time(str)); +} + +static PyObject *py_valid_attr_name(PyObject *self, PyObject *args) +{ + char *name; + if (!PyArg_ParseTuple(args, "s", &name)) + return NULL; + return PyBool_FromLong(ldb_valid_attr_name(name)); +} + +/* + encode a string using RFC2254 rules + */ +static PyObject *py_binary_encode(PyObject *self, PyObject *args) +{ + char *str, *encoded; + Py_ssize_t size = 0; + struct ldb_val val; + PyObject *ret; + + if (!PyArg_ParseTuple(args, "s#", &str, &size)) + return NULL; + val.data = (uint8_t *)str; + val.length = size; + + encoded = ldb_binary_encode(NULL, val); + if (encoded == NULL) { + PyErr_SetString(PyExc_TypeError, "unable to encode binary string"); + return NULL; + } + ret = PyUnicode_FromString(encoded); + talloc_free(encoded); + return ret; +} + +/* + decode a string using RFC2254 rules + */ +static PyObject *py_binary_decode(PyObject *self, PyObject *args) +{ + char *str; + struct ldb_val val; + PyObject *ret; + + if (!PyArg_ParseTuple(args, "s", &str)) + return NULL; + + val = ldb_binary_decode(NULL, str); + if (val.data == NULL) { + PyErr_SetString(PyExc_TypeError, "unable to decode binary string"); + return NULL; + } + ret = PyBytes_FromStringAndSize((const char*)val.data, val.length); + talloc_free(val.data); + return ret; +} + +static PyMethodDef py_ldb_global_methods[] = { + { "register_module", py_register_module, METH_VARARGS, + "S.register_module(module) -> None\n\n" + "Register a LDB module."}, + { "timestring", py_timestring, METH_VARARGS, + "S.timestring(int) -> string\n\n" + "Generate a LDAP time string from a UNIX timestamp" }, + { "string_to_time", py_string_to_time, METH_VARARGS, + "S.string_to_time(string) -> int\n\n" + "Parse a LDAP time string into a UNIX timestamp." }, + { "valid_attr_name", py_valid_attr_name, METH_VARARGS, + "S.valid_attr_name(name) -> bool\n\nn" + "Check whether the supplied name is a valid attribute name." }, + { "open", PY_DISCARD_FUNC_SIG(PyCFunction,py_ldb_new), + METH_VARARGS|METH_KEYWORDS, + "S.open() -> Ldb\n\n" + "Open a new LDB context." }, + { "binary_encode", py_binary_encode, METH_VARARGS, + "S.binary_encode(string) -> string\n\n" + "Perform a RFC2254 binary encoding on a string" }, + { "binary_decode", py_binary_decode, METH_VARARGS, + "S.binary_decode(string) -> string\n\n" + "Perform a RFC2254 binary decode on a string" }, + { NULL } +}; + +#define MODULE_DOC "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server." + +#if PY_MAJOR_VERSION >= 3 +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + .m_name = "ldb", + .m_doc = MODULE_DOC, + .m_size = -1, + .m_methods = py_ldb_global_methods, +}; +#endif + +static PyObject* module_init(void) +{ + PyObject *m; + + PyLdbBytesType.tp_base = &PyBytes_Type; + if (PyType_Ready(&PyLdbBytesType) < 0) { + return NULL; + } + + if (PyType_Ready(&PyLdbDn) < 0) + return NULL; + + if (PyType_Ready(&PyLdbMessage) < 0) + return NULL; + + if (PyType_Ready(&PyLdbMessageElement) < 0) + return NULL; + + if (PyType_Ready(&PyLdb) < 0) + return NULL; + + if (PyType_Ready(&PyLdbModule) < 0) + return NULL; + + if (PyType_Ready(&PyLdbTree) < 0) + return NULL; + + if (PyType_Ready(&PyLdbResult) < 0) + return NULL; + + if (PyType_Ready(&PyLdbSearchIterator) < 0) + return NULL; + + if (PyType_Ready(&PyLdbControl) < 0) + return NULL; + +#if PY_MAJOR_VERSION >= 3 + m = PyModule_Create(&moduledef); +#else + m = Py_InitModule3("ldb", py_ldb_global_methods, MODULE_DOC); +#endif + if (m == NULL) + return NULL; + +#define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val) + + ADD_LDB_INT(SEQ_HIGHEST_SEQ); + ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP); + ADD_LDB_INT(SEQ_NEXT); + ADD_LDB_INT(SCOPE_DEFAULT); + ADD_LDB_INT(SCOPE_BASE); + ADD_LDB_INT(SCOPE_ONELEVEL); + ADD_LDB_INT(SCOPE_SUBTREE); + + ADD_LDB_INT(CHANGETYPE_NONE); + ADD_LDB_INT(CHANGETYPE_ADD); + ADD_LDB_INT(CHANGETYPE_DELETE); + ADD_LDB_INT(CHANGETYPE_MODIFY); + + ADD_LDB_INT(FLAG_MOD_ADD); + ADD_LDB_INT(FLAG_MOD_REPLACE); + ADD_LDB_INT(FLAG_MOD_DELETE); + ADD_LDB_INT(FLAG_FORCE_NO_BASE64_LDIF); + + ADD_LDB_INT(ATTR_FLAG_HIDDEN); + ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX); + ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE); + ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF); + + ADD_LDB_INT(SUCCESS); + ADD_LDB_INT(ERR_OPERATIONS_ERROR); + ADD_LDB_INT(ERR_PROTOCOL_ERROR); + ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED); + ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED); + ADD_LDB_INT(ERR_COMPARE_FALSE); + ADD_LDB_INT(ERR_COMPARE_TRUE); + ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED); + ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED); + ADD_LDB_INT(ERR_REFERRAL); + ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED); + ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION); + ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED); + ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS); + ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE); + ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE); + ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING); + ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION); + ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS); + ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX); + ADD_LDB_INT(ERR_NO_SUCH_OBJECT); + ADD_LDB_INT(ERR_ALIAS_PROBLEM); + ADD_LDB_INT(ERR_INVALID_DN_SYNTAX); + ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM); + ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION); + ADD_LDB_INT(ERR_INVALID_CREDENTIALS); + ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS); + ADD_LDB_INT(ERR_BUSY); + ADD_LDB_INT(ERR_UNAVAILABLE); + ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM); + ADD_LDB_INT(ERR_LOOP_DETECT); + ADD_LDB_INT(ERR_NAMING_VIOLATION); + ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION); + ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF); + ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN); + ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS); + ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED); + ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS); + ADD_LDB_INT(ERR_OTHER); + + ADD_LDB_INT(FLG_RDONLY); + ADD_LDB_INT(FLG_NOSYNC); + ADD_LDB_INT(FLG_RECONNECT); + ADD_LDB_INT(FLG_NOMMAP); + ADD_LDB_INT(FLG_SHOW_BINARY); + ADD_LDB_INT(FLG_ENABLE_TRACING); + ADD_LDB_INT(FLG_DONT_CREATE_DB); + + ADD_LDB_INT(PACKING_FORMAT); + ADD_LDB_INT(PACKING_FORMAT_V2); + + /* Historical misspelling */ + PyModule_AddIntConstant(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM); + + PyModule_AddStringConstant(m, "__docformat__", "restructuredText"); + + PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL); + PyModule_AddObject(m, "LdbError", PyExc_LdbError); + + Py_INCREF(&PyLdb); + Py_INCREF(&PyLdbDn); + Py_INCREF(&PyLdbModule); + Py_INCREF(&PyLdbMessage); + Py_INCREF(&PyLdbMessageElement); + Py_INCREF(&PyLdbTree); + Py_INCREF(&PyLdbResult); + Py_INCREF(&PyLdbControl); + + PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb); + PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn); + PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage); + PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement); + PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule); + PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree); + PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl); + + PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION); + +#define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val) + + ADD_LDB_STRING(SYNTAX_DN); + ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING); + ADD_LDB_STRING(SYNTAX_INTEGER); + ADD_LDB_STRING(SYNTAX_ORDERED_INTEGER); + ADD_LDB_STRING(SYNTAX_BOOLEAN); + ADD_LDB_STRING(SYNTAX_OCTET_STRING); + ADD_LDB_STRING(SYNTAX_UTC_TIME); + ADD_LDB_STRING(OID_COMPARATOR_AND); + ADD_LDB_STRING(OID_COMPARATOR_OR); + + return m; +} + +#if PY_MAJOR_VERSION >= 3 +PyMODINIT_FUNC PyInit_ldb(void); +PyMODINIT_FUNC PyInit_ldb(void) +{ + return module_init(); +} +#else +void initldb(void); +void initldb(void) +{ + module_init(); +} +#endif diff --git a/ldb-2.0.8/pyldb.h b/ldb-2.0.8/pyldb.h new file mode 100644 index 0000000..4fc89ec --- /dev/null +++ b/ldb-2.0.8/pyldb.h @@ -0,0 +1,109 @@ +/* + Unix SMB/CIFS implementation. + + Python interface to ldb. + + Copyright (C) 2007-2008 Jelmer Vernooij + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#ifndef _PYLDB_H_ +#define _PYLDB_H_ + +#include + +typedef struct { + PyObject_HEAD + TALLOC_CTX *mem_ctx; + struct ldb_context *ldb_ctx; +} PyLdbObject; + +#define pyldb_Ldb_AsLdbContext(pyobj) ((PyLdbObject *)pyobj)->ldb_ctx + +typedef struct { + PyObject_HEAD + TALLOC_CTX *mem_ctx; + struct ldb_dn *dn; +} PyLdbDnObject; + +PyObject *pyldb_Dn_FromDn(struct ldb_dn *); +bool pyldb_Object_AsDn(TALLOC_CTX *mem_ctx, PyObject *object, struct ldb_context *ldb_ctx, struct ldb_dn **dn); +#define pyldb_Dn_AsDn(pyobj) ((PyLdbDnObject *)pyobj)->dn + +typedef struct { + PyObject_HEAD + TALLOC_CTX *mem_ctx; + struct ldb_message *msg; +} PyLdbMessageObject; +#define pyldb_Message_AsMessage(pyobj) ((PyLdbMessageObject *)pyobj)->msg + +typedef struct { + PyObject_HEAD + TALLOC_CTX *mem_ctx; + struct ldb_module *mod; +} PyLdbModuleObject; +#define pyldb_Module_AsModule(pyobj) ((PyLdbModuleObject *)pyobj)->mod + +/* + * NOTE: el (and so the return value of + * pyldb_MessageElement_AsMessageElement()) may not be a valid talloc + * context, it could be part of an array + */ + +typedef struct { + PyObject_HEAD + TALLOC_CTX *mem_ctx; + struct ldb_message_element *el; +} PyLdbMessageElementObject; + +#define pyldb_MessageElement_AsMessageElement(pyobj) ((PyLdbMessageElementObject *)pyobj)->el + +typedef struct { + PyObject_HEAD + TALLOC_CTX *mem_ctx; + struct ldb_parse_tree *tree; +} PyLdbTreeObject; +#define pyldb_Tree_AsTree(pyobj) ((PyLdbTreeObject *)pyobj)->tree + +typedef struct { + PyObject_HEAD + TALLOC_CTX *mem_ctx; + PyObject *msgs; + PyObject *referals; + PyObject *controls; +} PyLdbResultObject; + +typedef struct { + PyObject_HEAD + TALLOC_CTX *mem_ctx; + struct ldb_control *data; +} PyLdbControlObject; + +#define PyErr_LDB_ERROR_IS_ERR_RAISE(err,ret,ldb) do { \ + if (ret != LDB_SUCCESS) { \ + PyErr_SetLdbError(err, ret, ldb); \ + return NULL; \ + } \ +} while(0) + +/* Picked out of thin air. To do this properly, we should probably have some part of the + * errors in LDB be allocated to bindings ? */ +#define LDB_ERR_PYTHON_EXCEPTION 142 + +#endif /* _PYLDB_H_ */ diff --git a/ldb-2.0.8/pyldb_util.c b/ldb-2.0.8/pyldb_util.c new file mode 100644 index 0000000..f8d0664 --- /dev/null +++ b/ldb-2.0.8/pyldb_util.c @@ -0,0 +1,113 @@ +/* + Unix SMB/CIFS implementation. + + Python interface to ldb - utility functions. + + Copyright (C) 2007-2010 Jelmer Vernooij + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include +#include "ldb.h" +#include "pyldb.h" + +static PyObject *ldb_module = NULL; + +/** + * Find out PyTypeObject in ldb module for a given typename + */ +static PyTypeObject * PyLdb_GetPyType(const char *typename) +{ + PyObject *py_obj = NULL; + + if (ldb_module == NULL) { + ldb_module = PyImport_ImportModule("ldb"); + if (ldb_module == NULL) { + return NULL; + } + } + + py_obj = PyObject_GetAttrString(ldb_module, typename); + + return (PyTypeObject*)py_obj; +} + +/** + * Obtain a ldb DN from a Python object. + * + * @param mem_ctx Memory context + * @param object Python object + * @param ldb_ctx LDB context + * @return Whether or not the conversion succeeded + */ +bool pyldb_Object_AsDn(TALLOC_CTX *mem_ctx, PyObject *object, + struct ldb_context *ldb_ctx, struct ldb_dn **dn) +{ + struct ldb_dn *odn; + PyTypeObject *PyLdb_Dn_Type; + + if (ldb_ctx != NULL && (PyUnicode_Check(object))) { + odn = ldb_dn_new(mem_ctx, ldb_ctx, PyUnicode_AsUTF8(object)); + *dn = odn; + return true; + } + + if (ldb_ctx != NULL && PyBytes_Check(object)) { + odn = ldb_dn_new(mem_ctx, ldb_ctx, PyBytes_AsString(object)); + *dn = odn; + return true; + } + + PyLdb_Dn_Type = PyLdb_GetPyType("Dn"); + if (PyLdb_Dn_Type == NULL) { + return false; + } + + if (PyObject_TypeCheck(object, PyLdb_Dn_Type)) { + *dn = pyldb_Dn_AsDn(object); + return true; + } + + PyErr_SetString(PyExc_TypeError, "Expected DN"); + return false; +} + +PyObject *pyldb_Dn_FromDn(struct ldb_dn *dn) +{ + PyLdbDnObject *py_ret; + PyTypeObject *PyLdb_Dn_Type; + + if (dn == NULL) { + Py_RETURN_NONE; + } + + PyLdb_Dn_Type = PyLdb_GetPyType("Dn"); + if (PyLdb_Dn_Type == NULL) { + return NULL; + } + + py_ret = (PyLdbDnObject *)PyLdb_Dn_Type->tp_alloc(PyLdb_Dn_Type, 0); + if (py_ret == NULL) { + PyErr_NoMemory(); + return NULL; + } + py_ret->mem_ctx = talloc_new(NULL); + py_ret->dn = talloc_reference(py_ret->mem_ctx, dn); + return (PyObject *)py_ret; +} diff --git a/ldb-2.0.8/tests/guidindexpackv1.ldb b/ldb-2.0.8/tests/guidindexpackv1.ldb new file mode 100644 index 0000000000000000000000000000000000000000..4c79dfeddddb95cdb46a044522ca4eae99f3a3d4 GIT binary patch literal 1286144 zcmeI*U5H#)0SE9Kn}<+IjkbyvKNbsZ!Kkydp9x*rB%9QQxCz;f2CK#-JKILHNi>Gy zM?s_yLSKqRsZeO3FP1)Nu?4|a(p+S5}H6X!rWV5Nq2a<{;5aa>biD) zb9Rjzvvv5D8*^S~B|v}x0RjXF5FkK+009C72oNAZfB*pk1PBlyK!8A}3%vIioi3pN zODgd5B|V#y5g$ zxUBwOoB)BhFUd5FpUHz?qA!*HNQh;MAG=b!!9&5Fk)Y z;J%lN9e1-GwflEBTaP-kKN~J|X212C009C72oNAZptA(7_`bKZ0@qst1eQ$T$csyM zDkma9fB*pk1PFA5z`0*`L^pMk009C72oNB!WCEW%yJV+wA_4>m5FkK+Kt~8X|ErGZ zrcM$dK!5-N0t5&UAV7cs0RjXF5FkKc#R+uz+g2+s6AdD;Sb_h1p#BU~f4}~R`YqN7 z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV6TX3Ec6)nHEp1Ns4$f&xqD=6Xn1sNWc$9&!=oenc8zV{JhE+Qe9Nb{ZrK=~?AmjG@?bdXZJ|caVX^wB zx9=Gr-8Ghk*QqW&q0-2{>eJInY$)7#fSFu3W!!9$aksrvP)Qp0+8!+N=4y{BQl zw_&}nVZFa$eV}1|Ff?(|oEt)o#xo^H4@_68d*2@R)|@Okb~1BwI4ZYX zo;@N?e_0C4;jr{Q^VnVKu`@EZxvmd`sXkdy^n_JFLc&hG!hkD6uG zpP5y<$@y9JH_K`uJF8;DFDt7TPD~ExXVu?MR_RKuXVtfutZx7Mwa1!e)t8x7y2<%j z^)<_?KRc^p!!Ks_#BY=2-tZVdKmQn(`1u+CO;wT4&*5-^$5qgwtl`&fI8e_`EwzLDR*ayw%&U8(i{bwJ98|io18xuyPJ*0a`sp(_V$_^i?vx@o&L_c{H(g$$tqo`^{nDs zrclYs>gj(a*PCTk%FHU=vpCCTaV7{9Ola#&jVzH%w<%XEd;tiO?vzAqCFsVnj4bgKmR{7~iSwucTJeXufFeXVzfs^LD`rcz(IyHxHjmj^#q z`fPHd@|Ba7qlYSEC#MfqzFIvn-tp^R;G_Li*dI$2en(jD2+QOH7oVSN)0T;eJ)>Lq zhMQT{R)xLEaLu;3UM-&tU#~owBs;@n?Au4e68kpyv(TM z1UgROj5$>no%yLVi$2BTPVmK0-F<+?8LHj3z?BPaS5=V!0RjXF5FkK+009C7+7Wm> zRB|7n9XWLf5FkK+0D+rSpv&*NZqj6RtCIx=yXt!%{~lZY7Hb4LNZ==-ukHhMP~f^s zfB*pk1PBlyK!8BI0=v6rYSzxVVIINSIUmgTP2U+VYg&xO@+ ze9QCkMw9o)DLg`{om<9yf=y>)Zk#_iJvm?N*U|-MeVNH-?rYYy)O>=4vr13S*LqgP zCOiv)Wo2bP!NOUYPcUAWYvyy0zY1x%-Y+T|pDq9Z literal 0 HcmV?d00001 diff --git a/ldb-2.0.8/tests/init.ldif b/ldb-2.0.8/tests/init.ldif new file mode 100644 index 0000000..97b4561 --- /dev/null +++ b/ldb-2.0.8/tests/init.ldif @@ -0,0 +1,41 @@ +dn: o=University of Michigan,c=TEST +objectclass: organization +objectclass: domainRelatedObject +l: Ann Arbor, Michigan +st: Michigan +o: University of Michigan +o: UMICH +o: UM +o: U-M +o: U of M +description: The University of Michigan at Ann Arbor +postaladdress: University of Michigan $ 535 W. William St. $ Ann Arbor, MI 481 + 09 $ US +telephonenumber: +1 313 764-1817 +associateddomain: example.com + +# there was an empty "seeAlso" here + +dn: ou=People,o=University of Michigan,c=TEST +objectclass: organizationalUnit +objectclass: extensibleObject +ou: People +uidNumber: 0 +gidNumber: 0 + +dn: ou=Ldb Test,ou=People,o=University of Michigan,c=TEST +objectclass: organizationalUnit +objectclass: extensibleObject +ou: People +ou: Ldb Test +uidNumber: 0 +gidNumber: 0 + +dn: ou=LdbTspace,ou=People,o=University of Michigan,c=TEST +objectclass: organizationalUnit +objectclass: extensibleObject +ou: People +ou: LdbTspace +description: test white space removal in comparisons +uidNumber: 0 +gidNumber: 0 diff --git a/ldb-2.0.8/tests/init_slapd.sh b/ldb-2.0.8/tests/init_slapd.sh new file mode 100755 index 0000000..cf06acd --- /dev/null +++ b/ldb-2.0.8/tests/init_slapd.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +if [ -z "$LDBDIR" ]; then + LDBDIR=`dirname $0`/.. + export LDBDIR +fi + +rm -rf tests/tmp/db +mkdir -p tests/tmp/db + +if [ -f tests/tmp/slapd.pid ]; then + kill `cat tests/tmp/slapd.pid` + sleep 1 +fi +if [ -f tests/tmp/slapd.pid ]; then + kill -9 `cat tests/tmp/slapd.pid` + rm -f tests/tmp/slapd.pid +fi + +# we don't consider a slapadd failure as a test suite failure, as it +# has nothing to do with ldb + +MODCONF=tests/tmp/modules.conf +rm -f $MODCONF +touch $MODCONF || exit 1 + +slaptest -u -f $LDBDIR/tests/slapd.conf > /dev/null 2>&1 || { + echo "enabling sladp modules" +cat > $MODCONF < 2019 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* + * from cmocka.c: + * These headers or their equivalents should be included prior to + * including + * this header file. + * + * #include + * #include + * #include + * + * This allows test applications to use custom definitions of C standard + * library functions and types. + */ +#include +#include +#include +#include +#include + +#include "../include/ldb.h" +#include "../include/ldb_module.h" + +struct ldbtest_ctx { + struct tevent_context *ev; + struct ldb_context *ldb; +}; + +/* + * NOTE WELL: + * + * This test checks the current behaviour of the function, however + * this is not in a public ABI and many of the tested behaviours are + * not ideal. If the behaviour is deliberatly improved, this test + * should be updated without worry to the new better behaviour. + * + * In particular the test is particularly to ensure the current + * behaviour is memory-safe. + */ + +static int setup(void **state) +{ + struct ldbtest_ctx *test_ctx; + + test_ctx = talloc_zero(NULL, struct ldbtest_ctx); + assert_non_null(test_ctx); + + test_ctx->ev = tevent_context_init(test_ctx); + assert_non_null(test_ctx->ev); + + test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev); + assert_non_null(test_ctx->ldb); + + *state = test_ctx; + return 0; +} + +static int teardown(void **state) +{ + talloc_free(*state); + return 0; +} + + +/* + * Test against a record with only one attribute, matching the one in + * the list + */ +static void test_filter_attrs_one_attr_matched(void **state) +{ + struct ldbtest_ctx *ctx = *state; + int ret; + + struct ldb_message *filtered_msg = ldb_msg_new(ctx); + + const char *attrs[] = {"foo", NULL}; + + uint8_t value[] = "The value.......end"; + struct ldb_val value_1 = { + .data = value, + .length = (sizeof(value)) + }; + struct ldb_message_element element_1 = { + .name = "foo", + .num_values = 1, + .values = &value_1 + }; + struct ldb_message in = { + .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), + .num_elements = 1, + .elements = &element_1, + }; + + assert_non_null(in.dn); + + ret = ldb_filter_attrs(ctx->ldb, + &in, + attrs, + filtered_msg); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(filtered_msg); + + /* + * assert the ldb_filter_attrs does not read or modify + * filtered_msg.dn in this case + */ + assert_null(filtered_msg->dn); + assert_int_equal(filtered_msg->num_elements, 1); + assert_string_equal(filtered_msg->elements[0].name, "foo"); + assert_int_equal(filtered_msg->elements[0].num_values, 1); + assert_int_equal(filtered_msg->elements[0].values[0].length, + sizeof(value)); + assert_memory_equal(filtered_msg->elements[0].values[0].data, + value, sizeof(value)); +} + +/* + * Test against a record with only one attribute, matching the one of + * the multiple attributes in the list + */ +static void test_filter_attrs_one_attr_matched_of_many(void **state) +{ + struct ldbtest_ctx *ctx = *state; + int ret; + + struct ldb_message *filtered_msg = ldb_msg_new(ctx); + + const char *attrs[] = {"foo", "bar", "baz", NULL}; + + uint8_t value[] = "The value.......end"; + struct ldb_val value_1 = { + .data = value, + .length = (sizeof(value)) + }; + struct ldb_message_element element_1 = { + .name = "foo", + .num_values = 1, + .values = &value_1 + }; + struct ldb_message in = { + .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), + .num_elements = 1, + .elements = &element_1, + }; + + assert_non_null(in.dn); + + ret = ldb_filter_attrs(ctx->ldb, + &in, + attrs, + filtered_msg); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(filtered_msg); + + /* + * assert the ldb_filter_attrs does not read or modify + * filtered_msg.dn in this case + */ + assert_null(filtered_msg->dn); + assert_int_equal(filtered_msg->num_elements, 1); + assert_string_equal(filtered_msg->elements[0].name, "foo"); + assert_int_equal(filtered_msg->elements[0].num_values, 1); + assert_int_equal(filtered_msg->elements[0].values[0].length, + sizeof(value)); + assert_memory_equal(filtered_msg->elements[0].values[0].data, + value, sizeof(value)); +} + +/* + * Test against a record with only one attribute, matching both + * attributes in the list + */ +static void test_filter_attrs_two_attr_matched_attrs(void **state) +{ + struct ldbtest_ctx *ctx = *state; + int ret; + + struct ldb_message *filtered_msg = ldb_msg_new(ctx); + + /* deliberatly the other order */ + const char *attrs[] = {"bar", "foo", NULL}; + + uint8_t value1[] = "The value.......end"; + uint8_t value2[] = "The value..MUST.end"; + struct ldb_val value_1 = { + .data = value1, + .length = (sizeof(value1)) + }; + struct ldb_val value_2 = { + .data = value2, + .length = (sizeof(value2)) + }; + + /* foo and bar are the other order to in attrs */ + struct ldb_message_element elements[] = { + { + .name = "foo", + .num_values = 1, + .values = &value_1 + }, + { + .name = "bar", + .num_values = 1, + .values = &value_2 + } + }; + struct ldb_message in = { + .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), + .num_elements = 2, + .elements = elements, + }; + + assert_non_null(in.dn); + + ret = ldb_filter_attrs(ctx->ldb, + &in, + attrs, + filtered_msg); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(filtered_msg); + assert_int_equal(filtered_msg->num_elements, 2); + + /* + * assert the ldb_filter_attrs does not read or modify + * filtered_msg.dn in this case + */ + assert_null(filtered_msg->dn); + + /* Assert that DB order is preserved */ + assert_string_equal(filtered_msg->elements[0].name, "foo"); + assert_int_equal(filtered_msg->elements[0].num_values, 1); + assert_int_equal(filtered_msg->elements[0].values[0].length, + sizeof(value1)); + assert_memory_equal(filtered_msg->elements[0].values[0].data, + value1, sizeof(value1)); + assert_string_equal(filtered_msg->elements[1].name, "bar"); + assert_int_equal(filtered_msg->elements[1].num_values, 1); + assert_int_equal(filtered_msg->elements[1].values[0].length, + sizeof(value2)); + assert_memory_equal(filtered_msg->elements[1].values[0].data, + value2, sizeof(value2)); +} + +/* + * Test against a record with two attributes, only of which is in + * the list + */ +static void test_filter_attrs_two_attr_matched_one_attr(void **state) +{ + struct ldbtest_ctx *ctx = *state; + int ret; + + struct ldb_message *filtered_msg = ldb_msg_new(ctx); + + /* deliberatly the other order */ + const char *attrs[] = {"bar", NULL}; + + uint8_t value1[] = "The value.......end"; + uint8_t value2[] = "The value..MUST.end"; + struct ldb_val value_1 = { + .data = value1, + .length = (sizeof(value1)) + }; + struct ldb_val value_2 = { + .data = value2, + .length = (sizeof(value2)) + }; + + /* foo and bar are the other order to in attrs */ + struct ldb_message_element elements[] = { + { + .name = "foo", + .num_values = 1, + .values = &value_1 + }, + { + .name = "bar", + .num_values = 1, + .values = &value_2 + } + }; + struct ldb_message in = { + .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), + .num_elements = 2, + .elements = elements, + }; + + assert_non_null(in.dn); + + ret = ldb_filter_attrs(ctx->ldb, + &in, + attrs, + filtered_msg); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(filtered_msg); + assert_int_equal(filtered_msg->num_elements, 1); + + /* + * assert the ldb_filter_attrs does not read or modify + * filtered_msg.dn in this case + */ + assert_null(filtered_msg->dn); + + /* Assert that DB order is preserved */ + assert_string_equal(filtered_msg->elements[0].name, "bar"); + assert_int_equal(filtered_msg->elements[0].num_values, 1); + assert_int_equal(filtered_msg->elements[0].values[0].length, + sizeof(value2)); + assert_memory_equal(filtered_msg->elements[0].values[0].data, + value2, sizeof(value2)); +} + +/* + * Test against a record with two attributes, both matching the one + * specified attribute in the list (a corrupt record) + */ +static void test_filter_attrs_two_dup_attr_matched_one_attr(void **state) +{ + struct ldbtest_ctx *ctx = *state; + int ret; + + struct ldb_message *filtered_msg = ldb_msg_new(ctx); + + /* deliberatly the other order */ + const char *attrs[] = {"bar", NULL}; + + uint8_t value1[] = "The value.......end"; + uint8_t value2[] = "The value..MUST.end"; + struct ldb_val value_1 = { + .data = value1, + .length = (sizeof(value1)) + }; + struct ldb_val value_2 = { + .data = value2, + .length = (sizeof(value2)) + }; + + /* foo and bar are the other order to in attrs */ + struct ldb_message_element elements[] = { + { + .name = "bar", + .num_values = 1, + .values = &value_1 + }, + { + .name = "bar", + .num_values = 1, + .values = &value_2 + } + }; + struct ldb_message in = { + .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), + .num_elements = 2, + .elements = elements, + }; + + assert_non_null(in.dn); + + ret = ldb_filter_attrs(ctx->ldb, + &in, + attrs, + filtered_msg); + + /* This should fail the pidgenhole test */ + assert_int_equal(ret, -1); + assert_null(filtered_msg->elements); +} + +/* + * Test against a record with two attributes, both matching the one + * specified attribute in the list (a corrupt record) + */ +static void test_filter_attrs_two_dup_attr_matched_dup(void **state) +{ + struct ldbtest_ctx *ctx = *state; + int ret; + + struct ldb_message *filtered_msg = ldb_msg_new(ctx); + + const char *attrs[] = {"bar", "bar", NULL}; + + uint8_t value1[] = "The value.......end"; + uint8_t value2[] = "The value..MUST.end"; + struct ldb_val value_1 = { + .data = value1, + .length = (sizeof(value1)) + }; + struct ldb_val value_2 = { + .data = value2, + .length = (sizeof(value2)) + }; + + /* foo and bar are the other order to in attrs */ + struct ldb_message_element elements[] = { + { + .name = "bar", + .num_values = 1, + .values = &value_1 + }, + { + .name = "bar", + .num_values = 1, + .values = &value_2 + } + }; + struct ldb_message in = { + .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), + .num_elements = 2, + .elements = elements, + }; + + assert_non_null(in.dn); + + ret = ldb_filter_attrs(ctx->ldb, + &in, + attrs, + filtered_msg); + + /* This does not fail the pidgenhole test */ + assert_int_equal(ret, LDB_SUCCESS); + assert_int_equal(filtered_msg->num_elements, 2); + + /* Assert that DB order is preserved */ + assert_string_equal(filtered_msg->elements[0].name, "bar"); + assert_int_equal(filtered_msg->elements[0].num_values, 1); + assert_int_equal(filtered_msg->elements[0].values[0].length, + sizeof(value1)); + assert_memory_equal(filtered_msg->elements[0].values[0].data, + value1, sizeof(value1)); + assert_string_equal(filtered_msg->elements[1].name, "bar"); + assert_int_equal(filtered_msg->elements[1].num_values, 1); + assert_int_equal(filtered_msg->elements[1].values[0].length, + sizeof(value2)); + assert_memory_equal(filtered_msg->elements[1].values[0].data, + value2, sizeof(value2)); +} + +/* + * Test against a record with two attributes, both matching one of the + * specified attributes in the list (a corrupt record) + */ +static void test_filter_attrs_two_dup_attr_matched_one_of_two(void **state) +{ + struct ldbtest_ctx *ctx = *state; + int ret; + + struct ldb_message *filtered_msg = ldb_msg_new(ctx); + + const char *attrs[] = {"bar", "foo", NULL}; + + uint8_t value1[] = "The value.......end"; + uint8_t value2[] = "The value..MUST.end"; + struct ldb_val value_1 = { + .data = value1, + .length = (sizeof(value1)) + }; + struct ldb_val value_2 = { + .data = value2, + .length = (sizeof(value2)) + }; + + /* foo and bar are the other order to in attrs */ + struct ldb_message_element elements[] = { + { + .name = "bar", + .num_values = 1, + .values = &value_1 + }, + { + .name = "bar", + .num_values = 1, + .values = &value_2 + } + }; + struct ldb_message in = { + .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), + .num_elements = 2, + .elements = elements, + }; + + assert_non_null(in.dn); + + ret = ldb_filter_attrs(ctx->ldb, + &in, + attrs, + filtered_msg); + + /* This does not fail the pidgenhole test */ + assert_int_equal(ret, LDB_SUCCESS); + assert_int_equal(filtered_msg->num_elements, 2); + + /* Assert that DB order is preserved */ + assert_string_equal(filtered_msg->elements[0].name, "bar"); + assert_int_equal(filtered_msg->elements[0].num_values, 1); + assert_int_equal(filtered_msg->elements[0].values[0].length, + sizeof(value1)); + assert_memory_equal(filtered_msg->elements[0].values[0].data, + value1, sizeof(value1)); + assert_string_equal(filtered_msg->elements[1].name, "bar"); + assert_int_equal(filtered_msg->elements[1].num_values, 1); + assert_int_equal(filtered_msg->elements[1].values[0].length, + sizeof(value2)); + assert_memory_equal(filtered_msg->elements[1].values[0].data, + value2, sizeof(value2)); +} + +/* + * Test against a record with two attributes against * (but not the + * other named attribute) (a corrupt record) + */ +static void test_filter_attrs_two_dup_attr_matched_star(void **state) +{ + struct ldbtest_ctx *ctx = *state; + int ret; + + struct ldb_message *filtered_msg = ldb_msg_new(ctx); + + const char *attrs[] = {"*", "foo", NULL}; + + uint8_t value1[] = "The value.......end"; + uint8_t value2[] = "The value..MUST.end"; + struct ldb_val value_1 = { + .data = value1, + .length = (sizeof(value1)) + }; + struct ldb_val value_2 = { + .data = value2, + .length = (sizeof(value2)) + }; + + /* foo and bar are the other order to in attrs */ + struct ldb_message_element elements[] = { + { + .name = "bar", + .num_values = 1, + .values = &value_1 + }, + { + .name = "bar", + .num_values = 1, + .values = &value_2 + } + }; + struct ldb_message in = { + .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), + .num_elements = 2, + .elements = elements, + }; + + assert_non_null(in.dn); + + /* Needed as * implies distinguishedName */ + filtered_msg->dn = in.dn; + + ret = ldb_filter_attrs(ctx->ldb, + &in, + attrs, + filtered_msg); + + /* This does not fail the pidgenhole test */ + assert_int_equal(ret, LDB_SUCCESS); + assert_int_equal(filtered_msg->num_elements, 3); + + /* Assert that DB order is preserved */ + assert_string_equal(filtered_msg->elements[0].name, "bar"); + assert_int_equal(filtered_msg->elements[0].num_values, 1); + assert_int_equal(filtered_msg->elements[0].values[0].length, + sizeof(value1)); + assert_memory_equal(filtered_msg->elements[0].values[0].data, + value1, sizeof(value1)); + assert_string_equal(filtered_msg->elements[1].name, "bar"); + assert_int_equal(filtered_msg->elements[1].num_values, 1); + assert_int_equal(filtered_msg->elements[1].values[0].length, + sizeof(value2)); + assert_memory_equal(filtered_msg->elements[1].values[0].data, + value2, sizeof(value2)); + /* + * assert the ldb_filter_attrs does not modify filtered_msg.dn + * in this case + */ + assert_ptr_equal(filtered_msg->dn, in.dn); + assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, + "distinguishedName", + NULL), + ldb_dn_get_linearized(in.dn)); +} + +/* + * Test against a record with only one attribute, matching the * in + * the list + */ +static void test_filter_attrs_one_attr_matched_star(void **state) +{ + struct ldbtest_ctx *ctx = *state; + int ret; + + struct ldb_message *filtered_msg = ldb_msg_new(ctx); + + const char *attrs[] = {"*", NULL}; + + uint8_t value[] = "The value.......end"; + struct ldb_val value_1 = { + .data = value, + .length = (sizeof(value)) + }; + struct ldb_message_element element_1 = { + .name = "foo", + .num_values = 1, + .values = &value_1 + }; + struct ldb_message in = { + .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), + .num_elements = 1, + .elements = &element_1, + }; + + assert_non_null(in.dn); + + /* Needed as * implies distinguishedName */ + filtered_msg->dn = in.dn; + + ret = ldb_filter_attrs(ctx->ldb, + &in, + attrs, + filtered_msg); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(filtered_msg); + assert_int_equal(filtered_msg->num_elements, 2); + + /* + * assert the ldb_filter_attrs does not modify filtered_msg.dn + * in this case + */ + assert_ptr_equal(filtered_msg->dn, in.dn); + assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, + "distinguishedName", + NULL), + ldb_dn_get_linearized(in.dn)); + assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, + "foo", + NULL), + value); +} + +/* + * Test against a record with two attributes, matching the * in + * the list + */ +static void test_filter_attrs_two_attr_matched_star(void **state) +{ + struct ldbtest_ctx *ctx = *state; + int ret; + + struct ldb_message *filtered_msg = ldb_msg_new(ctx); + + const char *attrs[] = {"*", NULL}; + + uint8_t value1[] = "The value.......end"; + uint8_t value2[] = "The value..MUST.end"; + struct ldb_val value_1 = { + .data = value1, + .length = (sizeof(value1)) + }; + struct ldb_val value_2 = { + .data = value2, + .length = (sizeof(value2)) + }; + struct ldb_message_element elements[] = { + { + .name = "foo", + .num_values = 1, + .values = &value_1 + }, + { + .name = "bar", + .num_values = 1, + .values = &value_2 + } + }; + struct ldb_message in = { + .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), + .num_elements = 2, + .elements = elements, + }; + + assert_non_null(in.dn); + + /* Needed as * implies distinguishedName */ + filtered_msg->dn = in.dn; + + ret = ldb_filter_attrs(ctx->ldb, + &in, + attrs, + filtered_msg); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(filtered_msg); + assert_int_equal(filtered_msg->num_elements, 3); + + /* + * assert the ldb_filter_attrs does not modify filtered_msg.dn + * in this case + */ + assert_ptr_equal(filtered_msg->dn, in.dn); + assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, + "distinguishedName", + NULL), + ldb_dn_get_linearized(in.dn)); + assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, + "foo", + NULL), + value1); + assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, + "bar", + NULL), + value2); +} + +/* + * Test against a record with only one attribute, matching the * in + * the list, but without the DN being pre-filled. Fails due to need + * to contstruct the distinguishedName + */ +static void test_filter_attrs_one_attr_matched_star_no_dn(void **state) +{ + struct ldbtest_ctx *ctx = *state; + int ret; + + struct ldb_message *filtered_msg = ldb_msg_new(ctx); + + const char *attrs[] = {"*", NULL}; + + uint8_t value[] = "The value.......end"; + struct ldb_val value_1 = { + .data = value, + .length = (sizeof(value)) + }; + struct ldb_message_element element_1 = { + .name = "foo", + .num_values = 1, + .values = &value_1 + }; + struct ldb_message in = { + .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), + .num_elements = 1, + .elements = &element_1, + }; + + assert_non_null(in.dn); + + ret = ldb_filter_attrs(ctx->ldb, + &in, + attrs, + filtered_msg); + assert_int_equal(ret, -1); + assert_null(filtered_msg->elements); +} + +/* + * Test against a record with only one attribute, matching the * in + * the list plus requsesting distinguishedName + */ +static void test_filter_attrs_one_attr_matched_star_dn(void **state) +{ + struct ldbtest_ctx *ctx = *state; + int ret; + + struct ldb_message *filtered_msg = ldb_msg_new(ctx); + + const char *attrs[] = {"*", "distinguishedName", NULL}; + + uint8_t value[] = "The value.......end"; + struct ldb_val value_1 = { + .data = value, + .length = (sizeof(value)) + }; + struct ldb_message_element element_1 = { + .name = "foo", + .num_values = 1, + .values = &value_1 + }; + struct ldb_message in = { + .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), + .num_elements = 1, + .elements = &element_1, + }; + + assert_non_null(in.dn); + + /* Needed for distinguishedName */ + filtered_msg->dn = in.dn; + + ret = ldb_filter_attrs(ctx->ldb, + &in, + attrs, + filtered_msg); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(filtered_msg); + assert_int_equal(filtered_msg->num_elements, 2); + + /* show that ldb_filter_attrs does not modify in.dn */ + assert_ptr_equal(filtered_msg->dn, in.dn); + + assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, + "distinguishedName", + NULL), + ldb_dn_get_linearized(in.dn)); + assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, + "foo", + NULL), + value); +} + +/* + * Test against a record with only one attribute, but returning + * distinguishedName from the list (only) + */ +static void test_filter_attrs_one_attr_matched_dn(void **state) +{ + struct ldbtest_ctx *ctx = *state; + int ret; + + struct ldb_message *filtered_msg = ldb_msg_new(ctx); + + const char *attrs[] = {"distinguishedName", NULL}; + + uint8_t value[] = "The value.......end"; + struct ldb_val value_1 = { + .data = value, + .length = (sizeof(value)) + }; + struct ldb_message_element element_1 = { + .name = "foo", + .num_values = 1, + .values = &value_1 + }; + struct ldb_message in = { + .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), + .num_elements = 1, + .elements = &element_1, + }; + + assert_non_null(in.dn); + + /* Needed for distinguishedName */ + filtered_msg->dn = in.dn; + + ret = ldb_filter_attrs(ctx->ldb, + &in, + attrs, + filtered_msg); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(filtered_msg); + assert_int_equal(filtered_msg->num_elements, 1); + + /* show that ldb_filter_attrs does not modify in.dn */ + assert_ptr_equal(filtered_msg->dn, in.dn); + assert_string_equal(filtered_msg->elements[0].name, "distinguishedName"); + assert_int_equal(filtered_msg->elements[0].num_values, 1); + assert_string_equal(filtered_msg->elements[0].values[0].data, + ldb_dn_get_linearized(in.dn)); +} + +/* + * Test against a record with only one attribute, not matching the + * empty attribute list + */ +static void test_filter_attrs_one_attr_empty_list(void **state) +{ + struct ldbtest_ctx *ctx = *state; + int ret; + + struct ldb_message *filtered_msg = ldb_msg_new(ctx); + + const char *attrs[] = {NULL}; + + uint8_t value[] = "The value.......end"; + struct ldb_val value_1 = { + .data = value, + .length = (sizeof(value)) + }; + struct ldb_message_element element_1 = { + .name = "foo", + .num_values = 1, + .values = &value_1 + }; + struct ldb_message in = { + .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), + .num_elements = 1, + .elements = &element_1, + }; + + assert_non_null(in.dn); + + ret = ldb_filter_attrs(ctx->ldb, + &in, + attrs, + filtered_msg); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(filtered_msg); + assert_int_equal(filtered_msg->num_elements, 0); + assert_null(filtered_msg->dn); + assert_null(filtered_msg->elements); +} + +int main(int argc, const char **argv) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown( + test_filter_attrs_one_attr_matched, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_filter_attrs_one_attr_matched_of_many, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_filter_attrs_two_attr_matched_attrs, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_filter_attrs_two_attr_matched_one_attr, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_filter_attrs_two_dup_attr_matched_one_attr, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_filter_attrs_two_dup_attr_matched_dup, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_filter_attrs_two_dup_attr_matched_one_of_two, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_filter_attrs_two_dup_attr_matched_star, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_filter_attrs_one_attr_matched_star, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_filter_attrs_two_attr_matched_star, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_filter_attrs_one_attr_matched_star_no_dn, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_filter_attrs_one_attr_matched_star_dn, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_filter_attrs_one_attr_matched_dn, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_filter_attrs_one_attr_empty_list, + setup, + teardown), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/ldb-2.0.8/tests/ldb_key_value_sub_txn_mdb_test.valgrind b/ldb-2.0.8/tests/ldb_key_value_sub_txn_mdb_test.valgrind new file mode 100644 index 0000000..1747076 --- /dev/null +++ b/ldb-2.0.8/tests/ldb_key_value_sub_txn_mdb_test.valgrind @@ -0,0 +1,97 @@ +{ + Memory allocated by setup + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + ... + fun:setup +} +{ + Memory allocated by setup + Memcheck:Leak + match-leak-kinds: possible + fun:realloc + ... + fun:setup +} +{ + Memory allocated by ldb_init + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + ... + fun:ldb_init +} +{ + Memory allocated by ldb_init + Memcheck:Leak + match-leak-kinds: possible + fun:realloc + ... + fun:ldb_init +} +{ + Memory allocated by noconn_setup + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + ... + fun:noconn_setup +} +{ + Memory allocated by parse, which allocates on the NULL context + Memcheck:Leak + match-leak-kinds: all + fun:malloc + ... + fun:parse +} +{ + Memory allocated by tdb_parse_data + Memcheck:Leak + match-leak-kinds: all + fun:malloc + ... + fun:tdb_parse_data +} +{ + Memory allocated by ldb_connect + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + ... + fun:ldb_connect +} +{ + Memory allocated by ldb_connect + Memcheck:Leak + match-leak-kinds: possible + fun:calloc + ... + fun:ldb_connect +} +{ + Memory allocated by ldb_kv_cache_load + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + ... + fun:ldb_kv_cache_load +} +{ + Memory allocated by ldb_kv_index_load + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + ... + fun:ldb_kv_index_load +} +{ + Memory allocated by ldb_asprintf_errstring + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + ... + fun:ldb_asprintf_errstring +} + diff --git a/ldb-2.0.8/tests/ldb_key_value_sub_txn_test.c b/ldb-2.0.8/tests/ldb_key_value_sub_txn_test.c new file mode 100644 index 0000000..e71f81b --- /dev/null +++ b/ldb-2.0.8/tests/ldb_key_value_sub_txn_test.c @@ -0,0 +1,843 @@ +/* + * Tests exercising the ldb key value operations. + * + * Copyright (C) Andrew Bartlett 2018 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* + * from cmocka.c: + * These headers or their equivalents should be included prior to + * including + * this header file. + * + * #include + * #include + * #include + * + * This allows test applications to use custom definitions of C standard + * library functions and types. + * + */ + +/* + */ +#include +#include +#include +#include + +#include +#define NO_FAILURE INT_MAX +#define FAILURE_LDB_ERR LDB_ERR_OTHER + +/* + * To test failure in ldb_kv_add, ldb_kv_delete, ldb_kv_modify and ldb_kv_rename + * we use the following global variables and macros to trigger a failure in + * the ldb_kv__internal functions. This allows testing of the sub + * transaction commits and roll backs in those operations. + * + * NOTE: Not all back ends support nested/sub transactions + */ +int cmocka_unit_test_fail_add_internal_after = NO_FAILURE; +#define CMOCKA_UNIT_TEST_ADD_INTERNAL_FAIL \ + {\ + cmocka_unit_test_fail_add_internal_after--;\ + if (cmocka_unit_test_fail_add_internal_after <= 0) {\ + assert_int_equal(LDB_SUCCESS, ret);\ + ret = FAILURE_LDB_ERR;\ + }\ + }\ + +int cmocka_unit_test_fail_delete_internal_after = NO_FAILURE; +#define CMOCKA_UNIT_TEST_DELETE_INTERNAL_FAIL \ + {\ + cmocka_unit_test_fail_delete_internal_after--;\ + if (cmocka_unit_test_fail_delete_internal_after <= 0) {\ + assert_int_equal(LDB_SUCCESS, ret);\ + ret = FAILURE_LDB_ERR;\ + }\ + }\ + +int cmocka_unit_test_fail_rename_internal_after = NO_FAILURE; +#define CMOCKA_UNIT_TEST_RENAME_INTERNAL_FAIL \ + {\ + cmocka_unit_test_fail_rename_internal_after--;\ + if (cmocka_unit_test_fail_rename_internal_after <= 0) {\ + assert_int_equal(LDB_SUCCESS, ret);\ + ret = FAILURE_LDB_ERR;\ + }\ + }\ + +int cmocka_unit_test_fail_modify_internal_after = NO_FAILURE; +#define CMOCKA_UNIT_TEST_MODIFY_INTERNAL_FAIL \ + {\ + cmocka_unit_test_fail_modify_internal_after--;\ + if (cmocka_unit_test_fail_modify_internal_after <= 0) {\ + assert_int_equal(LDB_SUCCESS, ret);\ + ret = FAILURE_LDB_ERR;\ + }\ + }\ + +#include "ldb_key_value/ldb_kv.c" + + +#define DEFAULT_BE "tdb" + +#ifndef TEST_BE +#define TEST_BE DEFAULT_BE +#endif /* TEST_BE */ + +#define NUM_RECS 1024 + + +struct test_ctx { + struct tevent_context *ev; + struct ldb_context *ldb; + + const char *dbfile; + const char *lockfile; /* lockfile is separate */ + + const char *dbpath; +}; + +/* + * Remove the database files + */ +static void unlink_old_db(struct test_ctx *test_ctx) +{ + int ret; + + errno = 0; + ret = unlink(test_ctx->lockfile); + if (ret == -1 && errno != ENOENT) { + fail(); + } + + errno = 0; + ret = unlink(test_ctx->dbfile); + if (ret == -1 && errno != ENOENT) { + fail(); + } +} + +/* + * Test setup + */ +static int noconn_setup(void **state) +{ + struct test_ctx *test_ctx; + cmocka_unit_test_fail_add_internal_after = NO_FAILURE; + cmocka_unit_test_fail_delete_internal_after = NO_FAILURE; + cmocka_unit_test_fail_rename_internal_after = NO_FAILURE; + cmocka_unit_test_fail_modify_internal_after = NO_FAILURE; + + test_ctx = talloc_zero(NULL, struct test_ctx); + assert_non_null(test_ctx); + + test_ctx->ev = tevent_context_init(test_ctx); + assert_non_null(test_ctx->ev); + + test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev); + assert_non_null(test_ctx->ldb); + + test_ctx->dbfile = talloc_strdup(test_ctx, "kvopstest.ldb"); + assert_non_null(test_ctx->dbfile); + + test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock", + test_ctx->dbfile); + assert_non_null(test_ctx->lockfile); + + test_ctx->dbpath = talloc_asprintf(test_ctx, + TEST_BE"://%s", test_ctx->dbfile); + assert_non_null(test_ctx->dbpath); + + unlink_old_db(test_ctx); + *state = test_ctx; + return 0; +} + +/* + * Test teardown + */ +static int noconn_teardown(void **state) +{ + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + + unlink_old_db(test_ctx); + talloc_free(test_ctx); + return 0; +} + +/* + * Test setup + */ +static int setup(void **state) +{ + struct test_ctx *test_ctx; + int ret; + struct ldb_ldif *ldif; + const char *index_ldif = \ + "dn: @INDEXLIST\n" + "@IDXGUID: objectUUID\n" + "@IDX_DN_GUID: GUID\n" + "\n"; + + noconn_setup((void **) &test_ctx); + + ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL); + assert_int_equal(ret, 0); + + while ((ldif = ldb_ldif_read_string(test_ctx->ldb, &index_ldif))) { + ret = ldb_add(test_ctx->ldb, ldif->msg); + assert_int_equal(ret, LDB_SUCCESS); + } + *state = test_ctx; + return 0; +} + +/* + * Test teardown + */ +static int teardown(void **state) +{ + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + noconn_teardown((void **) &test_ctx); + return 0; +} + +/* + * Build an ldb_kv_context that can be passed to the ldb_kv operation under test + */ +static struct ldb_kv_context* build_ldb_kv_context( + TALLOC_CTX *ctx, + struct ldb_module *module, + struct ldb_request *req) +{ + struct ldb_kv_context *ldb_kv_ctx = NULL; + + ldb_kv_ctx = talloc_zero(ctx, struct ldb_kv_context); + assert_non_null(ldb_kv_ctx); + + ldb_kv_ctx->module = module; + ldb_kv_ctx->req = req; + + return ldb_kv_ctx; +} + +/* + * Build an add request + */ +static struct ldb_request *build_add_request( + TALLOC_CTX *ctx, + struct ldb_context *ldb, + const char* dc, + const char* uuid, + const char* cn) +{ + int ret; + struct ldb_message *msg; + struct ldb_request *req; + + msg = ldb_msg_new(ctx); + assert_non_null(msg); + + msg->dn = ldb_dn_new_fmt(msg, ldb, "dc=%s", dc); + assert_non_null(msg->dn); + + ret = ldb_msg_add_string(msg, "cn", cn); + assert_int_equal(ret, 0); + + ret = ldb_msg_add_string(msg, "objectUUID", uuid); + assert_int_equal(ret, 0); + + ret = ldb_msg_sanity_check(ldb, msg); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_build_add_req( + &req, ldb, ldb, msg, NULL, NULL, ldb_op_default_callback, NULL); + assert_int_equal(ret, LDB_SUCCESS); + return req; +} + +/* + * Build a delete request + */ +static struct ldb_request *build_delete_request( + TALLOC_CTX *ctx, + struct ldb_context *ldb, + const char* dc) +{ + int ret = LDB_SUCCESS; + struct ldb_dn *dn = NULL; + struct ldb_request *req = NULL; + + dn = ldb_dn_new_fmt(ctx, ldb, "dc=%s", dc); + assert_non_null(dn); + + ret = ldb_build_del_req( + &req, ldb, ctx, dn, NULL, NULL, ldb_op_default_callback, NULL); + assert_int_equal(ret, LDB_SUCCESS); + return req; +} + +/* + * Build a rename request + */ +static struct ldb_request *build_rename_request( + TALLOC_CTX *ctx, + struct ldb_context *ldb, + const char* old_dc, + const char* new_dc) +{ + int ret = LDB_SUCCESS; + struct ldb_dn *old_dn = NULL; + struct ldb_dn *new_dn = NULL; + struct ldb_request *req = NULL; + + old_dn = ldb_dn_new_fmt(ctx, ldb, "dc=%s", old_dc); + assert_non_null(old_dn); + + new_dn = ldb_dn_new_fmt(ctx, ldb, "dc=%s", new_dc); + assert_non_null(new_dn); + + ret = ldb_build_rename_req( + &req, + ldb, + ctx, + old_dn, + new_dn, + NULL, + NULL, + ldb_op_default_callback, + NULL); + assert_int_equal(ret, LDB_SUCCESS); + return req; +} + +/* + * Build a ldb modify request + */ +static struct ldb_request *build_modify_request( + TALLOC_CTX *ctx, + struct ldb_context *ldb, + const char* dc, + const char* cn) +{ + int ret; + struct ldb_message *msg; + struct ldb_request *req; + + msg = ldb_msg_new(ctx); + assert_non_null(msg); + + msg->dn = ldb_dn_new_fmt(msg, ldb, "dc=%s", dc); + assert_non_null(msg->dn); + + ret = ldb_msg_add_empty(msg, "cn", LDB_FLAG_MOD_REPLACE, NULL); + assert_int_equal(ret, LDB_SUCCESS); + ret = ldb_msg_add_string(msg, "cn", cn); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_msg_sanity_check(ldb, msg); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_build_mod_req( + &req, ldb, ldb, msg, NULL, NULL, ldb_op_default_callback, NULL); + assert_int_equal(ret, LDB_SUCCESS); + return req; +} + +/* + * Delete a record from the database + */ +static void delete_record( + TALLOC_CTX *ctx, + struct ldb_context *ldb, + const char* dc) +{ + struct ldb_kv_context *ldb_kv_ctx = NULL; + struct ldb_dn *basedn = NULL; + struct ldb_result *result = NULL; + struct ldb_request *req = NULL; + int ret = LDB_SUCCESS; + + req = build_delete_request(ctx, ldb, dc); + ldb_kv_ctx = build_ldb_kv_context(ctx, ldb->modules, req); + + ret = ldb_transaction_start(ldb); + assert_int_equal(ret, LDB_SUCCESS); + + cmocka_unit_test_fail_delete_internal_after = NO_FAILURE; + cmocka_unit_test_fail_modify_internal_after = NO_FAILURE; + ret = ldb_kv_delete(ldb_kv_ctx); + assert_int_equal(ret, LDB_SUCCESS); + TALLOC_FREE(ldb_kv_ctx); + TALLOC_FREE(req); + + ret = ldb_transaction_commit(ldb); + assert_int_equal(ret, LDB_SUCCESS); + + /* + * Ensure that the record was actually deleted. + */ + basedn = ldb_dn_new_fmt(ctx, ldb, "dc=%s", dc); + assert_non_null(basedn); + + /* + * DN search, indexed + */ + ret = ldb_search(ldb, ctx, &result, basedn, LDB_SCOPE_BASE, NULL, NULL); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(result); + assert_int_equal(result->count, 0); + TALLOC_FREE(basedn); + TALLOC_FREE(result); +} + +/* + * Add a record to the database + */ +static void add_record( + TALLOC_CTX *ctx, + struct ldb_context *ldb, + const char* dc, + const char* uuid, + const char* cn) +{ + + struct ldb_request *req = NULL; + int ret = LDB_SUCCESS; + struct ldb_kv_context *ldb_kv_ctx = NULL; + struct ldb_dn *basedn = NULL; + struct ldb_result *result = NULL; + + req = build_add_request(ctx, ldb, dc, uuid, cn); + + ldb_req_set_location(req, "add_record"); + + assert_int_equal(ret, LDB_SUCCESS); + + + ldb_kv_ctx = build_ldb_kv_context(ctx, ldb->modules, req); + cmocka_unit_test_fail_add_internal_after = NO_FAILURE; + cmocka_unit_test_fail_modify_internal_after = NO_FAILURE; + + ret = ldb_transaction_start(ldb); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_kv_add(ldb_kv_ctx); + assert_int_equal(ret, LDB_SUCCESS); + TALLOC_FREE(ldb_kv_ctx); + TALLOC_FREE(req); + + ret = ldb_transaction_commit(ldb); + assert_int_equal(ret, LDB_SUCCESS); + + /* + * Ensure that the record was actually written. + */ + basedn = ldb_dn_new_fmt(ctx, ldb, "dc=%s", dc); + assert_non_null(basedn); + + /* + * DN search, indexed + */ + ret = ldb_search(ldb, ctx, &result, basedn, LDB_SCOPE_BASE, NULL, NULL); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(result); + assert_int_equal(result->count, 1); + TALLOC_FREE(result); + + + /* + * CN search unindexed + */ + ret = ldb_search( + ldb, + ctx, + &result, + basedn, + LDB_SCOPE_SUBTREE, + NULL, + "(cn=%s)", + cn); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(result); + assert_int_equal(result->count, 1); + TALLOC_FREE(result); + TALLOC_FREE(basedn); +} + +/* + * Test that a failed add operation does not change the database. + */ +static void test_add_failure(void **state) +{ + int ret = LDB_SUCCESS; + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + struct ldb_request *req = NULL; + struct ldb_dn *basedn = NULL; + struct ldb_result *result = NULL; + struct ldb_kv_context *ldb_kv_ctx = NULL; + + TALLOC_CTX *tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + req = build_add_request( + tmp_ctx, + test_ctx->ldb, + "test_add_failure", + "0123456789abcdef", + "test_add_failure_value"); + + ldb_req_set_location(req, "test_add_failure"); + + ldb_kv_ctx = build_ldb_kv_context(tmp_ctx, test_ctx->ldb->modules, req); + cmocka_unit_test_fail_add_internal_after = 1; + + ret = ldb_transaction_start(test_ctx->ldb); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_kv_add(ldb_kv_ctx); + + assert_int_equal(ret, FAILURE_LDB_ERR); + TALLOC_FREE(ldb_kv_ctx); + TALLOC_FREE(req); + + + /* + * a search for "cn=test_add_failure_value" should fail + * as the transaction containing the operation should have been + * rolled back leaving the database consistent + * + * This should be an un-indexed search so the index caches won't be + * used. + */ + basedn = ldb_dn_new_fmt( + tmp_ctx, + test_ctx->ldb, + "dc=%s", + "test_add_failure"); + assert_non_null(basedn); + + ret = ldb_search( + test_ctx->ldb, tmp_ctx, + &result, + basedn, + LDB_SCOPE_SUBTREE, + NULL, + "(cn=%s)", + "test_add_failure_value"); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(result); + assert_int_equal(result->count, 0); + TALLOC_FREE(basedn); + TALLOC_FREE(result); + + ldb_transaction_cancel(test_ctx->ldb); + TALLOC_FREE(tmp_ctx); +} + + +/* + * Test that a failed delete operation does not modify the database. + */ +static void test_delete_failure(void **state) +{ + int ret = LDB_SUCCESS; + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + struct ldb_request *req = NULL; + struct ldb_dn *basedn = NULL; + struct ldb_result *result = NULL; + struct ldb_kv_context *ldb_kv_ctx = NULL; + + TALLOC_CTX *tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + add_record( + tmp_ctx, + test_ctx->ldb, + "test_delete_failure", + "0123456789abcded", + "test_delete_failure_value"); + + req = build_delete_request( + tmp_ctx, + test_ctx->ldb, + "test_delete_failure"); + + ldb_kv_ctx = build_ldb_kv_context(tmp_ctx, test_ctx->ldb->modules, req); + cmocka_unit_test_fail_delete_internal_after = 1; + + ret = ldb_transaction_start(test_ctx->ldb); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_kv_delete(ldb_kv_ctx); + assert_int_equal(ret, FAILURE_LDB_ERR); + TALLOC_FREE(ldb_kv_ctx); + TALLOC_FREE(req); + + /* + * a search for "cn=test_add_failure_value" should succeed + * as the transaction containing the operation should have been + * rolled back leaving the database consistent + * + * This should be an un-indexed search so the index caches won't be + * used. + */ + basedn = ldb_dn_new_fmt( + tmp_ctx, + test_ctx->ldb, + "dc=%s", + "test_delete_failure"); + assert_non_null(basedn); + + ret = ldb_search( + test_ctx->ldb, tmp_ctx, + &result, + basedn, + LDB_SCOPE_SUBTREE, + NULL, + "(cn=%s)", + "test_delete_failure_value"); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(result); + assert_int_equal(result->count, 1); + TALLOC_FREE(basedn); + TALLOC_FREE(result); + + + ldb_transaction_cancel(test_ctx->ldb); + delete_record( + tmp_ctx, + test_ctx->ldb, + "test_delete_failure"); + TALLOC_FREE(tmp_ctx); +} + +/* + * Test that a failed rename operation dies not change the database + */ +static void test_rename_failure(void **state) +{ + int ret = LDB_SUCCESS; + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + struct ldb_request *req = NULL; + struct ldb_dn *basedn = NULL; + struct ldb_result *result = NULL; + struct ldb_kv_context *ldb_kv_ctx = NULL; + + TALLOC_CTX *tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + add_record( + tmp_ctx, + test_ctx->ldb, + "test_rename_failure", + "0123456789abcdec", + "test_rename_failure_value"); + + req = build_rename_request( + tmp_ctx, + test_ctx->ldb, + "test_rename_failure", + "test_rename_failure_renamed"); + + ldb_kv_ctx = build_ldb_kv_context(tmp_ctx, test_ctx->ldb->modules, req); + cmocka_unit_test_fail_rename_internal_after = 1; + + ret = ldb_transaction_start(test_ctx->ldb); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_kv_rename(ldb_kv_ctx); + assert_int_equal(ret, FAILURE_LDB_ERR); + TALLOC_FREE(ldb_kv_ctx); + TALLOC_FREE(req); + + /* + * The original record should be present + */ + basedn = ldb_dn_new_fmt( + tmp_ctx, + test_ctx->ldb, + "dc=%s", + "test_rename_failure"); + assert_non_null(basedn); + + ret = ldb_search( + test_ctx->ldb, tmp_ctx, + &result, + basedn, + LDB_SCOPE_SUBTREE, + NULL, + "(cn=%s)", + "test_rename_failure_value"); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(result); + assert_int_equal(result->count, 1); + TALLOC_FREE(basedn); + TALLOC_FREE(result); + + /* + * And the renamed record should not be present + */ + basedn = ldb_dn_new_fmt( + tmp_ctx, + test_ctx->ldb, + "dc=%s", + "test_rename_failure_renamed"); + assert_non_null(basedn); + + ret = ldb_search( + test_ctx->ldb, tmp_ctx, + &result, + basedn, + LDB_SCOPE_SUBTREE, + NULL, + "(cn=%s)", + "test_rename_failure_value"); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(result); + assert_int_equal(result->count, 0); + TALLOC_FREE(basedn); + TALLOC_FREE(result); + + ldb_transaction_cancel(test_ctx->ldb); + delete_record( + tmp_ctx, + test_ctx->ldb, + "test_rename_failure"); + TALLOC_FREE(tmp_ctx); +} + +/* + * Test that a failed modification operation does not change the database + */ +static void test_modify_failure(void **state) +{ + int ret = LDB_SUCCESS; + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + struct ldb_request *req = NULL; + struct ldb_dn *basedn = NULL; + struct ldb_result *result = NULL; + struct ldb_kv_context *ldb_kv_ctx = NULL; + + TALLOC_CTX *tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + add_record( + tmp_ctx, + test_ctx->ldb, + "test_modify_failure", + "0123456789abcdeb", + "test_modify_failure_value"); + + req = build_modify_request( + tmp_ctx, + test_ctx->ldb, + "test_modify_failure", + "test_modify_failure_value_modified"); + + ldb_kv_ctx = build_ldb_kv_context(tmp_ctx, test_ctx->ldb->modules, req); + cmocka_unit_test_fail_modify_internal_after = 2; + + ret = ldb_transaction_start(test_ctx->ldb); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_kv_modify(ldb_kv_ctx); + assert_int_equal(ret, FAILURE_LDB_ERR); + TALLOC_FREE(ldb_kv_ctx); + TALLOC_FREE(req); + + + /* + * The original value should be present + */ + basedn = ldb_dn_new_fmt( + tmp_ctx, + test_ctx->ldb, + "dc=%s", + "test_modify_failure"); + assert_non_null(basedn); + + ret = ldb_search( + test_ctx->ldb, tmp_ctx, + &result, + basedn, + LDB_SCOPE_SUBTREE, + NULL, + "(cn=%s)", + "test_modify_failure_value"); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(result); + assert_int_equal(result->count, 1); + TALLOC_FREE(result); + + /* + * And the modified record should not be present + */ + ret = ldb_search( + test_ctx->ldb, tmp_ctx, + &result, + basedn, + LDB_SCOPE_SUBTREE, + NULL, + "(cn=%s)", + "test_modify_failure_value_modified"); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(result); + assert_int_equal(result->count, 0); + TALLOC_FREE(basedn); + TALLOC_FREE(result); + + ldb_transaction_cancel(test_ctx->ldb); + delete_record( + tmp_ctx, + test_ctx->ldb, + "test_modify_failure"); + TALLOC_FREE(tmp_ctx); +} + +int main(int argc, const char **argv) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown( + test_add_failure, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_delete_failure, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_rename_failure, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_modify_failure, + setup, + teardown), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/ldb-2.0.8/tests/ldb_key_value_test.c b/ldb-2.0.8/tests/ldb_key_value_test.c new file mode 100644 index 0000000..3f31bb9 --- /dev/null +++ b/ldb-2.0.8/tests/ldb_key_value_test.c @@ -0,0 +1,388 @@ +/* + * Tests exercising the ldb key value operations. + * + * Copyright (C) Andrew Bartlett 2019 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* + * from cmocka.c: + * These headers or their equivalents should be included prior to + * including + * this header file. + * + * #include + * #include + * #include + * + * This allows test applications to use custom definitions of C standard + * library functions and types. + * + */ + +/* + * + * Tests for the ldb key value layer + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "ldb_key_value/ldb_kv.c" +#include "ldb_key_value/ldb_kv_index.c" +#include "ldb_key_value/ldb_kv_search.c" + +#define DEFAULT_BE "tdb" + +#ifndef TEST_BE +#define TEST_BE DEFAULT_BE +#endif /* TEST_BE */ + +#define NUM_RECS 1024 +int ldb_kv_cache_reload(struct ldb_module *module) { + return LDB_SUCCESS; +} +int ldb_kv_cache_load(struct ldb_module *module) { + return LDB_SUCCESS; +} +int ldb_kv_check_at_attributes_values(const struct ldb_val *value) { + return LDB_SUCCESS; +} +int ldb_kv_increase_sequence_number(struct ldb_module *module) { + return LDB_SUCCESS; +} + +struct test_ctx { +}; + +static int setup(void **state) +{ + struct test_ctx *test_ctx; + + test_ctx = talloc_zero(NULL, struct test_ctx); + *state = test_ctx; + return 0; +} + +static int teardown(void **state) +{ + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + + talloc_free(test_ctx); + return 0; +} + +/* + * Test that the index cache is opened by ldb_kv_index_transaction_start + * and correctly initialised with the passed index cache size. + */ +static void test_index_cache_init(void **state) +{ + struct test_ctx *test_ctx = talloc_get_type_abort( + *state, + struct test_ctx); + struct ldb_module *module = NULL; + struct ldb_kv_private *ldb_kv = NULL; + int ret = LDB_SUCCESS; + + module = talloc_zero(test_ctx, struct ldb_module); + ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private); + ldb_module_set_private(module, ldb_kv); + + ret = ldb_kv_index_transaction_start(module, 191); + assert_int_equal(LDB_SUCCESS, ret); + + assert_non_null(ldb_kv->idxptr); + assert_non_null(ldb_kv->idxptr->itdb); + assert_int_equal(191, tdb_hash_size(ldb_kv->idxptr->itdb)); + + TALLOC_FREE(ldb_kv); + TALLOC_FREE(module); +} + +static int mock_begin_write(struct ldb_kv_private* ldb_kv) { + return LDB_SUCCESS; +} +static int mock_abort_write(struct ldb_kv_private* ldb_kv) { + return LDB_SUCCESS; +} + +/* + * Test that the index cache is set to the default cache size at the start of + * a transaction. + */ +static void test_default_index_cache_size(void **state) +{ + struct test_ctx *test_ctx = talloc_get_type_abort( + *state, + struct test_ctx); + struct ldb_module *module = NULL; + struct ldb_kv_private *ldb_kv = NULL; + int ret = LDB_SUCCESS; + const struct kv_db_ops ops = { + .begin_write = mock_begin_write, + .abort_write = mock_abort_write + }; + + module = talloc_zero(test_ctx, struct ldb_module); + ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private); + ldb_kv->pid = getpid(); + ldb_kv->kv_ops = &ops; + ldb_kv->index_transaction_cache_size = DEFAULT_INDEX_CACHE_SIZE; + ldb_module_set_private(module, ldb_kv); + + ret = ldb_kv_start_trans(module); + assert_int_equal(LDB_SUCCESS, ret); + + assert_int_equal( + DEFAULT_INDEX_CACHE_SIZE, + tdb_hash_size(ldb_kv->idxptr->itdb)); + + ret = ldb_kv_del_trans(module); + assert_int_equal(LDB_SUCCESS, ret); + + TALLOC_FREE(ldb_kv); + TALLOC_FREE(module); +} + +static int db_size = 0; +static size_t mock_get_size(struct ldb_kv_private *ldb_kv) { + return db_size; +} + +static int mock_iterate( + struct ldb_kv_private *ldb_kv, + ldb_kv_traverse_fn fn, + void *ctx) { + return 1; +} + +/* + * Test that the index cache is correctly sized by the re_index call + */ +static void test_reindex_cache_size(void **state) +{ + struct test_ctx *test_ctx = talloc_get_type_abort( + *state, + struct test_ctx); + struct ldb_module *module = NULL; + struct ldb_kv_private *ldb_kv = NULL; + int ret = LDB_SUCCESS; + const struct kv_db_ops ops = { + .iterate = mock_iterate, + .get_size = mock_get_size, + }; + + module = talloc_zero(test_ctx, struct ldb_module); + ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private); + ldb_kv->kv_ops = &ops; + ldb_module_set_private(module, ldb_kv); + + /* + * Use a value less than the DEFAULT_INDEX_CACHE_SIZE + * Should get the DEFAULT_INDEX_CACHE_SIZE + */ + db_size = DEFAULT_INDEX_CACHE_SIZE - 1; + ret = ldb_kv_reindex(module); + assert_int_equal(LDB_SUCCESS, ret); + + assert_int_equal( + DEFAULT_INDEX_CACHE_SIZE, + tdb_hash_size(ldb_kv->idxptr->itdb)); + + /* + * Use a value greater than the DEFAULT_INDEX_CACHE_SIZE + * Should get the value specified. + */ + db_size = DEFAULT_INDEX_CACHE_SIZE + 1; + ret = ldb_kv_reindex(module); + assert_int_equal(LDB_SUCCESS, ret); + + assert_int_equal(db_size, tdb_hash_size(ldb_kv->idxptr->itdb)); + + TALLOC_FREE(ldb_kv); + TALLOC_FREE(module); +} + +/* + * Test that ldb_kv_init_store sets the default index transaction cache size + * if the option is not supplied. + */ +static void test_init_store_default_index_cache_size(void **state) +{ + struct test_ctx *test_ctx = talloc_get_type_abort( + *state, + struct test_ctx); + struct ldb_module *module = NULL; + struct ldb_kv_private *ldb_kv = NULL; + struct ldb_context *ldb = NULL; + int ret = LDB_SUCCESS; + + module = talloc_zero(test_ctx, struct ldb_module); + ldb = talloc_zero(test_ctx, struct ldb_context); + ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private); + + ret = ldb_kv_init_store(ldb_kv, "test", ldb, NULL, &module); + assert_int_equal(LDB_SUCCESS, ret); + + assert_int_equal( + DEFAULT_INDEX_CACHE_SIZE, + ldb_kv->index_transaction_cache_size); + + TALLOC_FREE(ldb_kv); + TALLOC_FREE(module); + TALLOC_FREE(ldb); +} + +/* + * Test that ldb_kv_init_store sets the index transaction cache size + * to the value specified in the option. + */ +static void test_init_store_set_index_cache_size(void **state) +{ + struct test_ctx *test_ctx = talloc_get_type_abort( + *state, + struct test_ctx); + struct ldb_module *module = NULL; + struct ldb_kv_private *ldb_kv = NULL; + struct ldb_context *ldb = NULL; + const char *options[] = {"transaction_index_cache_size:1900", NULL}; + int ret = LDB_SUCCESS; + + module = talloc_zero(test_ctx, struct ldb_module); + ldb = talloc_zero(test_ctx, struct ldb_context); + ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private); + + ret = ldb_kv_init_store(ldb_kv, "test", ldb, options, &module); + assert_int_equal(LDB_SUCCESS, ret); + + assert_int_equal( 1900, ldb_kv->index_transaction_cache_size); + + TALLOC_FREE(ldb_kv); + TALLOC_FREE(module); + TALLOC_FREE(ldb); +} + +/* + * Test that ldb_kv_init_store sets the default index transaction cache size + * if the value specified in the option is not a number. + */ +static void test_init_store_set_index_cache_size_non_numeric(void **state) +{ + struct test_ctx *test_ctx = talloc_get_type_abort( + *state, + struct test_ctx); + struct ldb_module *module = NULL; + struct ldb_kv_private *ldb_kv = NULL; + struct ldb_context *ldb = NULL; + const char *options[] = {"transaction_index_cache_size:fred", NULL}; + int ret = LDB_SUCCESS; + + module = talloc_zero(test_ctx, struct ldb_module); + ldb = talloc_zero(test_ctx, struct ldb_context); + ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private); + + ret = ldb_kv_init_store(ldb_kv, "test", ldb, options, &module); + assert_int_equal(LDB_SUCCESS, ret); + + assert_int_equal( + DEFAULT_INDEX_CACHE_SIZE, + ldb_kv->index_transaction_cache_size); + + TALLOC_FREE(ldb_kv); + TALLOC_FREE(module); + TALLOC_FREE(ldb); +} + +/* + * Test that ldb_kv_init_store sets the default index transaction cache size + * if the value specified is too large + */ +static void test_init_store_set_index_cache_size_range(void **state) +{ + struct test_ctx *test_ctx = talloc_get_type_abort( + *state, + struct test_ctx); + struct ldb_module *module = NULL; + struct ldb_kv_private *ldb_kv = NULL; + struct ldb_context *ldb = NULL; + const char *options[] = { + "transaction_index_cache_size:0xfffffffffffffffffffffffffffff", + NULL}; + int ret = LDB_SUCCESS; + + module = talloc_zero(test_ctx, struct ldb_module); + ldb = talloc_zero(test_ctx, struct ldb_context); + ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private); + + ret = ldb_kv_init_store(ldb_kv, "test", ldb, options, &module); + assert_int_equal(LDB_SUCCESS, ret); + + assert_int_equal( + DEFAULT_INDEX_CACHE_SIZE, + ldb_kv->index_transaction_cache_size); + + TALLOC_FREE(ldb_kv); + TALLOC_FREE(module); + TALLOC_FREE(ldb); +} + +int main(int argc, const char **argv) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown( + test_index_cache_init, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_default_index_cache_size, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_reindex_cache_size, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_init_store_default_index_cache_size, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_init_store_set_index_cache_size, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_init_store_set_index_cache_size_non_numeric, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_init_store_set_index_cache_size_range, + setup, + teardown), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/ldb-2.0.8/tests/ldb_kv_ops_test.c b/ldb-2.0.8/tests/ldb_kv_ops_test.c new file mode 100644 index 0000000..98b5a43 --- /dev/null +++ b/ldb-2.0.8/tests/ldb_kv_ops_test.c @@ -0,0 +1,1804 @@ +/* + * Tests exercising the ldb key value operations. + * + * Copyright (C) Andrew Bartlett 2018 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* + * from cmocka.c: + * These headers or their equivalents should be included prior to + * including + * this header file. + * + * #include + * #include + * #include + * + * This allows test applications to use custom definitions of C standard + * library functions and types. + * + */ + +/* + * A KV module is expected to have the following behaviour + * + * - A transaction must be open to perform any read, write or delete operation + * - Writes and Deletes should not be visible until a transaction is commited + * - Nested transactions are not permitted + * - transactions can be rolled back and commited. + * - supports iteration over all records in the database + * - supports the update_in_iterate operation allowing entries to be + * re-keyed. + * - has a get_size implementation that returns an estimate of the number of + * records in the database. Note that this can be an estimate rather than + * an accurate size. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ldb_tdb/ldb_tdb.h" +#include "ldb_key_value/ldb_kv.h" + + +#define DEFAULT_BE "tdb" + +#ifndef TEST_BE +#define TEST_BE DEFAULT_BE +#endif /* TEST_BE */ + +#define NUM_RECS 1024 + + +struct test_ctx { + struct tevent_context *ev; + struct ldb_context *ldb; + + const char *dbfile; + const char *lockfile; /* lockfile is separate */ + + const char *dbpath; +}; + +static void unlink_old_db(struct test_ctx *test_ctx) +{ + int ret; + + errno = 0; + ret = unlink(test_ctx->lockfile); + if (ret == -1 && errno != ENOENT) { + fail(); + } + + errno = 0; + ret = unlink(test_ctx->dbfile); + if (ret == -1 && errno != ENOENT) { + fail(); + } +} + +static int noconn_setup(void **state) +{ + struct test_ctx *test_ctx; + + test_ctx = talloc_zero(NULL, struct test_ctx); + assert_non_null(test_ctx); + + test_ctx->ev = tevent_context_init(test_ctx); + assert_non_null(test_ctx->ev); + + test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev); + assert_non_null(test_ctx->ldb); + + test_ctx->dbfile = talloc_strdup(test_ctx, "kvopstest.ldb"); + assert_non_null(test_ctx->dbfile); + + test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock", + test_ctx->dbfile); + assert_non_null(test_ctx->lockfile); + + test_ctx->dbpath = talloc_asprintf(test_ctx, + TEST_BE"://%s", test_ctx->dbfile); + assert_non_null(test_ctx->dbpath); + + unlink_old_db(test_ctx); + *state = test_ctx; + return 0; +} + +static int noconn_teardown(void **state) +{ + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + + unlink_old_db(test_ctx); + talloc_free(test_ctx); + return 0; +} + +static int setup(void **state) +{ + struct test_ctx *test_ctx; + int ret; + struct ldb_ldif *ldif; + const char *index_ldif = \ + "dn: @INDEXLIST\n" + "@IDXGUID: objectUUID\n" + "@IDX_DN_GUID: GUID\n" + "\n"; + + noconn_setup((void **) &test_ctx); + + ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL); + assert_int_equal(ret, 0); + + while ((ldif = ldb_ldif_read_string(test_ctx->ldb, &index_ldif))) { + ret = ldb_add(test_ctx->ldb, ldif->msg); + assert_int_equal(ret, LDB_SUCCESS); + } + *state = test_ctx; + return 0; +} + +static int teardown(void **state) +{ + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + noconn_teardown((void **) &test_ctx); + return 0; +} + +static struct ldb_kv_private *get_ldb_kv(struct ldb_context *ldb) +{ + void *data = NULL; + struct ldb_kv_private *ldb_kv = NULL; + + data = ldb_module_get_private(ldb->modules); + assert_non_null(data); + + ldb_kv = talloc_get_type(data, struct ldb_kv_private); + assert_non_null(ldb_kv); + + return ldb_kv; +} + +static int parse(struct ldb_val key, + struct ldb_val data, + void *private_data) +{ + struct ldb_val* read = private_data; + + /* Yes, we leak this. That is OK */ + read->data = talloc_size(NULL, + data.length); + assert_non_null(read->data); + + memcpy(read->data, data.data, data.length); + read->length = data.length; + return LDB_SUCCESS; +} + +/* + * Parse function that just returns the int we pass it. + */ +static int parse_return(struct ldb_val key, + struct ldb_val data, + void *private_data) +{ + int *rcode = private_data; + return *rcode; +} + +/* + * Test that data can be written to the kv store and be read back. + */ +static void test_add_get(void **state) +{ + int ret; + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); + uint8_t key_val[] = "TheKey"; + struct ldb_val key = { + .data = key_val, + .length = sizeof(key_val) + }; + + uint8_t value[] = "The record contents"; + struct ldb_val data = { + .data = value, + .length = sizeof(value) + }; + + struct ldb_val read; + int rcode; + + int flags = 0; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + /* + * Begin a transaction + */ + ret = ldb_kv->kv_ops->begin_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * Write the record + */ + ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); + assert_int_equal(ret, 0); + + /* + * Commit the transaction + */ + ret = ldb_kv->kv_ops->finish_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * And now read it back + */ + ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); + assert_int_equal(ret, 0); + + ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); + assert_int_equal(ret, 0); + + assert_int_equal(sizeof(value), read.length); + assert_memory_equal(value, read.data, sizeof(value)); + + /* + * Now check that the error code we return in the + * parse function is returned by fetch_and_parse. + */ + for (rcode=0; rcode<50; rcode++) { + ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, + parse_return, + &rcode); + assert_int_equal(ret, rcode); + } + + ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); + assert_int_equal(ret, 0); + talloc_free(tmp_ctx); +} + +/* + * Test that attempts to read data without a read transaction fail. + */ +static void test_read_outside_transaction(void **state) +{ + int ret; + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); + uint8_t key_val[] = "TheKey"; + struct ldb_val key = { + .data = key_val, + .length = sizeof(key_val) + }; + + uint8_t value[] = "The record contents"; + struct ldb_val data = { + .data = value, + .length = sizeof(value) + }; + + struct ldb_val read; + + int flags = 0; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + /* + * Begin a transaction + */ + ret = ldb_kv->kv_ops->begin_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * Write the record + */ + ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); + assert_int_equal(ret, 0); + + /* + * Commit the transaction + */ + ret = ldb_kv->kv_ops->finish_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * And now read it back + * Note there is no read transaction active + */ + ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); + assert_int_equal(ret, LDB_ERR_PROTOCOL_ERROR); + + talloc_free(tmp_ctx); +} + +/* + * Test that data can be deleted from the kv store + */ +static void test_delete(void **state) +{ + int ret; + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); + uint8_t key_val[] = "TheKey"; + struct ldb_val key = { + .data = key_val, + .length = sizeof(key_val) + }; + + uint8_t value[] = "The record contents"; + struct ldb_val data = { + .data = value, + .length = sizeof(value) + }; + + struct ldb_val read; + + int flags = 0; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + /* + * Begin a transaction + */ + ret = ldb_kv->kv_ops->begin_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * Write the record + */ + ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); + assert_int_equal(ret, 0); + + /* + * Commit the transaction + */ + ret = ldb_kv->kv_ops->finish_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * And now read it back + */ + ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); + assert_int_equal(ret, 0); + ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); + assert_int_equal(ret, 0); + assert_int_equal(sizeof(value), read.length); + assert_memory_equal(value, read.data, sizeof(value)); + ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); + assert_int_equal(ret, 0); + + /* + * Begin a transaction + */ + ret = ldb_kv->kv_ops->begin_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * Now delete it. + */ + ret = ldb_kv->kv_ops->delete (ldb_kv, key); + assert_int_equal(ret, 0); + + /* + * Commit the transaction + */ + ret = ldb_kv->kv_ops->finish_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * And now try to read it back + */ + ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); + assert_int_equal(ret, 0); + ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); + assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT); + ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); + assert_int_equal(ret, 0); + + talloc_free(tmp_ctx); +} + +/* + * Check that writes are correctly rolled back when a transaction + * is rolled back. + */ +static void test_transaction_abort_write(void **state) +{ + int ret; + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); + uint8_t key_val[] = "TheKey"; + struct ldb_val key = { + .data = key_val, + .length = sizeof(key_val) + }; + + uint8_t value[] = "The record contents"; + struct ldb_val data = { + .data = value, + .length = sizeof(value) + }; + + struct ldb_val read; + + int flags = 0; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + /* + * Begin a transaction + */ + ret = ldb_kv->kv_ops->begin_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * Write the record + */ + ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); + assert_int_equal(ret, 0); + + /* + * And now read it back + */ + ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); + assert_int_equal(ret, 0); + assert_int_equal(sizeof(value), read.length); + assert_memory_equal(value, read.data, sizeof(value)); + + + /* + * Now abort the transaction + */ + ret = ldb_kv->kv_ops->abort_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * And now read it back, should not be there + */ + ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); + assert_int_equal(ret, 0); + ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); + assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT); + ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); + assert_int_equal(ret, 0); + + talloc_free(tmp_ctx); +} + +/* + * Check that deletes are correctly rolled back when a transaction is + * aborted. + */ +static void test_transaction_abort_delete(void **state) +{ + int ret; + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); + uint8_t key_val[] = "TheKey"; + struct ldb_val key = { + .data = key_val, + .length = sizeof(key_val) + }; + + uint8_t value[] = "The record contents"; + struct ldb_val data = { + .data = value, + .length = sizeof(value) + }; + + struct ldb_val read; + + int flags = 0; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + /* + * Begin a transaction + */ + ret = ldb_kv->kv_ops->begin_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * Write the record + */ + ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); + assert_int_equal(ret, 0); + + /* + * Commit the transaction + */ + ret = ldb_kv->kv_ops->finish_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * And now read it back + */ + ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); + assert_int_equal(ret, 0); + ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); + assert_int_equal(ret, 0); + assert_int_equal(sizeof(value), read.length); + assert_memory_equal(value, read.data, sizeof(value)); + ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); + assert_int_equal(ret, 0); + + /* + * Begin a transaction + */ + ret = ldb_kv->kv_ops->begin_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * Now delete it. + */ + ret = ldb_kv->kv_ops->delete (ldb_kv, key); + assert_int_equal(ret, 0); + + /* + * And now read it back + */ + ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); + assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT); + + /* + * Abort the transaction + */ + ret = ldb_kv->kv_ops->abort_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * And now try to read it back + */ + ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); + assert_int_equal(ret, 0); + ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); + assert_int_equal(ret, 0); + assert_int_equal(sizeof(value), read.length); + assert_memory_equal(value, read.data, sizeof(value)); + ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); + assert_int_equal(ret, 0); + + talloc_free(tmp_ctx); +} + +/* + * Test that writes outside a transaction fail + */ +static void test_write_outside_transaction(void **state) +{ + int ret; + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); + uint8_t key_val[] = "TheKey"; + struct ldb_val key = { + .data = key_val, + .length = sizeof(key_val) + }; + + uint8_t value[] = "The record contents"; + struct ldb_val data = { + .data = value, + .length = sizeof(value) + }; + + + int flags = 0; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + /* + * Attempt to write the record + */ + ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); + assert_int_equal(ret, LDB_ERR_PROTOCOL_ERROR); + + talloc_free(tmp_ctx); +} + +/* + * Test data can not be deleted outside a transaction + */ +static void test_delete_outside_transaction(void **state) +{ + int ret; + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); + uint8_t key_val[] = "TheKey"; + struct ldb_val key = { + .data = key_val, + .length = sizeof(key_val) + }; + + uint8_t value[] = "The record contents"; + struct ldb_val data = { + .data = value, + .length = sizeof(value) + }; + + struct ldb_val read; + + int flags = 0; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + /* + * Begin a transaction + */ + ret = ldb_kv->kv_ops->begin_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * Write the record + */ + ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); + assert_int_equal(ret, 0); + + /* + * Commit the transaction + */ + ret = ldb_kv->kv_ops->finish_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * And now read it back + */ + ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); + assert_int_equal(ret, 0); + ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); + assert_int_equal(ret, 0); + assert_int_equal(sizeof(value), read.length); + assert_memory_equal(value, read.data, sizeof(value)); + ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); + assert_int_equal(ret, 0); + + /* + * Now attempt to delete a record + */ + ret = ldb_kv->kv_ops->delete (ldb_kv, key); + assert_int_equal(ret, LDB_ERR_PROTOCOL_ERROR); + + /* + * And now read it back + */ + ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); + assert_int_equal(ret, 0); + ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); + assert_int_equal(ret, 0); + assert_int_equal(sizeof(value), read.length); + assert_memory_equal(value, read.data, sizeof(value)); + ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); + assert_int_equal(ret, 0); + + talloc_free(tmp_ctx); +} + +static int traverse_fn(struct ldb_kv_private *ldb_kv, + struct ldb_val key, + struct ldb_val data, + void *ctx) +{ + + int *visits = ctx; + int i; + + if (strncmp("key ", (char *) key.data, 4) == 0) { + i = strtol((char *) &key.data[4], NULL, 10); + visits[i]++; + } + return LDB_SUCCESS; +} + +/* + * Test that iterate visits all the records. + */ +static void test_iterate(void **state) +{ + int ret; + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); + int i; + int num_recs = 1024; + int visits[num_recs]; + + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + /* + * Begin a transaction + */ + ret = ldb_kv->kv_ops->begin_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * Write the records + */ + for (i = 0; i < num_recs; i++) { + struct ldb_val key; + struct ldb_val rec; + int flags = 0; + + visits[i] = 0; + key.data = (uint8_t *)talloc_asprintf(tmp_ctx, "key %04d", i); + key.length = strlen((char *)key.data) + 1; + + rec.data = (uint8_t *) talloc_asprintf(tmp_ctx, + "data for record (%04d)", + i); + rec.length = strlen((char *)rec.data) + 1; + + ret = ldb_kv->kv_ops->store(ldb_kv, key, rec, flags); + assert_int_equal(ret, 0); + + TALLOC_FREE(key.data); + TALLOC_FREE(rec.data); + } + + /* + * Commit the transaction + */ + ret = ldb_kv->kv_ops->finish_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * Now iterate over the kv store and ensure that all the + * records are visited. + */ + ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); + assert_int_equal(ret, 0); + ret = ldb_kv->kv_ops->iterate(ldb_kv, traverse_fn, visits); + for (i = 0; i kv_ops->unlock_read(test_ctx->ldb->modules); + assert_int_equal(ret, 0); + + TALLOC_FREE(tmp_ctx); +} + +static void do_iterate_range_test(void **state, int range_start, + int range_end, bool fail) +{ + int ret; + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); + int i; + int num_recs = 1024; + int skip_recs = 10; + int visits[num_recs]; + struct ldb_val sk, ek; + + TALLOC_CTX *tmp_ctx; + + for (i = 0; i < num_recs; i++){ + visits[i] = 0; + } + + /* + * No iterate_range on tdb + */ + if (strcmp(TEST_BE, "tdb") == 0) { + return; + } + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + /* + * Begin a transaction + */ + ret = ldb_kv->kv_ops->begin_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * Write the records + */ + for (i = skip_recs; i <= num_recs - skip_recs; i++) { + struct ldb_val key; + struct ldb_val rec; + int flags = 0; + + key.data = (uint8_t *)talloc_asprintf(tmp_ctx, + "key %04d", + i); + key.length = strlen((char *)key.data); + + rec.data = (uint8_t *)talloc_asprintf(tmp_ctx, + "data for record (%04d)", + i); + rec.length = strlen((char *)rec.data) + 1; + + ret = ldb_kv->kv_ops->store(ldb_kv, key, rec, flags); + assert_int_equal(ret, 0); + + TALLOC_FREE(key.data); + TALLOC_FREE(rec.data); + } + + /* + * Commit the transaction + */ + ret = ldb_kv->kv_ops->finish_write(ldb_kv); + assert_int_equal(ret, 0); + + sk.data = (uint8_t *)talloc_asprintf(tmp_ctx, "key %04d", range_start); + sk.length = strlen((char *)sk.data); + + ek.data = (uint8_t *)talloc_asprintf(tmp_ctx, "key %04d", range_end); + ek.length = strlen((char *)ek.data) + 1; + + ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); + assert_int_equal(ret, 0); + ret = ldb_kv->kv_ops->iterate_range(ldb_kv, sk, ek, + traverse_fn, visits); + if (fail){ + assert_int_equal(ret, LDB_ERR_PROTOCOL_ERROR); + TALLOC_FREE(tmp_ctx); + return; + } else{ + assert_int_equal(ret, 0); + } + for (i = 0; i < num_recs; i++) { + if (i >= skip_recs && i <= num_recs - skip_recs && + i >= range_start && i <= range_end){ + assert_int_equal(1, visits[i]); + } else { + assert_int_equal(0, visits[i]); + } + } + + ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); + assert_int_equal(ret, 0); + + TALLOC_FREE(tmp_ctx); +} + +/* + * Test that iterate_range visits all the records between two keys. + */ +static void test_iterate_range(void **state) +{ + do_iterate_range_test(state, 300, 900, false); + + /* + * test start_key = end_key + */ + do_iterate_range_test(state, 20, 20, false); + + /* + * test reverse range fails + */ + do_iterate_range_test(state, 50, 40, true); + + /* + * keys are between 10-1014 so test with keys outside that range + */ + do_iterate_range_test(state, 0, 20, false); + do_iterate_range_test(state, 1010, 1030, false); + do_iterate_range_test(state, 0, 1030, false); +} + +struct update_context { + struct ldb_context* ldb; + int visits[NUM_RECS]; +}; + +static int update_fn(struct ldb_kv_private *ldb_kv, + struct ldb_val key, + struct ldb_val data, + void *ctx) +{ + + struct ldb_val new_key; + struct ldb_module *module = NULL; + struct update_context *context =NULL; + int ret = LDB_SUCCESS; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(ldb_kv); + assert_non_null(tmp_ctx); + + context = talloc_get_type_abort(ctx, struct update_context); + + module = talloc_zero(tmp_ctx, struct ldb_module); + module->ldb = context->ldb; + + if (strncmp("key ", (char *) key.data, 4) == 0) { + int i = strtol((char *) &key.data[4], NULL, 10); + context->visits[i]++; + new_key.data = talloc_memdup(tmp_ctx, key.data, key.length); + new_key.length = key.length; + new_key.data[0] = 'K'; + + ret = ldb_kv->kv_ops->update_in_iterate( + ldb_kv, key, new_key, data, &module); + } + TALLOC_FREE(tmp_ctx); + return ret; +} + +/* + * Test that update_in_iterate behaves as expected. + */ +static void test_update_in_iterate(void **state) +{ + int ret; + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); + int i; + struct update_context *context = NULL; + + + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + context = talloc_zero(tmp_ctx, struct update_context); + assert_non_null(context); + context->ldb = test_ctx->ldb; + /* + * Begin a transaction + */ + ret = ldb_kv->kv_ops->begin_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * Write the records + */ + for (i = 0; i < NUM_RECS; i++) { + struct ldb_val key; + struct ldb_val rec; + int flags = 0; + + key.data = (uint8_t *)talloc_asprintf(tmp_ctx, "key %04d", i); + key.length = strlen((char *)key.data) + 1; + + rec.data = (uint8_t *) talloc_asprintf(tmp_ctx, + "data for record (%04d)", + i); + rec.length = strlen((char *)rec.data) + 1; + + ret = ldb_kv->kv_ops->store(ldb_kv, key, rec, flags); + assert_int_equal(ret, 0); + + TALLOC_FREE(key.data); + TALLOC_FREE(rec.data); + } + + /* + * Commit the transaction + */ + ret = ldb_kv->kv_ops->finish_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * Now iterate over the kv store and ensure that all the + * records are visited. + */ + + /* + * Needs to be done inside a transaction + */ + ret = ldb_kv->kv_ops->begin_write(ldb_kv); + assert_int_equal(ret, 0); + + ret = ldb_kv->kv_ops->iterate(ldb_kv, update_fn, context); + for (i = 0; i < NUM_RECS; i++) { + assert_int_equal(1, context->visits[i]); + } + + ret = ldb_kv->kv_ops->finish_write(ldb_kv); + assert_int_equal(ret, 0); + + TALLOC_FREE(tmp_ctx); +} + +/* + * Ensure that writes are not visible until the transaction has been + * committed. + */ +static void test_write_transaction_isolation(void **state) +{ + int ret; + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); + struct ldb_val key; + struct ldb_val val; + + const char *KEY1 = "KEY01"; + const char *VAL1 = "VALUE01"; + + const char *KEY2 = "KEY02"; + const char *VAL2 = "VALUE02"; + + /* + * Pipes etc to co-ordinate the processes + */ + int to_child[2]; + int to_parent[2]; + char buf[2]; + pid_t pid, w_pid; + int wstatus; + + TALLOC_CTX *tmp_ctx; + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + + /* + * Add a record to the database + */ + ret = ldb_kv->kv_ops->begin_write(ldb_kv); + assert_int_equal(ret, 0); + + key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1); + key.length = strlen(KEY1) + 1; + + val.data = (uint8_t *)talloc_strdup(tmp_ctx, VAL1); + val.length = strlen(VAL1) + 1; + + ret = ldb_kv->kv_ops->store(ldb_kv, key, val, 0); + assert_int_equal(ret, 0); + + ret = ldb_kv->kv_ops->finish_write(ldb_kv); + assert_int_equal(ret, 0); + + + ret = pipe(to_child); + assert_int_equal(ret, 0); + ret = pipe(to_parent); + assert_int_equal(ret, 0); + /* + * Now fork a new process + */ + + pid = fork(); + if (pid == 0) { + + struct ldb_context *ldb = NULL; + close(to_child[1]); + close(to_parent[0]); + + /* + * Wait for the transaction to start + */ + ret = read(to_child[0], buf, 2); + if (ret != 2) { + print_error(__location__": read returned (%d)\n", + ret); + exit(LDB_ERR_OPERATIONS_ERROR); + } + ldb = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb, test_ctx->dbpath, 0, NULL); + if (ret != LDB_SUCCESS) { + print_error(__location__": ldb_connect returned (%d)\n", + ret); + exit(ret); + } + + ldb_kv = get_ldb_kv(ldb); + + ret = ldb_kv->kv_ops->lock_read(ldb->modules); + if (ret != LDB_SUCCESS) { + print_error(__location__": lock_read returned (%d)\n", + ret); + exit(ret); + } + + /* + * Check that KEY1 is there + */ + key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1); + key.length = strlen(KEY1) + 1; + + ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val); + if (ret != LDB_SUCCESS) { + print_error(__location__": fetch_and_parse returned " + "(%d)\n", + ret); + exit(ret); + } + + if ((strlen(VAL1) + 1) != val.length) { + print_error(__location__": KEY1 value lengths different" + ", expected (%d) actual(%d)\n", + (int)(strlen(VAL1) + 1), (int)val.length); + exit(LDB_ERR_OPERATIONS_ERROR); + } + if (memcmp(VAL1, val.data, strlen(VAL1)) != 0) { + print_error(__location__": KEY1 values different, " + "expected (%s) actual(%s)\n", + VAL1, + val.data); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_kv->kv_ops->unlock_read(ldb->modules); + if (ret != LDB_SUCCESS) { + print_error(__location__": unlock_read returned (%d)\n", + ret); + exit(ret); + } + + /* + * Check that KEY2 is not there + */ + key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2); + key.length = strlen(KEY2 + 1); + + ret = ldb_kv->kv_ops->lock_read(ldb->modules); + if (ret != LDB_SUCCESS) { + print_error(__location__": lock_read returned (%d)\n", + ret); + exit(ret); + } + + ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val); + if (ret != LDB_ERR_NO_SUCH_OBJECT) { + print_error(__location__": fetch_and_parse returned " + "(%d)\n", + ret); + exit(ret); + } + + ret = ldb_kv->kv_ops->unlock_read(ldb->modules); + if (ret != LDB_SUCCESS) { + print_error(__location__": unlock_read returned (%d)\n", + ret); + exit(ret); + } + + /* + * Signal the other process to commit the transaction + */ + ret = write(to_parent[1], "GO", 2); + if (ret != 2) { + print_error(__location__": write returned (%d)\n", + ret); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + /* + * Wait for the transaction to be commited + */ + ret = read(to_child[0], buf, 2); + if (ret != 2) { + print_error(__location__": read returned (%d)\n", + ret); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + /* + * Check that KEY1 is there + */ + ret = ldb_kv->kv_ops->lock_read(ldb->modules); + if (ret != LDB_SUCCESS) { + print_error(__location__": unlock_read returned (%d)\n", + ret); + exit(ret); + } + key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1); + key.length = strlen(KEY1) + 1; + + ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val); + if (ret != LDB_SUCCESS) { + print_error(__location__": fetch_and_parse returned " + "(%d)\n", + ret); + exit(ret); + } + + if ((strlen(VAL1) + 1) != val.length) { + print_error(__location__": KEY1 value lengths different" + ", expected (%d) actual(%d)\n", + (int)(strlen(VAL1) + 1), (int)val.length); + exit(LDB_ERR_OPERATIONS_ERROR); + } + if (memcmp(VAL1, val.data, strlen(VAL1)) != 0) { + print_error(__location__": KEY1 values different, " + "expected (%s) actual(%s)\n", + VAL1, + val.data); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_kv->kv_ops->unlock_read(ldb->modules); + if (ret != LDB_SUCCESS) { + print_error(__location__": unlock_read returned (%d)\n", + ret); + exit(ret); + } + + + /* + * Check that KEY2 is there + */ + ret = ldb_kv->kv_ops->lock_read(ldb->modules); + if (ret != LDB_SUCCESS) { + print_error(__location__": unlock_read returned (%d)\n", + ret); + exit(ret); + } + + key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2); + key.length = strlen(KEY2) + 1; + + ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val); + if (ret != LDB_SUCCESS) { + print_error(__location__": fetch_and_parse returned " + "(%d)\n", + ret); + exit(ret); + } + + if ((strlen(VAL2) + 1) != val.length) { + print_error(__location__": KEY2 value lengths different" + ", expected (%d) actual(%d)\n", + (int)(strlen(VAL2) + 1), (int)val.length); + exit(LDB_ERR_OPERATIONS_ERROR); + } + if (memcmp(VAL2, val.data, strlen(VAL2)) != 0) { + print_error(__location__": KEY2 values different, " + "expected (%s) actual(%s)\n", + VAL2, + val.data); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_kv->kv_ops->unlock_read(ldb->modules); + if (ret != LDB_SUCCESS) { + print_error(__location__": unlock_read returned (%d)\n", + ret); + exit(ret); + } + + exit(0); + } + close(to_child[0]); + close(to_parent[1]); + + /* + * Begin a transaction and add a record to the database + * but leave the transaction open + */ + ret = ldb_kv->kv_ops->begin_write(ldb_kv); + assert_int_equal(ret, 0); + + key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2); + key.length = strlen(KEY2) + 1; + + val.data = (uint8_t *)talloc_strdup(tmp_ctx, VAL2); + val.length = strlen(VAL2) + 1; + + ret = ldb_kv->kv_ops->store(ldb_kv, key, val, 0); + assert_int_equal(ret, 0); + + /* + * Signal the child process + */ + ret = write(to_child[1], "GO", 2); + assert_int_equal(2, ret); + + /* + * Wait for the child process to check the DB state while the + * transaction is active + */ + ret = read(to_parent[0], buf, 2); + assert_int_equal(2, ret); + + /* + * commit the transaction + */ + ret = ldb_kv->kv_ops->finish_write(ldb_kv); + assert_int_equal(0, ret); + + /* + * Signal the child process + */ + ret = write(to_child[1], "GO", 2); + assert_int_equal(2, ret); + + w_pid = waitpid(pid, &wstatus, 0); + assert_int_equal(pid, w_pid); + + assert_true(WIFEXITED(wstatus)); + + assert_int_equal(WEXITSTATUS(wstatus), 0); + + + TALLOC_FREE(tmp_ctx); +} + +/* + * Ensure that deletes are not visible until the transaction has been + * committed. + */ +static void test_delete_transaction_isolation(void **state) +{ + int ret; + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); + struct ldb_val key; + struct ldb_val val; + + const char *KEY1 = "KEY01"; + const char *VAL1 = "VALUE01"; + + const char *KEY2 = "KEY02"; + const char *VAL2 = "VALUE02"; + + /* + * Pipes etc to co-ordinate the processes + */ + int to_child[2]; + int to_parent[2]; + char buf[2]; + pid_t pid, w_pid; + int wstatus; + + TALLOC_CTX *tmp_ctx; + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + + /* + * Add records to the database + */ + ret = ldb_kv->kv_ops->begin_write(ldb_kv); + assert_int_equal(ret, 0); + + key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1); + key.length = strlen(KEY1) + 1; + + val.data = (uint8_t *)talloc_strdup(tmp_ctx, VAL1); + val.length = strlen(VAL1) + 1; + + ret = ldb_kv->kv_ops->store(ldb_kv, key, val, 0); + assert_int_equal(ret, 0); + + key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2); + key.length = strlen(KEY2) + 1; + + val.data = (uint8_t *)talloc_strdup(tmp_ctx, VAL2); + val.length = strlen(VAL2) + 1; + + ret = ldb_kv->kv_ops->store(ldb_kv, key, val, 0); + assert_int_equal(ret, 0); + + ret = ldb_kv->kv_ops->finish_write(ldb_kv); + assert_int_equal(ret, 0); + + + ret = pipe(to_child); + assert_int_equal(ret, 0); + ret = pipe(to_parent); + assert_int_equal(ret, 0); + /* + * Now fork a new process + */ + + pid = fork(); + if (pid == 0) { + + struct ldb_context *ldb = NULL; + close(to_child[1]); + close(to_parent[0]); + + /* + * Wait for the transaction to be started + */ + ret = read(to_child[0], buf, 2); + if (ret != 2) { + print_error(__location__": read returned (%d)\n", + ret); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ldb = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb, test_ctx->dbpath, 0, NULL); + if (ret != LDB_SUCCESS) { + print_error(__location__": ldb_connect returned (%d)\n", + ret); + exit(ret); + } + + ldb_kv = get_ldb_kv(ldb); + + ret = ldb_kv->kv_ops->lock_read(ldb->modules); + if (ret != LDB_SUCCESS) { + print_error(__location__": lock_read returned (%d)\n", + ret); + exit(ret); + } + + /* + * Check that KEY1 is there + */ + key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1); + key.length = strlen(KEY1) + 1; + + ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val); + if (ret != LDB_SUCCESS) { + print_error(__location__": fetch_and_parse returned " + "(%d)\n", + ret); + exit(ret); + } + + if ((strlen(VAL1) + 1) != val.length) { + print_error(__location__": KEY1 value lengths different" + ", expected (%d) actual(%d)\n", + (int)(strlen(VAL1) + 1), (int)val.length); + exit(LDB_ERR_OPERATIONS_ERROR); + } + if (memcmp(VAL1, val.data, strlen(VAL1)) != 0) { + print_error(__location__": KEY1 values different, " + "expected (%s) actual(%s)\n", + VAL1, + val.data); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + /* + * Check that KEY2 is there + */ + + key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2); + key.length = strlen(KEY2) + 1; + + ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val); + if (ret != LDB_SUCCESS) { + print_error(__location__": fetch_and_parse returned " + "(%d)\n", + ret); + exit(ret); + } + + if ((strlen(VAL2) + 1) != val.length) { + print_error(__location__": KEY2 value lengths different" + ", expected (%d) actual(%d)\n", + (int)(strlen(VAL2) + 1), (int)val.length); + exit(LDB_ERR_OPERATIONS_ERROR); + } + if (memcmp(VAL2, val.data, strlen(VAL2)) != 0) { + print_error(__location__": KEY2 values different, " + "expected (%s) actual(%s)\n", + VAL2, + val.data); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_kv->kv_ops->unlock_read(ldb->modules); + if (ret != LDB_SUCCESS) { + print_error(__location__": unlock_read returned (%d)\n", + ret); + exit(ret); + } + + /* + * Signal the other process to commit the transaction + */ + ret = write(to_parent[1], "GO", 2); + if (ret != 2) { + print_error(__location__": write returned (%d)\n", + ret); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + /* + * Wait for the transaction to be commited + */ + ret = read(to_child[0], buf, 2); + if (ret != 2) { + print_error(__location__": read returned (%d)\n", + ret); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + /* + * Check that KEY1 is there + */ + ret = ldb_kv->kv_ops->lock_read(ldb->modules); + if (ret != LDB_SUCCESS) { + print_error(__location__": unlock_read returned (%d)\n", + ret); + exit(ret); + } + key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1); + key.length = strlen(KEY1) + 1; + + ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val); + if (ret != LDB_SUCCESS) { + print_error(__location__": fetch_and_parse returned " + "(%d)\n", + ret); + exit(ret); + } + + if ((strlen(VAL1) + 1) != val.length) { + print_error(__location__": KEY1 value lengths different" + ", expected (%d) actual(%d)\n", + (int)(strlen(VAL1) + 1), (int)val.length); + exit(LDB_ERR_OPERATIONS_ERROR); + } + if (memcmp(VAL1, val.data, strlen(VAL1)) != 0) { + print_error(__location__": KEY1 values different, " + "expected (%s) actual(%s)\n", + VAL1, + val.data); + exit(LDB_ERR_OPERATIONS_ERROR); + } + ret = ldb_kv->kv_ops->unlock_read(ldb->modules); + if (ret != LDB_SUCCESS) { + print_error(__location__": unlock_read returned (%d)\n", + ret); + exit(ret); + } + + /* + * Check that KEY2 is not there + */ + key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2); + key.length = strlen(KEY2 + 1); + + ret = ldb_kv->kv_ops->lock_read(ldb->modules); + if (ret != LDB_SUCCESS) { + print_error(__location__": lock_read returned (%d)\n", + ret); + exit(ret); + } + + ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val); + if (ret != LDB_ERR_NO_SUCH_OBJECT) { + print_error(__location__": fetch_and_parse returned " + "(%d)\n", + ret); + exit(ret); + } + + ret = ldb_kv->kv_ops->unlock_read(ldb->modules); + if (ret != LDB_SUCCESS) { + print_error(__location__": unlock_read returned (%d)\n", + ret); + exit(ret); + } + TALLOC_FREE(tmp_ctx); + exit(0); + } + close(to_child[0]); + close(to_parent[1]); + + /* + * Begin a transaction and delete a record from the database + * but leave the transaction open + */ + ret = ldb_kv->kv_ops->begin_write(ldb_kv); + assert_int_equal(ret, 0); + + key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2); + key.length = strlen(KEY2) + 1; + + ret = ldb_kv->kv_ops->delete (ldb_kv, key); + assert_int_equal(ret, 0); + /* + * Signal the child process + */ + ret = write(to_child[1], "GO", 2); + assert_int_equal(2, ret); + + /* + * Wait for the child process to check the DB state while the + * transaction is active + */ + ret = read(to_parent[0], buf, 2); + assert_int_equal(2, ret); + + /* + * commit the transaction + */ + ret = ldb_kv->kv_ops->finish_write(ldb_kv); + assert_int_equal(0, ret); + + /* + * Signal the child process + */ + ret = write(to_child[1], "GO", 2); + assert_int_equal(2, ret); + + w_pid = waitpid(pid, &wstatus, 0); + assert_int_equal(pid, w_pid); + + assert_true(WIFEXITED(wstatus)); + + assert_int_equal(WEXITSTATUS(wstatus), 0); + + + TALLOC_FREE(tmp_ctx); +} + + +/* + * Test that get_size returns a sensible estimate of the number of records + * in the database. + */ +static void test_get_size(void **state) +{ + int ret; + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); + uint8_t key_val[] = "TheKey"; + struct ldb_val key = { + .data = key_val, + .length = sizeof(key_val) + }; + + uint8_t value[] = "The record contents"; + struct ldb_val data = { + .data = value, + .length = sizeof(value) + }; + size_t size = 0; + + int flags = 0; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + size = ldb_kv->kv_ops->get_size(ldb_kv); +#if defined(TEST_LMDB) + assert_int_equal(2, size); +#else + /* + * The tdb implementation of get_size over estimates for sparse files + * which is perfectly acceptable for it's intended use. + */ + assert_true( size > 2500); +#endif + + /* + * Begin a transaction + */ + ret = ldb_kv->kv_ops->begin_write(ldb_kv); + assert_int_equal(ret, 0); + + /* + * Write the record + */ + ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); + assert_int_equal(ret, 0); + + /* + * Commit the transaction + */ + ret = ldb_kv->kv_ops->finish_write(ldb_kv); + assert_int_equal(ret, 0); + + size = ldb_kv->kv_ops->get_size(ldb_kv); +#ifdef TEST_LMDB + assert_int_equal(3, size); +#endif + talloc_free(tmp_ctx); +} + +int main(int argc, const char **argv) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown( + test_add_get, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_delete, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_transaction_abort_write, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_transaction_abort_delete, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_read_outside_transaction, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_write_outside_transaction, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_delete_outside_transaction, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_iterate, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_iterate_range, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_update_in_iterate, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_write_transaction_isolation, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_delete_transaction_isolation, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_get_size, + setup, + teardown), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/ldb-2.0.8/tests/ldb_kv_ops_test.valgrind b/ldb-2.0.8/tests/ldb_kv_ops_test.valgrind new file mode 100644 index 0000000..1747076 --- /dev/null +++ b/ldb-2.0.8/tests/ldb_kv_ops_test.valgrind @@ -0,0 +1,97 @@ +{ + Memory allocated by setup + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + ... + fun:setup +} +{ + Memory allocated by setup + Memcheck:Leak + match-leak-kinds: possible + fun:realloc + ... + fun:setup +} +{ + Memory allocated by ldb_init + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + ... + fun:ldb_init +} +{ + Memory allocated by ldb_init + Memcheck:Leak + match-leak-kinds: possible + fun:realloc + ... + fun:ldb_init +} +{ + Memory allocated by noconn_setup + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + ... + fun:noconn_setup +} +{ + Memory allocated by parse, which allocates on the NULL context + Memcheck:Leak + match-leak-kinds: all + fun:malloc + ... + fun:parse +} +{ + Memory allocated by tdb_parse_data + Memcheck:Leak + match-leak-kinds: all + fun:malloc + ... + fun:tdb_parse_data +} +{ + Memory allocated by ldb_connect + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + ... + fun:ldb_connect +} +{ + Memory allocated by ldb_connect + Memcheck:Leak + match-leak-kinds: possible + fun:calloc + ... + fun:ldb_connect +} +{ + Memory allocated by ldb_kv_cache_load + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + ... + fun:ldb_kv_cache_load +} +{ + Memory allocated by ldb_kv_index_load + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + ... + fun:ldb_kv_index_load +} +{ + Memory allocated by ldb_asprintf_errstring + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + ... + fun:ldb_asprintf_errstring +} + diff --git a/ldb-2.0.8/tests/ldb_lmdb_size_test.c b/ldb-2.0.8/tests/ldb_lmdb_size_test.c new file mode 100644 index 0000000..af015fa --- /dev/null +++ b/ldb-2.0.8/tests/ldb_lmdb_size_test.c @@ -0,0 +1,210 @@ +/* + * lmdb backend specific tests for ldb + * Tests for truncated index keys + * + * Copyright (C) Andrew Bartlett 2018 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* + * These tests confirm that database sizes of > 4GB are supported + * Due to the disk space requirement they are not run as part of the normal + * self test runs. + * + * Setup and tear down code copied from ldb_mod_op_test.c + */ + +/* + * from cmocka.c: + * These headers or their equivalents should be included prior to + * including + * this header file. + * + * #include + * #include + * #include + * + * This allows test applications to use custom definitions of C standard + * library functions and types. + * + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + + +#define TEST_BE "mdb" + +struct ldbtest_ctx { + struct tevent_context *ev; + struct ldb_context *ldb; + + const char *dbfile; + const char *lockfile; /* lockfile is separate */ + + const char *dbpath; +}; + +static void unlink_old_db(struct ldbtest_ctx *test_ctx) +{ + int ret; + + errno = 0; + ret = unlink(test_ctx->lockfile); + if (ret == -1 && errno != ENOENT) { + fail(); + } + + errno = 0; + ret = unlink(test_ctx->dbfile); + if (ret == -1 && errno != ENOENT) { + fail(); + } +} + +static int ldbtest_noconn_setup(void **state) +{ + struct ldbtest_ctx *test_ctx; + + test_ctx = talloc_zero(NULL, struct ldbtest_ctx); + assert_non_null(test_ctx); + + test_ctx->ev = tevent_context_init(test_ctx); + assert_non_null(test_ctx->ev); + + test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev); + assert_non_null(test_ctx->ldb); + + test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb"); + assert_non_null(test_ctx->dbfile); + + test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock", + test_ctx->dbfile); + assert_non_null(test_ctx->lockfile); + + test_ctx->dbpath = talloc_asprintf(test_ctx, + TEST_BE"://%s", test_ctx->dbfile); + assert_non_null(test_ctx->dbpath); + + unlink_old_db(test_ctx); + *state = test_ctx; + return 0; +} + +static int ldbtest_noconn_teardown(void **state) +{ + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + + unlink_old_db(test_ctx); + talloc_free(test_ctx); + return 0; +} + +static int ldbtest_setup(void **state) +{ + struct ldbtest_ctx *test_ctx; + int ret; + + ldbtest_noconn_setup((void **) &test_ctx); + + ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL); + assert_int_equal(ret, 0); + + *state = test_ctx; + return 0; +} + +static int ldbtest_teardown(void **state) +{ + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + ldbtest_noconn_teardown((void **) &test_ctx); + return 0; +} + +static void test_db_size_gt_4GB(void **state) +{ + int ret, x; + struct ldb_message *msg; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + const int MB = 1024 * 1024; + char *blob = NULL; + + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + + blob = talloc_zero_size(tmp_ctx, (MB + 1)); + assert_non_null(blob); + memset(blob, 'x', MB); + + + for (x = 0; x < 6144; x++) { + msg = ldb_msg_new(tmp_ctx); + assert_non_null(msg); + + msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test%d", x); + assert_non_null(msg->dn); + + ldb_transaction_start(test_ctx->ldb); + ret = ldb_msg_add_string(msg, "blob", blob); + assert_int_equal(ret, 0); + + ret = ldb_add(test_ctx->ldb, msg); + assert_int_equal(ret, 0); + ldb_transaction_commit(test_ctx->ldb); + + TALLOC_FREE(msg); + } + talloc_free(tmp_ctx); + { + struct stat s; + ret = stat(test_ctx->dbfile, &s); + assert_int_equal(ret, 0); + assert_true(s.st_size > (6144LL * MB)); + } +} + +int main(int argc, const char **argv) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown( + test_db_size_gt_4GB, + ldbtest_setup, + ldbtest_teardown), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/ldb-2.0.8/tests/ldb_lmdb_test.c b/ldb-2.0.8/tests/ldb_lmdb_test.c new file mode 100644 index 0000000..78758bb --- /dev/null +++ b/ldb-2.0.8/tests/ldb_lmdb_test.c @@ -0,0 +1,589 @@ +/* + * lmdb backend specific tests for ldb + * + * Copyright (C) Andrew Bartlett 2018 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* + * lmdb backend specific tests for ldb + * + * Setup and tear down code copied from ldb_mod_op_test.c + */ + +/* + * from cmocka.c: + * These headers or their equivalents should be included prior to + * including + * this header file. + * + * #include + * #include + * #include + * + * This allows test applications to use custom definitions of C standard + * library functions and types. + * + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../ldb_tdb/ldb_tdb.h" +#include "../ldb_mdb/ldb_mdb.h" +#include "../ldb_key_value/ldb_kv.h" + +#define TEST_BE "mdb" + +#define LMDB_MAX_KEY_SIZE 511 + +struct ldbtest_ctx { + struct tevent_context *ev; + struct ldb_context *ldb; + + const char *dbfile; + const char *lockfile; /* lockfile is separate */ + + const char *dbpath; +}; + +static void unlink_old_db(struct ldbtest_ctx *test_ctx) +{ + int ret; + + errno = 0; + ret = unlink(test_ctx->lockfile); + if (ret == -1 && errno != ENOENT) { + fail(); + } + + errno = 0; + ret = unlink(test_ctx->dbfile); + if (ret == -1 && errno != ENOENT) { + fail(); + } +} + +static int ldbtest_noconn_setup(void **state) +{ + struct ldbtest_ctx *test_ctx; + + test_ctx = talloc_zero(NULL, struct ldbtest_ctx); + assert_non_null(test_ctx); + + test_ctx->ev = tevent_context_init(test_ctx); + assert_non_null(test_ctx->ev); + + test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev); + assert_non_null(test_ctx->ldb); + + test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb"); + assert_non_null(test_ctx->dbfile); + + test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock", + test_ctx->dbfile); + assert_non_null(test_ctx->lockfile); + + test_ctx->dbpath = talloc_asprintf(test_ctx, + TEST_BE"://%s", test_ctx->dbfile); + assert_non_null(test_ctx->dbpath); + + unlink_old_db(test_ctx); + *state = test_ctx; + return 0; +} + +static int ldbtest_noconn_teardown(void **state) +{ + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + + unlink_old_db(test_ctx); + talloc_free(test_ctx); + return 0; +} + +static int ldbtest_setup(void **state) +{ + struct ldbtest_ctx *test_ctx; + int ret; + struct ldb_ldif *ldif; + const char *index_ldif = \ + "dn: @INDEXLIST\n" + "@IDXGUID: objectUUID\n" + "@IDX_DN_GUID: GUID\n" + "\n"; + + ldbtest_noconn_setup((void **) &test_ctx); + + ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL); + assert_int_equal(ret, 0); + + while ((ldif = ldb_ldif_read_string(test_ctx->ldb, &index_ldif))) { + ret = ldb_add(test_ctx->ldb, ldif->msg); + assert_int_equal(ret, LDB_SUCCESS); + } + *state = test_ctx; + return 0; +} + +static int ldbtest_teardown(void **state) +{ + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + ldbtest_noconn_teardown((void **) &test_ctx); + return 0; +} + +static void test_ldb_add_key_len_gt_max(void **state) +{ + int ret; + int xs_size = 0; + struct ldb_message *msg; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + char *xs = NULL; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + msg = ldb_msg_new(tmp_ctx); + assert_non_null(msg); + + /* + * The zero terminator is part of the key if we were not in + * GUID mode + */ + + xs_size = LMDB_MAX_KEY_SIZE - 7; /* "dn=dc=" and the zero terminator */ + xs_size += 1; /* want key on char too long */ + xs = talloc_zero_size(tmp_ctx, (xs_size + 1)); + memset(xs, 'x', xs_size); + + msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=%s", xs); + assert_non_null(msg->dn); + + ret = ldb_msg_add_string(msg, "cn", "test_cn_val"); + assert_int_equal(ret, 0); + + ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef"); + assert_int_equal(ret, 0); + + ret = ldb_add(test_ctx->ldb, msg); + assert_int_equal(ret, LDB_SUCCESS); + + talloc_free(tmp_ctx); +} + +static void test_ldb_add_key_len_2x_gt_max(void **state) +{ + int ret; + int xs_size = 0; + struct ldb_message *msg; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + char *xs = NULL; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + msg = ldb_msg_new(tmp_ctx); + assert_non_null(msg); + + /* + * The zero terminator is part of the key if we were not in + * GUID mode + */ + + xs_size = 2 * LMDB_MAX_KEY_SIZE; + xs = talloc_zero_size(tmp_ctx, (xs_size + 1)); + memset(xs, 'x', xs_size); + + msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=%s", xs); + assert_non_null(msg->dn); + + ret = ldb_msg_add_string(msg, "cn", "test_cn_val"); + assert_int_equal(ret, 0); + + ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef"); + assert_int_equal(ret, 0); + + ret = ldb_add(test_ctx->ldb, msg); + assert_int_equal(ret, LDB_SUCCESS); + + talloc_free(tmp_ctx); +} + +static void test_ldb_add_key_len_eq_max(void **state) +{ + int ret; + int xs_size = 0; + struct ldb_message *msg; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + char *xs = NULL; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + msg = ldb_msg_new(tmp_ctx); + assert_non_null(msg); + + /* + * The zero terminator is part of the key if we were not in + * GUID mode + */ + + xs_size = LMDB_MAX_KEY_SIZE - 7; /* "dn=dc=" and the zero terminator */ + xs = talloc_zero_size(tmp_ctx, (xs_size + 1)); + memset(xs, 'x', xs_size); + + msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=%s", xs); + assert_non_null(msg->dn); + + ret = ldb_msg_add_string(msg, "cn", "test_cn_val"); + assert_int_equal(ret, 0); + + ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef"); + assert_int_equal(ret, 0); + + ret = ldb_add(test_ctx->ldb, msg); + assert_int_equal(ret, 0); + + talloc_free(tmp_ctx); +} + +static int ldbtest_setup_noguid(void **state) +{ + struct ldbtest_ctx *test_ctx; + int ret; + + ldbtest_noconn_setup((void **) &test_ctx); + + ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL); + assert_int_equal(ret, 0); + + *state = test_ctx; + return 0; +} + +static void test_ldb_add_special_key_len_gt_max(void **state) +{ + int ret; + int xs_size = 0; + struct ldb_message *msg; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + char *xs = NULL; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + msg = ldb_msg_new(tmp_ctx); + assert_non_null(msg); + + /* + * The zero terminator is part of the key if we were not in + * GUID mode + */ + + xs_size = LMDB_MAX_KEY_SIZE - 5; /* "dn=@" and the zero terminator */ + xs_size += 1; /* want key on char too long */ + xs = talloc_zero_size(tmp_ctx, (xs_size + 1)); + memset(xs, 'x', xs_size); + + msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "@%s", xs); + assert_non_null(msg->dn); + + ret = ldb_msg_add_string(msg, "cn", "test_cn_val"); + assert_int_equal(ret, 0); + + ret = ldb_add(test_ctx->ldb, msg); + assert_int_equal(ret, LDB_ERR_PROTOCOL_ERROR); + + talloc_free(tmp_ctx); +} + +static void test_ldb_add_special_key_len_eq_max(void **state) +{ + int ret; + int xs_size = 0; + struct ldb_message *msg; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + char *xs = NULL; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + msg = ldb_msg_new(tmp_ctx); + assert_non_null(msg); + + /* + * The zero terminator is part of the key if we were not in + * GUID mode + */ + + xs_size = LMDB_MAX_KEY_SIZE - 5; /* "dn=@" and the zero terminator */ + xs = talloc_zero_size(tmp_ctx, (xs_size + 1)); + memset(xs, 'x', xs_size); + + msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "@%s", xs); + assert_non_null(msg->dn); + + ret = ldb_msg_add_string(msg, "cn", "test_cn_val"); + assert_int_equal(ret, 0); + + ret = ldb_add(test_ctx->ldb, msg); + assert_int_equal(ret, LDB_SUCCESS); + + talloc_free(tmp_ctx); +} + +static void test_ldb_add_dn_no_guid_mode(void **state) +{ + int ret; + int xs_size = 0; + struct ldb_message *msg; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + char *xs = NULL; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + msg = ldb_msg_new(tmp_ctx); + assert_non_null(msg); + + /* + * The zero terminator is part of the key if we were not in + * GUID mode + */ + + xs_size = LMDB_MAX_KEY_SIZE - 7; /* "dn=dc=" and the zero terminator */ + xs_size += 1; /* want key on char too long */ + xs = talloc_zero_size(tmp_ctx, (xs_size + 1)); + memset(xs, 'x', xs_size); + + msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=%s", xs); + assert_non_null(msg->dn); + + ret = ldb_msg_add_string(msg, "cn", "test_cn_val"); + assert_int_equal(ret, 0); + + ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef"); + assert_int_equal(ret, 0); + + ret = ldb_add(test_ctx->ldb, msg); + assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM); + + talloc_free(tmp_ctx); +} + +static struct MDB_env *get_mdb_env(struct ldb_context *ldb) +{ + void *data = NULL; + struct ldb_kv_private *ldb_kv = NULL; + struct lmdb_private *lmdb = NULL; + struct MDB_env *env = NULL; + + data = ldb_module_get_private(ldb->modules); + assert_non_null(data); + + ldb_kv = talloc_get_type(data, struct ldb_kv_private); + assert_non_null(ldb_kv); + + lmdb = ldb_kv->lmdb_private; + assert_non_null(lmdb); + + env = lmdb->env; + assert_non_null(env); + + return env; +} + +static void test_multiple_opens(void **state) +{ + struct ldb_context *ldb1 = NULL; + struct ldb_context *ldb2 = NULL; + struct ldb_context *ldb3 = NULL; + struct MDB_env *env1 = NULL; + struct MDB_env *env2 = NULL; + struct MDB_env *env3 = NULL; + int ret; + struct ldbtest_ctx *test_ctx = NULL; + + test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); + + /* + * Open the database again + */ + ldb1 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); + assert_int_equal(ret, 0); + + ldb2 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb2, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); + assert_int_equal(ret, 0); + + ldb3 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL); + assert_int_equal(ret, 0); + /* + * We now have 3 ldb's open pointing to the same on disk database + * they should all share the same MDB_env + */ + env1 = get_mdb_env(ldb1); + env2 = get_mdb_env(ldb2); + env3 = get_mdb_env(ldb3); + + assert_ptr_equal(env1, env2); + assert_ptr_equal(env1, env3); +} + +static void test_multiple_opens_across_fork(void **state) +{ + struct ldb_context *ldb1 = NULL; + struct ldb_context *ldb2 = NULL; + struct MDB_env *env1 = NULL; + struct MDB_env *env2 = NULL; + int ret; + struct ldbtest_ctx *test_ctx = NULL; + int pipes[2]; + char buf[2]; + int wstatus; + pid_t pid, child_pid; + + test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); + + /* + * Open the database again + */ + ldb1 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); + assert_int_equal(ret, 0); + + ldb2 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb2, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); + assert_int_equal(ret, 0); + + env1 = get_mdb_env(ldb1); + env2 = get_mdb_env(ldb2); + + ret = pipe(pipes); + assert_int_equal(ret, 0); + + child_pid = fork(); + if (child_pid == 0) { + struct ldb_context *ldb3 = NULL; + struct MDB_env *env3 = NULL; + + close(pipes[0]); + ldb3 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL); + if (ret != 0) { + print_error(__location__": ldb_connect returned (%d)\n", + ret); + exit(ret); + } + env3 = get_mdb_env(ldb3); + if (env1 != env2) { + print_error(__location__": env1 != env2\n"); + exit(LDB_ERR_OPERATIONS_ERROR); + } + if (env1 == env3) { + print_error(__location__": env1 == env3\n"); + exit(LDB_ERR_OPERATIONS_ERROR); + } + ret = write(pipes[1], "GO", 2); + if (ret != 2) { + print_error(__location__ + " write returned (%d)", + ret); + exit(LDB_ERR_OPERATIONS_ERROR); + } + exit(LDB_SUCCESS); + } + close(pipes[1]); + ret = read(pipes[0], buf, 2); + assert_int_equal(ret, 2); + + pid = waitpid(child_pid, &wstatus, 0); + assert_int_equal(pid, child_pid); + + assert_true(WIFEXITED(wstatus)); + + assert_int_equal(WEXITSTATUS(wstatus), 0); +} + +int main(int argc, const char **argv) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown( + test_ldb_add_key_len_eq_max, + ldbtest_setup, + ldbtest_teardown), + cmocka_unit_test_setup_teardown( + test_ldb_add_key_len_gt_max, + ldbtest_setup, + ldbtest_teardown), + cmocka_unit_test_setup_teardown( + test_ldb_add_key_len_2x_gt_max, + ldbtest_setup, + ldbtest_teardown), + cmocka_unit_test_setup_teardown( + test_ldb_add_special_key_len_eq_max, + ldbtest_setup_noguid, + ldbtest_teardown), + cmocka_unit_test_setup_teardown( + test_ldb_add_special_key_len_gt_max, + ldbtest_setup_noguid, + ldbtest_teardown), + cmocka_unit_test_setup_teardown( + test_ldb_add_dn_no_guid_mode, + ldbtest_setup_noguid, + ldbtest_teardown), + cmocka_unit_test_setup_teardown( + test_multiple_opens, + ldbtest_setup, + ldbtest_teardown), + cmocka_unit_test_setup_teardown( + test_multiple_opens_across_fork, + ldbtest_setup, + ldbtest_teardown), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/ldb-2.0.8/tests/ldb_match_test.c b/ldb-2.0.8/tests/ldb_match_test.c new file mode 100644 index 0000000..e09f50c --- /dev/null +++ b/ldb-2.0.8/tests/ldb_match_test.c @@ -0,0 +1,191 @@ +/* + * Tests exercising the ldb match operations. + * + * + * Copyright (C) Catalyst.NET Ltd 2017 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* + * from cmocka.c: + * These headers or their equivalents should be included prior to + * including + * this header file. + * + * #include + * #include + * #include + * + * This allows test applications to use custom definitions of C standard + * library functions and types. + */ +#include +#include +#include +#include +#include + +#include "../common/ldb_match.c" + +#include "../include/ldb.h" + +struct ldbtest_ctx { + struct tevent_context *ev; + struct ldb_context *ldb; +}; + +static int ldb_test_canonicalise( + struct ldb_context *ldb, + void *mem_ctx, + const struct ldb_val *in, + struct ldb_val *out) +{ + out->length = in->length; + out->data = in->data; + return 0; +} + +static int setup(void **state) +{ + struct ldbtest_ctx *test_ctx; + struct ldb_schema_syntax *syntax = NULL; + int ret; + + test_ctx = talloc_zero(NULL, struct ldbtest_ctx); + assert_non_null(test_ctx); + + test_ctx->ev = tevent_context_init(test_ctx); + assert_non_null(test_ctx->ev); + + test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev); + assert_non_null(test_ctx->ldb); + + syntax = talloc_zero(test_ctx, struct ldb_schema_syntax); + assert_non_null(syntax); + syntax->canonicalise_fn = ldb_test_canonicalise; + + ret = ldb_schema_attribute_add_with_syntax( + test_ctx->ldb, "a", LDB_ATTR_FLAG_FIXED, syntax); + assert_int_equal(LDB_SUCCESS, ret); + + *state = test_ctx; + return 0; +} + +static int teardown(void **state) +{ + talloc_free(*state); + return 0; +} + + +/* + * The wild card pattern "attribute=*" is parsed as an LDB_OP_PRESENT operation + * rather than a LDB_OP_???? + * + * This test serves to document that behaviour, and to confirm that + * ldb_wildcard_compare handles this case appropriately. + */ +static void test_wildcard_match_star(void **state) +{ + struct ldbtest_ctx *ctx = *state; + bool matched = false; + int ret; + + uint8_t value[] = "The value.......end"; + struct ldb_val val = { + .data = value, + .length = (sizeof(value)) + }; + struct ldb_parse_tree *tree = ldb_parse_tree(ctx, "a=*"); + assert_non_null(tree); + + ret = ldb_wildcard_compare(ctx->ldb, tree, val, &matched); + assert_false(matched); + assert_int_equal(LDB_ERR_INAPPROPRIATE_MATCHING, ret); +} + +/* + * Test basic wild card matching + * + */ +static void test_wildcard_match(void **state) +{ + struct ldbtest_ctx *ctx = *state; + bool matched = false; + + uint8_t value[] = "The value.......end"; + struct ldb_val val = { + .data = value, + .length = (sizeof(value)) + }; + struct ldb_parse_tree *tree = ldb_parse_tree(ctx, "objectClass=*end"); + assert_non_null(tree); + + ldb_wildcard_compare(ctx->ldb, tree, val, &matched); + assert_true(matched); +} + + +/* + * ldb_handler_copy and ldb_val_dup over allocate by one and add a trailing '\0' + * to the data, to make them safe to use the C string functions on. + * + * However testing for the trailing '\0' is not the correct way to test for + * the end of a value, the length should be checked instead. + */ +static void test_wildcard_match_end_condition(void **state) +{ + struct ldbtest_ctx *ctx = *state; + bool matched = false; + + uint8_t value[] = "hellomynameisbobx"; + struct ldb_val val = { + .data = talloc_memdup(NULL, value, sizeof(value)), + .length = (sizeof(value) - 2) + }; + struct ldb_parse_tree *tree = ldb_parse_tree(ctx, "a=*hello*mynameis*bob"); + assert_non_null(tree); + + ldb_wildcard_compare(ctx->ldb, tree, val, &matched); + assert_true(matched); +} + +/* + * Note: to run under valgrind use: + * valgrind \ + * --suppressions=lib/ldb/tests/ldb_match_test.valgrind \ + * bin/ldb_match_test + */ +int main(int argc, const char **argv) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown( + test_wildcard_match_star, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_wildcard_match, + setup, + teardown), + cmocka_unit_test_setup_teardown( + test_wildcard_match_end_condition, + setup, + teardown), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/ldb-2.0.8/tests/ldb_match_test.valgrind b/ldb-2.0.8/tests/ldb_match_test.valgrind new file mode 100644 index 0000000..660bd5a --- /dev/null +++ b/ldb-2.0.8/tests/ldb_match_test.valgrind @@ -0,0 +1,16 @@ +{ + Memory allocated in set-up + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + ... + fun:setup +} +{ + Memory allocated by ldb_init + Memcheck:Leak + match-leak-kinds: possible + fun:malloc + ... + fun:ldb_init +} diff --git a/ldb-2.0.8/tests/ldb_mod_op_test.c b/ldb-2.0.8/tests/ldb_mod_op_test.c new file mode 100644 index 0000000..b6a0d1e --- /dev/null +++ b/ldb-2.0.8/tests/ldb_mod_op_test.c @@ -0,0 +1,4721 @@ +/* + * from cmocka.c: + * These headers or their equivalents should be included prior to + * including + * this header file. + * + * #include + * #include + * #include + * + * This allows test applications to use custom definitions of C standard + * library functions and types. + */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#define TEVENT_DEPRECATED 1 +#include + +#include +#include +#include +#include +#include + +#include + + +#define DEFAULT_BE "tdb" + +#ifndef TEST_BE +#define TEST_BE DEFAULT_BE +#endif /* TEST_BE */ + +#ifdef TEST_LMDB +#include "lmdb.h" +#include "../ldb_tdb/ldb_tdb.h" +#include "../ldb_mdb/ldb_mdb.h" +#endif + +struct ldbtest_ctx { + struct tevent_context *ev; + struct ldb_context *ldb; + + const char *dbfile; + const char *lockfile; /* lockfile is separate */ + + const char *dbpath; +}; + +static void unlink_old_db(struct ldbtest_ctx *test_ctx) +{ + int ret; + + errno = 0; + ret = unlink(test_ctx->lockfile); + if (ret == -1 && errno != ENOENT) { + fail(); + } + + errno = 0; + ret = unlink(test_ctx->dbfile); + if (ret == -1 && errno != ENOENT) { + fail(); + } +} + +static int ldbtest_noconn_setup(void **state) +{ + struct ldbtest_ctx *test_ctx; + + test_ctx = talloc_zero(NULL, struct ldbtest_ctx); + assert_non_null(test_ctx); + + test_ctx->ev = tevent_context_init(test_ctx); + assert_non_null(test_ctx->ev); + + test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev); + assert_non_null(test_ctx->ldb); + + test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb"); + assert_non_null(test_ctx->dbfile); + + test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock", + test_ctx->dbfile); + assert_non_null(test_ctx->lockfile); + + test_ctx->dbpath = talloc_asprintf(test_ctx, + TEST_BE"://%s", test_ctx->dbfile); + assert_non_null(test_ctx->dbpath); + + unlink_old_db(test_ctx); + *state = test_ctx; + return 0; +} + +static int ldbtest_noconn_teardown(void **state) +{ + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + + unlink_old_db(test_ctx); + talloc_free(test_ctx); + return 0; +} + +static void test_connect(void **state) +{ + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + int ret; + + ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL); + assert_int_equal(ret, 0); +} + +static struct ldb_message *get_test_ldb_message(TALLOC_CTX *mem_ctx, + struct ldb_context *ldb) +{ + struct ldb_message *msg = ldb_msg_new(mem_ctx); + int ret; + assert_non_null(msg); + + msg->dn = ldb_dn_new(msg, ldb, "dc=samba,dc=org"); + assert_non_null(msg->dn); + ret = ldb_msg_add_string(msg, "public", "key"); + assert_int_equal(ret, LDB_SUCCESS); + ret = ldb_msg_add_string(msg, "supersecret", "password"); + assert_int_equal(ret, LDB_SUCCESS); + ret = ldb_msg_add_string(msg, "binary", "\xff\xff\0"); + assert_int_equal(ret, LDB_SUCCESS); + return msg; +} + +static void test_ldif_message(void **state) +{ + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + char *got_ldif; + const char *expected_ldif = + "dn: dc=samba,dc=org\n" + "changetype: add\n" + "public: key\n" + "supersecret: password\n" + "binary:: //8=\n" + "\n"; + + struct ldb_message *msg = get_test_ldb_message(test_ctx, + test_ctx->ldb); + + got_ldif = ldb_ldif_message_string(test_ctx->ldb, + test_ctx, + LDB_CHANGETYPE_ADD, + msg); + assert_string_equal(got_ldif, expected_ldif); + TALLOC_FREE(got_ldif); +} + +static void test_ldif_message_redacted(void **state) +{ + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + int ret; + char *got_ldif; + const char *expected_ldif = + "dn: dc=samba,dc=org\n" + "changetype: add\n" + "public: key\n" + "# supersecret::: REDACTED SECRET ATTRIBUTE\n" + "binary:: //8=\n" + "\n"; + + const char *secret_attrs[] = { + "supersecret", + NULL + }; + + struct ldb_message *msg = ldb_msg_new(test_ctx); + + ldb_set_opaque(test_ctx->ldb, + LDB_SECRET_ATTRIBUTE_LIST_OPAQUE, + secret_attrs); + + assert_non_null(msg); + + msg->dn = ldb_dn_new(msg, test_ctx->ldb, "dc=samba,dc=org"); + ret = ldb_msg_add_string(msg, "public", "key"); + assert_int_equal(ret, LDB_SUCCESS); + ret = ldb_msg_add_string(msg, "supersecret", "password"); + assert_int_equal(ret, LDB_SUCCESS); + ret = ldb_msg_add_string(msg, "binary", "\xff\xff\0"); + assert_int_equal(ret, LDB_SUCCESS); + got_ldif = ldb_ldif_message_redacted_string(test_ctx->ldb, + test_ctx, + LDB_CHANGETYPE_ADD, + msg); + assert_string_equal(got_ldif, expected_ldif); + TALLOC_FREE(got_ldif); + assert_int_equal(ret, 0); +} + +static int ldbtest_setup(void **state) +{ + struct ldbtest_ctx *test_ctx; + struct ldb_ldif *ldif; +#ifdef GUID_IDX + const char *index_ldif = \ + "dn: @INDEXLIST\n" + "@IDXGUID: objectUUID\n" + "@IDX_DN_GUID: GUID\n" + "\n"; +#else + const char *index_ldif = "\n"; +#endif + int ret; + + ldbtest_noconn_setup((void **) &test_ctx); + + ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL); + assert_int_equal(ret, 0); + + while ((ldif = ldb_ldif_read_string(test_ctx->ldb, &index_ldif))) { + ret = ldb_add(test_ctx->ldb, ldif->msg); + assert_int_equal(ret, LDB_SUCCESS); + } + *state = test_ctx; + return 0; +} + +static int ldbtest_teardown(void **state) +{ + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + ldbtest_noconn_teardown((void **) &test_ctx); + return 0; +} + +static void test_ldb_add(void **state) +{ + int ret; + struct ldb_message *msg; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + msg = ldb_msg_new(tmp_ctx); + assert_non_null(msg); + + msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test"); + assert_non_null(msg->dn); + + ret = ldb_msg_add_string(msg, "cn", "test_cn_val"); + assert_int_equal(ret, 0); + + ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef"); + assert_int_equal(ret, 0); + + ret = ldb_add(test_ctx->ldb, msg); + assert_int_equal(ret, 0); + + talloc_free(tmp_ctx); +} + +static void test_ldb_search(void **state) +{ + int ret; + struct ldb_message *msg; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + TALLOC_CTX *tmp_ctx; + struct ldb_dn *basedn; + struct ldb_dn *basedn2; + struct ldb_result *result = NULL; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test"); + assert_non_null(basedn); + + ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn, + LDB_SCOPE_BASE, NULL, NULL); + assert_int_equal(ret, 0); + assert_non_null(result); + assert_int_equal(result->count, 0); + + msg = ldb_msg_new(tmp_ctx); + assert_non_null(msg); + + msg->dn = basedn; + assert_non_null(msg->dn); + + ret = ldb_msg_add_string(msg, "cn", "test_cn_val1"); + assert_int_equal(ret, 0); + + ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcde1"); + assert_int_equal(ret, 0); + + ret = ldb_add(test_ctx->ldb, msg); + assert_int_equal(ret, 0); + + basedn2 = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test2"); + assert_non_null(basedn2); + + msg = ldb_msg_new(tmp_ctx); + assert_non_null(msg); + + msg->dn = basedn2; + assert_non_null(msg->dn); + + ret = ldb_msg_add_string(msg, "cn", "test_cn_val2"); + assert_int_equal(ret, 0); + + ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcde2"); + assert_int_equal(ret, 0); + + ret = ldb_add(test_ctx->ldb, msg); + assert_int_equal(ret, 0); + + ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn, + LDB_SCOPE_BASE, NULL, NULL); + assert_int_equal(ret, 0); + assert_non_null(result); + assert_int_equal(result->count, 1); + assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn), + ldb_dn_get_linearized(basedn)); + + ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn2, + LDB_SCOPE_BASE, NULL, NULL); + assert_int_equal(ret, 0); + assert_non_null(result); + assert_int_equal(result->count, 1); + assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn), + ldb_dn_get_linearized(basedn2)); + + talloc_free(tmp_ctx); +} + +static int base_search_count(struct ldbtest_ctx *test_ctx, const char *entry_dn) +{ + TALLOC_CTX *tmp_ctx; + struct ldb_dn *basedn; + struct ldb_result *result = NULL; + int ret; + int count; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", entry_dn); + assert_non_null(basedn); + + ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn, + LDB_SCOPE_BASE, NULL, NULL); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(result); + + count = result->count; + talloc_free(tmp_ctx); + return count; +} + +static int sub_search_count(struct ldbtest_ctx *test_ctx, + const char *base_dn, + const char *filter) +{ + TALLOC_CTX *tmp_ctx; + struct ldb_dn *basedn; + struct ldb_result *result = NULL; + int ret; + int count; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", base_dn); + assert_non_null(basedn); + + ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn, + LDB_SCOPE_SUBTREE, NULL, "%s", filter); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(result); + + count = result->count; + talloc_free(tmp_ctx); + return count; +} + +/* In general it would be better if utility test functions didn't assert + * but only returned a value, then assert in the test shows correct + * line + */ +static void assert_dn_exists(struct ldbtest_ctx *test_ctx, + const char *entry_dn) +{ + int count; + + count = base_search_count(test_ctx, entry_dn); + assert_int_equal(count, 1); +} + +static void assert_dn_doesnt_exist(struct ldbtest_ctx *test_ctx, + const char *entry_dn) +{ + int count; + + count = base_search_count(test_ctx, entry_dn); + assert_int_equal(count, 0); +} + +static void add_dn_with_cn(struct ldbtest_ctx *test_ctx, + struct ldb_dn *dn, + const char *cn_value, + const char *uuid_value) +{ + int ret; + TALLOC_CTX *tmp_ctx; + struct ldb_message *msg; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + assert_dn_doesnt_exist(test_ctx, + ldb_dn_get_linearized(dn)); + + msg = ldb_msg_new(tmp_ctx); + assert_non_null(msg); + msg->dn = dn; + + ret = ldb_msg_add_string(msg, "cn", cn_value); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_msg_add_string(msg, "objectUUID", uuid_value); + assert_int_equal(ret, 0); + + ret = ldb_add(test_ctx->ldb, msg); + assert_int_equal(ret, LDB_SUCCESS); + + assert_dn_exists(test_ctx, + ldb_dn_get_linearized(dn)); + talloc_free(tmp_ctx); +} + +static void test_ldb_del(void **state) +{ + int ret; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + const char *basedn = "dc=ldb_del_test"; + struct ldb_dn *dn; + + dn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s", basedn); + assert_non_null(dn); + + add_dn_with_cn(test_ctx, dn, + "test_del_cn_val", + "0123456789abcdef"); + + ret = ldb_delete(test_ctx->ldb, dn); + assert_int_equal(ret, LDB_SUCCESS); + + assert_dn_doesnt_exist(test_ctx, basedn); +} + +static void test_ldb_del_noexist(void **state) +{ + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + struct ldb_dn *basedn; + int ret; + + basedn = ldb_dn_new(test_ctx, test_ctx->ldb, "dc=nosuchplace"); + assert_non_null(basedn); + + ret = ldb_delete(test_ctx->ldb, basedn); + assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT); +} + +static void test_ldb_handle(void **state) +{ + int ret; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + TALLOC_CTX *tmp_ctx; + struct ldb_dn *basedn; + struct ldb_request *request = NULL; + struct ldb_request *request2 = NULL; + struct ldb_result *res = NULL; + const char *attrs[] = { "cn", NULL }; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test"); + assert_non_null(basedn); + + res = talloc_zero(tmp_ctx, struct ldb_result); + assert_non_null(res); + + ret = ldb_build_search_req(&request, test_ctx->ldb, tmp_ctx, + basedn, LDB_SCOPE_BASE, + NULL, attrs, NULL, res, + ldb_search_default_callback, + NULL); + assert_int_equal(ret, 0); + + /* We are against ldb_tdb, so expect private event contexts */ + assert_ptr_not_equal(ldb_handle_get_event_context(request->handle), + ldb_get_event_context(test_ctx->ldb)); + + ret = ldb_build_search_req(&request2, test_ctx->ldb, tmp_ctx, + basedn, LDB_SCOPE_BASE, + NULL, attrs, NULL, res, + ldb_search_default_callback, + request); + assert_int_equal(ret, 0); + + /* Expect that same event context will be chained */ + assert_ptr_equal(ldb_handle_get_event_context(request->handle), + ldb_handle_get_event_context(request2->handle)); + + /* Now force this to use the global context */ + ldb_handle_use_global_event_context(request2->handle); + assert_ptr_equal(ldb_handle_get_event_context(request2->handle), + ldb_get_event_context(test_ctx->ldb)); + + talloc_free(tmp_ctx); +} + +static void test_ldb_build_search_req(void **state) +{ + int ret; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + TALLOC_CTX *tmp_ctx; + struct ldb_dn *basedn; + struct ldb_request *request = NULL; + struct ldb_request *request2 = NULL; + struct ldb_result *res = NULL; + const char *attrs[] = { "cn", NULL }; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test"); + assert_non_null(basedn); + + res = talloc_zero(tmp_ctx, struct ldb_result); + assert_non_null(res); + + ret = ldb_build_search_req(&request, test_ctx->ldb, tmp_ctx, + basedn, LDB_SCOPE_BASE, + NULL, attrs, NULL, res, + ldb_search_default_callback, + NULL); + assert_int_equal(ret, 0); + + assert_int_equal(request->operation, LDB_SEARCH); + assert_ptr_equal(request->op.search.base, basedn); + assert_int_equal(request->op.search.scope, LDB_SCOPE_BASE); + assert_non_null(request->op.search.tree); + assert_ptr_equal(request->op.search.attrs, attrs); + assert_ptr_equal(request->context, res); + assert_ptr_equal(request->callback, ldb_search_default_callback); + + ret = ldb_build_search_req(&request2, test_ctx->ldb, tmp_ctx, + basedn, LDB_SCOPE_BASE, + NULL, attrs, NULL, res, + ldb_search_default_callback, + request); + assert_int_equal(ret, 0); + assert_ptr_equal(request, request2->handle->parent); + assert_int_equal(request->starttime, request2->starttime); + assert_int_equal(request->timeout, request2->timeout); + + talloc_free(tmp_ctx); +} + +static void add_keyval(struct ldbtest_ctx *test_ctx, + const char *key, + const char *val, + const char *uuid) +{ + int ret; + struct ldb_message *msg; + + msg = ldb_msg_new(test_ctx); + assert_non_null(msg); + + msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s=%s", key, val); + assert_non_null(msg->dn); + + ret = ldb_msg_add_string(msg, key, val); + assert_int_equal(ret, 0); + + ret = ldb_msg_add_string(msg, "objectUUID", uuid); + assert_int_equal(ret, 0); + + ret = ldb_add(test_ctx->ldb, msg); + assert_int_equal(ret, 0); + + talloc_free(msg); +} + +static struct ldb_result *get_keyval(struct ldbtest_ctx *test_ctx, + const char *key, + const char *val) +{ + int ret; + struct ldb_result *result; + struct ldb_dn *basedn; + + basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s=%s", key, val); + assert_non_null(basedn); + + ret = ldb_search(test_ctx->ldb, test_ctx, &result, basedn, + LDB_SCOPE_BASE, NULL, NULL); + assert_int_equal(ret, 0); + + return result; +} + +static void test_transactions(void **state) +{ + int ret; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + struct ldb_result *res; + + /* start lev-0 transaction */ + ret = ldb_transaction_start(test_ctx->ldb); + assert_int_equal(ret, 0); + + add_keyval(test_ctx, "vegetable", "carrot", + "0123456789abcde0"); + + /* commit lev-0 transaction */ + ret = ldb_transaction_commit(test_ctx->ldb); + assert_int_equal(ret, 0); + + /* start another lev-1 nested transaction */ + ret = ldb_transaction_start(test_ctx->ldb); + assert_int_equal(ret, 0); + + add_keyval(test_ctx, "fruit", "apple", + "0123456789abcde1"); + + /* abort lev-1 nested transaction */ + ret = ldb_transaction_cancel(test_ctx->ldb); + assert_int_equal(ret, 0); + + res = get_keyval(test_ctx, "vegetable", "carrot"); + assert_non_null(res); + assert_int_equal(res->count, 1); + + res = get_keyval(test_ctx, "fruit", "apple"); + assert_non_null(res); + assert_int_equal(res->count, 0); +} + +static void test_nested_transactions(void **state) +{ + int ret; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + struct ldb_result *res; + + /* start lev-0 transaction */ + ret = ldb_transaction_start(test_ctx->ldb); + assert_int_equal(ret, 0); + + add_keyval(test_ctx, "vegetable", "carrot", + "0123456789abcde0"); + + + /* start another lev-1 nested transaction */ + ret = ldb_transaction_start(test_ctx->ldb); + assert_int_equal(ret, 0); + + add_keyval(test_ctx, "fruit", "apple", + "0123456789abcde1"); + + /* abort lev-1 nested transaction */ + ret = ldb_transaction_cancel(test_ctx->ldb); + assert_int_equal(ret, 0); + + /* commit lev-0 transaction */ + ret = ldb_transaction_commit(test_ctx->ldb); + assert_int_equal(ret, 0); + + res = get_keyval(test_ctx, "vegetable", "carrot"); + assert_non_null(res); + assert_int_equal(res->count, 1); + + /* This documents the current ldb behaviour, i.e. nested + * transactions are not supported. And the cancellation of the nested + * transaction has no effect. + */ + res = get_keyval(test_ctx, "fruit", "apple"); + assert_non_null(res); + assert_int_equal(res->count, 1); +} +struct ldb_mod_test_ctx { + struct ldbtest_ctx *ldb_test_ctx; + const char *entry_dn; +}; + +struct keyval { + const char *key; + const char *val; +}; + +static struct ldb_message *build_mod_msg(TALLOC_CTX *mem_ctx, + struct ldbtest_ctx *test_ctx, + const char *dn, + int modify_flags, + struct keyval *kvs) +{ + struct ldb_message *msg; + int ret; + int i; + + msg = ldb_msg_new(mem_ctx); + assert_non_null(msg); + + msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s", dn); + assert_non_null(msg->dn); + + for (i = 0; kvs[i].key != NULL; i++) { + if (modify_flags) { + ret = ldb_msg_add_empty(msg, kvs[i].key, + modify_flags, NULL); + assert_int_equal(ret, 0); + } + + if (kvs[i].val) { + ret = ldb_msg_add_string(msg, kvs[i].key, kvs[i].val); + assert_int_equal(ret, LDB_SUCCESS); + } + } + + return msg; +} + +static void ldb_test_add_data(TALLOC_CTX *mem_ctx, + struct ldbtest_ctx *ldb_test_ctx, + const char *basedn, + struct keyval *kvs) +{ + TALLOC_CTX *tmp_ctx; + struct ldb_message *msg; + struct ldb_result *result = NULL; + int ret; + + tmp_ctx = talloc_new(mem_ctx); + assert_non_null(tmp_ctx); + + msg = build_mod_msg(tmp_ctx, ldb_test_ctx, + basedn, 0, kvs); + assert_non_null(msg); + + ret = ldb_add(ldb_test_ctx->ldb, msg); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_search(ldb_test_ctx->ldb, tmp_ctx, &result, msg->dn, + LDB_SCOPE_BASE, NULL, NULL); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(result); + assert_int_equal(result->count, 1); + assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn), + ldb_dn_get_linearized(msg->dn)); + + talloc_free(tmp_ctx); +} + +static void ldb_test_remove_data(TALLOC_CTX *mem_ctx, + struct ldbtest_ctx *ldb_test_ctx, + const char *strdn) +{ + TALLOC_CTX *tmp_ctx; + struct ldb_dn *basedn; + int ret; + size_t count; + + tmp_ctx = talloc_new(mem_ctx); + assert_non_null(tmp_ctx); + + basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb, + "%s", strdn); + assert_non_null(basedn); + + ret = ldb_delete(ldb_test_ctx->ldb, basedn); + assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_NO_SUCH_OBJECT); + + count = base_search_count(ldb_test_ctx, ldb_dn_get_linearized(basedn)); + assert_int_equal(count, 0); + + talloc_free(tmp_ctx); +} + +static void mod_test_add_data(struct ldb_mod_test_ctx *mod_test_ctx, + struct keyval *kvs) +{ + ldb_test_add_data(mod_test_ctx, + mod_test_ctx->ldb_test_ctx, + mod_test_ctx->entry_dn, + kvs); +} + +static void mod_test_remove_data(struct ldb_mod_test_ctx *mod_test_ctx) +{ + ldb_test_remove_data(mod_test_ctx, + mod_test_ctx->ldb_test_ctx, + mod_test_ctx->entry_dn); +} + +static struct ldb_result *run_mod_test(struct ldb_mod_test_ctx *mod_test_ctx, + int modify_flags, + struct keyval *kvs) +{ + TALLOC_CTX *tmp_ctx; + struct ldb_result *res; + struct ldb_message *mod_msg; + struct ldb_dn *basedn; + struct ldbtest_ctx *ldb_test_ctx; + int ret; + + ldb_test_ctx = mod_test_ctx->ldb_test_ctx; + + tmp_ctx = talloc_new(mod_test_ctx); + assert_non_null(tmp_ctx); + + mod_msg = build_mod_msg(tmp_ctx, ldb_test_ctx, mod_test_ctx->entry_dn, + modify_flags, kvs); + assert_non_null(mod_msg); + + ret = ldb_modify(ldb_test_ctx->ldb, mod_msg); + assert_int_equal(ret, LDB_SUCCESS); + + basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb, + "%s", mod_test_ctx->entry_dn); + assert_non_null(basedn); + + ret = ldb_search(ldb_test_ctx->ldb, mod_test_ctx, &res, basedn, + LDB_SCOPE_BASE, NULL, NULL); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(res); + assert_int_equal(res->count, 1); + assert_string_equal(ldb_dn_get_linearized(res->msgs[0]->dn), + ldb_dn_get_linearized(mod_msg->dn)); + + talloc_free(tmp_ctx); + return res; +} + +static int ldb_modify_test_setup(void **state) +{ + struct ldbtest_ctx *ldb_test_ctx; + struct ldb_mod_test_ctx *mod_test_ctx; + struct keyval kvs[] = { + { "cn", "test_mod_cn" }, + { "objectUUID", "0123456789abcdef"}, + { NULL, NULL }, + }; + + ldbtest_setup((void **) &ldb_test_ctx); + + mod_test_ctx = talloc(ldb_test_ctx, struct ldb_mod_test_ctx); + assert_non_null(mod_test_ctx); + + mod_test_ctx->entry_dn = "dc=mod_test_entry"; + mod_test_ctx->ldb_test_ctx = ldb_test_ctx; + + mod_test_remove_data(mod_test_ctx); + mod_test_add_data(mod_test_ctx, kvs); + *state = mod_test_ctx; + return 0; +} + +static int ldb_modify_test_teardown(void **state) +{ + struct ldb_mod_test_ctx *mod_test_ctx = \ + talloc_get_type_abort(*state, + struct ldb_mod_test_ctx); + struct ldbtest_ctx *ldb_test_ctx; + + ldb_test_ctx = mod_test_ctx->ldb_test_ctx; + + mod_test_remove_data(mod_test_ctx); + talloc_free(mod_test_ctx); + + ldbtest_teardown((void **) &ldb_test_ctx); + return 0; +} + +static void test_ldb_modify_add_key(void **state) +{ + struct ldb_mod_test_ctx *mod_test_ctx = \ + talloc_get_type_abort(*state, + struct ldb_mod_test_ctx); + struct keyval mod_kvs[] = { + { "name", "test_mod_name" }, + { NULL, NULL }, + }; + struct ldb_result *res; + struct ldb_message_element *el; + + res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs); + assert_non_null(res); + + /* Check cn is intact and name was added */ + assert_int_equal(res->count, 1); + el = ldb_msg_find_element(res->msgs[0], "cn"); + assert_non_null(el); + assert_int_equal(el->num_values, 1); + assert_string_equal(el->values[0].data, "test_mod_cn"); + + el = ldb_msg_find_element(res->msgs[0], "name"); + assert_non_null(el); + assert_int_equal(el->num_values, 1); + assert_string_equal(el->values[0].data, "test_mod_name"); +} + +static void test_ldb_modify_extend_key(void **state) +{ + struct ldb_mod_test_ctx *mod_test_ctx = \ + talloc_get_type_abort(*state, + struct ldb_mod_test_ctx); + struct keyval mod_kvs[] = { + { "cn", "test_mod_cn2" }, + { NULL, NULL }, + }; + struct ldb_result *res; + struct ldb_message_element *el; + + res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs); + assert_non_null(res); + + /* Check cn was extended with another value */ + assert_int_equal(res->count, 1); + el = ldb_msg_find_element(res->msgs[0], "cn"); + assert_non_null(el); + assert_int_equal(el->num_values, 2); + assert_string_equal(el->values[0].data, "test_mod_cn"); + assert_string_equal(el->values[1].data, "test_mod_cn2"); +} + +static void test_ldb_modify_add_key_noval(void **state) +{ + struct ldb_mod_test_ctx *mod_test_ctx = \ + talloc_get_type_abort(*state, + struct ldb_mod_test_ctx); + struct ldb_message *mod_msg; + struct ldbtest_ctx *ldb_test_ctx; + struct ldb_message_element *el; + int ret; + + ldb_test_ctx = mod_test_ctx->ldb_test_ctx; + + mod_msg = ldb_msg_new(mod_test_ctx); + assert_non_null(mod_msg); + + mod_msg->dn = ldb_dn_new_fmt(mod_msg, ldb_test_ctx->ldb, + "%s", mod_test_ctx->entry_dn); + assert_non_null(mod_msg->dn); + + el = talloc_zero(mod_msg, struct ldb_message_element); + el->flags = LDB_FLAG_MOD_ADD; + assert_non_null(el); + el->name = talloc_strdup(el, "cn"); + assert_non_null(el->name); + + mod_msg->elements = el; + mod_msg->num_elements = 1; + + ret = ldb_modify(ldb_test_ctx->ldb, mod_msg); + assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION); +} + +static void test_ldb_modify_replace_key(void **state) +{ + struct ldb_mod_test_ctx *mod_test_ctx = \ + talloc_get_type_abort(*state, + struct ldb_mod_test_ctx); + const char *new_cn = "new_cn"; + struct keyval mod_kvs[] = { + { "cn", new_cn }, + { NULL, NULL }, + }; + struct ldb_result *res; + struct ldb_message_element *el; + + res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs); + assert_non_null(res); + + /* Check cn was replaced */ + assert_int_equal(res->count, 1); + el = ldb_msg_find_element(res->msgs[0], "cn"); + assert_non_null(el); + assert_int_equal(el->num_values, 1); + assert_string_equal(el->values[0].data, new_cn); +} + +static void test_ldb_modify_replace_noexist_key(void **state) +{ + struct ldb_mod_test_ctx *mod_test_ctx = \ + talloc_get_type_abort(*state, + struct ldb_mod_test_ctx); + struct keyval mod_kvs[] = { + { "name", "name_val" }, + { NULL, NULL }, + }; + struct ldb_result *res; + struct ldb_message_element *el; + + res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs); + assert_non_null(res); + + /* Check cn is intact and name was added */ + assert_int_equal(res->count, 1); + el = ldb_msg_find_element(res->msgs[0], "cn"); + assert_non_null(el); + assert_int_equal(el->num_values, 1); + assert_string_equal(el->values[0].data, "test_mod_cn"); + + el = ldb_msg_find_element(res->msgs[0], mod_kvs[0].key); + assert_non_null(el); + assert_int_equal(el->num_values, 1); + assert_string_equal(el->values[0].data, mod_kvs[0].val); +} + +static void test_ldb_modify_replace_zero_vals(void **state) +{ + struct ldb_mod_test_ctx *mod_test_ctx = \ + talloc_get_type_abort(*state, + struct ldb_mod_test_ctx); + struct ldb_message_element *el; + struct ldb_result *res; + struct keyval kvs[] = { + { "cn", NULL }, + { NULL, NULL }, + }; + + /* cn must be gone */ + res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs); + assert_non_null(res); + el = ldb_msg_find_element(res->msgs[0], "cn"); + assert_null(el); +} + +static void test_ldb_modify_replace_noexist_key_zero_vals(void **state) +{ + struct ldb_mod_test_ctx *mod_test_ctx = \ + talloc_get_type_abort(*state, + struct ldb_mod_test_ctx); + struct ldb_message_element *el; + struct ldb_result *res; + struct keyval kvs[] = { + { "noexist_key", NULL }, + { NULL, NULL }, + }; + + /* cn must be gone */ + res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs); + assert_non_null(res); + + /* cn should be intact */ + el = ldb_msg_find_element(res->msgs[0], "cn"); + assert_non_null(el); +} + +static void test_ldb_modify_del_key(void **state) +{ + struct ldb_mod_test_ctx *mod_test_ctx = \ + talloc_get_type_abort(*state, + struct ldb_mod_test_ctx); + struct ldb_message_element *el; + struct ldb_result *res; + struct keyval kvs[] = { + { "cn", NULL }, + { NULL, NULL }, + }; + + /* cn must be gone */ + res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs); + assert_non_null(res); + + el = ldb_msg_find_element(res->msgs[0], "cn"); + assert_null(el); +} + +static void test_ldb_modify_del_keyval(void **state) +{ + struct ldb_mod_test_ctx *mod_test_ctx = \ + talloc_get_type_abort(*state, + struct ldb_mod_test_ctx); + struct ldb_message_element *el; + struct ldb_result *res; + struct keyval kvs[] = { + { "cn", "test_mod_cn" }, + { NULL, NULL }, + }; + + /* cn must be gone */ + res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs); + assert_non_null(res); + + el = ldb_msg_find_element(res->msgs[0], "cn"); + assert_null(el); +} + +struct search_test_ctx { + struct ldbtest_ctx *ldb_test_ctx; + const char *base_dn; +}; + +static char *get_full_dn(TALLOC_CTX *mem_ctx, + struct search_test_ctx *search_test_ctx, + const char *rdn) +{ + char *full_dn; + + full_dn = talloc_asprintf(mem_ctx, + "%s,%s", rdn, search_test_ctx->base_dn); + assert_non_null(full_dn); + + return full_dn; +} + +static void search_test_add_data(struct search_test_ctx *search_test_ctx, + const char *rdn, + struct keyval *kvs) +{ + char *full_dn; + + full_dn = get_full_dn(search_test_ctx, search_test_ctx, rdn); + + ldb_test_add_data(search_test_ctx, + search_test_ctx->ldb_test_ctx, + full_dn, + kvs); +} + +static void search_test_remove_data(struct search_test_ctx *search_test_ctx, + const char *rdn) +{ + char *full_dn; + + full_dn = talloc_asprintf(search_test_ctx, + "%s,%s", rdn, search_test_ctx->base_dn); + assert_non_null(full_dn); + + ldb_test_remove_data(search_test_ctx, + search_test_ctx->ldb_test_ctx, + full_dn); +} + +static int ldb_search_test_setup(void **state) +{ + struct ldbtest_ctx *ldb_test_ctx; + struct search_test_ctx *search_test_ctx; + struct keyval kvs[] = { + { "cn", "test_search_cn" }, + { "cn", "test_search_cn2" }, + { "uid", "test_search_uid" }, + { "uid", "test_search_uid2" }, + { "objectUUID", "0123456789abcde0"}, + { NULL, NULL }, + }; + struct keyval kvs2[] = { + { "cn", "test_search_2_cn" }, + { "cn", "test_search_2_cn2" }, + { "uid", "test_search_2_uid" }, + { "uid", "test_search_2_uid2" }, + { "objectUUID", "0123456789abcde1"}, + { NULL, NULL }, + }; + + ldbtest_setup((void **) &ldb_test_ctx); + + search_test_ctx = talloc(ldb_test_ctx, struct search_test_ctx); + assert_non_null(search_test_ctx); + + search_test_ctx->base_dn = "dc=search_test_entry"; + search_test_ctx->ldb_test_ctx = ldb_test_ctx; + + search_test_remove_data(search_test_ctx, "cn=test_search_cn"); + search_test_add_data(search_test_ctx, "cn=test_search_cn", kvs); + + search_test_remove_data(search_test_ctx, "cn=test_search_2_cn"); + search_test_add_data(search_test_ctx, "cn=test_search_2_cn", kvs2); + + *state = search_test_ctx; + return 0; +} + +static int ldb_search_test_teardown(void **state) +{ + struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, + struct search_test_ctx); + struct ldbtest_ctx *ldb_test_ctx; + + ldb_test_ctx = search_test_ctx->ldb_test_ctx; + + search_test_remove_data(search_test_ctx, "cn=test_search_cn"); + search_test_remove_data(search_test_ctx, "cn=test_search_2_cn"); + ldbtest_teardown((void **) &ldb_test_ctx); + return 0; +} + +static void assert_attr_has_vals(struct ldb_message *msg, + const char *attr, + const char *vals[], + const size_t nvals) +{ + struct ldb_message_element *el; + size_t i; + + el = ldb_msg_find_element(msg, attr); + assert_non_null(el); + + assert_int_equal(el->num_values, nvals); + for (i = 0; i < nvals; i++) { + assert_string_equal(el->values[i].data, + vals[i]); + } +} + +static void assert_has_no_attr(struct ldb_message *msg, + const char *attr) +{ + struct ldb_message_element *el; + + el = ldb_msg_find_element(msg, attr); + assert_null(el); +} + +static bool has_dn(struct ldb_message *msg, const char *dn) +{ + const char *msgdn; + + msgdn = ldb_dn_get_linearized(msg->dn); + if (strcmp(dn, msgdn) == 0) { + return true; + } + + return false; +} + +static void test_search_match_none(void **state) +{ + struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, + struct search_test_ctx); + size_t count; + + count = base_search_count(search_test_ctx->ldb_test_ctx, + "dc=no_such_entry"); + assert_int_equal(count, 0); +} + +static void test_search_match_one(void **state) +{ + struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, + struct search_test_ctx); + int ret; + struct ldb_dn *basedn; + struct ldb_result *result = NULL; + const char *cn_vals[] = { "test_search_cn", + "test_search_cn2" }; + const char *uid_vals[] = { "test_search_uid", + "test_search_uid2" }; + + basedn = ldb_dn_new_fmt(search_test_ctx, + search_test_ctx->ldb_test_ctx->ldb, + "%s", + search_test_ctx->base_dn); + assert_non_null(basedn); + + ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, + search_test_ctx, + &result, + basedn, + LDB_SCOPE_SUBTREE, NULL, + "cn=test_search_cn"); + assert_int_equal(ret, 0); + assert_non_null(result); + assert_int_equal(result->count, 1); + + assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2); + assert_attr_has_vals(result->msgs[0], "uid", uid_vals, 2); +} + +static void test_search_match_filter(void **state) +{ + struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, + struct search_test_ctx); + int ret; + struct ldb_dn *basedn; + struct ldb_result *result = NULL; + const char *cn_vals[] = { "test_search_cn", + "test_search_cn2" }; + const char *attrs[] = { "cn", NULL }; + + basedn = ldb_dn_new_fmt(search_test_ctx, + search_test_ctx->ldb_test_ctx->ldb, + "%s", + search_test_ctx->base_dn); + assert_non_null(basedn); + + ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, + search_test_ctx, + &result, + basedn, + LDB_SCOPE_SUBTREE, + attrs, + "cn=test_search_cn"); + assert_int_equal(ret, 0); + assert_non_null(result); + assert_int_equal(result->count, 1); + + assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2); + assert_has_no_attr(result->msgs[0], "uid"); +} + +static void assert_expected(struct search_test_ctx *search_test_ctx, + struct ldb_message *msg) +{ + char *full_dn1; + char *full_dn2; + const char *cn_vals[] = { "test_search_cn", + "test_search_cn2" }; + const char *uid_vals[] = { "test_search_uid", + "test_search_uid2" }; + const char *cn2_vals[] = { "test_search_2_cn", + "test_search_2_cn2" }; + const char *uid2_vals[] = { "test_search_2_uid", + "test_search_2_uid2" }; + + full_dn1 = get_full_dn(search_test_ctx, + search_test_ctx, + "cn=test_search_cn"); + + full_dn2 = get_full_dn(search_test_ctx, + search_test_ctx, + "cn=test_search_2_cn"); + + if (has_dn(msg, full_dn1) == true) { + assert_attr_has_vals(msg, "cn", cn_vals, 2); + assert_attr_has_vals(msg, "uid", uid_vals, 2); + } else if (has_dn(msg, full_dn2) == true) { + assert_attr_has_vals(msg, "cn", cn2_vals, 2); + assert_attr_has_vals(msg, "uid", uid2_vals, 2); + } else { + fail(); + } +} + +static void test_search_match_both(void **state) +{ + struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, + struct search_test_ctx); + int ret; + struct ldb_dn *basedn; + struct ldb_result *result = NULL; + + basedn = ldb_dn_new_fmt(search_test_ctx, + search_test_ctx->ldb_test_ctx->ldb, + "%s", + search_test_ctx->base_dn); + assert_non_null(basedn); + + ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, + search_test_ctx, + &result, + basedn, + LDB_SCOPE_SUBTREE, NULL, + "cn=test_search_*"); + assert_int_equal(ret, 0); + assert_non_null(result); + assert_int_equal(result->count, 2); + + assert_expected(search_test_ctx, result->msgs[0]); + assert_expected(search_test_ctx, result->msgs[1]); +} + +static void test_search_match_basedn(void **state) +{ + struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, + struct search_test_ctx); + int ret; + struct ldb_dn *basedn; + struct ldb_result *result = NULL; + struct ldb_message *msg; + + basedn = ldb_dn_new_fmt(search_test_ctx, + search_test_ctx->ldb_test_ctx->ldb, + "dc=nosuchdn"); + assert_non_null(basedn); + + ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, + search_test_ctx, + &result, + basedn, + LDB_SCOPE_SUBTREE, NULL, + "cn=*"); + assert_int_equal(ret, 0); + + /* Add 'checkBaseOnSearch' to @OPTIONS */ + msg = ldb_msg_new(search_test_ctx); + assert_non_null(msg); + + msg->dn = ldb_dn_new_fmt(msg, + search_test_ctx->ldb_test_ctx->ldb, + "@OPTIONS"); + assert_non_null(msg->dn); + + ret = ldb_msg_add_string(msg, "checkBaseOnSearch", "TRUE"); + assert_int_equal(ret, 0); + + ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb, msg); + assert_int_equal(ret, 0); + + /* Search again */ + /* The search should return LDB_ERR_NO_SUCH_OBJECT */ + ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, + search_test_ctx, + &result, + basedn, + LDB_SCOPE_SUBTREE, NULL, + "cn=*"); + assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT); + + ret = ldb_delete(search_test_ctx->ldb_test_ctx->ldb, msg->dn); + assert_int_equal(ret, 0); +} + + +/* + * This test is complex. + * The purpose is to test for a deadlock detected between ldb_search() + * and ldb_transaction_commit(). The deadlock happens if in process + * (1) and (2): + * - (1) the all-record lock is taken in ltdb_search() + * - (2) the ldb_transaction_start() call is made + * - (1) an un-indexed search starts (forced here by doing it in + * the callback + * - (2) the ldb_transaction_commit() is called. + * This returns LDB_ERR_BUSY if the deadlock is detected + * + * With ldb 1.1.31 and tdb 1.3.12 we avoid this only due to a missing + * lock call in ltdb_search() due to a refcounting bug in + * ltdb_lock_read() + */ + +struct search_against_transaction_ctx { + struct ldbtest_ctx *test_ctx; + int res_count; + pid_t child_pid; + struct ldb_dn *basedn; +}; + +static int test_ldb_search_against_transaction_callback2(struct ldb_request *req, + struct ldb_reply *ares) +{ + struct search_against_transaction_ctx *ctx = req->context; + switch (ares->type) { + case LDB_REPLY_ENTRY: + ctx->res_count++; + if (ctx->res_count != 1) { + return LDB_SUCCESS; + } + + break; + + case LDB_REPLY_REFERRAL: + break; + + case LDB_REPLY_DONE: + return ldb_request_done(req, LDB_SUCCESS); + } + + return 0; + +} + +/* + * This purpose of this callback is to trigger a transaction in + * the child process while the all-record lock is held, but before + * we take any locks in the tdb_traverse_read() handler. + * + * In tdb 1.3.12 tdb_traverse_read() take the read transaction lock + * however in ldb 1.1.31 ltdb_search() forgets to take the all-record + * lock (except the very first time) due to a ref-counting bug. + * + */ + +static int test_ldb_search_against_transaction_callback1(struct ldb_request *req, + struct ldb_reply *ares) +{ + int ret, ret2; + int pipes[2]; + char buf[2]; + struct search_against_transaction_ctx *ctx = req->context; + switch (ares->type) { + case LDB_REPLY_ENTRY: + break; + + case LDB_REPLY_REFERRAL: + return LDB_SUCCESS; + + case LDB_REPLY_DONE: + return ldb_request_done(req, LDB_SUCCESS); + } + + ret = pipe(pipes); + assert_int_equal(ret, 0); + + ctx->child_pid = fork(); + if (ctx->child_pid == 0) { + TALLOC_CTX *tmp_ctx = NULL; + struct ldb_message *msg; + TALLOC_FREE(ctx->test_ctx->ldb); + TALLOC_FREE(ctx->test_ctx->ev); + close(pipes[0]); + ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx); + if (ctx->test_ctx->ev == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ctx->test_ctx->ldb = ldb_init(ctx->test_ctx, + ctx->test_ctx->ev); + if (ctx->test_ctx->ldb == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_connect(ctx->test_ctx->ldb, + ctx->test_ctx->dbpath, 0, NULL); + if (ret != LDB_SUCCESS) { + exit(ret); + } + + tmp_ctx = talloc_new(ctx->test_ctx); + if (tmp_ctx == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + msg = ldb_msg_new(tmp_ctx); + if (msg == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb, + "dc=test"); + if (msg->dn == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_msg_add_string(msg, "cn", "test_cn_val"); + if (ret != 0) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_transaction_start(ctx->test_ctx->ldb); + if (ret != 0) { + exit(ret); + } + + ret = write(pipes[1], "GO", 2); + if (ret != 2) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_msg_add_string(msg, "objectUUID", + "0123456789abcdef"); + if (ret != 0) { + exit(ret); + } + + ret = ldb_add(ctx->test_ctx->ldb, msg); + if (ret != 0) { + exit(ret); + } + + ret = ldb_transaction_commit(ctx->test_ctx->ldb); + exit(ret); + } + close(pipes[1]); + ret = read(pipes[0], buf, 2); + assert_int_equal(ret, 2); + + /* This search must be unindexed (ie traverse in tdb) */ + ret = ldb_build_search_req(&req, + ctx->test_ctx->ldb, + ctx->test_ctx, + ctx->basedn, + LDB_SCOPE_SUBTREE, + "cn=*", NULL, + NULL, + ctx, + test_ldb_search_against_transaction_callback2, + NULL); + /* + * we don't assert on these return codes until after the search is + * finished, or the clean up will fail because we hold locks. + */ + + ret2 = ldb_request(ctx->test_ctx->ldb, req); + + if (ret2 == LDB_SUCCESS) { + ret2 = ldb_wait(req->handle, LDB_WAIT_ALL); + } + assert_int_equal(ret, 0); + assert_int_equal(ret2, 0); + assert_int_equal(ctx->res_count, 2); + + return LDB_SUCCESS; +} + +static void test_ldb_search_against_transaction(void **state) +{ + struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, + struct search_test_ctx); + struct search_against_transaction_ctx + ctx = + { .res_count = 0, + .test_ctx = search_test_ctx->ldb_test_ctx + }; + + int ret; + struct ldb_request *req; + pid_t pid; + int wstatus; + struct ldb_dn *base_search_dn; + + tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev); + + base_search_dn + = ldb_dn_new_fmt(search_test_ctx, + search_test_ctx->ldb_test_ctx->ldb, + "cn=test_search_cn,%s", + search_test_ctx->base_dn); + assert_non_null(base_search_dn); + + ctx.basedn + = ldb_dn_new_fmt(search_test_ctx, + search_test_ctx->ldb_test_ctx->ldb, + "%s", + search_test_ctx->base_dn); + assert_non_null(ctx.basedn); + + + /* This search must be indexed (ie no traverse in tdb) */ + ret = ldb_build_search_req(&req, + search_test_ctx->ldb_test_ctx->ldb, + search_test_ctx, + base_search_dn, + LDB_SCOPE_BASE, + "cn=*", NULL, + NULL, + &ctx, + test_ldb_search_against_transaction_callback1, + NULL); + assert_int_equal(ret, 0); + ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req); + + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + assert_int_equal(ret, 0); + assert_int_equal(ctx.res_count, 2); + + pid = waitpid(ctx.child_pid, &wstatus, 0); + assert_int_equal(pid, ctx.child_pid); + + assert_true(WIFEXITED(wstatus)); + + assert_int_equal(WEXITSTATUS(wstatus), 0); + + +} + +/* + * This test is also complex. + * The purpose is to test if a modify can occur during an ldb_search() + * This would be a failure if if in process + * (1) and (2): + * - (1) ltdb_search() starts and calls back for one entry + * - (2) one of the entries to be matched is modified + * - (1) the indexed search tries to return the modified entry, but + * it is no longer found, either: + * - despite it still matching (dn changed) + * - it no longer matching (attrs changed) + * + * We also try un-indexed to show that the behaviour differs on this + * point, which it should not (an index should only impact search + * speed). + */ + +struct modify_during_search_test_ctx { + struct ldbtest_ctx *test_ctx; + int res_count; + pid_t child_pid; + struct ldb_dn *basedn; + bool got_cn; + bool got_2_cn; + bool rename; +}; + +/* + * This purpose of this callback is to trigger a write in + * the child process while a search is in progress. + * + * In tdb 1.3.12 tdb_traverse_read() take the read transaction lock + * however in ldb 1.1.31 ltdb_search() forgets to take the all-record + * lock (except the very first time) due to a ref-counting bug. + * + * We assume that if the write will proceed, it will proceed in a 3 + * second window after the function is called. + */ + +static int test_ldb_modify_during_search_callback1(struct ldb_request *req, + struct ldb_reply *ares) +{ + int ret; + int pipes[2]; + char buf[2]; + struct modify_during_search_test_ctx *ctx = req->context; + switch (ares->type) { + case LDB_REPLY_ENTRY: + { + const struct ldb_val *cn_val + = ldb_dn_get_component_val(ares->message->dn, 0); + const char *cn = (char *)cn_val->data; + ctx->res_count++; + if (strcmp(cn, "test_search_cn") == 0) { + ctx->got_cn = true; + } else if (strcmp(cn, "test_search_2_cn") == 0) { + ctx->got_2_cn = true; + } + if (ctx->res_count == 2) { + return LDB_SUCCESS; + } + break; + } + case LDB_REPLY_REFERRAL: + return LDB_SUCCESS; + + case LDB_REPLY_DONE: + return ldb_request_done(req, LDB_SUCCESS); + } + + ret = pipe(pipes); + assert_int_equal(ret, 0); + + ctx->child_pid = fork(); + if (ctx->child_pid == 0 && ctx->rename) { + TALLOC_CTX *tmp_ctx = NULL; + struct ldb_dn *dn, *new_dn; + TALLOC_FREE(ctx->test_ctx->ldb); + TALLOC_FREE(ctx->test_ctx->ev); + close(pipes[0]); + ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx); + if (ctx->test_ctx->ev == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ctx->test_ctx->ldb = ldb_init(ctx->test_ctx, + ctx->test_ctx->ev); + if (ctx->test_ctx->ldb == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_connect(ctx->test_ctx->ldb, + ctx->test_ctx->dbpath, 0, NULL); + if (ret != LDB_SUCCESS) { + exit(ret); + } + + tmp_ctx = talloc_new(ctx->test_ctx); + if (tmp_ctx == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + if (ctx->got_cn) { + /* Modify the other one */ + dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb, + "cn=test_search_2_cn," + "dc=search_test_entry"); + } else { + dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb, + "cn=test_search_cn," + "dc=search_test_entry"); + } + if (dn == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + new_dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb, + "cn=test_search_cn_renamed," + "dc=search_test_entry"); + if (new_dn == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_transaction_start(ctx->test_ctx->ldb); + if (ret != 0) { + exit(ret); + } + + if (write(pipes[1], "GO", 2) != 2) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_rename(ctx->test_ctx->ldb, dn, new_dn); + if (ret != 0) { + exit(ret); + } + + ret = ldb_transaction_commit(ctx->test_ctx->ldb); + exit(ret); + + } else if (ctx->child_pid == 0) { + TALLOC_CTX *tmp_ctx = NULL; + struct ldb_message *msg; + struct ldb_message_element *el; + TALLOC_FREE(ctx->test_ctx->ldb); + TALLOC_FREE(ctx->test_ctx->ev); + close(pipes[0]); + ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx); + if (ctx->test_ctx->ev == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ctx->test_ctx->ldb = ldb_init(ctx->test_ctx, + ctx->test_ctx->ev); + if (ctx->test_ctx->ldb == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_connect(ctx->test_ctx->ldb, + ctx->test_ctx->dbpath, 0, NULL); + if (ret != LDB_SUCCESS) { + exit(ret); + } + + tmp_ctx = talloc_new(ctx->test_ctx); + if (tmp_ctx == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + msg = ldb_msg_new(tmp_ctx); + if (msg == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + if (ctx->got_cn) { + /* Modify the other one */ + msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb, + "cn=test_search_2_cn," + "dc=search_test_entry"); + } else { + msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb, + "cn=test_search_cn," + "dc=search_test_entry"); + } + if (msg->dn == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_msg_add_string(msg, "filterAttr", "TRUE"); + if (ret != 0) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + el = ldb_msg_find_element(msg, "filterAttr"); + if (el == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + el->flags = LDB_FLAG_MOD_REPLACE; + + ret = ldb_transaction_start(ctx->test_ctx->ldb); + if (ret != 0) { + exit(ret); + } + + if (write(pipes[1], "GO", 2) != 2) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_modify(ctx->test_ctx->ldb, msg); + if (ret != 0) { + exit(ret); + } + + ret = ldb_transaction_commit(ctx->test_ctx->ldb); + exit(ret); + } + + /* + * With TDB 1.3.13 and before "tdb: Remove locking from tdb_traverse_read()" + * we will hang here because the child process can not proceed to + * sending the "GO" as it is blocked at ldb_transaction_start(). + */ + + close(pipes[1]); + ret = read(pipes[0], buf, 2); + assert_int_equal(ret, 2); + + sleep(3); + + return LDB_SUCCESS; +} + +static void test_ldb_modify_during_search(void **state, bool add_index, + bool rename) +{ + struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, + struct search_test_ctx); + struct modify_during_search_test_ctx + ctx = + { .res_count = 0, + .test_ctx = search_test_ctx->ldb_test_ctx, + .rename = rename + }; + + int ret; + struct ldb_request *req; + pid_t pid; + int wstatus; + + if (add_index) { + struct ldb_message *msg; + struct ldb_dn *indexlist = ldb_dn_new(search_test_ctx, + search_test_ctx->ldb_test_ctx->ldb, + "@INDEXLIST"); + assert_non_null(indexlist); + + msg = ldb_msg_new(search_test_ctx); + assert_non_null(msg); + + msg->dn = indexlist; + + ret = ldb_msg_add_string(msg, "@IDXATTR", "cn"); + assert_int_equal(ret, LDB_SUCCESS); + ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb, + msg); + if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { + msg->elements[0].flags = LDB_FLAG_MOD_ADD; + ret = ldb_modify(search_test_ctx->ldb_test_ctx->ldb, + msg); + } + assert_int_equal(ret, LDB_SUCCESS); + } + + tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev); + + ctx.basedn + = ldb_dn_new_fmt(search_test_ctx, + search_test_ctx->ldb_test_ctx->ldb, + "%s", + search_test_ctx->base_dn); + assert_non_null(ctx.basedn); + + + /* + * This search must be over multiple items, and should include + * the new name after a rename, to show that it would match + * both before and after that modify + */ + ret = ldb_build_search_req(&req, + search_test_ctx->ldb_test_ctx->ldb, + search_test_ctx, + ctx.basedn, + LDB_SCOPE_SUBTREE, + "(&(!(filterAttr=*))" + "(|(cn=test_search_cn_renamed)" + "(cn=test_search_cn)" + "(cn=test_search_2_cn)" + "))", + NULL, + NULL, + &ctx, + test_ldb_modify_during_search_callback1, + NULL); + assert_int_equal(ret, 0); + ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req); + + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + assert_int_equal(ret, 0); + assert_int_equal(ctx.res_count, 2); + assert_int_equal(ctx.got_cn, true); + assert_int_equal(ctx.got_2_cn, true); + + pid = waitpid(ctx.child_pid, &wstatus, 0); + assert_int_equal(pid, ctx.child_pid); + + assert_true(WIFEXITED(wstatus)); + + assert_int_equal(WEXITSTATUS(wstatus), 0); + + +} + +static void test_ldb_modify_during_indexed_search(void **state) +{ + test_ldb_modify_during_search(state, true, false); +} + +static void test_ldb_modify_during_unindexed_search(void **state) +{ + test_ldb_modify_during_search(state, false, false); +} + +static void test_ldb_rename_during_indexed_search(void **state) +{ + test_ldb_modify_during_search(state, true, true); +} + +static void test_ldb_rename_during_unindexed_search(void **state) +{ + test_ldb_modify_during_search(state, false, true); +} + +/* + * This test is also complex. + * + * The purpose is to test if a modify can occur during an ldb_search() + * before the end of the callback + * + * This would be a failure if if in process + * (1) and (2): + * - (1) ldb_search() starts and calls back for a number of entries + * - (2) an entry in the DB is allowed to change before the callback returns + * - (1) the callback can see the modification + * + */ + +/* + * This purpose of this callback is to trigger a write in + * the child process while a search DONE callback is in progress. + * + * In ldb 1.1.31 ldb_search() omitted to take a all-record + * lock for the full duration of the search and callbacks + * + * We assume that if the write will proceed, it will proceed in a 3 + * second window after the function is called. + */ + +static int test_ldb_modify_during_whole_search_callback1(struct ldb_request *req, + struct ldb_reply *ares) +{ + int ret; + int pipes[2]; + char buf[2]; + struct modify_during_search_test_ctx *ctx = req->context; + struct ldb_dn *search_dn; + struct ldb_result *res2; + unsigned res_count; + switch (ares->type) { + case LDB_REPLY_ENTRY: + case LDB_REPLY_REFERRAL: + return LDB_SUCCESS; + + case LDB_REPLY_DONE: + break; + } + + ret = pipe(pipes); + assert_int_equal(ret, 0); + + ctx->child_pid = fork(); + if (ctx->child_pid == 0) { + TALLOC_CTX *tmp_ctx = NULL; + struct ldb_message *msg; + struct ldb_message_element *el; + TALLOC_FREE(ctx->test_ctx->ldb); + TALLOC_FREE(ctx->test_ctx->ev); + close(pipes[0]); + ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx); + if (ctx->test_ctx->ev == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ctx->test_ctx->ldb = ldb_init(ctx->test_ctx, + ctx->test_ctx->ev); + if (ctx->test_ctx->ldb == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_connect(ctx->test_ctx->ldb, + ctx->test_ctx->dbpath, 0, NULL); + if (ret != LDB_SUCCESS) { + exit(ret); + } + + tmp_ctx = talloc_new(ctx->test_ctx); + if (tmp_ctx == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + msg = ldb_msg_new(tmp_ctx); + if (msg == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb, + "cn=test_search_cn," + "dc=search_test_entry"); + if (msg->dn == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_msg_add_string(msg, "filterAttr", "TRUE"); + if (ret != 0) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + el = ldb_msg_find_element(msg, "filterAttr"); + if (el == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + el->flags = LDB_FLAG_MOD_REPLACE; + + ret = ldb_transaction_start(ctx->test_ctx->ldb); + if (ret != 0) { + exit(ret); + } + + if (write(pipes[1], "GO", 2) != 2) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_modify(ctx->test_ctx->ldb, msg); + if (ret != 0) { + exit(ret); + } + + ret = ldb_transaction_commit(ctx->test_ctx->ldb); + exit(ret); + } + + close(pipes[1]); + ret = read(pipes[0], buf, 2); + assert_int_equal(ret, 2); + + sleep(3); + + /* + * If writes are not blocked until after this function, we + * will be able to successfully search for this modification + * here + */ + + search_dn = ldb_dn_new_fmt(ares, ctx->test_ctx->ldb, + "cn=test_search_cn," + "dc=search_test_entry"); + + ret = ldb_search(ctx->test_ctx->ldb, ares, + &res2, search_dn, LDB_SCOPE_BASE, NULL, + "filterAttr=TRUE"); + + /* + * We do this in an unusual order, because if we fail an assert before + * ldb_request_done(), we will also fail to clean up as we hold locks. + */ + + res_count = res2->count; + ldb_request_done(req, LDB_SUCCESS); + assert_int_equal(ret, 0); + + /* We should not have got the result */ + assert_int_equal(res_count, 0); + + return ret; +} + +static void test_ldb_modify_during_whole_search(void **state) +{ + struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, + struct search_test_ctx); + struct modify_during_search_test_ctx + ctx = + { + .test_ctx = search_test_ctx->ldb_test_ctx, + }; + + int ret; + struct ldb_request *req; + pid_t pid; + int wstatus; + struct ldb_dn *search_dn; + struct ldb_result *res2; + + tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev); + + ctx.basedn + = ldb_dn_new_fmt(search_test_ctx, + search_test_ctx->ldb_test_ctx->ldb, + "%s", + search_test_ctx->base_dn); + assert_non_null(ctx.basedn); + + + /* + * The search just needs to call DONE, we don't care about the + * contents of the search for this test + */ + ret = ldb_build_search_req(&req, + search_test_ctx->ldb_test_ctx->ldb, + search_test_ctx, + ctx.basedn, + LDB_SCOPE_SUBTREE, + "(&(!(filterAttr=*))" + "(cn=test_search_cn))", + NULL, + NULL, + &ctx, + test_ldb_modify_during_whole_search_callback1, + NULL); + assert_int_equal(ret, 0); + ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req); + + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + assert_int_equal(ret, 0); + + pid = waitpid(ctx.child_pid, &wstatus, 0); + assert_int_equal(pid, ctx.child_pid); + + assert_true(WIFEXITED(wstatus)); + + assert_int_equal(WEXITSTATUS(wstatus), 0); + + /* + * If writes are blocked until after the search function, we + * will be able to successfully search for this modification + * now + */ + + search_dn = ldb_dn_new_fmt(search_test_ctx, + search_test_ctx->ldb_test_ctx->ldb, + "cn=test_search_cn," + "dc=search_test_entry"); + + ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, + search_test_ctx, + &res2, search_dn, LDB_SCOPE_BASE, NULL, + "filterAttr=TRUE"); + assert_int_equal(ret, 0); + + /* We got the result */ + assert_int_equal(res2->count, 1); +} + +/* + * This test is also complex. + * + * The purpose is to test if a modify can occur during an ldb_search() + * before the request is destroyed with TALLOC_FREE() + * + * This would be a failure if in process + * (1) and (2): + * - (1) ldb_search() starts and waits + * - (2) an entry in the DB is allowed to change before the ldb_wait() is called + * - (1) the original process can see the modification before the TALLOC_FREE() + * also we check that + * - (1) the original process can see the modification after the TALLOC_FREE() + * + */ + +/* + * This purpose of this callback is to trigger a write in + * the child process before the ldb_wait() is called + * + * In ldb 1.1.31 ldb_search() omitted to take a all-record + * lock for the full duration of the search and callbacks + * + * We assume that if the write will proceed, it will proceed in a 3 + * second window after the function is called. + */ + +static int test_ldb_modify_before_ldb_wait_callback1(struct ldb_request *req, + struct ldb_reply *ares) +{ + switch (ares->type) { + case LDB_REPLY_ENTRY: + case LDB_REPLY_REFERRAL: + return LDB_SUCCESS; + + case LDB_REPLY_DONE: + break; + } + + return ldb_request_done(req, LDB_SUCCESS); +} + +static void test_ldb_modify_before_ldb_wait(void **state) +{ + struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, + struct search_test_ctx); + int ret; + struct ldb_request *req; + pid_t pid; + int wstatus; + struct ldb_dn *search_dn; + struct ldb_dn *basedn; + struct ldb_result *res2; + int pipes[2]; + char buf[2]; + pid_t child_pid; + unsigned res_count; + + search_dn = ldb_dn_new_fmt(search_test_ctx, + search_test_ctx->ldb_test_ctx->ldb, + "cn=test_search_cn," + "dc=search_test_entry"); + assert_non_null(search_dn); + + basedn = ldb_dn_new_fmt(search_test_ctx, + search_test_ctx->ldb_test_ctx->ldb, + "%s", + search_test_ctx->base_dn); + assert_non_null(basedn); + + /* + * The search just needs to call DONE, we don't care about the + * contents of the search for this test + */ + ret = ldb_build_search_req(&req, + search_test_ctx->ldb_test_ctx->ldb, + search_test_ctx, + basedn, + LDB_SCOPE_SUBTREE, + "(&(!(filterAttr=*))" + "(cn=test_search_cn))", + NULL, + NULL, + NULL, + test_ldb_modify_before_ldb_wait_callback1, + NULL); + assert_int_equal(ret, 0); + ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req); + + ret = pipe(pipes); + assert_int_equal(ret, 0); + + child_pid = fork(); + if (child_pid == 0) { + TALLOC_CTX *tmp_ctx = NULL; + struct ldb_message *msg; + struct ldb_message_element *el; + TALLOC_FREE(search_test_ctx->ldb_test_ctx->ldb); + TALLOC_FREE(search_test_ctx->ldb_test_ctx->ev); + close(pipes[0]); + search_test_ctx->ldb_test_ctx->ev = tevent_context_init(search_test_ctx->ldb_test_ctx); + if (search_test_ctx->ldb_test_ctx->ev == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + search_test_ctx->ldb_test_ctx->ldb = ldb_init(search_test_ctx->ldb_test_ctx, + search_test_ctx->ldb_test_ctx->ev); + if (search_test_ctx->ldb_test_ctx->ldb == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_connect(search_test_ctx->ldb_test_ctx->ldb, + search_test_ctx->ldb_test_ctx->dbpath, 0, NULL); + if (ret != LDB_SUCCESS) { + exit(ret); + } + + tmp_ctx = talloc_new(search_test_ctx->ldb_test_ctx); + if (tmp_ctx == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + msg = ldb_msg_new(tmp_ctx); + if (msg == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + /* + * We must re-create this DN from a string to ensure + * it does not reference the now-gone LDB context of + * the parent + */ + msg->dn = ldb_dn_new_fmt(search_test_ctx, + search_test_ctx->ldb_test_ctx->ldb, + "cn=test_search_cn," + "dc=search_test_entry"); + + if (msg->dn == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_msg_add_string(msg, "filterAttr", "TRUE"); + if (ret != 0) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + el = ldb_msg_find_element(msg, "filterAttr"); + if (el == NULL) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + el->flags = LDB_FLAG_MOD_REPLACE; + + ret = ldb_transaction_start(search_test_ctx->ldb_test_ctx->ldb); + if (ret != 0) { + exit(ret); + } + + if (write(pipes[1], "GO", 2) != 2) { + exit(LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_modify(search_test_ctx->ldb_test_ctx->ldb, msg); + if (ret != 0) { + exit(ret); + } + + ret = ldb_transaction_commit(search_test_ctx->ldb_test_ctx->ldb); + exit(ret); + } + close(pipes[1]); + + ret = read(pipes[0], buf, 2); + assert_int_equal(ret, 2); + + sleep(3); + + /* + * If writes are not blocked until after the (never called) ldb_wait(), we + * will be able to successfully search for this modification + * here + */ + + ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, search_test_ctx, + &res2, search_dn, LDB_SCOPE_BASE, NULL, + "filterAttr=TRUE"); + + /* + * We avoid making assertions before TALLOC_FREE()ing the request, + * lest the assert fail and mess with the clean-up because we still + * have locks. + */ + res_count = res2->count; + TALLOC_FREE(req); + + /* We should not have got the result */ + assert_int_equal(res_count, 0); + assert_int_equal(ret, 0); + + pid = waitpid(child_pid, &wstatus, 0); + assert_int_equal(pid, child_pid); + + assert_true(WIFEXITED(wstatus)); + + assert_int_equal(WEXITSTATUS(wstatus), 0); + + /* + * If writes are blocked until after the search request was freed, we + * will be able to successfully search for this modification + * now + */ + + search_dn = ldb_dn_new_fmt(search_test_ctx, + search_test_ctx->ldb_test_ctx->ldb, + "cn=test_search_cn," + "dc=search_test_entry"); + + ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, + search_test_ctx, + &res2, search_dn, LDB_SCOPE_BASE, NULL, + "filterAttr=TRUE"); + assert_int_equal(ret, 0); + + /* We got the result */ + assert_int_equal(res2->count, 1); +} + +/* + * This test is also complex. + * The purpose is to test if a modify can occur during an ldb_search() + * This would be a failure if if in process + * (1) and (2): + * - (1) ltdb_search() starts and calls back for one entry + * - (2) one of the entries to be matched is modified + * - (1) the indexed search tries to return the modified entry, but + * it is no longer found, either: + * - despite it still matching (dn changed) + * - it no longer matching (attrs changed) + * + * We also try un-indexed to show that the behaviour differs on this + * point, which it should not (an index should only impact search + * speed). + */ + +/* + * This purpose of this callback is to trigger a write in the callback + * so as to change in in-memory index code while looping over the + * index result. + */ + +static int test_ldb_callback_modify_during_search_callback1(struct ldb_request *req, + struct ldb_reply *ares) +{ + int ret; + struct modify_during_search_test_ctx *ctx = req->context; + struct ldb_dn *dn = NULL, *new_dn = NULL; + TALLOC_CTX *tmp_ctx = talloc_new(ctx->test_ctx); + struct ldb_message *msg = NULL; + + assert_non_null(tmp_ctx); + + switch (ares->type) { + case LDB_REPLY_ENTRY: + { + const struct ldb_val *cn_val + = ldb_dn_get_component_val(ares->message->dn, 0); + const char *cn = (char *)cn_val->data; + ctx->res_count++; + if (strcmp(cn, "test_search_cn") == 0) { + ctx->got_cn = true; + } else if (strcmp(cn, "test_search_2_cn") == 0) { + ctx->got_2_cn = true; + } + if (ctx->res_count == 2) { + return LDB_SUCCESS; + } + break; + } + case LDB_REPLY_REFERRAL: + return LDB_SUCCESS; + + case LDB_REPLY_DONE: + return ldb_request_done(req, LDB_SUCCESS); + } + + if (ctx->rename) { + if (ctx->got_2_cn) { + /* Modify this one */ + dn = ldb_dn_new_fmt(tmp_ctx, + ctx->test_ctx->ldb, + "cn=test_search_2_cn,%s", + ldb_dn_get_linearized(ctx->basedn)); + } else { + dn = ldb_dn_new_fmt(tmp_ctx, + ctx->test_ctx->ldb, + "cn=test_search_cn,%s", + ldb_dn_get_linearized(ctx->basedn)); + } + assert_non_null(dn); + + new_dn = ldb_dn_new_fmt(tmp_ctx, + ctx->test_ctx->ldb, + "cn=test_search_cn_renamed," + "dc=not_search_test_entry"); + assert_non_null(new_dn); + + ret = ldb_rename(ctx->test_ctx->ldb, dn, new_dn); + assert_int_equal(ret, 0); + + } else { + if (ctx->got_2_cn) { + /* Delete this one */ + dn = ldb_dn_new_fmt(tmp_ctx, + ctx->test_ctx->ldb, + "cn=test_search_2_cn,%s", + ldb_dn_get_linearized(ctx->basedn)); + } else { + dn = ldb_dn_new_fmt(tmp_ctx, + ctx->test_ctx->ldb, + "cn=test_search_cn,%s", + ldb_dn_get_linearized(ctx->basedn)); + } + assert_non_null(dn); + + ret = ldb_delete(ctx->test_ctx->ldb, dn); + assert_int_equal(ret, 0); + } + + /* + * Now fill in the position we just removed from the + * index to ensure we fail the test (otherwise we just read + * past the end of the array and find the value we wanted to + * skip) + */ + msg = ldb_msg_new(tmp_ctx); + assert_non_null(msg); + + /* We deliberatly use ou= not cn= here */ + msg->dn = ldb_dn_new_fmt(msg, + ctx->test_ctx->ldb, + "ou=test_search_cn_extra,%s", + ldb_dn_get_linearized(ctx->basedn)); + + ret = ldb_msg_add_string(msg, + "objectUUID", + "0123456789abcde3"); + + ret = ldb_add(ctx->test_ctx->ldb, + msg); + assert_int_equal(ret, LDB_SUCCESS); + + TALLOC_FREE(tmp_ctx); + return LDB_SUCCESS; +} + +static void test_ldb_callback_modify_during_search(void **state, bool add_index, + bool rename) +{ + struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, + struct search_test_ctx); + struct modify_during_search_test_ctx + ctx = + { .res_count = 0, + .test_ctx = search_test_ctx->ldb_test_ctx, + .rename = rename + }; + + int ret; + struct ldb_request *req; + + ret = ldb_transaction_start(search_test_ctx->ldb_test_ctx->ldb); + assert_int_equal(ret, 0); + + if (add_index) { + struct ldb_message *msg; + struct ldb_dn *indexlist = ldb_dn_new(search_test_ctx, + search_test_ctx->ldb_test_ctx->ldb, + "@INDEXLIST"); + assert_non_null(indexlist); + + msg = ldb_msg_new(search_test_ctx); + assert_non_null(msg); + + msg->dn = indexlist; + + ret = ldb_msg_add_string(msg, "@IDXONE", "1"); + assert_int_equal(ret, LDB_SUCCESS); + ret = ldb_msg_add_string(msg, "@IDXATTR", "cn"); + assert_int_equal(ret, LDB_SUCCESS); + ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb, + msg); + if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { + msg->elements[0].flags = LDB_FLAG_MOD_ADD; + msg->elements[1].flags = LDB_FLAG_MOD_ADD; + ret = ldb_modify(search_test_ctx->ldb_test_ctx->ldb, + msg); + } + assert_int_equal(ret, LDB_SUCCESS); + + /* + * Now bring the IDXONE index into memory by modifying + * it. This exposes an issue in ldb_tdb + */ + msg = ldb_msg_new(search_test_ctx); + assert_non_null(msg); + + msg->dn = ldb_dn_new_fmt(search_test_ctx, + search_test_ctx->ldb_test_ctx->ldb, + "cn=test_search_cn_extra,%s", + search_test_ctx->base_dn); + + ret = ldb_msg_add_string(msg, + "objectUUID", + "0123456789abcde2"); + + ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb, + msg); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_delete(search_test_ctx->ldb_test_ctx->ldb, + msg->dn); + assert_int_equal(ret, LDB_SUCCESS); + } + + tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev); + + ctx.basedn + = ldb_dn_new_fmt(search_test_ctx, + search_test_ctx->ldb_test_ctx->ldb, + "%s", + search_test_ctx->base_dn); + assert_non_null(ctx.basedn); + + + /* + * This search must be over multiple items, and should include + * the new name after a rename, to show that it would match + * both before and after that modify + * + * This needs to be a search that isn't matched by an index so + * that we just use the one-level index. + */ + ret = ldb_build_search_req(&req, + search_test_ctx->ldb_test_ctx->ldb, + search_test_ctx, + ctx.basedn, + LDB_SCOPE_ONELEVEL, + "(cn=*)", + NULL, + NULL, + &ctx, + test_ldb_callback_modify_during_search_callback1, + NULL); + assert_int_equal(ret, 0); + + ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req); + + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + assert_int_equal(ret, 0); + + ret = ldb_transaction_commit(search_test_ctx->ldb_test_ctx->ldb); + assert_int_equal(ret, 0); + + assert_int_equal(ctx.res_count, 2); + assert_int_equal(ctx.got_cn, true); + assert_int_equal(ctx.got_2_cn, true); +} + +static void test_ldb_callback_delete_during_indexed_search(void **state) +{ + test_ldb_callback_modify_during_search(state, true, false); +} + +static void test_ldb_callback_delete_during_unindexed_search(void **state) +{ + test_ldb_callback_modify_during_search(state, false, false); +} + +static void test_ldb_callback_rename_during_indexed_search(void **state) +{ + test_ldb_callback_modify_during_search(state, true, true); +} + +static void test_ldb_callback_rename_during_unindexed_search(void **state) +{ + test_ldb_callback_modify_during_search(state, false, true); +} + +static int ldb_case_test_setup(void **state) +{ + int ret; + struct ldb_ldif *ldif; + struct ldbtest_ctx *ldb_test_ctx; + const char *attrs_ldif = \ + "dn: @ATTRIBUTES\n" + "cn: CASE_INSENSITIVE\n" + "\n"; + struct keyval kvs[] = { + { "cn", "CaseInsensitiveValue" }, + { "uid", "CaseSensitiveValue" }, + { "objectUUID", "0123456789abcdef" }, + { NULL, NULL }, + }; + + + ldbtest_setup((void **) &ldb_test_ctx); + + while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) { + ret = ldb_add(ldb_test_ctx->ldb, ldif->msg); + assert_int_equal(ret, LDB_SUCCESS); + } + + ldb_test_add_data(ldb_test_ctx, + ldb_test_ctx, + "cn=CaseInsensitiveValue", + kvs); + + *state = ldb_test_ctx; + return 0; +} + +static int ldb_case_test_teardown(void **state) +{ + int ret; + struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + + struct ldb_dn *del_dn; + + del_dn = ldb_dn_new_fmt(ldb_test_ctx, + ldb_test_ctx->ldb, + "@ATTRIBUTES"); + assert_non_null(del_dn); + + ret = ldb_delete(ldb_test_ctx->ldb, del_dn); + assert_int_equal(ret, LDB_SUCCESS); + + assert_dn_doesnt_exist(ldb_test_ctx, + "@ATTRIBUTES"); + + ldb_test_remove_data(ldb_test_ctx, ldb_test_ctx, + "cn=CaseInsensitiveValue"); + + ldbtest_teardown((void **) &ldb_test_ctx); + return 0; +} + +static void test_ldb_attrs_case_insensitive(void **state) +{ + int cnt; + struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + + /* cn matches exact case */ + cnt = sub_search_count(ldb_test_ctx, "", "cn=CaseInsensitiveValue"); + assert_int_equal(cnt, 1); + + /* cn matches lower case */ + cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); + assert_int_equal(cnt, 1); + + /* uid matches exact case */ + cnt = sub_search_count(ldb_test_ctx, "", "uid=CaseSensitiveValue"); + assert_int_equal(cnt, 1); + + /* uid does not match lower case */ + cnt = sub_search_count(ldb_test_ctx, "", "uid=casesensitivevalue"); + assert_int_equal(cnt, 0); +} + +static struct ldb_schema_attribute cn_attr_1; +static struct ldb_schema_attribute cn_attr_2; +static struct ldb_schema_attribute default_attr; + +/* + override the name to attribute handler function + */ +static const struct ldb_schema_attribute *ldb_test_attribute_handler_override(struct ldb_context *ldb, + void *private_data, + const char *name) +{ + if (private_data != NULL && ldb_attr_cmp(name, "cn") == 0) { + return &cn_attr_1; + } else if (private_data == NULL && ldb_attr_cmp(name, "cn") == 0) { + return &cn_attr_2; + } else if (ldb_attr_cmp(name, "uid") == 0) { + return &cn_attr_2; + } + return &default_attr; +} + +static void test_ldb_attrs_case_handler(void **state) +{ + int cnt; + int ret; + const struct ldb_schema_syntax *syntax; + + struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + struct ldb_context *ldb = ldb_test_ctx->ldb; + + /* cn matches lower case */ + cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); + assert_int_equal(cnt, 1); + + syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING); + assert_non_null(syntax); + + ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb, + "*", 0, + syntax, &default_attr); + assert_int_equal(ret, LDB_SUCCESS); + + syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING); + assert_non_null(syntax); + + ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb, + "cn", 0, + syntax, &cn_attr_1); + assert_int_equal(ret, LDB_SUCCESS); + + /* + * Set an attribute handler, which will fail to match as we + * force case sensitive + */ + ldb_schema_attribute_set_override_handler(ldb, + ldb_test_attribute_handler_override, + (void *)1); + + /* cn does not matche lower case */ + cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); + assert_int_equal(cnt, 0); + + syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING); + assert_non_null(syntax); + + ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb, + "cn", 0, + syntax, &cn_attr_2); + assert_int_equal(ret, LDB_SUCCESS); + + /* + * Set an attribute handler, which will match as we + * force case insensitive + */ + ldb_schema_attribute_set_override_handler(ldb, + ldb_test_attribute_handler_override, + NULL); + + /* cn matches lower case */ + cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); + assert_int_equal(cnt, 1); + +} + + +static void test_ldb_attrs_index_handler(void **state) +{ + int cnt; + int ret; + const struct ldb_schema_syntax *syntax; + struct ldb_ldif *ldif; + + const char *index_ldif = \ + "dn: @INDEXLIST\n" + "@IDXATTR: cn\n" + "\n"; + + struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + struct ldb_context *ldb = ldb_test_ctx->ldb; + + /* cn matches lower case */ + cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); + assert_int_equal(cnt, 1); + + syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING); + assert_non_null(syntax); + + ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb, + "cn", 0, + syntax, &cn_attr_1); + assert_int_equal(ret, LDB_SUCCESS); + + syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING); + assert_non_null(syntax); + + ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb, + "cn", LDB_ATTR_FLAG_INDEXED, + syntax, &cn_attr_2); + assert_int_equal(ret, LDB_SUCCESS); + + syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING); + assert_non_null(syntax); + + ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb, + "", 0, + syntax, &default_attr); + assert_int_equal(ret, LDB_SUCCESS); + + /* + * Set an attribute handler + */ + ldb_schema_attribute_set_override_handler(ldb, + ldb_test_attribute_handler_override, + NULL); + + /* cn matches lower case */ + cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); + assert_int_equal(cnt, 1); + + /* Add the index (actually any modify will do) */ + while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) { + ret = ldb_add(ldb_test_ctx->ldb, ldif->msg); + if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { + ldif->msg->elements[0].flags = LDB_FLAG_MOD_ADD; + ret = ldb_modify(ldb_test_ctx->ldb, + ldif->msg); + } + assert_int_equal(ret, LDB_SUCCESS); + } + + ldb_schema_set_override_indexlist(ldb, false); + + /* cn does match as there is an index now */ + cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); + assert_int_equal(cnt, 1); + + /* + * Set an attribute handler, which will later fail to match as we + * didn't re-index the DB + */ + ldb_schema_attribute_set_override_handler(ldb, + ldb_test_attribute_handler_override, + (void *)1); + + /* + * cn does not match as we changed the case sensitivity, but + * didn't re-index + * + * This shows that the override is in control + */ + cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); + assert_int_equal(cnt, 0); + +} + +static int ldb_case_attrs_index_test_teardown(void **state) +{ + int ret; + struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + struct ldb_dn *del_dn; + + del_dn = ldb_dn_new_fmt(ldb_test_ctx, + ldb_test_ctx->ldb, + "@INDEXLIST"); + assert_non_null(del_dn); + + ret = ldb_delete(ldb_test_ctx->ldb, del_dn); + if (ret != LDB_ERR_NO_SUCH_OBJECT) { + assert_int_equal(ret, LDB_SUCCESS); + } + + assert_dn_doesnt_exist(ldb_test_ctx, + "@INDEXLIST"); + + ldb_case_test_teardown(state); + return 0; +} + + +struct rename_test_ctx { + struct ldbtest_ctx *ldb_test_ctx; + + struct ldb_dn *basedn; + const char *str_basedn; + + const char *teardown_dn; +}; + +static int ldb_rename_test_setup(void **state) +{ + struct ldbtest_ctx *ldb_test_ctx; + struct rename_test_ctx *rename_test_ctx; + const char *strdn = "dc=rename_test_entry_from"; + + ldbtest_setup((void **) &ldb_test_ctx); + + rename_test_ctx = talloc(ldb_test_ctx, struct rename_test_ctx); + assert_non_null(rename_test_ctx); + rename_test_ctx->ldb_test_ctx = ldb_test_ctx; + assert_non_null(rename_test_ctx->ldb_test_ctx); + + rename_test_ctx->basedn = ldb_dn_new_fmt(rename_test_ctx, + rename_test_ctx->ldb_test_ctx->ldb, + "%s", strdn); + assert_non_null(rename_test_ctx->basedn); + + rename_test_ctx->str_basedn = strdn; + rename_test_ctx->teardown_dn = strdn; + + add_dn_with_cn(ldb_test_ctx, + rename_test_ctx->basedn, + "test_rename_cn_val", + "0123456789abcde0"); + + *state = rename_test_ctx; + return 0; +} + +static int ldb_rename_test_teardown(void **state) +{ + int ret; + struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(*state, + struct rename_test_ctx); + struct ldbtest_ctx *ldb_test_ctx; + struct ldb_dn *del_dn; + + ldb_test_ctx = rename_test_ctx->ldb_test_ctx; + + del_dn = ldb_dn_new_fmt(rename_test_ctx, + rename_test_ctx->ldb_test_ctx->ldb, + "%s", rename_test_ctx->teardown_dn); + assert_non_null(del_dn); + + ret = ldb_delete(ldb_test_ctx->ldb, del_dn); + assert_int_equal(ret, LDB_SUCCESS); + + assert_dn_doesnt_exist(ldb_test_ctx, + rename_test_ctx->teardown_dn); + + ldbtest_teardown((void **) &ldb_test_ctx); + return 0; +} + +static void test_ldb_rename(void **state) +{ + struct rename_test_ctx *rename_test_ctx = + talloc_get_type_abort(*state, struct rename_test_ctx); + int ret; + const char *str_new_dn = "dc=rename_test_entry_to"; + struct ldb_dn *new_dn; + + new_dn = ldb_dn_new_fmt(rename_test_ctx, + rename_test_ctx->ldb_test_ctx->ldb, + "%s", str_new_dn); + assert_non_null(new_dn); + + ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb, + rename_test_ctx->basedn, + new_dn); + assert_int_equal(ret, LDB_SUCCESS); + + assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn); + assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx, + rename_test_ctx->str_basedn); + rename_test_ctx->teardown_dn = str_new_dn; + + /* FIXME - test the values which didn't change */ +} + +static void test_ldb_rename_from_doesnt_exist(void **state) +{ + struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort( + *state, + struct rename_test_ctx); + int ret; + const char *str_new_dn = "dc=rename_test_entry_to"; + const char *str_bad_old_dn = "dc=rename_test_no_such_entry"; + struct ldb_dn *new_dn; + struct ldb_dn *bad_old_dn; + + new_dn = ldb_dn_new_fmt(rename_test_ctx, + rename_test_ctx->ldb_test_ctx->ldb, + "%s", str_new_dn); + assert_non_null(new_dn); + + bad_old_dn = ldb_dn_new_fmt(rename_test_ctx, + rename_test_ctx->ldb_test_ctx->ldb, + "%s", str_bad_old_dn); + assert_non_null(bad_old_dn); + + assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx, + str_bad_old_dn); + + ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb, + bad_old_dn, new_dn); + assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT); + + assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx, + str_new_dn); +} + +static void test_ldb_rename_to_exists(void **state) +{ + struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort( + *state, + struct rename_test_ctx); + int ret; + const char *str_new_dn = "dc=rename_test_already_exists"; + struct ldb_dn *new_dn; + + new_dn = ldb_dn_new_fmt(rename_test_ctx, + rename_test_ctx->ldb_test_ctx->ldb, + "%s", str_new_dn); + assert_non_null(new_dn); + + add_dn_with_cn(rename_test_ctx->ldb_test_ctx, + new_dn, + "test_rename_cn_val", + "0123456789abcde1"); + + ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb, + rename_test_ctx->basedn, + new_dn); + assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS); + + /* Old object must still exist */ + assert_dn_exists(rename_test_ctx->ldb_test_ctx, + rename_test_ctx->str_basedn); + + ret = ldb_delete(rename_test_ctx->ldb_test_ctx->ldb, + new_dn); + assert_int_equal(ret, LDB_SUCCESS); + + assert_dn_exists(rename_test_ctx->ldb_test_ctx, + rename_test_ctx->teardown_dn); +} + +static void test_ldb_rename_self(void **state) +{ + struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort( + *state, + struct rename_test_ctx); + int ret; + + /* Oddly enough, this is a success in ldb.. */ + ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb, + rename_test_ctx->basedn, + rename_test_ctx->basedn); + assert_int_equal(ret, LDB_SUCCESS); + + /* Old object must still exist */ + assert_dn_exists(rename_test_ctx->ldb_test_ctx, + rename_test_ctx->str_basedn); +} + +static void test_ldb_rename_dn_case_change(void **state) +{ + struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort( + *state, + struct rename_test_ctx); + int ret; + char *str_new_dn; + struct ldb_dn *new_dn; + unsigned i; + + str_new_dn = talloc_strdup(rename_test_ctx, rename_test_ctx->str_basedn); + assert_non_null(str_new_dn); + for (i = 0; str_new_dn[i]; i++) { + str_new_dn[i] = toupper(str_new_dn[i]); + } + + new_dn = ldb_dn_new_fmt(rename_test_ctx, + rename_test_ctx->ldb_test_ctx->ldb, + "%s", str_new_dn); + assert_non_null(new_dn); + + ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb, + rename_test_ctx->basedn, + new_dn); + assert_int_equal(ret, LDB_SUCCESS); + + /* DNs are case insensitive, so both searches will match */ + assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn); + assert_dn_exists(rename_test_ctx->ldb_test_ctx, + rename_test_ctx->str_basedn); + /* FIXME - test the values didn't change */ +} + +static int ldb_read_only_setup(void **state) +{ + struct ldbtest_ctx *test_ctx; + + ldbtest_setup((void **) &test_ctx); + + *state = test_ctx; + return 0; +} + +static int ldb_read_only_teardown(void **state) +{ + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + ldbtest_teardown((void **) &test_ctx); + return 0; +} + +static void test_read_only(void **state) +{ + struct ldb_context *ro_ldb = NULL; + struct ldb_context *rw_ldb = NULL; + int ret; + TALLOC_CTX *tmp_ctx = NULL; + + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + /* + * Close the ldb context freeing it this will ensure it exists on + * disk and can be opened in read only mode + */ + TALLOC_FREE(test_ctx->ldb); + + /* + * Open the database in read only and read write mode, + * ensure it's opend in read only mode first + */ + ro_ldb = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ro_ldb, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); + assert_int_equal(ret, 0); + + rw_ldb = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(rw_ldb, test_ctx->dbpath, 0, NULL); + assert_int_equal(ret, 0); + + + /* + * Set up a context for the temporary variables + */ + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + /* + * Ensure that we can search the read write database + */ + { + struct ldb_result *result = NULL; + struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb, + "dc=test"); + assert_non_null(dn); + + ret = ldb_search(rw_ldb, tmp_ctx, &result, dn, + LDB_SCOPE_BASE, NULL, NULL); + assert_int_equal(ret, LDB_SUCCESS); + TALLOC_FREE(result); + TALLOC_FREE(dn); + } + + /* + * Ensure that we can search the read only database + */ + { + struct ldb_result *result = NULL; + struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb, + "dc=test"); + assert_non_null(dn); + + ret = ldb_search(ro_ldb, tmp_ctx, &result, dn, + LDB_SCOPE_BASE, NULL, NULL); + assert_int_equal(ret, LDB_SUCCESS); + TALLOC_FREE(result); + TALLOC_FREE(dn); + } + /* + * Ensure that a write to the read only database fails + */ + { + struct ldb_message *msg = NULL; + msg = ldb_msg_new(tmp_ctx); + assert_non_null(msg); + + msg->dn = ldb_dn_new_fmt(msg, ro_ldb, "dc=test"); + assert_non_null(msg->dn); + + ret = ldb_msg_add_string(msg, "cn", "test_cn_val"); + assert_int_equal(ret, 0); + + ret = ldb_msg_add_string(msg, "objectUUID", + "0123456789abcde1"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_add(ro_ldb, msg); + assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM); + TALLOC_FREE(msg); + } + + /* + * Ensure that a write to the read write database succeeds + */ + { + struct ldb_message *msg = NULL; + msg = ldb_msg_new(tmp_ctx); + assert_non_null(msg); + + msg->dn = ldb_dn_new_fmt(msg, rw_ldb, "dc=test"); + assert_non_null(msg->dn); + + ret = ldb_msg_add_string(msg, "cn", "test_cn_val"); + assert_int_equal(ret, 0); + + ret = ldb_msg_add_string(msg, "objectUUID", + "0123456789abcde2"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_add(rw_ldb, msg); + assert_int_equal(ret, LDB_SUCCESS); + TALLOC_FREE(msg); + } + + /* + * Ensure that a delete from a read only database fails + */ + { + struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb, "dc=test"); + assert_non_null(dn); + + ret = ldb_delete(ro_ldb, dn); + assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM); + TALLOC_FREE(dn); + } + + + /* + * Ensure that a delete from a read write succeeds + */ + { + struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb, "dc=test"); + assert_non_null(dn); + + ret = ldb_delete(rw_ldb, dn); + assert_int_equal(ret, LDB_SUCCESS); + TALLOC_FREE(dn); + } + TALLOC_FREE(tmp_ctx); +} + +static bool unique_values = false; + +static int unique_index_test_module_add( + struct ldb_module *module, + struct ldb_request *req) +{ + if (unique_values) { + struct ldb_message *msg = discard_const(req->op.add.message); + struct ldb_message_element *el = NULL; + el = ldb_msg_find_element(msg, "cn"); + if (el != NULL) { + el->flags |= LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX; + } + } + + return ldb_next_request(module, req); +} + +static int unique_index_test_module_init(struct ldb_module *module) +{ + return ldb_next_init(module); +} + +static const struct ldb_module_ops ldb_unique_index_test_module_ops = { + .name = "unique_index_test", + .init_context = unique_index_test_module_init, + .add = unique_index_test_module_add, +}; + +static int ldb_unique_index_test_setup(void **state) +{ + int ret; + struct ldb_ldif *ldif; + struct ldbtest_ctx *ldb_test_ctx; + const char *attrs_ldif = \ + "dn: @ATTRIBUTES\n" + "cn: UNIQUE_INDEX\n" + "\n"; + const char *index_ldif = \ + "dn: @INDEXLIST\n" + "@IDXATTR: cn\n" +#ifdef GUID_IDX + "@IDXGUID: objectUUID\n" + "@IDX_DN_GUID: GUID\n" +#endif + "\n"; + const char *options[] = {"modules:unique_index_test", NULL}; + + + ret = ldb_register_module(&ldb_unique_index_test_module_ops); + assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_ENTRY_ALREADY_EXISTS); + ldbtest_noconn_setup((void **) &ldb_test_ctx); + + + ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options); + assert_int_equal(ret, 0); + + while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) { + ret = ldb_add(ldb_test_ctx->ldb, ldif->msg); + assert_int_equal(ret, LDB_SUCCESS); + } + + while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) { + ret = ldb_add(ldb_test_ctx->ldb, ldif->msg); + assert_int_equal(ret, LDB_SUCCESS); + } + + unique_values = true; + + *state = ldb_test_ctx; + return 0; +} + +static int ldb_unique_index_test_teardown(void **state) +{ + int ret; + struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + struct ldb_dn *del_dn; + + del_dn = ldb_dn_new_fmt(ldb_test_ctx, + ldb_test_ctx->ldb, + "@INDEXLIST"); + assert_non_null(del_dn); + + ret = ldb_delete(ldb_test_ctx->ldb, del_dn); + if (ret != LDB_ERR_NO_SUCH_OBJECT) { + assert_int_equal(ret, LDB_SUCCESS); + } + + assert_dn_doesnt_exist(ldb_test_ctx, + "@INDEXLIST"); + + TALLOC_FREE(del_dn); + + del_dn = ldb_dn_new_fmt(ldb_test_ctx, + ldb_test_ctx->ldb, + "@ATTRIBUTES"); + assert_non_null(del_dn); + + ret = ldb_delete(ldb_test_ctx->ldb, del_dn); + if (ret != LDB_ERR_NO_SUCH_OBJECT) { + assert_int_equal(ret, LDB_SUCCESS); + } + + assert_dn_doesnt_exist(ldb_test_ctx, + "@ATTRIBUTES"); + + ldbtest_teardown((void **) &ldb_test_ctx); + return 0; +} + + +static void test_ldb_add_unique_value_to_unique_index(void **state) +{ + int ret; + struct ldb_message *msg; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + msg = ldb_msg_new(tmp_ctx); + assert_non_null(msg); + + msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test"); + assert_non_null(msg->dn); + + ret = ldb_msg_add_string(msg, "cn", "test_unique_index"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_msg_add_string(msg, "objectUUID", + "0123456789abcde1"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_add(test_ctx->ldb, msg); + assert_int_equal(ret, LDB_SUCCESS); + + talloc_free(tmp_ctx); +} + +static int ldb_non_unique_index_test_setup(void **state) +{ + int ret; + struct ldb_ldif *ldif; + struct ldbtest_ctx *ldb_test_ctx; + const char *index_ldif = \ + "dn: @INDEXLIST\n" + "@IDXATTR: cn\n" +#ifdef GUID_IDX + "@IDXGUID: objectUUID\n" + "@IDX_DN_GUID: GUID\n" +#endif + "\n"; + const char *options[] = {"modules:unique_index_test", NULL}; + + + ret = ldb_register_module(&ldb_unique_index_test_module_ops); + assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_ENTRY_ALREADY_EXISTS); + ldbtest_noconn_setup((void **) &ldb_test_ctx); + + + ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options); + assert_int_equal(ret, 0); + + while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) { + ret = ldb_add(ldb_test_ctx->ldb, ldif->msg); + assert_int_equal(ret, LDB_SUCCESS); + } + + unique_values = true; + + *state = ldb_test_ctx; + return 0; +} + +static int ldb_non_unique_index_test_teardown(void **state) +{ + int ret; + struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + struct ldb_dn *del_dn; + + del_dn = ldb_dn_new_fmt(ldb_test_ctx, + ldb_test_ctx->ldb, + "@INDEXLIST"); + assert_non_null(del_dn); + + ret = ldb_delete(ldb_test_ctx->ldb, del_dn); + if (ret != LDB_ERR_NO_SUCH_OBJECT) { + assert_int_equal(ret, LDB_SUCCESS); + } + + assert_dn_doesnt_exist(ldb_test_ctx, + "@INDEXLIST"); + + TALLOC_FREE(del_dn); + + ldbtest_teardown((void **) &ldb_test_ctx); + return 0; +} + +static void test_ldb_add_duplicate_value_to_unique_index(void **state) +{ + int ret; + struct ldb_message *msg01; + struct ldb_message *msg02; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + msg01 = ldb_msg_new(tmp_ctx); + assert_non_null(msg01); + + msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01"); + assert_non_null(msg01->dn); + + ret = ldb_msg_add_string(msg01, "cn", "test_unique_index"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_msg_add_string(msg01, "objectUUID", + "0123456789abcde1"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_add(test_ctx->ldb, msg01); + assert_int_equal(ret, LDB_SUCCESS); + + msg02 = ldb_msg_new(tmp_ctx); + assert_non_null(msg02); + + msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02"); + assert_non_null(msg02->dn); + + ret = ldb_msg_add_string(msg02, "cn", "test_unique_index"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_msg_add_string(msg02, "objectUUID", + "0123456789abcde2"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_add(test_ctx->ldb, msg02); + assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION); + talloc_free(tmp_ctx); +} + +static void test_ldb_add_to_index_duplicates_allowed(void **state) +{ + int ret; + struct ldb_message *msg01; + struct ldb_message *msg02; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + TALLOC_CTX *tmp_ctx; + + unique_values = false; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + + msg01 = ldb_msg_new(tmp_ctx); + assert_non_null(msg01); + + msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01"); + assert_non_null(msg01->dn); + + ret = ldb_msg_add_string(msg01, "cn", "test_unique_index"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_msg_add_string(msg01, "objectUUID", + "0123456789abcde1"); + + ret = ldb_add(test_ctx->ldb, msg01); + assert_int_equal(ret, LDB_SUCCESS); + + msg02 = ldb_msg_new(tmp_ctx); + assert_non_null(msg02); + + msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02"); + assert_non_null(msg02->dn); + + ret = ldb_msg_add_string(msg02, "cn", "test_unique_index"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_msg_add_string(msg02, "objectUUID", + "0123456789abcde2"); + + ret = ldb_add(test_ctx->ldb, msg02); + assert_int_equal(ret, LDB_SUCCESS); + talloc_free(tmp_ctx); +} + +static void test_ldb_add_to_index_unique_values_required(void **state) +{ + int ret; + struct ldb_message *msg01; + struct ldb_message *msg02; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + TALLOC_CTX *tmp_ctx; + + unique_values = true; + + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + + msg01 = ldb_msg_new(tmp_ctx); + assert_non_null(msg01); + + msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01"); + assert_non_null(msg01->dn); + + ret = ldb_msg_add_string(msg01, "cn", "test_unique_index"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_msg_add_string(msg01, "objectUUID", + "0123456789abcde1"); + + ret = ldb_add(test_ctx->ldb, msg01); + assert_int_equal(ret, LDB_SUCCESS); + + msg02 = ldb_msg_new(tmp_ctx); + assert_non_null(msg02); + + msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02"); + assert_non_null(msg02->dn); + + ret = ldb_msg_add_string(msg02, "cn", "test_unique_index"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_msg_add_string(msg02, "objectUUID", + "0123456789abcde2"); + + ret = ldb_add(test_ctx->ldb, msg02); + assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION); + talloc_free(tmp_ctx); +} + +static void ldb_debug_string(void *context, enum ldb_debug_level level, + const char *fmt, va_list ap) +{ + + if (level <= LDB_DEBUG_WARNING) { + *((char **)context) = talloc_vasprintf(NULL, fmt, ap); + } +} + +static void test_ldb_unique_index_duplicate_logging(void **state) +{ + int ret; + struct ldb_message *msg01; + struct ldb_message *msg02; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + TALLOC_CTX *tmp_ctx; + char *debug_string = NULL; + char *p = NULL; + + /* The GUID mode is not compatible with this test */ +#ifdef GUID_IDX + return; +#endif + + ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string); + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + msg01 = ldb_msg_new(tmp_ctx); + assert_non_null(msg01); + + msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01"); + assert_non_null(msg01->dn); + + ret = ldb_msg_add_string(msg01, "cn", "test_unique_index"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_msg_add_string(msg01, "objectUUID", + "0123456789abcde1"); + + ret = ldb_add(test_ctx->ldb, msg01); + assert_int_equal(ret, LDB_SUCCESS); + + msg02 = ldb_msg_new(tmp_ctx); + assert_non_null(msg02); + + msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02"); + assert_non_null(msg02->dn); + + ret = ldb_msg_add_string(msg02, "cn", "test_unique_index"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_msg_add_string(msg02, "objectUUID", + "0123456789abcde2"); + + ret = ldb_add(test_ctx->ldb, msg02); + assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION); + + assert_non_null(debug_string); + p = strstr( + debug_string, + "unique index violation on cn " + "in dc=test02, conflicts with dc=test01 in " + "@INDEX:CN:test_unique_index"); + assert_non_null(p); + TALLOC_FREE(debug_string); + talloc_free(tmp_ctx); +} + +static void test_ldb_duplicate_dn_logging(void **state) +{ + int ret; + struct ldb_message *msg01; + struct ldb_message *msg02; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + TALLOC_CTX *tmp_ctx; + char *debug_string = NULL; + + /* The GUID mode is not compatible with this test */ +#ifdef GUID_IDX + return; +#endif + + ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string); + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + msg01 = ldb_msg_new(tmp_ctx); + assert_non_null(msg01); + + msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01"); + assert_non_null(msg01->dn); + + ret = ldb_msg_add_string(msg01, "cn", "test_unique_index01"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_msg_add_string(msg01, "objectUUID", + "0123456789abcde1"); + + ret = ldb_add(test_ctx->ldb, msg01); + assert_int_equal(ret, LDB_SUCCESS); + + msg02 = ldb_msg_new(tmp_ctx); + assert_non_null(msg02); + + msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test01"); + assert_non_null(msg02->dn); + + ret = ldb_msg_add_string(msg02, "cn", "test_unique_index02"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_msg_add_string(msg02, "objectUUID", + "0123456789abcde2"); + + ret = ldb_add(test_ctx->ldb, msg02); + assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS); + + assert_null(debug_string); + talloc_free(tmp_ctx); +} + +static int ldb_guid_index_test_setup(void **state) +{ + int ret; + struct ldb_ldif *ldif; + struct ldbtest_ctx *ldb_test_ctx; + const char *attrs_ldif = \ + "dn: @ATTRIBUTES\n" + "cn: UNIQUE_INDEX\n" + "\n"; + const char *index_ldif = \ + "dn: @INDEXLIST\n" + "@IDXATTR: cn\n" + "@IDXGUID: objectUUID\n" + "@IDX_DN_GUID: GUID\n" + "\n"; + + ldbtest_noconn_setup((void **) &ldb_test_ctx); + + + ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, NULL); + assert_int_equal(ret, 0); + + while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) { + ret = ldb_add(ldb_test_ctx->ldb, ldif->msg); + assert_int_equal(ret, LDB_SUCCESS); + } + + while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) { + ret = ldb_add(ldb_test_ctx->ldb, ldif->msg); + assert_int_equal(ret, LDB_SUCCESS); + } + + *state = ldb_test_ctx; + return 0; +} + +static int ldb_guid_index_test_teardown(void **state) +{ + int ret; + struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + struct ldb_dn *del_dn; + + del_dn = ldb_dn_new_fmt(ldb_test_ctx, + ldb_test_ctx->ldb, + "@INDEXLIST"); + assert_non_null(del_dn); + + ret = ldb_delete(ldb_test_ctx->ldb, del_dn); + if (ret != LDB_ERR_NO_SUCH_OBJECT) { + assert_int_equal(ret, LDB_SUCCESS); + } + + assert_dn_doesnt_exist(ldb_test_ctx, + "@INDEXLIST"); + + TALLOC_FREE(del_dn); + + del_dn = ldb_dn_new_fmt(ldb_test_ctx, + ldb_test_ctx->ldb, + "@ATTRIBUTES"); + assert_non_null(del_dn); + + ret = ldb_delete(ldb_test_ctx->ldb, del_dn); + if (ret != LDB_ERR_NO_SUCH_OBJECT) { + assert_int_equal(ret, LDB_SUCCESS); + } + + assert_dn_doesnt_exist(ldb_test_ctx, + "@ATTRIBUTES"); + + ldbtest_teardown((void **) &ldb_test_ctx); + return 0; +} + + +static void test_ldb_unique_index_duplicate_with_guid(void **state) +{ + int ret; + struct ldb_message *msg01; + struct ldb_message *msg02; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + TALLOC_CTX *tmp_ctx; + char *debug_string = NULL; + char *p = NULL; + + ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string); + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + msg01 = ldb_msg_new(tmp_ctx); + assert_non_null(msg01); + + msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01"); + assert_non_null(msg01->dn); + + ret = ldb_msg_add_string(msg01, "cn", "test_unique_index"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_msg_add_string(msg01, "objectUUID", "0123456789abcdef"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_add(test_ctx->ldb, msg01); + assert_int_equal(ret, LDB_SUCCESS); + + msg02 = ldb_msg_new(tmp_ctx); + assert_non_null(msg02); + + msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02"); + assert_non_null(msg02->dn); + + ret = ldb_msg_add_string(msg02, "cn", "test_unique_index"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_msg_add_string(msg02, "objectUUID", "0123456789abcde0"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_add(test_ctx->ldb, msg02); + assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION); + + assert_non_null(debug_string); + p = strstr( + debug_string, + "unique index violation on cn in dc=test02, conflicts with " + "objectUUID 0123456789abcdef in @INDEX:CN:test_unique_index"); + assert_non_null(p); + TALLOC_FREE(debug_string); + talloc_free(tmp_ctx); + ldb_set_debug(test_ctx->ldb, NULL, NULL); +} + +static void test_ldb_guid_index_duplicate_dn_logging(void **state) +{ + int ret; + struct ldb_message *msg01; + struct ldb_message *msg02; + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + TALLOC_CTX *tmp_ctx; + char *debug_string = NULL; + + ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string); + tmp_ctx = talloc_new(test_ctx); + assert_non_null(tmp_ctx); + + msg01 = ldb_msg_new(tmp_ctx); + assert_non_null(msg01); + + msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01"); + assert_non_null(msg01->dn); + + ret = ldb_msg_add_string(msg01, "cn", "test_unique_index01"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_msg_add_string(msg01, "objectUUID", "0123456789abcdef"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_add(test_ctx->ldb, msg01); + assert_int_equal(ret, LDB_SUCCESS); + + msg02 = ldb_msg_new(tmp_ctx); + assert_non_null(msg02); + + msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test01"); + assert_non_null(msg02->dn); + + ret = ldb_msg_add_string(msg02, "cn", "test_unique_index02"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_msg_add_string(msg02, "objectUUID", "0123456789abcde1"); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_add(test_ctx->ldb, msg02); + assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS); + + assert_null(debug_string); + talloc_free(tmp_ctx); + ldb_set_debug(test_ctx->ldb, NULL, NULL); +} + +static void test_ldb_talloc_destructor_transaction_cleanup(void **state) +{ + struct ldbtest_ctx *test_ctx = NULL; + + test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); + assert_non_null(test_ctx); + + ldb_transaction_start(test_ctx->ldb); + + /* + * Trigger the destructor + */ + TALLOC_FREE(test_ctx->ldb); + + /* + * Now ensure that a new connection can be opened + */ + { + TALLOC_CTX *tctx = talloc_new(test_ctx); + struct ldbtest_ctx *ctx = talloc_zero(tctx, struct ldbtest_ctx); + struct ldb_dn *basedn; + struct ldb_result *result = NULL; + int ret; + + ldbtest_setup((void *)&ctx); + + basedn = ldb_dn_new_fmt(tctx, ctx->ldb, "dc=test"); + assert_non_null(basedn); + + ret = ldb_search(ctx->ldb, + tctx, + &result, + basedn, + LDB_SCOPE_BASE, + NULL, + NULL); + assert_int_equal(ret, 0); + assert_non_null(result); + assert_int_equal(result->count, 0); + + ldbtest_teardown((void *)&ctx); + } +} + +#ifdef TEST_LMDB +static int test_ldb_multiple_connections_callback(struct ldb_request *req, + struct ldb_reply *ares) +{ + int ret; + int pipes[2]; + char buf[2]; + int pid, child_pid; + int wstatus; + + switch (ares->type) { + case LDB_REPLY_ENTRY: + break; + + case LDB_REPLY_REFERRAL: + return LDB_SUCCESS; + + case LDB_REPLY_DONE: + return ldb_request_done(req, LDB_SUCCESS); + } + + { + /* + * We open a new ldb on an ldb that is already open and + * then close it. + * + * If the multiple connection wrapping is correct the + * underlying MDB_env will be left open and we should see + * an active reader in the child we fork next + */ + struct ldb_context *ldb = NULL; + struct tevent_context *ev = NULL; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + + ev = tevent_context_init(mem_ctx); + assert_non_null(ev); + + ldb = ldb_init(mem_ctx, ev); + assert_non_null(ldb); + + ret = ldb_connect(ldb, TEST_BE"://apitest.ldb" , 0, NULL); + if (ret != LDB_SUCCESS) { + return ret; + } + TALLOC_FREE(ldb); + TALLOC_FREE(mem_ctx); + } + + ret = pipe(pipes); + assert_int_equal(ret, 0); + + child_pid = fork(); + if (child_pid == 0) { + struct MDB_env *env = NULL; + struct MDB_envinfo stat; + close(pipes[0]); + + /* + * Check that there are exactly two readers on the MDB file + * backing the ldb. + * + */ + ret = mdb_env_create(&env); + if (ret != 0) { + print_error(__location__ + " mdb_env_create returned (%d)", + ret); + exit(ret); + } + + ret = mdb_env_open(env, + "apitest.ldb", + MDB_NOSUBDIR | MDB_NOTLS, + 0644); + if (ret != 0) { + print_error(__location__ + " mdb_env_open returned (%d)", + ret); + exit(ret); + } + + ret = mdb_env_info(env, &stat); + if (ret != 0) { + print_error(__location__ + " mdb_env_info returned (%d)", + ret); + exit(ret); + } + if (stat.me_numreaders != 2) { + print_error(__location__ + " Incorrect number of readers (%d)", + stat.me_numreaders); + exit(LDB_ERR_CONSTRAINT_VIOLATION); + } + + ret = write(pipes[1], "GO", 2); + if (ret != 2) { + print_error(__location__ + " write returned (%d)", + ret); + exit(LDB_ERR_OPERATIONS_ERROR); + } + exit(LDB_SUCCESS); + } + close(pipes[1]); + ret = read(pipes[0], buf, 2); + assert_int_equal(ret, 2); + + pid = waitpid(child_pid, &wstatus, 0); + assert_int_equal(pid, child_pid); + + assert_true(WIFEXITED(wstatus)); + + assert_int_equal(WEXITSTATUS(wstatus), 0); + return LDB_SUCCESS; + +} + +static void test_ldb_close_with_multiple_connections(void **state) +{ + struct search_test_ctx *search_test_ctx = NULL; + struct ldb_dn *search_dn = NULL; + struct ldb_request *req = NULL; + int ret = 0; + + search_test_ctx = talloc_get_type_abort(*state, struct search_test_ctx); + assert_non_null(search_test_ctx); + + search_dn = ldb_dn_new_fmt(search_test_ctx, + search_test_ctx->ldb_test_ctx->ldb, + "cn=test_search_cn," + "dc=search_test_entry"); + assert_non_null(search_dn); + + /* + * The search just needs to call DONE, we don't care about the + * contents of the search for this test + */ + ret = ldb_build_search_req(&req, + search_test_ctx->ldb_test_ctx->ldb, + search_test_ctx, + search_dn, + LDB_SCOPE_SUBTREE, + "(&(!(filterAttr=*))" + "(cn=test_search_cn))", + NULL, + NULL, + NULL, + test_ldb_multiple_connections_callback, + NULL); + assert_int_equal(ret, 0); + + ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req); + assert_int_equal(ret, 0); + + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + assert_int_equal(ret, 0); +} + +#endif + +static void test_transaction_start_across_fork(void **state) +{ + struct ldb_context *ldb1 = NULL; + int ret; + struct ldbtest_ctx *test_ctx = NULL; + int pipes[2]; + char buf[2]; + int wstatus; + pid_t pid, child_pid; + + test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); + + /* + * Open the database + */ + ldb1 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb1, test_ctx->dbpath, 0, NULL); + assert_int_equal(ret, 0); + + ret = pipe(pipes); + assert_int_equal(ret, 0); + + child_pid = fork(); + if (child_pid == 0) { + close(pipes[0]); + ret = ldb_transaction_start(ldb1); + if (ret != LDB_ERR_PROTOCOL_ERROR) { + print_error(__location__": ldb_transaction_start " + "returned (%d) %s\n", + ret, + ldb1->err_string); + exit(LDB_ERR_OTHER); + } + + ret = write(pipes[1], "GO", 2); + if (ret != 2) { + print_error(__location__ + " write returned (%d)", + ret); + exit(LDB_ERR_OPERATIONS_ERROR); + } + exit(LDB_SUCCESS); + } + close(pipes[1]); + ret = read(pipes[0], buf, 2); + assert_int_equal(ret, 2); + + pid = waitpid(child_pid, &wstatus, 0); + assert_int_equal(pid, child_pid); + + assert_true(WIFEXITED(wstatus)); + + assert_int_equal(WEXITSTATUS(wstatus), 0); +} + +static void test_transaction_commit_across_fork(void **state) +{ + struct ldb_context *ldb1 = NULL; + int ret; + struct ldbtest_ctx *test_ctx = NULL; + int pipes[2]; + char buf[2]; + int wstatus; + pid_t pid, child_pid; + + test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); + + /* + * Open the database + */ + ldb1 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb1, test_ctx->dbpath, 0, NULL); + assert_int_equal(ret, 0); + + ret = ldb_transaction_start(ldb1); + assert_int_equal(ret, 0); + + ret = pipe(pipes); + assert_int_equal(ret, 0); + + child_pid = fork(); + if (child_pid == 0) { + close(pipes[0]); + ret = ldb_transaction_commit(ldb1); + + if (ret != LDB_ERR_PROTOCOL_ERROR) { + print_error(__location__": ldb_transaction_commit " + "returned (%d) %s\n", + ret, + ldb1->err_string); + exit(LDB_ERR_OTHER); + } + + ret = write(pipes[1], "GO", 2); + if (ret != 2) { + print_error(__location__ + " write returned (%d)", + ret); + exit(LDB_ERR_OPERATIONS_ERROR); + } + exit(LDB_SUCCESS); + } + close(pipes[1]); + ret = read(pipes[0], buf, 2); + assert_int_equal(ret, 2); + + pid = waitpid(child_pid, &wstatus, 0); + assert_int_equal(pid, child_pid); + + assert_true(WIFEXITED(wstatus)); + + assert_int_equal(WEXITSTATUS(wstatus), 0); +} + +static void test_lock_read_across_fork(void **state) +{ + struct ldb_context *ldb1 = NULL; + int ret; + struct ldbtest_ctx *test_ctx = NULL; + int pipes[2]; + char buf[2]; + int wstatus; + pid_t pid, child_pid; + + test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); + + /* + * Open the database + */ + ldb1 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb1, test_ctx->dbpath, 0, NULL); + assert_int_equal(ret, 0); + + ret = pipe(pipes); + assert_int_equal(ret, 0); + + child_pid = fork(); + if (child_pid == 0) { + struct ldb_dn *basedn; + struct ldb_result *result = NULL; + + close(pipes[0]); + + basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "dc=test"); + assert_non_null(basedn); + + ret = ldb_search(test_ctx->ldb, + test_ctx, + &result, + basedn, + LDB_SCOPE_BASE, + NULL, + NULL); + if (ret != LDB_ERR_PROTOCOL_ERROR) { + print_error(__location__": ldb_search " + "returned (%d) %s\n", + ret, + ldb1->err_string); + exit(LDB_ERR_OTHER); + } + + ret = write(pipes[1], "GO", 2); + if (ret != 2) { + print_error(__location__ + " write returned (%d)", + ret); + exit(LDB_ERR_OPERATIONS_ERROR); + } + exit(LDB_SUCCESS); + } + close(pipes[1]); + ret = read(pipes[0], buf, 2); + assert_int_equal(ret, 2); + + pid = waitpid(child_pid, &wstatus, 0); + assert_int_equal(pid, child_pid); + + assert_true(WIFEXITED(wstatus)); + + assert_int_equal(WEXITSTATUS(wstatus), 0); + + { + /* + * Ensure that the search actually succeeds on the opening + * pid + */ + struct ldb_dn *basedn; + struct ldb_result *result = NULL; + + close(pipes[0]); + + basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "dc=test"); + assert_non_null(basedn); + + ret = ldb_search(test_ctx->ldb, + test_ctx, + &result, + basedn, + LDB_SCOPE_BASE, + NULL, + NULL); + assert_int_equal(0, ret); + } +} + +static void test_multiple_opens_across_fork(void **state) +{ + struct ldb_context *ldb1 = NULL; + struct ldb_context *ldb2 = NULL; + int ret; + struct ldbtest_ctx *test_ctx = NULL; + int pipes[2]; + char buf[2]; + int wstatus; + pid_t pid, child_pid; + + test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); + + /* + * Open the database again + */ + ldb1 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); + assert_int_equal(ret, 0); + + ldb2 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb2, test_ctx->dbpath, 0, NULL); + assert_int_equal(ret, 0); + + ret = pipe(pipes); + assert_int_equal(ret, 0); + + child_pid = fork(); + if (child_pid == 0) { + struct ldb_context *ldb3 = NULL; + + close(pipes[0]); + ldb3 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL); + if (ret != 0) { + print_error(__location__": ldb_connect returned (%d)\n", + ret); + exit(ret); + } + ret = write(pipes[1], "GO", 2); + if (ret != 2) { + print_error(__location__ + " write returned (%d)", + ret); + exit(LDB_ERR_OPERATIONS_ERROR); + } + exit(LDB_SUCCESS); + } + close(pipes[1]); + ret = read(pipes[0], buf, 2); + assert_int_equal(ret, 2); + + pid = waitpid(child_pid, &wstatus, 0); + assert_int_equal(pid, child_pid); + + assert_true(WIFEXITED(wstatus)); + + assert_int_equal(WEXITSTATUS(wstatus), 0); +} + +int main(int argc, const char **argv) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown(test_connect, + ldbtest_noconn_setup, + ldbtest_noconn_teardown), + cmocka_unit_test_setup_teardown(test_ldif_message, + ldbtest_noconn_setup, + ldbtest_noconn_teardown), + cmocka_unit_test_setup_teardown(test_ldif_message_redacted, + ldbtest_noconn_setup, + ldbtest_noconn_teardown), + cmocka_unit_test_setup_teardown(test_ldb_add, + ldbtest_setup, + ldbtest_teardown), + cmocka_unit_test_setup_teardown(test_ldb_search, + ldbtest_setup, + ldbtest_teardown), + cmocka_unit_test_setup_teardown(test_ldb_del, + ldbtest_setup, + ldbtest_teardown), + cmocka_unit_test_setup_teardown(test_ldb_del_noexist, + ldbtest_setup, + ldbtest_teardown), + cmocka_unit_test_setup_teardown(test_ldb_handle, + ldbtest_setup, + ldbtest_teardown), + cmocka_unit_test_setup_teardown(test_ldb_build_search_req, + ldbtest_setup, + ldbtest_teardown), + cmocka_unit_test_setup_teardown(test_transactions, + ldbtest_setup, + ldbtest_teardown), + cmocka_unit_test_setup_teardown(test_nested_transactions, + ldbtest_setup, + ldbtest_teardown), + cmocka_unit_test_setup_teardown(test_ldb_modify_add_key, + ldb_modify_test_setup, + ldb_modify_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_modify_extend_key, + ldb_modify_test_setup, + ldb_modify_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_modify_add_key_noval, + ldb_modify_test_setup, + ldb_modify_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_modify_replace_key, + ldb_modify_test_setup, + ldb_modify_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key, + ldb_modify_test_setup, + ldb_modify_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_modify_replace_zero_vals, + ldb_modify_test_setup, + ldb_modify_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key_zero_vals, + ldb_modify_test_setup, + ldb_modify_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_modify_del_key, + ldb_modify_test_setup, + ldb_modify_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_modify_del_keyval, + ldb_modify_test_setup, + ldb_modify_test_teardown), + cmocka_unit_test_setup_teardown(test_search_match_none, + ldb_search_test_setup, + ldb_search_test_teardown), + cmocka_unit_test_setup_teardown(test_search_match_one, + ldb_search_test_setup, + ldb_search_test_teardown), + cmocka_unit_test_setup_teardown(test_search_match_filter, + ldb_search_test_setup, + ldb_search_test_teardown), + cmocka_unit_test_setup_teardown(test_search_match_both, + ldb_search_test_setup, + ldb_search_test_teardown), + cmocka_unit_test_setup_teardown(test_search_match_basedn, + ldb_search_test_setup, + ldb_search_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_search_against_transaction, + ldb_search_test_setup, + ldb_search_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_modify_during_unindexed_search, + ldb_search_test_setup, + ldb_search_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_modify_during_indexed_search, + ldb_search_test_setup, + ldb_search_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_rename_during_unindexed_search, + ldb_search_test_setup, + ldb_search_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_rename_during_indexed_search, + ldb_search_test_setup, + ldb_search_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_callback_rename_during_unindexed_search, + ldb_search_test_setup, + ldb_search_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_callback_rename_during_indexed_search, + ldb_search_test_setup, + ldb_search_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_callback_delete_during_unindexed_search, + ldb_search_test_setup, + ldb_search_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_callback_delete_during_indexed_search, + ldb_search_test_setup, + ldb_search_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_modify_during_whole_search, + ldb_search_test_setup, + ldb_search_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_modify_before_ldb_wait, + ldb_search_test_setup, + ldb_search_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_attrs_case_insensitive, + ldb_case_test_setup, + ldb_case_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_attrs_case_handler, + ldb_case_test_setup, + ldb_case_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_attrs_index_handler, + ldb_case_test_setup, + ldb_case_attrs_index_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_rename, + ldb_rename_test_setup, + ldb_rename_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_rename_from_doesnt_exist, + ldb_rename_test_setup, + ldb_rename_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_rename_to_exists, + ldb_rename_test_setup, + ldb_rename_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_rename_self, + ldb_rename_test_setup, + ldb_rename_test_teardown), + cmocka_unit_test_setup_teardown(test_ldb_rename_dn_case_change, + ldb_rename_test_setup, + ldb_rename_test_teardown), + cmocka_unit_test_setup_teardown(test_read_only, + ldb_read_only_setup, + ldb_read_only_teardown), + cmocka_unit_test_setup_teardown( + test_ldb_add_unique_value_to_unique_index, + ldb_unique_index_test_setup, + ldb_unique_index_test_teardown), + cmocka_unit_test_setup_teardown( + test_ldb_add_duplicate_value_to_unique_index, + ldb_unique_index_test_setup, + ldb_unique_index_test_teardown), + cmocka_unit_test_setup_teardown( + test_ldb_add_to_index_duplicates_allowed, + ldb_non_unique_index_test_setup, + ldb_non_unique_index_test_teardown), + cmocka_unit_test_setup_teardown( + test_ldb_add_to_index_unique_values_required, + ldb_non_unique_index_test_setup, + ldb_non_unique_index_test_teardown), + /* These tests are not compatible with mdb */ + cmocka_unit_test_setup_teardown( + test_ldb_unique_index_duplicate_logging, + ldb_unique_index_test_setup, + ldb_unique_index_test_teardown), + cmocka_unit_test_setup_teardown( + test_ldb_duplicate_dn_logging, + ldb_unique_index_test_setup, + ldb_unique_index_test_teardown), + cmocka_unit_test_setup_teardown( + test_ldb_guid_index_duplicate_dn_logging, + ldb_guid_index_test_setup, + ldb_guid_index_test_teardown), + cmocka_unit_test_setup_teardown( + test_ldb_unique_index_duplicate_with_guid, + ldb_guid_index_test_setup, + ldb_guid_index_test_teardown), + cmocka_unit_test_setup_teardown( + test_ldb_talloc_destructor_transaction_cleanup, + ldbtest_setup, + ldbtest_teardown), +#ifdef TEST_LMDB + cmocka_unit_test_setup_teardown( + test_ldb_close_with_multiple_connections, + ldb_search_test_setup, + ldb_search_test_teardown), +#endif + cmocka_unit_test_setup_teardown( + test_transaction_start_across_fork, + ldbtest_setup, + ldbtest_teardown), + cmocka_unit_test_setup_teardown( + test_transaction_commit_across_fork, + ldbtest_setup, + ldbtest_teardown), + cmocka_unit_test_setup_teardown( + test_lock_read_across_fork, + ldbtest_setup, + ldbtest_teardown), + cmocka_unit_test_setup_teardown( + test_multiple_opens_across_fork, + ldbtest_setup, + ldbtest_teardown), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/ldb-2.0.8/tests/ldb_msg.c b/ldb-2.0.8/tests/ldb_msg.c new file mode 100644 index 0000000..31786a9 --- /dev/null +++ b/ldb-2.0.8/tests/ldb_msg.c @@ -0,0 +1,380 @@ +/* + * from cmocka.c: + * These headers or their equivalents should be included prior to + * including + * this header file. + * + * #include + * #include + * #include + * + * This allows test applications to use custom definitions of C standard + * library functions and types. + */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +struct test_ctx { + struct ldb_message *msg; +}; + +static int ldb_msg_setup(void **state) +{ + struct test_ctx *test_ctx; + + test_ctx = talloc_zero(NULL, struct test_ctx); + assert_non_null(test_ctx); + + test_ctx->msg = ldb_msg_new(test_ctx); + + *state = test_ctx; + return 0; +} + +static int ldb_msg_teardown(void **state) +{ + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + + talloc_free(test_ctx); + return 0; +} + + +static void add_uint_value(struct test_ctx *test_ctx, + struct ldb_message *msg, + const char *attr, + unsigned int x) +{ + int ret; + struct ldb_val v, v_dup; + char s[5]; + snprintf(s, sizeof(s), "%04x", x); + v.data = (uint8_t *)s; + v.length = 4; + v_dup = ldb_val_dup(test_ctx, &v); + assert_non_null(v_dup.data); + assert_ptr_not_equal(v_dup.data, v.data); + assert_int_equal(v_dup.length, 4); + + ret = ldb_msg_add_value(msg, attr, &v_dup, NULL); + assert_int_equal(ret, LDB_SUCCESS); +} + + +static void test_ldb_msg_find_duplicate_val(void **state) +{ + int ret; + unsigned int i; + struct test_ctx *test_ctx = talloc_get_type_abort(*state, + struct test_ctx); + struct ldb_message *msg = test_ctx->msg; + struct ldb_message_element *el; + struct ldb_val dummy; + struct ldb_val *dupe = &dummy; /* so we can tell it was modified to NULL, not left as NULL */ + + ret = ldb_msg_add_empty(msg, "el1", 0, &el); + assert_int_equal(ret, LDB_SUCCESS); + + /* An empty message contains no duplicates */ + ret = ldb_msg_find_duplicate_val(NULL, test_ctx, el, &dupe, 0); + assert_int_equal(ret, LDB_SUCCESS); + assert_null(dupe); + + for (i = 0; i < 5; i++) { + add_uint_value(test_ctx, msg, "el1", i); + } + /* at this point there are no duplicates, and the check uses the naive + quadratic path */ + ret = ldb_msg_find_duplicate_val(NULL, test_ctx, el, &dupe, 0); + assert_int_equal(ret, LDB_SUCCESS); + assert_null(dupe); + + /* add a duplicate, still using quadratric path */ + add_uint_value(test_ctx, msg, "el1", 3); + ret = ldb_msg_find_duplicate_val(NULL, test_ctx, el, &dupe, 0); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(dupe); + assert_int_equal(dupe->length, 4); + assert_memory_equal(dupe->data, "0003", 4); + + /* add some more, triggering algorithmic jump */ + for (i = 2; i < 11; i++) { + add_uint_value(test_ctx, msg, "el1", i); + } + ret = ldb_msg_find_duplicate_val(NULL, test_ctx, el, &dupe, 0); + assert_int_equal(ret, LDB_SUCCESS); + assert_non_null(dupe); + assert_int_equal(dupe->length, 4); + /*XXX not really guaranteed by the API */ + assert_memory_equal(dupe->data, "0002", 4); + + /* start a new element without duplicates, for the clever algorithm */ + ldb_msg_add_empty(msg, "el2", 0, &el); + for (i = 0; i < 12; i++) { + add_uint_value(test_ctx, msg, "el2", i); + } + ret = ldb_msg_find_duplicate_val(NULL, test_ctx, el, &dupe, 0); + assert_int_equal(ret, LDB_SUCCESS); + assert_null(dupe); +} + + +static struct ldb_message_element *new_msg_element(TALLOC_CTX *mem_ctx, + const char *name, + unsigned int value_offset, + unsigned int num_values) +{ + unsigned int i, x; + struct ldb_message_element *el = talloc_zero(mem_ctx, + struct ldb_message_element); + + el->values = talloc_array(el, struct ldb_val, num_values); + for (i = 0; i < num_values; i++) { + struct ldb_val v; + char s[50]; + v.data = (uint8_t *)s; + /* % 3 is to ensure the values list is unsorted */ + x = i + value_offset; + v.length = snprintf(s, sizeof(s), "%u %u", x % 3, x); + el->values[i] = ldb_val_dup(mem_ctx, &v); + } + el->name = name; + el->num_values = num_values; + return el; +} + +static void _assert_element_equal(struct ldb_message_element *a, + struct ldb_message_element *b, + const char * const file, + const int line) +{ + unsigned int i; + _assert_int_equal(a->num_values, b->num_values, file, line); + _assert_int_equal(a->flags, b->flags, file, line); + _assert_string_equal(a->name, b->name, file, line); + for (i = 0; i < a->num_values; i++) { + struct ldb_val *v1 = &a->values[i]; + struct ldb_val *v2 = &b->values[i]; + _assert_int_equal(v1->length, v2->length, file, line); + _assert_memory_equal(v1->data, v2->data, v1->length, + file, line); + } +} + +#define assert_element_equal(a, b) \ + _assert_element_equal((a), (b), \ + __FILE__, __LINE__) + + +static void test_ldb_msg_find_common_values(void **state) +{ + /* we only use the state as a talloc context */ + struct ldb_message_element *el, *el2, *el3, *el4, *el2b, *empty; + struct ldb_message_element *orig, *orig2, *orig3, *orig4; + int ret; + const uint32_t remove_dupes = LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES; + el = new_msg_element(*state, "test", 0, 4); + el2 = new_msg_element(*state, "test", 4, 4); + el3 = new_msg_element(*state, "test", 6, 4); + empty = new_msg_element(*state, "test", 0, 0); + orig = new_msg_element(*state, "test", 0, 4); + orig2 = new_msg_element(*state, "test", 4, 4); + orig3 = new_msg_element(*state, "test", 6, 4); + + /* first round is with short value arrays, using quadratic method */ + /* we expect no collisions here */ + ret = ldb_msg_find_common_values(NULL, *state, el, el2, 0); + assert_int_equal(ret, LDB_SUCCESS); + + /*or here */ + ret = ldb_msg_find_common_values(NULL, *state, el, el3, 0); + assert_int_equal(ret, LDB_SUCCESS); + + /* the same elements in reverse order */ + ret = ldb_msg_find_common_values(NULL, *state, el2, el, 0); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_msg_find_common_values(NULL, *state, el3, el, 0); + assert_int_equal(ret, LDB_SUCCESS); + + /* 6, 7 collide */ + ret = ldb_msg_find_common_values(NULL, *state, el2, el3, 0); + assert_int_equal(ret, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS); + + /* and again */ + ret = ldb_msg_find_common_values(NULL, *state, el3, el2, 0); + assert_int_equal(ret, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS); + + /* make sure the arrays haven't changed */ + assert_element_equal(el, orig); + assert_element_equal(el2, orig2); + assert_element_equal(el3, orig3); + + /* now with the control permisive flag, the first element should be + modified to remove the overlap.*/ + + /* 6, 7 collide, so el2 will only have 4 and 5 */ + ret = ldb_msg_find_common_values(NULL, *state, el2, el3, remove_dupes); + assert_int_equal(ret, LDB_SUCCESS); + + assert_element_equal(el3, orig3); + assert_int_not_equal(el2->num_values, orig2->num_values); + assert_int_equal(el2->num_values, 2); + el2b = new_msg_element(*state, "test", 4, 2); + assert_element_equal(el2, el2b); + + /* now try the same things with a long and a short value list. + this should still trigger the quadratic path. + */ + el2 = new_msg_element(*state, "test", 4, 10); + orig2 = new_msg_element(*state, "test", 4, 10); + + /* no collisions */ + ret = ldb_msg_find_common_values(NULL, *state, el, el2, 0); + assert_int_equal(ret, LDB_SUCCESS); + ret = ldb_msg_find_common_values(NULL, *state, el2, el, 0); + assert_int_equal(ret, LDB_SUCCESS); + + /*collisions */ + ret = ldb_msg_find_common_values(NULL, *state, el3, el2, 0); + assert_int_equal(ret, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS); + + assert_element_equal(el, orig); + assert_element_equal(el2, orig2); + assert_element_equal(el3, orig3); + + /*collisions with permissive flag*/ + ret = ldb_msg_find_common_values(NULL, *state, el3, el2, remove_dupes); + assert_int_equal(ret, LDB_SUCCESS); + assert_element_equal(el2, orig2); + assert_int_equal(el3->num_values, 0); + + /* permutations involving empty elements. + everything should succeed. */ + ret = ldb_msg_find_common_values(NULL, *state, el3, el2, 0); + assert_int_equal(ret, LDB_SUCCESS); + ret = ldb_msg_find_common_values(NULL, *state, el3, el, 0); + assert_int_equal(ret, LDB_SUCCESS); + ret = ldb_msg_find_common_values(NULL, *state, el2, el3, 0); + assert_int_equal(ret, LDB_SUCCESS); + assert_int_equal(el2->num_values, orig2->num_values); + ret = ldb_msg_find_common_values(NULL, *state, el3, el2, remove_dupes); + assert_int_equal(ret, LDB_SUCCESS); + assert_int_equal(el2->num_values, orig2->num_values); + assert_int_equal(el3->num_values, 0); /* el3 is now empty */ + ret = ldb_msg_find_common_values(NULL, *state, el2, el3, remove_dupes); + assert_int_equal(ret, LDB_SUCCESS); + ret = ldb_msg_find_common_values(NULL, *state, el3, empty, 0); + assert_int_equal(ret, LDB_SUCCESS); + ret = ldb_msg_find_common_values(NULL, *state, empty, empty, 0); + assert_int_equal(ret, LDB_SUCCESS); + ret = ldb_msg_find_common_values(NULL, *state, empty, el3, 0); + assert_int_equal(ret, LDB_SUCCESS); + + assert_element_equal(el2, orig2); + assert_element_equal(el, orig); + assert_int_equal(el3->num_values, 0); + + /* now with two large value lists */ + el = new_msg_element(*state, "test", 0, 12); + orig = new_msg_element(*state, "test", 0, 12); + el4 = new_msg_element(*state, "test", 12, 12); + orig4 = new_msg_element(*state, "test", 12, 12); + + /* no collisions */ + ret = ldb_msg_find_common_values(NULL, *state, el, el4, 0); + assert_int_equal(ret, LDB_SUCCESS); + + ret = ldb_msg_find_common_values(NULL, *state, el4, el, 0); + assert_int_equal(ret, LDB_SUCCESS); + + /* collisions */ + ret = ldb_msg_find_common_values(NULL, *state, el4, el2, 0); + assert_int_equal(ret, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS); + ret = ldb_msg_find_common_values(NULL, *state, el2, el4, 0); + assert_int_equal(ret, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS); + ret = ldb_msg_find_common_values(NULL, *state, el2, el, 0); + assert_int_equal(ret, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS); + + assert_element_equal(el, orig); + assert_element_equal(el2, orig2); + assert_element_equal(el4, orig4); + + /* with permissive control, but no collisions */ + ret = ldb_msg_find_common_values(NULL, *state, el, el4, remove_dupes); + assert_int_equal(ret, LDB_SUCCESS); + ret = ldb_msg_find_common_values(NULL, *state, el4, el, remove_dupes); + assert_int_equal(ret, LDB_SUCCESS); + + assert_element_equal(el, orig); + assert_element_equal(el4, orig4); + + /* now with collisions, thus modifications. + At this stage: + el is 0-11 (inclusive) + e2 is 4-13 + el3 is empty + el4 is 12-23 + */ + ret = ldb_msg_find_common_values(NULL, *state, el4, el2, remove_dupes); + assert_int_equal(ret, LDB_SUCCESS); + assert_element_equal(el2, orig2); + assert_int_not_equal(el4->num_values, orig4->num_values); + /* 4 should start at 14 */ + orig4 = new_msg_element(*state, "test", 14, 10); + assert_element_equal(el4, orig4); + + ret = ldb_msg_find_common_values(NULL, *state, el2, el, remove_dupes); + assert_int_equal(ret, LDB_SUCCESS); + assert_element_equal(el, orig); + assert_int_not_equal(el2->num_values, orig2->num_values); + orig2 = new_msg_element(*state, "test", 12, 2); + assert_element_equal(el2, orig2); + + /* test the empty el against the full elements */ + ret = ldb_msg_find_common_values(NULL, *state, el, empty, 0); + assert_int_equal(ret, LDB_SUCCESS); + ret = ldb_msg_find_common_values(NULL, *state, empty, el, 0); + assert_int_equal(ret, LDB_SUCCESS); + ret = ldb_msg_find_common_values(NULL, *state, el, empty, remove_dupes); + assert_int_equal(ret, LDB_SUCCESS); + ret = ldb_msg_find_common_values(NULL, *state, empty, el, remove_dupes); + assert_int_equal(ret, LDB_SUCCESS); + assert_element_equal(el, orig); + assert_element_equal(empty, el3); + + /* make sure an identical element with a different name is rejected */ + el2 = new_msg_element(*state, "fish", 12, 2); + ret = ldb_msg_find_common_values(NULL, *state, el2, el, remove_dupes); + assert_int_equal(ret, LDB_ERR_INAPPROPRIATE_MATCHING); +} + + + +int main(int argc, const char **argv) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown(test_ldb_msg_find_duplicate_val, + ldb_msg_setup, + ldb_msg_teardown), + cmocka_unit_test_setup_teardown( + test_ldb_msg_find_common_values, + ldb_msg_setup, + ldb_msg_teardown), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/ldb-2.0.8/tests/ldb_no_lmdb_test.c b/ldb-2.0.8/tests/ldb_no_lmdb_test.c new file mode 100644 index 0000000..8e5a6ee --- /dev/null +++ b/ldb-2.0.8/tests/ldb_no_lmdb_test.c @@ -0,0 +1,158 @@ +/* + * Ensure lmdb backend is disabled + * + * Copyright (C) Mathieu Parent 2019 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* + * Ensure lmdb backend is disabled + * + * Setup and tear down code copied from ldb_lmdb_test.c + */ + +/* + * from cmocka.c: + * These headers or their equivalents should be included prior to + * including + * this header file. + * + * #include + * #include + * #include + * + * This allows test applications to use custom definitions of C standard + * library functions and types. + * + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define TEST_BE "mdb" + +struct ldbtest_ctx { + struct tevent_context *ev; + struct ldb_context *ldb; + + const char *dbfile; + const char *lockfile; /* lockfile is separate */ + + const char *dbpath; +}; + +static void unlink_old_db(struct ldbtest_ctx *test_ctx) +{ + int ret; + + errno = 0; + ret = unlink(test_ctx->lockfile); + if (ret == -1 && errno != ENOENT) { + fail(); + } + + errno = 0; + ret = unlink(test_ctx->dbfile); + if (ret == -1 && errno != ENOENT) { + fail(); + } +} + +static int ldbtest_noconn_setup(void **state) +{ + struct ldbtest_ctx *test_ctx; + + test_ctx = talloc_zero(NULL, struct ldbtest_ctx); + assert_non_null(test_ctx); + + test_ctx->ev = tevent_context_init(test_ctx); + assert_non_null(test_ctx->ev); + + test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev); + assert_non_null(test_ctx->ldb); + + test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb"); + assert_non_null(test_ctx->dbfile); + + test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock", + test_ctx->dbfile); + assert_non_null(test_ctx->lockfile); + + test_ctx->dbpath = talloc_asprintf(test_ctx, + TEST_BE"://%s", test_ctx->dbfile); + assert_non_null(test_ctx->dbpath); + + unlink_old_db(test_ctx); + *state = test_ctx; + return 0; +} + +static int ldbtest_noconn_teardown(void **state) +{ + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + + unlink_old_db(test_ctx); + talloc_free(test_ctx); + return 0; +} + +static int ldbtest_setup(void **state) +{ + struct ldbtest_ctx *test_ctx; + int ret; + + ldbtest_noconn_setup((void **) &test_ctx); + + ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL); + assert_int_equal(ret, LDB_ERR_OTHER); + + *state = test_ctx; + return 0; +} + +static int ldbtest_teardown(void **state) +{ + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + ldbtest_noconn_teardown((void **) &test_ctx); + return 0; +} + +static void test_ldb_lmdb_not_found(void **state) +{ + // Actual test in ldbtest_setup + assert_int_equal(0, 0); +} + +int main(int argc, const char **argv) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown( + test_ldb_lmdb_not_found, + ldbtest_setup, + ldbtest_teardown), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/ldb-2.0.8/tests/ldb_parse_test.c b/ldb-2.0.8/tests/ldb_parse_test.c new file mode 100644 index 0000000..a739d77 --- /dev/null +++ b/ldb-2.0.8/tests/ldb_parse_test.c @@ -0,0 +1,93 @@ +/* + * Tests exercising the ldb parse operations. + * + * Copyright (C) Catalyst.NET Ltd 2017 + * Copyright (C) Michael Hanselmann 2019 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include +#include + +#include "../include/ldb.h" + +struct test_ctx +{ +}; + +static int setup(void **state) +{ + struct test_ctx *ctx; + + ctx = talloc_zero(NULL, struct test_ctx); + assert_non_null(ctx); + + *state = ctx; + + return 0; +} + +static int teardown(void **state) +{ + struct test_ctx *ctx = + talloc_get_type_abort(*state, struct test_ctx); + + talloc_free(ctx); + + return 0; +} + +static void test_roundtrip(TALLOC_CTX *mem_ctx, const char *filter, const char *expected) +{ + struct ldb_parse_tree *tree; + char *serialized; + + assert_non_null(filter); + assert_non_null(expected); + + tree = ldb_parse_tree(mem_ctx, filter); + assert_non_null(tree); + + serialized = ldb_filter_from_tree(mem_ctx, tree); + assert_non_null(serialized); + + assert_string_equal(serialized, expected); +} + +static void test_parse_filtertype(void **state) +{ + struct test_ctx *ctx = + talloc_get_type_abort(*state, struct test_ctx); + + test_roundtrip(ctx, "", "(|(objectClass=*)(distinguishedName=*))"); + test_roundtrip(ctx, "a=value", "(a=value)"); + test_roundtrip(ctx, "(|(foo=bar)(baz=hello))", "(|(foo=bar)(baz=hello))"); + test_roundtrip(ctx, " ", "(|(objectClass=*)(distinguishedName=*))"); +} + +int main(int argc, const char **argv) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown(test_parse_filtertype, setup, teardown), + }; + + cmocka_set_message_output(CM_OUTPUT_SUBUNIT); + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/ldb-2.0.8/tests/ldb_tdb_test.c b/ldb-2.0.8/tests/ldb_tdb_test.c new file mode 100644 index 0000000..ef91ba5 --- /dev/null +++ b/ldb-2.0.8/tests/ldb_tdb_test.c @@ -0,0 +1,389 @@ +/* + * lmdb backend specific tests for ldb + * + * Copyright (C) Andrew Bartlett 2018 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* + * lmdb backend specific tests for ldb + * + * Setup and tear down code copied from ldb_mod_op_test.c + */ + +/* + * from cmocka.c: + * These headers or their equivalents should be included prior to + * including + * this header file. + * + * #include + * #include + * #include + * + * This allows test applications to use custom definitions of C standard + * library functions and types. + * + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../ldb_tdb/ldb_tdb.h" +#include "../ldb_key_value/ldb_kv.h" + +#define TEST_BE "tdb" + +struct ldbtest_ctx { + struct tevent_context *ev; + struct ldb_context *ldb; + + const char *dbfile; + + const char *dbpath; +}; + +static void unlink_old_db(struct ldbtest_ctx *test_ctx) +{ + int ret; + + errno = 0; + ret = unlink(test_ctx->dbfile); + if (ret == -1 && errno != ENOENT) { + fail(); + } +} + +static int ldbtest_noconn_setup(void **state) +{ + struct ldbtest_ctx *test_ctx; + + test_ctx = talloc_zero(NULL, struct ldbtest_ctx); + assert_non_null(test_ctx); + + test_ctx->ev = tevent_context_init(test_ctx); + assert_non_null(test_ctx->ev); + + test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev); + assert_non_null(test_ctx->ldb); + + test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb"); + assert_non_null(test_ctx->dbfile); + + test_ctx->dbpath = talloc_asprintf(test_ctx, + TEST_BE"://%s", test_ctx->dbfile); + assert_non_null(test_ctx->dbpath); + + unlink_old_db(test_ctx); + *state = test_ctx; + return 0; +} + +static int ldbtest_noconn_teardown(void **state) +{ + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + + unlink_old_db(test_ctx); + talloc_free(test_ctx); + return 0; +} + +static int ldbtest_setup(void **state) +{ + struct ldbtest_ctx *test_ctx; + int ret; + struct ldb_ldif *ldif; + const char *index_ldif = \ + "dn: @INDEXLIST\n" + "@IDXGUID: objectUUID\n" + "@IDX_DN_GUID: GUID\n" + "\n"; + + ldbtest_noconn_setup((void **) &test_ctx); + + ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL); + assert_int_equal(ret, 0); + + while ((ldif = ldb_ldif_read_string(test_ctx->ldb, &index_ldif))) { + ret = ldb_add(test_ctx->ldb, ldif->msg); + assert_int_equal(ret, LDB_SUCCESS); + } + *state = test_ctx; + return 0; +} + +static int ldbtest_teardown(void **state) +{ + struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, + struct ldbtest_ctx); + ldbtest_noconn_teardown((void **) &test_ctx); + return 0; +} + + +static TDB_CONTEXT *get_tdb_context(struct ldb_context *ldb) +{ + void *data = NULL; + struct ldb_kv_private *ldb_kv = NULL; + TDB_CONTEXT *tdb = NULL; + + data = ldb_module_get_private(ldb->modules); + assert_non_null(data); + + ldb_kv = talloc_get_type(data, struct ldb_kv_private); + assert_non_null(ldb_kv); + + tdb = ldb_kv->tdb; + assert_non_null(tdb); + + return tdb; +} + +static void test_multiple_opens(void **state) +{ + struct ldb_context *ldb1 = NULL; + struct ldb_context *ldb2 = NULL; + struct ldb_context *ldb3 = NULL; + TDB_CONTEXT *tdb1 = NULL; + TDB_CONTEXT *tdb2 = NULL; + TDB_CONTEXT *tdb3 = NULL; + int ret; + struct ldbtest_ctx *test_ctx = NULL; + + test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); + + /* + * Open the database again + */ + ldb1 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); + assert_int_equal(ret, 0); + + ldb2 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb2, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); + assert_int_equal(ret, 0); + + ldb3 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL); + assert_int_equal(ret, 0); + /* + * We now have 3 ldb's open pointing to the same on disk database + * they should all share the same MDB_env + */ + tdb1 = get_tdb_context(ldb1); + tdb2 = get_tdb_context(ldb2); + tdb3 = get_tdb_context(ldb3); + + assert_ptr_equal(tdb1, tdb2); + assert_ptr_equal(tdb1, tdb3); +} + +static void test_multiple_opens_across_fork(void **state) +{ + struct ldb_context *ldb1 = NULL; + struct ldb_context *ldb2 = NULL; + TDB_CONTEXT *tdb1 = NULL; + TDB_CONTEXT *tdb2 = NULL; + int ret; + struct ldbtest_ctx *test_ctx = NULL; + int pipes[2]; + char buf[2]; + int wstatus; + pid_t pid, child_pid; + + test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); + + /* + * Open the database again + */ + ldb1 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); + assert_int_equal(ret, 0); + + ldb2 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb2, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); + assert_int_equal(ret, 0); + + tdb1 = get_tdb_context(ldb1); + tdb2 = get_tdb_context(ldb2); + + ret = pipe(pipes); + assert_int_equal(ret, 0); + + child_pid = fork(); + if (child_pid == 0) { + struct ldb_context *ldb3 = NULL; + TDB_CONTEXT *tdb3 = NULL; + + close(pipes[0]); + ldb3 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL); + if (ret != 0) { + print_error(__location__": ldb_connect returned (%d)\n", + ret); + exit(ret); + } + tdb3 = get_tdb_context(ldb3); + if (tdb1 != tdb2) { + print_error(__location__": tdb1 != tdb2\n"); + exit(LDB_ERR_OPERATIONS_ERROR); + } + if (tdb1 != tdb3) { + print_error(__location__": tdb1 != tdb3\n"); + exit(LDB_ERR_OPERATIONS_ERROR); + } + ret = write(pipes[1], "GO", 2); + if (ret != 2) { + print_error(__location__ + " write returned (%d)", + ret); + exit(LDB_ERR_OPERATIONS_ERROR); + } + exit(LDB_SUCCESS); + } + close(pipes[1]); + ret = read(pipes[0], buf, 2); + assert_int_equal(ret, 2); + + pid = waitpid(child_pid, &wstatus, 0); + assert_int_equal(pid, child_pid); + + assert_true(WIFEXITED(wstatus)); + + assert_int_equal(WEXITSTATUS(wstatus), 0); +} + +static void test_multiple_opens_across_fork_triggers_reopen(void **state) +{ + struct ldb_context *ldb1 = NULL; + struct ldb_context *ldb2 = NULL; + TDB_CONTEXT *tdb1 = NULL; + TDB_CONTEXT *tdb2 = NULL; + int ret; + struct ldbtest_ctx *test_ctx = NULL; + int pipes[2]; + char buf[2]; + int wstatus; + pid_t pid, child_pid; + + test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); + + /* + * Open the database again + */ + ldb1 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); + assert_int_equal(ret, 0); + + ldb2 = ldb_init(test_ctx, test_ctx->ev); + ret = ldb_connect(ldb2, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); + assert_int_equal(ret, 0); + + tdb1 = get_tdb_context(ldb1); + tdb2 = get_tdb_context(ldb2); + assert_ptr_equal(tdb1, tdb2); + + /* + * Break the internal tdb_reopen() by making a + * transaction + * + * This shows that the tdb_reopen() is called, which is + * essential if the host OS does not have pread() + */ + ret = tdb_transaction_start(tdb1); + assert_int_equal(ret, 0); + + ret = pipe(pipes); + assert_int_equal(ret, 0); + + child_pid = fork(); + if (child_pid == 0) { + struct ldb_context *ldb3 = NULL; + + close(pipes[0]); + ldb3 = ldb_init(test_ctx, test_ctx->ev); + + /* + * This should fail as we have taken out a lock + * against the raw TDB above, and tdb_reopen() + * will fail in that state. + * + * This check matters as tdb_reopen() is important + * if the host does not have pread() + */ + ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL); + if (ret == 0) { + print_error(__location__": ldb_connect expected " + "LDB_ERR_OPERATIONS_ERROR " + "returned (%d)\n", + ret); + exit(5000); + } + ret = write(pipes[1], "GO", 2); + if (ret != 2) { + print_error(__location__ + " write returned (%d)", + ret); + exit(LDB_ERR_OPERATIONS_ERROR); + } + exit(LDB_SUCCESS); + } + close(pipes[1]); + ret = read(pipes[0], buf, 2); + assert_int_equal(ret, 2); + + pid = waitpid(child_pid, &wstatus, 0); + assert_int_equal(pid, child_pid); + + assert_true(WIFEXITED(wstatus)); + + assert_int_equal(WEXITSTATUS(wstatus), 0); +} + +int main(int argc, const char **argv) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown( + test_multiple_opens, + ldbtest_setup, + ldbtest_teardown), + cmocka_unit_test_setup_teardown( + test_multiple_opens_across_fork, + ldbtest_setup, + ldbtest_teardown), + cmocka_unit_test_setup_teardown( + test_multiple_opens_across_fork_triggers_reopen, + ldbtest_setup, + ldbtest_teardown), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/ldb-2.0.8/tests/photo.ldif b/ldb-2.0.8/tests/photo.ldif new file mode 100644 index 0000000..95ab065 --- /dev/null +++ b/ldb-2.0.8/tests/photo.ldif @@ -0,0 +1,5 @@ +dn: cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST +changetype: modify +add: jpegPhoto +jpegPhoto:< file://tests/samba4.png + diff --git a/ldb-2.0.8/tests/python/api.py b/ldb-2.0.8/tests/python/api.py new file mode 100755 index 0000000..4d55566 --- /dev/null +++ b/ldb-2.0.8/tests/python/api.py @@ -0,0 +1,3326 @@ +#!/usr/bin/env python3 +# Simple tests for the ldb python bindings. +# Copyright (C) 2007 Jelmer Vernooij + +import os +from unittest import TestCase +import sys +import gc +import time +import ldb +import shutil + +PY3 = sys.version_info > (3, 0) + +TDB_PREFIX = "tdb://" +MDB_PREFIX = "mdb://" + +MDB_INDEX_OBJ = { + "dn": "@INDEXLIST", + "@IDXONE": [b"1"], + "@IDXGUID": [b"objectUUID"], + "@IDX_DN_GUID": [b"GUID"] +} + + +def tempdir(): + import tempfile + try: + dir_prefix = os.path.join(os.environ["SELFTEST_PREFIX"], "tmp") + except KeyError: + dir_prefix = None + return tempfile.mkdtemp(dir=dir_prefix) + + +class NoContextTests(TestCase): + + def test_valid_attr_name(self): + self.assertTrue(ldb.valid_attr_name("foo")) + self.assertFalse(ldb.valid_attr_name("24foo")) + + def test_timestring(self): + self.assertEqual("19700101000000.0Z", ldb.timestring(0)) + self.assertEqual("20071119191012.0Z", ldb.timestring(1195499412)) + + def test_string_to_time(self): + self.assertEqual(0, ldb.string_to_time("19700101000000.0Z")) + self.assertEqual(1195499412, ldb.string_to_time("20071119191012.0Z")) + + def test_binary_encode(self): + encoded = ldb.binary_encode(b'test\\x') + decoded = ldb.binary_decode(encoded) + self.assertEqual(decoded, b'test\\x') + + encoded2 = ldb.binary_encode('test\\x') + self.assertEqual(encoded2, encoded) + + +class LdbBaseTest(TestCase): + def setUp(self): + super(LdbBaseTest, self).setUp() + try: + if self.prefix is None: + self.prefix = TDB_PREFIX + except AttributeError: + self.prefix = TDB_PREFIX + + def tearDown(self): + super(LdbBaseTest, self).tearDown() + + def url(self): + return self.prefix + self.filename + + def flags(self): + if self.prefix == MDB_PREFIX: + return ldb.FLG_NOSYNC + else: + return 0 + + +class SimpleLdb(LdbBaseTest): + + def setUp(self): + super(SimpleLdb, self).setUp() + self.testdir = tempdir() + self.filename = os.path.join(self.testdir, "test.ldb") + self.ldb = ldb.Ldb(self.url(), flags=self.flags()) + try: + self.ldb.add(self.index) + except AttributeError: + pass + + def tearDown(self): + shutil.rmtree(self.testdir) + super(SimpleLdb, self).tearDown() + # Ensure the LDB is closed now, so we close the FD + del(self.ldb) + + def test_connect(self): + ldb.Ldb(self.url(), flags=self.flags()) + + def test_connect_none(self): + ldb.Ldb() + + def test_connect_later(self): + x = ldb.Ldb() + x.connect(self.url(), flags=self.flags()) + + def test_repr(self): + x = ldb.Ldb() + self.assertTrue(repr(x).startswith("]", repr(x.modules())) + + def test_firstmodule_none(self): + x = ldb.Ldb() + self.assertEqual(x.firstmodule, None) + + def test_firstmodule_tdb(self): + x = ldb.Ldb(self.url(), flags=self.flags()) + mod = x.firstmodule + self.assertEqual(repr(mod), "") + + def test_search(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + self.assertEqual(len(l.search()), 0) + + def test_search_controls(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + self.assertEqual(len(l.search(controls=["paged_results:0:5"])), 0) + + def test_utf8_ldb_Dn(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + dn = ldb.Dn(l, (b'a=' + b'\xc4\x85\xc4\x87\xc4\x99\xc5\x82\xc5\x84\xc3\xb3\xc5\x9b\xc5\xba\xc5\xbc').decode('utf8')) + + def test_utf8_encoded_ldb_Dn(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + dn_encoded_utf8 = b'a=' + b'\xc4\x85\xc4\x87\xc4\x99\xc5\x82\xc5\x84\xc3\xb3\xc5\x9b\xc5\xba\xc5\xbc' + try: + dn = ldb.Dn(l, dn_encoded_utf8) + except UnicodeDecodeError as e: + raise + except TypeError as te: + if PY3: + p3errors = ["argument 2 must be str, not bytes", + "Can't convert 'bytes' object to str implicitly"] + self.assertIn(str(te), p3errors) + else: + raise + + def test_search_attrs(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + self.assertEqual(len(l.search(ldb.Dn(l, ""), ldb.SCOPE_SUBTREE, "(dc=*)", ["dc"])), 0) + + def test_search_string_dn(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + self.assertEqual(len(l.search("", ldb.SCOPE_SUBTREE, "(dc=*)", ["dc"])), 0) + + def test_search_attr_string(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + self.assertRaises(TypeError, l.search, attrs="dc") + self.assertRaises(TypeError, l.search, attrs=b"dc") + + def test_opaque(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + l.set_opaque("my_opaque", l) + self.assertTrue(l.get_opaque("my_opaque") is not None) + self.assertEqual(None, l.get_opaque("unknown")) + + def test_search_scope_base_empty_db(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + self.assertEqual(len(l.search(ldb.Dn(l, "dc=foo1"), + ldb.SCOPE_BASE)), 0) + + def test_search_scope_onelevel_empty_db(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + self.assertEqual(len(l.search(ldb.Dn(l, "dc=foo1"), + ldb.SCOPE_ONELEVEL)), 0) + + def test_delete(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + self.assertRaises(ldb.LdbError, lambda: l.delete(ldb.Dn(l, "dc=foo2"))) + + def test_delete_w_unhandled_ctrl(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=foo1") + m["b"] = [b"a"] + m["objectUUID"] = b"0123456789abcdef" + l.add(m) + self.assertRaises(ldb.LdbError, lambda: l.delete(m.dn, ["search_options:1:2"])) + l.delete(m.dn) + + def test_contains(self): + name = self.url() + l = ldb.Ldb(name, flags=self.flags()) + self.assertFalse(ldb.Dn(l, "dc=foo3") in l) + l = ldb.Ldb(name, flags=self.flags()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=foo3") + m["b"] = ["a"] + m["objectUUID"] = b"0123456789abcdef" + l.add(m) + try: + self.assertTrue(ldb.Dn(l, "dc=foo3") in l) + self.assertFalse(ldb.Dn(l, "dc=foo4") in l) + finally: + l.delete(m.dn) + + def test_get_config_basedn(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + self.assertEqual(None, l.get_config_basedn()) + + def test_get_root_basedn(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + self.assertEqual(None, l.get_root_basedn()) + + def test_get_schema_basedn(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + self.assertEqual(None, l.get_schema_basedn()) + + def test_get_default_basedn(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + self.assertEqual(None, l.get_default_basedn()) + + def test_add(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=foo4") + m["bla"] = b"bla" + m["objectUUID"] = b"0123456789abcdef" + self.assertEqual(len(l.search()), 0) + l.add(m) + try: + self.assertEqual(len(l.search()), 1) + finally: + l.delete(ldb.Dn(l, "dc=foo4")) + + def test_search_iterator(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + s = l.search_iterator() + s.abandon() + try: + for me in s: + self.fail() + self.fail() + except RuntimeError as re: + pass + try: + s.abandon() + self.fail() + except RuntimeError as re: + pass + try: + s.result() + self.fail() + except RuntimeError as re: + pass + + s = l.search_iterator() + count = 0 + for me in s: + self.assertTrue(isinstance(me, ldb.Message)) + count += 1 + r = s.result() + self.assertEqual(len(r), 0) + self.assertEqual(count, 0) + + m1 = ldb.Message() + m1.dn = ldb.Dn(l, "dc=foo4") + m1["bla"] = b"bla" + m1["objectUUID"] = b"0123456789abcdef" + l.add(m1) + try: + s = l.search_iterator() + msgs = [] + for me in s: + self.assertTrue(isinstance(me, ldb.Message)) + count += 1 + msgs.append(me) + r = s.result() + self.assertEqual(len(r), 0) + self.assertEqual(len(msgs), 1) + self.assertEqual(msgs[0].dn, m1.dn) + + m2 = ldb.Message() + m2.dn = ldb.Dn(l, "dc=foo5") + m2["bla"] = b"bla" + m2["objectUUID"] = b"0123456789abcdee" + l.add(m2) + + s = l.search_iterator() + msgs = [] + for me in s: + self.assertTrue(isinstance(me, ldb.Message)) + count += 1 + msgs.append(me) + r = s.result() + self.assertEqual(len(r), 0) + self.assertEqual(len(msgs), 2) + if msgs[0].dn == m1.dn: + self.assertEqual(msgs[0].dn, m1.dn) + self.assertEqual(msgs[1].dn, m2.dn) + else: + self.assertEqual(msgs[0].dn, m2.dn) + self.assertEqual(msgs[1].dn, m1.dn) + + s = l.search_iterator() + msgs = [] + for me in s: + self.assertTrue(isinstance(me, ldb.Message)) + count += 1 + msgs.append(me) + break + try: + s.result() + self.fail() + except RuntimeError as re: + pass + for me in s: + self.assertTrue(isinstance(me, ldb.Message)) + count += 1 + msgs.append(me) + break + for me in s: + self.fail() + + r = s.result() + self.assertEqual(len(r), 0) + self.assertEqual(len(msgs), 2) + if msgs[0].dn == m1.dn: + self.assertEqual(msgs[0].dn, m1.dn) + self.assertEqual(msgs[1].dn, m2.dn) + else: + self.assertEqual(msgs[0].dn, m2.dn) + self.assertEqual(msgs[1].dn, m1.dn) + finally: + l.delete(ldb.Dn(l, "dc=foo4")) + l.delete(ldb.Dn(l, "dc=foo5")) + + def test_add_text(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=foo4") + m["bla"] = "bla" + m["objectUUID"] = b"0123456789abcdef" + self.assertEqual(len(l.search()), 0) + l.add(m) + try: + self.assertEqual(len(l.search()), 1) + finally: + l.delete(ldb.Dn(l, "dc=foo4")) + + def test_add_w_unhandled_ctrl(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=foo4") + m["bla"] = b"bla" + self.assertEqual(len(l.search()), 0) + self.assertRaises(ldb.LdbError, lambda: l.add(m, ["search_options:1:2"])) + + def test_add_dict(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + m = {"dn": ldb.Dn(l, "dc=foo5"), + "bla": b"bla", + "objectUUID": b"0123456789abcdef"} + self.assertEqual(len(l.search()), 0) + l.add(m) + try: + self.assertEqual(len(l.search()), 1) + finally: + l.delete(ldb.Dn(l, "dc=foo5")) + + def test_add_dict_text(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + m = {"dn": ldb.Dn(l, "dc=foo5"), + "bla": "bla", + "objectUUID": b"0123456789abcdef"} + self.assertEqual(len(l.search()), 0) + l.add(m) + try: + self.assertEqual(len(l.search()), 1) + finally: + l.delete(ldb.Dn(l, "dc=foo5")) + + def test_add_dict_string_dn(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + m = {"dn": "dc=foo6", "bla": b"bla", + "objectUUID": b"0123456789abcdef"} + self.assertEqual(len(l.search()), 0) + l.add(m) + try: + self.assertEqual(len(l.search()), 1) + finally: + l.delete(ldb.Dn(l, "dc=foo6")) + + def test_add_dict_bytes_dn(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + m = {"dn": b"dc=foo6", "bla": b"bla", + "objectUUID": b"0123456789abcdef"} + self.assertEqual(len(l.search()), 0) + l.add(m) + try: + self.assertEqual(len(l.search()), 1) + finally: + l.delete(ldb.Dn(l, "dc=foo6")) + + def test_rename(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=foo7") + m["bla"] = b"bla" + m["objectUUID"] = b"0123456789abcdef" + self.assertEqual(len(l.search()), 0) + l.add(m) + try: + l.rename(ldb.Dn(l, "dc=foo7"), ldb.Dn(l, "dc=bar")) + self.assertEqual(len(l.search()), 1) + finally: + l.delete(ldb.Dn(l, "dc=bar")) + + def test_rename_string_dns(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=foo8") + m["bla"] = b"bla" + m["objectUUID"] = b"0123456789abcdef" + self.assertEqual(len(l.search()), 0) + l.add(m) + self.assertEqual(len(l.search()), 1) + try: + l.rename("dc=foo8", "dc=bar") + self.assertEqual(len(l.search()), 1) + finally: + l.delete(ldb.Dn(l, "dc=bar")) + + def test_rename_bad_string_dns(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=foo8") + m["bla"] = b"bla" + m["objectUUID"] = b"0123456789abcdef" + self.assertEqual(len(l.search()), 0) + l.add(m) + self.assertEqual(len(l.search()), 1) + self.assertRaises(ldb.LdbError,lambda: l.rename("dcXfoo8", "dc=bar")) + self.assertRaises(ldb.LdbError,lambda: l.rename("dc=foo8", "dcXbar")) + l.delete(ldb.Dn(l, "dc=foo8")) + + def test_empty_dn(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + self.assertEqual(0, len(l.search())) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=empty") + m["objectUUID"] = b"0123456789abcdef" + l.add(m) + rm = l.search() + self.assertEqual(1, len(rm)) + self.assertEqual(set(["dn", "distinguishedName", "objectUUID"]), + set(rm[0].keys())) + + rm = l.search(m.dn) + self.assertEqual(1, len(rm)) + self.assertEqual(set(["dn", "distinguishedName", "objectUUID"]), + set(rm[0].keys())) + rm = l.search(m.dn, attrs=["blah"]) + self.assertEqual(1, len(rm)) + self.assertEqual(0, len(rm[0])) + + def test_modify_delete(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=modifydelete") + m["bla"] = [b"1234"] + m["objectUUID"] = b"0123456789abcdef" + l.add(m) + rm = l.search(m.dn)[0] + self.assertEqual([b"1234"], list(rm["bla"])) + try: + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=modifydelete") + m["bla"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "bla") + self.assertEqual(ldb.FLAG_MOD_DELETE, m["bla"].flags()) + l.modify(m) + rm = l.search(m.dn) + self.assertEqual(1, len(rm)) + self.assertEqual(set(["dn", "distinguishedName", "objectUUID"]), + set(rm[0].keys())) + rm = l.search(m.dn, attrs=["bla"]) + self.assertEqual(1, len(rm)) + self.assertEqual(0, len(rm[0])) + finally: + l.delete(ldb.Dn(l, "dc=modifydelete")) + + def test_modify_delete_text(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=modifydelete") + m.text["bla"] = ["1234"] + m["objectUUID"] = b"0123456789abcdef" + l.add(m) + rm = l.search(m.dn)[0] + self.assertEqual(["1234"], list(rm.text["bla"])) + try: + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=modifydelete") + m["bla"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "bla") + self.assertEqual(ldb.FLAG_MOD_DELETE, m["bla"].flags()) + l.modify(m) + rm = l.search(m.dn) + self.assertEqual(1, len(rm)) + self.assertEqual(set(["dn", "distinguishedName", "objectUUID"]), + set(rm[0].keys())) + rm = l.search(m.dn, attrs=["bla"]) + self.assertEqual(1, len(rm)) + self.assertEqual(0, len(rm[0])) + finally: + l.delete(ldb.Dn(l, "dc=modifydelete")) + + def test_modify_add(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=add") + m["bla"] = [b"1234"] + m["objectUUID"] = b"0123456789abcdef" + l.add(m) + try: + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=add") + m["bla"] = ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla") + self.assertEqual(ldb.FLAG_MOD_ADD, m["bla"].flags()) + l.modify(m) + rm = l.search(m.dn)[0] + self.assertEqual(3, len(rm)) + self.assertEqual([b"1234", b"456"], list(rm["bla"])) + finally: + l.delete(ldb.Dn(l, "dc=add")) + + def test_modify_add_text(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=add") + m.text["bla"] = ["1234"] + m["objectUUID"] = b"0123456789abcdef" + l.add(m) + try: + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=add") + m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") + self.assertEqual(ldb.FLAG_MOD_ADD, m["bla"].flags()) + l.modify(m) + rm = l.search(m.dn)[0] + self.assertEqual(3, len(rm)) + self.assertEqual(["1234", "456"], list(rm.text["bla"])) + finally: + l.delete(ldb.Dn(l, "dc=add")) + + def test_modify_replace(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=modify2") + m["bla"] = [b"1234", b"456"] + m["objectUUID"] = b"0123456789abcdef" + l.add(m) + try: + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=modify2") + m["bla"] = ldb.MessageElement([b"789"], ldb.FLAG_MOD_REPLACE, "bla") + self.assertEqual(ldb.FLAG_MOD_REPLACE, m["bla"].flags()) + l.modify(m) + rm = l.search(m.dn)[0] + self.assertEqual(3, len(rm)) + self.assertEqual([b"789"], list(rm["bla"])) + rm = l.search(m.dn, attrs=["bla"])[0] + self.assertEqual(1, len(rm)) + finally: + l.delete(ldb.Dn(l, "dc=modify2")) + + def test_modify_replace_text(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=modify2") + m.text["bla"] = ["1234", "456"] + m["objectUUID"] = b"0123456789abcdef" + l.add(m) + try: + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=modify2") + m["bla"] = ldb.MessageElement(["789"], ldb.FLAG_MOD_REPLACE, "bla") + self.assertEqual(ldb.FLAG_MOD_REPLACE, m["bla"].flags()) + l.modify(m) + rm = l.search(m.dn)[0] + self.assertEqual(3, len(rm)) + self.assertEqual(["789"], list(rm.text["bla"])) + rm = l.search(m.dn, attrs=["bla"])[0] + self.assertEqual(1, len(rm)) + finally: + l.delete(ldb.Dn(l, "dc=modify2")) + + def test_modify_flags_change(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=add") + m["bla"] = [b"1234"] + m["objectUUID"] = b"0123456789abcdef" + l.add(m) + try: + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=add") + m["bla"] = ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla") + self.assertEqual(ldb.FLAG_MOD_ADD, m["bla"].flags()) + l.modify(m) + rm = l.search(m.dn)[0] + self.assertEqual(3, len(rm)) + self.assertEqual([b"1234", b"456"], list(rm["bla"])) + + # Now create another modify, but switch the flags before we do it + m["bla"] = ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla") + m["bla"].set_flags(ldb.FLAG_MOD_DELETE) + l.modify(m) + rm = l.search(m.dn, attrs=["bla"])[0] + self.assertEqual(1, len(rm)) + self.assertEqual([b"1234"], list(rm["bla"])) + finally: + l.delete(ldb.Dn(l, "dc=add")) + + def test_modify_flags_change_text(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=add") + m.text["bla"] = ["1234"] + m["objectUUID"] = b"0123456789abcdef" + l.add(m) + try: + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=add") + m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") + self.assertEqual(ldb.FLAG_MOD_ADD, m["bla"].flags()) + l.modify(m) + rm = l.search(m.dn)[0] + self.assertEqual(3, len(rm)) + self.assertEqual(["1234", "456"], list(rm.text["bla"])) + + # Now create another modify, but switch the flags before we do it + m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") + m["bla"].set_flags(ldb.FLAG_MOD_DELETE) + l.modify(m) + rm = l.search(m.dn, attrs=["bla"])[0] + self.assertEqual(1, len(rm)) + self.assertEqual(["1234"], list(rm.text["bla"])) + finally: + l.delete(ldb.Dn(l, "dc=add")) + + def test_transaction_commit(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + l.transaction_start() + m = ldb.Message(ldb.Dn(l, "dc=foo9")) + m["foo"] = [b"bar"] + m["objectUUID"] = b"0123456789abcdef" + l.add(m) + l.transaction_commit() + l.delete(m.dn) + + def test_transaction_cancel(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + l.transaction_start() + m = ldb.Message(ldb.Dn(l, "dc=foo10")) + m["foo"] = [b"bar"] + m["objectUUID"] = b"0123456789abcdee" + l.add(m) + l.transaction_cancel() + self.assertEqual(0, len(l.search(ldb.Dn(l, "dc=foo10")))) + + def test_set_debug(self): + def my_report_fn(level, text): + pass + l = ldb.Ldb(self.url(), flags=self.flags()) + l.set_debug(my_report_fn) + + def test_zero_byte_string(self): + """Testing we do not get trapped in the \0 byte in a property string.""" + l = ldb.Ldb(self.url(), flags=self.flags()) + l.add({ + "dn": b"dc=somedn", + "objectclass": b"user", + "cN": b"LDAPtestUSER", + "givenname": b"ldap", + "displayname": b"foo\0bar", + "objectUUID": b"0123456789abcdef" + }) + res = l.search(expression="(dn=dc=somedn)") + self.assertEqual(b"foo\0bar", res[0]["displayname"][0]) + + def test_no_crash_broken_expr(self): + l = ldb.Ldb(self.url(), flags=self.flags()) + self.assertRaises(ldb.LdbError, lambda: l.search("", ldb.SCOPE_SUBTREE, "&(dc=*)(dn=*)", ["dc"])) + +# Run the SimpleLdb tests against an lmdb backend + + +class SimpleLdbLmdb(SimpleLdb): + + def setUp(self): + if os.environ.get('HAVE_LMDB', '1') == '0': + self.skipTest("No lmdb backend") + self.prefix = MDB_PREFIX + self.index = MDB_INDEX_OBJ + super(SimpleLdbLmdb, self).setUp() + + def tearDown(self): + super(SimpleLdbLmdb, self).tearDown() + + +class SimpleLdbNoLmdb(LdbBaseTest): + + def setUp(self): + if os.environ.get('HAVE_LMDB', '1') != '0': + self.skipTest("lmdb backend enabled") + self.prefix = MDB_PREFIX + self.index = MDB_INDEX_OBJ + super(SimpleLdbNoLmdb, self).setUp() + + def tearDown(self): + super(SimpleLdbNoLmdb, self).tearDown() + + def test_lmdb_disabled(self): + self.testdir = tempdir() + self.filename = os.path.join(self.testdir, "test.ldb") + try: + self.ldb = ldb.Ldb(self.url(), flags=self.flags()) + self.fail("Should have failed on missing LMDB") + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_OTHER) + + +class SearchTests(LdbBaseTest): + def tearDown(self): + shutil.rmtree(self.testdir) + super(SearchTests, self).tearDown() + + # Ensure the LDB is closed now, so we close the FD + del(self.l) + + def setUp(self): + super(SearchTests, self).setUp() + self.testdir = tempdir() + self.filename = os.path.join(self.testdir, "search_test.ldb") + options = ["modules:rdn_name"] + if hasattr(self, 'IDXCHECK'): + options.append("disable_full_db_scan_for_self_test:1") + self.l = ldb.Ldb(self.url(), + flags=self.flags(), + options=options) + try: + self.l.add(self.index) + except AttributeError: + pass + + self.l.add({"dn": "@ATTRIBUTES", + "DC": "CASE_INSENSITIVE"}) + + # Note that we can't use the name objectGUID here, as we + # want to stay clear of the objectGUID handler in LDB and + # instead use just the 16 bytes raw, which we just keep + # to printable chars here for ease of handling. + + self.l.add({"dn": "DC=SAMBA,DC=ORG", + "name": b"samba.org", + "objectUUID": b"0123456789abcdef"}) + self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"0123456789abcde1"}) + self.l.add({"dn": "OU=USERS,DC=SAMBA,DC=ORG", + "name": b"Users", + "x": "z", "y": "a", + "objectUUID": b"0123456789abcde2"}) + self.l.add({"dn": "OU=OU1,DC=SAMBA,DC=ORG", + "name": b"OU #1", + "x": "y", "y": "a", + "objectUUID": b"0123456789abcde3"}) + self.l.add({"dn": "OU=OU2,DC=SAMBA,DC=ORG", + "name": b"OU #2", + "x": "y", "y": "a", + "objectUUID": b"0123456789abcde4"}) + self.l.add({"dn": "OU=OU3,DC=SAMBA,DC=ORG", + "name": b"OU #3", + "x": "y", "y": "a", + "objectUUID": b"0123456789abcde5"}) + self.l.add({"dn": "OU=OU4,DC=SAMBA,DC=ORG", + "name": b"OU #4", + "x": "y", "y": "a", + "objectUUID": b"0123456789abcde6"}) + self.l.add({"dn": "OU=OU5,DC=SAMBA,DC=ORG", + "name": b"OU #5", + "x": "y", "y": "a", + "objectUUID": b"0123456789abcde7"}) + self.l.add({"dn": "OU=OU6,DC=SAMBA,DC=ORG", + "name": b"OU #6", + "x": "y", "y": "a", + "objectUUID": b"0123456789abcde8"}) + self.l.add({"dn": "OU=OU7,DC=SAMBA,DC=ORG", + "name": b"OU #7", + "x": "y", "y": "a", + "objectUUID": b"0123456789abcde9"}) + self.l.add({"dn": "OU=OU8,DC=SAMBA,DC=ORG", + "name": b"OU #8", + "x": "y", "y": "a", + "objectUUID": b"0123456789abcde0"}) + self.l.add({"dn": "OU=OU9,DC=SAMBA,DC=ORG", + "name": b"OU #9", + "x": "y", "y": "a", + "objectUUID": b"0123456789abcdea"}) + self.l.add({"dn": "OU=OU10,DC=SAMBA,DC=ORG", + "name": b"OU #10", + "x": "y", "y": "a", + "objectUUID": b"0123456789abcdeb"}) + self.l.add({"dn": "OU=OU11,DC=SAMBA,DC=ORG", + "name": b"OU #10", + "x": "y", "y": "a", + "objectUUID": b"0123456789abcdec"}) + self.l.add({"dn": "OU=OU12,DC=SAMBA,DC=ORG", + "name": b"OU #10", + "x": "y", "y": "b", + "objectUUID": b"0123456789abcded"}) + self.l.add({"dn": "OU=OU13,DC=SAMBA,DC=ORG", + "name": b"OU #10", + "x": "x", "y": "b", + "objectUUID": b"0123456789abcdee"}) + self.l.add({"dn": "OU=OU14,DC=SAMBA,DC=ORG", + "name": b"OU #10", + "x": "x", "y": "b", + "objectUUID": b"0123456789abcd01"}) + self.l.add({"dn": "OU=OU15,DC=SAMBA,DC=ORG", + "name": b"OU #10", + "x": "x", "y": "b", + "objectUUID": b"0123456789abcd02"}) + self.l.add({"dn": "OU=OU16,DC=SAMBA,DC=ORG", + "name": b"OU #10", + "x": "x", "y": "b", + "objectUUID": b"0123456789abcd03"}) + self.l.add({"dn": "OU=OU17,DC=SAMBA,DC=ORG", + "name": b"OU #10", + "x": "x", "y": "b", + "objectUUID": b"0123456789abcd04"}) + self.l.add({"dn": "OU=OU18,DC=SAMBA,DC=ORG", + "name": b"OU #10", + "x": "x", "y": "b", + "objectUUID": b"0123456789abcd05"}) + self.l.add({"dn": "OU=OU19,DC=SAMBA,DC=ORG", + "name": b"OU #10", + "x": "x", "y": "b", + "objectUUID": b"0123456789abcd06"}) + self.l.add({"dn": "OU=OU20,DC=SAMBA,DC=ORG", + "name": b"OU #10", + "x": "x", "y": "b", + "objectUUID": b"0123456789abcd07"}) + self.l.add({"dn": "OU=OU21,DC=SAMBA,DC=ORG", + "name": b"OU #10", + "x": "x", "y": "c", + "objectUUID": b"0123456789abcd08"}) + self.l.add({"dn": "OU=OU22,DC=SAMBA,DC=ORG", + "name": b"OU #10", + "x": "x", "y": "c", + "objectUUID": b"0123456789abcd09"}) + + def test_base(self): + """Testing a search""" + + res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_BASE) + self.assertEqual(len(res11), 1) + + def test_base_lower(self): + """Testing a search""" + + res11 = self.l.search(base="OU=OU11,DC=samba,DC=org", + scope=ldb.SCOPE_BASE) + self.assertEqual(len(res11), 1) + + def test_base_or(self): + """Testing a search""" + + res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_BASE, + expression="(|(ou=ou11)(ou=ou12))") + self.assertEqual(len(res11), 1) + + def test_base_or2(self): + """Testing a search""" + + res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_BASE, + expression="(|(x=y)(y=b))") + self.assertEqual(len(res11), 1) + + def test_base_and(self): + """Testing a search""" + + res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_BASE, + expression="(&(ou=ou11)(ou=ou12))") + self.assertEqual(len(res11), 0) + + def test_base_and2(self): + """Testing a search""" + + res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_BASE, + expression="(&(x=y)(y=a))") + self.assertEqual(len(res11), 1) + + def test_base_false(self): + """Testing a search""" + + res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_BASE, + expression="(|(ou=ou13)(ou=ou12))") + self.assertEqual(len(res11), 0) + + def test_check_base_false(self): + """Testing a search""" + res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_BASE, + expression="(|(ou=ou13)(ou=ou12))") + self.assertEqual(len(res11), 0) + + def test_check_base_error(self): + """Testing a search""" + checkbaseonsearch = {"dn": "@OPTIONS", + "checkBaseOnSearch": b"TRUE"} + try: + self.l.add(checkbaseonsearch) + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) + m = ldb.Message.from_dict(self.l, + checkbaseonsearch) + self.l.modify(m) + + try: + res11 = self.l.search(base="OU=OU11x,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_BASE, + expression="(|(ou=ou13)(ou=ou12))") + self.fail("Should have failed on missing base") + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_NO_SUCH_OBJECT) + + def test_subtree_and(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(&(ou=ou11)(ou=ou12))") + self.assertEqual(len(res11), 0) + + def test_subtree_and2(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(&(x=y)(|(y=b)(y=c)))") + self.assertEqual(len(res11), 1) + + def test_subtree_and2_lower(self): + """Testing a search""" + + res11 = self.l.search(base="DC=samba,DC=org", + scope=ldb.SCOPE_SUBTREE, + expression="(&(x=y)(|(y=b)(y=c)))") + self.assertEqual(len(res11), 1) + + def test_subtree_or(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(|(ou=ou11)(ou=ou12))") + self.assertEqual(len(res11), 2) + + def test_subtree_or2(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(|(x=y)(y=b))") + self.assertEqual(len(res11), 20) + + def test_subtree_or3(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(|(x=y)(y=b)(y=c))") + self.assertEqual(len(res11), 22) + + def test_one_and(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(&(ou=ou11)(ou=ou12))") + self.assertEqual(len(res11), 0) + + def test_one_and2(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(&(x=y)(y=b))") + self.assertEqual(len(res11), 1) + + def test_one_or(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(|(ou=ou11)(ou=ou12))") + self.assertEqual(len(res11), 2) + + def test_one_or2(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(|(x=y)(y=b))") + self.assertEqual(len(res11), 20) + + def test_one_or2_lower(self): + """Testing a search""" + + res11 = self.l.search(base="DC=samba,DC=org", + scope=ldb.SCOPE_ONELEVEL, + expression="(|(x=y)(y=b))") + self.assertEqual(len(res11), 20) + + def test_one_unindexable(self): + """Testing a search""" + + try: + res11 = self.l.search(base="DC=samba,DC=org", + scope=ldb.SCOPE_ONELEVEL, + expression="(y=b*)") + if hasattr(self, 'IDX') and \ + not hasattr(self, 'IDXONE') and \ + hasattr(self, 'IDXCHECK'): + self.fail("Should have failed as un-indexed search") + + self.assertEqual(len(res11), 9) + + except ldb.LdbError as err: + enum = err.args[0] + estr = err.args[1] + self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING) + self.assertIn(estr, "ldb FULL SEARCH disabled") + + def test_one_unindexable_presence(self): + """Testing a search""" + + try: + res11 = self.l.search(base="DC=samba,DC=org", + scope=ldb.SCOPE_ONELEVEL, + expression="(y=*)") + if hasattr(self, 'IDX') and \ + not hasattr(self, 'IDXONE') and \ + hasattr(self, 'IDXCHECK'): + self.fail("Should have failed as un-indexed search") + + self.assertEqual(len(res11), 24) + + except ldb.LdbError as err: + enum = err.args[0] + estr = err.args[1] + self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING) + self.assertIn(estr, "ldb FULL SEARCH disabled") + + def test_subtree_and_or(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(&(|(x=z)(y=b))(x=x)(y=c))") + self.assertEqual(len(res11), 0) + + def test_subtree_and_or2(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(&(x=x)(y=c)(|(x=z)(y=b)))") + self.assertEqual(len(res11), 0) + + def test_subtree_and_or3(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(&(|(ou=ou11)(ou=ou10))(|(x=y)(y=b)(y=c)))") + self.assertEqual(len(res11), 2) + + def test_subtree_and_or4(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(&(|(x=y)(y=b)(y=c))(|(ou=ou11)(ou=ou10)))") + self.assertEqual(len(res11), 2) + + def test_subtree_and_or5(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(&(|(x=y)(y=b)(y=c))(ou=ou11))") + self.assertEqual(len(res11), 1) + + def test_subtree_or_and(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(|(x=x)(y=c)(&(x=z)(y=b)))") + self.assertEqual(len(res11), 10) + + def test_subtree_large_and_unique(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(&(ou=ou10)(y=a))") + self.assertEqual(len(res11), 1) + + def test_subtree_and_none(self): + """Testing a search""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(&(ou=ouX)(y=a))") + self.assertEqual(len(res11), 0) + + def test_subtree_and_idx_record(self): + """Testing a search against the index record""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(@IDXDN=DC=SAMBA,DC=ORG)") + self.assertEqual(len(res11), 0) + + def test_subtree_and_idxone_record(self): + """Testing a search against the index record""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(@IDXONE=DC=SAMBA,DC=ORG)") + self.assertEqual(len(res11), 0) + + def test_subtree_unindexable(self): + """Testing a search""" + + try: + res11 = self.l.search(base="DC=samba,DC=org", + scope=ldb.SCOPE_SUBTREE, + expression="(y=b*)") + if hasattr(self, 'IDX') and \ + hasattr(self, 'IDXCHECK'): + self.fail("Should have failed as un-indexed search") + + self.assertEqual(len(res11), 9) + + except ldb.LdbError as err: + enum = err.args[0] + estr = err.args[1] + self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING) + self.assertIn(estr, "ldb FULL SEARCH disabled") + + def test_subtree_unindexable_presence(self): + """Testing a search""" + + try: + res11 = self.l.search(base="DC=samba,DC=org", + scope=ldb.SCOPE_SUBTREE, + expression="(y=*)") + if hasattr(self, 'IDX') and \ + hasattr(self, 'IDXCHECK'): + self.fail("Should have failed as un-indexed search") + + self.assertEqual(len(res11), 24) + + except ldb.LdbError as err: + enum = err.args[0] + estr = err.args[1] + self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING) + self.assertIn(estr, "ldb FULL SEARCH disabled") + + def test_dn_filter_one(self): + """Testing that a dn= filter succeeds + (or fails with disallowDNFilter + set and IDXGUID or (IDX and not IDXONE) mode) + when the scope is SCOPE_ONELEVEL. + + This should be made more consistent, but for now lock in + the behaviour + + """ + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(dn=OU=OU1,DC=SAMBA,DC=ORG)") + if hasattr(self, 'disallowDNFilter') and \ + hasattr(self, 'IDX') and \ + (hasattr(self, 'IDXGUID') or + ((hasattr(self, 'IDXONE') == False and hasattr(self, 'IDX')))): + self.assertEqual(len(res11), 0) + else: + self.assertEqual(len(res11), 1) + + def test_dn_filter_subtree(self): + """Testing that a dn= filter succeeds + (or fails with disallowDNFilter set) + when the scope is SCOPE_SUBTREE""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(dn=OU=OU1,DC=SAMBA,DC=ORG)") + if hasattr(self, 'disallowDNFilter') \ + and hasattr(self, 'IDX'): + self.assertEqual(len(res11), 0) + else: + self.assertEqual(len(res11), 1) + + def test_dn_filter_base(self): + """Testing that (incorrectly) a dn= filter works + when the scope is SCOPE_BASE""" + + res11 = self.l.search(base="OU=OU1,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_BASE, + expression="(dn=OU=OU1,DC=SAMBA,DC=ORG)") + + # At some point we should fix this, but it isn't trivial + self.assertEqual(len(res11), 1) + + def test_distinguishedName_filter_one(self): + """Testing that a distinguishedName= filter succeeds + when the scope is SCOPE_ONELEVEL. + + This should be made more consistent, but for now lock in + the behaviour + + """ + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(distinguishedName=OU=OU1,DC=SAMBA,DC=ORG)") + self.assertEqual(len(res11), 1) + + def test_distinguishedName_filter_subtree(self): + """Testing that a distinguishedName= filter succeeds + when the scope is SCOPE_SUBTREE""" + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(distinguishedName=OU=OU1,DC=SAMBA,DC=ORG)") + self.assertEqual(len(res11), 1) + + def test_distinguishedName_filter_base(self): + """Testing that (incorrectly) a distinguishedName= filter works + when the scope is SCOPE_BASE""" + + res11 = self.l.search(base="OU=OU1,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_BASE, + expression="(distinguishedName=OU=OU1,DC=SAMBA,DC=ORG)") + + # At some point we should fix this, but it isn't trivial + self.assertEqual(len(res11), 1) + + def test_bad_dn_filter_base(self): + """Testing that a dn= filter on an invalid DN works + when the scope is SCOPE_BASE but + returns zero results""" + + res11 = self.l.search(base="OU=OU1,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_BASE, + expression="(dn=OU=OU1,DC=SAMBA,DCXXXX)") + + # At some point we should fix this, but it isn't trivial + self.assertEqual(len(res11), 0) + + + def test_bad_dn_filter_one(self): + """Testing that a dn= filter succeeds but returns zero + results when the DN is not valid on a SCOPE_ONELEVEL search + + """ + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(dn=OU=OU1,DC=SAMBA,DCXXXX)") + self.assertEqual(len(res11), 0) + + def test_bad_dn_filter_subtree(self): + """Testing that a dn= filter succeeds but returns zero + results when the DN is not valid on a SCOPE_SUBTREE search + + """ + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(dn=OU=OU1,DC=SAMBA,DCXXXX)") + self.assertEqual(len(res11), 0) + + def test_bad_distinguishedName_filter_base(self): + """Testing that a distinguishedName= filter on an invalid DN works + when the scope is SCOPE_BASE but + returns zero results""" + + res11 = self.l.search(base="OU=OU1,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_BASE, + expression="(distinguishedName=OU=OU1,DC=SAMBA,DCXXXX)") + + # At some point we should fix this, but it isn't trivial + self.assertEqual(len(res11), 0) + + + def test_bad_distinguishedName_filter_one(self): + """Testing that a distinguishedName= filter succeeds but returns zero + results when the DN is not valid on a SCOPE_ONELEVEL search + + """ + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression="(distinguishedName=OU=OU1,DC=SAMBA,DCXXXX)") + self.assertEqual(len(res11), 0) + + def test_bad_distinguishedName_filter_subtree(self): + """Testing that a distinguishedName= filter succeeds but returns zero + results when the DN is not valid on a SCOPE_SUBTREE search + + """ + + res11 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(distinguishedName=OU=OU1,DC=SAMBA,DCXXXX)") + self.assertEqual(len(res11), 0) + + def test_bad_dn_search_base(self): + """Testing with a bad base DN (SCOPE_BASE)""" + + try: + res11 = self.l.search(base="OU=OU1,DC=SAMBA,DCXXX", + scope=ldb.SCOPE_BASE) + self.fail("Should have failed with ERR_INVALID_DN_SYNTAX") + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_INVALID_DN_SYNTAX) + + + def test_bad_dn_search_one(self): + """Testing with a bad base DN (SCOPE_ONELEVEL)""" + + try: + res11 = self.l.search(base="DC=SAMBA,DCXXXX", + scope=ldb.SCOPE_ONELEVEL) + self.fail("Should have failed with ERR_INVALID_DN_SYNTAX") + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_INVALID_DN_SYNTAX) + + def test_bad_dn_search_subtree(self): + """Testing with a bad base DN (SCOPE_SUBTREE)""" + + try: + res11 = self.l.search(base="DC=SAMBA,DCXXXX", + scope=ldb.SCOPE_SUBTREE) + self.fail("Should have failed with ERR_INVALID_DN_SYNTAX") + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_INVALID_DN_SYNTAX) + + + +# Run the search tests against an lmdb backend +class SearchTestsLmdb(SearchTests): + + def setUp(self): + if os.environ.get('HAVE_LMDB', '1') == '0': + self.skipTest("No lmdb backend") + self.prefix = MDB_PREFIX + self.index = MDB_INDEX_OBJ + super(SearchTestsLmdb, self).setUp() + + def tearDown(self): + super(SearchTestsLmdb, self).tearDown() + + +class IndexedSearchTests(SearchTests): + """Test searches using the index, to ensure the index doesn't + break things""" + + def setUp(self): + super(IndexedSearchTests, self).setUp() + self.l.add({"dn": "@INDEXLIST", + "@IDXATTR": [b"x", b"y", b"ou"]}) + self.IDX = True + + +class IndexedCheckSearchTests(IndexedSearchTests): + """Test searches using the index, to ensure the index doesn't + break things (full scan disabled)""" + + def setUp(self): + self.IDXCHECK = True + super(IndexedCheckSearchTests, self).setUp() + + +class IndexedSearchDnFilterTests(SearchTests): + """Test searches using the index, to ensure the index doesn't + break things""" + + def setUp(self): + super(IndexedSearchDnFilterTests, self).setUp() + self.l.add({"dn": "@OPTIONS", + "disallowDNFilter": "TRUE"}) + self.disallowDNFilter = True + + self.l.add({"dn": "@INDEXLIST", + "@IDXATTR": [b"x", b"y", b"ou"]}) + self.IDX = True + + +class IndexedAndOneLevelSearchTests(SearchTests): + """Test searches using the index including @IDXONE, to ensure + the index doesn't break things""" + + def setUp(self): + super(IndexedAndOneLevelSearchTests, self).setUp() + self.l.add({"dn": "@INDEXLIST", + "@IDXATTR": [b"x", b"y", b"ou"], + "@IDXONE": [b"1"]}) + self.IDX = True + self.IDXONE = True + + +class IndexedCheckedAndOneLevelSearchTests(IndexedAndOneLevelSearchTests): + """Test searches using the index including @IDXONE, to ensure + the index doesn't break things (full scan disabled)""" + + def setUp(self): + self.IDXCHECK = True + super(IndexedCheckedAndOneLevelSearchTests, self).setUp() + + +class IndexedAndOneLevelDNFilterSearchTests(SearchTests): + """Test searches using the index including @IDXONE, to ensure + the index doesn't break things""" + + def setUp(self): + super(IndexedAndOneLevelDNFilterSearchTests, self).setUp() + self.l.add({"dn": "@OPTIONS", + "disallowDNFilter": "TRUE", + "checkBaseOnSearch": "TRUE"}) + self.disallowDNFilter = True + self.checkBaseOnSearch = True + + self.l.add({"dn": "@INDEXLIST", + "@IDXATTR": [b"x", b"y", b"ou"], + "@IDXONE": [b"1"]}) + self.IDX = True + self.IDXONE = True + + +class GUIDIndexedSearchTests(SearchTests): + """Test searches using the index, to ensure the index doesn't + break things""" + + def setUp(self): + self.index = {"dn": "@INDEXLIST", + "@IDXATTR": [b"x", b"y", b"ou"], + "@IDXGUID": [b"objectUUID"], + "@IDX_DN_GUID": [b"GUID"]} + super(GUIDIndexedSearchTests, self).setUp() + + self.IDXGUID = True + self.IDXONE = True + + +class GUIDIndexedDNFilterSearchTests(SearchTests): + """Test searches using the index, to ensure the index doesn't + break things""" + + def setUp(self): + self.index = {"dn": "@INDEXLIST", + "@IDXATTR": [b"x", b"y", b"ou"], + "@IDXGUID": [b"objectUUID"], + "@IDX_DN_GUID": [b"GUID"]} + super(GUIDIndexedDNFilterSearchTests, self).setUp() + self.l.add({"dn": "@OPTIONS", + "disallowDNFilter": "TRUE", + "checkBaseOnSearch": "TRUE"}) + self.disallowDNFilter = True + self.checkBaseOnSearch = True + self.IDX = True + self.IDXGUID = True + + +class GUIDAndOneLevelIndexedSearchTests(SearchTests): + """Test searches using the index including @IDXONE, to ensure + the index doesn't break things""" + + def setUp(self): + self.index = {"dn": "@INDEXLIST", + "@IDXATTR": [b"x", b"y", b"ou"], + "@IDXGUID": [b"objectUUID"], + "@IDX_DN_GUID": [b"GUID"]} + super(GUIDAndOneLevelIndexedSearchTests, self).setUp() + self.l.add({"dn": "@OPTIONS", + "disallowDNFilter": "TRUE", + "checkBaseOnSearch": "TRUE"}) + self.disallowDNFilter = True + self.checkBaseOnSearch = True + self.IDX = True + self.IDXGUID = True + self.IDXONE = True + + +class GUIDIndexedSearchTestsLmdb(GUIDIndexedSearchTests): + + def setUp(self): + if os.environ.get('HAVE_LMDB', '1') == '0': + self.skipTest("No lmdb backend") + self.prefix = MDB_PREFIX + super(GUIDIndexedSearchTestsLmdb, self).setUp() + + def tearDown(self): + super(GUIDIndexedSearchTestsLmdb, self).tearDown() + + +class GUIDIndexedDNFilterSearchTestsLmdb(GUIDIndexedDNFilterSearchTests): + + def setUp(self): + if os.environ.get('HAVE_LMDB', '1') == '0': + self.skipTest("No lmdb backend") + self.prefix = MDB_PREFIX + super(GUIDIndexedDNFilterSearchTestsLmdb, self).setUp() + + def tearDown(self): + super(GUIDIndexedDNFilterSearchTestsLmdb, self).tearDown() + + +class GUIDAndOneLevelIndexedSearchTestsLmdb(GUIDAndOneLevelIndexedSearchTests): + + def setUp(self): + if os.environ.get('HAVE_LMDB', '1') == '0': + self.skipTest("No lmdb backend") + self.prefix = MDB_PREFIX + super(GUIDAndOneLevelIndexedSearchTestsLmdb, self).setUp() + + def tearDown(self): + super(GUIDAndOneLevelIndexedSearchTestsLmdb, self).tearDown() + + +class AddModifyTests(LdbBaseTest): + def tearDown(self): + shutil.rmtree(self.testdir) + super(AddModifyTests, self).tearDown() + + # Ensure the LDB is closed now, so we close the FD + del(self.l) + + def setUp(self): + super(AddModifyTests, self).setUp() + self.testdir = tempdir() + self.filename = os.path.join(self.testdir, "add_test.ldb") + self.l = ldb.Ldb(self.url(), + flags=self.flags(), + options=["modules:rdn_name"]) + try: + self.l.add(self.index) + except AttributeError: + pass + + self.l.add({"dn": "DC=SAMBA,DC=ORG", + "name": b"samba.org", + "objectUUID": b"0123456789abcdef"}) + self.l.add({"dn": "@ATTRIBUTES", + "objectUUID": "UNIQUE_INDEX"}) + + def test_add_dup(self): + self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"0123456789abcde1"}) + try: + self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"0123456789abcde2"}) + self.fail("Should have failed adding dupliate entry") + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) + + def test_add_bad(self): + try: + self.l.add({"dn": "BAD,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"0123456789abcde1"}) + self.fail("Should have failed adding entry with invalid DN") + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_INVALID_DN_SYNTAX) + + def test_add_del_add(self): + self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"0123456789abcde1"}) + self.l.delete("OU=DUP,DC=SAMBA,DC=ORG") + self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"0123456789abcde2"}) + + def test_add_move_add(self): + self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"0123456789abcde1"}) + self.l.rename("OU=DUP,DC=SAMBA,DC=ORG", + "OU=DUP2,DC=SAMBA,DC=ORG") + self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"0123456789abcde2"}) + + def test_add_move_fail_move_move(self): + self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"0123456789abcde1"}) + self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"0123456789abcde2"}) + + res2 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(objectUUID=0123456789abcde1)") + self.assertEqual(len(res2), 1) + self.assertEqual(str(res2[0].dn), "OU=DUP,DC=SAMBA,DC=ORG") + + res3 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(objectUUID=0123456789abcde2)") + self.assertEqual(len(res3), 1) + self.assertEqual(str(res3[0].dn), "OU=DUP2,DC=SAMBA,DC=ORG") + + try: + self.l.rename("OU=DUP,DC=SAMBA,DC=ORG", + "OU=DUP2,DC=SAMBA,DC=ORG") + self.fail("Should have failed on duplicate DN") + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) + + self.l.rename("OU=DUP2,DC=SAMBA,DC=ORG", + "OU=DUP3,DC=SAMBA,DC=ORG") + + self.l.rename("OU=DUP,DC=SAMBA,DC=ORG", + "OU=DUP2,DC=SAMBA,DC=ORG") + + res2 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(objectUUID=0123456789abcde1)") + self.assertEqual(len(res2), 1) + self.assertEqual(str(res2[0].dn), "OU=DUP2,DC=SAMBA,DC=ORG") + + res3 = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(objectUUID=0123456789abcde2)") + self.assertEqual(len(res3), 1) + self.assertEqual(str(res3[0].dn), "OU=DUP3,DC=SAMBA,DC=ORG") + + def test_move_missing(self): + try: + self.l.rename("OU=DUP,DC=SAMBA,DC=ORG", + "OU=DUP2,DC=SAMBA,DC=ORG") + self.fail("Should have failed on missing") + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_NO_SUCH_OBJECT) + + def test_move_missing2(self): + self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"0123456789abcde2"}) + + try: + self.l.rename("OU=DUP,DC=SAMBA,DC=ORG", + "OU=DUP2,DC=SAMBA,DC=ORG") + self.fail("Should have failed on missing") + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_NO_SUCH_OBJECT) + + def test_move_bad(self): + self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"0123456789abcde2"}) + + try: + self.l.rename("OUXDUP,DC=SAMBA,DC=ORG", + "OU=DUP2,DC=SAMBA,DC=ORG") + self.fail("Should have failed on invalid DN") + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_INVALID_DN_SYNTAX) + + def test_move_bad2(self): + self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"0123456789abcde2"}) + + try: + self.l.rename("OU=DUP,DC=SAMBA,DC=ORG", + "OUXDUP2,DC=SAMBA,DC=ORG") + self.fail("Should have failed on missing") + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_INVALID_DN_SYNTAX) + + def test_move_fail_move_add(self): + self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"0123456789abcde1"}) + self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"0123456789abcde2"}) + try: + self.l.rename("OU=DUP,DC=SAMBA,DC=ORG", + "OU=DUP2,DC=SAMBA,DC=ORG") + self.fail("Should have failed on duplicate DN") + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) + + self.l.rename("OU=DUP2,DC=SAMBA,DC=ORG", + "OU=DUP3,DC=SAMBA,DC=ORG") + + self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"0123456789abcde3"}) + + +class AddModifyTestsLmdb(AddModifyTests): + + def setUp(self): + if os.environ.get('HAVE_LMDB', '1') == '0': + self.skipTest("No lmdb backend") + self.prefix = MDB_PREFIX + self.index = MDB_INDEX_OBJ + super(AddModifyTestsLmdb, self).setUp() + + def tearDown(self): + super(AddModifyTestsLmdb, self).tearDown() + + +class IndexedAddModifyTests(AddModifyTests): + """Test searches using the index, to ensure the index doesn't + break things""" + + def setUp(self): + if not hasattr(self, 'index'): + self.index = {"dn": "@INDEXLIST", + "@IDXATTR": [b"x", b"y", b"ou", b"objectUUID", b"z"], + "@IDXONE": [b"1"]} + super(IndexedAddModifyTests, self).setUp() + + def test_duplicate_GUID(self): + try: + self.l.add({"dn": "OU=DUPGUID,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"0123456789abcdef"}) + self.fail("Should have failed adding dupliate GUID") + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_CONSTRAINT_VIOLATION) + + def test_duplicate_name_dup_GUID(self): + self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"a123456789abcdef"}) + try: + self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"a123456789abcdef"}) + self.fail("Should have failed adding dupliate GUID") + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) + + def test_duplicate_name_dup_GUID2(self): + self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"abc3456789abcdef"}) + try: + self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"aaa3456789abcdef"}) + self.fail("Should have failed adding dupliate DN") + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) + + # Checking the GUID didn't stick in the index + self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"aaa3456789abcdef"}) + + def test_add_dup_guid_add(self): + self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"0123456789abcde1"}) + try: + self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"0123456789abcde1"}) + self.fail("Should have failed on duplicate GUID") + + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_CONSTRAINT_VIOLATION) + + self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG", + "name": b"Admins", + "x": "z", "y": "a", + "objectUUID": b"0123456789abcde2"}) + + def test_duplicate_index_values(self): + self.l.add({"dn": "OU=DIV1,DC=SAMBA,DC=ORG", + "name": b"Admins", + "z": "1", + "objectUUID": b"0123456789abcdff"}) + self.l.add({"dn": "OU=DIV2,DC=SAMBA,DC=ORG", + "name": b"Admins", + "z": "1", + "objectUUID": b"0123456789abcdfd"}) + + +class GUIDIndexedAddModifyTests(IndexedAddModifyTests): + """Test searches using the index, to ensure the index doesn't + break things""" + + def setUp(self): + self.index = {"dn": "@INDEXLIST", + "@IDXATTR": [b"x", b"y", b"ou"], + "@IDXONE": [b"1"], + "@IDXGUID": [b"objectUUID"], + "@IDX_DN_GUID": [b"GUID"]} + super(GUIDIndexedAddModifyTests, self).setUp() + + +class GUIDTransIndexedAddModifyTests(GUIDIndexedAddModifyTests): + """Test GUID index behaviour insdie the transaction""" + + def setUp(self): + super(GUIDTransIndexedAddModifyTests, self).setUp() + self.l.transaction_start() + + def tearDown(self): + self.l.transaction_commit() + super(GUIDTransIndexedAddModifyTests, self).tearDown() + + +class TransIndexedAddModifyTests(IndexedAddModifyTests): + """Test index behaviour insdie the transaction""" + + def setUp(self): + super(TransIndexedAddModifyTests, self).setUp() + self.l.transaction_start() + + def tearDown(self): + self.l.transaction_commit() + super(TransIndexedAddModifyTests, self).tearDown() + + +class GuidIndexedAddModifyTestsLmdb(GUIDIndexedAddModifyTests): + + def setUp(self): + if os.environ.get('HAVE_LMDB', '1') == '0': + self.skipTest("No lmdb backend") + self.prefix = MDB_PREFIX + super(GuidIndexedAddModifyTestsLmdb, self).setUp() + + def tearDown(self): + super(GuidIndexedAddModifyTestsLmdb, self).tearDown() + + +class GuidTransIndexedAddModifyTestsLmdb(GUIDTransIndexedAddModifyTests): + + def setUp(self): + if os.environ.get('HAVE_LMDB', '1') == '0': + self.skipTest("No lmdb backend") + self.prefix = MDB_PREFIX + super(GuidTransIndexedAddModifyTestsLmdb, self).setUp() + + def tearDown(self): + super(GuidTransIndexedAddModifyTestsLmdb, self).tearDown() + + +class BadIndexTests(LdbBaseTest): + def setUp(self): + super(BadIndexTests, self).setUp() + self.testdir = tempdir() + self.filename = os.path.join(self.testdir, "test.ldb") + self.ldb = ldb.Ldb(self.url(), flags=self.flags()) + if hasattr(self, 'IDXGUID'): + self.ldb.add({"dn": "@INDEXLIST", + "@IDXATTR": [b"x", b"y", b"ou"], + "@IDXGUID": [b"objectUUID"], + "@IDX_DN_GUID": [b"GUID"]}) + else: + self.ldb.add({"dn": "@INDEXLIST", + "@IDXATTR": [b"x", b"y", b"ou"]}) + + super(BadIndexTests, self).setUp() + + def test_unique(self): + self.ldb.add({"dn": "x=x,dc=samba,dc=org", + "objectUUID": b"0123456789abcde1", + "y": "1"}) + self.ldb.add({"dn": "x=y,dc=samba,dc=org", + "objectUUID": b"0123456789abcde2", + "y": "1"}) + self.ldb.add({"dn": "x=z,dc=samba,dc=org", + "objectUUID": b"0123456789abcde3", + "y": "1"}) + + res = self.ldb.search(expression="(y=1)", + base="dc=samba,dc=org") + self.assertEqual(len(res), 3) + + # Now set this to unique index, but forget to check the result + try: + self.ldb.add({"dn": "@ATTRIBUTES", + "y": "UNIQUE_INDEX"}) + self.fail() + except ldb.LdbError: + pass + + # We must still have a working index + res = self.ldb.search(expression="(y=1)", + base="dc=samba,dc=org") + self.assertEqual(len(res), 3) + + def test_unique_transaction(self): + self.ldb.add({"dn": "x=x,dc=samba,dc=org", + "objectUUID": b"0123456789abcde1", + "y": "1"}) + self.ldb.add({"dn": "x=y,dc=samba,dc=org", + "objectUUID": b"0123456789abcde2", + "y": "1"}) + self.ldb.add({"dn": "x=z,dc=samba,dc=org", + "objectUUID": b"0123456789abcde3", + "y": "1"}) + + res = self.ldb.search(expression="(y=1)", + base="dc=samba,dc=org") + self.assertEqual(len(res), 3) + + self.ldb.transaction_start() + + # Now set this to unique index, but forget to check the result + try: + self.ldb.add({"dn": "@ATTRIBUTES", + "y": "UNIQUE_INDEX"}) + except ldb.LdbError: + pass + + try: + self.ldb.transaction_commit() + self.fail() + + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_OPERATIONS_ERROR) + + # We must still have a working index + res = self.ldb.search(expression="(y=1)", + base="dc=samba,dc=org") + + self.assertEqual(len(res), 3) + + def test_casefold(self): + self.ldb.add({"dn": "x=x,dc=samba,dc=org", + "objectUUID": b"0123456789abcde1", + "y": "a"}) + self.ldb.add({"dn": "x=y,dc=samba,dc=org", + "objectUUID": b"0123456789abcde2", + "y": "A"}) + self.ldb.add({"dn": "x=z,dc=samba,dc=org", + "objectUUID": b"0123456789abcde3", + "y": ["a", "A"]}) + + res = self.ldb.search(expression="(y=a)", + base="dc=samba,dc=org") + self.assertEqual(len(res), 2) + + self.ldb.add({"dn": "@ATTRIBUTES", + "y": "CASE_INSENSITIVE"}) + + # We must still have a working index + res = self.ldb.search(expression="(y=a)", + base="dc=samba,dc=org") + + if hasattr(self, 'IDXGUID'): + self.assertEqual(len(res), 3) + else: + # We should not return this entry twice, but sadly + # we have not yet fixed + # https://bugzilla.samba.org/show_bug.cgi?id=13361 + self.assertEqual(len(res), 4) + + def test_casefold_transaction(self): + self.ldb.add({"dn": "x=x,dc=samba,dc=org", + "objectUUID": b"0123456789abcde1", + "y": "a"}) + self.ldb.add({"dn": "x=y,dc=samba,dc=org", + "objectUUID": b"0123456789abcde2", + "y": "A"}) + self.ldb.add({"dn": "x=z,dc=samba,dc=org", + "objectUUID": b"0123456789abcde3", + "y": ["a", "A"]}) + + res = self.ldb.search(expression="(y=a)", + base="dc=samba,dc=org") + self.assertEqual(len(res), 2) + + self.ldb.transaction_start() + + self.ldb.add({"dn": "@ATTRIBUTES", + "y": "CASE_INSENSITIVE"}) + + self.ldb.transaction_commit() + + # We must still have a working index + res = self.ldb.search(expression="(y=a)", + base="dc=samba,dc=org") + + if hasattr(self, 'IDXGUID'): + self.assertEqual(len(res), 3) + else: + # We should not return this entry twice, but sadly + # we have not yet fixed + # https://bugzilla.samba.org/show_bug.cgi?id=13361 + self.assertEqual(len(res), 4) + + def test_modify_transaction(self): + self.ldb.add({"dn": "x=y,dc=samba,dc=org", + "objectUUID": b"0123456789abcde1", + "y": "2", + "z": "2"}) + + res = self.ldb.search(expression="(y=2)", + base="dc=samba,dc=org") + self.assertEqual(len(res), 1) + + self.ldb.add({"dn": "@ATTRIBUTES", + "y": "UNIQUE_INDEX"}) + + self.ldb.transaction_start() + + m = ldb.Message() + m.dn = ldb.Dn(self.ldb, "x=y,dc=samba,dc=org") + m["0"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "y") + m["1"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "not-here") + + try: + self.ldb.modify(m) + self.fail() + + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_NO_SUCH_ATTRIBUTE) + + try: + self.ldb.transaction_commit() + # We should fail here, but we want to be sure + # we fail below + + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_OPERATIONS_ERROR) + + # The index should still be pointing to x=y + res = self.ldb.search(expression="(y=2)", + base="dc=samba,dc=org") + self.assertEqual(len(res), 1) + + try: + self.ldb.add({"dn": "x=y2,dc=samba,dc=org", + "objectUUID": b"0123456789abcde2", + "y": "2"}) + self.fail("Added unique attribute twice") + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_CONSTRAINT_VIOLATION) + + res = self.ldb.search(expression="(y=2)", + base="dc=samba,dc=org") + self.assertEqual(len(res), 1) + self.assertEqual(str(res[0].dn), "x=y,dc=samba,dc=org") + + def tearDown(self): + super(BadIndexTests, self).tearDown() + + +class GUIDBadIndexTests(BadIndexTests): + """Test Bad index things with GUID index mode""" + + def setUp(self): + self.IDXGUID = True + + super(GUIDBadIndexTests, self).setUp() + + +class GUIDBadIndexTestsLmdb(BadIndexTests): + + def setUp(self): + if os.environ.get('HAVE_LMDB', '1') == '0': + self.skipTest("No lmdb backend") + self.prefix = MDB_PREFIX + self.index = MDB_INDEX_OBJ + self.IDXGUID = True + super(GUIDBadIndexTestsLmdb, self).setUp() + + def tearDown(self): + super(GUIDBadIndexTestsLmdb, self).tearDown() + + +class BatchModeTests(LdbBaseTest): + + def setUp(self): + super(BatchModeTests, self).setUp() + self.testdir = tempdir() + self.filename = os.path.join(self.testdir, "test.ldb") + self.ldb = ldb.Ldb(self.url(), + flags=self.flags(), + options=["batch_mode:1"]) + if hasattr(self, 'IDXGUID'): + self.ldb.add({"dn": "@INDEXLIST", + "@IDXATTR": [b"x", b"y", b"ou"], + "@IDXGUID": [b"objectUUID"], + "@IDX_DN_GUID": [b"GUID"]}) + else: + self.ldb.add({"dn": "@INDEXLIST", + "@IDXATTR": [b"x", b"y", b"ou"]}) + + def test_modify_transaction(self): + self.ldb.add({"dn": "x=y,dc=samba,dc=org", + "objectUUID": b"0123456789abcde1", + "y": "2", + "z": "2"}) + + res = self.ldb.search(expression="(y=2)", + base="dc=samba,dc=org") + self.assertEqual(len(res), 1) + + self.ldb.add({"dn": "@ATTRIBUTES", + "y": "UNIQUE_INDEX"}) + + self.ldb.transaction_start() + + m = ldb.Message() + m.dn = ldb.Dn(self.ldb, "x=y,dc=samba,dc=org") + m["0"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "y") + m["1"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "not-here") + + try: + self.ldb.modify(m) + self.fail() + + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_NO_SUCH_ATTRIBUTE) + + try: + self.ldb.transaction_commit() + self.fail("Commit should have failed as we were in batch mode") + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_OPERATIONS_ERROR) + + def tearDown(self): + super(BatchModeTests, self).tearDown() + + +class DnTests(TestCase): + + def setUp(self): + super(DnTests, self).setUp() + self.ldb = ldb.Ldb() + + def tearDown(self): + super(DnTests, self).tearDown() + del(self.ldb) + + def test_set_dn_invalid(self): + x = ldb.Message() + + def assign(): + x.dn = "astring" + self.assertRaises(TypeError, assign) + + def test_eq(self): + x = ldb.Dn(self.ldb, "dc=foo11,bar=bloe") + y = ldb.Dn(self.ldb, "dc=foo11,bar=bloe") + self.assertEqual(x, y) + y = ldb.Dn(self.ldb, "dc=foo11,bar=blie") + self.assertNotEqual(x, y) + + def test_str(self): + x = ldb.Dn(self.ldb, "dc=foo12,bar=bloe") + self.assertEqual(x.__str__(), "dc=foo12,bar=bloe") + + def test_repr(self): + x = ldb.Dn(self.ldb, "dc=foo13,bla=blie") + self.assertEqual(x.__repr__(), "Dn('dc=foo13,bla=blie')") + + def test_get_casefold_2(self): + x = ldb.Dn(self.ldb, "dc=foo14,bar=bloe") + self.assertEqual(x.get_casefold(), "DC=FOO14,BAR=bloe") + + def test_validate(self): + x = ldb.Dn(self.ldb, "dc=foo15,bar=bloe") + self.assertTrue(x.validate()) + + def test_parent(self): + x = ldb.Dn(self.ldb, "dc=foo16,bar=bloe") + self.assertEqual("bar=bloe", x.parent().__str__()) + + def test_parent_nonexistent(self): + x = ldb.Dn(self.ldb, "@BLA") + self.assertEqual(None, x.parent()) + + def test_is_valid(self): + x = ldb.Dn(self.ldb, "dc=foo18,dc=bloe") + self.assertTrue(x.is_valid()) + x = ldb.Dn(self.ldb, "") + self.assertTrue(x.is_valid()) + + def test_is_special(self): + x = ldb.Dn(self.ldb, "dc=foo19,bar=bloe") + self.assertFalse(x.is_special()) + x = ldb.Dn(self.ldb, "@FOOBAR") + self.assertTrue(x.is_special()) + + def test_check_special(self): + x = ldb.Dn(self.ldb, "dc=foo20,bar=bloe") + self.assertFalse(x.check_special("FOOBAR")) + x = ldb.Dn(self.ldb, "@FOOBAR") + self.assertTrue(x.check_special("@FOOBAR")) + + def test_len(self): + x = ldb.Dn(self.ldb, "dc=foo21,bar=bloe") + self.assertEqual(2, len(x)) + x = ldb.Dn(self.ldb, "dc=foo21") + self.assertEqual(1, len(x)) + + def test_add_child(self): + x = ldb.Dn(self.ldb, "dc=foo22,bar=bloe") + self.assertTrue(x.add_child(ldb.Dn(self.ldb, "bla=bloe"))) + self.assertEqual("bla=bloe,dc=foo22,bar=bloe", x.__str__()) + + def test_add_base(self): + x = ldb.Dn(self.ldb, "dc=foo23,bar=bloe") + base = ldb.Dn(self.ldb, "bla=bloe") + self.assertTrue(x.add_base(base)) + self.assertEqual("dc=foo23,bar=bloe,bla=bloe", x.__str__()) + + def test_add_child_str(self): + x = ldb.Dn(self.ldb, "dc=foo22,bar=bloe") + self.assertTrue(x.add_child("bla=bloe")) + self.assertEqual("bla=bloe,dc=foo22,bar=bloe", x.__str__()) + + def test_add_base_str(self): + x = ldb.Dn(self.ldb, "dc=foo23,bar=bloe") + base = "bla=bloe" + self.assertTrue(x.add_base(base)) + self.assertEqual("dc=foo23,bar=bloe,bla=bloe", x.__str__()) + + def test_add(self): + x = ldb.Dn(self.ldb, "dc=foo24") + y = ldb.Dn(self.ldb, "bar=bla") + self.assertEqual("dc=foo24,bar=bla", str(x + y)) + + def test_remove_base_components(self): + x = ldb.Dn(self.ldb, "dc=foo24,dc=samba,dc=org") + x.remove_base_components(len(x) - 1) + self.assertEqual("dc=foo24", str(x)) + + def test_parse_ldif(self): + msgs = self.ldb.parse_ldif("dn: foo=bar\n") + msg = next(msgs) + self.assertEqual("foo=bar", str(msg[1].dn)) + self.assertTrue(isinstance(msg[1], ldb.Message)) + ldif = self.ldb.write_ldif(msg[1], ldb.CHANGETYPE_NONE) + self.assertEqual("dn: foo=bar\n\n", ldif) + + def test_parse_ldif_more(self): + msgs = self.ldb.parse_ldif("dn: foo=bar\n\n\ndn: bar=bar") + msg = next(msgs) + self.assertEqual("foo=bar", str(msg[1].dn)) + msg = next(msgs) + self.assertEqual("bar=bar", str(msg[1].dn)) + + def test_print_ldif(self): + ldif = '''dn: dc=foo27 +foo: foo + +''' + self.msg = ldb.Message(ldb.Dn(self.ldb, "dc=foo27")) + self.msg["foo"] = [b"foo"] + self.assertEqual(ldif, + self.ldb.write_ldif(self.msg, + ldb.CHANGETYPE_NONE)) + + def test_print_ldif_binary(self): + # this also confirms that ldb flags are set even without a URL) + self.ldb = ldb.Ldb(flags=ldb.FLG_SHOW_BINARY) + ldif = '''dn: dc=foo27 +foo: f +öö + +''' + self.msg = ldb.Message(ldb.Dn(self.ldb, "dc=foo27")) + self.msg["foo"] = ["f\nöö"] + self.assertEqual(ldif, + self.ldb.write_ldif(self.msg, + ldb.CHANGETYPE_NONE)) + + + def test_print_ldif_no_base64_bad(self): + ldif = '''dn: dc=foo27 +foo: f +öö + +''' + self.msg = ldb.Message(ldb.Dn(self.ldb, "dc=foo27")) + self.msg["foo"] = ["f\nöö"] + self.msg["foo"].set_flags(ldb.FLAG_FORCE_NO_BASE64_LDIF) + self.assertEqual(ldif, + self.ldb.write_ldif(self.msg, + ldb.CHANGETYPE_NONE)) + + def test_print_ldif_no_base64_good(self): + ldif = '''dn: dc=foo27 +foo: föö + +''' + self.msg = ldb.Message(ldb.Dn(self.ldb, "dc=foo27")) + self.msg["foo"] = ["föö"] + self.msg["foo"].set_flags(ldb.FLAG_FORCE_NO_BASE64_LDIF) + self.assertEqual(ldif, + self.ldb.write_ldif(self.msg, + ldb.CHANGETYPE_NONE)) + + def test_canonical_string(self): + x = ldb.Dn(self.ldb, "dc=foo25,bar=bloe") + self.assertEqual("/bloe/foo25", x.canonical_str()) + + def test_canonical_ex_string(self): + x = ldb.Dn(self.ldb, "dc=foo26,bar=bloe") + self.assertEqual("/bloe\nfoo26", x.canonical_ex_str()) + + def test_ldb_is_child_of(self): + """Testing ldb_dn_compare_dn""" + dn1 = ldb.Dn(self.ldb, "dc=base") + dn2 = ldb.Dn(self.ldb, "cn=foo,dc=base") + dn3 = ldb.Dn(self.ldb, "cn=bar,dc=base") + dn4 = ldb.Dn(self.ldb, "cn=baz,cn=bar,dc=base") + + self.assertTrue(dn1.is_child_of(dn1)) + self.assertTrue(dn2.is_child_of(dn1)) + self.assertTrue(dn4.is_child_of(dn1)) + self.assertTrue(dn4.is_child_of(dn3)) + self.assertTrue(dn4.is_child_of(dn4)) + self.assertFalse(dn3.is_child_of(dn2)) + self.assertFalse(dn1.is_child_of(dn4)) + + def test_ldb_is_child_of_str(self): + """Testing ldb_dn_compare_dn""" + dn1_str = "dc=base" + dn2_str = "cn=foo,dc=base" + dn3_str = "cn=bar,dc=base" + dn4_str = "cn=baz,cn=bar,dc=base" + + dn1 = ldb.Dn(self.ldb, dn1_str) + dn2 = ldb.Dn(self.ldb, dn2_str) + dn3 = ldb.Dn(self.ldb, dn3_str) + dn4 = ldb.Dn(self.ldb, dn4_str) + + self.assertTrue(dn1.is_child_of(dn1_str)) + self.assertTrue(dn2.is_child_of(dn1_str)) + self.assertTrue(dn4.is_child_of(dn1_str)) + self.assertTrue(dn4.is_child_of(dn3_str)) + self.assertTrue(dn4.is_child_of(dn4_str)) + self.assertFalse(dn3.is_child_of(dn2_str)) + self.assertFalse(dn1.is_child_of(dn4_str)) + + def test_get_component_name(self): + dn = ldb.Dn(self.ldb, "cn=foo,dc=base") + self.assertEqual(dn.get_component_name(0), 'cn') + self.assertEqual(dn.get_component_name(1), 'dc') + self.assertEqual(dn.get_component_name(2), None) + self.assertEqual(dn.get_component_name(-1), None) + + def test_get_component_value(self): + dn = ldb.Dn(self.ldb, "cn=foo,dc=base") + self.assertEqual(dn.get_component_value(0), 'foo') + self.assertEqual(dn.get_component_value(1), 'base') + self.assertEqual(dn.get_component_name(2), None) + self.assertEqual(dn.get_component_name(-1), None) + + def test_set_component(self): + dn = ldb.Dn(self.ldb, "cn=foo,dc=base") + dn.set_component(0, 'cn', 'bar') + self.assertEqual(str(dn), "cn=bar,dc=base") + dn.set_component(1, 'o', 'asep') + self.assertEqual(str(dn), "cn=bar,o=asep") + self.assertRaises(TypeError, dn.set_component, 2, 'dc', 'base') + self.assertEqual(str(dn), "cn=bar,o=asep") + dn.set_component(1, 'o', 'a,b+c') + self.assertEqual(str(dn), r"cn=bar,o=a\,b\+c") + + def test_set_component_bytes(self): + dn = ldb.Dn(self.ldb, "cn=foo,dc=base") + dn.set_component(0, 'cn', b'bar') + self.assertEqual(str(dn), "cn=bar,dc=base") + dn.set_component(1, 'o', b'asep') + self.assertEqual(str(dn), "cn=bar,o=asep") + + def test_set_component_none(self): + dn = ldb.Dn(self.ldb, "cn=foo,cn=bar,dc=base") + self.assertRaises(TypeError, dn.set_component, 1, 'cn', None) + + def test_get_extended_component_null(self): + dn = ldb.Dn(self.ldb, "cn=foo,cn=bar,dc=base") + self.assertEqual(dn.get_extended_component("TEST"), None) + + def test_get_extended_component(self): + self.ldb._register_test_extensions() + dn = ldb.Dn(self.ldb, ";cn=bar,dc=base") + self.assertEqual(dn.get_extended_component("TEST"), b"foo") + + def test_set_extended_component(self): + self.ldb._register_test_extensions() + dn = ldb.Dn(self.ldb, "dc=base") + dn.set_extended_component("TEST", "foo") + self.assertEqual(dn.get_extended_component("TEST"), b"foo") + dn.set_extended_component("TEST", b"bar") + self.assertEqual(dn.get_extended_component("TEST"), b"bar") + + def test_extended_str(self): + self.ldb._register_test_extensions() + dn = ldb.Dn(self.ldb, ";cn=bar,dc=base") + self.assertEqual(dn.extended_str(), ";cn=bar,dc=base") + + def test_get_rdn_name(self): + dn = ldb.Dn(self.ldb, "cn=foo,dc=base") + self.assertEqual(dn.get_rdn_name(), 'cn') + + def test_get_rdn_value(self): + dn = ldb.Dn(self.ldb, "cn=foo,dc=base") + self.assertEqual(dn.get_rdn_value(), 'foo') + + def test_get_casefold(self): + dn = ldb.Dn(self.ldb, "cn=foo,dc=base") + self.assertEqual(dn.get_casefold(), 'CN=FOO,DC=BASE') + + def test_get_linearized(self): + dn = ldb.Dn(self.ldb, "cn=foo,dc=base") + self.assertEqual(dn.get_linearized(), 'cn=foo,dc=base') + + def test_is_null(self): + dn = ldb.Dn(self.ldb, "cn=foo,dc=base") + self.assertFalse(dn.is_null()) + + dn = ldb.Dn(self.ldb, '') + self.assertTrue(dn.is_null()) + + +class LdbMsgTests(TestCase): + + def setUp(self): + super(LdbMsgTests, self).setUp() + self.msg = ldb.Message() + + def test_init_dn(self): + self.msg = ldb.Message(ldb.Dn(ldb.Ldb(), "dc=foo27")) + self.assertEqual("dc=foo27", str(self.msg.dn)) + + def test_iter_items(self): + self.assertEqual(0, len(self.msg.items())) + self.msg.dn = ldb.Dn(ldb.Ldb(), "dc=foo28") + self.assertEqual(1, len(self.msg.items())) + + def test_repr(self): + self.msg.dn = ldb.Dn(ldb.Ldb(), "dc=foo29") + self.msg["dc"] = b"foo" + if PY3: + self.assertIn(repr(self.msg), [ + "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement([b'foo'])})", + "Message({'dc': MessageElement([b'foo']), 'dn': Dn('dc=foo29')})", + ]) + self.assertIn(repr(self.msg.text), [ + "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement([b'foo'])}).text", + "Message({'dc': MessageElement([b'foo']), 'dn': Dn('dc=foo29')}).text", + ]) + else: + self.assertIn(repr(self.msg), [ + "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement(['foo'])})", + "Message({'dc': MessageElement(['foo']), 'dn': Dn('dc=foo29')})", + ]) + self.assertIn(repr(self.msg.text), [ + "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement(['foo'])}).text", + "Message({'dc': MessageElement(['foo']), 'dn': Dn('dc=foo29')}).text", + ]) + + def test_len(self): + self.assertEqual(0, len(self.msg)) + + def test_notpresent(self): + self.assertRaises(KeyError, lambda: self.msg["foo"]) + + def test_del(self): + del self.msg["foo"] + + def test_add(self): + self.msg.add(ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla")) + + def test_add_text(self): + self.msg.add(ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla")) + + def test_elements_empty(self): + self.assertEqual([], self.msg.elements()) + + def test_elements(self): + el = ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla") + self.msg.add(el) + self.assertEqual([el], self.msg.elements()) + self.assertEqual([el.text], self.msg.text.elements()) + + def test_add_value(self): + self.assertEqual(0, len(self.msg)) + self.msg["foo"] = [b"foo"] + self.assertEqual(1, len(self.msg)) + + def test_add_value_text(self): + self.assertEqual(0, len(self.msg)) + self.msg["foo"] = ["foo"] + self.assertEqual(1, len(self.msg)) + + def test_add_value_multiple(self): + self.assertEqual(0, len(self.msg)) + self.msg["foo"] = [b"foo", b"bla"] + self.assertEqual(1, len(self.msg)) + self.assertEqual([b"foo", b"bla"], list(self.msg["foo"])) + + def test_add_value_multiple_text(self): + self.assertEqual(0, len(self.msg)) + self.msg["foo"] = ["foo", "bla"] + self.assertEqual(1, len(self.msg)) + self.assertEqual(["foo", "bla"], list(self.msg.text["foo"])) + + def test_set_value(self): + self.msg["foo"] = [b"fool"] + self.assertEqual([b"fool"], list(self.msg["foo"])) + self.msg["foo"] = [b"bar"] + self.assertEqual([b"bar"], list(self.msg["foo"])) + + def test_set_value_text(self): + self.msg["foo"] = ["fool"] + self.assertEqual(["fool"], list(self.msg.text["foo"])) + self.msg["foo"] = ["bar"] + self.assertEqual(["bar"], list(self.msg.text["foo"])) + + def test_keys(self): + self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO") + self.msg["foo"] = [b"bla"] + self.msg["bar"] = [b"bla"] + self.assertEqual(["dn", "foo", "bar"], list(self.msg.keys())) + + def test_keys_text(self): + self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO") + self.msg["foo"] = ["bla"] + self.msg["bar"] = ["bla"] + self.assertEqual(["dn", "foo", "bar"], list(self.msg.text.keys())) + + def test_dn(self): + self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO") + self.assertEqual("@BASEINFO", self.msg.dn.__str__()) + + def test_get_dn(self): + self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO") + self.assertEqual("@BASEINFO", self.msg.get("dn").__str__()) + + def test_dn_text(self): + self.msg.text.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO") + self.assertEqual("@BASEINFO", str(self.msg.dn)) + self.assertEqual("@BASEINFO", str(self.msg.text.dn)) + + def test_get_dn_text(self): + self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO") + self.assertEqual("@BASEINFO", str(self.msg.get("dn"))) + self.assertEqual("@BASEINFO", str(self.msg.text.get("dn"))) + + def test_get_invalid(self): + self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO") + self.assertRaises(TypeError, self.msg.get, 42) + + def test_get_other(self): + self.msg["foo"] = [b"bar"] + self.assertEqual(b"bar", self.msg.get("foo")[0]) + self.assertEqual(b"bar", self.msg.get("foo", idx=0)) + self.assertEqual(None, self.msg.get("foo", idx=1)) + self.assertEqual("", self.msg.get("foo", default='', idx=1)) + + def test_get_other_text(self): + self.msg["foo"] = ["bar"] + self.assertEqual(["bar"], list(self.msg.text.get("foo"))) + self.assertEqual("bar", self.msg.text.get("foo")[0]) + self.assertEqual("bar", self.msg.text.get("foo", idx=0)) + self.assertEqual(None, self.msg.get("foo", idx=1)) + self.assertEqual("", self.msg.get("foo", default='', idx=1)) + + def test_get_default(self): + self.assertEqual(None, self.msg.get("tatayoyo", idx=0)) + self.assertEqual("anniecordie", self.msg.get("tatayoyo", "anniecordie")) + + def test_get_default_text(self): + self.assertEqual(None, self.msg.text.get("tatayoyo", idx=0)) + self.assertEqual("anniecordie", self.msg.text.get("tatayoyo", "anniecordie")) + + def test_get_unknown(self): + self.assertEqual(None, self.msg.get("lalalala")) + + def test_get_unknown_text(self): + self.assertEqual(None, self.msg.text.get("lalalala")) + + def test_msg_diff(self): + l = ldb.Ldb() + msgs = l.parse_ldif("dn: foo=bar\nfoo: bar\nbaz: do\n\ndn: foo=bar\nfoo: bar\nbaz: dont\n") + msg1 = next(msgs)[1] + msg2 = next(msgs)[1] + msgdiff = l.msg_diff(msg1, msg2) + self.assertEqual("foo=bar", msgdiff.get("dn").__str__()) + self.assertRaises(KeyError, lambda: msgdiff["foo"]) + self.assertEqual(1, len(msgdiff)) + + def test_equal_empty(self): + msg1 = ldb.Message() + msg2 = ldb.Message() + self.assertEqual(msg1, msg2) + + def test_equal_simplel(self): + db = ldb.Ldb() + msg1 = ldb.Message() + msg1.dn = ldb.Dn(db, "foo=bar") + msg2 = ldb.Message() + msg2.dn = ldb.Dn(db, "foo=bar") + self.assertEqual(msg1, msg2) + msg1['foo'] = b'bar' + msg2['foo'] = b'bar' + self.assertEqual(msg1, msg2) + msg2['foo'] = b'blie' + self.assertNotEqual(msg1, msg2) + msg2['foo'] = b'blie' + + def test_from_dict(self): + rec = {"dn": "dc=fromdict", + "a1": [b"a1-val1", b"a1-val1"]} + l = ldb.Ldb() + # check different types of input Flags + for flags in [ldb.FLAG_MOD_ADD, ldb.FLAG_MOD_REPLACE, ldb.FLAG_MOD_DELETE]: + m = ldb.Message.from_dict(l, rec, flags) + self.assertEqual(rec["a1"], list(m["a1"])) + self.assertEqual(flags, m["a1"].flags()) + # check input params + self.assertRaises(TypeError, ldb.Message.from_dict, dict(), rec, ldb.FLAG_MOD_REPLACE) + self.assertRaises(TypeError, ldb.Message.from_dict, l, list(), ldb.FLAG_MOD_REPLACE) + self.assertRaises(ValueError, ldb.Message.from_dict, l, rec, 0) + # Message.from_dict expects dictionary with 'dn' + err_rec = {"a1": [b"a1-val1", b"a1-val1"]} + self.assertRaises(TypeError, ldb.Message.from_dict, l, err_rec, ldb.FLAG_MOD_REPLACE) + + def test_from_dict_text(self): + rec = {"dn": "dc=fromdict", + "a1": ["a1-val1", "a1-val1"]} + l = ldb.Ldb() + # check different types of input Flags + for flags in [ldb.FLAG_MOD_ADD, ldb.FLAG_MOD_REPLACE, ldb.FLAG_MOD_DELETE]: + m = ldb.Message.from_dict(l, rec, flags) + self.assertEqual(rec["a1"], list(m.text["a1"])) + self.assertEqual(flags, m.text["a1"].flags()) + # check input params + self.assertRaises(TypeError, ldb.Message.from_dict, dict(), rec, ldb.FLAG_MOD_REPLACE) + self.assertRaises(TypeError, ldb.Message.from_dict, l, list(), ldb.FLAG_MOD_REPLACE) + self.assertRaises(ValueError, ldb.Message.from_dict, l, rec, 0) + # Message.from_dict expects dictionary with 'dn' + err_rec = {"a1": ["a1-val1", "a1-val1"]} + self.assertRaises(TypeError, ldb.Message.from_dict, l, err_rec, ldb.FLAG_MOD_REPLACE) + + def test_copy_add_message_element(self): + m = ldb.Message() + m["1"] = ldb.MessageElement([b"val 111"], ldb.FLAG_MOD_ADD, "1") + m["2"] = ldb.MessageElement([b"val 222"], ldb.FLAG_MOD_ADD, "2") + mto = ldb.Message() + mto["1"] = m["1"] + mto["2"] = m["2"] + self.assertEqual(mto["1"], m["1"]) + self.assertEqual(mto["2"], m["2"]) + mto = ldb.Message() + mto.add(m["1"]) + mto.add(m["2"]) + self.assertEqual(mto["1"], m["1"]) + self.assertEqual(mto["2"], m["2"]) + + def test_copy_add_message_element_text(self): + m = ldb.Message() + m["1"] = ldb.MessageElement(["val 111"], ldb.FLAG_MOD_ADD, "1") + m["2"] = ldb.MessageElement(["val 222"], ldb.FLAG_MOD_ADD, "2") + mto = ldb.Message() + mto["1"] = m["1"] + mto["2"] = m["2"] + self.assertEqual(mto["1"], m.text["1"]) + self.assertEqual(mto["2"], m.text["2"]) + mto = ldb.Message() + mto.add(m["1"]) + mto.add(m["2"]) + self.assertEqual(mto.text["1"], m.text["1"]) + self.assertEqual(mto.text["2"], m.text["2"]) + self.assertEqual(mto["1"], m["1"]) + self.assertEqual(mto["2"], m["2"]) + + +class MessageElementTests(TestCase): + + def test_cmp_element(self): + x = ldb.MessageElement([b"foo"]) + y = ldb.MessageElement([b"foo"]) + z = ldb.MessageElement([b"bzr"]) + self.assertEqual(x, y) + self.assertNotEqual(x, z) + + def test_cmp_element_text(self): + x = ldb.MessageElement([b"foo"]) + y = ldb.MessageElement(["foo"]) + self.assertEqual(x, y) + + def test_create_iterable(self): + x = ldb.MessageElement([b"foo"]) + self.assertEqual([b"foo"], list(x)) + self.assertEqual(["foo"], list(x.text)) + + def test_repr(self): + x = ldb.MessageElement([b"foo"]) + if PY3: + self.assertEqual("MessageElement([b'foo'])", repr(x)) + self.assertEqual("MessageElement([b'foo']).text", repr(x.text)) + else: + self.assertEqual("MessageElement(['foo'])", repr(x)) + self.assertEqual("MessageElement(['foo']).text", repr(x.text)) + x = ldb.MessageElement([b"foo", b"bla"]) + self.assertEqual(2, len(x)) + if PY3: + self.assertEqual("MessageElement([b'foo',b'bla'])", repr(x)) + self.assertEqual("MessageElement([b'foo',b'bla']).text", repr(x.text)) + else: + self.assertEqual("MessageElement(['foo','bla'])", repr(x)) + self.assertEqual("MessageElement(['foo','bla']).text", repr(x.text)) + + def test_get_item(self): + x = ldb.MessageElement([b"foo", b"bar"]) + self.assertEqual(b"foo", x[0]) + self.assertEqual(b"bar", x[1]) + self.assertEqual(b"bar", x[-1]) + self.assertRaises(IndexError, lambda: x[45]) + + def test_get_item_text(self): + x = ldb.MessageElement(["foo", "bar"]) + self.assertEqual("foo", x.text[0]) + self.assertEqual("bar", x.text[1]) + self.assertEqual("bar", x.text[-1]) + self.assertRaises(IndexError, lambda: x[45]) + + def test_len(self): + x = ldb.MessageElement([b"foo", b"bar"]) + self.assertEqual(2, len(x)) + + def test_eq(self): + x = ldb.MessageElement([b"foo", b"bar"]) + y = ldb.MessageElement([b"foo", b"bar"]) + self.assertEqual(y, x) + x = ldb.MessageElement([b"foo"]) + self.assertNotEqual(y, x) + y = ldb.MessageElement([b"foo"]) + self.assertEqual(y, x) + + def test_extended(self): + el = ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla") + if PY3: + self.assertEqual("MessageElement([b'456'])", repr(el)) + self.assertEqual("MessageElement([b'456']).text", repr(el.text)) + else: + self.assertEqual("MessageElement(['456'])", repr(el)) + self.assertEqual("MessageElement(['456']).text", repr(el.text)) + + def test_bad_text(self): + el = ldb.MessageElement(b'\xba\xdd') + self.assertRaises(UnicodeDecodeError, el.text.__getitem__, 0) + + +class ModuleTests(TestCase): + + def setUp(self): + super(ModuleTests, self).setUp() + self.testdir = tempdir() + self.filename = os.path.join(self.testdir, "test.ldb") + self.ldb = ldb.Ldb(self.filename) + + def tearDown(self): + shutil.rmtree(self.testdir) + super(ModuleTests, self).setUp() + + def test_register_module(self): + class ExampleModule: + name = "example" + ldb.register_module(ExampleModule) + + def test_use_module(self): + ops = [] + + class ExampleModule: + name = "bla" + + def __init__(self, ldb, next): + ops.append("init") + self.next = next + + def search(self, *args, **kwargs): + return self.next.search(*args, **kwargs) + + def request(self, *args, **kwargs): + pass + + ldb.register_module(ExampleModule) + l = ldb.Ldb(self.filename) + l.add({"dn": "@MODULES", "@LIST": "bla"}) + self.assertEqual([], ops) + l = ldb.Ldb(self.filename) + self.assertEqual(["init"], ops) + + +class LdbResultTests(LdbBaseTest): + + def setUp(self): + super(LdbResultTests, self).setUp() + self.testdir = tempdir() + self.filename = os.path.join(self.testdir, "test.ldb") + self.l = ldb.Ldb(self.url(), flags=self.flags()) + try: + self.l.add(self.index) + except AttributeError: + pass + self.l.add({"dn": "DC=SAMBA,DC=ORG", "name": b"samba.org", + "objectUUID": b"0123456789abcde0"}) + self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", "name": b"Admins", + "objectUUID": b"0123456789abcde1"}) + self.l.add({"dn": "OU=USERS,DC=SAMBA,DC=ORG", "name": b"Users", + "objectUUID": b"0123456789abcde2"}) + self.l.add({"dn": "OU=OU1,DC=SAMBA,DC=ORG", "name": b"OU #1", + "objectUUID": b"0123456789abcde3"}) + self.l.add({"dn": "OU=OU2,DC=SAMBA,DC=ORG", "name": b"OU #2", + "objectUUID": b"0123456789abcde4"}) + self.l.add({"dn": "OU=OU3,DC=SAMBA,DC=ORG", "name": b"OU #3", + "objectUUID": b"0123456789abcde5"}) + self.l.add({"dn": "OU=OU4,DC=SAMBA,DC=ORG", "name": b"OU #4", + "objectUUID": b"0123456789abcde6"}) + self.l.add({"dn": "OU=OU5,DC=SAMBA,DC=ORG", "name": b"OU #5", + "objectUUID": b"0123456789abcde7"}) + self.l.add({"dn": "OU=OU6,DC=SAMBA,DC=ORG", "name": b"OU #6", + "objectUUID": b"0123456789abcde8"}) + self.l.add({"dn": "OU=OU7,DC=SAMBA,DC=ORG", "name": b"OU #7", + "objectUUID": b"0123456789abcde9"}) + self.l.add({"dn": "OU=OU8,DC=SAMBA,DC=ORG", "name": b"OU #8", + "objectUUID": b"0123456789abcdea"}) + self.l.add({"dn": "OU=OU9,DC=SAMBA,DC=ORG", "name": b"OU #9", + "objectUUID": b"0123456789abcdeb"}) + self.l.add({"dn": "OU=OU10,DC=SAMBA,DC=ORG", "name": b"OU #10", + "objectUUID": b"0123456789abcdec"}) + + def tearDown(self): + shutil.rmtree(self.testdir) + super(LdbResultTests, self).tearDown() + # Ensure the LDB is closed now, so we close the FD + del(self.l) + + def test_return_type(self): + res = self.l.search() + self.assertEqual(str(res), "") + + def test_get_msgs(self): + res = self.l.search() + list = res.msgs + + def test_get_controls(self): + res = self.l.search() + list = res.controls + + def test_get_referals(self): + res = self.l.search() + list = res.referals + + def test_iter_msgs(self): + found = False + for l in self.l.search().msgs: + if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": + found = True + self.assertTrue(found) + + def test_iter_msgs_count(self): + self.assertTrue(self.l.search().count > 0) + # 13 objects has been added to the DC=SAMBA, DC=ORG + self.assertEqual(self.l.search(base="DC=SAMBA,DC=ORG").count, 13) + + def test_iter_controls(self): + res = self.l.search().controls + it = iter(res) + + def test_create_control(self): + self.assertRaises(ValueError, ldb.Control, self.l, "tatayoyo:0") + c = ldb.Control(self.l, "relax:1") + self.assertEqual(c.critical, True) + self.assertEqual(c.oid, "1.3.6.1.4.1.4203.666.5.12") + + def test_iter_refs(self): + res = self.l.search().referals + it = iter(res) + + def test_search_sequence_msgs(self): + found = False + res = self.l.search().msgs + + for i in range(0, len(res)): + l = res[i] + if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": + found = True + self.assertTrue(found) + + def test_search_as_iter(self): + found = False + res = self.l.search() + + for l in res: + if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": + found = True + self.assertTrue(found) + + def test_search_iter(self): + found = False + res = self.l.search_iterator() + + for l in res: + if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": + found = True + self.assertTrue(found) + + # Show that search results can't see into a transaction + + def test_search_against_trans(self): + found11 = False + + (r1, w1) = os.pipe() + + (r2, w2) = os.pipe() + + # For the first element, fork a child that will + # write to the DB + pid = os.fork() + if pid == 0: + # In the child, re-open + del(self.l) + gc.collect() + + child_ldb = ldb.Ldb(self.url(), flags=self.flags()) + # start a transaction + child_ldb.transaction_start() + + # write to it + child_ldb.add({"dn": "OU=OU11,DC=SAMBA,DC=ORG", + "name": b"samba.org", + "objectUUID": b"o123456789acbdef"}) + + os.write(w1, b"added") + + # Now wait for the search to be done + os.read(r2, 6) + + # and commit + try: + child_ldb.transaction_commit() + except ldb.LdbError as err: + # We print this here to see what went wrong in the child + print(err) + os._exit(1) + + os.write(w1, b"transaction") + os._exit(0) + + self.assertEqual(os.read(r1, 5), b"added") + + # This should not turn up until the transaction is concluded + res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_BASE) + self.assertEqual(len(res11), 0) + + os.write(w2, b"search") + + # Now wait for the transaction to be done. This should + # deadlock, but the search doesn't hold a read lock for the + # iterator lifetime currently. + self.assertEqual(os.read(r1, 11), b"transaction") + + # This should now turn up, as the transaction is over + res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_BASE) + self.assertEqual(len(res11), 1) + + self.assertFalse(found11) + + (got_pid, status) = os.waitpid(pid, 0) + self.assertEqual(got_pid, pid) + + def test_search_iter_against_trans(self): + found = False + found11 = False + + # We need to hold this iterator open to hold the all-record + # lock + res = self.l.search_iterator() + + (r1, w1) = os.pipe() + + (r2, w2) = os.pipe() + + # For the first element, with the sequence open (which + # means with ldb locks held), fork a child that will + # write to the DB + pid = os.fork() + if pid == 0: + # In the child, re-open + del(res) + del(self.l) + gc.collect() + + child_ldb = ldb.Ldb(self.url(), flags=self.flags()) + # start a transaction + child_ldb.transaction_start() + + # write to it + child_ldb.add({"dn": "OU=OU11,DC=SAMBA,DC=ORG", + "name": b"samba.org", + "objectUUID": b"o123456789acbdef"}) + + os.write(w1, b"added") + + # Now wait for the search to be done + os.read(r2, 6) + + # and commit + try: + child_ldb.transaction_commit() + except ldb.LdbError as err: + # We print this here to see what went wrong in the child + print(err) + os._exit(1) + + os.write(w1, b"transaction") + os._exit(0) + + self.assertEqual(os.read(r1, 5), b"added") + + # This should not turn up until the transaction is concluded + res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_BASE) + self.assertEqual(len(res11), 0) + + os.write(w2, b"search") + + # allow the transaction to start + time.sleep(1) + + # This should not turn up until the search finishes and + # removed the read lock, but for ldb_tdb that happened as soon + # as we called the first res.next() + res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_BASE) + self.assertEqual(len(res11), 0) + + # These results are all collected at the first next(res) call + for l in res: + if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": + found = True + if str(l.dn) == "OU=OU11,DC=SAMBA,DC=ORG": + found11 = True + + # Now wait for the transaction to be done. + self.assertEqual(os.read(r1, 11), b"transaction") + + # This should now turn up, as the transaction is over and all + # read locks are gone + res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_BASE) + self.assertEqual(len(res11), 1) + + self.assertTrue(found) + self.assertFalse(found11) + + (got_pid, status) = os.waitpid(pid, 0) + self.assertEqual(got_pid, pid) + + +class LdbResultTestsLmdb(LdbResultTests): + + def setUp(self): + if os.environ.get('HAVE_LMDB', '1') == '0': + self.skipTest("No lmdb backend") + self.prefix = MDB_PREFIX + self.index = MDB_INDEX_OBJ + super(LdbResultTestsLmdb, self).setUp() + + def tearDown(self): + super(LdbResultTestsLmdb, self).tearDown() + + +class BadTypeTests(TestCase): + def test_control(self): + l = ldb.Ldb() + self.assertRaises(TypeError, ldb.Control, '', 'relax:1') + self.assertRaises(TypeError, ldb.Control, ldb, 1234) + + def test_modify(self): + l = ldb.Ldb() + dn = ldb.Dn(l, 'a=b') + m = ldb.Message(dn) + self.assertRaises(TypeError, l.modify, '') + self.assertRaises(TypeError, l.modify, m, '') + + def test_add(self): + l = ldb.Ldb() + dn = ldb.Dn(l, 'a=b') + m = ldb.Message(dn) + self.assertRaises(TypeError, l.add, '') + self.assertRaises(TypeError, l.add, m, '') + + def test_delete(self): + l = ldb.Ldb() + dn = ldb.Dn(l, 'a=b') + self.assertRaises(TypeError, l.add, '') + self.assertRaises(TypeError, l.add, dn, '') + + def test_rename(self): + l = ldb.Ldb() + dn = ldb.Dn(l, 'a=b') + self.assertRaises(TypeError, l.add, '', dn) + self.assertRaises(TypeError, l.add, dn, '') + self.assertRaises(TypeError, l.add, dn, dn, '') + + def test_search(self): + l = ldb.Ldb() + self.assertRaises(TypeError, l.search, base=1234) + self.assertRaises(TypeError, l.search, scope='') + self.assertRaises(TypeError, l.search, expression=1234) + self.assertRaises(TypeError, l.search, attrs='') + self.assertRaises(TypeError, l.search, controls='') + + +class VersionTests(TestCase): + + def test_version(self): + self.assertTrue(isinstance(ldb.__version__, str)) + +class NestedTransactionTests(LdbBaseTest): + def setUp(self): + super(NestedTransactionTests, self).setUp() + self.testdir = tempdir() + self.filename = os.path.join(self.testdir, "test.ldb") + self.ldb = ldb.Ldb(self.url(), flags=self.flags()) + self.ldb.add({"dn": "@INDEXLIST", + "@IDXATTR": [b"x", b"y", b"ou"], + "@IDXGUID": [b"objectUUID"], + "@IDX_DN_GUID": [b"GUID"]}) + + super(NestedTransactionTests, self).setUp() + + # + # This test documents that currently ldb does not support true nested + # transactions. + # + # Note: The test is written so that it treats failure as pass. + # It is done this way as standalone ldb builds do not use the samba + # known fail mechanism + # + def test_nested_transactions(self): + + self.ldb.transaction_start() + + self.ldb.add({"dn": "x=x1,dc=samba,dc=org", + "objectUUID": b"0123456789abcde1"}) + res = self.ldb.search(expression="(objectUUID=0123456789abcde1)", + base="dc=samba,dc=org") + self.assertEqual(len(res), 1) + + self.ldb.add({"dn": "x=x2,dc=samba,dc=org", + "objectUUID": b"0123456789abcde2"}) + res = self.ldb.search(expression="(objectUUID=0123456789abcde2)", + base="dc=samba,dc=org") + self.assertEqual(len(res), 1) + + self.ldb.transaction_start() + self.ldb.add({"dn": "x=x3,dc=samba,dc=org", + "objectUUID": b"0123456789abcde3"}) + res = self.ldb.search(expression="(objectUUID=0123456789abcde3)", + base="dc=samba,dc=org") + self.assertEqual(len(res), 1) + self.ldb.transaction_cancel() + # + # Check that we can not see the record added by the cancelled + # transaction. + # Currently this fails as ldb does not support true nested + # transactions, and only the outer commits and cancels have an effect + # + res = self.ldb.search(expression="(objectUUID=0123456789abcde3)", + base="dc=samba,dc=org") + # + # FIXME this test currently passes on a failure, i.e. if nested + # transaction support worked correctly the correct test would + # be. + # self.assertEqual(len(res), 0) + # as the add of objectUUID=0123456789abcde3 would reverted when + # the sub transaction it was nested in was rolled back. + # + # Currently this is not the case so the record is still present. + self.assertEqual(len(res), 1) + + + # Commit the outer transaction + # + self.ldb.transaction_commit() + # + # Now check we can still see the records added in the outer + # transaction. + # + res = self.ldb.search(expression="(objectUUID=0123456789abcde1)", + base="dc=samba,dc=org") + self.assertEqual(len(res), 1) + res = self.ldb.search(expression="(objectUUID=0123456789abcde2)", + base="dc=samba,dc=org") + self.assertEqual(len(res), 1) + # + # And that we can't see the records added by the nested transaction. + # + res = self.ldb.search(expression="(objectUUID=0123456789abcde3)", + base="dc=samba,dc=org") + # FIXME again if nested transactions worked correctly we would not + # see this record. The test should be. + # self.assertEqual(len(res), 0) + self.assertEqual(len(res), 1) + + def tearDown(self): + super(NestedTransactionTests, self).tearDown() + + +class LmdbNestedTransactionTests(NestedTransactionTests): + + def setUp(self): + if os.environ.get('HAVE_LMDB', '1') == '0': + self.skipTest("No lmdb backend") + self.prefix = MDB_PREFIX + self.index = MDB_INDEX_OBJ + super(LmdbNestedTransactionTests, self).setUp() + + def tearDown(self): + super(LmdbNestedTransactionTests, self).tearDown() + + +if __name__ == '__main__': + import unittest + unittest.TestProgram() diff --git a/ldb-2.0.8/tests/python/index.py b/ldb-2.0.8/tests/python/index.py new file mode 100755 index 0000000..f957087 --- /dev/null +++ b/ldb-2.0.8/tests/python/index.py @@ -0,0 +1,1455 @@ +#!/usr/bin/env python3 +# +# Tests for truncated index keys +# +# Copyright (C) Andrew Bartlett 2018 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +"""Tests for truncated index keys + +Databases such as lmdb have a maximum key length, these tests ensure that +ldb behaves correctly in those circumstances. + +""" + +import os +from unittest import TestCase +import sys +import ldb +import shutil + +PY3 = sys.version_info > (3, 0) + +TDB_PREFIX = "tdb://" +MDB_PREFIX = "mdb://" + + +def tempdir(): + import tempfile + try: + dir_prefix = os.path.join(os.environ["SELFTEST_PREFIX"], "tmp") + except KeyError: + dir_prefix = None + return tempfile.mkdtemp(dir=dir_prefix) + + +def contains(result, dn): + if result is None: + return False + + for r in result: + if str(r["dn"]) == dn: + return True + return False + + +class LdbBaseTest(TestCase): + def setUp(self): + super(LdbBaseTest, self).setUp() + try: + if self.prefix is None: + self.prefix = TDB_PREFIX + except AttributeError: + self.prefix = TDB_PREFIX + + def tearDown(self): + super(LdbBaseTest, self).tearDown() + + def url(self): + return self.prefix + self.filename + + def flags(self): + if self.prefix == MDB_PREFIX: + return ldb.FLG_NOSYNC + else: + return 0 + + +class MaxIndexKeyLengthTests(LdbBaseTest): + def checkGuids(self, key, guids): + # + # This check relies on the current implementation where the indexes + # are in the same database as the data. + # + # It checks that the index record exists, unless guids is None then + # the record must not exist. And the it contains the expected guid + # entries. + # + # The caller needs to provide the GUID's in the expected order + # + res = self.l.search( + base=key, + scope=ldb.SCOPE_BASE) + if guids is None: + self.assertEqual(len(res), 0) + return + self.assertEqual(len(res), 1) + + # The GUID index format has only one value + index = res[0]["@IDX"][0] + self.assertEqual(len(guids), len(index)) + self.assertEqual(guids, index) + + def tearDown(self): + shutil.rmtree(self.testdir) + super(MaxIndexKeyLengthTests, self).tearDown() + + # Ensure the LDB is closed now, so we close the FD + del(self.l) + + def setUp(self): + super(MaxIndexKeyLengthTests, self).setUp() + self.testdir = tempdir() + self.filename = os.path.join(self.testdir, "key_len_test.ldb") + # Note that the maximum key length is set to 54 + # This accounts for the 4 bytes added by the dn formatting + # a leading dn=, and a trailing zero terminator + # + self.l = ldb.Ldb(self.url(), + options=[ + "modules:rdn_name", + "max_key_len_for_self_test:54"]) + self.l.add({"dn": "@ATTRIBUTES", + "uniqueThing": "UNIQUE_INDEX"}) + self.l.add({"dn": "@INDEXLIST", + "@IDXATTR": [ + b"uniqueThing", + b"notUnique", + b"base64____lt", + b"base64_____eq", + b"base64______gt"], + "@IDXONE": [b"1"], + "@IDXGUID": [b"objectUUID"], + "@IDX_DN_GUID": [b"GUID"]}) + + # Add a value to a unique index that exceeds the maximum key length + # This should be rejected. + def test_add_long_unique_add(self): + try: + self.l.add({"dn": "OU=UNIQUE_MAX_LEN,DC=SAMBA,DC=ORG", + "objectUUID": b"0123456789abcdef", + "uniqueThing": "01234567890123456789012345678901"}) + # index key will be + # "@INDEX:UNIQUETHING:01234567890123456789012345678901" + self.fail("Should have failed on long index key") + + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_CONSTRAINT_VIOLATION) + + # Test that DN's longer the maximum key length can be added + # and that duplicate DN's are rejected correctly + def test_add_long_dn_add(self): + # + # For all entries the DN index key gets truncated to + # @INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA + # + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG", + "objectUUID": b"0123456789abcdef"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcdef") + + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM", + "objectUUID": b"0123456789abcde0"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcde0" + b"0123456789abcdef") + + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV", + "objectUUID": b"0123456789abcde1"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcde0" + b"0123456789abcde1" + b"0123456789abcdef") + + # Key is equal to max length does not get inserted into the truncated + # key namespace + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + "objectUUID": b"0123456789abcde5"}) + self.checkGuids( + "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcde5") + + # This key should not get truncated, as it's one character less than + # max, and will not be in the truncate name space + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXX,DC=SAMBA", + "objectUUID": b"0123456789abcde7"}) + self.checkGuids( + "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcde7") + + try: + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG", + "objectUUID": b"0123456789abcde2"}) + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) + + try: + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM", + "objectUUID": b"0123456789abcde3"}) + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) + + try: + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV", + "objectUUID": b"0123456789abcde4"}) + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) + + try: + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + "objectUUID": b"0123456789abcde6"}) + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) + + try: + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXX,DC=SAMBA", + "objectUUID": b"0123456789abcde8"}) + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) + + def test_rename_truncated_dn_keys(self): + # For all entries the DN index key gets truncated to + # 0 1 2 3 4 5 + # 12345678901234567890123456789012345678901234567890 + # @INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG", + "objectUUID": b"0123456789abcdef"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcdef") + + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM", + "objectUUID": b"0123456789abcde0"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcde0" + b"0123456789abcdef") + + # Non conflicting rename, should succeed + self.l.rename("OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG", + "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV") + # Index should be unchanged. + self.checkGuids( + "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcde0" + b"0123456789abcdef") + + # Conflicting rename should fail + try: + self.l.rename("OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM", + "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV") + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) + + def test_delete_truncated_dn_keys(self): + # + # For all entries the DN index key gets truncated to + # 0 1 2 3 4 5 + # 12345678901234567890123456789012345678901234567890 + # @INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA + # + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG", + "objectUUID": b"0123456789abcdef"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcdef") + + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV", + "objectUUID": b"0123456789abcde1"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcde1" + b"0123456789abcdef") + + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + "objectUUID": b"0123456789abcde5"}) + self.checkGuids( + "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcde5") + + # Try to delete a non existent DN with a truncated key + try: + self.l.delete("OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM") + except ldb.LdbError as err: + enum = err.args[0] + self.assertEqual(enum, ldb.ERR_NO_SUCH_OBJECT) + # Ensure that non of the other truncated DN's got deleted + res = self.l.search( + base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG") + self.assertEqual(len(res), 1) + + res = self.l.search( + base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV") + self.assertEqual(len(res), 1) + + # Ensure that the non truncated DN did not get deleted + res = self.l.search( + base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA") + self.assertEqual(len(res), 1) + + # Check the indexes are correct + self.checkGuids( + "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcde1" + b"0123456789abcdef") + self.checkGuids( + "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcde5") + + # delete an existing entry + self.l.delete("OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG") + + # Ensure it got deleted + res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG") + self.assertEqual(len(res), 0) + + # Ensure that non of the other truncated DN's got deleted + res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV") + self.assertEqual(len(res), 1) + + # Ensure the non truncated entry did not get deleted. + res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA") + self.assertEqual(len(res), 1) + + # Check the indexes are correct + self.checkGuids( + "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcde1") + self.checkGuids( + "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcde5") + + # delete an existing entry + self.l.delete("OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV") + + # Ensure it got deleted + res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXX,DC=SAMBA,DC=GOV") + self.assertEqual(len(res), 0) + + # Ensure that non of the non truncated DN's got deleted + res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA") + self.assertEqual(len(res), 1) + # Check the indexes are correct + self.checkGuids( + "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + None) + self.checkGuids( + "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcde5") + + # delete an existing entry + self.l.delete("OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA") + + # Ensure it got deleted + res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBAxxx") + self.assertEqual(len(res), 0) + self.checkGuids( + "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + None) + + def test_search_truncated_dn_keys(self): + # + # For all entries the DN index key gets truncated to + # 0 1 2 3 4 5 + # 12345678901234567890123456789012345678901234567890 + # @INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA + # + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG", + "objectUUID": b"0123456789abcdef"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcdef") + + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV", + "objectUUID": b"0123456789abcde1"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcde1" + b"0123456789abcdef") + + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + "objectUUID": b"0123456789abcde5"}) + self.checkGuids( + "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcde5") + + res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG") + self.assertEqual(len(res), 1) + + res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV") + self.assertEqual(len(res), 1) + + res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA") + self.assertEqual(len(res), 1) + + res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM") + self.assertEqual(len(res), 0) + + res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXX,DC=SAMBA,DC=GOV") + self.assertEqual(len(res), 0) + + # Non existent, key one less than truncation limit + res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXX,DC=SAMBA") + self.assertEqual(len(res), 0) + + def test_search_dn_filter_truncated_dn_keys(self): + # + # For all entries the DN index key gets truncated to + # 0 1 2 3 4 5 + # 12345678901234567890123456789012345678901234567890 + # @INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA + # + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG", + "objectUUID": b"0123456789abcdef"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcdef") + + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV", + "objectUUID": b"0123456789abcde1"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcde1" + b"0123456789abcdef") + + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + "objectUUID": b"0123456789abcde5"}) + self.checkGuids( + "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcde5") + + res = self.l.search( + expression="dn=OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG") + self.assertEqual(len(res), 1) + + res = self.l.search( + expression="dn=OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV") + self.assertEqual(len(res), 1) + + res = self.l.search( + expression="dn=OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA") + self.assertEqual(len(res), 1) + + res = self.l.search( + expression="dn=OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM") + self.assertEqual(len(res), 0) + + res = self.l.search( + expression="dn=OU=A_LONG_DNXXXXXXXXXXXX,DC=SAMBA,DC=GOV") + self.assertEqual(len(res), 0) + + # Non existent, key one less than truncation limit + res = self.l.search( + expression="dn=OU=A_LONG_DNXXXXXXXXXXXXXX,DC=SAMBA") + self.assertEqual(len(res), 0) + + def test_search_one_level_truncated_dn_keys(self): + # + # Except for the base DN's + # all entries the DN index key gets truncated to + # 0 1 2 3 4 5 + # 12345678901234567890123456789012345678901234567890 + # @INDEX:@IDXDN:OU=??,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA + # The base DN-s truncate to + # @INDEX:@IDXDN:OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR + # + self.l.add({"dn": "OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1", + "objectUUID": b"0123456789abcdef"}) + self.l.add({"dn": "OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2", + "objectUUID": b"0123456789abcd1f"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR", + b"0123456789abcd1f" + b"0123456789abcdef") + + self.l.add({"dn": "OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1", + "objectUUID": b"0123456789abcde1"}) + self.l.add({"dn": "OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2", + "objectUUID": b"0123456789abcd11"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA", + b"0123456789abcd11" + b"0123456789abcde1") + + self.l.add({"dn": "OU=02,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1", + "objectUUID": b"0123456789abcde2"}) + self.l.add({"dn": "OU=02,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2", + "objectUUID": b"0123456789abcdf2"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=02,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA", + b"0123456789abcde2" + b"0123456789abcdf2") + + self.l.add({"dn": "OU=03,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1", + "objectUUID": b"0123456789abcde3"}) + self.l.add({"dn": "OU=03,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2", + "objectUUID": b"0123456789abcd13"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=03,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA", + b"0123456789abcd13" + b"0123456789abcde3") + + # This key is not truncated as it's the max_key_len + self.l.add({"dn": "OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA", + "objectUUID": b"0123456789abcde7"}) + self.checkGuids( + "@INDEX:@IDXDN:OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA", + b"0123456789abcde7") + + res = self.l.search(base="OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1", + scope=ldb.SCOPE_ONELEVEL) + self.assertEqual(len(res), 3) + self.assertTrue( + contains(res, "OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1")) + self.assertTrue( + contains(res, "OU=02,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1")) + self.assertTrue( + contains(res, "OU=03,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1")) + + res = self.l.search(base="OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2", + scope=ldb.SCOPE_ONELEVEL) + self.assertEqual(len(res), 3) + self.assertTrue( + contains(res, "OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2")) + self.assertTrue( + contains(res, "OU=02,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2")) + self.assertTrue( + contains(res, "OU=03,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2")) + + res = self.l.search(base="OU=A_LONG_DN_ONE_LVLX,DC=SAMBA", + scope=ldb.SCOPE_ONELEVEL) + self.assertEqual(len(res), 1) + self.assertTrue( + contains(res, "OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA")) + + def test_search_sub_tree_truncated_dn_keys(self): + # + # Except for the base DN's + # all entries the DN index key gets truncated to + # 0 1 2 3 4 5 + # 12345678901234567890123456789012345678901234567890 + # @INDEX:@IDXDN:OU=??,OU=A_LONG_DN_SUB_TREE,DC=SAMBA + # The base DN-s truncate to + # @INDEX:@IDXDN:OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR + # + self.l.add({"dn": "OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1", + "objectUUID": b"0123456789abcdef"}) + self.l.add({"dn": "OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2", + "objectUUID": b"0123456789abcde4"}) + self.l.add({"dn": "OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR3", + "objectUUID": b"0123456789abcde8"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR", + b"0123456789abcde4" + b"0123456789abcde8" + b"0123456789abcdef") + + self.l.add({"dn": "OU=01,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1", + "objectUUID": b"0123456789abcde1"}) + self.l.add({"dn": "OU=01,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2", + "objectUUID": b"0123456789abcde5"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=01,OU=A_LONG_DN_SUB_TREE,DC=SAMBA", + b"0123456789abcde1" + b"0123456789abcde5") + + self.l.add({"dn": "OU=02,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1", + "objectUUID": b"0123456789abcde2"}) + self.l.add({"dn": "OU=02,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2", + "objectUUID": b"0123456789abcde6"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=02,OU=A_LONG_DN_SUB_TREE,DC=SAMBA", + b"0123456789abcde2" + b"0123456789abcde6") + + self.l.add({"dn": "OU=03,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1", + "objectUUID": b"0123456789abcde3"}) + + self.l.add({"dn": "OU=03,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2", + "objectUUID": b"0123456789abcde7"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=03,OU=A_LONG_DN_SUB_TREE,DC=SAMBA", + b"0123456789abcde3" + b"0123456789abcde7") + + self.l.add({"dn": "OU=04,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR4", + "objectUUID": b"0123456789abcde9"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=04,OU=A_LONG_DN_SUB_TREE,DC=SAMBA", + b"0123456789abcde9") + + res = self.l.search(base="OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1", + scope=ldb.SCOPE_SUBTREE) + self.assertEqual(len(res), 4) + self.assertTrue( + contains(res, "OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1")) + self.assertTrue( + contains(res, "OU=01,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1")) + self.assertTrue( + contains(res, "OU=02,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1")) + self.assertTrue( + contains(res, "OU=03,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1")) + + res = self.l.search(base="OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2", + scope=ldb.SCOPE_SUBTREE) + self.assertEqual(len(res), 4) + self.assertTrue( + contains(res, "OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2")) + self.assertTrue( + contains(res, "OU=01,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2")) + self.assertTrue( + contains(res, "OU=02,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2")) + self.assertTrue( + contains(res, "OU=03,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2")) + + res = self.l.search(base="OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR3", + scope=ldb.SCOPE_SUBTREE) + self.assertEqual(len(res), 1) + self.assertTrue( + contains(res, "OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR3")) + + res = self.l.search(base="OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR4", + scope=ldb.SCOPE_SUBTREE) + self.assertEqual(len(res), 1) + self.assertTrue( + contains(res, "OU=04,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR4")) + + def test_search_base_truncated_dn_keys(self): + # + # For all entries the DN index key gets truncated to + # 0 1 2 3 4 5 + # 12345678901234567890123456789012345678901234567890 + # @INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA + # + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG", + "objectUUID": b"0123456789abcdef"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcdef") + + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV", + "objectUUID": b"0123456789abcde1"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcde1" + b"0123456789abcdef") + + self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + "objectUUID": b"0123456789abcde5"}) + self.checkGuids( + "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + b"0123456789abcde5") + + res = self.l.search( + base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_BASE) + self.assertEqual(len(res), 1) + + res = self.l.search( + base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV", + scope=ldb.SCOPE_BASE) + self.assertEqual(len(res), 1) + + res = self.l.search( + base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", + scope=ldb.SCOPE_BASE) + self.assertEqual(len(res), 1) + + res = self.l.search( + base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM", + scope=ldb.SCOPE_BASE) + self.assertEqual(len(res), 0) + + res = self.l.search( + base="OU=A_LONG_DNXXXXXXXXXXXX,DC=SAMBA,DC=GOV", + scope=ldb.SCOPE_BASE) + self.assertEqual(len(res), 0) + + # Non existent, key one less than truncation limit + res = self.l.search( + base="OU=A_LONG_DNXXXXXXXXXXXXXX,DC=SAMBA", + scope=ldb.SCOPE_BASE) + self.assertEqual(len(res), 0) + + # + # Test non unique index searched with truncated keys + # + def test_index_truncated_keys(self): + # 0 1 2 3 4 5 + # 12345678901234567890123456789012345678901234567890 + # @INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + eq_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + gt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + lt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + # > than max length and differs in values that will be truncated + gt_max_b = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab" + + # Add two entries with the same value, key length = max so no + # truncation. + self.l.add({"dn": "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", + "notUnique": eq_max, + "objectUUID": b"0123456789abcde0"}) + self.checkGuids( + "@INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + b"0123456789abcde0") + + self.l.add({"dn": "OU=02,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", + "notUnique": eq_max, + "objectUUID": b"0123456789abcde1"}) + self.checkGuids( + "@INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + b"0123456789abcde0" + b"0123456789abcde1") + + # + # An entry outside the tree + # + self.l.add({"dn": "OU=10,OU=SEARCH_NON_UNIQUE01,DC=SAMBA,DC=ORG", + "notUnique": eq_max, + "objectUUID": b"0123456789abcd11"}) + self.checkGuids( + "@INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + b"0123456789abcd11" + b"0123456789abcde0" + b"0123456789abcde1") + + # Key longer than max so should get truncated to same key as + # the previous two entries + self.l.add({"dn": "OU=03,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", + "notUnique": gt_max, + "objectUUID": b"0123456789abcde2"}) + # But in the truncated key space + self.checkGuids( + "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + b"0123456789abcde2") + + # Key longer than max so should get truncated to same key as + # the previous entries but differs in the chars after max length + self.l.add({"dn": "OU=23,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", + "notUnique": gt_max_b, + "objectUUID": b"0123456789abcd22"}) + # But in the truncated key space + self.checkGuids( + "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + b"0123456789abcd22" + b"0123456789abcde2") + # + # An entry outside the tree + # + self.l.add({"dn": "OU=11,OU=SEARCH_NON_UNIQUE01,DC=SAMBA,DC=ORG", + "notUnique": gt_max, + "objectUUID": b"0123456789abcd12"}) + self.checkGuids( + "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + b"0123456789abcd12" + b"0123456789abcd22" + b"0123456789abcde2") + + # Key shorter than max + # + self.l.add({"dn": "OU=04,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", + "notUnique": lt_max, + "objectUUID": b"0123456789abcde3"}) + self.checkGuids( + "@INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + b"0123456789abcde3") + # + # An entry outside the tree + # + self.l.add({"dn": "OU=12,OU=SEARCH_NON_UNIQUE01,DC=SAMBA,DC=ORG", + "notUnique": lt_max, + "objectUUID": b"0123456789abcd13"}) + self.checkGuids( + "@INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + b"0123456789abcd13" + b"0123456789abcde3") + + # + # search for target is max value not truncated + # should return ou's 01, 02 + # + expression = "(notUnique=" + eq_max.decode('ascii') + ")" + res = self.l.search(base="OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression=expression) + self.assertEqual(len(res), 2) + self.assertTrue( + contains(res, "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) + self.assertTrue( + contains(res, "OU=02,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) + # + # search for target is max value not truncated + # search one level up the tree, scope is ONE_LEVEL + # So should get no matches + # + expression = "(notUnique=" + eq_max.decode('ascii') + ")" + res = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression=expression) + self.assertEqual(len(res), 0) + # + # search for target is max value not truncated + # search one level up the tree, scope is SUBTREE + # So should get 3 matches + # + res = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression=expression) + self.assertEqual(len(res), 3) + self.assertTrue( + contains(res, "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) + self.assertTrue( + contains(res, "OU=02,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) + self.assertTrue( + contains(res, "OU=10,OU=SEARCH_NON_UNIQUE01,DC=SAMBA,DC=ORG")) + # + # search for target is max value + 1 so truncated + # should return ou 23 as it's gt_max_b being searched for + # + expression = "(notUnique=" + gt_max_b.decode('ascii') + ")" + res = self.l.search(base="OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression=expression) + self.assertEqual(len(res), 1) + self.assertTrue( + contains(res, "OU=23,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) + + # + # search for target is max value + 1 so truncated + # should return ou 03 as it's gt_max being searched for + # + expression = "(notUnique=" + gt_max.decode('ascii') + ")" + res = self.l.search(base="OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression=expression) + self.assertEqual(len(res), 1) + self.assertTrue( + contains(res, "OU=03,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) + + # + # scope one level and one level up one level up should get no matches + # + res = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression=expression) + self.assertEqual(len(res), 0) + # + # scope sub tree and one level up one level up should get 2 matches + # + res = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression=expression) + self.assertEqual(len(res), 2) + self.assertTrue( + contains(res, "OU=03,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) + self.assertTrue( + contains(res, "OU=11,OU=SEARCH_NON_UNIQUE01,DC=SAMBA,DC=ORG")) + + # + # search for target is max value - 1 so not truncated + # should return ou 04 + # + expression = "(notUnique=" + lt_max.decode('ascii') + ")" + res = self.l.search(base="OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression=expression) + self.assertEqual(len(res), 1) + self.assertTrue( + contains(res, "OU=04,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) + + # + # scope one level and one level up one level up should get no matches + # + res = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression=expression) + self.assertEqual(len(res), 0) + + # + # scope sub tree and one level up one level up should get 2 matches + # + res = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression=expression) + self.assertEqual(len(res), 2) + self.assertTrue( + contains(res, "OU=04,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) + self.assertTrue( + contains(res, "OU=12,OU=SEARCH_NON_UNIQUE01,DC=SAMBA,DC=ORG")) + + # + # Test index key truncation for base64 encoded values + # + def test_index_truncated_base64_encoded_keys(self): + value = b"aaaaaaaaaaaaaaaaaaaa\x02" + # base64 encodes to "YWFhYWFhYWFhYWFhYWFhYWFhYWEC" + + # One less than max key length + self.l.add({"dn": "OU=01,OU=BASE64,DC=SAMBA,DC=ORG", + "base64____lt": value, + "objectUUID": b"0123456789abcde0"}) + self.checkGuids( + "@INDEX:BASE64____LT::YWFhYWFhYWFhYWFhYWFhYWFhYWEC", + b"0123456789abcde0") + + # Equal max key length + self.l.add({"dn": "OU=02,OU=BASE64,DC=SAMBA,DC=ORG", + "base64_____eq": value, + "objectUUID": b"0123456789abcde1"}) + self.checkGuids( + "@INDEX:BASE64_____EQ::YWFhYWFhYWFhYWFhYWFhYWFhYWEC", + b"0123456789abcde1") + + # One greater than max key length + self.l.add({"dn": "OU=03,OU=BASE64,DC=SAMBA,DC=ORG", + "base64______gt": value, + "objectUUID": b"0123456789abcde2"}) + self.checkGuids( + "@INDEX#BASE64______GT##YWFhYWFhYWFhYWFhYWFhYWFhYWE", + b"0123456789abcde2") + # + # Test adding to non unique index with identical multivalued index + # attributes + # + + def test_index_multi_valued_identical_keys(self): + # 0 1 2 3 4 5 + # 12345678901234567890123456789012345678901234567890 + # @INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + as_eq_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + bs_eq_max = b"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + + try: + self.l.add({"dn": "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", + "notUnique": [bs_eq_max, as_eq_max, as_eq_max], + "objectUUID": b"0123456789abcde0"}) + self.fail("Exception not thrown") + except ldb.LdbError as e: + code = e.args[0] + self.assertEqual(ldb.ERR_ATTRIBUTE_OR_VALUE_EXISTS, code) + + # + # Test non unique index with multivalued index attributes + # searched with non truncated keys + # + def test_search_index_multi_valued_truncated_keys(self): + # 0 1 2 3 4 5 + # 12345678901234567890123456789012345678901234567890 + # @INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + aa_gt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + ab_gt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab" + bb_gt_max = b"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + + self.l.add({"dn": "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", + "notUnique": [aa_gt_max, ab_gt_max, bb_gt_max], + "objectUUID": b"0123456789abcde0"}) + self.checkGuids( + "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + b"0123456789abcde0" + b"0123456789abcde0") + self.checkGuids( + "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + b"0123456789abcde0") + + expression = "(notUnique=" + aa_gt_max.decode('ascii') + ")" + res = self.l.search(base="OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression=expression) + self.assertEqual(len(res), 1) + self.assertTrue( + contains(res, "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) + + expression = "(notUnique=" + ab_gt_max.decode('ascii') + ")" + res = self.l.search(base="OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression=expression) + self.assertEqual(len(res), 1) + self.assertTrue( + contains(res, "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) + + expression = "(notUnique=" + bb_gt_max.decode('ascii') + ")" + res = self.l.search(base="OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_ONELEVEL, + expression=expression) + self.assertEqual(len(res), 1) + self.assertTrue( + contains(res, "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) + + # + # Test deletion of records with non unique index with multivalued index + # attributes + # replicate this to test modify with modify flags i.e. DELETE, REPLACE + # + def test_delete_index_multi_valued_truncated_keys(self): + # 0 1 2 3 4 5 + # 12345678901234567890123456789012345678901234567890 + # @INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + aa_gt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + ab_gt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab" + bb_gt_max = b"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + cc_gt_max = b"cccccccccccccccccccccccccccccccccc" + + self.l.add({"dn": "OU=01,OU=DELETE_NON_UNIQUE,DC=SAMBA,DC=ORG", + "notUnique": [aa_gt_max, ab_gt_max, bb_gt_max], + "objectUUID": b"0123456789abcde0"}) + self.l.add({"dn": "OU=02,OU=DELETE_NON_UNIQUE,DC=SAMBA,DC=ORG", + "notUnique": [aa_gt_max, ab_gt_max, cc_gt_max], + "objectUUID": b"0123456789abcde1"}) + self.checkGuids( + "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + b"0123456789abcde0" + b"0123456789abcde0" + + b"0123456789abcde1" + b"0123456789abcde1") + self.checkGuids( + "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + b"0123456789abcde0") + self.checkGuids( + "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc", + b"0123456789abcde1") + + res = self.l.search( + base="DC=SAMBA,DC=ORG", + expression="(notUnique=" + aa_gt_max.decode("ascii") + ")") + self.assertEqual(2, len(res)) + self.assertTrue( + contains(res, "OU=01,OU=DELETE_NON_UNIQUE,DC=SAMBA,DC=ORG")) + self.assertTrue( + contains(res, "OU=02,OU=DELETE_NON_UNIQUE,DC=SAMBA,DC=ORG")) + + self.l.delete("OU=02,OU=DELETE_NON_UNIQUE,DC=SAMBA,DC=ORG") + self.checkGuids( + "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + b"0123456789abcde0" + b"0123456789abcde0") + self.checkGuids( + "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + b"0123456789abcde0") + self.checkGuids( + "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc", + None) + + self.l.delete("OU=01,OU=DELETE_NON_UNIQUE,DC=SAMBA,DC=ORG") + self.checkGuids( + "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + None) + self.checkGuids( + "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + None) + self.checkGuids( + "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc", + None) + + # + # Test modification of records with non unique index with multivalued index + # attributes + # + def test_modify_index_multi_valued_truncated_keys(self): + # 0 1 2 3 4 5 + # 12345678901234567890123456789012345678901234567890 + # @INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + aa_gt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + ab_gt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab" + bb_gt_max = b"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + cc_gt_max = b"cccccccccccccccccccccccccccccccccc" + + self.l.add({"dn": "OU=01,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG", + "notUnique": [aa_gt_max, ab_gt_max, bb_gt_max], + "objectUUID": b"0123456789abcde0"}) + self.l.add({"dn": "OU=02,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG", + "notUnique": [aa_gt_max, ab_gt_max, cc_gt_max], + "objectUUID": b"0123456789abcde1"}) + self.checkGuids( + "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + b"0123456789abcde0" + b"0123456789abcde0" + + b"0123456789abcde1" + b"0123456789abcde1") + self.checkGuids( + "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + b"0123456789abcde0") + self.checkGuids( + "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc", + b"0123456789abcde1") + + res = self.l.search( + base="DC=SAMBA,DC=ORG", + expression="(notUnique=" + aa_gt_max.decode("ascii") + ")") + self.assertEqual(2, len(res)) + self.assertTrue( + contains(res, "OU=01,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG")) + self.assertTrue( + contains(res, "OU=02,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG")) + + # + # Modify that does not change the indexed attribute + # + msg = ldb.Message() + msg.dn = ldb.Dn(self.l, "OU=01,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG") + msg["notUnique"] = ldb.MessageElement( + [aa_gt_max, ab_gt_max, bb_gt_max], + ldb.FLAG_MOD_REPLACE, + "notUnique") + self.l.modify(msg) + # + # As the modify is replacing the attribute with the same contents + # there should be no changes to the indexes. + # + self.checkGuids( + "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + b"0123456789abcde0" + b"0123456789abcde0" + + b"0123456789abcde1" + b"0123456789abcde1") + self.checkGuids( + "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + b"0123456789abcde0") + self.checkGuids( + "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc", + b"0123456789abcde1") + + # + # Modify that removes a value from the indexed attribute + # + msg = ldb.Message() + msg.dn = ldb.Dn(self.l, "OU=01,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG") + msg["notUnique"] = ldb.MessageElement( + [aa_gt_max, bb_gt_max], + ldb.FLAG_MOD_REPLACE, + "notUnique") + self.l.modify(msg) + + self.checkGuids( + "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + b"0123456789abcde0" + + b"0123456789abcde1" + b"0123456789abcde1") + self.checkGuids( + "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + b"0123456789abcde0") + self.checkGuids( + "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc", + b"0123456789abcde1") + + # + # Modify that does a constrained delete the indexed attribute + # + msg = ldb.Message() + msg.dn = ldb.Dn(self.l, "OU=02,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG") + msg["notUnique"] = ldb.MessageElement( + [ab_gt_max], + ldb.FLAG_MOD_DELETE, + "notUnique") + self.l.modify(msg) + + self.checkGuids( + "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + b"0123456789abcde0" + b"0123456789abcde1") + self.checkGuids( + "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + b"0123456789abcde0") + self.checkGuids( + "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc", + b"0123456789abcde1") + + # + # Modify that does an unconstrained delete the indexed attribute + # + msg = ldb.Message() + msg.dn = ldb.Dn(self.l, "OU=02,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG") + msg["notUnique"] = ldb.MessageElement( + [], + ldb.FLAG_MOD_DELETE, + "notUnique") + self.l.modify(msg) + + self.checkGuids( + "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + b"0123456789abcde0") + self.checkGuids( + "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + b"0123456789abcde0") + self.checkGuids( + "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc", + None) + + # + # Modify that adds a value to the indexed attribute + # + msg = ldb.Message() + msg.dn = ldb.Dn(self.l, "OU=02,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG") + msg["notUnique"] = ldb.MessageElement( + [cc_gt_max], + ldb.FLAG_MOD_ADD, + "notUnique") + self.l.modify(msg) + + self.checkGuids( + "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + b"0123456789abcde0") + self.checkGuids( + "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + b"0123456789abcde0") + self.checkGuids( + "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc", + b"0123456789abcde1") + + # + # Modify that adds a values to the indexed attribute + # + msg = ldb.Message() + msg.dn = ldb.Dn(self.l, "OU=02,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG") + msg["notUnique"] = ldb.MessageElement( + [aa_gt_max, ab_gt_max], + ldb.FLAG_MOD_ADD, + "notUnique") + self.l.modify(msg) + + self.checkGuids( + "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + b"0123456789abcde0" + + b"0123456789abcde1" + b"0123456789abcde1") + self.checkGuids( + "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + b"0123456789abcde0") + self.checkGuids( + "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc", + b"0123456789abcde1") + + # + # Test Sub tree searches when checkBaseOnSearch is enabled and the + # DN indexes are truncated and collide. + # + def test_check_base_on_search_truncated_dn_keys(self): + # + # Except for the base DN's + # all entries the DN index key gets truncated to + # 0 1 2 3 4 5 + # 12345678901234567890123456789012345678901234567890 + # @INDEX:@IDXDN:OU=??,OU=CHECK_BASE_DN_XXXX,DC=SAMBA + # The base DN-s truncate to + # @INDEX:@IDXDN:OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR + # + checkbaseonsearch = {"dn": "@OPTIONS", + "checkBaseOnSearch": b"TRUE"} + self.l.add(checkbaseonsearch) + + self.l.add({"dn": "OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR1", + "objectUUID": b"0123456789abcdef"}) + self.l.add({"dn": "OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR2", + "objectUUID": b"0123456789abcdee"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR", + b"0123456789abcdee" + b"0123456789abcdef") + + self.l.add({"dn": "OU=01,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR1", + "objectUUID": b"0123456789abcdec"}) + self.l.add({"dn": "OU=01,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR2", + "objectUUID": b"0123456789abcdeb"}) + self.l.add({"dn": "OU=01,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR3", + "objectUUID": b"0123456789abcded"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=01,OU=CHECK_BASE_DN_XXXX,DC=SAMBA", + b"0123456789abcdeb" + b"0123456789abcdec" + b"0123456789abcded") + + self.l.add({"dn": "OU=02,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR1", + "objectUUID": b"0123456789abcde0"}) + self.l.add({"dn": "OU=02,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR2", + "objectUUID": b"0123456789abcde1"}) + self.l.add({"dn": "OU=02,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR3", + "objectUUID": b"0123456789abcde2"}) + self.checkGuids( + "@INDEX#@IDXDN#OU=02,OU=CHECK_BASE_DN_XXXX,DC=SAMBA", + b"0123456789abcde0" + b"0123456789abcde1" + b"0123456789abcde2") + + res = self.l.search(base="OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR1", + scope=ldb.SCOPE_SUBTREE) + self.assertEqual(len(res), 3) + self.assertTrue( + contains(res, "OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR1")) + self.assertTrue( + contains(res, "OU=01,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR1")) + self.assertTrue( + contains(res, "OU=02,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR1")) + + res = self.l.search(base="OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR2", + scope=ldb.SCOPE_SUBTREE) + self.assertEqual(len(res), 3) + self.assertTrue( + contains(res, "OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR2")) + self.assertTrue( + contains(res, "OU=01,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR2")) + self.assertTrue( + contains(res, "OU=02,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR2")) + + try: + res = self.l.search(base="OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR3", + scope=ldb.SCOPE_SUBTREE) + self.fail("Expected exception no thrown") + except ldb.LdbError as e: + code = e.args[0] + self.assertEqual(ldb.ERR_NO_SUCH_OBJECT, code) + + +# Run the index truncation tests against an lmdb backend +class MaxIndexKeyLengthTestsLmdb(MaxIndexKeyLengthTests): + + def setUp(self): + if os.environ.get('HAVE_LMDB', '1') == '0': + self.skipTest("No lmdb backend") + self.prefix = MDB_PREFIX + super(MaxIndexKeyLengthTestsLmdb, self).setUp() + + def tearDown(self): + super(MaxIndexKeyLengthTestsLmdb, self).tearDown() + + +class OrderedIntegerRangeTests(LdbBaseTest): + + def tearDown(self): + shutil.rmtree(self.testdir) + super(OrderedIntegerRangeTests, self).tearDown() + + # Ensure the LDB is closed now, so we close the FD + del(self.l) + + def setUp(self): + super(OrderedIntegerRangeTests, self).setUp() + self.testdir = tempdir() + self.filename = os.path.join(self.testdir, "ordered_integer_test.ldb") + + self.l = ldb.Ldb(self.url(), + options=self.options()) + self.l.add({"dn": "@ATTRIBUTES", + "int64attr": "ORDERED_INTEGER"}) + self.l.add({"dn": "@INDEXLIST", + "@IDXATTR": [b"int64attr"], + "@IDXONE": [b"1"], + "@IDXGUID": [b"objectUUID"], + "@IDX_DN_GUID": [b"GUID"]}) + + def options(self): + if self.prefix == MDB_PREFIX: + return ['modules:rdn_name', + 'disable_full_db_scan_for_self_test:1'] + else: + return ['modules:rdn_name'] + + def test_comparison_expression(self): + int64_max = 2**63-1 + int64_min = -2**63 + test_nums = list(range(-5, 5)) + test_nums += list(range(int64_max-5, int64_max+1)) + test_nums += list(range(int64_min, int64_min+5)) + test_nums = sorted(test_nums) + + for (i, num) in enumerate(test_nums): + ouuid = 0x0123456789abcdef + i + ouuid_s = bytes(('0' + hex(ouuid)[2:]).encode()) + self.l.add({"dn": "OU=COMPTESTOU{},DC=SAMBA,DC=ORG".format(i), + "objectUUID": ouuid_s, + "int64attr": str(num)}) + + def assert_int64_expr(expr, py_expr=None): + res = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(int64attr%s)" % (expr)) + + if not py_expr: + py_expr = expr + expect = [n for n in test_nums if eval(str(n) + py_expr)] + vals = sorted([int(r.get("int64attr")[0]) for r in res]) + self.assertEqual(len(res), len(expect)) + self.assertEqual(set(vals), set(expect)) + self.assertEqual(expect, vals) + + assert_int64_expr(">=-2") + assert_int64_expr("<=2") + assert_int64_expr(">=" + str(int64_min)) + assert_int64_expr("<=" + str(int64_min)) + assert_int64_expr("<=" + str(int64_min+1)) + assert_int64_expr("<=" + str(int64_max)) + assert_int64_expr(">=" + str(int64_max)) + assert_int64_expr(">=" + str(int64_max-1)) + assert_int64_expr("=10", "==10") + + def test_comparison_expression_duplicates(self): + int64_max = 2**63-1 + int64_min = -2**63 + test_nums = list(range(-5, 5)) * 3 + test_nums += list(range(-20, 20, 5)) * 2 + test_nums += list(range(-50, 50, 15)) + test_nums = sorted(test_nums) + + for (i, num) in enumerate(test_nums): + ouuid = 0x0123456789abcdef + i + ouuid_s = bytes(('0' + hex(ouuid)[2:]).encode()) + self.l.add({"dn": "OU=COMPTESTOU{},DC=SAMBA,DC=ORG".format(i), + "objectUUID": ouuid_s, + "int64attr": str(num)}) + + def assert_int64_expr(expr, py_expr=None): + res = self.l.search(base="DC=SAMBA,DC=ORG", + scope=ldb.SCOPE_SUBTREE, + expression="(int64attr%s)" % (expr)) + + if not py_expr: + py_expr = expr + expect = [n for n in test_nums if eval(str(n) + py_expr)] + vals = sorted([int(r.get("int64attr")[0]) for r in res]) + self.assertEqual(len(res), len(expect)) + self.assertEqual(set(vals), set(expect)) + self.assertEqual(expect, vals) + + assert_int64_expr(">=-2") + assert_int64_expr("<=2") + assert_int64_expr(">=" + str(int64_min)) + assert_int64_expr("<=" + str(int64_min)) + assert_int64_expr("<=" + str(int64_min+1)) + assert_int64_expr("<=" + str(int64_max)) + assert_int64_expr(">=" + str(int64_max)) + assert_int64_expr(">=" + str(int64_max-1)) + assert_int64_expr("=-5", "==-5") + assert_int64_expr("=5", "==5") + + +# Run the ordered integer range tests against an lmdb backend +class OrderedIntegerRangeTestsLmdb(OrderedIntegerRangeTests): + + def setUp(self): + if os.environ.get('HAVE_LMDB', '1') == '0': + self.skipTest("No lmdb backend") + self.prefix = MDB_PREFIX + super(OrderedIntegerRangeTestsLmdb, self).setUp() + + def tearDown(self): + super(OrderedIntegerRangeTestsLmdb, self).tearDown() + + +# Run the index truncation tests against an lmdb backend +class RejectSubDBIndex(LdbBaseTest): + + def setUp(self): + if os.environ.get('HAVE_LMDB', '1') == '0': + self.skipTest("No lmdb backend") + self.prefix = MDB_PREFIX + super(RejectSubDBIndex, self).setUp() + self.testdir = tempdir() + self.filename = os.path.join(self.testdir, + "reject_subidx_test.ldb") + self.l = ldb.Ldb(self.url(), + options=[ + "modules:rdn_name"]) + + def tearDown(self): + super(RejectSubDBIndex, self).tearDown() + + def test_try_subdb_index(self): + try: + self.l.add({"dn": "@INDEXLIST", + "@IDX_LMDB_SUBDB": [b"1"], + "@IDXONE": [b"1"], + "@IDXGUID": [b"objectUUID"], + "@IDX_DN_GUID": [b"GUID"], + }) + except ldb.LdbError as e: + code = e.args[0] + string = e.args[1] + self.assertEqual(ldb.ERR_OPERATIONS_ERROR, code) + self.assertIn("sub-database index", string) + + +if __name__ == '__main__': + import unittest + unittest.TestProgram() diff --git a/ldb-2.0.8/tests/python/repack.py b/ldb-2.0.8/tests/python/repack.py new file mode 100644 index 0000000..0844cd2 --- /dev/null +++ b/ldb-2.0.8/tests/python/repack.py @@ -0,0 +1,204 @@ +import os +from unittest import TestCase +import shutil +from subprocess import check_output +import ldb + +TDB_PREFIX = "tdb://" +MDB_PREFIX = "mdb://" + +def tempdir(): + import tempfile + try: + dir_prefix = os.path.join(os.environ["SELFTEST_PREFIX"], "tmp") + except KeyError: + dir_prefix = None + return tempfile.mkdtemp(dir=dir_prefix) + + +# Check enabling and disabling GUID indexing works and that the database is +# repacked at version 2 if GUID indexing is enabled, or version 1 if disabled. +class GUIDIndexAndPackFormatTests(TestCase): + prefix = TDB_PREFIX + + def setup_newdb(self): + self.testdir = tempdir() + self.filename = os.path.join(self.testdir, + "guidpackformattest.ldb") + url = self.prefix + self.filename + self.l = ldb.Ldb(url, options=["modules:"]) + + self.num_recs_added = 0 + + #guidindexpackv1.ldb is a pre-made database packed with version 1 format + #but with GUID indexing enabled, which is not allowed, so Samba should + #repack the database on the first transaction. + def setup_premade_v1_db(self): + db_name = "guidindexpackv1.ldb" + this_file_dir = os.path.dirname(os.path.abspath(__file__)) + db_path = os.path.join(this_file_dir, "../", db_name) + self.testdir = tempdir() + self.filename = os.path.join(self.testdir, db_name) + + shutil.copy(db_path, self.filename) + + url = self.prefix + self.filename + self.l = ldb.Ldb(url, options=["modules:"]) + self.num_recs_added = 10 + + def tearDown(self): + if hasattr(self, 'testdir'): + shutil.rmtree(self.testdir) + + def add_one_rec(self): + ouuid = 0x0123456789abcdef + self.num_recs_added + ouuid_s = '0' + hex(ouuid)[2:] + dn = "OU=GUIDPFTEST{},DC=SAMBA,DC=ORG".format(self.num_recs_added) + rec = {"dn": dn, "objectUUID": ouuid_s, "distinguishedName": dn} + self.l.add(rec) + self.num_recs_added += 1 + + # Turn GUID back into a str for easier comparisons + return rec + + def set_guid_indexing(self, enable=True): + modmsg = ldb.Message() + modmsg.dn = ldb.Dn(self.l, '@INDEXLIST') + + attrs = {"@IDXGUID": [b"objectUUID"], + "@IDX_DN_GUID": [b"GUID"]} + for attr, val in attrs.items(): + replace = ldb.FLAG_MOD_REPLACE + el = val if enable else [] + el = ldb.MessageElement(elements=el, flags=replace, name=attr) + modmsg.add(el) + + self.l.modify(modmsg) + + # Parse out the comments above each record that ldbdump produces + # containing pack format version and KV level key for each record. + # Return all GUID index keys and the set of all unique pack formats. + def ldbdump_guid_keys_pack_formats(self): + dump = check_output(["bin/ldbdump", "-i", self.filename]) + dump = dump.decode("utf-8") + dump = dump.split("\n") + + comments = [s for s in dump if s.startswith("#")] + + guid_key_tag = "# key: GUID=" + guid_keys = {c[len(guid_key_tag):] for c in comments + if c.startswith(guid_key_tag)} + + pack_format_tag = "# pack format: " + pack_formats = {c[len(pack_format_tag):] for c in comments + if c.startswith(pack_format_tag)} + pack_formats = [int(s, 16) for s in pack_formats] + + return guid_keys, pack_formats + + # Put the whole database in a dict so we can easily check the database + # hasn't changed + def get_database(self): + recs = self.l.search(base="", scope=ldb.SCOPE_SUBTREE, expression="") + db = dict() + for r in recs: + dn = str(r.dn) + self.assertNotIn(dn, db) + db[dn] = dict() + for k in r.keys(): + k = str(k) + db[dn][k] = str(r.get(k)) + return db + + # Toggle GUID indexing on and off a few times, and check that when GUID + # indexing is enabled, the database is repacked to pack format V2, and + # when GUID indexing is disabled again, the database is repacked with + # pack format V1. + def toggle_guidindex_check_pack(self): + expect_db = self.get_database() + + for enable in [False, False, True, False, True, True, False]: + pf = ldb.PACKING_FORMAT_V2 if enable else ldb.PACKING_FORMAT + + self.set_guid_indexing(enable=enable) + + guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() + num_guid_keys = self.num_recs_added if enable else 0 + self.assertEqual(len(guid_keys), num_guid_keys) + self.assertEqual(pack_formats, [pf]) + self.assertEqual(self.get_database(), expect_db) + + rec = self.add_one_rec() + expect_db[rec['dn']] = rec + + guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() + num_guid_keys = self.num_recs_added if enable else 0 + self.assertEqual(len(guid_keys), num_guid_keys) + self.assertEqual(pack_formats, [pf]) + self.assertEqual(self.get_database(), expect_db) + + # Check a newly created database is initially packed at V1, then is + # repacked at V2 when GUID indexing is enabled. + def test_repack(self): + self.setup_newdb() + + guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() + self.assertEqual(len(guid_keys), 0) + self.assertEqual(pack_formats, [ldb.PACKING_FORMAT]) + self.assertEqual(self.get_database(), {}) + + self.l.add({"dn": "@ATTRIBUTES"}) + + guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() + self.assertEqual(len(guid_keys), 0) + self.assertEqual(pack_formats, [ldb.PACKING_FORMAT]) + self.assertEqual(self.get_database(), {}) + + self.l.add({"dn": "@INDEXLIST", + "@IDXONE": [b"1"], + "@IDXGUID": [b"objectUUID"], + "@IDX_DN_GUID": [b"GUID"]}) + + guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() + self.assertEqual(len(guid_keys), 0) + self.assertEqual(pack_formats, [ldb.PACKING_FORMAT_V2]) + self.assertEqual(self.get_database(), {}) + + rec = self.add_one_rec() + expect_db = {rec["dn"]: rec} + + guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() + self.assertEqual(len(guid_keys), 1) + self.assertEqual(pack_formats, [ldb.PACKING_FORMAT_V2]) + self.assertEqual(self.get_database(), expect_db) + + self.toggle_guidindex_check_pack() + + # Check a database with V1 format with GUID indexing enabled is repacked + # with version 2 format. + def test_guid_indexed_v1_db(self): + self.setup_premade_v1_db() + + expect_db = self.get_database() + + guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() + self.assertEqual(len(guid_keys), self.num_recs_added) + self.assertEqual(pack_formats, [ldb.PACKING_FORMAT]) + self.assertEqual(self.get_database(), expect_db) + + rec = self.add_one_rec() + expect_db[rec['dn']] = rec + + guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() + self.assertEqual(len(guid_keys), self.num_recs_added) + self.assertEqual(pack_formats, [ldb.PACKING_FORMAT_V2]) + self.assertEqual(self.get_database(), expect_db) + + self.toggle_guidindex_check_pack() + + +if __name__ == '__main__': + import unittest + + + unittest.TestProgram() diff --git a/ldb-2.0.8/tests/samba4.png b/ldb-2.0.8/tests/samba4.png new file mode 100644 index 0000000000000000000000000000000000000000..c8096889a673007dfe4911ad3988e53e54fee7a2 GIT binary patch literal 6239 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 literal 0 HcmV?d00001 diff --git a/ldb-2.0.8/tests/sample_module.c b/ldb-2.0.8/tests/sample_module.c new file mode 100644 index 0000000..6ba9ed2 --- /dev/null +++ b/ldb-2.0.8/tests/sample_module.c @@ -0,0 +1,122 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jelmer Vernooij 2007 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#include "ldb_module.h" + +static int sample_add_callback(struct ldb_request *down_req, + struct ldb_reply *ares) +{ + struct ldb_request *req = + talloc_get_type_abort(down_req->context, + struct ldb_request); + + if (ares == NULL) { + return ldb_module_done(req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + if (ares->type == LDB_REPLY_REFERRAL) { + return ldb_module_send_referral(req, ares->referral); + } + + if (ares->error != LDB_SUCCESS) { + return ldb_module_done(req, ares->controls, + ares->response, ares->error); + } + + if (ares->type != LDB_REPLY_DONE) { + return ldb_module_done(req, NULL, NULL, + LDB_ERR_OPERATIONS_ERROR); + } + + return ldb_module_done(req, ares->controls, + ares->response, LDB_SUCCESS); +} + +static int sample_add(struct ldb_module *mod, struct ldb_request *req) +{ + struct ldb_context *ldb = ldb_module_get_ctx(mod); + struct ldb_control *control = NULL; + struct ldb_message *msg = NULL; + struct ldb_request *down_req = NULL; + int ret; + + /* check if there's a relax control */ + control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID); + if (control != NULL) { + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + msg = ldb_msg_copy_shallow(req, req->op.add.message); + if (msg == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_msg_add_fmt(msg, "touchedBy", "sample"); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_build_add_req(&down_req, ldb, req, + msg, + req->controls, + req, sample_add_callback, + req); + if (ret != LDB_SUCCESS) { + return ret; + } + + talloc_steal(down_req, msg); + + /* go on with the call chain */ + return ldb_next_request(mod, down_req); +} + +static int sample_modify(struct ldb_module *mod, struct ldb_request *req) +{ + struct ldb_control *control; + + /* check if there's a relax control */ + control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID); + if (control != NULL) { + return LDB_ERR_UNWILLING_TO_PERFORM; + } + + /* not found go on */ + return ldb_next_request(mod, req); +} + + +static struct ldb_module_ops ldb_sample_module_ops = { + .name = "sample", + .add = sample_add, + .del = sample_modify, + .modify = sample_modify, +}; + +int ldb_sample_init(const char *version) +{ + LDB_MODULE_CHECK_VERSION(version); + return ldb_register_module(&ldb_sample_module_ops); +} diff --git a/ldb-2.0.8/tests/schema-tests/schema-add-test.ldif b/ldb-2.0.8/tests/schema-tests/schema-add-test.ldif new file mode 100644 index 0000000..472ab48 --- /dev/null +++ b/ldb-2.0.8/tests/schema-tests/schema-add-test.ldif @@ -0,0 +1,66 @@ +dn: CN=Users,DC=schema,DC=test +objectClass: top +objectClass: container +cn: Users +description: Default container for upgraded user accounts +instanceType: 4 +whenCreated: 20050116175504.0Z +whenChanged: 20050116175504.0Z +uSNCreated: 1 +uSNChanged: 1 +showInAdvancedViewOnly: FALSE +name: Users +objectGUID: b847056a-9934-d87b-8a1a-99fabe0863c8 +systemFlags: 0x8c000000 +objectCategory: CN=Container,CN=Schema,CN=Configuration,DC=schema,DC=test +isCriticalSystemObject: TRUE +nTSecurityDescriptor: foo + +dn: CN=Administrator,CN=Users,DC=schema,DC=test +objectClass: top +objectClass: person +objectClass: organizationalPerson +objectClass: user +cn: Administrator +description: Built-in account for administering the computer/domain +instanceType: 4 +whenCreated: 20050116175504.0Z +whenChanged: 20050116175504.0Z +uSNCreated: 1 +memberOf: CN=Group Policy Creator Owners,CN=Users,DC=schema,DC=test +memberOf: CN=Domain Admins,CN=Users,DC=schema,DC=test +memberOf: CN=Enterprise Admins,CN=Users,DC=schema,DC=test +memberOf: CN=Schema Admins,CN=Users,DC=schema,DC=test +memberOf: CN=Administrators,CN=Builtin,DC=schema,DC=test +uSNChanged: 1 +name: Administrator +objectGUID: 6c02f98c-46c6-aa38-5f13-a510cac04e6c +userAccountControl: 0x10200 +badPwdCount: 0 +codePage: 0 +countryCode: 0 +badPasswordTime: 0 +lastLogoff: 0 +lastLogon: 0 +pwdLastSet: 0 +primaryGroupID: 513 +objectSid: S-1-5-21-43662522-77495566-38969261-500 +adminCount: 1 +accountExpires: 9223372036854775807 +logonCount: 0 +sAMAccountName: Administrator +sAMAccountType: 0x30000000 +objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=schema,DC=test +isCriticalSystemObject: TRUE +unicodePwd: samba +nTSecurityDescriptor: foo + +dn: CN=Test,CN=Users,DC=schema,DC=test +objectClass: top +objectClass: test +cn: Test +description: This is a test +objectCategory: CN=Test,CN=Schema,CN=Configuration,DC=schema,DC=test +nTSecurityDescriptor: foo +instanceType: 4 + diff --git a/ldb-2.0.8/tests/schema-tests/schema-mod-test-1.ldif b/ldb-2.0.8/tests/schema-tests/schema-mod-test-1.ldif new file mode 100644 index 0000000..b976724 --- /dev/null +++ b/ldb-2.0.8/tests/schema-tests/schema-mod-test-1.ldif @@ -0,0 +1,5 @@ +dn: CN=Test,CN=Users,DC=schema,DC=test +changetype: modify +replace: description +description: this test must not fail + diff --git a/ldb-2.0.8/tests/schema-tests/schema-mod-test-2.ldif b/ldb-2.0.8/tests/schema-tests/schema-mod-test-2.ldif new file mode 100644 index 0000000..fa193af --- /dev/null +++ b/ldb-2.0.8/tests/schema-tests/schema-mod-test-2.ldif @@ -0,0 +1,5 @@ +dn: CN=Test,CN=Users,DC=schema,DC=test +changetype: modify +delete: description +# this test must not fail + diff --git a/ldb-2.0.8/tests/schema-tests/schema-mod-test-3.ldif b/ldb-2.0.8/tests/schema-tests/schema-mod-test-3.ldif new file mode 100644 index 0000000..8ab7798 --- /dev/null +++ b/ldb-2.0.8/tests/schema-tests/schema-mod-test-3.ldif @@ -0,0 +1,5 @@ +dn: CN=Test,CN=Users,DC=schema,DC=test +changetype: modify +add: description +description: this test must not fail + diff --git a/ldb-2.0.8/tests/schema-tests/schema-mod-test-4.ldif b/ldb-2.0.8/tests/schema-tests/schema-mod-test-4.ldif new file mode 100644 index 0000000..cbf0e60 --- /dev/null +++ b/ldb-2.0.8/tests/schema-tests/schema-mod-test-4.ldif @@ -0,0 +1,5 @@ +dn: CN=Test,CN=Users,DC=schema,DC=test +changetype: modify +add: foo +foo: this test must fail + diff --git a/ldb-2.0.8/tests/schema-tests/schema-mod-test-5.ldif b/ldb-2.0.8/tests/schema-tests/schema-mod-test-5.ldif new file mode 100644 index 0000000..bc64e9e --- /dev/null +++ b/ldb-2.0.8/tests/schema-tests/schema-mod-test-5.ldif @@ -0,0 +1,5 @@ +dn: CN=Test,CN=Users,DC=schema,DC=test +changetype: modify +delete: nTSecurityDescriptor +# this test must fail + diff --git a/ldb-2.0.8/tests/schema-tests/schema.ldif b/ldb-2.0.8/tests/schema-tests/schema.ldif new file mode 100644 index 0000000..4ab1932 --- /dev/null +++ b/ldb-2.0.8/tests/schema-tests/schema.ldif @@ -0,0 +1,100 @@ +dn: @INDEXLIST +@IDXATTR: name +@IDXATTR: sAMAccountName +@IDXATTR: objectSid +@IDXATTR: objectClass +@IDXATTR: member +@IDXATTR: uidNumber +@IDXATTR: gidNumber +@IDXATTR: unixName +@IDXATTR: privilege +@IDXATTR: lDAPDisplayName + +dn: @ATTRIBUTES +realm: CASE_INSENSITIVE +userPrincipalName: CASE_INSENSITIVE +servicePrincipalName: CASE_INSENSITIVE +name: CASE_INSENSITIVE +dn: CASE_INSENSITIVE +sAMAccountName: CASE_INSENSITIVE +objectClass: CASE_INSENSITIVE +unicodePwd: HIDDEN +ntPwdHash: HIDDEN +ntPwdHistory: HIDDEN +lmPwdHash: HIDDEN +lmPwdHistory: HIDDEN +createTimestamp: HIDDEN +modifyTimestamp: HIDDEN + +dn: @MODULES +@LIST: timestamps,schema + +dn: CN=Top,CN=Schema,CN=Configuration,DC=schema,DC=test +objectClass: top +objectClass: classSchema +lDAPDisplayName: top +cn: Top +uSNCreated: 1 +uSNChanged: 1 +subClassOf: top +systemMustContain: objectClass +systemMayContain: structuralObjectClass +systemMayContain: createTimeStamp +systemMayContain: modifyTimeStamp +systemMayContain: creatorsName +systemMayContain: modifiersName +systemMayContain: hasSubordinates +systemMayContain: subschemaSubentry +systemMayContain: collectiveSubentry +systemMayContain: entryUUID +systemMayContain: entryCSN +systemMayContain: namingCSN +systemMayContain: superiorUUID +systemMayContain: contextCSN +systemMayContain: whenCreated +systemMayContain: whenChanged +systemMayContain: uSNCreated +systemMayContain: uSNChanged +systemMayContain: distinguishedName +systemMayContain: name +systemMayContain: cn +systemMayContain: userPassword +systemMayContain: labeledURI + +dn: CN=Class-Schema,CN=Schema,CN=Configuration,DC=schema,DC=test +objectClass: top +objectClass: classSchema +lDAPDisplayName: classSchema +cn: Class-Schema +uSNCreated: 2 +uSNChanged: 2 +lDAPDisplayName: classSchema +subClassOf: top +systemMustContain: cn +systemMustContain: subClassOf +systemMayContain: systemPossSuperiors +systemMayContain: systemOnly +systemMayContain: systemMustContain +systemMayContain: systemMayContain +systemMayContain: systemAuxiliaryClass +systemMayContain: possSuperiors +systemMayContain: mustContain +systemMayContain: mayContain +systemMayContain: lDAPDisplayName +systemMayContain: auxiliaryClass + +dn: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=schema,DC=test +objectClass: top +objectClass: classSchema +cn: Attribute-Schema +uSNCreated: 3 +uSNChanged: 3 +lDAPDisplayName: attributeSchema +subClassOf: top +systemMustContain: oMSyntax +systemMustContain: lDAPDisplayName +systemMustContain: isSingleValued +systemMustContain: cn +systemMustContain: attributeSyntax +systemMustContain: attributeID + diff --git a/ldb-2.0.8/tests/slapd.conf b/ldb-2.0.8/tests/slapd.conf new file mode 100644 index 0000000..fa2789d --- /dev/null +++ b/ldb-2.0.8/tests/slapd.conf @@ -0,0 +1,26 @@ +loglevel 0 + +include tests/schema/core.schema +include tests/schema/cosine.schema +include tests/schema/inetorgperson.schema +include tests/schema/openldap.schema +include tests/schema/nis.schema + + +pidfile tests/tmp/slapd.pid +argsfile tests/tmp/slapd.args + +access to * by * write + +allow update_anon bind_anon_dn + +include tests/tmp/modules.conf + +defaultsearchbase "o=University of Michigan,c=TEST" + +backend bdb +database bdb +suffix "o=University of Michigan,c=TEST" +directory tests/tmp/db +index objectClass eq +index uid eq diff --git a/ldb-2.0.8/tests/start_slapd.sh b/ldb-2.0.8/tests/start_slapd.sh new file mode 100755 index 0000000..11679d4 --- /dev/null +++ b/ldb-2.0.8/tests/start_slapd.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +if [ -z "$LDBDIR" ]; then + LDBDIR=`dirname $0`/.. + export LDBDIR +fi + +mkdir -p $LDBDIR/tests/tmp/db + +# running slapd in the background (with &) means it stays in the same process group, so it can be +# killed by timelimit +slapd -d0 -f $LDBDIR/tests/slapd.conf -h "`$LDBDIR/tests/ldapi_url.sh`" $* & + +sleep 2 diff --git a/ldb-2.0.8/tests/test-attribs.ldif b/ldb-2.0.8/tests/test-attribs.ldif new file mode 100644 index 0000000..79508c4 --- /dev/null +++ b/ldb-2.0.8/tests/test-attribs.ldif @@ -0,0 +1,6 @@ +dn: @ATTRIBUTES +uid: CASE_INSENSITIVE +cn: CASE_INSENSITIVE +ou: CASE_INSENSITIVE +dn: CASE_INSENSITIVE + diff --git a/ldb-2.0.8/tests/test-config.ldif b/ldb-2.0.8/tests/test-config.ldif new file mode 100644 index 0000000..7926a9e --- /dev/null +++ b/ldb-2.0.8/tests/test-config.ldif @@ -0,0 +1,67 @@ +############################## +# global configuration options +dn: cn=Global,cn=Config,cn=Samba +objectclass: globalconfig +LocalConfigCn: cn=%U,cn=Config,cn=Samba +LocalConfigCn;1: cn=%U,cn=Config,cn=Samba +LocalConfigCn;2: cn=%I,cn=Config,cn=Samba +LocalConfigCn;3: cn=%M,cn=Config,cn=Samba + +############# +dn: cn=Protocol,cn=Global,cn=Config,cn=Samba +maxXmit: 7000 + +################################ +dn: cn=Volker,cn=Config,cn=Samba +Workgroup: VNET3 +UnixCharset: UTF8 +Security: user +Interfaces: vmnet* eth* +NetbiosName: blu +GuestAccount: tridge + +################################# +dn: cn=Volker,cn=Config,cn=Samba +Workgroup: VNET3 +UnixCharset: UTF8 +Security: user +Interfaces: vmnet* eth* +NetbiosName: blu +GuestAccount: tridge +Include: cn=%U,cn=MyConfig,cn=Config,cn=Samba + +#### ((objectClass=fileshare)(cn=test)) +############################## +# [test] share +dn: cn=test,cn=Shares,cn=Config,cn=Samba +objectclass: fileshare +cn: test +Comment: a test share +Path: /home/tridge/samba4/prefix/test +ReadOnly: no + +##################################### +# [msdn] a remote proxy share, stored +# on \\msdn\test +dn: cn=msdn,cn=Shares,cn=Config,cn=Samba +objectclass: fileshare +cn: msdn +NtvfsHandler: cifs +ReadOnly: no +_CifsServer: msdn +_CifsUser: administrator +_CifsPassword: penguin +_CifsDomain: winxp +_CifsShare: test + + +############################## +# [VisualC] share +dn: cn=visualc,cn=Shares,cn=Config,cn=Samba +objectclass: fileshare +cn: VisualC +Comment: VisualC development +Path: /home/tridge/VisualC +ReadOnly: no +NtvfsHandler: simple + diff --git a/ldb-2.0.8/tests/test-controls.sh b/ldb-2.0.8/tests/test-controls.sh new file mode 100755 index 0000000..328ed29 --- /dev/null +++ b/ldb-2.0.8/tests/test-controls.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +if [ -n "$TEST_DATA_PREFIX" ]; then + LDB_URL="$TEST_DATA_PREFIX/tdbtest.ldb" +else + LDB_URL="tdbtest.ldb" +fi +export LDB_URL + +PATH=bin:$PATH +export PATH + +rm -f $LDB_URL* + +echo "LDB_URL: $LDB_URL" +cat </dev/null 2>&1 && exit 1 +dn: dc=foobar +dc: foobar +someThing: someThingElse +EOF + +cat </dev/null 2>&1 && exit 1 +dn: dc=bar +changetype: modify +replace someThing +someThing: someThingElseBetter +EOF + +$VALGRIND ldbsearch --controls "bypassoperational:0" >/dev/null 2>&1 || exit 1 diff --git a/ldb-2.0.8/tests/test-default-config.ldif b/ldb-2.0.8/tests/test-default-config.ldif new file mode 100644 index 0000000..87b7bcd --- /dev/null +++ b/ldb-2.0.8/tests/test-default-config.ldif @@ -0,0 +1,17 @@ +############################## +# global configuration options +dn: cn=Global,cn=DefaultConfig,cn=Samba +objectclass: globalconfig +Workgroup: WORKGROUP +UnixCharset: UTF8 +Security: user +NetbiosName: blu +GuestAccount: nobody + +############################## +# [_default_] share +dn: cn=_default_,cn=Shares,cn=DefaultConfig,cn=Samba +objectclass: fileshare +cn: _default_ +Path: /tmp +ReadOnly: yes diff --git a/ldb-2.0.8/tests/test-dup-2.ldif b/ldb-2.0.8/tests/test-dup-2.ldif new file mode 100644 index 0000000..a426101 --- /dev/null +++ b/ldb-2.0.8/tests/test-dup-2.ldif @@ -0,0 +1,6 @@ +dn: cn=Sentinel,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST +objectclass: OpenLDAPperson +cn: Sentinel +sn: USER +uid: USER, Sentinel + diff --git a/ldb-2.0.8/tests/test-dup.ldif b/ldb-2.0.8/tests/test-dup.ldif new file mode 100644 index 0000000..b35420b --- /dev/null +++ b/ldb-2.0.8/tests/test-dup.ldif @@ -0,0 +1,13 @@ +dn: cn=Fred Bassett,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST +objectclass: OpenLDAPperson +cn: Fred Bassett +sn: Bassett +uid: Bassett, Fred + +dn: cn=Sentinel,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST +objectclass: OpenLDAPperson +cn: Sentinel +sn: USER +uid: USER, Sentinel + + diff --git a/ldb-2.0.8/tests/test-extended.sh b/ldb-2.0.8/tests/test-extended.sh new file mode 100755 index 0000000..0599757 --- /dev/null +++ b/ldb-2.0.8/tests/test-extended.sh @@ -0,0 +1,69 @@ +#!/bin/sh + +echo "Running extended search tests" + +mv $LDB_URL $LDB_URL.1 + +cat < /dev/null && { + echo "Should have failed to add again - gave $?" + exit 1 +} + +echo "Adding LDIF with one already-existing user again - should fail" +$VALGRIND ldbadd $LDBDIR/tests/test-dup.ldif 2> /dev/null && { + echo "Should have failed to add again - gave $?" + exit 1 +} + +echo "Adding again - should succeed (as previous failed)" +$VALGRIND ldbadd $LDBDIR/tests/test-dup-2.ldif || exit 1 + +echo "Modifying elements" +$VALGRIND ldbmodify $LDBDIR/tests/test-modify.ldif || exit 1 + +echo "Modify LDIF with one un-met constraint - should fail" +$VALGRIND ldbadd $LDBDIR/tests/test-modify-unmet.ldif 2> /dev/null && { + echo "Should have failed to modify - gave $?" + exit 1 +} + +echo "Modify LDIF with after failure of un-met constraint - should also fail" +$VALGRIND ldbadd $LDBDIR/tests/test-modify-unmet-2.ldif 2> /dev/null && { + echo "Should have failed to modify - gave $?" + exit 1 +} + +echo "Showing modified record" +$VALGRIND ldbsearch '(uid=uham)' || exit 1 + +echo "Rename entry with ldbmodify - modrdn" +$VALGRIND ldbmodify $LDBDIR/tests/test-modify-modrdn.ldif || exit 1 + +echo "Rename entry with ldbrename" +OLDDN="cn=Ursula Hampster,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST" +NEWDN="cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST" +$VALGRIND ldbrename "$OLDDN" "$NEWDN" || exit 1 + +echo "Showing renamed record" +$VALGRIND ldbsearch '(uid=uham)' || exit 1 + +echo "Starting ldbtest" +$VALGRIND ldbtest --num-records 100 --num-searches 10 || exit 1 + +if [ $LDB_SPECIALS = 1 ]; then + echo "Adding index" + $VALGRIND ldbadd $LDBDIR/tests/test-index.ldif || exit 1 +fi + +echo "Adding bad attributes - should fail" +$VALGRIND ldbadd $LDBDIR/tests/test-wrong_attributes.ldif && { + echo "Should fhave failed - gave $?" + exit 1 +} + +echo "Testing indexed search" +$VALGRIND ldbsearch '(uid=uham)' || exit 1 +$VALGRIND ldbsearch '(&(objectclass=person)(objectclass=person)(objectclass=top))' || exit 1 +$VALGRIND ldbsearch '(&(uid=uham)(uid=uham))' || exit 1 +$VALGRIND ldbsearch '(|(uid=uham)(uid=uham))' || exit 1 +$VALGRIND ldbsearch '(|(uid=uham)(uid=uham)(objectclass=OpenLDAPperson))' || exit 1 +$VALGRIND ldbsearch '(&(uid=uham)(uid=uham)(!(objectclass=xxx)))' || exit 1 +$VALGRIND ldbsearch '(&(objectclass=person)(uid=uham)(!(uid=uhamxx)))' uid \* \+ dn || exit 1 +$VALGRIND ldbsearch '(&(uid=uham)(uid=uha*)(title=*))' uid || exit 1 + +echo "Testing invalid search expression" +$VALGRIND ldbsearch '(&(uid=uham)(title=foo\blah))' uid && exit 1 + +# note that the "((" is treated as an attribute not an expression +# this matches the openldap ldapsearch behaviour of looking for a '=' +# to see if the first argument is an expression or not +$VALGRIND ldbsearch '((' uid || exit 1 +$VALGRIND ldbsearch '(objectclass=)' uid || exit 1 +$VALGRIND ldbsearch -b 'cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST' -s base "" sn || exit 1 + +echo "Test wildcard match" +$VALGRIND ldbadd $LDBDIR/tests/test-wildcard.ldif || exit 1 +$VALGRIND ldbsearch '(cn=test*multi)' || exit 1 +$VALGRIND ldbsearch '(cn=*test*multi*)' || exit 1 +$VALGRIND ldbsearch '(cn=*test_multi)' || exit 1 +$VALGRIND ldbsearch '(cn=test_multi*)' || exit 1 +$VALGRIND ldbsearch '(cn=test*multi*test*multi)' || exit 1 +$VALGRIND ldbsearch '(cn=test*multi*test*multi*multi_*)' || exit 1 + +echo "Starting ldbtest indexed" +$VALGRIND ldbtest --num-records 100 --num-searches 500 || exit 1 + +echo "Testing one level search" +count=`$VALGRIND ldbsearch -b 'ou=Groups,o=University of Michigan,c=TEST' -s one 'objectclass=*' none |grep '^dn' | wc -l` +if [ $count != 3 ]; then + echo returned $count records - expected 3 + exit 1 +fi + +echo "Testing binary file attribute value" +$VALGRIND ldbmodify $LDBDIR/tests/photo.ldif || exit 1 +count=`$VALGRIND ldbsearch '(cn=Hampster Ursula)' jpegPhoto | grep '^dn' | wc -l` +if [ $count != 1 ]; then + echo returned $count records - expected 1 + exit 1 +fi + +echo "*TODO* Testing UTF8 upper lower case searches !!" + +echo "Testing compare" +count=`$VALGRIND ldbsearch '(cn>=t)' cn | grep '^dn' | wc -l` +if [ $count != 1 ]; then + # only "cn: test_multi_test_multi_test_multi" (comes after "t") + # upper-cased words come before "t" - hence excluded + echo returned $count records - expected 1 + exit 1 +fi +$VALGRIND ldbsearch '(cn>t)' cn && exit 1 # strictly greater should not work + +count=`$VALGRIND ldbsearch '(cn<=t)' cn | grep '^dn' | wc -l` +if [ $count != 18 ]; then + # everything except "cn: test_multi_test_multi_test_multi" (comes after "t") + # upper-cased letters come before "t" - hence included + echo returned $count records - expected 18 + exit 1 +fi +$VALGRIND ldbsearch '(cn + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include + +#include +#include "ldb_private.h" + +static void test_ldb_dn_add_child_fmt(void **state) +{ + struct ldb_context *ldb = ldb_init(NULL, NULL); + + struct ldb_dn *dn = ldb_dn_new(ldb, ldb, "dc=samba,dc=org"); + + assert_true(ldb_dn_add_child_fmt(dn, + "DC=X")); + + assert_string_equal("DC=X,dc=samba,dc=org", + ldb_dn_get_linearized(dn)); + + assert_string_equal("DC=X,DC=SAMBA,DC=ORG", + ldb_dn_get_casefold(dn)); + +} + +static void test_ldb_dn_add_child_fmt2(void **state) +{ + struct ldb_context *ldb = ldb_init(NULL, NULL); + + struct ldb_dn *dn = ldb_dn_new(ldb, ldb, "dc=samba,dc=org"); + + assert_true(ldb_dn_add_child_fmt(dn, + "DC=X,DC=Y")); + + assert_string_equal("DC=X,DC=Y,dc=samba,dc=org", + ldb_dn_get_linearized(dn)); + + assert_string_equal("DC=X,DC=Y,DC=SAMBA,DC=ORG", + ldb_dn_get_casefold(dn)); + + assert_int_equal(4, + ldb_dn_get_comp_num(dn)); + +} + +static void test_ldb_dn_add_child_val(void **state) +{ + struct ldb_context *ldb = ldb_init(NULL, NULL); + + struct ldb_dn *dn = ldb_dn_new(ldb, ldb, "dc=samba,dc=org"); + struct ldb_val name = {.data = discard_const("X"), + .length = 1 + }; + + assert_true(ldb_dn_add_child_val(dn, + "DC", name)); + + assert_string_equal("DC=X,dc=samba,dc=org", + ldb_dn_get_linearized(dn)); + + assert_string_equal("DC=X,DC=SAMBA,DC=ORG", + ldb_dn_get_casefold(dn)); + +} + +static void test_ldb_dn_add_child_val2(void **state) +{ + struct ldb_context *ldb = ldb_init(NULL, NULL); + + struct ldb_dn *dn = ldb_dn_new(ldb, ldb, "dc=samba,dc=org"); + + struct ldb_val name = {.data = discard_const("X,DC=Y"), + .length = 6 + }; + + assert_true(ldb_dn_add_child_val(dn, + "DC", name)); + + assert_string_equal("DC=X\\,DC\\3DY,dc=samba,dc=org", + ldb_dn_get_linearized(dn)); + + assert_string_equal("DC=X\\,DC\\3DY,DC=SAMBA,DC=ORG", + ldb_dn_get_casefold(dn)); + + assert_int_equal(3, + ldb_dn_get_comp_num(dn)); + +} + +struct explode_test { + const char *strdn; + int comp_num; + int ext_comp_num; + bool special; + bool invalid; + const char *linearized; + const char *ext_linearized_1; + bool explode_result; +}; + +static int extended_dn_read_ID(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + + /* Allow to check we can cope with validity checks */ + if (in->length != 4) { + return -1; + } + + *out = *in; + out->data = talloc_memdup(mem_ctx, in->data, in->length); + if (out->data == NULL) { + return -1; + } + + return 0; +} + +/* write out (resued for both HEX and clear for now) */ +static int extended_dn_write_ID(struct ldb_context *ldb, void *mem_ctx, + const struct ldb_val *in, struct ldb_val *out) +{ + *out = *in; + + out->data = talloc_memdup(mem_ctx, in->data, in->length); + if (out->data == NULL) { + return -1; + } + return 0; +} + + +static void test_ldb_dn_explode(void **state) +{ + size_t i; + struct ldb_context *ldb = ldb_init(NULL, NULL); + struct explode_test tests[] = { + {"A=B", 1, 0, false, false, "A=B", "A=B", true}, + {"", 0, 0, false, false, "", "", true}, + {" ", -1, -1, false, false, " ", " ", false}, + {"<>", 0, 0, false, false, "", NULL, true}, + {"<", 0, 0, false, false, "", NULL, true}, + {"<><", 0, 0, false, false, "", NULL, true}, + {"<><>", 0, 0, false, false, "", NULL, true}, + {"A=B,C=D", 2, 0, false, false, "A=B,C=D", "A=B,C=D", true}, + {"A=B,C=D", -1, -1, false, false, "", NULL, false}, + {";A=B,C=D", -1, -1, false, false, "A=B,C=D", NULL, false}, + {";A=B,C=D", -1, -1, false, true, "A=B,C=D", NULL, false}, + {";A=B,C=D", 2, 1, false, false, "A=B,C=D", ";A=B,C=D", true}, + {"x=🔥", 1, 0, false, false, "x=🔥", "x=🔥", true}, + {"@FOO", 0, 0, true, false, "@FOO", "@FOO", true}, + }; + + struct ldb_dn_extended_syntax syntax = { + .name = "ID", + .read_fn = extended_dn_read_ID, + .write_clear_fn = extended_dn_write_ID, + .write_hex_fn = extended_dn_write_ID + }; + + ldb_dn_extended_add_syntax(ldb, 0, &syntax); + + for (i = 0; i < ARRAY_SIZE(tests); i++) { + bool result; + const char *linear; + const char *ext_linear; + struct ldb_dn *dn = ldb_dn_new(ldb, ldb, tests[i].strdn); + + /* + * special, invalid, linear, and ext_linear are set before + * explode + */ + fprintf(stderr, "%zu «%s»: ", i, tests[i].strdn); + linear = ldb_dn_get_linearized(dn); + assert_true((linear == NULL) == (tests[i].linearized == NULL)); + assert_string_equal(linear, + tests[i].linearized); + + ext_linear = ldb_dn_get_extended_linearized(ldb, dn, 1); + assert_true((ext_linear == NULL) == + (tests[i].ext_linearized_1 == NULL)); + + if (tests[i].ext_linearized_1 != NULL) { + assert_string_equal(ext_linear, + tests[i].ext_linearized_1); + } + assert_true(ldb_dn_is_special(dn) == tests[i].special); + assert_true(ldb_dn_is_valid(dn) != tests[i].invalid); + + /* comp nums are set by explode */ + result = ldb_dn_validate(dn); + fprintf(stderr, "res %i lin «%s» ext «%s»\n", + result, linear, ext_linear); + + assert_true(result == tests[i].explode_result); + assert_int_equal(ldb_dn_get_comp_num(dn), + tests[i].comp_num); + assert_int_equal(ldb_dn_get_extended_comp_num(dn), + tests[i].ext_comp_num); + } +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_ldb_dn_add_child_fmt), + cmocka_unit_test(test_ldb_dn_add_child_fmt2), + cmocka_unit_test(test_ldb_dn_add_child_val), + cmocka_unit_test(test_ldb_dn_add_child_val2), + cmocka_unit_test(test_ldb_dn_explode), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/ldb-2.0.8/tests/test_ldb_qsort.c b/ldb-2.0.8/tests/test_ldb_qsort.c new file mode 100644 index 0000000..663cf0e --- /dev/null +++ b/ldb-2.0.8/tests/test_ldb_qsort.c @@ -0,0 +1,65 @@ +/* + * Unix SMB/CIFS implementation. + * + * Copyright (C) 2018 Andreas Schneider + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include + +#include + +static int cmp_integer(int *a, int *b, void *opaque) +{ + if (a == NULL || b == NULL) { + return 0; + } + + if (*a > *b) { + return 1; + } + + if (*a < *b) { + return -1; + } + + return 0; +} + +static void test_ldb_qsort(void **state) +{ + int a[6] = { 6, 3, 2, 7, 9, 4 }; + + ldb_qsort(a, 6, sizeof(int), NULL, (ldb_qsort_cmp_fn_t)cmp_integer); + + assert_int_equal(a[0], 2); + assert_int_equal(a[1], 3); + assert_int_equal(a[2], 4); + assert_int_equal(a[3], 6); + assert_int_equal(a[4], 7); + assert_int_equal(a[5], 9); +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_ldb_qsort), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/ldb-2.0.8/tests/testdata.txt b/ldb-2.0.8/tests/testdata.txt new file mode 100644 index 0000000..dadb9f0 --- /dev/null +++ b/ldb-2.0.8/tests/testdata.txt @@ -0,0 +1,8 @@ +foo=bar5 +(&(|(a=b)(c=d))(e=f)) +(&(|(a=b)(c=d)(g=h))(e=f)) +name=firstname lastname +(&(sid=S-1-2-3)(name = fred bloggs)) +(&(|(a=b)(c=d))(g=f)) +(&(sid=S-1-2-3)(!(name = fred bloggs))) +(&(!(|(a=b)(c=d))(g=f))) diff --git a/ldb-2.0.8/tests/testsearch.txt b/ldb-2.0.8/tests/testsearch.txt new file mode 100644 index 0000000..c573863 --- /dev/null +++ b/ldb-2.0.8/tests/testsearch.txt @@ -0,0 +1,5 @@ +(blah=foo) +(objectclass=person) +(dn=*) +(&(objectclass=person)(objectclass=person)) +(&(objectclass=person)(objectclass=personx)) diff --git a/ldb-2.0.8/third_party/cmocka/cmocka.c b/ldb-2.0.8/third_party/cmocka/cmocka.c new file mode 100644 index 0000000..b21fe15 --- /dev/null +++ b/ldb-2.0.8/third_party/cmocka/cmocka.c @@ -0,0 +1,3431 @@ +/* + * Copyright 2008 Google Inc. + * Copyright 2014-2018 Andreas Schneider + * Copyright 2015 Jakub Hrozek + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_MALLOC_H +#include +#endif + +#ifdef HAVE_INTTYPES_H +#include +#endif + +#ifdef HAVE_SIGNAL_H +#include +#endif + +#ifdef HAVE_STRINGS_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * This allows to add a platform specific header file. Some embedded platforms + * sometimes miss certain types and definitions. + * + * Example: + * + * typedef unsigned long int uintptr_t + * #define _UINTPTR_T 1 + * #define _UINTPTR_T_DEFINED 1 + */ +#ifdef CMOCKA_PLATFORM_INCLUDE +# include "cmocka_platform.h" +#endif /* CMOCKA_PLATFORM_INCLUDE */ + +#include +#include + +/* Size of guard bytes around dynamically allocated blocks. */ +#define MALLOC_GUARD_SIZE 16 +/* Pattern used to initialize guard blocks. */ +#define MALLOC_GUARD_PATTERN 0xEF +/* Pattern used to initialize memory allocated with test_malloc(). */ +#define MALLOC_ALLOC_PATTERN 0xBA +#define MALLOC_FREE_PATTERN 0xCD +/* Alignment of allocated blocks. NOTE: This must be base2. */ +#define MALLOC_ALIGNMENT sizeof(size_t) + +/* Printf formatting for source code locations. */ +#define SOURCE_LOCATION_FORMAT "%s:%u" + +#if defined(HAVE_GCC_THREAD_LOCAL_STORAGE) +# define CMOCKA_THREAD __thread +#elif defined(HAVE_MSVC_THREAD_LOCAL_STORAGE) +# define CMOCKA_THREAD __declspec(thread) +#else +# define CMOCKA_THREAD +#endif + +#ifdef HAVE_CLOCK_REALTIME +#define CMOCKA_CLOCK_GETTIME(clock_id, ts) clock_gettime((clock_id), (ts)) +#else +#define CMOCKA_CLOCK_GETTIME(clock_id, ts) +#endif + +#ifndef MAX +#define MAX(a,b) ((a) < (b) ? (b) : (a)) +#endif + +/** + * POSIX has sigsetjmp/siglongjmp, while Windows only has setjmp/longjmp. + */ +#ifdef HAVE_SIGLONGJMP +# define cm_jmp_buf sigjmp_buf +# define cm_setjmp(env) sigsetjmp(env, 1) +# define cm_longjmp(env, val) siglongjmp(env, val) +#else +# define cm_jmp_buf jmp_buf +# define cm_setjmp(env) setjmp(env) +# define cm_longjmp(env, val) longjmp(env, val) +#endif + + +/* + * Declare and initialize the pointer member of ValuePointer variable name + * with ptr. + */ +#define declare_initialize_value_pointer_pointer(name, ptr) \ + ValuePointer name ; \ + name.value = 0; \ + name.x.pointer = (void*)(ptr) + +/* + * Declare and initialize the value member of ValuePointer variable name + * with val. + */ +#define declare_initialize_value_pointer_value(name, val) \ + ValuePointer name ; \ + name.value = val + +/* Cast a LargestIntegralType to pointer_type via a ValuePointer. */ +#define cast_largest_integral_type_to_pointer( \ + pointer_type, largest_integral_type) \ + ((pointer_type)((ValuePointer*)&(largest_integral_type))->x.pointer) + +/* Used to cast LargetIntegralType to void* and vice versa. */ +typedef union ValuePointer { + LargestIntegralType value; + struct { +#if defined(WORDS_BIGENDIAN) && (WORDS_SIZEOF_VOID_P == 4) + unsigned int padding; +#endif + void *pointer; + } x; +} ValuePointer; + +/* Doubly linked list node. */ +typedef struct ListNode { + const void *value; + int refcount; + struct ListNode *next; + struct ListNode *prev; +} ListNode; + +/* Debug information for malloc(). */ +struct MallocBlockInfoData { + void* block; /* Address of the block returned by malloc(). */ + size_t allocated_size; /* Total size of the allocated block. */ + size_t size; /* Request block size. */ + SourceLocation location; /* Where the block was allocated. */ + ListNode node; /* Node within list of all allocated blocks. */ +}; + +typedef union { + struct MallocBlockInfoData *data; + char *ptr; +} MallocBlockInfo; + +/* State of each test. */ +typedef struct TestState { + const ListNode *check_point; /* Check point of the test if there's a */ + /* setup function. */ + void *state; /* State associated with the test. */ +} TestState; + +/* Determines whether two values are the same. */ +typedef int (*EqualityFunction)(const void *left, const void *right); + +/* Value of a symbol and the place it was declared. */ +typedef struct SymbolValue { + SourceLocation location; + LargestIntegralType value; +} SymbolValue; + +/* + * Contains a list of values for a symbol. + * NOTE: Each structure referenced by symbol_values_list_head must have a + * SourceLocation as its' first member. + */ +typedef struct SymbolMapValue { + const char *symbol_name; + ListNode symbol_values_list_head; +} SymbolMapValue; + +/* Where a particular ordering was located and its symbol name */ +typedef struct FuncOrderingValue { + SourceLocation location; + const char * function; +} FuncOrderingValue; + +/* Used by list_free() to deallocate values referenced by list nodes. */ +typedef void (*CleanupListValue)(const void *value, void *cleanup_value_data); + +/* Structure used to check the range of integer types.a */ +typedef struct CheckIntegerRange { + CheckParameterEvent event; + LargestIntegralType minimum; + LargestIntegralType maximum; +} CheckIntegerRange; + +/* Structure used to check whether an integer value is in a set. */ +typedef struct CheckIntegerSet { + CheckParameterEvent event; + const LargestIntegralType *set; + size_t size_of_set; +} CheckIntegerSet; + +/* Used to check whether a parameter matches the area of memory referenced by + * this structure. */ +typedef struct CheckMemoryData { + CheckParameterEvent event; + const void *memory; + size_t size; +} CheckMemoryData; + +static ListNode* list_initialize(ListNode * const node); +static ListNode* list_add(ListNode * const head, ListNode *new_node); +static ListNode* list_add_value(ListNode * const head, const void *value, + const int count); +static ListNode* list_remove( + ListNode * const node, const CleanupListValue cleanup_value, + void * const cleanup_value_data); +static void list_remove_free( + ListNode * const node, const CleanupListValue cleanup_value, + void * const cleanup_value_data); +static int list_empty(const ListNode * const head); +static int list_find( + ListNode * const head, const void *value, + const EqualityFunction equal_func, ListNode **output); +static int list_first(ListNode * const head, ListNode **output); +static ListNode* list_free( + ListNode * const head, const CleanupListValue cleanup_value, + void * const cleanup_value_data); + +static void add_symbol_value( + ListNode * const symbol_map_head, const char * const symbol_names[], + const size_t number_of_symbol_names, const void* value, const int count); +static int get_symbol_value( + ListNode * const symbol_map_head, const char * const symbol_names[], + const size_t number_of_symbol_names, void **output); +static void free_value(const void *value, void *cleanup_value_data); +static void free_symbol_map_value( + const void *value, void *cleanup_value_data); +static void remove_always_return_values(ListNode * const map_head, + const size_t number_of_symbol_names); + +static size_t check_for_leftover_values_list(const ListNode * head, + const char * const error_message); + +static size_t check_for_leftover_values( + const ListNode * const map_head, const char * const error_message, + const size_t number_of_symbol_names); + +static void remove_always_return_values_from_list(ListNode * const map_head); + +/* + * This must be called at the beginning of a test to initialize some data + * structures. + */ +static void initialize_testing(const char *test_name); + +/* This must be called at the end of a test to free() allocated structures. */ +static void teardown_testing(const char *test_name); + +static enum cm_message_output cm_get_output(void); + +static int cm_error_message_enabled = 1; +static CMOCKA_THREAD char *cm_error_message; + +void cm_print_error(const char * const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); + +/* + * Keeps track of the calling context returned by setenv() so that the fail() + * method can jump out of a test. + */ +static CMOCKA_THREAD cm_jmp_buf global_run_test_env; +static CMOCKA_THREAD int global_running_test = 0; + +/* Keeps track of the calling context returned by setenv() so that */ +/* mock_assert() can optionally jump back to expect_assert_failure(). */ +jmp_buf global_expect_assert_env; +int global_expecting_assert = 0; +const char *global_last_failed_assert = NULL; +static int global_skip_test; + +/* Keeps a map of the values that functions will have to return to provide */ +/* mocked interfaces. */ +static CMOCKA_THREAD ListNode global_function_result_map_head; +/* Location of the last mock value returned was declared. */ +static CMOCKA_THREAD SourceLocation global_last_mock_value_location; + +/* Keeps a map of the values that functions expect as parameters to their + * mocked interfaces. */ +static CMOCKA_THREAD ListNode global_function_parameter_map_head; +/* Location of last parameter value checked was declared. */ +static CMOCKA_THREAD SourceLocation global_last_parameter_location; + +/* List (acting as FIFO) of call ordering. */ +static CMOCKA_THREAD ListNode global_call_ordering_head; +/* Location of last call ordering that was declared. */ +static CMOCKA_THREAD SourceLocation global_last_call_ordering_location; + +/* List of all currently allocated blocks. */ +static CMOCKA_THREAD ListNode global_allocated_blocks; + +static enum cm_message_output global_msg_output = CM_OUTPUT_STDOUT; + +static const char *global_test_filter_pattern; + +#ifndef _WIN32 +/* Signals caught by exception_handler(). */ +static const int exception_signals[] = { + SIGFPE, + SIGILL, + SIGSEGV, +#ifdef SIGBUS + SIGBUS, +#endif +#ifdef SIGSYS + SIGSYS, +#endif +}; + +/* Default signal functions that should be restored after a test is complete. */ +typedef void (*SignalFunction)(int signal); +static SignalFunction default_signal_functions[ + ARRAY_SIZE(exception_signals)]; + +#else /* _WIN32 */ + +/* The default exception filter. */ +static LPTOP_LEVEL_EXCEPTION_FILTER previous_exception_filter; + +/* Fatal exceptions. */ +typedef struct ExceptionCodeInfo { + DWORD code; + const char* description; +} ExceptionCodeInfo; + +#define EXCEPTION_CODE_INFO(exception_code) {exception_code, #exception_code} + +static const ExceptionCodeInfo exception_codes[] = { + EXCEPTION_CODE_INFO(EXCEPTION_ACCESS_VIOLATION), + EXCEPTION_CODE_INFO(EXCEPTION_ARRAY_BOUNDS_EXCEEDED), + EXCEPTION_CODE_INFO(EXCEPTION_DATATYPE_MISALIGNMENT), + EXCEPTION_CODE_INFO(EXCEPTION_FLT_DENORMAL_OPERAND), + EXCEPTION_CODE_INFO(EXCEPTION_FLT_DIVIDE_BY_ZERO), + EXCEPTION_CODE_INFO(EXCEPTION_FLT_INEXACT_RESULT), + EXCEPTION_CODE_INFO(EXCEPTION_FLT_INVALID_OPERATION), + EXCEPTION_CODE_INFO(EXCEPTION_FLT_OVERFLOW), + EXCEPTION_CODE_INFO(EXCEPTION_FLT_STACK_CHECK), + EXCEPTION_CODE_INFO(EXCEPTION_FLT_UNDERFLOW), + EXCEPTION_CODE_INFO(EXCEPTION_GUARD_PAGE), + EXCEPTION_CODE_INFO(EXCEPTION_ILLEGAL_INSTRUCTION), + EXCEPTION_CODE_INFO(EXCEPTION_INT_DIVIDE_BY_ZERO), + EXCEPTION_CODE_INFO(EXCEPTION_INT_OVERFLOW), + EXCEPTION_CODE_INFO(EXCEPTION_INVALID_DISPOSITION), + EXCEPTION_CODE_INFO(EXCEPTION_INVALID_HANDLE), + EXCEPTION_CODE_INFO(EXCEPTION_IN_PAGE_ERROR), + EXCEPTION_CODE_INFO(EXCEPTION_NONCONTINUABLE_EXCEPTION), + EXCEPTION_CODE_INFO(EXCEPTION_PRIV_INSTRUCTION), + EXCEPTION_CODE_INFO(EXCEPTION_STACK_OVERFLOW), +}; +#endif /* !_WIN32 */ + +enum CMUnitTestStatus { + CM_TEST_NOT_STARTED, + CM_TEST_PASSED, + CM_TEST_FAILED, + CM_TEST_ERROR, + CM_TEST_SKIPPED, +}; + +struct CMUnitTestState { + const ListNode *check_point; /* Check point of the test if there's a setup function. */ + const struct CMUnitTest *test; /* Point to array element in the tests we get passed */ + void *state; /* State associated with the test */ + const char *error_message; /* The error messages by the test */ + enum CMUnitTestStatus status; /* PASSED, FAILED, ABORT ... */ + double runtime; /* Time calculations */ +}; + +/* Exit the currently executing test. */ +static void exit_test(const int quit_application) +{ + const char *env = getenv("CMOCKA_TEST_ABORT"); + int abort_test = 0; + + if (env != NULL && strlen(env) == 1) { + abort_test = (env[0] == '1'); + } + + if (global_skip_test == 0 && + abort_test == 1) { + print_error("%s", cm_error_message); + abort(); + } else if (global_running_test) { + cm_longjmp(global_run_test_env, 1); + } else if (quit_application) { + exit(-1); + } +} + +void _skip(const char * const file, const int line) +{ + cm_print_error(SOURCE_LOCATION_FORMAT ": Skipped!\n", file, line); + global_skip_test = 1; + exit_test(1); +} + +/* Initialize a SourceLocation structure. */ +static void initialize_source_location(SourceLocation * const location) { + assert_non_null(location); + location->file = NULL; + location->line = 0; +} + + +/* Determine whether a source location is currently set. */ +static int source_location_is_set(const SourceLocation * const location) { + assert_non_null(location); + return location->file && location->line; +} + + +/* Set a source location. */ +static void set_source_location( + SourceLocation * const location, const char * const file, + const int line) { + assert_non_null(location); + location->file = file; + location->line = line; +} + + +static int c_strreplace(char *src, + size_t src_len, + const char *pattern, + const char *repl, + int *str_replaced) +{ + char *p = NULL; + + p = strstr(src, pattern); + if (p == NULL) { + return -1; + } + + do { + size_t of = p - src; + size_t l = strlen(src); + size_t pl = strlen(pattern); + size_t rl = strlen(repl); + + /* overflow check */ + if (src_len <= l + MAX(pl, rl) + 1) { + return -1; + } + + if (rl != pl) { + memmove(src + of + rl, src + of + pl, l - of - pl + 1); + } + + memcpy(src + of, repl, rl); + + if (str_replaced != NULL) { + *str_replaced = 1; + } + p = strstr(src, pattern); + } while (p != NULL); + + return 0; +} + +static int c_strmatch(const char *str, const char *pattern) +{ + int ok; + + if (str == NULL || pattern == NULL) { + return 0; + } + + for (;;) { + /* Check if pattern is done */ + if (*pattern == '\0') { + /* If string is at the end, we're good */ + if (*str == '\0') { + return 1; + } + + return 0; + } + + if (*pattern == '*') { + /* Move on */ + pattern++; + + /* If we are at the end, everything is fine */ + if (*pattern == '\0') { + return 1; + } + + /* Try to match each position */ + for (; *str != '\0'; str++) { + ok = c_strmatch(str, pattern); + if (ok) { + return 1; + } + } + + /* No match */ + return 0; + } + + /* If we are at the end, leave */ + if (*str == '\0') { + return 0; + } + + /* Check if we have a single wildcard or matching char */ + if (*pattern != '?' && *str != *pattern) { + return 0; + } + + /* Move string and pattern */ + str++; + pattern++; + } + + return 0; +} + +/* Create function results and expected parameter lists. */ +void initialize_testing(const char *test_name) { + (void)test_name; + list_initialize(&global_function_result_map_head); + initialize_source_location(&global_last_mock_value_location); + list_initialize(&global_function_parameter_map_head); + initialize_source_location(&global_last_parameter_location); + list_initialize(&global_call_ordering_head); + initialize_source_location(&global_last_parameter_location); +} + + +static void fail_if_leftover_values(const char *test_name) { + int error_occurred = 0; + (void)test_name; + remove_always_return_values(&global_function_result_map_head, 1); + if (check_for_leftover_values( + &global_function_result_map_head, + "%s() has remaining non-returned values.\n", 1)) { + error_occurred = 1; + } + + remove_always_return_values(&global_function_parameter_map_head, 2); + if (check_for_leftover_values( + &global_function_parameter_map_head, + "'%s' parameter still has values that haven't been checked.\n", + 2)) { + error_occurred = 1; + } + + remove_always_return_values_from_list(&global_call_ordering_head); + if (check_for_leftover_values_list(&global_call_ordering_head, + "%s function was expected to be called but was not not.\n")) { + error_occurred = 1; + } + if (error_occurred) { + exit_test(1); + } +} + + +static void teardown_testing(const char *test_name) { + (void)test_name; + list_free(&global_function_result_map_head, free_symbol_map_value, + (void*)0); + initialize_source_location(&global_last_mock_value_location); + list_free(&global_function_parameter_map_head, free_symbol_map_value, + (void*)1); + initialize_source_location(&global_last_parameter_location); + list_free(&global_call_ordering_head, free_value, + (void*)0); + initialize_source_location(&global_last_call_ordering_location); +} + +/* Initialize a list node. */ +static ListNode* list_initialize(ListNode * const node) { + node->value = NULL; + node->next = node; + node->prev = node; + node->refcount = 1; + return node; +} + + +/* + * Adds a value at the tail of a given list. + * The node referencing the value is allocated from the heap. + */ +static ListNode* list_add_value(ListNode * const head, const void *value, + const int refcount) { + ListNode * const new_node = (ListNode*)malloc(sizeof(ListNode)); + assert_non_null(head); + assert_non_null(value); + new_node->value = value; + new_node->refcount = refcount; + return list_add(head, new_node); +} + + +/* Add new_node to the end of the list. */ +static ListNode* list_add(ListNode * const head, ListNode *new_node) { + assert_non_null(head); + assert_non_null(new_node); + new_node->next = head; + new_node->prev = head->prev; + head->prev->next = new_node; + head->prev = new_node; + return new_node; +} + + +/* Remove a node from a list. */ +static ListNode* list_remove( + ListNode * const node, const CleanupListValue cleanup_value, + void * const cleanup_value_data) { + assert_non_null(node); + node->prev->next = node->next; + node->next->prev = node->prev; + if (cleanup_value) { + cleanup_value(node->value, cleanup_value_data); + } + return node; +} + + +/* Remove a list node from a list and free the node. */ +static void list_remove_free( + ListNode * const node, const CleanupListValue cleanup_value, + void * const cleanup_value_data) { + assert_non_null(node); + free(list_remove(node, cleanup_value, cleanup_value_data)); +} + + +/* + * Frees memory kept by a linked list The cleanup_value function is called for + * every "value" field of nodes in the list, except for the head. In addition + * to each list value, cleanup_value_data is passed to each call to + * cleanup_value. The head of the list is not deallocated. + */ +static ListNode* list_free( + ListNode * const head, const CleanupListValue cleanup_value, + void * const cleanup_value_data) { + assert_non_null(head); + while (!list_empty(head)) { + list_remove_free(head->next, cleanup_value, cleanup_value_data); + } + return head; +} + + +/* Determine whether a list is empty. */ +static int list_empty(const ListNode * const head) { + assert_non_null(head); + return head->next == head; +} + + +/* + * Find a value in the list using the equal_func to compare each node with the + * value. + */ +static int list_find(ListNode * const head, const void *value, + const EqualityFunction equal_func, ListNode **output) { + ListNode *current; + assert_non_null(head); + for (current = head->next; current != head; current = current->next) { + if (equal_func(current->value, value)) { + *output = current; + return 1; + } + } + return 0; +} + +/* Returns the first node of a list */ +static int list_first(ListNode * const head, ListNode **output) { + ListNode *target_node = NULL; + assert_non_null(head); + if (list_empty(head)) { + return 0; + } + target_node = head->next; + *output = target_node; + return 1; +} + + +/* Deallocate a value referenced by a list. */ +static void free_value(const void *value, void *cleanup_value_data) { + (void)cleanup_value_data; + assert_non_null(value); + free((void*)value); +} + + +/* Releases memory associated to a symbol_map_value. */ +static void free_symbol_map_value(const void *value, + void *cleanup_value_data) { + SymbolMapValue * const map_value = (SymbolMapValue*)value; + const LargestIntegralType children = cast_ptr_to_largest_integral_type(cleanup_value_data); + assert_non_null(value); + list_free(&map_value->symbol_values_list_head, + children ? free_symbol_map_value : free_value, + (void *) ((uintptr_t)children - 1)); + free(map_value); +} + + +/* + * Determine whether a symbol name referenced by a symbol_map_value matches the + * specified function name. + */ +static int symbol_names_match(const void *map_value, const void *symbol) { + return !strcmp(((SymbolMapValue*)map_value)->symbol_name, + (const char*)symbol); +} + +/* + * Adds a value to the queue of values associated with the given hierarchy of + * symbols. It's assumed value is allocated from the heap. + */ +static void add_symbol_value(ListNode * const symbol_map_head, + const char * const symbol_names[], + const size_t number_of_symbol_names, + const void* value, const int refcount) { + const char* symbol_name; + ListNode *target_node; + SymbolMapValue *target_map_value; + assert_non_null(symbol_map_head); + assert_non_null(symbol_names); + assert_true(number_of_symbol_names); + symbol_name = symbol_names[0]; + + if (!list_find(symbol_map_head, symbol_name, symbol_names_match, + &target_node)) { + SymbolMapValue * const new_symbol_map_value = + (SymbolMapValue*)malloc(sizeof(*new_symbol_map_value)); + new_symbol_map_value->symbol_name = symbol_name; + list_initialize(&new_symbol_map_value->symbol_values_list_head); + target_node = list_add_value(symbol_map_head, new_symbol_map_value, + 1); + } + + target_map_value = (SymbolMapValue*)target_node->value; + if (number_of_symbol_names == 1) { + list_add_value(&target_map_value->symbol_values_list_head, + value, refcount); + } else { + add_symbol_value(&target_map_value->symbol_values_list_head, + &symbol_names[1], number_of_symbol_names - 1, value, + refcount); + } +} + + +/* + * Gets the next value associated with the given hierarchy of symbols. + * The value is returned as an output parameter with the function returning the + * node's old refcount value if a value is found, 0 otherwise. This means that + * a return value of 1 indicates the node was just removed from the list. + */ +static int get_symbol_value( + ListNode * const head, const char * const symbol_names[], + const size_t number_of_symbol_names, void **output) { + const char* symbol_name = NULL; + ListNode *target_node = NULL; + assert_non_null(head); + assert_non_null(symbol_names); + assert_true(number_of_symbol_names); + assert_non_null(output); + symbol_name = symbol_names[0]; + + if (list_find(head, symbol_name, symbol_names_match, &target_node)) { + SymbolMapValue *map_value = NULL; + ListNode *child_list = NULL; + int return_value = 0; + assert_non_null(target_node); + assert_non_null(target_node->value); + + map_value = (SymbolMapValue*)target_node->value; + child_list = &map_value->symbol_values_list_head; + + if (number_of_symbol_names == 1) { + ListNode *value_node = NULL; + return_value = list_first(child_list, &value_node); + assert_true(return_value); + /* Add a check to silence clang analyzer */ + if (return_value == 0) { + goto out; + } + *output = (void*) value_node->value; + return_value = value_node->refcount; + if (value_node->refcount - 1 == 0) { + list_remove_free(value_node, NULL, NULL); + } else if (value_node->refcount > WILL_RETURN_ONCE) { + --value_node->refcount; + } + } else { + return_value = get_symbol_value( + child_list, &symbol_names[1], number_of_symbol_names - 1, + output); + } + if (list_empty(child_list)) { + list_remove_free(target_node, free_symbol_map_value, (void*)0); + } + return return_value; + } +out: + cm_print_error("No entries for symbol %s.\n", symbol_name); + return 0; +} + +/** + * Taverse a list of nodes and remove first symbol value in list that has a + * refcount < -1 (i.e. should always be returned and has been returned at + * least once). + */ + +static void remove_always_return_values_from_list(ListNode * const map_head) +{ + ListNode * current = NULL; + ListNode * next = NULL; + assert_non_null(map_head); + + for (current = map_head->next, next = current->next; + current != map_head; + current = next, next = current->next) { + if (current->refcount < -1) { + list_remove_free(current, free_value, NULL); + } + } +} + +/* + * Traverse down a tree of symbol values and remove the first symbol value + * in each branch that has a refcount < -1 (i.e should always be returned + * and has been returned at least once). + */ +static void remove_always_return_values(ListNode * const map_head, + const size_t number_of_symbol_names) { + ListNode *current; + assert_non_null(map_head); + assert_true(number_of_symbol_names); + current = map_head->next; + while (current != map_head) { + SymbolMapValue * const value = (SymbolMapValue*)current->value; + ListNode * const next = current->next; + ListNode *child_list; + assert_non_null(value); + child_list = &value->symbol_values_list_head; + + if (!list_empty(child_list)) { + if (number_of_symbol_names == 1) { + ListNode * const child_node = child_list->next; + /* If this item has been returned more than once, free it. */ + if (child_node->refcount < -1) { + list_remove_free(child_node, free_value, NULL); + } + } else { + remove_always_return_values(child_list, + number_of_symbol_names - 1); + } + } + + if (list_empty(child_list)) { + list_remove_free(current, free_value, NULL); + } + current = next; + } +} + +static size_t check_for_leftover_values_list(const ListNode * head, + const char * const error_message) +{ + ListNode *child_node; + size_t leftover_count = 0; + if (!list_empty(head)) + { + for (child_node = head->next; child_node != head; + child_node = child_node->next, ++leftover_count) { + const FuncOrderingValue *const o = + (const FuncOrderingValue*) child_node->value; + cm_print_error(error_message, o->function); + cm_print_error(SOURCE_LOCATION_FORMAT + ": note: remaining item was declared here\n", + o->location.file, o->location.line); + } + } + return leftover_count; +} + +/* + * Checks if there are any leftover values set up by the test that were never + * retrieved through execution, and fail the test if that is the case. + */ +static size_t check_for_leftover_values( + const ListNode * const map_head, const char * const error_message, + const size_t number_of_symbol_names) { + const ListNode *current; + size_t symbols_with_leftover_values = 0; + assert_non_null(map_head); + assert_true(number_of_symbol_names); + + for (current = map_head->next; current != map_head; + current = current->next) { + const SymbolMapValue * const value = + (SymbolMapValue*)current->value; + const ListNode *child_list; + assert_non_null(value); + child_list = &value->symbol_values_list_head; + + if (!list_empty(child_list)) { + if (number_of_symbol_names == 1) { + const ListNode *child_node; + cm_print_error(error_message, value->symbol_name); + + for (child_node = child_list->next; child_node != child_list; + child_node = child_node->next) { + const SourceLocation * const location = + (const SourceLocation*)child_node->value; + cm_print_error(SOURCE_LOCATION_FORMAT + ": note: remaining item was declared here\n", + location->file, location->line); + } + } else { + cm_print_error("%s: ", value->symbol_name); + check_for_leftover_values(child_list, error_message, + number_of_symbol_names - 1); + } + symbols_with_leftover_values ++; + } + } + return symbols_with_leftover_values; +} + + +/* Get the next return value for the specified mock function. */ +LargestIntegralType _mock(const char * const function, const char* const file, + const int line) { + void *result; + const int rc = get_symbol_value(&global_function_result_map_head, + &function, 1, &result); + if (rc) { + SymbolValue * const symbol = (SymbolValue*)result; + const LargestIntegralType value = symbol->value; + global_last_mock_value_location = symbol->location; + if (rc == 1) { + free(symbol); + } + return value; + } else { + cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value " + "to mock function %s\n", file, line, function); + if (source_location_is_set(&global_last_mock_value_location)) { + cm_print_error(SOURCE_LOCATION_FORMAT + ": note: Previously returned mock value was declared here\n", + global_last_mock_value_location.file, + global_last_mock_value_location.line); + } else { + cm_print_error("There were no previously returned mock values for " + "this test.\n"); + } + exit_test(1); + } + return 0; +} + +/* Ensure that function is being called in proper order */ +void _function_called(const char *const function, + const char *const file, + const int line) +{ + ListNode *first_value_node = NULL; + ListNode *value_node = NULL; + int rc; + + rc = list_first(&global_call_ordering_head, &value_node); + first_value_node = value_node; + if (rc) { + FuncOrderingValue *expected_call; + int cmp; + + expected_call = (FuncOrderingValue *)value_node->value; + + cmp = strcmp(expected_call->function, function); + if (value_node->refcount < -1) { + /* + * Search through value nodes until either function is found or + * encounter a non-zero refcount greater than -2 + */ + if (cmp != 0) { + value_node = value_node->next; + expected_call = (FuncOrderingValue *)value_node->value; + + cmp = strcmp(expected_call->function, function); + while (value_node->refcount < -1 && + cmp != 0 && + value_node != first_value_node->prev) { + value_node = value_node->next; + if (value_node == NULL) { + break; + } + expected_call = (FuncOrderingValue *)value_node->value; + if (expected_call == NULL) { + continue; + } + cmp = strcmp(expected_call->function, function); + } + + if (expected_call == NULL || value_node == first_value_node->prev) { + cm_print_error(SOURCE_LOCATION_FORMAT + ": error: No expected mock calls matching " + "called() invocation in %s", + file, line, + function); + exit_test(1); + } + } + } + + if (cmp == 0) { + if (value_node->refcount > -2 && --value_node->refcount == 0) { + list_remove_free(value_node, free_value, NULL); + } + } else { + cm_print_error(SOURCE_LOCATION_FORMAT + ": error: Expected call to %s but received called() " + "in %s\n", + file, line, + expected_call->function, + function); + exit_test(1); + } + } else { + cm_print_error(SOURCE_LOCATION_FORMAT + ": error: No mock calls expected but called() was " + "invoked in %s\n", + file, line, + function); + exit_test(1); + } +} + +/* Add a return value for the specified mock function name. */ +void _will_return(const char * const function_name, const char * const file, + const int line, const LargestIntegralType value, + const int count) { + SymbolValue * const return_value = + (SymbolValue*)malloc(sizeof(*return_value)); + assert_true(count != 0); + return_value->value = value; + set_source_location(&return_value->location, file, line); + add_symbol_value(&global_function_result_map_head, &function_name, 1, + return_value, count); +} + + +/* + * Add a custom parameter checking function. If the event parameter is NULL + * the event structure is allocated internally by this function. If event + * parameter is provided it must be allocated on the heap and doesn't need to + * be deallocated by the caller. + */ +void _expect_check( + const char* const function, const char* const parameter, + const char* const file, const int line, + const CheckParameterValue check_function, + const LargestIntegralType check_data, + CheckParameterEvent * const event, const int count) { + CheckParameterEvent * const check = + event ? event : (CheckParameterEvent*)malloc(sizeof(*check)); + const char* symbols[] = {function, parameter}; + check->parameter_name = parameter; + check->check_value = check_function; + check->check_value_data = check_data; + set_source_location(&check->location, file, line); + add_symbol_value(&global_function_parameter_map_head, symbols, 2, check, + count); +} + +/* + * Add an call expectations that a particular function is called correctly. + * This is used for code under test that makes calls to several functions + * in depended upon components (mocks). + */ + +void _expect_function_call( + const char * const function_name, + const char * const file, + const int line, + const int count) +{ + FuncOrderingValue *ordering; + + assert_non_null(function_name); + assert_non_null(file); + assert_true(count != 0); + + ordering = (FuncOrderingValue *)malloc(sizeof(*ordering)); + + set_source_location(&ordering->location, file, line); + ordering->function = function_name; + + list_add_value(&global_call_ordering_head, ordering, count); +} + +/* Returns 1 if the specified values are equal. If the values are not equal + * an error is displayed and 0 is returned. */ +static int values_equal_display_error(const LargestIntegralType left, + const LargestIntegralType right) { + const int equal = left == right; + if (!equal) { + cm_print_error(LargestIntegralTypePrintfFormat " != " + LargestIntegralTypePrintfFormat "\n", left, right); + } + return equal; +} + +/* + * Returns 1 if the specified values are not equal. If the values are equal + * an error is displayed and 0 is returned. */ +static int values_not_equal_display_error(const LargestIntegralType left, + const LargestIntegralType right) { + const int not_equal = left != right; + if (!not_equal) { + cm_print_error(LargestIntegralTypePrintfFormat " == " + LargestIntegralTypePrintfFormat "\n", left, right); + } + return not_equal; +} + + +/* + * Determine whether value is contained within check_integer_set. + * If invert is 0 and the value is in the set 1 is returned, otherwise 0 is + * returned and an error is displayed. If invert is 1 and the value is not + * in the set 1 is returned, otherwise 0 is returned and an error is + * displayed. + */ +static int value_in_set_display_error( + const LargestIntegralType value, + const CheckIntegerSet * const check_integer_set, const int invert) { + int succeeded = invert; + assert_non_null(check_integer_set); + { + const LargestIntegralType * const set = check_integer_set->set; + const size_t size_of_set = check_integer_set->size_of_set; + size_t i; + for (i = 0; i < size_of_set; i++) { + if (set[i] == value) { + /* If invert = 0 and item is found, succeeded = 1. */ + /* If invert = 1 and item is found, succeeded = 0. */ + succeeded = !succeeded; + break; + } + } + if (succeeded) { + return 1; + } + cm_print_error(LargestIntegralTypePrintfFormatDecimal + " is %sin the set (", + value, invert ? "" : "not "); + for (i = 0; i < size_of_set; i++) { + cm_print_error(LargestIntegralTypePrintfFormat ", ", set[i]); + } + cm_print_error(")\n"); + } + return 0; +} + + +/* + * Determine whether a value is within the specified range. If the value is + * within the specified range 1 is returned. If the value isn't within the + * specified range an error is displayed and 0 is returned. + */ +static int integer_in_range_display_error( + const LargestIntegralType value, const LargestIntegralType range_min, + const LargestIntegralType range_max) { + if (value >= range_min && value <= range_max) { + return 1; + } + cm_print_error(LargestIntegralTypePrintfFormatDecimal + " is not within the range " + LargestIntegralTypePrintfFormatDecimal "-" + LargestIntegralTypePrintfFormatDecimal "\n", + value, range_min, range_max); + return 0; +} + + +/* + * Determine whether a value is within the specified range. If the value + * is not within the range 1 is returned. If the value is within the + * specified range an error is displayed and zero is returned. + */ +static int integer_not_in_range_display_error( + const LargestIntegralType value, const LargestIntegralType range_min, + const LargestIntegralType range_max) { + if (value < range_min || value > range_max) { + return 1; + } + cm_print_error(LargestIntegralTypePrintfFormatDecimal + " is within the range " + LargestIntegralTypePrintfFormatDecimal "-" + LargestIntegralTypePrintfFormatDecimal "\n", + value, range_min, range_max); + return 0; +} + + +/* + * Determine whether the specified strings are equal. If the strings are equal + * 1 is returned. If they're not equal an error is displayed and 0 is + * returned. + */ +static int string_equal_display_error( + const char * const left, const char * const right) { + if (strcmp(left, right) == 0) { + return 1; + } + cm_print_error("\"%s\" != \"%s\"\n", left, right); + return 0; +} + + +/* + * Determine whether the specified strings are equal. If the strings are not + * equal 1 is returned. If they're not equal an error is displayed and 0 is + * returned + */ +static int string_not_equal_display_error( + const char * const left, const char * const right) { + if (strcmp(left, right) != 0) { + return 1; + } + cm_print_error("\"%s\" == \"%s\"\n", left, right); + return 0; +} + + +/* + * Determine whether the specified areas of memory are equal. If they're equal + * 1 is returned otherwise an error is displayed and 0 is returned. + */ +static int memory_equal_display_error(const char* const a, const char* const b, + const size_t size) { + size_t differences = 0; + size_t i; + for (i = 0; i < size; i++) { + const char l = a[i]; + const char r = b[i]; + if (l != r) { + if (differences < 16) { + cm_print_error("difference at offset %" PRIdS " 0x%02x 0x%02x\n", + i, l, r); + } + differences ++; + } + } + if (differences > 0) { + if (differences >= 16) { + cm_print_error("...\n"); + } + cm_print_error("%"PRIdS " bytes of %p and %p differ\n", + differences, (void *)a, (void *)b); + return 0; + } + return 1; +} + + +/* + * Determine whether the specified areas of memory are not equal. If they're + * not equal 1 is returned otherwise an error is displayed and 0 is + * returned. + */ +static int memory_not_equal_display_error( + const char* const a, const char* const b, const size_t size) { + size_t same = 0; + size_t i; + for (i = 0; i < size; i++) { + const char l = a[i]; + const char r = b[i]; + if (l == r) { + same ++; + } + } + if (same == size) { + cm_print_error("%"PRIdS "bytes of %p and %p the same\n", + same, (void *)a, (void *)b); + return 0; + } + return 1; +} + + +/* CheckParameterValue callback to check whether a value is within a set. */ +static int check_in_set(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + return value_in_set_display_error(value, + cast_largest_integral_type_to_pointer(CheckIntegerSet*, + check_value_data), 0); +} + + +/* CheckParameterValue callback to check whether a value isn't within a set. */ +static int check_not_in_set(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + return value_in_set_display_error(value, + cast_largest_integral_type_to_pointer(CheckIntegerSet*, + check_value_data), 1); +} + + +/* Create the callback data for check_in_set() or check_not_in_set() and + * register a check event. */ +static void expect_set( + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType values[], const size_t number_of_values, + const CheckParameterValue check_function, const int count) { + CheckIntegerSet * const check_integer_set = + (CheckIntegerSet*)malloc(sizeof(*check_integer_set) + + (sizeof(values[0]) * number_of_values)); + LargestIntegralType * const set = (LargestIntegralType*)( + check_integer_set + 1); + declare_initialize_value_pointer_pointer(check_data, check_integer_set); + assert_non_null(values); + assert_true(number_of_values); + memcpy(set, values, number_of_values * sizeof(values[0])); + check_integer_set->set = set; + check_integer_set->size_of_set = number_of_values; + _expect_check( + function, parameter, file, line, check_function, + check_data.value, &check_integer_set->event, count); +} + + +/* Add an event to check whether a value is in a set. */ +void _expect_in_set( + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType values[], const size_t number_of_values, + const int count) { + expect_set(function, parameter, file, line, values, number_of_values, + check_in_set, count); +} + + +/* Add an event to check whether a value isn't in a set. */ +void _expect_not_in_set( + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType values[], const size_t number_of_values, + const int count) { + expect_set(function, parameter, file, line, values, number_of_values, + check_not_in_set, count); +} + + +/* CheckParameterValue callback to check whether a value is within a range. */ +static int check_in_range(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + CheckIntegerRange * const check_integer_range = + cast_largest_integral_type_to_pointer(CheckIntegerRange*, + check_value_data); + assert_non_null(check_integer_range); + return integer_in_range_display_error(value, check_integer_range->minimum, + check_integer_range->maximum); +} + + +/* CheckParameterValue callback to check whether a value is not within a range. */ +static int check_not_in_range(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + CheckIntegerRange * const check_integer_range = + cast_largest_integral_type_to_pointer(CheckIntegerRange*, + check_value_data); + assert_non_null(check_integer_range); + return integer_not_in_range_display_error( + value, check_integer_range->minimum, check_integer_range->maximum); +} + + +/* Create the callback data for check_in_range() or check_not_in_range() and + * register a check event. */ +static void expect_range( + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType minimum, const LargestIntegralType maximum, + const CheckParameterValue check_function, const int count) { + CheckIntegerRange * const check_integer_range = + (CheckIntegerRange*)malloc(sizeof(*check_integer_range)); + declare_initialize_value_pointer_pointer(check_data, check_integer_range); + check_integer_range->minimum = minimum; + check_integer_range->maximum = maximum; + _expect_check(function, parameter, file, line, check_function, + check_data.value, &check_integer_range->event, count); +} + + +/* Add an event to determine whether a parameter is within a range. */ +void _expect_in_range( + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType minimum, const LargestIntegralType maximum, + const int count) { + expect_range(function, parameter, file, line, minimum, maximum, + check_in_range, count); +} + + +/* Add an event to determine whether a parameter is not within a range. */ +void _expect_not_in_range( + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType minimum, const LargestIntegralType maximum, + const int count) { + expect_range(function, parameter, file, line, minimum, maximum, + check_not_in_range, count); +} + + +/* CheckParameterValue callback to check whether a value is equal to an + * expected value. */ +static int check_value(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + return values_equal_display_error(value, check_value_data); +} + + +/* Add an event to check a parameter equals an expected value. */ +void _expect_value( + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType value, const int count) { + _expect_check(function, parameter, file, line, check_value, value, NULL, + count); +} + + +/* CheckParameterValue callback to check whether a value is not equal to an + * expected value. */ +static int check_not_value(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + return values_not_equal_display_error(value, check_value_data); +} + + +/* Add an event to check a parameter is not equal to an expected value. */ +void _expect_not_value( + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType value, const int count) { + _expect_check(function, parameter, file, line, check_not_value, value, + NULL, count); +} + + +/* CheckParameterValue callback to check whether a parameter equals a string. */ +static int check_string(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + return string_equal_display_error( + cast_largest_integral_type_to_pointer(char*, value), + cast_largest_integral_type_to_pointer(char*, check_value_data)); +} + + +/* Add an event to check whether a parameter is equal to a string. */ +void _expect_string( + const char* const function, const char* const parameter, + const char* const file, const int line, const char* string, + const int count) { + declare_initialize_value_pointer_pointer(string_pointer, + discard_const(string)); + _expect_check(function, parameter, file, line, check_string, + string_pointer.value, NULL, count); +} + + +/* CheckParameterValue callback to check whether a parameter is not equals to + * a string. */ +static int check_not_string(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + return string_not_equal_display_error( + cast_largest_integral_type_to_pointer(char*, value), + cast_largest_integral_type_to_pointer(char*, check_value_data)); +} + + +/* Add an event to check whether a parameter is not equal to a string. */ +void _expect_not_string( + const char* const function, const char* const parameter, + const char* const file, const int line, const char* string, + const int count) { + declare_initialize_value_pointer_pointer(string_pointer, + discard_const(string)); + _expect_check(function, parameter, file, line, check_not_string, + string_pointer.value, NULL, count); +} + +/* CheckParameterValue callback to check whether a parameter equals an area of + * memory. */ +static int check_memory(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + CheckMemoryData * const check = cast_largest_integral_type_to_pointer( + CheckMemoryData*, check_value_data); + assert_non_null(check); + return memory_equal_display_error( + cast_largest_integral_type_to_pointer(const char*, value), + (const char*)check->memory, check->size); +} + + +/* Create the callback data for check_memory() or check_not_memory() and + * register a check event. */ +static void expect_memory_setup( + const char* const function, const char* const parameter, + const char* const file, const int line, + const void * const memory, const size_t size, + const CheckParameterValue check_function, const int count) { + CheckMemoryData * const check_data = + (CheckMemoryData*)malloc(sizeof(*check_data) + size); + void * const mem = (void*)(check_data + 1); + declare_initialize_value_pointer_pointer(check_data_pointer, check_data); + assert_non_null(memory); + assert_true(size); + memcpy(mem, memory, size); + check_data->memory = mem; + check_data->size = size; + _expect_check(function, parameter, file, line, check_function, + check_data_pointer.value, &check_data->event, count); +} + + +/* Add an event to check whether a parameter matches an area of memory. */ +void _expect_memory( + const char* const function, const char* const parameter, + const char* const file, const int line, const void* const memory, + const size_t size, const int count) { + expect_memory_setup(function, parameter, file, line, memory, size, + check_memory, count); +} + + +/* CheckParameterValue callback to check whether a parameter is not equal to + * an area of memory. */ +static int check_not_memory(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + CheckMemoryData * const check = cast_largest_integral_type_to_pointer( + CheckMemoryData*, check_value_data); + assert_non_null(check); + return memory_not_equal_display_error( + cast_largest_integral_type_to_pointer(const char*, value), + (const char*)check->memory, + check->size); +} + + +/* Add an event to check whether a parameter doesn't match an area of memory. */ +void _expect_not_memory( + const char* const function, const char* const parameter, + const char* const file, const int line, const void* const memory, + const size_t size, const int count) { + expect_memory_setup(function, parameter, file, line, memory, size, + check_not_memory, count); +} + + +/* CheckParameterValue callback that always returns 1. */ +static int check_any(const LargestIntegralType value, + const LargestIntegralType check_value_data) { + (void)value; + (void)check_value_data; + return 1; +} + + +/* Add an event to allow any value for a parameter. */ +void _expect_any( + const char* const function, const char* const parameter, + const char* const file, const int line, const int count) { + _expect_check(function, parameter, file, line, check_any, 0, NULL, + count); +} + + +void _check_expected( + const char * const function_name, const char * const parameter_name, + const char* file, const int line, const LargestIntegralType value) { + void *result = NULL; + const char* symbols[] = {function_name, parameter_name}; + const int rc = get_symbol_value(&global_function_parameter_map_head, + symbols, 2, &result); + if (rc) { + CheckParameterEvent * const check = (CheckParameterEvent*)result; + int check_succeeded; + global_last_parameter_location = check->location; + check_succeeded = check->check_value(value, check->check_value_data); + if (rc == 1) { + free(check); + } + if (!check_succeeded) { + cm_print_error(SOURCE_LOCATION_FORMAT + ": error: Check of parameter %s, function %s failed\n" + SOURCE_LOCATION_FORMAT + ": note: Expected parameter declared here\n", + file, line, + parameter_name, function_name, + global_last_parameter_location.file, + global_last_parameter_location.line); + _fail(file, line); + } + } else { + cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value " + "to check parameter %s of function %s\n", file, line, + parameter_name, function_name); + if (source_location_is_set(&global_last_parameter_location)) { + cm_print_error(SOURCE_LOCATION_FORMAT + ": note: Previously declared parameter value was declared here\n", + global_last_parameter_location.file, + global_last_parameter_location.line); + } else { + cm_print_error("There were no previously declared parameter values " + "for this test.\n"); + } + exit_test(1); + } +} + + +/* Replacement for assert. */ +void mock_assert(const int result, const char* const expression, + const char* const file, const int line) { + if (!result) { + if (global_expecting_assert) { + global_last_failed_assert = expression; + longjmp(global_expect_assert_env, result); + } else { + cm_print_error("ASSERT: %s\n", expression); + _fail(file, line); + } + } +} + + +void _assert_true(const LargestIntegralType result, + const char * const expression, + const char * const file, const int line) { + if (!result) { + cm_print_error("%s\n", expression); + _fail(file, line); + } +} + +void _assert_return_code(const LargestIntegralType result, + size_t rlen, + const LargestIntegralType error, + const char * const expression, + const char * const file, + const int line) +{ + LargestIntegralType valmax; + + + switch (rlen) { + case 1: + valmax = 255; + break; + case 2: + valmax = 32767; + break; + case 4: + valmax = 2147483647; + break; + case 8: + default: + if (rlen > sizeof(valmax)) { + valmax = 2147483647; + } else { + valmax = 9223372036854775807L; + } + break; + } + + if (result > valmax - 1) { + if (error > 0) { + cm_print_error("%s < 0, errno(" + LargestIntegralTypePrintfFormatDecimal "): %s\n", + expression, error, strerror((int)error)); + } else { + cm_print_error("%s < 0\n", expression); + } + _fail(file, line); + } +} + +void _assert_int_equal( + const LargestIntegralType a, const LargestIntegralType b, + const char * const file, const int line) { + if (!values_equal_display_error(a, b)) { + _fail(file, line); + } +} + + +void _assert_int_not_equal( + const LargestIntegralType a, const LargestIntegralType b, + const char * const file, const int line) { + if (!values_not_equal_display_error(a, b)) { + _fail(file, line); + } +} + + +void _assert_string_equal(const char * const a, const char * const b, + const char * const file, const int line) { + if (!string_equal_display_error(a, b)) { + _fail(file, line); + } +} + + +void _assert_string_not_equal(const char * const a, const char * const b, + const char *file, const int line) { + if (!string_not_equal_display_error(a, b)) { + _fail(file, line); + } +} + + +void _assert_memory_equal(const void * const a, const void * const b, + const size_t size, const char* const file, + const int line) { + if (!memory_equal_display_error((const char*)a, (const char*)b, size)) { + _fail(file, line); + } +} + + +void _assert_memory_not_equal(const void * const a, const void * const b, + const size_t size, const char* const file, + const int line) { + if (!memory_not_equal_display_error((const char*)a, (const char*)b, + size)) { + _fail(file, line); + } +} + + +void _assert_in_range( + const LargestIntegralType value, const LargestIntegralType minimum, + const LargestIntegralType maximum, const char* const file, + const int line) { + if (!integer_in_range_display_error(value, minimum, maximum)) { + _fail(file, line); + } +} + +void _assert_not_in_range( + const LargestIntegralType value, const LargestIntegralType minimum, + const LargestIntegralType maximum, const char* const file, + const int line) { + if (!integer_not_in_range_display_error(value, minimum, maximum)) { + _fail(file, line); + } +} + +void _assert_in_set(const LargestIntegralType value, + const LargestIntegralType values[], + const size_t number_of_values, const char* const file, + const int line) { + CheckIntegerSet check_integer_set; + check_integer_set.set = values; + check_integer_set.size_of_set = number_of_values; + if (!value_in_set_display_error(value, &check_integer_set, 0)) { + _fail(file, line); + } +} + +void _assert_not_in_set(const LargestIntegralType value, + const LargestIntegralType values[], + const size_t number_of_values, const char* const file, + const int line) { + CheckIntegerSet check_integer_set; + check_integer_set.set = values; + check_integer_set.size_of_set = number_of_values; + if (!value_in_set_display_error(value, &check_integer_set, 1)) { + _fail(file, line); + } +} + + +/* Get the list of allocated blocks. */ +static ListNode* get_allocated_blocks_list(void) { + /* If it initialized, initialize the list of allocated blocks. */ + if (!global_allocated_blocks.value) { + list_initialize(&global_allocated_blocks); + global_allocated_blocks.value = (void*)1; + } + return &global_allocated_blocks; +} + +static void *libc_malloc(size_t size) +{ +#undef malloc + return malloc(size); +#define malloc test_malloc +} + +static void libc_free(void *ptr) +{ +#undef free + free(ptr); +#define free test_free +} + +static void *libc_realloc(void *ptr, size_t size) +{ +#undef realloc + return realloc(ptr, size); +#define realloc test_realloc +} + +static void vcm_print_error(const char* const format, + va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0); + +/* It's important to use the libc malloc and free here otherwise + * the automatic free of leaked blocks can reap the error messages + */ +static void vcm_print_error(const char* const format, va_list args) +{ + char buffer[1024]; + size_t msg_len = 0; + va_list ap; + int len; + va_copy(ap, args); + + len = vsnprintf(buffer, sizeof(buffer), format, args); + if (len < 0) { + /* TODO */ + goto end; + } + + if (cm_error_message == NULL) { + /* CREATE MESSAGE */ + + cm_error_message = libc_malloc(len + 1); + if (cm_error_message == NULL) { + /* TODO */ + goto end; + } + } else { + /* APPEND MESSAGE */ + char *tmp; + + msg_len = strlen(cm_error_message); + tmp = libc_realloc(cm_error_message, msg_len + len + 1); + if (tmp == NULL) { + goto end; + } + cm_error_message = tmp; + } + + if (((size_t)len) < sizeof(buffer)) { + /* Use len + 1 to also copy '\0' */ + memcpy(cm_error_message + msg_len, buffer, len + 1); + } else { + vsnprintf(cm_error_message + msg_len, len, format, ap); + } +end: + va_end(ap); + +} + +static void vcm_free_error(char *err_msg) +{ + libc_free(err_msg); +} + +/* Use the real malloc in this function. */ +#undef malloc +void* _test_malloc(const size_t size, const char* file, const int line) { + char *ptr = NULL; + MallocBlockInfo block_info; + ListNode * const block_list = get_allocated_blocks_list(); + size_t allocate_size; + char *block = NULL; + + allocate_size = size + (MALLOC_GUARD_SIZE * 2) + + sizeof(struct MallocBlockInfoData) + MALLOC_ALIGNMENT; + assert_true(allocate_size > size); + + block = (char *)malloc(allocate_size); + assert_non_null(block); + + /* Calculate the returned address. */ + ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE + + sizeof(struct MallocBlockInfoData) + + MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1)); + + /* Initialize the guard blocks. */ + memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE); + memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE); + memset(ptr, MALLOC_ALLOC_PATTERN, size); + + block_info.ptr = ptr - (MALLOC_GUARD_SIZE + + sizeof(struct MallocBlockInfoData)); + set_source_location(&block_info.data->location, file, line); + block_info.data->allocated_size = allocate_size; + block_info.data->size = size; + block_info.data->block = block; + block_info.data->node.value = block_info.ptr; + list_add(block_list, &block_info.data->node); + return ptr; +} +#define malloc test_malloc + + +void* _test_calloc(const size_t number_of_elements, const size_t size, + const char* file, const int line) { + void* const ptr = _test_malloc(number_of_elements * size, file, line); + if (ptr) { + memset(ptr, 0, number_of_elements * size); + } + return ptr; +} + + +/* Use the real free in this function. */ +#undef free +void _test_free(void* const ptr, const char* file, const int line) { + unsigned int i; + char *block = discard_const_p(char, ptr); + MallocBlockInfo block_info; + + if (ptr == NULL) { + return; + } + + _assert_true(cast_ptr_to_largest_integral_type(ptr), "ptr", file, line); + block_info.ptr = block - (MALLOC_GUARD_SIZE + + sizeof(struct MallocBlockInfoData)); + /* Check the guard blocks. */ + { + char *guards[2] = {block - MALLOC_GUARD_SIZE, + block + block_info.data->size}; + for (i = 0; i < ARRAY_SIZE(guards); i++) { + unsigned int j; + char * const guard = guards[i]; + for (j = 0; j < MALLOC_GUARD_SIZE; j++) { + const char diff = guard[j] - MALLOC_GUARD_PATTERN; + if (diff) { + cm_print_error(SOURCE_LOCATION_FORMAT + ": error: Guard block of %p size=%lu is corrupt\n" + SOURCE_LOCATION_FORMAT ": note: allocated here at %p\n", + file, + line, + ptr, + (unsigned long)block_info.data->size, + block_info.data->location.file, + block_info.data->location.line, + (void *)&guard[j]); + _fail(file, line); + } + } + } + } + list_remove(&block_info.data->node, NULL, NULL); + + block = discard_const_p(char, block_info.data->block); + memset(block, MALLOC_FREE_PATTERN, block_info.data->allocated_size); + free(block); +} +#define free test_free + +#undef realloc +void *_test_realloc(void *ptr, + const size_t size, + const char *file, + const int line) +{ + MallocBlockInfo block_info; + char *block = ptr; + size_t block_size = size; + void *new_block; + + if (ptr == NULL) { + return _test_malloc(size, file, line); + } + + if (size == 0) { + _test_free(ptr, file, line); + return NULL; + } + + block_info.ptr = block - (MALLOC_GUARD_SIZE + + sizeof(struct MallocBlockInfoData)); + + new_block = _test_malloc(size, file, line); + if (new_block == NULL) { + return NULL; + } + + if (block_info.data->size < size) { + block_size = block_info.data->size; + } + + memcpy(new_block, ptr, block_size); + + /* Free previous memory */ + _test_free(ptr, file, line); + + return new_block; +} +#define realloc test_realloc + +/* Crudely checkpoint the current heap state. */ +static const ListNode* check_point_allocated_blocks(void) { + return get_allocated_blocks_list()->prev; +} + + +/* Display the blocks allocated after the specified check point. This + * function returns the number of blocks displayed. */ +static size_t display_allocated_blocks(const ListNode * const check_point) { + const ListNode * const head = get_allocated_blocks_list(); + const ListNode *node; + size_t allocated_blocks = 0; + assert_non_null(check_point); + assert_non_null(check_point->next); + + for (node = check_point->next; node != head; node = node->next) { + const MallocBlockInfo block_info = { + .ptr = discard_const(node->value), + }; + assert_non_null(block_info.ptr); + + if (allocated_blocks == 0) { + cm_print_error("Blocks allocated...\n"); + } + cm_print_error(SOURCE_LOCATION_FORMAT ": note: block %p allocated here\n", + block_info.data->location.file, + block_info.data->location.line, + block_info.data->block); + allocated_blocks++; + } + return allocated_blocks; +} + + +/* Free all blocks allocated after the specified check point. */ +static void free_allocated_blocks(const ListNode * const check_point) { + const ListNode * const head = get_allocated_blocks_list(); + const ListNode *node; + assert_non_null(check_point); + + node = check_point->next; + assert_non_null(node); + + while (node != head) { + const MallocBlockInfo block_info = { + .ptr = discard_const(node->value), + }; + node = node->next; + free(discard_const_p(char, block_info.data) + + sizeof(struct MallocBlockInfoData) + + MALLOC_GUARD_SIZE); + } +} + + +/* Fail if any any blocks are allocated after the specified check point. */ +static void fail_if_blocks_allocated(const ListNode * const check_point, + const char * const test_name) { + const size_t allocated_blocks = display_allocated_blocks(check_point); + if (allocated_blocks > 0) { + free_allocated_blocks(check_point); + cm_print_error("ERROR: %s leaked %zu block(s)\n", test_name, + allocated_blocks); + exit_test(1); + } +} + + +void _fail(const char * const file, const int line) { + enum cm_message_output output = cm_get_output(); + + switch(output) { + case CM_OUTPUT_STDOUT: + cm_print_error("[ LINE ] --- " SOURCE_LOCATION_FORMAT ": error: Failure!", file, line); + break; + default: + cm_print_error(SOURCE_LOCATION_FORMAT ": error: Failure!", file, line); + break; + } + exit_test(1); +} + + +#ifndef _WIN32 +static void exception_handler(int sig) { + const char *sig_strerror = ""; + +#ifdef HAVE_STRSIGNAL + sig_strerror = strsignal(sig); +#endif + + cm_print_error("Test failed with exception: %s(%d)", + sig_strerror, sig); + exit_test(1); +} + +#else /* _WIN32 */ + +static LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) { + EXCEPTION_RECORD * const exception_record = + exception_pointers->ExceptionRecord; + const DWORD code = exception_record->ExceptionCode; + unsigned int i; + for (i = 0; i < ARRAY_SIZE(exception_codes); i++) { + const ExceptionCodeInfo * const code_info = &exception_codes[i]; + if (code == code_info->code) { + static int shown_debug_message = 0; + fflush(stdout); + cm_print_error("%s occurred at %p.\n", code_info->description, + exception_record->ExceptionAddress); + if (!shown_debug_message) { + cm_print_error( + "\n" + "To debug in Visual Studio...\n" + "1. Select menu item File->Open Project\n" + "2. Change 'Files of type' to 'Executable Files'\n" + "3. Open this executable.\n" + "4. Select menu item Debug->Start\n" + "\n" + "Alternatively, set the environment variable \n" + "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n" + "then click 'Debug' in the popup dialog box.\n" + "\n"); + shown_debug_message = 1; + } + exit_test(0); + return EXCEPTION_EXECUTE_HANDLER; + } + } + return EXCEPTION_CONTINUE_SEARCH; +} +#endif /* !_WIN32 */ + +void cm_print_error(const char * const format, ...) +{ + va_list args; + va_start(args, format); + if (cm_error_message_enabled) { + vcm_print_error(format, args); + } else { + vprint_error(format, args); + } + va_end(args); +} + +/* Standard output and error print methods. */ +void vprint_message(const char* const format, va_list args) { + char buffer[1024]; + vsnprintf(buffer, sizeof(buffer), format, args); + printf("%s", buffer); + fflush(stdout); +#ifdef _WIN32 + OutputDebugString(buffer); +#endif /* _WIN32 */ +} + + +void vprint_error(const char* const format, va_list args) { + char buffer[1024]; + vsnprintf(buffer, sizeof(buffer), format, args); + fprintf(stderr, "%s", buffer); + fflush(stderr); +#ifdef _WIN32 + OutputDebugString(buffer); +#endif /* _WIN32 */ +} + + +void print_message(const char* const format, ...) { + va_list args; + va_start(args, format); + vprint_message(format, args); + va_end(args); +} + + +void print_error(const char* const format, ...) { + va_list args; + va_start(args, format); + vprint_error(format, args); + va_end(args); +} + +/* New formatter */ +static enum cm_message_output cm_get_output(void) +{ + enum cm_message_output output = global_msg_output; + char *env; + + env = getenv("CMOCKA_MESSAGE_OUTPUT"); + if (env != NULL) { + if (strcasecmp(env, "STDOUT") == 0) { + output = CM_OUTPUT_STDOUT; + } else if (strcasecmp(env, "SUBUNIT") == 0) { + output = CM_OUTPUT_SUBUNIT; + } else if (strcasecmp(env, "TAP") == 0) { + output = CM_OUTPUT_TAP; + } else if (strcasecmp(env, "XML") == 0) { + output = CM_OUTPUT_XML; + } + } + + return output; +} + +enum cm_printf_type { + PRINTF_TEST_START, + PRINTF_TEST_SUCCESS, + PRINTF_TEST_FAILURE, + PRINTF_TEST_ERROR, + PRINTF_TEST_SKIPPED, +}; + +static int xml_printed; +static int file_append; + +static void cmprintf_group_finish_xml(const char *group_name, + size_t total_executed, + size_t total_failed, + size_t total_errors, + size_t total_skipped, + double total_runtime, + struct CMUnitTestState *cm_tests) +{ + FILE *fp = stdout; + int file_opened = 0; + int multiple_files = 0; + char *env; + size_t i; + + env = getenv("CMOCKA_XML_FILE"); + if (env != NULL) { + char buf[1024]; + int rc; + + snprintf(buf, sizeof(buf), "%s", env); + + rc = c_strreplace(buf, sizeof(buf), "%g", group_name, &multiple_files); + if (rc < 0) { + snprintf(buf, sizeof(buf), "%s", env); + } + + fp = fopen(buf, "r"); + if (fp == NULL) { + fp = fopen(buf, "w"); + if (fp != NULL) { + file_append = 1; + file_opened = 1; + } else { + fp = stderr; + } + } else { + fclose(fp); + if (file_append) { + fp = fopen(buf, "a"); + if (fp != NULL) { + file_opened = 1; + xml_printed = 1; + } else { + fp = stderr; + } + } else { + fp = stderr; + } + } + } + + if (!xml_printed || (file_opened && !file_append)) { + fprintf(fp, "\n"); + if (!file_opened) { + xml_printed = 1; + } + } + + fprintf(fp, "\n"); + fprintf(fp, " \n", + group_name, + total_runtime, /* seconds */ + (unsigned)total_executed, + (unsigned)total_failed, + (unsigned)total_errors, + (unsigned)total_skipped); + + for (i = 0; i < total_executed; i++) { + struct CMUnitTestState *cmtest = &cm_tests[i]; + + fprintf(fp, " \n", + cmtest->test->name, cmtest->runtime); + + switch (cmtest->status) { + case CM_TEST_ERROR: + case CM_TEST_FAILED: + if (cmtest->error_message != NULL) { + fprintf(fp, " \n", + cmtest->error_message); + } else { + fprintf(fp, " \n"); + } + break; + case CM_TEST_SKIPPED: + fprintf(fp, " \n"); + break; + + case CM_TEST_PASSED: + case CM_TEST_NOT_STARTED: + break; + } + + fprintf(fp, " \n"); + } + + fprintf(fp, " \n"); + fprintf(fp, "\n"); + + if (file_opened) { + fclose(fp); + } +} + +static void cmprintf_group_start_standard(const size_t num_tests) +{ + print_message("[==========] Running %u test(s).\n", + (unsigned)num_tests); +} + +static void cmprintf_group_finish_standard(size_t total_executed, + size_t total_passed, + size_t total_failed, + size_t total_errors, + size_t total_skipped, + struct CMUnitTestState *cm_tests) +{ + size_t i; + + print_message("[==========] %u test(s) run.\n", (unsigned)total_executed); + print_error("[ PASSED ] %u test(s).\n", + (unsigned)(total_passed)); + + if (total_skipped) { + print_error("[ SKIPPED ] %"PRIdS " test(s), listed below:\n", total_skipped); + for (i = 0; i < total_executed; i++) { + struct CMUnitTestState *cmtest = &cm_tests[i]; + + if (cmtest->status == CM_TEST_SKIPPED) { + print_error("[ SKIPPED ] %s\n", cmtest->test->name); + } + } + print_error("\n %u SKIPPED TEST(S)\n", (unsigned)(total_skipped)); + } + + if (total_failed) { + print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed); + for (i = 0; i < total_executed; i++) { + struct CMUnitTestState *cmtest = &cm_tests[i]; + + if (cmtest->status == CM_TEST_FAILED) { + print_error("[ FAILED ] %s\n", cmtest->test->name); + } + } + print_error("\n %u FAILED TEST(S)\n", + (unsigned)(total_failed + total_errors)); + } +} + +static void cmprintf_standard(enum cm_printf_type type, + const char *test_name, + const char *error_message) +{ + switch (type) { + case PRINTF_TEST_START: + print_message("[ RUN ] %s\n", test_name); + break; + case PRINTF_TEST_SUCCESS: + print_message("[ OK ] %s\n", test_name); + break; + case PRINTF_TEST_FAILURE: + if (error_message != NULL) { + print_error("[ ERROR ] --- %s\n", error_message); + } + print_message("[ FAILED ] %s\n", test_name); + break; + case PRINTF_TEST_SKIPPED: + print_message("[ SKIPPED ] %s\n", test_name); + break; + case PRINTF_TEST_ERROR: + if (error_message != NULL) { + print_error("%s\n", error_message); + } + print_error("[ ERROR ] %s\n", test_name); + break; + } +} + +static void cmprintf_group_start_tap(const size_t num_tests) +{ + print_message("1..%u\n", (unsigned)num_tests); +} + +static void cmprintf_group_finish_tap(const char *group_name, + size_t total_executed, + size_t total_passed, + size_t total_skipped) +{ + const char *status = "not ok"; + if (total_passed + total_skipped == total_executed) { + status = "ok"; + } + print_message("# %s - %s\n", status, group_name); +} + +static void cmprintf_tap(enum cm_printf_type type, + uint32_t test_number, + const char *test_name, + const char *error_message) +{ + switch (type) { + case PRINTF_TEST_START: + break; + case PRINTF_TEST_SUCCESS: + print_message("ok %u - %s\n", (unsigned)test_number, test_name); + break; + case PRINTF_TEST_FAILURE: + print_message("not ok %u - %s\n", (unsigned)test_number, test_name); + if (error_message != NULL) { + char *msg; + char *p; + + msg = strdup(error_message); + if (msg == NULL) { + return; + } + p = msg; + + while (p[0] != '\0') { + char *q = p; + + p = strchr(q, '\n'); + if (p != NULL) { + p[0] = '\0'; + } + + print_message("# %s\n", q); + + if (p == NULL) { + break; + } + p++; + } + libc_free(msg); + } + break; + case PRINTF_TEST_SKIPPED: + print_message("not ok %u # SKIP %s\n", (unsigned)test_number, test_name); + break; + case PRINTF_TEST_ERROR: + print_message("not ok %u - %s %s\n", + (unsigned)test_number, test_name, error_message); + break; + } +} + +static void cmprintf_subunit(enum cm_printf_type type, + const char *test_name, + const char *error_message) +{ + switch (type) { + case PRINTF_TEST_START: + print_message("test: %s\n", test_name); + break; + case PRINTF_TEST_SUCCESS: + print_message("success: %s\n", test_name); + break; + case PRINTF_TEST_FAILURE: + print_message("failure: %s", test_name); + if (error_message != NULL) { + print_message(" [\n%s\n]\n", error_message); + } + break; + case PRINTF_TEST_SKIPPED: + print_message("skip: %s\n", test_name); + break; + case PRINTF_TEST_ERROR: + print_message("error: %s [ %s ]\n", test_name, error_message); + break; + } +} + +static void cmprintf_group_start(const size_t num_tests) +{ + enum cm_message_output output; + + output = cm_get_output(); + + switch (output) { + case CM_OUTPUT_STDOUT: + cmprintf_group_start_standard(num_tests); + break; + case CM_OUTPUT_SUBUNIT: + break; + case CM_OUTPUT_TAP: + cmprintf_group_start_tap(num_tests); + break; + case CM_OUTPUT_XML: + break; + } +} + +static void cmprintf_group_finish(const char *group_name, + size_t total_executed, + size_t total_passed, + size_t total_failed, + size_t total_errors, + size_t total_skipped, + double total_runtime, + struct CMUnitTestState *cm_tests) +{ + enum cm_message_output output; + + output = cm_get_output(); + + switch (output) { + case CM_OUTPUT_STDOUT: + cmprintf_group_finish_standard(total_executed, + total_passed, + total_failed, + total_errors, + total_skipped, + cm_tests); + break; + case CM_OUTPUT_SUBUNIT: + break; + case CM_OUTPUT_TAP: + cmprintf_group_finish_tap(group_name, total_executed, total_passed, total_skipped); + break; + case CM_OUTPUT_XML: + cmprintf_group_finish_xml(group_name, + total_executed, + total_failed, + total_errors, + total_skipped, + total_runtime, + cm_tests); + break; + } +} + +static void cmprintf(enum cm_printf_type type, + size_t test_number, + const char *test_name, + const char *error_message) +{ + enum cm_message_output output; + + output = cm_get_output(); + + switch (output) { + case CM_OUTPUT_STDOUT: + cmprintf_standard(type, test_name, error_message); + break; + case CM_OUTPUT_SUBUNIT: + cmprintf_subunit(type, test_name, error_message); + break; + case CM_OUTPUT_TAP: + cmprintf_tap(type, test_number, test_name, error_message); + break; + case CM_OUTPUT_XML: + break; + } +} + +void cmocka_set_message_output(enum cm_message_output output) +{ + global_msg_output = output; +} + +void cmocka_set_test_filter(const char *pattern) +{ + global_test_filter_pattern = pattern; +} + +/**************************************************************************** + * TIME CALCULATIONS + ****************************************************************************/ + +#ifdef HAVE_STRUCT_TIMESPEC +static struct timespec cm_tspecdiff(struct timespec time1, + struct timespec time0) +{ + struct timespec ret; + int xsec = 0; + int sign = 1; + + if (time0.tv_nsec > time1.tv_nsec) { + xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1)); + time0.tv_nsec -= (long int) (1E9 * xsec); + time0.tv_sec += xsec; + } + + if ((time1.tv_nsec - time0.tv_nsec) > 1E9) { + xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9); + time0.tv_nsec += (long int) (1E9 * xsec); + time0.tv_sec -= xsec; + } + + ret.tv_sec = time1.tv_sec - time0.tv_sec; + ret.tv_nsec = time1.tv_nsec - time0.tv_nsec; + + if (time1.tv_sec < time0.tv_sec) { + sign = -1; + } + + ret.tv_sec = ret.tv_sec * sign; + + return ret; +} + +static double cm_secdiff(struct timespec clock1, struct timespec clock0) +{ + double ret; + struct timespec diff; + + diff = cm_tspecdiff(clock1, clock0); + + ret = diff.tv_sec; + ret += (double) diff.tv_nsec / (double) 1E9; + + return ret; +} +#endif /* HAVE_STRUCT_TIMESPEC */ + +/**************************************************************************** + * CMOCKA TEST RUNNER + ****************************************************************************/ +static int cmocka_run_one_test_or_fixture(const char *function_name, + CMUnitTestFunction test_func, + CMFixtureFunction setup_func, + CMFixtureFunction teardown_func, + void ** const volatile state, + const void *const heap_check_point) +{ + const ListNode * const volatile check_point = (const ListNode*) + (heap_check_point != NULL ? + heap_check_point : check_point_allocated_blocks()); + int handle_exceptions = 1; + void *current_state = NULL; + int rc = 0; + + /* FIXME check only one test or fixture is set */ + + /* Detect if we should handle exceptions */ +#ifdef _WIN32 + handle_exceptions = !IsDebuggerPresent(); +#endif /* _WIN32 */ +#ifdef UNIT_TESTING_DEBUG + handle_exceptions = 0; +#endif /* UNIT_TESTING_DEBUG */ + + + if (handle_exceptions) { +#ifndef _WIN32 + unsigned int i; + for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { + default_signal_functions[i] = signal( + exception_signals[i], exception_handler); + } +#else /* _WIN32 */ + previous_exception_filter = SetUnhandledExceptionFilter( + exception_filter); +#endif /* !_WIN32 */ + } + + /* Init the test structure */ + initialize_testing(function_name); + + global_running_test = 1; + + if (cm_setjmp(global_run_test_env) == 0) { + if (test_func != NULL) { + test_func(state != NULL ? state : ¤t_state); + + fail_if_blocks_allocated(check_point, function_name); + rc = 0; + } else if (setup_func != NULL) { + rc = setup_func(state != NULL ? state : ¤t_state); + + /* + * For setup we can ignore any allocated blocks. We just need to + * ensure they're deallocated on tear down. + */ + } else if (teardown_func != NULL) { + rc = teardown_func(state != NULL ? state : ¤t_state); + + fail_if_blocks_allocated(check_point, function_name); + } else { + /* ERROR */ + } + fail_if_leftover_values(function_name); + global_running_test = 0; + } else { + /* TEST FAILED */ + global_running_test = 0; + rc = -1; + } + teardown_testing(function_name); + + if (handle_exceptions) { +#ifndef _WIN32 + unsigned int i; + for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { + signal(exception_signals[i], default_signal_functions[i]); + } +#else /* _WIN32 */ + if (previous_exception_filter) { + SetUnhandledExceptionFilter(previous_exception_filter); + previous_exception_filter = NULL; + } +#endif /* !_WIN32 */ + } + + return rc; +} + +static int cmocka_run_group_fixture(const char *function_name, + CMFixtureFunction setup_func, + CMFixtureFunction teardown_func, + void **state, + const void *const heap_check_point) +{ + int rc; + + if (setup_func != NULL) { + rc = cmocka_run_one_test_or_fixture(function_name, + NULL, + setup_func, + NULL, + state, + heap_check_point); + } else { + rc = cmocka_run_one_test_or_fixture(function_name, + NULL, + NULL, + teardown_func, + state, + heap_check_point); + } + + return rc; +} + +static int cmocka_run_one_tests(struct CMUnitTestState *test_state) +{ +#ifdef HAVE_STRUCT_TIMESPEC + struct timespec start = { + .tv_sec = 0, + .tv_nsec = 0, + }; + struct timespec finish = { + .tv_sec = 0, + .tv_nsec = 0, + }; +#endif + int rc = 0; + + /* Run setup */ + if (test_state->test->setup_func != NULL) { + /* Setup the memory check point, it will be evaluated on teardown */ + test_state->check_point = check_point_allocated_blocks(); + + rc = cmocka_run_one_test_or_fixture(test_state->test->name, + NULL, + test_state->test->setup_func, + NULL, + &test_state->state, + test_state->check_point); + if (rc != 0) { + test_state->status = CM_TEST_ERROR; + cm_print_error("Test setup failed"); + } + } + + /* Run test */ +#ifdef HAVE_STRUCT_TIMESPEC + CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &start); +#endif + + if (rc == 0) { + rc = cmocka_run_one_test_or_fixture(test_state->test->name, + test_state->test->test_func, + NULL, + NULL, + &test_state->state, + NULL); + if (rc == 0) { + test_state->status = CM_TEST_PASSED; + } else { + if (global_skip_test) { + test_state->status = CM_TEST_SKIPPED; + global_skip_test = 0; /* Do not skip the next test */ + } else { + test_state->status = CM_TEST_FAILED; + } + } + rc = 0; + } + + test_state->runtime = 0.0; + +#ifdef HAVE_STRUCT_TIMESPEC + CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &finish); + test_state->runtime = cm_secdiff(finish, start); +#endif + + /* Run teardown */ + if (rc == 0 && test_state->test->teardown_func != NULL) { + rc = cmocka_run_one_test_or_fixture(test_state->test->name, + NULL, + NULL, + test_state->test->teardown_func, + &test_state->state, + test_state->check_point); + if (rc != 0) { + test_state->status = CM_TEST_ERROR; + cm_print_error("Test teardown failed"); + } + } + + test_state->error_message = cm_error_message; + cm_error_message = NULL; + + return rc; +} + +int _cmocka_run_group_tests(const char *group_name, + const struct CMUnitTest * const tests, + const size_t num_tests, + CMFixtureFunction group_setup, + CMFixtureFunction group_teardown) +{ + struct CMUnitTestState *cm_tests; + const ListNode *group_check_point = check_point_allocated_blocks(); + void *group_state = NULL; + size_t total_tests = 0; + size_t total_failed = 0; + size_t total_passed = 0; + size_t total_executed = 0; + size_t total_errors = 0; + size_t total_skipped = 0; + double total_runtime = 0; + size_t i; + int rc; + + /* Make sure LargestIntegralType is at least the size of a pointer. */ + assert_true(sizeof(LargestIntegralType) >= sizeof(void*)); + + cm_tests = (struct CMUnitTestState *)libc_malloc(sizeof(struct CMUnitTestState) * num_tests); + if (cm_tests == NULL) { + return -1; + } + + /* Setup cmocka test array */ + for (i = 0; i < num_tests; i++) { + if (tests[i].name != NULL && + (tests[i].test_func != NULL + || tests[i].setup_func != NULL + || tests[i].teardown_func != NULL)) { + if (global_test_filter_pattern != NULL) { + int ok; + + ok = c_strmatch(tests[i].name, global_test_filter_pattern); + if (!ok) { + continue; + } + } + cm_tests[total_tests] = (struct CMUnitTestState) { + .test = &tests[i], + .status = CM_TEST_NOT_STARTED, + .state = NULL, + }; + total_tests++; + } + } + + cmprintf_group_start(total_tests); + + rc = 0; + + /* Run group setup */ + if (group_setup != NULL) { + rc = cmocka_run_group_fixture("cmocka_group_setup", + group_setup, + NULL, + &group_state, + group_check_point); + } + + if (rc == 0) { + /* Execute tests */ + for (i = 0; i < total_tests; i++) { + struct CMUnitTestState *cmtest = &cm_tests[i]; + size_t test_number = i + 1; + + cmprintf(PRINTF_TEST_START, test_number, cmtest->test->name, NULL); + + if (group_state != NULL) { + cmtest->state = group_state; + } else if (cmtest->test->initial_state != NULL) { + cmtest->state = cmtest->test->initial_state; + } + + rc = cmocka_run_one_tests(cmtest); + total_executed++; + total_runtime += cmtest->runtime; + if (rc == 0) { + switch (cmtest->status) { + case CM_TEST_PASSED: + cmprintf(PRINTF_TEST_SUCCESS, + test_number, + cmtest->test->name, + cmtest->error_message); + total_passed++; + break; + case CM_TEST_SKIPPED: + cmprintf(PRINTF_TEST_SKIPPED, + test_number, + cmtest->test->name, + cmtest->error_message); + total_skipped++; + break; + case CM_TEST_FAILED: + cmprintf(PRINTF_TEST_FAILURE, + test_number, + cmtest->test->name, + cmtest->error_message); + total_failed++; + break; + default: + cmprintf(PRINTF_TEST_ERROR, + test_number, + cmtest->test->name, + "Internal cmocka error"); + total_errors++; + break; + } + } else { + char err_msg[2048] = {0}; + + snprintf(err_msg, sizeof(err_msg), + "Could not run test: %s", + cmtest->error_message); + + cmprintf(PRINTF_TEST_ERROR, + test_number, + cmtest->test->name, + err_msg); + total_errors++; + } + } + } else { + if (cm_error_message != NULL) { + print_error("[ ERROR ] --- %s\n", cm_error_message); + vcm_free_error(cm_error_message); + cm_error_message = NULL; + } + cmprintf(PRINTF_TEST_ERROR, 0, + group_name, "[ FAILED ] GROUP SETUP"); + total_errors++; + } + + /* Run group teardown */ + if (group_teardown != NULL) { + rc = cmocka_run_group_fixture("cmocka_group_teardown", + NULL, + group_teardown, + &group_state, + group_check_point); + if (rc != 0) { + if (cm_error_message != NULL) { + print_error("[ ERROR ] --- %s\n", cm_error_message); + vcm_free_error(cm_error_message); + cm_error_message = NULL; + } + cmprintf(PRINTF_TEST_ERROR, 0, + group_name, "[ FAILED ] GROUP TEARDOWN"); + } + } + + cmprintf_group_finish(group_name, + total_executed, + total_passed, + total_failed, + total_errors, + total_skipped, + total_runtime, + cm_tests); + + for (i = 0; i < total_tests; i++) { + vcm_free_error(discard_const_p(char, cm_tests[i].error_message)); + } + libc_free(cm_tests); + fail_if_blocks_allocated(group_check_point, "cmocka_group_tests"); + + return total_failed + total_errors; +} + +/**************************************************************************** + * DEPRECATED TEST RUNNER + ****************************************************************************/ + +int _run_test( + const char * const function_name, const UnitTestFunction Function, + void ** const volatile state, const UnitTestFunctionType function_type, + const void* const heap_check_point) { + const ListNode * const volatile check_point = (const ListNode*) + (heap_check_point ? + heap_check_point : check_point_allocated_blocks()); + void *current_state = NULL; + volatile int rc = 1; + int handle_exceptions = 1; +#ifdef _WIN32 + handle_exceptions = !IsDebuggerPresent(); +#endif /* _WIN32 */ +#ifdef UNIT_TESTING_DEBUG + handle_exceptions = 0; +#endif /* UNIT_TESTING_DEBUG */ + + cm_error_message_enabled = 0; + + if (handle_exceptions) { +#ifndef _WIN32 + unsigned int i; + for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { + default_signal_functions[i] = signal( + exception_signals[i], exception_handler); + } +#else /* _WIN32 */ + previous_exception_filter = SetUnhandledExceptionFilter( + exception_filter); +#endif /* !_WIN32 */ + } + + if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) { + print_message("[ RUN ] %s\n", function_name); + } + initialize_testing(function_name); + global_running_test = 1; + if (cm_setjmp(global_run_test_env) == 0) { + Function(state ? state : ¤t_state); + fail_if_leftover_values(function_name); + + /* If this is a setup function then ignore any allocated blocks + * only ensure they're deallocated on tear down. */ + if (function_type != UNIT_TEST_FUNCTION_TYPE_SETUP) { + fail_if_blocks_allocated(check_point, function_name); + } + + global_running_test = 0; + + if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) { + print_message("[ OK ] %s\n", function_name); + } + rc = 0; + } else { + global_running_test = 0; + print_message("[ FAILED ] %s\n", function_name); + } + teardown_testing(function_name); + + if (handle_exceptions) { +#ifndef _WIN32 + unsigned int i; + for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { + signal(exception_signals[i], default_signal_functions[i]); + } +#else /* _WIN32 */ + if (previous_exception_filter) { + SetUnhandledExceptionFilter(previous_exception_filter); + previous_exception_filter = NULL; + } +#endif /* !_WIN32 */ + } + + return rc; +} + + +int _run_tests(const UnitTest * const tests, const size_t number_of_tests) { + /* Whether to execute the next test. */ + int run_next_test = 1; + /* Whether the previous test failed. */ + int previous_test_failed = 0; + /* Whether the previous setup failed. */ + int previous_setup_failed = 0; + /* Check point of the heap state. */ + const ListNode * const check_point = check_point_allocated_blocks(); + /* Current test being executed. */ + size_t current_test = 0; + /* Number of tests executed. */ + size_t tests_executed = 0; + /* Number of failed tests. */ + size_t total_failed = 0; + /* Number of setup functions. */ + size_t setups = 0; + /* Number of teardown functions. */ + size_t teardowns = 0; + size_t i; + /* + * A stack of test states. A state is pushed on the stack + * when a test setup occurs and popped on tear down. + */ + TestState* test_states = + (TestState*)malloc(number_of_tests * sizeof(*test_states)); + /* The number of test states which should be 0 at the end */ + long number_of_test_states = 0; + /* Names of the tests that failed. */ + const char** failed_names = (const char**)malloc(number_of_tests * + sizeof(*failed_names)); + void **current_state = NULL; + + /* Count setup and teardown functions */ + for (i = 0; i < number_of_tests; i++) { + const UnitTest * const test = &tests[i]; + + if (test->function_type == UNIT_TEST_FUNCTION_TYPE_SETUP) { + setups++; + } + + if (test->function_type == UNIT_TEST_FUNCTION_TYPE_TEARDOWN) { + teardowns++; + } + } + + print_message("[==========] Running %"PRIdS " test(s).\n", + number_of_tests - setups - teardowns); + + /* Make sure LargestIntegralType is at least the size of a pointer. */ + assert_true(sizeof(LargestIntegralType) >= sizeof(void*)); + + while (current_test < number_of_tests) { + const ListNode *test_check_point = NULL; + TestState *current_TestState; + const UnitTest * const test = &tests[current_test++]; + if (!test->function) { + continue; + } + + switch (test->function_type) { + case UNIT_TEST_FUNCTION_TYPE_TEST: + if (! previous_setup_failed) { + run_next_test = 1; + } + break; + case UNIT_TEST_FUNCTION_TYPE_SETUP: { + /* Checkpoint the heap before the setup. */ + current_TestState = &test_states[number_of_test_states++]; + current_TestState->check_point = check_point_allocated_blocks(); + test_check_point = current_TestState->check_point; + current_state = ¤t_TestState->state; + *current_state = NULL; + run_next_test = 1; + break; + } + case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: + /* Check the heap based on the last setup checkpoint. */ + assert_true(number_of_test_states); + current_TestState = &test_states[--number_of_test_states]; + test_check_point = current_TestState->check_point; + current_state = ¤t_TestState->state; + break; + default: + print_error("Invalid unit test function type %d\n", + test->function_type); + exit_test(1); + break; + } + + if (run_next_test) { + int failed = _run_test(test->name, test->function, current_state, + test->function_type, test_check_point); + if (failed) { + failed_names[total_failed] = test->name; + } + + switch (test->function_type) { + case UNIT_TEST_FUNCTION_TYPE_TEST: + previous_test_failed = failed; + total_failed += failed; + tests_executed ++; + break; + + case UNIT_TEST_FUNCTION_TYPE_SETUP: + if (failed) { + total_failed ++; + tests_executed ++; + /* Skip forward until the next test or setup function. */ + run_next_test = 0; + previous_setup_failed = 1; + } + previous_test_failed = 0; + break; + + case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: + /* If this test failed. */ + if (failed && !previous_test_failed) { + total_failed ++; + } + break; + default: +#ifndef _HPUX + assert_null("BUG: shouldn't be here!"); +#endif + break; + } + } + } + + print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed); + print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed); + + if (total_failed > 0) { + print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed); + for (i = 0; i < total_failed; i++) { + print_error("[ FAILED ] %s\n", failed_names[i]); + } + } else { + print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed); + } + + if (number_of_test_states != 0) { + print_error("[ ERROR ] Mismatched number of setup %"PRIdS " and " + "teardown %"PRIdS " functions\n", setups, teardowns); + total_failed = (size_t)-1; + } + + free(test_states); + free((void*)failed_names); + + fail_if_blocks_allocated(check_point, "run_tests"); + return (int)total_failed; +} + +int _run_group_tests(const UnitTest * const tests, const size_t number_of_tests) +{ + UnitTestFunction setup = NULL; + const char *setup_name; + size_t num_setups = 0; + UnitTestFunction teardown = NULL; + const char *teardown_name = NULL; + size_t num_teardowns = 0; + size_t current_test = 0; + size_t i; + + /* Number of tests executed. */ + size_t tests_executed = 0; + /* Number of failed tests. */ + size_t total_failed = 0; + /* Check point of the heap state. */ + const ListNode * const check_point = check_point_allocated_blocks(); + const char **failed_names = NULL; + void **current_state = NULL; + TestState group_state = { + .check_point = NULL, + }; + + if (number_of_tests == 0) { + return -1; + } + + failed_names = (const char **)malloc(number_of_tests * + sizeof(*failed_names)); + if (failed_names == NULL) { + return -2; + } + + /* Find setup and teardown function */ + for (i = 0; i < number_of_tests; i++) { + const UnitTest * const test = &tests[i]; + + if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP) { + if (setup == NULL) { + setup = test->function; + setup_name = test->name; + num_setups = 1; + } else { + print_error("[ ERROR ] More than one group setup function detected\n"); + exit_test(1); + } + } + + if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN) { + if (teardown == NULL) { + teardown = test->function; + teardown_name = test->name; + num_teardowns = 1; + } else { + print_error("[ ERROR ] More than one group teardown function detected\n"); + exit_test(1); + } + } + } + + print_message("[==========] Running %"PRIdS " test(s).\n", + number_of_tests - num_setups - num_teardowns); + + if (setup != NULL) { + int failed; + + group_state.check_point = check_point_allocated_blocks(); + current_state = &group_state.state; + *current_state = NULL; + failed = _run_test(setup_name, + setup, + current_state, + UNIT_TEST_FUNCTION_TYPE_SETUP, + group_state.check_point); + if (failed) { + failed_names[total_failed] = setup_name; + } + + total_failed += failed; + tests_executed++; + } + + while (current_test < number_of_tests) { + int run_test = 0; + const UnitTest * const test = &tests[current_test++]; + if (test->function == NULL) { + continue; + } + + switch (test->function_type) { + case UNIT_TEST_FUNCTION_TYPE_TEST: + run_test = 1; + break; + case UNIT_TEST_FUNCTION_TYPE_SETUP: + case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: + case UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP: + case UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN: + break; + default: + print_error("Invalid unit test function type %d\n", + test->function_type); + break; + } + + if (run_test) { + int failed; + + failed = _run_test(test->name, + test->function, + current_state, + test->function_type, + NULL); + if (failed) { + failed_names[total_failed] = test->name; + } + + total_failed += failed; + tests_executed++; + } + } + + if (teardown != NULL) { + int failed; + + failed = _run_test(teardown_name, + teardown, + current_state, + UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN, + group_state.check_point); + if (failed) { + failed_names[total_failed] = teardown_name; + } + + total_failed += failed; + tests_executed++; + } + + print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed); + print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed); + + if (total_failed) { + print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed); + for (i = 0; i < total_failed; i++) { + print_error("[ FAILED ] %s\n", failed_names[i]); + } + } else { + print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed); + } + + free((void*)failed_names); + fail_if_blocks_allocated(check_point, "run_group_tests"); + + return (int)total_failed; +} diff --git a/ldb-2.0.8/third_party/cmocka/cmocka.h b/ldb-2.0.8/third_party/cmocka/cmocka.h new file mode 100644 index 0000000..e6861c8 --- /dev/null +++ b/ldb-2.0.8/third_party/cmocka/cmocka.h @@ -0,0 +1,2298 @@ +/* + * Copyright 2008 Google Inc. + * Copyright 2014-2018 Andreas Schneider + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef CMOCKA_H_ +#define CMOCKA_H_ + +#ifdef _WIN32 +# ifdef _MSC_VER + +#define __func__ __FUNCTION__ + +# ifndef inline +#define inline __inline +# endif /* inline */ + +# if _MSC_VER < 1500 +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ +int __stdcall IsDebuggerPresent(); +# ifdef __cplusplus +} /* extern "C" */ +# endif /* __cplusplus */ +# endif /* _MSC_VER < 1500 */ +# endif /* _MSC_VER */ +#endif /* _WIN32 */ + +/** + * @defgroup cmocka The CMocka API + * + * These headers or their equivalents should be included prior to including + * this header file. + * @code + * #include + * #include + * #include + * @endcode + * + * This allows test applications to use custom definitions of C standard + * library functions and types. + * + * @{ + */ + +/* If __WORDSIZE is not set, try to figure it out and default to 32 bit. */ +#ifndef __WORDSIZE +# if (defined(__x86_64__) && !defined(__ILP32__)) || defined(__sparc_v9__) || defined(__sparcv9) +# define __WORDSIZE 64 +# else +# define __WORDSIZE 32 +# endif +#endif + +#ifdef DOXYGEN +/** + * Largest integral type. This type should be large enough to hold any + * pointer or integer supported by the compiler. + */ +typedef uintmax_t LargestIntegralType; +#else /* DOXGEN */ +#ifndef LargestIntegralType +# if __WORDSIZE == 64 && !defined(_WIN64) +# define LargestIntegralType unsigned long int +# else +# define LargestIntegralType unsigned long long int +# endif +#endif /* LargestIntegralType */ +#endif /* DOXYGEN */ + +/* Printf format used to display LargestIntegralType as a hexidecimal. */ +#ifndef LargestIntegralTypePrintfFormat +# ifdef _WIN32 +# define LargestIntegralTypePrintfFormat "0x%I64x" +# else +# if __WORDSIZE == 64 +# define LargestIntegralTypePrintfFormat "%#lx" +# else +# define LargestIntegralTypePrintfFormat "%#llx" +# endif +# endif /* _WIN32 */ +#endif /* LargestIntegralTypePrintfFormat */ + +/* Printf format used to display LargestIntegralType as a decimal. */ +#ifndef LargestIntegralTypePrintfFormatDecimal +# ifdef _WIN32 +# define LargestIntegralTypePrintfFormatDecimal "%I64u" +# else +# if __WORDSIZE == 64 +# define LargestIntegralTypePrintfFormatDecimal "%lu" +# else +# define LargestIntegralTypePrintfFormatDecimal "%llu" +# endif +# endif /* _WIN32 */ +#endif /* LargestIntegralTypePrintfFormat */ + +/* Perform an unsigned cast to LargestIntegralType. */ +#define cast_to_largest_integral_type(value) \ + ((LargestIntegralType)(value)) + +/* Smallest integral type capable of holding a pointer. */ +#if !defined(_UINTPTR_T) && !defined(_UINTPTR_T_DEFINED) +# if defined(_WIN32) + /* WIN32 is an ILP32 platform */ + typedef unsigned int uintptr_t; +# elif defined(_WIN64) + typedef unsigned long int uintptr_t +# else /* _WIN32 */ + +/* ILP32 and LP64 platforms */ +# ifdef __WORDSIZE /* glibc */ +# if __WORDSIZE == 64 + typedef unsigned long int uintptr_t; +# else + typedef unsigned int uintptr_t; +# endif /* __WORDSIZE == 64 */ +# else /* __WORDSIZE */ +# if defined(_LP64) || defined(_I32LPx) + typedef unsigned long int uintptr_t; +# else + typedef unsigned int uintptr_t; +# endif +# endif /* __WORDSIZE */ +# endif /* _WIN32 */ + +# define _UINTPTR_T +# define _UINTPTR_T_DEFINED +#endif /* !defined(_UINTPTR_T) || !defined(_UINTPTR_T_DEFINED) */ + +/* Perform an unsigned cast to uintptr_t. */ +#define cast_to_pointer_integral_type(value) \ + ((uintptr_t)((size_t)(value))) + +/* Perform a cast of a pointer to LargestIntegralType */ +#define cast_ptr_to_largest_integral_type(value) \ +cast_to_largest_integral_type(cast_to_pointer_integral_type(value)) + +/* GCC have printf type attribute check. */ +#ifdef __GNUC__ +#define CMOCKA_PRINTF_ATTRIBUTE(a,b) \ + __attribute__ ((__format__ (__printf__, a, b))) +#else +#define CMOCKA_PRINTF_ATTRIBUTE(a,b) +#endif /* __GNUC__ */ + +#if defined(__GNUC__) +#define CMOCKA_DEPRECATED __attribute__ ((deprecated)) +#elif defined(_MSC_VER) +#define CMOCKA_DEPRECATED __declspec(deprecated) +#else +#define CMOCKA_DEPRECATED +#endif + +#define WILL_RETURN_ALWAYS -1 +#define WILL_RETURN_ONCE -2 + +/** + * @defgroup cmocka_mock Mock Objects + * @ingroup cmocka + * + * Mock objects mock objects are simulated objects that mimic the behavior of + * real objects. Instead of calling the real objects, the tested object calls a + * mock object that merely asserts that the correct methods were called, with + * the expected parameters, in the correct order. + * + *

        + *
      • will_return(function, value) - The will_return() macro + * pushes a value onto a stack of mock values. This macro is intended to be + * used by the unit test itself, while programming the behaviour of the mocked + * object.
      • + * + *
      • mock() - the mock macro pops a value from a stack of + * test values. The user of the mock() macro is the mocked object that uses it + * to learn how it should behave.
      • + *
      + * + * Because the will_return() and mock() are intended to be used in pairs, the + * cmocka library would fail the test if there are more values pushed onto the + * stack using will_return() than consumed with mock() and vice-versa. + * + * The following unit test stub illustrates how would a unit test instruct the + * mock object to return a particular value: + * + * @code + * will_return(chef_cook, "hotdog"); + * will_return(chef_cook, 0); + * @endcode + * + * Now the mock object can check if the parameter it received is the parameter + * which is expected by the test driver. This can be done the following way: + * + * @code + * int chef_cook(const char *order, char **dish_out) + * { + * check_expected(order); + * } + * @endcode + * + * For a complete example please at a look + * here. + * + * @{ + */ + +#ifdef DOXYGEN +/** + * @brief Retrieve a return value of the current function. + * + * @return The value which was stored to return by this function. + * + * @see will_return() + */ +LargestIntegralType mock(void); +#else +#define mock() _mock(__func__, __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Retrieve a typed return value of the current function. + * + * The value would be casted to type internally to avoid having the + * caller to do the cast manually. + * + * @param[in] #type The expected type of the return value + * + * @return The value which was stored to return by this function. + * + * @code + * int param; + * + * param = mock_type(int); + * @endcode + * + * @see will_return() + * @see mock() + * @see mock_ptr_type() + */ +#type mock_type(#type); +#else +#define mock_type(type) ((type) mock()) +#endif + +#ifdef DOXYGEN +/** + * @brief Retrieve a typed return value of the current function. + * + * The value would be casted to type internally to avoid having the + * caller to do the cast manually but also casted to uintptr_t to make + * sure the result has a valid size to be used as a pointer. + * + * @param[in] #type The expected type of the return value + * + * @return The value which was stored to return by this function. + * + * @code + * char *param; + * + * param = mock_ptr_type(char *); + * @endcode + * + * @see will_return() + * @see mock() + * @see mock_type() + */ +type mock_ptr_type(#type); +#else +#define mock_ptr_type(type) ((type) (uintptr_t) mock()) +#endif + + +#ifdef DOXYGEN +/** + * @brief Store a value to be returned by mock() later. + * + * @param[in] #function The function which should return the given value. + * + * @param[in] value The value to be returned by mock(). + * + * @code + * int return_integer(void) + * { + * return (int)mock(); + * } + * + * static void test_integer_return(void **state) + * { + * will_return(return_integer, 42); + * + * assert_int_equal(my_function_calling_return_integer(), 42); + * } + * @endcode + * + * @see mock() + * @see will_return_count() + */ +void will_return(#function, LargestIntegralType value); +#else +#define will_return(function, value) \ + _will_return(#function, __FILE__, __LINE__, \ + cast_to_largest_integral_type(value), 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a value to be returned by mock() later. + * + * @param[in] #function The function which should return the given value. + * + * @param[in] value The value to be returned by mock(). + * + * @param[in] count The parameter indicates the number of times the value should + * be returned by mock(). If count is set to -1, the value + * will always be returned but must be returned at least once. + * If count is set to -2, the value will always be returned + * by mock(), but is not required to be returned. + * + * @see mock() + */ +void will_return_count(#function, LargestIntegralType value, int count); +#else +#define will_return_count(function, value, count) \ + _will_return(#function, __FILE__, __LINE__, \ + cast_to_largest_integral_type(value), count) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a value that will be always returned by mock(). + * + * @param[in] #function The function which should return the given value. + * + * @param[in] #value The value to be returned by mock(). + * + * This is equivalent to: + * @code + * will_return_count(function, value, -1); + * @endcode + * + * @see will_return_count() + * @see mock() + */ +void will_return_always(#function, LargestIntegralType value); +#else +#define will_return_always(function, value) \ + will_return_count(function, (value), WILL_RETURN_ALWAYS) +#endif + +#ifdef DOXYGEN +/** + * @brief Store a value that may be always returned by mock(). + * + * This stores a value which will always be returned by mock() but is not + * required to be returned by at least one call to mock(). Therefore, + * in contrast to will_return_always() which causes a test failure if it + * is not returned at least once, will_return_maybe() will never cause a test + * to fail if its value is not returned. + * + * @param[in] #function The function which should return the given value. + * + * @param[in] #value The value to be returned by mock(). + * + * This is equivalent to: + * @code + * will_return_count(function, value, -2); + * @endcode + * + * @see will_return_count() + * @see mock() + */ +void will_return_maybe(#function, LargestIntegralType value); +#else +#define will_return_maybe(function, value) \ + will_return_count(function, (value), WILL_RETURN_ONCE) +#endif +/** @} */ + +/** + * @defgroup cmocka_param Checking Parameters + * @ingroup cmocka + * + * Functionality to store expected values for mock function parameters. + * + * In addition to storing the return values of mock functions, cmocka provides + * functionality to store expected values for mock function parameters using + * the expect_*() functions provided. A mock function parameter can then be + * validated using the check_expected() macro. + * + * Successive calls to expect_*() macros for a parameter queues values to check + * the specified parameter. check_expected() checks a function parameter + * against the next value queued using expect_*(), if the parameter check fails + * a test failure is signalled. In addition if check_expected() is called and + * no more parameter values are queued a test failure occurs. + * + * The following test stub illustrates how to do this. First is the the function + * we call in the test driver: + * + * @code + * static void test_driver(void **state) + * { + * expect_string(chef_cook, order, "hotdog"); + * } + * @endcode + * + * Now the chef_cook function can check if the parameter we got passed is the + * parameter which is expected by the test driver. This can be done the + * following way: + * + * @code + * int chef_cook(const char *order, char **dish_out) + * { + * check_expected(order); + * } + * @endcode + * + * For a complete example please at a look at + * here + * + * @{ + */ + +/* + * Add a custom parameter checking function. If the event parameter is NULL + * the event structure is allocated internally by this function. If event + * parameter is provided it must be allocated on the heap and doesn't need to + * be deallocated by the caller. + */ +#ifdef DOXYGEN +/** + * @brief Add a custom parameter checking function. + * + * If the event parameter is NULL the event structure is allocated internally + * by this function. If the parameter is provided it must be allocated on the + * heap and doesn't need to be deallocated by the caller. + * + * @param[in] #function The function to add a custom parameter checking + * function for. + * + * @param[in] #parameter The parameters passed to the function. + * + * @param[in] #check_function The check function to call. + * + * @param[in] check_data The data to pass to the check function. + */ +void expect_check(#function, #parameter, #check_function, const void *check_data); +#else +#define expect_check(function, parameter, check_function, check_data) \ + _expect_check(#function, #parameter, __FILE__, __LINE__, check_function, \ + cast_to_largest_integral_type(check_data), NULL, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter value is part of the provided + * array. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] value_array[] The array to check for the value. + * + * @see check_expected(). + */ +void expect_in_set(#function, #parameter, LargestIntegralType value_array[]); +#else +#define expect_in_set(function, parameter, value_array) \ + expect_in_set_count(function, parameter, value_array, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter value is part of the provided + * array. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] value_array[] The array to check for the value. + * + * @param[in] count The count parameter returns the number of times the value + * should be returned by check_expected(). If count is set + * to -1 the value will always be returned. + * + * @see check_expected(). + */ +void expect_in_set_count(#function, #parameter, LargestIntegralType value_array[], size_t count); +#else +#define expect_in_set_count(function, parameter, value_array, count) \ + _expect_in_set(#function, #parameter, __FILE__, __LINE__, value_array, \ + sizeof(value_array) / sizeof((value_array)[0]), count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter value is not part of the + * provided array. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] value_array[] The array to check for the value. + * + * @see check_expected(). + */ +void expect_not_in_set(#function, #parameter, LargestIntegralType value_array[]); +#else +#define expect_not_in_set(function, parameter, value_array) \ + expect_not_in_set_count(function, parameter, value_array, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter value is not part of the + * provided array. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] value_array[] The array to check for the value. + * + * @param[in] count The count parameter returns the number of times the value + * should be returned by check_expected(). If count is set + * to -1 the value will always be returned. + * + * @see check_expected(). + */ +void expect_not_in_set_count(#function, #parameter, LargestIntegralType value_array[], size_t count); +#else +#define expect_not_in_set_count(function, parameter, value_array, count) \ + _expect_not_in_set( \ + #function, #parameter, __FILE__, __LINE__, value_array, \ + sizeof(value_array) / sizeof((value_array)[0]), count) +#endif + + +#ifdef DOXYGEN +/** + * @brief Add an event to check a parameter is inside a numerical range. + * The check would succeed if minimum <= value <= maximum. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] minimum The lower boundary of the interval to check against. + * + * @param[in] maximum The upper boundary of the interval to check against. + * + * @see check_expected(). + */ +void expect_in_range(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum); +#else +#define expect_in_range(function, parameter, minimum, maximum) \ + expect_in_range_count(function, parameter, minimum, maximum, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check a parameter is inside a + * numerical range. The check would succeed if minimum <= value <= maximum. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] minimum The lower boundary of the interval to check against. + * + * @param[in] maximum The upper boundary of the interval to check against. + * + * @param[in] count The count parameter returns the number of times the value + * should be returned by check_expected(). If count is set + * to -1 the value will always be returned. + * + * @see check_expected(). + */ +void expect_in_range_count(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum, size_t count); +#else +#define expect_in_range_count(function, parameter, minimum, maximum, count) \ + _expect_in_range(#function, #parameter, __FILE__, __LINE__, minimum, \ + maximum, count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check a parameter is outside a numerical range. + * The check would succeed if minimum > value > maximum. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] minimum The lower boundary of the interval to check against. + * + * @param[in] maximum The upper boundary of the interval to check against. + * + * @see check_expected(). + */ +void expect_not_in_range(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum); +#else +#define expect_not_in_range(function, parameter, minimum, maximum) \ + expect_not_in_range_count(function, parameter, minimum, maximum, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check a parameter is outside a + * numerical range. The check would succeed if minimum > value > maximum. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] minimum The lower boundary of the interval to check against. + * + * @param[in] maximum The upper boundary of the interval to check against. + * + * @param[in] count The count parameter returns the number of times the value + * should be returned by check_expected(). If count is set + * to -1 the value will always be returned. + * + * @see check_expected(). + */ +void expect_not_in_range_count(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum, size_t count); +#else +#define expect_not_in_range_count(function, parameter, minimum, maximum, \ + count) \ + _expect_not_in_range(#function, #parameter, __FILE__, __LINE__, \ + minimum, maximum, count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if a parameter is the given value. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] value The value to check. + * + * @see check_expected(). + */ +void expect_value(#function, #parameter, LargestIntegralType value); +#else +#define expect_value(function, parameter, value) \ + expect_value_count(function, parameter, value, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check if a parameter is the given value. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] value The value to check. + * + * @param[in] count The count parameter returns the number of times the value + * should be returned by check_expected(). If count is set + * to -1 the value will always be returned. + * + * @see check_expected(). + */ +void expect_value_count(#function, #parameter, LargestIntegralType value, size_t count); +#else +#define expect_value_count(function, parameter, value, count) \ + _expect_value(#function, #parameter, __FILE__, __LINE__, \ + cast_to_largest_integral_type(value), count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if a parameter isn't the given value. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] value The value to check. + * + * @see check_expected(). + */ +void expect_not_value(#function, #parameter, LargestIntegralType value); +#else +#define expect_not_value(function, parameter, value) \ + expect_not_value_count(function, parameter, value, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check if a parameter isn't the given value. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] value The value to check. + * + * @param[in] count The count parameter returns the number of times the value + * should be returned by check_expected(). If count is set + * to -1 the value will always be returned. + * + * @see check_expected(). + */ +void expect_not_value_count(#function, #parameter, LargestIntegralType value, size_t count); +#else +#define expect_not_value_count(function, parameter, value, count) \ + _expect_not_value(#function, #parameter, __FILE__, __LINE__, \ + cast_to_largest_integral_type(value), count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter value is equal to the + * provided string. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] string The string value to compare. + * + * @see check_expected(). + */ +void expect_string(#function, #parameter, const char *string); +#else +#define expect_string(function, parameter, string) \ + expect_string_count(function, parameter, string, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter value is equal to the + * provided string. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] string The string value to compare. + * + * @param[in] count The count parameter returns the number of times the value + * should be returned by check_expected(). If count is set + * to -1 the value will always be returned. + * + * @see check_expected(). + */ +void expect_string_count(#function, #parameter, const char *string, size_t count); +#else +#define expect_string_count(function, parameter, string, count) \ + _expect_string(#function, #parameter, __FILE__, __LINE__, \ + (const char*)(string), count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter value isn't equal to the + * provided string. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] string The string value to compare. + * + * @see check_expected(). + */ +void expect_not_string(#function, #parameter, const char *string); +#else +#define expect_not_string(function, parameter, string) \ + expect_not_string_count(function, parameter, string, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter value isn't equal to the + * provided string. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] string The string value to compare. + * + * @param[in] count The count parameter returns the number of times the value + * should be returned by check_expected(). If count is set + * to -1 the value will always be returned. + * + * @see check_expected(). + */ +void expect_not_string_count(#function, #parameter, const char *string, size_t count); +#else +#define expect_not_string_count(function, parameter, string, count) \ + _expect_not_string(#function, #parameter, __FILE__, __LINE__, \ + (const char*)(string), count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter does match an area of memory. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] memory The memory to compare. + * + * @param[in] size The size of the memory to compare. + * + * @see check_expected(). + */ +void expect_memory(#function, #parameter, void *memory, size_t size); +#else +#define expect_memory(function, parameter, memory, size) \ + expect_memory_count(function, parameter, memory, size, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check if the parameter does match an area + * of memory. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] memory The memory to compare. + * + * @param[in] size The size of the memory to compare. + * + * @param[in] count The count parameter returns the number of times the value + * should be returned by check_expected(). If count is set + * to -1 the value will always be returned. + * + * @see check_expected(). + */ +void expect_memory_count(#function, #parameter, void *memory, size_t size, size_t count); +#else +#define expect_memory_count(function, parameter, memory, size, count) \ + _expect_memory(#function, #parameter, __FILE__, __LINE__, \ + (const void*)(memory), size, count) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to check if the parameter doesn't match an area of + * memory. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] memory The memory to compare. + * + * @param[in] size The size of the memory to compare. + * + * @see check_expected(). + */ +void expect_not_memory(#function, #parameter, void *memory, size_t size); +#else +#define expect_not_memory(function, parameter, memory, size) \ + expect_not_memory_count(function, parameter, memory, size, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check if the parameter doesn't match an + * area of memory. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] memory The memory to compare. + * + * @param[in] size The size of the memory to compare. + * + * @param[in] count The count parameter returns the number of times the value + * should be returned by check_expected(). If count is set + * to -1 the value will always be returned. + * + * @see check_expected(). + */ +void expect_not_memory_count(#function, #parameter, void *memory, size_t size, size_t count); +#else +#define expect_not_memory_count(function, parameter, memory, size, count) \ + _expect_not_memory(#function, #parameter, __FILE__, __LINE__, \ + (const void*)(memory), size, count) +#endif + + +#ifdef DOXYGEN +/** + * @brief Add an event to check if a parameter (of any value) has been passed. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @see check_expected(). + */ +void expect_any(#function, #parameter); +#else +#define expect_any(function, parameter) \ + expect_any_count(function, parameter, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Add an event to repeatedly check if a parameter (of any value) has + * been passed. + * + * The event is triggered by calling check_expected() in the mocked function. + * + * @param[in] #function The function to add the check for. + * + * @param[in] #parameter The name of the parameter passed to the function. + * + * @param[in] count The count parameter returns the number of times the value + * should be returned by check_expected(). If count is set + * to -1 the value will always be returned. + * + * @see check_expected(). + */ +void expect_any_count(#function, #parameter, size_t count); +#else +#define expect_any_count(function, parameter, count) \ + _expect_any(#function, #parameter, __FILE__, __LINE__, count) +#endif + +#ifdef DOXYGEN +/** + * @brief Determine whether a function parameter is correct. + * + * This ensures the next value queued by one of the expect_*() macros matches + * the specified variable. + * + * This function needs to be called in the mock object. + * + * @param[in] #parameter The parameter to check. + */ +void check_expected(#parameter); +#else +#define check_expected(parameter) \ + _check_expected(__func__, #parameter, __FILE__, __LINE__, \ + cast_to_largest_integral_type(parameter)) +#endif + +#ifdef DOXYGEN +/** + * @brief Determine whether a function parameter is correct. + * + * This ensures the next value queued by one of the expect_*() macros matches + * the specified variable. + * + * This function needs to be called in the mock object. + * + * @param[in] #parameter The pointer to check. + */ +void check_expected_ptr(#parameter); +#else +#define check_expected_ptr(parameter) \ + _check_expected(__func__, #parameter, __FILE__, __LINE__, \ + cast_ptr_to_largest_integral_type(parameter)) +#endif + +/** @} */ + +/** + * @defgroup cmocka_asserts Assert Macros + * @ingroup cmocka + * + * This is a set of useful assert macros like the standard C libary's + * assert(3) macro. + * + * On an assertion failure a cmocka assert macro will write the failure to the + * standard error stream and signal a test failure. Due to limitations of the C + * language the general C standard library assert() and cmocka's assert_true() + * and assert_false() macros can only display the expression that caused the + * assert failure. cmocka's type specific assert macros, assert_{type}_equal() + * and assert_{type}_not_equal(), display the data that caused the assertion + * failure which increases data visibility aiding debugging of failing test + * cases. + * + * @{ + */ + +#ifdef DOXYGEN +/** + * @brief Assert that the given expression is true. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if expression is false (i.e., compares equal to + * zero). + * + * @param[in] expression The expression to evaluate. + * + * @see assert_int_equal() + * @see assert_string_equal() + */ +void assert_true(scalar expression); +#else +#define assert_true(c) _assert_true(cast_to_largest_integral_type(c), #c, \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the given expression is false. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if expression is true. + * + * @param[in] expression The expression to evaluate. + * + * @see assert_int_equal() + * @see assert_string_equal() + */ +void assert_false(scalar expression); +#else +#define assert_false(c) _assert_true(!(cast_to_largest_integral_type(c)), #c, \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the return_code is greater than or equal to 0. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the return code is smaller than 0. If the function + * you check sets an errno if it fails you can pass it to the function and + * it will be printed as part of the error message. + * + * @param[in] rc The return code to evaluate. + * + * @param[in] error Pass errno here or 0. + */ +void assert_return_code(int rc, int error); +#else +#define assert_return_code(rc, error) \ + _assert_return_code(cast_to_largest_integral_type(rc), \ + sizeof(rc), \ + cast_to_largest_integral_type(error), \ + #rc, __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the given pointer is non-NULL. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the pointer is NULL. + * + * @param[in] pointer The pointer to evaluate. + * + * @see assert_null() + */ +void assert_non_null(void *pointer); +#else +#define assert_non_null(c) _assert_true(cast_ptr_to_largest_integral_type(c), #c, \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the given pointer is NULL. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the pointer is non-NULL. + * + * @param[in] pointer The pointer to evaluate. + * + * @see assert_non_null() + */ +void assert_null(void *pointer); +#else +#define assert_null(c) _assert_true(!(cast_ptr_to_largest_integral_type(c)), #c, \ +__FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given pointers are equal. + * + * The function prints an error message and terminates the test by calling + * fail() if the pointers are not equal. + * + * @param[in] a The first pointer to compare. + * + * @param[in] b The pointer to compare against the first one. + */ +void assert_ptr_equal(void *a, void *b); +#else +#define assert_ptr_equal(a, b) \ + _assert_int_equal(cast_ptr_to_largest_integral_type(a), \ + cast_ptr_to_largest_integral_type(b), \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given pointers are not equal. + * + * The function prints an error message and terminates the test by calling + * fail() if the pointers are equal. + * + * @param[in] a The first pointer to compare. + * + * @param[in] b The pointer to compare against the first one. + */ +void assert_ptr_not_equal(void *a, void *b); +#else +#define assert_ptr_not_equal(a, b) \ + _assert_int_not_equal(cast_ptr_to_largest_integral_type(a), \ + cast_ptr_to_largest_integral_type(b), \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given integers are equal. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the integers are not equal. + * + * @param[in] a The first integer to compare. + * + * @param[in] b The integer to compare against the first one. + */ +void assert_int_equal(int a, int b); +#else +#define assert_int_equal(a, b) \ + _assert_int_equal(cast_to_largest_integral_type(a), \ + cast_to_largest_integral_type(b), \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given integers are not equal. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the integers are equal. + * + * @param[in] a The first integer to compare. + * + * @param[in] b The integer to compare against the first one. + * + * @see assert_int_equal() + */ +void assert_int_not_equal(int a, int b); +#else +#define assert_int_not_equal(a, b) \ + _assert_int_not_equal(cast_to_largest_integral_type(a), \ + cast_to_largest_integral_type(b), \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given strings are equal. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the strings are not equal. + * + * @param[in] a The string to check. + * + * @param[in] b The other string to compare. + */ +void assert_string_equal(const char *a, const char *b); +#else +#define assert_string_equal(a, b) \ + _assert_string_equal((const char*)(a), (const char*)(b), __FILE__, \ + __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given strings are not equal. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the strings are equal. + * + * @param[in] a The string to check. + * + * @param[in] b The other string to compare. + */ +void assert_string_not_equal(const char *a, const char *b); +#else +#define assert_string_not_equal(a, b) \ + _assert_string_not_equal((const char*)(a), (const char*)(b), __FILE__, \ + __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given areas of memory are equal, otherwise fail. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the memory is not equal. + * + * @param[in] a The first memory area to compare + * (interpreted as unsigned char). + * + * @param[in] b The second memory area to compare + * (interpreted as unsigned char). + * + * @param[in] size The first n bytes of the memory areas to compare. + */ +void assert_memory_equal(const void *a, const void *b, size_t size); +#else +#define assert_memory_equal(a, b, size) \ + _assert_memory_equal((const void*)(a), (const void*)(b), size, __FILE__, \ + __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the two given areas of memory are not equal. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if the memory is equal. + * + * @param[in] a The first memory area to compare + * (interpreted as unsigned char). + * + * @param[in] b The second memory area to compare + * (interpreted as unsigned char). + * + * @param[in] size The first n bytes of the memory areas to compare. + */ +void assert_memory_not_equal(const void *a, const void *b, size_t size); +#else +#define assert_memory_not_equal(a, b, size) \ + _assert_memory_not_equal((const void*)(a), (const void*)(b), size, \ + __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the specified value is not smaller than the minimum + * and and not greater than the maximum. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if value is not in range. + * + * @param[in] value The value to check. + * + * @param[in] minimum The minimum value allowed. + * + * @param[in] maximum The maximum value allowed. + */ +void assert_in_range(LargestIntegralType value, LargestIntegralType minimum, LargestIntegralType maximum); +#else +#define assert_in_range(value, minimum, maximum) \ + _assert_in_range( \ + cast_to_largest_integral_type(value), \ + cast_to_largest_integral_type(minimum), \ + cast_to_largest_integral_type(maximum), __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the specified value is smaller than the minimum or + * greater than the maximum. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if value is in range. + * + * @param[in] value The value to check. + * + * @param[in] minimum The minimum value to compare. + * + * @param[in] maximum The maximum value to compare. + */ +void assert_not_in_range(LargestIntegralType value, LargestIntegralType minimum, LargestIntegralType maximum); +#else +#define assert_not_in_range(value, minimum, maximum) \ + _assert_not_in_range( \ + cast_to_largest_integral_type(value), \ + cast_to_largest_integral_type(minimum), \ + cast_to_largest_integral_type(maximum), __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the specified value is within a set. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if value is not within a set. + * + * @param[in] value The value to look up + * + * @param[in] values[] The array to check for the value. + * + * @param[in] count The size of the values array. + */ +void assert_in_set(LargestIntegralType value, LargestIntegralType values[], size_t count); +#else +#define assert_in_set(value, values, number_of_values) \ + _assert_in_set(value, values, number_of_values, __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Assert that the specified value is not within a set. + * + * The function prints an error message to standard error and terminates the + * test by calling fail() if value is within a set. + * + * @param[in] value The value to look up + * + * @param[in] values[] The array to check for the value. + * + * @param[in] count The size of the values array. + */ +void assert_not_in_set(LargestIntegralType value, LargestIntegralType values[], size_t count); +#else +#define assert_not_in_set(value, values, number_of_values) \ + _assert_not_in_set(value, values, number_of_values, __FILE__, __LINE__) +#endif + +/** @} */ + +/** + * @defgroup cmocka_call_order Call Ordering + * @ingroup cmocka + * + * It is often beneficial to make sure that functions are called in an + * order. This is independent of mock returns and parameter checking as both + * of the aforementioned do not check the order in which they are called from + * different functions. + * + *
        + *
      • expect_function_call(function) - The + * expect_function_call() macro pushes an expectation onto the stack of + * expected calls.
      • + * + *
      • function_called() - pops a value from the stack of + * expected calls. function_called() is invoked within the mock object + * that uses it. + *
      + * + * expect_function_call() and function_called() are intended to be used in + * pairs. Cmocka will fail a test if there are more or less expected calls + * created (e.g. expect_function_call()) than consumed with function_called(). + * There are provisions such as ignore_function_calls() which allow this + * restriction to be circumvented in tests where mock calls for the code under + * test are not the focus of the test. + * + * The following example illustrates how a unit test instructs cmocka + * to expect a function_called() from a particular mock, + * chef_sing(): + * + * @code + * void chef_sing(void); + * + * void code_under_test() + * { + * chef_sing(); + * } + * + * void some_test(void **state) + * { + * expect_function_call(chef_sing); + * code_under_test(); + * } + * @endcode + * + * The implementation of the mock then must check whether it was meant to + * be called by invoking function_called(): + * + * @code + * void chef_sing() + * { + * function_called(); + * } + * @endcode + * + * @{ + */ + +#ifdef DOXYGEN +/** + * @brief Check that current mocked function is being called in the expected + * order + * + * @see expect_function_call() + */ +void function_called(void); +#else +#define function_called() _function_called(__func__, __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Store expected call(s) to a mock to be checked by function_called() + * later. + * + * @param[in] #function The function which should should be called + * + * @param[in] times number of times this mock must be called + * + * @see function_called() + */ +void expect_function_calls(#function, const int times); +#else +#define expect_function_calls(function, times) \ + _expect_function_call(#function, __FILE__, __LINE__, times) +#endif + +#ifdef DOXYGEN +/** + * @brief Store expected single call to a mock to be checked by + * function_called() later. + * + * @param[in] #function The function which should should be called + * + * @see function_called() + */ +void expect_function_call(#function); +#else +#define expect_function_call(function) \ + _expect_function_call(#function, __FILE__, __LINE__, 1) +#endif + +#ifdef DOXYGEN +/** + * @brief Expects function_called() from given mock at least once + * + * @param[in] #function The function which should should be called + * + * @see function_called() + */ +void expect_function_call_any(#function); +#else +#define expect_function_call_any(function) \ + _expect_function_call(#function, __FILE__, __LINE__, -1) +#endif + +#ifdef DOXYGEN +/** + * @brief Ignores function_called() invocations from given mock function. + * + * @param[in] #function The function which should should be called + * + * @see function_called() + */ +void ignore_function_calls(#function); +#else +#define ignore_function_calls(function) \ + _expect_function_call(#function, __FILE__, __LINE__, -2) +#endif + +/** @} */ + +/** + * @defgroup cmocka_exec Running Tests + * @ingroup cmocka + * + * This is the way tests are executed with CMocka. + * + * The following example illustrates this macro's use with the unit_test macro. + * + * @code + * void Test0(void **state); + * void Test1(void **state); + * + * int main(void) + * { + * const struct CMUnitTest tests[] = { + * cmocka_unit_test(Test0), + * cmocka_unit_test(Test1), + * }; + * + * return cmocka_run_group_tests(tests, NULL, NULL); + * } + * @endcode + * + * @{ + */ + +#ifdef DOXYGEN +/** + * @brief Forces the test to fail immediately and quit. + */ +void fail(void); +#else +#define fail() _fail(__FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Forces the test to not be executed, but marked as skipped + */ +void skip(void); +#else +#define skip() _skip(__FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Forces the test to fail immediately and quit, printing the reason. + * + * @code + * fail_msg("This is some error message for test"); + * @endcode + * + * or + * + * @code + * char *error_msg = "This is some error message for test"; + * fail_msg("%s", error_msg); + * @endcode + */ +void fail_msg(const char *msg, ...); +#else +#define fail_msg(msg, ...) do { \ + print_error("ERROR: " msg "\n", ##__VA_ARGS__); \ + fail(); \ +} while (0) +#endif + +#ifdef DOXYGEN +/** + * @brief Generic method to run a single test. + * + * @deprecated This function was deprecated in favor of cmocka_run_group_tests + * + * @param[in] #function The function to test. + * + * @return 0 on success, 1 if an error occured. + * + * @code + * // A test case that does nothing and succeeds. + * void null_test_success(void **state) { + * } + * + * int main(void) { + * return run_test(null_test_success); + * } + * @endcode + */ +int run_test(#function); +#else +#define run_test(f) _run_test(#f, f, NULL, UNIT_TEST_FUNCTION_TYPE_TEST, NULL) +#endif + +static inline void _unit_test_dummy(void **state) { + (void)state; +} + +/** Initializes a UnitTest structure. + * + * @deprecated This function was deprecated in favor of cmocka_unit_test + */ +#define unit_test(f) { #f, f, UNIT_TEST_FUNCTION_TYPE_TEST } + +#define _unit_test_setup(test, setup) \ + { #test "_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_SETUP } + +/** Initializes a UnitTest structure with a setup function. + * + * @deprecated This function was deprecated in favor of cmocka_unit_test_setup + */ +#define unit_test_setup(test, setup) \ + _unit_test_setup(test, setup), \ + unit_test(test), \ + _unit_test_teardown(test, _unit_test_dummy) + +#define _unit_test_teardown(test, teardown) \ + { #test "_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_TEARDOWN } + +/** Initializes a UnitTest structure with a teardown function. + * + * @deprecated This function was deprecated in favor of cmocka_unit_test_teardown + */ +#define unit_test_teardown(test, teardown) \ + _unit_test_setup(test, _unit_test_dummy), \ + unit_test(test), \ + _unit_test_teardown(test, teardown) + +/** Initializes a UnitTest structure for a group setup function. + * + * @deprecated This function was deprecated in favor of cmocka_run_group_tests + */ +#define group_test_setup(setup) \ + { "group_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP } + +/** Initializes a UnitTest structure for a group teardown function. + * + * @deprecated This function was deprecated in favor of cmocka_run_group_tests + */ +#define group_test_teardown(teardown) \ + { "group_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN } + +/** + * Initialize an array of UnitTest structures with a setup function for a test + * and a teardown function. Either setup or teardown can be NULL. + * + * @deprecated This function was deprecated in favor of + * cmocka_unit_test_setup_teardown + */ +#define unit_test_setup_teardown(test, setup, teardown) \ + _unit_test_setup(test, setup), \ + unit_test(test), \ + _unit_test_teardown(test, teardown) + + +/** Initializes a CMUnitTest structure. */ +#define cmocka_unit_test(f) { #f, f, NULL, NULL, NULL } + +/** Initializes a CMUnitTest structure with a setup function. */ +#define cmocka_unit_test_setup(f, setup) { #f, f, setup, NULL, NULL } + +/** Initializes a CMUnitTest structure with a teardown function. */ +#define cmocka_unit_test_teardown(f, teardown) { #f, f, NULL, teardown, NULL } + +/** + * Initialize an array of CMUnitTest structures with a setup function for a test + * and a teardown function. Either setup or teardown can be NULL. + */ +#define cmocka_unit_test_setup_teardown(f, setup, teardown) { #f, f, setup, teardown, NULL } + +/** + * Initialize a CMUnitTest structure with given initial state. It will be passed + * to test function as an argument later. It can be used when test state does + * not need special initialization or was initialized already. + * @note If the group setup function initialized the state already, it won't be + * overridden by the initial state defined here. + */ +#define cmocka_unit_test_prestate(f, state) { #f, f, NULL, NULL, state } + +/** + * Initialize a CMUnitTest structure with given initial state, setup and + * teardown function. Any of these values can be NULL. Initial state is passed + * later to setup function, or directly to test if none was given. + * @note If the group setup function initialized the state already, it won't be + * overridden by the initial state defined here. + */ +#define cmocka_unit_test_prestate_setup_teardown(f, setup, teardown, state) { #f, f, setup, teardown, state } + +#define run_tests(tests) _run_tests(tests, sizeof(tests) / sizeof((tests)[0])) +#define run_group_tests(tests) _run_group_tests(tests, sizeof(tests) / sizeof((tests)[0])) + +#ifdef DOXYGEN +/** + * @brief Run tests specified by an array of CMUnitTest structures. + * + * @param[in] group_tests[] The array of unit tests to execute. + * + * @param[in] group_setup The setup function which should be called before + * all unit tests are executed. + * + * @param[in] group_teardown The teardown function to be called after all + * tests have finished. + * + * @return 0 on success, or the number of failed tests. + * + * @code + * static int setup(void **state) { + * int *answer = malloc(sizeof(int)); + * if (*answer == NULL) { + * return -1; + * } + * *answer = 42; + * + * *state = answer; + * + * return 0; + * } + * + * static int teardown(void **state) { + * free(*state); + * + * return 0; + * } + * + * static void null_test_success(void **state) { + * (void) state; + * } + * + * static void int_test_success(void **state) { + * int *answer = *state; + * assert_int_equal(*answer, 42); + * } + * + * int main(void) { + * const struct CMUnitTest tests[] = { + * cmocka_unit_test(null_test_success), + * cmocka_unit_test_setup_teardown(int_test_success, setup, teardown), + * }; + * + * return cmocka_run_group_tests(tests, NULL, NULL); + * } + * @endcode + * + * @see cmocka_unit_test + * @see cmocka_unit_test_setup + * @see cmocka_unit_test_teardown + * @see cmocka_unit_test_setup_teardown + */ +int cmocka_run_group_tests(const struct CMUnitTest group_tests[], + CMFixtureFunction group_setup, + CMFixtureFunction group_teardown); +#else +# define cmocka_run_group_tests(group_tests, group_setup, group_teardown) \ + _cmocka_run_group_tests(#group_tests, group_tests, sizeof(group_tests) / sizeof((group_tests)[0]), group_setup, group_teardown) +#endif + +#ifdef DOXYGEN +/** + * @brief Run tests specified by an array of CMUnitTest structures and specify + * a name. + * + * @param[in] group_name The name of the group test. + * + * @param[in] group_tests[] The array of unit tests to execute. + * + * @param[in] group_setup The setup function which should be called before + * all unit tests are executed. + * + * @param[in] group_teardown The teardown function to be called after all + * tests have finished. + * + * @return 0 on success, or the number of failed tests. + * + * @code + * static int setup(void **state) { + * int *answer = malloc(sizeof(int)); + * if (*answer == NULL) { + * return -1; + * } + * *answer = 42; + * + * *state = answer; + * + * return 0; + * } + * + * static int teardown(void **state) { + * free(*state); + * + * return 0; + * } + * + * static void null_test_success(void **state) { + * (void) state; + * } + * + * static void int_test_success(void **state) { + * int *answer = *state; + * assert_int_equal(*answer, 42); + * } + * + * int main(void) { + * const struct CMUnitTest tests[] = { + * cmocka_unit_test(null_test_success), + * cmocka_unit_test_setup_teardown(int_test_success, setup, teardown), + * }; + * + * return cmocka_run_group_tests_name("success_test", tests, NULL, NULL); + * } + * @endcode + * + * @see cmocka_unit_test + * @see cmocka_unit_test_setup + * @see cmocka_unit_test_teardown + * @see cmocka_unit_test_setup_teardown + */ +int cmocka_run_group_tests_name(const char *group_name, + const struct CMUnitTest group_tests[], + CMFixtureFunction group_setup, + CMFixtureFunction group_teardown); +#else +# define cmocka_run_group_tests_name(group_name, group_tests, group_setup, group_teardown) \ + _cmocka_run_group_tests(group_name, group_tests, sizeof(group_tests) / sizeof((group_tests)[0]), group_setup, group_teardown) +#endif + +/** @} */ + +/** + * @defgroup cmocka_alloc Dynamic Memory Allocation + * @ingroup cmocka + * + * Memory leaks, buffer overflows and underflows can be checked using cmocka. + * + * To test for memory leaks, buffer overflows and underflows a module being + * tested by cmocka should replace calls to malloc(), calloc() and free() to + * test_malloc(), test_calloc() and test_free() respectively. Each time a block + * is deallocated using test_free() it is checked for corruption, if a corrupt + * block is found a test failure is signalled. All blocks allocated using the + * test_*() allocation functions are tracked by the cmocka library. When a test + * completes if any allocated blocks (memory leaks) remain they are reported + * and a test failure is signalled. + * + * For simplicity cmocka currently executes all tests in one process. Therefore + * all test cases in a test application share a single address space which + * means memory corruption from a single test case could potentially cause the + * test application to exit prematurely. + * + * @{ + */ + +#ifdef DOXYGEN +/** + * @brief Test function overriding malloc. + * + * @param[in] size The bytes which should be allocated. + * + * @return A pointer to the allocated memory or NULL on error. + * + * @code + * #ifdef UNIT_TESTING + * extern void* _test_malloc(const size_t size, const char* file, const int line); + * + * #define malloc(size) _test_malloc(size, __FILE__, __LINE__) + * #endif + * + * void leak_memory() { + * int * const temporary = (int*)malloc(sizeof(int)); + * *temporary = 0; + * } + * @endcode + * + * @see malloc(3) + */ +void *test_malloc(size_t size); +#else +#define test_malloc(size) _test_malloc(size, __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Test function overriding calloc. + * + * The memory is set to zero. + * + * @param[in] nmemb The number of elements for an array to be allocated. + * + * @param[in] size The size in bytes of each array element to allocate. + * + * @return A pointer to the allocated memory, NULL on error. + * + * @see calloc(3) + */ +void *test_calloc(size_t nmemb, size_t size); +#else +#define test_calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Test function overriding realloc which detects buffer overruns + * and memoery leaks. + * + * @param[in] ptr The memory block which should be changed. + * + * @param[in] size The bytes which should be allocated. + * + * @return The newly allocated memory block, NULL on error. + */ +void *test_realloc(void *ptr, size_t size); +#else +#define test_realloc(ptr, size) _test_realloc(ptr, size, __FILE__, __LINE__) +#endif + +#ifdef DOXYGEN +/** + * @brief Test function overriding free(3). + * + * @param[in] ptr The pointer to the memory space to free. + * + * @see free(3). + */ +void test_free(void *ptr); +#else +#define test_free(ptr) _test_free(ptr, __FILE__, __LINE__) +#endif + +/* Redirect malloc, calloc and free to the unit test allocators. */ +#ifdef UNIT_TESTING +#define malloc test_malloc +#define realloc test_realloc +#define calloc test_calloc +#define free test_free +#endif /* UNIT_TESTING */ + +/** @} */ + + +/** + * @defgroup cmocka_mock_assert Standard Assertions + * @ingroup cmocka + * + * How to handle assert(3) of the standard C library. + * + * Runtime assert macros like the standard C library's assert() should be + * redefined in modules being tested to use cmocka's mock_assert() function. + * Normally mock_assert() signals a test failure. If a function is called using + * the expect_assert_failure() macro, any calls to mock_assert() within the + * function will result in the execution of the test. If no calls to + * mock_assert() occur during the function called via expect_assert_failure() a + * test failure is signalled. + * + * @{ + */ + +/** + * @brief Function to replace assert(3) in tested code. + * + * In conjuction with check_assert() it's possible to determine whether an + * assert condition has failed without stopping a test. + * + * @param[in] result The expression to assert. + * + * @param[in] expression The expression as string. + * + * @param[in] file The file mock_assert() is called. + * + * @param[in] line The line mock_assert() is called. + * + * @code + * #ifdef UNIT_TESTING + * extern void mock_assert(const int result, const char* const expression, + * const char * const file, const int line); + * + * #undef assert + * #define assert(expression) \ + * mock_assert((int)(expression), #expression, __FILE__, __LINE__); + * #endif + * + * void increment_value(int * const value) { + * assert(value); + * (*value) ++; + * } + * @endcode + * + * @see assert(3) + * @see expect_assert_failure + */ +void mock_assert(const int result, const char* const expression, + const char * const file, const int line); + +#ifdef DOXYGEN +/** + * @brief Ensure that mock_assert() is called. + * + * If mock_assert() is called the assert expression string is returned. + * + * @param[in] fn_call The function will will call mock_assert(). + * + * @code + * #define assert mock_assert + * + * void showmessage(const char *message) { + * assert(message); + * } + * + * int main(int argc, const char* argv[]) { + * expect_assert_failure(show_message(NULL)); + * printf("succeeded\n"); + * return 0; + * } + * @endcode + * + */ +void expect_assert_failure(function fn_call); +#else +#define expect_assert_failure(function_call) \ + { \ + const int result = setjmp(global_expect_assert_env); \ + global_expecting_assert = 1; \ + if (result) { \ + print_message("Expected assertion %s occurred\n", \ + global_last_failed_assert); \ + global_expecting_assert = 0; \ + } else { \ + function_call ; \ + global_expecting_assert = 0; \ + print_error("Expected assert in %s\n", #function_call); \ + _fail(__FILE__, __LINE__); \ + } \ + } +#endif + +/** @} */ + +/* Function prototype for setup, test and teardown functions. */ +typedef void (*UnitTestFunction)(void **state); + +/* Function that determines whether a function parameter value is correct. */ +typedef int (*CheckParameterValue)(const LargestIntegralType value, + const LargestIntegralType check_value_data); + +/* Type of the unit test function. */ +typedef enum UnitTestFunctionType { + UNIT_TEST_FUNCTION_TYPE_TEST = 0, + UNIT_TEST_FUNCTION_TYPE_SETUP, + UNIT_TEST_FUNCTION_TYPE_TEARDOWN, + UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP, + UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN, +} UnitTestFunctionType; + +/* + * Stores a unit test function with its name and type. + * NOTE: Every setup function must be paired with a teardown function. It's + * possible to specify NULL function pointers. + */ +typedef struct UnitTest { + const char* name; + UnitTestFunction function; + UnitTestFunctionType function_type; +} UnitTest; + +typedef struct GroupTest { + UnitTestFunction setup; + UnitTestFunction teardown; + const UnitTest *tests; + const size_t number_of_tests; +} GroupTest; + +/* Function prototype for test functions. */ +typedef void (*CMUnitTestFunction)(void **state); + +/* Function prototype for setup and teardown functions. */ +typedef int (*CMFixtureFunction)(void **state); + +struct CMUnitTest { + const char *name; + CMUnitTestFunction test_func; + CMFixtureFunction setup_func; + CMFixtureFunction teardown_func; + void *initial_state; +}; + +/* Location within some source code. */ +typedef struct SourceLocation { + const char* file; + int line; +} SourceLocation; + +/* Event that's called to check a parameter value. */ +typedef struct CheckParameterEvent { + SourceLocation location; + const char *parameter_name; + CheckParameterValue check_value; + LargestIntegralType check_value_data; +} CheckParameterEvent; + +/* Used by expect_assert_failure() and mock_assert(). */ +extern int global_expecting_assert; +extern jmp_buf global_expect_assert_env; +extern const char * global_last_failed_assert; + +/* Retrieves a value for the given function, as set by "will_return". */ +LargestIntegralType _mock(const char * const function, const char* const file, + const int line); + +void _expect_function_call( + const char * const function_name, + const char * const file, + const int line, + const int count); + +void _function_called(const char * const function, const char* const file, + const int line); + +void _expect_check( + const char* const function, const char* const parameter, + const char* const file, const int line, + const CheckParameterValue check_function, + const LargestIntegralType check_data, CheckParameterEvent * const event, + const int count); + +void _expect_in_set( + const char* const function, const char* const parameter, + const char* const file, const int line, const LargestIntegralType values[], + const size_t number_of_values, const int count); +void _expect_not_in_set( + const char* const function, const char* const parameter, + const char* const file, const int line, const LargestIntegralType values[], + const size_t number_of_values, const int count); + +void _expect_in_range( + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType minimum, + const LargestIntegralType maximum, const int count); +void _expect_not_in_range( + const char* const function, const char* const parameter, + const char* const file, const int line, + const LargestIntegralType minimum, + const LargestIntegralType maximum, const int count); + +void _expect_value( + const char* const function, const char* const parameter, + const char* const file, const int line, const LargestIntegralType value, + const int count); +void _expect_not_value( + const char* const function, const char* const parameter, + const char* const file, const int line, const LargestIntegralType value, + const int count); + +void _expect_string( + const char* const function, const char* const parameter, + const char* const file, const int line, const char* string, + const int count); +void _expect_not_string( + const char* const function, const char* const parameter, + const char* const file, const int line, const char* string, + const int count); + +void _expect_memory( + const char* const function, const char* const parameter, + const char* const file, const int line, const void* const memory, + const size_t size, const int count); +void _expect_not_memory( + const char* const function, const char* const parameter, + const char* const file, const int line, const void* const memory, + const size_t size, const int count); + +void _expect_any( + const char* const function, const char* const parameter, + const char* const file, const int line, const int count); + +void _check_expected( + const char * const function_name, const char * const parameter_name, + const char* file, const int line, const LargestIntegralType value); + +void _will_return(const char * const function_name, const char * const file, + const int line, const LargestIntegralType value, + const int count); +void _assert_true(const LargestIntegralType result, + const char* const expression, + const char * const file, const int line); +void _assert_return_code(const LargestIntegralType result, + size_t rlen, + const LargestIntegralType error, + const char * const expression, + const char * const file, + const int line); +void _assert_int_equal( + const LargestIntegralType a, const LargestIntegralType b, + const char * const file, const int line); +void _assert_int_not_equal( + const LargestIntegralType a, const LargestIntegralType b, + const char * const file, const int line); +void _assert_string_equal(const char * const a, const char * const b, + const char * const file, const int line); +void _assert_string_not_equal(const char * const a, const char * const b, + const char *file, const int line); +void _assert_memory_equal(const void * const a, const void * const b, + const size_t size, const char* const file, + const int line); +void _assert_memory_not_equal(const void * const a, const void * const b, + const size_t size, const char* const file, + const int line); +void _assert_in_range( + const LargestIntegralType value, const LargestIntegralType minimum, + const LargestIntegralType maximum, const char* const file, const int line); +void _assert_not_in_range( + const LargestIntegralType value, const LargestIntegralType minimum, + const LargestIntegralType maximum, const char* const file, const int line); +void _assert_in_set( + const LargestIntegralType value, const LargestIntegralType values[], + const size_t number_of_values, const char* const file, const int line); +void _assert_not_in_set( + const LargestIntegralType value, const LargestIntegralType values[], + const size_t number_of_values, const char* const file, const int line); + +void* _test_malloc(const size_t size, const char* file, const int line); +void* _test_realloc(void *ptr, const size_t size, const char* file, const int line); +void* _test_calloc(const size_t number_of_elements, const size_t size, + const char* file, const int line); +void _test_free(void* const ptr, const char* file, const int line); + +void _fail(const char * const file, const int line); + +void _skip(const char * const file, const int line); + +int _run_test( + const char * const function_name, const UnitTestFunction Function, + void ** const volatile state, const UnitTestFunctionType function_type, + const void* const heap_check_point); +CMOCKA_DEPRECATED int _run_tests(const UnitTest * const tests, + const size_t number_of_tests); +CMOCKA_DEPRECATED int _run_group_tests(const UnitTest * const tests, + const size_t number_of_tests); + +/* Test runner */ +int _cmocka_run_group_tests(const char *group_name, + const struct CMUnitTest * const tests, + const size_t num_tests, + CMFixtureFunction group_setup, + CMFixtureFunction group_teardown); + +/* Standard output and error print methods. */ +void print_message(const char* const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); +void print_error(const char* const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); +void vprint_message(const char* const format, va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0); +void vprint_error(const char* const format, va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0); + +enum cm_message_output { + CM_OUTPUT_STDOUT, + CM_OUTPUT_SUBUNIT, + CM_OUTPUT_TAP, + CM_OUTPUT_XML, +}; + +/** + * @brief Function to set the output format for a test. + * + * The ouput format for the test can either be set globally using this + * function or overriden with environment variable CMOCKA_MESSAGE_OUTPUT. + * + * The environment variable can be set to either STDOUT, SUBUNIT, TAP or XML. + * + * @param[in] output The output format to use for the test. + * + */ +void cmocka_set_message_output(enum cm_message_output output); + + +/** + * @brief Set a pattern to only run the test matching the pattern. + * + * This allows to filter tests and only run the ones matching the pattern. Thep + * pattern can include two wildards. The first is '*', a wildcard that matches + * zero or more characters, or ‘?’, a wildcard that matches exactly one + * character. + * + * @param[in] pattern The pattern to match, e.g. "test_wurst*" + */ +void cmocka_set_test_filter(const char *pattern); + +/** @} */ + +#endif /* CMOCKA_H_ */ diff --git a/ldb-2.0.8/third_party/cmocka/cmocka_private.h b/ldb-2.0.8/third_party/cmocka/cmocka_private.h new file mode 100644 index 0000000..d20d841 --- /dev/null +++ b/ldb-2.0.8/third_party/cmocka/cmocka_private.h @@ -0,0 +1,163 @@ +/* + * Copyright 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CMOCKA_PRIVATE_H_ +#define CMOCKA_PRIVATE_H_ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#ifdef _WIN32 +#include + +# ifdef _MSC_VER +# include /* _snprintf */ + +# undef inline +# define inline __inline + +# ifndef va_copy +# define va_copy(dest, src) (dest = src) +# endif + +# define strcasecmp _stricmp +# define strncasecmp _strnicmp + +# if defined(HAVE__SNPRINTF_S) +# undef snprintf +# define snprintf(d, n, ...) _snprintf_s((d), (n), _TRUNCATE, __VA_ARGS__) +# else /* HAVE__SNPRINTF_S */ +# if defined(HAVE__SNPRINTF) +# undef snprintf +# define snprintf _snprintf +# else /* HAVE__SNPRINTF */ +# if !defined(HAVE_SNPRINTF) +# error "no snprintf compatible function found" +# endif /* HAVE_SNPRINTF */ +# endif /* HAVE__SNPRINTF */ +# endif /* HAVE__SNPRINTF_S */ + +# if defined(HAVE__VSNPRINTF_S) +# undef vsnprintf +# define vsnprintf(s, n, f, v) _vsnprintf_s((s), (n), _TRUNCATE, (f), (v)) +# else /* HAVE__VSNPRINTF_S */ +# if defined(HAVE__VSNPRINTF) +# undef vsnprintf +# define vsnprintf _vsnprintf +# else +# if !defined(HAVE_VSNPRINTF) +# error "No vsnprintf compatible function found" +# endif /* HAVE_VSNPRINTF */ +# endif /* HAVE__VSNPRINTF */ +# endif /* HAVE__VSNPRINTF_S */ +# endif /* _MSC_VER */ + +/* + * Backwards compatibility with headers shipped with Visual Studio 2005 and + * earlier. + */ +WINBASEAPI BOOL WINAPI IsDebuggerPresent(VOID); + +#ifndef PRIdS +# define PRIdS "Id" +#endif + +#ifndef PRIu64 +# define PRIu64 "I64u" +#endif + +#ifndef PRIuMAX +# define PRIuMAX PRIu64 +#endif + +#ifndef PRIxMAX +#define PRIxMAX "I64x" +#endif + +#ifndef PRIXMAX +#define PRIXMAX "I64X" +#endif + +#else /* _WIN32 */ + +#ifndef __PRI64_PREFIX +# if __WORDSIZE == 64 +# define __PRI64_PREFIX "l" +# else +# define __PRI64_PREFIX "ll" +# endif +#endif + +#ifndef PRIdS +# define PRIdS "zd" +#endif + +#ifndef PRIu64 +# define PRIu64 __PRI64_PREFIX "u" +#endif + +#ifndef PRIuMAX +# define PRIuMAX __PRI64_PREFIX "u" +#endif + +#ifndef PRIxMAX +#define PRIxMAX __PRI64_PREFIX "x" +#endif + +#ifndef PRIXMAX +#define PRIXMAX __PRI64_PREFIX "X" +#endif + +#endif /* _WIN32 */ + +/** Free memory space */ +#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0) + +/** Zero a structure */ +#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x)) + +/** Zero a structure given a pointer to the structure */ +#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0) + +/** Get the size of an array */ +#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) + +/** Overwrite the complete string with 'X' */ +#define BURN_STRING(x) do { if ((x) != NULL) memset((x), 'X', strlen((x))); } while(0) + +/** + * This is a hack to fix warnings. The idea is to use this everywhere that we + * get the "discarding const" warning by the compiler. That doesn't actually + * fix the real issue, but marks the place and you can search the code for + * discard_const. + * + * Please use this macro only when there is no other way to fix the warning. + * We should use this function in only in a very few places. + * + * Also, please call this via the discard_const_p() macro interface, as that + * makes the return type safe. + */ +#define discard_const(ptr) ((void *)((uintptr_t)(ptr))) + +/** + * Type-safe version of discard_const + */ +#define discard_const_p(type, ptr) ((type *)discard_const(ptr)) + +#endif /* CMOCKA_PRIVATE_H_ */ diff --git a/ldb-2.0.8/third_party/cmocka/wscript b/ldb-2.0.8/third_party/cmocka/wscript new file mode 100644 index 0000000..3c2ad50 --- /dev/null +++ b/ldb-2.0.8/third_party/cmocka/wscript @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +from waflib import Options + +def configure(conf): + conf.CHECK_FUNCS('longjmp siglongjmp') + + if conf.CHECK_CMOCKA(): + conf.define('USING_SYSTEM_CMOCKA', 1) + +def build(bld): + if bld.CONFIG_SET('USING_SYSTEM_CMOCKA'): + return + + extra_libs='' + + # Link to librt if needed for clock_gettime() + if bld.CONFIG_SET('HAVE_LIBRT'): extra_libs += ' rt' + + bld.SAMBA_LIBRARY('cmocka', + source='cmocka.c', + deps=extra_libs, + allow_warnings=True, + private_library=True) diff --git a/ldb-2.0.8/third_party/popt/CHANGES b/ldb-2.0.8/third_party/popt/CHANGES new file mode 100644 index 0000000..db16a5f --- /dev/null +++ b/ldb-2.0.8/third_party/popt/CHANGES @@ -0,0 +1,46 @@ +1.5 -> 1.6 + - add ability to perform callbacks for every, not just first, match. + +1.3 -> 1.5 + - heavy dose of const's + - poptParseArgvString() now NULL terminates the list + +1.2.3 -> 1.3 + - added support for single - + - misc bug fixes + - portability improvements + +1.2.2 -> 1.2.3 + - fixed memset() in help message generation (Dale Hawkins) + - added extern "C" stuff to popt.h for C++ compilers (Dale Hawkins) + - const'ified poptParseArgvString (Jeff Garzik) + +1.2.1 -> 1.2.2 + - fixed bug in chaind alias happens which seems to have only + affected --triggers in rpm + - added POPT_ARG_VAL + - popt.3 installed by default + +1.2 -> 1.2.1 + - added POPT_ARG_INTL_DOMAIN (Elliot Lee) + - updated Makefile's to be more GNUish (Elliot Lee) + +1.1 -> 1.2 + - added popt.3 man page (Robert Lynch) + - don't use mmap anymore (its lack of portability isn't worth the + trouble) + - added test script + - added support for exec + - removed support for *_POPT_ALIASES env variable -- it was a bad + idea + - reorganized into multiple source files + - added automatic help generation, POPT_AUTOHELP + - added table callbacks + - added table inclusion + - updated man page for new features + - added test scripts + +1.0 -> 1.1 + - moved to autoconf (Fred Fish) + - added STRERROR replacement (Norbert Warmuth) + - added const keywords (Bruce Perens) diff --git a/ldb-2.0.8/third_party/popt/COPYING b/ldb-2.0.8/third_party/popt/COPYING new file mode 100644 index 0000000..b4c7ca8 --- /dev/null +++ b/ldb-2.0.8/third_party/popt/COPYING @@ -0,0 +1,22 @@ +Copyright (c) 1998 Red Hat Software + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. diff --git a/ldb-2.0.8/third_party/popt/README b/ldb-2.0.8/third_party/popt/README new file mode 100644 index 0000000..c66432d --- /dev/null +++ b/ldb-2.0.8/third_party/popt/README @@ -0,0 +1,16 @@ +This is the popt(3) command line option parsing library. While it is similiar +to getopt(3), it contains a number of enhancements, including: + + 1) popt is fully reentrant + 2) popt can parse arbitrary argv[] style arrays while + getopt(3) makes this quite difficult + 3) popt allows users to alias command line arguments + 4) popt provides convience functions for parsing strings + into argv[] style arrays + +Complete documentation on popt(3) is available in popt.ps (included in this +tarball), which is excerpted with permission from the book "Linux +Application Development" by Michael K. Johnson and Erik Troan (available +from Addison Wesley in May, 1998). + +Comments on popt should be addressed to popt-devel@rpm5.org. diff --git a/ldb-2.0.8/third_party/popt/findme.h b/ldb-2.0.8/third_party/popt/findme.h new file mode 100644 index 0000000..a016b86 --- /dev/null +++ b/ldb-2.0.8/third_party/popt/findme.h @@ -0,0 +1,20 @@ +/** \ingroup popt + * \file popt/findme.h + */ + +/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING + file accompanying popt source distributions, available from + ftp://ftp.rpm.org/pub/rpm/dist. */ + +#ifndef H_FINDME +#define H_FINDME + +/** + * Return absolute path to executable by searching PATH. + * @param argv0 name of executable + * @return (malloc'd) absolute path to executable (or NULL) + */ +/*@null@*/ const char * findProgramPath(/*@null@*/ const char * argv0) + /*@*/; + +#endif diff --git a/ldb-2.0.8/third_party/popt/lookup3.c b/ldb-2.0.8/third_party/popt/lookup3.c new file mode 100644 index 0000000..eb4e5ce --- /dev/null +++ b/ldb-2.0.8/third_party/popt/lookup3.c @@ -0,0 +1,969 @@ +/* -------------------------------------------------------------------- */ +/* + * lookup3.c, by Bob Jenkins, May 2006, Public Domain. + * + * These are functions for producing 32-bit hashes for hash table lookup. + * jlu32w(), jlu32l(), jlu32lpair(), jlu32b(), _JLU3_MIX(), and _JLU3_FINAL() + * are externally useful functions. Routines to test the hash are included + * if SELF_TEST is defined. You can use this free for any purpose. It's in + * the public domain. It has no warranty. + * + * You probably want to use jlu32l(). jlu32l() and jlu32b() + * hash byte arrays. jlu32l() is is faster than jlu32b() on + * little-endian machines. Intel and AMD are little-endian machines. + * On second thought, you probably want jlu32lpair(), which is identical to + * jlu32l() except it returns two 32-bit hashes for the price of one. + * You could implement jlu32bpair() if you wanted but I haven't bothered here. + * + * If you want to find a hash of, say, exactly 7 integers, do + * a = i1; b = i2; c = i3; + * _JLU3_MIX(a,b,c); + * a += i4; b += i5; c += i6; + * _JLU3_MIX(a,b,c); + * a += i7; + * _JLU3_FINAL(a,b,c); + * then use c as the hash value. If you have a variable size array of + * 4-byte integers to hash, use jlu32w(). If you have a byte array (like + * a character string), use jlu32l(). If you have several byte arrays, or + * a mix of things, see the comments above jlu32l(). + * + * Why is this so big? I read 12 bytes at a time into 3 4-byte integers, + * then mix those integers. This is fast (you can do a lot more thorough + * mixing with 12*3 instructions on 3 integers than you can with 3 instructions + * on 1 byte), but shoehorning those bytes into integers efficiently is messy. +*/ +/* -------------------------------------------------------------------- */ + +#include + +#if defined(_JLU3_SELFTEST) +# define _JLU3_jlu32w 1 +# define _JLU3_jlu32l 1 +# define _JLU3_jlu32lpair 1 +# define _JLU3_jlu32b 1 +#endif + +/*@-redef@*/ +/*@unchecked@*/ +static const union _dbswap { + const uint32_t ui; + const unsigned char uc[4]; +} endian = { .ui = 0x11223344 }; +# define HASH_LITTLE_ENDIAN (endian.uc[0] == (unsigned char) 0x44) +# define HASH_BIG_ENDIAN (endian.uc[0] == (unsigned char) 0x11) +/*@=redef@*/ + +#ifndef ROTL32 +# define ROTL32(x, s) (((x) << (s)) | ((x) >> (32 - (s)))) +#endif + +/* NOTE: The _size parameter should be in bytes. */ +#define _JLU3_INIT(_h, _size) (0xdeadbeef + ((uint32_t)(_size)) + (_h)) + +/* -------------------------------------------------------------------- */ +/* + * _JLU3_MIX -- mix 3 32-bit values reversibly. + * + * This is reversible, so any information in (a,b,c) before _JLU3_MIX() is + * still in (a,b,c) after _JLU3_MIX(). + * + * If four pairs of (a,b,c) inputs are run through _JLU3_MIX(), or through + * _JLU3_MIX() in reverse, there are at least 32 bits of the output that + * are sometimes the same for one pair and different for another pair. + * This was tested for: + * * pairs that differed by one bit, by two bits, in any combination + * of top bits of (a,b,c), or in any combination of bottom bits of + * (a,b,c). + * * "differ" is defined as +, -, ^, or ~^. For + and -, I transformed + * the output delta to a Gray code (a^(a>>1)) so a string of 1's (as + * is commonly produced by subtraction) look like a single 1-bit + * difference. + * * the base values were pseudorandom, all zero but one bit set, or + * all zero plus a counter that starts at zero. + * + * Some k values for my "a-=c; a^=ROTL32(c,k); c+=b;" arrangement that + * satisfy this are + * 4 6 8 16 19 4 + * 9 15 3 18 27 15 + * 14 9 3 7 17 3 + * Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing + * for "differ" defined as + with a one-bit base and a two-bit delta. I + * used http://burtleburtle.net/bob/hash/avalanche.html to choose + * the operations, constants, and arrangements of the variables. + * + * This does not achieve avalanche. There are input bits of (a,b,c) + * that fail to affect some output bits of (a,b,c), especially of a. The + * most thoroughly mixed value is c, but it doesn't really even achieve + * avalanche in c. + * + * This allows some parallelism. Read-after-writes are good at doubling + * the number of bits affected, so the goal of mixing pulls in the opposite + * direction as the goal of parallelism. I did what I could. Rotates + * seem to cost as much as shifts on every machine I could lay my hands + * on, and rotates are much kinder to the top and bottom bits, so I used + * rotates. + */ +/* -------------------------------------------------------------------- */ +#define _JLU3_MIX(a,b,c) \ +{ \ + a -= c; a ^= ROTL32(c, 4); c += b; \ + b -= a; b ^= ROTL32(a, 6); a += c; \ + c -= b; c ^= ROTL32(b, 8); b += a; \ + a -= c; a ^= ROTL32(c,16); c += b; \ + b -= a; b ^= ROTL32(a,19); a += c; \ + c -= b; c ^= ROTL32(b, 4); b += a; \ +} + +/* -------------------------------------------------------------------- */ +/** + * _JLU3_FINAL -- final mixing of 3 32-bit values (a,b,c) into c + * + * Pairs of (a,b,c) values differing in only a few bits will usually + * produce values of c that look totally different. This was tested for + * * pairs that differed by one bit, by two bits, in any combination + * of top bits of (a,b,c), or in any combination of bottom bits of + * (a,b,c). + * * "differ" is defined as +, -, ^, or ~^. For + and -, I transformed + * the output delta to a Gray code (a^(a>>1)) so a string of 1's (as + * is commonly produced by subtraction) look like a single 1-bit + * difference. + * * the base values were pseudorandom, all zero but one bit set, or + * all zero plus a counter that starts at zero. + * + * These constants passed: + * 14 11 25 16 4 14 24 + * 12 14 25 16 4 14 24 + * and these came close: + * 4 8 15 26 3 22 24 + * 10 8 15 26 3 22 24 + * 11 8 15 26 3 22 24 + */ +/* -------------------------------------------------------------------- */ +#define _JLU3_FINAL(a,b,c) \ +{ \ + c ^= b; c -= ROTL32(b,14); \ + a ^= c; a -= ROTL32(c,11); \ + b ^= a; b -= ROTL32(a,25); \ + c ^= b; c -= ROTL32(b,16); \ + a ^= c; a -= ROTL32(c,4); \ + b ^= a; b -= ROTL32(a,14); \ + c ^= b; c -= ROTL32(b,24); \ +} + +#if defined(_JLU3_jlu32w) +uint32_t jlu32w(uint32_t h, /*@null@*/ const uint32_t *k, size_t size) + /*@*/; +/* -------------------------------------------------------------------- */ +/** + * This works on all machines. To be useful, it requires + * -- that the key be an array of uint32_t's, and + * -- that the size be the number of uint32_t's in the key + * + * The function jlu32w() is identical to jlu32l() on little-endian + * machines, and identical to jlu32b() on big-endian machines, + * except that the size has to be measured in uint32_ts rather than in + * bytes. jlu32l() is more complicated than jlu32w() only because + * jlu32l() has to dance around fitting the key bytes into registers. + * + * @param h the previous hash, or an arbitrary value + * @param *k the key, an array of uint32_t values + * @param size the size of the key, in uint32_ts + * @return the lookup3 hash + */ +/* -------------------------------------------------------------------- */ +uint32_t jlu32w(uint32_t h, const uint32_t *k, size_t size) +{ + uint32_t a = _JLU3_INIT(h, (size * sizeof(*k))); + uint32_t b = a; + uint32_t c = a; + + if (k == NULL) + goto exit; + + /*----------------------------------------------- handle most of the key */ + while (size > 3) { + a += k[0]; + b += k[1]; + c += k[2]; + _JLU3_MIX(a,b,c); + size -= 3; + k += 3; + } + + /*----------------------------------------- handle the last 3 uint32_t's */ + switch (size) { + case 3 : c+=k[2]; + case 2 : b+=k[1]; + case 1 : a+=k[0]; + _JLU3_FINAL(a,b,c); + /*@fallthrough@*/ + case 0: + break; + } + /*---------------------------------------------------- report the result */ +exit: + return c; +} +#endif /* defined(_JLU3_jlu32w) */ + +#if defined(_JLU3_jlu32l) +uint32_t jlu32l(uint32_t h, const void *key, size_t size) + /*@*/; +/* -------------------------------------------------------------------- */ +/* + * jlu32l() -- hash a variable-length key into a 32-bit value + * h : can be any 4-byte value + * k : the key (the unaligned variable-length array of bytes) + * size : the size of the key, counting by bytes + * Returns a 32-bit value. Every bit of the key affects every bit of + * the return value. Two keys differing by one or two bits will have + * totally different hash values. + * + * The best hash table sizes are powers of 2. There is no need to do + * mod a prime (mod is sooo slow!). If you need less than 32 bits, + * use a bitmask. For example, if you need only 10 bits, do + * h = (h & hashmask(10)); + * In which case, the hash table should have hashsize(10) elements. + * + * If you are hashing n strings (uint8_t **)k, do it like this: + * for (i=0, h=0; i 12) { + a += k[0]; + b += k[1]; + c += k[2]; + _JLU3_MIX(a,b,c); + size -= 12; + k += 3; + } + + /*------------------------- handle the last (probably partial) block */ + /* + * "k[2]&0xffffff" actually reads beyond the end of the string, but + * then masks off the part it's not allowed to read. Because the + * string is aligned, the masked-off tail is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticably faster for short strings (like English words). + */ +#ifndef VALGRIND + + switch (size) { + case 12: c += k[2]; b+=k[1]; a+=k[0]; break; + case 11: c += k[2]&0xffffff; b+=k[1]; a+=k[0]; break; + case 10: c += k[2]&0xffff; b+=k[1]; a+=k[0]; break; + case 9: c += k[2]&0xff; b+=k[1]; a+=k[0]; break; + case 8: b += k[1]; a+=k[0]; break; + case 7: b += k[1]&0xffffff; a+=k[0]; break; + case 6: b += k[1]&0xffff; a+=k[0]; break; + case 5: b += k[1]&0xff; a+=k[0]; break; + case 4: a += k[0]; break; + case 3: a += k[0]&0xffffff; break; + case 2: a += k[0]&0xffff; break; + case 1: a += k[0]&0xff; break; + case 0: goto exit; + } + +#else /* make valgrind happy */ + + k8 = (const uint8_t *)k; + switch (size) { + case 12: c += k[2]; b+=k[1]; a+=k[0] break; + case 11: c += ((uint32_t)k8[10])<<16; /*@fallthrough@*/ + case 10: c += ((uint32_t)k8[9])<<8; /*@fallthrough@*/ + case 9: c += k8[8]; /*@fallthrough@*/ + case 8: b += k[1]; a+=k[0]; break; + case 7: b += ((uint32_t)k8[6])<<16; /*@fallthrough@*/ + case 6: b += ((uint32_t)k8[5])<<8; /*@fallthrough@*/ + case 5: b += k8[4]; /*@fallthrough@*/ + case 4: a += k[0]; break; + case 3: a += ((uint32_t)k8[2])<<16; /*@fallthrough@*/ + case 2: a += ((uint32_t)k8[1])<<8; /*@fallthrough@*/ + case 1: a += k8[0]; break; + case 0: goto exit; + } + +#endif /* !valgrind */ + + } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { + const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ + const uint8_t *k8; + + /*----------- all but last block: aligned reads and different mixing */ + while (size > 12) { + a += k[0] + (((uint32_t)k[1])<<16); + b += k[2] + (((uint32_t)k[3])<<16); + c += k[4] + (((uint32_t)k[5])<<16); + _JLU3_MIX(a,b,c); + size -= 12; + k += 6; + } + + /*------------------------- handle the last (probably partial) block */ + k8 = (const uint8_t *)k; + switch (size) { + case 12: + c += k[4]+(((uint32_t)k[5])<<16); + b += k[2]+(((uint32_t)k[3])<<16); + a += k[0]+(((uint32_t)k[1])<<16); + break; + case 11: + c += ((uint32_t)k8[10])<<16; + /*@fallthrough@*/ + case 10: + c += (uint32_t)k[4]; + b += k[2]+(((uint32_t)k[3])<<16); + a += k[0]+(((uint32_t)k[1])<<16); + break; + case 9: + c += (uint32_t)k8[8]; + /*@fallthrough@*/ + case 8: + b += k[2]+(((uint32_t)k[3])<<16); + a += k[0]+(((uint32_t)k[1])<<16); + break; + case 7: + b += ((uint32_t)k8[6])<<16; + /*@fallthrough@*/ + case 6: + b += (uint32_t)k[2]; + a += k[0]+(((uint32_t)k[1])<<16); + break; + case 5: + b += (uint32_t)k8[4]; + /*@fallthrough@*/ + case 4: + a += k[0]+(((uint32_t)k[1])<<16); + break; + case 3: + a += ((uint32_t)k8[2])<<16; + /*@fallthrough@*/ + case 2: + a += (uint32_t)k[0]; + break; + case 1: + a += (uint32_t)k8[0]; + break; + case 0: + goto exit; + } + + } else { /* need to read the key one byte at a time */ + const uint8_t *k = (const uint8_t *)key; + + /*----------- all but the last block: affect some 32 bits of (a,b,c) */ + while (size > 12) { + a += (uint32_t)k[0]; + a += ((uint32_t)k[1])<<8; + a += ((uint32_t)k[2])<<16; + a += ((uint32_t)k[3])<<24; + b += (uint32_t)k[4]; + b += ((uint32_t)k[5])<<8; + b += ((uint32_t)k[6])<<16; + b += ((uint32_t)k[7])<<24; + c += (uint32_t)k[8]; + c += ((uint32_t)k[9])<<8; + c += ((uint32_t)k[10])<<16; + c += ((uint32_t)k[11])<<24; + _JLU3_MIX(a,b,c); + size -= 12; + k += 12; + } + + /*---------------------------- last block: affect all 32 bits of (c) */ + switch (size) { + case 12: c += ((uint32_t)k[11])<<24; /*@fallthrough@*/ + case 11: c += ((uint32_t)k[10])<<16; /*@fallthrough@*/ + case 10: c += ((uint32_t)k[9])<<8; /*@fallthrough@*/ + case 9: c += (uint32_t)k[8]; /*@fallthrough@*/ + case 8: b += ((uint32_t)k[7])<<24; /*@fallthrough@*/ + case 7: b += ((uint32_t)k[6])<<16; /*@fallthrough@*/ + case 6: b += ((uint32_t)k[5])<<8; /*@fallthrough@*/ + case 5: b += (uint32_t)k[4]; /*@fallthrough@*/ + case 4: a += ((uint32_t)k[3])<<24; /*@fallthrough@*/ + case 3: a += ((uint32_t)k[2])<<16; /*@fallthrough@*/ + case 2: a += ((uint32_t)k[1])<<8; /*@fallthrough@*/ + case 1: a += (uint32_t)k[0]; + break; + case 0: + goto exit; + } + } + + _JLU3_FINAL(a,b,c); + +exit: + return c; +} +#endif /* defined(_JLU3_jlu32l) */ + +#if defined(_JLU3_jlu32lpair) +/** + * jlu32lpair: return 2 32-bit hash values. + * + * This is identical to jlu32l(), except it returns two 32-bit hash + * values instead of just one. This is good enough for hash table + * lookup with 2^^64 buckets, or if you want a second hash if you're not + * happy with the first, or if you want a probably-unique 64-bit ID for + * the key. *pc is better mixed than *pb, so use *pc first. If you want + * a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)". + * + * @param h the previous hash, or an arbitrary value + * @param *key the key, an array of uint8_t values + * @param size the size of the key in bytes + * @retval *pc, IN: primary initval, OUT: primary hash + * *retval *pb IN: secondary initval, OUT: secondary hash + */ +void jlu32lpair(const void *key, size_t size, uint32_t *pc, uint32_t *pb) +{ + union { const void *ptr; size_t i; } u; + uint32_t a = _JLU3_INIT(*pc, size); + uint32_t b = a; + uint32_t c = a; + + if (key == NULL) + goto exit; + + c += *pb; /* Add the secondary hash. */ + + u.ptr = key; + if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { + const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ +#ifdef VALGRIND + const uint8_t *k8; +#endif + + /*-- all but last block: aligned reads and affect 32 bits of (a,b,c) */ + while (size > (size_t)12) { + a += k[0]; + b += k[1]; + c += k[2]; + _JLU3_MIX(a,b,c); + size -= 12; + k += 3; + } + /*------------------------- handle the last (probably partial) block */ + /* + * "k[2]&0xffffff" actually reads beyond the end of the string, but + * then masks off the part it's not allowed to read. Because the + * string is aligned, the masked-off tail is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticably faster for short strings (like English words). + */ +#ifndef VALGRIND + + switch (size) { + case 12: c += k[2]; b+=k[1]; a+=k[0]; break; + case 11: c += k[2]&0xffffff; b+=k[1]; a+=k[0]; break; + case 10: c += k[2]&0xffff; b+=k[1]; a+=k[0]; break; + case 9: c += k[2]&0xff; b+=k[1]; a+=k[0]; break; + case 8: b += k[1]; a+=k[0]; break; + case 7: b += k[1]&0xffffff; a+=k[0]; break; + case 6: b += k[1]&0xffff; a+=k[0]; break; + case 5: b += k[1]&0xff; a+=k[0]; break; + case 4: a += k[0]; break; + case 3: a += k[0]&0xffffff; break; + case 2: a += k[0]&0xffff; break; + case 1: a += k[0]&0xff; break; + case 0: goto exit; + } + +#else /* make valgrind happy */ + + k8 = (const uint8_t *)k; + switch (size) { + case 12: c += k[2]; b+=k[1]; a+=k[0]; break; + case 11: c += ((uint32_t)k8[10])<<16; /*@fallthrough@*/ + case 10: c += ((uint32_t)k8[9])<<8; /*@fallthrough@*/ + case 9: c += k8[8]; /*@fallthrough@*/ + case 8: b += k[1]; a+=k[0]; break; + case 7: b += ((uint32_t)k8[6])<<16; /*@fallthrough@*/ + case 6: b += ((uint32_t)k8[5])<<8; /*@fallthrough@*/ + case 5: b += k8[4]; /*@fallthrough@*/ + case 4: a += k[0]; break; + case 3: a += ((uint32_t)k8[2])<<16; /*@fallthrough@*/ + case 2: a += ((uint32_t)k8[1])<<8; /*@fallthrough@*/ + case 1: a += k8[0]; break; + case 0: goto exit; + } + +#endif /* !valgrind */ + + } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { + const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ + const uint8_t *k8; + + /*----------- all but last block: aligned reads and different mixing */ + while (size > (size_t)12) { + a += k[0] + (((uint32_t)k[1])<<16); + b += k[2] + (((uint32_t)k[3])<<16); + c += k[4] + (((uint32_t)k[5])<<16); + _JLU3_MIX(a,b,c); + size -= 12; + k += 6; + } + + /*------------------------- handle the last (probably partial) block */ + k8 = (const uint8_t *)k; + switch (size) { + case 12: + c += k[4]+(((uint32_t)k[5])<<16); + b += k[2]+(((uint32_t)k[3])<<16); + a += k[0]+(((uint32_t)k[1])<<16); + break; + case 11: + c += ((uint32_t)k8[10])<<16; + /*@fallthrough@*/ + case 10: + c += k[4]; + b += k[2]+(((uint32_t)k[3])<<16); + a += k[0]+(((uint32_t)k[1])<<16); + break; + case 9: + c += k8[8]; + /*@fallthrough@*/ + case 8: + b += k[2]+(((uint32_t)k[3])<<16); + a += k[0]+(((uint32_t)k[1])<<16); + break; + case 7: + b += ((uint32_t)k8[6])<<16; + /*@fallthrough@*/ + case 6: + b += k[2]; + a += k[0]+(((uint32_t)k[1])<<16); + break; + case 5: + b += k8[4]; + /*@fallthrough@*/ + case 4: + a += k[0]+(((uint32_t)k[1])<<16); + break; + case 3: + a += ((uint32_t)k8[2])<<16; + /*@fallthrough@*/ + case 2: + a += k[0]; + break; + case 1: + a += k8[0]; + break; + case 0: + goto exit; + } + + } else { /* need to read the key one byte at a time */ + const uint8_t *k = (const uint8_t *)key; + + /*----------- all but the last block: affect some 32 bits of (a,b,c) */ + while (size > (size_t)12) { + a += k[0]; + a += ((uint32_t)k[1])<<8; + a += ((uint32_t)k[2])<<16; + a += ((uint32_t)k[3])<<24; + b += k[4]; + b += ((uint32_t)k[5])<<8; + b += ((uint32_t)k[6])<<16; + b += ((uint32_t)k[7])<<24; + c += k[8]; + c += ((uint32_t)k[9])<<8; + c += ((uint32_t)k[10])<<16; + c += ((uint32_t)k[11])<<24; + _JLU3_MIX(a,b,c); + size -= 12; + k += 12; + } + + /*---------------------------- last block: affect all 32 bits of (c) */ + switch (size) { + case 12: c += ((uint32_t)k[11])<<24; /*@fallthrough@*/ + case 11: c += ((uint32_t)k[10])<<16; /*@fallthrough@*/ + case 10: c += ((uint32_t)k[9])<<8; /*@fallthrough@*/ + case 9: c += k[8]; /*@fallthrough@*/ + case 8: b += ((uint32_t)k[7])<<24; /*@fallthrough@*/ + case 7: b += ((uint32_t)k[6])<<16; /*@fallthrough@*/ + case 6: b += ((uint32_t)k[5])<<8; /*@fallthrough@*/ + case 5: b += k[4]; /*@fallthrough@*/ + case 4: a += ((uint32_t)k[3])<<24; /*@fallthrough@*/ + case 3: a += ((uint32_t)k[2])<<16; /*@fallthrough@*/ + case 2: a += ((uint32_t)k[1])<<8; /*@fallthrough@*/ + case 1: a += k[0]; + break; + case 0: + goto exit; + } + } + + _JLU3_FINAL(a,b,c); + +exit: + *pc = c; + *pb = b; + return; +} +#endif /* defined(_JLU3_jlu32lpair) */ + +#if defined(_JLU3_jlu32b) +uint32_t jlu32b(uint32_t h, /*@null@*/ const void *key, size_t size) + /*@*/; +/* + * jlu32b(): + * This is the same as jlu32w() on big-endian machines. It is different + * from jlu32l() on all machines. jlu32b() takes advantage of + * big-endian byte ordering. + * + * @param h the previous hash, or an arbitrary value + * @param *k the key, an array of uint8_t values + * @param size the size of the key + * @return the lookup3 hash + */ +uint32_t jlu32b(uint32_t h, const void *key, size_t size) +{ + union { const void *ptr; size_t i; } u; + uint32_t a = _JLU3_INIT(h, size); + uint32_t b = a; + uint32_t c = a; + + if (key == NULL) + return h; + + u.ptr = key; + if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) { + const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ +#ifdef VALGRIND + const uint8_t *k8; +#endif + + /*-- all but last block: aligned reads and affect 32 bits of (a,b,c) */ + while (size > 12) { + a += k[0]; + b += k[1]; + c += k[2]; + _JLU3_MIX(a,b,c); + size -= 12; + k += 3; + } + + /*------------------------- handle the last (probably partial) block */ + /* + * "k[2]<<8" actually reads beyond the end of the string, but + * then shifts out the part it's not allowed to read. Because the + * string is aligned, the illegal read is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticably faster for short strings (like English words). + */ +#ifndef VALGRIND + + switch (size) { + case 12: c += k[2]; b+=k[1]; a+=k[0]; break; + case 11: c += k[2]&0xffffff00; b+=k[1]; a+=k[0]; break; + case 10: c += k[2]&0xffff0000; b+=k[1]; a+=k[0]; break; + case 9: c += k[2]&0xff000000; b+=k[1]; a+=k[0]; break; + case 8: b += k[1]; a+=k[0]; break; + case 7: b += k[1]&0xffffff00; a+=k[0]; break; + case 6: b += k[1]&0xffff0000; a+=k[0]; break; + case 5: b += k[1]&0xff000000; a+=k[0]; break; + case 4: a += k[0]; break; + case 3: a += k[0]&0xffffff00; break; + case 2: a += k[0]&0xffff0000; break; + case 1: a += k[0]&0xff000000; break; + case 0: goto exit; + } + +#else /* make valgrind happy */ + + k8 = (const uint8_t *)k; + switch (size) { /* all the case statements fall through */ + case 12: c += k[2]; b+=k[1]; a+=k[0]; break; + case 11: c += ((uint32_t)k8[10])<<8; /*@fallthrough@*/ + case 10: c += ((uint32_t)k8[9])<<16; /*@fallthrough@*/ + case 9: c += ((uint32_t)k8[8])<<24; /*@fallthrough@*/ + case 8: b += k[1]; a+=k[0]; break; + case 7: b += ((uint32_t)k8[6])<<8; /*@fallthrough@*/ + case 6: b += ((uint32_t)k8[5])<<16; /*@fallthrough@*/ + case 5: b += ((uint32_t)k8[4])<<24; /*@fallthrough@*/ + case 4: a += k[0]; break; + case 3: a += ((uint32_t)k8[2])<<8; /*@fallthrough@*/ + case 2: a += ((uint32_t)k8[1])<<16; /*@fallthrough@*/ + case 1: a += ((uint32_t)k8[0])<<24; break; + case 0: goto exit; + } + +#endif /* !VALGRIND */ + + } else { /* need to read the key one byte at a time */ + const uint8_t *k = (const uint8_t *)key; + + /*----------- all but the last block: affect some 32 bits of (a,b,c) */ + while (size > 12) { + a += ((uint32_t)k[0])<<24; + a += ((uint32_t)k[1])<<16; + a += ((uint32_t)k[2])<<8; + a += ((uint32_t)k[3]); + b += ((uint32_t)k[4])<<24; + b += ((uint32_t)k[5])<<16; + b += ((uint32_t)k[6])<<8; + b += ((uint32_t)k[7]); + c += ((uint32_t)k[8])<<24; + c += ((uint32_t)k[9])<<16; + c += ((uint32_t)k[10])<<8; + c += ((uint32_t)k[11]); + _JLU3_MIX(a,b,c); + size -= 12; + k += 12; + } + + /*---------------------------- last block: affect all 32 bits of (c) */ + switch (size) { /* all the case statements fall through */ + case 12: c += k[11]; /*@fallthrough@*/ + case 11: c += ((uint32_t)k[10])<<8; /*@fallthrough@*/ + case 10: c += ((uint32_t)k[9])<<16; /*@fallthrough@*/ + case 9: c += ((uint32_t)k[8])<<24; /*@fallthrough@*/ + case 8: b += k[7]; /*@fallthrough@*/ + case 7: b += ((uint32_t)k[6])<<8; /*@fallthrough@*/ + case 6: b += ((uint32_t)k[5])<<16; /*@fallthrough@*/ + case 5: b += ((uint32_t)k[4])<<24; /*@fallthrough@*/ + case 4: a += k[3]; /*@fallthrough@*/ + case 3: a += ((uint32_t)k[2])<<8; /*@fallthrough@*/ + case 2: a += ((uint32_t)k[1])<<16; /*@fallthrough@*/ + case 1: a += ((uint32_t)k[0])<<24; /*@fallthrough@*/ + break; + case 0: + goto exit; + } + } + + _JLU3_FINAL(a,b,c); + +exit: + return c; +} +#endif /* defined(_JLU3_jlu32b) */ + +#if defined(_JLU3_SELFTEST) + +/* used for timings */ +static void driver1(void) + /*@*/ +{ + uint8_t buf[256]; + uint32_t i; + uint32_t h=0; + time_t a,z; + + time(&a); + for (i=0; i<256; ++i) buf[i] = 'x'; + for (i=0; i<1; ++i) { + h = jlu32l(h, &buf[0], sizeof(buf[0])); + } + time(&z); + if (z-a > 0) printf("time %d %.8x\n", (int)(z-a), h); +} + +/* check that every input bit changes every output bit half the time */ +#define HASHSTATE 1 +#define HASHLEN 1 +#define MAXPAIR 60 +#define MAXLEN 70 +static void driver2(void) + /*@*/ +{ + uint8_t qa[MAXLEN+1], qb[MAXLEN+2], *a = &qa[0], *b = &qb[1]; + uint32_t c[HASHSTATE], d[HASHSTATE], i=0, j=0, k, l, m=0, z; + uint32_t e[HASHSTATE],f[HASHSTATE],g[HASHSTATE],h[HASHSTATE]; + uint32_t x[HASHSTATE],y[HASHSTATE]; + uint32_t hlen; + + printf("No more than %d trials should ever be needed \n",MAXPAIR/2); + for (hlen=0; hlen < MAXLEN; ++hlen) { + z=0; + for (i=0; i>(8-j)); + c[0] = jlu32l(m, a, hlen); + b[i] ^= ((k+1)<>(8-j)); + d[0] = jlu32l(m, b, hlen); + /* check every bit is 1, 0, set, and not set at least once */ + for (l=0; lz) z=k; + if (k == MAXPAIR) { + printf("Some bit didn't change: "); + printf("%.8x %.8x %.8x %.8x %.8x %.8x ", + e[0],f[0],g[0],h[0],x[0],y[0]); + printf("i %d j %d m %d len %d\n", i, j, m, hlen); + } + if (z == MAXPAIR) goto done; + } + } + } + done: + if (z < MAXPAIR) { + printf("Mix success %2d bytes %2d initvals ",i,m); + printf("required %d trials\n", z/2); + } + } + printf("\n"); +} + +/* Check for reading beyond the end of the buffer and alignment problems */ +static void driver3(void) + /*@*/ +{ + uint8_t buf[MAXLEN+20], *b; + uint32_t len; + uint8_t q[] = "This is the time for all good men to come to the aid of their country..."; + uint32_t h; + uint8_t qq[] = "xThis is the time for all good men to come to the aid of their country..."; + uint32_t i; + uint8_t qqq[] = "xxThis is the time for all good men to come to the aid of their country..."; + uint32_t j; + uint8_t qqqq[] = "xxxThis is the time for all good men to come to the aid of their country..."; + uint32_t ref,x,y; + uint8_t *p; + uint32_t m = 13; + + printf("Endianness. These lines should all be the same (for values filled in):\n"); + printf("%.8x %.8x %.8x\n", + jlu32w(m, (const uint32_t *)q, (sizeof(q)-1)/4), + jlu32w(m, (const uint32_t *)q, (sizeof(q)-5)/4), + jlu32w(m, (const uint32_t *)q, (sizeof(q)-9)/4)); + p = q; + printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + jlu32l(m, p, sizeof(q)-1), jlu32l(m, p, sizeof(q)-2), + jlu32l(m, p, sizeof(q)-3), jlu32l(m, p, sizeof(q)-4), + jlu32l(m, p, sizeof(q)-5), jlu32l(m, p, sizeof(q)-6), + jlu32l(m, p, sizeof(q)-7), jlu32l(m, p, sizeof(q)-8), + jlu32l(m, p, sizeof(q)-9), jlu32l(m, p, sizeof(q)-10), + jlu32l(m, p, sizeof(q)-11), jlu32l(m, p, sizeof(q)-12)); + p = &qq[1]; + printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + jlu32l(m, p, sizeof(q)-1), jlu32l(m, p, sizeof(q)-2), + jlu32l(m, p, sizeof(q)-3), jlu32l(m, p, sizeof(q)-4), + jlu32l(m, p, sizeof(q)-5), jlu32l(m, p, sizeof(q)-6), + jlu32l(m, p, sizeof(q)-7), jlu32l(m, p, sizeof(q)-8), + jlu32l(m, p, sizeof(q)-9), jlu32l(m, p, sizeof(q)-10), + jlu32l(m, p, sizeof(q)-11), jlu32l(m, p, sizeof(q)-12)); + p = &qqq[2]; + printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + jlu32l(m, p, sizeof(q)-1), jlu32l(m, p, sizeof(q)-2), + jlu32l(m, p, sizeof(q)-3), jlu32l(m, p, sizeof(q)-4), + jlu32l(m, p, sizeof(q)-5), jlu32l(m, p, sizeof(q)-6), + jlu32l(m, p, sizeof(q)-7), jlu32l(m, p, sizeof(q)-8), + jlu32l(m, p, sizeof(q)-9), jlu32l(m, p, sizeof(q)-10), + jlu32l(m, p, sizeof(q)-11), jlu32l(m, p, sizeof(q)-12)); + p = &qqqq[3]; + printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", + jlu32l(m, p, sizeof(q)-1), jlu32l(m, p, sizeof(q)-2), + jlu32l(m, p, sizeof(q)-3), jlu32l(m, p, sizeof(q)-4), + jlu32l(m, p, sizeof(q)-5), jlu32l(m, p, sizeof(q)-6), + jlu32l(m, p, sizeof(q)-7), jlu32l(m, p, sizeof(q)-8), + jlu32l(m, p, sizeof(q)-9), jlu32l(m, p, sizeof(q)-10), + jlu32l(m, p, sizeof(q)-11), jlu32l(m, p, sizeof(q)-12)); + printf("\n"); + for (h=0, b=buf+1; h<8; ++h, ++b) { + for (i=0; i +#endif +#include + +#include "poptint.h" + +#ifdef MYDEBUG +/*@unchecked@*/ +int _popt_debug = 0; +#endif + +/*@unchecked@*/ +unsigned int _poptArgMask = POPT_ARG_MASK; +/*@unchecked@*/ +unsigned int _poptGroupMask = POPT_GROUP_MASK; + +#if !defined(HAVE_STRERROR) && !defined(__LCLINT__) +static char * strerror(int errno) +{ + extern int sys_nerr; + extern char * sys_errlist[]; + + if ((0 <= errno) && (errno < sys_nerr)) + return sys_errlist[errno]; + else + return POPT_("unknown errno"); +} +#endif + +#ifdef MYDEBUG +/*@unused@*/ +static void prtcon(const char *msg, poptContext con) +{ + if (msg) fprintf(stderr, "%s", msg); + fprintf(stderr, "\tcon %p os %p nextCharArg \"%s\" nextArg \"%s\" argv[%d] \"%s\"\n", + con, con->os, + (con->os->nextCharArg ? con->os->nextCharArg : ""), + (con->os->nextArg ? con->os->nextArg : ""), + con->os->next, + (con->os->argv && con->os->argv[con->os->next] + ? con->os->argv[con->os->next] : "")); +} +#endif + +void poptSetExecPath(poptContext con, const char * path, int allowAbsolute) +{ + con->execPath = _free(con->execPath); + con->execPath = xstrdup(path); + con->execAbsolute = allowAbsolute; + return; +} + +static void invokeCallbacksPRE(poptContext con, const struct poptOption * opt) + /*@globals internalState@*/ + /*@modifies internalState@*/ +{ + if (opt != NULL) + for (; opt->longName || opt->shortName || opt->arg; opt++) { + poptArg arg = { .ptr = opt->arg }; + if (arg.ptr) + switch (poptArgType(opt)) { + case POPT_ARG_INCLUDE_TABLE: /* Recurse on included sub-tables. */ + poptSubstituteHelpI18N(arg.opt); /* XXX side effects */ + invokeCallbacksPRE(con, arg.opt); + /*@switchbreak@*/ break; + case POPT_ARG_CALLBACK: /* Perform callback. */ + if (!CBF_ISSET(opt, PRE)) + /*@switchbreak@*/ break; +/*@-noeffectuncon @*/ /* XXX no known way to annotate (*vector) calls. */ + arg.cb(con, POPT_CALLBACK_REASON_PRE, NULL, NULL, opt->descrip); +/*@=noeffectuncon @*/ + /*@switchbreak@*/ break; + } + } +} + +static void invokeCallbacksPOST(poptContext con, const struct poptOption * opt) + /*@globals internalState@*/ + /*@modifies internalState@*/ +{ + if (opt != NULL) + for (; opt->longName || opt->shortName || opt->arg; opt++) { + poptArg arg = { .ptr = opt->arg }; + if (arg.ptr) + switch (poptArgType(opt)) { + case POPT_ARG_INCLUDE_TABLE: /* Recurse on included sub-tables. */ + poptSubstituteHelpI18N(arg.opt); /* XXX side effects */ + invokeCallbacksPOST(con, arg.opt); + /*@switchbreak@*/ break; + case POPT_ARG_CALLBACK: /* Perform callback. */ + if (!CBF_ISSET(opt, POST)) + /*@switchbreak@*/ break; +/*@-noeffectuncon @*/ /* XXX no known way to annotate (*vector) calls. */ + arg.cb(con, POPT_CALLBACK_REASON_POST, NULL, NULL, opt->descrip); +/*@=noeffectuncon @*/ + /*@switchbreak@*/ break; + } + } +} + +static void invokeCallbacksOPTION(poptContext con, + const struct poptOption * opt, + const struct poptOption * myOpt, + /*@null@*/ const void * myData, int shorty) + /*@globals internalState@*/ + /*@modifies internalState@*/ +{ + const struct poptOption * cbopt = NULL; + poptArg cbarg = { .ptr = NULL }; + + if (opt != NULL) + for (; opt->longName || opt->shortName || opt->arg; opt++) { + poptArg arg = { .ptr = opt->arg }; + switch (poptArgType(opt)) { + case POPT_ARG_INCLUDE_TABLE: /* Recurse on included sub-tables. */ + poptSubstituteHelpI18N(arg.opt); /* XXX side effects */ + if (opt->arg != NULL) + invokeCallbacksOPTION(con, opt->arg, myOpt, myData, shorty); + /*@switchbreak@*/ break; + case POPT_ARG_CALLBACK: /* Save callback info. */ + if (CBF_ISSET(opt, SKIPOPTION)) + /*@switchbreak@*/ break; + cbopt = opt; + cbarg.ptr = opt->arg; + /*@switchbreak@*/ break; + default: /* Perform callback on matching option. */ + if (cbopt == NULL || cbarg.cb == NULL) + /*@switchbreak@*/ break; + if ((myOpt->shortName && opt->shortName && shorty && + myOpt->shortName == opt->shortName) + || (myOpt->longName != NULL && opt->longName != NULL && + !strcmp(myOpt->longName, opt->longName))) + { const void *cbData = (cbopt->descrip ? cbopt->descrip : myData); +/*@-noeffectuncon @*/ /* XXX no known way to annotate (*vector) calls. */ + cbarg.cb(con, POPT_CALLBACK_REASON_OPTION, + myOpt, con->os->nextArg, cbData); +/*@=noeffectuncon @*/ + /* Terminate (unless explcitly continuing). */ + if (!CBF_ISSET(cbopt, CONTINUE)) + return; + } + /*@switchbreak@*/ break; + } + } +} + +poptContext poptGetContext(const char * name, int argc, const char ** argv, + const struct poptOption * options, unsigned int flags) +{ + poptContext con = malloc(sizeof(*con)); + + if (con == NULL) return NULL; /* XXX can't happen */ + memset(con, 0, sizeof(*con)); + + con->os = con->optionStack; + con->os->argc = argc; +/*@-dependenttrans -assignexpose@*/ /* FIX: W2DO? */ + con->os->argv = argv; +/*@=dependenttrans =assignexpose@*/ + con->os->argb = NULL; + + if (!(flags & POPT_CONTEXT_KEEP_FIRST)) + con->os->next = 1; /* skip argv[0] */ + + con->leftovers = calloc( (size_t)(argc + 1), sizeof(*con->leftovers) ); +/*@-dependenttrans -assignexpose@*/ /* FIX: W2DO? */ + con->options = options; +/*@=dependenttrans =assignexpose@*/ + con->aliases = NULL; + con->numAliases = 0; + con->flags = flags; + con->execs = NULL; + con->numExecs = 0; + con->finalArgvAlloced = argc * 2; + con->finalArgv = calloc( (size_t)con->finalArgvAlloced, sizeof(*con->finalArgv) ); + con->execAbsolute = 1; + con->arg_strip = NULL; + + if (getenv("POSIXLY_CORRECT") || getenv("POSIX_ME_HARDER")) + con->flags |= POPT_CONTEXT_POSIXMEHARDER; + + if (name) + con->appName = xstrdup(name); + + invokeCallbacksPRE(con, con->options); + + return con; +} + +static void cleanOSE(/*@special@*/ struct optionStackEntry *os) + /*@uses os @*/ + /*@releases os->nextArg, os->argv, os->argb @*/ + /*@modifies os @*/ +{ + os->nextArg = _free(os->nextArg); + os->argv = _free(os->argv); + os->argb = PBM_FREE(os->argb); +} + +void poptResetContext(poptContext con) +{ + int i; + + if (con == NULL) return; + while (con->os > con->optionStack) { + cleanOSE(con->os--); + } + con->os->argb = PBM_FREE(con->os->argb); + con->os->currAlias = NULL; + con->os->nextCharArg = NULL; + con->os->nextArg = NULL; + con->os->next = 1; /* skip argv[0] */ + + con->numLeftovers = 0; + con->nextLeftover = 0; + con->restLeftover = 0; + con->doExec = NULL; + + if (con->finalArgv != NULL) + for (i = 0; i < con->finalArgvCount; i++) { +/*@-unqualifiedtrans@*/ /* FIX: typedef double indirection. */ + con->finalArgv[i] = _free(con->finalArgv[i]); +/*@=unqualifiedtrans@*/ + } + + con->finalArgvCount = 0; + con->arg_strip = PBM_FREE(con->arg_strip); +/*@-nullstate@*/ /* FIX: con->finalArgv != NULL */ + return; +/*@=nullstate@*/ +} + +/* Only one of longName, shortName should be set, not both. */ +static int handleExec(/*@special@*/ poptContext con, + /*@null@*/ const char * longName, char shortName) + /*@uses con->execs, con->numExecs, con->flags, con->doExec, + con->finalArgv, con->finalArgvAlloced, con->finalArgvCount @*/ + /*@modifies con @*/ +{ + poptItem item; + int i; + + if (con->execs == NULL || con->numExecs <= 0) /* XXX can't happen */ + return 0; + + for (i = con->numExecs - 1; i >= 0; i--) { + item = con->execs + i; + if (longName && !(item->option.longName && + !strcmp(longName, item->option.longName))) + continue; + else if (shortName != item->option.shortName) + continue; + break; + } + if (i < 0) return 0; + + + if (con->flags & POPT_CONTEXT_NO_EXEC) + return 1; + + if (con->doExec == NULL) { + con->doExec = con->execs + i; + return 1; + } + + /* We already have an exec to do; remember this option for next + time 'round */ + if ((con->finalArgvCount + 1) >= (con->finalArgvAlloced)) { + con->finalArgvAlloced += 10; + con->finalArgv = realloc(con->finalArgv, + sizeof(*con->finalArgv) * con->finalArgvAlloced); + } + + i = con->finalArgvCount++; + if (con->finalArgv != NULL) /* XXX can't happen */ + { char *s = malloc((longName ? strlen(longName) : 0) + sizeof("--")); + if (s != NULL) { /* XXX can't happen */ + con->finalArgv[i] = s; + *s++ = '-'; + if (longName) + s = stpcpy( stpcpy(s, "-"), longName); + else + *s++ = shortName; + *s = '\0'; + } else + con->finalArgv[i] = NULL; + } + + return 1; +} + +/** + * Compare long option for equality, adjusting for POPT_ARGFLAG_TOGGLE. + * @param opt option + * @param longName arg option + * @param longNameLen arg option length + * @return does long option match? + */ +static int +longOptionStrcmp(const struct poptOption * opt, + /*@null@*/ const char * longName, size_t longNameLen) + /*@*/ +{ + const char * optLongName = opt->longName; + int rc; + + if (optLongName == NULL || longName == NULL) /* XXX can't heppen */ + return 0; + + if (F_ISSET(opt, TOGGLE)) { + if (optLongName[0] == 'n' && optLongName[1] == 'o') { + optLongName += sizeof("no") - 1; + if (optLongName[0] == '-') + optLongName++; + } + if (longName[0] == 'n' && longName[1] == 'o') { + longName += sizeof("no") - 1; + longNameLen -= sizeof("no") - 1; + if (longName[0] == '-') { + longName++; + longNameLen--; + } + } + } + rc = (int)(strlen(optLongName) == longNameLen); + if (rc) + rc = (int)(strncmp(optLongName, longName, longNameLen) == 0); + return rc; +} + +/* Only one of longName, shortName may be set at a time */ +static int handleAlias(/*@special@*/ poptContext con, + /*@null@*/ const char * longName, size_t longNameLen, + char shortName, + /*@exposed@*/ /*@null@*/ const char * nextArg) + /*@uses con->aliases, con->numAliases, con->optionStack, con->os, + con->os->currAlias, con->os->currAlias->option.longName @*/ + /*@modifies con @*/ +{ + poptItem item = con->os->currAlias; + int rc; + int i; + + if (item) { + if (longName && item->option.longName != NULL + && longOptionStrcmp(&item->option, longName, longNameLen)) + return 0; + else + if (shortName && shortName == item->option.shortName) + return 0; + } + + if (con->aliases == NULL || con->numAliases <= 0) /* XXX can't happen */ + return 0; + + for (i = con->numAliases - 1; i >= 0; i--) { + item = con->aliases + i; + if (longName) { + if (item->option.longName == NULL) + continue; + if (!longOptionStrcmp(&item->option, longName, longNameLen)) + continue; + } else if (shortName != item->option.shortName) + continue; + break; + } + if (i < 0) return 0; + + if ((con->os - con->optionStack + 1) == POPT_OPTION_DEPTH) + return POPT_ERROR_OPTSTOODEEP; + + if (longName == NULL && nextArg != NULL && *nextArg != '\0') + con->os->nextCharArg = nextArg; + + con->os++; + con->os->next = 0; + con->os->stuffed = 0; + con->os->nextArg = NULL; + con->os->nextCharArg = NULL; + con->os->currAlias = con->aliases + i; + { const char ** av; + int ac = con->os->currAlias->argc; + /* Append --foo=bar arg to alias argv array (if present). */ + if (longName && nextArg != NULL && *nextArg != '\0') { + av = malloc((ac + 1 + 1) * sizeof(*av)); + if (av != NULL) { /* XXX won't happen. */ + for (i = 0; i < ac; i++) { + av[i] = con->os->currAlias->argv[i]; + } + av[ac++] = nextArg; + av[ac] = NULL; + } else /* XXX revert to old popt behavior if malloc fails. */ + av = con->os->currAlias->argv; + } else + av = con->os->currAlias->argv; + rc = poptDupArgv(ac, av, &con->os->argc, &con->os->argv); + if (av != NULL && av != con->os->currAlias->argv) + free(av); + } + con->os->argb = NULL; + + return (rc ? rc : 1); +} + +/** + * Return absolute path to executable by searching PATH. + * @param argv0 name of executable + * @return (malloc'd) absolute path to executable (or NULL) + */ +static /*@null@*/ +const char * findProgramPath(/*@null@*/ const char * argv0) + /*@*/ +{ + char *path = NULL, *s = NULL, *se; + char *t = NULL; + + if (argv0 == NULL) return NULL; /* XXX can't happen */ + + /* If there is a / in argv[0], it has to be an absolute path. */ + /* XXX Hmmm, why not if (argv0[0] == '/') ... instead? */ + if (strchr(argv0, '/')) + return xstrdup(argv0); + + if ((path = getenv("PATH")) == NULL || (path = xstrdup(path)) == NULL) + return NULL; + + /* The return buffer in t is big enough for any path. */ + if ((t = malloc(strlen(path) + strlen(argv0) + sizeof("/"))) != NULL) + for (s = path; s && *s; s = se) { + + /* Snip PATH element into [s,se). */ + if ((se = strchr(s, ':'))) + *se++ = '\0'; + + /* Append argv0 to PATH element. */ + (void) stpcpy(stpcpy(stpcpy(t, s), "/"), argv0); + + /* If file is executable, bingo! */ + if (!access(t, X_OK)) + break; + } + + /* If no executable was found in PATH, return NULL. */ +/*@-compdef@*/ + if (!(s && *s) && t != NULL) + t = _free(t); +/*@=compdef@*/ +/*@-modobserver -observertrans -usedef @*/ + path = _free(path); +/*@=modobserver =observertrans =usedef @*/ + + return t; +} + +static int execCommand(poptContext con) + /*@globals internalState @*/ + /*@modifies internalState @*/ +{ + poptItem item = con->doExec; + poptArgv argv = NULL; + int argc = 0; + int rc; + int ec = POPT_ERROR_ERRNO; + + if (item == NULL) /*XXX can't happen*/ + return POPT_ERROR_NOARG; + + if (item->argv == NULL || item->argc < 1 || + (!con->execAbsolute && strchr(item->argv[0], '/'))) + return POPT_ERROR_NOARG; + + argv = malloc(sizeof(*argv) * + (6 + item->argc + con->numLeftovers + con->finalArgvCount)); + if (argv == NULL) return POPT_ERROR_MALLOC; + + if (!strchr(item->argv[0], '/') && con->execPath != NULL) { + char *s = malloc(strlen(con->execPath) + strlen(item->argv[0]) + sizeof("/")); + if (s) + (void)stpcpy(stpcpy(stpcpy(s, con->execPath), "/"), item->argv[0]); + + argv[argc] = s; + } else + argv[argc] = findProgramPath(item->argv[0]); + if (argv[argc++] == NULL) { + ec = POPT_ERROR_NOARG; + goto exit; + } + + if (item->argc > 1) { + memcpy(argv + argc, item->argv + 1, sizeof(*argv) * (item->argc - 1)); + argc += (item->argc - 1); + } + + if (con->finalArgv != NULL && con->finalArgvCount > 0) { + memcpy(argv + argc, con->finalArgv, + sizeof(*argv) * con->finalArgvCount); + argc += con->finalArgvCount; + } + + if (con->leftovers != NULL && con->numLeftovers > 0) { + memcpy(argv + argc, con->leftovers, sizeof(*argv) * con->numLeftovers); + argc += con->numLeftovers; + } + + argv[argc] = NULL; + +#if defined(hpux) || defined(__hpux) + rc = setresgid(getgid(), getgid(),-1); + if (rc) goto exit; + rc = setresuid(getuid(), getuid(),-1); + if (rc) goto exit; +#else +/* + * XXX " ... on BSD systems setuid() should be preferred over setreuid()" + * XXX sez' Timur Bakeyev + * XXX from Norbert Warmuth + */ +#if defined(HAVE_SETUID) + rc = setgid(getgid()); + if (rc) goto exit; + rc = setuid(getuid()); + if (rc) goto exit; +#elif defined (HAVE_SETREUID) + rc = setregid(getgid(), getgid()); + if (rc) goto exit; + rc = setreuid(getuid(), getuid()); + if (rc) goto exit; +#else + ; /* Can't drop privileges */ +#endif +#endif + +#ifdef MYDEBUG +if (_popt_debug) + { poptArgv avp; + fprintf(stderr, "==> execvp(%s) argv[%d]:", argv[0], argc); + for (avp = argv; *avp; avp++) + fprintf(stderr, " '%s'", *avp); + fprintf(stderr, "\n"); + } +#endif + +/*@-nullstate@*/ + rc = execvp(argv[0], (char *const *)argv); +/*@=nullstate@*/ + +exit: + if (argv) { + if (argv[0]) + free((void *)argv[0]); + free(argv); + } + return ec; +} + +/*@observer@*/ /*@null@*/ +static const struct poptOption * +findOption(const struct poptOption * opt, + /*@null@*/ const char * longName, size_t longNameLen, + char shortName, + /*@null@*/ /*@out@*/ poptCallbackType * callback, + /*@null@*/ /*@out@*/ const void ** callbackData, + unsigned int argInfo) + /*@modifies *callback, *callbackData */ +{ + const struct poptOption * cb = NULL; + poptArg cbarg = { .ptr = NULL }; + + /* This happens when a single - is given */ + if (LF_ISSET(ONEDASH) && !shortName && (longName && *longName == '\0')) + shortName = '-'; + + for (; opt->longName || opt->shortName || opt->arg; opt++) { + poptArg arg = { .ptr = opt->arg }; + + switch (poptArgType(opt)) { + case POPT_ARG_INCLUDE_TABLE: /* Recurse on included sub-tables. */ + { const struct poptOption * opt2; + + poptSubstituteHelpI18N(arg.opt); /* XXX side effects */ + if (arg.ptr == NULL) continue; /* XXX program error */ + opt2 = findOption(arg.opt, longName, longNameLen, shortName, callback, + callbackData, argInfo); + if (opt2 == NULL) continue; + /* Sub-table data will be inheirited if no data yet. */ +/*@-observertrans -dependenttrans @*/ + if (callback && *callback + && callbackData && *callbackData == NULL) + *callbackData = opt->descrip; +/*@=observertrans =dependenttrans @*/ + return opt2; + } /*@notreached@*/ /*@switchbreak@*/ break; + case POPT_ARG_CALLBACK: + cb = opt; + cbarg.ptr = opt->arg; + continue; + /*@notreached@*/ /*@switchbreak@*/ break; + default: + /*@switchbreak@*/ break; + } + + if (longName != NULL && opt->longName != NULL && + (!LF_ISSET(ONEDASH) || F_ISSET(opt, ONEDASH)) && + longOptionStrcmp(opt, longName, longNameLen)) + { + break; + } else if (shortName && shortName == opt->shortName) { + break; + } + } + + if (opt->longName == NULL && !opt->shortName) + return NULL; + +/*@-modobserver -mods @*/ + if (callback) + *callback = (cb ? cbarg.cb : NULL); + if (callbackData) +/*@-observertrans -dependenttrans @*/ + *callbackData = (cb && !CBF_ISSET(cb, INC_DATA) ? cb->descrip : NULL); +/*@=observertrans =dependenttrans @*/ +/*@=modobserver =mods @*/ + + return opt; +} + +static const char * findNextArg(/*@special@*/ poptContext con, + unsigned argx, int delete_arg) + /*@uses con->optionStack, con->os, + con->os->next, con->os->argb, con->os->argc, con->os->argv @*/ + /*@modifies con @*/ +{ + struct optionStackEntry * os = con->os; + const char * arg; + + do { + int i; + arg = NULL; + while (os->next == os->argc && os > con->optionStack) os--; + if (os->next == os->argc && os == con->optionStack) break; + if (os->argv != NULL) + for (i = os->next; i < os->argc; i++) { +/*@-sizeoftype@*/ + if (os->argb && PBM_ISSET(i, os->argb)) + /*@innercontinue@*/ continue; + if (*os->argv[i] == '-') + /*@innercontinue@*/ continue; + if (--argx > 0) + /*@innercontinue@*/ continue; + arg = os->argv[i]; + if (delete_arg) { + if (os->argb == NULL) os->argb = PBM_ALLOC(os->argc); + if (os->argb != NULL) /* XXX can't happen */ + PBM_SET(i, os->argb); + } + /*@innerbreak@*/ break; +/*@=sizeoftype@*/ + } + if (os > con->optionStack) os--; + } while (arg == NULL); + return arg; +} + +static /*@only@*/ /*@null@*/ const char * +expandNextArg(/*@special@*/ poptContext con, const char * s) + /*@uses con->optionStack, con->os, + con->os->next, con->os->argb, con->os->argc, con->os->argv @*/ + /*@modifies con @*/ +{ + const char * a = NULL; + char *t, *te; + size_t tn = strlen(s) + 1; + char c; + + te = t = malloc(tn); + if (t == NULL) return NULL; /* XXX can't happen */ + *t = '\0'; + while ((c = *s++) != '\0') { + switch (c) { +#if 0 /* XXX can't do this */ + case '\\': /* escape */ + c = *s++; + /*@switchbreak@*/ break; +#endif + case '!': + if (!(s[0] == '#' && s[1] == ':' && s[2] == '+')) + /*@switchbreak@*/ break; + /* XXX Make sure that findNextArg deletes only next arg. */ + if (a == NULL) { + if ((a = findNextArg(con, 1U, 1)) == NULL) + /*@switchbreak@*/ break; + } + s += sizeof("#:+") - 1; + + tn += strlen(a); + { size_t pos = (size_t) (te - t); + if ((t = realloc(t, tn)) == NULL) /* XXX can't happen */ + return NULL; + te = stpcpy(t + pos, a); + } + continue; + /*@notreached@*/ /*@switchbreak@*/ break; + default: + /*@switchbreak@*/ break; + } + *te++ = c; + } + *te++ = '\0'; + /* If the new string is longer than needed, shorten. */ + if ((t + tn) > te) { +/*@-usereleased@*/ /* XXX splint can't follow the pointers. */ + if ((te = realloc(t, (size_t)(te - t))) == NULL) + free(t); + t = te; +/*@=usereleased@*/ + } + return t; +} + +static void poptStripArg(/*@special@*/ poptContext con, int which) + /*@uses con->optionStack @*/ + /*@defines con->arg_strip @*/ + /*@modifies con @*/ +{ +/*@-compdef -sizeoftype -usedef @*/ + if (con->arg_strip == NULL) + con->arg_strip = PBM_ALLOC(con->optionStack[0].argc); + if (con->arg_strip != NULL) /* XXX can't happen */ + PBM_SET(which, con->arg_strip); + return; +/*@=compdef =sizeoftype =usedef @*/ +} + +/*@unchecked@*/ +unsigned int _poptBitsN = _POPT_BITS_N; +/*@unchecked@*/ +unsigned int _poptBitsM = _POPT_BITS_M; +/*@unchecked@*/ +unsigned int _poptBitsK = _POPT_BITS_K; + +/*@-sizeoftype@*/ +static int _poptBitsNew(/*@null@*/ poptBits *bitsp) + /*@globals _poptBitsN, _poptBitsM, _poptBitsK @*/ + /*@modifies *bitsp, _poptBitsN, _poptBitsM, _poptBitsK @*/ +{ + if (bitsp == NULL) + return POPT_ERROR_NULLARG; + + /* XXX handle negated initialization. */ + if (*bitsp == NULL) { + if (_poptBitsN == 0) { + _poptBitsN = _POPT_BITS_N; + _poptBitsM = _POPT_BITS_M; + } + if (_poptBitsM == 0U) _poptBitsM = (3 * _poptBitsN) / 2; + if (_poptBitsK == 0U || _poptBitsK > 32U) _poptBitsK = _POPT_BITS_K; + *bitsp = PBM_ALLOC(_poptBitsM-1); + } +/*@-nullstate@*/ + return 0; +/*@=nullstate@*/ +} + +int poptBitsAdd(poptBits bits, const char * s) +{ + size_t ns = (s ? strlen(s) : 0); + uint32_t h0 = 0; + uint32_t h1 = 0; + + if (bits == NULL || ns == 0) + return POPT_ERROR_NULLARG; + + poptJlu32lpair(s, ns, &h0, &h1); + + for (ns = 0; ns < (size_t)_poptBitsK; ns++) { + uint32_t h = h0 + ns * h1; + uint32_t ix = (h % _poptBitsM); + PBM_SET(ix, bits); + } + return 0; +} + +int poptBitsChk(poptBits bits, const char * s) +{ + size_t ns = (s ? strlen(s) : 0); + uint32_t h0 = 0; + uint32_t h1 = 0; + int rc = 1; + + if (bits == NULL || ns == 0) + return POPT_ERROR_NULLARG; + + poptJlu32lpair(s, ns, &h0, &h1); + + for (ns = 0; ns < (size_t)_poptBitsK; ns++) { + uint32_t h = h0 + ns * h1; + uint32_t ix = (h % _poptBitsM); + if (PBM_ISSET(ix, bits)) + continue; + rc = 0; + break; + } + return rc; +} + +int poptBitsClr(poptBits bits) +{ + static size_t nbw = (__PBM_NBITS/8); + size_t nw = (__PBM_IX(_poptBitsM-1) + 1); + + if (bits == NULL) + return POPT_ERROR_NULLARG; + memset(bits, 0, nw * nbw); + return 0; +} + +int poptBitsDel(poptBits bits, const char * s) +{ + size_t ns = (s ? strlen(s) : 0); + uint32_t h0 = 0; + uint32_t h1 = 0; + + if (bits == NULL || ns == 0) + return POPT_ERROR_NULLARG; + + poptJlu32lpair(s, ns, &h0, &h1); + + for (ns = 0; ns < (size_t)_poptBitsK; ns++) { + uint32_t h = h0 + ns * h1; + uint32_t ix = (h % _poptBitsM); + PBM_CLR(ix, bits); + } + return 0; +} + +int poptBitsIntersect(poptBits *ap, const poptBits b) +{ + __pbm_bits *abits; + __pbm_bits *bbits; + __pbm_bits rc = 0; + size_t nw = (__PBM_IX(_poptBitsM-1) + 1); + size_t i; + + if (ap == NULL || b == NULL || _poptBitsNew(ap)) + return POPT_ERROR_NULLARG; + abits = __PBM_BITS(*ap); + bbits = __PBM_BITS(b); + + for (i = 0; i < nw; i++) { + abits[i] &= bbits[i]; + rc |= abits[i]; + } + return (rc ? 1 : 0); +} + +int poptBitsUnion(poptBits *ap, const poptBits b) +{ + __pbm_bits *abits; + __pbm_bits *bbits; + __pbm_bits rc = 0; + size_t nw = (__PBM_IX(_poptBitsM-1) + 1); + size_t i; + + if (ap == NULL || b == NULL || _poptBitsNew(ap)) + return POPT_ERROR_NULLARG; + abits = __PBM_BITS(*ap); + bbits = __PBM_BITS(b); + + for (i = 0; i < nw; i++) { + abits[i] |= bbits[i]; + rc |= abits[i]; + } + return (rc ? 1 : 0); +} + +int poptBitsArgs(poptContext con, poptBits *ap) +{ + const char ** av; + int rc = 0; + + if (con == NULL || ap == NULL || _poptBitsNew(ap) || + con->leftovers == NULL || con->numLeftovers == con->nextLeftover) + return POPT_ERROR_NULLARG; + + /* some apps like [like RPM ;-) ] need this NULL terminated */ + con->leftovers[con->numLeftovers] = NULL; + + for (av = con->leftovers + con->nextLeftover; *av != NULL; av++) { + if ((rc = poptBitsAdd(*ap, *av)) != 0) + break; + } +/*@-nullstate@*/ + return rc; +/*@=nullstate@*/ +} + +int poptSaveBits(poptBits * bitsp, + /*@unused@*/ UNUSED(unsigned int argInfo), const char * s) +{ + char *tbuf = NULL; + char *t, *te; + int rc = 0; + + if (bitsp == NULL || s == NULL || *s == '\0' || _poptBitsNew(bitsp)) + return POPT_ERROR_NULLARG; + + /* Parse comma separated attributes. */ + te = tbuf = xstrdup(s); + while ((t = te) != NULL && *t) { + while (*te != '\0' && *te != ',') + te++; + if (*te != '\0') + *te++ = '\0'; + /* XXX Ignore empty strings. */ + if (*t == '\0') + continue; + /* XXX Permit negated attributes. caveat emptor: false negatives. */ + if (*t == '!') { + t++; + if ((rc = poptBitsChk(*bitsp, t)) > 0) + rc = poptBitsDel(*bitsp, t); + } else + rc = poptBitsAdd(*bitsp, t); + if (rc) + break; + } + tbuf = _free(tbuf); + return rc; +} +/*@=sizeoftype@*/ + +int poptSaveString(const char *** argvp, + /*@unused@*/ UNUSED(unsigned int argInfo), const char * val) +{ + int argc = 0; + + if (argvp == NULL || val == NULL) + return POPT_ERROR_NULLARG; + + /* XXX likely needs an upper bound on argc. */ + if (*argvp != NULL) + while ((*argvp)[argc] != NULL) + argc++; + +/*@-unqualifiedtrans -nullstate@*/ /* XXX no annotation for (*argvp) */ + if ((*argvp = xrealloc(*argvp, (argc + 1 + 1) * sizeof(**argvp))) != NULL) { + (*argvp)[argc++] = xstrdup(val); + (*argvp)[argc ] = NULL; + } + return 0; +/*@=unqualifiedtrans =nullstate@*/ +} + +/*@unchecked@*/ +static unsigned int seed = 0; + +int poptSaveLongLong(long long * arg, unsigned int argInfo, long long aLongLong) +{ + if (arg == NULL +#ifdef NOTYET + /* XXX Check alignment, may fail on funky platforms. */ + || (((unsigned long long)arg) & (sizeof(*arg)-1)) +#endif + ) + return POPT_ERROR_NULLARG; + + if (aLongLong != 0 && LF_ISSET(RANDOM)) { +#if defined(HAVE_SRANDOM) + if (!seed) { + srandom((unsigned)getpid()); + srandom((unsigned)random()); + } + aLongLong = (long long)(random() % (aLongLong > 0 ? aLongLong : -aLongLong)); + aLongLong++; +#else + /* XXX avoid adding POPT_ERROR_UNIMPLEMENTED to minimize i18n churn. */ + return POPT_ERROR_BADOPERATION; +#endif + } + if (LF_ISSET(NOT)) + aLongLong = ~aLongLong; + switch (LF_ISSET(LOGICALOPS)) { + case 0: + *arg = aLongLong; + break; + case POPT_ARGFLAG_OR: + *(unsigned long long *)arg |= (unsigned long long)aLongLong; + break; + case POPT_ARGFLAG_AND: + *(unsigned long long *)arg &= (unsigned long long)aLongLong; + break; + case POPT_ARGFLAG_XOR: + *(unsigned long long *)arg ^= (unsigned long long)aLongLong; + break; + default: + return POPT_ERROR_BADOPERATION; + /*@notreached@*/ break; + } + return 0; +} + +int poptSaveLong(long * arg, unsigned int argInfo, long aLong) +{ + /* XXX Check alignment, may fail on funky platforms. */ + if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1))) + return POPT_ERROR_NULLARG; + + if (aLong != 0 && LF_ISSET(RANDOM)) { +#if defined(HAVE_SRANDOM) + if (!seed) { + srandom((unsigned)getpid()); + srandom((unsigned)random()); + } + aLong = random() % (aLong > 0 ? aLong : -aLong); + aLong++; +#else + /* XXX avoid adding POPT_ERROR_UNIMPLEMENTED to minimize i18n churn. */ + return POPT_ERROR_BADOPERATION; +#endif + } + if (LF_ISSET(NOT)) + aLong = ~aLong; + switch (LF_ISSET(LOGICALOPS)) { + case 0: *arg = aLong; break; + case POPT_ARGFLAG_OR: *(unsigned long *)arg |= (unsigned long)aLong; break; + case POPT_ARGFLAG_AND: *(unsigned long *)arg &= (unsigned long)aLong; break; + case POPT_ARGFLAG_XOR: *(unsigned long *)arg ^= (unsigned long)aLong; break; + default: + return POPT_ERROR_BADOPERATION; + /*@notreached@*/ break; + } + return 0; +} + +int poptSaveInt(/*@null@*/ int * arg, unsigned int argInfo, long aLong) +{ + /* XXX Check alignment, may fail on funky platforms. */ + if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1))) + return POPT_ERROR_NULLARG; + + if (aLong != 0 && LF_ISSET(RANDOM)) { +#if defined(HAVE_SRANDOM) + if (!seed) { + srandom((unsigned)getpid()); + srandom((unsigned)random()); + } + aLong = random() % (aLong > 0 ? aLong : -aLong); + aLong++; +#else + /* XXX avoid adding POPT_ERROR_UNIMPLEMENTED to minimize i18n churn. */ + return POPT_ERROR_BADOPERATION; +#endif + } + if (LF_ISSET(NOT)) + aLong = ~aLong; + switch (LF_ISSET(LOGICALOPS)) { + case 0: *arg = (int) aLong; break; + case POPT_ARGFLAG_OR: *(unsigned int *)arg |= (unsigned int) aLong; break; + case POPT_ARGFLAG_AND: *(unsigned int *)arg &= (unsigned int) aLong; break; + case POPT_ARGFLAG_XOR: *(unsigned int *)arg ^= (unsigned int) aLong; break; + default: + return POPT_ERROR_BADOPERATION; + /*@notreached@*/ break; + } + return 0; +} + +int poptSaveShort(/*@null@*/ short * arg, unsigned int argInfo, long aLong) +{ + /* XXX Check alignment, may fail on funky platforms. */ + if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1))) + return POPT_ERROR_NULLARG; + + if (aLong != 0 && LF_ISSET(RANDOM)) { +#if defined(HAVE_SRANDOM) + if (!seed) { + srandom((unsigned)getpid()); + srandom((unsigned)random()); + } + aLong = random() % (aLong > 0 ? aLong : -aLong); + aLong++; +#else + /* XXX avoid adding POPT_ERROR_UNIMPLEMENTED to minimize i18n churn. */ + return POPT_ERROR_BADOPERATION; +#endif + } + if (LF_ISSET(NOT)) + aLong = ~aLong; + switch (LF_ISSET(LOGICALOPS)) { + case 0: *arg = (short) aLong; + break; + case POPT_ARGFLAG_OR: *(unsigned short *)arg |= (unsigned short) aLong; + break; + case POPT_ARGFLAG_AND: *(unsigned short *)arg &= (unsigned short) aLong; + break; + case POPT_ARGFLAG_XOR: *(unsigned short *)arg ^= (unsigned short) aLong; + break; + default: return POPT_ERROR_BADOPERATION; + /*@notreached@*/ break; + } + return 0; +} + +/** + * Return argInfo field, handling POPT_ARGFLAG_TOGGLE overrides. + * @param con context + * @param opt option + * @return argInfo + */ +static unsigned int poptArgInfo(poptContext con, const struct poptOption * opt) + /*@*/ +{ + unsigned int argInfo = opt->argInfo; + + if (con->os->argv != NULL && con->os->next > 0 && opt->longName != NULL) + if (LF_ISSET(TOGGLE)) { + const char * longName = con->os->argv[con->os->next-1]; + while (*longName == '-') longName++; + /* XXX almost good enough but consider --[no]nofoo corner cases. */ + if (longName[0] != opt->longName[0] || longName[1] != opt->longName[1]) + { + if (!LF_ISSET(XOR)) { /* XXX dont toggle with XOR */ + /* Toggle POPT_BIT_SET <=> POPT_BIT_CLR. */ + if (LF_ISSET(LOGICALOPS)) + argInfo ^= (POPT_ARGFLAG_OR|POPT_ARGFLAG_AND); + argInfo ^= POPT_ARGFLAG_NOT; + } + } + } + return argInfo; +} + +/** + * Parse an integer expression. + * @retval *llp integer expression value + * @param argInfo integer expression type + * @param val integer expression string + * @return 0 on success, otherwise POPT_* error. + */ +static int poptParseInteger(long long * llp, + /*@unused@*/ UNUSED(unsigned int argInfo), + /*@null@*/ const char * val) + /*@modifies *llp @*/ +{ + if (val) { + char *end = NULL; + *llp = strtoll(val, &end, 0); + + /* XXX parse scaling suffixes here. */ + + if (!(end && *end == '\0')) + return POPT_ERROR_BADNUMBER; + } else + *llp = 0; + return 0; +} + +/** + * Save the option argument through the (*opt->arg) pointer. + * @param con context + * @param opt option + * @return 0 on success, otherwise POPT_* error. + */ +static int poptSaveArg(poptContext con, const struct poptOption * opt) + /*@globals fileSystem, internalState @*/ + /*@modifies con, fileSystem, internalState @*/ +{ + poptArg arg = { .ptr = opt->arg }; + int rc = 0; /* assume success */ + + switch (poptArgType(opt)) { + case POPT_ARG_BITSET: + /* XXX memory leak, application is responsible for free. */ + rc = poptSaveBits(arg.ptr, opt->argInfo, con->os->nextArg); + /*@switchbreak@*/ break; + case POPT_ARG_ARGV: + /* XXX memory leak, application is responsible for free. */ + rc = poptSaveString(arg.ptr, opt->argInfo, con->os->nextArg); + /*@switchbreak@*/ break; + case POPT_ARG_STRING: + /* XXX memory leak, application is responsible for free. */ + arg.argv[0] = (con->os->nextArg) ? xstrdup(con->os->nextArg) : NULL; + /*@switchbreak@*/ break; + + case POPT_ARG_INT: + case POPT_ARG_SHORT: + case POPT_ARG_LONG: + case POPT_ARG_LONGLONG: + { unsigned int argInfo = poptArgInfo(con, opt); + long long aNUM = 0; + + if ((rc = poptParseInteger(&aNUM, argInfo, con->os->nextArg)) != 0) + break; + + switch (poptArgType(opt)) { + case POPT_ARG_LONGLONG: +/* XXX let's not demand C99 compiler flags for quite yet. */ +#if !defined(LLONG_MAX) +# define LLONG_MAX 9223372036854775807LL +# define LLONG_MIN (-LLONG_MAX - 1LL) +#endif + rc = !(aNUM == LLONG_MIN || aNUM == LLONG_MAX) + ? poptSaveLongLong(arg.longlongp, argInfo, aNUM) + : POPT_ERROR_OVERFLOW; + /*@innerbreak@*/ break; + case POPT_ARG_LONG: + rc = !(aNUM < (long long)LONG_MIN || aNUM > (long long)LONG_MAX) + ? poptSaveLong(arg.longp, argInfo, (long)aNUM) + : POPT_ERROR_OVERFLOW; + /*@innerbreak@*/ break; + case POPT_ARG_INT: + rc = !(aNUM < (long long)INT_MIN || aNUM > (long long)INT_MAX) + ? poptSaveInt(arg.intp, argInfo, (long)aNUM) + : POPT_ERROR_OVERFLOW; + /*@innerbreak@*/ break; + case POPT_ARG_SHORT: + rc = !(aNUM < (long long)SHRT_MIN || aNUM > (long long)SHRT_MAX) + ? poptSaveShort(arg.shortp, argInfo, (long)aNUM) + : POPT_ERROR_OVERFLOW; + /*@innerbreak@*/ break; + } + } /*@switchbreak@*/ break; + + case POPT_ARG_FLOAT: + case POPT_ARG_DOUBLE: + { char *end = NULL; + double aDouble = 0.0; + + if (con->os->nextArg) { +/*@-mods@*/ + int saveerrno = errno; + errno = 0; + aDouble = strtod(con->os->nextArg, &end); + if (errno == ERANGE) { + rc = POPT_ERROR_OVERFLOW; + break; + } + errno = saveerrno; +/*@=mods@*/ + if (*end != '\0') { + rc = POPT_ERROR_BADNUMBER; + break; + } + } + + switch (poptArgType(opt)) { + case POPT_ARG_DOUBLE: + arg.doublep[0] = aDouble; + /*@innerbreak@*/ break; + case POPT_ARG_FLOAT: +#if !defined(DBL_EPSILON) && !defined(__LCLINT__) +#define DBL_EPSILON 2.2204460492503131e-16 +#endif +#define POPT_ABS(a) ((((a) - 0.0) < DBL_EPSILON) ? -(a) : (a)) + if ((FLT_MIN - POPT_ABS(aDouble)) > DBL_EPSILON + || (POPT_ABS(aDouble) - FLT_MAX) > DBL_EPSILON) + rc = POPT_ERROR_OVERFLOW; + else + arg.floatp[0] = (float) aDouble; + /*@innerbreak@*/ break; + } + } /*@switchbreak@*/ break; + case POPT_ARG_MAINCALL: +/*@-assignexpose -type@*/ + con->maincall = opt->arg; +/*@=assignexpose =type@*/ + /*@switchbreak@*/ break; + default: + fprintf(stdout, POPT_("option type (%u) not implemented in popt\n"), + poptArgType(opt)); + exit(EXIT_FAILURE); + /*@notreached@*/ /*@switchbreak@*/ break; + } + return rc; +} + +/* returns 'val' element, -1 on last item, POPT_ERROR_* on error */ +int poptGetNextOpt(poptContext con) +{ + const struct poptOption * opt = NULL; + int done = 0; + + if (con == NULL) + return -1; + while (!done) { + const char * origOptString = NULL; + poptCallbackType cb = NULL; + const void * cbData = NULL; + const char * longArg = NULL; + int canstrip = 0; + int shorty = 0; + + while (!con->os->nextCharArg && con->os->next == con->os->argc + && con->os > con->optionStack) { + cleanOSE(con->os--); + } + if (!con->os->nextCharArg && con->os->next == con->os->argc) { + invokeCallbacksPOST(con, con->options); + + if (con->maincall) { + /*@-noeffectuncon @*/ + (void) (*con->maincall) (con->finalArgvCount, con->finalArgv); + /*@=noeffectuncon @*/ + return -1; + } + + if (con->doExec) return execCommand(con); + return -1; + } + + /* Process next long option */ + if (!con->os->nextCharArg) { + const char * optString; + size_t optStringLen; + int thisopt; + +/*@-sizeoftype@*/ + if (con->os->argb && PBM_ISSET(con->os->next, con->os->argb)) { + con->os->next++; + continue; + } +/*@=sizeoftype@*/ + thisopt = con->os->next; + if (con->os->argv != NULL) /* XXX can't happen */ + origOptString = con->os->argv[con->os->next++]; + + if (origOptString == NULL) /* XXX can't happen */ + return POPT_ERROR_BADOPT; + + if (con->restLeftover || *origOptString != '-' || + (*origOptString == '-' && origOptString[1] == '\0')) + { + if (con->flags & POPT_CONTEXT_POSIXMEHARDER) + con->restLeftover = 1; + if (con->flags & POPT_CONTEXT_ARG_OPTS) { + con->os->nextArg = xstrdup(origOptString); + return 0; + } + if (con->leftovers != NULL) /* XXX can't happen */ + con->leftovers[con->numLeftovers++] = origOptString; + continue; + } + + /* Make a copy we can hack at */ + optString = origOptString; + + if (optString[0] == '\0') + return POPT_ERROR_BADOPT; + + if (optString[1] == '-' && !optString[2]) { + con->restLeftover = 1; + continue; + } else { + const char *oe; + unsigned int argInfo = 0; + + optString++; + if (*optString == '-') + optString++; + else + argInfo |= POPT_ARGFLAG_ONEDASH; + + /* Check for "--long=arg" option. */ + for (oe = optString; *oe && *oe != '='; oe++) + {}; + optStringLen = (size_t)(oe - optString); + if (*oe == '=') + longArg = oe + 1; + + /* XXX aliases with arg substitution need "--alias=arg" */ + if (handleAlias(con, optString, optStringLen, '\0', longArg)) { + longArg = NULL; + continue; + } + + if (handleExec(con, optString, '\0')) + continue; + + opt = findOption(con->options, optString, optStringLen, '\0', &cb, &cbData, + argInfo); + if (!opt && !LF_ISSET(ONEDASH)) + return POPT_ERROR_BADOPT; + } + + if (!opt) { + con->os->nextCharArg = origOptString + 1; + longArg = NULL; + } else { + if (con->os == con->optionStack && F_ISSET(opt, STRIP)) + { + canstrip = 1; + poptStripArg(con, thisopt); + } + shorty = 0; + } + } + + /* Process next short option */ + if (con->os->nextCharArg) { + const char * nextCharArg = con->os->nextCharArg; + + con->os->nextCharArg = NULL; + + if (handleAlias(con, NULL, 0, *nextCharArg, nextCharArg + 1)) + continue; + + if (handleExec(con, NULL, *nextCharArg)) { + /* Restore rest of short options for further processing */ + nextCharArg++; + if (*nextCharArg != '\0') + con->os->nextCharArg = nextCharArg; + continue; + } + + opt = findOption(con->options, NULL, 0, *nextCharArg, &cb, + &cbData, 0); + if (!opt) + return POPT_ERROR_BADOPT; + shorty = 1; + + nextCharArg++; + if (*nextCharArg != '\0') + con->os->nextCharArg = nextCharArg + (int)(*nextCharArg == '='); + } + + if (opt == NULL) return POPT_ERROR_BADOPT; /* XXX can't happen */ + if (opt->arg && poptArgType(opt) == POPT_ARG_NONE) { + unsigned int argInfo = poptArgInfo(con, opt); + if (poptSaveInt((int *)opt->arg, argInfo, 1L)) + return POPT_ERROR_BADOPERATION; + } else if (poptArgType(opt) == POPT_ARG_VAL) { + if (opt->arg) { + unsigned int argInfo = poptArgInfo(con, opt); + if (poptSaveInt((int *)opt->arg, argInfo, (long)opt->val)) + return POPT_ERROR_BADOPERATION; + } + } else if (poptArgType(opt) != POPT_ARG_NONE) { + int rc; + + con->os->nextArg = _free(con->os->nextArg); + if (longArg) { + longArg = expandNextArg(con, longArg); + con->os->nextArg = (char *) longArg; + } else if (con->os->nextCharArg) { + longArg = expandNextArg(con, con->os->nextCharArg); + con->os->nextArg = (char *) longArg; + con->os->nextCharArg = NULL; + } else { + while (con->os->next == con->os->argc && + con->os > con->optionStack) + { + cleanOSE(con->os--); + } + if (con->os->next == con->os->argc) { + if (!F_ISSET(opt, OPTIONAL)) + return POPT_ERROR_NOARG; + con->os->nextArg = NULL; + } else { + + /* + * Make sure this isn't part of a short arg or the + * result of an alias expansion. + */ + if (con->os == con->optionStack + && F_ISSET(opt, STRIP) && canstrip) + { + poptStripArg(con, con->os->next); + } + + if (con->os->argv != NULL) { /* XXX can't happen */ + if (F_ISSET(opt, OPTIONAL) && + con->os->argv[con->os->next][0] == '-') { + con->os->nextArg = NULL; + } else { + /* XXX watchout: subtle side-effects live here. */ + longArg = con->os->argv[con->os->next++]; + longArg = expandNextArg(con, longArg); + con->os->nextArg = (char *) longArg; + } + } + } + } + longArg = NULL; + + /* Save the option argument through a (*opt->arg) pointer. */ + if (opt->arg != NULL && (rc = poptSaveArg(con, opt)) != 0) + return rc; + } + + if (cb) + invokeCallbacksOPTION(con, con->options, opt, cbData, shorty); + else if (opt->val && (poptArgType(opt) != POPT_ARG_VAL)) + done = 1; + + if ((con->finalArgvCount + 2) >= (con->finalArgvAlloced)) { + con->finalArgvAlloced += 10; + con->finalArgv = realloc(con->finalArgv, + sizeof(*con->finalArgv) * con->finalArgvAlloced); + } + + if (con->finalArgv != NULL) + { char *s = malloc((opt->longName ? strlen(opt->longName) : 0) + sizeof("--")); + if (s != NULL) { /* XXX can't happen */ + con->finalArgv[con->finalArgvCount++] = s; + *s++ = '-'; + if (opt->longName) { + if (!F_ISSET(opt, ONEDASH)) + *s++ = '-'; + s = stpcpy(s, opt->longName); + } else { + *s++ = opt->shortName; + *s = '\0'; + } + } else + con->finalArgv[con->finalArgvCount++] = NULL; + } + + if (opt->arg && poptArgType(opt) == POPT_ARG_NONE) + /*@-ifempty@*/ ; /*@=ifempty@*/ + else if (poptArgType(opt) == POPT_ARG_VAL) + /*@-ifempty@*/ ; /*@=ifempty@*/ + else if (poptArgType(opt) != POPT_ARG_NONE) { + if (con->finalArgv != NULL && con->os->nextArg != NULL) + con->finalArgv[con->finalArgvCount++] = + xstrdup(con->os->nextArg); + } + } + + return (opt ? opt->val : -1); /* XXX can't happen */ +} + +char * poptGetOptArg(poptContext con) +{ + char * ret = NULL; + if (con) { + ret = con->os->nextArg; + con->os->nextArg = NULL; + } + return ret; +} + +const char * poptGetArg(poptContext con) +{ + const char * ret = NULL; + if (con && con->leftovers != NULL && con->nextLeftover < con->numLeftovers) + ret = con->leftovers[con->nextLeftover++]; + return ret; +} + +const char * poptPeekArg(poptContext con) +{ + const char * ret = NULL; + if (con && con->leftovers != NULL && con->nextLeftover < con->numLeftovers) + ret = con->leftovers[con->nextLeftover]; + return ret; +} + +const char ** poptGetArgs(poptContext con) +{ + if (con == NULL || + con->leftovers == NULL || con->numLeftovers == con->nextLeftover) + return NULL; + + /* some apps like [like RPM ;-) ] need this NULL terminated */ + con->leftovers[con->numLeftovers] = NULL; + +/*@-nullret -nullstate @*/ /* FIX: typedef double indirection. */ + return (con->leftovers + con->nextLeftover); +/*@=nullret =nullstate @*/ +} + +static /*@null@*/ +poptItem poptFreeItems(/*@only@*/ /*@null@*/ poptItem items, int nitems) + /*@modifies items @*/ +{ + if (items != NULL) { + poptItem item = items; + while (--nitems >= 0) { +/*@-modobserver -observertrans -dependenttrans@*/ + item->option.longName = _free(item->option.longName); + item->option.descrip = _free(item->option.descrip); + item->option.argDescrip = _free(item->option.argDescrip); +/*@=modobserver =observertrans =dependenttrans@*/ + item->argv = _free(item->argv); + item++; + } + items = _free(items); + } + return NULL; +} + +poptContext poptFreeContext(poptContext con) +{ + if (con == NULL) return con; + poptResetContext(con); + con->os->argb = _free(con->os->argb); + + con->aliases = poptFreeItems(con->aliases, con->numAliases); + con->numAliases = 0; + + con->execs = poptFreeItems(con->execs, con->numExecs); + con->numExecs = 0; + + con->leftovers = _free(con->leftovers); + con->finalArgv = _free(con->finalArgv); + con->appName = _free(con->appName); + con->otherHelp = _free(con->otherHelp); + con->execPath = _free(con->execPath); + con->arg_strip = PBM_FREE(con->arg_strip); + + con = _free(con); + return con; +} + +int poptAddAlias(poptContext con, struct poptAlias alias, + /*@unused@*/ UNUSED(int flags)) +{ + struct poptItem_s item_buf; + poptItem item = &item_buf; + memset(item, 0, sizeof(*item)); + item->option.longName = alias.longName; + item->option.shortName = alias.shortName; + item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN; + item->option.arg = 0; + item->option.val = 0; + item->option.descrip = NULL; + item->option.argDescrip = NULL; + item->argc = alias.argc; + item->argv = alias.argv; + return poptAddItem(con, item, 0); +} + +int poptAddItem(poptContext con, poptItem newItem, int flags) +{ + poptItem * items, item; + int * nitems; + + switch (flags) { + case 1: + items = &con->execs; + nitems = &con->numExecs; + break; + case 0: + items = &con->aliases; + nitems = &con->numAliases; + break; + default: + return 1; + /*@notreached@*/ break; + } + + *items = realloc((*items), ((*nitems) + 1) * sizeof(**items)); + if ((*items) == NULL) + return 1; + + item = (*items) + (*nitems); + + item->option.longName = + (newItem->option.longName ? xstrdup(newItem->option.longName) : NULL); + item->option.shortName = newItem->option.shortName; + item->option.argInfo = newItem->option.argInfo; + item->option.arg = newItem->option.arg; + item->option.val = newItem->option.val; + item->option.descrip = + (newItem->option.descrip ? xstrdup(newItem->option.descrip) : NULL); + item->option.argDescrip = + (newItem->option.argDescrip ? xstrdup(newItem->option.argDescrip) : NULL); + item->argc = newItem->argc; + item->argv = newItem->argv; + + (*nitems)++; + + return 0; +} + +const char * poptBadOption(poptContext con, unsigned int flags) +{ + struct optionStackEntry * os = NULL; + + if (con != NULL) + os = (flags & POPT_BADOPTION_NOALIAS) ? con->optionStack : con->os; + + return (os != NULL && os->argv != NULL ? os->argv[os->next - 1] : NULL); +} + +const char * poptStrerror(const int error) +{ + switch (error) { + case POPT_ERROR_NOARG: + return POPT_("missing argument"); + case POPT_ERROR_BADOPT: + return POPT_("unknown option"); + case POPT_ERROR_BADOPERATION: + return POPT_("mutually exclusive logical operations requested"); + case POPT_ERROR_NULLARG: + return POPT_("opt->arg should not be NULL"); + case POPT_ERROR_OPTSTOODEEP: + return POPT_("aliases nested too deeply"); + case POPT_ERROR_BADQUOTE: + return POPT_("error in parameter quoting"); + case POPT_ERROR_BADNUMBER: + return POPT_("invalid numeric value"); + case POPT_ERROR_OVERFLOW: + return POPT_("number too large or too small"); + case POPT_ERROR_MALLOC: + return POPT_("memory allocation failed"); + case POPT_ERROR_BADCONFIG: + return POPT_("config file failed sanity test"); + case POPT_ERROR_ERRNO: + return strerror(errno); + default: + return POPT_("unknown error"); + } +} + +int poptStuffArgs(poptContext con, const char ** argv) +{ + int argc; + int rc; + + if ((con->os - con->optionStack) == POPT_OPTION_DEPTH) + return POPT_ERROR_OPTSTOODEEP; + + for (argc = 0; argv[argc]; argc++) + {}; + + con->os++; + con->os->next = 0; + con->os->nextArg = NULL; + con->os->nextCharArg = NULL; + con->os->currAlias = NULL; + rc = poptDupArgv(argc, argv, &con->os->argc, &con->os->argv); + con->os->argb = NULL; + con->os->stuffed = 1; + + return rc; +} + +const char * poptGetInvocationName(poptContext con) +{ + return (con->os->argv ? con->os->argv[0] : ""); +} + +int poptStrippedArgv(poptContext con, int argc, char ** argv) +{ + int numargs = argc; + int j = 1; + int i; + +/*@-sizeoftype@*/ + if (con->arg_strip) + for (i = 1; i < argc; i++) { + if (PBM_ISSET(i, con->arg_strip)) + numargs--; + } + + for (i = 1; i < argc; i++) { + if (con->arg_strip && PBM_ISSET(i, con->arg_strip)) + continue; + argv[j] = (j < numargs) ? argv[i] : NULL; + j++; + } +/*@=sizeoftype@*/ + + return numargs; +} diff --git a/ldb-2.0.8/third_party/popt/popt.h b/ldb-2.0.8/third_party/popt/popt.h new file mode 100644 index 0000000..a12d143 --- /dev/null +++ b/ldb-2.0.8/third_party/popt/popt.h @@ -0,0 +1,744 @@ +/** \file popt/popt.h + * \ingroup popt + */ + +/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING + file accompanying popt source distributions, available from + ftp://ftp.rpm.org/pub/rpm/dist. */ + +#ifndef H_POPT +#define H_POPT + +#include /* for FILE * */ + +#define POPT_OPTION_DEPTH 10 + +/** \ingroup popt + * \name Arg type identifiers + */ +/*@{*/ +#define POPT_ARG_NONE 0U /*!< no arg */ +#define POPT_ARG_STRING 1U /*!< arg will be saved as string */ +#define POPT_ARG_INT 2U /*!< arg ==> int */ +#define POPT_ARG_LONG 3U /*!< arg ==> long */ +#define POPT_ARG_INCLUDE_TABLE 4U /*!< arg points to table */ +#define POPT_ARG_CALLBACK 5U /*!< table-wide callback... must be + set first in table; arg points + to callback, descrip points to + callback data to pass */ +#define POPT_ARG_INTL_DOMAIN 6U /*!< set the translation domain + for this table and any + included tables; arg points + to the domain string */ +#define POPT_ARG_VAL 7U /*!< arg should take value val */ +#define POPT_ARG_FLOAT 8U /*!< arg ==> float */ +#define POPT_ARG_DOUBLE 9U /*!< arg ==> double */ +#define POPT_ARG_LONGLONG 10U /*!< arg ==> long long */ + +#define POPT_ARG_MAINCALL 16U+11U /*!< EXPERIMENTAL: return (*arg) (argc, argv) */ +#define POPT_ARG_ARGV 12U /*!< dupe'd arg appended to realloc'd argv array. */ +#define POPT_ARG_SHORT 13U /*!< arg ==> short */ +#define POPT_ARG_BITSET 16U+14U /*!< arg ==> bit set */ + +#define POPT_ARG_MASK 0x000000FFU +#define POPT_GROUP_MASK 0x0000FF00U + +/*@}*/ + +/** \ingroup popt + * \name Arg modifiers + */ +/*@{*/ +#define POPT_ARGFLAG_ONEDASH 0x80000000U /*!< allow -longoption */ +#define POPT_ARGFLAG_DOC_HIDDEN 0x40000000U /*!< don't show in help/usage */ +#define POPT_ARGFLAG_STRIP 0x20000000U /*!< strip this arg from argv(only applies to long args) */ +#define POPT_ARGFLAG_OPTIONAL 0x10000000U /*!< arg may be missing */ + +#define POPT_ARGFLAG_OR 0x08000000U /*!< arg will be or'ed */ +#define POPT_ARGFLAG_NOR 0x09000000U /*!< arg will be nor'ed */ +#define POPT_ARGFLAG_AND 0x04000000U /*!< arg will be and'ed */ +#define POPT_ARGFLAG_NAND 0x05000000U /*!< arg will be nand'ed */ +#define POPT_ARGFLAG_XOR 0x02000000U /*!< arg will be xor'ed */ +#define POPT_ARGFLAG_NOT 0x01000000U /*!< arg will be negated */ +#define POPT_ARGFLAG_LOGICALOPS \ + (POPT_ARGFLAG_OR|POPT_ARGFLAG_AND|POPT_ARGFLAG_XOR) + +#define POPT_BIT_SET (POPT_ARG_VAL|POPT_ARGFLAG_OR) + /*!< set arg bit(s) */ +#define POPT_BIT_CLR (POPT_ARG_VAL|POPT_ARGFLAG_NAND) + /*!< clear arg bit(s) */ + +#define POPT_ARGFLAG_SHOW_DEFAULT 0x00800000U /*!< show default value in --help */ +#define POPT_ARGFLAG_RANDOM 0x00400000U /*!< random value in [1,arg] */ +#define POPT_ARGFLAG_TOGGLE 0x00200000U /*!< permit --[no]opt prefix toggle */ + +/*@}*/ + +/** \ingroup popt + * \name Callback modifiers + */ +/*@{*/ +#define POPT_CBFLAG_PRE 0x80000000U /*!< call the callback before parse */ +#define POPT_CBFLAG_POST 0x40000000U /*!< call the callback after parse */ +#define POPT_CBFLAG_INC_DATA 0x20000000U /*!< use data from the include line, + not the subtable */ +#define POPT_CBFLAG_SKIPOPTION 0x10000000U /*!< don't callback with option */ +#define POPT_CBFLAG_CONTINUE 0x08000000U /*!< continue callbacks with option */ +/*@}*/ + +/** \ingroup popt + * \name Error return values + */ +/*@{*/ +#define POPT_ERROR_NOARG -10 /*!< missing argument */ +#define POPT_ERROR_BADOPT -11 /*!< unknown option */ +#define POPT_ERROR_OPTSTOODEEP -13 /*!< aliases nested too deeply */ +#define POPT_ERROR_BADQUOTE -15 /*!< error in paramter quoting */ +#define POPT_ERROR_ERRNO -16 /*!< errno set, use strerror(errno) */ +#define POPT_ERROR_BADNUMBER -17 /*!< invalid numeric value */ +#define POPT_ERROR_OVERFLOW -18 /*!< number too large or too small */ +#define POPT_ERROR_BADOPERATION -19 /*!< mutually exclusive logical operations requested */ +#define POPT_ERROR_NULLARG -20 /*!< opt->arg should not be NULL */ +#define POPT_ERROR_MALLOC -21 /*!< memory allocation failed */ +#define POPT_ERROR_BADCONFIG -22 /*!< config file failed sanity test */ +/*@}*/ + +/** \ingroup popt + * \name poptBadOption() flags + */ +/*@{*/ +#define POPT_BADOPTION_NOALIAS (1U << 0) /*!< don't go into an alias */ +/*@}*/ + +/** \ingroup popt + * \name poptGetContext() flags + */ +/*@{*/ +#define POPT_CONTEXT_NO_EXEC (1U << 0) /*!< ignore exec expansions */ +#define POPT_CONTEXT_KEEP_FIRST (1U << 1) /*!< pay attention to argv[0] */ +#define POPT_CONTEXT_POSIXMEHARDER (1U << 2) /*!< options can't follow args */ +#define POPT_CONTEXT_ARG_OPTS (1U << 4) /*!< return args as options with value 0 */ +/*@}*/ + +/** \ingroup popt + */ +struct poptOption { +/*@observer@*/ /*@null@*/ + const char * longName; /*!< may be NULL */ + char shortName; /*!< may be NUL */ + unsigned int argInfo; +/*@shared@*/ /*@null@*/ + void * arg; /*!< depends on argInfo */ + int val; /*!< 0 means don't return, just update flag */ +/*@observer@*/ /*@null@*/ + const char * descrip; /*!< description for autohelp -- may be NULL */ +/*@observer@*/ /*@null@*/ + const char * argDescrip; /*!< argument description for autohelp */ +}; + +/** \ingroup popt + * A popt alias argument for poptAddAlias(). + */ +struct poptAlias { +/*@owned@*/ /*@null@*/ + const char * longName; /*!< may be NULL */ + char shortName; /*!< may be NUL */ + int argc; +/*@owned@*/ + const char ** argv; /*!< must be free()able */ +}; + +/** \ingroup popt + * A popt alias or exec argument for poptAddItem(). + */ +/*@-exporttype@*/ +typedef struct poptItem_s { + struct poptOption option; /*!< alias/exec name(s) and description. */ + int argc; /*!< (alias) no. of args. */ +/*@owned@*/ + const char ** argv; /*!< (alias) args, must be free()able. */ +} * poptItem; +/*@=exporttype@*/ + +/** \ingroup popt + * \name Auto-generated help/usage + */ +/*@{*/ + +/** + * Empty table marker to enable displaying popt alias/exec options. + */ +/*@-exportvar@*/ +/*@unchecked@*/ /*@observer@*/ +extern struct poptOption poptAliasOptions[]; +/*@=exportvar@*/ +#define POPT_AUTOALIAS { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptAliasOptions, \ + 0, "Options implemented via popt alias/exec:", NULL }, + +/** + * Auto help table options. + */ +/*@-exportvar@*/ +/*@unchecked@*/ /*@observer@*/ +extern struct poptOption poptHelpOptions[]; +/*@=exportvar@*/ + +/*@-exportvar@*/ +/*@unchecked@*/ /*@observer@*/ +extern struct poptOption * poptHelpOptionsI18N; +/*@=exportvar@*/ + +#define POPT_AUTOHELP { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptHelpOptions, \ + 0, "Help options:", NULL }, + +#define POPT_TABLEEND { NULL, '\0', 0, NULL, 0, NULL, NULL } +/*@}*/ + +/** \ingroup popt + */ +/*@-exporttype@*/ +typedef /*@abstract@*/ struct poptContext_s * poptContext; +/*@=exporttype@*/ + +/** \ingroup popt + */ +#ifndef __cplusplus +/*@-exporttype -typeuse@*/ +typedef struct poptOption * poptOption; +/*@=exporttype =typeuse@*/ +#endif + +/** \ingroup popt + */ +/*@-exportconst@*/ +enum poptCallbackReason { + POPT_CALLBACK_REASON_PRE = 0, + POPT_CALLBACK_REASON_POST = 1, + POPT_CALLBACK_REASON_OPTION = 2 +}; +/*@=exportconst@*/ + +#ifdef __cplusplus +extern "C" { +#endif +/*@-type@*/ + +/** \ingroup popt + * Table callback prototype. + * @param con context + * @param reason reason for callback + * @param opt option that triggered callback + * @param arg @todo Document. + * @param data @todo Document. + */ +typedef void (*poptCallbackType) (poptContext con, + enum poptCallbackReason reason, + /*@null@*/ const struct poptOption * opt, + /*@null@*/ const char * arg, + /*@null@*/ const void * data) + /*@globals internalState @*/ + /*@modifies internalState @*/; + +/** \ingroup popt + * Destroy context. + * @param con context + * @return NULL always + */ +/*@null@*/ +poptContext poptFreeContext( /*@only@*/ /*@null@*/ poptContext con) + /*@modifies con @*/; + +/** \ingroup popt + * Initialize popt context. + * @param name context name (usually argv[0] program name) + * @param argc no. of arguments + * @param argv argument array + * @param options address of popt option table + * @param flags or'd POPT_CONTEXT_* bits + * @return initialized popt context + */ +/*@only@*/ /*@null@*/ +poptContext poptGetContext( + /*@dependent@*/ /*@keep@*/ const char * name, + int argc, /*@dependent@*/ /*@keep@*/ const char ** argv, + /*@dependent@*/ /*@keep@*/ const struct poptOption * options, + unsigned int flags) + /*@globals internalState @*/ + /*@modifies internalState @*/; + +/** \ingroup popt + * Destroy context (alternative implementation). + * @param con context + * @return NULL always + */ +/*@null@*/ +poptContext poptFini( /*@only@*/ /*@null@*/ poptContext con) + /*@modifies con @*/; + +/** \ingroup popt + * Initialize popt context (alternative implementation). + * This routine does poptGetContext() and then poptReadConfigFiles(). + * @param argc no. of arguments + * @param argv argument array + * @param options address of popt option table + * @param configPaths colon separated file path(s) to read. + * @return initialized popt context (NULL on error). + */ +/*@only@*/ /*@null@*/ /*@unused@*/ +poptContext poptInit(int argc, /*@dependent@*/ /*@keep@*/ const char ** argv, + /*@dependent@*/ /*@keep@*/ const struct poptOption * options, + /*@null@*/ const char * configPaths) + /*@globals fileSystem, internalState @*/ + /*@modifies fileSystem, internalState @*/; + +/** \ingroup popt + * Reinitialize popt context. + * @param con context + */ +/*@unused@*/ +void poptResetContext(/*@null@*/poptContext con) + /*@modifies con @*/; + +/** \ingroup popt + * Return value of next option found. + * @param con context + * @return next option val, -1 on last item, POPT_ERROR_* on error + */ +int poptGetNextOpt(/*@null@*/poptContext con) + /*@globals fileSystem, internalState @*/ + /*@modifies con, fileSystem, internalState @*/; + +/** \ingroup popt + * Return next option argument (if any). + * @param con context + * @return option argument, NULL if no argument is available + */ +/*@observer@*/ /*@null@*/ /*@unused@*/ +char * poptGetOptArg(/*@null@*/poptContext con) + /*@modifies con @*/; + +/** \ingroup popt + * Return next argument. + * @param con context + * @return next argument, NULL if no argument is available + */ +/*@observer@*/ /*@null@*/ /*@unused@*/ +const char * poptGetArg(/*@null@*/poptContext con) + /*@modifies con @*/; + +/** \ingroup popt + * Peek at current argument. + * @param con context + * @return current argument, NULL if no argument is available + */ +/*@observer@*/ /*@null@*/ /*@unused@*/ +const char * poptPeekArg(/*@null@*/poptContext con) + /*@*/; + +/** \ingroup popt + * Return remaining arguments. + * @param con context + * @return argument array, NULL terminated + */ +/*@observer@*/ /*@null@*/ +const char ** poptGetArgs(/*@null@*/poptContext con) + /*@modifies con @*/; + +/** \ingroup popt + * Return the option which caused the most recent error. + * @param con context + * @param flags + * @return offending option + */ +/*@observer@*/ +const char * poptBadOption(/*@null@*/poptContext con, unsigned int flags) + /*@*/; + +/** \ingroup popt + * Add arguments to context. + * @param con context + * @param argv argument array, NULL terminated + * @return 0 on success, POPT_ERROR_OPTSTOODEEP on failure + */ +/*@unused@*/ +int poptStuffArgs(poptContext con, /*@keep@*/ const char ** argv) + /*@modifies con @*/; + +/** \ingroup popt + * Add alias to context. + * @todo Pass alias by reference, not value. + * @deprecated Use poptAddItem instead. + * @param con context + * @param alias alias to add + * @param flags (unused) + * @return 0 on success + */ +/*@unused@*/ +int poptAddAlias(poptContext con, struct poptAlias alias, int flags) + /*@modifies con @*/; + +/** \ingroup popt + * Add alias/exec item to context. + * @param con context + * @param newItem alias/exec item to add + * @param flags 0 for alias, 1 for exec + * @return 0 on success + */ +int poptAddItem(poptContext con, poptItem newItem, int flags) + /*@modifies con @*/; + +/** \ingroup popt + * Perform sanity checks on a file path. + * @param fn file name + * @return 0 on OK, 1 on NOTOK. + */ +int poptSaneFile(const char * fn) + /*@globals errno, internalState @*/ + /*@modifies errno, internalState @*/; + +/** + * Read a file into a buffer. + * @param fn file name + * @retval *bp buffer (malloc'd) (or NULL) + * @retval *nbp no. of bytes in buffer (including final NUL) (or NULL) + * @param flags 1 to trim escaped newlines + * return 0 on success + */ +int poptReadFile(const char * fn, /*@null@*/ /*@out@*/ char ** bp, + /*@null@*/ /*@out@*/ size_t * nbp, int flags) + /*@globals errno, fileSystem, internalState @*/ + /*@modifies *bp, *nbp, errno, fileSystem, internalState @*/; +#define POPT_READFILE_TRIMNEWLINES 1 + +/** \ingroup popt + * Read configuration file. + * @param con context + * @param fn file name to read + * @return 0 on success, POPT_ERROR_ERRNO on failure + */ +int poptReadConfigFile(poptContext con, const char * fn) + /*@globals errno, fileSystem, internalState @*/ + /*@modifies con->execs, con->numExecs, + errno, fileSystem, internalState @*/; + +/** \ingroup popt + * Read configuration file(s). + * Colon separated files to read, looping over poptReadConfigFile(). + * Note that an '@' character preceeding a path in the list will + * also perform additional sanity checks on the file before reading. + * @param con context + * @param paths colon separated file name(s) to read + * @return 0 on success, POPT_ERROR_BADCONFIG on failure + */ +int poptReadConfigFiles(poptContext con, /*@null@*/ const char * paths) + /*@globals errno, fileSystem, internalState @*/ + /*@modifies con->execs, con->numExecs, + errno, fileSystem, internalState @*/; + +/** \ingroup popt + * Read default configuration from /etc/popt and $HOME/.popt. + * @param con context + * @param useEnv (unused) + * @return 0 on success, POPT_ERROR_ERRNO on failure + */ +/*@unused@*/ +int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv) + /*@globals fileSystem, internalState @*/ + /*@modifies con->execs, con->numExecs, + fileSystem, internalState @*/; + +/** \ingroup popt + * Duplicate an argument array. + * @note: The argument array is malloc'd as a single area, so only argv must + * be free'd. + * + * @param argc no. of arguments + * @param argv argument array + * @retval argcPtr address of returned no. of arguments + * @retval argvPtr address of returned argument array + * @return 0 on success, POPT_ERROR_NOARG on failure + */ +int poptDupArgv(int argc, /*@null@*/ const char **argv, + /*@null@*/ /*@out@*/ int * argcPtr, + /*@null@*/ /*@out@*/ const char *** argvPtr) + /*@modifies *argcPtr, *argvPtr @*/; + +/** \ingroup popt + * Parse a string into an argument array. + * The parse allows ', ", and \ quoting, but ' is treated the same as " and + * both may include \ quotes. + * @note: The argument array is malloc'd as a single area, so only argv must + * be free'd. + * + * @param s string to parse + * @retval argcPtr address of returned no. of arguments + * @retval argvPtr address of returned argument array + */ +int poptParseArgvString(const char * s, + /*@out@*/ int * argcPtr, /*@out@*/ const char *** argvPtr) + /*@modifies *argcPtr, *argvPtr @*/; + +/** \ingroup popt + * Parses an input configuration file and returns an string that is a + * command line. For use with popt. You must free the return value when done. + * + * Given the file: +\verbatim +# this line is ignored + # this one too +aaa + bbb + ccc +bla=bla + +this_is = fdsafdas + bad_line= + reall bad line + reall bad line = again +5555= 55555 + test = with lots of spaces +\endverbatim +* +* The result is: +\verbatim +--aaa --bbb --ccc --bla="bla" --this_is="fdsafdas" --5555="55555" --test="with lots of spaces" +\endverbatim +* +* Passing this to poptParseArgvString() yields an argv of: +\verbatim +'--aaa' +'--bbb' +'--ccc' +'--bla=bla' +'--this_is=fdsafdas' +'--5555=55555' +'--test=with lots of spaces' +\endverbatim + * + * @bug NULL is returned if file line is too long. + * @bug Silently ignores invalid lines. + * + * @param fp file handle to read + * @param *argstrp return string of options (malloc'd) + * @param flags unused + * @return 0 on success + * @see poptParseArgvString + */ +/*@-fcnuse@*/ +int poptConfigFileToString(FILE *fp, /*@out@*/ char ** argstrp, int flags) + /*@globals fileSystem @*/ + /*@modifies *fp, *argstrp, fileSystem @*/; +/*@=fcnuse@*/ + +/** \ingroup popt + * Return formatted error string for popt failure. + * @param error popt error + * @return error string + */ +/*@observer@*/ +const char * poptStrerror(const int error) + /*@*/; + +/** \ingroup popt + * Limit search for executables. + * @param con context + * @param path single path to search for executables + * @param allowAbsolute absolute paths only? + */ +/*@unused@*/ +void poptSetExecPath(poptContext con, const char * path, int allowAbsolute) + /*@modifies con @*/; + +/** \ingroup popt + * Print detailed description of options. + * @param con context + * @param fp ouput file handle + * @param flags (unused) + */ +void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ int flags) + /*@globals fileSystem @*/ + /*@modifies fp, fileSystem @*/; + +/** \ingroup popt + * Print terse description of options. + * @param con context + * @param fp ouput file handle + * @param flags (unused) + */ +void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ int flags) + /*@globals fileSystem @*/ + /*@modifies fp, fileSystem @*/; + +/** \ingroup popt + * Provide text to replace default "[OPTION...]" in help/usage output. + * @param con context + * @param text replacement text + */ +/*@-fcnuse@*/ +void poptSetOtherOptionHelp(poptContext con, const char * text) + /*@modifies con @*/; +/*@=fcnuse@*/ + +/** \ingroup popt + * Return argv[0] from context. + * @param con context + * @return argv[0] + */ +/*@-fcnuse@*/ +/*@observer@*/ +const char * poptGetInvocationName(poptContext con) + /*@*/; +/*@=fcnuse@*/ + +/** \ingroup popt + * Shuffle argv pointers to remove stripped args, returns new argc. + * @param con context + * @param argc no. of args + * @param argv arg vector + * @return new argc + */ +/*@-fcnuse@*/ +int poptStrippedArgv(poptContext con, int argc, char ** argv) + /*@modifies *argv @*/; +/*@=fcnuse@*/ + +/** + * Add a string to an argv array. + * @retval *argvp argv array + * @param argInfo (unused) + * @param val string arg to add (using strdup) + * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION + */ +/*@unused@*/ +int poptSaveString(/*@null@*/ const char *** argvp, unsigned int argInfo, + /*@null@*/const char * val) + /*@modifies *argvp @*/; + +/** + * Save a long long, performing logical operation with value. + * @warning Alignment check may be too strict on certain platorms. + * @param arg integer pointer, aligned on int boundary. + * @param argInfo logical operation (see POPT_ARGFLAG_*) + * @param aLongLong value to use + * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION + */ +/*@-incondefs@*/ +/*@unused@*/ +int poptSaveLongLong(/*@null@*/ long long * arg, unsigned int argInfo, + long long aLongLong) + /*@globals internalState @*/ + /*@modifies *arg, internalState @*/ + /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/; +/*@=incondefs@*/ + +/** + * Save a long, performing logical operation with value. + * @warning Alignment check may be too strict on certain platorms. + * @param arg integer pointer, aligned on int boundary. + * @param argInfo logical operation (see POPT_ARGFLAG_*) + * @param aLong value to use + * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION + */ +/*@-incondefs@*/ +/*@unused@*/ +int poptSaveLong(/*@null@*/ long * arg, unsigned int argInfo, long aLong) + /*@globals internalState @*/ + /*@modifies *arg, internalState @*/ + /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/; +/*@=incondefs@*/ + +/** + * Save a short integer, performing logical operation with value. + * @warning Alignment check may be too strict on certain platorms. + * @param arg short pointer, aligned on short boundary. + * @param argInfo logical operation (see POPT_ARGFLAG_*) + * @param aLong value to use + * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION + */ +/*@-incondefs@*/ +/*@unused@*/ +int poptSaveShort(/*@null@*/ short * arg, unsigned int argInfo, long aLong) + /*@globals internalState @*/ + /*@modifies *arg, internalState @*/ + /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/; +/*@=incondefs@*/ + +/** + * Save an integer, performing logical operation with value. + * @warning Alignment check may be too strict on certain platorms. + * @param arg integer pointer, aligned on int boundary. + * @param argInfo logical operation (see POPT_ARGFLAG_*) + * @param aLong value to use + * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION + */ +/*@-incondefs@*/ +/*@unused@*/ +int poptSaveInt(/*@null@*/ int * arg, unsigned int argInfo, long aLong) + /*@globals internalState @*/ + /*@modifies *arg, internalState @*/ + /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/; +/*@=incondefs@*/ + +/* The bit set typedef. */ +/*@-exporttype@*/ +typedef struct poptBits_s { + unsigned int bits[1]; +} * poptBits; +/*@=exporttype@*/ + +#define _POPT_BITS_N 1024U /* estimated population */ +#define _POPT_BITS_M ((3U * _POPT_BITS_N) / 2U) +#define _POPT_BITS_K 16U /* no. of linear hash combinations */ + +/*@-exportlocal -exportvar -globuse @*/ +/*@unchecked@*/ +extern unsigned int _poptBitsN; +/*@unchecked@*/ +extern unsigned int _poptBitsM; +/*@unchecked@*/ +extern unsigned int _poptBitsK; +/*@=exportlocal =exportvar =globuse @*/ + +/*@-exportlocal@*/ +int poptBitsAdd(/*@null@*/poptBits bits, /*@null@*/const char * s) + /*@modifies bits @*/; +/*@=exportlocal@*/ +int poptBitsChk(/*@null@*/poptBits bits, /*@null@*/const char * s) + /*@*/; +int poptBitsClr(/*@null@*/poptBits bits) + /*@modifies bits @*/; +/*@-exportlocal@*/ +int poptBitsDel(/*@null@*/poptBits bits, /*@null@*/const char * s) + /*@modifies bits @*/; +/*@-fcnuse@*/ +int poptBitsIntersect(/*@null@*/ poptBits * ap, /*@null@*/ const poptBits b) + /*@modifies *ap @*/; +int poptBitsUnion(/*@null@*/ poptBits * ap, /*@null@*/ const poptBits b) + /*@modifies *ap @*/; +int poptBitsArgs(/*@null@*/ poptContext con, /*@null@*/ poptBits * ap) + /*@modifies con, *ap @*/; +/*@=fcnuse@*/ +/*@=exportlocal@*/ + +/** + * Save a string into a bit set (experimental). + * @retval *bits bit set (lazily malloc'd if NULL) + * @param argInfo logical operation (see POPT_ARGFLAG_*) + * @param s string to add to bit set + * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION + */ +/*@-incondefs@*/ +/*@unused@*/ +int poptSaveBits(/*@null@*/ poptBits * bitsp, unsigned int argInfo, + /*@null@*/ const char * s) + /*@globals _poptBitsN, _poptBitsM, _poptBitsK, internalState @*/ + /*@modifies *bitsp, _poptBitsN, _poptBitsM, _poptBitsK, internalState @*/; +/*@=incondefs@*/ + +/*@=type@*/ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/ldb-2.0.8/third_party/popt/poptconfig.c b/ldb-2.0.8/third_party/popt/poptconfig.c new file mode 100644 index 0000000..f0a92e0 --- /dev/null +++ b/ldb-2.0.8/third_party/popt/poptconfig.c @@ -0,0 +1,582 @@ +/** \ingroup popt + * \file popt/poptconfig.c + */ + +/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING + file accompanying popt source distributions, available from + ftp://ftp.rpm.org/pub/rpm/dist. */ + +#include "system.h" +#include "poptint.h" +#include + +#if defined(HAVE_FNMATCH_H) +#include + +#if defined(__LCLINT__) +/*@-declundef -exportheader -incondefs -protoparammatch -redecl -type @*/ +extern int fnmatch (const char *__pattern, const char *__name, int __flags) + /*@*/; +/*@=declundef =exportheader =incondefs =protoparammatch =redecl =type @*/ +#endif /* __LCLINT__ */ +#endif + +#if defined(HAVE_GLOB_H) +#include + +#if defined(__LCLINT__) +/*@-declundef -exportheader -incondefs -protoparammatch -redecl -type @*/ +extern int glob (const char *__pattern, int __flags, + /*@null@*/ int (*__errfunc) (const char *, int), + /*@out@*/ glob_t *__pglob) + /*@globals errno, fileSystem @*/ + /*@modifies *__pglob, errno, fileSystem @*/; + +/* XXX only annotation is a white lie */ +extern void globfree (/*@only@*/ glob_t *__pglob) + /*@modifies *__pglob @*/; + +/* XXX _GNU_SOURCE ifdef and/or retrofit is needed for portability. */ +extern int glob_pattern_p (const char *__pattern, int __quote) + /*@*/; +/*@=declundef =exportheader =incondefs =protoparammatch =redecl =type @*/ +#endif /* __LCLINT__ */ + +#if !defined(__GLIBC__) +/* Return nonzero if PATTERN contains any metacharacters. + Metacharacters can be quoted with backslashes if QUOTE is nonzero. */ +static int +glob_pattern_p (const char * pattern, int quote) + /*@*/ +{ + const char * p; + int open = 0; + + for (p = pattern; *p != '\0'; ++p) + switch (*p) { + case '?': + case '*': + return 1; + /*@notreached@*/ /*@switchbreak@*/ break; + case '\\': + if (quote && p[1] != '\0') + ++p; + /*@switchbreak@*/ break; + case '[': + open = 1; + /*@switchbreak@*/ break; + case ']': + if (open) + return 1; + /*@switchbreak@*/ break; + } + return 0; +} +#endif /* !defined(__GLIBC__) */ + +/*@unchecked@*/ +static int poptGlobFlags = 0; + +static int poptGlob_error(/*@unused@*/ UNUSED(const char * epath), + /*@unused@*/ UNUSED(int eerrno)) + /*@*/ +{ + return 1; +} +#endif /* HAVE_GLOB_H */ + +/** + * Return path(s) from a glob pattern. + * @param con context + * @param pattern glob pattern + * @retval *acp no. of paths + * @retval *avp array of paths + * @return 0 on success + */ +static int poptGlob(/*@unused@*/ UNUSED(poptContext con), const char * pattern, + /*@out@*/ int * acp, /*@out@*/ const char *** avp) + /*@modifies *acp, *avp @*/ +{ + const char * pat = pattern; + int rc = 0; /* assume success */ + + /* XXX skip the attention marker. */ + if (pat[0] == '@' && pat[1] != '(') + pat++; + +#if defined(HAVE_GLOB_H) + if (glob_pattern_p(pat, 0)) { + glob_t _g, *pglob = &_g; + + if (!glob(pat, poptGlobFlags, poptGlob_error, pglob)) { + if (acp) { + *acp = (int) pglob->gl_pathc; + pglob->gl_pathc = 0; + } + if (avp) { +/*@-onlytrans@*/ + *avp = (const char **) pglob->gl_pathv; +/*@=onlytrans@*/ + pglob->gl_pathv = NULL; + } +/*@-nullstate@*/ + globfree(pglob); +/*@=nullstate@*/ + } else + rc = POPT_ERROR_ERRNO; + } else +#endif /* HAVE_GLOB_H */ + { + if (acp) + *acp = 1; + if (avp && (*avp = calloc((size_t)(1 + 1), sizeof (**avp))) != NULL) + (*avp)[0] = xstrdup(pat); + } + + return rc; +} + +/*@access poptContext @*/ + +int poptSaneFile(const char * fn) +{ + struct stat sb; + uid_t uid = getuid(); + + if (stat(fn, &sb) == -1) + return 1; + if ((uid_t)sb.st_uid != uid) + return 0; + if (!S_ISREG(sb.st_mode)) + return 0; +/*@-bitwisesigned@*/ + if (sb.st_mode & (S_IWGRP|S_IWOTH)) + return 0; +/*@=bitwisesigned@*/ + return 1; +} + +int poptReadFile(const char * fn, char ** bp, size_t * nbp, int flags) +{ + int fdno; + char * b = NULL; + off_t nb = 0; + char * s, * t, * se; + int rc = POPT_ERROR_ERRNO; /* assume failure */ + + fdno = open(fn, O_RDONLY); + if (fdno < 0) + goto exit; + + if ((nb = lseek(fdno, 0, SEEK_END)) == (off_t)-1 + || lseek(fdno, 0, SEEK_SET) == (off_t)-1 + || (b = calloc(sizeof(*b), (size_t)nb + 1)) == NULL + || read(fdno, (char *)b, (size_t)nb) != (ssize_t)nb) + { + int oerrno = errno; + (void) close(fdno); + errno = oerrno; + goto exit; + } + if (close(fdno) == -1) + goto exit; + if (b == NULL) { + rc = POPT_ERROR_MALLOC; + goto exit; + } + rc = 0; + + /* Trim out escaped newlines. */ +/*@-bitwisesigned@*/ + if (flags & POPT_READFILE_TRIMNEWLINES) +/*@=bitwisesigned@*/ + { + for (t = b, s = b, se = b + nb; *s && s < se; s++) { + switch (*s) { + case '\\': + if (s[1] == '\n') { + s++; + continue; + } + /*@fallthrough@*/ + default: + *t++ = *s; + /*@switchbreak@*/ break; + } + } + *t++ = '\0'; + nb = (off_t)(t - b); + } + +exit: + if (rc != 0) { +/*@-usedef@*/ + if (b) + free(b); +/*@=usedef@*/ + b = NULL; + nb = 0; + } + if (bp) + *bp = b; +/*@-usereleased@*/ + else if (b) + free(b); +/*@=usereleased@*/ + if (nbp) + *nbp = (size_t)nb; +/*@-compdef -nullstate @*/ /* XXX cannot annotate char ** correctly */ + return rc; +/*@=compdef =nullstate @*/ +} + +/** + * Check for application match. + * @param con context + * @param s config application name + * return 0 if config application matches + */ +static int configAppMatch(poptContext con, const char * s) + /*@*/ +{ + int rc = 1; + + if (con->appName == NULL) /* XXX can't happen. */ + return rc; + +#if defined(HAVE_GLOB_H) && defined(HAVE_FNMATCH_H) + if (glob_pattern_p(s, 1)) { +/*@-bitwisesigned@*/ + static int flags = FNM_PATHNAME | FNM_PERIOD; +#ifdef FNM_EXTMATCH + flags |= FNM_EXTMATCH; +#endif +/*@=bitwisesigned@*/ + rc = fnmatch(s, con->appName, flags); + } else +#endif + rc = strcmp(s, con->appName); + return rc; +} + +/*@-compmempass@*/ /* FIX: item->option.longName kept, not dependent. */ +static int poptConfigLine(poptContext con, char * line) + /*@globals fileSystem, internalState @*/ + /*@modifies con, fileSystem, internalState @*/ +{ + char *b = NULL; + size_t nb = 0; + char * se = line; + const char * appName; + const char * entryType; + const char * opt; + struct poptItem_s item_buf; + poptItem item = &item_buf; + int i, j; + int rc = POPT_ERROR_BADCONFIG; + + if (con->appName == NULL) + goto exit; + + memset(item, 0, sizeof(*item)); + + appName = se; + while (*se != '\0' && !_isspaceptr(se)) se++; + if (*se == '\0') + goto exit; + else + *se++ = '\0'; + + if (configAppMatch(con, appName)) goto exit; + + while (*se != '\0' && _isspaceptr(se)) se++; + entryType = se; + while (*se != '\0' && !_isspaceptr(se)) se++; + if (*se != '\0') *se++ = '\0'; + + while (*se != '\0' && _isspaceptr(se)) se++; + if (*se == '\0') goto exit; + opt = se; + while (*se != '\0' && !_isspaceptr(se)) se++; + if (opt[0] == '-' && *se == '\0') goto exit; + if (*se != '\0') *se++ = '\0'; + + while (*se != '\0' && _isspaceptr(se)) se++; + if (opt[0] == '-' && *se == '\0') goto exit; + +/*@-temptrans@*/ /* FIX: line alias is saved */ + if (opt[0] == '-' && opt[1] == '-') + item->option.longName = opt + 2; + else if (opt[0] == '-' && opt[2] == '\0') + item->option.shortName = opt[1]; + else { + const char * fn = opt; + + /* XXX handle globs and directories in fn? */ + if ((rc = poptReadFile(fn, &b, &nb, POPT_READFILE_TRIMNEWLINES)) != 0) + goto exit; + if (b == NULL || nb == 0) + goto exit; + + /* Append remaining text to the interpolated file option text. */ + if (*se != '\0') { + size_t nse = strlen(se) + 1; + if ((b = realloc(b, (nb + nse))) == NULL) /* XXX can't happen */ + goto exit; + (void) stpcpy( stpcpy(&b[nb-1], " "), se); + nb += nse; + } + se = b; + + /* Use the basename of the path as the long option name. */ + { const char * longName = strrchr(fn, '/'); + if (longName != NULL) + longName++; + else + longName = fn; + if (longName == NULL) /* XXX can't happen. */ + goto exit; + /* Single character basenames are treated as short options. */ + if (longName[1] != '\0') + item->option.longName = longName; + else + item->option.shortName = longName[0]; + } + } +/*@=temptrans@*/ + + if (poptParseArgvString(se, &item->argc, &item->argv)) goto exit; + +/*@-modobserver@*/ + item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN; + for (i = 0, j = 0; i < item->argc; i++, j++) { + const char * f; + if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) { + f = item->argv[i] + sizeof("--POPTdesc="); + if (f[0] == '$' && f[1] == '"') f++; + item->option.descrip = f; + item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; + j--; + } else + if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) { + f = item->argv[i] + sizeof("--POPTargs="); + if (f[0] == '$' && f[1] == '"') f++; + item->option.argDescrip = f; + item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; + item->option.argInfo |= POPT_ARG_STRING; + j--; + } else + if (j != i) + item->argv[j] = item->argv[i]; + } + if (j != i) { + item->argv[j] = NULL; + item->argc = j; + } +/*@=modobserver@*/ + +/*@-nullstate@*/ /* FIX: item->argv[] may be NULL */ + if (!strcmp(entryType, "alias")) + rc = poptAddItem(con, item, 0); + else if (!strcmp(entryType, "exec")) + rc = poptAddItem(con, item, 1); +/*@=nullstate@*/ +exit: + rc = 0; /* XXX for now, always return success */ + if (b) + free(b); + return rc; +} +/*@=compmempass@*/ + +int poptReadConfigFile(poptContext con, const char * fn) +{ + char * b = NULL, *be; + size_t nb = 0; + const char *se; + char *t, *te; + int rc; + int xx; + + if ((rc = poptReadFile(fn, &b, &nb, POPT_READFILE_TRIMNEWLINES)) != 0) + return (errno == ENOENT ? 0 : rc); + if (b == NULL || nb == 0) + return POPT_ERROR_BADCONFIG; + + if ((t = malloc(nb + 1)) == NULL) + goto exit; + te = t; + + be = (b + nb); + for (se = b; se < be; se++) { + switch (*se) { + case '\n': + *te = '\0'; + te = t; + while (*te && _isspaceptr(te)) te++; + if (*te && *te != '#') + xx = poptConfigLine(con, te); + /*@switchbreak@*/ break; +/*@-usedef@*/ /* XXX *se may be uninitialized */ + case '\\': + *te = *se++; + /* \ at the end of a line does not insert a \n */ + if (se < be && *se != '\n') { + te++; + *te++ = *se; + } + /*@switchbreak@*/ break; + default: + *te++ = *se; + /*@switchbreak@*/ break; +/*@=usedef@*/ + } + } + + free(t); + rc = 0; + +exit: + if (b) + free(b); + return rc; +} + +int poptReadConfigFiles(poptContext con, const char * paths) +{ + char * buf = (paths ? xstrdup(paths) : NULL); + const char * p; + char * pe; + int rc = 0; /* assume success */ + + for (p = buf; p != NULL && *p != '\0'; p = pe) { + const char ** av = NULL; + int ac = 0; + int i; + int xx; + + /* locate start of next path element */ + pe = strchr(p, ':'); + if (pe != NULL && *pe == ':') + *pe++ = '\0'; + else + pe = (char *) (p + strlen(p)); + + xx = poptGlob(con, p, &ac, &av); + + /* work-off each resulting file from the path element */ + for (i = 0; i < ac; i++) { + const char * fn = av[i]; + if (av[i] == NULL) /* XXX can't happen */ + /*@innercontinue@*/ continue; + /* XXX should '@' attention be pushed into poptReadConfigFile? */ + if (p[0] == '@' && p[1] != '(') { + if (fn[0] == '@' && fn[1] != '(') + fn++; + xx = poptSaneFile(fn); + if (!xx && rc == 0) + rc = POPT_ERROR_BADCONFIG; + /*@innercontinue@*/ continue; + } + xx = poptReadConfigFile(con, fn); + if (xx && rc == 0) + rc = xx; + free((void *)av[i]); + av[i] = NULL; + } + free(av); + av = NULL; + } + +/*@-usedef@*/ + if (buf) + free(buf); +/*@=usedef@*/ + + return rc; +} + +int poptReadDefaultConfig(poptContext con, /*@unused@*/ UNUSED(int useEnv)) +{ + static const char _popt_sysconfdir[] = POPT_SYSCONFDIR "/popt"; + static const char _popt_etc[] = "/etc/popt"; + char * home; + struct stat sb; + int rc = 0; /* assume success */ + + if (con->appName == NULL) goto exit; + + if (strcmp(_popt_sysconfdir, _popt_etc)) { + rc = poptReadConfigFile(con, _popt_sysconfdir); + if (rc) goto exit; + } + + rc = poptReadConfigFile(con, _popt_etc); + if (rc) goto exit; + +#if defined(HAVE_GLOB_H) + if (!stat("/etc/popt.d", &sb) && S_ISDIR(sb.st_mode)) { + const char ** av = NULL; + int ac = 0; + int i; + + if ((rc = poptGlob(con, "/etc/popt.d/*", &ac, &av)) == 0) { + for (i = 0; rc == 0 && i < ac; i++) { + const char * fn = av[i]; + if (fn == NULL || strstr(fn, ".rpmnew") || strstr(fn, ".rpmsave")) + continue; + if (!stat(fn, &sb)) { + if (!S_ISREG(sb.st_mode) && !S_ISLNK(sb.st_mode)) + continue; + } + rc = poptReadConfigFile(con, fn); + free((void *)av[i]); + av[i] = NULL; + } + free(av); + av = NULL; + } + } + if (rc) goto exit; +#endif + + if ((home = getenv("HOME"))) { + char * fn = malloc(strlen(home) + 20); + if (fn != NULL) { + (void) stpcpy(stpcpy(fn, home), "/.popt"); + rc = poptReadConfigFile(con, fn); + free(fn); + } else + rc = POPT_ERROR_ERRNO; + if (rc) goto exit; + } + +exit: + return rc; +} + +poptContext +poptFini(poptContext con) +{ + return poptFreeContext(con); +} + +poptContext +poptInit(int argc, const char ** argv, + const struct poptOption * options, const char * configPaths) +{ + poptContext con = NULL; + const char * argv0; + + if (argv == NULL || argv[0] == NULL || options == NULL) + return con; + + if ((argv0 = strrchr(argv[0], '/')) != NULL) argv0++; + else argv0 = argv[0]; + + con = poptGetContext(argv0, argc, (const char **)argv, options, 0); + if (con != NULL&& poptReadConfigFiles(con, configPaths)) + con = poptFini(con); + + return con; +} diff --git a/ldb-2.0.8/third_party/popt/popthelp.c b/ldb-2.0.8/third_party/popt/popthelp.c new file mode 100644 index 0000000..0d8548b --- /dev/null +++ b/ldb-2.0.8/third_party/popt/popthelp.c @@ -0,0 +1,925 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ + +/** \ingroup popt + * \file popt/popthelp.c + */ + +/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING + file accompanying popt source distributions, available from + ftp://ftp.rpm.org/pub/rpm/dist. */ + +#include "system.h" + +#define POPT_USE_TIOCGWINSZ +#ifdef POPT_USE_TIOCGWINSZ +#include +#endif + +#define POPT_WCHAR_HACK +#ifdef POPT_WCHAR_HACK +#include /* for mbsrtowcs */ +/*@access mbstate_t @*/ +#endif +#include "poptint.h" + +/*@access poptContext@*/ + +/** + * Display arguments. + * @param con context + * @param foo (unused) + * @param key option(s) + * @param arg (unused) + * @param data (unused) + */ +/*@exits@*/ +static void displayArgs(poptContext con, + /*@unused@*/ UNUSED(enum poptCallbackReason foo), + struct poptOption * key, + /*@unused@*/ UNUSED(const char * arg), + /*@unused@*/ UNUSED(void * data)) + /*@globals fileSystem@*/ + /*@modifies fileSystem@*/ +{ + if (key->shortName == '?') + poptPrintHelp(con, stdout, 0); + else + poptPrintUsage(con, stdout, 0); + +#if !defined(__LCLINT__) /* XXX keep both splint & valgrind happy */ + con = poptFreeContext(con); +#endif + exit(0); +} + +#ifdef NOTYET +/*@unchecked@*/ +static int show_option_defaults = 0; +#endif + +/** + * Empty table marker to enable displaying popt alias/exec options. + */ +/*@observer@*/ /*@unchecked@*/ +struct poptOption poptAliasOptions[] = { + POPT_TABLEEND +}; + +/** + * Auto help table options. + */ +/*@-castfcnptr@*/ +/*@observer@*/ /*@unchecked@*/ +struct poptOption poptHelpOptions[] = { + { NULL, '\0', POPT_ARG_CALLBACK, (void *)displayArgs, 0, NULL, NULL }, + { "help", '?', 0, NULL, (int)'?', N_("Show this help message"), NULL }, + { "usage", '\0', 0, NULL, (int)'u', N_("Display brief usage message"), NULL }, + POPT_TABLEEND +} ; + +/*@observer@*/ /*@unchecked@*/ +static struct poptOption poptHelpOptions2[] = { +/*@-readonlytrans@*/ + { NULL, '\0', POPT_ARG_INTL_DOMAIN, PACKAGE, 0, NULL, NULL}, +/*@=readonlytrans@*/ + { NULL, '\0', POPT_ARG_CALLBACK, (void *)displayArgs, 0, NULL, NULL }, + { "help", '?', 0, NULL, (int)'?', N_("Show this help message"), NULL }, + { "usage", '\0', 0, NULL, (int)'u', N_("Display brief usage message"), NULL }, +#ifdef NOTYET + { "defaults", '\0', POPT_ARG_NONE, &show_option_defaults, 0, + N_("Display option defaults in message"), NULL }, +#endif + { "", '\0', 0, NULL, 0, N_("Terminate options"), NULL }, + POPT_TABLEEND +} ; + +/*@observer@*/ /*@unchecked@*/ +struct poptOption * poptHelpOptionsI18N = poptHelpOptions2; +/*@=castfcnptr@*/ + +#define _POPTHELP_MAXLINE ((size_t)79) + +typedef struct columns_s { + size_t cur; + size_t max; +} * columns_t; + +/** + * Return no. of columns in output window. + * @param fp FILE + * @return no. of columns + */ +static size_t maxColumnWidth(FILE *fp) + /*@*/ +{ + size_t maxcols = _POPTHELP_MAXLINE; +#if defined(TIOCGWINSZ) + struct winsize ws; + int fdno = fileno(fp ? fp : stdout); + + memset(&ws, 0, sizeof(ws)); + if (fdno >= 0 && !ioctl(fdno, (unsigned long)TIOCGWINSZ, &ws)) { + size_t ws_col = (size_t)ws.ws_col; + if (ws_col > maxcols && ws_col < (size_t)256) + maxcols = ws_col - 1; + } +#endif + return maxcols; +} + +/** + * Determine number of display characters in a string. + * @param s string + * @return no. of display characters. + */ +static inline size_t stringDisplayWidth(const char *s) + /*@*/ +{ + size_t n = strlen(s); +#ifdef POPT_WCHAR_HACK + mbstate_t t; + + memset ((void *)&t, 0, sizeof (t)); /* In initial state. */ + /* Determine number of display characters. */ + n = mbsrtowcs (NULL, &s, n, &t); +#else + n = 0; + for (; *s; s = POPT_next_char(s)) + n++; +#endif + + return n; +} + +/** + * @param opt option(s) + */ +/*@observer@*/ /*@null@*/ static const char * +getTableTranslationDomain(/*@null@*/ const struct poptOption *opt) + /*@*/ +{ + if (opt != NULL) + for (; opt->longName || opt->shortName || opt->arg; opt++) { + if (opt->argInfo == POPT_ARG_INTL_DOMAIN) + return opt->arg; + } + return NULL; +} + +/** + * @param opt option(s) + * @param translation_domain translation domain + */ +/*@observer@*/ /*@null@*/ static const char * +getArgDescrip(const struct poptOption * opt, + /*@-paramuse@*/ /* FIX: i18n macros disabled with lclint */ + /*@null@*/ const char * translation_domain) + /*@=paramuse@*/ + /*@*/ +{ + if (!poptArgType(opt)) return NULL; + + if (poptArgType(opt) == POPT_ARG_MAINCALL) + return opt->argDescrip; + if (poptArgType(opt) == POPT_ARG_ARGV) + return opt->argDescrip; + + if (opt->argDescrip) { + /* Some strings need popt library, not application, i18n domain. */ + if (opt == (poptHelpOptions + 1) + || opt == (poptHelpOptions + 2) + || !strcmp(opt->argDescrip, N_("Help options:")) + || !strcmp(opt->argDescrip, N_("Options implemented via popt alias/exec:"))) + return POPT_(opt->argDescrip); + + /* Use the application i18n domain. */ + return D_(translation_domain, opt->argDescrip); + } + + switch (poptArgType(opt)) { + case POPT_ARG_NONE: return POPT_("NONE"); +#ifdef DYING + case POPT_ARG_VAL: return POPT_("VAL"); +#else + case POPT_ARG_VAL: return NULL; +#endif + case POPT_ARG_INT: return POPT_("INT"); + case POPT_ARG_SHORT: return POPT_("SHORT"); + case POPT_ARG_LONG: return POPT_("LONG"); + case POPT_ARG_LONGLONG: return POPT_("LONGLONG"); + case POPT_ARG_STRING: return POPT_("STRING"); + case POPT_ARG_FLOAT: return POPT_("FLOAT"); + case POPT_ARG_DOUBLE: return POPT_("DOUBLE"); + case POPT_ARG_MAINCALL: return NULL; + case POPT_ARG_ARGV: return NULL; + default: return POPT_("ARG"); + } +} + +/** + * Display default value for an option. + * @param lineLength display positions remaining + * @param opt option(s) + * @param translation_domain translation domain + * @return + */ +static /*@only@*/ /*@null@*/ char * +singleOptionDefaultValue(size_t lineLength, + const struct poptOption * opt, + /*@-paramuse@*/ /* FIX: i18n macros disabled with lclint */ + /*@null@*/ const char * translation_domain) + /*@=paramuse@*/ + /*@*/ +{ + const char * defstr = D_(translation_domain, "default"); + char * le = malloc(4*lineLength + 1); + char * l = le; + + if (le == NULL) return NULL; /* XXX can't happen */ + *le = '\0'; + *le++ = '('; + le = stpcpy(le, defstr); + *le++ = ':'; + *le++ = ' '; + if (opt->arg) { /* XXX programmer error */ + poptArg arg = { .ptr = opt->arg }; + switch (poptArgType(opt)) { + case POPT_ARG_VAL: + case POPT_ARG_INT: + le += sprintf(le, "%d", arg.intp[0]); + break; + case POPT_ARG_SHORT: + le += sprintf(le, "%hd", arg.shortp[0]); + break; + case POPT_ARG_LONG: + le += sprintf(le, "%ld", arg.longp[0]); + break; + case POPT_ARG_LONGLONG: + le += sprintf(le, "%lld", arg.longlongp[0]); + break; + case POPT_ARG_FLOAT: + { double aDouble = (double) arg.floatp[0]; + le += sprintf(le, "%g", aDouble); + } break; + case POPT_ARG_DOUBLE: + le += sprintf(le, "%g", arg.doublep[0]); + break; + case POPT_ARG_MAINCALL: + le += sprintf(le, "%p", opt->arg); + break; + case POPT_ARG_ARGV: + le += sprintf(le, "%p", opt->arg); + break; + case POPT_ARG_STRING: + { const char * s = arg.argv[0]; + if (s == NULL) + le = stpcpy(le, "null"); + else { + size_t limit = 4*lineLength - (le - l) - sizeof("\"\")"); + size_t slen; + *le++ = '"'; + strncpy(le, s, limit); le[limit] = '\0'; le += (slen = strlen(le)); + if (slen == limit && s[limit]) + le[-1] = le[-2] = le[-3] = '.'; + *le++ = '"'; + } + } break; + case POPT_ARG_NONE: + default: + l = _free(l); + return NULL; + /*@notreached@*/ break; + } + } + *le++ = ')'; + *le = '\0'; + + return l; +} + +/** + * Display help text for an option. + * @param fp output file handle + * @param columns output display width control + * @param opt option(s) + * @param translation_domain translation domain + */ +static void singleOptionHelp(FILE * fp, columns_t columns, + const struct poptOption * opt, + /*@null@*/ const char * translation_domain) + /*@globals fileSystem @*/ + /*@modifies fp, fileSystem @*/ +{ + size_t maxLeftCol = columns->cur; + size_t indentLength = maxLeftCol + 5; + size_t lineLength = columns->max - indentLength; + const char * help = D_(translation_domain, opt->descrip); + const char * argDescrip = getArgDescrip(opt, translation_domain); + /* Display shortName iff printable non-space. */ + int prtshort = (int)(isprint((int)opt->shortName) && opt->shortName != ' '); + size_t helpLength; + char * defs = NULL; + char * left; + size_t nb = maxLeftCol + 1; + int displaypad = 0; + int xx; + + /* Make sure there's more than enough room in target buffer. */ + if (opt->longName) nb += strlen(opt->longName); + if (F_ISSET(opt, TOGGLE)) nb += sizeof("[no]") - 1; + if (argDescrip) nb += strlen(argDescrip); + + left = malloc(nb); + if (left == NULL) return; /* XXX can't happen */ + left[0] = '\0'; + left[maxLeftCol] = '\0'; + +#define prtlong (opt->longName != NULL) /* XXX splint needs a clue */ + if (!(prtshort || prtlong)) + goto out; + if (prtshort && prtlong) { + char *dash = F_ISSET(opt, ONEDASH) ? "-" : "--"; + left[0] = '-'; + left[1] = opt->shortName; + (void) stpcpy(stpcpy(stpcpy(left+2, ", "), dash), opt->longName); + } else if (prtshort) { + left[0] = '-'; + left[1] = opt->shortName; + left[2] = '\0'; + } else if (prtlong) { + /* XXX --long always padded for alignment with/without "-X, ". */ + char *dash = poptArgType(opt) == POPT_ARG_MAINCALL ? "" + : (F_ISSET(opt, ONEDASH) ? "-" : "--"); + const char *longName = opt->longName; + const char *toggle; + if (F_ISSET(opt, TOGGLE)) { + toggle = "[no]"; + if (longName[0] == 'n' && longName[1] == 'o') { + longName += sizeof("no") - 1; + if (longName[0] == '-') + longName++; + } + } else + toggle = ""; + (void) stpcpy(stpcpy(stpcpy(stpcpy(left, " "), dash), toggle), longName); + } +#undef prtlong + + if (argDescrip) { + char * le = left + strlen(left); + + if (F_ISSET(opt, OPTIONAL)) + *le++ = '['; + + /* Choose type of output */ + if (F_ISSET(opt, SHOW_DEFAULT)) { + defs = singleOptionDefaultValue(lineLength, opt, translation_domain); + if (defs) { + char * t = malloc((help ? strlen(help) : 0) + + strlen(defs) + sizeof(" ")); + if (t) { + char * te = t; + if (help) + te = stpcpy(te, help); + *te++ = ' '; + strcpy(te, defs); + defs = _free(defs); + defs = t; + } + } + } + + if (opt->argDescrip == NULL) { + switch (poptArgType(opt)) { + case POPT_ARG_NONE: + break; + case POPT_ARG_VAL: +#ifdef NOTNOW /* XXX pug ugly nerdy output */ + { long aLong = opt->val; + int ops = F_ISSET(opt, LOGICALOPS); + int negate = F_ISSET(opt, NOT); + + /* Don't bother displaying typical values */ + if (!ops && (aLong == 0L || aLong == 1L || aLong == -1L)) + break; + *le++ = '['; + switch (ops) { + case POPT_ARGFLAG_OR: + *le++ = '|'; + /*@innerbreak@*/ break; + case POPT_ARGFLAG_AND: + *le++ = '&'; + /*@innerbreak@*/ break; + case POPT_ARGFLAG_XOR: + *le++ = '^'; + /*@innerbreak@*/ break; + default: + /*@innerbreak@*/ break; + } + *le++ = (opt->longName != NULL ? '=' : ' '); + if (negate) *le++ = '~'; + /*@-formatconst@*/ + le += sprintf(le, (ops ? "0x%lx" : "%ld"), aLong); + /*@=formatconst@*/ + *le++ = ']'; + } +#endif + break; + case POPT_ARG_INT: + case POPT_ARG_SHORT: + case POPT_ARG_LONG: + case POPT_ARG_LONGLONG: + case POPT_ARG_FLOAT: + case POPT_ARG_DOUBLE: + case POPT_ARG_STRING: + *le++ = (opt->longName != NULL ? '=' : ' '); + le = stpcpy(le, argDescrip); + break; + default: + break; + } + } else { + char *leo; + + /* XXX argDescrip[0] determines "--foo=bar" or "--foo bar". */ + if (!strchr(" =(", argDescrip[0])) + *le++ = ((poptArgType(opt) == POPT_ARG_MAINCALL) ? ' ' : + (poptArgType(opt) == POPT_ARG_ARGV) ? ' ' : '='); + le = stpcpy(leo = le, argDescrip); + + /* Adjust for (possible) wide characters. */ + displaypad = (int)((le - leo) - stringDisplayWidth(argDescrip)); + } + if (F_ISSET(opt, OPTIONAL)) + *le++ = ']'; + *le = '\0'; + } + + if (help) + xx = POPT_fprintf(fp," %-*s ", (int)(maxLeftCol+displaypad), left); + else { + xx = POPT_fprintf(fp," %s\n", left); + goto out; + } + + left = _free(left); + if (defs) + help = defs; + + helpLength = strlen(help); + while (helpLength > lineLength) { + const char * ch; + char format[16]; + + ch = help + lineLength - 1; + while (ch > help && !_isspaceptr(ch)) + ch = POPT_prev_char(ch); + if (ch == help) break; /* give up */ + while (ch > (help + 1) && _isspaceptr(ch)) + ch = POPT_prev_char (ch); + ch = POPT_next_char(ch); + + /* + * XXX strdup is necessary to add NUL terminator so that an unknown + * no. of (possible) multi-byte characters can be displayed. + */ + { char * fmthelp = xstrdup(help); + if (fmthelp) { + fmthelp[ch - help] = '\0'; + sprintf(format, "%%s\n%%%ds", (int) indentLength); + /*@-formatconst@*/ + xx = POPT_fprintf(fp, format, fmthelp, " "); + /*@=formatconst@*/ + free(fmthelp); + } + } + + help = ch; + while (_isspaceptr(help) && *help) + help = POPT_next_char(help); + helpLength = strlen(help); + } + + if (helpLength) fprintf(fp, "%s\n", help); + help = NULL; + +out: + /*@-dependenttrans@*/ + defs = _free(defs); + /*@=dependenttrans@*/ + left = _free(left); +} + +/** + * Find display width for longest argument string. + * @param opt option(s) + * @param translation_domain translation domain + * @return display width + */ +static size_t maxArgWidth(const struct poptOption * opt, + /*@null@*/ const char * translation_domain) + /*@*/ +{ + size_t max = 0; + size_t len = 0; + const char * argDescrip; + + if (opt != NULL) + while (opt->longName || opt->shortName || opt->arg) { + if (poptArgType(opt) == POPT_ARG_INCLUDE_TABLE) { + if (opt->arg) /* XXX program error */ + len = maxArgWidth(opt->arg, translation_domain); + if (len > max) max = len; + } else if (!F_ISSET(opt, DOC_HIDDEN)) { + len = sizeof(" ")-1; + /* XXX --long always padded for alignment with/without "-X, ". */ + len += sizeof("-X, ")-1; + if (opt->longName) { + len += (F_ISSET(opt, ONEDASH) ? sizeof("-") : sizeof("--")) - 1; + len += strlen(opt->longName); + } + + argDescrip = getArgDescrip(opt, translation_domain); + + if (argDescrip) { + + /* XXX argDescrip[0] determines "--foo=bar" or "--foo bar". */ + if (!strchr(" =(", argDescrip[0])) len += sizeof("=")-1; + + /* Adjust for (possible) wide characters. */ + len += stringDisplayWidth(argDescrip); + } + + if (F_ISSET(opt, OPTIONAL)) len += sizeof("[]")-1; + if (len > max) max = len; + } + opt++; + } + + return max; +} + +/** + * Display popt alias and exec help. + * @param fp output file handle + * @param items alias/exec array + * @param nitems no. of alias/exec entries + * @param columns output display width control + * @param translation_domain translation domain + */ +static void itemHelp(FILE * fp, + /*@null@*/ poptItem items, int nitems, + columns_t columns, + /*@null@*/ const char * translation_domain) + /*@globals fileSystem @*/ + /*@modifies fp, fileSystem @*/ +{ + poptItem item; + int i; + + if (items != NULL) + for (i = 0, item = items; i < nitems; i++, item++) { + const struct poptOption * opt; + opt = &item->option; + if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN)) + singleOptionHelp(fp, columns, opt, translation_domain); + } +} + +/** + * Display help text for a table of options. + * @param con context + * @param fp output file handle + * @param table option(s) + * @param columns output display width control + * @param translation_domain translation domain + */ +static void singleTableHelp(poptContext con, FILE * fp, + /*@null@*/ const struct poptOption * table, + columns_t columns, + /*@null@*/ const char * translation_domain) + /*@globals fileSystem @*/ + /*@modifies fp, columns->cur, fileSystem @*/ +{ + const struct poptOption * opt; + const char *sub_transdom; + int xx; + + if (table == poptAliasOptions) { + itemHelp(fp, con->aliases, con->numAliases, columns, NULL); + itemHelp(fp, con->execs, con->numExecs, columns, NULL); + return; + } + + if (table != NULL) + for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) { + if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN)) + singleOptionHelp(fp, columns, opt, translation_domain); + } + + if (table != NULL) + for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) { + if (poptArgType(opt) != POPT_ARG_INCLUDE_TABLE) + continue; + sub_transdom = getTableTranslationDomain(opt->arg); + if (sub_transdom == NULL) + sub_transdom = translation_domain; + + /* If no popt aliases/execs, skip poptAliasOption processing. */ + if (opt->arg == poptAliasOptions && !(con->numAliases || con->numExecs)) + continue; + if (opt->descrip) + xx = POPT_fprintf(fp, "\n%s\n", D_(sub_transdom, opt->descrip)); + + singleTableHelp(con, fp, opt->arg, columns, sub_transdom); + } +} + +/** + * @param con context + * @param fp output file handle + */ +static size_t showHelpIntro(poptContext con, FILE * fp) + /*@globals fileSystem @*/ + /*@modifies fp, fileSystem @*/ +{ + size_t len = (size_t)6; + int xx; + + xx = POPT_fprintf(fp, POPT_("Usage:")); + if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) { + struct optionStackEntry * os = con->optionStack; + const char * fn = (os->argv ? os->argv[0] : NULL); + if (fn == NULL) return len; + if (strchr(fn, '/')) fn = strrchr(fn, '/') + 1; + /* XXX POPT_fprintf not needed for argv[0] display. */ + fprintf(fp, " %s", fn); + len += strlen(fn) + 1; + } + + return len; +} + +void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ UNUSED(int flags)) +{ + columns_t columns = calloc((size_t)1, sizeof(*columns)); + int xx; + + (void) showHelpIntro(con, fp); + if (con->otherHelp) + xx = POPT_fprintf(fp, " %s\n", con->otherHelp); + else + xx = POPT_fprintf(fp, " %s\n", POPT_("[OPTION...]")); + + if (columns) { + columns->cur = maxArgWidth(con->options, NULL); + columns->max = maxColumnWidth(fp); + singleTableHelp(con, fp, con->options, columns, NULL); + free(columns); + } +} + +/** + * Display usage text for an option. + * @param fp output file handle + * @param columns output display width control + * @param opt option(s) + * @param translation_domain translation domain + */ +static size_t singleOptionUsage(FILE * fp, columns_t columns, + const struct poptOption * opt, + /*@null@*/ const char *translation_domain) + /*@globals fileSystem @*/ + /*@modifies fp, columns->cur, fileSystem @*/ +{ + size_t len = sizeof(" []")-1; + const char * argDescrip = getArgDescrip(opt, translation_domain); + /* Display shortName iff printable non-space. */ + int prtshort = (int)(isprint((int)opt->shortName) && opt->shortName != ' '); + +#define prtlong (opt->longName != NULL) /* XXX splint needs a clue */ + if (!(prtshort || prtlong)) + return columns->cur; + + len = sizeof(" []")-1; + if (prtshort) + len += sizeof("-c")-1; + if (prtlong) { + if (prtshort) len += sizeof("|")-1; + len += (F_ISSET(opt, ONEDASH) ? sizeof("-") : sizeof("--")) - 1; + len += strlen(opt->longName); + } + + if (argDescrip) { + + /* XXX argDescrip[0] determines "--foo=bar" or "--foo bar". */ + if (!strchr(" =(", argDescrip[0])) len += sizeof("=")-1; + + /* Adjust for (possible) wide characters. */ + len += stringDisplayWidth(argDescrip); + } + + if ((columns->cur + len) > columns->max) { + fprintf(fp, "\n "); + columns->cur = (size_t)7; + } + + fprintf(fp, " ["); + if (prtshort) + fprintf(fp, "-%c", opt->shortName); + if (prtlong) + fprintf(fp, "%s%s%s", + (prtshort ? "|" : ""), + (F_ISSET(opt, ONEDASH) ? "-" : "--"), + opt->longName); +#undef prtlong + + if (argDescrip) { + /* XXX argDescrip[0] determines "--foo=bar" or "--foo bar". */ + if (!strchr(" =(", argDescrip[0])) fprintf(fp, "="); + fprintf(fp, "%s", argDescrip); + } + fprintf(fp, "]"); + + return columns->cur + len + 1; +} + +/** + * Display popt alias and exec usage. + * @param fp output file handle + * @param columns output display width control + * @param item alias/exec array + * @param nitems no. of ara/exec entries + * @param translation_domain translation domain + */ +static size_t itemUsage(FILE * fp, columns_t columns, + /*@null@*/ poptItem item, int nitems, + /*@null@*/ const char * translation_domain) + /*@globals fileSystem @*/ + /*@modifies fp, columns->cur, fileSystem @*/ +{ + int i; + + if (item != NULL) + for (i = 0; i < nitems; i++, item++) { + const struct poptOption * opt; + opt = &item->option; + if (poptArgType(opt) == POPT_ARG_INTL_DOMAIN) { + translation_domain = (const char *)opt->arg; + } else + if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN)) { + columns->cur = singleOptionUsage(fp, columns, opt, translation_domain); + } + } + + return columns->cur; +} + +/** + * Keep track of option tables already processed. + */ +typedef struct poptDone_s { + int nopts; + int maxopts; +/*@null@*/ + const void ** opts; +} * poptDone; + +/** + * Display usage text for a table of options. + * @param con context + * @param fp output file handle + * @param columns output display width control + * @param opt option(s) + * @param translation_domain translation domain + * @param done tables already processed + * @return + */ +static size_t singleTableUsage(poptContext con, FILE * fp, columns_t columns, + /*@null@*/ const struct poptOption * opt, + /*@null@*/ const char * translation_domain, + /*@null@*/ poptDone done) + /*@globals fileSystem @*/ + /*@modifies fp, columns->cur, done, fileSystem @*/ +{ + if (opt != NULL) + for (; (opt->longName || opt->shortName || opt->arg) ; opt++) { + if (poptArgType(opt) == POPT_ARG_INTL_DOMAIN) { + translation_domain = (const char *)opt->arg; + } else + if (poptArgType(opt) == POPT_ARG_INCLUDE_TABLE) { + if (done) { + int i = 0; + if (done->opts != NULL) + for (i = 0; i < done->nopts; i++) { + const void * that = done->opts[i]; + if (that == NULL || that != opt->arg) + /*@innercontinue@*/ continue; + /*@innerbreak@*/ break; + } + /* Skip if this table has already been processed. */ + if (opt->arg == NULL || i < done->nopts) + continue; + if (done->opts != NULL && done->nopts < done->maxopts) + done->opts[done->nopts++] = (const void *) opt->arg; + } + columns->cur = singleTableUsage(con, fp, columns, opt->arg, + translation_domain, done); + } else + if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN)) { + columns->cur = singleOptionUsage(fp, columns, opt, translation_domain); + } + } + + return columns->cur; +} + +/** + * Return concatenated short options for display. + * @todo Sub-tables should be recursed. + * @param opt option(s) + * @param fp output file handle + * @retval str concatenation of short options + * @return length of display string + */ +static size_t showShortOptions(const struct poptOption * opt, FILE * fp, + /*@null@*/ char * str) + /*@globals fileSystem @*/ + /*@modifies str, *fp, fileSystem @*/ + /*@requires maxRead(str) >= 0 @*/ +{ + /* bufsize larger then the ascii set, lazy allocation on top level call. */ + size_t nb = (size_t)300; + char * s = (str != NULL ? str : calloc((size_t)1, nb)); + size_t len = (size_t)0; + + if (s == NULL) + return 0; + + if (opt != NULL) + for (; (opt->longName || opt->shortName || opt->arg); opt++) { + if (!F_ISSET(opt, DOC_HIDDEN) && opt->shortName && !poptArgType(opt)) + { + /* Display shortName iff unique printable non-space. */ + if (!strchr(s, opt->shortName) && isprint((int)opt->shortName) + && opt->shortName != ' ') + s[strlen(s)] = opt->shortName; + } else if (poptArgType(opt) == POPT_ARG_INCLUDE_TABLE) + if (opt->arg) /* XXX program error */ + len = showShortOptions(opt->arg, fp, s); + } + + /* On return to top level, print the short options, return print length. */ + if (s != str && *s != '\0') { + fprintf(fp, " [-%s]", s); + len = strlen(s) + sizeof(" [-]")-1; + } +/*@-temptrans@*/ /* LCL: local s, not str arg, is being freed. */ + if (s != str) + free(s); +/*@=temptrans@*/ + return len; +} + +void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ UNUSED(int flags)) +{ + columns_t columns = calloc((size_t)1, sizeof(*columns)); + struct poptDone_s done_buf; + poptDone done = &done_buf; + + memset(done, 0, sizeof(*done)); + done->nopts = 0; + done->maxopts = 64; + if (columns) { + columns->cur = done->maxopts * sizeof(*done->opts); + columns->max = maxColumnWidth(fp); + done->opts = calloc((size_t)1, columns->cur); + /*@-keeptrans@*/ + if (done->opts != NULL) + done->opts[done->nopts++] = (const void *) con->options; + /*@=keeptrans@*/ + + columns->cur = showHelpIntro(con, fp); + columns->cur += showShortOptions(con->options, fp, NULL); + columns->cur = singleTableUsage(con, fp, columns, con->options, NULL, done); + columns->cur = itemUsage(fp, columns, con->aliases, con->numAliases, NULL); + columns->cur = itemUsage(fp, columns, con->execs, con->numExecs, NULL); + + if (con->otherHelp) { + columns->cur += strlen(con->otherHelp) + 1; + if (columns->cur > columns->max) fprintf(fp, "\n "); + fprintf(fp, " %s", con->otherHelp); + } + + fprintf(fp, "\n"); + if (done->opts != NULL) + free(done->opts); + free(columns); + } +} + +void poptSetOtherOptionHelp(poptContext con, const char * text) +{ + con->otherHelp = _free(con->otherHelp); + con->otherHelp = xstrdup(text); +} diff --git a/ldb-2.0.8/third_party/popt/poptint.c b/ldb-2.0.8/third_party/popt/poptint.c new file mode 100644 index 0000000..1af46ff --- /dev/null +++ b/ldb-2.0.8/third_party/popt/poptint.c @@ -0,0 +1,199 @@ +#include "system.h" +#include +#include "poptint.h" + +/* Any pair of 32 bit hashes can be used. lookup3.c generates pairs, will do. */ +#define _JLU3_jlu32lpair 1 +#define jlu32lpair poptJlu32lpair +#include "lookup3.c" + +/*@-varuse +charint +ignoresigns @*/ +/*@unchecked@*/ /*@observer@*/ +static const unsigned char utf8_skip_data[256] = { + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1 +}; +/*@=varuse =charint =ignoresigns @*/ + +const char * +POPT_prev_char (const char *str) +{ + const char *p = str; + + while (1) { + p--; + if (((unsigned)*p & 0xc0) != (unsigned)0x80) + return p; + } +} + +const char * +POPT_next_char (const char *str) +{ + const char *p = str; + + while (*p != '\0') { + p++; + if (((unsigned)*p & 0xc0) != (unsigned)0x80) + break; + } + return p; +} + +#if !defined(POPT_fprintf) /* XXX lose all the goop ... */ + +#if defined(HAVE_DCGETTEXT) && !defined(__LCLINT__) +/* + * Rebind a "UTF-8" codeset for popt's internal use. + */ +char * +POPT_dgettext(const char * dom, const char * str) +{ + char * codeset = NULL; + char * retval = NULL; + + if (!dom) + dom = textdomain(NULL); + codeset = bind_textdomain_codeset(dom, NULL); + bind_textdomain_codeset(dom, "UTF-8"); + retval = dgettext(dom, str); + bind_textdomain_codeset(dom, codeset); + + return retval; +} +#endif + +#ifdef HAVE_ICONV +/** + * Return malloc'd string converted from UTF-8 to current locale. + * @param istr input string (UTF-8 encoding assumed) + * @return localized string + */ +static /*@only@*/ /*@null@*/ char * +strdup_locale_from_utf8 (/*@null@*/ char * istr) + /*@*/ +{ + char * codeset = NULL; + char * ostr = NULL; + iconv_t cd; + + if (istr == NULL) + return NULL; + +#ifdef HAVE_LANGINFO_H + codeset = nl_langinfo ((nl_item)CODESET); +#endif + + if (codeset != NULL && strcmp(codeset, "UTF-8") != 0 + && (cd = iconv_open(codeset, "UTF-8")) != (iconv_t)-1) + { + char * shift_pin = NULL; + size_t db = strlen(istr); +/*@owned@*/ + char * dstr = malloc((db + 1) * sizeof(*dstr)); + char * pin = istr; + char * pout = dstr; + size_t ib = db; + size_t ob = db; + size_t err; + + if (dstr == NULL) + return NULL; + err = iconv(cd, NULL, NULL, NULL, NULL); + while (1) { + *pout = '\0'; + err = iconv(cd, &pin, &ib, &pout, &ob); + if (err != (size_t)-1) { + if (shift_pin == NULL) { + shift_pin = pin; + pin = NULL; + ib = 0; + continue; + } + } else + switch (errno) { + case E2BIG: + { size_t used = (size_t)(pout - dstr); + db *= 2; + dstr = realloc(dstr, (db + 1) * sizeof(*dstr)); + if (dstr != NULL) { + pout = dstr + used; + ob = db - used; + continue; + } + } /*@switchbreak@*/ break; + case EINVAL: + case EILSEQ: + default: + /*@switchbreak@*/ break; + } + break; + } + (void) iconv_close(cd); + *pout = '\0'; + ostr = xstrdup(dstr); + free(dstr); + } else + ostr = xstrdup(istr); + + return ostr; +} +#endif + +int +POPT_fprintf (FILE * stream, const char * format, ...) +{ + char * b = NULL, * ob = NULL; + int rc; + va_list ap; + +#if defined(HAVE_VASPRINTF) && !defined(__LCLINT__) + va_start(ap, format); + if ((rc = vasprintf(&b, format, ap)) < 0) + b = NULL; + va_end(ap); +#else + size_t nb = (size_t)1; + + /* HACK: add +1 to the realloc no. of bytes "just in case". */ + /* XXX Likely unneeded, the issues wrto vsnprintf(3) return b0rkage have + * to do with whether the final '\0' is counted (or not). The code + * below already adds +1 for the (possibly already counted) trailing NUL. + */ + while ((b = realloc(b, nb+1)) != NULL) { + va_start(ap, format); + rc = vsnprintf(b, nb, format, ap); + va_end(ap); + if (rc > -1) { /* glibc 2.1 */ + if ((size_t)rc < nb) + break; + nb = (size_t)(rc + 1); /* precise buffer length known */ + } else /* glibc 2.0 */ + nb += (nb < (size_t)100 ? (size_t)100 : nb); + ob = b; + } +#endif + + rc = 0; + if (b != NULL) { +#ifdef HAVE_ICONV + ob = strdup_locale_from_utf8(b); + if (ob != NULL) { + rc = fprintf(stream, "%s", ob); + free(ob); + } else +#endif + rc = fprintf(stream, "%s", b); + free (b); + } + + return rc; +} + +#endif /* !defined(POPT_fprintf) */ diff --git a/ldb-2.0.8/third_party/popt/poptint.h b/ldb-2.0.8/third_party/popt/poptint.h new file mode 100644 index 0000000..80cbaca --- /dev/null +++ b/ldb-2.0.8/third_party/popt/poptint.h @@ -0,0 +1,222 @@ +/** \ingroup popt + * \file popt/poptint.h + */ + +/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING + file accompanying popt source distributions, available from + ftp://ftp.rpm.org/pub/rpm/dist. */ + +#ifndef H_POPTINT +#define H_POPTINT + +#include + +/** + * Wrapper to free(3), hides const compilation noise, permit NULL, return NULL. + * @param p memory to free + * @retval NULL always + */ +/*@unused@*/ static inline /*@null@*/ void * +_free(/*@only@*/ /*@null@*/ const void * p) + /*@modifies p @*/ +{ + if (p != NULL) free((void *)p); + return NULL; +} + +/* Bit mask macros. */ +/*@-exporttype -redef @*/ +typedef unsigned int __pbm_bits; +/*@=exporttype =redef @*/ +#define __PBM_NBITS (8 * sizeof (__pbm_bits)) +#define __PBM_IX(d) ((d) / __PBM_NBITS) +#define __PBM_MASK(d) ((__pbm_bits) 1 << (((unsigned)(d)) % __PBM_NBITS)) +/*@-exporttype -redef @*/ +typedef struct { + __pbm_bits bits[1]; +} pbm_set; +/*@=exporttype =redef @*/ +#define __PBM_BITS(set) ((set)->bits) + +#define PBM_ALLOC(d) calloc(__PBM_IX (d) + 1, sizeof(__pbm_bits)) +#define PBM_FREE(s) _free(s); +#define PBM_SET(d, s) (__PBM_BITS (s)[__PBM_IX (d)] |= __PBM_MASK (d)) +#define PBM_CLR(d, s) (__PBM_BITS (s)[__PBM_IX (d)] &= ~__PBM_MASK (d)) +#define PBM_ISSET(d, s) ((__PBM_BITS (s)[__PBM_IX (d)] & __PBM_MASK (d)) != 0) + +extern void poptJlu32lpair(/*@null@*/ const void *key, size_t size, + uint32_t *pc, uint32_t *pb) + /*@modifies *pc, *pb@*/; + +/** \ingroup popt + * Typedef's for string and array of strings. + */ +/*@-exporttype@*/ +typedef const char * poptString; +typedef poptString * poptArgv; +/*@=exporttype@*/ + +/** \ingroup popt + * A union to simplify opt->arg access without casting. + */ +/*@-exporttype -fielduse@*/ +typedef union poptArg_u { +/*@shared@*/ + void * ptr; + int * intp; + short * shortp; + long * longp; + long long * longlongp; + float * floatp; + double * doublep; + const char ** argv; + poptCallbackType cb; +/*@shared@*/ + poptOption opt; +} poptArg; +/*@=exporttype =fielduse@*/ + +/*@-exportvar@*/ +/*@unchecked@*/ +extern unsigned int _poptArgMask; +/*@unchecked@*/ +extern unsigned int _poptGroupMask; +/*@=exportvar@*/ + +#define poptArgType(_opt) ((_opt)->argInfo & _poptArgMask) +#define poptGroup(_opt) ((_opt)->argInfo & _poptGroupMask) + +#define F_ISSET(_opt, _FLAG) ((_opt)->argInfo & POPT_ARGFLAG_##_FLAG) +#define LF_ISSET(_FLAG) (argInfo & POPT_ARGFLAG_##_FLAG) +#define CBF_ISSET(_opt, _FLAG) ((_opt)->argInfo & POPT_CBFLAG_##_FLAG) + +/* XXX sick hack to preserve pretense of a popt-1.x ABI. */ +#define poptSubstituteHelpI18N(opt) \ + { /*@-observertrans@*/ \ + if ((opt) == poptHelpOptions) (opt) = poptHelpOptionsI18N; \ + /*@=observertrans@*/ } + +struct optionStackEntry { + int argc; +/*@only@*/ /*@null@*/ + poptArgv argv; +/*@only@*/ /*@null@*/ + pbm_set * argb; + int next; +/*@only@*/ /*@null@*/ + char * nextArg; +/*@observer@*/ /*@null@*/ + const char * nextCharArg; +/*@dependent@*/ /*@null@*/ + poptItem currAlias; + int stuffed; +}; + +struct poptContext_s { + struct optionStackEntry optionStack[POPT_OPTION_DEPTH]; +/*@dependent@*/ + struct optionStackEntry * os; +/*@owned@*/ /*@null@*/ + poptArgv leftovers; + int numLeftovers; + int nextLeftover; +/*@keep@*/ + const struct poptOption * options; + int restLeftover; +/*@only@*/ /*@null@*/ + const char * appName; +/*@only@*/ /*@null@*/ + poptItem aliases; + int numAliases; + unsigned int flags; +/*@owned@*/ /*@null@*/ + poptItem execs; + int numExecs; +/*@only@*/ /*@null@*/ + poptArgv finalArgv; + int finalArgvCount; + int finalArgvAlloced; +/*@null@*/ + int (*maincall) (int argc, const char **argv); +/*@dependent@*/ /*@null@*/ + poptItem doExec; +/*@only@*/ /*@null@*/ + const char * execPath; + int execAbsolute; +/*@only@*/ /*@relnull@*/ + const char * otherHelp; +/*@null@*/ + pbm_set * arg_strip; +}; + +#if defined(POPT_fprintf) +#define POPT_dgettext dgettext +#else +#ifdef HAVE_ICONV +#include +#if defined(__LCLINT__) +/*@-declundef -incondefs @*/ +extern /*@only@*/ iconv_t iconv_open(const char *__tocode, const char *__fromcode) + /*@*/; + +extern size_t iconv(iconv_t __cd, /*@null@*/ char ** __inbuf, + /*@null@*/ /*@out@*/ size_t * __inbytesleft, + /*@null@*/ /*@out@*/ char ** __outbuf, + /*@null@*/ /*@out@*/ size_t * __outbytesleft) + /*@modifies __cd, + *__inbuf, *__inbytesleft, *__outbuf, *__outbytesleft @*/; + +extern int iconv_close(/*@only@*/ iconv_t __cd) + /*@modifies __cd @*/; +/*@=declundef =incondefs @*/ +#endif +#endif + +#ifdef HAVE_LANGINFO_H +#include +#if defined(__LCLINT__) +/*@-declundef -incondefs @*/ +extern char *nl_langinfo (nl_item __item) + /*@*/; +/*@=declundef =incondefs @*/ +#endif +#endif + +#if defined(HAVE_DCGETTEXT) && !defined(__LCLINT__) +char *POPT_dgettext(const char * dom, const char * str) + /*@*/; +#endif + +int POPT_fprintf (FILE* stream, const char *format, ...) + /*@globals fileSystem @*/ + /*@modifies stream, fileSystem @*/; +#endif /* !defined(POPT_fprintf) */ + +const char *POPT_prev_char (/*@returned@*/ const char *str) + /*@*/; + +const char *POPT_next_char (/*@returned@*/ const char *str) + /*@*/; + +#endif + +#if defined(ENABLE_NLS) && defined(HAVE_LIBINTL_H) +#include +#endif + +#if defined(ENABLE_NLS) && defined(HAVE_GETTEXT) && !defined(__LCLINT__) +#define _(foo) gettext(foo) +#else +#define _(foo) foo +#endif + +#if defined(ENABLE_NLS) && defined(HAVE_DCGETTEXT) && !defined(__LCLINT__) +#define D_(dom, str) POPT_dgettext(dom, str) +#define POPT_(foo) D_("popt", foo) +#else +#define D_(dom, str) str +#define POPT_(foo) foo +#endif + +#define N_(foo) foo + diff --git a/ldb-2.0.8/third_party/popt/poptparse.c b/ldb-2.0.8/third_party/popt/poptparse.c new file mode 100644 index 0000000..39bf1aa --- /dev/null +++ b/ldb-2.0.8/third_party/popt/poptparse.c @@ -0,0 +1,230 @@ +/** \ingroup popt + * \file popt/poptparse.c + */ + +/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING + file accompanying popt source distributions, available from + ftp://ftp.rpm.org/pub/rpm/dist. */ + +#include "system.h" + +#define POPT_ARGV_ARRAY_GROW_DELTA 5 + +int poptDupArgv(int argc, const char **argv, + int * argcPtr, const char *** argvPtr) +{ + size_t nb = (argc + 1) * sizeof(*argv); + const char ** argv2; + char * dst; + int i; + + if (argc <= 0 || argv == NULL) /* XXX can't happen */ + return POPT_ERROR_NOARG; + for (i = 0; i < argc; i++) { + if (argv[i] == NULL) + return POPT_ERROR_NOARG; + nb += strlen(argv[i]) + 1; + } + + dst = malloc(nb); + if (dst == NULL) /* XXX can't happen */ + return POPT_ERROR_MALLOC; + argv2 = (void *) dst; + dst += (argc + 1) * sizeof(*argv); + *dst = '\0'; + + for (i = 0; i < argc; i++) { + argv2[i] = dst; + dst = stpcpy(dst, argv[i]); + dst++; /* trailing NUL */ + } + argv2[argc] = NULL; + + if (argvPtr) { + *argvPtr = argv2; + } else { + free(argv2); + argv2 = NULL; + } + if (argcPtr) + *argcPtr = argc; + return 0; +} + +int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr) +{ + const char * src; + char quote = '\0'; + int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA; + const char ** argv = malloc(sizeof(*argv) * argvAlloced); + int argc = 0; + size_t buflen = strlen(s) + 1; + char * buf, * bufOrig = NULL; + int rc = POPT_ERROR_MALLOC; + + if (argv == NULL) return rc; + buf = bufOrig = calloc((size_t)1, buflen); + if (buf == NULL) { + free(argv); + return rc; + } + argv[argc] = buf; + + for (src = s; *src != '\0'; src++) { + if (quote == *src) { + quote = '\0'; + } else if (quote != '\0') { + if (*src == '\\') { + src++; + if (!*src) { + rc = POPT_ERROR_BADQUOTE; + goto exit; + } + if (*src != quote) *buf++ = '\\'; + } + *buf++ = *src; + } else if (_isspaceptr(src)) { + if (*argv[argc] != '\0') { + buf++, argc++; + if (argc == argvAlloced) { + argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA; + argv = realloc(argv, sizeof(*argv) * argvAlloced); + if (argv == NULL) goto exit; + } + argv[argc] = buf; + } + } else switch (*src) { + case '"': + case '\'': + quote = *src; + /*@switchbreak@*/ break; + case '\\': + src++; + if (!*src) { + rc = POPT_ERROR_BADQUOTE; + goto exit; + } + /*@fallthrough@*/ + default: + *buf++ = *src; + /*@switchbreak@*/ break; + } + } + + if (strlen(argv[argc])) { + argc++, buf++; + } + + rc = poptDupArgv(argc, argv, argcPtr, argvPtr); + +exit: + if (bufOrig) free(bufOrig); + if (argv) free(argv); + return rc; +} + +/* still in the dev stage. + * return values, perhaps 1== file erro + * 2== line to long + * 3== umm.... more? + */ +int poptConfigFileToString(FILE *fp, char ** argstrp, + /*@unused@*/ UNUSED(int flags)) +{ + char line[999]; + char * argstr; + char * p; + char * q; + char * x; + size_t t; + size_t argvlen = 0; + size_t maxlinelen = sizeof(line); + size_t linelen; + size_t maxargvlen = (size_t)480; + + *argstrp = NULL; + + /* | this_is = our_line + * p q x + */ + + if (fp == NULL) + return POPT_ERROR_NULLARG; + + argstr = calloc(maxargvlen, sizeof(*argstr)); + if (argstr == NULL) return POPT_ERROR_MALLOC; + + while (fgets(line, (int)maxlinelen, fp) != NULL) { + p = line; + + /* loop until first non-space char or EOL */ + while( *p != '\0' && _isspaceptr(p) ) + p++; + + linelen = strlen(p); + if (linelen >= maxlinelen-1) { + free(argstr); + return POPT_ERROR_OVERFLOW; /* XXX line too long */ + } + + if (*p == '\0' || *p == '\n') continue; /* line is empty */ + if (*p == '#') continue; /* comment line */ + + q = p; + + while (*q != '\0' && (!_isspaceptr(q)) && *q != '=') + q++; + + if (_isspaceptr(q)) { + /* a space after the name, find next non space */ + *q++='\0'; + while( *q != '\0' && _isspaceptr(q) ) q++; + } + if (*q == '\0') { + /* single command line option (ie, no name=val, just name) */ + q[-1] = '\0'; /* kill off newline from fgets() call */ + argvlen += (t = (size_t)(q - p)) + (sizeof(" --")-1); + if (argvlen >= maxargvlen) { + maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; + argstr = realloc(argstr, maxargvlen); + if (argstr == NULL) return POPT_ERROR_MALLOC; + } + strcat(argstr, " --"); + strcat(argstr, p); + continue; + } + if (*q != '=') + continue; /* XXX for now, silently ignore bogus line */ + + /* *q is an equal sign. */ + *q++ = '\0'; + + /* find next non-space letter of value */ + while (*q != '\0' && _isspaceptr(q)) + q++; + if (*q == '\0') + continue; /* XXX silently ignore missing value */ + + /* now, loop and strip all ending whitespace */ + x = p + linelen; + while (_isspaceptr(--x)) + *x = '\0'; /* null out last char if space (including fgets() NL) */ + + /* rest of line accept */ + t = (size_t)(x - p); + argvlen += t + (sizeof("' --='")-1); + if (argvlen >= maxargvlen) { + maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; + argstr = realloc(argstr, maxargvlen); + if (argstr == NULL) return POPT_ERROR_MALLOC; + } + strcat(argstr, " --"); + strcat(argstr, p); + strcat(argstr, "=\""); + strcat(argstr, q); + strcat(argstr, "\""); + } + + *argstrp = argstr; + return 0; +} diff --git a/ldb-2.0.8/third_party/popt/system.h b/ldb-2.0.8/third_party/popt/system.h new file mode 100644 index 0000000..452bf40 --- /dev/null +++ b/ldb-2.0.8/third_party/popt/system.h @@ -0,0 +1,103 @@ +/** + * \file popt/system.h + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined (__GLIBC__) && defined(__LCLINT__) +/*@-declundef@*/ +/*@unchecked@*/ +extern __const __int32_t *__ctype_tolower; +/*@unchecked@*/ +extern __const __int32_t *__ctype_toupper; +/*@=declundef@*/ +#endif + +#include + +/* XXX isspace(3) has i18n encoding signednesss issues on Solaris. */ +#define _isspaceptr(_chp) isspace((int)(*(unsigned char *)(_chp))) + +#include +#include +#include + +#ifdef HAVE_MCHECK_H +#include +#endif + +#include +#include +#include + +#if defined(HAVE_UNISTD_H) && !defined(__LCLINT__) +#include +#endif + +#ifdef __NeXT +/* access macros are not declared in non posix mode in unistd.h - + don't try to use posix on NeXTstep 3.3 ! */ +#include +#endif + +/*@-incondefs@*/ +/*@mayexit@*/ /*@only@*/ /*@out@*/ /*@unused@*/ +void * xmalloc (size_t size) + /*@globals errno @*/ + /*@ensures maxSet(result) == (size - 1) @*/ + /*@modifies errno @*/; + +/*@mayexit@*/ /*@only@*/ /*@unused@*/ +void * xcalloc (size_t nmemb, size_t size) + /*@ensures maxSet(result) == (nmemb - 1) @*/ + /*@*/; + +/*@mayexit@*/ /*@only@*/ /*@unused@*/ +void * xrealloc (/*@null@*/ /*@only@*/ void * ptr, size_t size) + /*@ensures maxSet(result) == (size - 1) @*/ + /*@modifies *ptr @*/; + +/*@mayexit@*/ /*@only@*/ /*@unused@*/ +char * xstrdup (const char *str) + /*@*/; +/*@=incondefs@*/ + +#if !defined(HAVE_STPCPY) +/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */ +static inline char * stpcpy (char *dest, const char * src) { + register char *d = dest; + register const char *s = src; + + do + *d++ = *s; + while (*s++ != '\0'); + return d - 1; +} +#endif + +/* Memory allocation via macro defs to get meaningful locations from mtrace() */ +#if defined(HAVE_MCHECK_H) && defined(__GNUC__) +#define vmefail() (fprintf(stderr, "virtual memory exhausted.\n"), exit(EXIT_FAILURE), NULL) +#define xmalloc(_size) (malloc(_size) ? : vmefail()) +#define xcalloc(_nmemb, _size) (calloc((_nmemb), (_size)) ? : vmefail()) +#define xrealloc(_ptr, _size) (realloc((_ptr), (_size)) ? : vmefail()) +#define xstrdup(_str) (strcpy((malloc(strlen(_str)+1) ? : vmefail()), (_str))) +#else +#define xmalloc(_size) malloc(_size) +#define xcalloc(_nmemb, _size) calloc((_nmemb), (_size)) +#define xrealloc(_ptr, _size) realloc((_ptr), (_size)) +#define xstrdup(_str) strdup(_str) +#endif /* defined(HAVE_MCHECK_H) && defined(__GNUC__) */ + +#if defined(HAVE___SECURE_GETENV) && !defined(__LCLINT__) +#define getenv(_s) __secure_getenv(_s) +#endif + +#if !defined(__GNUC__) && !defined(__attribute__) +#define __attribute__(x) +#endif +#define UNUSED(x) x __attribute__((__unused__)) + +#include "popt.h" diff --git a/ldb-2.0.8/third_party/popt/wscript b/ldb-2.0.8/third_party/popt/wscript new file mode 100644 index 0000000..ea655bb --- /dev/null +++ b/ldb-2.0.8/third_party/popt/wscript @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +from waflib import Options + +def configure(conf): + if conf.CHECK_POPT(): + conf.define('USING_SYSTEM_POPT', 1) + return + + conf.CHECK_HEADERS('float.h') + conf.CHECK_FUNCS('stpcpy') + conf.CHECK_LIB('iconv', shlib=True) + +def build(bld): + if bld.CONFIG_SET('USING_SYSTEM_POPT'): + return + + cflags = '-DPACKAGE="popt" -DPOPT_SYSCONFDIR="%s"' % bld.env.SYSCONFDIR + bld.SAMBA_LIBRARY('popt', + source='popt.c poptconfig.c popthelp.c poptint.c poptparse.c', + cflags=cflags, + deps='iconv', + allow_warnings=True, + private_library=True) diff --git a/ldb-2.0.8/third_party/waf/waflib/Build.py b/ldb-2.0.8/third_party/waf/waflib/Build.py new file mode 100644 index 0000000..39f0991 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Build.py @@ -0,0 +1,1512 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2005-2018 (ita) + +""" +Classes related to the build phase (build, clean, install, step, etc) + +The inheritance tree is the following: + +""" + +import os, sys, errno, re, shutil, stat +try: + import cPickle +except ImportError: + import pickle as cPickle +from waflib import Node, Runner, TaskGen, Utils, ConfigSet, Task, Logs, Options, Context, Errors + +CACHE_DIR = 'c4che' +"""Name of the cache directory""" + +CACHE_SUFFIX = '_cache.py' +"""ConfigSet cache files for variants are written under :py:attr:´waflib.Build.CACHE_DIR´ in the form ´variant_name´_cache.py""" + +INSTALL = 1337 +"""Positive value '->' install, see :py:attr:`waflib.Build.BuildContext.is_install`""" + +UNINSTALL = -1337 +"""Negative value '<-' uninstall, see :py:attr:`waflib.Build.BuildContext.is_install`""" + +SAVED_ATTRS = 'root node_sigs task_sigs imp_sigs raw_deps node_deps'.split() +"""Build class members to save between the runs; these should be all dicts +except for `root` which represents a :py:class:`waflib.Node.Node` instance +""" + +CFG_FILES = 'cfg_files' +"""Files from the build directory to hash before starting the build (``config.h`` written during the configuration)""" + +POST_AT_ONCE = 0 +"""Post mode: all task generators are posted before any task executed""" + +POST_LAZY = 1 +"""Post mode: post the task generators group after group, the tasks in the next group are created when the tasks in the previous groups are done""" + +PROTOCOL = -1 +if sys.platform == 'cli': + PROTOCOL = 0 + +class BuildContext(Context.Context): + '''executes the build''' + + cmd = 'build' + variant = '' + + def __init__(self, **kw): + super(BuildContext, self).__init__(**kw) + + self.is_install = 0 + """Non-zero value when installing or uninstalling file""" + + self.top_dir = kw.get('top_dir', Context.top_dir) + """See :py:attr:`waflib.Context.top_dir`; prefer :py:attr:`waflib.Build.BuildContext.srcnode`""" + + self.out_dir = kw.get('out_dir', Context.out_dir) + """See :py:attr:`waflib.Context.out_dir`; prefer :py:attr:`waflib.Build.BuildContext.bldnode`""" + + self.run_dir = kw.get('run_dir', Context.run_dir) + """See :py:attr:`waflib.Context.run_dir`""" + + self.launch_dir = Context.launch_dir + """See :py:attr:`waflib.Context.out_dir`; prefer :py:meth:`waflib.Build.BuildContext.launch_node`""" + + self.post_mode = POST_LAZY + """Whether to post the task generators at once or group-by-group (default is group-by-group)""" + + self.cache_dir = kw.get('cache_dir') + if not self.cache_dir: + self.cache_dir = os.path.join(self.out_dir, CACHE_DIR) + + self.all_envs = {} + """Map names to :py:class:`waflib.ConfigSet.ConfigSet`, the empty string must map to the default environment""" + + # ======================================= # + # cache variables + + self.node_sigs = {} + """Dict mapping build nodes to task identifier (uid), it indicates whether a task created a particular file (persists across builds)""" + + self.task_sigs = {} + """Dict mapping task identifiers (uid) to task signatures (persists across builds)""" + + self.imp_sigs = {} + """Dict mapping task identifiers (uid) to implicit task dependencies used for scanning targets (persists across builds)""" + + self.node_deps = {} + """Dict mapping task identifiers (uid) to node dependencies found by :py:meth:`waflib.Task.Task.scan` (persists across builds)""" + + self.raw_deps = {} + """Dict mapping task identifiers (uid) to custom data returned by :py:meth:`waflib.Task.Task.scan` (persists across builds)""" + + self.task_gen_cache_names = {} + + self.jobs = Options.options.jobs + """Amount of jobs to run in parallel""" + + self.targets = Options.options.targets + """List of targets to build (default: \\*)""" + + self.keep = Options.options.keep + """Whether the build should continue past errors""" + + self.progress_bar = Options.options.progress_bar + """ + Level of progress status: + + 0. normal output + 1. progress bar + 2. IDE output + 3. No output at all + """ + + # Manual dependencies. + self.deps_man = Utils.defaultdict(list) + """Manual dependencies set by :py:meth:`waflib.Build.BuildContext.add_manual_dependency`""" + + # just the structure here + self.current_group = 0 + """ + Current build group + """ + + self.groups = [] + """ + List containing lists of task generators + """ + + self.group_names = {} + """ + Map group names to the group lists. See :py:meth:`waflib.Build.BuildContext.add_group` + """ + + for v in SAVED_ATTRS: + if not hasattr(self, v): + setattr(self, v, {}) + + def get_variant_dir(self): + """Getter for the variant_dir attribute""" + if not self.variant: + return self.out_dir + return os.path.join(self.out_dir, os.path.normpath(self.variant)) + variant_dir = property(get_variant_dir, None) + + def __call__(self, *k, **kw): + """ + Create a task generator and add it to the current build group. The following forms are equivalent:: + + def build(bld): + tg = bld(a=1, b=2) + + def build(bld): + tg = bld() + tg.a = 1 + tg.b = 2 + + def build(bld): + tg = TaskGen.task_gen(a=1, b=2) + bld.add_to_group(tg, None) + + :param group: group name to add the task generator to + :type group: string + """ + kw['bld'] = self + ret = TaskGen.task_gen(*k, **kw) + self.task_gen_cache_names = {} # reset the cache, each time + self.add_to_group(ret, group=kw.get('group')) + return ret + + def __copy__(self): + """ + Build contexts cannot be copied + + :raises: :py:class:`waflib.Errors.WafError` + """ + raise Errors.WafError('build contexts cannot be copied') + + def load_envs(self): + """ + The configuration command creates files of the form ``build/c4che/NAMEcache.py``. This method + creates a :py:class:`waflib.ConfigSet.ConfigSet` instance for each ``NAME`` by reading those + files and stores them in :py:attr:`waflib.Build.BuildContext.allenvs`. + """ + node = self.root.find_node(self.cache_dir) + if not node: + raise Errors.WafError('The project was not configured: run "waf configure" first!') + lst = node.ant_glob('**/*%s' % CACHE_SUFFIX, quiet=True) + + if not lst: + raise Errors.WafError('The cache directory is empty: reconfigure the project') + + for x in lst: + name = x.path_from(node).replace(CACHE_SUFFIX, '').replace('\\', '/') + env = ConfigSet.ConfigSet(x.abspath()) + self.all_envs[name] = env + for f in env[CFG_FILES]: + newnode = self.root.find_resource(f) + if not newnode or not newnode.exists(): + raise Errors.WafError('Missing configuration file %r, reconfigure the project!' % f) + + def init_dirs(self): + """ + Initialize the project directory and the build directory by creating the nodes + :py:attr:`waflib.Build.BuildContext.srcnode` and :py:attr:`waflib.Build.BuildContext.bldnode` + corresponding to ``top_dir`` and ``variant_dir`` respectively. The ``bldnode`` directory is + created if necessary. + """ + if not (os.path.isabs(self.top_dir) and os.path.isabs(self.out_dir)): + raise Errors.WafError('The project was not configured: run "waf configure" first!') + + self.path = self.srcnode = self.root.find_dir(self.top_dir) + self.bldnode = self.root.make_node(self.variant_dir) + self.bldnode.mkdir() + + def execute(self): + """ + Restore data from previous builds and call :py:meth:`waflib.Build.BuildContext.execute_build`. + Overrides from :py:func:`waflib.Context.Context.execute` + """ + self.restore() + if not self.all_envs: + self.load_envs() + self.execute_build() + + def execute_build(self): + """ + Execute the build by: + + * reading the scripts (see :py:meth:`waflib.Context.Context.recurse`) + * calling :py:meth:`waflib.Build.BuildContext.pre_build` to call user build functions + * calling :py:meth:`waflib.Build.BuildContext.compile` to process the tasks + * calling :py:meth:`waflib.Build.BuildContext.post_build` to call user build functions + """ + + Logs.info("Waf: Entering directory `%s'", self.variant_dir) + self.recurse([self.run_dir]) + self.pre_build() + + # display the time elapsed in the progress bar + self.timer = Utils.Timer() + + try: + self.compile() + finally: + if self.progress_bar == 1 and sys.stderr.isatty(): + c = self.producer.processed or 1 + m = self.progress_line(c, c, Logs.colors.BLUE, Logs.colors.NORMAL) + Logs.info(m, extra={'stream': sys.stderr, 'c1': Logs.colors.cursor_off, 'c2' : Logs.colors.cursor_on}) + Logs.info("Waf: Leaving directory `%s'", self.variant_dir) + try: + self.producer.bld = None + del self.producer + except AttributeError: + pass + self.post_build() + + def restore(self): + """ + Load data from a previous run, sets the attributes listed in :py:const:`waflib.Build.SAVED_ATTRS` + """ + try: + env = ConfigSet.ConfigSet(os.path.join(self.cache_dir, 'build.config.py')) + except EnvironmentError: + pass + else: + if env.version < Context.HEXVERSION: + raise Errors.WafError('Project was configured with a different version of Waf, please reconfigure it') + + for t in env.tools: + self.setup(**t) + + dbfn = os.path.join(self.variant_dir, Context.DBFILE) + try: + data = Utils.readf(dbfn, 'rb') + except (EnvironmentError, EOFError): + # handle missing file/empty file + Logs.debug('build: Could not load the build cache %s (missing)', dbfn) + else: + try: + Node.pickle_lock.acquire() + Node.Nod3 = self.node_class + try: + data = cPickle.loads(data) + except Exception as e: + Logs.debug('build: Could not pickle the build cache %s: %r', dbfn, e) + else: + for x in SAVED_ATTRS: + setattr(self, x, data.get(x, {})) + finally: + Node.pickle_lock.release() + + self.init_dirs() + + def store(self): + """ + Store data for next runs, set the attributes listed in :py:const:`waflib.Build.SAVED_ATTRS`. Uses a temporary + file to avoid problems on ctrl+c. + """ + data = {} + for x in SAVED_ATTRS: + data[x] = getattr(self, x) + db = os.path.join(self.variant_dir, Context.DBFILE) + + try: + Node.pickle_lock.acquire() + Node.Nod3 = self.node_class + x = cPickle.dumps(data, PROTOCOL) + finally: + Node.pickle_lock.release() + + Utils.writef(db + '.tmp', x, m='wb') + + try: + st = os.stat(db) + os.remove(db) + if not Utils.is_win32: # win32 has no chown but we're paranoid + os.chown(db + '.tmp', st.st_uid, st.st_gid) + except (AttributeError, OSError): + pass + + # do not use shutil.move (copy is not thread-safe) + os.rename(db + '.tmp', db) + + def compile(self): + """ + Run the build by creating an instance of :py:class:`waflib.Runner.Parallel` + The cache file is written when at least a task was executed. + + :raises: :py:class:`waflib.Errors.BuildError` in case the build fails + """ + Logs.debug('build: compile()') + + # delegate the producer-consumer logic to another object to reduce the complexity + self.producer = Runner.Parallel(self, self.jobs) + self.producer.biter = self.get_build_iterator() + try: + self.producer.start() + except KeyboardInterrupt: + if self.is_dirty(): + self.store() + raise + else: + if self.is_dirty(): + self.store() + + if self.producer.error: + raise Errors.BuildError(self.producer.error) + + def is_dirty(self): + return self.producer.dirty + + def setup(self, tool, tooldir=None, funs=None): + """ + Import waf tools defined during the configuration:: + + def configure(conf): + conf.load('glib2') + + def build(bld): + pass # glib2 is imported implicitly + + :param tool: tool list + :type tool: list + :param tooldir: optional tool directory (sys.path) + :type tooldir: list of string + :param funs: unused variable + """ + if isinstance(tool, list): + for i in tool: + self.setup(i, tooldir) + return + + module = Context.load_tool(tool, tooldir) + if hasattr(module, "setup"): + module.setup(self) + + def get_env(self): + """Getter for the env property""" + try: + return self.all_envs[self.variant] + except KeyError: + return self.all_envs[''] + def set_env(self, val): + """Setter for the env property""" + self.all_envs[self.variant] = val + + env = property(get_env, set_env) + + def add_manual_dependency(self, path, value): + """ + Adds a dependency from a node object to a value:: + + def build(bld): + bld.add_manual_dependency( + bld.path.find_resource('wscript'), + bld.root.find_resource('/etc/fstab')) + + :param path: file path + :type path: string or :py:class:`waflib.Node.Node` + :param value: value to depend + :type value: :py:class:`waflib.Node.Node`, byte object, or function returning a byte object + """ + if not path: + raise ValueError('Invalid input path %r' % path) + + if isinstance(path, Node.Node): + node = path + elif os.path.isabs(path): + node = self.root.find_resource(path) + else: + node = self.path.find_resource(path) + if not node: + raise ValueError('Could not find the path %r' % path) + + if isinstance(value, list): + self.deps_man[node].extend(value) + else: + self.deps_man[node].append(value) + + def launch_node(self): + """Returns the launch directory as a :py:class:`waflib.Node.Node` object (cached)""" + try: + # private cache + return self.p_ln + except AttributeError: + self.p_ln = self.root.find_dir(self.launch_dir) + return self.p_ln + + def hash_env_vars(self, env, vars_lst): + """ + Hashes configuration set variables:: + + def build(bld): + bld.hash_env_vars(bld.env, ['CXX', 'CC']) + + This method uses an internal cache. + + :param env: Configuration Set + :type env: :py:class:`waflib.ConfigSet.ConfigSet` + :param vars_lst: list of variables + :type vars_list: list of string + """ + + if not env.table: + env = env.parent + if not env: + return Utils.SIG_NIL + + idx = str(id(env)) + str(vars_lst) + try: + cache = self.cache_env + except AttributeError: + cache = self.cache_env = {} + else: + try: + return self.cache_env[idx] + except KeyError: + pass + + lst = [env[a] for a in vars_lst] + cache[idx] = ret = Utils.h_list(lst) + Logs.debug('envhash: %s %r', Utils.to_hex(ret), lst) + return ret + + def get_tgen_by_name(self, name): + """ + Fetches a task generator by its name or its target attribute; + the name must be unique in a build:: + + def build(bld): + tg = bld(name='foo') + tg == bld.get_tgen_by_name('foo') + + This method use a private internal cache. + + :param name: Task generator name + :raises: :py:class:`waflib.Errors.WafError` in case there is no task genenerator by that name + """ + cache = self.task_gen_cache_names + if not cache: + # create the index lazily + for g in self.groups: + for tg in g: + try: + cache[tg.name] = tg + except AttributeError: + # raised if not a task generator, which should be uncommon + pass + try: + return cache[name] + except KeyError: + raise Errors.WafError('Could not find a task generator for the name %r' % name) + + def progress_line(self, idx, total, col1, col2): + """ + Computes a progress bar line displayed when running ``waf -p`` + + :returns: progress bar line + :rtype: string + """ + if not sys.stderr.isatty(): + return '' + + n = len(str(total)) + + Utils.rot_idx += 1 + ind = Utils.rot_chr[Utils.rot_idx % 4] + + pc = (100. * idx)/total + fs = "[%%%dd/%%d][%%s%%2d%%%%%%s][%s][" % (n, ind) + left = fs % (idx, total, col1, pc, col2) + right = '][%s%s%s]' % (col1, self.timer, col2) + + cols = Logs.get_term_cols() - len(left) - len(right) + 2*len(col1) + 2*len(col2) + if cols < 7: + cols = 7 + + ratio = ((cols * idx)//total) - 1 + + bar = ('='*ratio+'>').ljust(cols) + msg = Logs.indicator % (left, bar, right) + + return msg + + def declare_chain(self, *k, **kw): + """ + Wraps :py:func:`waflib.TaskGen.declare_chain` for convenience + """ + return TaskGen.declare_chain(*k, **kw) + + def pre_build(self): + """Executes user-defined methods before the build starts, see :py:meth:`waflib.Build.BuildContext.add_pre_fun`""" + for m in getattr(self, 'pre_funs', []): + m(self) + + def post_build(self): + """Executes user-defined methods after the build is successful, see :py:meth:`waflib.Build.BuildContext.add_post_fun`""" + for m in getattr(self, 'post_funs', []): + m(self) + + def add_pre_fun(self, meth): + """ + Binds a callback method to execute after the scripts are read and before the build starts:: + + def mycallback(bld): + print("Hello, world!") + + def build(bld): + bld.add_pre_fun(mycallback) + """ + try: + self.pre_funs.append(meth) + except AttributeError: + self.pre_funs = [meth] + + def add_post_fun(self, meth): + """ + Binds a callback method to execute immediately after the build is successful:: + + def call_ldconfig(bld): + bld.exec_command('/sbin/ldconfig') + + def build(bld): + if bld.cmd == 'install': + bld.add_pre_fun(call_ldconfig) + """ + try: + self.post_funs.append(meth) + except AttributeError: + self.post_funs = [meth] + + def get_group(self, x): + """ + Returns the build group named `x`, or the current group if `x` is None + + :param x: name or number or None + :type x: string, int or None + """ + if not self.groups: + self.add_group() + if x is None: + return self.groups[self.current_group] + if x in self.group_names: + return self.group_names[x] + return self.groups[x] + + def add_to_group(self, tgen, group=None): + """Adds a task or a task generator to the build; there is no attempt to remove it if it was already added.""" + assert(isinstance(tgen, TaskGen.task_gen) or isinstance(tgen, Task.Task)) + tgen.bld = self + self.get_group(group).append(tgen) + + def get_group_name(self, g): + """ + Returns the name of the input build group + + :param g: build group object or build group index + :type g: integer or list + :return: name + :rtype: string + """ + if not isinstance(g, list): + g = self.groups[g] + for x in self.group_names: + if id(self.group_names[x]) == id(g): + return x + return '' + + def get_group_idx(self, tg): + """ + Returns the index of the group containing the task generator given as argument:: + + def build(bld): + tg = bld(name='nada') + 0 == bld.get_group_idx(tg) + + :param tg: Task generator object + :type tg: :py:class:`waflib.TaskGen.task_gen` + :rtype: int + """ + se = id(tg) + for i, tmp in enumerate(self.groups): + for t in tmp: + if id(t) == se: + return i + return None + + def add_group(self, name=None, move=True): + """ + Adds a new group of tasks/task generators. By default the new group becomes + the default group for new task generators (make sure to create build groups in order). + + :param name: name for this group + :type name: string + :param move: set this new group as default group (True by default) + :type move: bool + :raises: :py:class:`waflib.Errors.WafError` if a group by the name given already exists + """ + if name and name in self.group_names: + raise Errors.WafError('add_group: name %s already present', name) + g = [] + self.group_names[name] = g + self.groups.append(g) + if move: + self.current_group = len(self.groups) - 1 + + def set_group(self, idx): + """ + Sets the build group at position idx as current so that newly added + task generators are added to this one by default:: + + def build(bld): + bld(rule='touch ${TGT}', target='foo.txt') + bld.add_group() # now the current group is 1 + bld(rule='touch ${TGT}', target='bar.txt') + bld.set_group(0) # now the current group is 0 + bld(rule='touch ${TGT}', target='truc.txt') # build truc.txt before bar.txt + + :param idx: group name or group index + :type idx: string or int + """ + if isinstance(idx, str): + g = self.group_names[idx] + for i, tmp in enumerate(self.groups): + if id(g) == id(tmp): + self.current_group = i + break + else: + self.current_group = idx + + def total(self): + """ + Approximate task count: this value may be inaccurate if task generators + are posted lazily (see :py:attr:`waflib.Build.BuildContext.post_mode`). + The value :py:attr:`waflib.Runner.Parallel.total` is updated during the task execution. + + :rtype: int + """ + total = 0 + for group in self.groups: + for tg in group: + try: + total += len(tg.tasks) + except AttributeError: + total += 1 + return total + + def get_targets(self): + """ + This method returns a pair containing the index of the last build group to post, + and the list of task generator objects corresponding to the target names. + + This is used internally by :py:meth:`waflib.Build.BuildContext.get_build_iterator` + to perform partial builds:: + + $ waf --targets=myprogram,myshlib + + :return: the minimum build group index, and list of task generators + :rtype: tuple + """ + to_post = [] + min_grp = 0 + for name in self.targets.split(','): + tg = self.get_tgen_by_name(name) + m = self.get_group_idx(tg) + if m > min_grp: + min_grp = m + to_post = [tg] + elif m == min_grp: + to_post.append(tg) + return (min_grp, to_post) + + def get_all_task_gen(self): + """ + Returns a list of all task generators for troubleshooting purposes. + """ + lst = [] + for g in self.groups: + lst.extend(g) + return lst + + def post_group(self): + """ + Post task generators from the group indexed by self.current_group; used internally + by :py:meth:`waflib.Build.BuildContext.get_build_iterator` + """ + def tgpost(tg): + try: + f = tg.post + except AttributeError: + pass + else: + f() + + if self.targets == '*': + for tg in self.groups[self.current_group]: + tgpost(tg) + elif self.targets: + if self.current_group < self._min_grp: + for tg in self.groups[self.current_group]: + tgpost(tg) + else: + for tg in self._exact_tg: + tg.post() + else: + ln = self.launch_node() + if ln.is_child_of(self.bldnode): + Logs.warn('Building from the build directory, forcing --targets=*') + ln = self.srcnode + elif not ln.is_child_of(self.srcnode): + Logs.warn('CWD %s is not under %s, forcing --targets=* (run distclean?)', ln.abspath(), self.srcnode.abspath()) + ln = self.srcnode + + def is_post(tg, ln): + try: + p = tg.path + except AttributeError: + pass + else: + if p.is_child_of(ln): + return True + + def is_post_group(): + for i, g in enumerate(self.groups): + if i > self.current_group: + for tg in g: + if is_post(tg, ln): + return True + + if self.post_mode == POST_LAZY and ln != self.srcnode: + # partial folder builds require all targets from a previous build group + if is_post_group(): + ln = self.srcnode + + for tg in self.groups[self.current_group]: + if is_post(tg, ln): + tgpost(tg) + + def get_tasks_group(self, idx): + """ + Returns all task instances for the build group at position idx, + used internally by :py:meth:`waflib.Build.BuildContext.get_build_iterator` + + :rtype: list of :py:class:`waflib.Task.Task` + """ + tasks = [] + for tg in self.groups[idx]: + try: + tasks.extend(tg.tasks) + except AttributeError: # not a task generator + tasks.append(tg) + return tasks + + def get_build_iterator(self): + """ + Creates a Python generator object that returns lists of tasks that may be processed in parallel. + + :return: tasks which can be executed immediately + :rtype: generator returning lists of :py:class:`waflib.Task.Task` + """ + if self.targets and self.targets != '*': + (self._min_grp, self._exact_tg) = self.get_targets() + + if self.post_mode != POST_LAZY: + for self.current_group, _ in enumerate(self.groups): + self.post_group() + + for self.current_group, _ in enumerate(self.groups): + # first post the task generators for the group + if self.post_mode != POST_AT_ONCE: + self.post_group() + + # then extract the tasks + tasks = self.get_tasks_group(self.current_group) + + # if the constraints are set properly (ext_in/ext_out, before/after) + # the call to set_file_constraints may be removed (can be a 15% penalty on no-op rebuilds) + # (but leave set_file_constraints for the installation step) + # + # if the tasks have only files, set_file_constraints is required but set_precedence_constraints is not necessary + # + Task.set_file_constraints(tasks) + Task.set_precedence_constraints(tasks) + + self.cur_tasks = tasks + if tasks: + yield tasks + + while 1: + # the build stops once there are no tasks to process + yield [] + + def install_files(self, dest, files, **kw): + """ + Creates a task generator to install files on the system:: + + def build(bld): + bld.install_files('${DATADIR}', self.path.find_resource('wscript')) + + :param dest: path representing the destination directory + :type dest: :py:class:`waflib.Node.Node` or string (absolute path) + :param files: input files + :type files: list of strings or list of :py:class:`waflib.Node.Node` + :param env: configuration set to expand *dest* + :type env: :py:class:`waflib.ConfigSet.ConfigSet` + :param relative_trick: preserve the folder hierarchy when installing whole folders + :type relative_trick: bool + :param cwd: parent node for searching srcfile, when srcfile is not an instance of :py:class:`waflib.Node.Node` + :type cwd: :py:class:`waflib.Node.Node` + :param postpone: execute the task immediately to perform the installation (False by default) + :type postpone: bool + """ + assert(dest) + tg = self(features='install_task', install_to=dest, install_from=files, **kw) + tg.dest = tg.install_to + tg.type = 'install_files' + if not kw.get('postpone', True): + tg.post() + return tg + + def install_as(self, dest, srcfile, **kw): + """ + Creates a task generator to install a file on the system with a different name:: + + def build(bld): + bld.install_as('${PREFIX}/bin', 'myapp', chmod=Utils.O755) + + :param dest: destination file + :type dest: :py:class:`waflib.Node.Node` or string (absolute path) + :param srcfile: input file + :type srcfile: string or :py:class:`waflib.Node.Node` + :param cwd: parent node for searching srcfile, when srcfile is not an instance of :py:class:`waflib.Node.Node` + :type cwd: :py:class:`waflib.Node.Node` + :param env: configuration set for performing substitutions in dest + :type env: :py:class:`waflib.ConfigSet.ConfigSet` + :param postpone: execute the task immediately to perform the installation (False by default) + :type postpone: bool + """ + assert(dest) + tg = self(features='install_task', install_to=dest, install_from=srcfile, **kw) + tg.dest = tg.install_to + tg.type = 'install_as' + if not kw.get('postpone', True): + tg.post() + return tg + + def symlink_as(self, dest, src, **kw): + """ + Creates a task generator to install a symlink:: + + def build(bld): + bld.symlink_as('${PREFIX}/lib/libfoo.so', 'libfoo.so.1.2.3') + + :param dest: absolute path of the symlink + :type dest: :py:class:`waflib.Node.Node` or string (absolute path) + :param src: link contents, which is a relative or absolute path which may exist or not + :type src: string + :param env: configuration set for performing substitutions in dest + :type env: :py:class:`waflib.ConfigSet.ConfigSet` + :param add: add the task created to a build group - set ``False`` only if the installation task is created after the build has started + :type add: bool + :param postpone: execute the task immediately to perform the installation + :type postpone: bool + :param relative_trick: make the symlink relative (default: ``False``) + :type relative_trick: bool + """ + assert(dest) + tg = self(features='install_task', install_to=dest, install_from=src, **kw) + tg.dest = tg.install_to + tg.type = 'symlink_as' + tg.link = src + # TODO if add: self.add_to_group(tsk) + if not kw.get('postpone', True): + tg.post() + return tg + +@TaskGen.feature('install_task') +@TaskGen.before_method('process_rule', 'process_source') +def process_install_task(self): + """Creates the installation task for the current task generator; uses :py:func:`waflib.Build.add_install_task` internally.""" + self.add_install_task(**self.__dict__) + +@TaskGen.taskgen_method +def add_install_task(self, **kw): + """ + Creates the installation task for the current task generator, and executes it immediately if necessary + + :returns: An installation task + :rtype: :py:class:`waflib.Build.inst` + """ + if not self.bld.is_install: + return + if not kw['install_to']: + return + + if kw['type'] == 'symlink_as' and Utils.is_win32: + if kw.get('win32_install'): + kw['type'] = 'install_as' + else: + # just exit + return + + tsk = self.install_task = self.create_task('inst') + tsk.chmod = kw.get('chmod', Utils.O644) + tsk.link = kw.get('link', '') or kw.get('install_from', '') + tsk.relative_trick = kw.get('relative_trick', False) + tsk.type = kw['type'] + tsk.install_to = tsk.dest = kw['install_to'] + tsk.install_from = kw['install_from'] + tsk.relative_base = kw.get('cwd') or kw.get('relative_base', self.path) + tsk.install_user = kw.get('install_user') + tsk.install_group = kw.get('install_group') + tsk.init_files() + if not kw.get('postpone', True): + tsk.run_now() + return tsk + +@TaskGen.taskgen_method +def add_install_files(self, **kw): + """ + Creates an installation task for files + + :returns: An installation task + :rtype: :py:class:`waflib.Build.inst` + """ + kw['type'] = 'install_files' + return self.add_install_task(**kw) + +@TaskGen.taskgen_method +def add_install_as(self, **kw): + """ + Creates an installation task for a single file + + :returns: An installation task + :rtype: :py:class:`waflib.Build.inst` + """ + kw['type'] = 'install_as' + return self.add_install_task(**kw) + +@TaskGen.taskgen_method +def add_symlink_as(self, **kw): + """ + Creates an installation task for a symbolic link + + :returns: An installation task + :rtype: :py:class:`waflib.Build.inst` + """ + kw['type'] = 'symlink_as' + return self.add_install_task(**kw) + +class inst(Task.Task): + """Task that installs files or symlinks; it is typically executed by :py:class:`waflib.Build.InstallContext` and :py:class:`waflib.Build.UnInstallContext`""" + def __str__(self): + """Returns an empty string to disable the standard task display""" + return '' + + def uid(self): + """Returns a unique identifier for the task""" + lst = self.inputs + self.outputs + [self.link, self.generator.path.abspath()] + return Utils.h_list(lst) + + def init_files(self): + """ + Initializes the task input and output nodes + """ + if self.type == 'symlink_as': + inputs = [] + else: + inputs = self.generator.to_nodes(self.install_from) + if self.type == 'install_as': + assert len(inputs) == 1 + self.set_inputs(inputs) + + dest = self.get_install_path() + outputs = [] + if self.type == 'symlink_as': + if self.relative_trick: + self.link = os.path.relpath(self.link, os.path.dirname(dest)) + outputs.append(self.generator.bld.root.make_node(dest)) + elif self.type == 'install_as': + outputs.append(self.generator.bld.root.make_node(dest)) + else: + for y in inputs: + if self.relative_trick: + destfile = os.path.join(dest, y.path_from(self.relative_base)) + else: + destfile = os.path.join(dest, y.name) + outputs.append(self.generator.bld.root.make_node(destfile)) + self.set_outputs(outputs) + + def runnable_status(self): + """ + Installation tasks are always executed, so this method returns either :py:const:`waflib.Task.ASK_LATER` or :py:const:`waflib.Task.RUN_ME`. + """ + ret = super(inst, self).runnable_status() + if ret == Task.SKIP_ME and self.generator.bld.is_install: + return Task.RUN_ME + return ret + + def post_run(self): + """ + Disables any post-run operations + """ + pass + + def get_install_path(self, destdir=True): + """ + Returns the destination path where files will be installed, pre-pending `destdir`. + + Relative paths will be interpreted relative to `PREFIX` if no `destdir` is given. + + :rtype: string + """ + if isinstance(self.install_to, Node.Node): + dest = self.install_to.abspath() + else: + dest = os.path.normpath(Utils.subst_vars(self.install_to, self.env)) + if not os.path.isabs(dest): + dest = os.path.join(self.env.PREFIX, dest) + if destdir and Options.options.destdir: + dest = os.path.join(Options.options.destdir, os.path.splitdrive(dest)[1].lstrip(os.sep)) + return dest + + def copy_fun(self, src, tgt): + """ + Copies a file from src to tgt, preserving permissions and trying to work + around path limitations on Windows platforms. On Unix-like platforms, + the owner/group of the target file may be set through install_user/install_group + + :param src: absolute path + :type src: string + :param tgt: absolute path + :type tgt: string + """ + # override this if you want to strip executables + # kw['tsk'].source is the task that created the files in the build + if Utils.is_win32 and len(tgt) > 259 and not tgt.startswith('\\\\?\\'): + tgt = '\\\\?\\' + tgt + shutil.copy2(src, tgt) + self.fix_perms(tgt) + + def rm_empty_dirs(self, tgt): + """ + Removes empty folders recursively when uninstalling. + + :param tgt: absolute path + :type tgt: string + """ + while tgt: + tgt = os.path.dirname(tgt) + try: + os.rmdir(tgt) + except OSError: + break + + def run(self): + """ + Performs file or symlink installation + """ + is_install = self.generator.bld.is_install + if not is_install: # unnecessary? + return + + for x in self.outputs: + if is_install == INSTALL: + x.parent.mkdir() + if self.type == 'symlink_as': + fun = is_install == INSTALL and self.do_link or self.do_unlink + fun(self.link, self.outputs[0].abspath()) + else: + fun = is_install == INSTALL and self.do_install or self.do_uninstall + launch_node = self.generator.bld.launch_node() + for x, y in zip(self.inputs, self.outputs): + fun(x.abspath(), y.abspath(), x.path_from(launch_node)) + + def run_now(self): + """ + Try executing the installation task right now + + :raises: :py:class:`waflib.Errors.TaskNotReady` + """ + status = self.runnable_status() + if status not in (Task.RUN_ME, Task.SKIP_ME): + raise Errors.TaskNotReady('Could not process %r: status %r' % (self, status)) + self.run() + self.hasrun = Task.SUCCESS + + def do_install(self, src, tgt, lbl, **kw): + """ + Copies a file from src to tgt with given file permissions. The actual copy is only performed + if the source and target file sizes or timestamps differ. When the copy occurs, + the file is always first removed and then copied so as to prevent stale inodes. + + :param src: file name as absolute path + :type src: string + :param tgt: file destination, as absolute path + :type tgt: string + :param lbl: file source description + :type lbl: string + :param chmod: installation mode + :type chmod: int + :raises: :py:class:`waflib.Errors.WafError` if the file cannot be written + """ + if not Options.options.force: + # check if the file is already there to avoid a copy + try: + st1 = os.stat(tgt) + st2 = os.stat(src) + except OSError: + pass + else: + # same size and identical timestamps -> make no copy + if st1.st_mtime + 2 >= st2.st_mtime and st1.st_size == st2.st_size: + if not self.generator.bld.progress_bar: + + c1 = Logs.colors.NORMAL + c2 = Logs.colors.BLUE + + Logs.info('%s- install %s%s%s (from %s)', c1, c2, tgt, c1, lbl) + return False + + if not self.generator.bld.progress_bar: + + c1 = Logs.colors.NORMAL + c2 = Logs.colors.BLUE + + Logs.info('%s+ install %s%s%s (from %s)', c1, c2, tgt, c1, lbl) + + # Give best attempt at making destination overwritable, + # like the 'install' utility used by 'make install' does. + try: + os.chmod(tgt, Utils.O644 | stat.S_IMODE(os.stat(tgt).st_mode)) + except EnvironmentError: + pass + + # following is for shared libs and stale inodes (-_-) + try: + os.remove(tgt) + except OSError: + pass + + try: + self.copy_fun(src, tgt) + except EnvironmentError as e: + if not os.path.exists(src): + Logs.error('File %r does not exist', src) + elif not os.path.isfile(src): + Logs.error('Input %r is not a file', src) + raise Errors.WafError('Could not install the file %r' % tgt, e) + + def fix_perms(self, tgt): + """ + Change the ownership of the file/folder/link pointed by the given path + This looks up for `install_user` or `install_group` attributes + on the task or on the task generator:: + + def build(bld): + bld.install_as('${PREFIX}/wscript', + 'wscript', + install_user='nobody', install_group='nogroup') + bld.symlink_as('${PREFIX}/wscript_link', + Utils.subst_vars('${PREFIX}/wscript', bld.env), + install_user='nobody', install_group='nogroup') + """ + if not Utils.is_win32: + user = getattr(self, 'install_user', None) or getattr(self.generator, 'install_user', None) + group = getattr(self, 'install_group', None) or getattr(self.generator, 'install_group', None) + if user or group: + Utils.lchown(tgt, user or -1, group or -1) + if not os.path.islink(tgt): + os.chmod(tgt, self.chmod) + + def do_link(self, src, tgt, **kw): + """ + Creates a symlink from tgt to src. + + :param src: file name as absolute path + :type src: string + :param tgt: file destination, as absolute path + :type tgt: string + """ + if os.path.islink(tgt) and os.readlink(tgt) == src: + if not self.generator.bld.progress_bar: + c1 = Logs.colors.NORMAL + c2 = Logs.colors.BLUE + Logs.info('%s- symlink %s%s%s (to %s)', c1, c2, tgt, c1, src) + else: + try: + os.remove(tgt) + except OSError: + pass + if not self.generator.bld.progress_bar: + c1 = Logs.colors.NORMAL + c2 = Logs.colors.BLUE + Logs.info('%s+ symlink %s%s%s (to %s)', c1, c2, tgt, c1, src) + os.symlink(src, tgt) + self.fix_perms(tgt) + + def do_uninstall(self, src, tgt, lbl, **kw): + """ + See :py:meth:`waflib.Build.inst.do_install` + """ + if not self.generator.bld.progress_bar: + c1 = Logs.colors.NORMAL + c2 = Logs.colors.BLUE + Logs.info('%s- remove %s%s%s', c1, c2, tgt, c1) + + #self.uninstall.append(tgt) + try: + os.remove(tgt) + except OSError as e: + if e.errno != errno.ENOENT: + if not getattr(self, 'uninstall_error', None): + self.uninstall_error = True + Logs.warn('build: some files could not be uninstalled (retry with -vv to list them)') + if Logs.verbose > 1: + Logs.warn('Could not remove %s (error code %r)', e.filename, e.errno) + self.rm_empty_dirs(tgt) + + def do_unlink(self, src, tgt, **kw): + """ + See :py:meth:`waflib.Build.inst.do_link` + """ + try: + if not self.generator.bld.progress_bar: + c1 = Logs.colors.NORMAL + c2 = Logs.colors.BLUE + Logs.info('%s- remove %s%s%s', c1, c2, tgt, c1) + os.remove(tgt) + except OSError: + pass + self.rm_empty_dirs(tgt) + +class InstallContext(BuildContext): + '''installs the targets on the system''' + cmd = 'install' + + def __init__(self, **kw): + super(InstallContext, self).__init__(**kw) + self.is_install = INSTALL + +class UninstallContext(InstallContext): + '''removes the targets installed''' + cmd = 'uninstall' + + def __init__(self, **kw): + super(UninstallContext, self).__init__(**kw) + self.is_install = UNINSTALL + +class CleanContext(BuildContext): + '''cleans the project''' + cmd = 'clean' + def execute(self): + """ + See :py:func:`waflib.Build.BuildContext.execute`. + """ + self.restore() + if not self.all_envs: + self.load_envs() + + self.recurse([self.run_dir]) + try: + self.clean() + finally: + self.store() + + def clean(self): + """ + Remove most files from the build directory, and reset all caches. + + Custom lists of files to clean can be declared as `bld.clean_files`. + For example, exclude `build/program/myprogram` from getting removed:: + + def build(bld): + bld.clean_files = bld.bldnode.ant_glob('**', + excl='.lock* config.log c4che/* config.h program/myprogram', + quiet=True, generator=True) + """ + Logs.debug('build: clean called') + + if hasattr(self, 'clean_files'): + for n in self.clean_files: + n.delete() + elif self.bldnode != self.srcnode: + # would lead to a disaster if top == out + lst = [] + for env in self.all_envs.values(): + lst.extend(self.root.find_or_declare(f) for f in env[CFG_FILES]) + excluded_dirs = '.lock* *conf_check_*/** config.log %s/*' % CACHE_DIR + for n in self.bldnode.ant_glob('**/*', excl=excluded_dirs, quiet=True): + if n in lst: + continue + n.delete() + self.root.children = {} + + for v in SAVED_ATTRS: + if v == 'root': + continue + setattr(self, v, {}) + +class ListContext(BuildContext): + '''lists the targets to execute''' + cmd = 'list' + + def execute(self): + """ + In addition to printing the name of each build target, + a description column will include text for each task + generator which has a "description" field set. + + See :py:func:`waflib.Build.BuildContext.execute`. + """ + self.restore() + if not self.all_envs: + self.load_envs() + + self.recurse([self.run_dir]) + self.pre_build() + + # display the time elapsed in the progress bar + self.timer = Utils.Timer() + + for g in self.groups: + for tg in g: + try: + f = tg.post + except AttributeError: + pass + else: + f() + + try: + # force the cache initialization + self.get_tgen_by_name('') + except Errors.WafError: + pass + + targets = sorted(self.task_gen_cache_names) + + # figure out how much to left-justify, for largest target name + line_just = max(len(t) for t in targets) if targets else 0 + + for target in targets: + tgen = self.task_gen_cache_names[target] + + # Support displaying the description for the target + # if it was set on the tgen + descript = getattr(tgen, 'description', '') + if descript: + target = target.ljust(line_just) + descript = ': %s' % descript + + Logs.pprint('GREEN', target, label=descript) + +class StepContext(BuildContext): + '''executes tasks in a step-by-step fashion, for debugging''' + cmd = 'step' + + def __init__(self, **kw): + super(StepContext, self).__init__(**kw) + self.files = Options.options.files + + def compile(self): + """ + Overrides :py:meth:`waflib.Build.BuildContext.compile` to perform a partial build + on tasks matching the input/output pattern given (regular expression matching):: + + $ waf step --files=foo.c,bar.c,in:truc.c,out:bar.o + $ waf step --files=in:foo.cpp.1.o # link task only + + """ + if not self.files: + Logs.warn('Add a pattern for the debug build, for example "waf step --files=main.c,app"') + BuildContext.compile(self) + return + + targets = [] + if self.targets and self.targets != '*': + targets = self.targets.split(',') + + for g in self.groups: + for tg in g: + if targets and tg.name not in targets: + continue + + try: + f = tg.post + except AttributeError: + pass + else: + f() + + for pat in self.files.split(','): + matcher = self.get_matcher(pat) + for tg in g: + if isinstance(tg, Task.Task): + lst = [tg] + else: + lst = tg.tasks + for tsk in lst: + do_exec = False + for node in tsk.inputs: + if matcher(node, output=False): + do_exec = True + break + for node in tsk.outputs: + if matcher(node, output=True): + do_exec = True + break + if do_exec: + ret = tsk.run() + Logs.info('%s -> exit %r', tsk, ret) + + def get_matcher(self, pat): + """ + Converts a step pattern into a function + + :param: pat: pattern of the form in:truc.c,out:bar.o + :returns: Python function that uses Node objects as inputs and returns matches + :rtype: function + """ + # this returns a function + inn = True + out = True + if pat.startswith('in:'): + out = False + pat = pat.replace('in:', '') + elif pat.startswith('out:'): + inn = False + pat = pat.replace('out:', '') + + anode = self.root.find_node(pat) + pattern = None + if not anode: + if not pat.startswith('^'): + pat = '^.+?%s' % pat + if not pat.endswith('$'): + pat = '%s$' % pat + pattern = re.compile(pat) + + def match(node, output): + if output and not out: + return False + if not output and not inn: + return False + + if anode: + return anode == node + else: + return pattern.match(node.abspath()) + return match + +class EnvContext(BuildContext): + """Subclass EnvContext to create commands that require configuration data in 'env'""" + fun = cmd = None + def execute(self): + """ + See :py:func:`waflib.Build.BuildContext.execute`. + """ + self.restore() + if not self.all_envs: + self.load_envs() + self.recurse([self.run_dir]) + diff --git a/ldb-2.0.8/third_party/waf/waflib/ConfigSet.py b/ldb-2.0.8/third_party/waf/waflib/ConfigSet.py new file mode 100644 index 0000000..901fba6 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/ConfigSet.py @@ -0,0 +1,361 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2005-2018 (ita) + +""" + +ConfigSet: a special dict + +The values put in :py:class:`ConfigSet` must be serializable (dicts, lists, strings) +""" + +import copy, re, os +from waflib import Logs, Utils +re_imp = re.compile(r'^(#)*?([^#=]*?)\ =\ (.*?)$', re.M) + +class ConfigSet(object): + """ + A copy-on-write dict with human-readable serialized format. The serialization format + is human-readable (python-like) and performed by using eval() and repr(). + For high performance prefer pickle. Do not store functions as they are not serializable. + + The values can be accessed by attributes or by keys:: + + from waflib.ConfigSet import ConfigSet + env = ConfigSet() + env.FOO = 'test' + env['FOO'] = 'test' + """ + __slots__ = ('table', 'parent') + def __init__(self, filename=None): + self.table = {} + """ + Internal dict holding the object values + """ + #self.parent = None + + if filename: + self.load(filename) + + def __contains__(self, key): + """ + Enables the *in* syntax:: + + if 'foo' in env: + print(env['foo']) + """ + if key in self.table: + return True + try: + return self.parent.__contains__(key) + except AttributeError: + return False # parent may not exist + + def keys(self): + """Dict interface""" + keys = set() + cur = self + while cur: + keys.update(cur.table.keys()) + cur = getattr(cur, 'parent', None) + keys = list(keys) + keys.sort() + return keys + + def __iter__(self): + return iter(self.keys()) + + def __str__(self): + """Text representation of the ConfigSet (for debugging purposes)""" + return "\n".join(["%r %r" % (x, self.__getitem__(x)) for x in self.keys()]) + + def __getitem__(self, key): + """ + Dictionary interface: get value from key:: + + def configure(conf): + conf.env['foo'] = {} + print(env['foo']) + """ + try: + while 1: + x = self.table.get(key) + if not x is None: + return x + self = self.parent + except AttributeError: + return [] + + def __setitem__(self, key, value): + """ + Dictionary interface: set value from key + """ + self.table[key] = value + + def __delitem__(self, key): + """ + Dictionary interface: mark the value as missing + """ + self[key] = [] + + def __getattr__(self, name): + """ + Attribute access provided for convenience. The following forms are equivalent:: + + def configure(conf): + conf.env.value + conf.env['value'] + """ + if name in self.__slots__: + return object.__getattribute__(self, name) + else: + return self[name] + + def __setattr__(self, name, value): + """ + Attribute access provided for convenience. The following forms are equivalent:: + + def configure(conf): + conf.env.value = x + env['value'] = x + """ + if name in self.__slots__: + object.__setattr__(self, name, value) + else: + self[name] = value + + def __delattr__(self, name): + """ + Attribute access provided for convenience. The following forms are equivalent:: + + def configure(conf): + del env.value + del env['value'] + """ + if name in self.__slots__: + object.__delattr__(self, name) + else: + del self[name] + + def derive(self): + """ + Returns a new ConfigSet deriving from self. The copy returned + will be a shallow copy:: + + from waflib.ConfigSet import ConfigSet + env = ConfigSet() + env.append_value('CFLAGS', ['-O2']) + child = env.derive() + child.CFLAGS.append('test') # warning! this will modify 'env' + child.CFLAGS = ['-O3'] # new list, ok + child.append_value('CFLAGS', ['-O3']) # ok + + Use :py:func:`ConfigSet.detach` to detach the child from the parent. + """ + newenv = ConfigSet() + newenv.parent = self + return newenv + + def detach(self): + """ + Detaches this instance from its parent (if present) + + Modifying the parent :py:class:`ConfigSet` will not change the current object + Modifying this :py:class:`ConfigSet` will not modify the parent one. + """ + tbl = self.get_merged_dict() + try: + delattr(self, 'parent') + except AttributeError: + pass + else: + keys = tbl.keys() + for x in keys: + tbl[x] = copy.deepcopy(tbl[x]) + self.table = tbl + return self + + def get_flat(self, key): + """ + Returns a value as a string. If the input is a list, the value returned is space-separated. + + :param key: key to use + :type key: string + """ + s = self[key] + if isinstance(s, str): + return s + return ' '.join(s) + + def _get_list_value_for_modification(self, key): + """ + Returns a list value for further modification. + + The list may be modified inplace and there is no need to do this afterwards:: + + self.table[var] = value + """ + try: + value = self.table[key] + except KeyError: + try: + value = self.parent[key] + except AttributeError: + value = [] + else: + if isinstance(value, list): + # force a copy + value = value[:] + else: + value = [value] + self.table[key] = value + else: + if not isinstance(value, list): + self.table[key] = value = [value] + return value + + def append_value(self, var, val): + """ + Appends a value to the specified config key:: + + def build(bld): + bld.env.append_value('CFLAGS', ['-O2']) + + The value must be a list or a tuple + """ + if isinstance(val, str): # if there were string everywhere we could optimize this + val = [val] + current_value = self._get_list_value_for_modification(var) + current_value.extend(val) + + def prepend_value(self, var, val): + """ + Prepends a value to the specified item:: + + def configure(conf): + conf.env.prepend_value('CFLAGS', ['-O2']) + + The value must be a list or a tuple + """ + if isinstance(val, str): + val = [val] + self.table[var] = val + self._get_list_value_for_modification(var) + + def append_unique(self, var, val): + """ + Appends a value to the specified item only if it's not already present:: + + def build(bld): + bld.env.append_unique('CFLAGS', ['-O2', '-g']) + + The value must be a list or a tuple + """ + if isinstance(val, str): + val = [val] + current_value = self._get_list_value_for_modification(var) + + for x in val: + if x not in current_value: + current_value.append(x) + + def get_merged_dict(self): + """ + Computes the merged dictionary from the fusion of self and all its parent + + :rtype: a ConfigSet object + """ + table_list = [] + env = self + while 1: + table_list.insert(0, env.table) + try: + env = env.parent + except AttributeError: + break + merged_table = {} + for table in table_list: + merged_table.update(table) + return merged_table + + def store(self, filename): + """ + Serializes the :py:class:`ConfigSet` data to a file. See :py:meth:`ConfigSet.load` for reading such files. + + :param filename: file to use + :type filename: string + """ + try: + os.makedirs(os.path.split(filename)[0]) + except OSError: + pass + + buf = [] + merged_table = self.get_merged_dict() + keys = list(merged_table.keys()) + keys.sort() + + try: + fun = ascii + except NameError: + fun = repr + + for k in keys: + if k != 'undo_stack': + buf.append('%s = %s\n' % (k, fun(merged_table[k]))) + Utils.writef(filename, ''.join(buf)) + + def load(self, filename): + """ + Restores contents from a file (current values are not cleared). Files are written using :py:meth:`ConfigSet.store`. + + :param filename: file to use + :type filename: string + """ + tbl = self.table + code = Utils.readf(filename, m='r') + for m in re_imp.finditer(code): + g = m.group + tbl[g(2)] = eval(g(3)) + Logs.debug('env: %s', self.table) + + def update(self, d): + """ + Dictionary interface: replace values with the ones from another dict + + :param d: object to use the value from + :type d: dict-like object + """ + self.table.update(d) + + def stash(self): + """ + Stores the object state to provide transactionality semantics:: + + env = ConfigSet() + env.stash() + try: + env.append_value('CFLAGS', '-O3') + call_some_method(env) + finally: + env.revert() + + The history is kept in a stack, and is lost during the serialization by :py:meth:`ConfigSet.store` + """ + orig = self.table + tbl = self.table = self.table.copy() + for x in tbl.keys(): + tbl[x] = copy.deepcopy(tbl[x]) + self.undo_stack = self.undo_stack + [orig] + + def commit(self): + """ + Commits transactional changes. See :py:meth:`ConfigSet.stash` + """ + self.undo_stack.pop(-1) + + def revert(self): + """ + Reverts the object to a previous state. See :py:meth:`ConfigSet.stash` + """ + self.table = self.undo_stack.pop(-1) + diff --git a/ldb-2.0.8/third_party/waf/waflib/Configure.py b/ldb-2.0.8/third_party/waf/waflib/Configure.py new file mode 100644 index 0000000..5762eb6 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Configure.py @@ -0,0 +1,649 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2005-2018 (ita) + +""" +Configuration system + +A :py:class:`waflib.Configure.ConfigurationContext` instance is created when ``waf configure`` is called, it is used to: + +* create data dictionaries (ConfigSet instances) +* store the list of modules to import +* hold configuration routines such as ``find_program``, etc +""" + +import os, re, shlex, shutil, sys, time, traceback +from waflib import ConfigSet, Utils, Options, Logs, Context, Build, Errors + +WAF_CONFIG_LOG = 'config.log' +"""Name of the configuration log file""" + +autoconfig = False +"""Execute the configuration automatically""" + +conf_template = '''# project %(app)s configured on %(now)s by +# waf %(wafver)s (abi %(abi)s, python %(pyver)x on %(systype)s) +# using %(args)s +#''' + +class ConfigurationContext(Context.Context): + '''configures the project''' + + cmd = 'configure' + + error_handlers = [] + """ + Additional functions to handle configuration errors + """ + + def __init__(self, **kw): + super(ConfigurationContext, self).__init__(**kw) + self.environ = dict(os.environ) + self.all_envs = {} + + self.top_dir = None + self.out_dir = None + + self.tools = [] # tools loaded in the configuration, and that will be loaded when building + + self.hash = 0 + self.files = [] + + self.tool_cache = [] + + self.setenv('') + + def setenv(self, name, env=None): + """ + Set a new config set for conf.env. If a config set of that name already exists, + recall it without modification. + + The name is the filename prefix to save to ``c4che/NAME_cache.py``, and it + is also used as *variants* by the build commands. + Though related to variants, whatever kind of data may be stored in the config set:: + + def configure(cfg): + cfg.env.ONE = 1 + cfg.setenv('foo') + cfg.env.ONE = 2 + + def build(bld): + 2 == bld.env_of_name('foo').ONE + + :param name: name of the configuration set + :type name: string + :param env: ConfigSet to copy, or an empty ConfigSet is created + :type env: :py:class:`waflib.ConfigSet.ConfigSet` + """ + if name not in self.all_envs or env: + if not env: + env = ConfigSet.ConfigSet() + self.prepare_env(env) + else: + env = env.derive() + self.all_envs[name] = env + self.variant = name + + def get_env(self): + """Getter for the env property""" + return self.all_envs[self.variant] + def set_env(self, val): + """Setter for the env property""" + self.all_envs[self.variant] = val + + env = property(get_env, set_env) + + def init_dirs(self): + """ + Initialize the project directory and the build directory + """ + + top = self.top_dir + if not top: + top = Options.options.top + if not top: + top = getattr(Context.g_module, Context.TOP, None) + if not top: + top = self.path.abspath() + top = os.path.abspath(top) + + self.srcnode = (os.path.isabs(top) and self.root or self.path).find_dir(top) + assert(self.srcnode) + + out = self.out_dir + if not out: + out = Options.options.out + if not out: + out = getattr(Context.g_module, Context.OUT, None) + if not out: + out = Options.lockfile.replace('.lock-waf_%s_' % sys.platform, '').replace('.lock-waf', '') + + # someone can be messing with symlinks + out = os.path.realpath(out) + + self.bldnode = (os.path.isabs(out) and self.root or self.path).make_node(out) + self.bldnode.mkdir() + + if not os.path.isdir(self.bldnode.abspath()): + self.fatal('Could not create the build directory %s' % self.bldnode.abspath()) + + def execute(self): + """ + See :py:func:`waflib.Context.Context.execute` + """ + self.init_dirs() + + self.cachedir = self.bldnode.make_node(Build.CACHE_DIR) + self.cachedir.mkdir() + + path = os.path.join(self.bldnode.abspath(), WAF_CONFIG_LOG) + self.logger = Logs.make_logger(path, 'cfg') + + app = getattr(Context.g_module, 'APPNAME', '') + if app: + ver = getattr(Context.g_module, 'VERSION', '') + if ver: + app = "%s (%s)" % (app, ver) + + params = {'now': time.ctime(), 'pyver': sys.hexversion, 'systype': sys.platform, 'args': " ".join(sys.argv), 'wafver': Context.WAFVERSION, 'abi': Context.ABI, 'app': app} + self.to_log(conf_template % params) + self.msg('Setting top to', self.srcnode.abspath()) + self.msg('Setting out to', self.bldnode.abspath()) + + if id(self.srcnode) == id(self.bldnode): + Logs.warn('Setting top == out') + elif id(self.path) != id(self.srcnode): + if self.srcnode.is_child_of(self.path): + Logs.warn('Are you certain that you do not want to set top="." ?') + + super(ConfigurationContext, self).execute() + + self.store() + + Context.top_dir = self.srcnode.abspath() + Context.out_dir = self.bldnode.abspath() + + # this will write a configure lock so that subsequent builds will + # consider the current path as the root directory (see prepare_impl). + # to remove: use 'waf distclean' + env = ConfigSet.ConfigSet() + env.argv = sys.argv + env.options = Options.options.__dict__ + env.config_cmd = self.cmd + + env.run_dir = Context.run_dir + env.top_dir = Context.top_dir + env.out_dir = Context.out_dir + + # conf.hash & conf.files hold wscript files paths and hash + # (used only by Configure.autoconfig) + env.hash = self.hash + env.files = self.files + env.environ = dict(self.environ) + env.launch_dir = Context.launch_dir + + if not (self.env.NO_LOCK_IN_RUN or env.environ.get('NO_LOCK_IN_RUN') or getattr(Options.options, 'no_lock_in_run')): + env.store(os.path.join(Context.run_dir, Options.lockfile)) + if not (self.env.NO_LOCK_IN_TOP or env.environ.get('NO_LOCK_IN_TOP') or getattr(Options.options, 'no_lock_in_top')): + env.store(os.path.join(Context.top_dir, Options.lockfile)) + if not (self.env.NO_LOCK_IN_OUT or env.environ.get('NO_LOCK_IN_OUT') or getattr(Options.options, 'no_lock_in_out')): + env.store(os.path.join(Context.out_dir, Options.lockfile)) + + def prepare_env(self, env): + """ + Insert *PREFIX*, *BINDIR* and *LIBDIR* values into ``env`` + + :type env: :py:class:`waflib.ConfigSet.ConfigSet` + :param env: a ConfigSet, usually ``conf.env`` + """ + if not env.PREFIX: + if Options.options.prefix or Utils.is_win32: + env.PREFIX = Options.options.prefix + else: + env.PREFIX = '/' + if not env.BINDIR: + if Options.options.bindir: + env.BINDIR = Options.options.bindir + else: + env.BINDIR = Utils.subst_vars('${PREFIX}/bin', env) + if not env.LIBDIR: + if Options.options.libdir: + env.LIBDIR = Options.options.libdir + else: + env.LIBDIR = Utils.subst_vars('${PREFIX}/lib%s' % Utils.lib64(), env) + + def store(self): + """Save the config results into the cache file""" + n = self.cachedir.make_node('build.config.py') + n.write('version = 0x%x\ntools = %r\n' % (Context.HEXVERSION, self.tools)) + + if not self.all_envs: + self.fatal('nothing to store in the configuration context!') + + for key in self.all_envs: + tmpenv = self.all_envs[key] + tmpenv.store(os.path.join(self.cachedir.abspath(), key + Build.CACHE_SUFFIX)) + + def load(self, tool_list, tooldir=None, funs=None, with_sys_path=True, cache=False): + """ + Load Waf tools, which will be imported whenever a build is started. + + :param tool_list: waf tools to import + :type tool_list: list of string + :param tooldir: paths for the imports + :type tooldir: list of string + :param funs: functions to execute from the waf tools + :type funs: list of string + :param cache: whether to prevent the tool from running twice + :type cache: bool + """ + + tools = Utils.to_list(tool_list) + if tooldir: + tooldir = Utils.to_list(tooldir) + for tool in tools: + # avoid loading the same tool more than once with the same functions + # used by composite projects + + if cache: + mag = (tool, id(self.env), tooldir, funs) + if mag in self.tool_cache: + self.to_log('(tool %s is already loaded, skipping)' % tool) + continue + self.tool_cache.append(mag) + + module = None + try: + module = Context.load_tool(tool, tooldir, ctx=self, with_sys_path=with_sys_path) + except ImportError as e: + self.fatal('Could not load the Waf tool %r from %r\n%s' % (tool, getattr(e, 'waf_sys_path', sys.path), e)) + except Exception as e: + self.to_log('imp %r (%r & %r)' % (tool, tooldir, funs)) + self.to_log(traceback.format_exc()) + raise + + if funs is not None: + self.eval_rules(funs) + else: + func = getattr(module, 'configure', None) + if func: + if type(func) is type(Utils.readf): + func(self) + else: + self.eval_rules(func) + + self.tools.append({'tool':tool, 'tooldir':tooldir, 'funs':funs}) + + def post_recurse(self, node): + """ + Records the path and a hash of the scripts visited, see :py:meth:`waflib.Context.Context.post_recurse` + + :param node: script + :type node: :py:class:`waflib.Node.Node` + """ + super(ConfigurationContext, self).post_recurse(node) + self.hash = Utils.h_list((self.hash, node.read('rb'))) + self.files.append(node.abspath()) + + def eval_rules(self, rules): + """ + Execute configuration tests provided as list of functions to run + + :param rules: list of configuration method names + :type rules: list of string + """ + self.rules = Utils.to_list(rules) + for x in self.rules: + f = getattr(self, x) + if not f: + self.fatal('No such configuration function %r' % x) + f() + +def conf(f): + """ + Decorator: attach new configuration functions to :py:class:`waflib.Build.BuildContext` and + :py:class:`waflib.Configure.ConfigurationContext`. The methods bound will accept a parameter + named 'mandatory' to disable the configuration errors:: + + def configure(conf): + conf.find_program('abc', mandatory=False) + + :param f: method to bind + :type f: function + """ + def fun(*k, **kw): + mandatory = kw.pop('mandatory', True) + try: + return f(*k, **kw) + except Errors.ConfigurationError: + if mandatory: + raise + + fun.__name__ = f.__name__ + setattr(ConfigurationContext, f.__name__, fun) + setattr(Build.BuildContext, f.__name__, fun) + return f + +@conf +def add_os_flags(self, var, dest=None, dup=False): + """ + Import operating system environment values into ``conf.env`` dict:: + + def configure(conf): + conf.add_os_flags('CFLAGS') + + :param var: variable to use + :type var: string + :param dest: destination variable, by default the same as var + :type dest: string + :param dup: add the same set of flags again + :type dup: bool + """ + try: + flags = shlex.split(self.environ[var]) + except KeyError: + return + if dup or ''.join(flags) not in ''.join(Utils.to_list(self.env[dest or var])): + self.env.append_value(dest or var, flags) + +@conf +def cmd_to_list(self, cmd): + """ + Detect if a command is written in pseudo shell like ``ccache g++`` and return a list. + + :param cmd: command + :type cmd: a string or a list of string + """ + if isinstance(cmd, str): + if os.path.isfile(cmd): + # do not take any risk + return [cmd] + if os.sep == '/': + return shlex.split(cmd) + else: + try: + return shlex.split(cmd, posix=False) + except TypeError: + # Python 2.5 on windows? + return shlex.split(cmd) + return cmd + +@conf +def check_waf_version(self, mini='1.9.99', maxi='2.1.0', **kw): + """ + Raise a Configuration error if the Waf version does not strictly match the given bounds:: + + conf.check_waf_version(mini='1.9.99', maxi='2.1.0') + + :type mini: number, tuple or string + :param mini: Minimum required version + :type maxi: number, tuple or string + :param maxi: Maximum allowed version + """ + self.start_msg('Checking for waf version in %s-%s' % (str(mini), str(maxi)), **kw) + ver = Context.HEXVERSION + if Utils.num2ver(mini) > ver: + self.fatal('waf version should be at least %r (%r found)' % (Utils.num2ver(mini), ver)) + if Utils.num2ver(maxi) < ver: + self.fatal('waf version should be at most %r (%r found)' % (Utils.num2ver(maxi), ver)) + self.end_msg('ok', **kw) + +@conf +def find_file(self, filename, path_list=[]): + """ + Find a file in a list of paths + + :param filename: name of the file to search for + :param path_list: list of directories to search + :return: the first matching filename; else a configuration exception is raised + """ + for n in Utils.to_list(filename): + for d in Utils.to_list(path_list): + p = os.path.expanduser(os.path.join(d, n)) + if os.path.exists(p): + return p + self.fatal('Could not find %r' % filename) + +@conf +def find_program(self, filename, **kw): + """ + Search for a program on the operating system + + When var is used, you may set os.environ[var] to help find a specific program version, for example:: + + $ CC='ccache gcc' waf configure + + :param path_list: paths to use for searching + :type param_list: list of string + :param var: store the result to conf.env[var] where var defaults to filename.upper() if not provided; the result is stored as a list of strings + :type var: string + :param value: obtain the program from the value passed exclusively + :type value: list or string (list is preferred) + :param exts: list of extensions for the binary (do not add an extension for portability) + :type exts: list of string + :param msg: name to display in the log, by default filename is used + :type msg: string + :param interpreter: interpreter for the program + :type interpreter: ConfigSet variable key + :raises: :py:class:`waflib.Errors.ConfigurationError` + """ + + exts = kw.get('exts', Utils.is_win32 and '.exe,.com,.bat,.cmd' or ',.sh,.pl,.py') + + environ = kw.get('environ', getattr(self, 'environ', os.environ)) + + ret = '' + + filename = Utils.to_list(filename) + msg = kw.get('msg', ', '.join(filename)) + + var = kw.get('var', '') + if not var: + var = re.sub(r'[-.]', '_', filename[0].upper()) + + path_list = kw.get('path_list', '') + if path_list: + path_list = Utils.to_list(path_list) + else: + path_list = environ.get('PATH', '').split(os.pathsep) + + if kw.get('value'): + # user-provided in command-line options and passed to find_program + ret = self.cmd_to_list(kw['value']) + elif environ.get(var): + # user-provided in the os environment + ret = self.cmd_to_list(environ[var]) + elif self.env[var]: + # a default option in the wscript file + ret = self.cmd_to_list(self.env[var]) + else: + if not ret: + ret = self.find_binary(filename, exts.split(','), path_list) + if not ret and Utils.winreg: + ret = Utils.get_registry_app_path(Utils.winreg.HKEY_CURRENT_USER, filename) + if not ret and Utils.winreg: + ret = Utils.get_registry_app_path(Utils.winreg.HKEY_LOCAL_MACHINE, filename) + ret = self.cmd_to_list(ret) + + if ret: + if len(ret) == 1: + retmsg = ret[0] + else: + retmsg = ret + else: + retmsg = False + + self.msg('Checking for program %r' % msg, retmsg, **kw) + if not kw.get('quiet'): + self.to_log('find program=%r paths=%r var=%r -> %r' % (filename, path_list, var, ret)) + + if not ret: + self.fatal(kw.get('errmsg', '') or 'Could not find the program %r' % filename) + + interpreter = kw.get('interpreter') + if interpreter is None: + if not Utils.check_exe(ret[0], env=environ): + self.fatal('Program %r is not executable' % ret) + self.env[var] = ret + else: + self.env[var] = self.env[interpreter] + ret + + return ret + +@conf +def find_binary(self, filenames, exts, paths): + for f in filenames: + for ext in exts: + exe_name = f + ext + if os.path.isabs(exe_name): + if os.path.isfile(exe_name): + return exe_name + else: + for path in paths: + x = os.path.expanduser(os.path.join(path, exe_name)) + if os.path.isfile(x): + return x + return None + +@conf +def run_build(self, *k, **kw): + """ + Create a temporary build context to execute a build. A reference to that build + context is kept on self.test_bld for debugging purposes, and you should not rely + on it too much (read the note on the cache below). + The parameters given in the arguments to this function are passed as arguments for + a single task generator created in the build. Only three parameters are obligatory: + + :param features: features to pass to a task generator created in the build + :type features: list of string + :param compile_filename: file to create for the compilation (default: *test.c*) + :type compile_filename: string + :param code: code to write in the filename to compile + :type code: string + + Though this function returns *0* by default, the build may set an attribute named *retval* on the + build context object to return a particular value. See :py:func:`waflib.Tools.c_config.test_exec_fun` for example. + + This function also features a cache which can be enabled by the following option:: + + def options(opt): + opt.add_option('--confcache', dest='confcache', default=0, + action='count', help='Use a configuration cache') + + And execute the configuration with the following command-line:: + + $ waf configure --confcache + + """ + buf = [] + for key in sorted(kw.keys()): + v = kw[key] + if hasattr(v, '__call__'): + buf.append(Utils.h_fun(v)) + else: + buf.append(str(v)) + h = Utils.h_list(buf) + dir = self.bldnode.abspath() + os.sep + (not Utils.is_win32 and '.' or '') + 'conf_check_' + Utils.to_hex(h) + + cachemode = kw.get('confcache', getattr(Options.options, 'confcache', None)) + + if not cachemode and os.path.exists(dir): + shutil.rmtree(dir) + + try: + os.makedirs(dir) + except OSError: + pass + + try: + os.stat(dir) + except OSError: + self.fatal('cannot use the configuration test folder %r' % dir) + + if cachemode == 1: + try: + proj = ConfigSet.ConfigSet(os.path.join(dir, 'cache_run_build')) + except EnvironmentError: + pass + else: + ret = proj['cache_run_build'] + if isinstance(ret, str) and ret.startswith('Test does not build'): + self.fatal(ret) + return ret + + bdir = os.path.join(dir, 'testbuild') + + if not os.path.exists(bdir): + os.makedirs(bdir) + + cls_name = kw.get('run_build_cls') or getattr(self, 'run_build_cls', 'build') + self.test_bld = bld = Context.create_context(cls_name, top_dir=dir, out_dir=bdir) + bld.init_dirs() + bld.progress_bar = 0 + bld.targets = '*' + + bld.logger = self.logger + bld.all_envs.update(self.all_envs) # not really necessary + bld.env = kw['env'] + + bld.kw = kw + bld.conf = self + kw['build_fun'](bld) + ret = -1 + try: + try: + bld.compile() + except Errors.WafError: + ret = 'Test does not build: %s' % traceback.format_exc() + self.fatal(ret) + else: + ret = getattr(bld, 'retval', 0) + finally: + if cachemode: + # cache the results each time + proj = ConfigSet.ConfigSet() + proj['cache_run_build'] = ret + proj.store(os.path.join(dir, 'cache_run_build')) + else: + shutil.rmtree(dir) + return ret + +@conf +def ret_msg(self, msg, args): + if isinstance(msg, str): + return msg + return msg(args) + +@conf +def test(self, *k, **kw): + + if not 'env' in kw: + kw['env'] = self.env.derive() + + # validate_c for example + if kw.get('validate'): + kw['validate'](kw) + + self.start_msg(kw['msg'], **kw) + ret = None + try: + ret = self.run_build(*k, **kw) + except self.errors.ConfigurationError: + self.end_msg(kw['errmsg'], 'YELLOW', **kw) + if Logs.verbose > 1: + raise + else: + self.fatal('The configuration failed') + else: + kw['success'] = ret + + if kw.get('post_check'): + ret = kw['post_check'](kw) + + if ret: + self.end_msg(kw['errmsg'], 'YELLOW', **kw) + self.fatal('The configuration failed %r' % ret) + else: + self.end_msg(self.ret_msg(kw['okmsg'], kw), **kw) + return ret + diff --git a/ldb-2.0.8/third_party/waf/waflib/Context.py b/ldb-2.0.8/third_party/waf/waflib/Context.py new file mode 100644 index 0000000..e3305fa --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Context.py @@ -0,0 +1,737 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2010-2018 (ita) + +""" +Classes and functions enabling the command system +""" + +import os, re, imp, sys +from waflib import Utils, Errors, Logs +import waflib.Node + +# the following 3 constants are updated on each new release (do not touch) +HEXVERSION=0x2001200 +"""Constant updated on new releases""" + +WAFVERSION="2.0.18" +"""Constant updated on new releases""" + +WAFREVISION="314689b8994259a84f0de0aaef74d7ce91f541ad" +"""Git revision when the waf version is updated""" + +ABI = 20 +"""Version of the build data cache file format (used in :py:const:`waflib.Context.DBFILE`)""" + +DBFILE = '.wafpickle-%s-%d-%d' % (sys.platform, sys.hexversion, ABI) +"""Name of the pickle file for storing the build data""" + +APPNAME = 'APPNAME' +"""Default application name (used by ``waf dist``)""" + +VERSION = 'VERSION' +"""Default application version (used by ``waf dist``)""" + +TOP = 'top' +"""The variable name for the top-level directory in wscript files""" + +OUT = 'out' +"""The variable name for the output directory in wscript files""" + +WSCRIPT_FILE = 'wscript' +"""Name of the waf script files""" + +launch_dir = '' +"""Directory from which waf has been called""" +run_dir = '' +"""Location of the wscript file to use as the entry point""" +top_dir = '' +"""Location of the project directory (top), if the project was configured""" +out_dir = '' +"""Location of the build directory (out), if the project was configured""" +waf_dir = '' +"""Directory containing the waf modules""" + +default_encoding = Utils.console_encoding() +"""Encoding to use when reading outputs from other processes""" + +g_module = None +""" +Module representing the top-level wscript file (see :py:const:`waflib.Context.run_dir`) +""" + +STDOUT = 1 +STDERR = -1 +BOTH = 0 + +classes = [] +""" +List of :py:class:`waflib.Context.Context` subclasses that can be used as waf commands. The classes +are added automatically by a metaclass. +""" + +def create_context(cmd_name, *k, **kw): + """ + Returns a new :py:class:`waflib.Context.Context` instance corresponding to the given command. + Used in particular by :py:func:`waflib.Scripting.run_command` + + :param cmd_name: command name + :type cmd_name: string + :param k: arguments to give to the context class initializer + :type k: list + :param k: keyword arguments to give to the context class initializer + :type k: dict + :return: Context object + :rtype: :py:class:`waflib.Context.Context` + """ + for x in classes: + if x.cmd == cmd_name: + return x(*k, **kw) + ctx = Context(*k, **kw) + ctx.fun = cmd_name + return ctx + +class store_context(type): + """ + Metaclass that registers command classes into the list :py:const:`waflib.Context.classes` + Context classes must provide an attribute 'cmd' representing the command name, and a function + attribute 'fun' representing the function name that the command uses. + """ + def __init__(cls, name, bases, dct): + super(store_context, cls).__init__(name, bases, dct) + name = cls.__name__ + + if name in ('ctx', 'Context'): + return + + try: + cls.cmd + except AttributeError: + raise Errors.WafError('Missing command for the context class %r (cmd)' % name) + + if not getattr(cls, 'fun', None): + cls.fun = cls.cmd + + classes.insert(0, cls) + +ctx = store_context('ctx', (object,), {}) +"""Base class for all :py:class:`waflib.Context.Context` classes""" + +class Context(ctx): + """ + Default context for waf commands, and base class for new command contexts. + + Context objects are passed to top-level functions:: + + def foo(ctx): + print(ctx.__class__.__name__) # waflib.Context.Context + + Subclasses must define the class attributes 'cmd' and 'fun': + + :param cmd: command to execute as in ``waf cmd`` + :type cmd: string + :param fun: function name to execute when the command is called + :type fun: string + + .. inheritance-diagram:: waflib.Context.Context waflib.Build.BuildContext waflib.Build.InstallContext waflib.Build.UninstallContext waflib.Build.StepContext waflib.Build.ListContext waflib.Configure.ConfigurationContext waflib.Scripting.Dist waflib.Scripting.DistCheck waflib.Build.CleanContext + + """ + + errors = Errors + """ + Shortcut to :py:mod:`waflib.Errors` provided for convenience + """ + + tools = {} + """ + A module cache for wscript files; see :py:meth:`Context.Context.load` + """ + + def __init__(self, **kw): + try: + rd = kw['run_dir'] + except KeyError: + rd = run_dir + + # binds the context to the nodes in use to avoid a context singleton + self.node_class = type('Nod3', (waflib.Node.Node,), {}) + self.node_class.__module__ = 'waflib.Node' + self.node_class.ctx = self + + self.root = self.node_class('', None) + self.cur_script = None + self.path = self.root.find_dir(rd) + + self.stack_path = [] + self.exec_dict = {'ctx':self, 'conf':self, 'bld':self, 'opt':self} + self.logger = None + + def finalize(self): + """ + Called to free resources such as logger files + """ + try: + logger = self.logger + except AttributeError: + pass + else: + Logs.free_logger(logger) + delattr(self, 'logger') + + def load(self, tool_list, *k, **kw): + """ + Loads a Waf tool as a module, and try calling the function named :py:const:`waflib.Context.Context.fun` + from it. A ``tooldir`` argument may be provided as a list of module paths. + + :param tool_list: list of Waf tool names to load + :type tool_list: list of string or space-separated string + """ + tools = Utils.to_list(tool_list) + path = Utils.to_list(kw.get('tooldir', '')) + with_sys_path = kw.get('with_sys_path', True) + + for t in tools: + module = load_tool(t, path, with_sys_path=with_sys_path) + fun = getattr(module, kw.get('name', self.fun), None) + if fun: + fun(self) + + def execute(self): + """ + Here, it calls the function name in the top-level wscript file. Most subclasses + redefine this method to provide additional functionality. + """ + self.recurse([os.path.dirname(g_module.root_path)]) + + def pre_recurse(self, node): + """ + Method executed immediately before a folder is read by :py:meth:`waflib.Context.Context.recurse`. + The current script is bound as a Node object on ``self.cur_script``, and the current path + is bound to ``self.path`` + + :param node: script + :type node: :py:class:`waflib.Node.Node` + """ + self.stack_path.append(self.cur_script) + + self.cur_script = node + self.path = node.parent + + def post_recurse(self, node): + """ + Restores ``self.cur_script`` and ``self.path`` right after :py:meth:`waflib.Context.Context.recurse` terminates. + + :param node: script + :type node: :py:class:`waflib.Node.Node` + """ + self.cur_script = self.stack_path.pop() + if self.cur_script: + self.path = self.cur_script.parent + + def recurse(self, dirs, name=None, mandatory=True, once=True, encoding=None): + """ + Runs user-provided functions from the supplied list of directories. + The directories can be either absolute, or relative to the directory + of the wscript file + + The methods :py:meth:`waflib.Context.Context.pre_recurse` and + :py:meth:`waflib.Context.Context.post_recurse` are called immediately before + and after a script has been executed. + + :param dirs: List of directories to visit + :type dirs: list of string or space-separated string + :param name: Name of function to invoke from the wscript + :type name: string + :param mandatory: whether sub wscript files are required to exist + :type mandatory: bool + :param once: read the script file once for a particular context + :type once: bool + """ + try: + cache = self.recurse_cache + except AttributeError: + cache = self.recurse_cache = {} + + for d in Utils.to_list(dirs): + + if not os.path.isabs(d): + # absolute paths only + d = os.path.join(self.path.abspath(), d) + + WSCRIPT = os.path.join(d, WSCRIPT_FILE) + WSCRIPT_FUN = WSCRIPT + '_' + (name or self.fun) + + node = self.root.find_node(WSCRIPT_FUN) + if node and (not once or node not in cache): + cache[node] = True + self.pre_recurse(node) + try: + function_code = node.read('r', encoding) + exec(compile(function_code, node.abspath(), 'exec'), self.exec_dict) + finally: + self.post_recurse(node) + elif not node: + node = self.root.find_node(WSCRIPT) + tup = (node, name or self.fun) + if node and (not once or tup not in cache): + cache[tup] = True + self.pre_recurse(node) + try: + wscript_module = load_module(node.abspath(), encoding=encoding) + user_function = getattr(wscript_module, (name or self.fun), None) + if not user_function: + if not mandatory: + continue + raise Errors.WafError('No function %r defined in %s' % (name or self.fun, node.abspath())) + user_function(self) + finally: + self.post_recurse(node) + elif not node: + if not mandatory: + continue + try: + os.listdir(d) + except OSError: + raise Errors.WafError('Cannot read the folder %r' % d) + raise Errors.WafError('No wscript file in directory %s' % d) + + def log_command(self, cmd, kw): + if Logs.verbose: + fmt = os.environ.get('WAF_CMD_FORMAT') + if fmt == 'string': + if not isinstance(cmd, str): + cmd = Utils.shell_escape(cmd) + Logs.debug('runner: %r', cmd) + Logs.debug('runner_env: kw=%s', kw) + + def exec_command(self, cmd, **kw): + """ + Runs an external process and returns the exit status:: + + def run(tsk): + ret = tsk.generator.bld.exec_command('touch foo.txt') + return ret + + If the context has the attribute 'log', then captures and logs the process stderr/stdout. + Unlike :py:meth:`waflib.Context.Context.cmd_and_log`, this method does not return the + stdout/stderr values captured. + + :param cmd: command argument for subprocess.Popen + :type cmd: string or list + :param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate. + :type kw: dict + :returns: process exit status + :rtype: integer + :raises: :py:class:`waflib.Errors.WafError` if an invalid executable is specified for a non-shell process + :raises: :py:class:`waflib.Errors.WafError` in case of execution failure + """ + subprocess = Utils.subprocess + kw['shell'] = isinstance(cmd, str) + self.log_command(cmd, kw) + + if self.logger: + self.logger.info(cmd) + + if 'stdout' not in kw: + kw['stdout'] = subprocess.PIPE + if 'stderr' not in kw: + kw['stderr'] = subprocess.PIPE + + if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]): + raise Errors.WafError('Program %s not found!' % cmd[0]) + + cargs = {} + if 'timeout' in kw: + if sys.hexversion >= 0x3030000: + cargs['timeout'] = kw['timeout'] + if not 'start_new_session' in kw: + kw['start_new_session'] = True + del kw['timeout'] + if 'input' in kw: + if kw['input']: + cargs['input'] = kw['input'] + kw['stdin'] = subprocess.PIPE + del kw['input'] + + if 'cwd' in kw: + if not isinstance(kw['cwd'], str): + kw['cwd'] = kw['cwd'].abspath() + + encoding = kw.pop('decode_as', default_encoding) + + try: + ret, out, err = Utils.run_process(cmd, kw, cargs) + except Exception as e: + raise Errors.WafError('Execution failure: %s' % str(e), ex=e) + + if out: + if not isinstance(out, str): + out = out.decode(encoding, errors='replace') + if self.logger: + self.logger.debug('out: %s', out) + else: + Logs.info(out, extra={'stream':sys.stdout, 'c1': ''}) + if err: + if not isinstance(err, str): + err = err.decode(encoding, errors='replace') + if self.logger: + self.logger.error('err: %s' % err) + else: + Logs.info(err, extra={'stream':sys.stderr, 'c1': ''}) + + return ret + + def cmd_and_log(self, cmd, **kw): + """ + Executes a process and returns stdout/stderr if the execution is successful. + An exception is thrown when the exit status is non-0. In that case, both stderr and stdout + will be bound to the WafError object (configuration tests):: + + def configure(conf): + out = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.STDOUT, quiet=waflib.Context.BOTH) + (out, err) = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.BOTH) + (out, err) = conf.cmd_and_log(cmd, input='\\n'.encode(), output=waflib.Context.STDOUT) + try: + conf.cmd_and_log(['which', 'someapp'], output=waflib.Context.BOTH) + except Errors.WafError as e: + print(e.stdout, e.stderr) + + :param cmd: args for subprocess.Popen + :type cmd: list or string + :param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate. + :type kw: dict + :returns: a tuple containing the contents of stdout and stderr + :rtype: string + :raises: :py:class:`waflib.Errors.WafError` if an invalid executable is specified for a non-shell process + :raises: :py:class:`waflib.Errors.WafError` in case of execution failure; stdout/stderr/returncode are bound to the exception object + """ + subprocess = Utils.subprocess + kw['shell'] = isinstance(cmd, str) + self.log_command(cmd, kw) + + quiet = kw.pop('quiet', None) + to_ret = kw.pop('output', STDOUT) + + if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]): + raise Errors.WafError('Program %r not found!' % cmd[0]) + + kw['stdout'] = kw['stderr'] = subprocess.PIPE + if quiet is None: + self.to_log(cmd) + + cargs = {} + if 'timeout' in kw: + if sys.hexversion >= 0x3030000: + cargs['timeout'] = kw['timeout'] + if not 'start_new_session' in kw: + kw['start_new_session'] = True + del kw['timeout'] + if 'input' in kw: + if kw['input']: + cargs['input'] = kw['input'] + kw['stdin'] = subprocess.PIPE + del kw['input'] + + if 'cwd' in kw: + if not isinstance(kw['cwd'], str): + kw['cwd'] = kw['cwd'].abspath() + + encoding = kw.pop('decode_as', default_encoding) + + try: + ret, out, err = Utils.run_process(cmd, kw, cargs) + except Exception as e: + raise Errors.WafError('Execution failure: %s' % str(e), ex=e) + + if not isinstance(out, str): + out = out.decode(encoding, errors='replace') + if not isinstance(err, str): + err = err.decode(encoding, errors='replace') + + if out and quiet != STDOUT and quiet != BOTH: + self.to_log('out: %s' % out) + if err and quiet != STDERR and quiet != BOTH: + self.to_log('err: %s' % err) + + if ret: + e = Errors.WafError('Command %r returned %r' % (cmd, ret)) + e.returncode = ret + e.stderr = err + e.stdout = out + raise e + + if to_ret == BOTH: + return (out, err) + elif to_ret == STDERR: + return err + return out + + def fatal(self, msg, ex=None): + """ + Prints an error message in red and stops command execution; this is + usually used in the configuration section:: + + def configure(conf): + conf.fatal('a requirement is missing') + + :param msg: message to display + :type msg: string + :param ex: optional exception object + :type ex: exception + :raises: :py:class:`waflib.Errors.ConfigurationError` + """ + if self.logger: + self.logger.info('from %s: %s' % (self.path.abspath(), msg)) + try: + logfile = self.logger.handlers[0].baseFilename + except AttributeError: + pass + else: + if os.environ.get('WAF_PRINT_FAILURE_LOG'): + # see #1930 + msg = 'Log from (%s):\n%s\n' % (logfile, Utils.readf(logfile)) + else: + msg = '%s\n(complete log in %s)' % (msg, logfile) + raise self.errors.ConfigurationError(msg, ex=ex) + + def to_log(self, msg): + """ + Logs information to the logger (if present), or to stderr. + Empty messages are not printed:: + + def build(bld): + bld.to_log('starting the build') + + Provide a logger on the context class or override this method if necessary. + + :param msg: message + :type msg: string + """ + if not msg: + return + if self.logger: + self.logger.info(msg) + else: + sys.stderr.write(str(msg)) + sys.stderr.flush() + + + def msg(self, *k, **kw): + """ + Prints a configuration message of the form ``msg: result``. + The second part of the message will be in colors. The output + can be disabled easly by setting ``in_msg`` to a positive value:: + + def configure(conf): + self.in_msg = 1 + conf.msg('Checking for library foo', 'ok') + # no output + + :param msg: message to display to the user + :type msg: string + :param result: result to display + :type result: string or boolean + :param color: color to use, see :py:const:`waflib.Logs.colors_lst` + :type color: string + """ + try: + msg = kw['msg'] + except KeyError: + msg = k[0] + + self.start_msg(msg, **kw) + + try: + result = kw['result'] + except KeyError: + result = k[1] + + color = kw.get('color') + if not isinstance(color, str): + color = result and 'GREEN' or 'YELLOW' + + self.end_msg(result, color, **kw) + + def start_msg(self, *k, **kw): + """ + Prints the beginning of a 'Checking for xxx' message. See :py:meth:`waflib.Context.Context.msg` + """ + if kw.get('quiet'): + return + + msg = kw.get('msg') or k[0] + try: + if self.in_msg: + self.in_msg += 1 + return + except AttributeError: + self.in_msg = 0 + self.in_msg += 1 + + try: + self.line_just = max(self.line_just, len(msg)) + except AttributeError: + self.line_just = max(40, len(msg)) + for x in (self.line_just * '-', msg): + self.to_log(x) + Logs.pprint('NORMAL', "%s :" % msg.ljust(self.line_just), sep='') + + def end_msg(self, *k, **kw): + """Prints the end of a 'Checking for' message. See :py:meth:`waflib.Context.Context.msg`""" + if kw.get('quiet'): + return + self.in_msg -= 1 + if self.in_msg: + return + + result = kw.get('result') or k[0] + + defcolor = 'GREEN' + if result is True: + msg = 'ok' + elif not result: + msg = 'not found' + defcolor = 'YELLOW' + else: + msg = str(result) + + self.to_log(msg) + try: + color = kw['color'] + except KeyError: + if len(k) > 1 and k[1] in Logs.colors_lst: + # compatibility waf 1.7 + color = k[1] + else: + color = defcolor + Logs.pprint(color, msg) + + def load_special_tools(self, var, ban=[]): + """ + Loads third-party extensions modules for certain programming languages + by trying to list certain files in the extras/ directory. This method + is typically called once for a programming language group, see for + example :py:mod:`waflib.Tools.compiler_c` + + :param var: glob expression, for example 'cxx\\_\\*.py' + :type var: string + :param ban: list of exact file names to exclude + :type ban: list of string + """ + if os.path.isdir(waf_dir): + lst = self.root.find_node(waf_dir).find_node('waflib/extras').ant_glob(var) + for x in lst: + if not x.name in ban: + load_tool(x.name.replace('.py', '')) + else: + from zipfile import PyZipFile + waflibs = PyZipFile(waf_dir) + lst = waflibs.namelist() + for x in lst: + if not re.match('waflib/extras/%s' % var.replace('*', '.*'), var): + continue + f = os.path.basename(x) + doban = False + for b in ban: + r = b.replace('*', '.*') + if re.match(r, f): + doban = True + if not doban: + f = f.replace('.py', '') + load_tool(f) + +cache_modules = {} +""" +Dictionary holding already loaded modules (wscript), indexed by their absolute path. +The modules are added automatically by :py:func:`waflib.Context.load_module` +""" + +def load_module(path, encoding=None): + """ + Loads a wscript file as a python module. This method caches results in :py:attr:`waflib.Context.cache_modules` + + :param path: file path + :type path: string + :return: Loaded Python module + :rtype: module + """ + try: + return cache_modules[path] + except KeyError: + pass + + module = imp.new_module(WSCRIPT_FILE) + try: + code = Utils.readf(path, m='r', encoding=encoding) + except EnvironmentError: + raise Errors.WafError('Could not read the file %r' % path) + + module_dir = os.path.dirname(path) + sys.path.insert(0, module_dir) + try: + exec(compile(code, path, 'exec'), module.__dict__) + finally: + sys.path.remove(module_dir) + + cache_modules[path] = module + return module + +def load_tool(tool, tooldir=None, ctx=None, with_sys_path=True): + """ + Imports a Waf tool as a python module, and stores it in the dict :py:const:`waflib.Context.Context.tools` + + :type tool: string + :param tool: Name of the tool + :type tooldir: list + :param tooldir: List of directories to search for the tool module + :type with_sys_path: boolean + :param with_sys_path: whether or not to search the regular sys.path, besides waf_dir and potentially given tooldirs + """ + if tool == 'java': + tool = 'javaw' # jython + else: + tool = tool.replace('++', 'xx') + + if not with_sys_path: + back_path = sys.path + sys.path = [] + try: + if tooldir: + assert isinstance(tooldir, list) + sys.path = tooldir + sys.path + try: + __import__(tool) + except ImportError as e: + e.waf_sys_path = list(sys.path) + raise + finally: + for d in tooldir: + sys.path.remove(d) + ret = sys.modules[tool] + Context.tools[tool] = ret + return ret + else: + if not with_sys_path: + sys.path.insert(0, waf_dir) + try: + for x in ('waflib.Tools.%s', 'waflib.extras.%s', 'waflib.%s', '%s'): + try: + __import__(x % tool) + break + except ImportError: + x = None + else: # raise an exception + __import__(tool) + except ImportError as e: + e.waf_sys_path = list(sys.path) + raise + finally: + if not with_sys_path: + sys.path.remove(waf_dir) + ret = sys.modules[x % tool] + Context.tools[tool] = ret + return ret + finally: + if not with_sys_path: + sys.path += back_path + diff --git a/ldb-2.0.8/third_party/waf/waflib/Errors.py b/ldb-2.0.8/third_party/waf/waflib/Errors.py new file mode 100644 index 0000000..bf75c1b --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Errors.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2010-2018 (ita) + +""" +Exceptions used in the Waf code +""" + +import traceback, sys + +class WafError(Exception): + """Base class for all Waf errors""" + def __init__(self, msg='', ex=None): + """ + :param msg: error message + :type msg: string + :param ex: exception causing this error (optional) + :type ex: exception + """ + Exception.__init__(self) + self.msg = msg + assert not isinstance(msg, Exception) + + self.stack = [] + if ex: + if not msg: + self.msg = str(ex) + if isinstance(ex, WafError): + self.stack = ex.stack + else: + self.stack = traceback.extract_tb(sys.exc_info()[2]) + self.stack += traceback.extract_stack()[:-1] + self.verbose_msg = ''.join(traceback.format_list(self.stack)) + + def __str__(self): + return str(self.msg) + +class BuildError(WafError): + """Error raised during the build and install phases""" + def __init__(self, error_tasks=[]): + """ + :param error_tasks: tasks that could not complete normally + :type error_tasks: list of task objects + """ + self.tasks = error_tasks + WafError.__init__(self, self.format_error()) + + def format_error(self): + """Formats the error messages from the tasks that failed""" + lst = ['Build failed'] + for tsk in self.tasks: + txt = tsk.format_error() + if txt: + lst.append(txt) + return '\n'.join(lst) + +class ConfigurationError(WafError): + """Configuration exception raised in particular by :py:meth:`waflib.Context.Context.fatal`""" + pass + +class TaskRescan(WafError): + """Task-specific exception type signalling required signature recalculations""" + pass + +class TaskNotReady(WafError): + """Task-specific exception type signalling that task signatures cannot be computed""" + pass + diff --git a/ldb-2.0.8/third_party/waf/waflib/Logs.py b/ldb-2.0.8/third_party/waf/waflib/Logs.py new file mode 100644 index 0000000..298411d --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Logs.py @@ -0,0 +1,382 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2005-2018 (ita) + +""" +logging, colors, terminal width and pretty-print +""" + +import os, re, traceback, sys +from waflib import Utils, ansiterm + +if not os.environ.get('NOSYNC', False): + # synchronized output is nearly mandatory to prevent garbled output + if sys.stdout.isatty() and id(sys.stdout) == id(sys.__stdout__): + sys.stdout = ansiterm.AnsiTerm(sys.stdout) + if sys.stderr.isatty() and id(sys.stderr) == id(sys.__stderr__): + sys.stderr = ansiterm.AnsiTerm(sys.stderr) + +# import the logging module after since it holds a reference on sys.stderr +# in case someone uses the root logger +import logging + +LOG_FORMAT = os.environ.get('WAF_LOG_FORMAT', '%(asctime)s %(c1)s%(zone)s%(c2)s %(message)s') +HOUR_FORMAT = os.environ.get('WAF_HOUR_FORMAT', '%H:%M:%S') + +zones = [] +""" +See :py:class:`waflib.Logs.log_filter` +""" + +verbose = 0 +""" +Global verbosity level, see :py:func:`waflib.Logs.debug` and :py:func:`waflib.Logs.error` +""" + +colors_lst = { +'USE' : True, +'BOLD' :'\x1b[01;1m', +'RED' :'\x1b[01;31m', +'GREEN' :'\x1b[32m', +'YELLOW':'\x1b[33m', +'PINK' :'\x1b[35m', +'BLUE' :'\x1b[01;34m', +'CYAN' :'\x1b[36m', +'GREY' :'\x1b[37m', +'NORMAL':'\x1b[0m', +'cursor_on' :'\x1b[?25h', +'cursor_off' :'\x1b[?25l', +} + +indicator = '\r\x1b[K%s%s%s' + +try: + unicode +except NameError: + unicode = None + +def enable_colors(use): + """ + If *1* is given, then the system will perform a few verifications + before enabling colors, such as checking whether the interpreter + is running in a terminal. A value of zero will disable colors, + and a value above *1* will force colors. + + :param use: whether to enable colors or not + :type use: integer + """ + if use == 1: + if not (sys.stderr.isatty() or sys.stdout.isatty()): + use = 0 + if Utils.is_win32 and os.name != 'java': + term = os.environ.get('TERM', '') # has ansiterm + else: + term = os.environ.get('TERM', 'dumb') + + if term in ('dumb', 'emacs'): + use = 0 + + if use >= 1: + os.environ['TERM'] = 'vt100' + + colors_lst['USE'] = use + +# If console packages are available, replace the dummy function with a real +# implementation +try: + get_term_cols = ansiterm.get_term_cols +except AttributeError: + def get_term_cols(): + return 80 + +get_term_cols.__doc__ = """ + Returns the console width in characters. + + :return: the number of characters per line + :rtype: int + """ + +def get_color(cl): + """ + Returns the ansi sequence corresponding to the given color name. + An empty string is returned when coloring is globally disabled. + + :param cl: color name in capital letters + :type cl: string + """ + if colors_lst['USE']: + return colors_lst.get(cl, '') + return '' + +class color_dict(object): + """attribute-based color access, eg: colors.PINK""" + def __getattr__(self, a): + return get_color(a) + def __call__(self, a): + return get_color(a) + +colors = color_dict() + +re_log = re.compile(r'(\w+): (.*)', re.M) +class log_filter(logging.Filter): + """ + Waf logs are of the form 'name: message', and can be filtered by 'waf --zones=name'. + For example, the following:: + + from waflib import Logs + Logs.debug('test: here is a message') + + Will be displayed only when executing:: + + $ waf --zones=test + """ + def __init__(self, name=''): + logging.Filter.__init__(self, name) + + def filter(self, rec): + """ + Filters log records by zone and by logging level + + :param rec: log entry + """ + rec.zone = rec.module + if rec.levelno >= logging.INFO: + return True + + m = re_log.match(rec.msg) + if m: + rec.zone = m.group(1) + rec.msg = m.group(2) + + if zones: + return getattr(rec, 'zone', '') in zones or '*' in zones + elif not verbose > 2: + return False + return True + +class log_handler(logging.StreamHandler): + """Dispatches messages to stderr/stdout depending on the severity level""" + def emit(self, record): + """ + Delegates the functionality to :py:meth:`waflib.Log.log_handler.emit_override` + """ + # default implementation + try: + try: + self.stream = record.stream + except AttributeError: + if record.levelno >= logging.WARNING: + record.stream = self.stream = sys.stderr + else: + record.stream = self.stream = sys.stdout + self.emit_override(record) + self.flush() + except (KeyboardInterrupt, SystemExit): + raise + except: # from the python library -_- + self.handleError(record) + + def emit_override(self, record, **kw): + """ + Writes the log record to the desired stream (stderr/stdout) + """ + self.terminator = getattr(record, 'terminator', '\n') + stream = self.stream + if unicode: + # python2 + msg = self.formatter.format(record) + fs = '%s' + self.terminator + try: + if (isinstance(msg, unicode) and getattr(stream, 'encoding', None)): + fs = fs.decode(stream.encoding) + try: + stream.write(fs % msg) + except UnicodeEncodeError: + stream.write((fs % msg).encode(stream.encoding)) + else: + stream.write(fs % msg) + except UnicodeError: + stream.write((fs % msg).encode('utf-8')) + else: + logging.StreamHandler.emit(self, record) + +class formatter(logging.Formatter): + """Simple log formatter which handles colors""" + def __init__(self): + logging.Formatter.__init__(self, LOG_FORMAT, HOUR_FORMAT) + + def format(self, rec): + """ + Formats records and adds colors as needed. The records do not get + a leading hour format if the logging level is above *INFO*. + """ + try: + msg = rec.msg.decode('utf-8') + except Exception: + msg = rec.msg + + use = colors_lst['USE'] + if (use == 1 and rec.stream.isatty()) or use == 2: + + c1 = getattr(rec, 'c1', None) + if c1 is None: + c1 = '' + if rec.levelno >= logging.ERROR: + c1 = colors.RED + elif rec.levelno >= logging.WARNING: + c1 = colors.YELLOW + elif rec.levelno >= logging.INFO: + c1 = colors.GREEN + c2 = getattr(rec, 'c2', colors.NORMAL) + msg = '%s%s%s' % (c1, msg, c2) + else: + # remove single \r that make long lines in text files + # and other terminal commands + msg = re.sub(r'\r(?!\n)|\x1B\[(K|.*?(m|h|l))', '', msg) + + if rec.levelno >= logging.INFO: + # the goal of this is to format without the leading "Logs, hour" prefix + if rec.args: + try: + return msg % rec.args + except UnicodeDecodeError: + return msg.encode('utf-8') % rec.args + return msg + + rec.msg = msg + rec.c1 = colors.PINK + rec.c2 = colors.NORMAL + return logging.Formatter.format(self, rec) + +log = None +"""global logger for Logs.debug, Logs.error, etc""" + +def debug(*k, **kw): + """ + Wraps logging.debug and discards messages if the verbosity level :py:attr:`waflib.Logs.verbose` ≤ 0 + """ + if verbose: + k = list(k) + k[0] = k[0].replace('\n', ' ') + log.debug(*k, **kw) + +def error(*k, **kw): + """ + Wrap logging.errors, adds the stack trace when the verbosity level :py:attr:`waflib.Logs.verbose` ≥ 2 + """ + log.error(*k, **kw) + if verbose > 2: + st = traceback.extract_stack() + if st: + st = st[:-1] + buf = [] + for filename, lineno, name, line in st: + buf.append(' File %r, line %d, in %s' % (filename, lineno, name)) + if line: + buf.append(' %s' % line.strip()) + if buf: + log.error('\n'.join(buf)) + +def warn(*k, **kw): + """ + Wraps logging.warning + """ + log.warning(*k, **kw) + +def info(*k, **kw): + """ + Wraps logging.info + """ + log.info(*k, **kw) + +def init_log(): + """ + Initializes the logger :py:attr:`waflib.Logs.log` + """ + global log + log = logging.getLogger('waflib') + log.handlers = [] + log.filters = [] + hdlr = log_handler() + hdlr.setFormatter(formatter()) + log.addHandler(hdlr) + log.addFilter(log_filter()) + log.setLevel(logging.DEBUG) + +def make_logger(path, name): + """ + Creates a simple logger, which is often used to redirect the context command output:: + + from waflib import Logs + bld.logger = Logs.make_logger('test.log', 'build') + bld.check(header_name='sadlib.h', features='cxx cprogram', mandatory=False) + + # have the file closed immediately + Logs.free_logger(bld.logger) + + # stop logging + bld.logger = None + + The method finalize() of the command will try to free the logger, if any + + :param path: file name to write the log output to + :type path: string + :param name: logger name (loggers are reused) + :type name: string + """ + logger = logging.getLogger(name) + if sys.hexversion > 0x3000000: + encoding = sys.stdout.encoding + else: + encoding = None + hdlr = logging.FileHandler(path, 'w', encoding=encoding) + formatter = logging.Formatter('%(message)s') + hdlr.setFormatter(formatter) + logger.addHandler(hdlr) + logger.setLevel(logging.DEBUG) + return logger + +def make_mem_logger(name, to_log, size=8192): + """ + Creates a memory logger to avoid writing concurrently to the main logger + """ + from logging.handlers import MemoryHandler + logger = logging.getLogger(name) + hdlr = MemoryHandler(size, target=to_log) + formatter = logging.Formatter('%(message)s') + hdlr.setFormatter(formatter) + logger.addHandler(hdlr) + logger.memhandler = hdlr + logger.setLevel(logging.DEBUG) + return logger + +def free_logger(logger): + """ + Frees the resources held by the loggers created through make_logger or make_mem_logger. + This is used for file cleanup and for handler removal (logger objects are re-used). + """ + try: + for x in logger.handlers: + x.close() + logger.removeHandler(x) + except Exception: + pass + +def pprint(col, msg, label='', sep='\n'): + """ + Prints messages in color immediately on stderr:: + + from waflib import Logs + Logs.pprint('RED', 'Something bad just happened') + + :param col: color name to use in :py:const:`Logs.colors_lst` + :type col: string + :param msg: message to display + :type msg: string or a value that can be printed by %s + :param label: a message to add after the colored output + :type label: string + :param sep: a string to append at the end (line separator) + :type sep: string + """ + info('%s%s%s %s', colors(col), msg, colors.NORMAL, label, extra={'terminator':sep}) + diff --git a/ldb-2.0.8/third_party/waf/waflib/Node.py b/ldb-2.0.8/third_party/waf/waflib/Node.py new file mode 100644 index 0000000..2ad1846 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Node.py @@ -0,0 +1,969 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2005-2018 (ita) + +""" +Node: filesystem structure + +#. Each file/folder is represented by exactly one node. + +#. Some potential class properties are stored on :py:class:`waflib.Build.BuildContext` : nodes to depend on, etc. + Unused class members can increase the `.wafpickle` file size sensibly. + +#. Node objects should never be created directly, use + the methods :py:func:`Node.make_node` or :py:func:`Node.find_node` for the low-level operations + +#. The methods :py:func:`Node.find_resource`, :py:func:`Node.find_dir` :py:func:`Node.find_or_declare` must be + used when a build context is present + +#. Each instance of :py:class:`waflib.Context.Context` has a unique :py:class:`Node` subclass required for serialization. + (:py:class:`waflib.Node.Nod3`, see the :py:class:`waflib.Context.Context` initializer). A reference to the context + owning a node is held as *self.ctx* +""" + +import os, re, sys, shutil +from waflib import Utils, Errors + +exclude_regs = ''' +**/*~ +**/#*# +**/.#* +**/%*% +**/._* +**/*.swp +**/CVS +**/CVS/** +**/.cvsignore +**/SCCS +**/SCCS/** +**/vssver.scc +**/.svn +**/.svn/** +**/BitKeeper +**/.git +**/.git/** +**/.gitignore +**/.bzr +**/.bzrignore +**/.bzr/** +**/.hg +**/.hg/** +**/_MTN +**/_MTN/** +**/.arch-ids +**/{arch} +**/_darcs +**/_darcs/** +**/.intlcache +**/.DS_Store''' +""" +Ant patterns for files and folders to exclude while doing the +recursive traversal in :py:meth:`waflib.Node.Node.ant_glob` +""" + +def ant_matcher(s, ignorecase): + reflags = re.I if ignorecase else 0 + ret = [] + for x in Utils.to_list(s): + x = x.replace('\\', '/').replace('//', '/') + if x.endswith('/'): + x += '**' + accu = [] + for k in x.split('/'): + if k == '**': + accu.append(k) + else: + k = k.replace('.', '[.]').replace('*', '.*').replace('?', '.').replace('+', '\\+') + k = '^%s$' % k + try: + exp = re.compile(k, flags=reflags) + except Exception as e: + raise Errors.WafError('Invalid pattern: %s' % k, e) + else: + accu.append(exp) + ret.append(accu) + return ret + +def ant_sub_filter(name, nn): + ret = [] + for lst in nn: + if not lst: + pass + elif lst[0] == '**': + ret.append(lst) + if len(lst) > 1: + if lst[1].match(name): + ret.append(lst[2:]) + else: + ret.append([]) + elif lst[0].match(name): + ret.append(lst[1:]) + return ret + +def ant_sub_matcher(name, pats): + nacc = ant_sub_filter(name, pats[0]) + nrej = ant_sub_filter(name, pats[1]) + if [] in nrej: + nacc = [] + return [nacc, nrej] + +class Node(object): + """ + This class is organized in two parts: + + * The basic methods meant for filesystem access (compute paths, create folders, etc) + * The methods bound to a :py:class:`waflib.Build.BuildContext` (require ``bld.srcnode`` and ``bld.bldnode``) + """ + + dict_class = dict + """ + Subclasses can provide a dict class to enable case insensitivity for example. + """ + + __slots__ = ('name', 'parent', 'children', 'cache_abspath', 'cache_isdir') + def __init__(self, name, parent): + """ + .. note:: Use :py:func:`Node.make_node` or :py:func:`Node.find_node` instead of calling this constructor + """ + self.name = name + self.parent = parent + if parent: + if name in parent.children: + raise Errors.WafError('node %s exists in the parent files %r already' % (name, parent)) + parent.children[name] = self + + def __setstate__(self, data): + "Deserializes node information, used for persistence" + self.name = data[0] + self.parent = data[1] + if data[2] is not None: + # Issue 1480 + self.children = self.dict_class(data[2]) + + def __getstate__(self): + "Serializes node information, used for persistence" + return (self.name, self.parent, getattr(self, 'children', None)) + + def __str__(self): + """ + String representation (abspath), for debugging purposes + + :rtype: string + """ + return self.abspath() + + def __repr__(self): + """ + String representation (abspath), for debugging purposes + + :rtype: string + """ + return self.abspath() + + def __copy__(self): + """ + Provided to prevent nodes from being copied + + :raises: :py:class:`waflib.Errors.WafError` + """ + raise Errors.WafError('nodes are not supposed to be copied') + + def read(self, flags='r', encoding='latin-1'): + """ + Reads and returns the contents of the file represented by this node, see :py:func:`waflib.Utils.readf`:: + + def build(bld): + bld.path.find_node('wscript').read() + + :param flags: Open mode + :type flags: string + :param encoding: encoding value for Python3 + :type encoding: string + :rtype: string or bytes + :return: File contents + """ + return Utils.readf(self.abspath(), flags, encoding) + + def write(self, data, flags='w', encoding='latin-1'): + """ + Writes data to the file represented by this node, see :py:func:`waflib.Utils.writef`:: + + def build(bld): + bld.path.make_node('foo.txt').write('Hello, world!') + + :param data: data to write + :type data: string + :param flags: Write mode + :type flags: string + :param encoding: encoding value for Python3 + :type encoding: string + """ + Utils.writef(self.abspath(), data, flags, encoding) + + def read_json(self, convert=True, encoding='utf-8'): + """ + Reads and parses the contents of this node as JSON (Python ≥ 2.6):: + + def build(bld): + bld.path.find_node('abc.json').read_json() + + Note that this by default automatically decodes unicode strings on Python2, unlike what the Python JSON module does. + + :type convert: boolean + :param convert: Prevents decoding of unicode strings on Python2 + :type encoding: string + :param encoding: The encoding of the file to read. This default to UTF8 as per the JSON standard + :rtype: object + :return: Parsed file contents + """ + import json # Python 2.6 and up + object_pairs_hook = None + if convert and sys.hexversion < 0x3000000: + try: + _type = unicode + except NameError: + _type = str + + def convert(value): + if isinstance(value, list): + return [convert(element) for element in value] + elif isinstance(value, _type): + return str(value) + else: + return value + + def object_pairs(pairs): + return dict((str(pair[0]), convert(pair[1])) for pair in pairs) + + object_pairs_hook = object_pairs + + return json.loads(self.read(encoding=encoding), object_pairs_hook=object_pairs_hook) + + def write_json(self, data, pretty=True): + """ + Writes a python object as JSON to disk (Python ≥ 2.6) as UTF-8 data (JSON standard):: + + def build(bld): + bld.path.find_node('xyz.json').write_json(199) + + :type data: object + :param data: The data to write to disk + :type pretty: boolean + :param pretty: Determines if the JSON will be nicely space separated + """ + import json # Python 2.6 and up + indent = 2 + separators = (',', ': ') + sort_keys = pretty + newline = os.linesep + if not pretty: + indent = None + separators = (',', ':') + newline = '' + output = json.dumps(data, indent=indent, separators=separators, sort_keys=sort_keys) + newline + self.write(output, encoding='utf-8') + + def exists(self): + """ + Returns whether the Node is present on the filesystem + + :rtype: bool + """ + return os.path.exists(self.abspath()) + + def isdir(self): + """ + Returns whether the Node represents a folder + + :rtype: bool + """ + return os.path.isdir(self.abspath()) + + def chmod(self, val): + """ + Changes the file/dir permissions:: + + def build(bld): + bld.path.chmod(493) # 0755 + """ + os.chmod(self.abspath(), val) + + def delete(self, evict=True): + """ + Removes the file/folder from the filesystem (equivalent to `rm -rf`), and remove this object from the Node tree. + Do not use this object after calling this method. + """ + try: + try: + if os.path.isdir(self.abspath()): + shutil.rmtree(self.abspath()) + else: + os.remove(self.abspath()) + except OSError: + if os.path.exists(self.abspath()): + raise + finally: + if evict: + self.evict() + + def evict(self): + """ + Removes this node from the Node tree + """ + del self.parent.children[self.name] + + def suffix(self): + """ + Returns the file rightmost extension, for example `a.b.c.d → .d` + + :rtype: string + """ + k = max(0, self.name.rfind('.')) + return self.name[k:] + + def height(self): + """ + Returns the depth in the folder hierarchy from the filesystem root or from all the file drives + + :returns: filesystem depth + :rtype: integer + """ + d = self + val = -1 + while d: + d = d.parent + val += 1 + return val + + def listdir(self): + """ + Lists the folder contents + + :returns: list of file/folder names ordered alphabetically + :rtype: list of string + """ + lst = Utils.listdir(self.abspath()) + lst.sort() + return lst + + def mkdir(self): + """ + Creates a folder represented by this node. Intermediate folders are created as needed. + + :raises: :py:class:`waflib.Errors.WafError` when the folder is missing + """ + if self.isdir(): + return + + try: + self.parent.mkdir() + except OSError: + pass + + if self.name: + try: + os.makedirs(self.abspath()) + except OSError: + pass + + if not self.isdir(): + raise Errors.WafError('Could not create the directory %r' % self) + + try: + self.children + except AttributeError: + self.children = self.dict_class() + + def find_node(self, lst): + """ + Finds a node on the file system (files or folders), and creates the corresponding Node objects if it exists + + :param lst: relative path + :type lst: string or list of string + :returns: The corresponding Node object or None if no entry was found on the filesystem + :rtype: :py:class:´waflib.Node.Node´ + """ + + if isinstance(lst, str): + lst = [x for x in Utils.split_path(lst) if x and x != '.'] + + if lst and lst[0].startswith('\\\\') and not self.parent: + node = self.ctx.root.make_node(lst[0]) + node.cache_isdir = True + return node.find_node(lst[1:]) + + cur = self + for x in lst: + if x == '..': + cur = cur.parent or cur + continue + + try: + ch = cur.children + except AttributeError: + cur.children = self.dict_class() + else: + try: + cur = ch[x] + continue + except KeyError: + pass + + # optimistic: create the node first then look if it was correct to do so + cur = self.__class__(x, cur) + if not cur.exists(): + cur.evict() + return None + + if not cur.exists(): + cur.evict() + return None + + return cur + + def make_node(self, lst): + """ + Returns or creates a Node object corresponding to the input path without considering the filesystem. + + :param lst: relative path + :type lst: string or list of string + :rtype: :py:class:´waflib.Node.Node´ + """ + if isinstance(lst, str): + lst = [x for x in Utils.split_path(lst) if x and x != '.'] + + cur = self + for x in lst: + if x == '..': + cur = cur.parent or cur + continue + + try: + cur = cur.children[x] + except AttributeError: + cur.children = self.dict_class() + except KeyError: + pass + else: + continue + cur = self.__class__(x, cur) + return cur + + def search_node(self, lst): + """ + Returns a Node previously defined in the data structure. The filesystem is not considered. + + :param lst: relative path + :type lst: string or list of string + :rtype: :py:class:´waflib.Node.Node´ or None if there is no entry in the Node datastructure + """ + if isinstance(lst, str): + lst = [x for x in Utils.split_path(lst) if x and x != '.'] + + cur = self + for x in lst: + if x == '..': + cur = cur.parent or cur + else: + try: + cur = cur.children[x] + except (AttributeError, KeyError): + return None + return cur + + def path_from(self, node): + """ + Path of this node seen from the other:: + + def build(bld): + n1 = bld.path.find_node('foo/bar/xyz.txt') + n2 = bld.path.find_node('foo/stuff/') + n1.path_from(n2) # '../bar/xyz.txt' + + :param node: path to use as a reference + :type node: :py:class:`waflib.Node.Node` + :returns: a relative path or an absolute one if that is better + :rtype: string + """ + c1 = self + c2 = node + + c1h = c1.height() + c2h = c2.height() + + lst = [] + up = 0 + + while c1h > c2h: + lst.append(c1.name) + c1 = c1.parent + c1h -= 1 + + while c2h > c1h: + up += 1 + c2 = c2.parent + c2h -= 1 + + while not c1 is c2: + lst.append(c1.name) + up += 1 + + c1 = c1.parent + c2 = c2.parent + + if c1.parent: + lst.extend(['..'] * up) + lst.reverse() + return os.sep.join(lst) or '.' + else: + return self.abspath() + + def abspath(self): + """ + Returns the absolute path. A cache is kept in the context as ``cache_node_abspath`` + + :rtype: string + """ + try: + return self.cache_abspath + except AttributeError: + pass + # think twice before touching this (performance + complexity + correctness) + + if not self.parent: + val = os.sep + elif not self.parent.name: + val = os.sep + self.name + else: + val = self.parent.abspath() + os.sep + self.name + self.cache_abspath = val + return val + + if Utils.is_win32: + def abspath(self): + try: + return self.cache_abspath + except AttributeError: + pass + if not self.parent: + val = '' + elif not self.parent.name: + val = self.name + os.sep + else: + val = self.parent.abspath().rstrip(os.sep) + os.sep + self.name + self.cache_abspath = val + return val + + def is_child_of(self, node): + """ + Returns whether the object belongs to a subtree of the input node:: + + def build(bld): + node = bld.path.find_node('wscript') + node.is_child_of(bld.path) # True + + :param node: path to use as a reference + :type node: :py:class:`waflib.Node.Node` + :rtype: bool + """ + p = self + diff = self.height() - node.height() + while diff > 0: + diff -= 1 + p = p.parent + return p is node + + def ant_iter(self, accept=None, maxdepth=25, pats=[], dir=False, src=True, remove=True, quiet=False): + """ + Recursive method used by :py:meth:`waflib.Node.ant_glob`. + + :param accept: function used for accepting/rejecting a node, returns the patterns that can be still accepted in recursion + :type accept: function + :param maxdepth: maximum depth in the filesystem (25) + :type maxdepth: int + :param pats: list of patterns to accept and list of patterns to exclude + :type pats: tuple + :param dir: return folders too (False by default) + :type dir: bool + :param src: return files (True by default) + :type src: bool + :param remove: remove files/folders that do not exist (True by default) + :type remove: bool + :param quiet: disable build directory traversal warnings (verbose mode) + :type quiet: bool + :returns: A generator object to iterate from + :rtype: iterator + """ + dircont = self.listdir() + + try: + lst = set(self.children.keys()) + except AttributeError: + self.children = self.dict_class() + else: + if remove: + for x in lst - set(dircont): + self.children[x].evict() + + for name in dircont: + npats = accept(name, pats) + if npats and npats[0]: + accepted = [] in npats[0] + + node = self.make_node([name]) + + isdir = node.isdir() + if accepted: + if isdir: + if dir: + yield node + elif src: + yield node + + if isdir: + node.cache_isdir = True + if maxdepth: + for k in node.ant_iter(accept=accept, maxdepth=maxdepth - 1, pats=npats, dir=dir, src=src, remove=remove, quiet=quiet): + yield k + + def ant_glob(self, *k, **kw): + """ + Finds files across folders and returns Node objects: + + * ``**/*`` find all files recursively + * ``**/*.class`` find all files ending by .class + * ``..`` find files having two dot characters + + For example:: + + def configure(cfg): + # find all .cpp files + cfg.path.ant_glob('**/*.cpp') + # find particular files from the root filesystem (can be slow) + cfg.root.ant_glob('etc/*.txt') + # simple exclusion rule example + cfg.path.ant_glob('*.c*', excl=['*.c'], src=True, dir=False) + + For more information about the patterns, consult http://ant.apache.org/manual/dirtasks.html + Please remember that the '..' sequence does not represent the parent directory:: + + def configure(cfg): + cfg.path.ant_glob('../*.h') # incorrect + cfg.path.parent.ant_glob('*.h') # correct + + The Node structure is itself a filesystem cache, so certain precautions must + be taken while matching files in the build or installation phases. + Nodes objects that do have a corresponding file or folder are garbage-collected by default. + This garbage collection is usually required to prevent returning files that do not + exist anymore. Yet, this may also remove Node objects of files that are yet-to-be built. + + This typically happens when trying to match files in the build directory, + but there are also cases when files are created in the source directory. + Run ``waf -v`` to display any warnings, and try consider passing ``remove=False`` + when matching files in the build directory. + + Since ant_glob can traverse both source and build folders, it is a best practice + to call this method only from the most specific build node:: + + def build(bld): + # traverses the build directory, may need ``remove=False``: + bld.path.ant_glob('project/dir/**/*.h') + # better, no accidental build directory traversal: + bld.path.find_node('project/dir').ant_glob('**/*.h') # best + + In addition, files and folders are listed immediately. When matching files in the + build folders, consider passing ``generator=True`` so that the generator object + returned can defer computation to a later stage. For example:: + + def build(bld): + bld(rule='tar xvf ${SRC}', source='arch.tar') + bld.add_group() + gen = bld.bldnode.ant_glob("*.h", generator=True, remove=True) + # files will be listed only after the arch.tar is unpacked + bld(rule='ls ${SRC}', source=gen, name='XYZ') + + + :param incl: ant patterns or list of patterns to include + :type incl: string or list of strings + :param excl: ant patterns or list of patterns to exclude + :type excl: string or list of strings + :param dir: return folders too (False by default) + :type dir: bool + :param src: return files (True by default) + :type src: bool + :param maxdepth: maximum depth of recursion + :type maxdepth: int + :param ignorecase: ignore case while matching (False by default) + :type ignorecase: bool + :param generator: Whether to evaluate the Nodes lazily + :type generator: bool + :param remove: remove files/folders that do not exist (True by default) + :type remove: bool + :param quiet: disable build directory traversal warnings (verbose mode) + :type quiet: bool + :returns: The corresponding Node objects as a list or as a generator object (generator=True) + :rtype: by default, list of :py:class:`waflib.Node.Node` instances + """ + src = kw.get('src', True) + dir = kw.get('dir') + excl = kw.get('excl', exclude_regs) + incl = k and k[0] or kw.get('incl', '**') + remove = kw.get('remove', True) + maxdepth = kw.get('maxdepth', 25) + ignorecase = kw.get('ignorecase', False) + quiet = kw.get('quiet', False) + pats = (ant_matcher(incl, ignorecase), ant_matcher(excl, ignorecase)) + + if kw.get('generator'): + return Utils.lazy_generator(self.ant_iter, (ant_sub_matcher, maxdepth, pats, dir, src, remove, quiet)) + + it = self.ant_iter(ant_sub_matcher, maxdepth, pats, dir, src, remove, quiet) + if kw.get('flat'): + # returns relative paths as a space-delimited string + # prefer Node objects whenever possible + return ' '.join(x.path_from(self) for x in it) + return list(it) + + # ---------------------------------------------------------------------------- + # the methods below require the source/build folders (bld.srcnode/bld.bldnode) + + def is_src(self): + """ + Returns True if the node is below the source directory. Note that ``!is_src() ≠ is_bld()`` + + :rtype: bool + """ + cur = self + x = self.ctx.srcnode + y = self.ctx.bldnode + while cur.parent: + if cur is y: + return False + if cur is x: + return True + cur = cur.parent + return False + + def is_bld(self): + """ + Returns True if the node is below the build directory. Note that ``!is_bld() ≠ is_src()`` + + :rtype: bool + """ + cur = self + y = self.ctx.bldnode + while cur.parent: + if cur is y: + return True + cur = cur.parent + return False + + def get_src(self): + """ + Returns the corresponding Node object in the source directory (or self if already + under the source directory). Use this method only if the purpose is to create + a Node object (this is common with folders but not with files, see ticket 1937) + + :rtype: :py:class:`waflib.Node.Node` + """ + cur = self + x = self.ctx.srcnode + y = self.ctx.bldnode + lst = [] + while cur.parent: + if cur is y: + lst.reverse() + return x.make_node(lst) + if cur is x: + return self + lst.append(cur.name) + cur = cur.parent + return self + + def get_bld(self): + """ + Return the corresponding Node object in the build directory (or self if already + under the build directory). Use this method only if the purpose is to create + a Node object (this is common with folders but not with files, see ticket 1937) + + :rtype: :py:class:`waflib.Node.Node` + """ + cur = self + x = self.ctx.srcnode + y = self.ctx.bldnode + lst = [] + while cur.parent: + if cur is y: + return self + if cur is x: + lst.reverse() + return self.ctx.bldnode.make_node(lst) + lst.append(cur.name) + cur = cur.parent + # the file is external to the current project, make a fake root in the current build directory + lst.reverse() + if lst and Utils.is_win32 and len(lst[0]) == 2 and lst[0].endswith(':'): + lst[0] = lst[0][0] + return self.ctx.bldnode.make_node(['__root__'] + lst) + + def find_resource(self, lst): + """ + Use this method in the build phase to find source files corresponding to the relative path given. + + First it looks up the Node data structure to find any declared Node object in the build directory. + If None is found, it then considers the filesystem in the source directory. + + :param lst: relative path + :type lst: string or list of string + :returns: the corresponding Node object or None + :rtype: :py:class:`waflib.Node.Node` + """ + if isinstance(lst, str): + lst = [x for x in Utils.split_path(lst) if x and x != '.'] + + node = self.get_bld().search_node(lst) + if not node: + node = self.get_src().find_node(lst) + if node and node.isdir(): + return None + return node + + def find_or_declare(self, lst): + """ + Use this method in the build phase to declare output files which + are meant to be written in the build directory. + + This method creates the Node object and its parent folder + as needed. + + :param lst: relative path + :type lst: string or list of string + """ + if isinstance(lst, str) and os.path.isabs(lst): + node = self.ctx.root.make_node(lst) + else: + node = self.get_bld().make_node(lst) + node.parent.mkdir() + return node + + def find_dir(self, lst): + """ + Searches for a folder on the filesystem (see :py:meth:`waflib.Node.Node.find_node`) + + :param lst: relative path + :type lst: string or list of string + :returns: The corresponding Node object or None if there is no such folder + :rtype: :py:class:`waflib.Node.Node` + """ + if isinstance(lst, str): + lst = [x for x in Utils.split_path(lst) if x and x != '.'] + + node = self.find_node(lst) + if node and not node.isdir(): + return None + return node + + # helpers for building things + def change_ext(self, ext, ext_in=None): + """ + Declares a build node with a distinct extension; this is uses :py:meth:`waflib.Node.Node.find_or_declare` + + :return: A build node of the same path, but with a different extension + :rtype: :py:class:`waflib.Node.Node` + """ + name = self.name + if ext_in is None: + k = name.rfind('.') + if k >= 0: + name = name[:k] + ext + else: + name = name + ext + else: + name = name[:- len(ext_in)] + ext + + return self.parent.find_or_declare([name]) + + def bldpath(self): + """ + Returns the relative path seen from the build directory ``src/foo.cpp`` + + :rtype: string + """ + return self.path_from(self.ctx.bldnode) + + def srcpath(self): + """ + Returns the relative path seen from the source directory ``../src/foo.cpp`` + + :rtype: string + """ + return self.path_from(self.ctx.srcnode) + + def relpath(self): + """ + If a file in the build directory, returns :py:meth:`waflib.Node.Node.bldpath`, + else returns :py:meth:`waflib.Node.Node.srcpath` + + :rtype: string + """ + cur = self + x = self.ctx.bldnode + while cur.parent: + if cur is x: + return self.bldpath() + cur = cur.parent + return self.srcpath() + + def bld_dir(self): + """ + Equivalent to self.parent.bldpath() + + :rtype: string + """ + return self.parent.bldpath() + + def h_file(self): + """ + See :py:func:`waflib.Utils.h_file` + + :return: a hash representing the file contents + :rtype: string or bytes + """ + return Utils.h_file(self.abspath()) + + def get_bld_sig(self): + """ + Returns a signature (see :py:meth:`waflib.Node.Node.h_file`) for the purpose + of build dependency calculation. This method uses a per-context cache. + + :return: a hash representing the object contents + :rtype: string or bytes + """ + # previous behaviour can be set by returning self.ctx.node_sigs[self] when a build node + try: + cache = self.ctx.cache_sig + except AttributeError: + cache = self.ctx.cache_sig = {} + try: + ret = cache[self] + except KeyError: + p = self.abspath() + try: + ret = cache[self] = self.h_file() + except EnvironmentError: + if self.isdir(): + # allow folders as build nodes, do not use the creation time + st = os.stat(p) + ret = cache[self] = Utils.h_list([p, st.st_ino, st.st_mode]) + return ret + raise + return ret + +pickle_lock = Utils.threading.Lock() +"""Lock mandatory for thread-safe node serialization""" + +class Nod3(Node): + """Mandatory subclass for thread-safe node serialization""" + pass # do not remove + + diff --git a/ldb-2.0.8/third_party/waf/waflib/Options.py b/ldb-2.0.8/third_party/waf/waflib/Options.py new file mode 100644 index 0000000..ad802d4 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Options.py @@ -0,0 +1,342 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Scott Newton, 2005 (scottn) +# Thomas Nagy, 2006-2018 (ita) + +""" +Support for waf command-line options + +Provides default and command-line options, as well the command +that reads the ``options`` wscript function. +""" + +import os, tempfile, optparse, sys, re +from waflib import Logs, Utils, Context, Errors + +options = optparse.Values() +""" +A global dictionary representing user-provided command-line options:: + + $ waf --foo=bar +""" + +commands = [] +""" +List of commands to execute extracted from the command-line. This list +is consumed during the execution by :py:func:`waflib.Scripting.run_commands`. +""" + +envvars = [] +""" +List of environment variable declarations placed after the Waf executable name. +These are detected by searching for "=" in the remaining arguments. +You probably do not want to use this. +""" + +lockfile = os.environ.get('WAFLOCK', '.lock-waf_%s_build' % sys.platform) +""" +Name of the lock file that marks a project as configured +""" + +class opt_parser(optparse.OptionParser): + """ + Command-line options parser. + """ + def __init__(self, ctx, allow_unknown=False): + optparse.OptionParser.__init__(self, conflict_handler='resolve', add_help_option=False, + version='waf %s (%s)' % (Context.WAFVERSION, Context.WAFREVISION)) + self.formatter.width = Logs.get_term_cols() + self.ctx = ctx + self.allow_unknown = allow_unknown + + def _process_args(self, largs, rargs, values): + """ + Custom _process_args to allow unknown options according to the allow_unknown status + """ + while rargs: + try: + optparse.OptionParser._process_args(self,largs,rargs,values) + except (optparse.BadOptionError, optparse.AmbiguousOptionError) as e: + if self.allow_unknown: + largs.append(e.opt_str) + else: + self.error(str(e)) + + def print_usage(self, file=None): + return self.print_help(file) + + def get_usage(self): + """ + Builds the message to print on ``waf --help`` + + :rtype: string + """ + cmds_str = {} + for cls in Context.classes: + if not cls.cmd or cls.cmd == 'options' or cls.cmd.startswith( '_' ): + continue + + s = cls.__doc__ or '' + cmds_str[cls.cmd] = s + + if Context.g_module: + for (k, v) in Context.g_module.__dict__.items(): + if k in ('options', 'init', 'shutdown'): + continue + + if type(v) is type(Context.create_context): + if v.__doc__ and not k.startswith('_'): + cmds_str[k] = v.__doc__ + + just = 0 + for k in cmds_str: + just = max(just, len(k)) + + lst = [' %s: %s' % (k.ljust(just), v) for (k, v) in cmds_str.items()] + lst.sort() + ret = '\n'.join(lst) + + return '''waf [commands] [options] + +Main commands (example: ./waf build -j4) +%s +''' % ret + + +class OptionsContext(Context.Context): + """ + Collects custom options from wscript files and parses the command line. + Sets the global :py:const:`waflib.Options.commands` and :py:const:`waflib.Options.options` values. + """ + cmd = 'options' + fun = 'options' + + def __init__(self, **kw): + super(OptionsContext, self).__init__(**kw) + + self.parser = opt_parser(self) + """Instance of :py:class:`waflib.Options.opt_parser`""" + + self.option_groups = {} + + jobs = self.jobs() + p = self.add_option + color = os.environ.get('NOCOLOR', '') and 'no' or 'auto' + if os.environ.get('CLICOLOR', '') == '0': + color = 'no' + elif os.environ.get('CLICOLOR_FORCE', '') == '1': + color = 'yes' + p('-c', '--color', dest='colors', default=color, action='store', help='whether to use colors (yes/no/auto) [default: auto]', choices=('yes', 'no', 'auto')) + p('-j', '--jobs', dest='jobs', default=jobs, type='int', help='amount of parallel jobs (%r)' % jobs) + p('-k', '--keep', dest='keep', default=0, action='count', help='continue despite errors (-kk to try harder)') + p('-v', '--verbose', dest='verbose', default=0, action='count', help='verbosity level -v -vv or -vvv [default: 0]') + p('--zones', dest='zones', default='', action='store', help='debugging zones (task_gen, deps, tasks, etc)') + p('--profile', dest='profile', default=0, action='store_true', help=optparse.SUPPRESS_HELP) + p('--pdb', dest='pdb', default=0, action='store_true', help=optparse.SUPPRESS_HELP) + p('-h', '--help', dest='whelp', default=0, action='store_true', help="show this help message and exit") + + gr = self.add_option_group('Configuration options') + self.option_groups['configure options'] = gr + + gr.add_option('-o', '--out', action='store', default='', help='build dir for the project', dest='out') + gr.add_option('-t', '--top', action='store', default='', help='src dir for the project', dest='top') + + gr.add_option('--no-lock-in-run', action='store_true', default='', help=optparse.SUPPRESS_HELP, dest='no_lock_in_run') + gr.add_option('--no-lock-in-out', action='store_true', default='', help=optparse.SUPPRESS_HELP, dest='no_lock_in_out') + gr.add_option('--no-lock-in-top', action='store_true', default='', help=optparse.SUPPRESS_HELP, dest='no_lock_in_top') + + default_prefix = getattr(Context.g_module, 'default_prefix', os.environ.get('PREFIX')) + if not default_prefix: + if Utils.unversioned_sys_platform() == 'win32': + d = tempfile.gettempdir() + default_prefix = d[0].upper() + d[1:] + # win32 preserves the case, but gettempdir does not + else: + default_prefix = '/usr/local/' + gr.add_option('--prefix', dest='prefix', default=default_prefix, help='installation prefix [default: %r]' % default_prefix) + gr.add_option('--bindir', dest='bindir', help='bindir') + gr.add_option('--libdir', dest='libdir', help='libdir') + + gr = self.add_option_group('Build and installation options') + self.option_groups['build and install options'] = gr + gr.add_option('-p', '--progress', dest='progress_bar', default=0, action='count', help= '-p: progress bar; -pp: ide output') + gr.add_option('--targets', dest='targets', default='', action='store', help='task generators, e.g. "target1,target2"') + + gr = self.add_option_group('Step options') + self.option_groups['step options'] = gr + gr.add_option('--files', dest='files', default='', action='store', help='files to process, by regexp, e.g. "*/main.c,*/test/main.o"') + + default_destdir = os.environ.get('DESTDIR', '') + + gr = self.add_option_group('Installation and uninstallation options') + self.option_groups['install/uninstall options'] = gr + gr.add_option('--destdir', help='installation root [default: %r]' % default_destdir, default=default_destdir, dest='destdir') + gr.add_option('-f', '--force', dest='force', default=False, action='store_true', help='force file installation') + gr.add_option('--distcheck-args', metavar='ARGS', help='arguments to pass to distcheck', default=None, action='store') + + def jobs(self): + """ + Finds the optimal amount of cpu cores to use for parallel jobs. + At runtime the options can be obtained from :py:const:`waflib.Options.options` :: + + from waflib.Options import options + njobs = options.jobs + + :return: the amount of cpu cores + :rtype: int + """ + count = int(os.environ.get('JOBS', 0)) + if count < 1: + if 'NUMBER_OF_PROCESSORS' in os.environ: + # on Windows, use the NUMBER_OF_PROCESSORS environment variable + count = int(os.environ.get('NUMBER_OF_PROCESSORS', 1)) + else: + # on everything else, first try the POSIX sysconf values + if hasattr(os, 'sysconf_names'): + if 'SC_NPROCESSORS_ONLN' in os.sysconf_names: + count = int(os.sysconf('SC_NPROCESSORS_ONLN')) + elif 'SC_NPROCESSORS_CONF' in os.sysconf_names: + count = int(os.sysconf('SC_NPROCESSORS_CONF')) + if not count and os.name not in ('nt', 'java'): + try: + tmp = self.cmd_and_log(['sysctl', '-n', 'hw.ncpu'], quiet=0) + except Errors.WafError: + pass + else: + if re.match('^[0-9]+$', tmp): + count = int(tmp) + if count < 1: + count = 1 + elif count > 1024: + count = 1024 + return count + + def add_option(self, *k, **kw): + """ + Wraps ``optparse.add_option``:: + + def options(ctx): + ctx.add_option('-u', '--use', dest='use', default=False, + action='store_true', help='a boolean option') + + :rtype: optparse option object + """ + return self.parser.add_option(*k, **kw) + + def add_option_group(self, *k, **kw): + """ + Wraps ``optparse.add_option_group``:: + + def options(ctx): + gr = ctx.add_option_group('some options') + gr.add_option('-u', '--use', dest='use', default=False, action='store_true') + + :rtype: optparse option group object + """ + try: + gr = self.option_groups[k[0]] + except KeyError: + gr = self.parser.add_option_group(*k, **kw) + self.option_groups[k[0]] = gr + return gr + + def get_option_group(self, opt_str): + """ + Wraps ``optparse.get_option_group``:: + + def options(ctx): + gr = ctx.get_option_group('configure options') + gr.add_option('-o', '--out', action='store', default='', + help='build dir for the project', dest='out') + + :rtype: optparse option group object + """ + try: + return self.option_groups[opt_str] + except KeyError: + for group in self.parser.option_groups: + if group.title == opt_str: + return group + return None + + def sanitize_path(self, path, cwd=None): + if not cwd: + cwd = Context.launch_dir + p = os.path.expanduser(path) + p = os.path.join(cwd, p) + p = os.path.normpath(p) + p = os.path.abspath(p) + return p + + def parse_cmd_args(self, _args=None, cwd=None, allow_unknown=False): + """ + Just parse the arguments + """ + self.parser.allow_unknown = allow_unknown + (options, leftover_args) = self.parser.parse_args(args=_args) + envvars = [] + commands = [] + for arg in leftover_args: + if '=' in arg: + envvars.append(arg) + elif arg != 'options': + commands.append(arg) + + for name in 'top out destdir prefix bindir libdir'.split(): + # those paths are usually expanded from Context.launch_dir + if getattr(options, name, None): + path = self.sanitize_path(getattr(options, name), cwd) + setattr(options, name, path) + return options, commands, envvars + + def init_module_vars(self, arg_options, arg_commands, arg_envvars): + options.__dict__.clear() + del commands[:] + del envvars[:] + + options.__dict__.update(arg_options.__dict__) + commands.extend(arg_commands) + envvars.extend(arg_envvars) + + for var in envvars: + (name, value) = var.split('=', 1) + os.environ[name.strip()] = value + + def init_logs(self, options, commands, envvars): + Logs.verbose = options.verbose + if options.verbose >= 1: + self.load('errcheck') + + colors = {'yes' : 2, 'auto' : 1, 'no' : 0}[options.colors] + Logs.enable_colors(colors) + + if options.zones: + Logs.zones = options.zones.split(',') + if not Logs.verbose: + Logs.verbose = 1 + elif Logs.verbose > 0: + Logs.zones = ['runner'] + if Logs.verbose > 2: + Logs.zones = ['*'] + + def parse_args(self, _args=None): + """ + Parses arguments from a list which is not necessarily the command-line. + Initializes the module variables options, commands and envvars + If help is requested, prints it and exit the application + + :param _args: arguments + :type _args: list of strings + """ + options, commands, envvars = self.parse_cmd_args() + self.init_logs(options, commands, envvars) + self.init_module_vars(options, commands, envvars) + + def execute(self): + """ + See :py:func:`waflib.Context.Context.execute` + """ + super(OptionsContext, self).execute() + self.parse_args() + Utils.alloc_process_pool(options.jobs) + diff --git a/ldb-2.0.8/third_party/waf/waflib/Runner.py b/ldb-2.0.8/third_party/waf/waflib/Runner.py new file mode 100644 index 0000000..91d5547 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Runner.py @@ -0,0 +1,622 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2005-2018 (ita) + +""" +Runner.py: Task scheduling and execution +""" + +import heapq, traceback +try: + from queue import Queue, PriorityQueue +except ImportError: + from Queue import Queue + try: + from Queue import PriorityQueue + except ImportError: + class PriorityQueue(Queue): + def _init(self, maxsize): + self.maxsize = maxsize + self.queue = [] + def _put(self, item): + heapq.heappush(self.queue, item) + def _get(self): + return heapq.heappop(self.queue) + +from waflib import Utils, Task, Errors, Logs + +GAP = 5 +""" +Wait for at least ``GAP * njobs`` before trying to enqueue more tasks to run +""" + +class PriorityTasks(object): + def __init__(self): + self.lst = [] + def __len__(self): + return len(self.lst) + def __iter__(self): + return iter(self.lst) + def __str__(self): + return 'PriorityTasks: [%s]' % '\n '.join(str(x) for x in self.lst) + def clear(self): + self.lst = [] + def append(self, task): + heapq.heappush(self.lst, task) + def appendleft(self, task): + "Deprecated, do not use" + heapq.heappush(self.lst, task) + def pop(self): + return heapq.heappop(self.lst) + def extend(self, lst): + if self.lst: + for x in lst: + self.append(x) + else: + if isinstance(lst, list): + self.lst = lst + heapq.heapify(lst) + else: + self.lst = lst.lst + +class Consumer(Utils.threading.Thread): + """ + Daemon thread object that executes a task. It shares a semaphore with + the coordinator :py:class:`waflib.Runner.Spawner`. There is one + instance per task to consume. + """ + def __init__(self, spawner, task): + Utils.threading.Thread.__init__(self) + self.task = task + """Task to execute""" + self.spawner = spawner + """Coordinator object""" + self.setDaemon(1) + self.start() + def run(self): + """ + Processes a single task + """ + try: + if not self.spawner.master.stop: + self.spawner.master.process_task(self.task) + finally: + self.spawner.sem.release() + self.spawner.master.out.put(self.task) + self.task = None + self.spawner = None + +class Spawner(Utils.threading.Thread): + """ + Daemon thread that consumes tasks from :py:class:`waflib.Runner.Parallel` producer and + spawns a consuming thread :py:class:`waflib.Runner.Consumer` for each + :py:class:`waflib.Task.Task` instance. + """ + def __init__(self, master): + Utils.threading.Thread.__init__(self) + self.master = master + """:py:class:`waflib.Runner.Parallel` producer instance""" + self.sem = Utils.threading.Semaphore(master.numjobs) + """Bounded semaphore that prevents spawning more than *n* concurrent consumers""" + self.setDaemon(1) + self.start() + def run(self): + """ + Spawns new consumers to execute tasks by delegating to :py:meth:`waflib.Runner.Spawner.loop` + """ + try: + self.loop() + except Exception: + # Python 2 prints unnecessary messages when shutting down + # we also want to stop the thread properly + pass + def loop(self): + """ + Consumes task objects from the producer; ends when the producer has no more + task to provide. + """ + master = self.master + while 1: + task = master.ready.get() + self.sem.acquire() + if not master.stop: + task.log_display(task.generator.bld) + Consumer(self, task) + +class Parallel(object): + """ + Schedule the tasks obtained from the build context for execution. + """ + def __init__(self, bld, j=2): + """ + The initialization requires a build context reference + for computing the total number of jobs. + """ + + self.numjobs = j + """ + Amount of parallel consumers to use + """ + + self.bld = bld + """ + Instance of :py:class:`waflib.Build.BuildContext` + """ + + self.outstanding = PriorityTasks() + """Heap of :py:class:`waflib.Task.Task` that may be ready to be executed""" + + self.postponed = PriorityTasks() + """Heap of :py:class:`waflib.Task.Task` which are not ready to run for non-DAG reasons""" + + self.incomplete = set() + """List of :py:class:`waflib.Task.Task` waiting for dependent tasks to complete (DAG)""" + + self.ready = PriorityQueue(0) + """List of :py:class:`waflib.Task.Task` ready to be executed by consumers""" + + self.out = Queue(0) + """List of :py:class:`waflib.Task.Task` returned by the task consumers""" + + self.count = 0 + """Amount of tasks that may be processed by :py:class:`waflib.Runner.TaskConsumer`""" + + self.processed = 0 + """Amount of tasks processed""" + + self.stop = False + """Error flag to stop the build""" + + self.error = [] + """Tasks that could not be executed""" + + self.biter = None + """Task iterator which must give groups of parallelizable tasks when calling ``next()``""" + + self.dirty = False + """ + Flag that indicates that the build cache must be saved when a task was executed + (calls :py:meth:`waflib.Build.BuildContext.store`)""" + + self.revdeps = Utils.defaultdict(set) + """ + The reverse dependency graph of dependencies obtained from Task.run_after + """ + + self.spawner = None + """ + Coordinating daemon thread that spawns thread consumers + """ + if self.numjobs > 1: + self.spawner = Spawner(self) + + def get_next_task(self): + """ + Obtains the next Task instance to run + + :rtype: :py:class:`waflib.Task.Task` + """ + if not self.outstanding: + return None + return self.outstanding.pop() + + def postpone(self, tsk): + """ + Adds the task to the list :py:attr:`waflib.Runner.Parallel.postponed`. + The order is scrambled so as to consume as many tasks in parallel as possible. + + :param tsk: task instance + :type tsk: :py:class:`waflib.Task.Task` + """ + self.postponed.append(tsk) + + def refill_task_list(self): + """ + Pulls a next group of tasks to execute in :py:attr:`waflib.Runner.Parallel.outstanding`. + Ensures that all tasks in the current build group are complete before processing the next one. + """ + while self.count > self.numjobs * GAP: + self.get_out() + + while not self.outstanding: + if self.count: + self.get_out() + if self.outstanding: + break + elif self.postponed: + try: + cond = self.deadlock == self.processed + except AttributeError: + pass + else: + if cond: + # The most common reason is conflicting build order declaration + # for example: "X run_after Y" and "Y run_after X" + # Another can be changing "run_after" dependencies while the build is running + # for example: updating "tsk.run_after" in the "runnable_status" method + lst = [] + for tsk in self.postponed: + deps = [id(x) for x in tsk.run_after if not x.hasrun] + lst.append('%s\t-> %r' % (repr(tsk), deps)) + if not deps: + lst.append('\n task %r dependencies are done, check its *runnable_status*?' % id(tsk)) + raise Errors.WafError('Deadlock detected: check the task build order%s' % ''.join(lst)) + self.deadlock = self.processed + + if self.postponed: + self.outstanding.extend(self.postponed) + self.postponed.clear() + elif not self.count: + if self.incomplete: + for x in self.incomplete: + for k in x.run_after: + if not k.hasrun: + break + else: + # dependency added after the build started without updating revdeps + self.incomplete.remove(x) + self.outstanding.append(x) + break + else: + if self.stop or self.error: + break + raise Errors.WafError('Broken revdeps detected on %r' % self.incomplete) + else: + tasks = next(self.biter) + ready, waiting = self.prio_and_split(tasks) + self.outstanding.extend(ready) + self.incomplete.update(waiting) + self.total = self.bld.total() + break + + def add_more_tasks(self, tsk): + """ + If a task provides :py:attr:`waflib.Task.Task.more_tasks`, then the tasks contained + in that list are added to the current build and will be processed before the next build group. + + The priorities for dependent tasks are not re-calculated globally + + :param tsk: task instance + :type tsk: :py:attr:`waflib.Task.Task` + """ + if getattr(tsk, 'more_tasks', None): + more = set(tsk.more_tasks) + groups_done = set() + def iteri(a, b): + for x in a: + yield x + for x in b: + yield x + + # Update the dependency tree + # this assumes that task.run_after values were updated + for x in iteri(self.outstanding, self.incomplete): + for k in x.run_after: + if isinstance(k, Task.TaskGroup): + if k not in groups_done: + groups_done.add(k) + for j in k.prev & more: + self.revdeps[j].add(k) + elif k in more: + self.revdeps[k].add(x) + + ready, waiting = self.prio_and_split(tsk.more_tasks) + self.outstanding.extend(ready) + self.incomplete.update(waiting) + self.total += len(tsk.more_tasks) + + def mark_finished(self, tsk): + def try_unfreeze(x): + # DAG ancestors are likely to be in the incomplete set + # This assumes that the run_after contents have not changed + # after the build starts, else a deadlock may occur + if x in self.incomplete: + # TODO remove dependencies to free some memory? + # x.run_after.remove(tsk) + for k in x.run_after: + if not k.hasrun: + break + else: + self.incomplete.remove(x) + self.outstanding.append(x) + + if tsk in self.revdeps: + for x in self.revdeps[tsk]: + if isinstance(x, Task.TaskGroup): + x.prev.remove(tsk) + if not x.prev: + for k in x.next: + # TODO necessary optimization? + k.run_after.remove(x) + try_unfreeze(k) + # TODO necessary optimization? + x.next = [] + else: + try_unfreeze(x) + del self.revdeps[tsk] + + if hasattr(tsk, 'semaphore'): + sem = tsk.semaphore + try: + sem.release(tsk) + except KeyError: + # TODO + pass + else: + while sem.waiting and not sem.is_locked(): + # take a frozen task, make it ready to run + x = sem.waiting.pop() + self._add_task(x) + + def get_out(self): + """ + Waits for a Task that task consumers add to :py:attr:`waflib.Runner.Parallel.out` after execution. + Adds more Tasks if necessary through :py:attr:`waflib.Runner.Parallel.add_more_tasks`. + + :rtype: :py:attr:`waflib.Task.Task` + """ + tsk = self.out.get() + if not self.stop: + self.add_more_tasks(tsk) + self.mark_finished(tsk) + + self.count -= 1 + self.dirty = True + return tsk + + def add_task(self, tsk): + """ + Enqueue a Task to :py:attr:`waflib.Runner.Parallel.ready` so that consumers can run them. + + :param tsk: task instance + :type tsk: :py:attr:`waflib.Task.Task` + """ + # TODO change in waf 2.1 + self.ready.put(tsk) + + def _add_task(self, tsk): + if hasattr(tsk, 'semaphore'): + sem = tsk.semaphore + try: + sem.acquire(tsk) + except IndexError: + sem.waiting.add(tsk) + return + + self.count += 1 + self.processed += 1 + if self.numjobs == 1: + tsk.log_display(tsk.generator.bld) + try: + self.process_task(tsk) + finally: + self.out.put(tsk) + else: + self.add_task(tsk) + + def process_task(self, tsk): + """ + Processes a task and attempts to stop the build in case of errors + """ + tsk.process() + if tsk.hasrun != Task.SUCCESS: + self.error_handler(tsk) + + def skip(self, tsk): + """ + Mark a task as skipped/up-to-date + """ + tsk.hasrun = Task.SKIPPED + self.mark_finished(tsk) + + def cancel(self, tsk): + """ + Mark a task as failed because of unsatisfiable dependencies + """ + tsk.hasrun = Task.CANCELED + self.mark_finished(tsk) + + def error_handler(self, tsk): + """ + Called when a task cannot be executed. The flag :py:attr:`waflib.Runner.Parallel.stop` is set, + unless the build is executed with:: + + $ waf build -k + + :param tsk: task instance + :type tsk: :py:attr:`waflib.Task.Task` + """ + if not self.bld.keep: + self.stop = True + self.error.append(tsk) + + def task_status(self, tsk): + """ + Obtains the task status to decide whether to run it immediately or not. + + :return: the exit status, for example :py:attr:`waflib.Task.ASK_LATER` + :rtype: integer + """ + try: + return tsk.runnable_status() + except Exception: + self.processed += 1 + tsk.err_msg = traceback.format_exc() + if not self.stop and self.bld.keep: + self.skip(tsk) + if self.bld.keep == 1: + # if -k stop on the first exception, if -kk try to go as far as possible + if Logs.verbose > 1 or not self.error: + self.error.append(tsk) + self.stop = True + else: + if Logs.verbose > 1: + self.error.append(tsk) + return Task.EXCEPTION + + tsk.hasrun = Task.EXCEPTION + self.error_handler(tsk) + + return Task.EXCEPTION + + def start(self): + """ + Obtains Task instances from the BuildContext instance and adds the ones that need to be executed to + :py:class:`waflib.Runner.Parallel.ready` so that the :py:class:`waflib.Runner.Spawner` consumer thread + has them executed. Obtains the executed Tasks back from :py:class:`waflib.Runner.Parallel.out` + and marks the build as failed by setting the ``stop`` flag. + If only one job is used, then executes the tasks one by one, without consumers. + """ + self.total = self.bld.total() + + while not self.stop: + + self.refill_task_list() + + # consider the next task + tsk = self.get_next_task() + if not tsk: + if self.count: + # tasks may add new ones after they are run + continue + else: + # no tasks to run, no tasks running, time to exit + break + + if tsk.hasrun: + # if the task is marked as "run", just skip it + self.processed += 1 + continue + + if self.stop: # stop immediately after a failure is detected + break + + st = self.task_status(tsk) + if st == Task.RUN_ME: + self._add_task(tsk) + elif st == Task.ASK_LATER: + self.postpone(tsk) + elif st == Task.SKIP_ME: + self.processed += 1 + self.skip(tsk) + self.add_more_tasks(tsk) + elif st == Task.CANCEL_ME: + # A dependency problem has occurred, and the + # build is most likely run with `waf -k` + if Logs.verbose > 1: + self.error.append(tsk) + self.processed += 1 + self.cancel(tsk) + + # self.count represents the tasks that have been made available to the consumer threads + # collect all the tasks after an error else the message may be incomplete + while self.error and self.count: + self.get_out() + + self.ready.put(None) + if not self.stop: + assert not self.count + assert not self.postponed + assert not self.incomplete + + def prio_and_split(self, tasks): + """ + Label input tasks with priority values, and return a pair containing + the tasks that are ready to run and the tasks that are necessarily + waiting for other tasks to complete. + + The priority system is really meant as an optional layer for optimization: + dependency cycles are found quickly, and builds should be more efficient. + A high priority number means that a task is processed first. + + This method can be overridden to disable the priority system:: + + def prio_and_split(self, tasks): + return tasks, [] + + :return: A pair of task lists + :rtype: tuple + """ + # to disable: + #return tasks, [] + for x in tasks: + x.visited = 0 + + reverse = self.revdeps + + groups_done = set() + for x in tasks: + for k in x.run_after: + if isinstance(k, Task.TaskGroup): + if k not in groups_done: + groups_done.add(k) + for j in k.prev: + reverse[j].add(k) + else: + reverse[k].add(x) + + # the priority number is not the tree depth + def visit(n): + if isinstance(n, Task.TaskGroup): + return sum(visit(k) for k in n.next) + + if n.visited == 0: + n.visited = 1 + + if n in reverse: + rev = reverse[n] + n.prio_order = n.tree_weight + len(rev) + sum(visit(k) for k in rev) + else: + n.prio_order = n.tree_weight + + n.visited = 2 + elif n.visited == 1: + raise Errors.WafError('Dependency cycle found!') + return n.prio_order + + for x in tasks: + if x.visited != 0: + # must visit all to detect cycles + continue + try: + visit(x) + except Errors.WafError: + self.debug_cycles(tasks, reverse) + + ready = [] + waiting = [] + for x in tasks: + for k in x.run_after: + if not k.hasrun: + waiting.append(x) + break + else: + ready.append(x) + return (ready, waiting) + + def debug_cycles(self, tasks, reverse): + tmp = {} + for x in tasks: + tmp[x] = 0 + + def visit(n, acc): + if isinstance(n, Task.TaskGroup): + for k in n.next: + visit(k, acc) + return + if tmp[n] == 0: + tmp[n] = 1 + for k in reverse.get(n, []): + visit(k, [n] + acc) + tmp[n] = 2 + elif tmp[n] == 1: + lst = [] + for tsk in acc: + lst.append(repr(tsk)) + if tsk is n: + # exclude prior nodes, we want the minimum cycle + break + raise Errors.WafError('Task dependency cycle in "run_after" constraints: %s' % ''.join(lst)) + for x in tasks: + visit(x, []) + diff --git a/ldb-2.0.8/third_party/waf/waflib/Scripting.py b/ldb-2.0.8/third_party/waf/waflib/Scripting.py new file mode 100644 index 0000000..68dccf2 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Scripting.py @@ -0,0 +1,625 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2005-2018 (ita) + +"Module called for configuring, compiling and installing targets" + +from __future__ import with_statement + +import os, shlex, shutil, traceback, errno, sys, stat +from waflib import Utils, Configure, Logs, Options, ConfigSet, Context, Errors, Build, Node + +build_dir_override = None + +no_climb_commands = ['configure'] + +default_cmd = "build" + +def waf_entry_point(current_directory, version, wafdir): + """ + This is the main entry point, all Waf execution starts here. + + :param current_directory: absolute path representing the current directory + :type current_directory: string + :param version: version number + :type version: string + :param wafdir: absolute path representing the directory of the waf library + :type wafdir: string + """ + Logs.init_log() + + if Context.WAFVERSION != version: + Logs.error('Waf script %r and library %r do not match (directory %r)', version, Context.WAFVERSION, wafdir) + sys.exit(1) + + # Store current directory before any chdir + Context.waf_dir = wafdir + Context.run_dir = Context.launch_dir = current_directory + start_dir = current_directory + no_climb = os.environ.get('NOCLIMB') + + if len(sys.argv) > 1: + # os.path.join handles absolute paths + # if sys.argv[1] is not an absolute path, then it is relative to the current working directory + potential_wscript = os.path.join(current_directory, sys.argv[1]) + if os.path.basename(potential_wscript) == Context.WSCRIPT_FILE and os.path.isfile(potential_wscript): + # need to explicitly normalize the path, as it may contain extra '/.' + path = os.path.normpath(os.path.dirname(potential_wscript)) + start_dir = os.path.abspath(path) + no_climb = True + sys.argv.pop(1) + + ctx = Context.create_context('options') + (options, commands, env) = ctx.parse_cmd_args(allow_unknown=True) + if options.top: + start_dir = Context.run_dir = Context.top_dir = options.top + no_climb = True + if options.out: + Context.out_dir = options.out + + # if 'configure' is in the commands, do not search any further + if not no_climb: + for k in no_climb_commands: + for y in commands: + if y.startswith(k): + no_climb = True + break + + # try to find a lock file (if the project was configured) + # at the same time, store the first wscript file seen + cur = start_dir + while cur: + try: + lst = os.listdir(cur) + except OSError: + lst = [] + Logs.error('Directory %r is unreadable!', cur) + if Options.lockfile in lst: + env = ConfigSet.ConfigSet() + try: + env.load(os.path.join(cur, Options.lockfile)) + ino = os.stat(cur)[stat.ST_INO] + except EnvironmentError: + pass + else: + # check if the folder was not moved + for x in (env.run_dir, env.top_dir, env.out_dir): + if not x: + continue + if Utils.is_win32: + if cur == x: + load = True + break + else: + # if the filesystem features symlinks, compare the inode numbers + try: + ino2 = os.stat(x)[stat.ST_INO] + except OSError: + pass + else: + if ino == ino2: + load = True + break + else: + Logs.warn('invalid lock file in %s', cur) + load = False + + if load: + Context.run_dir = env.run_dir + Context.top_dir = env.top_dir + Context.out_dir = env.out_dir + break + + if not Context.run_dir: + if Context.WSCRIPT_FILE in lst: + Context.run_dir = cur + + next = os.path.dirname(cur) + if next == cur: + break + cur = next + + if no_climb: + break + + wscript = os.path.normpath(os.path.join(Context.run_dir, Context.WSCRIPT_FILE)) + if not os.path.exists(wscript): + if options.whelp: + Logs.warn('These are the generic options (no wscript/project found)') + ctx.parser.print_help() + sys.exit(0) + Logs.error('Waf: Run from a folder containing a %r file (or try -h for the generic options)', Context.WSCRIPT_FILE) + sys.exit(1) + + try: + os.chdir(Context.run_dir) + except OSError: + Logs.error('Waf: The folder %r is unreadable', Context.run_dir) + sys.exit(1) + + try: + set_main_module(wscript) + except Errors.WafError as e: + Logs.pprint('RED', e.verbose_msg) + Logs.error(str(e)) + sys.exit(1) + except Exception as e: + Logs.error('Waf: The wscript in %r is unreadable', Context.run_dir) + traceback.print_exc(file=sys.stdout) + sys.exit(2) + + if options.profile: + import cProfile, pstats + cProfile.runctx('from waflib import Scripting; Scripting.run_commands()', {}, {}, 'profi.txt') + p = pstats.Stats('profi.txt') + p.sort_stats('time').print_stats(75) # or 'cumulative' + else: + try: + try: + run_commands() + except: + if options.pdb: + import pdb + type, value, tb = sys.exc_info() + traceback.print_exc() + pdb.post_mortem(tb) + else: + raise + except Errors.WafError as e: + if Logs.verbose > 1: + Logs.pprint('RED', e.verbose_msg) + Logs.error(e.msg) + sys.exit(1) + except SystemExit: + raise + except Exception as e: + traceback.print_exc(file=sys.stdout) + sys.exit(2) + except KeyboardInterrupt: + Logs.pprint('RED', 'Interrupted') + sys.exit(68) + +def set_main_module(file_path): + """ + Read the main wscript file into :py:const:`waflib.Context.Context.g_module` and + bind default functions such as ``init``, ``dist``, ``distclean`` if not defined. + Called by :py:func:`waflib.Scripting.waf_entry_point` during the initialization. + + :param file_path: absolute path representing the top-level wscript file + :type file_path: string + """ + Context.g_module = Context.load_module(file_path) + Context.g_module.root_path = file_path + + # note: to register the module globally, use the following: + # sys.modules['wscript_main'] = g_module + + def set_def(obj): + name = obj.__name__ + if not name in Context.g_module.__dict__: + setattr(Context.g_module, name, obj) + for k in (dist, distclean, distcheck): + set_def(k) + # add dummy init and shutdown functions if they're not defined + if not 'init' in Context.g_module.__dict__: + Context.g_module.init = Utils.nada + if not 'shutdown' in Context.g_module.__dict__: + Context.g_module.shutdown = Utils.nada + if not 'options' in Context.g_module.__dict__: + Context.g_module.options = Utils.nada + +def parse_options(): + """ + Parses the command-line options and initialize the logging system. + Called by :py:func:`waflib.Scripting.waf_entry_point` during the initialization. + """ + ctx = Context.create_context('options') + ctx.execute() + if not Options.commands: + if isinstance(default_cmd, list): + Options.commands.extend(default_cmd) + else: + Options.commands.append(default_cmd) + if Options.options.whelp: + ctx.parser.print_help() + sys.exit(0) + +def run_command(cmd_name): + """ + Executes a single Waf command. Called by :py:func:`waflib.Scripting.run_commands`. + + :param cmd_name: command to execute, like ``build`` + :type cmd_name: string + """ + ctx = Context.create_context(cmd_name) + ctx.log_timer = Utils.Timer() + ctx.options = Options.options # provided for convenience + ctx.cmd = cmd_name + try: + ctx.execute() + finally: + # Issue 1374 + ctx.finalize() + return ctx + +def run_commands(): + """ + Execute the Waf commands that were given on the command-line, and the other options + Called by :py:func:`waflib.Scripting.waf_entry_point` during the initialization, and executed + after :py:func:`waflib.Scripting.parse_options`. + """ + parse_options() + run_command('init') + while Options.commands: + cmd_name = Options.commands.pop(0) + ctx = run_command(cmd_name) + Logs.info('%r finished successfully (%s)', cmd_name, ctx.log_timer) + run_command('shutdown') + +########################################################################################### + +def distclean_dir(dirname): + """ + Distclean function called in the particular case when:: + + top == out + + :param dirname: absolute path of the folder to clean + :type dirname: string + """ + for (root, dirs, files) in os.walk(dirname): + for f in files: + if f.endswith(('.o', '.moc', '.exe')): + fname = os.path.join(root, f) + try: + os.remove(fname) + except OSError: + Logs.warn('Could not remove %r', fname) + + for x in (Context.DBFILE, 'config.log'): + try: + os.remove(x) + except OSError: + pass + + try: + shutil.rmtree(Build.CACHE_DIR) + except OSError: + pass + +def distclean(ctx): + '''removes build folders and data''' + + def remove_and_log(k, fun): + try: + fun(k) + except EnvironmentError as e: + if e.errno != errno.ENOENT: + Logs.warn('Could not remove %r', k) + + # remove waf cache folders on the top-level + if not Options.commands: + for k in os.listdir('.'): + for x in '.waf-2 waf-2 .waf3-2 waf3-2'.split(): + if k.startswith(x): + remove_and_log(k, shutil.rmtree) + + # remove a build folder, if any + cur = '.' + if ctx.options.no_lock_in_top: + cur = ctx.options.out + + try: + lst = os.listdir(cur) + except OSError: + Logs.warn('Could not read %r', cur) + return + + if Options.lockfile in lst: + f = os.path.join(cur, Options.lockfile) + try: + env = ConfigSet.ConfigSet(f) + except EnvironmentError: + Logs.warn('Could not read %r', f) + return + + if not env.out_dir or not env.top_dir: + Logs.warn('Invalid lock file %r', f) + return + + if env.out_dir == env.top_dir: + distclean_dir(env.out_dir) + else: + remove_and_log(env.out_dir, shutil.rmtree) + + env_dirs = [env.out_dir] + if not ctx.options.no_lock_in_top: + env_dirs.append(env.top_dir) + if not ctx.options.no_lock_in_run: + env_dirs.append(env.run_dir) + for k in env_dirs: + p = os.path.join(k, Options.lockfile) + remove_and_log(p, os.remove) + +class Dist(Context.Context): + '''creates an archive containing the project source code''' + cmd = 'dist' + fun = 'dist' + algo = 'tar.bz2' + ext_algo = {} + + def execute(self): + """ + See :py:func:`waflib.Context.Context.execute` + """ + self.recurse([os.path.dirname(Context.g_module.root_path)]) + self.archive() + + def archive(self): + """ + Creates the source archive. + """ + import tarfile + + arch_name = self.get_arch_name() + + try: + self.base_path + except AttributeError: + self.base_path = self.path + + node = self.base_path.make_node(arch_name) + try: + node.delete() + except OSError: + pass + + files = self.get_files() + + if self.algo.startswith('tar.'): + tar = tarfile.open(node.abspath(), 'w:' + self.algo.replace('tar.', '')) + + for x in files: + self.add_tar_file(x, tar) + tar.close() + elif self.algo == 'zip': + import zipfile + zip = zipfile.ZipFile(node.abspath(), 'w', compression=zipfile.ZIP_DEFLATED) + + for x in files: + archive_name = self.get_base_name() + '/' + x.path_from(self.base_path) + zip.write(x.abspath(), archive_name, zipfile.ZIP_DEFLATED) + zip.close() + else: + self.fatal('Valid algo types are tar.bz2, tar.gz, tar.xz or zip') + + try: + from hashlib import sha256 + except ImportError: + digest = '' + else: + digest = ' (sha256=%r)' % sha256(node.read(flags='rb')).hexdigest() + + Logs.info('New archive created: %s%s', self.arch_name, digest) + + def get_tar_path(self, node): + """ + Return the path to use for a node in the tar archive, the purpose of this + is to let subclases resolve symbolic links or to change file names + + :return: absolute path + :rtype: string + """ + return node.abspath() + + def add_tar_file(self, x, tar): + """ + Adds a file to the tar archive. Symlinks are not verified. + + :param x: file path + :param tar: tar file object + """ + p = self.get_tar_path(x) + tinfo = tar.gettarinfo(name=p, arcname=self.get_tar_prefix() + '/' + x.path_from(self.base_path)) + tinfo.uid = 0 + tinfo.gid = 0 + tinfo.uname = 'root' + tinfo.gname = 'root' + + if os.path.isfile(p): + with open(p, 'rb') as f: + tar.addfile(tinfo, fileobj=f) + else: + tar.addfile(tinfo) + + def get_tar_prefix(self): + """ + Returns the base path for files added into the archive tar file + + :rtype: string + """ + try: + return self.tar_prefix + except AttributeError: + return self.get_base_name() + + def get_arch_name(self): + """ + Returns the archive file name. + Set the attribute *arch_name* to change the default value:: + + def dist(ctx): + ctx.arch_name = 'ctx.tar.bz2' + + :rtype: string + """ + try: + self.arch_name + except AttributeError: + self.arch_name = self.get_base_name() + '.' + self.ext_algo.get(self.algo, self.algo) + return self.arch_name + + def get_base_name(self): + """ + Returns the default name of the main directory in the archive, which is set to *appname-version*. + Set the attribute *base_name* to change the default value:: + + def dist(ctx): + ctx.base_name = 'files' + + :rtype: string + """ + try: + self.base_name + except AttributeError: + appname = getattr(Context.g_module, Context.APPNAME, 'noname') + version = getattr(Context.g_module, Context.VERSION, '1.0') + self.base_name = appname + '-' + version + return self.base_name + + def get_excl(self): + """ + Returns the patterns to exclude for finding the files in the top-level directory. + Set the attribute *excl* to change the default value:: + + def dist(ctx): + ctx.excl = 'build **/*.o **/*.class' + + :rtype: string + """ + try: + return self.excl + except AttributeError: + self.excl = Node.exclude_regs + ' **/waf-2.* **/.waf-2.* **/waf3-2.* **/.waf3-2.* **/*~ **/*.rej **/*.orig **/*.pyc **/*.pyo **/*.bak **/*.swp **/.lock-w*' + if Context.out_dir: + nd = self.root.find_node(Context.out_dir) + if nd: + self.excl += ' ' + nd.path_from(self.base_path) + return self.excl + + def get_files(self): + """ + Files to package are searched automatically by :py:func:`waflib.Node.Node.ant_glob`. + Set *files* to prevent this behaviour:: + + def dist(ctx): + ctx.files = ctx.path.find_node('wscript') + + Files are also searched from the directory 'base_path', to change it, set:: + + def dist(ctx): + ctx.base_path = path + + :rtype: list of :py:class:`waflib.Node.Node` + """ + try: + files = self.files + except AttributeError: + files = self.base_path.ant_glob('**/*', excl=self.get_excl()) + return files + +def dist(ctx): + '''makes a tarball for redistributing the sources''' + pass + +class DistCheck(Dist): + """creates an archive with dist, then tries to build it""" + fun = 'distcheck' + cmd = 'distcheck' + + def execute(self): + """ + See :py:func:`waflib.Context.Context.execute` + """ + self.recurse([os.path.dirname(Context.g_module.root_path)]) + self.archive() + self.check() + + def make_distcheck_cmd(self, tmpdir): + cfg = [] + if Options.options.distcheck_args: + cfg = shlex.split(Options.options.distcheck_args) + else: + cfg = [x for x in sys.argv if x.startswith('-')] + cmd = [sys.executable, sys.argv[0], 'configure', 'build', 'install', 'uninstall', '--destdir=' + tmpdir] + cfg + return cmd + + def check(self): + """ + Creates the archive, uncompresses it and tries to build the project + """ + import tempfile, tarfile + + with tarfile.open(self.get_arch_name()) as t: + for x in t: + t.extract(x) + + instdir = tempfile.mkdtemp('.inst', self.get_base_name()) + cmd = self.make_distcheck_cmd(instdir) + ret = Utils.subprocess.Popen(cmd, cwd=self.get_base_name()).wait() + if ret: + raise Errors.WafError('distcheck failed with code %r' % ret) + + if os.path.exists(instdir): + raise Errors.WafError('distcheck succeeded, but files were left in %s' % instdir) + + shutil.rmtree(self.get_base_name()) + + +def distcheck(ctx): + '''checks if the project compiles (tarball from 'dist')''' + pass + +def autoconfigure(execute_method): + """ + Decorator that enables context commands to run *configure* as needed. + """ + def execute(self): + """ + Wraps :py:func:`waflib.Context.Context.execute` on the context class + """ + if not Configure.autoconfig: + return execute_method(self) + + env = ConfigSet.ConfigSet() + do_config = False + try: + env.load(os.path.join(Context.top_dir, Options.lockfile)) + except EnvironmentError: + Logs.warn('Configuring the project') + do_config = True + else: + if env.run_dir != Context.run_dir: + do_config = True + else: + h = 0 + for f in env.files: + try: + h = Utils.h_list((h, Utils.readf(f, 'rb'))) + except EnvironmentError: + do_config = True + break + else: + do_config = h != env.hash + + if do_config: + cmd = env.config_cmd or 'configure' + if Configure.autoconfig == 'clobber': + tmp = Options.options.__dict__ + launch_dir_tmp = Context.launch_dir + if env.options: + Options.options.__dict__ = env.options + Context.launch_dir = env.launch_dir + try: + run_command(cmd) + finally: + Options.options.__dict__ = tmp + Context.launch_dir = launch_dir_tmp + else: + run_command(cmd) + run_command(self.cmd) + else: + return execute_method(self) + return execute +Build.BuildContext.execute = autoconfigure(Build.BuildContext.execute) + diff --git a/ldb-2.0.8/third_party/waf/waflib/Task.py b/ldb-2.0.8/third_party/waf/waflib/Task.py new file mode 100644 index 0000000..cb49a73 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Task.py @@ -0,0 +1,1406 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2005-2018 (ita) + +""" +Tasks represent atomic operations such as processes. +""" + +import os, re, sys, tempfile, traceback +from waflib import Utils, Logs, Errors + +# task states +NOT_RUN = 0 +"""The task was not executed yet""" + +MISSING = 1 +"""The task has been executed but the files have not been created""" + +CRASHED = 2 +"""The task execution returned a non-zero exit status""" + +EXCEPTION = 3 +"""An exception occurred in the task execution""" + +CANCELED = 4 +"""A dependency for the task is missing so it was cancelled""" + +SKIPPED = 8 +"""The task did not have to be executed""" + +SUCCESS = 9 +"""The task was successfully executed""" + +ASK_LATER = -1 +"""The task is not ready to be executed""" + +SKIP_ME = -2 +"""The task does not need to be executed""" + +RUN_ME = -3 +"""The task must be executed""" + +CANCEL_ME = -4 +"""The task cannot be executed because of a dependency problem""" + +COMPILE_TEMPLATE_SHELL = ''' +def f(tsk): + env = tsk.env + gen = tsk.generator + bld = gen.bld + cwdx = tsk.get_cwd() + p = env.get_flat + def to_list(xx): + if isinstance(xx, str): return [xx] + return xx + tsk.last_cmd = cmd = \'\'\' %s \'\'\' % s + return tsk.exec_command(cmd, cwd=cwdx, env=env.env or None) +''' + +COMPILE_TEMPLATE_NOSHELL = ''' +def f(tsk): + env = tsk.env + gen = tsk.generator + bld = gen.bld + cwdx = tsk.get_cwd() + def to_list(xx): + if isinstance(xx, str): return [xx] + return xx + def merge(lst1, lst2): + if lst1 and lst2: + return lst1[:-1] + [lst1[-1] + lst2[0]] + lst2[1:] + return lst1 + lst2 + lst = [] + %s + if '' in lst: + lst = [x for x in lst if x] + tsk.last_cmd = lst + return tsk.exec_command(lst, cwd=cwdx, env=env.env or None) +''' + +COMPILE_TEMPLATE_SIG_VARS = ''' +def f(tsk): + sig = tsk.generator.bld.hash_env_vars(tsk.env, tsk.vars) + tsk.m.update(sig) + env = tsk.env + gen = tsk.generator + bld = gen.bld + cwdx = tsk.get_cwd() + p = env.get_flat + buf = [] + %s + tsk.m.update(repr(buf).encode()) +''' + +classes = {} +""" +The metaclass :py:class:`waflib.Task.store_task_type` stores all class tasks +created by user scripts or Waf tools to this dict. It maps class names to class objects. +""" + +class store_task_type(type): + """ + Metaclass: store the task classes into the dict pointed by the + class attribute 'register' which defaults to :py:const:`waflib.Task.classes`, + + The attribute 'run_str' is compiled into a method 'run' bound to the task class. + """ + def __init__(cls, name, bases, dict): + super(store_task_type, cls).__init__(name, bases, dict) + name = cls.__name__ + + if name != 'evil' and name != 'Task': + if getattr(cls, 'run_str', None): + # if a string is provided, convert it to a method + (f, dvars) = compile_fun(cls.run_str, cls.shell) + cls.hcode = Utils.h_cmd(cls.run_str) + cls.orig_run_str = cls.run_str + # change the name of run_str or it is impossible to subclass with a function + cls.run_str = None + cls.run = f + # process variables + cls.vars = list(set(cls.vars + dvars)) + cls.vars.sort() + if cls.vars: + fun = compile_sig_vars(cls.vars) + if fun: + cls.sig_vars = fun + elif getattr(cls, 'run', None) and not 'hcode' in cls.__dict__: + # getattr(cls, 'hcode') would look in the upper classes + cls.hcode = Utils.h_cmd(cls.run) + + # be creative + getattr(cls, 'register', classes)[name] = cls + +evil = store_task_type('evil', (object,), {}) +"Base class provided to avoid writing a metaclass, so the code can run in python 2.6 and 3.x unmodified" + +class Task(evil): + """ + Task objects represents actions to perform such as commands to execute by calling the `run` method. + + Detecting when to execute a task occurs in the method :py:meth:`waflib.Task.Task.runnable_status`. + + Detecting which tasks to execute is performed through a hash value returned by + :py:meth:`waflib.Task.Task.signature`. The task signature is persistent from build to build. + """ + vars = [] + """ConfigSet variables that should trigger a rebuild (class attribute used for :py:meth:`waflib.Task.Task.sig_vars`)""" + + always_run = False + """Specify whether task instances must always be executed or not (class attribute)""" + + shell = False + """Execute the command with the shell (class attribute)""" + + color = 'GREEN' + """Color for the console display, see :py:const:`waflib.Logs.colors_lst`""" + + ext_in = [] + """File extensions that objects of this task class may use""" + + ext_out = [] + """File extensions that objects of this task class may create""" + + before = [] + """The instances of this class are executed before the instances of classes whose names are in this list""" + + after = [] + """The instances of this class are executed after the instances of classes whose names are in this list""" + + hcode = Utils.SIG_NIL + """String representing an additional hash for the class representation""" + + keep_last_cmd = False + """Whether to keep the last command executed on the instance after execution. + This may be useful for certain extensions but it can a lot of memory. + """ + + weight = 0 + """Optional weight to tune the priority for task instances. + The higher, the earlier. The weight only applies to single task objects.""" + + tree_weight = 0 + """Optional weight to tune the priority of task instances and whole subtrees. + The higher, the earlier.""" + + prio_order = 0 + """Priority order set by the scheduler on instances during the build phase. + You most likely do not need to set it. + """ + + __slots__ = ('hasrun', 'generator', 'env', 'inputs', 'outputs', 'dep_nodes', 'run_after') + + def __init__(self, *k, **kw): + self.hasrun = NOT_RUN + try: + self.generator = kw['generator'] + except KeyError: + self.generator = self + + self.env = kw['env'] + """:py:class:`waflib.ConfigSet.ConfigSet` object (make sure to provide one)""" + + self.inputs = [] + """List of input nodes, which represent the files used by the task instance""" + + self.outputs = [] + """List of output nodes, which represent the files created by the task instance""" + + self.dep_nodes = [] + """List of additional nodes to depend on""" + + self.run_after = set() + """Set of tasks that must be executed before this one""" + + def __lt__(self, other): + return self.priority() > other.priority() + def __le__(self, other): + return self.priority() >= other.priority() + def __gt__(self, other): + return self.priority() < other.priority() + def __ge__(self, other): + return self.priority() <= other.priority() + + def get_cwd(self): + """ + :return: current working directory + :rtype: :py:class:`waflib.Node.Node` + """ + bld = self.generator.bld + ret = getattr(self, 'cwd', None) or getattr(bld, 'cwd', bld.bldnode) + if isinstance(ret, str): + if os.path.isabs(ret): + ret = bld.root.make_node(ret) + else: + ret = self.generator.path.make_node(ret) + return ret + + def quote_flag(self, x): + """ + Surround a process argument by quotes so that a list of arguments can be written to a file + + :param x: flag + :type x: string + :return: quoted flag + :rtype: string + """ + old = x + if '\\' in x: + x = x.replace('\\', '\\\\') + if '"' in x: + x = x.replace('"', '\\"') + if old != x or ' ' in x or '\t' in x or "'" in x: + x = '"%s"' % x + return x + + def priority(self): + """ + Priority of execution; the higher, the earlier + + :return: the priority value + :rtype: a tuple of numeric values + """ + return (self.weight + self.prio_order, - getattr(self.generator, 'tg_idx_count', 0)) + + def split_argfile(self, cmd): + """ + Splits a list of process commands into the executable part and its list of arguments + + :return: a tuple containing the executable first and then the rest of arguments + :rtype: tuple + """ + return ([cmd[0]], [self.quote_flag(x) for x in cmd[1:]]) + + def exec_command(self, cmd, **kw): + """ + Wrapper for :py:meth:`waflib.Context.Context.exec_command`. + This version set the current working directory (``build.variant_dir``), + applies PATH settings (if self.env.PATH is provided), and can run long + commands through a temporary ``@argfile``. + + :param cmd: process command to execute + :type cmd: list of string (best) or string (process will use a shell) + :return: the return code + :rtype: int + + Optional parameters: + + #. cwd: current working directory (Node or string) + #. stdout: set to None to prevent waf from capturing the process standard output + #. stderr: set to None to prevent waf from capturing the process standard error + #. timeout: timeout value (Python 3) + """ + if not 'cwd' in kw: + kw['cwd'] = self.get_cwd() + + if hasattr(self, 'timeout'): + kw['timeout'] = self.timeout + + if self.env.PATH: + env = kw['env'] = dict(kw.get('env') or self.env.env or os.environ) + env['PATH'] = self.env.PATH if isinstance(self.env.PATH, str) else os.pathsep.join(self.env.PATH) + + if hasattr(self, 'stdout'): + kw['stdout'] = self.stdout + if hasattr(self, 'stderr'): + kw['stderr'] = self.stderr + + if not isinstance(cmd, str): + if Utils.is_win32: + # win32 compares the resulting length http://support.microsoft.com/kb/830473 + too_long = sum([len(arg) for arg in cmd]) + len(cmd) > 8192 + else: + # non-win32 counts the amount of arguments (200k) + too_long = len(cmd) > 200000 + + if too_long and getattr(self, 'allow_argsfile', True): + # Shunt arguments to a temporary file if the command is too long. + cmd, args = self.split_argfile(cmd) + try: + (fd, tmp) = tempfile.mkstemp() + os.write(fd, '\r\n'.join(args).encode()) + os.close(fd) + if Logs.verbose: + Logs.debug('argfile: @%r -> %r', tmp, args) + return self.generator.bld.exec_command(cmd + ['@' + tmp], **kw) + finally: + try: + os.remove(tmp) + except OSError: + # anti-virus and indexers can keep files open -_- + pass + return self.generator.bld.exec_command(cmd, **kw) + + def process(self): + """ + Runs the task and handles errors + + :return: 0 or None if everything is fine + :rtype: integer + """ + # remove the task signature immediately before it is executed + # so that the task will be executed again in case of failure + try: + del self.generator.bld.task_sigs[self.uid()] + except KeyError: + pass + + try: + ret = self.run() + except Exception: + self.err_msg = traceback.format_exc() + self.hasrun = EXCEPTION + else: + if ret: + self.err_code = ret + self.hasrun = CRASHED + else: + try: + self.post_run() + except Errors.WafError: + pass + except Exception: + self.err_msg = traceback.format_exc() + self.hasrun = EXCEPTION + else: + self.hasrun = SUCCESS + + if self.hasrun != SUCCESS and self.scan: + # rescan dependencies on next run + try: + del self.generator.bld.imp_sigs[self.uid()] + except KeyError: + pass + + def log_display(self, bld): + "Writes the execution status on the context logger" + if self.generator.bld.progress_bar == 3: + return + + s = self.display() + if s: + if bld.logger: + logger = bld.logger + else: + logger = Logs + + if self.generator.bld.progress_bar == 1: + c1 = Logs.colors.cursor_off + c2 = Logs.colors.cursor_on + logger.info(s, extra={'stream': sys.stderr, 'terminator':'', 'c1': c1, 'c2' : c2}) + else: + logger.info(s, extra={'terminator':'', 'c1': '', 'c2' : ''}) + + def display(self): + """ + Returns an execution status for the console, the progress bar, or the IDE output. + + :rtype: string + """ + col1 = Logs.colors(self.color) + col2 = Logs.colors.NORMAL + master = self.generator.bld.producer + + def cur(): + # the current task position, computed as late as possible + return master.processed - master.ready.qsize() + + if self.generator.bld.progress_bar == 1: + return self.generator.bld.progress_line(cur(), master.total, col1, col2) + + if self.generator.bld.progress_bar == 2: + ela = str(self.generator.bld.timer) + try: + ins = ','.join([n.name for n in self.inputs]) + except AttributeError: + ins = '' + try: + outs = ','.join([n.name for n in self.outputs]) + except AttributeError: + outs = '' + return '|Total %s|Current %s|Inputs %s|Outputs %s|Time %s|\n' % (master.total, cur(), ins, outs, ela) + + s = str(self) + if not s: + return None + + total = master.total + n = len(str(total)) + fs = '[%%%dd/%%%dd] %%s%%s%%s%%s\n' % (n, n) + kw = self.keyword() + if kw: + kw += ' ' + return fs % (cur(), total, kw, col1, s, col2) + + def hash_constraints(self): + """ + Identifies a task type for all the constraints relevant for the scheduler: precedence, file production + + :return: a hash value + :rtype: string + """ + return (tuple(self.before), tuple(self.after), tuple(self.ext_in), tuple(self.ext_out), self.__class__.__name__, self.hcode) + + def format_error(self): + """ + Returns an error message to display the build failure reasons + + :rtype: string + """ + if Logs.verbose: + msg = ': %r\n%r' % (self, getattr(self, 'last_cmd', '')) + else: + msg = ' (run with -v to display more information)' + name = getattr(self.generator, 'name', '') + if getattr(self, "err_msg", None): + return self.err_msg + elif not self.hasrun: + return 'task in %r was not executed for some reason: %r' % (name, self) + elif self.hasrun == CRASHED: + try: + return ' -> task in %r failed with exit status %r%s' % (name, self.err_code, msg) + except AttributeError: + return ' -> task in %r failed%s' % (name, msg) + elif self.hasrun == MISSING: + return ' -> missing files in %r%s' % (name, msg) + elif self.hasrun == CANCELED: + return ' -> %r canceled because of missing dependencies' % name + else: + return 'invalid status for task in %r: %r' % (name, self.hasrun) + + def colon(self, var1, var2): + """ + Enable scriptlet expressions of the form ${FOO_ST:FOO} + If the first variable (FOO_ST) is empty, then an empty list is returned + + The results will be slightly different if FOO_ST is a list, for example:: + + env.FOO = ['p1', 'p2'] + env.FOO_ST = '-I%s' + # ${FOO_ST:FOO} returns + ['-Ip1', '-Ip2'] + + env.FOO_ST = ['-a', '-b'] + # ${FOO_ST:FOO} returns + ['-a', '-b', 'p1', '-a', '-b', 'p2'] + """ + tmp = self.env[var1] + if not tmp: + return [] + + if isinstance(var2, str): + it = self.env[var2] + else: + it = var2 + if isinstance(tmp, str): + return [tmp % x for x in it] + else: + lst = [] + for y in it: + lst.extend(tmp) + lst.append(y) + return lst + + def __str__(self): + "string to display to the user" + name = self.__class__.__name__ + if self.outputs: + if name.endswith(('lib', 'program')) or not self.inputs: + node = self.outputs[0] + return node.path_from(node.ctx.launch_node()) + if not (self.inputs or self.outputs): + return self.__class__.__name__ + if len(self.inputs) == 1: + node = self.inputs[0] + return node.path_from(node.ctx.launch_node()) + + src_str = ' '.join([a.path_from(a.ctx.launch_node()) for a in self.inputs]) + tgt_str = ' '.join([a.path_from(a.ctx.launch_node()) for a in self.outputs]) + if self.outputs: + sep = ' -> ' + else: + sep = '' + return '%s: %s%s%s' % (self.__class__.__name__, src_str, sep, tgt_str) + + def keyword(self): + "Display keyword used to prettify the console outputs" + name = self.__class__.__name__ + if name.endswith(('lib', 'program')): + return 'Linking' + if len(self.inputs) == 1 and len(self.outputs) == 1: + return 'Compiling' + if not self.inputs: + if self.outputs: + return 'Creating' + else: + return 'Running' + return 'Processing' + + def __repr__(self): + "for debugging purposes" + try: + ins = ",".join([x.name for x in self.inputs]) + outs = ",".join([x.name for x in self.outputs]) + except AttributeError: + ins = ",".join([str(x) for x in self.inputs]) + outs = ",".join([str(x) for x in self.outputs]) + return "".join(['\n\t{task %r: ' % id(self), self.__class__.__name__, " ", ins, " -> ", outs, '}']) + + def uid(self): + """ + Returns an identifier used to determine if tasks are up-to-date. Since the + identifier will be stored between executions, it must be: + + - unique for a task: no two tasks return the same value (for a given build context) + - the same for a given task instance + + By default, the node paths, the class name, and the function are used + as inputs to compute a hash. + + The pointer to the object (python built-in 'id') will change between build executions, + and must be avoided in such hashes. + + :return: hash value + :rtype: string + """ + try: + return self.uid_ + except AttributeError: + m = Utils.md5(self.__class__.__name__) + up = m.update + for x in self.inputs + self.outputs: + up(x.abspath()) + self.uid_ = m.digest() + return self.uid_ + + def set_inputs(self, inp): + """ + Appends the nodes to the *inputs* list + + :param inp: input nodes + :type inp: node or list of nodes + """ + if isinstance(inp, list): + self.inputs += inp + else: + self.inputs.append(inp) + + def set_outputs(self, out): + """ + Appends the nodes to the *outputs* list + + :param out: output nodes + :type out: node or list of nodes + """ + if isinstance(out, list): + self.outputs += out + else: + self.outputs.append(out) + + def set_run_after(self, task): + """ + Run this task only after the given *task*. + + Calling this method from :py:meth:`waflib.Task.Task.runnable_status` may cause + build deadlocks; see :py:meth:`waflib.Tools.fc.fc.runnable_status` for details. + + :param task: task + :type task: :py:class:`waflib.Task.Task` + """ + assert isinstance(task, Task) + self.run_after.add(task) + + def signature(self): + """ + Task signatures are stored between build executions, they are use to track the changes + made to the input nodes (not to the outputs!). The signature hashes data from various sources: + + * explicit dependencies: files listed in the inputs (list of node objects) :py:meth:`waflib.Task.Task.sig_explicit_deps` + * implicit dependencies: list of nodes returned by scanner methods (when present) :py:meth:`waflib.Task.Task.sig_implicit_deps` + * hashed data: variables/values read from task.vars/task.env :py:meth:`waflib.Task.Task.sig_vars` + + If the signature is expected to give a different result, clear the cache kept in ``self.cache_sig``:: + + from waflib import Task + class cls(Task.Task): + def signature(self): + sig = super(Task.Task, self).signature() + delattr(self, 'cache_sig') + return super(Task.Task, self).signature() + + :return: the signature value + :rtype: string or bytes + """ + try: + return self.cache_sig + except AttributeError: + pass + + self.m = Utils.md5(self.hcode) + + # explicit deps + self.sig_explicit_deps() + + # env vars + self.sig_vars() + + # implicit deps / scanner results + if self.scan: + try: + self.sig_implicit_deps() + except Errors.TaskRescan: + return self.signature() + + ret = self.cache_sig = self.m.digest() + return ret + + def runnable_status(self): + """ + Returns the Task status + + :return: a task state in :py:const:`waflib.Task.RUN_ME`, + :py:const:`waflib.Task.SKIP_ME`, :py:const:`waflib.Task.CANCEL_ME` or :py:const:`waflib.Task.ASK_LATER`. + :rtype: int + """ + bld = self.generator.bld + if bld.is_install < 0: + return SKIP_ME + + for t in self.run_after: + if not t.hasrun: + return ASK_LATER + elif t.hasrun < SKIPPED: + # a dependency has an error + return CANCEL_ME + + # first compute the signature + try: + new_sig = self.signature() + except Errors.TaskNotReady: + return ASK_LATER + + # compare the signature to a signature computed previously + key = self.uid() + try: + prev_sig = bld.task_sigs[key] + except KeyError: + Logs.debug('task: task %r must run: it was never run before or the task code changed', self) + return RUN_ME + + if new_sig != prev_sig: + Logs.debug('task: task %r must run: the task signature changed', self) + return RUN_ME + + # compare the signatures of the outputs + for node in self.outputs: + sig = bld.node_sigs.get(node) + if not sig: + Logs.debug('task: task %r must run: an output node has no signature', self) + return RUN_ME + if sig != key: + Logs.debug('task: task %r must run: an output node was produced by another task', self) + return RUN_ME + if not node.exists(): + Logs.debug('task: task %r must run: an output node does not exist', self) + return RUN_ME + + return (self.always_run and RUN_ME) or SKIP_ME + + def post_run(self): + """ + Called after successful execution to record that the task has run by + updating the entry in :py:attr:`waflib.Build.BuildContext.task_sigs`. + """ + bld = self.generator.bld + for node in self.outputs: + if not node.exists(): + self.hasrun = MISSING + self.err_msg = '-> missing file: %r' % node.abspath() + raise Errors.WafError(self.err_msg) + bld.node_sigs[node] = self.uid() # make sure this task produced the files in question + bld.task_sigs[self.uid()] = self.signature() + if not self.keep_last_cmd: + try: + del self.last_cmd + except AttributeError: + pass + + def sig_explicit_deps(self): + """ + Used by :py:meth:`waflib.Task.Task.signature`; it hashes :py:attr:`waflib.Task.Task.inputs` + and :py:attr:`waflib.Task.Task.dep_nodes` signatures. + """ + bld = self.generator.bld + upd = self.m.update + + # the inputs + for x in self.inputs + self.dep_nodes: + upd(x.get_bld_sig()) + + # manual dependencies, they can slow down the builds + if bld.deps_man: + additional_deps = bld.deps_man + for x in self.inputs + self.outputs: + try: + d = additional_deps[x] + except KeyError: + continue + + for v in d: + try: + v = v.get_bld_sig() + except AttributeError: + if hasattr(v, '__call__'): + v = v() # dependency is a function, call it + upd(v) + + def sig_deep_inputs(self): + """ + Enable rebuilds on input files task signatures. Not used by default. + + Example: hashes of output programs can be unchanged after being re-linked, + despite the libraries being different. This method can thus prevent stale unit test + results (waf_unit_test.py). + + Hashing input file timestamps is another possibility for the implementation. + This may cause unnecessary rebuilds when input tasks are frequently executed. + Here is an implementation example:: + + lst = [] + for node in self.inputs + self.dep_nodes: + st = os.stat(node.abspath()) + lst.append(st.st_mtime) + lst.append(st.st_size) + self.m.update(Utils.h_list(lst)) + + The downside of the implementation is that it absolutely requires all build directory + files to be declared within the current build. + """ + bld = self.generator.bld + lst = [bld.task_sigs[bld.node_sigs[node]] for node in (self.inputs + self.dep_nodes) if node.is_bld()] + self.m.update(Utils.h_list(lst)) + + def sig_vars(self): + """ + Used by :py:meth:`waflib.Task.Task.signature`; it hashes :py:attr:`waflib.Task.Task.env` variables/values + When overriding this method, and if scriptlet expressions are used, make sure to follow + the code in :py:meth:`waflib.Task.Task.compile_sig_vars` to enable dependencies on scriptlet results. + + This method may be replaced on subclasses by the metaclass to force dependencies on scriptlet code. + """ + sig = self.generator.bld.hash_env_vars(self.env, self.vars) + self.m.update(sig) + + scan = None + """ + This method, when provided, returns a tuple containing: + + * a list of nodes corresponding to real files + * a list of names for files not found in path_lst + + For example:: + + from waflib.Task import Task + class mytask(Task): + def scan(self, node): + return ([], []) + + The first and second lists in the tuple are stored in :py:attr:`waflib.Build.BuildContext.node_deps` and + :py:attr:`waflib.Build.BuildContext.raw_deps` respectively. + """ + + def sig_implicit_deps(self): + """ + Used by :py:meth:`waflib.Task.Task.signature`; it hashes node signatures + obtained by scanning for dependencies (:py:meth:`waflib.Task.Task.scan`). + + The exception :py:class:`waflib.Errors.TaskRescan` is thrown + when a file has changed. In this case, the method :py:meth:`waflib.Task.Task.signature` is called + once again, and return here to call :py:meth:`waflib.Task.Task.scan` and searching for dependencies. + """ + bld = self.generator.bld + + # get the task signatures from previous runs + key = self.uid() + prev = bld.imp_sigs.get(key, []) + + # for issue #379 + if prev: + try: + if prev == self.compute_sig_implicit_deps(): + return prev + except Errors.TaskNotReady: + raise + except EnvironmentError: + # when a file was renamed, remove the stale nodes (headers in folders without source files) + # this will break the order calculation for headers created during the build in the source directory (should be uncommon) + # the behaviour will differ when top != out + for x in bld.node_deps.get(self.uid(), []): + if not x.is_bld() and not x.exists(): + try: + del x.parent.children[x.name] + except KeyError: + pass + del bld.imp_sigs[key] + raise Errors.TaskRescan('rescan') + + # no previous run or the signature of the dependencies has changed, rescan the dependencies + (bld.node_deps[key], bld.raw_deps[key]) = self.scan() + if Logs.verbose: + Logs.debug('deps: scanner for %s: %r; unresolved: %r', self, bld.node_deps[key], bld.raw_deps[key]) + + # recompute the signature and return it + try: + bld.imp_sigs[key] = self.compute_sig_implicit_deps() + except EnvironmentError: + for k in bld.node_deps.get(self.uid(), []): + if not k.exists(): + Logs.warn('Dependency %r for %r is missing: check the task declaration and the build order!', k, self) + raise + + def compute_sig_implicit_deps(self): + """ + Used by :py:meth:`waflib.Task.Task.sig_implicit_deps` for computing the actual hash of the + :py:class:`waflib.Node.Node` returned by the scanner. + + :return: a hash value for the implicit dependencies + :rtype: string or bytes + """ + upd = self.m.update + self.are_implicit_nodes_ready() + + # scanner returns a node that does not have a signature + # just *ignore* the error and let them figure out from the compiler output + # waf -k behaviour + for k in self.generator.bld.node_deps.get(self.uid(), []): + upd(k.get_bld_sig()) + return self.m.digest() + + def are_implicit_nodes_ready(self): + """ + For each node returned by the scanner, see if there is a task that creates it, + and infer the build order + + This has a low performance impact on null builds (1.86s->1.66s) thanks to caching (28s->1.86s) + """ + bld = self.generator.bld + try: + cache = bld.dct_implicit_nodes + except AttributeError: + bld.dct_implicit_nodes = cache = {} + + # one cache per build group + try: + dct = cache[bld.current_group] + except KeyError: + dct = cache[bld.current_group] = {} + for tsk in bld.cur_tasks: + for x in tsk.outputs: + dct[x] = tsk + + modified = False + for x in bld.node_deps.get(self.uid(), []): + if x in dct: + self.run_after.add(dct[x]) + modified = True + + if modified: + for tsk in self.run_after: + if not tsk.hasrun: + #print "task is not ready..." + raise Errors.TaskNotReady('not ready') +if sys.hexversion > 0x3000000: + def uid(self): + try: + return self.uid_ + except AttributeError: + m = Utils.md5(self.__class__.__name__.encode('latin-1', 'xmlcharrefreplace')) + up = m.update + for x in self.inputs + self.outputs: + up(x.abspath().encode('latin-1', 'xmlcharrefreplace')) + self.uid_ = m.digest() + return self.uid_ + uid.__doc__ = Task.uid.__doc__ + Task.uid = uid + +def is_before(t1, t2): + """ + Returns a non-zero value if task t1 is to be executed before task t2:: + + t1.ext_out = '.h' + t2.ext_in = '.h' + t2.after = ['t1'] + t1.before = ['t2'] + waflib.Task.is_before(t1, t2) # True + + :param t1: Task object + :type t1: :py:class:`waflib.Task.Task` + :param t2: Task object + :type t2: :py:class:`waflib.Task.Task` + """ + to_list = Utils.to_list + for k in to_list(t2.ext_in): + if k in to_list(t1.ext_out): + return 1 + + if t1.__class__.__name__ in to_list(t2.after): + return 1 + + if t2.__class__.__name__ in to_list(t1.before): + return 1 + + return 0 + +def set_file_constraints(tasks): + """ + Updates the ``run_after`` attribute of all tasks based on the task inputs and outputs + + :param tasks: tasks + :type tasks: list of :py:class:`waflib.Task.Task` + """ + ins = Utils.defaultdict(set) + outs = Utils.defaultdict(set) + for x in tasks: + for a in x.inputs: + ins[a].add(x) + for a in x.dep_nodes: + ins[a].add(x) + for a in x.outputs: + outs[a].add(x) + + links = set(ins.keys()).intersection(outs.keys()) + for k in links: + for a in ins[k]: + a.run_after.update(outs[k]) + + +class TaskGroup(object): + """ + Wrap nxm task order constraints into a single object + to prevent the creation of large list/set objects + + This is an optimization + """ + def __init__(self, prev, next): + self.prev = prev + self.next = next + self.done = False + + def get_hasrun(self): + for k in self.prev: + if not k.hasrun: + return NOT_RUN + return SUCCESS + + hasrun = property(get_hasrun, None) + +def set_precedence_constraints(tasks): + """ + Updates the ``run_after`` attribute of all tasks based on the after/before/ext_out/ext_in attributes + + :param tasks: tasks + :type tasks: list of :py:class:`waflib.Task.Task` + """ + cstr_groups = Utils.defaultdict(list) + for x in tasks: + h = x.hash_constraints() + cstr_groups[h].append(x) + + keys = list(cstr_groups.keys()) + maxi = len(keys) + + # this list should be short + for i in range(maxi): + t1 = cstr_groups[keys[i]][0] + for j in range(i + 1, maxi): + t2 = cstr_groups[keys[j]][0] + + # add the constraints based on the comparisons + if is_before(t1, t2): + a = i + b = j + elif is_before(t2, t1): + a = j + b = i + else: + continue + + a = cstr_groups[keys[a]] + b = cstr_groups[keys[b]] + + if len(a) < 2 or len(b) < 2: + for x in b: + x.run_after.update(a) + else: + group = TaskGroup(set(a), set(b)) + for x in b: + x.run_after.add(group) + +def funex(c): + """ + Compiles a scriptlet expression into a Python function + + :param c: function to compile + :type c: string + :return: the function 'f' declared in the input string + :rtype: function + """ + dc = {} + exec(c, dc) + return dc['f'] + +re_cond = re.compile(r'(?P\w+)|(?P\|)|(?P&)') +re_novar = re.compile(r'^(SRC|TGT)\W+.*?$') +reg_act = re.compile(r'(?P\\)|(?P\$\$)|(?P\$\{(?P\w+)(?P.*?)\})', re.M) +def compile_fun_shell(line): + """ + Creates a compiled function to execute a process through a sub-shell + """ + extr = [] + def repl(match): + g = match.group + if g('dollar'): + return "$" + elif g('backslash'): + return '\\\\' + elif g('subst'): + extr.append((g('var'), g('code'))) + return "%s" + return None + line = reg_act.sub(repl, line) or line + dvars = [] + def add_dvar(x): + if x not in dvars: + dvars.append(x) + + def replc(m): + # performs substitutions and populates dvars + if m.group('and'): + return ' and ' + elif m.group('or'): + return ' or ' + else: + x = m.group('var') + add_dvar(x) + return 'env[%r]' % x + + parm = [] + app = parm.append + for (var, meth) in extr: + if var == 'SRC': + if meth: + app('tsk.inputs%s' % meth) + else: + app('" ".join([a.path_from(cwdx) for a in tsk.inputs])') + elif var == 'TGT': + if meth: + app('tsk.outputs%s' % meth) + else: + app('" ".join([a.path_from(cwdx) for a in tsk.outputs])') + elif meth: + if meth.startswith(':'): + add_dvar(var) + m = meth[1:] + if m == 'SRC': + m = '[a.path_from(cwdx) for a in tsk.inputs]' + elif m == 'TGT': + m = '[a.path_from(cwdx) for a in tsk.outputs]' + elif re_novar.match(m): + m = '[tsk.inputs%s]' % m[3:] + elif re_novar.match(m): + m = '[tsk.outputs%s]' % m[3:] + else: + add_dvar(m) + if m[:3] not in ('tsk', 'gen', 'bld'): + m = '%r' % m + app('" ".join(tsk.colon(%r, %s))' % (var, m)) + elif meth.startswith('?'): + # In A?B|C output env.A if one of env.B or env.C is non-empty + expr = re_cond.sub(replc, meth[1:]) + app('p(%r) if (%s) else ""' % (var, expr)) + else: + call = '%s%s' % (var, meth) + add_dvar(call) + app(call) + else: + add_dvar(var) + app("p('%s')" % var) + if parm: + parm = "%% (%s) " % (',\n\t\t'.join(parm)) + else: + parm = '' + + c = COMPILE_TEMPLATE_SHELL % (line, parm) + Logs.debug('action: %s', c.strip().splitlines()) + return (funex(c), dvars) + +reg_act_noshell = re.compile(r"(?P\s+)|(?P\$\{(?P\w+)(?P.*?)\})|(?P([^$ \t\n\r\f\v]|\$\$)+)", re.M) +def compile_fun_noshell(line): + """ + Creates a compiled function to execute a process without a sub-shell + """ + buf = [] + dvars = [] + merge = False + app = buf.append + + def add_dvar(x): + if x not in dvars: + dvars.append(x) + + def replc(m): + # performs substitutions and populates dvars + if m.group('and'): + return ' and ' + elif m.group('or'): + return ' or ' + else: + x = m.group('var') + add_dvar(x) + return 'env[%r]' % x + + for m in reg_act_noshell.finditer(line): + if m.group('space'): + merge = False + continue + elif m.group('text'): + app('[%r]' % m.group('text').replace('$$', '$')) + elif m.group('subst'): + var = m.group('var') + code = m.group('code') + if var == 'SRC': + if code: + app('[tsk.inputs%s]' % code) + else: + app('[a.path_from(cwdx) for a in tsk.inputs]') + elif var == 'TGT': + if code: + app('[tsk.outputs%s]' % code) + else: + app('[a.path_from(cwdx) for a in tsk.outputs]') + elif code: + if code.startswith(':'): + # a composed variable ${FOO:OUT} + add_dvar(var) + m = code[1:] + if m == 'SRC': + m = '[a.path_from(cwdx) for a in tsk.inputs]' + elif m == 'TGT': + m = '[a.path_from(cwdx) for a in tsk.outputs]' + elif re_novar.match(m): + m = '[tsk.inputs%s]' % m[3:] + elif re_novar.match(m): + m = '[tsk.outputs%s]' % m[3:] + else: + add_dvar(m) + if m[:3] not in ('tsk', 'gen', 'bld'): + m = '%r' % m + app('tsk.colon(%r, %s)' % (var, m)) + elif code.startswith('?'): + # In A?B|C output env.A if one of env.B or env.C is non-empty + expr = re_cond.sub(replc, code[1:]) + app('to_list(env[%r] if (%s) else [])' % (var, expr)) + else: + # plain code such as ${tsk.inputs[0].abspath()} + call = '%s%s' % (var, code) + add_dvar(call) + app('to_list(%s)' % call) + else: + # a plain variable such as # a plain variable like ${AR} + app('to_list(env[%r])' % var) + add_dvar(var) + if merge: + tmp = 'merge(%s, %s)' % (buf[-2], buf[-1]) + del buf[-1] + buf[-1] = tmp + merge = True # next turn + + buf = ['lst.extend(%s)' % x for x in buf] + fun = COMPILE_TEMPLATE_NOSHELL % "\n\t".join(buf) + Logs.debug('action: %s', fun.strip().splitlines()) + return (funex(fun), dvars) + +def compile_fun(line, shell=False): + """ + Parses a string expression such as '${CC} ${SRC} -o ${TGT}' and returns a pair containing: + + * The function created (compiled) for use as :py:meth:`waflib.Task.Task.run` + * The list of variables that must cause rebuilds when *env* data is modified + + for example:: + + from waflib.Task import compile_fun + compile_fun('cxx', '${CXX} -o ${TGT[0]} ${SRC} -I ${SRC[0].parent.bldpath()}') + + def build(bld): + bld(source='wscript', rule='echo "foo\\${SRC[0].name}\\bar"') + + The env variables (CXX, ..) on the task must not hold dicts so as to preserve a consistent order. + The reserved keywords ``TGT`` and ``SRC`` represent the task input and output nodes + + """ + if isinstance(line, str): + if line.find('<') > 0 or line.find('>') > 0 or line.find('&&') > 0: + shell = True + else: + dvars_lst = [] + funs_lst = [] + for x in line: + if isinstance(x, str): + fun, dvars = compile_fun(x, shell) + dvars_lst += dvars + funs_lst.append(fun) + else: + # assume a function to let through + funs_lst.append(x) + def composed_fun(task): + for x in funs_lst: + ret = x(task) + if ret: + return ret + return None + return composed_fun, dvars_lst + if shell: + return compile_fun_shell(line) + else: + return compile_fun_noshell(line) + +def compile_sig_vars(vars): + """ + This method produces a sig_vars method suitable for subclasses that provide + scriptlet code in their run_str code. + If no such method can be created, this method returns None. + + The purpose of the sig_vars method returned is to ensures + that rebuilds occur whenever the contents of the expression changes. + This is the case B below:: + + import time + # case A: regular variables + tg = bld(rule='echo ${FOO}') + tg.env.FOO = '%s' % time.time() + # case B + bld(rule='echo ${gen.foo}', foo='%s' % time.time()) + + :param vars: env variables such as CXXFLAGS or gen.foo + :type vars: list of string + :return: A sig_vars method relevant for dependencies if adequate, else None + :rtype: A function, or None in most cases + """ + buf = [] + for x in sorted(vars): + if x[:3] in ('tsk', 'gen', 'bld'): + buf.append('buf.append(%s)' % x) + if buf: + return funex(COMPILE_TEMPLATE_SIG_VARS % '\n\t'.join(buf)) + return None + +def task_factory(name, func=None, vars=None, color='GREEN', ext_in=[], ext_out=[], before=[], after=[], shell=False, scan=None): + """ + Returns a new task subclass with the function ``run`` compiled from the line given. + + :param func: method run + :type func: string or function + :param vars: list of variables to hash + :type vars: list of string + :param color: color to use + :type color: string + :param shell: when *func* is a string, enable/disable the use of the shell + :type shell: bool + :param scan: method scan + :type scan: function + :rtype: :py:class:`waflib.Task.Task` + """ + + params = { + 'vars': vars or [], # function arguments are static, and this one may be modified by the class + 'color': color, + 'name': name, + 'shell': shell, + 'scan': scan, + } + + if isinstance(func, str) or isinstance(func, tuple): + params['run_str'] = func + else: + params['run'] = func + + cls = type(Task)(name, (Task,), params) + classes[name] = cls + + if ext_in: + cls.ext_in = Utils.to_list(ext_in) + if ext_out: + cls.ext_out = Utils.to_list(ext_out) + if before: + cls.before = Utils.to_list(before) + if after: + cls.after = Utils.to_list(after) + + return cls + +def deep_inputs(cls): + """ + Task class decorator to enable rebuilds on input files task signatures + """ + def sig_explicit_deps(self): + Task.sig_explicit_deps(self) + Task.sig_deep_inputs(self) + cls.sig_explicit_deps = sig_explicit_deps + return cls + +TaskBase = Task +"Provided for compatibility reasons, TaskBase should not be used" + +class TaskSemaphore(object): + """ + Task semaphores provide a simple and efficient way of throttling the amount of + a particular task to run concurrently. The throttling value is capped + by the amount of maximum jobs, so for example, a `TaskSemaphore(10)` + has no effect in a `-j2` build. + + Task semaphores are typically specified on the task class level:: + + class compile(waflib.Task.Task): + semaphore = waflib.Task.TaskSemaphore(2) + run_str = 'touch ${TGT}' + + Task semaphores are meant to be used by the build scheduler in the main + thread, so there are no guarantees of thread safety. + """ + def __init__(self, num): + """ + :param num: maximum value of concurrent tasks + :type num: int + """ + self.num = num + self.locking = set() + self.waiting = set() + + def is_locked(self): + """Returns True if this semaphore cannot be acquired by more tasks""" + return len(self.locking) >= self.num + + def acquire(self, tsk): + """ + Mark the semaphore as used by the given task (not re-entrant). + + :param tsk: task object + :type tsk: :py:class:`waflib.Task.Task` + :raises: :py:class:`IndexError` in case the resource is already acquired + """ + if self.is_locked(): + raise IndexError('Cannot lock more %r' % self.locking) + self.locking.add(tsk) + + def release(self, tsk): + """ + Mark the semaphore as unused by the given task. + + :param tsk: task object + :type tsk: :py:class:`waflib.Task.Task` + :raises: :py:class:`KeyError` in case the resource is not acquired by the task + """ + self.locking.remove(tsk) + diff --git a/ldb-2.0.8/third_party/waf/waflib/TaskGen.py b/ldb-2.0.8/third_party/waf/waflib/TaskGen.py new file mode 100644 index 0000000..f8f92bd --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/TaskGen.py @@ -0,0 +1,917 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2005-2018 (ita) + +""" +Task generators + +The class :py:class:`waflib.TaskGen.task_gen` encapsulates the creation of task objects (low-level code) +The instances can have various parameters, but the creation of task nodes (Task.py) +is deferred. To achieve this, various methods are called from the method "apply" +""" + +import copy, re, os, functools +from waflib import Task, Utils, Logs, Errors, ConfigSet, Node + +feats = Utils.defaultdict(set) +"""remember the methods declaring features""" + +HEADER_EXTS = ['.h', '.hpp', '.hxx', '.hh'] + +class task_gen(object): + """ + Instances of this class create :py:class:`waflib.Task.Task` when + calling the method :py:meth:`waflib.TaskGen.task_gen.post` from the main thread. + A few notes: + + * The methods to call (*self.meths*) can be specified dynamically (removing, adding, ..) + * The 'features' are used to add methods to self.meths and then execute them + * The attribute 'path' is a node representing the location of the task generator + * The tasks created are added to the attribute *tasks* + * The attribute 'idx' is a counter of task generators in the same path + """ + + mappings = Utils.ordered_iter_dict() + """Mappings are global file extension mappings that are retrieved in the order of definition""" + + prec = Utils.defaultdict(set) + """Dict that holds the precedence execution rules for task generator methods""" + + def __init__(self, *k, **kw): + """ + Task generator objects predefine various attributes (source, target) for possible + processing by process_rule (make-like rules) or process_source (extensions, misc methods) + + Tasks are stored on the attribute 'tasks'. They are created by calling methods + listed in ``self.meths`` or referenced in the attribute ``features`` + A topological sort is performed to execute the methods in correct order. + + The extra key/value elements passed in ``kw`` are set as attributes + """ + self.source = [] + self.target = '' + + self.meths = [] + """ + List of method names to execute (internal) + """ + + self.features = [] + """ + List of feature names for bringing new methods in + """ + + self.tasks = [] + """ + Tasks created are added to this list + """ + + if not 'bld' in kw: + # task generators without a build context :-/ + self.env = ConfigSet.ConfigSet() + self.idx = 0 + self.path = None + else: + self.bld = kw['bld'] + self.env = self.bld.env.derive() + self.path = kw.get('path', self.bld.path) # by default, emulate chdir when reading scripts + + # Provide a unique index per folder + # This is part of a measure to prevent output file name collisions + path = self.path.abspath() + try: + self.idx = self.bld.idx[path] = self.bld.idx.get(path, 0) + 1 + except AttributeError: + self.bld.idx = {} + self.idx = self.bld.idx[path] = 1 + + # Record the global task generator count + try: + self.tg_idx_count = self.bld.tg_idx_count = self.bld.tg_idx_count + 1 + except AttributeError: + self.tg_idx_count = self.bld.tg_idx_count = 1 + + for key, val in kw.items(): + setattr(self, key, val) + + def __str__(self): + """Debugging helper""" + return "" % (self.name, self.path.abspath()) + + def __repr__(self): + """Debugging helper""" + lst = [] + for x in self.__dict__: + if x not in ('env', 'bld', 'compiled_tasks', 'tasks'): + lst.append("%s=%s" % (x, repr(getattr(self, x)))) + return "bld(%s) in %s" % (", ".join(lst), self.path.abspath()) + + def get_cwd(self): + """ + Current working directory for the task generator, defaults to the build directory. + This is still used in a few places but it should disappear at some point as the classes + define their own working directory. + + :rtype: :py:class:`waflib.Node.Node` + """ + return self.bld.bldnode + + def get_name(self): + """ + If the attribute ``name`` is not set on the instance, + the name is computed from the target name:: + + def build(bld): + x = bld(name='foo') + x.get_name() # foo + y = bld(target='bar') + y.get_name() # bar + + :rtype: string + :return: name of this task generator + """ + try: + return self._name + except AttributeError: + if isinstance(self.target, list): + lst = [str(x) for x in self.target] + name = self._name = ','.join(lst) + else: + name = self._name = str(self.target) + return name + def set_name(self, name): + self._name = name + + name = property(get_name, set_name) + + def to_list(self, val): + """ + Ensures that a parameter is a list, see :py:func:`waflib.Utils.to_list` + + :type val: string or list of string + :param val: input to return as a list + :rtype: list + """ + if isinstance(val, str): + return val.split() + else: + return val + + def post(self): + """ + Creates tasks for this task generators. The following operations are performed: + + #. The body of this method is called only once and sets the attribute ``posted`` + #. The attribute ``features`` is used to add more methods in ``self.meths`` + #. The methods are sorted by the precedence table ``self.prec`` or `:waflib:attr:waflib.TaskGen.task_gen.prec` + #. The methods are then executed in order + #. The tasks created are added to :py:attr:`waflib.TaskGen.task_gen.tasks` + """ + if getattr(self, 'posted', None): + return False + self.posted = True + + keys = set(self.meths) + keys.update(feats['*']) + + # add the methods listed in the features + self.features = Utils.to_list(self.features) + for x in self.features: + st = feats[x] + if st: + keys.update(st) + elif not x in Task.classes: + Logs.warn('feature %r does not exist - bind at least one method to it?', x) + + # copy the precedence table + prec = {} + prec_tbl = self.prec + for x in prec_tbl: + if x in keys: + prec[x] = prec_tbl[x] + + # elements disconnected + tmp = [] + for a in keys: + for x in prec.values(): + if a in x: + break + else: + tmp.append(a) + + tmp.sort(reverse=True) + + # topological sort + out = [] + while tmp: + e = tmp.pop() + if e in keys: + out.append(e) + try: + nlst = prec[e] + except KeyError: + pass + else: + del prec[e] + for x in nlst: + for y in prec: + if x in prec[y]: + break + else: + tmp.append(x) + tmp.sort(reverse=True) + + if prec: + buf = ['Cycle detected in the method execution:'] + for k, v in prec.items(): + buf.append('- %s after %s' % (k, [x for x in v if x in prec])) + raise Errors.WafError('\n'.join(buf)) + self.meths = out + + # then we run the methods in order + Logs.debug('task_gen: posting %s %d', self, id(self)) + for x in out: + try: + v = getattr(self, x) + except AttributeError: + raise Errors.WafError('%r is not a valid task generator method' % x) + Logs.debug('task_gen: -> %s (%d)', x, id(self)) + v() + + Logs.debug('task_gen: posted %s', self.name) + return True + + def get_hook(self, node): + """ + Returns the ``@extension`` method to call for a Node of a particular extension. + + :param node: Input file to process + :type node: :py:class:`waflib.Tools.Node.Node` + :return: A method able to process the input node by looking at the extension + :rtype: function + """ + name = node.name + for k in self.mappings: + try: + if name.endswith(k): + return self.mappings[k] + except TypeError: + # regexps objects + if k.match(name): + return self.mappings[k] + keys = list(self.mappings.keys()) + raise Errors.WafError("File %r has no mapping in %r (load a waf tool?)" % (node, keys)) + + def create_task(self, name, src=None, tgt=None, **kw): + """ + Creates task instances. + + :param name: task class name + :type name: string + :param src: input nodes + :type src: list of :py:class:`waflib.Tools.Node.Node` + :param tgt: output nodes + :type tgt: list of :py:class:`waflib.Tools.Node.Node` + :return: A task object + :rtype: :py:class:`waflib.Task.Task` + """ + task = Task.classes[name](env=self.env.derive(), generator=self) + if src: + task.set_inputs(src) + if tgt: + task.set_outputs(tgt) + task.__dict__.update(kw) + self.tasks.append(task) + return task + + def clone(self, env): + """ + Makes a copy of a task generator. Once the copy is made, it is necessary to ensure that the + it does not create the same output files as the original, or the same files may + be compiled several times. + + :param env: A configuration set + :type env: :py:class:`waflib.ConfigSet.ConfigSet` + :return: A copy + :rtype: :py:class:`waflib.TaskGen.task_gen` + """ + newobj = self.bld() + for x in self.__dict__: + if x in ('env', 'bld'): + continue + elif x in ('path', 'features'): + setattr(newobj, x, getattr(self, x)) + else: + setattr(newobj, x, copy.copy(getattr(self, x))) + + newobj.posted = False + if isinstance(env, str): + newobj.env = self.bld.all_envs[env].derive() + else: + newobj.env = env.derive() + + return newobj + +def declare_chain(name='', rule=None, reentrant=None, color='BLUE', + ext_in=[], ext_out=[], before=[], after=[], decider=None, scan=None, install_path=None, shell=False): + """ + Creates a new mapping and a task class for processing files by extension. + See Tools/flex.py for an example. + + :param name: name for the task class + :type name: string + :param rule: function to execute or string to be compiled in a function + :type rule: string or function + :param reentrant: re-inject the output file in the process (done automatically, set to 0 to disable) + :type reentrant: int + :param color: color for the task output + :type color: string + :param ext_in: execute the task only after the files of such extensions are created + :type ext_in: list of string + :param ext_out: execute the task only before files of such extensions are processed + :type ext_out: list of string + :param before: execute instances of this task before classes of the given names + :type before: list of string + :param after: execute instances of this task after classes of the given names + :type after: list of string + :param decider: if present, function that returns a list of output file extensions (overrides ext_out for output files, but not for the build order) + :type decider: function + :param scan: scanner function for the task + :type scan: function + :param install_path: installation path for the output nodes + :type install_path: string + """ + ext_in = Utils.to_list(ext_in) + ext_out = Utils.to_list(ext_out) + if not name: + name = rule + cls = Task.task_factory(name, rule, color=color, ext_in=ext_in, ext_out=ext_out, before=before, after=after, scan=scan, shell=shell) + + def x_file(self, node): + if ext_in: + _ext_in = ext_in[0] + + tsk = self.create_task(name, node) + cnt = 0 + + ext = decider(self, node) if decider else cls.ext_out + for x in ext: + k = node.change_ext(x, ext_in=_ext_in) + tsk.outputs.append(k) + + if reentrant != None: + if cnt < int(reentrant): + self.source.append(k) + else: + # reinject downstream files into the build + for y in self.mappings: # ~ nfile * nextensions :-/ + if k.name.endswith(y): + self.source.append(k) + break + cnt += 1 + + if install_path: + self.install_task = self.add_install_files(install_to=install_path, install_from=tsk.outputs) + return tsk + + for x in cls.ext_in: + task_gen.mappings[x] = x_file + return x_file + +def taskgen_method(func): + """ + Decorator that registers method as a task generator method. + The function must accept a task generator as first parameter:: + + from waflib.TaskGen import taskgen_method + @taskgen_method + def mymethod(self): + pass + + :param func: task generator method to add + :type func: function + :rtype: function + """ + setattr(task_gen, func.__name__, func) + return func + +def feature(*k): + """ + Decorator that registers a task generator method that will be executed when the + object attribute ``feature`` contains the corresponding key(s):: + + from waflib.Task import feature + @feature('myfeature') + def myfunction(self): + print('that is my feature!') + def build(bld): + bld(features='myfeature') + + :param k: feature names + :type k: list of string + """ + def deco(func): + setattr(task_gen, func.__name__, func) + for name in k: + feats[name].update([func.__name__]) + return func + return deco + +def before_method(*k): + """ + Decorator that registera task generator method which will be executed + before the functions of given name(s):: + + from waflib.TaskGen import feature, before + @feature('myfeature') + @before_method('fun2') + def fun1(self): + print('feature 1!') + @feature('myfeature') + def fun2(self): + print('feature 2!') + def build(bld): + bld(features='myfeature') + + :param k: method names + :type k: list of string + """ + def deco(func): + setattr(task_gen, func.__name__, func) + for fun_name in k: + task_gen.prec[func.__name__].add(fun_name) + return func + return deco +before = before_method + +def after_method(*k): + """ + Decorator that registers a task generator method which will be executed + after the functions of given name(s):: + + from waflib.TaskGen import feature, after + @feature('myfeature') + @after_method('fun2') + def fun1(self): + print('feature 1!') + @feature('myfeature') + def fun2(self): + print('feature 2!') + def build(bld): + bld(features='myfeature') + + :param k: method names + :type k: list of string + """ + def deco(func): + setattr(task_gen, func.__name__, func) + for fun_name in k: + task_gen.prec[fun_name].add(func.__name__) + return func + return deco +after = after_method + +def extension(*k): + """ + Decorator that registers a task generator method which will be invoked during + the processing of source files for the extension given:: + + from waflib import Task + class mytask(Task): + run_str = 'cp ${SRC} ${TGT}' + @extension('.moo') + def create_maa_file(self, node): + self.create_task('mytask', node, node.change_ext('.maa')) + def build(bld): + bld(source='foo.moo') + """ + def deco(func): + setattr(task_gen, func.__name__, func) + for x in k: + task_gen.mappings[x] = func + return func + return deco + +@taskgen_method +def to_nodes(self, lst, path=None): + """ + Flatten the input list of string/nodes/lists into a list of nodes. + + It is used by :py:func:`waflib.TaskGen.process_source` and :py:func:`waflib.TaskGen.process_rule`. + It is designed for source files, for folders, see :py:func:`waflib.Tools.ccroot.to_incnodes`: + + :param lst: input list + :type lst: list of string and nodes + :param path: path from which to search the nodes (by default, :py:attr:`waflib.TaskGen.task_gen.path`) + :type path: :py:class:`waflib.Tools.Node.Node` + :rtype: list of :py:class:`waflib.Tools.Node.Node` + """ + tmp = [] + path = path or self.path + find = path.find_resource + + if isinstance(lst, Node.Node): + lst = [lst] + + for x in Utils.to_list(lst): + if isinstance(x, str): + node = find(x) + elif hasattr(x, 'name'): + node = x + else: + tmp.extend(self.to_nodes(x)) + continue + if not node: + raise Errors.WafError('source not found: %r in %r' % (x, self)) + tmp.append(node) + return tmp + +@feature('*') +def process_source(self): + """ + Processes each element in the attribute ``source`` by extension. + + #. The *source* list is converted through :py:meth:`waflib.TaskGen.to_nodes` to a list of :py:class:`waflib.Node.Node` first. + #. File extensions are mapped to methods having the signature: ``def meth(self, node)`` by :py:meth:`waflib.TaskGen.extension` + #. The method is retrieved through :py:meth:`waflib.TaskGen.task_gen.get_hook` + #. When called, the methods may modify self.source to append more source to process + #. The mappings can map an extension or a filename (see the code below) + """ + self.source = self.to_nodes(getattr(self, 'source', [])) + for node in self.source: + self.get_hook(node)(self, node) + +@feature('*') +@before_method('process_source') +def process_rule(self): + """ + Processes the attribute ``rule``. When present, :py:meth:`waflib.TaskGen.process_source` is disabled:: + + def build(bld): + bld(rule='cp ${SRC} ${TGT}', source='wscript', target='bar.txt') + + Main attributes processed: + + * rule: command to execute, it can be a tuple of strings for multiple commands + * chmod: permissions for the resulting files (integer value such as Utils.O755) + * shell: set to False to execute the command directly (default is True to use a shell) + * scan: scanner function + * vars: list of variables to trigger rebuilds, such as CFLAGS + * cls_str: string to display when executing the task + * cls_keyword: label to display when executing the task + * cache_rule: by default, try to re-use similar classes, set to False to disable + * source: list of Node or string objects representing the source files required by this task + * target: list of Node or string objects representing the files that this task creates + * cwd: current working directory (Node or string) + * stdout: standard output, set to None to prevent waf from capturing the text + * stderr: standard error, set to None to prevent waf from capturing the text + * timeout: timeout for command execution (Python 3) + * always: whether to always run the command (False by default) + * deep_inputs: whether the task must depend on the input file tasks too (False by default) + """ + if not getattr(self, 'rule', None): + return + + # create the task class + name = str(getattr(self, 'name', None) or self.target or getattr(self.rule, '__name__', self.rule)) + + # or we can put the class in a cache for performance reasons + try: + cache = self.bld.cache_rule_attr + except AttributeError: + cache = self.bld.cache_rule_attr = {} + + chmod = getattr(self, 'chmod', None) + shell = getattr(self, 'shell', True) + color = getattr(self, 'color', 'BLUE') + scan = getattr(self, 'scan', None) + _vars = getattr(self, 'vars', []) + cls_str = getattr(self, 'cls_str', None) + cls_keyword = getattr(self, 'cls_keyword', None) + use_cache = getattr(self, 'cache_rule', 'True') + deep_inputs = getattr(self, 'deep_inputs', False) + + scan_val = has_deps = hasattr(self, 'deps') + if scan: + scan_val = id(scan) + + key = Utils.h_list((name, self.rule, chmod, shell, color, cls_str, cls_keyword, scan_val, _vars, deep_inputs)) + + cls = None + if use_cache: + try: + cls = cache[key] + except KeyError: + pass + if not cls: + rule = self.rule + if chmod is not None: + def chmod_fun(tsk): + for x in tsk.outputs: + os.chmod(x.abspath(), tsk.generator.chmod) + if isinstance(rule, tuple): + rule = list(rule) + rule.append(chmod_fun) + rule = tuple(rule) + else: + rule = (rule, chmod_fun) + + cls = Task.task_factory(name, rule, _vars, shell=shell, color=color) + + if cls_str: + setattr(cls, '__str__', self.cls_str) + + if cls_keyword: + setattr(cls, 'keyword', self.cls_keyword) + + if deep_inputs: + Task.deep_inputs(cls) + + if scan: + cls.scan = self.scan + elif has_deps: + def scan(self): + nodes = [] + for x in self.generator.to_list(getattr(self.generator, 'deps', None)): + node = self.generator.path.find_resource(x) + if not node: + self.generator.bld.fatal('Could not find %r (was it declared?)' % x) + nodes.append(node) + return [nodes, []] + cls.scan = scan + + if use_cache: + cache[key] = cls + + # now create one instance + tsk = self.create_task(name) + + for x in ('after', 'before', 'ext_in', 'ext_out'): + setattr(tsk, x, getattr(self, x, [])) + + if hasattr(self, 'stdout'): + tsk.stdout = self.stdout + + if hasattr(self, 'stderr'): + tsk.stderr = self.stderr + + if getattr(self, 'timeout', None): + tsk.timeout = self.timeout + + if getattr(self, 'always', None): + tsk.always_run = True + + if getattr(self, 'target', None): + if isinstance(self.target, str): + self.target = self.target.split() + if not isinstance(self.target, list): + self.target = [self.target] + for x in self.target: + if isinstance(x, str): + tsk.outputs.append(self.path.find_or_declare(x)) + else: + x.parent.mkdir() # if a node was given, create the required folders + tsk.outputs.append(x) + if getattr(self, 'install_path', None): + self.install_task = self.add_install_files(install_to=self.install_path, + install_from=tsk.outputs, chmod=getattr(self, 'chmod', Utils.O644)) + + if getattr(self, 'source', None): + tsk.inputs = self.to_nodes(self.source) + # bypass the execution of process_source by setting the source to an empty list + self.source = [] + + if getattr(self, 'cwd', None): + tsk.cwd = self.cwd + + if isinstance(tsk.run, functools.partial): + # Python documentation says: "partial objects defined in classes + # behave like static methods and do not transform into bound + # methods during instance attribute look-up." + tsk.run = functools.partial(tsk.run, tsk) + +@feature('seq') +def sequence_order(self): + """ + Adds a strict sequential constraint between the tasks generated by task generators. + It works because task generators are posted in order. + It will not post objects which belong to other folders. + + Example:: + + bld(features='javac seq') + bld(features='jar seq') + + To start a new sequence, set the attribute seq_start, for example:: + + obj = bld(features='seq') + obj.seq_start = True + + Note that the method is executed in last position. This is more an + example than a widely-used solution. + """ + if self.meths and self.meths[-1] != 'sequence_order': + self.meths.append('sequence_order') + return + + if getattr(self, 'seq_start', None): + return + + # all the tasks previously declared must be run before these + if getattr(self.bld, 'prev', None): + self.bld.prev.post() + for x in self.bld.prev.tasks: + for y in self.tasks: + y.set_run_after(x) + + self.bld.prev = self + + +re_m4 = re.compile(r'@(\w+)@', re.M) + +class subst_pc(Task.Task): + """ + Creates *.pc* files from *.pc.in*. The task is executed whenever an input variable used + in the substitution changes. + """ + + def force_permissions(self): + "Private for the time being, we will probably refactor this into run_str=[run1,chmod]" + if getattr(self.generator, 'chmod', None): + for x in self.outputs: + os.chmod(x.abspath(), self.generator.chmod) + + def run(self): + "Substitutes variables in a .in file" + + if getattr(self.generator, 'is_copy', None): + for i, x in enumerate(self.outputs): + x.write(self.inputs[i].read('rb'), 'wb') + stat = os.stat(self.inputs[i].abspath()) # Preserve mtime of the copy + os.utime(self.outputs[i].abspath(), (stat.st_atime, stat.st_mtime)) + self.force_permissions() + return None + + if getattr(self.generator, 'fun', None): + ret = self.generator.fun(self) + if not ret: + self.force_permissions() + return ret + + code = self.inputs[0].read(encoding=getattr(self.generator, 'encoding', 'latin-1')) + if getattr(self.generator, 'subst_fun', None): + code = self.generator.subst_fun(self, code) + if code is not None: + self.outputs[0].write(code, encoding=getattr(self.generator, 'encoding', 'latin-1')) + self.force_permissions() + return None + + # replace all % by %% to prevent errors by % signs + code = code.replace('%', '%%') + + # extract the vars foo into lst and replace @foo@ by %(foo)s + lst = [] + def repl(match): + g = match.group + if g(1): + lst.append(g(1)) + return "%%(%s)s" % g(1) + return '' + code = getattr(self.generator, 're_m4', re_m4).sub(repl, code) + + try: + d = self.generator.dct + except AttributeError: + d = {} + for x in lst: + tmp = getattr(self.generator, x, '') or self.env[x] or self.env[x.upper()] + try: + tmp = ''.join(tmp) + except TypeError: + tmp = str(tmp) + d[x] = tmp + + code = code % d + self.outputs[0].write(code, encoding=getattr(self.generator, 'encoding', 'latin-1')) + self.generator.bld.raw_deps[self.uid()] = lst + + # make sure the signature is updated + try: + delattr(self, 'cache_sig') + except AttributeError: + pass + + self.force_permissions() + + def sig_vars(self): + """ + Compute a hash (signature) of the variables used in the substitution + """ + bld = self.generator.bld + env = self.env + upd = self.m.update + + if getattr(self.generator, 'fun', None): + upd(Utils.h_fun(self.generator.fun).encode()) + if getattr(self.generator, 'subst_fun', None): + upd(Utils.h_fun(self.generator.subst_fun).encode()) + + # raw_deps: persistent custom values returned by the scanner + vars = self.generator.bld.raw_deps.get(self.uid(), []) + + # hash both env vars and task generator attributes + act_sig = bld.hash_env_vars(env, vars) + upd(act_sig) + + lst = [getattr(self.generator, x, '') for x in vars] + upd(Utils.h_list(lst)) + + return self.m.digest() + +@extension('.pc.in') +def add_pcfile(self, node): + """ + Processes *.pc.in* files to *.pc*. Installs the results to ``${PREFIX}/lib/pkgconfig/`` by default + + def build(bld): + bld(source='foo.pc.in', install_path='${LIBDIR}/pkgconfig/') + """ + tsk = self.create_task('subst_pc', node, node.change_ext('.pc', '.pc.in')) + self.install_task = self.add_install_files( + install_to=getattr(self, 'install_path', '${LIBDIR}/pkgconfig/'), install_from=tsk.outputs) + +class subst(subst_pc): + pass + +@feature('subst') +@before_method('process_source', 'process_rule') +def process_subst(self): + """ + Defines a transformation that substitutes the contents of *source* files to *target* files:: + + def build(bld): + bld( + features='subst', + source='foo.c.in', + target='foo.c', + install_path='${LIBDIR}/pkgconfig', + VAR = 'val' + ) + + The input files are supposed to contain macros of the form *@VAR@*, where *VAR* is an argument + of the task generator object. + + This method overrides the processing by :py:meth:`waflib.TaskGen.process_source`. + """ + + src = Utils.to_list(getattr(self, 'source', [])) + if isinstance(src, Node.Node): + src = [src] + tgt = Utils.to_list(getattr(self, 'target', [])) + if isinstance(tgt, Node.Node): + tgt = [tgt] + if len(src) != len(tgt): + raise Errors.WafError('invalid number of source/target for %r' % self) + + for x, y in zip(src, tgt): + if not x or not y: + raise Errors.WafError('null source or target for %r' % self) + a, b = None, None + + if isinstance(x, str) and isinstance(y, str) and x == y: + a = self.path.find_node(x) + b = self.path.get_bld().make_node(y) + if not os.path.isfile(b.abspath()): + b.parent.mkdir() + else: + if isinstance(x, str): + a = self.path.find_resource(x) + elif isinstance(x, Node.Node): + a = x + if isinstance(y, str): + b = self.path.find_or_declare(y) + elif isinstance(y, Node.Node): + b = y + + if not a: + raise Errors.WafError('could not find %r for %r' % (x, self)) + + tsk = self.create_task('subst', a, b) + for k in ('after', 'before', 'ext_in', 'ext_out'): + val = getattr(self, k, None) + if val: + setattr(tsk, k, val) + + # paranoid safety measure for the general case foo.in->foo.h with ambiguous dependencies + for xt in HEADER_EXTS: + if b.name.endswith(xt): + tsk.ext_out = tsk.ext_out + ['.h'] + break + + inst_to = getattr(self, 'install_path', None) + if inst_to: + self.install_task = self.add_install_files(install_to=inst_to, + install_from=b, chmod=getattr(self, 'chmod', Utils.O644)) + + self.source = [] + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/__init__.py b/ldb-2.0.8/third_party/waf/waflib/Tools/__init__.py new file mode 100644 index 0000000..079df35 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/__init__.py @@ -0,0 +1,3 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2005-2018 (ita) diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/ar.py b/ldb-2.0.8/third_party/waf/waflib/Tools/ar.py new file mode 100644 index 0000000..b39b645 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/ar.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2006-2018 (ita) +# Ralf Habacker, 2006 (rh) + +""" +The **ar** program creates static libraries. This tool is almost always loaded +from others (C, C++, D, etc) for static library support. +""" + +from waflib.Configure import conf + +@conf +def find_ar(conf): + """Configuration helper used by C/C++ tools to enable the support for static libraries""" + conf.load('ar') + +def configure(conf): + """Finds the ar program and sets the default flags in ``conf.env.ARFLAGS``""" + conf.find_program('ar', var='AR') + conf.add_os_flags('ARFLAGS') + if not conf.env.ARFLAGS: + conf.env.ARFLAGS = ['rcs'] + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/asm.py b/ldb-2.0.8/third_party/waf/waflib/Tools/asm.py new file mode 100644 index 0000000..a57e83b --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/asm.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2008-2018 (ita) + +""" +Assembly support, used by tools such as gas and nasm + +To declare targets using assembly:: + + def configure(conf): + conf.load('gcc gas') + + def build(bld): + bld( + features='c cstlib asm', + source = 'test.S', + target = 'asmtest') + + bld( + features='asm asmprogram', + source = 'test.S', + target = 'asmtest') + +Support for pure asm programs and libraries should also work:: + + def configure(conf): + conf.load('nasm') + conf.find_program('ld', 'ASLINK') + + def build(bld): + bld( + features='asm asmprogram', + source = 'test.S', + target = 'asmtest') +""" + +import re +from waflib import Errors, Logs, Task +from waflib.Tools.ccroot import link_task, stlink_task +from waflib.TaskGen import extension +from waflib.Tools import c_preproc + +re_lines = re.compile( + '^[ \t]*(?:%)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef)[ \t]*(.*)\r*$', + re.IGNORECASE | re.MULTILINE) + +class asm_parser(c_preproc.c_parser): + def filter_comments(self, node): + code = node.read() + code = c_preproc.re_nl.sub('', code) + code = c_preproc.re_cpp.sub(c_preproc.repl, code) + return re_lines.findall(code) + +class asm(Task.Task): + """ + Compiles asm files by gas/nasm/yasm/... + """ + color = 'BLUE' + run_str = '${AS} ${ASFLAGS} ${ASMPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${AS_SRC_F}${SRC} ${AS_TGT_F}${TGT}' + + def scan(self): + if self.env.ASM_NAME == 'gas': + return c_preproc.scan(self) + Logs.warn('There is no dependency scanner for Nasm!') + return [[], []] + elif self.env.ASM_NAME == 'nasm': + Logs.warn('The Nasm dependency scanner is incomplete!') + + try: + incn = self.generator.includes_nodes + except AttributeError: + raise Errors.WafError('%r is missing the "asm" feature' % self.generator) + + if c_preproc.go_absolute: + nodepaths = incn + else: + nodepaths = [x for x in incn if x.is_child_of(x.ctx.srcnode) or x.is_child_of(x.ctx.bldnode)] + + tmp = asm_parser(nodepaths) + tmp.start(self.inputs[0], self.env) + return (tmp.nodes, tmp.names) + +@extension('.s', '.S', '.asm', '.ASM', '.spp', '.SPP') +def asm_hook(self, node): + """ + Binds the asm extension to the asm task + + :param node: input file + :type node: :py:class:`waflib.Node.Node` + """ + return self.create_compiled_task('asm', node) + +class asmprogram(link_task): + "Links object files into a c program" + run_str = '${ASLINK} ${ASLINKFLAGS} ${ASLNK_TGT_F}${TGT} ${ASLNK_SRC_F}${SRC}' + ext_out = ['.bin'] + inst_to = '${BINDIR}' + +class asmshlib(asmprogram): + "Links object files into a c shared library" + inst_to = '${LIBDIR}' + +class asmstlib(stlink_task): + "Links object files into a c static library" + pass # do not remove + +def configure(conf): + conf.env.ASMPATH_ST = '-I%s' diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/bison.py b/ldb-2.0.8/third_party/waf/waflib/Tools/bison.py new file mode 100644 index 0000000..eef56dc --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/bison.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +# encoding: utf-8 +# John O'Meara, 2006 +# Thomas Nagy 2009-2018 (ita) + +""" +The **bison** program is a code generator which creates C or C++ files. +The generated files are compiled into object files. +""" + +from waflib import Task +from waflib.TaskGen import extension + +class bison(Task.Task): + """Compiles bison files""" + color = 'BLUE' + run_str = '${BISON} ${BISONFLAGS} ${SRC[0].abspath()} -o ${TGT[0].name}' + ext_out = ['.h'] # just to make sure + +@extension('.y', '.yc', '.yy') +def big_bison(self, node): + """ + Creates a bison task, which must be executed from the directory of the output file. + """ + has_h = '-d' in self.env.BISONFLAGS + + outs = [] + if node.name.endswith('.yc'): + outs.append(node.change_ext('.tab.cc')) + if has_h: + outs.append(node.change_ext('.tab.hh')) + else: + outs.append(node.change_ext('.tab.c')) + if has_h: + outs.append(node.change_ext('.tab.h')) + + tsk = self.create_task('bison', node, outs) + tsk.cwd = node.parent.get_bld() + + # and the c/cxx file must be compiled too + self.source.append(outs[0]) + +def configure(conf): + """ + Detects the *bison* program + """ + conf.find_program('bison', var='BISON') + conf.env.BISONFLAGS = ['-d'] + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/c.py b/ldb-2.0.8/third_party/waf/waflib/Tools/c.py new file mode 100644 index 0000000..effd6b6 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/c.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2006-2018 (ita) + +"Base for c programs/libraries" + +from waflib import TaskGen, Task +from waflib.Tools import c_preproc +from waflib.Tools.ccroot import link_task, stlink_task + +@TaskGen.extension('.c') +def c_hook(self, node): + "Binds the c file extensions create :py:class:`waflib.Tools.c.c` instances" + if not self.env.CC and self.env.CXX: + return self.create_compiled_task('cxx', node) + return self.create_compiled_task('c', node) + +class c(Task.Task): + "Compiles C files into object files" + run_str = '${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CC_SRC_F}${SRC} ${CC_TGT_F}${TGT[0].abspath()} ${CPPFLAGS}' + vars = ['CCDEPS'] # unused variable to depend on, just in case + ext_in = ['.h'] # set the build order easily by using ext_out=['.h'] + scan = c_preproc.scan + +class cprogram(link_task): + "Links object files into c programs" + run_str = '${LINK_CC} ${LINKFLAGS} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LDFLAGS}' + ext_out = ['.bin'] + vars = ['LINKDEPS'] + inst_to = '${BINDIR}' + +class cshlib(cprogram): + "Links object files into c shared libraries" + inst_to = '${LIBDIR}' + +class cstlib(stlink_task): + "Links object files into a c static libraries" + pass # do not remove + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/c_aliases.py b/ldb-2.0.8/third_party/waf/waflib/Tools/c_aliases.py new file mode 100644 index 0000000..985e048 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/c_aliases.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2005-2015 (ita) + +"base for all c/c++ programs and libraries" + +from waflib import Utils, Errors +from waflib.Configure import conf + +def get_extensions(lst): + """ + Returns the file extensions for the list of files given as input + + :param lst: files to process + :list lst: list of string or :py:class:`waflib.Node.Node` + :return: list of file extensions + :rtype: list of string + """ + ret = [] + for x in Utils.to_list(lst): + if not isinstance(x, str): + x = x.name + ret.append(x[x.rfind('.') + 1:]) + return ret + +def sniff_features(**kw): + """ + Computes and returns the features required for a task generator by + looking at the file extensions. This aimed for C/C++ mainly:: + + snif_features(source=['foo.c', 'foo.cxx'], type='shlib') + # returns ['cxx', 'c', 'cxxshlib', 'cshlib'] + + :param source: source files to process + :type source: list of string or :py:class:`waflib.Node.Node` + :param type: object type in *program*, *shlib* or *stlib* + :type type: string + :return: the list of features for a task generator processing the source files + :rtype: list of string + """ + exts = get_extensions(kw['source']) + typ = kw['typ'] + feats = [] + + # watch the order, cxx will have the precedence + for x in 'cxx cpp c++ cc C'.split(): + if x in exts: + feats.append('cxx') + break + if 'c' in exts or 'vala' in exts or 'gs' in exts: + feats.append('c') + + if 's' in exts or 'S' in exts: + feats.append('asm') + + for x in 'f f90 F F90 for FOR'.split(): + if x in exts: + feats.append('fc') + break + + if 'd' in exts: + feats.append('d') + + if 'java' in exts: + feats.append('java') + return 'java' + + if typ in ('program', 'shlib', 'stlib'): + will_link = False + for x in feats: + if x in ('cxx', 'd', 'fc', 'c', 'asm'): + feats.append(x + typ) + will_link = True + if not will_link and not kw.get('features', []): + raise Errors.WafError('Cannot link from %r, try passing eg: features="c cprogram"?' % kw) + return feats + +def set_features(kw, typ): + """ + Inserts data in the input dict *kw* based on existing data and on the type of target + required (typ). + + :param kw: task generator parameters + :type kw: dict + :param typ: type of target + :type typ: string + """ + kw['typ'] = typ + kw['features'] = Utils.to_list(kw.get('features', [])) + Utils.to_list(sniff_features(**kw)) + +@conf +def program(bld, *k, **kw): + """ + Alias for creating programs by looking at the file extensions:: + + def build(bld): + bld.program(source='foo.c', target='app') + # equivalent to: + # bld(features='c cprogram', source='foo.c', target='app') + + """ + set_features(kw, 'program') + return bld(*k, **kw) + +@conf +def shlib(bld, *k, **kw): + """ + Alias for creating shared libraries by looking at the file extensions:: + + def build(bld): + bld.shlib(source='foo.c', target='app') + # equivalent to: + # bld(features='c cshlib', source='foo.c', target='app') + + """ + set_features(kw, 'shlib') + return bld(*k, **kw) + +@conf +def stlib(bld, *k, **kw): + """ + Alias for creating static libraries by looking at the file extensions:: + + def build(bld): + bld.stlib(source='foo.cpp', target='app') + # equivalent to: + # bld(features='cxx cxxstlib', source='foo.cpp', target='app') + + """ + set_features(kw, 'stlib') + return bld(*k, **kw) + +@conf +def objects(bld, *k, **kw): + """ + Alias for creating object files by looking at the file extensions:: + + def build(bld): + bld.objects(source='foo.c', target='app') + # equivalent to: + # bld(features='c', source='foo.c', target='app') + + """ + set_features(kw, 'objects') + return bld(*k, **kw) + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/c_config.py b/ldb-2.0.8/third_party/waf/waflib/Tools/c_config.py new file mode 100644 index 0000000..80580cc --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/c_config.py @@ -0,0 +1,1352 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2005-2018 (ita) + +""" +C/C++/D configuration helpers +""" + +from __future__ import with_statement + +import os, re, shlex +from waflib import Build, Utils, Task, Options, Logs, Errors, Runner +from waflib.TaskGen import after_method, feature +from waflib.Configure import conf + +WAF_CONFIG_H = 'config.h' +"""default name for the config.h file""" + +DEFKEYS = 'define_key' +INCKEYS = 'include_key' + +SNIP_EMPTY_PROGRAM = ''' +int main(int argc, char **argv) { + (void)argc; (void)argv; + return 0; +} +''' + +MACRO_TO_DESTOS = { +'__linux__' : 'linux', +'__GNU__' : 'gnu', # hurd +'__FreeBSD__' : 'freebsd', +'__NetBSD__' : 'netbsd', +'__OpenBSD__' : 'openbsd', +'__sun' : 'sunos', +'__hpux' : 'hpux', +'__sgi' : 'irix', +'_AIX' : 'aix', +'__CYGWIN__' : 'cygwin', +'__MSYS__' : 'cygwin', +'_UWIN' : 'uwin', +'_WIN64' : 'win32', +'_WIN32' : 'win32', +# Note about darwin: this is also tested with 'defined __APPLE__ && defined __MACH__' somewhere below in this file. +'__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' : 'darwin', +'__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__' : 'darwin', # iphone +'__QNX__' : 'qnx', +'__native_client__' : 'nacl' # google native client platform +} + +MACRO_TO_DEST_CPU = { +'__x86_64__' : 'x86_64', +'__amd64__' : 'x86_64', +'__i386__' : 'x86', +'__ia64__' : 'ia', +'__mips__' : 'mips', +'__sparc__' : 'sparc', +'__alpha__' : 'alpha', +'__aarch64__' : 'aarch64', +'__thumb__' : 'thumb', +'__arm__' : 'arm', +'__hppa__' : 'hppa', +'__powerpc__' : 'powerpc', +'__ppc__' : 'powerpc', +'__convex__' : 'convex', +'__m68k__' : 'm68k', +'__s390x__' : 's390x', +'__s390__' : 's390', +'__sh__' : 'sh', +'__xtensa__' : 'xtensa', +} + +@conf +def parse_flags(self, line, uselib_store, env=None, force_static=False, posix=None): + """ + Parses flags from the input lines, and adds them to the relevant use variables:: + + def configure(conf): + conf.parse_flags('-O3', 'FOO') + # conf.env.CXXFLAGS_FOO = ['-O3'] + # conf.env.CFLAGS_FOO = ['-O3'] + + :param line: flags + :type line: string + :param uselib_store: where to add the flags + :type uselib_store: string + :param env: config set or conf.env by default + :type env: :py:class:`waflib.ConfigSet.ConfigSet` + """ + + assert(isinstance(line, str)) + + env = env or self.env + + # Issue 811 and 1371 + if posix is None: + posix = True + if '\\' in line: + posix = ('\\ ' in line) or ('\\\\' in line) + + lex = shlex.shlex(line, posix=posix) + lex.whitespace_split = True + lex.commenters = '' + lst = list(lex) + + # append_unique is not always possible + # for example, apple flags may require both -arch i386 and -arch ppc + uselib = uselib_store + def app(var, val): + env.append_value('%s_%s' % (var, uselib), val) + def appu(var, val): + env.append_unique('%s_%s' % (var, uselib), val) + static = False + while lst: + x = lst.pop(0) + st = x[:2] + ot = x[2:] + + if st == '-I' or st == '/I': + if not ot: + ot = lst.pop(0) + appu('INCLUDES', ot) + elif st == '-i': + tmp = [x, lst.pop(0)] + app('CFLAGS', tmp) + app('CXXFLAGS', tmp) + elif st == '-D' or (env.CXX_NAME == 'msvc' and st == '/D'): # not perfect but.. + if not ot: + ot = lst.pop(0) + app('DEFINES', ot) + elif st == '-l': + if not ot: + ot = lst.pop(0) + prefix = 'STLIB' if (force_static or static) else 'LIB' + app(prefix, ot) + elif st == '-L': + if not ot: + ot = lst.pop(0) + prefix = 'STLIBPATH' if (force_static or static) else 'LIBPATH' + appu(prefix, ot) + elif x.startswith('/LIBPATH:'): + prefix = 'STLIBPATH' if (force_static or static) else 'LIBPATH' + appu(prefix, x.replace('/LIBPATH:', '')) + elif x.startswith('-std='): + prefix = 'CXXFLAGS' if '++' in x else 'CFLAGS' + app(prefix, x) + elif x.startswith('+') or x in ('-pthread', '-fPIC', '-fpic', '-fPIE', '-fpie'): + app('CFLAGS', x) + app('CXXFLAGS', x) + app('LINKFLAGS', x) + elif x == '-framework': + appu('FRAMEWORK', lst.pop(0)) + elif x.startswith('-F'): + appu('FRAMEWORKPATH', x[2:]) + elif x == '-Wl,-rpath' or x == '-Wl,-R': + app('RPATH', lst.pop(0).lstrip('-Wl,')) + elif x.startswith('-Wl,-R,'): + app('RPATH', x[7:]) + elif x.startswith('-Wl,-R'): + app('RPATH', x[6:]) + elif x.startswith('-Wl,-rpath,'): + app('RPATH', x[11:]) + elif x == '-Wl,-Bstatic' or x == '-Bstatic': + static = True + elif x == '-Wl,-Bdynamic' or x == '-Bdynamic': + static = False + elif x.startswith('-Wl') or x in ('-rdynamic', '-pie'): + app('LINKFLAGS', x) + elif x.startswith(('-m', '-f', '-dynamic', '-O', '-g')): + # Adding the -W option breaks python builds on Openindiana + app('CFLAGS', x) + app('CXXFLAGS', x) + elif x.startswith('-bundle'): + app('LINKFLAGS', x) + elif x.startswith(('-undefined', '-Xlinker')): + arg = lst.pop(0) + app('LINKFLAGS', [x, arg]) + elif x.startswith(('-arch', '-isysroot')): + tmp = [x, lst.pop(0)] + app('CFLAGS', tmp) + app('CXXFLAGS', tmp) + app('LINKFLAGS', tmp) + elif x.endswith(('.a', '.so', '.dylib', '.lib')): + appu('LINKFLAGS', x) # not cool, #762 + else: + self.to_log('Unhandled flag %r' % x) + +@conf +def validate_cfg(self, kw): + """ + Searches for the program *pkg-config* if missing, and validates the + parameters to pass to :py:func:`waflib.Tools.c_config.exec_cfg`. + + :param path: the **-config program to use** (default is *pkg-config*) + :type path: list of string + :param msg: message to display to describe the test executed + :type msg: string + :param okmsg: message to display when the test is successful + :type okmsg: string + :param errmsg: message to display in case of error + :type errmsg: string + """ + if not 'path' in kw: + if not self.env.PKGCONFIG: + self.find_program('pkg-config', var='PKGCONFIG') + kw['path'] = self.env.PKGCONFIG + + # verify that exactly one action is requested + s = ('atleast_pkgconfig_version' in kw) + ('modversion' in kw) + ('package' in kw) + if s != 1: + raise ValueError('exactly one of atleast_pkgconfig_version, modversion and package must be set') + if not 'msg' in kw: + if 'atleast_pkgconfig_version' in kw: + kw['msg'] = 'Checking for pkg-config version >= %r' % kw['atleast_pkgconfig_version'] + elif 'modversion' in kw: + kw['msg'] = 'Checking for %r version' % kw['modversion'] + else: + kw['msg'] = 'Checking for %r' %(kw['package']) + + # let the modversion check set the okmsg to the detected version + if not 'okmsg' in kw and not 'modversion' in kw: + kw['okmsg'] = 'yes' + if not 'errmsg' in kw: + kw['errmsg'] = 'not found' + + # pkg-config version + if 'atleast_pkgconfig_version' in kw: + pass + elif 'modversion' in kw: + if not 'uselib_store' in kw: + kw['uselib_store'] = kw['modversion'] + if not 'define_name' in kw: + kw['define_name'] = '%s_VERSION' % Utils.quote_define_name(kw['uselib_store']) + else: + if not 'uselib_store' in kw: + kw['uselib_store'] = Utils.to_list(kw['package'])[0].upper() + if not 'define_name' in kw: + kw['define_name'] = self.have_define(kw['uselib_store']) + +@conf +def exec_cfg(self, kw): + """ + Executes ``pkg-config`` or other ``-config`` applications to collect configuration flags: + + * if atleast_pkgconfig_version is given, check that pkg-config has the version n and return + * if modversion is given, then return the module version + * else, execute the *-config* program with the *args* and *variables* given, and set the flags on the *conf.env.FLAGS_name* variable + + :param atleast_pkgconfig_version: minimum pkg-config version to use (disable other tests) + :type atleast_pkgconfig_version: string + :param package: package name, for example *gtk+-2.0* + :type package: string + :param uselib_store: if the test is successful, define HAVE\\_*name*. It is also used to define *conf.env.FLAGS_name* variables. + :type uselib_store: string + :param modversion: if provided, return the version of the given module and define *name*\\_VERSION + :type modversion: string + :param args: arguments to give to *package* when retrieving flags + :type args: list of string + :param variables: return the values of particular variables + :type variables: list of string + :param define_variable: additional variables to define (also in conf.env.PKG_CONFIG_DEFINES) + :type define_variable: dict(string: string) + """ + + path = Utils.to_list(kw['path']) + env = self.env.env or None + if kw.get('pkg_config_path'): + if not env: + env = dict(self.environ) + env['PKG_CONFIG_PATH'] = kw['pkg_config_path'] + + def define_it(): + define_name = kw['define_name'] + # by default, add HAVE_X to the config.h, else provide DEFINES_X for use=X + if kw.get('global_define', 1): + self.define(define_name, 1, False) + else: + self.env.append_unique('DEFINES_%s' % kw['uselib_store'], "%s=1" % define_name) + + if kw.get('add_have_to_env', 1): + self.env[define_name] = 1 + + # pkg-config version + if 'atleast_pkgconfig_version' in kw: + cmd = path + ['--atleast-pkgconfig-version=%s' % kw['atleast_pkgconfig_version']] + self.cmd_and_log(cmd, env=env) + return + + # single version for a module + if 'modversion' in kw: + version = self.cmd_and_log(path + ['--modversion', kw['modversion']], env=env).strip() + if not 'okmsg' in kw: + kw['okmsg'] = version + self.define(kw['define_name'], version) + return version + + lst = [] + path + + defi = kw.get('define_variable') + if not defi: + defi = self.env.PKG_CONFIG_DEFINES or {} + for key, val in defi.items(): + lst.append('--define-variable=%s=%s' % (key, val)) + + static = kw.get('force_static', False) + if 'args' in kw: + args = Utils.to_list(kw['args']) + if '--static' in args or '--static-libs' in args: + static = True + lst += args + + # tools like pkgconf expect the package argument after the -- ones -_- + lst.extend(Utils.to_list(kw['package'])) + + # retrieving variables of a module + if 'variables' in kw: + v_env = kw.get('env', self.env) + vars = Utils.to_list(kw['variables']) + for v in vars: + val = self.cmd_and_log(lst + ['--variable=' + v], env=env).strip() + var = '%s_%s' % (kw['uselib_store'], v) + v_env[var] = val + return + + # so we assume the command-line will output flags to be parsed afterwards + ret = self.cmd_and_log(lst, env=env) + + define_it() + self.parse_flags(ret, kw['uselib_store'], kw.get('env', self.env), force_static=static, posix=kw.get('posix')) + return ret + +@conf +def check_cfg(self, *k, **kw): + """ + Checks for configuration flags using a **-config**-like program (pkg-config, sdl-config, etc). + This wraps internal calls to :py:func:`waflib.Tools.c_config.validate_cfg` and :py:func:`waflib.Tools.c_config.exec_cfg` + + A few examples:: + + def configure(conf): + conf.load('compiler_c') + conf.check_cfg(package='glib-2.0', args='--libs --cflags') + conf.check_cfg(package='pango') + conf.check_cfg(package='pango', uselib_store='MYPANGO', args=['--cflags', '--libs']) + conf.check_cfg(package='pango', + args=['pango >= 0.1.0', 'pango < 9.9.9', '--cflags', '--libs'], + msg="Checking for 'pango 0.1.0'") + conf.check_cfg(path='sdl-config', args='--cflags --libs', package='', uselib_store='SDL') + conf.check_cfg(path='mpicc', args='--showme:compile --showme:link', + package='', uselib_store='OPEN_MPI', mandatory=False) + # variables + conf.check_cfg(package='gtk+-2.0', variables=['includedir', 'prefix'], uselib_store='FOO') + print(conf.env.FOO_includedir) + """ + self.validate_cfg(kw) + if 'msg' in kw: + self.start_msg(kw['msg'], **kw) + ret = None + try: + ret = self.exec_cfg(kw) + except self.errors.WafError as e: + if 'errmsg' in kw: + self.end_msg(kw['errmsg'], 'YELLOW', **kw) + if Logs.verbose > 1: + self.to_log('Command failure: %s' % e) + self.fatal('The configuration failed') + else: + if not ret: + ret = True + kw['success'] = ret + if 'okmsg' in kw: + self.end_msg(self.ret_msg(kw['okmsg'], kw), **kw) + + return ret + +def build_fun(bld): + """ + Build function that is used for running configuration tests with ``conf.check()`` + """ + if bld.kw['compile_filename']: + node = bld.srcnode.make_node(bld.kw['compile_filename']) + node.write(bld.kw['code']) + + o = bld(features=bld.kw['features'], source=bld.kw['compile_filename'], target='testprog') + + for k, v in bld.kw.items(): + setattr(o, k, v) + + if not bld.kw.get('quiet'): + bld.conf.to_log("==>\n%s\n<==" % bld.kw['code']) + +@conf +def validate_c(self, kw): + """ + Pre-checks the parameters that will be given to :py:func:`waflib.Configure.run_build` + + :param compiler: c or cxx (tries to guess what is best) + :type compiler: string + :param type: cprogram, cshlib, cstlib - not required if *features are given directly* + :type type: binary to create + :param feature: desired features for the task generator that will execute the test, for example ``cxx cxxstlib`` + :type feature: list of string + :param fragment: provide a piece of code for the test (default is to let the system create one) + :type fragment: string + :param uselib_store: define variables after the test is executed (IMPORTANT!) + :type uselib_store: string + :param use: parameters to use for building (just like the normal *use* keyword) + :type use: list of string + :param define_name: define to set when the check is over + :type define_name: string + :param execute: execute the resulting binary + :type execute: bool + :param define_ret: if execute is set to True, use the execution output in both the define and the return value + :type define_ret: bool + :param header_name: check for a particular header + :type header_name: string + :param auto_add_header_name: if header_name was set, add the headers in env.INCKEYS so the next tests will include these headers + :type auto_add_header_name: bool + """ + for x in ('type_name', 'field_name', 'function_name'): + if x in kw: + Logs.warn('Invalid argument %r in test' % x) + + if not 'build_fun' in kw: + kw['build_fun'] = build_fun + + if not 'env' in kw: + kw['env'] = self.env.derive() + env = kw['env'] + + if not 'compiler' in kw and not 'features' in kw: + kw['compiler'] = 'c' + if env.CXX_NAME and Task.classes.get('cxx'): + kw['compiler'] = 'cxx' + if not self.env.CXX: + self.fatal('a c++ compiler is required') + else: + if not self.env.CC: + self.fatal('a c compiler is required') + + if not 'compile_mode' in kw: + kw['compile_mode'] = 'c' + if 'cxx' in Utils.to_list(kw.get('features', [])) or kw.get('compiler') == 'cxx': + kw['compile_mode'] = 'cxx' + + if not 'type' in kw: + kw['type'] = 'cprogram' + + if not 'features' in kw: + if not 'header_name' in kw or kw.get('link_header_test', True): + kw['features'] = [kw['compile_mode'], kw['type']] # "c ccprogram" + else: + kw['features'] = [kw['compile_mode']] + else: + kw['features'] = Utils.to_list(kw['features']) + + if not 'compile_filename' in kw: + kw['compile_filename'] = 'test.c' + ((kw['compile_mode'] == 'cxx') and 'pp' or '') + + def to_header(dct): + if 'header_name' in dct: + dct = Utils.to_list(dct['header_name']) + return ''.join(['#include <%s>\n' % x for x in dct]) + return '' + + if 'framework_name' in kw: + # OSX, not sure this is used anywhere + fwkname = kw['framework_name'] + if not 'uselib_store' in kw: + kw['uselib_store'] = fwkname.upper() + if not kw.get('no_header'): + fwk = '%s/%s.h' % (fwkname, fwkname) + if kw.get('remove_dot_h'): + fwk = fwk[:-2] + val = kw.get('header_name', []) + kw['header_name'] = Utils.to_list(val) + [fwk] + kw['msg'] = 'Checking for framework %s' % fwkname + kw['framework'] = fwkname + + elif 'header_name' in kw: + if not 'msg' in kw: + kw['msg'] = 'Checking for header %s' % kw['header_name'] + + l = Utils.to_list(kw['header_name']) + assert len(l), 'list of headers in header_name is empty' + + kw['code'] = to_header(kw) + SNIP_EMPTY_PROGRAM + if not 'uselib_store' in kw: + kw['uselib_store'] = l[0].upper() + if not 'define_name' in kw: + kw['define_name'] = self.have_define(l[0]) + + if 'lib' in kw: + if not 'msg' in kw: + kw['msg'] = 'Checking for library %s' % kw['lib'] + if not 'uselib_store' in kw: + kw['uselib_store'] = kw['lib'].upper() + + if 'stlib' in kw: + if not 'msg' in kw: + kw['msg'] = 'Checking for static library %s' % kw['stlib'] + if not 'uselib_store' in kw: + kw['uselib_store'] = kw['stlib'].upper() + + if 'fragment' in kw: + # an additional code fragment may be provided to replace the predefined code + # in custom headers + kw['code'] = kw['fragment'] + if not 'msg' in kw: + kw['msg'] = 'Checking for code snippet' + if not 'errmsg' in kw: + kw['errmsg'] = 'no' + + for (flagsname,flagstype) in (('cxxflags','compiler'), ('cflags','compiler'), ('linkflags','linker')): + if flagsname in kw: + if not 'msg' in kw: + kw['msg'] = 'Checking for %s flags %s' % (flagstype, kw[flagsname]) + if not 'errmsg' in kw: + kw['errmsg'] = 'no' + + if not 'execute' in kw: + kw['execute'] = False + if kw['execute']: + kw['features'].append('test_exec') + kw['chmod'] = Utils.O755 + + if not 'errmsg' in kw: + kw['errmsg'] = 'not found' + + if not 'okmsg' in kw: + kw['okmsg'] = 'yes' + + if not 'code' in kw: + kw['code'] = SNIP_EMPTY_PROGRAM + + # if there are headers to append automatically to the next tests + if self.env[INCKEYS]: + kw['code'] = '\n'.join(['#include <%s>' % x for x in self.env[INCKEYS]]) + '\n' + kw['code'] + + # in case defines lead to very long command-lines + if kw.get('merge_config_header') or env.merge_config_header: + kw['code'] = '%s\n\n%s' % (self.get_config_header(), kw['code']) + env.DEFINES = [] # modify the copy + + if not kw.get('success'): + kw['success'] = None + + if 'define_name' in kw: + self.undefine(kw['define_name']) + if not 'msg' in kw: + self.fatal('missing "msg" in conf.check(...)') + +@conf +def post_check(self, *k, **kw): + """ + Sets the variables after a test executed in + :py:func:`waflib.Tools.c_config.check` was run successfully + """ + is_success = 0 + if kw['execute']: + if kw['success'] is not None: + if kw.get('define_ret'): + is_success = kw['success'] + else: + is_success = (kw['success'] == 0) + else: + is_success = (kw['success'] == 0) + + if kw.get('define_name'): + comment = kw.get('comment', '') + define_name = kw['define_name'] + if kw['execute'] and kw.get('define_ret') and isinstance(is_success, str): + if kw.get('global_define', 1): + self.define(define_name, is_success, quote=kw.get('quote', 1), comment=comment) + else: + if kw.get('quote', 1): + succ = '"%s"' % is_success + else: + succ = int(is_success) + val = '%s=%s' % (define_name, succ) + var = 'DEFINES_%s' % kw['uselib_store'] + self.env.append_value(var, val) + else: + if kw.get('global_define', 1): + self.define_cond(define_name, is_success, comment=comment) + else: + var = 'DEFINES_%s' % kw['uselib_store'] + self.env.append_value(var, '%s=%s' % (define_name, int(is_success))) + + # define conf.env.HAVE_X to 1 + if kw.get('add_have_to_env', 1): + if kw.get('uselib_store'): + self.env[self.have_define(kw['uselib_store'])] = 1 + elif kw['execute'] and kw.get('define_ret'): + self.env[define_name] = is_success + else: + self.env[define_name] = int(is_success) + + if 'header_name' in kw: + if kw.get('auto_add_header_name'): + self.env.append_value(INCKEYS, Utils.to_list(kw['header_name'])) + + if is_success and 'uselib_store' in kw: + from waflib.Tools import ccroot + # See get_uselib_vars in ccroot.py + _vars = set() + for x in kw['features']: + if x in ccroot.USELIB_VARS: + _vars |= ccroot.USELIB_VARS[x] + + for k in _vars: + x = k.lower() + if x in kw: + self.env.append_value(k + '_' + kw['uselib_store'], kw[x]) + return is_success + +@conf +def check(self, *k, **kw): + """ + Performs a configuration test by calling :py:func:`waflib.Configure.run_build`. + For the complete list of parameters, see :py:func:`waflib.Tools.c_config.validate_c`. + To force a specific compiler, pass ``compiler='c'`` or ``compiler='cxx'`` to the list of arguments + + Besides build targets, complete builds can be given through a build function. All files will + be written to a temporary directory:: + + def build(bld): + lib_node = bld.srcnode.make_node('libdir/liblc1.c') + lib_node.parent.mkdir() + lib_node.write('#include \\nint lib_func(void) { FILE *f = fopen("foo", "r");}\\n', 'w') + bld(features='c cshlib', source=[lib_node], linkflags=conf.env.EXTRA_LDFLAGS, target='liblc') + conf.check(build_fun=build, msg=msg) + """ + self.validate_c(kw) + self.start_msg(kw['msg'], **kw) + ret = None + try: + ret = self.run_build(*k, **kw) + except self.errors.ConfigurationError: + self.end_msg(kw['errmsg'], 'YELLOW', **kw) + if Logs.verbose > 1: + raise + else: + self.fatal('The configuration failed') + else: + kw['success'] = ret + + ret = self.post_check(*k, **kw) + if not ret: + self.end_msg(kw['errmsg'], 'YELLOW', **kw) + self.fatal('The configuration failed %r' % ret) + else: + self.end_msg(self.ret_msg(kw['okmsg'], kw), **kw) + return ret + +class test_exec(Task.Task): + """ + A task that runs programs after they are built. See :py:func:`waflib.Tools.c_config.test_exec_fun`. + """ + color = 'PINK' + def run(self): + cmd = [self.inputs[0].abspath()] + getattr(self.generator, 'test_args', []) + if getattr(self.generator, 'rpath', None): + if getattr(self.generator, 'define_ret', False): + self.generator.bld.retval = self.generator.bld.cmd_and_log(cmd) + else: + self.generator.bld.retval = self.generator.bld.exec_command(cmd) + else: + env = self.env.env or {} + env.update(dict(os.environ)) + for var in ('LD_LIBRARY_PATH', 'DYLD_LIBRARY_PATH', 'PATH'): + env[var] = self.inputs[0].parent.abspath() + os.path.pathsep + env.get(var, '') + if getattr(self.generator, 'define_ret', False): + self.generator.bld.retval = self.generator.bld.cmd_and_log(cmd, env=env) + else: + self.generator.bld.retval = self.generator.bld.exec_command(cmd, env=env) + +@feature('test_exec') +@after_method('apply_link') +def test_exec_fun(self): + """ + The feature **test_exec** is used to create a task that will to execute the binary + created (link task output) during the build. The exit status will be set + on the build context, so only one program may have the feature *test_exec*. + This is used by configuration tests:: + + def configure(conf): + conf.check(execute=True) + """ + self.create_task('test_exec', self.link_task.outputs[0]) + +@conf +def check_cxx(self, *k, **kw): + """ + Runs a test with a task generator of the form:: + + conf.check(features='cxx cxxprogram', ...) + """ + kw['compiler'] = 'cxx' + return self.check(*k, **kw) + +@conf +def check_cc(self, *k, **kw): + """ + Runs a test with a task generator of the form:: + + conf.check(features='c cprogram', ...) + """ + kw['compiler'] = 'c' + return self.check(*k, **kw) + +@conf +def set_define_comment(self, key, comment): + """ + Sets a comment that will appear in the configuration header + + :type key: string + :type comment: string + """ + coms = self.env.DEFINE_COMMENTS + if not coms: + coms = self.env.DEFINE_COMMENTS = {} + coms[key] = comment or '' + +@conf +def get_define_comment(self, key): + """ + Returns the comment associated to a define + + :type key: string + """ + coms = self.env.DEFINE_COMMENTS or {} + return coms.get(key, '') + +@conf +def define(self, key, val, quote=True, comment=''): + """ + Stores a single define and its state into ``conf.env.DEFINES``. The value is cast to an integer (0/1). + + :param key: define name + :type key: string + :param val: value + :type val: int or string + :param quote: enclose strings in quotes (yes by default) + :type quote: bool + """ + assert isinstance(key, str) + if not key: + return + if val is True: + val = 1 + elif val in (False, None): + val = 0 + + if isinstance(val, int) or isinstance(val, float): + s = '%s=%s' + else: + s = quote and '%s="%s"' or '%s=%s' + app = s % (key, str(val)) + + ban = key + '=' + lst = self.env.DEFINES + for x in lst: + if x.startswith(ban): + lst[lst.index(x)] = app + break + else: + self.env.append_value('DEFINES', app) + + self.env.append_unique(DEFKEYS, key) + self.set_define_comment(key, comment) + +@conf +def undefine(self, key, comment=''): + """ + Removes a global define from ``conf.env.DEFINES`` + + :param key: define name + :type key: string + """ + assert isinstance(key, str) + if not key: + return + ban = key + '=' + lst = [x for x in self.env.DEFINES if not x.startswith(ban)] + self.env.DEFINES = lst + self.env.append_unique(DEFKEYS, key) + self.set_define_comment(key, comment) + +@conf +def define_cond(self, key, val, comment=''): + """ + Conditionally defines a name:: + + def configure(conf): + conf.define_cond('A', True) + # equivalent to: + # if val: conf.define('A', 1) + # else: conf.undefine('A') + + :param key: define name + :type key: string + :param val: value + :type val: int or string + """ + assert isinstance(key, str) + if not key: + return + if val: + self.define(key, 1, comment=comment) + else: + self.undefine(key, comment=comment) + +@conf +def is_defined(self, key): + """ + Indicates whether a particular define is globally set in ``conf.env.DEFINES``. + + :param key: define name + :type key: string + :return: True if the define is set + :rtype: bool + """ + assert key and isinstance(key, str) + + ban = key + '=' + for x in self.env.DEFINES: + if x.startswith(ban): + return True + return False + +@conf +def get_define(self, key): + """ + Returns the value of an existing define, or None if not found + + :param key: define name + :type key: string + :rtype: string + """ + assert key and isinstance(key, str) + + ban = key + '=' + for x in self.env.DEFINES: + if x.startswith(ban): + return x[len(ban):] + return None + +@conf +def have_define(self, key): + """ + Returns a variable suitable for command-line or header use by removing invalid characters + and prefixing it with ``HAVE_`` + + :param key: define name + :type key: string + :return: the input key prefixed by *HAVE_* and substitute any invalid characters. + :rtype: string + """ + return (self.env.HAVE_PAT or 'HAVE_%s') % Utils.quote_define_name(key) + +@conf +def write_config_header(self, configfile='', guard='', top=False, defines=True, headers=False, remove=True, define_prefix=''): + """ + Writes a configuration header containing defines and includes:: + + def configure(cnf): + cnf.define('A', 1) + cnf.write_config_header('config.h') + + This function only adds include guards (if necessary), consult + :py:func:`waflib.Tools.c_config.get_config_header` for details on the body. + + :param configfile: path to the file to create (relative or absolute) + :type configfile: string + :param guard: include guard name to add, by default it is computed from the file name + :type guard: string + :param top: write the configuration header from the build directory (default is from the current path) + :type top: bool + :param defines: add the defines (yes by default) + :type defines: bool + :param headers: add #include in the file + :type headers: bool + :param remove: remove the defines after they are added (yes by default, works like in autoconf) + :type remove: bool + :type define_prefix: string + :param define_prefix: prefix all the defines in the file with a particular prefix + """ + if not configfile: + configfile = WAF_CONFIG_H + waf_guard = guard or 'W_%s_WAF' % Utils.quote_define_name(configfile) + + node = top and self.bldnode or self.path.get_bld() + node = node.make_node(configfile) + node.parent.mkdir() + + lst = ['/* WARNING! All changes made to this file will be lost! */\n'] + lst.append('#ifndef %s\n#define %s\n' % (waf_guard, waf_guard)) + lst.append(self.get_config_header(defines, headers, define_prefix=define_prefix)) + lst.append('\n#endif /* %s */\n' % waf_guard) + + node.write('\n'.join(lst)) + + # config files must not be removed on "waf clean" + self.env.append_unique(Build.CFG_FILES, [node.abspath()]) + + if remove: + for key in self.env[DEFKEYS]: + self.undefine(key) + self.env[DEFKEYS] = [] + +@conf +def get_config_header(self, defines=True, headers=False, define_prefix=''): + """ + Creates the contents of a ``config.h`` file from the defines and includes + set in conf.env.define_key / conf.env.include_key. No include guards are added. + + A prelude will be added from the variable env.WAF_CONFIG_H_PRELUDE if provided. This + can be used to insert complex macros or include guards:: + + def configure(conf): + conf.env.WAF_CONFIG_H_PRELUDE = '#include \\n' + conf.write_config_header('config.h') + + :param defines: write the defines values + :type defines: bool + :param headers: write include entries for each element in self.env.INCKEYS + :type headers: bool + :type define_prefix: string + :param define_prefix: prefix all the defines with a particular prefix + :return: the contents of a ``config.h`` file + :rtype: string + """ + lst = [] + + if self.env.WAF_CONFIG_H_PRELUDE: + lst.append(self.env.WAF_CONFIG_H_PRELUDE) + + if headers: + for x in self.env[INCKEYS]: + lst.append('#include <%s>' % x) + + if defines: + tbl = {} + for k in self.env.DEFINES: + a, _, b = k.partition('=') + tbl[a] = b + + for k in self.env[DEFKEYS]: + caption = self.get_define_comment(k) + if caption: + caption = ' /* %s */' % caption + try: + txt = '#define %s%s %s%s' % (define_prefix, k, tbl[k], caption) + except KeyError: + txt = '/* #undef %s%s */%s' % (define_prefix, k, caption) + lst.append(txt) + return "\n".join(lst) + +@conf +def cc_add_flags(conf): + """ + Adds CFLAGS / CPPFLAGS from os.environ to conf.env + """ + conf.add_os_flags('CPPFLAGS', dup=False) + conf.add_os_flags('CFLAGS', dup=False) + +@conf +def cxx_add_flags(conf): + """ + Adds CXXFLAGS / CPPFLAGS from os.environ to conf.env + """ + conf.add_os_flags('CPPFLAGS', dup=False) + conf.add_os_flags('CXXFLAGS', dup=False) + +@conf +def link_add_flags(conf): + """ + Adds LINKFLAGS / LDFLAGS from os.environ to conf.env + """ + conf.add_os_flags('LINKFLAGS', dup=False) + conf.add_os_flags('LDFLAGS', dup=False) + +@conf +def cc_load_tools(conf): + """ + Loads the Waf c extensions + """ + if not conf.env.DEST_OS: + conf.env.DEST_OS = Utils.unversioned_sys_platform() + conf.load('c') + +@conf +def cxx_load_tools(conf): + """ + Loads the Waf c++ extensions + """ + if not conf.env.DEST_OS: + conf.env.DEST_OS = Utils.unversioned_sys_platform() + conf.load('cxx') + +@conf +def get_cc_version(conf, cc, gcc=False, icc=False, clang=False): + """ + Runs the preprocessor to determine the gcc/icc/clang version + + The variables CC_VERSION, DEST_OS, DEST_BINFMT and DEST_CPU will be set in *conf.env* + + :raise: :py:class:`waflib.Errors.ConfigurationError` + """ + cmd = cc + ['-dM', '-E', '-'] + env = conf.env.env or None + try: + out, err = conf.cmd_and_log(cmd, output=0, input='\n'.encode(), env=env) + except Errors.WafError: + conf.fatal('Could not determine the compiler version %r' % cmd) + + if gcc: + if out.find('__INTEL_COMPILER') >= 0: + conf.fatal('The intel compiler pretends to be gcc') + if out.find('__GNUC__') < 0 and out.find('__clang__') < 0: + conf.fatal('Could not determine the compiler type') + + if icc and out.find('__INTEL_COMPILER') < 0: + conf.fatal('Not icc/icpc') + + if clang and out.find('__clang__') < 0: + conf.fatal('Not clang/clang++') + if not clang and out.find('__clang__') >= 0: + conf.fatal('Could not find gcc/g++ (only Clang), if renamed try eg: CC=gcc48 CXX=g++48 waf configure') + + k = {} + if icc or gcc or clang: + out = out.splitlines() + for line in out: + lst = shlex.split(line) + if len(lst)>2: + key = lst[1] + val = lst[2] + k[key] = val + + def isD(var): + return var in k + + # Some documentation is available at http://predef.sourceforge.net + # The names given to DEST_OS must match what Utils.unversioned_sys_platform() returns. + if not conf.env.DEST_OS: + conf.env.DEST_OS = '' + for i in MACRO_TO_DESTOS: + if isD(i): + conf.env.DEST_OS = MACRO_TO_DESTOS[i] + break + else: + if isD('__APPLE__') and isD('__MACH__'): + conf.env.DEST_OS = 'darwin' + elif isD('__unix__'): # unix must be tested last as it's a generic fallback + conf.env.DEST_OS = 'generic' + + if isD('__ELF__'): + conf.env.DEST_BINFMT = 'elf' + elif isD('__WINNT__') or isD('__CYGWIN__') or isD('_WIN32'): + conf.env.DEST_BINFMT = 'pe' + if not conf.env.IMPLIBDIR: + conf.env.IMPLIBDIR = conf.env.LIBDIR # for .lib or .dll.a files + conf.env.LIBDIR = conf.env.BINDIR + elif isD('__APPLE__'): + conf.env.DEST_BINFMT = 'mac-o' + + if not conf.env.DEST_BINFMT: + # Infer the binary format from the os name. + conf.env.DEST_BINFMT = Utils.destos_to_binfmt(conf.env.DEST_OS) + + for i in MACRO_TO_DEST_CPU: + if isD(i): + conf.env.DEST_CPU = MACRO_TO_DEST_CPU[i] + break + + Logs.debug('ccroot: dest platform: ' + ' '.join([conf.env[x] or '?' for x in ('DEST_OS', 'DEST_BINFMT', 'DEST_CPU')])) + if icc: + ver = k['__INTEL_COMPILER'] + conf.env.CC_VERSION = (ver[:-2], ver[-2], ver[-1]) + else: + if isD('__clang__') and isD('__clang_major__'): + conf.env.CC_VERSION = (k['__clang_major__'], k['__clang_minor__'], k['__clang_patchlevel__']) + else: + # older clang versions and gcc + conf.env.CC_VERSION = (k['__GNUC__'], k['__GNUC_MINOR__'], k.get('__GNUC_PATCHLEVEL__', '0')) + return k + +@conf +def get_xlc_version(conf, cc): + """ + Returns the Aix compiler version + + :raise: :py:class:`waflib.Errors.ConfigurationError` + """ + cmd = cc + ['-qversion'] + try: + out, err = conf.cmd_and_log(cmd, output=0) + except Errors.WafError: + conf.fatal('Could not find xlc %r' % cmd) + + # the intention is to catch the 8.0 in "IBM XL C/C++ Enterprise Edition V8.0 for AIX..." + for v in (r"IBM XL C/C\+\+.* V(?P\d*)\.(?P\d*)",): + version_re = re.compile(v, re.I).search + match = version_re(out or err) + if match: + k = match.groupdict() + conf.env.CC_VERSION = (k['major'], k['minor']) + break + else: + conf.fatal('Could not determine the XLC version.') + +@conf +def get_suncc_version(conf, cc): + """ + Returns the Sun compiler version + + :raise: :py:class:`waflib.Errors.ConfigurationError` + """ + cmd = cc + ['-V'] + try: + out, err = conf.cmd_and_log(cmd, output=0) + except Errors.WafError as e: + # Older versions of the compiler exit with non-zero status when reporting their version + if not (hasattr(e, 'returncode') and hasattr(e, 'stdout') and hasattr(e, 'stderr')): + conf.fatal('Could not find suncc %r' % cmd) + out = e.stdout + err = e.stderr + + version = (out or err) + version = version.splitlines()[0] + + # cc: Sun C 5.10 SunOS_i386 2009/06/03 + # cc: Studio 12.5 Sun C++ 5.14 SunOS_sparc Beta 2015/11/17 + # cc: WorkShop Compilers 5.0 98/12/15 C 5.0 + version_re = re.compile(r'cc: (studio.*?|\s+)?(sun\s+(c\+\+|c)|(WorkShop\s+Compilers))?\s+(?P\d*)\.(?P\d*)', re.I).search + match = version_re(version) + if match: + k = match.groupdict() + conf.env.CC_VERSION = (k['major'], k['minor']) + else: + conf.fatal('Could not determine the suncc version.') + +# ============ the --as-needed flag should added during the configuration, not at runtime ========= + +@conf +def add_as_needed(self): + """ + Adds ``--as-needed`` to the *LINKFLAGS* + On some platforms, it is a default flag. In some cases (e.g., in NS-3) it is necessary to explicitly disable this feature with `-Wl,--no-as-needed` flag. + """ + if self.env.DEST_BINFMT == 'elf' and 'gcc' in (self.env.CXX_NAME, self.env.CC_NAME): + self.env.append_unique('LINKFLAGS', '-Wl,--as-needed') + +# ============ parallel configuration + +class cfgtask(Task.Task): + """ + A task that executes build configuration tests (calls conf.check) + + Make sure to use locks if concurrent access to the same conf.env data is necessary. + """ + def __init__(self, *k, **kw): + Task.Task.__init__(self, *k, **kw) + self.run_after = set() + + def display(self): + return '' + + def runnable_status(self): + for x in self.run_after: + if not x.hasrun: + return Task.ASK_LATER + return Task.RUN_ME + + def uid(self): + return Utils.SIG_NIL + + def signature(self): + return Utils.SIG_NIL + + def run(self): + conf = self.conf + bld = Build.BuildContext(top_dir=conf.srcnode.abspath(), out_dir=conf.bldnode.abspath()) + bld.env = conf.env + bld.init_dirs() + bld.in_msg = 1 # suppress top-level start_msg + bld.logger = self.logger + bld.multicheck_task = self + args = self.args + try: + if 'func' in args: + bld.test(build_fun=args['func'], + msg=args.get('msg', ''), + okmsg=args.get('okmsg', ''), + errmsg=args.get('errmsg', ''), + ) + else: + args['multicheck_mandatory'] = args.get('mandatory', True) + args['mandatory'] = True + try: + bld.check(**args) + finally: + args['mandatory'] = args['multicheck_mandatory'] + except Exception: + return 1 + + def process(self): + Task.Task.process(self) + if 'msg' in self.args: + with self.generator.bld.multicheck_lock: + self.conf.start_msg(self.args['msg']) + if self.hasrun == Task.NOT_RUN: + self.conf.end_msg('test cancelled', 'YELLOW') + elif self.hasrun != Task.SUCCESS: + self.conf.end_msg(self.args.get('errmsg', 'no'), 'YELLOW') + else: + self.conf.end_msg(self.args.get('okmsg', 'yes'), 'GREEN') + +@conf +def multicheck(self, *k, **kw): + """ + Runs configuration tests in parallel; results are printed sequentially at the end of the build + but each test must provide its own msg value to display a line:: + + def test_build(ctx): + ctx.in_msg = True # suppress console outputs + ctx.check_large_file(mandatory=False) + + conf.multicheck( + {'header_name':'stdio.h', 'msg':'... stdio', 'uselib_store':'STDIO', 'global_define':False}, + {'header_name':'xyztabcd.h', 'msg':'... optional xyztabcd.h', 'mandatory': False}, + {'header_name':'stdlib.h', 'msg':'... stdlib', 'okmsg': 'aye', 'errmsg': 'nope'}, + {'func': test_build, 'msg':'... testing an arbitrary build function', 'okmsg':'ok'}, + msg = 'Checking for headers in parallel', + mandatory = True, # mandatory tests raise an error at the end + run_all_tests = True, # try running all tests + ) + + The configuration tests may modify the values in conf.env in any order, and the define + values can affect configuration tests being executed. It is hence recommended + to provide `uselib_store` values with `global_define=False` to prevent such issues. + """ + self.start_msg(kw.get('msg', 'Executing %d configuration tests' % len(k)), **kw) + + # Force a copy so that threads append to the same list at least + # no order is guaranteed, but the values should not disappear at least + for var in ('DEFINES', DEFKEYS): + self.env.append_value(var, []) + self.env.DEFINE_COMMENTS = self.env.DEFINE_COMMENTS or {} + + # define a task object that will execute our tests + class par(object): + def __init__(self): + self.keep = False + self.task_sigs = {} + self.progress_bar = 0 + def total(self): + return len(tasks) + def to_log(self, *k, **kw): + return + + bld = par() + bld.keep = kw.get('run_all_tests', True) + bld.imp_sigs = {} + tasks = [] + + id_to_task = {} + for dct in k: + x = Task.classes['cfgtask'](bld=bld, env=None) + tasks.append(x) + x.args = dct + x.bld = bld + x.conf = self + x.args = dct + + # bind a logger that will keep the info in memory + x.logger = Logs.make_mem_logger(str(id(x)), self.logger) + + if 'id' in dct: + id_to_task[dct['id']] = x + + # second pass to set dependencies with after_test/before_test + for x in tasks: + for key in Utils.to_list(x.args.get('before_tests', [])): + tsk = id_to_task[key] + if not tsk: + raise ValueError('No test named %r' % key) + tsk.run_after.add(x) + for key in Utils.to_list(x.args.get('after_tests', [])): + tsk = id_to_task[key] + if not tsk: + raise ValueError('No test named %r' % key) + x.run_after.add(tsk) + + def it(): + yield tasks + while 1: + yield [] + bld.producer = p = Runner.Parallel(bld, Options.options.jobs) + bld.multicheck_lock = Utils.threading.Lock() + p.biter = it() + + self.end_msg('started') + p.start() + + # flush the logs in order into the config.log + for x in tasks: + x.logger.memhandler.flush() + + self.start_msg('-> processing test results') + if p.error: + for x in p.error: + if getattr(x, 'err_msg', None): + self.to_log(x.err_msg) + self.end_msg('fail', color='RED') + raise Errors.WafError('There is an error in the library, read config.log for more information') + + failure_count = 0 + for x in tasks: + if x.hasrun not in (Task.SUCCESS, Task.NOT_RUN): + failure_count += 1 + + if failure_count: + self.end_msg(kw.get('errmsg', '%s test failed' % failure_count), color='YELLOW', **kw) + else: + self.end_msg('all ok', **kw) + + for x in tasks: + if x.hasrun != Task.SUCCESS: + if x.args.get('mandatory', True): + self.fatal(kw.get('fatalmsg') or 'One of the tests has failed, read config.log for more information') + +@conf +def check_gcc_o_space(self, mode='c'): + if int(self.env.CC_VERSION[0]) > 4: + # this is for old compilers + return + self.env.stash() + if mode == 'c': + self.env.CCLNK_TGT_F = ['-o', ''] + elif mode == 'cxx': + self.env.CXXLNK_TGT_F = ['-o', ''] + features = '%s %sshlib' % (mode, mode) + try: + self.check(msg='Checking if the -o link must be split from arguments', fragment=SNIP_EMPTY_PROGRAM, features=features) + except self.errors.ConfigurationError: + self.env.revert() + else: + self.env.commit() + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/c_osx.py b/ldb-2.0.8/third_party/waf/waflib/Tools/c_osx.py new file mode 100644 index 0000000..f70b128 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/c_osx.py @@ -0,0 +1,193 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy 2008-2018 (ita) + +""" +MacOSX related tools +""" + +import os, shutil, platform +from waflib import Task, Utils +from waflib.TaskGen import taskgen_method, feature, after_method, before_method + +app_info = ''' + + + + + CFBundlePackageType + APPL + CFBundleGetInfoString + Created by Waf + CFBundleSignature + ???? + NOTE + THIS IS A GENERATED FILE, DO NOT MODIFY + CFBundleExecutable + {app_name} + + +''' +""" +plist template +""" + +@feature('c', 'cxx') +def set_macosx_deployment_target(self): + """ + see WAF issue 285 and also and also http://trac.macports.org/ticket/17059 + """ + if self.env.MACOSX_DEPLOYMENT_TARGET: + os.environ['MACOSX_DEPLOYMENT_TARGET'] = self.env.MACOSX_DEPLOYMENT_TARGET + elif 'MACOSX_DEPLOYMENT_TARGET' not in os.environ: + if Utils.unversioned_sys_platform() == 'darwin': + os.environ['MACOSX_DEPLOYMENT_TARGET'] = '.'.join(platform.mac_ver()[0].split('.')[:2]) + +@taskgen_method +def create_bundle_dirs(self, name, out): + """ + Creates bundle folders, used by :py:func:`create_task_macplist` and :py:func:`create_task_macapp` + """ + dir = out.parent.find_or_declare(name) + dir.mkdir() + macos = dir.find_or_declare(['Contents', 'MacOS']) + macos.mkdir() + return dir + +def bundle_name_for_output(out): + name = out.name + k = name.rfind('.') + if k >= 0: + name = name[:k] + '.app' + else: + name = name + '.app' + return name + +@feature('cprogram', 'cxxprogram') +@after_method('apply_link') +def create_task_macapp(self): + """ + To compile an executable into a Mac application (a .app), set its *mac_app* attribute:: + + def build(bld): + bld.shlib(source='a.c', target='foo', mac_app=True) + + To force *all* executables to be transformed into Mac applications:: + + def build(bld): + bld.env.MACAPP = True + bld.shlib(source='a.c', target='foo') + """ + if self.env.MACAPP or getattr(self, 'mac_app', False): + out = self.link_task.outputs[0] + + name = bundle_name_for_output(out) + dir = self.create_bundle_dirs(name, out) + + n1 = dir.find_or_declare(['Contents', 'MacOS', out.name]) + + self.apptask = self.create_task('macapp', self.link_task.outputs, n1) + inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Contents/MacOS/' % name + self.add_install_files(install_to=inst_to, install_from=n1, chmod=Utils.O755) + + if getattr(self, 'mac_files', None): + # this only accepts files; they will be installed as seen from mac_files_root + mac_files_root = getattr(self, 'mac_files_root', None) + if isinstance(mac_files_root, str): + mac_files_root = self.path.find_node(mac_files_root) + if not mac_files_root: + self.bld.fatal('Invalid mac_files_root %r' % self.mac_files_root) + res_dir = n1.parent.parent.make_node('Resources') + inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Resources' % name + for node in self.to_nodes(self.mac_files): + relpath = node.path_from(mac_files_root or node.parent) + self.create_task('macapp', node, res_dir.make_node(relpath)) + self.add_install_as(install_to=os.path.join(inst_to, relpath), install_from=node) + + if getattr(self.bld, 'is_install', None): + # disable regular binary installation + self.install_task.hasrun = Task.SKIP_ME + +@feature('cprogram', 'cxxprogram') +@after_method('apply_link') +def create_task_macplist(self): + """ + Creates a :py:class:`waflib.Tools.c_osx.macplist` instance. + """ + if self.env.MACAPP or getattr(self, 'mac_app', False): + out = self.link_task.outputs[0] + + name = bundle_name_for_output(out) + + dir = self.create_bundle_dirs(name, out) + n1 = dir.find_or_declare(['Contents', 'Info.plist']) + self.plisttask = plisttask = self.create_task('macplist', [], n1) + plisttask.context = { + 'app_name': self.link_task.outputs[0].name, + 'env': self.env + } + + plist_ctx = getattr(self, 'plist_context', None) + if (plist_ctx): + plisttask.context.update(plist_ctx) + + if getattr(self, 'mac_plist', False): + node = self.path.find_resource(self.mac_plist) + if node: + plisttask.inputs.append(node) + else: + plisttask.code = self.mac_plist + else: + plisttask.code = app_info + + inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Contents/' % name + self.add_install_files(install_to=inst_to, install_from=n1) + +@feature('cshlib', 'cxxshlib') +@before_method('apply_link', 'propagate_uselib_vars') +def apply_bundle(self): + """ + To make a bundled shared library (a ``.bundle``), set the *mac_bundle* attribute:: + + def build(bld): + bld.shlib(source='a.c', target='foo', mac_bundle = True) + + To force *all* executables to be transformed into bundles:: + + def build(bld): + bld.env.MACBUNDLE = True + bld.shlib(source='a.c', target='foo') + """ + if self.env.MACBUNDLE or getattr(self, 'mac_bundle', False): + self.env.LINKFLAGS_cshlib = self.env.LINKFLAGS_cxxshlib = [] # disable the '-dynamiclib' flag + self.env.cshlib_PATTERN = self.env.cxxshlib_PATTERN = self.env.macbundle_PATTERN + use = self.use = self.to_list(getattr(self, 'use', [])) + if not 'MACBUNDLE' in use: + use.append('MACBUNDLE') + +app_dirs = ['Contents', 'Contents/MacOS', 'Contents/Resources'] + +class macapp(Task.Task): + """ + Creates mac applications + """ + color = 'PINK' + def run(self): + self.outputs[0].parent.mkdir() + shutil.copy2(self.inputs[0].srcpath(), self.outputs[0].abspath()) + +class macplist(Task.Task): + """ + Creates plist files + """ + color = 'PINK' + ext_in = ['.bin'] + def run(self): + if getattr(self, 'code', None): + txt = self.code + else: + txt = self.inputs[0].read() + context = getattr(self, 'context', {}) + txt = txt.format(**context) + self.outputs[0].write(txt) + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/c_preproc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/c_preproc.py new file mode 100644 index 0000000..68e5f5a --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/c_preproc.py @@ -0,0 +1,1091 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2006-2018 (ita) + +""" +C/C++ preprocessor for finding dependencies + +Reasons for using the Waf preprocessor by default + +#. Some c/c++ extensions (Qt) require a custom preprocessor for obtaining the dependencies (.moc files) +#. Not all compilers provide .d files for obtaining the dependencies (portability) +#. A naive file scanner will not catch the constructs such as "#include foo()" +#. A naive file scanner will catch unnecessary dependencies (change an unused header -> recompile everything) + +Regarding the speed concerns: + +* the preprocessing is performed only when files must be compiled +* the macros are evaluated only for #if/#elif/#include +* system headers are not scanned by default + +Now if you do not want the Waf preprocessor, the tool +gccdeps* uses the .d files produced +during the compilation to track the dependencies (useful when used with the boost libraries). +It only works with gcc >= 4.4 though. + +A dumb preprocessor is also available in the tool *c_dumbpreproc* +""" +# TODO: more varargs, pragma once + +import re, string, traceback +from waflib import Logs, Utils, Errors + +class PreprocError(Errors.WafError): + pass + +FILE_CACHE_SIZE = 100000 +LINE_CACHE_SIZE = 100000 + +POPFILE = '-' +"Constant representing a special token used in :py:meth:`waflib.Tools.c_preproc.c_parser.start` iteration to switch to a header read previously" + +recursion_limit = 150 +"Limit on the amount of files to read in the dependency scanner" + +go_absolute = False +"Set to True to track headers on files in /usr/include, else absolute paths are ignored (but it becomes very slow)" + +standard_includes = ['/usr/local/include', '/usr/include'] +if Utils.is_win32: + standard_includes = [] + +use_trigraphs = 0 +"""Apply trigraph rules (False by default)""" + +# obsolete, do not use +strict_quotes = 0 + +g_optrans = { +'not':'!', +'not_eq':'!', +'and':'&&', +'and_eq':'&=', +'or':'||', +'or_eq':'|=', +'xor':'^', +'xor_eq':'^=', +'bitand':'&', +'bitor':'|', +'compl':'~', +} +"""Operators such as and/or/xor for c++. Set an empty dict to disable.""" + +# ignore #warning and #error +re_lines = re.compile( + '^[ \t]*(?:#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*)\r*$', + re.IGNORECASE | re.MULTILINE) +"""Match #include lines""" + +re_mac = re.compile(r"^[a-zA-Z_]\w*") +"""Match macro definitions""" + +re_fun = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*[(]') +"""Match macro functions""" + +re_pragma_once = re.compile(r'^\s*once\s*', re.IGNORECASE) +"""Match #pragma once statements""" + +re_nl = re.compile('\\\\\r*\n', re.MULTILINE) +"""Match newlines""" + +re_cpp = re.compile(r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', re.DOTALL | re.MULTILINE ) +"""Filter C/C++ comments""" + +trig_def = [('??'+a, b) for a, b in zip("=-/!'()<>", r'#~\|^[]{}')] +"""Trigraph definitions""" + +chr_esc = {'0':0, 'a':7, 'b':8, 't':9, 'n':10, 'f':11, 'v':12, 'r':13, '\\':92, "'":39} +"""Escape characters""" + +NUM = 'i' +"""Number token""" + +OP = 'O' +"""Operator token""" + +IDENT = 'T' +"""Identifier token""" + +STR = 's' +"""String token""" + +CHAR = 'c' +"""Character token""" + +tok_types = [NUM, STR, IDENT, OP] +"""Token types""" + +exp_types = [ + r"""0[xX](?P[a-fA-F0-9]+)(?P[uUlL]*)|L*?'(?P(\\.|[^\\'])+)'|(?P\d+)[Ee](?P[+-]*?\d+)(?P[fFlL]*)|(?P\d*\.\d+)([Ee](?P[+-]*?\d+))?(?P[fFlL]*)|(?P\d+\.\d*)([Ee](?P[+-]*?\d+))?(?P[fFlL]*)|(?P0*)(?P\d+)(?P[uUlL]*)""", + r'L?"([^"\\]|\\.)*"', + r'[a-zA-Z_]\w*', + r'%:%:|<<=|>>=|\.\.\.|<<|<%|<:|<=|>>|>=|\+\+|\+=|--|->|-=|\*=|/=|%:|%=|%>|==|&&|&=|\|\||\|=|\^=|:>|!=|##|[\(\)\{\}\[\]<>\?\|\^\*\+&=:!#;,%/\-\?\~\.]', +] +"""Expression types""" + +re_clexer = re.compile('|'.join(["(?P<%s>%s)" % (name, part) for name, part in zip(tok_types, exp_types)]), re.M) +"""Match expressions into tokens""" + +accepted = 'a' +"""Parser state is *accepted*""" + +ignored = 'i' +"""Parser state is *ignored*, for example preprocessor lines in an #if 0 block""" + +undefined = 'u' +"""Parser state is *undefined* at the moment""" + +skipped = 's' +"""Parser state is *skipped*, for example preprocessor lines in a #elif 0 block""" + +def repl(m): + """Replace function used with :py:attr:`waflib.Tools.c_preproc.re_cpp`""" + s = m.group() + if s[0] == '/': + return ' ' + return s + +prec = {} +""" +Operator precedence rules required for parsing expressions of the form:: + + #if 1 && 2 != 0 +""" +ops = ['* / %', '+ -', '<< >>', '< <= >= >', '== !=', '& | ^', '&& ||', ','] +for x, syms in enumerate(ops): + for u in syms.split(): + prec[u] = x + +def reduce_nums(val_1, val_2, val_op): + """ + Apply arithmetic rules to compute a result + + :param val1: input parameter + :type val1: int or string + :param val2: input parameter + :type val2: int or string + :param val_op: C operator in *+*, */*, *-*, etc + :type val_op: string + :rtype: int + """ + #print val_1, val_2, val_op + + # now perform the operation, make certain a and b are numeric + try: + a = 0 + val_1 + except TypeError: + a = int(val_1) + try: + b = 0 + val_2 + except TypeError: + b = int(val_2) + + d = val_op + if d == '%': + c = a % b + elif d=='+': + c = a + b + elif d=='-': + c = a - b + elif d=='*': + c = a * b + elif d=='/': + c = a / b + elif d=='^': + c = a ^ b + elif d=='==': + c = int(a == b) + elif d=='|' or d == 'bitor': + c = a | b + elif d=='||' or d == 'or' : + c = int(a or b) + elif d=='&' or d == 'bitand': + c = a & b + elif d=='&&' or d == 'and': + c = int(a and b) + elif d=='!=' or d == 'not_eq': + c = int(a != b) + elif d=='^' or d == 'xor': + c = int(a^b) + elif d=='<=': + c = int(a <= b) + elif d=='<': + c = int(a < b) + elif d=='>': + c = int(a > b) + elif d=='>=': + c = int(a >= b) + elif d=='<<': + c = a << b + elif d=='>>': + c = a >> b + else: + c = 0 + return c + +def get_num(lst): + """ + Try to obtain a number from a list of tokens. The token types are defined in :py:attr:`waflib.Tools.ccroot.tok_types`. + + :param lst: list of preprocessor tokens + :type lst: list of tuple (tokentype, value) + :return: a pair containing the number and the rest of the list + :rtype: tuple(value, list) + """ + if not lst: + raise PreprocError('empty list for get_num') + (p, v) = lst[0] + if p == OP: + if v == '(': + count_par = 1 + i = 1 + while i < len(lst): + (p, v) = lst[i] + + if p == OP: + if v == ')': + count_par -= 1 + if count_par == 0: + break + elif v == '(': + count_par += 1 + i += 1 + else: + raise PreprocError('rparen expected %r' % lst) + + (num, _) = get_term(lst[1:i]) + return (num, lst[i+1:]) + + elif v == '+': + return get_num(lst[1:]) + elif v == '-': + num, lst = get_num(lst[1:]) + return (reduce_nums('-1', num, '*'), lst) + elif v == '!': + num, lst = get_num(lst[1:]) + return (int(not int(num)), lst) + elif v == '~': + num, lst = get_num(lst[1:]) + return (~ int(num), lst) + else: + raise PreprocError('Invalid op token %r for get_num' % lst) + elif p == NUM: + return v, lst[1:] + elif p == IDENT: + # all macros should have been replaced, remaining identifiers eval to 0 + return 0, lst[1:] + else: + raise PreprocError('Invalid token %r for get_num' % lst) + +def get_term(lst): + """ + Evaluate an expression recursively, for example:: + + 1+1+1 -> 2+1 -> 3 + + :param lst: list of tokens + :type lst: list of tuple(token, value) + :return: the value and the remaining tokens + :rtype: value, list + """ + + if not lst: + raise PreprocError('empty list for get_term') + num, lst = get_num(lst) + if not lst: + return (num, []) + (p, v) = lst[0] + if p == OP: + if v == ',': + # skip + return get_term(lst[1:]) + elif v == '?': + count_par = 0 + i = 1 + while i < len(lst): + (p, v) = lst[i] + + if p == OP: + if v == ')': + count_par -= 1 + elif v == '(': + count_par += 1 + elif v == ':': + if count_par == 0: + break + i += 1 + else: + raise PreprocError('rparen expected %r' % lst) + + if int(num): + return get_term(lst[1:i]) + else: + return get_term(lst[i+1:]) + + else: + num2, lst = get_num(lst[1:]) + + if not lst: + # no more tokens to process + num2 = reduce_nums(num, num2, v) + return get_term([(NUM, num2)] + lst) + + # operator precedence + p2, v2 = lst[0] + if p2 != OP: + raise PreprocError('op expected %r' % lst) + + if prec[v2] >= prec[v]: + num2 = reduce_nums(num, num2, v) + return get_term([(NUM, num2)] + lst) + else: + num3, lst = get_num(lst[1:]) + num3 = reduce_nums(num2, num3, v2) + return get_term([(NUM, num), (p, v), (NUM, num3)] + lst) + + + raise PreprocError('cannot reduce %r' % lst) + +def reduce_eval(lst): + """ + Take a list of tokens and output true or false for #if/#elif conditions. + + :param lst: a list of tokens + :type lst: list of tuple(token, value) + :return: a token + :rtype: tuple(NUM, int) + """ + num, lst = get_term(lst) + return (NUM, num) + +def stringize(lst): + """ + Merge a list of tokens into a string + + :param lst: a list of tokens + :type lst: list of tuple(token, value) + :rtype: string + """ + lst = [str(v2) for (p2, v2) in lst] + return "".join(lst) + +def paste_tokens(t1, t2): + """ + Token pasting works between identifiers, particular operators, and identifiers and numbers:: + + a ## b -> ab + > ## = -> >= + a ## 2 -> a2 + + :param t1: token + :type t1: tuple(type, value) + :param t2: token + :type t2: tuple(type, value) + """ + p1 = None + if t1[0] == OP and t2[0] == OP: + p1 = OP + elif t1[0] == IDENT and (t2[0] == IDENT or t2[0] == NUM): + p1 = IDENT + elif t1[0] == NUM and t2[0] == NUM: + p1 = NUM + if not p1: + raise PreprocError('tokens do not make a valid paste %r and %r' % (t1, t2)) + return (p1, t1[1] + t2[1]) + +def reduce_tokens(lst, defs, ban=[]): + """ + Replace the tokens in lst, using the macros provided in defs, and a list of macros that cannot be re-applied + + :param lst: list of tokens + :type lst: list of tuple(token, value) + :param defs: macro definitions + :type defs: dict + :param ban: macros that cannot be substituted (recursion is not allowed) + :type ban: list of string + :return: the new list of tokens + :rtype: value, list + """ + + i = 0 + while i < len(lst): + (p, v) = lst[i] + + if p == IDENT and v == "defined": + del lst[i] + if i < len(lst): + (p2, v2) = lst[i] + if p2 == IDENT: + if v2 in defs: + lst[i] = (NUM, 1) + else: + lst[i] = (NUM, 0) + elif p2 == OP and v2 == '(': + del lst[i] + (p2, v2) = lst[i] + del lst[i] # remove the ident, and change the ) for the value + if v2 in defs: + lst[i] = (NUM, 1) + else: + lst[i] = (NUM, 0) + else: + raise PreprocError('Invalid define expression %r' % lst) + + elif p == IDENT and v in defs: + + if isinstance(defs[v], str): + a, b = extract_macro(defs[v]) + defs[v] = b + macro_def = defs[v] + to_add = macro_def[1] + + if isinstance(macro_def[0], list): + # macro without arguments + del lst[i] + accu = to_add[:] + reduce_tokens(accu, defs, ban+[v]) + for tmp in accu: + lst.insert(i, tmp) + i += 1 + else: + # collect the arguments for the funcall + + args = [] + del lst[i] + + if i >= len(lst): + raise PreprocError('expected ( after %r (got nothing)' % v) + + (p2, v2) = lst[i] + if p2 != OP or v2 != '(': + raise PreprocError('expected ( after %r' % v) + + del lst[i] + + one_param = [] + count_paren = 0 + while i < len(lst): + p2, v2 = lst[i] + + del lst[i] + if p2 == OP and count_paren == 0: + if v2 == '(': + one_param.append((p2, v2)) + count_paren += 1 + elif v2 == ')': + if one_param: + args.append(one_param) + break + elif v2 == ',': + if not one_param: + raise PreprocError('empty param in funcall %r' % v) + args.append(one_param) + one_param = [] + else: + one_param.append((p2, v2)) + else: + one_param.append((p2, v2)) + if v2 == '(': + count_paren += 1 + elif v2 == ')': + count_paren -= 1 + else: + raise PreprocError('malformed macro') + + # substitute the arguments within the define expression + accu = [] + arg_table = macro_def[0] + j = 0 + while j < len(to_add): + (p2, v2) = to_add[j] + + if p2 == OP and v2 == '#': + # stringize is for arguments only + if j+1 < len(to_add) and to_add[j+1][0] == IDENT and to_add[j+1][1] in arg_table: + toks = args[arg_table[to_add[j+1][1]]] + accu.append((STR, stringize(toks))) + j += 1 + else: + accu.append((p2, v2)) + elif p2 == OP and v2 == '##': + # token pasting, how can man invent such a complicated system? + if accu and j+1 < len(to_add): + # we have at least two tokens + + t1 = accu[-1] + + if to_add[j+1][0] == IDENT and to_add[j+1][1] in arg_table: + toks = args[arg_table[to_add[j+1][1]]] + + if toks: + accu[-1] = paste_tokens(t1, toks[0]) #(IDENT, accu[-1][1] + toks[0][1]) + accu.extend(toks[1:]) + else: + # error, case "a##" + accu.append((p2, v2)) + accu.extend(toks) + elif to_add[j+1][0] == IDENT and to_add[j+1][1] == '__VA_ARGS__': + # first collect the tokens + va_toks = [] + st = len(macro_def[0]) + pt = len(args) + for x in args[pt-st+1:]: + va_toks.extend(x) + va_toks.append((OP, ',')) + if va_toks: + va_toks.pop() # extra comma + if len(accu)>1: + (p3, v3) = accu[-1] + (p4, v4) = accu[-2] + if v3 == '##': + # remove the token paste + accu.pop() + if v4 == ',' and pt < st: + # remove the comma + accu.pop() + accu += va_toks + else: + accu[-1] = paste_tokens(t1, to_add[j+1]) + + j += 1 + else: + # Invalid paste, case "##a" or "b##" + accu.append((p2, v2)) + + elif p2 == IDENT and v2 in arg_table: + toks = args[arg_table[v2]] + reduce_tokens(toks, defs, ban+[v]) + accu.extend(toks) + else: + accu.append((p2, v2)) + + j += 1 + + + reduce_tokens(accu, defs, ban+[v]) + + for x in range(len(accu)-1, -1, -1): + lst.insert(i, accu[x]) + + i += 1 + + +def eval_macro(lst, defs): + """ + Reduce the tokens by :py:func:`waflib.Tools.c_preproc.reduce_tokens` and try to return a 0/1 result by :py:func:`waflib.Tools.c_preproc.reduce_eval`. + + :param lst: list of tokens + :type lst: list of tuple(token, value) + :param defs: macro definitions + :type defs: dict + :rtype: int + """ + reduce_tokens(lst, defs, []) + if not lst: + raise PreprocError('missing tokens to evaluate') + + if lst: + p, v = lst[0] + if p == IDENT and v not in defs: + raise PreprocError('missing macro %r' % lst) + + p, v = reduce_eval(lst) + return int(v) != 0 + +def extract_macro(txt): + """ + Process a macro definition of the form:: + #define f(x, y) x * y + + into a function or a simple macro without arguments + + :param txt: expression to exact a macro definition from + :type txt: string + :return: a tuple containing the name, the list of arguments and the replacement + :rtype: tuple(string, [list, list]) + """ + t = tokenize(txt) + if re_fun.search(txt): + p, name = t[0] + + p, v = t[1] + if p != OP: + raise PreprocError('expected (') + + i = 1 + pindex = 0 + params = {} + prev = '(' + + while 1: + i += 1 + p, v = t[i] + + if prev == '(': + if p == IDENT: + params[v] = pindex + pindex += 1 + prev = p + elif p == OP and v == ')': + break + else: + raise PreprocError('unexpected token (3)') + elif prev == IDENT: + if p == OP and v == ',': + prev = v + elif p == OP and v == ')': + break + else: + raise PreprocError('comma or ... expected') + elif prev == ',': + if p == IDENT: + params[v] = pindex + pindex += 1 + prev = p + elif p == OP and v == '...': + raise PreprocError('not implemented (1)') + else: + raise PreprocError('comma or ... expected (2)') + elif prev == '...': + raise PreprocError('not implemented (2)') + else: + raise PreprocError('unexpected else') + + #~ print (name, [params, t[i+1:]]) + return (name, [params, t[i+1:]]) + else: + (p, v) = t[0] + if len(t) > 1: + return (v, [[], t[1:]]) + else: + # empty define, assign an empty token + return (v, [[], [('T','')]]) + +re_include = re.compile(r'^\s*(<(?:.*)>|"(?:.*)")') +def extract_include(txt, defs): + """ + Process a line in the form:: + + #include foo + + :param txt: include line to process + :type txt: string + :param defs: macro definitions + :type defs: dict + :return: the file name + :rtype: string + """ + m = re_include.search(txt) + if m: + txt = m.group(1) + return txt[0], txt[1:-1] + + # perform preprocessing and look at the result, it must match an include + toks = tokenize(txt) + reduce_tokens(toks, defs, ['waf_include']) + + if not toks: + raise PreprocError('could not parse include %r' % txt) + + if len(toks) == 1: + if toks[0][0] == STR: + return '"', toks[0][1] + else: + if toks[0][1] == '<' and toks[-1][1] == '>': + ret = '<', stringize(toks).lstrip('<').rstrip('>') + return ret + + raise PreprocError('could not parse include %r' % txt) + +def parse_char(txt): + """ + Parse a c character + + :param txt: character to parse + :type txt: string + :return: a character literal + :rtype: string + """ + + if not txt: + raise PreprocError('attempted to parse a null char') + if txt[0] != '\\': + return ord(txt) + c = txt[1] + if c == 'x': + if len(txt) == 4 and txt[3] in string.hexdigits: + return int(txt[2:], 16) + return int(txt[2:], 16) + elif c.isdigit(): + if c == '0' and len(txt)==2: + return 0 + for i in 3, 2, 1: + if len(txt) > i and txt[1:1+i].isdigit(): + return (1+i, int(txt[1:1+i], 8)) + else: + try: + return chr_esc[c] + except KeyError: + raise PreprocError('could not parse char literal %r' % txt) + +def tokenize(s): + """ + Convert a string into a list of tokens (shlex.split does not apply to c/c++/d) + + :param s: input to tokenize + :type s: string + :return: a list of tokens + :rtype: list of tuple(token, value) + """ + return tokenize_private(s)[:] # force a copy of the results + +def tokenize_private(s): + ret = [] + for match in re_clexer.finditer(s): + m = match.group + for name in tok_types: + v = m(name) + if v: + if name == IDENT: + if v in g_optrans: + name = OP + elif v.lower() == "true": + v = 1 + name = NUM + elif v.lower() == "false": + v = 0 + name = NUM + elif name == NUM: + if m('oct'): + v = int(v, 8) + elif m('hex'): + v = int(m('hex'), 16) + elif m('n0'): + v = m('n0') + else: + v = m('char') + if v: + v = parse_char(v) + else: + v = m('n2') or m('n4') + elif name == OP: + if v == '%:': + v = '#' + elif v == '%:%:': + v = '##' + elif name == STR: + # remove the quotes around the string + v = v[1:-1] + ret.append((name, v)) + break + return ret + +def format_defines(lst): + ret = [] + for y in lst: + if y: + pos = y.find('=') + if pos == -1: + # "-DFOO" should give "#define FOO 1" + ret.append(y) + elif pos > 0: + # all others are assumed to be -DX=Y + ret.append('%s %s' % (y[:pos], y[pos+1:])) + else: + raise ValueError('Invalid define expression %r' % y) + return ret + +class c_parser(object): + """ + Used by :py:func:`waflib.Tools.c_preproc.scan` to parse c/h files. Note that by default, + only project headers are parsed. + """ + def __init__(self, nodepaths=None, defines=None): + self.lines = [] + """list of lines read""" + + if defines is None: + self.defs = {} + else: + self.defs = dict(defines) # make a copy + self.state = [] + + self.count_files = 0 + self.currentnode_stack = [] + + self.nodepaths = nodepaths or [] + """Include paths""" + + self.nodes = [] + """List of :py:class:`waflib.Node.Node` found so far""" + + self.names = [] + """List of file names that could not be matched by any file""" + + self.curfile = '' + """Current file""" + + self.ban_includes = set() + """Includes that must not be read (#pragma once)""" + + self.listed = set() + """Include nodes/names already listed to avoid duplicates in self.nodes/self.names""" + + def cached_find_resource(self, node, filename): + """ + Find a file from the input directory + + :param node: directory + :type node: :py:class:`waflib.Node.Node` + :param filename: header to find + :type filename: string + :return: the node if found, or None + :rtype: :py:class:`waflib.Node.Node` + """ + try: + cache = node.ctx.preproc_cache_node + except AttributeError: + cache = node.ctx.preproc_cache_node = Utils.lru_cache(FILE_CACHE_SIZE) + + key = (node, filename) + try: + return cache[key] + except KeyError: + ret = node.find_resource(filename) + if ret: + if getattr(ret, 'children', None): + ret = None + elif ret.is_child_of(node.ctx.bldnode): + tmp = node.ctx.srcnode.search_node(ret.path_from(node.ctx.bldnode)) + if tmp and getattr(tmp, 'children', None): + ret = None + cache[key] = ret + return ret + + def tryfind(self, filename, kind='"', env=None): + """ + Try to obtain a node from the filename based from the include paths. Will add + the node found to :py:attr:`waflib.Tools.c_preproc.c_parser.nodes` or the file name to + :py:attr:`waflib.Tools.c_preproc.c_parser.names` if no corresponding file is found. Called by + :py:attr:`waflib.Tools.c_preproc.c_parser.start`. + + :param filename: header to find + :type filename: string + :return: the node if found + :rtype: :py:class:`waflib.Node.Node` + """ + if filename.endswith('.moc'): + # we could let the qt4 module use a subclass, but then the function "scan" below must be duplicated + # in the qt4 and in the qt5 classes. So we have two lines here and it is sufficient. + self.names.append(filename) + return None + + self.curfile = filename + + found = None + if kind == '"': + if env.MSVC_VERSION: + for n in reversed(self.currentnode_stack): + found = self.cached_find_resource(n, filename) + if found: + break + else: + found = self.cached_find_resource(self.currentnode_stack[-1], filename) + + if not found: + for n in self.nodepaths: + found = self.cached_find_resource(n, filename) + if found: + break + + listed = self.listed + if found and not found in self.ban_includes: + if found not in listed: + listed.add(found) + self.nodes.append(found) + self.addlines(found) + else: + if filename not in listed: + listed.add(filename) + self.names.append(filename) + return found + + def filter_comments(self, node): + """ + Filter the comments from a c/h file, and return the preprocessor lines. + The regexps :py:attr:`waflib.Tools.c_preproc.re_cpp`, :py:attr:`waflib.Tools.c_preproc.re_nl` and :py:attr:`waflib.Tools.c_preproc.re_lines` are used internally. + + :return: the preprocessor directives as a list of (keyword, line) + :rtype: a list of string pairs + """ + # return a list of tuples : keyword, line + code = node.read() + if use_trigraphs: + for (a, b) in trig_def: + code = code.split(a).join(b) + code = re_nl.sub('', code) + code = re_cpp.sub(repl, code) + return re_lines.findall(code) + + def parse_lines(self, node): + try: + cache = node.ctx.preproc_cache_lines + except AttributeError: + cache = node.ctx.preproc_cache_lines = Utils.lru_cache(LINE_CACHE_SIZE) + try: + return cache[node] + except KeyError: + cache[node] = lines = self.filter_comments(node) + lines.append((POPFILE, '')) + lines.reverse() + return lines + + def addlines(self, node): + """ + Add the lines from a header in the list of preprocessor lines to parse + + :param node: header + :type node: :py:class:`waflib.Node.Node` + """ + + self.currentnode_stack.append(node.parent) + + self.count_files += 1 + if self.count_files > recursion_limit: + # issue #812 + raise PreprocError('recursion limit exceeded') + + if Logs.verbose: + Logs.debug('preproc: reading file %r', node) + try: + lines = self.parse_lines(node) + except EnvironmentError: + raise PreprocError('could not read the file %r' % node) + except Exception: + if Logs.verbose > 0: + Logs.error('parsing %r failed %s', node, traceback.format_exc()) + else: + self.lines.extend(lines) + + def start(self, node, env): + """ + Preprocess a source file to obtain the dependencies, which are accumulated to :py:attr:`waflib.Tools.c_preproc.c_parser.nodes` + and :py:attr:`waflib.Tools.c_preproc.c_parser.names`. + + :param node: source file + :type node: :py:class:`waflib.Node.Node` + :param env: config set containing additional defines to take into account + :type env: :py:class:`waflib.ConfigSet.ConfigSet` + """ + Logs.debug('preproc: scanning %s (in %s)', node.name, node.parent.name) + + self.current_file = node + self.addlines(node) + + # macros may be defined on the command-line, so they must be parsed as if they were part of the file + if env.DEFINES: + lst = format_defines(env.DEFINES) + lst.reverse() + self.lines.extend([('define', x) for x in lst]) + + while self.lines: + (token, line) = self.lines.pop() + if token == POPFILE: + self.count_files -= 1 + self.currentnode_stack.pop() + continue + + try: + state = self.state + + # make certain we define the state if we are about to enter in an if block + if token[:2] == 'if': + state.append(undefined) + elif token == 'endif': + state.pop() + + # skip lines when in a dead 'if' branch, wait for the endif + if token[0] != 'e': + if skipped in self.state or ignored in self.state: + continue + + if token == 'if': + ret = eval_macro(tokenize(line), self.defs) + if ret: + state[-1] = accepted + else: + state[-1] = ignored + elif token == 'ifdef': + m = re_mac.match(line) + if m and m.group() in self.defs: + state[-1] = accepted + else: + state[-1] = ignored + elif token == 'ifndef': + m = re_mac.match(line) + if m and m.group() in self.defs: + state[-1] = ignored + else: + state[-1] = accepted + elif token == 'include' or token == 'import': + (kind, inc) = extract_include(line, self.defs) + self.current_file = self.tryfind(inc, kind, env) + if token == 'import': + self.ban_includes.add(self.current_file) + elif token == 'elif': + if state[-1] == accepted: + state[-1] = skipped + elif state[-1] == ignored: + if eval_macro(tokenize(line), self.defs): + state[-1] = accepted + elif token == 'else': + if state[-1] == accepted: + state[-1] = skipped + elif state[-1] == ignored: + state[-1] = accepted + elif token == 'define': + try: + self.defs[self.define_name(line)] = line + except AttributeError: + raise PreprocError('Invalid define line %r' % line) + elif token == 'undef': + m = re_mac.match(line) + if m and m.group() in self.defs: + self.defs.__delitem__(m.group()) + #print "undef %s" % name + elif token == 'pragma': + if re_pragma_once.match(line.lower()): + self.ban_includes.add(self.current_file) + except Exception as e: + if Logs.verbose: + Logs.debug('preproc: line parsing failed (%s): %s %s', e, line, traceback.format_exc()) + + def define_name(self, line): + """ + :param line: define line + :type line: string + :rtype: string + :return: the define name + """ + return re_mac.match(line).group() + +def scan(task): + """ + Get the dependencies using a c/c++ preprocessor, this is required for finding dependencies of the kind:: + + #include some_macro() + + This function is bound as a task method on :py:class:`waflib.Tools.c.c` and :py:class:`waflib.Tools.cxx.cxx` for example + """ + try: + incn = task.generator.includes_nodes + except AttributeError: + raise Errors.WafError('%r is missing a feature such as "c", "cxx" or "includes": ' % task.generator) + + if go_absolute: + nodepaths = incn + [task.generator.bld.root.find_dir(x) for x in standard_includes] + else: + nodepaths = [x for x in incn if x.is_child_of(x.ctx.srcnode) or x.is_child_of(x.ctx.bldnode)] + + tmp = c_parser(nodepaths) + tmp.start(task.inputs[0], task.env) + return (tmp.nodes, tmp.names) diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/c_tests.py b/ldb-2.0.8/third_party/waf/waflib/Tools/c_tests.py new file mode 100644 index 0000000..7a4094f --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/c_tests.py @@ -0,0 +1,230 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2016-2018 (ita) + +""" +Various configuration tests. +""" + +from waflib import Task +from waflib.Configure import conf +from waflib.TaskGen import feature, before_method, after_method + +LIB_CODE = ''' +#ifdef _MSC_VER +#define testEXPORT __declspec(dllexport) +#else +#define testEXPORT +#endif +testEXPORT int lib_func(void) { return 9; } +''' + +MAIN_CODE = ''' +#ifdef _MSC_VER +#define testEXPORT __declspec(dllimport) +#else +#define testEXPORT +#endif +testEXPORT int lib_func(void); +int main(int argc, char **argv) { + (void)argc; (void)argv; + return !(lib_func() == 9); +} +''' + +@feature('link_lib_test') +@before_method('process_source') +def link_lib_test_fun(self): + """ + The configuration test :py:func:`waflib.Configure.run_build` declares a unique task generator, + so we need to create other task generators from here to check if the linker is able to link libraries. + """ + def write_test_file(task): + task.outputs[0].write(task.generator.code) + + rpath = [] + if getattr(self, 'add_rpath', False): + rpath = [self.bld.path.get_bld().abspath()] + + mode = self.mode + m = '%s %s' % (mode, mode) + ex = self.test_exec and 'test_exec' or '' + bld = self.bld + bld(rule=write_test_file, target='test.' + mode, code=LIB_CODE) + bld(rule=write_test_file, target='main.' + mode, code=MAIN_CODE) + bld(features='%sshlib' % m, source='test.' + mode, target='test') + bld(features='%sprogram %s' % (m, ex), source='main.' + mode, target='app', use='test', rpath=rpath) + +@conf +def check_library(self, mode=None, test_exec=True): + """ + Checks if libraries can be linked with the current linker. Uses :py:func:`waflib.Tools.c_tests.link_lib_test_fun`. + + :param mode: c or cxx or d + :type mode: string + """ + if not mode: + mode = 'c' + if self.env.CXX: + mode = 'cxx' + self.check( + compile_filename = [], + features = 'link_lib_test', + msg = 'Checking for libraries', + mode = mode, + test_exec = test_exec) + +######################################################################################## + +INLINE_CODE = ''' +typedef int foo_t; +static %s foo_t static_foo () {return 0; } +%s foo_t foo () { + return 0; +} +''' +INLINE_VALUES = ['inline', '__inline__', '__inline'] + +@conf +def check_inline(self, **kw): + """ + Checks for the right value for inline macro. + Define INLINE_MACRO to 1 if the define is found. + If the inline macro is not 'inline', add a define to the ``config.h`` (#define inline __inline__) + + :param define_name: define INLINE_MACRO by default to 1 if the macro is defined + :type define_name: string + :param features: by default *c* or *cxx* depending on the compiler present + :type features: list of string + """ + self.start_msg('Checking for inline') + + if not 'define_name' in kw: + kw['define_name'] = 'INLINE_MACRO' + if not 'features' in kw: + if self.env.CXX: + kw['features'] = ['cxx'] + else: + kw['features'] = ['c'] + + for x in INLINE_VALUES: + kw['fragment'] = INLINE_CODE % (x, x) + + try: + self.check(**kw) + except self.errors.ConfigurationError: + continue + else: + self.end_msg(x) + if x != 'inline': + self.define('inline', x, quote=False) + return x + self.fatal('could not use inline functions') + +######################################################################################## + +LARGE_FRAGMENT = '''#include +int main(int argc, char **argv) { + (void)argc; (void)argv; + return !(sizeof(off_t) >= 8); +} +''' + +@conf +def check_large_file(self, **kw): + """ + Checks for large file support and define the macro HAVE_LARGEFILE + The test is skipped on win32 systems (DEST_BINFMT == pe). + + :param define_name: define to set, by default *HAVE_LARGEFILE* + :type define_name: string + :param execute: execute the test (yes by default) + :type execute: bool + """ + if not 'define_name' in kw: + kw['define_name'] = 'HAVE_LARGEFILE' + if not 'execute' in kw: + kw['execute'] = True + + if not 'features' in kw: + if self.env.CXX: + kw['features'] = ['cxx', 'cxxprogram'] + else: + kw['features'] = ['c', 'cprogram'] + + kw['fragment'] = LARGE_FRAGMENT + + kw['msg'] = 'Checking for large file support' + ret = True + try: + if self.env.DEST_BINFMT != 'pe': + ret = self.check(**kw) + except self.errors.ConfigurationError: + pass + else: + if ret: + return True + + kw['msg'] = 'Checking for -D_FILE_OFFSET_BITS=64' + kw['defines'] = ['_FILE_OFFSET_BITS=64'] + try: + ret = self.check(**kw) + except self.errors.ConfigurationError: + pass + else: + self.define('_FILE_OFFSET_BITS', 64) + return ret + + self.fatal('There is no support for large files') + +######################################################################################## + +ENDIAN_FRAGMENT = ''' +short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; +short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; +int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; +} +short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; +short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; +int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; +} +extern int foo; +''' + +class grep_for_endianness(Task.Task): + """ + Task that reads a binary and tries to determine the endianness + """ + color = 'PINK' + def run(self): + txt = self.inputs[0].read(flags='rb').decode('latin-1') + if txt.find('LiTTleEnDian') > -1: + self.generator.tmp.append('little') + elif txt.find('BIGenDianSyS') > -1: + self.generator.tmp.append('big') + else: + return -1 + +@feature('grep_for_endianness') +@after_method('process_source') +def grep_for_endianness_fun(self): + """ + Used by the endianness configuration test + """ + self.create_task('grep_for_endianness', self.compiled_tasks[0].outputs[0]) + +@conf +def check_endianness(self): + """ + Executes a configuration test to determine the endianness + """ + tmp = [] + def check_msg(self): + return tmp[0] + self.check(fragment=ENDIAN_FRAGMENT, features='c grep_for_endianness', + msg='Checking for endianness', define='ENDIANNESS', tmp=tmp, + okmsg=check_msg, confcache=None) + return tmp[0] + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/ccroot.py b/ldb-2.0.8/third_party/waf/waflib/Tools/ccroot.py new file mode 100644 index 0000000..579d5b2 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/ccroot.py @@ -0,0 +1,791 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2005-2018 (ita) + +""" +Classes and methods shared by tools providing support for C-like language such +as C/C++/D/Assembly/Go (this support module is almost never used alone). +""" + +import os, re +from waflib import Task, Utils, Node, Errors, Logs +from waflib.TaskGen import after_method, before_method, feature, taskgen_method, extension +from waflib.Tools import c_aliases, c_preproc, c_config, c_osx, c_tests +from waflib.Configure import conf + +SYSTEM_LIB_PATHS = ['/usr/lib64', '/usr/lib', '/usr/local/lib64', '/usr/local/lib'] + +USELIB_VARS = Utils.defaultdict(set) +""" +Mapping for features to :py:class:`waflib.ConfigSet.ConfigSet` variables. See :py:func:`waflib.Tools.ccroot.propagate_uselib_vars`. +""" + +USELIB_VARS['c'] = set(['INCLUDES', 'FRAMEWORKPATH', 'DEFINES', 'CPPFLAGS', 'CCDEPS', 'CFLAGS', 'ARCH']) +USELIB_VARS['cxx'] = set(['INCLUDES', 'FRAMEWORKPATH', 'DEFINES', 'CPPFLAGS', 'CXXDEPS', 'CXXFLAGS', 'ARCH']) +USELIB_VARS['d'] = set(['INCLUDES', 'DFLAGS']) +USELIB_VARS['includes'] = set(['INCLUDES', 'FRAMEWORKPATH', 'ARCH']) + +USELIB_VARS['cprogram'] = USELIB_VARS['cxxprogram'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS', 'FRAMEWORK', 'FRAMEWORKPATH', 'ARCH', 'LDFLAGS']) +USELIB_VARS['cshlib'] = USELIB_VARS['cxxshlib'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS', 'FRAMEWORK', 'FRAMEWORKPATH', 'ARCH', 'LDFLAGS']) +USELIB_VARS['cstlib'] = USELIB_VARS['cxxstlib'] = set(['ARFLAGS', 'LINKDEPS']) + +USELIB_VARS['dprogram'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS']) +USELIB_VARS['dshlib'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS']) +USELIB_VARS['dstlib'] = set(['ARFLAGS', 'LINKDEPS']) + +USELIB_VARS['asm'] = set(['ASFLAGS']) + +# ================================================================================================= + +@taskgen_method +def create_compiled_task(self, name, node): + """ + Create the compilation task: c, cxx, asm, etc. The output node is created automatically (object file with a typical **.o** extension). + The task is appended to the list *compiled_tasks* which is then used by :py:func:`waflib.Tools.ccroot.apply_link` + + :param name: name of the task class + :type name: string + :param node: the file to compile + :type node: :py:class:`waflib.Node.Node` + :return: The task created + :rtype: :py:class:`waflib.Task.Task` + """ + out = '%s.%d.o' % (node.name, self.idx) + task = self.create_task(name, node, node.parent.find_or_declare(out)) + try: + self.compiled_tasks.append(task) + except AttributeError: + self.compiled_tasks = [task] + return task + +@taskgen_method +def to_incnodes(self, inlst): + """ + Task generator method provided to convert a list of string/nodes into a list of includes folders. + + The paths are assumed to be relative to the task generator path, except if they begin by **#** + in which case they are searched from the top-level directory (``bld.srcnode``). + The folders are simply assumed to be existing. + + The node objects in the list are returned in the output list. The strings are converted + into node objects if possible. The node is searched from the source directory, and if a match is found, + the equivalent build directory is created and added to the returned list too. When a folder cannot be found, it is ignored. + + :param inlst: list of folders + :type inlst: space-delimited string or a list of string/nodes + :rtype: list of :py:class:`waflib.Node.Node` + :return: list of include folders as nodes + """ + lst = [] + seen = set() + for x in self.to_list(inlst): + if x in seen or not x: + continue + seen.add(x) + + # with a real lot of targets, it is sometimes interesting to cache the results below + if isinstance(x, Node.Node): + lst.append(x) + else: + if os.path.isabs(x): + lst.append(self.bld.root.make_node(x) or x) + else: + if x[0] == '#': + p = self.bld.bldnode.make_node(x[1:]) + v = self.bld.srcnode.make_node(x[1:]) + else: + p = self.path.get_bld().make_node(x) + v = self.path.make_node(x) + if p.is_child_of(self.bld.bldnode): + p.mkdir() + lst.append(p) + lst.append(v) + return lst + +@feature('c', 'cxx', 'd', 'asm', 'fc', 'includes') +@after_method('propagate_uselib_vars', 'process_source') +def apply_incpaths(self): + """ + Task generator method that processes the attribute *includes*:: + + tg = bld(features='includes', includes='.') + + The folders only need to be relative to the current directory, the equivalent build directory is + added automatically (for headers created in the build directory). This enables using a build directory + or not (``top == out``). + + This method will add a list of nodes read by :py:func:`waflib.Tools.ccroot.to_incnodes` in ``tg.env.INCPATHS``, + and the list of include paths in ``tg.env.INCLUDES``. + """ + + lst = self.to_incnodes(self.to_list(getattr(self, 'includes', [])) + self.env.INCLUDES) + self.includes_nodes = lst + cwd = self.get_cwd() + self.env.INCPATHS = [x.path_from(cwd) for x in lst] + +class link_task(Task.Task): + """ + Base class for all link tasks. A task generator is supposed to have at most one link task bound in the attribute *link_task*. See :py:func:`waflib.Tools.ccroot.apply_link`. + + .. inheritance-diagram:: waflib.Tools.ccroot.stlink_task waflib.Tools.c.cprogram waflib.Tools.c.cshlib waflib.Tools.cxx.cxxstlib waflib.Tools.cxx.cxxprogram waflib.Tools.cxx.cxxshlib waflib.Tools.d.dprogram waflib.Tools.d.dshlib waflib.Tools.d.dstlib waflib.Tools.ccroot.fake_shlib waflib.Tools.ccroot.fake_stlib waflib.Tools.asm.asmprogram waflib.Tools.asm.asmshlib waflib.Tools.asm.asmstlib + """ + color = 'YELLOW' + + weight = 3 + """Try to process link tasks as early as possible""" + + inst_to = None + """Default installation path for the link task outputs, or None to disable""" + + chmod = Utils.O755 + """Default installation mode for the link task outputs""" + + def add_target(self, target): + """ + Process the *target* attribute to add the platform-specific prefix/suffix such as *.so* or *.exe*. + The settings are retrieved from ``env.clsname_PATTERN`` + """ + if isinstance(target, str): + base = self.generator.path + if target.startswith('#'): + # for those who like flat structures + target = target[1:] + base = self.generator.bld.bldnode + + pattern = self.env[self.__class__.__name__ + '_PATTERN'] + if not pattern: + pattern = '%s' + folder, name = os.path.split(target) + + if self.__class__.__name__.find('shlib') > 0 and getattr(self.generator, 'vnum', None): + nums = self.generator.vnum.split('.') + if self.env.DEST_BINFMT == 'pe': + # include the version in the dll file name, + # the import lib file name stays unversioned. + name = name + '-' + nums[0] + elif self.env.DEST_OS == 'openbsd': + pattern = '%s.%s' % (pattern, nums[0]) + if len(nums) >= 2: + pattern += '.%s' % nums[1] + + if folder: + tmp = folder + os.sep + pattern % name + else: + tmp = pattern % name + target = base.find_or_declare(tmp) + self.set_outputs(target) + + def exec_command(self, *k, **kw): + ret = super(link_task, self).exec_command(*k, **kw) + if not ret and self.env.DO_MANIFEST: + ret = self.exec_mf() + return ret + + def exec_mf(self): + """ + Create manifest files for VS-like compilers (msvc, ifort, ...) + """ + if not self.env.MT: + return 0 + + manifest = None + for out_node in self.outputs: + if out_node.name.endswith('.manifest'): + manifest = out_node.abspath() + break + else: + # Should never get here. If we do, it means the manifest file was + # never added to the outputs list, thus we don't have a manifest file + # to embed, so we just return. + return 0 + + # embedding mode. Different for EXE's and DLL's. + # see: http://msdn2.microsoft.com/en-us/library/ms235591(VS.80).aspx + mode = '' + for x in Utils.to_list(self.generator.features): + if x in ('cprogram', 'cxxprogram', 'fcprogram', 'fcprogram_test'): + mode = 1 + elif x in ('cshlib', 'cxxshlib', 'fcshlib'): + mode = 2 + + Logs.debug('msvc: embedding manifest in mode %r', mode) + + lst = [] + self.env.MT + lst.extend(Utils.to_list(self.env.MTFLAGS)) + lst.extend(['-manifest', manifest]) + lst.append('-outputresource:%s;%s' % (self.outputs[0].abspath(), mode)) + + return super(link_task, self).exec_command(lst) + +class stlink_task(link_task): + """ + Base for static link tasks, which use *ar* most of the time. + The target is always removed before being written. + """ + run_str = '${AR} ${ARFLAGS} ${AR_TGT_F}${TGT} ${AR_SRC_F}${SRC}' + + chmod = Utils.O644 + """Default installation mode for the static libraries""" + +def rm_tgt(cls): + old = cls.run + def wrap(self): + try: + os.remove(self.outputs[0].abspath()) + except OSError: + pass + return old(self) + setattr(cls, 'run', wrap) +rm_tgt(stlink_task) + +@feature('skip_stlib_link_deps') +@before_method('process_use') +def apply_skip_stlib_link_deps(self): + """ + This enables an optimization in the :py:func:wafilb.Tools.ccroot.processes_use: method that skips dependency and + link flag optimizations for targets that generate static libraries (via the :py:class:Tools.ccroot.stlink_task task). + The actual behavior is implemented in :py:func:wafilb.Tools.ccroot.processes_use: method so this feature only tells waf + to enable the new behavior. + """ + self.env.SKIP_STLIB_LINK_DEPS = True + +@feature('c', 'cxx', 'd', 'fc', 'asm') +@after_method('process_source') +def apply_link(self): + """ + Collect the tasks stored in ``compiled_tasks`` (created by :py:func:`waflib.Tools.ccroot.create_compiled_task`), and + use the outputs for a new instance of :py:class:`waflib.Tools.ccroot.link_task`. The class to use is the first link task + matching a name from the attribute *features*, for example:: + + def build(bld): + tg = bld(features='cxx cxxprogram cprogram', source='main.c', target='app') + + will create the task ``tg.link_task`` as a new instance of :py:class:`waflib.Tools.cxx.cxxprogram` + """ + + for x in self.features: + if x == 'cprogram' and 'cxx' in self.features: # limited compat + x = 'cxxprogram' + elif x == 'cshlib' and 'cxx' in self.features: + x = 'cxxshlib' + + if x in Task.classes: + if issubclass(Task.classes[x], link_task): + link = x + break + else: + return + + objs = [t.outputs[0] for t in getattr(self, 'compiled_tasks', [])] + self.link_task = self.create_task(link, objs) + self.link_task.add_target(self.target) + + # remember that the install paths are given by the task generators + try: + inst_to = self.install_path + except AttributeError: + inst_to = self.link_task.inst_to + if inst_to: + # install a copy of the node list we have at this moment (implib not added) + self.install_task = self.add_install_files( + install_to=inst_to, install_from=self.link_task.outputs[:], + chmod=self.link_task.chmod, task=self.link_task) + +@taskgen_method +def use_rec(self, name, **kw): + """ + Processes the ``use`` keyword recursively. This method is kind of private and only meant to be used from ``process_use`` + """ + + if name in self.tmp_use_not or name in self.tmp_use_seen: + return + + try: + y = self.bld.get_tgen_by_name(name) + except Errors.WafError: + self.uselib.append(name) + self.tmp_use_not.add(name) + return + + self.tmp_use_seen.append(name) + y.post() + + # bind temporary attributes on the task generator + y.tmp_use_objects = objects = kw.get('objects', True) + y.tmp_use_stlib = stlib = kw.get('stlib', True) + try: + link_task = y.link_task + except AttributeError: + y.tmp_use_var = '' + else: + objects = False + if not isinstance(link_task, stlink_task): + stlib = False + y.tmp_use_var = 'LIB' + else: + y.tmp_use_var = 'STLIB' + + p = self.tmp_use_prec + for x in self.to_list(getattr(y, 'use', [])): + if self.env["STLIB_" + x]: + continue + try: + p[x].append(name) + except KeyError: + p[x] = [name] + self.use_rec(x, objects=objects, stlib=stlib) + +@feature('c', 'cxx', 'd', 'use', 'fc') +@before_method('apply_incpaths', 'propagate_uselib_vars') +@after_method('apply_link', 'process_source') +def process_use(self): + """ + Process the ``use`` attribute which contains a list of task generator names:: + + def build(bld): + bld.shlib(source='a.c', target='lib1') + bld.program(source='main.c', target='app', use='lib1') + + See :py:func:`waflib.Tools.ccroot.use_rec`. + """ + + use_not = self.tmp_use_not = set() + self.tmp_use_seen = [] # we would like an ordered set + use_prec = self.tmp_use_prec = {} + self.uselib = self.to_list(getattr(self, 'uselib', [])) + self.includes = self.to_list(getattr(self, 'includes', [])) + names = self.to_list(getattr(self, 'use', [])) + + for x in names: + self.use_rec(x) + + for x in use_not: + if x in use_prec: + del use_prec[x] + + # topological sort + out = self.tmp_use_sorted = [] + tmp = [] + for x in self.tmp_use_seen: + for k in use_prec.values(): + if x in k: + break + else: + tmp.append(x) + + while tmp: + e = tmp.pop() + out.append(e) + try: + nlst = use_prec[e] + except KeyError: + pass + else: + del use_prec[e] + for x in nlst: + for y in use_prec: + if x in use_prec[y]: + break + else: + tmp.append(x) + if use_prec: + raise Errors.WafError('Cycle detected in the use processing %r' % use_prec) + out.reverse() + + link_task = getattr(self, 'link_task', None) + for x in out: + y = self.bld.get_tgen_by_name(x) + var = y.tmp_use_var + if var and link_task: + if self.env.SKIP_STLIB_LINK_DEPS and isinstance(link_task, stlink_task): + # If the skip_stlib_link_deps feature is enabled then we should + # avoid adding lib deps to the stlink_task instance. + pass + elif var == 'LIB' or y.tmp_use_stlib or x in names: + self.env.append_value(var, [y.target[y.target.rfind(os.sep) + 1:]]) + self.link_task.dep_nodes.extend(y.link_task.outputs) + tmp_path = y.link_task.outputs[0].parent.path_from(self.get_cwd()) + self.env.append_unique(var + 'PATH', [tmp_path]) + else: + if y.tmp_use_objects: + self.add_objects_from_tgen(y) + + if getattr(y, 'export_includes', None): + # self.includes may come from a global variable #2035 + self.includes = self.includes + y.to_incnodes(y.export_includes) + + if getattr(y, 'export_defines', None): + self.env.append_value('DEFINES', self.to_list(y.export_defines)) + + + # and finally, add the use variables (no recursion needed) + for x in names: + try: + y = self.bld.get_tgen_by_name(x) + except Errors.WafError: + if not self.env['STLIB_' + x] and not x in self.uselib: + self.uselib.append(x) + else: + for k in self.to_list(getattr(y, 'use', [])): + if not self.env['STLIB_' + k] and not k in self.uselib: + self.uselib.append(k) + +@taskgen_method +def accept_node_to_link(self, node): + """ + PRIVATE INTERNAL USE ONLY + """ + return not node.name.endswith('.pdb') + +@taskgen_method +def add_objects_from_tgen(self, tg): + """ + Add the objects from the depending compiled tasks as link task inputs. + + Some objects are filtered: for instance, .pdb files are added + to the compiled tasks but not to the link tasks (to avoid errors) + PRIVATE INTERNAL USE ONLY + """ + try: + link_task = self.link_task + except AttributeError: + pass + else: + for tsk in getattr(tg, 'compiled_tasks', []): + for x in tsk.outputs: + if self.accept_node_to_link(x): + link_task.inputs.append(x) + +@taskgen_method +def get_uselib_vars(self): + """ + :return: the *uselib* variables associated to the *features* attribute (see :py:attr:`waflib.Tools.ccroot.USELIB_VARS`) + :rtype: list of string + """ + _vars = set() + for x in self.features: + if x in USELIB_VARS: + _vars |= USELIB_VARS[x] + return _vars + +@feature('c', 'cxx', 'd', 'fc', 'javac', 'cs', 'uselib', 'asm') +@after_method('process_use') +def propagate_uselib_vars(self): + """ + Process uselib variables for adding flags. For example, the following target:: + + def build(bld): + bld.env.AFLAGS_aaa = ['bar'] + from waflib.Tools.ccroot import USELIB_VARS + USELIB_VARS['aaa'] = ['AFLAGS'] + + tg = bld(features='aaa', aflags='test') + + The *aflags* attribute will be processed and this method will set:: + + tg.env.AFLAGS = ['bar', 'test'] + """ + _vars = self.get_uselib_vars() + env = self.env + app = env.append_value + feature_uselib = self.features + self.to_list(getattr(self, 'uselib', [])) + for var in _vars: + y = var.lower() + val = getattr(self, y, []) + if val: + app(var, self.to_list(val)) + + for x in feature_uselib: + val = env['%s_%s' % (var, x)] + if val: + app(var, val) + +# ============ the code above must not know anything about import libs ========== + +@feature('cshlib', 'cxxshlib', 'fcshlib') +@after_method('apply_link') +def apply_implib(self): + """ + Handle dlls and their import libs on Windows-like systems. + + A ``.dll.a`` file called *import library* is generated. + It must be installed as it is required for linking the library. + """ + if not self.env.DEST_BINFMT == 'pe': + return + + dll = self.link_task.outputs[0] + if isinstance(self.target, Node.Node): + name = self.target.name + else: + name = os.path.split(self.target)[1] + implib = self.env.implib_PATTERN % name + implib = dll.parent.find_or_declare(implib) + self.env.append_value('LINKFLAGS', self.env.IMPLIB_ST % implib.bldpath()) + self.link_task.outputs.append(implib) + + if getattr(self, 'defs', None) and self.env.DEST_BINFMT == 'pe': + node = self.path.find_resource(self.defs) + if not node: + raise Errors.WafError('invalid def file %r' % self.defs) + if self.env.def_PATTERN: + self.env.append_value('LINKFLAGS', self.env.def_PATTERN % node.path_from(self.get_cwd())) + self.link_task.dep_nodes.append(node) + else: + # gcc for windows takes *.def file as input without any special flag + self.link_task.inputs.append(node) + + # where to put the import library + if getattr(self, 'install_task', None): + try: + # user has given a specific installation path for the import library + inst_to = self.install_path_implib + except AttributeError: + try: + # user has given an installation path for the main library, put the import library in it + inst_to = self.install_path + except AttributeError: + # else, put the library in BINDIR and the import library in LIBDIR + inst_to = '${IMPLIBDIR}' + self.install_task.install_to = '${BINDIR}' + if not self.env.IMPLIBDIR: + self.env.IMPLIBDIR = self.env.LIBDIR + self.implib_install_task = self.add_install_files(install_to=inst_to, install_from=implib, + chmod=self.link_task.chmod, task=self.link_task) + +# ============ the code above must not know anything about vnum processing on unix platforms ========= + +re_vnum = re.compile('^([1-9]\\d*|0)([.]([1-9]\\d*|0)){0,2}?$') +@feature('cshlib', 'cxxshlib', 'dshlib', 'fcshlib', 'vnum') +@after_method('apply_link', 'propagate_uselib_vars') +def apply_vnum(self): + """ + Enforce version numbering on shared libraries. The valid version numbers must have either zero or two dots:: + + def build(bld): + bld.shlib(source='a.c', target='foo', vnum='14.15.16') + + In this example on Linux platform, ``libfoo.so`` is installed as ``libfoo.so.14.15.16``, and the following symbolic links are created: + + * ``libfoo.so → libfoo.so.14.15.16`` + * ``libfoo.so.14 → libfoo.so.14.15.16`` + + By default, the library will be assigned SONAME ``libfoo.so.14``, effectively declaring ABI compatibility between all minor and patch releases for the major version of the library. When necessary, the compatibility can be explicitly defined using `cnum` parameter: + + def build(bld): + bld.shlib(source='a.c', target='foo', vnum='14.15.16', cnum='14.15') + + In this case, the assigned SONAME will be ``libfoo.so.14.15`` with ABI compatibility only between path releases for a specific major and minor version of the library. + + On OS X platform, install-name parameter will follow the above logic for SONAME with exception that it also specifies an absolute path (based on install_path) of the library. + """ + if not getattr(self, 'vnum', '') or os.name != 'posix' or self.env.DEST_BINFMT not in ('elf', 'mac-o'): + return + + link = self.link_task + if not re_vnum.match(self.vnum): + raise Errors.WafError('Invalid vnum %r for target %r' % (self.vnum, getattr(self, 'name', self))) + nums = self.vnum.split('.') + node = link.outputs[0] + + cnum = getattr(self, 'cnum', str(nums[0])) + cnums = cnum.split('.') + if len(cnums)>len(nums) or nums[0:len(cnums)] != cnums: + raise Errors.WafError('invalid compatibility version %s' % cnum) + + libname = node.name + if libname.endswith('.dylib'): + name3 = libname.replace('.dylib', '.%s.dylib' % self.vnum) + name2 = libname.replace('.dylib', '.%s.dylib' % cnum) + else: + name3 = libname + '.' + self.vnum + name2 = libname + '.' + cnum + + # add the so name for the ld linker - to disable, just unset env.SONAME_ST + if self.env.SONAME_ST: + v = self.env.SONAME_ST % name2 + self.env.append_value('LINKFLAGS', v.split()) + + # the following task is just to enable execution from the build dir :-/ + if self.env.DEST_OS != 'openbsd': + outs = [node.parent.make_node(name3)] + if name2 != name3: + outs.append(node.parent.make_node(name2)) + self.create_task('vnum', node, outs) + + if getattr(self, 'install_task', None): + self.install_task.hasrun = Task.SKIPPED + self.install_task.no_errcheck_out = True + path = self.install_task.install_to + if self.env.DEST_OS == 'openbsd': + libname = self.link_task.outputs[0].name + t1 = self.add_install_as(install_to='%s/%s' % (path, libname), install_from=node, chmod=self.link_task.chmod) + self.vnum_install_task = (t1,) + else: + t1 = self.add_install_as(install_to=path + os.sep + name3, install_from=node, chmod=self.link_task.chmod) + t3 = self.add_symlink_as(install_to=path + os.sep + libname, install_from=name3) + if name2 != name3: + t2 = self.add_symlink_as(install_to=path + os.sep + name2, install_from=name3) + self.vnum_install_task = (t1, t2, t3) + else: + self.vnum_install_task = (t1, t3) + + if '-dynamiclib' in self.env.LINKFLAGS: + # this requires after(propagate_uselib_vars) + try: + inst_to = self.install_path + except AttributeError: + inst_to = self.link_task.inst_to + if inst_to: + p = Utils.subst_vars(inst_to, self.env) + path = os.path.join(p, name2) + self.env.append_value('LINKFLAGS', ['-install_name', path]) + self.env.append_value('LINKFLAGS', '-Wl,-compatibility_version,%s' % cnum) + self.env.append_value('LINKFLAGS', '-Wl,-current_version,%s' % self.vnum) + +class vnum(Task.Task): + """ + Create the symbolic links for a versioned shared library. Instances are created by :py:func:`waflib.Tools.ccroot.apply_vnum` + """ + color = 'CYAN' + ext_in = ['.bin'] + def keyword(self): + return 'Symlinking' + def run(self): + for x in self.outputs: + path = x.abspath() + try: + os.remove(path) + except OSError: + pass + + try: + os.symlink(self.inputs[0].name, path) + except OSError: + return 1 + +class fake_shlib(link_task): + """ + Task used for reading a system library and adding the dependency on it + """ + def runnable_status(self): + for t in self.run_after: + if not t.hasrun: + return Task.ASK_LATER + return Task.SKIP_ME + +class fake_stlib(stlink_task): + """ + Task used for reading a system library and adding the dependency on it + """ + def runnable_status(self): + for t in self.run_after: + if not t.hasrun: + return Task.ASK_LATER + return Task.SKIP_ME + +@conf +def read_shlib(self, name, paths=[], export_includes=[], export_defines=[]): + """ + Read a system shared library, enabling its use as a local library. Will trigger a rebuild if the file changes:: + + def build(bld): + bld.read_shlib('m') + bld.program(source='main.c', use='m') + """ + return self(name=name, features='fake_lib', lib_paths=paths, lib_type='shlib', export_includes=export_includes, export_defines=export_defines) + +@conf +def read_stlib(self, name, paths=[], export_includes=[], export_defines=[]): + """ + Read a system static library, enabling a use as a local library. Will trigger a rebuild if the file changes. + """ + return self(name=name, features='fake_lib', lib_paths=paths, lib_type='stlib', export_includes=export_includes, export_defines=export_defines) + +lib_patterns = { + 'shlib' : ['lib%s.so', '%s.so', 'lib%s.dylib', 'lib%s.dll', '%s.dll'], + 'stlib' : ['lib%s.a', '%s.a', 'lib%s.dll', '%s.dll', 'lib%s.lib', '%s.lib'], +} + +@feature('fake_lib') +def process_lib(self): + """ + Find the location of a foreign library. Used by :py:class:`waflib.Tools.ccroot.read_shlib` and :py:class:`waflib.Tools.ccroot.read_stlib`. + """ + node = None + + names = [x % self.name for x in lib_patterns[self.lib_type]] + for x in self.lib_paths + [self.path] + SYSTEM_LIB_PATHS: + if not isinstance(x, Node.Node): + x = self.bld.root.find_node(x) or self.path.find_node(x) + if not x: + continue + + for y in names: + node = x.find_node(y) + if node: + try: + Utils.h_file(node.abspath()) + except EnvironmentError: + raise ValueError('Could not read %r' % y) + break + else: + continue + break + else: + raise Errors.WafError('could not find library %r' % self.name) + self.link_task = self.create_task('fake_%s' % self.lib_type, [], [node]) + self.target = self.name + + +class fake_o(Task.Task): + def runnable_status(self): + return Task.SKIP_ME + +@extension('.o', '.obj') +def add_those_o_files(self, node): + tsk = self.create_task('fake_o', [], node) + try: + self.compiled_tasks.append(tsk) + except AttributeError: + self.compiled_tasks = [tsk] + +@feature('fake_obj') +@before_method('process_source') +def process_objs(self): + """ + Puts object files in the task generator outputs + """ + for node in self.to_nodes(self.source): + self.add_those_o_files(node) + self.source = [] + +@conf +def read_object(self, obj): + """ + Read an object file, enabling injection in libs/programs. Will trigger a rebuild if the file changes. + + :param obj: object file path, as string or Node + """ + if not isinstance(obj, self.path.__class__): + obj = self.path.find_resource(obj) + return self(features='fake_obj', source=obj, name=obj.name) + +@feature('cxxprogram', 'cprogram') +@after_method('apply_link', 'process_use') +def set_full_paths_hpux(self): + """ + On hp-ux, extend the libpaths and static library paths to absolute paths + """ + if self.env.DEST_OS != 'hp-ux': + return + base = self.bld.bldnode.abspath() + for var in ['LIBPATH', 'STLIBPATH']: + lst = [] + for x in self.env[var]: + if x.startswith('/'): + lst.append(x) + else: + lst.append(os.path.normpath(os.path.join(base, x))) + self.env[var] = lst + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/clang.py b/ldb-2.0.8/third_party/waf/waflib/Tools/clang.py new file mode 100644 index 0000000..3828e39 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/clang.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Krzysztof Kosiński 2014 + +""" +Detect the Clang C compiler +""" + +from waflib.Tools import ccroot, ar, gcc +from waflib.Configure import conf + +@conf +def find_clang(conf): + """ + Finds the program clang and executes it to ensure it really is clang + """ + cc = conf.find_program('clang', var='CC') + conf.get_cc_version(cc, clang=True) + conf.env.CC_NAME = 'clang' + +def configure(conf): + conf.find_clang() + conf.find_program(['llvm-ar', 'ar'], var='AR') + conf.find_ar() + conf.gcc_common_flags() + conf.gcc_modifier_platform() + conf.cc_load_tools() + conf.cc_add_flags() + conf.link_add_flags() diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/clangxx.py b/ldb-2.0.8/third_party/waf/waflib/Tools/clangxx.py new file mode 100644 index 0000000..152013c --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/clangxx.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy 2009-2018 (ita) + +""" +Detect the Clang++ C++ compiler +""" + +from waflib.Tools import ccroot, ar, gxx +from waflib.Configure import conf + +@conf +def find_clangxx(conf): + """ + Finds the program clang++, and executes it to ensure it really is clang++ + """ + cxx = conf.find_program('clang++', var='CXX') + conf.get_cc_version(cxx, clang=True) + conf.env.CXX_NAME = 'clang' + +def configure(conf): + conf.find_clangxx() + conf.find_program(['llvm-ar', 'ar'], var='AR') + conf.find_ar() + conf.gxx_common_flags() + conf.gxx_modifier_platform() + conf.cxx_load_tools() + conf.cxx_add_flags() + conf.link_add_flags() + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_c.py b/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_c.py new file mode 100644 index 0000000..2dba3f8 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_c.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Matthias Jahn jahn dôt matthias ât freenet dôt de, 2007 (pmarat) + +""" +Try to detect a C compiler from the list of supported compilers (gcc, msvc, etc):: + + def options(opt): + opt.load('compiler_c') + def configure(cnf): + cnf.load('compiler_c') + def build(bld): + bld.program(source='main.c', target='app') + +The compilers are associated to platforms in :py:attr:`waflib.Tools.compiler_c.c_compiler`. To register +a new C compiler named *cfoo* (assuming the tool ``waflib/extras/cfoo.py`` exists), use:: + + from waflib.Tools.compiler_c import c_compiler + c_compiler['win32'] = ['cfoo', 'msvc', 'gcc'] + + def options(opt): + opt.load('compiler_c') + def configure(cnf): + cnf.load('compiler_c') + def build(bld): + bld.program(source='main.c', target='app') + +Not all compilers need to have a specific tool. For example, the clang compilers can be detected by the gcc tools when using:: + + $ CC=clang waf configure +""" + +import re +from waflib.Tools import ccroot +from waflib import Utils +from waflib.Logs import debug + +c_compiler = { +'win32': ['msvc', 'gcc', 'clang'], +'cygwin': ['gcc'], +'darwin': ['clang', 'gcc'], +'aix': ['xlc', 'gcc', 'clang'], +'linux': ['gcc', 'clang', 'icc'], +'sunos': ['suncc', 'gcc'], +'irix': ['gcc', 'irixcc'], +'hpux': ['gcc'], +'osf1V': ['gcc'], +'gnu': ['gcc', 'clang'], +'java': ['gcc', 'msvc', 'clang', 'icc'], +'default':['clang', 'gcc'], +} +""" +Dict mapping platform names to Waf tools finding specific C compilers:: + + from waflib.Tools.compiler_c import c_compiler + c_compiler['linux'] = ['gcc', 'icc', 'suncc'] +""" + +def default_compilers(): + build_platform = Utils.unversioned_sys_platform() + possible_compiler_list = c_compiler.get(build_platform, c_compiler['default']) + return ' '.join(possible_compiler_list) + +def configure(conf): + """ + Detects a suitable C compiler + + :raises: :py:class:`waflib.Errors.ConfigurationError` when no suitable compiler is found + """ + try: + test_for_compiler = conf.options.check_c_compiler or default_compilers() + except AttributeError: + conf.fatal("Add options(opt): opt.load('compiler_c')") + + for compiler in re.split('[ ,]+', test_for_compiler): + conf.env.stash() + conf.start_msg('Checking for %r (C compiler)' % compiler) + try: + conf.load(compiler) + except conf.errors.ConfigurationError as e: + conf.env.revert() + conf.end_msg(False) + debug('compiler_c: %r', e) + else: + if conf.env.CC: + conf.end_msg(conf.env.get_flat('CC')) + conf.env.COMPILER_CC = compiler + conf.env.commit() + break + conf.env.revert() + conf.end_msg(False) + else: + conf.fatal('could not configure a C compiler!') + +def options(opt): + """ + This is how to provide compiler preferences on the command-line:: + + $ waf configure --check-c-compiler=gcc + """ + test_for_compiler = default_compilers() + opt.load_special_tools('c_*.py', ban=['c_dumbpreproc.py']) + cc_compiler_opts = opt.add_option_group('Configuration options') + cc_compiler_opts.add_option('--check-c-compiler', default=None, + help='list of C compilers to try [%s]' % test_for_compiler, + dest="check_c_compiler") + + for x in test_for_compiler.split(): + opt.load('%s' % x) + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_cxx.py b/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_cxx.py new file mode 100644 index 0000000..1af65a2 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_cxx.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Matthias Jahn jahn dôt matthias ât freenet dôt de 2007 (pmarat) + +""" +Try to detect a C++ compiler from the list of supported compilers (g++, msvc, etc):: + + def options(opt): + opt.load('compiler_cxx') + def configure(cnf): + cnf.load('compiler_cxx') + def build(bld): + bld.program(source='main.cpp', target='app') + +The compilers are associated to platforms in :py:attr:`waflib.Tools.compiler_cxx.cxx_compiler`. To register +a new C++ compiler named *cfoo* (assuming the tool ``waflib/extras/cfoo.py`` exists), use:: + + from waflib.Tools.compiler_cxx import cxx_compiler + cxx_compiler['win32'] = ['cfoo', 'msvc', 'gcc'] + + def options(opt): + opt.load('compiler_cxx') + def configure(cnf): + cnf.load('compiler_cxx') + def build(bld): + bld.program(source='main.c', target='app') + +Not all compilers need to have a specific tool. For example, the clang compilers can be detected by the gcc tools when using:: + + $ CXX=clang waf configure +""" + + +import re +from waflib.Tools import ccroot +from waflib import Utils +from waflib.Logs import debug + +cxx_compiler = { +'win32': ['msvc', 'g++', 'clang++'], +'cygwin': ['g++'], +'darwin': ['clang++', 'g++'], +'aix': ['xlc++', 'g++', 'clang++'], +'linux': ['g++', 'clang++', 'icpc'], +'sunos': ['sunc++', 'g++'], +'irix': ['g++'], +'hpux': ['g++'], +'osf1V': ['g++'], +'gnu': ['g++', 'clang++'], +'java': ['g++', 'msvc', 'clang++', 'icpc'], +'default': ['clang++', 'g++'] +} +""" +Dict mapping the platform names to Waf tools finding specific C++ compilers:: + + from waflib.Tools.compiler_cxx import cxx_compiler + cxx_compiler['linux'] = ['gxx', 'icpc', 'suncxx'] +""" + +def default_compilers(): + build_platform = Utils.unversioned_sys_platform() + possible_compiler_list = cxx_compiler.get(build_platform, cxx_compiler['default']) + return ' '.join(possible_compiler_list) + +def configure(conf): + """ + Detects a suitable C++ compiler + + :raises: :py:class:`waflib.Errors.ConfigurationError` when no suitable compiler is found + """ + try: + test_for_compiler = conf.options.check_cxx_compiler or default_compilers() + except AttributeError: + conf.fatal("Add options(opt): opt.load('compiler_cxx')") + + for compiler in re.split('[ ,]+', test_for_compiler): + conf.env.stash() + conf.start_msg('Checking for %r (C++ compiler)' % compiler) + try: + conf.load(compiler) + except conf.errors.ConfigurationError as e: + conf.env.revert() + conf.end_msg(False) + debug('compiler_cxx: %r', e) + else: + if conf.env.CXX: + conf.end_msg(conf.env.get_flat('CXX')) + conf.env.COMPILER_CXX = compiler + conf.env.commit() + break + conf.env.revert() + conf.end_msg(False) + else: + conf.fatal('could not configure a C++ compiler!') + +def options(opt): + """ + This is how to provide compiler preferences on the command-line:: + + $ waf configure --check-cxx-compiler=gxx + """ + test_for_compiler = default_compilers() + opt.load_special_tools('cxx_*.py') + cxx_compiler_opts = opt.add_option_group('Configuration options') + cxx_compiler_opts.add_option('--check-cxx-compiler', default=None, + help='list of C++ compilers to try [%s]' % test_for_compiler, + dest="check_cxx_compiler") + + for x in test_for_compiler.split(): + opt.load('%s' % x) + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_d.py b/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_d.py new file mode 100644 index 0000000..43bb1f6 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_d.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Carlos Rafael Giani, 2007 (dv) +# Thomas Nagy, 2016-2018 (ita) + +""" +Try to detect a D compiler from the list of supported compilers:: + + def options(opt): + opt.load('compiler_d') + def configure(cnf): + cnf.load('compiler_d') + def build(bld): + bld.program(source='main.d', target='app') + +Only three D compilers are really present at the moment: + +* gdc +* dmd, the ldc compiler having a very similar command-line interface +* ldc2 +""" + +import re +from waflib import Utils, Logs + +d_compiler = { +'default' : ['gdc', 'dmd', 'ldc2'] +} +""" +Dict mapping the platform names to lists of names of D compilers to try, in order of preference:: + + from waflib.Tools.compiler_d import d_compiler + d_compiler['default'] = ['gdc', 'dmd', 'ldc2'] +""" + +def default_compilers(): + build_platform = Utils.unversioned_sys_platform() + possible_compiler_list = d_compiler.get(build_platform, d_compiler['default']) + return ' '.join(possible_compiler_list) + +def configure(conf): + """ + Detects a suitable D compiler + + :raises: :py:class:`waflib.Errors.ConfigurationError` when no suitable compiler is found + """ + try: + test_for_compiler = conf.options.check_d_compiler or default_compilers() + except AttributeError: + conf.fatal("Add options(opt): opt.load('compiler_d')") + + for compiler in re.split('[ ,]+', test_for_compiler): + conf.env.stash() + conf.start_msg('Checking for %r (D compiler)' % compiler) + try: + conf.load(compiler) + except conf.errors.ConfigurationError as e: + conf.env.revert() + conf.end_msg(False) + Logs.debug('compiler_d: %r', e) + else: + if conf.env.D: + conf.end_msg(conf.env.get_flat('D')) + conf.env.COMPILER_D = compiler + conf.env.commit() + break + conf.env.revert() + conf.end_msg(False) + else: + conf.fatal('could not configure a D compiler!') + +def options(opt): + """ + This is how to provide compiler preferences on the command-line:: + + $ waf configure --check-d-compiler=dmd + """ + test_for_compiler = default_compilers() + d_compiler_opts = opt.add_option_group('Configuration options') + d_compiler_opts.add_option('--check-d-compiler', default=None, + help='list of D compilers to try [%s]' % test_for_compiler, dest='check_d_compiler') + + for x in test_for_compiler.split(): + opt.load('%s' % x) + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_fc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_fc.py new file mode 100644 index 0000000..96b58e7 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_fc.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python +# encoding: utf-8 + +import re +from waflib import Utils, Logs +from waflib.Tools import fc + +fc_compiler = { + 'win32' : ['gfortran','ifort'], + 'darwin' : ['gfortran', 'g95', 'ifort'], + 'linux' : ['gfortran', 'g95', 'ifort'], + 'java' : ['gfortran', 'g95', 'ifort'], + 'default': ['gfortran'], + 'aix' : ['gfortran'] +} +""" +Dict mapping the platform names to lists of names of Fortran compilers to try, in order of preference:: + + from waflib.Tools.compiler_c import c_compiler + c_compiler['linux'] = ['gfortran', 'g95', 'ifort'] +""" + +def default_compilers(): + build_platform = Utils.unversioned_sys_platform() + possible_compiler_list = fc_compiler.get(build_platform, fc_compiler['default']) + return ' '.join(possible_compiler_list) + +def configure(conf): + """ + Detects a suitable Fortran compiler + + :raises: :py:class:`waflib.Errors.ConfigurationError` when no suitable compiler is found + """ + try: + test_for_compiler = conf.options.check_fortran_compiler or default_compilers() + except AttributeError: + conf.fatal("Add options(opt): opt.load('compiler_fc')") + for compiler in re.split('[ ,]+', test_for_compiler): + conf.env.stash() + conf.start_msg('Checking for %r (Fortran compiler)' % compiler) + try: + conf.load(compiler) + except conf.errors.ConfigurationError as e: + conf.env.revert() + conf.end_msg(False) + Logs.debug('compiler_fortran: %r', e) + else: + if conf.env.FC: + conf.end_msg(conf.env.get_flat('FC')) + conf.env.COMPILER_FORTRAN = compiler + conf.env.commit() + break + conf.env.revert() + conf.end_msg(False) + else: + conf.fatal('could not configure a Fortran compiler!') + +def options(opt): + """ + This is how to provide compiler preferences on the command-line:: + + $ waf configure --check-fortran-compiler=ifort + """ + test_for_compiler = default_compilers() + opt.load_special_tools('fc_*.py') + fortran_compiler_opts = opt.add_option_group('Configuration options') + fortran_compiler_opts.add_option('--check-fortran-compiler', default=None, + help='list of Fortran compiler to try [%s]' % test_for_compiler, + dest="check_fortran_compiler") + + for x in test_for_compiler.split(): + opt.load('%s' % x) + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/cs.py b/ldb-2.0.8/third_party/waf/waflib/Tools/cs.py new file mode 100644 index 0000000..aecca6d --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/cs.py @@ -0,0 +1,211 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2006-2018 (ita) + +""" +C# support. A simple example:: + + def configure(conf): + conf.load('cs') + def build(bld): + bld(features='cs', source='main.cs', gen='foo') + +Note that the configuration may compile C# snippets:: + + FRAG = ''' + namespace Moo { + public class Test { public static int Main(string[] args) { return 0; } } + }''' + def configure(conf): + conf.check(features='cs', fragment=FRAG, compile_filename='test.cs', gen='test.exe', + bintype='exe', csflags=['-pkg:gtk-sharp-2.0'], msg='Checking for Gtksharp support') +""" + +from waflib import Utils, Task, Options, Errors +from waflib.TaskGen import before_method, after_method, feature +from waflib.Tools import ccroot +from waflib.Configure import conf + +ccroot.USELIB_VARS['cs'] = set(['CSFLAGS', 'ASSEMBLIES', 'RESOURCES']) +ccroot.lib_patterns['csshlib'] = ['%s'] + +@feature('cs') +@before_method('process_source') +def apply_cs(self): + """ + Create a C# task bound to the attribute *cs_task*. There can be only one C# task by task generator. + """ + cs_nodes = [] + no_nodes = [] + for x in self.to_nodes(self.source): + if x.name.endswith('.cs'): + cs_nodes.append(x) + else: + no_nodes.append(x) + self.source = no_nodes + + bintype = getattr(self, 'bintype', self.gen.endswith('.dll') and 'library' or 'exe') + self.cs_task = tsk = self.create_task('mcs', cs_nodes, self.path.find_or_declare(self.gen)) + tsk.env.CSTYPE = '/target:%s' % bintype + tsk.env.OUT = '/out:%s' % tsk.outputs[0].abspath() + self.env.append_value('CSFLAGS', '/platform:%s' % getattr(self, 'platform', 'anycpu')) + + inst_to = getattr(self, 'install_path', bintype=='exe' and '${BINDIR}' or '${LIBDIR}') + if inst_to: + # note: we are making a copy, so the files added to cs_task.outputs won't be installed automatically + mod = getattr(self, 'chmod', bintype=='exe' and Utils.O755 or Utils.O644) + self.install_task = self.add_install_files(install_to=inst_to, install_from=self.cs_task.outputs[:], chmod=mod) + +@feature('cs') +@after_method('apply_cs') +def use_cs(self): + """ + C# applications honor the **use** keyword:: + + def build(bld): + bld(features='cs', source='My.cs', bintype='library', gen='my.dll', name='mylib') + bld(features='cs', source='Hi.cs', includes='.', bintype='exe', gen='hi.exe', use='mylib', name='hi') + """ + names = self.to_list(getattr(self, 'use', [])) + get = self.bld.get_tgen_by_name + for x in names: + try: + y = get(x) + except Errors.WafError: + self.env.append_value('CSFLAGS', '/reference:%s' % x) + continue + y.post() + + tsk = getattr(y, 'cs_task', None) or getattr(y, 'link_task', None) + if not tsk: + self.bld.fatal('cs task has no link task for use %r' % self) + self.cs_task.dep_nodes.extend(tsk.outputs) # dependency + self.cs_task.set_run_after(tsk) # order (redundant, the order is inferred from the nodes inputs/outputs) + self.env.append_value('CSFLAGS', '/reference:%s' % tsk.outputs[0].abspath()) + +@feature('cs') +@after_method('apply_cs', 'use_cs') +def debug_cs(self): + """ + The C# targets may create .mdb or .pdb files:: + + def build(bld): + bld(features='cs', source='My.cs', bintype='library', gen='my.dll', csdebug='full') + # csdebug is a value in (True, 'full', 'pdbonly') + """ + csdebug = getattr(self, 'csdebug', self.env.CSDEBUG) + if not csdebug: + return + + node = self.cs_task.outputs[0] + if self.env.CS_NAME == 'mono': + out = node.parent.find_or_declare(node.name + '.mdb') + else: + out = node.change_ext('.pdb') + self.cs_task.outputs.append(out) + + if getattr(self, 'install_task', None): + self.pdb_install_task = self.add_install_files( + install_to=self.install_task.install_to, install_from=out) + + if csdebug == 'pdbonly': + val = ['/debug+', '/debug:pdbonly'] + elif csdebug == 'full': + val = ['/debug+', '/debug:full'] + else: + val = ['/debug-'] + self.env.append_value('CSFLAGS', val) + +@feature('cs') +@after_method('debug_cs') +def doc_cs(self): + """ + The C# targets may create .xml documentation files:: + + def build(bld): + bld(features='cs', source='My.cs', bintype='library', gen='my.dll', csdoc=True) + # csdoc is a boolean value + """ + csdoc = getattr(self, 'csdoc', self.env.CSDOC) + if not csdoc: + return + + node = self.cs_task.outputs[0] + out = node.change_ext('.xml') + self.cs_task.outputs.append(out) + + if getattr(self, 'install_task', None): + self.doc_install_task = self.add_install_files( + install_to=self.install_task.install_to, install_from=out) + + self.env.append_value('CSFLAGS', '/doc:%s' % out.abspath()) + +class mcs(Task.Task): + """ + Compile C# files + """ + color = 'YELLOW' + run_str = '${MCS} ${CSTYPE} ${CSFLAGS} ${ASS_ST:ASSEMBLIES} ${RES_ST:RESOURCES} ${OUT} ${SRC}' + + def split_argfile(self, cmd): + inline = [cmd[0]] + infile = [] + for x in cmd[1:]: + # csc doesn't want /noconfig in @file + if x.lower() == '/noconfig': + inline.append(x) + else: + infile.append(self.quote_flag(x)) + return (inline, infile) + +def configure(conf): + """ + Find a C# compiler, set the variable MCS for the compiler and CS_NAME (mono or csc) + """ + csc = getattr(Options.options, 'cscbinary', None) + if csc: + conf.env.MCS = csc + conf.find_program(['csc', 'mcs', 'gmcs'], var='MCS') + conf.env.ASS_ST = '/r:%s' + conf.env.RES_ST = '/resource:%s' + + conf.env.CS_NAME = 'csc' + if str(conf.env.MCS).lower().find('mcs') > -1: + conf.env.CS_NAME = 'mono' + +def options(opt): + """ + Add a command-line option for the configuration:: + + $ waf configure --with-csc-binary=/foo/bar/mcs + """ + opt.add_option('--with-csc-binary', type='string', dest='cscbinary') + +class fake_csshlib(Task.Task): + """ + Task used for reading a foreign .net assembly and adding the dependency on it + """ + color = 'YELLOW' + inst_to = None + + def runnable_status(self): + return Task.SKIP_ME + +@conf +def read_csshlib(self, name, paths=[]): + """ + Read a foreign .net assembly for the *use* system:: + + def build(bld): + bld.read_csshlib('ManagedLibrary.dll', paths=[bld.env.mylibrarypath]) + bld(features='cs', source='Hi.cs', bintype='exe', gen='hi.exe', use='ManagedLibrary.dll') + + :param name: Name of the library + :type name: string + :param paths: Folders in which the library may be found + :type paths: list of string + :return: A task generator having the feature *fake_lib* which will call :py:func:`waflib.Tools.ccroot.process_lib` + :rtype: :py:class:`waflib.TaskGen.task_gen` + """ + return self(name=name, features='fake_lib', lib_paths=paths, lib_type='csshlib') + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/cxx.py b/ldb-2.0.8/third_party/waf/waflib/Tools/cxx.py new file mode 100644 index 0000000..194fad7 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/cxx.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2005-2018 (ita) + +"Base for c++ programs and libraries" + +from waflib import TaskGen, Task +from waflib.Tools import c_preproc +from waflib.Tools.ccroot import link_task, stlink_task + +@TaskGen.extension('.cpp','.cc','.cxx','.C','.c++') +def cxx_hook(self, node): + "Binds c++ file extensions to create :py:class:`waflib.Tools.cxx.cxx` instances" + return self.create_compiled_task('cxx', node) + +if not '.c' in TaskGen.task_gen.mappings: + TaskGen.task_gen.mappings['.c'] = TaskGen.task_gen.mappings['.cpp'] + +class cxx(Task.Task): + "Compiles C++ files into object files" + run_str = '${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT[0].abspath()} ${CPPFLAGS}' + vars = ['CXXDEPS'] # unused variable to depend on, just in case + ext_in = ['.h'] # set the build order easily by using ext_out=['.h'] + scan = c_preproc.scan + +class cxxprogram(link_task): + "Links object files into c++ programs" + run_str = '${LINK_CXX} ${LINKFLAGS} ${CXXLNK_SRC_F}${SRC} ${CXXLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LDFLAGS}' + vars = ['LINKDEPS'] + ext_out = ['.bin'] + inst_to = '${BINDIR}' + +class cxxshlib(cxxprogram): + "Links object files into c++ shared libraries" + inst_to = '${LIBDIR}' + +class cxxstlib(stlink_task): + "Links object files into c++ static libraries" + pass # do not remove + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/d.py b/ldb-2.0.8/third_party/waf/waflib/Tools/d.py new file mode 100644 index 0000000..e4cf73b --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/d.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Carlos Rafael Giani, 2007 (dv) +# Thomas Nagy, 2007-2018 (ita) + +from waflib import Utils, Task, Errors +from waflib.TaskGen import taskgen_method, feature, extension +from waflib.Tools import d_scan, d_config +from waflib.Tools.ccroot import link_task, stlink_task + +class d(Task.Task): + "Compile a d file into an object file" + color = 'GREEN' + run_str = '${D} ${DFLAGS} ${DINC_ST:INCPATHS} ${D_SRC_F:SRC} ${D_TGT_F:TGT}' + scan = d_scan.scan + +class d_with_header(d): + "Compile a d file and generate a header" + run_str = '${D} ${DFLAGS} ${DINC_ST:INCPATHS} ${D_HDR_F:tgt.outputs[1].bldpath()} ${D_SRC_F:SRC} ${D_TGT_F:tgt.outputs[0].bldpath()}' + +class d_header(Task.Task): + "Compile d headers" + color = 'BLUE' + run_str = '${D} ${D_HEADER} ${SRC}' + +class dprogram(link_task): + "Link object files into a d program" + run_str = '${D_LINKER} ${LINKFLAGS} ${DLNK_SRC_F}${SRC} ${DLNK_TGT_F:TGT} ${RPATH_ST:RPATH} ${DSTLIB_MARKER} ${DSTLIBPATH_ST:STLIBPATH} ${DSTLIB_ST:STLIB} ${DSHLIB_MARKER} ${DLIBPATH_ST:LIBPATH} ${DSHLIB_ST:LIB}' + inst_to = '${BINDIR}' + +class dshlib(dprogram): + "Link object files into a d shared library" + inst_to = '${LIBDIR}' + +class dstlib(stlink_task): + "Link object files into a d static library" + pass # do not remove + +@extension('.d', '.di', '.D') +def d_hook(self, node): + """ + Compile *D* files. To get .di files as well as .o files, set the following:: + + def build(bld): + bld.program(source='foo.d', target='app', generate_headers=True) + + """ + ext = Utils.destos_to_binfmt(self.env.DEST_OS) == 'pe' and 'obj' or 'o' + out = '%s.%d.%s' % (node.name, self.idx, ext) + def create_compiled_task(self, name, node): + task = self.create_task(name, node, node.parent.find_or_declare(out)) + try: + self.compiled_tasks.append(task) + except AttributeError: + self.compiled_tasks = [task] + return task + + if getattr(self, 'generate_headers', None): + tsk = create_compiled_task(self, 'd_with_header', node) + tsk.outputs.append(node.change_ext(self.env.DHEADER_ext)) + else: + tsk = create_compiled_task(self, 'd', node) + return tsk + +@taskgen_method +def generate_header(self, filename): + """ + See feature request #104:: + + def build(bld): + tg = bld.program(source='foo.d', target='app') + tg.generate_header('blah.d') + # is equivalent to: + #tg = bld.program(source='foo.d', target='app', header_lst='blah.d') + + :param filename: header to create + :type filename: string + """ + try: + self.header_lst.append([filename, self.install_path]) + except AttributeError: + self.header_lst = [[filename, self.install_path]] + +@feature('d') +def process_header(self): + """ + Process the attribute 'header_lst' to create the d header compilation tasks:: + + def build(bld): + bld.program(source='foo.d', target='app', header_lst='blah.d') + """ + for i in getattr(self, 'header_lst', []): + node = self.path.find_resource(i[0]) + if not node: + raise Errors.WafError('file %r not found on d obj' % i[0]) + self.create_task('d_header', node, node.change_ext('.di')) + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/d_config.py b/ldb-2.0.8/third_party/waf/waflib/Tools/d_config.py new file mode 100644 index 0000000..6637556 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/d_config.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2016-2018 (ita) + +from waflib import Utils +from waflib.Configure import conf + +@conf +def d_platform_flags(self): + """ + Sets the extensions dll/so for d programs and libraries + """ + v = self.env + if not v.DEST_OS: + v.DEST_OS = Utils.unversioned_sys_platform() + binfmt = Utils.destos_to_binfmt(self.env.DEST_OS) + if binfmt == 'pe': + v.dprogram_PATTERN = '%s.exe' + v.dshlib_PATTERN = 'lib%s.dll' + v.dstlib_PATTERN = 'lib%s.a' + elif binfmt == 'mac-o': + v.dprogram_PATTERN = '%s' + v.dshlib_PATTERN = 'lib%s.dylib' + v.dstlib_PATTERN = 'lib%s.a' + else: + v.dprogram_PATTERN = '%s' + v.dshlib_PATTERN = 'lib%s.so' + v.dstlib_PATTERN = 'lib%s.a' + +DLIB = ''' +version(D_Version2) { + import std.stdio; + int main() { + writefln("phobos2"); + return 0; + } +} else { + version(Tango) { + import tango.stdc.stdio; + int main() { + printf("tango"); + return 0; + } + } else { + import std.stdio; + int main() { + writefln("phobos1"); + return 0; + } + } +} +''' +"""Detection string for the D standard library""" + +@conf +def check_dlibrary(self, execute=True): + """ + Detects the kind of standard library that comes with the compiler, + and sets conf.env.DLIBRARY to tango, phobos1 or phobos2 + """ + ret = self.check_cc(features='d dprogram', fragment=DLIB, compile_filename='test.d', execute=execute, define_ret=True) + if execute: + self.env.DLIBRARY = ret.strip() + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/d_scan.py b/ldb-2.0.8/third_party/waf/waflib/Tools/d_scan.py new file mode 100644 index 0000000..4e807a6 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/d_scan.py @@ -0,0 +1,211 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2016-2018 (ita) + +""" +Provide a scanner for finding dependencies on d files +""" + +import re +from waflib import Utils + +def filter_comments(filename): + """ + :param filename: d file name + :type filename: string + :rtype: list + :return: a list of characters + """ + txt = Utils.readf(filename) + i = 0 + buf = [] + max = len(txt) + begin = 0 + while i < max: + c = txt[i] + if c == '"' or c == "'": # skip a string or character literal + buf.append(txt[begin:i]) + delim = c + i += 1 + while i < max: + c = txt[i] + if c == delim: + break + elif c == '\\': # skip the character following backslash + i += 1 + i += 1 + i += 1 + begin = i + elif c == '/': # try to replace a comment with whitespace + buf.append(txt[begin:i]) + i += 1 + if i == max: + break + c = txt[i] + if c == '+': # eat nesting /+ +/ comment + i += 1 + nesting = 1 + c = None + while i < max: + prev = c + c = txt[i] + if prev == '/' and c == '+': + nesting += 1 + c = None + elif prev == '+' and c == '/': + nesting -= 1 + if nesting == 0: + break + c = None + i += 1 + elif c == '*': # eat /* */ comment + i += 1 + c = None + while i < max: + prev = c + c = txt[i] + if prev == '*' and c == '/': + break + i += 1 + elif c == '/': # eat // comment + i += 1 + while i < max and txt[i] != '\n': + i += 1 + else: # no comment + begin = i - 1 + continue + i += 1 + begin = i + buf.append(' ') + else: + i += 1 + buf.append(txt[begin:]) + return buf + +class d_parser(object): + """ + Parser for d files + """ + def __init__(self, env, incpaths): + #self.code = '' + #self.module = '' + #self.imports = [] + + self.allnames = [] + + self.re_module = re.compile(r"module\s+([^;]+)") + self.re_import = re.compile(r"import\s+([^;]+)") + self.re_import_bindings = re.compile("([^:]+):(.*)") + self.re_import_alias = re.compile("[^=]+=(.+)") + + self.env = env + + self.nodes = [] + self.names = [] + + self.incpaths = incpaths + + def tryfind(self, filename): + """ + Search file a file matching an module/import directive + + :param filename: file to read + :type filename: string + """ + found = 0 + for n in self.incpaths: + found = n.find_resource(filename.replace('.', '/') + '.d') + if found: + self.nodes.append(found) + self.waiting.append(found) + break + if not found: + if not filename in self.names: + self.names.append(filename) + + def get_strings(self, code): + """ + :param code: d code to parse + :type code: string + :return: the modules that the code uses + :rtype: a list of match objects + """ + #self.imports = [] + self.module = '' + lst = [] + + # get the module name (if present) + + mod_name = self.re_module.search(code) + if mod_name: + self.module = re.sub(r'\s+', '', mod_name.group(1)) # strip all whitespaces + + # go through the code, have a look at all import occurrences + + # first, lets look at anything beginning with "import" and ending with ";" + import_iterator = self.re_import.finditer(code) + if import_iterator: + for import_match in import_iterator: + import_match_str = re.sub(r'\s+', '', import_match.group(1)) # strip all whitespaces + + # does this end with an import bindings declaration? + # (import bindings always terminate the list of imports) + bindings_match = self.re_import_bindings.match(import_match_str) + if bindings_match: + import_match_str = bindings_match.group(1) + # if so, extract the part before the ":" (since the module declaration(s) is/are located there) + + # split the matching string into a bunch of strings, separated by a comma + matches = import_match_str.split(',') + + for match in matches: + alias_match = self.re_import_alias.match(match) + if alias_match: + # is this an alias declaration? (alias = module name) if so, extract the module name + match = alias_match.group(1) + + lst.append(match) + return lst + + def start(self, node): + """ + The parsing starts here + + :param node: input file + :type node: :py:class:`waflib.Node.Node` + """ + self.waiting = [node] + # while the stack is not empty, add the dependencies + while self.waiting: + nd = self.waiting.pop(0) + self.iter(nd) + + def iter(self, node): + """ + Find all the modules that a file depends on, uses :py:meth:`waflib.Tools.d_scan.d_parser.tryfind` to process dependent files + + :param node: input file + :type node: :py:class:`waflib.Node.Node` + """ + path = node.abspath() # obtain the absolute path + code = "".join(filter_comments(path)) # read the file and filter the comments + names = self.get_strings(code) # obtain the import strings + for x in names: + # optimization + if x in self.allnames: + continue + self.allnames.append(x) + + # for each name, see if it is like a node or not + self.tryfind(x) + +def scan(self): + "look for .d/.di used by a d file" + env = self.env + gruik = d_parser(env, self.generator.includes_nodes) + node = self.inputs[0] + gruik.start(node) + nodes = gruik.nodes + names = gruik.names + return (nodes, names) + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/dbus.py b/ldb-2.0.8/third_party/waf/waflib/Tools/dbus.py new file mode 100644 index 0000000..d520f1c --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/dbus.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Ali Sabil, 2007 + +""" +Compiles dbus files with **dbus-binding-tool** + +Typical usage:: + + def options(opt): + opt.load('compiler_c dbus') + def configure(conf): + conf.load('compiler_c dbus') + def build(bld): + tg = bld.program( + includes = '.', + source = bld.path.ant_glob('*.c'), + target = 'gnome-hello') + tg.add_dbus_file('test.xml', 'test_prefix', 'glib-server') +""" + +from waflib import Task, Errors +from waflib.TaskGen import taskgen_method, before_method + +@taskgen_method +def add_dbus_file(self, filename, prefix, mode): + """ + Adds a dbus file to the list of dbus files to process. Store them in the attribute *dbus_lst*. + + :param filename: xml file to compile + :type filename: string + :param prefix: dbus binding tool prefix (--prefix=prefix) + :type prefix: string + :param mode: dbus binding tool mode (--mode=mode) + :type mode: string + """ + if not hasattr(self, 'dbus_lst'): + self.dbus_lst = [] + if not 'process_dbus' in self.meths: + self.meths.append('process_dbus') + self.dbus_lst.append([filename, prefix, mode]) + +@before_method('process_source') +def process_dbus(self): + """ + Processes the dbus files stored in the attribute *dbus_lst* to create :py:class:`waflib.Tools.dbus.dbus_binding_tool` instances. + """ + for filename, prefix, mode in getattr(self, 'dbus_lst', []): + node = self.path.find_resource(filename) + if not node: + raise Errors.WafError('file not found ' + filename) + tsk = self.create_task('dbus_binding_tool', node, node.change_ext('.h')) + tsk.env.DBUS_BINDING_TOOL_PREFIX = prefix + tsk.env.DBUS_BINDING_TOOL_MODE = mode + +class dbus_binding_tool(Task.Task): + """ + Compiles a dbus file + """ + color = 'BLUE' + ext_out = ['.h'] + run_str = '${DBUS_BINDING_TOOL} --prefix=${DBUS_BINDING_TOOL_PREFIX} --mode=${DBUS_BINDING_TOOL_MODE} --output=${TGT} ${SRC}' + shell = True # temporary workaround for #795 + +def configure(conf): + """ + Detects the program dbus-binding-tool and sets ``conf.env.DBUS_BINDING_TOOL`` + """ + conf.find_program('dbus-binding-tool', var='DBUS_BINDING_TOOL') + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/dmd.py b/ldb-2.0.8/third_party/waf/waflib/Tools/dmd.py new file mode 100644 index 0000000..8917ca1 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/dmd.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Carlos Rafael Giani, 2007 (dv) +# Thomas Nagy, 2008-2018 (ita) + +import sys +from waflib.Tools import ar, d +from waflib.Configure import conf + +@conf +def find_dmd(conf): + """ + Finds the program *dmd*, *dmd2*, or *ldc* and set the variable *D* + """ + conf.find_program(['dmd', 'dmd2', 'ldc'], var='D') + + # make sure that we're dealing with dmd1, dmd2, or ldc(1) + out = conf.cmd_and_log(conf.env.D + ['--help']) + if out.find("D Compiler v") == -1: + out = conf.cmd_and_log(conf.env.D + ['-version']) + if out.find("based on DMD v1.") == -1: + conf.fatal("detected compiler is not dmd/ldc") + +@conf +def common_flags_ldc(conf): + """ + Sets the D flags required by *ldc* + """ + v = conf.env + v.DFLAGS = ['-d-version=Posix'] + v.LINKFLAGS = [] + v.DFLAGS_dshlib = ['-relocation-model=pic'] + +@conf +def common_flags_dmd(conf): + """ + Set the flags required by *dmd* or *dmd2* + """ + v = conf.env + + v.D_SRC_F = ['-c'] + v.D_TGT_F = '-of%s' + + v.D_LINKER = v.D + v.DLNK_SRC_F = '' + v.DLNK_TGT_F = '-of%s' + v.DINC_ST = '-I%s' + + v.DSHLIB_MARKER = v.DSTLIB_MARKER = '' + v.DSTLIB_ST = v.DSHLIB_ST = '-L-l%s' + v.DSTLIBPATH_ST = v.DLIBPATH_ST = '-L-L%s' + + v.LINKFLAGS_dprogram= ['-quiet'] + + v.DFLAGS_dshlib = ['-fPIC'] + v.LINKFLAGS_dshlib = ['-L-shared'] + + v.DHEADER_ext = '.di' + v.DFLAGS_d_with_header = ['-H', '-Hf'] + v.D_HDR_F = '%s' + +def configure(conf): + """ + Configuration for *dmd*, *dmd2*, and *ldc* + """ + conf.find_dmd() + + if sys.platform == 'win32': + out = conf.cmd_and_log(conf.env.D + ['--help']) + if out.find('D Compiler v2.') > -1: + conf.fatal('dmd2 on Windows is not supported, use gdc or ldc2 instead') + + conf.load('ar') + conf.load('d') + conf.common_flags_dmd() + conf.d_platform_flags() + + if str(conf.env.D).find('ldc') > -1: + conf.common_flags_ldc() + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/errcheck.py b/ldb-2.0.8/third_party/waf/waflib/Tools/errcheck.py new file mode 100644 index 0000000..de8d75a --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/errcheck.py @@ -0,0 +1,237 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2011 (ita) + +""" +Common mistakes highlighting. + +There is a performance impact, so this tool is only loaded when running ``waf -v`` +""" + +typos = { +'feature':'features', +'sources':'source', +'targets':'target', +'include':'includes', +'export_include':'export_includes', +'define':'defines', +'importpath':'includes', +'installpath':'install_path', +'iscopy':'is_copy', +'uses':'use', +} + +meths_typos = ['__call__', 'program', 'shlib', 'stlib', 'objects'] + +import sys +from waflib import Logs, Build, Node, Task, TaskGen, ConfigSet, Errors, Utils +from waflib.Tools import ccroot + +def check_same_targets(self): + mp = Utils.defaultdict(list) + uids = {} + + def check_task(tsk): + if not isinstance(tsk, Task.Task): + return + if hasattr(tsk, 'no_errcheck_out'): + return + + for node in tsk.outputs: + mp[node].append(tsk) + try: + uids[tsk.uid()].append(tsk) + except KeyError: + uids[tsk.uid()] = [tsk] + + for g in self.groups: + for tg in g: + try: + for tsk in tg.tasks: + check_task(tsk) + except AttributeError: + # raised if not a task generator, which should be uncommon + check_task(tg) + + dupe = False + for (k, v) in mp.items(): + if len(v) > 1: + dupe = True + msg = '* Node %r is created more than once%s. The task generators are:' % (k, Logs.verbose == 1 and " (full message on 'waf -v -v')" or "") + Logs.error(msg) + for x in v: + if Logs.verbose > 1: + Logs.error(' %d. %r', 1 + v.index(x), x.generator) + else: + Logs.error(' %d. %r in %r', 1 + v.index(x), x.generator.name, getattr(x.generator, 'path', None)) + Logs.error('If you think that this is an error, set no_errcheck_out on the task instance') + + if not dupe: + for (k, v) in uids.items(): + if len(v) > 1: + Logs.error('* Several tasks use the same identifier. Please check the information on\n https://waf.io/apidocs/Task.html?highlight=uid#waflib.Task.Task.uid') + tg_details = tsk.generator.name + if Logs.verbose > 2: + tg_details = tsk.generator + for tsk in v: + Logs.error(' - object %r (%r) defined in %r', tsk.__class__.__name__, tsk, tg_details) + +def check_invalid_constraints(self): + feat = set() + for x in list(TaskGen.feats.values()): + feat.union(set(x)) + for (x, y) in TaskGen.task_gen.prec.items(): + feat.add(x) + feat.union(set(y)) + ext = set() + for x in TaskGen.task_gen.mappings.values(): + ext.add(x.__name__) + invalid = ext & feat + if invalid: + Logs.error('The methods %r have invalid annotations: @extension <-> @feature/@before_method/@after_method', list(invalid)) + + # the build scripts have been read, so we can check for invalid after/before attributes on task classes + for cls in list(Task.classes.values()): + if sys.hexversion > 0x3000000 and issubclass(cls, Task.Task) and isinstance(cls.hcode, str): + raise Errors.WafError('Class %r has hcode value %r of type , expecting (use Utils.h_cmd() ?)' % (cls, cls.hcode)) + + for x in ('before', 'after'): + for y in Utils.to_list(getattr(cls, x, [])): + if not Task.classes.get(y): + Logs.error('Erroneous order constraint %r=%r on task class %r', x, y, cls.__name__) + if getattr(cls, 'rule', None): + Logs.error('Erroneous attribute "rule" on task class %r (rename to "run_str")', cls.__name__) + +def replace(m): + """ + Replaces existing BuildContext methods to verify parameter names, + for example ``bld(source=)`` has no ending *s* + """ + oldcall = getattr(Build.BuildContext, m) + def call(self, *k, **kw): + ret = oldcall(self, *k, **kw) + for x in typos: + if x in kw: + if x == 'iscopy' and 'subst' in getattr(self, 'features', ''): + continue + Logs.error('Fix the typo %r -> %r on %r', x, typos[x], ret) + return ret + setattr(Build.BuildContext, m, call) + +def enhance_lib(): + """ + Modifies existing classes and methods to enable error verification + """ + for m in meths_typos: + replace(m) + + # catch '..' in ant_glob patterns + def ant_glob(self, *k, **kw): + if k: + lst = Utils.to_list(k[0]) + for pat in lst: + sp = pat.split('/') + if '..' in sp: + Logs.error("In ant_glob pattern %r: '..' means 'two dots', not 'parent directory'", k[0]) + if '.' in sp: + Logs.error("In ant_glob pattern %r: '.' means 'one dot', not 'current directory'", k[0]) + return self.old_ant_glob(*k, **kw) + Node.Node.old_ant_glob = Node.Node.ant_glob + Node.Node.ant_glob = ant_glob + + # catch ant_glob on build folders + def ant_iter(self, accept=None, maxdepth=25, pats=[], dir=False, src=True, remove=True, quiet=False): + if remove: + try: + if self.is_child_of(self.ctx.bldnode) and not quiet: + quiet = True + Logs.error('Calling ant_glob on build folders (%r) is dangerous: add quiet=True / remove=False', self) + except AttributeError: + pass + return self.old_ant_iter(accept, maxdepth, pats, dir, src, remove, quiet) + Node.Node.old_ant_iter = Node.Node.ant_iter + Node.Node.ant_iter = ant_iter + + # catch conflicting ext_in/ext_out/before/after declarations + old = Task.is_before + def is_before(t1, t2): + ret = old(t1, t2) + if ret and old(t2, t1): + Logs.error('Contradictory order constraints in classes %r %r', t1, t2) + return ret + Task.is_before = is_before + + # check for bld(feature='cshlib') where no 'c' is given - this can be either a mistake or on purpose + # so we only issue a warning + def check_err_features(self): + lst = self.to_list(self.features) + if 'shlib' in lst: + Logs.error('feature shlib -> cshlib, dshlib or cxxshlib') + for x in ('c', 'cxx', 'd', 'fc'): + if not x in lst and lst and lst[0] in [x+y for y in ('program', 'shlib', 'stlib')]: + Logs.error('%r features is probably missing %r', self, x) + TaskGen.feature('*')(check_err_features) + + # check for erroneous order constraints + def check_err_order(self): + if not hasattr(self, 'rule') and not 'subst' in Utils.to_list(self.features): + for x in ('before', 'after', 'ext_in', 'ext_out'): + if hasattr(self, x): + Logs.warn('Erroneous order constraint %r on non-rule based task generator %r', x, self) + else: + for x in ('before', 'after'): + for y in self.to_list(getattr(self, x, [])): + if not Task.classes.get(y): + Logs.error('Erroneous order constraint %s=%r on %r (no such class)', x, y, self) + TaskGen.feature('*')(check_err_order) + + # check for @extension used with @feature/@before_method/@after_method + def check_compile(self): + check_invalid_constraints(self) + try: + ret = self.orig_compile() + finally: + check_same_targets(self) + return ret + Build.BuildContext.orig_compile = Build.BuildContext.compile + Build.BuildContext.compile = check_compile + + # check for invalid build groups #914 + def use_rec(self, name, **kw): + try: + y = self.bld.get_tgen_by_name(name) + except Errors.WafError: + pass + else: + idx = self.bld.get_group_idx(self) + odx = self.bld.get_group_idx(y) + if odx > idx: + msg = "Invalid 'use' across build groups:" + if Logs.verbose > 1: + msg += '\n target %r\n uses:\n %r' % (self, y) + else: + msg += " %r uses %r (try 'waf -v -v' for the full error)" % (self.name, name) + raise Errors.WafError(msg) + self.orig_use_rec(name, **kw) + TaskGen.task_gen.orig_use_rec = TaskGen.task_gen.use_rec + TaskGen.task_gen.use_rec = use_rec + + # check for env.append + def _getattr(self, name, default=None): + if name == 'append' or name == 'add': + raise Errors.WafError('env.append and env.add do not exist: use env.append_value/env.append_unique') + elif name == 'prepend': + raise Errors.WafError('env.prepend does not exist: use env.prepend_value') + if name in self.__slots__: + return super(ConfigSet.ConfigSet, self).__getattr__(name, default) + else: + return self[name] + ConfigSet.ConfigSet.__getattr__ = _getattr + + +def options(opt): + """ + Error verification can be enabled by default (not just on ``waf -v``) by adding to the user script options + """ + enhance_lib() + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/fc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/fc.py new file mode 100644 index 0000000..fd4d39c --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/fc.py @@ -0,0 +1,203 @@ +#! /usr/bin/env python +# encoding: utf-8 +# DC 2008 +# Thomas Nagy 2016-2018 (ita) + +""" +Fortran support +""" + +from waflib import Utils, Task, Errors +from waflib.Tools import ccroot, fc_config, fc_scan +from waflib.TaskGen import extension +from waflib.Configure import conf + +ccroot.USELIB_VARS['fc'] = set(['FCFLAGS', 'DEFINES', 'INCLUDES', 'FCPPFLAGS']) +ccroot.USELIB_VARS['fcprogram_test'] = ccroot.USELIB_VARS['fcprogram'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS']) +ccroot.USELIB_VARS['fcshlib'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS']) +ccroot.USELIB_VARS['fcstlib'] = set(['ARFLAGS', 'LINKDEPS']) + +@extension('.f','.F','.f90','.F90','.for','.FOR','.f95','.F95','.f03','.F03','.f08','.F08') +def fc_hook(self, node): + "Binds the Fortran file extensions create :py:class:`waflib.Tools.fc.fc` instances" + return self.create_compiled_task('fc', node) + +@conf +def modfile(conf, name): + """ + Turns a module name into the right module file name. + Defaults to all lower case. + """ + if name.find(':') >= 0: + # Depending on a submodule! + separator = conf.env.FC_SUBMOD_SEPARATOR or '@' + # Ancestors of the submodule will be prefixed to the + # submodule name, separated by a colon. + modpath = name.split(':') + # Only the ancestor (actual) module and the submodule name + # will be used for the filename. + modname = modpath[0] + separator + modpath[-1] + suffix = conf.env.FC_SUBMOD_SUFFIX or '.smod' + else: + modname = name + suffix = '.mod' + + return {'lower' :modname.lower() + suffix.lower(), + 'lower.MOD' :modname.lower() + suffix.upper(), + 'UPPER.mod' :modname.upper() + suffix.lower(), + 'UPPER' :modname.upper() + suffix.upper()}[conf.env.FC_MOD_CAPITALIZATION or 'lower'] + +def get_fortran_tasks(tsk): + """ + Obtains all fortran tasks from the same build group. Those tasks must not have + the attribute 'nomod' or 'mod_fortran_done' + + :return: a list of :py:class:`waflib.Tools.fc.fc` instances + """ + bld = tsk.generator.bld + tasks = bld.get_tasks_group(bld.get_group_idx(tsk.generator)) + return [x for x in tasks if isinstance(x, fc) and not getattr(x, 'nomod', None) and not getattr(x, 'mod_fortran_done', None)] + +class fc(Task.Task): + """ + Fortran tasks can only run when all fortran tasks in a current task group are ready to be executed + This may cause a deadlock if some fortran task is waiting for something that cannot happen (circular dependency) + Should this ever happen, set the 'nomod=True' on those tasks instances to break the loop + """ + color = 'GREEN' + run_str = '${FC} ${FCFLAGS} ${FCINCPATH_ST:INCPATHS} ${FCDEFINES_ST:DEFINES} ${_FCMODOUTFLAGS} ${FC_TGT_F}${TGT[0].abspath()} ${FC_SRC_F}${SRC[0].abspath()} ${FCPPFLAGS}' + vars = ["FORTRANMODPATHFLAG"] + + def scan(self): + """Fortran dependency scanner""" + tmp = fc_scan.fortran_parser(self.generator.includes_nodes) + tmp.task = self + tmp.start(self.inputs[0]) + return (tmp.nodes, tmp.names) + + def runnable_status(self): + """ + Sets the mod file outputs and the dependencies on the mod files over all Fortran tasks + executed by the main thread so there are no concurrency issues + """ + if getattr(self, 'mod_fortran_done', None): + return super(fc, self).runnable_status() + + # now, if we reach this part it is because this fortran task is the first in the list + bld = self.generator.bld + + # obtain the fortran tasks + lst = get_fortran_tasks(self) + + # disable this method for other tasks + for tsk in lst: + tsk.mod_fortran_done = True + + # wait for all the .f tasks to be ready for execution + # and ensure that the scanners are called at least once + for tsk in lst: + ret = tsk.runnable_status() + if ret == Task.ASK_LATER: + # we have to wait for one of the other fortran tasks to be ready + # this may deadlock if there are dependencies between fortran tasks + # but this should not happen (we are setting them here!) + for x in lst: + x.mod_fortran_done = None + + return Task.ASK_LATER + + ins = Utils.defaultdict(set) + outs = Utils.defaultdict(set) + + # the .mod files to create + for tsk in lst: + key = tsk.uid() + for x in bld.raw_deps[key]: + if x.startswith('MOD@'): + name = bld.modfile(x.replace('MOD@', '')) + node = bld.srcnode.find_or_declare(name) + tsk.set_outputs(node) + outs[node].add(tsk) + + # the .mod files to use + for tsk in lst: + key = tsk.uid() + for x in bld.raw_deps[key]: + if x.startswith('USE@'): + name = bld.modfile(x.replace('USE@', '')) + node = bld.srcnode.find_resource(name) + if node and node not in tsk.outputs: + if not node in bld.node_deps[key]: + bld.node_deps[key].append(node) + ins[node].add(tsk) + + # if the intersection matches, set the order + for k in ins.keys(): + for a in ins[k]: + a.run_after.update(outs[k]) + for x in outs[k]: + self.generator.bld.producer.revdeps[x].add(a) + + # the scanner cannot output nodes, so we have to set them + # ourselves as task.dep_nodes (additional input nodes) + tmp = [] + for t in outs[k]: + tmp.extend(t.outputs) + a.dep_nodes.extend(tmp) + a.dep_nodes.sort(key=lambda x: x.abspath()) + + # the task objects have changed: clear the signature cache + for tsk in lst: + try: + delattr(tsk, 'cache_sig') + except AttributeError: + pass + + return super(fc, self).runnable_status() + +class fcprogram(ccroot.link_task): + """Links Fortran programs""" + color = 'YELLOW' + run_str = '${FC} ${LINKFLAGS} ${FCLNK_SRC_F}${SRC} ${FCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FCSTLIB_MARKER} ${FCSTLIBPATH_ST:STLIBPATH} ${FCSTLIB_ST:STLIB} ${FCSHLIB_MARKER} ${FCLIBPATH_ST:LIBPATH} ${FCLIB_ST:LIB} ${LDFLAGS}' + inst_to = '${BINDIR}' + +class fcshlib(fcprogram): + """Links Fortran libraries""" + inst_to = '${LIBDIR}' + +class fcstlib(ccroot.stlink_task): + """Links Fortran static libraries (uses ar by default)""" + pass # do not remove the pass statement + +class fcprogram_test(fcprogram): + """Custom link task to obtain compiler outputs for Fortran configuration tests""" + + def runnable_status(self): + """This task is always executed""" + ret = super(fcprogram_test, self).runnable_status() + if ret == Task.SKIP_ME: + ret = Task.RUN_ME + return ret + + def exec_command(self, cmd, **kw): + """Stores the compiler std our/err onto the build context, to bld.out + bld.err""" + bld = self.generator.bld + + kw['shell'] = isinstance(cmd, str) + kw['stdout'] = kw['stderr'] = Utils.subprocess.PIPE + kw['cwd'] = self.get_cwd() + bld.out = bld.err = '' + + bld.to_log('command: %s\n' % cmd) + + kw['output'] = 0 + try: + (bld.out, bld.err) = bld.cmd_and_log(cmd, **kw) + except Errors.WafError: + return -1 + + if bld.out: + bld.to_log('out: %s\n' % bld.out) + if bld.err: + bld.to_log('err: %s\n' % bld.err) + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/fc_config.py b/ldb-2.0.8/third_party/waf/waflib/Tools/fc_config.py new file mode 100644 index 0000000..dc5e5c9 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/fc_config.py @@ -0,0 +1,488 @@ +#! /usr/bin/env python +# encoding: utf-8 +# DC 2008 +# Thomas Nagy 2016-2018 (ita) + +""" +Fortran configuration helpers +""" + +import re, os, sys, shlex +from waflib.Configure import conf +from waflib.TaskGen import feature, before_method + +FC_FRAGMENT = ' program main\n end program main\n' +FC_FRAGMENT2 = ' PROGRAM MAIN\n END\n' # what's the actual difference between these? + +@conf +def fc_flags(conf): + """ + Defines common fortran configuration flags and file extensions + """ + v = conf.env + + v.FC_SRC_F = [] + v.FC_TGT_F = ['-c', '-o'] + v.FCINCPATH_ST = '-I%s' + v.FCDEFINES_ST = '-D%s' + + if not v.LINK_FC: + v.LINK_FC = v.FC + + v.FCLNK_SRC_F = [] + v.FCLNK_TGT_F = ['-o'] + + v.FCFLAGS_fcshlib = ['-fpic'] + v.LINKFLAGS_fcshlib = ['-shared'] + v.fcshlib_PATTERN = 'lib%s.so' + + v.fcstlib_PATTERN = 'lib%s.a' + + v.FCLIB_ST = '-l%s' + v.FCLIBPATH_ST = '-L%s' + v.FCSTLIB_ST = '-l%s' + v.FCSTLIBPATH_ST = '-L%s' + v.FCSTLIB_MARKER = '-Wl,-Bstatic' + v.FCSHLIB_MARKER = '-Wl,-Bdynamic' + + v.SONAME_ST = '-Wl,-h,%s' + +@conf +def fc_add_flags(conf): + """ + Adds FCFLAGS / LDFLAGS / LINKFLAGS from os.environ to conf.env + """ + conf.add_os_flags('FCPPFLAGS', dup=False) + conf.add_os_flags('FCFLAGS', dup=False) + conf.add_os_flags('LINKFLAGS', dup=False) + conf.add_os_flags('LDFLAGS', dup=False) + +@conf +def check_fortran(self, *k, **kw): + """ + Compiles a Fortran program to ensure that the settings are correct + """ + self.check_cc( + fragment = FC_FRAGMENT, + compile_filename = 'test.f', + features = 'fc fcprogram', + msg = 'Compiling a simple fortran app') + +@conf +def check_fc(self, *k, **kw): + """ + Same as :py:func:`waflib.Tools.c_config.check` but defaults to the *Fortran* programming language + (this overrides the C defaults in :py:func:`waflib.Tools.c_config.validate_c`) + """ + kw['compiler'] = 'fc' + if not 'compile_mode' in kw: + kw['compile_mode'] = 'fc' + if not 'type' in kw: + kw['type'] = 'fcprogram' + if not 'compile_filename' in kw: + kw['compile_filename'] = 'test.f90' + if not 'code' in kw: + kw['code'] = FC_FRAGMENT + return self.check(*k, **kw) + +# ------------------------------------------------------------------------ +# --- These are the default platform modifiers, refactored here for +# convenience. gfortran and g95 have much overlap. +# ------------------------------------------------------------------------ + +@conf +def fortran_modifier_darwin(conf): + """ + Defines Fortran flags and extensions for OSX systems + """ + v = conf.env + v.FCFLAGS_fcshlib = ['-fPIC'] + v.LINKFLAGS_fcshlib = ['-dynamiclib'] + v.fcshlib_PATTERN = 'lib%s.dylib' + v.FRAMEWORKPATH_ST = '-F%s' + v.FRAMEWORK_ST = ['-framework'] + + v.LINKFLAGS_fcstlib = [] + + v.FCSHLIB_MARKER = '' + v.FCSTLIB_MARKER = '' + v.SONAME_ST = '' + +@conf +def fortran_modifier_win32(conf): + """ + Defines Fortran flags for Windows platforms + """ + v = conf.env + v.fcprogram_PATTERN = v.fcprogram_test_PATTERN = '%s.exe' + + v.fcshlib_PATTERN = '%s.dll' + v.implib_PATTERN = '%s.dll.a' + v.IMPLIB_ST = '-Wl,--out-implib,%s' + + v.FCFLAGS_fcshlib = [] + + # Auto-import is enabled by default even without this option, + # but enabling it explicitly has the nice effect of suppressing the rather boring, debug-level messages + # that the linker emits otherwise. + v.append_value('LINKFLAGS', ['-Wl,--enable-auto-import']) + +@conf +def fortran_modifier_cygwin(conf): + """ + Defines Fortran flags for use on cygwin + """ + fortran_modifier_win32(conf) + v = conf.env + v.fcshlib_PATTERN = 'cyg%s.dll' + v.append_value('LINKFLAGS_fcshlib', ['-Wl,--enable-auto-image-base']) + v.FCFLAGS_fcshlib = [] + +# ------------------------------------------------------------------------ + +@conf +def check_fortran_dummy_main(self, *k, **kw): + """ + Determines if a main function is needed by compiling a code snippet with + the C compiler and linking it with the Fortran compiler (useful on unix-like systems) + """ + if not self.env.CC: + self.fatal('A c compiler is required for check_fortran_dummy_main') + + lst = ['MAIN__', '__MAIN', '_MAIN', 'MAIN_', 'MAIN'] + lst.extend([m.lower() for m in lst]) + lst.append('') + + self.start_msg('Detecting whether we need a dummy main') + for main in lst: + kw['fortran_main'] = main + try: + self.check_cc( + fragment = 'int %s() { return 0; }\n' % (main or 'test'), + features = 'c fcprogram', + mandatory = True + ) + if not main: + self.env.FC_MAIN = -1 + self.end_msg('no') + else: + self.env.FC_MAIN = main + self.end_msg('yes %s' % main) + break + except self.errors.ConfigurationError: + pass + else: + self.end_msg('not found') + self.fatal('could not detect whether fortran requires a dummy main, see the config.log') + +# ------------------------------------------------------------------------ + +GCC_DRIVER_LINE = re.compile('^Driving:') +POSIX_STATIC_EXT = re.compile(r'\S+\.a') +POSIX_LIB_FLAGS = re.compile(r'-l\S+') + +@conf +def is_link_verbose(self, txt): + """Returns True if 'useful' link options can be found in txt""" + assert isinstance(txt, str) + for line in txt.splitlines(): + if not GCC_DRIVER_LINE.search(line): + if POSIX_STATIC_EXT.search(line) or POSIX_LIB_FLAGS.search(line): + return True + return False + +@conf +def check_fortran_verbose_flag(self, *k, **kw): + """ + Checks what kind of verbose (-v) flag works, then sets it to env.FC_VERBOSE_FLAG + """ + self.start_msg('fortran link verbose flag') + for x in ('-v', '--verbose', '-verbose', '-V'): + try: + self.check_cc( + features = 'fc fcprogram_test', + fragment = FC_FRAGMENT2, + compile_filename = 'test.f', + linkflags = [x], + mandatory=True) + except self.errors.ConfigurationError: + pass + else: + # output is on stderr or stdout (for xlf) + if self.is_link_verbose(self.test_bld.err) or self.is_link_verbose(self.test_bld.out): + self.end_msg(x) + break + else: + self.end_msg('failure') + self.fatal('Could not obtain the fortran link verbose flag (see config.log)') + + self.env.FC_VERBOSE_FLAG = x + return x + +# ------------------------------------------------------------------------ + +# linkflags which match those are ignored +LINKFLAGS_IGNORED = [r'-lang*', r'-lcrt[a-zA-Z0-9\.]*\.o', r'-lc$', r'-lSystem', r'-libmil', r'-LIST:*', r'-LNO:*'] +if os.name == 'nt': + LINKFLAGS_IGNORED.extend([r'-lfrt*', r'-luser32', r'-lkernel32', r'-ladvapi32', r'-lmsvcrt', r'-lshell32', r'-lmingw', r'-lmoldname']) +else: + LINKFLAGS_IGNORED.append(r'-lgcc*') +RLINKFLAGS_IGNORED = [re.compile(f) for f in LINKFLAGS_IGNORED] + +def _match_ignore(line): + """Returns True if the line should be ignored (Fortran verbose flag test)""" + for i in RLINKFLAGS_IGNORED: + if i.match(line): + return True + return False + +def parse_fortran_link(lines): + """Given the output of verbose link of Fortran compiler, this returns a + list of flags necessary for linking using the standard linker.""" + final_flags = [] + for line in lines: + if not GCC_DRIVER_LINE.match(line): + _parse_flink_line(line, final_flags) + return final_flags + +SPACE_OPTS = re.compile('^-[LRuYz]$') +NOSPACE_OPTS = re.compile('^-[RL]') + +def _parse_flink_token(lexer, token, tmp_flags): + # Here we go (convention for wildcard is shell, not regex !) + # 1 TODO: we first get some root .a libraries + # 2 TODO: take everything starting by -bI:* + # 3 Ignore the following flags: -lang* | -lcrt*.o | -lc | + # -lgcc* | -lSystem | -libmil | -LANG:=* | -LIST:* | -LNO:*) + # 4 take into account -lkernel32 + # 5 For options of the kind -[[LRuYz]], as they take one argument + # after, the actual option is the next token + # 6 For -YP,*: take and replace by -Larg where arg is the old + # argument + # 7 For -[lLR]*: take + + # step 3 + if _match_ignore(token): + pass + # step 4 + elif token.startswith('-lkernel32') and sys.platform == 'cygwin': + tmp_flags.append(token) + # step 5 + elif SPACE_OPTS.match(token): + t = lexer.get_token() + if t.startswith('P,'): + t = t[2:] + for opt in t.split(os.pathsep): + tmp_flags.append('-L%s' % opt) + # step 6 + elif NOSPACE_OPTS.match(token): + tmp_flags.append(token) + # step 7 + elif POSIX_LIB_FLAGS.match(token): + tmp_flags.append(token) + else: + # ignore anything not explicitly taken into account + pass + + t = lexer.get_token() + return t + +def _parse_flink_line(line, final_flags): + """private""" + lexer = shlex.shlex(line, posix = True) + lexer.whitespace_split = True + + t = lexer.get_token() + tmp_flags = [] + while t: + t = _parse_flink_token(lexer, t, tmp_flags) + + final_flags.extend(tmp_flags) + return final_flags + +@conf +def check_fortran_clib(self, autoadd=True, *k, **kw): + """ + Obtains the flags for linking with the C library + if this check works, add uselib='CLIB' to your task generators + """ + if not self.env.FC_VERBOSE_FLAG: + self.fatal('env.FC_VERBOSE_FLAG is not set: execute check_fortran_verbose_flag?') + + self.start_msg('Getting fortran runtime link flags') + try: + self.check_cc( + fragment = FC_FRAGMENT2, + compile_filename = 'test.f', + features = 'fc fcprogram_test', + linkflags = [self.env.FC_VERBOSE_FLAG] + ) + except Exception: + self.end_msg(False) + if kw.get('mandatory', True): + conf.fatal('Could not find the c library flags') + else: + out = self.test_bld.err + flags = parse_fortran_link(out.splitlines()) + self.end_msg('ok (%s)' % ' '.join(flags)) + self.env.LINKFLAGS_CLIB = flags + return flags + return [] + +def getoutput(conf, cmd, stdin=False): + """ + Obtains Fortran command outputs + """ + from waflib import Errors + if conf.env.env: + env = conf.env.env + else: + env = dict(os.environ) + env['LANG'] = 'C' + input = stdin and '\n'.encode() or None + try: + out, err = conf.cmd_and_log(cmd, env=env, output=0, input=input) + except Errors.WafError as e: + # An WafError might indicate an error code during the command + # execution, in this case we still obtain the stderr and stdout, + # which we can use to find the version string. + if not (hasattr(e, 'stderr') and hasattr(e, 'stdout')): + raise e + else: + # Ignore the return code and return the original + # stdout and stderr. + out = e.stdout + err = e.stderr + except Exception: + conf.fatal('could not determine the compiler version %r' % cmd) + return (out, err) + +# ------------------------------------------------------------------------ + +ROUTINES_CODE = """\ + subroutine foobar() + return + end + subroutine foo_bar() + return + end +""" + +MAIN_CODE = """ +void %(dummy_func_nounder)s(void); +void %(dummy_func_under)s(void); +int %(main_func_name)s() { + %(dummy_func_nounder)s(); + %(dummy_func_under)s(); + return 0; +} +""" + +@feature('link_main_routines_func') +@before_method('process_source') +def link_main_routines_tg_method(self): + """ + The configuration test declares a unique task generator, + so we create other task generators from there for fortran link tests + """ + def write_test_file(task): + task.outputs[0].write(task.generator.code) + bld = self.bld + bld(rule=write_test_file, target='main.c', code=MAIN_CODE % self.__dict__) + bld(rule=write_test_file, target='test.f', code=ROUTINES_CODE) + bld(features='fc fcstlib', source='test.f', target='test') + bld(features='c fcprogram', source='main.c', target='app', use='test') + +def mangling_schemes(): + """ + Generate triplets for use with mangle_name + (used in check_fortran_mangling) + the order is tuned for gfortan + """ + for u in ('_', ''): + for du in ('', '_'): + for c in ("lower", "upper"): + yield (u, du, c) + +def mangle_name(u, du, c, name): + """Mangle a name from a triplet (used in check_fortran_mangling)""" + return getattr(name, c)() + u + (name.find('_') != -1 and du or '') + +@conf +def check_fortran_mangling(self, *k, **kw): + """ + Detect the mangling scheme, sets FORTRAN_MANGLING to the triplet found + + This test will compile a fortran static library, then link a c app against it + """ + if not self.env.CC: + self.fatal('A c compiler is required for link_main_routines') + if not self.env.FC: + self.fatal('A fortran compiler is required for link_main_routines') + if not self.env.FC_MAIN: + self.fatal('Checking for mangling requires self.env.FC_MAIN (execute "check_fortran_dummy_main" first?)') + + self.start_msg('Getting fortran mangling scheme') + for (u, du, c) in mangling_schemes(): + try: + self.check_cc( + compile_filename = [], + features = 'link_main_routines_func', + msg = 'nomsg', + errmsg = 'nomsg', + dummy_func_nounder = mangle_name(u, du, c, 'foobar'), + dummy_func_under = mangle_name(u, du, c, 'foo_bar'), + main_func_name = self.env.FC_MAIN + ) + except self.errors.ConfigurationError: + pass + else: + self.end_msg("ok ('%s', '%s', '%s-case')" % (u, du, c)) + self.env.FORTRAN_MANGLING = (u, du, c) + break + else: + self.end_msg(False) + self.fatal('mangler not found') + return (u, du, c) + +@feature('pyext') +@before_method('propagate_uselib_vars', 'apply_link') +def set_lib_pat(self): + """Sets the Fortran flags for linking with Python""" + self.env.fcshlib_PATTERN = self.env.pyext_PATTERN + +@conf +def detect_openmp(self): + """ + Detects openmp flags and sets the OPENMP ``FCFLAGS``/``LINKFLAGS`` + """ + for x in ('-fopenmp','-openmp','-mp','-xopenmp','-omp','-qsmp=omp'): + try: + self.check_fc( + msg = 'Checking for OpenMP flag %s' % x, + fragment = 'program main\n call omp_get_num_threads()\nend program main', + fcflags = x, + linkflags = x, + uselib_store = 'OPENMP' + ) + except self.errors.ConfigurationError: + pass + else: + break + else: + self.fatal('Could not find OpenMP') + +@conf +def check_gfortran_o_space(self): + if self.env.FC_NAME != 'GFORTRAN' or int(self.env.FC_VERSION[0]) > 4: + # This is for old compilers and only for gfortran. + # No idea how other implementations handle this. Be safe and bail out. + return + self.env.stash() + self.env.FCLNK_TGT_F = ['-o', ''] + try: + self.check_fc(msg='Checking if the -o link must be split from arguments', fragment=FC_FRAGMENT, features='fc fcshlib') + except self.errors.ConfigurationError: + self.env.revert() + else: + self.env.commit() diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/fc_scan.py b/ldb-2.0.8/third_party/waf/waflib/Tools/fc_scan.py new file mode 100644 index 0000000..0824c92 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/fc_scan.py @@ -0,0 +1,120 @@ +#! /usr/bin/env python +# encoding: utf-8 +# DC 2008 +# Thomas Nagy 2016-2018 (ita) + +import re + +INC_REGEX = r"""(?:^|['">]\s*;)\s*(?:|#\s*)INCLUDE\s+(?:\w+_)?[<"'](.+?)(?=["'>])""" +USE_REGEX = r"""(?:^|;)\s*USE(?:\s+|(?:(?:\s*,\s*(?:NON_)?INTRINSIC)?\s*::))\s*(\w+)""" +MOD_REGEX = r"""(?:^|;)\s*MODULE(?!\s+(?:PROCEDURE|SUBROUTINE|FUNCTION))\s+(\w+)""" +SMD_REGEX = r"""(?:^|;)\s*SUBMODULE\s*\(([\w:]+)\)\s*(\w+)""" + +re_inc = re.compile(INC_REGEX, re.I) +re_use = re.compile(USE_REGEX, re.I) +re_mod = re.compile(MOD_REGEX, re.I) +re_smd = re.compile(SMD_REGEX, re.I) + +class fortran_parser(object): + """ + This parser returns: + + * the nodes corresponding to the module names to produce + * the nodes corresponding to the include files used + * the module names used by the fortran files + """ + def __init__(self, incpaths): + self.seen = [] + """Files already parsed""" + + self.nodes = [] + """List of :py:class:`waflib.Node.Node` representing the dependencies to return""" + + self.names = [] + """List of module names to return""" + + self.incpaths = incpaths + """List of :py:class:`waflib.Node.Node` representing the include paths""" + + def find_deps(self, node): + """ + Parses a Fortran file to obtain the dependencies used/provided + + :param node: fortran file to read + :type node: :py:class:`waflib.Node.Node` + :return: lists representing the includes, the modules used, and the modules created by a fortran file + :rtype: tuple of list of strings + """ + txt = node.read() + incs = [] + uses = [] + mods = [] + for line in txt.splitlines(): + # line by line regexp search? optimize? + m = re_inc.search(line) + if m: + incs.append(m.group(1)) + m = re_use.search(line) + if m: + uses.append(m.group(1)) + m = re_mod.search(line) + if m: + mods.append(m.group(1)) + m = re_smd.search(line) + if m: + uses.append(m.group(1)) + mods.append('{0}:{1}'.format(m.group(1),m.group(2))) + return (incs, uses, mods) + + def start(self, node): + """ + Start parsing. Use the stack ``self.waiting`` to hold nodes to iterate on + + :param node: fortran file + :type node: :py:class:`waflib.Node.Node` + """ + self.waiting = [node] + while self.waiting: + nd = self.waiting.pop(0) + self.iter(nd) + + def iter(self, node): + """ + Processes a single file during dependency parsing. Extracts files used + modules used and modules provided. + """ + incs, uses, mods = self.find_deps(node) + for x in incs: + if x in self.seen: + continue + self.seen.append(x) + self.tryfind_header(x) + + for x in uses: + name = "USE@%s" % x + if not name in self.names: + self.names.append(name) + + for x in mods: + name = "MOD@%s" % x + if not name in self.names: + self.names.append(name) + + def tryfind_header(self, filename): + """ + Adds an include file to the list of nodes to process + + :param filename: file name + :type filename: string + """ + found = None + for n in self.incpaths: + found = n.find_resource(filename) + if found: + self.nodes.append(found) + self.waiting.append(found) + break + if not found: + if not filename in self.names: + self.names.append(filename) + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/flex.py b/ldb-2.0.8/third_party/waf/waflib/Tools/flex.py new file mode 100644 index 0000000..2256657 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/flex.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python +# encoding: utf-8 +# John O'Meara, 2006 +# Thomas Nagy, 2006-2018 (ita) + +""" +The **flex** program is a code generator which creates C or C++ files. +The generated files are compiled into object files. +""" + +import os, re +from waflib import Task, TaskGen +from waflib.Tools import ccroot + +def decide_ext(self, node): + if 'cxx' in self.features: + return ['.lex.cc'] + return ['.lex.c'] + +def flexfun(tsk): + env = tsk.env + bld = tsk.generator.bld + wd = bld.variant_dir + def to_list(xx): + if isinstance(xx, str): + return [xx] + return xx + tsk.last_cmd = lst = [] + lst.extend(to_list(env.FLEX)) + lst.extend(to_list(env.FLEXFLAGS)) + inputs = [a.path_from(tsk.get_cwd()) for a in tsk.inputs] + if env.FLEX_MSYS: + inputs = [x.replace(os.sep, '/') for x in inputs] + lst.extend(inputs) + lst = [x for x in lst if x] + txt = bld.cmd_and_log(lst, cwd=wd, env=env.env or None, quiet=0) + tsk.outputs[0].write(txt.replace('\r\n', '\n').replace('\r', '\n')) # issue #1207 + +TaskGen.declare_chain( + name = 'flex', + rule = flexfun, # issue #854 + ext_in = '.l', + decider = decide_ext, +) + +# To support the following: +# bld(features='c', flexflags='-P/foo') +Task.classes['flex'].vars = ['FLEXFLAGS', 'FLEX'] +ccroot.USELIB_VARS['c'].add('FLEXFLAGS') +ccroot.USELIB_VARS['cxx'].add('FLEXFLAGS') + +def configure(conf): + """ + Detect the *flex* program + """ + conf.find_program('flex', var='FLEX') + conf.env.FLEXFLAGS = ['-t'] + + if re.search (r"\\msys\\[0-9.]+\\bin\\flex.exe$", conf.env.FLEX[0]): + # this is the flex shipped with MSYS + conf.env.FLEX_MSYS = True + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/g95.py b/ldb-2.0.8/third_party/waf/waflib/Tools/g95.py new file mode 100644 index 0000000..f69ba4f --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/g95.py @@ -0,0 +1,66 @@ +#! /usr/bin/env python +# encoding: utf-8 +# KWS 2010 +# Thomas Nagy 2016-2018 (ita) + +import re +from waflib import Utils +from waflib.Tools import fc, fc_config, fc_scan, ar +from waflib.Configure import conf + +@conf +def find_g95(conf): + fc = conf.find_program('g95', var='FC') + conf.get_g95_version(fc) + conf.env.FC_NAME = 'G95' + +@conf +def g95_flags(conf): + v = conf.env + v.FCFLAGS_fcshlib = ['-fPIC'] + v.FORTRANMODFLAG = ['-fmod=', ''] # template for module path + v.FCFLAGS_DEBUG = ['-Werror'] # why not + +@conf +def g95_modifier_win32(conf): + fc_config.fortran_modifier_win32(conf) + +@conf +def g95_modifier_cygwin(conf): + fc_config.fortran_modifier_cygwin(conf) + +@conf +def g95_modifier_darwin(conf): + fc_config.fortran_modifier_darwin(conf) + +@conf +def g95_modifier_platform(conf): + dest_os = conf.env.DEST_OS or Utils.unversioned_sys_platform() + g95_modifier_func = getattr(conf, 'g95_modifier_' + dest_os, None) + if g95_modifier_func: + g95_modifier_func() + +@conf +def get_g95_version(conf, fc): + """get the compiler version""" + + version_re = re.compile(r"g95\s*(?P\d*)\.(?P\d*)").search + cmd = fc + ['--version'] + out, err = fc_config.getoutput(conf, cmd, stdin=False) + if out: + match = version_re(out) + else: + match = version_re(err) + if not match: + conf.fatal('cannot determine g95 version') + k = match.groupdict() + conf.env.FC_VERSION = (k['major'], k['minor']) + +def configure(conf): + conf.find_g95() + conf.find_ar() + conf.fc_flags() + conf.fc_add_flags() + conf.g95_flags() + conf.g95_modifier_platform() + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/gas.py b/ldb-2.0.8/third_party/waf/waflib/Tools/gas.py new file mode 100644 index 0000000..4a8745a --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/gas.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2008-2018 (ita) + +"Detect as/gas/gcc for compiling assembly files" + +import waflib.Tools.asm # - leave this +from waflib.Tools import ar + +def configure(conf): + """ + Find the programs gas/as/gcc and set the variable *AS* + """ + conf.find_program(['gas', 'gcc'], var='AS') + conf.env.AS_TGT_F = ['-c', '-o'] + conf.env.ASLNK_TGT_F = ['-o'] + conf.find_ar() + conf.load('asm') + conf.env.ASM_NAME = 'gas' diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/gcc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/gcc.py new file mode 100644 index 0000000..acdd473 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/gcc.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2006-2018 (ita) +# Ralf Habacker, 2006 (rh) +# Yinon Ehrlich, 2009 + +""" +gcc/llvm detection. +""" + +from waflib.Tools import ccroot, ar +from waflib.Configure import conf + +@conf +def find_gcc(conf): + """ + Find the program gcc, and if present, try to detect its version number + """ + cc = conf.find_program(['gcc', 'cc'], var='CC') + conf.get_cc_version(cc, gcc=True) + conf.env.CC_NAME = 'gcc' + +@conf +def gcc_common_flags(conf): + """ + Common flags for gcc on nearly all platforms + """ + v = conf.env + + v.CC_SRC_F = [] + v.CC_TGT_F = ['-c', '-o'] + + if not v.LINK_CC: + v.LINK_CC = v.CC + + v.CCLNK_SRC_F = [] + v.CCLNK_TGT_F = ['-o'] + v.CPPPATH_ST = '-I%s' + v.DEFINES_ST = '-D%s' + + v.LIB_ST = '-l%s' # template for adding libs + v.LIBPATH_ST = '-L%s' # template for adding libpaths + v.STLIB_ST = '-l%s' + v.STLIBPATH_ST = '-L%s' + v.RPATH_ST = '-Wl,-rpath,%s' + + v.SONAME_ST = '-Wl,-h,%s' + v.SHLIB_MARKER = '-Wl,-Bdynamic' + v.STLIB_MARKER = '-Wl,-Bstatic' + + v.cprogram_PATTERN = '%s' + + v.CFLAGS_cshlib = ['-fPIC'] + v.LINKFLAGS_cshlib = ['-shared'] + v.cshlib_PATTERN = 'lib%s.so' + + v.LINKFLAGS_cstlib = ['-Wl,-Bstatic'] + v.cstlib_PATTERN = 'lib%s.a' + + v.LINKFLAGS_MACBUNDLE = ['-bundle', '-undefined', 'dynamic_lookup'] + v.CFLAGS_MACBUNDLE = ['-fPIC'] + v.macbundle_PATTERN = '%s.bundle' + +@conf +def gcc_modifier_win32(conf): + """Configuration flags for executing gcc on Windows""" + v = conf.env + v.cprogram_PATTERN = '%s.exe' + + v.cshlib_PATTERN = '%s.dll' + v.implib_PATTERN = '%s.dll.a' + v.IMPLIB_ST = '-Wl,--out-implib,%s' + + v.CFLAGS_cshlib = [] + + # Auto-import is enabled by default even without this option, + # but enabling it explicitly has the nice effect of suppressing the rather boring, debug-level messages + # that the linker emits otherwise. + v.append_value('LINKFLAGS', ['-Wl,--enable-auto-import']) + +@conf +def gcc_modifier_cygwin(conf): + """Configuration flags for executing gcc on Cygwin""" + gcc_modifier_win32(conf) + v = conf.env + v.cshlib_PATTERN = 'cyg%s.dll' + v.append_value('LINKFLAGS_cshlib', ['-Wl,--enable-auto-image-base']) + v.CFLAGS_cshlib = [] + +@conf +def gcc_modifier_darwin(conf): + """Configuration flags for executing gcc on MacOS""" + v = conf.env + v.CFLAGS_cshlib = ['-fPIC'] + v.LINKFLAGS_cshlib = ['-dynamiclib'] + v.cshlib_PATTERN = 'lib%s.dylib' + v.FRAMEWORKPATH_ST = '-F%s' + v.FRAMEWORK_ST = ['-framework'] + v.ARCH_ST = ['-arch'] + + v.LINKFLAGS_cstlib = [] + + v.SHLIB_MARKER = [] + v.STLIB_MARKER = [] + v.SONAME_ST = [] + +@conf +def gcc_modifier_aix(conf): + """Configuration flags for executing gcc on AIX""" + v = conf.env + v.LINKFLAGS_cprogram = ['-Wl,-brtl'] + v.LINKFLAGS_cshlib = ['-shared','-Wl,-brtl,-bexpfull'] + v.SHLIB_MARKER = [] + +@conf +def gcc_modifier_hpux(conf): + v = conf.env + v.SHLIB_MARKER = [] + v.STLIB_MARKER = [] + v.CFLAGS_cshlib = ['-fPIC','-DPIC'] + v.cshlib_PATTERN = 'lib%s.sl' + +@conf +def gcc_modifier_openbsd(conf): + conf.env.SONAME_ST = [] + +@conf +def gcc_modifier_osf1V(conf): + v = conf.env + v.SHLIB_MARKER = [] + v.STLIB_MARKER = [] + v.SONAME_ST = [] + +@conf +def gcc_modifier_platform(conf): + """Execute platform-specific functions based on *gcc_modifier_+NAME*""" + # * set configurations specific for a platform. + # * the destination platform is detected automatically by looking at the macros the compiler predefines, + # and if it's not recognised, it fallbacks to sys.platform. + gcc_modifier_func = getattr(conf, 'gcc_modifier_' + conf.env.DEST_OS, None) + if gcc_modifier_func: + gcc_modifier_func() + +def configure(conf): + """ + Configuration for gcc + """ + conf.find_gcc() + conf.find_ar() + conf.gcc_common_flags() + conf.gcc_modifier_platform() + conf.cc_load_tools() + conf.cc_add_flags() + conf.link_add_flags() + conf.check_gcc_o_space() + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/gdc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/gdc.py new file mode 100644 index 0000000..d89a66d --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/gdc.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Carlos Rafael Giani, 2007 (dv) + +from waflib.Tools import ar, d +from waflib.Configure import conf + +@conf +def find_gdc(conf): + """ + Finds the program gdc and set the variable *D* + """ + conf.find_program('gdc', var='D') + + out = conf.cmd_and_log(conf.env.D + ['--version']) + if out.find("gdc") == -1: + conf.fatal("detected compiler is not gdc") + +@conf +def common_flags_gdc(conf): + """ + Sets the flags required by *gdc* + """ + v = conf.env + + v.DFLAGS = [] + + v.D_SRC_F = ['-c'] + v.D_TGT_F = '-o%s' + + v.D_LINKER = v.D + v.DLNK_SRC_F = '' + v.DLNK_TGT_F = '-o%s' + v.DINC_ST = '-I%s' + + v.DSHLIB_MARKER = v.DSTLIB_MARKER = '' + v.DSTLIB_ST = v.DSHLIB_ST = '-l%s' + v.DSTLIBPATH_ST = v.DLIBPATH_ST = '-L%s' + + v.LINKFLAGS_dshlib = ['-shared'] + + v.DHEADER_ext = '.di' + v.DFLAGS_d_with_header = '-fintfc' + v.D_HDR_F = '-fintfc-file=%s' + +def configure(conf): + """ + Configuration for gdc + """ + conf.find_gdc() + conf.load('ar') + conf.load('d') + conf.common_flags_gdc() + conf.d_platform_flags() + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/gfortran.py b/ldb-2.0.8/third_party/waf/waflib/Tools/gfortran.py new file mode 100644 index 0000000..1050667 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/gfortran.py @@ -0,0 +1,93 @@ +#! /usr/bin/env python +# encoding: utf-8 +# DC 2008 +# Thomas Nagy 2016-2018 (ita) + +import re +from waflib import Utils +from waflib.Tools import fc, fc_config, fc_scan, ar +from waflib.Configure import conf + +@conf +def find_gfortran(conf): + """Find the gfortran program (will look in the environment variable 'FC')""" + fc = conf.find_program(['gfortran','g77'], var='FC') + # (fallback to g77 for systems, where no gfortran is available) + conf.get_gfortran_version(fc) + conf.env.FC_NAME = 'GFORTRAN' + +@conf +def gfortran_flags(conf): + v = conf.env + v.FCFLAGS_fcshlib = ['-fPIC'] + v.FORTRANMODFLAG = ['-J', ''] # template for module path + v.FCFLAGS_DEBUG = ['-Werror'] # why not + +@conf +def gfortran_modifier_win32(conf): + fc_config.fortran_modifier_win32(conf) + +@conf +def gfortran_modifier_cygwin(conf): + fc_config.fortran_modifier_cygwin(conf) + +@conf +def gfortran_modifier_darwin(conf): + fc_config.fortran_modifier_darwin(conf) + +@conf +def gfortran_modifier_platform(conf): + dest_os = conf.env.DEST_OS or Utils.unversioned_sys_platform() + gfortran_modifier_func = getattr(conf, 'gfortran_modifier_' + dest_os, None) + if gfortran_modifier_func: + gfortran_modifier_func() + +@conf +def get_gfortran_version(conf, fc): + """Get the compiler version""" + + # ensure this is actually gfortran, not an imposter. + version_re = re.compile(r"GNU\s*Fortran", re.I).search + cmd = fc + ['--version'] + out, err = fc_config.getoutput(conf, cmd, stdin=False) + if out: + match = version_re(out) + else: + match = version_re(err) + if not match: + conf.fatal('Could not determine the compiler type') + + # --- now get more detailed info -- see c_config.get_cc_version + cmd = fc + ['-dM', '-E', '-'] + out, err = fc_config.getoutput(conf, cmd, stdin=True) + + if out.find('__GNUC__') < 0: + conf.fatal('Could not determine the compiler type') + + k = {} + out = out.splitlines() + import shlex + + for line in out: + lst = shlex.split(line) + if len(lst)>2: + key = lst[1] + val = lst[2] + k[key] = val + + def isD(var): + return var in k + + def isT(var): + return var in k and k[var] != '0' + + conf.env.FC_VERSION = (k['__GNUC__'], k['__GNUC_MINOR__'], k['__GNUC_PATCHLEVEL__']) + +def configure(conf): + conf.find_gfortran() + conf.find_ar() + conf.fc_flags() + conf.fc_add_flags() + conf.gfortran_flags() + conf.gfortran_modifier_platform() + conf.check_gfortran_o_space() diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/glib2.py b/ldb-2.0.8/third_party/waf/waflib/Tools/glib2.py new file mode 100644 index 0000000..949fe37 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/glib2.py @@ -0,0 +1,489 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2006-2018 (ita) + +""" +Support for GLib2 tools: + +* marshal +* enums +* gsettings +* gresource +""" + +import os +import functools +from waflib import Context, Task, Utils, Options, Errors, Logs +from waflib.TaskGen import taskgen_method, before_method, feature, extension +from waflib.Configure import conf + +################## marshal files + +@taskgen_method +def add_marshal_file(self, filename, prefix): + """ + Adds a file to the list of marshal files to process. Store them in the attribute *marshal_list*. + + :param filename: xml file to compile + :type filename: string + :param prefix: marshal prefix (--prefix=prefix) + :type prefix: string + """ + if not hasattr(self, 'marshal_list'): + self.marshal_list = [] + self.meths.append('process_marshal') + self.marshal_list.append((filename, prefix)) + +@before_method('process_source') +def process_marshal(self): + """ + Processes the marshal files stored in the attribute *marshal_list* to create :py:class:`waflib.Tools.glib2.glib_genmarshal` instances. + Adds the c file created to the list of source to process. + """ + for f, prefix in getattr(self, 'marshal_list', []): + node = self.path.find_resource(f) + + if not node: + raise Errors.WafError('file not found %r' % f) + + h_node = node.change_ext('.h') + c_node = node.change_ext('.c') + + task = self.create_task('glib_genmarshal', node, [h_node, c_node]) + task.env.GLIB_GENMARSHAL_PREFIX = prefix + self.source = self.to_nodes(getattr(self, 'source', [])) + self.source.append(c_node) + +class glib_genmarshal(Task.Task): + vars = ['GLIB_GENMARSHAL_PREFIX', 'GLIB_GENMARSHAL'] + color = 'BLUE' + ext_out = ['.h'] + def run(self): + bld = self.generator.bld + + get = self.env.get_flat + cmd1 = "%s %s --prefix=%s --header > %s" % ( + get('GLIB_GENMARSHAL'), + self.inputs[0].srcpath(), + get('GLIB_GENMARSHAL_PREFIX'), + self.outputs[0].abspath() + ) + + ret = bld.exec_command(cmd1) + if ret: + return ret + + #print self.outputs[1].abspath() + c = '''#include "%s"\n''' % self.outputs[0].name + self.outputs[1].write(c) + + cmd2 = "%s %s --prefix=%s --body >> %s" % ( + get('GLIB_GENMARSHAL'), + self.inputs[0].srcpath(), + get('GLIB_GENMARSHAL_PREFIX'), + self.outputs[1].abspath() + ) + return bld.exec_command(cmd2) + +########################## glib-mkenums + +@taskgen_method +def add_enums_from_template(self, source='', target='', template='', comments=''): + """ + Adds a file to the list of enum files to process. Stores them in the attribute *enums_list*. + + :param source: enum file to process + :type source: string + :param target: target file + :type target: string + :param template: template file + :type template: string + :param comments: comments + :type comments: string + """ + if not hasattr(self, 'enums_list'): + self.enums_list = [] + self.meths.append('process_enums') + self.enums_list.append({'source': source, + 'target': target, + 'template': template, + 'file-head': '', + 'file-prod': '', + 'file-tail': '', + 'enum-prod': '', + 'value-head': '', + 'value-prod': '', + 'value-tail': '', + 'comments': comments}) + +@taskgen_method +def add_enums(self, source='', target='', + file_head='', file_prod='', file_tail='', enum_prod='', + value_head='', value_prod='', value_tail='', comments=''): + """ + Adds a file to the list of enum files to process. Stores them in the attribute *enums_list*. + + :param source: enum file to process + :type source: string + :param target: target file + :type target: string + :param file_head: unused + :param file_prod: unused + :param file_tail: unused + :param enum_prod: unused + :param value_head: unused + :param value_prod: unused + :param value_tail: unused + :param comments: comments + :type comments: string + """ + if not hasattr(self, 'enums_list'): + self.enums_list = [] + self.meths.append('process_enums') + self.enums_list.append({'source': source, + 'template': '', + 'target': target, + 'file-head': file_head, + 'file-prod': file_prod, + 'file-tail': file_tail, + 'enum-prod': enum_prod, + 'value-head': value_head, + 'value-prod': value_prod, + 'value-tail': value_tail, + 'comments': comments}) + +@before_method('process_source') +def process_enums(self): + """ + Processes the enum files stored in the attribute *enum_list* to create :py:class:`waflib.Tools.glib2.glib_mkenums` instances. + """ + for enum in getattr(self, 'enums_list', []): + task = self.create_task('glib_mkenums') + env = task.env + + inputs = [] + + # process the source + source_list = self.to_list(enum['source']) + if not source_list: + raise Errors.WafError('missing source ' + str(enum)) + source_list = [self.path.find_resource(k) for k in source_list] + inputs += source_list + env.GLIB_MKENUMS_SOURCE = [k.abspath() for k in source_list] + + # find the target + if not enum['target']: + raise Errors.WafError('missing target ' + str(enum)) + tgt_node = self.path.find_or_declare(enum['target']) + if tgt_node.name.endswith('.c'): + self.source.append(tgt_node) + env.GLIB_MKENUMS_TARGET = tgt_node.abspath() + + + options = [] + + if enum['template']: # template, if provided + template_node = self.path.find_resource(enum['template']) + options.append('--template %s' % (template_node.abspath())) + inputs.append(template_node) + params = {'file-head' : '--fhead', + 'file-prod' : '--fprod', + 'file-tail' : '--ftail', + 'enum-prod' : '--eprod', + 'value-head' : '--vhead', + 'value-prod' : '--vprod', + 'value-tail' : '--vtail', + 'comments': '--comments'} + for param, option in params.items(): + if enum[param]: + options.append('%s %r' % (option, enum[param])) + + env.GLIB_MKENUMS_OPTIONS = ' '.join(options) + + # update the task instance + task.set_inputs(inputs) + task.set_outputs(tgt_node) + +class glib_mkenums(Task.Task): + """ + Processes enum files + """ + run_str = '${GLIB_MKENUMS} ${GLIB_MKENUMS_OPTIONS} ${GLIB_MKENUMS_SOURCE} > ${GLIB_MKENUMS_TARGET}' + color = 'PINK' + ext_out = ['.h'] + +######################################### gsettings + +@taskgen_method +def add_settings_schemas(self, filename_list): + """ + Adds settings files to process to *settings_schema_files* + + :param filename_list: files + :type filename_list: list of string + """ + if not hasattr(self, 'settings_schema_files'): + self.settings_schema_files = [] + + if not isinstance(filename_list, list): + filename_list = [filename_list] + + self.settings_schema_files.extend(filename_list) + +@taskgen_method +def add_settings_enums(self, namespace, filename_list): + """ + Called only once by task generator to set the enums namespace. + + :param namespace: namespace + :type namespace: string + :param filename_list: enum files to process + :type filename_list: file list + """ + if hasattr(self, 'settings_enum_namespace'): + raise Errors.WafError("Tried to add gsettings enums to %r more than once" % self.name) + self.settings_enum_namespace = namespace + + if not isinstance(filename_list, list): + filename_list = [filename_list] + self.settings_enum_files = filename_list + +@feature('glib2') +def process_settings(self): + """ + Processes the schema files in *settings_schema_files* to create :py:class:`waflib.Tools.glib2.glib_mkenums` instances. The + same files are validated through :py:class:`waflib.Tools.glib2.glib_validate_schema` tasks. + + """ + enums_tgt_node = [] + install_files = [] + + settings_schema_files = getattr(self, 'settings_schema_files', []) + if settings_schema_files and not self.env.GLIB_COMPILE_SCHEMAS: + raise Errors.WafError ("Unable to process GSettings schemas - glib-compile-schemas was not found during configure") + + # 1. process gsettings_enum_files (generate .enums.xml) + # + if hasattr(self, 'settings_enum_files'): + enums_task = self.create_task('glib_mkenums') + + source_list = self.settings_enum_files + source_list = [self.path.find_resource(k) for k in source_list] + enums_task.set_inputs(source_list) + enums_task.env.GLIB_MKENUMS_SOURCE = [k.abspath() for k in source_list] + + target = self.settings_enum_namespace + '.enums.xml' + tgt_node = self.path.find_or_declare(target) + enums_task.set_outputs(tgt_node) + enums_task.env.GLIB_MKENUMS_TARGET = tgt_node.abspath() + enums_tgt_node = [tgt_node] + + install_files.append(tgt_node) + + options = '--comments "" --fhead "" --vhead " <@type@ id=\\"%s.@EnumName@\\">" --vprod " " --vtail " " --ftail "" ' % (self.settings_enum_namespace) + enums_task.env.GLIB_MKENUMS_OPTIONS = options + + # 2. process gsettings_schema_files (validate .gschema.xml files) + # + for schema in settings_schema_files: + schema_task = self.create_task ('glib_validate_schema') + + schema_node = self.path.find_resource(schema) + if not schema_node: + raise Errors.WafError("Cannot find the schema file %r" % schema) + install_files.append(schema_node) + source_list = enums_tgt_node + [schema_node] + + schema_task.set_inputs (source_list) + schema_task.env.GLIB_COMPILE_SCHEMAS_OPTIONS = [("--schema-file=" + k.abspath()) for k in source_list] + + target_node = schema_node.change_ext('.xml.valid') + schema_task.set_outputs (target_node) + schema_task.env.GLIB_VALIDATE_SCHEMA_OUTPUT = target_node.abspath() + + # 3. schemas install task + def compile_schemas_callback(bld): + if not bld.is_install: + return + compile_schemas = Utils.to_list(bld.env.GLIB_COMPILE_SCHEMAS) + destdir = Options.options.destdir + paths = bld._compile_schemas_registered + if destdir: + paths = (os.path.join(destdir, path.lstrip(os.sep)) for path in paths) + for path in paths: + Logs.pprint('YELLOW', 'Updating GSettings schema cache %r' % path) + if self.bld.exec_command(compile_schemas + [path]): + Logs.warn('Could not update GSettings schema cache %r' % path) + + if self.bld.is_install: + schemadir = self.env.GSETTINGSSCHEMADIR + if not schemadir: + raise Errors.WafError ('GSETTINGSSCHEMADIR not defined (should have been set up automatically during configure)') + + if install_files: + self.add_install_files(install_to=schemadir, install_from=install_files) + registered_schemas = getattr(self.bld, '_compile_schemas_registered', None) + if not registered_schemas: + registered_schemas = self.bld._compile_schemas_registered = set() + self.bld.add_post_fun(compile_schemas_callback) + registered_schemas.add(schemadir) + +class glib_validate_schema(Task.Task): + """ + Validates schema files + """ + run_str = 'rm -f ${GLIB_VALIDATE_SCHEMA_OUTPUT} && ${GLIB_COMPILE_SCHEMAS} --dry-run ${GLIB_COMPILE_SCHEMAS_OPTIONS} && touch ${GLIB_VALIDATE_SCHEMA_OUTPUT}' + color = 'PINK' + +################## gresource + +@extension('.gresource.xml') +def process_gresource_source(self, node): + """ + Creates tasks that turn ``.gresource.xml`` files to C code + """ + if not self.env.GLIB_COMPILE_RESOURCES: + raise Errors.WafError ("Unable to process GResource file - glib-compile-resources was not found during configure") + + if 'gresource' in self.features: + return + + h_node = node.change_ext('_xml.h') + c_node = node.change_ext('_xml.c') + self.create_task('glib_gresource_source', node, [h_node, c_node]) + self.source.append(c_node) + +@feature('gresource') +def process_gresource_bundle(self): + """ + Creates tasks to turn ``.gresource`` files from ``.gresource.xml`` files:: + + def build(bld): + bld( + features='gresource', + source=['resources1.gresource.xml', 'resources2.gresource.xml'], + install_path='${LIBDIR}/${PACKAGE}' + ) + + :param source: XML files to process + :type source: list of string + :param install_path: installation path + :type install_path: string + """ + for i in self.to_list(self.source): + node = self.path.find_resource(i) + + task = self.create_task('glib_gresource_bundle', node, node.change_ext('')) + inst_to = getattr(self, 'install_path', None) + if inst_to: + self.add_install_files(install_to=inst_to, install_from=task.outputs) + +class glib_gresource_base(Task.Task): + """ + Base class for gresource based tasks + """ + color = 'BLUE' + base_cmd = '${GLIB_COMPILE_RESOURCES} --sourcedir=${SRC[0].parent.srcpath()} --sourcedir=${SRC[0].bld_dir()}' + + def scan(self): + """ + Scans gresource dependencies through ``glib-compile-resources --generate-dependencies command`` + """ + bld = self.generator.bld + kw = {} + kw['cwd'] = self.get_cwd() + kw['quiet'] = Context.BOTH + + cmd = Utils.subst_vars('${GLIB_COMPILE_RESOURCES} --sourcedir=%s --sourcedir=%s --generate-dependencies %s' % ( + self.inputs[0].parent.srcpath(), + self.inputs[0].bld_dir(), + self.inputs[0].bldpath() + ), self.env) + + output = bld.cmd_and_log(cmd, **kw) + + nodes = [] + names = [] + for dep in output.splitlines(): + if dep: + node = bld.bldnode.find_node(dep) + if node: + nodes.append(node) + else: + names.append(dep) + + return (nodes, names) + +class glib_gresource_source(glib_gresource_base): + """ + Task to generate C source code (.h and .c files) from a gresource.xml file + """ + vars = ['GLIB_COMPILE_RESOURCES'] + fun_h = Task.compile_fun_shell(glib_gresource_base.base_cmd + ' --target=${TGT[0].abspath()} --generate-header ${SRC}') + fun_c = Task.compile_fun_shell(glib_gresource_base.base_cmd + ' --target=${TGT[1].abspath()} --generate-source ${SRC}') + ext_out = ['.h'] + + def run(self): + return self.fun_h[0](self) or self.fun_c[0](self) + +class glib_gresource_bundle(glib_gresource_base): + """ + Task to generate a .gresource binary file from a gresource.xml file + """ + run_str = glib_gresource_base.base_cmd + ' --target=${TGT} ${SRC}' + shell = True # temporary workaround for #795 + +@conf +def find_glib_genmarshal(conf): + conf.find_program('glib-genmarshal', var='GLIB_GENMARSHAL') + +@conf +def find_glib_mkenums(conf): + if not conf.env.PERL: + conf.find_program('perl', var='PERL') + conf.find_program('glib-mkenums', interpreter='PERL', var='GLIB_MKENUMS') + +@conf +def find_glib_compile_schemas(conf): + # when cross-compiling, gsettings.m4 locates the program with the following: + # pkg-config --variable glib_compile_schemas gio-2.0 + conf.find_program('glib-compile-schemas', var='GLIB_COMPILE_SCHEMAS') + + def getstr(varname): + return getattr(Options.options, varname, getattr(conf.env,varname, '')) + + gsettingsschemadir = getstr('GSETTINGSSCHEMADIR') + if not gsettingsschemadir: + datadir = getstr('DATADIR') + if not datadir: + prefix = conf.env.PREFIX + datadir = os.path.join(prefix, 'share') + gsettingsschemadir = os.path.join(datadir, 'glib-2.0', 'schemas') + + conf.env.GSETTINGSSCHEMADIR = gsettingsschemadir + +@conf +def find_glib_compile_resources(conf): + conf.find_program('glib-compile-resources', var='GLIB_COMPILE_RESOURCES') + +def configure(conf): + """ + Finds the following programs: + + * *glib-genmarshal* and set *GLIB_GENMARSHAL* + * *glib-mkenums* and set *GLIB_MKENUMS* + * *glib-compile-schemas* and set *GLIB_COMPILE_SCHEMAS* (not mandatory) + * *glib-compile-resources* and set *GLIB_COMPILE_RESOURCES* (not mandatory) + """ + conf.find_glib_genmarshal() + conf.find_glib_mkenums() + conf.find_glib_compile_schemas(mandatory=False) + conf.find_glib_compile_resources(mandatory=False) + +def options(opt): + """ + Adds the ``--gsettingsschemadir`` command-line option + """ + gr = opt.add_option_group('Installation directories') + gr.add_option('--gsettingsschemadir', help='GSettings schema location [DATADIR/glib-2.0/schemas]', default='', dest='GSETTINGSSCHEMADIR') + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/gnu_dirs.py b/ldb-2.0.8/third_party/waf/waflib/Tools/gnu_dirs.py new file mode 100644 index 0000000..2847071 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/gnu_dirs.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Ali Sabil, 2007 + +""" +Sets various standard variables such as INCLUDEDIR. SBINDIR and others. To use this module just call:: + + opt.load('gnu_dirs') + +and:: + + conf.load('gnu_dirs') + +Add options for the standard GNU directories, this tool will add the options +found in autotools, and will update the environment with the following +installation variables: + +============== ========================================= ======================= +Variable Description Default Value +============== ========================================= ======================= +PREFIX installation prefix /usr/local +EXEC_PREFIX installation prefix for binaries PREFIX +BINDIR user commands EXEC_PREFIX/bin +SBINDIR system binaries EXEC_PREFIX/sbin +LIBEXECDIR program-specific binaries EXEC_PREFIX/libexec +SYSCONFDIR host-specific configuration PREFIX/etc +SHAREDSTATEDIR architecture-independent variable data PREFIX/com +LOCALSTATEDIR variable data PREFIX/var +LIBDIR object code libraries EXEC_PREFIX/lib +INCLUDEDIR header files PREFIX/include +OLDINCLUDEDIR header files for non-GCC compilers /usr/include +DATAROOTDIR architecture-independent data root PREFIX/share +DATADIR architecture-independent data DATAROOTDIR +INFODIR GNU "info" documentation DATAROOTDIR/info +LOCALEDIR locale-dependent data DATAROOTDIR/locale +MANDIR manual pages DATAROOTDIR/man +DOCDIR documentation root DATAROOTDIR/doc/APPNAME +HTMLDIR HTML documentation DOCDIR +DVIDIR DVI documentation DOCDIR +PDFDIR PDF documentation DOCDIR +PSDIR PostScript documentation DOCDIR +============== ========================================= ======================= +""" + +import os, re +from waflib import Utils, Options, Context + +gnuopts = ''' +bindir, user commands, ${EXEC_PREFIX}/bin +sbindir, system binaries, ${EXEC_PREFIX}/sbin +libexecdir, program-specific binaries, ${EXEC_PREFIX}/libexec +sysconfdir, host-specific configuration, ${PREFIX}/etc +sharedstatedir, architecture-independent variable data, ${PREFIX}/com +localstatedir, variable data, ${PREFIX}/var +libdir, object code libraries, ${EXEC_PREFIX}/lib%s +includedir, header files, ${PREFIX}/include +oldincludedir, header files for non-GCC compilers, /usr/include +datarootdir, architecture-independent data root, ${PREFIX}/share +datadir, architecture-independent data, ${DATAROOTDIR} +infodir, GNU "info" documentation, ${DATAROOTDIR}/info +localedir, locale-dependent data, ${DATAROOTDIR}/locale +mandir, manual pages, ${DATAROOTDIR}/man +docdir, documentation root, ${DATAROOTDIR}/doc/${PACKAGE} +htmldir, HTML documentation, ${DOCDIR} +dvidir, DVI documentation, ${DOCDIR} +pdfdir, PDF documentation, ${DOCDIR} +psdir, PostScript documentation, ${DOCDIR} +''' % Utils.lib64() + +_options = [x.split(', ') for x in gnuopts.splitlines() if x] + +def configure(conf): + """ + Reads the command-line options to set lots of variables in *conf.env*. The variables + BINDIR and LIBDIR will be overwritten. + """ + def get_param(varname, default): + return getattr(Options.options, varname, '') or default + + env = conf.env + env.LIBDIR = env.BINDIR = [] + env.EXEC_PREFIX = get_param('EXEC_PREFIX', env.PREFIX) + env.PACKAGE = getattr(Context.g_module, 'APPNAME', None) or env.PACKAGE + + complete = False + iter = 0 + while not complete and iter < len(_options) + 1: + iter += 1 + complete = True + for name, help, default in _options: + name = name.upper() + if not env[name]: + try: + env[name] = Utils.subst_vars(get_param(name, default).replace('/', os.sep), env) + except TypeError: + complete = False + + if not complete: + lst = [x for x, _, _ in _options if not env[x.upper()]] + raise conf.errors.WafError('Variable substitution failure %r' % lst) + +def options(opt): + """ + Adds lots of command-line options, for example:: + + --exec-prefix: EXEC_PREFIX + """ + inst_dir = opt.add_option_group('Installation prefix', +'By default, "waf install" will put the files in\ + "/usr/local/bin", "/usr/local/lib" etc. An installation prefix other\ + than "/usr/local" can be given using "--prefix", for example "--prefix=$HOME"') + + for k in ('--prefix', '--destdir'): + option = opt.parser.get_option(k) + if option: + opt.parser.remove_option(k) + inst_dir.add_option(option) + + inst_dir.add_option('--exec-prefix', + help = 'installation prefix for binaries [PREFIX]', + default = '', + dest = 'EXEC_PREFIX') + + dirs_options = opt.add_option_group('Installation directories') + + for name, help, default in _options: + option_name = '--' + name + str_default = default + str_help = '%s [%s]' % (help, re.sub(r'\$\{([^}]+)\}', r'\1', str_default)) + dirs_options.add_option(option_name, help=str_help, default='', dest=name.upper()) + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/gxx.py b/ldb-2.0.8/third_party/waf/waflib/Tools/gxx.py new file mode 100644 index 0000000..22c5d26 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/gxx.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2006-2018 (ita) +# Ralf Habacker, 2006 (rh) +# Yinon Ehrlich, 2009 + +""" +g++/llvm detection. +""" + +from waflib.Tools import ccroot, ar +from waflib.Configure import conf + +@conf +def find_gxx(conf): + """ + Finds the program g++, and if present, try to detect its version number + """ + cxx = conf.find_program(['g++', 'c++'], var='CXX') + conf.get_cc_version(cxx, gcc=True) + conf.env.CXX_NAME = 'gcc' + +@conf +def gxx_common_flags(conf): + """ + Common flags for g++ on nearly all platforms + """ + v = conf.env + + v.CXX_SRC_F = [] + v.CXX_TGT_F = ['-c', '-o'] + + if not v.LINK_CXX: + v.LINK_CXX = v.CXX + + v.CXXLNK_SRC_F = [] + v.CXXLNK_TGT_F = ['-o'] + v.CPPPATH_ST = '-I%s' + v.DEFINES_ST = '-D%s' + + v.LIB_ST = '-l%s' # template for adding libs + v.LIBPATH_ST = '-L%s' # template for adding libpaths + v.STLIB_ST = '-l%s' + v.STLIBPATH_ST = '-L%s' + v.RPATH_ST = '-Wl,-rpath,%s' + + v.SONAME_ST = '-Wl,-h,%s' + v.SHLIB_MARKER = '-Wl,-Bdynamic' + v.STLIB_MARKER = '-Wl,-Bstatic' + + v.cxxprogram_PATTERN = '%s' + + v.CXXFLAGS_cxxshlib = ['-fPIC'] + v.LINKFLAGS_cxxshlib = ['-shared'] + v.cxxshlib_PATTERN = 'lib%s.so' + + v.LINKFLAGS_cxxstlib = ['-Wl,-Bstatic'] + v.cxxstlib_PATTERN = 'lib%s.a' + + v.LINKFLAGS_MACBUNDLE = ['-bundle', '-undefined', 'dynamic_lookup'] + v.CXXFLAGS_MACBUNDLE = ['-fPIC'] + v.macbundle_PATTERN = '%s.bundle' + +@conf +def gxx_modifier_win32(conf): + """Configuration flags for executing gcc on Windows""" + v = conf.env + v.cxxprogram_PATTERN = '%s.exe' + + v.cxxshlib_PATTERN = '%s.dll' + v.implib_PATTERN = '%s.dll.a' + v.IMPLIB_ST = '-Wl,--out-implib,%s' + + v.CXXFLAGS_cxxshlib = [] + + # Auto-import is enabled by default even without this option, + # but enabling it explicitly has the nice effect of suppressing the rather boring, debug-level messages + # that the linker emits otherwise. + v.append_value('LINKFLAGS', ['-Wl,--enable-auto-import']) + +@conf +def gxx_modifier_cygwin(conf): + """Configuration flags for executing g++ on Cygwin""" + gxx_modifier_win32(conf) + v = conf.env + v.cxxshlib_PATTERN = 'cyg%s.dll' + v.append_value('LINKFLAGS_cxxshlib', ['-Wl,--enable-auto-image-base']) + v.CXXFLAGS_cxxshlib = [] + +@conf +def gxx_modifier_darwin(conf): + """Configuration flags for executing g++ on MacOS""" + v = conf.env + v.CXXFLAGS_cxxshlib = ['-fPIC'] + v.LINKFLAGS_cxxshlib = ['-dynamiclib'] + v.cxxshlib_PATTERN = 'lib%s.dylib' + v.FRAMEWORKPATH_ST = '-F%s' + v.FRAMEWORK_ST = ['-framework'] + v.ARCH_ST = ['-arch'] + + v.LINKFLAGS_cxxstlib = [] + + v.SHLIB_MARKER = [] + v.STLIB_MARKER = [] + v.SONAME_ST = [] + +@conf +def gxx_modifier_aix(conf): + """Configuration flags for executing g++ on AIX""" + v = conf.env + v.LINKFLAGS_cxxprogram= ['-Wl,-brtl'] + + v.LINKFLAGS_cxxshlib = ['-shared', '-Wl,-brtl,-bexpfull'] + v.SHLIB_MARKER = [] + +@conf +def gxx_modifier_hpux(conf): + v = conf.env + v.SHLIB_MARKER = [] + v.STLIB_MARKER = [] + v.CFLAGS_cxxshlib = ['-fPIC','-DPIC'] + v.cxxshlib_PATTERN = 'lib%s.sl' + +@conf +def gxx_modifier_openbsd(conf): + conf.env.SONAME_ST = [] + +@conf +def gcc_modifier_osf1V(conf): + v = conf.env + v.SHLIB_MARKER = [] + v.STLIB_MARKER = [] + v.SONAME_ST = [] + +@conf +def gxx_modifier_platform(conf): + """Execute platform-specific functions based on *gxx_modifier_+NAME*""" + # * set configurations specific for a platform. + # * the destination platform is detected automatically by looking at the macros the compiler predefines, + # and if it's not recognised, it fallbacks to sys.platform. + gxx_modifier_func = getattr(conf, 'gxx_modifier_' + conf.env.DEST_OS, None) + if gxx_modifier_func: + gxx_modifier_func() + +def configure(conf): + """ + Configuration for g++ + """ + conf.find_gxx() + conf.find_ar() + conf.gxx_common_flags() + conf.gxx_modifier_platform() + conf.cxx_load_tools() + conf.cxx_add_flags() + conf.link_add_flags() + conf.check_gcc_o_space('cxx') + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/icc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/icc.py new file mode 100644 index 0000000..b6492c8 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/icc.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Stian Selnes 2008 +# Thomas Nagy 2009-2018 (ita) + +""" +Detects the Intel C compiler +""" + +import sys +from waflib.Tools import ccroot, ar, gcc +from waflib.Configure import conf + +@conf +def find_icc(conf): + """ + Finds the program icc and execute it to ensure it really is icc + """ + cc = conf.find_program(['icc', 'ICL'], var='CC') + conf.get_cc_version(cc, icc=True) + conf.env.CC_NAME = 'icc' + +def configure(conf): + conf.find_icc() + conf.find_ar() + conf.gcc_common_flags() + conf.gcc_modifier_platform() + conf.cc_load_tools() + conf.cc_add_flags() + conf.link_add_flags() diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/icpc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/icpc.py new file mode 100644 index 0000000..8a6cc6c --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/icpc.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy 2009-2018 (ita) + +""" +Detects the Intel C++ compiler +""" + +import sys +from waflib.Tools import ccroot, ar, gxx +from waflib.Configure import conf + +@conf +def find_icpc(conf): + """ + Finds the program icpc, and execute it to ensure it really is icpc + """ + cxx = conf.find_program('icpc', var='CXX') + conf.get_cc_version(cxx, icc=True) + conf.env.CXX_NAME = 'icc' + +def configure(conf): + conf.find_icpc() + conf.find_ar() + conf.gxx_common_flags() + conf.gxx_modifier_platform() + conf.cxx_load_tools() + conf.cxx_add_flags() + conf.link_add_flags() + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/ifort.py b/ldb-2.0.8/third_party/waf/waflib/Tools/ifort.py new file mode 100644 index 0000000..17d3052 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/ifort.py @@ -0,0 +1,413 @@ +#! /usr/bin/env python +# encoding: utf-8 +# DC 2008 +# Thomas Nagy 2016-2018 (ita) + +import os, re, traceback +from waflib import Utils, Logs, Errors +from waflib.Tools import fc, fc_config, fc_scan, ar, ccroot +from waflib.Configure import conf +from waflib.TaskGen import after_method, feature + +@conf +def find_ifort(conf): + fc = conf.find_program('ifort', var='FC') + conf.get_ifort_version(fc) + conf.env.FC_NAME = 'IFORT' + +@conf +def ifort_modifier_win32(self): + v = self.env + v.IFORT_WIN32 = True + v.FCSTLIB_MARKER = '' + v.FCSHLIB_MARKER = '' + + v.FCLIB_ST = v.FCSTLIB_ST = '%s.lib' + v.FCLIBPATH_ST = v.STLIBPATH_ST = '/LIBPATH:%s' + v.FCINCPATH_ST = '/I%s' + v.FCDEFINES_ST = '/D%s' + + v.fcprogram_PATTERN = v.fcprogram_test_PATTERN = '%s.exe' + v.fcshlib_PATTERN = '%s.dll' + v.fcstlib_PATTERN = v.implib_PATTERN = '%s.lib' + + v.FCLNK_TGT_F = '/out:' + v.FC_TGT_F = ['/c', '/o', ''] + v.FCFLAGS_fcshlib = '' + v.LINKFLAGS_fcshlib = '/DLL' + v.AR_TGT_F = '/out:' + v.IMPLIB_ST = '/IMPLIB:%s' + + v.append_value('LINKFLAGS', '/subsystem:console') + if v.IFORT_MANIFEST: + v.append_value('LINKFLAGS', ['/MANIFEST']) + +@conf +def ifort_modifier_darwin(conf): + fc_config.fortran_modifier_darwin(conf) + +@conf +def ifort_modifier_platform(conf): + dest_os = conf.env.DEST_OS or Utils.unversioned_sys_platform() + ifort_modifier_func = getattr(conf, 'ifort_modifier_' + dest_os, None) + if ifort_modifier_func: + ifort_modifier_func() + +@conf +def get_ifort_version(conf, fc): + """ + Detects the compiler version and sets ``conf.env.FC_VERSION`` + """ + version_re = re.compile(r"\bIntel\b.*\bVersion\s*(?P\d*)\.(?P\d*)",re.I).search + if Utils.is_win32: + cmd = fc + else: + cmd = fc + ['-logo'] + + out, err = fc_config.getoutput(conf, cmd, stdin=False) + match = version_re(out) or version_re(err) + if not match: + conf.fatal('cannot determine ifort version.') + k = match.groupdict() + conf.env.FC_VERSION = (k['major'], k['minor']) + +def configure(conf): + """ + Detects the Intel Fortran compilers + """ + if Utils.is_win32: + compiler, version, path, includes, libdirs, arch = conf.detect_ifort() + v = conf.env + v.DEST_CPU = arch + v.PATH = path + v.INCLUDES = includes + v.LIBPATH = libdirs + v.MSVC_COMPILER = compiler + try: + v.MSVC_VERSION = float(version) + except ValueError: + v.MSVC_VERSION = float(version[:-3]) + + conf.find_ifort_win32() + conf.ifort_modifier_win32() + else: + conf.find_ifort() + conf.find_program('xiar', var='AR') + conf.find_ar() + conf.fc_flags() + conf.fc_add_flags() + conf.ifort_modifier_platform() + + +all_ifort_platforms = [ ('intel64', 'amd64'), ('em64t', 'amd64'), ('ia32', 'x86'), ('Itanium', 'ia64')] +"""List of icl platforms""" + +@conf +def gather_ifort_versions(conf, versions): + """ + List compiler versions by looking up registry keys + """ + version_pattern = re.compile(r'^...?.?\....?.?') + try: + all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Intel\\Compilers\\Fortran') + except OSError: + try: + all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Intel\\Compilers\\Fortran') + except OSError: + return + index = 0 + while 1: + try: + version = Utils.winreg.EnumKey(all_versions, index) + except OSError: + break + index += 1 + if not version_pattern.match(version): + continue + targets = {} + for target,arch in all_ifort_platforms: + if target=='intel64': + targetDir='EM64T_NATIVE' + else: + targetDir=target + try: + Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir) + icl_version=Utils.winreg.OpenKey(all_versions,version) + path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') + except OSError: + pass + else: + batch_file=os.path.join(path,'bin','ifortvars.bat') + if os.path.isfile(batch_file): + targets[target] = target_compiler(conf, 'intel', arch, version, target, batch_file) + + for target,arch in all_ifort_platforms: + try: + icl_version = Utils.winreg.OpenKey(all_versions, version+'\\'+target) + path,type = Utils.winreg.QueryValueEx(icl_version,'ProductDir') + except OSError: + continue + else: + batch_file=os.path.join(path,'bin','ifortvars.bat') + if os.path.isfile(batch_file): + targets[target] = target_compiler(conf, 'intel', arch, version, target, batch_file) + major = version[0:2] + versions['intel ' + major] = targets + +@conf +def setup_ifort(conf, versiondict): + """ + Checks installed compilers and targets and returns the first combination from the user's + options, env, or the global supported lists that checks. + + :param versiondict: dict(platform -> dict(architecture -> configuration)) + :type versiondict: dict(string -> dict(string -> target_compiler) + :return: the compiler, revision, path, include dirs, library paths and target architecture + :rtype: tuple of strings + """ + platforms = Utils.to_list(conf.env.MSVC_TARGETS) or [i for i,j in all_ifort_platforms] + desired_versions = conf.env.MSVC_VERSIONS or list(reversed(list(versiondict.keys()))) + for version in desired_versions: + try: + targets = versiondict[version] + except KeyError: + continue + for arch in platforms: + try: + cfg = targets[arch] + except KeyError: + continue + cfg.evaluate() + if cfg.is_valid: + compiler,revision = version.rsplit(' ', 1) + return compiler,revision,cfg.bindirs,cfg.incdirs,cfg.libdirs,cfg.cpu + conf.fatal('ifort: Impossible to find a valid architecture for building %r - %r' % (desired_versions, list(versiondict.keys()))) + +@conf +def get_ifort_version_win32(conf, compiler, version, target, vcvars): + # FIXME hack + try: + conf.msvc_cnt += 1 + except AttributeError: + conf.msvc_cnt = 1 + batfile = conf.bldnode.make_node('waf-print-msvc-%d.bat' % conf.msvc_cnt) + batfile.write("""@echo off +set INCLUDE= +set LIB= +call "%s" %s +echo PATH=%%PATH%% +echo INCLUDE=%%INCLUDE%% +echo LIB=%%LIB%%;%%LIBPATH%% +""" % (vcvars,target)) + sout = conf.cmd_and_log(['cmd.exe', '/E:on', '/V:on', '/C', batfile.abspath()]) + batfile.delete() + lines = sout.splitlines() + + if not lines[0]: + lines.pop(0) + + MSVC_PATH = MSVC_INCDIR = MSVC_LIBDIR = None + for line in lines: + if line.startswith('PATH='): + path = line[5:] + MSVC_PATH = path.split(';') + elif line.startswith('INCLUDE='): + MSVC_INCDIR = [i for i in line[8:].split(';') if i] + elif line.startswith('LIB='): + MSVC_LIBDIR = [i for i in line[4:].split(';') if i] + if None in (MSVC_PATH, MSVC_INCDIR, MSVC_LIBDIR): + conf.fatal('ifort: Could not find a valid architecture for building (get_ifort_version_win32)') + + # Check if the compiler is usable at all. + # The detection may return 64-bit versions even on 32-bit systems, and these would fail to run. + env = dict(os.environ) + env.update(PATH = path) + compiler_name, linker_name, lib_name = _get_prog_names(conf, compiler) + fc = conf.find_program(compiler_name, path_list=MSVC_PATH) + + # delete CL if exists. because it could contain parameters which can change cl's behaviour rather catastrophically. + if 'CL' in env: + del(env['CL']) + + try: + conf.cmd_and_log(fc + ['/help'], env=env) + except UnicodeError: + st = traceback.format_exc() + if conf.logger: + conf.logger.error(st) + conf.fatal('ifort: Unicode error - check the code page?') + except Exception as e: + Logs.debug('ifort: get_ifort_version: %r %r %r -> failure %s', compiler, version, target, str(e)) + conf.fatal('ifort: cannot run the compiler in get_ifort_version (run with -v to display errors)') + else: + Logs.debug('ifort: get_ifort_version: %r %r %r -> OK', compiler, version, target) + finally: + conf.env[compiler_name] = '' + + return (MSVC_PATH, MSVC_INCDIR, MSVC_LIBDIR) + +class target_compiler(object): + """ + Wraps a compiler configuration; call evaluate() to determine + whether the configuration is usable. + """ + def __init__(self, ctx, compiler, cpu, version, bat_target, bat, callback=None): + """ + :param ctx: configuration context to use to eventually get the version environment + :param compiler: compiler name + :param cpu: target cpu + :param version: compiler version number + :param bat_target: ? + :param bat: path to the batch file to run + :param callback: optional function to take the realized environment variables tup and map it (e.g. to combine other constant paths) + """ + self.conf = ctx + self.name = None + self.is_valid = False + self.is_done = False + + self.compiler = compiler + self.cpu = cpu + self.version = version + self.bat_target = bat_target + self.bat = bat + self.callback = callback + + def evaluate(self): + if self.is_done: + return + self.is_done = True + try: + vs = self.conf.get_ifort_version_win32(self.compiler, self.version, self.bat_target, self.bat) + except Errors.ConfigurationError: + self.is_valid = False + return + if self.callback: + vs = self.callback(self, vs) + self.is_valid = True + (self.bindirs, self.incdirs, self.libdirs) = vs + + def __str__(self): + return str((self.bindirs, self.incdirs, self.libdirs)) + + def __repr__(self): + return repr((self.bindirs, self.incdirs, self.libdirs)) + +@conf +def detect_ifort(self): + return self.setup_ifort(self.get_ifort_versions(False)) + +@conf +def get_ifort_versions(self, eval_and_save=True): + """ + :return: platforms to compiler configurations + :rtype: dict + """ + dct = {} + self.gather_ifort_versions(dct) + return dct + +def _get_prog_names(self, compiler): + if compiler=='intel': + compiler_name = 'ifort' + linker_name = 'XILINK' + lib_name = 'XILIB' + else: + # assumes CL.exe + compiler_name = 'CL' + linker_name = 'LINK' + lib_name = 'LIB' + return compiler_name, linker_name, lib_name + +@conf +def find_ifort_win32(conf): + # the autodetection is supposed to be performed before entering in this method + v = conf.env + path = v.PATH + compiler = v.MSVC_COMPILER + version = v.MSVC_VERSION + + compiler_name, linker_name, lib_name = _get_prog_names(conf, compiler) + v.IFORT_MANIFEST = (compiler == 'intel' and version >= 11) + + # compiler + fc = conf.find_program(compiler_name, var='FC', path_list=path) + + # before setting anything, check if the compiler is really intel fortran + env = dict(conf.environ) + if path: + env.update(PATH = ';'.join(path)) + if not conf.cmd_and_log(fc + ['/nologo', '/help'], env=env): + conf.fatal('not intel fortran compiler could not be identified') + + v.FC_NAME = 'IFORT' + + if not v.LINK_FC: + conf.find_program(linker_name, var='LINK_FC', path_list=path, mandatory=True) + + if not v.AR: + conf.find_program(lib_name, path_list=path, var='AR', mandatory=True) + v.ARFLAGS = ['/nologo'] + + # manifest tool. Not required for VS 2003 and below. Must have for VS 2005 and later + if v.IFORT_MANIFEST: + conf.find_program('MT', path_list=path, var='MT') + v.MTFLAGS = ['/nologo'] + + try: + conf.load('winres') + except Errors.WafError: + Logs.warn('Resource compiler not found. Compiling resource file is disabled') + +####################################################################################################### +##### conf above, build below + +@after_method('apply_link') +@feature('fc') +def apply_flags_ifort(self): + """ + Adds additional flags implied by msvc, such as subsystems and pdb files:: + + def build(bld): + bld.stlib(source='main.c', target='bar', subsystem='gruik') + """ + if not self.env.IFORT_WIN32 or not getattr(self, 'link_task', None): + return + + is_static = isinstance(self.link_task, ccroot.stlink_task) + + subsystem = getattr(self, 'subsystem', '') + if subsystem: + subsystem = '/subsystem:%s' % subsystem + flags = is_static and 'ARFLAGS' or 'LINKFLAGS' + self.env.append_value(flags, subsystem) + + if not is_static: + for f in self.env.LINKFLAGS: + d = f.lower() + if d[1:] == 'debug': + pdbnode = self.link_task.outputs[0].change_ext('.pdb') + self.link_task.outputs.append(pdbnode) + + if getattr(self, 'install_task', None): + self.pdb_install_task = self.add_install_files(install_to=self.install_task.install_to, install_from=pdbnode) + + break + +@feature('fcprogram', 'fcshlib', 'fcprogram_test') +@after_method('apply_link') +def apply_manifest_ifort(self): + """ + Enables manifest embedding in Fortran DLLs when using ifort on Windows + See: http://msdn2.microsoft.com/en-us/library/ms235542(VS.80).aspx + """ + if self.env.IFORT_WIN32 and getattr(self, 'link_task', None): + # it seems ifort.exe cannot be called for linking + self.link_task.env.FC = self.env.LINK_FC + + if self.env.IFORT_WIN32 and self.env.IFORT_MANIFEST and getattr(self, 'link_task', None): + out_node = self.link_task.outputs[0] + man_node = out_node.parent.find_or_declare(out_node.name + '.manifest') + self.link_task.outputs.append(man_node) + self.env.DO_MANIFEST = True + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/intltool.py b/ldb-2.0.8/third_party/waf/waflib/Tools/intltool.py new file mode 100644 index 0000000..af95ba8 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/intltool.py @@ -0,0 +1,231 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2006-2018 (ita) + +""" +Support for translation tools such as msgfmt and intltool + +Usage:: + + def configure(conf): + conf.load('gnu_dirs intltool') + + def build(bld): + # process the .po files into .gmo files, and install them in LOCALEDIR + bld(features='intltool_po', appname='myapp', podir='po', install_path="${LOCALEDIR}") + + # process an input file, substituting the translations from the po dir + bld( + features = "intltool_in", + podir = "../po", + style = "desktop", + flags = ["-u"], + source = 'kupfer.desktop.in', + install_path = "${DATADIR}/applications", + ) + +Usage of the :py:mod:`waflib.Tools.gnu_dirs` is recommended, but not obligatory. +""" + +from __future__ import with_statement + +import os, re +from waflib import Context, Task, Utils, Logs +import waflib.Tools.ccroot +from waflib.TaskGen import feature, before_method, taskgen_method +from waflib.Logs import error +from waflib.Configure import conf + +_style_flags = { + 'ba': '-b', + 'desktop': '-d', + 'keys': '-k', + 'quoted': '--quoted-style', + 'quotedxml': '--quotedxml-style', + 'rfc822deb': '-r', + 'schemas': '-s', + 'xml': '-x', +} + +@taskgen_method +def ensure_localedir(self): + """ + Expands LOCALEDIR from DATAROOTDIR/locale if possible, or falls back to PREFIX/share/locale + """ + # use the tool gnu_dirs to provide options to define this + if not self.env.LOCALEDIR: + if self.env.DATAROOTDIR: + self.env.LOCALEDIR = os.path.join(self.env.DATAROOTDIR, 'locale') + else: + self.env.LOCALEDIR = os.path.join(self.env.PREFIX, 'share', 'locale') + +@before_method('process_source') +@feature('intltool_in') +def apply_intltool_in_f(self): + """ + Creates tasks to translate files by intltool-merge:: + + def build(bld): + bld( + features = "intltool_in", + podir = "../po", + style = "desktop", + flags = ["-u"], + source = 'kupfer.desktop.in', + install_path = "${DATADIR}/applications", + ) + + :param podir: location of the .po files + :type podir: string + :param source: source files to process + :type source: list of string + :param style: the intltool-merge mode of operation, can be one of the following values: + ``ba``, ``desktop``, ``keys``, ``quoted``, ``quotedxml``, ``rfc822deb``, ``schemas`` and ``xml``. + See the ``intltool-merge`` man page for more information about supported modes of operation. + :type style: string + :param flags: compilation flags ("-quc" by default) + :type flags: list of string + :param install_path: installation path + :type install_path: string + """ + try: + self.meths.remove('process_source') + except ValueError: + pass + + self.ensure_localedir() + + podir = getattr(self, 'podir', '.') + podirnode = self.path.find_dir(podir) + if not podirnode: + error("could not find the podir %r" % podir) + return + + cache = getattr(self, 'intlcache', '.intlcache') + self.env.INTLCACHE = [os.path.join(str(self.path.get_bld()), podir, cache)] + self.env.INTLPODIR = podirnode.bldpath() + self.env.append_value('INTLFLAGS', getattr(self, 'flags', self.env.INTLFLAGS_DEFAULT)) + + if '-c' in self.env.INTLFLAGS: + self.bld.fatal('Redundant -c flag in intltool task %r' % self) + + style = getattr(self, 'style', None) + if style: + try: + style_flag = _style_flags[style] + except KeyError: + self.bld.fatal('intltool_in style "%s" is not valid' % style) + + self.env.append_unique('INTLFLAGS', [style_flag]) + + for i in self.to_list(self.source): + node = self.path.find_resource(i) + + task = self.create_task('intltool', node, node.change_ext('')) + inst = getattr(self, 'install_path', None) + if inst: + self.add_install_files(install_to=inst, install_from=task.outputs) + +@feature('intltool_po') +def apply_intltool_po(self): + """ + Creates tasks to process po files:: + + def build(bld): + bld(features='intltool_po', appname='myapp', podir='po', install_path="${LOCALEDIR}") + + The relevant task generator arguments are: + + :param podir: directory of the .po files + :type podir: string + :param appname: name of the application + :type appname: string + :param install_path: installation directory + :type install_path: string + + The file LINGUAS must be present in the directory pointed by *podir* and list the translation files to process. + """ + try: + self.meths.remove('process_source') + except ValueError: + pass + + self.ensure_localedir() + + appname = getattr(self, 'appname', getattr(Context.g_module, Context.APPNAME, 'set_your_app_name')) + podir = getattr(self, 'podir', '.') + inst = getattr(self, 'install_path', '${LOCALEDIR}') + + linguas = self.path.find_node(os.path.join(podir, 'LINGUAS')) + if linguas: + # scan LINGUAS file for locales to process + with open(linguas.abspath()) as f: + langs = [] + for line in f.readlines(): + # ignore lines containing comments + if not line.startswith('#'): + langs += line.split() + re_linguas = re.compile('[-a-zA-Z_@.]+') + for lang in langs: + # Make sure that we only process lines which contain locales + if re_linguas.match(lang): + node = self.path.find_resource(os.path.join(podir, re_linguas.match(lang).group() + '.po')) + task = self.create_task('po', node, node.change_ext('.mo')) + + if inst: + filename = task.outputs[0].name + (langname, ext) = os.path.splitext(filename) + inst_file = inst + os.sep + langname + os.sep + 'LC_MESSAGES' + os.sep + appname + '.mo' + self.add_install_as(install_to=inst_file, install_from=task.outputs[0], + chmod=getattr(self, 'chmod', Utils.O644)) + + else: + Logs.pprint('RED', "Error no LINGUAS file found in po directory") + +class po(Task.Task): + """ + Compiles .po files into .gmo files + """ + run_str = '${MSGFMT} -o ${TGT} ${SRC}' + color = 'BLUE' + +class intltool(Task.Task): + """ + Calls intltool-merge to update translation files + """ + run_str = '${INTLTOOL} ${INTLFLAGS} ${INTLCACHE_ST:INTLCACHE} ${INTLPODIR} ${SRC} ${TGT}' + color = 'BLUE' + +@conf +def find_msgfmt(conf): + """ + Detects msgfmt and sets the ``MSGFMT`` variable + """ + conf.find_program('msgfmt', var='MSGFMT') + +@conf +def find_intltool_merge(conf): + """ + Detects intltool-merge + """ + if not conf.env.PERL: + conf.find_program('perl', var='PERL') + conf.env.INTLCACHE_ST = '--cache=%s' + conf.env.INTLFLAGS_DEFAULT = ['-q', '-u'] + conf.find_program('intltool-merge', interpreter='PERL', var='INTLTOOL') + +def configure(conf): + """ + Detects the program *msgfmt* and set *conf.env.MSGFMT*. + Detects the program *intltool-merge* and set *conf.env.INTLTOOL*. + It is possible to set INTLTOOL in the environment, but it must not have spaces in it:: + + $ INTLTOOL="/path/to/the program/intltool" waf configure + + If a C/C++ compiler is present, execute a compilation test to find the header *locale.h*. + """ + conf.find_msgfmt() + conf.find_intltool_merge() + if conf.env.CC or conf.env.CXX: + conf.check(header_name='locale.h') + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/irixcc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/irixcc.py new file mode 100644 index 0000000..c3ae1ac --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/irixcc.py @@ -0,0 +1,66 @@ +#! /usr/bin/env python +# encoding: utf-8 +# imported from samba + +""" +Compiler definition for irix/MIPSpro cc compiler +""" + +from waflib import Errors +from waflib.Tools import ccroot, ar +from waflib.Configure import conf + +@conf +def find_irixcc(conf): + v = conf.env + cc = None + if v.CC: + cc = v.CC + elif 'CC' in conf.environ: + cc = conf.environ['CC'] + if not cc: + cc = conf.find_program('cc', var='CC') + if not cc: + conf.fatal('irixcc was not found') + + try: + conf.cmd_and_log(cc + ['-version']) + except Errors.WafError: + conf.fatal('%r -version could not be executed' % cc) + + v.CC = cc + v.CC_NAME = 'irix' + +@conf +def irixcc_common_flags(conf): + v = conf.env + + v.CC_SRC_F = '' + v.CC_TGT_F = ['-c', '-o'] + v.CPPPATH_ST = '-I%s' + v.DEFINES_ST = '-D%s' + + if not v.LINK_CC: + v.LINK_CC = v.CC + + v.CCLNK_SRC_F = '' + v.CCLNK_TGT_F = ['-o'] + + v.LIB_ST = '-l%s' # template for adding libs + v.LIBPATH_ST = '-L%s' # template for adding libpaths + v.STLIB_ST = '-l%s' + v.STLIBPATH_ST = '-L%s' + + v.cprogram_PATTERN = '%s' + v.cshlib_PATTERN = 'lib%s.so' + v.cstlib_PATTERN = 'lib%s.a' + +def configure(conf): + conf.find_irixcc() + conf.find_cpp() + conf.find_ar() + conf.irixcc_common_flags() + conf.cc_load_tools() + conf.cc_add_flags() + conf.link_add_flags() + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/javaw.py b/ldb-2.0.8/third_party/waf/waflib/Tools/javaw.py new file mode 100644 index 0000000..ceb08c2 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/javaw.py @@ -0,0 +1,593 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2006-2018 (ita) + +""" +Java support + +Javac is one of the few compilers that behaves very badly: + +#. it outputs files where it wants to (-d is only for the package root) + +#. it recompiles files silently behind your back + +#. it outputs an undefined amount of files (inner classes) + +Remember that the compilation can be performed using Jython[1] rather than regular Python. Instead of +running one of the following commands:: + + ./waf configure + python waf configure + +You would have to run:: + + java -jar /path/to/jython.jar waf configure + +[1] http://www.jython.org/ + +Usage +===== + +Load the "java" tool. + +def configure(conf): + conf.load('java') + +Java tools will be autodetected and eventually, if present, the quite +standard JAVA_HOME environment variable will be used. The also standard +CLASSPATH variable is used for library searching. + +In configuration phase checks can be done on the system environment, for +example to check if a class is known in the classpath:: + + conf.check_java_class('java.io.FileOutputStream') + +or if the system supports JNI applications building:: + + conf.check_jni_headers() + + +The java tool supports compiling java code, creating jar files and +creating javadoc documentation. This can be either done separately or +together in a single definition. For example to manage them separately:: + + bld(features = 'javac', + srcdir = 'src', + compat = '1.7', + use = 'animals', + name = 'cats-src', + ) + + bld(features = 'jar', + basedir = '.', + destfile = '../cats.jar', + name = 'cats', + use = 'cats-src' + ) + + +Or together by defining all the needed attributes:: + + bld(features = 'javac jar javadoc', + srcdir = 'src/', # folder containing the sources to compile + outdir = 'src', # folder where to output the classes (in the build directory) + compat = '1.6', # java compatibility version number + classpath = ['.', '..'], + + # jar + basedir = 'src', # folder containing the classes and other files to package (must match outdir) + destfile = 'foo.jar', # do not put the destfile in the folder of the java classes! + use = 'NNN', + jaropts = ['-C', 'default/src/', '.'], # can be used to give files + manifest = 'src/Manifest.mf', # Manifest file to include + + # javadoc + javadoc_package = ['com.meow' , 'com.meow.truc.bar', 'com.meow.truc.foo'], + javadoc_output = 'javadoc', + ) + +External jar dependencies can be mapped to a standard waf "use" dependency by +setting an environment variable with a CLASSPATH prefix in the configuration, +for example:: + + conf.env.CLASSPATH_NNN = ['aaaa.jar', 'bbbb.jar'] + +and then NNN can be freely used in rules as:: + + use = 'NNN', + +In the java tool the dependencies via use are not transitive by default, as +this necessity depends on the code. To enable recursive dependency scanning +use on a specific rule: + + recurse_use = True + +Or build-wise by setting RECURSE_JAVA: + + bld.env.RECURSE_JAVA = True + +Unit tests can be integrated in the waf unit test environment using the javatest extra. +""" + +import os, shutil +from waflib import Task, Utils, Errors, Node +from waflib.Configure import conf +from waflib.TaskGen import feature, before_method, after_method, taskgen_method + +from waflib.Tools import ccroot +ccroot.USELIB_VARS['javac'] = set(['CLASSPATH', 'JAVACFLAGS']) + +SOURCE_RE = '**/*.java' +JAR_RE = '**/*' + +class_check_source = ''' +public class Test { + public static void main(String[] argv) { + Class lib; + if (argv.length < 1) { + System.err.println("Missing argument"); + System.exit(77); + } + try { + lib = Class.forName(argv[0]); + } catch (ClassNotFoundException e) { + System.err.println("ClassNotFoundException"); + System.exit(1); + } + lib = null; + System.exit(0); + } +} +''' + +@feature('javac') +@before_method('process_source') +def apply_java(self): + """ + Create a javac task for compiling *.java files*. There can be + only one javac task by task generator. + """ + Utils.def_attrs(self, jarname='', classpath='', + sourcepath='.', srcdir='.', + jar_mf_attributes={}, jar_mf_classpath=[]) + + outdir = getattr(self, 'outdir', None) + if outdir: + if not isinstance(outdir, Node.Node): + outdir = self.path.get_bld().make_node(self.outdir) + else: + outdir = self.path.get_bld() + outdir.mkdir() + self.outdir = outdir + self.env.OUTDIR = outdir.abspath() + + self.javac_task = tsk = self.create_task('javac') + tmp = [] + + srcdir = getattr(self, 'srcdir', '') + if isinstance(srcdir, Node.Node): + srcdir = [srcdir] + for x in Utils.to_list(srcdir): + if isinstance(x, Node.Node): + y = x + else: + y = self.path.find_dir(x) + if not y: + self.bld.fatal('Could not find the folder %s from %s' % (x, self.path)) + tmp.append(y) + + tsk.srcdir = tmp + + if getattr(self, 'compat', None): + tsk.env.append_value('JAVACFLAGS', ['-source', str(self.compat)]) + + if hasattr(self, 'sourcepath'): + fold = [isinstance(x, Node.Node) and x or self.path.find_dir(x) for x in self.to_list(self.sourcepath)] + names = os.pathsep.join([x.srcpath() for x in fold]) + else: + names = [x.srcpath() for x in tsk.srcdir] + + if names: + tsk.env.append_value('JAVACFLAGS', ['-sourcepath', names]) + + +@taskgen_method +def java_use_rec(self, name, **kw): + """ + Processes recursively the *use* attribute for each referred java compilation + """ + if name in self.tmp_use_seen: + return + + self.tmp_use_seen.append(name) + + try: + y = self.bld.get_tgen_by_name(name) + except Errors.WafError: + self.uselib.append(name) + return + else: + y.post() + # Add generated JAR name for CLASSPATH. Task ordering (set_run_after) + # is already guaranteed by ordering done between the single tasks + if hasattr(y, 'jar_task'): + self.use_lst.append(y.jar_task.outputs[0].abspath()) + else: + if hasattr(y,'outdir'): + self.use_lst.append(y.outdir.abspath()) + else: + self.use_lst.append(y.path.get_bld().abspath()) + + for x in self.to_list(getattr(y, 'use', [])): + self.java_use_rec(x) + +@feature('javac') +@before_method('propagate_uselib_vars') +@after_method('apply_java') +def use_javac_files(self): + """ + Processes the *use* attribute referring to other java compilations + """ + self.use_lst = [] + self.tmp_use_seen = [] + self.uselib = self.to_list(getattr(self, 'uselib', [])) + names = self.to_list(getattr(self, 'use', [])) + get = self.bld.get_tgen_by_name + for x in names: + try: + tg = get(x) + except Errors.WafError: + self.uselib.append(x) + else: + tg.post() + if hasattr(tg, 'jar_task'): + self.use_lst.append(tg.jar_task.outputs[0].abspath()) + self.javac_task.set_run_after(tg.jar_task) + self.javac_task.dep_nodes.extend(tg.jar_task.outputs) + else: + if hasattr(tg, 'outdir'): + base_node = tg.outdir + else: + base_node = tg.path.get_bld() + + self.use_lst.append(base_node.abspath()) + self.javac_task.dep_nodes.extend([x for x in base_node.ant_glob(JAR_RE, remove=False, quiet=True)]) + + for tsk in tg.tasks: + self.javac_task.set_run_after(tsk) + + # If recurse use scan is enabled recursively add use attribute for each used one + if getattr(self, 'recurse_use', False) or self.bld.env.RECURSE_JAVA: + self.java_use_rec(x) + + self.env.append_value('CLASSPATH', self.use_lst) + +@feature('javac') +@after_method('apply_java', 'propagate_uselib_vars', 'use_javac_files') +def set_classpath(self): + """ + Sets the CLASSPATH value on the *javac* task previously created. + """ + if getattr(self, 'classpath', None): + self.env.append_unique('CLASSPATH', getattr(self, 'classpath', [])) + for x in self.tasks: + x.env.CLASSPATH = os.pathsep.join(self.env.CLASSPATH) + os.pathsep + +@feature('jar') +@after_method('apply_java', 'use_javac_files') +@before_method('process_source') +def jar_files(self): + """ + Creates a jar task (one maximum per task generator) + """ + destfile = getattr(self, 'destfile', 'test.jar') + jaropts = getattr(self, 'jaropts', []) + manifest = getattr(self, 'manifest', None) + + basedir = getattr(self, 'basedir', None) + if basedir: + if not isinstance(self.basedir, Node.Node): + basedir = self.path.get_bld().make_node(basedir) + else: + basedir = self.path.get_bld() + if not basedir: + self.bld.fatal('Could not find the basedir %r for %r' % (self.basedir, self)) + + self.jar_task = tsk = self.create_task('jar_create') + if manifest: + jarcreate = getattr(self, 'jarcreate', 'cfm') + if not isinstance(manifest,Node.Node): + node = self.path.find_resource(manifest) + else: + node = manifest + if not node: + self.bld.fatal('invalid manifest file %r for %r' % (manifest, self)) + tsk.dep_nodes.append(node) + jaropts.insert(0, node.abspath()) + else: + jarcreate = getattr(self, 'jarcreate', 'cf') + if not isinstance(destfile, Node.Node): + destfile = self.path.find_or_declare(destfile) + if not destfile: + self.bld.fatal('invalid destfile %r for %r' % (destfile, self)) + tsk.set_outputs(destfile) + tsk.basedir = basedir + + jaropts.append('-C') + jaropts.append(basedir.bldpath()) + jaropts.append('.') + + tsk.env.JAROPTS = jaropts + tsk.env.JARCREATE = jarcreate + + if getattr(self, 'javac_task', None): + tsk.set_run_after(self.javac_task) + +@feature('jar') +@after_method('jar_files') +def use_jar_files(self): + """ + Processes the *use* attribute to set the build order on the + tasks created by another task generator. + """ + self.uselib = self.to_list(getattr(self, 'uselib', [])) + names = self.to_list(getattr(self, 'use', [])) + get = self.bld.get_tgen_by_name + for x in names: + try: + y = get(x) + except Errors.WafError: + self.uselib.append(x) + else: + y.post() + self.jar_task.run_after.update(y.tasks) + +class JTask(Task.Task): + """ + Base class for java and jar tasks; provides functionality to run long commands + """ + def split_argfile(self, cmd): + inline = [cmd[0]] + infile = [] + for x in cmd[1:]: + # jar and javac do not want -J flags in @file + if x.startswith('-J'): + inline.append(x) + else: + infile.append(self.quote_flag(x)) + return (inline, infile) + +class jar_create(JTask): + """ + Creates a jar file + """ + color = 'GREEN' + run_str = '${JAR} ${JARCREATE} ${TGT} ${JAROPTS}' + + def runnable_status(self): + """ + Wait for dependent tasks to be executed, then read the + files to update the list of inputs. + """ + for t in self.run_after: + if not t.hasrun: + return Task.ASK_LATER + if not self.inputs: + try: + self.inputs = [x for x in self.basedir.ant_glob(JAR_RE, remove=False, quiet=True) if id(x) != id(self.outputs[0])] + except Exception: + raise Errors.WafError('Could not find the basedir %r for %r' % (self.basedir, self)) + return super(jar_create, self).runnable_status() + +class javac(JTask): + """ + Compiles java files + """ + color = 'BLUE' + run_str = '${JAVAC} -classpath ${CLASSPATH} -d ${OUTDIR} ${JAVACFLAGS} ${SRC}' + vars = ['CLASSPATH', 'JAVACFLAGS', 'JAVAC', 'OUTDIR'] + """ + The javac task will be executed again if the variables CLASSPATH, JAVACFLAGS, JAVAC or OUTDIR change. + """ + def uid(self): + """Identify java tasks by input&output folder""" + lst = [self.__class__.__name__, self.generator.outdir.abspath()] + for x in self.srcdir: + lst.append(x.abspath()) + return Utils.h_list(lst) + + def runnable_status(self): + """ + Waits for dependent tasks to be complete, then read the file system to find the input nodes. + """ + for t in self.run_after: + if not t.hasrun: + return Task.ASK_LATER + + if not self.inputs: + self.inputs = [] + for x in self.srcdir: + if x.exists(): + self.inputs.extend(x.ant_glob(SOURCE_RE, remove=False, quiet=True)) + return super(javac, self).runnable_status() + + def post_run(self): + """ + List class files created + """ + for node in self.generator.outdir.ant_glob('**/*.class', quiet=True): + self.generator.bld.node_sigs[node] = self.uid() + self.generator.bld.task_sigs[self.uid()] = self.cache_sig + +@feature('javadoc') +@after_method('process_rule') +def create_javadoc(self): + """ + Creates a javadoc task (feature 'javadoc') + """ + tsk = self.create_task('javadoc') + tsk.classpath = getattr(self, 'classpath', []) + self.javadoc_package = Utils.to_list(self.javadoc_package) + if not isinstance(self.javadoc_output, Node.Node): + self.javadoc_output = self.bld.path.find_or_declare(self.javadoc_output) + +class javadoc(Task.Task): + """ + Builds java documentation + """ + color = 'BLUE' + + def __str__(self): + return '%s: %s -> %s\n' % (self.__class__.__name__, self.generator.srcdir, self.generator.javadoc_output) + + def run(self): + env = self.env + bld = self.generator.bld + wd = bld.bldnode + + #add src node + bld node (for generated java code) + srcpath = self.generator.path.abspath() + os.sep + self.generator.srcdir + srcpath += os.pathsep + srcpath += self.generator.path.get_bld().abspath() + os.sep + self.generator.srcdir + + classpath = env.CLASSPATH + classpath += os.pathsep + classpath += os.pathsep.join(self.classpath) + classpath = "".join(classpath) + + self.last_cmd = lst = [] + lst.extend(Utils.to_list(env.JAVADOC)) + lst.extend(['-d', self.generator.javadoc_output.abspath()]) + lst.extend(['-sourcepath', srcpath]) + lst.extend(['-classpath', classpath]) + lst.extend(['-subpackages']) + lst.extend(self.generator.javadoc_package) + lst = [x for x in lst if x] + + self.generator.bld.cmd_and_log(lst, cwd=wd, env=env.env or None, quiet=0) + + def post_run(self): + nodes = self.generator.javadoc_output.ant_glob('**', quiet=True) + for node in nodes: + self.generator.bld.node_sigs[node] = self.uid() + self.generator.bld.task_sigs[self.uid()] = self.cache_sig + +def configure(self): + """ + Detects the javac, java and jar programs + """ + # If JAVA_PATH is set, we prepend it to the path list + java_path = self.environ['PATH'].split(os.pathsep) + v = self.env + + if 'JAVA_HOME' in self.environ: + java_path = [os.path.join(self.environ['JAVA_HOME'], 'bin')] + java_path + self.env.JAVA_HOME = [self.environ['JAVA_HOME']] + + for x in 'javac java jar javadoc'.split(): + self.find_program(x, var=x.upper(), path_list=java_path, mandatory=(x not in ('javadoc'))) + + if 'CLASSPATH' in self.environ: + v.CLASSPATH = self.environ['CLASSPATH'] + + if not v.JAR: + self.fatal('jar is required for making java packages') + if not v.JAVAC: + self.fatal('javac is required for compiling java classes') + + v.JARCREATE = 'cf' # can use cvf + v.JAVACFLAGS = [] + +@conf +def check_java_class(self, classname, with_classpath=None): + """ + Checks if the specified java class exists + + :param classname: class to check, like java.util.HashMap + :type classname: string + :param with_classpath: additional classpath to give + :type with_classpath: string + """ + javatestdir = '.waf-javatest' + + classpath = javatestdir + if self.env.CLASSPATH: + classpath += os.pathsep + self.env.CLASSPATH + if isinstance(with_classpath, str): + classpath += os.pathsep + with_classpath + + shutil.rmtree(javatestdir, True) + os.mkdir(javatestdir) + + Utils.writef(os.path.join(javatestdir, 'Test.java'), class_check_source) + + # Compile the source + self.exec_command(self.env.JAVAC + [os.path.join(javatestdir, 'Test.java')], shell=False) + + # Try to run the app + cmd = self.env.JAVA + ['-cp', classpath, 'Test', classname] + self.to_log("%s\n" % str(cmd)) + found = self.exec_command(cmd, shell=False) + + self.msg('Checking for java class %s' % classname, not found) + + shutil.rmtree(javatestdir, True) + + return found + +@conf +def check_jni_headers(conf): + """ + Checks for jni headers and libraries. On success the conf.env variables xxx_JAVA are added for use in C/C++ targets:: + + def options(opt): + opt.load('compiler_c') + + def configure(conf): + conf.load('compiler_c java') + conf.check_jni_headers() + + def build(bld): + bld.shlib(source='a.c', target='app', use='JAVA') + """ + if not conf.env.CC_NAME and not conf.env.CXX_NAME: + conf.fatal('load a compiler first (gcc, g++, ..)') + + if not conf.env.JAVA_HOME: + conf.fatal('set JAVA_HOME in the system environment') + + # jni requires the jvm + javaHome = conf.env.JAVA_HOME[0] + + dir = conf.root.find_dir(conf.env.JAVA_HOME[0] + '/include') + if dir is None: + dir = conf.root.find_dir(conf.env.JAVA_HOME[0] + '/../Headers') # think different?! + if dir is None: + conf.fatal('JAVA_HOME does not seem to be set properly') + + f = dir.ant_glob('**/(jni|jni_md).h') + incDirs = [x.parent.abspath() for x in f] + + dir = conf.root.find_dir(conf.env.JAVA_HOME[0]) + f = dir.ant_glob('**/*jvm.(so|dll|dylib)') + libDirs = [x.parent.abspath() for x in f] or [javaHome] + + # On windows, we need both the .dll and .lib to link. On my JDK, they are + # in different directories... + f = dir.ant_glob('**/*jvm.(lib)') + if f: + libDirs = [[x, y.parent.abspath()] for x in libDirs for y in f] + + if conf.env.DEST_OS == 'freebsd': + conf.env.append_unique('LINKFLAGS_JAVA', '-pthread') + for d in libDirs: + try: + conf.check(header_name='jni.h', define_name='HAVE_JNI_H', lib='jvm', + libpath=d, includes=incDirs, uselib_store='JAVA', uselib='JAVA') + except Exception: + pass + else: + break + else: + conf.fatal('could not find lib jvm in %r (see config.log)' % libDirs) + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/ldc2.py b/ldb-2.0.8/third_party/waf/waflib/Tools/ldc2.py new file mode 100644 index 0000000..a51c344 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/ldc2.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Alex Rønne Petersen, 2012 (alexrp/Zor) + +from waflib.Tools import ar, d +from waflib.Configure import conf + +@conf +def find_ldc2(conf): + """ + Finds the program *ldc2* and set the variable *D* + """ + conf.find_program(['ldc2'], var='D') + + out = conf.cmd_and_log(conf.env.D + ['-version']) + if out.find("based on DMD v2.") == -1: + conf.fatal("detected compiler is not ldc2") + +@conf +def common_flags_ldc2(conf): + """ + Sets the D flags required by *ldc2* + """ + v = conf.env + + v.D_SRC_F = ['-c'] + v.D_TGT_F = '-of%s' + + v.D_LINKER = v.D + v.DLNK_SRC_F = '' + v.DLNK_TGT_F = '-of%s' + v.DINC_ST = '-I%s' + + v.DSHLIB_MARKER = v.DSTLIB_MARKER = '' + v.DSTLIB_ST = v.DSHLIB_ST = '-L-l%s' + v.DSTLIBPATH_ST = v.DLIBPATH_ST = '-L-L%s' + + v.LINKFLAGS_dshlib = ['-L-shared'] + + v.DHEADER_ext = '.di' + v.DFLAGS_d_with_header = ['-H', '-Hf'] + v.D_HDR_F = '%s' + + v.LINKFLAGS = [] + v.DFLAGS_dshlib = ['-relocation-model=pic'] + +def configure(conf): + """ + Configuration for *ldc2* + """ + conf.find_ldc2() + conf.load('ar') + conf.load('d') + conf.common_flags_ldc2() + conf.d_platform_flags() + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/lua.py b/ldb-2.0.8/third_party/waf/waflib/Tools/lua.py new file mode 100644 index 0000000..15a333a --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/lua.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Sebastian Schlingmann, 2008 +# Thomas Nagy, 2008-2018 (ita) + +""" +Lua support. + +Compile *.lua* files into *.luac*:: + + def configure(conf): + conf.load('lua') + conf.env.LUADIR = '/usr/local/share/myapp/scripts/' + def build(bld): + bld(source='foo.lua') +""" + +from waflib.TaskGen import extension +from waflib import Task + +@extension('.lua') +def add_lua(self, node): + tsk = self.create_task('luac', node, node.change_ext('.luac')) + inst_to = getattr(self, 'install_path', self.env.LUADIR and '${LUADIR}' or None) + if inst_to: + self.add_install_files(install_to=inst_to, install_from=tsk.outputs) + return tsk + +class luac(Task.Task): + run_str = '${LUAC} -s -o ${TGT} ${SRC}' + color = 'PINK' + +def configure(conf): + """ + Detect the luac compiler and set *conf.env.LUAC* + """ + conf.find_program('luac', var='LUAC') + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/md5_tstamp.py b/ldb-2.0.8/third_party/waf/waflib/Tools/md5_tstamp.py new file mode 100644 index 0000000..d1569fa --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/md5_tstamp.py @@ -0,0 +1,41 @@ +#! /usr/bin/env python +# encoding: utf-8 + +""" +Re-calculate md5 hashes of files only when the file time have changed:: + + def options(opt): + opt.load('md5_tstamp') + +The hashes can also reflect either the file contents (STRONGEST=True) or the +file time and file size. + +The performance benefits of this module are usually insignificant. +""" + +import os, stat +from waflib import Utils, Build, Node + +STRONGEST = True + +Build.SAVED_ATTRS.append('hashes_md5_tstamp') +def h_file(self): + filename = self.abspath() + st = os.stat(filename) + + cache = self.ctx.hashes_md5_tstamp + if filename in cache and cache[filename][0] == st.st_mtime: + return cache[filename][1] + + if STRONGEST: + ret = Utils.h_file(filename) + else: + if stat.S_ISDIR(st[stat.ST_MODE]): + raise IOError('Not a file') + ret = Utils.md5(str((st.st_mtime, st.st_size)).encode()).digest() + + cache[filename] = (st.st_mtime, ret) + return ret +h_file.__doc__ = Node.Node.h_file.__doc__ +Node.Node.h_file = h_file + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/msvc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/msvc.py new file mode 100644 index 0000000..f169c7f --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/msvc.py @@ -0,0 +1,1020 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Carlos Rafael Giani, 2006 (dv) +# Tamas Pal, 2007 (folti) +# Nicolas Mercier, 2009 +# Matt Clarkson, 2012 + +""" +Microsoft Visual C++/Intel C++ compiler support + +If you get detection problems, first try any of the following:: + + chcp 65001 + set PYTHONIOENCODING=... + set PYTHONLEGACYWINDOWSSTDIO=1 + +Usage:: + + $ waf configure --msvc_version="msvc 10.0,msvc 9.0" --msvc_target="x64" + +or:: + + def configure(conf): + conf.env.MSVC_VERSIONS = ['msvc 10.0', 'msvc 9.0', 'msvc 8.0', 'msvc 7.1', 'msvc 7.0', 'msvc 6.0', 'wsdk 7.0', 'intel 11', 'PocketPC 9.0', 'Smartphone 8.0'] + conf.env.MSVC_TARGETS = ['x64'] + conf.load('msvc') + +or:: + + def configure(conf): + conf.load('msvc', funs='no_autodetect') + conf.check_lib_msvc('gdi32') + conf.check_libs_msvc('kernel32 user32') + def build(bld): + tg = bld.program(source='main.c', target='app', use='KERNEL32 USER32 GDI32') + +Platforms and targets will be tested in the order they appear; +the first good configuration will be used. + +To force testing all the configurations that are not used, use the ``--no-msvc-lazy`` option +or set ``conf.env.MSVC_LAZY_AUTODETECT=False``. + +Supported platforms: ia64, x64, x86, x86_amd64, x86_ia64, x86_arm, amd64_x86, amd64_arm + +Compilers supported: + +* msvc => Visual Studio, versions 6.0 (VC 98, VC .NET 2002) to 15 (Visual Studio 2017) +* wsdk => Windows SDK, versions 6.0, 6.1, 7.0, 7.1, 8.0 +* icl => Intel compiler, versions 9, 10, 11, 13 +* winphone => Visual Studio to target Windows Phone 8 native (version 8.0 for now) +* Smartphone => Compiler/SDK for Smartphone devices (armv4/v4i) +* PocketPC => Compiler/SDK for PocketPC devices (armv4/v4i) + +To use WAF in a VS2008 Make file project (see http://code.google.com/p/waf/issues/detail?id=894) +You may consider to set the environment variable "VS_UNICODE_OUTPUT" to nothing before calling waf. +So in your project settings use something like 'cmd.exe /C "set VS_UNICODE_OUTPUT=& set PYTHONUNBUFFERED=true & waf build"'. +cmd.exe /C "chcp 1252 & set PYTHONUNBUFFERED=true && set && waf configure" +Setting PYTHONUNBUFFERED gives the unbuffered output. +""" + +import os, sys, re, traceback +from waflib import Utils, Logs, Options, Errors +from waflib.TaskGen import after_method, feature + +from waflib.Configure import conf +from waflib.Tools import ccroot, c, cxx, ar + +g_msvc_systemlibs = ''' +aclui activeds ad1 adptif adsiid advapi32 asycfilt authz bhsupp bits bufferoverflowu cabinet +cap certadm certidl ciuuid clusapi comctl32 comdlg32 comsupp comsuppd comsuppw comsuppwd comsvcs +credui crypt32 cryptnet cryptui d3d8thk daouuid dbgeng dbghelp dciman32 ddao35 ddao35d +ddao35u ddao35ud delayimp dhcpcsvc dhcpsapi dlcapi dnsapi dsprop dsuiext dtchelp +faultrep fcachdll fci fdi framedyd framedyn gdi32 gdiplus glauxglu32 gpedit gpmuuid +gtrts32w gtrtst32hlink htmlhelp httpapi icm32 icmui imagehlp imm32 iphlpapi iprop +kernel32 ksguid ksproxy ksuser libcmt libcmtd libcpmt libcpmtd loadperf lz32 mapi +mapi32 mgmtapi minidump mmc mobsync mpr mprapi mqoa mqrt msacm32 mscms mscoree +msdasc msimg32 msrating mstask msvcmrt msvcurt msvcurtd mswsock msxml2 mtx mtxdm +netapi32 nmapinmsupp npptools ntdsapi ntdsbcli ntmsapi ntquery odbc32 odbcbcp +odbccp32 oldnames ole32 oleacc oleaut32 oledb oledlgolepro32 opends60 opengl32 +osptk parser pdh penter pgobootrun pgort powrprof psapi ptrustm ptrustmd ptrustu +ptrustud qosname rasapi32 rasdlg rassapi resutils riched20 rpcndr rpcns4 rpcrt4 rtm +rtutils runtmchk scarddlg scrnsave scrnsavw secur32 sensapi setupapi sfc shell32 +shfolder shlwapi sisbkup snmpapi sporder srclient sti strsafe svcguid tapi32 thunk32 +traffic unicows url urlmon user32 userenv usp10 uuid uxtheme vcomp vcompd vdmdbg +version vfw32 wbemuuid webpost wiaguid wininet winmm winscard winspool winstrm +wintrust wldap32 wmiutils wow32 ws2_32 wsnmp32 wsock32 wst wtsapi32 xaswitch xolehlp +'''.split() +"""importlibs provided by MSVC/Platform SDK. Do NOT search them""" + +all_msvc_platforms = [ ('x64', 'amd64'), ('x86', 'x86'), ('ia64', 'ia64'), + ('x86_amd64', 'amd64'), ('x86_ia64', 'ia64'), ('x86_arm', 'arm'), ('x86_arm64', 'arm64'), + ('amd64_x86', 'x86'), ('amd64_arm', 'arm'), ('amd64_arm64', 'arm64') ] +"""List of msvc platforms""" + +all_wince_platforms = [ ('armv4', 'arm'), ('armv4i', 'arm'), ('mipsii', 'mips'), ('mipsii_fp', 'mips'), ('mipsiv', 'mips'), ('mipsiv_fp', 'mips'), ('sh4', 'sh'), ('x86', 'cex86') ] +"""List of wince platforms""" + +all_icl_platforms = [ ('intel64', 'amd64'), ('em64t', 'amd64'), ('ia32', 'x86'), ('Itanium', 'ia64')] +"""List of icl platforms""" + +def options(opt): + opt.add_option('--msvc_version', type='string', help = 'msvc version, eg: "msvc 10.0,msvc 9.0"', default='') + opt.add_option('--msvc_targets', type='string', help = 'msvc targets, eg: "x64,arm"', default='') + opt.add_option('--no-msvc-lazy', action='store_false', help = 'lazily check msvc target environments', default=True, dest='msvc_lazy') + +@conf +def setup_msvc(conf, versiondict): + """ + Checks installed compilers and targets and returns the first combination from the user's + options, env, or the global supported lists that checks. + + :param versiondict: dict(platform -> dict(architecture -> configuration)) + :type versiondict: dict(string -> dict(string -> target_compiler) + :return: the compiler, revision, path, include dirs, library paths and target architecture + :rtype: tuple of strings + """ + platforms = getattr(Options.options, 'msvc_targets', '').split(',') + if platforms == ['']: + platforms=Utils.to_list(conf.env.MSVC_TARGETS) or [i for i,j in all_msvc_platforms+all_icl_platforms+all_wince_platforms] + desired_versions = getattr(Options.options, 'msvc_version', '').split(',') + if desired_versions == ['']: + desired_versions = conf.env.MSVC_VERSIONS or list(reversed(sorted(versiondict.keys()))) + + # Override lazy detection by evaluating after the fact. + lazy_detect = getattr(Options.options, 'msvc_lazy', True) + if conf.env.MSVC_LAZY_AUTODETECT is False: + lazy_detect = False + + if not lazy_detect: + for val in versiondict.values(): + for arch in list(val.keys()): + cfg = val[arch] + cfg.evaluate() + if not cfg.is_valid: + del val[arch] + conf.env.MSVC_INSTALLED_VERSIONS = versiondict + + for version in desired_versions: + Logs.debug('msvc: detecting %r - %r', version, desired_versions) + try: + targets = versiondict[version] + except KeyError: + continue + + seen = set() + for arch in platforms: + if arch in seen: + continue + else: + seen.add(arch) + try: + cfg = targets[arch] + except KeyError: + continue + + cfg.evaluate() + if cfg.is_valid: + compiler,revision = version.rsplit(' ', 1) + return compiler,revision,cfg.bindirs,cfg.incdirs,cfg.libdirs,cfg.cpu + conf.fatal('msvc: Impossible to find a valid architecture for building %r - %r' % (desired_versions, list(versiondict.keys()))) + +@conf +def get_msvc_version(conf, compiler, version, target, vcvars): + """ + Checks that an installed compiler actually runs and uses vcvars to obtain the + environment needed by the compiler. + + :param compiler: compiler type, for looking up the executable name + :param version: compiler version, for debugging only + :param target: target architecture + :param vcvars: batch file to run to check the environment + :return: the location of the compiler executable, the location of include dirs, and the library paths + :rtype: tuple of strings + """ + Logs.debug('msvc: get_msvc_version: %r %r %r', compiler, version, target) + + try: + conf.msvc_cnt += 1 + except AttributeError: + conf.msvc_cnt = 1 + batfile = conf.bldnode.make_node('waf-print-msvc-%d.bat' % conf.msvc_cnt) + batfile.write("""@echo off +set INCLUDE= +set LIB= +call "%s" %s +echo PATH=%%PATH%% +echo INCLUDE=%%INCLUDE%% +echo LIB=%%LIB%%;%%LIBPATH%% +""" % (vcvars,target)) + sout = conf.cmd_and_log(['cmd.exe', '/E:on', '/V:on', '/C', batfile.abspath()]) + lines = sout.splitlines() + + if not lines[0]: + lines.pop(0) + + MSVC_PATH = MSVC_INCDIR = MSVC_LIBDIR = None + for line in lines: + if line.startswith('PATH='): + path = line[5:] + MSVC_PATH = path.split(';') + elif line.startswith('INCLUDE='): + MSVC_INCDIR = [i for i in line[8:].split(';') if i] + elif line.startswith('LIB='): + MSVC_LIBDIR = [i for i in line[4:].split(';') if i] + if None in (MSVC_PATH, MSVC_INCDIR, MSVC_LIBDIR): + conf.fatal('msvc: Could not find a valid architecture for building (get_msvc_version_3)') + + # Check if the compiler is usable at all. + # The detection may return 64-bit versions even on 32-bit systems, and these would fail to run. + env = dict(os.environ) + env.update(PATH = path) + compiler_name, linker_name, lib_name = _get_prog_names(conf, compiler) + cxx = conf.find_program(compiler_name, path_list=MSVC_PATH) + + # delete CL if exists. because it could contain parameters which can change cl's behaviour rather catastrophically. + if 'CL' in env: + del(env['CL']) + + try: + conf.cmd_and_log(cxx + ['/help'], env=env) + except UnicodeError: + st = traceback.format_exc() + if conf.logger: + conf.logger.error(st) + conf.fatal('msvc: Unicode error - check the code page?') + except Exception as e: + Logs.debug('msvc: get_msvc_version: %r %r %r -> failure %s', compiler, version, target, str(e)) + conf.fatal('msvc: cannot run the compiler in get_msvc_version (run with -v to display errors)') + else: + Logs.debug('msvc: get_msvc_version: %r %r %r -> OK', compiler, version, target) + finally: + conf.env[compiler_name] = '' + + return (MSVC_PATH, MSVC_INCDIR, MSVC_LIBDIR) + +def gather_wince_supported_platforms(): + """ + Checks SmartPhones SDKs + + :param versions: list to modify + :type versions: list + """ + supported_wince_platforms = [] + try: + ce_sdk = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Microsoft\\Windows CE Tools\\SDKs') + except OSError: + try: + ce_sdk = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Microsoft\\Windows CE Tools\\SDKs') + except OSError: + ce_sdk = '' + if not ce_sdk: + return supported_wince_platforms + + index = 0 + while 1: + try: + sdk_device = Utils.winreg.EnumKey(ce_sdk, index) + sdk = Utils.winreg.OpenKey(ce_sdk, sdk_device) + except OSError: + break + index += 1 + try: + path,type = Utils.winreg.QueryValueEx(sdk, 'SDKRootDir') + except OSError: + try: + path,type = Utils.winreg.QueryValueEx(sdk,'SDKInformation') + except OSError: + continue + path,xml = os.path.split(path) + path = str(path) + path,device = os.path.split(path) + if not device: + path,device = os.path.split(path) + platforms = [] + for arch,compiler in all_wince_platforms: + if os.path.isdir(os.path.join(path, device, 'Lib', arch)): + platforms.append((arch, compiler, os.path.join(path, device, 'Include', arch), os.path.join(path, device, 'Lib', arch))) + if platforms: + supported_wince_platforms.append((device, platforms)) + return supported_wince_platforms + +def gather_msvc_detected_versions(): + #Detected MSVC versions! + version_pattern = re.compile(r'^(\d\d?\.\d\d?)(Exp)?$') + detected_versions = [] + for vcver,vcvar in (('VCExpress','Exp'), ('VisualStudio','')): + prefix = 'SOFTWARE\\Wow6432node\\Microsoft\\' + vcver + try: + all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, prefix) + except OSError: + prefix = 'SOFTWARE\\Microsoft\\' + vcver + try: + all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, prefix) + except OSError: + continue + + index = 0 + while 1: + try: + version = Utils.winreg.EnumKey(all_versions, index) + except OSError: + break + index += 1 + match = version_pattern.match(version) + if match: + versionnumber = float(match.group(1)) + else: + continue + detected_versions.append((versionnumber, version+vcvar, prefix+'\\'+version)) + def fun(tup): + return tup[0] + + detected_versions.sort(key = fun) + return detected_versions + +class target_compiler(object): + """ + Wrap a compiler configuration; call evaluate() to determine + whether the configuration is usable. + """ + def __init__(self, ctx, compiler, cpu, version, bat_target, bat, callback=None): + """ + :param ctx: configuration context to use to eventually get the version environment + :param compiler: compiler name + :param cpu: target cpu + :param version: compiler version number + :param bat_target: ? + :param bat: path to the batch file to run + """ + self.conf = ctx + self.name = None + self.is_valid = False + self.is_done = False + + self.compiler = compiler + self.cpu = cpu + self.version = version + self.bat_target = bat_target + self.bat = bat + self.callback = callback + + def evaluate(self): + if self.is_done: + return + self.is_done = True + try: + vs = self.conf.get_msvc_version(self.compiler, self.version, self.bat_target, self.bat) + except Errors.ConfigurationError: + self.is_valid = False + return + if self.callback: + vs = self.callback(self, vs) + self.is_valid = True + (self.bindirs, self.incdirs, self.libdirs) = vs + + def __str__(self): + return str((self.compiler, self.cpu, self.version, self.bat_target, self.bat)) + + def __repr__(self): + return repr((self.compiler, self.cpu, self.version, self.bat_target, self.bat)) + +@conf +def gather_wsdk_versions(conf, versions): + """ + Use winreg to add the msvc versions to the input list + + :param versions: list to modify + :type versions: list + """ + version_pattern = re.compile(r'^v..?.?\...?.?') + try: + all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Microsoft\\Microsoft SDKs\\Windows') + except OSError: + try: + all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows') + except OSError: + return + index = 0 + while 1: + try: + version = Utils.winreg.EnumKey(all_versions, index) + except OSError: + break + index += 1 + if not version_pattern.match(version): + continue + try: + msvc_version = Utils.winreg.OpenKey(all_versions, version) + path,type = Utils.winreg.QueryValueEx(msvc_version,'InstallationFolder') + except OSError: + continue + if path and os.path.isfile(os.path.join(path, 'bin', 'SetEnv.cmd')): + targets = {} + for target,arch in all_msvc_platforms: + targets[target] = target_compiler(conf, 'wsdk', arch, version, '/'+target, os.path.join(path, 'bin', 'SetEnv.cmd')) + versions['wsdk ' + version[1:]] = targets + +@conf +def gather_msvc_targets(conf, versions, version, vc_path): + #Looking for normal MSVC compilers! + targets = {} + + if os.path.isfile(os.path.join(vc_path, 'VC', 'Auxiliary', 'Build', 'vcvarsall.bat')): + for target,realtarget in all_msvc_platforms[::-1]: + targets[target] = target_compiler(conf, 'msvc', realtarget, version, target, os.path.join(vc_path, 'VC', 'Auxiliary', 'Build', 'vcvarsall.bat')) + elif os.path.isfile(os.path.join(vc_path, 'vcvarsall.bat')): + for target,realtarget in all_msvc_platforms[::-1]: + targets[target] = target_compiler(conf, 'msvc', realtarget, version, target, os.path.join(vc_path, 'vcvarsall.bat')) + elif os.path.isfile(os.path.join(vc_path, 'Common7', 'Tools', 'vsvars32.bat')): + targets['x86'] = target_compiler(conf, 'msvc', 'x86', version, 'x86', os.path.join(vc_path, 'Common7', 'Tools', 'vsvars32.bat')) + elif os.path.isfile(os.path.join(vc_path, 'Bin', 'vcvars32.bat')): + targets['x86'] = target_compiler(conf, 'msvc', 'x86', version, '', os.path.join(vc_path, 'Bin', 'vcvars32.bat')) + if targets: + versions['msvc %s' % version] = targets + +@conf +def gather_wince_targets(conf, versions, version, vc_path, vsvars, supported_platforms): + #Looking for Win CE compilers! + for device,platforms in supported_platforms: + targets = {} + for platform,compiler,include,lib in platforms: + winCEpath = os.path.join(vc_path, 'ce') + if not os.path.isdir(winCEpath): + continue + + if os.path.isdir(os.path.join(winCEpath, 'lib', platform)): + bindirs = [os.path.join(winCEpath, 'bin', compiler), os.path.join(winCEpath, 'bin', 'x86_'+compiler)] + incdirs = [os.path.join(winCEpath, 'include'), os.path.join(winCEpath, 'atlmfc', 'include'), include] + libdirs = [os.path.join(winCEpath, 'lib', platform), os.path.join(winCEpath, 'atlmfc', 'lib', platform), lib] + def combine_common(obj, compiler_env): + # TODO this is likely broken, remove in waf 2.1 + (common_bindirs,_1,_2) = compiler_env + return (bindirs + common_bindirs, incdirs, libdirs) + targets[platform] = target_compiler(conf, 'msvc', platform, version, 'x86', vsvars, combine_common) + if targets: + versions[device + ' ' + version] = targets + +@conf +def gather_winphone_targets(conf, versions, version, vc_path, vsvars): + #Looking for WinPhone compilers + targets = {} + for target,realtarget in all_msvc_platforms[::-1]: + targets[target] = target_compiler(conf, 'winphone', realtarget, version, target, vsvars) + if targets: + versions['winphone ' + version] = targets + +@conf +def gather_vswhere_versions(conf, versions): + try: + import json + except ImportError: + Logs.error('Visual Studio 2017 detection requires Python 2.6') + return + + prg_path = os.environ.get('ProgramFiles(x86)', os.environ.get('ProgramFiles', 'C:\\Program Files (x86)')) + + vswhere = os.path.join(prg_path, 'Microsoft Visual Studio', 'Installer', 'vswhere.exe') + args = [vswhere, '-products', '*', '-legacy', '-format', 'json'] + try: + txt = conf.cmd_and_log(args) + except Errors.WafError as e: + Logs.debug('msvc: vswhere.exe failed %s', e) + return + + if sys.version_info[0] < 3: + txt = txt.decode(Utils.console_encoding()) + + arr = json.loads(txt) + arr.sort(key=lambda x: x['installationVersion']) + for entry in arr: + ver = entry['installationVersion'] + ver = str('.'.join(ver.split('.')[:2])) + path = str(os.path.abspath(entry['installationPath'])) + if os.path.exists(path) and ('msvc %s' % ver) not in versions: + conf.gather_msvc_targets(versions, ver, path) + +@conf +def gather_msvc_versions(conf, versions): + vc_paths = [] + for (v,version,reg) in gather_msvc_detected_versions(): + try: + try: + msvc_version = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, reg + "\\Setup\\VC") + except OSError: + msvc_version = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, reg + "\\Setup\\Microsoft Visual C++") + path,type = Utils.winreg.QueryValueEx(msvc_version, 'ProductDir') + except OSError: + try: + msvc_version = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Wow6432node\\Microsoft\\VisualStudio\\SxS\\VS7") + path,type = Utils.winreg.QueryValueEx(msvc_version, version) + except OSError: + continue + else: + vc_paths.append((version, os.path.abspath(str(path)))) + continue + else: + vc_paths.append((version, os.path.abspath(str(path)))) + + wince_supported_platforms = gather_wince_supported_platforms() + + for version,vc_path in vc_paths: + vs_path = os.path.dirname(vc_path) + vsvars = os.path.join(vs_path, 'Common7', 'Tools', 'vsvars32.bat') + if wince_supported_platforms and os.path.isfile(vsvars): + conf.gather_wince_targets(versions, version, vc_path, vsvars, wince_supported_platforms) + + # WP80 works with 11.0Exp and 11.0, both of which resolve to the same vc_path. + # Stop after one is found. + for version,vc_path in vc_paths: + vs_path = os.path.dirname(vc_path) + vsvars = os.path.join(vs_path, 'VC', 'WPSDK', 'WP80', 'vcvarsphoneall.bat') + if os.path.isfile(vsvars): + conf.gather_winphone_targets(versions, '8.0', vc_path, vsvars) + break + + for version,vc_path in vc_paths: + vs_path = os.path.dirname(vc_path) + conf.gather_msvc_targets(versions, version, vc_path) + +@conf +def gather_icl_versions(conf, versions): + """ + Checks ICL compilers + + :param versions: list to modify + :type versions: list + """ + version_pattern = re.compile(r'^...?.?\....?.?') + try: + all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Intel\\Compilers\\C++') + except OSError: + try: + all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Intel\\Compilers\\C++') + except OSError: + return + index = 0 + while 1: + try: + version = Utils.winreg.EnumKey(all_versions, index) + except OSError: + break + index += 1 + if not version_pattern.match(version): + continue + targets = {} + for target,arch in all_icl_platforms: + if target=='intel64': + targetDir='EM64T_NATIVE' + else: + targetDir=target + try: + Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir) + icl_version=Utils.winreg.OpenKey(all_versions,version) + path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') + except OSError: + pass + else: + batch_file=os.path.join(path,'bin','iclvars.bat') + if os.path.isfile(batch_file): + targets[target] = target_compiler(conf, 'intel', arch, version, target, batch_file) + for target,arch in all_icl_platforms: + try: + icl_version = Utils.winreg.OpenKey(all_versions, version+'\\'+target) + path,type = Utils.winreg.QueryValueEx(icl_version,'ProductDir') + except OSError: + continue + else: + batch_file=os.path.join(path,'bin','iclvars.bat') + if os.path.isfile(batch_file): + targets[target] = target_compiler(conf, 'intel', arch, version, target, batch_file) + major = version[0:2] + versions['intel ' + major] = targets + +@conf +def gather_intel_composer_versions(conf, versions): + """ + Checks ICL compilers that are part of Intel Composer Suites + + :param versions: list to modify + :type versions: list + """ + version_pattern = re.compile(r'^...?.?\...?.?.?') + try: + all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Intel\\Suites') + except OSError: + try: + all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Intel\\Suites') + except OSError: + return + index = 0 + while 1: + try: + version = Utils.winreg.EnumKey(all_versions, index) + except OSError: + break + index += 1 + if not version_pattern.match(version): + continue + targets = {} + for target,arch in all_icl_platforms: + if target=='intel64': + targetDir='EM64T_NATIVE' + else: + targetDir=target + try: + try: + defaults = Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\'+targetDir) + except OSError: + if targetDir == 'EM64T_NATIVE': + defaults = Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\EM64T') + else: + raise + uid,type = Utils.winreg.QueryValueEx(defaults, 'SubKey') + Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++\\'+targetDir) + icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++') + path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') + except OSError: + pass + else: + batch_file=os.path.join(path,'bin','iclvars.bat') + if os.path.isfile(batch_file): + targets[target] = target_compiler(conf, 'intel', arch, version, target, batch_file) + # The intel compilervar_arch.bat is broken when used with Visual Studio Express 2012 + # http://software.intel.com/en-us/forums/topic/328487 + compilervars_warning_attr = '_compilervars_warning_key' + if version[0:2] == '13' and getattr(conf, compilervars_warning_attr, True): + setattr(conf, compilervars_warning_attr, False) + patch_url = 'http://software.intel.com/en-us/forums/topic/328487' + compilervars_arch = os.path.join(path, 'bin', 'compilervars_arch.bat') + for vscomntool in ('VS110COMNTOOLS', 'VS100COMNTOOLS'): + if vscomntool in os.environ: + vs_express_path = os.environ[vscomntool] + r'..\IDE\VSWinExpress.exe' + dev_env_path = os.environ[vscomntool] + r'..\IDE\devenv.exe' + if (r'if exist "%VS110COMNTOOLS%..\IDE\VSWinExpress.exe"' in Utils.readf(compilervars_arch) and + not os.path.exists(vs_express_path) and not os.path.exists(dev_env_path)): + Logs.warn(('The Intel compilervar_arch.bat only checks for one Visual Studio SKU ' + '(VSWinExpress.exe) but it does not seem to be installed at %r. ' + 'The intel command line set up will fail to configure unless the file %r' + 'is patched. See: %s') % (vs_express_path, compilervars_arch, patch_url)) + major = version[0:2] + versions['intel ' + major] = targets + +@conf +def detect_msvc(self): + return self.setup_msvc(self.get_msvc_versions()) + +@conf +def get_msvc_versions(self): + """ + :return: platform to compiler configurations + :rtype: dict + """ + dct = Utils.ordered_iter_dict() + self.gather_icl_versions(dct) + self.gather_intel_composer_versions(dct) + self.gather_wsdk_versions(dct) + self.gather_msvc_versions(dct) + self.gather_vswhere_versions(dct) + Logs.debug('msvc: detected versions %r', list(dct.keys())) + return dct + +@conf +def find_lt_names_msvc(self, libname, is_static=False): + """ + Win32/MSVC specific code to glean out information from libtool la files. + this function is not attached to the task_gen class. Returns a triplet: + (library absolute path, library name without extension, whether the library is static) + """ + lt_names=[ + 'lib%s.la' % libname, + '%s.la' % libname, + ] + + for path in self.env.LIBPATH: + for la in lt_names: + laf=os.path.join(path,la) + dll=None + if os.path.exists(laf): + ltdict = Utils.read_la_file(laf) + lt_libdir=None + if ltdict.get('libdir', ''): + lt_libdir = ltdict['libdir'] + if not is_static and ltdict.get('library_names', ''): + dllnames=ltdict['library_names'].split() + dll=dllnames[0].lower() + dll=re.sub(r'\.dll$', '', dll) + return (lt_libdir, dll, False) + elif ltdict.get('old_library', ''): + olib=ltdict['old_library'] + if os.path.exists(os.path.join(path,olib)): + return (path, olib, True) + elif lt_libdir != '' and os.path.exists(os.path.join(lt_libdir,olib)): + return (lt_libdir, olib, True) + else: + return (None, olib, True) + else: + raise self.errors.WafError('invalid libtool object file: %s' % laf) + return (None, None, None) + +@conf +def libname_msvc(self, libname, is_static=False): + lib = libname.lower() + lib = re.sub(r'\.lib$','',lib) + + if lib in g_msvc_systemlibs: + return lib + + lib=re.sub('^lib','',lib) + + if lib == 'm': + return None + + (lt_path, lt_libname, lt_static) = self.find_lt_names_msvc(lib, is_static) + + if lt_path != None and lt_libname != None: + if lt_static: + # file existence check has been made by find_lt_names + return os.path.join(lt_path,lt_libname) + + if lt_path != None: + _libpaths = [lt_path] + self.env.LIBPATH + else: + _libpaths = self.env.LIBPATH + + static_libs=[ + 'lib%ss.lib' % lib, + 'lib%s.lib' % lib, + '%ss.lib' % lib, + '%s.lib' %lib, + ] + + dynamic_libs=[ + 'lib%s.dll.lib' % lib, + 'lib%s.dll.a' % lib, + '%s.dll.lib' % lib, + '%s.dll.a' % lib, + 'lib%s_d.lib' % lib, + '%s_d.lib' % lib, + '%s.lib' %lib, + ] + + libnames=static_libs + if not is_static: + libnames=dynamic_libs + static_libs + + for path in _libpaths: + for libn in libnames: + if os.path.exists(os.path.join(path, libn)): + Logs.debug('msvc: lib found: %s', os.path.join(path,libn)) + return re.sub(r'\.lib$', '',libn) + + #if no lib can be found, just return the libname as msvc expects it + self.fatal('The library %r could not be found' % libname) + return re.sub(r'\.lib$', '', libname) + +@conf +def check_lib_msvc(self, libname, is_static=False, uselib_store=None): + """ + Ideally we should be able to place the lib in the right env var, either STLIB or LIB, + but we don't distinguish static libs from shared libs. + This is ok since msvc doesn't have any special linker flag to select static libs (no env.STLIB_MARKER) + """ + libn = self.libname_msvc(libname, is_static) + + if not uselib_store: + uselib_store = libname.upper() + + if False and is_static: # disabled + self.env['STLIB_' + uselib_store] = [libn] + else: + self.env['LIB_' + uselib_store] = [libn] + +@conf +def check_libs_msvc(self, libnames, is_static=False): + for libname in Utils.to_list(libnames): + self.check_lib_msvc(libname, is_static) + +def configure(conf): + """ + Configuration methods to call for detecting msvc + """ + conf.autodetect(True) + conf.find_msvc() + conf.msvc_common_flags() + conf.cc_load_tools() + conf.cxx_load_tools() + conf.cc_add_flags() + conf.cxx_add_flags() + conf.link_add_flags() + conf.visual_studio_add_flags() + +@conf +def no_autodetect(conf): + conf.env.NO_MSVC_DETECT = 1 + configure(conf) + +@conf +def autodetect(conf, arch=False): + v = conf.env + if v.NO_MSVC_DETECT: + return + + compiler, version, path, includes, libdirs, cpu = conf.detect_msvc() + if arch: + v.DEST_CPU = cpu + + v.PATH = path + v.INCLUDES = includes + v.LIBPATH = libdirs + v.MSVC_COMPILER = compiler + try: + v.MSVC_VERSION = float(version) + except ValueError: + v.MSVC_VERSION = float(version[:-3]) + +def _get_prog_names(conf, compiler): + if compiler == 'intel': + compiler_name = 'ICL' + linker_name = 'XILINK' + lib_name = 'XILIB' + else: + # assumes CL.exe + compiler_name = 'CL' + linker_name = 'LINK' + lib_name = 'LIB' + return compiler_name, linker_name, lib_name + +@conf +def find_msvc(conf): + """Due to path format limitations, limit operation only to native Win32. Yeah it sucks.""" + if sys.platform == 'cygwin': + conf.fatal('MSVC module does not work under cygwin Python!') + + # the autodetection is supposed to be performed before entering in this method + v = conf.env + path = v.PATH + compiler = v.MSVC_COMPILER + version = v.MSVC_VERSION + + compiler_name, linker_name, lib_name = _get_prog_names(conf, compiler) + v.MSVC_MANIFEST = (compiler == 'msvc' and version >= 8) or (compiler == 'wsdk' and version >= 6) or (compiler == 'intel' and version >= 11) + + # compiler + cxx = conf.find_program(compiler_name, var='CXX', path_list=path) + + # before setting anything, check if the compiler is really msvc + env = dict(conf.environ) + if path: + env.update(PATH = ';'.join(path)) + if not conf.cmd_and_log(cxx + ['/nologo', '/help'], env=env): + conf.fatal('the msvc compiler could not be identified') + + # c/c++ compiler + v.CC = v.CXX = cxx + v.CC_NAME = v.CXX_NAME = 'msvc' + + # linker + if not v.LINK_CXX: + conf.find_program(linker_name, path_list=path, errmsg='%s was not found (linker)' % linker_name, var='LINK_CXX') + + if not v.LINK_CC: + v.LINK_CC = v.LINK_CXX + + # staticlib linker + if not v.AR: + stliblink = conf.find_program(lib_name, path_list=path, var='AR') + if not stliblink: + return + v.ARFLAGS = ['/nologo'] + + # manifest tool. Not required for VS 2003 and below. Must have for VS 2005 and later + if v.MSVC_MANIFEST: + conf.find_program('MT', path_list=path, var='MT') + v.MTFLAGS = ['/nologo'] + + try: + conf.load('winres') + except Errors.ConfigurationError: + Logs.warn('Resource compiler not found. Compiling resource file is disabled') + +@conf +def visual_studio_add_flags(self): + """visual studio flags found in the system environment""" + v = self.env + if self.environ.get('INCLUDE'): + v.prepend_value('INCLUDES', [x for x in self.environ['INCLUDE'].split(';') if x]) # notice the 'S' + if self.environ.get('LIB'): + v.prepend_value('LIBPATH', [x for x in self.environ['LIB'].split(';') if x]) + +@conf +def msvc_common_flags(conf): + """ + Setup the flags required for executing the msvc compiler + """ + v = conf.env + + v.DEST_BINFMT = 'pe' + v.append_value('CFLAGS', ['/nologo']) + v.append_value('CXXFLAGS', ['/nologo']) + v.append_value('LINKFLAGS', ['/nologo']) + v.DEFINES_ST = '/D%s' + + v.CC_SRC_F = '' + v.CC_TGT_F = ['/c', '/Fo'] + v.CXX_SRC_F = '' + v.CXX_TGT_F = ['/c', '/Fo'] + + if (v.MSVC_COMPILER == 'msvc' and v.MSVC_VERSION >= 8) or (v.MSVC_COMPILER == 'wsdk' and v.MSVC_VERSION >= 6): + v.CC_TGT_F = ['/FC'] + v.CC_TGT_F + v.CXX_TGT_F = ['/FC'] + v.CXX_TGT_F + + v.CPPPATH_ST = '/I%s' # template for adding include paths + + v.AR_TGT_F = v.CCLNK_TGT_F = v.CXXLNK_TGT_F = '/OUT:' + + # CRT specific flags + v.CFLAGS_CRT_MULTITHREADED = v.CXXFLAGS_CRT_MULTITHREADED = ['/MT'] + v.CFLAGS_CRT_MULTITHREADED_DLL = v.CXXFLAGS_CRT_MULTITHREADED_DLL = ['/MD'] + + v.CFLAGS_CRT_MULTITHREADED_DBG = v.CXXFLAGS_CRT_MULTITHREADED_DBG = ['/MTd'] + v.CFLAGS_CRT_MULTITHREADED_DLL_DBG = v.CXXFLAGS_CRT_MULTITHREADED_DLL_DBG = ['/MDd'] + + v.LIB_ST = '%s.lib' + v.LIBPATH_ST = '/LIBPATH:%s' + v.STLIB_ST = '%s.lib' + v.STLIBPATH_ST = '/LIBPATH:%s' + + if v.MSVC_MANIFEST: + v.append_value('LINKFLAGS', ['/MANIFEST']) + + v.CFLAGS_cshlib = [] + v.CXXFLAGS_cxxshlib = [] + v.LINKFLAGS_cshlib = v.LINKFLAGS_cxxshlib = ['/DLL'] + v.cshlib_PATTERN = v.cxxshlib_PATTERN = '%s.dll' + v.implib_PATTERN = '%s.lib' + v.IMPLIB_ST = '/IMPLIB:%s' + + v.LINKFLAGS_cstlib = [] + v.cstlib_PATTERN = v.cxxstlib_PATTERN = '%s.lib' + + v.cprogram_PATTERN = v.cxxprogram_PATTERN = '%s.exe' + + v.def_PATTERN = '/def:%s' + + +####################################################################################################### +##### conf above, build below + +@after_method('apply_link') +@feature('c', 'cxx') +def apply_flags_msvc(self): + """ + Add additional flags implied by msvc, such as subsystems and pdb files:: + + def build(bld): + bld.stlib(source='main.c', target='bar', subsystem='gruik') + """ + if self.env.CC_NAME != 'msvc' or not getattr(self, 'link_task', None): + return + + is_static = isinstance(self.link_task, ccroot.stlink_task) + + subsystem = getattr(self, 'subsystem', '') + if subsystem: + subsystem = '/subsystem:%s' % subsystem + flags = is_static and 'ARFLAGS' or 'LINKFLAGS' + self.env.append_value(flags, subsystem) + + if not is_static: + for f in self.env.LINKFLAGS: + d = f.lower() + if d[1:] in ('debug', 'debug:full', 'debug:fastlink'): + pdbnode = self.link_task.outputs[0].change_ext('.pdb') + self.link_task.outputs.append(pdbnode) + + if getattr(self, 'install_task', None): + self.pdb_install_task = self.add_install_files( + install_to=self.install_task.install_to, install_from=pdbnode) + break + +@feature('cprogram', 'cshlib', 'cxxprogram', 'cxxshlib') +@after_method('apply_link') +def apply_manifest(self): + """ + Special linker for MSVC with support for embedding manifests into DLL's + and executables compiled by Visual Studio 2005 or probably later. Without + the manifest file, the binaries are unusable. + See: http://msdn2.microsoft.com/en-us/library/ms235542(VS.80).aspx + """ + if self.env.CC_NAME == 'msvc' and self.env.MSVC_MANIFEST and getattr(self, 'link_task', None): + out_node = self.link_task.outputs[0] + man_node = out_node.parent.find_or_declare(out_node.name + '.manifest') + self.link_task.outputs.append(man_node) + self.env.DO_MANIFEST = True + +def make_winapp(self, family): + append = self.env.append_unique + append('DEFINES', 'WINAPI_FAMILY=%s' % family) + append('CXXFLAGS', ['/ZW', '/TP']) + for lib_path in self.env.LIBPATH: + append('CXXFLAGS','/AI%s'%lib_path) + +@feature('winphoneapp') +@after_method('process_use') +@after_method('propagate_uselib_vars') +def make_winphone_app(self): + """ + Insert configuration flags for windows phone applications (adds /ZW, /TP...) + """ + make_winapp(self, 'WINAPI_FAMILY_PHONE_APP') + self.env.append_unique('LINKFLAGS', ['/NODEFAULTLIB:ole32.lib', 'PhoneAppModelHost.lib']) + +@feature('winapp') +@after_method('process_use') +@after_method('propagate_uselib_vars') +def make_windows_app(self): + """ + Insert configuration flags for windows applications (adds /ZW, /TP...) + """ + make_winapp(self, 'WINAPI_FAMILY_DESKTOP_APP') diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/nasm.py b/ldb-2.0.8/third_party/waf/waflib/Tools/nasm.py new file mode 100644 index 0000000..9c51c18 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/nasm.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2008-2018 (ita) + +""" +Nasm tool (asm processing) +""" + +import os +import waflib.Tools.asm # leave this +from waflib.TaskGen import feature + +@feature('asm') +def apply_nasm_vars(self): + """provided for compatibility""" + self.env.append_value('ASFLAGS', self.to_list(getattr(self, 'nasm_flags', []))) + +def configure(conf): + """ + Detect nasm/yasm and set the variable *AS* + """ + conf.find_program(['nasm', 'yasm'], var='AS') + conf.env.AS_TGT_F = ['-o'] + conf.env.ASLNK_TGT_F = ['-o'] + conf.load('asm') + conf.env.ASMPATH_ST = '-I%s' + os.sep + txt = conf.cmd_and_log(conf.env.AS + ['--version']) + if 'yasm' in txt.lower(): + conf.env.ASM_NAME = 'yasm' + else: + conf.env.ASM_NAME = 'nasm' diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/nobuild.py b/ldb-2.0.8/third_party/waf/waflib/Tools/nobuild.py new file mode 100644 index 0000000..2e4b055 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/nobuild.py @@ -0,0 +1,24 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2015 (ita) + +""" +Override the build commands to write empty files. +This is useful for profiling and evaluating the Python overhead. + +To use:: + + def build(bld): + ... + bld.load('nobuild') + +""" + +from waflib import Task +def build(bld): + def run(self): + for x in self.outputs: + x.write('') + for (name, cls) in Task.classes.items(): + cls.run = run + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/perl.py b/ldb-2.0.8/third_party/waf/waflib/Tools/perl.py new file mode 100644 index 0000000..32b03fb --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/perl.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python +# encoding: utf-8 +# andersg at 0x63.nu 2007 +# Thomas Nagy 2016-2018 (ita) + +""" +Support for Perl extensions. A C/C++ compiler is required:: + + def options(opt): + opt.load('compiler_c perl') + def configure(conf): + conf.load('compiler_c perl') + conf.check_perl_version((5,6,0)) + conf.check_perl_ext_devel() + conf.check_perl_module('Cairo') + conf.check_perl_module('Devel::PPPort 4.89') + def build(bld): + bld( + features = 'c cshlib perlext', + source = 'Mytest.xs', + target = 'Mytest', + install_path = '${ARCHDIR_PERL}/auto') + bld.install_files('${ARCHDIR_PERL}', 'Mytest.pm') +""" + +import os +from waflib import Task, Options, Utils, Errors +from waflib.Configure import conf +from waflib.TaskGen import extension, feature, before_method + +@before_method('apply_incpaths', 'apply_link', 'propagate_uselib_vars') +@feature('perlext') +def init_perlext(self): + """ + Change the values of *cshlib_PATTERN* and *cxxshlib_PATTERN* to remove the + *lib* prefix from library names. + """ + self.uselib = self.to_list(getattr(self, 'uselib', [])) + if not 'PERLEXT' in self.uselib: + self.uselib.append('PERLEXT') + self.env.cshlib_PATTERN = self.env.cxxshlib_PATTERN = self.env.perlext_PATTERN + +@extension('.xs') +def xsubpp_file(self, node): + """ + Create :py:class:`waflib.Tools.perl.xsubpp` tasks to process *.xs* files + """ + outnode = node.change_ext('.c') + self.create_task('xsubpp', node, outnode) + self.source.append(outnode) + +class xsubpp(Task.Task): + """ + Process *.xs* files + """ + run_str = '${PERL} ${XSUBPP} -noprototypes -typemap ${EXTUTILS_TYPEMAP} ${SRC} > ${TGT}' + color = 'BLUE' + ext_out = ['.h'] + +@conf +def check_perl_version(self, minver=None): + """ + Check if Perl is installed, and set the variable PERL. + minver is supposed to be a tuple + """ + res = True + if minver: + cver = '.'.join(map(str,minver)) + else: + cver = '' + + self.start_msg('Checking for minimum perl version %s' % cver) + + perl = self.find_program('perl', var='PERL', value=getattr(Options.options, 'perlbinary', None)) + version = self.cmd_and_log(perl + ["-e", 'printf \"%vd\", $^V']) + if not version: + res = False + version = "Unknown" + elif not minver is None: + ver = tuple(map(int, version.split("."))) + if ver < minver: + res = False + + self.end_msg(version, color=res and 'GREEN' or 'YELLOW') + return res + +@conf +def check_perl_module(self, module): + """ + Check if specified perlmodule is installed. + + The minimum version can be specified by specifying it after modulename + like this:: + + def configure(conf): + conf.check_perl_module("Some::Module 2.92") + """ + cmd = self.env.PERL + ['-e', 'use %s' % module] + self.start_msg('perl module %s' % module) + try: + r = self.cmd_and_log(cmd) + except Errors.WafError: + self.end_msg(False) + return None + self.end_msg(r or True) + return r + +@conf +def check_perl_ext_devel(self): + """ + Check for configuration needed to build perl extensions. + + Sets different xxx_PERLEXT variables in the environment. + + Also sets the ARCHDIR_PERL variable useful as installation path, + which can be overridden by ``--with-perl-archdir`` option. + """ + + env = self.env + perl = env.PERL + if not perl: + self.fatal('find perl first') + + def cmd_perl_config(s): + return perl + ['-MConfig', '-e', 'print \"%s\"' % s] + def cfg_str(cfg): + return self.cmd_and_log(cmd_perl_config(cfg)) + def cfg_lst(cfg): + return Utils.to_list(cfg_str(cfg)) + def find_xsubpp(): + for var in ('privlib', 'vendorlib'): + xsubpp = cfg_lst('$Config{%s}/ExtUtils/xsubpp$Config{exe_ext}' % var) + if xsubpp and os.path.isfile(xsubpp[0]): + return xsubpp + return self.find_program('xsubpp') + + env.LINKFLAGS_PERLEXT = cfg_lst('$Config{lddlflags}') + env.INCLUDES_PERLEXT = cfg_lst('$Config{archlib}/CORE') + env.CFLAGS_PERLEXT = cfg_lst('$Config{ccflags} $Config{cccdlflags}') + env.EXTUTILS_TYPEMAP = cfg_lst('$Config{privlib}/ExtUtils/typemap') + env.XSUBPP = find_xsubpp() + + if not getattr(Options.options, 'perlarchdir', None): + env.ARCHDIR_PERL = cfg_str('$Config{sitearch}') + else: + env.ARCHDIR_PERL = getattr(Options.options, 'perlarchdir') + + env.perlext_PATTERN = '%s.' + cfg_str('$Config{dlext}') + +def options(opt): + """ + Add the ``--with-perl-archdir`` and ``--with-perl-binary`` command-line options. + """ + opt.add_option('--with-perl-binary', type='string', dest='perlbinary', help = 'Specify alternate perl binary', default=None) + opt.add_option('--with-perl-archdir', type='string', dest='perlarchdir', help = 'Specify directory where to install arch specific files', default=None) + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/python.py b/ldb-2.0.8/third_party/waf/waflib/Tools/python.py new file mode 100644 index 0000000..7c45a76 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/python.py @@ -0,0 +1,644 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2007-2015 (ita) +# Gustavo Carneiro (gjc), 2007 + +""" +Support for Python, detect the headers and libraries and provide +*use* variables to link C/C++ programs against them:: + + def options(opt): + opt.load('compiler_c python') + def configure(conf): + conf.load('compiler_c python') + conf.check_python_version((2,4,2)) + conf.check_python_headers() + def build(bld): + bld.program(features='pyembed', source='a.c', target='myprog') + bld.shlib(features='pyext', source='b.c', target='mylib') +""" + +import os, sys +from waflib import Errors, Logs, Node, Options, Task, Utils +from waflib.TaskGen import extension, before_method, after_method, feature +from waflib.Configure import conf + +FRAG = ''' +#include +#ifdef __cplusplus +extern "C" { +#endif + void Py_Initialize(void); + void Py_Finalize(void); +#ifdef __cplusplus +} +#endif +int main(int argc, char **argv) +{ + (void)argc; (void)argv; + Py_Initialize(); + Py_Finalize(); + return 0; +} +''' +""" +Piece of C/C++ code used in :py:func:`waflib.Tools.python.check_python_headers` +""" + +INST = ''' +import sys, py_compile +py_compile.compile(sys.argv[1], sys.argv[2], sys.argv[3], True) +''' +""" +Piece of Python code used in :py:class:`waflib.Tools.python.pyo` and :py:class:`waflib.Tools.python.pyc` for byte-compiling python files +""" + +DISTUTILS_IMP = ['from distutils.sysconfig import get_config_var, get_python_lib'] + +@before_method('process_source') +@feature('py') +def feature_py(self): + """ + Create tasks to byte-compile .py files and install them, if requested + """ + self.install_path = getattr(self, 'install_path', '${PYTHONDIR}') + install_from = getattr(self, 'install_from', None) + if install_from and not isinstance(install_from, Node.Node): + install_from = self.path.find_dir(install_from) + self.install_from = install_from + + ver = self.env.PYTHON_VERSION + if not ver: + self.bld.fatal('Installing python files requires PYTHON_VERSION, try conf.check_python_version') + + if int(ver.replace('.', '')) > 31: + self.install_32 = True + +@extension('.py') +def process_py(self, node): + """ + Add signature of .py file, so it will be byte-compiled when necessary + """ + assert(hasattr(self, 'install_path')), 'add features="py" for target "%s" in "%s/wscript".' % (self.target, self.path.nice_path()) + self.install_from = getattr(self, 'install_from', None) + relative_trick = getattr(self, 'relative_trick', True) + if self.install_from: + assert isinstance(self.install_from, Node.Node), \ + 'add features="py" for target "%s" in "%s/wscript" (%s).' % (self.target, self.path.nice_path(), type(self.install_from)) + + # where to install the python file + if self.install_path: + if self.install_from: + self.add_install_files(install_to=self.install_path, install_from=node, cwd=self.install_from, relative_trick=relative_trick) + else: + self.add_install_files(install_to=self.install_path, install_from=node, relative_trick=relative_trick) + + lst = [] + if self.env.PYC: + lst.append('pyc') + if self.env.PYO: + lst.append('pyo') + + if self.install_path: + if self.install_from: + target_dir = node.path_from(self.install_from) if relative_trick else node.name + pyd = Utils.subst_vars("%s/%s" % (self.install_path, target_dir), self.env) + else: + target_dir = node.path_from(self.path) if relative_trick else node.name + pyd = Utils.subst_vars("%s/%s" % (self.install_path, target_dir), self.env) + else: + pyd = node.abspath() + + for ext in lst: + if self.env.PYTAG and not self.env.NOPYCACHE: + # __pycache__ installation for python 3.2 - PEP 3147 + name = node.name[:-3] + pyobj = node.parent.get_bld().make_node('__pycache__').make_node("%s.%s.%s" % (name, self.env.PYTAG, ext)) + pyobj.parent.mkdir() + else: + pyobj = node.change_ext(".%s" % ext) + + tsk = self.create_task(ext, node, pyobj) + tsk.pyd = pyd + + if self.install_path: + self.add_install_files(install_to=os.path.dirname(pyd), install_from=pyobj, cwd=node.parent.get_bld(), relative_trick=relative_trick) + +class pyc(Task.Task): + """ + Byte-compiling python files + """ + color = 'PINK' + def __str__(self): + node = self.outputs[0] + return node.path_from(node.ctx.launch_node()) + def run(self): + cmd = [Utils.subst_vars('${PYTHON}', self.env), '-c', INST, self.inputs[0].abspath(), self.outputs[0].abspath(), self.pyd] + ret = self.generator.bld.exec_command(cmd) + return ret + +class pyo(Task.Task): + """ + Byte-compiling python files + """ + color = 'PINK' + def __str__(self): + node = self.outputs[0] + return node.path_from(node.ctx.launch_node()) + def run(self): + cmd = [Utils.subst_vars('${PYTHON}', self.env), Utils.subst_vars('${PYFLAGS_OPT}', self.env), '-c', INST, self.inputs[0].abspath(), self.outputs[0].abspath(), self.pyd] + ret = self.generator.bld.exec_command(cmd) + return ret + +@feature('pyext') +@before_method('propagate_uselib_vars', 'apply_link') +@after_method('apply_bundle') +def init_pyext(self): + """ + Change the values of *cshlib_PATTERN* and *cxxshlib_PATTERN* to remove the + *lib* prefix from library names. + """ + self.uselib = self.to_list(getattr(self, 'uselib', [])) + if not 'PYEXT' in self.uselib: + self.uselib.append('PYEXT') + # override shlib_PATTERN set by the osx module + self.env.cshlib_PATTERN = self.env.cxxshlib_PATTERN = self.env.macbundle_PATTERN = self.env.pyext_PATTERN + self.env.fcshlib_PATTERN = self.env.dshlib_PATTERN = self.env.pyext_PATTERN + + try: + if not self.install_path: + return + except AttributeError: + self.install_path = '${PYTHONARCHDIR}' + +@feature('pyext') +@before_method('apply_link', 'apply_bundle') +def set_bundle(self): + """Mac-specific pyext extension that enables bundles from c_osx.py""" + if Utils.unversioned_sys_platform() == 'darwin': + self.mac_bundle = True + +@before_method('propagate_uselib_vars') +@feature('pyembed') +def init_pyembed(self): + """ + Add the PYEMBED variable. + """ + self.uselib = self.to_list(getattr(self, 'uselib', [])) + if not 'PYEMBED' in self.uselib: + self.uselib.append('PYEMBED') + +@conf +def get_python_variables(self, variables, imports=None): + """ + Spawn a new python process to dump configuration variables + + :param variables: variables to print + :type variables: list of string + :param imports: one import by element + :type imports: list of string + :return: the variable values + :rtype: list of string + """ + if not imports: + try: + imports = self.python_imports + except AttributeError: + imports = DISTUTILS_IMP + + program = list(imports) # copy + program.append('') + for v in variables: + program.append("print(repr(%s))" % v) + os_env = dict(os.environ) + try: + del os_env['MACOSX_DEPLOYMENT_TARGET'] # see comments in the OSX tool + except KeyError: + pass + + try: + out = self.cmd_and_log(self.env.PYTHON + ['-c', '\n'.join(program)], env=os_env) + except Errors.WafError: + self.fatal('The distutils module is unusable: install "python-devel"?') + self.to_log(out) + return_values = [] + for s in out.splitlines(): + s = s.strip() + if not s: + continue + if s == 'None': + return_values.append(None) + elif (s[0] == "'" and s[-1] == "'") or (s[0] == '"' and s[-1] == '"'): + return_values.append(eval(s)) + elif s[0].isdigit(): + return_values.append(int(s)) + else: break + return return_values + +@conf +def test_pyembed(self, mode, msg='Testing pyembed configuration'): + self.check(header_name='Python.h', define_name='HAVE_PYEMBED', msg=msg, + fragment=FRAG, errmsg='Could not build a python embedded interpreter', + features='%s %sprogram pyembed' % (mode, mode)) + +@conf +def test_pyext(self, mode, msg='Testing pyext configuration'): + self.check(header_name='Python.h', define_name='HAVE_PYEXT', msg=msg, + fragment=FRAG, errmsg='Could not build python extensions', + features='%s %sshlib pyext' % (mode, mode)) + +@conf +def python_cross_compile(self, features='pyembed pyext'): + """ + For cross-compilation purposes, it is possible to bypass the normal detection and set the flags that you want: + PYTHON_VERSION='3.4' PYTAG='cpython34' pyext_PATTERN="%s.so" PYTHON_LDFLAGS='-lpthread -ldl' waf configure + + The following variables are used: + PYTHON_VERSION required + PYTAG required + PYTHON_LDFLAGS required + pyext_PATTERN required + PYTHON_PYEXT_LDFLAGS + PYTHON_PYEMBED_LDFLAGS + """ + features = Utils.to_list(features) + if not ('PYTHON_LDFLAGS' in self.environ or 'PYTHON_PYEXT_LDFLAGS' in self.environ or 'PYTHON_PYEMBED_LDFLAGS' in self.environ): + return False + + for x in 'PYTHON_VERSION PYTAG pyext_PATTERN'.split(): + if not x in self.environ: + self.fatal('Please set %s in the os environment' % x) + else: + self.env[x] = self.environ[x] + + xx = self.env.CXX_NAME and 'cxx' or 'c' + if 'pyext' in features: + flags = self.environ.get('PYTHON_PYEXT_LDFLAGS', self.environ.get('PYTHON_LDFLAGS')) + if flags is None: + self.fatal('No flags provided through PYTHON_PYEXT_LDFLAGS as required') + else: + self.parse_flags(flags, 'PYEXT') + self.test_pyext(xx) + if 'pyembed' in features: + flags = self.environ.get('PYTHON_PYEMBED_LDFLAGS', self.environ.get('PYTHON_LDFLAGS')) + if flags is None: + self.fatal('No flags provided through PYTHON_PYEMBED_LDFLAGS as required') + else: + self.parse_flags(flags, 'PYEMBED') + self.test_pyembed(xx) + return True + +@conf +def check_python_headers(conf, features='pyembed pyext'): + """ + Check for headers and libraries necessary to extend or embed python by using the module *distutils*. + On success the environment variables xxx_PYEXT and xxx_PYEMBED are added: + + * PYEXT: for compiling python extensions + * PYEMBED: for embedding a python interpreter + """ + features = Utils.to_list(features) + assert ('pyembed' in features) or ('pyext' in features), "check_python_headers features must include 'pyembed' and/or 'pyext'" + env = conf.env + if not env.CC_NAME and not env.CXX_NAME: + conf.fatal('load a compiler first (gcc, g++, ..)') + + # bypass all the code below for cross-compilation + if conf.python_cross_compile(features): + return + + if not env.PYTHON_VERSION: + conf.check_python_version() + + pybin = env.PYTHON + if not pybin: + conf.fatal('Could not find the python executable') + + # so we actually do all this for compatibility reasons and for obtaining pyext_PATTERN below + v = 'prefix SO LDFLAGS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET LDSHARED CFLAGS LDVERSION'.split() + try: + lst = conf.get_python_variables(["get_config_var('%s') or ''" % x for x in v]) + except RuntimeError: + conf.fatal("Python development headers not found (-v for details).") + + vals = ['%s = %r' % (x, y) for (x, y) in zip(v, lst)] + conf.to_log("Configuration returned from %r:\n%s\n" % (pybin, '\n'.join(vals))) + + dct = dict(zip(v, lst)) + x = 'MACOSX_DEPLOYMENT_TARGET' + if dct[x]: + env[x] = conf.environ[x] = dct[x] + env.pyext_PATTERN = '%s' + dct['SO'] # not a mistake + + + # Try to get pythonX.Y-config + num = '.'.join(env.PYTHON_VERSION.split('.')[:2]) + conf.find_program([''.join(pybin) + '-config', 'python%s-config' % num, 'python-config-%s' % num, 'python%sm-config' % num], var='PYTHON_CONFIG', msg="python-config", mandatory=False) + + if env.PYTHON_CONFIG: + # check python-config output only once + if conf.env.HAVE_PYTHON_H: + return + + # python2.6-config requires 3 runs + all_flags = [['--cflags', '--libs', '--ldflags']] + if sys.hexversion < 0x2070000: + all_flags = [[k] for k in all_flags[0]] + + xx = env.CXX_NAME and 'cxx' or 'c' + + if 'pyembed' in features: + for flags in all_flags: + # Python 3.8 has different flags for pyembed, needs --embed + embedflags = flags + ['--embed'] + try: + conf.check_cfg(msg='Asking python-config for pyembed %r flags' % ' '.join(embedflags), path=env.PYTHON_CONFIG, package='', uselib_store='PYEMBED', args=embedflags) + except conf.errors.ConfigurationError: + # However Python < 3.8 doesn't accept --embed, so we need a fallback + conf.check_cfg(msg='Asking python-config for pyembed %r flags' % ' '.join(flags), path=env.PYTHON_CONFIG, package='', uselib_store='PYEMBED', args=flags) + + try: + conf.test_pyembed(xx) + except conf.errors.ConfigurationError: + # python bug 7352 + if dct['Py_ENABLE_SHARED'] and dct['LIBDIR']: + env.append_unique('LIBPATH_PYEMBED', [dct['LIBDIR']]) + conf.test_pyembed(xx) + else: + raise + + if 'pyext' in features: + for flags in all_flags: + conf.check_cfg(msg='Asking python-config for pyext %r flags' % ' '.join(flags), path=env.PYTHON_CONFIG, package='', uselib_store='PYEXT', args=flags) + + try: + conf.test_pyext(xx) + except conf.errors.ConfigurationError: + # python bug 7352 + if dct['Py_ENABLE_SHARED'] and dct['LIBDIR']: + env.append_unique('LIBPATH_PYEXT', [dct['LIBDIR']]) + conf.test_pyext(xx) + else: + raise + + conf.define('HAVE_PYTHON_H', 1) + return + + # No python-config, do something else on windows systems + all_flags = dct['LDFLAGS'] + ' ' + dct['CFLAGS'] + conf.parse_flags(all_flags, 'PYEMBED') + + all_flags = dct['LDFLAGS'] + ' ' + dct['LDSHARED'] + ' ' + dct['CFLAGS'] + conf.parse_flags(all_flags, 'PYEXT') + + result = None + if not dct["LDVERSION"]: + dct["LDVERSION"] = env.PYTHON_VERSION + + # further simplification will be complicated + for name in ('python' + dct['LDVERSION'], 'python' + env.PYTHON_VERSION + 'm', 'python' + env.PYTHON_VERSION.replace('.', '')): + + # LIBPATH_PYEMBED is already set; see if it works. + if not result and env.LIBPATH_PYEMBED: + path = env.LIBPATH_PYEMBED + conf.to_log("\n\n# Trying default LIBPATH_PYEMBED: %r\n" % path) + result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in LIBPATH_PYEMBED' % name) + + if not result and dct['LIBDIR']: + path = [dct['LIBDIR']] + conf.to_log("\n\n# try again with -L$python_LIBDIR: %r\n" % path) + result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in LIBDIR' % name) + + if not result and dct['LIBPL']: + path = [dct['LIBPL']] + conf.to_log("\n\n# try again with -L$python_LIBPL (some systems don't install the python library in $prefix/lib)\n") + result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in python_LIBPL' % name) + + if not result: + path = [os.path.join(dct['prefix'], "libs")] + conf.to_log("\n\n# try again with -L$prefix/libs, and pythonXY name rather than pythonX.Y (win32)\n") + result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in $prefix/libs' % name) + + if result: + break # do not forget to set LIBPATH_PYEMBED + + if result: + env.LIBPATH_PYEMBED = path + env.append_value('LIB_PYEMBED', [name]) + else: + conf.to_log("\n\n### LIB NOT FOUND\n") + + # under certain conditions, python extensions must link to + # python libraries, not just python embedding programs. + if Utils.is_win32 or dct['Py_ENABLE_SHARED']: + env.LIBPATH_PYEXT = env.LIBPATH_PYEMBED + env.LIB_PYEXT = env.LIB_PYEMBED + + conf.to_log("Include path for Python extensions (found via distutils module): %r\n" % (dct['INCLUDEPY'],)) + env.INCLUDES_PYEXT = [dct['INCLUDEPY']] + env.INCLUDES_PYEMBED = [dct['INCLUDEPY']] + + # Code using the Python API needs to be compiled with -fno-strict-aliasing + if env.CC_NAME == 'gcc': + env.append_unique('CFLAGS_PYEMBED', ['-fno-strict-aliasing']) + env.append_unique('CFLAGS_PYEXT', ['-fno-strict-aliasing']) + if env.CXX_NAME == 'gcc': + env.append_unique('CXXFLAGS_PYEMBED', ['-fno-strict-aliasing']) + env.append_unique('CXXFLAGS_PYEXT', ['-fno-strict-aliasing']) + + if env.CC_NAME == "msvc": + from distutils.msvccompiler import MSVCCompiler + dist_compiler = MSVCCompiler() + dist_compiler.initialize() + env.append_value('CFLAGS_PYEXT', dist_compiler.compile_options) + env.append_value('CXXFLAGS_PYEXT', dist_compiler.compile_options) + env.append_value('LINKFLAGS_PYEXT', dist_compiler.ldflags_shared) + + # See if it compiles + conf.check(header_name='Python.h', define_name='HAVE_PYTHON_H', uselib='PYEMBED', fragment=FRAG, errmsg='Distutils not installed? Broken python installation? Get python-config now!') + +@conf +def check_python_version(conf, minver=None): + """ + Check if the python interpreter is found matching a given minimum version. + minver should be a tuple, eg. to check for python >= 2.4.2 pass (2,4,2) as minver. + + If successful, PYTHON_VERSION is defined as 'MAJOR.MINOR' (eg. '2.4') + of the actual python version found, and PYTHONDIR and PYTHONARCHDIR + are defined, pointing to the site-packages directories appropriate for + this python version, where modules/packages/extensions should be + installed. + + :param minver: minimum version + :type minver: tuple of int + """ + assert minver is None or isinstance(minver, tuple) + pybin = conf.env.PYTHON + if not pybin: + conf.fatal('could not find the python executable') + + # Get python version string + cmd = pybin + ['-c', 'import sys\nfor x in sys.version_info: print(str(x))'] + Logs.debug('python: Running python command %r', cmd) + lines = conf.cmd_and_log(cmd).split() + assert len(lines) == 5, "found %r lines, expected 5: %r" % (len(lines), lines) + pyver_tuple = (int(lines[0]), int(lines[1]), int(lines[2]), lines[3], int(lines[4])) + + # Compare python version with the minimum required + result = (minver is None) or (pyver_tuple >= minver) + + if result: + # define useful environment variables + pyver = '.'.join([str(x) for x in pyver_tuple[:2]]) + conf.env.PYTHON_VERSION = pyver + + if 'PYTHONDIR' in conf.env: + # Check if --pythondir was specified + pydir = conf.env.PYTHONDIR + elif 'PYTHONDIR' in conf.environ: + # Check environment for PYTHONDIR + pydir = conf.environ['PYTHONDIR'] + else: + # Finally, try to guess + if Utils.is_win32: + (python_LIBDEST, pydir) = conf.get_python_variables( + ["get_config_var('LIBDEST') or ''", + "get_python_lib(standard_lib=0) or ''"]) + else: + python_LIBDEST = None + (pydir,) = conf.get_python_variables( ["get_python_lib(standard_lib=0, prefix=%r) or ''" % conf.env.PREFIX]) + if python_LIBDEST is None: + if conf.env.LIBDIR: + python_LIBDEST = os.path.join(conf.env.LIBDIR, 'python' + pyver) + else: + python_LIBDEST = os.path.join(conf.env.PREFIX, 'lib', 'python' + pyver) + + if 'PYTHONARCHDIR' in conf.env: + # Check if --pythonarchdir was specified + pyarchdir = conf.env.PYTHONARCHDIR + elif 'PYTHONARCHDIR' in conf.environ: + # Check environment for PYTHONDIR + pyarchdir = conf.environ['PYTHONARCHDIR'] + else: + # Finally, try to guess + (pyarchdir, ) = conf.get_python_variables( ["get_python_lib(plat_specific=1, standard_lib=0, prefix=%r) or ''" % conf.env.PREFIX]) + if not pyarchdir: + pyarchdir = pydir + + if hasattr(conf, 'define'): # conf.define is added by the C tool, so may not exist + conf.define('PYTHONDIR', pydir) + conf.define('PYTHONARCHDIR', pyarchdir) + + conf.env.PYTHONDIR = pydir + conf.env.PYTHONARCHDIR = pyarchdir + + # Feedback + pyver_full = '.'.join(map(str, pyver_tuple[:3])) + if minver is None: + conf.msg('Checking for python version', pyver_full) + else: + minver_str = '.'.join(map(str, minver)) + conf.msg('Checking for python version >= %s' % (minver_str,), pyver_full, color=result and 'GREEN' or 'YELLOW') + + if not result: + conf.fatal('The python version is too old, expecting %r' % (minver,)) + +PYTHON_MODULE_TEMPLATE = ''' +import %s as current_module +version = getattr(current_module, '__version__', None) +if version is not None: + print(str(version)) +else: + print('unknown version') +''' + +@conf +def check_python_module(conf, module_name, condition=''): + """ + Check if the selected python interpreter can import the given python module:: + + def configure(conf): + conf.check_python_module('pygccxml') + conf.check_python_module('re', condition="ver > num(2, 0, 4) and ver <= num(3, 0, 0)") + + :param module_name: module + :type module_name: string + """ + msg = "Checking for python module %r" % module_name + if condition: + msg = '%s (%s)' % (msg, condition) + conf.start_msg(msg) + try: + ret = conf.cmd_and_log(conf.env.PYTHON + ['-c', PYTHON_MODULE_TEMPLATE % module_name]) + except Errors.WafError: + conf.end_msg(False) + conf.fatal('Could not find the python module %r' % module_name) + + ret = ret.strip() + if condition: + conf.end_msg(ret) + if ret == 'unknown version': + conf.fatal('Could not check the %s version' % module_name) + + from distutils.version import LooseVersion + def num(*k): + if isinstance(k[0], int): + return LooseVersion('.'.join([str(x) for x in k])) + else: + return LooseVersion(k[0]) + d = {'num': num, 'ver': LooseVersion(ret)} + ev = eval(condition, {}, d) + if not ev: + conf.fatal('The %s version does not satisfy the requirements' % module_name) + else: + if ret == 'unknown version': + conf.end_msg(True) + else: + conf.end_msg(ret) + +def configure(conf): + """ + Detect the python interpreter + """ + v = conf.env + if getattr(Options.options, 'pythondir', None): + v.PYTHONDIR = Options.options.pythondir + if getattr(Options.options, 'pythonarchdir', None): + v.PYTHONARCHDIR = Options.options.pythonarchdir + if getattr(Options.options, 'nopycache', None): + v.NOPYCACHE=Options.options.nopycache + + if not v.PYTHON: + v.PYTHON = [getattr(Options.options, 'python', None) or sys.executable] + v.PYTHON = Utils.to_list(v.PYTHON) + conf.find_program('python', var='PYTHON') + + v.PYFLAGS = '' + v.PYFLAGS_OPT = '-O' + + v.PYC = getattr(Options.options, 'pyc', 1) + v.PYO = getattr(Options.options, 'pyo', 1) + + try: + v.PYTAG = conf.cmd_and_log(conf.env.PYTHON + ['-c', "import imp;print(imp.get_tag())"]).strip() + except Errors.WafError: + pass + +def options(opt): + """ + Add python-specific options + """ + pyopt=opt.add_option_group("Python Options") + pyopt.add_option('--nopyc', dest = 'pyc', action='store_false', default=1, + help = 'Do not install bytecode compiled .pyc files (configuration) [Default:install]') + pyopt.add_option('--nopyo', dest='pyo', action='store_false', default=1, + help='Do not install optimised compiled .pyo files (configuration) [Default:install]') + pyopt.add_option('--nopycache',dest='nopycache', action='store_true', + help='Do not use __pycache__ directory to install objects [Default:auto]') + pyopt.add_option('--python', dest="python", + help='python binary to be used [Default: %s]' % sys.executable) + pyopt.add_option('--pythondir', dest='pythondir', + help='Installation path for python modules (py, platform-independent .py and .pyc files)') + pyopt.add_option('--pythonarchdir', dest='pythonarchdir', + help='Installation path for python extension (pyext, platform-dependent .so or .dylib files)') + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/qt5.py b/ldb-2.0.8/third_party/waf/waflib/Tools/qt5.py new file mode 100644 index 0000000..287c253 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/qt5.py @@ -0,0 +1,800 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2006-2018 (ita) + +""" +This tool helps with finding Qt5 tools and libraries, +and also provides syntactic sugar for using Qt5 tools. + +The following snippet illustrates the tool usage:: + + def options(opt): + opt.load('compiler_cxx qt5') + + def configure(conf): + conf.load('compiler_cxx qt5') + + def build(bld): + bld( + features = 'qt5 cxx cxxprogram', + uselib = 'QT5CORE QT5GUI QT5OPENGL QT5SVG', + source = 'main.cpp textures.qrc aboutDialog.ui', + target = 'window', + ) + +Here, the UI description and resource files will be processed +to generate code. + +Usage +===== + +Load the "qt5" tool. + +You also need to edit your sources accordingly: + +- the normal way of doing things is to have your C++ files + include the .moc file. + This is regarded as the best practice (and provides much faster + compilations). + It also implies that the include paths have beenset properly. + +- to have the include paths added automatically, use the following:: + + from waflib.TaskGen import feature, before_method, after_method + @feature('cxx') + @after_method('process_source') + @before_method('apply_incpaths') + def add_includes_paths(self): + incs = set(self.to_list(getattr(self, 'includes', ''))) + for x in self.compiled_tasks: + incs.add(x.inputs[0].parent.path_from(self.path)) + self.includes = sorted(incs) + +Note: another tool provides Qt processing that does not require +.moc includes, see 'playground/slow_qt/'. + +A few options (--qt{dir,bin,...}) and environment variables +(QT5_{ROOT,DIR,MOC,UIC,XCOMPILE}) allow finer tuning of the tool, +tool path selection, etc; please read the source for more info. + +The detection uses pkg-config on Linux by default. To force static library detection use: +QT5_XCOMPILE=1 QT5_FORCE_STATIC=1 waf configure +""" + +from __future__ import with_statement + +try: + from xml.sax import make_parser + from xml.sax.handler import ContentHandler +except ImportError: + has_xml = False + ContentHandler = object +else: + has_xml = True + +import os, sys, re +from waflib.Tools import cxx +from waflib import Build, Task, Utils, Options, Errors, Context +from waflib.TaskGen import feature, after_method, extension, before_method +from waflib.Configure import conf +from waflib import Logs + +MOC_H = ['.h', '.hpp', '.hxx', '.hh'] +""" +File extensions associated to .moc files +""" + +EXT_RCC = ['.qrc'] +""" +File extension for the resource (.qrc) files +""" + +EXT_UI = ['.ui'] +""" +File extension for the user interface (.ui) files +""" + +EXT_QT5 = ['.cpp', '.cc', '.cxx', '.C'] +""" +File extensions of C++ files that may require a .moc processing +""" + +class qxx(Task.classes['cxx']): + """ + Each C++ file can have zero or several .moc files to create. + They are known only when the files are scanned (preprocessor) + To avoid scanning the c++ files each time (parsing C/C++), the results + are retrieved from the task cache (bld.node_deps/bld.raw_deps). + The moc tasks are also created *dynamically* during the build. + """ + + def __init__(self, *k, **kw): + Task.Task.__init__(self, *k, **kw) + self.moc_done = 0 + + def runnable_status(self): + """ + Compute the task signature to make sure the scanner was executed. Create the + moc tasks by using :py:meth:`waflib.Tools.qt5.qxx.add_moc_tasks` (if necessary), + then postpone the task execution (there is no need to recompute the task signature). + """ + if self.moc_done: + return Task.Task.runnable_status(self) + else: + for t in self.run_after: + if not t.hasrun: + return Task.ASK_LATER + self.add_moc_tasks() + return Task.Task.runnable_status(self) + + def create_moc_task(self, h_node, m_node): + """ + If several libraries use the same classes, it is possible that moc will run several times (Issue 1318) + It is not possible to change the file names, but we can assume that the moc transformation will be identical, + and the moc tasks can be shared in a global cache. + """ + try: + moc_cache = self.generator.bld.moc_cache + except AttributeError: + moc_cache = self.generator.bld.moc_cache = {} + + try: + return moc_cache[h_node] + except KeyError: + tsk = moc_cache[h_node] = Task.classes['moc'](env=self.env, generator=self.generator) + tsk.set_inputs(h_node) + tsk.set_outputs(m_node) + tsk.env.append_unique('MOC_FLAGS', '-i') + + if self.generator: + self.generator.tasks.append(tsk) + + # direct injection in the build phase (safe because called from the main thread) + gen = self.generator.bld.producer + gen.outstanding.append(tsk) + gen.total += 1 + + return tsk + + else: + # remove the signature, it must be recomputed with the moc task + delattr(self, 'cache_sig') + + def add_moc_tasks(self): + """ + Creates moc tasks by looking in the list of file dependencies ``bld.raw_deps[self.uid()]`` + """ + node = self.inputs[0] + bld = self.generator.bld + + # skip on uninstall due to generated files + if bld.is_install == Build.UNINSTALL: + return + + try: + # compute the signature once to know if there is a moc file to create + self.signature() + except KeyError: + # the moc file may be referenced somewhere else + pass + else: + # remove the signature, it must be recomputed with the moc task + delattr(self, 'cache_sig') + + include_nodes = [node.parent] + self.generator.includes_nodes + + moctasks = [] + mocfiles = set() + for d in bld.raw_deps.get(self.uid(), []): + if not d.endswith('.moc'): + continue + + # process that base.moc only once + if d in mocfiles: + continue + mocfiles.add(d) + + # find the source associated with the moc file + h_node = None + base2 = d[:-4] + + # foo.moc from foo.cpp + prefix = node.name[:node.name.rfind('.')] + if base2 == prefix: + h_node = node + else: + # this deviates from the standard + # if bar.cpp includes foo.moc, then assume it is from foo.h + for x in include_nodes: + for e in MOC_H: + h_node = x.find_node(base2 + e) + if h_node: + break + else: + continue + break + if h_node: + m_node = h_node.change_ext('.moc') + else: + raise Errors.WafError('No source found for %r which is a moc file' % d) + + # create the moc task + task = self.create_moc_task(h_node, m_node) + moctasks.append(task) + + # simple scheduler dependency: run the moc task before others + self.run_after.update(set(moctasks)) + self.moc_done = 1 + +class trans_update(Task.Task): + """Updates a .ts files from a list of C++ files""" + run_str = '${QT_LUPDATE} ${SRC} -ts ${TGT}' + color = 'BLUE' + +class XMLHandler(ContentHandler): + """ + Parses ``.qrc`` files + """ + def __init__(self): + ContentHandler.__init__(self) + self.buf = [] + self.files = [] + def startElement(self, name, attrs): + if name == 'file': + self.buf = [] + def endElement(self, name): + if name == 'file': + self.files.append(str(''.join(self.buf))) + def characters(self, cars): + self.buf.append(cars) + +@extension(*EXT_RCC) +def create_rcc_task(self, node): + "Creates rcc and cxx tasks for ``.qrc`` files" + rcnode = node.change_ext('_rc.%d.cpp' % self.idx) + self.create_task('rcc', node, rcnode) + cpptask = self.create_task('cxx', rcnode, rcnode.change_ext('.o')) + try: + self.compiled_tasks.append(cpptask) + except AttributeError: + self.compiled_tasks = [cpptask] + return cpptask + +@extension(*EXT_UI) +def create_uic_task(self, node): + "Create uic tasks for user interface ``.ui`` definition files" + + """ + If UIC file is used in more than one bld, we would have a conflict in parallel execution + It is not possible to change the file names (like .self.idx. as for objects) as they have + to be referenced by the source file, but we can assume that the transformation will be identical + and the tasks can be shared in a global cache. + """ + try: + uic_cache = self.bld.uic_cache + except AttributeError: + uic_cache = self.bld.uic_cache = {} + + if node not in uic_cache: + uictask = uic_cache[node] = self.create_task('ui5', node) + uictask.outputs = [node.parent.find_or_declare(self.env.ui_PATTERN % node.name[:-3])] + +@extension('.ts') +def add_lang(self, node): + """Adds all the .ts file into ``self.lang``""" + self.lang = self.to_list(getattr(self, 'lang', [])) + [node] + +@feature('qt5') +@before_method('process_source') +def process_mocs(self): + """ + Processes MOC files included in headers:: + + def build(bld): + bld.program(features='qt5', source='main.cpp', target='app', use='QT5CORE', moc='foo.h') + + The build will run moc on foo.h to create moc_foo.n.cpp. The number in the file name + is provided to avoid name clashes when the same headers are used by several targets. + """ + lst = self.to_nodes(getattr(self, 'moc', [])) + self.source = self.to_list(getattr(self, 'source', [])) + for x in lst: + prefix = x.name[:x.name.rfind('.')] # foo.h -> foo + moc_target = 'moc_%s.%d.cpp' % (prefix, self.idx) + moc_node = x.parent.find_or_declare(moc_target) + self.source.append(moc_node) + + self.create_task('moc', x, moc_node) + +@feature('qt5') +@after_method('apply_link') +def apply_qt5(self): + """ + Adds MOC_FLAGS which may be necessary for moc:: + + def build(bld): + bld.program(features='qt5', source='main.cpp', target='app', use='QT5CORE') + + The additional parameters are: + + :param lang: list of translation files (\\*.ts) to process + :type lang: list of :py:class:`waflib.Node.Node` or string without the .ts extension + :param update: whether to process the C++ files to update the \\*.ts files (use **waf --translate**) + :type update: bool + :param langname: if given, transform the \\*.ts files into a .qrc files to include in the binary file + :type langname: :py:class:`waflib.Node.Node` or string without the .qrc extension + """ + if getattr(self, 'lang', None): + qmtasks = [] + for x in self.to_list(self.lang): + if isinstance(x, str): + x = self.path.find_resource(x + '.ts') + qmtasks.append(self.create_task('ts2qm', x, x.change_ext('.%d.qm' % self.idx))) + + if getattr(self, 'update', None) and Options.options.trans_qt5: + cxxnodes = [a.inputs[0] for a in self.compiled_tasks] + [ + a.inputs[0] for a in self.tasks if a.inputs and a.inputs[0].name.endswith('.ui')] + for x in qmtasks: + self.create_task('trans_update', cxxnodes, x.inputs) + + if getattr(self, 'langname', None): + qmnodes = [x.outputs[0] for x in qmtasks] + rcnode = self.langname + if isinstance(rcnode, str): + rcnode = self.path.find_or_declare(rcnode + ('.%d.qrc' % self.idx)) + t = self.create_task('qm2rcc', qmnodes, rcnode) + k = create_rcc_task(self, t.outputs[0]) + self.link_task.inputs.append(k.outputs[0]) + + lst = [] + for flag in self.to_list(self.env.CXXFLAGS): + if len(flag) < 2: + continue + f = flag[0:2] + if f in ('-D', '-I', '/D', '/I'): + if (f[0] == '/'): + lst.append('-' + flag[1:]) + else: + lst.append(flag) + self.env.append_value('MOC_FLAGS', lst) + +@extension(*EXT_QT5) +def cxx_hook(self, node): + """ + Re-maps C++ file extensions to the :py:class:`waflib.Tools.qt5.qxx` task. + """ + return self.create_compiled_task('qxx', node) + +class rcc(Task.Task): + """ + Processes ``.qrc`` files + """ + color = 'BLUE' + run_str = '${QT_RCC} -name ${tsk.rcname()} ${SRC[0].abspath()} ${RCC_ST} -o ${TGT}' + ext_out = ['.h'] + + def rcname(self): + return os.path.splitext(self.inputs[0].name)[0] + + def scan(self): + """Parse the *.qrc* files""" + if not has_xml: + Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!') + return ([], []) + + parser = make_parser() + curHandler = XMLHandler() + parser.setContentHandler(curHandler) + with open(self.inputs[0].abspath(), 'r') as f: + parser.parse(f) + + nodes = [] + names = [] + root = self.inputs[0].parent + for x in curHandler.files: + nd = root.find_resource(x) + if nd: + nodes.append(nd) + else: + names.append(x) + return (nodes, names) + + def quote_flag(self, x): + """ + Override Task.quote_flag. QT parses the argument files + differently than cl.exe and link.exe + + :param x: flag + :type x: string + :return: quoted flag + :rtype: string + """ + return x + + +class moc(Task.Task): + """ + Creates ``.moc`` files + """ + color = 'BLUE' + run_str = '${QT_MOC} ${MOC_FLAGS} ${MOCCPPPATH_ST:INCPATHS} ${MOCDEFINES_ST:DEFINES} ${SRC} ${MOC_ST} ${TGT}' + + def quote_flag(self, x): + """ + Override Task.quote_flag. QT parses the argument files + differently than cl.exe and link.exe + + :param x: flag + :type x: string + :return: quoted flag + :rtype: string + """ + return x + + +class ui5(Task.Task): + """ + Processes ``.ui`` files + """ + color = 'BLUE' + run_str = '${QT_UIC} ${SRC} -o ${TGT}' + ext_out = ['.h'] + +class ts2qm(Task.Task): + """ + Generates ``.qm`` files from ``.ts`` files + """ + color = 'BLUE' + run_str = '${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}' + +class qm2rcc(Task.Task): + """ + Generates ``.qrc`` files from ``.qm`` files + """ + color = 'BLUE' + after = 'ts2qm' + def run(self): + """Create a qrc file including the inputs""" + txt = '\n'.join(['%s' % k.path_from(self.outputs[0].parent) for k in self.inputs]) + code = '\n\n%s\n\n' % txt + self.outputs[0].write(code) + +def configure(self): + """ + Besides the configuration options, the environment variable QT5_ROOT may be used + to give the location of the qt5 libraries (absolute path). + + The detection uses the program ``pkg-config`` through :py:func:`waflib.Tools.config_c.check_cfg` + """ + self.find_qt5_binaries() + self.set_qt5_libs_dir() + self.set_qt5_libs_to_check() + self.set_qt5_defines() + self.find_qt5_libraries() + self.add_qt5_rpath() + self.simplify_qt5_libs() + + # warn about this during the configuration too + if not has_xml: + Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!') + + if 'COMPILER_CXX' not in self.env: + self.fatal('No CXX compiler defined: did you forget to configure compiler_cxx first?') + + # Qt5 may be compiled with '-reduce-relocations' which requires dependent programs to have -fPIE or -fPIC? + frag = '#include \nint main(int argc, char **argv) {return 0;}\n' + uses = 'QT5CORE QT5WIDGETS QT5GUI' + for flag in [[], '-fPIE', '-fPIC', '-std=c++11' , ['-std=c++11', '-fPIE'], ['-std=c++11', '-fPIC']]: + msg = 'See if Qt files compile ' + if flag: + msg += 'with %s' % flag + try: + self.check(features='qt5 cxx', use=uses, uselib_store='qt5', cxxflags=flag, fragment=frag, msg=msg) + except self.errors.ConfigurationError: + pass + else: + break + else: + self.fatal('Could not build a simple Qt application') + + # FreeBSD does not add /usr/local/lib and the pkg-config files do not provide it either :-/ + if Utils.unversioned_sys_platform() == 'freebsd': + frag = '#include \nint main(int argc, char **argv) { QApplication app(argc, argv); return NULL != (void*) (&app);}\n' + try: + self.check(features='qt5 cxx cxxprogram', use=uses, fragment=frag, msg='Can we link Qt programs on FreeBSD directly?') + except self.errors.ConfigurationError: + self.check(features='qt5 cxx cxxprogram', use=uses, uselib_store='qt5', libpath='/usr/local/lib', fragment=frag, msg='Is /usr/local/lib required?') + +@conf +def find_qt5_binaries(self): + """ + Detects Qt programs such as qmake, moc, uic, lrelease + """ + env = self.env + opt = Options.options + + qtdir = getattr(opt, 'qtdir', '') + qtbin = getattr(opt, 'qtbin', '') + + paths = [] + + if qtdir: + qtbin = os.path.join(qtdir, 'bin') + + # the qt directory has been given from QT5_ROOT - deduce the qt binary path + if not qtdir: + qtdir = self.environ.get('QT5_ROOT', '') + qtbin = self.environ.get('QT5_BIN') or os.path.join(qtdir, 'bin') + + if qtbin: + paths = [qtbin] + + # no qtdir, look in the path and in /usr/local/Trolltech + if not qtdir: + paths = self.environ.get('PATH', '').split(os.pathsep) + paths.extend(['/usr/share/qt5/bin', '/usr/local/lib/qt5/bin']) + try: + lst = Utils.listdir('/usr/local/Trolltech/') + except OSError: + pass + else: + if lst: + lst.sort() + lst.reverse() + + # keep the highest version + qtdir = '/usr/local/Trolltech/%s/' % lst[0] + qtbin = os.path.join(qtdir, 'bin') + paths.append(qtbin) + + # at the end, try to find qmake in the paths given + # keep the one with the highest version + cand = None + prev_ver = ['5', '0', '0'] + for qmk in ('qmake-qt5', 'qmake5', 'qmake'): + try: + qmake = self.find_program(qmk, path_list=paths) + except self.errors.ConfigurationError: + pass + else: + try: + version = self.cmd_and_log(qmake + ['-query', 'QT_VERSION']).strip() + except self.errors.WafError: + pass + else: + if version: + new_ver = version.split('.') + if new_ver > prev_ver: + cand = qmake + prev_ver = new_ver + + # qmake could not be found easily, rely on qtchooser + if not cand: + try: + self.find_program('qtchooser') + except self.errors.ConfigurationError: + pass + else: + cmd = self.env.QTCHOOSER + ['-qt=5', '-run-tool=qmake'] + try: + version = self.cmd_and_log(cmd + ['-query', 'QT_VERSION']) + except self.errors.WafError: + pass + else: + cand = cmd + + if cand: + self.env.QMAKE = cand + else: + self.fatal('Could not find qmake for qt5') + + self.env.QT_HOST_BINS = qtbin = self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_HOST_BINS']).strip() + paths.insert(0, qtbin) + + def find_bin(lst, var): + if var in env: + return + for f in lst: + try: + ret = self.find_program(f, path_list=paths) + except self.errors.ConfigurationError: + pass + else: + env[var]=ret + break + + find_bin(['uic-qt5', 'uic'], 'QT_UIC') + if not env.QT_UIC: + self.fatal('cannot find the uic compiler for qt5') + + self.start_msg('Checking for uic version') + uicver = self.cmd_and_log(env.QT_UIC + ['-version'], output=Context.BOTH) + uicver = ''.join(uicver).strip() + uicver = uicver.replace('Qt User Interface Compiler ','').replace('User Interface Compiler for Qt', '') + self.end_msg(uicver) + if uicver.find(' 3.') != -1 or uicver.find(' 4.') != -1: + self.fatal('this uic compiler is for qt3 or qt4, add uic for qt5 to your path') + + find_bin(['moc-qt5', 'moc'], 'QT_MOC') + find_bin(['rcc-qt5', 'rcc'], 'QT_RCC') + find_bin(['lrelease-qt5', 'lrelease'], 'QT_LRELEASE') + find_bin(['lupdate-qt5', 'lupdate'], 'QT_LUPDATE') + + env.UIC_ST = '%s -o %s' + env.MOC_ST = '-o' + env.ui_PATTERN = 'ui_%s.h' + env.QT_LRELEASE_FLAGS = ['-silent'] + env.MOCCPPPATH_ST = '-I%s' + env.MOCDEFINES_ST = '-D%s' + +@conf +def set_qt5_libs_dir(self): + env = self.env + qtlibs = getattr(Options.options, 'qtlibs', None) or self.environ.get('QT5_LIBDIR') + if not qtlibs: + try: + qtlibs = self.cmd_and_log(env.QMAKE + ['-query', 'QT_INSTALL_LIBS']).strip() + except Errors.WafError: + qtdir = self.cmd_and_log(env.QMAKE + ['-query', 'QT_INSTALL_PREFIX']).strip() + qtlibs = os.path.join(qtdir, 'lib') + self.msg('Found the Qt5 libraries in', qtlibs) + env.QTLIBS = qtlibs + +@conf +def find_single_qt5_lib(self, name, uselib, qtlibs, qtincludes, force_static): + env = self.env + if force_static: + exts = ('.a', '.lib') + prefix = 'STLIB' + else: + exts = ('.so', '.lib') + prefix = 'LIB' + + def lib_names(): + for x in exts: + for k in ('', '5') if Utils.is_win32 else ['']: + for p in ('lib', ''): + yield (p, name, k, x) + + for tup in lib_names(): + k = ''.join(tup) + path = os.path.join(qtlibs, k) + if os.path.exists(path): + if env.DEST_OS == 'win32': + libval = ''.join(tup[:-1]) + else: + libval = name + env.append_unique(prefix + '_' + uselib, libval) + env.append_unique('%sPATH_%s' % (prefix, uselib), qtlibs) + env.append_unique('INCLUDES_' + uselib, qtincludes) + env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, name.replace('Qt5', 'Qt'))) + return k + return False + +@conf +def find_qt5_libraries(self): + env = self.env + + qtincludes = self.environ.get('QT5_INCLUDES') or self.cmd_and_log(env.QMAKE + ['-query', 'QT_INSTALL_HEADERS']).strip() + force_static = self.environ.get('QT5_FORCE_STATIC') + try: + if self.environ.get('QT5_XCOMPILE'): + self.fatal('QT5_XCOMPILE Disables pkg-config detection') + self.check_cfg(atleast_pkgconfig_version='0.1') + except self.errors.ConfigurationError: + for i in self.qt5_vars: + uselib = i.upper() + if Utils.unversioned_sys_platform() == 'darwin': + # Since at least qt 4.7.3 each library locates in separate directory + fwk = i.replace('Qt5', 'Qt') + frameworkName = fwk + '.framework' + + qtDynamicLib = os.path.join(env.QTLIBS, frameworkName, fwk) + if os.path.exists(qtDynamicLib): + env.append_unique('FRAMEWORK_' + uselib, fwk) + env.append_unique('FRAMEWORKPATH_' + uselib, env.QTLIBS) + self.msg('Checking for %s' % i, qtDynamicLib, 'GREEN') + else: + self.msg('Checking for %s' % i, False, 'YELLOW') + env.append_unique('INCLUDES_' + uselib, os.path.join(env.QTLIBS, frameworkName, 'Headers')) + else: + ret = self.find_single_qt5_lib(i, uselib, env.QTLIBS, qtincludes, force_static) + if not force_static and not ret: + ret = self.find_single_qt5_lib(i, uselib, env.QTLIBS, qtincludes, True) + self.msg('Checking for %s' % i, ret, 'GREEN' if ret else 'YELLOW') + else: + path = '%s:%s:%s/pkgconfig:/usr/lib/qt5/lib/pkgconfig:/opt/qt5/lib/pkgconfig:/usr/lib/qt5/lib:/opt/qt5/lib' % ( + self.environ.get('PKG_CONFIG_PATH', ''), env.QTLIBS, env.QTLIBS) + for i in self.qt5_vars: + self.check_cfg(package=i, args='--cflags --libs', mandatory=False, force_static=force_static, pkg_config_path=path) + +@conf +def simplify_qt5_libs(self): + """ + Since library paths make really long command-lines, + and since everything depends on qtcore, remove the qtcore ones from qtgui, etc + """ + env = self.env + def process_lib(vars_, coreval): + for d in vars_: + var = d.upper() + if var == 'QTCORE': + continue + + value = env['LIBPATH_'+var] + if value: + core = env[coreval] + accu = [] + for lib in value: + if lib in core: + continue + accu.append(lib) + env['LIBPATH_'+var] = accu + process_lib(self.qt5_vars, 'LIBPATH_QTCORE') + +@conf +def add_qt5_rpath(self): + """ + Defines rpath entries for Qt libraries + """ + env = self.env + if getattr(Options.options, 'want_rpath', False): + def process_rpath(vars_, coreval): + for d in vars_: + var = d.upper() + value = env['LIBPATH_' + var] + if value: + core = env[coreval] + accu = [] + for lib in value: + if var != 'QTCORE': + if lib in core: + continue + accu.append('-Wl,--rpath='+lib) + env['RPATH_' + var] = accu + process_rpath(self.qt5_vars, 'LIBPATH_QTCORE') + +@conf +def set_qt5_libs_to_check(self): + self.qt5_vars = Utils.to_list(getattr(self, 'qt5_vars', [])) + if not self.qt5_vars: + dirlst = Utils.listdir(self.env.QTLIBS) + + pat = self.env.cxxshlib_PATTERN + if Utils.is_win32: + pat = pat.replace('.dll', '.lib') + if self.environ.get('QT5_FORCE_STATIC'): + pat = self.env.cxxstlib_PATTERN + if Utils.unversioned_sys_platform() == 'darwin': + pat = r"%s\.framework" + re_qt = re.compile(pat%'Qt5?(?P.*)'+'$') + for x in dirlst: + m = re_qt.match(x) + if m: + self.qt5_vars.append("Qt5%s" % m.group('name')) + if not self.qt5_vars: + self.fatal('cannot find any Qt5 library (%r)' % self.env.QTLIBS) + + qtextralibs = getattr(Options.options, 'qtextralibs', None) + if qtextralibs: + self.qt5_vars.extend(qtextralibs.split(',')) + +@conf +def set_qt5_defines(self): + if sys.platform != 'win32': + return + for x in self.qt5_vars: + y=x.replace('Qt5', 'Qt')[2:].upper() + self.env.append_unique('DEFINES_%s' % x.upper(), 'QT_%s_LIB' % y) + +def options(opt): + """ + Command-line options + """ + opt.add_option('--want-rpath', action='store_true', default=False, dest='want_rpath', help='enable the rpath for qt libraries') + for i in 'qtdir qtbin qtlibs'.split(): + opt.add_option('--'+i, type='string', default='', dest=i) + + opt.add_option('--translate', action='store_true', help='collect translation strings', dest='trans_qt5', default=False) + opt.add_option('--qtextralibs', type='string', default='', dest='qtextralibs', help='additional qt libraries on the system to add to default ones, comma separated') + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/ruby.py b/ldb-2.0.8/third_party/waf/waflib/Tools/ruby.py new file mode 100644 index 0000000..8d92a79 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/ruby.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python +# encoding: utf-8 +# daniel.svensson at purplescout.se 2008 +# Thomas Nagy 2016-2018 (ita) + +""" +Support for Ruby extensions. A C/C++ compiler is required:: + + def options(opt): + opt.load('compiler_c ruby') + def configure(conf): + conf.load('compiler_c ruby') + conf.check_ruby_version((1,8,0)) + conf.check_ruby_ext_devel() + conf.check_ruby_module('libxml') + def build(bld): + bld( + features = 'c cshlib rubyext', + source = 'rb_mytest.c', + target = 'mytest_ext', + install_path = '${ARCHDIR_RUBY}') + bld.install_files('${LIBDIR_RUBY}', 'Mytest.rb') +""" + +import os +from waflib import Errors, Options, Task, Utils +from waflib.TaskGen import before_method, feature, extension +from waflib.Configure import conf + +@feature('rubyext') +@before_method('apply_incpaths', 'process_source', 'apply_bundle', 'apply_link') +def init_rubyext(self): + """ + Add required variables for ruby extensions + """ + self.install_path = '${ARCHDIR_RUBY}' + self.uselib = self.to_list(getattr(self, 'uselib', '')) + if not 'RUBY' in self.uselib: + self.uselib.append('RUBY') + if not 'RUBYEXT' in self.uselib: + self.uselib.append('RUBYEXT') + +@feature('rubyext') +@before_method('apply_link', 'propagate_uselib_vars') +def apply_ruby_so_name(self): + """ + Strip the *lib* prefix from ruby extensions + """ + self.env.cshlib_PATTERN = self.env.cxxshlib_PATTERN = self.env.rubyext_PATTERN + +@conf +def check_ruby_version(self, minver=()): + """ + Checks if ruby is installed. + If installed the variable RUBY will be set in environment. + The ruby binary can be overridden by ``--with-ruby-binary`` command-line option. + """ + + ruby = self.find_program('ruby', var='RUBY', value=Options.options.rubybinary) + + try: + version = self.cmd_and_log(ruby + ['-e', 'puts defined?(VERSION) ? VERSION : RUBY_VERSION']).strip() + except Errors.WafError: + self.fatal('could not determine ruby version') + self.env.RUBY_VERSION = version + + try: + ver = tuple(map(int, version.split('.'))) + except Errors.WafError: + self.fatal('unsupported ruby version %r' % version) + + cver = '' + if minver: + cver = '> ' + '.'.join(str(x) for x in minver) + if ver < minver: + self.fatal('ruby is too old %r' % ver) + + self.msg('Checking for ruby version %s' % cver, version) + +@conf +def check_ruby_ext_devel(self): + """ + Check if a ruby extension can be created + """ + if not self.env.RUBY: + self.fatal('ruby detection is required first') + + if not self.env.CC_NAME and not self.env.CXX_NAME: + self.fatal('load a c/c++ compiler first') + + version = tuple(map(int, self.env.RUBY_VERSION.split("."))) + + def read_out(cmd): + return Utils.to_list(self.cmd_and_log(self.env.RUBY + ['-rrbconfig', '-e', cmd])) + + def read_config(key): + return read_out('puts RbConfig::CONFIG[%r]' % key) + + cpppath = archdir = read_config('archdir') + + if version >= (1, 9, 0): + ruby_hdrdir = read_config('rubyhdrdir') + cpppath += ruby_hdrdir + if version >= (2, 0, 0): + cpppath += read_config('rubyarchhdrdir') + cpppath += [os.path.join(ruby_hdrdir[0], read_config('arch')[0])] + + self.check(header_name='ruby.h', includes=cpppath, errmsg='could not find ruby header file', link_header_test=False) + + self.env.LIBPATH_RUBYEXT = read_config('libdir') + self.env.LIBPATH_RUBYEXT += archdir + self.env.INCLUDES_RUBYEXT = cpppath + self.env.CFLAGS_RUBYEXT = read_config('CCDLFLAGS') + self.env.rubyext_PATTERN = '%s.' + read_config('DLEXT')[0] + + # ok this is really stupid, but the command and flags are combined. + # so we try to find the first argument... + flags = read_config('LDSHARED') + while flags and flags[0][0] != '-': + flags = flags[1:] + + # we also want to strip out the deprecated ppc flags + if len(flags) > 1 and flags[1] == "ppc": + flags = flags[2:] + + self.env.LINKFLAGS_RUBYEXT = flags + self.env.LINKFLAGS_RUBYEXT += read_config('LIBS') + self.env.LINKFLAGS_RUBYEXT += read_config('LIBRUBYARG_SHARED') + + if Options.options.rubyarchdir: + self.env.ARCHDIR_RUBY = Options.options.rubyarchdir + else: + self.env.ARCHDIR_RUBY = read_config('sitearchdir')[0] + + if Options.options.rubylibdir: + self.env.LIBDIR_RUBY = Options.options.rubylibdir + else: + self.env.LIBDIR_RUBY = read_config('sitelibdir')[0] + +@conf +def check_ruby_module(self, module_name): + """ + Check if the selected ruby interpreter can require the given ruby module:: + + def configure(conf): + conf.check_ruby_module('libxml') + + :param module_name: module + :type module_name: string + """ + self.start_msg('Ruby module %s' % module_name) + try: + self.cmd_and_log(self.env.RUBY + ['-e', 'require \'%s\';puts 1' % module_name]) + except Errors.WafError: + self.end_msg(False) + self.fatal('Could not find the ruby module %r' % module_name) + self.end_msg(True) + +@extension('.rb') +def process(self, node): + return self.create_task('run_ruby', node) + +class run_ruby(Task.Task): + """ + Task to run ruby files detected by file extension .rb:: + + def options(opt): + opt.load('ruby') + + def configure(ctx): + ctx.check_ruby_version() + + def build(bld): + bld.env.RBFLAGS = '-e puts "hello world"' + bld(source='a_ruby_file.rb') + """ + run_str = '${RUBY} ${RBFLAGS} -I ${SRC[0].parent.abspath()} ${SRC}' + +def options(opt): + """ + Add the ``--with-ruby-archdir``, ``--with-ruby-libdir`` and ``--with-ruby-binary`` options + """ + opt.add_option('--with-ruby-archdir', type='string', dest='rubyarchdir', help='Specify directory where to install arch specific files') + opt.add_option('--with-ruby-libdir', type='string', dest='rubylibdir', help='Specify alternate ruby library path') + opt.add_option('--with-ruby-binary', type='string', dest='rubybinary', help='Specify alternate ruby binary') + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/suncc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/suncc.py new file mode 100644 index 0000000..33d34fc --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/suncc.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2006-2018 (ita) +# Ralf Habacker, 2006 (rh) + +from waflib import Errors +from waflib.Tools import ccroot, ar +from waflib.Configure import conf + +@conf +def find_scc(conf): + """ + Detects the Sun C compiler + """ + v = conf.env + cc = conf.find_program('cc', var='CC') + try: + conf.cmd_and_log(cc + ['-flags']) + except Errors.WafError: + conf.fatal('%r is not a Sun compiler' % cc) + v.CC_NAME = 'sun' + conf.get_suncc_version(cc) + +@conf +def scc_common_flags(conf): + """ + Flags required for executing the sun C compiler + """ + v = conf.env + + v.CC_SRC_F = [] + v.CC_TGT_F = ['-c', '-o', ''] + + if not v.LINK_CC: + v.LINK_CC = v.CC + + v.CCLNK_SRC_F = '' + v.CCLNK_TGT_F = ['-o', ''] + v.CPPPATH_ST = '-I%s' + v.DEFINES_ST = '-D%s' + + v.LIB_ST = '-l%s' # template for adding libs + v.LIBPATH_ST = '-L%s' # template for adding libpaths + v.STLIB_ST = '-l%s' + v.STLIBPATH_ST = '-L%s' + + v.SONAME_ST = '-Wl,-h,%s' + v.SHLIB_MARKER = '-Bdynamic' + v.STLIB_MARKER = '-Bstatic' + + v.cprogram_PATTERN = '%s' + + v.CFLAGS_cshlib = ['-xcode=pic32', '-DPIC'] + v.LINKFLAGS_cshlib = ['-G'] + v.cshlib_PATTERN = 'lib%s.so' + + v.LINKFLAGS_cstlib = ['-Bstatic'] + v.cstlib_PATTERN = 'lib%s.a' + +def configure(conf): + conf.find_scc() + conf.find_ar() + conf.scc_common_flags() + conf.cc_load_tools() + conf.cc_add_flags() + conf.link_add_flags() + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/suncxx.py b/ldb-2.0.8/third_party/waf/waflib/Tools/suncxx.py new file mode 100644 index 0000000..3b384f6 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/suncxx.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2006-2018 (ita) +# Ralf Habacker, 2006 (rh) + +from waflib import Errors +from waflib.Tools import ccroot, ar +from waflib.Configure import conf + +@conf +def find_sxx(conf): + """ + Detects the sun C++ compiler + """ + v = conf.env + cc = conf.find_program(['CC', 'c++'], var='CXX') + try: + conf.cmd_and_log(cc + ['-flags']) + except Errors.WafError: + conf.fatal('%r is not a Sun compiler' % cc) + v.CXX_NAME = 'sun' + conf.get_suncc_version(cc) + +@conf +def sxx_common_flags(conf): + """ + Flags required for executing the sun C++ compiler + """ + v = conf.env + + v.CXX_SRC_F = [] + v.CXX_TGT_F = ['-c', '-o', ''] + + if not v.LINK_CXX: + v.LINK_CXX = v.CXX + + v.CXXLNK_SRC_F = [] + v.CXXLNK_TGT_F = ['-o', ''] + v.CPPPATH_ST = '-I%s' + v.DEFINES_ST = '-D%s' + + v.LIB_ST = '-l%s' # template for adding libs + v.LIBPATH_ST = '-L%s' # template for adding libpaths + v.STLIB_ST = '-l%s' + v.STLIBPATH_ST = '-L%s' + + v.SONAME_ST = '-Wl,-h,%s' + v.SHLIB_MARKER = '-Bdynamic' + v.STLIB_MARKER = '-Bstatic' + + v.cxxprogram_PATTERN = '%s' + + v.CXXFLAGS_cxxshlib = ['-xcode=pic32', '-DPIC'] + v.LINKFLAGS_cxxshlib = ['-G'] + v.cxxshlib_PATTERN = 'lib%s.so' + + v.LINKFLAGS_cxxstlib = ['-Bstatic'] + v.cxxstlib_PATTERN = 'lib%s.a' + +def configure(conf): + conf.find_sxx() + conf.find_ar() + conf.sxx_common_flags() + conf.cxx_load_tools() + conf.cxx_add_flags() + conf.link_add_flags() + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/tex.py b/ldb-2.0.8/third_party/waf/waflib/Tools/tex.py new file mode 100644 index 0000000..eaf9fdb --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/tex.py @@ -0,0 +1,543 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2006-2018 (ita) + +""" +TeX/LaTeX/PDFLaTeX/XeLaTeX support + +Example:: + + def configure(conf): + conf.load('tex') + if not conf.env.LATEX: + conf.fatal('The program LaTex is required') + + def build(bld): + bld( + features = 'tex', + type = 'latex', # pdflatex or xelatex + source = 'document.ltx', # mandatory, the source + outs = 'ps', # 'pdf' or 'ps pdf' + deps = 'crossreferencing.lst', # to give dependencies directly + prompt = 1, # 0 for the batch mode + ) + +Notes: + +- To configure with a special program, use:: + + $ PDFLATEX=luatex waf configure + +- This tool does not use the target attribute of the task generator + (``bld(target=...)``); the target file name is built from the source + base name and the output type(s) +""" + +import os, re +from waflib import Utils, Task, Errors, Logs, Node +from waflib.TaskGen import feature, before_method + +re_bibunit = re.compile(r'\\(?Pputbib)\[(?P[^\[\]]*)\]',re.M) +def bibunitscan(self): + """ + Parses TeX inputs and try to find the *bibunit* file dependencies + + :return: list of bibunit files + :rtype: list of :py:class:`waflib.Node.Node` + """ + node = self.inputs[0] + + nodes = [] + if not node: + return nodes + + code = node.read() + for match in re_bibunit.finditer(code): + path = match.group('file') + if path: + found = None + for k in ('', '.bib'): + # add another loop for the tex include paths? + Logs.debug('tex: trying %s%s', path, k) + fi = node.parent.find_resource(path + k) + if fi: + found = True + nodes.append(fi) + # no break + if not found: + Logs.debug('tex: could not find %s', path) + + Logs.debug('tex: found the following bibunit files: %s', nodes) + return nodes + +exts_deps_tex = ['', '.ltx', '.tex', '.bib', '.pdf', '.png', '.eps', '.ps', '.sty'] +"""List of typical file extensions included in latex files""" + +exts_tex = ['.ltx', '.tex'] +"""List of typical file extensions that contain latex""" + +re_tex = re.compile(r'\\(?Pusepackage|RequirePackage|include|bibliography([^\[\]{}]*)|putbib|includegraphics|input|import|bringin|lstinputlisting)(\[[^\[\]]*\])?{(?P[^{}]*)}',re.M) +"""Regexp for expressions that may include latex files""" + +g_bibtex_re = re.compile('bibdata', re.M) +"""Regexp for bibtex files""" + +g_glossaries_re = re.compile('\\@newglossary', re.M) +"""Regexp for expressions that create glossaries""" + +class tex(Task.Task): + """ + Compiles a tex/latex file. + + .. inheritance-diagram:: waflib.Tools.tex.latex waflib.Tools.tex.xelatex waflib.Tools.tex.pdflatex + """ + + bibtex_fun, _ = Task.compile_fun('${BIBTEX} ${BIBTEXFLAGS} ${SRCFILE}', shell=False) + bibtex_fun.__doc__ = """ + Execute the program **bibtex** + """ + + makeindex_fun, _ = Task.compile_fun('${MAKEINDEX} ${MAKEINDEXFLAGS} ${SRCFILE}', shell=False) + makeindex_fun.__doc__ = """ + Execute the program **makeindex** + """ + + makeglossaries_fun, _ = Task.compile_fun('${MAKEGLOSSARIES} ${SRCFILE}', shell=False) + makeglossaries_fun.__doc__ = """ + Execute the program **makeglossaries** + """ + + def exec_command(self, cmd, **kw): + """ + Executes TeX commands without buffering (latex may prompt for inputs) + + :return: the return code + :rtype: int + """ + if self.env.PROMPT_LATEX: + # capture the outputs in configuration tests + kw['stdout'] = kw['stderr'] = None + return super(tex, self).exec_command(cmd, **kw) + + def scan_aux(self, node): + """ + Recursive regex-based scanner that finds included auxiliary files. + """ + nodes = [node] + re_aux = re.compile(r'\\@input{(?P[^{}]*)}', re.M) + + def parse_node(node): + code = node.read() + for match in re_aux.finditer(code): + path = match.group('file') + found = node.parent.find_or_declare(path) + if found and found not in nodes: + Logs.debug('tex: found aux node %r', found) + nodes.append(found) + parse_node(found) + parse_node(node) + return nodes + + def scan(self): + """ + Recursive regex-based scanner that finds latex dependencies. It uses :py:attr:`waflib.Tools.tex.re_tex` + + Depending on your needs you might want: + + * to change re_tex:: + + from waflib.Tools import tex + tex.re_tex = myregex + + * or to change the method scan from the latex tasks:: + + from waflib.Task import classes + classes['latex'].scan = myscanfunction + """ + node = self.inputs[0] + + nodes = [] + names = [] + seen = [] + if not node: + return (nodes, names) + + def parse_node(node): + if node in seen: + return + seen.append(node) + code = node.read() + for match in re_tex.finditer(code): + + multibib = match.group('type') + if multibib and multibib.startswith('bibliography'): + multibib = multibib[len('bibliography'):] + if multibib.startswith('style'): + continue + else: + multibib = None + + for path in match.group('file').split(','): + if path: + add_name = True + found = None + for k in exts_deps_tex: + + # issue 1067, scan in all texinputs folders + for up in self.texinputs_nodes: + Logs.debug('tex: trying %s%s', path, k) + found = up.find_resource(path + k) + if found: + break + + + for tsk in self.generator.tasks: + if not found or found in tsk.outputs: + break + else: + nodes.append(found) + add_name = False + for ext in exts_tex: + if found.name.endswith(ext): + parse_node(found) + break + + # multibib stuff + if found and multibib and found.name.endswith('.bib'): + try: + self.multibibs.append(found) + except AttributeError: + self.multibibs = [found] + + # no break, people are crazy + if add_name: + names.append(path) + parse_node(node) + + for x in nodes: + x.parent.get_bld().mkdir() + + Logs.debug("tex: found the following : %s and names %s", nodes, names) + return (nodes, names) + + def check_status(self, msg, retcode): + """ + Checks an exit status and raise an error with a particular message + + :param msg: message to display if the code is non-zero + :type msg: string + :param retcode: condition + :type retcode: boolean + """ + if retcode != 0: + raise Errors.WafError('%r command exit status %r' % (msg, retcode)) + + def info(self, *k, **kw): + try: + info = self.generator.bld.conf.logger.info + except AttributeError: + info = Logs.info + info(*k, **kw) + + def bibfile(self): + """ + Parses *.aux* files to find bibfiles to process. + If present, execute :py:meth:`waflib.Tools.tex.tex.bibtex_fun` + """ + for aux_node in self.aux_nodes: + try: + ct = aux_node.read() + except EnvironmentError: + Logs.error('Error reading %s: %r', aux_node.abspath()) + continue + + if g_bibtex_re.findall(ct): + self.info('calling bibtex') + + self.env.env = {} + self.env.env.update(os.environ) + self.env.env.update({'BIBINPUTS': self.texinputs(), 'BSTINPUTS': self.texinputs()}) + self.env.SRCFILE = aux_node.name[:-4] + self.check_status('error when calling bibtex', self.bibtex_fun()) + + for node in getattr(self, 'multibibs', []): + self.env.env = {} + self.env.env.update(os.environ) + self.env.env.update({'BIBINPUTS': self.texinputs(), 'BSTINPUTS': self.texinputs()}) + self.env.SRCFILE = node.name[:-4] + self.check_status('error when calling bibtex', self.bibtex_fun()) + + def bibunits(self): + """ + Parses *.aux* file to find bibunit files. If there are bibunit files, + runs :py:meth:`waflib.Tools.tex.tex.bibtex_fun`. + """ + try: + bibunits = bibunitscan(self) + except OSError: + Logs.error('error bibunitscan') + else: + if bibunits: + fn = ['bu' + str(i) for i in range(1, len(bibunits) + 1)] + if fn: + self.info('calling bibtex on bibunits') + + for f in fn: + self.env.env = {'BIBINPUTS': self.texinputs(), 'BSTINPUTS': self.texinputs()} + self.env.SRCFILE = f + self.check_status('error when calling bibtex', self.bibtex_fun()) + + def makeindex(self): + """ + Searches the filesystem for *.idx* files to process. If present, + runs :py:meth:`waflib.Tools.tex.tex.makeindex_fun` + """ + self.idx_node = self.inputs[0].change_ext('.idx') + try: + idx_path = self.idx_node.abspath() + os.stat(idx_path) + except OSError: + self.info('index file %s absent, not calling makeindex', idx_path) + else: + self.info('calling makeindex') + + self.env.SRCFILE = self.idx_node.name + self.env.env = {} + self.check_status('error when calling makeindex %s' % idx_path, self.makeindex_fun()) + + def bibtopic(self): + """ + Lists additional .aux files from the bibtopic package + """ + p = self.inputs[0].parent.get_bld() + if os.path.exists(os.path.join(p.abspath(), 'btaux.aux')): + self.aux_nodes += p.ant_glob('*[0-9].aux') + + def makeglossaries(self): + """ + Lists additional glossaries from .aux files. If present, runs the makeglossaries program. + """ + src_file = self.inputs[0].abspath() + base_file = os.path.basename(src_file) + base, _ = os.path.splitext(base_file) + for aux_node in self.aux_nodes: + try: + ct = aux_node.read() + except EnvironmentError: + Logs.error('Error reading %s: %r', aux_node.abspath()) + continue + + if g_glossaries_re.findall(ct): + if not self.env.MAKEGLOSSARIES: + raise Errors.WafError("The program 'makeglossaries' is missing!") + Logs.warn('calling makeglossaries') + self.env.SRCFILE = base + self.check_status('error when calling makeglossaries %s' % base, self.makeglossaries_fun()) + return + + def texinputs(self): + """ + Returns the list of texinput nodes as a string suitable for the TEXINPUTS environment variables + + :rtype: string + """ + return os.pathsep.join([k.abspath() for k in self.texinputs_nodes]) + os.pathsep + + def run(self): + """ + Runs the whole TeX build process + + Multiple passes are required depending on the usage of cross-references, + bibliographies, glossaries, indexes and additional contents + The appropriate TeX compiler is called until the *.aux* files stop changing. + """ + env = self.env + + if not env.PROMPT_LATEX: + env.append_value('LATEXFLAGS', '-interaction=batchmode') + env.append_value('PDFLATEXFLAGS', '-interaction=batchmode') + env.append_value('XELATEXFLAGS', '-interaction=batchmode') + + # important, set the cwd for everybody + self.cwd = self.inputs[0].parent.get_bld() + + self.info('first pass on %s', self.__class__.__name__) + + # Hash .aux files before even calling the LaTeX compiler + cur_hash = self.hash_aux_nodes() + + self.call_latex() + + # Find the .aux files again since bibtex processing can require it + self.hash_aux_nodes() + + self.bibtopic() + self.bibfile() + self.bibunits() + self.makeindex() + self.makeglossaries() + + for i in range(10): + # There is no need to call latex again if the .aux hash value has not changed + prev_hash = cur_hash + cur_hash = self.hash_aux_nodes() + if not cur_hash: + Logs.error('No aux.h to process') + if cur_hash and cur_hash == prev_hash: + break + + # run the command + self.info('calling %s', self.__class__.__name__) + self.call_latex() + + def hash_aux_nodes(self): + """ + Returns a hash of the .aux file contents + + :rtype: string or bytes + """ + try: + self.aux_nodes + except AttributeError: + try: + self.aux_nodes = self.scan_aux(self.inputs[0].change_ext('.aux')) + except IOError: + return None + return Utils.h_list([Utils.h_file(x.abspath()) for x in self.aux_nodes]) + + def call_latex(self): + """ + Runs the TeX compiler once + """ + self.env.env = {} + self.env.env.update(os.environ) + self.env.env.update({'TEXINPUTS': self.texinputs()}) + self.env.SRCFILE = self.inputs[0].abspath() + self.check_status('error when calling latex', self.texfun()) + +class latex(tex): + "Compiles LaTeX files" + texfun, vars = Task.compile_fun('${LATEX} ${LATEXFLAGS} ${SRCFILE}', shell=False) + +class pdflatex(tex): + "Compiles PdfLaTeX files" + texfun, vars = Task.compile_fun('${PDFLATEX} ${PDFLATEXFLAGS} ${SRCFILE}', shell=False) + +class xelatex(tex): + "XeLaTeX files" + texfun, vars = Task.compile_fun('${XELATEX} ${XELATEXFLAGS} ${SRCFILE}', shell=False) + +class dvips(Task.Task): + "Converts dvi files to postscript" + run_str = '${DVIPS} ${DVIPSFLAGS} ${SRC} -o ${TGT}' + color = 'BLUE' + after = ['latex', 'pdflatex', 'xelatex'] + +class dvipdf(Task.Task): + "Converts dvi files to pdf" + run_str = '${DVIPDF} ${DVIPDFFLAGS} ${SRC} ${TGT}' + color = 'BLUE' + after = ['latex', 'pdflatex', 'xelatex'] + +class pdf2ps(Task.Task): + "Converts pdf files to postscript" + run_str = '${PDF2PS} ${PDF2PSFLAGS} ${SRC} ${TGT}' + color = 'BLUE' + after = ['latex', 'pdflatex', 'xelatex'] + +@feature('tex') +@before_method('process_source') +def apply_tex(self): + """ + Creates :py:class:`waflib.Tools.tex.tex` objects, and + dvips/dvipdf/pdf2ps tasks if necessary (outs='ps', etc). + """ + if not getattr(self, 'type', None) in ('latex', 'pdflatex', 'xelatex'): + self.type = 'pdflatex' + + outs = Utils.to_list(getattr(self, 'outs', [])) + + # prompt for incomplete files (else the batchmode is used) + try: + self.generator.bld.conf + except AttributeError: + default_prompt = False + else: + default_prompt = True + self.env.PROMPT_LATEX = getattr(self, 'prompt', default_prompt) + + deps_lst = [] + + if getattr(self, 'deps', None): + deps = self.to_list(self.deps) + for dep in deps: + if isinstance(dep, str): + n = self.path.find_resource(dep) + if not n: + self.bld.fatal('Could not find %r for %r' % (dep, self)) + if not n in deps_lst: + deps_lst.append(n) + elif isinstance(dep, Node.Node): + deps_lst.append(dep) + + for node in self.to_nodes(self.source): + if self.type == 'latex': + task = self.create_task('latex', node, node.change_ext('.dvi')) + elif self.type == 'pdflatex': + task = self.create_task('pdflatex', node, node.change_ext('.pdf')) + elif self.type == 'xelatex': + task = self.create_task('xelatex', node, node.change_ext('.pdf')) + + task.env = self.env + + # add the manual dependencies + if deps_lst: + for n in deps_lst: + if not n in task.dep_nodes: + task.dep_nodes.append(n) + + # texinputs is a nasty beast + if hasattr(self, 'texinputs_nodes'): + task.texinputs_nodes = self.texinputs_nodes + else: + task.texinputs_nodes = [node.parent, node.parent.get_bld(), self.path, self.path.get_bld()] + lst = os.environ.get('TEXINPUTS', '') + if self.env.TEXINPUTS: + lst += os.pathsep + self.env.TEXINPUTS + if lst: + lst = lst.split(os.pathsep) + for x in lst: + if x: + if os.path.isabs(x): + p = self.bld.root.find_node(x) + if p: + task.texinputs_nodes.append(p) + else: + Logs.error('Invalid TEXINPUTS folder %s', x) + else: + Logs.error('Cannot resolve relative paths in TEXINPUTS %s', x) + + if self.type == 'latex': + if 'ps' in outs: + tsk = self.create_task('dvips', task.outputs, node.change_ext('.ps')) + tsk.env.env = dict(os.environ) + if 'pdf' in outs: + tsk = self.create_task('dvipdf', task.outputs, node.change_ext('.pdf')) + tsk.env.env = dict(os.environ) + elif self.type == 'pdflatex': + if 'ps' in outs: + self.create_task('pdf2ps', task.outputs, node.change_ext('.ps')) + self.source = [] + +def configure(self): + """ + Find the programs tex, latex and others without raising errors. + """ + v = self.env + for p in 'tex latex pdflatex xelatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps makeglossaries'.split(): + try: + self.find_program(p, var=p.upper()) + except self.errors.ConfigurationError: + pass + v.DVIPSFLAGS = '-Ppdf' + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/vala.py b/ldb-2.0.8/third_party/waf/waflib/Tools/vala.py new file mode 100644 index 0000000..822ec50 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/vala.py @@ -0,0 +1,355 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Ali Sabil, 2007 +# Radosław Szkodziński, 2010 + +""" +At this point, vala is still unstable, so do not expect +this tool to be too stable either (apis, etc) +""" + +import re +from waflib import Build, Context, Errors, Logs, Node, Options, Task, Utils +from waflib.TaskGen import extension, taskgen_method +from waflib.Configure import conf + +class valac(Task.Task): + """ + Compiles vala files + """ + #run_str = "${VALAC} ${VALAFLAGS}" # ideally + #vars = ['VALAC_VERSION'] + vars = ["VALAC", "VALAC_VERSION", "VALAFLAGS"] + ext_out = ['.h'] + + def run(self): + cmd = self.env.VALAC + self.env.VALAFLAGS + resources = getattr(self, 'vala_exclude', []) + cmd.extend([a.abspath() for a in self.inputs if a not in resources]) + ret = self.exec_command(cmd, cwd=self.vala_dir_node.abspath()) + + if ret: + return ret + + if self.generator.dump_deps_node: + self.generator.dump_deps_node.write('\n'.join(self.generator.packages)) + + return ret + +@taskgen_method +def init_vala_task(self): + """ + Initializes the vala task with the relevant data (acts as a constructor) + """ + self.profile = getattr(self, 'profile', 'gobject') + + self.packages = packages = Utils.to_list(getattr(self, 'packages', [])) + self.use = Utils.to_list(getattr(self, 'use', [])) + if packages and not self.use: + self.use = packages[:] # copy + + if self.profile == 'gobject': + if not 'GOBJECT' in self.use: + self.use.append('GOBJECT') + + def addflags(flags): + self.env.append_value('VALAFLAGS', flags) + + if self.profile: + addflags('--profile=%s' % self.profile) + + valatask = self.valatask + + # output directory + if hasattr(self, 'vala_dir'): + if isinstance(self.vala_dir, str): + valatask.vala_dir_node = self.path.get_bld().make_node(self.vala_dir) + try: + valatask.vala_dir_node.mkdir() + except OSError: + raise self.bld.fatal('Cannot create the vala dir %r' % valatask.vala_dir_node) + else: + valatask.vala_dir_node = self.vala_dir + else: + valatask.vala_dir_node = self.path.get_bld() + addflags('--directory=%s' % valatask.vala_dir_node.abspath()) + + if hasattr(self, 'thread'): + if self.profile == 'gobject': + if not 'GTHREAD' in self.use: + self.use.append('GTHREAD') + else: + #Vala doesn't have threading support for dova nor posix + Logs.warn('Profile %s means no threading support', self.profile) + self.thread = False + + if self.thread: + addflags('--thread') + + self.is_lib = 'cprogram' not in self.features + if self.is_lib: + addflags('--library=%s' % self.target) + + h_node = valatask.vala_dir_node.find_or_declare('%s.h' % self.target) + valatask.outputs.append(h_node) + addflags('--header=%s' % h_node.name) + + valatask.outputs.append(valatask.vala_dir_node.find_or_declare('%s.vapi' % self.target)) + + if getattr(self, 'gir', None): + gir_node = valatask.vala_dir_node.find_or_declare('%s.gir' % self.gir) + addflags('--gir=%s' % gir_node.name) + valatask.outputs.append(gir_node) + + self.vala_target_glib = getattr(self, 'vala_target_glib', getattr(Options.options, 'vala_target_glib', None)) + if self.vala_target_glib: + addflags('--target-glib=%s' % self.vala_target_glib) + + addflags(['--define=%s' % x for x in Utils.to_list(getattr(self, 'vala_defines', []))]) + + packages_private = Utils.to_list(getattr(self, 'packages_private', [])) + addflags(['--pkg=%s' % x for x in packages_private]) + + def _get_api_version(): + api_version = '1.0' + if hasattr(Context.g_module, 'API_VERSION'): + version = Context.g_module.API_VERSION.split(".") + if version[0] == "0": + api_version = "0." + version[1] + else: + api_version = version[0] + ".0" + return api_version + + self.includes = Utils.to_list(getattr(self, 'includes', [])) + valatask.install_path = getattr(self, 'install_path', '') + + valatask.vapi_path = getattr(self, 'vapi_path', '${DATAROOTDIR}/vala/vapi') + valatask.pkg_name = getattr(self, 'pkg_name', self.env.PACKAGE) + valatask.header_path = getattr(self, 'header_path', '${INCLUDEDIR}/%s-%s' % (valatask.pkg_name, _get_api_version())) + valatask.install_binding = getattr(self, 'install_binding', True) + + self.vapi_dirs = vapi_dirs = Utils.to_list(getattr(self, 'vapi_dirs', [])) + #includes = [] + + if hasattr(self, 'use'): + local_packages = Utils.to_list(self.use)[:] # make sure to have a copy + seen = [] + while len(local_packages) > 0: + package = local_packages.pop() + if package in seen: + continue + seen.append(package) + + # check if the package exists + try: + package_obj = self.bld.get_tgen_by_name(package) + except Errors.WafError: + continue + + # in practice the other task is already processed + # but this makes it explicit + package_obj.post() + package_name = package_obj.target + task = getattr(package_obj, 'valatask', None) + if task: + for output in task.outputs: + if output.name == package_name + ".vapi": + valatask.set_run_after(task) + if package_name not in packages: + packages.append(package_name) + if output.parent not in vapi_dirs: + vapi_dirs.append(output.parent) + if output.parent not in self.includes: + self.includes.append(output.parent) + + if hasattr(package_obj, 'use'): + lst = self.to_list(package_obj.use) + lst.reverse() + local_packages = [pkg for pkg in lst if pkg not in seen] + local_packages + + addflags(['--pkg=%s' % p for p in packages]) + + for vapi_dir in vapi_dirs: + if isinstance(vapi_dir, Node.Node): + v_node = vapi_dir + else: + v_node = self.path.find_dir(vapi_dir) + if not v_node: + Logs.warn('Unable to locate Vala API directory: %r', vapi_dir) + else: + addflags('--vapidir=%s' % v_node.abspath()) + + self.dump_deps_node = None + if self.is_lib and self.packages: + self.dump_deps_node = valatask.vala_dir_node.find_or_declare('%s.deps' % self.target) + valatask.outputs.append(self.dump_deps_node) + + if self.is_lib and valatask.install_binding: + headers_list = [o for o in valatask.outputs if o.suffix() == ".h"] + if headers_list: + self.install_vheader = self.add_install_files(install_to=valatask.header_path, install_from=headers_list) + + vapi_list = [o for o in valatask.outputs if (o.suffix() in (".vapi", ".deps"))] + if vapi_list: + self.install_vapi = self.add_install_files(install_to=valatask.vapi_path, install_from=vapi_list) + + gir_list = [o for o in valatask.outputs if o.suffix() == '.gir'] + if gir_list: + self.install_gir = self.add_install_files( + install_to=getattr(self, 'gir_path', '${DATAROOTDIR}/gir-1.0'), install_from=gir_list) + + if hasattr(self, 'vala_resources'): + nodes = self.to_nodes(self.vala_resources) + valatask.vala_exclude = getattr(valatask, 'vala_exclude', []) + nodes + valatask.inputs.extend(nodes) + for x in nodes: + addflags(['--gresources', x.abspath()]) + +@extension('.vala', '.gs') +def vala_file(self, node): + """ + Compile a vala file and bind the task to *self.valatask*. If an existing vala task is already set, add the node + to its inputs. The typical example is:: + + def build(bld): + bld.program( + packages = 'gtk+-2.0', + target = 'vala-gtk-example', + use = 'GTK GLIB', + source = 'vala-gtk-example.vala foo.vala', + vala_defines = ['DEBUG'] # adds --define= values to the command-line + + # the following arguments are for libraries + #gir = 'hello-1.0', + #gir_path = '/tmp', + #vapi_path = '/tmp', + #pkg_name = 'hello' + # disable installing of gir, vapi and header + #install_binding = False + + # profile = 'xyz' # adds --profile= to enable profiling + # thread = True, # adds --thread, except if profile is on or not on 'gobject' + # vala_target_glib = 'xyz' # adds --target-glib=, can be given through the command-line option --vala-target-glib= + ) + + + :param node: vala file + :type node: :py:class:`waflib.Node.Node` + """ + + try: + valatask = self.valatask + except AttributeError: + valatask = self.valatask = self.create_task('valac') + self.init_vala_task() + + valatask.inputs.append(node) + name = node.name[:node.name.rfind('.')] + '.c' + c_node = valatask.vala_dir_node.find_or_declare(name) + valatask.outputs.append(c_node) + self.source.append(c_node) + +@extension('.vapi') +def vapi_file(self, node): + try: + valatask = self.valatask + except AttributeError: + valatask = self.valatask = self.create_task('valac') + self.init_vala_task() + valatask.inputs.append(node) + +@conf +def find_valac(self, valac_name, min_version): + """ + Find the valac program, and execute it to store the version + number in *conf.env.VALAC_VERSION* + + :param valac_name: program name + :type valac_name: string or list of string + :param min_version: minimum version acceptable + :type min_version: tuple of int + """ + valac = self.find_program(valac_name, var='VALAC') + try: + output = self.cmd_and_log(valac + ['--version']) + except Errors.WafError: + valac_version = None + else: + ver = re.search(r'\d+.\d+.\d+', output).group().split('.') + valac_version = tuple([int(x) for x in ver]) + + self.msg('Checking for %s version >= %r' % (valac_name, min_version), + valac_version, valac_version and valac_version >= min_version) + if valac and valac_version < min_version: + self.fatal("%s version %r is too old, need >= %r" % (valac_name, valac_version, min_version)) + + self.env.VALAC_VERSION = valac_version + return valac + +@conf +def check_vala(self, min_version=(0,8,0), branch=None): + """ + Check if vala compiler from a given branch exists of at least a given + version. + + :param min_version: minimum version acceptable (0.8.0) + :type min_version: tuple + :param branch: first part of the version number, in case a snapshot is used (0, 8) + :type branch: tuple of int + """ + if self.env.VALA_MINVER: + min_version = self.env.VALA_MINVER + if self.env.VALA_MINVER_BRANCH: + branch = self.env.VALA_MINVER_BRANCH + if not branch: + branch = min_version[:2] + try: + find_valac(self, 'valac-%d.%d' % (branch[0], branch[1]), min_version) + except self.errors.ConfigurationError: + find_valac(self, 'valac', min_version) + +@conf +def check_vala_deps(self): + """ + Load the gobject and gthread packages if they are missing. + """ + if not self.env.HAVE_GOBJECT: + pkg_args = {'package': 'gobject-2.0', + 'uselib_store': 'GOBJECT', + 'args': '--cflags --libs'} + if getattr(Options.options, 'vala_target_glib', None): + pkg_args['atleast_version'] = Options.options.vala_target_glib + self.check_cfg(**pkg_args) + + if not self.env.HAVE_GTHREAD: + pkg_args = {'package': 'gthread-2.0', + 'uselib_store': 'GTHREAD', + 'args': '--cflags --libs'} + if getattr(Options.options, 'vala_target_glib', None): + pkg_args['atleast_version'] = Options.options.vala_target_glib + self.check_cfg(**pkg_args) + +def configure(self): + """ + Use the following to enforce minimum vala version:: + + def configure(conf): + conf.env.VALA_MINVER = (0, 10, 0) + conf.load('vala') + """ + self.load('gnu_dirs') + self.check_vala_deps() + self.check_vala() + self.add_os_flags('VALAFLAGS') + self.env.append_unique('VALAFLAGS', ['-C']) + +def options(opt): + """ + Load the :py:mod:`waflib.Tools.gnu_dirs` tool and add the ``--vala-target-glib`` command-line option + """ + opt.load('gnu_dirs') + valaopts = opt.add_option_group('Vala Compiler Options') + valaopts.add_option('--vala-target-glib', default=None, + dest='vala_target_glib', metavar='MAJOR.MINOR', + help='Target version of glib for Vala GObject code generation') + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/waf_unit_test.py b/ldb-2.0.8/third_party/waf/waflib/Tools/waf_unit_test.py new file mode 100644 index 0000000..6ff6f72 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/waf_unit_test.py @@ -0,0 +1,296 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Carlos Rafael Giani, 2006 +# Thomas Nagy, 2010-2018 (ita) + +""" +Unit testing system for C/C++/D and interpreted languages providing test execution: + +* in parallel, by using ``waf -j`` +* partial (only the tests that have changed) or full (by using ``waf --alltests``) + +The tests are declared by adding the **test** feature to programs:: + + def options(opt): + opt.load('compiler_cxx waf_unit_test') + def configure(conf): + conf.load('compiler_cxx waf_unit_test') + def build(bld): + bld(features='cxx cxxprogram test', source='main.cpp', target='app') + # or + bld.program(features='test', source='main2.cpp', target='app2') + +When the build is executed, the program 'test' will be built and executed without arguments. +The success/failure is detected by looking at the return code. The status and the standard output/error +are stored on the build context. + +The results can be displayed by registering a callback function. Here is how to call +the predefined callback:: + + def build(bld): + bld(features='cxx cxxprogram test', source='main.c', target='app') + from waflib.Tools import waf_unit_test + bld.add_post_fun(waf_unit_test.summary) + +By passing --dump-test-scripts the build outputs corresponding python files +(with extension _run.py) that are useful for debugging purposes. +""" + +import os, shlex, sys +from waflib.TaskGen import feature, after_method, taskgen_method +from waflib import Utils, Task, Logs, Options +from waflib.Tools import ccroot +testlock = Utils.threading.Lock() + +SCRIPT_TEMPLATE = """#! %(python)s +import subprocess, sys +cmd = %(cmd)r +# if you want to debug with gdb: +#cmd = ['gdb', '-args'] + cmd +env = %(env)r +status = subprocess.call(cmd, env=env, cwd=%(cwd)r, shell=isinstance(cmd, str)) +sys.exit(status) +""" + +@taskgen_method +def handle_ut_cwd(self, key): + """ + Task generator method, used internally to limit code duplication. + This method may disappear anytime. + """ + cwd = getattr(self, key, None) + if cwd: + if isinstance(cwd, str): + # we want a Node instance + if os.path.isabs(cwd): + self.ut_cwd = self.bld.root.make_node(cwd) + else: + self.ut_cwd = self.path.make_node(cwd) + +@feature('test_scripts') +def make_interpreted_test(self): + """Create interpreted unit tests.""" + for x in ['test_scripts_source', 'test_scripts_template']: + if not hasattr(self, x): + Logs.warn('a test_scripts taskgen i missing %s' % x) + return + + self.ut_run, lst = Task.compile_fun(self.test_scripts_template, shell=getattr(self, 'test_scripts_shell', False)) + + script_nodes = self.to_nodes(self.test_scripts_source) + for script_node in script_nodes: + tsk = self.create_task('utest', [script_node]) + tsk.vars = lst + tsk.vars + tsk.env['SCRIPT'] = script_node.path_from(tsk.get_cwd()) + + self.handle_ut_cwd('test_scripts_cwd') + + env = getattr(self, 'test_scripts_env', None) + if env: + self.ut_env = env + else: + self.ut_env = dict(os.environ) + + paths = getattr(self, 'test_scripts_paths', {}) + for (k,v) in paths.items(): + p = self.ut_env.get(k, '').split(os.pathsep) + if isinstance(v, str): + v = v.split(os.pathsep) + self.ut_env[k] = os.pathsep.join(p + v) + +@feature('test') +@after_method('apply_link', 'process_use') +def make_test(self): + """Create the unit test task. There can be only one unit test task by task generator.""" + if not getattr(self, 'link_task', None): + return + + tsk = self.create_task('utest', self.link_task.outputs) + if getattr(self, 'ut_str', None): + self.ut_run, lst = Task.compile_fun(self.ut_str, shell=getattr(self, 'ut_shell', False)) + tsk.vars = lst + tsk.vars + + self.handle_ut_cwd('ut_cwd') + + if not hasattr(self, 'ut_paths'): + paths = [] + for x in self.tmp_use_sorted: + try: + y = self.bld.get_tgen_by_name(x).link_task + except AttributeError: + pass + else: + if not isinstance(y, ccroot.stlink_task): + paths.append(y.outputs[0].parent.abspath()) + self.ut_paths = os.pathsep.join(paths) + os.pathsep + + if not hasattr(self, 'ut_env'): + self.ut_env = dct = dict(os.environ) + def add_path(var): + dct[var] = self.ut_paths + dct.get(var,'') + if Utils.is_win32: + add_path('PATH') + elif Utils.unversioned_sys_platform() == 'darwin': + add_path('DYLD_LIBRARY_PATH') + add_path('LD_LIBRARY_PATH') + else: + add_path('LD_LIBRARY_PATH') + + if not hasattr(self, 'ut_cmd'): + self.ut_cmd = getattr(Options.options, 'testcmd', False) + +@taskgen_method +def add_test_results(self, tup): + """Override and return tup[1] to interrupt the build immediately if a test does not run""" + Logs.debug("ut: %r", tup) + try: + self.utest_results.append(tup) + except AttributeError: + self.utest_results = [tup] + try: + self.bld.utest_results.append(tup) + except AttributeError: + self.bld.utest_results = [tup] + +@Task.deep_inputs +class utest(Task.Task): + """ + Execute a unit test + """ + color = 'PINK' + after = ['vnum', 'inst'] + vars = [] + + def runnable_status(self): + """ + Always execute the task if `waf --alltests` was used or no + tests if ``waf --notests`` was used + """ + if getattr(Options.options, 'no_tests', False): + return Task.SKIP_ME + + ret = super(utest, self).runnable_status() + if ret == Task.SKIP_ME: + if getattr(Options.options, 'all_tests', False): + return Task.RUN_ME + return ret + + def get_test_env(self): + """ + In general, tests may require any library built anywhere in the project. + Override this method if fewer paths are needed + """ + return self.generator.ut_env + + def post_run(self): + super(utest, self).post_run() + if getattr(Options.options, 'clear_failed_tests', False) and self.waf_unit_test_results[1]: + self.generator.bld.task_sigs[self.uid()] = None + + def run(self): + """ + Execute the test. The execution is always successful, and the results + are stored on ``self.generator.bld.utest_results`` for postprocessing. + + Override ``add_test_results`` to interrupt the build + """ + if hasattr(self.generator, 'ut_run'): + return self.generator.ut_run(self) + + self.ut_exec = getattr(self.generator, 'ut_exec', [self.inputs[0].abspath()]) + ut_cmd = getattr(self.generator, 'ut_cmd', False) + if ut_cmd: + self.ut_exec = shlex.split(ut_cmd % ' '.join(self.ut_exec)) + + return self.exec_command(self.ut_exec) + + def exec_command(self, cmd, **kw): + self.generator.bld.log_command(cmd, kw) + if getattr(Options.options, 'dump_test_scripts', False): + script_code = SCRIPT_TEMPLATE % { + 'python': sys.executable, + 'env': self.get_test_env(), + 'cwd': self.get_cwd().abspath(), + 'cmd': cmd + } + script_file = self.inputs[0].abspath() + '_run.py' + Utils.writef(script_file, script_code, encoding='utf-8') + os.chmod(script_file, Utils.O755) + if Logs.verbose > 1: + Logs.info('Test debug file written as %r' % script_file) + + proc = Utils.subprocess.Popen(cmd, cwd=self.get_cwd().abspath(), env=self.get_test_env(), + stderr=Utils.subprocess.PIPE, stdout=Utils.subprocess.PIPE, shell=isinstance(cmd,str)) + (stdout, stderr) = proc.communicate() + self.waf_unit_test_results = tup = (self.inputs[0].abspath(), proc.returncode, stdout, stderr) + testlock.acquire() + try: + return self.generator.add_test_results(tup) + finally: + testlock.release() + + def get_cwd(self): + return getattr(self.generator, 'ut_cwd', self.inputs[0].parent) + +def summary(bld): + """ + Display an execution summary:: + + def build(bld): + bld(features='cxx cxxprogram test', source='main.c', target='app') + from waflib.Tools import waf_unit_test + bld.add_post_fun(waf_unit_test.summary) + """ + lst = getattr(bld, 'utest_results', []) + if lst: + Logs.pprint('CYAN', 'execution summary') + + total = len(lst) + tfail = len([x for x in lst if x[1]]) + + Logs.pprint('GREEN', ' tests that pass %d/%d' % (total-tfail, total)) + for (f, code, out, err) in lst: + if not code: + Logs.pprint('GREEN', ' %s' % f) + + Logs.pprint('GREEN' if tfail == 0 else 'RED', ' tests that fail %d/%d' % (tfail, total)) + for (f, code, out, err) in lst: + if code: + Logs.pprint('RED', ' %s' % f) + +def set_exit_code(bld): + """ + If any of the tests fail waf will exit with that exit code. + This is useful if you have an automated build system which need + to report on errors from the tests. + You may use it like this: + + def build(bld): + bld(features='cxx cxxprogram test', source='main.c', target='app') + from waflib.Tools import waf_unit_test + bld.add_post_fun(waf_unit_test.set_exit_code) + """ + lst = getattr(bld, 'utest_results', []) + for (f, code, out, err) in lst: + if code: + msg = [] + if out: + msg.append('stdout:%s%s' % (os.linesep, out.decode('utf-8'))) + if err: + msg.append('stderr:%s%s' % (os.linesep, err.decode('utf-8'))) + bld.fatal(os.linesep.join(msg)) + + +def options(opt): + """ + Provide the ``--alltests``, ``--notests`` and ``--testcmd`` command-line options. + """ + opt.add_option('--notests', action='store_true', default=False, help='Exec no unit tests', dest='no_tests') + opt.add_option('--alltests', action='store_true', default=False, help='Exec all unit tests', dest='all_tests') + opt.add_option('--clear-failed', action='store_true', default=False, + help='Force failed unit tests to run again next time', dest='clear_failed_tests') + opt.add_option('--testcmd', action='store', default=False, dest='testcmd', + help='Run the unit tests using the test-cmd string example "--testcmd="valgrind --error-exitcode=1 %s" to run under valgrind') + opt.add_option('--dump-test-scripts', action='store_true', default=False, + help='Create python scripts to help debug tests', dest='dump_test_scripts') + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/winres.py b/ldb-2.0.8/third_party/waf/waflib/Tools/winres.py new file mode 100644 index 0000000..9be1ed6 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/winres.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Brant Young, 2007 + +"Process *.rc* files for C/C++: X{.rc -> [.res|.rc.o]}" + +import re +from waflib import Task +from waflib.TaskGen import extension +from waflib.Tools import c_preproc + +@extension('.rc') +def rc_file(self, node): + """ + Binds the .rc extension to a winrc task + """ + obj_ext = '.rc.o' + if self.env.WINRC_TGT_F == '/fo': + obj_ext = '.res' + rctask = self.create_task('winrc', node, node.change_ext(obj_ext)) + try: + self.compiled_tasks.append(rctask) + except AttributeError: + self.compiled_tasks = [rctask] + +re_lines = re.compile( + r'(?:^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*?)\s*$)|'\ + r'(?:^\w+[ \t]*(ICON|BITMAP|CURSOR|HTML|FONT|MESSAGETABLE|TYPELIB|REGISTRY|D3DFX)[ \t]*(.*?)\s*$)', + re.IGNORECASE | re.MULTILINE) + +class rc_parser(c_preproc.c_parser): + """ + Calculates dependencies in .rc files + """ + def filter_comments(self, node): + """ + Overrides :py:meth:`waflib.Tools.c_preproc.c_parser.filter_comments` + """ + code = node.read() + if c_preproc.use_trigraphs: + for (a, b) in c_preproc.trig_def: + code = code.split(a).join(b) + code = c_preproc.re_nl.sub('', code) + code = c_preproc.re_cpp.sub(c_preproc.repl, code) + ret = [] + for m in re.finditer(re_lines, code): + if m.group(2): + ret.append((m.group(2), m.group(3))) + else: + ret.append(('include', m.group(5))) + return ret + +class winrc(Task.Task): + """ + Compiles resource files + """ + run_str = '${WINRC} ${WINRCFLAGS} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${WINRC_TGT_F} ${TGT} ${WINRC_SRC_F} ${SRC}' + color = 'BLUE' + def scan(self): + tmp = rc_parser(self.generator.includes_nodes) + tmp.start(self.inputs[0], self.env) + return (tmp.nodes, tmp.names) + +def configure(conf): + """ + Detects the programs RC or windres, depending on the C/C++ compiler in use + """ + v = conf.env + if not v.WINRC: + if v.CC_NAME == 'msvc': + conf.find_program('RC', var='WINRC', path_list=v.PATH) + v.WINRC_TGT_F = '/fo' + v.WINRC_SRC_F = '' + else: + conf.find_program('windres', var='WINRC', path_list=v.PATH) + v.WINRC_TGT_F = '-o' + v.WINRC_SRC_F = '-i' + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/xlc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/xlc.py new file mode 100644 index 0000000..134dd41 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/xlc.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2006-2018 (ita) +# Ralf Habacker, 2006 (rh) +# Yinon Ehrlich, 2009 +# Michael Kuhn, 2009 + +from waflib.Tools import ccroot, ar +from waflib.Configure import conf + +@conf +def find_xlc(conf): + """ + Detects the Aix C compiler + """ + cc = conf.find_program(['xlc_r', 'xlc'], var='CC') + conf.get_xlc_version(cc) + conf.env.CC_NAME = 'xlc' + +@conf +def xlc_common_flags(conf): + """ + Flags required for executing the Aix C compiler + """ + v = conf.env + + v.CC_SRC_F = [] + v.CC_TGT_F = ['-c', '-o'] + + if not v.LINK_CC: + v.LINK_CC = v.CC + + v.CCLNK_SRC_F = [] + v.CCLNK_TGT_F = ['-o'] + v.CPPPATH_ST = '-I%s' + v.DEFINES_ST = '-D%s' + + v.LIB_ST = '-l%s' # template for adding libs + v.LIBPATH_ST = '-L%s' # template for adding libpaths + v.STLIB_ST = '-l%s' + v.STLIBPATH_ST = '-L%s' + v.RPATH_ST = '-Wl,-rpath,%s' + + v.SONAME_ST = [] + v.SHLIB_MARKER = [] + v.STLIB_MARKER = [] + + v.LINKFLAGS_cprogram = ['-Wl,-brtl'] + v.cprogram_PATTERN = '%s' + + v.CFLAGS_cshlib = ['-fPIC'] + v.LINKFLAGS_cshlib = ['-G', '-Wl,-brtl,-bexpfull'] + v.cshlib_PATTERN = 'lib%s.so' + + v.LINKFLAGS_cstlib = [] + v.cstlib_PATTERN = 'lib%s.a' + +def configure(conf): + conf.find_xlc() + conf.find_ar() + conf.xlc_common_flags() + conf.cc_load_tools() + conf.cc_add_flags() + conf.link_add_flags() + diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/xlcxx.py b/ldb-2.0.8/third_party/waf/waflib/Tools/xlcxx.py new file mode 100644 index 0000000..76aa59b --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Tools/xlcxx.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2006-2018 (ita) +# Ralf Habacker, 2006 (rh) +# Yinon Ehrlich, 2009 +# Michael Kuhn, 2009 + +from waflib.Tools import ccroot, ar +from waflib.Configure import conf + +@conf +def find_xlcxx(conf): + """ + Detects the Aix C++ compiler + """ + cxx = conf.find_program(['xlc++_r', 'xlc++'], var='CXX') + conf.get_xlc_version(cxx) + conf.env.CXX_NAME = 'xlc++' + +@conf +def xlcxx_common_flags(conf): + """ + Flags required for executing the Aix C++ compiler + """ + v = conf.env + + v.CXX_SRC_F = [] + v.CXX_TGT_F = ['-c', '-o'] + + if not v.LINK_CXX: + v.LINK_CXX = v.CXX + + v.CXXLNK_SRC_F = [] + v.CXXLNK_TGT_F = ['-o'] + v.CPPPATH_ST = '-I%s' + v.DEFINES_ST = '-D%s' + + v.LIB_ST = '-l%s' # template for adding libs + v.LIBPATH_ST = '-L%s' # template for adding libpaths + v.STLIB_ST = '-l%s' + v.STLIBPATH_ST = '-L%s' + v.RPATH_ST = '-Wl,-rpath,%s' + + v.SONAME_ST = [] + v.SHLIB_MARKER = [] + v.STLIB_MARKER = [] + + v.LINKFLAGS_cxxprogram= ['-Wl,-brtl'] + v.cxxprogram_PATTERN = '%s' + + v.CXXFLAGS_cxxshlib = ['-fPIC'] + v.LINKFLAGS_cxxshlib = ['-G', '-Wl,-brtl,-bexpfull'] + v.cxxshlib_PATTERN = 'lib%s.so' + + v.LINKFLAGS_cxxstlib = [] + v.cxxstlib_PATTERN = 'lib%s.a' + +def configure(conf): + conf.find_xlcxx() + conf.find_ar() + conf.xlcxx_common_flags() + conf.cxx_load_tools() + conf.cxx_add_flags() + conf.link_add_flags() + diff --git a/ldb-2.0.8/third_party/waf/waflib/Utils.py b/ldb-2.0.8/third_party/waf/waflib/Utils.py new file mode 100644 index 0000000..7472226 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/Utils.py @@ -0,0 +1,1035 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2005-2018 (ita) + +""" +Utilities and platform-specific fixes + +The portability fixes try to provide a consistent behavior of the Waf API +through Python versions 2.5 to 3.X and across different platforms (win32, linux, etc) +""" + +from __future__ import with_statement + +import atexit, os, sys, errno, inspect, re, datetime, platform, base64, signal, functools, time + +try: + import cPickle +except ImportError: + import pickle as cPickle + +# leave this +if os.name == 'posix' and sys.version_info[0] < 3: + try: + import subprocess32 as subprocess + except ImportError: + import subprocess +else: + import subprocess + +try: + TimeoutExpired = subprocess.TimeoutExpired +except AttributeError: + class TimeoutExpired(Exception): + pass + +from collections import deque, defaultdict + +try: + import _winreg as winreg +except ImportError: + try: + import winreg + except ImportError: + winreg = None + +from waflib import Errors + +try: + from hashlib import md5 +except ImportError: + try: + from hashlib import sha1 as md5 + except ImportError: + # never fail to enable potential fixes from another module + pass +else: + try: + md5().digest() + except ValueError: + # Fips? #2213 + from hashlib import sha1 as md5 + +try: + import threading +except ImportError: + if not 'JOBS' in os.environ: + # no threading :-( + os.environ['JOBS'] = '1' + + class threading(object): + """ + A fake threading class for platforms lacking the threading module. + Use ``waf -j1`` on those platforms + """ + pass + class Lock(object): + """Fake Lock class""" + def acquire(self): + pass + def release(self): + pass + threading.Lock = threading.Thread = Lock + +SIG_NIL = 'SIG_NIL_SIG_NIL_'.encode() +"""Arbitrary null value for hashes. Modify this value according to the hash function in use""" + +O644 = 420 +"""Constant representing the permissions for regular files (0644 raises a syntax error on python 3)""" + +O755 = 493 +"""Constant representing the permissions for executable files (0755 raises a syntax error on python 3)""" + +rot_chr = ['\\', '|', '/', '-'] +"List of characters to use when displaying the throbber (progress bar)" + +rot_idx = 0 +"Index of the current throbber character (progress bar)" + +class ordered_iter_dict(dict): + """Ordered dictionary that provides iteration from the most recently inserted keys first""" + def __init__(self, *k, **kw): + self.lst = deque() + dict.__init__(self, *k, **kw) + def clear(self): + dict.clear(self) + self.lst = deque() + def __setitem__(self, key, value): + if key in dict.keys(self): + self.lst.remove(key) + dict.__setitem__(self, key, value) + self.lst.append(key) + def __delitem__(self, key): + dict.__delitem__(self, key) + try: + self.lst.remove(key) + except ValueError: + pass + def __iter__(self): + return reversed(self.lst) + def keys(self): + return reversed(self.lst) + +class lru_node(object): + """ + Used by :py:class:`waflib.Utils.lru_cache` + """ + __slots__ = ('next', 'prev', 'key', 'val') + def __init__(self): + self.next = self + self.prev = self + self.key = None + self.val = None + +class lru_cache(object): + """ + A simple least-recently used cache with lazy allocation + """ + __slots__ = ('maxlen', 'table', 'head') + def __init__(self, maxlen=100): + self.maxlen = maxlen + """ + Maximum amount of elements in the cache + """ + self.table = {} + """ + Mapping key-value + """ + self.head = lru_node() + self.head.next = self.head + self.head.prev = self.head + + def __getitem__(self, key): + node = self.table[key] + # assert(key==node.key) + if node is self.head: + return node.val + + # detach the node found + node.prev.next = node.next + node.next.prev = node.prev + + # replace the head + node.next = self.head.next + node.prev = self.head + self.head = node.next.prev = node.prev.next = node + + return node.val + + def __setitem__(self, key, val): + if key in self.table: + # update the value for an existing key + node = self.table[key] + node.val = val + self.__getitem__(key) + else: + if len(self.table) < self.maxlen: + # the very first item is unused until the maximum is reached + node = lru_node() + node.prev = self.head + node.next = self.head.next + node.prev.next = node.next.prev = node + else: + node = self.head = self.head.next + try: + # that's another key + del self.table[node.key] + except KeyError: + pass + + node.key = key + node.val = val + self.table[key] = node + +class lazy_generator(object): + def __init__(self, fun, params): + self.fun = fun + self.params = params + + def __iter__(self): + return self + + def __next__(self): + try: + it = self.it + except AttributeError: + it = self.it = self.fun(*self.params) + return next(it) + + next = __next__ + +is_win32 = os.sep == '\\' or sys.platform == 'win32' or os.name == 'nt' # msys2 +""" +Whether this system is a Windows series +""" + +def readf(fname, m='r', encoding='latin-1'): + """ + Reads an entire file into a string. See also :py:meth:`waflib.Node.Node.readf`:: + + def build(ctx): + from waflib import Utils + txt = Utils.readf(self.path.find_node('wscript').abspath()) + txt = ctx.path.find_node('wscript').read() + + :type fname: string + :param fname: Path to file + :type m: string + :param m: Open mode + :type encoding: string + :param encoding: encoding value, only used for python 3 + :rtype: string + :return: Content of the file + """ + + if sys.hexversion > 0x3000000 and not 'b' in m: + m += 'b' + with open(fname, m) as f: + txt = f.read() + if encoding: + txt = txt.decode(encoding) + else: + txt = txt.decode() + else: + with open(fname, m) as f: + txt = f.read() + return txt + +def writef(fname, data, m='w', encoding='latin-1'): + """ + Writes an entire file from a string. + See also :py:meth:`waflib.Node.Node.writef`:: + + def build(ctx): + from waflib import Utils + txt = Utils.writef(self.path.make_node('i_like_kittens').abspath(), 'some data') + self.path.make_node('i_like_kittens').write('some data') + + :type fname: string + :param fname: Path to file + :type data: string + :param data: The contents to write to the file + :type m: string + :param m: Open mode + :type encoding: string + :param encoding: encoding value, only used for python 3 + """ + if sys.hexversion > 0x3000000 and not 'b' in m: + data = data.encode(encoding) + m += 'b' + with open(fname, m) as f: + f.write(data) + +def h_file(fname): + """ + Computes a hash value for a file by using md5. Use the md5_tstamp + extension to get faster build hashes if necessary. + + :type fname: string + :param fname: path to the file to hash + :return: hash of the file contents + :rtype: string or bytes + """ + m = md5() + with open(fname, 'rb') as f: + while fname: + fname = f.read(200000) + m.update(fname) + return m.digest() + +def readf_win32(f, m='r', encoding='latin-1'): + flags = os.O_NOINHERIT | os.O_RDONLY + if 'b' in m: + flags |= os.O_BINARY + if '+' in m: + flags |= os.O_RDWR + try: + fd = os.open(f, flags) + except OSError: + raise IOError('Cannot read from %r' % f) + + if sys.hexversion > 0x3000000 and not 'b' in m: + m += 'b' + with os.fdopen(fd, m) as f: + txt = f.read() + if encoding: + txt = txt.decode(encoding) + else: + txt = txt.decode() + else: + with os.fdopen(fd, m) as f: + txt = f.read() + return txt + +def writef_win32(f, data, m='w', encoding='latin-1'): + if sys.hexversion > 0x3000000 and not 'b' in m: + data = data.encode(encoding) + m += 'b' + flags = os.O_CREAT | os.O_TRUNC | os.O_WRONLY | os.O_NOINHERIT + if 'b' in m: + flags |= os.O_BINARY + if '+' in m: + flags |= os.O_RDWR + try: + fd = os.open(f, flags) + except OSError: + raise OSError('Cannot write to %r' % f) + with os.fdopen(fd, m) as f: + f.write(data) + +def h_file_win32(fname): + try: + fd = os.open(fname, os.O_BINARY | os.O_RDONLY | os.O_NOINHERIT) + except OSError: + raise OSError('Cannot read from %r' % fname) + m = md5() + with os.fdopen(fd, 'rb') as f: + while fname: + fname = f.read(200000) + m.update(fname) + return m.digest() + +# always save these +readf_unix = readf +writef_unix = writef +h_file_unix = h_file +if hasattr(os, 'O_NOINHERIT') and sys.hexversion < 0x3040000: + # replace the default functions + readf = readf_win32 + writef = writef_win32 + h_file = h_file_win32 + +try: + x = ''.encode('hex') +except LookupError: + import binascii + def to_hex(s): + ret = binascii.hexlify(s) + if not isinstance(ret, str): + ret = ret.decode('utf-8') + return ret +else: + def to_hex(s): + return s.encode('hex') + +to_hex.__doc__ = """ +Return the hexadecimal representation of a string + +:param s: string to convert +:type s: string +""" + +def listdir_win32(s): + """ + Lists the contents of a folder in a portable manner. + On Win32, returns the list of drive letters: ['C:', 'X:', 'Z:'] when an empty string is given. + + :type s: string + :param s: a string, which can be empty on Windows + """ + if not s: + try: + import ctypes + except ImportError: + # there is nothing much we can do + return [x + ':\\' for x in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'] + else: + dlen = 4 # length of "?:\\x00" + maxdrives = 26 + buf = ctypes.create_string_buffer(maxdrives * dlen) + ndrives = ctypes.windll.kernel32.GetLogicalDriveStringsA(maxdrives*dlen, ctypes.byref(buf)) + return [ str(buf.raw[4*i:4*i+2].decode('ascii')) for i in range(int(ndrives/dlen)) ] + + if len(s) == 2 and s[1] == ":": + s += os.sep + + if not os.path.isdir(s): + e = OSError('%s is not a directory' % s) + e.errno = errno.ENOENT + raise e + return os.listdir(s) + +listdir = os.listdir +if is_win32: + listdir = listdir_win32 + +def num2ver(ver): + """ + Converts a string, tuple or version number into an integer. The number is supposed to have at most 4 digits:: + + from waflib.Utils import num2ver + num2ver('1.3.2') == num2ver((1,3,2)) == num2ver((1,3,2,0)) + + :type ver: string or tuple of numbers + :param ver: a version number + """ + if isinstance(ver, str): + ver = tuple(ver.split('.')) + if isinstance(ver, tuple): + ret = 0 + for i in range(4): + if i < len(ver): + ret += 256**(3 - i) * int(ver[i]) + return ret + return ver + +def to_list(val): + """ + Converts a string argument to a list by splitting it by spaces. + Returns the object if not a string:: + + from waflib.Utils import to_list + lst = to_list('a b c d') + + :param val: list of string or space-separated string + :rtype: list + :return: Argument converted to list + """ + if isinstance(val, str): + return val.split() + else: + return val + +def console_encoding(): + try: + import ctypes + except ImportError: + pass + else: + try: + codepage = ctypes.windll.kernel32.GetConsoleCP() + except AttributeError: + pass + else: + if codepage: + return 'cp%d' % codepage + return sys.stdout.encoding or ('cp1252' if is_win32 else 'latin-1') + +def split_path_unix(path): + return path.split('/') + +def split_path_cygwin(path): + if path.startswith('//'): + ret = path.split('/')[2:] + ret[0] = '/' + ret[0] + return ret + return path.split('/') + +re_sp = re.compile('[/\\\\]+') +def split_path_win32(path): + if path.startswith('\\\\'): + ret = re_sp.split(path)[1:] + ret[0] = '\\\\' + ret[0] + if ret[0] == '\\\\?': + return ret[1:] + return ret + return re_sp.split(path) + +msysroot = None +def split_path_msys(path): + if path.startswith(('/', '\\')) and not path.startswith(('//', '\\\\')): + # msys paths can be in the form /usr/bin + global msysroot + if not msysroot: + # msys has python 2.7 or 3, so we can use this + msysroot = subprocess.check_output(['cygpath', '-w', '/']).decode(sys.stdout.encoding or 'latin-1') + msysroot = msysroot.strip() + path = os.path.normpath(msysroot + os.sep + path) + return split_path_win32(path) + +if sys.platform == 'cygwin': + split_path = split_path_cygwin +elif is_win32: + # Consider this an MSYSTEM environment if $MSYSTEM is set and python + # reports is executable from a unix like path on a windows host. + if os.environ.get('MSYSTEM') and sys.executable.startswith('/'): + split_path = split_path_msys + else: + split_path = split_path_win32 +else: + split_path = split_path_unix + +split_path.__doc__ = """ +Splits a path by / or \\; do not confuse this function with with ``os.path.split`` + +:type path: string +:param path: path to split +:return: list of string +""" + +def check_dir(path): + """ + Ensures that a directory exists (similar to ``mkdir -p``). + + :type path: string + :param path: Path to directory + :raises: :py:class:`waflib.Errors.WafError` if the folder cannot be added. + """ + if not os.path.isdir(path): + try: + os.makedirs(path) + except OSError as e: + if not os.path.isdir(path): + raise Errors.WafError('Cannot create the folder %r' % path, ex=e) + +def check_exe(name, env=None): + """ + Ensures that a program exists + + :type name: string + :param name: path to the program + :param env: configuration object + :type env: :py:class:`waflib.ConfigSet.ConfigSet` + :return: path of the program or None + :raises: :py:class:`waflib.Errors.WafError` if the folder cannot be added. + """ + if not name: + raise ValueError('Cannot execute an empty string!') + def is_exe(fpath): + return os.path.isfile(fpath) and os.access(fpath, os.X_OK) + + fpath, fname = os.path.split(name) + if fpath and is_exe(name): + return os.path.abspath(name) + else: + env = env or os.environ + for path in env['PATH'].split(os.pathsep): + path = path.strip('"') + exe_file = os.path.join(path, name) + if is_exe(exe_file): + return os.path.abspath(exe_file) + return None + +def def_attrs(cls, **kw): + """ + Sets default attributes on a class instance + + :type cls: class + :param cls: the class to update the given attributes in. + :type kw: dict + :param kw: dictionary of attributes names and values. + """ + for k, v in kw.items(): + if not hasattr(cls, k): + setattr(cls, k, v) + +def quote_define_name(s): + """ + Converts a string into an identifier suitable for C defines. + + :type s: string + :param s: String to convert + :rtype: string + :return: Identifier suitable for C defines + """ + fu = re.sub('[^a-zA-Z0-9]', '_', s) + fu = re.sub('_+', '_', fu) + fu = fu.upper() + return fu + +re_sh = re.compile('\\s|\'|"') +""" +Regexp used for shell_escape below +""" + +def shell_escape(cmd): + """ + Escapes a command: + ['ls', '-l', 'arg space'] -> ls -l 'arg space' + """ + if isinstance(cmd, str): + return cmd + return ' '.join(repr(x) if re_sh.search(x) else x for x in cmd) + +def h_list(lst): + """ + Hashes lists of ordered data. + + Using hash(tup) for tuples would be much more efficient, + but Python now enforces hash randomization + + :param lst: list to hash + :type lst: list of strings + :return: hash of the list + """ + return md5(repr(lst).encode()).digest() + +if sys.hexversion < 0x3000000: + def h_list_python2(lst): + return md5(repr(lst)).digest() + h_list_python2.__doc__ = h_list.__doc__ + h_list = h_list_python2 + +def h_fun(fun): + """ + Hash functions + + :param fun: function to hash + :type fun: function + :return: hash of the function + :rtype: string or bytes + """ + try: + return fun.code + except AttributeError: + if isinstance(fun, functools.partial): + code = list(fun.args) + # The method items() provides a sequence of tuples where the first element + # represents an optional argument of the partial function application + # + # The sorting result outcome will be consistent because: + # 1. tuples are compared in order of their elements + # 2. optional argument namess are unique + code.extend(sorted(fun.keywords.items())) + code.append(h_fun(fun.func)) + fun.code = h_list(code) + return fun.code + try: + h = inspect.getsource(fun) + except EnvironmentError: + h = 'nocode' + try: + fun.code = h + except AttributeError: + pass + return h + +def h_cmd(ins): + """ + Hashes objects recursively + + :param ins: input object + :type ins: string or list or tuple or function + :rtype: string or bytes + """ + # this function is not meant to be particularly fast + if isinstance(ins, str): + # a command is either a string + ret = ins + elif isinstance(ins, list) or isinstance(ins, tuple): + # or a list of functions/strings + ret = str([h_cmd(x) for x in ins]) + else: + # or just a python function + ret = str(h_fun(ins)) + if sys.hexversion > 0x3000000: + ret = ret.encode('latin-1', 'xmlcharrefreplace') + return ret + +reg_subst = re.compile(r"(\\\\)|(\$\$)|\$\{([^}]+)\}") +def subst_vars(expr, params): + """ + Replaces ${VAR} with the value of VAR taken from a dict or a config set:: + + from waflib import Utils + s = Utils.subst_vars('${PREFIX}/bin', env) + + :type expr: string + :param expr: String to perform substitution on + :param params: Dictionary or config set to look up variable values. + """ + def repl_var(m): + if m.group(1): + return '\\' + if m.group(2): + return '$' + try: + # ConfigSet instances may contain lists + return params.get_flat(m.group(3)) + except AttributeError: + return params[m.group(3)] + # if you get a TypeError, it means that 'expr' is not a string... + # Utils.subst_vars(None, env) will not work + return reg_subst.sub(repl_var, expr) + +def destos_to_binfmt(key): + """ + Returns the binary format based on the unversioned platform name, + and defaults to ``elf`` if nothing is found. + + :param key: platform name + :type key: string + :return: string representing the binary format + """ + if key == 'darwin': + return 'mac-o' + elif key in ('win32', 'cygwin', 'uwin', 'msys'): + return 'pe' + return 'elf' + +def unversioned_sys_platform(): + """ + Returns the unversioned platform name. + Some Python platform names contain versions, that depend on + the build environment, e.g. linux2, freebsd6, etc. + This returns the name without the version number. Exceptions are + os2 and win32, which are returned verbatim. + + :rtype: string + :return: Unversioned platform name + """ + s = sys.platform + if s.startswith('java'): + # The real OS is hidden under the JVM. + from java.lang import System + s = System.getProperty('os.name') + # see http://lopica.sourceforge.net/os.html for a list of possible values + if s == 'Mac OS X': + return 'darwin' + elif s.startswith('Windows '): + return 'win32' + elif s == 'OS/2': + return 'os2' + elif s == 'HP-UX': + return 'hp-ux' + elif s in ('SunOS', 'Solaris'): + return 'sunos' + else: s = s.lower() + + # powerpc == darwin for our purposes + if s == 'powerpc': + return 'darwin' + if s == 'win32' or s == 'os2': + return s + if s == 'cli' and os.name == 'nt': + # ironpython is only on windows as far as we know + return 'win32' + return re.split(r'\d+$', s)[0] + +def nada(*k, **kw): + """ + Does nothing + + :return: None + """ + pass + +class Timer(object): + """ + Simple object for timing the execution of commands. + Its string representation is the duration:: + + from waflib.Utils import Timer + timer = Timer() + a_few_operations() + s = str(timer) + """ + def __init__(self): + self.start_time = self.now() + + def __str__(self): + delta = self.now() - self.start_time + if not isinstance(delta, datetime.timedelta): + delta = datetime.timedelta(seconds=delta) + days = delta.days + hours, rem = divmod(delta.seconds, 3600) + minutes, seconds = divmod(rem, 60) + seconds += delta.microseconds * 1e-6 + result = '' + if days: + result += '%dd' % days + if days or hours: + result += '%dh' % hours + if days or hours or minutes: + result += '%dm' % minutes + return '%s%.3fs' % (result, seconds) + + def now(self): + return datetime.datetime.utcnow() + + if hasattr(time, 'perf_counter'): + def now(self): + return time.perf_counter() + +def read_la_file(path): + """ + Reads property files, used by msvc.py + + :param path: file to read + :type path: string + """ + sp = re.compile(r'^([^=]+)=\'(.*)\'$') + dc = {} + for line in readf(path).splitlines(): + try: + _, left, right, _ = sp.split(line.strip()) + dc[left] = right + except ValueError: + pass + return dc + +def run_once(fun): + """ + Decorator: let a function cache its results, use like this:: + + @run_once + def foo(k): + return 345*2343 + + .. note:: in practice this can cause memory leaks, prefer a :py:class:`waflib.Utils.lru_cache` + + :param fun: function to execute + :type fun: function + :return: the return value of the function executed + """ + cache = {} + def wrap(*k): + try: + return cache[k] + except KeyError: + ret = fun(*k) + cache[k] = ret + return ret + wrap.__cache__ = cache + wrap.__name__ = fun.__name__ + return wrap + +def get_registry_app_path(key, filename): + """ + Returns the value of a registry key for an executable + + :type key: string + :type filename: list of string + """ + if not winreg: + return None + try: + result = winreg.QueryValue(key, "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\%s.exe" % filename[0]) + except OSError: + pass + else: + if os.path.isfile(result): + return result + +def lib64(): + """ + Guess the default ``/usr/lib`` extension for 64-bit applications + + :return: '64' or '' + :rtype: string + """ + # default settings for /usr/lib + if os.sep == '/': + if platform.architecture()[0] == '64bit': + if os.path.exists('/usr/lib64') and not os.path.exists('/usr/lib32'): + return '64' + return '' + +def sane_path(p): + # private function for the time being! + return os.path.abspath(os.path.expanduser(p)) + +process_pool = [] +""" +List of processes started to execute sub-process commands +""" + +def get_process(): + """ + Returns a process object that can execute commands as sub-processes + + :rtype: subprocess.Popen + """ + try: + return process_pool.pop() + except IndexError: + filepath = os.path.dirname(os.path.abspath(__file__)) + os.sep + 'processor.py' + cmd = [sys.executable, '-c', readf(filepath)] + return subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, bufsize=0, close_fds=not is_win32) + +def run_prefork_process(cmd, kwargs, cargs): + """ + Delegates process execution to a pre-forked process instance. + """ + if not 'env' in kwargs: + kwargs['env'] = dict(os.environ) + try: + obj = base64.b64encode(cPickle.dumps([cmd, kwargs, cargs])) + except (TypeError, AttributeError): + return run_regular_process(cmd, kwargs, cargs) + + proc = get_process() + if not proc: + return run_regular_process(cmd, kwargs, cargs) + + proc.stdin.write(obj) + proc.stdin.write('\n'.encode()) + proc.stdin.flush() + obj = proc.stdout.readline() + if not obj: + raise OSError('Preforked sub-process %r died' % proc.pid) + + process_pool.append(proc) + lst = cPickle.loads(base64.b64decode(obj)) + # Jython wrapper failures (bash/execvp) + assert len(lst) == 5 + ret, out, err, ex, trace = lst + if ex: + if ex == 'OSError': + raise OSError(trace) + elif ex == 'ValueError': + raise ValueError(trace) + elif ex == 'TimeoutExpired': + exc = TimeoutExpired(cmd, timeout=cargs['timeout'], output=out) + exc.stderr = err + raise exc + else: + raise Exception(trace) + return ret, out, err + +def lchown(path, user=-1, group=-1): + """ + Change the owner/group of a path, raises an OSError if the + ownership change fails. + + :param user: user to change + :type user: int or str + :param group: group to change + :type group: int or str + """ + if isinstance(user, str): + import pwd + entry = pwd.getpwnam(user) + if not entry: + raise OSError('Unknown user %r' % user) + user = entry[2] + if isinstance(group, str): + import grp + entry = grp.getgrnam(group) + if not entry: + raise OSError('Unknown group %r' % group) + group = entry[2] + return os.lchown(path, user, group) + +def run_regular_process(cmd, kwargs, cargs={}): + """ + Executes a subprocess command by using subprocess.Popen + """ + proc = subprocess.Popen(cmd, **kwargs) + if kwargs.get('stdout') or kwargs.get('stderr'): + try: + out, err = proc.communicate(**cargs) + except TimeoutExpired: + if kwargs.get('start_new_session') and hasattr(os, 'killpg'): + os.killpg(proc.pid, signal.SIGKILL) + else: + proc.kill() + out, err = proc.communicate() + exc = TimeoutExpired(proc.args, timeout=cargs['timeout'], output=out) + exc.stderr = err + raise exc + status = proc.returncode + else: + out, err = (None, None) + try: + status = proc.wait(**cargs) + except TimeoutExpired as e: + if kwargs.get('start_new_session') and hasattr(os, 'killpg'): + os.killpg(proc.pid, signal.SIGKILL) + else: + proc.kill() + proc.wait() + raise e + return status, out, err + +def run_process(cmd, kwargs, cargs={}): + """ + Executes a subprocess by using a pre-forked process when possible + or falling back to subprocess.Popen. See :py:func:`waflib.Utils.run_prefork_process` + and :py:func:`waflib.Utils.run_regular_process` + """ + if kwargs.get('stdout') and kwargs.get('stderr'): + return run_prefork_process(cmd, kwargs, cargs) + else: + return run_regular_process(cmd, kwargs, cargs) + +def alloc_process_pool(n, force=False): + """ + Allocates an amount of processes to the default pool so its size is at least *n*. + It is useful to call this function early so that the pre-forked + processes use as little memory as possible. + + :param n: pool size + :type n: integer + :param force: if True then *n* more processes are added to the existing pool + :type force: bool + """ + # mandatory on python2, unnecessary on python >= 3.2 + global run_process, get_process, alloc_process_pool + if not force: + n = max(n - len(process_pool), 0) + try: + lst = [get_process() for x in range(n)] + except OSError: + run_process = run_regular_process + get_process = alloc_process_pool = nada + else: + for x in lst: + process_pool.append(x) + +def atexit_pool(): + for k in process_pool: + try: + os.kill(k.pid, 9) + except OSError: + pass + else: + k.wait() +# see #1889 +if (sys.hexversion<0x207000f and not is_win32) or sys.hexversion>=0x306000f: + atexit.register(atexit_pool) + +if os.environ.get('WAF_NO_PREFORK') or sys.platform == 'cli' or not sys.executable: + run_process = run_regular_process + get_process = alloc_process_pool = nada + diff --git a/ldb-2.0.8/third_party/waf/waflib/__init__.py b/ldb-2.0.8/third_party/waf/waflib/__init__.py new file mode 100644 index 0000000..079df35 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/__init__.py @@ -0,0 +1,3 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2005-2018 (ita) diff --git a/ldb-2.0.8/third_party/waf/waflib/ansiterm.py b/ldb-2.0.8/third_party/waf/waflib/ansiterm.py new file mode 100644 index 0000000..027f0ad --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/ansiterm.py @@ -0,0 +1,342 @@ +#!/usr/bin/env python +# encoding: utf-8 + +""" +Emulate a vt100 terminal in cmd.exe + +By wrapping sys.stdout / sys.stderr with Ansiterm, +the vt100 escape characters will be interpreted and +the equivalent actions will be performed with Win32 +console commands. + +""" + +import os, re, sys +from waflib import Utils + +wlock = Utils.threading.Lock() + +try: + from ctypes import Structure, windll, c_short, c_ushort, c_ulong, c_int, byref, c_wchar, POINTER, c_long +except ImportError: + + class AnsiTerm(object): + def __init__(self, stream): + self.stream = stream + try: + self.errors = self.stream.errors + except AttributeError: + pass # python 2.5 + self.encoding = self.stream.encoding + + def write(self, txt): + try: + wlock.acquire() + self.stream.write(txt) + self.stream.flush() + finally: + wlock.release() + + def fileno(self): + return self.stream.fileno() + + def flush(self): + self.stream.flush() + + def isatty(self): + return self.stream.isatty() +else: + + class COORD(Structure): + _fields_ = [("X", c_short), ("Y", c_short)] + + class SMALL_RECT(Structure): + _fields_ = [("Left", c_short), ("Top", c_short), ("Right", c_short), ("Bottom", c_short)] + + class CONSOLE_SCREEN_BUFFER_INFO(Structure): + _fields_ = [("Size", COORD), ("CursorPosition", COORD), ("Attributes", c_ushort), ("Window", SMALL_RECT), ("MaximumWindowSize", COORD)] + + class CONSOLE_CURSOR_INFO(Structure): + _fields_ = [('dwSize', c_ulong), ('bVisible', c_int)] + + try: + _type = unicode + except NameError: + _type = str + + to_int = lambda number, default: number and int(number) or default + + STD_OUTPUT_HANDLE = -11 + STD_ERROR_HANDLE = -12 + + windll.kernel32.GetStdHandle.argtypes = [c_ulong] + windll.kernel32.GetStdHandle.restype = c_ulong + windll.kernel32.GetConsoleScreenBufferInfo.argtypes = [c_ulong, POINTER(CONSOLE_SCREEN_BUFFER_INFO)] + windll.kernel32.GetConsoleScreenBufferInfo.restype = c_long + windll.kernel32.SetConsoleTextAttribute.argtypes = [c_ulong, c_ushort] + windll.kernel32.SetConsoleTextAttribute.restype = c_long + windll.kernel32.FillConsoleOutputCharacterW.argtypes = [c_ulong, c_wchar, c_ulong, POINTER(COORD), POINTER(c_ulong)] + windll.kernel32.FillConsoleOutputCharacterW.restype = c_long + windll.kernel32.FillConsoleOutputAttribute.argtypes = [c_ulong, c_ushort, c_ulong, POINTER(COORD), POINTER(c_ulong) ] + windll.kernel32.FillConsoleOutputAttribute.restype = c_long + windll.kernel32.SetConsoleCursorPosition.argtypes = [c_ulong, POINTER(COORD) ] + windll.kernel32.SetConsoleCursorPosition.restype = c_long + windll.kernel32.SetConsoleCursorInfo.argtypes = [c_ulong, POINTER(CONSOLE_CURSOR_INFO)] + windll.kernel32.SetConsoleCursorInfo.restype = c_long + + class AnsiTerm(object): + """ + emulate a vt100 terminal in cmd.exe + """ + def __init__(self, s): + self.stream = s + try: + self.errors = s.errors + except AttributeError: + pass # python2.5 + self.encoding = s.encoding + self.cursor_history = [] + + handle = (s.fileno() == 2) and STD_ERROR_HANDLE or STD_OUTPUT_HANDLE + self.hconsole = windll.kernel32.GetStdHandle(handle) + + self._sbinfo = CONSOLE_SCREEN_BUFFER_INFO() + + self._csinfo = CONSOLE_CURSOR_INFO() + windll.kernel32.GetConsoleCursorInfo(self.hconsole, byref(self._csinfo)) + + # just to double check that the console is usable + self._orig_sbinfo = CONSOLE_SCREEN_BUFFER_INFO() + r = windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole, byref(self._orig_sbinfo)) + self._isatty = r == 1 + + def screen_buffer_info(self): + """ + Updates self._sbinfo and returns it + """ + windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole, byref(self._sbinfo)) + return self._sbinfo + + def clear_line(self, param): + mode = param and int(param) or 0 + sbinfo = self.screen_buffer_info() + if mode == 1: # Clear from beginning of line to cursor position + line_start = COORD(0, sbinfo.CursorPosition.Y) + line_length = sbinfo.Size.X + elif mode == 2: # Clear entire line + line_start = COORD(sbinfo.CursorPosition.X, sbinfo.CursorPosition.Y) + line_length = sbinfo.Size.X - sbinfo.CursorPosition.X + else: # Clear from cursor position to end of line + line_start = sbinfo.CursorPosition + line_length = sbinfo.Size.X - sbinfo.CursorPosition.X + chars_written = c_ulong() + windll.kernel32.FillConsoleOutputCharacterW(self.hconsole, c_wchar(' '), line_length, line_start, byref(chars_written)) + windll.kernel32.FillConsoleOutputAttribute(self.hconsole, sbinfo.Attributes, line_length, line_start, byref(chars_written)) + + def clear_screen(self, param): + mode = to_int(param, 0) + sbinfo = self.screen_buffer_info() + if mode == 1: # Clear from beginning of screen to cursor position + clear_start = COORD(0, 0) + clear_length = sbinfo.CursorPosition.X * sbinfo.CursorPosition.Y + elif mode == 2: # Clear entire screen and return cursor to home + clear_start = COORD(0, 0) + clear_length = sbinfo.Size.X * sbinfo.Size.Y + windll.kernel32.SetConsoleCursorPosition(self.hconsole, clear_start) + else: # Clear from cursor position to end of screen + clear_start = sbinfo.CursorPosition + clear_length = ((sbinfo.Size.X - sbinfo.CursorPosition.X) + sbinfo.Size.X * (sbinfo.Size.Y - sbinfo.CursorPosition.Y)) + chars_written = c_ulong() + windll.kernel32.FillConsoleOutputCharacterW(self.hconsole, c_wchar(' '), clear_length, clear_start, byref(chars_written)) + windll.kernel32.FillConsoleOutputAttribute(self.hconsole, sbinfo.Attributes, clear_length, clear_start, byref(chars_written)) + + def push_cursor(self, param): + sbinfo = self.screen_buffer_info() + self.cursor_history.append(sbinfo.CursorPosition) + + def pop_cursor(self, param): + if self.cursor_history: + old_pos = self.cursor_history.pop() + windll.kernel32.SetConsoleCursorPosition(self.hconsole, old_pos) + + def set_cursor(self, param): + y, sep, x = param.partition(';') + x = to_int(x, 1) - 1 + y = to_int(y, 1) - 1 + sbinfo = self.screen_buffer_info() + new_pos = COORD( + min(max(0, x), sbinfo.Size.X), + min(max(0, y), sbinfo.Size.Y) + ) + windll.kernel32.SetConsoleCursorPosition(self.hconsole, new_pos) + + def set_column(self, param): + x = to_int(param, 1) - 1 + sbinfo = self.screen_buffer_info() + new_pos = COORD( + min(max(0, x), sbinfo.Size.X), + sbinfo.CursorPosition.Y + ) + windll.kernel32.SetConsoleCursorPosition(self.hconsole, new_pos) + + def move_cursor(self, x_offset=0, y_offset=0): + sbinfo = self.screen_buffer_info() + new_pos = COORD( + min(max(0, sbinfo.CursorPosition.X + x_offset), sbinfo.Size.X), + min(max(0, sbinfo.CursorPosition.Y + y_offset), sbinfo.Size.Y) + ) + windll.kernel32.SetConsoleCursorPosition(self.hconsole, new_pos) + + def move_up(self, param): + self.move_cursor(y_offset = -to_int(param, 1)) + + def move_down(self, param): + self.move_cursor(y_offset = to_int(param, 1)) + + def move_left(self, param): + self.move_cursor(x_offset = -to_int(param, 1)) + + def move_right(self, param): + self.move_cursor(x_offset = to_int(param, 1)) + + def next_line(self, param): + sbinfo = self.screen_buffer_info() + self.move_cursor( + x_offset = -sbinfo.CursorPosition.X, + y_offset = to_int(param, 1) + ) + + def prev_line(self, param): + sbinfo = self.screen_buffer_info() + self.move_cursor( + x_offset = -sbinfo.CursorPosition.X, + y_offset = -to_int(param, 1) + ) + + def rgb2bgr(self, c): + return ((c&1) << 2) | (c&2) | ((c&4)>>2) + + def set_color(self, param): + cols = param.split(';') + sbinfo = self.screen_buffer_info() + attr = sbinfo.Attributes + for c in cols: + c = to_int(c, 0) + if 29 < c < 38: # fgcolor + attr = (attr & 0xfff0) | self.rgb2bgr(c - 30) + elif 39 < c < 48: # bgcolor + attr = (attr & 0xff0f) | (self.rgb2bgr(c - 40) << 4) + elif c == 0: # reset + attr = self._orig_sbinfo.Attributes + elif c == 1: # strong + attr |= 0x08 + elif c == 4: # blink not available -> bg intensity + attr |= 0x80 + elif c == 7: # negative + attr = (attr & 0xff88) | ((attr & 0x70) >> 4) | ((attr & 0x07) << 4) + + windll.kernel32.SetConsoleTextAttribute(self.hconsole, attr) + + def show_cursor(self,param): + self._csinfo.bVisible = 1 + windll.kernel32.SetConsoleCursorInfo(self.hconsole, byref(self._csinfo)) + + def hide_cursor(self,param): + self._csinfo.bVisible = 0 + windll.kernel32.SetConsoleCursorInfo(self.hconsole, byref(self._csinfo)) + + ansi_command_table = { + 'A': move_up, + 'B': move_down, + 'C': move_right, + 'D': move_left, + 'E': next_line, + 'F': prev_line, + 'G': set_column, + 'H': set_cursor, + 'f': set_cursor, + 'J': clear_screen, + 'K': clear_line, + 'h': show_cursor, + 'l': hide_cursor, + 'm': set_color, + 's': push_cursor, + 'u': pop_cursor, + } + # Match either the escape sequence or text not containing escape sequence + ansi_tokens = re.compile(r'(?:\x1b\[([0-9?;]*)([a-zA-Z])|([^\x1b]+))') + def write(self, text): + try: + wlock.acquire() + if self._isatty: + for param, cmd, txt in self.ansi_tokens.findall(text): + if cmd: + cmd_func = self.ansi_command_table.get(cmd) + if cmd_func: + cmd_func(self, param) + else: + self.writeconsole(txt) + else: + # no support for colors in the console, just output the text: + # eclipse or msys may be able to interpret the escape sequences + self.stream.write(text) + finally: + wlock.release() + + def writeconsole(self, txt): + chars_written = c_ulong() + writeconsole = windll.kernel32.WriteConsoleA + if isinstance(txt, _type): + writeconsole = windll.kernel32.WriteConsoleW + + # MSDN says that there is a shared buffer of 64 KB for the console + # writes. Attempt to not get ERROR_NOT_ENOUGH_MEMORY, see waf issue #746 + done = 0 + todo = len(txt) + chunk = 32<<10 + while todo != 0: + doing = min(chunk, todo) + buf = txt[done:done+doing] + r = writeconsole(self.hconsole, buf, doing, byref(chars_written), None) + if r == 0: + chunk >>= 1 + continue + done += doing + todo -= doing + + + def fileno(self): + return self.stream.fileno() + + def flush(self): + pass + + def isatty(self): + return self._isatty + + if sys.stdout.isatty() or sys.stderr.isatty(): + handle = sys.stdout.isatty() and STD_OUTPUT_HANDLE or STD_ERROR_HANDLE + console = windll.kernel32.GetStdHandle(handle) + sbinfo = CONSOLE_SCREEN_BUFFER_INFO() + def get_term_cols(): + windll.kernel32.GetConsoleScreenBufferInfo(console, byref(sbinfo)) + # Issue 1401 - the progress bar cannot reach the last character + return sbinfo.Size.X - 1 + +# just try and see +try: + import struct, fcntl, termios +except ImportError: + pass +else: + if (sys.stdout.isatty() or sys.stderr.isatty()) and os.environ.get('TERM', '') not in ('dumb', 'emacs'): + FD = sys.stdout.isatty() and sys.stdout.fileno() or sys.stderr.fileno() + def fun(): + return struct.unpack("HHHH", fcntl.ioctl(FD, termios.TIOCGWINSZ, struct.pack("HHHH", 0, 0, 0, 0)))[1] + try: + fun() + except Exception as e: + pass + else: + get_term_cols = fun + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/__init__.py b/ldb-2.0.8/third_party/waf/waflib/extras/__init__.py new file mode 100644 index 0000000..c8a3c34 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/__init__.py @@ -0,0 +1,3 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2005-2010 (ita) diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/batched_cc.py b/ldb-2.0.8/third_party/waf/waflib/extras/batched_cc.py new file mode 100644 index 0000000..aad2872 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/batched_cc.py @@ -0,0 +1,173 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2006-2015 (ita) + +""" +Instead of compiling object files one by one, c/c++ compilers are often able to compile at once: +cc -c ../file1.c ../file2.c ../file3.c + +Files are output on the directory where the compiler is called, and dependencies are more difficult +to track (do not run the command on all source files if only one file changes) +As such, we do as if the files were compiled one by one, but no command is actually run: +replace each cc/cpp Task by a TaskSlave. A new task called TaskMaster collects the +signatures from each slave and finds out the command-line to run. + +Just import this module to start using it: +def build(bld): + bld.load('batched_cc') + +Note that this is provided as an example, unity builds are recommended +for best performance results (fewer tasks and fewer jobs to execute). +See waflib/extras/unity.py. +""" + +from waflib import Task, Utils +from waflib.TaskGen import extension, feature, after_method +from waflib.Tools import c, cxx + +MAX_BATCH = 50 + +c_str = '${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${tsk.batch_incpaths()} ${DEFINES_ST:DEFINES} -c ${SRCLST} ${CXX_TGT_F_BATCHED} ${CPPFLAGS}' +c_fun, _ = Task.compile_fun_noshell(c_str) + +cxx_str = '${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${tsk.batch_incpaths()} ${DEFINES_ST:DEFINES} -c ${SRCLST} ${CXX_TGT_F_BATCHED} ${CPPFLAGS}' +cxx_fun, _ = Task.compile_fun_noshell(cxx_str) + +count = 70000 +class batch(Task.Task): + color = 'PINK' + + after = ['c', 'cxx'] + before = ['cprogram', 'cshlib', 'cstlib', 'cxxprogram', 'cxxshlib', 'cxxstlib'] + + def uid(self): + return Utils.h_list([Task.Task.uid(self), self.generator.idx, self.generator.path.abspath(), self.generator.target]) + + def __str__(self): + return 'Batch compilation for %d slaves' % len(self.slaves) + + def __init__(self, *k, **kw): + Task.Task.__init__(self, *k, **kw) + self.slaves = [] + self.inputs = [] + self.hasrun = 0 + + global count + count += 1 + self.idx = count + + def add_slave(self, slave): + self.slaves.append(slave) + self.set_run_after(slave) + + def runnable_status(self): + for t in self.run_after: + if not t.hasrun: + return Task.ASK_LATER + + for t in self.slaves: + #if t.executed: + if t.hasrun != Task.SKIPPED: + return Task.RUN_ME + + return Task.SKIP_ME + + def get_cwd(self): + return self.slaves[0].outputs[0].parent + + def batch_incpaths(self): + st = self.env.CPPPATH_ST + return [st % node.abspath() for node in self.generator.includes_nodes] + + def run(self): + self.outputs = [] + + srclst = [] + slaves = [] + for t in self.slaves: + if t.hasrun != Task.SKIPPED: + slaves.append(t) + srclst.append(t.inputs[0].abspath()) + + self.env.SRCLST = srclst + + if self.slaves[0].__class__.__name__ == 'c': + ret = c_fun(self) + else: + ret = cxx_fun(self) + + if ret: + return ret + + for t in slaves: + t.old_post_run() + +def hook(cls_type): + def n_hook(self, node): + + ext = '.obj' if self.env.CC_NAME == 'msvc' else '.o' + name = node.name + k = name.rfind('.') + if k >= 0: + basename = name[:k] + ext + else: + basename = name + ext + + outdir = node.parent.get_bld().make_node('%d' % self.idx) + outdir.mkdir() + out = outdir.find_or_declare(basename) + + task = self.create_task(cls_type, node, out) + + try: + self.compiled_tasks.append(task) + except AttributeError: + self.compiled_tasks = [task] + + if not getattr(self, 'masters', None): + self.masters = {} + self.allmasters = [] + + def fix_path(tsk): + if self.env.CC_NAME == 'msvc': + tsk.env.append_unique('CXX_TGT_F_BATCHED', '/Fo%s\\' % outdir.abspath()) + + if not node.parent in self.masters: + m = self.masters[node.parent] = self.master = self.create_task('batch') + fix_path(m) + self.allmasters.append(m) + else: + m = self.masters[node.parent] + if len(m.slaves) > MAX_BATCH: + m = self.masters[node.parent] = self.master = self.create_task('batch') + fix_path(m) + self.allmasters.append(m) + m.add_slave(task) + return task + return n_hook + +extension('.c')(hook('c')) +extension('.cpp','.cc','.cxx','.C','.c++')(hook('cxx')) + +@feature('cprogram', 'cshlib', 'cstaticlib', 'cxxprogram', 'cxxshlib', 'cxxstlib') +@after_method('apply_link') +def link_after_masters(self): + if getattr(self, 'allmasters', None): + for m in self.allmasters: + self.link_task.set_run_after(m) + +# Modify the c and cxx task classes - in theory it would be best to +# create subclasses and to re-map the c/c++ extensions +for x in ('c', 'cxx'): + t = Task.classes[x] + def run(self): + pass + + def post_run(self): + pass + + setattr(t, 'oldrun', getattr(t, 'run', None)) + setattr(t, 'run', run) + setattr(t, 'old_post_run', t.post_run) + setattr(t, 'post_run', post_run) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/biber.py b/ldb-2.0.8/third_party/waf/waflib/extras/biber.py new file mode 100644 index 0000000..fd9db4e --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/biber.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2011 (ita) + +""" +Latex processing using "biber" +""" + +import os +from waflib import Task, Logs + +from waflib.Tools import tex as texmodule + +class tex(texmodule.tex): + biber_fun, _ = Task.compile_fun('${BIBER} ${BIBERFLAGS} ${SRCFILE}',shell=False) + biber_fun.__doc__ = """ + Execute the program **biber** + """ + + def bibfile(self): + return None + + def bibunits(self): + self.env.env = {} + self.env.env.update(os.environ) + self.env.env.update({'BIBINPUTS': self.texinputs(), 'BSTINPUTS': self.texinputs()}) + self.env.SRCFILE = self.aux_nodes[0].name[:-4] + + if not self.env['PROMPT_LATEX']: + self.env.append_unique('BIBERFLAGS', '--quiet') + + path = self.aux_nodes[0].abspath()[:-4] + '.bcf' + if os.path.isfile(path): + Logs.warn('calling biber') + self.check_status('error when calling biber, check %s.blg for errors' % (self.env.SRCFILE), self.biber_fun()) + else: + super(tex, self).bibfile() + super(tex, self).bibunits() + +class latex(tex): + texfun, vars = Task.compile_fun('${LATEX} ${LATEXFLAGS} ${SRCFILE}', shell=False) +class pdflatex(tex): + texfun, vars = Task.compile_fun('${PDFLATEX} ${PDFLATEXFLAGS} ${SRCFILE}', shell=False) +class xelatex(tex): + texfun, vars = Task.compile_fun('${XELATEX} ${XELATEXFLAGS} ${SRCFILE}', shell=False) + +def configure(self): + """ + Almost the same as in tex.py, but try to detect 'biber' + """ + v = self.env + for p in ' biber tex latex pdflatex xelatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps'.split(): + try: + self.find_program(p, var=p.upper()) + except self.errors.ConfigurationError: + pass + v['DVIPSFLAGS'] = '-Ppdf' + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/bjam.py b/ldb-2.0.8/third_party/waf/waflib/extras/bjam.py new file mode 100644 index 0000000..8e04d3a --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/bjam.py @@ -0,0 +1,128 @@ +#! /usr/bin/env python +# per rosengren 2011 + +from os import sep, readlink +from waflib import Logs +from waflib.TaskGen import feature, after_method +from waflib.Task import Task, always_run + +def options(opt): + grp = opt.add_option_group('Bjam Options') + grp.add_option('--bjam_src', default=None, help='You can find it in /tools/jam/src') + grp.add_option('--bjam_uname', default='linuxx86_64', help='bjam is built in /bin./bjam') + grp.add_option('--bjam_config', default=None) + grp.add_option('--bjam_toolset', default=None) + +def configure(cnf): + if not cnf.env.BJAM_SRC: + cnf.env.BJAM_SRC = cnf.options.bjam_src + if not cnf.env.BJAM_UNAME: + cnf.env.BJAM_UNAME = cnf.options.bjam_uname + try: + cnf.find_program('bjam', path_list=[ + cnf.env.BJAM_SRC + sep + 'bin.' + cnf.env.BJAM_UNAME + ]) + except Exception: + cnf.env.BJAM = None + if not cnf.env.BJAM_CONFIG: + cnf.env.BJAM_CONFIG = cnf.options.bjam_config + if not cnf.env.BJAM_TOOLSET: + cnf.env.BJAM_TOOLSET = cnf.options.bjam_toolset + +@feature('bjam') +@after_method('process_rule') +def process_bjam(self): + if not self.bld.env.BJAM: + self.create_task('bjam_creator') + self.create_task('bjam_build') + self.create_task('bjam_installer') + if getattr(self, 'always', False): + always_run(bjam_creator) + always_run(bjam_build) + always_run(bjam_installer) + +class bjam_creator(Task): + ext_out = 'bjam_exe' + vars=['BJAM_SRC', 'BJAM_UNAME'] + def run(self): + env = self.env + gen = self.generator + bjam = gen.bld.root.find_dir(env.BJAM_SRC) + if not bjam: + Logs.error('Can not find bjam source') + return -1 + bjam_exe_relpath = 'bin.' + env.BJAM_UNAME + '/bjam' + bjam_exe = bjam.find_resource(bjam_exe_relpath) + if bjam_exe: + env.BJAM = bjam_exe.srcpath() + return 0 + bjam_cmd = ['./build.sh'] + Logs.debug('runner: ' + bjam.srcpath() + '> ' + str(bjam_cmd)) + result = self.exec_command(bjam_cmd, cwd=bjam.srcpath()) + if not result == 0: + Logs.error('bjam failed') + return -1 + bjam_exe = bjam.find_resource(bjam_exe_relpath) + if bjam_exe: + env.BJAM = bjam_exe.srcpath() + return 0 + Logs.error('bjam failed') + return -1 + +class bjam_build(Task): + ext_in = 'bjam_exe' + ext_out = 'install' + vars = ['BJAM_TOOLSET'] + def run(self): + env = self.env + gen = self.generator + path = gen.path + bld = gen.bld + if hasattr(gen, 'root'): + build_root = path.find_node(gen.root) + else: + build_root = path + jam = bld.srcnode.find_resource(env.BJAM_CONFIG) + if jam: + Logs.debug('bjam: Using jam configuration from ' + jam.srcpath()) + jam_rel = jam.relpath_gen(build_root) + else: + Logs.warn('No build configuration in build_config/user-config.jam. Using default') + jam_rel = None + bjam_exe = bld.srcnode.find_node(env.BJAM) + if not bjam_exe: + Logs.error('env.BJAM is not set') + return -1 + bjam_exe_rel = bjam_exe.relpath_gen(build_root) + cmd = ([bjam_exe_rel] + + (['--user-config=' + jam_rel] if jam_rel else []) + + ['--stagedir=' + path.get_bld().path_from(build_root)] + + ['--debug-configuration'] + + ['--with-' + lib for lib in self.generator.target] + + (['toolset=' + env.BJAM_TOOLSET] if env.BJAM_TOOLSET else []) + + ['link=' + 'shared'] + + ['variant=' + 'release'] + ) + Logs.debug('runner: ' + build_root.srcpath() + '> ' + str(cmd)) + ret = self.exec_command(cmd, cwd=build_root.srcpath()) + if ret != 0: + return ret + self.set_outputs(path.get_bld().ant_glob('lib/*') + path.get_bld().ant_glob('bin/*')) + return 0 + +class bjam_installer(Task): + ext_in = 'install' + def run(self): + gen = self.generator + path = gen.path + for idir, pat in (('${LIBDIR}', 'lib/*'), ('${BINDIR}', 'bin/*')): + files = [] + for n in path.get_bld().ant_glob(pat): + try: + t = readlink(n.srcpath()) + gen.bld.symlink_as(sep.join([idir, n.name]), t, postpone=False) + except OSError: + files.append(n) + gen.bld.install_files(idir, files, postpone=False) + return 0 + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/blender.py b/ldb-2.0.8/third_party/waf/waflib/extras/blender.py new file mode 100644 index 0000000..e5efc28 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/blender.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Michal Proszek, 2014 (poxip) + +""" +Detect the version of Blender, path +and install the extension: + + def options(opt): + opt.load('blender') + def configure(cnf): + cnf.load('blender') + def build(bld): + bld(name='io_mesh_raw', + feature='blender', + files=['file1.py', 'file2.py'] + ) +If name variable is empty, files are installed in scripts/addons, otherwise scripts/addons/name +Use ./waf configure --system to set the installation directory to system path +""" +import os +import re +from getpass import getuser + +from waflib import Utils +from waflib.TaskGen import feature +from waflib.Configure import conf + +def options(opt): + opt.add_option( + '-s', '--system', + dest='directory_system', + default=False, + action='store_true', + help='determines installation directory (default: user)' + ) + +@conf +def find_blender(ctx): + '''Return version number of blender, if not exist return None''' + blender = ctx.find_program('blender') + output = ctx.cmd_and_log(blender + ['--version']) + m = re.search(r'Blender\s*((\d+(\.|))*)', output) + if not m: + ctx.fatal('Could not retrieve blender version') + + try: + blender_version = m.group(1) + except IndexError: + ctx.fatal('Could not retrieve blender version') + + ctx.env['BLENDER_VERSION'] = blender_version + return blender + +@conf +def configure_paths(ctx): + """Setup blender paths""" + # Get the username + user = getuser() + _platform = Utils.unversioned_sys_platform() + config_path = {'user': '', 'system': ''} + if _platform.startswith('linux'): + config_path['user'] = '/home/%s/.config/blender/' % user + config_path['system'] = '/usr/share/blender/' + elif _platform == 'darwin': + # MAC OS X + config_path['user'] = \ + '/Users/%s/Library/Application Support/Blender/' % user + config_path['system'] = '/Library/Application Support/Blender/' + elif Utils.is_win32: + # Windows + appdata_path = ctx.getenv('APPDATA').replace('\\', '/') + homedrive = ctx.getenv('HOMEDRIVE').replace('\\', '/') + + config_path['user'] = '%s/Blender Foundation/Blender/' % appdata_path + config_path['system'] = \ + '%sAll Users/AppData/Roaming/Blender Foundation/Blender/' % homedrive + else: + ctx.fatal( + 'Unsupported platform. ' + 'Available platforms: Linux, OSX, MS-Windows.' + ) + + blender_version = ctx.env['BLENDER_VERSION'] + + config_path['user'] += blender_version + '/' + config_path['system'] += blender_version + '/' + + ctx.env['BLENDER_CONFIG_DIR'] = os.path.abspath(config_path['user']) + if ctx.options.directory_system: + ctx.env['BLENDER_CONFIG_DIR'] = config_path['system'] + + ctx.env['BLENDER_ADDONS_DIR'] = os.path.join( + ctx.env['BLENDER_CONFIG_DIR'], 'scripts/addons' + ) + Utils.check_dir(ctx.env['BLENDER_ADDONS_DIR']) + +def configure(ctx): + ctx.find_blender() + ctx.configure_paths() + +@feature('blender_list') +def blender(self): + # Two ways to install a blender extension: as a module or just .py files + dest_dir = os.path.join(self.env.BLENDER_ADDONS_DIR, self.get_name()) + Utils.check_dir(dest_dir) + self.add_install_files(install_to=dest_dir, install_from=getattr(self, 'files', '.')) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/boo.py b/ldb-2.0.8/third_party/waf/waflib/extras/boo.py new file mode 100644 index 0000000..06623d4 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/boo.py @@ -0,0 +1,81 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Yannick LM 2011 + +""" +Support for the boo programming language, for example:: + + bld(features = "boo", # necessary feature + source = "src.boo", # list of boo files + gen = "world.dll", # target + type = "library", # library/exe ("-target:xyz" flag) + name = "world" # necessary if the target is referenced by 'use' + ) +""" + +from waflib import Task +from waflib.Configure import conf +from waflib.TaskGen import feature, after_method, before_method, extension + +@extension('.boo') +def boo_hook(self, node): + # Nothing here yet ... + # TODO filter the non-boo source files in 'apply_booc' and remove this method + pass + +@feature('boo') +@before_method('process_source') +def apply_booc(self): + """Create a booc task """ + src_nodes = self.to_nodes(self.source) + out_node = self.path.find_or_declare(self.gen) + + self.boo_task = self.create_task('booc', src_nodes, [out_node]) + + # Set variables used by the 'booc' task + self.boo_task.env.OUT = '-o:%s' % out_node.abspath() + + # type is "exe" by default + type = getattr(self, "type", "exe") + self.boo_task.env.BOO_TARGET_TYPE = "-target:%s" % type + +@feature('boo') +@after_method('apply_boo') +def use_boo(self): + """" + boo applications honor the **use** keyword:: + """ + dep_names = self.to_list(getattr(self, 'use', [])) + for dep_name in dep_names: + dep_task_gen = self.bld.get_tgen_by_name(dep_name) + if not dep_task_gen: + continue + dep_task_gen.post() + dep_task = getattr(dep_task_gen, 'boo_task', None) + if not dep_task: + # Try a cs task: + dep_task = getattr(dep_task_gen, 'cs_task', None) + if not dep_task: + # Try a link task: + dep_task = getattr(dep_task, 'link_task', None) + if not dep_task: + # Abort ... + continue + self.boo_task.set_run_after(dep_task) # order + self.boo_task.dep_nodes.extend(dep_task.outputs) # dependency + self.boo_task.env.append_value('BOO_FLAGS', '-reference:%s' % dep_task.outputs[0].abspath()) + +class booc(Task.Task): + """Compiles .boo files """ + color = 'YELLOW' + run_str = '${BOOC} ${BOO_FLAGS} ${BOO_TARGET_TYPE} ${OUT} ${SRC}' + +@conf +def check_booc(self): + self.find_program('booc', 'BOOC') + self.env.BOO_FLAGS = ['-nologo'] + +def configure(self): + """Check that booc is available """ + self.check_booc() + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/boost.py b/ldb-2.0.8/third_party/waf/waflib/extras/boost.py new file mode 100644 index 0000000..c2aaaa9 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/boost.py @@ -0,0 +1,525 @@ +#!/usr/bin/env python +# encoding: utf-8 +# +# partially based on boost.py written by Gernot Vormayr +# written by Ruediger Sonderfeld , 2008 +# modified by Bjoern Michaelsen, 2008 +# modified by Luca Fossati, 2008 +# rewritten for waf 1.5.1, Thomas Nagy, 2008 +# rewritten for waf 1.6.2, Sylvain Rouquette, 2011 + +''' + +This is an extra tool, not bundled with the default waf binary. +To add the boost tool to the waf file: +$ ./waf-light --tools=compat15,boost + or, if you have waf >= 1.6.2 +$ ./waf update --files=boost + +When using this tool, the wscript will look like: + + def options(opt): + opt.load('compiler_cxx boost') + + def configure(conf): + conf.load('compiler_cxx boost') + conf.check_boost(lib='system filesystem') + + def build(bld): + bld(source='main.cpp', target='app', use='BOOST') + +Options are generated, in order to specify the location of boost includes/libraries. +The `check_boost` configuration function allows to specify the used boost libraries. +It can also provide default arguments to the --boost-mt command-line arguments. +Everything will be packaged together in a BOOST component that you can use. + +When using MSVC, a lot of compilation flags need to match your BOOST build configuration: + - you may have to add /EHsc to your CXXFLAGS or define boost::throw_exception if BOOST_NO_EXCEPTIONS is defined. + Errors: C4530 + - boost libraries will try to be smart and use the (pretty but often not useful) auto-linking feature of MSVC + So before calling `conf.check_boost` you might want to disabling by adding + conf.env.DEFINES_BOOST += ['BOOST_ALL_NO_LIB'] + Errors: + - boost might also be compiled with /MT, which links the runtime statically. + If you have problems with redefined symbols, + self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB'] + self.env['CXXFLAGS_%s' % var] += ['/MD', '/EHsc'] +Passing `--boost-linkage_autodetect` might help ensuring having a correct linkage in some basic cases. + +''' + +import sys +import re +from waflib import Utils, Logs, Errors +from waflib.Configure import conf +from waflib.TaskGen import feature, after_method + +BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib'] +BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include'] +BOOST_VERSION_FILE = 'boost/version.hpp' +BOOST_VERSION_CODE = ''' +#include +#include +int main() { std::cout << BOOST_LIB_VERSION << ":" << BOOST_VERSION << std::endl; } +''' + +BOOST_ERROR_CODE = ''' +#include +int main() { boost::system::error_code c; } +''' + +PTHREAD_CODE = ''' +#include +static void* f(void*) { return 0; } +int main() { + pthread_t th; + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_create(&th, &attr, &f, 0); + pthread_join(th, 0); + pthread_cleanup_push(0, 0); + pthread_cleanup_pop(0); + pthread_attr_destroy(&attr); +} +''' + +BOOST_THREAD_CODE = ''' +#include +int main() { boost::thread t; } +''' + +BOOST_LOG_CODE = ''' +#include +#include +#include +int main() { + using namespace boost::log; + add_common_attributes(); + add_console_log(std::clog, keywords::format = "%Message%"); + BOOST_LOG_TRIVIAL(debug) << "log is working" << std::endl; +} +''' + +# toolsets from {boost_dir}/tools/build/v2/tools/common.jam +PLATFORM = Utils.unversioned_sys_platform() +detect_intel = lambda env: (PLATFORM == 'win32') and 'iw' or 'il' +detect_clang = lambda env: (PLATFORM == 'darwin') and 'clang-darwin' or 'clang' +detect_mingw = lambda env: (re.search('MinGW', env.CXX[0])) and 'mgw' or 'gcc' +BOOST_TOOLSETS = { + 'borland': 'bcb', + 'clang': detect_clang, + 'como': 'como', + 'cw': 'cw', + 'darwin': 'xgcc', + 'edg': 'edg', + 'g++': detect_mingw, + 'gcc': detect_mingw, + 'icpc': detect_intel, + 'intel': detect_intel, + 'kcc': 'kcc', + 'kylix': 'bck', + 'mipspro': 'mp', + 'mingw': 'mgw', + 'msvc': 'vc', + 'qcc': 'qcc', + 'sun': 'sw', + 'sunc++': 'sw', + 'tru64cxx': 'tru', + 'vacpp': 'xlc' +} + + +def options(opt): + opt = opt.add_option_group('Boost Options') + opt.add_option('--boost-includes', type='string', + default='', dest='boost_includes', + help='''path to the directory where the boost includes are, + e.g., /path/to/boost_1_55_0/stage/include''') + opt.add_option('--boost-libs', type='string', + default='', dest='boost_libs', + help='''path to the directory where the boost libs are, + e.g., path/to/boost_1_55_0/stage/lib''') + opt.add_option('--boost-mt', action='store_true', + default=False, dest='boost_mt', + help='select multi-threaded libraries') + opt.add_option('--boost-abi', type='string', default='', dest='boost_abi', + help='''select libraries with tags (gd for debug, static is automatically added), + see doc Boost, Getting Started, chapter 6.1''') + opt.add_option('--boost-linkage_autodetect', action="store_true", dest='boost_linkage_autodetect', + help="auto-detect boost linkage options (don't get used to it / might break other stuff)") + opt.add_option('--boost-toolset', type='string', + default='', dest='boost_toolset', + help='force a toolset e.g. msvc, vc90, \ + gcc, mingw, mgw45 (default: auto)') + py_version = '%d%d' % (sys.version_info[0], sys.version_info[1]) + opt.add_option('--boost-python', type='string', + default=py_version, dest='boost_python', + help='select the lib python with this version \ + (default: %s)' % py_version) + + +@conf +def __boost_get_version_file(self, d): + if not d: + return None + dnode = self.root.find_dir(d) + if dnode: + return dnode.find_node(BOOST_VERSION_FILE) + return None + +@conf +def boost_get_version(self, d): + """silently retrieve the boost version number""" + node = self.__boost_get_version_file(d) + if node: + try: + txt = node.read() + except EnvironmentError: + Logs.error("Could not read the file %r", node.abspath()) + else: + re_but1 = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.+)"', re.M) + m1 = re_but1.search(txt) + re_but2 = re.compile('^#define\\s+BOOST_VERSION\\s+(\\d+)', re.M) + m2 = re_but2.search(txt) + if m1 and m2: + return (m1.group(1), m2.group(1)) + return self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[d], execute=True, define_ret=True).split(":") + +@conf +def boost_get_includes(self, *k, **kw): + includes = k and k[0] or kw.get('includes') + if includes and self.__boost_get_version_file(includes): + return includes + for d in self.environ.get('INCLUDE', '').split(';') + BOOST_INCLUDES: + if self.__boost_get_version_file(d): + return d + if includes: + self.end_msg('headers not found in %s' % includes) + self.fatal('The configuration failed') + else: + self.end_msg('headers not found, please provide a --boost-includes argument (see help)') + self.fatal('The configuration failed') + + +@conf +def boost_get_toolset(self, cc): + toolset = cc + if not cc: + build_platform = Utils.unversioned_sys_platform() + if build_platform in BOOST_TOOLSETS: + cc = build_platform + else: + cc = self.env.CXX_NAME + if cc in BOOST_TOOLSETS: + toolset = BOOST_TOOLSETS[cc] + return isinstance(toolset, str) and toolset or toolset(self.env) + + +@conf +def __boost_get_libs_path(self, *k, **kw): + ''' return the lib path and all the files in it ''' + if 'files' in kw: + return self.root.find_dir('.'), Utils.to_list(kw['files']) + libs = k and k[0] or kw.get('libs') + if libs: + path = self.root.find_dir(libs) + files = path.ant_glob('*boost_*') + if not libs or not files: + for d in self.environ.get('LIB', '').split(';') + BOOST_LIBS: + if not d: + continue + path = self.root.find_dir(d) + if path: + files = path.ant_glob('*boost_*') + if files: + break + path = self.root.find_dir(d + '64') + if path: + files = path.ant_glob('*boost_*') + if files: + break + if not path: + if libs: + self.end_msg('libs not found in %s' % libs) + self.fatal('The configuration failed') + else: + self.end_msg('libs not found, please provide a --boost-libs argument (see help)') + self.fatal('The configuration failed') + + self.to_log('Found the boost path in %r with the libraries:' % path) + for x in files: + self.to_log(' %r' % x) + return path, files + +@conf +def boost_get_libs(self, *k, **kw): + ''' + return the lib path and the required libs + according to the parameters + ''' + path, files = self.__boost_get_libs_path(**kw) + files = sorted(files, key=lambda f: (len(f.name), f.name), reverse=True) + toolset = self.boost_get_toolset(kw.get('toolset', '')) + toolset_pat = '(-%s[0-9]{0,3})' % toolset + version = '-%s' % self.env.BOOST_VERSION + + def find_lib(re_lib, files): + for file in files: + if re_lib.search(file.name): + self.to_log('Found boost lib %s' % file) + return file + return None + + def format_lib_name(name): + if name.startswith('lib') and self.env.CC_NAME != 'msvc': + name = name[3:] + return name[:name.rfind('.')] + + def match_libs(lib_names, is_static): + libs = [] + lib_names = Utils.to_list(lib_names) + if not lib_names: + return libs + t = [] + if kw.get('mt', False): + t.append('-mt') + if kw.get('abi'): + t.append('%s%s' % (is_static and '-s' or '-', kw['abi'])) + elif is_static: + t.append('-s') + tags_pat = t and ''.join(t) or '' + ext = is_static and self.env.cxxstlib_PATTERN or self.env.cxxshlib_PATTERN + ext = ext.partition('%s')[2] # remove '%s' or 'lib%s' from PATTERN + + for lib in lib_names: + if lib == 'python': + # for instance, with python='27', + # accepts '-py27', '-py2', '27', '-2.7' and '2' + # but will reject '-py3', '-py26', '26' and '3' + tags = '({0})?((-py{2})|(-py{1}(?=[^0-9]))|({2})|(-{1}.{3})|({1}(?=[^0-9]))|(?=[^0-9])(?!-py))'.format(tags_pat, kw['python'][0], kw['python'], kw['python'][1]) + else: + tags = tags_pat + # Trying libraries, from most strict match to least one + for pattern in ['boost_%s%s%s%s%s$' % (lib, toolset_pat, tags, version, ext), + 'boost_%s%s%s%s$' % (lib, tags, version, ext), + # Give up trying to find the right version + 'boost_%s%s%s%s$' % (lib, toolset_pat, tags, ext), + 'boost_%s%s%s$' % (lib, tags, ext), + 'boost_%s%s$' % (lib, ext), + 'boost_%s' % lib]: + self.to_log('Trying pattern %s' % pattern) + file = find_lib(re.compile(pattern), files) + if file: + libs.append(format_lib_name(file.name)) + break + else: + self.end_msg('lib %s not found in %s' % (lib, path.abspath())) + self.fatal('The configuration failed') + return libs + + return path.abspath(), match_libs(kw.get('lib'), False), match_libs(kw.get('stlib'), True) + +@conf +def _check_pthread_flag(self, *k, **kw): + ''' + Computes which flags should be added to CXXFLAGS and LINKFLAGS to compile in multi-threading mode + + Yes, we *need* to put the -pthread thing in CPPFLAGS because with GCC3, + boost/thread.hpp will trigger a #error if -pthread isn't used: + boost/config/requires_threads.hpp:47:5: #error "Compiler threading support + is not turned on. Please set the correct command line options for + threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)" + + Based on _BOOST_PTHREAD_FLAG(): https://github.com/tsuna/boost.m4/blob/master/build-aux/boost.m4 + ''' + + var = kw.get('uselib_store', 'BOOST') + + self.start_msg('Checking the flags needed to use pthreads') + + # The ordering *is* (sometimes) important. Some notes on the + # individual items follow: + # (none): in case threads are in libc; should be tried before -Kthread and + # other compiler flags to prevent continual compiler warnings + # -lpthreads: AIX (must check this before -lpthread) + # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # -llthread: LinuxThreads port on FreeBSD (also preferred to -pthread) + # -pthread: GNU Linux/GCC (kernel threads), BSD/GCC (userland threads) + # -pthreads: Solaris/GCC + # -mthreads: MinGW32/GCC, Lynx/GCC + # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it + # doesn't hurt to check since this sometimes defines pthreads too; + # also defines -D_REENTRANT) + # ... -mt is also the pthreads flag for HP/aCC + # -lpthread: GNU Linux, etc. + # --thread-safe: KAI C++ + if Utils.unversioned_sys_platform() == "sunos": + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + boost_pthread_flags = ["-pthreads", "-lpthread", "-mt", "-pthread"] + else: + boost_pthread_flags = ["", "-lpthreads", "-Kthread", "-kthread", "-llthread", "-pthread", + "-pthreads", "-mthreads", "-lpthread", "--thread-safe", "-mt"] + + for boost_pthread_flag in boost_pthread_flags: + try: + self.env.stash() + self.env.append_value('CXXFLAGS_%s' % var, boost_pthread_flag) + self.env.append_value('LINKFLAGS_%s' % var, boost_pthread_flag) + self.check_cxx(code=PTHREAD_CODE, msg=None, use=var, execute=False) + + self.end_msg(boost_pthread_flag) + return + except self.errors.ConfigurationError: + self.env.revert() + self.end_msg('None') + +@conf +def check_boost(self, *k, **kw): + """ + Initialize boost libraries to be used. + + Keywords: you can pass the same parameters as with the command line (without "--boost-"). + Note that the command line has the priority, and should preferably be used. + """ + if not self.env['CXX']: + self.fatal('load a c++ compiler first, conf.load("compiler_cxx")') + + params = { + 'lib': k and k[0] or kw.get('lib'), + 'stlib': kw.get('stlib') + } + for key, value in self.options.__dict__.items(): + if not key.startswith('boost_'): + continue + key = key[len('boost_'):] + params[key] = value and value or kw.get(key, '') + + var = kw.get('uselib_store', 'BOOST') + + self.find_program('dpkg-architecture', var='DPKG_ARCHITECTURE', mandatory=False) + if self.env.DPKG_ARCHITECTURE: + deb_host_multiarch = self.cmd_and_log([self.env.DPKG_ARCHITECTURE[0], '-qDEB_HOST_MULTIARCH']) + BOOST_LIBS.insert(0, '/usr/lib/%s' % deb_host_multiarch.strip()) + + self.start_msg('Checking boost includes') + self.env['INCLUDES_%s' % var] = inc = self.boost_get_includes(**params) + versions = self.boost_get_version(inc) + self.env.BOOST_VERSION = versions[0] + self.env.BOOST_VERSION_NUMBER = int(versions[1]) + self.end_msg("%d.%d.%d" % (int(versions[1]) / 100000, + int(versions[1]) / 100 % 1000, + int(versions[1]) % 100)) + if Logs.verbose: + Logs.pprint('CYAN', ' path : %s' % self.env['INCLUDES_%s' % var]) + + if not params['lib'] and not params['stlib']: + return + if 'static' in kw or 'static' in params: + Logs.warn('boost: static parameter is deprecated, use stlib instead.') + self.start_msg('Checking boost libs') + path, libs, stlibs = self.boost_get_libs(**params) + self.env['LIBPATH_%s' % var] = [path] + self.env['STLIBPATH_%s' % var] = [path] + self.env['LIB_%s' % var] = libs + self.env['STLIB_%s' % var] = stlibs + self.end_msg('ok') + if Logs.verbose: + Logs.pprint('CYAN', ' path : %s' % path) + Logs.pprint('CYAN', ' shared libs : %s' % libs) + Logs.pprint('CYAN', ' static libs : %s' % stlibs) + + def has_shlib(lib): + return params['lib'] and lib in params['lib'] + def has_stlib(lib): + return params['stlib'] and lib in params['stlib'] + def has_lib(lib): + return has_shlib(lib) or has_stlib(lib) + if has_lib('thread'): + # not inside try_link to make check visible in the output + self._check_pthread_flag(k, kw) + + def try_link(): + if has_lib('system'): + self.check_cxx(fragment=BOOST_ERROR_CODE, use=var, execute=False) + if has_lib('thread'): + self.check_cxx(fragment=BOOST_THREAD_CODE, use=var, execute=False) + if has_lib('log'): + if not has_lib('thread'): + self.env['DEFINES_%s' % var] += ['BOOST_LOG_NO_THREADS'] + if has_shlib('log'): + self.env['DEFINES_%s' % var] += ['BOOST_LOG_DYN_LINK'] + self.check_cxx(fragment=BOOST_LOG_CODE, use=var, execute=False) + + if params.get('linkage_autodetect', False): + self.start_msg("Attempting to detect boost linkage flags") + toolset = self.boost_get_toolset(kw.get('toolset', '')) + if toolset in ('vc',): + # disable auto-linking feature, causing error LNK1181 + # because the code wants to be linked against + self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB'] + + # if no dlls are present, we guess the .lib files are not stubs + has_dlls = False + for x in Utils.listdir(path): + if x.endswith(self.env.cxxshlib_PATTERN % ''): + has_dlls = True + break + if not has_dlls: + self.env['STLIBPATH_%s' % var] = [path] + self.env['STLIB_%s' % var] = libs + del self.env['LIB_%s' % var] + del self.env['LIBPATH_%s' % var] + + # we attempt to play with some known-to-work CXXFLAGS combinations + for cxxflags in (['/MD', '/EHsc'], []): + self.env.stash() + self.env["CXXFLAGS_%s" % var] += cxxflags + try: + try_link() + except Errors.ConfigurationError as e: + self.env.revert() + exc = e + else: + self.end_msg("ok: winning cxxflags combination: %s" % (self.env["CXXFLAGS_%s" % var])) + exc = None + self.env.commit() + break + + if exc is not None: + self.end_msg("Could not auto-detect boost linking flags combination, you may report it to boost.py author", ex=exc) + self.fatal('The configuration failed') + else: + self.end_msg("Boost linkage flags auto-detection not implemented (needed ?) for this toolchain") + self.fatal('The configuration failed') + else: + self.start_msg('Checking for boost linkage') + try: + try_link() + except Errors.ConfigurationError as e: + self.end_msg("Could not link against boost libraries using supplied options") + self.fatal('The configuration failed') + self.end_msg('ok') + + +@feature('cxx') +@after_method('apply_link') +def install_boost(self): + if install_boost.done or not Utils.is_win32 or not self.bld.cmd.startswith('install'): + return + install_boost.done = True + inst_to = getattr(self, 'install_path', '${BINDIR}') + for lib in self.env.LIB_BOOST: + try: + file = self.bld.find_file(self.env.cxxshlib_PATTERN % lib, self.env.LIBPATH_BOOST) + self.add_install_files(install_to=inst_to, install_from=self.bld.root.find_node(file)) + except: + continue +install_boost.done = False + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/build_file_tracker.py b/ldb-2.0.8/third_party/waf/waflib/extras/build_file_tracker.py new file mode 100644 index 0000000..c4f26fd --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/build_file_tracker.py @@ -0,0 +1,28 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2015 + +""" +Force files to depend on the timestamps of those located in the build directory. You may +want to use this to force partial rebuilds, see playground/track_output_files/ for a working example. + +Note that there is a variety of ways to implement this, one may want use timestamps on source files too for example, +or one may want to hash the files in the source directory only under certain conditions (md5_tstamp tool) +or to hash the file in the build directory with its timestamp +""" + +import os +from waflib import Node, Utils + +def get_bld_sig(self): + if not self.is_bld() or self.ctx.bldnode is self.ctx.srcnode: + return Utils.h_file(self.abspath()) + + try: + # add the creation time to the signature + return self.sig + str(os.stat(self.abspath()).st_mtime) + except AttributeError: + return None + +Node.Node.get_bld_sig = get_bld_sig + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/build_logs.py b/ldb-2.0.8/third_party/waf/waflib/extras/build_logs.py new file mode 100644 index 0000000..cdf8ed0 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/build_logs.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2013 (ita) + +""" +A system for recording all outputs to a log file. Just add the following to your wscript file:: + + def init(ctx): + ctx.load('build_logs') +""" + +import atexit, sys, time, os, shutil, threading +from waflib import ansiterm, Logs, Context + +# adding the logs under the build/ directory will clash with the clean/ command +try: + up = os.path.dirname(Context.g_module.__file__) +except AttributeError: + up = '.' +LOGFILE = os.path.join(up, 'logs', time.strftime('%Y_%m_%d_%H_%M.log')) + +wlock = threading.Lock() +class log_to_file(object): + def __init__(self, stream, fileobj, filename): + self.stream = stream + self.encoding = self.stream.encoding + self.fileobj = fileobj + self.filename = filename + self.is_valid = True + def replace_colors(self, data): + for x in Logs.colors_lst.values(): + if isinstance(x, str): + data = data.replace(x, '') + return data + def write(self, data): + try: + wlock.acquire() + self.stream.write(data) + self.stream.flush() + if self.is_valid: + self.fileobj.write(self.replace_colors(data)) + finally: + wlock.release() + def fileno(self): + return self.stream.fileno() + def flush(self): + self.stream.flush() + if self.is_valid: + self.fileobj.flush() + def isatty(self): + return self.stream.isatty() + +def init(ctx): + global LOGFILE + filename = os.path.abspath(LOGFILE) + try: + os.makedirs(os.path.dirname(os.path.abspath(filename))) + except OSError: + pass + + if hasattr(os, 'O_NOINHERIT'): + fd = os.open(LOGFILE, os.O_CREAT | os.O_TRUNC | os.O_WRONLY | os.O_NOINHERIT) + fileobj = os.fdopen(fd, 'w') + else: + fileobj = open(LOGFILE, 'w') + old_stderr = sys.stderr + + # sys.stdout has already been replaced, so __stdout__ will be faster + #sys.stdout = log_to_file(sys.stdout, fileobj, filename) + #sys.stderr = log_to_file(sys.stderr, fileobj, filename) + def wrap(stream): + if stream.isatty(): + return ansiterm.AnsiTerm(stream) + return stream + sys.stdout = log_to_file(wrap(sys.__stdout__), fileobj, filename) + sys.stderr = log_to_file(wrap(sys.__stderr__), fileobj, filename) + + # now mess with the logging module... + for x in Logs.log.handlers: + try: + stream = x.stream + except AttributeError: + pass + else: + if id(stream) == id(old_stderr): + x.stream = sys.stderr + +def exit_cleanup(): + try: + fileobj = sys.stdout.fileobj + except AttributeError: + pass + else: + sys.stdout.is_valid = False + sys.stderr.is_valid = False + fileobj.close() + filename = sys.stdout.filename + + Logs.info('Output logged to %r', filename) + + # then copy the log file to "latest.log" if possible + up = os.path.dirname(os.path.abspath(filename)) + try: + shutil.copy(filename, os.path.join(up, 'latest.log')) + except OSError: + # this may fail on windows due to processes spawned + pass + +atexit.register(exit_cleanup) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/buildcopy.py b/ldb-2.0.8/third_party/waf/waflib/extras/buildcopy.py new file mode 100644 index 0000000..eaff7e6 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/buildcopy.py @@ -0,0 +1,85 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Calle Rosenquist, 2017 (xbreak) +""" +Create task that copies source files to the associated build node. +This is useful to e.g. construct a complete Python package so it can be unit tested +without installation. + +Source files to be copied can be specified either in `buildcopy_source` attribute, or +`source` attribute. If both are specified `buildcopy_source` has priority. + +Examples:: + + def build(bld): + bld(name = 'bar', + features = 'py buildcopy', + source = bld.path.ant_glob('src/bar/*.py')) + + bld(name = 'py baz', + features = 'buildcopy', + buildcopy_source = bld.path.ant_glob('src/bar/*.py') + ['src/bar/resource.txt']) + +""" +import os, shutil +from waflib import Errors, Task, TaskGen, Utils, Node, Logs + +@TaskGen.before_method('process_source') +@TaskGen.feature('buildcopy') +def make_buildcopy(self): + """ + Creates the buildcopy task. + """ + def to_src_nodes(lst): + """Find file nodes only in src, TaskGen.to_nodes will not work for this since it gives + preference to nodes in build. + """ + if isinstance(lst, Node.Node): + if not lst.is_src(): + raise Errors.WafError('buildcopy: node %s is not in src'%lst) + if not os.path.isfile(lst.abspath()): + raise Errors.WafError('buildcopy: Cannot copy directory %s (unsupported action)'%lst) + return lst + + if isinstance(lst, str): + lst = [x for x in Utils.split_path(lst) if x and x != '.'] + + node = self.bld.path.get_src().search_node(lst) + if node: + if not os.path.isfile(node.abspath()): + raise Errors.WafError('buildcopy: Cannot copy directory %s (unsupported action)'%node) + return node + + node = self.bld.path.get_src().find_node(lst) + if node: + if not os.path.isfile(node.abspath()): + raise Errors.WafError('buildcopy: Cannot copy directory %s (unsupported action)'%node) + return node + raise Errors.WafError('buildcopy: File not found in src: %s'%os.path.join(*lst)) + + nodes = [ to_src_nodes(n) for n in getattr(self, 'buildcopy_source', getattr(self, 'source', [])) ] + if not nodes: + Logs.warn('buildcopy: No source files provided to buildcopy in %s (set `buildcopy_source` or `source`)', + self) + return + node_pairs = [(n, n.get_bld()) for n in nodes] + self.create_task('buildcopy', [n[0] for n in node_pairs], [n[1] for n in node_pairs], node_pairs=node_pairs) + +class buildcopy(Task.Task): + """ + Copy for each pair `n` in `node_pairs`: n[0] -> n[1]. + + Attribute `node_pairs` should contain a list of tuples describing source and target: + + node_pairs = [(in, out), ...] + + """ + color = 'PINK' + + def keyword(self): + return 'Copying' + + def run(self): + for f,t in self.node_pairs: + t.parent.mkdir() + shutil.copy2(f.abspath(), t.abspath()) diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/c_bgxlc.py b/ldb-2.0.8/third_party/waf/waflib/extras/c_bgxlc.py new file mode 100644 index 0000000..6e3eaf7 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/c_bgxlc.py @@ -0,0 +1,32 @@ +#! /usr/bin/env python +# encoding: utf-8 +# harald at klimachs.de + +""" +IBM XL Compiler for Blue Gene +""" + +from waflib.Tools import ccroot,ar +from waflib.Configure import conf + +from waflib.Tools import xlc # method xlc_common_flags +from waflib.Tools.compiler_c import c_compiler +c_compiler['linux'].append('c_bgxlc') + +@conf +def find_bgxlc(conf): + cc = conf.find_program(['bgxlc_r','bgxlc'], var='CC') + conf.get_xlc_version(cc) + conf.env.CC = cc + conf.env.CC_NAME = 'bgxlc' + +def configure(conf): + conf.find_bgxlc() + conf.find_ar() + conf.xlc_common_flags() + conf.env.LINKFLAGS_cshlib = ['-G','-Wl,-bexpfull'] + conf.env.LINKFLAGS_cprogram = [] + conf.cc_load_tools() + conf.cc_add_flags() + conf.link_add_flags() + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/c_dumbpreproc.py b/ldb-2.0.8/third_party/waf/waflib/extras/c_dumbpreproc.py new file mode 100644 index 0000000..ce9e1a4 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/c_dumbpreproc.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2006-2010 (ita) + +""" +Dumb C/C++ preprocessor for finding dependencies + +It will look at all include files it can find after removing the comments, so the following +will always add the dependency on both "a.h" and "b.h":: + + #include "a.h" + #ifdef B + #include "b.h" + #endif + int main() { + return 0; + } + +To use:: + + def configure(conf): + conf.load('compiler_c') + conf.load('c_dumbpreproc') +""" + +import re +from waflib.Tools import c_preproc + +re_inc = re.compile( + '^[ \t]*(#|%:)[ \t]*(include)[ \t]*[<"](.*)[>"]\r*$', + re.IGNORECASE | re.MULTILINE) + +def lines_includes(node): + code = node.read() + if c_preproc.use_trigraphs: + for (a, b) in c_preproc.trig_def: + code = code.split(a).join(b) + code = c_preproc.re_nl.sub('', code) + code = c_preproc.re_cpp.sub(c_preproc.repl, code) + return [(m.group(2), m.group(3)) for m in re.finditer(re_inc, code)] + +parser = c_preproc.c_parser +class dumb_parser(parser): + def addlines(self, node): + if node in self.nodes[:-1]: + return + self.currentnode_stack.append(node.parent) + + # Avoid reading the same files again + try: + lines = self.parse_cache[node] + except KeyError: + lines = self.parse_cache[node] = lines_includes(node) + + self.lines = lines + [(c_preproc.POPFILE, '')] + self.lines + + def start(self, node, env): + try: + self.parse_cache = node.ctx.parse_cache + except AttributeError: + self.parse_cache = node.ctx.parse_cache = {} + + self.addlines(node) + while self.lines: + (x, y) = self.lines.pop(0) + if x == c_preproc.POPFILE: + self.currentnode_stack.pop() + continue + self.tryfind(y) + +c_preproc.c_parser = dumb_parser + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/c_emscripten.py b/ldb-2.0.8/third_party/waf/waflib/extras/c_emscripten.py new file mode 100644 index 0000000..e1ac494 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/c_emscripten.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# -*- coding: utf-8 vi:ts=4:noexpandtab + +import subprocess, shlex, sys + +from waflib.Tools import ccroot, gcc, gxx +from waflib.Configure import conf +from waflib.TaskGen import after_method, feature + +from waflib.Tools.compiler_c import c_compiler +from waflib.Tools.compiler_cxx import cxx_compiler + +for supported_os in ('linux', 'darwin', 'gnu', 'aix'): + c_compiler[supported_os].append('c_emscripten') + cxx_compiler[supported_os].append('c_emscripten') + + +@conf +def get_emscripten_version(conf, cc): + """ + Emscripten doesn't support processing '-' like clang/gcc + """ + + dummy = conf.cachedir.parent.make_node("waf-emscripten.c") + dummy.write("") + cmd = cc + ['-dM', '-E', '-x', 'c', dummy.abspath()] + env = conf.env.env or None + try: + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) + out = p.communicate()[0] + except Exception as e: + conf.fatal('Could not determine emscripten version %r: %s' % (cmd, e)) + + if not isinstance(out, str): + out = out.decode(sys.stdout.encoding or 'latin-1') + + k = {} + out = out.splitlines() + for line in out: + lst = shlex.split(line) + if len(lst)>2: + key = lst[1] + val = lst[2] + k[key] = val + + if not ('__clang__' in k and 'EMSCRIPTEN' in k): + conf.fatal('Could not determine the emscripten compiler version.') + + conf.env.DEST_OS = 'generic' + conf.env.DEST_BINFMT = 'elf' + conf.env.DEST_CPU = 'asm-js' + conf.env.CC_VERSION = (k['__clang_major__'], k['__clang_minor__'], k['__clang_patchlevel__']) + return k + +@conf +def find_emscripten(conf): + cc = conf.find_program(['emcc'], var='CC') + conf.get_emscripten_version(cc) + conf.env.CC = cc + conf.env.CC_NAME = 'emscripten' + cxx = conf.find_program(['em++'], var='CXX') + conf.env.CXX = cxx + conf.env.CXX_NAME = 'emscripten' + conf.find_program(['emar'], var='AR') + +def configure(conf): + conf.find_emscripten() + conf.find_ar() + conf.gcc_common_flags() + conf.gxx_common_flags() + conf.cc_load_tools() + conf.cc_add_flags() + conf.cxx_load_tools() + conf.cxx_add_flags() + conf.link_add_flags() + conf.env.ARFLAGS = ['rcs'] + conf.env.cshlib_PATTERN = '%s.js' + conf.env.cxxshlib_PATTERN = '%s.js' + conf.env.cstlib_PATTERN = '%s.a' + conf.env.cxxstlib_PATTERN = '%s.a' + conf.env.cprogram_PATTERN = '%s.html' + conf.env.cxxprogram_PATTERN = '%s.html' + conf.env.CXX_TGT_F = ['-c', '-o', ''] + conf.env.CC_TGT_F = ['-c', '-o', ''] + conf.env.CXXLNK_TGT_F = ['-o', ''] + conf.env.CCLNK_TGT_F = ['-o', ''] + conf.env.append_value('LINKFLAGS',['-Wl,--enable-auto-import']) diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/c_nec.py b/ldb-2.0.8/third_party/waf/waflib/extras/c_nec.py new file mode 100644 index 0000000..96bfae4 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/c_nec.py @@ -0,0 +1,74 @@ +#! /usr/bin/env python +# encoding: utf-8 +# harald at klimachs.de + +""" +NEC SX Compiler for SX vector systems +""" + +import re +from waflib import Utils +from waflib.Tools import ccroot,ar +from waflib.Configure import conf + +from waflib.Tools import xlc # method xlc_common_flags +from waflib.Tools.compiler_c import c_compiler +c_compiler['linux'].append('c_nec') + +@conf +def find_sxc(conf): + cc = conf.find_program(['sxcc'], var='CC') + conf.get_sxc_version(cc) + conf.env.CC = cc + conf.env.CC_NAME = 'sxcc' + +@conf +def get_sxc_version(conf, fc): + version_re = re.compile(r"C\+\+/SX\s*Version\s*(?P\d*)\.(?P\d*)", re.I).search + cmd = fc + ['-V'] + p = Utils.subprocess.Popen(cmd, stdin=False, stdout=Utils.subprocess.PIPE, stderr=Utils.subprocess.PIPE, env=None) + out, err = p.communicate() + + if out: + match = version_re(out) + else: + match = version_re(err) + if not match: + conf.fatal('Could not determine the NEC C compiler version.') + k = match.groupdict() + conf.env['C_VERSION'] = (k['major'], k['minor']) + +@conf +def sxc_common_flags(conf): + v=conf.env + v['CC_SRC_F']=[] + v['CC_TGT_F']=['-c','-o'] + if not v['LINK_CC']: + v['LINK_CC']=v['CC'] + v['CCLNK_SRC_F']=[] + v['CCLNK_TGT_F']=['-o'] + v['CPPPATH_ST']='-I%s' + v['DEFINES_ST']='-D%s' + v['LIB_ST']='-l%s' + v['LIBPATH_ST']='-L%s' + v['STLIB_ST']='-l%s' + v['STLIBPATH_ST']='-L%s' + v['RPATH_ST']='' + v['SONAME_ST']=[] + v['SHLIB_MARKER']=[] + v['STLIB_MARKER']=[] + v['LINKFLAGS_cprogram']=[''] + v['cprogram_PATTERN']='%s' + v['CFLAGS_cshlib']=['-fPIC'] + v['LINKFLAGS_cshlib']=[''] + v['cshlib_PATTERN']='lib%s.so' + v['LINKFLAGS_cstlib']=[] + v['cstlib_PATTERN']='lib%s.a' + +def configure(conf): + conf.find_sxc() + conf.find_program('sxar',VAR='AR') + conf.sxc_common_flags() + conf.cc_load_tools() + conf.cc_add_flags() + conf.link_add_flags() diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/cabal.py b/ldb-2.0.8/third_party/waf/waflib/extras/cabal.py new file mode 100644 index 0000000..e10a0d1 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/cabal.py @@ -0,0 +1,152 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Anton Feldmann, 2012 +# "Base for cabal" + +from waflib import Task, Utils +from waflib.TaskGen import extension +from waflib.Utils import threading +from shutil import rmtree + +lock = threading.Lock() +registering = False + +def configure(self): + self.find_program('cabal', var='CABAL') + self.find_program('ghc-pkg', var='GHCPKG') + pkgconfd = self.bldnode.abspath() + '/package.conf.d' + self.env.PREFIX = self.bldnode.abspath() + '/dist' + self.env.PKGCONFD = pkgconfd + if self.root.find_node(pkgconfd + '/package.cache'): + self.msg('Using existing package database', pkgconfd, color='CYAN') + else: + pkgdir = self.root.find_dir(pkgconfd) + if pkgdir: + self.msg('Deleting corrupt package database', pkgdir.abspath(), color ='RED') + rmtree(pkgdir.abspath()) + pkgdir = None + + self.cmd_and_log(self.env.GHCPKG + ['init', pkgconfd]) + self.msg('Created package database', pkgconfd, color = 'YELLOW' if pkgdir else 'GREEN') + +@extension('.cabal') +def process_cabal(self, node): + out_dir_node = self.bld.root.find_dir(self.bld.out_dir) + package_node = node.change_ext('.package') + package_node = out_dir_node.find_or_declare(package_node.name) + build_node = node.parent.get_bld() + build_path = build_node.abspath() + config_node = build_node.find_or_declare('setup-config') + inplace_node = build_node.find_or_declare('package.conf.inplace') + + config_task = self.create_task('cabal_configure', node) + config_task.cwd = node.parent.abspath() + config_task.depends_on = getattr(self, 'depends_on', '') + config_task.build_path = build_path + config_task.set_outputs(config_node) + + build_task = self.create_task('cabal_build', config_node) + build_task.cwd = node.parent.abspath() + build_task.build_path = build_path + build_task.set_outputs(inplace_node) + + copy_task = self.create_task('cabal_copy', inplace_node) + copy_task.cwd = node.parent.abspath() + copy_task.depends_on = getattr(self, 'depends_on', '') + copy_task.build_path = build_path + + last_task = copy_task + task_list = [config_task, build_task, copy_task] + + if (getattr(self, 'register', False)): + register_task = self.create_task('cabal_register', inplace_node) + register_task.cwd = node.parent.abspath() + register_task.set_run_after(copy_task) + register_task.build_path = build_path + + pkgreg_task = self.create_task('ghcpkg_register', inplace_node) + pkgreg_task.cwd = node.parent.abspath() + pkgreg_task.set_run_after(register_task) + pkgreg_task.build_path = build_path + + last_task = pkgreg_task + task_list += [register_task, pkgreg_task] + + touch_task = self.create_task('cabal_touch', inplace_node) + touch_task.set_run_after(last_task) + touch_task.set_outputs(package_node) + touch_task.build_path = build_path + + task_list += [touch_task] + + return task_list + +def get_all_src_deps(node): + hs_deps = node.ant_glob('**/*.hs') + hsc_deps = node.ant_glob('**/*.hsc') + lhs_deps = node.ant_glob('**/*.lhs') + c_deps = node.ant_glob('**/*.c') + cpp_deps = node.ant_glob('**/*.cpp') + proto_deps = node.ant_glob('**/*.proto') + return sum([hs_deps, hsc_deps, lhs_deps, c_deps, cpp_deps, proto_deps], []) + +class Cabal(Task.Task): + def scan(self): + return (get_all_src_deps(self.generator.path), ()) + +class cabal_configure(Cabal): + run_str = '${CABAL} configure -v0 --prefix=${PREFIX} --global --user --package-db=${PKGCONFD} --builddir=${tsk.build_path}' + shell = True + + def scan(self): + out_node = self.generator.bld.root.find_dir(self.generator.bld.out_dir) + deps = [out_node.find_or_declare(dep).change_ext('.package') for dep in Utils.to_list(self.depends_on)] + return (deps, ()) + +class cabal_build(Cabal): + run_str = '${CABAL} build -v1 --builddir=${tsk.build_path}/' + shell = True + +class cabal_copy(Cabal): + run_str = '${CABAL} copy -v0 --builddir=${tsk.build_path}' + shell = True + +class cabal_register(Cabal): + run_str = '${CABAL} register -v0 --gen-pkg-config=${tsk.build_path}/pkg.config --builddir=${tsk.build_path}' + shell = True + +class ghcpkg_register(Cabal): + run_str = '${GHCPKG} update -v0 --global --user --package-conf=${PKGCONFD} ${tsk.build_path}/pkg.config' + shell = True + + def runnable_status(self): + global lock, registering + + val = False + lock.acquire() + val = registering + lock.release() + + if val: + return Task.ASK_LATER + + ret = Task.Task.runnable_status(self) + if ret == Task.RUN_ME: + lock.acquire() + registering = True + lock.release() + + return ret + + def post_run(self): + global lock, registering + + lock.acquire() + registering = False + lock.release() + + return Task.Task.post_run(self) + +class cabal_touch(Cabal): + run_str = 'touch ${TGT}' + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/cfg_altoptions.py b/ldb-2.0.8/third_party/waf/waflib/extras/cfg_altoptions.py new file mode 100644 index 0000000..47b1189 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/cfg_altoptions.py @@ -0,0 +1,110 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Tool to extend c_config.check_cfg() + +__author__ = __maintainer__ = "Jérôme Carretero " +__copyright__ = "Jérôme Carretero, 2014" + +""" + +This tool allows to work around the absence of ``*-config`` programs +on systems, by keeping the same clean configuration syntax but inferring +values or permitting their modification via the options interface. + +Note that pkg-config can also support setting ``PKG_CONFIG_PATH``, +so you can put custom files in a folder containing new .pc files. +This tool could also be implemented by taking advantage of this fact. + +Usage:: + + def options(opt): + opt.load('c_config_alt') + opt.add_package_option('package') + + def configure(cfg): + conf.load('c_config_alt') + conf.check_cfg(...) + +Known issues: + +- Behavior with different build contexts... + +""" + +import os +import functools +from waflib import Configure, Options, Errors + +def name_to_dest(x): + return x.lower().replace('-', '_') + + +def options(opt): + def x(opt, param): + dest = name_to_dest(param) + gr = opt.get_option_group("configure options") + gr.add_option('--%s-root' % dest, + help="path containing include and lib subfolders for %s" \ + % param, + ) + + opt.add_package_option = functools.partial(x, opt) + + +check_cfg_old = getattr(Configure.ConfigurationContext, 'check_cfg') + +@Configure.conf +def check_cfg(conf, *k, **kw): + if k: + lst = k[0].split() + kw['package'] = lst[0] + kw['args'] = ' '.join(lst[1:]) + + if not 'package' in kw: + return check_cfg_old(conf, **kw) + + package = kw['package'] + + package_lo = name_to_dest(package) + package_hi = package.upper().replace('-', '_') # TODO FIXME + package_hi = kw.get('uselib_store', package_hi) + + def check_folder(path, name): + try: + assert os.path.isdir(path) + except AssertionError: + raise Errors.ConfigurationError( + "%s_%s (%s) is not a folder!" \ + % (package_lo, name, path)) + return path + + root = getattr(Options.options, '%s_root' % package_lo, None) + + if root is None: + return check_cfg_old(conf, **kw) + else: + def add_manual_var(k, v): + conf.start_msg('Adding for %s a manual var' % (package)) + conf.env["%s_%s" % (k, package_hi)] = v + conf.end_msg("%s = %s" % (k, v)) + + + check_folder(root, 'root') + + pkg_inc = check_folder(os.path.join(root, "include"), 'inc') + add_manual_var('INCLUDES', [pkg_inc]) + pkg_lib = check_folder(os.path.join(root, "lib"), 'libpath') + add_manual_var('LIBPATH', [pkg_lib]) + add_manual_var('LIB', [package]) + + for x in kw.get('manual_deps', []): + for k, v in sorted(conf.env.get_merged_dict().items()): + if k.endswith('_%s' % x): + k = k.replace('_%s' % x, '') + conf.start_msg('Adding for %s a manual dep' \ + %(package)) + conf.env["%s_%s" % (k, package_hi)] += v + conf.end_msg('%s += %s' % (k, v)) + + return True + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/clang_compilation_database.py b/ldb-2.0.8/third_party/waf/waflib/extras/clang_compilation_database.py new file mode 100644 index 0000000..4d9b5e2 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/clang_compilation_database.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Christoph Koke, 2013 + +""" +Writes the c and cpp compile commands into build/compile_commands.json +see http://clang.llvm.org/docs/JSONCompilationDatabase.html + +Usage: + + def configure(conf): + conf.load('compiler_cxx') + ... + conf.load('clang_compilation_database') +""" + +import sys, os, json, shlex, pipes +from waflib import Logs, TaskGen, Task + +Task.Task.keep_last_cmd = True + +@TaskGen.feature('c', 'cxx') +@TaskGen.after_method('process_use') +def collect_compilation_db_tasks(self): + "Add a compilation database entry for compiled tasks" + try: + clang_db = self.bld.clang_compilation_database_tasks + except AttributeError: + clang_db = self.bld.clang_compilation_database_tasks = [] + self.bld.add_post_fun(write_compilation_database) + + tup = tuple(y for y in [Task.classes.get(x) for x in ('c', 'cxx')] if y) + for task in getattr(self, 'compiled_tasks', []): + if isinstance(task, tup): + clang_db.append(task) + +def write_compilation_database(ctx): + "Write the clang compilation database as JSON" + database_file = ctx.bldnode.make_node('compile_commands.json') + Logs.info('Build commands will be stored in %s', database_file.path_from(ctx.path)) + try: + root = json.load(database_file) + except IOError: + root = [] + clang_db = dict((x['file'], x) for x in root) + for task in getattr(ctx, 'clang_compilation_database_tasks', []): + try: + cmd = task.last_cmd + except AttributeError: + continue + directory = getattr(task, 'cwd', ctx.variant_dir) + f_node = task.inputs[0] + filename = os.path.relpath(f_node.abspath(), directory) + entry = { + "directory": directory, + "arguments": cmd, + "file": filename, + } + clang_db[filename] = entry + root = list(clang_db.values()) + database_file.write(json.dumps(root, indent=2)) + +# Override the runnable_status function to do a dummy/dry run when the file doesn't need to be compiled. +# This will make sure compile_commands.json is always fully up to date. +# Previously you could end up with a partial compile_commands.json if the build failed. +for x in ('c', 'cxx'): + if x not in Task.classes: + continue + + t = Task.classes[x] + + def runnable_status(self): + def exec_command(cmd, **kw): + pass + + run_status = self.old_runnable_status() + if run_status == Task.SKIP_ME: + setattr(self, 'old_exec_command', getattr(self, 'exec_command', None)) + setattr(self, 'exec_command', exec_command) + self.run() + setattr(self, 'exec_command', getattr(self, 'old_exec_command', None)) + return run_status + + setattr(t, 'old_runnable_status', getattr(t, 'runnable_status', None)) + setattr(t, 'runnable_status', runnable_status) diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/clang_cross.py b/ldb-2.0.8/third_party/waf/waflib/extras/clang_cross.py new file mode 100644 index 0000000..1b51e28 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/clang_cross.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Krzysztof Kosiński 2014 +# DragoonX6 2018 + +""" +Detect the Clang C compiler +This version is an attempt at supporting the -target and -sysroot flag of Clang. +""" + +from waflib.Tools import ccroot, ar, gcc +from waflib.Configure import conf +import waflib.Context +import waflib.extras.clang_cross_common + +def options(opt): + """ + Target triplet for clang:: + $ waf configure --clang-target-triple=x86_64-pc-linux-gnu + """ + cc_compiler_opts = opt.add_option_group('Configuration options') + cc_compiler_opts.add_option('--clang-target-triple', default=None, + help='Target triple for clang', + dest='clang_target_triple') + cc_compiler_opts.add_option('--clang-sysroot', default=None, + help='Sysroot for clang', + dest='clang_sysroot') + +@conf +def find_clang(conf): + """ + Finds the program clang and executes it to ensure it really is clang + """ + + import os + + cc = conf.find_program('clang', var='CC') + + if conf.options.clang_target_triple != None: + conf.env.append_value('CC', ['-target', conf.options.clang_target_triple]) + + if conf.options.clang_sysroot != None: + sysroot = str() + + if os.path.isabs(conf.options.clang_sysroot): + sysroot = conf.options.clang_sysroot + else: + sysroot = os.path.normpath(os.path.join(os.getcwd(), conf.options.clang_sysroot)) + + conf.env.append_value('CC', ['--sysroot', sysroot]) + + conf.get_cc_version(cc, clang=True) + conf.env.CC_NAME = 'clang' + +@conf +def clang_modifier_x86_64_w64_mingw32(conf): + conf.gcc_modifier_win32() + +@conf +def clang_modifier_i386_w64_mingw32(conf): + conf.gcc_modifier_win32() + +@conf +def clang_modifier_x86_64_windows_msvc(conf): + conf.clang_modifier_msvc() + + # Allow the user to override any flags if they so desire. + clang_modifier_user_func = getattr(conf, 'clang_modifier_x86_64_windows_msvc_user', None) + if clang_modifier_user_func: + clang_modifier_user_func() + +@conf +def clang_modifier_i386_windows_msvc(conf): + conf.clang_modifier_msvc() + + # Allow the user to override any flags if they so desire. + clang_modifier_user_func = getattr(conf, 'clang_modifier_i386_windows_msvc_user', None) + if clang_modifier_user_func: + clang_modifier_user_func() + +def configure(conf): + conf.find_clang() + conf.find_program(['llvm-ar', 'ar'], var='AR') + conf.find_ar() + conf.gcc_common_flags() + # Allow the user to provide flags for the target platform. + conf.gcc_modifier_platform() + # And allow more fine grained control based on the compiler's triplet. + conf.clang_modifier_target_triple() + conf.cc_load_tools() + conf.cc_add_flags() + conf.link_add_flags() diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/clang_cross_common.py b/ldb-2.0.8/third_party/waf/waflib/extras/clang_cross_common.py new file mode 100644 index 0000000..b76a070 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/clang_cross_common.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python +# encoding: utf-8 +# DragoonX6 2018 + +""" +Common routines for cross_clang.py and cross_clangxx.py +""" + +from waflib.Configure import conf +import waflib.Context + +def normalize_target_triple(target_triple): + target_triple = target_triple[:-1] + normalized_triple = target_triple.replace('--', '-unknown-') + + if normalized_triple.startswith('-'): + normalized_triple = 'unknown' + normalized_triple + + if normalized_triple.endswith('-'): + normalized_triple += 'unknown' + + # Normalize MinGW builds to *arch*-w64-mingw32 + if normalized_triple.endswith('windows-gnu'): + normalized_triple = normalized_triple[:normalized_triple.index('-')] + '-w64-mingw32' + + # Strip the vendor when doing msvc builds, since it's unused anyway. + if normalized_triple.endswith('windows-msvc'): + normalized_triple = normalized_triple[:normalized_triple.index('-')] + '-windows-msvc' + + return normalized_triple.replace('-', '_') + +@conf +def clang_modifier_msvc(conf): + import os + + """ + Really basic setup to use clang in msvc mode. + We actually don't really want to do a lot, even though clang is msvc compatible + in this mode, that doesn't mean we're actually using msvc. + It's probably the best to leave it to the user, we can assume msvc mode if the user + uses the clang-cl frontend, but this module only concerns itself with the gcc-like frontend. + """ + v = conf.env + v.cprogram_PATTERN = '%s.exe' + + v.cshlib_PATTERN = '%s.dll' + v.implib_PATTERN = '%s.lib' + v.IMPLIB_ST = '-Wl,-IMPLIB:%s' + v.SHLIB_MARKER = [] + + v.CFLAGS_cshlib = [] + v.LINKFLAGS_cshlib = ['-Wl,-DLL'] + v.cstlib_PATTERN = '%s.lib' + v.STLIB_MARKER = [] + + del(v.AR) + conf.find_program(['llvm-lib', 'lib'], var='AR') + v.ARFLAGS = ['-nologo'] + v.AR_TGT_F = ['-out:'] + + # Default to the linker supplied with llvm instead of link.exe or ld + v.LINK_CC = v.CC + ['-fuse-ld=lld', '-nostdlib'] + v.CCLNK_TGT_F = ['-o'] + v.def_PATTERN = '-Wl,-def:%s' + + v.LINKFLAGS = [] + + v.LIB_ST = '-l%s' + v.LIBPATH_ST = '-Wl,-LIBPATH:%s' + v.STLIB_ST = '-l%s' + v.STLIBPATH_ST = '-Wl,-LIBPATH:%s' + + CFLAGS_CRT_COMMON = [ + '-Xclang', '--dependent-lib=oldnames', + '-Xclang', '-fno-rtti-data', + '-D_MT' + ] + + v.CFLAGS_CRT_MULTITHREADED = CFLAGS_CRT_COMMON + [ + '-Xclang', '-flto-visibility-public-std', + '-Xclang', '--dependent-lib=libcmt', + ] + v.CXXFLAGS_CRT_MULTITHREADED = v.CFLAGS_CRT_MULTITHREADED + + v.CFLAGS_CRT_MULTITHREADED_DBG = CFLAGS_CRT_COMMON + [ + '-D_DEBUG', + '-Xclang', '-flto-visibility-public-std', + '-Xclang', '--dependent-lib=libcmtd', + ] + v.CXXFLAGS_CRT_MULTITHREADED_DBG = v.CFLAGS_CRT_MULTITHREADED_DBG + + v.CFLAGS_CRT_MULTITHREADED_DLL = CFLAGS_CRT_COMMON + [ + '-D_DLL', + '-Xclang', '--dependent-lib=msvcrt' + ] + v.CXXFLAGS_CRT_MULTITHREADED_DLL = v.CFLAGS_CRT_MULTITHREADED_DLL + + v.CFLAGS_CRT_MULTITHREADED_DLL_DBG = CFLAGS_CRT_COMMON + [ + '-D_DLL', + '-D_DEBUG', + '-Xclang', '--dependent-lib=msvcrtd', + ] + v.CXXFLAGS_CRT_MULTITHREADED_DLL_DBG = v.CFLAGS_CRT_MULTITHREADED_DLL_DBG + +@conf +def clang_modifier_target_triple(conf, cpp=False): + compiler = conf.env.CXX if cpp else conf.env.CC + output = conf.cmd_and_log(compiler + ['-dumpmachine'], output=waflib.Context.STDOUT) + + modifier = ('clangxx' if cpp else 'clang') + '_modifier_' + clang_modifier_func = getattr(conf, modifier + normalize_target_triple(output), None) + if clang_modifier_func: + clang_modifier_func() diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/clangxx_cross.py b/ldb-2.0.8/third_party/waf/waflib/extras/clangxx_cross.py new file mode 100644 index 0000000..0ad38ad --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/clangxx_cross.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy 2009-2018 (ita) +# DragoonX6 2018 + +""" +Detect the Clang++ C++ compiler +This version is an attempt at supporting the -target and -sysroot flag of Clang++. +""" + +from waflib.Tools import ccroot, ar, gxx +from waflib.Configure import conf +import waflib.extras.clang_cross_common + +def options(opt): + """ + Target triplet for clang++:: + $ waf configure --clangxx-target-triple=x86_64-pc-linux-gnu + """ + cxx_compiler_opts = opt.add_option_group('Configuration options') + cxx_compiler_opts.add_option('--clangxx-target-triple', default=None, + help='Target triple for clang++', + dest='clangxx_target_triple') + cxx_compiler_opts.add_option('--clangxx-sysroot', default=None, + help='Sysroot for clang++', + dest='clangxx_sysroot') + +@conf +def find_clangxx(conf): + """ + Finds the program clang++, and executes it to ensure it really is clang++ + """ + + import os + + cxx = conf.find_program('clang++', var='CXX') + + if conf.options.clangxx_target_triple != None: + conf.env.append_value('CXX', ['-target', conf.options.clangxx_target_triple]) + + if conf.options.clangxx_sysroot != None: + sysroot = str() + + if os.path.isabs(conf.options.clangxx_sysroot): + sysroot = conf.options.clangxx_sysroot + else: + sysroot = os.path.normpath(os.path.join(os.getcwd(), conf.options.clangxx_sysroot)) + + conf.env.append_value('CXX', ['--sysroot', sysroot]) + + conf.get_cc_version(cxx, clang=True) + conf.env.CXX_NAME = 'clang' + +@conf +def clangxx_modifier_x86_64_w64_mingw32(conf): + conf.gcc_modifier_win32() + +@conf +def clangxx_modifier_i386_w64_mingw32(conf): + conf.gcc_modifier_win32() + +@conf +def clangxx_modifier_msvc(conf): + v = conf.env + v.cxxprogram_PATTERN = v.cprogram_PATTERN + v.cxxshlib_PATTERN = v.cshlib_PATTERN + + v.CXXFLAGS_cxxshlib = [] + v.LINKFLAGS_cxxshlib = v.LINKFLAGS_cshlib + v.cxxstlib_PATTERN = v.cstlib_PATTERN + + v.LINK_CXX = v.CXX + ['-fuse-ld=lld', '-nostdlib'] + v.CXXLNK_TGT_F = v.CCLNK_TGT_F + +@conf +def clangxx_modifier_x86_64_windows_msvc(conf): + conf.clang_modifier_msvc() + conf.clangxx_modifier_msvc() + + # Allow the user to override any flags if they so desire. + clang_modifier_user_func = getattr(conf, 'clangxx_modifier_x86_64_windows_msvc_user', None) + if clang_modifier_user_func: + clang_modifier_user_func() + +@conf +def clangxx_modifier_i386_windows_msvc(conf): + conf.clang_modifier_msvc() + conf.clangxx_modifier_msvc() + + # Allow the user to override any flags if they so desire. + clang_modifier_user_func = getattr(conf, 'clangxx_modifier_i386_windows_msvc_user', None) + if clang_modifier_user_func: + clang_modifier_user_func() + +def configure(conf): + conf.find_clangxx() + conf.find_program(['llvm-ar', 'ar'], var='AR') + conf.find_ar() + conf.gxx_common_flags() + # Allow the user to provide flags for the target platform. + conf.gxx_modifier_platform() + # And allow more fine grained control based on the compiler's triplet. + conf.clang_modifier_target_triple(cpp=True) + conf.cxx_load_tools() + conf.cxx_add_flags() + conf.link_add_flags() diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/codelite.py b/ldb-2.0.8/third_party/waf/waflib/extras/codelite.py new file mode 100644 index 0000000..523302c --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/codelite.py @@ -0,0 +1,875 @@ +#! /usr/bin/env python +# encoding: utf-8 +# CodeLite Project +# Christian Klein (chrikle@berlios.de) +# Created: Jan 2012 +# As templete for this file I used the msvs.py +# I hope this template will work proper + +""" +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +""" + +""" + + +To add this tool to your project: +def options(conf): + opt.load('codelite') + +It can be a good idea to add the sync_exec tool too. + +To generate solution files: +$ waf configure codelite + +To customize the outputs, provide subclasses in your wscript files: + +from waflib.extras import codelite +class vsnode_target(codelite.vsnode_target): + def get_build_command(self, props): + # likely to be required + return "waf.bat build" + def collect_source(self): + # likely to be required + ... +class codelite_bar(codelite.codelite_generator): + def init(self): + codelite.codelite_generator.init(self) + self.vsnode_target = vsnode_target + +The codelite class re-uses the same build() function for reading the targets (task generators), +you may therefore specify codelite settings on the context object: + +def build(bld): + bld.codelite_solution_name = 'foo.workspace' + bld.waf_command = 'waf.bat' + bld.projects_dir = bld.srcnode.make_node('') + bld.projects_dir.mkdir() + + +ASSUMPTIONS: +* a project can be either a directory or a target, project files are written only for targets that have source files +* each project is a vcxproj file, therefore the project uuid needs only to be a hash of the absolute path +""" + +import os, re, sys +import uuid # requires python 2.5 +from waflib.Build import BuildContext +from waflib import Utils, TaskGen, Logs, Task, Context, Node, Options + +HEADERS_GLOB = '**/(*.h|*.hpp|*.H|*.inl)' + +PROJECT_TEMPLATE = r''' + + + + + + + + + + ${for x in project.source} + ${if (project.get_key(x)=="sourcefile")} + + ${endif} + ${endfor} + + + ${for x in project.source} + ${if (project.get_key(x)=="headerfile")} + + ${endif} + ${endfor} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $b = project.build_properties[0]} + ${xml:project.get_rebuild_command(project.build_properties[0])} + ${xml:project.get_clean_command(project.build_properties[0])} + ${xml:project.get_build_command(project.build_properties[0])} + ${xml:project.get_install_command(project.build_properties[0])} + ${xml:project.get_build_and_install_command(project.build_properties[0])} + ${xml:project.get_build_all_command(project.build_properties[0])} + ${xml:project.get_rebuild_all_command(project.build_properties[0])} + ${xml:project.get_clean_all_command(project.build_properties[0])} + ${xml:project.get_build_and_install_all_command(project.build_properties[0])} + + + + None + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +''' + + + + +SOLUTION_TEMPLATE = ''' + +${for p in project.all_projects} + +${endfor} + + +${for p in project.all_projects} + +${endfor} + + +''' + + + +COMPILE_TEMPLATE = '''def f(project): + lst = [] + def xml_escape(value): + return value.replace("&", "&").replace('"', """).replace("'", "'").replace("<", "<").replace(">", ">") + + %s + + #f = open('cmd.txt', 'w') + #f.write(str(lst)) + #f.close() + return ''.join(lst) +''' +reg_act = re.compile(r"(?P\\)|(?P\$\$)|(?P\$\{(?P[^}]*?)\})", re.M) +def compile_template(line): + """ + Compile a template expression into a python function (like jsps, but way shorter) + """ + extr = [] + def repl(match): + g = match.group + if g('dollar'): + return "$" + elif g('backslash'): + return "\\" + elif g('subst'): + extr.append(g('code')) + return "<<|@|>>" + return None + + line2 = reg_act.sub(repl, line) + params = line2.split('<<|@|>>') + assert(extr) + + + indent = 0 + buf = [] + app = buf.append + + def app(txt): + buf.append(indent * '\t' + txt) + + for x in range(len(extr)): + if params[x]: + app("lst.append(%r)" % params[x]) + + f = extr[x] + if f.startswith(('if', 'for')): + app(f + ':') + indent += 1 + elif f.startswith('py:'): + app(f[3:]) + elif f.startswith(('endif', 'endfor')): + indent -= 1 + elif f.startswith(('else', 'elif')): + indent -= 1 + app(f + ':') + indent += 1 + elif f.startswith('xml:'): + app('lst.append(xml_escape(%s))' % f[4:]) + else: + #app('lst.append((%s) or "cannot find %s")' % (f, f)) + app('lst.append(%s)' % f) + + if extr: + if params[-1]: + app("lst.append(%r)" % params[-1]) + + fun = COMPILE_TEMPLATE % "\n\t".join(buf) + #print(fun) + return Task.funex(fun) + + +re_blank = re.compile('(\n|\r|\\s)*\n', re.M) +def rm_blank_lines(txt): + txt = re_blank.sub('\r\n', txt) + return txt + +BOM = '\xef\xbb\xbf' +try: + BOM = bytes(BOM, 'latin-1') # python 3 +except (TypeError, NameError): + pass + +def stealth_write(self, data, flags='wb'): + try: + unicode + except NameError: + data = data.encode('utf-8') # python 3 + else: + data = data.decode(sys.getfilesystemencoding(), 'replace') + data = data.encode('utf-8') + + if self.name.endswith('.project'): + data = BOM + data + + try: + txt = self.read(flags='rb') + if txt != data: + raise ValueError('must write') + except (IOError, ValueError): + self.write(data, flags=flags) + else: + Logs.debug('codelite: skipping %r', self) +Node.Node.stealth_write = stealth_write + +re_quote = re.compile("[^a-zA-Z0-9-]") +def quote(s): + return re_quote.sub("_", s) + +def xml_escape(value): + return value.replace("&", "&").replace('"', """).replace("'", "'").replace("<", "<").replace(">", ">") + +def make_uuid(v, prefix = None): + """ + simple utility function + """ + if isinstance(v, dict): + keys = list(v.keys()) + keys.sort() + tmp = str([(k, v[k]) for k in keys]) + else: + tmp = str(v) + d = Utils.md5(tmp.encode()).hexdigest().upper() + if prefix: + d = '%s%s' % (prefix, d[8:]) + gid = uuid.UUID(d, version = 4) + return str(gid).upper() + +def diff(node, fromnode): + # difference between two nodes, but with "(..)" instead of ".." + c1 = node + c2 = fromnode + + c1h = c1.height() + c2h = c2.height() + + lst = [] + up = 0 + + while c1h > c2h: + lst.append(c1.name) + c1 = c1.parent + c1h -= 1 + + while c2h > c1h: + up += 1 + c2 = c2.parent + c2h -= 1 + + while id(c1) != id(c2): + lst.append(c1.name) + up += 1 + + c1 = c1.parent + c2 = c2.parent + + for i in range(up): + lst.append('(..)') + lst.reverse() + return tuple(lst) + +class build_property(object): + pass + +class vsnode(object): + """ + Abstract class representing visual studio elements + We assume that all visual studio nodes have a uuid and a parent + """ + def __init__(self, ctx): + self.ctx = ctx # codelite context + self.name = '' # string, mandatory + self.vspath = '' # path in visual studio (name for dirs, absolute path for projects) + self.uuid = '' # string, mandatory + self.parent = None # parent node for visual studio nesting + + def get_waf(self): + """ + Override in subclasses... + """ + return '%s/%s' % (self.ctx.srcnode.abspath(), getattr(self.ctx, 'waf_command', 'waf')) + + def ptype(self): + """ + Return a special uuid for projects written in the solution file + """ + pass + + def write(self): + """ + Write the project file, by default, do nothing + """ + pass + + def make_uuid(self, val): + """ + Alias for creating uuid values easily (the templates cannot access global variables) + """ + return make_uuid(val) + +class vsnode_vsdir(vsnode): + """ + Nodes representing visual studio folders (which do not match the filesystem tree!) + """ + VS_GUID_SOLUTIONFOLDER = "2150E333-8FDC-42A3-9474-1A3956D46DE8" + def __init__(self, ctx, uuid, name, vspath=''): + vsnode.__init__(self, ctx) + self.title = self.name = name + self.uuid = uuid + self.vspath = vspath or name + + def ptype(self): + return self.VS_GUID_SOLUTIONFOLDER + +class vsnode_project(vsnode): + """ + Abstract class representing visual studio project elements + A project is assumed to be writable, and has a node representing the file to write to + """ + VS_GUID_VCPROJ = "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942" + def ptype(self): + return self.VS_GUID_VCPROJ + + def __init__(self, ctx, node): + vsnode.__init__(self, ctx) + self.path = node + self.uuid = make_uuid(node.abspath()) + self.name = node.name + self.title = self.path.abspath() + self.source = [] # list of node objects + self.build_properties = [] # list of properties (nmake commands, output dir, etc) + + def dirs(self): + """ + Get the list of parent folders of the source files (header files included) + for writing the filters + """ + lst = [] + def add(x): + if x.height() > self.tg.path.height() and x not in lst: + lst.append(x) + add(x.parent) + for x in self.source: + add(x.parent) + return lst + + def write(self): + Logs.debug('codelite: creating %r', self.path) + #print "self.name:",self.name + + # first write the project file + template1 = compile_template(PROJECT_TEMPLATE) + proj_str = template1(self) + proj_str = rm_blank_lines(proj_str) + self.path.stealth_write(proj_str) + + # then write the filter + #template2 = compile_template(FILTER_TEMPLATE) + #filter_str = template2(self) + #filter_str = rm_blank_lines(filter_str) + #tmp = self.path.parent.make_node(self.path.name + '.filters') + #tmp.stealth_write(filter_str) + + def get_key(self, node): + """ + required for writing the source files + """ + name = node.name + if name.endswith(('.cpp', '.c')): + return 'sourcefile' + return 'headerfile' + + def collect_properties(self): + """ + Returns a list of triplet (configuration, platform, output_directory) + """ + ret = [] + for c in self.ctx.configurations: + for p in self.ctx.platforms: + x = build_property() + x.outdir = '' + + x.configuration = c + x.platform = p + + x.preprocessor_definitions = '' + x.includes_search_path = '' + + # can specify "deploy_dir" too + ret.append(x) + self.build_properties = ret + + def get_build_params(self, props): + opt = '' + return (self.get_waf(), opt) + + def get_build_command(self, props): + return "%s build %s" % self.get_build_params(props) + + def get_clean_command(self, props): + return "%s clean %s" % self.get_build_params(props) + + def get_rebuild_command(self, props): + return "%s clean build %s" % self.get_build_params(props) + + def get_install_command(self, props): + return "%s install %s" % self.get_build_params(props) + def get_build_and_install_command(self, props): + return "%s build install %s" % self.get_build_params(props) + + def get_build_and_install_all_command(self, props): + return "%s build install" % self.get_build_params(props)[0] + + def get_clean_all_command(self, props): + return "%s clean" % self.get_build_params(props)[0] + + def get_build_all_command(self, props): + return "%s build" % self.get_build_params(props)[0] + + def get_rebuild_all_command(self, props): + return "%s clean build" % self.get_build_params(props)[0] + + def get_filter_name(self, node): + lst = diff(node, self.tg.path) + return '\\'.join(lst) or '.' + +class vsnode_alias(vsnode_project): + def __init__(self, ctx, node, name): + vsnode_project.__init__(self, ctx, node) + self.name = name + self.output_file = '' + +class vsnode_build_all(vsnode_alias): + """ + Fake target used to emulate the behaviour of "make all" (starting one process by target is slow) + This is the only alias enabled by default + """ + def __init__(self, ctx, node, name='build_all_projects'): + vsnode_alias.__init__(self, ctx, node, name) + self.is_active = True + +class vsnode_install_all(vsnode_alias): + """ + Fake target used to emulate the behaviour of "make install" + """ + def __init__(self, ctx, node, name='install_all_projects'): + vsnode_alias.__init__(self, ctx, node, name) + + def get_build_command(self, props): + return "%s build install %s" % self.get_build_params(props) + + def get_clean_command(self, props): + return "%s clean %s" % self.get_build_params(props) + + def get_rebuild_command(self, props): + return "%s clean build install %s" % self.get_build_params(props) + +class vsnode_project_view(vsnode_alias): + """ + Fake target used to emulate a file system view + """ + def __init__(self, ctx, node, name='project_view'): + vsnode_alias.__init__(self, ctx, node, name) + self.tg = self.ctx() # fake one, cannot remove + self.exclude_files = Node.exclude_regs + ''' +waf-2* +waf3-2*/** +.waf-2* +.waf3-2*/** +**/*.sdf +**/*.suo +**/*.ncb +**/%s + ''' % Options.lockfile + + def collect_source(self): + # this is likely to be slow + self.source = self.ctx.srcnode.ant_glob('**', excl=self.exclude_files) + + def get_build_command(self, props): + params = self.get_build_params(props) + (self.ctx.cmd,) + return "%s %s %s" % params + + def get_clean_command(self, props): + return "" + + def get_rebuild_command(self, props): + return self.get_build_command(props) + +class vsnode_target(vsnode_project): + """ + CodeLite project representing a targets (programs, libraries, etc) and bound + to a task generator + """ + def __init__(self, ctx, tg): + """ + A project is more or less equivalent to a file/folder + """ + base = getattr(ctx, 'projects_dir', None) or tg.path + node = base.make_node(quote(tg.name) + ctx.project_extension) # the project file as a Node + vsnode_project.__init__(self, ctx, node) + self.name = quote(tg.name) + self.tg = tg # task generator + + def get_build_params(self, props): + """ + Override the default to add the target name + """ + opt = '' + if getattr(self, 'tg', None): + opt += " --targets=%s" % self.tg.name + return (self.get_waf(), opt) + + def collect_source(self): + tg = self.tg + source_files = tg.to_nodes(getattr(tg, 'source', [])) + include_dirs = Utils.to_list(getattr(tg, 'codelite_includes', [])) + include_files = [] + for x in include_dirs: + if isinstance(x, str): + x = tg.path.find_node(x) + if x: + lst = [y for y in x.ant_glob(HEADERS_GLOB, flat=False)] + include_files.extend(lst) + + # remove duplicates + self.source.extend(list(set(source_files + include_files))) + self.source.sort(key=lambda x: x.abspath()) + + def collect_properties(self): + """ + CodeLite projects are associated with platforms and configurations (for building especially) + """ + super(vsnode_target, self).collect_properties() + for x in self.build_properties: + x.outdir = self.path.parent.abspath() + x.preprocessor_definitions = '' + x.includes_search_path = '' + + try: + tsk = self.tg.link_task + except AttributeError: + pass + else: + x.output_file = tsk.outputs[0].abspath() + x.preprocessor_definitions = ';'.join(tsk.env.DEFINES) + x.includes_search_path = ';'.join(self.tg.env.INCPATHS) + +class codelite_generator(BuildContext): + '''generates a CodeLite workspace''' + cmd = 'codelite' + fun = 'build' + + def init(self): + """ + Some data that needs to be present + """ + if not getattr(self, 'configurations', None): + self.configurations = ['Release'] # LocalRelease, RemoteDebug, etc + if not getattr(self, 'platforms', None): + self.platforms = ['Win32'] + if not getattr(self, 'all_projects', None): + self.all_projects = [] + if not getattr(self, 'project_extension', None): + self.project_extension = '.project' + if not getattr(self, 'projects_dir', None): + self.projects_dir = self.srcnode.make_node('') + self.projects_dir.mkdir() + + # bind the classes to the object, so that subclass can provide custom generators + if not getattr(self, 'vsnode_vsdir', None): + self.vsnode_vsdir = vsnode_vsdir + if not getattr(self, 'vsnode_target', None): + self.vsnode_target = vsnode_target + if not getattr(self, 'vsnode_build_all', None): + self.vsnode_build_all = vsnode_build_all + if not getattr(self, 'vsnode_install_all', None): + self.vsnode_install_all = vsnode_install_all + if not getattr(self, 'vsnode_project_view', None): + self.vsnode_project_view = vsnode_project_view + + self.numver = '11.00' + self.vsver = '2010' + + def execute(self): + """ + Entry point + """ + self.restore() + if not self.all_envs: + self.load_envs() + self.recurse([self.run_dir]) + + # user initialization + self.init() + + # two phases for creating the solution + self.collect_projects() # add project objects into "self.all_projects" + self.write_files() # write the corresponding project and solution files + + def collect_projects(self): + """ + Fill the list self.all_projects with project objects + Fill the list of build targets + """ + self.collect_targets() + #self.add_aliases() + #self.collect_dirs() + default_project = getattr(self, 'default_project', None) + def sortfun(x): + if x.name == default_project: + return '' + return getattr(x, 'path', None) and x.path.abspath() or x.name + self.all_projects.sort(key=sortfun) + + def write_files(self): + """ + Write the project and solution files from the data collected + so far. It is unlikely that you will want to change this + """ + for p in self.all_projects: + p.write() + + # and finally write the solution file + node = self.get_solution_node() + node.parent.mkdir() + Logs.warn('Creating %r', node) + #a = dir(self.root) + #for b in a: + # print b + #print self.group_names + #print "Hallo2: ",self.root.listdir() + #print getattr(self, 'codelite_solution_name', None) + template1 = compile_template(SOLUTION_TEMPLATE) + sln_str = template1(self) + sln_str = rm_blank_lines(sln_str) + node.stealth_write(sln_str) + + def get_solution_node(self): + """ + The solution filename is required when writing the .vcproj files + return self.solution_node and if it does not exist, make one + """ + try: + return self.solution_node + except: + pass + + codelite_solution_name = getattr(self, 'codelite_solution_name', None) + if not codelite_solution_name: + codelite_solution_name = getattr(Context.g_module, Context.APPNAME, 'project') + '.workspace' + setattr(self, 'codelite_solution_name', codelite_solution_name) + if os.path.isabs(codelite_solution_name): + self.solution_node = self.root.make_node(codelite_solution_name) + else: + self.solution_node = self.srcnode.make_node(codelite_solution_name) + return self.solution_node + + def project_configurations(self): + """ + Helper that returns all the pairs (config,platform) + """ + ret = [] + for c in self.configurations: + for p in self.platforms: + ret.append((c, p)) + return ret + + def collect_targets(self): + """ + Process the list of task generators + """ + for g in self.groups: + for tg in g: + if not isinstance(tg, TaskGen.task_gen): + continue + + if not hasattr(tg, 'codelite_includes'): + tg.codelite_includes = tg.to_list(getattr(tg, 'includes', [])) + tg.to_list(getattr(tg, 'export_includes', [])) + tg.post() + if not getattr(tg, 'link_task', None): + continue + + p = self.vsnode_target(self, tg) + p.collect_source() # delegate this processing + p.collect_properties() + self.all_projects.append(p) + + def add_aliases(self): + """ + Add a specific target that emulates the "make all" necessary for Visual studio when pressing F7 + We also add an alias for "make install" (disabled by default) + """ + base = getattr(self, 'projects_dir', None) or self.tg.path + + node_project = base.make_node('build_all_projects' + self.project_extension) # Node + p_build = self.vsnode_build_all(self, node_project) + p_build.collect_properties() + self.all_projects.append(p_build) + + node_project = base.make_node('install_all_projects' + self.project_extension) # Node + p_install = self.vsnode_install_all(self, node_project) + p_install.collect_properties() + self.all_projects.append(p_install) + + node_project = base.make_node('project_view' + self.project_extension) # Node + p_view = self.vsnode_project_view(self, node_project) + p_view.collect_source() + p_view.collect_properties() + self.all_projects.append(p_view) + + n = self.vsnode_vsdir(self, make_uuid(self.srcnode.abspath() + 'build_aliases'), "build_aliases") + p_build.parent = p_install.parent = p_view.parent = n + self.all_projects.append(n) + + def collect_dirs(self): + """ + Create the folder structure in the CodeLite project view + """ + seen = {} + def make_parents(proj): + # look at a project, try to make a parent + if getattr(proj, 'parent', None): + # aliases already have parents + return + x = proj.iter_path + if x in seen: + proj.parent = seen[x] + return + + # There is not vsnode_vsdir for x. + # So create a project representing the folder "x" + n = proj.parent = seen[x] = self.vsnode_vsdir(self, make_uuid(x.abspath()), x.name) + n.iter_path = x.parent + self.all_projects.append(n) + + # recurse up to the project directory + if x.height() > self.srcnode.height() + 1: + make_parents(n) + + for p in self.all_projects[:]: # iterate over a copy of all projects + if not getattr(p, 'tg', None): + # but only projects that have a task generator + continue + + # make a folder for each task generator + p.iter_path = p.tg.path + make_parents(p) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/color_gcc.py b/ldb-2.0.8/third_party/waf/waflib/extras/color_gcc.py new file mode 100644 index 0000000..b68c5eb --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/color_gcc.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python +# encoding: utf-8 + +# Replaces the default formatter by one which understands GCC output and colorizes it. + +__author__ = __maintainer__ = "Jérôme Carretero " +__copyright__ = "Jérôme Carretero, 2012" + +import sys +from waflib import Logs + +class ColorGCCFormatter(Logs.formatter): + def __init__(self, colors): + self.colors = colors + Logs.formatter.__init__(self) + def format(self, rec): + frame = sys._getframe() + while frame: + func = frame.f_code.co_name + if func == 'exec_command': + cmd = frame.f_locals.get('cmd') + if isinstance(cmd, list) and ('gcc' in cmd[0] or 'g++' in cmd[0]): + lines = [] + for line in rec.msg.splitlines(): + if 'warning: ' in line: + lines.append(self.colors.YELLOW + line) + elif 'error: ' in line: + lines.append(self.colors.RED + line) + elif 'note: ' in line: + lines.append(self.colors.CYAN + line) + else: + lines.append(line) + rec.msg = "\n".join(lines) + frame = frame.f_back + return Logs.formatter.format(self, rec) + +def options(opt): + Logs.log.handlers[0].setFormatter(ColorGCCFormatter(Logs.colors)) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/color_msvc.py b/ldb-2.0.8/third_party/waf/waflib/extras/color_msvc.py new file mode 100644 index 0000000..60bacb7 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/color_msvc.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# encoding: utf-8 + +# Replaces the default formatter by one which understands MSVC output and colorizes it. +# Modified from color_gcc.py + +__author__ = __maintainer__ = "Alibek Omarov " +__copyright__ = "Alibek Omarov, 2019" + +import sys +from waflib import Logs + +class ColorMSVCFormatter(Logs.formatter): + def __init__(self, colors): + self.colors = colors + Logs.formatter.__init__(self) + + def parseMessage(self, line, color): + # Split messaage from 'disk:filepath: type: message' + arr = line.split(':', 3) + if len(arr) < 4: + return line + + colored = self.colors.BOLD + arr[0] + ':' + arr[1] + ':' + self.colors.NORMAL + colored += color + arr[2] + ':' + self.colors.NORMAL + colored += arr[3] + return colored + + def format(self, rec): + frame = sys._getframe() + while frame: + func = frame.f_code.co_name + if func == 'exec_command': + cmd = frame.f_locals.get('cmd') + if isinstance(cmd, list): + # Fix file case, it may be CL.EXE or cl.exe + argv0 = cmd[0].lower() + if 'cl.exe' in argv0: + lines = [] + # This will not work with "localized" versions + # of MSVC + for line in rec.msg.splitlines(): + if ': warning ' in line: + lines.append(self.parseMessage(line, self.colors.YELLOW)) + elif ': error ' in line: + lines.append(self.parseMessage(line, self.colors.RED)) + elif ': fatal error ' in line: + lines.append(self.parseMessage(line, self.colors.RED + self.colors.BOLD)) + elif ': note: ' in line: + lines.append(self.parseMessage(line, self.colors.CYAN)) + else: + lines.append(line) + rec.msg = "\n".join(lines) + frame = frame.f_back + return Logs.formatter.format(self, rec) + +def options(opt): + Logs.log.handlers[0].setFormatter(ColorMSVCFormatter(Logs.colors)) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/color_rvct.py b/ldb-2.0.8/third_party/waf/waflib/extras/color_rvct.py new file mode 100644 index 0000000..f89ccbd --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/color_rvct.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python +# encoding: utf-8 + +# Replaces the default formatter by one which understands RVCT output and colorizes it. + +__author__ = __maintainer__ = "Jérôme Carretero " +__copyright__ = "Jérôme Carretero, 2012" + +import sys +import atexit +from waflib import Logs + +errors = [] + +def show_errors(): + for i, e in enumerate(errors): + if i > 5: + break + print("Error: %s" % e) + +atexit.register(show_errors) + +class RcvtFormatter(Logs.formatter): + def __init__(self, colors): + Logs.formatter.__init__(self) + self.colors = colors + def format(self, rec): + frame = sys._getframe() + while frame: + func = frame.f_code.co_name + if func == 'exec_command': + cmd = frame.f_locals['cmd'] + if isinstance(cmd, list) and ('armcc' in cmd[0] or 'armld' in cmd[0]): + lines = [] + for line in rec.msg.splitlines(): + if 'Warning: ' in line: + lines.append(self.colors.YELLOW + line) + elif 'Error: ' in line: + lines.append(self.colors.RED + line) + errors.append(line) + elif 'note: ' in line: + lines.append(self.colors.CYAN + line) + else: + lines.append(line) + rec.msg = "\n".join(lines) + frame = frame.f_back + return Logs.formatter.format(self, rec) + +def options(opt): + Logs.log.handlers[0].setFormatter(RcvtFormatter(Logs.colors)) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/compat15.py b/ldb-2.0.8/third_party/waf/waflib/extras/compat15.py new file mode 100644 index 0000000..0e74df8 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/compat15.py @@ -0,0 +1,406 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2010 (ita) + +""" +This file is provided to enable compatibility with waf 1.5 +It was enabled by default in waf 1.6, but it is not used in waf 1.7 +""" + +import sys +from waflib import ConfigSet, Logs, Options, Scripting, Task, Build, Configure, Node, Runner, TaskGen, Utils, Errors, Context + +# the following is to bring some compatibility with waf 1.5 "import waflib.Configure → import Configure" +sys.modules['Environment'] = ConfigSet +ConfigSet.Environment = ConfigSet.ConfigSet + +sys.modules['Logs'] = Logs +sys.modules['Options'] = Options +sys.modules['Scripting'] = Scripting +sys.modules['Task'] = Task +sys.modules['Build'] = Build +sys.modules['Configure'] = Configure +sys.modules['Node'] = Node +sys.modules['Runner'] = Runner +sys.modules['TaskGen'] = TaskGen +sys.modules['Utils'] = Utils +sys.modules['Constants'] = Context +Context.SRCDIR = '' +Context.BLDDIR = '' + +from waflib.Tools import c_preproc +sys.modules['preproc'] = c_preproc + +from waflib.Tools import c_config +sys.modules['config_c'] = c_config + +ConfigSet.ConfigSet.copy = ConfigSet.ConfigSet.derive +ConfigSet.ConfigSet.set_variant = Utils.nada + +Utils.pproc = Utils.subprocess + +Build.BuildContext.add_subdirs = Build.BuildContext.recurse +Build.BuildContext.new_task_gen = Build.BuildContext.__call__ +Build.BuildContext.is_install = 0 +Node.Node.relpath_gen = Node.Node.path_from + +Utils.pproc = Utils.subprocess +Utils.get_term_cols = Logs.get_term_cols + +def cmd_output(cmd, **kw): + + silent = False + if 'silent' in kw: + silent = kw['silent'] + del(kw['silent']) + + if 'e' in kw: + tmp = kw['e'] + del(kw['e']) + kw['env'] = tmp + + kw['shell'] = isinstance(cmd, str) + kw['stdout'] = Utils.subprocess.PIPE + if silent: + kw['stderr'] = Utils.subprocess.PIPE + + try: + p = Utils.subprocess.Popen(cmd, **kw) + output = p.communicate()[0] + except OSError as e: + raise ValueError(str(e)) + + if p.returncode: + if not silent: + msg = "command execution failed: %s -> %r" % (cmd, str(output)) + raise ValueError(msg) + output = '' + return output +Utils.cmd_output = cmd_output + +def name_to_obj(self, s, env=None): + if Logs.verbose: + Logs.warn('compat: change "name_to_obj(name, env)" by "get_tgen_by_name(name)"') + return self.get_tgen_by_name(s) +Build.BuildContext.name_to_obj = name_to_obj + +def env_of_name(self, name): + try: + return self.all_envs[name] + except KeyError: + Logs.error('no such environment: '+name) + return None +Build.BuildContext.env_of_name = env_of_name + + +def set_env_name(self, name, env): + self.all_envs[name] = env + return env +Configure.ConfigurationContext.set_env_name = set_env_name + +def retrieve(self, name, fromenv=None): + try: + env = self.all_envs[name] + except KeyError: + env = ConfigSet.ConfigSet() + self.prepare_env(env) + self.all_envs[name] = env + else: + if fromenv: + Logs.warn('The environment %s may have been configured already', name) + return env +Configure.ConfigurationContext.retrieve = retrieve + +Configure.ConfigurationContext.sub_config = Configure.ConfigurationContext.recurse +Configure.ConfigurationContext.check_tool = Configure.ConfigurationContext.load +Configure.conftest = Configure.conf +Configure.ConfigurationError = Errors.ConfigurationError +Utils.WafError = Errors.WafError + +Options.OptionsContext.sub_options = Options.OptionsContext.recurse +Options.OptionsContext.tool_options = Context.Context.load +Options.Handler = Options.OptionsContext + +Task.simple_task_type = Task.task_type_from_func = Task.task_factory +Task.Task.classes = Task.classes + +def setitem(self, key, value): + if key.startswith('CCFLAGS'): + key = key[1:] + self.table[key] = value +ConfigSet.ConfigSet.__setitem__ = setitem + +@TaskGen.feature('d') +@TaskGen.before('apply_incpaths') +def old_importpaths(self): + if getattr(self, 'importpaths', []): + self.includes = self.importpaths + +from waflib import Context +eld = Context.load_tool +def load_tool(*k, **kw): + ret = eld(*k, **kw) + if 'set_options' in ret.__dict__: + if Logs.verbose: + Logs.warn('compat: rename "set_options" to options') + ret.options = ret.set_options + if 'detect' in ret.__dict__: + if Logs.verbose: + Logs.warn('compat: rename "detect" to "configure"') + ret.configure = ret.detect + return ret +Context.load_tool = load_tool + +def get_curdir(self): + return self.path.abspath() +Context.Context.curdir = property(get_curdir, Utils.nada) + +def get_srcdir(self): + return self.srcnode.abspath() +Configure.ConfigurationContext.srcdir = property(get_srcdir, Utils.nada) + +def get_blddir(self): + return self.bldnode.abspath() +Configure.ConfigurationContext.blddir = property(get_blddir, Utils.nada) + +Configure.ConfigurationContext.check_message_1 = Configure.ConfigurationContext.start_msg +Configure.ConfigurationContext.check_message_2 = Configure.ConfigurationContext.end_msg + +rev = Context.load_module +def load_module(path, encoding=None): + ret = rev(path, encoding) + if 'set_options' in ret.__dict__: + if Logs.verbose: + Logs.warn('compat: rename "set_options" to "options" (%r)', path) + ret.options = ret.set_options + if 'srcdir' in ret.__dict__: + if Logs.verbose: + Logs.warn('compat: rename "srcdir" to "top" (%r)', path) + ret.top = ret.srcdir + if 'blddir' in ret.__dict__: + if Logs.verbose: + Logs.warn('compat: rename "blddir" to "out" (%r)', path) + ret.out = ret.blddir + Utils.g_module = Context.g_module + Options.launch_dir = Context.launch_dir + return ret +Context.load_module = load_module + +old_post = TaskGen.task_gen.post +def post(self): + self.features = self.to_list(self.features) + if 'cc' in self.features: + if Logs.verbose: + Logs.warn('compat: the feature cc does not exist anymore (use "c")') + self.features.remove('cc') + self.features.append('c') + if 'cstaticlib' in self.features: + if Logs.verbose: + Logs.warn('compat: the feature cstaticlib does not exist anymore (use "cstlib" or "cxxstlib")') + self.features.remove('cstaticlib') + self.features.append(('cxx' in self.features) and 'cxxstlib' or 'cstlib') + if getattr(self, 'ccflags', None): + if Logs.verbose: + Logs.warn('compat: "ccflags" was renamed to "cflags"') + self.cflags = self.ccflags + return old_post(self) +TaskGen.task_gen.post = post + +def waf_version(*k, **kw): + Logs.warn('wrong version (waf_version was removed in waf 1.6)') +Utils.waf_version = waf_version + + +import os +@TaskGen.feature('c', 'cxx', 'd') +@TaskGen.before('apply_incpaths', 'propagate_uselib_vars') +@TaskGen.after('apply_link', 'process_source') +def apply_uselib_local(self): + """ + process the uselib_local attribute + execute after apply_link because of the execution order set on 'link_task' + """ + env = self.env + from waflib.Tools.ccroot import stlink_task + + # 1. the case of the libs defined in the project (visit ancestors first) + # the ancestors external libraries (uselib) will be prepended + self.uselib = self.to_list(getattr(self, 'uselib', [])) + self.includes = self.to_list(getattr(self, 'includes', [])) + names = self.to_list(getattr(self, 'uselib_local', [])) + get = self.bld.get_tgen_by_name + seen = set() + seen_uselib = set() + tmp = Utils.deque(names) # consume a copy of the list of names + if tmp: + if Logs.verbose: + Logs.warn('compat: "uselib_local" is deprecated, replace by "use"') + while tmp: + lib_name = tmp.popleft() + # visit dependencies only once + if lib_name in seen: + continue + + y = get(lib_name) + y.post() + seen.add(lib_name) + + # object has ancestors to process (shared libraries): add them to the end of the list + if getattr(y, 'uselib_local', None): + for x in self.to_list(getattr(y, 'uselib_local', [])): + obj = get(x) + obj.post() + if getattr(obj, 'link_task', None): + if not isinstance(obj.link_task, stlink_task): + tmp.append(x) + + # link task and flags + if getattr(y, 'link_task', None): + + link_name = y.target[y.target.rfind(os.sep) + 1:] + if isinstance(y.link_task, stlink_task): + env.append_value('STLIB', [link_name]) + else: + # some linkers can link against programs + env.append_value('LIB', [link_name]) + + # the order + self.link_task.set_run_after(y.link_task) + + # for the recompilation + self.link_task.dep_nodes += y.link_task.outputs + + # add the link path too + tmp_path = y.link_task.outputs[0].parent.bldpath() + if not tmp_path in env['LIBPATH']: + env.prepend_value('LIBPATH', [tmp_path]) + + # add ancestors uselib too - but only propagate those that have no staticlib defined + for v in self.to_list(getattr(y, 'uselib', [])): + if v not in seen_uselib: + seen_uselib.add(v) + if not env['STLIB_' + v]: + if not v in self.uselib: + self.uselib.insert(0, v) + + # if the library task generator provides 'export_includes', add to the include path + # the export_includes must be a list of paths relative to the other library + if getattr(y, 'export_includes', None): + self.includes.extend(y.to_incnodes(y.export_includes)) + +@TaskGen.feature('cprogram', 'cxxprogram', 'cstlib', 'cxxstlib', 'cshlib', 'cxxshlib', 'dprogram', 'dstlib', 'dshlib') +@TaskGen.after('apply_link') +def apply_objdeps(self): + "add the .o files produced by some other object files in the same manner as uselib_local" + names = getattr(self, 'add_objects', []) + if not names: + return + names = self.to_list(names) + + get = self.bld.get_tgen_by_name + seen = [] + while names: + x = names[0] + + # visit dependencies only once + if x in seen: + names = names[1:] + continue + + # object does not exist ? + y = get(x) + + # object has ancestors to process first ? update the list of names + if getattr(y, 'add_objects', None): + added = 0 + lst = y.to_list(y.add_objects) + lst.reverse() + for u in lst: + if u in seen: + continue + added = 1 + names = [u]+names + if added: + continue # list of names modified, loop + + # safe to process the current object + y.post() + seen.append(x) + + for t in getattr(y, 'compiled_tasks', []): + self.link_task.inputs.extend(t.outputs) + +@TaskGen.after('apply_link') +def process_obj_files(self): + if not hasattr(self, 'obj_files'): + return + for x in self.obj_files: + node = self.path.find_resource(x) + self.link_task.inputs.append(node) + +@TaskGen.taskgen_method +def add_obj_file(self, file): + """Small example on how to link object files as if they were source + obj = bld.create_obj('cc') + obj.add_obj_file('foo.o')""" + if not hasattr(self, 'obj_files'): + self.obj_files = [] + if not 'process_obj_files' in self.meths: + self.meths.append('process_obj_files') + self.obj_files.append(file) + + +old_define = Configure.ConfigurationContext.__dict__['define'] + +@Configure.conf +def define(self, key, val, quote=True, comment=''): + old_define(self, key, val, quote, comment) + if key.startswith('HAVE_'): + self.env[key] = 1 + +old_undefine = Configure.ConfigurationContext.__dict__['undefine'] + +@Configure.conf +def undefine(self, key, comment=''): + old_undefine(self, key, comment) + if key.startswith('HAVE_'): + self.env[key] = 0 + +# some people might want to use export_incdirs, but it was renamed +def set_incdirs(self, val): + Logs.warn('compat: change "export_incdirs" by "export_includes"') + self.export_includes = val +TaskGen.task_gen.export_incdirs = property(None, set_incdirs) + +def install_dir(self, path): + if not path: + return [] + + destpath = Utils.subst_vars(path, self.env) + + if self.is_install > 0: + Logs.info('* creating %s', destpath) + Utils.check_dir(destpath) + elif self.is_install < 0: + Logs.info('* removing %s', destpath) + try: + os.remove(destpath) + except OSError: + pass +Build.BuildContext.install_dir = install_dir + +# before/after names +repl = {'apply_core': 'process_source', + 'apply_lib_vars': 'process_source', + 'apply_obj_vars': 'propagate_uselib_vars', + 'exec_rule': 'process_rule' +} +def after(*k): + k = [repl.get(key, key) for key in k] + return TaskGen.after_method(*k) + +def before(*k): + k = [repl.get(key, key) for key in k] + return TaskGen.before_method(*k) +TaskGen.before = before + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/cppcheck.py b/ldb-2.0.8/third_party/waf/waflib/extras/cppcheck.py new file mode 100644 index 0000000..13ff424 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/cppcheck.py @@ -0,0 +1,591 @@ +#! /usr/bin/env python +# -*- encoding: utf-8 -*- +# Michel Mooij, michel.mooij7@gmail.com + +""" +Tool Description +================ +This module provides a waf wrapper (i.e. waftool) around the C/C++ source code +checking tool 'cppcheck'. + +See http://cppcheck.sourceforge.net/ for more information on the cppcheck tool +itself. +Note that many linux distributions already provide a ready to install version +of cppcheck. On fedora, for instance, it can be installed using yum: + + 'sudo yum install cppcheck' + + +Usage +===== +In order to use this waftool simply add it to the 'options' and 'configure' +functions of your main waf script as shown in the example below: + + def options(opt): + opt.load('cppcheck', tooldir='./waftools') + + def configure(conf): + conf.load('cppcheck') + +Note that example shown above assumes that the cppcheck waftool is located in +the sub directory named 'waftools'. + +When configured as shown in the example above, cppcheck will automatically +perform a source code analysis on all C/C++ build tasks that have been +defined in your waf build system. + +The example shown below for a C program will be used as input for cppcheck when +building the task. + + def build(bld): + bld.program(name='foo', src='foobar.c') + +The result of the source code analysis will be stored both as xml and html +files in the build location for the task. Should any error be detected by +cppcheck the build will be aborted and a link to the html report will be shown. +By default, one index.html file is created for each task generator. A global +index.html file can be obtained by setting the following variable +in the configuration section: + + conf.env.CPPCHECK_SINGLE_HTML = False + +When needed source code checking by cppcheck can be disabled per task, per +detected error or warning for a particular task. It can be also be disabled for +all tasks. + +In order to exclude a task from source code checking add the skip option to the +task as shown below: + + def build(bld): + bld.program( + name='foo', + src='foobar.c' + cppcheck_skip=True + ) + +When needed problems detected by cppcheck may be suppressed using a file +containing a list of suppression rules. The relative or absolute path to this +file can be added to the build task as shown in the example below: + + bld.program( + name='bar', + src='foobar.c', + cppcheck_suppress='bar.suppress' + ) + +A cppcheck suppress file should contain one suppress rule per line. Each of +these rules will be passed as an '--suppress=' argument to cppcheck. + +Dependencies +================ +This waftool depends on the python pygments module, it is used for source code +syntax highlighting when creating the html reports. see http://pygments.org/ for +more information on this package. + +Remarks +================ +The generation of the html report is originally based on the cppcheck-htmlreport.py +script that comes shipped with the cppcheck tool. +""" + +import sys +import xml.etree.ElementTree as ElementTree +from waflib import Task, TaskGen, Logs, Context, Options + +PYGMENTS_EXC_MSG= ''' +The required module 'pygments' could not be found. Please install it using your +platform package manager (e.g. apt-get or yum), using 'pip' or 'easy_install', +see 'http://pygments.org/download/' for installation instructions. +''' + +try: + import pygments + from pygments import formatters, lexers +except ImportError as e: + Logs.warn(PYGMENTS_EXC_MSG) + raise e + + +def options(opt): + opt.add_option('--cppcheck-skip', dest='cppcheck_skip', + default=False, action='store_true', + help='do not check C/C++ sources (default=False)') + + opt.add_option('--cppcheck-err-resume', dest='cppcheck_err_resume', + default=False, action='store_true', + help='continue in case of errors (default=False)') + + opt.add_option('--cppcheck-bin-enable', dest='cppcheck_bin_enable', + default='warning,performance,portability,style,unusedFunction', action='store', + help="cppcheck option '--enable=' for binaries (default=warning,performance,portability,style,unusedFunction)") + + opt.add_option('--cppcheck-lib-enable', dest='cppcheck_lib_enable', + default='warning,performance,portability,style', action='store', + help="cppcheck option '--enable=' for libraries (default=warning,performance,portability,style)") + + opt.add_option('--cppcheck-std-c', dest='cppcheck_std_c', + default='c99', action='store', + help='cppcheck standard to use when checking C (default=c99)') + + opt.add_option('--cppcheck-std-cxx', dest='cppcheck_std_cxx', + default='c++03', action='store', + help='cppcheck standard to use when checking C++ (default=c++03)') + + opt.add_option('--cppcheck-check-config', dest='cppcheck_check_config', + default=False, action='store_true', + help='forced check for missing buildin include files, e.g. stdio.h (default=False)') + + opt.add_option('--cppcheck-max-configs', dest='cppcheck_max_configs', + default='20', action='store', + help='maximum preprocessor (--max-configs) define iterations (default=20)') + + opt.add_option('--cppcheck-jobs', dest='cppcheck_jobs', + default='1', action='store', + help='number of jobs (-j) to do the checking work (default=1)') + +def configure(conf): + if conf.options.cppcheck_skip: + conf.env.CPPCHECK_SKIP = [True] + conf.env.CPPCHECK_STD_C = conf.options.cppcheck_std_c + conf.env.CPPCHECK_STD_CXX = conf.options.cppcheck_std_cxx + conf.env.CPPCHECK_MAX_CONFIGS = conf.options.cppcheck_max_configs + conf.env.CPPCHECK_BIN_ENABLE = conf.options.cppcheck_bin_enable + conf.env.CPPCHECK_LIB_ENABLE = conf.options.cppcheck_lib_enable + conf.env.CPPCHECK_JOBS = conf.options.cppcheck_jobs + if conf.options.cppcheck_jobs != '1' and ('unusedFunction' in conf.options.cppcheck_bin_enable or 'unusedFunction' in conf.options.cppcheck_lib_enable or 'all' in conf.options.cppcheck_bin_enable or 'all' in conf.options.cppcheck_lib_enable): + Logs.warn('cppcheck: unusedFunction cannot be used with multiple threads, cppcheck will disable it automatically') + conf.find_program('cppcheck', var='CPPCHECK') + + # set to True to get a single index.html file + conf.env.CPPCHECK_SINGLE_HTML = False + +@TaskGen.feature('c') +@TaskGen.feature('cxx') +def cppcheck_execute(self): + if hasattr(self.bld, 'conf'): + return + if len(self.env.CPPCHECK_SKIP) or Options.options.cppcheck_skip: + return + if getattr(self, 'cppcheck_skip', False): + return + task = self.create_task('cppcheck') + task.cmd = _tgen_create_cmd(self) + task.fatal = [] + if not Options.options.cppcheck_err_resume: + task.fatal.append('error') + + +def _tgen_create_cmd(self): + features = getattr(self, 'features', []) + std_c = self.env.CPPCHECK_STD_C + std_cxx = self.env.CPPCHECK_STD_CXX + max_configs = self.env.CPPCHECK_MAX_CONFIGS + bin_enable = self.env.CPPCHECK_BIN_ENABLE + lib_enable = self.env.CPPCHECK_LIB_ENABLE + jobs = self.env.CPPCHECK_JOBS + + cmd = self.env.CPPCHECK + args = ['--inconclusive','--report-progress','--verbose','--xml','--xml-version=2'] + args.append('--max-configs=%s' % max_configs) + args.append('-j %s' % jobs) + + if 'cxx' in features: + args.append('--language=c++') + args.append('--std=%s' % std_cxx) + else: + args.append('--language=c') + args.append('--std=%s' % std_c) + + if Options.options.cppcheck_check_config: + args.append('--check-config') + + if set(['cprogram','cxxprogram']) & set(features): + args.append('--enable=%s' % bin_enable) + else: + args.append('--enable=%s' % lib_enable) + + for src in self.to_list(getattr(self, 'source', [])): + if not isinstance(src, str): + src = repr(src) + args.append(src) + for inc in self.to_incnodes(self.to_list(getattr(self, 'includes', []))): + if not isinstance(inc, str): + inc = repr(inc) + args.append('-I%s' % inc) + for inc in self.to_incnodes(self.to_list(self.env.INCLUDES)): + if not isinstance(inc, str): + inc = repr(inc) + args.append('-I%s' % inc) + return cmd + args + + +class cppcheck(Task.Task): + quiet = True + + def run(self): + stderr = self.generator.bld.cmd_and_log(self.cmd, quiet=Context.STDERR, output=Context.STDERR) + self._save_xml_report(stderr) + defects = self._get_defects(stderr) + index = self._create_html_report(defects) + self._errors_evaluate(defects, index) + return 0 + + def _save_xml_report(self, s): + '''use cppcheck xml result string, add the command string used to invoke cppcheck + and save as xml file. + ''' + header = '%s\n' % s.splitlines()[0] + root = ElementTree.fromstring(s) + cmd = ElementTree.SubElement(root.find('cppcheck'), 'cmd') + cmd.text = str(self.cmd) + body = ElementTree.tostring(root).decode('us-ascii') + body_html_name = 'cppcheck-%s.xml' % self.generator.get_name() + if self.env.CPPCHECK_SINGLE_HTML: + body_html_name = 'cppcheck.xml' + node = self.generator.path.get_bld().find_or_declare(body_html_name) + node.write(header + body) + + def _get_defects(self, xml_string): + '''evaluate the xml string returned by cppcheck (on sdterr) and use it to create + a list of defects. + ''' + defects = [] + for error in ElementTree.fromstring(xml_string).iter('error'): + defect = {} + defect['id'] = error.get('id') + defect['severity'] = error.get('severity') + defect['msg'] = str(error.get('msg')).replace('<','<') + defect['verbose'] = error.get('verbose') + for location in error.findall('location'): + defect['file'] = location.get('file') + defect['line'] = str(int(location.get('line')) - 1) + defects.append(defect) + return defects + + def _create_html_report(self, defects): + files, css_style_defs = self._create_html_files(defects) + index = self._create_html_index(files) + self._create_css_file(css_style_defs) + return index + + def _create_html_files(self, defects): + sources = {} + defects = [defect for defect in defects if 'file' in defect] + for defect in defects: + name = defect['file'] + if not name in sources: + sources[name] = [defect] + else: + sources[name].append(defect) + + files = {} + css_style_defs = None + bpath = self.generator.path.get_bld().abspath() + names = list(sources.keys()) + for i in range(0,len(names)): + name = names[i] + if self.env.CPPCHECK_SINGLE_HTML: + htmlfile = 'cppcheck/%i.html' % (i) + else: + htmlfile = 'cppcheck/%s%i.html' % (self.generator.get_name(),i) + errors = sources[name] + files[name] = { 'htmlfile': '%s/%s' % (bpath, htmlfile), 'errors': errors } + css_style_defs = self._create_html_file(name, htmlfile, errors) + return files, css_style_defs + + def _create_html_file(self, sourcefile, htmlfile, errors): + name = self.generator.get_name() + root = ElementTree.fromstring(CPPCHECK_HTML_FILE) + title = root.find('head/title') + title.text = 'cppcheck - report - %s' % name + + body = root.find('body') + for div in body.findall('div'): + if div.get('id') == 'page': + page = div + break + for div in page.findall('div'): + if div.get('id') == 'header': + h1 = div.find('h1') + h1.text = 'cppcheck report - %s' % name + if div.get('id') == 'menu': + indexlink = div.find('a') + if self.env.CPPCHECK_SINGLE_HTML: + indexlink.attrib['href'] = 'index.html' + else: + indexlink.attrib['href'] = 'index-%s.html' % name + if div.get('id') == 'content': + content = div + srcnode = self.generator.bld.root.find_node(sourcefile) + hl_lines = [e['line'] for e in errors if 'line' in e] + formatter = CppcheckHtmlFormatter(linenos=True, style='colorful', hl_lines=hl_lines, lineanchors='line') + formatter.errors = [e for e in errors if 'line' in e] + css_style_defs = formatter.get_style_defs('.highlight') + lexer = pygments.lexers.guess_lexer_for_filename(sourcefile, "") + s = pygments.highlight(srcnode.read(), lexer, formatter) + table = ElementTree.fromstring(s) + content.append(table) + + s = ElementTree.tostring(root, method='html').decode('us-ascii') + s = CCPCHECK_HTML_TYPE + s + node = self.generator.path.get_bld().find_or_declare(htmlfile) + node.write(s) + return css_style_defs + + def _create_html_index(self, files): + name = self.generator.get_name() + root = ElementTree.fromstring(CPPCHECK_HTML_FILE) + title = root.find('head/title') + title.text = 'cppcheck - report - %s' % name + + body = root.find('body') + for div in body.findall('div'): + if div.get('id') == 'page': + page = div + break + for div in page.findall('div'): + if div.get('id') == 'header': + h1 = div.find('h1') + h1.text = 'cppcheck report - %s' % name + if div.get('id') == 'content': + content = div + self._create_html_table(content, files) + if div.get('id') == 'menu': + indexlink = div.find('a') + if self.env.CPPCHECK_SINGLE_HTML: + indexlink.attrib['href'] = 'index.html' + else: + indexlink.attrib['href'] = 'index-%s.html' % name + + s = ElementTree.tostring(root, method='html').decode('us-ascii') + s = CCPCHECK_HTML_TYPE + s + index_html_name = 'cppcheck/index-%s.html' % name + if self.env.CPPCHECK_SINGLE_HTML: + index_html_name = 'cppcheck/index.html' + node = self.generator.path.get_bld().find_or_declare(index_html_name) + node.write(s) + return node + + def _create_html_table(self, content, files): + table = ElementTree.fromstring(CPPCHECK_HTML_TABLE) + for name, val in files.items(): + f = val['htmlfile'] + s = '%s\n' % (f,name) + row = ElementTree.fromstring(s) + table.append(row) + + errors = sorted(val['errors'], key=lambda e: int(e['line']) if 'line' in e else sys.maxint) + for e in errors: + if not 'line' in e: + s = '%s%s%s\n' % (e['id'], e['severity'], e['msg']) + else: + attr = '' + if e['severity'] == 'error': + attr = 'class="error"' + s = '%s' % (f, e['line'], e['line']) + s+= '%s%s%s\n' % (e['id'], e['severity'], attr, e['msg']) + row = ElementTree.fromstring(s) + table.append(row) + content.append(table) + + def _create_css_file(self, css_style_defs): + css = str(CPPCHECK_CSS_FILE) + if css_style_defs: + css = "%s\n%s\n" % (css, css_style_defs) + node = self.generator.path.get_bld().find_or_declare('cppcheck/style.css') + node.write(css) + + def _errors_evaluate(self, errors, http_index): + name = self.generator.get_name() + fatal = self.fatal + severity = [err['severity'] for err in errors] + problems = [err for err in errors if err['severity'] != 'information'] + + if set(fatal) & set(severity): + exc = "\n" + exc += "\nccpcheck detected fatal error(s) in task '%s', see report for details:" % name + exc += "\n file://%r" % (http_index) + exc += "\n" + self.generator.bld.fatal(exc) + + elif len(problems): + msg = "\nccpcheck detected (possible) problem(s) in task '%s', see report for details:" % name + msg += "\n file://%r" % http_index + msg += "\n" + Logs.error(msg) + + +class CppcheckHtmlFormatter(pygments.formatters.HtmlFormatter): + errors = [] + + def wrap(self, source, outfile): + line_no = 1 + for i, t in super(CppcheckHtmlFormatter, self).wrap(source, outfile): + # If this is a source code line we want to add a span tag at the end. + if i == 1: + for error in self.errors: + if int(error['line']) == line_no: + t = t.replace('\n', CPPCHECK_HTML_ERROR % error['msg']) + line_no += 1 + yield i, t + + +CCPCHECK_HTML_TYPE = \ +'\n' + +CPPCHECK_HTML_FILE = """ +]> + + + cppcheck - report - XXX + + + + + +
      + + +
      +
      + +   +
      + + + +""" + +CPPCHECK_HTML_TABLE = """ + + + + + + + +
      LineIdSeverityMessage
      +""" + +CPPCHECK_HTML_ERROR = \ +'<--- %s\n' + +CPPCHECK_CSS_FILE = """ +body.body { + font-family: Arial; + font-size: 13px; + background-color: black; + padding: 0px; + margin: 0px; +} + +.error { + font-family: Arial; + font-size: 13px; + background-color: #ffb7b7; + padding: 0px; + margin: 0px; +} + +th, td { + min-width: 100px; + text-align: left; +} + +#page-header { + clear: both; + width: 1200px; + margin: 20px auto 0px auto; + height: 10px; + border-bottom-width: 2px; + border-bottom-style: solid; + border-bottom-color: #aaaaaa; +} + +#page { + width: 1160px; + margin: auto; + border-left-width: 2px; + border-left-style: solid; + border-left-color: #aaaaaa; + border-right-width: 2px; + border-right-style: solid; + border-right-color: #aaaaaa; + background-color: White; + padding: 20px; +} + +#page-footer { + clear: both; + width: 1200px; + margin: auto; + height: 10px; + border-top-width: 2px; + border-top-style: solid; + border-top-color: #aaaaaa; +} + +#header { + width: 100%; + height: 70px; + background-image: url(logo.png); + background-repeat: no-repeat; + background-position: left top; + border-bottom-style: solid; + border-bottom-width: thin; + border-bottom-color: #aaaaaa; +} + +#menu { + margin-top: 5px; + text-align: left; + float: left; + width: 100px; + height: 300px; +} + +#menu > a { + margin-left: 10px; + display: block; +} + +#content { + float: left; + width: 1020px; + margin: 5px; + padding: 0px 10px 10px 10px; + border-left-style: solid; + border-left-width: thin; + border-left-color: #aaaaaa; +} + +#footer { + padding-bottom: 5px; + padding-top: 5px; + border-top-style: solid; + border-top-width: thin; + border-top-color: #aaaaaa; + clear: both; + font-size: 10px; +} + +#footer > div { + float: left; + width: 33%; +} + +""" + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/cpplint.py b/ldb-2.0.8/third_party/waf/waflib/extras/cpplint.py new file mode 100644 index 0000000..8cdd6dd --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/cpplint.py @@ -0,0 +1,209 @@ +#! /usr/bin/env python +# encoding: utf-8 +# +# written by Sylvain Rouquette, 2014 + +''' + +This is an extra tool, not bundled with the default waf binary. +To add the cpplint tool to the waf file: +$ ./waf-light --tools=compat15,cpplint + +this tool also requires cpplint for python. +If you have PIP, you can install it like this: pip install cpplint + +When using this tool, the wscript will look like: + + def options(opt): + opt.load('compiler_cxx cpplint') + + def configure(conf): + conf.load('compiler_cxx cpplint') + # optional, you can also specify them on the command line + conf.env.CPPLINT_FILTERS = ','.join(( + '-whitespace/newline', # c++11 lambda + '-readability/braces', # c++11 constructor + '-whitespace/braces', # c++11 constructor + '-build/storage_class', # c++11 for-range + '-whitespace/blank_line', # user pref + '-whitespace/labels' # user pref + )) + + def build(bld): + bld(features='cpplint', source='main.cpp', target='app') + # add include files, because they aren't usually built + bld(features='cpplint', source=bld.path.ant_glob('**/*.hpp')) +''' + +from __future__ import absolute_import +import sys, re +import logging +from waflib import Errors, Task, TaskGen, Logs, Options, Node, Utils + + +critical_errors = 0 +CPPLINT_FORMAT = '[CPPLINT] %(filename)s:\nline %(linenum)s, severity %(confidence)s, category: %(category)s\n%(message)s\n' +RE_EMACS = re.compile(r'(?P.*):(?P\d+): (?P.*) \[(?P.*)\] \[(?P\d+)\]') +CPPLINT_RE = { + 'waf': RE_EMACS, + 'emacs': RE_EMACS, + 'vs7': re.compile(r'(?P.*)\((?P\d+)\): (?P.*) \[(?P.*)\] \[(?P\d+)\]'), + 'eclipse': re.compile(r'(?P.*):(?P\d+): warning: (?P.*) \[(?P.*)\] \[(?P\d+)\]'), +} +CPPLINT_STR = ('${CPPLINT} ' + '--verbose=${CPPLINT_LEVEL} ' + '--output=${CPPLINT_OUTPUT} ' + '--filter=${CPPLINT_FILTERS} ' + '--root=${CPPLINT_ROOT} ' + '--linelength=${CPPLINT_LINE_LENGTH} ') + + +def options(opt): + opt.add_option('--cpplint-filters', type='string', + default='', dest='CPPLINT_FILTERS', + help='add filters to cpplint') + opt.add_option('--cpplint-length', type='int', + default=80, dest='CPPLINT_LINE_LENGTH', + help='specify the line length (default: 80)') + opt.add_option('--cpplint-level', default=1, type='int', dest='CPPLINT_LEVEL', + help='specify the log level (default: 1)') + opt.add_option('--cpplint-break', default=5, type='int', dest='CPPLINT_BREAK', + help='break the build if error >= level (default: 5)') + opt.add_option('--cpplint-root', type='string', + default='', dest='CPPLINT_ROOT', + help='root directory used to derive header guard') + opt.add_option('--cpplint-skip', action='store_true', + default=False, dest='CPPLINT_SKIP', + help='skip cpplint during build') + opt.add_option('--cpplint-output', type='string', + default='waf', dest='CPPLINT_OUTPUT', + help='select output format (waf, emacs, vs7, eclipse)') + + +def configure(conf): + try: + conf.find_program('cpplint', var='CPPLINT') + except Errors.ConfigurationError: + conf.env.CPPLINT_SKIP = True + + +class cpplint_formatter(Logs.formatter, object): + def __init__(self, fmt): + logging.Formatter.__init__(self, CPPLINT_FORMAT) + self.fmt = fmt + + def format(self, rec): + if self.fmt == 'waf': + result = CPPLINT_RE[self.fmt].match(rec.msg).groupdict() + rec.msg = CPPLINT_FORMAT % result + if rec.levelno <= logging.INFO: + rec.c1 = Logs.colors.CYAN + return super(cpplint_formatter, self).format(rec) + + +class cpplint_handler(Logs.log_handler, object): + def __init__(self, stream=sys.stderr, **kw): + super(cpplint_handler, self).__init__(stream, **kw) + self.stream = stream + + def emit(self, rec): + rec.stream = self.stream + self.emit_override(rec) + self.flush() + + +class cpplint_wrapper(object): + def __init__(self, logger, threshold, fmt): + self.logger = logger + self.threshold = threshold + self.fmt = fmt + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_value, traceback): + if isinstance(exc_value, Utils.subprocess.CalledProcessError): + messages = [m for m in exc_value.output.splitlines() + if 'Done processing' not in m + and 'Total errors found' not in m] + for message in messages: + self.write(message) + return True + + def write(self, message): + global critical_errors + result = CPPLINT_RE[self.fmt].match(message) + if not result: + return + level = int(result.groupdict()['confidence']) + if level >= self.threshold: + critical_errors += 1 + if level <= 2: + self.logger.info(message) + elif level <= 4: + self.logger.warning(message) + else: + self.logger.error(message) + + +cpplint_logger = None +def get_cpplint_logger(fmt): + global cpplint_logger + if cpplint_logger: + return cpplint_logger + cpplint_logger = logging.getLogger('cpplint') + hdlr = cpplint_handler() + hdlr.setFormatter(cpplint_formatter(fmt)) + cpplint_logger.addHandler(hdlr) + cpplint_logger.setLevel(logging.DEBUG) + return cpplint_logger + + +class cpplint(Task.Task): + color = 'PINK' + + def __init__(self, *k, **kw): + super(cpplint, self).__init__(*k, **kw) + + def run(self): + global critical_errors + with cpplint_wrapper(get_cpplint_logger(self.env.CPPLINT_OUTPUT), self.env.CPPLINT_BREAK, self.env.CPPLINT_OUTPUT): + params = {key: str(self.env[key]) for key in self.env if 'CPPLINT_' in key} + if params['CPPLINT_OUTPUT'] is 'waf': + params['CPPLINT_OUTPUT'] = 'emacs' + params['CPPLINT'] = self.env.get_flat('CPPLINT') + cmd = Utils.subst_vars(CPPLINT_STR, params) + env = self.env.env or None + Utils.subprocess.check_output(cmd + self.inputs[0].abspath(), + stderr=Utils.subprocess.STDOUT, + env=env, shell=True) + return critical_errors + +@TaskGen.extension('.h', '.hh', '.hpp', '.hxx') +def cpplint_includes(self, node): + pass + +@TaskGen.feature('cpplint') +@TaskGen.before_method('process_source') +def post_cpplint(self): + if not self.env.CPPLINT_INITIALIZED: + for key, value in Options.options.__dict__.items(): + if not key.startswith('CPPLINT_') or self.env[key]: + continue + self.env[key] = value + self.env.CPPLINT_INITIALIZED = True + + if self.env.CPPLINT_SKIP: + return + + if not self.env.CPPLINT_OUTPUT in CPPLINT_RE: + return + + for src in self.to_list(getattr(self, 'source', [])): + if isinstance(src, Node.Node): + node = src + else: + node = self.path.find_or_declare(src) + if not node: + self.bld.fatal('Could not find %r' % src) + self.create_task('cpplint', node) diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/cross_gnu.py b/ldb-2.0.8/third_party/waf/waflib/extras/cross_gnu.py new file mode 100644 index 0000000..309f53b --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/cross_gnu.py @@ -0,0 +1,227 @@ +#!/usr/bin/python +# -*- coding: utf-8 vi:ts=4:noexpandtab +# Tool to provide dedicated variables for cross-compilation + +__author__ = __maintainer__ = "Jérôme Carretero " +__copyright__ = "Jérôme Carretero, 2014" + +""" +This tool allows to use environment variables to define cross-compilation +variables intended for build variants. + +The variables are obtained from the environment in 3 ways: + +1. By defining CHOST, they can be derived as ${CHOST}-${TOOL} +2. By defining HOST_x +3. By defining ${CHOST//-/_}_x + +else one can set ``cfg.env.CHOST`` in ``wscript`` before loading ``cross_gnu``. + +Usage: + +- In your build script:: + + def configure(cfg): + ... + for variant in x_variants: + setenv(variant) + conf.load('cross_gnu') + conf.xcheck_host_var('POUET') + ... + + +- Then:: + + CHOST=arm-hardfloat-linux-gnueabi waf configure + env arm-hardfloat-linux-gnueabi-CC="clang -..." waf configure + CFLAGS=... CHOST=arm-hardfloat-linux-gnueabi HOST_CFLAGS=-g waf configure + HOST_CC="clang -..." waf configure + +This example ``wscript`` compiles to Microchip PIC (xc16-gcc-xyz must be in PATH): + +.. code:: python + + from waflib import Configure + + #from https://gist.github.com/rpuntaie/2bddfb5d7b77db26415ee14371289971 + import waf_variants + + variants='pc fw/variant1 fw/variant2'.split() + + top = "." + out = "../build" + + PIC = '33FJ128GP804' #dsPICxxx + + @Configure.conf + def gcc_modifier_xc16(cfg): + v = cfg.env + v.cprogram_PATTERN = '%s.elf' + v.LINKFLAGS_cprogram = ','.join(['-Wl','','','--defsym=__MPLAB_BUILD=0','','--script=p'+PIC+'.gld', + '--stack=16','--check-sections','--data-init','--pack-data','--handles','--isr','--no-gc-sections', + '--fill-upper=0','--stackguard=16','--no-force-link','--smart-io']) #,'--report-mem']) + v.CFLAGS_cprogram=['-mcpu='+PIC,'-omf=elf','-mlarge-code','-msmart-io=1', + '-msfr-warn=off','-mno-override-inline','-finline','-Winline'] + + def configure(cfg): + if 'fw' in cfg.variant: #firmware + cfg.env.DEST_OS = 'xc16' #cfg.env.CHOST = 'xc16' #works too + cfg.load('c cross_gnu') #cfg.env.CHOST becomes ['xc16'] + ... + else: #configure for pc SW + ... + + def build(bld): + if 'fw' in bld.variant: #firmware + bld.program(source='maintst.c', target='maintst'); + bld(source='maintst.elf', target='maintst.hex', rule="xc16-bin2hex ${SRC} -a -omf=elf") + else: #build for pc SW + ... + +""" + +import os +from waflib import Utils, Configure +from waflib.Tools import ccroot, gcc + +try: + from shlex import quote +except ImportError: + from pipes import quote + +def get_chost_stuff(conf): + """ + Get the CHOST environment variable contents + """ + chost = None + chost_envar = None + if conf.env.CHOST: + chost = conf.env.CHOST[0] + chost_envar = chost.replace('-', '_') + return chost, chost_envar + + +@Configure.conf +def xcheck_var(conf, name, wafname=None, cross=False): + wafname = wafname or name + + if wafname in conf.env: + value = conf.env[wafname] + if isinstance(value, str): + value = [value] + else: + envar = os.environ.get(name) + if not envar: + return + value = Utils.to_list(envar) if envar != '' else [envar] + + conf.env[wafname] = value + if cross: + pretty = 'cross-compilation %s' % wafname + else: + pretty = wafname + conf.msg('Will use %s' % pretty, " ".join(quote(x) for x in value)) + +@Configure.conf +def xcheck_host_prog(conf, name, tool, wafname=None): + wafname = wafname or name + + chost, chost_envar = get_chost_stuff(conf) + + specific = None + if chost: + specific = os.environ.get('%s_%s' % (chost_envar, name)) + + if specific: + value = Utils.to_list(specific) + conf.env[wafname] += value + conf.msg('Will use cross-compilation %s from %s_%s' % (name, chost_envar, name), + " ".join(quote(x) for x in value)) + return + else: + envar = os.environ.get('HOST_%s' % name) + if envar is not None: + value = Utils.to_list(envar) + conf.env[wafname] = value + conf.msg('Will use cross-compilation %s from HOST_%s' % (name, name), + " ".join(quote(x) for x in value)) + return + + if conf.env[wafname]: + return + + value = None + if chost: + value = '%s-%s' % (chost, tool) + + if value: + conf.env[wafname] = value + conf.msg('Will use cross-compilation %s from CHOST' % wafname, value) + +@Configure.conf +def xcheck_host_envar(conf, name, wafname=None): + wafname = wafname or name + + chost, chost_envar = get_chost_stuff(conf) + + specific = None + if chost: + specific = os.environ.get('%s_%s' % (chost_envar, name)) + + if specific: + value = Utils.to_list(specific) + conf.env[wafname] += value + conf.msg('Will use cross-compilation %s from %s_%s' \ + % (name, chost_envar, name), + " ".join(quote(x) for x in value)) + return + + + envar = os.environ.get('HOST_%s' % name) + if envar is None: + return + + value = Utils.to_list(envar) if envar != '' else [envar] + + conf.env[wafname] = value + conf.msg('Will use cross-compilation %s from HOST_%s' % (name, name), + " ".join(quote(x) for x in value)) + + +@Configure.conf +def xcheck_host(conf): + conf.xcheck_var('CHOST', cross=True) + conf.env.CHOST = conf.env.CHOST or [conf.env.DEST_OS] + conf.env.DEST_OS = conf.env.CHOST[0].replace('-','_') + conf.xcheck_host_prog('CC', 'gcc') + conf.xcheck_host_prog('CXX', 'g++') + conf.xcheck_host_prog('LINK_CC', 'gcc') + conf.xcheck_host_prog('LINK_CXX', 'g++') + conf.xcheck_host_prog('AR', 'ar') + conf.xcheck_host_prog('AS', 'as') + conf.xcheck_host_prog('LD', 'ld') + conf.xcheck_host_envar('CFLAGS') + conf.xcheck_host_envar('CXXFLAGS') + conf.xcheck_host_envar('LDFLAGS', 'LINKFLAGS') + conf.xcheck_host_envar('LIB') + conf.xcheck_host_envar('PKG_CONFIG_LIBDIR') + conf.xcheck_host_envar('PKG_CONFIG_PATH') + + if not conf.env.env: + conf.env.env = {} + conf.env.env.update(os.environ) + if conf.env.PKG_CONFIG_LIBDIR: + conf.env.env['PKG_CONFIG_LIBDIR'] = conf.env.PKG_CONFIG_LIBDIR[0] + if conf.env.PKG_CONFIG_PATH: + conf.env.env['PKG_CONFIG_PATH'] = conf.env.PKG_CONFIG_PATH[0] + +def configure(conf): + """ + Configuration example for gcc, it will not work for g++/clang/clang++ + """ + conf.xcheck_host() + conf.gcc_common_flags() + conf.gcc_modifier_platform() + conf.cc_load_tools() + conf.cc_add_flags() + conf.link_add_flags() diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/cython.py b/ldb-2.0.8/third_party/waf/waflib/extras/cython.py new file mode 100644 index 0000000..591c274 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/cython.py @@ -0,0 +1,147 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2010-2015 + +import re +from waflib import Task, Logs +from waflib.TaskGen import extension + +cy_api_pat = re.compile(r'\s*?cdef\s*?(public|api)\w*') +re_cyt = re.compile(r""" + ^\s* # must begin with some whitespace characters + (?:from\s+(\w+)(?:\.\w+)*\s+)? # optionally match "from foo(.baz)" and capture foo + c?import\s(\w+|[*]) # require "import bar" and capture bar + """, re.M | re.VERBOSE) + +@extension('.pyx') +def add_cython_file(self, node): + """ + Process a *.pyx* file given in the list of source files. No additional + feature is required:: + + def build(bld): + bld(features='c cshlib pyext', source='main.c foo.pyx', target='app') + """ + ext = '.c' + if 'cxx' in self.features: + self.env.append_unique('CYTHONFLAGS', '--cplus') + ext = '.cc' + + for x in getattr(self, 'cython_includes', []): + # TODO re-use these nodes in "scan" below + d = self.path.find_dir(x) + if d: + self.env.append_unique('CYTHONFLAGS', '-I%s' % d.abspath()) + + tsk = self.create_task('cython', node, node.change_ext(ext)) + self.source += tsk.outputs + +class cython(Task.Task): + run_str = '${CYTHON} ${CYTHONFLAGS} -o ${TGT[0].abspath()} ${SRC}' + color = 'GREEN' + + vars = ['INCLUDES'] + """ + Rebuild whenever the INCLUDES change. The variables such as CYTHONFLAGS will be appended + by the metaclass. + """ + + ext_out = ['.h'] + """ + The creation of a .h file is known only after the build has begun, so it is not + possible to compute a build order just by looking at the task inputs/outputs. + """ + + def runnable_status(self): + """ + Perform a double-check to add the headers created by cython + to the output nodes. The scanner is executed only when the cython task + must be executed (optimization). + """ + ret = super(cython, self).runnable_status() + if ret == Task.ASK_LATER: + return ret + for x in self.generator.bld.raw_deps[self.uid()]: + if x.startswith('header:'): + self.outputs.append(self.inputs[0].parent.find_or_declare(x.replace('header:', ''))) + return super(cython, self).runnable_status() + + def post_run(self): + for x in self.outputs: + if x.name.endswith('.h'): + if not x.exists(): + if Logs.verbose: + Logs.warn('Expected %r', x.abspath()) + x.write('') + return Task.Task.post_run(self) + + def scan(self): + """ + Return the dependent files (.pxd) by looking in the include folders. + Put the headers to generate in the custom list "bld.raw_deps". + To inspect the scanne results use:: + + $ waf clean build --zones=deps + """ + node = self.inputs[0] + txt = node.read() + + mods = set() + for m in re_cyt.finditer(txt): + if m.group(1): # matches "from foo import bar" + mods.add(m.group(1)) + else: + mods.add(m.group(2)) + + Logs.debug('cython: mods %r', mods) + incs = getattr(self.generator, 'cython_includes', []) + incs = [self.generator.path.find_dir(x) for x in incs] + incs.append(node.parent) + + found = [] + missing = [] + for x in sorted(mods): + for y in incs: + k = y.find_resource(x + '.pxd') + if k: + found.append(k) + break + else: + missing.append(x) + + # the cython file implicitly depends on a pxd file that might be present + implicit = node.parent.find_resource(node.name[:-3] + 'pxd') + if implicit: + found.append(implicit) + + Logs.debug('cython: found %r', found) + + # Now the .h created - store them in bld.raw_deps for later use + has_api = False + has_public = False + for l in txt.splitlines(): + if cy_api_pat.match(l): + if ' api ' in l: + has_api = True + if ' public ' in l: + has_public = True + name = node.name.replace('.pyx', '') + if has_api: + missing.append('header:%s_api.h' % name) + if has_public: + missing.append('header:%s.h' % name) + + return (found, missing) + +def options(ctx): + ctx.add_option('--cython-flags', action='store', default='', help='space separated list of flags to pass to cython') + +def configure(ctx): + if not ctx.env.CC and not ctx.env.CXX: + ctx.fatal('Load a C/C++ compiler first') + if not ctx.env.PYTHON: + ctx.fatal('Load the python tool first!') + ctx.find_program('cython', var='CYTHON') + if hasattr(ctx.options, 'cython_flags'): + ctx.env.CYTHONFLAGS = ctx.options.cython_flags + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/dcc.py b/ldb-2.0.8/third_party/waf/waflib/extras/dcc.py new file mode 100644 index 0000000..c1a57c0 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/dcc.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Jérôme Carretero, 2011 (zougloub) + +from waflib import Options +from waflib.Tools import ccroot +from waflib.Configure import conf + +@conf +def find_dcc(conf): + conf.find_program(['dcc'], var='CC', path_list=getattr(Options.options, 'diabbindir', "")) + conf.env.CC_NAME = 'dcc' + +@conf +def find_dld(conf): + conf.find_program(['dld'], var='LINK_CC', path_list=getattr(Options.options, 'diabbindir', "")) + conf.env.LINK_CC_NAME = 'dld' + +@conf +def find_dar(conf): + conf.find_program(['dar'], var='AR', path_list=getattr(Options.options, 'diabbindir', "")) + conf.env.AR_NAME = 'dar' + conf.env.ARFLAGS = 'rcs' + +@conf +def find_ddump(conf): + conf.find_program(['ddump'], var='DDUMP', path_list=getattr(Options.options, 'diabbindir', "")) + +@conf +def dcc_common_flags(conf): + v = conf.env + v['CC_SRC_F'] = [] + v['CC_TGT_F'] = ['-c', '-o'] + + # linker + if not v['LINK_CC']: + v['LINK_CC'] = v['CC'] + v['CCLNK_SRC_F'] = [] + v['CCLNK_TGT_F'] = ['-o'] + v['CPPPATH_ST'] = '-I%s' + v['DEFINES_ST'] = '-D%s' + + v['LIB_ST'] = '-l:%s' # template for adding libs + v['LIBPATH_ST'] = '-L%s' # template for adding libpaths + v['STLIB_ST'] = '-l:%s' + v['STLIBPATH_ST'] = '-L%s' + v['RPATH_ST'] = '-Wl,-rpath,%s' + #v['STLIB_MARKER'] = '-Wl,-Bstatic' + + # program + v['cprogram_PATTERN'] = '%s.elf' + + # static lib + v['LINKFLAGS_cstlib'] = ['-Wl,-Bstatic'] + v['cstlib_PATTERN'] = 'lib%s.a' + +def configure(conf): + conf.find_dcc() + conf.find_dar() + conf.find_dld() + conf.find_ddump() + conf.dcc_common_flags() + conf.cc_load_tools() + conf.cc_add_flags() + conf.link_add_flags() + +def options(opt): + """ + Add the ``--with-diab-bindir`` command-line options. + """ + opt.add_option('--with-diab-bindir', type='string', dest='diabbindir', help = 'Specify alternate diab bin folder', default="") + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/distnet.py b/ldb-2.0.8/third_party/waf/waflib/extras/distnet.py new file mode 100644 index 0000000..ff3ed8e --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/distnet.py @@ -0,0 +1,430 @@ +#! /usr/bin/env python +# encoding: utf-8 + +""" +waf-powered distributed network builds, with a network cache. + +Caching files from a server has advantages over a NFS/Samba shared folder: + +- builds are much faster because they use local files +- builds just continue to work in case of a network glitch +- permissions are much simpler to manage +""" + +import os, urllib, tarfile, re, shutil, tempfile, sys +from collections import OrderedDict +from waflib import Context, Utils, Logs + +try: + from urllib.parse import urlencode +except ImportError: + urlencode = urllib.urlencode + +def safe_urlencode(data): + x = urlencode(data) + try: + x = x.encode('utf-8') + except Exception: + pass + return x + +try: + from urllib.error import URLError +except ImportError: + from urllib2 import URLError + +try: + from urllib.request import Request, urlopen +except ImportError: + from urllib2 import Request, urlopen + +DISTNETCACHE = os.environ.get('DISTNETCACHE', '/tmp/distnetcache') +DISTNETSERVER = os.environ.get('DISTNETSERVER', 'http://localhost:8000/cgi-bin/') +TARFORMAT = 'w:bz2' +TIMEOUT = 60 +REQUIRES = 'requires.txt' + +re_com = re.compile(r'\s*#.*', re.M) + +def total_version_order(num): + lst = num.split('.') + template = '%10s' * len(lst) + ret = template % tuple(lst) + return ret + +def get_distnet_cache(): + return getattr(Context.g_module, 'DISTNETCACHE', DISTNETCACHE) + +def get_server_url(): + return getattr(Context.g_module, 'DISTNETSERVER', DISTNETSERVER) + +def get_download_url(): + return '%s/download.py' % get_server_url() + +def get_upload_url(): + return '%s/upload.py' % get_server_url() + +def get_resolve_url(): + return '%s/resolve.py' % get_server_url() + +def send_package_name(): + out = getattr(Context.g_module, 'out', 'build') + pkgfile = '%s/package_to_upload.tarfile' % out + return pkgfile + +class package(Context.Context): + fun = 'package' + cmd = 'package' + + def execute(self): + try: + files = self.files + except AttributeError: + files = self.files = [] + + Context.Context.execute(self) + pkgfile = send_package_name() + if not pkgfile in files: + if not REQUIRES in files: + files.append(REQUIRES) + self.make_tarfile(pkgfile, files, add_to_package=False) + + def make_tarfile(self, filename, files, **kw): + if kw.get('add_to_package', True): + self.files.append(filename) + + with tarfile.open(filename, TARFORMAT) as tar: + endname = os.path.split(filename)[-1] + endname = endname.split('.')[0] + '/' + for x in files: + tarinfo = tar.gettarinfo(x, x) + tarinfo.uid = tarinfo.gid = 0 + tarinfo.uname = tarinfo.gname = 'root' + tarinfo.size = os.stat(x).st_size + + # TODO - more archive creation options? + if kw.get('bare', True): + tarinfo.name = os.path.split(x)[1] + else: + tarinfo.name = endname + x # todo, if tuple, then.. + Logs.debug('distnet: adding %r to %s', tarinfo.name, filename) + with open(x, 'rb') as f: + tar.addfile(tarinfo, f) + Logs.info('Created %s', filename) + +class publish(Context.Context): + fun = 'publish' + cmd = 'publish' + def execute(self): + if hasattr(Context.g_module, 'publish'): + Context.Context.execute(self) + mod = Context.g_module + + rfile = getattr(self, 'rfile', send_package_name()) + if not os.path.isfile(rfile): + self.fatal('Create the release file with "waf release" first! %r' % rfile) + + fdata = Utils.readf(rfile, m='rb') + data = safe_urlencode([('pkgdata', fdata), ('pkgname', mod.APPNAME), ('pkgver', mod.VERSION)]) + + req = Request(get_upload_url(), data) + response = urlopen(req, timeout=TIMEOUT) + data = response.read().strip() + + if sys.hexversion>0x300000f: + data = data.decode('utf-8') + + if data != 'ok': + self.fatal('Could not publish the package %r' % data) + +class constraint(object): + def __init__(self, line=''): + self.required_line = line + self.info = [] + + line = line.strip() + if not line: + return + + lst = line.split(',') + if lst: + self.pkgname = lst[0] + self.required_version = lst[1] + for k in lst: + a, b, c = k.partition('=') + if a and c: + self.info.append((a, c)) + def __str__(self): + buf = [] + buf.append(self.pkgname) + buf.append(self.required_version) + for k in self.info: + buf.append('%s=%s' % k) + return ','.join(buf) + + def __repr__(self): + return "requires %s-%s" % (self.pkgname, self.required_version) + + def human_display(self, pkgname, pkgver): + return '%s-%s requires %s-%s' % (pkgname, pkgver, self.pkgname, self.required_version) + + def why(self): + ret = [] + for x in self.info: + if x[0] == 'reason': + ret.append(x[1]) + return ret + + def add_reason(self, reason): + self.info.append(('reason', reason)) + +def parse_constraints(text): + assert(text is not None) + constraints = [] + text = re.sub(re_com, '', text) + lines = text.splitlines() + for line in lines: + line = line.strip() + if not line: + continue + constraints.append(constraint(line)) + return constraints + +def list_package_versions(cachedir, pkgname): + pkgdir = os.path.join(cachedir, pkgname) + try: + versions = os.listdir(pkgdir) + except OSError: + return [] + versions.sort(key=total_version_order) + versions.reverse() + return versions + +class package_reader(Context.Context): + cmd = 'solver' + fun = 'solver' + + def __init__(self, **kw): + Context.Context.__init__(self, **kw) + + self.myproject = getattr(Context.g_module, 'APPNAME', 'project') + self.myversion = getattr(Context.g_module, 'VERSION', '1.0') + self.cache_constraints = {} + self.constraints = [] + + def compute_dependencies(self, filename=REQUIRES): + text = Utils.readf(filename) + data = safe_urlencode([('text', text)]) + + if '--offline' in sys.argv: + self.constraints = self.local_resolve(text) + else: + req = Request(get_resolve_url(), data) + try: + response = urlopen(req, timeout=TIMEOUT) + except URLError as e: + Logs.warn('The package server is down! %r', e) + self.constraints = self.local_resolve(text) + else: + ret = response.read() + try: + ret = ret.decode('utf-8') + except Exception: + pass + self.trace(ret) + self.constraints = parse_constraints(ret) + self.check_errors() + + def check_errors(self): + errors = False + for c in self.constraints: + if not c.required_version: + errors = True + + reasons = c.why() + if len(reasons) == 1: + Logs.error('%s but no matching package could be found in this repository', reasons[0]) + else: + Logs.error('Conflicts on package %r:', c.pkgname) + for r in reasons: + Logs.error(' %s', r) + if errors: + self.fatal('The package requirements cannot be satisfied!') + + def load_constraints(self, pkgname, pkgver, requires=REQUIRES): + try: + return self.cache_constraints[(pkgname, pkgver)] + except KeyError: + text = Utils.readf(os.path.join(get_distnet_cache(), pkgname, pkgver, requires)) + ret = parse_constraints(text) + self.cache_constraints[(pkgname, pkgver)] = ret + return ret + + def apply_constraint(self, domain, constraint): + vname = constraint.required_version.replace('*', '.*') + rev = re.compile(vname, re.M) + ret = [x for x in domain if rev.match(x)] + return ret + + def trace(self, *k): + if getattr(self, 'debug', None): + Logs.error(*k) + + def solve(self, packages_to_versions={}, packages_to_constraints={}, pkgname='', pkgver='', todo=[], done=[]): + # breadth first search + n_packages_to_versions = dict(packages_to_versions) + n_packages_to_constraints = dict(packages_to_constraints) + + self.trace("calling solve with %r %r %r" % (packages_to_versions, todo, done)) + done = done + [pkgname] + + constraints = self.load_constraints(pkgname, pkgver) + self.trace("constraints %r" % constraints) + + for k in constraints: + try: + domain = n_packages_to_versions[k.pkgname] + except KeyError: + domain = list_package_versions(get_distnet_cache(), k.pkgname) + + + self.trace("constraints?") + if not k.pkgname in done: + todo = todo + [k.pkgname] + + self.trace("domain before %s -> %s, %r" % (pkgname, k.pkgname, domain)) + + # apply the constraint + domain = self.apply_constraint(domain, k) + + self.trace("domain after %s -> %s, %r" % (pkgname, k.pkgname, domain)) + + n_packages_to_versions[k.pkgname] = domain + + # then store the constraint applied + constraints = list(packages_to_constraints.get(k.pkgname, [])) + constraints.append((pkgname, pkgver, k)) + n_packages_to_constraints[k.pkgname] = constraints + + if not domain: + self.trace("no domain while processing constraint %r from %r %r" % (domain, pkgname, pkgver)) + return (n_packages_to_versions, n_packages_to_constraints) + + # next package on the todo list + if not todo: + return (n_packages_to_versions, n_packages_to_constraints) + + n_pkgname = todo[0] + n_pkgver = n_packages_to_versions[n_pkgname][0] + tmp = dict(n_packages_to_versions) + tmp[n_pkgname] = [n_pkgver] + + self.trace("fixed point %s" % n_pkgname) + + return self.solve(tmp, n_packages_to_constraints, n_pkgname, n_pkgver, todo[1:], done) + + def get_results(self): + return '\n'.join([str(c) for c in self.constraints]) + + def solution_to_constraints(self, versions, constraints): + solution = [] + for p in versions: + c = constraint() + solution.append(c) + + c.pkgname = p + if versions[p]: + c.required_version = versions[p][0] + else: + c.required_version = '' + for (from_pkgname, from_pkgver, c2) in constraints.get(p, ''): + c.add_reason(c2.human_display(from_pkgname, from_pkgver)) + return solution + + def local_resolve(self, text): + self.cache_constraints[(self.myproject, self.myversion)] = parse_constraints(text) + p2v = OrderedDict({self.myproject: [self.myversion]}) + (versions, constraints) = self.solve(p2v, {}, self.myproject, self.myversion, []) + return self.solution_to_constraints(versions, constraints) + + def download_to_file(self, pkgname, pkgver, subdir, tmp): + data = safe_urlencode([('pkgname', pkgname), ('pkgver', pkgver), ('pkgfile', subdir)]) + req = urlopen(get_download_url(), data, timeout=TIMEOUT) + with open(tmp, 'wb') as f: + while True: + buf = req.read(8192) + if not buf: + break + f.write(buf) + + def extract_tar(self, subdir, pkgdir, tmpfile): + with tarfile.open(tmpfile) as f: + temp = tempfile.mkdtemp(dir=pkgdir) + try: + f.extractall(temp) + os.rename(temp, os.path.join(pkgdir, subdir)) + finally: + try: + shutil.rmtree(temp) + except Exception: + pass + + def get_pkg_dir(self, pkgname, pkgver, subdir): + pkgdir = os.path.join(get_distnet_cache(), pkgname, pkgver) + if not os.path.isdir(pkgdir): + os.makedirs(pkgdir) + + target = os.path.join(pkgdir, subdir) + + if os.path.exists(target): + return target + + (fd, tmp) = tempfile.mkstemp(dir=pkgdir) + try: + os.close(fd) + self.download_to_file(pkgname, pkgver, subdir, tmp) + if subdir == REQUIRES: + os.rename(tmp, target) + else: + self.extract_tar(subdir, pkgdir, tmp) + finally: + try: + os.remove(tmp) + except OSError: + pass + + return target + + def __iter__(self): + if not self.constraints: + self.compute_dependencies() + for x in self.constraints: + if x.pkgname == self.myproject: + continue + yield x + + def execute(self): + self.compute_dependencies() + +packages = package_reader() + +def load_tools(ctx, extra): + global packages + for c in packages: + packages.get_pkg_dir(c.pkgname, c.required_version, extra) + noarchdir = packages.get_pkg_dir(c.pkgname, c.required_version, 'noarch') + for x in os.listdir(noarchdir): + if x.startswith('waf_') and x.endswith('.py'): + ctx.load([x.rstrip('.py')], tooldir=[noarchdir]) + +def options(opt): + opt.add_option('--offline', action='store_true') + packages.execute() + load_tools(opt, REQUIRES) + +def configure(conf): + load_tools(conf, conf.variant) + +def build(bld): + load_tools(bld, bld.variant) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/doxygen.py b/ldb-2.0.8/third_party/waf/waflib/extras/doxygen.py new file mode 100644 index 0000000..20cd9e1 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/doxygen.py @@ -0,0 +1,235 @@ +#! /usr/bin/env python +# encoding: UTF-8 +# Thomas Nagy 2008-2010 (ita) + +""" + +Doxygen support + +Variables passed to bld(): +* doxyfile -- the Doxyfile to use +* doxy_tar -- destination archive for generated documentation (if desired) +* install_path -- where to install the documentation +* pars -- dictionary overriding doxygen configuration settings + +When using this tool, the wscript will look like: + + def options(opt): + opt.load('doxygen') + + def configure(conf): + conf.load('doxygen') + # check conf.env.DOXYGEN, if it is mandatory + + def build(bld): + if bld.env.DOXYGEN: + bld(features="doxygen", doxyfile='Doxyfile', ...) +""" + +import os, os.path, re +from collections import OrderedDict +from waflib import Task, Utils, Node +from waflib.TaskGen import feature + +DOXY_STR = '"${DOXYGEN}" - ' +DOXY_FMTS = 'html latex man rft xml'.split() +DOXY_FILE_PATTERNS = '*.' + ' *.'.join(''' +c cc cxx cpp c++ java ii ixx ipp i++ inl h hh hxx hpp h++ idl odl cs php php3 +inc m mm py f90c cc cxx cpp c++ java ii ixx ipp i++ inl h hh hxx +'''.split()) + +re_rl = re.compile('\\\\\r*\n', re.MULTILINE) +re_nl = re.compile('\r*\n', re.M) +def parse_doxy(txt): + ''' + Parses a doxygen file. + Returns an ordered dictionary. We cannot return a default dictionary, as the + order in which the entries are reported does matter, especially for the + '@INCLUDE' lines. + ''' + tbl = OrderedDict() + txt = re_rl.sub('', txt) + lines = re_nl.split(txt) + for x in lines: + x = x.strip() + if not x or x.startswith('#') or x.find('=') < 0: + continue + if x.find('+=') >= 0: + tmp = x.split('+=') + key = tmp[0].strip() + if key in tbl: + tbl[key] += ' ' + '+='.join(tmp[1:]).strip() + else: + tbl[key] = '+='.join(tmp[1:]).strip() + else: + tmp = x.split('=') + tbl[tmp[0].strip()] = '='.join(tmp[1:]).strip() + return tbl + +class doxygen(Task.Task): + vars = ['DOXYGEN', 'DOXYFLAGS'] + color = 'BLUE' + + def runnable_status(self): + ''' + self.pars are populated in runnable_status - because this function is being + run *before* both self.pars "consumers" - scan() and run() + + set output_dir (node) for the output + ''' + + for x in self.run_after: + if not x.hasrun: + return Task.ASK_LATER + + if not getattr(self, 'pars', None): + txt = self.inputs[0].read() + self.pars = parse_doxy(txt) + + # Override with any parameters passed to the task generator + if getattr(self.generator, 'pars', None): + for k, v in self.generator.pars.items(): + self.pars[k] = v + + if self.pars.get('OUTPUT_DIRECTORY'): + # Use the path parsed from the Doxyfile as an absolute path + output_node = self.inputs[0].parent.get_bld().make_node(self.pars['OUTPUT_DIRECTORY']) + else: + # If no OUTPUT_PATH was specified in the Doxyfile, build path from the Doxyfile name + '.doxy' + output_node = self.inputs[0].parent.get_bld().make_node(self.inputs[0].name + '.doxy') + output_node.mkdir() + self.pars['OUTPUT_DIRECTORY'] = output_node.abspath() + + self.doxy_inputs = getattr(self, 'doxy_inputs', []) + if not self.pars.get('INPUT'): + self.doxy_inputs.append(self.inputs[0].parent) + else: + for i in self.pars.get('INPUT').split(): + if os.path.isabs(i): + node = self.generator.bld.root.find_node(i) + else: + node = self.inputs[0].parent.find_node(i) + if not node: + self.generator.bld.fatal('Could not find the doxygen input %r' % i) + self.doxy_inputs.append(node) + + if not getattr(self, 'output_dir', None): + bld = self.generator.bld + # Output path is always an absolute path as it was transformed above. + self.output_dir = bld.root.find_dir(self.pars['OUTPUT_DIRECTORY']) + + self.signature() + ret = Task.Task.runnable_status(self) + if ret == Task.SKIP_ME: + # in case the files were removed + self.add_install() + return ret + + def scan(self): + exclude_patterns = self.pars.get('EXCLUDE_PATTERNS','').split() + exclude_patterns = [pattern.replace('*/', '**/') for pattern in exclude_patterns] + file_patterns = self.pars.get('FILE_PATTERNS','').split() + if not file_patterns: + file_patterns = DOXY_FILE_PATTERNS.split() + if self.pars.get('RECURSIVE') == 'YES': + file_patterns = ["**/%s" % pattern for pattern in file_patterns] + nodes = [] + names = [] + for node in self.doxy_inputs: + if os.path.isdir(node.abspath()): + for m in node.ant_glob(incl=file_patterns, excl=exclude_patterns): + nodes.append(m) + else: + nodes.append(node) + return (nodes, names) + + def run(self): + dct = self.pars.copy() + code = '\n'.join(['%s = %s' % (x, dct[x]) for x in self.pars]) + code = code.encode() # for python 3 + #fmt = DOXY_STR % (self.inputs[0].parent.abspath()) + cmd = Utils.subst_vars(DOXY_STR, self.env) + env = self.env.env or None + proc = Utils.subprocess.Popen(cmd, shell=True, stdin=Utils.subprocess.PIPE, env=env, cwd=self.inputs[0].parent.abspath()) + proc.communicate(code) + return proc.returncode + + def post_run(self): + nodes = self.output_dir.ant_glob('**/*', quiet=True) + for x in nodes: + self.generator.bld.node_sigs[x] = self.uid() + self.add_install() + return Task.Task.post_run(self) + + def add_install(self): + nodes = self.output_dir.ant_glob('**/*', quiet=True) + self.outputs += nodes + if getattr(self.generator, 'install_path', None): + if not getattr(self.generator, 'doxy_tar', None): + self.generator.add_install_files(install_to=self.generator.install_path, + install_from=self.outputs, + postpone=False, + cwd=self.output_dir, + relative_trick=True) + +class tar(Task.Task): + "quick tar creation" + run_str = '${TAR} ${TAROPTS} ${TGT} ${SRC}' + color = 'RED' + after = ['doxygen'] + def runnable_status(self): + for x in getattr(self, 'input_tasks', []): + if not x.hasrun: + return Task.ASK_LATER + + if not getattr(self, 'tar_done_adding', None): + # execute this only once + self.tar_done_adding = True + for x in getattr(self, 'input_tasks', []): + self.set_inputs(x.outputs) + if not self.inputs: + return Task.SKIP_ME + return Task.Task.runnable_status(self) + + def __str__(self): + tgt_str = ' '.join([a.path_from(a.ctx.launch_node()) for a in self.outputs]) + return '%s: %s\n' % (self.__class__.__name__, tgt_str) + +@feature('doxygen') +def process_doxy(self): + if not getattr(self, 'doxyfile', None): + self.bld.fatal('no doxyfile variable specified??') + + node = self.doxyfile + if not isinstance(node, Node.Node): + node = self.path.find_resource(node) + if not node: + self.bld.fatal('doxygen file %s not found' % self.doxyfile) + + # the task instance + dsk = self.create_task('doxygen', node) + + if getattr(self, 'doxy_tar', None): + tsk = self.create_task('tar') + tsk.input_tasks = [dsk] + tsk.set_outputs(self.path.find_or_declare(self.doxy_tar)) + if self.doxy_tar.endswith('bz2'): + tsk.env['TAROPTS'] = ['cjf'] + elif self.doxy_tar.endswith('gz'): + tsk.env['TAROPTS'] = ['czf'] + else: + tsk.env['TAROPTS'] = ['cf'] + if getattr(self, 'install_path', None): + self.add_install_files(install_to=self.install_path, install_from=tsk.outputs) + +def configure(conf): + ''' + Check if doxygen and tar commands are present in the system + + If the commands are present, then conf.env.DOXYGEN and conf.env.TAR + variables will be set. Detection can be controlled by setting DOXYGEN and + TAR environmental variables. + ''' + + conf.find_program('doxygen', var='DOXYGEN', mandatory=False) + conf.find_program('tar', var='TAR', mandatory=False) diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/dpapi.py b/ldb-2.0.8/third_party/waf/waflib/extras/dpapi.py new file mode 100644 index 0000000..b94d482 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/dpapi.py @@ -0,0 +1,87 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Matt Clarkson, 2012 + +''' +DPAPI access library (http://msdn.microsoft.com/en-us/library/ms995355.aspx) +This file uses code originally created by Crusher Joe: +http://article.gmane.org/gmane.comp.python.ctypes/420 +And modified by Wayne Koorts: +http://stackoverflow.com/questions/463832/using-dpapi-with-python +''' + +from ctypes import windll, byref, cdll, Structure, POINTER, c_char, c_buffer +from ctypes.wintypes import DWORD +from waflib.Configure import conf + +LocalFree = windll.kernel32.LocalFree +memcpy = cdll.msvcrt.memcpy +CryptProtectData = windll.crypt32.CryptProtectData +CryptUnprotectData = windll.crypt32.CryptUnprotectData +CRYPTPROTECT_UI_FORBIDDEN = 0x01 +try: + extra_entropy = 'cl;ad13 \0al;323kjd #(adl;k$#ajsd'.encode('ascii') +except AttributeError: + extra_entropy = 'cl;ad13 \0al;323kjd #(adl;k$#ajsd' + +class DATA_BLOB(Structure): + _fields_ = [ + ('cbData', DWORD), + ('pbData', POINTER(c_char)) + ] + +def get_data(blob_out): + cbData = int(blob_out.cbData) + pbData = blob_out.pbData + buffer = c_buffer(cbData) + memcpy(buffer, pbData, cbData) + LocalFree(pbData) + return buffer.raw + +@conf +def dpapi_encrypt_data(self, input_bytes, entropy = extra_entropy): + ''' + Encrypts data and returns byte string + + :param input_bytes: The data to be encrypted + :type input_bytes: String or Bytes + :param entropy: Extra entropy to add to the encryption process (optional) + :type entropy: String or Bytes + ''' + if not isinstance(input_bytes, bytes) or not isinstance(entropy, bytes): + self.fatal('The inputs to dpapi must be bytes') + buffer_in = c_buffer(input_bytes, len(input_bytes)) + buffer_entropy = c_buffer(entropy, len(entropy)) + blob_in = DATA_BLOB(len(input_bytes), buffer_in) + blob_entropy = DATA_BLOB(len(entropy), buffer_entropy) + blob_out = DATA_BLOB() + + if CryptProtectData(byref(blob_in), 'python_data', byref(blob_entropy), + None, None, CRYPTPROTECT_UI_FORBIDDEN, byref(blob_out)): + return get_data(blob_out) + else: + self.fatal('Failed to decrypt data') + +@conf +def dpapi_decrypt_data(self, encrypted_bytes, entropy = extra_entropy): + ''' + Decrypts data and returns byte string + + :param encrypted_bytes: The encrypted data + :type encrypted_bytes: Bytes + :param entropy: Extra entropy to add to the encryption process (optional) + :type entropy: String or Bytes + ''' + if not isinstance(encrypted_bytes, bytes) or not isinstance(entropy, bytes): + self.fatal('The inputs to dpapi must be bytes') + buffer_in = c_buffer(encrypted_bytes, len(encrypted_bytes)) + buffer_entropy = c_buffer(entropy, len(entropy)) + blob_in = DATA_BLOB(len(encrypted_bytes), buffer_in) + blob_entropy = DATA_BLOB(len(entropy), buffer_entropy) + blob_out = DATA_BLOB() + if CryptUnprotectData(byref(blob_in), None, byref(blob_entropy), None, + None, CRYPTPROTECT_UI_FORBIDDEN, byref(blob_out)): + return get_data(blob_out) + else: + self.fatal('Failed to decrypt data') + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/eclipse.py b/ldb-2.0.8/third_party/waf/waflib/extras/eclipse.py new file mode 100644 index 0000000..bb78741 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/eclipse.py @@ -0,0 +1,431 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Eclipse CDT 5.0 generator for Waf +# Richard Quirk 2009-1011 (New BSD License) +# Thomas Nagy 2011 (ported to Waf 1.6) + +""" +Usage: + +def options(opt): + opt.load('eclipse') + +$ waf configure eclipse +""" + +import sys, os +from waflib import Utils, Logs, Context, Build, TaskGen, Scripting, Errors, Node +from xml.dom.minidom import Document + +STANDARD_INCLUDES = [ '/usr/local/include', '/usr/include' ] + +oe_cdt = 'org.eclipse.cdt' +cdt_mk = oe_cdt + '.make.core' +cdt_core = oe_cdt + '.core' +cdt_bld = oe_cdt + '.build.core' +extbuilder_dir = '.externalToolBuilders' +extbuilder_name = 'Waf_Builder.launch' + +class eclipse(Build.BuildContext): + cmd = 'eclipse' + fun = Scripting.default_cmd + + def execute(self): + """ + Entry point + """ + self.restore() + if not self.all_envs: + self.load_envs() + self.recurse([self.run_dir]) + + appname = getattr(Context.g_module, Context.APPNAME, os.path.basename(self.srcnode.abspath())) + self.create_cproject(appname, pythonpath=self.env['ECLIPSE_PYTHON_PATH']) + + # Helper to dump the XML document content to XML with UTF-8 encoding + def write_conf_to_xml(self, filename, document): + self.srcnode.make_node(filename).write(document.toprettyxml(encoding='UTF-8'), flags='wb') + + def create_cproject(self, appname, workspace_includes=[], pythonpath=[]): + """ + Create the Eclipse CDT .project and .cproject files + @param appname The name that will appear in the Project Explorer + @param build The BuildContext object to extract includes from + @param workspace_includes Optional project includes to prevent + "Unresolved Inclusion" errors in the Eclipse editor + @param pythonpath Optional project specific python paths + """ + hasc = hasjava = haspython = False + source_dirs = [] + cpppath = self.env['CPPPATH'] + javasrcpath = [] + javalibpath = [] + includes = STANDARD_INCLUDES + if sys.platform != 'win32': + cc = self.env.CC or self.env.CXX + if cc: + cmd = cc + ['-xc++', '-E', '-Wp,-v', '-'] + try: + gccout = self.cmd_and_log(cmd, output=Context.STDERR, quiet=Context.BOTH, input='\n'.encode()).splitlines() + except Errors.WafError: + pass + else: + includes = [] + for ipath in gccout: + if ipath.startswith(' /'): + includes.append(ipath[1:]) + cpppath += includes + Logs.warn('Generating Eclipse CDT project files') + + for g in self.groups: + for tg in g: + if not isinstance(tg, TaskGen.task_gen): + continue + + tg.post() + + # Add local Python modules paths to configuration so object resolving will work in IDE + # This may also contain generated files (ie. pyqt5 or protoc) that get picked from build + if 'py' in tg.features: + pypath = tg.path.relpath() + py_installfrom = getattr(tg, 'install_from', None) + if isinstance(py_installfrom, Node.Node): + pypath = py_installfrom.path_from(self.root.make_node(self.top_dir)) + if pypath not in pythonpath: + pythonpath.append(pypath) + haspython = True + + # Add Java source directories so object resolving works in IDE + # This may also contain generated files (ie. protoc) that get picked from build + if 'javac' in tg.features: + java_src = tg.path.relpath() + java_srcdir = getattr(tg.javac_task, 'srcdir', None) + if java_srcdir: + if isinstance(java_srcdir, Node.Node): + java_srcdir = [java_srcdir] + for x in Utils.to_list(java_srcdir): + x = x.path_from(self.root.make_node(self.top_dir)) + if x not in javasrcpath: + javasrcpath.append(x) + else: + if java_src not in javasrcpath: + javasrcpath.append(java_src) + hasjava = True + + # Check if there are external dependencies and add them as external jar so they will be resolved by Eclipse + usedlibs=getattr(tg, 'use', []) + for x in Utils.to_list(usedlibs): + for cl in Utils.to_list(tg.env['CLASSPATH_'+x]): + if cl not in javalibpath: + javalibpath.append(cl) + + if not getattr(tg, 'link_task', None): + continue + + features = Utils.to_list(getattr(tg, 'features', '')) + + is_cc = 'c' in features or 'cxx' in features + + incnodes = tg.to_incnodes(tg.to_list(getattr(tg, 'includes', [])) + tg.env['INCLUDES']) + for p in incnodes: + path = p.path_from(self.srcnode) + + if (path.startswith("/")): + cpppath.append(path) + else: + workspace_includes.append(path) + + if is_cc and path not in source_dirs: + source_dirs.append(path) + + hasc = True + + waf_executable = os.path.abspath(sys.argv[0]) + project = self.impl_create_project(sys.executable, appname, hasc, hasjava, haspython, waf_executable) + self.write_conf_to_xml('.project', project) + + if hasc: + project = self.impl_create_cproject(sys.executable, waf_executable, appname, workspace_includes, cpppath, source_dirs) + self.write_conf_to_xml('.cproject', project) + + if haspython: + project = self.impl_create_pydevproject(sys.path, pythonpath) + self.write_conf_to_xml('.pydevproject', project) + + if hasjava: + project = self.impl_create_javaproject(javasrcpath, javalibpath) + self.write_conf_to_xml('.classpath', project) + + def impl_create_project(self, executable, appname, hasc, hasjava, haspython, waf_executable): + doc = Document() + projectDescription = doc.createElement('projectDescription') + self.add(doc, projectDescription, 'name', appname) + self.add(doc, projectDescription, 'comment') + self.add(doc, projectDescription, 'projects') + buildSpec = self.add(doc, projectDescription, 'buildSpec') + buildCommand = self.add(doc, buildSpec, 'buildCommand') + self.add(doc, buildCommand, 'triggers', 'clean,full,incremental,') + arguments = self.add(doc, buildCommand, 'arguments') + dictionaries = {} + + # If CDT is present, instruct this one to call waf as it is more flexible (separate build/clean ...) + if hasc: + self.add(doc, buildCommand, 'name', oe_cdt + '.managedbuilder.core.genmakebuilder') + # the default make-style targets are overwritten by the .cproject values + dictionaries = { + cdt_mk + '.contents': cdt_mk + '.activeConfigSettings', + cdt_mk + '.enableAutoBuild': 'false', + cdt_mk + '.enableCleanBuild': 'true', + cdt_mk + '.enableFullBuild': 'true', + } + else: + # Otherwise for Java/Python an external builder tool is created that will call waf build + self.add(doc, buildCommand, 'name', 'org.eclipse.ui.externaltools.ExternalToolBuilder') + dictionaries = { + 'LaunchConfigHandle': '/%s/%s'%(extbuilder_dir, extbuilder_name), + } + # The definition is in a separate directory XML file + try: + os.mkdir(extbuilder_dir) + except OSError: + pass # Ignore error if already exists + + # Populate here the external builder XML calling waf + builder = Document() + launchConfiguration = doc.createElement('launchConfiguration') + launchConfiguration.setAttribute('type', 'org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType') + self.add(doc, launchConfiguration, 'booleanAttribute', {'key': 'org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND', 'value': 'false'}) + self.add(doc, launchConfiguration, 'booleanAttribute', {'key': 'org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED', 'value': 'true'}) + self.add(doc, launchConfiguration, 'stringAttribute', {'key': 'org.eclipse.ui.externaltools.ATTR_LOCATION', 'value': waf_executable}) + self.add(doc, launchConfiguration, 'stringAttribute', {'key': 'org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS', 'value': 'full,incremental,'}) + self.add(doc, launchConfiguration, 'stringAttribute', {'key': 'org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS', 'value': 'build'}) + self.add(doc, launchConfiguration, 'stringAttribute', {'key': 'org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY', 'value': '${project_loc}'}) + builder.appendChild(launchConfiguration) + # And write the XML to the file references before + self.write_conf_to_xml('%s%s%s'%(extbuilder_dir, os.path.sep, extbuilder_name), builder) + + + for k, v in dictionaries.items(): + self.addDictionary(doc, arguments, k, v) + + natures = self.add(doc, projectDescription, 'natures') + + if hasc: + nature_list = """ + core.ccnature + managedbuilder.core.ScannerConfigNature + managedbuilder.core.managedBuildNature + core.cnature + """.split() + for n in nature_list: + self.add(doc, natures, 'nature', oe_cdt + '.' + n) + + if haspython: + self.add(doc, natures, 'nature', 'org.python.pydev.pythonNature') + if hasjava: + self.add(doc, natures, 'nature', 'org.eclipse.jdt.core.javanature') + + doc.appendChild(projectDescription) + return doc + + def impl_create_cproject(self, executable, waf_executable, appname, workspace_includes, cpppath, source_dirs=[]): + doc = Document() + doc.appendChild(doc.createProcessingInstruction('fileVersion', '4.0.0')) + cconf_id = cdt_core + '.default.config.1' + cproject = doc.createElement('cproject') + storageModule = self.add(doc, cproject, 'storageModule', + {'moduleId': cdt_core + '.settings'}) + cconf = self.add(doc, storageModule, 'cconfiguration', {'id':cconf_id}) + + storageModule = self.add(doc, cconf, 'storageModule', + {'buildSystemId': oe_cdt + '.managedbuilder.core.configurationDataProvider', + 'id': cconf_id, + 'moduleId': cdt_core + '.settings', + 'name': 'Default'}) + + self.add(doc, storageModule, 'externalSettings') + + extensions = self.add(doc, storageModule, 'extensions') + extension_list = """ + VCErrorParser + MakeErrorParser + GCCErrorParser + GASErrorParser + GLDErrorParser + """.split() + self.add(doc, extensions, 'extension', {'id': cdt_core + '.ELF', 'point':cdt_core + '.BinaryParser'}) + for e in extension_list: + self.add(doc, extensions, 'extension', {'id': cdt_core + '.' + e, 'point':cdt_core + '.ErrorParser'}) + + storageModule = self.add(doc, cconf, 'storageModule', + {'moduleId': 'cdtBuildSystem', 'version': '4.0.0'}) + config = self.add(doc, storageModule, 'configuration', + {'artifactName': appname, + 'id': cconf_id, + 'name': 'Default', + 'parent': cdt_bld + '.prefbase.cfg'}) + folderInfo = self.add(doc, config, 'folderInfo', + {'id': cconf_id+'.', 'name': '/', 'resourcePath': ''}) + + toolChain = self.add(doc, folderInfo, 'toolChain', + {'id': cdt_bld + '.prefbase.toolchain.1', + 'name': 'No ToolChain', + 'resourceTypeBasedDiscovery': 'false', + 'superClass': cdt_bld + '.prefbase.toolchain'}) + + self.add(doc, toolChain, 'targetPlatform', {'binaryParser': 'org.eclipse.cdt.core.ELF', 'id': cdt_bld + '.prefbase.toolchain.1', 'name': ''}) + + waf_build = '"%s" %s'%(waf_executable, eclipse.fun) + waf_clean = '"%s" clean'%(waf_executable) + self.add(doc, toolChain, 'builder', + {'autoBuildTarget': waf_build, + 'command': executable, + 'enableAutoBuild': 'false', + 'cleanBuildTarget': waf_clean, + 'enableIncrementalBuild': 'true', + 'id': cdt_bld + '.settings.default.builder.1', + 'incrementalBuildTarget': waf_build, + 'managedBuildOn': 'false', + 'name': 'Gnu Make Builder', + 'superClass': cdt_bld + '.settings.default.builder'}) + + tool_index = 1; + for tool_name in ("Assembly", "GNU C++", "GNU C"): + tool = self.add(doc, toolChain, 'tool', + {'id': cdt_bld + '.settings.holder.' + str(tool_index), + 'name': tool_name, + 'superClass': cdt_bld + '.settings.holder'}) + if cpppath or workspace_includes: + incpaths = cdt_bld + '.settings.holder.incpaths' + option = self.add(doc, tool, 'option', + {'id': incpaths + '.' + str(tool_index), + 'name': 'Include Paths', + 'superClass': incpaths, + 'valueType': 'includePath'}) + for i in workspace_includes: + self.add(doc, option, 'listOptionValue', + {'builtIn': 'false', + 'value': '"${workspace_loc:/%s/%s}"'%(appname, i)}) + for i in cpppath: + self.add(doc, option, 'listOptionValue', + {'builtIn': 'false', + 'value': '"%s"'%(i)}) + if tool_name == "GNU C++" or tool_name == "GNU C": + self.add(doc,tool,'inputType',{ 'id':'org.eclipse.cdt.build.core.settings.holder.inType.' + str(tool_index), \ + 'languageId':'org.eclipse.cdt.core.gcc' if tool_name == "GNU C" else 'org.eclipse.cdt.core.g++','languageName':tool_name, \ + 'sourceContentType':'org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader', \ + 'superClass':'org.eclipse.cdt.build.core.settings.holder.inType' }) + tool_index += 1 + + if source_dirs: + sourceEntries = self.add(doc, config, 'sourceEntries') + for i in source_dirs: + self.add(doc, sourceEntries, 'entry', + {'excluding': i, + 'flags': 'VALUE_WORKSPACE_PATH|RESOLVED', + 'kind': 'sourcePath', + 'name': ''}) + self.add(doc, sourceEntries, 'entry', + { + 'flags': 'VALUE_WORKSPACE_PATH|RESOLVED', + 'kind': 'sourcePath', + 'name': i}) + + storageModule = self.add(doc, cconf, 'storageModule', + {'moduleId': cdt_mk + '.buildtargets'}) + buildTargets = self.add(doc, storageModule, 'buildTargets') + def addTargetWrap(name, runAll): + return self.addTarget(doc, buildTargets, executable, name, + '"%s" %s'%(waf_executable, name), runAll) + addTargetWrap('configure', True) + addTargetWrap('dist', False) + addTargetWrap('install', False) + addTargetWrap('check', False) + + storageModule = self.add(doc, cproject, 'storageModule', + {'moduleId': 'cdtBuildSystem', + 'version': '4.0.0'}) + + self.add(doc, storageModule, 'project', {'id': '%s.null.1'%appname, 'name': appname}) + + doc.appendChild(cproject) + return doc + + def impl_create_pydevproject(self, system_path, user_path): + # create a pydevproject file + doc = Document() + doc.appendChild(doc.createProcessingInstruction('eclipse-pydev', 'version="1.0"')) + pydevproject = doc.createElement('pydev_project') + prop = self.add(doc, pydevproject, + 'pydev_property', + 'python %d.%d'%(sys.version_info[0], sys.version_info[1])) + prop.setAttribute('name', 'org.python.pydev.PYTHON_PROJECT_VERSION') + prop = self.add(doc, pydevproject, 'pydev_property', 'Default') + prop.setAttribute('name', 'org.python.pydev.PYTHON_PROJECT_INTERPRETER') + # add waf's paths + wafadmin = [p for p in system_path if p.find('wafadmin') != -1] + if wafadmin: + prop = self.add(doc, pydevproject, 'pydev_pathproperty', + {'name':'org.python.pydev.PROJECT_EXTERNAL_SOURCE_PATH'}) + for i in wafadmin: + self.add(doc, prop, 'path', i) + if user_path: + prop = self.add(doc, pydevproject, 'pydev_pathproperty', + {'name':'org.python.pydev.PROJECT_SOURCE_PATH'}) + for i in user_path: + self.add(doc, prop, 'path', '/${PROJECT_DIR_NAME}/'+i) + + doc.appendChild(pydevproject) + return doc + + def impl_create_javaproject(self, javasrcpath, javalibpath): + # create a .classpath file for java usage + doc = Document() + javaproject = doc.createElement('classpath') + if javasrcpath: + for i in javasrcpath: + self.add(doc, javaproject, 'classpathentry', + {'kind': 'src', 'path': i}) + + if javalibpath: + for i in javalibpath: + self.add(doc, javaproject, 'classpathentry', + {'kind': 'lib', 'path': i}) + + self.add(doc, javaproject, 'classpathentry', {'kind': 'con', 'path': 'org.eclipse.jdt.launching.JRE_CONTAINER'}) + self.add(doc, javaproject, 'classpathentry', {'kind': 'output', 'path': self.bldnode.name }) + doc.appendChild(javaproject) + return doc + + def addDictionary(self, doc, parent, k, v): + dictionary = self.add(doc, parent, 'dictionary') + self.add(doc, dictionary, 'key', k) + self.add(doc, dictionary, 'value', v) + return dictionary + + def addTarget(self, doc, buildTargets, executable, name, buildTarget, runAllBuilders=True): + target = self.add(doc, buildTargets, 'target', + {'name': name, + 'path': '', + 'targetID': oe_cdt + '.build.MakeTargetBuilder'}) + self.add(doc, target, 'buildCommand', executable) + self.add(doc, target, 'buildArguments', None) + self.add(doc, target, 'buildTarget', buildTarget) + self.add(doc, target, 'stopOnError', 'true') + self.add(doc, target, 'useDefaultCommand', 'false') + self.add(doc, target, 'runAllBuilders', str(runAllBuilders).lower()) + + def add(self, doc, parent, tag, value = None): + el = doc.createElement(tag) + if (value): + if type(value) == type(str()): + el.appendChild(doc.createTextNode(value)) + elif type(value) == type(dict()): + self.setAttributes(el, value) + parent.appendChild(el) + return el + + def setAttributes(self, node, attrs): + for k, v in attrs.items(): + node.setAttribute(k, v) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/erlang.py b/ldb-2.0.8/third_party/waf/waflib/extras/erlang.py new file mode 100644 index 0000000..0b93d9a --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/erlang.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2010 (ita) +# Przemyslaw Rzepecki, 2016 + +""" +Erlang support +""" + +import re +from waflib import Task, TaskGen +from waflib.TaskGen import feature, after_method, before_method +# to load the method "to_incnodes" below +from waflib.Tools import ccroot + +# Those flags are required by the Erlang VM to execute/evaluate code in +# non-interactive mode. It is used in this tool to create Erlang modules +# documentation and run unit tests. The user can pass additional arguments to the +# 'erl' command with ERL_FLAGS environment variable. +EXEC_NON_INTERACTIVE = ['-noshell', '-noinput', '-eval'] + +def configure(conf): + conf.find_program('erlc', var='ERLC') + conf.find_program('erl', var='ERL') + conf.add_os_flags('ERLC_FLAGS') + conf.add_os_flags('ERL_FLAGS') + conf.env.ERLC_DEF_PATTERN = '-D%s' + conf.env.ERLC_INC_PATTERN = '-I%s' + +@TaskGen.extension('.erl') +def process_erl_node(self, node): + tsk = self.create_task('erl', node, node.change_ext('.beam')) + tsk.erlc_incnodes = [tsk.outputs[0].parent] + self.to_incnodes(self.includes) + tsk.env.append_value('ERLC_INCPATHS', [x.abspath() for x in tsk.erlc_incnodes]) + tsk.env.append_value('ERLC_DEFINES', self.to_list(getattr(self, 'defines', []))) + tsk.env.append_value('ERLC_FLAGS', self.to_list(getattr(self, 'flags', []))) + tsk.cwd = tsk.outputs[0].parent + +class erl(Task.Task): + color = 'GREEN' + run_str = '${ERLC} ${ERL_FLAGS} ${ERLC_INC_PATTERN:ERLC_INCPATHS} ${ERLC_DEF_PATTERN:ERLC_DEFINES} ${SRC}' + + def scan(task): + node = task.inputs[0] + + deps = [] + scanned = set([]) + nodes_to_scan = [node] + + for n in nodes_to_scan: + if n.abspath() in scanned: + continue + + for i in re.findall(r'-include\("(.*)"\)\.', n.read()): + for d in task.erlc_incnodes: + r = d.find_node(i) + if r: + deps.append(r) + nodes_to_scan.append(r) + break + scanned.add(n.abspath()) + + return (deps, []) + +@TaskGen.extension('.beam') +def process(self, node): + pass + + +class erl_test(Task.Task): + color = 'BLUE' + run_str = '${ERL} ${ERL_FLAGS} ${ERL_TEST_FLAGS}' + +@feature('eunit') +@after_method('process_source') +def add_erl_test_run(self): + test_modules = [t.outputs[0] for t in self.tasks] + test_task = self.create_task('erl_test') + test_task.set_inputs(self.source + test_modules) + test_task.cwd = test_modules[0].parent + + test_task.env.append_value('ERL_FLAGS', self.to_list(getattr(self, 'flags', []))) + + test_list = ", ".join([m.change_ext("").path_from(test_task.cwd)+":test()" for m in test_modules]) + test_flag = 'halt(case lists:all(fun(Elem) -> Elem == ok end, [%s]) of true -> 0; false -> 1 end).' % test_list + test_task.env.append_value('ERL_TEST_FLAGS', EXEC_NON_INTERACTIVE) + test_task.env.append_value('ERL_TEST_FLAGS', test_flag) + + +class edoc(Task.Task): + color = 'BLUE' + run_str = "${ERL} ${ERL_FLAGS} ${ERL_DOC_FLAGS}" + def keyword(self): + return 'Generating edoc' + +@feature('edoc') +@before_method('process_source') +def add_edoc_task(self): + # do not process source, it would create double erl->beam task + self.meths.remove('process_source') + e = self.path.find_resource(self.source) + t = e.change_ext('.html') + png = t.parent.make_node('erlang.png') + css = t.parent.make_node('stylesheet.css') + tsk = self.create_task('edoc', e, [t, png, css]) + tsk.cwd = tsk.outputs[0].parent + tsk.env.append_value('ERL_DOC_FLAGS', EXEC_NON_INTERACTIVE) + tsk.env.append_value('ERL_DOC_FLAGS', 'edoc:files(["%s"]), halt(0).' % tsk.inputs[0].abspath()) + # TODO the above can break if a file path contains '"' + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fast_partial.py b/ldb-2.0.8/third_party/waf/waflib/extras/fast_partial.py new file mode 100644 index 0000000..90a9472 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/fast_partial.py @@ -0,0 +1,531 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2017-2018 (ita) + +""" +A system for fast partial rebuilds + +Creating a large amount of task objects up front can take some time. +By making a few assumptions, it is possible to avoid posting creating +task objects for targets that are already up-to-date. + +On a silly benchmark the gain observed for 1M tasks can be 5m->10s +for a single file change. + +Usage:: + + def options(opt): + opt.load('fast_partial') + +Assumptions: +* Start with a clean build (run "waf distclean" after enabling) +* Mostly for C/C++/Fortran targets with link tasks (object-only targets are not handled) + try it in the folder generated by utils/genbench.py +* For full project builds: no --targets and no pruning from subfolders +* The installation phase is ignored +* `use=` dependencies are specified up front even across build groups +* Task generator source files are not obtained from globs + +Implementation details: +* The first layer obtains file timestamps to recalculate file hashes only + when necessary (similar to md5_tstamp); the timestamps are then stored + in a dedicated pickle file +* A second layer associates each task generator to a file set to help + detecting changes. Task generators are to create their tasks only when + the related files have been modified. A specific db file is created + to store such data (5m -> 1m10) +* A third layer binds build context proxies onto task generators, replacing + the default context. While loading data for the full build uses more memory + (4GB -> 9GB), partial builds are then much faster (1m10 -> 13s) +* A fourth layer enables a 2-level cache on file signatures to + reduce the size of the main pickle file (13s -> 10s) +""" + +import os +from waflib import Build, Context, Errors, Logs, Task, TaskGen, Utils +from waflib.TaskGen import feature, after_method, taskgen_method +import waflib.Node + +DONE = 0 +DIRTY = 1 +NEEDED = 2 + +SKIPPABLE = ['cshlib', 'cxxshlib', 'cstlib', 'cxxstlib', 'cprogram', 'cxxprogram'] + +TSTAMP_DB = '.wafpickle_tstamp_db_file' + +SAVED_ATTRS = 'root node_sigs task_sigs imp_sigs raw_deps node_deps'.split() + +class bld_proxy(object): + def __init__(self, bld): + object.__setattr__(self, 'bld', bld) + + object.__setattr__(self, 'node_class', type('Nod3', (waflib.Node.Node,), {})) + self.node_class.__module__ = 'waflib.Node' + self.node_class.ctx = self + + object.__setattr__(self, 'root', self.node_class('', None)) + for x in SAVED_ATTRS: + if x != 'root': + object.__setattr__(self, x, {}) + + self.fix_nodes() + + def __setattr__(self, name, value): + bld = object.__getattribute__(self, 'bld') + setattr(bld, name, value) + + def __delattr__(self, name): + bld = object.__getattribute__(self, 'bld') + delattr(bld, name) + + def __getattribute__(self, name): + try: + return object.__getattribute__(self, name) + except AttributeError: + bld = object.__getattribute__(self, 'bld') + return getattr(bld, name) + + def __call__(self, *k, **kw): + return self.bld(*k, **kw) + + def fix_nodes(self): + for x in ('srcnode', 'path', 'bldnode'): + node = self.root.find_dir(getattr(self.bld, x).abspath()) + object.__setattr__(self, x, node) + + def set_key(self, store_key): + object.__setattr__(self, 'store_key', store_key) + + def fix_tg_path(self, *tgs): + # changing Node objects on task generators is possible + # yet, all Node objects must belong to the same parent + for tg in tgs: + tg.path = self.root.make_node(tg.path.abspath()) + + def restore(self): + dbfn = os.path.join(self.variant_dir, Context.DBFILE + self.store_key) + Logs.debug('rev_use: reading %s', dbfn) + try: + data = Utils.readf(dbfn, 'rb') + except (EnvironmentError, EOFError): + # handle missing file/empty file + Logs.debug('rev_use: Could not load the build cache %s (missing)', dbfn) + else: + try: + waflib.Node.pickle_lock.acquire() + waflib.Node.Nod3 = self.node_class + try: + data = Build.cPickle.loads(data) + except Exception as e: + Logs.debug('rev_use: Could not pickle the build cache %s: %r', dbfn, e) + else: + for x in SAVED_ATTRS: + object.__setattr__(self, x, data.get(x, {})) + finally: + waflib.Node.pickle_lock.release() + self.fix_nodes() + + def store(self): + data = {} + for x in Build.SAVED_ATTRS: + data[x] = getattr(self, x) + db = os.path.join(self.variant_dir, Context.DBFILE + self.store_key) + + with waflib.Node.pickle_lock: + waflib.Node.Nod3 = self.node_class + try: + x = Build.cPickle.dumps(data, Build.PROTOCOL) + except Build.cPickle.PicklingError: + root = data['root'] + for node_deps in data['node_deps'].values(): + for idx, node in enumerate(node_deps): + # there may be more cross-context Node objects to fix, + # but this should be the main source + node_deps[idx] = root.find_node(node.abspath()) + x = Build.cPickle.dumps(data, Build.PROTOCOL) + + Logs.debug('rev_use: storing %s', db) + Utils.writef(db + '.tmp', x, m='wb') + try: + st = os.stat(db) + os.remove(db) + if not Utils.is_win32: + os.chown(db + '.tmp', st.st_uid, st.st_gid) + except (AttributeError, OSError): + pass + os.rename(db + '.tmp', db) + +class bld(Build.BuildContext): + def __init__(self, **kw): + super(bld, self).__init__(**kw) + self.hashes_md5_tstamp = {} + + def __call__(self, *k, **kw): + # this is one way of doing it, one could use a task generator method too + bld = kw['bld'] = bld_proxy(self) + ret = TaskGen.task_gen(*k, **kw) + self.task_gen_cache_names = {} + self.add_to_group(ret, group=kw.get('group')) + ret.bld = bld + bld.set_key(ret.path.abspath().replace(os.sep, '') + str(ret.idx)) + return ret + + def is_dirty(self): + return True + + def store_tstamps(self): + # Called after a build is finished + # For each task generator, record all files involved in task objects + # optimization: done only if there was something built + do_store = False + try: + f_deps = self.f_deps + except AttributeError: + f_deps = self.f_deps = {} + self.f_tstamps = {} + + allfiles = set() + for g in self.groups: + for tg in g: + try: + staleness = tg.staleness + except AttributeError: + staleness = DIRTY + + if staleness != DIRTY: + # DONE case: there was nothing built + # NEEDED case: the tg was brought in because of 'use' propagation + # but nothing really changed for them, there may be incomplete + # tasks (object files) and in this case it is best to let the next build + # figure out if an input/output file changed + continue + + do_cache = False + for tsk in tg.tasks: + if tsk.hasrun == Task.SUCCESS: + do_cache = True + pass + elif tsk.hasrun == Task.SKIPPED: + pass + else: + # one failed task, clear the cache for this tg + try: + del f_deps[(tg.path.abspath(), tg.idx)] + except KeyError: + pass + else: + # just store the new state because there is a change + do_store = True + + # skip the rest because there is no valid cache possible + break + else: + if not do_cache: + # all skipped, but is there anything in cache? + try: + f_deps[(tg.path.abspath(), tg.idx)] + except KeyError: + # probably cleared because a wscript file changed + # store it + do_cache = True + + if do_cache: + + # there was a rebuild, store the data structure too + tg.bld.store() + + # all tasks skipped but no cache + # or a successful task build + do_store = True + st = set() + for tsk in tg.tasks: + st.update(tsk.inputs) + st.update(self.node_deps.get(tsk.uid(), [])) + + # TODO do last/when loading the tgs? + lst = [] + for k in ('wscript', 'wscript_build'): + n = tg.path.find_node(k) + if n: + n.get_bld_sig() + lst.append(n.abspath()) + + lst.extend(sorted(x.abspath() for x in st)) + allfiles.update(lst) + f_deps[(tg.path.abspath(), tg.idx)] = lst + + for x in allfiles: + # f_tstamps has everything, while md5_tstamp can be relatively empty on partial builds + self.f_tstamps[x] = self.hashes_md5_tstamp[x][0] + + if do_store: + dbfn = os.path.join(self.variant_dir, TSTAMP_DB) + Logs.debug('rev_use: storing %s', dbfn) + dbfn_tmp = dbfn + '.tmp' + x = Build.cPickle.dumps([self.f_tstamps, f_deps], Build.PROTOCOL) + Utils.writef(dbfn_tmp, x, m='wb') + os.rename(dbfn_tmp, dbfn) + Logs.debug('rev_use: stored %s', dbfn) + + def store(self): + self.store_tstamps() + if self.producer.dirty: + Build.BuildContext.store(self) + + def compute_needed_tgs(self): + # assume the 'use' keys are not modified during the build phase + + dbfn = os.path.join(self.variant_dir, TSTAMP_DB) + Logs.debug('rev_use: Loading %s', dbfn) + try: + data = Utils.readf(dbfn, 'rb') + except (EnvironmentError, EOFError): + Logs.debug('rev_use: Could not load the build cache %s (missing)', dbfn) + self.f_deps = {} + self.f_tstamps = {} + else: + try: + self.f_tstamps, self.f_deps = Build.cPickle.loads(data) + except Exception as e: + Logs.debug('rev_use: Could not pickle the build cache %s: %r', dbfn, e) + self.f_deps = {} + self.f_tstamps = {} + else: + Logs.debug('rev_use: Loaded %s', dbfn) + + + # 1. obtain task generators that contain rebuilds + # 2. obtain the 'use' graph and its dual + stales = set() + reverse_use_map = Utils.defaultdict(list) + use_map = Utils.defaultdict(list) + + for g in self.groups: + for tg in g: + if tg.is_stale(): + stales.add(tg) + + try: + lst = tg.use = Utils.to_list(tg.use) + except AttributeError: + pass + else: + for x in lst: + try: + xtg = self.get_tgen_by_name(x) + except Errors.WafError: + pass + else: + use_map[tg].append(xtg) + reverse_use_map[xtg].append(tg) + + Logs.debug('rev_use: found %r stale tgs', len(stales)) + + # 3. dfs to post downstream tg as stale + visited = set() + def mark_down(tg): + if tg in visited: + return + visited.add(tg) + Logs.debug('rev_use: marking down %r as stale', tg.name) + tg.staleness = DIRTY + for x in reverse_use_map[tg]: + mark_down(x) + for tg in stales: + mark_down(tg) + + # 4. dfs to find ancestors tg to mark as needed + self.needed_tgs = needed_tgs = set() + def mark_needed(tg): + if tg in needed_tgs: + return + needed_tgs.add(tg) + if tg.staleness == DONE: + Logs.debug('rev_use: marking up %r as needed', tg.name) + tg.staleness = NEEDED + for x in use_map[tg]: + mark_needed(x) + for xx in visited: + mark_needed(xx) + + # so we have the whole tg trees to post in the set "needed" + # load their build trees + for tg in needed_tgs: + tg.bld.restore() + tg.bld.fix_tg_path(tg) + + # the stale ones should be fully build, while the needed ones + # may skip a few tasks, see create_compiled_task and apply_link_after below + Logs.debug('rev_use: amount of needed task gens: %r', len(needed_tgs)) + + def post_group(self): + # assumption: we can ignore the folder/subfolders cuts + def tgpost(tg): + try: + f = tg.post + except AttributeError: + pass + else: + f() + + if not self.targets or self.targets == '*': + for tg in self.groups[self.current_group]: + # this can cut quite a lot of tg objects + if tg in self.needed_tgs: + tgpost(tg) + else: + # default implementation + return Build.BuildContext.post_group() + + def get_build_iterator(self): + if not self.targets or self.targets == '*': + self.compute_needed_tgs() + return Build.BuildContext.get_build_iterator(self) + +@taskgen_method +def is_stale(self): + # assume no globs + self.staleness = DIRTY + + # 1. the case of always stale targets + if getattr(self, 'always_stale', False): + return True + + # 2. check if the db file exists + db = os.path.join(self.bld.variant_dir, Context.DBFILE) + try: + dbstat = os.stat(db).st_mtime + except OSError: + Logs.debug('rev_use: must post %r because this is a clean build') + return True + + # 3.a check if the configuration exists + cache_node = self.bld.bldnode.find_node('c4che/build.config.py') + if not cache_node: + return True + + # 3.b check if the configuration changed + if os.stat(cache_node.abspath()).st_mtime > dbstat: + Logs.debug('rev_use: must post %r because the configuration has changed', self.name) + return True + + # 3.c any tstamp data? + try: + f_deps = self.bld.f_deps + except AttributeError: + Logs.debug('rev_use: must post %r because there is no f_deps', self.name) + return True + + # 4. check if this is the first build (no cache) + try: + lst = f_deps[(self.path.abspath(), self.idx)] + except KeyError: + Logs.debug('rev_use: must post %r because there it has no cached data', self.name) + return True + + try: + cache = self.bld.cache_tstamp_rev_use + except AttributeError: + cache = self.bld.cache_tstamp_rev_use = {} + + # 5. check the timestamp of each dependency files listed is unchanged + f_tstamps = self.bld.f_tstamps + for x in lst: + try: + old_ts = f_tstamps[x] + except KeyError: + Logs.debug('rev_use: must post %r because %r is not in cache', self.name, x) + return True + + try: + try: + ts = cache[x] + except KeyError: + ts = cache[x] = os.stat(x).st_mtime + except OSError: + del f_deps[(self.path.abspath(), self.idx)] + Logs.debug('rev_use: must post %r because %r does not exist anymore', self.name, x) + return True + else: + if ts != old_ts: + Logs.debug('rev_use: must post %r because the timestamp on %r changed %r %r', self.name, x, old_ts, ts) + return True + + self.staleness = DONE + return False + +@taskgen_method +def create_compiled_task(self, name, node): + # skip the creation of object files + # assumption: object-only targets are not skippable + if self.staleness == NEEDED: + # only libraries/programs can skip object files + for x in SKIPPABLE: + if x in self.features: + return None + + out = '%s.%d.o' % (node.name, self.idx) + task = self.create_task(name, node, node.parent.find_or_declare(out)) + try: + self.compiled_tasks.append(task) + except AttributeError: + self.compiled_tasks = [task] + return task + +@feature(*SKIPPABLE) +@after_method('apply_link') +def apply_link_after(self): + # cprogram/cxxprogram might be unnecessary + if self.staleness != NEEDED: + return + for tsk in self.tasks: + tsk.hasrun = Task.SKIPPED + +def path_from(self, node): + # handle nodes of distinct types + if node.ctx is not self.ctx: + node = self.ctx.root.make_node(node.abspath()) + return self.default_path_from(node) +waflib.Node.Node.default_path_from = waflib.Node.Node.path_from +waflib.Node.Node.path_from = path_from + +def h_file(self): + # similar to md5_tstamp.py, but with 2-layer cache + # global_cache for the build context common for all task generators + # local_cache for the build context proxy (one by task generator) + # + # the global cache is not persistent + # the local cache is persistent and meant for partial builds + # + # assume all calls are made from a single thread + # + filename = self.abspath() + st = os.stat(filename) + + global_cache = self.ctx.bld.hashes_md5_tstamp + local_cache = self.ctx.hashes_md5_tstamp + + if filename in global_cache: + # value already calculated in this build + cval = global_cache[filename] + + # the value in global cache is assumed to be calculated once + # reverifying it could cause task generators + # to get distinct tstamp values, thus missing rebuilds + local_cache[filename] = cval + return cval[1] + + if filename in local_cache: + cval = local_cache[filename] + if cval[0] == st.st_mtime: + # correct value from a previous build + # put it in the global cache + global_cache[filename] = cval + return cval[1] + + ret = Utils.h_file(filename) + local_cache[filename] = global_cache[filename] = (st.st_mtime, ret) + return ret +waflib.Node.Node.h_file = h_file + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fc_bgxlf.py b/ldb-2.0.8/third_party/waf/waflib/extras/fc_bgxlf.py new file mode 100644 index 0000000..cca1810 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/fc_bgxlf.py @@ -0,0 +1,32 @@ +#! /usr/bin/env python +# encoding: utf-8 +# harald at klimachs.de + +from waflib.Tools import fc, fc_config, fc_scan +from waflib.Configure import conf + +from waflib.Tools.compiler_fc import fc_compiler +fc_compiler['linux'].insert(0, 'fc_bgxlf') + +@conf +def find_bgxlf(conf): + fc = conf.find_program(['bgxlf2003_r','bgxlf2003'], var='FC') + conf.get_xlf_version(fc) + conf.env.FC_NAME = 'BGXLF' + +@conf +def bg_flags(self): + self.env.SONAME_ST = '' + self.env.FCSHLIB_MARKER = '' + self.env.FCSTLIB_MARKER = '' + self.env.FCFLAGS_fcshlib = ['-fPIC'] + self.env.LINKFLAGS_fcshlib = ['-G', '-Wl,-bexpfull'] + +def configure(conf): + conf.find_bgxlf() + conf.find_ar() + conf.fc_flags() + conf.fc_add_flags() + conf.xlf_flags() + conf.bg_flags() + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fc_cray.py b/ldb-2.0.8/third_party/waf/waflib/extras/fc_cray.py new file mode 100644 index 0000000..da733fa --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/fc_cray.py @@ -0,0 +1,51 @@ +#! /usr/bin/env python +# encoding: utf-8 +# harald at klimachs.de + +import re +from waflib.Tools import fc, fc_config, fc_scan +from waflib.Configure import conf + +from waflib.Tools.compiler_fc import fc_compiler +fc_compiler['linux'].append('fc_cray') + +@conf +def find_crayftn(conf): + """Find the Cray fortran compiler (will look in the environment variable 'FC')""" + fc = conf.find_program(['crayftn'], var='FC') + conf.get_crayftn_version(fc) + conf.env.FC_NAME = 'CRAY' + conf.env.FC_MOD_CAPITALIZATION = 'UPPER.mod' + +@conf +def crayftn_flags(conf): + v = conf.env + v['_FCMODOUTFLAGS'] = ['-em', '-J.'] # enable module files and put them in the current directory + v['FCFLAGS_DEBUG'] = ['-m1'] # more verbose compiler warnings + v['FCFLAGS_fcshlib'] = ['-h pic'] + v['LINKFLAGS_fcshlib'] = ['-h shared'] + + v['FCSTLIB_MARKER'] = '-h static' + v['FCSHLIB_MARKER'] = '-h dynamic' + +@conf +def get_crayftn_version(conf, fc): + version_re = re.compile(r"Cray Fortran\s*:\s*Version\s*(?P\d*)\.(?P\d*)", re.I).search + cmd = fc + ['-V'] + out,err = fc_config.getoutput(conf, cmd, stdin=False) + if out: + match = version_re(out) + else: + match = version_re(err) + if not match: + conf.fatal('Could not determine the Cray Fortran compiler version.') + k = match.groupdict() + conf.env['FC_VERSION'] = (k['major'], k['minor']) + +def configure(conf): + conf.find_crayftn() + conf.find_ar() + conf.fc_flags() + conf.fc_add_flags() + conf.crayftn_flags() + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fc_nag.py b/ldb-2.0.8/third_party/waf/waflib/extras/fc_nag.py new file mode 100644 index 0000000..edcb218 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/fc_nag.py @@ -0,0 +1,61 @@ +#! /usr/bin/env python +# encoding: utf-8 +# harald at klimachs.de + +import re +from waflib import Utils +from waflib.Tools import fc,fc_config,fc_scan +from waflib.Configure import conf + +from waflib.Tools.compiler_fc import fc_compiler +fc_compiler['linux'].insert(0, 'fc_nag') + +@conf +def find_nag(conf): + """Find the NAG Fortran Compiler (will look in the environment variable 'FC')""" + + fc = conf.find_program(['nagfor'], var='FC') + conf.get_nag_version(fc) + conf.env.FC_NAME = 'NAG' + conf.env.FC_MOD_CAPITALIZATION = 'lower' + +@conf +def nag_flags(conf): + v = conf.env + v.FCFLAGS_DEBUG = ['-C=all'] + v.FCLNK_TGT_F = ['-o', ''] + v.FC_TGT_F = ['-c', '-o', ''] + +@conf +def nag_modifier_platform(conf): + dest_os = conf.env['DEST_OS'] or Utils.unversioned_sys_platform() + nag_modifier_func = getattr(conf, 'nag_modifier_' + dest_os, None) + if nag_modifier_func: + nag_modifier_func() + +@conf +def get_nag_version(conf, fc): + """Get the NAG compiler version""" + + version_re = re.compile(r"^NAG Fortran Compiler *Release *(?P\d*)\.(?P\d*)", re.M).search + cmd = fc + ['-V'] + + out, err = fc_config.getoutput(conf,cmd,stdin=False) + if out: + match = version_re(out) + if not match: + match = version_re(err) + else: match = version_re(err) + if not match: + conf.fatal('Could not determine the NAG version.') + k = match.groupdict() + conf.env['FC_VERSION'] = (k['major'], k['minor']) + +def configure(conf): + conf.find_nag() + conf.find_ar() + conf.fc_flags() + conf.fc_add_flags() + conf.nag_flags() + conf.nag_modifier_platform() + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fc_nec.py b/ldb-2.0.8/third_party/waf/waflib/extras/fc_nec.py new file mode 100644 index 0000000..67c8680 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/fc_nec.py @@ -0,0 +1,60 @@ +#! /usr/bin/env python +# encoding: utf-8 +# harald at klimachs.de + +import re +from waflib.Tools import fc, fc_config, fc_scan +from waflib.Configure import conf + +from waflib.Tools.compiler_fc import fc_compiler +fc_compiler['linux'].append('fc_nec') + +@conf +def find_sxfc(conf): + """Find the NEC fortran compiler (will look in the environment variable 'FC')""" + fc = conf.find_program(['sxf90','sxf03'], var='FC') + conf.get_sxfc_version(fc) + conf.env.FC_NAME = 'NEC' + conf.env.FC_MOD_CAPITALIZATION = 'lower' + +@conf +def sxfc_flags(conf): + v = conf.env + v['_FCMODOUTFLAGS'] = [] # enable module files and put them in the current directory + v['FCFLAGS_DEBUG'] = [] # more verbose compiler warnings + v['FCFLAGS_fcshlib'] = [] + v['LINKFLAGS_fcshlib'] = [] + + v['FCSTLIB_MARKER'] = '' + v['FCSHLIB_MARKER'] = '' + +@conf +def get_sxfc_version(conf, fc): + version_re = re.compile(r"FORTRAN90/SX\s*Version\s*(?P\d*)\.(?P\d*)", re.I).search + cmd = fc + ['-V'] + out,err = fc_config.getoutput(conf, cmd, stdin=False) + if out: + match = version_re(out) + else: + match = version_re(err) + if not match: + version_re=re.compile(r"NEC Fortran 2003 Compiler for\s*(?P\S*)\s*\(c\)\s*(?P\d*)",re.I).search + if out: + match = version_re(out) + else: + match = version_re(err) + if not match: + conf.fatal('Could not determine the NEC Fortran compiler version.') + k = match.groupdict() + conf.env['FC_VERSION'] = (k['major'], k['minor']) + +def configure(conf): + conf.find_sxfc() + conf.find_program('sxar',var='AR') + conf.add_os_flags('ARFLAGS') + if not conf.env.ARFLAGS: + conf.env.ARFLAGS=['rcs'] + + conf.fc_flags() + conf.fc_add_flags() + conf.sxfc_flags() diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fc_nfort.py b/ldb-2.0.8/third_party/waf/waflib/extras/fc_nfort.py new file mode 100644 index 0000000..c25886b --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/fc_nfort.py @@ -0,0 +1,52 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Detection of the NEC Fortran compiler for Aurora Tsubasa + +import re +from waflib.Tools import fc,fc_config,fc_scan +from waflib.Configure import conf +from waflib.Tools.compiler_fc import fc_compiler +fc_compiler['linux'].append('fc_nfort') + +@conf +def find_nfort(conf): + fc=conf.find_program(['nfort'],var='FC') + conf.get_nfort_version(fc) + conf.env.FC_NAME='NFORT' + conf.env.FC_MOD_CAPITALIZATION='lower' + +@conf +def nfort_flags(conf): + v=conf.env + v['_FCMODOUTFLAGS']=[] + v['FCFLAGS_DEBUG']=[] + v['FCFLAGS_fcshlib']=[] + v['LINKFLAGS_fcshlib']=[] + v['FCSTLIB_MARKER']='' + v['FCSHLIB_MARKER']='' + +@conf +def get_nfort_version(conf,fc): + version_re=re.compile(r"nfort\s*\(NFORT\)\s*(?P\d+)\.(?P\d+)\.",re.I).search + cmd=fc+['--version'] + out,err=fc_config.getoutput(conf,cmd,stdin=False) + if out: + match=version_re(out) + else: + match=version_re(err) + if not match: + return(False) + conf.fatal('Could not determine the NEC NFORT Fortran compiler version.') + else: + k=match.groupdict() + conf.env['FC_VERSION']=(k['major'],k['minor']) + +def configure(conf): + conf.find_nfort() + conf.find_program('nar',var='AR') + conf.add_os_flags('ARFLAGS') + if not conf.env.ARFLAGS: + conf.env.ARFLAGS=['rcs'] + conf.fc_flags() + conf.fc_add_flags() + conf.nfort_flags() diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fc_open64.py b/ldb-2.0.8/third_party/waf/waflib/extras/fc_open64.py new file mode 100644 index 0000000..413719f --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/fc_open64.py @@ -0,0 +1,58 @@ +#! /usr/bin/env python +# encoding: utf-8 +# harald at klimachs.de + +import re +from waflib import Utils +from waflib.Tools import fc,fc_config,fc_scan +from waflib.Configure import conf + +from waflib.Tools.compiler_fc import fc_compiler +fc_compiler['linux'].insert(0, 'fc_open64') + +@conf +def find_openf95(conf): + """Find the Open64 Fortran Compiler (will look in the environment variable 'FC')""" + + fc = conf.find_program(['openf95', 'openf90'], var='FC') + conf.get_open64_version(fc) + conf.env.FC_NAME = 'OPEN64' + conf.env.FC_MOD_CAPITALIZATION = 'UPPER.mod' + +@conf +def openf95_flags(conf): + v = conf.env + v['FCFLAGS_DEBUG'] = ['-fullwarn'] + +@conf +def openf95_modifier_platform(conf): + dest_os = conf.env['DEST_OS'] or Utils.unversioned_sys_platform() + openf95_modifier_func = getattr(conf, 'openf95_modifier_' + dest_os, None) + if openf95_modifier_func: + openf95_modifier_func() + +@conf +def get_open64_version(conf, fc): + """Get the Open64 compiler version""" + + version_re = re.compile(r"Open64 Compiler Suite: *Version *(?P\d*)\.(?P\d*)", re.I).search + cmd = fc + ['-version'] + + out, err = fc_config.getoutput(conf,cmd,stdin=False) + if out: + match = version_re(out) + else: + match = version_re(err) + if not match: + conf.fatal('Could not determine the Open64 version.') + k = match.groupdict() + conf.env['FC_VERSION'] = (k['major'], k['minor']) + +def configure(conf): + conf.find_openf95() + conf.find_ar() + conf.fc_flags() + conf.fc_add_flags() + conf.openf95_flags() + conf.openf95_modifier_platform() + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fc_pgfortran.py b/ldb-2.0.8/third_party/waf/waflib/extras/fc_pgfortran.py new file mode 100644 index 0000000..afb2817 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/fc_pgfortran.py @@ -0,0 +1,68 @@ +#! /usr/bin/env python +# encoding: utf-8 +# harald at klimachs.de + +import re +from waflib.Tools import fc, fc_config, fc_scan +from waflib.Configure import conf + +from waflib.Tools.compiler_fc import fc_compiler +fc_compiler['linux'].append('fc_pgfortran') + +@conf +def find_pgfortran(conf): + """Find the PGI fortran compiler (will look in the environment variable 'FC')""" + fc = conf.find_program(['pgfortran', 'pgf95', 'pgf90'], var='FC') + conf.get_pgfortran_version(fc) + conf.env.FC_NAME = 'PGFC' + +@conf +def pgfortran_flags(conf): + v = conf.env + v['FCFLAGS_fcshlib'] = ['-shared'] + v['FCFLAGS_DEBUG'] = ['-Minform=inform', '-Mstandard'] # why not + v['FCSTLIB_MARKER'] = '-Bstatic' + v['FCSHLIB_MARKER'] = '-Bdynamic' + v['SONAME_ST'] = '-soname %s' + +@conf +def get_pgfortran_version(conf,fc): + version_re = re.compile(r"The Portland Group", re.I).search + cmd = fc + ['-V'] + out,err = fc_config.getoutput(conf, cmd, stdin=False) + if out: + match = version_re(out) + else: + match = version_re(err) + if not match: + conf.fatal('Could not verify PGI signature') + cmd = fc + ['-help=variable'] + out,err = fc_config.getoutput(conf, cmd, stdin=False) + if out.find('COMPVER')<0: + conf.fatal('Could not determine the compiler type') + k = {} + prevk = '' + out = out.splitlines() + for line in out: + lst = line.partition('=') + if lst[1] == '=': + key = lst[0].rstrip() + if key == '': + key = prevk + val = lst[2].rstrip() + k[key] = val + else: + prevk = line.partition(' ')[0] + def isD(var): + return var in k + def isT(var): + return var in k and k[var]!='0' + conf.env['FC_VERSION'] = (k['COMPVER'].split('.')) + +def configure(conf): + conf.find_pgfortran() + conf.find_ar() + conf.fc_flags() + conf.fc_add_flags() + conf.pgfortran_flags() + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fc_solstudio.py b/ldb-2.0.8/third_party/waf/waflib/extras/fc_solstudio.py new file mode 100644 index 0000000..53766df --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/fc_solstudio.py @@ -0,0 +1,62 @@ +#! /usr/bin/env python +# encoding: utf-8 +# harald at klimachs.de + +import re +from waflib import Utils +from waflib.Tools import fc,fc_config,fc_scan +from waflib.Configure import conf + +from waflib.Tools.compiler_fc import fc_compiler +fc_compiler['linux'].append('fc_solstudio') + +@conf +def find_solstudio(conf): + """Find the Solaris Studio compiler (will look in the environment variable 'FC')""" + + fc = conf.find_program(['sunf95', 'f95', 'sunf90', 'f90'], var='FC') + conf.get_solstudio_version(fc) + conf.env.FC_NAME = 'SOL' + +@conf +def solstudio_flags(conf): + v = conf.env + v['FCFLAGS_fcshlib'] = ['-Kpic'] + v['FCFLAGS_DEBUG'] = ['-w3'] + v['LINKFLAGS_fcshlib'] = ['-G'] + v['FCSTLIB_MARKER'] = '-Bstatic' + v['FCSHLIB_MARKER'] = '-Bdynamic' + v['SONAME_ST'] = '-h %s' + +@conf +def solstudio_modifier_platform(conf): + dest_os = conf.env['DEST_OS'] or Utils.unversioned_sys_platform() + solstudio_modifier_func = getattr(conf, 'solstudio_modifier_' + dest_os, None) + if solstudio_modifier_func: + solstudio_modifier_func() + +@conf +def get_solstudio_version(conf, fc): + """Get the compiler version""" + + version_re = re.compile(r"Sun Fortran 95 *(?P\d*)\.(?P\d*)", re.I).search + cmd = fc + ['-V'] + + out, err = fc_config.getoutput(conf,cmd,stdin=False) + if out: + match = version_re(out) + else: + match = version_re(err) + if not match: + conf.fatal('Could not determine the Sun Studio Fortran version.') + k = match.groupdict() + conf.env['FC_VERSION'] = (k['major'], k['minor']) + +def configure(conf): + conf.find_solstudio() + conf.find_ar() + conf.fc_flags() + conf.fc_add_flags() + conf.solstudio_flags() + conf.solstudio_modifier_platform() + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fc_xlf.py b/ldb-2.0.8/third_party/waf/waflib/extras/fc_xlf.py new file mode 100644 index 0000000..5a3da03 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/fc_xlf.py @@ -0,0 +1,63 @@ +#! /usr/bin/env python +# encoding: utf-8 +# harald at klimachs.de + +import re +from waflib import Utils,Errors +from waflib.Tools import fc,fc_config,fc_scan +from waflib.Configure import conf + +from waflib.Tools.compiler_fc import fc_compiler +fc_compiler['aix'].insert(0, 'fc_xlf') + +@conf +def find_xlf(conf): + """Find the xlf program (will look in the environment variable 'FC')""" + + fc = conf.find_program(['xlf2003_r', 'xlf2003', 'xlf95_r', 'xlf95', 'xlf90_r', 'xlf90', 'xlf_r', 'xlf'], var='FC') + conf.get_xlf_version(fc) + conf.env.FC_NAME='XLF' + +@conf +def xlf_flags(conf): + v = conf.env + v['FCDEFINES_ST'] = '-WF,-D%s' + v['FCFLAGS_fcshlib'] = ['-qpic=small'] + v['FCFLAGS_DEBUG'] = ['-qhalt=w'] + v['LINKFLAGS_fcshlib'] = ['-Wl,-shared'] + +@conf +def xlf_modifier_platform(conf): + dest_os = conf.env['DEST_OS'] or Utils.unversioned_sys_platform() + xlf_modifier_func = getattr(conf, 'xlf_modifier_' + dest_os, None) + if xlf_modifier_func: + xlf_modifier_func() + +@conf +def get_xlf_version(conf, fc): + """Get the compiler version""" + + cmd = fc + ['-qversion'] + try: + out, err = conf.cmd_and_log(cmd, output=0) + except Errors.WafError: + conf.fatal('Could not find xlf %r' % cmd) + + for v in (r"IBM XL Fortran.* V(?P\d*)\.(?P\d*)",): + version_re = re.compile(v, re.I).search + match = version_re(out or err) + if match: + k = match.groupdict() + conf.env['FC_VERSION'] = (k['major'], k['minor']) + break + else: + conf.fatal('Could not determine the XLF version.') + +def configure(conf): + conf.find_xlf() + conf.find_ar() + conf.fc_flags() + conf.fc_add_flags() + conf.xlf_flags() + conf.xlf_modifier_platform() + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/file_to_object.py b/ldb-2.0.8/third_party/waf/waflib/extras/file_to_object.py new file mode 100644 index 0000000..1393b51 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/file_to_object.py @@ -0,0 +1,137 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Tool to embed file into objects + +__author__ = __maintainer__ = "Jérôme Carretero " +__copyright__ = "Jérôme Carretero, 2014" + +""" + +This tool allows to embed file contents in object files (.o). +It is not exactly portable, and the file contents are reachable +using various non-portable fashions. +The goal here is to provide a functional interface to the embedding +of file data in objects. +See the ``playground/embedded_resources`` example for an example. + +Usage:: + + bld( + name='pipeline', + # ^ Reference this in use="..." for things using the generated code + features='file_to_object', + source='some.file', + # ^ Name of the file to embed in binary section. + ) + +Known issues: + +- Destination is named like source, with extension renamed to .o + eg. some.file -> some.o + +""" + +import os +from waflib import Task, TaskGen, Errors + +def filename_c_escape(x): + return x.replace("\\", "\\\\") + +class file_to_object_s(Task.Task): + color = 'CYAN' + vars = ['DEST_CPU', 'DEST_BINFMT'] + + def run(self): + name = [] + for i, x in enumerate(self.inputs[0].name): + if x.isalnum(): + name.append(x) + else: + name.append('_') + file = self.inputs[0].abspath() + size = os.path.getsize(file) + if self.env.DEST_CPU in ('x86_64', 'ia', 'aarch64'): + unit = 'quad' + align = 8 + elif self.env.DEST_CPU in ('x86','arm', 'thumb', 'm68k'): + unit = 'long' + align = 4 + else: + raise Errors.WafError("Unsupported DEST_CPU, please report bug!") + + file = filename_c_escape(file) + name = "_binary_" + "".join(name) + rodata = ".section .rodata" + if self.env.DEST_BINFMT == "mac-o": + name = "_" + name + rodata = ".section __TEXT,__const" + + with open(self.outputs[0].abspath(), 'w') as f: + f.write(\ +""" + .global %(name)s_start + .global %(name)s_end + .global %(name)s_size + %(rodata)s +%(name)s_start: + .incbin "%(file)s" +%(name)s_end: + .align %(align)d +%(name)s_size: + .%(unit)s 0x%(size)x +""" % locals()) + +class file_to_object_c(Task.Task): + color = 'CYAN' + def run(self): + name = [] + for i, x in enumerate(self.inputs[0].name): + if x.isalnum(): + name.append(x) + else: + name.append('_') + file = self.inputs[0].abspath() + size = os.path.getsize(file) + + name = "_binary_" + "".join(name) + + data = self.inputs[0].read('rb') + lines, line = [], [] + for idx_byte, byte in enumerate(data): + line.append(byte) + if len(line) > 15 or idx_byte == size-1: + lines.append(", ".join(("0x%02x" % ord(x)) for x in line)) + line = [] + data = ",\n ".join(lines) + + self.outputs[0].write(\ +""" +unsigned long %(name)s_size = %(size)dL; +char const %(name)s_start[] = { + %(data)s +}; +char const %(name)s_end[] = {}; +""" % locals()) + +@TaskGen.feature('file_to_object') +@TaskGen.before_method('process_source') +def tg_file_to_object(self): + bld = self.bld + sources = self.to_nodes(self.source) + targets = [] + for src in sources: + if bld.env.F2O_METHOD == ["asm"]: + tgt = src.parent.find_or_declare(src.name + '.f2o.s') + tsk = self.create_task('file_to_object_s', src, tgt) + tsk.cwd = src.parent.abspath() # verify + else: + tgt = src.parent.find_or_declare(src.name + '.f2o.c') + tsk = self.create_task('file_to_object_c', src, tgt) + tsk.cwd = src.parent.abspath() # verify + targets.append(tgt) + self.source = targets + +def configure(conf): + conf.load('gas') + conf.env.F2O_METHOD = ["c"] + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fluid.py b/ldb-2.0.8/third_party/waf/waflib/extras/fluid.py new file mode 100644 index 0000000..4814a35 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/fluid.py @@ -0,0 +1,30 @@ +#!/usr/bin/python +# encoding: utf-8 +# Grygoriy Fuchedzhy 2009 + +""" +Compile fluid files (fltk graphic library). Use the 'fluid' feature in conjunction with the 'cxx' feature. +""" + +from waflib import Task +from waflib.TaskGen import extension + +class fluid(Task.Task): + color = 'BLUE' + ext_out = ['.h'] + run_str = '${FLUID} -c -o ${TGT[0].abspath()} -h ${TGT[1].abspath()} ${SRC}' + +@extension('.fl') +def process_fluid(self, node): + """add the .fl to the source list; the cxx file generated will be compiled when possible""" + cpp = node.change_ext('.cpp') + hpp = node.change_ext('.hpp') + self.create_task('fluid', node, [cpp, hpp]) + + if 'cxx' in self.features: + self.source.append(cpp) + +def configure(conf): + conf.find_program('fluid', var='FLUID') + conf.check_cfg(path='fltk-config', package='', args='--cxxflags --ldflags', uselib_store='FLTK', mandatory=True) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/freeimage.py b/ldb-2.0.8/third_party/waf/waflib/extras/freeimage.py new file mode 100644 index 0000000..f27e525 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/freeimage.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python +# encoding: utf-8 +# +# written by Sylvain Rouquette, 2011 + +''' +To add the freeimage tool to the waf file: +$ ./waf-light --tools=compat15,freeimage + or, if you have waf >= 1.6.2 +$ ./waf update --files=freeimage + +The wscript will look like: + +def options(opt): + opt.load('compiler_cxx freeimage') + +def configure(conf): + conf.load('compiler_cxx freeimage') + + # you can call check_freeimage with some parameters. + # It's optional on Linux, it's 'mandatory' on Windows if + # you didn't use --fi-path on the command-line + + # conf.check_freeimage(path='FreeImage/Dist', fip=True) + +def build(bld): + bld(source='main.cpp', target='app', use='FREEIMAGE') +''' + +from waflib import Utils +from waflib.Configure import conf + + +def options(opt): + opt.add_option('--fi-path', type='string', default='', dest='fi_path', + help='''path to the FreeImage directory \ + where the files are e.g. /FreeImage/Dist''') + opt.add_option('--fip', action='store_true', default=False, dest='fip', + help='link with FreeImagePlus') + opt.add_option('--fi-static', action='store_true', + default=False, dest='fi_static', + help="link as shared libraries") + + +@conf +def check_freeimage(self, path=None, fip=False): + self.start_msg('Checking FreeImage') + if not self.env['CXX']: + self.fatal('you must load compiler_cxx before loading freeimage') + prefix = self.options.fi_static and 'ST' or '' + platform = Utils.unversioned_sys_platform() + if platform == 'win32': + if not path: + self.fatal('you must specify the path to FreeImage. \ + use --fi-path=/FreeImage/Dist') + else: + self.env['INCLUDES_FREEIMAGE'] = path + self.env['%sLIBPATH_FREEIMAGE' % prefix] = path + libs = ['FreeImage'] + if self.options.fip: + libs.append('FreeImagePlus') + if platform == 'win32': + self.env['%sLIB_FREEIMAGE' % prefix] = libs + else: + self.env['%sLIB_FREEIMAGE' % prefix] = [i.lower() for i in libs] + self.end_msg('ok') + + +def configure(conf): + platform = Utils.unversioned_sys_platform() + if platform == 'win32' and not conf.options.fi_path: + return + conf.check_freeimage(conf.options.fi_path, conf.options.fip) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fsb.py b/ldb-2.0.8/third_party/waf/waflib/extras/fsb.py new file mode 100644 index 0000000..1b8f398 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/fsb.py @@ -0,0 +1,31 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2011 (ita) + +""" +Fully sequential builds + +The previous tasks from task generators are re-processed, and this may lead to speed issues +Yet, if you are using this, speed is probably a minor concern +""" + +from waflib import Build + +def options(opt): + pass + +def configure(conf): + pass + +class FSBContext(Build.BuildContext): + def __call__(self, *k, **kw): + ret = Build.BuildContext.__call__(self, *k, **kw) + + # evaluate the results immediately + Build.BuildContext.compile(self) + + return ret + + def compile(self): + pass + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fsc.py b/ldb-2.0.8/third_party/waf/waflib/extras/fsc.py new file mode 100644 index 0000000..c67e70b --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/fsc.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2011 (ita) + +""" +Experimental F# stuff + +FSC="mono /path/to/fsc.exe" waf configure build +""" + +from waflib import Utils, Task +from waflib.TaskGen import before_method, after_method, feature +from waflib.Tools import ccroot, cs + +ccroot.USELIB_VARS['fsc'] = set(['CSFLAGS', 'ASSEMBLIES', 'RESOURCES']) + +@feature('fs') +@before_method('process_source') +def apply_fsc(self): + cs_nodes = [] + no_nodes = [] + for x in self.to_nodes(self.source): + if x.name.endswith('.fs'): + cs_nodes.append(x) + else: + no_nodes.append(x) + self.source = no_nodes + + bintype = getattr(self, 'type', self.gen.endswith('.dll') and 'library' or 'exe') + self.cs_task = tsk = self.create_task('fsc', cs_nodes, self.path.find_or_declare(self.gen)) + tsk.env.CSTYPE = '/target:%s' % bintype + tsk.env.OUT = '/out:%s' % tsk.outputs[0].abspath() + + inst_to = getattr(self, 'install_path', bintype=='exe' and '${BINDIR}' or '${LIBDIR}') + if inst_to: + # note: we are making a copy, so the files added to cs_task.outputs won't be installed automatically + mod = getattr(self, 'chmod', bintype=='exe' and Utils.O755 or Utils.O644) + self.install_task = self.add_install_files(install_to=inst_to, install_from=self.cs_task.outputs[:], chmod=mod) + +feature('fs')(cs.use_cs) +after_method('apply_fsc')(cs.use_cs) + +feature('fs')(cs.debug_cs) +after_method('apply_fsc', 'use_cs')(cs.debug_cs) + +class fsc(Task.Task): + """ + Compile F# files + """ + color = 'YELLOW' + run_str = '${FSC} ${CSTYPE} ${CSFLAGS} ${ASS_ST:ASSEMBLIES} ${RES_ST:RESOURCES} ${OUT} ${SRC}' + +def configure(conf): + """ + Find a F# compiler, set the variable FSC for the compiler and FS_NAME (mono or fsc) + """ + conf.find_program(['fsc.exe', 'fsharpc'], var='FSC') + conf.env.ASS_ST = '/r:%s' + conf.env.RES_ST = '/resource:%s' + + conf.env.FS_NAME = 'fsc' + if str(conf.env.FSC).lower().find('fsharpc') > -1: + conf.env.FS_NAME = 'mono' + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/gccdeps.py b/ldb-2.0.8/third_party/waf/waflib/extras/gccdeps.py new file mode 100644 index 0000000..bfabe72 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/gccdeps.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2008-2010 (ita) + +""" +Execute the tasks with gcc -MD, read the dependencies from the .d file +and prepare the dependency calculation for the next run. +This affects the cxx class, so make sure to load Qt5 after this tool. + +Usage:: + + def options(opt): + opt.load('compiler_cxx') + def configure(conf): + conf.load('compiler_cxx gccdeps') +""" + +import os, re, threading +from waflib import Task, Logs, Utils, Errors +from waflib.Tools import c_preproc +from waflib.TaskGen import before_method, feature + +lock = threading.Lock() + +gccdeps_flags = ['-MD'] +if not c_preproc.go_absolute: + gccdeps_flags = ['-MMD'] + +# Third-party tools are allowed to add extra names in here with append() +supported_compilers = ['gcc', 'icc', 'clang'] + +def scan(self): + if not self.__class__.__name__ in self.env.ENABLE_GCCDEPS: + return super(self.derived_gccdeps, self).scan() + nodes = self.generator.bld.node_deps.get(self.uid(), []) + names = [] + return (nodes, names) + +re_o = re.compile(r"\.o$") +re_splitter = re.compile(r'(?= 0: + return line[sep_idx + 2:] + else: + return line + +def path_to_node(base_node, path, cached_nodes): + # Take the base node and the path and return a node + # Results are cached because searching the node tree is expensive + # The following code is executed by threads, it is not safe, so a lock is needed... + if getattr(path, '__hash__'): + node_lookup_key = (base_node, path) + else: + # Not hashable, assume it is a list and join into a string + node_lookup_key = (base_node, os.path.sep.join(path)) + try: + lock.acquire() + node = cached_nodes[node_lookup_key] + except KeyError: + node = base_node.find_resource(path) + cached_nodes[node_lookup_key] = node + finally: + lock.release() + return node + +def post_run(self): + if not self.__class__.__name__ in self.env.ENABLE_GCCDEPS: + return super(self.derived_gccdeps, self).post_run() + + name = self.outputs[0].abspath() + name = re_o.sub('.d', name) + try: + txt = Utils.readf(name) + except EnvironmentError: + Logs.error('Could not find a .d dependency file, are cflags/cxxflags overwritten?') + raise + #os.remove(name) + + # Compilers have the choice to either output the file's dependencies + # as one large Makefile rule: + # + # /path/to/file.o: /path/to/dep1.h \ + # /path/to/dep2.h \ + # /path/to/dep3.h \ + # ... + # + # or as many individual rules: + # + # /path/to/file.o: /path/to/dep1.h + # /path/to/file.o: /path/to/dep2.h + # /path/to/file.o: /path/to/dep3.h + # ... + # + # So the first step is to sanitize the input by stripping out the left- + # hand side of all these lines. After that, whatever remains are the + # implicit dependencies of task.outputs[0] + txt = '\n'.join([remove_makefile_rule_lhs(line) for line in txt.splitlines()]) + + # Now join all the lines together + txt = txt.replace('\\\n', '') + + val = txt.strip() + val = [x.replace('\\ ', ' ') for x in re_splitter.split(val) if x] + + nodes = [] + bld = self.generator.bld + + # Dynamically bind to the cache + try: + cached_nodes = bld.cached_nodes + except AttributeError: + cached_nodes = bld.cached_nodes = {} + + for x in val: + + node = None + if os.path.isabs(x): + node = path_to_node(bld.root, x, cached_nodes) + else: + # TODO waf 1.9 - single cwd value + path = getattr(bld, 'cwdx', bld.bldnode) + # when calling find_resource, make sure the path does not contain '..' + x = [k for k in Utils.split_path(x) if k and k != '.'] + while '..' in x: + idx = x.index('..') + if idx == 0: + x = x[1:] + path = path.parent + else: + del x[idx] + del x[idx-1] + + node = path_to_node(path, x, cached_nodes) + + if not node: + raise ValueError('could not find %r for %r' % (x, self)) + if id(node) == id(self.inputs[0]): + # ignore the source file, it is already in the dependencies + # this way, successful config tests may be retrieved from the cache + continue + nodes.append(node) + + Logs.debug('deps: gccdeps for %s returned %s', self, nodes) + + bld.node_deps[self.uid()] = nodes + bld.raw_deps[self.uid()] = [] + + try: + del self.cache_sig + except AttributeError: + pass + + Task.Task.post_run(self) + +def sig_implicit_deps(self): + if not self.__class__.__name__ in self.env.ENABLE_GCCDEPS: + return super(self.derived_gccdeps, self).sig_implicit_deps() + try: + return Task.Task.sig_implicit_deps(self) + except Errors.WafError: + return Utils.SIG_NIL + +def wrap_compiled_task(classname): + derived_class = type(classname, (Task.classes[classname],), {}) + derived_class.derived_gccdeps = derived_class + derived_class.post_run = post_run + derived_class.scan = scan + derived_class.sig_implicit_deps = sig_implicit_deps + +for k in ('c', 'cxx'): + if k in Task.classes: + wrap_compiled_task(k) + +@before_method('process_source') +@feature('force_gccdeps') +def force_gccdeps(self): + self.env.ENABLE_GCCDEPS = ['c', 'cxx'] + +def configure(conf): + # in case someone provides a --enable-gccdeps command-line option + if not getattr(conf.options, 'enable_gccdeps', True): + return + + global gccdeps_flags + flags = conf.env.GCCDEPS_FLAGS or gccdeps_flags + if conf.env.CC_NAME in supported_compilers: + try: + conf.check(fragment='int main() { return 0; }', features='c force_gccdeps', cflags=flags, msg='Checking for c flags %r' % ''.join(flags)) + except Errors.ConfigurationError: + pass + else: + conf.env.append_value('CFLAGS', flags) + conf.env.append_unique('ENABLE_GCCDEPS', 'c') + + if conf.env.CXX_NAME in supported_compilers: + try: + conf.check(fragment='int main() { return 0; }', features='cxx force_gccdeps', cxxflags=flags, msg='Checking for cxx flags %r' % ''.join(flags)) + except Errors.ConfigurationError: + pass + else: + conf.env.append_value('CXXFLAGS', flags) + conf.env.append_unique('ENABLE_GCCDEPS', 'cxx') + +def options(opt): + raise ValueError('Do not load gccdeps options') + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/gdbus.py b/ldb-2.0.8/third_party/waf/waflib/extras/gdbus.py new file mode 100644 index 0000000..0e0476e --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/gdbus.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Copyright Garmin International or its subsidiaries, 2018 +# +# Heavily based on dbus.py + +""" +Compiles dbus files with **gdbus-codegen** +Typical usage:: + def options(opt): + opt.load('compiler_c gdbus') + def configure(conf): + conf.load('compiler_c gdbus') + def build(bld): + tg = bld.program( + includes = '.', + source = bld.path.ant_glob('*.c'), + target = 'gnome-hello') + tg.add_gdbus_file('test.xml', 'com.example.example.', 'Example') +""" + +from waflib import Task, Errors, Utils +from waflib.TaskGen import taskgen_method, before_method + +@taskgen_method +def add_gdbus_file(self, filename, prefix, namespace, export=False): + """ + Adds a dbus file to the list of dbus files to process. Store them in the attribute *dbus_lst*. + :param filename: xml file to compile + :type filename: string + :param prefix: interface prefix (--interface-prefix=prefix) + :type prefix: string + :param mode: C namespace (--c-namespace=namespace) + :type mode: string + :param export: Export Headers? + :type export: boolean + """ + if not hasattr(self, 'gdbus_lst'): + self.gdbus_lst = [] + if not 'process_gdbus' in self.meths: + self.meths.append('process_gdbus') + self.gdbus_lst.append([filename, prefix, namespace, export]) + +@before_method('process_source') +def process_gdbus(self): + """ + Processes the dbus files stored in the attribute *gdbus_lst* to create :py:class:`gdbus_binding_tool` instances. + """ + output_node = self.path.get_bld().make_node(['gdbus', self.get_name()]) + sources = [] + + for filename, prefix, namespace, export in getattr(self, 'gdbus_lst', []): + node = self.path.find_resource(filename) + if not node: + raise Errors.WafError('file not found ' + filename) + c_file = output_node.find_or_declare(node.change_ext('.c').name) + h_file = output_node.find_or_declare(node.change_ext('.h').name) + tsk = self.create_task('gdbus_binding_tool', node, [c_file, h_file]) + tsk.cwd = output_node.abspath() + + tsk.env.GDBUS_CODEGEN_INTERFACE_PREFIX = prefix + tsk.env.GDBUS_CODEGEN_NAMESPACE = namespace + tsk.env.GDBUS_CODEGEN_OUTPUT = node.change_ext('').name + sources.append(c_file) + + if sources: + output_node.mkdir() + self.source = Utils.to_list(self.source) + sources + self.includes = [output_node] + self.to_incnodes(getattr(self, 'includes', [])) + if export: + self.export_includes = [output_node] + self.to_incnodes(getattr(self, 'export_includes', [])) + +class gdbus_binding_tool(Task.Task): + """ + Compiles a dbus file + """ + color = 'BLUE' + ext_out = ['.h', '.c'] + run_str = '${GDBUS_CODEGEN} --interface-prefix ${GDBUS_CODEGEN_INTERFACE_PREFIX} --generate-c-code ${GDBUS_CODEGEN_OUTPUT} --c-namespace ${GDBUS_CODEGEN_NAMESPACE} --c-generate-object-manager ${SRC[0].abspath()}' + shell = True + +def configure(conf): + """ + Detects the program gdbus-codegen and sets ``conf.env.GDBUS_CODEGEN`` + """ + conf.find_program('gdbus-codegen', var='GDBUS_CODEGEN') + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/genpybind.py b/ldb-2.0.8/third_party/waf/waflib/extras/genpybind.py new file mode 100644 index 0000000..ac206ee --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/genpybind.py @@ -0,0 +1,194 @@ +import os +import pipes +import subprocess +import sys + +from waflib import Logs, Task, Context +from waflib.Tools.c_preproc import scan as scan_impl +# ^-- Note: waflib.extras.gccdeps.scan does not work for us, +# due to its current implementation: +# The -MD flag is injected into the {C,CXX}FLAGS environment variable and +# dependencies are read out in a separate step after compiling by reading +# the .d file saved alongside the object file. +# As the genpybind task refers to a header file that is never compiled itself, +# gccdeps will not be able to extract the list of dependencies. + +from waflib.TaskGen import feature, before_method + + +def join_args(args): + return " ".join(pipes.quote(arg) for arg in args) + + +def configure(cfg): + cfg.load("compiler_cxx") + cfg.load("python") + cfg.check_python_version(minver=(2, 7)) + if not cfg.env.LLVM_CONFIG: + cfg.find_program("llvm-config", var="LLVM_CONFIG") + if not cfg.env.GENPYBIND: + cfg.find_program("genpybind", var="GENPYBIND") + + # find clang reasource dir for builtin headers + cfg.env.GENPYBIND_RESOURCE_DIR = os.path.join( + cfg.cmd_and_log(cfg.env.LLVM_CONFIG + ["--libdir"]).strip(), + "clang", + cfg.cmd_and_log(cfg.env.LLVM_CONFIG + ["--version"]).strip()) + if os.path.exists(cfg.env.GENPYBIND_RESOURCE_DIR): + cfg.msg("Checking clang resource dir", cfg.env.GENPYBIND_RESOURCE_DIR) + else: + cfg.fatal("Clang resource dir not found") + + +@feature("genpybind") +@before_method("process_source") +def generate_genpybind_source(self): + """ + Run genpybind on the headers provided in `source` and compile/link the + generated code instead. This works by generating the code on the fly and + swapping the source node before `process_source` is run. + """ + # name of module defaults to name of target + module = getattr(self, "module", self.target) + + # create temporary source file in build directory to hold generated code + out = "genpybind-%s.%d.cpp" % (module, self.idx) + out = self.path.get_bld().find_or_declare(out) + + task = self.create_task("genpybind", self.to_nodes(self.source), out) + # used to detect whether CFLAGS or CXXFLAGS should be passed to genpybind + task.features = self.features + task.module = module + # can be used to select definitions to include in the current module + # (when header files are shared by more than one module) + task.genpybind_tags = self.to_list(getattr(self, "genpybind_tags", [])) + # additional include directories + task.includes = self.to_list(getattr(self, "includes", [])) + task.genpybind = self.env.GENPYBIND + + # Tell waf to compile/link the generated code instead of the headers + # originally passed-in via the `source` parameter. (see `process_source`) + self.source = [out] + + +class genpybind(Task.Task): # pylint: disable=invalid-name + """ + Runs genpybind on headers provided as input to this task. + Generated code will be written to the first (and only) output node. + """ + quiet = True + color = "PINK" + scan = scan_impl + + @staticmethod + def keyword(): + return "Analyzing" + + def run(self): + if not self.inputs: + return + + args = self.find_genpybind() + self._arguments( + resource_dir=self.env.GENPYBIND_RESOURCE_DIR) + + output = self.run_genpybind(args) + + # For debugging / log output + pasteable_command = join_args(args) + + # write generated code to file in build directory + # (will be compiled during process_source stage) + (output_node,) = self.outputs + output_node.write("// {}\n{}\n".format( + pasteable_command.replace("\n", "\n// "), output)) + + def find_genpybind(self): + return self.genpybind + + def run_genpybind(self, args): + bld = self.generator.bld + + kwargs = dict(cwd=bld.variant_dir) + if hasattr(bld, "log_command"): + bld.log_command(args, kwargs) + else: + Logs.debug("runner: {!r}".format(args)) + proc = subprocess.Popen( + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs) + stdout, stderr = proc.communicate() + + if not isinstance(stdout, str): + stdout = stdout.decode(sys.stdout.encoding, errors="replace") + if not isinstance(stderr, str): + stderr = stderr.decode(sys.stderr.encoding, errors="replace") + + if proc.returncode != 0: + bld.fatal( + "genpybind returned {code} during the following call:" + "\n{command}\n\n{stdout}\n\n{stderr}".format( + code=proc.returncode, + command=join_args(args), + stdout=stdout, + stderr=stderr, + )) + + if stderr.strip(): + Logs.debug("non-fatal warnings during genpybind run:\n{}".format(stderr)) + + return stdout + + def _include_paths(self): + return self.generator.to_incnodes(self.includes + self.env.INCLUDES) + + def _inputs_as_relative_includes(self): + include_paths = self._include_paths() + relative_includes = [] + for node in self.inputs: + for inc in include_paths: + if node.is_child_of(inc): + relative_includes.append(node.path_from(inc)) + break + else: + self.generator.bld.fatal("could not resolve {}".format(node)) + return relative_includes + + def _arguments(self, genpybind_parse=None, resource_dir=None): + args = [] + relative_includes = self._inputs_as_relative_includes() + is_cxx = "cxx" in self.features + + # options for genpybind + args.extend(["--genpybind-module", self.module]) + if self.genpybind_tags: + args.extend(["--genpybind-tag"] + self.genpybind_tags) + if relative_includes: + args.extend(["--genpybind-include"] + relative_includes) + if genpybind_parse: + args.extend(["--genpybind-parse", genpybind_parse]) + + args.append("--") + + # headers to be processed by genpybind + args.extend(node.abspath() for node in self.inputs) + + args.append("--") + + # options for clang/genpybind-parse + args.append("-D__GENPYBIND__") + args.append("-xc++" if is_cxx else "-xc") + has_std_argument = False + for flag in self.env["CXXFLAGS" if is_cxx else "CFLAGS"]: + flag = flag.replace("-std=gnu", "-std=c") + if flag.startswith("-std=c"): + has_std_argument = True + args.append(flag) + if not has_std_argument: + args.append("-std=c++14") + args.extend("-I{}".format(n.abspath()) for n in self._include_paths()) + args.extend("-D{}".format(p) for p in self.env.DEFINES) + + # point to clang resource dir, if specified + if resource_dir: + args.append("-resource-dir={}".format(resource_dir)) + + return args diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/gob2.py b/ldb-2.0.8/third_party/waf/waflib/extras/gob2.py new file mode 100644 index 0000000..b4fa3b9 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/gob2.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Ali Sabil, 2007 + +from waflib import TaskGen + +TaskGen.declare_chain( + name = 'gob2', + rule = '${GOB2} -o ${TGT[0].bld_dir()} ${GOB2FLAGS} ${SRC}', + ext_in = '.gob', + ext_out = '.c' +) + +def configure(conf): + conf.find_program('gob2', var='GOB2') + conf.env['GOB2FLAGS'] = '' + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/halide.py b/ldb-2.0.8/third_party/waf/waflib/extras/halide.py new file mode 100644 index 0000000..6078e38 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/halide.py @@ -0,0 +1,151 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Halide code generation tool + +__author__ = __maintainer__ = "Jérôme Carretero " +__copyright__ = "Jérôme Carretero, 2014" + +""" + +Tool to run `Halide `_ code generators. + +Usage:: + + bld( + name='pipeline', + # ^ Reference this in use="..." for things using the generated code + #target=['pipeline.o', 'pipeline.h'] + # ^ by default, name.{o,h} is added, but you can set the outputs here + features='halide', + halide_env="HL_TRACE=1 HL_TARGET=host-opencl-gpu_debug", + # ^ Environment passed to the generator, + # can be a dict, k/v list, or string. + args=[], + # ^ Command-line arguments to the generator (optional), + # eg. to give parameters to the scheduling + source='pipeline_gen', + # ^ Name of the source executable + ) + + +Known issues: + + +- Currently only supports Linux (no ".exe") + +- Doesn't rerun on input modification when input is part of a build + chain, and has been modified externally. + +""" + +import os +from waflib import Task, Utils, Options, TaskGen, Errors + +class run_halide_gen(Task.Task): + color = 'CYAN' + vars = ['HALIDE_ENV', 'HALIDE_ARGS'] + run_str = "${SRC[0].abspath()} ${HALIDE_ARGS}" + def __str__(self): + stuff = "halide" + stuff += ("[%s]" % (",".join( + ('%s=%s' % (k,v)) for k, v in sorted(self.env.env.items())))) + return Task.Task.__str__(self).replace(self.__class__.__name__, + stuff) + +@TaskGen.feature('halide') +@TaskGen.before_method('process_source') +def halide(self): + Utils.def_attrs(self, + args=[], + halide_env={}, + ) + + bld = self.bld + + env = self.halide_env + try: + if isinstance(env, str): + env = dict(x.split('=') for x in env.split()) + elif isinstance(env, list): + env = dict(x.split('=') for x in env) + assert isinstance(env, dict) + except Exception as e: + if not isinstance(e, ValueError) \ + and not isinstance(e, AssertionError): + raise + raise Errors.WafError( + "halide_env must be under the form" \ + " {'HL_x':'a', 'HL_y':'b'}" \ + " or ['HL_x=y', 'HL_y=b']" \ + " or 'HL_x=y HL_y=b'") + + src = self.to_nodes(self.source) + assert len(src) == 1, "Only one source expected" + src = src[0] + + args = Utils.to_list(self.args) + + def change_ext(src, ext): + # Return a node with a new extension, in an appropriate folder + name = src.name + xpos = src.name.rfind('.') + if xpos == -1: + xpos = len(src.name) + newname = name[:xpos] + ext + if src.is_child_of(bld.bldnode): + node = src.get_src().parent.find_or_declare(newname) + else: + node = bld.bldnode.find_or_declare(newname) + return node + + def to_nodes(self, lst, path=None): + tmp = [] + path = path or self.path + find = path.find_or_declare + + if isinstance(lst, self.path.__class__): + lst = [lst] + + for x in Utils.to_list(lst): + if isinstance(x, str): + node = find(x) + else: + node = x + tmp.append(node) + return tmp + + tgt = to_nodes(self, self.target) + if not tgt: + tgt = [change_ext(src, '.o'), change_ext(src, '.h')] + cwd = tgt[0].parent.abspath() + task = self.create_task('run_halide_gen', src, tgt, cwd=cwd) + task.env.append_unique('HALIDE_ARGS', args) + if task.env.env == []: + task.env.env = {} + task.env.env.update(env) + task.env.HALIDE_ENV = " ".join(("%s=%s" % (k,v)) for (k,v) in sorted(env.items())) + task.env.HALIDE_ARGS = args + + try: + self.compiled_tasks.append(task) + except AttributeError: + self.compiled_tasks = [task] + self.source = [] + +def configure(conf): + if Options.options.halide_root is None: + conf.check_cfg(package='Halide', args='--cflags --libs') + else: + halide_root = Options.options.halide_root + conf.env.INCLUDES_HALIDE = [ os.path.join(halide_root, "include") ] + conf.env.LIBPATH_HALIDE = [ os.path.join(halide_root, "lib") ] + conf.env.LIB_HALIDE = ["Halide"] + + # You might want to add this, while upstream doesn't fix it + #conf.env.LIB_HALIDE += ['ncurses', 'dl', 'pthread'] + +def options(opt): + opt.add_option('--halide-root', + help="path to Halide include and lib files", + ) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/javatest.py b/ldb-2.0.8/third_party/waf/waflib/extras/javatest.py new file mode 100755 index 0000000..979b8d8 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/javatest.py @@ -0,0 +1,118 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Federico Pellegrin, 2017 (fedepell) + +""" +Provides Java Unit test support using :py:class:`waflib.Tools.waf_unit_test.utest` +task via the **javatest** feature. + +This gives the possibility to run unit test and have them integrated into the +standard waf unit test environment. It has been tested with TestNG and JUnit +but should be easily expandable to other frameworks given the flexibility of +ut_str provided by the standard waf unit test environment. + +Example usage: + +def options(opt): + opt.load('java waf_unit_test javatest') + +def configure(conf): + conf.load('java javatest') + +def build(bld): + + [ ... mainprog is built here ... ] + + bld(features = 'javac javatest', + srcdir = 'test/', + outdir = 'test', + sourcepath = ['test'], + classpath = [ 'src' ], + basedir = 'test', + use = ['JAVATEST', 'mainprog'], # mainprog is the program being tested in src/ + ut_str = 'java -cp ${CLASSPATH} ${JTRUNNER} ${SRC}', + jtest_source = bld.path.ant_glob('test/*.xml'), + ) + + +At command line the CLASSPATH where to find the testing environment and the +test runner (default TestNG) that will then be seen in the environment as +CLASSPATH_JAVATEST (then used for use) and JTRUNNER and can be used for +dependencies and ut_str generation. + +Example configure for TestNG: + waf configure --jtpath=/tmp/testng-6.12.jar:/tmp/jcommander-1.71.jar --jtrunner=org.testng.TestNG + or as default runner is TestNG: + waf configure --jtpath=/tmp/testng-6.12.jar:/tmp/jcommander-1.71.jar + +Example configure for JUnit: + waf configure --jtpath=/tmp/junit.jar --jtrunner=org.junit.runner.JUnitCore + +The runner class presence on the system is checked for at configuration stage. + +""" + +import os +from waflib import Task, TaskGen, Options + +@TaskGen.feature('javatest') +@TaskGen.after_method('apply_java', 'use_javac_files', 'set_classpath') +def make_javatest(self): + """ + Creates a ``utest`` task with a populated environment for Java Unit test execution + + """ + tsk = self.create_task('utest') + tsk.set_run_after(self.javac_task) + + # Put test input files as waf_unit_test relies on that for some prints and log generation + # If jtest_source is there, this is specially useful for passing XML for TestNG + # that contain test specification, use that as inputs, otherwise test sources + if getattr(self, 'jtest_source', None): + tsk.inputs = self.to_nodes(self.jtest_source) + else: + if self.javac_task.srcdir[0].exists(): + tsk.inputs = self.javac_task.srcdir[0].ant_glob('**/*.java', remove=False) + + if getattr(self, 'ut_str', None): + self.ut_run, lst = Task.compile_fun(self.ut_str, shell=getattr(self, 'ut_shell', False)) + tsk.vars = lst + tsk.vars + + if getattr(self, 'ut_cwd', None): + if isinstance(self.ut_cwd, str): + # we want a Node instance + if os.path.isabs(self.ut_cwd): + self.ut_cwd = self.bld.root.make_node(self.ut_cwd) + else: + self.ut_cwd = self.path.make_node(self.ut_cwd) + else: + self.ut_cwd = self.bld.bldnode + + # Get parent CLASSPATH and add output dir of test, we run from wscript dir + # We have to change it from list to the standard java -cp format (: separated) + tsk.env.CLASSPATH = ':'.join(self.env.CLASSPATH) + ':' + self.outdir.abspath() + + if not self.ut_cwd.exists(): + self.ut_cwd.mkdir() + + if not hasattr(self, 'ut_env'): + self.ut_env = dict(os.environ) + +def configure(ctx): + cp = ctx.env.CLASSPATH or '.' + if getattr(Options.options, 'jtpath', None): + ctx.env.CLASSPATH_JAVATEST = getattr(Options.options, 'jtpath').split(':') + cp += ':' + getattr(Options.options, 'jtpath') + + if getattr(Options.options, 'jtrunner', None): + ctx.env.JTRUNNER = getattr(Options.options, 'jtrunner') + + if ctx.check_java_class(ctx.env.JTRUNNER, with_classpath=cp): + ctx.fatal('Could not run test class %r' % ctx.env.JTRUNNER) + +def options(opt): + opt.add_option('--jtpath', action='store', default='', dest='jtpath', + help='Path to jar(s) needed for javatest execution, colon separated, if not in the system CLASSPATH') + opt.add_option('--jtrunner', action='store', default='org.testng.TestNG', dest='jtrunner', + help='Class to run javatest test [default: org.testng.TestNG]') + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/kde4.py b/ldb-2.0.8/third_party/waf/waflib/extras/kde4.py new file mode 100644 index 0000000..aed9bfb --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/kde4.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2006-2010 (ita) + +""" +Support for the KDE4 libraries and msgfmt +""" + +import os, re +from waflib import Task, Utils +from waflib.TaskGen import feature + +@feature('msgfmt') +def apply_msgfmt(self): + """ + Process all languages to create .mo files and to install them:: + + def build(bld): + bld(features='msgfmt', langs='es de fr', appname='myapp', install_path='${KDE4_LOCALE_INSTALL_DIR}') + """ + for lang in self.to_list(self.langs): + node = self.path.find_resource(lang+'.po') + task = self.create_task('msgfmt', node, node.change_ext('.mo')) + + langname = lang.split('/') + langname = langname[-1] + + inst = getattr(self, 'install_path', '${KDE4_LOCALE_INSTALL_DIR}') + + self.add_install_as( + inst_to = inst + os.sep + langname + os.sep + 'LC_MESSAGES' + os.sep + getattr(self, 'appname', 'set_your_appname') + '.mo', + inst_from = task.outputs[0], + chmod = getattr(self, 'chmod', Utils.O644)) + +class msgfmt(Task.Task): + """ + Transform .po files into .mo files + """ + color = 'BLUE' + run_str = '${MSGFMT} ${SRC} -o ${TGT}' + +def configure(self): + """ + Detect kde4-config and set various variables for the *use* system:: + + def options(opt): + opt.load('compiler_cxx kde4') + def configure(conf): + conf.load('compiler_cxx kde4') + def build(bld): + bld.program(source='main.c', target='app', use='KDECORE KIO KHTML') + """ + kdeconfig = self.find_program('kde4-config') + prefix = self.cmd_and_log(kdeconfig + ['--prefix']).strip() + fname = '%s/share/apps/cmake/modules/KDELibsDependencies.cmake' % prefix + try: + os.stat(fname) + except OSError: + fname = '%s/share/kde4/apps/cmake/modules/KDELibsDependencies.cmake' % prefix + try: + os.stat(fname) + except OSError: + self.fatal('could not open %s' % fname) + + try: + txt = Utils.readf(fname) + except EnvironmentError: + self.fatal('could not read %s' % fname) + + txt = txt.replace('\\\n', '\n') + fu = re.compile('#(.*)\n') + txt = fu.sub('', txt) + + setregexp = re.compile(r'([sS][eE][tT]\s*\()\s*([^\s]+)\s+\"([^"]+)\"\)') + found = setregexp.findall(txt) + + for (_, key, val) in found: + #print key, val + self.env[key] = val + + # well well, i could just write an interpreter for cmake files + self.env['LIB_KDECORE']= ['kdecore'] + self.env['LIB_KDEUI'] = ['kdeui'] + self.env['LIB_KIO'] = ['kio'] + self.env['LIB_KHTML'] = ['khtml'] + self.env['LIB_KPARTS'] = ['kparts'] + + self.env['LIBPATH_KDECORE'] = [os.path.join(self.env.KDE4_LIB_INSTALL_DIR, 'kde4', 'devel'), self.env.KDE4_LIB_INSTALL_DIR] + self.env['INCLUDES_KDECORE'] = [self.env['KDE4_INCLUDE_INSTALL_DIR']] + self.env.append_value('INCLUDES_KDECORE', [self.env['KDE4_INCLUDE_INSTALL_DIR']+ os.sep + 'KDE']) + + self.find_program('msgfmt', var='MSGFMT') + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/local_rpath.py b/ldb-2.0.8/third_party/waf/waflib/extras/local_rpath.py new file mode 100644 index 0000000..e3923d9 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/local_rpath.py @@ -0,0 +1,21 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2011 (ita) + +import copy +from waflib.TaskGen import after_method, feature + +@after_method('propagate_uselib_vars') +@feature('cprogram', 'cshlib', 'cxxprogram', 'cxxshlib', 'fcprogram', 'fcshlib') +def add_rpath_stuff(self): + all = copy.copy(self.to_list(getattr(self, 'use', []))) + while all: + name = all.pop() + try: + tg = self.bld.get_tgen_by_name(name) + except: + continue + if hasattr(tg, 'link_task'): + self.env.append_value('RPATH', tg.link_task.outputs[0].parent.abspath()) + all.extend(self.to_list(getattr(tg, 'use', []))) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/make.py b/ldb-2.0.8/third_party/waf/waflib/extras/make.py new file mode 100644 index 0000000..933d9ca --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/make.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2011 (ita) + +""" +A make-like way of executing the build, following the relationships between inputs/outputs + +This algorithm will lead to slower builds, will not be as flexible as "waf build", but +it might be useful for building data files (?) + +It is likely to break in the following cases: +- files are created dynamically (no inputs or outputs) +- headers +- building two files from different groups +""" + +import re +from waflib import Options, Task +from waflib.Build import BuildContext + +class MakeContext(BuildContext): + '''executes tasks in a step-by-step manner, following dependencies between inputs/outputs''' + cmd = 'make' + fun = 'build' + + def __init__(self, **kw): + super(MakeContext, self).__init__(**kw) + self.files = Options.options.files + + def get_build_iterator(self): + if not self.files: + while 1: + yield super(MakeContext, self).get_build_iterator() + + for g in self.groups: + for tg in g: + try: + f = tg.post + except AttributeError: + pass + else: + f() + + provides = {} + uses = {} + all_tasks = [] + tasks = [] + for pat in self.files.split(','): + matcher = self.get_matcher(pat) + for tg in g: + if isinstance(tg, Task.Task): + lst = [tg] + else: + lst = tg.tasks + for tsk in lst: + all_tasks.append(tsk) + + do_exec = False + for node in tsk.inputs: + try: + uses[node].append(tsk) + except: + uses[node] = [tsk] + + if matcher(node, output=False): + do_exec = True + break + + for node in tsk.outputs: + try: + provides[node].append(tsk) + except: + provides[node] = [tsk] + + if matcher(node, output=True): + do_exec = True + break + if do_exec: + tasks.append(tsk) + + # so we have the tasks that we need to process, the list of all tasks, + # the map of the tasks providing nodes, and the map of tasks using nodes + + if not tasks: + # if there are no tasks matching, return everything in the current group + result = all_tasks + else: + # this is like a big filter... + result = set() + seen = set() + cur = set(tasks) + while cur: + result |= cur + tosee = set() + for tsk in cur: + for node in tsk.inputs: + if node in seen: + continue + seen.add(node) + tosee |= set(provides.get(node, [])) + cur = tosee + result = list(result) + + Task.set_file_constraints(result) + Task.set_precedence_constraints(result) + yield result + + while 1: + yield [] + + def get_matcher(self, pat): + # this returns a function + inn = True + out = True + if pat.startswith('in:'): + out = False + pat = pat.replace('in:', '') + elif pat.startswith('out:'): + inn = False + pat = pat.replace('out:', '') + + anode = self.root.find_node(pat) + pattern = None + if not anode: + if not pat.startswith('^'): + pat = '^.+?%s' % pat + if not pat.endswith('$'): + pat = '%s$' % pat + pattern = re.compile(pat) + + def match(node, output): + if output and not out: + return False + if not output and not inn: + return False + + if anode: + return anode == node + else: + return pattern.match(node.abspath()) + return match + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/midl.py b/ldb-2.0.8/third_party/waf/waflib/extras/midl.py new file mode 100644 index 0000000..43e6cf9 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/midl.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python +# Issue 1185 ultrix gmail com + +""" +Microsoft Interface Definition Language support. Given ComObject.idl, this tool +will generate ComObject.tlb ComObject_i.h ComObject_i.c ComObject_p.c and dlldata.c + +To declare targets using midl:: + + def configure(conf): + conf.load('msvc') + conf.load('midl') + + def build(bld): + bld( + features='c cshlib', + # Note: ComObject_i.c is generated from ComObject.idl + source = 'main.c ComObject.idl ComObject_i.c', + target = 'ComObject.dll') +""" + +from waflib import Task, Utils +from waflib.TaskGen import feature, before_method +import os + +def configure(conf): + conf.find_program(['midl'], var='MIDL') + + conf.env.MIDLFLAGS = [ + '/nologo', + '/D', + '_DEBUG', + '/W1', + '/char', + 'signed', + '/Oicf', + ] + +@feature('c', 'cxx') +@before_method('process_source') +def idl_file(self): + # Do this before process_source so that the generated header can be resolved + # when scanning source dependencies. + idl_nodes = [] + src_nodes = [] + for node in Utils.to_list(self.source): + if str(node).endswith('.idl'): + idl_nodes.append(node) + else: + src_nodes.append(node) + + for node in self.to_nodes(idl_nodes): + t = node.change_ext('.tlb') + h = node.change_ext('_i.h') + c = node.change_ext('_i.c') + p = node.change_ext('_p.c') + d = node.parent.find_or_declare('dlldata.c') + self.create_task('midl', node, [t, h, c, p, d]) + + self.source = src_nodes + +class midl(Task.Task): + """ + Compile idl files + """ + color = 'YELLOW' + run_str = '${MIDL} ${MIDLFLAGS} ${CPPPATH_ST:INCLUDES} /tlb ${TGT[0].bldpath()} /header ${TGT[1].bldpath()} /iid ${TGT[2].bldpath()} /proxy ${TGT[3].bldpath()} /dlldata ${TGT[4].bldpath()} ${SRC}' + before = ['winrc'] + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/msvcdeps.py b/ldb-2.0.8/third_party/waf/waflib/extras/msvcdeps.py new file mode 100644 index 0000000..873a419 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/msvcdeps.py @@ -0,0 +1,251 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Copyright Garmin International or its subsidiaries, 2012-2013 + +''' +Off-load dependency scanning from Python code to MSVC compiler + +This tool is safe to load in any environment; it will only activate the +MSVC exploits when it finds that a particular taskgen uses MSVC to +compile. + +Empirical testing shows about a 10% execution time savings from using +this tool as compared to c_preproc. + +The technique of gutting scan() and pushing the dependency calculation +down to post_run() is cribbed from gccdeps.py. + +This affects the cxx class, so make sure to load Qt5 after this tool. + +Usage:: + + def options(opt): + opt.load('compiler_cxx') + def configure(conf): + conf.load('compiler_cxx msvcdeps') +''' + +import os, sys, tempfile, threading + +from waflib import Context, Errors, Logs, Task, Utils +from waflib.Tools import c_preproc, c, cxx, msvc +from waflib.TaskGen import feature, before_method + +lock = threading.Lock() +nodes = {} # Cache the path -> Node lookup + +PREPROCESSOR_FLAG = '/showIncludes' +INCLUDE_PATTERN = 'Note: including file:' + +# Extensible by outside tools +supported_compilers = ['msvc'] + +@feature('c', 'cxx') +@before_method('process_source') +def apply_msvcdeps_flags(taskgen): + if taskgen.env.CC_NAME not in supported_compilers: + return + + for flag in ('CFLAGS', 'CXXFLAGS'): + if taskgen.env.get_flat(flag).find(PREPROCESSOR_FLAG) < 0: + taskgen.env.append_value(flag, PREPROCESSOR_FLAG) + +def path_to_node(base_node, path, cached_nodes): + ''' + Take the base node and the path and return a node + Results are cached because searching the node tree is expensive + The following code is executed by threads, it is not safe, so a lock is needed... + ''' + # normalize the path because ant_glob() does not understand + # parent path components (..) + path = os.path.normpath(path) + + # normalize the path case to increase likelihood of a cache hit + path = os.path.normcase(path) + + # ant_glob interprets [] and () characters, so those must be replaced + path = path.replace('[', '?').replace(']', '?').replace('(', '[(]').replace(')', '[)]') + + node_lookup_key = (base_node, path) + + try: + node = cached_nodes[node_lookup_key] + except KeyError: + # retry with lock on cache miss + with lock: + try: + node = cached_nodes[node_lookup_key] + except KeyError: + node_list = base_node.ant_glob([path], ignorecase=True, remove=False, quiet=True, regex=False) + node = cached_nodes[node_lookup_key] = node_list[0] if node_list else None + + return node + +def post_run(self): + if self.env.CC_NAME not in supported_compilers: + return super(self.derived_msvcdeps, self).post_run() + + # TODO this is unlikely to work with netcache + if getattr(self, 'cached', None): + return Task.Task.post_run(self) + + bld = self.generator.bld + unresolved_names = [] + resolved_nodes = [] + + # Dynamically bind to the cache + try: + cached_nodes = bld.cached_nodes + except AttributeError: + cached_nodes = bld.cached_nodes = {} + + for path in self.msvcdeps_paths: + node = None + if os.path.isabs(path): + node = path_to_node(bld.root, path, cached_nodes) + else: + # when calling find_resource, make sure the path does not begin with '..' + base_node = bld.bldnode + path = [k for k in Utils.split_path(path) if k and k != '.'] + while path[0] == '..': + path.pop(0) + base_node = base_node.parent + path = os.sep.join(path) + + node = path_to_node(base_node, path, cached_nodes) + + if not node: + raise ValueError('could not find %r for %r' % (path, self)) + else: + if not c_preproc.go_absolute: + if not (node.is_child_of(bld.srcnode) or node.is_child_of(bld.bldnode)): + # System library + Logs.debug('msvcdeps: Ignoring system include %r', node) + continue + + if id(node) == id(self.inputs[0]): + # Self-dependency + continue + + resolved_nodes.append(node) + + bld.node_deps[self.uid()] = resolved_nodes + bld.raw_deps[self.uid()] = unresolved_names + + try: + del self.cache_sig + except AttributeError: + pass + + Task.Task.post_run(self) + +def scan(self): + if self.env.CC_NAME not in supported_compilers: + return super(self.derived_msvcdeps, self).scan() + + resolved_nodes = self.generator.bld.node_deps.get(self.uid(), []) + unresolved_names = [] + return (resolved_nodes, unresolved_names) + +def sig_implicit_deps(self): + if self.env.CC_NAME not in supported_compilers: + return super(self.derived_msvcdeps, self).sig_implicit_deps() + + try: + return Task.Task.sig_implicit_deps(self) + except Errors.WafError: + return Utils.SIG_NIL + +def exec_command(self, cmd, **kw): + if self.env.CC_NAME not in supported_compilers: + return super(self.derived_msvcdeps, self).exec_command(cmd, **kw) + + if not 'cwd' in kw: + kw['cwd'] = self.get_cwd() + + if self.env.PATH: + env = kw['env'] = dict(kw.get('env') or self.env.env or os.environ) + env['PATH'] = self.env.PATH if isinstance(self.env.PATH, str) else os.pathsep.join(self.env.PATH) + + # The Visual Studio IDE adds an environment variable that causes + # the MS compiler to send its textual output directly to the + # debugging window rather than normal stdout/stderr. + # + # This is unrecoverably bad for this tool because it will cause + # all the dependency scanning to see an empty stdout stream and + # assume that the file being compiled uses no headers. + # + # See http://blogs.msdn.com/b/freik/archive/2006/04/05/569025.aspx + # + # Attempting to repair the situation by deleting the offending + # envvar at this point in tool execution will not be good enough-- + # its presence poisons the 'waf configure' step earlier. We just + # want to put a sanity check here in order to help developers + # quickly diagnose the issue if an otherwise-good Waf tree + # is then executed inside the MSVS IDE. + assert 'VS_UNICODE_OUTPUT' not in kw['env'] + + cmd, args = self.split_argfile(cmd) + try: + (fd, tmp) = tempfile.mkstemp() + os.write(fd, '\r\n'.join(args).encode()) + os.close(fd) + + self.msvcdeps_paths = [] + kw['env'] = kw.get('env', os.environ.copy()) + kw['cwd'] = kw.get('cwd', os.getcwd()) + kw['quiet'] = Context.STDOUT + kw['output'] = Context.STDOUT + + out = [] + if Logs.verbose: + Logs.debug('argfile: @%r -> %r', tmp, args) + try: + raw_out = self.generator.bld.cmd_and_log(cmd + ['@' + tmp], **kw) + ret = 0 + except Errors.WafError as e: + # Use e.msg if e.stdout is not set + raw_out = getattr(e, 'stdout', e.msg) + + # Return non-zero error code even if we didn't + # get one from the exception object + ret = getattr(e, 'returncode', 1) + + for line in raw_out.splitlines(): + if line.startswith(INCLUDE_PATTERN): + inc_path = line[len(INCLUDE_PATTERN):].strip() + Logs.debug('msvcdeps: Regex matched %s', inc_path) + self.msvcdeps_paths.append(inc_path) + else: + out.append(line) + + # Pipe through the remaining stdout content (not related to /showIncludes) + if self.generator.bld.logger: + self.generator.bld.logger.debug('out: %s' % os.linesep.join(out)) + else: + sys.stdout.write(os.linesep.join(out) + os.linesep) + + return ret + finally: + try: + os.remove(tmp) + except OSError: + # anti-virus and indexers can keep files open -_- + pass + + +def wrap_compiled_task(classname): + derived_class = type(classname, (Task.classes[classname],), {}) + derived_class.derived_msvcdeps = derived_class + derived_class.post_run = post_run + derived_class.scan = scan + derived_class.sig_implicit_deps = sig_implicit_deps + derived_class.exec_command = exec_command + +for k in ('c', 'cxx'): + if k in Task.classes: + wrap_compiled_task(k) + +def options(opt): + raise ValueError('Do not load msvcdeps options') + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/msvs.py b/ldb-2.0.8/third_party/waf/waflib/extras/msvs.py new file mode 100644 index 0000000..8aa2db0 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/msvs.py @@ -0,0 +1,1048 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Avalanche Studios 2009-2011 +# Thomas Nagy 2011 + +""" +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +""" + +""" +To add this tool to your project: +def options(conf): + opt.load('msvs') + +It can be a good idea to add the sync_exec tool too. + +To generate solution files: +$ waf configure msvs + +To customize the outputs, provide subclasses in your wscript files:: + + from waflib.extras import msvs + class vsnode_target(msvs.vsnode_target): + def get_build_command(self, props): + # likely to be required + return "waf.bat build" + def collect_source(self): + # likely to be required + ... + class msvs_bar(msvs.msvs_generator): + def init(self): + msvs.msvs_generator.init(self) + self.vsnode_target = vsnode_target + +The msvs class re-uses the same build() function for reading the targets (task generators), +you may therefore specify msvs settings on the context object:: + + def build(bld): + bld.solution_name = 'foo.sln' + bld.waf_command = 'waf.bat' + bld.projects_dir = bld.srcnode.make_node('.depproj') + bld.projects_dir.mkdir() + +For visual studio 2008, the command is called 'msvs2008', and the classes +such as vsnode_target are wrapped by a decorator class 'wrap_2008' to +provide special functionality. + +To customize platform toolsets, pass additional parameters, for example:: + + class msvs_2013(msvs.msvs_generator): + cmd = 'msvs2013' + numver = '13.00' + vsver = '2013' + platform_toolset_ver = 'v120' + +ASSUMPTIONS: +* a project can be either a directory or a target, vcxproj files are written only for targets that have source files +* each project is a vcxproj file, therefore the project uuid needs only to be a hash of the absolute path +""" + +import os, re, sys +import uuid # requires python 2.5 +from waflib.Build import BuildContext +from waflib import Utils, TaskGen, Logs, Task, Context, Node, Options + +HEADERS_GLOB = '**/(*.h|*.hpp|*.H|*.inl)' + +PROJECT_TEMPLATE = r''' + + + + ${for b in project.build_properties} + + ${b.configuration} + ${b.platform} + + ${endfor} + + + + {${project.uuid}} + MakeFileProj + ${project.name} + + + + ${for b in project.build_properties} + + Makefile + ${b.outdir} + ${project.platform_toolset_ver} + + ${endfor} + + + + + + ${for b in project.build_properties} + + + + ${endfor} + + ${for b in project.build_properties} + + ${xml:project.get_build_command(b)} + ${xml:project.get_rebuild_command(b)} + ${xml:project.get_clean_command(b)} + ${xml:b.includes_search_path} + ${xml:b.preprocessor_definitions};$(NMakePreprocessorDefinitions) + ${xml:b.includes_search_path} + $(ExecutablePath) + + ${if getattr(b, 'output_file', None)} + ${xml:b.output_file} + ${endif} + ${if getattr(b, 'deploy_dir', None)} + ${xml:b.deploy_dir} + ${endif} + + ${endfor} + + ${for b in project.build_properties} + ${if getattr(b, 'deploy_dir', None)} + + + CopyToHardDrive + + + ${endif} + ${endfor} + + + ${for x in project.source} + <${project.get_key(x)} Include='${x.win32path()}' /> + ${endfor} + + + + + +''' + +FILTER_TEMPLATE = ''' + + + ${for x in project.source} + <${project.get_key(x)} Include="${x.win32path()}"> + ${project.get_filter_name(x.parent)} + + ${endfor} + + + ${for x in project.dirs()} + + {${project.make_uuid(x.win32path())}} + + ${endfor} + + +''' + +PROJECT_2008_TEMPLATE = r''' + + + ${if project.build_properties} + ${for b in project.build_properties} + + ${endfor} + ${else} + + ${endif} + + + + + ${if project.build_properties} + ${for b in project.build_properties} + + + + ${endfor} + ${else} + + + ${endif} + + + + +${project.display_filter()} + + +''' + +SOLUTION_TEMPLATE = '''Microsoft Visual Studio Solution File, Format Version ${project.numver} +# Visual Studio ${project.vsver} +${for p in project.all_projects} +Project("{${p.ptype()}}") = "${p.name}", "${p.title}", "{${p.uuid}}" +EndProject${endfor} +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + ${if project.all_projects} + ${for (configuration, platform) in project.all_projects[0].ctx.project_configurations()} + ${configuration}|${platform} = ${configuration}|${platform} + ${endfor} + ${endif} + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + ${for p in project.all_projects} + ${if hasattr(p, 'source')} + ${for b in p.build_properties} + {${p.uuid}}.${b.configuration}|${b.platform}.ActiveCfg = ${b.configuration}|${b.platform} + ${if getattr(p, 'is_active', None)} + {${p.uuid}}.${b.configuration}|${b.platform}.Build.0 = ${b.configuration}|${b.platform} + ${endif} + ${if getattr(p, 'is_deploy', None)} + {${p.uuid}}.${b.configuration}|${b.platform}.Deploy.0 = ${b.configuration}|${b.platform} + ${endif} + ${endfor} + ${endif} + ${endfor} + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + ${for p in project.all_projects} + ${if p.parent} + {${p.uuid}} = {${p.parent.uuid}} + ${endif} + ${endfor} + EndGlobalSection +EndGlobal +''' + +COMPILE_TEMPLATE = '''def f(project): + lst = [] + def xml_escape(value): + return value.replace("&", "&").replace('"', """).replace("'", "'").replace("<", "<").replace(">", ">") + + %s + + #f = open('cmd.txt', 'w') + #f.write(str(lst)) + #f.close() + return ''.join(lst) +''' +reg_act = re.compile(r"(?P\\)|(?P\$\$)|(?P\$\{(?P[^}]*?)\})", re.M) +def compile_template(line): + """ + Compile a template expression into a python function (like jsps, but way shorter) + """ + extr = [] + def repl(match): + g = match.group + if g('dollar'): + return "$" + elif g('backslash'): + return "\\" + elif g('subst'): + extr.append(g('code')) + return "<<|@|>>" + return None + + line2 = reg_act.sub(repl, line) + params = line2.split('<<|@|>>') + assert(extr) + + + indent = 0 + buf = [] + app = buf.append + + def app(txt): + buf.append(indent * '\t' + txt) + + for x in range(len(extr)): + if params[x]: + app("lst.append(%r)" % params[x]) + + f = extr[x] + if f.startswith(('if', 'for')): + app(f + ':') + indent += 1 + elif f.startswith('py:'): + app(f[3:]) + elif f.startswith(('endif', 'endfor')): + indent -= 1 + elif f.startswith(('else', 'elif')): + indent -= 1 + app(f + ':') + indent += 1 + elif f.startswith('xml:'): + app('lst.append(xml_escape(%s))' % f[4:]) + else: + #app('lst.append((%s) or "cannot find %s")' % (f, f)) + app('lst.append(%s)' % f) + + if extr: + if params[-1]: + app("lst.append(%r)" % params[-1]) + + fun = COMPILE_TEMPLATE % "\n\t".join(buf) + #print(fun) + return Task.funex(fun) + + +re_blank = re.compile('(\n|\r|\\s)*\n', re.M) +def rm_blank_lines(txt): + txt = re_blank.sub('\r\n', txt) + return txt + +BOM = '\xef\xbb\xbf' +try: + BOM = bytes(BOM, 'latin-1') # python 3 +except TypeError: + pass + +def stealth_write(self, data, flags='wb'): + try: + unicode + except NameError: + data = data.encode('utf-8') # python 3 + else: + data = data.decode(sys.getfilesystemencoding(), 'replace') + data = data.encode('utf-8') + + if self.name.endswith(('.vcproj', '.vcxproj')): + data = BOM + data + + try: + txt = self.read(flags='rb') + if txt != data: + raise ValueError('must write') + except (IOError, ValueError): + self.write(data, flags=flags) + else: + Logs.debug('msvs: skipping %s', self.win32path()) +Node.Node.stealth_write = stealth_write + +re_win32 = re.compile(r'^([/\\]cygdrive)?[/\\]([a-z])([^a-z0-9_-].*)', re.I) +def win32path(self): + p = self.abspath() + m = re_win32.match(p) + if m: + return "%s:%s" % (m.group(2).upper(), m.group(3)) + return p +Node.Node.win32path = win32path + +re_quote = re.compile("[^a-zA-Z0-9-]") +def quote(s): + return re_quote.sub("_", s) + +def xml_escape(value): + return value.replace("&", "&").replace('"', """).replace("'", "'").replace("<", "<").replace(">", ">") + +def make_uuid(v, prefix = None): + """ + simple utility function + """ + if isinstance(v, dict): + keys = list(v.keys()) + keys.sort() + tmp = str([(k, v[k]) for k in keys]) + else: + tmp = str(v) + d = Utils.md5(tmp.encode()).hexdigest().upper() + if prefix: + d = '%s%s' % (prefix, d[8:]) + gid = uuid.UUID(d, version = 4) + return str(gid).upper() + +def diff(node, fromnode): + # difference between two nodes, but with "(..)" instead of ".." + c1 = node + c2 = fromnode + + c1h = c1.height() + c2h = c2.height() + + lst = [] + up = 0 + + while c1h > c2h: + lst.append(c1.name) + c1 = c1.parent + c1h -= 1 + + while c2h > c1h: + up += 1 + c2 = c2.parent + c2h -= 1 + + while id(c1) != id(c2): + lst.append(c1.name) + up += 1 + + c1 = c1.parent + c2 = c2.parent + + for i in range(up): + lst.append('(..)') + lst.reverse() + return tuple(lst) + +class build_property(object): + pass + +class vsnode(object): + """ + Abstract class representing visual studio elements + We assume that all visual studio nodes have a uuid and a parent + """ + def __init__(self, ctx): + self.ctx = ctx # msvs context + self.name = '' # string, mandatory + self.vspath = '' # path in visual studio (name for dirs, absolute path for projects) + self.uuid = '' # string, mandatory + self.parent = None # parent node for visual studio nesting + + def get_waf(self): + """ + Override in subclasses... + """ + return 'cd /d "%s" & %s' % (self.ctx.srcnode.win32path(), getattr(self.ctx, 'waf_command', 'waf.bat')) + + def ptype(self): + """ + Return a special uuid for projects written in the solution file + """ + pass + + def write(self): + """ + Write the project file, by default, do nothing + """ + pass + + def make_uuid(self, val): + """ + Alias for creating uuid values easily (the templates cannot access global variables) + """ + return make_uuid(val) + +class vsnode_vsdir(vsnode): + """ + Nodes representing visual studio folders (which do not match the filesystem tree!) + """ + VS_GUID_SOLUTIONFOLDER = "2150E333-8FDC-42A3-9474-1A3956D46DE8" + def __init__(self, ctx, uuid, name, vspath=''): + vsnode.__init__(self, ctx) + self.title = self.name = name + self.uuid = uuid + self.vspath = vspath or name + + def ptype(self): + return self.VS_GUID_SOLUTIONFOLDER + +class vsnode_project(vsnode): + """ + Abstract class representing visual studio project elements + A project is assumed to be writable, and has a node representing the file to write to + """ + VS_GUID_VCPROJ = "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942" + def ptype(self): + return self.VS_GUID_VCPROJ + + def __init__(self, ctx, node): + vsnode.__init__(self, ctx) + self.path = node + self.uuid = make_uuid(node.win32path()) + self.name = node.name + self.platform_toolset_ver = getattr(ctx, 'platform_toolset_ver', None) + self.title = self.path.win32path() + self.source = [] # list of node objects + self.build_properties = [] # list of properties (nmake commands, output dir, etc) + + def dirs(self): + """ + Get the list of parent folders of the source files (header files included) + for writing the filters + """ + lst = [] + def add(x): + if x.height() > self.tg.path.height() and x not in lst: + lst.append(x) + add(x.parent) + for x in self.source: + add(x.parent) + return lst + + def write(self): + Logs.debug('msvs: creating %r', self.path) + + # first write the project file + template1 = compile_template(PROJECT_TEMPLATE) + proj_str = template1(self) + proj_str = rm_blank_lines(proj_str) + self.path.stealth_write(proj_str) + + # then write the filter + template2 = compile_template(FILTER_TEMPLATE) + filter_str = template2(self) + filter_str = rm_blank_lines(filter_str) + tmp = self.path.parent.make_node(self.path.name + '.filters') + tmp.stealth_write(filter_str) + + def get_key(self, node): + """ + required for writing the source files + """ + name = node.name + if name.endswith(('.cpp', '.c')): + return 'ClCompile' + return 'ClInclude' + + def collect_properties(self): + """ + Returns a list of triplet (configuration, platform, output_directory) + """ + ret = [] + for c in self.ctx.configurations: + for p in self.ctx.platforms: + x = build_property() + x.outdir = '' + + x.configuration = c + x.platform = p + + x.preprocessor_definitions = '' + x.includes_search_path = '' + + # can specify "deploy_dir" too + ret.append(x) + self.build_properties = ret + + def get_build_params(self, props): + opt = '--execsolution=%s' % self.ctx.get_solution_node().win32path() + return (self.get_waf(), opt) + + def get_build_command(self, props): + return "%s build %s" % self.get_build_params(props) + + def get_clean_command(self, props): + return "%s clean %s" % self.get_build_params(props) + + def get_rebuild_command(self, props): + return "%s clean build %s" % self.get_build_params(props) + + def get_filter_name(self, node): + lst = diff(node, self.tg.path) + return '\\'.join(lst) or '.' + +class vsnode_alias(vsnode_project): + def __init__(self, ctx, node, name): + vsnode_project.__init__(self, ctx, node) + self.name = name + self.output_file = '' + +class vsnode_build_all(vsnode_alias): + """ + Fake target used to emulate the behaviour of "make all" (starting one process by target is slow) + This is the only alias enabled by default + """ + def __init__(self, ctx, node, name='build_all_projects'): + vsnode_alias.__init__(self, ctx, node, name) + self.is_active = True + +class vsnode_install_all(vsnode_alias): + """ + Fake target used to emulate the behaviour of "make install" + """ + def __init__(self, ctx, node, name='install_all_projects'): + vsnode_alias.__init__(self, ctx, node, name) + + def get_build_command(self, props): + return "%s build install %s" % self.get_build_params(props) + + def get_clean_command(self, props): + return "%s clean %s" % self.get_build_params(props) + + def get_rebuild_command(self, props): + return "%s clean build install %s" % self.get_build_params(props) + +class vsnode_project_view(vsnode_alias): + """ + Fake target used to emulate a file system view + """ + def __init__(self, ctx, node, name='project_view'): + vsnode_alias.__init__(self, ctx, node, name) + self.tg = self.ctx() # fake one, cannot remove + self.exclude_files = Node.exclude_regs + ''' +waf-2* +waf3-2*/** +.waf-2* +.waf3-2*/** +**/*.sdf +**/*.suo +**/*.ncb +**/%s + ''' % Options.lockfile + + def collect_source(self): + # this is likely to be slow + self.source = self.ctx.srcnode.ant_glob('**', excl=self.exclude_files) + + def get_build_command(self, props): + params = self.get_build_params(props) + (self.ctx.cmd,) + return "%s %s %s" % params + + def get_clean_command(self, props): + return "" + + def get_rebuild_command(self, props): + return self.get_build_command(props) + +class vsnode_target(vsnode_project): + """ + Visual studio project representing a targets (programs, libraries, etc) and bound + to a task generator + """ + def __init__(self, ctx, tg): + """ + A project is more or less equivalent to a file/folder + """ + base = getattr(ctx, 'projects_dir', None) or tg.path + node = base.make_node(quote(tg.name) + ctx.project_extension) # the project file as a Node + vsnode_project.__init__(self, ctx, node) + self.name = quote(tg.name) + self.tg = tg # task generator + + def get_build_params(self, props): + """ + Override the default to add the target name + """ + opt = '--execsolution=%s' % self.ctx.get_solution_node().win32path() + if getattr(self, 'tg', None): + opt += " --targets=%s" % self.tg.name + return (self.get_waf(), opt) + + def collect_source(self): + tg = self.tg + source_files = tg.to_nodes(getattr(tg, 'source', [])) + include_dirs = Utils.to_list(getattr(tg, 'msvs_includes', [])) + include_files = [] + for x in include_dirs: + if isinstance(x, str): + x = tg.path.find_node(x) + if x: + lst = [y for y in x.ant_glob(HEADERS_GLOB, flat=False)] + include_files.extend(lst) + + # remove duplicates + self.source.extend(list(set(source_files + include_files))) + self.source.sort(key=lambda x: x.win32path()) + + def collect_properties(self): + """ + Visual studio projects are associated with platforms and configurations (for building especially) + """ + super(vsnode_target, self).collect_properties() + for x in self.build_properties: + x.outdir = self.path.parent.win32path() + x.preprocessor_definitions = '' + x.includes_search_path = '' + + try: + tsk = self.tg.link_task + except AttributeError: + pass + else: + x.output_file = tsk.outputs[0].win32path() + x.preprocessor_definitions = ';'.join(tsk.env.DEFINES) + x.includes_search_path = ';'.join(self.tg.env.INCPATHS) + +class msvs_generator(BuildContext): + '''generates a visual studio 2010 solution''' + cmd = 'msvs' + fun = 'build' + numver = '11.00' # Visual Studio Version Number + vsver = '2010' # Visual Studio Version Year + platform_toolset_ver = 'v110' # Platform Toolset Version Number + + def init(self): + """ + Some data that needs to be present + """ + if not getattr(self, 'configurations', None): + self.configurations = ['Release'] # LocalRelease, RemoteDebug, etc + if not getattr(self, 'platforms', None): + self.platforms = ['Win32'] + if not getattr(self, 'all_projects', None): + self.all_projects = [] + if not getattr(self, 'project_extension', None): + self.project_extension = '.vcxproj' + if not getattr(self, 'projects_dir', None): + self.projects_dir = self.srcnode.make_node('.depproj') + self.projects_dir.mkdir() + + # bind the classes to the object, so that subclass can provide custom generators + if not getattr(self, 'vsnode_vsdir', None): + self.vsnode_vsdir = vsnode_vsdir + if not getattr(self, 'vsnode_target', None): + self.vsnode_target = vsnode_target + if not getattr(self, 'vsnode_build_all', None): + self.vsnode_build_all = vsnode_build_all + if not getattr(self, 'vsnode_install_all', None): + self.vsnode_install_all = vsnode_install_all + if not getattr(self, 'vsnode_project_view', None): + self.vsnode_project_view = vsnode_project_view + + self.numver = self.__class__.numver + self.vsver = self.__class__.vsver + self.platform_toolset_ver = self.__class__.platform_toolset_ver + + def execute(self): + """ + Entry point + """ + self.restore() + if not self.all_envs: + self.load_envs() + self.recurse([self.run_dir]) + + # user initialization + self.init() + + # two phases for creating the solution + self.collect_projects() # add project objects into "self.all_projects" + self.write_files() # write the corresponding project and solution files + + def collect_projects(self): + """ + Fill the list self.all_projects with project objects + Fill the list of build targets + """ + self.collect_targets() + self.add_aliases() + self.collect_dirs() + default_project = getattr(self, 'default_project', None) + def sortfun(x): + if x.name == default_project: + return '' + return getattr(x, 'path', None) and x.path.win32path() or x.name + self.all_projects.sort(key=sortfun) + + def write_files(self): + """ + Write the project and solution files from the data collected + so far. It is unlikely that you will want to change this + """ + for p in self.all_projects: + p.write() + + # and finally write the solution file + node = self.get_solution_node() + node.parent.mkdir() + Logs.warn('Creating %r', node) + template1 = compile_template(SOLUTION_TEMPLATE) + sln_str = template1(self) + sln_str = rm_blank_lines(sln_str) + node.stealth_write(sln_str) + + def get_solution_node(self): + """ + The solution filename is required when writing the .vcproj files + return self.solution_node and if it does not exist, make one + """ + try: + return self.solution_node + except AttributeError: + pass + + solution_name = getattr(self, 'solution_name', None) + if not solution_name: + solution_name = getattr(Context.g_module, Context.APPNAME, 'project') + '.sln' + if os.path.isabs(solution_name): + self.solution_node = self.root.make_node(solution_name) + else: + self.solution_node = self.srcnode.make_node(solution_name) + return self.solution_node + + def project_configurations(self): + """ + Helper that returns all the pairs (config,platform) + """ + ret = [] + for c in self.configurations: + for p in self.platforms: + ret.append((c, p)) + return ret + + def collect_targets(self): + """ + Process the list of task generators + """ + for g in self.groups: + for tg in g: + if not isinstance(tg, TaskGen.task_gen): + continue + + if not hasattr(tg, 'msvs_includes'): + tg.msvs_includes = tg.to_list(getattr(tg, 'includes', [])) + tg.to_list(getattr(tg, 'export_includes', [])) + tg.post() + if not getattr(tg, 'link_task', None): + continue + + p = self.vsnode_target(self, tg) + p.collect_source() # delegate this processing + p.collect_properties() + self.all_projects.append(p) + + def add_aliases(self): + """ + Add a specific target that emulates the "make all" necessary for Visual studio when pressing F7 + We also add an alias for "make install" (disabled by default) + """ + base = getattr(self, 'projects_dir', None) or self.tg.path + + node_project = base.make_node('build_all_projects' + self.project_extension) # Node + p_build = self.vsnode_build_all(self, node_project) + p_build.collect_properties() + self.all_projects.append(p_build) + + node_project = base.make_node('install_all_projects' + self.project_extension) # Node + p_install = self.vsnode_install_all(self, node_project) + p_install.collect_properties() + self.all_projects.append(p_install) + + node_project = base.make_node('project_view' + self.project_extension) # Node + p_view = self.vsnode_project_view(self, node_project) + p_view.collect_source() + p_view.collect_properties() + self.all_projects.append(p_view) + + n = self.vsnode_vsdir(self, make_uuid(self.srcnode.win32path() + 'build_aliases'), "build_aliases") + p_build.parent = p_install.parent = p_view.parent = n + self.all_projects.append(n) + + def collect_dirs(self): + """ + Create the folder structure in the Visual studio project view + """ + seen = {} + def make_parents(proj): + # look at a project, try to make a parent + if getattr(proj, 'parent', None): + # aliases already have parents + return + x = proj.iter_path + if x in seen: + proj.parent = seen[x] + return + + # There is not vsnode_vsdir for x. + # So create a project representing the folder "x" + n = proj.parent = seen[x] = self.vsnode_vsdir(self, make_uuid(x.win32path()), x.name) + n.iter_path = x.parent + self.all_projects.append(n) + + # recurse up to the project directory + if x.height() > self.srcnode.height() + 1: + make_parents(n) + + for p in self.all_projects[:]: # iterate over a copy of all projects + if not getattr(p, 'tg', None): + # but only projects that have a task generator + continue + + # make a folder for each task generator + p.iter_path = p.tg.path + make_parents(p) + +def wrap_2008(cls): + class dec(cls): + def __init__(self, *k, **kw): + cls.__init__(self, *k, **kw) + self.project_template = PROJECT_2008_TEMPLATE + + def display_filter(self): + + root = build_property() + root.subfilters = [] + root.sourcefiles = [] + root.source = [] + root.name = '' + + @Utils.run_once + def add_path(lst): + if not lst: + return root + child = build_property() + child.subfilters = [] + child.sourcefiles = [] + child.source = [] + child.name = lst[-1] + + par = add_path(lst[:-1]) + par.subfilters.append(child) + return child + + for x in self.source: + # this crap is for enabling subclasses to override get_filter_name + tmp = self.get_filter_name(x.parent) + tmp = tmp != '.' and tuple(tmp.split('\\')) or () + par = add_path(tmp) + par.source.append(x) + + def display(n): + buf = [] + for x in n.source: + buf.append('\n' % (xml_escape(x.win32path()), self.get_key(x))) + for x in n.subfilters: + buf.append('' % xml_escape(x.name)) + buf.append(display(x)) + buf.append('') + return '\n'.join(buf) + + return display(root) + + def get_key(self, node): + """ + If you do not want to let visual studio use the default file extensions, + override this method to return a value: + 0: C/C++ Code, 1: C++ Class, 2: C++ Header File, 3: C++ Form, + 4: C++ Control, 5: Text File, 6: DEF File, 7: IDL File, + 8: Makefile, 9: RGS File, 10: RC File, 11: RES File, 12: XSD File, + 13: XML File, 14: HTML File, 15: CSS File, 16: Bitmap, 17: Icon, + 18: Resx File, 19: BSC File, 20: XSX File, 21: C++ Web Service, + 22: ASAX File, 23: Asp Page, 24: Document, 25: Discovery File, + 26: C# File, 27: eFileTypeClassDiagram, 28: MHTML Document, + 29: Property Sheet, 30: Cursor, 31: Manifest, 32: eFileTypeRDLC + """ + return '' + + def write(self): + Logs.debug('msvs: creating %r', self.path) + template1 = compile_template(self.project_template) + proj_str = template1(self) + proj_str = rm_blank_lines(proj_str) + self.path.stealth_write(proj_str) + + return dec + +class msvs_2008_generator(msvs_generator): + '''generates a visual studio 2008 solution''' + cmd = 'msvs2008' + fun = msvs_generator.fun + numver = '10.00' + vsver = '2008' + + def init(self): + if not getattr(self, 'project_extension', None): + self.project_extension = '_2008.vcproj' + if not getattr(self, 'solution_name', None): + self.solution_name = getattr(Context.g_module, Context.APPNAME, 'project') + '_2008.sln' + + if not getattr(self, 'vsnode_target', None): + self.vsnode_target = wrap_2008(vsnode_target) + if not getattr(self, 'vsnode_build_all', None): + self.vsnode_build_all = wrap_2008(vsnode_build_all) + if not getattr(self, 'vsnode_install_all', None): + self.vsnode_install_all = wrap_2008(vsnode_install_all) + if not getattr(self, 'vsnode_project_view', None): + self.vsnode_project_view = wrap_2008(vsnode_project_view) + + msvs_generator.init(self) + +def options(ctx): + """ + If the msvs option is used, try to detect if the build is made from visual studio + """ + ctx.add_option('--execsolution', action='store', help='when building with visual studio, use a build state file') + + old = BuildContext.execute + def override_build_state(ctx): + def lock(rm, add): + uns = ctx.options.execsolution.replace('.sln', rm) + uns = ctx.root.make_node(uns) + try: + uns.delete() + except OSError: + pass + + uns = ctx.options.execsolution.replace('.sln', add) + uns = ctx.root.make_node(uns) + try: + uns.write('') + except EnvironmentError: + pass + + if ctx.options.execsolution: + ctx.launch_dir = Context.top_dir # force a build for the whole project (invalid cwd when called by visual studio) + lock('.lastbuildstate', '.unsuccessfulbuild') + old(ctx) + lock('.unsuccessfulbuild', '.lastbuildstate') + else: + old(ctx) + BuildContext.execute = override_build_state + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/netcache_client.py b/ldb-2.0.8/third_party/waf/waflib/extras/netcache_client.py new file mode 100644 index 0000000..dc49048 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/netcache_client.py @@ -0,0 +1,390 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2011-2015 (ita) + +""" +A client for the network cache (playground/netcache/). Launch the server with: +./netcache_server, then use it for the builds by adding the following: + + def build(bld): + bld.load('netcache_client') + +The parameters should be present in the environment in the form: + NETCACHE=host:port waf configure build + +Or in a more detailed way: + NETCACHE_PUSH=host:port NETCACHE_PULL=host:port waf configure build + +where: + host: host where the server resides, by default localhost + port: by default push on 11001 and pull on 12001 + +Use the server provided in playground/netcache/Netcache.java +""" + +import os, socket, time, atexit, sys +from waflib import Task, Logs, Utils, Build, Runner +from waflib.Configure import conf + +BUF = 8192 * 16 +HEADER_SIZE = 128 +MODES = ['PUSH', 'PULL', 'PUSH_PULL'] +STALE_TIME = 30 # seconds + +GET = 'GET' +PUT = 'PUT' +LST = 'LST' +BYE = 'BYE' + +all_sigs_in_cache = (0.0, []) + +def put_data(conn, data): + if sys.hexversion > 0x3000000: + data = data.encode('latin-1') + cnt = 0 + while cnt < len(data): + sent = conn.send(data[cnt:]) + if sent == 0: + raise RuntimeError('connection ended') + cnt += sent + +push_connections = Runner.Queue(0) +pull_connections = Runner.Queue(0) +def get_connection(push=False): + # return a new connection... do not forget to release it! + try: + if push: + ret = push_connections.get(block=False) + else: + ret = pull_connections.get(block=False) + except Exception: + ret = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + if push: + ret.connect(Task.push_addr) + else: + ret.connect(Task.pull_addr) + return ret + +def release_connection(conn, msg='', push=False): + if conn: + if push: + push_connections.put(conn) + else: + pull_connections.put(conn) + +def close_connection(conn, msg=''): + if conn: + data = '%s,%s' % (BYE, msg) + try: + put_data(conn, data.ljust(HEADER_SIZE)) + except: + pass + try: + conn.close() + except: + pass + +def close_all(): + for q in (push_connections, pull_connections): + while q.qsize(): + conn = q.get() + try: + close_connection(conn) + except: + # ignore errors when cleaning up + pass +atexit.register(close_all) + +def read_header(conn): + cnt = 0 + buf = [] + while cnt < HEADER_SIZE: + data = conn.recv(HEADER_SIZE - cnt) + if not data: + #import traceback + #traceback.print_stack() + raise ValueError('connection ended when reading a header %r' % buf) + buf.append(data) + cnt += len(data) + if sys.hexversion > 0x3000000: + ret = ''.encode('latin-1').join(buf) + ret = ret.decode('latin-1') + else: + ret = ''.join(buf) + return ret + +def check_cache(conn, ssig): + """ + List the files on the server, this is an optimization because it assumes that + concurrent builds are rare + """ + global all_sigs_in_cache + if not STALE_TIME: + return + if time.time() - all_sigs_in_cache[0] > STALE_TIME: + + params = (LST,'') + put_data(conn, ','.join(params).ljust(HEADER_SIZE)) + + # read what is coming back + ret = read_header(conn) + size = int(ret.split(',')[0]) + + buf = [] + cnt = 0 + while cnt < size: + data = conn.recv(min(BUF, size-cnt)) + if not data: + raise ValueError('connection ended %r %r' % (cnt, size)) + buf.append(data) + cnt += len(data) + + if sys.hexversion > 0x3000000: + ret = ''.encode('latin-1').join(buf) + ret = ret.decode('latin-1') + else: + ret = ''.join(buf) + + all_sigs_in_cache = (time.time(), ret.splitlines()) + Logs.debug('netcache: server cache has %r entries', len(all_sigs_in_cache[1])) + + if not ssig in all_sigs_in_cache[1]: + raise ValueError('no file %s in cache' % ssig) + +class MissingFile(Exception): + pass + +def recv_file(conn, ssig, count, p): + check_cache(conn, ssig) + + params = (GET, ssig, str(count)) + put_data(conn, ','.join(params).ljust(HEADER_SIZE)) + data = read_header(conn) + + size = int(data.split(',')[0]) + + if size == -1: + raise MissingFile('no file %s - %s in cache' % (ssig, count)) + + # get the file, writing immediately + # TODO a tmp file would be better + f = open(p, 'wb') + cnt = 0 + while cnt < size: + data = conn.recv(min(BUF, size-cnt)) + if not data: + raise ValueError('connection ended %r %r' % (cnt, size)) + f.write(data) + cnt += len(data) + f.close() + +def sock_send(conn, ssig, cnt, p): + #print "pushing %r %r %r" % (ssig, cnt, p) + size = os.stat(p).st_size + params = (PUT, ssig, str(cnt), str(size)) + put_data(conn, ','.join(params).ljust(HEADER_SIZE)) + f = open(p, 'rb') + cnt = 0 + while cnt < size: + r = f.read(min(BUF, size-cnt)) + while r: + k = conn.send(r) + if not k: + raise ValueError('connection ended') + cnt += k + r = r[k:] + +def can_retrieve_cache(self): + if not Task.pull_addr: + return False + if not self.outputs: + return False + self.cached = False + + cnt = 0 + sig = self.signature() + ssig = Utils.to_hex(self.uid() + sig) + + conn = None + err = False + try: + try: + conn = get_connection() + for node in self.outputs: + p = node.abspath() + recv_file(conn, ssig, cnt, p) + cnt += 1 + except MissingFile as e: + Logs.debug('netcache: file is not in the cache %r', e) + err = True + except Exception as e: + Logs.debug('netcache: could not get the files %r', self.outputs) + if Logs.verbose > 1: + Logs.debug('netcache: exception %r', e) + err = True + + # broken connection? remove this one + close_connection(conn) + conn = None + else: + Logs.debug('netcache: obtained %r from cache', self.outputs) + + finally: + release_connection(conn) + if err: + return False + + self.cached = True + return True + +@Utils.run_once +def put_files_cache(self): + if not Task.push_addr: + return + if not self.outputs: + return + if getattr(self, 'cached', None): + return + + #print "called put_files_cache", id(self) + bld = self.generator.bld + sig = self.signature() + ssig = Utils.to_hex(self.uid() + sig) + + conn = None + cnt = 0 + try: + for node in self.outputs: + # We could re-create the signature of the task with the signature of the outputs + # in practice, this means hashing the output files + # this is unnecessary + try: + if not conn: + conn = get_connection(push=True) + sock_send(conn, ssig, cnt, node.abspath()) + Logs.debug('netcache: sent %r', node) + except Exception as e: + Logs.debug('netcache: could not push the files %r', e) + + # broken connection? remove this one + close_connection(conn) + conn = None + cnt += 1 + finally: + release_connection(conn, push=True) + + bld.task_sigs[self.uid()] = self.cache_sig + +def hash_env_vars(self, env, vars_lst): + # reimplement so that the resulting hash does not depend on local paths + if not env.table: + env = env.parent + if not env: + return Utils.SIG_NIL + + idx = str(id(env)) + str(vars_lst) + try: + cache = self.cache_env + except AttributeError: + cache = self.cache_env = {} + else: + try: + return self.cache_env[idx] + except KeyError: + pass + + v = str([env[a] for a in vars_lst]) + v = v.replace(self.srcnode.abspath().__repr__()[:-1], '') + m = Utils.md5() + m.update(v.encode()) + ret = m.digest() + + Logs.debug('envhash: %r %r', ret, v) + + cache[idx] = ret + + return ret + +def uid(self): + # reimplement so that the signature does not depend on local paths + try: + return self.uid_ + except AttributeError: + m = Utils.md5() + src = self.generator.bld.srcnode + up = m.update + up(self.__class__.__name__.encode()) + for x in self.inputs + self.outputs: + up(x.path_from(src).encode()) + self.uid_ = m.digest() + return self.uid_ + + +def make_cached(cls): + if getattr(cls, 'nocache', None): + return + + m1 = cls.run + def run(self): + if getattr(self, 'nocache', False): + return m1(self) + if self.can_retrieve_cache(): + return 0 + return m1(self) + cls.run = run + + m2 = cls.post_run + def post_run(self): + if getattr(self, 'nocache', False): + return m2(self) + bld = self.generator.bld + ret = m2(self) + if bld.cache_global: + self.put_files_cache() + if hasattr(self, 'chmod'): + for node in self.outputs: + os.chmod(node.abspath(), self.chmod) + return ret + cls.post_run = post_run + +@conf +def setup_netcache(ctx, push_addr, pull_addr): + Task.Task.can_retrieve_cache = can_retrieve_cache + Task.Task.put_files_cache = put_files_cache + Task.Task.uid = uid + Task.push_addr = push_addr + Task.pull_addr = pull_addr + Build.BuildContext.hash_env_vars = hash_env_vars + ctx.cache_global = True + + for x in Task.classes.values(): + make_cached(x) + +def build(bld): + if not 'NETCACHE' in os.environ and not 'NETCACHE_PULL' in os.environ and not 'NETCACHE_PUSH' in os.environ: + Logs.warn('Setting NETCACHE_PULL=127.0.0.1:11001 and NETCACHE_PUSH=127.0.0.1:12001') + os.environ['NETCACHE_PULL'] = '127.0.0.1:12001' + os.environ['NETCACHE_PUSH'] = '127.0.0.1:11001' + + if 'NETCACHE' in os.environ: + if not 'NETCACHE_PUSH' in os.environ: + os.environ['NETCACHE_PUSH'] = os.environ['NETCACHE'] + if not 'NETCACHE_PULL' in os.environ: + os.environ['NETCACHE_PULL'] = os.environ['NETCACHE'] + + v = os.environ['NETCACHE_PULL'] + if v: + h, p = v.split(':') + pull_addr = (h, int(p)) + else: + pull_addr = None + + v = os.environ['NETCACHE_PUSH'] + if v: + h, p = v.split(':') + push_addr = (h, int(p)) + else: + push_addr = None + + setup_netcache(bld, push_addr, pull_addr) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/objcopy.py b/ldb-2.0.8/third_party/waf/waflib/extras/objcopy.py new file mode 100644 index 0000000..bb7ca6e --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/objcopy.py @@ -0,0 +1,53 @@ +#!/usr/bin/python +# Grygoriy Fuchedzhy 2010 + +""" +Support for converting linked targets to ihex, srec or binary files using +objcopy. Use the 'objcopy' feature in conjunction with the 'cc' or 'cxx' +feature. The 'objcopy' feature uses the following attributes: + +objcopy_bfdname Target object format name (eg. ihex, srec, binary). + Defaults to ihex. +objcopy_target File name used for objcopy output. This defaults to the + target name with objcopy_bfdname as extension. +objcopy_install_path Install path for objcopy_target file. Defaults to ${PREFIX}/fw. +objcopy_flags Additional flags passed to objcopy. +""" + +from waflib.Utils import def_attrs +from waflib import Task, Options +from waflib.TaskGen import feature, after_method + +class objcopy(Task.Task): + run_str = '${OBJCOPY} -O ${TARGET_BFDNAME} ${OBJCOPYFLAGS} ${SRC} ${TGT}' + color = 'CYAN' + +@feature('objcopy') +@after_method('apply_link') +def map_objcopy(self): + def_attrs(self, + objcopy_bfdname = 'ihex', + objcopy_target = None, + objcopy_install_path = "${PREFIX}/firmware", + objcopy_flags = '') + + link_output = self.link_task.outputs[0] + if not self.objcopy_target: + self.objcopy_target = link_output.change_ext('.' + self.objcopy_bfdname).name + task = self.create_task('objcopy', src=link_output, tgt=self.path.find_or_declare(self.objcopy_target)) + + task.env.append_unique('TARGET_BFDNAME', self.objcopy_bfdname) + try: + task.env.append_unique('OBJCOPYFLAGS', getattr(self, 'objcopy_flags')) + except AttributeError: + pass + + if self.objcopy_install_path: + self.add_install_files(install_to=self.objcopy_install_path, install_from=task.outputs[0]) + +def configure(ctx): + program_name = 'objcopy' + prefix = getattr(Options.options, 'cross_prefix', None) + if prefix: + program_name = '{}-{}'.format(prefix, program_name) + ctx.find_program(program_name, var='OBJCOPY', mandatory=True) diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/ocaml.py b/ldb-2.0.8/third_party/waf/waflib/extras/ocaml.py new file mode 100644 index 0000000..7d785c6 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/ocaml.py @@ -0,0 +1,348 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2006-2010 (ita) + +"ocaml support" + +import os, re +from waflib import Utils, Task +from waflib.Logs import error +from waflib.TaskGen import feature, before_method, after_method, extension + +EXT_MLL = ['.mll'] +EXT_MLY = ['.mly'] +EXT_MLI = ['.mli'] +EXT_MLC = ['.c'] +EXT_ML = ['.ml'] + +open_re = re.compile(r'^\s*open\s+([a-zA-Z]+)(;;){0,1}$', re.M) +foo = re.compile(r"""(\(\*)|(\*\))|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^()*"'\\]*)""", re.M) +def filter_comments(txt): + meh = [0] + def repl(m): + if m.group(1): + meh[0] += 1 + elif m.group(2): + meh[0] -= 1 + elif not meh[0]: + return m.group() + return '' + return foo.sub(repl, txt) + +def scan(self): + node = self.inputs[0] + code = filter_comments(node.read()) + + global open_re + names = [] + import_iterator = open_re.finditer(code) + if import_iterator: + for import_match in import_iterator: + names.append(import_match.group(1)) + found_lst = [] + raw_lst = [] + for name in names: + nd = None + for x in self.incpaths: + nd = x.find_resource(name.lower()+'.ml') + if not nd: + nd = x.find_resource(name+'.ml') + if nd: + found_lst.append(nd) + break + else: + raw_lst.append(name) + + return (found_lst, raw_lst) + +native_lst=['native', 'all', 'c_object'] +bytecode_lst=['bytecode', 'all'] + +@feature('ocaml') +def init_ml(self): + Utils.def_attrs(self, + type = 'all', + incpaths_lst = [], + bld_incpaths_lst = [], + mlltasks = [], + mlytasks = [], + mlitasks = [], + native_tasks = [], + bytecode_tasks = [], + linktasks = [], + bytecode_env = None, + native_env = None, + compiled_tasks = [], + includes = '', + uselib = '', + are_deps_set = 0) + +@feature('ocaml') +@after_method('init_ml') +def init_envs_ml(self): + + self.islibrary = getattr(self, 'islibrary', False) + + global native_lst, bytecode_lst + self.native_env = None + if self.type in native_lst: + self.native_env = self.env.derive() + if self.islibrary: + self.native_env['OCALINKFLAGS'] = '-a' + + self.bytecode_env = None + if self.type in bytecode_lst: + self.bytecode_env = self.env.derive() + if self.islibrary: + self.bytecode_env['OCALINKFLAGS'] = '-a' + + if self.type == 'c_object': + self.native_env.append_unique('OCALINKFLAGS_OPT', '-output-obj') + +@feature('ocaml') +@before_method('apply_vars_ml') +@after_method('init_envs_ml') +def apply_incpaths_ml(self): + inc_lst = self.includes.split() + lst = self.incpaths_lst + for dir in inc_lst: + node = self.path.find_dir(dir) + if not node: + error("node not found: " + str(dir)) + continue + if not node in lst: + lst.append(node) + self.bld_incpaths_lst.append(node) + # now the nodes are added to self.incpaths_lst + +@feature('ocaml') +@before_method('process_source') +def apply_vars_ml(self): + for i in self.incpaths_lst: + if self.bytecode_env: + app = self.bytecode_env.append_value + app('OCAMLPATH', ['-I', i.bldpath(), '-I', i.srcpath()]) + + if self.native_env: + app = self.native_env.append_value + app('OCAMLPATH', ['-I', i.bldpath(), '-I', i.srcpath()]) + + varnames = ['INCLUDES', 'OCAMLFLAGS', 'OCALINKFLAGS', 'OCALINKFLAGS_OPT'] + for name in self.uselib.split(): + for vname in varnames: + cnt = self.env[vname+'_'+name] + if cnt: + if self.bytecode_env: + self.bytecode_env.append_value(vname, cnt) + if self.native_env: + self.native_env.append_value(vname, cnt) + +@feature('ocaml') +@after_method('process_source') +def apply_link_ml(self): + + if self.bytecode_env: + ext = self.islibrary and '.cma' or '.run' + + linktask = self.create_task('ocalink') + linktask.bytecode = 1 + linktask.set_outputs(self.path.find_or_declare(self.target + ext)) + linktask.env = self.bytecode_env + self.linktasks.append(linktask) + + if self.native_env: + if self.type == 'c_object': + ext = '.o' + elif self.islibrary: + ext = '.cmxa' + else: + ext = '' + + linktask = self.create_task('ocalinkx') + linktask.set_outputs(self.path.find_or_declare(self.target + ext)) + linktask.env = self.native_env + self.linktasks.append(linktask) + + # we produce a .o file to be used by gcc + self.compiled_tasks.append(linktask) + +@extension(*EXT_MLL) +def mll_hook(self, node): + mll_task = self.create_task('ocamllex', node, node.change_ext('.ml')) + mll_task.env = self.native_env.derive() + self.mlltasks.append(mll_task) + + self.source.append(mll_task.outputs[0]) + +@extension(*EXT_MLY) +def mly_hook(self, node): + mly_task = self.create_task('ocamlyacc', node, [node.change_ext('.ml'), node.change_ext('.mli')]) + mly_task.env = self.native_env.derive() + self.mlytasks.append(mly_task) + self.source.append(mly_task.outputs[0]) + + task = self.create_task('ocamlcmi', mly_task.outputs[1], mly_task.outputs[1].change_ext('.cmi')) + task.env = self.native_env.derive() + +@extension(*EXT_MLI) +def mli_hook(self, node): + task = self.create_task('ocamlcmi', node, node.change_ext('.cmi')) + task.env = self.native_env.derive() + self.mlitasks.append(task) + +@extension(*EXT_MLC) +def mlc_hook(self, node): + task = self.create_task('ocamlcc', node, node.change_ext('.o')) + task.env = self.native_env.derive() + self.compiled_tasks.append(task) + +@extension(*EXT_ML) +def ml_hook(self, node): + if self.native_env: + task = self.create_task('ocamlx', node, node.change_ext('.cmx')) + task.env = self.native_env.derive() + task.incpaths = self.bld_incpaths_lst + self.native_tasks.append(task) + + if self.bytecode_env: + task = self.create_task('ocaml', node, node.change_ext('.cmo')) + task.env = self.bytecode_env.derive() + task.bytecode = 1 + task.incpaths = self.bld_incpaths_lst + self.bytecode_tasks.append(task) + +def compile_may_start(self): + + if not getattr(self, 'flag_deps', ''): + self.flag_deps = 1 + + # the evil part is that we can only compute the dependencies after the + # source files can be read (this means actually producing the source files) + if getattr(self, 'bytecode', ''): + alltasks = self.generator.bytecode_tasks + else: + alltasks = self.generator.native_tasks + + self.signature() # ensure that files are scanned - unfortunately + tree = self.generator.bld + for node in self.inputs: + lst = tree.node_deps[self.uid()] + for depnode in lst: + for t in alltasks: + if t == self: + continue + if depnode in t.inputs: + self.set_run_after(t) + + # TODO necessary to get the signature right - for now + delattr(self, 'cache_sig') + self.signature() + + return Task.Task.runnable_status(self) + +class ocamlx(Task.Task): + """native caml compilation""" + color = 'GREEN' + run_str = '${OCAMLOPT} ${OCAMLPATH} ${OCAMLFLAGS} ${OCAMLINCLUDES} -c -o ${TGT} ${SRC}' + scan = scan + runnable_status = compile_may_start + +class ocaml(Task.Task): + """bytecode caml compilation""" + color = 'GREEN' + run_str = '${OCAMLC} ${OCAMLPATH} ${OCAMLFLAGS} ${OCAMLINCLUDES} -c -o ${TGT} ${SRC}' + scan = scan + runnable_status = compile_may_start + +class ocamlcmi(Task.Task): + """interface generator (the .i files?)""" + color = 'BLUE' + run_str = '${OCAMLC} ${OCAMLPATH} ${OCAMLINCLUDES} -o ${TGT} -c ${SRC}' + before = ['ocamlcc', 'ocaml', 'ocamlcc'] + +class ocamlcc(Task.Task): + """ocaml to c interfaces""" + color = 'GREEN' + run_str = 'cd ${TGT[0].bld_dir()} && ${OCAMLOPT} ${OCAMLFLAGS} ${OCAMLPATH} ${OCAMLINCLUDES} -c ${SRC[0].abspath()}' + +class ocamllex(Task.Task): + """lexical generator""" + color = 'BLUE' + run_str = '${OCAMLLEX} ${SRC} -o ${TGT}' + before = ['ocamlcmi', 'ocaml', 'ocamlcc'] + +class ocamlyacc(Task.Task): + """parser generator""" + color = 'BLUE' + run_str = '${OCAMLYACC} -b ${tsk.base()} ${SRC}' + before = ['ocamlcmi', 'ocaml', 'ocamlcc'] + + def base(self): + node = self.outputs[0] + s = os.path.splitext(node.name)[0] + return node.bld_dir() + os.sep + s + +def link_may_start(self): + + if getattr(self, 'bytecode', 0): + alltasks = self.generator.bytecode_tasks + else: + alltasks = self.generator.native_tasks + + for x in alltasks: + if not x.hasrun: + return Task.ASK_LATER + + if not getattr(self, 'order', ''): + + # now reorder the inputs given the task dependencies + # this part is difficult, we do not have a total order on the tasks + # if the dependencies are wrong, this may not stop + seen = [] + pendant = []+alltasks + while pendant: + task = pendant.pop(0) + if task in seen: + continue + for x in task.run_after: + if not x in seen: + pendant.append(task) + break + else: + seen.append(task) + self.inputs = [x.outputs[0] for x in seen] + self.order = 1 + return Task.Task.runnable_status(self) + +class ocalink(Task.Task): + """bytecode caml link""" + color = 'YELLOW' + run_str = '${OCAMLC} -o ${TGT} ${OCAMLINCLUDES} ${OCALINKFLAGS} ${SRC}' + runnable_status = link_may_start + after = ['ocaml', 'ocamlcc'] + +class ocalinkx(Task.Task): + """native caml link""" + color = 'YELLOW' + run_str = '${OCAMLOPT} -o ${TGT} ${OCAMLINCLUDES} ${OCALINKFLAGS_OPT} ${SRC}' + runnable_status = link_may_start + after = ['ocamlx', 'ocamlcc'] + +def configure(conf): + opt = conf.find_program('ocamlopt', var='OCAMLOPT', mandatory=False) + occ = conf.find_program('ocamlc', var='OCAMLC', mandatory=False) + if (not opt) or (not occ): + conf.fatal('The objective caml compiler was not found:\ninstall it or make it available in your PATH') + + v = conf.env + v['OCAMLC'] = occ + v['OCAMLOPT'] = opt + v['OCAMLLEX'] = conf.find_program('ocamllex', var='OCAMLLEX', mandatory=False) + v['OCAMLYACC'] = conf.find_program('ocamlyacc', var='OCAMLYACC', mandatory=False) + v['OCAMLFLAGS'] = '' + where = conf.cmd_and_log(conf.env.OCAMLC + ['-where']).strip()+os.sep + v['OCAMLLIB'] = where + v['LIBPATH_OCAML'] = where + v['INCLUDES_OCAML'] = where + v['LIB_OCAML'] = 'camlrun' + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/package.py b/ldb-2.0.8/third_party/waf/waflib/extras/package.py new file mode 100644 index 0000000..c06498e --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/package.py @@ -0,0 +1,76 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2011 + +""" +Obtain packages, unpack them in a location, and add associated uselib variables +(CFLAGS_pkgname, LIBPATH_pkgname, etc). + +The default is use a Dependencies.txt file in the source directory. + +This is a work in progress. + +Usage: + +def options(opt): + opt.load('package') + +def configure(conf): + conf.load_packages() +""" + +from waflib import Logs +from waflib.Configure import conf + +try: + from urllib import request +except ImportError: + from urllib import urlopen +else: + urlopen = request.urlopen + + +CACHEVAR = 'WAFCACHE_PACKAGE' + +@conf +def get_package_cache_dir(self): + cache = None + if CACHEVAR in conf.environ: + cache = conf.environ[CACHEVAR] + cache = self.root.make_node(cache) + elif self.env[CACHEVAR]: + cache = self.env[CACHEVAR] + cache = self.root.make_node(cache) + else: + cache = self.srcnode.make_node('.wafcache_package') + cache.mkdir() + return cache + +@conf +def download_archive(self, src, dst): + for x in self.env.PACKAGE_REPO: + url = '/'.join((x, src)) + try: + web = urlopen(url) + try: + if web.getcode() != 200: + continue + except AttributeError: + pass + except Exception: + # on python3 urlopen throws an exception + # python 2.3 does not have getcode and throws an exception to fail + continue + else: + tmp = self.root.make_node(dst) + tmp.write(web.read()) + Logs.warn('Downloaded %s from %s', tmp.abspath(), url) + break + else: + self.fatal('Could not get the package %s' % src) + +@conf +def load_packages(self): + self.get_package_cache_dir() + # read the dependencies, get the archives, .. + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/parallel_debug.py b/ldb-2.0.8/third_party/waf/waflib/extras/parallel_debug.py new file mode 100644 index 0000000..4ffec5e --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/parallel_debug.py @@ -0,0 +1,462 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2007-2010 (ita) + +""" +Debugging helper for parallel compilation. + +Copy it to your project and load it with:: + + def options(opt): + opt.load('parallel_debug', tooldir='.') + def build(bld): + ... + +The build will then output a file named pdebug.svg in the source directory. +""" + +import re, sys, threading, time, traceback +try: + from Queue import Queue +except: + from queue import Queue +from waflib import Runner, Options, Task, Logs, Errors + +SVG_TEMPLATE = """ + + + + + + + + + + +${if project.title} + ${project.title} +${endif} + + +${for cls in project.groups} + + ${for rect in cls.rects} + + ${endfor} + +${endfor} + +${for info in project.infos} + + + ${info.text} + +${endfor} + +${if project.tooltip} + + + + +${endif} + + +""" + +COMPILE_TEMPLATE = '''def f(project): + lst = [] + def xml_escape(value): + return value.replace("&", "&").replace('"', """).replace("'", "'").replace("<", "<").replace(">", ">") + + %s + return ''.join(lst) +''' +reg_act = re.compile(r"(?P\\)|(?P\$\$)|(?P\$\{(?P[^}]*?)\})", re.M) +def compile_template(line): + + extr = [] + def repl(match): + g = match.group + if g('dollar'): + return "$" + elif g('backslash'): + return "\\" + elif g('subst'): + extr.append(g('code')) + return "<<|@|>>" + return None + + line2 = reg_act.sub(repl, line) + params = line2.split('<<|@|>>') + assert(extr) + + + indent = 0 + buf = [] + app = buf.append + + def app(txt): + buf.append(indent * '\t' + txt) + + for x in range(len(extr)): + if params[x]: + app("lst.append(%r)" % params[x]) + + f = extr[x] + if f.startswith(('if', 'for')): + app(f + ':') + indent += 1 + elif f.startswith('py:'): + app(f[3:]) + elif f.startswith(('endif', 'endfor')): + indent -= 1 + elif f.startswith(('else', 'elif')): + indent -= 1 + app(f + ':') + indent += 1 + elif f.startswith('xml:'): + app('lst.append(xml_escape(%s))' % f[4:]) + else: + #app('lst.append((%s) or "cannot find %s")' % (f, f)) + app('lst.append(str(%s))' % f) + + if extr: + if params[-1]: + app("lst.append(%r)" % params[-1]) + + fun = COMPILE_TEMPLATE % "\n\t".join(buf) + # uncomment the following to debug the template + #for i, x in enumerate(fun.splitlines()): + # print i, x + return Task.funex(fun) + +# red #ff4d4d +# green #4da74d +# lila #a751ff + +color2code = { + 'GREEN' : '#4da74d', + 'YELLOW' : '#fefe44', + 'PINK' : '#a751ff', + 'RED' : '#cc1d1d', + 'BLUE' : '#6687bb', + 'CYAN' : '#34e2e2', +} + +mp = {} +info = [] # list of (text,color) + +def map_to_color(name): + if name in mp: + return mp[name] + try: + cls = Task.classes[name] + except KeyError: + return color2code['RED'] + if cls.color in mp: + return mp[cls.color] + if cls.color in color2code: + return color2code[cls.color] + return color2code['RED'] + +def process(self): + m = self.generator.bld.producer + try: + # TODO another place for this? + del self.generator.bld.task_sigs[self.uid()] + except KeyError: + pass + + self.generator.bld.producer.set_running(1, self) + + try: + ret = self.run() + except Exception: + self.err_msg = traceback.format_exc() + self.hasrun = Task.EXCEPTION + + # TODO cleanup + m.error_handler(self) + return + + if ret: + self.err_code = ret + self.hasrun = Task.CRASHED + else: + try: + self.post_run() + except Errors.WafError: + pass + except Exception: + self.err_msg = traceback.format_exc() + self.hasrun = Task.EXCEPTION + else: + self.hasrun = Task.SUCCESS + if self.hasrun != Task.SUCCESS: + m.error_handler(self) + + self.generator.bld.producer.set_running(-1, self) + +Task.Task.process_back = Task.Task.process +Task.Task.process = process + +old_start = Runner.Parallel.start +def do_start(self): + try: + Options.options.dband + except AttributeError: + self.bld.fatal('use def options(opt): opt.load("parallel_debug")!') + + self.taskinfo = Queue() + old_start(self) + if self.dirty: + make_picture(self) +Runner.Parallel.start = do_start + +lock_running = threading.Lock() +def set_running(self, by, tsk): + with lock_running: + try: + cache = self.lock_cache + except AttributeError: + cache = self.lock_cache = {} + + i = 0 + if by > 0: + vals = cache.values() + for i in range(self.numjobs): + if i not in vals: + cache[tsk] = i + break + else: + i = cache[tsk] + del cache[tsk] + + self.taskinfo.put( (i, id(tsk), time.time(), tsk.__class__.__name__, self.processed, self.count, by, ",".join(map(str, tsk.outputs))) ) +Runner.Parallel.set_running = set_running + +def name2class(name): + return name.replace(' ', '_').replace('.', '_') + +def make_picture(producer): + # first, cast the parameters + if not hasattr(producer.bld, 'path'): + return + + tmp = [] + try: + while True: + tup = producer.taskinfo.get(False) + tmp.append(list(tup)) + except: + pass + + try: + ini = float(tmp[0][2]) + except: + return + + if not info: + seen = [] + for x in tmp: + name = x[3] + if not name in seen: + seen.append(name) + else: + continue + + info.append((name, map_to_color(name))) + info.sort(key=lambda x: x[0]) + + thread_count = 0 + acc = [] + for x in tmp: + thread_count += x[6] + acc.append("%d %d %f %r %d %d %d %s" % (x[0], x[1], x[2] - ini, x[3], x[4], x[5], thread_count, x[7])) + + data_node = producer.bld.path.make_node('pdebug.dat') + data_node.write('\n'.join(acc)) + + tmp = [lst[:2] + [float(lst[2]) - ini] + lst[3:] for lst in tmp] + + st = {} + for l in tmp: + if not l[0] in st: + st[l[0]] = len(st.keys()) + tmp = [ [st[lst[0]]] + lst[1:] for lst in tmp ] + THREAD_AMOUNT = len(st.keys()) + + st = {} + for l in tmp: + if not l[1] in st: + st[l[1]] = len(st.keys()) + tmp = [ [lst[0]] + [st[lst[1]]] + lst[2:] for lst in tmp ] + + + BAND = Options.options.dband + + seen = {} + acc = [] + for x in range(len(tmp)): + line = tmp[x] + id = line[1] + + if id in seen: + continue + seen[id] = True + + begin = line[2] + thread_id = line[0] + for y in range(x + 1, len(tmp)): + line = tmp[y] + if line[1] == id: + end = line[2] + #print id, thread_id, begin, end + #acc.append( ( 10*thread_id, 10*(thread_id+1), 10*begin, 10*end ) ) + acc.append( (BAND * begin, BAND*thread_id, BAND*end - BAND*begin, BAND, line[3], line[7]) ) + break + + if Options.options.dmaxtime < 0.1: + gwidth = 1 + for x in tmp: + m = BAND * x[2] + if m > gwidth: + gwidth = m + else: + gwidth = BAND * Options.options.dmaxtime + + ratio = float(Options.options.dwidth) / gwidth + gwidth = Options.options.dwidth + gheight = BAND * (THREAD_AMOUNT + len(info) + 1.5) + + + # simple data model for our template + class tobject(object): + pass + + model = tobject() + model.x = 0 + model.y = 0 + model.width = gwidth + 4 + model.height = gheight + 4 + + model.tooltip = not Options.options.dnotooltip + + model.title = Options.options.dtitle + model.title_x = gwidth / 2 + model.title_y = gheight + - 5 + + groups = {} + for (x, y, w, h, clsname, name) in acc: + try: + groups[clsname].append((x, y, w, h, name)) + except: + groups[clsname] = [(x, y, w, h, name)] + + # groups of rectangles (else js highlighting is slow) + model.groups = [] + for cls in groups: + g = tobject() + model.groups.append(g) + g.classname = name2class(cls) + g.rects = [] + for (x, y, w, h, name) in groups[cls]: + r = tobject() + g.rects.append(r) + r.x = 2 + x * ratio + r.y = 2 + y + r.width = w * ratio + r.height = h + r.name = name + r.color = map_to_color(cls) + + cnt = THREAD_AMOUNT + + # caption + model.infos = [] + for (text, color) in info: + inf = tobject() + model.infos.append(inf) + inf.classname = name2class(text) + inf.x = 2 + BAND + inf.y = 5 + (cnt + 0.5) * BAND + inf.width = BAND/2 + inf.height = BAND/2 + inf.color = color + + inf.text = text + inf.text_x = 2 + 2 * BAND + inf.text_y = 5 + (cnt + 0.5) * BAND + 10 + + cnt += 1 + + # write the file... + template1 = compile_template(SVG_TEMPLATE) + txt = template1(model) + + node = producer.bld.path.make_node('pdebug.svg') + node.write(txt) + Logs.warn('Created the diagram %r', node) + +def options(opt): + opt.add_option('--dtitle', action='store', default='Parallel build representation for %r' % ' '.join(sys.argv), + help='title for the svg diagram', dest='dtitle') + opt.add_option('--dwidth', action='store', type='int', help='diagram width', default=800, dest='dwidth') + opt.add_option('--dtime', action='store', type='float', help='recording interval in seconds', default=0.009, dest='dtime') + opt.add_option('--dband', action='store', type='int', help='band width', default=22, dest='dband') + opt.add_option('--dmaxtime', action='store', type='float', help='maximum time, for drawing fair comparisons', default=0, dest='dmaxtime') + opt.add_option('--dnotooltip', action='store_true', help='disable tooltips', default=False, dest='dnotooltip') + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/pch.py b/ldb-2.0.8/third_party/waf/waflib/extras/pch.py new file mode 100644 index 0000000..103e752 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/pch.py @@ -0,0 +1,148 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Alexander Afanasyev (UCLA), 2014 + +""" +Enable precompiled C++ header support (currently only clang++ and g++ are supported) + +To use this tool, wscript should look like: + + def options(opt): + opt.load('pch') + # This will add `--with-pch` configure option. + # Unless --with-pch during configure stage specified, the precompiled header support is disabled + + def configure(conf): + conf.load('pch') + # this will set conf.env.WITH_PCH if --with-pch is specified and the supported compiler is used + # Unless conf.env.WITH_PCH is set, the precompiled header support is disabled + + def build(bld): + bld(features='cxx pch', + target='precompiled-headers', + name='precompiled-headers', + headers='a.h b.h c.h', # headers to pre-compile into `precompiled-headers` + + # Other parameters to compile precompiled headers + # includes=..., + # export_includes=..., + # use=..., + # ... + + # Exported parameters will be propagated even if precompiled headers are disabled + ) + + bld( + target='test', + features='cxx cxxprogram', + source='a.cpp b.cpp d.cpp main.cpp', + use='precompiled-headers', + ) + + # or + + bld( + target='test', + features='pch cxx cxxprogram', + source='a.cpp b.cpp d.cpp main.cpp', + headers='a.h b.h c.h', + ) + +Note that precompiled header must have multiple inclusion guards. If the guards are missing, any benefit of precompiled header will be voided and compilation may fail in some cases. +""" + +import os +from waflib import Task, TaskGen, Utils +from waflib.Tools import c_preproc, cxx + + +PCH_COMPILER_OPTIONS = { + 'clang++': [['-include'], '.pch', ['-x', 'c++-header']], + 'g++': [['-include'], '.gch', ['-x', 'c++-header']], +} + + +def options(opt): + opt.add_option('--without-pch', action='store_false', default=True, dest='with_pch', help='''Try to use precompiled header to speed up compilation (only g++ and clang++)''') + +def configure(conf): + if (conf.options.with_pch and conf.env['COMPILER_CXX'] in PCH_COMPILER_OPTIONS.keys()): + conf.env.WITH_PCH = True + flags = PCH_COMPILER_OPTIONS[conf.env['COMPILER_CXX']] + conf.env.CXXPCH_F = flags[0] + conf.env.CXXPCH_EXT = flags[1] + conf.env.CXXPCH_FLAGS = flags[2] + + +@TaskGen.feature('pch') +@TaskGen.before('process_source') +def apply_pch(self): + if not self.env.WITH_PCH: + return + + if getattr(self.bld, 'pch_tasks', None) is None: + self.bld.pch_tasks = {} + + if getattr(self, 'headers', None) is None: + return + + self.headers = self.to_nodes(self.headers) + + if getattr(self, 'name', None): + try: + task = self.bld.pch_tasks["%s.%s" % (self.name, self.idx)] + self.bld.fatal("Duplicated 'pch' task with name %r" % "%s.%s" % (self.name, self.idx)) + except KeyError: + pass + + out = '%s.%d%s' % (self.target, self.idx, self.env['CXXPCH_EXT']) + out = self.path.find_or_declare(out) + task = self.create_task('gchx', self.headers, out) + + # target should be an absolute path of `out`, but without precompiled header extension + task.target = out.abspath()[:-len(out.suffix())] + + self.pch_task = task + if getattr(self, 'name', None): + self.bld.pch_tasks["%s.%s" % (self.name, self.idx)] = task + +@TaskGen.feature('cxx') +@TaskGen.after_method('process_source', 'propagate_uselib_vars') +def add_pch(self): + if not (self.env['WITH_PCH'] and getattr(self, 'use', None) and getattr(self, 'compiled_tasks', None) and getattr(self.bld, 'pch_tasks', None)): + return + + pch = None + # find pch task, if any + + if getattr(self, 'pch_task', None): + pch = self.pch_task + else: + for use in Utils.to_list(self.use): + try: + pch = self.bld.pch_tasks[use] + except KeyError: + pass + + if pch: + for x in self.compiled_tasks: + x.env.append_value('CXXFLAGS', self.env['CXXPCH_F'] + [pch.target]) + +class gchx(Task.Task): + run_str = '${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${CXXPCH_FLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXXPCH_F:SRC} ${CXX_SRC_F}${SRC[0].abspath()} ${CXX_TGT_F}${TGT[0].abspath()} ${CPPFLAGS}' + scan = c_preproc.scan + color = 'BLUE' + ext_out=['.h'] + + def runnable_status(self): + try: + node_deps = self.generator.bld.node_deps[self.uid()] + except KeyError: + node_deps = [] + ret = Task.Task.runnable_status(self) + if ret == Task.SKIP_ME and self.env.CXX_NAME == 'clang': + t = os.stat(self.outputs[0].abspath()).st_mtime + for n in self.inputs + node_deps: + if os.stat(n.abspath()).st_mtime > t: + return Task.RUN_ME + return ret diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/pep8.py b/ldb-2.0.8/third_party/waf/waflib/extras/pep8.py new file mode 100644 index 0000000..676beed --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/pep8.py @@ -0,0 +1,106 @@ +#! /usr/bin/env python +# encoding: utf-8 +# +# written by Sylvain Rouquette, 2011 + +''' +Install pep8 module: +$ easy_install pep8 + or +$ pip install pep8 + +To add the pep8 tool to the waf file: +$ ./waf-light --tools=compat15,pep8 + or, if you have waf >= 1.6.2 +$ ./waf update --files=pep8 + + +Then add this to your wscript: + +[at]extension('.py', 'wscript') +def run_pep8(self, node): + self.create_task('Pep8', node) + +''' + +import threading +from waflib import Task, Options + +pep8 = __import__('pep8') + + +class Pep8(Task.Task): + color = 'PINK' + lock = threading.Lock() + + def check_options(self): + if pep8.options: + return + pep8.options = Options.options + pep8.options.prog = 'pep8' + excl = pep8.options.exclude.split(',') + pep8.options.exclude = [s.rstrip('/') for s in excl] + if pep8.options.filename: + pep8.options.filename = pep8.options.filename.split(',') + if pep8.options.select: + pep8.options.select = pep8.options.select.split(',') + else: + pep8.options.select = [] + if pep8.options.ignore: + pep8.options.ignore = pep8.options.ignore.split(',') + elif pep8.options.select: + # Ignore all checks which are not explicitly selected + pep8.options.ignore = [''] + elif pep8.options.testsuite or pep8.options.doctest: + # For doctest and testsuite, all checks are required + pep8.options.ignore = [] + else: + # The default choice: ignore controversial checks + pep8.options.ignore = pep8.DEFAULT_IGNORE.split(',') + pep8.options.physical_checks = pep8.find_checks('physical_line') + pep8.options.logical_checks = pep8.find_checks('logical_line') + pep8.options.counters = dict.fromkeys(pep8.BENCHMARK_KEYS, 0) + pep8.options.messages = {} + + def run(self): + with Pep8.lock: + self.check_options() + pep8.input_file(self.inputs[0].abspath()) + return 0 if not pep8.get_count() else -1 + + +def options(opt): + opt.add_option('-q', '--quiet', default=0, action='count', + help="report only file names, or nothing with -qq") + opt.add_option('-r', '--repeat', action='store_true', + help="show all occurrences of the same error") + opt.add_option('--exclude', metavar='patterns', + default=pep8.DEFAULT_EXCLUDE, + help="exclude files or directories which match these " + "comma separated patterns (default: %s)" % + pep8.DEFAULT_EXCLUDE, + dest='exclude') + opt.add_option('--filename', metavar='patterns', default='*.py', + help="when parsing directories, only check filenames " + "matching these comma separated patterns (default: " + "*.py)") + opt.add_option('--select', metavar='errors', default='', + help="select errors and warnings (e.g. E,W6)") + opt.add_option('--ignore', metavar='errors', default='', + help="skip errors and warnings (e.g. E4,W)") + opt.add_option('--show-source', action='store_true', + help="show source code for each error") + opt.add_option('--show-pep8', action='store_true', + help="show text of PEP 8 for each error") + opt.add_option('--statistics', action='store_true', + help="count errors and warnings") + opt.add_option('--count', action='store_true', + help="print total number of errors and warnings " + "to standard error and set exit code to 1 if " + "total is not null") + opt.add_option('--benchmark', action='store_true', + help="measure processing speed") + opt.add_option('--testsuite', metavar='dir', + help="run regression tests from dir") + opt.add_option('--doctest', action='store_true', + help="run doctest on myself") diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/pgicc.py b/ldb-2.0.8/third_party/waf/waflib/extras/pgicc.py new file mode 100644 index 0000000..f8068d5 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/pgicc.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Antoine Dechaume 2011 + +""" +Detect the PGI C compiler +""" + +import sys, re +from waflib import Errors +from waflib.Configure import conf +from waflib.Tools.compiler_c import c_compiler +c_compiler['linux'].append('pgicc') + +@conf +def find_pgi_compiler(conf, var, name): + """ + Find the program name, and execute it to ensure it really is itself. + """ + if sys.platform == 'cygwin': + conf.fatal('The PGI compiler does not work on Cygwin') + + v = conf.env + cc = None + if v[var]: + cc = v[var] + elif var in conf.environ: + cc = conf.environ[var] + if not cc: + cc = conf.find_program(name, var=var) + if not cc: + conf.fatal('PGI Compiler (%s) was not found' % name) + + v[var + '_VERSION'] = conf.get_pgi_version(cc) + v[var] = cc + v[var + '_NAME'] = 'pgi' + +@conf +def get_pgi_version(conf, cc): + """Find the version of a pgi compiler.""" + version_re = re.compile(r"The Portland Group", re.I).search + cmd = cc + ['-V', '-E'] # Issue 1078, prevent wrappers from linking + + try: + out, err = conf.cmd_and_log(cmd, output=0) + except Errors.WafError: + conf.fatal('Could not find pgi compiler %r' % cmd) + + if out: + match = version_re(out) + else: + match = version_re(err) + + if not match: + conf.fatal('Could not verify PGI signature') + + cmd = cc + ['-help=variable'] + try: + out, err = conf.cmd_and_log(cmd, output=0) + except Errors.WafError: + conf.fatal('Could not find pgi compiler %r' % cmd) + + version = re.findall(r'^COMPVER\s*=(.*)', out, re.M) + if len(version) != 1: + conf.fatal('Could not determine the compiler version') + return version[0] + +def configure(conf): + conf.find_pgi_compiler('CC', 'pgcc') + conf.find_ar() + conf.gcc_common_flags() + conf.cc_load_tools() + conf.cc_add_flags() + conf.link_add_flags() + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/pgicxx.py b/ldb-2.0.8/third_party/waf/waflib/extras/pgicxx.py new file mode 100644 index 0000000..eae121c --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/pgicxx.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Antoine Dechaume 2011 + +""" +Detect the PGI C++ compiler +""" + +from waflib.Tools.compiler_cxx import cxx_compiler +cxx_compiler['linux'].append('pgicxx') + +from waflib.extras import pgicc + +def configure(conf): + conf.find_pgi_compiler('CXX', 'pgCC') + conf.find_ar() + conf.gxx_common_flags() + conf.cxx_load_tools() + conf.cxx_add_flags() + conf.link_add_flags() diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/proc.py b/ldb-2.0.8/third_party/waf/waflib/extras/proc.py new file mode 100644 index 0000000..764abec --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/proc.py @@ -0,0 +1,54 @@ +#! /usr/bin/env python +# per rosengren 2011 + +from os import environ, path +from waflib import TaskGen, Utils + +def options(opt): + grp = opt.add_option_group('Oracle ProC Options') + grp.add_option('--oracle_home', action='store', default=environ.get('PROC_ORACLE'), help='Path to Oracle installation home (has bin/lib)') + grp.add_option('--tns_admin', action='store', default=environ.get('TNS_ADMIN'), help='Directory containing server list (TNS_NAMES.ORA)') + grp.add_option('--connection', action='store', default='dummy-user/dummy-password@dummy-server', help='Format: user/password@server') + +def configure(cnf): + env = cnf.env + if not env.PROC_ORACLE: + env.PROC_ORACLE = cnf.options.oracle_home + if not env.PROC_TNS_ADMIN: + env.PROC_TNS_ADMIN = cnf.options.tns_admin + if not env.PROC_CONNECTION: + env.PROC_CONNECTION = cnf.options.connection + cnf.find_program('proc', var='PROC', path_list=env.PROC_ORACLE + path.sep + 'bin') + +def proc(tsk): + env = tsk.env + gen = tsk.generator + inc_nodes = gen.to_incnodes(Utils.to_list(getattr(gen,'includes',[])) + env['INCLUDES']) + + cmd = ( + [env.PROC] + + ['SQLCHECK=SEMANTICS'] + + (['SYS_INCLUDE=(' + ','.join(env.PROC_INCLUDES) + ')'] + if env.PROC_INCLUDES else []) + + ['INCLUDE=(' + ','.join( + [i.bldpath() for i in inc_nodes] + ) + ')'] + + ['userid=' + env.PROC_CONNECTION] + + ['INAME=' + tsk.inputs[0].bldpath()] + + ['ONAME=' + tsk.outputs[0].bldpath()] + ) + exec_env = { + 'ORACLE_HOME': env.PROC_ORACLE, + 'LD_LIBRARY_PATH': env.PROC_ORACLE + path.sep + 'lib', + } + if env.PROC_TNS_ADMIN: + exec_env['TNS_ADMIN'] = env.PROC_TNS_ADMIN + return tsk.exec_command(cmd, env=exec_env) + +TaskGen.declare_chain( + name = 'proc', + rule = proc, + ext_in = '.pc', + ext_out = '.c', +) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/protoc.py b/ldb-2.0.8/third_party/waf/waflib/extras/protoc.py new file mode 100644 index 0000000..4a519cc --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/protoc.py @@ -0,0 +1,224 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Philipp Bender, 2012 +# Matt Clarkson, 2012 + +import re, os +from waflib.Task import Task +from waflib.TaskGen import extension +from waflib import Errors, Context, Logs + +""" +A simple tool to integrate protocol buffers into your build system. + +Example for C++: + + def configure(conf): + conf.load('compiler_cxx cxx protoc') + + def build(bld): + bld( + features = 'cxx cxxprogram' + source = 'main.cpp file1.proto proto/file2.proto', + includes = '. proto', + target = 'executable') + +Example for Python: + + def configure(conf): + conf.load('python protoc') + + def build(bld): + bld( + features = 'py' + source = 'main.py file1.proto proto/file2.proto', + protoc_includes = 'proto') + +Example for both Python and C++ at same time: + + def configure(conf): + conf.load('cxx python protoc') + + def build(bld): + bld( + features = 'cxx py' + source = 'file1.proto proto/file2.proto', + protoc_includes = 'proto') # or includes + + +Example for Java: + + def options(opt): + opt.load('java') + + def configure(conf): + conf.load('python java protoc') + # Here you have to point to your protobuf-java JAR and have it in classpath + conf.env.CLASSPATH_PROTOBUF = ['protobuf-java-2.5.0.jar'] + + def build(bld): + bld( + features = 'javac protoc', + name = 'pbjava', + srcdir = 'inc/ src', # directories used by javac + source = ['inc/message_inc.proto', 'inc/message.proto'], + # source is used by protoc for .proto files + use = 'PROTOBUF', + protoc_includes = ['inc']) # for protoc to search dependencies + + +Protoc includes passed via protoc_includes are either relative to the taskgen +or to the project and are searched in this order. + +Include directories external to the waf project can also be passed to the +extra by using protoc_extincludes + + protoc_extincludes = ['/usr/include/pblib'] + + +Notes when using this tool: + +- protoc command line parsing is tricky. + + The generated files can be put in subfolders which depend on + the order of the include paths. + + Try to be simple when creating task generators + containing protoc stuff. + +""" + +class protoc(Task): + run_str = '${PROTOC} ${PROTOC_FL:PROTOC_FLAGS} ${PROTOC_ST:INCPATHS} ${PROTOC_ST:PROTOC_INCPATHS} ${PROTOC_ST:PROTOC_EXTINCPATHS} ${SRC[0].bldpath()}' + color = 'BLUE' + ext_out = ['.h', 'pb.cc', '.py', '.java'] + def scan(self): + """ + Scan .proto dependencies + """ + node = self.inputs[0] + + nodes = [] + names = [] + seen = [] + search_nodes = [] + + if not node: + return (nodes, names) + + if 'cxx' in self.generator.features: + search_nodes = self.generator.includes_nodes + + if 'py' in self.generator.features or 'javac' in self.generator.features: + for incpath in getattr(self.generator, 'protoc_includes', []): + incpath_node = self.generator.path.find_node(incpath) + if incpath_node: + search_nodes.append(incpath_node) + else: + # Check if relative to top-level for extra tg dependencies + incpath_node = self.generator.bld.path.find_node(incpath) + if incpath_node: + search_nodes.append(incpath_node) + else: + raise Errors.WafError('protoc: include path %r does not exist' % incpath) + + + def parse_node(node): + if node in seen: + return + seen.append(node) + code = node.read().splitlines() + for line in code: + m = re.search(r'^import\s+"(.*)";.*(//)?.*', line) + if m: + dep = m.groups()[0] + for incnode in search_nodes: + found = incnode.find_resource(dep) + if found: + nodes.append(found) + parse_node(found) + else: + names.append(dep) + + parse_node(node) + # Add also dependencies path to INCPATHS so protoc will find the included file + for deppath in nodes: + self.env.append_unique('INCPATHS', deppath.parent.bldpath()) + return (nodes, names) + +@extension('.proto') +def process_protoc(self, node): + incdirs = [] + out_nodes = [] + protoc_flags = [] + + # ensure PROTOC_FLAGS is a list; a copy is used below anyway + self.env.PROTOC_FLAGS = self.to_list(self.env.PROTOC_FLAGS) + + if 'cxx' in self.features: + cpp_node = node.change_ext('.pb.cc') + hpp_node = node.change_ext('.pb.h') + self.source.append(cpp_node) + out_nodes.append(cpp_node) + out_nodes.append(hpp_node) + protoc_flags.append('--cpp_out=%s' % node.parent.get_bld().bldpath()) + + if 'py' in self.features: + py_node = node.change_ext('_pb2.py') + self.source.append(py_node) + out_nodes.append(py_node) + protoc_flags.append('--python_out=%s' % node.parent.get_bld().bldpath()) + + if 'javac' in self.features: + # Make javac get also pick java code generated in build + if not node.parent.get_bld() in self.javac_task.srcdir: + self.javac_task.srcdir.append(node.parent.get_bld()) + + protoc_flags.append('--java_out=%s' % node.parent.get_bld().bldpath()) + node.parent.get_bld().mkdir() + + tsk = self.create_task('protoc', node, out_nodes) + tsk.env.append_value('PROTOC_FLAGS', protoc_flags) + + if 'javac' in self.features: + self.javac_task.set_run_after(tsk) + + # Instruct protoc where to search for .proto included files. + # For C++ standard include files dirs are used, + # but this doesn't apply to Python for example + for incpath in getattr(self, 'protoc_includes', []): + incpath_node = self.path.find_node(incpath) + if incpath_node: + incdirs.append(incpath_node.bldpath()) + else: + # Check if relative to top-level for extra tg dependencies + incpath_node = self.bld.path.find_node(incpath) + if incpath_node: + incdirs.append(incpath_node.bldpath()) + else: + raise Errors.WafError('protoc: include path %r does not exist' % incpath) + + tsk.env.PROTOC_INCPATHS = incdirs + + # Include paths external to the waf project (ie. shared pb repositories) + tsk.env.PROTOC_EXTINCPATHS = getattr(self, 'protoc_extincludes', []) + + # PR2115: protoc generates output of .proto files in nested + # directories by canonicalizing paths. To avoid this we have to pass + # as first include the full directory file of the .proto file + tsk.env.prepend_value('INCPATHS', node.parent.bldpath()) + + use = getattr(self, 'use', '') + if not 'PROTOBUF' in use: + self.use = self.to_list(use) + ['PROTOBUF'] + +def configure(conf): + conf.check_cfg(package='protobuf', uselib_store='PROTOBUF', args=['--cflags', '--libs']) + conf.find_program('protoc', var='PROTOC') + conf.start_msg('Checking for protoc version') + protocver = conf.cmd_and_log(conf.env.PROTOC + ['--version'], output=Context.BOTH) + protocver = ''.join(protocver).strip()[protocver[0].rfind(' ')+1:] + conf.end_msg(protocver) + conf.env.PROTOC_MAJOR = protocver[:protocver.find('.')] + conf.env.PROTOC_ST = '-I%s' + conf.env.PROTOC_FL = '%s' diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/pyqt5.py b/ldb-2.0.8/third_party/waf/waflib/extras/pyqt5.py new file mode 100644 index 0000000..9c94176 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/pyqt5.py @@ -0,0 +1,246 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Federico Pellegrin, 2016-2019 (fedepell) adapted for Python + +""" +This tool helps with finding Python Qt5 tools and libraries, +and provides translation from QT5 files to Python code. + +The following snippet illustrates the tool usage:: + + def options(opt): + opt.load('py pyqt5') + + def configure(conf): + conf.load('py pyqt5') + + def build(bld): + bld( + features = 'py pyqt5', + source = 'main.py textures.qrc aboutDialog.ui', + ) + +Here, the UI description and resource files will be processed +to generate code. + +Usage +===== + +Load the "pyqt5" tool. + +Add into the sources list also the qrc resources files or ui5 +definition files and they will be translated into python code +with the system tools (PyQt5, PySide2, PyQt4 are searched in this +order) and then compiled +""" + +try: + from xml.sax import make_parser + from xml.sax.handler import ContentHandler +except ImportError: + has_xml = False + ContentHandler = object +else: + has_xml = True + +import os +from waflib.Tools import python +from waflib import Task, Options +from waflib.TaskGen import feature, extension +from waflib.Configure import conf +from waflib import Logs + +EXT_RCC = ['.qrc'] +""" +File extension for the resource (.qrc) files +""" + +EXT_UI = ['.ui'] +""" +File extension for the user interface (.ui) files +""" + + +class XMLHandler(ContentHandler): + """ + Parses ``.qrc`` files + """ + def __init__(self): + self.buf = [] + self.files = [] + def startElement(self, name, attrs): + if name == 'file': + self.buf = [] + def endElement(self, name): + if name == 'file': + self.files.append(str(''.join(self.buf))) + def characters(self, cars): + self.buf.append(cars) + +@extension(*EXT_RCC) +def create_pyrcc_task(self, node): + "Creates rcc and py task for ``.qrc`` files" + rcnode = node.change_ext('.py') + self.create_task('pyrcc', node, rcnode) + if getattr(self, 'install_from', None): + self.install_from = self.install_from.get_bld() + else: + self.install_from = self.path.get_bld() + self.install_path = getattr(self, 'install_path', '${PYTHONDIR}') + self.process_py(rcnode) + +@extension(*EXT_UI) +def create_pyuic_task(self, node): + "Create uic tasks and py for user interface ``.ui`` definition files" + uinode = node.change_ext('.py') + self.create_task('ui5py', node, uinode) + if getattr(self, 'install_from', None): + self.install_from = self.install_from.get_bld() + else: + self.install_from = self.path.get_bld() + self.install_path = getattr(self, 'install_path', '${PYTHONDIR}') + self.process_py(uinode) + +@extension('.ts') +def add_pylang(self, node): + """Adds all the .ts file into ``self.lang``""" + self.lang = self.to_list(getattr(self, 'lang', [])) + [node] + +@feature('pyqt5') +def apply_pyqt5(self): + """ + The additional parameters are: + + :param lang: list of translation files (\\*.ts) to process + :type lang: list of :py:class:`waflib.Node.Node` or string without the .ts extension + :param langname: if given, transform the \\*.ts files into a .qrc files to include in the binary file + :type langname: :py:class:`waflib.Node.Node` or string without the .qrc extension + """ + if getattr(self, 'lang', None): + qmtasks = [] + for x in self.to_list(self.lang): + if isinstance(x, str): + x = self.path.find_resource(x + '.ts') + qmtasks.append(self.create_task('ts2qm', x, x.change_ext('.qm'))) + + + if getattr(self, 'langname', None): + qmnodes = [k.outputs[0] for k in qmtasks] + rcnode = self.langname + if isinstance(rcnode, str): + rcnode = self.path.find_or_declare(rcnode + '.qrc') + t = self.create_task('qm2rcc', qmnodes, rcnode) + create_pyrcc_task(self, t.outputs[0]) + +class pyrcc(Task.Task): + """ + Processes ``.qrc`` files + """ + color = 'BLUE' + run_str = '${QT_PYRCC} ${SRC} -o ${TGT}' + ext_out = ['.py'] + + def rcname(self): + return os.path.splitext(self.inputs[0].name)[0] + + def scan(self): + """Parse the *.qrc* files""" + if not has_xml: + Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!') + return ([], []) + + parser = make_parser() + curHandler = XMLHandler() + parser.setContentHandler(curHandler) + fi = open(self.inputs[0].abspath(), 'r') + try: + parser.parse(fi) + finally: + fi.close() + + nodes = [] + names = [] + root = self.inputs[0].parent + for x in curHandler.files: + nd = root.find_resource(x) + if nd: + nodes.append(nd) + else: + names.append(x) + return (nodes, names) + + +class ui5py(Task.Task): + """ + Processes ``.ui`` files for python + """ + color = 'BLUE' + run_str = '${QT_PYUIC} ${SRC} -o ${TGT}' + ext_out = ['.py'] + +class ts2qm(Task.Task): + """ + Generates ``.qm`` files from ``.ts`` files + """ + color = 'BLUE' + run_str = '${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}' + +class qm2rcc(Task.Task): + """ + Generates ``.qrc`` files from ``.qm`` files + """ + color = 'BLUE' + after = 'ts2qm' + def run(self): + """Create a qrc file including the inputs""" + txt = '\n'.join(['%s' % k.path_from(self.outputs[0].parent) for k in self.inputs]) + code = '\n\n%s\n\n' % txt + self.outputs[0].write(code) + +def configure(self): + self.find_pyqt5_binaries() + + # warn about this during the configuration too + if not has_xml: + Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!') + +@conf +def find_pyqt5_binaries(self): + """ + Detects PyQt5 or PySide2 programs such as pyuic5/pyside2-uic, pyrcc5/pyside2-rcc + """ + env = self.env + + if getattr(Options.options, 'want_pyqt5', True): + self.find_program(['pyuic5'], var='QT_PYUIC') + self.find_program(['pyrcc5'], var='QT_PYRCC') + self.find_program(['pylupdate5'], var='QT_PYLUPDATE') + elif getattr(Options.options, 'want_pyside2', True): + self.find_program(['pyside2-uic'], var='QT_PYUIC') + self.find_program(['pyside2-rcc'], var='QT_PYRCC') + self.find_program(['pyside2-lupdate'], var='QT_PYLUPDATE') + elif getattr(Options.options, 'want_pyqt4', True): + self.find_program(['pyuic4'], var='QT_PYUIC') + self.find_program(['pyrcc4'], var='QT_PYRCC') + self.find_program(['pylupdate4'], var='QT_PYLUPDATE') + else: + self.find_program(['pyuic5','pyside2-uic','pyuic4'], var='QT_PYUIC') + self.find_program(['pyrcc5','pyside2-rcc','pyrcc4'], var='QT_PYRCC') + self.find_program(['pylupdate5', 'pyside2-lupdate','pylupdate4'], var='QT_PYLUPDATE') + + if not env.QT_PYUIC: + self.fatal('cannot find the uic compiler for python for qt5') + + if not env.QT_PYRCC: + self.fatal('cannot find the rcc compiler for python for qt5') + + self.find_program(['lrelease-qt5', 'lrelease'], var='QT_LRELEASE') + +def options(opt): + """ + Command-line options + """ + pyqt5opt=opt.add_option_group("Python QT5 Options") + pyqt5opt.add_option('--pyqt5-pyqt5', action='store_true', default=False, dest='want_pyqt5', help='use PyQt5 bindings as python QT5 bindings (default PyQt5 is searched first, PySide2 after, PyQt4 last)') + pyqt5opt.add_option('--pyqt5-pyside2', action='store_true', default=False, dest='want_pyside2', help='use PySide2 bindings as python QT5 bindings (default PyQt5 is searched first, PySide2 after, PyQt4 last)') + pyqt5opt.add_option('--pyqt5-pyqt4', action='store_true', default=False, dest='want_pyqt4', help='use PyQt4 bindings as python QT5 bindings (default PyQt5 is searched first, PySide2 after, PyQt4 last)') diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/pytest.py b/ldb-2.0.8/third_party/waf/waflib/extras/pytest.py new file mode 100644 index 0000000..7dd5a1a --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/pytest.py @@ -0,0 +1,225 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Calle Rosenquist, 2016-2018 (xbreak) + +""" +Provides Python unit test support using :py:class:`waflib.Tools.waf_unit_test.utest` +task via the **pytest** feature. + +To use pytest the following is needed: + +1. Load `pytest` and the dependency `waf_unit_test` tools. +2. Create a task generator with feature `pytest` (not `test`) and customize behaviour with + the following attributes: + + - `pytest_source`: Test input files. + - `ut_str`: Test runner command, e.g. ``${PYTHON} -B -m unittest discover`` or + if nose is used: ``${NOSETESTS} --no-byte-compile ${SRC}``. + - `ut_shell`: Determines if ``ut_str`` is executed in a shell. Default: False. + - `ut_cwd`: Working directory for test runner. Defaults to directory of + first ``pytest_source`` file. + + Additionally the following `pytest` specific attributes are used in dependent taskgens: + + - `pytest_path`: Node or string list of additional Python paths. + - `pytest_libpath`: Node or string list of additional library paths. + +The `use` dependencies are used for both update calculation and to populate +the following environment variables for the `pytest` test runner: + +1. `PYTHONPATH` (`sys.path`) of any dependent taskgen that has the feature `py`: + + - `install_from` attribute is used to determine where the root of the Python sources + are located. If `install_from` is not specified the default is to use the taskgen path + as the root. + + - `pytest_path` attribute is used to manually specify additional Python paths. + +2. Dynamic linker search path variable (e.g. `LD_LIBRARY_PATH`) of any dependent taskgen with + non-static link_task. + + - `pytest_libpath` attribute is used to manually specify additional linker paths. + +Note: `pytest` cannot automatically determine the correct `PYTHONPATH` for `pyext` taskgens + because the extension might be part of a Python package or used standalone: + + - When used as part of another `py` package, the `PYTHONPATH` is provided by + that taskgen so no additional action is required. + + - When used as a standalone module, the user needs to specify the `PYTHONPATH` explicitly + via the `pytest_path` attribute on the `pyext` taskgen. + + For details c.f. the pytest playground examples. + + +For example:: + + # A standalone Python C extension that demonstrates unit test environment population + # of PYTHONPATH and LD_LIBRARY_PATH/PATH/DYLD_LIBRARY_PATH. + # + # Note: `pytest_path` is provided here because pytest cannot automatically determine + # if the extension is part of another Python package or is used standalone. + bld(name = 'foo_ext', + features = 'c cshlib pyext', + source = 'src/foo_ext.c', + target = 'foo_ext', + pytest_path = [ bld.path.get_bld() ]) + + # Python package under test that also depend on the Python module `foo_ext` + # + # Note: `install_from` is added automatically to `PYTHONPATH`. + bld(name = 'foo', + features = 'py', + use = 'foo_ext', + source = bld.path.ant_glob('src/foo/*.py'), + install_from = 'src') + + # Unit test example using the built in module unittest and let that discover + # any test cases. + bld(name = 'foo_test', + features = 'pytest', + use = 'foo', + pytest_source = bld.path.ant_glob('test/*.py'), + ut_str = '${PYTHON} -B -m unittest discover') + +""" + +import os +from waflib import Task, TaskGen, Errors, Utils, Logs +from waflib.Tools import ccroot + +def _process_use_rec(self, name): + """ + Recursively process ``use`` for task generator with name ``name``.. + Used by pytest_process_use. + """ + if name in self.pytest_use_not or name in self.pytest_use_seen: + return + try: + tg = self.bld.get_tgen_by_name(name) + except Errors.WafError: + self.pytest_use_not.add(name) + return + + self.pytest_use_seen.append(name) + tg.post() + + for n in self.to_list(getattr(tg, 'use', [])): + _process_use_rec(self, n) + + +@TaskGen.feature('pytest') +@TaskGen.after_method('process_source', 'apply_link') +def pytest_process_use(self): + """ + Process the ``use`` attribute which contains a list of task generator names and store + paths that later is used to populate the unit test runtime environment. + """ + self.pytest_use_not = set() + self.pytest_use_seen = [] + self.pytest_paths = [] # strings or Nodes + self.pytest_libpaths = [] # strings or Nodes + self.pytest_dep_nodes = [] + + names = self.to_list(getattr(self, 'use', [])) + for name in names: + _process_use_rec(self, name) + + def extend_unique(lst, varlst): + ext = [] + for x in varlst: + if x not in lst: + ext.append(x) + lst.extend(ext) + + # Collect type specific info needed to construct a valid runtime environment + # for the test. + for name in self.pytest_use_seen: + tg = self.bld.get_tgen_by_name(name) + + extend_unique(self.pytest_paths, Utils.to_list(getattr(tg, 'pytest_path', []))) + extend_unique(self.pytest_libpaths, Utils.to_list(getattr(tg, 'pytest_libpath', []))) + + if 'py' in tg.features: + # Python dependencies are added to PYTHONPATH + pypath = getattr(tg, 'install_from', tg.path) + + if 'buildcopy' in tg.features: + # Since buildcopy is used we assume that PYTHONPATH in build should be used, + # not source + extend_unique(self.pytest_paths, [pypath.get_bld().abspath()]) + + # Add buildcopy output nodes to dependencies + extend_unique(self.pytest_dep_nodes, [o for task in getattr(tg, 'tasks', []) \ + for o in getattr(task, 'outputs', [])]) + else: + # If buildcopy is not used, depend on sources instead + extend_unique(self.pytest_dep_nodes, tg.source) + extend_unique(self.pytest_paths, [pypath.abspath()]) + + if getattr(tg, 'link_task', None): + # For tasks with a link_task (C, C++, D et.c.) include their library paths: + if not isinstance(tg.link_task, ccroot.stlink_task): + extend_unique(self.pytest_dep_nodes, tg.link_task.outputs) + extend_unique(self.pytest_libpaths, tg.link_task.env.LIBPATH) + + if 'pyext' in tg.features: + # If the taskgen is extending Python we also want to add the interpreter libpath. + extend_unique(self.pytest_libpaths, tg.link_task.env.LIBPATH_PYEXT) + else: + # Only add to libpath if the link task is not a Python extension + extend_unique(self.pytest_libpaths, [tg.link_task.outputs[0].parent.abspath()]) + + +@TaskGen.feature('pytest') +@TaskGen.after_method('pytest_process_use') +def make_pytest(self): + """ + Creates a ``utest`` task with a populated environment for Python if not specified in ``ut_env``: + + - Paths in `pytest_paths` attribute are used to populate PYTHONPATH + - Paths in `pytest_libpaths` attribute are used to populate the system library path (e.g. LD_LIBRARY_PATH) + """ + nodes = self.to_nodes(self.pytest_source) + tsk = self.create_task('utest', nodes) + + tsk.dep_nodes.extend(self.pytest_dep_nodes) + if getattr(self, 'ut_str', None): + self.ut_run, lst = Task.compile_fun(self.ut_str, shell=getattr(self, 'ut_shell', False)) + tsk.vars = lst + tsk.vars + + if getattr(self, 'ut_cwd', None): + if isinstance(self.ut_cwd, str): + # we want a Node instance + if os.path.isabs(self.ut_cwd): + self.ut_cwd = self.bld.root.make_node(self.ut_cwd) + else: + self.ut_cwd = self.path.make_node(self.ut_cwd) + else: + if tsk.inputs: + self.ut_cwd = tsk.inputs[0].parent + else: + raise Errors.WafError("no valid input files for pytest task, check pytest_source value") + + if not self.ut_cwd.exists(): + self.ut_cwd.mkdir() + + if not hasattr(self, 'ut_env'): + self.ut_env = dict(os.environ) + def add_paths(var, lst): + # Add list of paths to a variable, lst can contain strings or nodes + lst = [ str(n) for n in lst ] + Logs.debug("ut: %s: Adding paths %s=%s", self, var, lst) + self.ut_env[var] = os.pathsep.join(lst) + os.pathsep + self.ut_env.get(var, '') + + # Prepend dependency paths to PYTHONPATH and LD_LIBRARY_PATH + add_paths('PYTHONPATH', self.pytest_paths) + + if Utils.is_win32: + add_paths('PATH', self.pytest_libpaths) + elif Utils.unversioned_sys_platform() == 'darwin': + add_paths('DYLD_LIBRARY_PATH', self.pytest_libpaths) + add_paths('LD_LIBRARY_PATH', self.pytest_libpaths) + else: + add_paths('LD_LIBRARY_PATH', self.pytest_libpaths) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/qnxnto.py b/ldb-2.0.8/third_party/waf/waflib/extras/qnxnto.py new file mode 100644 index 0000000..1158124 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/qnxnto.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Jérôme Carretero 2011 (zougloub) +# QNX neutrino compatibility functions + +import sys, os +from waflib import Utils + +class Popen(object): + """ + Popen cannot work on QNX from a threaded program: + Forking in threads is not implemented in neutrino. + + Python's os.popen / spawn / fork won't work when running in threads (they will if in the main program thread) + + In waf, this happens mostly in build. + And the use cases can be replaced by os.system() calls. + """ + __slots__ = ["prog", "kw", "popen", "verbose"] + verbose = 0 + def __init__(self, prog, **kw): + try: + self.prog = prog + self.kw = kw + self.popen = None + if Popen.verbose: + sys.stdout.write("Popen created: %r, kw=%r..." % (prog, kw)) + + do_delegate = kw.get('stdout') == -1 and kw.get('stderr') == -1 + if do_delegate: + if Popen.verbose: + print("Delegating to real Popen") + self.popen = self.real_Popen(prog, **kw) + else: + if Popen.verbose: + print("Emulating") + except Exception as e: + if Popen.verbose: + print("Exception: %s" % e) + raise + + def __getattr__(self, name): + if Popen.verbose: + sys.stdout.write("Getattr: %s..." % name) + if name in Popen.__slots__: + return object.__getattribute__(self, name) + else: + if self.popen is not None: + if Popen.verbose: + print("from Popen") + return getattr(self.popen, name) + else: + if name == "wait": + return self.emu_wait + else: + raise Exception("subprocess emulation: not implemented: %s" % name) + + def emu_wait(self): + if Popen.verbose: + print("emulated wait (%r kw=%r)" % (self.prog, self.kw)) + if isinstance(self.prog, str): + cmd = self.prog + else: + cmd = " ".join(self.prog) + if 'cwd' in self.kw: + cmd = 'cd "%s" && %s' % (self.kw['cwd'], cmd) + return os.system(cmd) + +if sys.platform == "qnx6": + Popen.real_Popen = Utils.subprocess.Popen + Utils.subprocess.Popen = Popen + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/qt4.py b/ldb-2.0.8/third_party/waf/waflib/extras/qt4.py new file mode 100644 index 0000000..d19a4dd --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/qt4.py @@ -0,0 +1,695 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2006-2010 (ita) + +""" + +Tool Description +================ + +This tool helps with finding Qt4 tools and libraries, +and also provides syntactic sugar for using Qt4 tools. + +The following snippet illustrates the tool usage:: + + def options(opt): + opt.load('compiler_cxx qt4') + + def configure(conf): + conf.load('compiler_cxx qt4') + + def build(bld): + bld( + features = 'qt4 cxx cxxprogram', + uselib = 'QTCORE QTGUI QTOPENGL QTSVG', + source = 'main.cpp textures.qrc aboutDialog.ui', + target = 'window', + ) + +Here, the UI description and resource files will be processed +to generate code. + +Usage +===== + +Load the "qt4" tool. + +You also need to edit your sources accordingly: + +- the normal way of doing things is to have your C++ files + include the .moc file. + This is regarded as the best practice (and provides much faster + compilations). + It also implies that the include paths have beenset properly. + +- to have the include paths added automatically, use the following:: + + from waflib.TaskGen import feature, before_method, after_method + @feature('cxx') + @after_method('process_source') + @before_method('apply_incpaths') + def add_includes_paths(self): + incs = set(self.to_list(getattr(self, 'includes', ''))) + for x in self.compiled_tasks: + incs.add(x.inputs[0].parent.path_from(self.path)) + self.includes = sorted(incs) + +Note: another tool provides Qt processing that does not require +.moc includes, see 'playground/slow_qt/'. + +A few options (--qt{dir,bin,...}) and environment variables +(QT4_{ROOT,DIR,MOC,UIC,XCOMPILE}) allow finer tuning of the tool, +tool path selection, etc; please read the source for more info. + +""" + +try: + from xml.sax import make_parser + from xml.sax.handler import ContentHandler +except ImportError: + has_xml = False + ContentHandler = object +else: + has_xml = True + +import os, sys +from waflib.Tools import cxx +from waflib import Task, Utils, Options, Errors, Context +from waflib.TaskGen import feature, after_method, extension +from waflib.Configure import conf +from waflib import Logs + +MOC_H = ['.h', '.hpp', '.hxx', '.hh'] +""" +File extensions associated to the .moc files +""" + +EXT_RCC = ['.qrc'] +""" +File extension for the resource (.qrc) files +""" + +EXT_UI = ['.ui'] +""" +File extension for the user interface (.ui) files +""" + +EXT_QT4 = ['.cpp', '.cc', '.cxx', '.C'] +""" +File extensions of C++ files that may require a .moc processing +""" + +QT4_LIBS = "QtCore QtGui QtUiTools QtNetwork QtOpenGL QtSql QtSvg QtTest QtXml QtXmlPatterns QtWebKit Qt3Support QtHelp QtScript QtDeclarative QtDesigner" + +class qxx(Task.classes['cxx']): + """ + Each C++ file can have zero or several .moc files to create. + They are known only when the files are scanned (preprocessor) + To avoid scanning the c++ files each time (parsing C/C++), the results + are retrieved from the task cache (bld.node_deps/bld.raw_deps). + The moc tasks are also created *dynamically* during the build. + """ + + def __init__(self, *k, **kw): + Task.Task.__init__(self, *k, **kw) + self.moc_done = 0 + + def runnable_status(self): + """ + Compute the task signature to make sure the scanner was executed. Create the + moc tasks by using :py:meth:`waflib.Tools.qt4.qxx.add_moc_tasks` (if necessary), + then postpone the task execution (there is no need to recompute the task signature). + """ + if self.moc_done: + return Task.Task.runnable_status(self) + else: + for t in self.run_after: + if not t.hasrun: + return Task.ASK_LATER + self.add_moc_tasks() + return Task.Task.runnable_status(self) + + def create_moc_task(self, h_node, m_node): + """ + If several libraries use the same classes, it is possible that moc will run several times (Issue 1318) + It is not possible to change the file names, but we can assume that the moc transformation will be identical, + and the moc tasks can be shared in a global cache. + + The defines passed to moc will then depend on task generator order. If this is not acceptable, then + use the tool slow_qt4 instead (and enjoy the slow builds... :-( ) + """ + try: + moc_cache = self.generator.bld.moc_cache + except AttributeError: + moc_cache = self.generator.bld.moc_cache = {} + + try: + return moc_cache[h_node] + except KeyError: + tsk = moc_cache[h_node] = Task.classes['moc'](env=self.env, generator=self.generator) + tsk.set_inputs(h_node) + tsk.set_outputs(m_node) + + if self.generator: + self.generator.tasks.append(tsk) + + # direct injection in the build phase (safe because called from the main thread) + gen = self.generator.bld.producer + gen.outstanding.append(tsk) + gen.total += 1 + + return tsk + + def moc_h_ext(self): + ext = [] + try: + ext = Options.options.qt_header_ext.split() + except AttributeError: + pass + if not ext: + ext = MOC_H + return ext + + def add_moc_tasks(self): + """ + Create the moc tasks by looking in ``bld.raw_deps[self.uid()]`` + """ + node = self.inputs[0] + bld = self.generator.bld + + try: + # compute the signature once to know if there is a moc file to create + self.signature() + except KeyError: + # the moc file may be referenced somewhere else + pass + else: + # remove the signature, it must be recomputed with the moc task + delattr(self, 'cache_sig') + + include_nodes = [node.parent] + self.generator.includes_nodes + + moctasks = [] + mocfiles = set() + for d in bld.raw_deps.get(self.uid(), []): + if not d.endswith('.moc'): + continue + + # process that base.moc only once + if d in mocfiles: + continue + mocfiles.add(d) + + # find the source associated with the moc file + h_node = None + + base2 = d[:-4] + for x in include_nodes: + for e in self.moc_h_ext(): + h_node = x.find_node(base2 + e) + if h_node: + break + if h_node: + m_node = h_node.change_ext('.moc') + break + else: + # foo.cpp -> foo.cpp.moc + for k in EXT_QT4: + if base2.endswith(k): + for x in include_nodes: + h_node = x.find_node(base2) + if h_node: + break + if h_node: + m_node = h_node.change_ext(k + '.moc') + break + + if not h_node: + raise Errors.WafError('No source found for %r which is a moc file' % d) + + # create the moc task + task = self.create_moc_task(h_node, m_node) + moctasks.append(task) + + # simple scheduler dependency: run the moc task before others + self.run_after.update(set(moctasks)) + self.moc_done = 1 + +class trans_update(Task.Task): + """Update a .ts files from a list of C++ files""" + run_str = '${QT_LUPDATE} ${SRC} -ts ${TGT}' + color = 'BLUE' + +class XMLHandler(ContentHandler): + """ + Parser for *.qrc* files + """ + def __init__(self): + self.buf = [] + self.files = [] + def startElement(self, name, attrs): + if name == 'file': + self.buf = [] + def endElement(self, name): + if name == 'file': + self.files.append(str(''.join(self.buf))) + def characters(self, cars): + self.buf.append(cars) + +@extension(*EXT_RCC) +def create_rcc_task(self, node): + "Create rcc and cxx tasks for *.qrc* files" + rcnode = node.change_ext('_rc.cpp') + self.create_task('rcc', node, rcnode) + cpptask = self.create_task('cxx', rcnode, rcnode.change_ext('.o')) + try: + self.compiled_tasks.append(cpptask) + except AttributeError: + self.compiled_tasks = [cpptask] + return cpptask + +@extension(*EXT_UI) +def create_uic_task(self, node): + "hook for uic tasks" + uictask = self.create_task('ui4', node) + uictask.outputs = [self.path.find_or_declare(self.env['ui_PATTERN'] % node.name[:-3])] + +@extension('.ts') +def add_lang(self, node): + """add all the .ts file into self.lang""" + self.lang = self.to_list(getattr(self, 'lang', [])) + [node] + +@feature('qt4') +@after_method('apply_link') +def apply_qt4(self): + """ + Add MOC_FLAGS which may be necessary for moc:: + + def build(bld): + bld.program(features='qt4', source='main.cpp', target='app', use='QTCORE') + + The additional parameters are: + + :param lang: list of translation files (\\*.ts) to process + :type lang: list of :py:class:`waflib.Node.Node` or string without the .ts extension + :param update: whether to process the C++ files to update the \\*.ts files (use **waf --translate**) + :type update: bool + :param langname: if given, transform the \\*.ts files into a .qrc files to include in the binary file + :type langname: :py:class:`waflib.Node.Node` or string without the .qrc extension + """ + if getattr(self, 'lang', None): + qmtasks = [] + for x in self.to_list(self.lang): + if isinstance(x, str): + x = self.path.find_resource(x + '.ts') + qmtasks.append(self.create_task('ts2qm', x, x.change_ext('.qm'))) + + if getattr(self, 'update', None) and Options.options.trans_qt4: + cxxnodes = [a.inputs[0] for a in self.compiled_tasks] + [ + a.inputs[0] for a in self.tasks if getattr(a, 'inputs', None) and a.inputs[0].name.endswith('.ui')] + for x in qmtasks: + self.create_task('trans_update', cxxnodes, x.inputs) + + if getattr(self, 'langname', None): + qmnodes = [x.outputs[0] for x in qmtasks] + rcnode = self.langname + if isinstance(rcnode, str): + rcnode = self.path.find_or_declare(rcnode + '.qrc') + t = self.create_task('qm2rcc', qmnodes, rcnode) + k = create_rcc_task(self, t.outputs[0]) + self.link_task.inputs.append(k.outputs[0]) + + lst = [] + for flag in self.to_list(self.env['CXXFLAGS']): + if len(flag) < 2: + continue + f = flag[0:2] + if f in ('-D', '-I', '/D', '/I'): + if (f[0] == '/'): + lst.append('-' + flag[1:]) + else: + lst.append(flag) + self.env.append_value('MOC_FLAGS', lst) + +@extension(*EXT_QT4) +def cxx_hook(self, node): + """ + Re-map C++ file extensions to the :py:class:`waflib.Tools.qt4.qxx` task. + """ + return self.create_compiled_task('qxx', node) + +class rcc(Task.Task): + """ + Process *.qrc* files + """ + color = 'BLUE' + run_str = '${QT_RCC} -name ${tsk.rcname()} ${SRC[0].abspath()} ${RCC_ST} -o ${TGT}' + ext_out = ['.h'] + + def rcname(self): + return os.path.splitext(self.inputs[0].name)[0] + + def scan(self): + """Parse the *.qrc* files""" + if not has_xml: + Logs.error('no xml support was found, the rcc dependencies will be incomplete!') + return ([], []) + + parser = make_parser() + curHandler = XMLHandler() + parser.setContentHandler(curHandler) + fi = open(self.inputs[0].abspath(), 'r') + try: + parser.parse(fi) + finally: + fi.close() + + nodes = [] + names = [] + root = self.inputs[0].parent + for x in curHandler.files: + nd = root.find_resource(x) + if nd: + nodes.append(nd) + else: + names.append(x) + return (nodes, names) + +class moc(Task.Task): + """ + Create *.moc* files + """ + color = 'BLUE' + run_str = '${QT_MOC} ${MOC_FLAGS} ${MOCCPPPATH_ST:INCPATHS} ${MOCDEFINES_ST:DEFINES} ${SRC} ${MOC_ST} ${TGT}' + def keyword(self): + return "Creating" + def __str__(self): + return self.outputs[0].path_from(self.generator.bld.launch_node()) + +class ui4(Task.Task): + """ + Process *.ui* files + """ + color = 'BLUE' + run_str = '${QT_UIC} ${SRC} -o ${TGT}' + ext_out = ['.h'] + +class ts2qm(Task.Task): + """ + Create *.qm* files from *.ts* files + """ + color = 'BLUE' + run_str = '${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}' + +class qm2rcc(Task.Task): + """ + Transform *.qm* files into *.rc* files + """ + color = 'BLUE' + after = 'ts2qm' + + def run(self): + """Create a qrc file including the inputs""" + txt = '\n'.join(['%s' % k.path_from(self.outputs[0].parent) for k in self.inputs]) + code = '\n\n%s\n\n' % txt + self.outputs[0].write(code) + +def configure(self): + """ + Besides the configuration options, the environment variable QT4_ROOT may be used + to give the location of the qt4 libraries (absolute path). + + The detection will use the program *pkg-config* through :py:func:`waflib.Tools.config_c.check_cfg` + """ + self.find_qt4_binaries() + self.set_qt4_libs_to_check() + self.set_qt4_defines() + self.find_qt4_libraries() + self.add_qt4_rpath() + self.simplify_qt4_libs() + +@conf +def find_qt4_binaries(self): + env = self.env + opt = Options.options + + qtdir = getattr(opt, 'qtdir', '') + qtbin = getattr(opt, 'qtbin', '') + + paths = [] + + if qtdir: + qtbin = os.path.join(qtdir, 'bin') + + # the qt directory has been given from QT4_ROOT - deduce the qt binary path + if not qtdir: + qtdir = os.environ.get('QT4_ROOT', '') + qtbin = os.environ.get('QT4_BIN') or os.path.join(qtdir, 'bin') + + if qtbin: + paths = [qtbin] + + # no qtdir, look in the path and in /usr/local/Trolltech + if not qtdir: + paths = os.environ.get('PATH', '').split(os.pathsep) + paths.append('/usr/share/qt4/bin/') + try: + lst = Utils.listdir('/usr/local/Trolltech/') + except OSError: + pass + else: + if lst: + lst.sort() + lst.reverse() + + # keep the highest version + qtdir = '/usr/local/Trolltech/%s/' % lst[0] + qtbin = os.path.join(qtdir, 'bin') + paths.append(qtbin) + + # at the end, try to find qmake in the paths given + # keep the one with the highest version + cand = None + prev_ver = ['4', '0', '0'] + for qmk in ('qmake-qt4', 'qmake4', 'qmake'): + try: + qmake = self.find_program(qmk, path_list=paths) + except self.errors.ConfigurationError: + pass + else: + try: + version = self.cmd_and_log(qmake + ['-query', 'QT_VERSION']).strip() + except self.errors.WafError: + pass + else: + if version: + new_ver = version.split('.') + if new_ver > prev_ver: + cand = qmake + prev_ver = new_ver + if cand: + self.env.QMAKE = cand + else: + self.fatal('Could not find qmake for qt4') + + qtbin = self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_INSTALL_BINS']).strip() + os.sep + + def find_bin(lst, var): + if var in env: + return + for f in lst: + try: + ret = self.find_program(f, path_list=paths) + except self.errors.ConfigurationError: + pass + else: + env[var]=ret + break + + find_bin(['uic-qt3', 'uic3'], 'QT_UIC3') + find_bin(['uic-qt4', 'uic'], 'QT_UIC') + if not env.QT_UIC: + self.fatal('cannot find the uic compiler for qt4') + + self.start_msg('Checking for uic version') + uicver = self.cmd_and_log(env.QT_UIC + ["-version"], output=Context.BOTH) + uicver = ''.join(uicver).strip() + uicver = uicver.replace('Qt User Interface Compiler ','').replace('User Interface Compiler for Qt', '') + self.end_msg(uicver) + if uicver.find(' 3.') != -1: + self.fatal('this uic compiler is for qt3, add uic for qt4 to your path') + + find_bin(['moc-qt4', 'moc'], 'QT_MOC') + find_bin(['rcc-qt4', 'rcc'], 'QT_RCC') + find_bin(['lrelease-qt4', 'lrelease'], 'QT_LRELEASE') + find_bin(['lupdate-qt4', 'lupdate'], 'QT_LUPDATE') + + env['UIC3_ST']= '%s -o %s' + env['UIC_ST'] = '%s -o %s' + env['MOC_ST'] = '-o' + env['ui_PATTERN'] = 'ui_%s.h' + env['QT_LRELEASE_FLAGS'] = ['-silent'] + env.MOCCPPPATH_ST = '-I%s' + env.MOCDEFINES_ST = '-D%s' + +@conf +def find_qt4_libraries(self): + qtlibs = getattr(Options.options, 'qtlibs', None) or os.environ.get("QT4_LIBDIR") + if not qtlibs: + try: + qtlibs = self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_INSTALL_LIBS']).strip() + except Errors.WafError: + qtdir = self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_INSTALL_PREFIX']).strip() + os.sep + qtlibs = os.path.join(qtdir, 'lib') + self.msg('Found the Qt4 libraries in', qtlibs) + + qtincludes = os.environ.get("QT4_INCLUDES") or self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_INSTALL_HEADERS']).strip() + env = self.env + if not 'PKG_CONFIG_PATH' in os.environ: + os.environ['PKG_CONFIG_PATH'] = '%s:%s/pkgconfig:/usr/lib/qt4/lib/pkgconfig:/opt/qt4/lib/pkgconfig:/usr/lib/qt4/lib:/opt/qt4/lib' % (qtlibs, qtlibs) + + try: + if os.environ.get("QT4_XCOMPILE"): + raise self.errors.ConfigurationError() + self.check_cfg(atleast_pkgconfig_version='0.1') + except self.errors.ConfigurationError: + for i in self.qt4_vars: + uselib = i.upper() + if Utils.unversioned_sys_platform() == "darwin": + # Since at least qt 4.7.3 each library locates in separate directory + frameworkName = i + ".framework" + qtDynamicLib = os.path.join(qtlibs, frameworkName, i) + if os.path.exists(qtDynamicLib): + env.append_unique('FRAMEWORK_' + uselib, i) + self.msg('Checking for %s' % i, qtDynamicLib, 'GREEN') + else: + self.msg('Checking for %s' % i, False, 'YELLOW') + env.append_unique('INCLUDES_' + uselib, os.path.join(qtlibs, frameworkName, 'Headers')) + elif env.DEST_OS != "win32": + qtDynamicLib = os.path.join(qtlibs, "lib" + i + ".so") + qtStaticLib = os.path.join(qtlibs, "lib" + i + ".a") + if os.path.exists(qtDynamicLib): + env.append_unique('LIB_' + uselib, i) + self.msg('Checking for %s' % i, qtDynamicLib, 'GREEN') + elif os.path.exists(qtStaticLib): + env.append_unique('LIB_' + uselib, i) + self.msg('Checking for %s' % i, qtStaticLib, 'GREEN') + else: + self.msg('Checking for %s' % i, False, 'YELLOW') + + env.append_unique('LIBPATH_' + uselib, qtlibs) + env.append_unique('INCLUDES_' + uselib, qtincludes) + env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i)) + else: + # Release library names are like QtCore4 + for k in ("lib%s.a", "lib%s4.a", "%s.lib", "%s4.lib"): + lib = os.path.join(qtlibs, k % i) + if os.path.exists(lib): + env.append_unique('LIB_' + uselib, i + k[k.find("%s") + 2 : k.find('.')]) + self.msg('Checking for %s' % i, lib, 'GREEN') + break + else: + self.msg('Checking for %s' % i, False, 'YELLOW') + + env.append_unique('LIBPATH_' + uselib, qtlibs) + env.append_unique('INCLUDES_' + uselib, qtincludes) + env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i)) + + # Debug library names are like QtCore4d + uselib = i.upper() + "_debug" + for k in ("lib%sd.a", "lib%sd4.a", "%sd.lib", "%sd4.lib"): + lib = os.path.join(qtlibs, k % i) + if os.path.exists(lib): + env.append_unique('LIB_' + uselib, i + k[k.find("%s") + 2 : k.find('.')]) + self.msg('Checking for %s' % i, lib, 'GREEN') + break + else: + self.msg('Checking for %s' % i, False, 'YELLOW') + + env.append_unique('LIBPATH_' + uselib, qtlibs) + env.append_unique('INCLUDES_' + uselib, qtincludes) + env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i)) + else: + for i in self.qt4_vars_debug + self.qt4_vars: + self.check_cfg(package=i, args='--cflags --libs', mandatory=False) + +@conf +def simplify_qt4_libs(self): + # the libpaths make really long command-lines + # remove the qtcore ones from qtgui, etc + env = self.env + def process_lib(vars_, coreval): + for d in vars_: + var = d.upper() + if var == 'QTCORE': + continue + + value = env['LIBPATH_'+var] + if value: + core = env[coreval] + accu = [] + for lib in value: + if lib in core: + continue + accu.append(lib) + env['LIBPATH_'+var] = accu + + process_lib(self.qt4_vars, 'LIBPATH_QTCORE') + process_lib(self.qt4_vars_debug, 'LIBPATH_QTCORE_DEBUG') + +@conf +def add_qt4_rpath(self): + # rpath if wanted + env = self.env + if getattr(Options.options, 'want_rpath', False): + def process_rpath(vars_, coreval): + for d in vars_: + var = d.upper() + value = env['LIBPATH_'+var] + if value: + core = env[coreval] + accu = [] + for lib in value: + if var != 'QTCORE': + if lib in core: + continue + accu.append('-Wl,--rpath='+lib) + env['RPATH_'+var] = accu + process_rpath(self.qt4_vars, 'LIBPATH_QTCORE') + process_rpath(self.qt4_vars_debug, 'LIBPATH_QTCORE_DEBUG') + +@conf +def set_qt4_libs_to_check(self): + if not hasattr(self, 'qt4_vars'): + self.qt4_vars = QT4_LIBS + self.qt4_vars = Utils.to_list(self.qt4_vars) + if not hasattr(self, 'qt4_vars_debug'): + self.qt4_vars_debug = [a + '_debug' for a in self.qt4_vars] + self.qt4_vars_debug = Utils.to_list(self.qt4_vars_debug) + +@conf +def set_qt4_defines(self): + if sys.platform != 'win32': + return + for x in self.qt4_vars: + y = x[2:].upper() + self.env.append_unique('DEFINES_%s' % x.upper(), 'QT_%s_LIB' % y) + self.env.append_unique('DEFINES_%s_DEBUG' % x.upper(), 'QT_%s_LIB' % y) + +def options(opt): + """ + Command-line options + """ + opt.add_option('--want-rpath', action='store_true', default=False, dest='want_rpath', help='enable the rpath for qt libraries') + + opt.add_option('--header-ext', + type='string', + default='', + help='header extension for moc files', + dest='qt_header_ext') + + for i in 'qtdir qtbin qtlibs'.split(): + opt.add_option('--'+i, type='string', default='', dest=i) + + opt.add_option('--translate', action="store_true", help="collect translation strings", dest="trans_qt4", default=False) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/relocation.py b/ldb-2.0.8/third_party/waf/waflib/extras/relocation.py new file mode 100644 index 0000000..7e821f4 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/relocation.py @@ -0,0 +1,85 @@ +#! /usr/bin/env python +# encoding: utf-8 + +""" +Waf 1.6 + +Try to detect if the project directory was relocated, and if it was, +change the node representing the project directory. Just call: + + waf configure build + +Note that if the project directory name changes, the signatures for the tasks using +files in that directory will change, causing a partial build. +""" + +import os +from waflib import Build, ConfigSet, Task, Utils, Errors +from waflib.TaskGen import feature, after_method + +EXTRA_LOCK = '.old_srcdir' + +old1 = Build.BuildContext.store +def store(self): + old1(self) + db = os.path.join(self.variant_dir, EXTRA_LOCK) + env = ConfigSet.ConfigSet() + env.SRCDIR = self.srcnode.abspath() + env.store(db) +Build.BuildContext.store = store + +old2 = Build.BuildContext.init_dirs +def init_dirs(self): + + if not (os.path.isabs(self.top_dir) and os.path.isabs(self.out_dir)): + raise Errors.WafError('The project was not configured: run "waf configure" first!') + + srcdir = None + db = os.path.join(self.variant_dir, EXTRA_LOCK) + env = ConfigSet.ConfigSet() + try: + env.load(db) + srcdir = env.SRCDIR + except: + pass + + if srcdir: + d = self.root.find_node(srcdir) + if d and srcdir != self.top_dir and getattr(d, 'children', ''): + srcnode = self.root.make_node(self.top_dir) + print("relocating the source directory %r -> %r" % (srcdir, self.top_dir)) + srcnode.children = {} + + for (k, v) in d.children.items(): + srcnode.children[k] = v + v.parent = srcnode + d.children = {} + + old2(self) + +Build.BuildContext.init_dirs = init_dirs + + +def uid(self): + try: + return self.uid_ + except AttributeError: + # this is not a real hot zone, but we want to avoid surprises here + m = Utils.md5() + up = m.update + up(self.__class__.__name__.encode()) + for x in self.inputs + self.outputs: + up(x.path_from(x.ctx.srcnode).encode()) + self.uid_ = m.digest() + return self.uid_ +Task.Task.uid = uid + +@feature('c', 'cxx', 'd', 'go', 'asm', 'fc', 'includes') +@after_method('propagate_uselib_vars', 'process_source') +def apply_incpaths(self): + lst = self.to_incnodes(self.to_list(getattr(self, 'includes', [])) + self.env['INCLUDES']) + self.includes_nodes = lst + bld = self.bld + self.env['INCPATHS'] = [x.is_child_of(bld.srcnode) and x.path_from(bld.bldnode) or x.abspath() for x in lst] + + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/remote.py b/ldb-2.0.8/third_party/waf/waflib/extras/remote.py new file mode 100644 index 0000000..f43b600 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/remote.py @@ -0,0 +1,327 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Remote Builds tool using rsync+ssh + +__author__ = "Jérôme Carretero " +__copyright__ = "Jérôme Carretero, 2013" + +""" +Simple Remote Builds +******************** + +This tool is an *experimental* tool (meaning, do not even try to pollute +the waf bug tracker with bugs in here, contact me directly) providing simple +remote builds. + +It uses rsync and ssh to perform the remote builds. +It is intended for performing cross-compilation on platforms where +a cross-compiler is either unavailable (eg. MacOS, QNX) a specific product +does not exist (eg. Windows builds using Visual Studio) or simply not installed. +This tool sends the sources and the waf script to the remote host, +and commands the usual waf execution. + +There are alternatives to using this tool, such as setting up shared folders, +logging on to remote machines, and building on the shared folders. +Electing one method or another depends on the size of the program. + + +Usage +===== + +1. Set your wscript file so it includes a list of variants, + e.g.:: + + from waflib import Utils + top = '.' + out = 'build' + + variants = [ + 'linux_64_debug', + 'linux_64_release', + 'linux_32_debug', + 'linux_32_release', + ] + + from waflib.extras import remote + + def options(opt): + # normal stuff from here on + opt.load('compiler_c') + + def configure(conf): + if not conf.variant: + return + # normal stuff from here on + conf.load('compiler_c') + + def build(bld): + if not bld.variant: + return + # normal stuff from here on + bld(features='c cprogram', target='app', source='main.c') + + +2. Build the waf file, so it includes this tool, and put it in the current + directory + + .. code:: bash + + ./waf-light --tools=remote + +3. Set the host names to access the hosts: + + .. code:: bash + + export REMOTE_QNX=user@kiunix + +4. Setup the ssh server and ssh keys + + The ssh key should not be protected by a password, or it will prompt for it every time. + Create the key on the client: + + .. code:: bash + + ssh-keygen -t rsa -f foo.rsa + + Then copy foo.rsa.pub to the remote machine (user@kiunix:/home/user/.ssh/authorized_keys), + and make sure the permissions are correct (chmod go-w ~ ~/.ssh ~/.ssh/authorized_keys) + + A separate key for the build processes can be set in the environment variable WAF_SSH_KEY. + The tool will then use 'ssh-keyscan' to avoid prompting for remote hosts, so + be warned to use this feature on internal networks only (MITM). + + .. code:: bash + + export WAF_SSH_KEY=~/foo.rsa + +5. Perform the build: + + .. code:: bash + + waf configure_all build_all --remote + +""" + + +import getpass, os, re, sys +from collections import OrderedDict +from waflib import Context, Options, Utils, ConfigSet + +from waflib.Build import BuildContext, CleanContext, InstallContext, UninstallContext +from waflib.Configure import ConfigurationContext + + +is_remote = False +if '--remote' in sys.argv: + is_remote = True + sys.argv.remove('--remote') + +class init(Context.Context): + """ + Generates the *_all commands + """ + cmd = 'init' + fun = 'init' + def execute(self): + for x in list(Context.g_module.variants): + self.make_variant(x) + lst = ['remote'] + for k in Options.commands: + if k.endswith('_all'): + name = k.replace('_all', '') + for x in Context.g_module.variants: + lst.append('%s_%s' % (name, x)) + else: + lst.append(k) + del Options.commands[:] + Options.commands += lst + + def make_variant(self, x): + for y in (BuildContext, CleanContext, InstallContext, UninstallContext): + name = y.__name__.replace('Context','').lower() + class tmp(y): + cmd = name + '_' + x + fun = 'build' + variant = x + class tmp(ConfigurationContext): + cmd = 'configure_' + x + fun = 'configure' + variant = x + def __init__(self, **kw): + ConfigurationContext.__init__(self, **kw) + self.setenv(x) + +class remote(BuildContext): + cmd = 'remote' + fun = 'build' + + def get_ssh_hosts(self): + lst = [] + for v in Context.g_module.variants: + self.env.HOST = self.login_to_host(self.variant_to_login(v)) + cmd = Utils.subst_vars('${SSH_KEYSCAN} -t rsa,ecdsa ${HOST}', self.env) + out, err = self.cmd_and_log(cmd, output=Context.BOTH, quiet=Context.BOTH) + lst.append(out.strip()) + return lst + + def setup_private_ssh_key(self): + """ + When WAF_SSH_KEY points to a private key, a .ssh directory will be created in the build directory + Make sure that the ssh key does not prompt for a password + """ + key = os.environ.get('WAF_SSH_KEY', '') + if not key: + return + if not os.path.isfile(key): + self.fatal('Key in WAF_SSH_KEY must point to a valid file') + self.ssh_dir = os.path.join(self.path.abspath(), 'build', '.ssh') + self.ssh_hosts = os.path.join(self.ssh_dir, 'known_hosts') + self.ssh_key = os.path.join(self.ssh_dir, os.path.basename(key)) + self.ssh_config = os.path.join(self.ssh_dir, 'config') + for x in self.ssh_hosts, self.ssh_key, self.ssh_config: + if not os.path.isfile(x): + if not os.path.isdir(self.ssh_dir): + os.makedirs(self.ssh_dir) + Utils.writef(self.ssh_key, Utils.readf(key), 'wb') + os.chmod(self.ssh_key, 448) + + Utils.writef(self.ssh_hosts, '\n'.join(self.get_ssh_hosts())) + os.chmod(self.ssh_key, 448) + + Utils.writef(self.ssh_config, 'UserKnownHostsFile %s' % self.ssh_hosts, 'wb') + os.chmod(self.ssh_config, 448) + self.env.SSH_OPTS = ['-F', self.ssh_config, '-i', self.ssh_key] + self.env.append_value('RSYNC_SEND_OPTS', '--exclude=build/.ssh') + + def skip_unbuildable_variant(self): + # skip variants that cannot be built on this OS + for k in Options.commands: + a, _, b = k.partition('_') + if b in Context.g_module.variants: + c, _, _ = b.partition('_') + if c != Utils.unversioned_sys_platform(): + Options.commands.remove(k) + + def login_to_host(self, login): + return re.sub(r'(\w+@)', '', login) + + def variant_to_login(self, variant): + """linux_32_debug -> search env.LINUX_32 and then env.LINUX""" + x = variant[:variant.rfind('_')] + ret = os.environ.get('REMOTE_' + x.upper(), '') + if not ret: + x = x[:x.find('_')] + ret = os.environ.get('REMOTE_' + x.upper(), '') + if not ret: + ret = '%s@localhost' % getpass.getuser() + return ret + + def execute(self): + global is_remote + if not is_remote: + self.skip_unbuildable_variant() + else: + BuildContext.execute(self) + + def restore(self): + self.top_dir = os.path.abspath(Context.g_module.top) + self.srcnode = self.root.find_node(self.top_dir) + self.path = self.srcnode + + self.out_dir = os.path.join(self.top_dir, Context.g_module.out) + self.bldnode = self.root.make_node(self.out_dir) + self.bldnode.mkdir() + + self.env = ConfigSet.ConfigSet() + + def extract_groups_of_builds(self): + """Return a dict mapping each variants to the commands to build""" + self.vgroups = {} + for x in reversed(Options.commands): + _, _, variant = x.partition('_') + if variant in Context.g_module.variants: + try: + dct = self.vgroups[variant] + except KeyError: + dct = self.vgroups[variant] = OrderedDict() + try: + dct[variant].append(x) + except KeyError: + dct[variant] = [x] + Options.commands.remove(x) + + def custom_options(self, login): + try: + return Context.g_module.host_options[login] + except (AttributeError, KeyError): + return {} + + def recurse(self, *k, **kw): + self.env.RSYNC = getattr(Context.g_module, 'rsync', 'rsync -a --chmod=u+rwx') + self.env.SSH = getattr(Context.g_module, 'ssh', 'ssh') + self.env.SSH_KEYSCAN = getattr(Context.g_module, 'ssh_keyscan', 'ssh-keyscan') + try: + self.env.WAF = getattr(Context.g_module, 'waf') + except AttributeError: + try: + os.stat('waf') + except KeyError: + self.fatal('Put a waf file in the directory (./waf-light --tools=remote)') + else: + self.env.WAF = './waf' + + self.extract_groups_of_builds() + self.setup_private_ssh_key() + for k, v in self.vgroups.items(): + task = self(rule=rsync_and_ssh, always=True) + task.env.login = self.variant_to_login(k) + + task.env.commands = [] + for opt, value in v.items(): + task.env.commands += value + task.env.variant = task.env.commands[0].partition('_')[2] + for opt, value in self.custom_options(k): + task.env[opt] = value + self.jobs = len(self.vgroups) + + def make_mkdir_command(self, task): + return Utils.subst_vars('${SSH} ${SSH_OPTS} ${login} "rm -fr ${remote_dir} && mkdir -p ${remote_dir}"', task.env) + + def make_send_command(self, task): + return Utils.subst_vars('${RSYNC} ${RSYNC_SEND_OPTS} -e "${SSH} ${SSH_OPTS}" ${local_dir} ${login}:${remote_dir}', task.env) + + def make_exec_command(self, task): + txt = '''${SSH} ${SSH_OPTS} ${login} "cd ${remote_dir} && ${WAF} ${commands}"''' + return Utils.subst_vars(txt, task.env) + + def make_save_command(self, task): + return Utils.subst_vars('${RSYNC} ${RSYNC_SAVE_OPTS} -e "${SSH} ${SSH_OPTS}" ${login}:${remote_dir_variant} ${build_dir}', task.env) + +def rsync_and_ssh(task): + + # remove a warning + task.uid_ = id(task) + + bld = task.generator.bld + + task.env.user, _, _ = task.env.login.partition('@') + task.env.hdir = Utils.to_hex(Utils.h_list((task.generator.path.abspath(), task.env.variant))) + task.env.remote_dir = '~%s/wafremote/%s' % (task.env.user, task.env.hdir) + task.env.local_dir = bld.srcnode.abspath() + '/' + + task.env.remote_dir_variant = '%s/%s/%s' % (task.env.remote_dir, Context.g_module.out, task.env.variant) + task.env.build_dir = bld.bldnode.abspath() + + ret = task.exec_command(bld.make_mkdir_command(task)) + if ret: + return ret + ret = task.exec_command(bld.make_send_command(task)) + if ret: + return ret + ret = task.exec_command(bld.make_exec_command(task)) + if ret: + return ret + ret = task.exec_command(bld.make_save_command(task)) + if ret: + return ret + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/resx.py b/ldb-2.0.8/third_party/waf/waflib/extras/resx.py new file mode 100644 index 0000000..caf4d31 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/resx.py @@ -0,0 +1,35 @@ +#! /usr/bin/env python +# encoding: utf-8 + +import os +from waflib import Task +from waflib.TaskGen import extension + +def configure(conf): + conf.find_program(['resgen'], var='RESGEN') + conf.env.RESGENFLAGS = '/useSourcePath' + +@extension('.resx') +def resx_file(self, node): + """ + Bind the .resx extension to a resgen task + """ + if not getattr(self, 'cs_task', None): + self.bld.fatal('resx_file has no link task for use %r' % self) + + # Given assembly 'Foo' and file 'Sub/Dir/File.resx', create 'Foo.Sub.Dir.File.resources' + assembly = getattr(self, 'namespace', os.path.splitext(self.gen)[0]) + res = os.path.splitext(node.path_from(self.path))[0].replace('/', '.').replace('\\', '.') + out = self.path.find_or_declare(assembly + '.' + res + '.resources') + + tsk = self.create_task('resgen', node, out) + + self.cs_task.dep_nodes.extend(tsk.outputs) # dependency + self.env.append_value('RESOURCES', tsk.outputs[0].bldpath()) + +class resgen(Task.Task): + """ + Compile C# resource files + """ + color = 'YELLOW' + run_str = '${RESGEN} ${RESGENFLAGS} ${SRC} ${TGT}' diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/review.py b/ldb-2.0.8/third_party/waf/waflib/extras/review.py new file mode 100644 index 0000000..561e062 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/review.py @@ -0,0 +1,325 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Laurent Birtz, 2011 +# moved the code into a separate tool (ita) + +""" +There are several things here: +- a different command-line option management making options persistent +- the review command to display the options set + +Assumptions: +- configuration options are not always added to the right group (and do not count on the users to do it...) +- the options are persistent between the executions (waf options are NOT persistent by design), even for the configuration +- when the options change, the build is invalidated (forcing a reconfiguration) +""" + +import os, textwrap, shutil +from waflib import Logs, Context, ConfigSet, Options, Build, Configure + +class Odict(dict): + """Ordered dictionary""" + def __init__(self, data=None): + self._keys = [] + dict.__init__(self) + if data: + # we were provided a regular dict + if isinstance(data, dict): + self.append_from_dict(data) + + # we were provided a tuple list + elif type(data) == list: + self.append_from_plist(data) + + # we were provided invalid input + else: + raise Exception("expected a dict or a tuple list") + + def append_from_dict(self, dict): + map(self.__setitem__, dict.keys(), dict.values()) + + def append_from_plist(self, plist): + for pair in plist: + if len(pair) != 2: + raise Exception("invalid pairs list") + for (k, v) in plist: + self.__setitem__(k, v) + + def __delitem__(self, key): + if not key in self._keys: + raise KeyError(key) + dict.__delitem__(self, key) + self._keys.remove(key) + + def __setitem__(self, key, item): + dict.__setitem__(self, key, item) + if key not in self._keys: + self._keys.append(key) + + def clear(self): + dict.clear(self) + self._keys = [] + + def copy(self): + return Odict(self.plist()) + + def items(self): + return zip(self._keys, self.values()) + + def keys(self): + return list(self._keys) # return a copy of the list + + def values(self): + return map(self.get, self._keys) + + def plist(self): + p = [] + for k, v in self.items(): + p.append( (k, v) ) + return p + + def __str__(self): + buf = [] + buf.append("{ ") + for k, v in self.items(): + buf.append('%r : %r, ' % (k, v)) + buf.append("}") + return ''.join(buf) + +review_options = Odict() +""" +Ordered dictionary mapping configuration option names to their optparse option. +""" + +review_defaults = {} +""" +Dictionary mapping configuration option names to their default value. +""" + +old_review_set = None +""" +Review set containing the configuration values before parsing the command line. +""" + +new_review_set = None +""" +Review set containing the configuration values after parsing the command line. +""" + +class OptionsReview(Options.OptionsContext): + def __init__(self, **kw): + super(self.__class__, self).__init__(**kw) + + def prepare_config_review(self): + """ + Find the configuration options that are reviewable, detach + their default value from their optparse object and store them + into the review dictionaries. + """ + gr = self.get_option_group('configure options') + for opt in gr.option_list: + if opt.action != 'store' or opt.dest in ("out", "top"): + continue + review_options[opt.dest] = opt + review_defaults[opt.dest] = opt.default + if gr.defaults.has_key(opt.dest): + del gr.defaults[opt.dest] + opt.default = None + + def parse_args(self): + self.prepare_config_review() + self.parser.get_option('--prefix').help = 'installation prefix' + super(OptionsReview, self).parse_args() + Context.create_context('review').refresh_review_set() + +class ReviewContext(Context.Context): + '''reviews the configuration values''' + + cmd = 'review' + + def __init__(self, **kw): + super(self.__class__, self).__init__(**kw) + + out = Options.options.out + if not out: + out = getattr(Context.g_module, Context.OUT, None) + if not out: + out = Options.lockfile.replace('.lock-waf', '') + self.build_path = (os.path.isabs(out) and self.root or self.path).make_node(out).abspath() + """Path to the build directory""" + + self.cache_path = os.path.join(self.build_path, Build.CACHE_DIR) + """Path to the cache directory""" + + self.review_path = os.path.join(self.cache_path, 'review.cache') + """Path to the review cache file""" + + def execute(self): + """ + Display and store the review set. Invalidate the cache as required. + """ + if not self.compare_review_set(old_review_set, new_review_set): + self.invalidate_cache() + self.store_review_set(new_review_set) + print(self.display_review_set(new_review_set)) + + def invalidate_cache(self): + """Invalidate the cache to prevent bad builds.""" + try: + Logs.warn("Removing the cached configuration since the options have changed") + shutil.rmtree(self.cache_path) + except: + pass + + def refresh_review_set(self): + """ + Obtain the old review set and the new review set, and import the new set. + """ + global old_review_set, new_review_set + old_review_set = self.load_review_set() + new_review_set = self.update_review_set(old_review_set) + self.import_review_set(new_review_set) + + def load_review_set(self): + """ + Load and return the review set from the cache if it exists. + Otherwise, return an empty set. + """ + if os.path.isfile(self.review_path): + return ConfigSet.ConfigSet(self.review_path) + return ConfigSet.ConfigSet() + + def store_review_set(self, review_set): + """ + Store the review set specified in the cache. + """ + if not os.path.isdir(self.cache_path): + os.makedirs(self.cache_path) + review_set.store(self.review_path) + + def update_review_set(self, old_set): + """ + Merge the options passed on the command line with those imported + from the previous review set and return the corresponding + preview set. + """ + + # Convert value to string. It's important that 'None' maps to + # the empty string. + def val_to_str(val): + if val == None or val == '': + return '' + return str(val) + + new_set = ConfigSet.ConfigSet() + opt_dict = Options.options.__dict__ + + for name in review_options.keys(): + # the option is specified explicitly on the command line + if name in opt_dict: + # if the option is the default, pretend it was never specified + if val_to_str(opt_dict[name]) != val_to_str(review_defaults[name]): + new_set[name] = opt_dict[name] + # the option was explicitly specified in a previous command + elif name in old_set: + new_set[name] = old_set[name] + + return new_set + + def import_review_set(self, review_set): + """ + Import the actual value of the reviewable options in the option + dictionary, given the current review set. + """ + for name in review_options.keys(): + if name in review_set: + value = review_set[name] + else: + value = review_defaults[name] + setattr(Options.options, name, value) + + def compare_review_set(self, set1, set2): + """ + Return true if the review sets specified are equal. + """ + if len(set1.keys()) != len(set2.keys()): + return False + for key in set1.keys(): + if not key in set2 or set1[key] != set2[key]: + return False + return True + + def display_review_set(self, review_set): + """ + Return the string representing the review set specified. + """ + term_width = Logs.get_term_cols() + lines = [] + for dest in review_options.keys(): + opt = review_options[dest] + name = ", ".join(opt._short_opts + opt._long_opts) + help = opt.help + actual = None + if dest in review_set: + actual = review_set[dest] + default = review_defaults[dest] + lines.append(self.format_option(name, help, actual, default, term_width)) + return "Configuration:\n\n" + "\n\n".join(lines) + "\n" + + def format_option(self, name, help, actual, default, term_width): + """ + Return the string representing the option specified. + """ + def val_to_str(val): + if val == None or val == '': + return "(void)" + return str(val) + + max_name_len = 20 + sep_len = 2 + + w = textwrap.TextWrapper() + w.width = term_width - 1 + if w.width < 60: + w.width = 60 + + out = "" + + # format the help + out += w.fill(help) + "\n" + + # format the name + name_len = len(name) + out += Logs.colors.CYAN + name + Logs.colors.NORMAL + + # set the indentation used when the value wraps to the next line + w.subsequent_indent = " ".rjust(max_name_len + sep_len) + w.width -= (max_name_len + sep_len) + + # the name string is too long, switch to the next line + if name_len > max_name_len: + out += "\n" + w.subsequent_indent + + # fill the remaining of the line with spaces + else: + out += " ".rjust(max_name_len + sep_len - name_len) + + # format the actual value, if there is one + if actual != None: + out += Logs.colors.BOLD + w.fill(val_to_str(actual)) + Logs.colors.NORMAL + "\n" + w.subsequent_indent + + # format the default value + default_fmt = val_to_str(default) + if actual != None: + default_fmt = "default: " + default_fmt + out += Logs.colors.NORMAL + w.fill(default_fmt) + Logs.colors.NORMAL + + return out + +# Monkey-patch ConfigurationContext.execute() to have it store the review set. +old_configure_execute = Configure.ConfigurationContext.execute +def new_configure_execute(self): + old_configure_execute(self) + Context.create_context('review').store_review_set(new_review_set) +Configure.ConfigurationContext.execute = new_configure_execute + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/rst.py b/ldb-2.0.8/third_party/waf/waflib/extras/rst.py new file mode 100644 index 0000000..f3c3a5e --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/rst.py @@ -0,0 +1,260 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Jérôme Carretero, 2013 (zougloub) + +""" +reStructuredText support (experimental) + +Example:: + + def configure(conf): + conf.load('rst') + if not conf.env.RST2HTML: + conf.fatal('The program rst2html is required') + + def build(bld): + bld( + features = 'rst', + type = 'rst2html', # rst2html, rst2pdf, ... + source = 'index.rst', # mandatory, the source + deps = 'image.png', # to give additional non-trivial dependencies + ) + +By default the tool looks for a set of programs in PATH. +The tools are defined in `rst_progs`. +To configure with a special program use:: + + $ RST2HTML=/path/to/rst2html waf configure + +This tool is experimental; don't hesitate to contribute to it. + +""" + +import re +from waflib import Node, Utils, Task, Errors, Logs +from waflib.TaskGen import feature, before_method + +rst_progs = "rst2html rst2xetex rst2latex rst2xml rst2pdf rst2s5 rst2man rst2odt rst2rtf".split() + +def parse_rst_node(task, node, nodes, names, seen, dirs=None): + # TODO add extensibility, to handle custom rst include tags... + if dirs is None: + dirs = (node.parent,node.get_bld().parent) + + if node in seen: + return + seen.append(node) + code = node.read() + re_rst = re.compile(r'^\s*.. ((?P\|\S+\|) )?(?Pinclude|image|figure):: (?P.*)$', re.M) + for match in re_rst.finditer(code): + ipath = match.group('file') + itype = match.group('type') + Logs.debug('rst: visiting %s: %s', itype, ipath) + found = False + for d in dirs: + Logs.debug('rst: looking for %s in %s', ipath, d.abspath()) + found = d.find_node(ipath) + if found: + Logs.debug('rst: found %s as %s', ipath, found.abspath()) + nodes.append((itype, found)) + if itype == 'include': + parse_rst_node(task, found, nodes, names, seen) + break + if not found: + names.append((itype, ipath)) + +class docutils(Task.Task): + """ + Compile a rst file. + """ + + def scan(self): + """ + A recursive regex-based scanner that finds rst dependencies. + """ + + nodes = [] + names = [] + seen = [] + + node = self.inputs[0] + + if not node: + return (nodes, names) + + parse_rst_node(self, node, nodes, names, seen) + + Logs.debug('rst: %r: found the following file deps: %r', self, nodes) + if names: + Logs.warn('rst: %r: could not find the following file deps: %r', self, names) + + return ([v for (t,v) in nodes], [v for (t,v) in names]) + + def check_status(self, msg, retcode): + """ + Check an exit status and raise an error with a particular message + + :param msg: message to display if the code is non-zero + :type msg: string + :param retcode: condition + :type retcode: boolean + """ + if retcode != 0: + raise Errors.WafError('%r command exit status %r' % (msg, retcode)) + + def run(self): + """ + Runs the rst compilation using docutils + """ + raise NotImplementedError() + +class rst2html(docutils): + color = 'BLUE' + + def __init__(self, *args, **kw): + docutils.__init__(self, *args, **kw) + self.command = self.generator.env.RST2HTML + self.attributes = ['stylesheet'] + + def scan(self): + nodes, names = docutils.scan(self) + + for attribute in self.attributes: + stylesheet = getattr(self.generator, attribute, None) + if stylesheet is not None: + ssnode = self.generator.to_nodes(stylesheet)[0] + nodes.append(ssnode) + Logs.debug('rst: adding dep to %s %s', attribute, stylesheet) + + return nodes, names + + def run(self): + cwdn = self.outputs[0].parent + src = self.inputs[0].path_from(cwdn) + dst = self.outputs[0].path_from(cwdn) + + cmd = self.command + [src, dst] + cmd += Utils.to_list(getattr(self.generator, 'options', [])) + for attribute in self.attributes: + stylesheet = getattr(self.generator, attribute, None) + if stylesheet is not None: + stylesheet = self.generator.to_nodes(stylesheet)[0] + cmd += ['--%s' % attribute, stylesheet.path_from(cwdn)] + + return self.exec_command(cmd, cwd=cwdn.abspath()) + +class rst2s5(rst2html): + def __init__(self, *args, **kw): + rst2html.__init__(self, *args, **kw) + self.command = self.generator.env.RST2S5 + self.attributes = ['stylesheet'] + +class rst2latex(rst2html): + def __init__(self, *args, **kw): + rst2html.__init__(self, *args, **kw) + self.command = self.generator.env.RST2LATEX + self.attributes = ['stylesheet'] + +class rst2xetex(rst2html): + def __init__(self, *args, **kw): + rst2html.__init__(self, *args, **kw) + self.command = self.generator.env.RST2XETEX + self.attributes = ['stylesheet'] + +class rst2pdf(docutils): + color = 'BLUE' + def run(self): + cwdn = self.outputs[0].parent + src = self.inputs[0].path_from(cwdn) + dst = self.outputs[0].path_from(cwdn) + + cmd = self.generator.env.RST2PDF + [src, '-o', dst] + cmd += Utils.to_list(getattr(self.generator, 'options', [])) + + return self.exec_command(cmd, cwd=cwdn.abspath()) + + +@feature('rst') +@before_method('process_source') +def apply_rst(self): + """ + Create :py:class:`rst` or other rst-related task objects + """ + + if self.target: + if isinstance(self.target, Node.Node): + tgt = self.target + elif isinstance(self.target, str): + tgt = self.path.get_bld().make_node(self.target) + else: + self.bld.fatal("rst: Don't know how to build target name %s which is not a string or Node for %s" % (self.target, self)) + else: + tgt = None + + tsk_type = getattr(self, 'type', None) + + src = self.to_nodes(self.source) + assert len(src) == 1 + src = src[0] + + if tsk_type is not None and tgt is None: + if tsk_type.startswith('rst2'): + ext = tsk_type[4:] + else: + self.bld.fatal("rst: Could not detect the output file extension for %s" % self) + tgt = src.change_ext('.%s' % ext) + elif tsk_type is None and tgt is not None: + out = tgt.name + ext = out[out.rfind('.')+1:] + self.type = 'rst2' + ext + elif tsk_type is not None and tgt is not None: + # the user knows what he wants + pass + else: + self.bld.fatal("rst: Need to indicate task type or target name for %s" % self) + + deps_lst = [] + + if getattr(self, 'deps', None): + deps = self.to_list(self.deps) + for filename in deps: + n = self.path.find_resource(filename) + if not n: + self.bld.fatal('Could not find %r for %r' % (filename, self)) + if not n in deps_lst: + deps_lst.append(n) + + try: + task = self.create_task(self.type, src, tgt) + except KeyError: + self.bld.fatal("rst: Task of type %s not implemented (created by %s)" % (self.type, self)) + + task.env = self.env + + # add the manual dependencies + if deps_lst: + try: + lst = self.bld.node_deps[task.uid()] + for n in deps_lst: + if not n in lst: + lst.append(n) + except KeyError: + self.bld.node_deps[task.uid()] = deps_lst + + inst_to = getattr(self, 'install_path', None) + if inst_to: + self.install_task = self.add_install_files(install_to=inst_to, install_from=task.outputs[:]) + + self.source = [] + +def configure(self): + """ + Try to find the rst programs. + + Do not raise any error if they are not found. + You'll have to use additional code in configure() to die + if programs were not found. + """ + for p in rst_progs: + self.find_program(p, mandatory=False) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/run_do_script.py b/ldb-2.0.8/third_party/waf/waflib/extras/run_do_script.py new file mode 100644 index 0000000..07e3aa2 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/run_do_script.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Hans-Martin von Gaudecker, 2012 + +""" +Run a Stata do-script in the directory specified by **ctx.bldnode**. The +first and only argument will be the name of the do-script (no extension), +which can be accessed inside the do-script by the local macro `1'. Useful +for keeping a log file. + +The tool uses the log file that is automatically kept by Stata only +for error-catching purposes, it will be destroyed if the task finished +without error. In case of an error in **some_script.do**, you can inspect +it as **some_script.log** in the **ctx.bldnode** directory. + +Note that Stata will not return an error code if it exits abnormally -- +catching errors relies on parsing the log file mentioned before. Should +the parser behave incorrectly please send an email to hmgaudecker [at] gmail. + +**WARNING** + + The tool will not work if multiple do-scripts of the same name---but in + different directories---are run at the same time! Avoid this situation. + +Usage:: + + ctx(features='run_do_script', + source='some_script.do', + target=['some_table.tex', 'some_figure.eps'], + deps='some_data.csv') +""" + + +import os, re, sys +from waflib import Task, TaskGen, Logs + +if sys.platform == 'darwin': + STATA_COMMANDS = ['Stata64MP', 'StataMP', + 'Stata64SE', 'StataSE', + 'Stata64', 'Stata'] + STATAFLAGS = '-e -q do' + STATAENCODING = 'MacRoman' +elif sys.platform.startswith('linux'): + STATA_COMMANDS = ['stata-mp', 'stata-se', 'stata'] + STATAFLAGS = '-b -q do' + # Not sure whether this is correct... + STATAENCODING = 'Latin-1' +elif sys.platform.lower().startswith('win'): + STATA_COMMANDS = ['StataMP-64', 'StataMP-ia', + 'StataMP', 'StataSE-64', + 'StataSE-ia', 'StataSE', + 'Stata-64', 'Stata-ia', + 'Stata.e', 'WMPSTATA', + 'WSESTATA', 'WSTATA'] + STATAFLAGS = '/e do' + STATAENCODING = 'Latin-1' +else: + raise Exception("Unknown sys.platform: %s " % sys.platform) + +def configure(ctx): + ctx.find_program(STATA_COMMANDS, var='STATACMD', errmsg="""\n +No Stata executable found!\n\n +If Stata is needed:\n + 1) Check the settings of your system path. + 2) Note we are looking for Stata executables called: %s + If yours has a different name, please report to hmgaudecker [at] gmail\n +Else:\n + Do not load the 'run_do_script' tool in the main wscript.\n\n""" % STATA_COMMANDS) + ctx.env.STATAFLAGS = STATAFLAGS + ctx.env.STATAENCODING = STATAENCODING + +class run_do_script_base(Task.Task): + """Run a Stata do-script from the bldnode directory.""" + run_str = '"${STATACMD}" ${STATAFLAGS} "${SRC[0].abspath()}" "${DOFILETRUNK}"' + shell = True + +class run_do_script(run_do_script_base): + """Use the log file automatically kept by Stata for error-catching. + Erase it if the task finished without error. If not, it will show + up as do_script.log in the bldnode directory. + """ + def run(self): + run_do_script_base.run(self) + ret, log_tail = self.check_erase_log_file() + if ret: + Logs.error("""Running Stata on %r failed with code %r.\n\nCheck the log file %s, last 10 lines\n\n%s\n\n\n""", + self.inputs[0], ret, self.env.LOGFILEPATH, log_tail) + return ret + + def check_erase_log_file(self): + """Parse Stata's default log file and erase it if everything okay. + + Parser is based on Brendan Halpin's shell script found here: + http://teaching.sociology.ul.ie/bhalpin/wordpress/?p=122 + """ + + if sys.version_info.major >= 3: + kwargs = {'file': self.env.LOGFILEPATH, 'mode': 'r', 'encoding': self.env.STATAENCODING} + else: + kwargs = {'name': self.env.LOGFILEPATH, 'mode': 'r'} + with open(**kwargs) as log: + log_tail = log.readlines()[-10:] + for line in log_tail: + error_found = re.match(r"r\(([0-9]+)\)", line) + if error_found: + return error_found.group(1), ''.join(log_tail) + else: + pass + # Only end up here if the parser did not identify an error. + os.remove(self.env.LOGFILEPATH) + return None, None + + +@TaskGen.feature('run_do_script') +@TaskGen.before_method('process_source') +def apply_run_do_script(tg): + """Task generator customising the options etc. to call Stata in batch + mode for running a do-script. + """ + + # Convert sources and targets to nodes + src_node = tg.path.find_resource(tg.source) + tgt_nodes = [tg.path.find_or_declare(t) for t in tg.to_list(tg.target)] + + tsk = tg.create_task('run_do_script', src=src_node, tgt=tgt_nodes) + tsk.env.DOFILETRUNK = os.path.splitext(src_node.name)[0] + tsk.env.LOGFILEPATH = os.path.join(tg.bld.bldnode.abspath(), '%s.log' % (tsk.env.DOFILETRUNK)) + + # dependencies (if the attribute 'deps' changes, trigger a recompilation) + for x in tg.to_list(getattr(tg, 'deps', [])): + node = tg.path.find_resource(x) + if not node: + tg.bld.fatal('Could not find dependency %r for running %r' % (x, src_node.abspath())) + tsk.dep_nodes.append(node) + Logs.debug('deps: found dependencies %r for running %r', tsk.dep_nodes, src_node.abspath()) + + # Bypass the execution of process_source by setting the source to an empty list + tg.source = [] + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/run_m_script.py b/ldb-2.0.8/third_party/waf/waflib/extras/run_m_script.py new file mode 100644 index 0000000..b5f27eb --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/run_m_script.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Hans-Martin von Gaudecker, 2012 + +""" +Run a Matlab script. + +Note that the script is run in the directory where it lives -- Matlab won't +allow it any other way. + +For error-catching purposes, keep an own log-file that is destroyed if the +task finished without error. If not, it will show up as mscript_[index].log +in the bldnode directory. + +Usage:: + + ctx(features='run_m_script', + source='some_script.m', + target=['some_table.tex', 'some_figure.eps'], + deps='some_data.mat') +""" + +import os, sys +from waflib import Task, TaskGen, Logs + +MATLAB_COMMANDS = ['matlab'] + +def configure(ctx): + ctx.find_program(MATLAB_COMMANDS, var='MATLABCMD', errmsg = """\n +No Matlab executable found!\n\n +If Matlab is needed:\n + 1) Check the settings of your system path. + 2) Note we are looking for Matlab executables called: %s + If yours has a different name, please report to hmgaudecker [at] gmail\n +Else:\n + Do not load the 'run_m_script' tool in the main wscript.\n\n""" % MATLAB_COMMANDS) + ctx.env.MATLABFLAGS = '-wait -nojvm -nosplash -minimize' + +class run_m_script_base(Task.Task): + """Run a Matlab script.""" + run_str = '"${MATLABCMD}" ${MATLABFLAGS} -logfile "${LOGFILEPATH}" -r "try, ${MSCRIPTTRUNK}, exit(0), catch err, disp(err.getReport()), exit(1), end"' + shell = True + +class run_m_script(run_m_script_base): + """Erase the Matlab overall log file if everything went okay, else raise an + error and print its 10 last lines. + """ + def run(self): + ret = run_m_script_base.run(self) + logfile = self.env.LOGFILEPATH + if ret: + mode = 'r' + if sys.version_info.major >= 3: + mode = 'rb' + with open(logfile, mode=mode) as f: + tail = f.readlines()[-10:] + Logs.error("""Running Matlab on %r returned the error %r\n\nCheck the log file %s, last 10 lines\n\n%s\n\n\n""", + self.inputs[0], ret, logfile, '\n'.join(tail)) + else: + os.remove(logfile) + return ret + +@TaskGen.feature('run_m_script') +@TaskGen.before_method('process_source') +def apply_run_m_script(tg): + """Task generator customising the options etc. to call Matlab in batch + mode for running a m-script. + """ + + # Convert sources and targets to nodes + src_node = tg.path.find_resource(tg.source) + tgt_nodes = [tg.path.find_or_declare(t) for t in tg.to_list(tg.target)] + + tsk = tg.create_task('run_m_script', src=src_node, tgt=tgt_nodes) + tsk.cwd = src_node.parent.abspath() + tsk.env.MSCRIPTTRUNK = os.path.splitext(src_node.name)[0] + tsk.env.LOGFILEPATH = os.path.join(tg.bld.bldnode.abspath(), '%s_%d.log' % (tsk.env.MSCRIPTTRUNK, tg.idx)) + + # dependencies (if the attribute 'deps' changes, trigger a recompilation) + for x in tg.to_list(getattr(tg, 'deps', [])): + node = tg.path.find_resource(x) + if not node: + tg.bld.fatal('Could not find dependency %r for running %r' % (x, src_node.abspath())) + tsk.dep_nodes.append(node) + Logs.debug('deps: found dependencies %r for running %r', tsk.dep_nodes, src_node.abspath()) + + # Bypass the execution of process_source by setting the source to an empty list + tg.source = [] diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/run_py_script.py b/ldb-2.0.8/third_party/waf/waflib/extras/run_py_script.py new file mode 100644 index 0000000..3670381 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/run_py_script.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Hans-Martin von Gaudecker, 2012 + +""" +Run a Python script in the directory specified by **ctx.bldnode**. + +Select a Python version by specifying the **version** keyword for +the task generator instance as integer 2 or 3. Default is 3. + +If the build environment has an attribute "PROJECT_PATHS" with +a key "PROJECT_ROOT", its value will be appended to the PYTHONPATH. +Same a string passed to the optional **add_to_pythonpath** +keyword (appended after the PROJECT_ROOT). + +Usage:: + + ctx(features='run_py_script', version=3, + source='some_script.py', + target=['some_table.tex', 'some_figure.eps'], + deps='some_data.csv', + add_to_pythonpath='src/some/library') +""" + +import os, re +from waflib import Task, TaskGen, Logs + + +def configure(conf): + """TODO: Might need to be updated for Windows once + "PEP 397":http://www.python.org/dev/peps/pep-0397/ is settled. + """ + conf.find_program('python', var='PY2CMD', mandatory=False) + conf.find_program('python3', var='PY3CMD', mandatory=False) + if not conf.env.PY2CMD and not conf.env.PY3CMD: + conf.fatal("No Python interpreter found!") + +class run_py_2_script(Task.Task): + """Run a Python 2 script.""" + run_str = '${PY2CMD} ${SRC[0].abspath()}' + shell=True + +class run_py_3_script(Task.Task): + """Run a Python 3 script.""" + run_str = '${PY3CMD} ${SRC[0].abspath()}' + shell=True + +@TaskGen.feature('run_py_script') +@TaskGen.before_method('process_source') +def apply_run_py_script(tg): + """Task generator for running either Python 2 or Python 3 on a single + script. + + Attributes: + + * source -- A **single** source node or string. (required) + * target -- A single target or list of targets (nodes or strings) + * deps -- A single dependency or list of dependencies (nodes or strings) + * add_to_pythonpath -- A string that will be appended to the PYTHONPATH environment variable + + If the build environment has an attribute "PROJECT_PATHS" with + a key "PROJECT_ROOT", its value will be appended to the PYTHONPATH. + """ + + # Set the Python version to use, default to 3. + v = getattr(tg, 'version', 3) + if v not in (2, 3): + raise ValueError("Specify the 'version' attribute for run_py_script task generator as integer 2 or 3.\n Got: %s" %v) + + # Convert sources and targets to nodes + src_node = tg.path.find_resource(tg.source) + tgt_nodes = [tg.path.find_or_declare(t) for t in tg.to_list(tg.target)] + + # Create the task. + tsk = tg.create_task('run_py_%d_script' %v, src=src_node, tgt=tgt_nodes) + + # custom execution environment + # TODO use a list and os.sep.join(lst) at the end instead of concatenating strings + tsk.env.env = dict(os.environ) + tsk.env.env['PYTHONPATH'] = tsk.env.env.get('PYTHONPATH', '') + project_paths = getattr(tsk.env, 'PROJECT_PATHS', None) + if project_paths and 'PROJECT_ROOT' in project_paths: + tsk.env.env['PYTHONPATH'] += os.pathsep + project_paths['PROJECT_ROOT'].abspath() + if getattr(tg, 'add_to_pythonpath', None): + tsk.env.env['PYTHONPATH'] += os.pathsep + tg.add_to_pythonpath + + # Clean up the PYTHONPATH -- replace double occurrences of path separator + tsk.env.env['PYTHONPATH'] = re.sub(os.pathsep + '+', os.pathsep, tsk.env.env['PYTHONPATH']) + + # Clean up the PYTHONPATH -- doesn't like starting with path separator + if tsk.env.env['PYTHONPATH'].startswith(os.pathsep): + tsk.env.env['PYTHONPATH'] = tsk.env.env['PYTHONPATH'][1:] + + # dependencies (if the attribute 'deps' changes, trigger a recompilation) + for x in tg.to_list(getattr(tg, 'deps', [])): + node = tg.path.find_resource(x) + if not node: + tg.bld.fatal('Could not find dependency %r for running %r' % (x, src_node.abspath())) + tsk.dep_nodes.append(node) + Logs.debug('deps: found dependencies %r for running %r', tsk.dep_nodes, src_node.abspath()) + + # Bypass the execution of process_source by setting the source to an empty list + tg.source = [] + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/run_r_script.py b/ldb-2.0.8/third_party/waf/waflib/extras/run_r_script.py new file mode 100644 index 0000000..b0d8f2b --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/run_r_script.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Hans-Martin von Gaudecker, 2012 + +""" +Run a R script in the directory specified by **ctx.bldnode**. + +For error-catching purposes, keep an own log-file that is destroyed if the +task finished without error. If not, it will show up as rscript_[index].log +in the bldnode directory. + +Usage:: + + ctx(features='run_r_script', + source='some_script.r', + target=['some_table.tex', 'some_figure.eps'], + deps='some_data.csv') +""" + + +import os, sys +from waflib import Task, TaskGen, Logs + +R_COMMANDS = ['RTerm', 'R', 'r'] + +def configure(ctx): + ctx.find_program(R_COMMANDS, var='RCMD', errmsg = """\n +No R executable found!\n\n +If R is needed:\n + 1) Check the settings of your system path. + 2) Note we are looking for R executables called: %s + If yours has a different name, please report to hmgaudecker [at] gmail\n +Else:\n + Do not load the 'run_r_script' tool in the main wscript.\n\n""" % R_COMMANDS) + ctx.env.RFLAGS = 'CMD BATCH --slave' + +class run_r_script_base(Task.Task): + """Run a R script.""" + run_str = '"${RCMD}" ${RFLAGS} "${SRC[0].abspath()}" "${LOGFILEPATH}"' + shell = True + +class run_r_script(run_r_script_base): + """Erase the R overall log file if everything went okay, else raise an + error and print its 10 last lines. + """ + def run(self): + ret = run_r_script_base.run(self) + logfile = self.env.LOGFILEPATH + if ret: + mode = 'r' + if sys.version_info.major >= 3: + mode = 'rb' + with open(logfile, mode=mode) as f: + tail = f.readlines()[-10:] + Logs.error("""Running R on %r returned the error %r\n\nCheck the log file %s, last 10 lines\n\n%s\n\n\n""", + self.inputs[0], ret, logfile, '\n'.join(tail)) + else: + os.remove(logfile) + return ret + + +@TaskGen.feature('run_r_script') +@TaskGen.before_method('process_source') +def apply_run_r_script(tg): + """Task generator customising the options etc. to call R in batch + mode for running a R script. + """ + + # Convert sources and targets to nodes + src_node = tg.path.find_resource(tg.source) + tgt_nodes = [tg.path.find_or_declare(t) for t in tg.to_list(tg.target)] + + tsk = tg.create_task('run_r_script', src=src_node, tgt=tgt_nodes) + tsk.env.LOGFILEPATH = os.path.join(tg.bld.bldnode.abspath(), '%s_%d.log' % (os.path.splitext(src_node.name)[0], tg.idx)) + + # dependencies (if the attribute 'deps' changes, trigger a recompilation) + for x in tg.to_list(getattr(tg, 'deps', [])): + node = tg.path.find_resource(x) + if not node: + tg.bld.fatal('Could not find dependency %r for running %r' % (x, src_node.abspath())) + tsk.dep_nodes.append(node) + Logs.debug('deps: found dependencies %r for running %r', tsk.dep_nodes, src_node.abspath()) + + # Bypass the execution of process_source by setting the source to an empty list + tg.source = [] + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/sas.py b/ldb-2.0.8/third_party/waf/waflib/extras/sas.py new file mode 100644 index 0000000..754c614 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/sas.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Mark Coggeshall, 2010 + +"SAS support" + +import os +from waflib import Task, Errors, Logs +from waflib.TaskGen import feature, before_method + +sas_fun, _ = Task.compile_fun('sas -sysin ${SRCFILE} -log ${LOGFILE} -print ${LSTFILE}', shell=False) + +class sas(Task.Task): + vars = ['SAS', 'SASFLAGS'] + def run(task): + command = 'SAS' + fun = sas_fun + + node = task.inputs[0] + logfilenode = node.change_ext('.log') + lstfilenode = node.change_ext('.lst') + + # set the cwd + task.cwd = task.inputs[0].parent.get_src().abspath() + Logs.debug('runner: %r on %r', command, node) + + SASINPUTS = node.parent.get_bld().abspath() + os.pathsep + node.parent.get_src().abspath() + os.pathsep + task.env.env = {'SASINPUTS': SASINPUTS} + + task.env.SRCFILE = node.abspath() + task.env.LOGFILE = logfilenode.abspath() + task.env.LSTFILE = lstfilenode.abspath() + ret = fun(task) + if ret: + Logs.error('Running %s on %r returned a non-zero exit', command, node) + Logs.error('SRCFILE = %r', node) + Logs.error('LOGFILE = %r', logfilenode) + Logs.error('LSTFILE = %r', lstfilenode) + return ret + +@feature('sas') +@before_method('process_source') +def apply_sas(self): + if not getattr(self, 'type', None) in ('sas',): + self.type = 'sas' + + self.env['logdir'] = getattr(self, 'logdir', 'log') + self.env['lstdir'] = getattr(self, 'lstdir', 'lst') + + deps_lst = [] + + if getattr(self, 'deps', None): + deps = self.to_list(self.deps) + for filename in deps: + n = self.path.find_resource(filename) + if not n: + n = self.bld.root.find_resource(filename) + if not n: + raise Errors.WafError('cannot find input file %s for processing' % filename) + if not n in deps_lst: + deps_lst.append(n) + + for node in self.to_nodes(self.source): + if self.type == 'sas': + task = self.create_task('sas', src=node) + task.dep_nodes = deps_lst + self.source = [] + +def configure(self): + self.find_program('sas', var='SAS', mandatory=False) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/satellite_assembly.py b/ldb-2.0.8/third_party/waf/waflib/extras/satellite_assembly.py new file mode 100644 index 0000000..005eb07 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/satellite_assembly.py @@ -0,0 +1,57 @@ +#!/usr/bin/python +# encoding: utf-8 +# vim: tabstop=4 noexpandtab + +""" +Create a satellite assembly from "*.??.txt" files. ?? stands for a language code. + +The projects Resources subfolder contains resources.??.txt string files for several languages. +The build folder will hold the satellite assemblies as ./??/ExeName.resources.dll + +#gen becomes template (It is called gen because it also uses resx.py). +bld(source='Resources/resources.de.txt',gen=ExeName) +""" + +import os, re +from waflib import Task +from waflib.TaskGen import feature,before_method + +class al(Task.Task): + run_str = '${AL} ${ALFLAGS}' + +@feature('satellite_assembly') +@before_method('process_source') +def satellite_assembly(self): + if not getattr(self, 'gen', None): + self.bld.fatal('satellite_assembly needs a template assembly provided with the "gen" parameter') + res_lang = re.compile(r'(.*)\.(\w\w)\.(?:resx|txt)',flags=re.I) + + # self.source can contain node objects, so this will break in one way or another + self.source = self.to_list(self.source) + for i, x in enumerate(self.source): + #x = 'resources/resources.de.resx' + #x = 'resources/resources.de.txt' + mo = res_lang.match(x) + if mo: + template = os.path.splitext(self.gen)[0] + templatedir, templatename = os.path.split(template) + res = mo.group(1) + lang = mo.group(2) + #./Resources/resources.de.resources + resources = self.path.find_or_declare(res+ '.' + lang + '.resources') + self.create_task('resgen', self.to_nodes(x), [resources]) + #./de/Exename.resources.dll + satellite = self.path.find_or_declare(os.path.join(templatedir,lang,templatename) + '.resources.dll') + tsk = self.create_task('al',[resources],[satellite]) + tsk.env.append_value('ALFLAGS','/template:'+os.path.join(self.path.relpath(),self.gen)) + tsk.env.append_value('ALFLAGS','/embed:'+resources.relpath()) + tsk.env.append_value('ALFLAGS','/culture:'+lang) + tsk.env.append_value('ALFLAGS','/out:'+satellite.relpath()) + self.source[i] = None + # remove the None elements that we just substituted + self.source = list(filter(lambda x:x, self.source)) + +def configure(ctx): + ctx.find_program('al', var='AL', mandatory=True) + ctx.load('resx') + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/scala.py b/ldb-2.0.8/third_party/waf/waflib/extras/scala.py new file mode 100644 index 0000000..a9880f0 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/scala.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2010 (ita) + +""" +Scala support + +scalac outputs files a bit where it wants to +""" + +import os +from waflib import Task, Utils, Node +from waflib.TaskGen import feature, before_method, after_method + +from waflib.Tools import ccroot +ccroot.USELIB_VARS['scalac'] = set(['CLASSPATH', 'SCALACFLAGS']) + +from waflib.Tools import javaw + +@feature('scalac') +@before_method('process_source') +def apply_scalac(self): + + Utils.def_attrs(self, jarname='', classpath='', + sourcepath='.', srcdir='.', + jar_mf_attributes={}, jar_mf_classpath=[]) + + outdir = getattr(self, 'outdir', None) + if outdir: + if not isinstance(outdir, Node.Node): + outdir = self.path.get_bld().make_node(self.outdir) + else: + outdir = self.path.get_bld() + outdir.mkdir() + self.env['OUTDIR'] = outdir.abspath() + + self.scalac_task = tsk = self.create_task('scalac') + tmp = [] + + srcdir = getattr(self, 'srcdir', '') + if isinstance(srcdir, Node.Node): + srcdir = [srcdir] + for x in Utils.to_list(srcdir): + if isinstance(x, Node.Node): + y = x + else: + y = self.path.find_dir(x) + if not y: + self.bld.fatal('Could not find the folder %s from %s' % (x, self.path)) + tmp.append(y) + tsk.srcdir = tmp + +# reuse some code +feature('scalac')(javaw.use_javac_files) +after_method('apply_scalac')(javaw.use_javac_files) + +feature('scalac')(javaw.set_classpath) +after_method('apply_scalac', 'use_scalac_files')(javaw.set_classpath) + + +SOURCE_RE = '**/*.scala' +class scalac(javaw.javac): + color = 'GREEN' + vars = ['CLASSPATH', 'SCALACFLAGS', 'SCALAC', 'OUTDIR'] + + def runnable_status(self): + """ + Wait for dependent tasks to be complete, then read the file system to find the input nodes. + """ + for t in self.run_after: + if not t.hasrun: + return Task.ASK_LATER + + if not self.inputs: + global SOURCE_RE + self.inputs = [] + for x in self.srcdir: + self.inputs.extend(x.ant_glob(SOURCE_RE, remove=False)) + return super(javaw.javac, self).runnable_status() + + def run(self): + """ + Execute the scalac compiler + """ + env = self.env + gen = self.generator + bld = gen.bld + wd = bld.bldnode.abspath() + def to_list(xx): + if isinstance(xx, str): + return [xx] + return xx + self.last_cmd = lst = [] + lst.extend(to_list(env['SCALAC'])) + lst.extend(['-classpath']) + lst.extend(to_list(env['CLASSPATH'])) + lst.extend(['-d']) + lst.extend(to_list(env['OUTDIR'])) + lst.extend(to_list(env['SCALACFLAGS'])) + lst.extend([a.abspath() for a in self.inputs]) + lst = [x for x in lst if x] + try: + self.out = self.generator.bld.cmd_and_log(lst, cwd=wd, env=env.env or None, output=0, quiet=0)[1] + except: + self.generator.bld.cmd_and_log(lst, cwd=wd, env=env.env or None) + +def configure(self): + """ + Detect the scalac program + """ + # If SCALA_HOME is set, we prepend it to the path list + java_path = self.environ['PATH'].split(os.pathsep) + v = self.env + + if 'SCALA_HOME' in self.environ: + java_path = [os.path.join(self.environ['SCALA_HOME'], 'bin')] + java_path + self.env['SCALA_HOME'] = [self.environ['SCALA_HOME']] + + for x in 'scalac scala'.split(): + self.find_program(x, var=x.upper(), path_list=java_path) + + if 'CLASSPATH' in self.environ: + v['CLASSPATH'] = self.environ['CLASSPATH'] + + v.SCALACFLAGS = ['-verbose'] + if not v['SCALAC']: + self.fatal('scalac is required for compiling scala classes') + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/slow_qt4.py b/ldb-2.0.8/third_party/waf/waflib/extras/slow_qt4.py new file mode 100644 index 0000000..ec7880b --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/slow_qt4.py @@ -0,0 +1,96 @@ +#! /usr/bin/env python +# Thomas Nagy, 2011 (ita) + +""" +Create _moc.cpp files + +The builds are 30-40% faster when .moc files are included, +you should NOT use this tool. If you really +really want it: + +def configure(conf): + conf.load('compiler_cxx qt4') + conf.load('slow_qt4') + +See playground/slow_qt/wscript for a complete example. +""" + +from waflib.TaskGen import extension +from waflib import Task +import waflib.Tools.qt4 +import waflib.Tools.cxx + +@extension(*waflib.Tools.qt4.EXT_QT4) +def cxx_hook(self, node): + return self.create_compiled_task('cxx_qt', node) + +class cxx_qt(Task.classes['cxx']): + def runnable_status(self): + ret = Task.classes['cxx'].runnable_status(self) + if ret != Task.ASK_LATER and not getattr(self, 'moc_done', None): + + try: + cache = self.generator.moc_cache + except AttributeError: + cache = self.generator.moc_cache = {} + + deps = self.generator.bld.node_deps[self.uid()] + for x in [self.inputs[0]] + deps: + if x.read().find('Q_OBJECT') > 0: + + # process "foo.h -> foo.moc" only if "foo.cpp" is in the sources for the current task generator + # this code will work because it is in the main thread (runnable_status) + if x.name.rfind('.') > -1: # a .h file... + name = x.name[:x.name.rfind('.')] + for tsk in self.generator.compiled_tasks: + if tsk.inputs and tsk.inputs[0].name.startswith(name): + break + else: + # no corresponding file, continue + continue + + # the file foo.cpp could be compiled for a static and a shared library - hence the %number in the name + cxx_node = x.parent.get_bld().make_node(x.name.replace('.', '_') + '_%d_moc.cpp' % self.generator.idx) + if cxx_node in cache: + continue + cache[cxx_node] = self + + tsk = Task.classes['moc'](env=self.env, generator=self.generator) + tsk.set_inputs(x) + tsk.set_outputs(cxx_node) + + if x.name.endswith('.cpp'): + # moc is trying to be too smart but it is too dumb: + # why forcing the #include when Q_OBJECT is in the cpp file? + gen = self.generator.bld.producer + gen.outstanding.append(tsk) + gen.total += 1 + self.set_run_after(tsk) + else: + cxxtsk = Task.classes['cxx'](env=self.env, generator=self.generator) + cxxtsk.set_inputs(tsk.outputs) + cxxtsk.set_outputs(cxx_node.change_ext('.o')) + cxxtsk.set_run_after(tsk) + + try: + self.more_tasks.extend([tsk, cxxtsk]) + except AttributeError: + self.more_tasks = [tsk, cxxtsk] + + try: + link = self.generator.link_task + except AttributeError: + pass + else: + link.set_run_after(cxxtsk) + link.inputs.extend(cxxtsk.outputs) + link.inputs.sort(key=lambda x: x.abspath()) + + self.moc_done = True + + for t in self.run_after: + if not t.hasrun: + return Task.ASK_LATER + + return ret + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/softlink_libs.py b/ldb-2.0.8/third_party/waf/waflib/extras/softlink_libs.py new file mode 100644 index 0000000..50c777f --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/softlink_libs.py @@ -0,0 +1,76 @@ +#! /usr/bin/env python +# per rosengren 2011 + +from waflib.TaskGen import feature, after_method +from waflib.Task import Task, always_run +from os.path import basename, isabs +from os import tmpfile, linesep + +def options(opt): + grp = opt.add_option_group('Softlink Libraries Options') + grp.add_option('--exclude', default='/usr/lib,/lib', help='No symbolic links are created for libs within [%default]') + +def configure(cnf): + cnf.find_program('ldd') + if not cnf.env.SOFTLINK_EXCLUDE: + cnf.env.SOFTLINK_EXCLUDE = cnf.options.exclude.split(',') + +@feature('softlink_libs') +@after_method('process_rule') +def add_finder(self): + tgt = self.path.find_or_declare(self.target) + self.create_task('sll_finder', tgt=tgt) + self.create_task('sll_installer', tgt=tgt) + always_run(sll_installer) + +class sll_finder(Task): + ext_out = 'softlink_libs' + def run(self): + bld = self.generator.bld + linked=[] + target_paths = [] + for g in bld.groups: + for tgen in g: + # FIXME it might be better to check if there is a link_task (getattr?) + target_paths += [tgen.path.get_bld().bldpath()] + linked += [t.outputs[0].bldpath() + for t in getattr(tgen, 'tasks', []) + if t.__class__.__name__ in + ['cprogram', 'cshlib', 'cxxprogram', 'cxxshlib']] + lib_list = [] + if len(linked): + cmd = [self.env.LDD] + linked + # FIXME add DYLD_LIBRARY_PATH+PATH for osx+win32 + ldd_env = {'LD_LIBRARY_PATH': ':'.join(target_paths + self.env.LIBPATH)} + # FIXME the with syntax will not work in python 2 + with tmpfile() as result: + self.exec_command(cmd, env=ldd_env, stdout=result) + result.seek(0) + for line in result.readlines(): + words = line.split() + if len(words) < 3 or words[1] != '=>': + continue + lib = words[2] + if lib == 'not': + continue + if any([lib.startswith(p) for p in + [bld.bldnode.abspath(), '('] + + self.env.SOFTLINK_EXCLUDE]): + continue + if not isabs(lib): + continue + lib_list.append(lib) + lib_list = sorted(set(lib_list)) + self.outputs[0].write(linesep.join(lib_list + self.env.DYNAMIC_LIBS)) + return 0 + +class sll_installer(Task): + ext_in = 'softlink_libs' + def run(self): + tgt = self.outputs[0] + self.generator.bld.install_files('${LIBDIR}', tgt, postpone=False) + lib_list=tgt.read().split() + for lib in lib_list: + self.generator.bld.symlink_as('${LIBDIR}/'+basename(lib), lib, postpone=False) + return 0 + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/sphinx.py b/ldb-2.0.8/third_party/waf/waflib/extras/sphinx.py new file mode 100644 index 0000000..ce11110 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/sphinx.py @@ -0,0 +1,81 @@ +"""Support for Sphinx documentation + +This is a wrapper for sphinx-build program. Please note that sphinx-build supports only one output format which can +passed to build via sphinx_output_format attribute. The default output format is html. + +Example wscript: + +def configure(cnf): + conf.load('sphinx') + +def build(bld): + bld( + features='sphinx', + sphinx_source='sources', # path to source directory + sphinx_options='-a -v', # sphinx-build program additional options + sphinx_output_format='man' # output format of sphinx documentation + ) + +""" + +from waflib.Node import Node +from waflib import Utils +from waflib.Task import Task +from waflib.TaskGen import feature, after_method + + +def configure(cnf): + """Check if sphinx-build program is available and loads gnu_dirs tool.""" + cnf.find_program('sphinx-build', var='SPHINX_BUILD', mandatory=False) + cnf.load('gnu_dirs') + + +@feature('sphinx') +def build_sphinx(self): + """Builds sphinx sources. + """ + if not self.env.SPHINX_BUILD: + self.bld.fatal('Program SPHINX_BUILD not defined.') + if not getattr(self, 'sphinx_source', None): + self.bld.fatal('Attribute sphinx_source not defined.') + if not isinstance(self.sphinx_source, Node): + self.sphinx_source = self.path.find_node(self.sphinx_source) + if not self.sphinx_source: + self.bld.fatal('Can\'t find sphinx_source: %r' % self.sphinx_source) + + Utils.def_attrs(self, sphinx_output_format='html') + self.env.SPHINX_OUTPUT_FORMAT = self.sphinx_output_format + self.env.SPHINX_OPTIONS = getattr(self, 'sphinx_options', []) + + for source_file in self.sphinx_source.ant_glob('**/*'): + self.bld.add_manual_dependency(self.sphinx_source, source_file) + + sphinx_build_task = self.create_task('SphinxBuildingTask') + sphinx_build_task.set_inputs(self.sphinx_source) + sphinx_build_task.set_outputs(self.path.get_bld()) + + # the sphinx-build results are in directory + sphinx_output_directory = self.path.get_bld().make_node(self.env.SPHINX_OUTPUT_FORMAT) + sphinx_output_directory.mkdir() + Utils.def_attrs(self, install_path=get_install_path(self)) + self.add_install_files(install_to=self.install_path, + install_from=sphinx_output_directory.ant_glob('**/*'), + cwd=sphinx_output_directory, + relative_trick=True) + + +def get_install_path(tg): + if tg.env.SPHINX_OUTPUT_FORMAT == 'man': + return tg.env.MANDIR + elif tg.env.SPHINX_OUTPUT_FORMAT == 'info': + return tg.env.INFODIR + else: + return tg.env.DOCDIR + + +class SphinxBuildingTask(Task): + color = 'BOLD' + run_str = '${SPHINX_BUILD} -M ${SPHINX_OUTPUT_FORMAT} ${SRC} ${TGT} ${SPHINX_OPTIONS}' + + def keyword(self): + return 'Compiling (%s)' % self.env.SPHINX_OUTPUT_FORMAT diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/stale.py b/ldb-2.0.8/third_party/waf/waflib/extras/stale.py new file mode 100644 index 0000000..cac3f46 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/stale.py @@ -0,0 +1,98 @@ +#! /usr/bin/env python +# encoding: UTF-8 +# Thomas Nagy, 2006-2015 (ita) + +""" +Add a pre-build hook to remove build files (declared in the system) +that do not have a corresponding target + +This can be used for example to remove the targets +that have changed name without performing +a full 'waf clean' + +Of course, it will only work if there are no dynamically generated +nodes/tasks, in which case the method will have to be modified +to exclude some folders for example. + +Make sure to set bld.post_mode = waflib.Build.POST_AT_ONCE +""" + +from waflib import Logs, Build +from waflib.Runner import Parallel + +DYNAMIC_EXT = [] # add your non-cleanable files/extensions here +MOC_H_EXTS = '.cpp .cxx .hpp .hxx .h'.split() + +def can_delete(node): + """Imperfect moc cleanup which does not look for a Q_OBJECT macro in the files""" + if not node.name.endswith('.moc'): + return True + base = node.name[:-4] + p1 = node.parent.get_src() + p2 = node.parent.get_bld() + for k in MOC_H_EXTS: + h_name = base + k + n = p1.search_node(h_name) + if n: + return False + n = p2.search_node(h_name) + if n: + return False + + # foo.cpp.moc, foo.h.moc, etc. + if base.endswith(k): + return False + + return True + +# recursion over the nodes to find the stale files +def stale_rec(node, nodes): + if node.abspath() in node.ctx.env[Build.CFG_FILES]: + return + + if getattr(node, 'children', []): + for x in node.children.values(): + if x.name != "c4che": + stale_rec(x, nodes) + else: + for ext in DYNAMIC_EXT: + if node.name.endswith(ext): + break + else: + if not node in nodes: + if can_delete(node): + Logs.warn('Removing stale file -> %r', node) + node.delete() + +old = Parallel.refill_task_list +def refill_task_list(self): + iit = old(self) + bld = self.bld + + # execute this operation only once + if getattr(self, 'stale_done', False): + return iit + self.stale_done = True + + # this does not work in partial builds + if bld.targets != '*': + return iit + + # this does not work in dynamic builds + if getattr(bld, 'post_mode') == Build.POST_AT_ONCE: + return iit + + # obtain the nodes to use during the build + nodes = [] + for tasks in bld.groups: + for x in tasks: + try: + nodes.extend(x.outputs) + except AttributeError: + pass + + stale_rec(bld.bldnode, nodes) + return iit + +Parallel.refill_task_list = refill_task_list + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/stracedeps.py b/ldb-2.0.8/third_party/waf/waflib/extras/stracedeps.py new file mode 100644 index 0000000..37d82cb --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/stracedeps.py @@ -0,0 +1,174 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2015 (ita) + +""" +Execute tasks through strace to obtain dependencies after the process is run. This +scheme is similar to that of the Fabricate script. + +To use:: + + def configure(conf): + conf.load('strace') + +WARNING: +* This will not work when advanced scanners are needed (qt4/qt5) +* The overhead of running 'strace' is significant (56s -> 1m29s) +* It will not work on Windows :-) +""" + +import os, re, threading +from waflib import Task, Logs, Utils + +#TRACECALLS = 'trace=access,chdir,clone,creat,execve,exit_group,fork,lstat,lstat64,mkdir,open,rename,stat,stat64,symlink,vfork' +TRACECALLS = 'trace=process,file' + +BANNED = ('/tmp', '/proc', '/sys', '/dev') + +s_process = r'(?:clone|fork|vfork)\(.*?(?P\d+)' +s_file = r'(?P\w+)\("(?P([^"\\]|\\.)*)"(.*)' +re_lines = re.compile(r'^(?P\d+)\s+(?:(?:%s)|(?:%s))\r*$' % (s_file, s_process), re.IGNORECASE | re.MULTILINE) +strace_lock = threading.Lock() + +def configure(conf): + conf.find_program('strace') + +def task_method(func): + # Decorator function to bind/replace methods on the base Task class + # + # The methods Task.exec_command and Task.sig_implicit_deps already exists and are rarely overridden + # we thus expect that we are the only ones doing this + try: + setattr(Task.Task, 'nostrace_%s' % func.__name__, getattr(Task.Task, func.__name__)) + except AttributeError: + pass + setattr(Task.Task, func.__name__, func) + return func + +@task_method +def get_strace_file(self): + try: + return self.strace_file + except AttributeError: + pass + + if self.outputs: + ret = self.outputs[0].abspath() + '.strace' + else: + ret = '%s%s%d%s' % (self.generator.bld.bldnode.abspath(), os.sep, id(self), '.strace') + self.strace_file = ret + return ret + +@task_method +def get_strace_args(self): + return (self.env.STRACE or ['strace']) + ['-e', TRACECALLS, '-f', '-o', self.get_strace_file()] + +@task_method +def exec_command(self, cmd, **kw): + bld = self.generator.bld + if not 'cwd' in kw: + kw['cwd'] = self.get_cwd() + + args = self.get_strace_args() + fname = self.get_strace_file() + if isinstance(cmd, list): + cmd = args + cmd + else: + cmd = '%s %s' % (' '.join(args), cmd) + + try: + ret = bld.exec_command(cmd, **kw) + finally: + if not ret: + self.parse_strace_deps(fname, kw['cwd']) + return ret + +@task_method +def sig_implicit_deps(self): + # bypass the scanner functions + return + +@task_method +def parse_strace_deps(self, path, cwd): + # uncomment the following line to disable the dependencies and force a file scan + # return + try: + cnt = Utils.readf(path) + finally: + try: + os.remove(path) + except OSError: + pass + + if not isinstance(cwd, str): + cwd = cwd.abspath() + + nodes = [] + bld = self.generator.bld + try: + cache = bld.strace_cache + except AttributeError: + cache = bld.strace_cache = {} + + # chdir and relative paths + pid_to_cwd = {} + + global BANNED + done = set() + for m in re.finditer(re_lines, cnt): + # scraping the output of strace + pid = m.group('pid') + if m.group('npid'): + npid = m.group('npid') + pid_to_cwd[npid] = pid_to_cwd.get(pid, cwd) + continue + + p = m.group('path').replace('\\"', '"') + + if p == '.' or m.group().find('= -1 ENOENT') > -1: + # just to speed it up a bit + continue + + if not os.path.isabs(p): + p = os.path.join(pid_to_cwd.get(pid, cwd), p) + + call = m.group('call') + if call == 'chdir': + pid_to_cwd[pid] = p + continue + + if p in done: + continue + done.add(p) + + for x in BANNED: + if p.startswith(x): + break + else: + if p.endswith('/') or os.path.isdir(p): + continue + + try: + node = cache[p] + except KeyError: + strace_lock.acquire() + try: + cache[p] = node = bld.root.find_node(p) + if not node: + continue + finally: + strace_lock.release() + nodes.append(node) + + # record the dependencies then force the task signature recalculation for next time + if Logs.verbose: + Logs.debug('deps: real scanner for %r returned %r', self, nodes) + bld = self.generator.bld + bld.node_deps[self.uid()] = nodes + bld.raw_deps[self.uid()] = [] + try: + del self.cache_sig + except AttributeError: + pass + self.signature() + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/swig.py b/ldb-2.0.8/third_party/waf/waflib/extras/swig.py new file mode 100644 index 0000000..740ab46 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/swig.py @@ -0,0 +1,237 @@ +#! /usr/bin/env python +# encoding: UTF-8 +# Petar Forai +# Thomas Nagy 2008-2010 (ita) + +import re +from waflib import Task, Logs +from waflib.TaskGen import extension, feature, after_method +from waflib.Configure import conf +from waflib.Tools import c_preproc + +""" +tasks have to be added dynamically: +- swig interface files may be created at runtime +- the module name may be unknown in advance +""" + +SWIG_EXTS = ['.swig', '.i'] + +re_module = re.compile(r'%module(?:\s*\(.*\))?\s+(.+)', re.M) + +re_1 = re.compile(r'^%module.*?\s+([\w]+)\s*?$', re.M) +re_2 = re.compile(r'[#%](?:include|import(?:\(module=".*"\))+|python(?:begin|code)) [<"](.*)[">]', re.M) + +class swig(Task.Task): + color = 'BLUE' + run_str = '${SWIG} ${SWIGFLAGS} ${SWIGPATH_ST:INCPATHS} ${SWIGDEF_ST:DEFINES} ${SRC}' + ext_out = ['.h'] # might produce .h files although it is not mandatory + vars = ['SWIG_VERSION', 'SWIGDEPS'] + + def runnable_status(self): + for t in self.run_after: + if not t.hasrun: + return Task.ASK_LATER + + if not getattr(self, 'init_outputs', None): + self.init_outputs = True + if not getattr(self, 'module', None): + # search the module name + txt = self.inputs[0].read() + m = re_module.search(txt) + if not m: + raise ValueError("could not find the swig module name") + self.module = m.group(1) + + swig_c(self) + + # add the language-specific output files as nodes + # call funs in the dict swig_langs + for x in self.env['SWIGFLAGS']: + # obtain the language + x = x[1:] + try: + fun = swig_langs[x] + except KeyError: + pass + else: + fun(self) + + return super(swig, self).runnable_status() + + def scan(self): + "scan for swig dependencies, climb the .i files" + lst_src = [] + + seen = [] + missing = [] + to_see = [self.inputs[0]] + + while to_see: + node = to_see.pop(0) + if node in seen: + continue + seen.append(node) + lst_src.append(node) + + # read the file + code = node.read() + code = c_preproc.re_nl.sub('', code) + code = c_preproc.re_cpp.sub(c_preproc.repl, code) + + # find .i files and project headers + names = re_2.findall(code) + for n in names: + for d in self.generator.includes_nodes + [node.parent]: + u = d.find_resource(n) + if u: + to_see.append(u) + break + else: + missing.append(n) + return (lst_src, missing) + +# provide additional language processing +swig_langs = {} +def swigf(fun): + swig_langs[fun.__name__.replace('swig_', '')] = fun + return fun +swig.swigf = swigf + +def swig_c(self): + ext = '.swigwrap_%d.c' % self.generator.idx + flags = self.env['SWIGFLAGS'] + if '-c++' in flags: + ext += 'xx' + out_node = self.inputs[0].parent.find_or_declare(self.module + ext) + + if '-c++' in flags: + c_tsk = self.generator.cxx_hook(out_node) + else: + c_tsk = self.generator.c_hook(out_node) + + c_tsk.set_run_after(self) + + # transfer weights from swig task to c task + if getattr(self, 'weight', None): + c_tsk.weight = self.weight + if getattr(self, 'tree_weight', None): + c_tsk.tree_weight = self.tree_weight + + try: + self.more_tasks.append(c_tsk) + except AttributeError: + self.more_tasks = [c_tsk] + + try: + ltask = self.generator.link_task + except AttributeError: + pass + else: + ltask.set_run_after(c_tsk) + # setting input nodes does not declare the build order + # because the build already started, but it sets + # the dependency to enable rebuilds + ltask.inputs.append(c_tsk.outputs[0]) + + self.outputs.append(out_node) + + if not '-o' in self.env['SWIGFLAGS']: + self.env.append_value('SWIGFLAGS', ['-o', self.outputs[0].abspath()]) + +@swigf +def swig_python(tsk): + node = tsk.inputs[0].parent + if tsk.outdir: + node = tsk.outdir + tsk.set_outputs(node.find_or_declare(tsk.module+'.py')) + +@swigf +def swig_ocaml(tsk): + node = tsk.inputs[0].parent + if tsk.outdir: + node = tsk.outdir + tsk.set_outputs(node.find_or_declare(tsk.module+'.ml')) + tsk.set_outputs(node.find_or_declare(tsk.module+'.mli')) + +@extension(*SWIG_EXTS) +def i_file(self, node): + # the task instance + tsk = self.create_task('swig') + tsk.set_inputs(node) + tsk.module = getattr(self, 'swig_module', None) + + flags = self.to_list(getattr(self, 'swig_flags', [])) + tsk.env.append_value('SWIGFLAGS', flags) + + tsk.outdir = None + if '-outdir' in flags: + outdir = flags[flags.index('-outdir')+1] + outdir = tsk.generator.bld.bldnode.make_node(outdir) + outdir.mkdir() + tsk.outdir = outdir + +@feature('c', 'cxx', 'd', 'fc', 'asm') +@after_method('apply_link', 'process_source') +def enforce_swig_before_link(self): + try: + link_task = self.link_task + except AttributeError: + pass + else: + for x in self.tasks: + if x.__class__.__name__ == 'swig': + link_task.run_after.add(x) + +@conf +def check_swig_version(conf, minver=None): + """ + Check if the swig tool is found matching a given minimum version. + minver should be a tuple, eg. to check for swig >= 1.3.28 pass (1,3,28) as minver. + + If successful, SWIG_VERSION is defined as 'MAJOR.MINOR' + (eg. '1.3') of the actual swig version found. + + :param minver: minimum version + :type minver: tuple of int + :return: swig version + :rtype: tuple of int + """ + assert minver is None or isinstance(minver, tuple) + swigbin = conf.env['SWIG'] + if not swigbin: + conf.fatal('could not find the swig executable') + + # Get swig version string + cmd = swigbin + ['-version'] + Logs.debug('swig: Running swig command %r', cmd) + reg_swig = re.compile(r'SWIG Version\s(.*)', re.M) + swig_out = conf.cmd_and_log(cmd) + swigver_tuple = tuple([int(s) for s in reg_swig.findall(swig_out)[0].split('.')]) + + # Compare swig version with the minimum required + result = (minver is None) or (swigver_tuple >= minver) + + if result: + # Define useful environment variables + swigver = '.'.join([str(x) for x in swigver_tuple[:2]]) + conf.env['SWIG_VERSION'] = swigver + + # Feedback + swigver_full = '.'.join(map(str, swigver_tuple[:3])) + if minver is None: + conf.msg('Checking for swig version', swigver_full) + else: + minver_str = '.'.join(map(str, minver)) + conf.msg('Checking for swig version >= %s' % (minver_str,), swigver_full, color=result and 'GREEN' or 'YELLOW') + + if not result: + conf.fatal('The swig version is too old, expecting %r' % (minver,)) + + return swigver_tuple + +def configure(conf): + conf.find_program('swig', var='SWIG') + conf.env.SWIGPATH_ST = '-I%s' + conf.env.SWIGDEF_ST = '-D%s' + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/syms.py b/ldb-2.0.8/third_party/waf/waflib/extras/syms.py new file mode 100644 index 0000000..562f708 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/syms.py @@ -0,0 +1,84 @@ +#! /usr/bin/env python +# encoding: utf-8 + +""" +This tool supports the export_symbols_regex to export the symbols in a shared library. +by default, all symbols are exported by gcc, and nothing by msvc. +to use the tool, do something like: + +def build(ctx): + ctx(features='c cshlib syms', source='a.c b.c', export_symbols_regex='mylib_.*', target='testlib') + +only the symbols starting with 'mylib_' will be exported. +""" + +import re +from waflib.Context import STDOUT +from waflib.Task import Task +from waflib.Errors import WafError +from waflib.TaskGen import feature, after_method + +class gen_sym(Task): + def run(self): + obj = self.inputs[0] + kw = {} + + reg = getattr(self.generator, 'export_symbols_regex', '.+?') + if 'msvc' in (self.env.CC_NAME, self.env.CXX_NAME): + re_nm = re.compile(r'External\s+\|\s+_(?P%s)\b' % reg) + cmd = (self.env.DUMPBIN or ['dumpbin']) + ['/symbols', obj.abspath()] + else: + if self.env.DEST_BINFMT == 'pe': #gcc uses nm, and has a preceding _ on windows + re_nm = re.compile(r'(T|D)\s+_(?P%s)\b' % reg) + elif self.env.DEST_BINFMT=='mac-o': + re_nm=re.compile(r'(T|D)\s+(?P_?(%s))\b' % reg) + else: + re_nm = re.compile(r'(T|D)\s+(?P%s)\b' % reg) + cmd = (self.env.NM or ['nm']) + ['-g', obj.abspath()] + syms = [m.group('symbol') for m in re_nm.finditer(self.generator.bld.cmd_and_log(cmd, quiet=STDOUT, **kw))] + self.outputs[0].write('%r' % syms) + +class compile_sym(Task): + def run(self): + syms = {} + for x in self.inputs: + slist = eval(x.read()) + for s in slist: + syms[s] = 1 + lsyms = list(syms.keys()) + lsyms.sort() + if self.env.DEST_BINFMT == 'pe': + self.outputs[0].write('EXPORTS\n' + '\n'.join(lsyms)) + elif self.env.DEST_BINFMT == 'elf': + self.outputs[0].write('{ global:\n' + ';\n'.join(lsyms) + ";\nlocal: *; };\n") + elif self.env.DEST_BINFMT=='mac-o': + self.outputs[0].write('\n'.join(lsyms) + '\n') + else: + raise WafError('NotImplemented') + +@feature('syms') +@after_method('process_source', 'process_use', 'apply_link', 'process_uselib_local', 'propagate_uselib_vars') +def do_the_symbol_stuff(self): + def_node = self.path.find_or_declare(getattr(self, 'sym_file', self.target + '.def')) + compiled_tasks = getattr(self, 'compiled_tasks', None) + if compiled_tasks: + ins = [x.outputs[0] for x in compiled_tasks] + self.gen_sym_tasks = [self.create_task('gen_sym', x, x.change_ext('.%d.sym' % self.idx)) for x in ins] + self.create_task('compile_sym', [x.outputs[0] for x in self.gen_sym_tasks], def_node) + + link_task = getattr(self, 'link_task', None) + if link_task: + self.link_task.dep_nodes.append(def_node) + + if 'msvc' in (self.env.CC_NAME, self.env.CXX_NAME): + self.link_task.env.append_value('LINKFLAGS', ['/def:' + def_node.bldpath()]) + elif self.env.DEST_BINFMT == 'pe': + # gcc on windows takes *.def as an additional input + self.link_task.inputs.append(def_node) + elif self.env.DEST_BINFMT == 'elf': + self.link_task.env.append_value('LINKFLAGS', ['-Wl,-version-script', '-Wl,' + def_node.bldpath()]) + elif self.env.DEST_BINFMT=='mac-o': + self.link_task.env.append_value('LINKFLAGS',['-Wl,-exported_symbols_list,' + def_node.bldpath()]) + else: + raise WafError('NotImplemented') + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/ticgt.py b/ldb-2.0.8/third_party/waf/waflib/extras/ticgt.py new file mode 100644 index 0000000..f43a7ea --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/ticgt.py @@ -0,0 +1,300 @@ +#!/usr/bin/env python +# encoding: utf-8 + +# Texas Instruments code generator support (experimental) +# When reporting issues, please directly assign the bug to the maintainer. + +__author__ = __maintainer__ = "Jérôme Carretero " +__copyright__ = "Jérôme Carretero, 2012" + +""" +TI cgt6x is a compiler suite for TI DSPs. + +The toolchain does pretty weird things, and I'm sure I'm missing some of them. +But still, the tool saves time. + +What this tool does is: + +- create a TI compiler environment +- create TI compiler features, to handle some specifics about this compiler + It has a few idiosyncracies, such as not giving the liberty of the .o file names +- automatically activate them when using the TI compiler +- handle the tconf tool + The tool + +TODO: + +- the set_platform_flags() function is not nice +- more tests +- broaden tool scope, if needed + +""" + +import os, re + +from waflib import Options, Utils, Task, TaskGen +from waflib.Tools import c, ccroot, c_preproc +from waflib.Configure import conf +from waflib.TaskGen import feature, before_method +from waflib.Tools.c import cprogram + +opj = os.path.join + +@conf +def find_ticc(conf): + conf.find_program(['cl6x'], var='CC', path_list=opj(getattr(Options.options, 'ti-cgt-dir', ""), 'bin')) + conf.env.CC_NAME = 'ticc' + +@conf +def find_tild(conf): + conf.find_program(['lnk6x'], var='LINK_CC', path_list=opj(getattr(Options.options, 'ti-cgt-dir', ""), 'bin')) + conf.env.LINK_CC_NAME = 'tild' + +@conf +def find_tiar(conf): + conf.find_program(['ar6x'], var='AR', path_list=opj(getattr(Options.options, 'ti-cgt-dir', ""), 'bin')) + conf.env.AR_NAME = 'tiar' + conf.env.ARFLAGS = 'qru' + +@conf +def ticc_common_flags(conf): + v = conf.env + + if not v['LINK_CC']: + v['LINK_CC'] = v['CC'] + v['CCLNK_SRC_F'] = [] + v['CCLNK_TGT_F'] = ['-o'] + v['CPPPATH_ST'] = '-I%s' + v['DEFINES_ST'] = '-d%s' + + v['LIB_ST'] = '-l%s' # template for adding libs + v['LIBPATH_ST'] = '-i%s' # template for adding libpaths + v['STLIB_ST'] = '-l=%s.lib' + v['STLIBPATH_ST'] = '-i%s' + + # program + v['cprogram_PATTERN'] = '%s.out' + + # static lib + #v['LINKFLAGS_cstlib'] = ['-Wl,-Bstatic'] + v['cstlib_PATTERN'] = '%s.lib' + +def configure(conf): + v = conf.env + v.TI_CGT_DIR = getattr(Options.options, 'ti-cgt-dir', "") + v.TI_DSPLINK_DIR = getattr(Options.options, 'ti-dsplink-dir', "") + v.TI_BIOSUTILS_DIR = getattr(Options.options, 'ti-biosutils-dir', "") + v.TI_DSPBIOS_DIR = getattr(Options.options, 'ti-dspbios-dir', "") + v.TI_XDCTOOLS_DIR = getattr(Options.options, 'ti-xdctools-dir', "") + conf.find_ticc() + conf.find_tiar() + conf.find_tild() + conf.ticc_common_flags() + conf.cc_load_tools() + conf.cc_add_flags() + conf.link_add_flags() + conf.find_program(['tconf'], var='TCONF', path_list=v.TI_XDCTOOLS_DIR) + + conf.env.TCONF_INCLUDES += [ + opj(conf.env.TI_DSPBIOS_DIR, 'packages'), + ] + + conf.env.INCLUDES += [ + opj(conf.env.TI_CGT_DIR, 'include'), + ] + + conf.env.LIBPATH += [ + opj(conf.env.TI_CGT_DIR, "lib"), + ] + + conf.env.INCLUDES_DSPBIOS += [ + opj(conf.env.TI_DSPBIOS_DIR, 'packages', 'ti', 'bios', 'include'), + ] + + conf.env.LIBPATH_DSPBIOS += [ + opj(conf.env.TI_DSPBIOS_DIR, 'packages', 'ti', 'bios', 'lib'), + ] + + conf.env.INCLUDES_DSPLINK += [ + opj(conf.env.TI_DSPLINK_DIR, 'dsplink', 'dsp', 'inc'), + ] + +@conf +def ti_set_debug(cfg, debug=1): + """ + Sets debug flags for the compiler. + + TODO: + - for each TI CFLAG/INCLUDES/LINKFLAGS/LIBPATH replace RELEASE by DEBUG + - -g --no_compress + """ + if debug: + cfg.env.CFLAGS += "-d_DEBUG -dDEBUG -dDDSP_DEBUG".split() + +@conf +def ti_dsplink_set_platform_flags(cfg, splat, dsp, dspbios_ver, board): + """ + Sets the INCLUDES, LINKFLAGS for DSPLINK and TCONF_INCLUDES + For the specific hardware. + + Assumes that DSPLINK was built in its own folder. + + :param splat: short platform name (eg. OMAPL138) + :param dsp: DSP name (eg. 674X) + :param dspbios_ver: string identifying DspBios version (eg. 5.XX) + :param board: board name (eg. OMAPL138GEM) + + """ + d1 = opj(cfg.env.TI_DSPLINK_DIR, 'dsplink', 'dsp', 'inc', 'DspBios', dspbios_ver) + d = opj(cfg.env.TI_DSPLINK_DIR, 'dsplink', 'dsp', 'inc', 'DspBios', dspbios_ver, board) + cfg.env.TCONF_INCLUDES += [d1, d] + cfg.env.INCLUDES_DSPLINK += [ + opj(cfg.env.TI_DSPLINK_DIR, 'dsplink', 'dsp', 'inc', dsp), + d, + ] + + cfg.env.LINKFLAGS_DSPLINK += [ + opj(cfg.env.TI_DSPLINK_DIR, 'dsplink', 'dsp', 'export', 'BIN', 'DspBios', splat, board+'_0', 'RELEASE', 'dsplink%s.lib' % x) + for x in ('', 'pool', 'mpcs', 'mplist', 'msg', 'data', 'notify', 'ringio') + ] + + +def options(opt): + opt.add_option('--with-ti-cgt', type='string', dest='ti-cgt-dir', help = 'Specify alternate cgt root folder', default="") + opt.add_option('--with-ti-biosutils', type='string', dest='ti-biosutils-dir', help = 'Specify alternate biosutils folder', default="") + opt.add_option('--with-ti-dspbios', type='string', dest='ti-dspbios-dir', help = 'Specify alternate dspbios folder', default="") + opt.add_option('--with-ti-dsplink', type='string', dest='ti-dsplink-dir', help = 'Specify alternate dsplink folder', default="") + opt.add_option('--with-ti-xdctools', type='string', dest='ti-xdctools-dir', help = 'Specify alternate xdctools folder', default="") + +class ti_cprogram(cprogram): + """ + Link object files into a c program + + Changes: + + - the linked executable to have a relative path (because we can) + - put the LIBPATH first + """ + run_str = '${LINK_CC} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LINKFLAGS} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].bldpath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ' + +@feature("c") +@before_method('apply_link') +def use_ti_cprogram(self): + """ + Automatically uses ti_cprogram link process + """ + if 'cprogram' in self.features and self.env.CC_NAME == 'ticc': + self.features.insert(0, "ti_cprogram") + +class ti_c(Task.Task): + """ + Compile task for the TI codegen compiler + + This compiler does not allow specifying the output file name, only the output path. + + """ + "Compile C files into object files" + run_str = '${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${SRC} -c ${OUT} ${CPPFLAGS}' + vars = ['CCDEPS'] # unused variable to depend on, just in case + ext_in = ['.h'] # set the build order easily by using ext_out=['.h'] + scan = c_preproc.scan + +def create_compiled_task(self, name, node): + """ + Overrides ccroot.create_compiled_task to support ti_c + """ + out = '%s' % (node.change_ext('.obj').name) + if self.env.CC_NAME == 'ticc': + name = 'ti_c' + task = self.create_task(name, node, node.parent.find_or_declare(out)) + self.env.OUT = '-fr%s' % (node.parent.get_bld().abspath()) + try: + self.compiled_tasks.append(task) + except AttributeError: + self.compiled_tasks = [task] + return task + +@TaskGen.extension('.c') +def c_hook(self, node): + "Bind the c file extension to the creation of a :py:class:`waflib.Tools.c.c` instance" + if self.env.CC_NAME == 'ticc': + return create_compiled_task(self, 'ti_c', node) + else: + return self.create_compiled_task('c', node) + + +@feature("ti-tconf") +@before_method('process_source') +def apply_tconf(self): + sources = [x.get_src() for x in self.to_nodes(self.source, path=self.path.get_src())] + node = sources[0] + assert(sources[0].name.endswith(".tcf")) + if len(sources) > 1: + assert(sources[1].name.endswith(".cmd")) + + target = getattr(self, 'target', self.source) + target_node = node.get_bld().parent.find_or_declare(node.name) + + procid = "%d" % int(getattr(self, 'procid', 0)) + + importpaths = [] + includes = Utils.to_list(getattr(self, 'includes', [])) + for x in includes + self.env.TCONF_INCLUDES: + if x == os.path.abspath(x): + importpaths.append(x) + else: + relpath = self.path.find_node(x).path_from(target_node.parent) + importpaths.append(relpath) + + task = self.create_task('ti_tconf', sources, target_node.change_ext('.cdb')) + task.path = self.path + task.includes = includes + task.cwd = target_node.parent.abspath() + task.env = self.env.derive() + task.env["TCONFSRC"] = node.path_from(target_node.parent) + task.env["TCONFINC"] = '-Dconfig.importPath=%s' % ";".join(importpaths) + task.env['TCONFPROGNAME'] = '-Dconfig.programName=%s' % target + task.env['PROCID'] = procid + task.outputs = [ + target_node.change_ext("cfg_c.c"), + target_node.change_ext("cfg.s62"), + target_node.change_ext("cfg.cmd"), + ] + + create_compiled_task(self, 'ti_c', task.outputs[1]) + ctask = create_compiled_task(self, 'ti_c', task.outputs[0]) + ctask.env = self.env.derive() + + self.add_those_o_files(target_node.change_ext("cfg.cmd")) + if len(sources) > 1: + self.add_those_o_files(sources[1]) + self.source = [] + +re_tconf_include = re.compile(r'(?Putils\.importFile)\("(?P.*)"\)',re.M) +class ti_tconf(Task.Task): + run_str = '${TCONF} ${TCONFINC} ${TCONFPROGNAME} ${TCONFSRC} ${PROCID}' + color = 'PINK' + + def scan(self): + includes = Utils.to_list(getattr(self, 'includes', [])) + + def deps(node): + nodes, names = [], [] + if node: + code = Utils.readf(node.abspath()) + for match in re_tconf_include.finditer(code): + path = match.group('file') + if path: + for x in includes: + filename = opj(x, path) + fi = self.path.find_resource(filename) + if fi: + subnodes, subnames = deps(fi) + nodes += subnodes + names += subnames + nodes.append(fi) + names.append(path) + break + return nodes, names + return deps(self.inputs[0]) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/unity.py b/ldb-2.0.8/third_party/waf/waflib/extras/unity.py new file mode 100644 index 0000000..78128ed --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/unity.py @@ -0,0 +1,108 @@ +#! /usr/bin/env python +# encoding: utf-8 + +""" +Compile whole groups of C/C++ files at once +(C and C++ files are processed independently though). + +To enable globally:: + + def options(opt): + opt.load('compiler_cxx') + def build(bld): + bld.load('compiler_cxx unity') + +To enable for specific task generators only:: + + def build(bld): + bld(features='c cprogram unity', source='main.c', ...) + +The file order is often significant in such builds, so it can be +necessary to adjust the order of source files and the batch sizes. +To control the amount of files processed in a batch per target +(the default is 50):: + + def build(bld): + bld(features='c cprogram', unity_size=20) + +""" + +from waflib import Task, Options +from waflib.Tools import c_preproc +from waflib import TaskGen + +MAX_BATCH = 50 + +EXTS_C = ('.c',) +EXTS_CXX = ('.cpp','.cc','.cxx','.C','.c++') + +def options(opt): + global MAX_BATCH + opt.add_option('--batchsize', action='store', dest='batchsize', type='int', default=MAX_BATCH, + help='default unity batch size (0 disables unity builds)') + +@TaskGen.taskgen_method +def batch_size(self): + default = getattr(Options.options, 'batchsize', MAX_BATCH) + if default < 1: + return 0 + return getattr(self, 'unity_size', default) + + +class unity(Task.Task): + color = 'BLUE' + scan = c_preproc.scan + def to_include(self, node): + ret = node.path_from(self.outputs[0].parent) + ret = ret.replace('\\', '\\\\').replace('"', '\\"') + return ret + def run(self): + lst = ['#include "%s"\n' % self.to_include(node) for node in self.inputs] + txt = ''.join(lst) + self.outputs[0].write(txt) + def __str__(self): + node = self.outputs[0] + return node.path_from(node.ctx.launch_node()) + +def bind_unity(obj, cls_name, exts): + if not 'mappings' in obj.__dict__: + obj.mappings = dict(obj.mappings) + + for j in exts: + fun = obj.mappings[j] + if fun.__name__ == 'unity_fun': + raise ValueError('Attempt to bind unity mappings multiple times %r' % j) + + def unity_fun(self, node): + cnt = self.batch_size() + if cnt <= 1: + return fun(self, node) + x = getattr(self, 'master_%s' % cls_name, None) + if not x or len(x.inputs) >= cnt: + x = self.create_task('unity') + setattr(self, 'master_%s' % cls_name, x) + + cnt_cur = getattr(self, 'cnt_%s' % cls_name, 0) + c_node = node.parent.find_or_declare('unity_%s_%d_%d.%s' % (self.idx, cnt_cur, cnt, cls_name)) + x.outputs = [c_node] + setattr(self, 'cnt_%s' % cls_name, cnt_cur + 1) + fun(self, c_node) + x.inputs.append(node) + + obj.mappings[j] = unity_fun + +@TaskGen.feature('unity') +@TaskGen.before('process_source') +def single_unity(self): + lst = self.to_list(self.features) + if 'c' in lst: + bind_unity(self, 'c', EXTS_C) + if 'cxx' in lst: + bind_unity(self, 'cxx', EXTS_CXX) + +def build(bld): + if bld.env.CC_NAME: + bind_unity(TaskGen.task_gen, 'c', EXTS_C) + if bld.env.CXX_NAME: + bind_unity(TaskGen.task_gen, 'cxx', EXTS_CXX) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/use_config.py b/ldb-2.0.8/third_party/waf/waflib/extras/use_config.py new file mode 100644 index 0000000..ef5129f --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/use_config.py @@ -0,0 +1,185 @@ +#!/usr/bin/env python +# coding=utf-8 +# Mathieu Courtois - EDF R&D, 2013 - http://www.code-aster.org + +""" +When a project has a lot of options the 'waf configure' command line can be +very long and it becomes a cause of error. +This tool provides a convenient way to load a set of configuration parameters +from a local file or from a remote url. + +The configuration parameters are stored in a Python file that is imported as +an extra waf tool can be. + +Example: +$ waf configure --use-config-dir=http://www.anywhere.org --use-config=myconf1 ... + +The file 'myconf1' will be downloaded from 'http://www.anywhere.org' +(or 'http://www.anywhere.org/wafcfg'). +If the files are available locally, it could be: +$ waf configure --use-config-dir=/somewhere/myconfigurations --use-config=myconf1 ... + +The configuration of 'myconf1.py' is automatically loaded by calling +its 'configure' function. In this example, it defines environment variables and +set options: + +def configure(self): + self.env['CC'] = 'gcc-4.8' + self.env.append_value('LIBPATH', [...]) + self.options.perlbinary = '/usr/local/bin/perl' + self.options.pyc = False + +The corresponding command line should have been: +$ CC=gcc-4.8 LIBPATH=... waf configure --nopyc --with-perl-binary=/usr/local/bin/perl + + +This is an extra tool, not bundled with the default waf binary. +To add the use_config tool to the waf file: +$ ./waf-light --tools=use_config + +When using this tool, the wscript will look like: + + def options(opt): + opt.load('use_config') + + def configure(conf): + conf.load('use_config') +""" + +import sys +import os.path as osp +import os + +local_repo = '' +"""Local repository containing additional Waf tools (plugins)""" +remote_repo = 'https://gitlab.com/ita1024/waf/raw/master/' +""" +Remote directory containing downloadable waf tools. The missing tools can be downloaded by using:: + + $ waf configure --download +""" + +remote_locs = ['waflib/extras', 'waflib/Tools'] +""" +Remote directories for use with :py:const:`waflib.extras.use_config.remote_repo` +""" + + +try: + from urllib import request +except ImportError: + from urllib import urlopen +else: + urlopen = request.urlopen + + +from waflib import Errors, Context, Logs, Utils, Options, Configure + +try: + from urllib.parse import urlparse +except ImportError: + from urlparse import urlparse + + + + +DEFAULT_DIR = 'wafcfg' +# add first the current wafcfg subdirectory +sys.path.append(osp.abspath(DEFAULT_DIR)) + +def options(self): + group = self.add_option_group('configure options') + group.add_option('--download', dest='download', default=False, action='store_true', help='try to download the tools if missing') + + group.add_option('--use-config', action='store', default=None, + metavar='CFG', dest='use_config', + help='force the configuration parameters by importing ' + 'CFG.py. Several modules may be provided (comma ' + 'separated).') + group.add_option('--use-config-dir', action='store', default=DEFAULT_DIR, + metavar='CFG_DIR', dest='use_config_dir', + help='path or url where to find the configuration file') + +def download_check(node): + """ + Hook to check for the tools which are downloaded. Replace with your function if necessary. + """ + pass + + +def download_tool(tool, force=False, ctx=None): + """ + Download a Waf tool from the remote repository defined in :py:const:`waflib.extras.use_config.remote_repo`:: + + $ waf configure --download + """ + for x in Utils.to_list(remote_repo): + for sub in Utils.to_list(remote_locs): + url = '/'.join((x, sub, tool + '.py')) + try: + web = urlopen(url) + try: + if web.getcode() != 200: + continue + except AttributeError: + pass + except Exception: + # on python3 urlopen throws an exception + # python 2.3 does not have getcode and throws an exception to fail + continue + else: + tmp = ctx.root.make_node(os.sep.join((Context.waf_dir, 'waflib', 'extras', tool + '.py'))) + tmp.write(web.read(), 'wb') + Logs.warn('Downloaded %s from %s', tool, url) + download_check(tmp) + try: + module = Context.load_tool(tool) + except Exception: + Logs.warn('The tool %s from %s is unusable', tool, url) + try: + tmp.delete() + except Exception: + pass + continue + return module + + raise Errors.WafError('Could not load the Waf tool') + +def load_tool(tool, tooldir=None, ctx=None, with_sys_path=True): + try: + module = Context.load_tool_default(tool, tooldir, ctx, with_sys_path) + except ImportError as e: + if not ctx or not hasattr(Options.options, 'download'): + Logs.error('Could not load %r during options phase (download unavailable at this point)' % tool) + raise + if Options.options.download: + module = download_tool(tool, ctx=ctx) + if not module: + ctx.fatal('Could not load the Waf tool %r or download a suitable replacement from the repository (sys.path %r)\n%s' % (tool, sys.path, e)) + else: + ctx.fatal('Could not load the Waf tool %r from %r (try the --download option?):\n%s' % (tool, sys.path, e)) + return module + +Context.load_tool_default = Context.load_tool +Context.load_tool = load_tool +Configure.download_tool = download_tool + +def configure(self): + opts = self.options + use_cfg = opts.use_config + if use_cfg is None: + return + url = urlparse(opts.use_config_dir) + kwargs = {} + if url.scheme: + kwargs['download'] = True + kwargs['remote_url'] = url.geturl() + # search first with the exact url, else try with +'/wafcfg' + kwargs['remote_locs'] = ['', DEFAULT_DIR] + tooldir = url.geturl() + ' ' + DEFAULT_DIR + for cfg in use_cfg.split(','): + Logs.pprint('NORMAL', "Searching configuration '%s'..." % cfg) + self.load(cfg, tooldir=tooldir, **kwargs) + self.start_msg('Checking for configuration') + self.end_msg(use_cfg) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/valadoc.py b/ldb-2.0.8/third_party/waf/waflib/extras/valadoc.py new file mode 100644 index 0000000..c50f69e --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/valadoc.py @@ -0,0 +1,140 @@ +#! /usr/bin/env python +# encoding: UTF-8 +# Nicolas Joseph 2009 + +""" +ported from waf 1.5: +TODO: tabs vs spaces +""" + +from waflib import Task, Utils, Errors, Logs +from waflib.TaskGen import feature + +VALADOC_STR = '${VALADOC}' + +class valadoc(Task.Task): + vars = ['VALADOC', 'VALADOCFLAGS'] + color = 'BLUE' + after = ['cprogram', 'cstlib', 'cshlib', 'cxxprogram', 'cxxstlib', 'cxxshlib'] + quiet = True # no outputs .. this is weird + + def __init__(self, *k, **kw): + Task.Task.__init__(self, *k, **kw) + self.output_dir = '' + self.doclet = '' + self.package_name = '' + self.package_version = '' + self.files = [] + self.vapi_dirs = [] + self.protected = True + self.private = False + self.inherit = False + self.deps = False + self.vala_defines = [] + self.vala_target_glib = None + self.enable_non_null_experimental = False + self.force = False + + def run(self): + if not self.env['VALADOCFLAGS']: + self.env['VALADOCFLAGS'] = '' + cmd = [Utils.subst_vars(VALADOC_STR, self.env)] + cmd.append ('-o %s' % self.output_dir) + if getattr(self, 'doclet', None): + cmd.append ('--doclet %s' % self.doclet) + cmd.append ('--package-name %s' % self.package_name) + if getattr(self, 'package_version', None): + cmd.append ('--package-version %s' % self.package_version) + if getattr(self, 'packages', None): + for package in self.packages: + cmd.append ('--pkg %s' % package) + if getattr(self, 'vapi_dirs', None): + for vapi_dir in self.vapi_dirs: + cmd.append ('--vapidir %s' % vapi_dir) + if not getattr(self, 'protected', None): + cmd.append ('--no-protected') + if getattr(self, 'private', None): + cmd.append ('--private') + if getattr(self, 'inherit', None): + cmd.append ('--inherit') + if getattr(self, 'deps', None): + cmd.append ('--deps') + if getattr(self, 'vala_defines', None): + for define in self.vala_defines: + cmd.append ('--define %s' % define) + if getattr(self, 'vala_target_glib', None): + cmd.append ('--target-glib=%s' % self.vala_target_glib) + if getattr(self, 'enable_non_null_experimental', None): + cmd.append ('--enable-non-null-experimental') + if getattr(self, 'force', None): + cmd.append ('--force') + cmd.append (' '.join ([x.abspath() for x in self.files])) + return self.generator.bld.exec_command(' '.join(cmd)) + +@feature('valadoc') +def process_valadoc(self): + """ + Generate API documentation from Vala source code with valadoc + + doc = bld( + features = 'valadoc', + output_dir = '../doc/html', + package_name = 'vala-gtk-example', + package_version = '1.0.0', + packages = 'gtk+-2.0', + vapi_dirs = '../vapi', + force = True + ) + + path = bld.path.find_dir ('../src') + doc.files = path.ant_glob (incl='**/*.vala') + """ + + task = self.create_task('valadoc') + if getattr(self, 'output_dir', None): + task.output_dir = self.path.find_or_declare(self.output_dir).abspath() + else: + Errors.WafError('no output directory') + if getattr(self, 'doclet', None): + task.doclet = self.doclet + else: + Errors.WafError('no doclet directory') + if getattr(self, 'package_name', None): + task.package_name = self.package_name + else: + Errors.WafError('no package name') + if getattr(self, 'package_version', None): + task.package_version = self.package_version + if getattr(self, 'packages', None): + task.packages = Utils.to_list(self.packages) + if getattr(self, 'vapi_dirs', None): + vapi_dirs = Utils.to_list(self.vapi_dirs) + for vapi_dir in vapi_dirs: + try: + task.vapi_dirs.append(self.path.find_dir(vapi_dir).abspath()) + except AttributeError: + Logs.warn('Unable to locate Vala API directory: %r', vapi_dir) + if getattr(self, 'files', None): + task.files = self.files + else: + Errors.WafError('no input file') + if getattr(self, 'protected', None): + task.protected = self.protected + if getattr(self, 'private', None): + task.private = self.private + if getattr(self, 'inherit', None): + task.inherit = self.inherit + if getattr(self, 'deps', None): + task.deps = self.deps + if getattr(self, 'vala_defines', None): + task.vala_defines = Utils.to_list(self.vala_defines) + if getattr(self, 'vala_target_glib', None): + task.vala_target_glib = self.vala_target_glib + if getattr(self, 'enable_non_null_experimental', None): + task.enable_non_null_experimental = self.enable_non_null_experimental + if getattr(self, 'force', None): + task.force = self.force + +def configure(conf): + conf.find_program('valadoc', errmsg='You must install valadoc for generate the API documentation') + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/waf_xattr.py b/ldb-2.0.8/third_party/waf/waflib/extras/waf_xattr.py new file mode 100644 index 0000000..351dd63 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/waf_xattr.py @@ -0,0 +1,150 @@ +#! /usr/bin/env python +# encoding: utf-8 + +""" +Use extended attributes instead of database files + +1. Input files will be made writable +2. This is only for systems providing extended filesystem attributes +3. By default, hashes are calculated only if timestamp/size change (HASH_CACHE below) +4. The module enables "deep_inputs" on all tasks by propagating task signatures +5. This module also skips task signature comparisons for task code changes due to point 4. +6. This module is for Python3/Linux only, but it could be extended to Python2/other systems + using the xattr library +7. For projects in which tasks always declare output files, it should be possible to + store the rest of build context attributes on output files (imp_sigs, raw_deps and node_deps) + but this is not done here + +On a simple C++ project benchmark, the variations before and after adding waf_xattr.py were observed: +total build time: 20s -> 22s +no-op build time: 2.4s -> 1.8s +pickle file size: 2.9MB -> 2.6MB +""" + +import os +from waflib import Logs, Node, Task, Utils, Errors +from waflib.Task import SKIP_ME, RUN_ME, CANCEL_ME, ASK_LATER, SKIPPED, MISSING + +HASH_CACHE = True +SIG_VAR = 'user.waf.sig' +SEP = ','.encode() +TEMPLATE = '%b%d,%d'.encode() + +try: + PermissionError +except NameError: + PermissionError = IOError + +def getxattr(self): + return os.getxattr(self.abspath(), SIG_VAR) + +def setxattr(self, val): + os.setxattr(self.abspath(), SIG_VAR, val) + +def h_file(self): + try: + ret = getxattr(self) + except OSError: + if HASH_CACHE: + st = os.stat(self.abspath()) + mtime = st.st_mtime + size = st.st_size + else: + if len(ret) == 16: + # for build directory files + return ret + + if HASH_CACHE: + # check if timestamp and mtime match to avoid re-hashing + st = os.stat(self.abspath()) + mtime, size = ret[16:].split(SEP) + if int(1000 * st.st_mtime) == int(mtime) and st.st_size == int(size): + return ret[:16] + + ret = Utils.h_file(self.abspath()) + if HASH_CACHE: + val = TEMPLATE % (ret, int(1000 * st.st_mtime), int(st.st_size)) + try: + setxattr(self, val) + except PermissionError: + os.chmod(self.abspath(), st.st_mode | 128) + setxattr(self, val) + return ret + +def runnable_status(self): + bld = self.generator.bld + if bld.is_install < 0: + return SKIP_ME + + for t in self.run_after: + if not t.hasrun: + return ASK_LATER + elif t.hasrun < SKIPPED: + # a dependency has an error + return CANCEL_ME + + # first compute the signature + try: + new_sig = self.signature() + except Errors.TaskNotReady: + return ASK_LATER + + if not self.outputs: + # compare the signature to a signature computed previously + # this part is only for tasks with no output files + key = self.uid() + try: + prev_sig = bld.task_sigs[key] + except KeyError: + Logs.debug('task: task %r must run: it was never run before or the task code changed', self) + return RUN_ME + if new_sig != prev_sig: + Logs.debug('task: task %r must run: the task signature changed', self) + return RUN_ME + + # compare the signatures of the outputs to make a decision + for node in self.outputs: + try: + sig = node.h_file() + except EnvironmentError: + Logs.debug('task: task %r must run: an output node does not exist', self) + return RUN_ME + if sig != new_sig: + Logs.debug('task: task %r must run: an output node is stale', self) + return RUN_ME + + return (self.always_run and RUN_ME) or SKIP_ME + +def post_run(self): + bld = self.generator.bld + sig = self.signature() + for node in self.outputs: + if not node.exists(): + self.hasrun = MISSING + self.err_msg = '-> missing file: %r' % node.abspath() + raise Errors.WafError(self.err_msg) + os.setxattr(node.abspath(), 'user.waf.sig', sig) + if not self.outputs: + # only for task with no outputs + bld.task_sigs[self.uid()] = sig + if not self.keep_last_cmd: + try: + del self.last_cmd + except AttributeError: + pass + +try: + os.getxattr +except AttributeError: + pass +else: + h_file.__doc__ = Node.Node.h_file.__doc__ + + # keep file hashes as file attributes + Node.Node.h_file = h_file + + # enable "deep_inputs" on all tasks + Task.Task.runnable_status = runnable_status + Task.Task.post_run = post_run + Task.Task.sig_deep_inputs = Utils.nada + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/why.py b/ldb-2.0.8/third_party/waf/waflib/extras/why.py new file mode 100644 index 0000000..1bb941f --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/why.py @@ -0,0 +1,78 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2010 (ita) + +""" +This tool modifies the task signature scheme to store and obtain +information about the task execution (why it must run, etc):: + + def configure(conf): + conf.load('why') + +After adding the tool, a full rebuild is necessary: +waf clean build --zones=task +""" + +from waflib import Task, Utils, Logs, Errors + +def signature(self): + # compute the result one time, and suppose the scan_signature will give the good result + try: + return self.cache_sig + except AttributeError: + pass + + self.m = Utils.md5() + self.m.update(self.hcode) + id_sig = self.m.digest() + + # explicit deps + self.m = Utils.md5() + self.sig_explicit_deps() + exp_sig = self.m.digest() + + # env vars + self.m = Utils.md5() + self.sig_vars() + var_sig = self.m.digest() + + # implicit deps / scanner results + self.m = Utils.md5() + if self.scan: + try: + self.sig_implicit_deps() + except Errors.TaskRescan: + return self.signature() + impl_sig = self.m.digest() + + ret = self.cache_sig = impl_sig + id_sig + exp_sig + var_sig + return ret + + +Task.Task.signature = signature + +old = Task.Task.runnable_status +def runnable_status(self): + ret = old(self) + if ret == Task.RUN_ME: + try: + old_sigs = self.generator.bld.task_sigs[self.uid()] + except (KeyError, AttributeError): + Logs.debug("task: task must run as no previous signature exists") + else: + new_sigs = self.cache_sig + def v(x): + return Utils.to_hex(x) + + Logs.debug('Task %r', self) + msgs = ['* Implicit or scanner dependency', '* Task code', '* Source file, explicit or manual dependency', '* Configuration data variable'] + tmp = 'task: -> %s: %s %s' + for x in range(len(msgs)): + l = len(Utils.SIG_NIL) + a = new_sigs[x*l : (x+1)*l] + b = old_sigs[x*l : (x+1)*l] + if (a != b): + Logs.debug(tmp, msgs[x].ljust(35), v(a), v(b)) + return ret +Task.Task.runnable_status = runnable_status + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/win32_opts.py b/ldb-2.0.8/third_party/waf/waflib/extras/win32_opts.py new file mode 100644 index 0000000..9f7443c --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/win32_opts.py @@ -0,0 +1,170 @@ +#! /usr/bin/env python +# encoding: utf-8 + +""" +Windows-specific optimizations + +This module can help reducing the overhead of listing files on windows +(more than 10000 files). Python 3.5 already provides the listdir +optimization though. +""" + +import os +from waflib import Utils, Build, Node, Logs + +try: + TP = '%s\\*'.decode('ascii') +except AttributeError: + TP = '%s\\*' + +if Utils.is_win32: + from waflib.Tools import md5_tstamp + import ctypes, ctypes.wintypes + + FindFirstFile = ctypes.windll.kernel32.FindFirstFileW + FindNextFile = ctypes.windll.kernel32.FindNextFileW + FindClose = ctypes.windll.kernel32.FindClose + FILE_ATTRIBUTE_DIRECTORY = 0x10 + INVALID_HANDLE_VALUE = -1 + UPPER_FOLDERS = ('.', '..') + try: + UPPER_FOLDERS = [unicode(x) for x in UPPER_FOLDERS] + except NameError: + pass + + def cached_hash_file(self): + try: + cache = self.ctx.cache_listdir_cache_hash_file + except AttributeError: + cache = self.ctx.cache_listdir_cache_hash_file = {} + + if id(self.parent) in cache: + try: + t = cache[id(self.parent)][self.name] + except KeyError: + raise IOError('Not a file') + else: + # an opportunity to list the files and the timestamps at once + findData = ctypes.wintypes.WIN32_FIND_DATAW() + find = FindFirstFile(TP % self.parent.abspath(), ctypes.byref(findData)) + + if find == INVALID_HANDLE_VALUE: + cache[id(self.parent)] = {} + raise IOError('Not a file') + + cache[id(self.parent)] = lst_files = {} + try: + while True: + if findData.cFileName not in UPPER_FOLDERS: + thatsadir = findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY + if not thatsadir: + ts = findData.ftLastWriteTime + d = (ts.dwLowDateTime << 32) | ts.dwHighDateTime + lst_files[str(findData.cFileName)] = d + if not FindNextFile(find, ctypes.byref(findData)): + break + except Exception: + cache[id(self.parent)] = {} + raise IOError('Not a file') + finally: + FindClose(find) + t = lst_files[self.name] + + fname = self.abspath() + if fname in Build.hashes_md5_tstamp: + if Build.hashes_md5_tstamp[fname][0] == t: + return Build.hashes_md5_tstamp[fname][1] + + try: + fd = os.open(fname, os.O_BINARY | os.O_RDONLY | os.O_NOINHERIT) + except OSError: + raise IOError('Cannot read from %r' % fname) + f = os.fdopen(fd, 'rb') + m = Utils.md5() + rb = 1 + try: + while rb: + rb = f.read(200000) + m.update(rb) + finally: + f.close() + + # ensure that the cache is overwritten + Build.hashes_md5_tstamp[fname] = (t, m.digest()) + return m.digest() + Node.Node.cached_hash_file = cached_hash_file + + def get_bld_sig_win32(self): + try: + return self.ctx.hash_cache[id(self)] + except KeyError: + pass + except AttributeError: + self.ctx.hash_cache = {} + self.ctx.hash_cache[id(self)] = ret = Utils.h_file(self.abspath()) + return ret + Node.Node.get_bld_sig = get_bld_sig_win32 + + def isfile_cached(self): + # optimize for nt.stat calls, assuming there are many files for few folders + try: + cache = self.__class__.cache_isfile_cache + except AttributeError: + cache = self.__class__.cache_isfile_cache = {} + + try: + c1 = cache[id(self.parent)] + except KeyError: + c1 = cache[id(self.parent)] = [] + + curpath = self.parent.abspath() + findData = ctypes.wintypes.WIN32_FIND_DATAW() + find = FindFirstFile(TP % curpath, ctypes.byref(findData)) + + if find == INVALID_HANDLE_VALUE: + Logs.error("invalid win32 handle isfile_cached %r", self.abspath()) + return os.path.isfile(self.abspath()) + + try: + while True: + if findData.cFileName not in UPPER_FOLDERS: + thatsadir = findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY + if not thatsadir: + c1.append(str(findData.cFileName)) + if not FindNextFile(find, ctypes.byref(findData)): + break + except Exception as e: + Logs.error('exception while listing a folder %r %r', self.abspath(), e) + return os.path.isfile(self.abspath()) + finally: + FindClose(find) + return self.name in c1 + Node.Node.isfile_cached = isfile_cached + + def find_or_declare_win32(self, lst): + # assuming that "find_or_declare" is called before the build starts, remove the calls to os.path.isfile + if isinstance(lst, str): + lst = [x for x in Utils.split_path(lst) if x and x != '.'] + + node = self.get_bld().search_node(lst) + if node: + if not node.isfile_cached(): + try: + node.parent.mkdir() + except OSError: + pass + return node + self = self.get_src() + node = self.find_node(lst) + if node: + if not node.isfile_cached(): + try: + node.parent.mkdir() + except OSError: + pass + return node + node = self.get_bld().make_node(lst) + node.parent.mkdir() + return node + Node.Node.find_or_declare = find_or_declare_win32 + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/wix.py b/ldb-2.0.8/third_party/waf/waflib/extras/wix.py new file mode 100644 index 0000000..d87bfbb --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/wix.py @@ -0,0 +1,87 @@ +#!/usr/bin/python +# encoding: utf-8 +# vim: tabstop=4 noexpandtab + +""" +Windows Installer XML Tool (WiX) + +.wxs --- candle ---> .wxobj --- light ---> .msi + +bld(features='wix', some.wxs, gen='some.msi', candleflags=[..], lightflags=[..]) + +bld(features='wix', source=['bundle.wxs','WixBalExtension'], gen='setup.exe', candleflags=[..]) +""" + +import os, copy +from waflib import TaskGen +from waflib import Task +from waflib.Utils import winreg + +class candle(Task.Task): + run_str = '${CANDLE} -nologo ${CANDLEFLAGS} -out ${TGT} ${SRC[0].abspath()}', + +class light(Task.Task): + run_str = "${LIGHT} -nologo -b ${SRC[0].parent.abspath()} ${LIGHTFLAGS} -out ${TGT} ${SRC[0].abspath()}" + +@TaskGen.feature('wix') +@TaskGen.before_method('process_source') +def wix(self): + #X.wxs -> ${SRC} for CANDLE + #X.wxobj -> ${SRC} for LIGHT + #X.dll -> -ext X in ${LIGHTFLAGS} + #X.wxl -> wixui.wixlib -loc X.wxl in ${LIGHTFLAGS} + wxobj = [] + wxs = [] + exts = [] + wxl = [] + rest = [] + for x in self.source: + if x.endswith('.wxobj'): + wxobj.append(x) + elif x.endswith('.wxs'): + wxobj.append(self.path.find_or_declare(x[:-4]+'.wxobj')) + wxs.append(x) + elif x.endswith('.dll'): + exts.append(x[:-4]) + elif '.' not in x: + exts.append(x) + elif x.endswith('.wxl'): + wxl.append(x) + else: + rest.append(x) + self.source = self.to_nodes(rest) #.wxs + + cndl = self.create_task('candle', self.to_nodes(wxs), self.to_nodes(wxobj)) + lght = self.create_task('light', self.to_nodes(wxobj), self.path.find_or_declare(self.gen)) + + cndl.env.CANDLEFLAGS = copy.copy(getattr(self,'candleflags',[])) + lght.env.LIGHTFLAGS = copy.copy(getattr(self,'lightflags',[])) + + for x in wxl: + lght.env.append_value('LIGHTFLAGS','wixui.wixlib') + lght.env.append_value('LIGHTFLAGS','-loc') + lght.env.append_value('LIGHTFLAGS',x) + for x in exts: + cndl.env.append_value('CANDLEFLAGS','-ext') + cndl.env.append_value('CANDLEFLAGS',x) + lght.env.append_value('LIGHTFLAGS','-ext') + lght.env.append_value('LIGHTFLAGS',x) + +#wix_bin_path() +def wix_bin_path(): + basekey = r"SOFTWARE\Microsoft\.NETFramework\AssemblyFolders" + query = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, basekey) + cnt=winreg.QueryInfoKey(query)[0] + thiskey = r'C:\Program Files (x86)\WiX Toolset v3.10\SDK' + for i in range(cnt-1,-1,-1): + thiskey = winreg.EnumKey(query,i) + if 'WiX' in thiskey: + break + winreg.CloseKey(query) + return os.path.normpath(winreg.QueryValue(winreg.HKEY_LOCAL_MACHINE, basekey+r'\\'+thiskey)+'..\\bin') + +def configure(ctx): + path_list=[wix_bin_path()] + ctx.find_program('candle', var='CANDLE', mandatory=True, path_list = path_list) + ctx.find_program('light', var='LIGHT', mandatory=True, path_list = path_list) + diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/xcode6.py b/ldb-2.0.8/third_party/waf/waflib/extras/xcode6.py new file mode 100644 index 0000000..91bbff1 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/extras/xcode6.py @@ -0,0 +1,727 @@ +#! /usr/bin/env python +# encoding: utf-8 +# XCode 3/XCode 4/XCode 6/Xcode 7 generator for Waf +# Based on work by Nicolas Mercier 2011 +# Extended by Simon Warg 2015, https://github.com/mimon +# XCode project file format based on http://www.monobjc.net/xcode-project-file-format.html + +""" +See playground/xcode6/ for usage examples. + +""" + +from waflib import Context, TaskGen, Build, Utils, Errors, Logs +import os, sys + +# FIXME too few extensions +XCODE_EXTS = ['.c', '.cpp', '.m', '.mm'] + +HEADERS_GLOB = '**/(*.h|*.hpp|*.H|*.inl)' + +MAP_EXT = { + '': "folder", + '.h' : "sourcecode.c.h", + + '.hh': "sourcecode.cpp.h", + '.inl': "sourcecode.cpp.h", + '.hpp': "sourcecode.cpp.h", + + '.c': "sourcecode.c.c", + + '.m': "sourcecode.c.objc", + + '.mm': "sourcecode.cpp.objcpp", + + '.cc': "sourcecode.cpp.cpp", + + '.cpp': "sourcecode.cpp.cpp", + '.C': "sourcecode.cpp.cpp", + '.cxx': "sourcecode.cpp.cpp", + '.c++': "sourcecode.cpp.cpp", + + '.l': "sourcecode.lex", # luthor + '.ll': "sourcecode.lex", + + '.y': "sourcecode.yacc", + '.yy': "sourcecode.yacc", + + '.plist': "text.plist.xml", + ".nib": "wrapper.nib", + ".xib": "text.xib", +} + +# Used in PBXNativeTarget elements +PRODUCT_TYPE_APPLICATION = 'com.apple.product-type.application' +PRODUCT_TYPE_FRAMEWORK = 'com.apple.product-type.framework' +PRODUCT_TYPE_EXECUTABLE = 'com.apple.product-type.tool' +PRODUCT_TYPE_LIB_STATIC = 'com.apple.product-type.library.static' +PRODUCT_TYPE_LIB_DYNAMIC = 'com.apple.product-type.library.dynamic' +PRODUCT_TYPE_EXTENSION = 'com.apple.product-type.kernel-extension' +PRODUCT_TYPE_IOKIT = 'com.apple.product-type.kernel-extension.iokit' + +# Used in PBXFileReference elements +FILE_TYPE_APPLICATION = 'wrapper.cfbundle' +FILE_TYPE_FRAMEWORK = 'wrapper.framework' +FILE_TYPE_LIB_DYNAMIC = 'compiled.mach-o.dylib' +FILE_TYPE_LIB_STATIC = 'archive.ar' +FILE_TYPE_EXECUTABLE = 'compiled.mach-o.executable' + +# Tuple packs of the above +TARGET_TYPE_FRAMEWORK = (PRODUCT_TYPE_FRAMEWORK, FILE_TYPE_FRAMEWORK, '.framework') +TARGET_TYPE_APPLICATION = (PRODUCT_TYPE_APPLICATION, FILE_TYPE_APPLICATION, '.app') +TARGET_TYPE_DYNAMIC_LIB = (PRODUCT_TYPE_LIB_DYNAMIC, FILE_TYPE_LIB_DYNAMIC, '.dylib') +TARGET_TYPE_STATIC_LIB = (PRODUCT_TYPE_LIB_STATIC, FILE_TYPE_LIB_STATIC, '.a') +TARGET_TYPE_EXECUTABLE = (PRODUCT_TYPE_EXECUTABLE, FILE_TYPE_EXECUTABLE, '') + +# Maps target type string to its data +TARGET_TYPES = { + 'framework': TARGET_TYPE_FRAMEWORK, + 'app': TARGET_TYPE_APPLICATION, + 'dylib': TARGET_TYPE_DYNAMIC_LIB, + 'stlib': TARGET_TYPE_STATIC_LIB, + 'exe' :TARGET_TYPE_EXECUTABLE, +} + +def delete_invalid_values(dct): + """ Deletes entries that are dictionaries or sets """ + for k, v in list(dct.items()): + if isinstance(v, dict) or isinstance(v, set): + del dct[k] + return dct + +""" +Configuration of the global project settings. Sets an environment variable 'PROJ_CONFIGURATION' +which is a dictionary of configuration name and buildsettings pair. +E.g.: +env.PROJ_CONFIGURATION = { + 'Debug': { + 'ARCHS': 'x86', + ... + } + 'Release': { + 'ARCHS' x86_64' + ... + } +} +The user can define a completely customized dictionary in configure() stage. Otherwise a default Debug/Release will be created +based on env variable +""" +def configure(self): + if not self.env.PROJ_CONFIGURATION: + self.to_log("A default project configuration was created since no custom one was given in the configure(conf) stage. Define your custom project settings by adding PROJ_CONFIGURATION to env. The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.\n") + + # Check for any added config files added by the tool 'c_config'. + if 'cfg_files' in self.env: + self.env.INCLUDES = Utils.to_list(self.env.INCLUDES) + [os.path.abspath(os.path.dirname(f)) for f in self.env.cfg_files] + + # Create default project configuration? + if 'PROJ_CONFIGURATION' not in self.env: + defaults = delete_invalid_values(self.env.get_merged_dict()) + self.env.PROJ_CONFIGURATION = { + "Debug": defaults, + "Release": defaults, + } + + # Some build settings are required to be present by XCode. We will supply default values + # if user hasn't defined any. + defaults_required = [('PRODUCT_NAME', '$(TARGET_NAME)')] + for cfgname,settings in self.env.PROJ_CONFIGURATION.items(): + for default_var, default_val in defaults_required: + if default_var not in settings: + settings[default_var] = default_val + + # Error check customization + if not isinstance(self.env.PROJ_CONFIGURATION, dict): + raise Errors.ConfigurationError("The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.") + +part1 = 0 +part2 = 10000 +part3 = 0 +id = 562000999 +def newid(): + global id + id += 1 + return "%04X%04X%04X%012d" % (0, 10000, 0, id) + +""" +Represents a tree node in the XCode project plist file format. +When written to a file, all attributes of XCodeNode are stringified together with +its value. However, attributes starting with an underscore _ are ignored +during that process and allows you to store arbitrary values that are not supposed +to be written out. +""" +class XCodeNode(object): + def __init__(self): + self._id = newid() + self._been_written = False + + def tostring(self, value): + if isinstance(value, dict): + result = "{\n" + for k,v in value.items(): + result = result + "\t\t\t%s = %s;\n" % (k, self.tostring(v)) + result = result + "\t\t}" + return result + elif isinstance(value, str): + return "\"%s\"" % value + elif isinstance(value, list): + result = "(\n" + for i in value: + result = result + "\t\t\t%s,\n" % self.tostring(i) + result = result + "\t\t)" + return result + elif isinstance(value, XCodeNode): + return value._id + else: + return str(value) + + def write_recursive(self, value, file): + if isinstance(value, dict): + for k,v in value.items(): + self.write_recursive(v, file) + elif isinstance(value, list): + for i in value: + self.write_recursive(i, file) + elif isinstance(value, XCodeNode): + value.write(file) + + def write(self, file): + if not self._been_written: + self._been_written = True + for attribute,value in self.__dict__.items(): + if attribute[0] != '_': + self.write_recursive(value, file) + w = file.write + w("\t%s = {\n" % self._id) + w("\t\tisa = %s;\n" % self.__class__.__name__) + for attribute,value in self.__dict__.items(): + if attribute[0] != '_': + w("\t\t%s = %s;\n" % (attribute, self.tostring(value))) + w("\t};\n\n") + +# Configurations +class XCBuildConfiguration(XCodeNode): + def __init__(self, name, settings = {}, env=None): + XCodeNode.__init__(self) + self.baseConfigurationReference = "" + self.buildSettings = settings + self.name = name + if env and env.ARCH: + settings['ARCHS'] = " ".join(env.ARCH) + + +class XCConfigurationList(XCodeNode): + def __init__(self, configlst): + """ :param configlst: list of XCConfigurationList """ + XCodeNode.__init__(self) + self.buildConfigurations = configlst + self.defaultConfigurationIsVisible = 0 + self.defaultConfigurationName = configlst and configlst[0].name or "" + +# Group/Files +class PBXFileReference(XCodeNode): + def __init__(self, name, path, filetype = '', sourcetree = "SOURCE_ROOT"): + + XCodeNode.__init__(self) + self.fileEncoding = 4 + if not filetype: + _, ext = os.path.splitext(name) + filetype = MAP_EXT.get(ext, 'text') + self.lastKnownFileType = filetype + self.explicitFileType = filetype + self.name = name + self.path = path + self.sourceTree = sourcetree + + def __hash__(self): + return (self.path+self.name).__hash__() + + def __eq__(self, other): + return (self.path, self.name) == (other.path, other.name) + +class PBXBuildFile(XCodeNode): + """ This element indicate a file reference that is used in a PBXBuildPhase (either as an include or resource). """ + def __init__(self, fileRef, settings={}): + XCodeNode.__init__(self) + + # fileRef is a reference to a PBXFileReference object + self.fileRef = fileRef + + # A map of key/value pairs for additional settings. + self.settings = settings + + def __hash__(self): + return (self.fileRef).__hash__() + + def __eq__(self, other): + return self.fileRef == other.fileRef + +class PBXGroup(XCodeNode): + def __init__(self, name, sourcetree = 'SOURCE_TREE'): + XCodeNode.__init__(self) + self.children = [] + self.name = name + self.sourceTree = sourcetree + + # Maintain a lookup table for all PBXFileReferences + # that are contained in this group. + self._filerefs = {} + + def add(self, sources): + """ + Add a list of PBXFileReferences to this group + + :param sources: list of PBXFileReferences objects + """ + self._filerefs.update(dict(zip(sources, sources))) + self.children.extend(sources) + + def get_sub_groups(self): + """ + Returns all child PBXGroup objects contained in this group + """ + return list(filter(lambda x: isinstance(x, PBXGroup), self.children)) + + def find_fileref(self, fileref): + """ + Recursively search this group for an existing PBXFileReference. Returns None + if none were found. + + The reason you'd want to reuse existing PBXFileReferences from a PBXGroup is that XCode doesn't like PBXFileReferences that aren't part of a PBXGroup hierarchy. + If it isn't, the consequence is that certain UI features like 'Reveal in Finder' + stops working. + """ + if fileref in self._filerefs: + return self._filerefs[fileref] + elif self.children: + for childgroup in self.get_sub_groups(): + f = childgroup.find_fileref(fileref) + if f: + return f + return None + +class PBXContainerItemProxy(XCodeNode): + """ This is the element for to decorate a target item. """ + def __init__(self, containerPortal, remoteGlobalIDString, remoteInfo='', proxyType=1): + XCodeNode.__init__(self) + self.containerPortal = containerPortal # PBXProject + self.remoteGlobalIDString = remoteGlobalIDString # PBXNativeTarget + self.remoteInfo = remoteInfo # Target name + self.proxyType = proxyType + +class PBXTargetDependency(XCodeNode): + """ This is the element for referencing other target through content proxies. """ + def __init__(self, native_target, proxy): + XCodeNode.__init__(self) + self.target = native_target + self.targetProxy = proxy + +class PBXFrameworksBuildPhase(XCodeNode): + """ This is the element for the framework link build phase, i.e. linking to frameworks """ + def __init__(self, pbxbuildfiles): + XCodeNode.__init__(self) + self.buildActionMask = 2147483647 + self.runOnlyForDeploymentPostprocessing = 0 + self.files = pbxbuildfiles #List of PBXBuildFile (.o, .framework, .dylib) + +class PBXHeadersBuildPhase(XCodeNode): + """ This is the element for adding header files to be packaged into the .framework """ + def __init__(self, pbxbuildfiles): + XCodeNode.__init__(self) + self.buildActionMask = 2147483647 + self.runOnlyForDeploymentPostprocessing = 0 + self.files = pbxbuildfiles #List of PBXBuildFile (.o, .framework, .dylib) + +class PBXCopyFilesBuildPhase(XCodeNode): + """ + Represents the PBXCopyFilesBuildPhase section. PBXBuildFile + can be added to this node to copy files after build is done. + """ + def __init__(self, pbxbuildfiles, dstpath, dstSubpathSpec=0, *args, **kwargs): + XCodeNode.__init__(self) + self.files = pbxbuildfiles + self.dstPath = dstpath + self.dstSubfolderSpec = dstSubpathSpec + +class PBXSourcesBuildPhase(XCodeNode): + """ Represents the 'Compile Sources' build phase in a Xcode target """ + def __init__(self, buildfiles): + XCodeNode.__init__(self) + self.files = buildfiles # List of PBXBuildFile objects + +class PBXLegacyTarget(XCodeNode): + def __init__(self, action, target=''): + XCodeNode.__init__(self) + self.buildConfigurationList = XCConfigurationList([XCBuildConfiguration('waf', {})]) + if not target: + self.buildArgumentsString = "%s %s" % (sys.argv[0], action) + else: + self.buildArgumentsString = "%s %s --targets=%s" % (sys.argv[0], action, target) + self.buildPhases = [] + self.buildToolPath = sys.executable + self.buildWorkingDirectory = "" + self.dependencies = [] + self.name = target or action + self.productName = target or action + self.passBuildSettingsInEnvironment = 0 + +class PBXShellScriptBuildPhase(XCodeNode): + def __init__(self, action, target): + XCodeNode.__init__(self) + self.buildActionMask = 2147483647 + self.files = [] + self.inputPaths = [] + self.outputPaths = [] + self.runOnlyForDeploymentPostProcessing = 0 + self.shellPath = "/bin/sh" + self.shellScript = "%s %s %s --targets=%s" % (sys.executable, sys.argv[0], action, target) + +class PBXNativeTarget(XCodeNode): + """ Represents a target in XCode, e.g. App, DyLib, Framework etc. """ + def __init__(self, target, node, target_type=TARGET_TYPE_APPLICATION, configlist=[], buildphases=[]): + XCodeNode.__init__(self) + product_type = target_type[0] + file_type = target_type[1] + + self.buildConfigurationList = XCConfigurationList(configlist) + self.buildPhases = buildphases + self.buildRules = [] + self.dependencies = [] + self.name = target + self.productName = target + self.productType = product_type # See TARGET_TYPE_ tuples constants + self.productReference = PBXFileReference(node.name, node.abspath(), file_type, '') + + def add_configuration(self, cf): + """ :type cf: XCBuildConfiguration """ + self.buildConfigurationList.buildConfigurations.append(cf) + + def add_build_phase(self, phase): + # Some build phase types may appear only once. If a phase type already exists, then merge them. + if ( (phase.__class__ == PBXFrameworksBuildPhase) + or (phase.__class__ == PBXSourcesBuildPhase) ): + for b in self.buildPhases: + if b.__class__ == phase.__class__: + b.files.extend(phase.files) + return + self.buildPhases.append(phase) + + def add_dependency(self, depnd): + self.dependencies.append(depnd) + +# Root project object +class PBXProject(XCodeNode): + def __init__(self, name, version, env): + XCodeNode.__init__(self) + + if not isinstance(env.PROJ_CONFIGURATION, dict): + raise Errors.WafError("Error: env.PROJ_CONFIGURATION must be a dictionary. This is done for you if you do not define one yourself. However, did you load the xcode module at the end of your wscript configure() ?") + + # Retrieve project configuration + configurations = [] + for config_name, settings in env.PROJ_CONFIGURATION.items(): + cf = XCBuildConfiguration(config_name, settings) + configurations.append(cf) + + self.buildConfigurationList = XCConfigurationList(configurations) + self.compatibilityVersion = version[0] + self.hasScannedForEncodings = 1 + self.mainGroup = PBXGroup(name) + self.projectRoot = "" + self.projectDirPath = "" + self.targets = [] + self._objectVersion = version[1] + + def create_target_dependency(self, target, name): + """ : param target : PXBNativeTarget """ + proxy = PBXContainerItemProxy(self, target, name) + dependency = PBXTargetDependency(target, proxy) + return dependency + + def write(self, file): + + # Make sure this is written only once + if self._been_written: + return + + w = file.write + w("// !$*UTF8*$!\n") + w("{\n") + w("\tarchiveVersion = 1;\n") + w("\tclasses = {\n") + w("\t};\n") + w("\tobjectVersion = %d;\n" % self._objectVersion) + w("\tobjects = {\n\n") + + XCodeNode.write(self, file) + + w("\t};\n") + w("\trootObject = %s;\n" % self._id) + w("}\n") + + def add_target(self, target): + self.targets.append(target) + + def get_target(self, name): + """ Get a reference to PBXNativeTarget if it exists """ + for t in self.targets: + if t.name == name: + return t + return None + +@TaskGen.feature('c', 'cxx') +@TaskGen.after('propagate_uselib_vars', 'apply_incpaths') +def process_xcode(self): + bld = self.bld + try: + p = bld.project + except AttributeError: + return + + if not hasattr(self, 'target_type'): + return + + products_group = bld.products_group + + target_group = PBXGroup(self.name) + p.mainGroup.children.append(target_group) + + # Determine what type to build - framework, app bundle etc. + target_type = getattr(self, 'target_type', 'app') + if target_type not in TARGET_TYPES: + raise Errors.WafError("Target type '%s' does not exists. Available options are '%s'. In target '%s'" % (target_type, "', '".join(TARGET_TYPES.keys()), self.name)) + else: + target_type = TARGET_TYPES[target_type] + file_ext = target_type[2] + + # Create the output node + target_node = self.path.find_or_declare(self.name+file_ext) + target = PBXNativeTarget(self.name, target_node, target_type, [], []) + + products_group.children.append(target.productReference) + + # Pull source files from the 'source' attribute and assign them to a UI group. + # Use a default UI group named 'Source' unless the user + # provides a 'group_files' dictionary to customize the UI grouping. + sources = getattr(self, 'source', []) + if hasattr(self, 'group_files'): + group_files = getattr(self, 'group_files', []) + for grpname,files in group_files.items(): + group = bld.create_group(grpname, files) + target_group.children.append(group) + else: + group = bld.create_group('Source', sources) + target_group.children.append(group) + + # Create a PBXFileReference for each source file. + # If the source file already exists as a PBXFileReference in any of the UI groups, then + # reuse that PBXFileReference object (XCode does not like it if we don't reuse) + for idx, path in enumerate(sources): + fileref = PBXFileReference(path.name, path.abspath()) + existing_fileref = target_group.find_fileref(fileref) + if existing_fileref: + sources[idx] = existing_fileref + else: + sources[idx] = fileref + + # If the 'source' attribute contains any file extension that XCode can't work with, + # then remove it. The allowed file extensions are defined in XCODE_EXTS. + is_valid_file_extension = lambda file: os.path.splitext(file.path)[1] in XCODE_EXTS + sources = list(filter(is_valid_file_extension, sources)) + + buildfiles = [bld.unique_buildfile(PBXBuildFile(x)) for x in sources] + target.add_build_phase(PBXSourcesBuildPhase(buildfiles)) + + # Check if any framework to link against is some other target we've made + libs = getattr(self, 'tmp_use_seen', []) + for lib in libs: + use_target = p.get_target(lib) + if use_target: + # Create an XCode dependency so that XCode knows to build the other target before this target + dependency = p.create_target_dependency(use_target, use_target.name) + target.add_dependency(dependency) + + buildphase = PBXFrameworksBuildPhase([PBXBuildFile(use_target.productReference)]) + target.add_build_phase(buildphase) + if lib in self.env.LIB: + self.env.LIB = list(filter(lambda x: x != lib, self.env.LIB)) + + # If 'export_headers' is present, add files to the Headers build phase in xcode. + # These are files that'll get packed into the Framework for instance. + exp_hdrs = getattr(self, 'export_headers', []) + hdrs = bld.as_nodes(Utils.to_list(exp_hdrs)) + files = [p.mainGroup.find_fileref(PBXFileReference(n.name, n.abspath())) for n in hdrs] + files = [PBXBuildFile(f, {'ATTRIBUTES': ('Public',)}) for f in files] + buildphase = PBXHeadersBuildPhase(files) + target.add_build_phase(buildphase) + + # Merge frameworks and libs into one list, and prefix the frameworks + frameworks = Utils.to_list(self.env.FRAMEWORK) + frameworks = ' '.join(['-framework %s' % (f.split('.framework')[0]) for f in frameworks]) + + libs = Utils.to_list(self.env.STLIB) + Utils.to_list(self.env.LIB) + libs = ' '.join(bld.env['STLIB_ST'] % t for t in libs) + + # Override target specific build settings + bldsettings = { + 'HEADER_SEARCH_PATHS': ['$(inherited)'] + self.env['INCPATHS'], + 'LIBRARY_SEARCH_PATHS': ['$(inherited)'] + Utils.to_list(self.env.LIBPATH) + Utils.to_list(self.env.STLIBPATH) + Utils.to_list(self.env.LIBDIR) , + 'FRAMEWORK_SEARCH_PATHS': ['$(inherited)'] + Utils.to_list(self.env.FRAMEWORKPATH), + 'OTHER_LDFLAGS': libs + ' ' + frameworks, + 'OTHER_LIBTOOLFLAGS': bld.env['LINKFLAGS'], + 'OTHER_CPLUSPLUSFLAGS': Utils.to_list(self.env['CXXFLAGS']), + 'OTHER_CFLAGS': Utils.to_list(self.env['CFLAGS']), + 'INSTALL_PATH': [] + } + + # Install path + installpaths = Utils.to_list(getattr(self, 'install', [])) + prodbuildfile = PBXBuildFile(target.productReference) + for instpath in installpaths: + bldsettings['INSTALL_PATH'].append(instpath) + target.add_build_phase(PBXCopyFilesBuildPhase([prodbuildfile], instpath)) + + if not bldsettings['INSTALL_PATH']: + del bldsettings['INSTALL_PATH'] + + # Create build settings which can override the project settings. Defaults to none if user + # did not pass argument. This will be filled up with target specific + # search paths, libs to link etc. + settings = getattr(self, 'settings', {}) + + # The keys represents different build configuration, e.g. Debug, Release and so on.. + # Insert our generated build settings to all configuration names + keys = set(settings.keys() + bld.env.PROJ_CONFIGURATION.keys()) + for k in keys: + if k in settings: + settings[k].update(bldsettings) + else: + settings[k] = bldsettings + + for k,v in settings.items(): + target.add_configuration(XCBuildConfiguration(k, v)) + + p.add_target(target) + + +class xcode(Build.BuildContext): + cmd = 'xcode6' + fun = 'build' + + def as_nodes(self, files): + """ Returns a list of waflib.Nodes from a list of string of file paths """ + nodes = [] + for x in files: + if not isinstance(x, str): + d = x + else: + d = self.srcnode.find_node(x) + if not d: + raise Errors.WafError('File \'%s\' was not found' % x) + nodes.append(d) + return nodes + + def create_group(self, name, files): + """ + Returns a new PBXGroup containing the files (paths) passed in the files arg + :type files: string + """ + group = PBXGroup(name) + """ + Do not use unique file reference here, since XCode seem to allow only one file reference + to be referenced by a group. + """ + files_ = [] + for d in self.as_nodes(Utils.to_list(files)): + fileref = PBXFileReference(d.name, d.abspath()) + files_.append(fileref) + group.add(files_) + return group + + def unique_buildfile(self, buildfile): + """ + Returns a unique buildfile, possibly an existing one. + Use this after you've constructed a PBXBuildFile to make sure there is + only one PBXBuildFile for the same file in the same project. + """ + try: + build_files = self.build_files + except AttributeError: + build_files = self.build_files = {} + + if buildfile not in build_files: + build_files[buildfile] = buildfile + return build_files[buildfile] + + def execute(self): + """ + Entry point + """ + self.restore() + if not self.all_envs: + self.load_envs() + self.recurse([self.run_dir]) + + appname = getattr(Context.g_module, Context.APPNAME, os.path.basename(self.srcnode.abspath())) + + p = PBXProject(appname, ('Xcode 3.2', 46), self.env) + + # If we don't create a Products group, then + # XCode will create one, which entails that + # we'll start to see duplicate files in the UI + # for some reason. + products_group = PBXGroup('Products') + p.mainGroup.children.append(products_group) + + self.project = p + self.products_group = products_group + + # post all task generators + # the process_xcode method above will be called for each target + if self.targets and self.targets != '*': + (self._min_grp, self._exact_tg) = self.get_targets() + + self.current_group = 0 + while self.current_group < len(self.groups): + self.post_group() + self.current_group += 1 + + node = self.bldnode.make_node('%s.xcodeproj' % appname) + node.mkdir() + node = node.make_node('project.pbxproj') + with open(node.abspath(), 'w') as f: + p.write(f) + Logs.pprint('GREEN', 'Wrote %r' % node.abspath()) + +def bind_fun(tgtype): + def fun(self, *k, **kw): + tgtype = fun.__name__ + if tgtype == 'shlib' or tgtype == 'dylib': + features = 'cxx cxxshlib' + tgtype = 'dylib' + elif tgtype == 'framework': + features = 'cxx cxxshlib' + tgtype = 'framework' + elif tgtype == 'program': + features = 'cxx cxxprogram' + tgtype = 'exe' + elif tgtype == 'app': + features = 'cxx cxxprogram' + tgtype = 'app' + elif tgtype == 'stlib': + features = 'cxx cxxstlib' + tgtype = 'stlib' + lst = kw['features'] = Utils.to_list(kw.get('features', [])) + for x in features.split(): + if not x in kw['features']: + lst.append(x) + + kw['target_type'] = tgtype + return self(*k, **kw) + fun.__name__ = tgtype + setattr(Build.BuildContext, tgtype, fun) + return fun + +for xx in 'app framework dylib shlib stlib program'.split(): + bind_fun(xx) + diff --git a/ldb-2.0.8/third_party/waf/waflib/fixpy2.py b/ldb-2.0.8/third_party/waf/waflib/fixpy2.py new file mode 100644 index 0000000..24176e0 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/fixpy2.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2010-2018 (ita) + +from __future__ import with_statement + +import os + +all_modifs = {} + +def fixdir(dir): + """Call all substitution functions on Waf folders""" + for k in all_modifs: + for v in all_modifs[k]: + modif(os.path.join(dir, 'waflib'), k, v) + +def modif(dir, name, fun): + """Call a substitution function""" + if name == '*': + lst = [] + for y in '. Tools extras'.split(): + for x in os.listdir(os.path.join(dir, y)): + if x.endswith('.py'): + lst.append(y + os.sep + x) + for x in lst: + modif(dir, x, fun) + return + + filename = os.path.join(dir, name) + with open(filename, 'r') as f: + txt = f.read() + + txt = fun(txt) + + with open(filename, 'w') as f: + f.write(txt) + +def subst(*k): + """register a substitution function""" + def do_subst(fun): + for x in k: + try: + all_modifs[x].append(fun) + except KeyError: + all_modifs[x] = [fun] + return fun + return do_subst + +@subst('*') +def r1(code): + "utf-8 fixes for python < 2.6" + code = code.replace('as e:', ',e:') + code = code.replace(".decode(sys.stdout.encoding or'latin-1',errors='replace')", '') + return code.replace('.encode()', '') + +@subst('Runner.py') +def r4(code): + "generator syntax" + return code.replace('next(self.biter)', 'self.biter.next()') + +@subst('Context.py') +def r5(code): + return code.replace("('Execution failure: %s'%str(e),ex=e)", "('Execution failure: %s'%str(e),ex=e),None,sys.exc_info()[2]") + diff --git a/ldb-2.0.8/third_party/waf/waflib/processor.py b/ldb-2.0.8/third_party/waf/waflib/processor.py new file mode 100755 index 0000000..eff2e69 --- /dev/null +++ b/ldb-2.0.8/third_party/waf/waflib/processor.py @@ -0,0 +1,68 @@ +#! /usr/bin/env python +# encoding: utf-8 +# Thomas Nagy, 2016-2018 (ita) + +import os, sys, traceback, base64, signal +try: + import cPickle +except ImportError: + import pickle as cPickle + +try: + import subprocess32 as subprocess +except ImportError: + import subprocess + +try: + TimeoutExpired = subprocess.TimeoutExpired +except AttributeError: + class TimeoutExpired(Exception): + pass + +def run(): + txt = sys.stdin.readline().strip() + if not txt: + # parent process probably ended + sys.exit(1) + [cmd, kwargs, cargs] = cPickle.loads(base64.b64decode(txt)) + cargs = cargs or {} + + if not 'close_fds' in kwargs: + # workers have no fds + kwargs['close_fds'] = False + + ret = 1 + out, err, ex, trace = (None, None, None, None) + try: + proc = subprocess.Popen(cmd, **kwargs) + try: + out, err = proc.communicate(**cargs) + except TimeoutExpired: + if kwargs.get('start_new_session') and hasattr(os, 'killpg'): + os.killpg(proc.pid, signal.SIGKILL) + else: + proc.kill() + out, err = proc.communicate() + exc = TimeoutExpired(proc.args, timeout=cargs['timeout'], output=out) + exc.stderr = err + raise exc + ret = proc.returncode + except Exception as e: + exc_type, exc_value, tb = sys.exc_info() + exc_lines = traceback.format_exception(exc_type, exc_value, tb) + trace = str(cmd) + '\n' + ''.join(exc_lines) + ex = e.__class__.__name__ + + # it is just text so maybe we do not need to pickle() + tmp = [ret, out, err, ex, trace] + obj = base64.b64encode(cPickle.dumps(tmp)) + sys.stdout.write(obj.decode()) + sys.stdout.write('\n') + sys.stdout.flush() + +while 1: + try: + run() + except KeyboardInterrupt: + break + diff --git a/ldb-2.0.8/tools/cmdline.c b/ldb-2.0.8/tools/cmdline.c new file mode 100644 index 0000000..a2fe97e --- /dev/null +++ b/ldb-2.0.8/tools/cmdline.c @@ -0,0 +1,521 @@ +/* + ldb database library - command line handling for ldb tools + + Copyright (C) Andrew Tridgell 2005 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb.h" +#include "ldb_module.h" +#include "tools/cmdline.h" + +static struct ldb_cmdline options; /* needs to be static for older compilers */ + +enum ldb_cmdline_options { CMDLINE_RELAX=1 }; + +static struct poptOption builtin_popt_options[] = { + POPT_AUTOHELP + { "url", 'H', POPT_ARG_STRING, &options.url, 0, "database URL", "URL" }, + { "basedn", 'b', POPT_ARG_STRING, &options.basedn, 0, "base DN", "DN" }, + { "editor", 'e', POPT_ARG_STRING, &options.editor, 0, "external editor", "PROGRAM" }, + { "scope", 's', POPT_ARG_STRING, NULL, 's', "search scope", "SCOPE" }, + { "verbose", 'v', POPT_ARG_NONE, NULL, 'v', "increase verbosity", NULL }, + { "trace", 0, POPT_ARG_NONE, &options.tracing, 0, "enable tracing", NULL }, + { "interactive", 'i', POPT_ARG_NONE, &options.interactive, 0, "input from stdin", NULL }, + { "recursive", 'r', POPT_ARG_NONE, &options.recursive, 0, "recursive delete", NULL }, + { "modules-path", 0, POPT_ARG_STRING, &options.modules_path, 0, "modules path", "PATH" }, + { "num-searches", 0, POPT_ARG_INT, &options.num_searches, 0, "number of test searches", NULL }, + { "num-records", 0, POPT_ARG_INT, &options.num_records, 0, "number of test records", NULL }, + { "all", 'a', POPT_ARG_NONE, &options.all_records, 0, "(|(objectClass=*)(distinguishedName=*))", NULL }, + { "nosync", 0, POPT_ARG_NONE, &options.nosync, 0, "non-synchronous transactions", NULL }, + { "sorted", 'S', POPT_ARG_NONE, &options.sorted, 0, "sort attributes", NULL }, + { NULL, 'o', POPT_ARG_STRING, NULL, 'o', "ldb_connect option", "OPTION" }, + { "controls", 0, POPT_ARG_STRING, NULL, 'c', "controls", NULL }, + { "show-binary", 0, POPT_ARG_NONE, &options.show_binary, 0, "display binary LDIF", NULL }, + { "paged", 0, POPT_ARG_NONE, NULL, 'P', "use a paged search", NULL }, + { "show-deleted", 0, POPT_ARG_NONE, NULL, 'D', "show deleted objects", NULL }, + { "show-recycled", 0, POPT_ARG_NONE, NULL, 'R', "show recycled objects", NULL }, + { "show-deactivated-link", 0, POPT_ARG_NONE, NULL, 'd', "show deactivated links", NULL }, + { "reveal", 0, POPT_ARG_NONE, NULL, 'r', "reveal ldb internals", NULL }, + { "relax", 0, POPT_ARG_NONE, NULL, CMDLINE_RELAX, "pass relax control", NULL }, + { "cross-ncs", 0, POPT_ARG_NONE, NULL, 'N', "search across NC boundaries", NULL }, + { "extended-dn", 0, POPT_ARG_NONE, NULL, 'E', "show extended DNs", NULL }, + { NULL } +}; + +void ldb_cmdline_help(struct ldb_context *ldb, const char *cmdname, FILE *f) +{ + poptContext pc; + struct poptOption **popt_options = ldb_module_popt_options(ldb); + pc = poptGetContext(cmdname, 0, NULL, *popt_options, + POPT_CONTEXT_KEEP_FIRST); + poptPrintHelp(pc, f, 0); +} + +/* + add a control to the options structure + */ +static bool add_control(TALLOC_CTX *mem_ctx, const char *control) +{ + unsigned int i; + + /* count how many controls we already have */ + for (i=0; options.controls && options.controls[i]; i++) ; + + options.controls = talloc_realloc(mem_ctx, options.controls, const char *, i + 2); + if (options.controls == NULL) { + return false; + } + options.controls[i] = control; + options.controls[i+1] = NULL; + return true; +} + +/** + process command line options +*/ +static struct ldb_cmdline *ldb_cmdline_process_internal(struct ldb_context *ldb, + int argc, const char **argv, + void (*usage)(struct ldb_context *), + bool search) +{ + struct ldb_cmdline *ret=NULL; + poptContext pc; + int num_options = 0; + int opt; + unsigned int flags = 0; + int rc; + struct poptOption **popt_options; + + /* make the ldb utilities line buffered */ + setlinebuf(stdout); + + ret = talloc_zero(ldb, struct ldb_cmdline); + if (ret == NULL) { + fprintf(stderr, "Out of memory!\n"); + goto failed; + } + + options = *ret; + + /* pull in URL */ + options.url = getenv("LDB_URL"); + + /* and editor (used by ldbedit) */ + options.editor = getenv("VISUAL"); + if (!options.editor) { + options.editor = getenv("EDITOR"); + } + if (!options.editor) { + options.editor = "vi"; + } + + options.scope = LDB_SCOPE_DEFAULT; + + popt_options = ldb_module_popt_options(ldb); + (*popt_options) = builtin_popt_options; + + rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_OPTIONS); + if (rc != LDB_SUCCESS) { + fprintf(stderr, "ldb: failed to run command line hooks : %s\n", ldb_strerror(rc)); + goto failed; + } + + pc = poptGetContext(argv[0], argc, argv, *popt_options, + POPT_CONTEXT_KEEP_FIRST); + + while((opt = poptGetNextOpt(pc)) != -1) { + switch (opt) { + case 's': { + const char *arg = poptGetOptArg(pc); + if (strcmp(arg, "base") == 0) { + options.scope = LDB_SCOPE_BASE; + } else if (strcmp(arg, "sub") == 0) { + options.scope = LDB_SCOPE_SUBTREE; + } else if (strcmp(arg, "one") == 0) { + options.scope = LDB_SCOPE_ONELEVEL; + } else { + fprintf(stderr, "Invalid scope '%s'\n", arg); + goto failed; + } + break; + } + + case 'v': + options.verbose++; + break; + + case 'o': + options.options = talloc_realloc(ret, options.options, + const char *, num_options+3); + if (options.options == NULL) { + fprintf(stderr, "Out of memory!\n"); + goto failed; + } + options.options[num_options] = poptGetOptArg(pc); + options.options[num_options+1] = NULL; + num_options++; + break; + + case 'c': { + const char *cs = poptGetOptArg(pc); + const char *p; + + for (p = cs; p != NULL; ) { + const char *t, *c; + + t = strchr(p, ','); + if (t == NULL) { + c = talloc_strdup(options.controls, p); + p = NULL; + } else { + c = talloc_strndup(options.controls, p, t-p); + p = t + 1; + } + if (c == NULL || !add_control(ret, c)) { + fprintf(stderr, __location__ ": out of memory\n"); + goto failed; + } + } + + break; + } + case 'P': + if (!add_control(ret, "paged_results:1:1024")) { + fprintf(stderr, __location__ ": out of memory\n"); + goto failed; + } + break; + case 'D': + if (!add_control(ret, "show_deleted:1")) { + fprintf(stderr, __location__ ": out of memory\n"); + goto failed; + } + break; + case 'R': + if (!add_control(ret, "show_recycled:0")) { + fprintf(stderr, __location__ ": out of memory\n"); + goto failed; + } + break; + case 'd': + if (!add_control(ret, "show_deactivated_link:0")) { + fprintf(stderr, __location__ ": out of memory\n"); + goto failed; + } + break; + case 'r': + if (!add_control(ret, "reveal_internals:0")) { + fprintf(stderr, __location__ ": out of memory\n"); + goto failed; + } + break; + case CMDLINE_RELAX: + if (!add_control(ret, "relax:0")) { + fprintf(stderr, __location__ ": out of memory\n"); + goto failed; + } + break; + case 'N': + if (!add_control(ret, "search_options:1:2")) { + fprintf(stderr, __location__ ": out of memory\n"); + goto failed; + } + break; + case 'E': + if (!add_control(ret, "extended_dn:1:1")) { + fprintf(stderr, __location__ ": out of memory\n"); + goto failed; + } + break; + default: + fprintf(stderr, "Invalid option %s: %s\n", + poptBadOption(pc, 0), poptStrerror(opt)); + if (usage) usage(ldb); + goto failed; + } + } + + /* setup the remaining options for the main program to use */ + options.argv = poptGetArgs(pc); + if (options.argv) { + options.argv++; + while (options.argv[options.argc]) options.argc++; + } + + *ret = options; + + /* all utils need some option */ + if (ret->url == NULL) { + fprintf(stderr, "You must supply a url with -H or with $LDB_URL\n"); + if (usage) usage(ldb); + goto failed; + } + + if (strcmp(ret->url, "NONE") == 0) { + return ret; + } + + if (options.nosync) { + flags |= LDB_FLG_NOSYNC; + } + + if (search) { + flags |= LDB_FLG_DONT_CREATE_DB; + + if (options.show_binary) { + flags |= LDB_FLG_SHOW_BINARY; + } + } + + if (options.tracing) { + flags |= LDB_FLG_ENABLE_TRACING; + } + + if (options.modules_path != NULL) { + ldb_set_modules_dir(ldb, options.modules_path); + } + + rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_PRECONNECT); + if (rc != LDB_SUCCESS) { + fprintf(stderr, "ldb: failed to run preconnect hooks : %s\n", ldb_strerror(rc)); + goto failed; + } + + /* now connect to the ldb */ + if (ldb_connect(ldb, ret->url, flags, ret->options) != LDB_SUCCESS) { + fprintf(stderr, "Failed to connect to %s - %s\n", + ret->url, ldb_errstring(ldb)); + goto failed; + } + + rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_POSTCONNECT); + if (rc != LDB_SUCCESS) { + fprintf(stderr, "ldb: failed to run post connect hooks : %s\n", ldb_strerror(rc)); + goto failed; + } + + return ret; + +failed: + talloc_free(ret); + exit(LDB_ERR_OPERATIONS_ERROR); + return NULL; +} + +struct ldb_cmdline *ldb_cmdline_process_search(struct ldb_context *ldb, + int argc, const char **argv, + void (*usage)(struct ldb_context *)) +{ + return ldb_cmdline_process_internal(ldb, argc, argv, usage, true); +} + +struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, + int argc, const char **argv, + void (*usage)(struct ldb_context *)) +{ + return ldb_cmdline_process_internal(ldb, argc, argv, usage, false); +} + +/* this function check controls reply and determines if more + * processing is needed setting up the request controls correctly + * + * returns: + * -1 error + * 0 all ok + * 1 all ok, more processing required + */ +int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request) +{ + unsigned int i, j; + int ret = 0; + + if (reply == NULL || request == NULL) return -1; + + for (i = 0; reply[i]; i++) { + if (strcmp(LDB_CONTROL_VLV_RESP_OID, reply[i]->oid) == 0) { + struct ldb_vlv_resp_control *rep_control; + + rep_control = talloc_get_type(reply[i]->data, struct ldb_vlv_resp_control); + + /* check we have a matching control in the request */ + for (j = 0; request[j]; j++) { + if (strcmp(LDB_CONTROL_VLV_REQ_OID, request[j]->oid) == 0) + break; + } + if (! request[j]) { + fprintf(stderr, "Warning VLV reply received but no request have been made\n"); + continue; + } + + /* check the result */ + if (rep_control->vlv_result != 0) { + fprintf(stderr, "Warning: VLV not performed with error: %d\n", rep_control->vlv_result); + } else { + fprintf(stderr, "VLV Info: target position = %d, content count = %d\n", rep_control->targetPosition, rep_control->contentCount); + } + + continue; + } + + if (strcmp(LDB_CONTROL_ASQ_OID, reply[i]->oid) == 0) { + struct ldb_asq_control *rep_control; + + rep_control = talloc_get_type(reply[i]->data, struct ldb_asq_control); + + /* check the result */ + if (rep_control->result != 0) { + fprintf(stderr, "Warning: ASQ not performed with error: %d\n", rep_control->result); + } + + continue; + } + + if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, reply[i]->oid) == 0) { + struct ldb_paged_control *rep_control, *req_control; + + rep_control = talloc_get_type(reply[i]->data, struct ldb_paged_control); + if (rep_control->cookie_len == 0) /* we are done */ + break; + + /* more processing required */ + /* let's fill in the request control with the new cookie */ + + for (j = 0; request[j]; j++) { + if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, request[j]->oid) == 0) + break; + } + /* if there's a reply control we must find a request + * control matching it */ + if (! request[j]) return -1; + + req_control = talloc_get_type(request[j]->data, struct ldb_paged_control); + + if (req_control->cookie) + talloc_free(req_control->cookie); + req_control->cookie = (char *)talloc_memdup( + req_control, rep_control->cookie, + rep_control->cookie_len); + req_control->cookie_len = rep_control->cookie_len; + + ret = 1; + + continue; + } + + if (strcmp(LDB_CONTROL_SORT_RESP_OID, reply[i]->oid) == 0) { + struct ldb_sort_resp_control *rep_control; + + rep_control = talloc_get_type(reply[i]->data, struct ldb_sort_resp_control); + + /* check we have a matching control in the request */ + for (j = 0; request[j]; j++) { + if (strcmp(LDB_CONTROL_SERVER_SORT_OID, request[j]->oid) == 0) + break; + } + if (! request[j]) { + fprintf(stderr, "Warning Server Sort reply received but no request found\n"); + continue; + } + + /* check the result */ + if (rep_control->result != 0) { + fprintf(stderr, "Warning: Sorting not performed with error: %d\n", rep_control->result); + } + + continue; + } + + if (strcmp(LDB_CONTROL_DIRSYNC_OID, reply[i]->oid) == 0) { + struct ldb_dirsync_control *rep_control, *req_control; + char *cookie; + + rep_control = talloc_get_type(reply[i]->data, struct ldb_dirsync_control); + if (rep_control->cookie_len == 0) /* we are done */ + break; + + /* more processing required */ + /* let's fill in the request control with the new cookie */ + + for (j = 0; request[j]; j++) { + if (strcmp(LDB_CONTROL_DIRSYNC_OID, request[j]->oid) == 0) + break; + } + /* if there's a reply control we must find a request + * control matching it */ + if (! request[j]) return -1; + + req_control = talloc_get_type(request[j]->data, struct ldb_dirsync_control); + + if (req_control->cookie) + talloc_free(req_control->cookie); + req_control->cookie = (char *)talloc_memdup( + req_control, rep_control->cookie, + rep_control->cookie_len); + req_control->cookie_len = rep_control->cookie_len; + + cookie = ldb_base64_encode(req_control, rep_control->cookie, rep_control->cookie_len); + printf("# DIRSYNC cookie returned was:\n# %s\n", cookie); + + continue; + } + if (strcmp(LDB_CONTROL_DIRSYNC_EX_OID, reply[i]->oid) == 0) { + struct ldb_dirsync_control *rep_control, *req_control; + char *cookie; + + rep_control = talloc_get_type(reply[i]->data, struct ldb_dirsync_control); + if (rep_control->cookie_len == 0) /* we are done */ + break; + + /* more processing required */ + /* let's fill in the request control with the new cookie */ + + for (j = 0; request[j]; j++) { + if (strcmp(LDB_CONTROL_DIRSYNC_EX_OID, request[j]->oid) == 0) + break; + } + /* if there's a reply control we must find a request + * control matching it */ + if (! request[j]) return -1; + + req_control = talloc_get_type(request[j]->data, struct ldb_dirsync_control); + + if (req_control->cookie) + talloc_free(req_control->cookie); + req_control->cookie = (char *)talloc_memdup( + req_control, rep_control->cookie, + rep_control->cookie_len); + req_control->cookie_len = rep_control->cookie_len; + + cookie = ldb_base64_encode(req_control, rep_control->cookie, rep_control->cookie_len); + printf("# DIRSYNC_EX cookie returned was:\n# %s\n", cookie); + + continue; + } + + /* no controls matched, throw a warning */ + fprintf(stderr, "Unknown reply control oid: %s\n", reply[i]->oid); + } + + return ret; +} + diff --git a/ldb-2.0.8/tools/cmdline.h b/ldb-2.0.8/tools/cmdline.h new file mode 100644 index 0000000..9af0ea1 --- /dev/null +++ b/ldb-2.0.8/tools/cmdline.h @@ -0,0 +1,59 @@ +/* + ldb database library - command line handling for ldb tools + + Copyright (C) Andrew Tridgell 2005 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +#include + +struct ldb_cmdline { + const char *url; + enum ldb_scope scope; + const char *basedn; + const char *modules_path; + int interactive; + int sorted; + const char *editor; + int verbose; + int recursive; + int all_records; + int nosync; + const char **options; + int argc; + const char **argv; + int num_records; + int num_searches; + const char *sasl_mechanism; + const char **controls; + int show_binary; + int tracing; +}; + +struct ldb_cmdline *ldb_cmdline_process_search(struct ldb_context *ldb, + int argc, const char **argv, + void (*usage)(struct ldb_context *)); +struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, + const char **argv, + void (*usage)(struct ldb_context *)); + + +int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request); +void ldb_cmdline_help(struct ldb_context *ldb, const char *cmdname, FILE *f); + diff --git a/ldb-2.0.8/tools/ldbadd.c b/ldb-2.0.8/tools/ldbadd.c new file mode 100644 index 0000000..e6cea29 --- /dev/null +++ b/ldb-2.0.8/tools/ldbadd.c @@ -0,0 +1,186 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldbadd + * + * Description: utility to add records - modelled on ldapadd + * + * Author: Andrew Tridgell + */ + +#include "replace.h" +#include "ldb.h" +#include "tools/cmdline.h" +#include "ldbutil.h" +#include "include/ldb_private.h" + +static struct ldb_cmdline *options; + +static void usage(struct ldb_context *ldb) +{ + printf("Usage: ldbadd \n"); + printf("Adds records to a ldb, reading ldif the specified list of files\n\n"); + ldb_cmdline_help(ldb, "ldbadd", stdout); + exit(LDB_ERR_OPERATIONS_ERROR); +} + + +/* + add records from an opened file +*/ +static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) +{ + struct ldb_ldif *ldif; + int fun_ret = LDB_SUCCESS, ret; + struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); + struct ldif_read_file_state state = { + .f = f + }; + + if (options->controls != NULL && req_ctrls== NULL) { + printf("parsing controls failed: %s\n", ldb_errstring(ldb)); + return LDB_ERR_OPERATIONS_ERROR; + } + + fun_ret = ldb_transaction_start(ldb); + if (fun_ret != LDB_SUCCESS) { + fprintf(stderr, "ERR: (%s) on transaction start\n", + ldb_errstring(ldb)); + return fun_ret; + } + + while ((ldif = ldb_ldif_read_file_state(ldb, &state))) { + if (ldif->changetype != LDB_CHANGETYPE_ADD && + ldif->changetype != LDB_CHANGETYPE_NONE) { + fprintf(stderr, "Only CHANGETYPE_ADD records allowed\n"); + break; + } + + ret = ldb_msg_normalize(ldb, ldif, ldif->msg, &ldif->msg); + if (ret != LDB_SUCCESS) { + fprintf(stderr, + "ERR: Message canonicalize failed - %s\n", + ldb_strerror(ret)); + fun_ret = ret; + ldb_ldif_read_free(ldb, ldif); + continue; + } + + ret = ldb_add_ctrl(ldb, ldif->msg,req_ctrls); + if (ret != LDB_SUCCESS) { + fprintf(stderr, "ERR: %s : \"%s\" on DN %s at block before line %llu\n", + ldb_strerror(ret), ldb_errstring(ldb), + ldb_dn_get_linearized(ldif->msg->dn), + (unsigned long long)state.line_no); + fun_ret = ret; + } else { + (*count)++; + if (options->verbose) { + printf("Added %s\n", ldb_dn_get_linearized(ldif->msg->dn)); + } + } + ldb_ldif_read_free(ldb, ldif); + if (ret) { + break; + } + } + + if (fun_ret == LDB_SUCCESS && !feof(f)) { + fprintf(stderr, "Failed to parse ldif\n"); + fun_ret = LDB_ERR_OPERATIONS_ERROR; + } + + if (fun_ret == LDB_SUCCESS) { + fun_ret = ldb_transaction_commit(ldb); + if (fun_ret != LDB_SUCCESS) { + fprintf(stderr, "ERR: (%s) on transaction commit\n", + ldb_errstring(ldb)); + } + } else { + ldb_transaction_cancel(ldb); + } + + return fun_ret; +} + + + +int main(int argc, const char **argv) +{ + struct ldb_context *ldb; + unsigned int i, count = 0; + int ret = LDB_SUCCESS; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + + ldb = ldb_init(mem_ctx, NULL); + if (ldb == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + options = ldb_cmdline_process(ldb, argc, argv, usage); + + ret = ldb_transaction_start(ldb); + if (ret != LDB_SUCCESS) { + printf("Failed to start transaction: %s\n", ldb_errstring(ldb)); + return ret; + } + + if (options->argc == 0) { + ret = process_file(ldb, stdin, &count); + } else { + for (i=0;iargc;i++) { + const char *fname = options->argv[i]; + FILE *f; + f = fopen(fname, "r"); + if (!f) { + perror(fname); + return LDB_ERR_OPERATIONS_ERROR; + } + ret = process_file(ldb, f, &count); + fclose(f); + } + } + + if (count != 0) { + ret = ldb_transaction_commit(ldb); + if (ret != LDB_SUCCESS) { + printf("Failed to commit transaction: %s\n", ldb_errstring(ldb)); + return ret; + } + } else { + ldb_transaction_cancel(ldb); + } + + talloc_free(mem_ctx); + + if (ret) { + printf("Add failed after processing %u records\n", count); + } else { + printf("Added %u records successfully\n", count); + } + + return ret; +} diff --git a/ldb-2.0.8/tools/ldbdel.c b/ldb-2.0.8/tools/ldbdel.c new file mode 100644 index 0000000..8036d09 --- /dev/null +++ b/ldb-2.0.8/tools/ldbdel.c @@ -0,0 +1,135 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldbdel + * + * Description: utility to delete records - modelled on ldapdelete + * + * Author: Andrew Tridgell + */ + +#include "replace.h" +#include "ldb.h" +#include "tools/cmdline.h" +#include "ldbutil.h" + +static int dn_cmp(struct ldb_message **msg1, struct ldb_message **msg2) +{ + return ldb_dn_compare((*msg1)->dn, (*msg2)->dn); +} + +static int ldb_delete_recursive(struct ldb_context *ldb, struct ldb_dn *dn,struct ldb_control **req_ctrls) +{ + int ret; + unsigned int i, total=0; + const char *attrs[] = { NULL }; + struct ldb_result *res; + + ret = ldb_search(ldb, ldb, &res, dn, LDB_SCOPE_SUBTREE, attrs, "distinguishedName=*"); + if (ret != LDB_SUCCESS) return ret; + + /* sort the DNs, deepest first */ + TYPESAFE_QSORT(res->msgs, res->count, dn_cmp); + + for (i = 0; i < res->count; i++) { + if (ldb_delete_ctrl(ldb, res->msgs[i]->dn,req_ctrls) == LDB_SUCCESS) { + total++; + } else { + printf("Failed to delete '%s' - %s\n", + ldb_dn_get_linearized(res->msgs[i]->dn), + ldb_errstring(ldb)); + } + } + + talloc_free(res); + + if (total == 0) { + return LDB_ERR_OPERATIONS_ERROR; + } + printf("Deleted %u records\n", total); + return LDB_SUCCESS; +} + +static void usage(struct ldb_context *ldb) +{ + printf("Usage: ldbdel \n"); + printf("Deletes records from a ldb\n\n"); + ldb_cmdline_help(ldb, "ldbdel", stdout); + exit(LDB_ERR_OPERATIONS_ERROR); +} + +int main(int argc, const char **argv) +{ + struct ldb_control **req_ctrls; + struct ldb_cmdline *options; + struct ldb_context *ldb; + int ret = 0, i; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + + ldb = ldb_init(mem_ctx, NULL); + if (ldb == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + options = ldb_cmdline_process(ldb, argc, argv, usage); + + if (options->argc < 1) { + usage(ldb); + } + + req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); + if (options->controls != NULL && req_ctrls== NULL) { + printf("parsing controls failed: %s\n", ldb_errstring(ldb)); + return LDB_ERR_OPERATIONS_ERROR; + } + + for (i=0;iargc;i++) { + struct ldb_dn *dn; + + dn = ldb_dn_new(ldb, ldb, options->argv[i]); + if (dn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + if (options->recursive) { + ret = ldb_delete_recursive(ldb, dn,req_ctrls); + } else { + ret = ldb_delete_ctrl(ldb, dn,req_ctrls); + if (ret == LDB_SUCCESS) { + printf("Deleted 1 record\n"); + } + } + if (ret != LDB_SUCCESS) { + printf("delete of '%s' failed - (%s) %s\n", + ldb_dn_get_linearized(dn), + ldb_strerror(ret), + ldb_errstring(ldb)); + } + } + + talloc_free(mem_ctx); + + return ret; +} diff --git a/ldb-2.0.8/tools/ldbdump.c b/ldb-2.0.8/tools/ldbdump.c new file mode 100644 index 0000000..5cdb7d8 --- /dev/null +++ b/ldb-2.0.8/tools/ldbdump.c @@ -0,0 +1,383 @@ +/* + Unix SMB/CIFS implementation. + simple ldb tdb dump util + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Andrew Bartlett 2012 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "replace.h" +#include "system/locale.h" +#include "system/time.h" +#include "system/filesys.h" +#include "system/wait.h" +#include +#include +#include + +#ifdef HAVE_LMDB +#include +#endif /* ifdef HAVE_LMDB */ + + +static struct ldb_context *ldb; +bool show_index = false; +bool validate_contents = false; + +static void print_data(TDB_DATA d) +{ + unsigned char *p = (unsigned char *)d.dptr; + int len = d.dsize; + while (len--) { + if (isprint(*p) && !strchr("\"\\", *p)) { + fputc(*p, stdout); + } else { + printf("\\%02X", *p); + } + p++; + } +} + +static unsigned int pull_uint32(uint8_t *p) +{ + return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24); +} + + +static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA _dbuf, void *state) +{ + int ret, i, j; + struct ldb_dn *dn = state; + struct ldb_message *msg = ldb_msg_new(NULL); + struct ldb_val dbuf = { + .data = _dbuf.dptr, + .length = _dbuf.dsize, + }; + struct ldb_ldif ldif = { + .msg = msg, + .changetype = LDB_CHANGETYPE_NONE + }; + if (!msg) { + return -1; + } + + ret = ldb_unpack_data(ldb, &dbuf, msg); + if (ret != 0) { + fprintf(stderr, "Failed to parse record %*.*s as an LDB record\n", (int)key.dsize, (int)key.dsize, (char *)key.dptr); + TALLOC_FREE(msg); + return 0; + } + + if (dn && ldb_dn_compare(msg->dn, dn) != 0) { + TALLOC_FREE(msg); + return 0; + } + + if (!show_index && ldb_dn_is_special(msg->dn)) { + const char *dn_lin = ldb_dn_get_linearized(msg->dn); + if ((strcmp(dn_lin, "@BASEINFO") == 0) || (strncmp(dn_lin, "@INDEX:", strlen("@INDEX:")) == 0)) { + /* + the user has asked not to show index + records. Also exclude BASEINFO as it + contains meta-data which will be re-created + if this database is restored + */ + TALLOC_FREE(msg); + return 0; + } + } + + printf("# key: "); + print_data(key); + printf("\n# pack format: %#010x\n", pull_uint32(_dbuf.dptr)); + + if (!validate_contents || ldb_dn_is_special(msg->dn)) { + ldb_ldif_write_file(ldb, stdout, &ldif); + TALLOC_FREE(msg); + return 0; + } + + for (i=0;inum_elements;i++) { + const struct ldb_schema_attribute *a; + + a = ldb_schema_attribute_by_name(ldb, msg->elements[i].name); + for (j=0;jelements[i].num_values;j++) { + struct ldb_val v; + ret = a->syntax->ldif_write_fn(ldb, msg, &msg->elements[i].values[j], &v); + if (ret != 0) { + v = msg->elements[i].values[j]; + if (ldb_should_b64_encode(ldb, &v)) { + v.data = (uint8_t *)ldb_base64_encode(ldb, (char *)v.data, v.length); + v.length = strlen((char *)v.data); + } + fprintf(stderr, "On %s element %s value %d (%*.*s) failed to convert to LDIF correctly, skipping possibly corrupt record\n", + ldb_dn_get_linearized(msg->dn), + msg->elements[i].name, + j, (int)v.length, (int)v.length, + v.data); + TALLOC_FREE(msg); + return 0; + } + } + } + ldb_ldif_write_file(ldb, stdout, &ldif); + TALLOC_FREE(msg); + + return 0; +} + +static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level, + const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); + +static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level, + const char *fmt, ...) +{ + va_list ap; + const char *name = tdb_name(tdb); + const char *prefix = ""; + + if (!name) + name = "unnamed"; + + switch (level) { + case TDB_DEBUG_ERROR: + prefix = "ERROR: "; + break; + case TDB_DEBUG_WARNING: + prefix = "WARNING: "; + break; + case TDB_DEBUG_TRACE: + return; + + default: + case TDB_DEBUG_FATAL: + prefix = "FATAL: "; + break; + } + + va_start(ap, fmt); + fprintf(stderr, "tdb(%s): %s", name, prefix); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + +static void emergency_walk(TDB_DATA key, TDB_DATA dbuf, void *keyname) +{ + traverse_fn(NULL, key, dbuf, keyname); +} + +static int dump_tdb(const char *fname, struct ldb_dn *dn, bool emergency) +{ + TDB_CONTEXT *tdb; + struct tdb_logging_context logfn = { + .log_fn = log_stderr, + }; + + tdb = tdb_open_ex(fname, 0, 0, O_RDONLY, 0, &logfn, NULL); + if (!tdb) { + fprintf(stderr, "Failed to open %s\n", fname); + return 1; + } + + if (emergency) { + return tdb_rescue(tdb, emergency_walk, dn) == 0; + } + return tdb_traverse(tdb, traverse_fn, dn) == -1 ? 1 : 0; +} + +#ifdef HAVE_LMDB +static int dump_lmdb(const char *fname, struct ldb_dn *dn, bool emergency) +{ + int ret; + struct MDB_env *env = NULL; + struct MDB_txn *txn = NULL; + MDB_dbi dbi; + struct MDB_cursor *cursor = NULL; + struct MDB_val key; + struct MDB_val data; + + ret = mdb_env_create(&env); + if (ret != 0) { + fprintf(stderr, + "Could not create MDB environment: (%d) %s\n", + ret, + mdb_strerror(ret)); + goto close_env; + } + + ret = mdb_env_open(env, + fname, + MDB_NOSUBDIR|MDB_NOTLS|MDB_RDONLY, + 0600); + if (ret != 0) { + fprintf(stderr, + "Could not open environment for %s: (%d) %s\n", + fname, + ret, + mdb_strerror(ret)); + goto close_env; + } + + ret = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn); + if (ret != 0) { + fprintf(stderr, + "Could not start transaction: (%d) %s\n", + ret, + mdb_strerror(ret)); + goto close_env; + } + + ret = mdb_dbi_open(txn, NULL, 0, &dbi); + if (ret != 0) { + fprintf(stderr, + "Could not open database: (%d) %s\n", + ret, + mdb_strerror(ret)); + goto close_txn; + } + + ret = mdb_cursor_open(txn, dbi, &cursor); + if (ret != 0) { + fprintf(stderr, + "Could not open cursor: (%d) %s\n", + ret, + mdb_strerror(ret)); + goto close_txn; + } + + ret = mdb_cursor_get(cursor, &key, &data, MDB_FIRST); + if (ret != 0 && ret != MDB_NOTFOUND) { + fprintf(stderr, + "Could not find first record: (%d) %s\n", + ret, + mdb_strerror(ret)); + goto close_cursor; + } + while (ret != MDB_NOTFOUND) { + struct TDB_DATA tkey = { + .dptr = key.mv_data, + .dsize = key.mv_size + }; + struct TDB_DATA tdata = { + .dptr = data.mv_data, + .dsize = data.mv_size + }; + traverse_fn(NULL, tkey, tdata, dn); + ret = mdb_cursor_get(cursor, &key, &data, MDB_NEXT); + if (ret != 0 && ret != MDB_NOTFOUND) { + fprintf(stderr, + "Could not read next record: (%d) %s\n", + ret, + mdb_strerror(ret)); + goto close_cursor; + } + } + ret = 0; + +close_cursor: + mdb_cursor_close(cursor); +close_txn: + mdb_txn_commit(txn); +close_env: + mdb_env_close(env); + + if (ret != 0) { + return 1; + } + return 0; + +} +#else +static int dump_lmdb(const char *fname, struct ldb_dn *dn, bool emergency) +{ + /* not built with lmdb support */ + return 1; +} +#endif /* #ifdef HAVE_LMDB */ + +static void usage( void) +{ + printf( "Usage: ldbdump [options] \n\n"); + printf( " -h this help message\n"); + printf( " -d DN dumps DN only\n"); + printf( " -e emergency dump, for corrupt databases\n"); + printf( " -i include index and @BASEINFO records in dump\n"); + printf( " -c validate contents of the records\n"); +} + + int main(int argc, char *argv[]) +{ + bool emergency = false; + int c, rc; + char *fname; + struct ldb_dn *dn = NULL; + + ldb = ldb_init(NULL, NULL); + if (ldb == NULL) { + fprintf(stderr, "ldb: ldb_init failed()"); + exit(1); + } + + rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_PRECONNECT); + if (rc != LDB_SUCCESS) { + fprintf(stderr, "ldb: failed to run preconnect hooks (needed to get Samba LDIF handlers): %s\n", ldb_strerror(rc)); + exit(1); + } + + if (argc < 2) { + printf("Usage: ldbdump \n"); + exit(1); + } + + while ((c = getopt( argc, argv, "hd:eic")) != -1) { + switch (c) { + case 'h': + usage(); + exit( 0); + case 'd': + dn = ldb_dn_new(ldb, ldb, optarg); + if (!dn) { + fprintf(stderr, "ldb failed to parse %s as a DN\n", optarg); + exit(1); + } + break; + case 'e': + emergency = true; + break; + case 'i': + show_index = true; + break; + case 'c': + validate_contents = true; + break; + default: + usage(); + exit( 1); + } + } + + fname = argv[optind]; + + rc = dump_lmdb(fname, dn, emergency); + if (rc != 0) { + rc = dump_tdb(fname, dn, emergency); + if (rc != 0) { + fprintf(stderr, "Failed to open %s\n", fname); + return 1; + } + } + return 0; + +} diff --git a/ldb-2.0.8/tools/ldbedit.c b/ldb-2.0.8/tools/ldbedit.c new file mode 100644 index 0000000..5b83783 --- /dev/null +++ b/ldb-2.0.8/tools/ldbedit.c @@ -0,0 +1,383 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldbedit + * + * Description: utility for ldb database editing + * + * Author: Andrew Tridgell + */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "system/filesys.h" +#include "ldb.h" +#include "tools/cmdline.h" +#include "tools/ldbutil.h" + +static struct ldb_cmdline *options; + +/* + debug routine +*/ +static void ldif_write_msg(struct ldb_context *ldb, + FILE *f, + enum ldb_changetype changetype, + struct ldb_message *msg) +{ + struct ldb_ldif ldif; + ldif.changetype = changetype; + ldif.msg = msg; + ldb_ldif_write_file(ldb, f, &ldif); +} + +/* + modify a database record so msg1 becomes msg2 + returns the number of modified elements +*/ +static int modify_record(struct ldb_context *ldb, + struct ldb_message *msg1, + struct ldb_message *msg2, + struct ldb_control **req_ctrls) +{ + int ret; + struct ldb_message *mod; + + if (ldb_msg_difference(ldb, ldb, msg1, msg2, &mod) != LDB_SUCCESS) { + fprintf(stderr, "Failed to calculate message differences\n"); + return -1; + } + + ret = mod->num_elements; + if (ret == 0) { + goto done; + } + + if (options->verbose > 0) { + ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_MODIFY, mod); + } + + if (ldb_modify_ctrl(ldb, mod, req_ctrls) != LDB_SUCCESS) { + fprintf(stderr, "failed to modify %s - %s\n", + ldb_dn_get_linearized(msg1->dn), ldb_errstring(ldb)); + ret = -1; + goto done; + } + +done: + talloc_free(mod); + return ret; +} + +/* + find dn in msgs[] +*/ +static struct ldb_message *msg_find(struct ldb_context *ldb, + struct ldb_message **msgs, + unsigned int count, + struct ldb_dn *dn) +{ + unsigned int i; + for (i=0;idn) == 0) { + return msgs[i]; + } + } + return NULL; +} + +/* + merge the changes in msgs2 into the messages from msgs1 +*/ +static int merge_edits(struct ldb_context *ldb, + struct ldb_message **msgs1, unsigned int count1, + struct ldb_message **msgs2, unsigned int count2) +{ + unsigned int i; + struct ldb_message *msg; + int ret; + unsigned int adds=0, modifies=0, deletes=0; + struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); + if (options->controls != NULL && req_ctrls == NULL) { + fprintf(stderr, "parsing controls failed: %s\n", ldb_errstring(ldb)); + return -1; + } + + if (ldb_transaction_start(ldb) != LDB_SUCCESS) { + fprintf(stderr, "Failed to start transaction: %s\n", ldb_errstring(ldb)); + return -1; + } + + /* do the adds and modifies */ + for (i=0;idn); + if (!msg) { + if (options->verbose > 0) { + ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_ADD, msgs2[i]); + } + if (ldb_add_ctrl(ldb, msgs2[i], req_ctrls) != LDB_SUCCESS) { + fprintf(stderr, "failed to add %s - %s\n", + ldb_dn_get_linearized(msgs2[i]->dn), + ldb_errstring(ldb)); + ldb_transaction_cancel(ldb); + return -1; + } + adds++; + } else { + ret = modify_record(ldb, msg, msgs2[i], req_ctrls); + if (ret != -1) { + modifies += (unsigned int) ret; + } else { + ldb_transaction_cancel(ldb); + return -1; + } + } + } + + /* do the deletes */ + for (i=0;idn); + if (!msg) { + if (options->verbose > 0) { + ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_DELETE, msgs1[i]); + } + if (ldb_delete_ctrl(ldb, msgs1[i]->dn, req_ctrls) != LDB_SUCCESS) { + fprintf(stderr, "failed to delete %s - %s\n", + ldb_dn_get_linearized(msgs1[i]->dn), + ldb_errstring(ldb)); + ldb_transaction_cancel(ldb); + return -1; + } + deletes++; + } + } + + if (ldb_transaction_commit(ldb) != LDB_SUCCESS) { + fprintf(stderr, "Failed to commit transaction: %s\n", ldb_errstring(ldb)); + return -1; + } + + printf("# %u adds %u modifies %u deletes\n", adds, modifies, deletes); + + return 0; +} + +/* + save a set of messages as ldif to a file +*/ +static int save_ldif(struct ldb_context *ldb, + FILE *f, struct ldb_message **msgs, unsigned int count) +{ + unsigned int i; + + fprintf(f, "# editing %u records\n", count); + + for (i=0;imsg; + } + + /* the feof() test works here, even for the last line of the + * file, as we parse ldif files character by character, and + * feof() is only true if we have failed to read a character + * from the file. So if the last line is bad, we don't get + * feof() set, so we know the record was bad. Only if we + * attempt to go to the next record will we get feof() and + * thus consider that the ldif has ended without errors + */ + if (!feof(f)) { + fprintf(stderr, "Error parsing ldif - aborting\n"); + fclose(f); + unlink(file_template); + return -1; + } + + fclose(f); + unlink(file_template); + + return merge_edits(ldb, msgs1, count1, msgs2, count2); +} + +static void usage(struct ldb_context *ldb) +{ + printf("Usage: ldbedit \n"); + ldb_cmdline_help(ldb, "ldbedit", stdout); + exit(LDB_ERR_OPERATIONS_ERROR); +} + +int main(int argc, const char **argv) +{ + struct ldb_context *ldb; + struct ldb_result *result = NULL; + struct ldb_dn *basedn = NULL; + int ret; + const char *expression = "(|(objectClass=*)(distinguishedName=*))"; + const char * const * attrs = NULL; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + struct ldb_control **req_ctrls; + unsigned int i; + + ldb = ldb_init(mem_ctx, NULL); + if (ldb == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + options = ldb_cmdline_process(ldb, argc, argv, usage); + + /* the check for '=' is for compatibility with ldapsearch */ + if (options->argc > 0 && + strchr(options->argv[0], '=')) { + expression = options->argv[0]; + options->argv++; + options->argc--; + } + + if (options->argc > 0) { + attrs = (const char * const *)(options->argv); + } + + if (options->basedn != NULL) { + basedn = ldb_dn_new(ldb, ldb, options->basedn); + if (basedn == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + } + + for (i = 0; options->controls != NULL && options->controls[i] != NULL; i++) { + if (strncmp(options->controls[i], "reveal_internals:", 17) == 0) { + printf("Using reveal internals has unintended consequences.\n"); + printf("If this is your intent, manually perform the search," + " and use ldbmodify directly.\n"); + return LDB_ERR_OPERATIONS_ERROR; + } + } + + req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); + if (options->controls != NULL && req_ctrls== NULL) { + printf("parsing controls failed: %s\n", ldb_errstring(ldb)); + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_search_ctrl(ldb, ldb, &result, basedn, options->scope, attrs, req_ctrls, "%s", expression); + if (ret != LDB_SUCCESS) { + printf("search failed - %s\n", ldb_errstring(ldb)); + return ret; + } + + if (result->count == 0) { + printf("no matching records - cannot edit\n"); + talloc_free(mem_ctx); + return LDB_SUCCESS; + } + + ret = do_edit(ldb, result->msgs, result->count, options->editor); + + talloc_free(mem_ctx); + + return ret == 0 ? LDB_SUCCESS : LDB_ERR_OPERATIONS_ERROR; +} diff --git a/ldb-2.0.8/tools/ldbmodify.c b/ldb-2.0.8/tools/ldbmodify.c new file mode 100644 index 0000000..9b4d7b7 --- /dev/null +++ b/ldb-2.0.8/tools/ldbmodify.c @@ -0,0 +1,184 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldbmodify + * + * Description: utility to modify records - modelled on ldapmodify + * + * Author: Andrew Tridgell + */ + +#include "replace.h" +#include "ldb.h" +#include "tools/cmdline.h" +#include "ldbutil.h" +#include "include/ldb_private.h" + +static struct ldb_cmdline *options; + +static void usage(struct ldb_context *ldb) +{ + printf("Usage: ldbmodify \n"); + printf("Modifies a ldb based upon ldif change records\n\n"); + ldb_cmdline_help(ldb, "ldbmodify", stdout); + exit(LDB_ERR_OPERATIONS_ERROR); +} + +/* + process modifies for one file +*/ +static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) +{ + struct ldb_ldif *ldif; + int fun_ret = LDB_SUCCESS, ret; + struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); + struct ldif_read_file_state state = { + .f = f + }; + + if (options->controls != NULL && req_ctrls== NULL) { + printf("parsing controls failed: %s\n", ldb_errstring(ldb)); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + fun_ret = ldb_transaction_start(ldb); + if (fun_ret != LDB_SUCCESS) { + fprintf(stderr, "ERR: (%s) on transaction start\n", + ldb_errstring(ldb)); + return fun_ret; + } + + while ((ldif = ldb_ldif_read_file_state(ldb, &state))) { + struct ldb_dn *olddn; + bool deleteoldrdn = false; + struct ldb_dn *newdn; + const char *errstr = NULL; + + switch (ldif->changetype) { + case LDB_CHANGETYPE_NONE: + case LDB_CHANGETYPE_ADD: + ret = ldb_add_ctrl(ldb, ldif->msg,req_ctrls); + break; + case LDB_CHANGETYPE_DELETE: + ret = ldb_delete_ctrl(ldb, ldif->msg->dn,req_ctrls); + break; + case LDB_CHANGETYPE_MODIFY: + ret = ldb_modify_ctrl(ldb, ldif->msg,req_ctrls); + break; + case LDB_CHANGETYPE_MODRDN: + ret = ldb_ldif_parse_modrdn(ldb, ldif, ldif, &olddn, + NULL, &deleteoldrdn, + NULL, &newdn); + if (ret == LDB_SUCCESS) { + if (deleteoldrdn) { + ret = ldb_rename(ldb, olddn, newdn); + } else { + errstr = "modrdn: deleteoldrdn=0 " + "not supported."; + ret = LDB_ERR_CONSTRAINT_VIOLATION; + } + } + break; + } + if (ret != LDB_SUCCESS) { + if (errstr == NULL) { + errstr = ldb_errstring(ldb); + } + fprintf(stderr, "ERR: (%s) \"%s\" on DN %s at block before line %llu\n", + ldb_strerror(ret), + errstr, ldb_dn_get_linearized(ldif->msg->dn), + (unsigned long long)state.line_no); + fun_ret = ret; + } else { + (*count)++; + if (options->verbose) { + printf("Modified %s\n", ldb_dn_get_linearized(ldif->msg->dn)); + } + } + ldb_ldif_read_free(ldb, ldif); + if (ret) { + break; + } + } + + if (fun_ret == LDB_SUCCESS && !feof(f)) { + fprintf(stderr, "Failed to parse ldif\n"); + fun_ret = LDB_ERR_OPERATIONS_ERROR; + } + + if (fun_ret == LDB_SUCCESS) { + fun_ret = ldb_transaction_commit(ldb); + if (fun_ret != LDB_SUCCESS) { + fprintf(stderr, "ERR: (%s) on transaction commit\n", + ldb_errstring(ldb)); + } + } else { + ldb_transaction_cancel(ldb); + } + + return fun_ret; +} + +int main(int argc, const char **argv) +{ + struct ldb_context *ldb; + unsigned int i, count = 0; + int ret = LDB_SUCCESS; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + + ldb = ldb_init(mem_ctx, NULL); + if (ldb == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + options = ldb_cmdline_process(ldb, argc, argv, usage); + + if (options->argc == 0) { + ret = process_file(ldb, stdin, &count); + } else { + for (i=0;iargc;i++) { + const char *fname = options->argv[i]; + FILE *f; + f = fopen(fname, "r"); + if (!f) { + perror(fname); + return LDB_ERR_OPERATIONS_ERROR; + } + ret = process_file(ldb, f, &count); + fclose(f); + } + } + + talloc_free(mem_ctx); + + if (ret) { + printf("Modify failed after processing %u records\n", count); + } else { + printf("Modified %u records successfully\n", count); + } + + return ret; +} diff --git a/ldb-2.0.8/tools/ldbrename.c b/ldb-2.0.8/tools/ldbrename.c new file mode 100644 index 0000000..ab2be4d --- /dev/null +++ b/ldb-2.0.8/tools/ldbrename.c @@ -0,0 +1,85 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Stefan Metzmacher 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldbrename + * + * Description: utility to rename records - modelled on ldapmodrdn + * + * Author: Andrew Tridgell + * Author: Stefan Metzmacher + */ + +#include "replace.h" +#include "ldb.h" +#include "tools/cmdline.h" + +static void usage(struct ldb_context *ldb) +{ + printf("Usage: ldbrename [] \n"); + printf("Renames records in a ldb\n\n"); + ldb_cmdline_help(ldb, "ldbmodify", stdout); + exit(LDB_ERR_OPERATIONS_ERROR); +} + + +int main(int argc, const char **argv) +{ + struct ldb_context *ldb; + int ret; + struct ldb_cmdline *options; + struct ldb_dn *dn1, *dn2; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + + ldb = ldb_init(mem_ctx, NULL); + if (ldb == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + options = ldb_cmdline_process(ldb, argc, argv, usage); + + if (options->argc < 2) { + usage(ldb); + } + + dn1 = ldb_dn_new(ldb, ldb, options->argv[0]); + dn2 = ldb_dn_new(ldb, ldb, options->argv[1]); + if ((dn1 == NULL) || (dn2 == NULL)) { + return LDB_ERR_OPERATIONS_ERROR; + } + + ret = ldb_rename(ldb, dn1, dn2); + if (ret == LDB_SUCCESS) { + printf("Renamed 1 record\n"); + } else { + printf("rename of '%s' to '%s' failed - %s\n", + options->argv[0], options->argv[1], ldb_errstring(ldb)); + } + + talloc_free(mem_ctx); + + return ret; +} diff --git a/ldb-2.0.8/tools/ldbsearch.c b/ldb-2.0.8/tools/ldbsearch.c new file mode 100644 index 0000000..374f240 --- /dev/null +++ b/ldb-2.0.8/tools/ldbsearch.c @@ -0,0 +1,342 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldbsearch + * + * Description: utility for ldb search - modelled on ldapsearch + * + * Author: Andrew Tridgell + */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb.h" +#include "tools/cmdline.h" + +static void usage(struct ldb_context *ldb) +{ + printf("Usage: ldbsearch \n"); + ldb_cmdline_help(ldb, "ldbsearch", stdout); + exit(LDB_ERR_OPERATIONS_ERROR); +} + +static int do_compare_msg(struct ldb_message **el1, + struct ldb_message **el2, + void *opaque) +{ + return ldb_dn_compare((*el1)->dn, (*el2)->dn); +} + +struct search_context { + struct ldb_context *ldb; + struct ldb_control **req_ctrls; + + int sort; + unsigned int num_stored; + struct ldb_message **store; + unsigned int refs_stored; + char **refs_store; + + unsigned int entries; + unsigned int refs; + + unsigned int pending; + int status; +}; + +static int store_message(struct ldb_message *msg, struct search_context *sctx) { + + sctx->store = talloc_realloc(sctx, sctx->store, struct ldb_message *, sctx->num_stored + 2); + if (!sctx->store) { + fprintf(stderr, "talloc_realloc failed while storing messages\n"); + return -1; + } + + sctx->store[sctx->num_stored] = talloc_move(sctx->store, &msg); + sctx->num_stored++; + sctx->store[sctx->num_stored] = NULL; + + return 0; +} + +static int store_referral(char *referral, struct search_context *sctx) { + + sctx->refs_store = talloc_realloc(sctx, sctx->refs_store, char *, sctx->refs_stored + 2); + if (!sctx->refs_store) { + fprintf(stderr, "talloc_realloc failed while storing referrals\n"); + return -1; + } + + sctx->refs_store[sctx->refs_stored] = talloc_move(sctx->refs_store, &referral); + sctx->refs_stored++; + sctx->refs_store[sctx->refs_stored] = NULL; + + return 0; +} + +static int display_message(struct ldb_message *msg, struct search_context *sctx) { + struct ldb_ldif ldif; + + sctx->entries++; + printf("# record %d\n", sctx->entries); + + ldif.changetype = LDB_CHANGETYPE_NONE; + ldif.msg = msg; + + if (sctx->sort) { + /* + * Ensure attributes are always returned in the same + * order. For testing, this makes comparison of old + * vs. new much easier. + */ + ldb_msg_sort_elements(ldif.msg); + } + + ldb_ldif_write_file(sctx->ldb, stdout, &ldif); + + return 0; +} + +static int display_referral(char *referral, struct search_context *sctx) +{ + + sctx->refs++; + printf("# Referral\nref: %s\n\n", referral); + + return 0; +} + +static int search_callback(struct ldb_request *req, struct ldb_reply *ares) +{ + struct search_context *sctx; + int ret = LDB_SUCCESS; + + sctx = talloc_get_type(req->context, struct search_context); + + if (!ares) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + if (ares->error != LDB_SUCCESS) { + return ldb_request_done(req, ares->error); + } + + switch (ares->type) { + case LDB_REPLY_ENTRY: + if (sctx->sort) { + ret = store_message(ares->message, sctx); + } else { + ret = display_message(ares->message, sctx); + } + break; + + case LDB_REPLY_REFERRAL: + if (sctx->sort) { + ret = store_referral(ares->referral, sctx); + } else { + ret = display_referral(ares->referral, sctx); + } + if (ret) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + break; + + case LDB_REPLY_DONE: + if (ares->controls) { + if (handle_controls_reply(ares->controls, sctx->req_ctrls) == 1) + sctx->pending = 1; + } + talloc_free(ares); + return ldb_request_done(req, LDB_SUCCESS); + } + + talloc_free(ares); + if (ret != LDB_SUCCESS) { + return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); + } + + return LDB_SUCCESS; +} + +static int do_search(struct ldb_context *ldb, + struct ldb_dn *basedn, + struct ldb_cmdline *options, + const char *expression, + const char * const *attrs) +{ + struct ldb_request *req; + struct search_context *sctx; + int ret; + + req = NULL; + + sctx = talloc_zero(ldb, struct search_context); + if (!sctx) return LDB_ERR_OPERATIONS_ERROR; + + sctx->ldb = ldb; + sctx->sort = options->sorted; + sctx->req_ctrls = ldb_parse_control_strings(ldb, sctx, (const char **)options->controls); + if (options->controls != NULL && sctx->req_ctrls== NULL) { + printf("parsing controls failed: %s\n", ldb_errstring(ldb)); + return LDB_ERR_OPERATIONS_ERROR; + } + +again: + /* free any previous requests */ + if (req) talloc_free(req); + + ret = ldb_build_search_req(&req, ldb, ldb, + basedn, options->scope, + expression, attrs, + sctx->req_ctrls, + sctx, search_callback, + NULL); + if (ret != LDB_SUCCESS) { + talloc_free(sctx); + printf("allocating request failed: %s\n", ldb_errstring(ldb)); + return ret; + } + + if (basedn == NULL) { + /* + we need to use a NULL base DN when doing a cross-ncs + search so we find results on all partitions in a + forest. When doing a domain-local search, default to + the default basedn + */ + struct ldb_control *ctrl; + struct ldb_search_options_control *search_options = NULL; + + ctrl = ldb_request_get_control(req, LDB_CONTROL_SEARCH_OPTIONS_OID); + if (ctrl) { + search_options = talloc_get_type(ctrl->data, struct ldb_search_options_control); + } + + if (ctrl == NULL || search_options == NULL || + !(search_options->search_options & LDB_SEARCH_OPTION_PHANTOM_ROOT)) { + struct ldb_dn *base = ldb_get_default_basedn(ldb); + if (base != NULL) { + req->op.search.base = base; + } + } + } + + sctx->pending = 0; + + ret = ldb_request(ldb, req); + if (ret != LDB_SUCCESS) { + talloc_free(sctx); + talloc_free(req); + printf("search failed - %s\n", ldb_errstring(ldb)); + return ret; + } + + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + if (ret != LDB_SUCCESS) { + talloc_free(sctx); + talloc_free(req); + printf("search error - %s\n", ldb_errstring(ldb)); + return ret; + } + + if (sctx->pending) + goto again; + + if (sctx->sort && (sctx->num_stored != 0 || sctx->refs != 0)) { + unsigned int i; + + if (sctx->num_stored) { + LDB_TYPESAFE_QSORT(sctx->store, sctx->num_stored, ldb, do_compare_msg); + } + for (i = 0; i < sctx->num_stored; i++) { + display_message(sctx->store[i], sctx); + } + + for (i = 0; i < sctx->refs_stored; i++) { + display_referral(sctx->refs_store[i], sctx); + } + } + + printf("# returned %u records\n# %u entries\n# %u referrals\n", + sctx->entries + sctx->refs, sctx->entries, sctx->refs); + + talloc_free(sctx); + talloc_free(req); + + return LDB_SUCCESS; +} + +int main(int argc, const char **argv) +{ + struct ldb_context *ldb; + struct ldb_dn *basedn = NULL; + const char * const * attrs = NULL; + struct ldb_cmdline *options; + int ret = -1; + const char *expression = "(|(objectClass=*)(distinguishedName=*))"; + TALLOC_CTX *mem_ctx = talloc_new(NULL); + + ldb = ldb_init(mem_ctx, NULL); + if (ldb == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + options = ldb_cmdline_process_search(ldb, argc, argv, usage); + + /* the check for '=' is for compatibility with ldapsearch */ + if (!options->interactive && + options->argc > 0 && + strpbrk(options->argv[0], "=<>~:")) { + expression = options->argv[0]; + options->argv++; + options->argc--; + } + + if (options->argc > 0) { + attrs = (const char * const *)(options->argv); + } + + if (options->basedn != NULL) { + basedn = ldb_dn_new(ldb, ldb, options->basedn); + if (basedn == NULL) { + talloc_free(mem_ctx); + return LDB_ERR_OPERATIONS_ERROR; + } + } + + if (options->interactive) { + char line[1024]; + while (fgets(line, sizeof(line), stdin)) { + ret = do_search(ldb, basedn, options, line, attrs); + } + } else { + ret = do_search(ldb, basedn, options, expression, attrs); + } + + talloc_free(mem_ctx); + + return ret; +} diff --git a/ldb-2.0.8/tools/ldbtest.c b/ldb-2.0.8/tools/ldbtest.c new file mode 100644 index 0000000..64b6baa --- /dev/null +++ b/ldb-2.0.8/tools/ldbtest.c @@ -0,0 +1,438 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Component: ldbtest + * + * Description: utility to test ldb + * + * Author: Andrew Tridgell + */ + +#include "replace.h" +#include "system/filesys.h" +#include "system/time.h" +#include "ldb.h" +#include "tools/cmdline.h" + +static struct timespec tp1,tp2; +static struct ldb_cmdline *options; + +static void _start_timer(void) +{ + if (clock_gettime(CUSTOM_CLOCK_MONOTONIC, &tp1) != 0) { + clock_gettime(CLOCK_REALTIME, &tp1); + } +} + +static double _end_timer(void) +{ + if (clock_gettime(CUSTOM_CLOCK_MONOTONIC, &tp2) != 0) { + clock_gettime(CLOCK_REALTIME, &tp2); + } + return((tp2.tv_sec - tp1.tv_sec) + + (tp2.tv_nsec - tp1.tv_nsec)*1.0e-9); +} + +static void add_records(struct ldb_context *ldb, + struct ldb_dn *basedn, + unsigned int count) +{ + struct ldb_message msg = {0}; + unsigned int i; + +#if 0 + if (ldb_lock(ldb, "transaction") != 0) { + printf("transaction lock failed\n"); + exit(LDB_ERR_OPERATIONS_ERROR); + } +#endif + for (i=0;icount != 1)) { + printf("Failed to find %s - %s\n", expr, ldb_errstring(ldb)); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + if (uid >= nrecords && res->count > 0) { + printf("Found %s !? - %d\n", expr, ret); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + printf("Testing uid %d/%d - %d \r", i, uid, res->count); + fflush(stdout); + + talloc_free(res); + talloc_free(expr); + } + + printf("\n"); +} + +static void start_test(struct ldb_context *ldb, unsigned int nrecords, + unsigned int nsearches) +{ + struct ldb_dn *basedn; + + basedn = ldb_dn_new(ldb, ldb, options->basedn); + if ( ! ldb_dn_validate(basedn)) { + printf("Invalid base DN format\n"); + exit(LDB_ERR_INVALID_DN_SYNTAX); + } + + printf("Adding %d records\n", nrecords); + add_records(ldb, basedn, nrecords); + + printf("Starting search on uid\n"); + _start_timer(); + search_uid(ldb, basedn, nrecords, nsearches); + printf("uid search took %.2f seconds\n", _end_timer()); + + printf("Modifying records\n"); + modify_records(ldb, basedn, nrecords); + + printf("Deleting records\n"); + delete_records(ldb, basedn, nrecords); +} + + +/* + 2) Store an @indexlist record + + 3) Store a record that contains fields that should be index according +to @index + + 4) disconnection from database + + 5) connect to same database + + 6) search for record added in step 3 using a search key that should +be indexed +*/ +static void start_test_index(struct ldb_context **ldb) +{ + struct ldb_message *msg; + struct ldb_result *res = NULL; + struct ldb_dn *indexlist; + struct ldb_dn *basedn; + int ret; + unsigned int flags = 0; + const char *specials; + + specials = getenv("LDB_SPECIALS"); + if (specials && atoi(specials) == 0) { + printf("LDB_SPECIALS disabled - skipping index test\n"); + return; + } + + if (options->nosync) { + flags |= LDB_FLG_NOSYNC; + } + + printf("Starting index test\n"); + + indexlist = ldb_dn_new(*ldb, *ldb, "@INDEXLIST"); + + ldb_delete(*ldb, indexlist); + + msg = ldb_msg_new(NULL); + if (msg == NULL) { + printf("ldb_msg_new failed\n"); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + msg->dn = indexlist; + ldb_msg_add_string(msg, "@IDXATTR", strdup("uid")); + + if (ldb_add(*ldb, msg) != 0) { + printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb)); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + basedn = ldb_dn_new(*ldb, *ldb, options->basedn); + + memset(msg, 0, sizeof(*msg)); + msg->dn = ldb_dn_copy(msg, basedn); + ldb_dn_add_child_fmt(msg->dn, "cn=test"); + ldb_msg_add_string(msg, "cn", strdup("test")); + ldb_msg_add_string(msg, "sn", strdup("test")); + ldb_msg_add_string(msg, "uid", strdup("test")); + ldb_msg_add_string(msg, "objectClass", strdup("OpenLDAPperson")); + + if (ldb_add(*ldb, msg) != LDB_SUCCESS) { + printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb)); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + if (talloc_free(*ldb) != 0) { + printf("failed to free/close ldb database"); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + (*ldb) = ldb_init(options, NULL); + + ret = ldb_connect(*ldb, options->url, flags, NULL); + if (ret != LDB_SUCCESS) { + printf("failed to connect to %s\n", options->url); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + basedn = ldb_dn_new(*ldb, *ldb, options->basedn); + msg->dn = basedn; + ldb_dn_add_child_fmt(msg->dn, "cn=test"); + + ret = ldb_search(*ldb, *ldb, &res, basedn, LDB_SCOPE_SUBTREE, NULL, "uid=test"); + if (ret != LDB_SUCCESS) { + printf("Search with (uid=test) filter failed!\n"); + exit(LDB_ERR_OPERATIONS_ERROR); + } + if(res->count != 1) { + printf("Should have found 1 record - found %d\n", res->count); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + indexlist = ldb_dn_new(*ldb, *ldb, "@INDEXLIST"); + + if (ldb_delete(*ldb, msg->dn) != 0 || + ldb_delete(*ldb, indexlist) != 0) { + printf("cleanup failed - %s\n", ldb_errstring(*ldb)); + exit(LDB_ERR_OPERATIONS_ERROR); + } + + printf("Finished index test\n"); +} + + +static void usage(struct ldb_context *ldb) +{ + printf("Usage: ldbtest \n"); + printf("Options:\n"); + printf(" -H ldb_url choose the database (or $LDB_URL)\n"); + printf(" --num-records nrecords database size to use\n"); + printf(" --num-searches nsearches number of searches to do\n"); + printf("\n"); + printf("tests ldb API\n\n"); + exit(LDB_ERR_OPERATIONS_ERROR); +} + +int main(int argc, const char **argv) +{ + TALLOC_CTX *mem_ctx = talloc_new(NULL); + struct ldb_context *ldb; + + ldb = ldb_init(mem_ctx, NULL); + if (ldb == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + options = ldb_cmdline_process(ldb, argc, argv, usage); + + talloc_steal(mem_ctx, options); + + if (options->basedn == NULL) { + options->basedn = "ou=Ldb Test,ou=People,o=University of Michigan,c=TEST"; + } + + srandom(1); + + printf("Testing with num-records=%d and num-searches=%d\n", + options->num_records, options->num_searches); + + start_test(ldb, + (unsigned int) options->num_records, + (unsigned int) options->num_searches); + + start_test_index(&ldb); + + talloc_free(mem_ctx); + + return LDB_SUCCESS; +} diff --git a/ldb-2.0.8/tools/ldbutil.c b/ldb-2.0.8/tools/ldbutil.c new file mode 100644 index 0000000..9ff7fad --- /dev/null +++ b/ldb-2.0.8/tools/ldbutil.c @@ -0,0 +1,220 @@ +/* + ldb database library utility + + Copyright (C) Matthieu Patou 2009 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Description: Common function used by ldb_add/ldb_modify/ldb_delete + * + * Author: Matthieu Patou + */ + +#include "replace.h" +#include "ldb.h" +#include "ldb_module.h" +#include "ldbutil.h" + + +/* autostarts a transacion if none active */ +static int ldb_do_autotransaction(struct ldb_context *ldb, + struct ldb_request *req) +{ + int ret; + + ret = ldb_transaction_start(ldb); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_request(ldb, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + if (ret == LDB_SUCCESS) { + return ldb_transaction_commit(ldb); + } + ldb_transaction_cancel(ldb); + + if (ldb_errstring(ldb) == NULL) { + /* no error string was setup by the backend */ + ldb_asprintf_errstring(ldb, "%s (%d)", ldb_strerror(ret), ret); + } + + return ret; +} +/* + Same as ldb_add but accept control +*/ +int ldb_add_ctrl(struct ldb_context *ldb, + const struct ldb_message *message, + struct ldb_control **controls) +{ + struct ldb_request *req; + int ret; + + ret = ldb_msg_sanity_check(ldb, message); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_build_add_req(&req, ldb, ldb, + message, + controls, + NULL, + ldb_op_default_callback, + NULL); + + if (ret != LDB_SUCCESS) return ret; + + /* do request and autostart a transaction */ + ret = ldb_do_autotransaction(ldb, req); + + talloc_free(req); + return ret; +} + +/* + same as ldb_delete but accept control +*/ +int ldb_delete_ctrl(struct ldb_context *ldb, struct ldb_dn *dn, + struct ldb_control **controls) +{ + struct ldb_request *req; + int ret; + + ret = ldb_build_del_req(&req, ldb, ldb, + dn, + controls, + NULL, + ldb_op_default_callback, + NULL); + + if (ret != LDB_SUCCESS) return ret; + + /* do request and autostart a transaction */ + ret = ldb_do_autotransaction(ldb, req); + + talloc_free(req); + return ret; +} + + +/* + same as ldb_modify, but accepts controls +*/ +int ldb_modify_ctrl(struct ldb_context *ldb, + const struct ldb_message *message, + struct ldb_control **controls) +{ + struct ldb_request *req; + int ret; + + ret = ldb_msg_sanity_check(ldb, message); + if (ret != LDB_SUCCESS) { + return ret; + } + + ret = ldb_build_mod_req(&req, ldb, ldb, + message, + controls, + NULL, + ldb_op_default_callback, + NULL); + + if (ret != LDB_SUCCESS) return ret; + + /* do request and autostart a transaction */ + ret = ldb_do_autotransaction(ldb, req); + + talloc_free(req); + return ret; +} + + +/* + ldb_search with controls +*/ +int ldb_search_ctrl(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + struct ldb_result **result, struct ldb_dn *base, + enum ldb_scope scope, const char * const *attrs, + struct ldb_control **controls, + const char *exp_fmt, ...) +{ + struct ldb_request *req; + struct ldb_result *res; + char *expression; + va_list ap; + int ret; + + expression = NULL; + *result = NULL; + req = NULL; + + res = talloc_zero(mem_ctx, struct ldb_result); + if (!res) { + return LDB_ERR_OPERATIONS_ERROR; + } + + if (exp_fmt) { + va_start(ap, exp_fmt); + expression = talloc_vasprintf(mem_ctx, exp_fmt, ap); + va_end(ap); + + if (!expression) { + talloc_free(res); + return LDB_ERR_OPERATIONS_ERROR; + } + } + + ret = ldb_build_search_req(&req, ldb, mem_ctx, + base?base:ldb_get_default_basedn(ldb), + scope, + expression, + attrs, + controls, + res, + ldb_search_default_callback, + NULL); + ldb_req_set_location(req, "ldb_search_ctrl"); + + if (ret != LDB_SUCCESS) goto done; + + ret = ldb_request(ldb, req); + + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + +done: + if (ret != LDB_SUCCESS) { + talloc_free(res); + res = NULL; + } + + talloc_free(expression); + talloc_free(req); + + *result = res; + return ret; +} diff --git a/ldb-2.0.8/tools/ldbutil.h b/ldb-2.0.8/tools/ldbutil.h new file mode 100644 index 0000000..6723863 --- /dev/null +++ b/ldb-2.0.8/tools/ldbutil.h @@ -0,0 +1,46 @@ +/* + ldb database library utility header file + + Copyright (C) Matthieu Patou 2009 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see . +*/ + +/* + * Name: ldb + * + * Description: Common function used by ldb_add/ldb_modify/ldb_delete + * + * Author: Matthieu Patou + */ + +#include "ldb.h" + +int ldb_add_ctrl(struct ldb_context *ldb, + const struct ldb_message *message, + struct ldb_control **controls); +int ldb_delete_ctrl(struct ldb_context *ldb, struct ldb_dn *dn, + struct ldb_control **controls); +int ldb_modify_ctrl(struct ldb_context *ldb, + const struct ldb_message *message, + struct ldb_control **controls); +int ldb_search_ctrl(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + struct ldb_result **result, struct ldb_dn *base, + enum ldb_scope scope, const char * const *attrs, + struct ldb_control **controls, + const char *exp_fmt, ...) PRINTF_ATTRIBUTE(8,9); diff --git a/ldb-2.0.8/web/index.html b/ldb-2.0.8/web/index.html new file mode 100644 index 0000000..7f50cdc --- /dev/null +++ b/ldb-2.0.8/web/index.html @@ -0,0 +1,74 @@ + + + +ldb + + + +

      ldb

      + +ldb is a LDAP-like embedded database. It is not at all +LDAP +standards compliant, so if you want a standards compliant database then please +see the excellent OpenLDAP +project.

      + +What ldb does is provide a fast database with an LDAP-like API +designed to be used within an application. In some ways it can be seen +as a intermediate solution between key-value pair databases and a real +LDAP database.

      + +ldb is the database engine used in Samba4. + +

      Features

      + +The main features that separate ldb from other solutions are: + +
        +
      • Safe multi-reader, multi-writer, using byte range locking +
      • LDAP-like API +
      • fast operation +
      • choice of local tdb or remote LDAP backends +
      • integration with talloc +
      • schema-less operation, for trivial setup +
      • modules for extensions (such as schema support) +
      • easy setup of indexes and attribute properties +
      • LDIF for import/export +
      • ldbedit tool for database (via LDIF) editing (reminiscent of 'vipw') +
      + +

      Documentation

      + +Currently ldb is completely lacking in programmer or user +documentation. This is your opportunity to make a contribution! Start +with the public functions declared in ldb.h +and the example code in the tools +directory. Documentation in the same docbook format used by Samba +would be preferred. + +

      Discussion and bug reports

      + +ldb does not have its own mailing list or bug tracking system. Please +use +the samba-technical +mailing list, and the Samba +bugzilla bug tracking system. + +

      Download

      + +You can download the latest release here:
      + http://samba.org/ftp/pub/ldb + +Alternatively, you can fetch via git. See the following guide:
      +Using Git for Samba Development
      + +
      + +Andrew Tridgell
      +ldb AT tridgell.net +
      + + + diff --git a/ldb-2.0.8/wscript b/ldb-2.0.8/wscript new file mode 100644 index 0000000..5b5c42d --- /dev/null +++ b/ldb-2.0.8/wscript @@ -0,0 +1,650 @@ +#!/usr/bin/env python + +APPNAME = 'ldb' +VERSION = '2.0.8' + +import sys, os + +# find the buildtools directory +top = '.' +while not os.path.exists(top+'/buildtools') and len(top.split('/')) < 5: + top = top + '/..' +sys.path.insert(0, top + '/buildtools/wafsamba') + +out = 'bin' + +import wafsamba +from wafsamba import samba_dist, samba_utils +from waflib import Errors, Options, Logs, Context +import shutil + +samba_dist.DIST_DIRS('''lib/ldb:. lib/replace:lib/replace lib/talloc:lib/talloc + lib/tdb:lib/tdb lib/tdb:lib/tdb lib/tevent:lib/tevent + third_party/popt:third_party/popt + third_party/cmocka:third_party/cmocka + buildtools:buildtools third_party/waf:third_party/waf''') + +samba_dist.DIST_FILES('''lib/util/binsearch.h:lib/util/binsearch.h + lib/util/attr.h:lib/util/attr.h''') + +def options(opt): + opt.BUILTIN_DEFAULT('replace') + opt.PRIVATE_EXTENSION_DEFAULT('ldb', noextension='ldb') + opt.RECURSE('lib/tdb') + opt.RECURSE('lib/tevent') + opt.RECURSE('lib/replace') + opt.load('python') # options for disabling pyc or pyo compilation + + opt.add_option('--without-ldb-lmdb', + help='disable new LMDB backend for LDB', + action='store_true', dest='without_ldb_lmdb', default=False) + + +def configure(conf): + conf.RECURSE('lib/tdb') + conf.RECURSE('lib/tevent') + + if conf.CHECK_FOR_THIRD_PARTY(): + conf.RECURSE('third_party/popt') + conf.RECURSE('third_party/cmocka') + else: + if not conf.CHECK_POPT(): + raise Errors.WafError('popt development packages have not been found.\nIf third_party is installed, check that it is in the proper place.') + else: + conf.define('USING_SYSTEM_POPT', 1) + + if not conf.CHECK_CMOCKA(): + raise Errors.WafError('cmocka development package have not been found.\nIf third_party is installed, check that it is in the proper place.') + else: + conf.define('USING_SYSTEM_CMOCKA', 1) + + conf.RECURSE('lib/replace') + conf.find_program('xsltproc', var='XSLTPROC') + conf.SAMBA_CHECK_PYTHON() + conf.SAMBA_CHECK_PYTHON_HEADERS() + + # where does the default LIBDIR end up? in conf.env somewhere? + # + conf.CONFIG_PATH('LDB_MODULESDIR', conf.SUBST_ENV_VAR('MODULESDIR') + '/ldb') + + conf.env.standalone_ldb = conf.IN_LAUNCH_DIR() + + if not conf.env.standalone_ldb: + max_ldb_version = [int(x) for x in VERSION.split(".")] + max_ldb_version[2] = 999 + max_ldb_version_dots = "%d.%d.%d" % tuple(max_ldb_version) + + if conf.env.disable_python: + if conf.CHECK_BUNDLED_SYSTEM_PKG('ldb', + minversion=VERSION, + maxversion=max_ldb_version_dots, + onlyif='talloc tdb tevent', + implied_deps='replace talloc tdb tevent'): + conf.define('USING_SYSTEM_LDB', 1) + else: + using_system_pyldb_util = True + dflt_name = 'pyldb-util' + conf.all_envs['default']['PYTHON_SO_ABI_FLAG'] + if not conf.CHECK_BUNDLED_SYSTEM_PKG(dflt_name, + minversion=VERSION, + maxversion=max_ldb_version_dots, + onlyif='talloc tdb tevent', + implied_deps='replace talloc tdb tevent ldb'): + using_system_pyldb_util = False + + if using_system_pyldb_util: + conf.define('USING_SYSTEM_PYLDB_UTIL', 1) + + if conf.CHECK_BUNDLED_SYSTEM_PKG('ldb', + minversion=VERSION, + maxversion=max_ldb_version_dots, + onlyif='talloc tdb tevent %s' % dflt_name, + implied_deps='replace talloc tdb tevent'): + conf.define('USING_SYSTEM_LDB', 1) + + if not conf.CHECK_CODE('return !(sizeof(size_t) >= 8)', + "HAVE_64_BIT_SIZE_T_FOR_LMDB", + execute=True, + msg='Checking for a 64-bit host to ' + 'support lmdb'): + Logs.warn("--without-ldb-lmdb implied as this " + "host is not 64-bit") + + if not conf.env.standalone_ldb and \ + not Options.options.without_ad_dc and \ + conf.CONFIG_GET('ENABLE_SELFTEST'): + Logs.warn("NOTE: Some AD DC parts of selftest will fail") + + conf.env.REQUIRE_LMDB = False + else: + if conf.env.standalone_ldb: + if Options.options.without_ldb_lmdb: + conf.env.REQUIRE_LMDB = False + else: + conf.env.REQUIRE_LMDB = True + elif Options.options.without_ad_dc: + conf.env.REQUIRE_LMDB = False + else: + if Options.options.without_ldb_lmdb: + if not Options.options.without_ad_dc and \ + conf.CONFIG_GET('ENABLE_SELFTEST'): + raise Errors.WafError('--without-ldb-lmdb conflicts ' + 'with --enable-selftest while ' + 'building the AD DC') + + conf.env.REQUIRE_LMDB = False + else: + conf.env.REQUIRE_LMDB = True + + + if conf.CONFIG_SET('USING_SYSTEM_LDB'): + v = VERSION.split('.') + conf.DEFINE('EXPECTED_SYSTEM_LDB_VERSION_MAJOR', int(v[0])) + conf.DEFINE('EXPECTED_SYSTEM_LDB_VERSION_MINOR', int(v[1])) + conf.DEFINE('EXPECTED_SYSTEM_LDB_VERSION_RELEASE', int(v[2])) + + if conf.env.standalone_ldb: + conf.CHECK_XSLTPROC_MANPAGES() + + # we need this for the ldap backend + if conf.CHECK_FUNCS_IN('ber_flush ldap_open ldap_initialize', 'lber ldap', headers='lber.h ldap.h'): + conf.env.ENABLE_LDAP_BACKEND = True + + # we don't want any libraries or modules to rely on runtime + # resolution of symbols + if not sys.platform.startswith("openbsd"): + conf.ADD_LDFLAGS('-Wl,-no-undefined', testflags=True) + + # if lmdb support is enabled then we require lmdb + # is present, build the mdb back end and enable lmdb support in + # the tools. + if conf.env.REQUIRE_LMDB and \ + not conf.CONFIG_SET('USING_SYSTEM_LDB'): + if not conf.CHECK_CFG(package='lmdb', + args='"lmdb >= 0.9.16" --cflags --libs', + msg='Checking for lmdb >= 0.9.16', + mandatory=False): + if not conf.CHECK_CODE(''' + #if MDB_VERSION_MAJOR == 0 \ + && MDB_VERSION_MINOR <= 9 \ + && MDB_VERSION_PATCH < 16 + #error LMDB too old + #endif + ''', + 'HAVE_GOOD_LMDB_VERSION', + headers='lmdb.h', + msg='Checking for lmdb >= 0.9.16 via header check'): + + if conf.env.standalone_ldb: + raise Errors.WafError('ldb build (unless --without-ldb-lmdb) ' + 'requires ' + 'lmdb 0.9.16 or later') + elif not Options.options.without_ad_dc: + raise Errors.WafError('Samba AD DC and --enable-selftest ' + 'requires ' + 'lmdb 0.9.16 or later') + + if conf.CHECK_FUNCS_IN('mdb_env_create', 'lmdb', headers='lmdb.h'): + conf.DEFINE('HAVE_LMDB', '1') + conf.env.HAVE_LMDB = True + + + conf.DEFINE('HAVE_CONFIG_H', 1, add_to_cflags=True) + + conf.SAMBA_CONFIG_H() + + conf.SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS() + +def build(bld): + bld.RECURSE('lib/tevent') + + if bld.CHECK_FOR_THIRD_PARTY(): + bld.RECURSE('third_party/popt') + bld.RECURSE('third_party/cmocka') + + bld.RECURSE('lib/replace') + bld.RECURSE('lib/tdb') + + if bld.env.standalone_ldb: + if not 'PACKAGE_VERSION' in bld.env: + bld.env.PACKAGE_VERSION = VERSION + bld.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig' + private_library = False + else: + private_library = True + # we're not currently linking against the ldap libs, but ldb.pc.in + # has @LDAP_LIBS@ + bld.env.LDAP_LIBS = '' + + LDB_MAP_SRC = bld.SUBDIR('ldb_map', + 'ldb_map.c ldb_map_inbound.c ldb_map_outbound.c') + + COMMON_SRC = bld.SUBDIR('common', + '''ldb_modules.c ldb_ldif.c ldb_parse.c ldb_msg.c ldb_utf8.c + ldb_debug.c ldb_dn.c ldb_match.c ldb_options.c ldb_pack.c + ldb_attributes.c attrib_handlers.c ldb_controls.c qsort.c''') + + bld.SAMBA_MODULE('ldb_ldap', 'ldb_ldap/ldb_ldap.c', + init_function='ldb_ldap_init', + module_init_name='ldb_init_module', + deps='talloc lber ldap ldb', + enabled=bld.env.ENABLE_LDAP_BACKEND, + internal_module=False, + subsystem='ldb') + + if bld.PYTHON_BUILD_IS_ENABLED(): + if not bld.CONFIG_SET('USING_SYSTEM_PYLDB_UTIL'): + name = bld.pyembed_libname('pyldb-util') + bld.SAMBA_LIBRARY(name, + deps='replace ldb', + source='pyldb_util.c', + public_headers=('' if private_library else 'pyldb.h'), + public_headers_install=not private_library, + vnum=VERSION, + private_library=private_library, + pc_files='pyldb-util.pc', + pyembed=True, + enabled=bld.PYTHON_BUILD_IS_ENABLED(), + abi_directory='ABI', + abi_match='pyldb_*') + + if not bld.CONFIG_SET('USING_SYSTEM_LDB'): + bld.SAMBA_PYTHON('pyldb', 'pyldb.c', + deps='replace ldb ' + name, + realname='ldb.so', + cflags='-DPACKAGE_VERSION=\"%s\"' % VERSION) + + # Do only install this file as part of the Samba build if we do not + # use the system libldb! + if not bld.CONFIG_SET('USING_SYSTEM_PYLDB_UTIL'): + bld.SAMBA_SCRIPT('_ldb_text.py', + pattern='_ldb_text.py', + installdir='python') + + bld.INSTALL_FILES('${PYTHONARCHDIR}', '_ldb_text.py') + + if not bld.CONFIG_SET('USING_SYSTEM_LDB'): + if bld.is_install: + modules_dir = bld.EXPAND_VARIABLES('${LDB_MODULESDIR}') + else: + # when we run from the source directory, we want to use + # the current modules, not the installed ones + modules_dir = os.path.join(os.getcwd(), 'bin/modules/ldb') + + abi_match = '!ldb_*module_ops !ldb_*backend_ops ldb_*' + + ldb_headers = ('include/ldb.h include/ldb_errors.h ' + 'include/ldb_module.h include/ldb_handlers.h') + + bld.SAMBA_LIBRARY('ldb', + COMMON_SRC + ' ' + LDB_MAP_SRC, + deps='tevent LIBLDB_MAIN replace', + includes='include', + public_headers=('' if private_library else ldb_headers), + public_headers_install=not private_library, + pc_files='ldb.pc', + vnum=VERSION, + private_library=private_library, + manpages='man/ldb.3', + abi_directory='ABI', + abi_match = abi_match) + + # generate a include/ldb_version.h + def generate_ldb_version_h(t): + '''generate a vscript file for our public libraries''' + + tgt = t.outputs[0].bldpath(t.env) + + v = t.env.LDB_VERSION.split('.') + + f = open(tgt, mode='w') + try: + f.write('#define LDB_VERSION "%s"\n' % t.env.LDB_VERSION) + f.write('#define LDB_VERSION_MAJOR %d\n' % int(v[0])) + f.write('#define LDB_VERSION_MINOR %d\n' % int(v[1])) + f.write('#define LDB_VERSION_RELEASE %d\n' % int(v[2])) + finally: + f.close() + return + t = bld.SAMBA_GENERATOR('ldb_version.h', + rule=generate_ldb_version_h, + dep_vars=['LDB_VERSION'], + target='include/ldb_version.h', + public_headers='include/ldb_version.h', + public_headers_install=not private_library) + t.env.LDB_VERSION = VERSION + + bld.SAMBA_MODULE('ldb_asq', + 'modules/asq.c', + init_function='ldb_asq_init', + module_init_name='ldb_init_module', + internal_module=False, + deps='ldb', + subsystem='ldb') + + bld.SAMBA_MODULE('ldb_server_sort', + 'modules/sort.c', + init_function='ldb_server_sort_init', + internal_module=False, + module_init_name='ldb_init_module', + deps='ldb', + subsystem='ldb') + + bld.SAMBA_MODULE('ldb_paged_searches', + 'modules/paged_searches.c', + init_function='ldb_paged_searches_init', + internal_module=False, + module_init_name='ldb_init_module', + deps='ldb', + subsystem='ldb') + + bld.SAMBA_MODULE('ldb_rdn_name', + 'modules/rdn_name.c', + init_function='ldb_rdn_name_init', + internal_module=False, + module_init_name='ldb_init_module', + deps='ldb', + subsystem='ldb') + + bld.SAMBA_MODULE('ldb_sample', + 'tests/sample_module.c', + init_function='ldb_sample_init', + internal_module=False, + module_init_name='ldb_init_module', + deps='ldb', + subsystem='ldb') + + bld.SAMBA_MODULE('ldb_skel', + 'modules/skel.c', + init_function='ldb_skel_init', + internal_module=False, + module_init_name='ldb_init_module', + deps='ldb', + subsystem='ldb') + + bld.SAMBA_MODULE('ldb_sqlite3', + 'sqlite3/ldb_sqlite3.c', + init_function='ldb_sqlite3_init', + internal_module=False, + module_init_name='ldb_init_module', + enabled=False, + deps='ldb', + subsystem='ldb') + + bld.SAMBA_MODULE('ldb_tdb', + bld.SUBDIR('ldb_tdb', + '''ldb_tdb_init.c'''), + init_function='ldb_tdb_init', + module_init_name='ldb_init_module', + internal_module=False, + deps='ldb ldb_tdb_int ldb_key_value', + subsystem='ldb') + + bld.SAMBA_LIBRARY('ldb_tdb_int', + bld.SUBDIR('ldb_tdb', + '''ldb_tdb_wrap.c ldb_tdb.c'''), + private_library=True, + deps='ldb tdb ldb_key_value ldb_tdb_err_map') + + bld.SAMBA_LIBRARY('ldb_tdb_err_map', + bld.SUBDIR('ldb_tdb', + '''ldb_tdb_err_map.c '''), + private_library=True, + deps='ldb tdb') + + bld.SAMBA_LIBRARY('ldb_key_value', + bld.SUBDIR('ldb_key_value', + '''ldb_kv.c ldb_kv_search.c ldb_kv_index.c + ldb_kv_cache.c'''), + private_library=True, + deps='tdb ldb ldb_tdb_err_map') + + if bld.CONFIG_SET('HAVE_LMDB'): + bld.SAMBA_MODULE('ldb_mdb', + bld.SUBDIR('ldb_mdb', + '''ldb_mdb_init.c'''), + init_function='ldb_mdb_init', + module_init_name='ldb_init_module', + internal_module=False, + deps='ldb ldb_key_value ldb_mdb_int', + subsystem='ldb') + + bld.SAMBA_LIBRARY('ldb_mdb_int', + bld.SUBDIR('ldb_mdb', + '''ldb_mdb.c '''), + private_library=True, + deps='ldb lmdb ldb_key_value') + lmdb_deps = ' ldb_mdb_int' + else: + lmdb_deps = '' + + + bld.SAMBA_MODULE('ldb_ldb', + bld.SUBDIR('ldb_ldb', + '''ldb_ldb.c'''), + init_function='ldb_ldb_init', + module_init_name='ldb_init_module', + internal_module=False, + deps='ldb ldb_tdb_int ldb_key_value' + lmdb_deps, + subsystem='ldb') + + # have a separate subsystem for common/ldb.c, so it can rebuild + # for install with a different -DLDB_MODULESDIR= + bld.SAMBA_SUBSYSTEM('LIBLDB_MAIN', + 'common/ldb.c', + deps='tevent tdb', + includes='include', + cflags=['-DLDB_MODULESDIR=\"%s\"' % modules_dir]) + + LDB_TOOLS='ldbadd ldbsearch ldbdel ldbmodify ldbedit ldbrename' + for t in LDB_TOOLS.split(): + bld.SAMBA_BINARY(t, 'tools/%s.c' % t, deps='ldb-cmdline ldb', + manpages='man/%s.1' % t) + + # ldbtest doesn't get installed + bld.SAMBA_BINARY('ldbtest', 'tools/ldbtest.c', deps='ldb-cmdline ldb', + install=False) + + if bld.CONFIG_SET('HAVE_LMDB'): + lmdb_deps = ' lmdb' + else: + lmdb_deps = '' + # ldbdump doesn't get installed + bld.SAMBA_BINARY('ldbdump', + 'tools/ldbdump.c', + deps='ldb-cmdline ldb' + lmdb_deps, + install=False) + + bld.SAMBA_LIBRARY('ldb-cmdline', + source='tools/ldbutil.c tools/cmdline.c', + deps='ldb dl popt', + private_library=True) + + bld.SAMBA_BINARY('ldb_tdb_mod_op_test', + source='tests/ldb_mod_op_test.c', + cflags='-DTEST_BE=\"tdb\"', + deps='cmocka ldb', + install=False) + + bld.SAMBA_BINARY('ldb_tdb_guid_mod_op_test', + source='tests/ldb_mod_op_test.c', + cflags='-DTEST_BE=\"tdb\" -DGUID_IDX=1', + deps='cmocka ldb', + install=False) + + bld.SAMBA_BINARY('ldb_tdb_kv_ops_test', + source='tests/ldb_kv_ops_test.c', + cflags='-DTEST_BE=\"tdb\"', + deps='cmocka ldb', + install=False) + + bld.SAMBA_BINARY('ldb_tdb_test', + source='tests/ldb_tdb_test.c', + deps='cmocka ldb', + install=False) + + bld.SAMBA_BINARY('ldb_msg_test', + source='tests/ldb_msg.c', + deps='cmocka ldb', + install=False) + + bld.SAMBA_BINARY('test_ldb_qsort', + source='tests/test_ldb_qsort.c', + deps='cmocka ldb', + install=False) + + bld.SAMBA_BINARY('test_ldb_dn', + source='tests/test_ldb_dn.c', + deps='cmocka ldb', + install=False) + + bld.SAMBA_BINARY('ldb_match_test', + source='tests/ldb_match_test.c', + deps='cmocka ldb', + install=False) + + bld.SAMBA_BINARY('ldb_key_value_test', + source='tests/ldb_key_value_test.c', + deps='cmocka ldb ldb_tdb_err_map', + install=False) + + bld.SAMBA_BINARY('ldb_parse_test', + source='tests/ldb_parse_test.c', + deps='cmocka ldb ldb_tdb_err_map', + install=False) + + bld.SAMBA_BINARY('ldb_filter_attrs_test', + source='tests/ldb_filter_attrs_test.c', + deps='cmocka ldb ldb_tdb_err_map', + install=False) + + bld.SAMBA_BINARY('ldb_key_value_sub_txn_tdb_test', + bld.SUBDIR('ldb_key_value', + '''ldb_kv_search.c + ldb_kv_index.c + ldb_kv_cache.c''') + + 'tests/ldb_key_value_sub_txn_test.c', + cflags='-DTEST_BE=\"tdb\"', + deps='cmocka ldb ldb_tdb_err_map', + install=False) + + if bld.CONFIG_SET('HAVE_LMDB'): + bld.SAMBA_BINARY('ldb_mdb_mod_op_test', + source='tests/ldb_mod_op_test.c', + cflags='-DTEST_BE=\"mdb\" -DGUID_IDX=1 ' + + '-DTEST_LMDB=1', + deps='cmocka ldb lmdb', + install=False) + + bld.SAMBA_BINARY('ldb_lmdb_test', + source='tests/ldb_lmdb_test.c', + deps='cmocka ldb', + install=False) + + bld.SAMBA_BINARY('ldb_lmdb_size_test', + source='tests/ldb_lmdb_size_test.c', + deps='cmocka ldb', + install=False) + + bld.SAMBA_BINARY('ldb_mdb_kv_ops_test', + source='tests/ldb_kv_ops_test.c', + cflags='-DTEST_BE=\"mdb\" -DTEST_LMDB=1', + deps='cmocka ldb', + install=False) + + # + # We rely on the versions of the ldb_key_value functions included + # in ldb_key_value_sub_txn_test.c taking priority over the versions + # in the ldb_key_value shared library. + # If this turns out to not be the case, the dependencies will + # need to be unrolled, and all the source files included and the + # ldb_tdb module initialization code will need to be called + # manually. + bld.SAMBA_BINARY('ldb_key_value_sub_txn_mdb_test', + bld.SUBDIR('ldb_key_value', + '''ldb_kv_search.c + ldb_kv_index.c + ldb_kv_cache.c''') + + 'tests/ldb_key_value_sub_txn_test.c', + cflags='-DTEST_BE=\"mdb\"', + deps='cmocka ldb ldb_tdb_err_map', + install=False) + else: + bld.SAMBA_BINARY('ldb_no_lmdb_test', + source='tests/ldb_no_lmdb_test.c', + deps='cmocka ldb', + install=False) + +def test(ctx): + '''run ldb testsuite''' + env = samba_utils.LOAD_ENVIRONMENT() + ctx.env = env + + test_prefix = "%s/st" % (Context.g_module.out) + shutil.rmtree(test_prefix, ignore_errors=True) + os.makedirs(test_prefix) + os.environ['TEST_DATA_PREFIX'] = test_prefix + os.environ['LDB_MODULES_PATH'] = Context.g_module.out + "/modules/ldb" + if env.HAVE_LMDB: + os.environ['HAVE_LMDB'] = '1' + else: + os.environ['HAVE_LMDB'] = '0' + samba_utils.ADD_LD_LIBRARY_PATH('bin/shared') + samba_utils.ADD_LD_LIBRARY_PATH('bin/shared/private') + + cmd = 'tests/test-tdb.sh %s' % Context.g_module.out + ret = samba_utils.RUN_COMMAND(cmd) + print("testsuite returned %d" % ret) + + tmp_dir = os.path.join(test_prefix, 'tmp') + if not os.path.exists(tmp_dir): + os.mkdir(tmp_dir) + pyret = samba_utils.RUN_PYTHON_TESTS( + ['tests/python/api.py', + 'tests/python/index.py', + 'tests/python/repack.py'], + extra_env={'SELFTEST_PREFIX': test_prefix}) + print("Python testsuite returned %d" % pyret) + + cmocka_ret = 0 + test_exes = ['test_ldb_qsort', + 'test_ldb_dn', + 'ldb_msg_test', + 'ldb_tdb_mod_op_test', + 'ldb_tdb_guid_mod_op_test', + 'ldb_msg_test', + 'ldb_tdb_kv_ops_test', + 'ldb_tdb_test', + 'ldb_match_test', + 'ldb_key_value_test', + # we currently don't run ldb_key_value_sub_txn_tdb_test as it + # tests the nested/sub transaction handling + # on operations which the TDB backend does not currently + # support + # 'ldb_key_value_sub_txn_tdb_test' + 'ldb_parse_test'] + + if env.HAVE_LMDB: + test_exes += ['ldb_mdb_mod_op_test', + 'ldb_lmdb_test', + # we don't want to run ldb_lmdb_size_test (which proves we can + # fit > 4G of data into the DB), it would fill up the disk on + # many of our test instances + 'ldb_mdb_kv_ops_test', + 'ldb_key_value_sub_txn_mdb_test'] + else: + test_exes += ['ldb_no_lmdb_test'] + + for test_exe in test_exes: + cmd = os.path.join(Context.g_module.out, test_exe) + cmocka_ret = cmocka_ret or samba_utils.RUN_COMMAND(cmd) + + sys.exit(ret or pyret or cmocka_ret) + +def dist(): + '''makes a tarball for distribution''' + samba_dist.dist() + +def reconfigure(ctx): + '''reconfigure if config scripts have changed''' + import samba_utils + samba_utils.reconfigure(ctx) diff --git a/libldb.spec b/libldb.spec index eac5054..a1fd727 100644 --- a/libldb.spec +++ b/libldb.spec @@ -85,10 +85,8 @@ make %{?_smp_mflags} V=1 doxygen Doxyfile %check -%ifarch ppc64le echo disabling one assertion in tests/python/repack.py sed -e '/test_guid_indexed_v1_db/,+18{/toggle_guidindex_check_pack/d}' -i tests/python/repack.py -%endif make %{?_smp_mflags} check -- Gitee From fa8fc616f3651c8bb5dabad95ec95698ec2a28b2 Mon Sep 17 00:00:00 2001 From: zhanglu Date: Tue, 18 Feb 2020 15:27:09 +0800 Subject: [PATCH 3/3] update to 2.0.8 --- ldb-2.0.8/ABI/ldb-0.9.10.sigs | 218 - ldb-2.0.8/ABI/ldb-0.9.12.sigs | 219 - ldb-2.0.8/ABI/ldb-0.9.15.sigs | 226 - ldb-2.0.8/ABI/ldb-0.9.16.sigs | 228 - ldb-2.0.8/ABI/ldb-0.9.17.sigs | 229 - ldb-2.0.8/ABI/ldb-0.9.18.sigs | 240 - ldb-2.0.8/ABI/ldb-0.9.19.sigs | 245 - ldb-2.0.8/ABI/ldb-0.9.20.sigs | 245 - ldb-2.0.8/ABI/ldb-0.9.22.sigs | 245 - ldb-2.0.8/ABI/ldb-0.9.23.sigs | 247 - ldb-2.0.8/ABI/ldb-0.9.24.sigs | 248 - ldb-2.0.8/ABI/ldb-1.0.0.sigs | 248 - ldb-2.0.8/ABI/ldb-1.0.1.sigs | 248 - ldb-2.0.8/ABI/ldb-1.0.2.sigs | 250 - ldb-2.0.8/ABI/ldb-1.1.0.sigs | 253 - ldb-2.0.8/ABI/ldb-1.1.1.sigs | 254 - ldb-2.0.8/ABI/ldb-1.1.10.sigs | 259 - ldb-2.0.8/ABI/ldb-1.1.11.sigs | 259 - ldb-2.0.8/ABI/ldb-1.1.12.sigs | 260 - ldb-2.0.8/ABI/ldb-1.1.13.sigs | 260 - ldb-2.0.8/ABI/ldb-1.1.14.sigs | 262 - ldb-2.0.8/ABI/ldb-1.1.15.sigs | 262 - ldb-2.0.8/ABI/ldb-1.1.16.sigs | 262 - ldb-2.0.8/ABI/ldb-1.1.17.sigs | 262 - ldb-2.0.8/ABI/ldb-1.1.18.sigs | 262 - ldb-2.0.8/ABI/ldb-1.1.19.sigs | 263 - ldb-2.0.8/ABI/ldb-1.1.2.sigs | 256 - ldb-2.0.8/ABI/ldb-1.1.20.sigs | 263 - ldb-2.0.8/ABI/ldb-1.1.21.sigs | 263 - ldb-2.0.8/ABI/ldb-1.1.22.sigs | 264 - ldb-2.0.8/ABI/ldb-1.1.23.sigs | 264 - ldb-2.0.8/ABI/ldb-1.1.24.sigs | 264 - ldb-2.0.8/ABI/ldb-1.1.25.sigs | 265 - ldb-2.0.8/ABI/ldb-1.1.26.sigs | 265 - ldb-2.0.8/ABI/ldb-1.1.27.sigs | 266 - ldb-2.0.8/ABI/ldb-1.1.28.sigs | 266 - ldb-2.0.8/ABI/ldb-1.1.29.sigs | 268 - ldb-2.0.8/ABI/ldb-1.1.3.sigs | 256 - ldb-2.0.8/ABI/ldb-1.1.30.sigs | 272 - ldb-2.0.8/ABI/ldb-1.1.31.sigs | 274 - ldb-2.0.8/ABI/ldb-1.1.4.sigs | 256 - ldb-2.0.8/ABI/ldb-1.1.5.sigs | 257 - ldb-2.0.8/ABI/ldb-1.1.6.sigs | 258 - ldb-2.0.8/ABI/ldb-1.1.7.sigs | 258 - ldb-2.0.8/ABI/ldb-1.1.8.sigs | 258 - ldb-2.0.8/ABI/ldb-1.1.9.sigs | 258 - ldb-2.0.8/ABI/ldb-1.2.0.sigs | 276 - ldb-2.0.8/ABI/ldb-1.2.1.sigs | 276 - ldb-2.0.8/ABI/ldb-1.2.2.sigs | 277 - ldb-2.0.8/ABI/ldb-1.2.3.sigs | 277 - ldb-2.0.8/ABI/ldb-1.3.0.sigs | 279 - ldb-2.0.8/ABI/ldb-1.3.1.sigs | 279 - ldb-2.0.8/ABI/ldb-1.3.2.sigs | 279 - ldb-2.0.8/ABI/ldb-1.4.0.sigs | 279 - ldb-2.0.8/ABI/ldb-1.4.1.sigs | 279 - ldb-2.0.8/ABI/ldb-1.5.0.sigs | 279 - ldb-2.0.8/ABI/ldb-1.5.1.sigs | 280 - ldb-2.0.8/ABI/ldb-1.5.2.sigs | 280 - ldb-2.0.8/ABI/ldb-1.5.3.sigs | 280 - ldb-2.0.8/ABI/ldb-1.6.0.sigs | 280 - ldb-2.0.8/ABI/ldb-1.6.1.sigs | 280 - ldb-2.0.8/ABI/ldb-1.6.2.sigs | 280 - ldb-2.0.8/ABI/ldb-1.6.3.sigs | 280 - ldb-2.0.8/ABI/ldb-2.0.0.sigs | 280 - ldb-2.0.8/ABI/ldb-2.0.1.sigs | 280 - ldb-2.0.8/ABI/ldb-2.0.2.sigs | 281 - ldb-2.0.8/ABI/ldb-2.0.3.sigs | 281 - ldb-2.0.8/ABI/ldb-2.0.4.sigs | 282 - ldb-2.0.8/ABI/ldb-2.0.5.sigs | 283 - ldb-2.0.8/ABI/ldb-2.0.6.sigs | 283 - ldb-2.0.8/ABI/ldb-2.0.7.sigs | 283 - ldb-2.0.8/ABI/ldb-2.0.8.sigs | 283 - ldb-2.0.8/ABI/ldb-ildap-0.9.12.sigs | 224 - ldb-2.0.8/ABI/ldb-samba4-0.9.10.sigs | 223 - ldb-2.0.8/ABI/ldb-samba4-0.9.11.sigs | 224 - ldb-2.0.8/ABI/pyldb-util-1.1.10.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.11.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.12.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.13.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.14.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.15.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.16.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.17.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.18.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.19.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.2.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.20.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.21.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.22.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.23.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.24.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.25.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.26.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.27.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.28.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.29.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.3.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.30.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.31.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.4.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.5.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.6.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.7.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.8.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.1.9.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.2.0.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.2.1.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.2.2.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.2.3.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.3.0.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.3.1.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.3.2.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.4.0.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.4.1.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.5.0.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.5.1.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.5.2.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.5.3.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.6.0.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.6.1.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.6.2.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-1.6.3.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-2.0.0.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-2.0.1.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-2.0.2.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-2.0.3.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-2.0.4.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-2.0.5.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-2.0.6.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-2.0.7.sigs | 2 - ldb-2.0.8/ABI/pyldb-util-2.0.8.sigs | 2 - ldb-2.0.8/ABI/pyldb-util.py3-2.0.0.sigs | 2 - ldb-2.0.8/Doxyfile | 26 - ldb-2.0.8/Makefile | 53 - ldb-2.0.8/README_gcov.txt | 29 - ldb-2.0.8/_ldb_text.py | 146 - ldb-2.0.8/buildtools/README | 12 - ldb-2.0.8/buildtools/bin/waf | 167 - ldb-2.0.8/buildtools/compare_config_h4.sh | 12 - ldb-2.0.8/buildtools/compare_generated.sh | 50 - ldb-2.0.8/buildtools/compare_install.sh | 8 - .../buildtools/examples/run_on_target.py | 148 - ldb-2.0.8/buildtools/scripts/Makefile.waf | 72 - ldb-2.0.8/buildtools/scripts/abi_gen.sh | 21 - ldb-2.0.8/buildtools/scripts/autogen-waf.sh | 27 - ldb-2.0.8/buildtools/scripts/configure.waf | 14 - ldb-2.0.8/buildtools/testwaf.sh | 70 - ldb-2.0.8/buildtools/wafsamba/README | 8 - ldb-2.0.8/buildtools/wafsamba/__init__.py | 0 .../buildtools/wafsamba/configure_file.py | 41 - ldb-2.0.8/buildtools/wafsamba/generic_cc.py | 70 - ldb-2.0.8/buildtools/wafsamba/pkgconfig.py | 68 - ldb-2.0.8/buildtools/wafsamba/samba3.py | 105 - ldb-2.0.8/buildtools/wafsamba/samba_abi.py | 261 - .../buildtools/wafsamba/samba_autoconf.py | 948 ---- .../buildtools/wafsamba/samba_autoproto.py | 24 - .../buildtools/wafsamba/samba_bundled.py | 274 - .../buildtools/wafsamba/samba_conftests.py | 528 -- ldb-2.0.8/buildtools/wafsamba/samba_cross.py | 175 - ldb-2.0.8/buildtools/wafsamba/samba_deps.py | 1181 ----- ldb-2.0.8/buildtools/wafsamba/samba_dist.py | 280 - ldb-2.0.8/buildtools/wafsamba/samba_git.py | 57 - .../buildtools/wafsamba/samba_headers.py | 181 - .../buildtools/wafsamba/samba_install.py | 236 - .../buildtools/wafsamba/samba_patterns.py | 201 - ldb-2.0.8/buildtools/wafsamba/samba_perl.py | 59 - ldb-2.0.8/buildtools/wafsamba/samba_pidl.py | 150 - ldb-2.0.8/buildtools/wafsamba/samba_python.py | 159 - .../buildtools/wafsamba/samba_third_party.py | 66 - ldb-2.0.8/buildtools/wafsamba/samba_utils.py | 763 --- .../buildtools/wafsamba/samba_version.py | 267 - ldb-2.0.8/buildtools/wafsamba/samba_waf18.py | 431 -- .../buildtools/wafsamba/samba_wildcard.py | 151 - ldb-2.0.8/buildtools/wafsamba/stale_files.py | 113 - ldb-2.0.8/buildtools/wafsamba/symbols.py | 659 --- .../wafsamba/test_duplicate_symbol.sh | 12 - .../buildtools/wafsamba/tests/__init__.py | 35 - .../buildtools/wafsamba/tests/test_abi.py | 134 - .../buildtools/wafsamba/tests/test_bundled.py | 27 - .../buildtools/wafsamba/tests/test_utils.py | 76 - ldb-2.0.8/buildtools/wafsamba/wafsamba.py | 950 ---- ldb-2.0.8/buildtools/wafsamba/wscript | 611 --- ldb-2.0.8/common/attrib_handlers.c | 639 --- ldb-2.0.8/common/ldb.c | 2194 -------- ldb-2.0.8/common/ldb_attributes.c | 411 -- ldb-2.0.8/common/ldb_controls.c | 1319 ----- ldb-2.0.8/common/ldb_debug.c | 150 - ldb-2.0.8/common/ldb_dn.c | 2240 -------- ldb-2.0.8/common/ldb_ldif.c | 1108 ---- ldb-2.0.8/common/ldb_match.c | 755 --- ldb-2.0.8/common/ldb_modules.c | 1236 ----- ldb-2.0.8/common/ldb_msg.c | 1469 ----- ldb-2.0.8/common/ldb_options.c | 107 - ldb-2.0.8/common/ldb_pack.c | 1261 ----- ldb-2.0.8/common/ldb_parse.c | 974 ---- ldb-2.0.8/common/ldb_utf8.c | 136 - ldb-2.0.8/common/qsort.c | 251 - ldb-2.0.8/configure | 21 - ldb-2.0.8/docs/builddocs.sh | 52 - ldb-2.0.8/docs/design.txt | 41 - ldb-2.0.8/docs/installdocs.sh | 17 - ldb-2.0.8/examples.dox | 16 - ldb-2.0.8/examples/ldbreader.c | 122 - ldb-2.0.8/examples/ldifreader.c | 125 - ldb-2.0.8/include/dlinklist.h | 178 - ldb-2.0.8/include/ldb.h | 2365 --------- ldb-2.0.8/include/ldb_errors.h | 312 -- ldb-2.0.8/include/ldb_handlers.h | 45 - ldb-2.0.8/include/ldb_module.h | 595 --- ldb-2.0.8/include/ldb_private.h | 320 -- ldb-2.0.8/ldb.pc.in | 16 - ldb-2.0.8/ldb_key_value/ldb_kv.c | 2292 -------- ldb-2.0.8/ldb_key_value/ldb_kv.h | 336 -- ldb-2.0.8/ldb_key_value/ldb_kv_cache.c | 697 --- ldb-2.0.8/ldb_key_value/ldb_kv_index.c | 3917 -------------- ldb-2.0.8/ldb_key_value/ldb_kv_search.c | 707 --- ldb-2.0.8/ldb_ldap/ldb_ldap.c | 969 ---- ldb-2.0.8/ldb_ldb/ldb_ldb.c | 80 - ldb-2.0.8/ldb_map/ldb_map.c | 1156 ---- ldb-2.0.8/ldb_map/ldb_map.h | 174 - ldb-2.0.8/ldb_map/ldb_map_inbound.c | 846 --- ldb-2.0.8/ldb_map/ldb_map_outbound.c | 1417 ----- ldb-2.0.8/ldb_map/ldb_map_private.h | 96 - ldb-2.0.8/ldb_mdb/ldb_mdb.c | 1126 ---- ldb-2.0.8/ldb_mdb/ldb_mdb.h | 60 - ldb-2.0.8/ldb_mdb/ldb_mdb_init.c | 31 - ldb-2.0.8/ldb_sqlite3/README | 7 - ldb-2.0.8/ldb_sqlite3/base160.c | 154 - ldb-2.0.8/ldb_sqlite3/ldb_sqlite3.c | 1958 ------- ldb-2.0.8/ldb_sqlite3/schema | 328 -- ldb-2.0.8/ldb_sqlite3/trees.ps | 1760 ------ ldb-2.0.8/ldb_tdb/ldb_tdb.c | 593 --- ldb-2.0.8/ldb_tdb/ldb_tdb.h | 16 - ldb-2.0.8/ldb_tdb/ldb_tdb_err_map.c | 84 - ldb-2.0.8/ldb_tdb/ldb_tdb_init.c | 59 - ldb-2.0.8/ldb_tdb/ldb_tdb_wrap.c | 162 - ldb-2.0.8/lib/replace/.checker_innocent | 4 - ldb-2.0.8/lib/replace/Makefile | 64 - ldb-2.0.8/lib/replace/README | 128 - ldb-2.0.8/lib/replace/closefrom.c | 138 - ldb-2.0.8/lib/replace/configure | 21 - ldb-2.0.8/lib/replace/crypt.c | 770 --- ldb-2.0.8/lib/replace/cwrap.c | 46 - ldb-2.0.8/lib/replace/dlfcn.c | 76 - ldb-2.0.8/lib/replace/getaddrinfo.c | 493 -- ldb-2.0.8/lib/replace/getaddrinfo.h | 91 - ldb-2.0.8/lib/replace/getifaddrs.c | 383 -- ldb-2.0.8/lib/replace/hdr_replace.h | 2 - ldb-2.0.8/lib/replace/inet_aton.c | 33 - ldb-2.0.8/lib/replace/inet_ntoa.c | 39 - ldb-2.0.8/lib/replace/inet_ntop.c | 191 - ldb-2.0.8/lib/replace/inet_pton.c | 213 - ldb-2.0.8/lib/replace/poll.c | 139 - ldb-2.0.8/lib/replace/replace-test.h | 9 - ldb-2.0.8/lib/replace/replace-testsuite.h | 10 - ldb-2.0.8/lib/replace/replace.c | 1058 ---- ldb-2.0.8/lib/replace/replace.h | 976 ---- ldb-2.0.8/lib/replace/snprintf.c | 1534 ------ ldb-2.0.8/lib/replace/socket.c | 39 - ldb-2.0.8/lib/replace/socketpair.c | 46 - ldb-2.0.8/lib/replace/strptime.c | 995 ---- ldb-2.0.8/lib/replace/system/README | 4 - ldb-2.0.8/lib/replace/system/aio.h | 32 - ldb-2.0.8/lib/replace/system/capability.h | 57 - ldb-2.0.8/lib/replace/system/dir.h | 71 - ldb-2.0.8/lib/replace/system/filesys.h | 242 - ldb-2.0.8/lib/replace/system/glob.h | 37 - ldb-2.0.8/lib/replace/system/gssapi.h | 53 - ldb-2.0.8/lib/replace/system/iconv.h | 57 - ldb-2.0.8/lib/replace/system/kerberos.h | 41 - ldb-2.0.8/lib/replace/system/locale.h | 42 - ldb-2.0.8/lib/replace/system/network.h | 372 -- ldb-2.0.8/lib/replace/system/nis.h | 55 - ldb-2.0.8/lib/replace/system/passwd.h | 92 - ldb-2.0.8/lib/replace/system/readline.h | 61 - ldb-2.0.8/lib/replace/system/select.h | 81 - ldb-2.0.8/lib/replace/system/shmem.h | 59 - ldb-2.0.8/lib/replace/system/syslog.h | 70 - ldb-2.0.8/lib/replace/system/terminal.h | 46 - ldb-2.0.8/lib/replace/system/threads.h | 72 - ldb-2.0.8/lib/replace/system/time.h | 99 - ldb-2.0.8/lib/replace/system/wait.h | 55 - .../lib/replace/system/wscript_configure | 18 - ldb-2.0.8/lib/replace/tests/getifaddrs.c | 105 - ldb-2.0.8/lib/replace/tests/incoherent_mmap.c | 83 - ldb-2.0.8/lib/replace/tests/main.c | 35 - ldb-2.0.8/lib/replace/tests/os2_delete.c | 134 - ldb-2.0.8/lib/replace/tests/shared_mmap.c | 71 - ldb-2.0.8/lib/replace/tests/shared_mremap.c | 51 - ldb-2.0.8/lib/replace/tests/snprintf.c | 29 - ldb-2.0.8/lib/replace/tests/strptime.c | 173 - ldb-2.0.8/lib/replace/tests/testsuite.c | 1151 ---- ldb-2.0.8/lib/replace/timegm.c | 78 - ldb-2.0.8/lib/replace/win32_replace.h | 159 - ldb-2.0.8/lib/replace/wscript | 955 ---- ldb-2.0.8/lib/replace/xattr.c | 785 --- .../lib/talloc/ABI/pytalloc-util-2.0.6.sigs | 6 - .../lib/talloc/ABI/pytalloc-util-2.0.7.sigs | 6 - .../lib/talloc/ABI/pytalloc-util-2.0.8.sigs | 6 - .../lib/talloc/ABI/pytalloc-util-2.1.0.sigs | 6 - .../lib/talloc/ABI/pytalloc-util-2.1.1.sigs | 6 - .../lib/talloc/ABI/pytalloc-util-2.1.10.sigs | 16 - .../lib/talloc/ABI/pytalloc-util-2.1.11.sigs | 16 - .../lib/talloc/ABI/pytalloc-util-2.1.12.sigs | 16 - .../lib/talloc/ABI/pytalloc-util-2.1.13.sigs | 16 - .../lib/talloc/ABI/pytalloc-util-2.1.14.sigs | 16 - .../lib/talloc/ABI/pytalloc-util-2.1.15.sigs | 16 - .../lib/talloc/ABI/pytalloc-util-2.1.16.sigs | 16 - .../lib/talloc/ABI/pytalloc-util-2.1.2.sigs | 6 - .../lib/talloc/ABI/pytalloc-util-2.1.3.sigs | 6 - .../lib/talloc/ABI/pytalloc-util-2.1.4.sigs | 6 - .../lib/talloc/ABI/pytalloc-util-2.1.5.sigs | 6 - .../lib/talloc/ABI/pytalloc-util-2.1.6.sigs | 13 - .../lib/talloc/ABI/pytalloc-util-2.1.7.sigs | 13 - .../lib/talloc/ABI/pytalloc-util-2.1.8.sigs | 13 - .../lib/talloc/ABI/pytalloc-util-2.1.9.sigs | 16 - .../lib/talloc/ABI/pytalloc-util-2.2.0.sigs | 15 - ldb-2.0.8/lib/talloc/ABI/talloc-2.0.2.sigs | 62 - ldb-2.0.8/lib/talloc/ABI/talloc-2.0.3.sigs | 62 - ldb-2.0.8/lib/talloc/ABI/talloc-2.0.4.sigs | 62 - ldb-2.0.8/lib/talloc/ABI/talloc-2.0.5.sigs | 62 - ldb-2.0.8/lib/talloc/ABI/talloc-2.0.6.sigs | 62 - ldb-2.0.8/lib/talloc/ABI/talloc-2.0.7.sigs | 62 - ldb-2.0.8/lib/talloc/ABI/talloc-2.0.8.sigs | 63 - ldb-2.0.8/lib/talloc/ABI/talloc-2.1.0.sigs | 64 - ldb-2.0.8/lib/talloc/ABI/talloc-2.1.1.sigs | 64 - ldb-2.0.8/lib/talloc/ABI/talloc-2.1.10.sigs | 65 - ldb-2.0.8/lib/talloc/ABI/talloc-2.1.11.sigs | 65 - ldb-2.0.8/lib/talloc/ABI/talloc-2.1.12.sigs | 65 - ldb-2.0.8/lib/talloc/ABI/talloc-2.1.13.sigs | 65 - ldb-2.0.8/lib/talloc/ABI/talloc-2.1.14.sigs | 65 - ldb-2.0.8/lib/talloc/ABI/talloc-2.1.15.sigs | 65 - ldb-2.0.8/lib/talloc/ABI/talloc-2.1.16.sigs | 65 - ldb-2.0.8/lib/talloc/ABI/talloc-2.1.2.sigs | 64 - ldb-2.0.8/lib/talloc/ABI/talloc-2.1.3.sigs | 64 - ldb-2.0.8/lib/talloc/ABI/talloc-2.1.4.sigs | 65 - ldb-2.0.8/lib/talloc/ABI/talloc-2.1.5.sigs | 65 - ldb-2.0.8/lib/talloc/ABI/talloc-2.1.6.sigs | 65 - ldb-2.0.8/lib/talloc/ABI/talloc-2.1.7.sigs | 65 - ldb-2.0.8/lib/talloc/ABI/talloc-2.1.8.sigs | 65 - ldb-2.0.8/lib/talloc/ABI/talloc-2.1.9.sigs | 65 - ldb-2.0.8/lib/talloc/ABI/talloc-2.2.0.sigs | 65 - ldb-2.0.8/lib/talloc/Makefile | 68 - ldb-2.0.8/lib/talloc/NEWS | 13 - ldb-2.0.8/lib/talloc/compat/talloc_compat1.c | 51 - ldb-2.0.8/lib/talloc/compat/talloc_compat1.mk | 21 - ldb-2.0.8/lib/talloc/configure | 21 - ldb-2.0.8/lib/talloc/doc/context.png | Bin 4715 -> 0 bytes ldb-2.0.8/lib/talloc/doc/context_tree.png | Bin 6158 -> 0 bytes ldb-2.0.8/lib/talloc/doc/mainpage.dox | 111 - ldb-2.0.8/lib/talloc/doc/stealing.png | Bin 6994 -> 0 bytes .../lib/talloc/doc/tutorial_bestpractices.dox | 192 - ldb-2.0.8/lib/talloc/doc/tutorial_context.dox | 198 - .../lib/talloc/doc/tutorial_debugging.dox | 116 - .../lib/talloc/doc/tutorial_destructors.dox | 82 - ldb-2.0.8/lib/talloc/doc/tutorial_dts.dox | 109 - .../lib/talloc/doc/tutorial_introduction.dox | 45 - ldb-2.0.8/lib/talloc/doc/tutorial_pools.dox | 93 - .../lib/talloc/doc/tutorial_stealing.dox | 55 - ldb-2.0.8/lib/talloc/doc/tutorial_threads.dox | 203 - ldb-2.0.8/lib/talloc/doxy.config | 1807 ------- ldb-2.0.8/lib/talloc/man/talloc.3.xml | 814 --- ldb-2.0.8/lib/talloc/pytalloc-util.pc.in | 11 - ldb-2.0.8/lib/talloc/pytalloc.c | 309 -- ldb-2.0.8/lib/talloc/pytalloc.h | 79 - ldb-2.0.8/lib/talloc/pytalloc_guide.txt | 252 - ldb-2.0.8/lib/talloc/pytalloc_private.h | 26 - ldb-2.0.8/lib/talloc/pytalloc_util.c | 333 -- ldb-2.0.8/lib/talloc/talloc.c | 3050 ----------- ldb-2.0.8/lib/talloc/talloc.h | 1945 ------- ldb-2.0.8/lib/talloc/talloc.pc.in | 11 - ldb-2.0.8/lib/talloc/talloc_guide.txt | 768 --- ldb-2.0.8/lib/talloc/talloc_testsuite.h | 7 - ldb-2.0.8/lib/talloc/test_magic_differs.sh | 16 - .../lib/talloc/test_magic_differs_helper.c | 12 - ldb-2.0.8/lib/talloc/test_pytalloc.c | 244 - ldb-2.0.8/lib/talloc/test_pytalloc.py | 189 - ldb-2.0.8/lib/talloc/testsuite.c | 2169 -------- ldb-2.0.8/lib/talloc/testsuite_main.c | 36 - ldb-2.0.8/lib/talloc/web/index.html | 51 - ldb-2.0.8/lib/talloc/wscript | 198 - ldb-2.0.8/lib/tdb/ABI/tdb-1.2.1.sigs | 95 - ldb-2.0.8/lib/tdb/ABI/tdb-1.2.10.sigs | 66 - ldb-2.0.8/lib/tdb/ABI/tdb-1.2.11.sigs | 67 - ldb-2.0.8/lib/tdb/ABI/tdb-1.2.12.sigs | 67 - ldb-2.0.8/lib/tdb/ABI/tdb-1.2.13.sigs | 67 - ldb-2.0.8/lib/tdb/ABI/tdb-1.2.2.sigs | 60 - ldb-2.0.8/lib/tdb/ABI/tdb-1.2.3.sigs | 60 - ldb-2.0.8/lib/tdb/ABI/tdb-1.2.4.sigs | 60 - ldb-2.0.8/lib/tdb/ABI/tdb-1.2.5.sigs | 61 - ldb-2.0.8/lib/tdb/ABI/tdb-1.2.6.sigs | 61 - ldb-2.0.8/lib/tdb/ABI/tdb-1.2.7.sigs | 61 - ldb-2.0.8/lib/tdb/ABI/tdb-1.2.8.sigs | 61 - ldb-2.0.8/lib/tdb/ABI/tdb-1.2.9.sigs | 62 - ldb-2.0.8/lib/tdb/ABI/tdb-1.3.0.sigs | 68 - ldb-2.0.8/lib/tdb/ABI/tdb-1.3.1.sigs | 68 - ldb-2.0.8/lib/tdb/ABI/tdb-1.3.10.sigs | 69 - ldb-2.0.8/lib/tdb/ABI/tdb-1.3.11.sigs | 70 - ldb-2.0.8/lib/tdb/ABI/tdb-1.3.12.sigs | 70 - ldb-2.0.8/lib/tdb/ABI/tdb-1.3.13.sigs | 70 - ldb-2.0.8/lib/tdb/ABI/tdb-1.3.14.sigs | 71 - ldb-2.0.8/lib/tdb/ABI/tdb-1.3.15.sigs | 71 - ldb-2.0.8/lib/tdb/ABI/tdb-1.3.16.sigs | 71 - ldb-2.0.8/lib/tdb/ABI/tdb-1.3.17.sigs | 73 - ldb-2.0.8/lib/tdb/ABI/tdb-1.3.18.sigs | 73 - ldb-2.0.8/lib/tdb/ABI/tdb-1.3.2.sigs | 68 - ldb-2.0.8/lib/tdb/ABI/tdb-1.3.3.sigs | 68 - ldb-2.0.8/lib/tdb/ABI/tdb-1.3.4.sigs | 68 - ldb-2.0.8/lib/tdb/ABI/tdb-1.3.5.sigs | 69 - ldb-2.0.8/lib/tdb/ABI/tdb-1.3.6.sigs | 69 - ldb-2.0.8/lib/tdb/ABI/tdb-1.3.7.sigs | 69 - ldb-2.0.8/lib/tdb/ABI/tdb-1.3.8.sigs | 69 - ldb-2.0.8/lib/tdb/ABI/tdb-1.3.9.sigs | 69 - ldb-2.0.8/lib/tdb/ABI/tdb-1.4.0.sigs | 73 - ldb-2.0.8/lib/tdb/ABI/tdb-1.4.1.sigs | 73 - ldb-2.0.8/lib/tdb/ABI/tdb-1.4.2.sigs | 73 - ldb-2.0.8/lib/tdb/Makefile | 68 - ldb-2.0.8/lib/tdb/_tdb_text.py | 137 - ldb-2.0.8/lib/tdb/common/check.c | 489 -- ldb-2.0.8/lib/tdb/common/dump.c | 149 - ldb-2.0.8/lib/tdb/common/error.c | 57 - ldb-2.0.8/lib/tdb/common/freelist.c | 747 --- ldb-2.0.8/lib/tdb/common/freelistcheck.c | 107 - ldb-2.0.8/lib/tdb/common/hash.c | 345 -- ldb-2.0.8/lib/tdb/common/io.c | 806 --- ldb-2.0.8/lib/tdb/common/lock.c | 1031 ---- ldb-2.0.8/lib/tdb/common/mutex.c | 1077 ---- ldb-2.0.8/lib/tdb/common/open.c | 962 ---- ldb-2.0.8/lib/tdb/common/rescue.c | 351 -- ldb-2.0.8/lib/tdb/common/summary.c | 219 - ldb-2.0.8/lib/tdb/common/tdb.c | 1324 ----- ldb-2.0.8/lib/tdb/common/tdb_private.h | 370 -- ldb-2.0.8/lib/tdb/common/transaction.c | 1387 ----- ldb-2.0.8/lib/tdb/common/traverse.c | 510 -- ldb-2.0.8/lib/tdb/configure | 21 - ldb-2.0.8/lib/tdb/docs/README | 273 - ldb-2.0.8/lib/tdb/docs/mainpage.dox | 61 - ldb-2.0.8/lib/tdb/docs/mutex.txt | 136 - ldb-2.0.8/lib/tdb/docs/tdb.magic | 10 - ldb-2.0.8/lib/tdb/docs/tracing.txt | 46 - ldb-2.0.8/lib/tdb/doxy.config | 1697 ------ ldb-2.0.8/lib/tdb/include/tdb.h | 1025 ---- ldb-2.0.8/lib/tdb/man/tdbbackup.8.xml | 157 - ldb-2.0.8/lib/tdb/man/tdbdump.8.xml | 93 - ldb-2.0.8/lib/tdb/man/tdbrestore.8.xml | 67 - ldb-2.0.8/lib/tdb/man/tdbtool.8.xml | 275 - ldb-2.0.8/lib/tdb/pytdb.c | 830 --- ldb-2.0.8/lib/tdb/python/tdbdump.py | 13 - ldb-2.0.8/lib/tdb/python/tests/simple.py | 311 -- ldb-2.0.8/lib/tdb/tdb.pc.in | 11 - ldb-2.0.8/lib/tdb/test/circular_chain.tdb | Bin 272 -> 0 bytes ldb-2.0.8/lib/tdb/test/circular_freelist.tdb | Bin 400 -> 0 bytes ldb-2.0.8/lib/tdb/test/external-agent.c | 224 - ldb-2.0.8/lib/tdb/test/external-agent.h | 44 - ldb-2.0.8/lib/tdb/test/jenkins-be-hash.tdb | Bin 696 -> 0 bytes ldb-2.0.8/lib/tdb/test/jenkins-le-hash.tdb | Bin 696 -> 0 bytes ldb-2.0.8/lib/tdb/test/lock-tracking.c | 157 - ldb-2.0.8/lib/tdb/test/lock-tracking.h | 25 - ldb-2.0.8/lib/tdb/test/logging.c | 33 - ldb-2.0.8/lib/tdb/test/logging.h | 11 - ldb-2.0.8/lib/tdb/test/old-nohash-be.tdb | Bin 696 -> 0 bytes ldb-2.0.8/lib/tdb/test/old-nohash-le.tdb | Bin 696 -> 0 bytes ldb-2.0.8/lib/tdb/test/run-3G-file.c | 145 - .../test/run-allrecord-traverse-deadlock.c | 203 - ldb-2.0.8/lib/tdb/test/run-bad-tdb-header.c | 59 - ldb-2.0.8/lib/tdb/test/run-check.c | 65 - ldb-2.0.8/lib/tdb/test/run-circular-chain.c | 42 - .../lib/tdb/test/run-circular-freelist.c | 50 - ldb-2.0.8/lib/tdb/test/run-corrupt.c | 132 - .../lib/tdb/test/run-die-during-transaction.c | 232 - ldb-2.0.8/lib/tdb/test/run-endian.c | 64 - ldb-2.0.8/lib/tdb/test/run-fcntl-deadlock.c | 202 - ldb-2.0.8/lib/tdb/test/run-incompatible.c | 188 - .../lib/tdb/test/run-marklock-deadlock.c | 278 - .../lib/tdb/test/run-mutex-allrecord-bench.c | 82 - .../lib/tdb/test/run-mutex-allrecord-block.c | 120 - .../tdb/test/run-mutex-allrecord-trylock.c | 113 - ldb-2.0.8/lib/tdb/test/run-mutex-die.c | 269 - ldb-2.0.8/lib/tdb/test/run-mutex-openflags2.c | 146 - .../lib/tdb/test/run-mutex-transaction1.c | 236 - ldb-2.0.8/lib/tdb/test/run-mutex-trylock.c | 122 - ldb-2.0.8/lib/tdb/test/run-mutex1.c | 138 - .../lib/tdb/test/run-nested-transactions.c | 79 - ldb-2.0.8/lib/tdb/test/run-nested-traverse.c | 111 - .../tdb/test/run-no-lock-during-traverse.c | 114 - ldb-2.0.8/lib/tdb/test/run-oldhash.c | 50 - .../tdb/test/run-open-during-transaction.c | 183 - ldb-2.0.8/lib/tdb/test/run-rdlock-upgrade.c | 166 - ldb-2.0.8/lib/tdb/test/run-readonly-check.c | 53 - .../lib/tdb/test/run-rescue-find_entry.c | 51 - ldb-2.0.8/lib/tdb/test/run-rescue.c | 127 - ldb-2.0.8/lib/tdb/test/run-rwlock-check.c | 46 - ldb-2.0.8/lib/tdb/test/run-summary.c | 65 - .../lib/tdb/test/run-transaction-expand.c | 125 - ldb-2.0.8/lib/tdb/test/run-traverse-chain.c | 94 - .../tdb/test/run-traverse-in-transaction.c | 90 - ldb-2.0.8/lib/tdb/test/run-wronghash-fail.c | 121 - ldb-2.0.8/lib/tdb/test/run-zero-append.c | 41 - ldb-2.0.8/lib/tdb/test/run.c | 50 - ldb-2.0.8/lib/tdb/test/rwlock-be.tdb | Bin 696 -> 0 bytes ldb-2.0.8/lib/tdb/test/rwlock-le.tdb | Bin 696 -> 0 bytes ldb-2.0.8/lib/tdb/test/sample_tdb.tdb | Bin 8192 -> 0 bytes ldb-2.0.8/lib/tdb/test/tap-interface.h | 58 - ldb-2.0.8/lib/tdb/test/tap-to-subunit.h | 155 - ldb-2.0.8/lib/tdb/test/tdb.corrupt | Bin 192512 -> 0 bytes ldb-2.0.8/lib/tdb/test/test_tdbbackup.sh | 54 - ldb-2.0.8/lib/tdb/tools/tdbbackup.c | 370 -- ldb-2.0.8/lib/tdb/tools/tdbdump.c | 181 - ldb-2.0.8/lib/tdb/tools/tdbrestore.c | 222 - ldb-2.0.8/lib/tdb/tools/tdbtest.c | 290 - ldb-2.0.8/lib/tdb/tools/tdbtool.c | 944 ---- ldb-2.0.8/lib/tdb/tools/tdbtorture.c | 501 -- ldb-2.0.8/lib/tdb/web/index.html | 48 - ldb-2.0.8/lib/tdb/wscript | 259 - ldb-2.0.8/lib/tevent/ABI/tevent-0.10.0.sigs | 126 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.10.sigs | 73 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.11.sigs | 73 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.12.sigs | 74 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.13.sigs | 75 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.14.sigs | 78 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.15.sigs | 78 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.16.sigs | 82 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.17.sigs | 82 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.18.sigs | 83 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.19.sigs | 83 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.20.sigs | 87 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.21.sigs | 88 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.22.sigs | 88 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.23.sigs | 88 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.24.sigs | 88 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.25.sigs | 88 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.26.sigs | 90 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.27.sigs | 90 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.28.sigs | 90 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.29.sigs | 90 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.30.sigs | 96 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.31.sigs | 99 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.32.sigs | 99 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.33.sigs | 99 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.34.sigs | 99 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.35.sigs | 99 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.36.sigs | 100 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.37.sigs | 126 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.38.sigs | 126 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.39.sigs | 126 - ldb-2.0.8/lib/tevent/ABI/tevent-0.9.9.sigs | 73 - ldb-2.0.8/lib/tevent/Makefile | 52 - ldb-2.0.8/lib/tevent/bindings.py | 116 - ldb-2.0.8/lib/tevent/configure | 21 - .../doc/img/tevent_context_stucture.png | Bin 21888 -> 0 bytes .../lib/tevent/doc/img/tevent_subrequest.png | Bin 22453 -> 0 bytes ldb-2.0.8/lib/tevent/doc/mainpage.dox | 47 - ldb-2.0.8/lib/tevent/doc/tevent_context.dox | 75 - ldb-2.0.8/lib/tevent/doc/tevent_data.dox | 137 - ldb-2.0.8/lib/tevent/doc/tevent_events.dox | 341 -- ldb-2.0.8/lib/tevent/doc/tevent_queue.dox | 275 - ldb-2.0.8/lib/tevent/doc/tevent_request.dox | 189 - ldb-2.0.8/lib/tevent/doc/tevent_thread.dox | 322 -- ldb-2.0.8/lib/tevent/doc/tevent_tutorial.dox | 22 - ldb-2.0.8/lib/tevent/doc/tutorials.dox | 43 - ldb-2.0.8/lib/tevent/doxy.config | 1908 ------- ldb-2.0.8/lib/tevent/echo_server.c | 667 --- ldb-2.0.8/lib/tevent/pytevent.c | 945 ---- ldb-2.0.8/lib/tevent/test_req.c | 288 - ldb-2.0.8/lib/tevent/testsuite.c | 1821 ------- ldb-2.0.8/lib/tevent/tevent.c | 1037 ---- ldb-2.0.8/lib/tevent/tevent.h | 2511 --------- ldb-2.0.8/lib/tevent/tevent.pc.in | 12 - ldb-2.0.8/lib/tevent/tevent.py | 28 - ldb-2.0.8/lib/tevent/tevent_debug.c | 135 - ldb-2.0.8/lib/tevent/tevent_epoll.c | 956 ---- ldb-2.0.8/lib/tevent/tevent_fd.c | 161 - ldb-2.0.8/lib/tevent/tevent_immediate.c | 210 - ldb-2.0.8/lib/tevent/tevent_internal.h | 471 -- ldb-2.0.8/lib/tevent/tevent_liboop.c | 292 - ldb-2.0.8/lib/tevent/tevent_poll.c | 663 --- ldb-2.0.8/lib/tevent/tevent_port.c | 803 --- ldb-2.0.8/lib/tevent/tevent_queue.c | 370 -- ldb-2.0.8/lib/tevent/tevent_req.c | 570 -- ldb-2.0.8/lib/tevent/tevent_signal.c | 518 -- ldb-2.0.8/lib/tevent/tevent_standard.c | 238 - ldb-2.0.8/lib/tevent/tevent_threads.c | 601 --- ldb-2.0.8/lib/tevent/tevent_timed.c | 449 -- ldb-2.0.8/lib/tevent/tevent_util.c | 107 - ldb-2.0.8/lib/tevent/tevent_util.h | 185 - ldb-2.0.8/lib/tevent/tevent_wakeup.c | 67 - ldb-2.0.8/lib/tevent/tevent_wrapper.c | 571 -- ldb-2.0.8/lib/tevent/wscript | 142 - ldb-2.0.8/lib/util/attr.h | 101 - ldb-2.0.8/lib/util/binsearch.h | 121 - ldb-2.0.8/mainpage.dox | 80 - ldb-2.0.8/man/ldb.3.xml | 265 - ldb-2.0.8/man/ldbadd.1.xml | 108 - ldb-2.0.8/man/ldbdel.1.xml | 108 - ldb-2.0.8/man/ldbedit.1.xml | 203 - ldb-2.0.8/man/ldbmodify.1.xml | 96 - ldb-2.0.8/man/ldbrename.1.xml | 110 - ldb-2.0.8/man/ldbsearch.1.xml | 122 - ldb-2.0.8/modules/asq.c | 416 -- ldb-2.0.8/modules/paged_searches.c | 391 -- ldb-2.0.8/modules/rdn_name.c | 610 --- ldb-2.0.8/modules/skel.c | 147 - ldb-2.0.8/modules/sort.c | 402 -- ldb-2.0.8/nssldb/README.txt | 34 - ldb-2.0.8/nssldb/ldb-grp.c | 429 -- ldb-2.0.8/nssldb/ldb-nss.c | 395 -- ldb-2.0.8/nssldb/ldb-nss.h | 84 - ldb-2.0.8/nssldb/ldb-pwd.c | 242 - ldb-2.0.8/pyldb-util.pc.in | 13 - ldb-2.0.8/pyldb.c | 4470 ---------------- ldb-2.0.8/pyldb.h | 109 - ldb-2.0.8/pyldb_util.c | 113 - ldb-2.0.8/tests/guidindexpackv1.ldb | Bin 1286144 -> 0 bytes ldb-2.0.8/tests/init.ldif | 41 - ldb-2.0.8/tests/init_slapd.sh | 41 - ldb-2.0.8/tests/kill_slapd.sh | 12 - ldb-2.0.8/tests/ldapi_url.sh | 11 - ldb-2.0.8/tests/ldb_filter_attrs_test.c | 988 ---- .../ldb_key_value_sub_txn_mdb_test.valgrind | 97 - ldb-2.0.8/tests/ldb_key_value_sub_txn_test.c | 843 --- ldb-2.0.8/tests/ldb_key_value_test.c | 388 -- ldb-2.0.8/tests/ldb_kv_ops_test.c | 1804 ------- ldb-2.0.8/tests/ldb_kv_ops_test.valgrind | 97 - ldb-2.0.8/tests/ldb_lmdb_size_test.c | 210 - ldb-2.0.8/tests/ldb_lmdb_test.c | 589 -- ldb-2.0.8/tests/ldb_match_test.c | 191 - ldb-2.0.8/tests/ldb_match_test.valgrind | 16 - ldb-2.0.8/tests/ldb_mod_op_test.c | 4721 ----------------- ldb-2.0.8/tests/ldb_msg.c | 380 -- ldb-2.0.8/tests/ldb_no_lmdb_test.c | 158 - ldb-2.0.8/tests/ldb_parse_test.c | 93 - ldb-2.0.8/tests/ldb_tdb_test.c | 389 -- ldb-2.0.8/tests/photo.ldif | 5 - ldb-2.0.8/tests/python/api.py | 3326 ------------ ldb-2.0.8/tests/python/index.py | 1455 ----- ldb-2.0.8/tests/python/repack.py | 204 - ldb-2.0.8/tests/samba4.png | Bin 6239 -> 0 bytes ldb-2.0.8/tests/sample_module.c | 122 - .../tests/schema-tests/schema-add-test.ldif | 66 - .../tests/schema-tests/schema-mod-test-1.ldif | 5 - .../tests/schema-tests/schema-mod-test-2.ldif | 5 - .../tests/schema-tests/schema-mod-test-3.ldif | 5 - .../tests/schema-tests/schema-mod-test-4.ldif | 5 - .../tests/schema-tests/schema-mod-test-5.ldif | 5 - ldb-2.0.8/tests/schema-tests/schema.ldif | 100 - ldb-2.0.8/tests/slapd.conf | 26 - ldb-2.0.8/tests/start_slapd.sh | 14 - ldb-2.0.8/tests/test-attribs.ldif | 6 - ldb-2.0.8/tests/test-config.ldif | 67 - ldb-2.0.8/tests/test-controls.sh | 43 - ldb-2.0.8/tests/test-default-config.ldif | 17 - ldb-2.0.8/tests/test-dup-2.ldif | 6 - ldb-2.0.8/tests/test-dup.ldif | 13 - ldb-2.0.8/tests/test-extended.sh | 69 - ldb-2.0.8/tests/test-generic.sh | 157 - ldb-2.0.8/tests/test-index.ldif | 7 - ldb-2.0.8/tests/test-ldap.sh | 54 - ldb-2.0.8/tests/test-modify-modrdn.ldif | 12 - ldb-2.0.8/tests/test-modify-unmet-2.ldif | 7 - ldb-2.0.8/tests/test-modify-unmet.ldif | 15 - ldb-2.0.8/tests/test-modify.ldif | 23 - ldb-2.0.8/tests/test-schema.sh | 34 - ldb-2.0.8/tests/test-soloading.sh | 32 - ldb-2.0.8/tests/test-sqlite3.sh | 25 - ldb-2.0.8/tests/test-tdb-features.sh | 178 - ldb-2.0.8/tests/test-tdb-subunit.sh | 7 - ldb-2.0.8/tests/test-tdb.sh | 38 - ldb-2.0.8/tests/test-wildcard.ldif | 5 - ldb-2.0.8/tests/test-wrong_attributes.ldif | 3 - ldb-2.0.8/tests/test.ldif | 440 -- ldb-2.0.8/tests/test_ldb_dn.c | 232 - ldb-2.0.8/tests/test_ldb_qsort.c | 65 - ldb-2.0.8/tests/testdata.txt | 8 - ldb-2.0.8/tests/testsearch.txt | 5 - ldb-2.0.8/third_party/cmocka/cmocka.c | 3431 ------------ ldb-2.0.8/third_party/cmocka/cmocka.h | 2298 -------- ldb-2.0.8/third_party/cmocka/cmocka_private.h | 163 - ldb-2.0.8/third_party/cmocka/wscript | 24 - ldb-2.0.8/third_party/popt/CHANGES | 46 - ldb-2.0.8/third_party/popt/COPYING | 22 - ldb-2.0.8/third_party/popt/README | 16 - ldb-2.0.8/third_party/popt/findme.h | 20 - ldb-2.0.8/third_party/popt/lookup3.c | 969 ---- ldb-2.0.8/third_party/popt/popt.c | 1787 ------- ldb-2.0.8/third_party/popt/popt.h | 744 --- ldb-2.0.8/third_party/popt/poptconfig.c | 582 -- ldb-2.0.8/third_party/popt/popthelp.c | 925 ---- ldb-2.0.8/third_party/popt/poptint.c | 199 - ldb-2.0.8/third_party/popt/poptint.h | 222 - ldb-2.0.8/third_party/popt/poptparse.c | 230 - ldb-2.0.8/third_party/popt/system.h | 103 - ldb-2.0.8/third_party/popt/wscript | 24 - ldb-2.0.8/third_party/waf/waflib/Build.py | 1512 ------ ldb-2.0.8/third_party/waf/waflib/ConfigSet.py | 361 -- ldb-2.0.8/third_party/waf/waflib/Configure.py | 649 --- ldb-2.0.8/third_party/waf/waflib/Context.py | 737 --- ldb-2.0.8/third_party/waf/waflib/Errors.py | 68 - ldb-2.0.8/third_party/waf/waflib/Logs.py | 382 -- ldb-2.0.8/third_party/waf/waflib/Node.py | 969 ---- ldb-2.0.8/third_party/waf/waflib/Options.py | 342 -- ldb-2.0.8/third_party/waf/waflib/Runner.py | 622 --- ldb-2.0.8/third_party/waf/waflib/Scripting.py | 625 --- ldb-2.0.8/third_party/waf/waflib/Task.py | 1406 ----- ldb-2.0.8/third_party/waf/waflib/TaskGen.py | 917 ---- .../third_party/waf/waflib/Tools/__init__.py | 3 - ldb-2.0.8/third_party/waf/waflib/Tools/ar.py | 24 - ldb-2.0.8/third_party/waf/waflib/Tools/asm.py | 108 - .../third_party/waf/waflib/Tools/bison.py | 49 - ldb-2.0.8/third_party/waf/waflib/Tools/c.py | 39 - .../third_party/waf/waflib/Tools/c_aliases.py | 146 - .../third_party/waf/waflib/Tools/c_config.py | 1352 ----- .../third_party/waf/waflib/Tools/c_osx.py | 193 - .../third_party/waf/waflib/Tools/c_preproc.py | 1091 ---- .../third_party/waf/waflib/Tools/c_tests.py | 230 - .../third_party/waf/waflib/Tools/ccroot.py | 791 --- .../third_party/waf/waflib/Tools/clang.py | 29 - .../third_party/waf/waflib/Tools/clangxx.py | 30 - .../waf/waflib/Tools/compiler_c.py | 110 - .../waf/waflib/Tools/compiler_cxx.py | 111 - .../waf/waflib/Tools/compiler_d.py | 85 - .../waf/waflib/Tools/compiler_fc.py | 73 - ldb-2.0.8/third_party/waf/waflib/Tools/cs.py | 211 - ldb-2.0.8/third_party/waf/waflib/Tools/cxx.py | 40 - ldb-2.0.8/third_party/waf/waflib/Tools/d.py | 97 - .../third_party/waf/waflib/Tools/d_config.py | 64 - .../third_party/waf/waflib/Tools/d_scan.py | 211 - .../third_party/waf/waflib/Tools/dbus.py | 70 - ldb-2.0.8/third_party/waf/waflib/Tools/dmd.py | 80 - .../third_party/waf/waflib/Tools/errcheck.py | 237 - ldb-2.0.8/third_party/waf/waflib/Tools/fc.py | 203 - .../third_party/waf/waflib/Tools/fc_config.py | 488 -- .../third_party/waf/waflib/Tools/fc_scan.py | 120 - .../third_party/waf/waflib/Tools/flex.py | 62 - ldb-2.0.8/third_party/waf/waflib/Tools/g95.py | 66 - ldb-2.0.8/third_party/waf/waflib/Tools/gas.py | 19 - ldb-2.0.8/third_party/waf/waflib/Tools/gcc.py | 156 - ldb-2.0.8/third_party/waf/waflib/Tools/gdc.py | 55 - .../third_party/waf/waflib/Tools/gfortran.py | 93 - .../third_party/waf/waflib/Tools/glib2.py | 489 -- .../third_party/waf/waflib/Tools/gnu_dirs.py | 131 - ldb-2.0.8/third_party/waf/waflib/Tools/gxx.py | 157 - ldb-2.0.8/third_party/waf/waflib/Tools/icc.py | 30 - .../third_party/waf/waflib/Tools/icpc.py | 30 - .../third_party/waf/waflib/Tools/ifort.py | 413 -- .../third_party/waf/waflib/Tools/intltool.py | 231 - .../third_party/waf/waflib/Tools/irixcc.py | 66 - .../third_party/waf/waflib/Tools/javaw.py | 593 --- .../third_party/waf/waflib/Tools/ldc2.py | 56 - ldb-2.0.8/third_party/waf/waflib/Tools/lua.py | 38 - .../waf/waflib/Tools/md5_tstamp.py | 41 - .../third_party/waf/waflib/Tools/msvc.py | 1020 ---- .../third_party/waf/waflib/Tools/nasm.py | 31 - .../third_party/waf/waflib/Tools/nobuild.py | 24 - .../third_party/waf/waflib/Tools/perl.py | 156 - .../third_party/waf/waflib/Tools/python.py | 644 --- ldb-2.0.8/third_party/waf/waflib/Tools/qt5.py | 800 --- .../third_party/waf/waflib/Tools/ruby.py | 186 - .../third_party/waf/waflib/Tools/suncc.py | 67 - .../third_party/waf/waflib/Tools/suncxx.py | 67 - ldb-2.0.8/third_party/waf/waflib/Tools/tex.py | 543 -- .../third_party/waf/waflib/Tools/vala.py | 355 -- .../waf/waflib/Tools/waf_unit_test.py | 296 -- .../third_party/waf/waflib/Tools/winres.py | 78 - ldb-2.0.8/third_party/waf/waflib/Tools/xlc.py | 65 - .../third_party/waf/waflib/Tools/xlcxx.py | 65 - ldb-2.0.8/third_party/waf/waflib/Utils.py | 1035 ---- ldb-2.0.8/third_party/waf/waflib/__init__.py | 3 - ldb-2.0.8/third_party/waf/waflib/ansiterm.py | 342 -- .../third_party/waf/waflib/extras/__init__.py | 3 - .../waf/waflib/extras/batched_cc.py | 173 - .../third_party/waf/waflib/extras/biber.py | 58 - .../third_party/waf/waflib/extras/bjam.py | 128 - .../third_party/waf/waflib/extras/blender.py | 108 - .../third_party/waf/waflib/extras/boo.py | 81 - .../third_party/waf/waflib/extras/boost.py | 525 -- .../waf/waflib/extras/build_file_tracker.py | 28 - .../waf/waflib/extras/build_logs.py | 110 - .../waf/waflib/extras/buildcopy.py | 85 - .../third_party/waf/waflib/extras/c_bgxlc.py | 32 - .../waf/waflib/extras/c_dumbpreproc.py | 72 - .../waf/waflib/extras/c_emscripten.py | 87 - .../third_party/waf/waflib/extras/c_nec.py | 74 - .../third_party/waf/waflib/extras/cabal.py | 152 - .../waf/waflib/extras/cfg_altoptions.py | 110 - .../extras/clang_compilation_database.py | 85 - .../waf/waflib/extras/clang_cross.py | 92 - .../waf/waflib/extras/clang_cross_common.py | 113 - .../waf/waflib/extras/clangxx_cross.py | 106 - .../third_party/waf/waflib/extras/codelite.py | 875 --- .../waf/waflib/extras/color_gcc.py | 39 - .../waf/waflib/extras/color_msvc.py | 59 - .../waf/waflib/extras/color_rvct.py | 51 - .../third_party/waf/waflib/extras/compat15.py | 406 -- .../third_party/waf/waflib/extras/cppcheck.py | 591 --- .../third_party/waf/waflib/extras/cpplint.py | 209 - .../waf/waflib/extras/cross_gnu.py | 227 - .../third_party/waf/waflib/extras/cython.py | 147 - .../third_party/waf/waflib/extras/dcc.py | 72 - .../third_party/waf/waflib/extras/distnet.py | 430 -- .../third_party/waf/waflib/extras/doxygen.py | 235 - .../third_party/waf/waflib/extras/dpapi.py | 87 - .../third_party/waf/waflib/extras/eclipse.py | 431 -- .../third_party/waf/waflib/extras/erlang.py | 110 - .../waf/waflib/extras/fast_partial.py | 531 -- .../third_party/waf/waflib/extras/fc_bgxlf.py | 32 - .../third_party/waf/waflib/extras/fc_cray.py | 51 - .../third_party/waf/waflib/extras/fc_nag.py | 61 - .../third_party/waf/waflib/extras/fc_nec.py | 60 - .../third_party/waf/waflib/extras/fc_nfort.py | 52 - .../waf/waflib/extras/fc_open64.py | 58 - .../waf/waflib/extras/fc_pgfortran.py | 68 - .../waf/waflib/extras/fc_solstudio.py | 62 - .../third_party/waf/waflib/extras/fc_xlf.py | 63 - .../waf/waflib/extras/file_to_object.py | 137 - .../third_party/waf/waflib/extras/fluid.py | 30 - .../waf/waflib/extras/freeimage.py | 74 - .../third_party/waf/waflib/extras/fsb.py | 31 - .../third_party/waf/waflib/extras/fsc.py | 64 - .../third_party/waf/waflib/extras/gccdeps.py | 214 - .../third_party/waf/waflib/extras/gdbus.py | 87 - .../waf/waflib/extras/genpybind.py | 194 - .../third_party/waf/waflib/extras/gob2.py | 17 - .../third_party/waf/waflib/extras/halide.py | 151 - .../third_party/waf/waflib/extras/javatest.py | 118 - .../third_party/waf/waflib/extras/kde4.py | 93 - .../waf/waflib/extras/local_rpath.py | 21 - .../third_party/waf/waflib/extras/make.py | 142 - .../third_party/waf/waflib/extras/midl.py | 69 - .../third_party/waf/waflib/extras/msvcdeps.py | 251 - .../third_party/waf/waflib/extras/msvs.py | 1048 ---- .../waf/waflib/extras/netcache_client.py | 390 -- .../third_party/waf/waflib/extras/objcopy.py | 53 - .../third_party/waf/waflib/extras/ocaml.py | 348 -- .../third_party/waf/waflib/extras/package.py | 76 - .../waf/waflib/extras/parallel_debug.py | 462 -- .../third_party/waf/waflib/extras/pch.py | 148 - .../third_party/waf/waflib/extras/pep8.py | 106 - .../third_party/waf/waflib/extras/pgicc.py | 75 - .../third_party/waf/waflib/extras/pgicxx.py | 20 - .../third_party/waf/waflib/extras/proc.py | 54 - .../third_party/waf/waflib/extras/protoc.py | 224 - .../third_party/waf/waflib/extras/pyqt5.py | 246 - .../third_party/waf/waflib/extras/pytest.py | 225 - .../third_party/waf/waflib/extras/qnxnto.py | 72 - .../third_party/waf/waflib/extras/qt4.py | 695 --- .../waf/waflib/extras/relocation.py | 85 - .../third_party/waf/waflib/extras/remote.py | 327 -- .../third_party/waf/waflib/extras/resx.py | 35 - .../third_party/waf/waflib/extras/review.py | 325 -- .../third_party/waf/waflib/extras/rst.py | 260 - .../waf/waflib/extras/run_do_script.py | 139 - .../waf/waflib/extras/run_m_script.py | 88 - .../waf/waflib/extras/run_py_script.py | 104 - .../waf/waflib/extras/run_r_script.py | 86 - .../third_party/waf/waflib/extras/sas.py | 71 - .../waf/waflib/extras/satellite_assembly.py | 57 - .../third_party/waf/waflib/extras/scala.py | 128 - .../third_party/waf/waflib/extras/slow_qt4.py | 96 - .../waf/waflib/extras/softlink_libs.py | 76 - .../third_party/waf/waflib/extras/sphinx.py | 81 - .../third_party/waf/waflib/extras/stale.py | 98 - .../waf/waflib/extras/stracedeps.py | 174 - .../third_party/waf/waflib/extras/swig.py | 237 - .../third_party/waf/waflib/extras/syms.py | 84 - .../third_party/waf/waflib/extras/ticgt.py | 300 -- .../third_party/waf/waflib/extras/unity.py | 108 - .../waf/waflib/extras/use_config.py | 185 - .../third_party/waf/waflib/extras/valadoc.py | 140 - .../waf/waflib/extras/waf_xattr.py | 150 - .../third_party/waf/waflib/extras/why.py | 78 - .../waf/waflib/extras/win32_opts.py | 170 - .../third_party/waf/waflib/extras/wix.py | 87 - .../third_party/waf/waflib/extras/xcode6.py | 727 --- ldb-2.0.8/third_party/waf/waflib/fixpy2.py | 64 - ldb-2.0.8/third_party/waf/waflib/processor.py | 68 - ldb-2.0.8/tools/cmdline.c | 521 -- ldb-2.0.8/tools/cmdline.h | 59 - ldb-2.0.8/tools/ldbadd.c | 186 - ldb-2.0.8/tools/ldbdel.c | 135 - ldb-2.0.8/tools/ldbdump.c | 383 -- ldb-2.0.8/tools/ldbedit.c | 383 -- ldb-2.0.8/tools/ldbmodify.c | 184 - ldb-2.0.8/tools/ldbrename.c | 85 - ldb-2.0.8/tools/ldbsearch.c | 342 -- ldb-2.0.8/tools/ldbtest.c | 438 -- ldb-2.0.8/tools/ldbutil.c | 220 - ldb-2.0.8/tools/ldbutil.h | 46 - ldb-2.0.8/web/index.html | 74 - ldb-2.0.8/wscript | 650 --- libldb.spec | 1 - 890 files changed, 226700 deletions(-) delete mode 100644 ldb-2.0.8/ABI/ldb-0.9.10.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-0.9.12.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-0.9.15.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-0.9.16.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-0.9.17.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-0.9.18.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-0.9.19.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-0.9.20.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-0.9.22.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-0.9.23.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-0.9.24.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.0.0.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.0.1.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.0.2.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.0.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.1.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.10.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.11.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.12.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.13.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.14.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.15.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.16.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.17.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.18.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.19.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.2.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.20.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.21.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.22.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.23.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.24.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.25.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.26.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.27.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.28.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.29.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.3.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.30.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.31.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.4.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.5.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.6.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.7.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.8.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.1.9.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.2.0.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.2.1.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.2.2.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.2.3.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.3.0.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.3.1.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.3.2.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.4.0.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.4.1.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.5.0.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.5.1.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.5.2.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.5.3.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.6.0.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.6.1.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.6.2.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-1.6.3.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-2.0.0.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-2.0.1.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-2.0.2.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-2.0.3.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-2.0.4.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-2.0.5.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-2.0.6.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-2.0.7.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-2.0.8.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-ildap-0.9.12.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-samba4-0.9.10.sigs delete mode 100644 ldb-2.0.8/ABI/ldb-samba4-0.9.11.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.10.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.11.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.12.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.13.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.14.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.15.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.16.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.17.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.18.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.19.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.2.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.20.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.21.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.22.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.23.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.24.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.25.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.26.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.27.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.28.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.29.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.3.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.30.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.31.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.4.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.5.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.6.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.7.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.8.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.1.9.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.2.0.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.2.1.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.2.2.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.2.3.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.3.0.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.3.1.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.3.2.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.4.0.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.4.1.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.5.0.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.5.1.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.5.2.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.5.3.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.6.0.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.6.1.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.6.2.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-1.6.3.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-2.0.0.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-2.0.1.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-2.0.2.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-2.0.3.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-2.0.4.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-2.0.5.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-2.0.6.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-2.0.7.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util-2.0.8.sigs delete mode 100644 ldb-2.0.8/ABI/pyldb-util.py3-2.0.0.sigs delete mode 100644 ldb-2.0.8/Doxyfile delete mode 100644 ldb-2.0.8/Makefile delete mode 100644 ldb-2.0.8/README_gcov.txt delete mode 100644 ldb-2.0.8/_ldb_text.py delete mode 100644 ldb-2.0.8/buildtools/README delete mode 100755 ldb-2.0.8/buildtools/bin/waf delete mode 100755 ldb-2.0.8/buildtools/compare_config_h4.sh delete mode 100755 ldb-2.0.8/buildtools/compare_generated.sh delete mode 100755 ldb-2.0.8/buildtools/compare_install.sh delete mode 100755 ldb-2.0.8/buildtools/examples/run_on_target.py delete mode 100644 ldb-2.0.8/buildtools/scripts/Makefile.waf delete mode 100755 ldb-2.0.8/buildtools/scripts/abi_gen.sh delete mode 100755 ldb-2.0.8/buildtools/scripts/autogen-waf.sh delete mode 100755 ldb-2.0.8/buildtools/scripts/configure.waf delete mode 100755 ldb-2.0.8/buildtools/testwaf.sh delete mode 100644 ldb-2.0.8/buildtools/wafsamba/README delete mode 100644 ldb-2.0.8/buildtools/wafsamba/__init__.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/configure_file.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/generic_cc.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/pkgconfig.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/samba3.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_abi.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_autoconf.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_autoproto.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_bundled.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_conftests.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_cross.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_deps.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_dist.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_git.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_headers.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_install.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_patterns.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_perl.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_pidl.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_python.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_third_party.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_utils.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_version.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_waf18.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/samba_wildcard.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/stale_files.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/symbols.py delete mode 100755 ldb-2.0.8/buildtools/wafsamba/test_duplicate_symbol.sh delete mode 100644 ldb-2.0.8/buildtools/wafsamba/tests/__init__.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/tests/test_abi.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/tests/test_bundled.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/tests/test_utils.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/wafsamba.py delete mode 100644 ldb-2.0.8/buildtools/wafsamba/wscript delete mode 100644 ldb-2.0.8/common/attrib_handlers.c delete mode 100644 ldb-2.0.8/common/ldb.c delete mode 100644 ldb-2.0.8/common/ldb_attributes.c delete mode 100644 ldb-2.0.8/common/ldb_controls.c delete mode 100644 ldb-2.0.8/common/ldb_debug.c delete mode 100644 ldb-2.0.8/common/ldb_dn.c delete mode 100644 ldb-2.0.8/common/ldb_ldif.c delete mode 100644 ldb-2.0.8/common/ldb_match.c delete mode 100644 ldb-2.0.8/common/ldb_modules.c delete mode 100644 ldb-2.0.8/common/ldb_msg.c delete mode 100644 ldb-2.0.8/common/ldb_options.c delete mode 100644 ldb-2.0.8/common/ldb_pack.c delete mode 100644 ldb-2.0.8/common/ldb_parse.c delete mode 100644 ldb-2.0.8/common/ldb_utf8.c delete mode 100644 ldb-2.0.8/common/qsort.c delete mode 100755 ldb-2.0.8/configure delete mode 100755 ldb-2.0.8/docs/builddocs.sh delete mode 100644 ldb-2.0.8/docs/design.txt delete mode 100755 ldb-2.0.8/docs/installdocs.sh delete mode 100644 ldb-2.0.8/examples.dox delete mode 100644 ldb-2.0.8/examples/ldbreader.c delete mode 100644 ldb-2.0.8/examples/ldifreader.c delete mode 100644 ldb-2.0.8/include/dlinklist.h delete mode 100644 ldb-2.0.8/include/ldb.h delete mode 100644 ldb-2.0.8/include/ldb_errors.h delete mode 100644 ldb-2.0.8/include/ldb_handlers.h delete mode 100644 ldb-2.0.8/include/ldb_module.h delete mode 100644 ldb-2.0.8/include/ldb_private.h delete mode 100644 ldb-2.0.8/ldb.pc.in delete mode 100644 ldb-2.0.8/ldb_key_value/ldb_kv.c delete mode 100644 ldb-2.0.8/ldb_key_value/ldb_kv.h delete mode 100644 ldb-2.0.8/ldb_key_value/ldb_kv_cache.c delete mode 100644 ldb-2.0.8/ldb_key_value/ldb_kv_index.c delete mode 100644 ldb-2.0.8/ldb_key_value/ldb_kv_search.c delete mode 100644 ldb-2.0.8/ldb_ldap/ldb_ldap.c delete mode 100644 ldb-2.0.8/ldb_ldb/ldb_ldb.c delete mode 100644 ldb-2.0.8/ldb_map/ldb_map.c delete mode 100644 ldb-2.0.8/ldb_map/ldb_map.h delete mode 100644 ldb-2.0.8/ldb_map/ldb_map_inbound.c delete mode 100644 ldb-2.0.8/ldb_map/ldb_map_outbound.c delete mode 100644 ldb-2.0.8/ldb_map/ldb_map_private.h delete mode 100644 ldb-2.0.8/ldb_mdb/ldb_mdb.c delete mode 100644 ldb-2.0.8/ldb_mdb/ldb_mdb.h delete mode 100644 ldb-2.0.8/ldb_mdb/ldb_mdb_init.c delete mode 100644 ldb-2.0.8/ldb_sqlite3/README delete mode 100644 ldb-2.0.8/ldb_sqlite3/base160.c delete mode 100644 ldb-2.0.8/ldb_sqlite3/ldb_sqlite3.c delete mode 100644 ldb-2.0.8/ldb_sqlite3/schema delete mode 100644 ldb-2.0.8/ldb_sqlite3/trees.ps delete mode 100644 ldb-2.0.8/ldb_tdb/ldb_tdb.c delete mode 100644 ldb-2.0.8/ldb_tdb/ldb_tdb.h delete mode 100644 ldb-2.0.8/ldb_tdb/ldb_tdb_err_map.c delete mode 100644 ldb-2.0.8/ldb_tdb/ldb_tdb_init.c delete mode 100644 ldb-2.0.8/ldb_tdb/ldb_tdb_wrap.c delete mode 100644 ldb-2.0.8/lib/replace/.checker_innocent delete mode 100644 ldb-2.0.8/lib/replace/Makefile delete mode 100644 ldb-2.0.8/lib/replace/README delete mode 100644 ldb-2.0.8/lib/replace/closefrom.c delete mode 100755 ldb-2.0.8/lib/replace/configure delete mode 100644 ldb-2.0.8/lib/replace/crypt.c delete mode 100644 ldb-2.0.8/lib/replace/cwrap.c delete mode 100644 ldb-2.0.8/lib/replace/dlfcn.c delete mode 100644 ldb-2.0.8/lib/replace/getaddrinfo.c delete mode 100644 ldb-2.0.8/lib/replace/getaddrinfo.h delete mode 100644 ldb-2.0.8/lib/replace/getifaddrs.c delete mode 100644 ldb-2.0.8/lib/replace/hdr_replace.h delete mode 100644 ldb-2.0.8/lib/replace/inet_aton.c delete mode 100644 ldb-2.0.8/lib/replace/inet_ntoa.c delete mode 100644 ldb-2.0.8/lib/replace/inet_ntop.c delete mode 100644 ldb-2.0.8/lib/replace/inet_pton.c delete mode 100644 ldb-2.0.8/lib/replace/poll.c delete mode 100644 ldb-2.0.8/lib/replace/replace-test.h delete mode 100644 ldb-2.0.8/lib/replace/replace-testsuite.h delete mode 100644 ldb-2.0.8/lib/replace/replace.c delete mode 100644 ldb-2.0.8/lib/replace/replace.h delete mode 100644 ldb-2.0.8/lib/replace/snprintf.c delete mode 100644 ldb-2.0.8/lib/replace/socket.c delete mode 100644 ldb-2.0.8/lib/replace/socketpair.c delete mode 100644 ldb-2.0.8/lib/replace/strptime.c delete mode 100644 ldb-2.0.8/lib/replace/system/README delete mode 100644 ldb-2.0.8/lib/replace/system/aio.h delete mode 100644 ldb-2.0.8/lib/replace/system/capability.h delete mode 100644 ldb-2.0.8/lib/replace/system/dir.h delete mode 100644 ldb-2.0.8/lib/replace/system/filesys.h delete mode 100644 ldb-2.0.8/lib/replace/system/glob.h delete mode 100644 ldb-2.0.8/lib/replace/system/gssapi.h delete mode 100644 ldb-2.0.8/lib/replace/system/iconv.h delete mode 100644 ldb-2.0.8/lib/replace/system/kerberos.h delete mode 100644 ldb-2.0.8/lib/replace/system/locale.h delete mode 100644 ldb-2.0.8/lib/replace/system/network.h delete mode 100644 ldb-2.0.8/lib/replace/system/nis.h delete mode 100644 ldb-2.0.8/lib/replace/system/passwd.h delete mode 100644 ldb-2.0.8/lib/replace/system/readline.h delete mode 100644 ldb-2.0.8/lib/replace/system/select.h delete mode 100644 ldb-2.0.8/lib/replace/system/shmem.h delete mode 100644 ldb-2.0.8/lib/replace/system/syslog.h delete mode 100644 ldb-2.0.8/lib/replace/system/terminal.h delete mode 100644 ldb-2.0.8/lib/replace/system/threads.h delete mode 100644 ldb-2.0.8/lib/replace/system/time.h delete mode 100644 ldb-2.0.8/lib/replace/system/wait.h delete mode 100644 ldb-2.0.8/lib/replace/system/wscript_configure delete mode 100644 ldb-2.0.8/lib/replace/tests/getifaddrs.c delete mode 100644 ldb-2.0.8/lib/replace/tests/incoherent_mmap.c delete mode 100644 ldb-2.0.8/lib/replace/tests/main.c delete mode 100644 ldb-2.0.8/lib/replace/tests/os2_delete.c delete mode 100644 ldb-2.0.8/lib/replace/tests/shared_mmap.c delete mode 100644 ldb-2.0.8/lib/replace/tests/shared_mremap.c delete mode 100644 ldb-2.0.8/lib/replace/tests/snprintf.c delete mode 100644 ldb-2.0.8/lib/replace/tests/strptime.c delete mode 100644 ldb-2.0.8/lib/replace/tests/testsuite.c delete mode 100644 ldb-2.0.8/lib/replace/timegm.c delete mode 100644 ldb-2.0.8/lib/replace/win32_replace.h delete mode 100644 ldb-2.0.8/lib/replace/wscript delete mode 100644 ldb-2.0.8/lib/replace/xattr.c delete mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.6.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.7.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.8.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.0.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.1.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.10.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.11.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.12.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.13.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.14.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.15.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.16.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.2.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.3.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.4.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.5.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.6.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.7.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.8.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.9.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.2.0.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.0.2.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.0.3.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.0.4.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.0.5.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.0.6.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.0.7.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.0.8.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.0.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.1.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.10.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.11.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.12.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.13.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.14.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.15.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.16.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.2.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.3.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.4.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.5.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.6.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.7.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.8.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.1.9.sigs delete mode 100644 ldb-2.0.8/lib/talloc/ABI/talloc-2.2.0.sigs delete mode 100644 ldb-2.0.8/lib/talloc/Makefile delete mode 100644 ldb-2.0.8/lib/talloc/NEWS delete mode 100644 ldb-2.0.8/lib/talloc/compat/talloc_compat1.c delete mode 100644 ldb-2.0.8/lib/talloc/compat/talloc_compat1.mk delete mode 100755 ldb-2.0.8/lib/talloc/configure delete mode 100644 ldb-2.0.8/lib/talloc/doc/context.png delete mode 100644 ldb-2.0.8/lib/talloc/doc/context_tree.png delete mode 100644 ldb-2.0.8/lib/talloc/doc/mainpage.dox delete mode 100644 ldb-2.0.8/lib/talloc/doc/stealing.png delete mode 100644 ldb-2.0.8/lib/talloc/doc/tutorial_bestpractices.dox delete mode 100644 ldb-2.0.8/lib/talloc/doc/tutorial_context.dox delete mode 100644 ldb-2.0.8/lib/talloc/doc/tutorial_debugging.dox delete mode 100644 ldb-2.0.8/lib/talloc/doc/tutorial_destructors.dox delete mode 100644 ldb-2.0.8/lib/talloc/doc/tutorial_dts.dox delete mode 100644 ldb-2.0.8/lib/talloc/doc/tutorial_introduction.dox delete mode 100644 ldb-2.0.8/lib/talloc/doc/tutorial_pools.dox delete mode 100644 ldb-2.0.8/lib/talloc/doc/tutorial_stealing.dox delete mode 100644 ldb-2.0.8/lib/talloc/doc/tutorial_threads.dox delete mode 100644 ldb-2.0.8/lib/talloc/doxy.config delete mode 100644 ldb-2.0.8/lib/talloc/man/talloc.3.xml delete mode 100644 ldb-2.0.8/lib/talloc/pytalloc-util.pc.in delete mode 100644 ldb-2.0.8/lib/talloc/pytalloc.c delete mode 100644 ldb-2.0.8/lib/talloc/pytalloc.h delete mode 100644 ldb-2.0.8/lib/talloc/pytalloc_guide.txt delete mode 100644 ldb-2.0.8/lib/talloc/pytalloc_private.h delete mode 100644 ldb-2.0.8/lib/talloc/pytalloc_util.c delete mode 100644 ldb-2.0.8/lib/talloc/talloc.c delete mode 100644 ldb-2.0.8/lib/talloc/talloc.h delete mode 100644 ldb-2.0.8/lib/talloc/talloc.pc.in delete mode 100644 ldb-2.0.8/lib/talloc/talloc_guide.txt delete mode 100644 ldb-2.0.8/lib/talloc/talloc_testsuite.h delete mode 100755 ldb-2.0.8/lib/talloc/test_magic_differs.sh delete mode 100644 ldb-2.0.8/lib/talloc/test_magic_differs_helper.c delete mode 100644 ldb-2.0.8/lib/talloc/test_pytalloc.c delete mode 100644 ldb-2.0.8/lib/talloc/test_pytalloc.py delete mode 100644 ldb-2.0.8/lib/talloc/testsuite.c delete mode 100644 ldb-2.0.8/lib/talloc/testsuite_main.c delete mode 100644 ldb-2.0.8/lib/talloc/web/index.html delete mode 100644 ldb-2.0.8/lib/talloc/wscript delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.1.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.10.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.11.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.12.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.13.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.2.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.3.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.4.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.5.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.6.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.7.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.8.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.2.9.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.0.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.1.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.10.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.11.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.12.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.13.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.14.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.15.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.16.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.17.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.18.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.2.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.3.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.4.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.5.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.6.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.7.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.8.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.3.9.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.4.0.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.4.1.sigs delete mode 100644 ldb-2.0.8/lib/tdb/ABI/tdb-1.4.2.sigs delete mode 100644 ldb-2.0.8/lib/tdb/Makefile delete mode 100644 ldb-2.0.8/lib/tdb/_tdb_text.py delete mode 100644 ldb-2.0.8/lib/tdb/common/check.c delete mode 100644 ldb-2.0.8/lib/tdb/common/dump.c delete mode 100644 ldb-2.0.8/lib/tdb/common/error.c delete mode 100644 ldb-2.0.8/lib/tdb/common/freelist.c delete mode 100644 ldb-2.0.8/lib/tdb/common/freelistcheck.c delete mode 100644 ldb-2.0.8/lib/tdb/common/hash.c delete mode 100644 ldb-2.0.8/lib/tdb/common/io.c delete mode 100644 ldb-2.0.8/lib/tdb/common/lock.c delete mode 100644 ldb-2.0.8/lib/tdb/common/mutex.c delete mode 100644 ldb-2.0.8/lib/tdb/common/open.c delete mode 100644 ldb-2.0.8/lib/tdb/common/rescue.c delete mode 100644 ldb-2.0.8/lib/tdb/common/summary.c delete mode 100644 ldb-2.0.8/lib/tdb/common/tdb.c delete mode 100644 ldb-2.0.8/lib/tdb/common/tdb_private.h delete mode 100644 ldb-2.0.8/lib/tdb/common/transaction.c delete mode 100644 ldb-2.0.8/lib/tdb/common/traverse.c delete mode 100755 ldb-2.0.8/lib/tdb/configure delete mode 100644 ldb-2.0.8/lib/tdb/docs/README delete mode 100644 ldb-2.0.8/lib/tdb/docs/mainpage.dox delete mode 100644 ldb-2.0.8/lib/tdb/docs/mutex.txt delete mode 100644 ldb-2.0.8/lib/tdb/docs/tdb.magic delete mode 100644 ldb-2.0.8/lib/tdb/docs/tracing.txt delete mode 100644 ldb-2.0.8/lib/tdb/doxy.config delete mode 100644 ldb-2.0.8/lib/tdb/include/tdb.h delete mode 100644 ldb-2.0.8/lib/tdb/man/tdbbackup.8.xml delete mode 100644 ldb-2.0.8/lib/tdb/man/tdbdump.8.xml delete mode 100644 ldb-2.0.8/lib/tdb/man/tdbrestore.8.xml delete mode 100644 ldb-2.0.8/lib/tdb/man/tdbtool.8.xml delete mode 100644 ldb-2.0.8/lib/tdb/pytdb.c delete mode 100644 ldb-2.0.8/lib/tdb/python/tdbdump.py delete mode 100644 ldb-2.0.8/lib/tdb/python/tests/simple.py delete mode 100644 ldb-2.0.8/lib/tdb/tdb.pc.in delete mode 100644 ldb-2.0.8/lib/tdb/test/circular_chain.tdb delete mode 100644 ldb-2.0.8/lib/tdb/test/circular_freelist.tdb delete mode 100644 ldb-2.0.8/lib/tdb/test/external-agent.c delete mode 100644 ldb-2.0.8/lib/tdb/test/external-agent.h delete mode 100644 ldb-2.0.8/lib/tdb/test/jenkins-be-hash.tdb delete mode 100644 ldb-2.0.8/lib/tdb/test/jenkins-le-hash.tdb delete mode 100644 ldb-2.0.8/lib/tdb/test/lock-tracking.c delete mode 100644 ldb-2.0.8/lib/tdb/test/lock-tracking.h delete mode 100644 ldb-2.0.8/lib/tdb/test/logging.c delete mode 100644 ldb-2.0.8/lib/tdb/test/logging.h delete mode 100644 ldb-2.0.8/lib/tdb/test/old-nohash-be.tdb delete mode 100644 ldb-2.0.8/lib/tdb/test/old-nohash-le.tdb delete mode 100644 ldb-2.0.8/lib/tdb/test/run-3G-file.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-allrecord-traverse-deadlock.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-bad-tdb-header.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-check.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-circular-chain.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-circular-freelist.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-corrupt.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-die-during-transaction.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-endian.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-fcntl-deadlock.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-incompatible.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-marklock-deadlock.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-bench.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-block.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-trylock.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-mutex-die.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-mutex-openflags2.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-mutex-transaction1.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-mutex-trylock.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-mutex1.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-nested-transactions.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-nested-traverse.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-no-lock-during-traverse.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-oldhash.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-open-during-transaction.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-rdlock-upgrade.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-readonly-check.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-rescue-find_entry.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-rescue.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-rwlock-check.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-summary.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-transaction-expand.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-traverse-chain.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-traverse-in-transaction.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-wronghash-fail.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run-zero-append.c delete mode 100644 ldb-2.0.8/lib/tdb/test/run.c delete mode 100644 ldb-2.0.8/lib/tdb/test/rwlock-be.tdb delete mode 100644 ldb-2.0.8/lib/tdb/test/rwlock-le.tdb delete mode 100644 ldb-2.0.8/lib/tdb/test/sample_tdb.tdb delete mode 100644 ldb-2.0.8/lib/tdb/test/tap-interface.h delete mode 100644 ldb-2.0.8/lib/tdb/test/tap-to-subunit.h delete mode 100644 ldb-2.0.8/lib/tdb/test/tdb.corrupt delete mode 100755 ldb-2.0.8/lib/tdb/test/test_tdbbackup.sh delete mode 100644 ldb-2.0.8/lib/tdb/tools/tdbbackup.c delete mode 100644 ldb-2.0.8/lib/tdb/tools/tdbdump.c delete mode 100644 ldb-2.0.8/lib/tdb/tools/tdbrestore.c delete mode 100644 ldb-2.0.8/lib/tdb/tools/tdbtest.c delete mode 100644 ldb-2.0.8/lib/tdb/tools/tdbtool.c delete mode 100644 ldb-2.0.8/lib/tdb/tools/tdbtorture.c delete mode 100644 ldb-2.0.8/lib/tdb/web/index.html delete mode 100644 ldb-2.0.8/lib/tdb/wscript delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.10.0.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.10.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.11.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.12.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.13.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.14.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.15.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.16.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.17.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.18.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.19.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.20.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.21.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.22.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.23.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.24.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.25.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.26.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.27.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.28.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.29.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.30.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.31.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.32.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.33.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.34.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.35.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.36.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.37.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.38.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.39.sigs delete mode 100644 ldb-2.0.8/lib/tevent/ABI/tevent-0.9.9.sigs delete mode 100644 ldb-2.0.8/lib/tevent/Makefile delete mode 100644 ldb-2.0.8/lib/tevent/bindings.py delete mode 100755 ldb-2.0.8/lib/tevent/configure delete mode 100644 ldb-2.0.8/lib/tevent/doc/img/tevent_context_stucture.png delete mode 100644 ldb-2.0.8/lib/tevent/doc/img/tevent_subrequest.png delete mode 100644 ldb-2.0.8/lib/tevent/doc/mainpage.dox delete mode 100644 ldb-2.0.8/lib/tevent/doc/tevent_context.dox delete mode 100644 ldb-2.0.8/lib/tevent/doc/tevent_data.dox delete mode 100644 ldb-2.0.8/lib/tevent/doc/tevent_events.dox delete mode 100644 ldb-2.0.8/lib/tevent/doc/tevent_queue.dox delete mode 100644 ldb-2.0.8/lib/tevent/doc/tevent_request.dox delete mode 100644 ldb-2.0.8/lib/tevent/doc/tevent_thread.dox delete mode 100644 ldb-2.0.8/lib/tevent/doc/tevent_tutorial.dox delete mode 100644 ldb-2.0.8/lib/tevent/doc/tutorials.dox delete mode 100644 ldb-2.0.8/lib/tevent/doxy.config delete mode 100644 ldb-2.0.8/lib/tevent/echo_server.c delete mode 100644 ldb-2.0.8/lib/tevent/pytevent.c delete mode 100644 ldb-2.0.8/lib/tevent/test_req.c delete mode 100644 ldb-2.0.8/lib/tevent/testsuite.c delete mode 100644 ldb-2.0.8/lib/tevent/tevent.c delete mode 100644 ldb-2.0.8/lib/tevent/tevent.h delete mode 100644 ldb-2.0.8/lib/tevent/tevent.pc.in delete mode 100644 ldb-2.0.8/lib/tevent/tevent.py delete mode 100644 ldb-2.0.8/lib/tevent/tevent_debug.c delete mode 100644 ldb-2.0.8/lib/tevent/tevent_epoll.c delete mode 100644 ldb-2.0.8/lib/tevent/tevent_fd.c delete mode 100644 ldb-2.0.8/lib/tevent/tevent_immediate.c delete mode 100644 ldb-2.0.8/lib/tevent/tevent_internal.h delete mode 100644 ldb-2.0.8/lib/tevent/tevent_liboop.c delete mode 100644 ldb-2.0.8/lib/tevent/tevent_poll.c delete mode 100644 ldb-2.0.8/lib/tevent/tevent_port.c delete mode 100644 ldb-2.0.8/lib/tevent/tevent_queue.c delete mode 100644 ldb-2.0.8/lib/tevent/tevent_req.c delete mode 100644 ldb-2.0.8/lib/tevent/tevent_signal.c delete mode 100644 ldb-2.0.8/lib/tevent/tevent_standard.c delete mode 100644 ldb-2.0.8/lib/tevent/tevent_threads.c delete mode 100644 ldb-2.0.8/lib/tevent/tevent_timed.c delete mode 100644 ldb-2.0.8/lib/tevent/tevent_util.c delete mode 100644 ldb-2.0.8/lib/tevent/tevent_util.h delete mode 100644 ldb-2.0.8/lib/tevent/tevent_wakeup.c delete mode 100644 ldb-2.0.8/lib/tevent/tevent_wrapper.c delete mode 100644 ldb-2.0.8/lib/tevent/wscript delete mode 100644 ldb-2.0.8/lib/util/attr.h delete mode 100644 ldb-2.0.8/lib/util/binsearch.h delete mode 100644 ldb-2.0.8/mainpage.dox delete mode 100644 ldb-2.0.8/man/ldb.3.xml delete mode 100644 ldb-2.0.8/man/ldbadd.1.xml delete mode 100644 ldb-2.0.8/man/ldbdel.1.xml delete mode 100644 ldb-2.0.8/man/ldbedit.1.xml delete mode 100644 ldb-2.0.8/man/ldbmodify.1.xml delete mode 100644 ldb-2.0.8/man/ldbrename.1.xml delete mode 100644 ldb-2.0.8/man/ldbsearch.1.xml delete mode 100644 ldb-2.0.8/modules/asq.c delete mode 100644 ldb-2.0.8/modules/paged_searches.c delete mode 100644 ldb-2.0.8/modules/rdn_name.c delete mode 100644 ldb-2.0.8/modules/skel.c delete mode 100644 ldb-2.0.8/modules/sort.c delete mode 100644 ldb-2.0.8/nssldb/README.txt delete mode 100644 ldb-2.0.8/nssldb/ldb-grp.c delete mode 100644 ldb-2.0.8/nssldb/ldb-nss.c delete mode 100644 ldb-2.0.8/nssldb/ldb-nss.h delete mode 100644 ldb-2.0.8/nssldb/ldb-pwd.c delete mode 100644 ldb-2.0.8/pyldb-util.pc.in delete mode 100644 ldb-2.0.8/pyldb.c delete mode 100644 ldb-2.0.8/pyldb.h delete mode 100644 ldb-2.0.8/pyldb_util.c delete mode 100644 ldb-2.0.8/tests/guidindexpackv1.ldb delete mode 100644 ldb-2.0.8/tests/init.ldif delete mode 100755 ldb-2.0.8/tests/init_slapd.sh delete mode 100755 ldb-2.0.8/tests/kill_slapd.sh delete mode 100755 ldb-2.0.8/tests/ldapi_url.sh delete mode 100644 ldb-2.0.8/tests/ldb_filter_attrs_test.c delete mode 100644 ldb-2.0.8/tests/ldb_key_value_sub_txn_mdb_test.valgrind delete mode 100644 ldb-2.0.8/tests/ldb_key_value_sub_txn_test.c delete mode 100644 ldb-2.0.8/tests/ldb_key_value_test.c delete mode 100644 ldb-2.0.8/tests/ldb_kv_ops_test.c delete mode 100644 ldb-2.0.8/tests/ldb_kv_ops_test.valgrind delete mode 100644 ldb-2.0.8/tests/ldb_lmdb_size_test.c delete mode 100644 ldb-2.0.8/tests/ldb_lmdb_test.c delete mode 100644 ldb-2.0.8/tests/ldb_match_test.c delete mode 100644 ldb-2.0.8/tests/ldb_match_test.valgrind delete mode 100644 ldb-2.0.8/tests/ldb_mod_op_test.c delete mode 100644 ldb-2.0.8/tests/ldb_msg.c delete mode 100644 ldb-2.0.8/tests/ldb_no_lmdb_test.c delete mode 100644 ldb-2.0.8/tests/ldb_parse_test.c delete mode 100644 ldb-2.0.8/tests/ldb_tdb_test.c delete mode 100644 ldb-2.0.8/tests/photo.ldif delete mode 100755 ldb-2.0.8/tests/python/api.py delete mode 100755 ldb-2.0.8/tests/python/index.py delete mode 100644 ldb-2.0.8/tests/python/repack.py delete mode 100644 ldb-2.0.8/tests/samba4.png delete mode 100644 ldb-2.0.8/tests/sample_module.c delete mode 100644 ldb-2.0.8/tests/schema-tests/schema-add-test.ldif delete mode 100644 ldb-2.0.8/tests/schema-tests/schema-mod-test-1.ldif delete mode 100644 ldb-2.0.8/tests/schema-tests/schema-mod-test-2.ldif delete mode 100644 ldb-2.0.8/tests/schema-tests/schema-mod-test-3.ldif delete mode 100644 ldb-2.0.8/tests/schema-tests/schema-mod-test-4.ldif delete mode 100644 ldb-2.0.8/tests/schema-tests/schema-mod-test-5.ldif delete mode 100644 ldb-2.0.8/tests/schema-tests/schema.ldif delete mode 100644 ldb-2.0.8/tests/slapd.conf delete mode 100755 ldb-2.0.8/tests/start_slapd.sh delete mode 100644 ldb-2.0.8/tests/test-attribs.ldif delete mode 100644 ldb-2.0.8/tests/test-config.ldif delete mode 100755 ldb-2.0.8/tests/test-controls.sh delete mode 100644 ldb-2.0.8/tests/test-default-config.ldif delete mode 100644 ldb-2.0.8/tests/test-dup-2.ldif delete mode 100644 ldb-2.0.8/tests/test-dup.ldif delete mode 100755 ldb-2.0.8/tests/test-extended.sh delete mode 100755 ldb-2.0.8/tests/test-generic.sh delete mode 100644 ldb-2.0.8/tests/test-index.ldif delete mode 100755 ldb-2.0.8/tests/test-ldap.sh delete mode 100644 ldb-2.0.8/tests/test-modify-modrdn.ldif delete mode 100644 ldb-2.0.8/tests/test-modify-unmet-2.ldif delete mode 100644 ldb-2.0.8/tests/test-modify-unmet.ldif delete mode 100644 ldb-2.0.8/tests/test-modify.ldif delete mode 100755 ldb-2.0.8/tests/test-schema.sh delete mode 100755 ldb-2.0.8/tests/test-soloading.sh delete mode 100755 ldb-2.0.8/tests/test-sqlite3.sh delete mode 100644 ldb-2.0.8/tests/test-tdb-features.sh delete mode 100755 ldb-2.0.8/tests/test-tdb-subunit.sh delete mode 100755 ldb-2.0.8/tests/test-tdb.sh delete mode 100644 ldb-2.0.8/tests/test-wildcard.ldif delete mode 100644 ldb-2.0.8/tests/test-wrong_attributes.ldif delete mode 100644 ldb-2.0.8/tests/test.ldif delete mode 100644 ldb-2.0.8/tests/test_ldb_dn.c delete mode 100644 ldb-2.0.8/tests/test_ldb_qsort.c delete mode 100644 ldb-2.0.8/tests/testdata.txt delete mode 100644 ldb-2.0.8/tests/testsearch.txt delete mode 100644 ldb-2.0.8/third_party/cmocka/cmocka.c delete mode 100644 ldb-2.0.8/third_party/cmocka/cmocka.h delete mode 100644 ldb-2.0.8/third_party/cmocka/cmocka_private.h delete mode 100644 ldb-2.0.8/third_party/cmocka/wscript delete mode 100644 ldb-2.0.8/third_party/popt/CHANGES delete mode 100644 ldb-2.0.8/third_party/popt/COPYING delete mode 100644 ldb-2.0.8/third_party/popt/README delete mode 100644 ldb-2.0.8/third_party/popt/findme.h delete mode 100644 ldb-2.0.8/third_party/popt/lookup3.c delete mode 100644 ldb-2.0.8/third_party/popt/popt.c delete mode 100644 ldb-2.0.8/third_party/popt/popt.h delete mode 100644 ldb-2.0.8/third_party/popt/poptconfig.c delete mode 100644 ldb-2.0.8/third_party/popt/popthelp.c delete mode 100644 ldb-2.0.8/third_party/popt/poptint.c delete mode 100644 ldb-2.0.8/third_party/popt/poptint.h delete mode 100644 ldb-2.0.8/third_party/popt/poptparse.c delete mode 100644 ldb-2.0.8/third_party/popt/system.h delete mode 100644 ldb-2.0.8/third_party/popt/wscript delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Build.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/ConfigSet.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Configure.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Context.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Errors.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Logs.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Node.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Options.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Runner.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Scripting.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Task.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/TaskGen.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/__init__.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/ar.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/asm.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/bison.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/c.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/c_aliases.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/c_config.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/c_osx.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/c_preproc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/c_tests.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/ccroot.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/clang.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/clangxx.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/compiler_c.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/compiler_cxx.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/compiler_d.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/compiler_fc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/cs.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/cxx.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/d.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/d_config.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/d_scan.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/dbus.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/dmd.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/errcheck.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/fc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/fc_config.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/fc_scan.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/flex.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/g95.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/gas.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/gcc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/gdc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/gfortran.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/glib2.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/gnu_dirs.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/gxx.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/icc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/icpc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/ifort.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/intltool.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/irixcc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/javaw.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/ldc2.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/lua.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/md5_tstamp.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/msvc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/nasm.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/nobuild.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/perl.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/python.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/qt5.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/ruby.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/suncc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/suncxx.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/tex.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/vala.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/waf_unit_test.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/winres.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/xlc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Tools/xlcxx.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/Utils.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/__init__.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/ansiterm.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/__init__.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/batched_cc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/biber.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/bjam.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/blender.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/boo.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/boost.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/build_file_tracker.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/build_logs.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/buildcopy.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/c_bgxlc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/c_dumbpreproc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/c_emscripten.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/c_nec.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/cabal.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/cfg_altoptions.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/clang_compilation_database.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/clang_cross.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/clang_cross_common.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/clangxx_cross.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/codelite.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/color_gcc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/color_msvc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/color_rvct.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/compat15.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/cppcheck.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/cpplint.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/cross_gnu.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/cython.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/dcc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/distnet.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/doxygen.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/dpapi.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/eclipse.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/erlang.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fast_partial.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fc_bgxlf.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fc_cray.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fc_nag.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fc_nec.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fc_nfort.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fc_open64.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fc_pgfortran.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fc_solstudio.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fc_xlf.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/file_to_object.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fluid.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/freeimage.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fsb.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/fsc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/gccdeps.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/gdbus.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/genpybind.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/gob2.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/halide.py delete mode 100755 ldb-2.0.8/third_party/waf/waflib/extras/javatest.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/kde4.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/local_rpath.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/make.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/midl.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/msvcdeps.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/msvs.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/netcache_client.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/objcopy.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/ocaml.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/package.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/parallel_debug.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/pch.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/pep8.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/pgicc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/pgicxx.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/proc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/protoc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/pyqt5.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/pytest.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/qnxnto.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/qt4.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/relocation.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/remote.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/resx.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/review.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/rst.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/run_do_script.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/run_m_script.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/run_py_script.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/run_r_script.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/sas.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/satellite_assembly.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/scala.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/slow_qt4.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/softlink_libs.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/sphinx.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/stale.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/stracedeps.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/swig.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/syms.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/ticgt.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/unity.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/use_config.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/valadoc.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/waf_xattr.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/why.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/win32_opts.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/wix.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/extras/xcode6.py delete mode 100644 ldb-2.0.8/third_party/waf/waflib/fixpy2.py delete mode 100755 ldb-2.0.8/third_party/waf/waflib/processor.py delete mode 100644 ldb-2.0.8/tools/cmdline.c delete mode 100644 ldb-2.0.8/tools/cmdline.h delete mode 100644 ldb-2.0.8/tools/ldbadd.c delete mode 100644 ldb-2.0.8/tools/ldbdel.c delete mode 100644 ldb-2.0.8/tools/ldbdump.c delete mode 100644 ldb-2.0.8/tools/ldbedit.c delete mode 100644 ldb-2.0.8/tools/ldbmodify.c delete mode 100644 ldb-2.0.8/tools/ldbrename.c delete mode 100644 ldb-2.0.8/tools/ldbsearch.c delete mode 100644 ldb-2.0.8/tools/ldbtest.c delete mode 100644 ldb-2.0.8/tools/ldbutil.c delete mode 100644 ldb-2.0.8/tools/ldbutil.h delete mode 100644 ldb-2.0.8/web/index.html delete mode 100644 ldb-2.0.8/wscript diff --git a/ldb-2.0.8/ABI/ldb-0.9.10.sigs b/ldb-2.0.8/ABI/ldb-0.9.10.sigs deleted file mode 100644 index 012ac65..0000000 --- a/ldb-2.0.8/ABI/ldb-0.9.10.sigs +++ /dev/null @@ -1,218 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(void *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(void *, const char *, int) -ldb_binary_decode: struct ldb_val (void *, const char *) -ldb_binary_encode: char *(void *, struct ldb_val) -ldb_binary_encode_string: char *(void *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, void *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, void *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, void *, const char *, size_t) -ldb_casefold_default: char *(void *, void *, const char *, size_t) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(void *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) -ldb_dn_canonical_string: char *(void *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(void *, struct ldb_dn *) -ldb_dn_escape_value: char *(void *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(void *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(void *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(void *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(void *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(void *, struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_init_module_chain: int (struct ldb_context *, struct ldb_module *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(void *) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(void *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (void *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-0.9.12.sigs b/ldb-2.0.8/ABI/ldb-0.9.12.sigs deleted file mode 100644 index 2206e79..0000000 --- a/ldb-2.0.8/ABI/ldb-0.9.12.sigs +++ /dev/null @@ -1,219 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(void *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(void *, const char *, int) -ldb_binary_decode: struct ldb_val (void *, const char *) -ldb_binary_encode: char *(void *, struct ldb_val) -ldb_binary_encode_string: char *(void *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, void *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, void *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, void *, const char *, size_t) -ldb_casefold_default: char *(void *, void *, const char *, size_t) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(void *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) -ldb_dn_canonical_string: char *(void *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(void *, struct ldb_dn *) -ldb_dn_escape_value: char *(void *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(void *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(void *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(void *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(void *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(void *, struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_init_module_chain: int (struct ldb_context *, struct ldb_module *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(void *) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(void *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (void *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-0.9.15.sigs b/ldb-2.0.8/ABI/ldb-0.9.15.sigs deleted file mode 100644 index 39d2f3e..0000000 --- a/ldb-2.0.8/ABI/ldb-0.9.15.sigs +++ /dev/null @@ -1,226 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_init_module_chain: int (struct ldb_context *, struct ldb_module *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-0.9.16.sigs b/ldb-2.0.8/ABI/ldb-0.9.16.sigs deleted file mode 100644 index 610a0a4..0000000 --- a/ldb-2.0.8/ABI/ldb-0.9.16.sigs +++ /dev/null @@ -1,228 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_init_module_chain: int (struct ldb_context *, struct ldb_module *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-0.9.17.sigs b/ldb-2.0.8/ABI/ldb-0.9.17.sigs deleted file mode 100644 index d0f5699..0000000 --- a/ldb-2.0.8/ABI/ldb-0.9.17.sigs +++ /dev/null @@ -1,229 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_init_module_chain: int (struct ldb_context *, struct ldb_module *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-0.9.18.sigs b/ldb-2.0.8/ABI/ldb-0.9.18.sigs deleted file mode 100644 index 15913c9..0000000 --- a/ldb-2.0.8/ABI/ldb-0.9.18.sigs +++ /dev/null @@ -1,240 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_asq_init: int (const char *) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_init_module_chain: int (struct ldb_context *, struct ldb_module *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_paged_results_init: int (const char *) -ldb_paged_searches_init: int (const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_rdn_name_init: int (const char *) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_sample_init: int (const char *) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_server_sort_init: int (const char *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_skel_init: int (const char *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_tdb_init: int (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-0.9.19.sigs b/ldb-2.0.8/ABI/ldb-0.9.19.sigs deleted file mode 100644 index 6273870..0000000 --- a/ldb-2.0.8/ABI/ldb-0.9.19.sigs +++ /dev/null @@ -1,245 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_asq_init: int (const char *) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_paged_results_init: int (const char *) -ldb_paged_searches_init: int (const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_rdn_name_init: int (const char *) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_sample_init: int (const char *) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_server_sort_init: int (const char *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_skel_init: int (const char *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_tdb_init: int (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-0.9.20.sigs b/ldb-2.0.8/ABI/ldb-0.9.20.sigs deleted file mode 100644 index 6273870..0000000 --- a/ldb-2.0.8/ABI/ldb-0.9.20.sigs +++ /dev/null @@ -1,245 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_asq_init: int (const char *) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_paged_results_init: int (const char *) -ldb_paged_searches_init: int (const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_rdn_name_init: int (const char *) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_sample_init: int (const char *) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_server_sort_init: int (const char *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_skel_init: int (const char *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_tdb_init: int (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-0.9.22.sigs b/ldb-2.0.8/ABI/ldb-0.9.22.sigs deleted file mode 100644 index b5a69c1..0000000 --- a/ldb-2.0.8/ABI/ldb-0.9.22.sigs +++ /dev/null @@ -1,245 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-0.9.23.sigs b/ldb-2.0.8/ABI/ldb-0.9.23.sigs deleted file mode 100644 index 73e5caa..0000000 --- a/ldb-2.0.8/ABI/ldb-0.9.23.sigs +++ /dev/null @@ -1,247 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-0.9.24.sigs b/ldb-2.0.8/ABI/ldb-0.9.24.sigs deleted file mode 100644 index 5cb32f7..0000000 --- a/ldb-2.0.8/ABI/ldb-0.9.24.sigs +++ /dev/null @@ -1,248 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.0.0.sigs b/ldb-2.0.8/ABI/ldb-1.0.0.sigs deleted file mode 100644 index 5cb32f7..0000000 --- a/ldb-2.0.8/ABI/ldb-1.0.0.sigs +++ /dev/null @@ -1,248 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.0.1.sigs b/ldb-2.0.8/ABI/ldb-1.0.1.sigs deleted file mode 100644 index 5cb32f7..0000000 --- a/ldb-2.0.8/ABI/ldb-1.0.1.sigs +++ /dev/null @@ -1,248 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.0.2.sigs b/ldb-2.0.8/ABI/ldb-1.0.2.sigs deleted file mode 100644 index c13ac87..0000000 --- a/ldb-2.0.8/ABI/ldb-1.0.2.sigs +++ /dev/null @@ -1,250 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.0.sigs b/ldb-2.0.8/ABI/ldb-1.1.0.sigs deleted file mode 100644 index 149d4bc..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.0.sigs +++ /dev/null @@ -1,253 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.1.sigs b/ldb-2.0.8/ABI/ldb-1.1.1.sigs deleted file mode 100644 index 2fe215c..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.1.sigs +++ /dev/null @@ -1,254 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.10.sigs b/ldb-2.0.8/ABI/ldb-1.1.10.sigs deleted file mode 100644 index de5026e..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.10.sigs +++ /dev/null @@ -1,259 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.11.sigs b/ldb-2.0.8/ABI/ldb-1.1.11.sigs deleted file mode 100644 index de5026e..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.11.sigs +++ /dev/null @@ -1,259 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.12.sigs b/ldb-2.0.8/ABI/ldb-1.1.12.sigs deleted file mode 100644 index c8ccd25..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.12.sigs +++ /dev/null @@ -1,260 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.13.sigs b/ldb-2.0.8/ABI/ldb-1.1.13.sigs deleted file mode 100644 index c8ccd25..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.13.sigs +++ /dev/null @@ -1,260 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.14.sigs b/ldb-2.0.8/ABI/ldb-1.1.14.sigs deleted file mode 100644 index eac5194..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.14.sigs +++ /dev/null @@ -1,262 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.15.sigs b/ldb-2.0.8/ABI/ldb-1.1.15.sigs deleted file mode 100644 index eac5194..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.15.sigs +++ /dev/null @@ -1,262 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.16.sigs b/ldb-2.0.8/ABI/ldb-1.1.16.sigs deleted file mode 100644 index eac5194..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.16.sigs +++ /dev/null @@ -1,262 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.17.sigs b/ldb-2.0.8/ABI/ldb-1.1.17.sigs deleted file mode 100644 index eac5194..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.17.sigs +++ /dev/null @@ -1,262 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.18.sigs b/ldb-2.0.8/ABI/ldb-1.1.18.sigs deleted file mode 100644 index eac5194..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.18.sigs +++ /dev/null @@ -1,262 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.19.sigs b/ldb-2.0.8/ABI/ldb-1.1.19.sigs deleted file mode 100644 index b46c5c7..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.19.sigs +++ /dev/null @@ -1,263 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.2.sigs b/ldb-2.0.8/ABI/ldb-1.1.2.sigs deleted file mode 100644 index d0df756..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.2.sigs +++ /dev/null @@ -1,256 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.20.sigs b/ldb-2.0.8/ABI/ldb-1.1.20.sigs deleted file mode 100644 index b46c5c7..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.20.sigs +++ /dev/null @@ -1,263 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.21.sigs b/ldb-2.0.8/ABI/ldb-1.1.21.sigs deleted file mode 100644 index b46c5c7..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.21.sigs +++ /dev/null @@ -1,263 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.22.sigs b/ldb-2.0.8/ABI/ldb-1.1.22.sigs deleted file mode 100644 index 6d9767b..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.22.sigs +++ /dev/null @@ -1,264 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.23.sigs b/ldb-2.0.8/ABI/ldb-1.1.23.sigs deleted file mode 100644 index 6d9767b..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.23.sigs +++ /dev/null @@ -1,264 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.24.sigs b/ldb-2.0.8/ABI/ldb-1.1.24.sigs deleted file mode 100644 index 6d9767b..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.24.sigs +++ /dev/null @@ -1,264 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.25.sigs b/ldb-2.0.8/ABI/ldb-1.1.25.sigs deleted file mode 100644 index 3f33df9..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.25.sigs +++ /dev/null @@ -1,265 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.26.sigs b/ldb-2.0.8/ABI/ldb-1.1.26.sigs deleted file mode 100644 index 3f33df9..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.26.sigs +++ /dev/null @@ -1,265 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.27.sigs b/ldb-2.0.8/ABI/ldb-1.1.27.sigs deleted file mode 100644 index 4fa30d8..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.27.sigs +++ /dev/null @@ -1,266 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.28.sigs b/ldb-2.0.8/ABI/ldb-1.1.28.sigs deleted file mode 100644 index 4fa30d8..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.28.sigs +++ /dev/null @@ -1,266 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.29.sigs b/ldb-2.0.8/ABI/ldb-1.1.29.sigs deleted file mode 100644 index 0ea968d..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.29.sigs +++ /dev/null @@ -1,268 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.3.sigs b/ldb-2.0.8/ABI/ldb-1.1.3.sigs deleted file mode 100644 index d0df756..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.3.sigs +++ /dev/null @@ -1,256 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.30.sigs b/ldb-2.0.8/ABI/ldb-1.1.30.sigs deleted file mode 100644 index ef9c53e..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.30.sigs +++ /dev/null @@ -1,272 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.31.sigs b/ldb-2.0.8/ABI/ldb-1.1.31.sigs deleted file mode 100644 index d183708..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.31.sigs +++ /dev/null @@ -1,274 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.4.sigs b/ldb-2.0.8/ABI/ldb-1.1.4.sigs deleted file mode 100644 index d0df756..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.4.sigs +++ /dev/null @@ -1,256 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.5.sigs b/ldb-2.0.8/ABI/ldb-1.1.5.sigs deleted file mode 100644 index cc0f859..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.5.sigs +++ /dev/null @@ -1,257 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.6.sigs b/ldb-2.0.8/ABI/ldb-1.1.6.sigs deleted file mode 100644 index f90fa13..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.6.sigs +++ /dev/null @@ -1,258 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.7.sigs b/ldb-2.0.8/ABI/ldb-1.1.7.sigs deleted file mode 100644 index f90fa13..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.7.sigs +++ /dev/null @@ -1,258 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.8.sigs b/ldb-2.0.8/ABI/ldb-1.1.8.sigs deleted file mode 100644 index f90fa13..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.8.sigs +++ /dev/null @@ -1,258 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.1.9.sigs b/ldb-2.0.8/ABI/ldb-1.1.9.sigs deleted file mode 100644 index f90fa13..0000000 --- a/ldb-2.0.8/ABI/ldb-1.1.9.sigs +++ /dev/null @@ -1,258 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.2.0.sigs b/ldb-2.0.8/ABI/ldb-1.2.0.sigs deleted file mode 100644 index 1be2ae7..0000000 --- a/ldb-2.0.8/ABI/ldb-1.2.0.sigs +++ /dev/null @@ -1,276 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.2.1.sigs b/ldb-2.0.8/ABI/ldb-1.2.1.sigs deleted file mode 100644 index 1be2ae7..0000000 --- a/ldb-2.0.8/ABI/ldb-1.2.1.sigs +++ /dev/null @@ -1,276 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.2.2.sigs b/ldb-2.0.8/ABI/ldb-1.2.2.sigs deleted file mode 100644 index 9dc61cd..0000000 --- a/ldb-2.0.8/ABI/ldb-1.2.2.sigs +++ /dev/null @@ -1,277 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.2.3.sigs b/ldb-2.0.8/ABI/ldb-1.2.3.sigs deleted file mode 100644 index 9dc61cd..0000000 --- a/ldb-2.0.8/ABI/ldb-1.2.3.sigs +++ /dev/null @@ -1,277 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.3.0.sigs b/ldb-2.0.8/ABI/ldb-1.3.0.sigs deleted file mode 100644 index a31b84e..0000000 --- a/ldb-2.0.8/ABI/ldb-1.3.0.sigs +++ /dev/null @@ -1,279 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.3.1.sigs b/ldb-2.0.8/ABI/ldb-1.3.1.sigs deleted file mode 100644 index a31b84e..0000000 --- a/ldb-2.0.8/ABI/ldb-1.3.1.sigs +++ /dev/null @@ -1,279 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.3.2.sigs b/ldb-2.0.8/ABI/ldb-1.3.2.sigs deleted file mode 100644 index a31b84e..0000000 --- a/ldb-2.0.8/ABI/ldb-1.3.2.sigs +++ /dev/null @@ -1,279 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.4.0.sigs b/ldb-2.0.8/ABI/ldb-1.4.0.sigs deleted file mode 100644 index a31b84e..0000000 --- a/ldb-2.0.8/ABI/ldb-1.4.0.sigs +++ /dev/null @@ -1,279 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.4.1.sigs b/ldb-2.0.8/ABI/ldb-1.4.1.sigs deleted file mode 100644 index a31b84e..0000000 --- a/ldb-2.0.8/ABI/ldb-1.4.1.sigs +++ /dev/null @@ -1,279 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.5.0.sigs b/ldb-2.0.8/ABI/ldb-1.5.0.sigs deleted file mode 100644 index a31b84e..0000000 --- a/ldb-2.0.8/ABI/ldb-1.5.0.sigs +++ /dev/null @@ -1,279 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.5.1.sigs b/ldb-2.0.8/ABI/ldb-1.5.1.sigs deleted file mode 100644 index 0c1234f..0000000 --- a/ldb-2.0.8/ABI/ldb-1.5.1.sigs +++ /dev/null @@ -1,280 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.5.2.sigs b/ldb-2.0.8/ABI/ldb-1.5.2.sigs deleted file mode 100644 index 0c1234f..0000000 --- a/ldb-2.0.8/ABI/ldb-1.5.2.sigs +++ /dev/null @@ -1,280 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.5.3.sigs b/ldb-2.0.8/ABI/ldb-1.5.3.sigs deleted file mode 100644 index 0c1234f..0000000 --- a/ldb-2.0.8/ABI/ldb-1.5.3.sigs +++ /dev/null @@ -1,280 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.6.0.sigs b/ldb-2.0.8/ABI/ldb-1.6.0.sigs deleted file mode 100644 index 0c1234f..0000000 --- a/ldb-2.0.8/ABI/ldb-1.6.0.sigs +++ /dev/null @@ -1,280 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.6.1.sigs b/ldb-2.0.8/ABI/ldb-1.6.1.sigs deleted file mode 100644 index 0c1234f..0000000 --- a/ldb-2.0.8/ABI/ldb-1.6.1.sigs +++ /dev/null @@ -1,280 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.6.2.sigs b/ldb-2.0.8/ABI/ldb-1.6.2.sigs deleted file mode 100644 index 0c1234f..0000000 --- a/ldb-2.0.8/ABI/ldb-1.6.2.sigs +++ /dev/null @@ -1,280 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-1.6.3.sigs b/ldb-2.0.8/ABI/ldb-1.6.3.sigs deleted file mode 100644 index 0c1234f..0000000 --- a/ldb-2.0.8/ABI/ldb-1.6.3.sigs +++ /dev/null @@ -1,280 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-2.0.0.sigs b/ldb-2.0.8/ABI/ldb-2.0.0.sigs deleted file mode 100644 index 0c1234f..0000000 --- a/ldb-2.0.8/ABI/ldb-2.0.0.sigs +++ /dev/null @@ -1,280 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_only_attr_list: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int *) -ldb_unpack_data_only_attr_list_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, const char * const *, unsigned int, unsigned int, unsigned int *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-2.0.1.sigs b/ldb-2.0.8/ABI/ldb-2.0.1.sigs deleted file mode 100644 index f782d73..0000000 --- a/ldb-2.0.8/ABI/ldb-2.0.1.sigs +++ /dev/null @@ -1,280 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-2.0.2.sigs b/ldb-2.0.8/ABI/ldb-2.0.2.sigs deleted file mode 100644 index 5fc5560..0000000 --- a/ldb-2.0.8/ABI/ldb-2.0.2.sigs +++ /dev/null @@ -1,281 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) -ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-2.0.3.sigs b/ldb-2.0.8/ABI/ldb-2.0.3.sigs deleted file mode 100644 index 5fc5560..0000000 --- a/ldb-2.0.8/ABI/ldb-2.0.3.sigs +++ /dev/null @@ -1,281 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) -ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-2.0.4.sigs b/ldb-2.0.8/ABI/ldb-2.0.4.sigs deleted file mode 100644 index 446804b..0000000 --- a/ldb-2.0.8/ABI/ldb-2.0.4.sigs +++ /dev/null @@ -1,282 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_copy: const char **(TALLOC_CTX *, const char **) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) -ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-2.0.5.sigs b/ldb-2.0.8/ABI/ldb-2.0.5.sigs deleted file mode 100644 index 5049dc6..0000000 --- a/ldb-2.0.8/ABI/ldb-2.0.5.sigs +++ /dev/null @@ -1,283 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_copy: const char **(TALLOC_CTX *, const char **) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_options_get: const char **(struct ldb_context *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) -ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-2.0.6.sigs b/ldb-2.0.8/ABI/ldb-2.0.6.sigs deleted file mode 100644 index 5049dc6..0000000 --- a/ldb-2.0.8/ABI/ldb-2.0.6.sigs +++ /dev/null @@ -1,283 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_copy: const char **(TALLOC_CTX *, const char **) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_options_get: const char **(struct ldb_context *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) -ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-2.0.7.sigs b/ldb-2.0.8/ABI/ldb-2.0.7.sigs deleted file mode 100644 index 5049dc6..0000000 --- a/ldb-2.0.8/ABI/ldb-2.0.7.sigs +++ /dev/null @@ -1,283 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_copy: const char **(TALLOC_CTX *, const char **) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_options_get: const char **(struct ldb_context *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) -ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-2.0.8.sigs b/ldb-2.0.8/ABI/ldb-2.0.8.sigs deleted file mode 100644 index 5049dc6..0000000 --- a/ldb-2.0.8/ABI/ldb-2.0.8.sigs +++ /dev/null @@ -1,283 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(TALLOC_CTX *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) -ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) -ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) -ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) -ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) -ldb_check_critical_controls: int (struct ldb_control **) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) -ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) -ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_comp_num: int (struct ldb_dn *) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) -ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_minimise: bool (struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) -ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handle_use_global_event_context: void (struct ldb_handle *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_map_add: int (struct ldb_module *, struct ldb_request *) -ldb_map_delete: int (struct ldb_module *, struct ldb_request *) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_map_modify: int (struct ldb_module *, struct ldb_request *) -ldb_map_rename: int (struct ldb_module *, struct ldb_request *) -ldb_map_search: int (struct ldb_module *, struct ldb_request *) -ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) -ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_flags: uint32_t (struct ldb_context *) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) -ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_next: struct ldb_module *(struct ldb_module *) -ldb_module_popt_options: struct poptOption **(struct ldb_context *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_modules_load: int (const char *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) -ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(TALLOC_CTX *) -ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_read_lock: int (struct ldb_module *) -ldb_next_read_unlock: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_options_copy: const char **(TALLOC_CTX *, const char **) -ldb_options_find: const char *(struct ldb_context *, const char **, const char *) -ldb_options_get: const char **(struct ldb_context *) -ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t) -ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn, bool) -ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) -ldb_register_hook: int (ldb_hook_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_req_get_custom_flags: uint32_t (struct ldb_request *) -ldb_req_is_untrusted: bool (struct ldb_request *) -ldb_req_location: const char *(struct ldb_request *) -ldb_req_mark_trusted: void (struct ldb_request *) -ldb_req_mark_untrusted: void (struct ldb_request *) -ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) -ldb_req_set_location: void (struct ldb_request *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) -ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_require_private_event_context: void (struct ldb_context *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) -ldb_unpack_data_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) -ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) -ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_string_cmp: int (const struct ldb_val *, const char *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) diff --git a/ldb-2.0.8/ABI/ldb-ildap-0.9.12.sigs b/ldb-2.0.8/ABI/ldb-ildap-0.9.12.sigs deleted file mode 100644 index 4639220..0000000 --- a/ldb-2.0.8/ABI/ldb-ildap-0.9.12.sigs +++ /dev/null @@ -1,224 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(void *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(void *, const char *, int) -ldb_binary_decode: struct ldb_val (void *, const char *) -ldb_binary_encode: char *(void *, struct ldb_val) -ldb_binary_encode_string: char *(void *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, void *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, void *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, void *, const char *, size_t) -ldb_casefold_default: char *(void *, void *, const char *, size_t) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(void *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) -ldb_dn_canonical_string: char *(void *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(void *, struct ldb_dn *) -ldb_dn_escape_value: char *(void *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(void *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(void *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(void *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(void *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(void *, struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_init_module_chain: int (struct ldb_context *, struct ldb_module *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(void *) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(void *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_register_samba_handlers: int (struct ldb_context *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_samba_syntax_by_lDAPDisplayName: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_samba_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (void *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) -ldb_wrap_connect: struct ldb_context *(TALLOC_CTX *, struct tevent_context *, struct loadparm_context *, const char *, struct auth_session_info *, struct cli_credentials *, unsigned int) -ldb_wrap_fork_hook: void (void) diff --git a/ldb-2.0.8/ABI/ldb-samba4-0.9.10.sigs b/ldb-2.0.8/ABI/ldb-samba4-0.9.10.sigs deleted file mode 100644 index 7f9dbb5..0000000 --- a/ldb-2.0.8/ABI/ldb-samba4-0.9.10.sigs +++ /dev/null @@ -1,223 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(void *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(void *, const char *, int) -ldb_binary_decode: struct ldb_val (void *, const char *) -ldb_binary_encode: char *(void *, struct ldb_val) -ldb_binary_encode_string: char *(void *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, void *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, void *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, void *, const char *, size_t) -ldb_casefold_default: char *(void *, void *, const char *, size_t) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(void *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) -ldb_dn_canonical_string: char *(void *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(void *, struct ldb_dn *) -ldb_dn_escape_value: char *(void *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(void *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(void *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(void *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(void *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(void *, struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_init_module_chain: int (struct ldb_context *, struct ldb_module *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(void *) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(void *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_register_samba_handlers: int (struct ldb_context *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_samba_syntax_by_lDAPDisplayName: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_samba_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (void *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) -ldb_wrap_connect: struct ldb_context *(TALLOC_CTX *, struct tevent_context *, struct loadparm_context *, const char *, struct auth_session_info *, struct cli_credentials *, unsigned int) -ldb_wrap_fork_hook: void (void) diff --git a/ldb-2.0.8/ABI/ldb-samba4-0.9.11.sigs b/ldb-2.0.8/ABI/ldb-samba4-0.9.11.sigs deleted file mode 100644 index 4639220..0000000 --- a/ldb-2.0.8/ABI/ldb-samba4-0.9.11.sigs +++ /dev/null @@ -1,224 +0,0 @@ -ldb_add: int (struct ldb_context *, const struct ldb_message *) -ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) -ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) -ldb_attr_casefold: char *(void *, const char *) -ldb_attr_dn: int (const char *) -ldb_attr_in_list: int (const char * const *, const char *) -ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) -ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) -ldb_base64_decode: int (char *) -ldb_base64_encode: char *(void *, const char *, int) -ldb_binary_decode: struct ldb_val (void *, const char *) -ldb_binary_encode: char *(void *, struct ldb_val) -ldb_binary_encode_string: char *(void *, const char *) -ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, void *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, void *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, void *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, void *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) -ldb_casefold: char *(struct ldb_context *, void *, const char *, size_t) -ldb_casefold_default: char *(void *, void *, const char *, size_t) -ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) -ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) -ldb_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) -ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_debug_add: void (struct ldb_context *, const char *, ...) -ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) -ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) -ldb_delete: int (struct ldb_context *, struct ldb_dn *) -ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) -ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) -ldb_dn_alloc_casefold: char *(void *, struct ldb_dn *) -ldb_dn_alloc_linearized: char *(void *, struct ldb_dn *) -ldb_dn_canonical_ex_string: char *(void *, struct ldb_dn *) -ldb_dn_canonical_string: char *(void *, struct ldb_dn *) -ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) -ldb_dn_check_special: bool (struct ldb_dn *, const char *) -ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) -ldb_dn_copy: struct ldb_dn *(void *, struct ldb_dn *) -ldb_dn_escape_value: char *(void *, struct ldb_val) -ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) -ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) -ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) -ldb_dn_from_ldb_val: struct ldb_dn *(void *, struct ldb_context *, const struct ldb_val *) -ldb_dn_get_casefold: const char *(struct ldb_dn *) -ldb_dn_get_comp_num: int (struct ldb_dn *) -ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) -ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) -ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) -ldb_dn_get_extended_linearized: char *(void *, struct ldb_dn *, int) -ldb_dn_get_linearized: const char *(struct ldb_dn *) -ldb_dn_get_parent: struct ldb_dn *(void *, struct ldb_dn *) -ldb_dn_get_rdn_name: const char *(struct ldb_dn *) -ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) -ldb_dn_has_extended: bool (struct ldb_dn *) -ldb_dn_is_null: bool (struct ldb_dn *) -ldb_dn_is_special: bool (struct ldb_dn *) -ldb_dn_is_valid: bool (struct ldb_dn *) -ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) -ldb_dn_new: struct ldb_dn *(void *, struct ldb_context *, const char *) -ldb_dn_new_fmt: struct ldb_dn *(void *, struct ldb_context *, const char *, ...) -ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) -ldb_dn_remove_extended_components: void (struct ldb_dn *) -ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) -ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) -ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) -ldb_dn_validate: bool (struct ldb_dn *) -ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) -ldb_errstring: const char *(struct ldb_context *) -ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) -ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_filter_from_tree: char *(void *, struct ldb_parse_tree *) -ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_create_perms: unsigned int (struct ldb_context *) -ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_event_context: struct tevent_context *(struct ldb_context *) -ldb_get_flags: unsigned int (struct ldb_context *) -ldb_get_opaque: void *(struct ldb_context *, const char *) -ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) -ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) -ldb_global_init: int (void) -ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) -ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) -ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) -ldb_init_module_chain: int (struct ldb_context *, struct ldb_module *) -ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) -ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) -ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) -ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) -ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) -ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) -ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) -ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) -ldb_load_modules: int (struct ldb_context *, const char **) -ldb_load_modules_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) -ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) -ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) -ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) -ldb_mod_register_control: int (struct ldb_module *, const char *) -ldb_modify: int (struct ldb_context *, const struct ldb_message *) -ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) -ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) -ldb_module_get_name: const char *(struct ldb_module *) -ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) -ldb_module_get_private: void *(struct ldb_module *) -ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) -ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) -ldb_module_send_referral: int (struct ldb_request *, char *) -ldb_module_set_private: void (struct ldb_module *, void *) -ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) -ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) -ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) -ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) -ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) -ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) -ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) -ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) -ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) -ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) -ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) -ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) -ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) -ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) -ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, void *, const struct ldb_message *, const char *) -ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) -ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) -ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) -ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) -ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) -ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) -ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) -ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) -ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) -ldb_msg_new: struct ldb_message *(void *) -ldb_msg_remove_attr: void (struct ldb_message *, const char *) -ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) -ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) -ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) -ldb_msg_sort_elements: void (struct ldb_message *) -ldb_next_del_trans: int (struct ldb_module *) -ldb_next_end_trans: int (struct ldb_module *) -ldb_next_init: int (struct ldb_module *) -ldb_next_prepare_commit: int (struct ldb_module *) -ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_request: int (struct ldb_module *, struct ldb_request *) -ldb_next_start_trans: int (struct ldb_module *) -ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, void *, const char **) -ldb_parse_tree: struct ldb_parse_tree *(void *, const char *) -ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) -ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) -ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) -ldb_register_backend: int (const char *, ldb_connect_fn) -ldb_register_module: int (const struct ldb_module_ops *) -ldb_register_samba_handlers: int (struct ldb_context *) -ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) -ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) -ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) -ldb_request: int (struct ldb_context *, struct ldb_request *) -ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) -ldb_request_done: int (struct ldb_request *, int) -ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) -ldb_request_get_status: int (struct ldb_request *) -ldb_request_set_state: void (struct ldb_request *, int) -ldb_reset_err_string: void (struct ldb_context *) -ldb_samba_syntax_by_lDAPDisplayName: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_samba_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) -ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) -ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) -ldb_schema_attribute_remove: void (struct ldb_context *, const char *) -ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) -ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) -ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) -ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) -ldb_set_create_perms: void (struct ldb_context *, unsigned int) -ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) -ldb_set_debug_stderr: int (struct ldb_context *) -ldb_set_default_dns: void (struct ldb_context *) -ldb_set_errstring: void (struct ldb_context *, const char *) -ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) -ldb_set_flags: void (struct ldb_context *, unsigned int) -ldb_set_modules_dir: void (struct ldb_context *, const char *) -ldb_set_opaque: int (struct ldb_context *, const char *, void *) -ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) -ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) -ldb_set_utf8_default: void (struct ldb_context *) -ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) -ldb_setup_wellknown_attributes: int (struct ldb_context *) -ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) -ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) -ldb_strerror: const char *(int) -ldb_string_to_time: time_t (const char *) -ldb_string_utc_to_time: time_t (const char *) -ldb_timestring: char *(TALLOC_CTX *, time_t) -ldb_timestring_utc: char *(TALLOC_CTX *, time_t) -ldb_transaction_cancel: int (struct ldb_context *) -ldb_transaction_cancel_noerr: int (struct ldb_context *) -ldb_transaction_commit: int (struct ldb_context *) -ldb_transaction_prepare_commit: int (struct ldb_context *) -ldb_transaction_start: int (struct ldb_context *) -ldb_val_dup: struct ldb_val (void *, const struct ldb_val *) -ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) -ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) -ldb_val_to_time: int (const struct ldb_val *, time_t *) -ldb_valid_attr_name: int (const char *) -ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) -ldb_wrap_connect: struct ldb_context *(TALLOC_CTX *, struct tevent_context *, struct loadparm_context *, const char *, struct auth_session_info *, struct cli_credentials *, unsigned int) -ldb_wrap_fork_hook: void (void) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.10.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.10.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.10.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.11.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.11.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.11.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.12.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.12.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.12.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.13.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.13.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.13.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.14.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.14.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.14.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.15.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.15.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.15.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.16.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.16.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.16.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.17.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.17.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.17.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.18.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.18.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.18.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.19.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.19.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.19.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.2.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.2.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.2.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.20.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.20.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.20.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.21.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.21.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.21.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.22.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.22.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.22.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.23.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.23.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.23.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.24.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.24.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.24.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.25.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.25.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.25.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.26.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.26.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.26.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.27.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.27.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.27.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.28.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.28.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.28.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.29.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.29.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.29.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.3.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.3.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.3.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.30.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.30.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.30.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.31.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.31.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.31.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.4.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.4.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.4.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.5.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.5.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.5.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.6.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.6.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.6.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.7.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.7.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.7.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.8.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.8.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.8.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.1.9.sigs b/ldb-2.0.8/ABI/pyldb-util-1.1.9.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.1.9.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.2.0.sigs b/ldb-2.0.8/ABI/pyldb-util-1.2.0.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.2.0.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.2.1.sigs b/ldb-2.0.8/ABI/pyldb-util-1.2.1.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.2.1.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.2.2.sigs b/ldb-2.0.8/ABI/pyldb-util-1.2.2.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.2.2.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.2.3.sigs b/ldb-2.0.8/ABI/pyldb-util-1.2.3.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.2.3.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.3.0.sigs b/ldb-2.0.8/ABI/pyldb-util-1.3.0.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.3.0.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.3.1.sigs b/ldb-2.0.8/ABI/pyldb-util-1.3.1.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.3.1.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.3.2.sigs b/ldb-2.0.8/ABI/pyldb-util-1.3.2.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.3.2.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.4.0.sigs b/ldb-2.0.8/ABI/pyldb-util-1.4.0.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.4.0.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.4.1.sigs b/ldb-2.0.8/ABI/pyldb-util-1.4.1.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.4.1.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.5.0.sigs b/ldb-2.0.8/ABI/pyldb-util-1.5.0.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.5.0.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.5.1.sigs b/ldb-2.0.8/ABI/pyldb-util-1.5.1.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.5.1.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.5.2.sigs b/ldb-2.0.8/ABI/pyldb-util-1.5.2.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.5.2.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.5.3.sigs b/ldb-2.0.8/ABI/pyldb-util-1.5.3.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.5.3.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.6.0.sigs b/ldb-2.0.8/ABI/pyldb-util-1.6.0.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.6.0.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.6.1.sigs b/ldb-2.0.8/ABI/pyldb-util-1.6.1.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.6.1.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.6.2.sigs b/ldb-2.0.8/ABI/pyldb-util-1.6.2.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.6.2.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-1.6.3.sigs b/ldb-2.0.8/ABI/pyldb-util-1.6.3.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-1.6.3.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-2.0.0.sigs b/ldb-2.0.8/ABI/pyldb-util-2.0.0.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-2.0.0.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-2.0.1.sigs b/ldb-2.0.8/ABI/pyldb-util-2.0.1.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-2.0.1.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-2.0.2.sigs b/ldb-2.0.8/ABI/pyldb-util-2.0.2.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-2.0.2.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-2.0.3.sigs b/ldb-2.0.8/ABI/pyldb-util-2.0.3.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-2.0.3.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-2.0.4.sigs b/ldb-2.0.8/ABI/pyldb-util-2.0.4.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-2.0.4.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-2.0.5.sigs b/ldb-2.0.8/ABI/pyldb-util-2.0.5.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-2.0.5.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-2.0.6.sigs b/ldb-2.0.8/ABI/pyldb-util-2.0.6.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-2.0.6.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-2.0.7.sigs b/ldb-2.0.8/ABI/pyldb-util-2.0.7.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-2.0.7.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util-2.0.8.sigs b/ldb-2.0.8/ABI/pyldb-util-2.0.8.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util-2.0.8.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/ABI/pyldb-util.py3-2.0.0.sigs b/ldb-2.0.8/ABI/pyldb-util.py3-2.0.0.sigs deleted file mode 100644 index 74d6719..0000000 --- a/ldb-2.0.8/ABI/pyldb-util.py3-2.0.0.sigs +++ /dev/null @@ -1,2 +0,0 @@ -pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) -pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) diff --git a/ldb-2.0.8/Doxyfile b/ldb-2.0.8/Doxyfile deleted file mode 100644 index 07b12b5..0000000 --- a/ldb-2.0.8/Doxyfile +++ /dev/null @@ -1,26 +0,0 @@ -PROJECT_NAME = LDB -OUTPUT_DIRECTORY = apidocs -REPEAT_BRIEF = YES -OPTIMIZE_OUTPUT_FOR_C = YES -SORT_MEMBER_DOCS = YES -SORT_BRIEF_DOCS = NO -GENERATE_TODOLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES -SHOW_USED_FILES = NO -SHOW_DIRECTORIES = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_IF_DOC_ERROR = YES -WARN_NO_PARAMDOC = NO -WARN_FORMAT = "$file:$line: $text" -INPUT = include . -FILE_PATTERNS = *.h *.dox -EXCLUDE = include/config.h include/dlinklist.h \ - include/includes.h -EXAMPLE_PATH = examples -GENERATE_HTML = YES -HTML_OUTPUT = html -GENERATE_MAN = YES -ALWAYS_DETAILED_SEC = YES -JAVADOC_AUTOBRIEF = YES diff --git a/ldb-2.0.8/Makefile b/ldb-2.0.8/Makefile deleted file mode 100644 index b82723f..0000000 --- a/ldb-2.0.8/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# simple makefile wrapper to run waf - -WAF_BIN=`PATH=buildtools/bin:../../buildtools/bin:$$PATH which waf` -WAF_BINARY=$(PYTHON) $(WAF_BIN) -WAF=PYTHONHASHSEED=1 WAF_MAKE=1 $(WAF_BINARY) - -all: - $(WAF) build - -install: - $(WAF) install - -uninstall: - $(WAF) uninstall - -test: - $(WAF) test $(TEST_OPTIONS) - -dist: - touch .tmplock - WAFLOCK=.tmplock $(WAF) dist - -distcheck: - touch .tmplock - WAFLOCK=.tmplock $(WAF) distcheck - -clean: - $(WAF) clean - -distclean: - $(WAF) distclean - -reconfigure: configure - $(WAF) reconfigure - -show_waf_options: - $(WAF) --help - -# some compatibility make targets -everything: all - -testsuite: all - -check: test - -# this should do an install as well, once install is finished -installcheck: test - -etags: - $(WAF) etags - -ctags: - $(WAF) ctags diff --git a/ldb-2.0.8/README_gcov.txt b/ldb-2.0.8/README_gcov.txt deleted file mode 100644 index 2abd937..0000000 --- a/ldb-2.0.8/README_gcov.txt +++ /dev/null @@ -1,29 +0,0 @@ -Here is how to use gcov to test code coverage in ldb. - -Step 1: build ldb with gcov enabled - - make clean all WITH_GCOV=1 - -Step 3: run the test suite - make test-tdb - -Step 4: produce the gcov report - make gcov - -Step 5: read the summary reports - less *.report.gcov - -Step 6: examine the per-file reports - less ldb_tdb\#ldb_tdb.c.gcov - -You can also combine steps 2 to 4 like this: - - make clean all test-tdb gcov WITH_GCOV=1 - -Note that you should not expect 100% coverage, as some error paths -(such as memory allocation failures) are very hard to trigger. There -are ways of working around this, but they are quite tricky (they -involve allocation wrappers that "fork and fail on malloc"). - -The lines to look for in the per-file reports are the ones starting -with "#####". Those are lines that are never executed. diff --git a/ldb-2.0.8/_ldb_text.py b/ldb-2.0.8/_ldb_text.py deleted file mode 100644 index e0505e1..0000000 --- a/ldb-2.0.8/_ldb_text.py +++ /dev/null @@ -1,146 +0,0 @@ -# Text wrapper for ldb bindings -# -# Copyright (C) 2015 Petr Viktorin -# Published under the GNU LGPLv3 or later - -import ldb - - -def _recursive_encode(obj): - if isinstance(obj, bytes): - return obj - elif isinstance(obj, str): - return obj.encode('utf-8') - else: - return [_recursive_encode(o) for o in obj] - - -class _WrapBase(object): - - @classmethod - def _wrap(cls, wrapped): - self = cls.__new__(cls) - self._wrapped = wrapped - return self - - def __len__(self): - return len(self._wrapped) - - def __eq__(self, other): - if hasattr(other, '_wrapped'): - return self._wrapped == other._wrapped - else: - return self._wrapped == other - - def __ne__(self, other): - if hasattr(other, '_wrapped'): - return self._wrapped != other._wrapped - else: - return self._wrapped != other - - def __lt__(self, other): - if hasattr(other, '_wrapped'): - return self._wrapped < other._wrapped - else: - return self._wrapped < other - - def __le__(self, other): - if hasattr(other, '_wrapped'): - return self._wrapped >= other._wrapped - else: - return self._wrapped >= other - - def __gt__(self, other): - if hasattr(other, '_wrapped'): - return self._wrapped > other._wrapped - else: - return self._wrapped > other - - def __ge__(self, other): - if hasattr(other, '_wrapped'): - return self._wrapped >= other._wrapped - else: - return self._wrapped >= other - - def __repr__(self): - return '%s.text' % repr(self._wrapped) - - -class MessageElementTextWrapper(_WrapBase): - - """Text interface for a LDB message element""" - - def __iter__(self): - for item in self._wrapped: - yield item.decode('utf-8') - - def __getitem__(self, key): - result = self._wrapped[key] - if result is None: - return None - else: - return result.decode('utf-8') - - @property - def flags(self): - return self._wrapped.flags - - @property - def set_flags(self): - return self._wrapped.set_flags - - -_wrap_element = MessageElementTextWrapper._wrap - - -class MessageTextWrapper(_WrapBase): - - """Text interface for a LDB message""" - - def __getitem__(self, key): - result = self._wrapped[key] - if result is None: - return None - else: - return _wrap_element(result) - - def get(self, *args, **kwargs): - result = self._wrapped.get(*args, **kwargs) - if isinstance(result, ldb.MessageElement): - return _wrap_element(result) - elif isinstance(result, bytes): - return result.decode('utf-8') - else: - return result - - def __setitem__(self, key, item): - self._wrapped[key] = _recursive_encode(item) - - def __delitem__(self, key): - del self._wrapped[key] - - def elements(self): - return [_wrap_element(el) for el in self._wrapped.elements()] - - def items(self): - return [(attr, _wrap_element(el)) for attr, el in self._wrapped.items()] - - @property - def keys(self): - return self._wrapped.keys - - @property - def remove(self): - return self._wrapped.remove - - @property - def add(self): - return self._wrapped.add - - @property - def dn(self): - return self._wrapped.dn - - @dn.setter - def dn(self, new_value): - self._wrapped.dn = new_value diff --git a/ldb-2.0.8/buildtools/README b/ldb-2.0.8/buildtools/README deleted file mode 100644 index eab0382..0000000 --- a/ldb-2.0.8/buildtools/README +++ /dev/null @@ -1,12 +0,0 @@ -See http://code.google.com/p/waf/ for more information on waf - -You can get a svn copy of the upstream source with: - - svn checkout http://waf.googlecode.com/svn/trunk/ waf-read-only - -Samba currently uses waf 1.5, which can be found at: - - http://waf.googlecode.com/svn/branches/waf-1.5 - -To update the current copy of waf, use the update-waf.sh script in this -directory. diff --git a/ldb-2.0.8/buildtools/bin/waf b/ldb-2.0.8/buildtools/bin/waf deleted file mode 100755 index 11ce8e7..0000000 --- a/ldb-2.0.8/buildtools/bin/waf +++ /dev/null @@ -1,167 +0,0 @@ -#!/usr/bin/env python3 -# encoding: latin-1 -# Thomas Nagy, 2005-2018 -# -""" -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -""" - -import os, sys, inspect - -VERSION="2.0.18" -REVISION="x" -GIT="x" -INSTALL="x" -C1='x' -C2='x' -C3='x' -cwd = os.getcwd() -join = os.path.join - -if sys.hexversion<0x206000f: - raise ImportError('Python >= 2.6 is required to create the waf file') - -WAF='waf' -def b(x): - return x -if sys.hexversion>0x300000f: - WAF='waf3' - def b(x): - return x.encode() - -def err(m): - print(('\033[91mError: %s\033[0m' % m)) - sys.exit(1) - -def unpack_wafdir(dir, src): - f = open(src,'rb') - c = 'corrupt archive (%d)' - while 1: - line = f.readline() - if not line: err('run waf-light from a folder containing waflib') - if line == b('#==>\n'): - txt = f.readline() - if not txt: err(c % 1) - if f.readline() != b('#<==\n'): err(c % 2) - break - if not txt: err(c % 3) - txt = txt[1:-1].replace(b(C1), b('\n')).replace(b(C2), b('\r')).replace(b(C3), b('\x00')) - - import shutil, tarfile - try: shutil.rmtree(dir) - except OSError: pass - try: - for x in ('Tools', 'extras'): - os.makedirs(join(dir, 'waflib', x)) - except OSError: - err("Cannot unpack waf lib into %s\nMove waf in a writable directory" % dir) - - os.chdir(dir) - tmp = 't.bz2' - t = open(tmp,'wb') - try: t.write(txt) - finally: t.close() - - try: - t = tarfile.open(tmp) - except: - try: - os.system('bunzip2 t.bz2') - t = tarfile.open('t') - tmp = 't' - except: - os.chdir(cwd) - try: shutil.rmtree(dir) - except OSError: pass - err("Waf cannot be unpacked, check that bzip2 support is present") - - try: - for x in t: t.extract(x) - finally: - t.close() - - for x in ('Tools', 'extras'): - os.chmod(join('waflib',x), 493) - - if sys.hexversion<0x300000f: - sys.path = [join(dir, 'waflib')] + sys.path - import fixpy2 - fixpy2.fixdir(dir) - - os.remove(tmp) - os.chdir(cwd) - - try: dir = unicode(dir, 'mbcs') - except: pass - try: - from ctypes import windll - windll.kernel32.SetFileAttributesW(dir, 2) - except: - pass - -def test(dir): - try: - os.stat(join(dir, 'waflib')) - return os.path.abspath(dir) - except OSError: - pass - -def find_lib(): - path = '../../third_party/waf' - paths = [path, path+'/waflib'] - return [os.path.abspath(os.path.join(os.path.dirname(__file__), x)) for x in paths] - -wafdir = find_lib() -for p in wafdir: - sys.path.insert(0, p) - -if __name__ == '__main__': - #import extras.compat15#PRELUDE - import sys - - from waflib.Tools import ccroot, c, ar, compiler_c, gcc - sys.modules['cc'] = c - sys.modules['ccroot'] = ccroot - sys.modules['ar'] = ar - sys.modules['compiler_cc'] = compiler_c - sys.modules['gcc'] = gcc - - from waflib import Options - Options.lockfile = os.environ.get('WAFLOCK', '.lock-wscript') - if os.path.isfile(Options.lockfile) and os.stat(Options.lockfile).st_size == 0: - os.environ['NOCLIMB'] = "1" - # there is a single top-level, but libraries must build independently - os.environ['NO_LOCK_IN_TOP'] = "1" - - from waflib import Task - class o(object): - display = None - Task.classes['cc_link'] = o - - from waflib import Scripting - Scripting.waf_entry_point(cwd, VERSION, wafdir[0]) - diff --git a/ldb-2.0.8/buildtools/compare_config_h4.sh b/ldb-2.0.8/buildtools/compare_config_h4.sh deleted file mode 100755 index b78b36f..0000000 --- a/ldb-2.0.8/buildtools/compare_config_h4.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -# compare the generated config.h from a waf build with existing samba -# build - -grep "^.define" bin/default/source4/include/config.h | sort > waf-config.h -grep "^.define" $HOME/samba_old/source4/include/config.h | sort > old-config.h - -comm -23 old-config.h waf-config.h - -#echo -#diff -u old-config.h waf-config.h diff --git a/ldb-2.0.8/buildtools/compare_generated.sh b/ldb-2.0.8/buildtools/compare_generated.sh deleted file mode 100755 index ebef8a9..0000000 --- a/ldb-2.0.8/buildtools/compare_generated.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/sh - -# compare the generated files from a waf - -old_build=$HOME/samba_old - -gen_files=$(cd bin/default && find . -type f -name '*.[ch]') - -2>&1 - -strip_file() -{ - in_file=$1 - out_file=$2 - cat $in_file | - grep -v 'The following definitions come from' | - grep -v 'Automatically generated at' | - grep -v 'Generated from' | - sed 's|/home/tnagy/samba/source4||g' | - sed 's|/home/tnagy/samba/|../|g' | - sed 's|bin/default/source4/||g' | - sed 's|bin/default/|../|g' | - sed 's/define _____/define ___/g' | - sed 's/define __*/define _/g' | - sed 's/define _DEFAULT_/define _/g' | - sed 's/define _SOURCE4_/define ___/g' | - sed 's/define ___/define _/g' | - sed 's/ifndef ___/ifndef _/g' | - sed 's|endif /* ____|endif /* __|g' | - sed s/__DEFAULT_SOURCE4/__/ | - sed s/__DEFAULT_SOURCE4/__/ | - sed s/__DEFAULT/____/ > $out_file -} - -compare_file() -{ - f=$f - bname=$(basename $f) - t1=/tmp/$bname.old.$$ - t2=/tmp/$bname.new.$$ - strip_file $old_build/$f $t1 - strip_file bin/default/$f $t2 - diff -u -b $t1 $t2 2>&1 - rm -f $t1 $t2 -} - -for f in $gen_files; do - compare_file $f -done - diff --git a/ldb-2.0.8/buildtools/compare_install.sh b/ldb-2.0.8/buildtools/compare_install.sh deleted file mode 100755 index b964117..0000000 --- a/ldb-2.0.8/buildtools/compare_install.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -prefix1="$1" -prefix2="$2" - -(cd $prefix1 && find . ) | sort > p1.txt -(cd $prefix2 && find . ) | sort > p2.txt -diff -u p[12].txt diff --git a/ldb-2.0.8/buildtools/examples/run_on_target.py b/ldb-2.0.8/buildtools/examples/run_on_target.py deleted file mode 100755 index 79c5730..0000000 --- a/ldb-2.0.8/buildtools/examples/run_on_target.py +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env python3 - -# -# Sample run-on-target script -# This is a script that can be used as cross-execute parameter to samba -# configuration process, running the command on a remote target for which -# the cross-compiled configure test was compiled. -# -# To use: -# ./configure \ -# --cross-compile \ -# '--cross-execute=./buildtools/example/run_on_target.py --host=' -# -# A more elaborate example: -# ./configure \ -# --cross-compile \ -# '--cross-execute=./buildtools/example/run_on_target.py --host= --user= "--ssh=ssh -i " --destdir=/path/to/dir' -# -# Typically this is to be used also with --cross-answers, so that the -# cross answers file gets built and further builds can be made without -# the help of a remote target. -# -# The following assumptions are made: -# 1. rsync is available on build machine and target machine -# 2. A running ssh service on target machine with password-less shell login -# 3. A directory writable by the password-less login user -# 4. The tests on the target can run and provide reliable results -# from the login account's home directory. This is significant -# for example in locking tests which -# create files in the current directory. As a workaround to this -# assumption, the TESTDIR environment variable can be set on the target -# (using ssh command line or server config) and the tests shall -# chdir to that directory. -# - -import sys -import os -import subprocess -from optparse import OptionParser - -# those are defaults, but can be overidden using command line -SSH = 'ssh' -USER = None -HOST = 'localhost' - - -def xfer_files(ssh, srcdir, host, user, targ_destdir): - """Transfer executable files to target - - Use rsync to copy the directory containing program to run - INTO a destination directory on the target. An exact copy - of the source directory is created on the target machine, - possibly deleting files on the target machine which do not - exist on the source directory. - - The idea is that the test may include files in addition to - the compiled binary, and all of those files reside alongside - the binary in a source directory. - - For example, if the test to run is /foo/bar/test and the - destination directory on the target is /tbaz, then /tbaz/bar - on the target shall be an exact copy of /foo/bar on the source, - including deletion of files inside /tbaz/bar which do not exist - on the source. - """ - - userhost = host - if user: - userhost = '%s@%s' % (user, host) - - cmd = 'rsync --verbose -rl --ignore-times --delete -e "%s" %s %s:%s/' % \ - (ssh, srcdir, userhost, targ_destdir) - p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - (out, err) = p.communicate() - if p.returncode != 0: - raise Exception('failed syncing files\n stdout:\n%s\nstderr:%s\n' - % (out, err)) - - -def exec_remote(ssh, host, user, destdir, targdir, prog, args): - """Run a test on the target - - Using password-less ssh, run the compiled binary on the target. - - An assumption is that there's no need to cd into the target dir, - same as there's no need to do it on a native build. - """ - userhost = host - if user: - userhost = '%s@%s' % (user, host) - - cmd = '%s %s %s/%s/%s' % (ssh, userhost, destdir, targdir, prog) - if args: - cmd = cmd + ' ' + ' '.join(args) - p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - (out, err) = p.communicate() - return (p.returncode, out) - - -def main(argv): - usage = "usage: %prog [options] [args]" - parser = OptionParser(usage) - - parser.add_option('--ssh', help="SSH client and additional flags", - default=SSH) - parser.add_option('--host', help="target host name or IP address", - default=HOST) - parser.add_option('--user', help="login user on target", - default=USER) - parser.add_option('--destdir', help="work directory on target", - default='~') - - (options, args) = parser.parse_args(argv) - if len(args) < 1: - parser.error("please supply test program to run") - - progpath = args[0] - - # assume that a test that was not compiled fails (e.g. getconf) - if progpath[0] != '/': - return (1, "") - - progdir = os.path.dirname(progpath) - prog = os.path.basename(progpath) - targ_progdir = os.path.basename(progdir) - - xfer_files( - options.ssh, - progdir, - options.host, - options.user, - options.destdir) - - (rc, out) = exec_remote(options.ssh, - options.host, - options.user, - options.destdir, - targ_progdir, - prog, args[1:]) - return (rc, out) - - -if __name__ == '__main__': - (rc, out) = main(sys.argv[1:]) - sys.stdout.write(out) - sys.exit(rc) diff --git a/ldb-2.0.8/buildtools/scripts/Makefile.waf b/ldb-2.0.8/buildtools/scripts/Makefile.waf deleted file mode 100644 index 5fc939c..0000000 --- a/ldb-2.0.8/buildtools/scripts/Makefile.waf +++ /dev/null @@ -1,72 +0,0 @@ -# simple makefile wrapper to run waf - -WAF_BINARY=BUILDTOOLS/bin/waf -WAF=WAF_MAKE=1 $(WAF_BINARY) - -all: - $(WAF) build - -install: - $(WAF) install - -uninstall: - $(WAF) uninstall - -test: - $(WAF) test $(TEST_OPTIONS) - -help: - @echo NOTE: to run extended waf options use $(WAF_BINARY) or modify your PATH - $(WAF) --help - -testenv: - $(WAF) test --testenv $(TEST_OPTIONS) - -quicktest: - $(WAF) test --quick $(TEST_OPTIONS) - -dist: - $(WAF) dist - -distcheck: - $(WAF) distcheck - -clean: - $(WAF) clean - -distclean: - $(WAF) distclean - -reconfigure: configure - $(WAF) reconfigure - -show_waf_options: - $(WAF) --help - -# some compatibility make targets -everything: all - -testsuite: all - -check: test - -torture: all - -# this should do an install as well, once install is finished -installcheck: test - -etags: - $(WAF) etags - -ctags: - $(WAF) ctags - -bin/%:: FORCE - $(WAF) --targets=$@ -FORCE: - -configure: autogen-waf.sh BUILDTOOLS/scripts/configure.waf - ./autogen-waf.sh - -Makefile: autogen-waf.sh configure BUILDTOOLS/scripts/Makefile.waf - ./autogen-waf.sh diff --git a/ldb-2.0.8/buildtools/scripts/abi_gen.sh b/ldb-2.0.8/buildtools/scripts/abi_gen.sh deleted file mode 100755 index 6dd6d32..0000000 --- a/ldb-2.0.8/buildtools/scripts/abi_gen.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh -# generate a set of ABI signatures from a shared library - -SHAREDLIB="$1" - -GDBSCRIPT="gdb_syms.$$" - -( -cat < $GDBSCRIPT - -# forcing the terminal avoids a problem on Fedora12 -TERM=none gdb -n -batch -x $GDBSCRIPT "$SHAREDLIB" < /dev/null -rm -f $GDBSCRIPT diff --git a/ldb-2.0.8/buildtools/scripts/autogen-waf.sh b/ldb-2.0.8/buildtools/scripts/autogen-waf.sh deleted file mode 100755 index 7a6e94c..0000000 --- a/ldb-2.0.8/buildtools/scripts/autogen-waf.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh - -p=`dirname $0` - -echo "Setting up for waf build" - -echo "Looking for the buildtools directory" - -d="buildtools" -while test \! -d "$p/$d"; do d="../$d"; done - -echo "Found buildtools in $p/$d" - -echo "Setting up configure" -rm -f $p/configure $p/include/config*.h* -sed "s|BUILDTOOLS|$d|g;s|BUILDPATH|$p|g" < "$p/$d/scripts/configure.waf" > $p/configure -chmod +x $p/configure - -echo "Setting up Makefile" -rm -f $p/makefile $p/Makefile -sed "s|BUILDTOOLS|$d|g" < "$p/$d/scripts/Makefile.waf" > $p/Makefile - -echo "done. Now run $p/configure or $p/configure.developer then make." -if [ $p != "." ]; then - echo "Notice: The build invoke path is not 'source4'! Use make with the parameter" - echo "-C <'source4' path>. Example: make -C source4 all" -fi diff --git a/ldb-2.0.8/buildtools/scripts/configure.waf b/ldb-2.0.8/buildtools/scripts/configure.waf deleted file mode 100755 index a7d8d1d..0000000 --- a/ldb-2.0.8/buildtools/scripts/configure.waf +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -PREVPATH=`dirname $0` - -WAF=BUILDTOOLS/bin/waf - -# using JOBS=1 gives maximum compatibility with -# systems like AIX which have broken threading in python -JOBS=1 -export JOBS - -cd BUILDPATH || exit 1 -$WAF configure "$@" || exit 1 -cd $PREVPATH diff --git a/ldb-2.0.8/buildtools/testwaf.sh b/ldb-2.0.8/buildtools/testwaf.sh deleted file mode 100755 index 127e525..0000000 --- a/ldb-2.0.8/buildtools/testwaf.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/bin/bash - -set -e -set -x - -d=$(dirname $0) - -cd $d/.. -PREFIX=$HOME/testprefix - -if [ $# -gt 0 ]; then - tests="$*" -else - tests="lib/replace lib/talloc lib/tevent lib/tdb lib/ldb" -fi - -echo "testing in dirs $tests" - -for d in $tests; do - echo "`date`: testing $d" - pushd $d - rm -rf bin - type waf - waf dist - ./configure -C --enable-developer --prefix=$PREFIX - time make - make install - make distcheck - case $d in - "lib/ldb") - ldd bin/ldbadd - ;; - "lib/replace") - ldd bin/replace_testsuite - ;; - "lib/talloc") - ldd bin/talloc_testsuite - ;; - "lib/tdb") - ldd bin/tdbtool - ;; - esac - popd -done - -echo "testing python portability" -pushd lib/talloc -versions="python2.4 python2.5 python2.6 python3.0 python3.1" -for p in $versions; do - ret=$(which $p || echo "failed") - if [ $ret = "failed" ]; then - echo "$p not found, skipping" - continue - fi - echo "Testing $p" - $p ../../buildtools/bin/waf configure -C --enable-developer --prefix=$PREFIX - $p ../../buildtools/bin/waf build install -done -popd - -echo "testing cross compiling" -pushd lib/talloc -ret=$(which arm-linux-gnueabi-gcc || echo "failed") -if [ $ret != "failed" ]; then - CC=arm-linux-gnueabi-gcc ./configure -C --prefix=$PREFIX --cross-compile --cross-execute='runarm' - make && make install -else - echo "Cross-compiler not installed, skipping test" -fi -popd diff --git a/ldb-2.0.8/buildtools/wafsamba/README b/ldb-2.0.8/buildtools/wafsamba/README deleted file mode 100644 index 1968b55..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/README +++ /dev/null @@ -1,8 +0,0 @@ -This is a set of waf 'tools' to help make building the Samba -components easier, by having common functions in one place. This gives -us a more consistent build, and ensures that our project rules are -obeyed - - -TODO: - see http://wiki.samba.org/index.php/Waf diff --git a/ldb-2.0.8/buildtools/wafsamba/__init__.py b/ldb-2.0.8/buildtools/wafsamba/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/ldb-2.0.8/buildtools/wafsamba/configure_file.py b/ldb-2.0.8/buildtools/wafsamba/configure_file.py deleted file mode 100644 index 6ad4354..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/configure_file.py +++ /dev/null @@ -1,41 +0,0 @@ -# handle substitution of variables in .in files - -import sys -import re -import os -from waflib import Build, Logs -from samba_utils import SUBST_VARS_RECURSIVE - -def subst_at_vars(task): - '''substiture @VAR@ style variables in a file''' - - env = task.env - s = task.inputs[0].read() - - # split on the vars - a = re.split('(@\w+@)', s) - out = [] - for v in a: - if re.match('@\w+@', v): - vname = v[1:-1] - if not vname in task.env and vname.upper() in task.env: - vname = vname.upper() - if not vname in task.env: - Logs.error("Unknown substitution %s in %s" % (v, task.name)) - sys.exit(1) - v = SUBST_VARS_RECURSIVE(task.env[vname], task.env) - out.append(v) - contents = ''.join(out) - task.outputs[0].write(contents) - return 0 - -def CONFIGURE_FILE(bld, in_file, **kwargs): - '''configure file''' - - base=os.path.basename(in_file) - t = bld.SAMBA_GENERATOR('INFILE_%s' % base, - rule = subst_at_vars, - source = in_file + '.in', - target = in_file, - vars = kwargs) -Build.BuildContext.CONFIGURE_FILE = CONFIGURE_FILE diff --git a/ldb-2.0.8/buildtools/wafsamba/generic_cc.py b/ldb-2.0.8/buildtools/wafsamba/generic_cc.py deleted file mode 100644 index 1352c54..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/generic_cc.py +++ /dev/null @@ -1,70 +0,0 @@ - -# compiler definition for a generic C compiler -# based on suncc.py from waf - -import os, optparse -from waflib import Errors -from waflib.Tools import ccroot, ar -from waflib.Configure import conf - -# -# Let waflib provide useful defaults, but -# provide generic_cc as last resort fallback on -# all platforms -# -from waflib.Tools.compiler_c import c_compiler -for key in c_compiler.keys(): - c_compiler[key].append('generic_cc') - -@conf -def find_generic_cc(conf): - v = conf.env - cc = None - if v.CC: - cc = v.CC - elif 'CC' in conf.environ: - cc = conf.environ['CC'] - if not cc: - cc = conf.find_program('cc', var='CC') - if not cc: - conf.fatal('generic_cc was not found') - - try: - conf.cmd_and_log(cc + ['--version']) - except Errors.WafError: - conf.fatal('%r --version could not be executed' % cc) - - v.CC = cc - v.CC_NAME = 'generic_cc' - -@conf -def generic_cc_common_flags(conf): - v = conf.env - - v.CC_SRC_F = '' - v.CC_TGT_F = ['-c', '-o'] - v.CPPPATH_ST = '-I%s' - v.DEFINES_ST = '-D%s' - - if not v.LINK_CC: - v.LINK_CC = v.CC - - v.CCLNK_SRC_F = '' - v.CCLNK_TGT_F = ['-o'] - - v.LIB_ST = '-l%s' # template for adding libs - v.LIBPATH_ST = '-L%s' # template for adding libpaths - v.STLIB_ST = '-l%s' - v.STLIBPATH_ST = '-L%s' - - v.cprogram_PATTERN = '%s' - v.cshlib_PATTERN = 'lib%s.so' - v.cstlib_PATTERN = 'lib%s.a' - -def configure(conf): - conf.find_generic_cc() - conf.find_ar() - conf.generic_cc_common_flags() - conf.cc_load_tools() - conf.cc_add_flags() - conf.link_add_flags() diff --git a/ldb-2.0.8/buildtools/wafsamba/pkgconfig.py b/ldb-2.0.8/buildtools/wafsamba/pkgconfig.py deleted file mode 100644 index b83d5f3..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/pkgconfig.py +++ /dev/null @@ -1,68 +0,0 @@ -# handle substitution of variables in pc files - -import os, re, sys -from waflib import Build, Logs -from samba_utils import SUBST_VARS_RECURSIVE, TO_LIST - -def subst_at_vars(task): - '''substiture @VAR@ style variables in a file''' - - s = task.inputs[0].read() - # split on the vars - a = re.split('(@\w+@)', s) - out = [] - done_var = {} - back_sub = [ ('PREFIX', '${prefix}'), ('EXEC_PREFIX', '${exec_prefix}')] - for v in a: - if re.match('@\w+@', v): - vname = v[1:-1] - if not vname in task.env and vname.upper() in task.env: - vname = vname.upper() - if not vname in task.env: - Logs.error("Unknown substitution %s in %s" % (v, task.name)) - sys.exit(1) - v = SUBST_VARS_RECURSIVE(task.env[vname], task.env) - # now we back substitute the allowed pc vars - for (b, m) in back_sub: - s = task.env[b] - if s == v[0:len(s)]: - if not b in done_var: - # we don't want to substitute the first usage - done_var[b] = True - else: - v = m + v[len(s):] - break - out.append(v) - contents = ''.join(out) - task.outputs[0].write(contents) - return 0 - - -def PKG_CONFIG_FILES(bld, pc_files, vnum=None, extra_name=None): - '''install some pkg_config pc files''' - dest = '${PKGCONFIGDIR}' - dest = bld.EXPAND_VARIABLES(dest) - for f in TO_LIST(pc_files): - if extra_name: - target = f.split('.pc')[0] + extra_name + ".pc" - else: - target = f - base=os.path.basename(target) - t = bld.SAMBA_GENERATOR('PKGCONFIG_%s' % base, - rule=subst_at_vars, - source=f+'.in', - target=target) - bld.add_manual_dependency(bld.path.find_or_declare(f), bld.env['PREFIX'].encode('utf8')) - t.vars = [] - if t.env.RPATH_ON_INSTALL: - t.env.LIB_RPATH = t.env.RPATH_ST % t.env.LIBDIR - else: - t.env.LIB_RPATH = '' - if vnum: - t.env.PACKAGE_VERSION = vnum - for v in [ 'PREFIX', 'EXEC_PREFIX', 'LIB_RPATH' ]: - t.vars.append(t.env[v]) - bld.INSTALL_FILES(dest, target, flat=True, destname=base) -Build.BuildContext.PKG_CONFIG_FILES = PKG_CONFIG_FILES - - diff --git a/ldb-2.0.8/buildtools/wafsamba/samba3.py b/ldb-2.0.8/buildtools/wafsamba/samba3.py deleted file mode 100644 index 5aab250..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/samba3.py +++ /dev/null @@ -1,105 +0,0 @@ -# a waf tool to add autoconf-like macros to the configure section -# and for SAMBA_ macros for building libraries, binaries etc - -import os -from waflib import Build -from samba_utils import os_path_relpath, TO_LIST -from samba_autoconf import library_flags - -def SAMBA3_IS_STATIC_MODULE(bld, module): - '''Check whether module is in static list''' - if module in bld.env['static_modules']: - return True - return False -Build.BuildContext.SAMBA3_IS_STATIC_MODULE = SAMBA3_IS_STATIC_MODULE - -def SAMBA3_IS_SHARED_MODULE(bld, module): - '''Check whether module is in shared list''' - if module in bld.env['shared_modules']: - return True - return False -Build.BuildContext.SAMBA3_IS_SHARED_MODULE = SAMBA3_IS_SHARED_MODULE - -def SAMBA3_IS_ENABLED_MODULE(bld, module): - '''Check whether module is in either shared or static list ''' - return SAMBA3_IS_STATIC_MODULE(bld, module) or SAMBA3_IS_SHARED_MODULE(bld, module) -Build.BuildContext.SAMBA3_IS_ENABLED_MODULE = SAMBA3_IS_ENABLED_MODULE - - - -def s3_fix_kwargs(bld, kwargs): - '''fix the build arguments for s3 build rules to include the - necessary includes, subdir and cflags options ''' - s3dir = os.path.join(bld.env.srcdir, 'source3') - s3reldir = os_path_relpath(s3dir, bld.path.abspath()) - - # the extra_includes list is relative to the source3 directory - extra_includes = [ '.', 'include', 'lib' ] - # local heimdal paths only included when USING_SYSTEM_KRB5 is not set - if not bld.CONFIG_SET("USING_SYSTEM_KRB5"): - extra_includes += [ '../source4/heimdal/lib/com_err', - '../source4/heimdal/lib/krb5', - '../source4/heimdal/lib/gssapi', - '../source4/heimdal_build', - '../bin/default/source4/heimdal/lib/asn1' ] - - if bld.CONFIG_SET('USING_SYSTEM_TDB'): - (tdb_includes, tdb_ldflags, tdb_cpppath) = library_flags(bld, 'tdb') - extra_includes += tdb_cpppath - else: - extra_includes += [ '../lib/tdb/include' ] - - if bld.CONFIG_SET('USING_SYSTEM_TEVENT'): - (tevent_includes, tevent_ldflags, tevent_cpppath) = library_flags(bld, 'tevent') - extra_includes += tevent_cpppath - else: - extra_includes += [ '../lib/tevent' ] - - if bld.CONFIG_SET('USING_SYSTEM_TALLOC'): - (talloc_includes, talloc_ldflags, talloc_cpppath) = library_flags(bld, 'talloc') - extra_includes += talloc_cpppath - else: - extra_includes += [ '../lib/talloc' ] - - if bld.CONFIG_SET('USING_SYSTEM_POPT'): - (popt_includes, popt_ldflags, popt_cpppath) = library_flags(bld, 'popt') - extra_includes += popt_cpppath - else: - extra_includes += [ '../lib/popt' ] - - # s3 builds assume that they will have a bunch of extra include paths - includes = [] - for d in extra_includes: - includes += [ os.path.join(s3reldir, d) ] - - # the rule may already have some includes listed - if 'includes' in kwargs: - includes += TO_LIST(kwargs['includes']) - kwargs['includes'] = includes - -# these wrappers allow for mixing of S3 and S4 build rules in the one build - -def SAMBA3_LIBRARY(bld, name, *args, **kwargs): - s3_fix_kwargs(bld, kwargs) - return bld.SAMBA_LIBRARY(name, *args, **kwargs) -Build.BuildContext.SAMBA3_LIBRARY = SAMBA3_LIBRARY - -def SAMBA3_MODULE(bld, name, *args, **kwargs): - s3_fix_kwargs(bld, kwargs) - return bld.SAMBA_MODULE(name, *args, **kwargs) -Build.BuildContext.SAMBA3_MODULE = SAMBA3_MODULE - -def SAMBA3_SUBSYSTEM(bld, name, *args, **kwargs): - s3_fix_kwargs(bld, kwargs) - return bld.SAMBA_SUBSYSTEM(name, *args, **kwargs) -Build.BuildContext.SAMBA3_SUBSYSTEM = SAMBA3_SUBSYSTEM - -def SAMBA3_BINARY(bld, name, *args, **kwargs): - s3_fix_kwargs(bld, kwargs) - return bld.SAMBA_BINARY(name, *args, **kwargs) -Build.BuildContext.SAMBA3_BINARY = SAMBA3_BINARY - -def SAMBA3_PYTHON(bld, name, *args, **kwargs): - s3_fix_kwargs(bld, kwargs) - return bld.SAMBA_PYTHON(name, *args, **kwargs) -Build.BuildContext.SAMBA3_PYTHON = SAMBA3_PYTHON diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_abi.py b/ldb-2.0.8/buildtools/wafsamba/samba_abi.py deleted file mode 100644 index 5e7686d..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/samba_abi.py +++ /dev/null @@ -1,261 +0,0 @@ -# functions for handling ABI checking of libraries - -import os -import sys -import re -import fnmatch - -from waflib import Options, Utils, Logs, Task, Build, Errors -from waflib.TaskGen import feature, before, after -from wafsamba import samba_utils - -# these type maps cope with platform specific names for common types -# please add new type mappings into the list below -abi_type_maps = { - '_Bool' : 'bool', - 'struct __va_list_tag *' : 'va_list' - } - -version_key = lambda x: list(map(int, x.split("."))) - -def normalise_signature(sig): - '''normalise a signature from gdb''' - sig = sig.strip() - sig = re.sub('^\$[0-9]+\s=\s\{(.+)\}$', r'\1', sig) - sig = re.sub('^\$[0-9]+\s=\s\{(.+)\}(\s0x[0-9a-f]+\s<\w+>)+$', r'\1', sig) - sig = re.sub('^\$[0-9]+\s=\s(0x[0-9a-f]+)\s?(<\w+>)?$', r'\1', sig) - sig = re.sub('0x[0-9a-f]+', '0xXXXX', sig) - sig = re.sub('", ', r'\1"', sig) - - for t in abi_type_maps: - # we need to cope with non-word characters in mapped types - m = t - m = m.replace('*', '\*') - if m[-1].isalnum() or m[-1] == '_': - m += '\\b' - if m[0].isalnum() or m[0] == '_': - m = '\\b' + m - sig = re.sub(m, abi_type_maps[t], sig) - return sig - - -def normalise_varargs(sig): - '''cope with older versions of gdb''' - sig = re.sub(',\s\.\.\.', '', sig) - return sig - - -def parse_sigs(sigs, abi_match): - '''parse ABI signatures file''' - abi_match = samba_utils.TO_LIST(abi_match) - ret = {} - a = sigs.split('\n') - for s in a: - if s.find(':') == -1: - continue - sa = s.split(':') - if abi_match: - matched = False - negative = False - for p in abi_match: - if p[0] == '!' and fnmatch.fnmatch(sa[0], p[1:]): - negative = True - break - elif fnmatch.fnmatch(sa[0], p): - matched = True - break - if (not matched) and negative: - continue - Logs.debug("%s -> %s" % (sa[1], normalise_signature(sa[1]))) - ret[sa[0]] = normalise_signature(sa[1]) - return ret - -def save_sigs(sig_file, parsed_sigs): - '''save ABI signatures to a file''' - sigs = '' - for s in sorted(parsed_sigs.keys()): - sigs += '%s: %s\n' % (s, parsed_sigs[s]) - return samba_utils.save_file(sig_file, sigs, create_dir=True) - - -def abi_check_task(self): - '''check if the ABI has changed''' - abi_gen = self.ABI_GEN - - libpath = self.inputs[0].abspath(self.env) - libname = os.path.basename(libpath) - - sigs = samba_utils.get_string(Utils.cmd_output([abi_gen, libpath])) - parsed_sigs = parse_sigs(sigs, self.ABI_MATCH) - - sig_file = self.ABI_FILE - - old_sigs = samba_utils.load_file(sig_file) - if old_sigs is None or Options.options.ABI_UPDATE: - if not save_sigs(sig_file, parsed_sigs): - raise Errors.WafError('Failed to save ABI file "%s"' % sig_file) - Logs.warn('Generated ABI signatures %s' % sig_file) - return - - parsed_old_sigs = parse_sigs(old_sigs, self.ABI_MATCH) - - # check all old sigs - got_error = False - for s in parsed_old_sigs: - if not s in parsed_sigs: - Logs.error('%s: symbol %s has been removed - please update major version\n\tsignature: %s' % ( - libname, s, parsed_old_sigs[s])) - got_error = True - elif normalise_varargs(parsed_old_sigs[s]) != normalise_varargs(parsed_sigs[s]): - Logs.error('%s: symbol %s has changed - please update major version\n\told_signature: %s\n\tnew_signature: %s' % ( - libname, s, parsed_old_sigs[s], parsed_sigs[s])) - got_error = True - - for s in parsed_sigs: - if not s in parsed_old_sigs: - Logs.error('%s: symbol %s has been added - please mark it _PRIVATE_ or update minor version\n\tsignature: %s' % ( - libname, s, parsed_sigs[s])) - got_error = True - - if got_error: - raise Errors.WafError('ABI for %s has changed - please fix library version then build with --abi-update\nSee http://wiki.samba.org/index.php/Waf#ABI_Checking for more information\nIf you have not changed any ABI, and your platform always gives this error, please configure with --abi-check-disable to skip this check' % libname) - - -t = Task.task_factory('abi_check', abi_check_task, color='BLUE', ext_in='.bin') -t.quiet = True -# allow "waf --abi-check" to force re-checking the ABI -if '--abi-check' in sys.argv: - t.always_run = True - -@after('apply_link') -@feature('abi_check') -def abi_check(self): - '''check that ABI matches saved signatures''' - env = self.bld.env - if not env.ABI_CHECK or self.abi_directory is None: - return - - # if the platform doesn't support -fvisibility=hidden then the ABI - # checks become fairly meaningless - if not env.HAVE_VISIBILITY_ATTR: - return - - topsrc = self.bld.srcnode.abspath() - abi_gen = os.path.join(topsrc, 'buildtools/scripts/abi_gen.sh') - - abi_file = "%s/%s-%s.sigs" % (self.abi_directory, self.version_libname, - self.vnum) - - tsk = self.create_task('abi_check', self.link_task.outputs[0]) - tsk.ABI_FILE = abi_file - tsk.ABI_MATCH = self.abi_match - tsk.ABI_GEN = abi_gen - - -def abi_process_file(fname, version, symmap): - '''process one ABI file, adding new symbols to the symmap''' - for line in Utils.readf(fname).splitlines(): - symname = line.split(":")[0] - if not symname in symmap: - symmap[symname] = version - - -def abi_write_vscript(f, libname, current_version, versions, symmap, abi_match): - """Write a vscript file for a library in --version-script format. - - :param f: File-like object to write to - :param libname: Name of the library, uppercased - :param current_version: Current version - :param versions: Versions to consider - :param symmap: Dictionary mapping symbols -> version - :param abi_match: List of symbols considered to be public in the current - version - """ - - invmap = {} - for s in symmap: - invmap.setdefault(symmap[s], []).append(s) - - last_key = "" - versions = sorted(versions, key=version_key) - for k in versions: - symver = "%s_%s" % (libname, k) - if symver == current_version: - break - f.write("%s {\n" % symver) - if k in sorted(invmap.keys()): - f.write("\tglobal:\n") - for s in invmap.get(k, []): - f.write("\t\t%s;\n" % s); - f.write("}%s;\n\n" % last_key) - last_key = " %s" % symver - f.write("%s {\n" % current_version) - local_abi = list(filter(lambda x: x[0] == '!', abi_match)) - global_abi = list(filter(lambda x: x[0] != '!', abi_match)) - f.write("\tglobal:\n") - if len(global_abi) > 0: - for x in global_abi: - f.write("\t\t%s;\n" % x) - else: - f.write("\t\t*;\n") - # Always hide symbols that must be local if exist - local_abi.extend(["!_end", "!__bss_start", "!_edata"]) - f.write("\tlocal:\n") - for x in local_abi: - f.write("\t\t%s;\n" % x[1:]) - if global_abi != ["*"]: - if len(global_abi) > 0: - f.write("\t\t*;\n") - f.write("};\n") - - -def abi_build_vscript(task): - '''generate a vscript file for our public libraries''' - - tgt = task.outputs[0].bldpath(task.env) - - symmap = {} - versions = [] - for f in task.inputs: - fname = f.abspath(task.env) - basename = os.path.basename(fname) - version = basename[len(task.env.LIBNAME)+1:-len(".sigs")] - versions.append(version) - abi_process_file(fname, version, symmap) - f = open(tgt, mode='w') - try: - abi_write_vscript(f, task.env.LIBNAME, task.env.VERSION, versions, - symmap, task.env.ABI_MATCH) - finally: - f.close() - - -def ABI_VSCRIPT(bld, libname, abi_directory, version, vscript, abi_match=None): - '''generate a vscript file for our public libraries''' - if abi_directory: - source = bld.path.ant_glob('%s/%s-[0-9]*.sigs' % (abi_directory, libname), flat=True) - def abi_file_key(path): - return version_key(path[:-len(".sigs")].rsplit("-")[-1]) - source = sorted(source.split(), key=abi_file_key) - else: - source = '' - - libname = os.path.basename(libname) - version = os.path.basename(version) - libname = libname.replace("-", "_").replace("+","_").upper() - version = version.replace("-", "_").replace("+","_").upper() - - t = bld.SAMBA_GENERATOR(vscript, - rule=abi_build_vscript, - source=source, - group='vscripts', - target=vscript) - if abi_match is None: - abi_match = ["*"] - else: - abi_match = samba_utils.TO_LIST(abi_match) - t.env.ABI_MATCH = abi_match - t.env.VERSION = version - t.env.LIBNAME = libname - t.vars = ['LIBNAME', 'VERSION', 'ABI_MATCH'] -Build.BuildContext.ABI_VSCRIPT = ABI_VSCRIPT diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_autoconf.py b/ldb-2.0.8/buildtools/wafsamba/samba_autoconf.py deleted file mode 100644 index 62d3e20..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/samba_autoconf.py +++ /dev/null @@ -1,948 +0,0 @@ -# a waf tool to add autoconf-like macros to the configure section - -import os, sys -from waflib import Build, Options, Logs, Context -from waflib.Configure import conf -from waflib.TaskGen import feature -from waflib.Tools import c_preproc as preproc -from samba_utils import TO_LIST, GET_TARGET_TYPE, SET_TARGET_TYPE, unique_list, mkdir_p - -missing_headers = set() - -#################################################### -# some autoconf like helpers, to make the transition -# to waf a bit easier for those used to autoconf -# m4 files - -@conf -def DEFINE(conf, d, v, add_to_cflags=False, quote=False): - '''define a config option''' - conf.define(d, v, quote=quote) - if add_to_cflags: - conf.env.append_value('CFLAGS', '-D%s=%s' % (d, str(v))) - -def hlist_to_string(conf, headers=None): - '''convert a headers list to a set of #include lines''' - hdrs='' - hlist = conf.env.hlist - if headers: - hlist = hlist[:] - hlist.extend(TO_LIST(headers)) - for h in hlist: - hdrs += '#include <%s>\n' % h - return hdrs - - -@conf -def COMPOUND_START(conf, msg): - '''start a compound test''' - def null_check_message_1(self,*k,**kw): - return - def null_check_message_2(self,*k,**kw): - return - - v = getattr(conf.env, 'in_compound', []) - if v != [] and v != 0: - conf.env.in_compound = v + 1 - return - conf.start_msg(msg) - conf.saved_check_message_1 = conf.start_msg - conf.start_msg = null_check_message_1 - conf.saved_check_message_2 = conf.end_msg - conf.end_msg = null_check_message_2 - conf.env.in_compound = 1 - - -@conf -def COMPOUND_END(conf, result): - '''start a compound test''' - conf.env.in_compound -= 1 - if conf.env.in_compound != 0: - return - conf.start_msg = conf.saved_check_message_1 - conf.end_msg = conf.saved_check_message_2 - p = conf.end_msg - if result is True: - p('ok') - elif not result: - p('not found', 'YELLOW') - else: - p(result) - - -@feature('nolink') -def nolink(self): - '''using the nolink type in conf.check() allows us to avoid - the link stage of a test, thus speeding it up for tests - that where linking is not needed''' - pass - - -def CHECK_HEADER(conf, h, add_headers=False, lib=None): - '''check for a header''' - if h in missing_headers and lib is None: - return False - d = h.upper().replace('/', '_') - d = d.replace('.', '_') - d = d.replace('-', '_') - d = 'HAVE_%s' % d - if CONFIG_SET(conf, d): - if add_headers: - if not h in conf.env.hlist: - conf.env.hlist.append(h) - return True - - (ccflags, ldflags, cpppath) = library_flags(conf, lib) - - hdrs = hlist_to_string(conf, headers=h) - if lib is None: - lib = "" - ret = conf.check(fragment='%s\nint main(void) { return 0; }\n' % hdrs, - type='nolink', - execute=0, - cflags=ccflags, - mandatory=False, - includes=cpppath, - uselib=lib.upper(), - msg="Checking for header %s" % h) - if not ret: - missing_headers.add(h) - return False - - conf.DEFINE(d, 1) - if add_headers and not h in conf.env.hlist: - conf.env.hlist.append(h) - return ret - - -@conf -def CHECK_HEADERS(conf, headers, add_headers=False, together=False, lib=None): - '''check for a list of headers - - when together==True, then the headers accumulate within this test. - This is useful for interdependent headers - ''' - ret = True - if not add_headers and together: - saved_hlist = conf.env.hlist[:] - set_add_headers = True - else: - set_add_headers = add_headers - for hdr in TO_LIST(headers): - if not CHECK_HEADER(conf, hdr, set_add_headers, lib=lib): - ret = False - if not add_headers and together: - conf.env.hlist = saved_hlist - return ret - - -def header_list(conf, headers=None, lib=None): - '''form a list of headers which exist, as a string''' - hlist=[] - if headers is not None: - for h in TO_LIST(headers): - if CHECK_HEADER(conf, h, add_headers=False, lib=lib): - hlist.append(h) - return hlist_to_string(conf, headers=hlist) - - -@conf -def CHECK_TYPE(conf, t, alternate=None, headers=None, define=None, lib=None, msg=None): - '''check for a single type''' - if define is None: - define = 'HAVE_' + t.upper().replace(' ', '_') - if msg is None: - msg='Checking for %s' % t - ret = CHECK_CODE(conf, '%s _x' % t, - define, - execute=False, - headers=headers, - local_include=False, - msg=msg, - lib=lib, - link=False) - if not ret and alternate: - conf.DEFINE(t, alternate) - return ret - - -@conf -def CHECK_TYPES(conf, list, headers=None, define=None, alternate=None, lib=None): - '''check for a list of types''' - ret = True - for t in TO_LIST(list): - if not CHECK_TYPE(conf, t, headers=headers, - define=define, alternate=alternate, lib=lib): - ret = False - return ret - - -@conf -def CHECK_TYPE_IN(conf, t, headers=None, alternate=None, define=None): - '''check for a single type with a header''' - return CHECK_TYPE(conf, t, headers=headers, alternate=alternate, define=define) - - -@conf -def CHECK_VARIABLE(conf, v, define=None, always=False, - headers=None, msg=None, lib=None): - '''check for a variable declaration (or define)''' - if define is None: - define = 'HAVE_%s' % v.upper() - - if msg is None: - msg="Checking for variable %s" % v - - return CHECK_CODE(conf, - # we need to make sure the compiler doesn't - # optimize it out... - ''' - #ifndef %s - void *_x; _x=(void *)&%s; return (int)_x; - #endif - return 0 - ''' % (v, v), - execute=False, - link=False, - msg=msg, - local_include=False, - lib=lib, - headers=headers, - define=define, - always=always) - - -@conf -def CHECK_DECLS(conf, vars, reverse=False, headers=None, always=False): - '''check a list of variable declarations, using the HAVE_DECL_xxx form - of define - - When reverse==True then use HAVE_xxx_DECL instead of HAVE_DECL_xxx - ''' - ret = True - for v in TO_LIST(vars): - if not reverse: - define='HAVE_DECL_%s' % v.upper() - else: - define='HAVE_%s_DECL' % v.upper() - if not CHECK_VARIABLE(conf, v, - define=define, - headers=headers, - msg='Checking for declaration of %s' % v, - always=always): - if not CHECK_CODE(conf, - ''' - return (int)%s; - ''' % (v), - execute=False, - link=False, - msg='Checking for declaration of %s (as enum)' % v, - local_include=False, - headers=headers, - define=define, - always=always): - ret = False - return ret - - -def CHECK_FUNC(conf, f, link=True, lib=None, headers=None): - '''check for a function''' - define='HAVE_%s' % f.upper() - - ret = False - - in_lib_str = "" - if lib: - in_lib_str = " in %s" % lib - conf.COMPOUND_START('Checking for %s%s' % (f, in_lib_str)) - - if link is None or link: - ret = CHECK_CODE(conf, - # this is based on the autoconf strategy - ''' - #define %s __fake__%s - #ifdef HAVE_LIMITS_H - # include - #else - # include - #endif - #undef %s - #if defined __stub_%s || defined __stub___%s - #error "bad glibc stub" - #endif - extern char %s(); - int main() { return %s(); } - ''' % (f, f, f, f, f, f, f), - execute=False, - link=True, - addmain=False, - add_headers=False, - define=define, - local_include=False, - lib=lib, - headers=headers, - msg='Checking for %s' % f) - - if not ret: - ret = CHECK_CODE(conf, - # it might be a macro - # we need to make sure the compiler doesn't - # optimize it out... - 'void *__x = (void *)%s; return (int)__x' % f, - execute=False, - link=True, - addmain=True, - add_headers=True, - define=define, - local_include=False, - lib=lib, - headers=headers, - msg='Checking for macro %s' % f) - - if not ret and (link is None or not link): - ret = CHECK_VARIABLE(conf, f, - define=define, - headers=headers, - msg='Checking for declaration of %s' % f) - conf.COMPOUND_END(ret) - return ret - - -@conf -def CHECK_FUNCS(conf, list, link=True, lib=None, headers=None): - '''check for a list of functions''' - ret = True - for f in TO_LIST(list): - if not CHECK_FUNC(conf, f, link=link, lib=lib, headers=headers): - ret = False - return ret - - -@conf -def CHECK_SIZEOF(conf, vars, headers=None, define=None, critical=True): - '''check the size of a type''' - for v in TO_LIST(vars): - v_define = define - ret = False - if v_define is None: - v_define = 'SIZEOF_%s' % v.upper().replace(' ', '_') - for size in list((1, 2, 4, 8, 16, 32, 64)): - if CHECK_CODE(conf, - 'static int test_array[1 - 2 * !(((long int)(sizeof(%s))) <= %d)];' % (v, size), - define=v_define, - quote=False, - headers=headers, - local_include=False, - msg="Checking if size of %s == %d" % (v, size)): - conf.DEFINE(v_define, size) - ret = True - break - if not ret and critical: - Logs.error("Couldn't determine size of '%s'" % v) - sys.exit(1) - return ret - -@conf -def CHECK_VALUEOF(conf, v, headers=None, define=None): - '''check the value of a variable/define''' - ret = True - v_define = define - if v_define is None: - v_define = 'VALUEOF_%s' % v.upper().replace(' ', '_') - if CHECK_CODE(conf, - 'printf("%%u", (unsigned)(%s))' % v, - define=v_define, - execute=True, - define_ret=True, - quote=False, - headers=headers, - local_include=False, - msg="Checking value of %s" % v): - return int(conf.env[v_define]) - - return None - -@conf -def CHECK_CODE(conf, code, define, - always=False, execute=False, addmain=True, - add_headers=True, mandatory=False, - headers=None, msg=None, cflags='', includes='# .', - local_include=True, lib=None, link=True, - define_ret=False, quote=False, - on_target=True, strict=False): - '''check if some code compiles and/or runs''' - - if CONFIG_SET(conf, define): - return True - - if headers is not None: - CHECK_HEADERS(conf, headers=headers, lib=lib) - - if add_headers: - hdrs = header_list(conf, headers=headers, lib=lib) - else: - hdrs = '' - if execute: - execute = 1 - else: - execute = 0 - - if addmain: - fragment='%s\n int main(void) { %s; return 0; }\n' % (hdrs, code) - else: - fragment='%s\n%s\n' % (hdrs, code) - - if msg is None: - msg="Checking for %s" % define - - cflags = TO_LIST(cflags) - - # Be strict when relying on a compiler check - # Some compilers (e.g. xlc) ignore non-supported features as warnings - if strict: - if 'WERROR_CFLAGS' in conf.env: - cflags.extend(conf.env['WERROR_CFLAGS']) - - if local_include: - cflags.append('-I%s' % conf.path.abspath()) - - if not link: - type='nolink' - else: - type='cprogram' - - uselib = TO_LIST(lib) - - (ccflags, ldflags, cpppath) = library_flags(conf, uselib) - - includes = TO_LIST(includes) - includes.extend(cpppath) - - uselib = [l.upper() for l in uselib] - - cflags.extend(ccflags) - - if on_target: - test_args = conf.SAMBA_CROSS_ARGS(msg=msg) - else: - test_args = [] - - conf.COMPOUND_START(msg) - - try: - ret = conf.check(fragment=fragment, - execute=execute, - define_name = define, - cflags=cflags, - ldflags=ldflags, - includes=includes, - uselib=uselib, - type=type, - msg=msg, - quote=quote, - test_args=test_args, - define_ret=define_ret) - except Exception: - if always: - conf.DEFINE(define, 0) - else: - conf.undefine(define) - conf.COMPOUND_END(False) - if mandatory: - raise - return False - else: - # Success is indicated by ret but we should unset - # defines set by WAF's c_config.check() because it - # defines it to int(ret) and we want to undefine it - if not ret: - conf.undefine(define) - conf.COMPOUND_END(False) - return False - if not define_ret: - conf.DEFINE(define, 1) - conf.COMPOUND_END(True) - else: - conf.DEFINE(define, ret, quote=quote) - conf.COMPOUND_END(ret) - return True - - -@conf -def CHECK_STRUCTURE_MEMBER(conf, structname, member, - always=False, define=None, headers=None, - lib=None): - '''check for a structure member''' - if define is None: - define = 'HAVE_%s' % member.upper() - return CHECK_CODE(conf, - '%s s; void *_x; _x=(void *)&s.%s' % (structname, member), - define, - execute=False, - link=False, - lib=lib, - always=always, - headers=headers, - local_include=False, - msg="Checking for member %s in %s" % (member, structname)) - - -@conf -def CHECK_CFLAGS(conf, cflags, fragment='int main(void) { return 0; }\n'): - '''check if the given cflags are accepted by the compiler - ''' - check_cflags = TO_LIST(cflags) - if 'WERROR_CFLAGS' in conf.env: - check_cflags.extend(conf.env['WERROR_CFLAGS']) - return conf.check(fragment=fragment, - execute=0, - mandatory=False, - type='nolink', - cflags=check_cflags, - msg="Checking compiler accepts %s" % cflags) - -@conf -def CHECK_LDFLAGS(conf, ldflags): - '''check if the given ldflags are accepted by the linker - ''' - return conf.check(fragment='int main(void) { return 0; }\n', - execute=0, - ldflags=ldflags, - mandatory=False, - msg="Checking linker accepts %s" % ldflags) - - -@conf -def CONFIG_GET(conf, option): - '''return True if a configuration option was found''' - if (option in conf.env): - return conf.env[option] - else: - return None - -@conf -def CONFIG_SET(conf, option): - '''return True if a configuration option was found''' - if option not in conf.env: - return False - v = conf.env[option] - if v is None: - return False - if v == []: - return False - if v == (): - return False - return True - -@conf -def CONFIG_RESET(conf, option): - if option not in conf.env: - return - del conf.env[option] - -Build.BuildContext.CONFIG_RESET = CONFIG_RESET -Build.BuildContext.CONFIG_SET = CONFIG_SET -Build.BuildContext.CONFIG_GET = CONFIG_GET - - -def library_flags(self, libs): - '''work out flags from pkg_config''' - ccflags = [] - ldflags = [] - cpppath = [] - for lib in TO_LIST(libs): - # note that we do not add the -I and -L in here, as that is added by the waf - # core. Adding it here would just change the order that it is put on the link line - # which can cause system paths to be added before internal libraries - extra_ccflags = TO_LIST(getattr(self.env, 'CFLAGS_%s' % lib.upper(), [])) - extra_ldflags = TO_LIST(getattr(self.env, 'LDFLAGS_%s' % lib.upper(), [])) - extra_cpppath = TO_LIST(getattr(self.env, 'CPPPATH_%s' % lib.upper(), [])) - ccflags.extend(extra_ccflags) - ldflags.extend(extra_ldflags) - cpppath.extend(extra_cpppath) - - extra_cpppath = TO_LIST(getattr(self.env, 'INCLUDES_%s' % lib.upper(), [])) - cpppath.extend(extra_cpppath) - if 'EXTRA_LDFLAGS' in self.env: - ldflags.extend(self.env['EXTRA_LDFLAGS']) - - ccflags = unique_list(ccflags) - ldflags = unique_list(ldflags) - cpppath = unique_list(cpppath) - return (ccflags, ldflags, cpppath) - - -@conf -def CHECK_LIB(conf, libs, mandatory=False, empty_decl=True, set_target=True, shlib=False): - '''check if a set of libraries exist as system libraries - - returns the sublist of libs that do exist as a syslib or [] - ''' - - fragment= ''' -int foo() -{ - int v = 2; - return v*2; -} -''' - ret = [] - liblist = TO_LIST(libs) - for lib in liblist[:]: - if GET_TARGET_TYPE(conf, lib) == 'SYSLIB': - ret.append(lib) - continue - - (ccflags, ldflags, cpppath) = library_flags(conf, lib) - if shlib: - res = conf.check(features='c cshlib', fragment=fragment, lib=lib, uselib_store=lib, cflags=ccflags, ldflags=ldflags, uselib=lib.upper(), mandatory=False) - else: - res = conf.check(lib=lib, uselib_store=lib, cflags=ccflags, ldflags=ldflags, uselib=lib.upper(), mandatory=False) - - if not res: - if mandatory: - Logs.error("Mandatory library '%s' not found for functions '%s'" % (lib, list)) - sys.exit(1) - if empty_decl: - # if it isn't a mandatory library, then remove it from dependency lists - if set_target: - SET_TARGET_TYPE(conf, lib, 'EMPTY') - else: - conf.define('HAVE_LIB%s' % lib.upper().replace('-','_').replace('.','_'), 1) - conf.env['LIB_' + lib.upper()] = lib - if set_target: - conf.SET_TARGET_TYPE(lib, 'SYSLIB') - ret.append(lib) - - return ret - - - -@conf -def CHECK_FUNCS_IN(conf, list, library, mandatory=False, checklibc=False, - headers=None, link=True, empty_decl=True, set_target=True): - """ - check that the functions in 'list' are available in 'library' - if they are, then make that library available as a dependency - - if the library is not available and mandatory==True, then - raise an error. - - If the library is not available and mandatory==False, then - add the library to the list of dependencies to remove from - build rules - - optionally check for the functions first in libc - """ - remaining = TO_LIST(list) - liblist = TO_LIST(library) - - # check if some already found - for f in remaining[:]: - if CONFIG_SET(conf, 'HAVE_%s' % f.upper()): - remaining.remove(f) - - # see if the functions are in libc - if checklibc: - for f in remaining[:]: - if CHECK_FUNC(conf, f, link=True, headers=headers): - remaining.remove(f) - - if remaining == []: - for lib in liblist: - if GET_TARGET_TYPE(conf, lib) != 'SYSLIB' and empty_decl: - SET_TARGET_TYPE(conf, lib, 'EMPTY') - return True - - checklist = conf.CHECK_LIB(liblist, empty_decl=empty_decl, set_target=set_target) - for lib in liblist[:]: - if not lib in checklist and mandatory: - Logs.error("Mandatory library '%s' not found for functions '%s'" % (lib, list)) - sys.exit(1) - - ret = True - for f in remaining: - if not CHECK_FUNC(conf, f, lib=' '.join(checklist), headers=headers, link=link): - ret = False - - return ret - - -@conf -def IN_LAUNCH_DIR(conf): - '''return True if this rule is being run from the launch directory''' - return os.path.realpath(conf.path.abspath()) == os.path.realpath(Context.launch_dir) -Options.OptionsContext.IN_LAUNCH_DIR = IN_LAUNCH_DIR - - -@conf -def SAMBA_CONFIG_H(conf, path=None): - '''write out config.h in the right directory''' - # we don't want to produce a config.h in places like lib/replace - # when we are building projects that depend on lib/replace - if not IN_LAUNCH_DIR(conf): - return - - # we need to build real code that can't be optimized away to test - stack_protect_list = ['-fstack-protector-strong', '-fstack-protector'] - for stack_protect_flag in stack_protect_list: - flag_supported = conf.check(fragment=''' - #include - - int main(void) - { - char t[100000]; - while (fgets(t, sizeof(t), stdin)); - return 0; - } - ''', - execute=0, - cflags=[ '-Werror', '-Wp,-D_FORTIFY_SOURCE=2', stack_protect_flag], - mandatory=False, - msg='Checking if compiler accepts %s' % (stack_protect_flag)) - if flag_supported: - conf.ADD_CFLAGS('%s' % (stack_protect_flag)) - break - - flag_supported = conf.check(fragment=''' - #include - - int main(void) - { - char t[100000]; - while (fgets(t, sizeof(t), stdin)); - return 0; - } - ''', - execute=0, - cflags=[ '-Werror', '-fstack-clash-protection'], - mandatory=False, - msg='Checking if compiler accepts -fstack-clash-protection') - if flag_supported: - conf.ADD_CFLAGS('-fstack-clash-protection') - - if Options.options.debug: - conf.ADD_CFLAGS('-g', testflags=True) - - if Options.options.developer: - conf.env.DEVELOPER_MODE = True - - conf.ADD_CFLAGS('-g', testflags=True) - conf.ADD_CFLAGS('-Wall', testflags=True) - conf.ADD_CFLAGS('-Wshadow', testflags=True) - conf.ADD_CFLAGS('-Wmissing-prototypes', testflags=True) - if CHECK_CODE(conf, - 'struct a { int b; }; struct c { struct a d; } e = { };', - 'CHECK_C99_INIT', - link=False, - cflags='-Wmissing-field-initializers -Werror=missing-field-initializers', - msg="Checking C99 init of nested structs."): - conf.ADD_CFLAGS('-Wmissing-field-initializers', testflags=True) - conf.ADD_CFLAGS('-Wformat-overflow=2', testflags=True) - conf.ADD_CFLAGS('-Wformat-zero-length', testflags=True) - conf.ADD_CFLAGS('-Wcast-align -Wcast-qual', testflags=True) - conf.ADD_CFLAGS('-fno-common', testflags=True) - - conf.ADD_CFLAGS('-Werror=address', testflags=True) - # we add these here to ensure that -Wstrict-prototypes is not set during configure - conf.ADD_CFLAGS('-Werror=strict-prototypes -Wstrict-prototypes', - testflags=True) - conf.ADD_CFLAGS('-Werror=write-strings -Wwrite-strings', - testflags=True) - conf.ADD_CFLAGS('-Werror-implicit-function-declaration', - testflags=True) - conf.ADD_CFLAGS('-Werror=pointer-arith -Wpointer-arith', - testflags=True) - conf.ADD_CFLAGS('-Werror=declaration-after-statement -Wdeclaration-after-statement', - testflags=True) - conf.ADD_CFLAGS('-Werror=return-type -Wreturn-type', - testflags=True) - conf.ADD_CFLAGS('-Werror=uninitialized -Wuninitialized', - testflags=True) - conf.ADD_CFLAGS('-Wimplicit-fallthrough', - testflags=True) - conf.ADD_CFLAGS('-Werror=strict-overflow -Wstrict-overflow=2', - testflags=True) - - conf.ADD_CFLAGS('-Wformat=2 -Wno-format-y2k', testflags=True) - conf.ADD_CFLAGS('-Wno-format-zero-length', testflags=True) - conf.ADD_CFLAGS('-Werror=format-security -Wformat-security', - testflags=True, prereq_flags='-Wformat') - # This check is because for ldb_search(), a NULL format string - # is not an error, but some compilers complain about that. - if CHECK_CFLAGS(conf, ["-Werror=format", "-Wformat=2"], ''' -int testformat(char *format, ...) __attribute__ ((format (__printf__, 1, 2))); - -int main(void) { - testformat(0); - return 0; -} - -'''): - if not 'EXTRA_CFLAGS' in conf.env: - conf.env['EXTRA_CFLAGS'] = [] - conf.env['EXTRA_CFLAGS'].extend(TO_LIST("-Werror=format")) - - if Options.options.picky_developer: - conf.ADD_NAMED_CFLAGS('PICKY_CFLAGS', '-Werror -Wno-error=deprecated-declarations', testflags=True) - conf.ADD_NAMED_CFLAGS('PICKY_CFLAGS', '-Wno-error=tautological-compare', testflags=True) - - if Options.options.fatal_errors: - conf.ADD_CFLAGS('-Wfatal-errors', testflags=True) - - if Options.options.pedantic: - conf.ADD_CFLAGS('-W', testflags=True) - - if (Options.options.address_sanitizer or - Options.options.undefined_sanitizer): - conf.ADD_CFLAGS('-g -O1', testflags=True) - if Options.options.address_sanitizer: - conf.ADD_CFLAGS('-fno-omit-frame-pointer', testflags=True) - conf.ADD_CFLAGS('-fsanitize=address', testflags=True) - conf.ADD_LDFLAGS('-fsanitize=address', testflags=True) - conf.env['ADDRESS_SANITIZER'] = True - if Options.options.undefined_sanitizer: - conf.ADD_CFLAGS('-fsanitize=undefined', testflags=True) - conf.ADD_CFLAGS('-fsanitize=null', testflags=True) - conf.ADD_CFLAGS('-fsanitize=alignment', testflags=True) - conf.ADD_LDFLAGS('-fsanitize=undefined', testflags=True) - conf.env['UNDEFINED_SANITIZER'] = True - - - # Let people pass an additional ADDITIONAL_{CFLAGS,LDFLAGS} - # environment variables which are only used the for final build. - # - # The CFLAGS and LDFLAGS environment variables are also - # used for the configure checks which might impact their results. - conf.add_os_flags('ADDITIONAL_CFLAGS') - if conf.env.ADDITIONAL_CFLAGS and conf.CHECK_CFLAGS(conf.env['ADDITIONAL_CFLAGS']): - conf.env['EXTRA_CFLAGS'].extend(conf.env['ADDITIONAL_CFLAGS']) - conf.add_os_flags('ADDITIONAL_LDFLAGS') - if conf.env.ADDITIONAL_LDFLAGS and conf.CHECK_LDFLAGS(conf.env['ADDITIONAL_LDFLAGS']): - conf.env['EXTRA_LDFLAGS'].extend(conf.env['ADDITIONAL_LDFLAGS']) - - if path is None: - conf.write_config_header('default/config.h', top=True, remove=False) - else: - conf.write_config_header(os.path.join(conf.variant, path), remove=False) - for key in conf.env.define_key: - conf.undefine(key, from_env=False) - conf.env.define_key = [] - conf.SAMBA_CROSS_CHECK_COMPLETE() - - -@conf -def CONFIG_PATH(conf, name, default): - '''setup a configurable path''' - if not name in conf.env: - if default[0] == '/': - conf.env[name] = default - else: - conf.env[name] = conf.env['PREFIX'] + default - -@conf -def ADD_NAMED_CFLAGS(conf, name, flags, testflags=False, prereq_flags=[]): - '''add some CFLAGS to the command line - optionally set testflags to ensure all the flags work - ''' - prereq_flags = TO_LIST(prereq_flags) - if testflags: - ok_flags=[] - for f in flags.split(): - if CHECK_CFLAGS(conf, [f] + prereq_flags): - ok_flags.append(f) - flags = ok_flags - if not name in conf.env: - conf.env[name] = [] - conf.env[name].extend(TO_LIST(flags)) - -@conf -def ADD_CFLAGS(conf, flags, testflags=False, prereq_flags=[]): - '''add some CFLAGS to the command line - optionally set testflags to ensure all the flags work - ''' - ADD_NAMED_CFLAGS(conf, 'EXTRA_CFLAGS', flags, testflags=testflags, - prereq_flags=prereq_flags) - -@conf -def ADD_LDFLAGS(conf, flags, testflags=False): - '''add some LDFLAGS to the command line - optionally set testflags to ensure all the flags work - - this will return the flags that are added, if any - ''' - if testflags: - ok_flags=[] - for f in flags.split(): - if CHECK_LDFLAGS(conf, f): - ok_flags.append(f) - flags = ok_flags - if not 'EXTRA_LDFLAGS' in conf.env: - conf.env['EXTRA_LDFLAGS'] = [] - conf.env['EXTRA_LDFLAGS'].extend(TO_LIST(flags)) - return flags - - -@conf -def ADD_EXTRA_INCLUDES(conf, includes): - '''add some extra include directories to all builds''' - if not 'EXTRA_INCLUDES' in conf.env: - conf.env['EXTRA_INCLUDES'] = [] - conf.env['EXTRA_INCLUDES'].extend(TO_LIST(includes)) - - - -def CURRENT_CFLAGS(bld, target, cflags, allow_warnings=False, hide_symbols=False): - '''work out the current flags. local flags are added first''' - ret = TO_LIST(cflags) - if not 'EXTRA_CFLAGS' in bld.env: - list = [] - else: - list = bld.env['EXTRA_CFLAGS']; - ret.extend(list) - if not allow_warnings and 'PICKY_CFLAGS' in bld.env: - list = bld.env['PICKY_CFLAGS']; - ret.extend(list) - if hide_symbols and bld.env.HAVE_VISIBILITY_ATTR: - ret.append(bld.env.VISIBILITY_CFLAGS) - return ret - - -@conf -def CHECK_CC_ENV(conf): - """trim whitespaces from 'CC'. - The build farm sometimes puts a space at the start""" - if os.environ.get('CC'): - conf.env.CC = TO_LIST(os.environ.get('CC')) - - -@conf -def SETUP_CONFIGURE_CACHE(conf, enable): - '''enable/disable cache of configure results''' - if enable: - # when -C is chosen, we will use a private cache and will - # not look into system includes. This roughtly matches what - # autoconf does with -C - cache_path = os.path.join(conf.bldnode.abspath(), '.confcache') - mkdir_p(cache_path) - Options.cache_global = os.environ['WAFCACHE'] = cache_path - else: - # when -C is not chosen we will not cache configure checks - # We set the recursion limit low to prevent waf from spending - # a lot of time on the signatures of the files. - Options.cache_global = os.environ['WAFCACHE'] = '' - preproc.recursion_limit = 1 - # in either case we don't need to scan system includes - preproc.go_absolute = False - - -@conf -def SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS(conf): - if not sys.platform.startswith("openbsd"): - # we don't want any libraries or modules to rely on runtime - # resolution of symbols - conf.env.undefined_ldflags = conf.ADD_LDFLAGS('-Wl,-no-undefined', testflags=True) - - if (conf.env.undefined_ignore_ldflags == [] and - conf.CHECK_LDFLAGS(['-undefined', 'dynamic_lookup'])): - conf.env.undefined_ignore_ldflags = ['-undefined', 'dynamic_lookup'] diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_autoproto.py b/ldb-2.0.8/buildtools/wafsamba/samba_autoproto.py deleted file mode 100644 index ace434f..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/samba_autoproto.py +++ /dev/null @@ -1,24 +0,0 @@ -# waf build tool for building automatic prototypes from C source - -import os -from waflib import Build -from samba_utils import SET_TARGET_TYPE, os_path_relpath - -def SAMBA_AUTOPROTO(bld, header, source): - '''rule for samba prototype generation''' - bld.SET_BUILD_GROUP('prototypes') - relpath = os_path_relpath(bld.path.abspath(), bld.srcnode.abspath()) - name = os.path.join(relpath, header) - SET_TARGET_TYPE(bld, name, 'PROTOTYPE') - t = bld( - name = name, - source = source, - target = header, - update_outputs=True, - ext_out='.c', - before ='c', - rule = '${PERL} "${SCRIPT}/mkproto.pl" --srcdir=.. --builddir=. --public=/dev/null --private="${TGT}" ${SRC}' - ) - t.env.SCRIPT = os.path.join(bld.srcnode.abspath(), 'source4/script') -Build.BuildContext.SAMBA_AUTOPROTO = SAMBA_AUTOPROTO - diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_bundled.py b/ldb-2.0.8/buildtools/wafsamba/samba_bundled.py deleted file mode 100644 index 60ce7da..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/samba_bundled.py +++ /dev/null @@ -1,274 +0,0 @@ -# functions to support bundled libraries - -import sys -from waflib import Build, Options, Logs -from waflib.Configure import conf -from wafsamba import samba_utils - -def PRIVATE_NAME(bld, name, private_extension, private_library): - '''possibly rename a library to include a bundled extension''' - - if not private_library: - return name - - # we now use the same private name for libraries as the public name. - # see http://git.samba.org/?p=tridge/junkcode.git;a=tree;f=shlib for a - # demonstration that this is the right thing to do - # also see http://lists.samba.org/archive/samba-technical/2011-January/075816.html - if private_extension: - return name - - extension = bld.env.PRIVATE_EXTENSION - - if extension and name.startswith('%s' % extension): - return name - - if extension and name.endswith('%s' % extension): - return name - - return "%s-%s" % (name, extension) - - -def target_in_list(target, lst, default): - for l in lst: - if target == l: - return True - if '!' + target == l: - return False - if l == 'ALL': - return True - if l == 'NONE': - return False - return default - - -def BUILTIN_LIBRARY(bld, name): - '''return True if a library should be builtin - instead of being built as a shared lib''' - return target_in_list(name, bld.env.BUILTIN_LIBRARIES, False) -Build.BuildContext.BUILTIN_LIBRARY = BUILTIN_LIBRARY - - -def BUILTIN_DEFAULT(opt, builtins): - '''set a comma separated default list of builtin libraries for this package''' - if 'BUILTIN_LIBRARIES_DEFAULT' in Options.options.__dict__: - return - Options.options.__dict__['BUILTIN_LIBRARIES_DEFAULT'] = builtins -Options.OptionsContext.BUILTIN_DEFAULT = BUILTIN_DEFAULT - - -def PRIVATE_EXTENSION_DEFAULT(opt, extension, noextension=''): - '''set a default private library extension''' - if 'PRIVATE_EXTENSION_DEFAULT' in Options.options.__dict__: - return - Options.options.__dict__['PRIVATE_EXTENSION_DEFAULT'] = extension - Options.options.__dict__['PRIVATE_EXTENSION_EXCEPTION'] = noextension -Options.OptionsContext.PRIVATE_EXTENSION_DEFAULT = PRIVATE_EXTENSION_DEFAULT - - -def minimum_library_version(conf, libname, default): - '''allow override of mininum system library version''' - - minlist = Options.options.MINIMUM_LIBRARY_VERSION - if not minlist: - return default - - for m in minlist.split(','): - a = m.split(':') - if len(a) != 2: - Logs.error("Bad syntax for --minimum-library-version of %s" % m) - sys.exit(1) - if a[0] == libname: - return a[1] - return default - - -@conf -def LIB_MAY_BE_BUNDLED(conf, libname): - if libname in conf.env.SYSTEM_LIBS: - return False - if libname in conf.env.BUNDLED_LIBS: - return True - if '!%s' % libname in conf.env.BUNDLED_LIBS: - return False - if 'NONE' in conf.env.BUNDLED_LIBS: - return False - return True - -@conf -def LIB_MUST_BE_BUNDLED(conf, libname): - if libname in conf.env.BUNDLED_LIBS: - return True - if '!%s' % libname in conf.env.BUNDLED_LIBS: - return False - if 'ALL' in conf.env.BUNDLED_LIBS: - return True - return False - -@conf -def LIB_MUST_BE_PRIVATE(conf, libname): - return ('ALL' in conf.env.PRIVATE_LIBS or - libname in conf.env.PRIVATE_LIBS) - -@conf -def CHECK_BUNDLED_SYSTEM_PKG(conf, libname, minversion='0.0.0', - maxversion=None, version_blacklist=[], - onlyif=None, implied_deps=None, pkg=None): - '''check if a library is available as a system library. - - This only tries using pkg-config - ''' - return conf.CHECK_BUNDLED_SYSTEM(libname, - minversion=minversion, - maxversion=maxversion, - version_blacklist=version_blacklist, - onlyif=onlyif, - implied_deps=implied_deps, - pkg=pkg) - -@conf -def CHECK_BUNDLED_SYSTEM(conf, libname, minversion='0.0.0', - maxversion=None, version_blacklist=[], - checkfunctions=None, headers=None, checkcode=None, - onlyif=None, implied_deps=None, - require_headers=True, pkg=None, set_target=True): - '''check if a library is available as a system library. - this first tries via pkg-config, then if that fails - tries by testing for a specified function in the specified lib - ''' - # We always do a logic validation of 'onlyif' first - missing = [] - if onlyif: - for l in samba_utils.TO_LIST(onlyif): - f = 'FOUND_SYSTEMLIB_%s' % l - if not f in conf.env: - Logs.error('ERROR: CHECK_BUNDLED_SYSTEM(%s) - ' % (libname) + - 'missing prerequisite check for ' + - 'system library %s, onlyif=%r' % (l, onlyif)) - sys.exit(1) - if not conf.env[f]: - missing.append(l) - found = 'FOUND_SYSTEMLIB_%s' % libname - if found in conf.env: - return conf.env[found] - if conf.LIB_MUST_BE_BUNDLED(libname): - conf.env[found] = False - return False - - # see if the library should only use a system version if another dependent - # system version is found. That prevents possible use of mixed library - # versions - if missing: - if not conf.LIB_MAY_BE_BUNDLED(libname): - Logs.error('ERROR: Use of system library %s depends on missing system library/libraries %r' % (libname, missing)) - sys.exit(1) - conf.env[found] = False - return False - - def check_functions_headers_code(): - '''helper function for CHECK_BUNDLED_SYSTEM''' - if require_headers and headers and not conf.CHECK_HEADERS(headers, lib=libname): - return False - if checkfunctions is not None: - ok = conf.CHECK_FUNCS_IN(checkfunctions, libname, headers=headers, - empty_decl=False, set_target=False) - if not ok: - return False - if checkcode is not None: - define='CHECK_BUNDLED_SYSTEM_%s' % libname.upper() - ok = conf.CHECK_CODE(checkcode, lib=libname, - headers=headers, local_include=False, - msg=msg, define=define) - conf.CONFIG_RESET(define) - if not ok: - return False - return True - - minversion = minimum_library_version(conf, libname, minversion) - - msg = 'Checking for system %s' % libname - msg_ver = [] - if minversion != '0.0.0': - msg_ver.append('>=%s' % minversion) - if maxversion is not None: - msg_ver.append('<=%s' % maxversion) - for v in version_blacklist: - msg_ver.append('!=%s' % v) - if msg_ver != []: - msg += " (%s)" % (" ".join(msg_ver)) - - uselib_store=libname.upper() - if pkg is None: - pkg = libname - - version_checks = '%s >= %s' % (pkg, minversion) - if maxversion is not None: - version_checks += ' %s <= %s' % (pkg, maxversion) - for v in version_blacklist: - version_checks += ' %s != %s' % (pkg, v) - - # try pkgconfig first - if (conf.CHECK_CFG(package=pkg, - args='"%s" --cflags --libs' % (version_checks), - msg=msg, uselib_store=uselib_store) and - check_functions_headers_code()): - if set_target: - conf.SET_TARGET_TYPE(libname, 'SYSLIB') - conf.env[found] = True - if implied_deps: - conf.SET_SYSLIB_DEPS(libname, implied_deps) - return True - if checkfunctions is not None: - if check_functions_headers_code(): - conf.env[found] = True - if implied_deps: - conf.SET_SYSLIB_DEPS(libname, implied_deps) - if set_target: - conf.SET_TARGET_TYPE(libname, 'SYSLIB') - return True - conf.env[found] = False - if not conf.LIB_MAY_BE_BUNDLED(libname): - Logs.error('ERROR: System library %s of version %s not found, and bundling disabled' % (libname, minversion)) - sys.exit(1) - return False - - -def tuplize_version(version): - return tuple([int(x) for x in version.split(".")]) - -@conf -def CHECK_BUNDLED_SYSTEM_PYTHON(conf, libname, modulename, minversion='0.0.0'): - '''check if a python module is available on the system and - has the specified minimum version. - ''' - if conf.LIB_MUST_BE_BUNDLED(libname): - return False - - # see if the library should only use a system version if another dependent - # system version is found. That prevents possible use of mixed library - # versions - minversion = minimum_library_version(conf, libname, minversion) - - try: - m = __import__(modulename) - except ImportError: - found = False - else: - try: - version = m.__version__ - except AttributeError: - found = False - else: - found = tuplize_version(version) >= tuplize_version(minversion) - if not found and not conf.LIB_MAY_BE_BUNDLED(libname): - Logs.error('ERROR: Python module %s of version %s not found, and bundling disabled' % (libname, minversion)) - sys.exit(1) - return found - - -def NONSHARED_BINARY(bld, name): - '''return True if a binary should be built without non-system shared libs''' - return target_in_list(name, bld.env.NONSHARED_BINARIES, False) -Build.BuildContext.NONSHARED_BINARY = NONSHARED_BINARY - - diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_conftests.py b/ldb-2.0.8/buildtools/wafsamba/samba_conftests.py deleted file mode 100644 index ef632ba..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/samba_conftests.py +++ /dev/null @@ -1,528 +0,0 @@ -# a set of config tests that use the samba_autoconf functions -# to test for commonly needed configuration options - -import os, shutil, re -from waflib import Build, Configure, Utils, Options, Logs, Errors -from waflib.Configure import conf -from samba_utils import TO_LIST, ADD_LD_LIBRARY_PATH, get_string - - -def add_option(self, *k, **kw): - '''syntax help: provide the "match" attribute to opt.add_option() so that folders can be added to specific config tests''' - Options.OptionsContext.parser = self - match = kw.get('match', []) - if match: - del kw['match'] - opt = self.parser.add_option(*k, **kw) - opt.match = match - return opt -Options.OptionsContext.add_option = add_option - -@conf -def check(self, *k, **kw): - '''Override the waf defaults to inject --with-directory options''' - - if not 'env' in kw: - kw['env'] = self.env.derive() - - # match the configuration test with specific options, for example: - # --with-libiconv -> Options.options.iconv_open -> "Checking for library iconv" - additional_dirs = [] - if 'msg' in kw: - msg = kw['msg'] - for x in Options.OptionsContext.parser.parser.option_list: - if getattr(x, 'match', None) and msg in x.match: - d = getattr(Options.options, x.dest, '') - if d: - additional_dirs.append(d) - - # we add the additional dirs twice: once for the test data, and again if the compilation test suceeds below - def add_options_dir(dirs, env): - for x in dirs: - if not x in env.CPPPATH: - env.CPPPATH = [os.path.join(x, 'include')] + env.CPPPATH - if not x in env.LIBPATH: - env.LIBPATH = [os.path.join(x, 'lib')] + env.LIBPATH - - add_options_dir(additional_dirs, kw['env']) - - self.validate_c(kw) - self.start_msg(kw['msg']) - ret = None - try: - ret = self.run_c_code(*k, **kw) - except Configure.ConfigurationError as e: - self.end_msg(kw['errmsg'], 'YELLOW') - if 'mandatory' in kw and kw['mandatory']: - if Logs.verbose > 1: - raise - else: - self.fatal('the configuration failed (see %r)' % self.log.name) - else: - kw['success'] = ret - self.end_msg(self.ret_msg(kw['okmsg'], kw)) - - # success! keep the CPPPATH/LIBPATH - add_options_dir(additional_dirs, self.env) - - self.post_check(*k, **kw) - if not kw.get('execute', False): - return ret == 0 - return ret - - -@conf -def CHECK_ICONV(conf, define='HAVE_NATIVE_ICONV'): - '''check if the iconv library is installed - optionally pass a define''' - if conf.CHECK_FUNCS_IN('iconv_open', 'iconv', checklibc=True, headers='iconv.h'): - conf.DEFINE(define, 1) - return True - return False - - -@conf -def CHECK_LARGEFILE(conf, define='HAVE_LARGEFILE'): - '''see what we need for largefile support''' - getconf_cflags = conf.CHECK_COMMAND(['getconf', 'LFS_CFLAGS']); - if getconf_cflags is not False: - if (conf.CHECK_CODE('if (sizeof(off_t) < 8) return 1', - define='WORKING_GETCONF_LFS_CFLAGS', - execute=True, - cflags=getconf_cflags, - msg='Checking getconf large file support flags work')): - conf.ADD_CFLAGS(getconf_cflags) - getconf_cflags_list=TO_LIST(getconf_cflags) - for flag in getconf_cflags_list: - if flag[:2] == "-D": - flag_split = flag[2:].split('=') - if len(flag_split) == 1: - conf.DEFINE(flag_split[0], '1') - else: - conf.DEFINE(flag_split[0], flag_split[1]) - - if conf.CHECK_CODE('if (sizeof(off_t) < 8) return 1', - define, - execute=True, - msg='Checking for large file support without additional flags'): - return True - - if conf.CHECK_CODE('if (sizeof(off_t) < 8) return 1', - define, - execute=True, - cflags='-D_FILE_OFFSET_BITS=64', - msg='Checking for -D_FILE_OFFSET_BITS=64'): - conf.DEFINE('_FILE_OFFSET_BITS', 64) - return True - - if conf.CHECK_CODE('if (sizeof(off_t) < 8) return 1', - define, - execute=True, - cflags='-D_LARGE_FILES', - msg='Checking for -D_LARGE_FILES'): - conf.DEFINE('_LARGE_FILES', 1) - return True - return False - - -@conf -def CHECK_C_PROTOTYPE(conf, function, prototype, define, headers=None, msg=None): - '''verify that a C prototype matches the one on the current system''' - if not conf.CHECK_DECLS(function, headers=headers): - return False - if not msg: - msg = 'Checking C prototype for %s' % function - return conf.CHECK_CODE('%s; void *_x = (void *)%s' % (prototype, function), - define=define, - local_include=False, - headers=headers, - link=False, - execute=False, - msg=msg) - - -@conf -def CHECK_CHARSET_EXISTS(conf, charset, outcharset='UCS-2LE', headers=None, define=None): - '''check that a named charset is able to be used with iconv_open() for conversion - to a target charset - ''' - msg = 'Checking if can we convert from %s to %s' % (charset, outcharset) - if define is None: - define = 'HAVE_CHARSET_%s' % charset.upper().replace('-','_') - return conf.CHECK_CODE(''' - iconv_t cd = iconv_open("%s", "%s"); - if (cd == 0 || cd == (iconv_t)-1) return -1; - ''' % (charset, outcharset), - define=define, - execute=True, - msg=msg, - lib='iconv', - headers=headers) - -def find_config_dir(conf): - '''find a directory to run tests in''' - k = 0 - while k < 10000: - dir = os.path.join(conf.bldnode.abspath(), '.conf_check_%d' % k) - try: - shutil.rmtree(dir) - except OSError: - pass - try: - os.stat(dir) - except: - break - k += 1 - - try: - os.makedirs(dir) - except: - conf.fatal('cannot create a configuration test folder %r' % dir) - - try: - os.stat(dir) - except: - conf.fatal('cannot use the configuration test folder %r' % dir) - return dir - -@conf -def CHECK_SHLIB_INTRASINC_NAME_FLAGS(conf, msg): - ''' - check if the waf default flags for setting the name of lib - are ok - ''' - - snip = ''' -int foo(int v) { - return v * 2; -} -''' - return conf.check(features='c cshlib',vnum="1",fragment=snip,msg=msg, mandatory=False) - -@conf -def CHECK_NEED_LC(conf, msg): - '''check if we need -lc''' - - dir = find_config_dir(conf) - - env = conf.env - - bdir = os.path.join(dir, 'testbuild2') - if not os.path.exists(bdir): - os.makedirs(bdir) - - - subdir = os.path.join(dir, "liblctest") - - os.makedirs(subdir) - - Utils.writef(os.path.join(subdir, 'liblc1.c'), '#include \nint lib_func(void) { FILE *f = fopen("foo", "r");}\n') - - bld = Build.BuildContext() - bld.log = conf.log - bld.all_envs.update(conf.all_envs) - bld.all_envs['default'] = env - bld.lst_variants = bld.all_envs.keys() - bld.load_dirs(dir, bdir) - - bld.rescan(bld.srcnode) - - bld(features='c cshlib', - source='liblctest/liblc1.c', - ldflags=conf.env['EXTRA_LDFLAGS'], - target='liblc', - name='liblc') - - try: - bld.compile() - conf.check_message(msg, '', True) - return True - except: - conf.check_message(msg, '', False) - return False - - -@conf -def CHECK_SHLIB_W_PYTHON(conf, msg): - '''check if we need -undefined dynamic_lookup''' - - dir = find_config_dir(conf) - snip = ''' -#include -#include -#define environ (*_NSGetEnviron()) - -static PyObject *ldb_module = NULL; -int foo(int v) { - extern char **environ; - environ[0] = 1; - ldb_module = PyImport_ImportModule("ldb"); - return v * 2; -} -''' - return conf.check(features='c cshlib',uselib='PYEMBED',fragment=snip,msg=msg, mandatory=False) - -# this one is quite complex, and should probably be broken up -# into several parts. I'd quite like to create a set of CHECK_COMPOUND() -# functions that make writing complex compound tests like this much easier -@conf -def CHECK_LIBRARY_SUPPORT(conf, rpath=False, version_script=False, msg=None): - '''see if the platform supports building libraries''' - - if msg is None: - if rpath: - msg = "rpath library support" - else: - msg = "building library support" - - dir = find_config_dir(conf) - - bdir = os.path.join(dir, 'testbuild') - if not os.path.exists(bdir): - os.makedirs(bdir) - - env = conf.env - - subdir = os.path.join(dir, "libdir") - - os.makedirs(subdir) - - Utils.writef(os.path.join(subdir, 'lib1.c'), 'int lib_func(void) { return 42; }\n') - Utils.writef(os.path.join(dir, 'main.c'), - 'int lib_func(void);\n' - 'int main(void) {return !(lib_func() == 42);}\n') - - bld = Build.BuildContext() - bld.log = conf.log - bld.all_envs.update(conf.all_envs) - bld.all_envs['default'] = env - bld.lst_variants = bld.all_envs.keys() - bld.load_dirs(dir, bdir) - - bld.rescan(bld.srcnode) - - ldflags = [] - if version_script: - ldflags.append("-Wl,--version-script=%s/vscript" % bld.path.abspath()) - Utils.writef(os.path.join(dir,'vscript'), 'TEST_1.0A2 { global: *; };\n') - - bld(features='c cshlib', - source='libdir/lib1.c', - target='libdir/lib1', - ldflags=ldflags, - name='lib1') - - o = bld(features='c cprogram', - source='main.c', - target='prog1', - uselib_local='lib1') - - if rpath: - o.rpath=os.path.join(bdir, 'default/libdir') - - # compile the program - try: - bld.compile() - except: - conf.check_message(msg, '', False) - return False - - # path for execution - lastprog = o.link_task.outputs[0].abspath(env) - - if not rpath: - if 'LD_LIBRARY_PATH' in os.environ: - old_ld_library_path = os.environ['LD_LIBRARY_PATH'] - else: - old_ld_library_path = None - ADD_LD_LIBRARY_PATH(os.path.join(bdir, 'default/libdir')) - - # we need to run the program, try to get its result - args = conf.SAMBA_CROSS_ARGS(msg=msg) - proc = Utils.subprocess.Popen([lastprog] + args, - stdout=Utils.subprocess.PIPE, stderr=Utils.subprocess.PIPE) - (out, err) = proc.communicate() - w = conf.log.write - w(str(out)) - w('\n') - w(str(err)) - w('\nreturncode %r\n' % proc.returncode) - ret = (proc.returncode == 0) - - if not rpath: - os.environ['LD_LIBRARY_PATH'] = old_ld_library_path or '' - - conf.check_message(msg, '', ret) - return ret - - - -@conf -def CHECK_PERL_MANPAGE(conf, msg=None, section=None): - '''work out what extension perl uses for manpages''' - - if msg is None: - if section: - msg = "perl man%s extension" % section - else: - msg = "perl manpage generation" - - conf.start_msg(msg) - - dir = find_config_dir(conf) - - bdir = os.path.join(dir, 'testbuild') - if not os.path.exists(bdir): - os.makedirs(bdir) - - Utils.writef(os.path.join(bdir, 'Makefile.PL'), """ -use ExtUtils::MakeMaker; -WriteMakefile( - 'NAME' => 'WafTest', - 'EXE_FILES' => [ 'WafTest' ] -); -""") - back = os.path.abspath('.') - os.chdir(bdir) - proc = Utils.subprocess.Popen(['perl', 'Makefile.PL'], - stdout=Utils.subprocess.PIPE, - stderr=Utils.subprocess.PIPE) - (out, err) = proc.communicate() - os.chdir(back) - - ret = (proc.returncode == 0) - if not ret: - conf.end_msg('not found', color='YELLOW') - return - - if section: - man = Utils.readf(os.path.join(bdir,'Makefile')) - m = re.search('MAN%sEXT\s+=\s+(\w+)' % section, man) - if not m: - conf.end_msg('not found', color='YELLOW') - return - ext = m.group(1) - conf.end_msg(ext) - return ext - - conf.end_msg('ok') - return True - - -@conf -def CHECK_COMMAND(conf, cmd, msg=None, define=None, on_target=True, boolean=False): - '''run a command and return result''' - if msg is None: - msg = 'Checking %s' % ' '.join(cmd) - conf.COMPOUND_START(msg) - cmd = cmd[:] - if on_target: - cmd.extend(conf.SAMBA_CROSS_ARGS(msg=msg)) - try: - ret = get_string(Utils.cmd_output(cmd)) - except: - conf.COMPOUND_END(False) - return False - if boolean: - conf.COMPOUND_END('ok') - if define: - conf.DEFINE(define, '1') - else: - ret = ret.strip() - conf.COMPOUND_END(ret) - if define: - conf.DEFINE(define, ret, quote=True) - return ret - - -@conf -def CHECK_UNAME(conf): - '''setup SYSTEM_UNAME_* defines''' - ret = True - for v in "sysname machine release version".split(): - if not conf.CHECK_CODE(''' - int printf(const char *format, ...); - struct utsname n; - if (uname(&n) == -1) return -1; - printf("%%s", n.%s); - ''' % v, - define='SYSTEM_UNAME_%s' % v.upper(), - execute=True, - define_ret=True, - quote=True, - headers='sys/utsname.h', - local_include=False, - msg="Checking uname %s type" % v): - ret = False - return ret - -@conf -def CHECK_INLINE(conf): - '''check for the right value for inline''' - conf.COMPOUND_START('Checking for inline') - for i in ['inline', '__inline__', '__inline']: - ret = conf.CHECK_CODE(''' - typedef int foo_t; - static %s foo_t static_foo () {return 0; } - %s foo_t foo () {return 0; }\n''' % (i, i), - define='INLINE_MACRO', - addmain=False, - link=False) - if ret: - if i != 'inline': - conf.DEFINE('inline', i, quote=False) - break - if not ret: - conf.COMPOUND_END(ret) - else: - conf.COMPOUND_END(i) - return ret - -@conf -def CHECK_XSLTPROC_MANPAGES(conf): - '''check if xsltproc can run with the given stylesheets''' - - - if not conf.CONFIG_SET('XSLTPROC'): - conf.find_program('xsltproc', var='XSLTPROC') - if not conf.CONFIG_SET('XSLTPROC'): - return False - - s='http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl' - conf.CHECK_COMMAND('%s --nonet %s 2> /dev/null' % (conf.env.get_flat('XSLTPROC'), s), - msg='Checking for stylesheet %s' % s, - define='XSLTPROC_MANPAGES', on_target=False, - boolean=True) - if not conf.CONFIG_SET('XSLTPROC_MANPAGES'): - print("A local copy of the docbook.xsl wasn't found on your system" \ - " consider installing package like docbook-xsl") - -# -# Determine the standard libpath for the used compiler, -# so we can later use that to filter out these standard -# library paths when some tools like cups-config or -# python-config report standard lib paths with their -# ldflags (-L...) -# -@conf -def CHECK_STANDARD_LIBPATH(conf): - # at least gcc and clang support this: - try: - cmd = conf.env.CC + ['-print-search-dirs'] - out = get_string(Utils.cmd_output(cmd)).split('\n') - except ValueError: - # option not supported by compiler - use a standard list of directories - dirlist = [ '/usr/lib', '/usr/lib64' ] - except: - raise Errors.WafError('Unexpected error running "%s"' % (cmd)) - else: - dirlist = [] - for line in out: - line = line.strip() - if line.startswith("libraries: ="): - dirliststr = line[len("libraries: ="):] - dirlist = [ os.path.normpath(x) for x in dirliststr.split(':') ] - break - - conf.env.STANDARD_LIBPATH = dirlist - diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_cross.py b/ldb-2.0.8/buildtools/wafsamba/samba_cross.py deleted file mode 100644 index 0868a85..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/samba_cross.py +++ /dev/null @@ -1,175 +0,0 @@ -# functions for handling cross-compilation - -import os, sys, re, shlex -from waflib import Utils, Logs, Options, Errors, Context -from waflib.Configure import conf -from wafsamba import samba_utils - -real_Popen = None - -ANSWER_UNKNOWN = (254, "") -ANSWER_NO = (1, "") -ANSWER_OK = (0, "") - -cross_answers_incomplete = False - - -def add_answer(ca_file, msg, answer): - '''add an answer to a set of cross answers''' - try: - f = open(ca_file, 'a') - except: - Logs.error("Unable to open cross-answers file %s" % ca_file) - sys.exit(1) - (retcode, retstring) = answer - # if retstring is more than one line then we probably - # don't care about its actual content (the tests should - # yield one-line output in order to comply with the cross-answer - # format) - retstring = retstring.strip() - if len(retstring.split('\n')) > 1: - retstring = '' - answer = (retcode, retstring) - - if answer == ANSWER_OK: - f.write('%s: OK\n' % msg) - elif answer == ANSWER_UNKNOWN: - f.write('%s: UNKNOWN\n' % msg) - elif answer == ANSWER_NO: - f.write('%s: NO\n' % msg) - else: - if retcode == 0: - f.write('%s: "%s"\n' % (msg, retstring)) - else: - f.write('%s: (%d, "%s")\n' % (msg, retcode, retstring)) - f.close() - - -def cross_answer(ca_file, msg): - '''return a (retcode,retstring) tuple from a answers file''' - try: - f = open(ca_file, 'r') - except: - return ANSWER_UNKNOWN - for line in f: - line = line.strip() - if line == '' or line[0] == '#': - continue - if line.find(':') != -1: - a = line.split(':', 1) - thismsg = a[0].strip() - if thismsg != msg: - continue - ans = a[1].strip() - if ans == "OK" or ans == "YES": - f.close() - return ANSWER_OK - elif ans == "UNKNOWN": - f.close() - return ANSWER_UNKNOWN - elif ans == "FAIL" or ans == "NO": - f.close() - return ANSWER_NO - elif ans[0] == '"': - f.close() - return (0, ans.strip('"')) - elif ans[0] == "'": - f.close() - return (0, ans.strip("'")) - else: - m = re.match('\(\s*(-?\d+)\s*,\s*\"(.*)\"\s*\)', ans) - if m: - f.close() - return (int(m.group(1)), m.group(2)) - else: - raise Errors.WafError("Bad answer format '%s' in %s" % (line, ca_file)) - f.close() - return ANSWER_UNKNOWN - - -class cross_Popen(Utils.subprocess.Popen): - '''cross-compilation wrapper for Popen''' - def __init__(*k, **kw): - (obj, args) = k - use_answers = False - ans = ANSWER_UNKNOWN - - # Three possibilities: - # 1. Only cross-answers - try the cross-answers file, and if - # there's no corresponding answer, add to the file and mark - # the configure process as unfinished. - # 2. Only cross-execute - get the answer from cross-execute - # 3. Both - try the cross-answers file, and if there is no - # corresponding answer - use cross-execute to get an answer, - # and add that answer to the file. - if '--cross-answers' in args: - # when --cross-answers is set, then change the arguments - # to use the cross answers if available - use_answers = True - i = args.index('--cross-answers') - ca_file = args[i+1] - msg = args[i+2] - ans = cross_answer(ca_file, msg) - - if '--cross-execute' in args and ans == ANSWER_UNKNOWN: - # when --cross-execute is set, then change the arguments - # to use the cross emulator - i = args.index('--cross-execute') - newargs = shlex.split(args[i+1]) - newargs.extend(args[0:i]) - if use_answers: - p = real_Popen(newargs, - stdout=Utils.subprocess.PIPE, - stderr=Utils.subprocess.PIPE, - env=kw.get('env', {})) - ce_out, ce_err = p.communicate() - ans = (p.returncode, samba_utils.get_string(ce_out)) - add_answer(ca_file, msg, ans) - else: - args = newargs - - if use_answers: - if ans == ANSWER_UNKNOWN: - global cross_answers_incomplete - cross_answers_incomplete = True - add_answer(ca_file, msg, ans) - (retcode, retstring) = ans - args = ['/bin/sh', '-c', "echo -n '%s'; exit %d" % (retstring, retcode)] - real_Popen.__init__(*(obj, args), **kw) - - -@conf -def SAMBA_CROSS_ARGS(conf, msg=None): - '''get test_args to pass when running cross compiled binaries''' - if not conf.env.CROSS_COMPILE: - return [] - - global real_Popen - if real_Popen is None: - real_Popen = Utils.subprocess.Popen - Utils.subprocess.Popen = cross_Popen - Utils.run_process = Utils.run_regular_process - Utils.get_process = Utils.alloc_process_pool = Utils.nada - - ret = [] - - if conf.env.CROSS_EXECUTE: - ret.extend(['--cross-execute', conf.env.CROSS_EXECUTE]) - - if conf.env.CROSS_ANSWERS: - if msg is None: - raise Errors.WafError("Cannot have NULL msg in cross-answers") - ret.extend(['--cross-answers', os.path.join(Context.launch_dir, conf.env.CROSS_ANSWERS), msg]) - - if ret == []: - raise Errors.WafError("Cannot cross-compile without either --cross-execute or --cross-answers") - - return ret - -@conf -def SAMBA_CROSS_CHECK_COMPLETE(conf): - '''check if we have some unanswered questions''' - global cross_answers_incomplete - if conf.env.CROSS_COMPILE and cross_answers_incomplete: - raise Errors.WafError("Cross answers file %s is incomplete" % conf.env.CROSS_ANSWERS) - return True diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_deps.py b/ldb-2.0.8/buildtools/wafsamba/samba_deps.py deleted file mode 100644 index 03c3707..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/samba_deps.py +++ /dev/null @@ -1,1181 +0,0 @@ -# Samba automatic dependency handling and project rules - -import os, sys, re - -from waflib import Build, Options, Logs, Utils, Errors -from waflib.Logs import debug -from waflib.Configure import conf -from waflib import ConfigSet - -from samba_bundled import BUILTIN_LIBRARY -from samba_utils import LOCAL_CACHE, TO_LIST, get_tgt_list, unique_list, os_path_relpath -from samba_autoconf import library_flags - -@conf -def ADD_GLOBAL_DEPENDENCY(ctx, dep): - '''add a dependency for all binaries and libraries''' - if not 'GLOBAL_DEPENDENCIES' in ctx.env: - ctx.env.GLOBAL_DEPENDENCIES = [] - ctx.env.GLOBAL_DEPENDENCIES.append(dep) - - -@conf -def BREAK_CIRCULAR_LIBRARY_DEPENDENCIES(ctx): - '''indicate that circular dependencies between libraries should be broken.''' - ctx.env.ALLOW_CIRCULAR_LIB_DEPENDENCIES = True - - -@conf -def SET_SYSLIB_DEPS(conf, target, deps): - '''setup some implied dependencies for a SYSLIB''' - cache = LOCAL_CACHE(conf, 'SYSLIB_DEPS') - cache[target] = deps - - -def expand_subsystem_deps(bld): - '''expand the reverse dependencies resulting from subsystem - attributes of modules. This is walking over the complete list - of declared subsystems, and expands the samba_deps_extended list for any - module<->subsystem dependencies''' - - subsystem_list = LOCAL_CACHE(bld, 'INIT_FUNCTIONS') - targets = LOCAL_CACHE(bld, 'TARGET_TYPE') - - for subsystem_name in subsystem_list: - bld.ASSERT(subsystem_name in targets, "Subsystem target %s not declared" % subsystem_name) - type = targets[subsystem_name] - if type == 'DISABLED' or type == 'EMPTY': - continue - - # for example, - # subsystem_name = dcerpc_server (a subsystem) - # subsystem = dcerpc_server (a subsystem object) - # module_name = rpc_epmapper (a module within the dcerpc_server subsystem) - # module = rpc_epmapper (a module object within the dcerpc_server subsystem) - - subsystem = bld.get_tgen_by_name(subsystem_name) - bld.ASSERT(subsystem is not None, "Unable to find subsystem %s" % subsystem_name) - for d in subsystem_list[subsystem_name]: - module_name = d['TARGET'] - module_type = targets[module_name] - if module_type in ['DISABLED', 'EMPTY']: - continue - bld.ASSERT(subsystem is not None, - "Subsystem target %s for %s (%s) not found" % (subsystem_name, module_name, module_type)) - if module_type in ['SUBSYSTEM']: - # if a module is a plain object type (not a library) then the - # subsystem it is part of needs to have it as a dependency, so targets - # that depend on this subsystem get the modules of that subsystem - subsystem.samba_deps_extended.append(module_name) - subsystem.samba_deps_extended = unique_list(subsystem.samba_deps_extended) - - - -def build_dependencies(self): - '''This builds the dependency list for a target. It runs after all the targets are declared - - The reason this is not just done in the SAMBA_*() rules is that we have no way of knowing - the full dependency list for a target until we have all of the targets declared. - ''' - - if self.samba_type in ['LIBRARY', 'BINARY', 'PYTHON']: - self.uselib = list(self.final_syslibs) - self.uselib_local = list(self.final_libs) - self.add_objects = list(self.final_objects) - - # extra link flags from pkg_config - libs = self.final_syslibs.copy() - - (cflags, ldflags, cpppath) = library_flags(self, list(libs)) - new_ldflags = getattr(self, 'samba_ldflags', [])[:] - new_ldflags.extend(ldflags) - self.ldflags = new_ldflags - - if getattr(self, 'allow_undefined_symbols', False) and self.env.undefined_ldflags: - for f in self.env.undefined_ldflags: - self.ldflags.remove(f) - - if getattr(self, 'allow_undefined_symbols', False) and self.env.undefined_ignore_ldflags: - for f in self.env.undefined_ignore_ldflags: - self.ldflags.append(f) - - debug('deps: computed dependencies for target %s: uselib=%s uselib_local=%s add_objects=%s', - self.sname, self.uselib, self.uselib_local, self.add_objects) - - if self.samba_type in ['SUBSYSTEM']: - # this is needed for the cflags of libs that come from pkg_config - self.uselib = list(self.final_syslibs) - self.uselib.extend(list(self.direct_syslibs)) - for lib in self.final_libs: - t = self.bld.get_tgen_by_name(lib) - self.uselib.extend(list(t.final_syslibs)) - self.uselib = unique_list(self.uselib) - - if getattr(self, 'uselib', None): - up_list = [] - for l in self.uselib: - up_list.append(l.upper()) - self.uselib = up_list - - -def build_includes(self): - '''This builds the right set of includes for a target. - - One tricky part of this is that the includes= attribute for a - target needs to use paths which are relative to that targets - declaration directory (which we can get at via t.path). - - The way this works is the includes list gets added as - samba_includes in the main build task declaration. Then this - function runs after all of the tasks are declared, and it - processes the samba_includes attribute to produce a includes= - attribute - ''' - - if getattr(self, 'samba_includes', None) is None: - return - - bld = self.bld - - inc_deps = includes_objects(bld, self, set(), {}) - - includes = [] - - # maybe add local includes - if getattr(self, 'local_include', True) and getattr(self, 'local_include_first', True): - includes.append('.') - - includes.extend(self.samba_includes_extended) - - if 'EXTRA_INCLUDES' in bld.env and getattr(self, 'global_include', True): - includes.extend(bld.env['EXTRA_INCLUDES']) - - includes.append('#') - - inc_set = set() - inc_abs = [] - - for d in inc_deps: - t = bld.get_tgen_by_name(d) - bld.ASSERT(t is not None, "Unable to find dependency %s for %s" % (d, self.sname)) - inclist = getattr(t, 'samba_includes_extended', [])[:] - if getattr(t, 'local_include', True): - inclist.append('.') - if inclist == []: - continue - tpath = t.samba_abspath - for inc in inclist: - npath = tpath + '/' + inc - if not npath in inc_set: - inc_abs.append(npath) - inc_set.add(npath) - - mypath = self.path.abspath(bld.env) - for inc in inc_abs: - relpath = os_path_relpath(inc, mypath) - includes.append(relpath) - - if getattr(self, 'local_include', True) and not getattr(self, 'local_include_first', True): - includes.append('.') - - # now transform the includes list to be relative to the top directory - # which is represented by '#' in waf. This allows waf to cache the - # includes lists more efficiently - includes_top = [] - for i in includes: - if i[0] == '#': - # some are already top based - includes_top.append(i) - continue - absinc = os.path.join(self.path.abspath(), i) - relinc = os_path_relpath(absinc, self.bld.srcnode.abspath()) - includes_top.append('#' + relinc) - - self.includes = unique_list(includes_top) - debug('deps: includes for target %s: includes=%s', - self.sname, self.includes) - - -def add_init_functions(self): - '''This builds the right set of init functions''' - - bld = self.bld - - subsystems = LOCAL_CACHE(bld, 'INIT_FUNCTIONS') - - # cope with the separated object lists from BINARY and LIBRARY targets - sname = self.sname - if sname.endswith('.objlist'): - sname = sname[0:-8] - - modules = [] - if sname in subsystems: - modules.append(sname) - - m = getattr(self, 'samba_modules', None) - if m is not None: - modules.extend(TO_LIST(m)) - - m = getattr(self, 'samba_subsystem', None) - if m is not None: - modules.append(m) - - if 'pyembed' in self.features: - return - - sentinel = getattr(self, 'init_function_sentinel', 'NULL') - - targets = LOCAL_CACHE(bld, 'TARGET_TYPE') - cflags = getattr(self, 'samba_cflags', [])[:] - - if modules == []: - sname = sname.replace('-','_') - sname = sname.replace('.','_') - sname = sname.replace('/','_') - cflags.append('-DSTATIC_%s_MODULES=%s' % (sname, sentinel)) - if sentinel == 'NULL': - proto = "extern void __%s_dummy_module_proto(void)" % (sname) - cflags.append('-DSTATIC_%s_MODULES_PROTO=%s' % (sname, proto)) - self.cflags = cflags - return - - for m in modules: - bld.ASSERT(m in subsystems, - "No init_function defined for module '%s' in target '%s'" % (m, self.sname)) - init_fn_list = [] - for d in subsystems[m]: - if targets[d['TARGET']] != 'DISABLED': - init_fn_list.append(d['INIT_FUNCTION']) - if init_fn_list == []: - cflags.append('-DSTATIC_%s_MODULES=%s' % (m, sentinel)) - if sentinel == 'NULL': - proto = "extern void __%s_dummy_module_proto(void)" % (m) - cflags.append('-DSTATIC_%s_MODULES_PROTO=%s' % (m, proto)) - else: - cflags.append('-DSTATIC_%s_MODULES=%s' % (m, ','.join(init_fn_list) + ',' + sentinel)) - proto='' - for f in init_fn_list: - proto += '_MODULE_PROTO(%s)' % f - proto += "extern void __%s_dummy_module_proto(void)" % (m) - cflags.append('-DSTATIC_%s_MODULES_PROTO=%s' % (m, proto)) - self.cflags = cflags - - -def check_duplicate_sources(bld, tgt_list): - '''see if we are compiling the same source file more than once''' - - debug('deps: checking for duplicate sources') - targets = LOCAL_CACHE(bld, 'TARGET_TYPE') - - for t in tgt_list: - source_list = TO_LIST(getattr(t, 'source', '')) - tpath = os.path.normpath(os_path_relpath(t.path.abspath(bld.env), t.env.BUILD_DIRECTORY + '/default')) - obj_sources = set() - for s in source_list: - if not isinstance(s, str): - print('strange path in check_duplicate_sources %r' % s) - s = s.abspath() - p = os.path.normpath(os.path.join(tpath, s)) - if p in obj_sources: - Logs.error("ERROR: source %s appears twice in target '%s'" % (p, t.sname)) - sys.exit(1) - obj_sources.add(p) - t.samba_source_set = obj_sources - - subsystems = {} - - # build a list of targets that each source file is part of - for t in tgt_list: - if not targets[t.sname] in [ 'LIBRARY', 'BINARY', 'PYTHON' ]: - continue - for obj in t.add_objects: - t2 = t.bld.get_tgen_by_name(obj) - source_set = getattr(t2, 'samba_source_set', set()) - for s in source_set: - if not s in subsystems: - subsystems[s] = {} - if not t.sname in subsystems[s]: - subsystems[s][t.sname] = [] - subsystems[s][t.sname].append(t2.sname) - - for s in subsystems: - if len(subsystems[s]) > 1 and Options.options.SHOW_DUPLICATES: - Logs.warn("WARNING: source %s is in more than one target: %s" % (s, subsystems[s].keys())) - for tname in subsystems[s]: - if len(subsystems[s][tname]) > 1: - raise Errors.WafError("ERROR: source %s is in more than one subsystem of target '%s': %s" % (s, tname, subsystems[s][tname])) - - return True - -def check_group_ordering(bld, tgt_list): - '''see if we have any dependencies that violate the group ordering - - It is an error for a target to depend on a target from a later - build group - ''' - - def group_name(g): - tm = bld.task_manager - return [x for x in tm.groups_names if id(tm.groups_names[x]) == id(g)][0] - - for g in bld.task_manager.groups: - gname = group_name(g) - for t in g.tasks_gen: - t.samba_group = gname - - grp_map = {} - idx = 0 - for g in bld.task_manager.groups: - name = group_name(g) - grp_map[name] = idx - idx += 1 - - targets = LOCAL_CACHE(bld, 'TARGET_TYPE') - - ret = True - for t in tgt_list: - tdeps = getattr(t, 'add_objects', []) + getattr(t, 'uselib_local', []) - for d in tdeps: - t2 = bld.get_tgen_by_name(d) - if t2 is None: - continue - map1 = grp_map[t.samba_group] - map2 = grp_map[t2.samba_group] - - if map2 > map1: - Logs.error("Target %r in build group %r depends on target %r from later build group %r" % ( - t.sname, t.samba_group, t2.sname, t2.samba_group)) - ret = False - - return ret -Build.BuildContext.check_group_ordering = check_group_ordering - -def show_final_deps(bld, tgt_list): - '''show the final dependencies for all targets''' - - targets = LOCAL_CACHE(bld, 'TARGET_TYPE') - - for t in tgt_list: - if not targets[t.sname] in ['LIBRARY', 'BINARY', 'PYTHON', 'SUBSYSTEM']: - continue - debug('deps: final dependencies for target %s: uselib=%s uselib_local=%s add_objects=%s', - t.sname, t.uselib, getattr(t, 'uselib_local', []), getattr(t, 'add_objects', [])) - - -def add_samba_attributes(bld, tgt_list): - '''ensure a target has a the required samba attributes''' - - targets = LOCAL_CACHE(bld, 'TARGET_TYPE') - - for t in tgt_list: - if t.name != '': - t.sname = t.name - else: - t.sname = t.target - t.samba_type = targets[t.sname] - t.samba_abspath = t.path.abspath(bld.env) - t.samba_deps_extended = t.samba_deps[:] - t.samba_includes_extended = TO_LIST(t.samba_includes)[:] - t.cflags = getattr(t, 'samba_cflags', '') - -def replace_grouping_libraries(bld, tgt_list): - '''replace dependencies based on grouping libraries - - If a library is marked as a grouping library, then any target that - depends on a subsystem that is part of that grouping library gets - that dependency replaced with a dependency on the grouping library - ''' - - targets = LOCAL_CACHE(bld, 'TARGET_TYPE') - - grouping = {} - - # find our list of grouping libraries, mapped from the subsystems they depend on - for t in tgt_list: - if not getattr(t, 'grouping_library', False): - continue - for dep in t.samba_deps_extended: - bld.ASSERT(dep in targets, "grouping library target %s not declared in %s" % (dep, t.sname)) - if targets[dep] == 'SUBSYSTEM': - grouping[dep] = t.sname - - # now replace any dependencies on elements of grouping libraries - for t in tgt_list: - for i in range(len(t.samba_deps_extended)): - dep = t.samba_deps_extended[i] - if dep in grouping: - if t.sname != grouping[dep]: - debug("deps: target %s: replacing dependency %s with grouping library %s" % (t.sname, dep, grouping[dep])) - t.samba_deps_extended[i] = grouping[dep] - - - -def build_direct_deps(bld, tgt_list): - '''build the direct_objects and direct_libs sets for each target''' - - targets = LOCAL_CACHE(bld, 'TARGET_TYPE') - syslib_deps = LOCAL_CACHE(bld, 'SYSLIB_DEPS') - - global_deps = bld.env.GLOBAL_DEPENDENCIES - global_deps_exclude = set() - for dep in global_deps: - t = bld.get_tgen_by_name(dep) - for d in t.samba_deps: - # prevent loops from the global dependencies list - global_deps_exclude.add(d) - global_deps_exclude.add(d + '.objlist') - - for t in tgt_list: - t.direct_objects = set() - t.direct_libs = set() - t.direct_syslibs = set() - deps = t.samba_deps_extended[:] - if getattr(t, 'samba_use_global_deps', False) and not t.sname in global_deps_exclude: - deps.extend(global_deps) - for d in deps: - if d == t.sname: continue - if not d in targets: - Logs.error("Unknown dependency '%s' in '%s'" % (d, t.sname)) - sys.exit(1) - if targets[d] in [ 'EMPTY', 'DISABLED' ]: - continue - if targets[d] == 'PYTHON' and targets[t.sname] != 'PYTHON' and t.sname.find('.objlist') == -1: - # this check should be more restrictive, but for now we have pidl-generated python - # code that directly depends on other python modules - Logs.error('ERROR: Target %s has dependency on python module %s' % (t.sname, d)) - sys.exit(1) - if targets[d] == 'SYSLIB': - t.direct_syslibs.add(d) - if d in syslib_deps: - for implied in TO_LIST(syslib_deps[d]): - if BUILTIN_LIBRARY(bld, implied): - t.direct_objects.add(implied) - elif targets[implied] == 'SYSLIB': - t.direct_syslibs.add(implied) - elif targets[implied] in ['LIBRARY', 'MODULE']: - t.direct_libs.add(implied) - else: - Logs.error('Implied dependency %s in %s is of type %s' % ( - implied, t.sname, targets[implied])) - sys.exit(1) - continue - t2 = bld.get_tgen_by_name(d) - if t2 is None: - Logs.error("no task %s of type %s in %s" % (d, targets[d], t.sname)) - sys.exit(1) - if t2.samba_type in [ 'LIBRARY', 'MODULE' ]: - t.direct_libs.add(d) - elif t2.samba_type in [ 'SUBSYSTEM', 'ASN1', 'PYTHON' ]: - t.direct_objects.add(d) - debug('deps: built direct dependencies') - - -def dependency_loop(loops, t, target): - '''add a dependency loop to the loops dictionary''' - if t.sname == target: - return - if not target in loops: - loops[target] = set() - if not t.sname in loops[target]: - loops[target].add(t.sname) - - -def indirect_libs(bld, t, chain, loops): - '''recursively calculate the indirect library dependencies for a target - - An indirect library is a library that results from a dependency on - a subsystem - ''' - - ret = getattr(t, 'indirect_libs', None) - if ret is not None: - return ret - - ret = set() - for obj in t.direct_objects: - if obj in chain: - dependency_loop(loops, t, obj) - continue - chain.add(obj) - t2 = bld.get_tgen_by_name(obj) - r2 = indirect_libs(bld, t2, chain, loops) - chain.remove(obj) - ret = ret.union(t2.direct_libs) - ret = ret.union(r2) - - for obj in indirect_objects(bld, t, set(), loops): - if obj in chain: - dependency_loop(loops, t, obj) - continue - chain.add(obj) - t2 = bld.get_tgen_by_name(obj) - r2 = indirect_libs(bld, t2, chain, loops) - chain.remove(obj) - ret = ret.union(t2.direct_libs) - ret = ret.union(r2) - - t.indirect_libs = ret - - return ret - - -def indirect_objects(bld, t, chain, loops): - '''recursively calculate the indirect object dependencies for a target - - indirect objects are the set of objects from expanding the - subsystem dependencies - ''' - - ret = getattr(t, 'indirect_objects', None) - if ret is not None: return ret - - ret = set() - for lib in t.direct_objects: - if lib in chain: - dependency_loop(loops, t, lib) - continue - chain.add(lib) - t2 = bld.get_tgen_by_name(lib) - r2 = indirect_objects(bld, t2, chain, loops) - chain.remove(lib) - ret = ret.union(t2.direct_objects) - ret = ret.union(r2) - - t.indirect_objects = ret - return ret - - -def extended_objects(bld, t, chain): - '''recursively calculate the extended object dependencies for a target - - extended objects are the union of: - - direct objects - - indirect objects - - direct and indirect objects of all direct and indirect libraries - ''' - - ret = getattr(t, 'extended_objects', None) - if ret is not None: return ret - - ret = set() - ret = ret.union(t.final_objects) - - for lib in t.final_libs: - if lib in chain: - continue - t2 = bld.get_tgen_by_name(lib) - chain.add(lib) - r2 = extended_objects(bld, t2, chain) - chain.remove(lib) - ret = ret.union(t2.final_objects) - ret = ret.union(r2) - - t.extended_objects = ret - return ret - - -def includes_objects(bld, t, chain, inc_loops): - '''recursively calculate the includes object dependencies for a target - - includes dependencies come from either library or object dependencies - ''' - ret = getattr(t, 'includes_objects', None) - if ret is not None: - return ret - - ret = t.direct_objects.copy() - ret = ret.union(t.direct_libs) - - for obj in t.direct_objects: - if obj in chain: - dependency_loop(inc_loops, t, obj) - continue - chain.add(obj) - t2 = bld.get_tgen_by_name(obj) - r2 = includes_objects(bld, t2, chain, inc_loops) - chain.remove(obj) - ret = ret.union(t2.direct_objects) - ret = ret.union(r2) - - for lib in t.direct_libs: - if lib in chain: - dependency_loop(inc_loops, t, lib) - continue - chain.add(lib) - t2 = bld.get_tgen_by_name(lib) - if t2 is None: - targets = LOCAL_CACHE(bld, 'TARGET_TYPE') - Logs.error('Target %s of type %s not found in direct_libs for %s' % ( - lib, targets[lib], t.sname)) - sys.exit(1) - r2 = includes_objects(bld, t2, chain, inc_loops) - chain.remove(lib) - ret = ret.union(t2.direct_objects) - ret = ret.union(r2) - - t.includes_objects = ret - return ret - - -def break_dependency_loops(bld, tgt_list): - '''find and break dependency loops''' - loops = {} - inc_loops = {} - - # build up the list of loops - for t in tgt_list: - indirect_objects(bld, t, set(), loops) - indirect_libs(bld, t, set(), loops) - includes_objects(bld, t, set(), inc_loops) - - # break the loops - for t in tgt_list: - if t.sname in loops: - for attr in ['direct_objects', 'indirect_objects', 'direct_libs', 'indirect_libs']: - objs = getattr(t, attr, set()) - setattr(t, attr, objs.difference(loops[t.sname])) - - for loop in loops: - debug('deps: Found dependency loops for target %s : %s', loop, loops[loop]) - - for loop in inc_loops: - debug('deps: Found include loops for target %s : %s', loop, inc_loops[loop]) - - # expand the loops mapping by one level - for loop in loops.copy(): - for tgt in loops[loop]: - if tgt in loops: - loops[loop] = loops[loop].union(loops[tgt]) - - for loop in inc_loops.copy(): - for tgt in inc_loops[loop]: - if tgt in inc_loops: - inc_loops[loop] = inc_loops[loop].union(inc_loops[tgt]) - - - # expand indirect subsystem and library loops - for loop in loops.copy(): - t = bld.get_tgen_by_name(loop) - if t.samba_type in ['SUBSYSTEM']: - loops[loop] = loops[loop].union(t.indirect_objects) - loops[loop] = loops[loop].union(t.direct_objects) - if t.samba_type in ['LIBRARY','PYTHON']: - loops[loop] = loops[loop].union(t.indirect_libs) - loops[loop] = loops[loop].union(t.direct_libs) - if loop in loops[loop]: - loops[loop].remove(loop) - - # expand indirect includes loops - for loop in inc_loops.copy(): - t = bld.get_tgen_by_name(loop) - inc_loops[loop] = inc_loops[loop].union(t.includes_objects) - if loop in inc_loops[loop]: - inc_loops[loop].remove(loop) - - # add in the replacement dependencies - for t in tgt_list: - for loop in loops: - for attr in ['indirect_objects', 'indirect_libs']: - objs = getattr(t, attr, set()) - if loop in objs: - diff = loops[loop].difference(objs) - if t.sname in diff: - diff.remove(t.sname) - if diff: - debug('deps: Expanded target %s of type %s from loop %s by %s', t.sname, t.samba_type, loop, diff) - objs = objs.union(diff) - setattr(t, attr, objs) - - for loop in inc_loops: - objs = getattr(t, 'includes_objects', set()) - if loop in objs: - diff = inc_loops[loop].difference(objs) - if t.sname in diff: - diff.remove(t.sname) - if diff: - debug('deps: Expanded target %s includes of type %s from loop %s by %s', t.sname, t.samba_type, loop, diff) - objs = objs.union(diff) - setattr(t, 'includes_objects', objs) - - -def reduce_objects(bld, tgt_list): - '''reduce objects by looking for indirect object dependencies''' - rely_on = {} - - for t in tgt_list: - t.extended_objects = None - - changed = False - - for type in ['BINARY', 'PYTHON', 'LIBRARY']: - for t in tgt_list: - if t.samba_type != type: continue - # if we will indirectly link to a target then we don't need it - new = t.final_objects.copy() - for l in t.final_libs: - t2 = bld.get_tgen_by_name(l) - t2_obj = extended_objects(bld, t2, set()) - dup = new.intersection(t2_obj) - if t.sname in rely_on: - dup = dup.difference(rely_on[t.sname]) - if dup: - # Do not remove duplicates of BUILTINS - d = next(iter(dup)) - if BUILTIN_LIBRARY(bld, d): - continue - - debug('deps: removing dups from %s of type %s: %s also in %s %s', - t.sname, t.samba_type, dup, t2.samba_type, l) - new = new.difference(dup) - changed = True - if not l in rely_on: - rely_on[l] = set() - rely_on[l] = rely_on[l].union(dup) - t.final_objects = new - - if not changed: - return False - - # add back in any objects that were relied upon by the reduction rules - for r in rely_on: - t = bld.get_tgen_by_name(r) - t.final_objects = t.final_objects.union(rely_on[r]) - - return True - - -def show_library_loop(bld, lib1, lib2, path, seen): - '''show the detailed path of a library loop between lib1 and lib2''' - - t = bld.get_tgen_by_name(lib1) - if not lib2 in getattr(t, 'final_libs', set()): - return - - for d in t.samba_deps_extended: - if d in seen: - continue - seen.add(d) - path2 = path + '=>' + d - if d == lib2: - Logs.warn('library loop path: ' + path2) - return - show_library_loop(bld, d, lib2, path2, seen) - seen.remove(d) - - -def calculate_final_deps(bld, tgt_list, loops): - '''calculate the final library and object dependencies''' - for t in tgt_list: - # start with the maximum possible list - t.final_libs = t.direct_libs.union(indirect_libs(bld, t, set(), loops)) - t.final_objects = t.direct_objects.union(indirect_objects(bld, t, set(), loops)) - - for t in tgt_list: - # don't depend on ourselves - if t.sname in t.final_libs: - t.final_libs.remove(t.sname) - if t.sname in t.final_objects: - t.final_objects.remove(t.sname) - - # handle any non-shared binaries - for t in tgt_list: - if t.samba_type == 'BINARY' and bld.NONSHARED_BINARY(t.sname): - subsystem_list = LOCAL_CACHE(bld, 'INIT_FUNCTIONS') - targets = LOCAL_CACHE(bld, 'TARGET_TYPE') - - # replace lib deps with objlist deps - for l in t.final_libs: - objname = l + '.objlist' - t2 = bld.get_tgen_by_name(objname) - if t2 is None: - Logs.error('ERROR: subsystem %s not found' % objname) - sys.exit(1) - t.final_objects.add(objname) - t.final_objects = t.final_objects.union(extended_objects(bld, t2, set())) - if l in subsystem_list: - # its a subsystem - we also need the contents of any modules - for d in subsystem_list[l]: - module_name = d['TARGET'] - if targets[module_name] == 'LIBRARY': - objname = module_name + '.objlist' - elif targets[module_name] == 'SUBSYSTEM': - objname = module_name - else: - continue - t2 = bld.get_tgen_by_name(objname) - if t2 is None: - Logs.error('ERROR: subsystem %s not found' % objname) - sys.exit(1) - t.final_objects.add(objname) - t.final_objects = t.final_objects.union(extended_objects(bld, t2, set())) - t.final_libs = set() - - # find any library loops - for t in tgt_list: - if t.samba_type in ['LIBRARY', 'PYTHON']: - for l in t.final_libs.copy(): - t2 = bld.get_tgen_by_name(l) - if t.sname in t2.final_libs: - if getattr(bld.env, "ALLOW_CIRCULAR_LIB_DEPENDENCIES", False): - # we could break this in either direction. If one of the libraries - # has a version number, and will this be distributed publicly, then - # we should make it the lower level library in the DAG - Logs.warn('deps: removing library loop %s from %s' % (t.sname, t2.sname)) - dependency_loop(loops, t, t2.sname) - t2.final_libs.remove(t.sname) - else: - Logs.error('ERROR: circular library dependency between %s and %s' - % (t.sname, t2.sname)) - show_library_loop(bld, t.sname, t2.sname, t.sname, set()) - show_library_loop(bld, t2.sname, t.sname, t2.sname, set()) - sys.exit(1) - - for loop in loops: - debug('deps: Found dependency loops for target %s : %s', loop, loops[loop]) - - # we now need to make corrections for any library loops we broke up - # any target that depended on the target of the loop and doesn't - # depend on the source of the loop needs to get the loop source added - for type in ['BINARY','PYTHON','LIBRARY','BINARY']: - for t in tgt_list: - if t.samba_type != type: continue - for loop in loops: - if loop in t.final_libs: - diff = loops[loop].difference(t.final_libs) - if t.sname in diff: - diff.remove(t.sname) - if t.sname in diff: - diff.remove(t.sname) - # make sure we don't recreate the loop again! - for d in diff.copy(): - t2 = bld.get_tgen_by_name(d) - if t2.samba_type == 'LIBRARY': - if t.sname in t2.final_libs: - debug('deps: removing expansion %s from %s', d, t.sname) - diff.remove(d) - if diff: - debug('deps: Expanded target %s by loop %s libraries (loop %s) %s', t.sname, loop, - loops[loop], diff) - t.final_libs = t.final_libs.union(diff) - - # remove objects that are also available in linked libs - count = 0 - while reduce_objects(bld, tgt_list): - count += 1 - if count > 100: - Logs.warn("WARNING: Unable to remove all inter-target object duplicates") - break - debug('deps: Object reduction took %u iterations', count) - - # add in any syslib dependencies - for t in tgt_list: - if not t.samba_type in ['BINARY','PYTHON','LIBRARY','SUBSYSTEM']: - continue - syslibs = set() - for d in t.final_objects: - t2 = bld.get_tgen_by_name(d) - syslibs = syslibs.union(t2.direct_syslibs) - # this adds the indirect syslibs as well, which may not be needed - # depending on the linker flags - for d in t.final_libs: - t2 = bld.get_tgen_by_name(d) - syslibs = syslibs.union(t2.direct_syslibs) - t.final_syslibs = syslibs - - - # find any unresolved library loops - lib_loop_error = False - for t in tgt_list: - if t.samba_type in ['LIBRARY', 'PYTHON']: - for l in t.final_libs.copy(): - t2 = bld.get_tgen_by_name(l) - if t.sname in t2.final_libs: - Logs.error('ERROR: Unresolved library loop %s from %s' % (t.sname, t2.sname)) - lib_loop_error = True - if lib_loop_error: - sys.exit(1) - - debug('deps: removed duplicate dependencies') - - -def show_dependencies(bld, target, seen): - '''recursively show the dependencies of target''' - - if target in seen: - return - - t = bld.get_tgen_by_name(target) - if t is None: - Logs.error("ERROR: Unable to find target '%s'" % target) - sys.exit(1) - - Logs.info('%s(OBJECTS): %s' % (target, t.direct_objects)) - Logs.info('%s(LIBS): %s' % (target, t.direct_libs)) - Logs.info('%s(SYSLIBS): %s' % (target, t.direct_syslibs)) - - seen.add(target) - - for t2 in t.direct_objects: - show_dependencies(bld, t2, seen) - - -def show_object_duplicates(bld, tgt_list): - '''show a list of object files that are included in more than - one library or binary''' - - targets = LOCAL_CACHE(bld, 'TARGET_TYPE') - - used_by = {} - - Logs.info("showing duplicate objects") - - for t in tgt_list: - if not targets[t.sname] in [ 'LIBRARY', 'PYTHON' ]: - continue - for n in getattr(t, 'final_objects', set()): - t2 = bld.get_tgen_by_name(n) - if not n in used_by: - used_by[n] = set() - used_by[n].add(t.sname) - - for n in used_by: - if len(used_by[n]) > 1: - Logs.info("target '%s' is used by %s" % (n, used_by[n])) - - Logs.info("showing indirect dependency counts (sorted by count)") - - def indirect_count(t1, t2): - return len(t2.indirect_objects) - len(t1.indirect_objects) - - sorted_list = sorted(tgt_list, cmp=indirect_count) - for t in sorted_list: - if len(t.indirect_objects) > 1: - Logs.info("%s depends on %u indirect objects" % (t.sname, len(t.indirect_objects))) - - -###################################################################### -# this provides a way to save our dependency calculations between runs -savedeps_version = 3 -savedeps_inputs = ['samba_deps', 'samba_includes', 'local_include', 'local_include_first', 'samba_cflags', - 'source', 'grouping_library', 'samba_ldflags', 'allow_undefined_symbols', - 'use_global_deps', 'global_include' ] -savedeps_outputs = ['uselib', 'uselib_local', 'add_objects', 'includes', - 'cflags', 'ldflags', 'samba_deps_extended', 'final_libs'] -savedeps_outenv = ['INC_PATHS'] -savedeps_envvars = ['NONSHARED_BINARIES', 'GLOBAL_DEPENDENCIES', 'EXTRA_CFLAGS', 'EXTRA_LDFLAGS', 'EXTRA_INCLUDES' ] -savedeps_caches = ['GLOBAL_DEPENDENCIES', 'TARGET_TYPE', 'INIT_FUNCTIONS', 'SYSLIB_DEPS'] -savedeps_files = ['buildtools/wafsamba/samba_deps.py'] - -def save_samba_deps(bld, tgt_list): - '''save the dependency calculations between builds, to make - further builds faster''' - denv = ConfigSet.ConfigSet() - - denv.version = savedeps_version - denv.savedeps_inputs = savedeps_inputs - denv.savedeps_outputs = savedeps_outputs - denv.input = {} - denv.output = {} - denv.outenv = {} - denv.caches = {} - denv.envvar = {} - denv.files = {} - - for f in savedeps_files: - denv.files[f] = os.stat(os.path.join(bld.srcnode.abspath(), f)).st_mtime - - for c in savedeps_caches: - denv.caches[c] = LOCAL_CACHE(bld, c) - - for e in savedeps_envvars: - denv.envvar[e] = bld.env[e] - - for t in tgt_list: - # save all the input attributes for each target - tdeps = {} - for attr in savedeps_inputs: - v = getattr(t, attr, None) - if v is not None: - tdeps[attr] = v - if tdeps != {}: - denv.input[t.sname] = tdeps - - # save all the output attributes for each target - tdeps = {} - for attr in savedeps_outputs: - v = getattr(t, attr, None) - if v is not None: - tdeps[attr] = v - if tdeps != {}: - denv.output[t.sname] = tdeps - - tdeps = {} - for attr in savedeps_outenv: - if attr in t.env: - tdeps[attr] = t.env[attr] - if tdeps != {}: - denv.outenv[t.sname] = tdeps - - depsfile = os.path.join(bld.cache_dir, "sambadeps") - denv.store_fast(depsfile) - - - -def load_samba_deps(bld, tgt_list): - '''load a previous set of build dependencies if possible''' - depsfile = os.path.join(bld.cache_dir, "sambadeps") - denv = ConfigSet.ConfigSet() - try: - debug('deps: checking saved dependencies') - denv.load_fast(depsfile) - if (denv.version != savedeps_version or - denv.savedeps_inputs != savedeps_inputs or - denv.savedeps_outputs != savedeps_outputs): - return False - except Exception: - return False - - # check if critical files have changed - for f in savedeps_files: - if f not in denv.files: - return False - if denv.files[f] != os.stat(os.path.join(bld.srcnode.abspath(), f)).st_mtime: - return False - - # check if caches are the same - for c in savedeps_caches: - if c not in denv.caches or denv.caches[c] != LOCAL_CACHE(bld, c): - return False - - # check if caches are the same - for e in savedeps_envvars: - if e not in denv.envvar or denv.envvar[e] != bld.env[e]: - return False - - # check inputs are the same - for t in tgt_list: - tdeps = {} - for attr in savedeps_inputs: - v = getattr(t, attr, None) - if v is not None: - tdeps[attr] = v - if t.sname in denv.input: - olddeps = denv.input[t.sname] - else: - olddeps = {} - if tdeps != olddeps: - #print '%s: \ntdeps=%s \nodeps=%s' % (t.sname, tdeps, olddeps) - return False - - # put outputs in place - for t in tgt_list: - if not t.sname in denv.output: continue - tdeps = denv.output[t.sname] - for a in tdeps: - setattr(t, a, tdeps[a]) - - # put output env vars in place - for t in tgt_list: - if not t.sname in denv.outenv: continue - tdeps = denv.outenv[t.sname] - for a in tdeps: - t.env[a] = tdeps[a] - - debug('deps: loaded saved dependencies') - return True - - - -def check_project_rules(bld): - '''check the project rules - ensuring the targets are sane''' - - loops = {} - inc_loops = {} - - tgt_list = get_tgt_list(bld) - - add_samba_attributes(bld, tgt_list) - - force_project_rules = (Options.options.SHOWDEPS or - Options.options.SHOW_DUPLICATES) - - if not force_project_rules and load_samba_deps(bld, tgt_list): - return - - timer = Utils.Timer() - - bld.new_rules = True - Logs.info("Checking project rules ...") - - debug('deps: project rules checking started') - - expand_subsystem_deps(bld) - - debug("deps: expand_subsystem_deps: %s" % str(timer)) - - replace_grouping_libraries(bld, tgt_list) - - debug("deps: replace_grouping_libraries: %s" % str(timer)) - - build_direct_deps(bld, tgt_list) - - debug("deps: build_direct_deps: %s" % str(timer)) - - break_dependency_loops(bld, tgt_list) - - debug("deps: break_dependency_loops: %s" % str(timer)) - - if Options.options.SHOWDEPS: - show_dependencies(bld, Options.options.SHOWDEPS, set()) - - calculate_final_deps(bld, tgt_list, loops) - - debug("deps: calculate_final_deps: %s" % str(timer)) - - if Options.options.SHOW_DUPLICATES: - show_object_duplicates(bld, tgt_list) - - # run the various attribute generators - for f in [ build_dependencies, build_includes, add_init_functions ]: - debug('deps: project rules checking %s', f) - for t in tgt_list: f(t) - debug("deps: %s: %s" % (f, str(timer))) - - debug('deps: project rules stage1 completed') - - if not check_duplicate_sources(bld, tgt_list): - Logs.error("Duplicate sources present - aborting") - sys.exit(1) - - debug("deps: check_duplicate_sources: %s" % str(timer)) - - if not bld.check_group_ordering(tgt_list): - Logs.error("Bad group ordering - aborting") - sys.exit(1) - - debug("deps: check_group_ordering: %s" % str(timer)) - - show_final_deps(bld, tgt_list) - - debug("deps: show_final_deps: %s" % str(timer)) - - debug('deps: project rules checking completed - %u targets checked', - len(tgt_list)) - - if not bld.is_install: - save_samba_deps(bld, tgt_list) - - debug("deps: save_samba_deps: %s" % str(timer)) - - Logs.info("Project rules pass") - - -def CHECK_PROJECT_RULES(bld): - '''enable checking of project targets for sanity''' - if bld.env.added_project_rules: - return - bld.env.added_project_rules = True - bld.add_pre_fun(check_project_rules) -Build.BuildContext.CHECK_PROJECT_RULES = CHECK_PROJECT_RULES - - diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_dist.py b/ldb-2.0.8/buildtools/wafsamba/samba_dist.py deleted file mode 100644 index 6af7bb4..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/samba_dist.py +++ /dev/null @@ -1,280 +0,0 @@ -# customised version of 'waf dist' for Samba tools -# uses git ls-files to get file lists - -import os, sys, tarfile -from waflib import Utils, Scripting, Logs, Options -from waflib.Configure import conf -from samba_utils import os_path_relpath, get_string -from waflib import Context - -dist_dirs = None -dist_files = None -dist_blacklist = "" -dist_archive = None - -class Dist(Context.Context): - # TODO remove - cmd = 'dist' - fun = 'dist' - def execute(self): - Context.g_module.dist() - -class DistCheck(Scripting.DistCheck): - fun = 'distcheck' - cmd = 'distcheck' - def execute(self): - Options.options.distcheck_args = '' - if Context.g_module.distcheck is Scripting.distcheck: - # default - Context.g_module.distcheck(self) - else: - Context.g_module.distcheck() - Context.g_module.dist() - self.check() - def get_arch_name(self): - global dist_archive - return dist_archive - def make_distcheck_cmd(self, tmpdir): - waf = os.path.abspath(sys.argv[0]) - return [sys.executable, waf, 'configure', 'build', 'install', 'uninstall', '--destdir=' + tmpdir] - -def add_symlink(tar, fname, abspath, basedir): - '''handle symlinks to directories that may move during packaging''' - if not os.path.islink(abspath): - return False - tinfo = tar.gettarinfo(name=abspath, arcname=fname) - tgt = os.readlink(abspath) - - if dist_dirs: - # we need to find the target relative to the main directory - # this is here to cope with symlinks into the buildtools - # directory from within the standalone libraries in Samba. For example, - # a symlink to ../../builtools/scripts/autogen-waf.sh needs - # to be rewritten as a symlink to buildtools/scripts/autogen-waf.sh - # when the tarball for talloc is built - - # the filename without the appname-version - rel_fname = '/'.join(fname.split('/')[1:]) - - # join this with the symlink target - tgt_full = os.path.join(os.path.dirname(rel_fname), tgt) - - # join with the base directory - tgt_base = os.path.normpath(os.path.join(basedir, tgt_full)) - - # see if this is inside one of our dist_dirs - for dir in dist_dirs.split(): - if dir.find(':') != -1: - destdir=dir.split(':')[1] - dir=dir.split(':')[0] - else: - destdir = '.' - if dir == basedir: - # internal links don't get rewritten - continue - if dir == tgt_base[0:len(dir)] and tgt_base[len(dir)] == '/': - new_tgt = destdir + tgt_base[len(dir):] - tinfo.linkname = new_tgt - break - - tinfo.uid = 0 - tinfo.gid = 0 - tinfo.uname = 'root' - tinfo.gname = 'root' - tar.addfile(tinfo) - return True - -def add_tarfile(tar, fname, abspath, basedir): - '''add a file to the tarball''' - if add_symlink(tar, fname, abspath, basedir): - return - try: - tinfo = tar.gettarinfo(name=abspath, arcname=fname) - except OSError: - Logs.error('Unable to find file %s - missing from git checkout?' % abspath) - sys.exit(1) - tinfo.uid = 0 - tinfo.gid = 0 - tinfo.uname = 'root' - tinfo.gname = 'root' - fh = open(abspath, "rb") - tar.addfile(tinfo, fileobj=fh) - fh.close() - - -def vcs_dir_contents(path): - """Return the versioned files under a path. - - :return: List of paths relative to path - """ - repo = path - while repo != "/": - if os.path.isdir(os.path.join(repo, ".git")): - ls_files_cmd = [ 'git', 'ls-files', '--full-name', - os_path_relpath(path, repo) ] - cwd = None - env = dict(os.environ) - env["GIT_DIR"] = os.path.join(repo, ".git") - break - repo = os.path.dirname(repo) - if repo == "/": - raise Exception("unsupported or no vcs for %s" % path) - return get_string(Utils.cmd_output(ls_files_cmd, cwd=cwd, env=env)).split('\n') - - -def dist(appname='', version=''): - - def add_files_to_tarball(tar, srcdir, srcsubdir, dstdir, dstsubdir, blacklist, files): - if blacklist is None: - blacklist = [] - for f in files: - abspath = os.path.join(srcdir, f) - - if srcsubdir != '.': - f = f[len(srcsubdir)+1:] - - # Remove files in the blacklist - if f in blacklist: - continue - blacklisted = False - # Remove directories in the blacklist - for d in blacklist: - if f.startswith(d): - blacklisted = True - if blacklisted: - continue - if os.path.isdir(abspath) and not os.path.islink(abspath): - continue - if dstsubdir != '.': - f = dstsubdir + '/' + f - fname = dstdir + '/' + f - add_tarfile(tar, fname, abspath, srcsubdir) - - - def list_directory_files(path): - curdir = os.getcwd() - os.chdir(srcdir) - out_files = [] - for root, dirs, files in os.walk(path): - for f in files: - out_files.append(os.path.join(root, f)) - os.chdir(curdir) - return out_files - - - if not isinstance(appname, str) or not appname: - # this copes with a mismatch in the calling arguments for dist() - appname = Context.g_module.APPNAME - version = Context.g_module.VERSION - if not version: - version = Context.g_module.VERSION - - srcdir = os.path.normpath( - os.path.join(os.path.dirname(Context.g_module.root_path), - Context.g_module.top)) - - if not dist_dirs: - Logs.error('You must use samba_dist.DIST_DIRS() to set which directories to package') - sys.exit(1) - - dist_base = '%s-%s' % (appname, version) - - if Options.options.SIGN_RELEASE: - dist_name = '%s.tar' % (dist_base) - tar = tarfile.open(dist_name, 'w') - else: - dist_name = '%s.tar.gz' % (dist_base) - tar = tarfile.open(dist_name, 'w:gz') - - blacklist = dist_blacklist.split() - - for dir in dist_dirs.split(): - if dir.find(':') != -1: - destdir=dir.split(':')[1] - dir=dir.split(':')[0] - else: - destdir = '.' - absdir = os.path.join(srcdir, dir) - try: - files = vcs_dir_contents(absdir) - except Exception as e: - Logs.error('unable to get contents of %s: %s' % (absdir, e)) - sys.exit(1) - add_files_to_tarball(tar, srcdir, dir, dist_base, destdir, blacklist, files) - - if dist_files: - for file in dist_files.split(): - if file.find(':') != -1: - destfile = file.split(':')[1] - file = file.split(':')[0] - else: - destfile = file - - absfile = os.path.join(srcdir, file) - - if os.path.isdir(absfile) and not os.path.islink(absfile): - destdir = destfile - dir = file - files = list_directory_files(dir) - add_files_to_tarball(tar, srcdir, dir, dist_base, destdir, blacklist, files) - else: - fname = dist_base + '/' + destfile - add_tarfile(tar, fname, absfile, destfile) - - tar.close() - - if Options.options.SIGN_RELEASE: - import gzip - try: - os.unlink(dist_name + '.asc') - except OSError: - pass - - cmd = "gpg --detach-sign --armor " + dist_name - os.system(cmd) - uncompressed_tar = open(dist_name, 'rb') - compressed_tar = gzip.open(dist_name + '.gz', 'wb') - while 1: - buffer = uncompressed_tar.read(1048576) - if buffer: - compressed_tar.write(buffer) - else: - break - uncompressed_tar.close() - compressed_tar.close() - os.unlink(dist_name) - Logs.info('Created %s.gz %s.asc' % (dist_name, dist_name)) - dist_name = dist_name + '.gz' - else: - Logs.info('Created %s' % dist_name) - - # TODO use the ctx object instead - global dist_archive - dist_archive = dist_name - return dist_name - - -@conf -def DIST_DIRS(dirs): - '''set the directories to package, relative to top srcdir''' - global dist_dirs - if not dist_dirs: - dist_dirs = dirs - -@conf -def DIST_FILES(files, extend=False): - '''set additional files for packaging, relative to top srcdir''' - global dist_files - if not dist_files: - dist_files = files - elif extend: - dist_files = dist_files + " " + files - -@conf -def DIST_BLACKLIST(blacklist): - '''set the files to exclude from packaging, relative to top srcdir''' - global dist_blacklist - if not dist_blacklist: - dist_blacklist = blacklist - -Scripting.dist = dist diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_git.py b/ldb-2.0.8/buildtools/wafsamba/samba_git.py deleted file mode 100644 index 09a204f..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/samba_git.py +++ /dev/null @@ -1,57 +0,0 @@ -import os -import subprocess - -def find_git(env=None): - """Find the git binary.""" - if env is not None and 'GIT' in env: - return env.get_flat('GIT') - - # Get version from GIT - if os.path.exists("/usr/bin/git"): - # this is useful when doing make dist without configuring - return "/usr/bin/git" - - return None - - -def has_submodules(path): - """Check whether a source directory is git-versioned and has submodules. - - :param path: Path to Samba source directory - """ - return (os.path.isdir(os.path.join(path, ".git")) and - os.path.isfile(os.path.join(path, ".gitmodules"))) - - -def read_submodule_status(path, env=None): - """Check status of submodules. - - :param path: Path to git directory - :param env: Optional waf environment - :return: Yields tuples with submodule relpath and status - (one of: 'out-of-date', 'not-checked-out', 'up-to-date') - :raise RuntimeError: raised when parsing of 'git submodule status' output - fails. - """ - if not has_submodules(path): - # No point in running git. - return - git = find_git(env) - if git is None: - return - p = subprocess.Popen([git, "submodule", "status"], stdout=subprocess.PIPE, - cwd=path) - (stdout, stderr) = p.communicate(None) - for l in stdout.splitlines(): - l = l.rstrip() - status = l[0] - l = l[1:] - parts = l.split(" ") - if len(parts) > 2 and status in ("-", "+"): - yield (parts[1], "out-of-date") - elif len(parts) == 2 and status == "-": - yield (parts[1], "not-checked-out") - elif len(parts) > 2 and status == " ": - yield (parts[1], "up-to-date") - else: - raise RuntimeError("Unable to parse submodule status: %r, %r" % (status, parts)) diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_headers.py b/ldb-2.0.8/buildtools/wafsamba/samba_headers.py deleted file mode 100644 index a268c01..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/samba_headers.py +++ /dev/null @@ -1,181 +0,0 @@ -# specialist handling of header files for Samba - -import os, re, sys, fnmatch -from waflib import Build, Logs, Utils, Errors -from samba_utils import TO_LIST, os_path_relpath - - -def header_install_path(header, header_path): - '''find the installation path for a header, given a header_path option''' - if not header_path: - return '' - if not isinstance(header_path, list): - return header_path - for (p1, dir) in header_path: - for p2 in TO_LIST(p1): - if fnmatch.fnmatch(header, p2): - return dir - # default to current path - return '' - - -re_header = re.compile('^\s*#\s*include[ \t]*"([^"]+)"', re.I | re.M) - -# a dictionary mapping source header paths to public header paths -header_map = {} - -def find_suggested_header(hpath): - '''find a suggested header path to use''' - base = os.path.basename(hpath) - ret = [] - for h in header_map: - if os.path.basename(h) == base: - ret.append('<%s>' % header_map[h]) - ret.append('"%s"' % h) - return ret - -def create_public_header(task): - '''create a public header from a private one, output within the build tree''' - src = task.inputs[0].abspath(task.env) - tgt = task.outputs[0].bldpath(task.env) - - if os.path.exists(tgt): - os.unlink(tgt) - - relsrc = os_path_relpath(src, task.env.TOPDIR) - - infile = open(src, mode='r') - outfile = open(tgt, mode='w') - linenumber = 0 - - search_paths = [ '', task.env.RELPATH ] - for i in task.env.EXTRA_INCLUDES: - if i.startswith('#'): - search_paths.append(i[1:]) - - for line in infile: - linenumber += 1 - - # allow some straight substitutions - if task.env.public_headers_replace and line.strip() in task.env.public_headers_replace: - outfile.write(task.env.public_headers_replace[line.strip()] + '\n') - continue - - # see if its an include line - m = re_header.match(line) - if m is None: - outfile.write(line) - continue - - # its an include, get the header path - hpath = m.group(1) - if hpath.startswith("bin/default/"): - hpath = hpath[12:] - - # some are always allowed - if task.env.public_headers_skip and hpath in task.env.public_headers_skip: - outfile.write(line) - continue - - # work out the header this refers to - found = False - for s in search_paths: - p = os.path.normpath(os.path.join(s, hpath)) - if p in header_map: - outfile.write("#include <%s>\n" % header_map[p]) - found = True - break - if found: - continue - - if task.env.public_headers_allow_broken: - Logs.warn("Broken public header include '%s' in '%s'" % (hpath, relsrc)) - outfile.write(line) - continue - - # try to be nice to the developer by suggesting an alternative - suggested = find_suggested_header(hpath) - outfile.close() - os.unlink(tgt) - sys.stderr.write("%s:%u:Error: unable to resolve public header %s (maybe try one of %s)\n" % ( - os.path.relpath(src, os.getcwd()), linenumber, hpath, suggested)) - raise Errors.WafError("Unable to resolve header path '%s' in public header '%s' in directory %s" % ( - hpath, relsrc, task.env.RELPATH)) - infile.close() - outfile.close() - - -def public_headers_simple(bld, public_headers, header_path=None, public_headers_install=True): - '''install some headers - simple version, no munging needed - ''' - if not public_headers_install: - return - for h in TO_LIST(public_headers): - inst_path = header_install_path(h, header_path) - if h.find(':') != -1: - s = h.split(":") - h_name = s[0] - inst_name = s[1] - else: - h_name = h - inst_name = os.path.basename(h) - bld.INSTALL_FILES('${INCLUDEDIR}', h_name, destname=inst_name) - - -def PUBLIC_HEADERS(bld, public_headers, header_path=None, public_headers_install=True): - '''install some headers - - header_path may either be a string that is added to the INCLUDEDIR, - or it can be a dictionary of wildcard patterns which map to destination - directories relative to INCLUDEDIR - ''' - bld.SET_BUILD_GROUP('final') - - if not bld.env.build_public_headers: - # in this case no header munging neeeded. Used for tdb, talloc etc - public_headers_simple(bld, public_headers, header_path=header_path, - public_headers_install=public_headers_install) - return - - # create the public header in the given path - # in the build tree - for h in TO_LIST(public_headers): - inst_path = header_install_path(h, header_path) - if h.find(':') != -1: - s = h.split(":") - h_name = s[0] - inst_name = s[1] - else: - h_name = h - inst_name = os.path.basename(h) - curdir = bld.path.abspath() - relpath1 = os_path_relpath(bld.srcnode.abspath(), curdir) - relpath2 = os_path_relpath(curdir, bld.srcnode.abspath()) - targetdir = os.path.normpath(os.path.join(relpath1, bld.env.build_public_headers, inst_path)) - if not os.path.exists(os.path.join(curdir, targetdir)): - raise Errors.WafError("missing source directory %s for public header %s" % (targetdir, inst_name)) - target = os.path.join(targetdir, inst_name) - - # the source path of the header, relative to the top of the source tree - src_path = os.path.normpath(os.path.join(relpath2, h_name)) - - # the install path of the header, relative to the public include directory - target_path = os.path.normpath(os.path.join(inst_path, inst_name)) - - header_map[src_path] = target_path - - t = bld.SAMBA_GENERATOR('HEADER_%s/%s/%s' % (relpath2, inst_path, inst_name), - group='headers', - rule=create_public_header, - source=h_name, - target=target) - t.env.RELPATH = relpath2 - t.env.TOPDIR = bld.srcnode.abspath() - if not bld.env.public_headers_list: - bld.env.public_headers_list = [] - bld.env.public_headers_list.append(os.path.join(inst_path, inst_name)) - if public_headers_install: - bld.INSTALL_FILES('${INCLUDEDIR}', - target, - destname=os.path.join(inst_path, inst_name), flat=True) -Build.BuildContext.PUBLIC_HEADERS = PUBLIC_HEADERS diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_install.py b/ldb-2.0.8/buildtools/wafsamba/samba_install.py deleted file mode 100644 index 07b01d6..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/samba_install.py +++ /dev/null @@ -1,236 +0,0 @@ -########################### -# this handles the magic we need to do for installing -# with all the configure options that affect rpath and shared -# library use - -import os -from waflib import Utils, Errors -from waflib.TaskGen import feature, before, after -from samba_utils import LIB_PATH, MODE_755, install_rpath, build_rpath - -@feature('install_bin') -@after('apply_core') -@before('apply_link', 'apply_obj_vars') -def install_binary(self): - '''install a binary, taking account of the different rpath varients''' - bld = self.bld - - # get the ldflags we will use for install and build - install_ldflags = install_rpath(self) - build_ldflags = build_rpath(bld) - - if not self.bld.is_install: - # just need to set rpath if we are not installing - self.env.RPATH = build_ldflags - return - - # work out the install path, expanding variables - install_path = getattr(self, 'samba_inst_path', None) or '${BINDIR}' - install_path = bld.EXPAND_VARIABLES(install_path) - - orig_target = os.path.basename(self.target) - - if install_ldflags != build_ldflags: - # we will be creating a new target name, and using that for the - # install link. That stops us from overwriting the existing build - # target, which has different ldflags - self.target += '.inst' - - # setup the right rpath link flags for the install - self.env.RPATH = install_ldflags - - if not self.samba_install: - # this binary is marked not to be installed - return - - # tell waf to install the right binary - bld.install_as(os.path.join(install_path, orig_target), - self.path.find_or_declare(self.target), - chmod=MODE_755) - - - -@feature('install_lib') -@after('apply_core') -@before('apply_link', 'apply_obj_vars') -def install_library(self): - '''install a library, taking account of the different rpath varients''' - if getattr(self, 'done_install_library', False): - return - - bld = self.bld - - default_env = bld.all_envs['default'] - try: - install_ldflags = install_rpath(self) - build_ldflags = build_rpath(bld) - - if not self.bld.is_install or not getattr(self, 'samba_install', True): - # just need to set the build rpath if we are not installing - self.env.RPATH = build_ldflags - return - - # setup the install path, expanding variables - install_path = getattr(self, 'samba_inst_path', None) - if install_path is None: - if getattr(self, 'private_library', False): - install_path = '${PRIVATELIBDIR}' - else: - install_path = '${LIBDIR}' - install_path = bld.EXPAND_VARIABLES(install_path) - - target_name = self.target - - if install_ldflags != build_ldflags: - # we will be creating a new target name, and using that for the - # install link. That stops us from overwriting the existing build - # target, which has different ldflags - self.done_install_library = True - t = self.clone(self.env) - t.posted = False - t.target += '.inst' - t.name = self.name + '.inst' - self.env.RPATH = build_ldflags - else: - t = self - - t.env.RPATH = install_ldflags - - dev_link = None - - # in the following the names are: - # - inst_name is the name with .inst. in it, in the build - # directory - # - install_name is the name in the install directory - # - install_link is a symlink in the install directory, to install_name - - if getattr(self, 'samba_realname', None): - install_name = self.samba_realname - install_link = None - if getattr(self, 'soname', ''): - install_link = self.soname - if getattr(self, 'samba_type', None) == 'PYTHON': - inst_name = bld.make_libname(t.target, nolibprefix=True, python=True) - else: - inst_name = bld.make_libname(t.target) - elif self.vnum: - vnum_base = self.vnum.split('.')[0] - install_name = bld.make_libname(target_name, version=self.vnum) - install_link = bld.make_libname(target_name, version=vnum_base) - inst_name = bld.make_libname(t.target) - if not self.private_library or not t.env.SONAME_ST: - # only generate the dev link for non-bundled libs - dev_link = bld.make_libname(target_name) - elif getattr(self, 'soname', ''): - install_name = bld.make_libname(target_name) - install_link = self.soname - inst_name = bld.make_libname(t.target) - else: - install_name = bld.make_libname(target_name) - install_link = None - inst_name = bld.make_libname(t.target) - - if t.env.SONAME_ST: - # ensure we get the right names in the library - if install_link: - t.env.append_value('LINKFLAGS', t.env.SONAME_ST % install_link) - else: - t.env.append_value('LINKFLAGS', t.env.SONAME_ST % install_name) - t.env.SONAME_ST = '' - - # tell waf to install the library - bld.install_as(os.path.join(install_path, install_name), - self.path.find_or_declare(inst_name), - chmod=MODE_755) - - if install_link and install_link != install_name: - # and the symlink if needed - bld.symlink_as(os.path.join(install_path, install_link), os.path.basename(install_name)) - if dev_link: - bld.symlink_as(os.path.join(install_path, dev_link), os.path.basename(install_name)) - finally: - bld.all_envs['default'] = default_env - - -@feature('cshlib') -@after('apply_implib') -@before('apply_vnum') -def apply_soname(self): - '''install a library, taking account of the different rpath varients''' - - if self.env.SONAME_ST and getattr(self, 'soname', ''): - self.env.append_value('LINKFLAGS', self.env.SONAME_ST % self.soname) - self.env.SONAME_ST = '' - -@feature('cshlib') -@after('apply_implib') -@before('apply_vnum') -def apply_vscript(self): - '''add version-script arguments to library build''' - - if self.env.HAVE_LD_VERSION_SCRIPT and getattr(self, 'version_script', ''): - self.env.append_value('LINKFLAGS', "-Wl,--version-script=%s" % - self.version_script) - self.version_script = None - - -############################## -# handle the creation of links for libraries and binaries in the build tree - -@feature('symlink_lib') -@after('apply_link') -def symlink_lib(self): - '''symlink a shared lib''' - - if self.target.endswith('.inst'): - return - - blddir = os.path.dirname(self.bld.srcnode.abspath(self.bld.env)) - libpath = self.link_task.outputs[0].abspath(self.env) - - # calculat the link target and put it in the environment - soext="" - vnum = getattr(self, 'vnum', None) - if vnum is not None: - soext = '.' + vnum.split('.')[0] - - link_target = getattr(self, 'link_name', '') - if link_target == '': - basename = os.path.basename(self.bld.make_libname(self.target, version=soext)) - if getattr(self, "private_library", False): - link_target = '%s/private/%s' % (LIB_PATH, basename) - else: - link_target = '%s/%s' % (LIB_PATH, basename) - - link_target = os.path.join(blddir, link_target) - - if os.path.lexists(link_target): - if os.path.islink(link_target) and os.readlink(link_target) == libpath: - return - os.unlink(link_target) - - link_container = os.path.dirname(link_target) - if not os.path.isdir(link_container): - os.makedirs(link_container) - - os.symlink(libpath, link_target) - - -@feature('symlink_bin') -@after('apply_link') -def symlink_bin(self): - '''symlink a binary into the build directory''' - - if self.target.endswith('.inst'): - return - - if not self.link_task.outputs or not self.link_task.outputs[0]: - raise Errors.WafError('no outputs found for %s in symlink_bin' % self.name) - binpath = self.link_task.outputs[0].abspath(self.env) - bldpath = os.path.join(self.bld.env.BUILD_DIRECTORY, self.link_task.outputs[0].name) - - if os.path.lexists(bldpath): - if os.path.islink(bldpath) and os.readlink(bldpath) == binpath: - return - os.unlink(bldpath) - os.symlink(binpath, bldpath) diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_patterns.py b/ldb-2.0.8/buildtools/wafsamba/samba_patterns.py deleted file mode 100644 index d0fe965..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/samba_patterns.py +++ /dev/null @@ -1,201 +0,0 @@ -# a waf tool to add extension based build patterns for Samba - -import sys -from waflib import Build -from wafsamba import samba_version_file - -def write_version_header(task): - '''print version.h contents''' - src = task.inputs[0].srcpath(task.env) - - version = samba_version_file(src, task.env.srcdir, env=task.env, is_install=task.generator.bld.is_install) - string = str(version) - - task.outputs[0].write(string) - return 0 - - -def SAMBA_MKVERSION(bld, target, source='VERSION'): - '''generate the version.h header for Samba''' - - # We only force waf to re-generate this file if we are installing, - # because only then is information not included in the deps (the - # git revision) included in the version. - t = bld.SAMBA_GENERATOR('VERSION', - rule=write_version_header, - source=source, - target=target, - always=bld.is_install) -Build.BuildContext.SAMBA_MKVERSION = SAMBA_MKVERSION - - -def write_build_options_header(fp): - '''write preamble for build_options.c''' - fp.write("/*\n") - fp.write(" Unix SMB/CIFS implementation.\n") - fp.write(" Build Options for Samba Suite\n") - fp.write(" Copyright (C) Vance Lankhaar 2003\n") - fp.write(" Copyright (C) Andrew Bartlett 2001\n") - fp.write("\n") - fp.write(" This program is free software; you can redistribute it and/or modify\n") - fp.write(" it under the terms of the GNU General Public License as published by\n") - fp.write(" the Free Software Foundation; either version 3 of the License, or\n") - fp.write(" (at your option) any later version.\n") - fp.write("\n") - fp.write(" This program is distributed in the hope that it will be useful,\n") - fp.write(" but WITHOUT ANY WARRANTY; without even the implied warranty of\n") - fp.write(" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") - fp.write(" GNU General Public License for more details.\n") - fp.write("\n") - fp.write(" You should have received a copy of the GNU General Public License\n") - fp.write(" along with this program; if not, see .\n") - fp.write("*/\n") - fp.write("\n") - fp.write("#include \"includes.h\"\n") - fp.write("#include \"dynconfig/dynconfig.h\"\n") - fp.write("#include \"lib/cluster_support.h\"\n") - - fp.write("\n") - fp.write("static int output(bool screen, const char *format, ...) PRINTF_ATTRIBUTE(2,3);\n") - fp.write("void build_options(bool screen);\n") - fp.write("\n") - fp.write("\n") - fp.write("/****************************************************************************\n") - fp.write("helper function for build_options\n") - fp.write("****************************************************************************/\n") - fp.write("static int output(bool screen, const char *format, ...)\n") - fp.write("{\n") - fp.write(" char *ptr = NULL;\n") - fp.write(" int ret = 0;\n") - fp.write(" va_list ap;\n") - fp.write(" \n") - fp.write(" va_start(ap, format);\n") - fp.write(" ret = vasprintf(&ptr,format,ap);\n") - fp.write(" va_end(ap);\n") - fp.write("\n") - fp.write(" if (screen) {\n") - fp.write(" d_printf(\"%s\", ptr ? ptr : \"\");\n") - fp.write(" } else {\n") - fp.write(" DEBUG(4,(\"%s\", ptr ? ptr : \"\"));\n") - fp.write(" }\n") - fp.write(" \n") - fp.write(" SAFE_FREE(ptr);\n") - fp.write(" return ret;\n") - fp.write("}\n") - fp.write("\n") - fp.write("/****************************************************************************\n") - fp.write("options set at build time for the samba suite\n") - fp.write("****************************************************************************/\n") - fp.write("void build_options(bool screen)\n") - fp.write("{\n") - fp.write(" if ((DEBUGLEVEL < 4) && (!screen)) {\n") - fp.write(" return;\n") - fp.write(" }\n") - fp.write("\n") - fp.write("\n") - fp.write(" /* Output various paths to files and directories */\n") - fp.write(" output(screen,\"\\nPaths:\\n\");\n") - fp.write(" output(screen,\" SBINDIR: %s\\n\", get_dyn_SBINDIR());\n") - fp.write(" output(screen,\" BINDIR: %s\\n\", get_dyn_BINDIR());\n") - fp.write(" output(screen,\" CONFIGFILE: %s\\n\", get_dyn_CONFIGFILE());\n") - fp.write(" output(screen,\" LOGFILEBASE: %s\\n\", get_dyn_LOGFILEBASE());\n") - fp.write(" output(screen,\" LMHOSTSFILE: %s\\n\",get_dyn_LMHOSTSFILE());\n") - fp.write(" output(screen,\" LIBDIR: %s\\n\",get_dyn_LIBDIR());\n") - fp.write(" output(screen,\" MODULESDIR: %s\\n\",get_dyn_MODULESDIR());\n") - fp.write(" output(screen,\" SHLIBEXT: %s\\n\",get_dyn_SHLIBEXT());\n") - fp.write(" output(screen,\" LOCKDIR: %s\\n\",get_dyn_LOCKDIR());\n") - fp.write(" output(screen,\" STATEDIR: %s\\n\",get_dyn_STATEDIR());\n") - fp.write(" output(screen,\" CACHEDIR: %s\\n\",get_dyn_CACHEDIR());\n") - fp.write(" output(screen,\" PIDDIR: %s\\n\", get_dyn_PIDDIR());\n") - fp.write(" output(screen,\" SMB_PASSWD_FILE: %s\\n\",get_dyn_SMB_PASSWD_FILE());\n") - fp.write(" output(screen,\" PRIVATE_DIR: %s\\n\",get_dyn_PRIVATE_DIR());\n") - fp.write(" output(screen,\" BINDDNS_DIR: %s\\n\",get_dyn_BINDDNS_DIR());\n") - fp.write("\n") - -def write_build_options_footer(fp): - fp.write(" /* Output the sizes of the various cluster features */\n") - fp.write(" output(screen, \"\\n%s\", cluster_support_features());\n") - fp.write("\n") - fp.write(" /* Output the sizes of the various types */\n") - fp.write(" output(screen, \"\\nType sizes:\\n\");\n") - fp.write(" output(screen, \" sizeof(char): %lu\\n\",(unsigned long)sizeof(char));\n") - fp.write(" output(screen, \" sizeof(int): %lu\\n\",(unsigned long)sizeof(int));\n") - fp.write(" output(screen, \" sizeof(long): %lu\\n\",(unsigned long)sizeof(long));\n") - fp.write(" output(screen, \" sizeof(long long): %lu\\n\",(unsigned long)sizeof(long long));\n") - fp.write(" output(screen, \" sizeof(uint8_t): %lu\\n\",(unsigned long)sizeof(uint8_t));\n") - fp.write(" output(screen, \" sizeof(uint16_t): %lu\\n\",(unsigned long)sizeof(uint16_t));\n") - fp.write(" output(screen, \" sizeof(uint32_t): %lu\\n\",(unsigned long)sizeof(uint32_t));\n") - fp.write(" output(screen, \" sizeof(short): %lu\\n\",(unsigned long)sizeof(short));\n") - fp.write(" output(screen, \" sizeof(void*): %lu\\n\",(unsigned long)sizeof(void*));\n") - fp.write(" output(screen, \" sizeof(size_t): %lu\\n\",(unsigned long)sizeof(size_t));\n") - fp.write(" output(screen, \" sizeof(off_t): %lu\\n\",(unsigned long)sizeof(off_t));\n") - fp.write(" output(screen, \" sizeof(ino_t): %lu\\n\",(unsigned long)sizeof(ino_t));\n") - fp.write(" output(screen, \" sizeof(dev_t): %lu\\n\",(unsigned long)sizeof(dev_t));\n") - fp.write("\n") - fp.write(" output(screen, \"\\nBuiltin modules:\\n\");\n") - fp.write(" output(screen, \" %s\\n\", STRING_STATIC_MODULES);\n") - fp.write("}\n") - -def write_build_options_section(fp, keys, section): - fp.write("\n\t/* Show %s */\n" % section) - fp.write(" output(screen, \"\\n%s:\\n\");\n\n" % section) - - for k in sorted(keys): - fp.write("#ifdef %s\n" % k) - fp.write(" output(screen, \" %s\\n\");\n" % k) - fp.write("#endif\n") - fp.write("\n") - -def write_build_options(task): - tbl = task.env - keys_option_with = [] - keys_option_utmp = [] - keys_option_have = [] - keys_header_sys = [] - keys_header_other = [] - keys_misc = [] - if sys.hexversion>0x300000f: - trans_table = bytes.maketrans(b'.-()', b'____') - else: - import string - trans_table = string.maketrans('.-()', '____') - - for key in tbl: - if key.startswith("HAVE_UT_UT_") or key.find("UTMP") >= 0: - keys_option_utmp.append(key) - elif key.startswith("WITH_"): - keys_option_with.append(key) - elif key.startswith("HAVE_SYS_"): - keys_header_sys.append(key) - elif key.startswith("HAVE_"): - if key.endswith("_H"): - keys_header_other.append(key) - else: - keys_option_have.append(key) - elif key.startswith("static_init_"): - l = key.split("(") - keys_misc.append(l[0]) - else: - keys_misc.append(key.translate(trans_table)) - - tgt = task.outputs[0].bldpath(task.env) - f = open(tgt, 'w') - write_build_options_header(f) - write_build_options_section(f, keys_header_sys, "System Headers") - write_build_options_section(f, keys_header_other, "Headers") - write_build_options_section(f, keys_option_utmp, "UTMP Options") - write_build_options_section(f, keys_option_have, "HAVE_* Defines") - write_build_options_section(f, keys_option_with, "--with Options") - write_build_options_section(f, keys_misc, "Build Options") - write_build_options_footer(f) - f.close() - return 0 - - -def SAMBA_BLDOPTIONS(bld, target): - '''generate the bld_options.c for Samba''' - t = bld.SAMBA_GENERATOR(target, - rule=write_build_options, - dep_vars=['defines'], - target=target) -Build.BuildContext.SAMBA_BLDOPTIONS = SAMBA_BLDOPTIONS diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_perl.py b/ldb-2.0.8/buildtools/wafsamba/samba_perl.py deleted file mode 100644 index e019acb..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/samba_perl.py +++ /dev/null @@ -1,59 +0,0 @@ -from waflib import Utils -from waflib.Configure import conf -from samba_utils import get_string -done = {} - -@conf -def SAMBA_CHECK_PERL(conf, mandatory=True, version=(5,0,0)): - if "done" in done: - return - done["done"] = True - conf.find_program('perl', var='PERL', mandatory=mandatory) - conf.load('perl') - path_perl = conf.find_program('perl') - conf.env.PERL_SPECIFIED = (conf.env.PERL != path_perl) - conf.check_perl_version(version) - - def read_perl_config_var(cmd): - output = Utils.cmd_output([conf.env.get_flat('PERL'), '-MConfig', '-e', cmd]) - if not isinstance(output, str): - output = get_string(output) - return Utils.to_list(output) - - def check_perl_config_var(var): - conf.start_msg("Checking for perl $Config{%s}:" % var) - try: - v = read_perl_config_var('print $Config{%s}' % var)[0] - conf.end_msg("'%s'" % (v), 'GREEN') - return v - except IndexError: - conf.end_msg(False, 'YELLOW') - pass - return None - - vendor_prefix = check_perl_config_var('vendorprefix') - - perl_arch_install_dir = None - if vendor_prefix == conf.env.PREFIX: - perl_arch_install_dir = check_perl_config_var('vendorarch'); - if perl_arch_install_dir is None: - perl_arch_install_dir = "${LIBDIR}/perl5"; - conf.start_msg("PERL_ARCH_INSTALL_DIR: ") - conf.end_msg("'%s'" % (perl_arch_install_dir), 'GREEN') - conf.env.PERL_ARCH_INSTALL_DIR = perl_arch_install_dir - - perl_lib_install_dir = None - if vendor_prefix == conf.env.PREFIX: - perl_lib_install_dir = check_perl_config_var('vendorlib'); - if perl_lib_install_dir is None: - perl_lib_install_dir = "${DATADIR}/perl5"; - conf.start_msg("PERL_LIB_INSTALL_DIR: ") - conf.end_msg("'%s'" % (perl_lib_install_dir), 'GREEN') - conf.env.PERL_LIB_INSTALL_DIR = perl_lib_install_dir - - perl_inc = read_perl_config_var('print "@INC"') - if '.' in perl_inc: - perl_inc.remove('.') - conf.start_msg("PERL_INC: ") - conf.end_msg("%s" % (perl_inc), 'GREEN') - conf.env.PERL_INC = perl_inc diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_pidl.py b/ldb-2.0.8/buildtools/wafsamba/samba_pidl.py deleted file mode 100644 index 3fecfa9..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/samba_pidl.py +++ /dev/null @@ -1,150 +0,0 @@ -# waf build tool for building IDL files with pidl - -import os -from waflib import Build, Utils -from waflib.TaskGen import feature, before -from samba_utils import SET_TARGET_TYPE, TO_LIST, LOCAL_CACHE - -def SAMBA_PIDL(bld, pname, source, - options='', - output_dir='.', - generate_tables=True): - '''Build a IDL file using pidl. - This will produce up to 13 output files depending on the options used''' - - bname = source[0:-4]; # strip off the .idl suffix - bname = os.path.basename(bname) - name = "%s_%s" % (pname, bname.upper()) - - if not SET_TARGET_TYPE(bld, name, 'PIDL'): - return - - bld.SET_BUILD_GROUP('build_source') - - # the output files depend on the options used. Use this dictionary - # to map between the options and the resulting file names - options_map = { '--header' : '%s.h', - '--ndr-parser' : 'ndr_%s.c ndr_%s.h', - '--samba3-ndr-server' : 'srv_%s.c srv_%s.h', - '--samba3-ndr-client' : 'cli_%s.c cli_%s.h', - '--server' : 'ndr_%s_s.c', - '--client' : 'ndr_%s_c.c ndr_%s_c.h', - '--python' : 'py_%s.c', - '--tdr-parser' : 'tdr_%s.c tdr_%s.h', - '--dcom-proxy' : '%s_p.c', - '--com-header' : 'com_%s.h' - } - - table_header_idx = None - out_files = [] - options_list = TO_LIST(options) - - for o in options_list: - if o in options_map: - ofiles = TO_LIST(options_map[o]) - for f in ofiles: - out_files.append(os.path.join(output_dir, f % bname)) - if f == 'ndr_%s.h': - # remember this one for the tables generation - table_header_idx = len(out_files) - 1 - - # depend on the full pidl sources - source = TO_LIST(source) - try: - pidl_src_nodes = bld.pidl_files_cache - except AttributeError: - bld.pidl_files_cache = bld.srcnode.ant_glob('pidl/lib/Parse/**/*.pm', flat=False) - bld.pidl_files_cache.extend(bld.srcnode.ant_glob('pidl', flat=False)) - pidl_src_nodes = bld.pidl_files_cache - - # the cd .. is needed because pidl currently is sensitive to the directory it is run in - cpp = "" - cc = "" - if bld.CONFIG_SET("CPP") and bld.CONFIG_GET("CPP") != "": - if isinstance(bld.CONFIG_GET("CPP"), list): - cpp = 'CPP="%s"' % " ".join(bld.CONFIG_GET("CPP")) - else: - cpp = 'CPP="%s"' % bld.CONFIG_GET("CPP") - - if cpp == "CPP=xlc_r": - cpp = "" - - - if bld.CONFIG_SET("CC"): - if isinstance(bld.CONFIG_GET("CC"), list): - cc = 'CC="%s"' % " ".join(bld.CONFIG_GET("CC")) - else: - cc = 'CC="%s"' % bld.CONFIG_GET("CC") - - t = bld(rule='cd ${PIDL_LAUNCH_DIR} && %s %s ${PERL} ${PIDL} --quiet ${OPTIONS} --outputdir ${OUTPUTDIR} -- "${IDLSRC}"' % (cpp, cc), - ext_out = '.c', - before = 'c', - update_outputs = True, - shell = True, - source = source, - target = out_files, - name = name, - samba_type = 'PIDL') - - - t.env.PIDL_LAUNCH_DIR = bld.srcnode.path_from(bld.bldnode) - pnode = bld.srcnode.find_resource('pidl/pidl') - t.env.PIDL = pnode.path_from(bld.srcnode) - t.env.OPTIONS = TO_LIST(options) - snode = t.path.find_resource(source[0]) - t.env.IDLSRC = snode.path_from(bld.srcnode) - t.env.OUTPUTDIR = bld.bldnode.path_from(bld.srcnode) + '/' + bld.path.find_dir(output_dir).path_from(bld.srcnode) - - bld.add_manual_dependency(snode, pidl_src_nodes) - - if generate_tables and table_header_idx is not None: - pidl_headers = LOCAL_CACHE(bld, 'PIDL_HEADERS') - pidl_headers[name] = [bld.path.find_or_declare(out_files[table_header_idx])] - - t.more_includes = '#' + bld.path.path_from(bld.srcnode) -Build.BuildContext.SAMBA_PIDL = SAMBA_PIDL - - -def SAMBA_PIDL_LIST(bld, name, source, - options='', - output_dir='.', - generate_tables=True): - '''A wrapper for building a set of IDL files''' - for p in TO_LIST(source): - bld.SAMBA_PIDL(name, p, options=options, output_dir=output_dir, generate_tables=generate_tables) -Build.BuildContext.SAMBA_PIDL_LIST = SAMBA_PIDL_LIST - - -################################################################# -# the rule for generating the NDR tables -@feature('collect') -@before('exec_rule') -def collect(self): - pidl_headers = LOCAL_CACHE(self.bld, 'PIDL_HEADERS') - # The first source is tables.pl itself - self.source = Utils.to_list(self.source) - for (name, hd) in pidl_headers.items(): - y = self.bld.get_tgen_by_name(name) - self.bld.ASSERT(y is not None, 'Failed to find PIDL header %s' % name) - y.post() - for node in hd: - self.bld.ASSERT(node is not None, 'Got None as build node generating PIDL table for %s' % name) - self.source.append(node) - - -def SAMBA_PIDL_TABLES(bld, name, target): - '''generate the pidl NDR tables file''' - bld.SET_BUILD_GROUP('main') - t = bld( - features = 'collect', - rule = '${PERL} ${SRC} > ${TGT}', - ext_out = '.c', - before = 'c', - update_outputs = True, - shell = True, - source = '../../librpc/tables.pl', - target = target, - name = name) - t.env.LIBRPC = os.path.join(bld.srcnode.abspath(), 'librpc') -Build.BuildContext.SAMBA_PIDL_TABLES = SAMBA_PIDL_TABLES - diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_python.py b/ldb-2.0.8/buildtools/wafsamba/samba_python.py deleted file mode 100644 index 4476d33..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/samba_python.py +++ /dev/null @@ -1,159 +0,0 @@ -# waf build tool for building IDL files with pidl - -import os, sys -from waflib import Build, Logs, Utils, Configure, Errors -from waflib.Configure import conf - -@conf -def SAMBA_CHECK_PYTHON(conf, version=(3,4,0)): - - if conf.env.disable_python: - version=(2,6,0) - - # enable tool to build python extensions - if conf.env.HAVE_PYTHON_H: - conf.check_python_version(version) - return - - interpreters = [] - - conf.find_program('python3', var='PYTHON', - mandatory=not conf.env.disable_python) - conf.load('python') - path_python = conf.find_program('python3') - - conf.env.PYTHON_SPECIFIED = (conf.env.PYTHON != path_python) - conf.check_python_version(version) - - interpreters.append(conf.env['PYTHON']) - conf.env.python_interpreters = interpreters - - -@conf -def SAMBA_CHECK_PYTHON_HEADERS(conf): - if conf.env.disable_python: - - conf.msg("python headers", "Check disabled due to --disable-python") - # we don't want PYTHONDIR in config.h, as otherwise changing - # --prefix causes a complete rebuild - conf.env.DEFINES = [x for x in conf.env.DEFINES - if not x.startswith('PYTHONDIR=') - and not x.startswith('PYTHONARCHDIR=')] - - return - - if conf.env["python_headers_checked"] == []: - _check_python_headers(conf) - conf.env["python_headers_checked"] = "yes" - - else: - conf.msg("python headers", "using cache") - - # we don't want PYTHONDIR in config.h, as otherwise changing - # --prefix causes a complete rebuild - conf.env.DEFINES = [x for x in conf.env.DEFINES - if not x.startswith('PYTHONDIR=') - and not x.startswith('PYTHONARCHDIR=')] - -def _check_python_headers(conf): - conf.check_python_headers() - - if conf.env['PYTHON_VERSION'] > '3': - abi_pattern = os.path.splitext(conf.env['pyext_PATTERN'])[0] - conf.env['PYTHON_SO_ABI_FLAG'] = abi_pattern % '' - else: - conf.env['PYTHON_SO_ABI_FLAG'] = '' - conf.env['PYTHON_LIBNAME_SO_ABI_FLAG'] = ( - conf.env['PYTHON_SO_ABI_FLAG'].replace('_', '-')) - - for lib in conf.env['LINKFLAGS_PYEMBED']: - if lib.startswith('-L'): - conf.env.append_unique('LIBPATH_PYEMBED', lib[2:]) # strip '-L' - conf.env['LINKFLAGS_PYEMBED'].remove(lib) - - # same as in waf 1.5, keep only '-fno-strict-aliasing' - # and ignore defines such as NDEBUG _FORTIFY_SOURCE=2 - conf.env.DEFINES_PYEXT = [] - conf.env.CFLAGS_PYEXT = ['-fno-strict-aliasing'] - - return - -def PYTHON_BUILD_IS_ENABLED(self): - return self.CONFIG_SET('HAVE_PYTHON_H') - -Build.BuildContext.PYTHON_BUILD_IS_ENABLED = PYTHON_BUILD_IS_ENABLED - - -def SAMBA_PYTHON(bld, name, - source='', - deps='', - public_deps='', - realname=None, - cflags='', - cflags_end=None, - includes='', - init_function_sentinel=None, - local_include=True, - vars=None, - install=True, - enabled=True): - '''build a python extension for Samba''' - - # force-disable when we can't build python modules, so - # every single call doesn't need to pass this in. - if not bld.PYTHON_BUILD_IS_ENABLED(): - enabled = False - - # when we support static python modules we'll need to gather - # the list from all the SAMBA_PYTHON() targets - if init_function_sentinel is not None: - cflags += ' -DSTATIC_LIBPYTHON_MODULES=%s' % init_function_sentinel - - # From https://docs.python.org/2/c-api/arg.html: - # Starting with Python 2.5 the type of the length argument to - # PyArg_ParseTuple(), PyArg_ParseTupleAndKeywords() and PyArg_Parse() - # can be controlled by defining the macro PY_SSIZE_T_CLEAN before - # including Python.h. If the macro is defined, length is a Py_ssize_t - # rather than an int. - - # Because if often included before includes.h/config.h - # This must be in the -D compiler options - cflags += ' -DPY_SSIZE_T_CLEAN=1' - - source = bld.EXPAND_VARIABLES(source, vars=vars) - - if realname is not None: - link_name = 'python/%s' % realname - else: - link_name = None - - bld.SAMBA_LIBRARY(name, - source=source, - deps=deps, - public_deps=public_deps, - includes=includes, - cflags=cflags, - cflags_end=cflags_end, - local_include=local_include, - vars=vars, - realname=realname, - link_name=link_name, - pyext=True, - target_type='PYTHON', - install_path='${PYTHONARCHDIR}', - allow_undefined_symbols=True, - install=install, - enabled=enabled) - -Build.BuildContext.SAMBA_PYTHON = SAMBA_PYTHON - - -def pyembed_libname(bld, name): - if bld.env['PYTHON_SO_ABI_FLAG']: - return name + bld.env['PYTHON_SO_ABI_FLAG'] - else: - return name - -Build.BuildContext.pyembed_libname = pyembed_libname - - diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_third_party.py b/ldb-2.0.8/buildtools/wafsamba/samba_third_party.py deleted file mode 100644 index f7410ec..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/samba_third_party.py +++ /dev/null @@ -1,66 +0,0 @@ -# functions to support third party libraries - -import os -from waflib import Utils, Build, Context -from waflib.Configure import conf - -@conf -def CHECK_FOR_THIRD_PARTY(conf): - return os.path.exists(os.path.join(Context.g_module.top, 'third_party')) - -Build.BuildContext.CHECK_FOR_THIRD_PARTY = CHECK_FOR_THIRD_PARTY - -@conf -def CHECK_ZLIB(conf): - version_check=''' - #if (ZLIB_VERNUM >= 0x1230) - #else - #error "ZLIB_VERNUM < 0x1230" - #endif - z_stream *z; - inflateInit2(z, -15); - ''' - return conf.CHECK_BUNDLED_SYSTEM('z', minversion='1.2.3', pkg='zlib', - checkfunctions='zlibVersion', - headers='zlib.h', - checkcode=version_check, - implied_deps='replace') - -Build.BuildContext.CHECK_ZLIB = CHECK_ZLIB - -@conf -def CHECK_POPT(conf): - return conf.CHECK_BUNDLED_SYSTEM('popt', checkfunctions='poptGetContext', headers='popt.h') - -Build.BuildContext.CHECK_POPT = CHECK_POPT - -@conf -def CHECK_CMOCKA(conf): - return conf.CHECK_BUNDLED_SYSTEM_PKG('cmocka', minversion='1.1.3') - -Build.BuildContext.CHECK_CMOCKA = CHECK_CMOCKA - -@conf -def CHECK_SOCKET_WRAPPER(conf): - return conf.CHECK_BUNDLED_SYSTEM_PKG('socket_wrapper', minversion='1.2.3') -Build.BuildContext.CHECK_SOCKET_WRAPPER = CHECK_SOCKET_WRAPPER - -@conf -def CHECK_NSS_WRAPPER(conf): - return conf.CHECK_BUNDLED_SYSTEM_PKG('nss_wrapper', minversion='1.1.6') -Build.BuildContext.CHECK_NSS_WRAPPER = CHECK_NSS_WRAPPER - -@conf -def CHECK_RESOLV_WRAPPER(conf): - return conf.CHECK_BUNDLED_SYSTEM_PKG('resolv_wrapper', minversion='1.1.4') -Build.BuildContext.CHECK_RESOLV_WRAPPER = CHECK_RESOLV_WRAPPER - -@conf -def CHECK_UID_WRAPPER(conf): - return conf.CHECK_BUNDLED_SYSTEM_PKG('uid_wrapper', minversion='1.2.4') -Build.BuildContext.CHECK_UID_WRAPPER = CHECK_UID_WRAPPER - -@conf -def CHECK_PAM_WRAPPER(conf): - return conf.CHECK_BUNDLED_SYSTEM_PKG('pam_wrapper', minversion='1.0.7') -Build.BuildContext.CHECK_PAM_WRAPPER = CHECK_PAM_WRAPPER diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_utils.py b/ldb-2.0.8/buildtools/wafsamba/samba_utils.py deleted file mode 100644 index ad97de1..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/samba_utils.py +++ /dev/null @@ -1,763 +0,0 @@ -# a waf tool to add autoconf-like macros to the configure section -# and for SAMBA_ macros for building libraries, binaries etc - -import errno -import os, sys, re, fnmatch, shlex, inspect -from optparse import SUPPRESS_HELP -from waflib import Build, Options, Utils, Task, Logs, Configure, Errors, Context -from waflib import Scripting -from waflib.TaskGen import feature, before, after -from waflib.Configure import ConfigurationContext -from waflib.Logs import debug -from waflib import ConfigSet -from waflib.Build import CACHE_SUFFIX - -# TODO: make this a --option -LIB_PATH="shared" - - -PY3 = sys.version_info[0] == 3 - -if PY3: - - # helper function to get a string from a variable that maybe 'str' or - # 'bytes' if 'bytes' then it is decoded using 'utf8'. If 'str' is passed - # it is returned unchanged - # Using this function is PY2/PY3 code should ensure in most cases - # the PY2 code runs unchanged in PY2 whereas the code in PY3 possibly - # decodes the variable (see PY2 implementation of this function below) - def get_string(bytesorstring): - tmp = bytesorstring - if isinstance(bytesorstring, bytes): - tmp = bytesorstring.decode('utf8') - elif not isinstance(bytesorstring, str): - raise ValueError('Expected byte of string for %s:%s' % (type(bytesorstring), bytesorstring)) - return tmp - -else: - - # Helper function to return string. - # if 'str' or 'unicode' passed in they are returned unchanged - # otherwise an exception is generated - # Using this function is PY2/PY3 code should ensure in most cases - # the PY2 code runs unchanged in PY2 whereas the code in PY3 possibly - # decodes the variable (see PY3 implementation of this function above) - def get_string(bytesorstring): - tmp = bytesorstring - if not(isinstance(bytesorstring, str) or isinstance(bytesorstring, unicode)): - raise ValueError('Expected str or unicode for %s:%s' % (type(bytesorstring), bytesorstring)) - return tmp - -# sigh, python octal constants are a mess -MODE_644 = int('644', 8) -MODE_744 = int('744', 8) -MODE_755 = int('755', 8) -MODE_777 = int('777', 8) - -def conf(f): - # override in order to propagate the argument "mandatory" - def fun(*k, **kw): - mandatory = True - if 'mandatory' in kw: - mandatory = kw['mandatory'] - del kw['mandatory'] - - try: - return f(*k, **kw) - except Errors.ConfigurationError: - if mandatory: - raise - - fun.__name__ = f.__name__ - if 'mandatory' in inspect.getsource(f): - fun = f - - setattr(Configure.ConfigurationContext, f.__name__, fun) - setattr(Build.BuildContext, f.__name__, fun) - return f -Configure.conf = conf -Configure.conftest = conf - -@conf -def SET_TARGET_TYPE(ctx, target, value): - '''set the target type of a target''' - cache = LOCAL_CACHE(ctx, 'TARGET_TYPE') - if target in cache and cache[target] != 'EMPTY': - Logs.error("ERROR: Target '%s' in directory %s re-defined as %s - was %s" % (target, ctx.path.abspath(), value, cache[target])) - sys.exit(1) - LOCAL_CACHE_SET(ctx, 'TARGET_TYPE', target, value) - debug("task_gen: Target '%s' created of type '%s' in %s" % (target, value, ctx.path.abspath())) - return True - - -def GET_TARGET_TYPE(ctx, target): - '''get target type from cache''' - cache = LOCAL_CACHE(ctx, 'TARGET_TYPE') - if not target in cache: - return None - return cache[target] - - -def ADD_LD_LIBRARY_PATH(path): - '''add something to LD_LIBRARY_PATH''' - if 'LD_LIBRARY_PATH' in os.environ: - oldpath = os.environ['LD_LIBRARY_PATH'] - else: - oldpath = '' - newpath = oldpath.split(':') - if not path in newpath: - newpath.append(path) - os.environ['LD_LIBRARY_PATH'] = ':'.join(newpath) - - -def needs_private_lib(bld, target): - '''return True if a target links to a private library''' - for lib in getattr(target, "final_libs", []): - t = bld.get_tgen_by_name(lib) - if t and getattr(t, 'private_library', False): - return True - return False - - -def install_rpath(target): - '''the rpath value for installation''' - bld = target.bld - bld.env['RPATH'] = [] - ret = set() - if bld.env.RPATH_ON_INSTALL: - ret.add(bld.EXPAND_VARIABLES(bld.env.LIBDIR)) - if bld.env.RPATH_ON_INSTALL_PRIVATE and needs_private_lib(bld, target): - ret.add(bld.EXPAND_VARIABLES(bld.env.PRIVATELIBDIR)) - return list(ret) - - -def build_rpath(bld): - '''the rpath value for build''' - rpaths = [os.path.normpath('%s/%s' % (bld.env.BUILD_DIRECTORY, d)) for d in ("shared", "shared/private")] - bld.env['RPATH'] = [] - if bld.env.RPATH_ON_BUILD: - return rpaths - for rpath in rpaths: - ADD_LD_LIBRARY_PATH(rpath) - return [] - - -@conf -def LOCAL_CACHE(ctx, name): - '''return a named build cache dictionary, used to store - state inside other functions''' - if name in ctx.env: - return ctx.env[name] - ctx.env[name] = {} - return ctx.env[name] - - -@conf -def LOCAL_CACHE_SET(ctx, cachename, key, value): - '''set a value in a local cache''' - cache = LOCAL_CACHE(ctx, cachename) - cache[key] = value - - -@conf -def ASSERT(ctx, expression, msg): - '''a build assert call''' - if not expression: - raise Errors.WafError("ERROR: %s\n" % msg) -Build.BuildContext.ASSERT = ASSERT - - -def SUBDIR(bld, subdir, list): - '''create a list of files by pre-pending each with a subdir name''' - ret = '' - for l in TO_LIST(list): - ret = ret + os.path.normpath(os.path.join(subdir, l)) + ' ' - return ret -Build.BuildContext.SUBDIR = SUBDIR - - -def dict_concat(d1, d2): - '''concatenate two dictionaries d1 += d2''' - for t in d2: - if t not in d1: - d1[t] = d2[t] - -def ADD_COMMAND(opt, name, function): - '''add a new top level command to waf''' - Context.g_module.__dict__[name] = function - opt.name = function -Options.OptionsContext.ADD_COMMAND = ADD_COMMAND - - -@feature('c', 'cc', 'cshlib', 'cprogram') -@before('apply_core','exec_rule') -def process_depends_on(self): - '''The new depends_on attribute for build rules - allow us to specify a dependency on output from - a source generation rule''' - if getattr(self , 'depends_on', None): - lst = self.to_list(self.depends_on) - for x in lst: - y = self.bld.get_tgen_by_name(x) - self.bld.ASSERT(y is not None, "Failed to find dependency %s of %s" % (x, self.name)) - y.post() - if getattr(y, 'more_includes', None): - self.includes += " " + y.more_includes - - -os_path_relpath = getattr(os.path, 'relpath', None) -if os_path_relpath is None: - # Python < 2.6 does not have os.path.relpath, provide a replacement - # (imported from Python2.6.5~rc2) - def os_path_relpath(path, start): - """Return a relative version of a path""" - start_list = os.path.abspath(start).split("/") - path_list = os.path.abspath(path).split("/") - - # Work out how much of the filepath is shared by start and path. - i = len(os.path.commonprefix([start_list, path_list])) - - rel_list = ['..'] * (len(start_list)-i) + path_list[i:] - if not rel_list: - return start - return os.path.join(*rel_list) - - -def unique_list(seq): - '''return a uniquified list in the same order as the existing list''' - seen = {} - result = [] - for item in seq: - if item in seen: continue - seen[item] = True - result.append(item) - return result - - -def TO_LIST(str, delimiter=None): - '''Split a list, preserving quoted strings and existing lists''' - if str is None: - return [] - if isinstance(str, list): - # we need to return a new independent list... - return list(str) - if len(str) == 0: - return [] - lst = str.split(delimiter) - # the string may have had quotes in it, now we - # check if we did have quotes, and use the slower shlex - # if we need to - for e in lst: - if e[0] == '"': - return shlex.split(str) - return lst - - -def subst_vars_error(string, env): - '''substitute vars, throw an error if a variable is not defined''' - lst = re.split('(\$\{\w+\})', string) - out = [] - for v in lst: - if re.match('\$\{\w+\}', v): - vname = v[2:-1] - if not vname in env: - raise KeyError("Failed to find variable %s in %s in env %s <%s>" % (vname, string, env.__class__, str(env))) - v = env[vname] - if isinstance(v, list): - v = ' '.join(v) - out.append(v) - return ''.join(out) - - -@conf -def SUBST_ENV_VAR(ctx, varname): - '''Substitute an environment variable for any embedded variables''' - return subst_vars_error(ctx.env[varname], ctx.env) -Build.BuildContext.SUBST_ENV_VAR = SUBST_ENV_VAR - - -def recursive_dirlist(dir, relbase, pattern=None): - '''recursive directory list''' - ret = [] - for f in os.listdir(dir): - f2 = dir + '/' + f - if os.path.isdir(f2): - ret.extend(recursive_dirlist(f2, relbase)) - else: - if pattern and not fnmatch.fnmatch(f, pattern): - continue - ret.append(os_path_relpath(f2, relbase)) - return ret - - -def symlink(src, dst, force=True): - """Can create symlink by force""" - try: - os.symlink(src, dst) - except OSError as exc: - if exc.errno == errno.EEXIST and force: - os.remove(dst) - os.symlink(src, dst) - else: - raise - - -def mkdir_p(dir): - '''like mkdir -p''' - if not dir: - return - if dir.endswith("/"): - mkdir_p(dir[:-1]) - return - if os.path.isdir(dir): - return - mkdir_p(os.path.dirname(dir)) - os.mkdir(dir) - - -def SUBST_VARS_RECURSIVE(string, env): - '''recursively expand variables''' - if string is None: - return string - limit=100 - while (string.find('${') != -1 and limit > 0): - string = subst_vars_error(string, env) - limit -= 1 - return string - - -@conf -def EXPAND_VARIABLES(ctx, varstr, vars=None): - '''expand variables from a user supplied dictionary - - This is most useful when you pass vars=locals() to expand - all your local variables in strings - ''' - - if isinstance(varstr, list): - ret = [] - for s in varstr: - ret.append(EXPAND_VARIABLES(ctx, s, vars=vars)) - return ret - - if not isinstance(varstr, str): - return varstr - - env = ConfigSet.ConfigSet() - ret = varstr - # substitute on user supplied dict if avaiilable - if vars is not None: - for v in vars.keys(): - env[v] = vars[v] - ret = SUBST_VARS_RECURSIVE(ret, env) - - # if anything left, subst on the environment as well - if ret.find('${') != -1: - ret = SUBST_VARS_RECURSIVE(ret, ctx.env) - # make sure there is nothing left. Also check for the common - # typo of $( instead of ${ - if ret.find('${') != -1 or ret.find('$(') != -1: - Logs.error('Failed to substitute all variables in varstr=%s' % ret) - sys.exit(1) - return ret -Build.BuildContext.EXPAND_VARIABLES = EXPAND_VARIABLES - - -def RUN_COMMAND(cmd, - env=None, - shell=False): - '''run a external command, return exit code or signal''' - if env: - cmd = SUBST_VARS_RECURSIVE(cmd, env) - - status = os.system(cmd) - if os.WIFEXITED(status): - return os.WEXITSTATUS(status) - if os.WIFSIGNALED(status): - return - os.WTERMSIG(status) - Logs.error("Unknown exit reason %d for command: %s" % (status, cmd)) - return -1 - - -def RUN_PYTHON_TESTS(testfiles, pythonpath=None, extra_env=None): - env = LOAD_ENVIRONMENT() - if pythonpath is None: - pythonpath = os.path.join(Context.g_module.out, 'python') - result = 0 - for interp in env.python_interpreters: - if not isinstance(interp, str): - interp = ' '.join(interp) - for testfile in testfiles: - cmd = "PYTHONPATH=%s %s %s" % (pythonpath, interp, testfile) - if extra_env: - for key, value in extra_env.items(): - cmd = "%s=%s %s" % (key, value, cmd) - print('Running Python test with %s: %s' % (interp, testfile)) - ret = RUN_COMMAND(cmd) - if ret: - print('Python test failed: %s' % cmd) - result = ret - return result - - -# make sure we have md5. some systems don't have it -try: - from hashlib import md5 - # Even if hashlib.md5 exists, it may be unusable. - # Try to use MD5 function. In FIPS mode this will cause an exception - # and we'll get to the replacement code - foo = md5(b'abcd') -except: - try: - import md5 - # repeat the same check here, mere success of import is not enough. - # Try to use MD5 function. In FIPS mode this will cause an exception - foo = md5.md5(b'abcd') - except: - Context.SIG_NIL = hash('abcd') - class replace_md5(object): - def __init__(self): - self.val = None - def update(self, val): - self.val = hash((self.val, val)) - def digest(self): - return str(self.val) - def hexdigest(self): - return self.digest().encode('hex') - def replace_h_file(filename): - f = open(filename, 'rb') - m = replace_md5() - while (filename): - filename = f.read(100000) - m.update(filename) - f.close() - return m.digest() - Utils.md5 = replace_md5 - Task.md5 = replace_md5 - Utils.h_file = replace_h_file - - -def LOAD_ENVIRONMENT(): - '''load the configuration environment, allowing access to env vars - from new commands''' - env = ConfigSet.ConfigSet() - try: - p = os.path.join(Context.g_module.out, 'c4che/default'+CACHE_SUFFIX) - env.load(p) - except (OSError, IOError): - pass - return env - - -def IS_NEWER(bld, file1, file2): - '''return True if file1 is newer than file2''' - curdir = bld.path.abspath() - t1 = os.stat(os.path.join(curdir, file1)).st_mtime - t2 = os.stat(os.path.join(curdir, file2)).st_mtime - return t1 > t2 -Build.BuildContext.IS_NEWER = IS_NEWER - - -@conf -def RECURSE(ctx, directory): - '''recurse into a directory, relative to the curdir or top level''' - try: - visited_dirs = ctx.visited_dirs - except AttributeError: - visited_dirs = ctx.visited_dirs = set() - d = os.path.join(ctx.path.abspath(), directory) - if os.path.exists(d): - abspath = os.path.abspath(d) - else: - abspath = os.path.abspath(os.path.join(Context.g_module.top, directory)) - ctxclass = ctx.__class__.__name__ - key = ctxclass + ':' + abspath - if key in visited_dirs: - # already done it - return - visited_dirs.add(key) - relpath = os_path_relpath(abspath, ctx.path.abspath()) - if ctxclass in ['tmp', 'OptionsContext', 'ConfigurationContext', 'BuildContext']: - return ctx.recurse(relpath) - if 'waflib.extras.compat15' in sys.modules: - return ctx.recurse(relpath) - Logs.error('Unknown RECURSE context class: {}'.format(ctxclass)) - raise -Options.OptionsContext.RECURSE = RECURSE -Build.BuildContext.RECURSE = RECURSE - - -def CHECK_MAKEFLAGS(options): - '''check for MAKEFLAGS environment variable in case we are being - called from a Makefile try to honor a few make command line flags''' - if not 'WAF_MAKE' in os.environ: - return - makeflags = os.environ.get('MAKEFLAGS') - if makeflags is None: - makeflags = "" - jobs_set = False - jobs = None - # we need to use shlex.split to cope with the escaping of spaces - # in makeflags - for opt in shlex.split(makeflags): - # options can come either as -x or as x - if opt[0:2] == 'V=': - options.verbose = Logs.verbose = int(opt[2:]) - if Logs.verbose > 0: - Logs.zones = ['runner'] - if Logs.verbose > 2: - Logs.zones = ['*'] - elif opt[0].isupper() and opt.find('=') != -1: - # this allows us to set waf options on the make command line - # for example, if you do "make FOO=blah", then we set the - # option 'FOO' in Options.options, to blah. If you look in wafsamba/wscript - # you will see that the command line accessible options have their dest= - # set to uppercase, to allow for passing of options from make in this way - # this is also how "make test TESTS=testpattern" works, and - # "make VERBOSE=1" as well as things like "make SYMBOLCHECK=1" - loc = opt.find('=') - setattr(options, opt[0:loc], opt[loc+1:]) - elif opt[0] != '-': - for v in opt: - if re.search(r'j[0-9]*$', v): - jobs_set = True - jobs = opt.strip('j') - elif v == 'k': - options.keep = True - elif re.search(r'-j[0-9]*$', opt): - jobs_set = True - jobs = opt.strip('-j') - elif opt == '-k': - options.keep = True - if not jobs_set: - # default to one job - options.jobs = 1 - elif jobs_set and jobs: - options.jobs = int(jobs) - -waflib_options_parse_cmd_args = Options.OptionsContext.parse_cmd_args -def wafsamba_options_parse_cmd_args(self, _args=None, cwd=None, allow_unknown=False): - (options, commands, envvars) = \ - waflib_options_parse_cmd_args(self, - _args=_args, - cwd=cwd, - allow_unknown=allow_unknown) - CHECK_MAKEFLAGS(options) - if options.jobs == 1: - # - # waflib.Runner.Parallel processes jobs inline if the possible number - # of jobs is just 1. But (at least in waf <= 2.0.12) it still calls - # create a waflib.Runner.Spawner() which creates a single - # waflib.Runner.Consumer() thread that tries to process jobs from the - # queue. - # - # This has strange effects, which are not noticed typically, - # but at least on AIX python has broken threading and fails - # in random ways. - # - # So we just add a dummy Spawner class. - class NoOpSpawner(object): - def __init__(self, master): - return - from waflib import Runner - Runner.Spawner = NoOpSpawner - return options, commands, envvars -Options.OptionsContext.parse_cmd_args = wafsamba_options_parse_cmd_args - -option_groups = {} - -def option_group(opt, name): - '''find or create an option group''' - global option_groups - if name in option_groups: - return option_groups[name] - gr = opt.add_option_group(name) - option_groups[name] = gr - return gr -Options.OptionsContext.option_group = option_group - - -def save_file(filename, contents, create_dir=False): - '''save data to a file''' - if create_dir: - mkdir_p(os.path.dirname(filename)) - try: - f = open(filename, 'w') - f.write(contents) - f.close() - except: - return False - return True - - -def load_file(filename): - '''return contents of a file''' - try: - f = open(filename, 'r') - r = f.read() - f.close() - except: - return None - return r - - -def reconfigure(ctx): - '''rerun configure if necessary''' - if not os.path.exists(os.environ.get('WAFLOCK', '.lock-wscript')): - raise Errors.WafError('configure has not been run') - import samba_wildcard - bld = samba_wildcard.fake_build_environment() - Configure.autoconfig = True - Scripting.check_configured(bld) - - -def map_shlib_extension(ctx, name, python=False): - '''map a filename with a shared library extension of .so to the real shlib name''' - if name is None: - return None - if name[-1:].isdigit(): - # some libraries have specified versions in the wscript rule - return name - (root1, ext1) = os.path.splitext(name) - if python: - return ctx.env.pyext_PATTERN % root1 - else: - (root2, ext2) = os.path.splitext(ctx.env.cshlib_PATTERN) - return root1+ext2 -Build.BuildContext.map_shlib_extension = map_shlib_extension - -def apply_pattern(filename, pattern): - '''apply a filename pattern to a filename that may have a directory component''' - dirname = os.path.dirname(filename) - if not dirname: - return pattern % filename - basename = os.path.basename(filename) - return os.path.join(dirname, pattern % basename) - -def make_libname(ctx, name, nolibprefix=False, version=None, python=False): - """make a library filename - Options: - nolibprefix: don't include the lib prefix - version : add a version number - python : if we should use python module name conventions""" - - if python: - libname = apply_pattern(name, ctx.env.pyext_PATTERN) - else: - libname = apply_pattern(name, ctx.env.cshlib_PATTERN) - if nolibprefix and libname[0:3] == 'lib': - libname = libname[3:] - if version: - if version[0] == '.': - version = version[1:] - (root, ext) = os.path.splitext(libname) - if ext == ".dylib": - # special case - version goes before the prefix - libname = "%s.%s%s" % (root, version, ext) - else: - libname = "%s%s.%s" % (root, ext, version) - return libname -Build.BuildContext.make_libname = make_libname - - -def get_tgt_list(bld): - '''return a list of build objects for samba''' - - targets = LOCAL_CACHE(bld, 'TARGET_TYPE') - - # build a list of task generators we are interested in - tgt_list = [] - for tgt in targets: - type = targets[tgt] - if not type in ['SUBSYSTEM', 'MODULE', 'BINARY', 'LIBRARY', 'ASN1', 'PYTHON']: - continue - t = bld.get_tgen_by_name(tgt) - if t is None: - Logs.error("Target %s of type %s has no task generator" % (tgt, type)) - sys.exit(1) - tgt_list.append(t) - return tgt_list - -from waflib.Context import WSCRIPT_FILE -def PROCESS_SEPARATE_RULE(self, rule): - ''' cause waf to process additional script based on `rule'. - You should have file named wscript__rule in the current directory - where stage is either 'configure' or 'build' - ''' - stage = '' - if isinstance(self, Configure.ConfigurationContext): - stage = 'configure' - elif isinstance(self, Build.BuildContext): - stage = 'build' - file_path = os.path.join(self.path.abspath(), WSCRIPT_FILE+'_'+stage+'_'+rule) - node = self.root.find_node(file_path) - if node: - try: - cache = self.recurse_cache - except AttributeError: - cache = self.recurse_cache = {} - if node not in cache: - cache[node] = True - self.pre_recurse(node) - try: - function_code = node.read('rU', None) - exec(compile(function_code, node.abspath(), 'exec'), self.exec_dict) - finally: - self.post_recurse(node) - -Build.BuildContext.PROCESS_SEPARATE_RULE = PROCESS_SEPARATE_RULE -ConfigurationContext.PROCESS_SEPARATE_RULE = PROCESS_SEPARATE_RULE - -def AD_DC_BUILD_IS_ENABLED(self): - if self.CONFIG_SET('AD_DC_BUILD_IS_ENABLED'): - return True - return False - -Build.BuildContext.AD_DC_BUILD_IS_ENABLED = AD_DC_BUILD_IS_ENABLED - -@feature('cprogram', 'cshlib', 'cstaticlib') -@after('apply_lib_vars') -@before('apply_obj_vars') -def samba_before_apply_obj_vars(self): - """before apply_obj_vars for uselib, this removes the standard paths""" - - def is_standard_libpath(env, path): - for _path in env.STANDARD_LIBPATH: - if _path == os.path.normpath(path): - return True - return False - - v = self.env - - for i in v['RPATH']: - if is_standard_libpath(v, i): - v['RPATH'].remove(i) - - for i in v['LIBPATH']: - if is_standard_libpath(v, i): - v['LIBPATH'].remove(i) - -def samba_add_onoff_option(opt, option, help=(), dest=None, default=True, - with_name="with", without_name="without"): - if default is None: - default_str = "auto" - elif default is True: - default_str = "yes" - elif default is False: - default_str = "no" - else: - default_str = str(default) - - if help == (): - help = ("Build with %s support (default=%s)" % (option, default_str)) - if dest is None: - dest = "with_%s" % option.replace('-', '_') - - with_val = "--%s-%s" % (with_name, option) - without_val = "--%s-%s" % (without_name, option) - - opt.add_option(with_val, help=help, action="store_true", dest=dest, - default=default) - opt.add_option(without_val, help=SUPPRESS_HELP, action="store_false", - dest=dest) -Options.OptionsContext.samba_add_onoff_option = samba_add_onoff_option diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_version.py b/ldb-2.0.8/buildtools/wafsamba/samba_version.py deleted file mode 100644 index f0e7b4d..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/samba_version.py +++ /dev/null @@ -1,267 +0,0 @@ -import os, sys -from waflib import Utils, Context -import samba_utils -from samba_git import find_git - -def git_version_summary(path, env=None): - git = find_git(env) - - if git is None: - return ("GIT-UNKNOWN", {}) - - env.GIT = git - - environ = dict(os.environ) - environ["GIT_DIR"] = '%s/.git' % path - environ["GIT_WORK_TREE"] = path - git = samba_utils.get_string(Utils.cmd_output(env.GIT + ' show --pretty=format:"%h%n%ct%n%H%n%cd" --stat HEAD', silent=True, env=environ)) - - lines = git.splitlines() - if not lines or len(lines) < 4: - return ("GIT-UNKNOWN", {}) - - fields = { - "GIT_COMMIT_ABBREV": lines[0], - "GIT_COMMIT_FULLREV": lines[2], - "COMMIT_TIME": int(lines[1]), - "COMMIT_DATE": lines[3], - } - - ret = "GIT-" + fields["GIT_COMMIT_ABBREV"] - - if env.GIT_LOCAL_CHANGES: - clean = Utils.cmd_output('%s diff HEAD | wc -l' % env.GIT, silent=True).strip() - if clean == "0": - fields["COMMIT_IS_CLEAN"] = 1 - else: - fields["COMMIT_IS_CLEAN"] = 0 - ret += "+" - - return (ret, fields) - - -def distversion_version_summary(path): - #get version from .distversion file - suffix = None - fields = {} - - for line in Utils.readf(path + '/.distversion').splitlines(): - if line == '': - continue - if line.startswith("#"): - continue - try: - split_line = line.split("=") - if split_line[1] != "": - key = split_line[0] - value = split_line[1] - if key == "SUFFIX": - suffix = value - continue - fields[key] = value - except: - print("Failed to parse line %s from .distversion file." % (line)) - raise - - if "COMMIT_TIME" in fields: - fields["COMMIT_TIME"] = int(fields["COMMIT_TIME"]) - - if suffix is None: - return ("UNKNOWN", fields) - - return (suffix, fields) - - -class SambaVersion(object): - - def __init__(self, version_dict, path, env=None, is_install=True): - '''Determine the version number of samba - -See VERSION for the format. Entries on that file are -also accepted as dictionary entries here - ''' - - self.MAJOR=None - self.MINOR=None - self.RELEASE=None - self.REVISION=None - self.TP_RELEASE=None - self.ALPHA_RELEASE=None - self.BETA_RELEASE=None - self.PRE_RELEASE=None - self.RC_RELEASE=None - self.IS_SNAPSHOT=True - self.RELEASE_NICKNAME=None - self.VENDOR_SUFFIX=None - self.VENDOR_PATCH=None - - for a, b in version_dict.items(): - if a.startswith("SAMBA_VERSION_"): - setattr(self, a[14:], b) - else: - setattr(self, a, b) - - if self.IS_GIT_SNAPSHOT == "yes": - self.IS_SNAPSHOT=True - elif self.IS_GIT_SNAPSHOT == "no": - self.IS_SNAPSHOT=False - else: - raise Exception("Unknown value for IS_GIT_SNAPSHOT: %s" % self.IS_GIT_SNAPSHOT) - - ## - ## start with "3.0.22" - ## - self.MAJOR=int(self.MAJOR) - self.MINOR=int(self.MINOR) - self.RELEASE=int(self.RELEASE) - - SAMBA_VERSION_STRING = ("%u.%u.%u" % (self.MAJOR, self.MINOR, self.RELEASE)) - -## -## maybe add "3.0.22a" or "4.0.0tp11" or "4.0.0alpha1" or "4.0.0beta1" or "3.0.22pre1" or "3.0.22rc1" -## We do not do pre or rc version on patch/letter releases -## - if self.REVISION is not None: - SAMBA_VERSION_STRING += self.REVISION - if self.TP_RELEASE is not None: - self.TP_RELEASE = int(self.TP_RELEASE) - SAMBA_VERSION_STRING += "tp%u" % self.TP_RELEASE - if self.ALPHA_RELEASE is not None: - self.ALPHA_RELEASE = int(self.ALPHA_RELEASE) - SAMBA_VERSION_STRING += ("alpha%u" % self.ALPHA_RELEASE) - if self.BETA_RELEASE is not None: - self.BETA_RELEASE = int(self.BETA_RELEASE) - SAMBA_VERSION_STRING += ("beta%u" % self.BETA_RELEASE) - if self.PRE_RELEASE is not None: - self.PRE_RELEASE = int(self.PRE_RELEASE) - SAMBA_VERSION_STRING += ("pre%u" % self.PRE_RELEASE) - if self.RC_RELEASE is not None: - self.RC_RELEASE = int(self.RC_RELEASE) - SAMBA_VERSION_STRING += ("rc%u" % self.RC_RELEASE) - - if self.IS_SNAPSHOT: - if not is_install: - suffix = "DEVELOPERBUILD" - self.vcs_fields = {} - elif os.path.exists(os.path.join(path, ".git")): - suffix, self.vcs_fields = git_version_summary(path, env=env) - elif os.path.exists(os.path.join(path, ".distversion")): - suffix, self.vcs_fields = distversion_version_summary(path) - else: - suffix = "UNKNOWN" - self.vcs_fields = {} - self.vcs_fields["SUFFIX"] = suffix - SAMBA_VERSION_STRING += "-" + suffix - else: - self.vcs_fields = {} - - self.OFFICIAL_STRING = SAMBA_VERSION_STRING - - if self.VENDOR_SUFFIX is not None: - SAMBA_VERSION_STRING += ("-" + self.VENDOR_SUFFIX) - self.VENDOR_SUFFIX = self.VENDOR_SUFFIX - - if self.VENDOR_PATCH is not None: - SAMBA_VERSION_STRING += ("-" + self.VENDOR_PATCH) - self.VENDOR_PATCH = self.VENDOR_PATCH - - self.STRING = SAMBA_VERSION_STRING - - if self.RELEASE_NICKNAME is not None: - self.STRING_WITH_NICKNAME = "%s (%s)" % (self.STRING, self.RELEASE_NICKNAME) - else: - self.STRING_WITH_NICKNAME = self.STRING - - def __str__(self): - string="/* Autogenerated by waf */\n" - string+="#define SAMBA_VERSION_MAJOR %u\n" % self.MAJOR - string+="#define SAMBA_VERSION_MINOR %u\n" % self.MINOR - string+="#define SAMBA_VERSION_RELEASE %u\n" % self.RELEASE - if self.REVISION is not None: - string+="#define SAMBA_VERSION_REVISION %u\n" % self.REVISION - - if self.TP_RELEASE is not None: - string+="#define SAMBA_VERSION_TP_RELEASE %u\n" % self.TP_RELEASE - - if self.ALPHA_RELEASE is not None: - string+="#define SAMBA_VERSION_ALPHA_RELEASE %u\n" % self.ALPHA_RELEASE - - if self.BETA_RELEASE is not None: - string+="#define SAMBA_VERSION_BETA_RELEASE %u\n" % self.BETA_RELEASE - - if self.PRE_RELEASE is not None: - string+="#define SAMBA_VERSION_PRE_RELEASE %u\n" % self.PRE_RELEASE - - if self.RC_RELEASE is not None: - string+="#define SAMBA_VERSION_RC_RELEASE %u\n" % self.RC_RELEASE - - for name in sorted(self.vcs_fields.keys()): - string+="#define SAMBA_VERSION_%s " % name - value = self.vcs_fields[name] - string_types = str - if sys.version_info[0] < 3: - string_types = basestring - if isinstance(value, string_types): - string += "\"%s\"" % value - elif type(value) is int: - string += "%d" % value - else: - raise Exception("Unknown type for %s: %r" % (name, value)) - string += "\n" - - string+="#define SAMBA_VERSION_OFFICIAL_STRING \"" + self.OFFICIAL_STRING + "\"\n" - - if self.VENDOR_SUFFIX is not None: - string+="#define SAMBA_VERSION_VENDOR_SUFFIX " + self.VENDOR_SUFFIX + "\n" - if self.VENDOR_PATCH is not None: - string+="#define SAMBA_VERSION_VENDOR_PATCH " + self.VENDOR_PATCH + "\n" - - if self.RELEASE_NICKNAME is not None: - string+="#define SAMBA_VERSION_RELEASE_NICKNAME " + self.RELEASE_NICKNAME + "\n" - - # We need to put this #ifdef in to the headers so that vendors can override the version with a function - string+=''' -#ifdef SAMBA_VERSION_VENDOR_FUNCTION -# define SAMBA_VERSION_STRING SAMBA_VERSION_VENDOR_FUNCTION -#else /* SAMBA_VERSION_VENDOR_FUNCTION */ -# define SAMBA_VERSION_STRING "''' + self.STRING_WITH_NICKNAME + '''" -#endif -''' - string+="/* Version for mkrelease.sh: \nSAMBA_VERSION_STRING=" + self.STRING_WITH_NICKNAME + "\n */\n" - - return string - - -def samba_version_file(version_file, path, env=None, is_install=True): - '''Parse the version information from a VERSION file''' - - f = open(version_file, 'r') - version_dict = {} - for line in f: - line = line.strip() - if line == '': - continue - if line.startswith("#"): - continue - try: - split_line = line.split("=") - if split_line[1] != "": - value = split_line[1].strip('"') - version_dict[split_line[0]] = value - except: - print("Failed to parse line %s from %s" % (line, version_file)) - raise - - return SambaVersion(version_dict, path, env=env, is_install=is_install) - - - -def load_version(env=None, is_install=True): - '''load samba versions either from ./VERSION or git - return a version object for detailed breakdown''' - if not env: - env = samba_utils.LOAD_ENVIRONMENT() - - version = samba_version_file("./VERSION", ".", env, is_install=is_install) - Context.g_module.VERSION = version.STRING - return version diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_waf18.py b/ldb-2.0.8/buildtools/wafsamba/samba_waf18.py deleted file mode 100644 index c0bb6bf..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/samba_waf18.py +++ /dev/null @@ -1,431 +0,0 @@ -# compatibility layer for building with more recent waf versions - -import os, shlex, sys -from waflib import Build, Configure, Node, Utils, Options, Logs, TaskGen -from waflib import ConfigSet -from waflib.TaskGen import feature, after -from waflib.Configure import conf, ConfigurationContext - -from waflib.Tools.flex import decide_ext - -# This version of flexfun runs in tsk.get_cwd() as opposed to the -# bld.variant_dir: since input paths adjusted against tsk.get_cwd(), we have to -# use tsk.get_cwd() for the work directory as well. -def flexfun(tsk): - env = tsk.env - bld = tsk.generator.bld - def to_list(xx): - if isinstance(xx, str): - return [xx] - return xx - tsk.last_cmd = lst = [] - lst.extend(to_list(env.FLEX)) - lst.extend(to_list(env.FLEXFLAGS)) - inputs = [a.path_from(tsk.get_cwd()) for a in tsk.inputs] - if env.FLEX_MSYS: - inputs = [x.replace(os.sep, '/') for x in inputs] - lst.extend(inputs) - lst = [x for x in lst if x] - txt = bld.cmd_and_log(lst, cwd=tsk.get_cwd(), env=env.env or None, quiet=0) - tsk.outputs[0].write(txt.replace('\r\n', '\n').replace('\r', '\n')) # issue #1207 - -TaskGen.declare_chain( - name = 'flex', - rule = flexfun, # issue #854 - ext_in = '.l', - decider = decide_ext, -) - - -for y in (Build.BuildContext, Build.CleanContext, Build.InstallContext, Build.UninstallContext, Build.ListContext): - class tmp(y): - variant = 'default' - -def abspath(self, env=None): - if env and hasattr(self, 'children'): - return self.get_bld().abspath() - return self.old_abspath() -Node.Node.old_abspath = Node.Node.abspath -Node.Node.abspath = abspath - -def bldpath(self, env=None): - return self.abspath() - #return self.path_from(self.ctx.bldnode.parent) -Node.Node.bldpath = bldpath - -def srcpath(self, env=None): - return self.abspath() - #return self.path_from(self.ctx.bldnode.parent) -Node.Node.srcpath = srcpath - -def store_fast(self, filename): - file = open(filename, 'wb') - data = self.get_merged_dict() - try: - Build.cPickle.dump(data, file, -1) - finally: - file.close() -ConfigSet.ConfigSet.store_fast = store_fast - -def load_fast(self, filename): - file = open(filename, 'rb') - try: - data = Build.cPickle.load(file) - finally: - file.close() - self.table.update(data) -ConfigSet.ConfigSet.load_fast = load_fast - -@feature('c', 'cxx', 'd', 'asm', 'fc', 'includes') -@after('propagate_uselib_vars', 'process_source') -def apply_incpaths(self): - lst = self.to_incnodes(self.to_list(getattr(self, 'includes', [])) + self.env['INCLUDES']) - self.includes_nodes = lst - cwdx = getattr(self.bld, 'cwdx', self.bld.bldnode) - self.env['INCPATHS'] = [x.path_from(cwdx) for x in lst] - -@conf -def define(self, key, val, quote=True, comment=None): - assert key and isinstance(key, str) - - if val is None: - val = () - elif isinstance(val, bool): - val = int(val) - - # waf 1.5 - self.env[key] = val - - if isinstance(val, int) or isinstance(val, float): - s = '%s=%s' - else: - s = quote and '%s="%s"' or '%s=%s' - app = s % (key, str(val)) - - ban = key + '=' - lst = self.env.DEFINES - for x in lst: - if x.startswith(ban): - lst[lst.index(x)] = app - break - else: - self.env.append_value('DEFINES', app) - - self.env.append_unique('define_key', key) - -# compat15 removes this but we want to keep it -@conf -def undefine(self, key, from_env=True, comment=None): - assert key and isinstance(key, str) - - ban = key + '=' - self.env.DEFINES = [x for x in self.env.DEFINES if not x.startswith(ban)] - self.env.append_unique('define_key', key) - # waf 1.5 - if from_env: - self.env[key] = () - -class ConfigurationContext(Configure.ConfigurationContext): - def init_dirs(self): - self.setenv('default') - self.env.merge_config_header = True - return super(ConfigurationContext, self).init_dirs() - -def find_program_samba(self, *k, **kw): - # Override the waf default set in the @conf decorator in Configure.py - if 'mandatory' not in kw: - kw['mandatory'] = False - ret = self.find_program_old(*k, **kw) - return ret -Configure.ConfigurationContext.find_program_old = Configure.ConfigurationContext.find_program -Configure.ConfigurationContext.find_program = find_program_samba - -Build.BuildContext.ENFORCE_GROUP_ORDERING = Utils.nada -Build.BuildContext.AUTOCLEANUP_STALE_FILES = Utils.nada - -@conf -def check(self, *k, **kw): - '''Override the waf defaults to inject --with-directory options''' - - # match the configuration test with speficic options, for example: - # --with-libiconv -> Options.options.iconv_open -> "Checking for library iconv" - self.validate_c(kw) - - additional_dirs = [] - if 'msg' in kw: - msg = kw['msg'] - for x in Options.OptionsContext.parser.parser.option_list: - if getattr(x, 'match', None) and msg in x.match: - d = getattr(Options.options, x.dest, '') - if d: - additional_dirs.append(d) - - # we add the additional dirs twice: once for the test data, and again if the compilation test suceeds below - def add_options_dir(dirs, env): - for x in dirs: - if not x in env.CPPPATH: - env.CPPPATH = [os.path.join(x, 'include')] + env.CPPPATH - if not x in env.LIBPATH: - env.LIBPATH = [os.path.join(x, 'lib')] + env.LIBPATH - - add_options_dir(additional_dirs, kw['env']) - - self.start_msg(kw['msg'], **kw) - ret = None - try: - ret = self.run_build(*k, **kw) - except self.errors.ConfigurationError: - self.end_msg(kw['errmsg'], 'YELLOW', **kw) - if Logs.verbose > 1: - raise - else: - self.fatal('The configuration failed') - else: - kw['success'] = ret - # success! time for brandy - add_options_dir(additional_dirs, self.env) - - ret = self.post_check(*k, **kw) - if not ret: - self.end_msg(kw['errmsg'], 'YELLOW', **kw) - self.fatal('The configuration failed %r' % ret) - else: - self.end_msg(self.ret_msg(kw['okmsg'], kw), **kw) - return ret - -@conf -def CHECK_LIBRARY_SUPPORT(conf, rpath=False, version_script=False, msg=None): - '''see if the platform supports building libraries''' - - if msg is None: - if rpath: - msg = "rpath library support" - else: - msg = "building library support" - - def build(bld): - lib_node = bld.srcnode.make_node('libdir/liblc1.c') - lib_node.parent.mkdir() - lib_node.write('int lib_func(void) { return 42; }\n', 'w') - main_node = bld.srcnode.make_node('main.c') - main_node.write('int main(void) {return !(lib_func() == 42);}', 'w') - linkflags = [] - if version_script: - script = bld.srcnode.make_node('ldscript') - script.write('TEST_1.0A2 { global: *; };\n', 'w') - linkflags.append('-Wl,--version-script=%s' % script.abspath()) - bld(features='c cshlib', source=lib_node, target='lib1', linkflags=linkflags, name='lib1') - o = bld(features='c cprogram', source=main_node, target='prog1', uselib_local='lib1') - if rpath: - o.rpath = [lib_node.parent.abspath()] - def run_app(self): - args = conf.SAMBA_CROSS_ARGS(msg=msg) - env = dict(os.environ) - env['LD_LIBRARY_PATH'] = self.inputs[0].parent.abspath() + os.pathsep + env.get('LD_LIBRARY_PATH', '') - self.generator.bld.cmd_and_log([self.inputs[0].abspath()] + args, env=env) - o.post() - bld(rule=run_app, source=o.link_task.outputs[0]) - - # ok, so it builds - try: - conf.check(build_fun=build, msg='Checking for %s' % msg) - except conf.errors.ConfigurationError: - return False - return True - -@conf -def CHECK_NEED_LC(conf, msg): - '''check if we need -lc''' - def build(bld): - lib_node = bld.srcnode.make_node('libdir/liblc1.c') - lib_node.parent.mkdir() - lib_node.write('#include \nint lib_func(void) { FILE *f = fopen("foo", "r");}\n', 'w') - bld(features='c cshlib', source=[lib_node], linkflags=conf.env.EXTRA_LDFLAGS, target='liblc') - try: - conf.check(build_fun=build, msg=msg, okmsg='-lc is unnecessary', errmsg='-lc is necessary') - except conf.errors.ConfigurationError: - return False - return True - -# already implemented on "waf -v" -def order(bld, tgt_list): - return True -Build.BuildContext.check_group_ordering = order - -@conf -def CHECK_CFG(self, *k, **kw): - if 'args' in kw: - kw['args'] = shlex.split(kw['args']) - if not 'mandatory' in kw: - kw['mandatory'] = False - kw['global_define'] = True - return self.check_cfg(*k, **kw) - -def cmd_output(cmd, **kw): - - silent = False - if 'silent' in kw: - silent = kw['silent'] - del(kw['silent']) - - if 'e' in kw: - tmp = kw['e'] - del(kw['e']) - kw['env'] = tmp - - kw['shell'] = isinstance(cmd, str) - kw['stdout'] = Utils.subprocess.PIPE - if silent: - kw['stderr'] = Utils.subprocess.PIPE - - try: - p = Utils.subprocess.Popen(cmd, **kw) - output = p.communicate()[0] - except OSError as e: - raise ValueError(str(e)) - - if p.returncode: - if not silent: - msg = "command execution failed: %s -> %r" % (cmd, str(output)) - raise ValueError(msg) - output = '' - return output -Utils.cmd_output = cmd_output - - -@TaskGen.feature('c', 'cxx', 'd') -@TaskGen.before('apply_incpaths', 'propagate_uselib_vars') -@TaskGen.after('apply_link', 'process_source') -def apply_uselib_local(self): - """ - process the uselib_local attribute - execute after apply_link because of the execution order set on 'link_task' - """ - env = self.env - from waflib.Tools.ccroot import stlink_task - - # 1. the case of the libs defined in the project (visit ancestors first) - # the ancestors external libraries (uselib) will be prepended - self.uselib = self.to_list(getattr(self, 'uselib', [])) - self.includes = self.to_list(getattr(self, 'includes', [])) - names = self.to_list(getattr(self, 'uselib_local', [])) - get = self.bld.get_tgen_by_name - seen = set() - seen_uselib = set() - tmp = Utils.deque(names) # consume a copy of the list of names - if tmp: - if Logs.verbose: - Logs.warn('compat: "uselib_local" is deprecated, replace by "use"') - while tmp: - lib_name = tmp.popleft() - # visit dependencies only once - if lib_name in seen: - continue - - y = get(lib_name) - y.post() - seen.add(lib_name) - - # object has ancestors to process (shared libraries): add them to the end of the list - if getattr(y, 'uselib_local', None): - for x in self.to_list(getattr(y, 'uselib_local', [])): - obj = get(x) - obj.post() - if getattr(obj, 'link_task', None): - if not isinstance(obj.link_task, stlink_task): - tmp.append(x) - - # link task and flags - if getattr(y, 'link_task', None): - - link_name = y.target[y.target.rfind(os.sep) + 1:] - if isinstance(y.link_task, stlink_task): - env.append_value('STLIB', [link_name]) - else: - # some linkers can link against programs - env.append_value('LIB', [link_name]) - - # the order - self.link_task.set_run_after(y.link_task) - - # for the recompilation - self.link_task.dep_nodes += y.link_task.outputs - - # add the link path too - tmp_path = y.link_task.outputs[0].parent.bldpath() - if not tmp_path in env['LIBPATH']: - env.prepend_value('LIBPATH', [tmp_path]) - - # add ancestors uselib too - but only propagate those that have no staticlib defined - for v in self.to_list(getattr(y, 'uselib', [])): - if v not in seen_uselib: - seen_uselib.add(v) - if not env['STLIB_' + v]: - if not v in self.uselib: - self.uselib.insert(0, v) - - # if the library task generator provides 'export_includes', add to the include path - # the export_includes must be a list of paths relative to the other library - if getattr(y, 'export_includes', None): - self.includes.extend(y.to_incnodes(y.export_includes)) - -@TaskGen.feature('cprogram', 'cxxprogram', 'cstlib', 'cxxstlib', 'cshlib', 'cxxshlib', 'dprogram', 'dstlib', 'dshlib') -@TaskGen.after('apply_link') -def apply_objdeps(self): - "add the .o files produced by some other object files in the same manner as uselib_local" - names = getattr(self, 'add_objects', []) - if not names: - return - names = self.to_list(names) - - get = self.bld.get_tgen_by_name - seen = [] - while names: - x = names[0] - - # visit dependencies only once - if x in seen: - names = names[1:] - continue - - # object does not exist ? - y = get(x) - - # object has ancestors to process first ? update the list of names - if getattr(y, 'add_objects', None): - added = 0 - lst = y.to_list(y.add_objects) - lst.reverse() - for u in lst: - if u in seen: - continue - added = 1 - names = [u]+names - if added: - continue # list of names modified, loop - - # safe to process the current object - y.post() - seen.append(x) - - for t in getattr(y, 'compiled_tasks', []): - self.link_task.inputs.extend(t.outputs) - -@TaskGen.after('apply_link') -def process_obj_files(self): - if not hasattr(self, 'obj_files'): - return - for x in self.obj_files: - node = self.path.find_resource(x) - self.link_task.inputs.append(node) - -@TaskGen.taskgen_method -def add_obj_file(self, file): - """Small example on how to link object files as if they were source - obj = bld.create_obj('cc') - obj.add_obj_file('foo.o')""" - if not hasattr(self, 'obj_files'): - self.obj_files = [] - if not 'process_obj_files' in self.meths: - self.meths.append('process_obj_files') - self.obj_files.append(file) diff --git a/ldb-2.0.8/buildtools/wafsamba/samba_wildcard.py b/ldb-2.0.8/buildtools/wafsamba/samba_wildcard.py deleted file mode 100644 index 6173ce8..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/samba_wildcard.py +++ /dev/null @@ -1,151 +0,0 @@ -# based on playground/evil in the waf svn tree - -import os, datetime, fnmatch -from waflib import Scripting, Utils, Options, Logs, Errors -from waflib import ConfigSet, Context -from samba_utils import LOCAL_CACHE, os_path_relpath - -def run_task(t, k): - '''run a single build task''' - ret = t.run() - if ret: - raise Errors.WafError("Failed to build %s: %u" % (k, ret)) - - -def run_named_build_task(cmd): - '''run a named build task, matching the cmd name using fnmatch - wildcards against inputs and outputs of all build tasks''' - bld = fake_build_environment(info=False) - found = False - cwd_node = bld.root.find_dir(os.getcwd()) - top_node = bld.root.find_dir(bld.srcnode.abspath()) - - cmd = os.path.normpath(cmd) - - # cope with builds of bin/*/* - if os.path.islink(cmd): - cmd = os_path_relpath(os.readlink(cmd), os.getcwd()) - - if cmd[0:12] == "bin/default/": - cmd = cmd[12:] - - for g in bld.task_manager.groups: - for attr in ['outputs', 'inputs']: - for t in g.tasks: - s = getattr(t, attr, []) - for k in s: - relpath1 = k.relpath_gen(cwd_node) - relpath2 = k.relpath_gen(top_node) - if (fnmatch.fnmatch(relpath1, cmd) or - fnmatch.fnmatch(relpath2, cmd)): - t.position = [0,0] - print(t.display()) - run_task(t, k) - found = True - - - if not found: - raise Errors.WafError("Unable to find build target matching %s" % cmd) - - -def rewrite_compile_targets(): - '''cope with the bin/ form of compile target''' - if not Options.options.compile_targets: - return - - bld = fake_build_environment(info=False) - targets = LOCAL_CACHE(bld, 'TARGET_TYPE') - tlist = [] - - for t in Options.options.compile_targets.split(','): - if not os.path.islink(t): - tlist.append(t) - continue - link = os.readlink(t) - list = link.split('/') - for name in [list[-1], '/'.join(list[-2:])]: - if name in targets: - tlist.append(name) - continue - Options.options.compile_targets = ",".join(tlist) - - - -def wildcard_main(missing_cmd_fn): - '''this replaces main from Scripting, allowing us to override the - behaviour for unknown commands - - If a unknown command is found, then missing_cmd_fn() is called with - the name of the requested command - ''' - Scripting.commands = Options.arg_line[:] - - # rewrite the compile targets to cope with the bin/xx form - rewrite_compile_targets() - - while Scripting.commands: - x = Scripting.commands.pop(0) - - ini = datetime.datetime.now() - if x == 'configure': - fun = Scripting.configure - elif x == 'build': - fun = Scripting.build - else: - fun = getattr(Utils.g_module, x, None) - - # this is the new addition on top of main from Scripting.py - if not fun: - missing_cmd_fn(x) - break - - ctx = getattr(Utils.g_module, x + '_context', Utils.Context)() - - if x in ['init', 'shutdown', 'dist', 'distclean', 'distcheck']: - try: - fun(ctx) - except TypeError: - fun() - else: - fun(ctx) - - ela = '' - if not Options.options.progress_bar: - ela = ' (%s)' % Utils.get_elapsed_time(ini) - - if x != 'init' and x != 'shutdown': - Logs.info('%r finished successfully%s' % (x, ela)) - - if not Scripting.commands and x != 'shutdown': - Scripting.commands.append('shutdown') - - - - -def fake_build_environment(info=True, flush=False): - """create all the tasks for the project, but do not run the build - return the build context in use""" - bld = getattr(Context.g_module, 'build_context', Utils.Context)() - bld = Scripting.check_configured(bld) - - Options.commands['install'] = False - Options.commands['uninstall'] = False - - bld.is_install = 0 # False - - try: - proj = ConfigSet.ConfigSet(Options.lockfile) - except IOError: - raise Errors.WafError("Project not configured (run 'waf configure' first)") - - bld.load_envs() - - if info: - Logs.info("Waf: Entering directory `%s'" % bld.bldnode.abspath()) - bld.add_subdirs([os.path.split(Context.g_module.root_path)[0]]) - - bld.pre_build() - if flush: - bld.flush() - return bld - diff --git a/ldb-2.0.8/buildtools/wafsamba/stale_files.py b/ldb-2.0.8/buildtools/wafsamba/stale_files.py deleted file mode 100644 index 175f573..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/stale_files.py +++ /dev/null @@ -1,113 +0,0 @@ -# encoding: utf-8 -# Thomas Nagy, 2006-2010 (ita) - -""" -Add a pre-build hook to remove all build files -which do not have a corresponding target - -This can be used for example to remove the targets -that have changed name without performing -a full 'waf clean' - -Of course, it will only work if there are no dynamically generated -nodes/tasks, in which case the method will have to be modified -to exclude some folders for example. -""" - -from waflib import Logs, Build, Options, Utils, Errors -import os -from wafsamba import samba_utils -from Runner import Parallel - -old_refill_task_list = Parallel.refill_task_list -def replace_refill_task_list(self): - '''replacement for refill_task_list() that deletes stale files''' - - iit = old_refill_task_list(self) - bld = self.bld - - if not getattr(bld, 'new_rules', False): - # we only need to check for stale files if the build rules changed - return iit - - if Options.options.compile_targets: - # not safe when --target is used - return iit - - # execute only once - if getattr(self, 'cleanup_done', False): - return iit - self.cleanup_done = True - - def group_name(g): - tm = self.bld.task_manager - return [x for x in tm.groups_names if id(tm.groups_names[x]) == id(g)][0] - - bin_base = bld.bldnode.abspath() - bin_base_len = len(bin_base) - - # paranoia - if bin_base[-4:] != '/bin': - raise Errors.WafError("Invalid bin base: %s" % bin_base) - - # obtain the expected list of files - expected = [] - for i in range(len(bld.task_manager.groups)): - g = bld.task_manager.groups[i] - tasks = g.tasks_gen - for x in tasks: - try: - if getattr(x, 'target'): - tlist = samba_utils.TO_LIST(getattr(x, 'target')) - ttype = getattr(x, 'samba_type', None) - task_list = getattr(x, 'compiled_tasks', []) - if task_list: - # this gets all of the .o files, including the task - # ids, so foo.c maps to foo_3.o for idx=3 - for tsk in task_list: - for output in tsk.outputs: - objpath = os.path.normpath(output.abspath(bld.env)) - expected.append(objpath) - for t in tlist: - if ttype in ['LIBRARY','MODULE']: - t = samba_utils.apply_pattern(t, bld.env.shlib_PATTERN) - if ttype == 'PYTHON': - t = samba_utils.apply_pattern(t, bld.env.pyext_PATTERN) - p = os.path.join(x.path.abspath(bld.env), t) - p = os.path.normpath(p) - expected.append(p) - for n in x.allnodes: - p = n.abspath(bld.env) - if p[0:bin_base_len] == bin_base: - expected.append(p) - except: - pass - - for root, dirs, files in os.walk(bin_base): - for f in files: - p = root + '/' + f - if os.path.islink(p): - link = os.readlink(p) - if link[0:bin_base_len] == bin_base: - p = link - if f in ['config.h']: - continue - (froot, fext) = os.path.splitext(f) - if fext not in [ '.c', '.h', '.so', '.o' ]: - continue - if f[-7:] == '.inst.h': - continue - if p.find("/.conf") != -1: - continue - if not p in expected and os.path.exists(p): - Logs.warn("Removing stale file: %s" % p) - os.unlink(p) - return iit - - -def AUTOCLEANUP_STALE_FILES(bld): - """automatically clean up any files in bin that shouldn't be there""" - old_refill_task_list = Parallel.refill_task_list - Parallel.refill_task_list = replace_refill_task_list - Parallel.bld = bld -Build.BuildContext.AUTOCLEANUP_STALE_FILES = AUTOCLEANUP_STALE_FILES diff --git a/ldb-2.0.8/buildtools/wafsamba/symbols.py b/ldb-2.0.8/buildtools/wafsamba/symbols.py deleted file mode 100644 index 3eca3d4..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/symbols.py +++ /dev/null @@ -1,659 +0,0 @@ -# a waf tool to extract symbols from object files or libraries -# using nm, producing a set of exposed defined/undefined symbols - -import os, re, subprocess -from waflib import Utils, Build, Options, Logs, Errors -from waflib.Logs import debug -from samba_utils import TO_LIST, LOCAL_CACHE, get_tgt_list, os_path_relpath - -# these are the data structures used in symbols.py: -# -# bld.env.symbol_map : dictionary mapping public symbol names to list of -# subsystem names where that symbol exists -# -# t.in_library : list of libraries that t is in -# -# bld.env.public_symbols: set of public symbols for each subsystem -# bld.env.used_symbols : set of used symbols for each subsystem -# -# bld.env.syslib_symbols: dictionary mapping system library name to set of symbols -# for that library -# bld.env.library_dict : dictionary mapping built library paths to subsystem names -# -# LOCAL_CACHE(bld, 'TARGET_TYPE') : dictionary mapping subsystem name to target type - - -def symbols_extract(bld, objfiles, dynamic=False): - '''extract symbols from objfile, returning a dictionary containing - the set of undefined and public symbols for each file''' - - ret = {} - - # see if we can get some results from the nm cache - if not bld.env.nm_cache: - bld.env.nm_cache = {} - - objfiles = set(objfiles).copy() - - remaining = set() - for obj in objfiles: - if obj in bld.env.nm_cache: - ret[obj] = bld.env.nm_cache[obj].copy() - else: - remaining.add(obj) - objfiles = remaining - - if len(objfiles) == 0: - return ret - - cmd = ["nm"] - if dynamic: - # needed for some .so files - cmd.append("-D") - cmd.extend(list(objfiles)) - - nmpipe = subprocess.Popen(cmd, stdout=subprocess.PIPE).stdout - if len(objfiles) == 1: - filename = list(objfiles)[0] - ret[filename] = { "PUBLIC": set(), "UNDEFINED" : set()} - - for line in nmpipe: - line = line.strip() - if line.endswith(b':'): - filename = line[:-1] - ret[filename] = { "PUBLIC": set(), "UNDEFINED" : set() } - continue - cols = line.split(b" ") - if cols == [b'']: - continue - # see if the line starts with an address - if len(cols) == 3: - symbol_type = cols[1] - symbol = cols[2] - else: - symbol_type = cols[0] - symbol = cols[1] - if symbol_type in b"BDGTRVWSi": - # its a public symbol - ret[filename]["PUBLIC"].add(symbol) - elif symbol_type in b"U": - ret[filename]["UNDEFINED"].add(symbol) - - # add to the cache - for obj in objfiles: - if obj in ret: - bld.env.nm_cache[obj] = ret[obj].copy() - else: - bld.env.nm_cache[obj] = { "PUBLIC": set(), "UNDEFINED" : set() } - - return ret - - -def real_name(name): - if name.find(".objlist") != -1: - name = name[:-8] - return name - - -def find_ldd_path(bld, libname, binary): - '''find the path to the syslib we will link against''' - ret = None - if not bld.env.syslib_paths: - bld.env.syslib_paths = {} - if libname in bld.env.syslib_paths: - return bld.env.syslib_paths[libname] - - lddpipe = subprocess.Popen(['ldd', binary], stdout=subprocess.PIPE).stdout - for line in lddpipe: - line = line.strip() - cols = line.split(b" ") - if len(cols) < 3 or cols[1] != b"=>": - continue - if cols[0].startswith(b"libc."): - # save this one too - bld.env.libc_path = cols[2] - if cols[0].startswith(libname): - ret = cols[2] - bld.env.syslib_paths[libname] = ret - return ret - - -# some regular expressions for parsing readelf output -re_sharedlib = re.compile(b'Shared library: \[(.*)\]') -# output from readelf could be `Library rpath` or `Libray runpath` -re_rpath = re.compile(b'Library (rpath|runpath): \[(.*)\]') - -def get_libs(bld, binname): - '''find the list of linked libraries for any binary or library - binname is the path to the binary/library on disk - - We do this using readelf instead of ldd as we need to avoid recursing - into system libraries - ''' - - # see if we can get the result from the ldd cache - if not bld.env.lib_cache: - bld.env.lib_cache = {} - if binname in bld.env.lib_cache: - return bld.env.lib_cache[binname].copy() - - rpath = [] - libs = set() - - elfpipe = subprocess.Popen(['readelf', '--dynamic', binname], stdout=subprocess.PIPE).stdout - for line in elfpipe: - m = re_sharedlib.search(line) - if m: - libs.add(m.group(1)) - m = re_rpath.search(line) - if m: - # output from Popen is always bytestr even in py3 - rpath.extend(m.group(2).split(b":")) - - ret = set() - for lib in libs: - found = False - for r in rpath: - path = os.path.join(r, lib) - if os.path.exists(path): - ret.add(os.path.realpath(path)) - found = True - break - if not found: - # we didn't find this lib using rpath. It is probably a system - # library, so to find the path to it we either need to use ldd - # or we need to start parsing /etc/ld.so.conf* ourselves. We'll - # use ldd for now, even though it is slow - path = find_ldd_path(bld, lib, binname) - if path: - ret.add(os.path.realpath(path)) - - bld.env.lib_cache[binname] = ret.copy() - - return ret - - -def get_libs_recursive(bld, binname, seen): - '''find the recursive list of linked libraries for any binary or library - binname is the path to the binary/library on disk. seen is a set used - to prevent loops - ''' - if binname in seen: - return set() - ret = get_libs(bld, binname) - seen.add(binname) - for lib in ret: - # we don't want to recurse into system libraries. If a system - # library that we use (eg. libcups) happens to use another library - # (such as libkrb5) which contains common symbols with our own - # libraries, then that is not an error - if lib in bld.env.library_dict: - ret = ret.union(get_libs_recursive(bld, lib, seen)) - return ret - - - -def find_syslib_path(bld, libname, deps): - '''find the path to the syslib we will link against''' - # the strategy is to use the targets that depend on the library, and run ldd - # on it to find the real location of the library that is used - - linkpath = deps[0].link_task.outputs[0].abspath(bld.env) - - if libname == "python": - libname += bld.env.PYTHON_VERSION - - return find_ldd_path(bld, "lib%s" % libname.lower(), linkpath) - - -def build_symbol_sets(bld, tgt_list): - '''build the public_symbols and undefined_symbols attributes for each target''' - - if bld.env.public_symbols: - return - - objlist = [] # list of object file - objmap = {} # map from object filename to target (subsystem) name - - for t in tgt_list: - t.public_symbols = set() - t.undefined_symbols = set() - t.used_symbols = set() - for tsk in getattr(t, 'compiled_tasks', []): - for output in tsk.outputs: - objpath = output.abspath(bld.env) - objlist.append(objpath) - objmap[objpath] = t - - symbols = symbols_extract(bld, objlist) - for obj in objlist: - t = objmap[obj] - t.public_symbols = t.public_symbols.union(symbols[obj]["PUBLIC"]) - t.undefined_symbols = t.undefined_symbols.union(symbols[obj]["UNDEFINED"]) - t.used_symbols = t.used_symbols.union(symbols[obj]["UNDEFINED"]) - - t.undefined_symbols = t.undefined_symbols.difference(t.public_symbols) - - # and the reverse map of public symbols to subsystem name - bld.env.symbol_map = {} - - for t in tgt_list: - for s in t.public_symbols: - if not s in bld.env.symbol_map: - bld.env.symbol_map[s] = [] - bld.env.symbol_map[s].append(real_name(t.sname)) - - targets = LOCAL_CACHE(bld, 'TARGET_TYPE') - - bld.env.public_symbols = {} - for t in tgt_list: - name = real_name(t.sname) - if name in bld.env.public_symbols: - bld.env.public_symbols[name] = bld.env.public_symbols[name].union(t.public_symbols) - else: - bld.env.public_symbols[name] = t.public_symbols - if t.samba_type == 'LIBRARY': - for dep in t.add_objects: - t2 = bld.get_tgen_by_name(dep) - bld.ASSERT(t2 is not None, "Library '%s' has unknown dependency '%s'" % (name, dep)) - bld.env.public_symbols[name] = bld.env.public_symbols[name].union(t2.public_symbols) - - bld.env.used_symbols = {} - for t in tgt_list: - name = real_name(t.sname) - if name in bld.env.used_symbols: - bld.env.used_symbols[name] = bld.env.used_symbols[name].union(t.used_symbols) - else: - bld.env.used_symbols[name] = t.used_symbols - if t.samba_type == 'LIBRARY': - for dep in t.add_objects: - t2 = bld.get_tgen_by_name(dep) - bld.ASSERT(t2 is not None, "Library '%s' has unknown dependency '%s'" % (name, dep)) - bld.env.used_symbols[name] = bld.env.used_symbols[name].union(t2.used_symbols) - - -def build_library_dict(bld, tgt_list): - '''build the library_dict dictionary''' - - if bld.env.library_dict: - return - - bld.env.library_dict = {} - - for t in tgt_list: - if t.samba_type in [ 'LIBRARY', 'PYTHON' ]: - linkpath = os.path.realpath(t.link_task.outputs[0].abspath(bld.env)) - bld.env.library_dict[linkpath] = t.sname - - -def build_syslib_sets(bld, tgt_list): - '''build the public_symbols for all syslibs''' - - if bld.env.syslib_symbols: - return - - # work out what syslibs we depend on, and what targets those are used in - syslibs = {} - objmap = {} - for t in tgt_list: - if getattr(t, 'uselib', []) and t.samba_type in [ 'LIBRARY', 'BINARY', 'PYTHON' ]: - for lib in t.uselib: - if lib in ['PYEMBED', 'PYEXT']: - lib = "python" - if not lib in syslibs: - syslibs[lib] = [] - syslibs[lib].append(t) - - # work out the paths to each syslib - syslib_paths = [] - for lib in syslibs: - path = find_syslib_path(bld, lib, syslibs[lib]) - if path is None: - Logs.warn("Unable to find syslib path for %s" % lib) - if path is not None: - syslib_paths.append(path) - objmap[path] = lib.lower() - - # add in libc - syslib_paths.append(bld.env.libc_path) - objmap[bld.env.libc_path] = 'c' - - symbols = symbols_extract(bld, syslib_paths, dynamic=True) - - # keep a map of syslib names to public symbols - bld.env.syslib_symbols = {} - for lib in symbols: - bld.env.syslib_symbols[lib] = symbols[lib]["PUBLIC"] - - # add to the map of symbols to dependencies - for lib in symbols: - for sym in symbols[lib]["PUBLIC"]: - if not sym in bld.env.symbol_map: - bld.env.symbol_map[sym] = [] - bld.env.symbol_map[sym].append(objmap[lib]) - - # keep the libc symbols as well, as these are useful for some of the - # sanity checks - bld.env.libc_symbols = symbols[bld.env.libc_path]["PUBLIC"] - - # add to the combined map of dependency name to public_symbols - for lib in bld.env.syslib_symbols: - bld.env.public_symbols[objmap[lib]] = bld.env.syslib_symbols[lib] - - -def build_autodeps(bld, t): - '''build the set of dependencies for a target''' - deps = set() - name = real_name(t.sname) - - targets = LOCAL_CACHE(bld, 'TARGET_TYPE') - - for sym in t.undefined_symbols: - if sym in t.public_symbols: - continue - if sym in bld.env.symbol_map: - depname = bld.env.symbol_map[sym] - if depname == [ name ]: - # self dependencies aren't interesting - continue - if t.in_library == depname: - # no need to depend on the library we are part of - continue - if depname[0] in ['c', 'python']: - # these don't go into autodeps - continue - if targets[depname[0]] in [ 'SYSLIB' ]: - deps.add(depname[0]) - continue - t2 = bld.get_tgen_by_name(depname[0]) - if len(t2.in_library) != 1: - deps.add(depname[0]) - continue - if t2.in_library == t.in_library: - # if we're part of the same library, we don't need to autodep - continue - deps.add(t2.in_library[0]) - t.autodeps = deps - - -def build_library_names(bld, tgt_list): - '''add a in_library attribute to all targets that are part of a library''' - - if bld.env.done_build_library_names: - return - - for t in tgt_list: - t.in_library = [] - - for t in tgt_list: - if t.samba_type in [ 'LIBRARY' ]: - for obj in t.samba_deps_extended: - t2 = bld.get_tgen_by_name(obj) - if t2 and t2.samba_type in [ 'SUBSYSTEM', 'ASN1' ]: - if not t.sname in t2.in_library: - t2.in_library.append(t.sname) - bld.env.done_build_library_names = True - - -def check_library_deps(bld, t): - '''check that all the autodeps that have mutual dependency of this - target are in the same library as the target''' - - name = real_name(t.sname) - - if len(t.in_library) > 1: - Logs.warn("WARNING: Target '%s' in multiple libraries: %s" % (t.sname, t.in_library)) - - for dep in t.autodeps: - t2 = bld.get_tgen_by_name(dep) - if t2 is None: - continue - for dep2 in t2.autodeps: - if dep2 == name and t.in_library != t2.in_library: - Logs.warn("WARNING: mutual dependency %s <=> %s" % (name, real_name(t2.sname))) - Logs.warn("Libraries should match. %s != %s" % (t.in_library, t2.in_library)) - # raise Errors.WafError("illegal mutual dependency") - - -def check_syslib_collisions(bld, tgt_list): - '''check if a target has any symbol collisions with a syslib - - We do not want any code in Samba to use a symbol name from a - system library. The chance of that causing problems is just too - high. Note that libreplace uses a rep_XX approach of renaming - symbols via macros - ''' - - has_error = False - for t in tgt_list: - for lib in bld.env.syslib_symbols: - common = t.public_symbols.intersection(bld.env.syslib_symbols[lib]) - if common: - Logs.error("ERROR: Target '%s' has symbols '%s' which is also in syslib '%s'" % (t.sname, common, lib)) - has_error = True - if has_error: - raise Errors.WafError("symbols in common with system libraries") - - -def check_dependencies(bld, t): - '''check for depenencies that should be changed''' - - if bld.get_tgen_by_name(t.sname + ".objlist"): - return - - targets = LOCAL_CACHE(bld, 'TARGET_TYPE') - - remaining = t.undefined_symbols.copy() - remaining = remaining.difference(t.public_symbols) - - sname = real_name(t.sname) - - deps = set(t.samba_deps) - for d in t.samba_deps: - if targets[d] in [ 'EMPTY', 'DISABLED', 'SYSLIB', 'GENERATOR' ]: - continue - bld.ASSERT(d in bld.env.public_symbols, "Failed to find symbol list for dependency '%s'" % d) - diff = remaining.intersection(bld.env.public_symbols[d]) - if not diff and targets[sname] != 'LIBRARY': - Logs.info("Target '%s' has no dependency on %s" % (sname, d)) - else: - remaining = remaining.difference(diff) - - t.unsatisfied_symbols = set() - needed = {} - for sym in remaining: - if sym in bld.env.symbol_map: - dep = bld.env.symbol_map[sym] - if not dep[0] in needed: - needed[dep[0]] = set() - needed[dep[0]].add(sym) - else: - t.unsatisfied_symbols.add(sym) - - for dep in needed: - Logs.info("Target '%s' should add dep '%s' for symbols %s" % (sname, dep, " ".join(needed[dep]))) - - - -def check_syslib_dependencies(bld, t): - '''check for syslib depenencies''' - - if bld.get_tgen_by_name(t.sname + ".objlist"): - return - - sname = real_name(t.sname) - - remaining = set() - - features = TO_LIST(t.features) - if 'pyembed' in features or 'pyext' in features: - if 'python' in bld.env.public_symbols: - t.unsatisfied_symbols = t.unsatisfied_symbols.difference(bld.env.public_symbols['python']) - - needed = {} - for sym in t.unsatisfied_symbols: - if sym in bld.env.symbol_map: - dep = bld.env.symbol_map[sym][0] - if dep == 'c': - continue - if not dep in needed: - needed[dep] = set() - needed[dep].add(sym) - else: - remaining.add(sym) - - for dep in needed: - Logs.info("Target '%s' should add syslib dep '%s' for symbols %s" % (sname, dep, " ".join(needed[dep]))) - - if remaining: - debug("deps: Target '%s' has unsatisfied symbols: %s" % (sname, " ".join(remaining))) - - - -def symbols_symbolcheck(task): - '''check the internal dependency lists''' - bld = task.env.bld - tgt_list = get_tgt_list(bld) - - build_symbol_sets(bld, tgt_list) - build_library_names(bld, tgt_list) - - for t in tgt_list: - t.autodeps = set() - if getattr(t, 'source', ''): - build_autodeps(bld, t) - - for t in tgt_list: - check_dependencies(bld, t) - - for t in tgt_list: - check_library_deps(bld, t) - -def symbols_syslibcheck(task): - '''check the syslib dependencies''' - bld = task.env.bld - tgt_list = get_tgt_list(bld) - - build_syslib_sets(bld, tgt_list) - check_syslib_collisions(bld, tgt_list) - - for t in tgt_list: - check_syslib_dependencies(bld, t) - - -def symbols_whyneeded(task): - """check why 'target' needs to link to 'subsystem'""" - bld = task.env.bld - tgt_list = get_tgt_list(bld) - - why = Options.options.WHYNEEDED.split(":") - if len(why) != 2: - raise Errors.WafError("usage: WHYNEEDED=TARGET:DEPENDENCY") - target = why[0] - subsystem = why[1] - - build_symbol_sets(bld, tgt_list) - build_library_names(bld, tgt_list) - build_syslib_sets(bld, tgt_list) - - Logs.info("Checking why %s needs to link to %s" % (target, subsystem)) - if not target in bld.env.used_symbols: - Logs.warn("unable to find target '%s' in used_symbols dict" % target) - return - if not subsystem in bld.env.public_symbols: - Logs.warn("unable to find subsystem '%s' in public_symbols dict" % subsystem) - return - overlap = bld.env.used_symbols[target].intersection(bld.env.public_symbols[subsystem]) - if not overlap: - Logs.info("target '%s' doesn't use any public symbols from '%s'" % (target, subsystem)) - else: - Logs.info("target '%s' uses symbols %s from '%s'" % (target, overlap, subsystem)) - - -def report_duplicate(bld, binname, sym, libs, fail_on_error): - '''report duplicated symbols''' - if sym in ['_init', '_fini', '_edata', '_end', '__bss_start']: - return - libnames = [] - for lib in libs: - if lib in bld.env.library_dict: - libnames.append(bld.env.library_dict[lib]) - else: - libnames.append(lib) - if fail_on_error: - raise Errors.WafError("%s: Symbol %s linked in multiple libraries %s" % (binname, sym, libnames)) - else: - print("%s: Symbol %s linked in multiple libraries %s" % (binname, sym, libnames)) - - -def symbols_dupcheck_binary(bld, binname, fail_on_error): - '''check for duplicated symbols in one binary''' - - libs = get_libs_recursive(bld, binname, set()) - symlist = symbols_extract(bld, libs, dynamic=True) - - symmap = {} - for libpath in symlist: - for sym in symlist[libpath]['PUBLIC']: - if sym == '_GLOBAL_OFFSET_TABLE_': - continue - if not sym in symmap: - symmap[sym] = set() - symmap[sym].add(libpath) - for sym in symmap: - if len(symmap[sym]) > 1: - for libpath in symmap[sym]: - if libpath in bld.env.library_dict: - report_duplicate(bld, binname, sym, symmap[sym], fail_on_error) - break - -def symbols_dupcheck(task, fail_on_error=False): - '''check for symbols defined in two different subsystems''' - bld = task.env.bld - tgt_list = get_tgt_list(bld) - - targets = LOCAL_CACHE(bld, 'TARGET_TYPE') - - build_library_dict(bld, tgt_list) - for t in tgt_list: - if t.samba_type == 'BINARY': - binname = os_path_relpath(t.link_task.outputs[0].abspath(bld.env), os.getcwd()) - symbols_dupcheck_binary(bld, binname, fail_on_error) - - -def symbols_dupcheck_fatal(task): - '''check for symbols defined in two different subsystems (and fail if duplicates are found)''' - symbols_dupcheck(task, fail_on_error=True) - - -def SYMBOL_CHECK(bld): - '''check our dependency lists''' - if Options.options.SYMBOLCHECK: - bld.SET_BUILD_GROUP('symbolcheck') - task = bld(rule=symbols_symbolcheck, always=True, name='symbol checking') - task.env.bld = bld - - bld.SET_BUILD_GROUP('syslibcheck') - task = bld(rule=symbols_syslibcheck, always=True, name='syslib checking') - task.env.bld = bld - - bld.SET_BUILD_GROUP('syslibcheck') - task = bld(rule=symbols_dupcheck, always=True, name='symbol duplicate checking') - task.env.bld = bld - - if Options.options.WHYNEEDED: - bld.SET_BUILD_GROUP('syslibcheck') - task = bld(rule=symbols_whyneeded, always=True, name='check why a dependency is needed') - task.env.bld = bld - - -Build.BuildContext.SYMBOL_CHECK = SYMBOL_CHECK - -def DUP_SYMBOL_CHECK(bld): - if Options.options.DUP_SYMBOLCHECK and bld.env.DEVELOPER: - '''check for duplicate symbols''' - bld.SET_BUILD_GROUP('syslibcheck') - task = bld(rule=symbols_dupcheck_fatal, always=True, name='symbol duplicate checking') - task.env.bld = bld - -Build.BuildContext.DUP_SYMBOL_CHECK = DUP_SYMBOL_CHECK diff --git a/ldb-2.0.8/buildtools/wafsamba/test_duplicate_symbol.sh b/ldb-2.0.8/buildtools/wafsamba/test_duplicate_symbol.sh deleted file mode 100755 index 46f44a6..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/test_duplicate_symbol.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -# Run the waf duplicate symbol check, wrapped in subunit. - -. testprogs/blackbox/subunit.sh - -subunit_start_test duplicate_symbols - -if $PYTHON ./buildtools/bin/waf build --dup-symbol-check; then - subunit_pass_test duplicate_symbols -else - echo | subunit_fail_test duplicate_symbols -fi diff --git a/ldb-2.0.8/buildtools/wafsamba/tests/__init__.py b/ldb-2.0.8/buildtools/wafsamba/tests/__init__.py deleted file mode 100644 index ae27418..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/tests/__init__.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright (C) 2012 Jelmer Vernooij - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. - -# You should have received a copy of the GNU Lesser General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -"""Tests for wafsamba.""" - -from unittest import ( - TestCase, - TestLoader, - ) - -def test_suite(): - names = [ - 'abi', - 'bundled', - 'utils', - ] - module_names = ['wafsamba.tests.test_' + name for name in names] - loader = TestLoader() - result = loader.suiteClass() - suite = loader.loadTestsFromNames(module_names) - result.addTests(suite) - return result diff --git a/ldb-2.0.8/buildtools/wafsamba/tests/test_abi.py b/ldb-2.0.8/buildtools/wafsamba/tests/test_abi.py deleted file mode 100644 index d6bdb04..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/tests/test_abi.py +++ /dev/null @@ -1,134 +0,0 @@ -# Copyright (C) 2012 Jelmer Vernooij - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. - -# You should have received a copy of the GNU Lesser General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -from wafsamba.tests import TestCase - -from wafsamba.samba_abi import ( - abi_write_vscript, - normalise_signature, - ) - -from samba.compat import StringIO - - -class NormaliseSignatureTests(TestCase): - - def test_function_simple(self): - self.assertEquals("int (const struct GUID *, const struct GUID *)", - normalise_signature("$2 = {int (const struct GUID *, const struct GUID *)} 0xe871 ")) - - def test_maps_Bool(self): - # Some types have different internal names - self.assertEquals("bool (const struct GUID *)", - normalise_signature("$1 = {_Bool (const struct GUID *)} 0xe75b ")) - - def test_function_keep(self): - self.assertEquals( - "enum ndr_err_code (struct ndr_push *, int, const union winreg_Data *)", - normalise_signature("enum ndr_err_code (struct ndr_push *, int, const union winreg_Data *)")) - - def test_struct_constant(self): - self.assertEquals( - 'uuid = {time_low = 0, time_mid = 0, time_hi_and_version = 0, clock_seq = "\\000", node = "\\000\\000\\000\\000\\000"}, if_version = 0', - normalise_signature('$239 = {uuid = {time_low = 0, time_mid = 0, time_hi_and_version = 0, clock_seq = "\\000", node = "\\000\\000\\000\\000\\000"}, if_version = 0}')) - - def test_incomplete_sequence(self): - # Newer versions of gdb insert these incomplete sequence elements - self.assertEquals( - 'uuid = {time_low = 2324192516, time_mid = 7403, time_hi_and_version = 4553, clock_seq = "\\237\\350", node = "\\b\\000+\\020H`"}, if_version = 2', - normalise_signature('$244 = {uuid = {time_low = 2324192516, time_mid = 7403, time_hi_and_version = 4553, clock_seq = "\\237", , node = "\\b\\000+\\020H`"}, if_version = 2}')) - self.assertEquals( - 'uuid = {time_low = 2324192516, time_mid = 7403, time_hi_and_version = 4553, clock_seq = "\\237\\350", node = "\\b\\000+\\020H`"}, if_version = 2', - normalise_signature('$244 = {uuid = {time_low = 2324192516, time_mid = 7403, time_hi_and_version = 4553, clock_seq = "\\237\\350", node = "\\b\\000+\\020H`"}, if_version = 2}')) - - -class WriteVscriptTests(TestCase): - - def test_one(self): - f = StringIO() - abi_write_vscript(f, "MYLIB", "1.0", [], { - "old": "1.0", - "new": "1.0"}, ["*"]) - self.assertEquals(f.getvalue(), """\ -1.0 { -\tglobal: -\t\t*; -\tlocal: -\t\t_end; -\t\t__bss_start; -\t\t_edata; -}; -""") - - def test_simple(self): - # No restrictions. - f = StringIO() - abi_write_vscript(f, "MYLIB", "1.0", ["0.1"], { - "old": "0.1", - "new": "1.0"}, ["*"]) - self.assertEquals(f.getvalue(), """\ -MYLIB_0.1 { -\tglobal: -\t\told; -}; - -1.0 { -\tglobal: -\t\t*; -\tlocal: -\t\t_end; -\t\t__bss_start; -\t\t_edata; -}; -""") - - def test_exclude(self): - f = StringIO() - abi_write_vscript(f, "MYLIB", "1.0", [], { - "exc_old": "0.1", - "old": "0.1", - "new": "1.0"}, ["!exc_*"]) - self.assertEquals(f.getvalue(), """\ -1.0 { -\tglobal: -\t\t*; -\tlocal: -\t\texc_*; -\t\t_end; -\t\t__bss_start; -\t\t_edata; -}; -""") - - def test_excludes_and_includes(self): - f = StringIO() - abi_write_vscript(f, "MYLIB", "1.0", [], { - "pub_foo": "1.0", - "exc_bar": "1.0", - "other": "1.0" - }, ["pub_*", "!exc_*"]) - self.assertEquals(f.getvalue(), """\ -1.0 { -\tglobal: -\t\tpub_*; -\tlocal: -\t\texc_*; -\t\t_end; -\t\t__bss_start; -\t\t_edata; -\t\t*; -}; -""") diff --git a/ldb-2.0.8/buildtools/wafsamba/tests/test_bundled.py b/ldb-2.0.8/buildtools/wafsamba/tests/test_bundled.py deleted file mode 100644 index c5f0db6..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/tests/test_bundled.py +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (C) 2012 Jelmer Vernooij - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. - -# You should have received a copy of the GNU Lesser General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -from wafsamba.tests import TestCase - -from wafsamba.samba_bundled import ( - tuplize_version, - ) - - -class TuplizeVersionTests(TestCase): - - def test_simple(self): - self.assertEquals((1, 2, 10), tuplize_version("1.2.10")) diff --git a/ldb-2.0.8/buildtools/wafsamba/tests/test_utils.py b/ldb-2.0.8/buildtools/wafsamba/tests/test_utils.py deleted file mode 100644 index a9578e2..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/tests/test_utils.py +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright (C) 2012 Jelmer Vernooij - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. - -# You should have received a copy of the GNU Lesser General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -from wafsamba.tests import TestCase - -from wafsamba.samba_utils import ( - TO_LIST, - dict_concat, - subst_vars_error, - unique_list, - ) - -class ToListTests(TestCase): - - def test_none(self): - self.assertEquals([], TO_LIST(None)) - - def test_already_list(self): - self.assertEquals(["foo", "bar", 1], TO_LIST(["foo", "bar", 1])) - - def test_default_delimiter(self): - self.assertEquals(["foo", "bar"], TO_LIST("foo bar")) - self.assertEquals(["foo", "bar"], TO_LIST(" foo bar ")) - self.assertEquals(["foo ", "bar"], TO_LIST(" \"foo \" bar ")) - - def test_delimiter(self): - self.assertEquals(["foo", "bar"], TO_LIST("foo,bar", ",")) - self.assertEquals([" foo", "bar "], TO_LIST(" foo,bar ", ",")) - self.assertEquals([" \" foo\"", " bar "], TO_LIST(" \" foo\", bar ", ",")) - - -class UniqueListTests(TestCase): - - def test_unique_list(self): - self.assertEquals(["foo", "bar"], unique_list(["foo", "bar", "foo"])) - - -class SubstVarsErrorTests(TestCase): - - def test_valid(self): - self.assertEquals("", subst_vars_error("", {})) - self.assertEquals("FOO bar", subst_vars_error("${F} bar", {"F": "FOO"})) - - def test_invalid(self): - self.assertRaises(KeyError, subst_vars_error, "${F}", {}) - - -class DictConcatTests(TestCase): - - def test_empty(self): - ret = {} - dict_concat(ret, {}) - self.assertEquals({}, ret) - - def test_same(self): - ret = {"foo": "bar"} - dict_concat(ret, {"foo": "bla"}) - self.assertEquals({"foo": "bar"}, ret) - - def test_simple(self): - ret = {"foo": "bar"} - dict_concat(ret, {"blie": "bla"}) - self.assertEquals({"foo": "bar", "blie": "bla"}, ret) diff --git a/ldb-2.0.8/buildtools/wafsamba/wafsamba.py b/ldb-2.0.8/buildtools/wafsamba/wafsamba.py deleted file mode 100644 index 205d5b4..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/wafsamba.py +++ /dev/null @@ -1,950 +0,0 @@ -# a waf tool to add autoconf-like macros to the configure section -# and for SAMBA_ macros for building libraries, binaries etc - -import os, sys, re, shutil, fnmatch -from waflib import Build, Options, Task, Utils, TaskGen, Logs, Context, Errors -from waflib.Configure import conf -from waflib.Logs import debug -from samba_utils import SUBST_VARS_RECURSIVE -TaskGen.task_gen.apply_verif = Utils.nada - -# bring in the other samba modules -from samba_utils import * -from samba_utils import symlink -from samba_version import * -from samba_autoconf import * -from samba_patterns import * -from samba_pidl import * -from samba_autoproto import * -from samba_python import * -from samba_perl import * -from samba_deps import * -from samba_bundled import * -from samba_third_party import * -import samba_cross -import samba_install -import samba_conftests -import samba_abi -import samba_headers -import generic_cc -import samba_dist -import samba_wildcard -import symbols -import pkgconfig -import configure_file -import samba_waf18 - -LIB_PATH="shared" - -os.environ['PYTHONUNBUFFERED'] = '1' - -if Context.HEXVERSION not in (0x2001200,): - Logs.error(''' -Please use the version of waf that comes with Samba, not -a system installed version. See http://wiki.samba.org/index.php/Waf -for details. - -Alternatively, please run ./configure and make as usual. That will -call the right version of waf.''') - sys.exit(1) - -@conf -def SAMBA_BUILD_ENV(conf): - '''create the samba build environment''' - conf.env.BUILD_DIRECTORY = conf.bldnode.abspath() - mkdir_p(os.path.join(conf.env.BUILD_DIRECTORY, LIB_PATH)) - mkdir_p(os.path.join(conf.env.BUILD_DIRECTORY, LIB_PATH, "private")) - mkdir_p(os.path.join(conf.env.BUILD_DIRECTORY, "modules")) - mkdir_p(os.path.join(conf.env.BUILD_DIRECTORY, 'python/samba/dcerpc')) - # this allows all of the bin/shared and bin/python targets - # to be expressed in terms of build directory paths - mkdir_p(os.path.join(conf.env.BUILD_DIRECTORY, 'default')) - for (source, target) in [('shared', 'shared'), ('modules', 'modules'), ('python', 'python')]: - link_target = os.path.join(conf.env.BUILD_DIRECTORY, 'default/' + target) - if not os.path.lexists(link_target): - symlink('../' + source, link_target) - - # get perl to put the blib files in the build directory - blib_bld = os.path.join(conf.env.BUILD_DIRECTORY, 'default/pidl/blib') - blib_src = os.path.join(conf.srcnode.abspath(), 'pidl/blib') - mkdir_p(blib_bld + '/man1') - mkdir_p(blib_bld + '/man3') - if os.path.islink(blib_src): - os.unlink(blib_src) - elif os.path.exists(blib_src): - shutil.rmtree(blib_src) - - -def ADD_INIT_FUNCTION(bld, subsystem, target, init_function): - '''add an init_function to the list for a subsystem''' - if init_function is None: - return - bld.ASSERT(subsystem is not None, "You must specify a subsystem for init_function '%s'" % init_function) - cache = LOCAL_CACHE(bld, 'INIT_FUNCTIONS') - if not subsystem in cache: - cache[subsystem] = [] - cache[subsystem].append( { 'TARGET':target, 'INIT_FUNCTION':init_function } ) -Build.BuildContext.ADD_INIT_FUNCTION = ADD_INIT_FUNCTION - - -def generate_empty_file(task): - task.outputs[0].write('') - return 0 - -################################################################# -def SAMBA_LIBRARY(bld, libname, source, - deps='', - public_deps='', - includes='', - public_headers=None, - public_headers_install=True, - private_headers=None, - header_path=None, - pc_files=None, - vnum=None, - soname=None, - cflags='', - cflags_end=None, - ldflags='', - external_library=False, - realname=None, - keep_underscore=False, - autoproto=None, - autoproto_extra_source='', - group='main', - depends_on='', - local_include=True, - global_include=True, - vars=None, - subdir=None, - install_path=None, - install=True, - pyembed=False, - pyext=False, - target_type='LIBRARY', - bundled_extension=False, - bundled_name=None, - link_name=None, - abi_directory=None, - abi_match=None, - hide_symbols=False, - manpages=None, - private_library=False, - grouping_library=False, - allow_undefined_symbols=False, - allow_warnings=False, - enabled=True): - '''define a Samba library''' - - if private_library and public_headers: - raise Errors.WafError("private library '%s' must not have public header files" % - libname) - - if LIB_MUST_BE_PRIVATE(bld, libname): - private_library = True - - if not enabled: - SET_TARGET_TYPE(bld, libname, 'DISABLED') - return - - source = bld.EXPAND_VARIABLES(source, vars=vars) - if subdir: - source = bld.SUBDIR(subdir, source) - - # remember empty libraries, so we can strip the dependencies - if ((source == '') or (source == [])): - if deps == '' and public_deps == '': - SET_TARGET_TYPE(bld, libname, 'EMPTY') - return - empty_c = libname + '.empty.c' - bld.SAMBA_GENERATOR('%s_empty_c' % libname, - rule=generate_empty_file, - target=empty_c) - source=empty_c - - if BUILTIN_LIBRARY(bld, libname): - obj_target = libname - else: - obj_target = libname + '.objlist' - - if group == 'libraries': - subsystem_group = 'main' - else: - subsystem_group = group - - # first create a target for building the object files for this library - # by separating in this way, we avoid recompiling the C files - # separately for the install library and the build library - bld.SAMBA_SUBSYSTEM(obj_target, - source = source, - deps = deps, - public_deps = public_deps, - includes = includes, - public_headers = public_headers, - public_headers_install = public_headers_install, - private_headers= private_headers, - header_path = header_path, - cflags = cflags, - cflags_end = cflags_end, - group = subsystem_group, - autoproto = autoproto, - autoproto_extra_source=autoproto_extra_source, - depends_on = depends_on, - hide_symbols = hide_symbols, - allow_warnings = allow_warnings, - pyembed = pyembed, - pyext = pyext, - local_include = local_include, - global_include = global_include) - - if BUILTIN_LIBRARY(bld, libname): - return - - if not SET_TARGET_TYPE(bld, libname, target_type): - return - - # the library itself will depend on that object target - deps += ' ' + public_deps - deps = TO_LIST(deps) - deps.append(obj_target) - - realname = bld.map_shlib_extension(realname, python=(target_type=='PYTHON')) - link_name = bld.map_shlib_extension(link_name, python=(target_type=='PYTHON')) - - # we don't want any public libraries without version numbers - if (not private_library and target_type != 'PYTHON' and not realname): - if vnum is None and soname is None: - raise Errors.WafError("public library '%s' must have a vnum" % - libname) - if pc_files is None: - raise Errors.WafError("public library '%s' must have pkg-config file" % - libname) - if public_headers is None: - raise Errors.WafError("public library '%s' must have header files" % - libname) - - if bundled_name is not None: - pass - elif target_type == 'PYTHON' or realname or not private_library: - if keep_underscore: - bundled_name = libname - else: - bundled_name = libname.replace('_', '-') - else: - assert (private_library == True and realname is None) - if abi_directory or vnum or soname: - bundled_extension=True - bundled_name = PRIVATE_NAME(bld, libname.replace('_', '-'), - bundled_extension, private_library) - - ldflags = TO_LIST(ldflags) - if bld.env['ENABLE_RELRO'] is True: - ldflags.extend(TO_LIST('-Wl,-z,relro,-z,now')) - - features = 'c cshlib symlink_lib install_lib' - if pyext: - features += ' pyext' - if pyembed: - features += ' pyembed' - - if abi_directory: - features += ' abi_check' - - if pyembed and bld.env['PYTHON_SO_ABI_FLAG']: - # For ABI checking, we don't care about the Python version. - # Remove the Python ABI tag (e.g. ".cpython-35m") - abi_flag = bld.env['PYTHON_SO_ABI_FLAG'] - replacement = '' - version_libname = libname.replace(abi_flag, replacement) - else: - version_libname = libname - - vscript = None - if bld.env.HAVE_LD_VERSION_SCRIPT: - if private_library: - version = "%s_%s" % (Context.g_module.APPNAME, Context.g_module.VERSION) - elif vnum: - version = "%s_%s" % (libname, vnum) - else: - version = None - if version: - vscript = "%s.vscript" % libname - bld.ABI_VSCRIPT(version_libname, abi_directory, version, vscript, - abi_match) - fullname = apply_pattern(bundled_name, bld.env.cshlib_PATTERN) - fullpath = bld.path.find_or_declare(fullname) - vscriptpath = bld.path.find_or_declare(vscript) - if not fullpath: - raise Errors.WafError("unable to find fullpath for %s" % fullname) - if not vscriptpath: - raise Errors.WafError("unable to find vscript path for %s" % vscript) - bld.add_manual_dependency(fullpath, vscriptpath) - if bld.is_install: - # also make the .inst file depend on the vscript - instname = apply_pattern(bundled_name + '.inst', bld.env.cshlib_PATTERN) - bld.add_manual_dependency(bld.path.find_or_declare(instname), bld.path.find_or_declare(vscript)) - vscript = os.path.join(bld.path.abspath(bld.env), vscript) - - bld.SET_BUILD_GROUP(group) - t = bld( - features = features, - source = [], - target = bundled_name, - depends_on = depends_on, - samba_ldflags = ldflags, - samba_deps = deps, - samba_includes = includes, - version_script = vscript, - version_libname = version_libname, - local_include = local_include, - global_include = global_include, - vnum = vnum, - soname = soname, - install_path = None, - samba_inst_path = install_path, - name = libname, - samba_realname = realname, - samba_install = install, - abi_directory = "%s/%s" % (bld.path.abspath(), abi_directory), - abi_match = abi_match, - private_library = private_library, - grouping_library=grouping_library, - allow_undefined_symbols=allow_undefined_symbols - ) - - if realname and not link_name: - link_name = 'shared/%s' % realname - - if link_name: - if 'waflib.extras.compat15' in sys.modules: - link_name = 'default/' + link_name - t.link_name = link_name - - if pc_files is not None and not private_library: - if pyembed: - bld.PKG_CONFIG_FILES(pc_files, vnum=vnum, extra_name=bld.env['PYTHON_SO_ABI_FLAG']) - else: - bld.PKG_CONFIG_FILES(pc_files, vnum=vnum) - - if (manpages is not None and 'XSLTPROC_MANPAGES' in bld.env and - bld.env['XSLTPROC_MANPAGES']): - bld.MANPAGES(manpages, install) - - -Build.BuildContext.SAMBA_LIBRARY = SAMBA_LIBRARY - - -################################################################# -def SAMBA_BINARY(bld, binname, source, - deps='', - includes='', - public_headers=None, - private_headers=None, - header_path=None, - modules=None, - ldflags=None, - cflags='', - cflags_end=None, - autoproto=None, - use_hostcc=False, - use_global_deps=True, - compiler=None, - group='main', - manpages=None, - local_include=True, - global_include=True, - subsystem_name=None, - pyembed=False, - vars=None, - subdir=None, - install=True, - install_path=None, - enabled=True): - '''define a Samba binary''' - - if not enabled: - SET_TARGET_TYPE(bld, binname, 'DISABLED') - return - - if not SET_TARGET_TYPE(bld, binname, 'BINARY'): - return - - features = 'c cprogram symlink_bin install_bin' - if pyembed: - features += ' pyembed' - - obj_target = binname + '.objlist' - - source = bld.EXPAND_VARIABLES(source, vars=vars) - if subdir: - source = bld.SUBDIR(subdir, source) - source = unique_list(TO_LIST(source)) - - if group == 'binaries': - subsystem_group = 'main' - else: - subsystem_group = group - - # only specify PIE flags for binaries - pie_cflags = cflags - pie_ldflags = TO_LIST(ldflags) - if bld.env['ENABLE_PIE'] is True: - pie_cflags += ' -fPIE' - pie_ldflags.extend(TO_LIST('-pie')) - if bld.env['ENABLE_RELRO'] is True: - pie_ldflags.extend(TO_LIST('-Wl,-z,relro,-z,now')) - - # first create a target for building the object files for this binary - # by separating in this way, we avoid recompiling the C files - # separately for the install binary and the build binary - bld.SAMBA_SUBSYSTEM(obj_target, - source = source, - deps = deps, - includes = includes, - cflags = pie_cflags, - cflags_end = cflags_end, - group = subsystem_group, - autoproto = autoproto, - subsystem_name = subsystem_name, - local_include = local_include, - global_include = global_include, - use_hostcc = use_hostcc, - pyext = pyembed, - use_global_deps= use_global_deps) - - bld.SET_BUILD_GROUP(group) - - # the binary itself will depend on that object target - deps = TO_LIST(deps) - deps.append(obj_target) - - t = bld( - features = features, - source = [], - target = binname, - samba_deps = deps, - samba_includes = includes, - local_include = local_include, - global_include = global_include, - samba_modules = modules, - top = True, - samba_subsystem= subsystem_name, - install_path = None, - samba_inst_path= install_path, - samba_install = install, - samba_ldflags = pie_ldflags - ) - - if manpages is not None and 'XSLTPROC_MANPAGES' in bld.env and bld.env['XSLTPROC_MANPAGES']: - bld.MANPAGES(manpages, install) - -Build.BuildContext.SAMBA_BINARY = SAMBA_BINARY - - -################################################################# -def SAMBA_MODULE(bld, modname, source, - deps='', - includes='', - subsystem=None, - init_function=None, - module_init_name='samba_init_module', - autoproto=None, - autoproto_extra_source='', - cflags='', - cflags_end=None, - internal_module=True, - local_include=True, - global_include=True, - vars=None, - subdir=None, - enabled=True, - pyembed=False, - manpages=None, - allow_undefined_symbols=False, - allow_warnings=False, - install=True - ): - '''define a Samba module.''' - - bld.ASSERT(subsystem, "You must specify a subsystem for SAMBA_MODULE(%s)" % modname) - - source = bld.EXPAND_VARIABLES(source, vars=vars) - if subdir: - source = bld.SUBDIR(subdir, source) - - if internal_module or BUILTIN_LIBRARY(bld, modname): - # Do not create modules for disabled subsystems - if GET_TARGET_TYPE(bld, subsystem) == 'DISABLED': - return - bld.SAMBA_SUBSYSTEM(modname, source, - deps=deps, - includes=includes, - autoproto=autoproto, - autoproto_extra_source=autoproto_extra_source, - cflags=cflags, - cflags_end=cflags_end, - local_include=local_include, - global_include=global_include, - allow_warnings=allow_warnings, - enabled=enabled) - - bld.ADD_INIT_FUNCTION(subsystem, modname, init_function) - return - - if not enabled: - SET_TARGET_TYPE(bld, modname, 'DISABLED') - return - - # Do not create modules for disabled subsystems - if GET_TARGET_TYPE(bld, subsystem) == 'DISABLED': - return - - realname = modname - deps += ' ' + subsystem - while realname.startswith("lib"+subsystem+"_"): - realname = realname[len("lib"+subsystem+"_"):] - while realname.startswith(subsystem+"_"): - realname = realname[len(subsystem+"_"):] - - build_name = "%s_module_%s" % (subsystem, realname) - - realname = bld.make_libname(realname) - while realname.startswith("lib"): - realname = realname[len("lib"):] - - build_link_name = "modules/%s/%s" % (subsystem, realname) - - if init_function: - cflags += " -D%s=%s" % (init_function, module_init_name) - - bld.SAMBA_LIBRARY(modname, - source, - deps=deps, - includes=includes, - cflags=cflags, - cflags_end=cflags_end, - realname = realname, - autoproto = autoproto, - local_include=local_include, - global_include=global_include, - vars=vars, - bundled_name=build_name, - link_name=build_link_name, - install_path="${MODULESDIR}/%s" % subsystem, - pyembed=pyembed, - manpages=manpages, - allow_undefined_symbols=allow_undefined_symbols, - allow_warnings=allow_warnings, - install=install - ) - - -Build.BuildContext.SAMBA_MODULE = SAMBA_MODULE - - -################################################################# -def SAMBA_SUBSYSTEM(bld, modname, source, - deps='', - public_deps='', - includes='', - public_headers=None, - public_headers_install=True, - private_headers=None, - header_path=None, - cflags='', - cflags_end=None, - group='main', - init_function_sentinel=None, - autoproto=None, - autoproto_extra_source='', - depends_on='', - local_include=True, - local_include_first=True, - global_include=True, - subsystem_name=None, - enabled=True, - use_hostcc=False, - use_global_deps=True, - vars=None, - subdir=None, - hide_symbols=False, - allow_warnings=False, - pyext=False, - pyembed=False): - '''define a Samba subsystem''' - - if not enabled: - SET_TARGET_TYPE(bld, modname, 'DISABLED') - return - - # remember empty subsystems, so we can strip the dependencies - if ((source == '') or (source == [])): - if deps == '' and public_deps == '': - SET_TARGET_TYPE(bld, modname, 'EMPTY') - return - empty_c = modname + '.empty.c' - bld.SAMBA_GENERATOR('%s_empty_c' % modname, - rule=generate_empty_file, - target=empty_c) - source=empty_c - - if not SET_TARGET_TYPE(bld, modname, 'SUBSYSTEM'): - return - - source = bld.EXPAND_VARIABLES(source, vars=vars) - if subdir: - source = bld.SUBDIR(subdir, source) - source = unique_list(TO_LIST(source)) - - deps += ' ' + public_deps - - bld.SET_BUILD_GROUP(group) - - features = 'c' - if pyext: - features += ' pyext' - if pyembed: - features += ' pyembed' - - t = bld( - features = features, - source = source, - target = modname, - samba_cflags = CURRENT_CFLAGS(bld, modname, cflags, - allow_warnings=allow_warnings, - hide_symbols=hide_symbols), - depends_on = depends_on, - samba_deps = TO_LIST(deps), - samba_includes = includes, - local_include = local_include, - local_include_first = local_include_first, - global_include = global_include, - samba_subsystem= subsystem_name, - samba_use_hostcc = use_hostcc, - samba_use_global_deps = use_global_deps, - ) - - if cflags_end is not None: - t.samba_cflags.extend(TO_LIST(cflags_end)) - - if autoproto is not None: - bld.SAMBA_AUTOPROTO(autoproto, source + TO_LIST(autoproto_extra_source)) - if public_headers is not None: - bld.PUBLIC_HEADERS(public_headers, header_path=header_path, - public_headers_install=public_headers_install) - return t - - -Build.BuildContext.SAMBA_SUBSYSTEM = SAMBA_SUBSYSTEM - - -def SAMBA_GENERATOR(bld, name, rule, source='', target='', - group='generators', enabled=True, - public_headers=None, - public_headers_install=True, - private_headers=None, - header_path=None, - vars=None, - dep_vars=[], - always=False): - '''A generic source generator target''' - - if not SET_TARGET_TYPE(bld, name, 'GENERATOR'): - return - - if not enabled: - return - - dep_vars.append('ruledeps') - dep_vars.append('SAMBA_GENERATOR_VARS') - - bld.SET_BUILD_GROUP(group) - t = bld( - rule=rule, - source=bld.EXPAND_VARIABLES(source, vars=vars), - target=target, - shell=isinstance(rule, str), - update_outputs=True, - before='c', - ext_out='.c', - samba_type='GENERATOR', - dep_vars = dep_vars, - name=name) - - if vars is None: - vars = {} - t.env.SAMBA_GENERATOR_VARS = vars - - if always: - t.always = True - - if public_headers is not None: - bld.PUBLIC_HEADERS(public_headers, header_path=header_path, - public_headers_install=public_headers_install) - return t -Build.BuildContext.SAMBA_GENERATOR = SAMBA_GENERATOR - - - -@Utils.run_once -def SETUP_BUILD_GROUPS(bld): - '''setup build groups used to ensure that the different build - phases happen consecutively''' - bld.p_ln = bld.srcnode # we do want to see all targets! - bld.env['USING_BUILD_GROUPS'] = True - bld.add_group('setup') - bld.add_group('build_compiler_source') - bld.add_group('vscripts') - bld.add_group('base_libraries') - bld.add_group('generators') - bld.add_group('compiler_prototypes') - bld.add_group('compiler_libraries') - bld.add_group('build_compilers') - bld.add_group('build_source') - bld.add_group('prototypes') - bld.add_group('headers') - bld.add_group('main') - bld.add_group('symbolcheck') - bld.add_group('syslibcheck') - bld.add_group('final') -Build.BuildContext.SETUP_BUILD_GROUPS = SETUP_BUILD_GROUPS - - -def SET_BUILD_GROUP(bld, group): - '''set the current build group''' - if not 'USING_BUILD_GROUPS' in bld.env: - return - bld.set_group(group) -Build.BuildContext.SET_BUILD_GROUP = SET_BUILD_GROUP - - - -def SAMBA_SCRIPT(bld, name, pattern, installdir, installname=None): - '''used to copy scripts from the source tree into the build directory - for use by selftest''' - - source = bld.path.ant_glob(pattern, flat=True) - - bld.SET_BUILD_GROUP('build_source') - for s in TO_LIST(source): - iname = s - if installname is not None: - iname = installname - target = os.path.join(installdir, iname) - tgtdir = os.path.dirname(os.path.join(bld.srcnode.abspath(bld.env), '..', target)) - mkdir_p(tgtdir) - link_src = os.path.normpath(os.path.join(bld.path.abspath(), s)) - link_dst = os.path.join(tgtdir, os.path.basename(iname)) - if os.path.islink(link_dst) and os.readlink(link_dst) == link_src: - continue - if os.path.islink(link_dst): - os.unlink(link_dst) - Logs.info("symlink: %s -> %s/%s" % (s, installdir, iname)) - symlink(link_src, link_dst) -Build.BuildContext.SAMBA_SCRIPT = SAMBA_SCRIPT - - -def copy_and_fix_python_path(task): - pattern='sys.path.insert(0, "bin/python")' - if task.env["PYTHONARCHDIR"] in sys.path and task.env["PYTHONDIR"] in sys.path: - replacement = "" - elif task.env["PYTHONARCHDIR"] == task.env["PYTHONDIR"]: - replacement="""sys.path.insert(0, "%s")""" % task.env["PYTHONDIR"] - else: - replacement="""sys.path.insert(0, "%s") -sys.path.insert(1, "%s")""" % (task.env["PYTHONARCHDIR"], task.env["PYTHONDIR"]) - - if task.env["PYTHON"][0].startswith("/"): - replacement_shebang = "#!%s\n" % task.env["PYTHON"][0] - else: - replacement_shebang = "#!/usr/bin/env %s\n" % task.env["PYTHON"][0] - - installed_location=task.outputs[0].bldpath(task.env) - source_file = open(task.inputs[0].srcpath(task.env)) - installed_file = open(installed_location, 'w') - lineno = 0 - for line in source_file: - newline = line - if (lineno == 0 and - line[:2] == "#!"): - newline = replacement_shebang - elif pattern in line: - newline = line.replace(pattern, replacement) - installed_file.write(newline) - lineno = lineno + 1 - installed_file.close() - os.chmod(installed_location, 0o755) - return 0 - -def copy_and_fix_perl_path(task): - pattern='use lib "$RealBin/lib";' - - replacement = "" - if not task.env["PERL_LIB_INSTALL_DIR"] in task.env["PERL_INC"]: - replacement = 'use lib "%s";' % task.env["PERL_LIB_INSTALL_DIR"] - - if task.env["PERL"][0] == "/": - replacement_shebang = "#!%s\n" % task.env["PERL"] - else: - replacement_shebang = "#!/usr/bin/env %s\n" % task.env["PERL"] - - installed_location=task.outputs[0].bldpath(task.env) - source_file = open(task.inputs[0].srcpath(task.env)) - installed_file = open(installed_location, 'w') - lineno = 0 - for line in source_file: - newline = line - if lineno == 0 and task.env["PERL_SPECIFIED"] == True and line[:2] == "#!": - newline = replacement_shebang - elif pattern in line: - newline = line.replace(pattern, replacement) - installed_file.write(newline) - lineno = lineno + 1 - installed_file.close() - os.chmod(installed_location, 0o755) - return 0 - - -def install_file(bld, destdir, file, chmod=MODE_644, flat=False, - python_fixup=False, perl_fixup=False, - destname=None, base_name=None): - '''install a file''' - if not isinstance(file, str): - file = file.abspath() - destdir = bld.EXPAND_VARIABLES(destdir) - if not destname: - destname = file - if flat: - destname = os.path.basename(destname) - dest = os.path.join(destdir, destname) - if python_fixup: - # fix the path python will use to find Samba modules - inst_file = file + '.inst' - bld.SAMBA_GENERATOR('python_%s' % destname, - rule=copy_and_fix_python_path, - dep_vars=["PYTHON","PYTHON_SPECIFIED","PYTHONDIR","PYTHONARCHDIR"], - source=file, - target=inst_file) - file = inst_file - if perl_fixup: - # fix the path perl will use to find Samba modules - inst_file = file + '.inst' - bld.SAMBA_GENERATOR('perl_%s' % destname, - rule=copy_and_fix_perl_path, - dep_vars=["PERL","PERL_SPECIFIED","PERL_LIB_INSTALL_DIR"], - source=file, - target=inst_file) - file = inst_file - if base_name: - file = os.path.join(base_name, file) - bld.install_as(dest, file, chmod=chmod) - - -def INSTALL_FILES(bld, destdir, files, chmod=MODE_644, flat=False, - python_fixup=False, perl_fixup=False, - destname=None, base_name=None): - '''install a set of files''' - for f in TO_LIST(files): - install_file(bld, destdir, f, chmod=chmod, flat=flat, - python_fixup=python_fixup, perl_fixup=perl_fixup, - destname=destname, base_name=base_name) -Build.BuildContext.INSTALL_FILES = INSTALL_FILES - - -def INSTALL_WILDCARD(bld, destdir, pattern, chmod=MODE_644, flat=False, - python_fixup=False, exclude=None, trim_path=None): - '''install a set of files matching a wildcard pattern''' - files=TO_LIST(bld.path.ant_glob(pattern, flat=True)) - if trim_path: - files2 = [] - for f in files: - files2.append(os_path_relpath(f, trim_path)) - files = files2 - - if exclude: - for f in files[:]: - if fnmatch.fnmatch(f, exclude): - files.remove(f) - INSTALL_FILES(bld, destdir, files, chmod=chmod, flat=flat, - python_fixup=python_fixup, base_name=trim_path) -Build.BuildContext.INSTALL_WILDCARD = INSTALL_WILDCARD - -def INSTALL_DIR(bld, path, chmod=0o755, env=None): - """Install a directory if it doesn't exist, always set permissions.""" - - if not path: - return [] - - destpath = bld.EXPAND_VARIABLES(path) - if Options.options.destdir: - destpath = os.path.join(Options.options.destdir, destpath.lstrip(os.sep)) - - if bld.is_install > 0: - if not os.path.isdir(destpath): - try: - Logs.info('* create %s', destpath) - os.makedirs(destpath) - os.chmod(destpath, chmod) - except OSError as e: - if not os.path.isdir(destpath): - raise Errors.WafError("Cannot create the folder '%s' (error: %s)" % (path, e)) -Build.BuildContext.INSTALL_DIR = INSTALL_DIR - -def INSTALL_DIRS(bld, destdir, dirs, chmod=0o755, env=None): - '''install a set of directories''' - destdir = bld.EXPAND_VARIABLES(destdir) - dirs = bld.EXPAND_VARIABLES(dirs) - for d in TO_LIST(dirs): - INSTALL_DIR(bld, os.path.join(destdir, d), chmod, env) -Build.BuildContext.INSTALL_DIRS = INSTALL_DIRS - - -def MANPAGES(bld, manpages, install): - '''build and install manual pages''' - bld.env.MAN_XSL = 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl' - for m in manpages.split(): - source = m + '.xml' - bld.SAMBA_GENERATOR(m, - source=source, - target=m, - group='final', - rule='${XSLTPROC} --xinclude -o ${TGT} --nonet ${MAN_XSL} ${SRC}' - ) - if install: - bld.INSTALL_FILES('${MANDIR}/man%s' % m[-1], m, flat=True) -Build.BuildContext.MANPAGES = MANPAGES - -def SAMBAMANPAGES(bld, manpages, extra_source=None): - '''build and install manual pages''' - bld.env.SAMBA_EXPAND_XSL = bld.srcnode.abspath() + '/docs-xml/xslt/expand-sambadoc.xsl' - bld.env.SAMBA_MAN_XSL = bld.srcnode.abspath() + '/docs-xml/xslt/man.xsl' - bld.env.SAMBA_CATALOG = bld.bldnode.abspath() + '/docs-xml/build/catalog.xml' - bld.env.SAMBA_CATALOGS = 'file:///etc/xml/catalog file:///usr/local/share/xml/catalog file://' + bld.env.SAMBA_CATALOG - - for m in manpages.split(): - source = m + '.xml' - if extra_source is not None: - source = [source, extra_source] - bld.SAMBA_GENERATOR(m, - source=source, - target=m, - group='final', - dep_vars=['SAMBA_MAN_XSL', 'SAMBA_EXPAND_XSL', 'SAMBA_CATALOG'], - rule='''XML_CATALOG_FILES="${SAMBA_CATALOGS}" - export XML_CATALOG_FILES - ${XSLTPROC} --xinclude --stringparam noreference 0 -o ${TGT}.xml --nonet ${SAMBA_EXPAND_XSL} ${SRC[0].abspath(env)} - ${XSLTPROC} --nonet -o ${TGT} ${SAMBA_MAN_XSL} ${TGT}.xml''' - ) - bld.INSTALL_FILES('${MANDIR}/man%s' % m[-1], m, flat=True) -Build.BuildContext.SAMBAMANPAGES = SAMBAMANPAGES - -@after('apply_link') -@feature('cshlib') -def apply_bundle_remove_dynamiclib_patch(self): - if self.env['MACBUNDLE'] or getattr(self,'mac_bundle',False): - if not getattr(self,'vnum',None): - try: - self.env['LINKFLAGS'].remove('-dynamiclib') - self.env['LINKFLAGS'].remove('-single_module') - except ValueError: - pass diff --git a/ldb-2.0.8/buildtools/wafsamba/wscript b/ldb-2.0.8/buildtools/wafsamba/wscript deleted file mode 100644 index 8014716..0000000 --- a/ldb-2.0.8/buildtools/wafsamba/wscript +++ /dev/null @@ -1,611 +0,0 @@ -#!/usr/bin/env python - -# this is a base set of waf rules that everything else pulls in first - -import os, sys -from waflib import Configure, Logs, Options, Utils, Context, Errors -import wafsamba -from samba_utils import os_path_relpath -from optparse import SUPPRESS_HELP - -# this forces configure to be re-run if any of the configure -# sections of the build scripts change. We have to check -# for this in sys.argv as options have not yet been parsed when -# we need to set this. This is off by default until some issues -# are resolved related to WAFCACHE. It will need a lot of testing -# before it is enabled by default. -if '--enable-auto-reconfigure' in sys.argv: - Configure.autoconfig = 'clobber' - -def default_value(option, default=''): - if option in Options.options.__dict__: - return Options.options.__dict__[option] - return default - -def options(opt): - opt.load('compiler_cc') - - opt.load('gnu_dirs') - - gr = opt.option_group('library handling options') - - gr.add_option('--bundled-libraries', - help=("comma separated list of bundled libraries. May include !LIBNAME to disable bundling a library. Can be 'NONE' or 'ALL' [auto]"), - action="store", dest='BUNDLED_LIBS', default='') - - gr.add_option('--private-libraries', - help=("comma separated list of normally public libraries to build instead as private libraries. May include !LIBNAME to disable making a library private. Can be 'NONE' or 'ALL' [auto]"), - action="store", dest='PRIVATE_LIBS', default='') - - extension_default = default_value('PRIVATE_EXTENSION_DEFAULT') - gr.add_option('--private-library-extension', - help=("name extension for private libraries [%s]" % extension_default), - action="store", dest='PRIVATE_EXTENSION', default=extension_default) - - extension_exception = default_value('PRIVATE_EXTENSION_EXCEPTION') - gr.add_option('--private-extension-exception', - help=("comma separated list of libraries to not apply extension to [%s]" % extension_exception), - action="store", dest='PRIVATE_EXTENSION_EXCEPTION', default=extension_exception) - - builtin_default = default_value('BUILTIN_LIBRARIES_DEFAULT') - gr.add_option('--builtin-libraries', - help=("command separated list of libraries to build directly into binaries [%s]" % builtin_default), - action="store", dest='BUILTIN_LIBRARIES', default=builtin_default) - - gr.add_option('--minimum-library-version', - help=("list of minimum system library versions (LIBNAME1:version,LIBNAME2:version)"), - action="store", dest='MINIMUM_LIBRARY_VERSION', default='') - - gr.add_option('--disable-rpath', - help=("Disable use of rpath for build binaries"), - action="store_true", dest='disable_rpath_build', default=False) - gr.add_option('--disable-rpath-install', - help=("Disable use of rpath for library path in installed files"), - action="store_true", dest='disable_rpath_install', default=False) - gr.add_option('--disable-rpath-private-install', - help=("Disable use of rpath for private library path in installed files"), - action="store_true", dest='disable_rpath_private_install', default=False) - gr.add_option('--nonshared-binary', - help=("Disable use of shared libs for the listed binaries"), - action="store", dest='NONSHARED_BINARIES', default='') - gr.add_option('--disable-symbol-versions', - help=("Disable use of the --version-script linker option"), - action="store_true", dest='disable_symbol_versions', default=False) - - opt.add_option('--with-modulesdir', - help=("modules directory [PREFIX/modules]"), - action="store", dest='MODULESDIR', default='${PREFIX}/modules') - - opt.add_option('--with-privatelibdir', - help=("private library directory [PREFIX/lib/%s]" % Context.g_module.APPNAME), - action="store", dest='PRIVATELIBDIR', default=None) - - opt.add_option('--with-libiconv', - help='additional directory to search for libiconv', - action='store', dest='iconv_open', default='/usr/local', - match = ['Checking for library iconv', 'Checking for iconv_open', 'Checking for header iconv.h']) - opt.add_option('--without-gettext', - help=("Disable use of gettext"), - action="store_true", dest='disable_gettext', default=False) - - gr = opt.option_group('developer options') - - gr.add_option('-C', - help='enable configure cacheing', - action='store_true', dest='enable_configure_cache') - gr.add_option('--enable-auto-reconfigure', - help='enable automatic reconfigure on build', - action='store_true', dest='enable_auto_reconfigure') - gr.add_option('--enable-debug', - help=("Turn on debugging symbols"), - action="store_true", dest='debug', default=False) - gr.add_option('--enable-developer', - help=("Turn on developer warnings and debugging"), - action="store_true", dest='developer', default=False) - opt.add_option('--enable-coverage', - help=("enable options necessary for code coverage " - "reporting on selftest (default=no)"), - action="store_true", dest='enable_coverage', default=False) - def picky_developer_callback(option, opt_str, value, parser): - parser.values.developer = True - parser.values.picky_developer = True - gr.add_option('--picky-developer', - help=("Treat all warnings as errors (enable -Werror)"), - action="callback", callback=picky_developer_callback, - dest='picky_developer', default=False) - gr.add_option('--fatal-errors', - help=("Stop compilation on first error (enable -Wfatal-errors)"), - action="store_true", dest='fatal_errors', default=False) - gr.add_option('--enable-gccdeps', - help=("Enable use of gcc -MD dependency module"), - action="store_true", dest='enable_gccdeps', default=True) - gr.add_option('--pedantic', - help=("Enable even more compiler warnings"), - action='store_true', dest='pedantic', default=False) - gr.add_option('--git-local-changes', - help=("mark version with + if local git changes"), - action='store_true', dest='GIT_LOCAL_CHANGES', default=False) - gr.add_option('--address-sanitizer', - help=("Enable address sanitizer compile and linker flags"), - action="store_true", dest='address_sanitizer', default=False) - gr.add_option('--undefined-sanitizer', - help=("Enable undefined behaviour sanitizer compile and linker flags"), - action="store_true", - dest='undefined_sanitizer', - default=False) - - gr.add_option('--abi-check', - help=("Check ABI signatures for libraries"), - action='store_true', dest='ABI_CHECK', default=False) - gr.add_option('--abi-check-disable', - help=("Disable ABI checking (used with --enable-developer)"), - action='store_true', dest='ABI_CHECK_DISABLE', default=False) - gr.add_option('--abi-update', - help=("Update ABI signature files for libraries"), - action='store_true', dest='ABI_UPDATE', default=False) - - gr.add_option('--show-deps', - help=("Show dependency tree for the given target"), - dest='SHOWDEPS', default='') - - gr.add_option('--symbol-check', - help=("check symbols in object files against project rules"), - action='store_true', dest='SYMBOLCHECK', default=False) - - gr.add_option('--dup-symbol-check', - help=("check for duplicate symbols in object files and system libs (must be configured with --enable-developer)"), - action='store_true', dest='DUP_SYMBOLCHECK', default=False) - - gr.add_option('--why-needed', - help=("TARGET:DEPENDENCY check why TARGET needs DEPENDENCY"), - action='store', type='str', dest='WHYNEEDED', default=None) - - gr.add_option('--show-duplicates', - help=("Show objects which are included in multiple binaries or libraries"), - action='store_true', dest='SHOW_DUPLICATES', default=False) - - gr = opt.add_option_group('cross compilation options') - - gr.add_option('--cross-compile', - help=("configure for cross-compilation"), - action='store_true', dest='CROSS_COMPILE', default=False) - gr.add_option('--cross-execute', - help=("command prefix to use for cross-execution in configure"), - action='store', dest='CROSS_EXECUTE', default='') - gr.add_option('--cross-answers', - help=("answers to cross-compilation configuration (auto modified)"), - action='store', dest='CROSS_ANSWERS', default='') - gr.add_option('--hostcc', - help=("set host compiler when cross compiling"), - action='store', dest='HOSTCC', default=False) - - # we use SUPPRESS_HELP for these, as they are ignored, and are there only - # to allow existing RPM spec files to work - opt.add_option('--build', - help=SUPPRESS_HELP, - action='store', dest='AUTOCONF_BUILD', default='') - opt.add_option('--host', - help=SUPPRESS_HELP, - action='store', dest='AUTOCONF_HOST', default='') - opt.add_option('--target', - help=SUPPRESS_HELP, - action='store', dest='AUTOCONF_TARGET', default='') - opt.add_option('--program-prefix', - help=SUPPRESS_HELP, - action='store', dest='AUTOCONF_PROGRAM_PREFIX', default='') - opt.add_option('--disable-dependency-tracking', - help=SUPPRESS_HELP, - action='store_true', dest='AUTOCONF_DISABLE_DEPENDENCY_TRACKING', default=False) - opt.add_option('--disable-silent-rules', - help=SUPPRESS_HELP, - action='store_true', dest='AUTOCONF_DISABLE_SILENT_RULES', default=False) - - gr = opt.option_group('dist options') - gr.add_option('--sign-release', - help='sign the release tarball created by waf dist', - action='store_true', dest='SIGN_RELEASE') - gr.add_option('--tag', - help='tag release in git at the same time', - type='string', action='store', dest='TAG_RELEASE') - - opt.add_option('--disable-python', - help='do not generate python modules', - action='store_true', dest='disable_python', default=False) - - -@Utils.run_once -def configure(conf): - conf.env.hlist = [] - conf.env.srcdir = conf.srcnode.abspath() - - conf.define('SRCDIR', conf.env['srcdir']) - - conf.SETUP_CONFIGURE_CACHE(Options.options.enable_configure_cache) - - # load our local waf extensions - conf.load('gnu_dirs') - conf.load('wafsamba') - - conf.CHECK_CC_ENV() - - conf.load('compiler_c') - - conf.CHECK_STANDARD_LIBPATH() - - # we need git for 'waf dist' - conf.find_program('git', var='GIT') - - # older gcc versions (< 4.4) does not work with gccdeps, so we have to see if the .d file is generated - if Options.options.enable_gccdeps: - # stale file removal - the configuration may pick up the old .pyc file - p = os.path.join(conf.env.srcdir, 'buildtools/wafsamba/gccdeps.pyc') - if os.path.exists(p): - os.remove(p) - conf.load('gccdeps') - - # make the install paths available in environment - conf.env.LIBDIR = Options.options.LIBDIR or '${PREFIX}/lib' - conf.env.BINDIR = Options.options.BINDIR or '${PREFIX}/bin' - conf.env.SBINDIR = Options.options.SBINDIR or '${PREFIX}/sbin' - conf.env.MODULESDIR = Options.options.MODULESDIR - conf.env.PRIVATELIBDIR = Options.options.PRIVATELIBDIR - conf.env.BUNDLED_LIBS = Options.options.BUNDLED_LIBS.split(',') - conf.env.SYSTEM_LIBS = () - conf.env.PRIVATE_LIBS = Options.options.PRIVATE_LIBS.split(',') - conf.env.BUILTIN_LIBRARIES = Options.options.BUILTIN_LIBRARIES.split(',') - conf.env.NONSHARED_BINARIES = Options.options.NONSHARED_BINARIES.split(',') - - conf.env.PRIVATE_EXTENSION = Options.options.PRIVATE_EXTENSION - conf.env.PRIVATE_EXTENSION_EXCEPTION = Options.options.PRIVATE_EXTENSION_EXCEPTION.split(',') - - conf.env.CROSS_COMPILE = Options.options.CROSS_COMPILE - conf.env.CROSS_EXECUTE = Options.options.CROSS_EXECUTE - conf.env.CROSS_ANSWERS = Options.options.CROSS_ANSWERS - conf.env.HOSTCC = Options.options.HOSTCC - - conf.env.AUTOCONF_BUILD = Options.options.AUTOCONF_BUILD - conf.env.AUTOCONF_HOST = Options.options.AUTOCONF_HOST - conf.env.AUTOCONF_PROGRAM_PREFIX = Options.options.AUTOCONF_PROGRAM_PREFIX - - conf.env.disable_python = Options.options.disable_python - - if (conf.env.AUTOCONF_HOST and - conf.env.AUTOCONF_BUILD and - conf.env.AUTOCONF_BUILD != conf.env.AUTOCONF_HOST): - Logs.error('ERROR: Mismatch between --build and --host. Please use --cross-compile instead') - sys.exit(1) - if conf.env.AUTOCONF_PROGRAM_PREFIX: - Logs.error('ERROR: --program-prefix not supported') - sys.exit(1) - - # enable ABI checking for developers - conf.env.ABI_CHECK = Options.options.ABI_CHECK or Options.options.developer - if Options.options.ABI_CHECK_DISABLE: - conf.env.ABI_CHECK = False - try: - conf.find_program('gdb', mandatory=True) - except: - conf.env.ABI_CHECK = False - - conf.env.enable_coverage = Options.options.enable_coverage - if conf.env.enable_coverage: - conf.ADD_LDFLAGS('-lgcov', testflags=True) - conf.ADD_CFLAGS('--coverage', testflags=True) - # disable abi check for coverage, otherwise ld will fail - conf.env.ABI_CHECK = False - - conf.env.GIT_LOCAL_CHANGES = Options.options.GIT_LOCAL_CHANGES - - conf.CHECK_UNAME() - - # see if we can compile and run a simple C program - conf.CHECK_CODE('printf("hello world")', - define='HAVE_SIMPLE_C_PROG', - mandatory=True, - execute=True, - headers='stdio.h', - msg='Checking simple C program') - - # Try to find the right extra flags for -Werror behaviour - for f in ["-Werror", # GCC - "-errwarn=%all", # Sun Studio - "-qhalt=w", # IBM xlc - "-w2", # Tru64 - ]: - if conf.CHECK_CFLAGS([f]): - if not 'WERROR_CFLAGS' in conf.env: - conf.env['WERROR_CFLAGS'] = [] - conf.env['WERROR_CFLAGS'].extend([f]) - break - - # check which compiler/linker flags are needed for rpath support - if conf.CHECK_LDFLAGS(['-Wl,-rpath,.']): - conf.env['RPATH_ST'] = '-Wl,-rpath,%s' - elif conf.CHECK_LDFLAGS(['-Wl,-R,.']): - conf.env['RPATH_ST'] = '-Wl,-R,%s' - - # check for rpath - if conf.CHECK_LIBRARY_SUPPORT(rpath=True): - support_rpath = True - conf.env.RPATH_ON_BUILD = not Options.options.disable_rpath_build - conf.env.RPATH_ON_INSTALL = (conf.env.RPATH_ON_BUILD and - not Options.options.disable_rpath_install) - if not conf.env.PRIVATELIBDIR: - conf.env.PRIVATELIBDIR = '%s/%s' % (conf.env.LIBDIR, Context.g_module.APPNAME) - conf.env.RPATH_ON_INSTALL_PRIVATE = ( - not Options.options.disable_rpath_private_install) - else: - support_rpath = False - conf.env.RPATH_ON_INSTALL = False - conf.env.RPATH_ON_BUILD = False - conf.env.RPATH_ON_INSTALL_PRIVATE = False - if not conf.env.PRIVATELIBDIR: - # rpath is not possible so there is no sense in having a - # private library directory by default. - # the user can of course always override it. - conf.env.PRIVATELIBDIR = conf.env.LIBDIR - - if (not Options.options.disable_symbol_versions and - conf.CHECK_LIBRARY_SUPPORT(rpath=support_rpath, - version_script=True, - msg='-Wl,--version-script support')): - conf.env.HAVE_LD_VERSION_SCRIPT = True - else: - conf.env.HAVE_LD_VERSION_SCRIPT = False - - if conf.CHECK_CFLAGS(['-fvisibility=hidden']): - conf.env.VISIBILITY_CFLAGS = '-fvisibility=hidden' - conf.CHECK_CODE('''int main(void) { return 0; } - __attribute__((visibility("default"))) void vis_foo2(void) {}\n''', - cflags=conf.env.VISIBILITY_CFLAGS, - strict=True, - define='HAVE_VISIBILITY_ATTR', addmain=False) - - # check HAVE_CONSTRUCTOR_ATTRIBUTE - conf.CHECK_CODE(''' - void test_constructor_attribute(void) __attribute__ ((constructor)); - - void test_constructor_attribute(void) - { - return; - } - - int main(void) { - return 0; - } - ''', - 'HAVE_CONSTRUCTOR_ATTRIBUTE', - addmain=False, - strict=True, - msg='Checking for library constructor support') - - # check HAVE_DESTRUCTOR_ATTRIBUTE - conf.CHECK_CODE(''' - void test_destructor_attribute(void) __attribute__ ((destructor)); - - void test_destructor_attribute(void) - { - return; - } - - int main(void) { - return 0; - } - ''', - 'HAVE_DESTRUCTOR_ATTRIBUTE', - addmain=False, - strict=True, - msg='Checking for library destructor support') - - conf.CHECK_CODE(''' - void test_attribute(void) __attribute__ (()); - - void test_attribute(void) - { - return; - } - - int main(void) { - return 0; - } - ''', - 'HAVE___ATTRIBUTE__', - addmain=False, - strict=True, - msg='Checking for __attribute__') - - if sys.platform.startswith('aix'): - conf.DEFINE('_ALL_SOURCE', 1, add_to_cflags=True) - # Might not be needed if ALL_SOURCE is defined - # conf.DEFINE('_XOPEN_SOURCE', 600, add_to_cflags=True) - - # we should use the PIC options in waf instead - # Some compilo didn't support -fPIC but just print a warning - if conf.env['COMPILER_CC'] == "suncc": - conf.ADD_CFLAGS('-KPIC', testflags=True) - # we really want define here as we need to have this - # define even during the tests otherwise detection of - # boolean is broken - conf.DEFINE('_STDC_C99', 1, add_to_cflags=True) - conf.DEFINE('_XPG6', 1, add_to_cflags=True) - else: - conf.ADD_CFLAGS('-fPIC', testflags=True) - - # On Solaris 8 with suncc (at least) the flags for the linker to define the name of the - # library are not always working (if the command line is very very long and with a lot - # files) - - if conf.env['COMPILER_CC'] == "suncc": - save = conf.env['SONAME_ST'] - conf.env['SONAME_ST'] = '-Wl,-h,%s' - if not conf.CHECK_SHLIB_INTRASINC_NAME_FLAGS("Checking if flags %s are ok" % conf.env['SONAME_ST']): - conf.env['SONAME_ST'] = save - - conf.CHECK_INLINE() - - # check for pkgconfig - conf.CHECK_CFG(atleast_pkgconfig_version='0.0.0') - - conf.DEFINE('_GNU_SOURCE', 1, add_to_cflags=True) - conf.DEFINE('_XOPEN_SOURCE_EXTENDED', 1, add_to_cflags=True) - - # - # Needs to be defined before std*.h and string*.h are included - # As Python.h already brings string.h we need it in CFLAGS. - # See memset_s() details here: - # https://en.cppreference.com/w/c/string/byte/memset - # - if conf.CHECK_CFLAGS(['-D__STDC_WANT_LIB_EXT1__=1']): - conf.ADD_CFLAGS('-D__STDC_WANT_LIB_EXT1__=1') - - # on Tru64 certain features are only available with _OSF_SOURCE set to 1 - # and _XOPEN_SOURCE set to 600 - if conf.env['SYSTEM_UNAME_SYSNAME'] == 'OSF1': - conf.DEFINE('_OSF_SOURCE', 1, add_to_cflags=True) - conf.DEFINE('_XOPEN_SOURCE', 600, add_to_cflags=True) - - # SCM_RIGHTS is only avail if _XOPEN_SOURCE iÑ• defined on IRIX - if conf.env['SYSTEM_UNAME_SYSNAME'] == 'IRIX': - conf.DEFINE('_XOPEN_SOURCE', 600, add_to_cflags=True) - conf.DEFINE('_BSD_TYPES', 1, add_to_cflags=True) - - # Try to find the right extra flags for C99 initialisers - for f in ["", "-AC99", "-qlanglvl=extc99", "-qlanglvl=stdc99", "-c99"]: - if conf.CHECK_CFLAGS([f], ''' -struct foo {int x;char y;}; -struct foo bar = { .y = 'X', .x = 1 }; -'''): - if f != "": - conf.ADD_CFLAGS(f) - break - - # get the base headers we'll use for the rest of the tests - conf.CHECK_HEADERS('stdio.h sys/types.h sys/stat.h stdlib.h stddef.h memory.h string.h', - add_headers=True) - conf.CHECK_HEADERS('strings.h inttypes.h stdint.h unistd.h minix/config.h', add_headers=True) - conf.CHECK_HEADERS('ctype.h', add_headers=True) - - if sys.platform != 'darwin': - conf.CHECK_HEADERS('standards.h', add_headers=True) - - conf.CHECK_HEADERS('stdbool.h stdint.h stdarg.h vararg.h', add_headers=True) - conf.CHECK_HEADERS('limits.h assert.h') - - # see if we need special largefile flags - if not conf.CHECK_LARGEFILE(): - raise Errors.WafError('Samba requires large file support support, but not available on this platform: sizeof(off_t) < 8') - - if conf.env.HAVE_STDDEF_H and conf.env.HAVE_STDLIB_H: - conf.DEFINE('STDC_HEADERS', 1) - - conf.CHECK_HEADERS('sys/time.h time.h', together=True) - - if conf.env.HAVE_SYS_TIME_H and conf.env.HAVE_TIME_H: - conf.DEFINE('TIME_WITH_SYS_TIME', 1) - - # cope with different extensions for libraries - (root, ext) = os.path.splitext(conf.env.cshlib_PATTERN) - if ext[0] == '.': - conf.define('SHLIBEXT', ext[1:], quote=True) - else: - conf.define('SHLIBEXT', "so", quote=True) - - # First try a header check for cross-compile friendlyness - conf.CHECK_CODE(code = """#ifdef __BYTE_ORDER - #define B __BYTE_ORDER - #elif defined(BYTE_ORDER) - #define B BYTE_ORDER - #endif - - #ifdef __LITTLE_ENDIAN - #define LITTLE __LITTLE_ENDIAN - #elif defined(LITTLE_ENDIAN) - #define LITTLE LITTLE_ENDIAN - #endif - - #if !defined(LITTLE) || !defined(B) || LITTLE != B - #error Not little endian. - #endif - int main(void) { return 0; }\n""", - addmain=False, - headers="endian.h sys/endian.h", - define="HAVE_LITTLE_ENDIAN") - conf.CHECK_CODE(code = """#ifdef __BYTE_ORDER - #define B __BYTE_ORDER - #elif defined(BYTE_ORDER) - #define B BYTE_ORDER - #endif - - #ifdef __BIG_ENDIAN - #define BIG __BIG_ENDIAN - #elif defined(BIG_ENDIAN) - #define BIG BIG_ENDIAN - #endif - - #if !defined(BIG) || !defined(B) || BIG != B - #error Not big endian. - #endif - int main(void) { return 0; }\n""", - addmain=False, - headers="endian.h sys/endian.h", - define="HAVE_BIG_ENDIAN") - - if not conf.CONFIG_SET("HAVE_BIG_ENDIAN") and not conf.CONFIG_SET("HAVE_LITTLE_ENDIAN"): - # That didn't work! Do runtime test. - conf.CHECK_CODE("""union { int i; char c[sizeof(int)]; } u; - u.i = 0x01020304; - return u.c[0] == 0x04 && u.c[1] == 0x03 && u.c[2] == 0x02 && u.c[3] == 0x01 ? 0 : 1;""", - addmain=True, execute=True, - define='HAVE_LITTLE_ENDIAN', - msg="Checking for HAVE_LITTLE_ENDIAN - runtime") - conf.CHECK_CODE("""union { int i; char c[sizeof(int)]; } u; - u.i = 0x01020304; - return u.c[0] == 0x01 && u.c[1] == 0x02 && u.c[2] == 0x03 && u.c[3] == 0x04 ? 0 : 1;""", - addmain=True, execute=True, - define='HAVE_BIG_ENDIAN', - msg="Checking for HAVE_BIG_ENDIAN - runtime") - - # Extra sanity check. - if conf.CONFIG_SET("HAVE_BIG_ENDIAN") == conf.CONFIG_SET("HAVE_LITTLE_ENDIAN"): - Logs.error("Failed endian determination. The PDP-11 is back?") - sys.exit(1) - else: - if conf.CONFIG_SET("HAVE_BIG_ENDIAN"): - conf.DEFINE('WORDS_BIGENDIAN', 1) - - # check if signal() takes a void function - if conf.CHECK_CODE('return *(signal (0, 0)) (0) == 1', - define='RETSIGTYPE_INT', - execute=False, - headers='signal.h', - msg='Checking if signal handlers return int'): - conf.DEFINE('RETSIGTYPE', 'int') - else: - conf.DEFINE('RETSIGTYPE', 'void') - - conf.CHECK_VARIABLE('__FUNCTION__', define='HAVE_FUNCTION_MACRO') - - conf.CHECK_CODE('va_list ap1,ap2; va_copy(ap1,ap2)', - define="HAVE_VA_COPY", - msg="Checking for va_copy") - - conf.CHECK_CODE(''' - #define eprintf(...) fprintf(stderr, __VA_ARGS__) - eprintf("bla", "bar") - ''', define='HAVE__VA_ARGS__MACRO') - - conf.SAMBA_BUILD_ENV() - - -def build(bld): - # give a more useful message if the source directory has moved - curdir = bld.path.abspath() - srcdir = bld.srcnode.abspath() - relpath = os_path_relpath(curdir, srcdir) - if relpath.find('../') != -1: - Logs.error('bld.path %s is not a child of %s' % (curdir, srcdir)) - raise Errors.WafError('''The top source directory has moved. Please run distclean and reconfigure''') - - bld.SETUP_BUILD_GROUPS() - bld.ENFORCE_GROUP_ORDERING() - bld.CHECK_PROJECT_RULES() diff --git a/ldb-2.0.8/common/attrib_handlers.c b/ldb-2.0.8/common/attrib_handlers.c deleted file mode 100644 index b5212b7..0000000 --- a/ldb-2.0.8/common/attrib_handlers.c +++ /dev/null @@ -1,639 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2005 - Copyright (C) Andrew Bartlett 2006-2009 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ -/* - attribute handlers for well known attribute types, selected by syntax OID - see rfc2252 -*/ - -#include "ldb_private.h" -#include "system/locale.h" -#include "ldb_handlers.h" - -/* - default handler that just copies a ldb_val. -*/ -int ldb_handler_copy(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - *out = ldb_val_dup(mem_ctx, in); - if (in->length > 0 && out->data == NULL) { - ldb_oom(ldb); - return -1; - } - return 0; -} - -/* - a case folding copy handler, removing leading and trailing spaces and - multiple internal spaces - - We exploit the fact that utf8 never uses the space octet except for - the space itself -*/ -int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - char *s, *t; - size_t l; - - if (!in || !out || !(in->data)) { - return -1; - } - - out->data = (uint8_t *)ldb_casefold(ldb, mem_ctx, (const char *)(in->data), in->length); - if (out->data == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_handler_fold: unable to casefold string [%.*s]", (int)in->length, (const char *)in->data); - return -1; - } - - s = (char *)(out->data); - - /* remove trailing spaces if any */ - l = strlen(s); - while (l > 0 && s[l - 1] == ' ') l--; - s[l] = '\0'; - - /* remove leading spaces if any */ - if (*s == ' ') { - for (t = s; *s == ' '; s++) ; - - /* remove leading spaces by moving down the string */ - memmove(t, s, l); - - s = t; - } - - /* check middle spaces */ - while ((t = strchr(s, ' ')) != NULL) { - for (s = t; *s == ' '; s++) ; - - if ((s - t) > 1) { - l = strlen(s); - - /* remove all spaces but one by moving down the string */ - memmove(t + 1, s, l); - } - } - - out->length = strlen((char *)out->data); - return 0; -} - -/* length limited conversion of a ldb_val to a int32_t */ -static int val_to_int64(const struct ldb_val *in, int64_t *v) -{ - char *end; - char buf[64]; - - /* make sure we don't read past the end of the data */ - if (in->length > sizeof(buf)-1) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - strncpy(buf, (char *)in->data, in->length); - buf[in->length] = 0; - - /* We've to use "strtoll" here to have the intended overflows. - * Otherwise we may get "LONG_MAX" and the conversion is wrong. */ - *v = (int64_t) strtoll(buf, &end, 0); - if (*end != 0) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - return LDB_SUCCESS; -} - - -/* - canonicalise a ldap Integer - rfc2252 specifies it should be in decimal form -*/ -static int ldb_canonicalise_Integer(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - int64_t i; - int ret; - - ret = val_to_int64(in, &i); - if (ret != LDB_SUCCESS) { - return ret; - } - out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%lld", (long long)i); - if (out->data == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - out->length = strlen((char *)out->data); - return 0; -} - -/* - * Lexicographically ordered format for a ldap Integer - * - * [ INT64_MIN ... -3, -2, -1 | 0 | +1, +2, +3 ... INT64_MAX ] - * n o p - * - * For human readability sake, we continue to format the key as a string - * (like the canonicalize) rather than store as a fixed binary representation. - * - * In order to sort the integers in the correct string order, there are three - * techniques we use: - * - * 1. Zero padding - * 2. Negative integer inversion - * 3. 1-byte prefixes: 'n' < 'o' < 'p' - * - * 1. To have a fixed-width representation so that 10 sorts after 2 rather than - * after 1, we zero pad, like this 4-byte width example: - * - * 0001, 0002, 0010 - * - * INT64_MAX = 2^63 - 1 = 9223372036854775807 (19 characters long) - * - * Meaning we need to pad to 19 characters. - * - * 2. This works for positive integers, but negative integers will still be - * sorted backwards, for example: - * - * -9223372036854775808 ..., -0000000000000000002, -0000000000000000001 - * INT64_MIN -2 -1 - * - * gets sorted based on string as: - * - * -0000000000000000001, -0000000000000000002, ... -9223372036854775808 - * - * In order to fix this, we invert the negative integer range, so that they - * get sorted the same way as positive numbers. INT64_MIN becomes the lowest - * possible non-negative number (zero), and -1 becomes the highest (INT64_MAX). - * - * The actual conversion applied to negative number 'x' is: - * INT64_MAX - abs(x) + 1 - * (The +1 is needed because abs(INT64_MIN) is one greater than INT64_MAX) - * - * 3. Finally, we now have two different numbers that map to the same key, e.g. - * INT64_MIN maps to -0000000000000000000 and zero maps to 0000000000000000000. - * In order to avoid confusion, we give every number a prefix representing its - * sign: 'n' for negative numbers, 'o' for zero, and 'p' for positive. (Note - * that '+' and '-' weren't used because they sort the wrong way). - * - * The result is a range of key values that look like this: - * - * n0000000000000000000, ... n9223372036854775807, - * INT64_MIN -1 - * - * o0000000000000000000, - * ZERO - * - * p0000000000000000001, ... p9223372036854775807 - * +1 INT64_MAX - */ -static int ldb_index_format_Integer(struct ldb_context *ldb, - void *mem_ctx, - const struct ldb_val *in, - struct ldb_val *out) -{ - int64_t i; - int ret; - char prefix; - size_t len; - - ret = val_to_int64(in, &i); - if (ret != LDB_SUCCESS) { - return ret; - } - - if (i < 0) { - /* - * i is negative, so this is subtraction rather than - * wrap-around. - */ - prefix = 'n'; - i = INT64_MAX + i + 1; - } else if (i > 0) { - prefix = 'p'; - } else { - prefix = 'o'; - } - - out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%c%019lld", prefix, (long long)i); - if (out->data == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - len = talloc_array_length(out->data) - 1; - if (len != 20) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - __location__ ": expected index format str %s to" - " have length 20 but got %zu", - (char*)out->data, len); - return LDB_ERR_OPERATIONS_ERROR; - } - - out->length = 20; - return 0; -} - -/* - compare two Integers -*/ -static int ldb_comparison_Integer(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - int64_t i1=0, i2=0; - val_to_int64(v1, &i1); - val_to_int64(v2, &i2); - if (i1 == i2) return 0; - return i1 > i2? 1 : -1; -} - -/* - canonicalise a ldap Boolean - rfc2252 specifies it should be either "TRUE" or "FALSE" -*/ -static int ldb_canonicalise_Boolean(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - if (in->length >= 4 && strncasecmp((char *)in->data, "TRUE", in->length) == 0) { - out->data = (uint8_t *)talloc_strdup(mem_ctx, "TRUE"); - out->length = 4; - } else if (in->length >= 5 && strncasecmp((char *)in->data, "FALSE", in->length) == 0) { - out->data = (uint8_t *)talloc_strdup(mem_ctx, "FALSE"); - out->length = 5; - } else { - return -1; - } - return 0; -} - -/* - compare two Booleans -*/ -static int ldb_comparison_Boolean(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - if (v1->length != v2->length) { - return v1->length - v2->length; - } - return strncasecmp((char *)v1->data, (char *)v2->data, v1->length); -} - - -/* - compare two binary blobs -*/ -int ldb_comparison_binary(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - if (v1->length != v2->length) { - return v1->length - v2->length; - } - return memcmp(v1->data, v2->data, v1->length); -} - -/* - compare two case insensitive strings, ignoring multiple whitespaces - and leading and trailing whitespaces - see rfc2252 section 8.1 - - try to optimize for the ascii case, - but if we find out an utf8 codepoint revert to slower but correct function -*/ -int ldb_comparison_fold(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - const char *s1=(const char *)v1->data, *s2=(const char *)v2->data; - size_t n1 = v1->length, n2 = v2->length; - char *b1, *b2; - const char *u1, *u2; - int ret; - while (n1 && *s1 == ' ') { s1++; n1--; }; - while (n2 && *s2 == ' ') { s2++; n2--; }; - - while (n1 && n2 && *s1 && *s2) { - /* the first 127 (0x7F) chars are ascii and utf8 guarantes they - * never appear in multibyte sequences */ - if (((unsigned char)s1[0]) & 0x80) goto utf8str; - if (((unsigned char)s2[0]) & 0x80) goto utf8str; - if (toupper((unsigned char)*s1) != toupper((unsigned char)*s2)) - break; - if (*s1 == ' ') { - while (n1 && s1[0] == s1[1]) { s1++; n1--; } - while (n2 && s2[0] == s2[1]) { s2++; n2--; } - } - s1++; s2++; - n1--; n2--; - } - - /* check for trailing spaces only if the other pointers has - * reached the end of the strings otherwise we can - * mistakenly match. ex. "domain users" <-> - * "domainUpdates" - */ - if (n1 && *s1 == ' ' && (!n2 || !*s2)) { - while (n1 && *s1 == ' ') { s1++; n1--; } - } - if (n2 && *s2 == ' ' && (!n1 || !*s1)) { - while (n2 && *s2 == ' ') { s2++; n2--; } - } - if (n1 == 0 && n2 != 0) { - return -(int)toupper(*s2); - } - if (n2 == 0 && n1 != 0) { - return (int)toupper(*s1); - } - if (n1 == 0 && n2 == 0) { - return 0; - } - return (int)toupper(*s1) - (int)toupper(*s2); - -utf8str: - /* no need to recheck from the start, just from the first utf8 char found */ - b1 = ldb_casefold(ldb, mem_ctx, s1, n1); - b2 = ldb_casefold(ldb, mem_ctx, s2, n2); - - if (!b1 || !b2) { - /* One of the strings was not UTF8, so we have no - * options but to do a binary compare */ - talloc_free(b1); - talloc_free(b2); - ret = memcmp(s1, s2, MIN(n1, n2)); - if (ret == 0) { - if (n1 == n2) return 0; - if (n1 > n2) { - return (int)toupper(s1[n2]); - } else { - return -(int)toupper(s2[n1]); - } - } - return ret; - } - - u1 = b1; - u2 = b2; - - while (*u1 & *u2) { - if (*u1 != *u2) - break; - if (*u1 == ' ') { - while (u1[0] == u1[1]) u1++; - while (u2[0] == u2[1]) u2++; - } - u1++; u2++; - } - if (! (*u1 && *u2)) { - while (*u1 == ' ') u1++; - while (*u2 == ' ') u2++; - } - ret = (int)(*u1 - *u2); - - talloc_free(b1); - talloc_free(b2); - - return ret; -} - - -/* - canonicalise a attribute in DN format -*/ -static int ldb_canonicalise_dn(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - struct ldb_dn *dn; - int ret = -1; - - out->length = 0; - out->data = NULL; - - dn = ldb_dn_from_ldb_val(mem_ctx, ldb, in); - if ( ! ldb_dn_validate(dn)) { - return LDB_ERR_INVALID_DN_SYNTAX; - } - - out->data = (uint8_t *)ldb_dn_alloc_casefold(mem_ctx, dn); - if (out->data == NULL) { - goto done; - } - out->length = strlen((char *)out->data); - - ret = 0; - -done: - talloc_free(dn); - - return ret; -} - -/* - compare two dns -*/ -static int ldb_comparison_dn(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - struct ldb_dn *dn1 = NULL, *dn2 = NULL; - int ret; - - dn1 = ldb_dn_from_ldb_val(mem_ctx, ldb, v1); - if ( ! ldb_dn_validate(dn1)) return -1; - - dn2 = ldb_dn_from_ldb_val(mem_ctx, ldb, v2); - if ( ! ldb_dn_validate(dn2)) { - talloc_free(dn1); - return -1; - } - - ret = ldb_dn_compare(dn1, dn2); - - talloc_free(dn1); - talloc_free(dn2); - return ret; -} - -/* - compare two utc time values. 1 second resolution -*/ -static int ldb_comparison_utctime(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - time_t t1=0, t2=0; - ldb_val_to_time(v1, &t1); - ldb_val_to_time(v2, &t2); - if (t1 == t2) return 0; - return t1 > t2? 1 : -1; -} - -/* - canonicalise a utc time -*/ -static int ldb_canonicalise_utctime(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - time_t t; - int ret; - ret = ldb_val_to_time(in, &t); - if (ret != LDB_SUCCESS) { - return ret; - } - out->data = (uint8_t *)ldb_timestring_utc(mem_ctx, t); - if (out->data == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - out->length = strlen((char *)out->data); - return 0; -} - -/* - canonicalise a generalized time -*/ -static int ldb_canonicalise_generalizedtime(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - time_t t; - int ret; - ret = ldb_val_to_time(in, &t); - if (ret != LDB_SUCCESS) { - return ret; - } - out->data = (uint8_t *)ldb_timestring(mem_ctx, t); - if (out->data == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - out->length = strlen((char *)out->data); - return 0; -} - -/* - table of standard attribute handlers -*/ -static const struct ldb_schema_syntax ldb_standard_syntaxes[] = { - { - .name = LDB_SYNTAX_INTEGER, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_canonicalise_Integer, - .comparison_fn = ldb_comparison_Integer - }, - { - .name = LDB_SYNTAX_ORDERED_INTEGER, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_canonicalise_Integer, - .index_format_fn = ldb_index_format_Integer, - .comparison_fn = ldb_comparison_Integer - }, - { - .name = LDB_SYNTAX_OCTET_STRING, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_handler_copy, - .comparison_fn = ldb_comparison_binary - }, - { - .name = LDB_SYNTAX_DIRECTORY_STRING, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_handler_fold, - .comparison_fn = ldb_comparison_fold - }, - { - .name = LDB_SYNTAX_DN, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_canonicalise_dn, - .comparison_fn = ldb_comparison_dn - }, - { - .name = LDB_SYNTAX_OBJECTCLASS, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_handler_fold, - .comparison_fn = ldb_comparison_fold - }, - { - .name = LDB_SYNTAX_UTC_TIME, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_canonicalise_utctime, - .comparison_fn = ldb_comparison_utctime - }, - { - .name = LDB_SYNTAX_GENERALIZED_TIME, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_canonicalise_generalizedtime, - .comparison_fn = ldb_comparison_utctime - }, - { - .name = LDB_SYNTAX_BOOLEAN, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_canonicalise_Boolean, - .comparison_fn = ldb_comparison_Boolean - }, -}; - - -/* - return the attribute handlers for a given syntax name -*/ -const struct ldb_schema_syntax *ldb_standard_syntax_by_name(struct ldb_context *ldb, - const char *syntax) -{ - unsigned int i; - unsigned num_handlers = sizeof(ldb_standard_syntaxes)/sizeof(ldb_standard_syntaxes[0]); - /* TODO: should be replaced with a binary search */ - for (i=0;i. -*/ - -/* - * Name: ldb - * - * Component: ldb core API - * - * Description: core API routines interfacing to ldb backends - * - * Author: Andrew Tridgell - */ - -#define TEVENT_DEPRECATED 1 -#include "ldb_private.h" -#include "ldb.h" - -static int ldb_context_destructor(void *ptr) -{ - struct ldb_context *ldb = talloc_get_type(ptr, struct ldb_context); - - if (ldb->transaction_active) { - ldb_debug(ldb, LDB_DEBUG_FATAL, - "A transaction is still active in ldb context [%p] on %s", - ldb, (const char *)ldb_get_opaque(ldb, "ldb_url")); - } - - return 0; -} - -/* - this is used to catch debug messages from events -*/ -static void ldb_tevent_debug(void *context, enum tevent_debug_level level, - const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); - -static void ldb_tevent_debug(void *context, enum tevent_debug_level level, - const char *fmt, va_list ap) -{ - struct ldb_context *ldb = talloc_get_type(context, struct ldb_context); - enum ldb_debug_level ldb_level = LDB_DEBUG_FATAL; - - switch (level) { - case TEVENT_DEBUG_FATAL: - ldb_level = LDB_DEBUG_FATAL; - break; - case TEVENT_DEBUG_ERROR: - ldb_level = LDB_DEBUG_ERROR; - break; - case TEVENT_DEBUG_WARNING: - ldb_level = LDB_DEBUG_WARNING; - break; - case TEVENT_DEBUG_TRACE: - ldb_level = LDB_DEBUG_TRACE; - break; - }; - - /* There isn't a tevent: prefix here because to add it means - * actually printing the string, and most of the time we don't - * want to show it */ - ldb_vdebug(ldb, ldb_level, fmt, ap); -} - -/* - initialise a ldb context - The mem_ctx is required - The event_ctx is required -*/ -struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx) -{ - struct ldb_context *ldb; - int ret; - const char *modules_path = getenv("LDB_MODULES_PATH"); - - if (modules_path == NULL) { - modules_path = LDB_MODULESDIR; - } - - ret = ldb_modules_load(modules_path, LDB_VERSION); - if (ret != LDB_SUCCESS) { - return NULL; - } - - ldb = talloc_zero(mem_ctx, struct ldb_context); - if (ldb == NULL) { - return NULL; - } - - /* A new event context so that callers who don't want ldb - * operating on their global event context can work without - * having to provide their own private one explicitly */ - if (ev_ctx == NULL) { - ev_ctx = tevent_context_init(ldb); - if (ev_ctx == NULL) { - talloc_free(ldb); - return NULL; - } - tevent_set_debug(ev_ctx, ldb_tevent_debug, ldb); - tevent_loop_allow_nesting(ev_ctx); - } - - ret = ldb_setup_wellknown_attributes(ldb); - if (ret != LDB_SUCCESS) { - talloc_free(ldb); - return NULL; - } - - ldb_set_utf8_default(ldb); - ldb_set_create_perms(ldb, 0666); - ldb_set_modules_dir(ldb, LDB_MODULESDIR); - ldb_set_event_context(ldb, ev_ctx); - ret = ldb_register_extended_match_rules(ldb); - if (ret != LDB_SUCCESS) { - talloc_free(ldb); - return NULL; - } - - /* TODO: get timeout from options if available there */ - ldb->default_timeout = 300; /* set default to 5 minutes */ - - talloc_set_destructor((TALLOC_CTX *)ldb, ldb_context_destructor); - - return ldb; -} - -/* - try to autodetect a basedn if none specified. This fixes one of my - pet hates about ldapsearch, which is that you have to get a long, - complex basedn right to make any use of it. -*/ -void ldb_set_default_dns(struct ldb_context *ldb) -{ - TALLOC_CTX *tmp_ctx; - int ret; - struct ldb_result *res; - struct ldb_dn *tmp_dn=NULL; - static const char *attrs[] = { - "rootDomainNamingContext", - "configurationNamingContext", - "schemaNamingContext", - "defaultNamingContext", - NULL - }; - - tmp_ctx = talloc_new(ldb); - ret = ldb_search(ldb, tmp_ctx, &res, ldb_dn_new(tmp_ctx, ldb, NULL), - LDB_SCOPE_BASE, attrs, "(objectClass=*)"); - if (ret != LDB_SUCCESS) { - talloc_free(tmp_ctx); - return; - } - - if (res->count != 1) { - talloc_free(tmp_ctx); - return; - } - - if (!ldb_get_opaque(ldb, "rootDomainNamingContext")) { - tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], - "rootDomainNamingContext"); - ldb_set_opaque(ldb, "rootDomainNamingContext", tmp_dn); - } - - if (!ldb_get_opaque(ldb, "configurationNamingContext")) { - tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], - "configurationNamingContext"); - ldb_set_opaque(ldb, "configurationNamingContext", tmp_dn); - } - - if (!ldb_get_opaque(ldb, "schemaNamingContext")) { - tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], - "schemaNamingContext"); - ldb_set_opaque(ldb, "schemaNamingContext", tmp_dn); - } - - if (!ldb_get_opaque(ldb, "defaultNamingContext")) { - tmp_dn = ldb_msg_find_attr_as_dn(ldb, ldb, res->msgs[0], - "defaultNamingContext"); - ldb_set_opaque(ldb, "defaultNamingContext", tmp_dn); - } - - talloc_free(tmp_ctx); -} - -struct ldb_dn *ldb_get_root_basedn(struct ldb_context *ldb) -{ - void *opaque = ldb_get_opaque(ldb, "rootDomainNamingContext"); - return talloc_get_type(opaque, struct ldb_dn); -} - -struct ldb_dn *ldb_get_config_basedn(struct ldb_context *ldb) -{ - void *opaque = ldb_get_opaque(ldb, "configurationNamingContext"); - return talloc_get_type(opaque, struct ldb_dn); -} - -struct ldb_dn *ldb_get_schema_basedn(struct ldb_context *ldb) -{ - void *opaque = ldb_get_opaque(ldb, "schemaNamingContext"); - return talloc_get_type(opaque, struct ldb_dn); -} - -struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb) -{ - void *opaque = ldb_get_opaque(ldb, "defaultNamingContext"); - return talloc_get_type(opaque, struct ldb_dn); -} - -/* - connect to a database. The URL can either be one of the following forms - ldb://path - ldapi://path - - flags is made up of LDB_FLG_* - - the options are passed uninterpreted to the backend, and are - backend specific -*/ -int ldb_connect(struct ldb_context *ldb, const char *url, - unsigned int flags, const char *options[]) -{ - int ret; - char *url2; - /* We seem to need to do this here, or else some utilities don't - * get ldb backends */ - - ldb->flags = flags; - - url2 = talloc_strdup(ldb, url); - if (!url2) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - ret = ldb_set_opaque(ldb, "ldb_url", url2); - if (ret != LDB_SUCCESS) { - return ret; - } - - /* - * Take a copy of the options. - */ - ldb->options = ldb_options_copy(ldb, options); - if (ldb->options == NULL && options != NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_module_connect_backend(ldb, url, options, &ldb->modules); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_load_modules(ldb, options); - if (ret != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_FATAL, - "Unable to load modules for %s: %s", - url, ldb_errstring(ldb)); - return ret; - } - - /* set the default base dn */ - ldb_set_default_dns(ldb); - - return LDB_SUCCESS; -} - -void ldb_set_errstring(struct ldb_context *ldb, const char *err_string) -{ - ldb_asprintf_errstring(ldb, "%s", err_string); -} - -void ldb_asprintf_errstring(struct ldb_context *ldb, const char *format, ...) -{ - va_list ap; - char *old_err_string = NULL; - if (ldb->err_string) { - old_err_string = ldb->err_string; - } - - va_start(ap, format); - ldb->err_string = talloc_vasprintf(ldb, format, ap); - va_end(ap); - - TALLOC_FREE(old_err_string); - - if (ldb->flags & LDB_FLG_ENABLE_TRACING) { - ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_asprintf/set_errstring: %s", - ldb->err_string); - } -} - -void ldb_reset_err_string(struct ldb_context *ldb) -{ - if (ldb->err_string) { - talloc_free(ldb->err_string); - ldb->err_string = NULL; - } -} - - - -/* - set an ldb error based on file:line -*/ -int ldb_error_at(struct ldb_context *ldb, int ecode, - const char *reason, const char *file, int line) -{ - if (reason == NULL) { - reason = ldb_strerror(ecode); - } - ldb_asprintf_errstring(ldb, "%s at %s:%d", reason, file, line); - return ecode; -} - - -#define FIRST_OP_NOERR(ldb, op) do { \ - next_module = ldb->modules; \ - while (next_module && next_module->ops->op == NULL) { \ - next_module = next_module->next; \ - }; \ - if ((ldb->flags & LDB_FLG_ENABLE_TRACING) && next_module) { \ - ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_trace_request: (%s)->" #op, \ - next_module->ops->name); \ - } \ -} while (0) - -#define FIRST_OP(ldb, op) do { \ - FIRST_OP_NOERR(ldb, op); \ - if (next_module == NULL) { \ - ldb_asprintf_errstring(ldb, "unable to find module or backend to handle operation: " #op); \ - return LDB_ERR_OPERATIONS_ERROR; \ - } \ -} while (0) - - -/* - start a transaction -*/ -int ldb_transaction_start(struct ldb_context *ldb) -{ - struct ldb_module *next_module; - int status; - - ldb_debug(ldb, LDB_DEBUG_TRACE, - "start ldb transaction (nesting: %d)", - ldb->transaction_active); - - /* explicit transaction active, count nested requests */ - if (ldb->transaction_active) { - ldb->transaction_active++; - return LDB_SUCCESS; - } - - /* start a new transaction */ - ldb->transaction_active++; - ldb->prepare_commit_done = false; - - FIRST_OP(ldb, start_transaction); - - ldb_reset_err_string(ldb); - - status = next_module->ops->start_transaction(next_module); - if (status != LDB_SUCCESS) { - if (ldb->err_string == NULL) { - /* no error string was setup by the backend */ - ldb_asprintf_errstring(ldb, - "ldb transaction start: %s (%d)", - ldb_strerror(status), - status); - ldb->transaction_active--; - } - if ((next_module && next_module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { - ldb_debug(next_module->ldb, LDB_DEBUG_TRACE, "start ldb transaction error: %s", - ldb_errstring(next_module->ldb)); - } - } else { - if ((next_module && next_module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { - ldb_debug(next_module->ldb, LDB_DEBUG_TRACE, "start ldb transaction success"); - } - } - return status; -} - -/* - prepare for transaction commit (first phase of two phase commit) -*/ -int ldb_transaction_prepare_commit(struct ldb_context *ldb) -{ - struct ldb_module *next_module; - int status; - - if (ldb->prepare_commit_done) { - return LDB_SUCCESS; - } - - /* commit only when all nested transactions are complete */ - if (ldb->transaction_active > 1) { - return LDB_SUCCESS; - } - - ldb->prepare_commit_done = true; - - if (ldb->transaction_active < 0) { - ldb_debug(ldb, LDB_DEBUG_FATAL, - "prepare commit called but no ldb transactions are active!"); - ldb->transaction_active = 0; - return LDB_ERR_OPERATIONS_ERROR; - } - - /* call prepare transaction if available */ - FIRST_OP_NOERR(ldb, prepare_commit); - if (next_module == NULL) { - return LDB_SUCCESS; - } - - ldb_reset_err_string(ldb); - - status = next_module->ops->prepare_commit(next_module); - if (status != LDB_SUCCESS) { - ldb->transaction_active--; - /* if a next_module fails the prepare then we need - to call the end transaction for everyone */ - FIRST_OP(ldb, del_transaction); - next_module->ops->del_transaction(next_module); - if (ldb->err_string == NULL) { - /* no error string was setup by the backend */ - ldb_asprintf_errstring(ldb, - "ldb transaction prepare commit: %s (%d)", - ldb_strerror(status), - status); - } - if ((next_module && next_module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { - ldb_debug(next_module->ldb, LDB_DEBUG_TRACE, "prepare commit transaction error: %s", - ldb_errstring(next_module->ldb)); - } - } - - return status; -} - - -/* - commit a transaction -*/ -int ldb_transaction_commit(struct ldb_context *ldb) -{ - struct ldb_module *next_module; - int status; - - status = ldb_transaction_prepare_commit(ldb); - if (status != LDB_SUCCESS) { - return status; - } - - ldb->transaction_active--; - - ldb_debug(ldb, LDB_DEBUG_TRACE, - "commit ldb transaction (nesting: %d)", - ldb->transaction_active); - - /* commit only when all nested transactions are complete */ - if (ldb->transaction_active > 0) { - return LDB_SUCCESS; - } - - if (ldb->transaction_active < 0) { - ldb_debug(ldb, LDB_DEBUG_FATAL, - "commit called but no ldb transactions are active!"); - ldb->transaction_active = 0; - return LDB_ERR_OPERATIONS_ERROR; - } - - ldb_reset_err_string(ldb); - - FIRST_OP(ldb, end_transaction); - status = next_module->ops->end_transaction(next_module); - if (status != LDB_SUCCESS) { - if (ldb->err_string == NULL) { - /* no error string was setup by the backend */ - ldb_asprintf_errstring(ldb, - "ldb transaction commit: %s (%d)", - ldb_strerror(status), - status); - } - if ((next_module && next_module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { - ldb_debug(next_module->ldb, LDB_DEBUG_TRACE, "commit ldb transaction error: %s", - ldb_errstring(next_module->ldb)); - } - } - return status; -} - - -/* - cancel a transaction -*/ -int ldb_transaction_cancel(struct ldb_context *ldb) -{ - struct ldb_module *next_module; - int status; - - ldb->transaction_active--; - - ldb_debug(ldb, LDB_DEBUG_TRACE, - "cancel ldb transaction (nesting: %d)", - ldb->transaction_active); - - /* really cancel only if all nested transactions are complete */ - if (ldb->transaction_active > 0) { - return LDB_SUCCESS; - } - - if (ldb->transaction_active < 0) { - ldb_debug(ldb, LDB_DEBUG_FATAL, - "cancel called but no ldb transactions are active!"); - ldb->transaction_active = 0; - return LDB_ERR_OPERATIONS_ERROR; - } - - FIRST_OP(ldb, del_transaction); - - status = next_module->ops->del_transaction(next_module); - if (status != LDB_SUCCESS) { - if (ldb->err_string == NULL) { - /* no error string was setup by the backend */ - ldb_asprintf_errstring(ldb, - "ldb transaction cancel: %s (%d)", - ldb_strerror(status), - status); - } - if ((next_module && next_module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { - ldb_debug(next_module->ldb, LDB_DEBUG_TRACE, "cancel ldb transaction error: %s", - ldb_errstring(next_module->ldb)); - } - } - return status; -} - -/* - cancel a transaction with no error if no transaction is pending - used when we fork() to clear any parent transactions -*/ -int ldb_transaction_cancel_noerr(struct ldb_context *ldb) -{ - if (ldb->transaction_active > 0) { - return ldb_transaction_cancel(ldb); - } - return LDB_SUCCESS; -} - - -/* autostarts a transaction if none active */ -static int ldb_autotransaction_request(struct ldb_context *ldb, - struct ldb_request *req) -{ - int ret; - - ret = ldb_transaction_start(ldb); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_request(ldb, req); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - - if (ret == LDB_SUCCESS) { - return ldb_transaction_commit(ldb); - } - ldb_transaction_cancel(ldb); - - return ret; -} - -int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type) -{ - struct tevent_context *ev; - int ret; - - if (handle == NULL) { - return LDB_ERR_UNAVAILABLE; - } - - if (handle->state == LDB_ASYNC_DONE) { - if ((handle->status != LDB_SUCCESS) && - (handle->ldb->err_string == NULL)) { - /* if no error string was setup by the backend */ - ldb_asprintf_errstring(handle->ldb, - "ldb_wait from %s with LDB_ASYNC_DONE: %s (%d)", - handle->location, - ldb_strerror(handle->status), - handle->status); - } - return handle->status; - } - - ev = ldb_handle_get_event_context(handle); - if (NULL == ev) { - return ldb_oom(handle->ldb); - } - - switch (type) { - case LDB_WAIT_NONE: - ret = tevent_loop_once(ev); - if (ret != 0) { - return ldb_operr(handle->ldb); - } - if (handle->status == LDB_SUCCESS) { - return LDB_SUCCESS; - } - if (handle->ldb->err_string != NULL) { - return handle->status; - } - /* - * if no error string was setup by the backend - */ - ldb_asprintf_errstring(handle->ldb, - "ldb_wait from %s with LDB_WAIT_NONE: %s (%d)", - handle->location, - ldb_strerror(handle->status), - handle->status); - return handle->status; - - case LDB_WAIT_ALL: - while (handle->state != LDB_ASYNC_DONE) { - ret = tevent_loop_once(ev); - if (ret != 0) { - return ldb_operr(handle->ldb); - } - if (handle->status != LDB_SUCCESS) { - if (handle->ldb->err_string != NULL) { - return handle->status; - } - /* - * if no error string was setup by the - * backend - */ - ldb_asprintf_errstring(handle->ldb, - "ldb_wait from %s with " - "LDB_WAIT_ALL: %s (%d)", - handle->location, - ldb_strerror(handle->status), - handle->status); - return handle->status; - } - } - if (handle->status == LDB_SUCCESS) { - return LDB_SUCCESS; - } - if (handle->ldb->err_string != NULL) { - return handle->status; - } - /* - * if no error string was setup by the backend - */ - ldb_asprintf_errstring(handle->ldb, - "ldb_wait from %s with LDB_WAIT_ALL," - " LDB_ASYNC_DONE: %s (%d)", - handle->location, - ldb_strerror(handle->status), - handle->status); - return handle->status; - } - - return LDB_SUCCESS; -} - -/* set the specified timeout or, if timeout is 0 set the default timeout */ -int ldb_set_timeout(struct ldb_context *ldb, - struct ldb_request *req, - int timeout) -{ - if (req == NULL) return LDB_ERR_OPERATIONS_ERROR; - - if (timeout != 0) { - req->timeout = timeout; - } else { - req->timeout = ldb->default_timeout; - } - req->starttime = time(NULL); - - return LDB_SUCCESS; -} - -/* calculates the new timeout based on the previous starttime and timeout */ -int ldb_set_timeout_from_prev_req(struct ldb_context *ldb, - struct ldb_request *oldreq, - struct ldb_request *newreq) -{ - if (newreq == NULL) return LDB_ERR_OPERATIONS_ERROR; - - if (oldreq == NULL) { - return ldb_set_timeout(ldb, newreq, 0); - } - - newreq->starttime = oldreq->starttime; - newreq->timeout = oldreq->timeout; - - return LDB_SUCCESS; -} - - -struct ldb_handle *ldb_handle_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb) -{ - struct ldb_handle *h; - - h = talloc_zero(mem_ctx, struct ldb_handle); - if (h == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return NULL; - } - - h->status = LDB_SUCCESS; - h->state = LDB_ASYNC_INIT; - h->ldb = ldb; - h->flags = 0; - h->location = NULL; - h->parent = NULL; - - if (h->ldb->require_private_event_context == true) { - h->event_context = tevent_context_init(h); - if (h->event_context == NULL) { - ldb_set_errstring(ldb, - "Out of Memory allocating " - "event context for new handle"); - return NULL; - } - tevent_set_debug(h->event_context, ldb_tevent_debug, ldb); - tevent_loop_allow_nesting(h->event_context); - } - - return h; -} - -static struct ldb_handle *ldb_handle_new_child(TALLOC_CTX *mem_ctx, - struct ldb_request *parent_req) -{ - struct ldb_handle *h; - - h = talloc_zero(mem_ctx, struct ldb_handle); - if (h == NULL) { - ldb_set_errstring(parent_req->handle->ldb, - "Out of Memory"); - return NULL; - } - - h->status = LDB_SUCCESS; - h->state = LDB_ASYNC_INIT; - h->ldb = parent_req->handle->ldb; - h->parent = parent_req; - h->nesting = parent_req->handle->nesting + 1; - h->flags = parent_req->handle->flags; - h->custom_flags = parent_req->handle->custom_flags; - h->event_context = parent_req->handle->event_context; - - return h; -} - -/* - set the permissions for new files to be passed to open() in - backends that use local files - */ -void ldb_set_create_perms(struct ldb_context *ldb, unsigned int perms) -{ - ldb->create_perms = perms; -} - -unsigned int ldb_get_create_perms(struct ldb_context *ldb) -{ - return ldb->create_perms; -} - -void ldb_set_event_context(struct ldb_context *ldb, struct tevent_context *ev) -{ - ldb->ev_ctx = ev; -} - -struct tevent_context * ldb_get_event_context(struct ldb_context *ldb) -{ - return ldb->ev_ctx; -} - -void ldb_request_set_state(struct ldb_request *req, int state) -{ - req->handle->state = state; -} - -int ldb_request_get_status(struct ldb_request *req) -{ - return req->handle->status; -} - -/* - * This function obtains the private event context for the handle, - * which may have been created to avoid nested event loops during - * ldb_tdb with the locks held - */ -struct tevent_context *ldb_handle_get_event_context(struct ldb_handle *handle) -{ - if (handle->event_context != NULL) { - return handle->event_context; - } - return ldb_get_event_context(handle->ldb); -} - -/* - * This function forces a specific ldb handle to use the global event - * context. This allows a nested event loop to operate, so any open - * transaction also needs to be aborted. - * - * Any events on this event context will be lost - * - * This is used in Samba when sending an IRPC to another part of the - * same process instead of making a local DB modification. - */ -void ldb_handle_use_global_event_context(struct ldb_handle *handle) -{ - TALLOC_FREE(handle->event_context); -} - -void ldb_set_require_private_event_context(struct ldb_context *ldb) -{ - ldb->require_private_event_context = true; -} - -/* - trace a ldb request -*/ -static void ldb_trace_request(struct ldb_context *ldb, struct ldb_request *req) -{ - TALLOC_CTX *tmp_ctx = talloc_new(req); - unsigned int i; - struct ldb_ldif ldif; - - switch (req->operation) { - case LDB_SEARCH: - ldb_debug_add(ldb, "ldb_trace_request: SEARCH\n"); - ldb_debug_add(ldb, " dn: %s\n", - ldb_dn_is_null(req->op.search.base)?"": - ldb_dn_get_linearized(req->op.search.base)); - ldb_debug_add(ldb, " scope: %s\n", - req->op.search.scope==LDB_SCOPE_BASE?"base": - req->op.search.scope==LDB_SCOPE_ONELEVEL?"one": - req->op.search.scope==LDB_SCOPE_SUBTREE?"sub":"UNKNOWN"); - ldb_debug_add(ldb, " expr: %s\n", - ldb_filter_from_tree(tmp_ctx, req->op.search.tree)); - if (req->op.search.attrs == NULL) { - ldb_debug_add(ldb, " attr: \n"); - } else { - for (i=0; req->op.search.attrs[i]; i++) { - ldb_debug_add(ldb, " attr: %s\n", req->op.search.attrs[i]); - } - } - break; - case LDB_DELETE: - ldb_debug_add(ldb, "ldb_trace_request: DELETE\n"); - ldb_debug_add(ldb, " dn: %s\n", - ldb_dn_get_linearized(req->op.del.dn)); - break; - case LDB_RENAME: - ldb_debug_add(ldb, "ldb_trace_request: RENAME\n"); - ldb_debug_add(ldb, " olddn: %s\n", - ldb_dn_get_linearized(req->op.rename.olddn)); - ldb_debug_add(ldb, " newdn: %s\n", - ldb_dn_get_linearized(req->op.rename.newdn)); - break; - case LDB_EXTENDED: - ldb_debug_add(ldb, "ldb_trace_request: EXTENDED\n"); - ldb_debug_add(ldb, " oid: %s\n", req->op.extended.oid); - ldb_debug_add(ldb, " data: %s\n", req->op.extended.data?"yes":"no"); - break; - case LDB_ADD: - ldif.changetype = LDB_CHANGETYPE_ADD; - ldif.msg = discard_const_p(struct ldb_message, req->op.add.message); - - ldb_debug_add(ldb, "ldb_trace_request: ADD\n"); - - /* - * The choice to call - * ldb_ldif_write_redacted_trace_string() is CRITICAL - * for security. It ensures that we do not output - * passwords into debug logs - */ - - ldb_debug_add(req->handle->ldb, "%s\n", - ldb_ldif_write_redacted_trace_string(req->handle->ldb, tmp_ctx, &ldif)); - break; - case LDB_MODIFY: - ldif.changetype = LDB_CHANGETYPE_MODIFY; - ldif.msg = discard_const_p(struct ldb_message, req->op.mod.message); - - ldb_debug_add(ldb, "ldb_trace_request: MODIFY\n"); - - /* - * The choice to call - * ldb_ldif_write_redacted_trace_string() is CRITICAL - * for security. It ensures that we do not output - * passwords into debug logs - */ - - ldb_debug_add(req->handle->ldb, "%s\n", - ldb_ldif_write_redacted_trace_string(req->handle->ldb, tmp_ctx, &ldif)); - break; - case LDB_REQ_REGISTER_CONTROL: - ldb_debug_add(ldb, "ldb_trace_request: REGISTER_CONTROL\n"); - ldb_debug_add(req->handle->ldb, "%s\n", - req->op.reg_control.oid); - break; - case LDB_REQ_REGISTER_PARTITION: - ldb_debug_add(ldb, "ldb_trace_request: REGISTER_PARTITION\n"); - ldb_debug_add(req->handle->ldb, "%s\n", - ldb_dn_get_linearized(req->op.reg_partition.dn)); - break; - default: - ldb_debug_add(ldb, "ldb_trace_request: UNKNOWN(%u)\n", - req->operation); - break; - } - - if (req->controls == NULL) { - ldb_debug_add(ldb, " control: \n"); - } else { - for (i=0; req->controls && req->controls[i]; i++) { - if (req->controls[i]->oid) { - ldb_debug_add(ldb, " control: %s crit:%u data:%s\n", - req->controls[i]->oid, - req->controls[i]->critical, - req->controls[i]->data?"yes":"no"); - } - } - } - - ldb_debug_end(ldb, LDB_DEBUG_TRACE); - - talloc_free(tmp_ctx); -} - -/* - check that the element flags don't have any internal bits set - */ -static int ldb_msg_check_element_flags(struct ldb_context *ldb, - const struct ldb_message *message) -{ - unsigned i; - for (i=0; inum_elements; i++) { - if (message->elements[i].flags & LDB_FLAG_INTERNAL_MASK) { - ldb_asprintf_errstring(ldb, "Invalid element flags 0x%08x on element %s in %s\n", - message->elements[i].flags, message->elements[i].name, - ldb_dn_get_linearized(message->dn)); - return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; - } - } - return LDB_SUCCESS; -} - -/* - * This context allows us to make the unlock be a talloc destructor - * - * This ensures that a request started, but not waited on, will still - * unlock. - */ -struct ldb_db_lock_context { - struct ldb_request *req; - struct ldb_context *ldb; -}; - -/* - * We have to have a the unlock on a destructor so that we unlock the - * DB if a caller calls talloc_free(req). We trust that the ldb - * context has not already gone away. - */ -static int ldb_db_lock_destructor(struct ldb_db_lock_context *lock_context) -{ - int ret; - struct ldb_module *next_module; - FIRST_OP_NOERR(lock_context->ldb, read_unlock); - if (next_module != NULL) { - ret = next_module->ops->read_unlock(next_module); - } else { - ret = LDB_SUCCESS; - } - - if (ret != LDB_SUCCESS) { - ldb_debug(lock_context->ldb, - LDB_DEBUG_FATAL, - "Failed to unlock db: %s / %s", - ldb_errstring(lock_context->ldb), - ldb_strerror(ret)); - } - return 0; -} - -static int ldb_lock_backend_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct ldb_db_lock_context *lock_context; - int ret; - - lock_context = talloc_get_type(req->context, - struct ldb_db_lock_context); - - if (!ares) { - return ldb_module_done(lock_context->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS || ares->type == LDB_REPLY_DONE) { - ret = ldb_module_done(lock_context->req, ares->controls, - ares->response, ares->error); - /* - * If this is a LDB_REPLY_DONE or an error, unlock the - * DB by calling the destructor on this context - */ - talloc_free(lock_context); - return ret; - } - - /* Otherwise pass on the callback */ - switch (ares->type) { - case LDB_REPLY_ENTRY: - return ldb_module_send_entry(lock_context->req, ares->message, - ares->controls); - - case LDB_REPLY_REFERRAL: - return ldb_module_send_referral(lock_context->req, - ares->referral); - default: - /* Can't happen */ - return LDB_ERR_OPERATIONS_ERROR; - } -} - -/* - * Do an ldb_search() with a lock held, but release it if the request - * is freed with talloc_free() - */ -static int lock_search(struct ldb_module *lock_module, struct ldb_request *req) -{ - /* Used in FIRST_OP_NOERR to find where to send the lock request */ - struct ldb_module *next_module = NULL; - struct ldb_request *down_req = NULL; - struct ldb_db_lock_context *lock_context; - struct ldb_context *ldb = ldb_module_get_ctx(lock_module); - int ret; - - lock_context = talloc(req, struct ldb_db_lock_context); - if (lock_context == NULL) { - return ldb_oom(ldb); - } - - lock_context->ldb = ldb; - lock_context->req = req; - - ret = ldb_build_search_req_ex(&down_req, ldb, req, - req->op.search.base, - req->op.search.scope, - req->op.search.tree, - req->op.search.attrs, - req->controls, - lock_context, - ldb_lock_backend_callback, - req); - LDB_REQ_SET_LOCATION(down_req); - if (ret != LDB_SUCCESS) { - return ret; - } - - /* call DB lock */ - FIRST_OP_NOERR(ldb, read_lock); - if (next_module != NULL) { - ret = next_module->ops->read_lock(next_module); - } else { - ret = LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; - } - - if (ret == LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION) { - /* We might be talking LDAP */ - ldb_reset_err_string(ldb); - TALLOC_FREE(lock_context); - - return ldb_next_request(lock_module, req); - } else if ((ret != LDB_SUCCESS) && (ldb->err_string == NULL)) { - /* if no error string was setup by the backend */ - ldb_asprintf_errstring(ldb, "Failed to get DB lock: %s (%d)", - ldb_strerror(ret), ret); - } else { - talloc_set_destructor(lock_context, ldb_db_lock_destructor); - } - - if (ret != LDB_SUCCESS) { - return ret; - } - - return ldb_next_request(lock_module, down_req); -} - -/* - start an ldb request - NOTE: the request must be a talloc context. - returns LDB_ERR_* on errors. -*/ -int ldb_request(struct ldb_context *ldb, struct ldb_request *req) -{ - struct ldb_module *next_module; - int ret; - - if (req->callback == NULL) { - ldb_set_errstring(ldb, "Requests MUST define callbacks"); - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - ldb_reset_err_string(ldb); - - if (ldb->flags & LDB_FLG_ENABLE_TRACING) { - ldb_trace_request(ldb, req); - } - - /* call the first module in the chain */ - switch (req->operation) { - case LDB_SEARCH: - { - /* - * A fake module to allow ldb_next_request() to be - * re-used and to keep the locking out of this function. - */ - static const struct ldb_module_ops lock_module_ops = { - .name = "lock_searches", - .search = lock_search - }; - struct ldb_module lock_module = { - .ldb = ldb, - .next = ldb->modules, - .ops = &lock_module_ops - }; - next_module = &lock_module; - - /* due to "ldb_build_search_req" base DN always != NULL */ - if (!ldb_dn_validate(req->op.search.base)) { - ldb_asprintf_errstring(ldb, "ldb_search: invalid basedn '%s'", - ldb_dn_get_linearized(req->op.search.base)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - ret = next_module->ops->search(next_module, req); - break; - } - case LDB_ADD: - if (!ldb_dn_validate(req->op.add.message->dn)) { - ldb_asprintf_errstring(ldb, "ldb_add: invalid dn '%s'", - ldb_dn_get_linearized(req->op.add.message->dn)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - /* - * we have to normalize here, as so many places - * in modules and backends assume we don't have two - * elements with the same name - */ - ret = ldb_msg_normalize(ldb, req, req->op.add.message, - discard_const(&req->op.add.message)); - if (ret != LDB_SUCCESS) { - ldb_oom(ldb); - return ret; - } - FIRST_OP(ldb, add); - ret = ldb_msg_check_element_flags(ldb, req->op.add.message); - if (ret != LDB_SUCCESS) { - /* - * "ldb_msg_check_element_flags" generates an error - * string - */ - return ret; - } - ret = next_module->ops->add(next_module, req); - break; - case LDB_MODIFY: - if (!ldb_dn_validate(req->op.mod.message->dn)) { - ldb_asprintf_errstring(ldb, "ldb_modify: invalid dn '%s'", - ldb_dn_get_linearized(req->op.mod.message->dn)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - FIRST_OP(ldb, modify); - ret = ldb_msg_check_element_flags(ldb, req->op.mod.message); - if (ret != LDB_SUCCESS) { - /* - * "ldb_msg_check_element_flags" generates an error - * string - */ - return ret; - } - ret = next_module->ops->modify(next_module, req); - break; - case LDB_DELETE: - if (!ldb_dn_validate(req->op.del.dn)) { - ldb_asprintf_errstring(ldb, "ldb_delete: invalid dn '%s'", - ldb_dn_get_linearized(req->op.del.dn)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - FIRST_OP(ldb, del); - ret = next_module->ops->del(next_module, req); - break; - case LDB_RENAME: - if (!ldb_dn_validate(req->op.rename.olddn)) { - ldb_asprintf_errstring(ldb, "ldb_rename: invalid olddn '%s'", - ldb_dn_get_linearized(req->op.rename.olddn)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - if (!ldb_dn_validate(req->op.rename.newdn)) { - ldb_asprintf_errstring(ldb, "ldb_rename: invalid newdn '%s'", - ldb_dn_get_linearized(req->op.rename.newdn)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - FIRST_OP(ldb, rename); - ret = next_module->ops->rename(next_module, req); - break; - case LDB_EXTENDED: - FIRST_OP(ldb, extended); - ret = next_module->ops->extended(next_module, req); - break; - default: - FIRST_OP(ldb, request); - ret = next_module->ops->request(next_module, req); - break; - } - - if ((ret != LDB_SUCCESS) && (ldb->err_string == NULL)) { - /* if no error string was setup by the backend */ - ldb_asprintf_errstring(ldb, "ldb_request: %s (%d)", - ldb_strerror(ret), ret); - } - - return ret; -} - -int ldb_request_done(struct ldb_request *req, int status) -{ - req->handle->state = LDB_ASYNC_DONE; - req->handle->status = status; - return status; -} - -/* - search the database given a LDAP-like search expression - - returns an LDB error code - - Use talloc_free to free the ldb_message returned in 'res', if successful - -*/ -int ldb_search_default_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct ldb_result *res; - unsigned int n; - - res = talloc_get_type(req->context, struct ldb_result); - - if (!ares) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_request_done(req, ares->error); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - res->msgs = talloc_realloc(res, res->msgs, - struct ldb_message *, res->count + 2); - if (! res->msgs) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - - res->msgs[res->count + 1] = NULL; - - res->msgs[res->count] = talloc_move(res->msgs, &ares->message); - res->count++; - break; - - case LDB_REPLY_REFERRAL: - if (res->refs) { - for (n = 0; res->refs[n]; n++) /*noop*/ ; - } else { - n = 0; - } - - res->refs = talloc_realloc(res, res->refs, char *, n + 2); - if (! res->refs) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - - res->refs[n] = talloc_move(res->refs, &ares->referral); - res->refs[n + 1] = NULL; - break; - - case LDB_REPLY_DONE: - /* TODO: we should really support controls on entries - * and referrals too! */ - res->controls = talloc_move(res, &ares->controls); - - /* this is the last message, and means the request is done */ - /* we have to signal and eventual ldb_wait() waiting that the - * async request operation was completed */ - talloc_free(ares); - return ldb_request_done(req, LDB_SUCCESS); - } - - talloc_free(ares); - - return LDB_SUCCESS; -} - -int ldb_modify_default_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct ldb_result *res; - unsigned int n; - int ret; - - res = talloc_get_type(req->context, struct ldb_result); - - if (!ares) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - - if (ares->error != LDB_SUCCESS) { - ret = ares->error; - talloc_free(ares); - return ldb_request_done(req, ret); - } - - switch (ares->type) { - case LDB_REPLY_REFERRAL: - if (res->refs) { - for (n = 0; res->refs[n]; n++) /*noop*/ ; - } else { - n = 0; - } - - res->refs = talloc_realloc(res, res->refs, char *, n + 2); - if (! res->refs) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - - res->refs[n] = talloc_move(res->refs, &ares->referral); - res->refs[n + 1] = NULL; - break; - - case LDB_REPLY_DONE: - talloc_free(ares); - return ldb_request_done(req, LDB_SUCCESS); - default: - talloc_free(ares); - ldb_asprintf_errstring(req->handle->ldb, "Invalid LDB reply type %d", ares->type); - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - - talloc_free(ares); - return ldb_request_done(req, LDB_SUCCESS); -} - -int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - int ret; - - if (!ares) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - - if (ares->error != LDB_SUCCESS) { - ret = ares->error; - talloc_free(ares); - return ldb_request_done(req, ret); - } - - if (ares->type != LDB_REPLY_DONE) { - talloc_free(ares); - ldb_asprintf_errstring(req->handle->ldb, "Invalid LDB reply type %d", ares->type); - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - - talloc_free(ares); - return ldb_request_done(req, LDB_SUCCESS); -} - -static struct ldb_request *ldb_build_req_common(TALLOC_CTX *mem_ctx, - struct ldb_context *ldb, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent) -{ - struct ldb_request *req = NULL; - - req = talloc_zero(mem_ctx, struct ldb_request); - if (req == NULL) { - return NULL; - } - req->controls = controls; - req->context = context; - req->callback = callback; - - ldb_set_timeout_from_prev_req(ldb, parent, req); - - if (parent != NULL) { - req->handle = ldb_handle_new_child(req, parent); - if (req->handle == NULL) { - TALLOC_FREE(req); - return NULL; - } - } else { - req->handle = ldb_handle_new(req, ldb); - if (req->handle == NULL) { - TALLOC_FREE(req); - return NULL; - } - } - - return req; -} - -int ldb_build_search_req_ex(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_dn *base, - enum ldb_scope scope, - struct ldb_parse_tree *tree, - const char * const *attrs, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent) -{ - struct ldb_request *req; - - *ret_req = NULL; - - req = ldb_build_req_common(mem_ctx, ldb, controls, - context, callback, parent); - if (req == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_SEARCH; - if (base == NULL) { - req->op.search.base = ldb_dn_new(req, ldb, NULL); - } else { - req->op.search.base = base; - } - req->op.search.scope = scope; - - req->op.search.tree = tree; - if (req->op.search.tree == NULL) { - ldb_set_errstring(ldb, "'tree' can't be NULL"); - talloc_free(req); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->op.search.attrs = attrs; - *ret_req = req; - return LDB_SUCCESS; -} - -int ldb_build_search_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_dn *base, - enum ldb_scope scope, - const char *expression, - const char * const *attrs, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent) -{ - struct ldb_parse_tree *tree; - int ret; - - tree = ldb_parse_tree(mem_ctx, expression); - if (tree == NULL) { - ldb_set_errstring(ldb, "Unable to parse search expression"); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_build_search_req_ex(ret_req, ldb, mem_ctx, base, - scope, tree, attrs, controls, - context, callback, parent); - if (ret == LDB_SUCCESS) { - talloc_steal(*ret_req, tree); - } - return ret; -} - -int ldb_build_add_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const struct ldb_message *message, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent) -{ - struct ldb_request *req; - - *ret_req = NULL; - - req = ldb_build_req_common(mem_ctx, ldb, controls, - context, callback, parent); - if (req == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_ADD; - req->op.add.message = message; - *ret_req = req; - return LDB_SUCCESS; -} - -int ldb_build_mod_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const struct ldb_message *message, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent) -{ - struct ldb_request *req; - - *ret_req = NULL; - - req = ldb_build_req_common(mem_ctx, ldb, controls, - context, callback, parent); - if (req == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_MODIFY; - req->op.mod.message = message; - - *ret_req = req; - return LDB_SUCCESS; -} - -int ldb_build_del_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_dn *dn, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent) -{ - struct ldb_request *req; - - *ret_req = NULL; - - req = ldb_build_req_common(mem_ctx, ldb, controls, - context, callback, parent); - if (req == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_DELETE; - req->op.del.dn = dn; - *ret_req = req; - return LDB_SUCCESS; -} - -int ldb_build_rename_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_dn *olddn, - struct ldb_dn *newdn, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent) -{ - struct ldb_request *req; - - *ret_req = NULL; - - req = ldb_build_req_common(mem_ctx, ldb, controls, - context, callback, parent); - if (req == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_RENAME; - req->op.rename.olddn = olddn; - req->op.rename.newdn = newdn; - *ret_req = req; - return LDB_SUCCESS; -} - -int ldb_extended_default_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct ldb_result *res; - - res = talloc_get_type(req->context, struct ldb_result); - - if (!ares) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_request_done(req, ares->error); - } - - if (ares->type == LDB_REPLY_DONE) { - - /* TODO: we should really support controls on entries and referrals too! */ - res->extended = talloc_move(res, &ares->response); - res->controls = talloc_move(res, &ares->controls); - - talloc_free(ares); - return ldb_request_done(req, LDB_SUCCESS); - } - - talloc_free(ares); - ldb_asprintf_errstring(req->handle->ldb, "Invalid LDB reply type %d", ares->type); - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); -} - -int ldb_build_extended_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const char *oid, - void *data, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent) -{ - struct ldb_request *req; - - *ret_req = NULL; - - req = ldb_build_req_common(mem_ctx, ldb, controls, - context, callback, parent); - if (req == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_EXTENDED; - req->op.extended.oid = oid; - req->op.extended.data = data; - *ret_req = req; - return LDB_SUCCESS; -} - -int ldb_extended(struct ldb_context *ldb, - const char *oid, - void *data, - struct ldb_result **_res) -{ - struct ldb_request *req; - int ret; - struct ldb_result *res; - - *_res = NULL; - req = NULL; - - res = talloc_zero(ldb, struct ldb_result); - if (!res) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_build_extended_req(&req, ldb, ldb, - oid, data, NULL, - res, ldb_extended_default_callback, - NULL); - ldb_req_set_location(req, "ldb_extended"); - - if (ret != LDB_SUCCESS) goto done; - - ldb_set_timeout(ldb, req, 0); /* use default timeout */ - - ret = ldb_request(ldb, req); - - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - -done: - if (ret != LDB_SUCCESS) { - talloc_free(res); - res = NULL; - } - - talloc_free(req); - - *_res = res; - return ret; -} - -/* - note that ldb_search() will automatically replace a NULL 'base' value - with the defaultNamingContext from the rootDSE if available. -*/ -int ldb_search(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - struct ldb_result **result, struct ldb_dn *base, - enum ldb_scope scope, const char * const *attrs, - const char *exp_fmt, ...) -{ - struct ldb_request *req; - struct ldb_result *res; - char *expression; - va_list ap; - int ret; - - expression = NULL; - *result = NULL; - req = NULL; - - res = talloc_zero(mem_ctx, struct ldb_result); - if (!res) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (exp_fmt) { - va_start(ap, exp_fmt); - expression = talloc_vasprintf(mem_ctx, exp_fmt, ap); - va_end(ap); - - if (!expression) { - talloc_free(res); - return LDB_ERR_OPERATIONS_ERROR; - } - } - - ret = ldb_build_search_req(&req, ldb, mem_ctx, - base?base:ldb_get_default_basedn(ldb), - scope, - expression, - attrs, - NULL, - res, - ldb_search_default_callback, - NULL); - ldb_req_set_location(req, "ldb_search"); - - if (ret != LDB_SUCCESS) goto done; - - ret = ldb_request(ldb, req); - - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - -done: - if (ret != LDB_SUCCESS) { - talloc_free(res); - res = NULL; - } - - talloc_free(expression); - talloc_free(req); - - *result = res; - return ret; -} - -/* - add a record to the database. Will fail if a record with the given class - and key already exists -*/ -int ldb_add(struct ldb_context *ldb, - const struct ldb_message *message) -{ - struct ldb_request *req; - int ret; - - ret = ldb_msg_sanity_check(ldb, message); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_build_add_req(&req, ldb, ldb, - message, - NULL, - NULL, - ldb_op_default_callback, - NULL); - ldb_req_set_location(req, "ldb_add"); - - if (ret != LDB_SUCCESS) return ret; - - /* do request and autostart a transaction */ - ret = ldb_autotransaction_request(ldb, req); - - talloc_free(req); - return ret; -} - -/* - modify the specified attributes of a record -*/ -int ldb_modify(struct ldb_context *ldb, - const struct ldb_message *message) -{ - struct ldb_request *req; - int ret; - - ret = ldb_msg_sanity_check(ldb, message); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_build_mod_req(&req, ldb, ldb, - message, - NULL, - NULL, - ldb_op_default_callback, - NULL); - ldb_req_set_location(req, "ldb_modify"); - - if (ret != LDB_SUCCESS) return ret; - - /* do request and autostart a transaction */ - ret = ldb_autotransaction_request(ldb, req); - - talloc_free(req); - return ret; -} - - -/* - delete a record from the database -*/ -int ldb_delete(struct ldb_context *ldb, struct ldb_dn *dn) -{ - struct ldb_request *req; - int ret; - - ret = ldb_build_del_req(&req, ldb, ldb, - dn, - NULL, - NULL, - ldb_op_default_callback, - NULL); - ldb_req_set_location(req, "ldb_delete"); - - if (ret != LDB_SUCCESS) return ret; - - /* do request and autostart a transaction */ - ret = ldb_autotransaction_request(ldb, req); - - talloc_free(req); - return ret; -} - -/* - rename a record in the database -*/ -int ldb_rename(struct ldb_context *ldb, - struct ldb_dn *olddn, struct ldb_dn *newdn) -{ - struct ldb_request *req; - int ret; - - ret = ldb_build_rename_req(&req, ldb, ldb, - olddn, - newdn, - NULL, - NULL, - ldb_op_default_callback, - NULL); - ldb_req_set_location(req, "ldb_rename"); - - if (ret != LDB_SUCCESS) return ret; - - /* do request and autostart a transaction */ - ret = ldb_autotransaction_request(ldb, req); - - talloc_free(req); - return ret; -} - - -/* - return the global sequence number -*/ -int ldb_sequence_number(struct ldb_context *ldb, - enum ldb_sequence_type type, uint64_t *seq_num) -{ - struct ldb_seqnum_request *seq; - struct ldb_seqnum_result *seqr; - struct ldb_result *res; - TALLOC_CTX *tmp_ctx; - int ret; - - *seq_num = 0; - - tmp_ctx = talloc_zero(ldb, struct ldb_request); - if (tmp_ctx == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - seq = talloc_zero(tmp_ctx, struct ldb_seqnum_request); - if (seq == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - seq->type = type; - - ret = ldb_extended(ldb, LDB_EXTENDED_SEQUENCE_NUMBER, seq, &res); - if (ret != LDB_SUCCESS) { - goto done; - } - talloc_steal(tmp_ctx, res); - - if (strcmp(LDB_EXTENDED_SEQUENCE_NUMBER, res->extended->oid) != 0) { - ldb_set_errstring(ldb, "Invalid OID in reply"); - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - seqr = talloc_get_type(res->extended->data, - struct ldb_seqnum_result); - *seq_num = seqr->seq_num; - -done: - talloc_free(tmp_ctx); - return ret; -} - -/* - return extended error information -*/ -const char *ldb_errstring(struct ldb_context *ldb) -{ - if (ldb->err_string) { - return ldb->err_string; - } - - return NULL; -} - -/* - return a string explaining what a ldb error constant meancs -*/ -const char *ldb_strerror(int ldb_err) -{ - switch (ldb_err) { - case LDB_SUCCESS: - return "Success"; - case LDB_ERR_OPERATIONS_ERROR: - return "Operations error"; - case LDB_ERR_PROTOCOL_ERROR: - return "Protocol error"; - case LDB_ERR_TIME_LIMIT_EXCEEDED: - return "Time limit exceeded"; - case LDB_ERR_SIZE_LIMIT_EXCEEDED: - return "Size limit exceeded"; - case LDB_ERR_COMPARE_FALSE: - return "Compare false"; - case LDB_ERR_COMPARE_TRUE: - return "Compare true"; - case LDB_ERR_AUTH_METHOD_NOT_SUPPORTED: - return "Auth method not supported"; - case LDB_ERR_STRONG_AUTH_REQUIRED: - return "Strong auth required"; -/* 9 RESERVED */ - case LDB_ERR_REFERRAL: - return "Referral error"; - case LDB_ERR_ADMIN_LIMIT_EXCEEDED: - return "Admin limit exceeded"; - case LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION: - return "Unsupported critical extension"; - case LDB_ERR_CONFIDENTIALITY_REQUIRED: - return "Confidentiality required"; - case LDB_ERR_SASL_BIND_IN_PROGRESS: - return "SASL bind in progress"; - case LDB_ERR_NO_SUCH_ATTRIBUTE: - return "No such attribute"; - case LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE: - return "Undefined attribute type"; - case LDB_ERR_INAPPROPRIATE_MATCHING: - return "Inappropriate matching"; - case LDB_ERR_CONSTRAINT_VIOLATION: - return "Constraint violation"; - case LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS: - return "Attribute or value exists"; - case LDB_ERR_INVALID_ATTRIBUTE_SYNTAX: - return "Invalid attribute syntax"; -/* 22-31 unused */ - case LDB_ERR_NO_SUCH_OBJECT: - return "No such object"; - case LDB_ERR_ALIAS_PROBLEM: - return "Alias problem"; - case LDB_ERR_INVALID_DN_SYNTAX: - return "Invalid DN syntax"; -/* 35 RESERVED */ - case LDB_ERR_ALIAS_DEREFERENCING_PROBLEM: - return "Alias dereferencing problem"; -/* 37-47 unused */ - case LDB_ERR_INAPPROPRIATE_AUTHENTICATION: - return "Inappropriate authentication"; - case LDB_ERR_INVALID_CREDENTIALS: - return "Invalid credentials"; - case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: - return "insufficient access rights"; - case LDB_ERR_BUSY: - return "Busy"; - case LDB_ERR_UNAVAILABLE: - return "Unavailable"; - case LDB_ERR_UNWILLING_TO_PERFORM: - return "Unwilling to perform"; - case LDB_ERR_LOOP_DETECT: - return "Loop detect"; -/* 55-63 unused */ - case LDB_ERR_NAMING_VIOLATION: - return "Naming violation"; - case LDB_ERR_OBJECT_CLASS_VIOLATION: - return "Object class violation"; - case LDB_ERR_NOT_ALLOWED_ON_NON_LEAF: - return "Not allowed on non-leaf"; - case LDB_ERR_NOT_ALLOWED_ON_RDN: - return "Not allowed on RDN"; - case LDB_ERR_ENTRY_ALREADY_EXISTS: - return "Entry already exists"; - case LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED: - return "Object class mods prohibited"; -/* 70 RESERVED FOR CLDAP */ - case LDB_ERR_AFFECTS_MULTIPLE_DSAS: - return "Affects multiple DSAs"; -/* 72-79 unused */ - case LDB_ERR_OTHER: - return "Other"; - } - - return "Unknown error"; -} - -/* - set backend specific opaque parameters -*/ -int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value) -{ - struct ldb_opaque *o; - - /* allow updating an existing value */ - for (o=ldb->opaque;o;o=o->next) { - if (strcmp(o->name, name) == 0) { - o->value = value; - return LDB_SUCCESS; - } - } - - o = talloc(ldb, struct ldb_opaque); - if (o == NULL) { - ldb_oom(ldb); - return LDB_ERR_OTHER; - } - o->next = ldb->opaque; - o->name = name; - o->value = value; - ldb->opaque = o; - return LDB_SUCCESS; -} - -/* - get a previously set opaque value -*/ -void *ldb_get_opaque(struct ldb_context *ldb, const char *name) -{ - struct ldb_opaque *o; - for (o=ldb->opaque;o;o=o->next) { - if (strcmp(o->name, name) == 0) { - return o->value; - } - } - return NULL; -} - -int ldb_global_init(void) -{ - /* Provided for compatibility with some older versions of ldb */ - return 0; -} - -/* return the ldb flags */ -unsigned int ldb_get_flags(struct ldb_context *ldb) -{ - return ldb->flags; -} - -/* set the ldb flags */ -void ldb_set_flags(struct ldb_context *ldb, unsigned flags) -{ - ldb->flags = flags; -} - - -/* - set the location in a ldb request. Used for debugging - */ -void ldb_req_set_location(struct ldb_request *req, const char *location) -{ - if (req && req->handle) { - req->handle->location = location; - } -} - -/* - return the location set with dsdb_req_set_location - */ -const char *ldb_req_location(struct ldb_request *req) -{ - return req->handle->location; -} - -/** - mark a request as untrusted. This tells the rootdse module to remove - unregistered controls - */ -void ldb_req_mark_untrusted(struct ldb_request *req) -{ - req->handle->flags |= LDB_HANDLE_FLAG_UNTRUSTED; -} - -/** - mark a request as trusted. - */ -void ldb_req_mark_trusted(struct ldb_request *req) -{ - req->handle->flags &= ~LDB_HANDLE_FLAG_UNTRUSTED; -} - -/** - set custom flags. Those flags are set by applications using ldb, - they are application dependent and the same bit can have different - meaning in different application. - */ -void ldb_req_set_custom_flags(struct ldb_request *req, uint32_t flags) -{ - if (req != NULL && req->handle != NULL) { - req->handle->custom_flags = flags; - } -} - - -/** - get custom flags. Those flags are set by applications using ldb, - they are application dependent and the same bit can have different - meaning in different application. - */ -uint32_t ldb_req_get_custom_flags(struct ldb_request *req) -{ - if (req != NULL && req->handle != NULL) { - return req->handle->custom_flags; - } - - /* - * 0 is not something any better or worse than - * anything else as req or the handle is NULL - */ - return 0; -} - - -/** - * return true if a request is untrusted - */ -bool ldb_req_is_untrusted(struct ldb_request *req) -{ - return (req->handle->flags & LDB_HANDLE_FLAG_UNTRUSTED) != 0; -} diff --git a/ldb-2.0.8/common/ldb_attributes.c b/ldb-2.0.8/common/ldb_attributes.c deleted file mode 100644 index 32f25fd..0000000 --- a/ldb-2.0.8/common/ldb_attributes.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ -/* - register handlers for specific attributes and objectclass relationships - - this allows a backend to store its schema information in any format - it likes (or to not have any schema information at all) while keeping the - message matching logic generic -*/ - -#include "ldb_private.h" -#include "ldb_handlers.h" - -/* - fill in an attribute to the ldb_schema into the supplied buffer - - if flags contains LDB_ATTR_FLAG_ALLOCATED - the attribute name string will be copied using - talloc_strdup(), otherwise it needs to be a static const - string at least with a lifetime longer than the ldb struct! - - the ldb_schema_syntax structure should be a pointer - to a static const struct or at least it needs to be - a struct with a longer lifetime than the ldb context! - -*/ -int ldb_schema_attribute_fill_with_syntax(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const char *attribute, - unsigned flags, - const struct ldb_schema_syntax *syntax, - struct ldb_schema_attribute *a) -{ - a->name = attribute; - a->flags = flags; - a->syntax = syntax; - - if (a->flags & LDB_ATTR_FLAG_ALLOCATED) { - a->name = talloc_strdup(mem_ctx, a->name); - if (a->name == NULL) { - ldb_oom(ldb); - return -1; - } - } - - return 0; -} - -/* - add a attribute to the ldb_schema - - if flags contains LDB_ATTR_FLAG_ALLOCATED - the attribute name string will be copied using - talloc_strdup(), otherwise it needs to be a static const - string at least with a lifetime longer than the ldb struct! - - the ldb_schema_syntax structure should be a pointer - to a static const struct or at least it needs to be - a struct with a longer lifetime than the ldb context! - -*/ -int ldb_schema_attribute_add_with_syntax(struct ldb_context *ldb, - const char *attribute, - unsigned flags, - const struct ldb_schema_syntax *syntax) -{ - unsigned int i, n; - struct ldb_schema_attribute *a; - - if (!syntax) { - return LDB_ERR_OPERATIONS_ERROR; - } - - n = ldb->schema.num_attributes + 1; - - a = talloc_realloc(ldb, ldb->schema.attributes, - struct ldb_schema_attribute, n); - if (a == NULL) { - ldb_oom(ldb); - return -1; - } - ldb->schema.attributes = a; - - for (i = 0; i < ldb->schema.num_attributes; i++) { - int cmp = ldb_attr_cmp(attribute, a[i].name); - if (cmp == 0) { - /* silently ignore attempts to overwrite fixed attributes */ - if (a[i].flags & LDB_ATTR_FLAG_FIXED) { - return 0; - } - if (a[i].flags & LDB_ATTR_FLAG_ALLOCATED) { - talloc_free(discard_const_p(char, a[i].name)); - } - /* To cancel out increment below */ - ldb->schema.num_attributes--; - break; - } else if (cmp < 0) { - memmove(a+i+1, a+i, sizeof(*a) * (ldb->schema.num_attributes-i)); - break; - } - } - ldb->schema.num_attributes++; - - a[i].name = attribute; - a[i].flags = flags; - a[i].syntax = syntax; - - if (a[i].flags & LDB_ATTR_FLAG_ALLOCATED) { - a[i].name = talloc_strdup(a, a[i].name); - if (a[i].name == NULL) { - ldb_oom(ldb); - return -1; - } - } - - return 0; -} - -static const struct ldb_schema_syntax ldb_syntax_default = { - .name = LDB_SYNTAX_OCTET_STRING, - .ldif_read_fn = ldb_handler_copy, - .ldif_write_fn = ldb_handler_copy, - .canonicalise_fn = ldb_handler_copy, - .comparison_fn = ldb_comparison_binary -}; - -static const struct ldb_schema_attribute ldb_attribute_default = { - .name = NULL, - .flags = 0, - .syntax = &ldb_syntax_default -}; - -/* - * Return the attribute handlers for a given attribute - * - * @param ldb ldb context - * @param name attribute name to search for - * @return Always return valid pointer to schema attribute. - * In case there is no attribute with name, - * ldb_attribute_default is returned - */ -static const struct ldb_schema_attribute *ldb_schema_attribute_by_name_internal( - struct ldb_context *ldb, - const char *name) -{ - /* for binary search we need signed variables */ - unsigned int i, e, b = 0; - int r; - const struct ldb_schema_attribute *def = &ldb_attribute_default; - - /* fallback to default attribute implementation */ - if (name == NULL) { - return def; - } - - /* as handlers are sorted, '*' must be the first if present */ - if (strcmp(ldb->schema.attributes[0].name, "*") == 0) { - def = &ldb->schema.attributes[0]; - b = 1; - } - - /* do a binary search on the array */ - e = ldb->schema.num_attributes - 1; - - while ((b <= e) && (e != (unsigned int) -1)) { - i = (b + e) / 2; - - r = ldb_attr_cmp(name, ldb->schema.attributes[i].name); - if (r == 0) { - return &ldb->schema.attributes[i]; - } - if (r < 0) { - e = i - 1; - } else { - b = i + 1; - } - } - - return def; -} - -/* - return the attribute handlers for a given attribute -*/ -const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_context *ldb, - const char *name) -{ - if (ldb->schema.attribute_handler_override) { - const struct ldb_schema_attribute *ret = - ldb->schema.attribute_handler_override(ldb, - ldb->schema.attribute_handler_override_private, - name); - if (ret) { - return ret; - } - } - - return ldb_schema_attribute_by_name_internal(ldb, name); -} - - -/* - add to the list of ldif handlers for this ldb context -*/ -void ldb_schema_attribute_remove(struct ldb_context *ldb, const char *name) -{ - const struct ldb_schema_attribute *a; - ptrdiff_t i; - - a = ldb_schema_attribute_by_name_internal(ldb, name); - if (a == NULL || a->name == NULL) { - return; - } - - /* FIXED attributes are never removed */ - if (a->flags & LDB_ATTR_FLAG_FIXED) { - return; - } - - if (a->flags & LDB_ATTR_FLAG_ALLOCATED) { - talloc_free(discard_const_p(char, a->name)); - } - - i = a - ldb->schema.attributes; - if (i < ldb->schema.num_attributes - 1) { - memmove(&ldb->schema.attributes[i], - a+1, sizeof(*a) * (ldb->schema.num_attributes-(i+1))); - } - - ldb->schema.num_attributes--; -} - -/* - remove attributes with a specified flag (eg LDB_ATTR_FLAG_FROM_DB) for this ldb context - - This is to permit correct reloads -*/ -void ldb_schema_attribute_remove_flagged(struct ldb_context *ldb, unsigned int flag) -{ - ptrdiff_t i; - - for (i = 0; i < ldb->schema.num_attributes;) { - const struct ldb_schema_attribute *a - = &ldb->schema.attributes[i]; - /* FIXED attributes are never removed */ - if (a->flags & LDB_ATTR_FLAG_FIXED) { - i++; - continue; - } - if ((a->flags & flag) == 0) { - i++; - continue; - } - if (a->flags & LDB_ATTR_FLAG_ALLOCATED) { - talloc_free(discard_const_p(char, a->name)); - } - if (i < ldb->schema.num_attributes - 1) { - memmove(&ldb->schema.attributes[i], - a+1, sizeof(*a) * (ldb->schema.num_attributes-(i+1))); - } - - ldb->schema.num_attributes--; - } -} - -/* - setup a attribute handler using a standard syntax -*/ -int ldb_schema_attribute_add(struct ldb_context *ldb, - const char *attribute, - unsigned flags, - const char *syntax) -{ - const struct ldb_schema_syntax *s = ldb_standard_syntax_by_name(ldb, syntax); - return ldb_schema_attribute_add_with_syntax(ldb, attribute, flags, s); -} - -/* - setup the attribute handles for well known attributes -*/ -int ldb_setup_wellknown_attributes(struct ldb_context *ldb) -{ - const struct { - const char *attr; - const char *syntax; - } wellknown[] = { - { "dn", LDB_SYNTAX_DN }, - { "distinguishedName", LDB_SYNTAX_DN }, - { "cn", LDB_SYNTAX_DIRECTORY_STRING }, - { "dc", LDB_SYNTAX_DIRECTORY_STRING }, - { "ou", LDB_SYNTAX_DIRECTORY_STRING }, - { "objectClass", LDB_SYNTAX_OBJECTCLASS } - }; - unsigned int i; - int ret; - - for (i=0;ischema.num_dn_extended_syntax + 1; - - a = talloc_realloc(ldb, ldb->schema.dn_extended_syntax, - struct ldb_dn_extended_syntax, n); - - if (!a) { - return LDB_ERR_OPERATIONS_ERROR; - } - - a[ldb->schema.num_dn_extended_syntax] = *syntax; - ldb->schema.dn_extended_syntax = a; - - ldb->schema.num_dn_extended_syntax = n; - - return LDB_SUCCESS; -} - -/* - return the extended dn syntax for a given name -*/ -const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb, - const char *name) -{ - unsigned int i; - for (i=0; i < ldb->schema.num_dn_extended_syntax; i++) { - if (ldb_attr_cmp(ldb->schema.dn_extended_syntax[i].name, name) == 0) { - return &ldb->schema.dn_extended_syntax[i]; - } - } - return NULL; -} - -/* - set an attribute handler override function - used to delegate schema handling - to external code - */ -void ldb_schema_attribute_set_override_handler(struct ldb_context *ldb, - ldb_attribute_handler_override_fn_t override, - void *private_data) -{ - ldb->schema.attribute_handler_override_private = private_data; - ldb->schema.attribute_handler_override = override; -} - -/* - set that the attribute handler override function - used to delegate - schema handling to external code, is handling setting - LDB_ATTR_FLAG_INDEXED - */ -void ldb_schema_set_override_indexlist(struct ldb_context *ldb, - bool one_level_indexes) -{ - ldb->schema.index_handler_override = true; - ldb->schema.one_level_indexes = one_level_indexes; -} - -/* - * set that the GUID index mode is in operation - * - * The caller must ensure the supplied strings do not go out of - * scope (they are typically constant memory). - */ -void ldb_schema_set_override_GUID_index(struct ldb_context *ldb, - const char *GUID_index_attribute, - const char *GUID_index_dn_component) -{ - ldb->schema.GUID_index_attribute = GUID_index_attribute; - ldb->schema.GUID_index_dn_component = GUID_index_dn_component; -} diff --git a/ldb-2.0.8/common/ldb_controls.c b/ldb-2.0.8/common/ldb_controls.c deleted file mode 100644 index e0f0eb4..0000000 --- a/ldb-2.0.8/common/ldb_controls.c +++ /dev/null @@ -1,1319 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb_controls.c - * - * Component: ldb controls utility functions - * - * Description: helper functions for control modules - * - * Author: Simo Sorce - */ - -#include "ldb_private.h" - -/* check if a control with the specified "oid" exist and return it */ -/* returns NULL if not found */ -struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid) -{ - unsigned int i; - - if (req->controls != NULL) { - for (i = 0; req->controls[i]; i++) { - if (req->controls[i]->oid && strcmp(oid, req->controls[i]->oid) == 0) { - break; - } - } - - return req->controls[i]; - } - - return NULL; -} - -/* check if a control with the specified "oid" exist and return it */ -/* returns NULL if not found */ -struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid) -{ - unsigned int i; - - if (rep->controls != NULL) { - for (i = 0; rep->controls[i]; i++) { - if (rep->controls[i]->oid && strcmp(oid, rep->controls[i]->oid) == 0) { - break; - } - } - - return rep->controls[i]; - } - - return NULL; -} - -/* - * Saves the current controls list into the "saver" (can also be NULL) and - * replace the one in "req" with a new one excluding the "exclude" control - * (if it is NULL then the list remains the same) - * - * Returns 0 on error. - */ -int ldb_save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver) -{ - struct ldb_control **lcs, **lcs_old; - unsigned int i, j; - - lcs_old = req->controls; - if (saver != NULL) { - *saver = lcs_old; - } - - for (i = 0; req->controls && req->controls[i]; i++); - if (i == 0) { - req->controls = NULL; - return 1; - } - - lcs = talloc_array(req, struct ldb_control *, i + 1); - if (!lcs) { - return 0; - } - - for (i = 0, j = 0; lcs_old[i]; i++) { - if (exclude == lcs_old[i]) continue; - lcs[j] = lcs_old[i]; - j++; - } - lcs[j] = NULL; - - req->controls = talloc_realloc(req, lcs, struct ldb_control *, j + 1); - if (req->controls == NULL) { - return 0; - } - return 1; -} - -/* - * Returns a list of controls, except the one specified with "exclude" (can - * also be NULL). Included controls become a child of returned list if they - * were children of "controls_in". - * - * Returns NULL on error (OOM) or an empty control list. - */ -struct ldb_control **ldb_controls_except_specified(struct ldb_control **controls_in, - TALLOC_CTX *mem_ctx, - struct ldb_control *exclude) -{ - struct ldb_control **lcs = NULL; - unsigned int i, j, n; - - for (i = 0; controls_in && controls_in[i]; i++); - if (i == 0) { - return NULL; - } - n = i; - - for (i = 0, j = 0; controls_in && controls_in[i]; i++) { - if (exclude == controls_in[i]) continue; - - if (!lcs) { - /* Allocate here so if we remove the only - * control, or there were no controls, we - * don't allocate at all, and just return - * NULL */ - lcs = talloc_array(mem_ctx, struct ldb_control *, - n + 1); - if (!lcs) { - return NULL; - } - } - - lcs[j] = controls_in[i]; - talloc_reparent(controls_in, lcs, lcs[j]); - j++; - } - if (lcs) { - lcs[j] = NULL; - - lcs = talloc_realloc(mem_ctx, lcs, struct ldb_control *, j + 1); - } - - return lcs; -} - -/* check if there's any control marked as critical in the list */ -/* return True if any, False if none */ -int ldb_check_critical_controls(struct ldb_control **controls) -{ - unsigned int i; - - if (controls == NULL) { - return 0; - } - - for (i = 0; controls[i]; i++) { - if (controls[i]->critical) { - return 1; - } - } - - return 0; -} - -int ldb_request_add_control(struct ldb_request *req, const char *oid, bool critical, void *data) -{ - unsigned int i, n; - struct ldb_control **ctrls; - struct ldb_control *ctrl; - - for (n=0; req->controls && req->controls[n];n++) { - /* having two controls of the same OID makes no sense */ - if (req->controls[n]->oid && strcmp(oid, req->controls[n]->oid) == 0) { - return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; - } - } - - ctrls = talloc_array(req, - struct ldb_control *, - n + 2); - if (!ctrls) return LDB_ERR_OPERATIONS_ERROR; - - for (i=0; icontrols[i]; - } - - req->controls = ctrls; - ctrls[n] = NULL; - ctrls[n+1] = NULL; - - ctrl = talloc(ctrls, struct ldb_control); - if (!ctrl) return LDB_ERR_OPERATIONS_ERROR; - - ctrl->oid = talloc_strdup(ctrl, oid); - if (!ctrl->oid) return LDB_ERR_OPERATIONS_ERROR; - ctrl->critical = critical; - ctrl->data = data; - - ctrls[n] = ctrl; - return LDB_SUCCESS; -} - -int ldb_reply_add_control(struct ldb_reply *ares, const char *oid, bool critical, void *data) -{ - unsigned n; - struct ldb_control **ctrls; - struct ldb_control *ctrl; - - for (n=0; ares->controls && ares->controls[n];) { - /* having two controls of the same OID makes no sense */ - if (ares->controls[n]->oid && strcmp(oid, ares->controls[n]->oid) == 0) { - return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; - } - n++; - } - - ctrls = talloc_realloc(ares, ares->controls, - struct ldb_control *, - n + 2); - if (!ctrls) return LDB_ERR_OPERATIONS_ERROR; - ares->controls = ctrls; - ctrls[n] = NULL; - ctrls[n+1] = NULL; - - ctrl = talloc(ctrls, struct ldb_control); - if (!ctrl) return LDB_ERR_OPERATIONS_ERROR; - - ctrl->oid = talloc_strdup(ctrl, oid); - if (!ctrl->oid) return LDB_ERR_OPERATIONS_ERROR; - ctrl->critical = critical; - ctrl->data = data; - - ctrls[n] = ctrl; - return LDB_SUCCESS; -} - -/* Add a control to the request, replacing the old one if it is already in the request */ -int ldb_request_replace_control(struct ldb_request *req, const char *oid, bool critical, void *data) -{ - unsigned int n; - int ret; - - ret = ldb_request_add_control(req, oid, critical, data); - if (ret != LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) { - return ret; - } - - for (n=0; req->controls[n];n++) { - if (req->controls[n]->oid && strcmp(oid, req->controls[n]->oid) == 0) { - req->controls[n]->critical = critical; - req->controls[n]->data = data; - return LDB_SUCCESS; - } - } - - return LDB_ERR_OPERATIONS_ERROR; -} - -/* - * Return a control as string - * the project (ie. name:value1:value2:...:valuen - * The string didn't include the criticity of the critical flag - */ -char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *control) -{ - char *res = NULL; - - if (strcmp(control->oid, LDB_CONTROL_PAGED_RESULTS_OID) == 0) { - struct ldb_paged_control *rep_control = talloc_get_type(control->data, struct ldb_paged_control); - char *cookie; - - cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, rep_control->cookie_len); - if (cookie == NULL) { - return NULL; - } - if (cookie[0] != '\0') { - res = talloc_asprintf(mem_ctx, "%s:%d:%s", - LDB_CONTROL_PAGED_RESULTS_NAME, - control->critical, - cookie); - - talloc_free(cookie); - } else { - res = talloc_asprintf(mem_ctx, "%s:%d", - LDB_CONTROL_PAGED_RESULTS_NAME, - control->critical); - } - return res; - } - - if (strcmp(control->oid, LDB_CONTROL_VLV_RESP_OID) == 0) { - struct ldb_vlv_resp_control *rep_control = talloc_get_type(control->data, - struct ldb_vlv_resp_control); - - char *cookie; - - cookie = ldb_base64_encode(mem_ctx, - (char *)rep_control->contextId, - rep_control->ctxid_len); - if (cookie == NULL) { - return NULL; - } - - res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%d:%s", - LDB_CONTROL_VLV_RESP_NAME, - control->critical, - rep_control->targetPosition, - rep_control->contentCount, - rep_control->vlv_result, - cookie); - - return res; - } - - if (strcmp(control->oid, LDB_CONTROL_SORT_RESP_OID) == 0) { - struct ldb_sort_resp_control *rep_control = talloc_get_type(control->data, - struct ldb_sort_resp_control); - - res = talloc_asprintf(mem_ctx, "%s:%d:%d:%s", - LDB_CONTROL_SORT_RESP_NAME, - control->critical, - rep_control->result, - rep_control->attr_desc); - - return res; - } - - if (strcmp(control->oid, LDB_CONTROL_ASQ_OID) == 0) { - struct ldb_asq_control *rep_control = talloc_get_type(control->data, - struct ldb_asq_control); - - res = talloc_asprintf(mem_ctx, "%s:%d:%d", - LDB_CONTROL_SORT_RESP_NAME, - control->critical, - rep_control->result); - - return res; - } - - if (strcmp(control->oid, LDB_CONTROL_DIRSYNC_OID) == 0) { - char *cookie; - struct ldb_dirsync_control *rep_control = talloc_get_type(control->data, - struct ldb_dirsync_control); - - cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, - rep_control->cookie_len); - if (cookie == NULL) { - return NULL; - } - res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%s", - LDB_CONTROL_DIRSYNC_NAME, - control->critical, - rep_control->flags, - rep_control->max_attributes, - cookie); - - talloc_free(cookie); - return res; - } - if (strcmp(control->oid, LDB_CONTROL_DIRSYNC_EX_OID) == 0) { - char *cookie; - struct ldb_dirsync_control *rep_control = talloc_get_type(control->data, - struct ldb_dirsync_control); - - cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, - rep_control->cookie_len); - if (cookie == NULL) { - return NULL; - } - res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%s", - LDB_CONTROL_DIRSYNC_EX_NAME, - control->critical, - rep_control->flags, - rep_control->max_attributes, - cookie); - - talloc_free(cookie); - return res; - } - - if (strcmp(control->oid, LDB_CONTROL_VERIFY_NAME_OID) == 0) { - struct ldb_verify_name_control *rep_control = talloc_get_type(control->data, struct ldb_verify_name_control); - - if (rep_control->gc != NULL) { - res = talloc_asprintf(mem_ctx, "%s:%d:%d:%s", - LDB_CONTROL_VERIFY_NAME_NAME, - control->critical, - rep_control->flags, - rep_control->gc); - - } else { - res = talloc_asprintf(mem_ctx, "%s:%d:%d", - LDB_CONTROL_VERIFY_NAME_NAME, - control->critical, - rep_control->flags); - } - return res; - } - - /* - * From here we don't know the control - */ - if (control->data == NULL) { - /* - * We don't know the control but there is no real data attached - * to it so we can represent it with local_oid:oid:criticity. - */ - res = talloc_asprintf(mem_ctx, "local_oid:%s:%d", - control->oid, - control->critical); - } else { - res = talloc_asprintf(mem_ctx, "unknown oid:%s", - control->oid); - } - return res; -} - - -/* - * A little trick to allow one to use constants defined in headers rather than - * hardwritten in the file. - * "sizeof" will return the \0 char as well so it will take the place of ":" - * in the length of the string. - */ -#define LDB_CONTROL_CMP(control, NAME) strncmp(control, NAME ":", sizeof(NAME)) - -/* Parse one string and return associated control if parsing is successful*/ -struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *control_strings) -{ - struct ldb_control *ctrl; - - if (!(ctrl = talloc(mem_ctx, struct ldb_control))) { - ldb_oom(ldb); - return NULL; - } - - if (LDB_CONTROL_CMP(control_strings, - LDB_CONTROL_VLV_REQ_NAME) == 0) { - struct ldb_vlv_req_control *control; - const char *p; - char attr[1024]; - char ctxid[1024]; - int crit, bc, ac, os, cc, ret; - - attr[0] = '\0'; - ctxid[0] = '\0'; - p = &(control_strings[sizeof(LDB_CONTROL_VLV_REQ_NAME)]); - ret = sscanf(p, "%d:%d:%d:%d:%d:%1023[^$]", &crit, &bc, &ac, &os, &cc, ctxid); - /* We allow 2 ways to encode the GT_EQ case, because the - comparison string might contain null bytes or colons, which - would break sscanf (or indeed any parsing mechanism). */ - if (ret == 3) { - ret = sscanf(p, "%d:%d:%d:>=%1023[^:]:%1023[^$]", &crit, &bc, &ac, attr, ctxid); - } - if (ret == 3) { - int len; - ret = sscanf(p, "%d:%d:%d:base64>=%1023[^:]:%1023[^$]", &crit, &bc, &ac, attr, ctxid); - len = ldb_base64_decode(attr); - if (len < 0) { - ret = -1; - } - } - - if ((ret < 4) || (crit < 0) || (crit > 1)) { - ldb_set_errstring(ldb, - "invalid VLV control syntax\n" - " syntax: crit(b):bc(n):ac(n):" - "{os(n):cc(n)|>=val(s)|base64>=val(o)}[:ctxid(o)]\n" - " note: b = boolean, n = number, s = string, o = b64 binary blob"); - talloc_free(ctrl); - return NULL; - } - ctrl->oid = LDB_CONTROL_VLV_REQ_OID; - ctrl->critical = crit; - if (!(control = talloc(ctrl, - struct ldb_vlv_req_control))) { - ldb_oom(ldb); - talloc_free(ctrl); - return NULL; - } - control->beforeCount = bc; - control->afterCount = ac; - if (attr[0]) { - control->type = 1; - control->match.gtOrEq.value = talloc_strdup(control, attr); - control->match.gtOrEq.value_len = strlen(attr); - } else { - control->type = 0; - control->match.byOffset.offset = os; - control->match.byOffset.contentCount = cc; - } - if (ctxid[0]) { - int len = ldb_base64_decode(ctxid); - if (len < 0) { - ldb_set_errstring(ldb, - "invalid VLV context_id\n"); - talloc_free(ctrl); - return NULL; - } - control->ctxid_len = len; - control->contextId = talloc_memdup(control, ctxid, - control->ctxid_len); - if (control->contextId == NULL) { - ldb_oom(ldb); - talloc_free(ctrl); - return NULL; - } - } else { - control->ctxid_len = 0; - control->contextId = NULL; - } - ctrl->data = control; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DIRSYNC_NAME) == 0) { - struct ldb_dirsync_control *control; - const char *p; - char *cookie = NULL; - int crit, max_attrs, ret; - uint32_t flags; - - cookie = talloc_zero_array(ctrl, char, - strlen(control_strings) + 1); - if (cookie == NULL) { - ldb_oom(ldb); - talloc_free(ctrl); - return NULL; - } - - p = &(control_strings[sizeof(LDB_CONTROL_DIRSYNC_NAME)]); - ret = sscanf(p, "%d:%u:%d:%[^$]", &crit, &flags, &max_attrs, cookie); - - if ((ret < 3) || (crit < 0) || (crit > 1) || (max_attrs < 0)) { - ldb_set_errstring(ldb, - "invalid dirsync control syntax\n" - " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n" - " note: b = boolean, n = number, o = b64 binary blob"); - talloc_free(ctrl); - return NULL; - } - - /* w2k3 seems to ignore the parameter, - * but w2k sends a wrong cookie when this value is to small - * this would cause looping forever, while getting - * the same data and same cookie forever - */ - if (max_attrs == 0) max_attrs = 0x0FFFFFFF; - - ctrl->oid = LDB_CONTROL_DIRSYNC_OID; - ctrl->critical = crit; - control = talloc(ctrl, struct ldb_dirsync_control); - if (control == NULL) { - ldb_oom(ldb); - talloc_free(ctrl); - return NULL; - } - control->flags = flags; - control->max_attributes = max_attrs; - if (*cookie) { - int len = ldb_base64_decode(cookie); - if (len < 0) { - ldb_set_errstring(ldb, - "invalid dirsync cookie\n"); - talloc_free(ctrl); - return NULL; - } - control->cookie_len = len; - control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len); - if (control->cookie == NULL) { - ldb_oom(ldb); - talloc_free(ctrl); - return NULL; - } - } else { - control->cookie = NULL; - control->cookie_len = 0; - } - ctrl->data = control; - TALLOC_FREE(cookie); - - return ctrl; - } - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DIRSYNC_EX_NAME) == 0) { - struct ldb_dirsync_control *control; - const char *p; - char *cookie = NULL; - int crit, max_attrs, ret; - uint32_t flags; - - cookie = talloc_zero_array(ctrl, char, - strlen(control_strings) + 1); - if (cookie == NULL) { - ldb_oom(ldb); - talloc_free(ctrl); - return NULL; - } - - p = &(control_strings[sizeof(LDB_CONTROL_DIRSYNC_EX_NAME)]); - ret = sscanf(p, "%d:%u:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie); - - if ((ret < 3) || (crit < 0) || (crit > 1) || (max_attrs < 0)) { - ldb_set_errstring(ldb, - "invalid dirsync_ex control syntax\n" - " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n" - " note: b = boolean, n = number, o = b64 binary blob"); - talloc_free(ctrl); - return NULL; - } - - /* w2k3 seems to ignore the parameter, - * but w2k sends a wrong cookie when this value is to small - * this would cause looping forever, while getting - * the same data and same cookie forever - */ - if (max_attrs == 0) max_attrs = 0x0FFFFFFF; - - ctrl->oid = LDB_CONTROL_DIRSYNC_EX_OID; - ctrl->critical = crit; - control = talloc(ctrl, struct ldb_dirsync_control); - if (control == NULL) { - ldb_oom(ldb); - talloc_free(ctrl); - return NULL; - } - control->flags = flags; - control->max_attributes = max_attrs; - if (*cookie) { - int len = ldb_base64_decode(cookie); - if (len < 0) { - ldb_set_errstring(ldb, - "invalid dirsync_ex cookie" - " (probably too long)\n"); - talloc_free(ctrl); - return NULL; - } - control->cookie_len = len; - control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len); - if (control->cookie == NULL) { - ldb_oom(ldb); - talloc_free(ctrl); - return NULL; - } - } else { - control->cookie = NULL; - control->cookie_len = 0; - } - ctrl->data = control; - TALLOC_FREE(cookie); - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_ASQ_NAME) == 0) { - struct ldb_asq_control *control; - const char *p; - char attr[256]; - int crit, ret; - - attr[0] = '\0'; - p = &(control_strings[sizeof(LDB_CONTROL_ASQ_NAME)]); - ret = sscanf(p, "%d:%255[^$]", &crit, attr); - if ((ret != 2) || (crit < 0) || (crit > 1) || (attr[0] == '\0')) { - ldb_set_errstring(ldb, - "invalid asq control syntax\n" - " syntax: crit(b):attr(s)\n" - " note: b = boolean, s = string"); - talloc_free(ctrl); - return NULL; - } - - ctrl->oid = LDB_CONTROL_ASQ_OID; - ctrl->critical = crit; - control = talloc(ctrl, struct ldb_asq_control); - if (control == NULL) { - ldb_oom(ldb); - talloc_free(ctrl); - return NULL; - } - control->request = 1; - control->source_attribute = talloc_strdup(control, attr); - control->src_attr_len = strlen(attr); - ctrl->data = control; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_EXTENDED_DN_NAME) == 0) { - struct ldb_extended_dn_control *control; - const char *p; - int crit, type, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_EXTENDED_DN_NAME)]); - ret = sscanf(p, "%d:%d", &crit, &type); - if ((ret != 2) || (crit < 0) || (crit > 1) || (type < 0) || (type > 1)) { - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - ldb_set_errstring(ldb, - "invalid extended_dn control syntax\n" - " syntax: crit(b)[:type(i)]\n" - " note: b = boolean\n" - " i = integer\n" - " valid values are: 0 - hexadecimal representation\n" - " 1 - normal string representation"); - talloc_free(ctrl); - return NULL; - } - control = NULL; - } else { - control = talloc(ctrl, struct ldb_extended_dn_control); - if (control == NULL) { - ldb_oom(ldb); - talloc_free(ctrl); - return NULL; - } - control->type = type; - } - - ctrl->oid = LDB_CONTROL_EXTENDED_DN_OID; - ctrl->critical = crit; - ctrl->data = talloc_steal(ctrl, control); - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SD_FLAGS_NAME) == 0) { - struct ldb_sd_flags_control *control; - const char *p; - int crit, ret; - unsigned secinfo_flags; - - p = &(control_strings[sizeof(LDB_CONTROL_SD_FLAGS_NAME)]); - ret = sscanf(p, "%d:%u", &crit, &secinfo_flags); - if ((ret != 2) || (crit < 0) || (crit > 1) || (secinfo_flags > 0xF)) { - ldb_set_errstring(ldb, - "invalid sd_flags control syntax\n" - " syntax: crit(b):secinfo_flags(n)\n" - " note: b = boolean, n = number"); - talloc_free(ctrl); - return NULL; - } - - ctrl->oid = LDB_CONTROL_SD_FLAGS_OID; - ctrl->critical = crit; - control = talloc(ctrl, struct ldb_sd_flags_control); - if (control == NULL) { - ldb_oom(ldb); - talloc_free(ctrl); - return NULL; - } - - control->secinfo_flags = secinfo_flags; - ctrl->data = control; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SEARCH_OPTIONS_NAME) == 0) { - struct ldb_search_options_control *control; - const char *p; - int crit, ret; - unsigned search_options; - - p = &(control_strings[sizeof(LDB_CONTROL_SEARCH_OPTIONS_NAME)]); - ret = sscanf(p, "%d:%u", &crit, &search_options); - if ((ret != 2) || (crit < 0) || (crit > 1) || (search_options > 0xF)) { - ldb_set_errstring(ldb, - "invalid search_options control syntax\n" - " syntax: crit(b):search_options(n)\n" - " note: b = boolean, n = number"); - talloc_free(ctrl); - return NULL; - } - - ctrl->oid = LDB_CONTROL_SEARCH_OPTIONS_OID; - ctrl->critical = crit; - control = talloc(ctrl, struct ldb_search_options_control); - if (control == NULL) { - ldb_oom(ldb); - talloc_free(ctrl); - return NULL; - } - - control->search_options = search_options; - ctrl->data = control; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_BYPASS_OPERATIONAL_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_BYPASS_OPERATIONAL_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - ldb_set_errstring(ldb, - "invalid bypassopreational control syntax\n" - " syntax: crit(b)\n" - " note: b = boolean"); - talloc_free(ctrl); - return NULL; - } - - ctrl->oid = LDB_CONTROL_BYPASS_OPERATIONAL_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RELAX_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_RELAX_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - ldb_set_errstring(ldb, - "invalid relax control syntax\n" - " syntax: crit(b)\n" - " note: b = boolean"); - talloc_free(ctrl); - return NULL; - } - - ctrl->oid = LDB_CONTROL_RELAX_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RECALCULATE_SD_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_RECALCULATE_SD_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - ldb_set_errstring(ldb, - "invalid recalculate_sd control syntax\n" - " syntax: crit(b)\n" - " note: b = boolean"); - talloc_free(ctrl); - return NULL; - } - - ctrl->oid = LDB_CONTROL_RECALCULATE_SD_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DOMAIN_SCOPE_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_DOMAIN_SCOPE_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - ldb_set_errstring(ldb, - "invalid domain_scope control syntax\n" - " syntax: crit(b)\n" - " note: b = boolean"); - talloc_free(ctrl); - return NULL; - } - - ctrl->oid = LDB_CONTROL_DOMAIN_SCOPE_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PAGED_RESULTS_NAME) == 0) { - struct ldb_paged_control *control; - const char *p; - char cookie[1024]; - int crit, size, ret; - - cookie[0] = '\0'; - p = &(control_strings[sizeof(LDB_CONTROL_PAGED_RESULTS_NAME)]); - ret = sscanf(p, "%d:%d:%1023[^$]", &crit, &size, cookie); - if ((ret < 2) || (ret > 3) || (crit < 0) || (crit > 1) || - (size < 0)) { - ldb_set_errstring(ldb, - "invalid paged_results control syntax\n" - " syntax: crit(b):size(n)[:cookie(base64)]\n" - " note: b = boolean, n = number"); - talloc_free(ctrl); - return NULL; - } - - ctrl->oid = LDB_CONTROL_PAGED_RESULTS_OID; - ctrl->critical = crit; - control = talloc(ctrl, struct ldb_paged_control); - if (control == NULL) { - ldb_oom(ldb); - talloc_free(ctrl); - return NULL; - } - - control->size = size; - if (cookie[0] != '\0') { - int len = ldb_base64_decode(cookie); - if (len < 0) { - ldb_set_errstring(ldb, - "invalid paged_results cookie" - " (probably too long)\n"); - talloc_free(ctrl); - return NULL; - } - control->cookie_len = len; - control->cookie = talloc_memdup(control, cookie, control->cookie_len); - if (control->cookie == NULL) { - ldb_oom(ldb); - talloc_free(ctrl); - return NULL; - } - } else { - control->cookie = NULL; - control->cookie_len = 0; - } - ctrl->data = control; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SERVER_SORT_NAME) == 0) { - struct ldb_server_sort_control **control; - const char *p; - char attr[256]; - char rule[128]; - int crit, rev, ret; - - attr[0] = '\0'; - rule[0] = '\0'; - p = &(control_strings[sizeof(LDB_CONTROL_SERVER_SORT_NAME)]); - ret = sscanf(p, "%d:%d:%255[^:]:%127[^:]", &crit, &rev, attr, rule); - if ((ret < 3) || (crit < 0) || (crit > 1) || (rev < 0 ) || (rev > 1) ||attr[0] == '\0') { - ldb_set_errstring(ldb, - "invalid server_sort control syntax\n" - " syntax: crit(b):rev(b):attr(s)[:rule(s)]\n" - " note: b = boolean, s = string"); - talloc_free(ctrl); - return NULL; - } - ctrl->oid = LDB_CONTROL_SERVER_SORT_OID; - ctrl->critical = crit; - control = talloc_array(ctrl, struct ldb_server_sort_control *, 2); - if (control == NULL) { - ldb_oom(ldb); - talloc_free(ctrl); - return NULL; - } - - control[0] = talloc(control, struct ldb_server_sort_control); - if (control[0] == NULL) { - ldb_oom(ldb); - talloc_free(ctrl); - return NULL; - } - - control[0]->attributeName = talloc_strdup(control, attr); - if (control[0]->attributeName == NULL) { - ldb_oom(ldb); - talloc_free(ctrl); - return NULL; - } - - if (rule[0]) { - control[0]->orderingRule = talloc_strdup(control, rule); - if (control[0]->orderingRule == NULL) { - ldb_oom(ldb); - talloc_free(ctrl); - return NULL; - } - } else { - control[0]->orderingRule = NULL; - } - control[0]->reverse = rev; - control[1] = NULL; - ctrl->data = control; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_NOTIFICATION_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_NOTIFICATION_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - ldb_set_errstring(ldb, - "invalid notification control syntax\n" - " syntax: crit(b)\n" - " note: b = boolean"); - talloc_free(ctrl); - return NULL; - } - - ctrl->oid = LDB_CONTROL_NOTIFICATION_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_TREE_DELETE_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_TREE_DELETE_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - ldb_set_errstring(ldb, - "invalid tree_delete control syntax\n" - " syntax: crit(b)\n" - " note: b = boolean"); - talloc_free(ctrl); - return NULL; - } - - ctrl->oid = LDB_CONTROL_TREE_DELETE_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_DELETED_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_SHOW_DELETED_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - ldb_set_errstring(ldb, - "invalid show_deleted control syntax\n" - " syntax: crit(b)\n" - " note: b = boolean"); - talloc_free(ctrl); - return NULL; - } - - ctrl->oid = LDB_CONTROL_SHOW_DELETED_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - ldb_set_errstring(ldb, - "invalid show_deactivated_link control syntax\n" - " syntax: crit(b)\n" - " note: b = boolean"); - talloc_free(ctrl); - return NULL; - } - - ctrl->oid = LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_RECYCLED_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_SHOW_RECYCLED_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - ldb_set_errstring(ldb, - "invalid show_recycled control syntax\n" - " syntax: crit(b)\n" - " note: b = boolean"); - talloc_free(ctrl); - return NULL; - } - - ctrl->oid = LDB_CONTROL_SHOW_RECYCLED_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PERMISSIVE_MODIFY_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_PERMISSIVE_MODIFY_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - ldb_set_errstring(ldb, - "invalid permissive_modify control syntax\n" - " syntax: crit(b)\n" - " note: b = boolean"); - talloc_free(ctrl); - return NULL; - } - - ctrl->oid = LDB_CONTROL_PERMISSIVE_MODIFY_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_REVEAL_INTERNALS_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_REVEAL_INTERNALS_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - ldb_set_errstring(ldb, - "invalid reveal_internals control syntax\n" - " syntax: crit(b)\n" - " note: b = boolean"); - talloc_free(ctrl); - return NULL; - } - - ctrl->oid = LDB_CONTROL_REVEAL_INTERNALS; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (strncmp(control_strings, "local_oid:", 10) == 0) { - const char *p; - int crit = 0, ret = 0; - char oid[256]; - - oid[0] = '\0'; - p = &(control_strings[10]); - ret = sscanf(p, "%255[^:]:%d", oid, &crit); - - if ((ret != 2) || strlen(oid) == 0 || (crit < 0) || (crit > 1)) { - ldb_set_errstring(ldb, - "invalid local_oid control syntax\n" - " syntax: oid(s):crit(b)\n" - " note: b = boolean, s = string"); - talloc_free(ctrl); - return NULL; - } - - ctrl->oid = talloc_strdup(ctrl, oid); - if (!ctrl->oid) { - ldb_oom(ldb); - talloc_free(ctrl); - return NULL; - } - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RODC_DCPROMO_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_RODC_DCPROMO_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - ldb_set_errstring(ldb, - "invalid rodc_join control syntax\n" - " syntax: crit(b)\n" - " note: b = boolean"); - talloc_free(ctrl); - return NULL; - } - - ctrl->oid = LDB_CONTROL_RODC_DCPROMO_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PROVISION_NAME) == 0) { - const char *p; - int crit, ret; - - p = &(control_strings[sizeof(LDB_CONTROL_PROVISION_NAME)]); - ret = sscanf(p, "%d", &crit); - if ((ret != 1) || (crit < 0) || (crit > 1)) { - ldb_set_errstring(ldb, - "invalid provision control syntax\n" - " syntax: crit(b)\n" - " note: b = boolean"); - talloc_free(ctrl); - return NULL; - } - - ctrl->oid = LDB_CONTROL_PROVISION_OID; - ctrl->critical = crit; - ctrl->data = NULL; - - return ctrl; - } - if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_VERIFY_NAME_NAME) == 0) { - const char *p; - char gc[1024]; - int crit, flags, ret; - struct ldb_verify_name_control *control; - - gc[0] = '\0'; - - p = &(control_strings[sizeof(LDB_CONTROL_VERIFY_NAME_NAME)]); - ret = sscanf(p, "%d:%d:%1023[^$]", &crit, &flags, gc); - if ((ret != 3) || (crit < 0) || (crit > 1)) { - ret = sscanf(p, "%d:%d", &crit, &flags); - if ((ret != 2) || (crit < 0) || (crit > 1)) { - ldb_set_errstring(ldb, - "invalid verify_name control syntax\n" - " syntax: crit(b):flags(i)[:gc(s)]\n" - " note: b = boolean" - " note: i = integer" - " note: s = string"); - talloc_free(ctrl); - return NULL; - } - } - - ctrl->oid = LDB_CONTROL_VERIFY_NAME_OID; - ctrl->critical = crit; - control = talloc(ctrl, struct ldb_verify_name_control); - if (control == NULL) { - ldb_oom(ldb); - talloc_free(ctrl); - return NULL; - } - - control->gc = talloc_strdup(control, gc); - if (control->gc == NULL) { - ldb_oom(ldb); - talloc_free(ctrl); - return NULL; - } - - control->gc_len = strlen(gc); - control->flags = flags; - ctrl->data = control; - return ctrl; - } - /* - * When no matching control has been found. - */ - return NULL; -} - -/* Parse controls from the format used on the command line and in ejs */ -struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char **control_strings) -{ - unsigned int i; - struct ldb_control **ctrl; - - if (control_strings == NULL || control_strings[0] == NULL) - return NULL; - - for (i = 0; control_strings[i]; i++); - - ctrl = talloc_array(mem_ctx, struct ldb_control *, i + 1); - - ldb_reset_err_string(ldb); - for (i = 0; control_strings[i]; i++) { - ctrl[i] = ldb_parse_control_from_string(ldb, ctrl, control_strings[i]); - if (ctrl[i] == NULL) { - if (ldb_errstring(ldb) == NULL) { - /* no controls matched, throw an error */ - ldb_asprintf_errstring(ldb, "Invalid control name: '%s'", control_strings[i]); - } - talloc_free(ctrl); - return NULL; - } - } - - ctrl[i] = NULL; - - return ctrl; -} - - diff --git a/ldb-2.0.8/common/ldb_debug.c b/ldb-2.0.8/common/ldb_debug.c deleted file mode 100644 index d5e9e7a..0000000 --- a/ldb-2.0.8/common/ldb_debug.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb debug - * - * Description: functions for printing debug messages - * - * Author: Andrew Tridgell - */ - -#include "ldb_private.h" - -/* - this allows the user to choose their own debug function -*/ -int ldb_set_debug(struct ldb_context *ldb, - void (*debug)(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap), - void *context) -{ - ldb->debug_ops.debug = debug; - ldb->debug_ops.context = context; - return 0; -} - -/* - debug function for ldb_set_debug_stderr -*/ -static void ldb_debug_stderr(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); -static void ldb_debug_stderr(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap) -{ - if (level <= LDB_DEBUG_WARNING) { - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - } -} - -static void ldb_debug_stderr_all(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); -static void ldb_debug_stderr_all(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap) -{ - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); -} - -/* - convenience function to setup debug messages on stderr - messages of level LDB_DEBUG_WARNING and higher are printed -*/ -int ldb_set_debug_stderr(struct ldb_context *ldb) -{ - return ldb_set_debug(ldb, ldb_debug_stderr, ldb); -} - -/* - log a message (va_list helper for ldb_tevent_debug) -*/ -void ldb_vdebug(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, va_list ap) -{ - if (ldb->debug_ops.debug == NULL) { - if (ldb->flags & LDB_FLG_ENABLE_TRACING) { - ldb_set_debug(ldb, ldb_debug_stderr_all, ldb); - } else { - ldb_set_debug_stderr(ldb); - } - } - ldb->debug_ops.debug(ldb->debug_ops.context, level, fmt, ap); -} - -/* - log a message -*/ -void ldb_debug(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - ldb_vdebug(ldb, level, fmt, ap); - va_end(ap); -} - -/* - add to an accumulated log message - */ -void ldb_debug_add(struct ldb_context *ldb, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - if (ldb->partial_debug == NULL) { - ldb->partial_debug = talloc_vasprintf(ldb, fmt, ap); - } else { - ldb->partial_debug = talloc_vasprintf_append(ldb->partial_debug, - fmt, ap); - } - va_end(ap); -} - -/* - send the accumulated log message, and free it - */ -void ldb_debug_end(struct ldb_context *ldb, enum ldb_debug_level level) -{ - ldb_debug(ldb, level, "%s", ldb->partial_debug); - talloc_free(ldb->partial_debug); - ldb->partial_debug = NULL; -} - -/* - log a message, and set the ldb error string to the same message -*/ -void ldb_debug_set(struct ldb_context *ldb, enum ldb_debug_level level, - const char *fmt, ...) -{ - va_list ap; - char *msg; - va_start(ap, fmt); - msg = talloc_vasprintf(ldb, fmt, ap); - va_end(ap); - if (msg != NULL) { - ldb_set_errstring(ldb, msg); - ldb_debug(ldb, level, "%s", msg); - } - talloc_free(msg); -} - diff --git a/ldb-2.0.8/common/ldb_dn.c b/ldb-2.0.8/common/ldb_dn.c deleted file mode 100644 index 83f94e3..0000000 --- a/ldb-2.0.8/common/ldb_dn.c +++ /dev/null @@ -1,2240 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb dn creation and manipulation utility functions - * - * Description: - explode a dn into it's own basic elements - * and put them in a structure (only if necessary) - * - manipulate ldb_dn structures - * - * Author: Simo Sorce - */ - -#include "ldb_private.h" -#include - -#define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed - -#define LDB_FREE(x) do { talloc_free(x); x = NULL; } while(0) - -/** - internal ldb exploded dn structures -*/ -struct ldb_dn_component { - - char *name; - struct ldb_val value; - - char *cf_name; - struct ldb_val cf_value; -}; - -struct ldb_dn_ext_component { - - const char *name; - struct ldb_val value; -}; - -struct ldb_dn { - - struct ldb_context *ldb; - - /* Special DNs are always linearized */ - bool special; - bool invalid; - - bool valid_case; - - char *linearized; - char *ext_linearized; - char *casefold; - - unsigned int comp_num; - struct ldb_dn_component *components; - - unsigned int ext_comp_num; - struct ldb_dn_ext_component *ext_components; -}; - -/* it is helpful to be able to break on this in gdb */ -static void ldb_dn_mark_invalid(struct ldb_dn *dn) -{ - dn->invalid = true; -} - -/* strdn may be NULL */ -struct ldb_dn *ldb_dn_from_ldb_val(TALLOC_CTX *mem_ctx, - struct ldb_context *ldb, - const struct ldb_val *strdn) -{ - struct ldb_dn *dn; - - if (ldb == NULL || strdn == NULL) { - return NULL; - } - if (strdn->data - && (strnlen((const char*)strdn->data, strdn->length) != strdn->length)) { - /* The RDN must not contain a character with value 0x0 */ - return NULL; - } - - dn = talloc_zero(mem_ctx, struct ldb_dn); - LDB_DN_NULL_FAILED(dn); - - dn->ldb = talloc_get_type(ldb, struct ldb_context); - if (dn->ldb == NULL) { - /* the caller probably got the arguments to - ldb_dn_new() mixed up */ - talloc_free(dn); - return NULL; - } - - if (strdn->data && strdn->length) { - const char *data = (const char *)strdn->data; - size_t length = strdn->length; - - if (data[0] == '@') { - dn->special = true; - } - dn->ext_linearized = talloc_strndup(dn, data, length); - LDB_DN_NULL_FAILED(dn->ext_linearized); - - if (data[0] == '<') { - const char *p_save, *p = dn->ext_linearized; - do { - p_save = p; - p = strstr(p, ">;"); - if (p) { - p = p + 2; - } - } while (p); - - if (p_save == dn->ext_linearized) { - dn->linearized = talloc_strdup(dn, ""); - } else { - dn->linearized = talloc_strdup(dn, p_save); - } - LDB_DN_NULL_FAILED(dn->linearized); - } else { - dn->linearized = dn->ext_linearized; - dn->ext_linearized = NULL; - } - } else { - dn->linearized = talloc_strdup(dn, ""); - LDB_DN_NULL_FAILED(dn->linearized); - } - - return dn; - -failed: - talloc_free(dn); - return NULL; -} - -/* strdn may be NULL */ -struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx, - struct ldb_context *ldb, - const char *strdn) -{ - struct ldb_val blob; - blob.data = discard_const_p(uint8_t, strdn); - blob.length = strdn ? strlen(strdn) : 0; - return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob); -} - -struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx, - struct ldb_context *ldb, - const char *new_fmt, ...) -{ - char *strdn; - va_list ap; - - if (! ldb) return NULL; - - va_start(ap, new_fmt); - strdn = talloc_vasprintf(mem_ctx, new_fmt, ap); - va_end(ap); - - if (strdn) { - struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn); - talloc_free(strdn); - return dn; - } - - return NULL; -} - -/* see RFC2253 section 2.4 */ -static int ldb_dn_escape_internal(char *dst, const char *src, int len) -{ - char c; - char *d; - int i; - d = dst; - - for (i = 0; i < len; i++){ - c = src[i]; - switch (c) { - case ' ': - if (i == 0 || i == len - 1) { - /* if at the beginning or end - * of the string then escape */ - *d++ = '\\'; - *d++ = c; - } else { - /* otherwise don't escape */ - *d++ = c; - } - break; - - case '#': - /* despite the RFC, windows escapes a # - anywhere in the string */ - case ',': - case '+': - case '"': - case '\\': - case '<': - case '>': - case '?': - /* these must be escaped using \c form */ - *d++ = '\\'; - *d++ = c; - break; - - case ';': - case '\r': - case '\n': - case '=': - case '\0': { - /* any others get \XX form */ - unsigned char v; - const char *hexbytes = "0123456789ABCDEF"; - v = (const unsigned char)c; - *d++ = '\\'; - *d++ = hexbytes[v>>4]; - *d++ = hexbytes[v&0xF]; - break; - } - default: - *d++ = c; - } - } - - /* return the length of the resulting string */ - return (d - dst); -} - -char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value) -{ - char *dst; - size_t len; - if (!value.length) - return NULL; - - /* allocate destination string, it will be at most 3 times the source */ - dst = talloc_array(mem_ctx, char, value.length * 3 + 1); - if ( ! dst) { - talloc_free(dst); - return NULL; - } - - len = ldb_dn_escape_internal(dst, (const char *)value.data, value.length); - - dst = talloc_realloc(mem_ctx, dst, char, len + 1); - if ( ! dst) { - talloc_free(dst); - return NULL; - } - dst[len] = '\0'; - return dst; -} - -/* - explode a DN string into a ldb_dn structure - based on RFC4514 except that we don't support multiple valued RDNs - - TODO: according to MS-ADTS:3.1.1.5.2 Naming Constraints - DN must be compliant with RFC2253 -*/ -static bool ldb_dn_explode(struct ldb_dn *dn) -{ - char *p, *ex_name = NULL, *ex_value = NULL, *data, *d, *dt, *t; - bool trim = true; - bool in_extended = true; - bool in_ex_name = false; - bool in_ex_value = false; - bool in_attr = false; - bool in_value = false; - bool in_quote = false; - bool is_oid = false; - bool escape = false; - unsigned int x; - size_t l = 0; - int ret; - char *parse_dn; - bool is_index; - - if (dn == NULL || dn->invalid == true) { - return false; - } - - if (dn->components != NULL) { - return true; - } - - if (dn->ext_linearized != NULL) { - parse_dn = dn->ext_linearized; - } else { - parse_dn = dn->linearized; - } - - if (parse_dn == NULL) { - return false; - } - - is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0); - - /* Empty DNs */ - if (parse_dn[0] == '\0') { - return true; - } - - /* Special DNs case */ - if (dn->special == true) { - return true; - } - - LDB_FREE(dn->ext_components); - dn->ext_comp_num = 0; - dn->comp_num = 0; - - /* in the common case we have 3 or more components */ - /* make sure all components are zeroed, other functions depend on it */ - dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3); - if (dn->components == NULL) { - return false; - } - - /* Components data space is allocated here once */ - data = talloc_array(dn->components, char, strlen(parse_dn) + 1); - if (data == NULL) { - goto failed; - } - - p = parse_dn; - t = NULL; - d = dt = data; - - while (*p) { - if (in_extended == true) { - - if (!in_ex_name && !in_ex_value) { - - if (p[0] == '<') { - p++; - ex_name = d; - in_ex_name = true; - continue; - } else { - in_extended = false; - in_attr = true; - dt = d; - - continue; - } - } - - if (in_ex_name && *p == '=') { - *d++ = '\0'; - p++; - ex_value = d; - in_ex_name = false; - in_ex_value = true; - continue; - } - - if (in_ex_value && *p == '>') { - struct ldb_dn_ext_component *ext_comp = NULL; - const struct ldb_dn_extended_syntax *ext_syntax; - struct ldb_val ex_val = { - .data = (uint8_t *)ex_value, - .length = d - ex_value - }; - - *d++ = '\0'; - p++; - in_ex_value = false; - - /* Process name and ex_value */ - - ext_comp = talloc_realloc( - dn, - dn->ext_components, - struct ldb_dn_ext_component, - dn->ext_comp_num + 1); - - if (ext_comp == NULL) { - /* ouch ! */ - goto failed; - } - - dn->ext_components = ext_comp; - - ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name); - if (ext_syntax == NULL) { - /* We don't know about this type of extended DN */ - goto failed; - } - - dn->ext_components[dn->ext_comp_num].name = ext_syntax->name; - ret = ext_syntax->read_fn(dn->ldb, dn->ext_components, - &ex_val, &dn->ext_components[dn->ext_comp_num].value); - if (ret != LDB_SUCCESS) { - ldb_dn_mark_invalid(dn); - goto failed; - } - - dn->ext_comp_num++; - - if (*p == '\0') { - /* We have reached the end (extended component only)! */ - talloc_free(data); - return true; - - } else if (*p == ';') { - p++; - continue; - } else { - ldb_dn_mark_invalid(dn); - goto failed; - } - } - - *d++ = *p++; - continue; - } - if (in_attr == true) { - if (trim == true) { - if (*p == ' ') { - p++; - continue; - } - - /* first char */ - trim = false; - - if (!isascii(*p)) { - /* attr names must be ascii only */ - ldb_dn_mark_invalid(dn); - goto failed; - } - - if (isdigit(*p)) { - is_oid = true; - } else - if ( ! isalpha(*p)) { - /* not a digit nor an alpha, - * invalid attribute name */ - ldb_dn_mark_invalid(dn); - goto failed; - } - - /* Copy this character across from parse_dn, - * now we have trimmed out spaces */ - *d++ = *p++; - continue; - } - - if (*p == ' ') { - p++; - /* valid only if we are at the end */ - trim = true; - continue; - } - - if (*p == '=') { - /* attribute terminated */ - in_attr = false; - in_value = true; - trim = true; - l = 0; - - /* Terminate this string in d - * (which is a copy of parse_dn - * with spaces trimmed) */ - *d++ = '\0'; - dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt); - if (dn->components[dn->comp_num].name == NULL) { - /* ouch */ - goto failed; - } - - dt = d; - - p++; - continue; - } - - if (!isascii(*p)) { - /* attr names must be ascii only */ - ldb_dn_mark_invalid(dn); - goto failed; - } - - if (is_oid == true && ( ! (isdigit(*p) || (*p == '.')))) { - /* not a digit nor a dot, - * invalid attribute oid */ - ldb_dn_mark_invalid(dn); - goto failed; - } else - if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) { - /* not ALPHA, DIGIT or HYPHEN */ - ldb_dn_mark_invalid(dn); - goto failed; - } - - *d++ = *p++; - continue; - } - - if (in_value == true) { - if (in_quote == true) { - if (*p == '\"') { - if (p[-1] != '\\') { - p++; - in_quote = false; - continue; - } - } - *d++ = *p++; - l++; - continue; - } - - if (trim == true) { - if (*p == ' ') { - p++; - continue; - } - - /* first char */ - trim = false; - - if (*p == '\"') { - in_quote = true; - p++; - continue; - } - } - - switch (*p) { - - /* TODO: support ber encoded values - case '#': - */ - - case ',': - if (escape == true) { - *d++ = *p++; - l++; - escape = false; - continue; - } - /* ok found value terminator */ - - if (t != NULL) { - /* trim back */ - d -= (p - t); - l -= (p - t); - } - - in_attr = true; - in_value = false; - trim = true; - - p++; - *d++ = '\0'; - - /* - * This talloc_memdup() is OK with the - * +1 because *d has been set to '\0' - * just above - */ - dn->components[dn->comp_num].value.data = \ - (uint8_t *)talloc_memdup(dn->components, dt, l + 1); - dn->components[dn->comp_num].value.length = l; - if (dn->components[dn->comp_num].value.data == NULL) { - /* ouch ! */ - goto failed; - } - talloc_set_name_const(dn->components[dn->comp_num].value.data, - (const char *)dn->components[dn->comp_num].value.data); - - dt = d; - - dn->comp_num++; - if (dn->comp_num > 2) { - dn->components = talloc_realloc(dn, - dn->components, - struct ldb_dn_component, - dn->comp_num + 1); - if (dn->components == NULL) { - /* ouch ! */ - goto failed; - } - /* make sure all components are zeroed, other functions depend on this */ - memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component)); - } - - continue; - - case '+': - case '=': - /* to main compatibility with earlier - versions of ldb indexing, we have to - accept the base64 encoded binary index - values, which contain a '+' or '=' - which should normally be escaped */ - if (is_index == true) { - if (t != NULL) { - t = NULL; - } - *d++ = *p++; - l++; - break; - } - - FALL_THROUGH; - case '\"': - case '<': - case '>': - case ';': - /* a string with not escaped specials is invalid (tested) */ - if (escape == false) { - ldb_dn_mark_invalid(dn); - goto failed; - } - escape = false; - - *d++ = *p++; - l++; - - if (t != NULL) { - t = NULL; - } - break; - - case '\\': - if (escape == false) { - escape = true; - p++; - continue; - } - escape = false; - - *d++ = *p++; - l++; - - if (t != NULL) { - t = NULL; - } - break; - - default: - if (escape == true) { - if (isxdigit(p[0]) && isxdigit(p[1])) { - if (sscanf(p, "%02x", &x) != 1) { - /* invalid escaping sequence */ - ldb_dn_mark_invalid(dn); - goto failed; - } - p += 2; - *d++ = (unsigned char)x; - } else { - *d++ = *p++; - } - - escape = false; - l++; - if (t != NULL) { - t = NULL; - } - break; - } - - if (*p == ' ') { - if (t == NULL) { - t = p; - } - } else { - if (t != NULL) { - t = NULL; - } - } - - *d++ = *p++; - l++; - - break; - } - - } - } - - if (in_attr == true || in_quote == true) { - /* invalid dn */ - ldb_dn_mark_invalid(dn); - goto failed; - } - - if (in_value == true) { - /* save last element */ - if (t != NULL) { - /* trim back */ - d -= (p - t); - l -= (p - t); - } - - *d++ = '\0'; - /* - * This talloc_memdup() is OK with the - * +1 because *d has been set to '\0' - * just above. - */ - dn->components[dn->comp_num].value.length = l; - dn->components[dn->comp_num].value.data = - (uint8_t *)talloc_memdup(dn->components, dt, l + 1); - if (dn->components[dn->comp_num].value.data == NULL) { - /* ouch */ - goto failed; - } - talloc_set_name_const(dn->components[dn->comp_num].value.data, - (const char *)dn->components[dn->comp_num].value.data); - - dn->comp_num++; - } - talloc_free(data); - return true; - -failed: - LDB_FREE(dn->components); /* "data" is implicitly free'd */ - dn->comp_num = 0; - LDB_FREE(dn->ext_components); - dn->ext_comp_num = 0; - - return false; -} - -bool ldb_dn_validate(struct ldb_dn *dn) -{ - return ldb_dn_explode(dn); -} - -const char *ldb_dn_get_linearized(struct ldb_dn *dn) -{ - unsigned int i; - size_t len; - char *d, *n; - - if ( ! dn || ( dn->invalid)) return NULL; - - if (dn->linearized) return dn->linearized; - - if ( ! dn->components) { - ldb_dn_mark_invalid(dn); - return NULL; - } - - if (dn->comp_num == 0) { - dn->linearized = talloc_strdup(dn, ""); - if ( ! dn->linearized) return NULL; - return dn->linearized; - } - - /* calculate maximum possible length of DN */ - for (len = 0, i = 0; i < dn->comp_num; i++) { - /* name len */ - len += strlen(dn->components[i].name); - /* max escaped data len */ - len += (dn->components[i].value.length * 3); - len += 2; /* '=' and ',' */ - } - dn->linearized = talloc_array(dn, char, len); - if ( ! dn->linearized) return NULL; - - d = dn->linearized; - - for (i = 0; i < dn->comp_num; i++) { - - /* copy the name */ - n = dn->components[i].name; - while (*n) *d++ = *n++; - - *d++ = '='; - - /* and the value */ - d += ldb_dn_escape_internal( d, - (char *)dn->components[i].value.data, - dn->components[i].value.length); - *d++ = ','; - } - - *(--d) = '\0'; - - /* don't waste more memory than necessary */ - dn->linearized = talloc_realloc(dn, dn->linearized, - char, (d - dn->linearized + 1)); - - return dn->linearized; -} - -static int ldb_dn_extended_component_compare(const void *p1, const void *p2) -{ - const struct ldb_dn_ext_component *ec1 = (const struct ldb_dn_ext_component *)p1; - const struct ldb_dn_ext_component *ec2 = (const struct ldb_dn_ext_component *)p2; - return strcmp(ec1->name, ec2->name); -} - -char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode) -{ - const char *linearized = ldb_dn_get_linearized(dn); - char *p = NULL; - unsigned int i; - - if (!linearized) { - return NULL; - } - - if (!ldb_dn_has_extended(dn)) { - return talloc_strdup(mem_ctx, linearized); - } - - if (!ldb_dn_validate(dn)) { - return NULL; - } - - /* sort the extended components by name. The idea is to make - * the resulting DNs consistent, plus to ensure that we put - * 'DELETED' first, so it can be very quickly recognised - */ - TYPESAFE_QSORT(dn->ext_components, dn->ext_comp_num, - ldb_dn_extended_component_compare); - - for (i = 0; i < dn->ext_comp_num; i++) { - const struct ldb_dn_extended_syntax *ext_syntax; - const char *name = dn->ext_components[i].name; - struct ldb_val ec_val = dn->ext_components[i].value; - struct ldb_val val; - int ret; - - ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name); - if (!ext_syntax) { - return NULL; - } - - if (mode == 1) { - ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx, - &ec_val, &val); - } else if (mode == 0) { - ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx, - &ec_val, &val); - } else { - ret = -1; - } - - if (ret != LDB_SUCCESS) { - return NULL; - } - - if (i == 0) { - p = talloc_asprintf(mem_ctx, "<%s=%.*s>", - name, - (int)val.length, - val.data); - } else { - p = talloc_asprintf_append_buffer(p, ";<%s=%.*s>", - name, - (int)val.length, - val.data); - } - - talloc_free(val.data); - - if (!p) { - return NULL; - } - } - - if (dn->ext_comp_num && *linearized) { - p = talloc_asprintf_append_buffer(p, ";%s", linearized); - } - - if (!p) { - return NULL; - } - - return p; -} - -/* - filter out all but an acceptable list of extended DN components - */ -void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list) -{ - unsigned int i; - for (i=0; iext_comp_num; i++) { - if (!ldb_attr_in_list(accept_list, dn->ext_components[i].name)) { - memmove(&dn->ext_components[i], - &dn->ext_components[i+1], - (dn->ext_comp_num-(i+1))*sizeof(dn->ext_components[0])); - dn->ext_comp_num--; - i--; - } - } - LDB_FREE(dn->ext_linearized); -} - - -char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) -{ - return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn)); -} - -/* - casefold a dn. We need to casefold the attribute names, and canonicalize - attribute values of case insensitive attributes. -*/ - -static bool ldb_dn_casefold_internal(struct ldb_dn *dn) -{ - unsigned int i; - int ret; - - if ( ! dn || dn->invalid) return false; - - if (dn->valid_case) return true; - - if (( ! dn->components) && ( ! ldb_dn_explode(dn))) { - return false; - } - - for (i = 0; i < dn->comp_num; i++) { - const struct ldb_schema_attribute *a; - - dn->components[i].cf_name = - ldb_attr_casefold(dn->components, - dn->components[i].name); - if (!dn->components[i].cf_name) { - goto failed; - } - - a = ldb_schema_attribute_by_name(dn->ldb, - dn->components[i].cf_name); - - ret = a->syntax->canonicalise_fn(dn->ldb, dn->components, - &(dn->components[i].value), - &(dn->components[i].cf_value)); - if (ret != 0) { - goto failed; - } - } - - dn->valid_case = true; - - return true; - -failed: - for (i = 0; i < dn->comp_num; i++) { - LDB_FREE(dn->components[i].cf_name); - LDB_FREE(dn->components[i].cf_value.data); - } - return false; -} - -const char *ldb_dn_get_casefold(struct ldb_dn *dn) -{ - unsigned int i; - size_t len; - char *d, *n; - - if (dn->casefold) return dn->casefold; - - if (dn->special) { - dn->casefold = talloc_strdup(dn, dn->linearized); - if (!dn->casefold) return NULL; - dn->valid_case = true; - return dn->casefold; - } - - if ( ! ldb_dn_casefold_internal(dn)) { - return NULL; - } - - if (dn->comp_num == 0) { - dn->casefold = talloc_strdup(dn, ""); - return dn->casefold; - } - - /* calculate maximum possible length of DN */ - for (len = 0, i = 0; i < dn->comp_num; i++) { - /* name len */ - len += strlen(dn->components[i].cf_name); - /* max escaped data len */ - len += (dn->components[i].cf_value.length * 3); - len += 2; /* '=' and ',' */ - } - dn->casefold = talloc_array(dn, char, len); - if ( ! dn->casefold) return NULL; - - d = dn->casefold; - - for (i = 0; i < dn->comp_num; i++) { - - /* copy the name */ - n = dn->components[i].cf_name; - while (*n) *d++ = *n++; - - *d++ = '='; - - /* and the value */ - d += ldb_dn_escape_internal( d, - (char *)dn->components[i].cf_value.data, - dn->components[i].cf_value.length); - *d++ = ','; - } - *(--d) = '\0'; - - /* don't waste more memory than necessary */ - dn->casefold = talloc_realloc(dn, dn->casefold, - char, strlen(dn->casefold) + 1); - - return dn->casefold; -} - -char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) -{ - return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn)); -} - -/* Determine if dn is below base, in the ldap tree. Used for - * evaluating a subtree search. - * 0 if they match, otherwise non-zero - */ - -int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn) -{ - int ret; - unsigned int n_base, n_dn; - - if ( ! base || base->invalid) return 1; - if ( ! dn || dn->invalid) return -1; - - if (( ! base->valid_case) || ( ! dn->valid_case)) { - if (base->linearized && dn->linearized && dn->special == base->special) { - /* try with a normal compare first, if we are lucky - * we will avoid exploding and casfolding */ - int dif; - dif = strlen(dn->linearized) - strlen(base->linearized); - if (dif < 0) { - return dif; - } - if (strcmp(base->linearized, - &dn->linearized[dif]) == 0) { - return 0; - } - } - - if ( ! ldb_dn_casefold_internal(base)) { - return 1; - } - - if ( ! ldb_dn_casefold_internal(dn)) { - return -1; - } - - } - - /* if base has more components, - * they don't have the same base */ - if (base->comp_num > dn->comp_num) { - return (dn->comp_num - base->comp_num); - } - - if ((dn->comp_num == 0) || (base->comp_num == 0)) { - if (dn->special && base->special) { - return strcmp(base->linearized, dn->linearized); - } else if (dn->special) { - return -1; - } else if (base->special) { - return 1; - } else { - return 0; - } - } - - n_base = base->comp_num - 1; - n_dn = dn->comp_num - 1; - - while (n_base != (unsigned int) -1) { - char *b_name = base->components[n_base].cf_name; - char *dn_name = dn->components[n_dn].cf_name; - - char *b_vdata = (char *)base->components[n_base].cf_value.data; - char *dn_vdata = (char *)dn->components[n_dn].cf_value.data; - - size_t b_vlen = base->components[n_base].cf_value.length; - size_t dn_vlen = dn->components[n_dn].cf_value.length; - - /* compare attr names */ - ret = strcmp(b_name, dn_name); - if (ret != 0) return ret; - - /* compare attr.cf_value. */ - if (b_vlen != dn_vlen) { - return b_vlen - dn_vlen; - } - ret = strncmp(b_vdata, dn_vdata, b_vlen); - if (ret != 0) return ret; - - n_base--; - n_dn--; - } - - return 0; -} - -/* compare DNs using casefolding compare functions. - - If they match, then return 0 - */ - -int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1) -{ - unsigned int i; - int ret; - - if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) { - return -1; - } - - if (( ! dn0->valid_case) || ( ! dn1->valid_case)) { - if (dn0->linearized && dn1->linearized) { - /* try with a normal compare first, if we are lucky - * we will avoid exploding and casfolding */ - if (strcmp(dn0->linearized, dn1->linearized) == 0) { - return 0; - } - } - - if ( ! ldb_dn_casefold_internal(dn0)) { - return 1; - } - - if ( ! ldb_dn_casefold_internal(dn1)) { - return -1; - } - - } - - if (dn0->comp_num != dn1->comp_num) { - return (dn1->comp_num - dn0->comp_num); - } - - if (dn0->comp_num == 0) { - if (dn0->special && dn1->special) { - return strcmp(dn0->linearized, dn1->linearized); - } else if (dn0->special) { - return 1; - } else if (dn1->special) { - return -1; - } else { - return 0; - } - } - - for (i = 0; i < dn0->comp_num; i++) { - char *dn0_name = dn0->components[i].cf_name; - char *dn1_name = dn1->components[i].cf_name; - - char *dn0_vdata = (char *)dn0->components[i].cf_value.data; - char *dn1_vdata = (char *)dn1->components[i].cf_value.data; - - size_t dn0_vlen = dn0->components[i].cf_value.length; - size_t dn1_vlen = dn1->components[i].cf_value.length; - - /* compare attr names */ - ret = strcmp(dn0_name, dn1_name); - if (ret != 0) { - return ret; - } - - /* compare attr.cf_value. */ - if (dn0_vlen != dn1_vlen) { - return dn0_vlen - dn1_vlen; - } - ret = strncmp(dn0_vdata, dn1_vdata, dn0_vlen); - if (ret != 0) { - return ret; - } - } - - return 0; -} - -static struct ldb_dn_component ldb_dn_copy_component( - TALLOC_CTX *mem_ctx, - struct ldb_dn_component *src) -{ - struct ldb_dn_component dst; - - memset(&dst, 0, sizeof(dst)); - - if (src == NULL) { - return dst; - } - - dst.value = ldb_val_dup(mem_ctx, &(src->value)); - if (dst.value.data == NULL) { - return dst; - } - - dst.name = talloc_strdup(mem_ctx, src->name); - if (dst.name == NULL) { - LDB_FREE(dst.value.data); - return dst; - } - - if (src->cf_value.data) { - dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value)); - if (dst.cf_value.data == NULL) { - LDB_FREE(dst.value.data); - LDB_FREE(dst.name); - return dst; - } - - dst.cf_name = talloc_strdup(mem_ctx, src->cf_name); - if (dst.cf_name == NULL) { - LDB_FREE(dst.cf_name); - LDB_FREE(dst.value.data); - LDB_FREE(dst.name); - return dst; - } - } else { - dst.cf_value.data = NULL; - dst.cf_name = NULL; - } - - return dst; -} - -static struct ldb_dn_ext_component ldb_dn_ext_copy_component( - TALLOC_CTX *mem_ctx, - struct ldb_dn_ext_component *src) -{ - struct ldb_dn_ext_component dst; - - memset(&dst, 0, sizeof(dst)); - - if (src == NULL) { - return dst; - } - - dst.value = ldb_val_dup(mem_ctx, &(src->value)); - if (dst.value.data == NULL) { - return dst; - } - - dst.name = talloc_strdup(mem_ctx, src->name); - if (dst.name == NULL) { - LDB_FREE(dst.value.data); - return dst; - } - - return dst; -} - -struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) -{ - struct ldb_dn *new_dn; - - if (!dn || dn->invalid) { - return NULL; - } - - new_dn = talloc_zero(mem_ctx, struct ldb_dn); - if ( !new_dn) { - return NULL; - } - - *new_dn = *dn; - - if (dn->components) { - unsigned int i; - - new_dn->components = - talloc_zero_array(new_dn, - struct ldb_dn_component, - dn->comp_num); - if ( ! new_dn->components) { - talloc_free(new_dn); - return NULL; - } - - for (i = 0; i < dn->comp_num; i++) { - new_dn->components[i] = - ldb_dn_copy_component(new_dn->components, - &dn->components[i]); - if ( ! new_dn->components[i].value.data) { - talloc_free(new_dn); - return NULL; - } - } - } - - if (dn->ext_components) { - unsigned int i; - - new_dn->ext_components = - talloc_zero_array(new_dn, - struct ldb_dn_ext_component, - dn->ext_comp_num); - if ( ! new_dn->ext_components) { - talloc_free(new_dn); - return NULL; - } - - for (i = 0; i < dn->ext_comp_num; i++) { - new_dn->ext_components[i] = - ldb_dn_ext_copy_component( - new_dn->ext_components, - &dn->ext_components[i]); - if ( ! new_dn->ext_components[i].value.data) { - talloc_free(new_dn); - return NULL; - } - } - } - - if (dn->casefold) { - new_dn->casefold = talloc_strdup(new_dn, dn->casefold); - if ( ! new_dn->casefold) { - talloc_free(new_dn); - return NULL; - } - } - - if (dn->linearized) { - new_dn->linearized = talloc_strdup(new_dn, dn->linearized); - if ( ! new_dn->linearized) { - talloc_free(new_dn); - return NULL; - } - } - - if (dn->ext_linearized) { - new_dn->ext_linearized = talloc_strdup(new_dn, - dn->ext_linearized); - if ( ! new_dn->ext_linearized) { - talloc_free(new_dn); - return NULL; - } - } - - return new_dn; -} - -/* modify the given dn by adding a base. - * - * return true if successful and false if not - * if false is returned the dn may be marked invalid - */ -bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base) -{ - const char *s; - char *t; - - if ( !base || base->invalid || !dn || dn->invalid) { - return false; - } - - if (dn == base) { - return false; /* or we will visit infinity */ - } - - if (dn->components) { - unsigned int i; - - if ( ! ldb_dn_validate(base)) { - return false; - } - - s = NULL; - if (dn->valid_case) { - if ( ! (s = ldb_dn_get_casefold(base))) { - return false; - } - } - - dn->components = talloc_realloc(dn, - dn->components, - struct ldb_dn_component, - dn->comp_num + base->comp_num); - if ( ! dn->components) { - ldb_dn_mark_invalid(dn); - return false; - } - - for (i = 0; i < base->comp_num; dn->comp_num++, i++) { - dn->components[dn->comp_num] = - ldb_dn_copy_component(dn->components, - &base->components[i]); - if (dn->components[dn->comp_num].value.data == NULL) { - ldb_dn_mark_invalid(dn); - return false; - } - } - - if (dn->casefold && s) { - if (*dn->casefold) { - t = talloc_asprintf(dn, "%s,%s", - dn->casefold, s); - } else { - t = talloc_strdup(dn, s); - } - LDB_FREE(dn->casefold); - dn->casefold = t; - } - } - - if (dn->linearized) { - - s = ldb_dn_get_linearized(base); - if ( ! s) { - return false; - } - - if (*dn->linearized) { - t = talloc_asprintf(dn, "%s,%s", - dn->linearized, s); - } else { - t = talloc_strdup(dn, s); - } - if ( ! t) { - ldb_dn_mark_invalid(dn); - return false; - } - LDB_FREE(dn->linearized); - dn->linearized = t; - } - - /* Wipe the ext_linearized DN, - * the GUID and SID are almost certainly no longer valid */ - LDB_FREE(dn->ext_linearized); - LDB_FREE(dn->ext_components); - dn->ext_comp_num = 0; - - return true; -} - -/* modify the given dn by adding a base. - * - * return true if successful and false if not - * if false is returned the dn may be marked invalid - */ -bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...) -{ - struct ldb_dn *base; - char *base_str; - va_list ap; - bool ret; - - if ( !dn || dn->invalid) { - return false; - } - - va_start(ap, base_fmt); - base_str = talloc_vasprintf(dn, base_fmt, ap); - va_end(ap); - - if (base_str == NULL) { - return false; - } - - base = ldb_dn_new(base_str, dn->ldb, base_str); - - ret = ldb_dn_add_base(dn, base); - - talloc_free(base_str); - - return ret; -} - -/* modify the given dn by adding children elements. - * - * return true if successful and false if not - * if false is returned the dn may be marked invalid - */ -bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child) -{ - const char *s; - char *t; - - if ( !child || child->invalid || !dn || dn->invalid) { - return false; - } - - if (dn->components) { - unsigned int n; - unsigned int i, j; - - if (dn->comp_num == 0) { - return false; - } - - if ( ! ldb_dn_validate(child)) { - return false; - } - - s = NULL; - if (dn->valid_case) { - if ( ! (s = ldb_dn_get_casefold(child))) { - return false; - } - } - - n = dn->comp_num + child->comp_num; - - dn->components = talloc_realloc(dn, - dn->components, - struct ldb_dn_component, - n); - if ( ! dn->components) { - ldb_dn_mark_invalid(dn); - return false; - } - - for (i = dn->comp_num - 1, j = n - 1; i != (unsigned int) -1; - i--, j--) { - dn->components[j] = dn->components[i]; - } - - for (i = 0; i < child->comp_num; i++) { - dn->components[i] = - ldb_dn_copy_component(dn->components, - &child->components[i]); - if (dn->components[i].value.data == NULL) { - ldb_dn_mark_invalid(dn); - return false; - } - } - - dn->comp_num = n; - - if (dn->casefold && s) { - t = talloc_asprintf(dn, "%s,%s", s, dn->casefold); - LDB_FREE(dn->casefold); - dn->casefold = t; - } - } - - if (dn->linearized) { - if (dn->linearized[0] == '\0') { - return false; - } - - s = ldb_dn_get_linearized(child); - if ( ! s) { - return false; - } - - t = talloc_asprintf(dn, "%s,%s", s, dn->linearized); - if ( ! t) { - ldb_dn_mark_invalid(dn); - return false; - } - LDB_FREE(dn->linearized); - dn->linearized = t; - } - - /* Wipe the ext_linearized DN, - * the GUID and SID are almost certainly no longer valid */ - LDB_FREE(dn->ext_linearized); - LDB_FREE(dn->ext_components); - dn->ext_comp_num = 0; - - return true; -} - -/* modify the given dn by adding children elements. - * - * return true if successful and false if not - * if false is returned the dn may be marked invalid - */ -bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...) -{ - struct ldb_dn *child; - char *child_str; - va_list ap; - bool ret; - - if ( !dn || dn->invalid) { - return false; - } - - va_start(ap, child_fmt); - child_str = talloc_vasprintf(dn, child_fmt, ap); - va_end(ap); - - if (child_str == NULL) { - return false; - } - - child = ldb_dn_new(child_str, dn->ldb, child_str); - - ret = ldb_dn_add_child(dn, child); - - talloc_free(child_str); - - return ret; -} - -/* modify the given dn by adding a single child element. - * - * return true if successful and false if not - * if false is returned the dn may be marked invalid - */ -bool ldb_dn_add_child_val(struct ldb_dn *dn, - const char *rdn, - struct ldb_val value) -{ - bool ret; - int ldb_ret; - struct ldb_dn *child = NULL; - - if ( !dn || dn->invalid) { - return false; - } - - child = ldb_dn_new(dn, dn->ldb, "X=Y"); - ret = ldb_dn_add_child(dn, child); - - if (ret == false) { - return false; - } - - ldb_ret = ldb_dn_set_component(dn, - 0, - rdn, - value); - if (ldb_ret != LDB_SUCCESS) { - return false; - } - - return true; -} - -bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num) -{ - unsigned int i; - - if ( ! ldb_dn_validate(dn)) { - return false; - } - - if (dn->comp_num < num) { - return false; - } - - /* free components */ - for (i = dn->comp_num - num; i < dn->comp_num; i++) { - LDB_FREE(dn->components[i].name); - LDB_FREE(dn->components[i].value.data); - LDB_FREE(dn->components[i].cf_name); - LDB_FREE(dn->components[i].cf_value.data); - } - - dn->comp_num -= num; - - if (dn->valid_case) { - for (i = 0; i < dn->comp_num; i++) { - LDB_FREE(dn->components[i].cf_name); - LDB_FREE(dn->components[i].cf_value.data); - } - dn->valid_case = false; - } - - LDB_FREE(dn->casefold); - LDB_FREE(dn->linearized); - - /* Wipe the ext_linearized DN, - * the GUID and SID are almost certainly no longer valid */ - LDB_FREE(dn->ext_linearized); - LDB_FREE(dn->ext_components); - dn->ext_comp_num = 0; - - return true; -} - -bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num) -{ - unsigned int i, j; - - if ( ! ldb_dn_validate(dn)) { - return false; - } - - if (dn->comp_num < num) { - return false; - } - - for (i = 0, j = num; j < dn->comp_num; i++, j++) { - if (i < num) { - LDB_FREE(dn->components[i].name); - LDB_FREE(dn->components[i].value.data); - LDB_FREE(dn->components[i].cf_name); - LDB_FREE(dn->components[i].cf_value.data); - } - dn->components[i] = dn->components[j]; - } - - dn->comp_num -= num; - - if (dn->valid_case) { - for (i = 0; i < dn->comp_num; i++) { - LDB_FREE(dn->components[i].cf_name); - LDB_FREE(dn->components[i].cf_value.data); - } - dn->valid_case = false; - } - - LDB_FREE(dn->casefold); - LDB_FREE(dn->linearized); - - /* Wipe the ext_linearized DN, - * the GUID and SID are almost certainly no longer valid */ - LDB_FREE(dn->ext_linearized); - LDB_FREE(dn->ext_components); - dn->ext_comp_num = 0; - - return true; -} - - -/* replace the components of a DN with those from another DN, without - * touching the extended components - * - * return true if successful and false if not - * if false is returned the dn may be marked invalid - */ -bool ldb_dn_replace_components(struct ldb_dn *dn, struct ldb_dn *new_dn) -{ - unsigned int i; - - if ( ! ldb_dn_validate(dn) || ! ldb_dn_validate(new_dn)) { - return false; - } - - /* free components */ - for (i = 0; i < dn->comp_num; i++) { - LDB_FREE(dn->components[i].name); - LDB_FREE(dn->components[i].value.data); - LDB_FREE(dn->components[i].cf_name); - LDB_FREE(dn->components[i].cf_value.data); - } - - dn->components = talloc_realloc(dn, - dn->components, - struct ldb_dn_component, - new_dn->comp_num); - if (dn->components == NULL) { - ldb_dn_mark_invalid(dn); - return false; - } - - dn->comp_num = new_dn->comp_num; - dn->valid_case = new_dn->valid_case; - - for (i = 0; i < dn->comp_num; i++) { - dn->components[i] = ldb_dn_copy_component(dn->components, &new_dn->components[i]); - if (dn->components[i].name == NULL) { - ldb_dn_mark_invalid(dn); - return false; - } - } - if (new_dn->linearized == NULL) { - dn->linearized = NULL; - } else { - dn->linearized = talloc_strdup(dn, new_dn->linearized); - if (dn->linearized == NULL) { - ldb_dn_mark_invalid(dn); - return false; - } - } - - return true; -} - - -struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) -{ - struct ldb_dn *new_dn; - - new_dn = ldb_dn_copy(mem_ctx, dn); - if ( !new_dn ) { - return NULL; - } - - if ( ! ldb_dn_remove_child_components(new_dn, 1)) { - talloc_free(new_dn); - return NULL; - } - - return new_dn; -} - -/* Create a 'canonical name' string from a DN: - - ie dc=samba,dc=org -> samba.org/ - uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator - - There are two formats, - the EX format has the last '/' replaced with a newline (\n). - -*/ -static char *ldb_dn_canonical(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int ex_format) { - unsigned int i; - TALLOC_CTX *tmpctx; - char *cracked = NULL; - const char *format = (ex_format ? "\n" : "/" ); - - if ( ! ldb_dn_validate(dn)) { - return NULL; - } - - tmpctx = talloc_new(mem_ctx); - - /* Walk backwards down the DN, grabbing 'dc' components at first */ - for (i = dn->comp_num - 1; i != (unsigned int) -1; i--) { - if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) { - break; - } - if (cracked) { - cracked = talloc_asprintf(tmpctx, "%s.%s", - ldb_dn_escape_value(tmpctx, - dn->components[i].value), - cracked); - } else { - cracked = ldb_dn_escape_value(tmpctx, - dn->components[i].value); - } - if (!cracked) { - goto done; - } - } - - /* Only domain components? Finish here */ - if (i == (unsigned int) -1) { - cracked = talloc_strdup_append_buffer(cracked, format); - talloc_steal(mem_ctx, cracked); - goto done; - } - - /* Now walk backwards appending remaining components */ - for (; i > 0; i--) { - cracked = talloc_asprintf_append_buffer(cracked, "/%s", - ldb_dn_escape_value(tmpctx, - dn->components[i].value)); - if (!cracked) { - goto done; - } - } - - /* Last one, possibly a newline for the 'ex' format */ - cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format, - ldb_dn_escape_value(tmpctx, - dn->components[i].value)); - - talloc_steal(mem_ctx, cracked); -done: - talloc_free(tmpctx); - return cracked; -} - -/* Wrapper functions for the above, for the two different string formats */ -char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) { - return ldb_dn_canonical(mem_ctx, dn, 0); - -} - -char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) { - return ldb_dn_canonical(mem_ctx, dn, 1); -} - -int ldb_dn_get_comp_num(struct ldb_dn *dn) -{ - if ( ! ldb_dn_validate(dn)) { - return -1; - } - return dn->comp_num; -} - -int ldb_dn_get_extended_comp_num(struct ldb_dn *dn) -{ - if ( ! ldb_dn_validate(dn)) { - return -1; - } - return dn->ext_comp_num; -} - -const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num) -{ - if ( ! ldb_dn_validate(dn)) { - return NULL; - } - if (num >= dn->comp_num) return NULL; - return dn->components[num].name; -} - -const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, - unsigned int num) -{ - if ( ! ldb_dn_validate(dn)) { - return NULL; - } - if (num >= dn->comp_num) return NULL; - return &dn->components[num].value; -} - -const char *ldb_dn_get_rdn_name(struct ldb_dn *dn) -{ - if ( ! ldb_dn_validate(dn)) { - return NULL; - } - if (dn->comp_num == 0) return NULL; - return dn->components[0].name; -} - -const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn) -{ - if ( ! ldb_dn_validate(dn)) { - return NULL; - } - if (dn->comp_num == 0) return NULL; - return &dn->components[0].value; -} - -int ldb_dn_set_component(struct ldb_dn *dn, int num, - const char *name, const struct ldb_val val) -{ - char *n; - struct ldb_val v; - - if ( ! ldb_dn_validate(dn)) { - return LDB_ERR_OTHER; - } - - if (num < 0) { - return LDB_ERR_OTHER; - } - - if ((unsigned)num >= dn->comp_num) { - return LDB_ERR_OTHER; - } - - if (val.length > val.length + 1) { - return LDB_ERR_OTHER; - } - - n = talloc_strdup(dn, name); - if ( ! n) { - return LDB_ERR_OTHER; - } - - v.length = val.length; - - /* - * This is like talloc_memdup(dn, v.data, v.length + 1), but - * avoids the over-read - */ - v.data = (uint8_t *)talloc_size(dn, v.length+1); - if ( ! v.data) { - talloc_free(n); - return LDB_ERR_OTHER; - } - memcpy(v.data, val.data, val.length); - - /* - * Enforce NUL termination outside the stated length, as is - * traditional in LDB - */ - v.data[v.length] = '\0'; - - talloc_free(dn->components[num].name); - talloc_free(dn->components[num].value.data); - dn->components[num].name = n; - dn->components[num].value = v; - - if (dn->valid_case) { - unsigned int i; - for (i = 0; i < dn->comp_num; i++) { - LDB_FREE(dn->components[i].cf_name); - LDB_FREE(dn->components[i].cf_value.data); - } - dn->valid_case = false; - } - LDB_FREE(dn->casefold); - LDB_FREE(dn->linearized); - - /* Wipe the ext_linearized DN, - * the GUID and SID are almost certainly no longer valid */ - LDB_FREE(dn->ext_linearized); - LDB_FREE(dn->ext_components); - dn->ext_comp_num = 0; - - return LDB_SUCCESS; -} - -const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, - const char *name) -{ - unsigned int i; - if ( ! ldb_dn_validate(dn)) { - return NULL; - } - for (i=0; i < dn->ext_comp_num; i++) { - if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) { - return &dn->ext_components[i].value; - } - } - return NULL; -} - -int ldb_dn_set_extended_component(struct ldb_dn *dn, - const char *name, const struct ldb_val *val) -{ - struct ldb_dn_ext_component *p; - unsigned int i; - struct ldb_val v2; - const struct ldb_dn_extended_syntax *ext_syntax; - - if ( ! ldb_dn_validate(dn)) { - return LDB_ERR_OTHER; - } - - ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name); - if (ext_syntax == NULL) { - /* We don't know how to handle this type of thing */ - return LDB_ERR_INVALID_DN_SYNTAX; - } - - for (i=0; i < dn->ext_comp_num; i++) { - if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) { - if (val) { - dn->ext_components[i].value = - ldb_val_dup(dn->ext_components, val); - - dn->ext_components[i].name = ext_syntax->name; - if (!dn->ext_components[i].value.data) { - ldb_dn_mark_invalid(dn); - return LDB_ERR_OPERATIONS_ERROR; - } - } else { - if (i != (dn->ext_comp_num - 1)) { - memmove(&dn->ext_components[i], - &dn->ext_components[i+1], - ((dn->ext_comp_num-1) - i) * - sizeof(*dn->ext_components)); - } - dn->ext_comp_num--; - - dn->ext_components = talloc_realloc(dn, - dn->ext_components, - struct ldb_dn_ext_component, - dn->ext_comp_num); - if (!dn->ext_components) { - ldb_dn_mark_invalid(dn); - return LDB_ERR_OPERATIONS_ERROR; - } - } - LDB_FREE(dn->ext_linearized); - - return LDB_SUCCESS; - } - } - - if (val == NULL) { - /* removing a value that doesn't exist is not an error */ - return LDB_SUCCESS; - } - - v2 = *val; - - p = dn->ext_components - = talloc_realloc(dn, - dn->ext_components, - struct ldb_dn_ext_component, - dn->ext_comp_num + 1); - if (!dn->ext_components) { - ldb_dn_mark_invalid(dn); - return LDB_ERR_OPERATIONS_ERROR; - } - - p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, &v2); - p[dn->ext_comp_num].name = talloc_strdup(p, name); - - if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) { - ldb_dn_mark_invalid(dn); - return LDB_ERR_OPERATIONS_ERROR; - } - dn->ext_components = p; - dn->ext_comp_num++; - - LDB_FREE(dn->ext_linearized); - - return LDB_SUCCESS; -} - -void ldb_dn_remove_extended_components(struct ldb_dn *dn) -{ - LDB_FREE(dn->ext_linearized); - LDB_FREE(dn->ext_components); - dn->ext_comp_num = 0; -} - -bool ldb_dn_is_valid(struct ldb_dn *dn) -{ - if ( ! dn) return false; - return ! dn->invalid; -} - -bool ldb_dn_is_special(struct ldb_dn *dn) -{ - if ( ! dn || dn->invalid) return false; - return dn->special; -} - -bool ldb_dn_has_extended(struct ldb_dn *dn) -{ - if ( ! dn || dn->invalid) return false; - if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true; - return dn->ext_comp_num != 0; -} - -bool ldb_dn_check_special(struct ldb_dn *dn, const char *check) -{ - if ( ! dn || dn->invalid) return false; - return ! strcmp(dn->linearized, check); -} - -bool ldb_dn_is_null(struct ldb_dn *dn) -{ - if ( ! dn || dn->invalid) return false; - if (ldb_dn_has_extended(dn)) return false; - if (dn->linearized && (dn->linearized[0] == '\0')) return true; - return false; -} - -/* - this updates dn->components, taking the components from ref_dn. - This is used by code that wants to update the DN path of a DN - while not impacting on the extended DN components - */ -int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn) -{ - dn->components = talloc_realloc(dn, dn->components, - struct ldb_dn_component, ref_dn->comp_num); - if (!dn->components) { - return LDB_ERR_OPERATIONS_ERROR; - } - memcpy(dn->components, ref_dn->components, - sizeof(struct ldb_dn_component)*ref_dn->comp_num); - dn->comp_num = ref_dn->comp_num; - - LDB_FREE(dn->casefold); - LDB_FREE(dn->linearized); - LDB_FREE(dn->ext_linearized); - - return LDB_SUCCESS; -} - -/* - minimise a DN. The caller must pass in a validated DN. - - If the DN has an extended component then only the first extended - component is kept, the DN string is stripped. - - The existing dn is modified - */ -bool ldb_dn_minimise(struct ldb_dn *dn) -{ - unsigned int i; - - if (!ldb_dn_validate(dn)) { - return false; - } - if (dn->ext_comp_num == 0) { - return true; - } - - /* free components */ - for (i = 0; i < dn->comp_num; i++) { - LDB_FREE(dn->components[i].name); - LDB_FREE(dn->components[i].value.data); - LDB_FREE(dn->components[i].cf_name); - LDB_FREE(dn->components[i].cf_value.data); - } - dn->comp_num = 0; - dn->valid_case = false; - - LDB_FREE(dn->casefold); - LDB_FREE(dn->linearized); - - /* note that we don't free dn->components as this there are - * several places in ldb_dn.c that rely on it being non-NULL - * for an exploded DN - */ - - for (i = 1; i < dn->ext_comp_num; i++) { - LDB_FREE(dn->ext_components[i].value.data); - } - dn->ext_comp_num = 1; - - dn->ext_components = talloc_realloc(dn, dn->ext_components, struct ldb_dn_ext_component, 1); - if (dn->ext_components == NULL) { - ldb_dn_mark_invalid(dn); - return false; - } - - LDB_FREE(dn->ext_linearized); - - return true; -} - -struct ldb_context *ldb_dn_get_ldb_context(struct ldb_dn *dn) -{ - return dn->ldb; -} diff --git a/ldb-2.0.8/common/ldb_ldif.c b/ldb-2.0.8/common/ldb_ldif.c deleted file mode 100644 index 6f7589f..0000000 --- a/ldb-2.0.8/common/ldb_ldif.c +++ /dev/null @@ -1,1108 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldif routines - * - * Description: ldif pack/unpack routines - * - * Author: Andrew Tridgell - */ - -/* - see RFC2849 for the LDIF format definition -*/ - -#include "ldb_private.h" -#include "system/locale.h" - -/* - -*/ -static int ldb_read_data_file(TALLOC_CTX *mem_ctx, struct ldb_val *value) -{ - struct stat statbuf; - char *buf; - int count, size, bytes; - int ret; - int f; - const char *fname = (const char *)value->data; - - if (strncmp(fname, "file://", 7) != 0) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - fname += 7; - - f = open(fname, O_RDONLY); - if (f == -1) { - return -1; - } - - if (fstat(f, &statbuf) != 0) { - ret = -1; - goto done; - } - - if (statbuf.st_size == 0) { - ret = -1; - goto done; - } - - value->data = (uint8_t *)talloc_size(mem_ctx, statbuf.st_size + 1); - if (value->data == NULL) { - ret = -1; - goto done; - } - value->data[statbuf.st_size] = 0; - - count = 0; - size = statbuf.st_size; - buf = (char *)value->data; - while (count < statbuf.st_size) { - bytes = read(f, buf, size); - if (bytes == -1) { - talloc_free(value->data); - ret = -1; - goto done; - } - count += bytes; - buf += bytes; - size -= bytes; - } - - value->length = statbuf.st_size; - ret = statbuf.st_size; - -done: - close(f); - return ret; -} - -/* - this base64 decoder was taken from jitterbug (written by tridge). - we might need to replace it with a new version -*/ -int ldb_base64_decode(char *s) -{ - const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - int bit_offset=0, byte_offset, idx, i, n; - uint8_t *d = (uint8_t *)s; - char *p=NULL; - - n=i=0; - - while (*s && (p=strchr(b64,*s))) { - idx = (int)(p - b64); - byte_offset = (i*6)/8; - bit_offset = (i*6)%8; - d[byte_offset] &= ~((1<<(8-bit_offset))-1); - if (bit_offset < 3) { - d[byte_offset] |= (idx << (2-bit_offset)); - n = byte_offset+1; - } else { - d[byte_offset] |= (idx >> (bit_offset-2)); - d[byte_offset+1] = 0; - d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF; - n = byte_offset+2; - } - s++; i++; - } - if (bit_offset >= 3) { - n--; - } - - if (*s && !p) { - /* the only termination allowed */ - if (*s != '=') { - return -1; - } - } - - /* null terminate */ - d[n] = 0; - return n; -} - - -/* - encode as base64 - caller frees -*/ -char *ldb_base64_encode(TALLOC_CTX *mem_ctx, const char *buf, int len) -{ - const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - int bit_offset, byte_offset, idx, i; - const uint8_t *d = (const uint8_t *)buf; - int bytes = (len*8 + 5)/6, pad_bytes = (bytes % 4) ? 4 - (bytes % 4) : 0; - char *out; - - out = talloc_array(mem_ctx, char, bytes+pad_bytes+1); - if (!out) return NULL; - - for (i=0;i> (2-bit_offset)) & 0x3F; - } else { - idx = (d[byte_offset] << (bit_offset-2)) & 0x3F; - if (byte_offset+1 < len) { - idx |= (d[byte_offset+1] >> (8-(bit_offset-2))); - } - } - out[i] = b64[idx]; - } - - for (;idata; - - if (val->length == 0) { - return 0; - } - - if (p[0] == ' ' || p[0] == ':') { - return 1; - } - - for (i=0; ilength; i++) { - if (!isprint(p[i]) || p[i] == '\n') { - return 1; - } - } - return 0; -} - -/* this macro is used to handle the return checking on fprintf_fn() */ -#define CHECK_RET do { if (ret < 0) return ret; total += ret; } while (0) - -/* - write a line folded string onto a file -*/ -static int fold_string(int (*fprintf_fn)(void *, const char *, ...), void *private_data, - const char *buf, size_t length, int start_pos) -{ - size_t i; - size_t total = 0; - int ret; - - for (i=0;imsg; - p = ldb_dn_get_extended_linearized(mem_ctx, msg->dn, 1); - ret = fprintf_fn(private_data, "dn: %s\n", p); - talloc_free(p); - CHECK_RET; - - if (ldif->changetype != LDB_CHANGETYPE_NONE) { - for (i=0;ldb_changetypes[i].name;i++) { - if (ldb_changetypes[i].changetype == ldif->changetype) { - break; - } - } - if (!ldb_changetypes[i].name) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Invalid ldif changetype %d", - ldif->changetype); - talloc_free(mem_ctx); - return -1; - } - ret = fprintf_fn(private_data, "changetype: %s\n", ldb_changetypes[i].name); - CHECK_RET; - } - - for (i=0;inum_elements;i++) { - const struct ldb_schema_attribute *a; - size_t namelen; - - if (msg->elements[i].name == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: Invalid element name (NULL) at position %d", i); - talloc_free(mem_ctx); - return -1; - } - - namelen = strlen(msg->elements[i].name); - a = ldb_schema_attribute_by_name(ldb, msg->elements[i].name); - - if (ldif->changetype == LDB_CHANGETYPE_MODIFY) { - switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) { - case LDB_FLAG_MOD_ADD: - fprintf_fn(private_data, "add: %s\n", - msg->elements[i].name); - break; - case LDB_FLAG_MOD_DELETE: - fprintf_fn(private_data, "delete: %s\n", - msg->elements[i].name); - break; - case LDB_FLAG_MOD_REPLACE: - fprintf_fn(private_data, "replace: %s\n", - msg->elements[i].name); - break; - } - } - - if (in_trace && secret_attributes && ldb_attr_in_list(secret_attributes, msg->elements[i].name)) { - /* Deliberatly skip printing this password */ - ret = fprintf_fn(private_data, "# %s::: REDACTED SECRET ATTRIBUTE\n", - msg->elements[i].name); - CHECK_RET; - continue; - } - for (j=0;jelements[i].num_values;j++) { - struct ldb_val v; - bool use_b64_encode = false; - bool copy_raw_bytes = false; - - ret = a->syntax->ldif_write_fn(ldb, mem_ctx, &msg->elements[i].values[j], &v); - if (ret != LDB_SUCCESS) { - v = msg->elements[i].values[j]; - } - - if (ldb->flags & LDB_FLG_SHOW_BINARY) { - use_b64_encode = false; - copy_raw_bytes = true; - } else if (a->flags & LDB_ATTR_FLAG_FORCE_BASE64_LDIF) { - use_b64_encode = true; - } else if (msg->elements[i].flags & - LDB_FLAG_FORCE_NO_BASE64_LDIF) { - use_b64_encode = false; - copy_raw_bytes = true; - } else { - use_b64_encode = ldb_should_b64_encode(ldb, &v); - } - - if (ret != LDB_SUCCESS || use_b64_encode) { - ret = fprintf_fn(private_data, "%s:: ", - msg->elements[i].name); - CHECK_RET; - ret = base64_encode_f(ldb, fprintf_fn, private_data, - (char *)v.data, v.length, - namelen + 3); - CHECK_RET; - ret = fprintf_fn(private_data, "\n"); - CHECK_RET; - } else { - ret = fprintf_fn(private_data, "%s: ", msg->elements[i].name); - CHECK_RET; - if (copy_raw_bytes) { - ret = fprintf_fn(private_data, "%*.*s", - v.length, v.length, (char *)v.data); - } else { - ret = fold_string(fprintf_fn, private_data, - (char *)v.data, v.length, - namelen + 2); - } - CHECK_RET; - ret = fprintf_fn(private_data, "\n"); - CHECK_RET; - } - if (v.data != msg->elements[i].values[j].data) { - talloc_free(v.data); - } - } - if (ldif->changetype == LDB_CHANGETYPE_MODIFY) { - fprintf_fn(private_data, "-\n"); - } - } - ret = fprintf_fn(private_data,"\n"); - CHECK_RET; - - talloc_free(mem_ctx); - - return total; -} - -#undef CHECK_RET - - -/* - write to ldif, using a caller supplied write method -*/ -int ldb_ldif_write(struct ldb_context *ldb, - int (*fprintf_fn)(void *, const char *, ...), - void *private_data, - const struct ldb_ldif *ldif) -{ - return ldb_ldif_write_trace(ldb, fprintf_fn, private_data, ldif, false); -} - - -/* - pull a ldif chunk, which is defined as a piece of data ending in \n\n or EOF - this routine removes any RFC2849 continuations and comments - - caller frees -*/ -static char *next_chunk(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - int (*fgetc_fn)(void *), void *private_data) -{ - size_t alloc_size=0, chunk_size = 0; - char *chunk = NULL; - int c; - int in_comment = 0; - - while ((c = fgetc_fn(private_data)) != EOF) { - if (chunk_size+1 >= alloc_size) { - char *c2; - alloc_size += 1024; - c2 = talloc_realloc(mem_ctx, chunk, char, alloc_size); - if (!c2) { - talloc_free(chunk); - errno = ENOMEM; - return NULL; - } - chunk = c2; - } - - if (in_comment) { - if (c == '\n') { - in_comment = 0; - } - continue; - } - - /* handle continuation lines - see RFC2849 */ - if (c == ' ' && chunk_size > 1 && chunk[chunk_size-1] == '\n') { - chunk_size--; - continue; - } - - /* chunks are terminated by a double line-feed */ - if (c == '\n' && chunk_size > 0 && chunk[chunk_size-1] == '\n') { - chunk[chunk_size-1] = 0; - return chunk; - } - - if (c == '#' && (chunk_size == 0 || chunk[chunk_size-1] == '\n')) { - in_comment = 1; - continue; - } - - /* ignore leading blank lines */ - if (chunk_size == 0 && c == '\n') { - continue; - } - - chunk[chunk_size++] = c; - } - - if (chunk) { - chunk[chunk_size] = 0; - } - - return chunk; -} - - -/* simple ldif attribute parser */ -static int next_attr(TALLOC_CTX *mem_ctx, char **s, const char **attr, struct ldb_val *value) -{ - char *p; - int base64_encoded = 0; - int binary_file = 0; - - if (strncmp(*s, "-\n", 2) == 0) { - value->length = 0; - *attr = "-"; - *s += 2; - return 0; - } - - p = strchr(*s, ':'); - if (!p) { - return -1; - } - - *p++ = 0; - - if (*p == ':') { - base64_encoded = 1; - p++; - } - - if (*p == '<') { - binary_file = 1; - p++; - } - - *attr = *s; - - while (*p == ' ' || *p == '\t') { - p++; - } - - value->data = (uint8_t *)p; - - p = strchr(p, '\n'); - - if (!p) { - value->length = strlen((char *)value->data); - *s = ((char *)value->data) + value->length; - } else { - value->length = p - (char *)value->data; - *s = p+1; - *p = 0; - } - - if (base64_encoded) { - int len = ldb_base64_decode((char *)value->data); - if (len == -1) { - /* it wasn't valid base64 data */ - return -1; - } - value->length = len; - } - - if (binary_file) { - int len = ldb_read_data_file(mem_ctx, value); - if (len == -1) { - /* an error occurred while trying to retrieve the file */ - return -1; - } - } - - return 0; -} - - -/* - free a message from a ldif_read -*/ -void ldb_ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *ldif) -{ - talloc_free(ldif); -} - -int ldb_ldif_parse_modrdn(struct ldb_context *ldb, - const struct ldb_ldif *ldif, - TALLOC_CTX *mem_ctx, - struct ldb_dn **_olddn, - struct ldb_dn **_newrdn, - bool *_deleteoldrdn, - struct ldb_dn **_newsuperior, - struct ldb_dn **_newdn) -{ - struct ldb_message *msg = ldif->msg; - struct ldb_val *newrdn_val = NULL; - struct ldb_val *deleteoldrdn_val = NULL; - struct ldb_val *newsuperior_val = NULL; - struct ldb_dn *olddn = NULL; - struct ldb_dn *newrdn = NULL; - bool deleteoldrdn = true; - struct ldb_dn *newsuperior = NULL; - struct ldb_dn *newdn = NULL; - struct ldb_val tmp_false; - struct ldb_val tmp_true; - bool ok; - TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); - - if (tmp_ctx == NULL) { - ldb_debug(ldb, LDB_DEBUG_FATAL, - "Error: talloc_new() failed"); - goto err_op; - } - - if (ldif->changetype != LDB_CHANGETYPE_MODRDN) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: invalid changetype '%d'", - ldif->changetype); - goto err_other; - } - - if (msg->num_elements < 2) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: num_elements[%u] < 2", - msg->num_elements); - goto err_other; - } - - if (msg->num_elements > 3) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: num_elements[%u] > 3", - msg->num_elements); - goto err_other; - } - -#define CHECK_ELEMENT(i, _name, v, needed) do { \ - v = NULL; \ - if (msg->num_elements < (i + 1)) { \ - if (needed) { \ - ldb_debug(ldb, LDB_DEBUG_ERROR, \ - "Error: num_elements[%u] < (%u + 1)", \ - msg->num_elements, i); \ - goto err_other; \ - } \ - } else if (ldb_attr_cmp(msg->elements[i].name, _name) != 0) { \ - ldb_debug(ldb, LDB_DEBUG_ERROR, \ - "Error: elements[%u].name[%s] != [%s]", \ - i, msg->elements[i].name, _name); \ - goto err_other; \ - } else if (msg->elements[i].flags != 0) { \ - ldb_debug(ldb, LDB_DEBUG_ERROR, \ - "Error: elements[%u].flags[0x%X} != [0x0]", \ - i, msg->elements[i].flags); \ - goto err_other; \ - } else if (msg->elements[i].num_values != 1) { \ - ldb_debug(ldb, LDB_DEBUG_ERROR, \ - "Error: elements[%u].num_values[%u] != 1", \ - i, msg->elements[i].num_values); \ - goto err_other; \ - } else { \ - v = &msg->elements[i].values[0]; \ - } \ -} while (0) - - CHECK_ELEMENT(0, "newrdn", newrdn_val, true); - CHECK_ELEMENT(1, "deleteoldrdn", deleteoldrdn_val, true); - CHECK_ELEMENT(2, "newsuperior", newsuperior_val, false); - -#undef CHECK_ELEMENT - - olddn = ldb_dn_copy(tmp_ctx, msg->dn); - if (olddn == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: failed to copy olddn '%s'", - ldb_dn_get_linearized(msg->dn)); - goto err_op; - } - - newrdn = ldb_dn_from_ldb_val(tmp_ctx, ldb, newrdn_val); - if (!ldb_dn_validate(newrdn)) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: Unable to parse dn '%s'", - (char *)newrdn_val->data); - goto err_dn; - } - - tmp_false.length = 1; - tmp_false.data = discard_const_p(uint8_t, "0"); - tmp_true.length = 1; - tmp_true.data = discard_const_p(uint8_t, "1"); - if (ldb_val_equal_exact(deleteoldrdn_val, &tmp_false) == 1) { - deleteoldrdn = false; - } else if (ldb_val_equal_exact(deleteoldrdn_val, &tmp_true) == 1) { - deleteoldrdn = true; - } else { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: deleteoldrdn value invalid '%s' not '0'/'1'", - (char *)deleteoldrdn_val->data); - goto err_attr; - } - - if (newsuperior_val) { - newsuperior = ldb_dn_from_ldb_val(tmp_ctx, ldb, newsuperior_val); - if (!ldb_dn_validate(newsuperior)) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: Unable to parse dn '%s'", - (char *)newsuperior_val->data); - goto err_dn; - } - } else { - newsuperior = ldb_dn_get_parent(tmp_ctx, msg->dn); - if (newsuperior == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: Unable to get parent dn '%s'", - ldb_dn_get_linearized(msg->dn)); - goto err_dn; - } - } - - newdn = ldb_dn_copy(tmp_ctx, newrdn); - if (newdn == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: failed to copy newrdn '%s'", - ldb_dn_get_linearized(newrdn)); - goto err_op; - } - - ok = ldb_dn_add_base(newdn, newsuperior); - if (!ok) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: failed to base '%s' to newdn '%s'", - ldb_dn_get_linearized(newsuperior), - ldb_dn_get_linearized(newdn)); - goto err_op; - } - - if (_olddn) { - *_olddn = talloc_move(mem_ctx, &olddn); - } - if (_newrdn) { - *_newrdn = talloc_move(mem_ctx, &newrdn); - } - if (_deleteoldrdn) { - *_deleteoldrdn = deleteoldrdn; - } - if (_newsuperior != NULL && _newrdn != NULL) { - if (newsuperior_val) { - *_newrdn = talloc_move(mem_ctx, &newrdn); - } else { - *_newrdn = NULL; - } - } - if (_newdn) { - *_newdn = talloc_move(mem_ctx, &newdn); - } - - talloc_free(tmp_ctx); - return LDB_SUCCESS; -err_other: - talloc_free(tmp_ctx); - return LDB_ERR_OTHER; -err_op: - talloc_free(tmp_ctx); - return LDB_ERR_OPERATIONS_ERROR; -err_attr: - talloc_free(tmp_ctx); - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; -err_dn: - talloc_free(tmp_ctx); - return LDB_ERR_INVALID_DN_SYNTAX; -} - -/* - read from a LDIF source, creating a ldb_message -*/ -struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, - int (*fgetc_fn)(void *), void *private_data) -{ - struct ldb_ldif *ldif; - struct ldb_message *msg; - const char *attr=NULL; - char *chunk=NULL, *s; - struct ldb_val value; - unsigned flags = 0; - value.data = NULL; - - ldif = talloc(ldb, struct ldb_ldif); - if (!ldif) return NULL; - - ldif->msg = ldb_msg_new(ldif); - if (ldif->msg == NULL) { - talloc_free(ldif); - return NULL; - } - - ldif->changetype = LDB_CHANGETYPE_NONE; - msg = ldif->msg; - - chunk = next_chunk(ldb, ldif, fgetc_fn, private_data); - if (!chunk) { - goto failed; - } - - s = chunk; - - if (next_attr(ldif, &s, &attr, &value) != 0) { - goto failed; - } - - /* first line must be a dn */ - if (ldb_attr_cmp(attr, "dn") != 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: First line of ldif must be a dn not '%s'", - attr); - goto failed; - } - - msg->dn = ldb_dn_from_ldb_val(msg, ldb, &value); - - if ( ! ldb_dn_validate(msg->dn)) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'", - (char *)value.data); - goto failed; - } - - while (next_attr(ldif, &s, &attr, &value) == 0) { - const struct ldb_schema_attribute *a; - struct ldb_message_element *el; - int ret, empty = 0; - - if (ldb_attr_cmp(attr, "changetype") == 0) { - int i; - for (i=0;ldb_changetypes[i].name;i++) { - if (ldb_attr_cmp((char *)value.data, ldb_changetypes[i].name) == 0) { - ldif->changetype = ldb_changetypes[i].changetype; - break; - } - } - if (!ldb_changetypes[i].name) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: Bad ldif changetype '%s'",(char *)value.data); - } - flags = 0; - continue; - } - - if (ldb_attr_cmp(attr, "add") == 0) { - flags = LDB_FLAG_MOD_ADD; - empty = 1; - } - if (ldb_attr_cmp(attr, "delete") == 0) { - flags = LDB_FLAG_MOD_DELETE; - empty = 1; - } - if (ldb_attr_cmp(attr, "replace") == 0) { - flags = LDB_FLAG_MOD_REPLACE; - empty = 1; - } - if (ldb_attr_cmp(attr, "-") == 0) { - flags = 0; - continue; - } - - if (empty) { - if (ldb_msg_add_empty(msg, (char *)value.data, flags, NULL) != 0) { - goto failed; - } - continue; - } - - el = &msg->elements[msg->num_elements-1]; - - a = ldb_schema_attribute_by_name(ldb, attr); - - if (msg->num_elements > 0 && ldb_attr_cmp(attr, el->name) == 0 && - flags == el->flags) { - /* its a continuation */ - el->values = - talloc_realloc(msg->elements, el->values, - struct ldb_val, el->num_values+1); - if (!el->values) { - goto failed; - } - ret = a->syntax->ldif_read_fn(ldb, el->values, &value, &el->values[el->num_values]); - if (ret != 0) { - goto failed; - } - if (value.length == 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: Attribute value cannot be empty for attribute '%s'", el->name); - goto failed; - } - if (value.data != el->values[el->num_values].data) { - talloc_steal(el->values, el->values[el->num_values].data); - } - el->num_values++; - } else { - /* its a new attribute */ - msg->elements = talloc_realloc(msg, msg->elements, - struct ldb_message_element, - msg->num_elements+1); - if (!msg->elements) { - goto failed; - } - el = &msg->elements[msg->num_elements]; - el->flags = flags; - el->name = talloc_strdup(msg->elements, attr); - el->values = talloc(msg->elements, struct ldb_val); - if (!el->values || !el->name) { - goto failed; - } - el->num_values = 1; - ret = a->syntax->ldif_read_fn(ldb, el->values, &value, &el->values[0]); - if (ret != 0) { - goto failed; - } - if (value.data != el->values[0].data) { - talloc_steal(el->values, el->values[0].data); - } - msg->num_elements++; - } - } - - if (ldif->changetype == LDB_CHANGETYPE_MODRDN) { - int ret; - - ret = ldb_ldif_parse_modrdn(ldb, ldif, ldif, - NULL, NULL, NULL, NULL, NULL); - if (ret != LDB_SUCCESS) { - goto failed; - } - } - - return ldif; - -failed: - talloc_free(ldif); - return NULL; -} - - - -/* - a wrapper around ldif_read() for reading from FILE* -*/ - -static int fgetc_file(void *private_data) -{ - int c; - struct ldif_read_file_state *state = - (struct ldif_read_file_state *)private_data; - c = fgetc(state->f); - if (c == '\n') { - state->line_no++; - } - return c; -} - -struct ldb_ldif *ldb_ldif_read_file_state(struct ldb_context *ldb, - struct ldif_read_file_state *state) -{ - return ldb_ldif_read(ldb, fgetc_file, state); -} - -struct ldb_ldif *ldb_ldif_read_file(struct ldb_context *ldb, FILE *f) -{ - struct ldif_read_file_state state; - state.f = f; - return ldb_ldif_read_file_state(ldb, &state); -} - -/* - a wrapper around ldif_read() for reading from const char* -*/ -struct ldif_read_string_state { - const char *s; -}; - -static int fgetc_string(void *private_data) -{ - struct ldif_read_string_state *state = - (struct ldif_read_string_state *)private_data; - if (state->s[0] != 0) { - return *state->s++; - } - return EOF; -} - -struct ldb_ldif *ldb_ldif_read_string(struct ldb_context *ldb, const char **s) -{ - struct ldif_read_string_state state; - struct ldb_ldif *ldif; - state.s = *s; - ldif = ldb_ldif_read(ldb, fgetc_string, &state); - *s = state.s; - return ldif; -} - - -/* - wrapper around ldif_write() for a file -*/ -struct ldif_write_file_state { - FILE *f; -}; - -static int fprintf_file(void *private_data, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); - -static int fprintf_file(void *private_data, const char *fmt, ...) -{ - struct ldif_write_file_state *state = - (struct ldif_write_file_state *)private_data; - int ret; - va_list ap; - - va_start(ap, fmt); - ret = vfprintf(state->f, fmt, ap); - va_end(ap); - return ret; -} - -int ldb_ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif *ldif) -{ - struct ldif_write_file_state state; - state.f = f; - return ldb_ldif_write(ldb, fprintf_file, &state, ldif); -} - -/* - wrapper around ldif_write() for a string -*/ -struct ldif_write_string_state { - char *string; -}; - -static int ldif_printf_string(void *private_data, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); - -static int ldif_printf_string(void *private_data, const char *fmt, ...) -{ - struct ldif_write_string_state *state = - (struct ldif_write_string_state *)private_data; - va_list ap; - size_t oldlen = talloc_get_size(state->string); - va_start(ap, fmt); - - state->string = talloc_vasprintf_append(state->string, fmt, ap); - va_end(ap); - if (!state->string) { - return -1; - } - - return talloc_get_size(state->string) - oldlen; -} - -char *ldb_ldif_write_redacted_trace_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - const struct ldb_ldif *ldif) -{ - struct ldif_write_string_state state; - state.string = talloc_strdup(mem_ctx, ""); - if (!state.string) { - return NULL; - } - if (ldb_ldif_write_trace(ldb, ldif_printf_string, &state, ldif, true) == -1) { - return NULL; - } - return state.string; -} - -char *ldb_ldif_write_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - const struct ldb_ldif *ldif) -{ - struct ldif_write_string_state state; - state.string = talloc_strdup(mem_ctx, ""); - if (!state.string) { - return NULL; - } - if (ldb_ldif_write(ldb, ldif_printf_string, &state, ldif) == -1) { - return NULL; - } - return state.string; -} - -/* - convenient function to turn a ldb_message into a string. Useful for - debugging - */ -char *ldb_ldif_message_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - enum ldb_changetype changetype, - const struct ldb_message *msg) -{ - struct ldb_ldif ldif; - - ldif.changetype = changetype; - ldif.msg = discard_const_p(struct ldb_message, msg); - - return ldb_ldif_write_string(ldb, mem_ctx, &ldif); -} - -/* - * convenient function to turn a ldb_message into a string. Useful for - * debugging but also safer if some of the LDIF could be sensitive. - * - * The secret attributes are specified in a 'const char * const *' within - * the LDB_SECRET_ATTRIBUTE_LIST opaque set on the ldb - * - */ -char *ldb_ldif_message_redacted_string(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - enum ldb_changetype changetype, - const struct ldb_message *msg) -{ - struct ldb_ldif ldif; - - ldif.changetype = changetype; - ldif.msg = discard_const_p(struct ldb_message, msg); - - return ldb_ldif_write_redacted_trace_string(ldb, mem_ctx, &ldif); -} diff --git a/ldb-2.0.8/common/ldb_match.c b/ldb-2.0.8/common/ldb_match.c deleted file mode 100644 index 829afa7..0000000 --- a/ldb-2.0.8/common/ldb_match.c +++ /dev/null @@ -1,755 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004-2005 - Copyright (C) Simo Sorce 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb expression matching - * - * Description: ldb expression matching - * - * Author: Andrew Tridgell - */ - -#include "ldb_private.h" -#include "dlinklist.h" - -/* - check if the scope matches in a search result -*/ -static int ldb_match_scope(struct ldb_context *ldb, - struct ldb_dn *base, - struct ldb_dn *dn, - enum ldb_scope scope) -{ - int ret = 0; - - if (base == NULL || dn == NULL) { - return 1; - } - - switch (scope) { - case LDB_SCOPE_BASE: - if (ldb_dn_compare(base, dn) == 0) { - ret = 1; - } - break; - - case LDB_SCOPE_ONELEVEL: - if (ldb_dn_get_comp_num(dn) == (ldb_dn_get_comp_num(base) + 1)) { - if (ldb_dn_compare_base(base, dn) == 0) { - ret = 1; - } - } - break; - - case LDB_SCOPE_SUBTREE: - default: - if (ldb_dn_compare_base(base, dn) == 0) { - ret = 1; - } - break; - } - - return ret; -} - - -/* - match if node is present -*/ -static int ldb_match_present(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - enum ldb_scope scope, bool *matched) -{ - const struct ldb_schema_attribute *a; - struct ldb_message_element *el; - - if (ldb_attr_dn(tree->u.present.attr) == 0) { - *matched = true; - return LDB_SUCCESS; - } - - el = ldb_msg_find_element(msg, tree->u.present.attr); - if (el == NULL) { - *matched = false; - return LDB_SUCCESS; - } - - a = ldb_schema_attribute_by_name(ldb, el->name); - if (!a) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - - if (a->syntax->operator_fn) { - unsigned int i; - for (i = 0; i < el->num_values; i++) { - int ret = a->syntax->operator_fn(ldb, LDB_OP_PRESENT, a, &el->values[i], NULL, matched); - if (ret != LDB_SUCCESS) return ret; - if (*matched) return LDB_SUCCESS; - } - *matched = false; - return LDB_SUCCESS; - } - - *matched = true; - return LDB_SUCCESS; -} - -static int ldb_match_comparison(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - enum ldb_scope scope, - enum ldb_parse_op comp_op, bool *matched) -{ - unsigned int i; - struct ldb_message_element *el; - const struct ldb_schema_attribute *a; - - /* FIXME: APPROX comparison not handled yet */ - if (comp_op == LDB_OP_APPROX) { - return LDB_ERR_INAPPROPRIATE_MATCHING; - } - - el = ldb_msg_find_element(msg, tree->u.comparison.attr); - if (el == NULL) { - *matched = false; - return LDB_SUCCESS; - } - - a = ldb_schema_attribute_by_name(ldb, el->name); - if (!a) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - - for (i = 0; i < el->num_values; i++) { - if (a->syntax->operator_fn) { - int ret; - ret = a->syntax->operator_fn(ldb, comp_op, a, &el->values[i], &tree->u.comparison.value, matched); - if (ret != LDB_SUCCESS) return ret; - if (*matched) return LDB_SUCCESS; - } else { - int ret = a->syntax->comparison_fn(ldb, ldb, &el->values[i], &tree->u.comparison.value); - - if (ret == 0) { - *matched = true; - return LDB_SUCCESS; - } - if (ret > 0 && comp_op == LDB_OP_GREATER) { - *matched = true; - return LDB_SUCCESS; - } - if (ret < 0 && comp_op == LDB_OP_LESS) { - *matched = true; - return LDB_SUCCESS; - } - } - } - - *matched = false; - return LDB_SUCCESS; -} - -/* - match a simple leaf node -*/ -static int ldb_match_equality(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - enum ldb_scope scope, - bool *matched) -{ - unsigned int i; - struct ldb_message_element *el; - const struct ldb_schema_attribute *a; - struct ldb_dn *valuedn; - int ret; - - if (ldb_attr_dn(tree->u.equality.attr) == 0) { - valuedn = ldb_dn_from_ldb_val(ldb, ldb, &tree->u.equality.value); - if (valuedn == NULL) { - return LDB_ERR_INVALID_DN_SYNTAX; - } - - ret = ldb_dn_compare(msg->dn, valuedn); - - talloc_free(valuedn); - - *matched = (ret == 0); - return LDB_SUCCESS; - } - - /* TODO: handle the "*" case derived from an extended search - operation without the attibute type defined */ - el = ldb_msg_find_element(msg, tree->u.equality.attr); - if (el == NULL) { - *matched = false; - return LDB_SUCCESS; - } - - a = ldb_schema_attribute_by_name(ldb, el->name); - if (a == NULL) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - - for (i=0;inum_values;i++) { - if (a->syntax->operator_fn) { - ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a, - &tree->u.equality.value, &el->values[i], matched); - if (ret != LDB_SUCCESS) return ret; - if (*matched) return LDB_SUCCESS; - } else { - if (a->syntax->comparison_fn(ldb, ldb, &tree->u.equality.value, - &el->values[i]) == 0) { - *matched = true; - return LDB_SUCCESS; - } - } - } - - *matched = false; - return LDB_SUCCESS; -} - -static int ldb_wildcard_compare(struct ldb_context *ldb, - const struct ldb_parse_tree *tree, - const struct ldb_val value, bool *matched) -{ - const struct ldb_schema_attribute *a; - struct ldb_val val; - struct ldb_val cnk; - struct ldb_val *chunk; - uint8_t *save_p = NULL; - unsigned int c = 0; - - if (tree->operation != LDB_OP_SUBSTRING) { - *matched = false; - return LDB_ERR_INAPPROPRIATE_MATCHING; - } - - a = ldb_schema_attribute_by_name(ldb, tree->u.substring.attr); - if (!a) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - - if (tree->u.substring.chunks == NULL) { - *matched = false; - return LDB_SUCCESS; - } - - if (a->syntax->canonicalise_fn(ldb, ldb, &value, &val) != 0) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - - save_p = val.data; - cnk.data = NULL; - - if ( ! tree->u.substring.start_with_wildcard ) { - - chunk = tree->u.substring.chunks[c]; - if (a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto mismatch; - - /* This deals with wildcard prefix searches on binary attributes (eg objectGUID) */ - if (cnk.length > val.length) { - goto mismatch; - } - /* - * Empty strings are returned as length 0. Ensure - * we can cope with this. - */ - if (cnk.length == 0) { - goto mismatch; - } - - if (memcmp((char *)val.data, (char *)cnk.data, cnk.length) != 0) goto mismatch; - val.length -= cnk.length; - val.data += cnk.length; - c++; - talloc_free(cnk.data); - cnk.data = NULL; - } - - while (tree->u.substring.chunks[c]) { - uint8_t *p; - - chunk = tree->u.substring.chunks[c]; - if(a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto mismatch; - - /* - * Empty strings are returned as length 0. Ensure - * we can cope with this. - */ - if (cnk.length == 0) { - goto mismatch; - } - /* - * Values might be binary blobs. Don't use string - * search, but memory search instead. - */ - p = memmem((const void *)val.data,val.length, - (const void *)cnk.data, cnk.length); - if (p == NULL) goto mismatch; - - /* - * At this point we know cnk.length <= val.length as - * otherwise there could be no match - */ - - if ( (! tree->u.substring.chunks[c + 1]) && (! tree->u.substring.end_with_wildcard) ) { - uint8_t *g; - uint8_t *end = val.data + val.length; - do { /* greedy */ - - /* - * haystack is a valid pointer in val - * because the memmem() can only - * succeed if the needle (cnk.length) - * is <= haystacklen - * - * p will be a pointer at least - * cnk.length from the end of haystack - */ - uint8_t *haystack - = p + cnk.length; - size_t haystacklen - = end - (haystack); - - g = memmem(haystack, - haystacklen, - (const uint8_t *)cnk.data, - cnk.length); - if (g) { - p = g; - } - } while(g); - } - val.length = val.length - (p - (uint8_t *)(val.data)) - cnk.length; - val.data = (uint8_t *)(p + cnk.length); - c++; - talloc_free(cnk.data); - cnk.data = NULL; - } - - /* last chunk may not have reached end of string */ - if ( (! tree->u.substring.end_with_wildcard) && (val.length != 0) ) goto mismatch; - talloc_free(save_p); - *matched = true; - return LDB_SUCCESS; - -mismatch: - *matched = false; - talloc_free(save_p); - talloc_free(cnk.data); - return LDB_SUCCESS; -} - -/* - match a simple leaf node -*/ -static int ldb_match_substring(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - enum ldb_scope scope, bool *matched) -{ - unsigned int i; - struct ldb_message_element *el; - - el = ldb_msg_find_element(msg, tree->u.substring.attr); - if (el == NULL) { - *matched = false; - return LDB_SUCCESS; - } - - for (i = 0; i < el->num_values; i++) { - int ret; - ret = ldb_wildcard_compare(ldb, tree, el->values[i], matched); - if (ret != LDB_SUCCESS) return ret; - if (*matched) return LDB_SUCCESS; - } - - *matched = false; - return LDB_SUCCESS; -} - - -/* - bitwise and/or comparator depending on oid -*/ -static int ldb_comparator_bitmask(const char *oid, const struct ldb_val *v1, const struct ldb_val *v2, - bool *matched) -{ - uint64_t i1, i2; - char ibuf[100]; - char *endptr = NULL; - - if (v1->length >= sizeof(ibuf)-1) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - memcpy(ibuf, (char *)v1->data, v1->length); - ibuf[v1->length] = 0; - i1 = strtoull(ibuf, &endptr, 0); - if (endptr != NULL) { - if (endptr == ibuf || *endptr != 0) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - } - - if (v2->length >= sizeof(ibuf)-1) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - endptr = NULL; - memcpy(ibuf, (char *)v2->data, v2->length); - ibuf[v2->length] = 0; - i2 = strtoull(ibuf, &endptr, 0); - if (endptr != NULL) { - if (endptr == ibuf || *endptr != 0) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - } - if (strcmp(LDB_OID_COMPARATOR_AND, oid) == 0) { - *matched = ((i1 & i2) == i2); - } else if (strcmp(LDB_OID_COMPARATOR_OR, oid) == 0) { - *matched = ((i1 & i2) != 0); - } else { - return LDB_ERR_INAPPROPRIATE_MATCHING; - } - return LDB_SUCCESS; -} - -static int ldb_match_bitmask(struct ldb_context *ldb, - const char *oid, - const struct ldb_message *msg, - const char *attribute_to_match, - const struct ldb_val *value_to_match, - bool *matched) -{ - unsigned int i; - struct ldb_message_element *el; - - /* find the message element */ - el = ldb_msg_find_element(msg, attribute_to_match); - if (el == NULL) { - *matched = false; - return LDB_SUCCESS; - } - - for (i=0;inum_values;i++) { - int ret; - struct ldb_val *v = &el->values[i]; - - ret = ldb_comparator_bitmask(oid, v, value_to_match, matched); - if (ret != LDB_SUCCESS) { - return ret; - } - if (*matched) { - return LDB_SUCCESS; - } - } - - *matched = false; - return LDB_SUCCESS; -} - -/* - always return false -*/ -static int ldb_comparator_false(struct ldb_context *ldb, - const char *oid, - const struct ldb_message *msg, - const char *attribute_to_match, - const struct ldb_val *value_to_match, - bool *matched) -{ - *matched = false; - return LDB_SUCCESS; -} - - -static const struct ldb_extended_match_rule *ldb_find_extended_match_rule(struct ldb_context *ldb, - const char *oid) -{ - struct ldb_extended_match_entry *extended_match_rule; - - for (extended_match_rule = ldb->extended_match_rules; - extended_match_rule; - extended_match_rule = extended_match_rule->next) { - if (strcmp(extended_match_rule->rule->oid, oid) == 0) { - return extended_match_rule->rule; - } - } - - return NULL; -} - - -/* - extended match, handles things like bitops -*/ -static int ldb_match_extended(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - enum ldb_scope scope, bool *matched) -{ - const struct ldb_extended_match_rule *rule; - - if (tree->u.extended.dnAttributes) { - /* FIXME: We really need to find out what this ":dn" part in - * an extended match means and how to handle it. For now print - * only a warning to have s3 winbind and other tools working - * against us. - Matthias */ - ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb: dnAttributes extended match not supported yet"); - } - if (tree->u.extended.rule_id == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: no-rule extended matches not supported yet"); - return LDB_ERR_INAPPROPRIATE_MATCHING; - } - if (tree->u.extended.attr == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: no-attribute extended matches not supported yet"); - return LDB_ERR_INAPPROPRIATE_MATCHING; - } - - rule = ldb_find_extended_match_rule(ldb, tree->u.extended.rule_id); - if (rule == NULL) { - *matched = false; - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb: unknown extended rule_id %s", - tree->u.extended.rule_id); - return LDB_SUCCESS; - } - - return rule->callback(ldb, rule->oid, msg, - tree->u.extended.attr, - &tree->u.extended.value, matched); -} - -/* - Check if a particular message will match the given filter - - set *matched to true if it matches, false otherwise - - returns LDB_SUCCESS or an error - - this is a recursive function, and does short-circuit evaluation - */ -int ldb_match_message(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - enum ldb_scope scope, bool *matched) -{ - unsigned int i; - int ret; - - *matched = false; - - if (scope != LDB_SCOPE_BASE && ldb_dn_is_special(msg->dn)) { - /* don't match special records except on base searches */ - return LDB_SUCCESS; - } - - switch (tree->operation) { - case LDB_OP_AND: - for (i=0;iu.list.num_elements;i++) { - ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched); - if (ret != LDB_SUCCESS) return ret; - if (!*matched) return LDB_SUCCESS; - } - *matched = true; - return LDB_SUCCESS; - - case LDB_OP_OR: - for (i=0;iu.list.num_elements;i++) { - ret = ldb_match_message(ldb, msg, tree->u.list.elements[i], scope, matched); - if (ret != LDB_SUCCESS) return ret; - if (*matched) return LDB_SUCCESS; - } - *matched = false; - return LDB_SUCCESS; - - case LDB_OP_NOT: - ret = ldb_match_message(ldb, msg, tree->u.isnot.child, scope, matched); - if (ret != LDB_SUCCESS) return ret; - *matched = ! *matched; - return LDB_SUCCESS; - - case LDB_OP_EQUALITY: - return ldb_match_equality(ldb, msg, tree, scope, matched); - - case LDB_OP_SUBSTRING: - return ldb_match_substring(ldb, msg, tree, scope, matched); - - case LDB_OP_GREATER: - return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_GREATER, matched); - - case LDB_OP_LESS: - return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_LESS, matched); - - case LDB_OP_PRESENT: - return ldb_match_present(ldb, msg, tree, scope, matched); - - case LDB_OP_APPROX: - return ldb_match_comparison(ldb, msg, tree, scope, LDB_OP_APPROX, matched); - - case LDB_OP_EXTENDED: - return ldb_match_extended(ldb, msg, tree, scope, matched); - } - - return LDB_ERR_INAPPROPRIATE_MATCHING; -} - -/* - return 0 if the given parse tree matches the given message. Assumes - the message is in sorted order - - return 1 if it matches, and 0 if it doesn't match -*/ - -int ldb_match_msg(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - struct ldb_dn *base, - enum ldb_scope scope) -{ - bool matched; - int ret; - - if ( ! ldb_match_scope(ldb, base, msg->dn, scope) ) { - return 0; - } - - ret = ldb_match_message(ldb, msg, tree, scope, &matched); - if (ret != LDB_SUCCESS) { - /* to match the old API, we need to consider this a - failure to match */ - return 0; - } - return matched?1:0; -} - -int ldb_match_msg_error(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - struct ldb_dn *base, - enum ldb_scope scope, - bool *matched) -{ - if ( ! ldb_match_scope(ldb, base, msg->dn, scope) ) { - *matched = false; - return LDB_SUCCESS; - } - - return ldb_match_message(ldb, msg, tree, scope, matched); -} - -int ldb_match_msg_objectclass(const struct ldb_message *msg, - const char *objectclass) -{ - unsigned int i; - struct ldb_message_element *el = ldb_msg_find_element(msg, "objectClass"); - if (!el) { - return 0; - } - for (i=0; i < el->num_values; i++) { - if (ldb_attr_cmp((const char *)el->values[i].data, objectclass) == 0) { - return 1; - } - } - return 0; -} - -_PRIVATE_ int ldb_register_extended_match_rules(struct ldb_context *ldb) -{ - struct ldb_extended_match_rule *bitmask_and; - struct ldb_extended_match_rule *bitmask_or; - struct ldb_extended_match_rule *always_false; - int ret; - - /* Register bitmask-and match */ - bitmask_and = talloc_zero(ldb, struct ldb_extended_match_rule); - if (bitmask_and == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - bitmask_and->oid = LDB_OID_COMPARATOR_AND; - bitmask_and->callback = ldb_match_bitmask; - - ret = ldb_register_extended_match_rule(ldb, bitmask_and); - if (ret != LDB_SUCCESS) { - return ret; - } - - /* Register bitmask-or match */ - bitmask_or = talloc_zero(ldb, struct ldb_extended_match_rule); - if (bitmask_or == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - bitmask_or->oid = LDB_OID_COMPARATOR_OR; - bitmask_or->callback = ldb_match_bitmask; - - ret = ldb_register_extended_match_rule(ldb, bitmask_or); - if (ret != LDB_SUCCESS) { - return ret; - } - - /* Register always-false match */ - always_false = talloc_zero(ldb, struct ldb_extended_match_rule); - if (always_false == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - always_false->oid = SAMBA_LDAP_MATCH_ALWAYS_FALSE; - always_false->callback = ldb_comparator_false; - - ret = ldb_register_extended_match_rule(ldb, always_false); - if (ret != LDB_SUCCESS) { - return ret; - } - - return LDB_SUCCESS; -} - -/* - register a new ldb extended matching rule -*/ -int ldb_register_extended_match_rule(struct ldb_context *ldb, - const struct ldb_extended_match_rule *rule) -{ - const struct ldb_extended_match_rule *lookup_rule; - struct ldb_extended_match_entry *entry; - - lookup_rule = ldb_find_extended_match_rule(ldb, rule->oid); - if (lookup_rule) { - return LDB_ERR_ENTRY_ALREADY_EXISTS; - } - - entry = talloc_zero(ldb, struct ldb_extended_match_entry); - if (!entry) { - return LDB_ERR_OPERATIONS_ERROR; - } - entry->rule = rule; - DLIST_ADD_END(ldb->extended_match_rules, entry); - - return LDB_SUCCESS; -} - diff --git a/ldb-2.0.8/common/ldb_modules.c b/ldb-2.0.8/common/ldb_modules.c deleted file mode 100644 index cc067ab..0000000 --- a/ldb-2.0.8/common/ldb_modules.c +++ /dev/null @@ -1,1236 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2004-2008 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb modules core - * - * Description: core modules routines - * - * Author: Simo Sorce - */ - -#include "ldb_private.h" -#include "dlinklist.h" -#include "system/dir.h" - -static char *ldb_modules_strdup_no_spaces(TALLOC_CTX *mem_ctx, const char *string) -{ - size_t i, len; - char *trimmed; - - trimmed = talloc_strdup(mem_ctx, string); - if (!trimmed) { - return NULL; - } - - len = strlen(trimmed); - for (i = 0; trimmed[i] != '\0'; i++) { - switch (trimmed[i]) { - case ' ': - case '\t': - case '\n': - memmove(&trimmed[i], &trimmed[i + 1], len -i -1); - break; - } - } - - return trimmed; -} - - -/* modules are called in inverse order on the stack. - Lets place them as an admin would think the right order is. - Modules order is important */ -const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string) -{ - char **modules = NULL; - const char **m; - char *modstr, *p; - unsigned int i; - - /* spaces not admitted */ - modstr = ldb_modules_strdup_no_spaces(mem_ctx, string); - if ( ! modstr) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_strdup_no_spaces()"); - return NULL; - } - - modules = talloc_realloc(mem_ctx, modules, char *, 2); - if ( ! modules ) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()"); - talloc_free(modstr); - return NULL; - } - talloc_steal(modules, modstr); - - if (modstr[0] == '\0') { - modules[0] = NULL; - m = discard_const_p(const char *, modules); - return m; - } - - i = 0; - /* The str*r*chr walks backwards: This is how we get the inverse order mentioned above */ - while ((p = strrchr(modstr, ',')) != NULL) { - *p = '\0'; - p++; - modules[i] = p; - - i++; - modules = talloc_realloc(mem_ctx, modules, char *, i + 2); - if ( ! modules ) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in ldb_modules_list_from_string()"); - return NULL; - } - - } - modules[i] = modstr; - - modules[i + 1] = NULL; - - m = discard_const_p(const char *, modules); - - return m; -} - -static struct backends_list_entry { - struct ldb_backend_ops *ops; - struct backends_list_entry *prev, *next; -} *ldb_backends = NULL; - -static struct ops_list_entry { - const struct ldb_module_ops *ops; - struct ops_list_entry *next; -} *registered_modules = NULL; - -static struct backends_list_entry *ldb_find_backend(const char *url_prefix) -{ - struct backends_list_entry *backend; - - for (backend = ldb_backends; backend; backend = backend->next) { - if (strcmp(backend->ops->name, url_prefix) == 0) { - return backend; - } - } - - return NULL; -} - -/* - register a new ldb backend - - if override is true, then override any existing backend for this prefix -*/ -int ldb_register_backend(const char *url_prefix, ldb_connect_fn connectfn, bool override) -{ - struct backends_list_entry *be; - - be = ldb_find_backend(url_prefix); - if (be) { - if (!override) { - return LDB_SUCCESS; - } - } else { - be = talloc_zero(ldb_backends, struct backends_list_entry); - if (!be) { - return LDB_ERR_OPERATIONS_ERROR; - } - be->ops = talloc_zero(be, struct ldb_backend_ops); - if (!be->ops) { - talloc_free(be); - return LDB_ERR_OPERATIONS_ERROR; - } - DLIST_ADD_END(ldb_backends, be); - } - - be->ops->name = url_prefix; - be->ops->connect_fn = connectfn; - - return LDB_SUCCESS; -} - -/* - Return the ldb module form of a database. - The URL can either be one of the following forms - ldb://path - ldapi://path - - flags is made up of LDB_FLG_* - - the options are passed uninterpreted to the backend, and are - backend specific. - - This allows modules to get at only the backend module, for example where a - module may wish to direct certain requests at a particular backend. -*/ -int ldb_module_connect_backend(struct ldb_context *ldb, - const char *url, - const char *options[], - struct ldb_module **backend_module) -{ - int ret; - char *backend; - struct backends_list_entry *be; - - if (strchr(url, ':') != NULL) { - backend = talloc_strndup(ldb, url, strchr(url, ':')-url); - } else { - /* Default to tdb */ - backend = talloc_strdup(ldb, "tdb"); - } - if (backend == NULL) { - return ldb_oom(ldb); - } - - be = ldb_find_backend(backend); - - talloc_free(backend); - - if (be == NULL) { - ldb_debug(ldb, LDB_DEBUG_FATAL, - "Unable to find backend for '%s' - do you need to set LDB_MODULES_PATH?", url); - return LDB_ERR_OTHER; - } - - ret = be->ops->connect_fn(ldb, url, ldb->flags, options, backend_module); - - if (ret != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Failed to connect to '%s' with backend '%s': %s", url, be->ops->name, ldb_errstring(ldb)); - return ret; - } - return ret; -} - -static struct ldb_hooks { - struct ldb_hooks *next, *prev; - ldb_hook_fn hook_fn; -} *ldb_hooks; - -/* - register a ldb hook function - */ -int ldb_register_hook(ldb_hook_fn hook_fn) -{ - struct ldb_hooks *lc; - lc = talloc_zero(ldb_hooks, struct ldb_hooks); - if (lc == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - lc->hook_fn = hook_fn; - DLIST_ADD_END(ldb_hooks, lc); - return LDB_SUCCESS; -} - -/* - call ldb hooks of a given type - */ -int ldb_modules_hook(struct ldb_context *ldb, enum ldb_module_hook_type t) -{ - struct ldb_hooks *lc; - for (lc = ldb_hooks; lc; lc=lc->next) { - int ret = lc->hook_fn(ldb, t); - if (ret != LDB_SUCCESS) { - return ret; - } - } - return LDB_SUCCESS; -} - - -static const struct ldb_module_ops *ldb_find_module_ops(const char *name) -{ - struct ops_list_entry *e; - - for (e = registered_modules; e; e = e->next) { - if (strcmp(e->ops->name, name) == 0) - return e->ops; - } - - return NULL; -} - - -int ldb_register_module(const struct ldb_module_ops *ops) -{ - struct ops_list_entry *entry; - - if (ldb_find_module_ops(ops->name) != NULL) - return LDB_ERR_ENTRY_ALREADY_EXISTS; - - /* - * ldb modules are not (yet) unloaded and - * are only loaded once (the above check - * makes sure of this). Allocate off the NULL - * context. We never want this to be freed - * until process shutdown. If eventually we - * want to unload ldb modules we can add a - * deregister function that walks and - * frees the list. - */ - entry = talloc(NULL, struct ops_list_entry); - if (entry == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - entry->ops = ops; - entry->next = registered_modules; - registered_modules = entry; - - return LDB_SUCCESS; -} - -/* - load a list of modules - */ -int ldb_module_load_list(struct ldb_context *ldb, const char **module_list, - struct ldb_module *backend, struct ldb_module **out) -{ - struct ldb_module *module; - unsigned int i; - - module = backend; - - for (i = 0; module_list && module_list[i] != NULL; i++) { - struct ldb_module *current; - const struct ldb_module_ops *ops; - - if (strcmp(module_list[i], "") == 0) { - continue; - } - - ops = ldb_find_module_ops(module_list[i]); - - if (ops == NULL) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "WARNING: Module [%s] not found - do you need to set LDB_MODULES_PATH?", - module_list[i]); - return LDB_ERR_OPERATIONS_ERROR; - } - - current = talloc_zero(ldb, struct ldb_module); - if (current == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - talloc_set_name(current, "ldb_module: %s", module_list[i]); - - current->ldb = ldb; - current->ops = ops; - - DLIST_ADD(module, current); - } - *out = module; - return LDB_SUCCESS; -} - -/* - initialise a chain of modules - */ -int ldb_module_init_chain(struct ldb_context *ldb, struct ldb_module *module) -{ - while (module && module->ops->init_context == NULL) - module = module->next; - - /* init is different in that it is not an error if modules - * do not require initialization */ - - if (module) { - int ret = module->ops->init_context(module); - if (ret != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "module %s initialization failed : %s", - module->ops->name, ldb_strerror(ret)); - return ret; - } - } - - return LDB_SUCCESS; -} - -int ldb_load_modules(struct ldb_context *ldb, const char *options[]) -{ - const char *modules_string; - const char **modules = NULL; - int ret; - TALLOC_CTX *mem_ctx = talloc_new(ldb); - if (!mem_ctx) { - return ldb_oom(ldb); - } - - /* find out which modules we are requested to activate */ - - /* check if we have a custom module list passd as ldb option */ - if (options) { - modules_string = ldb_options_find(ldb, options, "modules"); - if (modules_string) { - modules = ldb_modules_list_from_string(ldb, mem_ctx, modules_string); - } - } - - /* if not overloaded by options and the backend is not ldap try to load the modules list from ldb */ - if ((modules == NULL) && (strcmp("ldap", ldb->modules->ops->name) != 0)) { - const char * const attrs[] = { "@LIST" , NULL}; - struct ldb_result *res = NULL; - struct ldb_dn *mods_dn; - - mods_dn = ldb_dn_new(mem_ctx, ldb, "@MODULES"); - if (mods_dn == NULL) { - talloc_free(mem_ctx); - return ldb_oom(ldb); - } - - ret = ldb_search(ldb, mods_dn, &res, mods_dn, LDB_SCOPE_BASE, attrs, "@LIST=*"); - - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db"); - } else if (ret != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "ldb error (%s) occurred searching for modules, bailing out", ldb_errstring(ldb)); - talloc_free(mem_ctx); - return ret; - } else { - const char *module_list; - if (res->count == 0) { - ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db"); - } else if (res->count > 1) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "Too many records found (%u), bailing out", res->count); - talloc_free(mem_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } else { - module_list = ldb_msg_find_attr_as_string(res->msgs[0], "@LIST", NULL); - if (!module_list) { - ldb_debug(ldb, LDB_DEBUG_TRACE, "no modules required by the db"); - } - modules = ldb_modules_list_from_string(ldb, mem_ctx, - module_list); - } - } - - talloc_free(mods_dn); - } - - if (modules != NULL) { - ret = ldb_module_load_list(ldb, modules, ldb->modules, &ldb->modules); - if (ret != LDB_SUCCESS) { - talloc_free(mem_ctx); - return ret; - } - } else { - ldb_debug(ldb, LDB_DEBUG_TRACE, "No modules specified for this database"); - } - - ret = ldb_module_init_chain(ldb, ldb->modules); - talloc_free(mem_ctx); - return ret; -} - -/* - by using this we allow ldb modules to only implement the functions they care about, - which makes writing a module simpler, and makes it more likely to keep working - when ldb is extended -*/ -#define FIND_OP_NOERR(module, op) do { \ - module = module->next; \ - while (module && module->ops->op == NULL) module = module->next; \ - if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { \ - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_trace_next_request: (%s)->" #op, \ - module->ops->name); \ - } \ -} while (0) - -#define FIND_OP(module, op) do { \ - struct ldb_context *ldb = module->ldb; \ - FIND_OP_NOERR(module, op); \ - if (module == NULL) { \ - ldb_asprintf_errstring(ldb, "Unable to find backend operation for " #op ); \ - return LDB_ERR_OPERATIONS_ERROR; \ - } \ -} while (0) - - -struct ldb_module *ldb_module_new(TALLOC_CTX *memctx, - struct ldb_context *ldb, - const char *module_name, - const struct ldb_module_ops *ops) -{ - struct ldb_module *module; - - module = talloc(memctx, struct ldb_module); - if (!module) { - ldb_oom(ldb); - return NULL; - } - talloc_set_name_const(module, module_name); - module->ldb = ldb; - module->prev = module->next = NULL; - module->ops = ops; - - return module; -} - -const char * ldb_module_get_name(struct ldb_module *module) -{ - return module->ops->name; -} - -struct ldb_context *ldb_module_get_ctx(struct ldb_module *module) -{ - return module->ldb; -} - -const struct ldb_module_ops *ldb_module_get_ops(struct ldb_module *module) -{ - return module->ops; -} - -void *ldb_module_get_private(struct ldb_module *module) -{ - return module->private_data; -} - -void ldb_module_set_private(struct ldb_module *module, void *private_data) -{ - module->private_data = private_data; -} - -/* - helper functions to call the next module in chain -*/ - -int ldb_next_request(struct ldb_module *module, struct ldb_request *request) -{ - int ret; - - if (request->callback == NULL) { - ldb_set_errstring(module->ldb, "Requests MUST define callbacks"); - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - request->handle->nesting++; - - switch (request->operation) { - case LDB_SEARCH: - FIND_OP(module, search); - ret = module->ops->search(module, request); - break; - case LDB_ADD: - FIND_OP(module, add); - ret = module->ops->add(module, request); - break; - case LDB_MODIFY: - FIND_OP(module, modify); - ret = module->ops->modify(module, request); - break; - case LDB_DELETE: - FIND_OP(module, del); - ret = module->ops->del(module, request); - break; - case LDB_RENAME: - FIND_OP(module, rename); - ret = module->ops->rename(module, request); - break; - case LDB_EXTENDED: - FIND_OP(module, extended); - ret = module->ops->extended(module, request); - break; - default: - FIND_OP(module, request); - ret = module->ops->request(module, request); - break; - } - - request->handle->nesting--; - - if (ret == LDB_SUCCESS) { - return ret; - } - if (!ldb_errstring(module->ldb)) { - const char *op; - switch (request->operation) { - case LDB_SEARCH: - op = "LDB_SEARCH"; - break; - case LDB_ADD: - op = "LDB_ADD"; - break; - case LDB_MODIFY: - op = "LDB_MODIFY"; - break; - case LDB_DELETE: - op = "LDB_DELETE"; - break; - case LDB_RENAME: - op = "LDB_RENAME"; - break; - case LDB_EXTENDED: - op = "LDB_EXTENDED"; - break; - default: - op = "request"; - break; - } - - /* Set a default error string, to place the blame somewhere */ - ldb_asprintf_errstring(module->ldb, "error in module %s: %s during %s (%d)", module->ops->name, ldb_strerror(ret), op, ret); - } - - if (!(request->handle->flags & LDB_HANDLE_FLAG_DONE_CALLED)) { - /* It is _extremely_ common that a module returns a - * failure without calling ldb_module_done(), but that - * guarantees we will end up hanging in - * ldb_wait(). This fixes it without having to rewrite - * all our modules, and leaves us one less sharp - * corner for module developers to cut themselves on - */ - ret = ldb_module_done(request, NULL, NULL, ret); - } - return ret; -} - -int ldb_next_init(struct ldb_module *module) -{ - module = module->next; - - return ldb_module_init_chain(module->ldb, module); -} - -int ldb_next_start_trans(struct ldb_module *module) -{ - int ret; - FIND_OP(module, start_transaction); - ret = module->ops->start_transaction(module); - if (ret == LDB_SUCCESS) { - return ret; - } - if (!ldb_errstring(module->ldb)) { - /* Set a default error string, to place the blame somewhere */ - ldb_asprintf_errstring(module->ldb, "start_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); - } - if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_start_trans error: %s", - ldb_errstring(module->ldb)); - } - return ret; -} - -int ldb_next_end_trans(struct ldb_module *module) -{ - int ret; - FIND_OP(module, end_transaction); - ret = module->ops->end_transaction(module); - if (ret == LDB_SUCCESS) { - return ret; - } - if (!ldb_errstring(module->ldb)) { - /* Set a default error string, to place the blame somewhere */ - ldb_asprintf_errstring(module->ldb, "end_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); - } - if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_end_trans error: %s", - ldb_errstring(module->ldb)); - } - return ret; -} - -int ldb_next_read_lock(struct ldb_module *module) -{ - int ret; - FIND_OP(module, read_lock); - ret = module->ops->read_lock(module); - if (ret == LDB_SUCCESS) { - return ret; - } - if (!ldb_errstring(module->ldb)) { - /* Set a default error string, to place the blame somewhere */ - ldb_asprintf_errstring(module->ldb, - "read_lock error in module %s: %s (%d)", - module->ops->name, ldb_strerror(ret), - ret); - } - if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { - ldb_debug(module->ldb, LDB_DEBUG_TRACE, - "ldb_next_read_lock error: %s", - ldb_errstring(module->ldb)); - } - return ret; -} - -int ldb_next_read_unlock(struct ldb_module *module) -{ - int ret; - FIND_OP(module, read_unlock); - ret = module->ops->read_unlock(module); - if (ret == LDB_SUCCESS) { - return ret; - } - if (!ldb_errstring(module->ldb)) { - /* Set a default error string, to place the blame somewhere */ - ldb_asprintf_errstring(module->ldb, - "read_unlock error in module %s: %s (%d)", - module->ops->name, ldb_strerror(ret), - ret); - } - if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { - ldb_debug(module->ldb, LDB_DEBUG_TRACE, - "ldb_next_read_unlock error: %s", - ldb_errstring(module->ldb)); - } - return ret; -} - -int ldb_next_prepare_commit(struct ldb_module *module) -{ - int ret; - FIND_OP_NOERR(module, prepare_commit); - if (module == NULL) { - /* we are allowed to have no prepare commit in - backends */ - return LDB_SUCCESS; - } - ret = module->ops->prepare_commit(module); - if (ret == LDB_SUCCESS) { - return ret; - } - if (!ldb_errstring(module->ldb)) { - /* Set a default error string, to place the blame somewhere */ - ldb_asprintf_errstring(module->ldb, "prepare_commit error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); - } - if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_prepare_commit error: %s", - ldb_errstring(module->ldb)); - } - return ret; -} - -int ldb_next_del_trans(struct ldb_module *module) -{ - int ret; - FIND_OP(module, del_transaction); - ret = module->ops->del_transaction(module); - if (ret == LDB_SUCCESS) { - return ret; - } - if (!ldb_errstring(module->ldb)) { - /* Set a default error string, to place the blame somewhere */ - ldb_asprintf_errstring(module->ldb, "del_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); - } - if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { - ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_del_trans error: %s", - ldb_errstring(module->ldb)); - } - return ret; -} - -/* calls the request callback to send an entry - * - * params: - * req: the original request passed to your module - * msg: reply message (must be a talloc pointer, and it will be stolen - * on the ldb_reply that is sent to the callback) - * ctrls: controls to send in the reply (must be a talloc pointer, and it will be stolen - * on the ldb_reply that is sent to the callback) - */ - -int ldb_module_send_entry(struct ldb_request *req, - struct ldb_message *msg, - struct ldb_control **ctrls) -{ - struct ldb_reply *ares; - - ares = talloc_zero(req, struct ldb_reply); - if (!ares) { - ldb_oom(req->handle->ldb); - req->callback(req, NULL); - return LDB_ERR_OPERATIONS_ERROR; - } - ares->type = LDB_REPLY_ENTRY; - ares->message = talloc_steal(ares, msg); - ares->controls = talloc_steal(ares, ctrls); - ares->error = LDB_SUCCESS; - - if ((req->handle->ldb->flags & LDB_FLG_ENABLE_TRACING) && - req->handle->nesting == 0) { - char *s; - struct ldb_ldif ldif; - - ldif.changetype = LDB_CHANGETYPE_NONE; - ldif.msg = discard_const_p(struct ldb_message, msg); - - ldb_debug_add(req->handle->ldb, "ldb_trace_response: ENTRY\n"); - - /* - * The choice to call - * ldb_ldif_write_redacted_trace_string() is CRITICAL - * for security. It ensures that we do not output - * passwords into debug logs - */ - - s = ldb_ldif_write_redacted_trace_string(req->handle->ldb, msg, &ldif); - ldb_debug_add(req->handle->ldb, "%s\n", s); - talloc_free(s); - ldb_debug_end(req->handle->ldb, LDB_DEBUG_TRACE); - } - - return req->callback(req, ares); -} - -/* calls the request callback to send an referrals - * - * params: - * req: the original request passed to your module - * ref: referral string (must be a talloc pointer, steal) - */ - -int ldb_module_send_referral(struct ldb_request *req, - char *ref) -{ - struct ldb_reply *ares; - - ares = talloc_zero(req, struct ldb_reply); - if (!ares) { - ldb_oom(req->handle->ldb); - req->callback(req, NULL); - return LDB_ERR_OPERATIONS_ERROR; - } - ares->type = LDB_REPLY_REFERRAL; - ares->referral = talloc_steal(ares, ref); - ares->error = LDB_SUCCESS; - - if ((req->handle->ldb->flags & LDB_FLG_ENABLE_TRACING) && - req->handle->nesting == 0) { - ldb_debug_add(req->handle->ldb, "ldb_trace_response: REFERRAL\n"); - ldb_debug_add(req->handle->ldb, "ref: %s\n", ref); - ldb_debug_end(req->handle->ldb, LDB_DEBUG_TRACE); - } - - return req->callback(req, ares); -} - -/* calls the original request callback - * - * params: - * req: the original request passed to your module - * ctrls: controls to send in the reply (must be a talloc pointer, steal) - * response: results for extended request (steal) - * error: LDB_SUCCESS for a successful return - * any other ldb error otherwise - */ -int ldb_module_done(struct ldb_request *req, - struct ldb_control **ctrls, - struct ldb_extended *response, - int error) -{ - struct ldb_reply *ares; - - ares = talloc_zero(req, struct ldb_reply); - if (!ares) { - ldb_oom(req->handle->ldb); - req->callback(req, NULL); - return LDB_ERR_OPERATIONS_ERROR; - } - ares->type = LDB_REPLY_DONE; - ares->controls = talloc_steal(ares, ctrls); - ares->response = talloc_steal(ares, response); - ares->error = error; - - req->handle->flags |= LDB_HANDLE_FLAG_DONE_CALLED; - - if ((req->handle->ldb->flags & LDB_FLG_ENABLE_TRACING) && - req->handle->nesting == 0) { - ldb_debug_add(req->handle->ldb, "ldb_trace_response: DONE\n"); - ldb_debug_add(req->handle->ldb, "error: %d\n", error); - if (ldb_errstring(req->handle->ldb)) { - ldb_debug_add(req->handle->ldb, "msg: %s\n", - ldb_errstring(req->handle->ldb)); - } - ldb_debug_end(req->handle->ldb, LDB_DEBUG_TRACE); - } - - return req->callback(req, ares); -} - -/* to be used *only* in modules init functions. - * this function is synchronous and will register - * the requested OID in the rootdse module if present - * otherwise it will return an error */ -int ldb_mod_register_control(struct ldb_module *module, const char *oid) -{ - struct ldb_request *req; - int ret; - - req = talloc_zero(module, struct ldb_request); - if (req == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - req->operation = LDB_REQ_REGISTER_CONTROL; - req->op.reg_control.oid = oid; - req->callback = ldb_op_default_callback; - - ldb_set_timeout(module->ldb, req, 0); - - req->handle = ldb_handle_new(req, module->ldb); - if (req->handle == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_request(module->ldb, req); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - talloc_free(req); - - return ret; -} - -static int ldb_modules_load_dir(const char *modules_dir, const char *version); - - -/* - load one module. A static list of loaded module inode numbers is - used to prevent a module being loaded twice - - dlopen() is used on the module, and dlsym() is then used to look for - a ldb_init_module() function. If present, that function is called - with the ldb version number as an argument. - - The ldb_init_module() function will typically call - ldb_register_module() and ldb_register_backend() to register a - module or backend, but it may also be used to register command line - handling functions, ldif handlers or any other local - modififications. - - The ldb_init_module() function does not get a ldb_context passed in, - as modules will be used for multiple ldb context handles. The call - from the first ldb_init() is just a convenient way to ensure it is - called early enough. - */ -static int ldb_modules_load_path(const char *path, const char *version) -{ - void *handle; - int (*init_fn)(const char *); - int ret; - struct stat st; - static struct loaded { - struct loaded *next, *prev; - ino_t st_ino; - dev_t st_dev; - } *loaded; - struct loaded *le; - int dlopen_flags; - -#ifdef RTLD_DEEPBIND - bool deepbind_enabled = (getenv("LDB_MODULES_DISABLE_DEEPBIND") == NULL); -#endif - - ret = stat(path, &st); - if (ret != 0) { - fprintf(stderr, "ldb: unable to stat module %s : %s\n", path, strerror(errno)); - return LDB_ERR_UNAVAILABLE; - } - - for (le=loaded; le; le=le->next) { - if (le->st_ino == st.st_ino && - le->st_dev == st.st_dev) { - /* its already loaded */ - return LDB_SUCCESS; - } - } - - le = talloc(loaded, struct loaded); - if (le == NULL) { - fprintf(stderr, "ldb: unable to allocated loaded entry\n"); - return LDB_ERR_UNAVAILABLE; - } - - le->st_ino = st.st_ino; - le->st_dev = st.st_dev; - - DLIST_ADD_END(loaded, le); - - /* if it is a directory, recurse */ - if (S_ISDIR(st.st_mode)) { - return ldb_modules_load_dir(path, version); - } - - dlopen_flags = RTLD_NOW; -#ifdef RTLD_DEEPBIND - /* - * use deepbind if possible, to avoid issues with different - * system library variants, for example ldb modules may be linked - * against Heimdal while the application may use MIT kerberos. - * - * See the dlopen manpage for details. - * - * One typical user is the bind_dlz module of Samba, - * but symbol versioning might be enough... - * - * We need a way to disable this in order to allow the - * ldb_*ldap modules to work with a preloaded socket wrapper. - * - * So in future we may remove this completely - * or at least invert the default behavior. - */ - if (deepbind_enabled) { - dlopen_flags |= RTLD_DEEPBIND; - } -#endif - - handle = dlopen(path, dlopen_flags); - if (handle == NULL) { - fprintf(stderr, "ldb: unable to dlopen %s : %s\n", path, dlerror()); - return LDB_SUCCESS; - } - - init_fn = dlsym(handle, "ldb_init_module"); - if (init_fn == NULL) { - /* ignore it, it could be an old-style - * module. Once we've converted all modules we - * could consider this an error */ - dlclose(handle); - return LDB_SUCCESS; - } - - ret = init_fn(version); - if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { - /* the module is already registered - ignore this, as - * it can happen if LDB_MODULES_PATH points at both - * the build and install directory - */ - ret = LDB_SUCCESS; - } - return ret; -} - -static int qsort_string(const char **s1, const char **s2) -{ - return strcmp(*s1, *s2); -} - - -/* - load all modules from the given ldb modules directory. This is run once - during the first ldb_init() call. - - Modules are loaded in alphabetical order to ensure that any module - load ordering dependencies are reproducible. Modules should avoid - relying on load order - */ -static int ldb_modules_load_dir(const char *modules_dir, const char *version) -{ - DIR *dir; - struct dirent *de; - const char **modlist = NULL; - TALLOC_CTX *tmp_ctx = talloc_new(NULL); - unsigned i, num_modules = 0; - - dir = opendir(modules_dir); - if (dir == NULL) { - if (errno == ENOENT) { - talloc_free(tmp_ctx); - /* we don't have any modules */ - return LDB_SUCCESS; - } - talloc_free(tmp_ctx); - fprintf(stderr, "ldb: unable to open modules directory '%s' - %s\n", - modules_dir, strerror(errno)); - return LDB_ERR_UNAVAILABLE; - } - - - while ((de = readdir(dir))) { - if (ISDOT(de->d_name) || ISDOTDOT(de->d_name)) - continue; - - modlist = talloc_realloc(tmp_ctx, modlist, const char *, num_modules+1); - if (modlist == NULL) { - talloc_free(tmp_ctx); - closedir(dir); - fprintf(stderr, "ldb: unable to allocate modules list\n"); - return LDB_ERR_UNAVAILABLE; - } - modlist[num_modules] = talloc_asprintf(modlist, "%s/%s", modules_dir, de->d_name); - if (modlist[num_modules] == NULL) { - talloc_free(tmp_ctx); - closedir(dir); - fprintf(stderr, "ldb: unable to allocate module list entry\n"); - return LDB_ERR_UNAVAILABLE; - } - num_modules++; - } - - closedir(dir); - - /* sort the directory, so we get consistent load ordering */ - TYPESAFE_QSORT(modlist, num_modules, qsort_string); - - for (i=0; ihandle) { - char *s = talloc_asprintf_append_buffer(ret, "req[%u] %p : %s\n", - i++, req, ldb_req_location(req)); - if (s == NULL) { - talloc_free(ret); - return NULL; - } - ret = s; - req = req->handle->parent; - } - return ret; -} - - -/* - return the next module in the chain - */ -struct ldb_module *ldb_module_next(struct ldb_module *module) -{ - return module->next; -} - -/* - set the next module in the module chain - */ -void ldb_module_set_next(struct ldb_module *module, struct ldb_module *next) -{ - module->next = next; -} - - -/* - get the popt_options pointer in the ldb structure. This allows a ldb - module to change the command line parsing - */ -struct poptOption **ldb_module_popt_options(struct ldb_context *ldb) -{ - return &ldb->popt_options; -} - - -/* - return the current ldb flags LDB_FLG_* - */ -uint32_t ldb_module_flags(struct ldb_context *ldb) -{ - return ldb->flags; -} diff --git a/ldb-2.0.8/common/ldb_msg.c b/ldb-2.0.8/common/ldb_msg.c deleted file mode 100644 index 2346e66..0000000 --- a/ldb-2.0.8/common/ldb_msg.c +++ /dev/null @@ -1,1469 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb message component utility functions - * - * Description: functions for manipulating ldb_message structures - * - * Author: Andrew Tridgell - */ - -#include "ldb_private.h" - -/* - create a new ldb_message in a given memory context (NULL for top level) -*/ -struct ldb_message *ldb_msg_new(TALLOC_CTX *mem_ctx) -{ - return talloc_zero(mem_ctx, struct ldb_message); -} - -/* - find an element in a message by attribute name -*/ -struct ldb_message_element *ldb_msg_find_element(const struct ldb_message *msg, - const char *attr_name) -{ - unsigned int i; - for (i=0;inum_elements;i++) { - if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) { - return &msg->elements[i]; - } - } - return NULL; -} - -/* - see if two ldb_val structures contain exactly the same data - return 1 for a match, 0 for a mis-match -*/ -int ldb_val_equal_exact(const struct ldb_val *v1, const struct ldb_val *v2) -{ - if (v1->length != v2->length) return 0; - if (v1->data == v2->data) return 1; - if (v1->length == 0) return 1; - - if (memcmp(v1->data, v2->data, v1->length) == 0) { - return 1; - } - - return 0; -} - -/* - find a value in an element - assumes case sensitive comparison -*/ -struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el, - struct ldb_val *val) -{ - unsigned int i; - for (i=0;inum_values;i++) { - if (ldb_val_equal_exact(val, &el->values[i])) { - return &el->values[i]; - } - } - return NULL; -} - - -static int ldb_val_cmp(const struct ldb_val *v1, const struct ldb_val *v2) -{ - if (v1->length != v2->length) { - return v1->length - v2->length; - } - return memcmp(v1->data, v2->data, v1->length); -} - - -/* - ldb_msg_find_duplicate_val() will set the **duplicate pointer to the first - duplicate value it finds. It does a case sensitive comparison (memcmp). - - LDB_ERR_OPERATIONS_ERROR indicates an allocation failure or an unknown - options flag, otherwise LDB_SUCCESS. -*/ -#define LDB_DUP_QUADRATIC_THRESHOLD 10 - -int ldb_msg_find_duplicate_val(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const struct ldb_message_element *el, - struct ldb_val **duplicate, - uint32_t options) -{ - unsigned int i, j; - struct ldb_val *val; - - if (options != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - *duplicate = NULL; - - /* - If there are not many values, it is best to avoid the talloc - overhead and just do a brute force search. - */ - if (el->num_values < LDB_DUP_QUADRATIC_THRESHOLD) { - for (j = 0; j < el->num_values; j++) { - val = &el->values[j]; - for ( i = j + 1; i < el->num_values; i++) { - if (ldb_val_equal_exact(val, &el->values[i])) { - *duplicate = val; - return LDB_SUCCESS; - } - } - } - } else { - struct ldb_val *values; - values = talloc_array(mem_ctx, struct ldb_val, el->num_values); - if (values == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - memcpy(values, el->values, - el->num_values * sizeof(struct ldb_val)); - TYPESAFE_QSORT(values, el->num_values, ldb_val_cmp); - for (i = 1; i < el->num_values; i++) { - if (ldb_val_equal_exact(&values[i], - &values[i - 1])) { - /* find the original location */ - for (j = 0; j < el->num_values; j++) { - if (ldb_val_equal_exact(&values[i], - &el->values[j]) - ) { - *duplicate = &el->values[j]; - break; - } - } - talloc_free(values); - if (*duplicate == NULL) { - /* how we got here, I don't know */ - return LDB_ERR_OPERATIONS_ERROR; - } - return LDB_SUCCESS; - } - } - talloc_free(values); - } - return LDB_SUCCESS; -} - - -/* - Determine whether the values in an element are also in another element. - - Without any flags, return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS if the elements - share values, or LDB_SUCCESS if they don't. In this case, the function - simply determines the set intersection and it doesn't matter in which order - the elements are provided. - - With the LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES flag, any values in common are - removed from the first element and LDB_SUCCESS is returned. - - LDB_ERR_OPERATIONS_ERROR indicates an allocation failure or an unknown option. - LDB_ERR_INAPPROPRIATE_MATCHING is returned if the elements differ in name. -*/ - -int ldb_msg_find_common_values(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_message_element *el, - struct ldb_message_element *el2, - uint32_t options) -{ - struct ldb_val *values; - struct ldb_val *values2; - unsigned int i, j, k, n_values; - - bool remove_duplicates = options & LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES; - - if ((options & ~LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (strcmp(el->name, el2->name) != 0) { - return LDB_ERR_INAPPROPRIATE_MATCHING; - } - if (el->num_values == 0 || el2->num_values == 0) { - return LDB_SUCCESS; - } - /* - With few values, it is better to do the brute-force search than the - clever search involving tallocs, memcpys, sorts, etc. - */ - if (MIN(el->num_values, el2->num_values) == 1 || - MAX(el->num_values, el2->num_values) < LDB_DUP_QUADRATIC_THRESHOLD) { - for (i = 0; i < el2->num_values; i++) { - for (j = 0; j < el->num_values; j++) { - if (ldb_val_equal_exact(&el->values[j], - &el2->values[i])) { - if (! remove_duplicates) { - return \ - LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; - } - /* - With the remove_duplicates flag, we - resolve the intersection by removing - the offending one from el. - */ - el->num_values--; - for (k = j; k < el->num_values; k++) { - el->values[k] = \ - el->values[k + 1]; - } - j--; /* rewind */ - } - } - } - return LDB_SUCCESS; - } - - values = talloc_array(mem_ctx, struct ldb_val, el->num_values); - if (values == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - values2 = talloc_array(mem_ctx, struct ldb_val, - el2->num_values); - if (values2 == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - memcpy(values, el->values, - el->num_values * sizeof(struct ldb_val)); - memcpy(values2, el2->values, - el2->num_values * sizeof(struct ldb_val)); - TYPESAFE_QSORT(values, el->num_values, ldb_val_cmp); - TYPESAFE_QSORT(values2, el2->num_values, ldb_val_cmp); - - /* - el->n_values may diverge from the number of values in the sorted - list when the remove_duplicates flag is used. - */ - n_values = el->num_values; - i = 0; - j = 0; - while (i != n_values && j < el2->num_values) { - int ret = ldb_val_cmp(&values[i], &values2[j]); - if (ret < 0) { - i++; - } else if (ret > 0) { - j++; - } else { - /* we have a collision */ - if (! remove_duplicates) { - TALLOC_FREE(values); - TALLOC_FREE(values2); - return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; - } - /* - With the remove_duplicates flag we need to find - this in the original list and remove it, which is - inefficient but hopefully rare. - */ - for (k = 0; k < el->num_values; k++) { - if (ldb_val_equal_exact(&el->values[k], - &values[i])) { - break; - } - } - el->num_values--; - for (; k < el->num_values; k++) { - el->values[k] = el->values[k + 1]; - } - i++; - } - } - TALLOC_FREE(values); - TALLOC_FREE(values2); - - return LDB_SUCCESS; -} - -/* - duplicate a ldb_val structure -*/ -struct ldb_val ldb_val_dup(TALLOC_CTX *mem_ctx, const struct ldb_val *v) -{ - struct ldb_val v2; - v2.length = v->length; - if (v->data == NULL) { - v2.data = NULL; - return v2; - } - - /* the +1 is to cope with buggy C library routines like strndup - that look one byte beyond */ - v2.data = talloc_array(mem_ctx, uint8_t, v->length+1); - if (!v2.data) { - v2.length = 0; - return v2; - } - - memcpy(v2.data, v->data, v->length); - ((char *)v2.data)[v->length] = 0; - return v2; -} - -/** - * Adds new empty element to msg->elements - */ -static int _ldb_msg_add_el(struct ldb_message *msg, - struct ldb_message_element **return_el) -{ - struct ldb_message_element *els; - - /* - * TODO: Find out a way to assert on input parameters. - * msg and return_el must be valid - */ - - els = talloc_realloc(msg, msg->elements, - struct ldb_message_element, msg->num_elements + 1); - if (!els) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ZERO_STRUCT(els[msg->num_elements]); - - msg->elements = els; - msg->num_elements++; - - *return_el = &els[msg->num_elements-1]; - - return LDB_SUCCESS; -} - -/** - * Add an empty element with a given name to a message - */ -int ldb_msg_add_empty(struct ldb_message *msg, - const char *attr_name, - int flags, - struct ldb_message_element **return_el) -{ - int ret; - struct ldb_message_element *el; - - ret = _ldb_msg_add_el(msg, &el); - if (ret != LDB_SUCCESS) { - return ret; - } - - /* initialize newly added element */ - el->flags = flags; - el->name = talloc_strdup(msg->elements, attr_name); - if (!el->name) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (return_el) { - *return_el = el; - } - - return LDB_SUCCESS; -} - -/** - * Adds an element to a message. - * - * NOTE: Ownership of ldb_message_element fields - * is NOT transferred. Thus, if *el pointer - * is invalidated for some reason, this will - * corrupt *msg contents also - */ -int ldb_msg_add(struct ldb_message *msg, - const struct ldb_message_element *el, - int flags) -{ - int ret; - struct ldb_message_element *el_new; - /* We have to copy this, just in case *el is a pointer into - * what ldb_msg_add_empty() is about to realloc() */ - struct ldb_message_element el_copy = *el; - - ret = _ldb_msg_add_el(msg, &el_new); - if (ret != LDB_SUCCESS) { - return ret; - } - - el_new->flags = flags; - el_new->name = el_copy.name; - el_new->num_values = el_copy.num_values; - el_new->values = el_copy.values; - - return LDB_SUCCESS; -} - -/* - add a value to a message -*/ -int ldb_msg_add_value(struct ldb_message *msg, - const char *attr_name, - const struct ldb_val *val, - struct ldb_message_element **return_el) -{ - struct ldb_message_element *el; - struct ldb_val *vals; - int ret; - - el = ldb_msg_find_element(msg, attr_name); - if (!el) { - ret = ldb_msg_add_empty(msg, attr_name, 0, &el); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - vals = talloc_realloc(msg->elements, el->values, struct ldb_val, - el->num_values+1); - if (!vals) { - return LDB_ERR_OPERATIONS_ERROR; - } - el->values = vals; - el->values[el->num_values] = *val; - el->num_values++; - - if (return_el) { - *return_el = el; - } - - return LDB_SUCCESS; -} - - -/* - add a value to a message, stealing it into the 'right' place -*/ -int ldb_msg_add_steal_value(struct ldb_message *msg, - const char *attr_name, - struct ldb_val *val) -{ - int ret; - struct ldb_message_element *el; - - ret = ldb_msg_add_value(msg, attr_name, val, &el); - if (ret == LDB_SUCCESS) { - talloc_steal(el->values, val->data); - } - return ret; -} - - -/* - add a string element to a message -*/ -int ldb_msg_add_string(struct ldb_message *msg, - const char *attr_name, const char *str) -{ - struct ldb_val val; - - val.data = discard_const_p(uint8_t, str); - val.length = strlen(str); - - if (val.length == 0) { - /* allow empty strings as non-existent attributes */ - return LDB_SUCCESS; - } - - return ldb_msg_add_value(msg, attr_name, &val, NULL); -} - -/* - add a string element to a message, stealing it into the 'right' place -*/ -int ldb_msg_add_steal_string(struct ldb_message *msg, - const char *attr_name, char *str) -{ - struct ldb_val val; - - val.data = (uint8_t *)str; - val.length = strlen(str); - - if (val.length == 0) { - /* allow empty strings as non-existent attributes */ - return LDB_SUCCESS; - } - - return ldb_msg_add_steal_value(msg, attr_name, &val); -} - -/* - add a DN element to a message - WARNING: this uses the linearized string from the dn, and does not - copy the string. -*/ -int ldb_msg_add_linearized_dn(struct ldb_message *msg, const char *attr_name, - struct ldb_dn *dn) -{ - char *str = ldb_dn_alloc_linearized(msg, dn); - - if (str == NULL) { - /* we don't want to have unknown DNs added */ - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_msg_add_steal_string(msg, attr_name, str); -} - -/* - add a printf formatted element to a message -*/ -int ldb_msg_add_fmt(struct ldb_message *msg, - const char *attr_name, const char *fmt, ...) -{ - struct ldb_val val; - va_list ap; - char *str; - - va_start(ap, fmt); - str = talloc_vasprintf(msg, fmt, ap); - va_end(ap); - - if (str == NULL) return LDB_ERR_OPERATIONS_ERROR; - - val.data = (uint8_t *)str; - val.length = strlen(str); - - return ldb_msg_add_steal_value(msg, attr_name, &val); -} - -/* - compare two ldb_message_element structures - assumes case sensitive comparison -*/ -int ldb_msg_element_compare(struct ldb_message_element *el1, - struct ldb_message_element *el2) -{ - unsigned int i; - - if (el1->num_values != el2->num_values) { - return el1->num_values - el2->num_values; - } - - for (i=0;inum_values;i++) { - if (!ldb_msg_find_val(el2, &el1->values[i])) { - return -1; - } - } - - return 0; -} - -/* - compare two ldb_message_element structures. - Different ordering is considered a mismatch -*/ -bool ldb_msg_element_equal_ordered(const struct ldb_message_element *el1, - const struct ldb_message_element *el2) -{ - unsigned i; - if (el1->num_values != el2->num_values) { - return false; - } - for (i=0;inum_values;i++) { - if (ldb_val_equal_exact(&el1->values[i], - &el2->values[i]) != 1) { - return false; - } - } - return true; -} - -/* - compare two ldb_message_element structures - comparing by element name -*/ -int ldb_msg_element_compare_name(struct ldb_message_element *el1, - struct ldb_message_element *el2) -{ - return ldb_attr_cmp(el1->name, el2->name); -} - -/* - convenience functions to return common types from a message - these return the first value if the attribute is multi-valued -*/ -const struct ldb_val *ldb_msg_find_ldb_val(const struct ldb_message *msg, - const char *attr_name) -{ - struct ldb_message_element *el = ldb_msg_find_element(msg, attr_name); - if (!el || el->num_values == 0) { - return NULL; - } - return &el->values[0]; -} - -int ldb_msg_find_attr_as_int(const struct ldb_message *msg, - const char *attr_name, - int default_value) -{ - const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); - char buf[sizeof("-2147483648")]; - char *end = NULL; - int ret; - - if (!v || !v->data) { - return default_value; - } - - ZERO_STRUCT(buf); - if (v->length >= sizeof(buf)) { - return default_value; - } - - memcpy(buf, v->data, v->length); - errno = 0; - ret = (int) strtoll(buf, &end, 10); - if (errno != 0) { - return default_value; - } - if (end && end[0] != '\0') { - return default_value; - } - return ret; -} - -unsigned int ldb_msg_find_attr_as_uint(const struct ldb_message *msg, - const char *attr_name, - unsigned int default_value) -{ - const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); - char buf[sizeof("-2147483648")]; - char *end = NULL; - unsigned int ret; - - if (!v || !v->data) { - return default_value; - } - - ZERO_STRUCT(buf); - if (v->length >= sizeof(buf)) { - return default_value; - } - - memcpy(buf, v->data, v->length); - errno = 0; - ret = (unsigned int) strtoll(buf, &end, 10); - if (errno != 0) { - errno = 0; - ret = (unsigned int) strtoull(buf, &end, 10); - if (errno != 0) { - return default_value; - } - } - if (end && end[0] != '\0') { - return default_value; - } - return ret; -} - -int64_t ldb_msg_find_attr_as_int64(const struct ldb_message *msg, - const char *attr_name, - int64_t default_value) -{ - const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); - char buf[sizeof("-9223372036854775808")]; - char *end = NULL; - int64_t ret; - - if (!v || !v->data) { - return default_value; - } - - ZERO_STRUCT(buf); - if (v->length >= sizeof(buf)) { - return default_value; - } - - memcpy(buf, v->data, v->length); - errno = 0; - ret = (int64_t) strtoll(buf, &end, 10); - if (errno != 0) { - return default_value; - } - if (end && end[0] != '\0') { - return default_value; - } - return ret; -} - -uint64_t ldb_msg_find_attr_as_uint64(const struct ldb_message *msg, - const char *attr_name, - uint64_t default_value) -{ - const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); - char buf[sizeof("-9223372036854775808")]; - char *end = NULL; - uint64_t ret; - - if (!v || !v->data) { - return default_value; - } - - ZERO_STRUCT(buf); - if (v->length >= sizeof(buf)) { - return default_value; - } - - memcpy(buf, v->data, v->length); - errno = 0; - ret = (uint64_t) strtoll(buf, &end, 10); - if (errno != 0) { - errno = 0; - ret = (uint64_t) strtoull(buf, &end, 10); - if (errno != 0) { - return default_value; - } - } - if (end && end[0] != '\0') { - return default_value; - } - return ret; -} - -double ldb_msg_find_attr_as_double(const struct ldb_message *msg, - const char *attr_name, - double default_value) -{ - const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); - char *buf; - char *end = NULL; - double ret; - - if (!v || !v->data) { - return default_value; - } - buf = talloc_strndup(msg, (const char *)v->data, v->length); - if (buf == NULL) { - return default_value; - } - - errno = 0; - ret = strtod(buf, &end); - talloc_free(buf); - if (errno != 0) { - return default_value; - } - if (end && end[0] != '\0') { - return default_value; - } - return ret; -} - -int ldb_msg_find_attr_as_bool(const struct ldb_message *msg, - const char *attr_name, - int default_value) -{ - const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); - if (!v || !v->data) { - return default_value; - } - if (v->length == 5 && strncasecmp((const char *)v->data, "FALSE", 5) == 0) { - return 0; - } - if (v->length == 4 && strncasecmp((const char *)v->data, "TRUE", 4) == 0) { - return 1; - } - return default_value; -} - -const char *ldb_msg_find_attr_as_string(const struct ldb_message *msg, - const char *attr_name, - const char *default_value) -{ - const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr_name); - if (!v || !v->data) { - return default_value; - } - if (v->data[v->length] != '\0') { - return default_value; - } - return (const char *)v->data; -} - -struct ldb_dn *ldb_msg_find_attr_as_dn(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const struct ldb_message *msg, - const char *attr_name) -{ - struct ldb_dn *res_dn; - const struct ldb_val *v; - - v = ldb_msg_find_ldb_val(msg, attr_name); - if (!v || !v->data) { - return NULL; - } - res_dn = ldb_dn_from_ldb_val(mem_ctx, ldb, v); - if ( ! ldb_dn_validate(res_dn)) { - talloc_free(res_dn); - return NULL; - } - return res_dn; -} - -/* - sort the elements of a message by name -*/ -void ldb_msg_sort_elements(struct ldb_message *msg) -{ - TYPESAFE_QSORT(msg->elements, msg->num_elements, - ldb_msg_element_compare_name); -} - -/* - shallow copy a message - copying only the elements array so that the caller - can safely add new elements without changing the message -*/ -struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx, - const struct ldb_message *msg) -{ - struct ldb_message *msg2; - unsigned int i; - - msg2 = talloc(mem_ctx, struct ldb_message); - if (msg2 == NULL) return NULL; - - *msg2 = *msg; - - msg2->elements = talloc_array(msg2, struct ldb_message_element, - msg2->num_elements); - if (msg2->elements == NULL) goto failed; - - for (i=0;inum_elements;i++) { - msg2->elements[i] = msg->elements[i]; - } - - return msg2; - -failed: - talloc_free(msg2); - return NULL; -} - - -/* - copy a message, allocating new memory for all parts -*/ -struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, - const struct ldb_message *msg) -{ - struct ldb_message *msg2; - unsigned int i, j; - - msg2 = ldb_msg_copy_shallow(mem_ctx, msg); - if (msg2 == NULL) return NULL; - - msg2->dn = ldb_dn_copy(msg2, msg2->dn); - if (msg2->dn == NULL) goto failed; - - for (i=0;inum_elements;i++) { - struct ldb_message_element *el = &msg2->elements[i]; - struct ldb_val *values = el->values; - el->name = talloc_strdup(msg2->elements, el->name); - if (el->name == NULL) goto failed; - el->values = talloc_array(msg2->elements, struct ldb_val, el->num_values); - if (el->values == NULL) goto failed; - for (j=0;jnum_values;j++) { - el->values[j] = ldb_val_dup(el->values, &values[j]); - if (el->values[j].data == NULL && values[j].length != 0) { - goto failed; - } - } - } - - return msg2; - -failed: - talloc_free(msg2); - return NULL; -} - - -/** - * Canonicalize a message, merging elements of the same name - */ -struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, - const struct ldb_message *msg) -{ - int ret; - struct ldb_message *msg2; - - /* - * Preserve previous behavior and allocate - * *msg2 into *ldb context - */ - ret = ldb_msg_normalize(ldb, ldb, msg, &msg2); - if (ret != LDB_SUCCESS) { - return NULL; - } - - return msg2; -} - -/** - * Canonicalize a message, merging elements of the same name - */ -int ldb_msg_normalize(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const struct ldb_message *msg, - struct ldb_message **_msg_out) -{ - unsigned int i; - struct ldb_message *msg2; - - msg2 = ldb_msg_copy(mem_ctx, msg); - if (msg2 == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ldb_msg_sort_elements(msg2); - - for (i=1; i < msg2->num_elements; i++) { - struct ldb_message_element *el1 = &msg2->elements[i-1]; - struct ldb_message_element *el2 = &msg2->elements[i]; - - if (ldb_msg_element_compare_name(el1, el2) == 0) { - el1->values = talloc_realloc(msg2->elements, - el1->values, struct ldb_val, - el1->num_values + el2->num_values); - if (el1->num_values + el2->num_values > 0 && el1->values == NULL) { - talloc_free(msg2); - return LDB_ERR_OPERATIONS_ERROR; - } - memcpy(el1->values + el1->num_values, - el2->values, - sizeof(struct ldb_val) * el2->num_values); - el1->num_values += el2->num_values; - talloc_free(discard_const_p(char, el2->name)); - if ((i+1) < msg2->num_elements) { - memmove(el2, el2+1, sizeof(struct ldb_message_element) * - (msg2->num_elements - (i+1))); - } - msg2->num_elements--; - i--; - } - } - - *_msg_out = msg2; - return LDB_SUCCESS; -} - - -/** - * return a ldb_message representing the differences between msg1 and msg2. - * If you then use this in a ldb_modify() call, - * it can be used to save edits to a message - */ -struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, - struct ldb_message *msg1, - struct ldb_message *msg2) -{ - int ldb_ret; - struct ldb_message *mod; - - ldb_ret = ldb_msg_difference(ldb, ldb, msg1, msg2, &mod); - if (ldb_ret != LDB_SUCCESS) { - return NULL; - } - - return mod; -} - -/** - * return a ldb_message representing the differences between msg1 and msg2. - * If you then use this in a ldb_modify() call it can be used to save edits to a message - * - * Result message is constructed as follows: - * - LDB_FLAG_MOD_ADD - elements found only in msg2 - * - LDB_FLAG_MOD_REPLACE - elements in msg2 that have different value in msg1 - * Value for msg2 element is used - * - LDB_FLAG_MOD_DELETE - elements found only in msg2 - * - * @return LDB_SUCCESS or LDB_ERR_OPERATIONS_ERROR - */ -int ldb_msg_difference(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_message *msg1, - struct ldb_message *msg2, - struct ldb_message **_msg_out) -{ - int ldb_res; - unsigned int i; - struct ldb_message *mod; - struct ldb_message_element *el; - TALLOC_CTX *temp_ctx; - - temp_ctx = talloc_new(mem_ctx); - if (!temp_ctx) { - return LDB_ERR_OPERATIONS_ERROR; - } - - mod = ldb_msg_new(temp_ctx); - if (mod == NULL) { - goto failed; - } - - mod->dn = msg1->dn; - mod->num_elements = 0; - mod->elements = NULL; - - /* - * Canonicalize *msg2 so we have no repeated elements - * Resulting message is allocated in *mod's mem context, - * as we are going to move some elements from *msg2 to - * *mod object later - */ - ldb_res = ldb_msg_normalize(ldb, mod, msg2, &msg2); - if (ldb_res != LDB_SUCCESS) { - goto failed; - } - - /* look in msg2 to find elements that need to be added or modified */ - for (i=0;inum_elements;i++) { - el = ldb_msg_find_element(msg1, msg2->elements[i].name); - - if (el && ldb_msg_element_compare(el, &msg2->elements[i]) == 0) { - continue; - } - - ldb_res = ldb_msg_add(mod, - &msg2->elements[i], - el ? LDB_FLAG_MOD_REPLACE : LDB_FLAG_MOD_ADD); - if (ldb_res != LDB_SUCCESS) { - goto failed; - } - } - - /* look in msg1 to find elements that need to be deleted */ - for (i=0;inum_elements;i++) { - el = ldb_msg_find_element(msg2, msg1->elements[i].name); - if (el == NULL) { - ldb_res = ldb_msg_add_empty(mod, - msg1->elements[i].name, - LDB_FLAG_MOD_DELETE, NULL); - if (ldb_res != LDB_SUCCESS) { - goto failed; - } - } - } - - /* steal resulting message into supplied context */ - talloc_steal(mem_ctx, mod); - *_msg_out = mod; - - talloc_free(temp_ctx); - return LDB_SUCCESS; - -failed: - talloc_free(temp_ctx); - return LDB_ERR_OPERATIONS_ERROR; -} - - -int ldb_msg_sanity_check(struct ldb_context *ldb, - const struct ldb_message *msg) -{ - unsigned int i, j; - - /* basic check on DN */ - if (msg->dn == NULL) { - ldb_set_errstring(ldb, "ldb message lacks a DN!"); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - /* basic syntax checks */ - for (i = 0; i < msg->num_elements; i++) { - for (j = 0; j < msg->elements[i].num_values; j++) { - if (msg->elements[i].values[j].length == 0) { - /* an attribute cannot be empty */ - ldb_asprintf_errstring(ldb, "Element %s has empty attribute in ldb message (%s)!", - msg->elements[i].name, - ldb_dn_get_linearized(msg->dn)); - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - } - } - - return LDB_SUCCESS; -} - - - - -/* - copy an attribute list. This only copies the array, not the elements - (ie. the elements are left as the same pointers) -*/ -const char **ldb_attr_list_copy(TALLOC_CTX *mem_ctx, const char * const *attrs) -{ - const char **ret; - unsigned int i; - - for (i=0;attrs && attrs[i];i++) /* noop */ ; - ret = talloc_array(mem_ctx, const char *, i+1); - if (ret == NULL) { - return NULL; - } - for (i=0;attrs && attrs[i];i++) { - ret[i] = attrs[i]; - } - ret[i] = attrs[i]; - return ret; -} - - -/* - copy an attribute list. This only copies the array, not the elements - (ie. the elements are left as the same pointers). The new attribute is added to the list. -*/ -const char **ldb_attr_list_copy_add(TALLOC_CTX *mem_ctx, const char * const *attrs, const char *new_attr) -{ - const char **ret; - unsigned int i; - bool found = false; - - for (i=0;attrs && attrs[i];i++) { - if (ldb_attr_cmp(attrs[i], new_attr) == 0) { - found = true; - } - } - if (found) { - return ldb_attr_list_copy(mem_ctx, attrs); - } - ret = talloc_array(mem_ctx, const char *, i+2); - if (ret == NULL) { - return NULL; - } - for (i=0;attrs && attrs[i];i++) { - ret[i] = attrs[i]; - } - ret[i] = new_attr; - ret[i+1] = NULL; - return ret; -} - - -/* - return 1 if an attribute is in a list of attributes, or 0 otherwise -*/ -int ldb_attr_in_list(const char * const *attrs, const char *attr) -{ - unsigned int i; - for (i=0;attrs && attrs[i];i++) { - if (ldb_attr_cmp(attrs[i], attr) == 0) { - return 1; - } - } - return 0; -} - - -/* - rename the specified attribute in a search result -*/ -int ldb_msg_rename_attr(struct ldb_message *msg, const char *attr, const char *replace) -{ - struct ldb_message_element *el = ldb_msg_find_element(msg, attr); - if (el == NULL) { - return LDB_SUCCESS; - } - el->name = talloc_strdup(msg->elements, replace); - if (el->name == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - return LDB_SUCCESS; -} - - -/* - copy the specified attribute in a search result to a new attribute -*/ -int ldb_msg_copy_attr(struct ldb_message *msg, const char *attr, const char *replace) -{ - struct ldb_message_element *el = ldb_msg_find_element(msg, attr); - int ret; - - if (el == NULL) { - return LDB_SUCCESS; - } - ret = ldb_msg_add(msg, el, 0); - if (ret != LDB_SUCCESS) { - return ret; - } - return ldb_msg_rename_attr(msg, attr, replace); -} - -/* - remove the specified element in a search result -*/ -void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el) -{ - ptrdiff_t n = (el - msg->elements); - if (n >= msg->num_elements || n < 0) { - /* the element is not in the list. the caller is crazy. */ - return; - } - msg->num_elements--; - if (n != msg->num_elements) { - memmove(el, el+1, (msg->num_elements - n)*sizeof(*el)); - } -} - - -/* - remove the specified attribute in a search result -*/ -void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr) -{ - struct ldb_message_element *el; - - while ((el = ldb_msg_find_element(msg, attr)) != NULL) { - ldb_msg_remove_element(msg, el); - } -} - -/* - return a LDAP formatted GeneralizedTime string -*/ -char *ldb_timestring(TALLOC_CTX *mem_ctx, time_t t) -{ - struct tm *tm = gmtime(&t); - char *ts; - int r; - - if (!tm) { - return NULL; - } - - /* we now excatly how long this string will be */ - ts = talloc_array(mem_ctx, char, 18); - - /* formatted like: 20040408072012.0Z */ - r = snprintf(ts, 18, - "%04u%02u%02u%02u%02u%02u.0Z", - tm->tm_year+1900, tm->tm_mon+1, - tm->tm_mday, tm->tm_hour, tm->tm_min, - tm->tm_sec); - - if (r != 17) { - talloc_free(ts); - return NULL; - } - - return ts; -} - -/* - convert a LDAP GeneralizedTime string to a time_t. Return 0 if unable to convert -*/ -time_t ldb_string_to_time(const char *s) -{ - struct tm tm; - - if (s == NULL) return 0; - - memset(&tm, 0, sizeof(tm)); - if (sscanf(s, "%04u%02u%02u%02u%02u%02u.0Z", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday, - &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { - return 0; - } - tm.tm_year -= 1900; - tm.tm_mon -= 1; - - return timegm(&tm); -} - -/* - convert a LDAP GeneralizedTime string in ldb_val format to a - time_t. -*/ -int ldb_val_to_time(const struct ldb_val *v, time_t *t) -{ - char val[15] = {0}; - struct tm tm = { - .tm_year = 0, - }; - - if (v == NULL) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - - if (v->data == NULL) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - - if (v->length < 16 && v->length != 13) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - - if (v->data[v->length - 1] != 'Z') { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - - if (v->length == 13) { - memcpy(val, v->data, 12); - - if (sscanf(val, "%02u%02u%02u%02u%02u%02u", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday, - &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - if (tm.tm_year < 50) { - tm.tm_year += 100; - } - } else { - - /* - * anything between '.' and 'Z' is silently ignored. - */ - if (v->data[14] != '.') { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - - memcpy(val, v->data, 14); - - if (sscanf(val, "%04u%02u%02u%02u%02u%02u", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday, - &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - tm.tm_year -= 1900; - } - tm.tm_mon -= 1; - - *t = timegm(&tm); - - return LDB_SUCCESS; -} - -/* - return a LDAP formatted UTCTime string -*/ -char *ldb_timestring_utc(TALLOC_CTX *mem_ctx, time_t t) -{ - struct tm *tm = gmtime(&t); - char *ts; - int r; - - if (!tm) { - return NULL; - } - - /* we now excatly how long this string will be */ - ts = talloc_array(mem_ctx, char, 14); - - /* formatted like: 20040408072012.0Z => 040408072012Z */ - r = snprintf(ts, 14, - "%02u%02u%02u%02u%02u%02uZ", - (tm->tm_year+1900)%100, tm->tm_mon+1, - tm->tm_mday, tm->tm_hour, tm->tm_min, - tm->tm_sec); - - if (r != 13) { - talloc_free(ts); - return NULL; - } - - return ts; -} - -/* - convert a LDAP UTCTime string to a time_t. Return 0 if unable to convert -*/ -time_t ldb_string_utc_to_time(const char *s) -{ - struct tm tm; - - if (s == NULL) return 0; - - memset(&tm, 0, sizeof(tm)); - if (sscanf(s, "%02u%02u%02u%02u%02u%02uZ", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday, - &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { - return 0; - } - if (tm.tm_year < 50) { - tm.tm_year += 100; - } - tm.tm_mon -= 1; - - return timegm(&tm); -} - - -/* - dump a set of results to a file. Useful from within gdb -*/ -void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *f) -{ - unsigned int i; - - for (i = 0; i < result->count; i++) { - struct ldb_ldif ldif; - fprintf(f, "# record %d\n", i+1); - ldif.changetype = LDB_CHANGETYPE_NONE; - ldif.msg = result->msgs[i]; - ldb_ldif_write_file(ldb, f, &ldif); - } -} - -/* - checks for a string attribute. Returns "1" on match and otherwise "0". -*/ -int ldb_msg_check_string_attribute(const struct ldb_message *msg, - const char *name, const char *value) -{ - struct ldb_message_element *el; - struct ldb_val val; - - el = ldb_msg_find_element(msg, name); - if (el == NULL) { - return 0; - } - - val.data = discard_const_p(uint8_t, value); - val.length = strlen(value); - - if (ldb_msg_find_val(el, &val)) { - return 1; - } - - return 0; -} - - -/* - compare a ldb_val to a string -*/ -int ldb_val_string_cmp(const struct ldb_val *v, const char *str) -{ - size_t len = strlen(str); - if (len != v->length) { - return len - v->length; - } - return strncmp((const char *)v->data, str, len); -} diff --git a/ldb-2.0.8/common/ldb_options.c b/ldb-2.0.8/common/ldb_options.c deleted file mode 100644 index ee8c728..0000000 --- a/ldb-2.0.8/common/ldb_options.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2010 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb options[] handling - * - * Author: Andrew Tridgell - */ - -#include "ldb_private.h" - -/* - find an option within an options array - - accepts the following forms: - - NAME - NAME:value - NAME=value - - returns a pointer into an element of the options[] array, or NULL is - not found. - - For the NAME form, returns a pointer to an empty string (thus - allowing for boolean options). - */ -const char *ldb_options_find(struct ldb_context *ldb, const char *options[], - const char *option_name) -{ - size_t len = strlen(option_name); - int i; - - if (options == NULL) { - return NULL; - } - - for (i=0; options[i]; i++) { - if (strncmp(option_name, options[i], len) != 0) { - continue; - } - if (options[i][len] == ':' || options[i][len] == '=') { - return &options[i][len+1]; - } - if (options[i][len] == 0) { - return &options[i][len]; - } - } - - return NULL; -} - -const char **ldb_options_copy(TALLOC_CTX *ctx, const char *options[]) -{ - - size_t num_options = 0; - const char **copy = NULL; - size_t i = 0; - - if (options == NULL) { - return copy; - } - - for (i=0; options[i]; i++) { - num_options++; - } - - copy = talloc_zero_array(ctx, const char *, num_options + 1); - if (copy == NULL) { - return copy; - } - - for (i=0; options[i]; i++) { - copy[i] = talloc_strdup(copy, options[i]); - if (copy[i] == NULL) { - TALLOC_FREE(copy); - return copy; - } - } - return copy; -} - -const char **ldb_options_get(struct ldb_context *ldb) -{ - return ldb->options; -} diff --git a/ldb-2.0.8/common/ldb_pack.c b/ldb-2.0.8/common/ldb_pack.c deleted file mode 100644 index e7dd364..0000000 --- a/ldb-2.0.8/common/ldb_pack.c +++ /dev/null @@ -1,1261 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb pack/unpack - * - * Description: pack/unpack routines for ldb messages as key/value blobs - * - * Author: Andrew Tridgell - */ - -#include "ldb_private.h" - -/* - * These macros are from byte_array.h via libssh - * TODO: This will be replaced with use of the byte_array.h header when it - * becomes available. - * - * Macros for handling integer types in byte arrays - * - * This file is originally from the libssh.org project - * - * Copyright (c) 2018 Andreas Schneider - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#define _DATA_BYTE_CONST(data, pos) \ - ((uint8_t)(((const uint8_t *)(data))[(pos)])) -#define PULL_LE_U8(data, pos) \ - (_DATA_BYTE_CONST(data, pos)) -#define PULL_LE_U16(data, pos) \ - ((uint16_t)PULL_LE_U8(data, pos) |\ - ((uint16_t)(PULL_LE_U8(data, (pos) + 1))) << 8) -#define PULL_LE_U32(data, pos) \ - ((uint32_t)(PULL_LE_U16(data, pos) |\ - ((uint32_t)PULL_LE_U16(data, (pos) + 2)) << 16)) - -#define _DATA_BYTE(data, pos) \ - (((uint8_t *)(data))[(pos)]) -#define PUSH_LE_U8(data, pos, val) \ - (_DATA_BYTE(data, pos) = ((uint8_t)(val))) -#define PUSH_LE_U16(data, pos, val) \ - (PUSH_LE_U8((data), (pos), (uint8_t)((uint16_t)(val) & 0xff)),\ - PUSH_LE_U8((data), (pos) + 1,\ - (uint8_t)((uint16_t)(val) >> 8))) -#define PUSH_LE_U32(data, pos, val) \ - (PUSH_LE_U16((data), (pos), (uint16_t)((uint32_t)(val) & 0xffff)),\ - PUSH_LE_U16((data), (pos) + 2, (uint16_t)((uint32_t)(val) >> 16))) - -#define U32_LEN 4 -#define U16_LEN 2 -#define U8_LEN 1 -#define NULL_PAD_BYTE_LEN 1 - -static int attribute_storable_values(const struct ldb_message_element *el) -{ - if (el->num_values == 0) return 0; - - if (ldb_attr_cmp(el->name, "distinguishedName") == 0) return 0; - - return el->num_values; -} - -static int ldb_pack_data_v1(struct ldb_context *ldb, - const struct ldb_message *message, - struct ldb_val *data) -{ - unsigned int i, j, real_elements=0; - size_t size, dn_len, attr_len, value_len; - const char *dn; - uint8_t *p; - size_t len; - - dn = ldb_dn_get_linearized(message->dn); - if (dn == NULL) { - errno = ENOMEM; - return -1; - } - - /* work out how big it needs to be */ - size = U32_LEN * 2 + NULL_PAD_BYTE_LEN; - - dn_len = strlen(dn); - if (size + dn_len < size) { - errno = ENOMEM; - return -1; - } - size += dn_len; - - /* - * First calcuate the buffer size we need, and check for - * overflows - */ - for (i=0;inum_elements;i++) { - if (attribute_storable_values(&message->elements[i]) == 0) { - continue; - } - - real_elements++; - - if (size + U32_LEN + NULL_PAD_BYTE_LEN < size) { - errno = ENOMEM; - return -1; - } - size += U32_LEN + NULL_PAD_BYTE_LEN; - - attr_len = strlen(message->elements[i].name); - if (size + attr_len < size) { - errno = ENOMEM; - return -1; - } - size += attr_len; - - for (j=0;jelements[i].num_values;j++) { - if (size + U32_LEN + NULL_PAD_BYTE_LEN < size) { - errno = ENOMEM; - return -1; - } - size += U32_LEN + NULL_PAD_BYTE_LEN; - - value_len = message->elements[i].values[j].length; - if (size + value_len < size) { - errno = ENOMEM; - return -1; - } - size += value_len; - } - } - - /* allocate it */ - data->data = talloc_array(ldb, uint8_t, size); - if (!data->data) { - errno = ENOMEM; - return -1; - } - data->length = size; - - p = data->data; - PUSH_LE_U32(p, 0, LDB_PACKING_FORMAT); - p += U32_LEN; - PUSH_LE_U32(p, 0, real_elements); - p += U32_LEN; - - /* the dn needs to be packed so we can be case preserving - while hashing on a case folded dn */ - len = dn_len; - memcpy(p, dn, len+NULL_PAD_BYTE_LEN); - p += len + NULL_PAD_BYTE_LEN; - - for (i=0;inum_elements;i++) { - if (attribute_storable_values(&message->elements[i]) == 0) { - continue; - } - len = strlen(message->elements[i].name); - memcpy(p, message->elements[i].name, len+NULL_PAD_BYTE_LEN); - p += len + NULL_PAD_BYTE_LEN; - PUSH_LE_U32(p, 0, message->elements[i].num_values); - p += U32_LEN; - for (j=0;jelements[i].num_values;j++) { - PUSH_LE_U32(p, 0, - message->elements[i].values[j].length); - p += U32_LEN; - memcpy(p, message->elements[i].values[j].data, - message->elements[i].values[j].length); - p[message->elements[i].values[j].length] = 0; - p += message->elements[i].values[j].length + - NULL_PAD_BYTE_LEN; - } - } - - return 0; -} - -/* - * New pack version designed based on performance profiling of version 1. - * The approach is to separate value data from the rest of the record's data. - * This improves performance because value data is not needed during unpacking - * or filtering of the message's attribute list. During filtering we only copy - * attributes which are present in the attribute list, however at the parse - * stage we need to point to all attributes as they may be referenced in the - * search expression. - * With this new format, we don't lose time loading data (eg via - * talloc_memdup()) that is never needed (for the vast majority of attributes - * are are never found in either the search expression or attribute list). - * Additional changes include adding a canonicalized DN (for later - * optimizations) and variable width length fields for faster unpacking. - * The pack and unpack performance improvement is tested in the torture - * test torture_ldb_pack_format_perf. - * - * Layout: - * - * Version (4 bytes) - * Number of Elements (4 bytes) - * DN length (4 bytes) - * DN with null terminator (DN length + 1 bytes) - * Canonicalized DN length (4 bytes) - * Canonicalized DN with null terminator (Canonicalized DN length + 1 bytes) - * Number of bytes from here to value data section (4 bytes) - * # For each element: - * Element name length (4 bytes) - * Element name with null terminator (Element name length + 1 bytes) - * Number of values (4 bytes) - * Width of value lengths - * # For each value: - * Value data length (#bytes given by width field above) - * # For each element: - * # For each value: - * Value data (#bytes given by corresponding length above) - */ -static int ldb_pack_data_v2(struct ldb_context *ldb, - const struct ldb_message *message, - struct ldb_val *data) -{ - unsigned int i, j, real_elements=0; - size_t size, dn_len, dn_canon_len, attr_len, value_len; - const char *dn, *dn_canon; - uint8_t *p, *q; - size_t len; - size_t max_val_len; - uint8_t val_len_width; - - /* - * First half of this function will calculate required size for - * packed data. Initial size is 20 = 5 * 4. 5 fixed fields are: - * version, num elements, dn len, canon dn len, attr section len - */ - size = U32_LEN * 5; - - /* - * Get linearized and canonicalized form of the DN and add the lengths - * of each to size, plus 1 for null terminator. - */ - dn = ldb_dn_get_linearized(message->dn); - if (dn == NULL) { - errno = ENOMEM; - return -1; - } - - dn_len = strlen(dn) + NULL_PAD_BYTE_LEN; - if (size + dn_len < size) { - errno = ENOMEM; - return -1; - } - size += dn_len; - - if (ldb_dn_is_special(message->dn)) { - dn_canon_len = NULL_PAD_BYTE_LEN; - dn_canon = discard_const_p(char, "\0"); - } else { - dn_canon = ldb_dn_canonical_string(message->dn, message->dn); - if (dn_canon == NULL) { - errno = ENOMEM; - return -1; - } - - dn_canon_len = strlen(dn_canon) + NULL_PAD_BYTE_LEN; - if (size + dn_canon_len < size) { - errno = ENOMEM; - return -1; - } - } - size += dn_canon_len; - - /* Add the size required by each element */ - for (i=0;inum_elements;i++) { - if (attribute_storable_values(&message->elements[i]) == 0) { - continue; - } - - real_elements++; - - /* - * Add length of element name + 9 for: - * 1 for null terminator - * 4 for element name length field - * 4 for number of values field - */ - attr_len = strlen(message->elements[i].name); - if (size + attr_len + U32_LEN * 2 + NULL_PAD_BYTE_LEN < size) { - errno = ENOMEM; - return -1; - } - size += attr_len + U32_LEN * 2 + NULL_PAD_BYTE_LEN; - - /* - * Find the max value length, so we can calculate the width - * required for the value length fields. - */ - max_val_len = 0; - for (j=0;jelements[i].num_values;j++) { - value_len = message->elements[i].values[j].length; - if (value_len > max_val_len) { - max_val_len = value_len; - } - - if (size + value_len + NULL_PAD_BYTE_LEN < size) { - errno = ENOMEM; - return -1; - } - size += value_len + NULL_PAD_BYTE_LEN; - } - - if (max_val_len <= UCHAR_MAX) { - val_len_width = U8_LEN; - } else if (max_val_len <= USHRT_MAX) { - val_len_width = U16_LEN; - } else if (max_val_len <= UINT_MAX) { - val_len_width = U32_LEN; - } else { - errno = EMSGSIZE; - return -1; - } - - /* Total size required for val lengths (re-using variable) */ - max_val_len = (val_len_width*message->elements[i].num_values); - - /* Add one for storing the width */ - max_val_len += U8_LEN; - if (size + max_val_len < size) { - errno = ENOMEM; - return -1; - } - size += max_val_len; - } - - /* Allocate */ - data->data = talloc_array(ldb, uint8_t, size); - if (!data->data) { - errno = ENOMEM; - return -1; - } - data->length = size; - - /* Packing format version and number of element */ - p = data->data; - PUSH_LE_U32(p, 0, LDB_PACKING_FORMAT_V2); - p += U32_LEN; - PUSH_LE_U32(p, 0, real_elements); - p += U32_LEN; - - /* Pack DN and Canonicalized DN */ - PUSH_LE_U32(p, 0, dn_len-NULL_PAD_BYTE_LEN); - p += U32_LEN; - memcpy(p, dn, dn_len); - p += dn_len; - - PUSH_LE_U32(p, 0, dn_canon_len-NULL_PAD_BYTE_LEN); - p += U32_LEN; - memcpy(p, dn_canon, dn_canon_len); - p += dn_canon_len; - - /* - * Save pointer at this point and leave a U32_LEN gap for - * storing the size of the attribute names and value lengths - * section - */ - q = p; - p += U32_LEN; - - for (i=0;inum_elements;i++) { - if (attribute_storable_values(&message->elements[i]) == 0) { - continue; - } - - /* Length of el name */ - len = strlen(message->elements[i].name); - PUSH_LE_U32(p, 0, len); - p += U32_LEN; - - /* - * Even though we have the element name's length, put a null - * terminator at the end so if any code uses the name - * directly, it'll be safe to do things requiring null - * termination like strlen - */ - memcpy(p, message->elements[i].name, len+NULL_PAD_BYTE_LEN); - p += len + NULL_PAD_BYTE_LEN; - /* Num values */ - PUSH_LE_U32(p, 0, message->elements[i].num_values); - p += U32_LEN; - - /* - * Calculate value length width again. It's faster to - * calculate it again than do the array management to - * store the result during size calculation. - */ - max_val_len = 0; - for (j=0;jelements[i].num_values;j++) { - value_len = message->elements[i].values[j].length; - if (value_len > max_val_len) { - max_val_len = value_len; - } - } - - if (max_val_len <= UCHAR_MAX) { - val_len_width = U8_LEN; - } else if (max_val_len <= USHRT_MAX) { - val_len_width = U16_LEN; - } else if (max_val_len <= UINT_MAX) { - val_len_width = U32_LEN; - } else { - errno = EMSGSIZE; - return -1; - } - - /* Pack the width */ - *p = val_len_width & 0xFF; - p += U8_LEN; - - /* - * Pack each value's length using the minimum number of bytes - * required, which we just calculated. We repeat the loop - * for each case here so the compiler can inline code. - */ - if (val_len_width == U8_LEN) { - for (j=0;jelements[i].num_values;j++) { - PUSH_LE_U8(p, 0, - message->elements[i].values[j].length); - p += U8_LEN; - } - } else if (val_len_width == U16_LEN) { - for (j=0;jelements[i].num_values;j++) { - PUSH_LE_U16(p, 0, - message->elements[i].values[j].length); - p += U16_LEN; - } - } else if (val_len_width == U32_LEN) { - for (j=0;jelements[i].num_values;j++) { - PUSH_LE_U32(p, 0, - message->elements[i].values[j].length); - p += U32_LEN; - } - } - } - - /* - * We've finished packing the attr names and value lengths - * section, so store the size in the U32_LEN gap we left - * earlier - */ - PUSH_LE_U32(q, 0, p-q); - - /* Now pack the values */ - for (i=0;inum_elements;i++) { - if (attribute_storable_values(&message->elements[i]) == 0) { - continue; - } - for (j=0;jelements[i].num_values;j++) { - memcpy(p, message->elements[i].values[j].data, - message->elements[i].values[j].length); - - /* - * Even though we have the data length, put a null - * terminator at the end of each value's data so if - * any code uses the data directly, it'll be safe to - * do things requiring null termination like strlen. - */ - p[message->elements[i].values[j].length] = 0; - p += message->elements[i].values[j].length + - NULL_PAD_BYTE_LEN; - } - } - - /* - * If we didn't end up at the end of the data here, something has - * gone very wrong. - */ - if (p != data->data + size) { - errno = ENOMEM; - return -1; - } - - return 0; -} - -/* - pack a ldb message into a linear buffer in a ldb_val - - note that this routine avoids saving elements with zero values, - as these are equivalent to having no element - - caller frees the data buffer after use -*/ -int ldb_pack_data(struct ldb_context *ldb, - const struct ldb_message *message, - struct ldb_val *data, - uint32_t pack_format_version) { - - if (pack_format_version == LDB_PACKING_FORMAT) { - return ldb_pack_data_v1(ldb, message, data); - } else if (pack_format_version == LDB_PACKING_FORMAT_V2) { - return ldb_pack_data_v2(ldb, message, data); - } else { - errno = EINVAL; - return -1; - } -} - -/* - * Unpack a ldb message from a linear buffer in ldb_val - */ -static int ldb_unpack_data_flags_v1(struct ldb_context *ldb, - const struct ldb_val *data, - struct ldb_message *message, - unsigned int flags, - unsigned format) -{ - uint8_t *p; - size_t remaining; - size_t dn_len; - unsigned int i, j; - unsigned int nelem = 0; - size_t len; - struct ldb_val *ldb_val_single_array = NULL; - - message->elements = NULL; - - p = data->data; - - /* Format (U32, already read) + U32 for num_elements */ - if (data->length < U32_LEN * 2) { - errno = EIO; - goto failed; - } - - /* Skip first 4 bytes, format already read */ - p += U32_LEN; - message->num_elements = PULL_LE_U32(p, 0); - p += U32_LEN; - - remaining = data->length - U32_LEN * 2; - - switch (format) { - case LDB_PACKING_FORMAT_NODN: - message->dn = NULL; - break; - - case LDB_PACKING_FORMAT: - /* - * With this check, we know that the DN at p is \0 - * terminated. - */ - dn_len = strnlen((char *)p, remaining); - if (dn_len == remaining) { - errno = EIO; - goto failed; - } - if (flags & LDB_UNPACK_DATA_FLAG_NO_DN) { - message->dn = NULL; - } else { - struct ldb_val blob; - blob.data = discard_const_p(uint8_t, p); - blob.length = dn_len; - message->dn = ldb_dn_from_ldb_val(message, ldb, &blob); - if (message->dn == NULL) { - errno = ENOMEM; - goto failed; - } - } - /* - * Redundant: by definition, remaining must be more - * than one less than dn_len, as otherwise it would be - * == dn_len - */ - if (remaining < dn_len + NULL_PAD_BYTE_LEN) { - errno = EIO; - goto failed; - } - remaining -= dn_len + NULL_PAD_BYTE_LEN; - p += dn_len + NULL_PAD_BYTE_LEN; - break; - - default: - errno = EIO; - goto failed; - } - - if (flags & LDB_UNPACK_DATA_FLAG_NO_ATTRS) { - return 0; - } - - if (message->num_elements == 0) { - return 0; - } - - if (message->num_elements > remaining / 6) { - errno = EIO; - goto failed; - } - - message->elements = talloc_zero_array(message, struct ldb_message_element, - message->num_elements); - if (!message->elements) { - errno = ENOMEM; - goto failed; - } - - /* - * In typical use, most values are single-valued. This makes - * it quite expensive to allocate an array of ldb_val for each - * of these, just to then hold the pointer to the data buffer - * So with LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC we allocate this - * ahead of time and use it for the single values where possible. - * (This is used the the normal search case, but not in the - * index case because of caller requirements). - */ - if (flags & LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC) { - ldb_val_single_array = talloc_array(message->elements, struct ldb_val, - message->num_elements); - if (ldb_val_single_array == NULL) { - errno = ENOMEM; - goto failed; - } - } - - for (i=0;inum_elements;i++) { - const char *attr = NULL; - size_t attr_len; - struct ldb_message_element *element = NULL; - - /* - * Sanity check: Element must be at least the size of empty - * attr name and value and NULL terms for each. - */ - if (remaining < U32_LEN * 2 + NULL_PAD_BYTE_LEN * 2) { - errno = EIO; - goto failed; - } - - /* - * With this check, we know that the attribute name at - * p is \0 terminated. - */ - attr_len = strnlen((char *)p, remaining-6); - if (attr_len == remaining-6) { - errno = EIO; - goto failed; - } - if (attr_len == 0) { - errno = EIO; - goto failed; - } - attr = (char *)p; - - element = &message->elements[nelem]; - element->name = attr; - element->flags = 0; - - if (remaining < (attr_len + NULL_PAD_BYTE_LEN)) { - errno = EIO; - goto failed; - } - remaining -= attr_len + NULL_PAD_BYTE_LEN; - p += attr_len + NULL_PAD_BYTE_LEN; - element->num_values = PULL_LE_U32(p, 0); - element->values = NULL; - if ((flags & LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC) && element->num_values == 1) { - element->values = &ldb_val_single_array[nelem]; - } else if (element->num_values != 0) { - element->values = talloc_array(message->elements, - struct ldb_val, - element->num_values); - if (!element->values) { - errno = ENOMEM; - goto failed; - } - } - p += U32_LEN; - if (remaining < U32_LEN) { - errno = EIO; - goto failed; - } - remaining -= U32_LEN; - for (j = 0; j < element->num_values; j++) { - /* - * Sanity check: Value must be at least the size of - * empty val and NULL terminator. - */ - if (remaining < U32_LEN + NULL_PAD_BYTE_LEN) { - errno = EIO; - goto failed; - } - remaining -= U32_LEN + NULL_PAD_BYTE_LEN; - - len = PULL_LE_U32(p, 0); - if (remaining < len) { - errno = EIO; - goto failed; - } - if (len + NULL_PAD_BYTE_LEN < len) { - errno = EIO; - goto failed; - } - - element->values[j].length = len; - element->values[j].data = p + U32_LEN; - remaining -= len; - p += len + U32_LEN + NULL_PAD_BYTE_LEN; - } - nelem++; - } - /* - * Adapt the number of elements to the real number of unpacked elements, - * it means that we overallocated elements array. - */ - message->num_elements = nelem; - - /* - * Shrink the allocated size. On current talloc behaviour - * this will help if we skipped 32 or more attributes. - */ - message->elements = talloc_realloc(message, message->elements, - struct ldb_message_element, - message->num_elements); - - if (remaining != 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: %zu bytes unread in ldb_unpack_data_flags", - remaining); - } - - return 0; - -failed: - talloc_free(message->elements); - return -1; -} - -/* - * Unpack a ldb message from a linear buffer in ldb_val - */ -static int ldb_unpack_data_flags_v2(struct ldb_context *ldb, - const struct ldb_val *data, - struct ldb_message *message, - unsigned int flags) -{ - uint8_t *p, *q, *end_p, *value_section_p; - unsigned int i, j; - unsigned int nelem = 0; - size_t len; - struct ldb_val *ldb_val_single_array = NULL; - uint8_t val_len_width; - - message->elements = NULL; - - p = data->data; - end_p = p + data->length; - - /* Skip first 4 bytes, format already read */ - p += U32_LEN; - - /* First fields are fixed: num_elements, DN length */ - if (p + U32_LEN * 2 > end_p) { - errno = EIO; - goto failed; - } - - message->num_elements = PULL_LE_U32(p, 0); - p += U32_LEN; - - len = PULL_LE_U32(p, 0); - p += U32_LEN; - - if (p + len + NULL_PAD_BYTE_LEN > end_p) { - errno = EIO; - goto failed; - } - - if (flags & LDB_UNPACK_DATA_FLAG_NO_DN) { - message->dn = NULL; - } else { - struct ldb_val blob; - blob.data = discard_const_p(uint8_t, p); - blob.length = len; - message->dn = ldb_dn_from_ldb_val(message, ldb, &blob); - if (message->dn == NULL) { - errno = ENOMEM; - goto failed; - } - } - - p += len + NULL_PAD_BYTE_LEN; - - if (*(p-NULL_PAD_BYTE_LEN) != '\0') { - errno = EINVAL; - goto failed; - } - - /* Now skip the canonicalized DN and its length */ - len = PULL_LE_U32(p, 0) + NULL_PAD_BYTE_LEN; - p += U32_LEN; - - if (p + len > end_p) { - errno = EIO; - goto failed; - } - - p += len; - - if (*(p-NULL_PAD_BYTE_LEN) != '\0') { - errno = EINVAL; - goto failed; - } - - if (flags & LDB_UNPACK_DATA_FLAG_NO_ATTRS) { - return 0; - } - - if (message->num_elements == 0) { - return 0; - } - - /* - * Sanity check (17 bytes is the minimum element size) - */ - if (message->num_elements > (end_p - p) / 17) { - errno = EIO; - goto failed; - } - - message->elements = talloc_zero_array(message, - struct ldb_message_element, - message->num_elements); - if (!message->elements) { - errno = ENOMEM; - goto failed; - } - - /* - * In typical use, most values are single-valued. This makes - * it quite expensive to allocate an array of ldb_val for each - * of these, just to then hold the pointer to the data buffer. - * So with LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC we allocate this - * ahead of time and use it for the single values where possible. - * (This is used the the normal search case, but not in the - * index case because of caller requirements). - */ - if (flags & LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC) { - ldb_val_single_array = talloc_array(message->elements, - struct ldb_val, - message->num_elements); - if (ldb_val_single_array == NULL) { - errno = ENOMEM; - goto failed; - } - } - - q = p + PULL_LE_U32(p, 0); - value_section_p = q; - p += U32_LEN; - - for (i=0;inum_elements;i++) { - const char *attr = NULL; - size_t attr_len; - struct ldb_message_element *element = NULL; - - /* Sanity check: minimum element size */ - if (p + (U32_LEN * 2) + /* attr name len, num values */ - (U8_LEN * 2) + /* value length width, one val length */ - (NULL_PAD_BYTE_LEN * 2) /* null for attr name + val */ - > value_section_p) { - errno = EIO; - goto failed; - } - - attr_len = PULL_LE_U32(p, 0); - p += U32_LEN; - - if (attr_len == 0) { - errno = EIO; - goto failed; - } - attr = (char *)p; - - p += attr_len + NULL_PAD_BYTE_LEN; - /* - * num_values, val_len_width - * - * val_len_width is the width specifier - * for the variable length encoding - */ - if (p + U32_LEN + U8_LEN > value_section_p) { - errno = EIO; - goto failed; - } - - if (*(p-NULL_PAD_BYTE_LEN) != '\0') { - errno = EINVAL; - goto failed; - } - - element = &message->elements[nelem]; - element->name = attr; - element->flags = 0; - - element->num_values = PULL_LE_U32(p, 0); - element->values = NULL; - if ((flags & LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC) && - element->num_values == 1) { - element->values = &ldb_val_single_array[nelem]; - } else if (element->num_values != 0) { - element->values = talloc_array(message->elements, - struct ldb_val, - element->num_values); - if (!element->values) { - errno = ENOMEM; - goto failed; - } - } - - p += U32_LEN; - - /* - * Here we read how wide the remaining lengths are - * which avoids storing and parsing a lot of leading - * 0s - */ - val_len_width = *p; - p += U8_LEN; - - if (p + val_len_width * element->num_values > - value_section_p) { - errno = EIO; - goto failed; - } - - /* - * This is structured weird for compiler optimization - * purposes, but we need to pull the array of widths - * with different macros depending on how wide the - * biggest one is (specified by val_len_width) - */ - if (val_len_width == U8_LEN) { - for (j = 0; j < element->num_values; j++) { - element->values[j].length = PULL_LE_U8(p, 0); - p += U8_LEN; - } - } else if (val_len_width == U16_LEN) { - for (j = 0; j < element->num_values; j++) { - element->values[j].length = PULL_LE_U16(p, 0); - p += U16_LEN; - } - } else if (val_len_width == U32_LEN) { - for (j = 0; j < element->num_values; j++) { - element->values[j].length = PULL_LE_U32(p, 0); - p += U32_LEN; - } - } else { - errno = ERANGE; - goto failed; - } - - for (j = 0; j < element->num_values; j++) { - len = element->values[j].length; - if (len + NULL_PAD_BYTE_LEN < len) { - errno = EIO; - goto failed; - } - if (q + len + NULL_PAD_BYTE_LEN > end_p) { - errno = EIO; - goto failed; - } - - element->values[j].data = q; - q += len + NULL_PAD_BYTE_LEN; - } - nelem++; - } - - /* - * If p isn't now pointing at the beginning of the value section, - * something went very wrong. - */ - if (p != value_section_p) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: Data corruption in ldb_unpack_data_flags"); - errno = EIO; - goto failed; - } - - /* - * Adapt the number of elements to the real number of unpacked - * elements it means that we overallocated elements array. - */ - message->num_elements = nelem; - - /* - * Shrink the allocated size. On current talloc behaviour - * this will help if we skipped 32 or more attributes. - */ - message->elements = talloc_realloc(message, message->elements, - struct ldb_message_element, - message->num_elements); - - if (q != end_p) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Error: %zu bytes unread in ldb_unpack_data_flags", - end_p - q); - errno = EIO; - goto failed; - } - - return 0; - -failed: - talloc_free(message->elements); - return -1; -} - -int ldb_unpack_get_format(const struct ldb_val *data, - uint32_t *pack_format_version) -{ - if (data->length < U32_LEN) { - return LDB_ERR_OPERATIONS_ERROR; - } - *pack_format_version = PULL_LE_U32(data->data, 0); - return LDB_SUCCESS; -} - -/* - * Unpack a ldb message from a linear buffer in ldb_val - */ -int ldb_unpack_data_flags(struct ldb_context *ldb, - const struct ldb_val *data, - struct ldb_message *message, - unsigned int flags) -{ - unsigned format; - - if (data->length < U32_LEN) { - errno = EIO; - return -1; - } - - format = PULL_LE_U32(data->data, 0); - if (format == LDB_PACKING_FORMAT_V2) { - return ldb_unpack_data_flags_v2(ldb, data, message, flags); - } - - /* - * The v1 function we're about to call takes either LDB_PACKING_FORMAT - * or LDB_PACKING_FORMAT_NODN packing format versions, and will error - * if given some other version, so we don't need to do any further - * checks on 'format'. - */ - return ldb_unpack_data_flags_v1(ldb, data, message, flags, format); -} - - -/* - * Unpack a ldb message from a linear buffer in ldb_val - * - * Free with ldb_unpack_data_free() - */ -int ldb_unpack_data(struct ldb_context *ldb, - const struct ldb_val *data, - struct ldb_message *message) -{ - return ldb_unpack_data_flags(ldb, data, message, 0); -} - -/* - add the special distinguishedName element -*/ -static int msg_add_distinguished_name(struct ldb_message *msg) -{ - const char *dn_attr = "distinguishedName"; - char *dn = NULL; - - if (ldb_msg_find_element(msg, dn_attr)) { - /* - * This should not happen, but this is - * existing behaviour... - */ - return LDB_SUCCESS; - } - - dn = ldb_dn_alloc_linearized(msg, msg->dn); - if (dn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_msg_add_steal_string(msg, dn_attr, dn); -} - -/* - * filter the specified list of attributes from msg, - * adding requested attributes, and perhaps all for *, - * but not the DN to filtered_msg. - */ -int ldb_filter_attrs(struct ldb_context *ldb, - const struct ldb_message *msg, - const char *const *attrs, - struct ldb_message *filtered_msg) -{ - unsigned int i; - bool keep_all = false; - bool add_dn = false; - uint32_t num_elements; - uint32_t elements_size; - - if (attrs) { - /* check for special attrs */ - for (i = 0; attrs[i]; i++) { - int cmp = strcmp(attrs[i], "*"); - if (cmp == 0) { - keep_all = true; - break; - } - cmp = ldb_attr_cmp(attrs[i], "distinguishedName"); - if (cmp == 0) { - add_dn = true; - } - } - } else { - keep_all = true; - } - - if (keep_all) { - add_dn = true; - elements_size = msg->num_elements + 1; - - /* Shortcuts for the simple cases */ - } else if (add_dn && i == 1) { - if (msg_add_distinguished_name(filtered_msg) != 0) { - goto failed; - } - return 0; - } else if (i == 0) { - return 0; - - /* - * Otherwise we are copying at most as many elements as we - * have attributes - */ - } else { - elements_size = i; - } - - filtered_msg->elements = talloc_array(filtered_msg, - struct ldb_message_element, - elements_size); - if (filtered_msg->elements == NULL) goto failed; - - num_elements = 0; - - for (i = 0; i < msg->num_elements; i++) { - struct ldb_message_element *el = &msg->elements[i]; - - /* - * el2 is assigned after the Pigeonhole principle - * check below for clarity - */ - struct ldb_message_element *el2 = NULL; - unsigned int j; - - if (keep_all == false) { - bool found = false; - for (j = 0; attrs[j]; j++) { - int cmp = ldb_attr_cmp(el->name, attrs[j]); - if (cmp == 0) { - found = true; - break; - } - } - if (found == false) { - continue; - } - } - - /* - * Pigeonhole principle: we can't have more elements - * than the number of attributes if they are unique in - * the DB. - */ - if (num_elements >= elements_size) { - goto failed; - } - - el2 = &filtered_msg->elements[num_elements]; - - *el2 = *el; - el2->name = talloc_strdup(filtered_msg->elements, - el->name); - if (el2->name == NULL) { - goto failed; - } - el2->values = talloc_array(filtered_msg->elements, - struct ldb_val, el->num_values); - if (el2->values == NULL) { - goto failed; - } - for (j=0;jnum_values;j++) { - el2->values[j] = ldb_val_dup(el2->values, &el->values[j]); - if (el2->values[j].data == NULL && el->values[j].length != 0) { - goto failed; - } - } - num_elements++; - } - - filtered_msg->num_elements = num_elements; - - if (add_dn) { - if (msg_add_distinguished_name(filtered_msg) != 0) { - goto failed; - } - } - - if (filtered_msg->num_elements > 0) { - filtered_msg->elements - = talloc_realloc(filtered_msg, - filtered_msg->elements, - struct ldb_message_element, - filtered_msg->num_elements); - if (filtered_msg->elements == NULL) { - goto failed; - } - } else { - TALLOC_FREE(filtered_msg->elements); - } - - return 0; -failed: - TALLOC_FREE(filtered_msg->elements); - return -1; -} diff --git a/ldb-2.0.8/common/ldb_parse.c b/ldb-2.0.8/common/ldb_parse.c deleted file mode 100644 index 452c583..0000000 --- a/ldb-2.0.8/common/ldb_parse.c +++ /dev/null @@ -1,974 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb expression parsing - * - * Description: parse LDAP-like search expressions - * - * Author: Andrew Tridgell - */ - -/* - TODO: - - add RFC2254 binary string handling - - possibly add ~=, <= and >= handling - - expand the test suite - - add better parse error handling - -*/ - -#include "ldb_private.h" -#include "system/locale.h" - -static int ldb_parse_hex2char(const char *x) -{ - if (isxdigit(x[0]) && isxdigit(x[1])) { - const char h1 = x[0], h2 = x[1]; - int c = 0; - - if (h1 >= 'a') c = h1 - (int)'a' + 10; - else if (h1 >= 'A') c = h1 - (int)'A' + 10; - else if (h1 >= '0') c = h1 - (int)'0'; - c = c << 4; - if (h2 >= 'a') c += h2 - (int)'a' + 10; - else if (h2 >= 'A') c += h2 - (int)'A' + 10; - else if (h2 >= '0') c += h2 - (int)'0'; - - return c; - } - - return -1; -} - -/* -a filter is defined by: - ::= '(' ')' - ::= | | | - ::= '&' - ::= '|' - ::= '!' - ::= | - ::= - ::= '=' | '~=' | '<=' | '>=' -*/ - -/* - decode a RFC2254 binary string representation of a buffer. - Used in LDAP filters. -*/ -struct ldb_val ldb_binary_decode(TALLOC_CTX *mem_ctx, const char *str) -{ - size_t i, j; - struct ldb_val ret; - size_t slen = str?strlen(str):0; - - ret.data = (uint8_t *)talloc_size(mem_ctx, slen+1); - ret.length = 0; - if (ret.data == NULL) return ret; - - for (i=j=0;i 0x7E || strchr(" *()\\&|!\"", cval)) { - return true; - } - return false; -} - -/* - encode a blob as a RFC2254 binary string, escaping any - non-printable or '\' characters -*/ -char *ldb_binary_encode(TALLOC_CTX *mem_ctx, struct ldb_val val) -{ - size_t i; - char *ret; - size_t len = val.length; - unsigned char *buf = val.data; - - for (i=0;idata == NULL) return NULL; - - val++; - } - - if (ret != NULL) { - ret[val] = NULL; - } - - return ret; -} - -static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char **s); - - -/* - parse an extended match - - possible forms: - (attr:oid:=value) - (attr:dn:oid:=value) - (attr:dn:=value) - (:dn:oid:=value) - - the ':dn' part sets the dnAttributes boolean if present - the oid sets the rule_id string - -*/ -static struct ldb_parse_tree *ldb_parse_extended(struct ldb_parse_tree *ret, - char *attr, char *value) -{ - char *p1, *p2; - - ret->operation = LDB_OP_EXTENDED; - ret->u.extended.value = ldb_binary_decode(ret, value); - if (ret->u.extended.value.data == NULL) goto failed; - - p1 = strchr(attr, ':'); - if (p1 == NULL) goto failed; - p2 = strchr(p1+1, ':'); - - *p1 = 0; - if (p2) *p2 = 0; - - ret->u.extended.attr = attr; - if (strcmp(p1+1, "dn") == 0) { - ret->u.extended.dnAttributes = 1; - if (p2) { - ret->u.extended.rule_id = talloc_strdup(ret, p2+1); - if (ret->u.extended.rule_id == NULL) goto failed; - } else { - ret->u.extended.rule_id = NULL; - } - } else { - ret->u.extended.dnAttributes = 0; - ret->u.extended.rule_id = talloc_strdup(ret, p1+1); - if (ret->u.extended.rule_id == NULL) goto failed; - } - - return ret; - -failed: - talloc_free(ret); - return NULL; -} - -static enum ldb_parse_op ldb_parse_filtertype(TALLOC_CTX *mem_ctx, char **type, char **value, const char **s) -{ - enum ldb_parse_op filter = 0; - char *name, *val, *k; - const char *p = *s; - const char *t, *t1; - - /* retrieve attributetype name */ - t = p; - - if (*p == '@') { /* for internal attributes the first char can be @ */ - p++; - } - - while ((isascii(*p) && isalnum((unsigned char)*p)) || (*p == '-') || (*p == '.')) { - /* attribute names can only be alphanums */ - p++; - } - - if (*p == ':') { /* but extended searches have : and . chars too */ - p = strstr(p, ":="); - if (p == NULL) { /* malformed attribute name */ - return 0; - } - } - - t1 = p; - - while (isspace((unsigned char)*p)) p++; - - if (!strchr("=<>~:", *p)) { - return 0; - } - - /* save name */ - name = (char *)talloc_memdup(mem_ctx, t, t1 - t + 1); - if (name == NULL) return 0; - name[t1 - t] = '\0'; - - /* retrieve filtertype */ - - if (*p == '=') { - filter = LDB_OP_EQUALITY; - } else if (*p != '\0' && *(p + 1) == '=') { - switch (*p) { - case '<': - filter = LDB_OP_LESS; - p++; - break; - case '>': - filter = LDB_OP_GREATER; - p++; - break; - case '~': - filter = LDB_OP_APPROX; - p++; - break; - case ':': - filter = LDB_OP_EXTENDED; - p++; - break; - } - } - if (!filter) { - talloc_free(name); - return 0; - } - p++; - - while (isspace((unsigned char)*p)) p++; - - /* retrieve value */ - t = p; - - while (*p && ((*p != ')') || ((*p == ')') && (*(p - 1) == '\\')))) p++; - - val = (char *)talloc_memdup(mem_ctx, t, p - t + 1); - if (val == NULL) { - talloc_free(name); - return 0; - } - val[p - t] = '\0'; - - k = &(val[p - t]); - - /* remove trailing spaces from value */ - while ((k > val) && (isspace((unsigned char)*(k - 1)))) k--; - *k = '\0'; - - *type = name; - *value = val; - *s = p; - return filter; -} - -/* - ::= -*/ -static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *mem_ctx, const char **s) -{ - char *attr, *value; - struct ldb_parse_tree *ret; - enum ldb_parse_op filtertype; - - ret = talloc_zero(mem_ctx, struct ldb_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - filtertype = ldb_parse_filtertype(ret, &attr, &value, s); - if (!filtertype) { - talloc_free(ret); - return NULL; - } - - switch (filtertype) { - - case LDB_OP_PRESENT: - ret->operation = LDB_OP_PRESENT; - ret->u.present.attr = attr; - break; - - case LDB_OP_EQUALITY: - - if (strcmp(value, "*") == 0) { - ret->operation = LDB_OP_PRESENT; - ret->u.present.attr = attr; - break; - } - - if (ldb_parse_find_wildcard(value) != NULL) { - ret->operation = LDB_OP_SUBSTRING; - ret->u.substring.attr = attr; - ret->u.substring.start_with_wildcard = 0; - ret->u.substring.end_with_wildcard = 0; - ret->u.substring.chunks = ldb_wildcard_decode(ret, value); - if (ret->u.substring.chunks == NULL){ - talloc_free(ret); - return NULL; - } - if (value[0] == '*') - ret->u.substring.start_with_wildcard = 1; - if (value[strlen(value) - 1] == '*') - ret->u.substring.end_with_wildcard = 1; - talloc_free(value); - - break; - } - - ret->operation = LDB_OP_EQUALITY; - ret->u.equality.attr = attr; - ret->u.equality.value = ldb_binary_decode(ret, value); - if (ret->u.equality.value.data == NULL) { - talloc_free(ret); - return NULL; - } - talloc_free(value); - break; - - case LDB_OP_GREATER: - ret->operation = LDB_OP_GREATER; - ret->u.comparison.attr = attr; - ret->u.comparison.value = ldb_binary_decode(ret, value); - if (ret->u.comparison.value.data == NULL) { - talloc_free(ret); - return NULL; - } - talloc_free(value); - break; - - case LDB_OP_LESS: - ret->operation = LDB_OP_LESS; - ret->u.comparison.attr = attr; - ret->u.comparison.value = ldb_binary_decode(ret, value); - if (ret->u.comparison.value.data == NULL) { - talloc_free(ret); - return NULL; - } - talloc_free(value); - break; - - case LDB_OP_APPROX: - ret->operation = LDB_OP_APPROX; - ret->u.comparison.attr = attr; - ret->u.comparison.value = ldb_binary_decode(ret, value); - if (ret->u.comparison.value.data == NULL) { - talloc_free(ret); - return NULL; - } - talloc_free(value); - break; - - case LDB_OP_EXTENDED: - - ret = ldb_parse_extended(ret, attr, value); - break; - - default: - talloc_free(ret); - return NULL; - } - - return ret; -} - - -/* - parse a filterlist - ::= '&' - ::= '|' - ::= | -*/ -static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *mem_ctx, const char **s) -{ - struct ldb_parse_tree *ret, *next; - enum ldb_parse_op op; - const char *p = *s; - - switch (*p) { - case '&': - op = LDB_OP_AND; - break; - case '|': - op = LDB_OP_OR; - break; - default: - return NULL; - } - p++; - - while (isspace((unsigned char)*p)) p++; - - ret = talloc(mem_ctx, struct ldb_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - ret->operation = op; - ret->u.list.num_elements = 1; - ret->u.list.elements = talloc(ret, struct ldb_parse_tree *); - if (!ret->u.list.elements) { - errno = ENOMEM; - talloc_free(ret); - return NULL; - } - - ret->u.list.elements[0] = ldb_parse_filter(ret->u.list.elements, &p); - if (!ret->u.list.elements[0]) { - talloc_free(ret); - return NULL; - } - - while (isspace((unsigned char)*p)) p++; - - while (*p) { - struct ldb_parse_tree **e; - if (*p == ')') { - break; - } - - next = ldb_parse_filter(ret->u.list.elements, &p); - if (next == NULL) { - /* an invalid filter element */ - talloc_free(ret); - return NULL; - } - e = talloc_realloc(ret, ret->u.list.elements, - struct ldb_parse_tree *, - ret->u.list.num_elements + 1); - if (!e) { - errno = ENOMEM; - talloc_free(ret); - return NULL; - } - ret->u.list.elements = e; - ret->u.list.elements[ret->u.list.num_elements] = next; - ret->u.list.num_elements++; - while (isspace((unsigned char)*p)) p++; - } - - *s = p; - - return ret; -} - - -/* - ::= '!' -*/ -static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *mem_ctx, const char **s) -{ - struct ldb_parse_tree *ret; - const char *p = *s; - - if (*p != '!') { - return NULL; - } - p++; - - ret = talloc(mem_ctx, struct ldb_parse_tree); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - ret->operation = LDB_OP_NOT; - ret->u.isnot.child = ldb_parse_filter(ret, &p); - if (!ret->u.isnot.child) { - talloc_free(ret); - return NULL; - } - - *s = p; - - return ret; -} - -/* - parse a filtercomp - ::= | | | -*/ -static struct ldb_parse_tree *ldb_parse_filtercomp(TALLOC_CTX *mem_ctx, const char **s) -{ - struct ldb_parse_tree *ret; - const char *p = *s; - - while (isspace((unsigned char)*p)) p++; - - switch (*p) { - case '&': - ret = ldb_parse_filterlist(mem_ctx, &p); - break; - - case '|': - ret = ldb_parse_filterlist(mem_ctx, &p); - break; - - case '!': - ret = ldb_parse_not(mem_ctx, &p); - break; - - case '(': - case ')': - return NULL; - - default: - ret = ldb_parse_simple(mem_ctx, &p); - - } - - *s = p; - return ret; -} - - -/* - ::= '(' ')' -*/ -static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *mem_ctx, const char **s) -{ - struct ldb_parse_tree *ret; - const char *p = *s; - - if (*p != '(') { - return NULL; - } - p++; - - ret = ldb_parse_filtercomp(mem_ctx, &p); - - if (*p != ')') { - return NULL; - } - p++; - - while (isspace((unsigned char)*p)) { - p++; - } - - *s = p; - - return ret; -} - - -/* - main parser entry point. Takes a search string and returns a parse tree - - expression ::= | -*/ -struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s) -{ - while (s && isspace((unsigned char)*s)) s++; - - if (s == NULL || *s == 0) { - s = "(|(objectClass=*)(distinguishedName=*))"; - } - - if (*s == '(') { - return ldb_parse_filter(mem_ctx, &s); - } - - return ldb_parse_simple(mem_ctx, &s); -} - - -/* - construct a ldap parse filter given a parse tree -*/ -char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, const struct ldb_parse_tree *tree) -{ - char *s, *s2, *ret; - unsigned int i; - - if (tree == NULL) { - return NULL; - } - - switch (tree->operation) { - case LDB_OP_AND: - case LDB_OP_OR: - ret = talloc_asprintf(mem_ctx, "(%c", tree->operation==LDB_OP_AND?'&':'|'); - if (ret == NULL) return NULL; - for (i=0;iu.list.num_elements;i++) { - s = ldb_filter_from_tree(mem_ctx, tree->u.list.elements[i]); - if (s == NULL) { - talloc_free(ret); - return NULL; - } - s2 = talloc_asprintf_append(ret, "%s", s); - talloc_free(s); - if (s2 == NULL) { - talloc_free(ret); - return NULL; - } - ret = s2; - } - s = talloc_asprintf_append(ret, ")"); - if (s == NULL) { - talloc_free(ret); - return NULL; - } - return s; - case LDB_OP_NOT: - s = ldb_filter_from_tree(mem_ctx, tree->u.isnot.child); - if (s == NULL) return NULL; - - ret = talloc_asprintf(mem_ctx, "(!%s)", s); - talloc_free(s); - return ret; - case LDB_OP_EQUALITY: - s = ldb_binary_encode(mem_ctx, tree->u.equality.value); - if (s == NULL) return NULL; - ret = talloc_asprintf(mem_ctx, "(%s=%s)", - tree->u.equality.attr, s); - talloc_free(s); - return ret; - case LDB_OP_SUBSTRING: - ret = talloc_asprintf(mem_ctx, "(%s=%s", tree->u.substring.attr, - tree->u.substring.start_with_wildcard?"*":""); - if (ret == NULL) return NULL; - for (i = 0; tree->u.substring.chunks && tree->u.substring.chunks[i]; i++) { - s2 = ldb_binary_encode(mem_ctx, *(tree->u.substring.chunks[i])); - if (s2 == NULL) { - talloc_free(ret); - return NULL; - } - if (tree->u.substring.chunks[i+1] || - tree->u.substring.end_with_wildcard) { - s = talloc_asprintf_append(ret, "%s*", s2); - } else { - s = talloc_asprintf_append(ret, "%s", s2); - } - if (s == NULL) { - talloc_free(ret); - return NULL; - } - ret = s; - } - s = talloc_asprintf_append(ret, ")"); - if (s == NULL) { - talloc_free(ret); - return NULL; - } - ret = s; - return ret; - case LDB_OP_GREATER: - s = ldb_binary_encode(mem_ctx, tree->u.equality.value); - if (s == NULL) return NULL; - ret = talloc_asprintf(mem_ctx, "(%s>=%s)", - tree->u.equality.attr, s); - talloc_free(s); - return ret; - case LDB_OP_LESS: - s = ldb_binary_encode(mem_ctx, tree->u.equality.value); - if (s == NULL) return NULL; - ret = talloc_asprintf(mem_ctx, "(%s<=%s)", - tree->u.equality.attr, s); - talloc_free(s); - return ret; - case LDB_OP_PRESENT: - ret = talloc_asprintf(mem_ctx, "(%s=*)", tree->u.present.attr); - return ret; - case LDB_OP_APPROX: - s = ldb_binary_encode(mem_ctx, tree->u.equality.value); - if (s == NULL) return NULL; - ret = talloc_asprintf(mem_ctx, "(%s~=%s)", - tree->u.equality.attr, s); - talloc_free(s); - return ret; - case LDB_OP_EXTENDED: - s = ldb_binary_encode(mem_ctx, tree->u.extended.value); - if (s == NULL) return NULL; - ret = talloc_asprintf(mem_ctx, "(%s%s%s%s:=%s)", - tree->u.extended.attr?tree->u.extended.attr:"", - tree->u.extended.dnAttributes?":dn":"", - tree->u.extended.rule_id?":":"", - tree->u.extended.rule_id?tree->u.extended.rule_id:"", - s); - talloc_free(s); - return ret; - } - - return NULL; -} - - -/* - walk a parse tree, calling the provided callback on each node -*/ -int ldb_parse_tree_walk(struct ldb_parse_tree *tree, - int (*callback)(struct ldb_parse_tree *tree, void *), - void *private_context) -{ - unsigned int i; - int ret; - - ret = callback(tree, private_context); - if (ret != LDB_SUCCESS) { - return ret; - } - - switch (tree->operation) { - case LDB_OP_AND: - case LDB_OP_OR: - for (i=0;iu.list.num_elements;i++) { - ret = ldb_parse_tree_walk(tree->u.list.elements[i], callback, private_context); - if (ret != LDB_SUCCESS) { - return ret; - } - } - break; - case LDB_OP_NOT: - ret = ldb_parse_tree_walk(tree->u.isnot.child, callback, private_context); - if (ret != LDB_SUCCESS) { - return ret; - } - break; - case LDB_OP_EQUALITY: - case LDB_OP_GREATER: - case LDB_OP_LESS: - case LDB_OP_APPROX: - case LDB_OP_SUBSTRING: - case LDB_OP_PRESENT: - case LDB_OP_EXTENDED: - break; - } - return LDB_SUCCESS; -} - -struct parse_tree_attr_replace_ctx { - const char *attr; - const char *replace; -}; - -/* - callback for ldb_parse_tree_attr_replace() - */ -static int parse_tree_attr_replace(struct ldb_parse_tree *tree, void *private_context) -{ - struct parse_tree_attr_replace_ctx *ctx = private_context; - switch (tree->operation) { - case LDB_OP_EQUALITY: - case LDB_OP_GREATER: - case LDB_OP_LESS: - case LDB_OP_APPROX: - if (ldb_attr_cmp(tree->u.equality.attr, ctx->attr) == 0) { - tree->u.equality.attr = ctx->replace; - } - break; - case LDB_OP_SUBSTRING: - if (ldb_attr_cmp(tree->u.substring.attr, ctx->attr) == 0) { - tree->u.substring.attr = ctx->replace; - } - break; - case LDB_OP_PRESENT: - if (ldb_attr_cmp(tree->u.present.attr, ctx->attr) == 0) { - tree->u.present.attr = ctx->replace; - } - break; - case LDB_OP_EXTENDED: - if (tree->u.extended.attr && - ldb_attr_cmp(tree->u.extended.attr, ctx->attr) == 0) { - tree->u.extended.attr = ctx->replace; - } - break; - default: - break; - } - return LDB_SUCCESS; -} - -/* - replace any occurrences of an attribute name in the parse tree with a - new name -*/ -void ldb_parse_tree_attr_replace(struct ldb_parse_tree *tree, - const char *attr, - const char *replace) -{ - struct parse_tree_attr_replace_ctx ctx; - - ctx.attr = attr; - ctx.replace = replace; - - ldb_parse_tree_walk(tree, parse_tree_attr_replace, &ctx); -} - -/* - shallow copy a tree - copying only the elements array so that the caller - can safely add new elements without changing the message -*/ -struct ldb_parse_tree *ldb_parse_tree_copy_shallow(TALLOC_CTX *mem_ctx, - const struct ldb_parse_tree *ot) -{ - unsigned int i; - struct ldb_parse_tree *nt; - - nt = talloc(mem_ctx, struct ldb_parse_tree); - if (!nt) { - return NULL; - } - - *nt = *ot; - - switch (ot->operation) { - case LDB_OP_AND: - case LDB_OP_OR: - nt->u.list.elements = talloc_array(nt, struct ldb_parse_tree *, - ot->u.list.num_elements); - if (!nt->u.list.elements) { - talloc_free(nt); - return NULL; - } - - for (i=0;iu.list.num_elements;i++) { - nt->u.list.elements[i] = - ldb_parse_tree_copy_shallow(nt->u.list.elements, - ot->u.list.elements[i]); - if (!nt->u.list.elements[i]) { - talloc_free(nt); - return NULL; - } - } - break; - case LDB_OP_NOT: - nt->u.isnot.child = ldb_parse_tree_copy_shallow(nt, - ot->u.isnot.child); - if (!nt->u.isnot.child) { - talloc_free(nt); - return NULL; - } - break; - case LDB_OP_EQUALITY: - case LDB_OP_GREATER: - case LDB_OP_LESS: - case LDB_OP_APPROX: - case LDB_OP_SUBSTRING: - case LDB_OP_PRESENT: - case LDB_OP_EXTENDED: - break; - } - - return nt; -} diff --git a/ldb-2.0.8/common/ldb_utf8.c b/ldb-2.0.8/common/ldb_utf8.c deleted file mode 100644 index 55d8f90..0000000 --- a/ldb-2.0.8/common/ldb_utf8.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb utf8 handling - * - * Description: case folding and case comparison for UTF8 strings - * - * Author: Andrew Tridgell - */ - -#include "ldb_private.h" -#include "system/locale.h" - - -/* - this allow the user to pass in a caseless comparison - function to handle utf8 caseless comparisons - */ -void ldb_set_utf8_fns(struct ldb_context *ldb, - void *context, - char *(*casefold)(void *, void *, const char *, size_t)) -{ - if (context) - ldb->utf8_fns.context = context; - if (casefold) - ldb->utf8_fns.casefold = casefold; -} - -/* - a simple case folding function - NOTE: does not handle UTF8 -*/ -char *ldb_casefold_default(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n) -{ - size_t i; - char *ret = talloc_strndup(mem_ctx, s, n); - if (!s) { - errno = ENOMEM; - return NULL; - } - for (i=0;ret[i];i++) { - ret[i] = toupper((unsigned char)ret[i]); - } - return ret; -} - -void ldb_set_utf8_default(struct ldb_context *ldb) -{ - ldb_set_utf8_fns(ldb, NULL, ldb_casefold_default); -} - -char *ldb_casefold(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *s, size_t n) -{ - return ldb->utf8_fns.casefold(ldb->utf8_fns.context, mem_ctx, s, n); -} - -/* - check the attribute name is valid according to rfc2251 - returns 1 if the name is ok - */ - -int ldb_valid_attr_name(const char *s) -{ - size_t i; - - if (!s || !s[0]) - return 0; - - /* handle special ldb_tdb wildcard */ - if (strcmp(s, "*") == 0) return 1; - - for (i = 0; s[i]; i++) { - if (! isascii(s[i])) { - return 0; - } - if (i == 0) { /* first char must be an alpha (or our special '@' identifier) */ - if (! (isalpha(s[i]) || (s[i] == '@'))) { - return 0; - } - } else { - if (! (isalnum(s[i]) || (s[i] == '-'))) { - return 0; - } - } - } - return 1; -} - -char *ldb_attr_casefold(TALLOC_CTX *mem_ctx, const char *s) -{ - size_t i; - char *ret = talloc_strdup(mem_ctx, s); - if (!ret) { - errno = ENOMEM; - return NULL; - } - for (i = 0; ret[i]; i++) { - ret[i] = toupper((unsigned char)ret[i]); - } - return ret; -} - -/* - we accept either 'dn' or 'distinguishedName' for a distinguishedName -*/ -int ldb_attr_dn(const char *attr) -{ - if (ldb_attr_cmp(attr, "dn") == 0 || - ldb_attr_cmp(attr, "distinguishedName") == 0) { - return 0; - } - return -1; -} diff --git a/ldb-2.0.8/common/qsort.c b/ldb-2.0.8/common/qsort.c deleted file mode 100644 index 012aaf3..0000000 --- a/ldb-2.0.8/common/qsort.c +++ /dev/null @@ -1,251 +0,0 @@ -/* Copyright (C) 1991,1992,1996,1997,1999,2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Douglas C. Schmidt (schmidt@ics.uci.edu). - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see . */ - -/* If you consider tuning this algorithm, you should consult first: - Engineering a sort function; Jon Bentley and M. Douglas McIlroy; - Software - Practice and Experience; Vol. 23 (11), 1249-1265, 1993. */ - -/* Modified to be used in samba4 by - * Simo Sorce 2005 - */ - -#include "ldb_private.h" - -/* Byte-wise swap two items of size SIZE. */ -#define SWAP(a, b, size) \ - do \ - { \ - register size_t __size = (size); \ - register char *__a = (a), *__b = (b); \ - do \ - { \ - char __tmp = *__a; \ - *__a++ = *__b; \ - *__b++ = __tmp; \ - } while (--__size > 0); \ - } while (0) - -/* Discontinue quicksort algorithm when partition gets below this size. - This particular magic number was chosen to work best on a Sun 4/260. */ -#define MAX_THRESH 4 - -/* Stack node declarations used to store unfulfilled partition obligations. */ -typedef struct - { - char *lo; - char *hi; - } stack_node; - -/* The next 4 #defines implement a very fast in-line stack abstraction. */ -/* The stack needs log (total_elements) entries (we could even subtract - log(MAX_THRESH)). Since total_elements has type size_t, we get as - upper bound for log (total_elements): - bits per byte (CHAR_BIT) * sizeof(size_t). */ -#ifndef CHAR_BIT -#define CHAR_BIT 8 -#endif -#define STACK_SIZE (CHAR_BIT * sizeof(size_t)) -#define PUSH(low, high) ((void) ((stack[i].lo = (low)), (stack[i].hi = (high)), i++)) -#define POP(low, high) ((void) (i--, (low = stack[i].lo), (high = stack[i].hi))) - - -/* Order size using quicksort. This implementation incorporates - four optimizations discussed in Sedgewick: - - 1. Non-recursive, using an explicit stack of pointer that store the - next array partition to sort. To save time, this maximum amount - of space required to store an array of SIZE_MAX is allocated on the - stack. Assuming a 32-bit (64 bit) integer for size_t, this needs - only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes). - Pretty cheap, actually. - - 2. Chose the pivot element using a median-of-three decision tree. - This reduces the probability of selecting a bad pivot value and - eliminates certain extraneous comparisons. - - 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving - insertion sort to order the MAX_THRESH items within each partition. - This is a big win, since insertion sort is faster for small, mostly - sorted array segments. - - 4. The larger of the two sub-partitions is always pushed onto the - stack first, with the algorithm then concentrating on the - smaller partition. This *guarantees* no more than log (total_elems) - stack size is needed (actually O(1) in this case)! */ - -void ldb_qsort (void *const pbase, size_t total_elems, size_t size, - void *opaque, ldb_qsort_cmp_fn_t cmp) -{ - register char *base_ptr = (char *) pbase; - - const size_t max_thresh = MAX_THRESH * size; - - if (total_elems == 0) - /* Avoid lossage with unsigned arithmetic below. */ - return; - - if (total_elems > MAX_THRESH) - { - char *lo = base_ptr; - char *hi = &lo[size * (total_elems - 1)]; - stack_node stack[STACK_SIZE]; - size_t i = 0; - - PUSH (NULL, NULL); - - do - { - char *left_ptr; - char *right_ptr; - - /* Select median value from among LO, MID, and HI. Rearrange - LO and HI so the three values are sorted. This lowers the - probability of picking a pathological pivot value and - skips a comparison for both the LEFT_PTR and RIGHT_PTR in - the while loops. */ - - char *mid = lo + size * ((hi - lo) / size >> 1); - - if ((*cmp) ((void *) mid, (void *) lo, opaque) < 0) - SWAP (mid, lo, size); - if ((*cmp) ((void *) hi, (void *) mid, opaque) < 0) - SWAP (mid, hi, size); - else - goto jump_over; - if ((*cmp) ((void *) mid, (void *) lo, opaque) < 0) - SWAP (mid, lo, size); - jump_over:; - - left_ptr = lo + size; - right_ptr = hi - size; - - /* Here's the famous ``collapse the walls'' section of quicksort. - Gotta like those tight inner loops! They are the main reason - that this algorithm runs much faster than others. */ - do - { - while ((*cmp) ((void *) left_ptr, (void *) mid, opaque) < 0) - left_ptr += size; - - while ((*cmp) ((void *) mid, (void *) right_ptr, opaque) < 0) - right_ptr -= size; - - if (left_ptr < right_ptr) - { - SWAP (left_ptr, right_ptr, size); - if (mid == left_ptr) - mid = right_ptr; - else if (mid == right_ptr) - mid = left_ptr; - left_ptr += size; - right_ptr -= size; - } - else if (left_ptr == right_ptr) - { - left_ptr += size; - right_ptr -= size; - break; - } - } - while (left_ptr <= right_ptr); - - /* Set up pointers for next iteration. First determine whether - left and right partitions are below the threshold size. If so, - ignore one or both. Otherwise, push the larger partition's - bounds on the stack and continue sorting the smaller one. */ - - if ((size_t) (right_ptr - lo) <= max_thresh) - { - if ((size_t) (hi - left_ptr) <= max_thresh) - /* Ignore both small partitions. */ - POP (lo, hi); - else - /* Ignore small left partition. */ - lo = left_ptr; - } - else if ((size_t) (hi - left_ptr) <= max_thresh) - /* Ignore small right partition. */ - hi = right_ptr; - else if ((right_ptr - lo) > (hi - left_ptr)) - { - /* Push larger left partition indices. */ - PUSH (lo, right_ptr); - lo = left_ptr; - } - else - { - /* Push larger right partition indices. */ - PUSH (left_ptr, hi); - hi = right_ptr; - } - } - while (i > 0 && i < STACK_SIZE); - } - - /* Once the BASE_PTR array is partially sorted by quicksort the rest - is completely sorted using insertion sort, since this is efficient - for partitions below MAX_THRESH size. BASE_PTR points to the beginning - of the array to sort, and END_PTR points at the very last element in - the array (*not* one beyond it!). */ - -#define min(x, y) ((x) < (y) ? (x) : (y)) - - { - char *const end_ptr = &base_ptr[size * (total_elems - 1)]; - char *tmp_ptr = base_ptr; - char *thresh = min(end_ptr, base_ptr + max_thresh); - register char *run_ptr; - - /* Find smallest element in first threshold and place it at the - array's beginning. This is the smallest array element, - and the operation speeds up insertion sort's inner loop. */ - - for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size) - if ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, opaque) < 0) - tmp_ptr = run_ptr; - - if (tmp_ptr != base_ptr) - SWAP (tmp_ptr, base_ptr, size); - - /* Insertion sort, running from left-hand-side up to right-hand-side. */ - - run_ptr = base_ptr + size; - while ((run_ptr += size) <= end_ptr) - { - tmp_ptr = run_ptr - size; - while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, opaque) < 0) - tmp_ptr -= size; - - tmp_ptr += size; - if (tmp_ptr != run_ptr) - { - char *trav; - - trav = run_ptr + size; - while (--trav >= run_ptr) - { - char c = *trav; - char *hi, *lo; - - for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo) - *hi = *lo; - *hi = c; - } - } - } - } -} diff --git a/ldb-2.0.8/configure b/ldb-2.0.8/configure deleted file mode 100755 index 6c931bf..0000000 --- a/ldb-2.0.8/configure +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -PREVPATH=`dirname $0` - -if [ -f $PREVPATH/../../buildtools/bin/waf ]; then - WAF=../../buildtools/bin/waf -elif [ -f $PREVPATH/buildtools/bin/waf ]; then - WAF=./buildtools/bin/waf -else - echo "ldb: Unable to find waf" - exit 1 -fi - -# using JOBS=1 gives maximum compatibility with -# systems like AIX which have broken threading in python -JOBS=1 -export JOBS - -cd . || exit 1 -$PYTHON $WAF configure "$@" || exit 1 -cd $PREVPATH diff --git a/ldb-2.0.8/docs/builddocs.sh b/ldb-2.0.8/docs/builddocs.sh deleted file mode 100755 index 449dcb2..0000000 --- a/ldb-2.0.8/docs/builddocs.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/sh -# build ldb docs -# tridge@samba.org August 2006 - -XSLTPROC="$1" -SRCDIR="$2" - -if [ -z "$XSLTPROC" ] || [ ! -x "$XSLTPROC" ]; then - echo "xsltproc not installed" - exit 0 -fi - -MANXSL="http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl" -HTMLXSL="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl" - -mkdir -p man - -for f in $SRCDIR/man/*.xml; do - base=`basename $f .xml` - out=man/"`basename $base`" - if [ ! -f "$out" ] || [ "$f" -nt "$out" ]; then - echo Processing manpage $f - $XSLTPROC --nonet -o "$out" "$MANXSL" $f - ret=$? - if [ "$ret" = "4" ]; then - echo "ignoring stylesheet error 4 for $MANXSL" - exit 0 - fi - if [ "$ret" != "0" ]; then - echo "xsltproc failed with error $ret" - exit $ret - fi - fi -done - -for f in $SRCDIR/man/*.xml; do - base=`basename $f .xml` - out=man/"`basename $base`".html - if [ ! -f "$out" ] || [ "$f" -nt "$out" ]; then - echo Processing html $f - $XSLTPROC --nonet -o "$out" "$HTMLXSL" $f - ret=$? - if [ "$ret" = "4" ]; then - echo "ignoring stylesheet error 4 for $HTMLXSL" - exit 0 - fi - if [ "$ret" != "0" ]; then - echo "xsltproc failed with error $ret" - exit $ret - fi - fi -done diff --git a/ldb-2.0.8/docs/design.txt b/ldb-2.0.8/docs/design.txt deleted file mode 100644 index 0bb278b..0000000 --- a/ldb-2.0.8/docs/design.txt +++ /dev/null @@ -1,41 +0,0 @@ -The list of indexed fields --------------------------- - -dn=@INDEXLIST - list of field names that are indexed - - contains fields of type @IDXATTR which contain attriute names - of indexed fields - - -Data records ------------- - -for each user record in the db there is: - main record - key: DN=dn - data: packed attribute/value list - - a index record for each indexed field in the record - - -Index Records -------------- - -The index records contain the list of dn's that contain records -matching the index key - -All index records are of the form: - dn=@INDEX:field:value - -and contain fields of type @IDX which are the dns of the records -that have that value for some attribute - - -Search Expressions ------------------- - -Very similar to LDAP search expressions, but does not allow ~=, <= or >= - - attrib0 := (field=value) - attrib := attrib0 | (attrib&&attrib) | (attrib||attrib) | !attrib diff --git a/ldb-2.0.8/docs/installdocs.sh b/ldb-2.0.8/docs/installdocs.sh deleted file mode 100755 index 6cc7b74..0000000 --- a/ldb-2.0.8/docs/installdocs.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -# install ldb docs -# tridge@samba.org August 2006 - -MANDIR="$1" - -MAN1="`/bin/ls man/*.1`" -MAN3="`/bin/ls man/*.3`" - -if [ -z "$MAN1" ] && [ -z "$MAN3" ]; then - echo "No manpages have been built" - exit 0 -fi - -mkdir -p "$MANDIR/man1" "$MANDIR/man3" -cp $MAN1 "$MANDIR/man1/" || exit 1 -cp $MAN3 "$MANDIR/man3/" || exit 1 diff --git a/ldb-2.0.8/examples.dox b/ldb-2.0.8/examples.dox deleted file mode 100644 index ef4b4f0..0000000 --- a/ldb-2.0.8/examples.dox +++ /dev/null @@ -1,16 +0,0 @@ -/** \example ldbreader.c - -The code below shows a simple LDB application. - -It lists / dumps the records in a LDB database to standard output. - -*/ - - -/** \example ldifreader.c - -The code below shows a simple LDB application. - -It lists / dumps the entries in an LDIF file to standard output. - -*/ diff --git a/ldb-2.0.8/examples/ldbreader.c b/ldb-2.0.8/examples/ldbreader.c deleted file mode 100644 index 3496baf..0000000 --- a/ldb-2.0.8/examples/ldbreader.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - example code for the ldb database library - - Copyright (C) Brad Hards (bradh@frogmouth.net) 2005-2006 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/** \example ldbreader.c - -The code below shows a simple LDB application. - -It lists / dumps the records in a LDB database to standard output. - -*/ - -#include "ldb.h" - -/* - ldb_ldif_write takes a function pointer to a custom output - function. This version is about as simple as the output function can - be. In a more complex example, you'd likely be doing something with - the private data function (e.g. holding a file handle). -*/ -static int vprintf_fn(void *private_data, const char *fmt, ...) -{ - int retval; - va_list ap; - - va_start(ap, fmt); - /* We just write to standard output */ - retval = vprintf(fmt, ap); - va_end(ap); - /* Note that the function should return the number of - bytes written, or a negative error code */ - return retval; -} - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - const char *expression = "(dn=*)"; - struct ldb_result *resultMsg; - int i; - - /* - This is the always the first thing you want to do in an LDB - application - initialise up the context structure. - - Note that you can use the context structure as a parent - for talloc allocations as well - */ - ldb = ldb_init(NULL, NULL); - - /* - We now open the database. In this example we just hard code the connection path. - - Also note that the database is being opened read-only. This means that the - call will fail unless the database already exists. - */ - if (LDB_SUCCESS != ldb_connect(ldb, "tdb://tdbtest.ldb", LDB_FLG_RDONLY, NULL) ){ - printf("Problem on connection\n"); - exit(-1); - } - - /* - At this stage we have an open database, and can start using it. It is opened - read-only, so a query is possible. - - We construct a search that just returns all the (sensible) contents. You can do - quite fine grained results with the LDAP search syntax, however it is a bit - confusing to start with. See RFC2254. - */ - if (LDB_SUCCESS != ldb_search(ldb, ldb, &resultMsg, - NULL, LDB_SCOPE_DEFAULT, NULL, - "%s", expression)) { - printf("Problem in search\n"); - exit(-1); - } - - printf("%i records returned\n", resultMsg->count); - - /* - We can now iterate through the results, writing them out - (to standard output) with our custom output routine as defined - at the top of this file - */ - for (i = 0; i < resultMsg->count; ++i) { - struct ldb_ldif ldifMsg; - - printf("Message: %i\n", i+1); - - ldifMsg.changetype = LDB_CHANGETYPE_NONE; - ldifMsg.msg = resultMsg->msgs[i]; - ldb_ldif_write(ldb, vprintf_fn, NULL, &ldifMsg); - } - - /* - There are two objects to clean up - the result from the - ldb_search() query, and the original ldb context. - */ - talloc_free(resultMsg); - - talloc_free(ldb); - - return 0; -} diff --git a/ldb-2.0.8/examples/ldifreader.c b/ldb-2.0.8/examples/ldifreader.c deleted file mode 100644 index dcd9daf..0000000 --- a/ldb-2.0.8/examples/ldifreader.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - example code for the ldb database library - - Copyright (C) Brad Hards (bradh@frogmouth.net) 2005-2006 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/** \example ldifreader.c - -The code below shows a simple LDB application. - -It lists / dumps the entries in an LDIF file to standard output. - -*/ - -#include "ldb.h" - -/* - ldb_ldif_write takes a function pointer to a custom output - function. This version is about as simple as the output function can - be. In a more complex example, you'd likely be doing something with - the private data function (e.g. holding a file handle). -*/ -static int vprintf_fn(void *private_data, const char *fmt, ...) -{ - int retval; - va_list ap; - - va_start(ap, fmt); - /* We just write to standard output */ - retval = vprintf(fmt, ap); - va_end(ap); - /* Note that the function should return the number of - bytes written, or a negative error code */ - return retval; -} - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - FILE *fileStream; - struct ldb_ldif *ldifMsg; - - if (argc != 2) { - printf("Usage %s filename.ldif\n", argv[0]); - exit(1); - } - - /* - This is the always the first thing you want to do in an LDB - application - initialise up the context structure. - - Note that you can use the context structure as a parent - for talloc allocations as well - */ - ldb = ldb_init(NULL, NULL); - - fileStream = fopen(argv[1], "r"); - if (0 == fileStream) { - perror(argv[1]); - exit(1); - } - - /* - We now work through the filestream to get each entry. - */ - while ( (ldifMsg = ldb_ldif_read_file(ldb, fileStream)) ) { - /* - Each message has a particular change type. For Add, - Modify and Delete, this will also appear in the - output listing (as changetype: add, changetype: - modify or changetype:delete, respectively). - */ - switch (ldifMsg->changetype) { - case LDB_CHANGETYPE_NONE: - printf("ChangeType: None\n"); - break; - case LDB_CHANGETYPE_ADD: - printf("ChangeType: Add\n"); - break; - case LDB_CHANGETYPE_MODIFY: - printf("ChangeType: Modify\n"); - break; - case LDB_CHANGETYPE_DELETE: - printf("ChangeType: Delete\n"); - break; - default: - printf("ChangeType: Unknown\n"); - } - - /* - We can now write out the results, using our custom - output routine as defined at the top of this file. - */ - ldb_ldif_write(ldb, vprintf_fn, NULL, ldifMsg); - - /* - Clean up the message - */ - ldb_ldif_read_free(ldb, ldifMsg); - } - - /* - Clean up the context - */ - talloc_free(ldb); - - return 0; -} diff --git a/ldb-2.0.8/include/dlinklist.h b/ldb-2.0.8/include/dlinklist.h deleted file mode 100644 index 822a826..0000000 --- a/ldb-2.0.8/include/dlinklist.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - Unix SMB/CIFS implementation. - some simple double linked list macros - - Copyright (C) Andrew Tridgell 1998-2010 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* To use these macros you must have a structure containing a next and - prev pointer */ - -#ifndef _DLINKLIST_H -#define _DLINKLIST_H - -/* - February 2010 - changed list format to have a prev pointer from the - list head. This makes DLIST_ADD_END() O(1) even though we only have - one list pointer. - - The scheme is as follows: - - 1) with no entries in the list: - list_head == NULL - - 2) with 1 entry in the list: - list_head->next == NULL - list_head->prev == list_head - - 3) with 2 entries in the list: - list_head->next == element2 - list_head->prev == element2 - element2->prev == list_head - element2->next == NULL - - 4) with N entries in the list: - list_head->next == element2 - list_head->prev == elementN - elementN->prev == element{N-1} - elementN->next == NULL - - This allows us to find the tail of the list by using - list_head->prev, which means we can add to the end of the list in - O(1) time - */ - - -/* - add an element at the front of a list -*/ -#define DLIST_ADD(list, p) \ -do { \ - if (!(list)) { \ - (p)->prev = (list) = (p); \ - (p)->next = NULL; \ - } else { \ - (p)->prev = (list)->prev; \ - (list)->prev = (p); \ - (p)->next = (list); \ - (list) = (p); \ - } \ -} while (0) - -/* - remove an element from a list - Note that the element doesn't have to be in the list. If it - isn't then this is a no-op -*/ -#define DLIST_REMOVE(list, p) \ -do { \ - if ((p) == (list)) { \ - if ((p)->next) (p)->next->prev = (p)->prev; \ - (list) = (p)->next; \ - } else if ((p)->prev && (list) && (p) == (list)->prev) { \ - (p)->prev->next = NULL; \ - (list)->prev = (p)->prev; \ - } else { \ - if ((p)->prev) (p)->prev->next = (p)->next; \ - if ((p)->next) (p)->next->prev = (p)->prev; \ - } \ - if ((p) != (list)) (p)->next = (p)->prev = NULL; \ -} while (0) - -/* - find the head of the list given any element in it. - Note that this costs O(N), so you should avoid this macro - if at all possible! -*/ -#define DLIST_HEAD(p, result_head) \ -do { \ - (result_head) = (p); \ - while (DLIST_PREV(result_head)) (result_head) = (result_head)->prev; \ -} while(0) - -/* return the last element in the list */ -#define DLIST_TAIL(list) ((list)?(list)->prev:NULL) - -/* return the previous element in the list. */ -#define DLIST_PREV(p) (((p)->prev && (p)->prev->next != NULL)?(p)->prev:NULL) - -/* insert 'p' after the given element 'el' in a list. If el is NULL then - this is the same as a DLIST_ADD() */ -#define DLIST_ADD_AFTER(list, p, el) \ -do { \ - if (!(list) || !(el)) { \ - DLIST_ADD(list, p); \ - } else { \ - (p)->prev = (el); \ - (p)->next = (el)->next; \ - (el)->next = (p); \ - if ((p)->next) (p)->next->prev = (p); \ - if ((list)->prev == (el)) (list)->prev = (p); \ - }\ -} while (0) - - -/* - add to the end of a list. -*/ -#define DLIST_ADD_END(list, p) \ -do { \ - if (!(list)) { \ - DLIST_ADD(list, p); \ - } else { \ - DLIST_ADD_AFTER(list, p, (list)->prev); \ - } \ -} while (0) - -/* promote an element to the front of a list */ -#define DLIST_PROMOTE(list, p) \ -do { \ - DLIST_REMOVE(list, p); \ - DLIST_ADD(list, p); \ -} while (0) - -/* - demote an element to the end of a list. -*/ -#define DLIST_DEMOTE(list, p) \ -do { \ - DLIST_REMOVE(list, p); \ - DLIST_ADD_END(list, p); \ -} while (0) - -/* - concatenate two lists - putting all elements of the 2nd list at the - end of the first list. -*/ -#define DLIST_CONCATENATE(list1, list2) \ -do { \ - if (!(list1)) { \ - (list1) = (list2); \ - } else { \ - (list1)->prev->next = (list2); \ - if (list2) { \ - void *_tmplist = (void *)(list1)->prev; \ - (list1)->prev = (list2)->prev; \ - (list2)->prev = _tmplist; \ - } \ - } \ -} while (0) - -#endif /* _DLINKLIST_H */ diff --git a/ldb-2.0.8/include/ldb.h b/ldb-2.0.8/include/ldb.h deleted file mode 100644 index 3cba0f4..0000000 --- a/ldb-2.0.8/include/ldb.h +++ /dev/null @@ -1,2365 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 2005-2006 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb header - * - * Description: defines for base ldb API - * - * Author: Andrew Tridgell - * Author: Stefan Metzmacher - */ - -/** - \file ldb.h Samba's ldb database - - This header file provides the main API for ldb. -*/ - -#ifndef _LDB_H_ - -/*! \cond DOXYGEN_IGNORE */ -#define _LDB_H_ 1 -/*! \endcond */ - -#include -#include -#include -#include -#include - -/* - major restrictions as compared to normal LDAP: - - - each record must have a unique key field - - the key must be representable as a NULL terminated C string and may not - contain a comma or braces - - major restrictions as compared to tdb: - - - no explicit locking calls, but we have transactions when using ldb_tdb - -*/ - -#ifndef ldb_val -/** - Result value - - An individual lump of data in a result comes in this format. The - pointer will usually be to a UTF-8 string if the application is - sensible, but it can be to anything you like, including binary data - blobs of arbitrary size. - - \note the data is null (0x00) terminated, but the length does not - include the terminator. -*/ -struct ldb_val { - uint8_t *data; /*!< result data */ - size_t length; /*!< length of data */ -}; -#endif - -/*! \cond DOXYGEN_IGNORE */ -#ifndef PRINTF_ATTRIBUTE -#define PRINTF_ATTRIBUTE(a,b) -#endif - -#ifndef _DEPRECATED_ -#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) -#define _DEPRECATED_ __attribute__ ((deprecated)) -#else -#define _DEPRECATED_ -#endif -#endif -/*! \endcond */ - -/* opaque ldb_dn structures, see ldb_dn.c for internals */ -struct ldb_dn_component; -struct ldb_dn; - -/** - There are a number of flags that are used with ldap_modify() in - ldb_message_element.flags fields. The LDB_FLAG_MOD_ADD, - LDB_FLAG_MOD_DELETE and LDB_FLAG_MOD_REPLACE are better thought of as - an enumeration, not flags, and are used in ldap_modify() calls to - specify whether attributes are being added, deleted or modified - respectively. -*/ -#define LDB_FLAG_MOD_MASK 0x3 - -/** - use this to extract the mod type (enum) from the operation - */ -#define LDB_FLAG_MOD_TYPE(flags) ((flags) & LDB_FLAG_MOD_MASK) - -/** - Value used in ldap_modify() to indicate that attributes are - being added. - - \sa LDB_FLAG_MOD_MASK -*/ -#define LDB_FLAG_MOD_ADD 1 - -/** - Value used in ldap_modify() to indicate that attributes are - being replaced. - - \sa LDB_FLAG_MOD_MASK -*/ -#define LDB_FLAG_MOD_REPLACE 2 - -/** - Value used in ldap_modify() to indicate that attributes are - being deleted. - - \sa LDB_FLAG_MOD_MASK -*/ -#define LDB_FLAG_MOD_DELETE 3 - -/** - Flag value used in ldb_ldif_write_trace() to enforce binary encoded - attribute values per attribute. - - This is a genuine flag, being outside LDB_FLAG_MOD_MASK and also - outside LDB_FLAG_INTERNAL_MASK -*/ -#define LDB_FLAG_FORCE_NO_BASE64_LDIF 4 - -/** - flag bits on an element usable only by the internal implementation -*/ -#define LDB_FLAG_INTERNAL_MASK 0xFFFFFFF0 - -/** - OID for logic AND comaprison. - - This is the well known object ID for a logical AND comparitor. -*/ -#define LDB_OID_COMPARATOR_AND "1.2.840.113556.1.4.803" - -/** - OID for logic OR comparison. - - This is the well known object ID for a logical OR comparitor. -*/ -#define LDB_OID_COMPARATOR_OR "1.2.840.113556.1.4.804" - -/** - results are given back as arrays of ldb_message_element -*/ -struct ldb_message_element { - unsigned int flags; - const char *name; - unsigned int num_values; - struct ldb_val *values; -}; - - -/** - a ldb_message represents all or part of a record. It can contain an arbitrary - number of elements. -*/ -struct ldb_message { - struct ldb_dn *dn; - unsigned int num_elements; - struct ldb_message_element *elements; -}; - -enum ldb_changetype { - LDB_CHANGETYPE_NONE=0, - LDB_CHANGETYPE_ADD, - LDB_CHANGETYPE_DELETE, - LDB_CHANGETYPE_MODIFY, - LDB_CHANGETYPE_MODRDN -}; - -/** - LDIF record - - This structure contains a LDIF record, as returned from ldif_read() - and equivalent functions. -*/ -struct ldb_ldif { - enum ldb_changetype changetype; /*!< The type of change */ - struct ldb_message *msg; /*!< The changes */ -}; - -enum ldb_scope {LDB_SCOPE_DEFAULT=-1, - LDB_SCOPE_BASE=0, - LDB_SCOPE_ONELEVEL=1, - LDB_SCOPE_SUBTREE=2}; - -struct ldb_context; -struct tevent_context; - -/* debugging uses one of the following levels */ -enum ldb_debug_level {LDB_DEBUG_FATAL, LDB_DEBUG_ERROR, - LDB_DEBUG_WARNING, LDB_DEBUG_TRACE}; - -/* alias for something that's not a fatal error but we really want to log */ -#define LDB_DEBUG_ALWAYS_LOG LDB_DEBUG_FATAL - -/** - the user can optionally supply a debug function. The function - is based on the vfprintf() style of interface, but with the addition - of a severity level -*/ -struct ldb_debug_ops { - void (*debug)(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); - void *context; -}; - -/** - The user can optionally supply a custom utf8 functions, - to handle comparisons and casefolding. -*/ -struct ldb_utf8_fns { - void *context; - char *(*casefold)(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n); -}; - -/** - Flag value for database connection mode. - - If LDB_FLG_RDONLY is used in ldb_connect, then the database will be - opened read-only, if possible. -*/ -#define LDB_FLG_RDONLY 1 - -/** - Flag value for database connection mode. - - If LDB_FLG_NOSYNC is used in ldb_connect, then the database will be - opened without synchronous operations, if possible. -*/ -#define LDB_FLG_NOSYNC 2 - -/** - Flag value to specify autoreconnect mode. - - If LDB_FLG_RECONNECT is used in ldb_connect, then the backend will - be opened in a way that makes it try to auto reconnect if the - connection is dropped (actually make sense only with ldap). -*/ -#define LDB_FLG_RECONNECT 4 - -/** - Flag to tell backends not to use mmap -*/ -#define LDB_FLG_NOMMAP 8 - -/** - Flag to tell ldif handlers not to force encoding of binary - structures in base64 -*/ -#define LDB_FLG_SHOW_BINARY 16 - -/** - Flags to enable ldb tracing -*/ -#define LDB_FLG_ENABLE_TRACING 32 - -/** - Flags to tell LDB not to create a new database file: - - Without this flag ldb_tdb (for example) will create a blank file - during an invocation of ldb_connect(), even when the caller only - wanted read operations, for example in ldbsearch. -*/ -#define LDB_FLG_DONT_CREATE_DB 64 - -/* - structures for ldb_parse_tree handling code -*/ -enum ldb_parse_op { LDB_OP_AND=1, LDB_OP_OR=2, LDB_OP_NOT=3, - LDB_OP_EQUALITY=4, LDB_OP_SUBSTRING=5, - LDB_OP_GREATER=6, LDB_OP_LESS=7, LDB_OP_PRESENT=8, - LDB_OP_APPROX=9, LDB_OP_EXTENDED=10 }; - -struct ldb_parse_tree { - enum ldb_parse_op operation; - union { - struct { - struct ldb_parse_tree *child; - } isnot; - struct { - const char *attr; - struct ldb_val value; - } equality; - struct { - const char *attr; - int start_with_wildcard; - int end_with_wildcard; - struct ldb_val **chunks; - } substring; - struct { - const char *attr; - } present; - struct { - const char *attr; - struct ldb_val value; - } comparison; - struct { - const char *attr; - int dnAttributes; - const char *rule_id; - struct ldb_val value; - } extended; - struct { - unsigned int num_elements; - struct ldb_parse_tree **elements; - } list; - } u; -}; - -struct ldb_parse_tree *ldb_parse_tree(TALLOC_CTX *mem_ctx, const char *s); -char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, const struct ldb_parse_tree *tree); - -/** - Encode a binary blob - - This function encodes a binary blob using the encoding rules in RFC - 2254 (Section 4). This function also escapes any non-printable - characters. - - \param mem_ctx the memory context to allocate the return string in. - \param val the (potentially) binary data to be encoded - - \return the encoded data as a null terminated string - - \sa RFC 2252. -*/ -char *ldb_binary_encode(TALLOC_CTX *mem_ctx, struct ldb_val val); - -/** - Encode a string - - This function encodes a string using the encoding rules in RFC 2254 - (Section 4). This function also escapes any non-printable - characters. - - \param mem_ctx the memory context to allocate the return string in. - \param string the string to be encoded - - \return the encoded data as a null terminated string - - \sa RFC 2252. -*/ -char *ldb_binary_encode_string(TALLOC_CTX *mem_ctx, const char *string); - -/* - functions for controlling attribute handling -*/ -typedef int (*ldb_attr_handler_t)(struct ldb_context *, TALLOC_CTX *mem_ctx, const struct ldb_val *, struct ldb_val *); -typedef int (*ldb_attr_comparison_t)(struct ldb_context *, TALLOC_CTX *mem_ctx, const struct ldb_val *, const struct ldb_val *); -struct ldb_schema_attribute; -typedef int (*ldb_attr_operator_t)(struct ldb_context *, enum ldb_parse_op operation, - const struct ldb_schema_attribute *a, - const struct ldb_val *, const struct ldb_val *, bool *matched); - -/* - attribute handler structure - - attr -> The attribute name - ldif_read_fn -> convert from ldif to binary format - ldif_write_fn -> convert from binary to ldif format - canonicalise_fn -> canonicalise a value, for use by indexing and dn construction - index_form_fn -> get lexicographically sorted format for index - comparison_fn -> compare two values - operator_fn -> override function for optimizing out unnecessary - calls to canonicalise_fn and comparison_fn -*/ - -struct ldb_schema_syntax { - const char *name; - ldb_attr_handler_t ldif_read_fn; - ldb_attr_handler_t ldif_write_fn; - ldb_attr_handler_t canonicalise_fn; - ldb_attr_handler_t index_format_fn; - ldb_attr_comparison_t comparison_fn; - ldb_attr_operator_t operator_fn; -}; - -struct ldb_schema_attribute { - const char *name; - unsigned flags; - const struct ldb_schema_syntax *syntax; -}; - -const struct ldb_schema_attribute *ldb_schema_attribute_by_name(struct ldb_context *ldb, - const char *name); - -struct ldb_dn_extended_syntax { - const char *name; - ldb_attr_handler_t read_fn; - ldb_attr_handler_t write_clear_fn; - ldb_attr_handler_t write_hex_fn; -}; - -const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_context *ldb, - const char *name); - -/** - The attribute is not returned by default -*/ -#define LDB_ATTR_FLAG_HIDDEN (1<<0) - -/* the attribute handler name should be freed when released */ -#define LDB_ATTR_FLAG_ALLOCATED (1<<1) - -/** - The attribute is supplied by the application and should not be removed -*/ -#define LDB_ATTR_FLAG_FIXED (1<<2) - -/* - when this is set, attempts to create two records which have the same - value for this attribute will return LDB_ERR_ENTRY_ALREADY_EXISTS - */ -#define LDB_ATTR_FLAG_UNIQUE_INDEX (1<<3) - -/* - when this is set, attempts to create two attribute values for this attribute on a single DN will return LDB_ERR_CONSTRAINT_VIOLATION - */ -#define LDB_ATTR_FLAG_SINGLE_VALUE (1<<4) - -/* - * The values should always be base64 encoded - */ -#define LDB_ATTR_FLAG_FORCE_BASE64_LDIF (1<<5) - -/* - * The attribute was loaded from a DB, rather than via the C API - */ -#define LDB_ATTR_FLAG_FROM_DB (1<<6) - -/* - * The attribute is indexed - */ -#define LDB_ATTR_FLAG_INDEXED (1<<7) - -/** - LDAP attribute syntax for a DN - - This is the well-known LDAP attribute syntax for a DN. - - See RFC 2252, Section 4.3.2 -*/ -#define LDB_SYNTAX_DN "1.3.6.1.4.1.1466.115.121.1.12" - -/** - LDAP attribute syntax for a Directory String - - This is the well-known LDAP attribute syntax for a Directory String. - - \sa RFC 2252, Section 4.3.2 -*/ -#define LDB_SYNTAX_DIRECTORY_STRING "1.3.6.1.4.1.1466.115.121.1.15" - -/** - LDAP attribute syntax for an integer - - This is the well-known LDAP attribute syntax for an integer. - - See RFC 2252, Section 4.3.2 -*/ -#define LDB_SYNTAX_INTEGER "1.3.6.1.4.1.1466.115.121.1.27" - -/** - Custom attribute syntax for an integer whose index is lexicographically - ordered by attribute value in the database. -*/ -#define LDB_SYNTAX_ORDERED_INTEGER "LDB_SYNTAX_ORDERED_INTEGER" - -/** - LDAP attribute syntax for a boolean - - This is the well-known LDAP attribute syntax for a boolean. - - See RFC 2252, Section 4.3.2 -*/ -#define LDB_SYNTAX_BOOLEAN "1.3.6.1.4.1.1466.115.121.1.7" - -/** - LDAP attribute syntax for an octet string - - This is the well-known LDAP attribute syntax for an octet string. - - See RFC 2252, Section 4.3.2 -*/ -#define LDB_SYNTAX_OCTET_STRING "1.3.6.1.4.1.1466.115.121.1.40" - -/** - LDAP attribute syntax for UTC time. - - This is the well-known LDAP attribute syntax for a UTC time. - - See RFC 2252, Section 4.3.2 -*/ -#define LDB_SYNTAX_UTC_TIME "1.3.6.1.4.1.1466.115.121.1.53" -#define LDB_SYNTAX_GENERALIZED_TIME "1.3.6.1.4.1.1466.115.121.1.24" - -#define LDB_SYNTAX_OBJECTCLASS "LDB_SYNTAX_OBJECTCLASS" - -/* sorting helpers */ -typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque); - -/* Individual controls */ - -/** - OID for getting and manipulating attributes from the ldb - without interception in the operational module. - It can be used to access attribute that used to be stored in the sam - and that are now calculated. -*/ -#define LDB_CONTROL_BYPASS_OPERATIONAL_OID "1.3.6.1.4.1.7165.4.3.13" -#define LDB_CONTROL_BYPASS_OPERATIONAL_NAME "bypassoperational" - -/** - OID for recalculate RDN (rdn attribute and 'name') control. This control forces - the rdn_name module to the recalculate the rdn and name attributes as if the - object was just created. -*/ -#define LDB_CONTROL_RECALCULATE_RDN_OID "1.3.6.1.4.1.7165.4.3.30" - -/** - OID for recalculate SD control. This control force the - dsdb code to recalculate the SD of the object as if the - object was just created. - -*/ -#define LDB_CONTROL_RECALCULATE_SD_OID "1.3.6.1.4.1.7165.4.3.5" -#define LDB_CONTROL_RECALCULATE_SD_NAME "recalculate_sd" - -/** - REVEAL_INTERNALS is used to reveal internal attributes and DN - components which are not normally shown to the user -*/ -#define LDB_CONTROL_REVEAL_INTERNALS "1.3.6.1.4.1.7165.4.3.6" -#define LDB_CONTROL_REVEAL_INTERNALS_NAME "reveal_internals" - -/** - LDB_CONTROL_AS_SYSTEM is used to skip access checks on operations - that are performed by the system, but with a user's credentials, e.g. - updating prefix map -*/ -#define LDB_CONTROL_AS_SYSTEM_OID "1.3.6.1.4.1.7165.4.3.7" - -/** - LDB_CONTROL_PROVISION_OID is used to skip some constraint checks. It's is - mainly thought to be used for the provisioning. -*/ -#define LDB_CONTROL_PROVISION_OID "1.3.6.1.4.1.7165.4.3.16" -#define LDB_CONTROL_PROVISION_NAME "provision" - -/* AD controls */ - -/** - OID for the paged results control. This control is included in the - searchRequest and searchResultDone messages as part of the controls - field of the LDAPMessage, as defined in Section 4.1.12 of - LDAP v3. - - \sa RFC 2696. -*/ -#define LDB_CONTROL_PAGED_RESULTS_OID "1.2.840.113556.1.4.319" -#define LDB_CONTROL_PAGED_RESULTS_NAME "paged_results" - -/** - OID for specifying the returned elements of the ntSecurityDescriptor - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_SD_FLAGS_OID "1.2.840.113556.1.4.801" -#define LDB_CONTROL_SD_FLAGS_NAME "sd_flags" - -/** - OID for specifying an advanced scope for the search (one partition) - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_DOMAIN_SCOPE_OID "1.2.840.113556.1.4.1339" -#define LDB_CONTROL_DOMAIN_SCOPE_NAME "domain_scope" - -/** - OID for specifying an advanced scope for a search - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_SEARCH_OPTIONS_OID "1.2.840.113556.1.4.1340" -#define LDB_CONTROL_SEARCH_OPTIONS_NAME "search_options" - -/** - OID for notification - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_NOTIFICATION_OID "1.2.840.113556.1.4.528" -#define LDB_CONTROL_NOTIFICATION_NAME "notification" - -/** - OID for performing subtree deletes - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_TREE_DELETE_OID "1.2.840.113556.1.4.805" -#define LDB_CONTROL_TREE_DELETE_NAME "tree_delete" - -/** - OID for getting deleted objects - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_SHOW_DELETED_OID "1.2.840.113556.1.4.417" -#define LDB_CONTROL_SHOW_DELETED_NAME "show_deleted" - -/** - OID for getting recycled objects - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_SHOW_RECYCLED_OID "1.2.840.113556.1.4.2064" -#define LDB_CONTROL_SHOW_RECYCLED_NAME "show_recycled" - -/** - OID for getting deactivated linked attributes - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID "1.2.840.113556.1.4.2065" -#define LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME "show_deactivated_link" - -/** - OID for extended DN - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_EXTENDED_DN_OID "1.2.840.113556.1.4.529" -#define LDB_CONTROL_EXTENDED_DN_NAME "extended_dn" - -/** - OID for LDAP server sort result extension. - - This control is included in the searchRequest message as part of - the controls field of the LDAPMessage, as defined in Section 4.1.12 - of LDAP v3. The controlType is set to - "1.2.840.113556.1.4.473". The criticality MAY be either TRUE or - FALSE (where absent is also equivalent to FALSE) at the client's - option. - - \sa RFC 2891. -*/ -#define LDB_CONTROL_SERVER_SORT_OID "1.2.840.113556.1.4.473" -#define LDB_CONTROL_SERVER_SORT_NAME "server_sort" - -/** - OID for LDAP server sort result response extension. - - This control is included in the searchResultDone message as part of - the controls field of the LDAPMessage, as defined in Section 4.1.12 of - LDAP v3. - - \sa RFC 2891. -*/ -#define LDB_CONTROL_SORT_RESP_OID "1.2.840.113556.1.4.474" -#define LDB_CONTROL_SORT_RESP_NAME "server_sort_resp" - -/** - OID for LDAP Attribute Scoped Query extension. - - This control is included in SearchRequest or SearchResponse - messages as part of the controls field of the LDAPMessage. -*/ -#define LDB_CONTROL_ASQ_OID "1.2.840.113556.1.4.1504" -#define LDB_CONTROL_ASQ_NAME "asq" - -/** - OID for LDAP Directory Sync extension. - - This control is included in SearchRequest or SearchResponse - messages as part of the controls field of the LDAPMessage. -*/ -#define LDB_CONTROL_DIRSYNC_OID "1.2.840.113556.1.4.841" -#define LDB_CONTROL_DIRSYNC_NAME "dirsync" -#define LDB_CONTROL_DIRSYNC_EX_OID "1.2.840.113556.1.4.2090" -#define LDB_CONTROL_DIRSYNC_EX_NAME "dirsync_ex" - - -/** - OID for LDAP Virtual List View Request extension. - - This control is included in SearchRequest messages - as part of the controls field of the LDAPMessage. -*/ -#define LDB_CONTROL_VLV_REQ_OID "2.16.840.1.113730.3.4.9" -#define LDB_CONTROL_VLV_REQ_NAME "vlv" - -/** - OID for LDAP Virtual List View Response extension. - - This control is included in SearchResponse messages - as part of the controls field of the LDAPMessage. -*/ -#define LDB_CONTROL_VLV_RESP_OID "2.16.840.1.113730.3.4.10" -#define LDB_CONTROL_VLV_RESP_NAME "vlv_resp" - -/** - OID to let modifies don't give an error when adding an existing - attribute with the same value or deleting an nonexisting one attribute - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_PERMISSIVE_MODIFY_OID "1.2.840.113556.1.4.1413" -#define LDB_CONTROL_PERMISSIVE_MODIFY_NAME "permissive_modify" - -/** - OID to allow the server to be more 'fast and loose' with the data being added. - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_SERVER_LAZY_COMMIT "1.2.840.113556.1.4.619" - -/** - Control for RODC join -see [MS-ADTS] section 3.1.1.3.4.1.23 - - \sa Microsoft documentation of this OID -*/ -#define LDB_CONTROL_RODC_DCPROMO_OID "1.2.840.113556.1.4.1341" -#define LDB_CONTROL_RODC_DCPROMO_NAME "rodc_join" - -/* Other standardised controls */ - -/** - OID for the allowing client to request temporary relaxed - enforcement of constraints of the x.500 model. - - Mainly used for the OpenLDAP backend. - - \sa draft managedit. -*/ -#define LDB_CONTROL_RELAX_OID "1.3.6.1.4.1.4203.666.5.12" -#define LDB_CONTROL_RELAX_NAME "relax" - -/** - OID for the allowing some kind of relax check for attributes with DNs - - - \sa 3.1.1.3.4.1.16 in [MS-ADTS].pdf -*/ -#define LDB_CONTROL_VERIFY_NAME_OID "1.2.840.113556.1.4.1338" -#define LDB_CONTROL_VERIFY_NAME_NAME "verify_name" - -/* Extended operations */ - -/** - OID for LDAP Extended Operation SEQUENCE_NUMBER - - This extended operation is used to retrieve the extended sequence number. -*/ -#define LDB_EXTENDED_SEQUENCE_NUMBER "1.3.6.1.4.1.7165.4.4.3" - -/** - OID for LDAP Extended Operation PASSWORD_CHANGE. - - This Extended operation is used to allow user password changes by the user - itself. -*/ -#define LDB_EXTENDED_PASSWORD_CHANGE_OID "1.3.6.1.4.1.4203.1.11.1" - - -/** - OID for LDAP Extended Operation FAST_BIND - - This Extended operations is used to perform a fast bind. -*/ -#define LDB_EXTENDED_FAST_BIND_OID "1.2.840.113556.1.4.1781" - -/** - OID for LDAP Extended Operation START_TLS. - - This Extended operation is used to start a new TLS channel on top of a clear - text channel. -*/ -#define LDB_EXTENDED_START_TLS_OID "1.3.6.1.4.1.1466.20037" - -/** - OID for LDAP Extended Operation DYNAMIC_REFRESH. - - This Extended operation is used to create and maintain objects which exist - only a specific time, e.g. when a certain client or a certain person is - logged in. Data refreshes have to be periodically sent in a specific - interval. Otherwise the entry is going to be removed. -*/ -#define LDB_EXTENDED_DYNAMIC_OID "1.3.6.1.4.1.1466.101.119.1" - -struct ldb_sd_flags_control { - /* - * request the owner 0x00000001 - * request the group 0x00000002 - * request the DACL 0x00000004 - * request the SACL 0x00000008 - */ - unsigned secinfo_flags; -}; - -/* - * DOMAIN_SCOPE 0x00000001 - * this limits the search to one partition, - * and no referrals will be returned. - * (Note this doesn't limit the entries by there - * objectSid belonging to a domain! Builtin and Foreign Sids - * are still returned) - * - * PHANTOM_ROOT 0x00000002 - * this search on the whole tree on a domain controller - * over multiple partitions without referrals. - * (This is the default behavior on the Global Catalog Port) - */ - -#define LDB_SEARCH_OPTION_DOMAIN_SCOPE 0x00000001 -#define LDB_SEARCH_OPTION_PHANTOM_ROOT 0x00000002 - -struct ldb_search_options_control { - unsigned search_options; -}; - -struct ldb_paged_control { - int size; - int cookie_len; - char *cookie; -}; - -struct ldb_extended_dn_control { - int type; -}; - -struct ldb_server_sort_control { - const char *attributeName; - const char *orderingRule; - int reverse; -}; - -struct ldb_sort_resp_control { - int result; - char *attr_desc; -}; - -struct ldb_asq_control { - int request; - char *source_attribute; - int src_attr_len; - int result; -}; - -struct ldb_dirsync_control { - int flags; - int max_attributes; - int cookie_len; - char *cookie; -}; - -struct ldb_vlv_req_control { - int beforeCount; - int afterCount; - int type; - union { - struct { - int offset; - int contentCount; - } byOffset; - struct { - int value_len; - char *value; - } gtOrEq; - } match; - int ctxid_len; - uint8_t *contextId; -}; - -struct ldb_vlv_resp_control { - int targetPosition; - int contentCount; - int vlv_result; - int ctxid_len; - uint8_t *contextId; -}; - -struct ldb_verify_name_control { - int flags; - size_t gc_len; - char *gc; -}; - -struct ldb_control { - const char *oid; - int critical; - void *data; -}; - -enum ldb_request_type { - LDB_SEARCH, - LDB_ADD, - LDB_MODIFY, - LDB_DELETE, - LDB_RENAME, - LDB_EXTENDED, - LDB_REQ_REGISTER_CONTROL, - LDB_REQ_REGISTER_PARTITION -}; - -enum ldb_reply_type { - LDB_REPLY_ENTRY, - LDB_REPLY_REFERRAL, - LDB_REPLY_DONE -}; - -enum ldb_wait_type { - LDB_WAIT_ALL, - LDB_WAIT_NONE -}; - -enum ldb_state { - LDB_ASYNC_INIT, - LDB_ASYNC_PENDING, - LDB_ASYNC_DONE -}; - -struct ldb_extended { - const char *oid; - void *data; /* NULL or a valid talloc pointer! talloc_get_type() will be used on it */ -}; - -enum ldb_sequence_type { - LDB_SEQ_HIGHEST_SEQ, - LDB_SEQ_HIGHEST_TIMESTAMP, - LDB_SEQ_NEXT -}; - -#define LDB_SEQ_GLOBAL_SEQUENCE 0x01 -#define LDB_SEQ_TIMESTAMP_SEQUENCE 0x02 - -struct ldb_seqnum_request { - enum ldb_sequence_type type; -}; - -struct ldb_seqnum_result { - uint64_t seq_num; - uint32_t flags; -}; - -struct ldb_result { - unsigned int count; - struct ldb_message **msgs; - struct ldb_extended *extended; - struct ldb_control **controls; - char **refs; -}; - -struct ldb_reply { - int error; - enum ldb_reply_type type; - struct ldb_message *message; - struct ldb_extended *response; - struct ldb_control **controls; - char *referral; -}; - -struct ldb_request; -struct ldb_handle; - -struct ldb_search { - struct ldb_dn *base; - enum ldb_scope scope; - struct ldb_parse_tree *tree; - const char * const *attrs; - struct ldb_result *res; -}; - -struct ldb_add { - const struct ldb_message *message; -}; - -struct ldb_modify { - const struct ldb_message *message; -}; - -struct ldb_delete { - struct ldb_dn *dn; -}; - -struct ldb_rename { - struct ldb_dn *olddn; - struct ldb_dn *newdn; -}; - -struct ldb_register_control { - const char *oid; -}; - -struct ldb_register_partition { - struct ldb_dn *dn; -}; - -typedef int (*ldb_request_callback_t)(struct ldb_request *, struct ldb_reply *); - -struct ldb_request { - - enum ldb_request_type operation; - - union { - struct ldb_search search; - struct ldb_add add; - struct ldb_modify mod; - struct ldb_delete del; - struct ldb_rename rename; - struct ldb_extended extended; - struct ldb_register_control reg_control; - struct ldb_register_partition reg_partition; - } op; - - struct ldb_control **controls; - - void *context; - ldb_request_callback_t callback; - - int timeout; - time_t starttime; - struct ldb_handle *handle; -}; - -int ldb_request(struct ldb_context *ldb, struct ldb_request *request); -int ldb_request_done(struct ldb_request *req, int status); -bool ldb_request_is_done(struct ldb_request *req); - -int ldb_modules_wait(struct ldb_handle *handle); -int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type); - -int ldb_set_timeout(struct ldb_context *ldb, struct ldb_request *req, int timeout); -int ldb_set_timeout_from_prev_req(struct ldb_context *ldb, struct ldb_request *oldreq, struct ldb_request *newreq); -void ldb_set_create_perms(struct ldb_context *ldb, unsigned int perms); -void ldb_set_modules_dir(struct ldb_context *ldb, const char *path); -struct tevent_context; -void ldb_set_event_context(struct ldb_context *ldb, struct tevent_context *ev); -struct tevent_context * ldb_get_event_context(struct ldb_context *ldb); - -/** - Initialise ldbs' global information - - This is required before any other LDB call - - \return 0 if initialisation succeeded, -1 otherwise -*/ -int ldb_global_init(void); - -/** - Initialise an ldb context - - This is required before any other LDB call. - - \param mem_ctx pointer to a talloc memory context. Pass NULL if there is - no suitable context available. - - \note The LDB modules will be loaded from directory specified by the environment - variable LDB_MODULES_PATH. If the variable is not specified, the compiled-in default - is used. - - \return pointer to ldb_context that should be free'd (using talloc_free()) - at the end of the program. -*/ -struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx); - -typedef void (*ldb_async_timeout_fn) (void *); -typedef bool (*ldb_async_callback_fn) (void *); -typedef int (*ldb_async_ctx_add_op_fn)(void *, time_t, void *, ldb_async_timeout_fn, ldb_async_callback_fn); -typedef int (*ldb_async_ctx_wait_op_fn)(void *); - -void ldb_async_ctx_set_private_data(struct ldb_context *ldb, - void *private_data); -void ldb_async_ctx_set_add_op(struct ldb_context *ldb, - ldb_async_ctx_add_op_fn add_op); -void ldb_async_ctx_set_wait_op(struct ldb_context *ldb, - ldb_async_ctx_wait_op_fn wait_op); - -/** - Connect to a database. - - This is typically called soon after ldb_init(), and is required prior to - any search or database modification operations. - - The URL can be one of the following forms: - - tdb://path - - ldapi://path - - ldap://host - - sqlite://path - - \param ldb the context associated with the database (from ldb_init()) - \param url the URL of the database to connect to, as noted above - \param flags a combination of LDB_FLG_* to modify the connection behaviour - \param options backend specific options - passed uninterpreted to the backend - - \return result code (LDB_SUCCESS on success, or a failure code) - - \note It is an error to connect to a database that does not exist in readonly mode - (that is, with LDB_FLG_RDONLY). However in read-write mode, the database will be - created if it does not exist. -*/ -int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[]); - -/* - return an automatic basedn from the rootDomainNamingContext of the rootDSE - This value have been set in an opaque pointer at connection time -*/ -struct ldb_dn *ldb_get_root_basedn(struct ldb_context *ldb); - -/* - return an automatic basedn from the configurationNamingContext of the rootDSE - This value have been set in an opaque pointer at connection time -*/ -struct ldb_dn *ldb_get_config_basedn(struct ldb_context *ldb); - -/* - return an automatic basedn from the schemaNamingContext of the rootDSE - This value have been set in an opaque pointer at connection time -*/ -struct ldb_dn *ldb_get_schema_basedn(struct ldb_context *ldb); - -/* - return an automatic baseDN from the defaultNamingContext of the rootDSE - This value have been set in an opaque pointer at connection time -*/ -struct ldb_dn *ldb_get_default_basedn(struct ldb_context *ldb); - -/** - The default async search callback function - - \param req the request we are callback of - \param ares a single reply from the async core - - \return result code (LDB_SUCCESS on success, or a failure code) - - \note this function expects req->context to always be an struct ldb_result pointer - AND a talloc context, this function will steal on the context each message - from the ares reply passed on by the async core so that in the end all the - messages will be in the context (ldb_result) memory tree. - Freeing the passed context (ldb_result tree) will free all the resources - (the request need to be freed separately and the result doe not depend on the - request that can be freed as sson as the search request is finished) -*/ - -int ldb_search_default_callback(struct ldb_request *req, struct ldb_reply *ares); - -/** - The default async extended operation callback function - - \param req the request we are callback of - \param ares a single reply from the async core - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ -int ldb_op_default_callback(struct ldb_request *req, struct ldb_reply *ares); - -int ldb_modify_default_callback(struct ldb_request *req, struct ldb_reply *ares); - -/** - Helper function to build a search request - - \param ret_req the request structure is returned here (talloced on mem_ctx) - \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc memory context (used as parent of ret_req) - \param base the Base Distinguished Name for the query (use ldb_dn_new() for an empty one) - \param scope the search scope for the query - \param expression the search expression to use for this query - \param attrs the search attributes for the query (pass NULL if none required) - \param controls an array of controls - \param context the callback function context - \param the callback function to handle the async replies - \param the parent request if any - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ - -int ldb_build_search_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_dn *base, - enum ldb_scope scope, - const char *expression, - const char * const *attrs, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent); - -int ldb_build_search_req_ex(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_dn *base, - enum ldb_scope scope, - struct ldb_parse_tree *tree, - const char * const *attrs, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent); - -/** - Helper function to build an add request - - \param ret_req the request structure is returned here (talloced on mem_ctx) - \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc memory context (used as parent of ret_req) - \param message contains the entry to be added - \param controls an array of controls - \param context the callback function context - \param the callback function to handle the async replies - \param the parent request if any - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ - -int ldb_build_add_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const struct ldb_message *message, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent); - -/** - Helper function to build a modify request - - \param ret_req the request structure is returned here (talloced on mem_ctx) - \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc memory context (used as parent of ret_req) - \param message contains the entry to be modified - \param controls an array of controls - \param context the callback function context - \param the callback function to handle the async replies - \param the parent request if any - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ - -int ldb_build_mod_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const struct ldb_message *message, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent); - -/** - Helper function to build a delete request - - \param ret_req the request structure is returned here (talloced on mem_ctx) - \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc memory context (used as parent of ret_req) - \param dn the DN to be deleted - \param controls an array of controls - \param context the callback function context - \param the callback function to handle the async replies - \param the parent request if any - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ - -int ldb_build_del_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_dn *dn, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent); - -/** - Helper function to build a rename request - - \param ret_req the request structure is returned here (talloced on mem_ctx) - \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc memory context (used as parent of ret_req) - \param olddn the old DN - \param newdn the new DN - \param controls an array of controls - \param context the callback function context - \param the callback function to handle the async replies - \param the parent request if any - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ - -int ldb_build_rename_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_dn *olddn, - struct ldb_dn *newdn, - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent); - -/** - Add a ldb_control to a ldb_request - - \param req the request struct where to add the control - \param oid the object identifier of the control as string - \param critical whether the control should be critical or not - \param data a talloc pointer to the control specific data - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ -int ldb_request_add_control(struct ldb_request *req, const char *oid, bool critical, void *data); - -/** - replace a ldb_control in a ldb_request - - \param req the request struct where to add the control - \param oid the object identifier of the control as string - \param critical whether the control should be critical or not - \param data a talloc pointer to the control specific data - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ -int ldb_request_replace_control(struct ldb_request *req, const char *oid, bool critical, void *data); - -/** - check if a control with the specified "oid" exist and return it - \param req the request struct where to add the control - \param oid the object identifier of the control as string - - \return the control, NULL if not found -*/ -struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid); - -/** - check if a control with the specified "oid" exist and return it - \param rep the reply struct where to add the control - \param oid the object identifier of the control as string - - \return the control, NULL if not found -*/ -struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid); - -/** - Search the database - - This function searches the database, and returns - records that match an LDAP-like search expression - - \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx the memory context to use for the request and the results - \param result the return result - \param base the Base Distinguished Name for the query (use ldb_dn_new() for an empty one) - \param scope the search scope for the query - \param attrs the search attributes for the query (pass NULL if none required) - \param exp_fmt the search expression to use for this query (printf like) - - \return result code (LDB_SUCCESS on success, or a failure code) - - \note use talloc_free() to free the ldb_result returned -*/ -int ldb_search(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - struct ldb_result **result, struct ldb_dn *base, - enum ldb_scope scope, const char * const *attrs, - const char *exp_fmt, ...) PRINTF_ATTRIBUTE(7,8); - -/** - Add a record to the database. - - This function adds a record to the database. This function will fail - if a record with the specified class and key already exists in the - database. - - \param ldb the context associated with the database (from - ldb_init()) - \param message the message containing the record to add. - - \return result code (LDB_SUCCESS if the record was added, otherwise - a failure code) -*/ -int ldb_add(struct ldb_context *ldb, - const struct ldb_message *message); - -/** - Modify the specified attributes of a record - - This function modifies a record that is in the database. - - \param ldb the context associated with the database (from - ldb_init()) - \param message the message containing the changes required. - - \return result code (LDB_SUCCESS if the record was modified as - requested, otherwise a failure code) -*/ -int ldb_modify(struct ldb_context *ldb, - const struct ldb_message *message); - -/** - Rename a record in the database - - This function renames a record in the database. - - \param ldb the context associated with the database (from - ldb_init()) - \param olddn the DN for the record to be renamed. - \param newdn the new DN - - \return result code (LDB_SUCCESS if the record was renamed as - requested, otherwise a failure code) -*/ -int ldb_rename(struct ldb_context *ldb, struct ldb_dn *olddn, struct ldb_dn *newdn); - -/** - Delete a record from the database - - This function deletes a record from the database. - - \param ldb the context associated with the database (from - ldb_init()) - \param dn the DN for the record to be deleted. - - \return result code (LDB_SUCCESS if the record was deleted, - otherwise a failure code) -*/ -int ldb_delete(struct ldb_context *ldb, struct ldb_dn *dn); - -/** - The default async extended operation callback function - - \param req the request we are callback of - \param ares a single reply from the async core - - \return result code (LDB_SUCCESS on success, or a failure code) - - \note this function expects req->context to always be an struct ldb_result pointer - AND a talloc context, this function will steal on the context each message - from the ares reply passed on by the async core so that in the end all the - messages will be in the context (ldb_result) memory tree. - Freeing the passed context (ldb_result tree) will free all the resources - (the request need to be freed separately and the result doe not depend on the - request that can be freed as sson as the search request is finished) -*/ - -int ldb_extended_default_callback(struct ldb_request *req, struct ldb_reply *ares); - - -/** - Helper function to build a extended request - - \param ret_req the request structure is returned here (talloced on mem_ctx) - \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc memory context (used as parent of ret_req) - \param oid the OID of the extended operation. - \param data a void pointer a the extended operation specific parameters, - it needs to be NULL or a valid talloc pointer! talloc_get_type() will be used on it - \param controls an array of controls - \param context the callback function context - \param the callback function to handle the async replies - \param the parent request if any - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ -int ldb_build_extended_req(struct ldb_request **ret_req, - struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const char *oid, - void *data,/* NULL or a valid talloc pointer! talloc_get_type() will be used on it */ - struct ldb_control **controls, - void *context, - ldb_request_callback_t callback, - struct ldb_request *parent); - -/** - call an extended operation - - \param ldb the context associated with the database (from ldb_init()) - \param oid the OID of the extended operation. - \param data a void pointer a the extended operation specific parameters, - it needs to be NULL or a valid talloc pointer! talloc_get_type() will be used on it - \param res the result of the extended operation - - \return result code (LDB_SUCCESS if the extended operation returned fine, - otherwise a failure code) -*/ -int ldb_extended(struct ldb_context *ldb, - const char *oid, - void *data,/* NULL or a valid talloc pointer! talloc_get_type() will be used on it */ - struct ldb_result **res); - -/** - Obtain current/next database sequence number -*/ -int ldb_sequence_number(struct ldb_context *ldb, enum ldb_sequence_type type, uint64_t *seq_num); - -/** - start a transaction -*/ -int ldb_transaction_start(struct ldb_context *ldb); - -/** - first phase of two phase commit - */ -int ldb_transaction_prepare_commit(struct ldb_context *ldb); - -/** - commit a transaction -*/ -int ldb_transaction_commit(struct ldb_context *ldb); - -/** - cancel a transaction -*/ -int ldb_transaction_cancel(struct ldb_context *ldb); - -/* - cancel a transaction with no error if no transaction is pending - used when we fork() to clear any parent transactions -*/ -int ldb_transaction_cancel_noerr(struct ldb_context *ldb); - - -/** - return extended error information from the last call -*/ -const char *ldb_errstring(struct ldb_context *ldb); - -/** - return a string explaining what a ldb error constant means -*/ -const char *ldb_strerror(int ldb_err); - -/** - setup the default utf8 functions - FIXME: these functions do not yet handle utf8 -*/ -void ldb_set_utf8_default(struct ldb_context *ldb); - -/** - Casefold a string - - \param ldb the ldb context - \param mem_ctx the memory context to allocate the result string - memory from. - \param s the string that is to be folded - \return a copy of the string, converted to upper case - - \note The default function is not yet UTF8 aware. Provide your own - set of functions through ldb_set_utf8_fns() -*/ -char *ldb_casefold(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *s, size_t n); - -/** - Check the attribute name is valid according to rfc2251 - \param s the string to check - - \return 1 if the name is ok -*/ -int ldb_valid_attr_name(const char *s); - -/* - ldif manipulation functions -*/ - -/** - Write an LDIF message - - This function writes an LDIF message using a caller supplied write - function. - - \param ldb the ldb context (from ldb_init()) - \param fprintf_fn a function pointer for the write function. This must take - a private data pointer, followed by a format string, and then a variable argument - list. - \param private_data pointer that will be provided back to the write - function. This is useful for maintaining state or context. - \param ldif the message to write out - - \return the total number of bytes written, or an error code as returned - from the write function. - - \sa ldb_ldif_write_file for a more convenient way to write to a - file stream. - - \sa ldb_ldif_read for the reader equivalent to this function. -*/ -int ldb_ldif_write(struct ldb_context *ldb, - int (*fprintf_fn)(void *, const char *, ...) PRINTF_ATTRIBUTE(2,3), - void *private_data, - const struct ldb_ldif *ldif); - -/** - Clean up an LDIF message - - This function cleans up a LDIF message read using ldb_ldif_read() - or related functions (such as ldb_ldif_read_string() and - ldb_ldif_read_file(). - - \param ldb the ldb context (from ldb_init()) - \param msg the message to clean up and free - -*/ -void ldb_ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *msg); - -/** - Read an LDIF message - - This function creates an LDIF message using a caller supplied read - function. - - \param ldb the ldb context (from ldb_init()) - \param fgetc_fn a function pointer for the read function. This must - take a private data pointer, and must return a pointer to an - integer corresponding to the next byte read (or EOF if there is no - more data to be read). - \param private_data pointer that will be provided back to the read - function. This is udeful for maintaining state or context. - - \return the LDIF message that has been read in - - \note You must free the LDIF message when no longer required, using - ldb_ldif_read_free(). - - \sa ldb_ldif_read_file for a more convenient way to read from a - file stream. - - \sa ldb_ldif_read_string for a more convenient way to read from a - string (char array). - - \sa ldb_ldif_write for the writer equivalent to this function. -*/ -struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, - int (*fgetc_fn)(void *), void *private_data); - -/** - Read an LDIF message from a file - - This function reads the next LDIF message from the contents of a - file stream. If you want to get all of the LDIF messages, you will - need to repeatedly call this function, until it returns NULL. - - \param ldb the ldb context (from ldb_init()) - \param f the file stream to read from (typically from fdopen()) - - \sa ldb_ldif_read_string for an equivalent function that will read - from a string (char array). - - \sa ldb_ldif_write_file for the writer equivalent to this function. - -*/ -struct ldb_ldif *ldb_ldif_read_file(struct ldb_context *ldb, FILE *f); - -/** - Read an LDIF message from a string - - This function reads the next LDIF message from the contents of a char - array. If you want to get all of the LDIF messages, you will need - to repeatedly call this function, until it returns NULL. - - \param ldb the ldb context (from ldb_init()) - \param s pointer to the char array to read from - - \sa ldb_ldif_read_file for an equivalent function that will read - from a file stream. - - \sa ldb_ldif_write for a more general (arbitrary read function) - version of this function. -*/ -struct ldb_ldif *ldb_ldif_read_string(struct ldb_context *ldb, const char **s); - -/** - Parse a modrdn LDIF message from a struct ldb_message - - \param ldb the ldb context (from ldb_init()) - \param ldif the preparsed LDIF chunk (from ldb_ldif_read()) - - \param mem_ctx the memory context that's used for return values - - \param olddn the old dn as struct ldb_dn, if not needed pass NULL - \param newrdn the new rdn as struct ldb_dn, if not needed pass NULL - \param deleteoldrdn the deleteoldrdn value as bool, if not needed pass NULL - \param newsuperior the newsuperior dn as struct ldb_dn, if not needed pass NULL - *newsuperior can be NULL as it is optional in the LDIF - \param newdn the full constructed new dn as struct ldb_dn, if not needed pass NULL - -*/ -int ldb_ldif_parse_modrdn(struct ldb_context *ldb, - const struct ldb_ldif *ldif, - TALLOC_CTX *mem_ctx, - struct ldb_dn **olddn, - struct ldb_dn **newrdn, - bool *deleteoldrdn, - struct ldb_dn **newsuperior, - struct ldb_dn **newdn); - -/** - Write an LDIF message to a file - - \param ldb the ldb context (from ldb_init()) - \param f the file stream to write to (typically from fdopen()) - \param msg the message to write out - - \return the total number of bytes written, or a negative error code - - \sa ldb_ldif_read_file for the reader equivalent to this function. -*/ -int ldb_ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif *msg); - -/** - Write an LDIF message to a string - - \param ldb the ldb context (from ldb_init()) - \param mem_ctx the talloc context on which to attach the string) - \param msg the message to write out - - \return the string containing the LDIF, or NULL on error - - \sa ldb_ldif_read_string for the reader equivalent to this function. -*/ -char * ldb_ldif_write_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - const struct ldb_ldif *msg); - - -/** - Write an LDB message to a string - - \param ldb the ldb context (from ldb_init()) - \param mem_ctx the talloc context on which to attach the string) - \param changetype LDB_CHANGETYPE_ADD or LDB_CHANGETYPE_MODIFY - \param msg the message to write out - - \return the string containing the LDIF, or NULL on error - - \sa ldb_ldif_message_redacted_string for a safer version of this - function -*/ -char *ldb_ldif_message_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - enum ldb_changetype changetype, - const struct ldb_message *msg); - -/** - Write an LDB message to a string - - \param ldb the ldb context (from ldb_init()) - \param mem_ctx the talloc context on which to attach the string) - \param changetype LDB_CHANGETYPE_ADD or LDB_CHANGETYPE_MODIFY - \param msg the message to write out - - \return the string containing the LDIF, or NULL on error, but - with secret attributes redacted - - \note The secret attributes are specified in a - 'const char * const *' within the LDB_SECRET_ATTRIBUTE_LIST - opaque set on the ldb - - \sa ldb_ldif_message_string for an exact representiation of the - message as LDIF -*/ -char *ldb_ldif_message_redacted_string(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - enum ldb_changetype changetype, - const struct ldb_message *msg); - - -/** - Base64 encode a buffer - - \param mem_ctx the memory context that the result is allocated - from. - \param buf pointer to the array that is to be encoded - \param len the number of elements in the array to be encoded - - \return pointer to an array containing the encoded data - - \note The caller is responsible for freeing the result -*/ -char *ldb_base64_encode(TALLOC_CTX *mem_ctx, const char *buf, int len); - -/** - Base64 decode a buffer - - This function decodes a base64 encoded string in place. - - \param s the string to decode. - - \return the length of the returned (decoded) string. - - \note the string is null terminated, but the null terminator is not - included in the length. -*/ -int ldb_base64_decode(char *s); - -/* The following definitions come from lib/ldb/common/ldb_dn.c */ - -/** - Get the linear form of a DN (without any extended components) - - \param dn The DN to linearize -*/ - -const char *ldb_dn_get_linearized(struct ldb_dn *dn); - -/** - Allocate a copy of the linear form of a DN (without any extended components) onto the supplied memory context - - \param dn The DN to linearize - \param mem_ctx TALLOC context to return result on -*/ - -char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); - -/** - Get the linear form of a DN (with any extended components) - - \param mem_ctx TALLOC context to return result on - \param dn The DN to linearize - \param mode Style of extended DN to return (0 is HEX representation of binary form, 1 is a string form) -*/ -char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode); -const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, const char *name); -int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const struct ldb_val *val); -void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list); -void ldb_dn_remove_extended_components(struct ldb_dn *dn); -bool ldb_dn_has_extended(struct ldb_dn *dn); - -int ldb_dn_extended_add_syntax(struct ldb_context *ldb, - unsigned flags, - const struct ldb_dn_extended_syntax *syntax); - -/** - Allocate a new DN from a string - - \param mem_ctx TALLOC context to return resulting ldb_dn structure on - \param dn The new DN - - \note The DN will not be parsed at this time. Use ldb_dn_validate to tell if the DN is syntacticly correct -*/ - -struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *dn); -/** - Allocate a new DN from a printf style format string and arguments - - \param mem_ctx TALLOC context to return resulting ldb_dn structure on - \param new_fms The new DN as a format string (plus arguments) - - \note The DN will not be parsed at this time. Use ldb_dn_validate to tell if the DN is syntacticly correct -*/ - -struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...) PRINTF_ATTRIBUTE(3,4); -/** - Allocate a new DN from a struct ldb_val (useful to avoid buffer overrun) - - \param mem_ctx TALLOC context to return resulting ldb_dn structure on - \param dn The new DN - - \note The DN will not be parsed at this time. Use ldb_dn_validate to tell if the DN is syntacticly correct -*/ - -struct ldb_dn *ldb_dn_from_ldb_val(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const struct ldb_val *strdn); - -/** - Determine if this DN is syntactically valid - - \param dn The DN to validate -*/ - -bool ldb_dn_validate(struct ldb_dn *dn); - -char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value); -const char *ldb_dn_get_casefold(struct ldb_dn *dn); -char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); - -int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn); -int ldb_dn_compare(struct ldb_dn *edn0, struct ldb_dn *edn1); - -bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base); -bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...) PRINTF_ATTRIBUTE(2,3); -bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child); -bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...) PRINTF_ATTRIBUTE(2,3); -bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num); -bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num); -bool ldb_dn_add_child_val(struct ldb_dn *dn, - const char *rdn, - struct ldb_val value); - -struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); -struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); -char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); -char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn); -int ldb_dn_get_comp_num(struct ldb_dn *dn); -int ldb_dn_get_extended_comp_num(struct ldb_dn *dn); -const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num); -const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, unsigned int num); -const char *ldb_dn_get_rdn_name(struct ldb_dn *dn); -const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn); -int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val); - -bool ldb_dn_is_valid(struct ldb_dn *dn); -bool ldb_dn_is_special(struct ldb_dn *dn); -bool ldb_dn_check_special(struct ldb_dn *dn, const char *check); -bool ldb_dn_is_null(struct ldb_dn *dn); -int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn); - - -/** - Compare two attributes - - This function compares to attribute names. Note that this is a - case-insensitive comparison. - - \param a the first attribute name to compare - \param b the second attribute name to compare - - \return 0 if the attribute names are the same, or only differ in - case; non-zero if there are any differences - - attribute names are restricted by rfc2251 so using - strcasecmp and toupper here is ok. - return 0 for match -*/ -#define ldb_attr_cmp(a, b) strcasecmp(a, b) -char *ldb_attr_casefold(TALLOC_CTX *mem_ctx, const char *s); -int ldb_attr_dn(const char *attr); - -/** - Create an empty message - - \param mem_ctx the memory context to create in. You can pass NULL - to get the top level context, however the ldb context (from - ldb_init()) may be a better choice -*/ -struct ldb_message *ldb_msg_new(TALLOC_CTX *mem_ctx); - -/** - Find an element within an message -*/ -struct ldb_message_element *ldb_msg_find_element(const struct ldb_message *msg, - const char *attr_name); - -/** - Compare two ldb_val values - - \param v1 first ldb_val structure to be tested - \param v2 second ldb_val structure to be tested - - \return 1 for a match, 0 if there is any difference -*/ -int ldb_val_equal_exact(const struct ldb_val *v1, const struct ldb_val *v2); - -/** - find a value within an ldb_message_element - - \param el the element to search - \param val the value to search for - - \note This search is case sensitive -*/ -struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el, - struct ldb_val *val); - -/** - add a new empty element to a ldb_message -*/ -int ldb_msg_add_empty(struct ldb_message *msg, - const char *attr_name, - int flags, - struct ldb_message_element **return_el); - -/** - add a element to a ldb_message -*/ -int ldb_msg_add(struct ldb_message *msg, - const struct ldb_message_element *el, - int flags); -int ldb_msg_add_value(struct ldb_message *msg, - const char *attr_name, - const struct ldb_val *val, - struct ldb_message_element **return_el); -int ldb_msg_add_steal_value(struct ldb_message *msg, - const char *attr_name, - struct ldb_val *val); -int ldb_msg_add_steal_string(struct ldb_message *msg, - const char *attr_name, char *str); -int ldb_msg_add_string(struct ldb_message *msg, - const char *attr_name, const char *str); -int ldb_msg_add_linearized_dn(struct ldb_message *msg, const char *attr_name, - struct ldb_dn *dn); -int ldb_msg_add_fmt(struct ldb_message *msg, - const char *attr_name, const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); - -/** - compare two message elements - return 0 on match -*/ -int ldb_msg_element_compare(struct ldb_message_element *el1, - struct ldb_message_element *el2); -int ldb_msg_element_compare_name(struct ldb_message_element *el1, - struct ldb_message_element *el2); - -/** - Find elements in a message. - - This function finds elements and converts to a specific type, with - a give default value if not found. Assumes that elements are - single valued. -*/ -const struct ldb_val *ldb_msg_find_ldb_val(const struct ldb_message *msg, const char *attr_name); -int ldb_msg_find_attr_as_int(const struct ldb_message *msg, - const char *attr_name, - int default_value); -unsigned int ldb_msg_find_attr_as_uint(const struct ldb_message *msg, - const char *attr_name, - unsigned int default_value); -int64_t ldb_msg_find_attr_as_int64(const struct ldb_message *msg, - const char *attr_name, - int64_t default_value); -uint64_t ldb_msg_find_attr_as_uint64(const struct ldb_message *msg, - const char *attr_name, - uint64_t default_value); -double ldb_msg_find_attr_as_double(const struct ldb_message *msg, - const char *attr_name, - double default_value); -int ldb_msg_find_attr_as_bool(const struct ldb_message *msg, - const char *attr_name, - int default_value); -const char *ldb_msg_find_attr_as_string(const struct ldb_message *msg, - const char *attr_name, - const char *default_value); - -struct ldb_dn *ldb_msg_find_attr_as_dn(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const struct ldb_message *msg, - const char *attr_name); - -void ldb_msg_sort_elements(struct ldb_message *msg); - -struct ldb_message *ldb_msg_copy_shallow(TALLOC_CTX *mem_ctx, - const struct ldb_message *msg); -struct ldb_message *ldb_msg_copy(TALLOC_CTX *mem_ctx, - const struct ldb_message *msg); - -/* - * ldb_msg_canonicalize() is now depreciated - * Please use ldb_msg_normalize() instead - * - * NOTE: Returned ldb_message object is allocated - * into *ldb's context. Callers are recommended - * to steal the returned object into a TALLOC_CTX - * with short lifetime. - */ -struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb, - const struct ldb_message *msg) _DEPRECATED_; - -int ldb_msg_normalize(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const struct ldb_message *msg, - struct ldb_message **_msg_out); - - -/* - * ldb_msg_diff() is now depreciated - * Please use ldb_msg_difference() instead - * - * NOTE: Returned ldb_message object is allocated - * into *ldb's context. Callers are recommended - * to steal the returned object into a TALLOC_CTX - * with short lifetime. - */ -struct ldb_message *ldb_msg_diff(struct ldb_context *ldb, - struct ldb_message *msg1, - struct ldb_message *msg2) _DEPRECATED_; - -/** - * return a ldb_message representing the differences between msg1 and msg2. - * If you then use this in a ldb_modify() call, - * it can be used to save edits to a message - * - * Result message is constructed as follows: - * - LDB_FLAG_MOD_ADD - elements found only in msg2 - * - LDB_FLAG_MOD_REPLACE - elements in msg2 that have - * different value in msg1 - * Value for msg2 element is used - * - LDB_FLAG_MOD_DELETE - elements found only in msg2 - * - * @return LDB_SUCCESS or LDB_ERR_OPERATIONS_ERROR - */ -int ldb_msg_difference(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_message *msg1, - struct ldb_message *msg2, - struct ldb_message **_msg_out); - -/** - Tries to find a certain string attribute in a message - - \param msg the message to check - \param name attribute name - \param value attribute value - - \return 1 on match and 0 otherwise. -*/ -int ldb_msg_check_string_attribute(const struct ldb_message *msg, - const char *name, - const char *value); - -/** - Integrity check an ldb_message - - This function performs basic sanity / integrity checks on an - ldb_message. - - \param ldb context in which to perform the checks - \param msg the message to check - - \return LDB_SUCCESS if the message is OK, or a non-zero error code - (one of LDB_ERR_INVALID_DN_SYNTAX, LDB_ERR_ENTRY_ALREADY_EXISTS or - LDB_ERR_INVALID_ATTRIBUTE_SYNTAX) if there is a problem with a - message. -*/ -int ldb_msg_sanity_check(struct ldb_context *ldb, - const struct ldb_message *msg); - -/** - Duplicate an ldb_val structure - - This function copies an ldb value structure. - - \param mem_ctx the memory context that the duplicated value will be - allocated from - \param v the ldb_val to be duplicated. - - \return the duplicated ldb_val structure. -*/ -struct ldb_val ldb_val_dup(TALLOC_CTX *mem_ctx, const struct ldb_val *v); - -/** - this allows the user to set a debug function for error reporting -*/ -int ldb_set_debug(struct ldb_context *ldb, - void (*debug)(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0), - void *context); - -/** - this allows the user to set custom utf8 function for error reporting -*/ -void ldb_set_utf8_fns(struct ldb_context *ldb, - void *context, - char *(*casefold)(void *, void *, const char *, size_t n)); - -/** - this sets up debug to print messages on stderr -*/ -int ldb_set_debug_stderr(struct ldb_context *ldb); - -/* control backend specific opaque values */ -int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value); -void *ldb_get_opaque(struct ldb_context *ldb, const char *name); - -const char **ldb_attr_list_copy(TALLOC_CTX *mem_ctx, const char * const *attrs); -const char **ldb_attr_list_copy_add(TALLOC_CTX *mem_ctx, const char * const *attrs, const char *new_attr); -int ldb_attr_in_list(const char * const *attrs, const char *attr); - -int ldb_msg_rename_attr(struct ldb_message *msg, const char *attr, const char *replace); -int ldb_msg_copy_attr(struct ldb_message *msg, const char *attr, const char *replace); -void ldb_msg_remove_attr(struct ldb_message *msg, const char *attr); -void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element *el); - - -void ldb_parse_tree_attr_replace(struct ldb_parse_tree *tree, - const char *attr, - const char *replace); - -/* - shallow copy a tree - copying only the elements array so that the caller - can safely add new elements without changing the message -*/ -struct ldb_parse_tree *ldb_parse_tree_copy_shallow(TALLOC_CTX *mem_ctx, - const struct ldb_parse_tree *ot); - -/** - Convert a time structure to a string - - This function converts a time_t structure to an LDAP formatted - GeneralizedTime string. - - \param mem_ctx the memory context to allocate the return string in - \param t the time structure to convert - - \return the formatted string, or NULL if the time structure could - not be converted -*/ -char *ldb_timestring(TALLOC_CTX *mem_ctx, time_t t); - -/** - Convert a string to a time structure - - This function converts an LDAP formatted GeneralizedTime string - to a time_t structure. - - \param s the string to convert - - \return the time structure, or 0 if the string cannot be converted -*/ -time_t ldb_string_to_time(const char *s); - -/** - convert a LDAP GeneralizedTime string in ldb_val format to a - time_t. -*/ -int ldb_val_to_time(const struct ldb_val *v, time_t *t); - -/** - Convert a time structure to a string - - This function converts a time_t structure to an LDAP formatted - UTCTime string. - - \param mem_ctx the memory context to allocate the return string in - \param t the time structure to convert - - \return the formatted string, or NULL if the time structure could - not be converted -*/ -char *ldb_timestring_utc(TALLOC_CTX *mem_ctx, time_t t); - -/** - Convert a string to a time structure - - This function converts an LDAP formatted UTCTime string - to a time_t structure. - - \param s the string to convert - - \return the time structure, or 0 if the string cannot be converted -*/ -time_t ldb_string_utc_to_time(const char *s); - - -void ldb_qsort (void *const pbase, size_t total_elems, size_t size, void *opaque, ldb_qsort_cmp_fn_t cmp); - -#ifndef discard_const -#define discard_const(ptr) ((void *)((uintptr_t)(ptr))) -#endif - -/* - a wrapper around ldb_qsort() that ensures the comparison function is - type safe. This will produce a compilation warning if the types - don't match - */ -#define LDB_TYPESAFE_QSORT(base, numel, opaque, comparison) \ -do { \ - if (numel > 1) { \ - ldb_qsort(base, numel, sizeof((base)[0]), discard_const(opaque), (ldb_qsort_cmp_fn_t)comparison); \ - comparison(&((base)[0]), &((base)[1]), opaque); \ - } \ -} while (0) - -/* allow ldb to also call TYPESAFE_QSORT() */ -#ifndef TYPESAFE_QSORT -#define TYPESAFE_QSORT(base, numel, comparison) \ -do { \ - if (numel > 1) { \ - qsort(base, numel, sizeof((base)[0]), (int (*)(const void *, const void *))comparison); \ - comparison(&((base)[0]), &((base)[1])); \ - } \ -} while (0) -#endif - - - -/** - Convert a control into its string representation. - - \param mem_ctx TALLOC context to return result on, and to allocate error_string on - \param control A struct ldb_control to convert - - \return string representation of the control -*/ -char* ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *control); -/** - Convert a string representing a control into a ldb_control structure - - \param ldb LDB context - \param mem_ctx TALLOC context to return result on, and to allocate error_string on - \param control_strings A string-formatted control - - \return a ldb_control element -*/ -struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *control_strings); -/** - Convert an array of string represention of a control into an array of ldb_control structures - - \param ldb LDB context - \param mem_ctx TALLOC context to return result on, and to allocate error_string on - \param control_strings Array of string-formatted controls - - \return array of ldb_control elements -*/ -struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char **control_strings); - -/** - return the ldb flags -*/ -unsigned int ldb_get_flags(struct ldb_context *ldb); - -/* set the ldb flags */ -void ldb_set_flags(struct ldb_context *ldb, unsigned flags); - - -struct ldb_dn *ldb_dn_binary_from_ldb_val(TALLOC_CTX *mem_ctx, - struct ldb_context *ldb, - const struct ldb_val *strdn); - -int ldb_dn_get_binary(struct ldb_dn *dn, struct ldb_val *val); -int ldb_dn_set_binary(struct ldb_dn *dn, struct ldb_val *val); - -/* debugging functions for ldb requests */ -void ldb_req_set_location(struct ldb_request *req, const char *location); -const char *ldb_req_location(struct ldb_request *req); - -/* set the location marker on a request handle - used for debugging */ -#define LDB_REQ_SET_LOCATION(req) ldb_req_set_location(req, __location__) - -/* - minimise a DN. The caller must pass in a validated DN. - - If the DN has an extended component then only the first extended - component is kept, the DN string is stripped. - - The existing dn is modified - */ -bool ldb_dn_minimise(struct ldb_dn *dn); - -/* - compare a ldb_val to a string -*/ -int ldb_val_string_cmp(const struct ldb_val *v, const char *str); - -#endif diff --git a/ldb-2.0.8/include/ldb_errors.h b/ldb-2.0.8/include/ldb_errors.h deleted file mode 100644 index b247fbe..0000000 --- a/ldb-2.0.8/include/ldb_errors.h +++ /dev/null @@ -1,312 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb header - * - * Description: defines error codes following RFC 2251 ldap error codes - * - * Author: Simo Sorce - */ - -#ifndef _LDB_ERRORS_H_ - -/*! \cond DOXYGEN_IGNORE */ -#define _LDB_ERRORS_H_ 1 -/*! \endcond */ - -/** - \file ldb_errors.h - - This header provides a set of result codes for LDB function calls. - - Many LDB function calls return an integer value (int). As shown in - the function documentation, those return values may indicate - whether the function call worked correctly (in which case it - returns LDB_SUCCESS) or some problem occurred (in which case some - other value will be returned). As a special case, - LDB_ERR_COMPARE_FALSE or LDB_ERR_COMPARE_TRUE may be returned, - which does not indicate an error. - - \note Not all error codes make sense for LDB, however they are - based on the LDAP error codes, and are kept for reference and to - avoid overlap. - - \note Some of this documentation is based on information in - the OpenLDAP documentation, as developed and maintained by the - The OpenLDAP Project. - */ - -/** - The function call succeeded. - - If a function returns LDB_SUCCESS, then that function, and the - underlying transactions that may have been required, completed - successfully. -*/ -#define LDB_SUCCESS 0 - -/** - The function call failed for some non-specific reason. -*/ -#define LDB_ERR_OPERATIONS_ERROR 1 - -/** - The function call failed because of a protocol violation. -*/ -#define LDB_ERR_PROTOCOL_ERROR 2 - -/** - The function call failed because a time limit was exceeded. -*/ -#define LDB_ERR_TIME_LIMIT_EXCEEDED 3 - -/** - The function call failed because a size limit was exceeded. -*/ -#define LDB_ERR_SIZE_LIMIT_EXCEEDED 4 - -/** - The function was for value comparison, and the comparison operation - returned false. - - \note This is a status value, and doesn't normally indicate an - error. -*/ -#define LDB_ERR_COMPARE_FALSE 5 - -/** - The function was for value comparison, and the comparison operation - returned true. - - \note This is a status value, and doesn't normally indicate an - error. -*/ -#define LDB_ERR_COMPARE_TRUE 6 - -/** - The function used an authentication method that is not supported by - the database. -*/ -#define LDB_ERR_AUTH_METHOD_NOT_SUPPORTED 7 - -/** - The function call required a underlying operation that required - strong authentication. - - This will normally only occur if you are using LDB with a LDAP - backend. -*/ -#define LDB_ERR_STRONG_AUTH_REQUIRED 8 - -/* 9 RESERVED */ - -/** - The function resulted in a referral to another server. -*/ -#define LDB_ERR_REFERRAL 10 - -/** - The function failed because an administrative / policy limit was - exceeded. -*/ -#define LDB_ERR_ADMIN_LIMIT_EXCEEDED 11 - -/** - The function required an extension or capability that the - database cannot provide. -*/ -#define LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION 12 - -/** - The function involved a transaction or database operation that - could not be performed without a secure link. -*/ -#define LDB_ERR_CONFIDENTIALITY_REQUIRED 13 - -/** - This is an intermediate result code for SASL bind operations that - have more than one step. - - \note This is a result code that does not normally indicate an - error has occurred. -*/ -#define LDB_ERR_SASL_BIND_IN_PROGRESS 14 - -/** - The function referred to an attribute type that is not present in - the entry. -*/ -#define LDB_ERR_NO_SUCH_ATTRIBUTE 16 - -/** - The function referred to an attribute type that is invalid -*/ -#define LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE 17 - -/** - The function required a filter type that is not available for the - specified attribute. -*/ -#define LDB_ERR_INAPPROPRIATE_MATCHING 18 - -/** - The function would have violated an attribute constraint. -*/ -#define LDB_ERR_CONSTRAINT_VIOLATION 19 - -/** - The function involved an attribute type or attribute value that - already exists in the entry. -*/ -#define LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS 20 - -/** - The function used an invalid (incorrect syntax) attribute value. -*/ -#define LDB_ERR_INVALID_ATTRIBUTE_SYNTAX 21 - -/* 22-31 unused */ - -/** - The function referred to an object that does not exist in the - database. -*/ -#define LDB_ERR_NO_SUCH_OBJECT 32 - -/** - The function referred to an alias which points to a non-existent - object in the database. -*/ -#define LDB_ERR_ALIAS_PROBLEM 33 - -/** - The function used a DN which was invalid (incorrect syntax). -*/ -#define LDB_ERR_INVALID_DN_SYNTAX 34 - -/* 35 RESERVED */ - -/** - The function required dereferencing of an alias, and something went - wrong during the dereferencing process. -*/ -#define LDB_ERR_ALIAS_DEREFERENCING_PROBLEM 36 - -/* 37-47 unused */ - -/** - The function passed in the wrong authentication method. -*/ -#define LDB_ERR_INAPPROPRIATE_AUTHENTICATION 48 - -/** - The function passed in or referenced incorrect credentials during - authentication. -*/ -#define LDB_ERR_INVALID_CREDENTIALS 49 - -/** - The function required access permissions that the user does not - possess. -*/ -#define LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS 50 - -/** - The function required a transaction or call that the database could - not perform because it is busy. -*/ -#define LDB_ERR_BUSY 51 - -/** - The function required a transaction or call to a database that is - not available. -*/ -#define LDB_ERR_UNAVAILABLE 52 - -/** - The function required a transaction or call to a database that the - database declined to perform. -*/ -#define LDB_ERR_UNWILLING_TO_PERFORM 53 - -/** - The function failed because it resulted in a loop being detected. -*/ -#define LDB_ERR_LOOP_DETECT 54 - -/* 55-63 unused */ - -/** - The function failed because it would have violated a naming rule. -*/ -#define LDB_ERR_NAMING_VIOLATION 64 - -/** - The function failed because it would have violated the schema. -*/ -#define LDB_ERR_OBJECT_CLASS_VIOLATION 65 - -/** - The function required an operation that is only allowed on leaf - objects, but the object is not a leaf. -*/ -#define LDB_ERR_NOT_ALLOWED_ON_NON_LEAF 66 - -/** - The function required an operation that cannot be performed on a - Relative DN, but the object is a Relative DN. -*/ -#define LDB_ERR_NOT_ALLOWED_ON_RDN 67 - -/** - The function failed because the entry already exists. -*/ -#define LDB_ERR_ENTRY_ALREADY_EXISTS 68 - -/** - The function failed because modifications to an object class are - not allowable. -*/ -#define LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED 69 - -/* 70 RESERVED FOR CLDAP */ - -/** - The function failed because it needed to be applied to multiple - databases. -*/ -#define LDB_ERR_AFFECTS_MULTIPLE_DSAS 71 - -/* 72-79 unused */ - -/** - The function failed for unknown reasons. -*/ -#define LDB_ERR_OTHER 80 - -/* 81-90 RESERVED for APIs */ - -#endif /* _LDB_ERRORS_H_ */ diff --git a/ldb-2.0.8/include/ldb_handlers.h b/ldb-2.0.8/include/ldb_handlers.h deleted file mode 100644 index 79d8bb6..0000000 --- a/ldb-2.0.8/include/ldb_handlers.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb header - * - * Description: defines attribute handlers - * - * Author: Simo Sorce - */ -#ifndef __LDB_HANDLERS_H__ -#define __LDB_HANDLERS_H__ - -int ldb_handler_copy(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out); -int ldb_handler_fold(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out); -int ldb_comparison_binary(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2); -int ldb_comparison_fold(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2); - -#endif /* __LDB_HANDLERS_H__ */ diff --git a/ldb-2.0.8/include/ldb_module.h b/ldb-2.0.8/include/ldb_module.h deleted file mode 100644 index 8c1e5ee..0000000 --- a/ldb-2.0.8/include/ldb_module.h +++ /dev/null @@ -1,595 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2008 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb module header - * - * Description: defines ldb modules structures and helpers - * - */ - -#ifndef _LDB_MODULE_H_ -#define _LDB_MODULE_H_ - -#include - -#if defined(_SAMBA_BUILD_) && defined(USING_SYSTEM_LDB) - -/* - * Versions before 1.2.0 doesn't define these values - * so we assime 1.1.29 (which was used in Samba 4.6) - * - * See https://bugzilla.samba.org/show_bug.cgi?id=12859 - */ -#ifndef EXPECTED_SYSTEM_LDB_VERSION_MAJOR -#define EXPECTED_SYSTEM_LDB_VERSION_MAJOR 1 -#endif -#ifndef EXPECTED_SYSTEM_LDB_VERSION_MINOR -#define EXPECTED_SYSTEM_LDB_VERSION_MINOR 1 -#endif -#ifndef EXPECTED_SYSTEM_LDB_VERSION_MINOR -#define EXPECTED_SYSTEM_LDB_VERSION_MINOR 29 -#endif - -/* - * Only Samba versions which expect ldb >= 1.4.0 - * reopen the ldb after each fork(). - * - * See https://bugzilla.samba.org/show_bug.cgi?id=13519 - */ -#if EXPECTED_SYSTEM_LDB_VERSION_MAJOR > 1 -#define __LDB_FORK_COMPATIBLE__ 1 -#elif EXPECTED_SYSTEM_LDB_VERSION_MINOR > 3 -#define __LDB_FORK_COMPATIBLE__ 1 -#endif -#ifndef __LDB_FORK_COMPATIBLE__ -#error "Samba < 4.9 is not compatible with this version of ldb due to assumptions around fork() behaviour" -#endif - -#endif /* defined(_SAMBA_BUILD_) && defined(USING_SYSTEM_LDB) */ - -struct ldb_context; -struct ldb_module; - -/** - internal flag bits on message elements. Must be within LDB_FLAG_INTERNAL_MASK - */ -#define LDB_FLAG_INTERNAL_DISABLE_VALIDATION 0x10 - -/* disable any single value checking on this attribute */ -#define LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK 0x20 - -/* attribute has failed access check and must not be exposed */ -#define LDB_FLAG_INTERNAL_INACCESSIBLE_ATTRIBUTE 0x40 - -/* force single value checking on this attribute */ -#define LDB_FLAG_INTERNAL_FORCE_SINGLE_VALUE_CHECK 0x80 - -/* - * ensure that this value is unique on an index - * (despite the index not otherwise being configured as UNIQUE). - * For example, all words starting with 'a' must be unique, but duplicates of - * words starting with b are allowed. This is specifically for Samba's - * objectSid index which is unique in the primary domain only. - */ -#define LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX 0x100 - -/* an extended match rule that always fails to match */ -#define SAMBA_LDAP_MATCH_ALWAYS_FALSE "1.3.6.1.4.1.7165.4.5.1" - -/* The const char * const * pointer to a list of secret (password) - * attributes, not to be printed in trace messages */ -#define LDB_SECRET_ATTRIBUTE_LIST_OPAQUE "LDB_SECRET_ATTRIBUTE_LIST" - -/* - * The scheme to be used for referral entries, i.e. ldap or ldaps - */ -#define LDAP_REFERRAL_SCHEME_OPAQUE "LDAP_REFERRAL_SCHEME" - -/* - these function pointers define the operations that a ldb module can intercept -*/ -struct ldb_module_ops { - const char *name; - int (*init_context) (struct ldb_module *); - int (*search)(struct ldb_module *, struct ldb_request *); /* search */ - int (*add)(struct ldb_module *, struct ldb_request *); /* add */ - int (*modify)(struct ldb_module *, struct ldb_request *); /* modify */ - int (*del)(struct ldb_module *, struct ldb_request *); /* delete */ - int (*rename)(struct ldb_module *, struct ldb_request *); /* rename */ - int (*request)(struct ldb_module *, struct ldb_request *); /* match any other operation */ - int (*extended)(struct ldb_module *, struct ldb_request *); /* extended operations */ - int (*start_transaction)(struct ldb_module *); - int (*prepare_commit)(struct ldb_module *); - int (*end_transaction)(struct ldb_module *); - int (*del_transaction)(struct ldb_module *); - int (*sequence_number)(struct ldb_module *, struct ldb_request *); - int (*read_lock)(struct ldb_module *); - int (*read_unlock)(struct ldb_module *); - void *private_data; -}; - - -/* The following definitions come from lib/ldb/common/ldb_debug.c */ -void ldb_debug(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); -void ldb_debug_set(struct ldb_context *ldb, enum ldb_debug_level level, - const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); -void ldb_debug_add(struct ldb_context *ldb, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); -void ldb_debug_end(struct ldb_context *ldb, enum ldb_debug_level level); -void ldb_vdebug(struct ldb_context *ldb, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0); - -#define ldb_error(ldb, ecode, reason) ldb_error_at(ldb, ecode, reason, __FILE__, __LINE__) -#define ldb_module_error(module, ecode, reason) ldb_error_at(ldb_module_get_ctx(module), ecode, reason, __FILE__, __LINE__) - -#define ldb_oom(ldb) ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "ldb out of memory") -#define ldb_module_oom(module) ldb_oom(ldb_module_get_ctx(module)) -#define ldb_operr(ldb) ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "operations error") -#define ldb_module_operr(module) ldb_error(ldb_module_get_ctx(module), LDB_ERR_OPERATIONS_ERROR, "operations error") - -/* The following definitions come from lib/ldb/common/ldb.c */ - -void ldb_request_set_state(struct ldb_request *req, int state); -int ldb_request_get_status(struct ldb_request *req); - -unsigned int ldb_get_create_perms(struct ldb_context *ldb); - -const struct ldb_schema_syntax *ldb_standard_syntax_by_name(struct ldb_context *ldb, - const char *syntax); - -/* The following definitions come from lib/ldb/common/ldb_attributes.c */ - -int ldb_schema_attribute_add_with_syntax(struct ldb_context *ldb, - const char *name, - unsigned flags, - const struct ldb_schema_syntax *syntax); -int ldb_schema_attribute_add(struct ldb_context *ldb, - const char *name, - unsigned flags, - const char *syntax); -void ldb_schema_attribute_remove(struct ldb_context *ldb, const char *name); - -/* we allow external code to override the name -> schema_attribute function */ -typedef const struct ldb_schema_attribute *(*ldb_attribute_handler_override_fn_t)(struct ldb_context *, void *, const char *); - -/** - Allow the caller to define a callback for the attribute handler - - \param ldb The ldb context - \param override The callback to be used for attribute lookups - \param private_data Private data for the callback - -*/ -void ldb_schema_attribute_set_override_handler(struct ldb_context *ldb, - ldb_attribute_handler_override_fn_t override, - void *private_data); - -/** - Allow the caller to define that the callback for the attribute handler - also overrides the index list - - \param ldb The ldb context - \param one_level_indexes Indicates that the index for SCOPE_ONELEVEL - should also be maintained - -*/ -void ldb_schema_set_override_indexlist(struct ldb_context *ldb, - bool one_level_indexes); - -/** - - \param ldb The ldb context - \param GUID_index_attribute The globally attribute (eg objectGUID) - on each entry - \param GUID_index_attribute The DN component matching the - globally attribute on each entry (eg GUID) - - The caller must ensure the supplied strings do not go out of - scope (they are typically constant memory). - -*/ -void ldb_schema_set_override_GUID_index(struct ldb_context *ldb, - const char *GUID_index_attribute, - const char *GUID_index_dn_component); - -/* A useful function to build comparison functions with */ -int ldb_any_comparison(struct ldb_context *ldb, void *mem_ctx, - ldb_attr_handler_t canonicalise_fn, - const struct ldb_val *v1, - const struct ldb_val *v2); - -/* The following definitions come from lib/ldb/common/ldb_controls.c */ -int ldb_save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver); -/* Returns a list of controls, except the one specified. Included - * controls become a child of returned list if they were children of - * controls_in */ -struct ldb_control **ldb_controls_except_specified(struct ldb_control **controls_in, - TALLOC_CTX *mem_ctx, - struct ldb_control *exclude); -int ldb_check_critical_controls(struct ldb_control **controls); - -/* The following definitions come from lib/ldb/common/ldb_ldif.c */ -int ldb_should_b64_encode(struct ldb_context *ldb, const struct ldb_val *val); - -/* The following definitions come from lib/ldb/common/ldb_match.c */ -int ldb_match_msg(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - struct ldb_dn *base, - enum ldb_scope scope); - -int ldb_match_msg_error(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - struct ldb_dn *base, - enum ldb_scope scope, - bool *matched); - -int ldb_match_msg_objectclass(const struct ldb_message *msg, - const char *objectclass); - -int ldb_register_extended_match_rules(struct ldb_context *ldb); - -/* The following definitions come from lib/ldb/common/ldb_modules.c */ - -struct ldb_module *ldb_module_new(TALLOC_CTX *memctx, - struct ldb_context *ldb, - const char *module_name, - const struct ldb_module_ops *ops); - -const char * ldb_module_get_name(struct ldb_module *module); -struct ldb_context *ldb_module_get_ctx(struct ldb_module *module); -void *ldb_module_get_private(struct ldb_module *module); -void ldb_module_set_private(struct ldb_module *module, void *private_data); -const struct ldb_module_ops *ldb_module_get_ops(struct ldb_module *module); - -int ldb_next_request(struct ldb_module *module, struct ldb_request *request); -int ldb_next_start_trans(struct ldb_module *module); -int ldb_next_end_trans(struct ldb_module *module); -int ldb_next_del_trans(struct ldb_module *module); -int ldb_next_prepare_commit(struct ldb_module *module); -int ldb_next_init(struct ldb_module *module); -int ldb_next_read_lock(struct ldb_module *module); -int ldb_next_read_unlock(struct ldb_module *module); - -void ldb_set_errstring(struct ldb_context *ldb, const char *err_string); -void ldb_asprintf_errstring(struct ldb_context *ldb, const char *format, ...) PRINTF_ATTRIBUTE(2,3); -void ldb_reset_err_string(struct ldb_context *ldb); -int ldb_error_at(struct ldb_context *ldb, int ecode, const char *reason, const char *file, int line); - -const char *ldb_default_modules_dir(void); - -int ldb_register_module(const struct ldb_module_ops *); - -typedef int (*ldb_connect_fn)(struct ldb_context *ldb, const char *url, - unsigned int flags, const char *options[], - struct ldb_module **module); - -/** - Require that LDB use a private event context for each request - - A private event context may need to be created to avoid nested event - loops during ldb_tdb with the locks held. This indicates that a - backend is in use that requires this to hold locks safely. - - \param handle The ldb handle to set the flag on - */ -void ldb_set_require_private_event_context(struct ldb_context *ldb); - -struct ldb_backend_ops { - const char *name; - ldb_connect_fn connect_fn; -}; - -const char *ldb_default_modules_dir(void); - -int ldb_register_backend(const char *url_prefix, ldb_connect_fn, bool); - -struct ldb_handle *ldb_handle_new(TALLOC_CTX *mem_ctx, struct ldb_context *ldb); - -/** - Obtains the private event context for the handle, - - A private event context may have been created to avoid nested event - loops during ldb_tdb with the locks held. Otherwise return the - global one. - - \param handle The ldb handle to obtain the event context for - \return the tevent event context for this handle (private or global) - */ -struct tevent_context *ldb_handle_get_event_context(struct ldb_handle *handle); - -int ldb_module_send_entry(struct ldb_request *req, - struct ldb_message *msg, - struct ldb_control **ctrls); - -int ldb_module_send_referral(struct ldb_request *req, - char *ref); - -int ldb_module_done(struct ldb_request *req, - struct ldb_control **ctrls, - struct ldb_extended *response, - int error); - -int ldb_mod_register_control(struct ldb_module *module, const char *oid); - -void ldb_set_default_dns(struct ldb_context *ldb); -/** - Add a ldb_control to a ldb_reply - - \param ares the reply struct where to add the control - \param oid the object identifier of the control as string - \param critical whether the control should be critical or not - \param data a talloc pointer to the control specific data - - \return result code (LDB_SUCCESS on success, or a failure code) -*/ -int ldb_reply_add_control(struct ldb_reply *ares, const char *oid, bool critical, void *data); - -/** - mark a request as untrusted. - - This tells the rootdse module to remove unregistered controls - - \param req the request to mark as untrusted -*/ -void ldb_req_mark_untrusted(struct ldb_request *req); - -/** - mark a request as trusted. - - This tells the rootdse module to allow unregistered controls - - \param req the request to mark as trusted -*/ -void ldb_req_mark_trusted(struct ldb_request *req); - -/** - return true is a request is untrusted - - This indicates the request came across a trust boundary - for example over LDAP - - \param req the request check - \return is req trusted -*/ -bool ldb_req_is_untrusted(struct ldb_request *req); - -/** - set custom flags. Those flags are set by applications using ldb, - they are application dependent and the same bit can have different - meaning in different application. - */ -void ldb_req_set_custom_flags(struct ldb_request *req, uint32_t flags); - -/** - get custom flags. Those flags are set by applications using ldb, - they are application dependent and the same bit can have different - meaning in different application. - */ -uint32_t ldb_req_get_custom_flags(struct ldb_request *req); - -/* load all modules from the given directory */ -int ldb_modules_load(const char *modules_path, const char *version); - -/* init functions prototype */ -typedef int (*ldb_module_init_fn)(const char *); - -/* - general ldb hook function - */ -enum ldb_module_hook_type { LDB_MODULE_HOOK_CMDLINE_OPTIONS = 1, - LDB_MODULE_HOOK_CMDLINE_PRECONNECT = 2, - LDB_MODULE_HOOK_CMDLINE_POSTCONNECT = 3 }; - -typedef int (*ldb_hook_fn)(struct ldb_context *, enum ldb_module_hook_type ); - -/* - register a ldb hook function - */ -int ldb_register_hook(ldb_hook_fn hook_fn); - -/* - call ldb hooks of a given type - */ -int ldb_modules_hook(struct ldb_context *ldb, enum ldb_module_hook_type t); - -#define LDB_MODULE_CHECK_VERSION(version) do { \ - if (strcmp(version, LDB_VERSION) != 0) { \ - fprintf(stderr, "ldb: module version mismatch in %s : ldb_version=%s module_version=%s\n", \ - __FILE__, version, LDB_VERSION); \ - return LDB_ERR_UNAVAILABLE; \ - }} while (0) - - -/* - return a string representation of the calling chain for the given - ldb request - */ -char *ldb_module_call_chain(struct ldb_request *req, TALLOC_CTX *mem_ctx); - -/* - return the next module in the chain - */ -struct ldb_module *ldb_module_next(struct ldb_module *module); - -/* - set the next module in the module chain - */ -void ldb_module_set_next(struct ldb_module *module, struct ldb_module *next); - -/* - load a list of modules - */ -int ldb_module_load_list(struct ldb_context *ldb, const char **module_list, - struct ldb_module *backend, struct ldb_module **out); - -/* - get the popt_options pointer in the ldb structure. This allows a ldb - module to change the command line parsing - */ -struct poptOption **ldb_module_popt_options(struct ldb_context *ldb); - -/* modules are called in inverse order on the stack. - Lets place them as an admin would think the right order is. - Modules order is important */ -const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string); - -/* - return the current ldb flags LDB_FLG_* - */ -uint32_t ldb_module_flags(struct ldb_context *ldb); - -int ldb_module_connect_backend(struct ldb_context *ldb, - const char *url, - const char *options[], - struct ldb_module **backend_module); - -/* - initialise a chain of modules - */ -int ldb_module_init_chain(struct ldb_context *ldb, struct ldb_module *module); - -/* - * prototype for the init function defined by dynamically loaded modules - */ -int ldb_init_module(const char *version); - -/* replace the components of a DN with those from another DN, without - * touching the extended components - * - * return true if successful and false if not - * if false is returned the dn may be marked invalid - */ -bool ldb_dn_replace_components(struct ldb_dn *dn, struct ldb_dn *new_dn); - -/* - walk a parse tree, calling the provided callback on each node -*/ -int ldb_parse_tree_walk(struct ldb_parse_tree *tree, - int (*callback)(struct ldb_parse_tree *tree, void *), - void *private_context); - -/* compare two message elements with ordering - used by modify */ -bool ldb_msg_element_equal_ordered(const struct ldb_message_element *el1, - const struct ldb_message_element *el2); - - -struct ldb_extended_match_rule -{ - const char *oid; - int (*callback)(struct ldb_context *, const char *oid, - const struct ldb_message *, const char *, - const struct ldb_val *, bool *); -}; - -int ldb_register_extended_match_rule(struct ldb_context *ldb, - const struct ldb_extended_match_rule *rule); - -/* - * these pack/unpack functions are exposed in the library for use by - * ldb tools like ldbdump and for use in tests, - * but are not part of the public API - */ -int ldb_pack_data(struct ldb_context *ldb, - const struct ldb_message *message, - struct ldb_val *data, - uint32_t pack_format_version); -/* - * Unpack a ldb message from a linear buffer in ldb_val - */ -int ldb_unpack_data(struct ldb_context *ldb, - const struct ldb_val *data, - struct ldb_message *message); - -/* - * filter the specified list of attributes from msg, - * adding requested attributes, and perhaps all for *, - * but not the DN to filtered_msg. - */ -int ldb_filter_attrs(struct ldb_context *ldb, - const struct ldb_message *msg, - const char *const *attrs, - struct ldb_message *filtered_msg); -/* - * Unpack a ldb message from a linear buffer in ldb_val - * - * If LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC is specified, then values - * array are not allocated individually (for single-valued - * attributes), instead they point into a single buffer per message. - * - * Likewise if LDB_UNPACK_DATA_FLAG_NO_DN is specified, the DN is omitted. - * - * If LDB_UNPACK_DATA_FLAG_NO_ATTRS is specified, then no attributes - * are unpacked or returned. - * - */ -int ldb_unpack_data_flags(struct ldb_context *ldb, - const struct ldb_val *data, - struct ldb_message *message, - unsigned int flags); - -int ldb_unpack_get_format(const struct ldb_val *data, - uint32_t *pack_format_version); - -/* currently unused (was NO_DATA_ALLOC) 0x0001 */ -#define LDB_UNPACK_DATA_FLAG_NO_DN 0x0002 -#define LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC 0x0004 -#define LDB_UNPACK_DATA_FLAG_NO_ATTRS 0x0008 -#define LDB_UNPACK_DATA_FLAG_READ_LOCKED 0x0010 - -enum ldb_pack_format { - - /* Old packing format (based on a somewhat arbitrary date) */ - LDB_PACKING_FORMAT_NODN = 0x26011966, - - /* In-use packing formats */ - LDB_PACKING_FORMAT, - LDB_PACKING_FORMAT_V2 -}; - -/** - Forces a specific ldb handle to use the global event context. - - This allows a nested event loop to operate, so any open - transaction also needs to be aborted. - - Any events on this event context will be lost. - - This is used in Samba when sending an IRPC to another part of the - same process instead of making a local DB modification. - - \param handle The ldb handle to force to use the global context - - */ -void ldb_handle_use_global_event_context(struct ldb_handle *handle); - -/** - * Get the options passed to ldb_connect. - * - * This allows the options to be inspected by elements in the module stack - * - */ -const char **ldb_options_get(struct ldb_context *ldb); -#endif diff --git a/ldb-2.0.8/include/ldb_private.h b/ldb-2.0.8/include/ldb_private.h deleted file mode 100644 index 4deb246..0000000 --- a/ldb-2.0.8/include/ldb_private.h +++ /dev/null @@ -1,320 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 2004-2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb private header - * - * Description: defines internal ldb structures used by the subsystem and modules - * - * Author: Andrew Tridgell - * Author: Stefan Metzmacher - */ - -#ifndef _LDB_PRIVATE_H_ -#define _LDB_PRIVATE_H_ 1 - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb.h" -#include "ldb_module.h" - -struct ldb_context; - -struct ldb_module_ops; - -struct ldb_backend_ops; - -#define LDB_HANDLE_FLAG_DONE_CALLED 1 -/* call is from an untrusted source - eg. over ldap:// */ -#define LDB_HANDLE_FLAG_UNTRUSTED 2 - -struct ldb_handle { - int status; - enum ldb_state state; - struct ldb_context *ldb; - unsigned flags; - /* flags dedicated to be set by application using ldb */ - uint32_t custom_flags; - unsigned nesting; - - /* Private event context (if not NULL) */ - struct tevent_context *event_context; - - /* used for debugging */ - struct ldb_request *parent; - const char *location; -}; - -/* basic module structure */ -struct ldb_module { - struct ldb_module *prev, *next; - struct ldb_context *ldb; - void *private_data; - const struct ldb_module_ops *ops; -}; - -/* - schema related information needed for matching rules -*/ -struct ldb_schema { - void *attribute_handler_override_private; - ldb_attribute_handler_override_fn_t attribute_handler_override; - - /* attribute handling table */ - unsigned num_attributes; - struct ldb_schema_attribute *attributes; - - unsigned num_dn_extended_syntax; - struct ldb_dn_extended_syntax *dn_extended_syntax; - - /* - * If set, the attribute_handler_override has the details of - * what attributes have an index - */ - bool index_handler_override; - bool one_level_indexes; - - const char *GUID_index_attribute; - const char *GUID_index_dn_component; -}; - -/* - every ldb connection is started by establishing a ldb_context -*/ -struct ldb_context { - /* the operations provided by the backend */ - struct ldb_module *modules; - - /* debugging operations */ - struct ldb_debug_ops debug_ops; - - /* extended matching rules */ - struct ldb_extended_match_entry { - const struct ldb_extended_match_rule *rule; - struct ldb_extended_match_entry *prev, *next; - } *extended_match_rules; - - /* custom utf8 functions */ - struct ldb_utf8_fns utf8_fns; - - /* backend specific opaque parameters */ - struct ldb_opaque { - struct ldb_opaque *next; - const char *name; - void *value; - } *opaque; - - struct ldb_schema schema; - - char *err_string; - - int transaction_active; - - int default_timeout; - - unsigned int flags; - - unsigned int create_perms; - - struct tevent_context *ev_ctx; - - /* - * If the backend holds locks, we must not use a global event - * context, so this flag will be set and ldb_handle_new() will - * build a new event context - */ - bool require_private_event_context; - - bool prepare_commit_done; - - char *partial_debug; - - struct poptOption *popt_options; - - /* - * The ldb options passed to ldb_connect - * A NULL terminated array of zero terminated strings - */ - const char **options; -}; - -/* The following definitions come from lib/ldb/common/ldb.c */ - -extern const struct ldb_module_ops ldb_objectclass_module_ops; -extern const struct ldb_module_ops ldb_paged_results_module_ops; -extern const struct ldb_module_ops ldb_rdn_name_module_ops; -extern const struct ldb_module_ops ldb_schema_module_ops; -extern const struct ldb_module_ops ldb_asq_module_ops; -extern const struct ldb_module_ops ldb_server_sort_module_ops; -extern const struct ldb_module_ops ldb_ldap_module_ops; -extern const struct ldb_module_ops ldb_ildap_module_ops; -extern const struct ldb_module_ops ldb_paged_searches_module_ops; -extern const struct ldb_module_ops ldb_tdb_module_ops; -extern const struct ldb_module_ops ldb_skel_module_ops; -extern const struct ldb_module_ops ldb_subtree_rename_module_ops; -extern const struct ldb_module_ops ldb_subtree_delete_module_ops; -extern const struct ldb_module_ops ldb_sqlite3_module_ops; -extern const struct ldb_module_ops ldb_wins_ldb_module_ops; -extern const struct ldb_module_ops ldb_ranged_results_module_ops; - -extern const struct ldb_backend_ops ldb_tdb_backend_ops; -extern const struct ldb_backend_ops ldb_sqlite3_backend_ops; -extern const struct ldb_backend_ops ldb_ldap_backend_ops; -extern const struct ldb_backend_ops ldb_ldapi_backend_ops; -extern const struct ldb_backend_ops ldb_ldaps_backend_ops; - -int ldb_setup_wellknown_attributes(struct ldb_context *ldb); -/* - remove attributes with a specified flag (eg LDB_ATTR_FLAG_FROM_DB) for this ldb context - - This is to permit correct reloads -*/ -void ldb_schema_attribute_remove_flagged(struct ldb_context *ldb, unsigned int flag); -int ldb_schema_attribute_fill_with_syntax(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const char *attribute, - unsigned flags, - const struct ldb_schema_syntax *syntax, - struct ldb_schema_attribute *a); - -const char **ldb_subclass_list(struct ldb_context *ldb, const char *classname); -void ldb_subclass_remove(struct ldb_context *ldb, const char *classname); -int ldb_subclass_add(struct ldb_context *ldb, const char *classname, const char *subclass); - -/* The following definitions come from lib/ldb/common/ldb_utf8.c */ -char *ldb_casefold_default(void *context, TALLOC_CTX *mem_ctx, const char *s, size_t n); - -void ldb_dump_results(struct ldb_context *ldb, struct ldb_result *result, FILE *f); - - -/* The following definitions come from lib/ldb/common/ldb_modules.c */ - -const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *string); -int ldb_load_modules(struct ldb_context *ldb, const char *options[]); - -struct ldb_val ldb_binary_decode(TALLOC_CTX *mem_ctx, const char *str); - - -/* The following definitions come from lib/ldb/common/ldb_options.c */ - -const char *ldb_options_find(struct ldb_context *ldb, const char *options[], - const char *option_name); -const char **ldb_options_copy(TALLOC_CTX *ctx, const char *options[]); - -/* The following definitions come from lib/ldb/common/ldb_ldif.c */ - -struct ldif_read_file_state { - FILE *f; - size_t line_no; -}; - -struct ldb_ldif *ldb_ldif_read_file_state(struct ldb_context *ldb, - struct ldif_read_file_state *state); - -char *ldb_ldif_write_redacted_trace_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - const struct ldb_ldif *ldif); - -/* - * Get the LDB context in use on an LDB DN. - * - * This is helpful to the python LDB code, which may use as part of - * adding base and child components to an existing DN. - */ -struct ldb_context *ldb_dn_get_ldb_context(struct ldb_dn *dn); - -#define LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES 1 - -/** - Determine whether any values in an element are also in another element, - and optionally fix that. - - \param ldb an ldb context - \param mem_ctx a talloc context - \param el an element - \param other_el another element - \param options flags controlling the function behaviour - - Without the LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES flag, return - LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS if the elements share values, and - LDB_SUCCESS if they don't. That is, determine whether there is an - intersection without changing anything. - - With the LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES flag, any values in common - are removed from the first element and LDB_SUCCESS is returned. - - LDB_ERR_OPERATIONS_ERROR indicates an allocation failure or an unknown option. - LDB_ERR_INAPPROPRIATE_MATCHING means the elements differ in name. -*/ - -int ldb_msg_find_common_values(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - struct ldb_message_element *el, - struct ldb_message_element *other_el, - uint32_t options); - -/** - Detect whether an element contains duplicate values - - \param ldb a currently unused ldb_context struct - \param mem_ctx a talloc context - \param el the element to search - \param duplicate will point to a duplicate value if there are duplicates, - or NULL otherwise. - \param options is a flags field. All values are reserved. - - \return an ldb error code. LDB_ERR_OPERATIONS_ERROR indicates an allocation - failure or an unknown option flag. Otherwise LDB_SUCCESS. - - \note This search is case sensitive -*/ -int ldb_msg_find_duplicate_val(struct ldb_context *ldb, - TALLOC_CTX *mem_ctx, - const struct ldb_message_element *el, - struct ldb_val **duplicate, - uint32_t options); -/** - Check if a particular message will match the given filter - - \param ldb an ldb context - \param msg the message to be checked - \param tree the filter tree to check against - \param scope the scope to match against - (to avoid matching special DNs except on a base search) - \param matched a pointer to a boolean set true if it matches, - false otherwise - - returns LDB_SUCCESS or an error - - \note this is a recursive function, and does short-circuit evaluation - */ -int ldb_match_message(struct ldb_context *ldb, - const struct ldb_message *msg, - const struct ldb_parse_tree *tree, - enum ldb_scope scope, bool *matched); - -#endif diff --git a/ldb-2.0.8/ldb.pc.in b/ldb-2.0.8/ldb.pc.in deleted file mode 100644 index aeba17a..0000000 --- a/ldb-2.0.8/ldb.pc.in +++ /dev/null @@ -1,16 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -modulesdir=@LDB_MODULESDIR@ - -Name: ldb -Description: An LDAP-like embedded database -Version: @PACKAGE_VERSION@ -Requires.private: tdb -Requires: talloc -Libs: @LIB_RPATH@ -L${libdir} -lldb -Libs.private: @LDAP_LIBS@ -Cflags: -I${includedir} -Modulesdir: ${modulesdir} -URL: http://ldb.samba.org/ diff --git a/ldb-2.0.8/ldb_key_value/ldb_kv.c b/ldb-2.0.8/ldb_key_value/ldb_kv.c deleted file mode 100644 index 4e7b8a1..0000000 --- a/ldb-2.0.8/ldb_key_value/ldb_kv.c +++ /dev/null @@ -1,2292 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 2006-2008 - Copyright (C) Matthias Dieter Wallnöfer 2009-2010 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb_kv - * - * Component: ldb key value backend - * - * Description: core functions for ldb key value backend - * - * Author: Andrew Tridgell - * Author: Stefan Metzmacher - * - * Modifications: - * - * - description: make the module use asynchronous calls - * date: Feb 2006 - * Author: Simo Sorce - * - * - description: make it possible to use event contexts - * date: Jan 2008 - * Author: Simo Sorce - * - * - description: fix up memory leaks and small bugs - * date: Oct 2009 - * Author: Matthias Dieter Wallnöfer - */ - -#include "ldb_kv.h" -#include "ldb_private.h" -#include "lib/util/attr.h" - -/* - prevent memory errors on callbacks -*/ -struct ldb_kv_req_spy { - struct ldb_kv_context *ctx; -}; - -/* - * Determine if this key could hold a record. We allow the new GUID - * index, the old DN index and a possible future ID= - */ -bool ldb_kv_key_is_normal_record(struct ldb_val key) -{ - if (key.length < 4) { - return false; - } - - /* - * @ records are not normal records, we don't want to index - * them nor search on them - */ - if (key.length > 4 && - memcmp(key.data, "DN=@", 4) == 0) { - return false; - } - - /* All other DN= records are however */ - if (memcmp(key.data, "DN=", 3) == 0) { - return true; - } - - if (memcmp(key.data, "ID=", 3) == 0) { - return true; - } - - if (key.length < sizeof(LDB_KV_GUID_KEY_PREFIX)) { - return false; - } - - if (memcmp(key.data, LDB_KV_GUID_KEY_PREFIX, - sizeof(LDB_KV_GUID_KEY_PREFIX) - 1) == 0) { - return true; - } - - return false; -} - -/* - form a ldb_val for a record key - caller frees - - note that the key for a record can depend on whether the - dn refers to a case sensitive index record or not -*/ -struct ldb_val ldb_kv_key_dn(TALLOC_CTX *mem_ctx, - struct ldb_dn *dn) -{ - struct ldb_val key; - char *key_str = NULL; - const char *dn_folded = NULL; - - /* - most DNs are case insensitive. The exception is index DNs for - case sensitive attributes - - there are 3 cases dealt with in this code: - - 1) if the dn doesn't start with @ then uppercase the attribute - names and the attributes values of case insensitive attributes - 2) if the dn starts with @ then leave it alone - - the indexing code handles the rest - */ - - dn_folded = ldb_dn_get_casefold(dn); - if (!dn_folded) { - goto failed; - } - - key_str = talloc_strdup(mem_ctx, "DN="); - if (!key_str) { - goto failed; - } - - key_str = talloc_strdup_append_buffer(key_str, dn_folded); - if (!key_str) { - goto failed; - } - - key.data = (uint8_t *)key_str; - key.length = strlen(key_str) + 1; - - return key; - -failed: - errno = ENOMEM; - key.data = NULL; - key.length = 0; - return key; -} - -/* The caller is to provide a correctly sized key */ -int ldb_kv_guid_to_key(const struct ldb_val *GUID_val, - struct ldb_val *key) -{ - const char *GUID_prefix = LDB_KV_GUID_KEY_PREFIX; - const int GUID_prefix_len = sizeof(LDB_KV_GUID_KEY_PREFIX) - 1; - - if (key->length != (GUID_val->length+GUID_prefix_len)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - memcpy(key->data, GUID_prefix, GUID_prefix_len); - memcpy(&key->data[GUID_prefix_len], - GUID_val->data, GUID_val->length); - return LDB_SUCCESS; -} - -/* - * The caller is to provide a correctly sized key, used only in - * the GUID index mode - */ -int ldb_kv_idx_to_key(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - TALLOC_CTX *mem_ctx, - const struct ldb_val *idx_val, - struct ldb_val *key) -{ - struct ldb_context *ldb = ldb_module_get_ctx(module); - struct ldb_dn *dn; - - if (ldb_kv->cache->GUID_index_attribute != NULL) { - return ldb_kv_guid_to_key(idx_val, key); - } - - dn = ldb_dn_from_ldb_val(mem_ctx, ldb, idx_val); - if (dn == NULL) { - /* - * LDB_ERR_INVALID_DN_SYNTAX would just be confusing - * to the caller, as this in an invalid index value - */ - return LDB_ERR_OPERATIONS_ERROR; - } - /* form the key */ - *key = ldb_kv_key_dn(mem_ctx, dn); - TALLOC_FREE(dn); - if (!key->data) { - return ldb_module_oom(module); - } - return LDB_SUCCESS; -} - -/* - form a TDB_DATA for a record key - caller frees mem_ctx, which may or may not have the key - as a child. - - note that the key for a record can depend on whether a - GUID index is in use, or the DN is used as the key -*/ -struct ldb_val ldb_kv_key_msg(struct ldb_module *module, - TALLOC_CTX *mem_ctx, - const struct ldb_message *msg) -{ - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - struct ldb_val key; - const struct ldb_val *guid_val; - int ret; - - if (ldb_kv->cache->GUID_index_attribute == NULL) { - return ldb_kv_key_dn(mem_ctx, msg->dn); - } - - if (ldb_dn_is_special(msg->dn)) { - return ldb_kv_key_dn(mem_ctx, msg->dn); - } - - guid_val = - ldb_msg_find_ldb_val(msg, ldb_kv->cache->GUID_index_attribute); - if (guid_val == NULL) { - ldb_asprintf_errstring(ldb_module_get_ctx(module), - "Did not find GUID attribute %s " - "in %s, required for TDB record " - "key in " LDB_KV_IDXGUID " mode.", - ldb_kv->cache->GUID_index_attribute, - ldb_dn_get_linearized(msg->dn)); - errno = EINVAL; - key.data = NULL; - key.length = 0; - return key; - } - - /* In this case, allocate with talloc */ - key.data = talloc_size(mem_ctx, LDB_KV_GUID_KEY_SIZE); - if (key.data == NULL) { - errno = ENOMEM; - key.data = NULL; - key.length = 0; - return key; - } - key.length = talloc_get_size(key.data); - - ret = ldb_kv_guid_to_key(guid_val, &key); - - if (ret != LDB_SUCCESS) { - errno = EINVAL; - key.data = NULL; - key.length = 0; - return key; - } - return key; -} - -/* - check special dn's have valid attributes - currently only @ATTRIBUTES is checked -*/ -static int ldb_kv_check_special_dn(struct ldb_module *module, - const struct ldb_message *msg) -{ - struct ldb_context *ldb = ldb_module_get_ctx(module); - unsigned int i, j; - - if (! ldb_dn_is_special(msg->dn) || - ! ldb_dn_check_special(msg->dn, LDB_KV_ATTRIBUTES)) { - return LDB_SUCCESS; - } - - /* we have @ATTRIBUTES, let's check attributes are fine */ - /* should we check that we deny multivalued attributes ? */ - for (i = 0; i < msg->num_elements; i++) { - if (ldb_attr_cmp(msg->elements[i].name, "distinguishedName") == 0) continue; - - for (j = 0; j < msg->elements[i].num_values; j++) { - if (ldb_kv_check_at_attributes_values( - &msg->elements[i].values[j]) != 0) { - ldb_set_errstring(ldb, "Invalid attribute value in an @ATTRIBUTES entry"); - return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX; - } - } - } - - return LDB_SUCCESS; -} - -/* - * Called after modifies and when starting a transaction. Checks target pack - * format version and current pack format version, which are set by cache_load, - * and repacks if necessary. - */ -static int ldb_kv_maybe_repack(struct ldb_kv_private *ldb_kv) { - /* Override option taken from ldb options */ - if (ldb_kv->pack_format_override != 0) { - ldb_kv->target_pack_format_version = - ldb_kv->pack_format_override; - } - - if (ldb_kv->pack_format_version != - ldb_kv->target_pack_format_version) { - int r; - struct ldb_context *ldb = ldb_module_get_ctx(ldb_kv->module); - r = ldb_kv_repack(ldb_kv->module); - if (r != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Database repack failed."); - } - return r; - } - - return LDB_SUCCESS; -} - -/* - we've made a modification to a dn - possibly reindex and - update sequence number -*/ -static int ldb_kv_modified(struct ldb_module *module, struct ldb_dn *dn) -{ - int ret = LDB_SUCCESS; - struct ldb_kv_private *ldb_kv = talloc_get_type( - ldb_module_get_private(module), struct ldb_kv_private); - - /* only allow modifies inside a transaction, otherwise the - * ldb is unsafe */ - if (ldb_kv->kv_ops->transaction_active(ldb_kv) == false) { - ldb_set_errstring(ldb_module_get_ctx(module), "ltdb modify without transaction"); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (ldb_dn_is_special(dn) && - (ldb_dn_check_special(dn, LDB_KV_INDEXLIST) || - ldb_dn_check_special(dn, LDB_KV_ATTRIBUTES)) ) - { - if (ldb_kv->warn_reindex) { - ldb_debug(ldb_module_get_ctx(module), - LDB_DEBUG_ERROR, - "Reindexing %s due to modification on %s", - ldb_kv->kv_ops->name(ldb_kv), - ldb_dn_get_linearized(dn)); - } - ret = ldb_kv_reindex(module); - } - - /* If the modify was to a normal record, or any special except @BASEINFO, update the seq number */ - if (ret == LDB_SUCCESS && - !(ldb_dn_is_special(dn) && - ldb_dn_check_special(dn, LDB_KV_BASEINFO)) ) { - ret = ldb_kv_increase_sequence_number(module); - } - - /* If the modify was to @OPTIONS, reload the cache */ - if (ret == LDB_SUCCESS && - ldb_dn_is_special(dn) && - (ldb_dn_check_special(dn, LDB_KV_OPTIONS)) ) { - ret = ldb_kv_cache_reload(module); - } - - if (ret != LDB_SUCCESS) { - ldb_kv->reindex_failed = true; - } - - return ret; -} -/* - store a record into the db -*/ -int ldb_kv_store(struct ldb_module *module, - const struct ldb_message *msg, - int flgs) -{ - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - struct ldb_val key; - struct ldb_val ldb_data; - int ret = LDB_SUCCESS; - TALLOC_CTX *key_ctx = talloc_new(module); - - if (key_ctx == NULL) { - return ldb_module_oom(module); - } - - if (ldb_kv->read_only) { - talloc_free(key_ctx); - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - key = ldb_kv_key_msg(module, key_ctx, msg); - if (key.data == NULL) { - TALLOC_FREE(key_ctx); - return LDB_ERR_OTHER; - } - - ret = ldb_pack_data(ldb_module_get_ctx(module), - msg, &ldb_data, - ldb_kv->pack_format_version); - if (ret == -1) { - TALLOC_FREE(key_ctx); - return LDB_ERR_OTHER; - } - - ret = ldb_kv->kv_ops->store(ldb_kv, key, ldb_data, flgs); - if (ret != 0) { - bool is_special = ldb_dn_is_special(msg->dn); - ret = ldb_kv->kv_ops->error(ldb_kv); - - /* - * LDB_ERR_ENTRY_ALREADY_EXISTS means the DN, not - * the GUID, so re-map - */ - if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS && !is_special && - ldb_kv->cache->GUID_index_attribute != NULL) { - ret = LDB_ERR_CONSTRAINT_VIOLATION; - } - goto done; - } - -done: - TALLOC_FREE(key_ctx); - talloc_free(ldb_data.data); - - return ret; -} - - -/* - check if a attribute is a single valued, for a given element - */ -static bool ldb_kv_single_valued(const struct ldb_schema_attribute *a, - struct ldb_message_element *el) -{ - if (!a) return false; - if (el != NULL) { - if (el->flags & LDB_FLAG_INTERNAL_FORCE_SINGLE_VALUE_CHECK) { - /* override from a ldb module, for example - used for the description field, which is - marked multi-valued in the schema but which - should not actually accept multiple - values */ - return true; - } - if (el->flags & LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK) { - /* override from a ldb module, for example used for - deleted linked attribute entries */ - return false; - } - } - if (a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) { - return true; - } - return false; -} - -/* - * Starts a sub transaction if they are supported by the backend - * and the ldb connection has not been opened in batch mode. - */ -static int ldb_kv_sub_transaction_start(struct ldb_kv_private *ldb_kv) -{ - int ret = LDB_SUCCESS; - - if (ldb_kv->batch_mode) { - return ret; - } - - ret = ldb_kv->kv_ops->begin_nested_write(ldb_kv); - if (ret == LDB_SUCCESS) { - ret = ldb_kv_index_sub_transaction_start(ldb_kv); - } - return ret; -} - -/* - * Commits a sub transaction if they are supported by the backend - * and the ldb connection has not been opened in batch mode. - */ -static int ldb_kv_sub_transaction_commit(struct ldb_kv_private *ldb_kv) -{ - int ret = LDB_SUCCESS; - - if (ldb_kv->batch_mode) { - return ret; - } - - ret = ldb_kv_index_sub_transaction_commit(ldb_kv); - if (ret != LDB_SUCCESS) { - return ret; - } - ret = ldb_kv->kv_ops->finish_nested_write(ldb_kv); - return ret; -} - -/* - * Cancels a sub transaction if they are supported by the backend - * and the ldb connection has not been opened in batch mode. - */ -static int ldb_kv_sub_transaction_cancel(struct ldb_kv_private *ldb_kv) -{ - int ret = LDB_SUCCESS; - - if (ldb_kv->batch_mode) { - return ret; - } - - ret = ldb_kv_index_sub_transaction_cancel(ldb_kv); - if (ret != LDB_SUCCESS) { - struct ldb_context *ldb = ldb_module_get_ctx(ldb_kv->module); - /* - * In the event of a failure we log the failure and continue - * as we need to cancel the database transaction. - */ - ldb_debug(ldb, - LDB_DEBUG_ERROR, - __location__": ldb_kv_index_sub_transaction_cancel " - "failed: %s", - ldb_errstring(ldb)); - } - ret = ldb_kv->kv_ops->abort_nested_write(ldb_kv); - return ret; -} - -static int ldb_kv_add_internal(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_message *msg, - bool check_single_value) -{ - struct ldb_context *ldb = ldb_module_get_ctx(module); - int ret = LDB_SUCCESS; - unsigned int i; - bool valid_dn = false; - - /* Check the new DN is reasonable */ - valid_dn = ldb_dn_validate(msg->dn); - if (valid_dn == false) { - ldb_asprintf_errstring(ldb_module_get_ctx(module), - "Invalid DN in ADD: %s", - ldb_dn_get_linearized(msg->dn)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - for (i=0;inum_elements;i++) { - struct ldb_message_element *el = &msg->elements[i]; - const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name); - - if (el->num_values == 0) { - ldb_asprintf_errstring(ldb, "attribute '%s' on '%s' specified, but with 0 values (illegal)", - el->name, ldb_dn_get_linearized(msg->dn)); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - if (check_single_value && el->num_values > 1 && - ldb_kv_single_valued(a, el)) { - ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", - el->name, ldb_dn_get_linearized(msg->dn)); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - - /* Do not check "@ATTRIBUTES" for duplicated values */ - if (ldb_dn_is_special(msg->dn) && - ldb_dn_check_special(msg->dn, LDB_KV_ATTRIBUTES)) { - continue; - } - - if (check_single_value && - !(el->flags & - LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK)) { - struct ldb_val *duplicate = NULL; - - ret = ldb_msg_find_duplicate_val(ldb, discard_const(msg), - el, &duplicate, 0); - if (ret != LDB_SUCCESS) { - return ret; - } - if (duplicate != NULL) { - ldb_asprintf_errstring( - ldb, - "attribute '%s': value '%.*s' on '%s' " - "provided more than once in ADD object", - el->name, - (int)duplicate->length, - duplicate->data, - ldb_dn_get_linearized(msg->dn)); - return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; - } - } - } - - ret = ldb_kv_store(module, msg, TDB_INSERT); - if (ret != LDB_SUCCESS) { - /* - * Try really hard to get the right error code for - * a re-add situation, as this can matter! - */ - if (ret == LDB_ERR_CONSTRAINT_VIOLATION) { - int ret2; - struct ldb_dn *dn2 = NULL; - TALLOC_CTX *mem_ctx = talloc_new(module); - if (mem_ctx == NULL) { - return ldb_module_operr(module); - } - ret2 = - ldb_kv_search_base(module, mem_ctx, msg->dn, &dn2); - TALLOC_FREE(mem_ctx); - if (ret2 == LDB_SUCCESS) { - ret = LDB_ERR_ENTRY_ALREADY_EXISTS; - } - } - if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { - ldb_asprintf_errstring(ldb, - "Entry %s already exists", - ldb_dn_get_linearized(msg->dn)); - } - return ret; - } - - ret = ldb_kv_index_add_new(module, ldb_kv, msg); - if (ret != LDB_SUCCESS) { - /* - * If we failed to index, delete the message again. - * - * This is particularly important for the GUID index - * case, which will only fail for a duplicate DN - * in the index add. - * - * Note that the caller may not cancel the transation - * and this means the above add might really show up! - */ - ldb_kv_delete_noindex(module, msg); - return ret; - } - - ret = ldb_kv_modified(module, msg->dn); - - /* - * To allow testing of the error recovery code in ldb_kv_add - * cmocka tests can define CMOCKA_UNIT_TEST_ADD_INTERNAL_FAIL - * to inject failures at this point. - */ -#ifdef CMOCKA_UNIT_TEST_ADD_INTERNAL_FAIL - CMOCKA_UNIT_TEST_ADD_INTERNAL_FAIL -#endif - - return ret; -} - -/* - add a record to the database -*/ -static int ldb_kv_add(struct ldb_kv_context *ctx) -{ - struct ldb_module *module = ctx->module; - struct ldb_request *req = ctx->req; - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - int ret = LDB_SUCCESS; - - if (ldb_kv->max_key_length != 0 && - ldb_kv->cache->GUID_index_attribute == NULL && - !ldb_dn_is_special(req->op.add.message->dn)) { - ldb_set_errstring(ldb_module_get_ctx(module), - "Must operate ldb_mdb in GUID " - "index mode, but " LDB_KV_IDXGUID " not set."); - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - ret = ldb_kv_check_special_dn(module, req->op.add.message); - if (ret != LDB_SUCCESS) { - return ret; - } - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - if (ldb_kv_cache_load(module) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_kv_sub_transaction_start(ldb_kv); - if (ret != LDB_SUCCESS) { - return ret; - } - ret = ldb_kv_add_internal(module, ldb_kv, req->op.add.message, true); - if (ret != LDB_SUCCESS) { - int r = ldb_kv_sub_transaction_cancel(ldb_kv); - if (r != LDB_SUCCESS) { - ldb_debug( - ldb_module_get_ctx(module), - LDB_DEBUG_FATAL, - __location__ - ": Unable to roll back sub transaction"); - } - ldb_kv->operation_failed = true; - return ret; - } - ret = ldb_kv_sub_transaction_commit(ldb_kv); - - return ret; -} - -/* - delete a record from the database, not updating indexes (used for deleting - index records) -*/ -int ldb_kv_delete_noindex(struct ldb_module *module, - const struct ldb_message *msg) -{ - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - struct ldb_val key; - int ret; - TALLOC_CTX *tdb_key_ctx = talloc_new(module); - - if (tdb_key_ctx == NULL) { - return ldb_module_oom(module); - } - - if (ldb_kv->read_only) { - talloc_free(tdb_key_ctx); - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - key = ldb_kv_key_msg(module, tdb_key_ctx, msg); - if (!key.data) { - TALLOC_FREE(tdb_key_ctx); - return LDB_ERR_OTHER; - } - - ret = ldb_kv->kv_ops->delete(ldb_kv, key); - TALLOC_FREE(tdb_key_ctx); - - if (ret != 0) { - ret = ldb_kv->kv_ops->error(ldb_kv); - } - - return ret; -} - -static int ldb_kv_delete_internal(struct ldb_module *module, struct ldb_dn *dn) -{ - struct ldb_message *msg; - int ret = LDB_SUCCESS; - - msg = ldb_msg_new(module); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* in case any attribute of the message was indexed, we need - to fetch the old record */ - ret = ldb_kv_search_dn1(module, dn, msg, 0); - if (ret != LDB_SUCCESS) { - /* not finding the old record is an error */ - goto done; - } - - ret = ldb_kv_delete_noindex(module, msg); - if (ret != LDB_SUCCESS) { - goto done; - } - - /* remove any indexed attributes */ - ret = ldb_kv_index_delete(module, msg); - if (ret != LDB_SUCCESS) { - goto done; - } - - ret = ldb_kv_modified(module, dn); - if (ret != LDB_SUCCESS) { - goto done; - } - -done: - talloc_free(msg); - /* - * To allow testing of the error recovery code in ldb_kv_delete - * cmocka tests can define CMOCKA_UNIT_TEST_DELETE_INTERNAL_FAIL - * to inject failures at this point. - */ -#ifdef CMOCKA_UNIT_TEST_DELETE_INTERNAL_FAIL - CMOCKA_UNIT_TEST_DELETE_INTERNAL_FAIL -#endif - return ret; -} - -/* - delete a record from the database -*/ -static int ldb_kv_delete(struct ldb_kv_context *ctx) -{ - struct ldb_module *module = ctx->module; - struct ldb_request *req = ctx->req; - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - int ret = LDB_SUCCESS; - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - if (ldb_kv_cache_load(module) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_kv_sub_transaction_start(ldb_kv); - if (ret != LDB_SUCCESS) { - return ret; - } - ret = ldb_kv_delete_internal(module, req->op.del.dn); - if (ret != LDB_SUCCESS) { - int r = ldb_kv_sub_transaction_cancel(ldb_kv); - if (r != LDB_SUCCESS) { - ldb_debug( - ldb_module_get_ctx(module), - LDB_DEBUG_FATAL, - __location__ - ": Unable to roll back sub transaction"); - } - if (ret != LDB_ERR_NO_SUCH_OBJECT) { - ldb_kv->operation_failed = true; - } - return ret; - } - ret = ldb_kv_sub_transaction_commit(ldb_kv); - - return ret; -} - -/* - find an element by attribute name. At the moment this does a linear search, - it should be re-coded to use a binary search once all places that modify - records guarantee sorted order - - return the index of the first matching element if found, otherwise -1 -*/ -static int ldb_kv_find_element(const struct ldb_message *msg, const char *name) -{ - unsigned int i; - for (i=0;inum_elements;i++) { - if (ldb_attr_cmp(msg->elements[i].name, name) == 0) { - return i; - } - } - return -1; -} - - -/* - add an element to an existing record. Assumes a elements array that we - can call re-alloc on, and assumed that we can re-use the data pointers from - the passed in additional values. Use with care! - - returns 0 on success, -1 on failure (and sets errno) -*/ -static int ldb_kv_msg_add_element(struct ldb_message *msg, - struct ldb_message_element *el) -{ - struct ldb_message_element *e2; - unsigned int i; - - if (el->num_values == 0) { - /* nothing to do here - we don't add empty elements */ - return 0; - } - - e2 = talloc_realloc(msg, msg->elements, struct ldb_message_element, - msg->num_elements+1); - if (!e2) { - errno = ENOMEM; - return -1; - } - - msg->elements = e2; - - e2 = &msg->elements[msg->num_elements]; - - e2->name = el->name; - e2->flags = el->flags; - e2->values = talloc_array(msg->elements, - struct ldb_val, el->num_values); - if (!e2->values) { - errno = ENOMEM; - return -1; - } - for (i=0;inum_values;i++) { - e2->values[i] = el->values[i]; - } - e2->num_values = el->num_values; - - ++msg->num_elements; - - return 0; -} - -/* - delete all elements having a specified attribute name -*/ -static int ldb_kv_msg_delete_attribute(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - struct ldb_message *msg, - const char *name) -{ - int ret; - struct ldb_message_element *el; - bool is_special = ldb_dn_is_special(msg->dn); - - if (!is_special && ldb_kv->cache->GUID_index_attribute != NULL && - ldb_attr_cmp(name, ldb_kv->cache->GUID_index_attribute) == 0) { - struct ldb_context *ldb = ldb_module_get_ctx(module); - ldb_asprintf_errstring(ldb, - "Must not modify GUID " - "attribute %s (used as DB index)", - ldb_kv->cache->GUID_index_attribute); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - - el = ldb_msg_find_element(msg, name); - if (el == NULL) { - return LDB_ERR_NO_SUCH_ATTRIBUTE; - } - - ret = ldb_kv_index_del_element(module, ldb_kv, msg, el); - if (ret != LDB_SUCCESS) { - return ret; - } - - talloc_free(el->values); - ldb_msg_remove_element(msg, el); - msg->elements = talloc_realloc(msg, msg->elements, - struct ldb_message_element, - msg->num_elements); - return LDB_SUCCESS; -} - -/* - delete all elements matching an attribute name/value - - return LDB Error on failure -*/ -static int ldb_kv_msg_delete_element(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - struct ldb_message *msg, - const char *name, - const struct ldb_val *val) -{ - struct ldb_context *ldb = ldb_module_get_ctx(module); - unsigned int i; - int found, ret; - struct ldb_message_element *el; - const struct ldb_schema_attribute *a; - - found = ldb_kv_find_element(msg, name); - if (found == -1) { - return LDB_ERR_NO_SUCH_ATTRIBUTE; - } - - i = (unsigned int) found; - el = &(msg->elements[i]); - - a = ldb_schema_attribute_by_name(ldb, el->name); - - for (i=0;inum_values;i++) { - bool matched; - if (a->syntax->operator_fn) { - ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a, - &el->values[i], val, &matched); - if (ret != LDB_SUCCESS) return ret; - } else { - matched = (a->syntax->comparison_fn(ldb, ldb, - &el->values[i], val) == 0); - } - if (matched) { - if (el->num_values == 1) { - return ldb_kv_msg_delete_attribute( - module, ldb_kv, msg, name); - } - - ret = - ldb_kv_index_del_value(module, ldb_kv, msg, el, i); - if (ret != LDB_SUCCESS) { - return ret; - } - - if (inum_values-1) { - memmove(&el->values[i], &el->values[i+1], - sizeof(el->values[i])* - (el->num_values-(i+1))); - } - el->num_values--; - - /* per definition we find in a canonicalised message an - attribute value only once. So we are finished here */ - return LDB_SUCCESS; - } - } - - /* Not found */ - return LDB_ERR_NO_SUCH_ATTRIBUTE; -} - -/* - modify a record - internal interface - - yuck - this is O(n^2). Luckily n is usually small so we probably - get away with it, but if we ever have really large attribute lists - then we'll need to look at this again - - 'req' is optional, and is used to specify controls if supplied -*/ -int ldb_kv_modify_internal(struct ldb_module *module, - const struct ldb_message *msg, - struct ldb_request *req) -{ - struct ldb_context *ldb = ldb_module_get_ctx(module); - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - struct ldb_message *msg2; - unsigned int i, j; - int ret = LDB_SUCCESS, idx; - struct ldb_control *control_permissive = NULL; - TALLOC_CTX *mem_ctx = talloc_new(req); - - if (mem_ctx == NULL) { - return ldb_module_oom(module); - } - - if (req) { - control_permissive = ldb_request_get_control(req, - LDB_CONTROL_PERMISSIVE_MODIFY_OID); - } - - msg2 = ldb_msg_new(mem_ctx); - if (msg2 == NULL) { - ret = LDB_ERR_OTHER; - goto done; - } - - ret = ldb_kv_search_dn1(module, msg->dn, msg2, 0); - if (ret != LDB_SUCCESS) { - goto done; - } - - for (i=0; inum_elements; i++) { - struct ldb_message_element *el = &msg->elements[i], *el2; - struct ldb_val *vals; - const struct ldb_schema_attribute *a = ldb_schema_attribute_by_name(ldb, el->name); - const char *dn; - uint32_t options = 0; - if (control_permissive != NULL) { - options |= LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES; - } - - switch (msg->elements[i].flags & LDB_FLAG_MOD_MASK) { - case LDB_FLAG_MOD_ADD: - - if (el->num_values == 0) { - ldb_asprintf_errstring(ldb, - "attribute '%s': attribute on '%s' specified, but with 0 values (illegal)", - el->name, ldb_dn_get_linearized(msg2->dn)); - ret = LDB_ERR_CONSTRAINT_VIOLATION; - goto done; - } - - /* make a copy of the array so that a permissive - * control can remove duplicates without changing the - * original values, but do not copy data as we do not - * need to keep it around once the operation is - * finished */ - if (control_permissive) { - el = talloc(msg2, struct ldb_message_element); - if (!el) { - ret = LDB_ERR_OTHER; - goto done; - } - *el = msg->elements[i]; - el->values = talloc_array(el, struct ldb_val, el->num_values); - if (el->values == NULL) { - ret = LDB_ERR_OTHER; - goto done; - } - for (j = 0; j < el->num_values; j++) { - el->values[j] = msg->elements[i].values[j]; - } - } - - if (el->num_values > 1 && ldb_kv_single_valued(a, el)) { - ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", - el->name, ldb_dn_get_linearized(msg2->dn)); - ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; - goto done; - } - - /* Checks if element already exists */ - idx = ldb_kv_find_element(msg2, el->name); - if (idx == -1) { - if (ldb_kv_msg_add_element(msg2, el) != 0) { - ret = LDB_ERR_OTHER; - goto done; - } - ret = ldb_kv_index_add_element( - module, ldb_kv, msg2, el); - if (ret != LDB_SUCCESS) { - goto done; - } - } else { - j = (unsigned int) idx; - el2 = &(msg2->elements[j]); - - /* We cannot add another value on a existing one - if the attribute is single-valued */ - if (ldb_kv_single_valued(a, el)) { - ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", - el->name, ldb_dn_get_linearized(msg2->dn)); - ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; - goto done; - } - - /* Check that values don't exist yet on multi- - valued attributes or aren't provided twice */ - if (!(el->flags & - LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK)) { - struct ldb_val *duplicate = NULL; - ret = ldb_msg_find_common_values(ldb, - msg2, - el, - el2, - options); - - if (ret == - LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) { - ldb_asprintf_errstring(ldb, - "attribute '%s': value " - "#%u on '%s' already " - "exists", el->name, j, - ldb_dn_get_linearized(msg2->dn)); - goto done; - } else if (ret != LDB_SUCCESS) { - goto done; - } - - ret = ldb_msg_find_duplicate_val( - ldb, msg2, el, &duplicate, 0); - if (ret != LDB_SUCCESS) { - goto done; - } - if (duplicate != NULL) { - ldb_asprintf_errstring( - ldb, - "attribute '%s': value " - "'%.*s' on '%s' " - "provided more than " - "once in ADD", - el->name, - (int)duplicate->length, - duplicate->data, - ldb_dn_get_linearized(msg->dn)); - ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; - goto done; - } - } - - /* Now combine existing and new values to a new - attribute record */ - vals = talloc_realloc(msg2->elements, - el2->values, struct ldb_val, - el2->num_values + el->num_values); - if (vals == NULL) { - ldb_oom(ldb); - ret = LDB_ERR_OTHER; - goto done; - } - - for (j=0; jnum_values; j++) { - vals[el2->num_values + j] = - ldb_val_dup(vals, &el->values[j]); - } - - el2->values = vals; - el2->num_values += el->num_values; - - ret = ldb_kv_index_add_element( - module, ldb_kv, msg2, el); - if (ret != LDB_SUCCESS) { - goto done; - } - } - - break; - - case LDB_FLAG_MOD_REPLACE: - - if (el->num_values > 1 && ldb_kv_single_valued(a, el)) { - ldb_asprintf_errstring(ldb, "SINGLE-VALUE attribute %s on %s specified more than once", - el->name, ldb_dn_get_linearized(msg2->dn)); - ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; - goto done; - } - - /* - * We don't need to check this if we have been - * pre-screened by the repl_meta_data module - * in Samba, or someone else who can claim to - * know what they are doing. - */ - if (!(el->flags & LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK)) { - struct ldb_val *duplicate = NULL; - - ret = ldb_msg_find_duplicate_val(ldb, msg2, el, - &duplicate, 0); - if (ret != LDB_SUCCESS) { - goto done; - } - if (duplicate != NULL) { - ldb_asprintf_errstring( - ldb, - "attribute '%s': value '%.*s' " - "on '%s' provided more than " - "once in REPLACE", - el->name, - (int)duplicate->length, - duplicate->data, - ldb_dn_get_linearized(msg2->dn)); - ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; - goto done; - } - } - - /* Checks if element already exists */ - idx = ldb_kv_find_element(msg2, el->name); - if (idx != -1) { - j = (unsigned int) idx; - el2 = &(msg2->elements[j]); - - /* we consider two elements to be - * equal only if the order - * matches. This allows dbcheck to - * fix the ordering on attributes - * where order matters, such as - * objectClass - */ - if (ldb_msg_element_equal_ordered(el, el2)) { - continue; - } - - /* Delete the attribute if it exists in the DB */ - if (ldb_kv_msg_delete_attribute( - module, ldb_kv, msg2, el->name) != 0) { - ret = LDB_ERR_OTHER; - goto done; - } - } - - /* Recreate it with the new values */ - if (ldb_kv_msg_add_element(msg2, el) != 0) { - ret = LDB_ERR_OTHER; - goto done; - } - - ret = - ldb_kv_index_add_element(module, ldb_kv, msg2, el); - if (ret != LDB_SUCCESS) { - goto done; - } - - break; - - case LDB_FLAG_MOD_DELETE: - dn = ldb_dn_get_linearized(msg2->dn); - if (dn == NULL) { - ret = LDB_ERR_OTHER; - goto done; - } - - if (msg->elements[i].num_values == 0) { - /* Delete the whole attribute */ - ret = ldb_kv_msg_delete_attribute( - module, - ldb_kv, - msg2, - msg->elements[i].name); - if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE && - control_permissive) { - ret = LDB_SUCCESS; - } else { - ldb_asprintf_errstring(ldb, - "attribute '%s': no such attribute for delete on '%s'", - msg->elements[i].name, dn); - } - if (ret != LDB_SUCCESS) { - goto done; - } - } else { - /* Delete specified values from an attribute */ - for (j=0; j < msg->elements[i].num_values; j++) { - ret = ldb_kv_msg_delete_element( - module, - ldb_kv, - msg2, - msg->elements[i].name, - &msg->elements[i].values[j]); - if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE && - control_permissive) { - ret = LDB_SUCCESS; - } else if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { - ldb_asprintf_errstring(ldb, - "attribute '%s': no matching attribute value while deleting attribute on '%s'", - msg->elements[i].name, dn); - } - if (ret != LDB_SUCCESS) { - goto done; - } - } - } - break; - default: - ldb_asprintf_errstring(ldb, - "attribute '%s': invalid modify flags on '%s': 0x%x", - msg->elements[i].name, ldb_dn_get_linearized(msg->dn), - msg->elements[i].flags & LDB_FLAG_MOD_MASK); - ret = LDB_ERR_PROTOCOL_ERROR; - goto done; - } - } - - ret = ldb_kv_store(module, msg2, TDB_MODIFY); - if (ret != LDB_SUCCESS) { - goto done; - } - - ret = ldb_kv_modified(module, msg2->dn); - if (ret != LDB_SUCCESS) { - goto done; - } - -done: - TALLOC_FREE(mem_ctx); - /* - * To allow testing of the error recovery code in ldb_kv_modify - * cmocka tests can define CMOCKA_UNIT_TEST_MODIFY_INTERNAL_FAIL - * to inject failures at this point. - */ -#ifdef CMOCKA_UNIT_TEST_MODIFY_INTERNAL_FAIL - CMOCKA_UNIT_TEST_MODIFY_INTERNAL_FAIL -#endif - return ret; -} - -/* - modify a record -*/ -static int ldb_kv_modify(struct ldb_kv_context *ctx) -{ - struct ldb_module *module = ctx->module; - struct ldb_request *req = ctx->req; - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - int ret = LDB_SUCCESS; - - ret = ldb_kv_check_special_dn(module, req->op.mod.message); - if (ret != LDB_SUCCESS) { - return ret; - } - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - if (ldb_kv_cache_load(module) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_kv_sub_transaction_start(ldb_kv); - if (ret != LDB_SUCCESS) { - return ret; - } - ret = ldb_kv_modify_internal(module, req->op.mod.message, req); - if (ret != LDB_SUCCESS) { - int r = ldb_kv_sub_transaction_cancel(ldb_kv); - if (r != LDB_SUCCESS) { - ldb_debug( - ldb_module_get_ctx(module), - LDB_DEBUG_FATAL, - __location__ - ": Unable to roll back sub transaction"); - } - if (ret != LDB_ERR_NO_SUCH_OBJECT) { - ldb_kv->operation_failed = true; - } - return ret; - } - ret = ldb_kv_sub_transaction_commit(ldb_kv); - - - return ret; -} - -static int ldb_kv_rename_internal(struct ldb_module *module, - struct ldb_request *req, - struct ldb_message *msg) -{ - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - int ret = LDB_SUCCESS; - - /* Always delete first then add, to avoid conflicts with - * unique indexes. We rely on the transaction to make this - * atomic - */ - ret = ldb_kv_delete_internal(module, msg->dn); - if (ret != LDB_SUCCESS) { - return ret; - } - - msg->dn = ldb_dn_copy(msg, req->op.rename.newdn); - if (msg->dn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* We don't check single value as we can have more than 1 with - * deleted attributes. We could go through all elements but that's - * maybe not the most efficient way - */ - ret = ldb_kv_add_internal(module, ldb_kv, msg, false); - - /* - * To allow testing of the error recovery code in ldb_kv_rename - * cmocka tests can define CMOCKA_UNIT_TEST_RENAME_INTERNAL_FAIL - * to inject failures at this point. - */ -#ifdef CMOCKA_UNIT_TEST_RENAME_INTERNAL_FAIL - CMOCKA_UNIT_TEST_RENAME_INTERNAL_FAIL -#endif - return ret; -} - -/* - rename a record -*/ -static int ldb_kv_rename(struct ldb_kv_context *ctx) -{ - struct ldb_module *module = ctx->module; - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - struct ldb_request *req = ctx->req; - struct ldb_message *msg; - int ret = LDB_SUCCESS; - struct ldb_val key, key_old; - struct ldb_dn *db_dn; - bool valid_dn = false; - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - if (ldb_kv_cache_load(ctx->module) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - msg = ldb_msg_new(ctx); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Check the new DN is reasonable */ - valid_dn = ldb_dn_validate(req->op.rename.newdn); - if (valid_dn == false) { - ldb_asprintf_errstring(ldb_module_get_ctx(module), - "Invalid New DN: %s", - ldb_dn_get_linearized(req->op.rename.newdn)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - /* we need to fetch the old record to re-add under the new name */ - ret = ldb_kv_search_dn1(module, req->op.rename.olddn, msg, 0); - if (ret == LDB_ERR_INVALID_DN_SYNTAX) { - ldb_asprintf_errstring(ldb_module_get_ctx(module), - "Invalid Old DN: %s", - ldb_dn_get_linearized(req->op.rename.newdn)); - return ret; - } else if (ret != LDB_SUCCESS) { - /* not finding the old record is an error */ - return ret; - } - - /* We need to, before changing the DB, check if the new DN - * exists, so we can return this error to the caller with an - * unmodified DB - * - * Even in GUID index mode we use ltdb_key_dn() as we are - * trying to figure out if this is just a case rename - */ - key = ldb_kv_key_dn(msg, req->op.rename.newdn); - if (!key.data) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - key_old = ldb_kv_key_dn(msg, req->op.rename.olddn); - if (!key_old.data) { - talloc_free(msg); - talloc_free(key.data); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* - * Only declare a conflict if the new DN already exists, - * and it isn't a case change on the old DN - */ - if (key_old.length != key.length - || memcmp(key.data, key_old.data, key.length) != 0) { - ret = ldb_kv_search_base( - module, msg, req->op.rename.newdn, &db_dn); - if (ret == LDB_SUCCESS) { - ret = LDB_ERR_ENTRY_ALREADY_EXISTS; - } else if (ret == LDB_ERR_NO_SUCH_OBJECT) { - ret = LDB_SUCCESS; - } - } - - /* finding the new record already in the DB is an error */ - - if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { - ldb_asprintf_errstring(ldb_module_get_ctx(module), - "Entry %s already exists", - ldb_dn_get_linearized(req->op.rename.newdn)); - } - if (ret != LDB_SUCCESS) { - talloc_free(key_old.data); - talloc_free(key.data); - talloc_free(msg); - return ret; - } - - talloc_free(key_old.data); - talloc_free(key.data); - - - ret = ldb_kv_sub_transaction_start(ldb_kv); - if (ret != LDB_SUCCESS) { - talloc_free(msg); - return ret; - } - ret = ldb_kv_rename_internal(module, req, msg); - if (ret != LDB_SUCCESS) { - int r = ldb_kv_sub_transaction_cancel(ldb_kv); - if (r != LDB_SUCCESS) { - ldb_debug( - ldb_module_get_ctx(module), - LDB_DEBUG_FATAL, - __location__ - ": Unable to roll back sub transaction"); - } - talloc_free(msg); - ldb_kv->operation_failed = true; - return ret; - } - ret = ldb_kv_sub_transaction_commit(ldb_kv); - talloc_free(msg); - - return ret; -} - -static int ldb_kv_start_trans(struct ldb_module *module) -{ - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - - pid_t pid = getpid(); - - if (ldb_kv->pid != pid) { - ldb_asprintf_errstring(ldb_module_get_ctx(ldb_kv->module), - __location__ - ": Reusing ldb opend by pid %d in " - "process %d\n", - ldb_kv->pid, - pid); - return LDB_ERR_PROTOCOL_ERROR; - } - - /* Do not take out the transaction lock on a read-only DB */ - if (ldb_kv->read_only) { - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - if (ldb_kv->kv_ops->begin_write(ldb_kv) != 0) { - return ldb_kv->kv_ops->error(ldb_kv); - } - - ldb_kv_index_transaction_start( - module, - ldb_kv->index_transaction_cache_size); - - ldb_kv->reindex_failed = false; - ldb_kv->operation_failed = false; - - return LDB_SUCCESS; -} - -/* - * Forward declaration to allow prepare_commit to in fact abort the - * transaction - */ -static int ldb_kv_del_trans(struct ldb_module *module); - -static int ldb_kv_prepare_commit(struct ldb_module *module) -{ - int ret; - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - pid_t pid = getpid(); - - if (ldb_kv->pid != pid) { - ldb_asprintf_errstring(ldb_module_get_ctx(module), - __location__ - ": Reusing ldb opend by pid %d in " - "process %d\n", - ldb_kv->pid, - pid); - return LDB_ERR_PROTOCOL_ERROR; - } - - if (!ldb_kv->kv_ops->transaction_active(ldb_kv)) { - ldb_set_errstring(ldb_module_get_ctx(module), - "ltdb_prepare_commit() called " - "without transaction active"); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* - * Check if the last re-index failed. - * - * This can happen if for example a duplicate value was marked - * unique. We must not write a partial re-index into the DB. - */ - if (ldb_kv->reindex_failed) { - /* - * We must instead abort the transaction so we get the - * old values and old index back - */ - ldb_kv_del_trans(module); - ldb_set_errstring(ldb_module_get_ctx(module), - "Failure during re-index, so " - "transaction must be aborted."); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_kv_index_transaction_commit(module); - if (ret != LDB_SUCCESS) { - ldb_kv->kv_ops->abort_write(ldb_kv); - return ret; - } - - /* - * If GUID indexing was toggled in this transaction, we repack at - * format version 2 if GUID indexing was enabled, or version 1 if - * it was disabled. - */ - ret = ldb_kv_maybe_repack(ldb_kv); - if (ret != LDB_SUCCESS) { - ldb_kv_del_trans(module); - ldb_set_errstring(ldb_module_get_ctx(module), - "Failure during re-pack, so " - "transaction must be aborted."); - return ret; - } - - if (ldb_kv->kv_ops->prepare_write(ldb_kv) != 0) { - ret = ldb_kv->kv_ops->error(ldb_kv); - ldb_debug_set(ldb_module_get_ctx(module), - LDB_DEBUG_FATAL, - "Failure during " - "prepare_write): %s -> %s", - ldb_kv->kv_ops->errorstr(ldb_kv), - ldb_strerror(ret)); - return ret; - } - - ldb_kv->prepared_commit = true; - - return LDB_SUCCESS; -} - -static int ldb_kv_end_trans(struct ldb_module *module) -{ - int ret; - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - - /* - * If in batch mode and there has been an operation failure - * rollback the transaction rather than committing it to avoid - * any possible corruption - */ - if (ldb_kv->batch_mode && ldb_kv->operation_failed) { - ret = ldb_kv_del_trans( module); - if (ret != LDB_SUCCESS) { - ldb_debug_set(ldb_module_get_ctx(module), - LDB_DEBUG_FATAL, - "An operation failed during a batch mode " - "transaction. The transaction could not" - "be rolled back, ldb_kv_del_trans " - "returned (%s, %s)", - ldb_kv->kv_ops->errorstr(ldb_kv), - ldb_strerror(ret)); - } else { - ldb_debug_set(ldb_module_get_ctx(module), - LDB_DEBUG_FATAL, - "An operation failed during a batch mode " - "transaction, the transaction was " - "rolled back"); - } - return LDB_ERR_OPERATIONS_ERROR; - } - - if (!ldb_kv->prepared_commit) { - ret = ldb_kv_prepare_commit(module); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - ldb_kv->prepared_commit = false; - - if (ldb_kv->kv_ops->finish_write(ldb_kv) != 0) { - ret = ldb_kv->kv_ops->error(ldb_kv); - ldb_asprintf_errstring( - ldb_module_get_ctx(module), - "Failure during tdb_transaction_commit(): %s -> %s", - ldb_kv->kv_ops->errorstr(ldb_kv), - ldb_strerror(ret)); - return ret; - } - - return LDB_SUCCESS; -} - -static int ldb_kv_del_trans(struct ldb_module *module) -{ - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - - if (ldb_kv_index_transaction_cancel(module) != 0) { - ldb_kv->kv_ops->abort_write(ldb_kv); - return ldb_kv->kv_ops->error(ldb_kv); - } - - ldb_kv->kv_ops->abort_write(ldb_kv); - return LDB_SUCCESS; -} - -/* - return sequenceNumber from @BASEINFO -*/ -static int ldb_kv_sequence_number(struct ldb_kv_context *ctx, - struct ldb_extended **ext) -{ - struct ldb_context *ldb; - struct ldb_module *module = ctx->module; - struct ldb_request *req = ctx->req; - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - TALLOC_CTX *tmp_ctx = NULL; - struct ldb_seqnum_request *seq; - struct ldb_seqnum_result *res; - struct ldb_message *msg = NULL; - struct ldb_dn *dn; - const char *date; - int ret = LDB_SUCCESS; - - ldb = ldb_module_get_ctx(module); - - seq = talloc_get_type(req->op.extended.data, - struct ldb_seqnum_request); - if (seq == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - if (ldb_kv->kv_ops->lock_read(module) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - res = talloc_zero(req, struct ldb_seqnum_result); - if (res == NULL) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - - tmp_ctx = talloc_new(req); - if (tmp_ctx == NULL) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - - dn = ldb_dn_new(tmp_ctx, ldb, LDB_KV_BASEINFO); - if (dn == NULL) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - - msg = ldb_msg_new(tmp_ctx); - if (msg == NULL) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - - ret = ldb_kv_search_dn1(module, dn, msg, 0); - if (ret != LDB_SUCCESS) { - goto done; - } - - switch (seq->type) { - case LDB_SEQ_HIGHEST_SEQ: - res->seq_num = ldb_msg_find_attr_as_uint64(msg, LDB_KV_SEQUENCE_NUMBER, 0); - break; - case LDB_SEQ_NEXT: - res->seq_num = ldb_msg_find_attr_as_uint64(msg, LDB_KV_SEQUENCE_NUMBER, 0); - res->seq_num++; - break; - case LDB_SEQ_HIGHEST_TIMESTAMP: - date = ldb_msg_find_attr_as_string(msg, LDB_KV_MOD_TIMESTAMP, NULL); - if (date) { - res->seq_num = ldb_string_to_time(date); - } else { - res->seq_num = 0; - /* zero is as good as anything when we don't know */ - } - break; - } - - *ext = talloc_zero(req, struct ldb_extended); - if (*ext == NULL) { - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; - } - (*ext)->oid = LDB_EXTENDED_SEQUENCE_NUMBER; - (*ext)->data = talloc_steal(*ext, res); - -done: - talloc_free(tmp_ctx); - - ldb_kv->kv_ops->unlock_read(module); - return ret; -} - -static void ldb_kv_request_done(struct ldb_kv_context *ctx, int error) -{ - struct ldb_context *ldb; - struct ldb_request *req; - struct ldb_reply *ares; - - ldb = ldb_module_get_ctx(ctx->module); - req = ctx->req; - - /* if we already returned an error just return */ - if (ldb_request_get_status(req) != LDB_SUCCESS) { - return; - } - - ares = talloc_zero(req, struct ldb_reply); - if (!ares) { - ldb_oom(ldb); - req->callback(req, NULL); - return; - } - ares->type = LDB_REPLY_DONE; - ares->error = error; - - req->callback(req, ares); -} - -static void ldb_kv_timeout(_UNUSED_ struct tevent_context *ev, - _UNUSED_ struct tevent_timer *te, - _UNUSED_ struct timeval t, - void *private_data) -{ - struct ldb_kv_context *ctx; - ctx = talloc_get_type(private_data, struct ldb_kv_context); - - if (!ctx->request_terminated) { - /* request is done now */ - ldb_kv_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED); - } - - if (ctx->spy) { - /* neutralize the spy */ - ctx->spy->ctx = NULL; - ctx->spy = NULL; - } - talloc_free(ctx); -} - -static void ldb_kv_request_extended_done(struct ldb_kv_context *ctx, - struct ldb_extended *ext, - int error) -{ - struct ldb_context *ldb; - struct ldb_request *req; - struct ldb_reply *ares; - - ldb = ldb_module_get_ctx(ctx->module); - req = ctx->req; - - /* if we already returned an error just return */ - if (ldb_request_get_status(req) != LDB_SUCCESS) { - return; - } - - ares = talloc_zero(req, struct ldb_reply); - if (!ares) { - ldb_oom(ldb); - req->callback(req, NULL); - return; - } - ares->type = LDB_REPLY_DONE; - ares->response = ext; - ares->error = error; - - req->callback(req, ares); -} - -static void ldb_kv_handle_extended(struct ldb_kv_context *ctx) -{ - struct ldb_extended *ext = NULL; - int ret; - - if (strcmp(ctx->req->op.extended.oid, - LDB_EXTENDED_SEQUENCE_NUMBER) == 0) { - /* get sequence number */ - ret = ldb_kv_sequence_number(ctx, &ext); - } else { - /* not recognized */ - ret = LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; - } - - ldb_kv_request_extended_done(ctx, ext, ret); -} - -static void ldb_kv_callback(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval t, - void *private_data) -{ - struct ldb_kv_context *ctx; - int ret; - - ctx = talloc_get_type(private_data, struct ldb_kv_context); - - if (ctx->request_terminated) { - goto done; - } - - switch (ctx->req->operation) { - case LDB_SEARCH: - ret = ldb_kv_search(ctx); - break; - case LDB_ADD: - ret = ldb_kv_add(ctx); - break; - case LDB_MODIFY: - ret = ldb_kv_modify(ctx); - break; - case LDB_DELETE: - ret = ldb_kv_delete(ctx); - break; - case LDB_RENAME: - ret = ldb_kv_rename(ctx); - break; - case LDB_EXTENDED: - ldb_kv_handle_extended(ctx); - goto done; - default: - /* no other op supported */ - ret = LDB_ERR_PROTOCOL_ERROR; - } - - if (!ctx->request_terminated) { - /* request is done now */ - ldb_kv_request_done(ctx, ret); - } - -done: - if (ctx->spy) { - /* neutralize the spy */ - ctx->spy->ctx = NULL; - ctx->spy = NULL; - } - talloc_free(ctx); -} - -static int ldb_kv_request_destructor(void *ptr) -{ - struct ldb_kv_req_spy *spy = - talloc_get_type(ptr, struct ldb_kv_req_spy); - - if (spy->ctx != NULL) { - spy->ctx->spy = NULL; - spy->ctx->request_terminated = true; - spy->ctx = NULL; - } - - return 0; -} - -static int ldb_kv_handle_request(struct ldb_module *module, - struct ldb_request *req) -{ - struct ldb_control *control_permissive; - struct ldb_context *ldb; - struct tevent_context *ev; - struct ldb_kv_context *ac; - struct tevent_timer *te; - struct timeval tv; - unsigned int i; - - ldb = ldb_module_get_ctx(module); - - control_permissive = ldb_request_get_control(req, - LDB_CONTROL_PERMISSIVE_MODIFY_OID); - - for (i = 0; req->controls && req->controls[i]; i++) { - if (req->controls[i]->critical && - req->controls[i] != control_permissive) { - ldb_asprintf_errstring(ldb, "Unsupported critical extension %s", - req->controls[i]->oid); - return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; - } - } - - if (req->starttime == 0 || req->timeout == 0) { - ldb_set_errstring(ldb, "Invalid timeout settings"); - return LDB_ERR_TIME_LIMIT_EXCEEDED; - } - - ev = ldb_handle_get_event_context(req->handle); - - ac = talloc_zero(ldb, struct ldb_kv_context); - if (ac == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - - tv.tv_sec = 0; - tv.tv_usec = 0; - te = tevent_add_timer(ev, ac, tv, ldb_kv_callback, ac); - if (NULL == te) { - talloc_free(ac); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (req->timeout > 0) { - tv.tv_sec = req->starttime + req->timeout; - tv.tv_usec = 0; - ac->timeout_event = - tevent_add_timer(ev, ac, tv, ldb_kv_timeout, ac); - if (NULL == ac->timeout_event) { - talloc_free(ac); - return LDB_ERR_OPERATIONS_ERROR; - } - } - - /* set a spy so that we do not try to use the request context - * if it is freed before ltdb_callback fires */ - ac->spy = talloc(req, struct ldb_kv_req_spy); - if (NULL == ac->spy) { - talloc_free(ac); - return LDB_ERR_OPERATIONS_ERROR; - } - ac->spy->ctx = ac; - - talloc_set_destructor((TALLOC_CTX *)ac->spy, ldb_kv_request_destructor); - - return LDB_SUCCESS; -} - -static int ldb_kv_init_rootdse(struct ldb_module *module) -{ - /* ignore errors on this - we expect it for non-sam databases */ - ldb_mod_register_control(module, LDB_CONTROL_PERMISSIVE_MODIFY_OID); - - /* there can be no module beyond the backend, just return */ - return LDB_SUCCESS; -} - -static int ldb_kv_lock_read(struct ldb_module *module) -{ - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - return ldb_kv->kv_ops->lock_read(module); -} - -static int ldb_kv_unlock_read(struct ldb_module *module) -{ - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - return ldb_kv->kv_ops->unlock_read(module); -} - -static const struct ldb_module_ops ldb_kv_ops = { - .name = "tdb", - .init_context = ldb_kv_init_rootdse, - .search = ldb_kv_handle_request, - .add = ldb_kv_handle_request, - .modify = ldb_kv_handle_request, - .del = ldb_kv_handle_request, - .rename = ldb_kv_handle_request, - .extended = ldb_kv_handle_request, - .start_transaction = ldb_kv_start_trans, - .end_transaction = ldb_kv_end_trans, - .prepare_commit = ldb_kv_prepare_commit, - .del_transaction = ldb_kv_del_trans, - .read_lock = ldb_kv_lock_read, - .read_unlock = ldb_kv_unlock_read, -}; - -int ldb_kv_init_store(struct ldb_kv_private *ldb_kv, - const char *name, - struct ldb_context *ldb, - const char *options[], - struct ldb_module **_module) -{ - if (getenv("LDB_WARN_UNINDEXED")) { - ldb_kv->warn_unindexed = true; - } - - if (getenv("LDB_WARN_REINDEX")) { - ldb_kv->warn_reindex = true; - } - - ldb_kv->sequence_number = 0; - - ldb_kv->pid = getpid(); - - ldb_kv->pack_format_override = 0; - - ldb_kv->module = ldb_module_new(ldb, ldb, name, &ldb_kv_ops); - if (!ldb_kv->module) { - ldb_oom(ldb); - talloc_free(ldb_kv); - return LDB_ERR_OPERATIONS_ERROR; - } - ldb_module_set_private(ldb_kv->module, ldb_kv); - talloc_steal(ldb_kv->module, ldb_kv); - - if (ldb_kv_cache_load(ldb_kv->module) != 0) { - ldb_asprintf_errstring(ldb, "Unable to load ltdb cache " - "records for backend '%s'", name); - talloc_free(ldb_kv->module); - return LDB_ERR_OPERATIONS_ERROR; - } - - *_module = ldb_kv->module; - /* - * Set or override the maximum key length - * - * The ldb_mdb code will have set this to 511, but our tests - * set this even smaller (to make the tests more practical). - * - * This must only be used for the selftest as the length - * becomes encoded in the index keys. - */ - { - const char *len_str = - ldb_options_find(ldb, options, - "max_key_len_for_self_test"); - if (len_str != NULL) { - unsigned len = strtoul(len_str, NULL, 0); - ldb_kv->max_key_length = len; - } - } - - /* - * Usually the presence of GUID indexing determines the pack format - * we use but in certain circumstances such as downgrading an - * MDB-backed database, we want to override the target pack format. - * - * We set/get opaques here because in the Samba partitions module, - * 'options' are not passed correctly so sub-databases can't see - * the options they need. - */ - { - const char *pack_format_override = - ldb_options_find(ldb, options, "pack_format_override"); - if (pack_format_override != NULL) { - int ret; - ldb_kv->pack_format_override = - strtoul(pack_format_override, NULL, 0); - ret = ldb_set_opaque(ldb, - "pack_format_override", - (void *)(intptr_t)ldb_kv->pack_format_override); - if (ret != LDB_SUCCESS) { - talloc_free(ldb_kv->module); - return ldb_module_operr(ldb_kv->module); - } - } else { - /* - * NULL -> 0 is fine, otherwise we get back - * the number we needed - */ - ldb_kv->pack_format_override - = (intptr_t)ldb_get_opaque(ldb, - "pack_format_override"); - } - } - - /* - * Override full DB scans - * - * A full DB scan is expensive on a large database. This - * option is for testing to show that the full DB scan is not - * triggered. - */ - { - const char *len_str = - ldb_options_find(ldb, options, - "disable_full_db_scan_for_self_test"); - if (len_str != NULL) { - ldb_kv->disable_full_db_scan = true; - } - } - - /* - * Set the size of the transaction index cache. - * If the ldb option "transaction_index_cache_size" is set use that - * otherwise use DEFAULT_INDEX_CACHE_SIZE - */ - ldb_kv->index_transaction_cache_size = DEFAULT_INDEX_CACHE_SIZE; - { - const char *size = ldb_options_find( - ldb, - options, - "transaction_index_cache_size"); - if (size != NULL) { - size_t cache_size = 0; - errno = 0; - - cache_size = strtoul( size, NULL, 0); - if (cache_size == 0 || errno == ERANGE) { - ldb_debug( - ldb, - LDB_DEBUG_WARNING, - "Invalid transaction_index_cache_size " - "value [%s], using default(%d)\n", - size, - DEFAULT_INDEX_CACHE_SIZE); - } else { - ldb_kv->index_transaction_cache_size = - cache_size; - } - } - } - /* - * Set batch mode operation. - * This disables the nested sub transactions, and increases the - * chance of index corruption. If using this mode the transaction - * commit will be aborted if any operation fails. - */ - { - const char *batch_mode = ldb_options_find( - ldb, options, "batch_mode"); - if (batch_mode != NULL) { - ldb_kv->batch_mode = true; - } - } - - return LDB_SUCCESS; -} diff --git a/ldb-2.0.8/ldb_key_value/ldb_kv.h b/ldb-2.0.8/ldb_key_value/ldb_kv.h deleted file mode 100644 index f9dffae..0000000 --- a/ldb-2.0.8/ldb_key_value/ldb_kv.h +++ /dev/null @@ -1,336 +0,0 @@ -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "tdb.h" -#include "ldb_module.h" - -#ifndef __LDB_KV_H__ -#define __LDB_KV_H__ -struct ldb_kv_private; -typedef int (*ldb_kv_traverse_fn)(struct ldb_kv_private *ldb_kv, - struct ldb_val key, - struct ldb_val data, - void *ctx); - -struct kv_db_ops { - uint32_t options; - - int (*store)(struct ldb_kv_private *ldb_kv, - struct ldb_val key, - struct ldb_val data, - int flags); - int (*delete)(struct ldb_kv_private *ldb_kv, struct ldb_val key); - int (*iterate)(struct ldb_kv_private *ldb_kv, - ldb_kv_traverse_fn fn, - void *ctx); - int (*update_in_iterate)(struct ldb_kv_private *ldb_kv, - struct ldb_val key, - struct ldb_val key2, - struct ldb_val data, - void *ctx); - int (*fetch_and_parse)(struct ldb_kv_private *ldb_kv, - struct ldb_val key, - int (*parser)(struct ldb_val key, - struct ldb_val data, - void *private_data), - void *ctx); - int (*iterate_range)(struct ldb_kv_private *ldb_kv, - struct ldb_val start_key, - struct ldb_val end_key, - ldb_kv_traverse_fn fn, - void *ctx); - int (*lock_read)(struct ldb_module *); - int (*unlock_read)(struct ldb_module *); - int (*begin_write)(struct ldb_kv_private *); - int (*prepare_write)(struct ldb_kv_private *); - int (*abort_write)(struct ldb_kv_private *); - int (*finish_write)(struct ldb_kv_private *); - int (*error)(struct ldb_kv_private *ldb_kv); - const char *(*errorstr)(struct ldb_kv_private *ldb_kv); - const char *(*name)(struct ldb_kv_private *ldb_kv); - bool (*has_changed)(struct ldb_kv_private *ldb_kv); - bool (*transaction_active)(struct ldb_kv_private *ldb_kv); - size_t (*get_size)(struct ldb_kv_private *ldb_kv); - int (*begin_nested_write)(struct ldb_kv_private *); - int (*finish_nested_write)(struct ldb_kv_private *); - int (*abort_nested_write)(struct ldb_kv_private *); -}; - -/* this private structure is used by the key value backends in the - ldb_context */ -struct ldb_kv_private { - const struct kv_db_ops *kv_ops; - struct ldb_module *module; - TDB_CONTEXT *tdb; - struct lmdb_private *lmdb_private; - unsigned int connect_flags; - - unsigned long long sequence_number; - uint32_t pack_format_version; - uint32_t target_pack_format_version; - uint32_t pack_format_override; - - /* the low level tdb seqnum - used to avoid loading BASEINFO when - possible */ - int tdb_seqnum; - - struct ldb_kv_cache { - struct ldb_message *indexlist; - bool one_level_indexes; - bool attribute_indexes; - const char *GUID_index_attribute; - const char *GUID_index_dn_component; - } *cache; - - - bool check_base; - bool disallow_dn_filter; - /* - * To improve the performance of batch operations we maintain a cache - * of index records, these entries get written to disk in the - * prepare_commit phase. - */ - struct ldb_kv_idxptr *idxptr; - /* - * To ensure that the indexes in idxptr are consistent we cache any - * index updates during an operation, i.e. ldb_kv_add, ldb_kv_delete ... - * Once the changes to the data record have been commited to disk - * the contents of this cache are copied to idxptr - */ - struct ldb_kv_idxptr *nested_idx_ptr; - /* - * If batch mode is set the sub transactions and index caching - * wrapping individual operations is disabled. - * This is to improve the performance of large batch operations - * i.e. domain joins. - */ - bool batch_mode; - /* - * Has an operation failed, if true and we're in batch_mode - * the transaction commit will fail. - */ - bool operation_failed; - - bool prepared_commit; - int read_lock_count; - - bool warn_unindexed; - bool warn_reindex; - - bool read_only; - - bool reindex_failed; - - const struct ldb_schema_syntax *GUID_index_syntax; - - /* - * Maximum index key length. If non zero keys longer than this length - * will be truncated for non unique indexes. Keys for unique indexes - * greater than this length will be rejected. - */ - unsigned max_key_length; - - /* - * To allow testing that ensures the DB does not fall back - * to a full scan - */ - bool disable_full_db_scan; - - /* - * The PID that opened this database so we don't work in a - * fork()ed child. - */ - pid_t pid; - - /* - * The size to be used for the index transaction cache - */ - size_t index_transaction_cache_size; -}; - -struct ldb_kv_context { - struct ldb_module *module; - struct ldb_request *req; - - bool request_terminated; - struct ldb_kv_req_spy *spy; - - /* search stuff */ - const struct ldb_parse_tree *tree; - struct ldb_dn *base; - enum ldb_scope scope; - const char * const *attrs; - struct tevent_timer *timeout_event; - - /* error handling */ - int error; -}; - -struct ldb_kv_reindex_context { - int error; - uint32_t count; -}; - -struct ldb_kv_repack_context { - int error; - uint32_t count; - bool normal_record_seen; - uint32_t old_version; -}; - - -/* special record types */ -#define LDB_KV_INDEX "@INDEX" -#define LDB_KV_INDEXLIST "@INDEXLIST" -#define LDB_KV_IDX "@IDX" -#define LDB_KV_IDXVERSION "@IDXVERSION" -#define LDB_KV_IDXATTR "@IDXATTR" -#define LDB_KV_IDXONE "@IDXONE" -#define LDB_KV_IDXDN "@IDXDN" -#define LDB_KV_IDXGUID "@IDXGUID" -#define LDB_KV_IDX_DN_GUID "@IDX_DN_GUID" - -/* - * This will be used to indicate when a new, yet to be developed - * sub-database version of the indicies are in use, to ensure we do - * not load future databases unintentionally. - */ - -#define LDB_KV_IDX_LMDB_SUBDB "@IDX_LMDB_SUBDB" - -#define LDB_KV_BASEINFO "@BASEINFO" -#define LDB_KV_OPTIONS "@OPTIONS" -#define LDB_KV_ATTRIBUTES "@ATTRIBUTES" - -/* special attribute types */ -#define LDB_KV_SEQUENCE_NUMBER "sequenceNumber" -#define LDB_KV_CHECK_BASE "checkBaseOnSearch" -#define LDB_KV_DISALLOW_DN_FILTER "disallowDNFilter" -#define LDB_KV_MOD_TIMESTAMP "whenChanged" -#define LDB_KV_OBJECTCLASS "objectClass" - -/* DB keys */ -#define LDB_KV_GUID_KEY_PREFIX "GUID=" -#define LDB_KV_GUID_SIZE 16 -#define LDB_KV_GUID_KEY_SIZE (LDB_KV_GUID_SIZE + sizeof(LDB_KV_GUID_KEY_PREFIX) - 1) - -/* LDB KV options */ -/* - * This allows pointers to be referenced after the callback to any variant of - * iterate or fetch_and_parse -- as long as an overall read lock is held. - */ -#define LDB_KV_OPTION_STABLE_READ_LOCK 0x00000001 - -/* - * The following definitions come from lib/ldb/ldb_key_value/ldb_kv_cache.c - */ - -int ldb_kv_cache_reload(struct ldb_module *module); -int ldb_kv_cache_load(struct ldb_module *module); -int ldb_kv_increase_sequence_number(struct ldb_module *module); -int ldb_kv_check_at_attributes_values(const struct ldb_val *value); - -/* - * The following definitions come from lib/ldb/ldb_key_value/ldb_kv_index.c - */ - -/* - * The default size of the in memory TDB used to cache index records - * The value chosen gives a prime modulo for the hash table and keeps the - * tdb memory overhead under 4 kB - */ -#define DEFAULT_INDEX_CACHE_SIZE 491 - -struct ldb_parse_tree; - -int ldb_kv_search_indexed(struct ldb_kv_context *ctx, uint32_t *); -int ldb_kv_index_add_new(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_message *msg); -int ldb_kv_index_delete(struct ldb_module *module, - const struct ldb_message *msg); -int ldb_kv_index_del_element(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_message *msg, - struct ldb_message_element *el); -int ldb_kv_index_add_element(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_message *msg, - struct ldb_message_element *el); -int ldb_kv_index_del_value(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_message *msg, - struct ldb_message_element *el, - unsigned int v_idx); -int ldb_kv_reindex(struct ldb_module *module); -int ldb_kv_repack(struct ldb_module *module); -int ldb_kv_index_transaction_start( - struct ldb_module *module, - size_t cache_size); -int ldb_kv_index_transaction_commit(struct ldb_module *module); -int ldb_kv_index_transaction_cancel(struct ldb_module *module); -int ldb_kv_key_dn_from_idx(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - TALLOC_CTX *mem_ctx, - struct ldb_dn *dn, - struct ldb_val *key); - -/* - * The following definitions come from lib/ldb/ldb_key_value/ldb_kv_search.c - */ -int ldb_kv_search_dn1(struct ldb_module *module, - struct ldb_dn *dn, - struct ldb_message *msg, - unsigned int unpack_flags); -int ldb_kv_search_base(struct ldb_module *module, - TALLOC_CTX *mem_ctx, - struct ldb_dn *dn, - struct ldb_dn **ret_dn); -int ldb_kv_search_key(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_val ldb_key, - struct ldb_message *msg, - unsigned int unpack_flags); -int ldb_kv_filter_attrs(struct ldb_context *ldb, - const struct ldb_message *msg, - const char *const *attrs, - struct ldb_message *filtered_msg); -int ldb_kv_search(struct ldb_kv_context *ctx); - -/* - * The following definitions come from lib/ldb/ldb_key_value/ldb_kv.c */ -/* - * Determine if this key could hold a normal record. We allow the new - * GUID index, the old DN index and a possible future ID= but not - * DN=@. - */ -bool ldb_kv_key_is_normal_record(struct ldb_val key); -struct ldb_val ldb_kv_key_dn(TALLOC_CTX *mem_ctx, - struct ldb_dn *dn); -struct ldb_val ldb_kv_key_msg(struct ldb_module *module, - TALLOC_CTX *mem_ctx, - const struct ldb_message *msg); -int ldb_kv_guid_to_key(const struct ldb_val *GUID_val, - struct ldb_val *key); -int ldb_kv_idx_to_key(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - TALLOC_CTX *mem_ctx, - const struct ldb_val *idx_val, - struct ldb_val *key); -int ldb_kv_store(struct ldb_module *module, - const struct ldb_message *msg, - int flgs); -int ldb_kv_modify_internal(struct ldb_module *module, - const struct ldb_message *msg, - struct ldb_request *req); -int ldb_kv_delete_noindex(struct ldb_module *module, - const struct ldb_message *msg); -int ldb_kv_init_store(struct ldb_kv_private *ldb_kv, - const char *name, - struct ldb_context *ldb, - const char *options[], - struct ldb_module **_module); -int ldb_kv_index_sub_transaction_start(struct ldb_kv_private *ldb_kv); -int ldb_kv_index_sub_transaction_cancel(struct ldb_kv_private *ldb_kv); -int ldb_kv_index_sub_transaction_commit(struct ldb_kv_private *ldb_kv); -#endif /* __LDB_KV_H__ */ diff --git a/ldb-2.0.8/ldb_key_value/ldb_kv_cache.c b/ldb-2.0.8/ldb_key_value/ldb_kv_cache.c deleted file mode 100644 index 4a3c9f2..0000000 --- a/ldb-2.0.8/ldb_key_value/ldb_kv_cache.c +++ /dev/null @@ -1,697 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb key value cache functions - * - * Description: cache special records in a ldb/tdb - * - * Author: Andrew Tridgell - */ - -#include "ldb_kv.h" -#include "ldb_private.h" - -#define LDB_KV_FLAG_CASE_INSENSITIVE (1<<0) -#define LDB_KV_FLAG_INTEGER (1<<1) -#define LDB_KV_FLAG_UNIQUE_INDEX (1<<2) -#define LDB_KV_FLAG_ORDERED_INTEGER (1<<3) - -/* valid attribute flags */ -static const struct { - const char *name; - int value; -} ldb_kv_valid_attr_flags[] = { - { "CASE_INSENSITIVE", LDB_KV_FLAG_CASE_INSENSITIVE }, - { "INTEGER", LDB_KV_FLAG_INTEGER }, - { "ORDERED_INTEGER", LDB_KV_FLAG_ORDERED_INTEGER }, - { "HIDDEN", 0 }, - { "UNIQUE_INDEX", LDB_KV_FLAG_UNIQUE_INDEX}, - { "NONE", 0 }, - { NULL, 0 } -}; - -/* - de-register any special handlers for @ATTRIBUTES -*/ -static void ldb_kv_attributes_unload(struct ldb_module *module) -{ - struct ldb_context *ldb = ldb_module_get_ctx(module); - - ldb_schema_attribute_remove_flagged(ldb, LDB_ATTR_FLAG_FROM_DB); - -} - -/* - add up the attrib flags for a @ATTRIBUTES element -*/ -static int ldb_kv_attributes_flags(struct ldb_message_element *el, unsigned *v) -{ - unsigned int i; - unsigned value = 0; - for (i=0;inum_values;i++) { - unsigned int j; - for (j = 0; ldb_kv_valid_attr_flags[j].name; j++) { - if (strcmp(ldb_kv_valid_attr_flags[j].name, - (char *)el->values[i].data) == 0) { - value |= ldb_kv_valid_attr_flags[j].value; - break; - } - } - if (ldb_kv_valid_attr_flags[j].name == NULL) { - return -1; - } - } - *v = value; - return 0; -} - -static int ldb_schema_attribute_compare(const void *p1, const void *p2) -{ - const struct ldb_schema_attribute *sa1 = (const struct ldb_schema_attribute *)p1; - const struct ldb_schema_attribute *sa2 = (const struct ldb_schema_attribute *)p2; - return ldb_attr_cmp(sa1->name, sa2->name); -} - -/* - register any special handlers from @ATTRIBUTES -*/ -static int ldb_kv_attributes_load(struct ldb_module *module) -{ - struct ldb_schema_attribute *attrs; - struct ldb_context *ldb; - struct ldb_message *attrs_msg = NULL; - struct ldb_dn *dn; - unsigned int i; - unsigned int num_loaded_attrs = 0; - int r; - - ldb = ldb_module_get_ctx(module); - - if (ldb->schema.attribute_handler_override) { - /* we skip loading the @ATTRIBUTES record when a module is supplying - its own attribute handling */ - return 0; - } - - attrs_msg = ldb_msg_new(module); - if (attrs_msg == NULL) { - goto failed; - } - - dn = ldb_dn_new(module, ldb, LDB_KV_ATTRIBUTES); - if (dn == NULL) goto failed; - - r = ldb_kv_search_dn1(module, - dn, - attrs_msg, - LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC | - LDB_UNPACK_DATA_FLAG_NO_DN); - talloc_free(dn); - if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) { - goto failed; - } - if (r == LDB_ERR_NO_SUCH_OBJECT || attrs_msg->num_elements == 0) { - TALLOC_FREE(attrs_msg); - return 0; - } - - attrs = talloc_array(attrs_msg, - struct ldb_schema_attribute, - attrs_msg->num_elements - + ldb->schema.num_attributes); - if (attrs == NULL) { - goto failed; - } - - memcpy(attrs, - ldb->schema.attributes, - sizeof(ldb->schema.attributes[0]) * ldb->schema.num_attributes); - - /* mapping these flags onto ldap 'syntaxes' isn't strictly correct, - but its close enough for now */ - for (i=0;inum_elements;i++) { - unsigned flags = 0, attr_flags = 0; - const char *syntax; - const struct ldb_schema_syntax *s; - const struct ldb_schema_attribute *a = - ldb_schema_attribute_by_name(ldb, - attrs_msg->elements[i].name); - if (a != NULL && a->flags & LDB_ATTR_FLAG_FIXED) { - /* Must already be set in the array, and kept */ - continue; - } - - if (ldb_kv_attributes_flags(&attrs_msg->elements[i], &flags) != - 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Invalid @ATTRIBUTES element for '%s'", - attrs_msg->elements[i].name); - goto failed; - } - - if (flags & LDB_KV_FLAG_UNIQUE_INDEX) { - attr_flags = LDB_ATTR_FLAG_UNIQUE_INDEX; - } - flags &= ~LDB_KV_FLAG_UNIQUE_INDEX; - - /* These are not currently flags, each is exclusive */ - if (flags == LDB_KV_FLAG_CASE_INSENSITIVE) { - syntax = LDB_SYNTAX_DIRECTORY_STRING; - } else if (flags == LDB_KV_FLAG_INTEGER) { - syntax = LDB_SYNTAX_INTEGER; - } else if (flags == LDB_KV_FLAG_ORDERED_INTEGER) { - syntax = LDB_SYNTAX_ORDERED_INTEGER; - } else if (flags == 0) { - syntax = LDB_SYNTAX_OCTET_STRING; - } else { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Invalid flag combination 0x%x for '%s' " - "in @ATTRIBUTES", - flags, attrs_msg->elements[i].name); - goto failed; - } - - s = ldb_standard_syntax_by_name(ldb, syntax); - if (s == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Invalid attribute syntax '%s' for '%s' " - "in @ATTRIBUTES", - syntax, attrs_msg->elements[i].name); - goto failed; - } - - attr_flags |= LDB_ATTR_FLAG_ALLOCATED | LDB_ATTR_FLAG_FROM_DB; - - r = ldb_schema_attribute_fill_with_syntax(ldb, - attrs, - attrs_msg->elements[i].name, - attr_flags, s, - &attrs[num_loaded_attrs + ldb->schema.num_attributes]); - if (r != 0) { - goto failed; - } - num_loaded_attrs++; - } - - attrs = talloc_realloc(attrs_msg, - attrs, struct ldb_schema_attribute, - num_loaded_attrs + ldb->schema.num_attributes); - if (attrs == NULL) { - goto failed; - } - TYPESAFE_QSORT(attrs, num_loaded_attrs + ldb->schema.num_attributes, - ldb_schema_attribute_compare); - talloc_unlink(ldb, ldb->schema.attributes); - ldb->schema.attributes = talloc_steal(ldb, attrs); - ldb->schema.num_attributes = num_loaded_attrs + ldb->schema.num_attributes; - TALLOC_FREE(attrs_msg); - - return 0; -failed: - TALLOC_FREE(attrs_msg); - return -1; -} - -/* - register any index records we find for the DB -*/ -static int ldb_kv_index_load(struct ldb_module *module, - struct ldb_kv_private *ldb_kv) -{ - struct ldb_context *ldb = ldb_module_get_ctx(module); - struct ldb_dn *indexlist_dn; - int r, lmdb_subdb_version; - - if (ldb->schema.index_handler_override) { - /* - * we skip loading the @INDEXLIST record when a module is - * supplying its own attribute handling - */ - ldb_kv->cache->attribute_indexes = true; - ldb_kv->cache->one_level_indexes = - ldb->schema.one_level_indexes; - ldb_kv->cache->GUID_index_attribute = - ldb->schema.GUID_index_attribute; - ldb_kv->cache->GUID_index_dn_component = - ldb->schema.GUID_index_dn_component; - return 0; - } - - talloc_free(ldb_kv->cache->indexlist); - - ldb_kv->cache->indexlist = ldb_msg_new(ldb_kv->cache); - if (ldb_kv->cache->indexlist == NULL) { - return -1; - } - ldb_kv->cache->one_level_indexes = false; - ldb_kv->cache->attribute_indexes = false; - - indexlist_dn = ldb_dn_new(ldb_kv, ldb, LDB_KV_INDEXLIST); - if (indexlist_dn == NULL) { - return -1; - } - - r = ldb_kv_search_dn1(module, - indexlist_dn, - ldb_kv->cache->indexlist, - LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC | - LDB_UNPACK_DATA_FLAG_NO_DN); - TALLOC_FREE(indexlist_dn); - - if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) { - return -1; - } - - if (ldb_msg_find_element(ldb_kv->cache->indexlist, LDB_KV_IDXONE) != - NULL) { - ldb_kv->cache->one_level_indexes = true; - } - if (ldb_msg_find_element(ldb_kv->cache->indexlist, LDB_KV_IDXATTR) != - NULL) { - ldb_kv->cache->attribute_indexes = true; - } - ldb_kv->cache->GUID_index_attribute = ldb_msg_find_attr_as_string( - ldb_kv->cache->indexlist, LDB_KV_IDXGUID, NULL); - ldb_kv->cache->GUID_index_dn_component = ldb_msg_find_attr_as_string( - ldb_kv->cache->indexlist, LDB_KV_IDX_DN_GUID, NULL); - - lmdb_subdb_version = ldb_msg_find_attr_as_int( - ldb_kv->cache->indexlist, LDB_KV_IDX_LMDB_SUBDB, 0); - - if (lmdb_subdb_version != 0) { - ldb_set_errstring(ldb, - "FATAL: This ldb_mdb database has " - "been written in a new version of LDB " - "using a sub-database index that " - "is not understood by ldb " - LDB_VERSION); - return -1; - } - - return 0; -} - -/* - initialise the baseinfo record -*/ -static int ldb_kv_baseinfo_init(struct ldb_module *module) -{ - struct ldb_context *ldb; - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - struct ldb_message *msg; - struct ldb_message_element el; - struct ldb_val val; - int ret; - /* the initial sequence number must be different from the one - set in ltdb_cache_free(). Thanks to Jon for pointing this - out. */ - const char *initial_sequence_number = "1"; - - ldb = ldb_module_get_ctx(module); - - ldb_kv->sequence_number = atof(initial_sequence_number); - - msg = ldb_msg_new(ldb_kv); - if (msg == NULL) { - goto failed; - } - - msg->num_elements = 1; - msg->elements = ⪙ - msg->dn = ldb_dn_new(msg, ldb, LDB_KV_BASEINFO); - if (!msg->dn) { - goto failed; - } - el.name = talloc_strdup(msg, LDB_KV_SEQUENCE_NUMBER); - if (!el.name) { - goto failed; - } - el.values = &val; - el.num_values = 1; - el.flags = 0; - val.data = (uint8_t *)talloc_strdup(msg, initial_sequence_number); - if (!val.data) { - goto failed; - } - val.length = 1; - - ret = ldb_kv_store(module, msg, TDB_INSERT); - - talloc_free(msg); - - return ret; - -failed: - talloc_free(msg); - errno = ENOMEM; - return LDB_ERR_OPERATIONS_ERROR; -} - -/* - free any cache records - */ -static void ldb_kv_cache_free(struct ldb_module *module) -{ - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - - ldb_kv->sequence_number = 0; - talloc_free(ldb_kv->cache); - ldb_kv->cache = NULL; -} - -/* - force a cache reload -*/ -int ldb_kv_cache_reload(struct ldb_module *module) -{ - ldb_kv_attributes_unload(module); - ldb_kv_cache_free(module); - return ldb_kv_cache_load(module); -} -static int get_pack_format_version(struct ldb_val key, - struct ldb_val data, - void *private_data) -{ - uint32_t *v = (uint32_t *) private_data; - return ldb_unpack_get_format(&data, v); -} - -/* - load the cache records -*/ -int ldb_kv_cache_load(struct ldb_module *module) -{ - struct ldb_context *ldb; - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - struct ldb_dn *baseinfo_dn = NULL, *options_dn = NULL; - uint64_t seq; - struct ldb_message *baseinfo = NULL, *options = NULL; - const struct ldb_schema_attribute *a; - bool have_write_txn = false; - int r; - struct ldb_val key; - - ldb = ldb_module_get_ctx(module); - - /* a very fast check to avoid extra database reads */ - if (ldb_kv->cache != NULL && !ldb_kv->kv_ops->has_changed(ldb_kv)) { - return 0; - } - - if (ldb_kv->cache == NULL) { - ldb_kv->cache = talloc_zero(ldb_kv, struct ldb_kv_cache); - if (ldb_kv->cache == NULL) - goto failed; - } - - baseinfo = ldb_msg_new(ldb_kv->cache); - if (baseinfo == NULL) goto failed; - - baseinfo_dn = ldb_dn_new(baseinfo, ldb, LDB_KV_BASEINFO); - if (baseinfo_dn == NULL) goto failed; - - r = ldb_kv->kv_ops->lock_read(module); - if (r != LDB_SUCCESS) { - goto failed; - } - - key = ldb_kv_key_dn(baseinfo, baseinfo_dn); - if (!key.data) { - goto failed_and_unlock; - } - - /* Read packing format from first 4 bytes of @BASEINFO record */ - r = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, - get_pack_format_version, - &ldb_kv->pack_format_version); - - /* possibly initialise the baseinfo */ - if (r == LDB_ERR_NO_SUCH_OBJECT) { - - /* Give up the read lock, try again with a write lock */ - r = ldb_kv->kv_ops->unlock_read(module); - if (r != LDB_SUCCESS) { - goto failed; - } - - if (ldb_kv->kv_ops->begin_write(ldb_kv) != 0) { - goto failed; - } - - have_write_txn = true; - - /* - * We need to write but haven't figured out packing format yet. - * Just go with version 1 and we'll repack if we got it wrong. - */ - ldb_kv->pack_format_version = LDB_PACKING_FORMAT; - ldb_kv->target_pack_format_version = LDB_PACKING_FORMAT; - - /* error handling for ltdb_baseinfo_init() is by - looking for the record again. */ - ldb_kv_baseinfo_init(module); - - } else if (r != LDB_SUCCESS) { - goto failed_and_unlock; - } - - /* OK now we definitely have a @BASEINFO record so fetch it */ - r = ldb_kv_search_dn1(module, baseinfo_dn, baseinfo, 0); - if (r != LDB_SUCCESS) { - goto failed_and_unlock; - } - - /* Ignore the result, and update the sequence number */ - ldb_kv->kv_ops->has_changed(ldb_kv); - - /* if the current internal sequence number is the same as the one - in the database then assume the rest of the cache is OK */ - seq = ldb_msg_find_attr_as_uint64(baseinfo, LDB_KV_SEQUENCE_NUMBER, 0); - if (seq == ldb_kv->sequence_number) { - goto done; - } - ldb_kv->sequence_number = seq; - - /* Read an interpret database options */ - - options = ldb_msg_new(ldb_kv->cache); - if (options == NULL) goto failed_and_unlock; - - options_dn = ldb_dn_new(options, ldb, LDB_KV_OPTIONS); - if (options_dn == NULL) goto failed_and_unlock; - - r = ldb_kv_search_dn1(module, options_dn, options, 0); - talloc_free(options_dn); - if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) { - goto failed_and_unlock; - } - - /* set flags if they do exist */ - if (r == LDB_SUCCESS) { - ldb_kv->check_base = - ldb_msg_find_attr_as_bool(options, LDB_KV_CHECK_BASE, false); - ldb_kv->disallow_dn_filter = ldb_msg_find_attr_as_bool( - options, LDB_KV_DISALLOW_DN_FILTER, false); - } else { - ldb_kv->check_base = false; - ldb_kv->disallow_dn_filter = false; - } - - /* - * ltdb_attributes_unload() calls internally talloc_free() on - * any non-fixed elemnts in ldb->schema.attributes. - * - * NOTE WELL: This is per-ldb, not per module, so overwrites - * the handlers across all databases when used under Samba's - * partition module. - */ - ldb_kv_attributes_unload(module); - - if (ldb_kv_index_load(module, ldb_kv) == -1) { - goto failed_and_unlock; - } - - /* - * NOTE WELL: This is per-ldb, not per module, so overwrites - * the handlers across all databases when used under Samba's - * partition module. - */ - if (ldb_kv_attributes_load(module) == -1) { - goto failed_and_unlock; - } - - /* - * Initialise packing version and GUID index syntax, and force the - * two to travel together, ie a GUID indexed database must use V2 - * packing format and a DN indexed database must use V1. - */ - ldb_kv->GUID_index_syntax = NULL; - if (ldb_kv->cache->GUID_index_attribute != NULL) { - ldb_kv->target_pack_format_version = LDB_PACKING_FORMAT_V2; - - /* - * Now the attributes are loaded, set the guid_index_syntax. - * This can't fail, it will return a default at worst - */ - a = ldb_schema_attribute_by_name( - ldb, ldb_kv->cache->GUID_index_attribute); - ldb_kv->GUID_index_syntax = a->syntax; - } else { - ldb_kv->target_pack_format_version = LDB_PACKING_FORMAT; - } - -done: - if (have_write_txn) { - if (ldb_kv->kv_ops->finish_write(ldb_kv) != 0) { - goto failed; - } - } else { - ldb_kv->kv_ops->unlock_read(module); - } - - talloc_free(options); - talloc_free(baseinfo); - return 0; - -failed_and_unlock: - if (have_write_txn) { - ldb_kv->kv_ops->abort_write(ldb_kv); - } else { - ldb_kv->kv_ops->unlock_read(module); - } - -failed: - talloc_free(options); - talloc_free(baseinfo); - return -1; -} - - -/* - increase the sequence number to indicate a database change -*/ -int ldb_kv_increase_sequence_number(struct ldb_module *module) -{ - struct ldb_context *ldb; - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - struct ldb_message *msg; - struct ldb_message_element el[2]; - struct ldb_val val; - struct ldb_val val_time; - time_t t = time(NULL); - char *s = NULL; - int ret; - - ldb = ldb_module_get_ctx(module); - - msg = ldb_msg_new(ldb_kv); - if (msg == NULL) { - errno = ENOMEM; - return LDB_ERR_OPERATIONS_ERROR; - } - - s = talloc_asprintf(msg, "%llu", ldb_kv->sequence_number + 1); - if (!s) { - talloc_free(msg); - errno = ENOMEM; - return LDB_ERR_OPERATIONS_ERROR; - } - - msg->num_elements = ARRAY_SIZE(el); - msg->elements = el; - msg->dn = ldb_dn_new(msg, ldb, LDB_KV_BASEINFO); - if (msg->dn == NULL) { - talloc_free(msg); - errno = ENOMEM; - return LDB_ERR_OPERATIONS_ERROR; - } - el[0].name = talloc_strdup(msg, LDB_KV_SEQUENCE_NUMBER); - if (el[0].name == NULL) { - talloc_free(msg); - errno = ENOMEM; - return LDB_ERR_OPERATIONS_ERROR; - } - el[0].values = &val; - el[0].num_values = 1; - el[0].flags = LDB_FLAG_MOD_REPLACE; - val.data = (uint8_t *)s; - val.length = strlen(s); - - el[1].name = talloc_strdup(msg, LDB_KV_MOD_TIMESTAMP); - if (el[1].name == NULL) { - talloc_free(msg); - errno = ENOMEM; - return LDB_ERR_OPERATIONS_ERROR; - } - el[1].values = &val_time; - el[1].num_values = 1; - el[1].flags = LDB_FLAG_MOD_REPLACE; - - s = ldb_timestring(msg, t); - if (s == NULL) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - val_time.data = (uint8_t *)s; - val_time.length = strlen(s); - - ret = ldb_kv_modify_internal(module, msg, NULL); - - talloc_free(msg); - - if (ret == LDB_SUCCESS) { - ldb_kv->sequence_number += 1; - } - - /* updating the tdb_seqnum here avoids us reloading the cache - records due to our own modification */ - ldb_kv->kv_ops->has_changed(ldb_kv); - - return ret; -} - -int ldb_kv_check_at_attributes_values(const struct ldb_val *value) -{ - unsigned int i; - - for (i = 0; ldb_kv_valid_attr_flags[i].name != NULL; i++) { - if ((strcmp(ldb_kv_valid_attr_flags[i].name, - (char *)value->data) == 0)) { - return 0; - } - } - - return -1; -} diff --git a/ldb-2.0.8/ldb_key_value/ldb_kv_index.c b/ldb-2.0.8/ldb_key_value/ldb_kv_index.c deleted file mode 100644 index 0853b28..0000000 --- a/ldb-2.0.8/ldb_key_value/ldb_kv_index.c +++ /dev/null @@ -1,3917 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004-2009 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb key value backend - indexing - * - * Description: indexing routines for ldb key value backend - * - * Author: Andrew Tridgell - */ - -/* - -LDB Index design and choice of key: -======================================= - -LDB has index records held as LDB objects with a special record like: - -dn: @INDEX:attr:value - -value may be base64 encoded, if it is deemed not printable: - -dn: @INDEX:attr::base64-value - -In each record, there is two possible formats: - -The original format is: ------------------------ - -dn: @INDEX:NAME:DNSUPDATEPROXY -@IDXVERSION: 2 -@IDX: CN=DnsUpdateProxy,CN=Users,DC=addom,DC=samba,DC=example,DC=com - -In this format, @IDX is multi-valued, one entry for each match - -The corrosponding entry is stored in a TDB record with key: - -DN=CN=DNSUPDATEPROXY,CN=USERS,DC=ADDOM,DC=SAMBA,DC=EXAMPLE,DC=COM - -(This allows a scope BASE search to directly find the record via -a simple casefold of the DN). - -The original mixed-case DN is stored in the entry iself. - - -The new 'GUID index' format is: -------------------------------- - -dn: @INDEX:NAME:DNSUPDATEPROXY -@IDXVERSION: 3 -@IDX: [[...]] - -The binary guid is 16 bytes, as bytes and not expanded as hexidecimal -or pretty-printed. The GUID is chosen from the message to be stored -by the @IDXGUID attribute on @INDEXLIST. - -If there are multiple values the @IDX value simply becomes longer, -in multiples of 16. - -The corrosponding entry is stored in a TDB record with key: - -GUID= - -This allows a very quick translation between the fixed-length index -values and the TDB key, while seperating entries from other data -in the TDB, should they be unlucky enough to start with the bytes of -the 'DN=' prefix. - -Additionally, this allows a scope BASE search to directly find the -record via a simple match on a GUID= extended DN, controlled via -@IDX_DN_GUID on @INDEXLIST - -Exception for special @ DNs: - -@BASEINFO, @INDEXLIST and all other special DNs are stored as per the -original format, as they are never referenced in an index and are used -to bootstrap the database. - - -Control points for choice of index mode ---------------------------------------- - -The choice of index and TDB key mode is made based (for example, from -Samba) on entries in the @INDEXLIST DN: - -dn: @INDEXLIST -@IDXGUID: objectGUID -@IDX_DN_GUID: GUID - -By default, the original DN format is used. - - -Control points for choosing indexed attributes ----------------------------------------------- - -@IDXATTR controls if an attribute is indexed - -dn: @INDEXLIST -@IDXATTR: samAccountName -@IDXATTR: nETBIOSName - - -C Override functions --------------------- - -void ldb_schema_set_override_GUID_index(struct ldb_context *ldb, - const char *GUID_index_attribute, - const char *GUID_index_dn_component) - -This is used, particularly in combination with the below, instead of -the @IDXGUID and @IDX_DN_GUID values in @INDEXLIST. - -void ldb_schema_set_override_indexlist(struct ldb_context *ldb, - bool one_level_indexes); -void ldb_schema_attribute_set_override_handler(struct ldb_context *ldb, - ldb_attribute_handler_override_fn_t override, - void *private_data); - -When the above two functions are called in combination, the @INDEXLIST -values are not read from the DB, so -ldb_schema_set_override_GUID_index() must be called. - -*/ - -#include "ldb_kv.h" -#include "../ldb_tdb/ldb_tdb.h" -#include "ldb_private.h" -#include "lib/util/binsearch.h" -#include "lib/util/attr.h" - -struct dn_list { - unsigned int count; - struct ldb_val *dn; - /* - * Do not optimise the intersection of this list, - * we must never return an entry not in this - * list. This allows the index for - * SCOPE_ONELEVEL to be trusted. - */ - bool strict; -}; - -struct ldb_kv_idxptr { - /* - * In memory tdb to cache the index updates performed during a - * transaction. This improves the performance of operations like - * re-index and join - */ - struct tdb_context *itdb; - int error; -}; - -enum key_truncation { - KEY_NOT_TRUNCATED, - KEY_TRUNCATED, -}; - -static int ldb_kv_write_index_dn_guid(struct ldb_module *module, - const struct ldb_message *msg, - int add); -static int ldb_kv_index_dn_base_dn(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - struct ldb_dn *base_dn, - struct dn_list *dn_list, - enum key_truncation *truncation); - -static void ldb_kv_dn_list_sort(struct ldb_kv_private *ldb_kv, - struct dn_list *list); - -/* we put a @IDXVERSION attribute on index entries. This - allows us to tell if it was written by an older version -*/ -#define LDB_KV_INDEXING_VERSION 2 - -#define LDB_KV_GUID_INDEXING_VERSION 3 - -static unsigned ldb_kv_max_key_length(struct ldb_kv_private *ldb_kv) -{ - if (ldb_kv->max_key_length == 0) { - return UINT_MAX; - } - return ldb_kv->max_key_length; -} - -/* enable the idxptr mode when transactions start */ -int ldb_kv_index_transaction_start( - struct ldb_module *module, - size_t cache_size) -{ - struct ldb_kv_private *ldb_kv = talloc_get_type( - ldb_module_get_private(module), struct ldb_kv_private); - ldb_kv->idxptr = talloc_zero(ldb_kv, struct ldb_kv_idxptr); - if (ldb_kv->idxptr == NULL) { - return ldb_oom(ldb_module_get_ctx(module)); - } - - ldb_kv->idxptr->itdb = tdb_open( - NULL, - cache_size, - TDB_INTERNAL, - O_RDWR, - 0); - if (ldb_kv->idxptr->itdb == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return LDB_SUCCESS; -} - -/* - see if two ldb_val structures contain exactly the same data - return -1 or 1 for a mismatch, 0 for match -*/ -static int ldb_val_equal_exact_for_qsort(const struct ldb_val *v1, - const struct ldb_val *v2) -{ - if (v1->length > v2->length) { - return -1; - } - if (v1->length < v2->length) { - return 1; - } - return memcmp(v1->data, v2->data, v1->length); -} - -/* - see if two ldb_val structures contain exactly the same data - return -1 or 1 for a mismatch, 0 for match -*/ -static int ldb_val_equal_exact_ordered(const struct ldb_val v1, - const struct ldb_val *v2) -{ - if (v1.length > v2->length) { - return -1; - } - if (v1.length < v2->length) { - return 1; - } - return memcmp(v1.data, v2->data, v1.length); -} - - -/* - find a entry in a dn_list, using a ldb_val. Uses a case sensitive - binary-safe comparison for the 'dn' returns -1 if not found - - This is therefore safe when the value is a GUID in the future - */ -static int ldb_kv_dn_list_find_val(struct ldb_kv_private *ldb_kv, - const struct dn_list *list, - const struct ldb_val *v) -{ - unsigned int i; - struct ldb_val *exact = NULL, *next = NULL; - - if (ldb_kv->cache->GUID_index_attribute == NULL) { - for (i=0; icount; i++) { - if (ldb_val_equal_exact(&list->dn[i], v) == 1) { - return i; - } - } - return -1; - } - - BINARY_ARRAY_SEARCH_GTE(list->dn, list->count, - *v, ldb_val_equal_exact_ordered, - exact, next); - if (exact == NULL) { - return -1; - } - /* Not required, but keeps the compiler quiet */ - if (next != NULL) { - return -1; - } - - i = exact - list->dn; - return i; -} - -/* - find a entry in a dn_list. Uses a case sensitive comparison with the dn - returns -1 if not found - */ -static int ldb_kv_dn_list_find_msg(struct ldb_kv_private *ldb_kv, - struct dn_list *list, - const struct ldb_message *msg) -{ - struct ldb_val v; - const struct ldb_val *key_val; - if (ldb_kv->cache->GUID_index_attribute == NULL) { - const char *dn_str = ldb_dn_get_linearized(msg->dn); - v.data = discard_const_p(unsigned char, dn_str); - v.length = strlen(dn_str); - } else { - key_val = ldb_msg_find_ldb_val( - msg, ldb_kv->cache->GUID_index_attribute); - if (key_val == NULL) { - return -1; - } - v = *key_val; - } - return ldb_kv_dn_list_find_val(ldb_kv, list, &v); -} - -/* - this is effectively a cast function, but with lots of paranoia - checks and also copes with CPUs that are fussy about pointer - alignment - */ -static struct dn_list *ldb_kv_index_idxptr(struct ldb_module *module, - TDB_DATA rec) -{ - struct dn_list *list; - if (rec.dsize != sizeof(void *)) { - ldb_asprintf_errstring(ldb_module_get_ctx(module), - "Bad data size for idxptr %u", (unsigned)rec.dsize); - return NULL; - } - /* note that we can't just use a cast here, as rec.dptr may - not be aligned sufficiently for a pointer. A cast would cause - platforms like some ARM CPUs to crash */ - memcpy(&list, rec.dptr, sizeof(void *)); - list = talloc_get_type(list, struct dn_list); - if (list == NULL) { - ldb_asprintf_errstring(ldb_module_get_ctx(module), - "Bad type '%s' for idxptr", - talloc_get_name(list)); - return NULL; - } - return list; -} - -enum dn_list_will_be_read_only { - DN_LIST_MUTABLE = 0, - DN_LIST_WILL_BE_READ_ONLY = 1, -}; - -/* - return the @IDX list in an index entry for a dn as a - struct dn_list - */ -static int ldb_kv_dn_list_load(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - struct ldb_dn *dn, - struct dn_list *list, - enum dn_list_will_be_read_only read_only) -{ - struct ldb_message *msg; - int ret, version; - struct ldb_message_element *el; - TDB_DATA rec = {0}; - struct dn_list *list2; - bool from_primary_cache = false; - TDB_DATA key = {0}; - - list->dn = NULL; - list->count = 0; - list->strict = false; - - /* - * See if we have an in memory index cache - */ - if (ldb_kv->idxptr == NULL) { - goto normal_index; - } - - key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn)); - key.dsize = strlen((char *)key.dptr); - - /* - * Have we cached this index record? - * If we have a nested transaction cache try that first. - * then try the transaction cache. - * if the record is not cached it will need to be read from disk. - */ - if (ldb_kv->nested_idx_ptr != NULL) { - rec = tdb_fetch(ldb_kv->nested_idx_ptr->itdb, key); - } - if (rec.dptr == NULL) { - from_primary_cache = true; - rec = tdb_fetch(ldb_kv->idxptr->itdb, key); - } - if (rec.dptr == NULL) { - goto normal_index; - } - - /* we've found an in-memory index entry */ - list2 = ldb_kv_index_idxptr(module, rec); - if (list2 == NULL) { - free(rec.dptr); - return LDB_ERR_OPERATIONS_ERROR; - } - free(rec.dptr); - - /* - * If this is a read only transaction the indexes will not be - * changed so we don't need a copy in the event of a rollback - * - * In this case make an early return - */ - if (read_only == DN_LIST_WILL_BE_READ_ONLY) { - *list = *list2; - return LDB_SUCCESS; - } - - /* - * record was read from the sub transaction cache, so we have - * already copied the primary cache record - */ - if (!from_primary_cache) { - *list = *list2; - return LDB_SUCCESS; - } - - /* - * No index sub transaction active, so no need to cache a copy - */ - if (ldb_kv->nested_idx_ptr == NULL) { - *list = *list2; - return LDB_SUCCESS; - } - - /* - * There is an active index sub transaction, and the record was - * found in the primary index transaction cache. A copy of the - * record needs be taken to prevent the original entry being - * altered, until the index sub transaction is committed. - */ - - { - struct ldb_val *dns = NULL; - size_t x = 0; - - dns = talloc_array( - list, - struct ldb_val, - list2->count); - if (dns == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - for (x = 0; x < list2->count; x++) { - dns[x].length = list2->dn[x].length; - dns[x].data = talloc_memdup( - dns, - list2->dn[x].data, - list2->dn[x].length); - if (dns[x].data == NULL) { - TALLOC_FREE(dns); - return LDB_ERR_OPERATIONS_ERROR; - } - } - list->dn = dns; - list->count = list2->count; - } - return LDB_SUCCESS; - - /* - * Index record not found in the caches, read it from the - * database. - */ -normal_index: - msg = ldb_msg_new(list); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_kv_search_dn1(module, - dn, - msg, - LDB_UNPACK_DATA_FLAG_NO_DN | - /* - * The entry point ldb_kv_search_indexed is - * only called from the read-locked - * ldb_kv_search. - */ - LDB_UNPACK_DATA_FLAG_READ_LOCKED); - if (ret != LDB_SUCCESS) { - talloc_free(msg); - return ret; - } - - el = ldb_msg_find_element(msg, LDB_KV_IDX); - if (!el) { - talloc_free(msg); - return LDB_SUCCESS; - } - - version = ldb_msg_find_attr_as_int(msg, LDB_KV_IDXVERSION, 0); - - /* - * we avoid copying the strings by stealing the list. We have - * to steal msg onto el->values (which looks odd) because - * the memory is allocated on msg, not on each value. - */ - if (ldb_kv->cache->GUID_index_attribute == NULL) { - /* check indexing version number */ - if (version != LDB_KV_INDEXING_VERSION) { - ldb_debug_set(ldb_module_get_ctx(module), - LDB_DEBUG_ERROR, - "Wrong DN index version %d " - "expected %d for %s", - version, LDB_KV_INDEXING_VERSION, - ldb_dn_get_linearized(dn)); - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - talloc_steal(el->values, msg); - list->dn = talloc_steal(list, el->values); - list->count = el->num_values; - } else { - unsigned int i; - if (version != LDB_KV_GUID_INDEXING_VERSION) { - /* This is quite likely during the DB startup - on first upgrade to using a GUID index */ - ldb_debug_set(ldb_module_get_ctx(module), - LDB_DEBUG_ERROR, - "Wrong GUID index version %d " - "expected %d for %s", - version, LDB_KV_GUID_INDEXING_VERSION, - ldb_dn_get_linearized(dn)); - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (el->num_values == 0) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - if ((el->values[0].length % LDB_KV_GUID_SIZE) != 0) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - list->count = el->values[0].length / LDB_KV_GUID_SIZE; - list->dn = talloc_array(list, struct ldb_val, list->count); - if (list->dn == NULL) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* - * The actual data is on msg. - */ - talloc_steal(list->dn, msg); - for (i = 0; i < list->count; i++) { - list->dn[i].data - = &el->values[0].data[i * LDB_KV_GUID_SIZE]; - list->dn[i].length = LDB_KV_GUID_SIZE; - } - } - - /* We don't need msg->elements any more */ - talloc_free(msg->elements); - return LDB_SUCCESS; -} - -int ldb_kv_key_dn_from_idx(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - TALLOC_CTX *mem_ctx, - struct ldb_dn *dn, - struct ldb_val *ldb_key) -{ - struct ldb_context *ldb = ldb_module_get_ctx(module); - int ret; - int index = 0; - enum key_truncation truncation = KEY_NOT_TRUNCATED; - struct dn_list *list = talloc(mem_ctx, struct dn_list); - if (list == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_kv_index_dn_base_dn(module, ldb_kv, dn, list, &truncation); - if (ret != LDB_SUCCESS) { - TALLOC_FREE(list); - return ret; - } - - if (list->count == 0) { - TALLOC_FREE(list); - return LDB_ERR_NO_SUCH_OBJECT; - } - - if (list->count > 1 && truncation == KEY_NOT_TRUNCATED) { - const char *dn_str = ldb_dn_get_linearized(dn); - ldb_asprintf_errstring(ldb_module_get_ctx(module), - __location__ - ": Failed to read DN index " - "against %s for %s: too many " - "values (%u > 1)", - ldb_kv->cache->GUID_index_attribute, - dn_str, - list->count); - TALLOC_FREE(list); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - - if (list->count > 0 && truncation == KEY_TRUNCATED) { - /* - * DN key has been truncated, need to inspect the actual - * records to locate the actual DN - */ - unsigned int i; - index = -1; - for (i=0; i < list->count; i++) { - uint8_t guid_key[LDB_KV_GUID_KEY_SIZE]; - struct ldb_val key = { - .data = guid_key, - .length = sizeof(guid_key) - }; - const int flags = LDB_UNPACK_DATA_FLAG_NO_ATTRS; - struct ldb_message *rec = ldb_msg_new(ldb); - if (rec == NULL) { - TALLOC_FREE(list); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_kv_idx_to_key( - module, ldb_kv, ldb, &list->dn[i], &key); - if (ret != LDB_SUCCESS) { - TALLOC_FREE(list); - TALLOC_FREE(rec); - return ret; - } - - ret = - ldb_kv_search_key(module, ldb_kv, key, rec, flags); - if (key.data != guid_key) { - TALLOC_FREE(key.data); - } - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - /* - * the record has disappeared? - * yes, this can happen - */ - TALLOC_FREE(rec); - continue; - } - - if (ret != LDB_SUCCESS) { - /* an internal error */ - TALLOC_FREE(rec); - TALLOC_FREE(list); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* - * We found the actual DN that we wanted from in the - * multiple values that matched the index - * (due to truncation), so return that. - * - */ - if (ldb_dn_compare(dn, rec->dn) == 0) { - index = i; - TALLOC_FREE(rec); - break; - } - } - - /* - * We matched the index but the actual DN we wanted - * was not here. - */ - if (index == -1) { - TALLOC_FREE(list); - return LDB_ERR_NO_SUCH_OBJECT; - } - } - - /* The ldb_key memory is allocated by the caller */ - ret = ldb_kv_guid_to_key(&list->dn[index], ldb_key); - TALLOC_FREE(list); - - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return LDB_SUCCESS; -} - - - -/* - save a dn_list into a full @IDX style record - */ -static int ldb_kv_dn_list_store_full(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - struct ldb_dn *dn, - struct dn_list *list) -{ - struct ldb_message *msg; - int ret; - - msg = ldb_msg_new(module); - if (!msg) { - return ldb_module_oom(module); - } - - msg->dn = dn; - - if (list->count == 0) { - ret = ldb_kv_delete_noindex(module, msg); - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - ret = LDB_SUCCESS; - } - TALLOC_FREE(msg); - return ret; - } - - if (ldb_kv->cache->GUID_index_attribute == NULL) { - ret = ldb_msg_add_fmt(msg, LDB_KV_IDXVERSION, "%u", - LDB_KV_INDEXING_VERSION); - if (ret != LDB_SUCCESS) { - TALLOC_FREE(msg); - return ldb_module_oom(module); - } - } else { - ret = ldb_msg_add_fmt(msg, LDB_KV_IDXVERSION, "%u", - LDB_KV_GUID_INDEXING_VERSION); - if (ret != LDB_SUCCESS) { - TALLOC_FREE(msg); - return ldb_module_oom(module); - } - } - - if (list->count > 0) { - struct ldb_message_element *el; - - ret = ldb_msg_add_empty(msg, LDB_KV_IDX, LDB_FLAG_MOD_ADD, &el); - if (ret != LDB_SUCCESS) { - TALLOC_FREE(msg); - return ldb_module_oom(module); - } - - if (ldb_kv->cache->GUID_index_attribute == NULL) { - el->values = list->dn; - el->num_values = list->count; - } else { - struct ldb_val v; - unsigned int i; - el->values = talloc_array(msg, - struct ldb_val, 1); - if (el->values == NULL) { - TALLOC_FREE(msg); - return ldb_module_oom(module); - } - - v.data = talloc_array_size(el->values, - list->count, - LDB_KV_GUID_SIZE); - if (v.data == NULL) { - TALLOC_FREE(msg); - return ldb_module_oom(module); - } - - v.length = talloc_get_size(v.data); - - for (i = 0; i < list->count; i++) { - if (list->dn[i].length != - LDB_KV_GUID_SIZE) { - TALLOC_FREE(msg); - return ldb_module_operr(module); - } - memcpy(&v.data[LDB_KV_GUID_SIZE*i], - list->dn[i].data, - LDB_KV_GUID_SIZE); - } - el->values[0] = v; - el->num_values = 1; - } - } - - ret = ldb_kv_store(module, msg, TDB_REPLACE); - TALLOC_FREE(msg); - return ret; -} - -/* - save a dn_list into the database, in either @IDX or internal format - */ -static int ldb_kv_dn_list_store(struct ldb_module *module, - struct ldb_dn *dn, - struct dn_list *list) -{ - struct ldb_kv_private *ldb_kv = talloc_get_type( - ldb_module_get_private(module), struct ldb_kv_private); - TDB_DATA rec = {0}; - TDB_DATA key = {0}; - - int ret = LDB_SUCCESS; - struct dn_list *list2 = NULL; - struct ldb_kv_idxptr *idxptr = NULL; - - key.dptr = discard_const_p(unsigned char, ldb_dn_get_linearized(dn)); - if (key.dptr == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - key.dsize = strlen((char *)key.dptr); - - /* - * If there is an index sub transaction active, update the - * sub transaction index cache. Otherwise update the - * primary index cache - */ - if (ldb_kv->nested_idx_ptr != NULL) { - idxptr = ldb_kv->nested_idx_ptr; - } else { - idxptr = ldb_kv->idxptr; - } - /* - * Get the cache entry for the index - * - * As the value in the cache is a pointer to a dn_list we update - * the dn_list directly. - * - */ - rec = tdb_fetch(idxptr->itdb, key); - if (rec.dptr != NULL) { - list2 = ldb_kv_index_idxptr(module, rec); - if (list2 == NULL) { - free(rec.dptr); - return LDB_ERR_OPERATIONS_ERROR; - } - free(rec.dptr); - /* Now put the updated pointer back in the cache */ - if (list->dn == NULL) { - list2->dn = NULL; - list2->count = 0; - } else { - list2->dn = talloc_steal(list2, list->dn); - list2->count = list->count; - } - return LDB_SUCCESS; - } - - list2 = talloc(idxptr, struct dn_list); - if (list2 == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - list2->dn = talloc_steal(list2, list->dn); - list2->count = list->count; - - rec.dptr = (uint8_t *)&list2; - rec.dsize = sizeof(void *); - - - /* - * This is not a store into the main DB, but into an in-memory - * TDB, so we don't need a guard on ltdb->read_only - * - * Also as we directly update the in memory dn_list for existing - * cache entries we must be adding a new entry to the cache. - */ - ret = tdb_store(idxptr->itdb, key, rec, TDB_INSERT); - if (ret != 0) { - return ltdb_err_map( tdb_error(idxptr->itdb)); - } - return LDB_SUCCESS; -} - -/* - traverse function for storing the in-memory index entries on disk - */ -static int ldb_kv_index_traverse_store(_UNUSED_ struct tdb_context *tdb, - TDB_DATA key, - TDB_DATA data, - void *state) -{ - struct ldb_module *module = state; - struct ldb_kv_private *ldb_kv = talloc_get_type( - ldb_module_get_private(module), struct ldb_kv_private); - struct ldb_dn *dn; - struct ldb_context *ldb = ldb_module_get_ctx(module); - struct ldb_val v; - struct dn_list *list; - - list = ldb_kv_index_idxptr(module, data); - if (list == NULL) { - ldb_kv->idxptr->error = LDB_ERR_OPERATIONS_ERROR; - return -1; - } - - v.data = key.dptr; - v.length = strnlen((char *)key.dptr, key.dsize); - - dn = ldb_dn_from_ldb_val(module, ldb, &v); - if (dn == NULL) { - ldb_asprintf_errstring(ldb, "Failed to parse index key %*.*s as an LDB DN", (int)v.length, (int)v.length, (const char *)v.data); - ldb_kv->idxptr->error = LDB_ERR_OPERATIONS_ERROR; - return -1; - } - - ldb_kv->idxptr->error = - ldb_kv_dn_list_store_full(module, ldb_kv, dn, list); - talloc_free(dn); - if (ldb_kv->idxptr->error != 0) { - return -1; - } - return 0; -} - -/* cleanup the idxptr mode when transaction commits */ -int ldb_kv_index_transaction_commit(struct ldb_module *module) -{ - struct ldb_kv_private *ldb_kv = talloc_get_type( - ldb_module_get_private(module), struct ldb_kv_private); - int ret; - - struct ldb_context *ldb = ldb_module_get_ctx(module); - - ldb_reset_err_string(ldb); - - if (ldb_kv->idxptr->itdb) { - tdb_traverse( - ldb_kv->idxptr->itdb, ldb_kv_index_traverse_store, module); - tdb_close(ldb_kv->idxptr->itdb); - } - - ret = ldb_kv->idxptr->error; - if (ret != LDB_SUCCESS) { - if (!ldb_errstring(ldb)) { - ldb_set_errstring(ldb, ldb_strerror(ret)); - } - ldb_asprintf_errstring(ldb, "Failed to store index records in transaction commit: %s", ldb_errstring(ldb)); - } - - talloc_free(ldb_kv->idxptr); - ldb_kv->idxptr = NULL; - return ret; -} - -/* cleanup the idxptr mode when transaction cancels */ -int ldb_kv_index_transaction_cancel(struct ldb_module *module) -{ - struct ldb_kv_private *ldb_kv = talloc_get_type( - ldb_module_get_private(module), struct ldb_kv_private); - if (ldb_kv->idxptr && ldb_kv->idxptr->itdb) { - tdb_close(ldb_kv->idxptr->itdb); - } - TALLOC_FREE(ldb_kv->idxptr); - if (ldb_kv->nested_idx_ptr && ldb_kv->nested_idx_ptr->itdb) { - tdb_close(ldb_kv->nested_idx_ptr->itdb); - } - TALLOC_FREE(ldb_kv->nested_idx_ptr); - return LDB_SUCCESS; -} - - -/* - return the dn key to be used for an index - the caller is responsible for freeing -*/ -static struct ldb_dn *ldb_kv_index_key(struct ldb_context *ldb, - struct ldb_kv_private *ldb_kv, - const char *attr, - const struct ldb_val *value, - const struct ldb_schema_attribute **ap, - enum key_truncation *truncation) -{ - struct ldb_dn *ret; - struct ldb_val v; - const struct ldb_schema_attribute *a = NULL; - char *attr_folded = NULL; - const char *attr_for_dn = NULL; - int r; - bool should_b64_encode; - - unsigned int max_key_length = ldb_kv_max_key_length(ldb_kv); - size_t key_len = 0; - size_t attr_len = 0; - const size_t indx_len = sizeof(LDB_KV_INDEX) - 1; - unsigned frmt_len = 0; - const size_t additional_key_length = 4; - unsigned int num_separators = 3; /* Estimate for overflow check */ - const size_t min_data = 1; - const size_t min_key_length = additional_key_length - + indx_len + num_separators + min_data; - struct ldb_val empty; - - /* - * Accept a NULL value as a request for a key with no value. This is - * different from passing an empty value, which might be given - * significance by some canonicalise functions. - */ - bool empty_val = value == NULL; - if (empty_val) { - empty.length = 0; - empty.data = discard_const_p(unsigned char, ""); - value = ∅ - } - - if (attr[0] == '@') { - attr_for_dn = attr; - v = *value; - if (ap != NULL) { - *ap = NULL; - } - } else { - attr_folded = ldb_attr_casefold(ldb, attr); - if (!attr_folded) { - return NULL; - } - - attr_for_dn = attr_folded; - - a = ldb_schema_attribute_by_name(ldb, attr); - if (ap) { - *ap = a; - } - - if (empty_val) { - v = *value; - } else { - ldb_attr_handler_t fn; - if (a->syntax->index_format_fn && - ldb_kv->cache->GUID_index_attribute != NULL) { - fn = a->syntax->index_format_fn; - } else { - fn = a->syntax->canonicalise_fn; - } - r = fn(ldb, ldb, value, &v); - if (r != LDB_SUCCESS) { - const char *errstr = ldb_errstring(ldb); - /* canonicalisation can be refused. For - example, a attribute that takes wildcards - will refuse to canonicalise if the value - contains a wildcard */ - ldb_asprintf_errstring(ldb, - "Failed to create " - "index key for " - "attribute '%s':%s%s%s", - attr, ldb_strerror(r), - (errstr?":":""), - (errstr?errstr:"")); - talloc_free(attr_folded); - return NULL; - } - } - } - attr_len = strlen(attr_for_dn); - - /* - * Check if there is any hope this will fit into the DB. - * Overflow here is not actually critical the code below - * checks again to make the printf and the DB does another - * check for too long keys - */ - if (max_key_length - attr_len < min_key_length) { - ldb_asprintf_errstring( - ldb, - __location__ ": max_key_length " - "is too small (%u) < (%u)", - max_key_length, - (unsigned)(min_key_length + attr_len)); - talloc_free(attr_folded); - return NULL; - } - - /* - * ltdb_key_dn() makes something 4 bytes longer, it adds a leading - * "DN=" and a trailing string terminator - */ - max_key_length -= additional_key_length; - - /* - * We do not base 64 encode a DN in a key, it has already been - * casefold and lineraized, that is good enough. That already - * avoids embedded NUL etc. - */ - if (ldb_kv->cache->GUID_index_attribute != NULL) { - if (strcmp(attr, LDB_KV_IDXDN) == 0) { - should_b64_encode = false; - } else if (strcmp(attr, LDB_KV_IDXONE) == 0) { - /* - * We can only change the behaviour for IDXONE - * when the GUID index is enabled - */ - should_b64_encode = false; - } else { - should_b64_encode - = ldb_should_b64_encode(ldb, &v); - } - } else { - should_b64_encode = ldb_should_b64_encode(ldb, &v); - } - - if (should_b64_encode) { - size_t vstr_len = 0; - char *vstr = ldb_base64_encode(ldb, (char *)v.data, v.length); - if (!vstr) { - talloc_free(attr_folded); - return NULL; - } - vstr_len = strlen(vstr); - /* - * Overflow here is not critical as we only use this - * to choose the printf truncation - */ - key_len = num_separators + indx_len + attr_len + vstr_len; - if (key_len > max_key_length) { - size_t excess = key_len - max_key_length; - frmt_len = vstr_len - excess; - *truncation = KEY_TRUNCATED; - /* - * Truncated keys are placed in a separate key space - * from the non truncated keys - * Note: the double hash "##" is not a typo and - * indicates that the following value is base64 encoded - */ - ret = ldb_dn_new_fmt(ldb, ldb, "%s#%s##%.*s", - LDB_KV_INDEX, attr_for_dn, - frmt_len, vstr); - } else { - frmt_len = vstr_len; - *truncation = KEY_NOT_TRUNCATED; - /* - * Note: the double colon "::" is not a typo and - * indicates that the following value is base64 encoded - */ - ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s::%.*s", - LDB_KV_INDEX, attr_for_dn, - frmt_len, vstr); - } - talloc_free(vstr); - } else { - /* Only need two seperators */ - num_separators = 2; - - /* - * Overflow here is not critical as we only use this - * to choose the printf truncation - */ - key_len = num_separators + indx_len + attr_len + (int)v.length; - if (key_len > max_key_length) { - size_t excess = key_len - max_key_length; - frmt_len = v.length - excess; - *truncation = KEY_TRUNCATED; - /* - * Truncated keys are placed in a separate key space - * from the non truncated keys - */ - ret = ldb_dn_new_fmt(ldb, ldb, "%s#%s#%.*s", - LDB_KV_INDEX, attr_for_dn, - frmt_len, (char *)v.data); - } else { - frmt_len = v.length; - *truncation = KEY_NOT_TRUNCATED; - ret = ldb_dn_new_fmt(ldb, ldb, "%s:%s:%.*s", - LDB_KV_INDEX, attr_for_dn, - frmt_len, (char *)v.data); - } - } - - if (v.data != value->data && !empty_val) { - talloc_free(v.data); - } - talloc_free(attr_folded); - - return ret; -} - -/* - see if a attribute value is in the list of indexed attributes -*/ -static bool ldb_kv_is_indexed(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const char *attr) -{ - struct ldb_context *ldb = ldb_module_get_ctx(module); - unsigned int i; - struct ldb_message_element *el; - - if ((ldb_kv->cache->GUID_index_attribute != NULL) && - (ldb_attr_cmp(attr, ldb_kv->cache->GUID_index_attribute) == 0)) { - /* Implicity covered, this is the index key */ - return false; - } - if (ldb->schema.index_handler_override) { - const struct ldb_schema_attribute *a - = ldb_schema_attribute_by_name(ldb, attr); - - if (a == NULL) { - return false; - } - - if (a->flags & LDB_ATTR_FLAG_INDEXED) { - return true; - } else { - return false; - } - } - - if (!ldb_kv->cache->attribute_indexes) { - return false; - } - - el = ldb_msg_find_element(ldb_kv->cache->indexlist, LDB_KV_IDXATTR); - if (el == NULL) { - return false; - } - - /* TODO: this is too expensive! At least use a binary search */ - for (i=0; inum_values; i++) { - if (ldb_attr_cmp((char *)el->values[i].data, attr) == 0) { - return true; - } - } - return false; -} - -/* - in the following logic functions, the return value is treated as - follows: - - LDB_SUCCESS: we found some matching index values - - LDB_ERR_NO_SUCH_OBJECT: we know for sure that no object matches - - LDB_ERR_OPERATIONS_ERROR: indexing could not answer the call, - we'll need a full search - */ - -/* - return a list of dn's that might match a simple indexed search (an - equality search only) - */ -static int ldb_kv_index_dn_simple(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_parse_tree *tree, - struct dn_list *list) -{ - struct ldb_context *ldb; - struct ldb_dn *dn; - int ret; - enum key_truncation truncation = KEY_NOT_TRUNCATED; - - ldb = ldb_module_get_ctx(module); - - list->count = 0; - list->dn = NULL; - - /* if the attribute isn't in the list of indexed attributes then - this node needs a full search */ - if (!ldb_kv_is_indexed(module, ldb_kv, tree->u.equality.attr)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* the attribute is indexed. Pull the list of DNs that match the - search criterion */ - dn = ldb_kv_index_key(ldb, - ldb_kv, - tree->u.equality.attr, - &tree->u.equality.value, - NULL, - &truncation); - /* - * We ignore truncation here and allow multi-valued matches - * as ltdb_search_indexed will filter out the wrong one in - * ltdb_index_filter() which calls ldb_match_message(). - */ - if (!dn) return LDB_ERR_OPERATIONS_ERROR; - - ret = ldb_kv_dn_list_load(module, ldb_kv, dn, list, - DN_LIST_WILL_BE_READ_ONLY); - talloc_free(dn); - return ret; -} - -static bool list_union(struct ldb_context *ldb, - struct ldb_kv_private *ldb_kv, - struct dn_list *list, - struct dn_list *list2); - -/* - return a list of dn's that might match a leaf indexed search - */ -static int ldb_kv_index_dn_leaf(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_parse_tree *tree, - struct dn_list *list) -{ - if (ldb_kv->disallow_dn_filter && - (ldb_attr_cmp(tree->u.equality.attr, "dn") == 0)) { - /* in AD mode we do not support "(dn=...)" search filters */ - list->dn = NULL; - list->count = 0; - return LDB_SUCCESS; - } - if (tree->u.equality.attr[0] == '@') { - /* Do not allow a indexed search against an @ */ - list->dn = NULL; - list->count = 0; - return LDB_SUCCESS; - } - if (ldb_attr_dn(tree->u.equality.attr) == 0) { - enum key_truncation truncation = KEY_NOT_TRUNCATED; - bool valid_dn = false; - struct ldb_dn *dn - = ldb_dn_from_ldb_val(list, - ldb_module_get_ctx(module), - &tree->u.equality.value); - if (dn == NULL) { - /* If we can't parse it, no match */ - list->dn = NULL; - list->count = 0; - return LDB_SUCCESS; - } - - valid_dn = ldb_dn_validate(dn); - if (valid_dn == false) { - /* If we can't parse it, no match */ - list->dn = NULL; - list->count = 0; - return LDB_SUCCESS; - } - - /* - * Re-use the same code we use for a SCOPE_BASE - * search - * - * We can't call TALLOC_FREE(dn) as this must belong - * to list for the memory to remain valid. - */ - return ldb_kv_index_dn_base_dn( - module, ldb_kv, dn, list, &truncation); - /* - * We ignore truncation here and allow multi-valued matches - * as ltdb_search_indexed will filter out the wrong one in - * ltdb_index_filter() which calls ldb_match_message(). - */ - - } else if ((ldb_kv->cache->GUID_index_attribute != NULL) && - (ldb_attr_cmp(tree->u.equality.attr, - ldb_kv->cache->GUID_index_attribute) == 0)) { - int ret; - struct ldb_context *ldb = ldb_module_get_ctx(module); - list->dn = talloc_array(list, struct ldb_val, 1); - if (list->dn == NULL) { - ldb_module_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - /* - * We need to go via the canonicalise_fn() to - * ensure we get the index in binary, rather - * than a string - */ - ret = ldb_kv->GUID_index_syntax->canonicalise_fn( - ldb, list->dn, &tree->u.equality.value, &list->dn[0]); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - list->count = 1; - return LDB_SUCCESS; - } - - return ldb_kv_index_dn_simple(module, ldb_kv, tree, list); -} - - -/* - list intersection - list = list & list2 -*/ -static bool list_intersect(struct ldb_kv_private *ldb_kv, - struct dn_list *list, - const struct dn_list *list2) -{ - const struct dn_list *short_list, *long_list; - struct dn_list *list3; - unsigned int i; - - if (list->count == 0) { - /* 0 & X == 0 */ - return true; - } - if (list2->count == 0) { - /* X & 0 == 0 */ - list->count = 0; - list->dn = NULL; - return true; - } - - /* - * In both of the below we check for strict and in that - * case do not optimise the intersection of this list, - * we must never return an entry not in this - * list. This allows the index for - * SCOPE_ONELEVEL to be trusted. - */ - - /* the indexing code is allowed to return a longer list than - what really matches, as all results are filtered by the - full expression at the end - this shortcut avoids a lot of - work in some cases */ - if (list->count < 2 && list2->count > 10 && list2->strict == false) { - return true; - } - if (list2->count < 2 && list->count > 10 && list->strict == false) { - list->count = list2->count; - list->dn = list2->dn; - /* note that list2 may not be the parent of list2->dn, - as list2->dn may be owned by ltdb->idxptr. In that - case we expect this reparent call to fail, which is - OK */ - talloc_reparent(list2, list, list2->dn); - return true; - } - - if (list->count > list2->count) { - short_list = list2; - long_list = list; - } else { - short_list = list; - long_list = list2; - } - - list3 = talloc_zero(list, struct dn_list); - if (list3 == NULL) { - return false; - } - - list3->dn = talloc_array(list3, struct ldb_val, - MIN(list->count, list2->count)); - if (!list3->dn) { - talloc_free(list3); - return false; - } - list3->count = 0; - - for (i=0;icount;i++) { - /* For the GUID index case, this is a binary search */ - if (ldb_kv_dn_list_find_val( - ldb_kv, long_list, &short_list->dn[i]) != -1) { - list3->dn[list3->count] = short_list->dn[i]; - list3->count++; - } - } - - list->strict |= list2->strict; - list->dn = talloc_steal(list, list3->dn); - list->count = list3->count; - talloc_free(list3); - - return true; -} - - -/* - list union - list = list | list2 -*/ -static bool list_union(struct ldb_context *ldb, - struct ldb_kv_private *ldb_kv, - struct dn_list *list, - struct dn_list *list2) -{ - struct ldb_val *dn3; - unsigned int i = 0, j = 0, k = 0; - - if (list2->count == 0) { - /* X | 0 == X */ - return true; - } - - if (list->count == 0) { - /* 0 | X == X */ - list->count = list2->count; - list->dn = list2->dn; - /* note that list2 may not be the parent of list2->dn, - as list2->dn may be owned by ltdb->idxptr. In that - case we expect this reparent call to fail, which is - OK */ - talloc_reparent(list2, list, list2->dn); - return true; - } - - /* - * Sort the lists (if not in GUID DN mode) so we can do - * the de-duplication during the merge - * - * NOTE: This can sort the in-memory index values, as list or - * list2 might not be a copy! - */ - ldb_kv_dn_list_sort(ldb_kv, list); - ldb_kv_dn_list_sort(ldb_kv, list2); - - dn3 = talloc_array(list, struct ldb_val, list->count + list2->count); - if (!dn3) { - ldb_oom(ldb); - return false; - } - - while (i < list->count || j < list2->count) { - int cmp; - if (i >= list->count) { - cmp = 1; - } else if (j >= list2->count) { - cmp = -1; - } else { - cmp = ldb_val_equal_exact_ordered(list->dn[i], - &list2->dn[j]); - } - - if (cmp < 0) { - /* Take list */ - dn3[k] = list->dn[i]; - i++; - k++; - } else if (cmp > 0) { - /* Take list2 */ - dn3[k] = list2->dn[j]; - j++; - k++; - } else { - /* Equal, take list */ - dn3[k] = list->dn[i]; - i++; - j++; - k++; - } - } - - list->dn = dn3; - list->count = k; - - return true; -} - -static int ldb_kv_index_dn(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_parse_tree *tree, - struct dn_list *list); - -/* - process an OR list (a union) - */ -static int ldb_kv_index_dn_or(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_parse_tree *tree, - struct dn_list *list) -{ - struct ldb_context *ldb; - unsigned int i; - - ldb = ldb_module_get_ctx(module); - - list->dn = NULL; - list->count = 0; - - for (i=0; iu.list.num_elements; i++) { - struct dn_list *list2; - int ret; - - list2 = talloc_zero(list, struct dn_list); - if (list2 == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_kv_index_dn( - module, ldb_kv, tree->u.list.elements[i], list2); - - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - /* X || 0 == X */ - talloc_free(list2); - continue; - } - - if (ret != LDB_SUCCESS) { - /* X || * == * */ - talloc_free(list2); - return ret; - } - - if (!list_union(ldb, ldb_kv, list, list2)) { - talloc_free(list2); - return LDB_ERR_OPERATIONS_ERROR; - } - } - - if (list->count == 0) { - return LDB_ERR_NO_SUCH_OBJECT; - } - - return LDB_SUCCESS; -} - - -/* - NOT an index results - */ -static int ldb_kv_index_dn_not(_UNUSED_ struct ldb_module *module, - _UNUSED_ struct ldb_kv_private *ldb_kv, - _UNUSED_ const struct ldb_parse_tree *tree, - _UNUSED_ struct dn_list *list) -{ - /* the only way to do an indexed not would be if we could - negate the not via another not or if we knew the total - number of database elements so we could know that the - existing expression covered the whole database. - - instead, we just give up, and rely on a full index scan - (unless an outer & manages to reduce the list) - */ - return LDB_ERR_OPERATIONS_ERROR; -} - -/* - * These things are unique, so avoid a full scan if this is a search - * by GUID, DN or a unique attribute - */ -static bool ldb_kv_index_unique(struct ldb_context *ldb, - struct ldb_kv_private *ldb_kv, - const char *attr) -{ - const struct ldb_schema_attribute *a; - if (ldb_kv->cache->GUID_index_attribute != NULL) { - if (ldb_attr_cmp(attr, ldb_kv->cache->GUID_index_attribute) == - 0) { - return true; - } - } - if (ldb_attr_dn(attr) == 0) { - return true; - } - - a = ldb_schema_attribute_by_name(ldb, attr); - if (a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX) { - return true; - } - return false; -} - -/* - process an AND expression (intersection) - */ -static int ldb_kv_index_dn_and(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_parse_tree *tree, - struct dn_list *list) -{ - struct ldb_context *ldb; - unsigned int i; - bool found; - - ldb = ldb_module_get_ctx(module); - - list->dn = NULL; - list->count = 0; - - /* in the first pass we only look for unique simple - equality tests, in the hope of avoiding having to look - at any others */ - for (i=0; iu.list.num_elements; i++) { - const struct ldb_parse_tree *subtree = tree->u.list.elements[i]; - int ret; - - if (subtree->operation != LDB_OP_EQUALITY || - !ldb_kv_index_unique( - ldb, ldb_kv, subtree->u.equality.attr)) { - continue; - } - - ret = ldb_kv_index_dn(module, ldb_kv, subtree, list); - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - /* 0 && X == 0 */ - return LDB_ERR_NO_SUCH_OBJECT; - } - if (ret == LDB_SUCCESS) { - /* a unique index match means we can - * stop. Note that we don't care if we return - * a few too many objects, due to later - * filtering */ - return LDB_SUCCESS; - } - } - - /* now do a full intersection */ - found = false; - - for (i=0; iu.list.num_elements; i++) { - const struct ldb_parse_tree *subtree = tree->u.list.elements[i]; - struct dn_list *list2; - int ret; - - list2 = talloc_zero(list, struct dn_list); - if (list2 == NULL) { - return ldb_module_oom(module); - } - - ret = ldb_kv_index_dn(module, ldb_kv, subtree, list2); - - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - /* X && 0 == 0 */ - list->dn = NULL; - list->count = 0; - talloc_free(list2); - return LDB_ERR_NO_SUCH_OBJECT; - } - - if (ret != LDB_SUCCESS) { - /* this didn't adding anything */ - talloc_free(list2); - continue; - } - - if (!found) { - talloc_reparent(list2, list, list->dn); - list->dn = list2->dn; - list->count = list2->count; - found = true; - } else if (!list_intersect(ldb_kv, list, list2)) { - talloc_free(list2); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (list->count == 0) { - list->dn = NULL; - return LDB_ERR_NO_SUCH_OBJECT; - } - - if (list->count < 2) { - /* it isn't worth loading the next part of the tree */ - return LDB_SUCCESS; - } - } - - if (!found) { - /* none of the attributes were indexed */ - return LDB_ERR_OPERATIONS_ERROR; - } - - return LDB_SUCCESS; -} - -struct ldb_kv_ordered_index_context { - struct ldb_module *module; - int error; - struct dn_list *dn_list; -}; - -static int traverse_range_index(_UNUSED_ struct ldb_kv_private *ldb_kv, - _UNUSED_ struct ldb_val key, - struct ldb_val data, - void *state) -{ - - struct ldb_context *ldb; - struct ldb_kv_ordered_index_context *ctx = - (struct ldb_kv_ordered_index_context *)state; - struct ldb_module *module = ctx->module; - struct ldb_message_element *el = NULL; - struct ldb_message *msg = NULL; - int version; - size_t dn_array_size, additional_length; - unsigned int i; - - ldb = ldb_module_get_ctx(module); - - msg = ldb_msg_new(module); - - ctx->error = ldb_unpack_data_flags(ldb, &data, msg, - LDB_UNPACK_DATA_FLAG_NO_DN); - - if (ctx->error != LDB_SUCCESS) { - talloc_free(msg); - return ctx->error; - } - - el = ldb_msg_find_element(msg, LDB_KV_IDX); - if (!el) { - talloc_free(msg); - return LDB_SUCCESS; - } - - version = ldb_msg_find_attr_as_int(msg, LDB_KV_IDXVERSION, 0); - - /* - * we avoid copying the strings by stealing the list. We have - * to steal msg onto el->values (which looks odd) because - * the memory is allocated on msg, not on each value. - */ - if (version != LDB_KV_GUID_INDEXING_VERSION) { - /* This is quite likely during the DB startup - on first upgrade to using a GUID index */ - ldb_debug_set(ldb_module_get_ctx(module), - LDB_DEBUG_ERROR, __location__ - ": Wrong GUID index version %d expected %d", - version, LDB_KV_GUID_INDEXING_VERSION); - talloc_free(msg); - ctx->error = LDB_ERR_OPERATIONS_ERROR; - return ctx->error; - } - - if (el->num_values == 0) { - talloc_free(msg); - ctx->error = LDB_ERR_OPERATIONS_ERROR; - return ctx->error; - } - - if ((el->values[0].length % LDB_KV_GUID_SIZE) != 0 - || el->values[0].length == 0) { - talloc_free(msg); - ctx->error = LDB_ERR_OPERATIONS_ERROR; - return ctx->error; - } - - dn_array_size = talloc_array_length(ctx->dn_list->dn); - - additional_length = el->values[0].length / LDB_KV_GUID_SIZE; - - if (ctx->dn_list->count + additional_length < ctx->dn_list->count) { - talloc_free(msg); - ctx->error = LDB_ERR_OPERATIONS_ERROR; - return ctx->error; - } - - if ((ctx->dn_list->count + additional_length) >= dn_array_size) { - size_t new_array_length; - - if (dn_array_size * 2 < dn_array_size) { - talloc_free(msg); - ctx->error = LDB_ERR_OPERATIONS_ERROR; - return ctx->error; - } - - new_array_length = MAX(ctx->dn_list->count + additional_length, - dn_array_size * 2); - - ctx->dn_list->dn = talloc_realloc(ctx->dn_list, - ctx->dn_list->dn, - struct ldb_val, - new_array_length); - } - - if (ctx->dn_list->dn == NULL) { - talloc_free(msg); - ctx->error = LDB_ERR_OPERATIONS_ERROR; - return ctx->error; - } - - /* - * The actual data is on msg. - */ - talloc_steal(ctx->dn_list->dn, msg); - for (i = 0; i < additional_length; i++) { - ctx->dn_list->dn[i + ctx->dn_list->count].data - = &el->values[0].data[i * LDB_KV_GUID_SIZE]; - ctx->dn_list->dn[i + ctx->dn_list->count].length = LDB_KV_GUID_SIZE; - - } - - ctx->dn_list->count += additional_length; - - talloc_free(msg->elements); - - return LDB_SUCCESS; -} - -/* - * >= and <= indexing implemented using lexicographically sorted keys - * - * We only run this in GUID indexing mode and when there is no write - * transaction (only implicit read locks are being held). Otherwise, we would - * have to deal with the in-memory index cache. - * - * We rely on the implementation of index_format_fn on a schema syntax which - * will can help us to construct keys which can be ordered correctly, and we - * terminate using schema agnostic start and end keys. - * - * index_format_fn must output values which can be memcmp-able to produce the - * correct ordering as defined by the schema syntax class. - */ -static int ldb_kv_index_dn_ordered(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_parse_tree *tree, - struct dn_list *list, bool ascending) -{ - enum key_truncation truncation = KEY_NOT_TRUNCATED; - struct ldb_context *ldb = ldb_module_get_ctx(module); - - struct ldb_val ldb_key = { 0 }, ldb_key2 = { 0 }; - struct ldb_val start_key, end_key; - struct ldb_dn *key_dn = NULL; - const struct ldb_schema_attribute *a = NULL; - - struct ldb_kv_ordered_index_context ctx; - int ret; - - TALLOC_CTX *tmp_ctx = talloc_new(NULL); - - if (!ldb_kv_is_indexed(module, ldb_kv, tree->u.comparison.attr)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (ldb_kv->cache->GUID_index_attribute == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* bail out if we're in a transaction, full search instead. */ - if (ldb_kv->kv_ops->transaction_active(ldb_kv)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (ldb_kv->disallow_dn_filter && - (ldb_attr_cmp(tree->u.comparison.attr, "dn") == 0)) { - /* in AD mode we do not support "(dn=...)" search filters */ - list->dn = NULL; - list->count = 0; - return LDB_SUCCESS; - } - if (tree->u.comparison.attr[0] == '@') { - /* Do not allow a indexed search against an @ */ - list->dn = NULL; - list->count = 0; - return LDB_SUCCESS; - } - - a = ldb_schema_attribute_by_name(ldb, tree->u.comparison.attr); - - /* - * If there's no index format function defined for this attr, then - * the lexicographic order in the database doesn't correspond to the - * attr's ordering, so we can't use the iterate_range op. - */ - if (a->syntax->index_format_fn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - key_dn = ldb_kv_index_key(ldb, ldb_kv, tree->u.comparison.attr, - &tree->u.comparison.value, - NULL, &truncation); - if (!key_dn) { - return LDB_ERR_OPERATIONS_ERROR; - } else if (truncation == KEY_TRUNCATED) { - ldb_debug(ldb, LDB_DEBUG_WARNING, - __location__ - ": ordered index violation: key dn truncated: %s\n", - ldb_dn_get_linearized(key_dn)); - return LDB_ERR_OPERATIONS_ERROR; - } - ldb_key = ldb_kv_key_dn(tmp_ctx, key_dn); - talloc_free(key_dn); - if (ldb_key.data == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - key_dn = ldb_kv_index_key(ldb, ldb_kv, tree->u.comparison.attr, - NULL, NULL, &truncation); - if (!key_dn) { - return LDB_ERR_OPERATIONS_ERROR; - } else if (truncation == KEY_TRUNCATED) { - ldb_debug(ldb, LDB_DEBUG_WARNING, - __location__ - ": ordered index violation: key dn truncated: %s\n", - ldb_dn_get_linearized(key_dn)); - return LDB_ERR_OPERATIONS_ERROR; - } - - ldb_key2 = ldb_kv_key_dn(tmp_ctx, key_dn); - talloc_free(key_dn); - if (ldb_key2.data == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* - * In order to avoid defining a start and end key for the search, we - * notice that each index key is of the form: - * - * DN=@INDEX::\0. - * - * We can simply make our start key DN=@INDEX:: and our end - * key DN=@INDEX:; to return all index entries for a - * particular attribute. - * - * Our LMDB backend uses the default memcmp for key comparison. - */ - - /* Eliminate NUL byte at the end of the empty key */ - ldb_key2.length--; - - if (ascending) { - /* : becomes ; for pseudo end-key */ - ldb_key2.data[ldb_key2.length-1]++; - start_key = ldb_key; - end_key = ldb_key2; - } else { - start_key = ldb_key2; - end_key = ldb_key; - } - - ctx.module = module; - ctx.error = 0; - ctx.dn_list = list; - ctx.dn_list->count = 0; - ctx.dn_list->dn = talloc_zero_array(ctx.dn_list, struct ldb_val, 2); - - ret = ldb_kv->kv_ops->iterate_range(ldb_kv, start_key, end_key, - traverse_range_index, &ctx); - - if (ret != LDB_SUCCESS || ctx.error != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - TYPESAFE_QSORT(ctx.dn_list->dn, ctx.dn_list->count, - ldb_val_equal_exact_for_qsort); - - talloc_free(tmp_ctx); - - return LDB_SUCCESS; -} - -static int ldb_kv_index_dn_greater(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_parse_tree *tree, - struct dn_list *list) -{ - return ldb_kv_index_dn_ordered(module, - ldb_kv, - tree, - list, true); -} - -static int ldb_kv_index_dn_less(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_parse_tree *tree, - struct dn_list *list) -{ - return ldb_kv_index_dn_ordered(module, - ldb_kv, - tree, - list, false); -} - -/* - return a list of matching objects using a one-level index - */ -static int ldb_kv_index_dn_attr(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const char *attr, - struct ldb_dn *dn, - struct dn_list *list, - enum key_truncation *truncation) -{ - struct ldb_context *ldb; - struct ldb_dn *key; - struct ldb_val val; - int ret; - - ldb = ldb_module_get_ctx(module); - - /* work out the index key from the parent DN */ - val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(dn)); - if (val.data == NULL) { - const char *dn_str = ldb_dn_get_linearized(dn); - ldb_asprintf_errstring(ldb_module_get_ctx(module), - __location__ - ": Failed to get casefold DN " - "from: %s", - dn_str); - return LDB_ERR_OPERATIONS_ERROR; - } - val.length = strlen((char *)val.data); - key = ldb_kv_index_key(ldb, ldb_kv, attr, &val, NULL, truncation); - if (!key) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_kv_dn_list_load(module, ldb_kv, key, list, - DN_LIST_WILL_BE_READ_ONLY); - talloc_free(key); - if (ret != LDB_SUCCESS) { - return ret; - } - - if (list->count == 0) { - return LDB_ERR_NO_SUCH_OBJECT; - } - - return LDB_SUCCESS; -} - -/* - return a list of matching objects using a one-level index - */ -static int ldb_kv_index_dn_one(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - struct ldb_dn *parent_dn, - struct dn_list *list, - enum key_truncation *truncation) -{ - /* - * Ensure we do not shortcut on intersection for this list. - * We must never be lazy and return an entry not in this - * list. This allows the index for - * SCOPE_ONELEVEL to be trusted. - */ - - list->strict = true; - return ldb_kv_index_dn_attr( - module, ldb_kv, LDB_KV_IDXONE, parent_dn, list, truncation); -} - -/* - return a list of matching objects using the DN index - */ -static int ldb_kv_index_dn_base_dn(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - struct ldb_dn *base_dn, - struct dn_list *dn_list, - enum key_truncation *truncation) -{ - const struct ldb_val *guid_val = NULL; - if (ldb_kv->cache->GUID_index_attribute == NULL) { - dn_list->dn = talloc_array(dn_list, struct ldb_val, 1); - if (dn_list->dn == NULL) { - return ldb_module_oom(module); - } - dn_list->dn[0].data = discard_const_p(unsigned char, - ldb_dn_get_linearized(base_dn)); - if (dn_list->dn[0].data == NULL) { - talloc_free(dn_list->dn); - return ldb_module_oom(module); - } - dn_list->dn[0].length = strlen((char *)dn_list->dn[0].data); - dn_list->count = 1; - - return LDB_SUCCESS; - } - - if (ldb_kv->cache->GUID_index_dn_component != NULL) { - guid_val = ldb_dn_get_extended_component( - base_dn, ldb_kv->cache->GUID_index_dn_component); - } - - if (guid_val != NULL) { - dn_list->dn = talloc_array(dn_list, struct ldb_val, 1); - if (dn_list->dn == NULL) { - return ldb_module_oom(module); - } - dn_list->dn[0].data = guid_val->data; - dn_list->dn[0].length = guid_val->length; - dn_list->count = 1; - - return LDB_SUCCESS; - } - - return ldb_kv_index_dn_attr( - module, ldb_kv, LDB_KV_IDXDN, base_dn, dn_list, truncation); -} - -/* - return a list of dn's that might match a indexed search or - an error. return LDB_ERR_NO_SUCH_OBJECT for no matches, or LDB_SUCCESS for matches - */ -static int ldb_kv_index_dn(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_parse_tree *tree, - struct dn_list *list) -{ - int ret = LDB_ERR_OPERATIONS_ERROR; - - switch (tree->operation) { - case LDB_OP_AND: - ret = ldb_kv_index_dn_and(module, ldb_kv, tree, list); - break; - - case LDB_OP_OR: - ret = ldb_kv_index_dn_or(module, ldb_kv, tree, list); - break; - - case LDB_OP_NOT: - ret = ldb_kv_index_dn_not(module, ldb_kv, tree, list); - break; - - case LDB_OP_EQUALITY: - ret = ldb_kv_index_dn_leaf(module, ldb_kv, tree, list); - break; - - case LDB_OP_GREATER: - ret = ldb_kv_index_dn_greater(module, ldb_kv, tree, list); - break; - - case LDB_OP_LESS: - ret = ldb_kv_index_dn_less(module, ldb_kv, tree, list); - break; - - case LDB_OP_SUBSTRING: - case LDB_OP_PRESENT: - case LDB_OP_APPROX: - case LDB_OP_EXTENDED: - /* we can't index with fancy bitops yet */ - ret = LDB_ERR_OPERATIONS_ERROR; - break; - } - - return ret; -} - -/* - filter a candidate dn_list from an indexed search into a set of results - extracting just the given attributes -*/ -static int ldb_kv_index_filter(struct ldb_kv_private *ldb_kv, - const struct dn_list *dn_list, - struct ldb_kv_context *ac, - uint32_t *match_count, - enum key_truncation scope_one_truncation) -{ - struct ldb_context *ldb = ldb_module_get_ctx(ac->module); - struct ldb_message *msg; - struct ldb_message *filtered_msg; - unsigned int i; - unsigned int num_keys = 0; - uint8_t previous_guid_key[LDB_KV_GUID_KEY_SIZE] = {}; - struct ldb_val *keys = NULL; - - /* - * We have to allocate the key list (rather than just walk the - * caller supplied list) as the callback could change the list - * (by modifying an indexed attribute hosted in the in-memory - * index cache!) - */ - keys = talloc_array(ac, struct ldb_val, dn_list->count); - if (keys == NULL) { - return ldb_module_oom(ac->module); - } - - if (ldb_kv->cache->GUID_index_attribute != NULL) { - /* - * We speculate that the keys will be GUID based and so - * pre-fill in enough space for a GUID (avoiding a pile of - * small allocations) - */ - struct guid_tdb_key { - uint8_t guid_key[LDB_KV_GUID_KEY_SIZE]; - } *key_values = NULL; - - key_values = talloc_array(keys, - struct guid_tdb_key, - dn_list->count); - - if (key_values == NULL) { - talloc_free(keys); - return ldb_module_oom(ac->module); - } - for (i = 0; i < dn_list->count; i++) { - keys[i].data = key_values[i].guid_key; - keys[i].length = sizeof(key_values[i].guid_key); - } - } else { - for (i = 0; i < dn_list->count; i++) { - keys[i].data = NULL; - keys[i].length = 0; - } - } - - for (i = 0; i < dn_list->count; i++) { - int ret; - - ret = ldb_kv_idx_to_key( - ac->module, ldb_kv, keys, &dn_list->dn[i], &keys[num_keys]); - if (ret != LDB_SUCCESS) { - talloc_free(keys); - return ret; - } - - if (ldb_kv->cache->GUID_index_attribute != NULL) { - /* - * If we are in GUID index mode, then the dn_list is - * sorted. If we got a duplicate, forget about it, as - * otherwise we would send the same entry back more - * than once. - * - * This is needed in the truncated DN case, or if a - * duplicate was forced in via - * LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK - */ - - if (memcmp(previous_guid_key, - keys[num_keys].data, - sizeof(previous_guid_key)) == 0) { - continue; - } - - memcpy(previous_guid_key, - keys[num_keys].data, - sizeof(previous_guid_key)); - } - num_keys++; - } - - - /* - * Now that the list is a safe copy, send the callbacks - */ - for (i = 0; i < num_keys; i++) { - int ret; - bool matched; - msg = ldb_msg_new(ac); - if (!msg) { - talloc_free(keys); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = - ldb_kv_search_key(ac->module, - ldb_kv, - keys[i], - msg, - LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC | - /* - * The entry point ldb_kv_search_indexed is - * only called from the read-locked - * ldb_kv_search. - */ - LDB_UNPACK_DATA_FLAG_READ_LOCKED); - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - /* - * the record has disappeared? yes, this can - * happen if the entry is deleted by something - * operating in the callback (not another - * process, as we have a read lock) - */ - talloc_free(msg); - continue; - } - - if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) { - /* an internal error */ - talloc_free(keys); - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* - * We trust the index for LDB_SCOPE_ONELEVEL - * unless the index key has been truncated. - * - * LDB_SCOPE_BASE is not passed in by our only caller. - */ - if (ac->scope == LDB_SCOPE_ONELEVEL && - ldb_kv->cache->one_level_indexes && - scope_one_truncation == KEY_NOT_TRUNCATED) { - ret = ldb_match_message(ldb, msg, ac->tree, - ac->scope, &matched); - } else { - ret = ldb_match_msg_error(ldb, msg, - ac->tree, ac->base, - ac->scope, &matched); - } - - if (ret != LDB_SUCCESS) { - talloc_free(keys); - talloc_free(msg); - return ret; - } - if (!matched) { - talloc_free(msg); - continue; - } - - filtered_msg = ldb_msg_new(ac); - if (filtered_msg == NULL) { - TALLOC_FREE(keys); - TALLOC_FREE(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - filtered_msg->dn = talloc_steal(filtered_msg, msg->dn); - - /* filter the attributes that the user wants */ - ret = ldb_kv_filter_attrs(ldb, msg, ac->attrs, filtered_msg); - - talloc_free(msg); - - if (ret == -1) { - TALLOC_FREE(filtered_msg); - talloc_free(keys); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_module_send_entry(ac->req, filtered_msg, NULL); - if (ret != LDB_SUCCESS) { - /* Regardless of success or failure, the msg - * is the callbacks responsiblity, and should - * not be talloc_free()'ed */ - ac->request_terminated = true; - talloc_free(keys); - return ret; - } - - (*match_count)++; - } - - TALLOC_FREE(keys); - return LDB_SUCCESS; -} - -/* - sort a DN list - */ -static void ldb_kv_dn_list_sort(struct ldb_kv_private *ltdb, - struct dn_list *list) -{ - if (list->count < 2) { - return; - } - - /* We know the list is sorted when using the GUID index */ - if (ltdb->cache->GUID_index_attribute != NULL) { - return; - } - - TYPESAFE_QSORT(list->dn, list->count, - ldb_val_equal_exact_for_qsort); -} - -/* - search the database with a LDAP-like expression using indexes - returns -1 if an indexed search is not possible, in which - case the caller should call ltdb_search_full() -*/ -int ldb_kv_search_indexed(struct ldb_kv_context *ac, uint32_t *match_count) -{ - struct ldb_context *ldb = ldb_module_get_ctx(ac->module); - struct ldb_kv_private *ldb_kv = talloc_get_type( - ldb_module_get_private(ac->module), struct ldb_kv_private); - struct dn_list *dn_list; - int ret; - enum ldb_scope index_scope; - enum key_truncation scope_one_truncation = KEY_NOT_TRUNCATED; - - /* see if indexing is enabled */ - if (!ldb_kv->cache->attribute_indexes && - !ldb_kv->cache->one_level_indexes && ac->scope != LDB_SCOPE_BASE) { - /* fallback to a full search */ - return LDB_ERR_OPERATIONS_ERROR; - } - - dn_list = talloc_zero(ac, struct dn_list); - if (dn_list == NULL) { - return ldb_module_oom(ac->module); - } - - /* - * For the purposes of selecting the switch arm below, if we - * don't have a one-level index then treat it like a subtree - * search - */ - if (ac->scope == LDB_SCOPE_ONELEVEL && - !ldb_kv->cache->one_level_indexes) { - index_scope = LDB_SCOPE_SUBTREE; - } else { - index_scope = ac->scope; - } - - switch (index_scope) { - case LDB_SCOPE_BASE: - /* - * The only caller will have filtered the operation out - * so we should never get here - */ - return ldb_operr(ldb); - - case LDB_SCOPE_ONELEVEL: - - /* - * First, load all the one-level child objects (regardless of - * whether they match the search filter or not). The database - * maintains a one-level index, so retrieving this is quick. - */ - ret = ldb_kv_index_dn_one(ac->module, - ldb_kv, - ac->base, - dn_list, - &scope_one_truncation); - if (ret != LDB_SUCCESS) { - talloc_free(dn_list); - return ret; - } - - /* - * If we have too many children, running ldb_kv_index_filter() - * over all the child objects can be quite expensive. So next - * we do a separate indexed query using the search filter. - * - * This should be quick, but it may return objects that are not - * the direct one-level child objects we're interested in. - * - * We only do this in the GUID index mode, which is - * O(n*log(m)) otherwise the intersection below will - * be too costly at O(n*m). - * - * We don't set a heuristic for 'too many' but instead - * do it always and rely on the index lookup being - * fast enough in the small case. - */ - if (ldb_kv->cache->GUID_index_attribute != NULL) { - struct dn_list *indexed_search_result - = talloc_zero(ac, struct dn_list); - if (indexed_search_result == NULL) { - talloc_free(dn_list); - return ldb_module_oom(ac->module); - } - - if (!ldb_kv->cache->attribute_indexes) { - talloc_free(indexed_search_result); - talloc_free(dn_list); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* - * Try to do an indexed database search - */ - ret = ldb_kv_index_dn( - ac->module, ldb_kv, ac->tree, - indexed_search_result); - - /* - * We can stop if we're sure the object doesn't exist - */ - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - talloc_free(indexed_search_result); - talloc_free(dn_list); - return LDB_ERR_NO_SUCH_OBJECT; - } - - /* - * Once we have a successful search result, we - * intersect it with the one-level children (dn_list). - * This should give us exactly the result we're after - * (we still need to run ldb_kv_index_filter() to - * handle potential index truncation cases). - * - * The indexed search may fail because we don't support - * indexing on that type of search operation, e.g. - * matching against '*'. In which case we fall through - * and run ldb_kv_index_filter() over all the one-level - * children (which is still better than bailing out here - * and falling back to a full DB scan). - */ - if (ret == LDB_SUCCESS) { - if (!list_intersect(ldb_kv, - dn_list, - indexed_search_result)) { - talloc_free(indexed_search_result); - talloc_free(dn_list); - return LDB_ERR_OPERATIONS_ERROR; - } - } - } - break; - - case LDB_SCOPE_SUBTREE: - case LDB_SCOPE_DEFAULT: - if (!ldb_kv->cache->attribute_indexes) { - talloc_free(dn_list); - return LDB_ERR_OPERATIONS_ERROR; - } - /* - * Here we load the index for the tree. We have no - * index for the subtree. - */ - ret = ldb_kv_index_dn(ac->module, ldb_kv, ac->tree, dn_list); - if (ret != LDB_SUCCESS) { - talloc_free(dn_list); - return ret; - } - break; - } - - /* - * It is critical that this function do the re-filter even - * on things found by the index as the index can over-match - * in cases of truncation (as well as when it decides it is - * not worth further filtering) - * - * If this changes, then the index code above would need to - * pass up a flag to say if any index was truncated during - * processing as the truncation here refers only to the - * SCOPE_ONELEVEL index. - */ - ret = ldb_kv_index_filter( - ldb_kv, dn_list, ac, match_count, scope_one_truncation); - talloc_free(dn_list); - return ret; -} - -/** - * @brief Add a DN in the index list of a given attribute name/value pair - * - * This function will add the DN in the index list for the index for - * the given attribute name and value. - * - * @param[in] module A ldb_module structure - * - * @param[in] dn The string representation of the DN as it - * will be stored in the index entry - * - * @param[in] el A ldb_message_element array, one of the entry - * referred by the v_idx is the attribute name and - * value pair which will be used to construct the - * index name - * - * @param[in] v_idx The index of element in the el array to use - * - * @return An ldb error code - */ -static int ldb_kv_index_add1(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_message *msg, - struct ldb_message_element *el, - int v_idx) -{ - struct ldb_context *ldb; - struct ldb_dn *dn_key; - int ret; - const struct ldb_schema_attribute *a; - struct dn_list *list; - unsigned alloc_len; - enum key_truncation truncation = KEY_TRUNCATED; - - - ldb = ldb_module_get_ctx(module); - - list = talloc_zero(module, struct dn_list); - if (list == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - dn_key = ldb_kv_index_key( - ldb, ldb_kv, el->name, &el->values[v_idx], &a, &truncation); - if (!dn_key) { - talloc_free(list); - return LDB_ERR_OPERATIONS_ERROR; - } - /* - * Samba only maintains unique indexes on the objectSID and objectGUID - * so if a unique index key exceeds the maximum length there is a - * problem. - */ - if ((truncation == KEY_TRUNCATED) && (a != NULL && - (a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX || - (el->flags & LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX)))) { - - ldb_asprintf_errstring( - ldb, - __location__ ": unique index key on %s in %s, " - "exceeds maximum key length of %u (encoded).", - el->name, - ldb_dn_get_linearized(msg->dn), - ldb_kv->max_key_length); - talloc_free(list); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - talloc_steal(list, dn_key); - - ret = ldb_kv_dn_list_load(module, ldb_kv, dn_key, list, - DN_LIST_MUTABLE); - if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_OBJECT) { - talloc_free(list); - return ret; - } - - /* - * Check for duplicates in the @IDXDN DN -> GUID record - * - * This is very normal, it just means a duplicate DN creation - * was attempted, so don't set the error string or print scary - * messages. - */ - if (list->count > 0 && - ldb_attr_cmp(el->name, LDB_KV_IDXDN) == 0 && - truncation == KEY_NOT_TRUNCATED) { - - talloc_free(list); - return LDB_ERR_CONSTRAINT_VIOLATION; - - } else if (list->count > 0 - && ldb_attr_cmp(el->name, LDB_KV_IDXDN) == 0) { - - /* - * At least one existing entry in the DN->GUID index, which - * arises when the DN indexes have been truncated - * - * So need to pull the DN's to check if it's really a duplicate - */ - unsigned int i; - for (i=0; i < list->count; i++) { - uint8_t guid_key[LDB_KV_GUID_KEY_SIZE]; - struct ldb_val key = { - .data = guid_key, - .length = sizeof(guid_key) - }; - const int flags = LDB_UNPACK_DATA_FLAG_NO_ATTRS; - struct ldb_message *rec = ldb_msg_new(ldb); - if (rec == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_kv_idx_to_key( - module, ldb_kv, ldb, &list->dn[i], &key); - if (ret != LDB_SUCCESS) { - TALLOC_FREE(list); - TALLOC_FREE(rec); - return ret; - } - - ret = - ldb_kv_search_key(module, ldb_kv, key, rec, flags); - if (key.data != guid_key) { - TALLOC_FREE(key.data); - } - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - /* - * the record has disappeared? - * yes, this can happen - */ - talloc_free(rec); - continue; - } - - if (ret != LDB_SUCCESS) { - /* an internal error */ - TALLOC_FREE(rec); - TALLOC_FREE(list); - return LDB_ERR_OPERATIONS_ERROR; - } - /* - * The DN we are trying to add to the DB and index - * is already here, so we must deny the addition - */ - if (ldb_dn_compare(msg->dn, rec->dn) == 0) { - TALLOC_FREE(rec); - TALLOC_FREE(list); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - } - } - - /* - * Check for duplicates in unique indexes - * - * We don't need to do a loop test like the @IDXDN case - * above as we have a ban on long unique index values - * at the start of this function. - */ - if (list->count > 0 && - ((a != NULL - && (a->flags & LDB_ATTR_FLAG_UNIQUE_INDEX || - (el->flags & LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX))))) { - /* - * We do not want to print info about a possibly - * confidential DN that the conflict was with in the - * user-visible error string - */ - - if (ldb_kv->cache->GUID_index_attribute == NULL) { - ldb_debug(ldb, LDB_DEBUG_WARNING, - __location__ - ": unique index violation on %s in %s, " - "conflicts with %*.*s in %s", - el->name, ldb_dn_get_linearized(msg->dn), - (int)list->dn[0].length, - (int)list->dn[0].length, - list->dn[0].data, - ldb_dn_get_linearized(dn_key)); - } else { - /* This can't fail, gives a default at worst */ - const struct ldb_schema_attribute *attr = - ldb_schema_attribute_by_name( - ldb, ldb_kv->cache->GUID_index_attribute); - struct ldb_val v; - ret = attr->syntax->ldif_write_fn(ldb, list, - &list->dn[0], &v); - if (ret == LDB_SUCCESS) { - ldb_debug(ldb, - LDB_DEBUG_WARNING, - __location__ - ": unique index violation on %s in " - "%s, conflicts with %s %*.*s in %s", - el->name, - ldb_dn_get_linearized(msg->dn), - ldb_kv->cache->GUID_index_attribute, - (int)v.length, - (int)v.length, - v.data, - ldb_dn_get_linearized(dn_key)); - } - } - ldb_asprintf_errstring(ldb, - __location__ ": unique index violation " - "on %s in %s", - el->name, - ldb_dn_get_linearized(msg->dn)); - talloc_free(list); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - - /* overallocate the list a bit, to reduce the number of - * realloc trigered copies */ - alloc_len = ((list->count+1)+7) & ~7; - list->dn = talloc_realloc(list, list->dn, struct ldb_val, alloc_len); - if (list->dn == NULL) { - talloc_free(list); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (ldb_kv->cache->GUID_index_attribute == NULL) { - const char *dn_str = ldb_dn_get_linearized(msg->dn); - list->dn[list->count].data - = (uint8_t *)talloc_strdup(list->dn, dn_str); - if (list->dn[list->count].data == NULL) { - talloc_free(list); - return LDB_ERR_OPERATIONS_ERROR; - } - list->dn[list->count].length = strlen(dn_str); - } else { - const struct ldb_val *key_val; - struct ldb_val *exact = NULL, *next = NULL; - key_val = ldb_msg_find_ldb_val( - msg, ldb_kv->cache->GUID_index_attribute); - if (key_val == NULL) { - talloc_free(list); - return ldb_module_operr(module); - } - - if (key_val->length != LDB_KV_GUID_SIZE) { - talloc_free(list); - return ldb_module_operr(module); - } - - BINARY_ARRAY_SEARCH_GTE(list->dn, list->count, - *key_val, ldb_val_equal_exact_ordered, - exact, next); - - /* - * Give a warning rather than fail, this could be a - * duplicate value in the record allowed by a caller - * forcing in the value with - * LDB_FLAG_INTERNAL_DISABLE_SINGLE_VALUE_CHECK - */ - if (exact != NULL && truncation == KEY_NOT_TRUNCATED) { - /* This can't fail, gives a default at worst */ - const struct ldb_schema_attribute *attr = - ldb_schema_attribute_by_name( - ldb, ldb_kv->cache->GUID_index_attribute); - struct ldb_val v; - ret = attr->syntax->ldif_write_fn(ldb, list, - exact, &v); - if (ret == LDB_SUCCESS) { - ldb_debug(ldb, - LDB_DEBUG_WARNING, - __location__ - ": duplicate attribute value in %s " - "for index on %s, " - "duplicate of %s %*.*s in %s", - ldb_dn_get_linearized(msg->dn), - el->name, - ldb_kv->cache->GUID_index_attribute, - (int)v.length, - (int)v.length, - v.data, - ldb_dn_get_linearized(dn_key)); - } - } - - if (next == NULL) { - next = &list->dn[list->count]; - } else { - memmove(&next[1], next, - sizeof(*next) * (list->count - (next - list->dn))); - } - *next = ldb_val_dup(list->dn, key_val); - if (next->data == NULL) { - talloc_free(list); - return ldb_module_operr(module); - } - } - list->count++; - - ret = ldb_kv_dn_list_store(module, dn_key, list); - - talloc_free(list); - - return ret; -} - -/* - add index entries for one elements in a message - */ -static int ldb_kv_index_add_el(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_message *msg, - struct ldb_message_element *el) -{ - unsigned int i; - for (i = 0; i < el->num_values; i++) { - int ret = ldb_kv_index_add1(module, ldb_kv, msg, el, i); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - return LDB_SUCCESS; -} - -/* - add index entries for all elements in a message - */ -static int ldb_kv_index_add_all(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_message *msg) -{ - struct ldb_message_element *elements = msg->elements; - unsigned int i; - const char *dn_str; - int ret; - - if (ldb_dn_is_special(msg->dn)) { - return LDB_SUCCESS; - } - - dn_str = ldb_dn_get_linearized(msg->dn); - if (dn_str == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_kv_write_index_dn_guid(module, msg, 1); - if (ret != LDB_SUCCESS) { - return ret; - } - - if (!ldb_kv->cache->attribute_indexes) { - /* no indexed fields */ - return LDB_SUCCESS; - } - - for (i = 0; i < msg->num_elements; i++) { - if (!ldb_kv_is_indexed(module, ldb_kv, elements[i].name)) { - continue; - } - ret = ldb_kv_index_add_el(module, ldb_kv, msg, &elements[i]); - if (ret != LDB_SUCCESS) { - struct ldb_context *ldb = ldb_module_get_ctx(module); - ldb_asprintf_errstring(ldb, - __location__ ": Failed to re-index %s in %s - %s", - elements[i].name, dn_str, - ldb_errstring(ldb)); - return ret; - } - } - - return LDB_SUCCESS; -} - - -/* - insert a DN index for a message -*/ -static int ldb_kv_modify_index_dn(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_message *msg, - struct ldb_dn *dn, - const char *index, - int add) -{ - struct ldb_message_element el; - struct ldb_val val; - int ret; - - val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(dn)); - if (val.data == NULL) { - const char *dn_str = ldb_dn_get_linearized(dn); - ldb_asprintf_errstring(ldb_module_get_ctx(module), - __location__ ": Failed to modify %s " - "against %s in %s: failed " - "to get casefold DN", - index, - ldb_kv->cache->GUID_index_attribute, - dn_str); - return LDB_ERR_OPERATIONS_ERROR; - } - - val.length = strlen((char *)val.data); - el.name = index; - el.values = &val; - el.num_values = 1; - - if (add) { - ret = ldb_kv_index_add1(module, ldb_kv, msg, &el, 0); - } else { /* delete */ - ret = ldb_kv_index_del_value(module, ldb_kv, msg, &el, 0); - } - - if (ret != LDB_SUCCESS) { - struct ldb_context *ldb = ldb_module_get_ctx(module); - const char *dn_str = ldb_dn_get_linearized(dn); - ldb_asprintf_errstring(ldb, - __location__ ": Failed to modify %s " - "against %s in %s - %s", - index, - ldb_kv->cache->GUID_index_attribute, - dn_str, - ldb_errstring(ldb)); - return ret; - } - return ret; -} - -/* - insert a one level index for a message -*/ -static int ldb_kv_index_onelevel(struct ldb_module *module, - const struct ldb_message *msg, - int add) -{ - struct ldb_kv_private *ldb_kv = talloc_get_type( - ldb_module_get_private(module), struct ldb_kv_private); - struct ldb_dn *pdn; - int ret; - - /* We index for ONE Level only if requested */ - if (!ldb_kv->cache->one_level_indexes) { - return LDB_SUCCESS; - } - - pdn = ldb_dn_get_parent(module, msg->dn); - if (pdn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - ret = - ldb_kv_modify_index_dn(module, ldb_kv, msg, pdn, LDB_KV_IDXONE, add); - - talloc_free(pdn); - - return ret; -} - -/* - insert a one level index for a message -*/ -static int ldb_kv_write_index_dn_guid(struct ldb_module *module, - const struct ldb_message *msg, - int add) -{ - int ret; - struct ldb_kv_private *ldb_kv = talloc_get_type( - ldb_module_get_private(module), struct ldb_kv_private); - - /* We index for DN only if using a GUID index */ - if (ldb_kv->cache->GUID_index_attribute == NULL) { - return LDB_SUCCESS; - } - - ret = ldb_kv_modify_index_dn( - module, ldb_kv, msg, msg->dn, LDB_KV_IDXDN, add); - - if (ret == LDB_ERR_CONSTRAINT_VIOLATION) { - ldb_asprintf_errstring(ldb_module_get_ctx(module), - "Entry %s already exists", - ldb_dn_get_linearized(msg->dn)); - ret = LDB_ERR_ENTRY_ALREADY_EXISTS; - } - return ret; -} - -/* - add the index entries for a new element in a record - The caller guarantees that these element values are not yet indexed -*/ -int ldb_kv_index_add_element(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_message *msg, - struct ldb_message_element *el) -{ - if (ldb_dn_is_special(msg->dn)) { - return LDB_SUCCESS; - } - if (!ldb_kv_is_indexed(module, ldb_kv, el->name)) { - return LDB_SUCCESS; - } - return ldb_kv_index_add_el(module, ldb_kv, msg, el); -} - -/* - add the index entries for a new record -*/ -int ldb_kv_index_add_new(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_message *msg) -{ - int ret; - - if (ldb_dn_is_special(msg->dn)) { - return LDB_SUCCESS; - } - - ret = ldb_kv_index_add_all(module, ldb_kv, msg); - if (ret != LDB_SUCCESS) { - /* - * Because we can't trust the caller to be doing - * transactions properly, clean up any index for this - * entry rather than relying on a transaction - * cleanup - */ - - ldb_kv_index_delete(module, msg); - return ret; - } - - ret = ldb_kv_index_onelevel(module, msg, 1); - if (ret != LDB_SUCCESS) { - /* - * Because we can't trust the caller to be doing - * transactions properly, clean up any index for this - * entry rather than relying on a transaction - * cleanup - */ - ldb_kv_index_delete(module, msg); - return ret; - } - return ret; -} - - -/* - delete an index entry for one message element -*/ -int ldb_kv_index_del_value(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_message *msg, - struct ldb_message_element *el, - unsigned int v_idx) -{ - struct ldb_context *ldb; - struct ldb_dn *dn_key; - const char *dn_str; - int ret, i; - unsigned int j; - struct dn_list *list; - struct ldb_dn *dn = msg->dn; - enum key_truncation truncation = KEY_NOT_TRUNCATED; - - ldb = ldb_module_get_ctx(module); - - dn_str = ldb_dn_get_linearized(dn); - if (dn_str == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (dn_str[0] == '@') { - return LDB_SUCCESS; - } - - dn_key = ldb_kv_index_key( - ldb, ldb_kv, el->name, &el->values[v_idx], NULL, &truncation); - /* - * We ignore key truncation in ltdb_index_add1() so - * match that by ignoring it here as well - * - * Multiple values are legitimate and accepted - */ - if (!dn_key) { - return LDB_ERR_OPERATIONS_ERROR; - } - - list = talloc_zero(dn_key, struct dn_list); - if (list == NULL) { - talloc_free(dn_key); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_kv_dn_list_load(module, ldb_kv, dn_key, list, - DN_LIST_MUTABLE); - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - /* it wasn't indexed. Did we have an earlier error? If we did then - its gone now */ - talloc_free(dn_key); - return LDB_SUCCESS; - } - - if (ret != LDB_SUCCESS) { - talloc_free(dn_key); - return ret; - } - - /* - * Find one of the values matching this message to remove - */ - i = ldb_kv_dn_list_find_msg(ldb_kv, list, msg); - if (i == -1) { - /* nothing to delete */ - talloc_free(dn_key); - return LDB_SUCCESS; - } - - j = (unsigned int) i; - if (j != list->count - 1) { - memmove(&list->dn[j], &list->dn[j+1], sizeof(list->dn[0])*(list->count - (j+1))); - } - list->count--; - if (list->count == 0) { - talloc_free(list->dn); - list->dn = NULL; - } else { - list->dn = talloc_realloc(list, list->dn, struct ldb_val, list->count); - } - - ret = ldb_kv_dn_list_store(module, dn_key, list); - - talloc_free(dn_key); - - return ret; -} - -/* - delete the index entries for a element - return -1 on failure -*/ -int ldb_kv_index_del_element(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_message *msg, - struct ldb_message_element *el) -{ - const char *dn_str; - int ret; - unsigned int i; - - if (!ldb_kv->cache->attribute_indexes) { - /* no indexed fields */ - return LDB_SUCCESS; - } - - dn_str = ldb_dn_get_linearized(msg->dn); - if (dn_str == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (dn_str[0] == '@') { - return LDB_SUCCESS; - } - - if (!ldb_kv_is_indexed(module, ldb_kv, el->name)) { - return LDB_SUCCESS; - } - for (i = 0; i < el->num_values; i++) { - ret = ldb_kv_index_del_value(module, ldb_kv, msg, el, i); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - return LDB_SUCCESS; -} - -/* - delete the index entries for a record - return -1 on failure -*/ -int ldb_kv_index_delete(struct ldb_module *module, - const struct ldb_message *msg) -{ - struct ldb_kv_private *ldb_kv = talloc_get_type( - ldb_module_get_private(module), struct ldb_kv_private); - int ret; - unsigned int i; - - if (ldb_dn_is_special(msg->dn)) { - return LDB_SUCCESS; - } - - ret = ldb_kv_index_onelevel(module, msg, 0); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_kv_write_index_dn_guid(module, msg, 0); - if (ret != LDB_SUCCESS) { - return ret; - } - - if (!ldb_kv->cache->attribute_indexes) { - /* no indexed fields */ - return LDB_SUCCESS; - } - - for (i = 0; i < msg->num_elements; i++) { - ret = ldb_kv_index_del_element( - module, ldb_kv, msg, &msg->elements[i]); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - return LDB_SUCCESS; -} - - -/* - traversal function that deletes all @INDEX records in the in-memory - TDB. - - This does not touch the actual DB, that is done at transaction - commit, which in turn greatly reduces DB churn as we will likely - be able to do a direct update into the old record. -*/ -static int delete_index(struct ldb_kv_private *ldb_kv, - struct ldb_val key, - _UNUSED_ struct ldb_val data, - void *state) -{ - struct ldb_module *module = state; - const char *dnstr = "DN=" LDB_KV_INDEX ":"; - struct dn_list list; - struct ldb_dn *dn; - struct ldb_val v; - int ret; - - if (strncmp((char *)key.data, dnstr, strlen(dnstr)) != 0) { - return 0; - } - /* we need to put a empty list in the internal tdb for this - * index entry */ - list.dn = NULL; - list.count = 0; - - /* the offset of 3 is to remove the DN= prefix. */ - v.data = key.data + 3; - v.length = strnlen((char *)key.data, key.length) - 3; - - dn = ldb_dn_from_ldb_val(ldb_kv, ldb_module_get_ctx(module), &v); - - /* - * This does not actually touch the DB quite yet, just - * the in-memory index cache - */ - ret = ldb_kv_dn_list_store(module, dn, &list); - if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb_module_get_ctx(module), - "Unable to store null index for %s\n", - ldb_dn_get_linearized(dn)); - talloc_free(dn); - return -1; - } - talloc_free(dn); - return 0; -} - -/* - traversal function that adds @INDEX records during a re index TODO wrong comment -*/ -static int re_key(struct ldb_kv_private *ldb_kv, - struct ldb_val key, - struct ldb_val val, - void *state) -{ - struct ldb_context *ldb; - struct ldb_kv_reindex_context *ctx = - (struct ldb_kv_reindex_context *)state; - struct ldb_module *module = ldb_kv->module; - struct ldb_message *msg; - int ret; - struct ldb_val key2; - bool is_record; - - ldb = ldb_module_get_ctx(module); - - is_record = ldb_kv_key_is_normal_record(key); - if (is_record == false) { - return 0; - } - - msg = ldb_msg_new(module); - if (msg == NULL) { - return -1; - } - - ret = ldb_unpack_data(ldb, &val, msg); - if (ret != 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n", - ldb_dn_get_linearized(msg->dn)); - ctx->error = ret; - talloc_free(msg); - return -1; - } - - if (msg->dn == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Refusing to re-index as GUID " - "key %*.*s with no DN\n", - (int)key.length, (int)key.length, - (char *)key.data); - talloc_free(msg); - return -1; - } - - /* check if the DN key has changed, perhaps due to the case - insensitivity of an element changing, or a change from DN - to GUID keys */ - key2 = ldb_kv_key_msg(module, msg, msg); - if (key2.data == NULL) { - /* probably a corrupt record ... darn */ - ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s", - ldb_dn_get_linearized(msg->dn)); - talloc_free(msg); - return 0; - } - if (key.length != key2.length || - (memcmp(key.data, key2.data, key.length) != 0)) { - ldb_kv->kv_ops->update_in_iterate( - ldb_kv, key, key2, val, ctx); - } - talloc_free(key2.data); - - talloc_free(msg); - - ctx->count++; - if (ctx->count % 10000 == 0) { - ldb_debug(ldb, LDB_DEBUG_WARNING, - "Reindexing: re-keyed %u records so far", - ctx->count); - } - - return 0; -} - -/* - traversal function that adds @INDEX records during a re index -*/ -static int re_index(struct ldb_kv_private *ldb_kv, - struct ldb_val key, - struct ldb_val val, - void *state) -{ - struct ldb_context *ldb; - struct ldb_kv_reindex_context *ctx = - (struct ldb_kv_reindex_context *)state; - struct ldb_module *module = ldb_kv->module; - struct ldb_message *msg; - int ret; - bool is_record; - - ldb = ldb_module_get_ctx(module); - - is_record = ldb_kv_key_is_normal_record(key); - if (is_record == false) { - return 0; - } - - msg = ldb_msg_new(module); - if (msg == NULL) { - return -1; - } - - ret = ldb_unpack_data(ldb, &val, msg); - if (ret != 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %s\n", - ldb_dn_get_linearized(msg->dn)); - ctx->error = ret; - talloc_free(msg); - return -1; - } - - if (msg->dn == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Refusing to re-index as GUID " - "key %*.*s with no DN\n", - (int)key.length, (int)key.length, - (char *)key.data); - talloc_free(msg); - return -1; - } - - ret = ldb_kv_index_onelevel(module, msg, 1); - if (ret != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Adding special ONE LEVEL index failed (%s)!", - ldb_dn_get_linearized(msg->dn)); - talloc_free(msg); - return -1; - } - - ret = ldb_kv_index_add_all(module, ldb_kv, msg); - - if (ret != LDB_SUCCESS) { - ctx->error = ret; - talloc_free(msg); - return -1; - } - - talloc_free(msg); - - ctx->count++; - if (ctx->count % 10000 == 0) { - ldb_debug(ldb, LDB_DEBUG_WARNING, - "Reindexing: re-indexed %u records so far", - ctx->count); - } - - return 0; -} - -/* - * Convert the 4-byte pack format version to a number that's slightly - * more intelligible to a user e.g. version 0, 1, 2, etc. - */ -static uint32_t displayable_pack_version(uint32_t version) { - if (version < LDB_PACKING_FORMAT_NODN) { - return version; /* unknown - can't convert */ - } - - return (version - LDB_PACKING_FORMAT_NODN); -} - -static int re_pack(struct ldb_kv_private *ldb_kv, - _UNUSED_ struct ldb_val key, - struct ldb_val val, - void *state) -{ - struct ldb_context *ldb; - struct ldb_message *msg; - struct ldb_module *module = ldb_kv->module; - struct ldb_kv_repack_context *ctx = - (struct ldb_kv_repack_context *)state; - int ret; - - ldb = ldb_module_get_ctx(module); - - msg = ldb_msg_new(module); - if (msg == NULL) { - return -1; - } - - ret = ldb_unpack_data(ldb, &val, msg); - if (ret != 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Repack: unpack failed: %s\n", - ldb_dn_get_linearized(msg->dn)); - ctx->error = ret; - talloc_free(msg); - return -1; - } - - ret = ldb_kv_store(module, msg, TDB_MODIFY); - if (ret != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Repack: store failed: %s\n", - ldb_dn_get_linearized(msg->dn)); - ctx->error = ret; - talloc_free(msg); - return -1; - } - - /* - * Warn the user that we're repacking the first time we see a normal - * record. This means we never warn if we're repacking a database with - * only @ records. This is because during database initialisation, - * we might repack as initial settings are written out, and we don't - * want to spam the log. - */ - if ((!ctx->normal_record_seen) && (!ldb_dn_is_special(msg->dn))) { - ldb_debug(ldb, LDB_DEBUG_ALWAYS_LOG, - "Repacking database from v%u to v%u format " - "(first record %s)", - displayable_pack_version(ctx->old_version), - displayable_pack_version(ldb_kv->pack_format_version), - ldb_dn_get_linearized(msg->dn)); - ctx->normal_record_seen = true; - } - - ctx->count++; - if (ctx->count % 10000 == 0) { - ldb_debug(ldb, LDB_DEBUG_WARNING, - "Repack: re-packed %u records so far", - ctx->count); - } - - talloc_free(msg); - return 0; -} - -int ldb_kv_repack(struct ldb_module *module) -{ - struct ldb_kv_private *ldb_kv = talloc_get_type( - ldb_module_get_private(module), struct ldb_kv_private); - struct ldb_context *ldb = ldb_module_get_ctx(module); - struct ldb_kv_repack_context ctx; - int ret; - - ctx.old_version = ldb_kv->pack_format_version; - ctx.count = 0; - ctx.error = LDB_SUCCESS; - ctx.normal_record_seen = false; - - ldb_kv->pack_format_version = ldb_kv->target_pack_format_version; - - /* Iterate all database records and repack them in the new format */ - ret = ldb_kv->kv_ops->iterate(ldb_kv, re_pack, &ctx); - if (ret < 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Repack traverse failed: %s", - ldb_errstring(ldb)); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (ctx.error != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Repack failed: %s", - ldb_errstring(ldb)); - return ctx.error; - } - - return LDB_SUCCESS; -} - -/* - force a complete reindex of the database -*/ -int ldb_kv_reindex(struct ldb_module *module) -{ - struct ldb_kv_private *ldb_kv = talloc_get_type( - ldb_module_get_private(module), struct ldb_kv_private); - int ret; - struct ldb_kv_reindex_context ctx; - size_t index_cache_size = 0; - - /* - * Only triggered after a modification, but make clear we do - * not re-index a read-only DB - */ - if (ldb_kv->read_only) { - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - if (ldb_kv_cache_reload(module) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* - * Ensure we read (and so remove) the entries from the real - * DB, no values stored so far are any use as we want to do a - * re-index - */ - ldb_kv_index_transaction_cancel(module); - if (ldb_kv->nested_idx_ptr != NULL) { - ldb_kv_index_sub_transaction_cancel(ldb_kv); - } - - /* - * Calculate the size of the index cache needed for - * the re-index. If specified always use the - * ldb_kv->index_transaction_cache_size otherwise use the maximum - * of the size estimate or the DEFAULT_INDEX_CACHE_SIZE - */ - if (ldb_kv->index_transaction_cache_size > 0) { - index_cache_size = ldb_kv->index_transaction_cache_size; - } else { - index_cache_size = ldb_kv->kv_ops->get_size(ldb_kv); - if (index_cache_size < DEFAULT_INDEX_CACHE_SIZE) { - index_cache_size = DEFAULT_INDEX_CACHE_SIZE; - } - } - - /* - * Note that we don't start an index sub transaction for re-indexing - */ - ret = ldb_kv_index_transaction_start(module, index_cache_size); - if (ret != LDB_SUCCESS) { - return ret; - } - - /* first traverse the database deleting any @INDEX records by - * putting NULL entries in the in-memory tdb - */ - ret = ldb_kv->kv_ops->iterate(ldb_kv, delete_index, module); - if (ret < 0) { - struct ldb_context *ldb = ldb_module_get_ctx(module); - ldb_asprintf_errstring(ldb, "index deletion traverse failed: %s", - ldb_errstring(ldb)); - return LDB_ERR_OPERATIONS_ERROR; - } - - ctx.error = 0; - ctx.count = 0; - - ret = ldb_kv->kv_ops->iterate(ldb_kv, re_key, &ctx); - if (ret < 0) { - struct ldb_context *ldb = ldb_module_get_ctx(module); - ldb_asprintf_errstring(ldb, "key correction traverse failed: %s", - ldb_errstring(ldb)); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (ctx.error != LDB_SUCCESS) { - struct ldb_context *ldb = ldb_module_get_ctx(module); - ldb_asprintf_errstring(ldb, "reindexing failed: %s", ldb_errstring(ldb)); - return ctx.error; - } - - ctx.error = 0; - ctx.count = 0; - - /* now traverse adding any indexes for normal LDB records */ - ret = ldb_kv->kv_ops->iterate(ldb_kv, re_index, &ctx); - if (ret < 0) { - struct ldb_context *ldb = ldb_module_get_ctx(module); - ldb_asprintf_errstring(ldb, "reindexing traverse failed: %s", - ldb_errstring(ldb)); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (ctx.error != LDB_SUCCESS) { - struct ldb_context *ldb = ldb_module_get_ctx(module); - ldb_asprintf_errstring(ldb, "reindexing failed: %s", ldb_errstring(ldb)); - return ctx.error; - } - - if (ctx.count > 10000) { - ldb_debug(ldb_module_get_ctx(module), - LDB_DEBUG_WARNING, - "Reindexing: re_index successful on %s, " - "final index write-out will be in transaction commit", - ldb_kv->kv_ops->name(ldb_kv)); - } - return LDB_SUCCESS; -} - -/* - * Copy the contents of the nested transaction index cache record to the - * transaction index cache. - * - * During this 'commit' of the subtransaction to the main transaction - * (cache), care must be taken to free any existing index at the top - * level because otherwise we would leak memory. - */ -static int ldb_kv_sub_transaction_traverse( - struct tdb_context *tdb, - TDB_DATA key, - TDB_DATA data, - void *state) -{ - struct ldb_module *module = state; - struct ldb_kv_private *ldb_kv = talloc_get_type( - ldb_module_get_private(module), struct ldb_kv_private); - TDB_DATA rec = {0}; - struct dn_list *index_in_subtransaction = NULL; - struct dn_list *index_in_top_level = NULL; - int ret = 0; - - /* - * This unwraps the pointer in the DB into a pointer in - * memory, we are abusing TDB as a hash map, not a linearised - * database store - */ - index_in_subtransaction = ldb_kv_index_idxptr(module, data); - if (index_in_subtransaction == NULL) { - ldb_kv->idxptr->error = LDB_ERR_OPERATIONS_ERROR; - return -1; - } - - /* - * Do we already have an entry in the primary transaction cache - * If so free it's dn_list and replace it with the dn_list from - * the secondary cache - * - * The TDB and so the fetched rec contains NO DATA, just a - * pointer to data held in memory. - */ - rec = tdb_fetch(ldb_kv->idxptr->itdb, key); - if (rec.dptr != NULL) { - index_in_top_level = ldb_kv_index_idxptr(module, rec); - free(rec.dptr); - if (index_in_top_level == NULL) { - abort(); - } - /* - * We had this key at the top level. However we made a copy - * at the sub-transaction level so that we could possibly - * roll back. We have to free the top level index memory - * otherwise we would leak - */ - if (index_in_top_level->count > 0) { - TALLOC_FREE(index_in_top_level->dn); - } - index_in_top_level->dn - = talloc_steal(index_in_top_level, - index_in_subtransaction->dn); - index_in_top_level->count = index_in_subtransaction->count; - return 0; - } - - index_in_top_level = talloc(ldb_kv->idxptr, struct dn_list); - if (index_in_top_level == NULL) { - ldb_kv->idxptr->error = LDB_ERR_OPERATIONS_ERROR; - return -1; - } - index_in_top_level->dn - = talloc_steal(index_in_top_level, - index_in_subtransaction->dn); - index_in_top_level->count = index_in_subtransaction->count; - - rec.dptr = (uint8_t *)&index_in_top_level; - rec.dsize = sizeof(void *); - - - /* - * This is not a store into the main DB, but into an in-memory - * TDB, so we don't need a guard on ltdb->read_only - */ - ret = tdb_store(ldb_kv->idxptr->itdb, key, rec, TDB_INSERT); - if (ret != 0) { - ldb_kv->idxptr->error = ltdb_err_map( - tdb_error(ldb_kv->idxptr->itdb)); - return -1; - } - return 0; -} - -/* - * Initialise the index cache for a sub transaction. - */ -int ldb_kv_index_sub_transaction_start(struct ldb_kv_private *ldb_kv) -{ - ldb_kv->nested_idx_ptr = talloc_zero(ldb_kv, struct ldb_kv_idxptr); - if (ldb_kv->nested_idx_ptr == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* - * We use a tiny hash size for the sub-database (11). - * - * The sub-transaction is only for one record at a time, we - * would use a linked list but that would make the code even - * more complex when manipulating the index, as it would have - * to know if we were in a nested transaction (normal - * operations) or the top one (a reindex). - */ - ldb_kv->nested_idx_ptr->itdb = - tdb_open(NULL, 11, TDB_INTERNAL, O_RDWR, 0); - if (ldb_kv->nested_idx_ptr->itdb == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - return LDB_SUCCESS; -} - -/* - * Clear the contents of the nested transaction index cache when the nested - * transaction is cancelled. - */ -int ldb_kv_index_sub_transaction_cancel(struct ldb_kv_private *ldb_kv) -{ - if (ldb_kv->nested_idx_ptr != NULL) { - tdb_close(ldb_kv->nested_idx_ptr->itdb); - TALLOC_FREE(ldb_kv->nested_idx_ptr); - } - return LDB_SUCCESS; -} - -/* - * Commit a nested transaction, - * Copy the contents of the nested transaction index cache to the - * transaction index cache. - */ -int ldb_kv_index_sub_transaction_commit(struct ldb_kv_private *ldb_kv) -{ - int ret = 0; - - if (ldb_kv->nested_idx_ptr == NULL) { - return LDB_SUCCESS; - } - if (ldb_kv->nested_idx_ptr->itdb == NULL) { - return LDB_SUCCESS; - } - tdb_traverse( - ldb_kv->nested_idx_ptr->itdb, - ldb_kv_sub_transaction_traverse, - ldb_kv->module); - tdb_close(ldb_kv->nested_idx_ptr->itdb); - ldb_kv->nested_idx_ptr->itdb = NULL; - - ret = ldb_kv->nested_idx_ptr->error; - if (ret != LDB_SUCCESS) { - struct ldb_context *ldb = ldb_module_get_ctx(ldb_kv->module); - if (!ldb_errstring(ldb)) { - ldb_set_errstring(ldb, ldb_strerror(ret)); - } - ldb_asprintf_errstring( - ldb, - __location__": Failed to update index records in " - "sub transaction commit: %s", - ldb_errstring(ldb)); - } - TALLOC_FREE(ldb_kv->nested_idx_ptr); - return ret; -} diff --git a/ldb-2.0.8/ldb_key_value/ldb_kv_search.c b/ldb-2.0.8/ldb_key_value/ldb_kv_search.c deleted file mode 100644 index f2d9619..0000000 --- a/ldb-2.0.8/ldb_key_value/ldb_kv_search.c +++ /dev/null @@ -1,707 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb search functions - * - * Description: functions to search ldb+tdb databases - * - * Author: Andrew Tridgell - */ - -#include "ldb_kv.h" -#include "ldb_private.h" -#include "lib/util/attr.h" -/* - search the database for a single simple dn. - return LDB_ERR_NO_SUCH_OBJECT on record-not-found - and LDB_SUCCESS on success -*/ -int ldb_kv_search_base(struct ldb_module *module, - TALLOC_CTX *mem_ctx, - struct ldb_dn *dn, - struct ldb_dn **ret_dn) -{ - int exists; - int ret; - struct ldb_message *msg = NULL; - - if (ldb_dn_is_null(dn)) { - return LDB_ERR_NO_SUCH_OBJECT; - } - - /* - * We can't use tdb_exists() directly on a key when the TDB - * key is the GUID one, not the DN based one. So we just do a - * normal search and avoid most of the allocation with the - * LDB_UNPACK_DATA_FLAG_NO_ATTRS flag - */ - msg = ldb_msg_new(module); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_kv_search_dn1(module, dn, msg, LDB_UNPACK_DATA_FLAG_NO_ATTRS); - if (ret == LDB_SUCCESS) { - const char *dn_linearized - = ldb_dn_get_linearized(dn); - const char *msg_dn_linearized - = ldb_dn_get_linearized(msg->dn); - - if (strcmp(dn_linearized, msg_dn_linearized) == 0) { - /* - * Re-use the full incoming DN for - * subtree checks - */ - *ret_dn = dn; - } else { - /* - * Use the string DN from the unpack, so that - * we have a case-exact match of the base - */ - *ret_dn = talloc_steal(mem_ctx, msg->dn); - } - exists = true; - } else if (ret == LDB_ERR_NO_SUCH_OBJECT) { - exists = false; - } else { - talloc_free(msg); - return ret; - } - talloc_free(msg); - if (exists) { - return LDB_SUCCESS; - } - return LDB_ERR_NO_SUCH_OBJECT; -} - -struct ldb_kv_parse_data_unpack_ctx { - struct ldb_message *msg; - struct ldb_module *module; - struct ldb_kv_private *ldb_kv; - unsigned int unpack_flags; -}; - -static int ldb_kv_parse_data_unpack(struct ldb_val key, - struct ldb_val data, - void *private_data) -{ - struct ldb_kv_parse_data_unpack_ctx *ctx = private_data; - int ret; - struct ldb_context *ldb = ldb_module_get_ctx(ctx->module); - struct ldb_val data_parse = data; - - struct ldb_kv_private *ldb_kv = ctx->ldb_kv; - - if ((ldb_kv->kv_ops->options & LDB_KV_OPTION_STABLE_READ_LOCK) && - (ctx->unpack_flags & LDB_UNPACK_DATA_FLAG_READ_LOCKED) && - !ldb_kv->kv_ops->transaction_active(ldb_kv)) { - /* - * In the case where no transactions are active and - * we're in a read-lock, we can point directly into - * database memory. - * - * The database can't be changed underneath us and we - * will duplicate this data in the call to filter. - * - * This is seen in: - * - ldb_kv_index_filter - * - ldb_kv_search_and_return_base - */ - } else { - /* - * In every other case, since unpack doesn't memdup, we need - * to at least do a memdup on the whole data buffer as that - * may change later and the caller needs a stable result. - * - * During transactions, pointers could change and in - * TDB, there just aren't the same guarantees. - */ - data_parse.data = talloc_memdup(ctx->msg, - data.data, - data.length); - if (data_parse.data == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Unable to allocate data(%d) for %*.*s\n", - (int)data.length, - (int)key.length, (int)key.length, key.data); - return LDB_ERR_OPERATIONS_ERROR; - } - } - - ret = ldb_unpack_data_flags(ldb, &data_parse, - ctx->msg, ctx->unpack_flags); - if (ret == -1) { - if (data_parse.data != data.data) { - talloc_free(data_parse.data); - } - - ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid data for index %*.*s\n", - (int)key.length, (int)key.length, key.data); - return LDB_ERR_OPERATIONS_ERROR; - } - return ret; -} - -/* - search the database for a single simple dn, returning all attributes - in a single message - - return LDB_ERR_NO_SUCH_OBJECT on record-not-found - and LDB_SUCCESS on success -*/ -int ldb_kv_search_key(struct ldb_module *module, - struct ldb_kv_private *ldb_kv, - const struct ldb_val ldb_key, - struct ldb_message *msg, - unsigned int unpack_flags) -{ - int ret; - struct ldb_kv_parse_data_unpack_ctx ctx = { - .msg = msg, - .module = module, - .unpack_flags = unpack_flags, - .ldb_kv = ldb_kv - }; - - memset(msg, 0, sizeof(*msg)); - - msg->num_elements = 0; - msg->elements = NULL; - - ret = ldb_kv->kv_ops->fetch_and_parse( - ldb_kv, ldb_key, ldb_kv_parse_data_unpack, &ctx); - - if (ret == -1) { - ret = ldb_kv->kv_ops->error(ldb_kv); - if (ret == LDB_SUCCESS) { - /* - * Just to be sure we don't turn errors - * into success - */ - return LDB_ERR_OPERATIONS_ERROR; - } - return ret; - } else if (ret != LDB_SUCCESS) { - return ret; - } - - return LDB_SUCCESS; -} - -/* - search the database for a single simple dn, returning all attributes - in a single message - - return LDB_ERR_NO_SUCH_OBJECT on record-not-found - and LDB_SUCCESS on success -*/ -int ldb_kv_search_dn1(struct ldb_module *module, - struct ldb_dn *dn, - struct ldb_message *msg, - unsigned int unpack_flags) -{ - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - int ret; - uint8_t guid_key[LDB_KV_GUID_KEY_SIZE]; - struct ldb_val key = { - .data = guid_key, - .length = sizeof(guid_key) - }; - TALLOC_CTX *tdb_key_ctx = NULL; - - bool valid_dn = ldb_dn_validate(dn); - if (valid_dn == false) { - ldb_asprintf_errstring(ldb_module_get_ctx(module), - "Invalid Base DN: %s", - ldb_dn_get_linearized(dn)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - if (ldb_kv->cache->GUID_index_attribute == NULL || - ldb_dn_is_special(dn)) { - - tdb_key_ctx = talloc_new(msg); - if (!tdb_key_ctx) { - return ldb_module_oom(module); - } - - /* form the key */ - key = ldb_kv_key_dn(tdb_key_ctx, dn); - if (!key.data) { - TALLOC_FREE(tdb_key_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } - } else { - /* - * Look in the index to find the key for this DN. - * - * the tdb_key memory is allocated above, msg is just - * used for internal memory. - * - */ - ret = ldb_kv_key_dn_from_idx(module, ldb_kv, msg, dn, &key); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - ret = ldb_kv_search_key(module, ldb_kv, key, msg, unpack_flags); - - TALLOC_FREE(tdb_key_ctx); - - if (ret != LDB_SUCCESS) { - return ret; - } - - if ((unpack_flags & LDB_UNPACK_DATA_FLAG_NO_DN) == 0) { - if (!msg->dn) { - msg->dn = ldb_dn_copy(msg, dn); - } - if (!msg->dn) { - return LDB_ERR_OPERATIONS_ERROR; - } - } - - return LDB_SUCCESS; -} - -/* - * filter the specified list of attributes from msg, - * adding requested attributes, and perhaps all for *, - * but not the DN to filtered_msg. - */ -int ldb_kv_filter_attrs(struct ldb_context *ldb, - const struct ldb_message *msg, - const char *const *attrs, - struct ldb_message *filtered_msg) -{ - return ldb_filter_attrs(ldb, msg, attrs, filtered_msg); -} - -/* - search function for a non-indexed search - */ -static int search_func(_UNUSED_ struct ldb_kv_private *ldb_kv, - struct ldb_val key, - struct ldb_val val, - void *state) -{ - struct ldb_context *ldb; - struct ldb_kv_context *ac; - struct ldb_message *msg, *filtered_msg; - int ret; - bool matched; - - ac = talloc_get_type(state, struct ldb_kv_context); - ldb = ldb_module_get_ctx(ac->module); - - /* - * We want to skip @ records early in a search full scan - * - * @ records like @IDXLIST are only available via a base - * search on the specific name but the method by which they - * were excluded was expensive, after the unpack the DN is - * exploded and ldb_match_msg_error() would reject it for - * failing to match the scope. - * - * ldb_kv_key_is_normal_record() uses the fact that @ records - * have the DN=@ prefix on their TDB/LMDB key to quickly - * exclude them from consideration. - * - * (any other non-records are also excluded by the same key - * match) - */ - - if (ldb_kv_key_is_normal_record(key) == false) { - return 0; - } - - msg = ldb_msg_new(ac); - if (!msg) { - ac->error = LDB_ERR_OPERATIONS_ERROR; - return -1; - } - - /* unpack the record */ - ret = ldb_unpack_data_flags(ldb, &val, msg, - LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC); - if (ret == -1) { - talloc_free(msg); - ac->error = LDB_ERR_OPERATIONS_ERROR; - return -1; - } - - if (!msg->dn) { - msg->dn = ldb_dn_new(msg, ldb, - (char *)key.data + 3); - if (msg->dn == NULL) { - talloc_free(msg); - ac->error = LDB_ERR_OPERATIONS_ERROR; - return -1; - } - } - - /* see if it matches the given expression */ - ret = ldb_match_msg_error(ldb, msg, - ac->tree, ac->base, ac->scope, &matched); - if (ret != LDB_SUCCESS) { - talloc_free(msg); - ac->error = LDB_ERR_OPERATIONS_ERROR; - return -1; - } - if (!matched) { - talloc_free(msg); - return 0; - } - - filtered_msg = ldb_msg_new(ac); - if (filtered_msg == NULL) { - TALLOC_FREE(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - filtered_msg->dn = talloc_steal(filtered_msg, msg->dn); - - /* filter the attributes that the user wants */ - ret = ldb_kv_filter_attrs(ldb, msg, ac->attrs, filtered_msg); - talloc_free(msg); - - if (ret == -1) { - TALLOC_FREE(filtered_msg); - ac->error = LDB_ERR_OPERATIONS_ERROR; - return -1; - } - - ret = ldb_module_send_entry(ac->req, filtered_msg, NULL); - if (ret != LDB_SUCCESS) { - ac->request_terminated = true; - /* the callback failed, abort the operation */ - ac->error = LDB_ERR_OPERATIONS_ERROR; - return -1; - } - - return 0; -} - - -/* - search the database with a LDAP-like expression. - this is the "full search" non-indexed variant -*/ -static int ldb_kv_search_full(struct ldb_kv_context *ctx) -{ - void *data = ldb_module_get_private(ctx->module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - int ret; - - ctx->error = LDB_SUCCESS; - ret = ldb_kv->kv_ops->iterate(ldb_kv, search_func, ctx); - - if (ret < 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return ctx->error; -} - -static int ldb_kv_search_and_return_base(struct ldb_kv_private *ldb_kv, - struct ldb_kv_context *ctx) -{ - struct ldb_message *msg, *filtered_msg; - struct ldb_context *ldb = ldb_module_get_ctx(ctx->module); - const char *dn_linearized; - const char *msg_dn_linearized; - int ret; - bool matched; - - msg = ldb_msg_new(ctx); - if (!msg) { - return LDB_ERR_OPERATIONS_ERROR; - } - ret = ldb_kv_search_dn1(ctx->module, - ctx->base, - msg, - LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC | - LDB_UNPACK_DATA_FLAG_READ_LOCKED); - - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - if (ldb_kv->check_base == false) { - /* - * In this case, we are done, as no base - * checking is allowed in this DB - */ - talloc_free(msg); - return LDB_SUCCESS; - } - ldb_asprintf_errstring(ldb, - "No such Base DN: %s", - ldb_dn_get_linearized(ctx->base)); - } - if (ret != LDB_SUCCESS) { - talloc_free(msg); - return ret; - } - - - /* - * We use this, not ldb_match_msg_error() as we know - * we matched on the scope BASE, as we just fetched - * the base DN - */ - - ret = ldb_match_message(ldb, msg, - ctx->tree, - ctx->scope, - &matched); - if (ret != LDB_SUCCESS) { - talloc_free(msg); - return ret; - } - if (!matched) { - talloc_free(msg); - return LDB_SUCCESS; - } - - dn_linearized = ldb_dn_get_linearized(ctx->base); - msg_dn_linearized = ldb_dn_get_linearized(msg->dn); - - filtered_msg = ldb_msg_new(ctx); - if (filtered_msg == NULL) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (strcmp(dn_linearized, msg_dn_linearized) == 0) { - /* - * If the DN is exactly the same string, then - * re-use the full incoming DN for the - * returned result, as it has already been - * casefolded - */ - filtered_msg->dn = ldb_dn_copy(filtered_msg, ctx->base); - } - - /* - * If the ldb_dn_copy() failed, or if we did not choose that - * optimisation (filtered_msg is zeroed at allocation), - * steal the one from the unpack - */ - if (filtered_msg->dn == NULL) { - filtered_msg->dn = talloc_steal(filtered_msg, msg->dn); - } - - /* - * filter the attributes that the user wants. - */ - ret = ldb_kv_filter_attrs(ldb, msg, ctx->attrs, filtered_msg); - if (ret == -1) { - talloc_free(msg); - filtered_msg = NULL; - return LDB_ERR_OPERATIONS_ERROR; - } - - /* - * Remove any extended components possibly copied in from - * msg->dn, we just want the casefold components - */ - ldb_dn_remove_extended_components(filtered_msg->dn); - talloc_free(msg); - - ret = ldb_module_send_entry(ctx->req, filtered_msg, NULL); - if (ret != LDB_SUCCESS) { - /* Regardless of success or failure, the msg - * is the callbacks responsiblity, and should - * not be talloc_free()'ed */ - ctx->request_terminated = true; - return ret; - } - - return LDB_SUCCESS; -} - -/* - search the database with a LDAP-like expression. - choses a search method -*/ -int ldb_kv_search(struct ldb_kv_context *ctx) -{ - struct ldb_context *ldb; - struct ldb_module *module = ctx->module; - struct ldb_request *req = ctx->req; - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - int ret; - - ldb = ldb_module_get_ctx(module); - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - if (ldb_kv->kv_ops->lock_read(module) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (ldb_kv_cache_load(module) != 0) { - ldb_kv->kv_ops->unlock_read(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (req->op.search.tree == NULL) { - ldb_kv->kv_ops->unlock_read(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - ctx->tree = req->op.search.tree; - ctx->scope = req->op.search.scope; - ctx->base = req->op.search.base; - ctx->attrs = req->op.search.attrs; - - if ((req->op.search.base == NULL) || (ldb_dn_is_null(req->op.search.base) == true)) { - - /* Check what we should do with a NULL dn */ - switch (req->op.search.scope) { - case LDB_SCOPE_BASE: - ldb_asprintf_errstring(ldb, - "NULL Base DN invalid for a base search"); - ret = LDB_ERR_INVALID_DN_SYNTAX; - break; - case LDB_SCOPE_ONELEVEL: - ldb_asprintf_errstring(ldb, - "NULL Base DN invalid for a one-level search"); - ret = LDB_ERR_INVALID_DN_SYNTAX; - break; - case LDB_SCOPE_SUBTREE: - default: - /* We accept subtree searches from a NULL base DN, ie over the whole DB */ - ret = LDB_SUCCESS; - } - } else if (req->op.search.scope == LDB_SCOPE_BASE) { - - /* - * If we are LDB_SCOPE_BASE, do just one search and - * return early. This is critical to ensure we do not - * go into the index code for special DNs, as that - * will try to look up an index record for a special - * record (which doesn't exist). - */ - ret = ldb_kv_search_and_return_base(ldb_kv, ctx); - - ldb_kv->kv_ops->unlock_read(module); - - return ret; - - } else if (ldb_kv->check_base) { - /* - * This database has been marked as - * 'checkBaseOnSearch', so do a spot check of the base - * dn. Also optimise the subsequent filter by filling - * in the ctx->base to be exactly case correct - */ - ret = ldb_kv_search_base( - module, ctx, req->op.search.base, &ctx->base); - - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - ldb_asprintf_errstring(ldb, - "No such Base DN: %s", - ldb_dn_get_linearized(req->op.search.base)); - } - - } else if (ldb_dn_validate(req->op.search.base) == false) { - - /* We don't want invalid base DNs here */ - ldb_asprintf_errstring(ldb, - "Invalid Base DN: %s", - ldb_dn_get_linearized(req->op.search.base)); - ret = LDB_ERR_INVALID_DN_SYNTAX; - - } else { - /* If we are not checking the base DN life is easy */ - ret = LDB_SUCCESS; - } - - if (ret == LDB_SUCCESS) { - uint32_t match_count = 0; - - ret = ldb_kv_search_indexed(ctx, &match_count); - if (ret == LDB_ERR_NO_SUCH_OBJECT) { - /* Not in the index, therefore OK! */ - ret = LDB_SUCCESS; - - } - /* Check if we got just a normal error. - * In that case proceed to a full search unless we got a - * callback error */ - if (!ctx->request_terminated && ret != LDB_SUCCESS) { - /* Not indexed, so we need to do a full scan */ - if (ldb_kv->warn_unindexed || - ldb_kv->disable_full_db_scan) { - /* useful for debugging when slow performance - * is caused by unindexed searches */ - char *expression = ldb_filter_from_tree(ctx, ctx->tree); - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb FULL SEARCH: %s SCOPE: %s DN: %s", - expression, - req->op.search.scope==LDB_SCOPE_BASE?"base": - req->op.search.scope==LDB_SCOPE_ONELEVEL?"one": - req->op.search.scope==LDB_SCOPE_SUBTREE?"sub":"UNKNOWN", - ldb_dn_get_linearized(req->op.search.base)); - - talloc_free(expression); - } - - if (match_count != 0) { - /* the indexing code gave an error - * after having returned at least one - * entry. This means the indexes are - * corrupt or a database record is - * corrupt. We cannot continue with a - * full search or we may return - * duplicate entries - */ - ldb_kv->kv_ops->unlock_read(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (ldb_kv->disable_full_db_scan) { - ldb_set_errstring(ldb, - "ldb FULL SEARCH disabled"); - ldb_kv->kv_ops->unlock_read(module); - return LDB_ERR_INAPPROPRIATE_MATCHING; - } - - ret = ldb_kv_search_full(ctx); - if (ret != LDB_SUCCESS) { - ldb_set_errstring(ldb, "Indexed and full searches both failed!\n"); - } - } - } - - ldb_kv->kv_ops->unlock_read(module); - - return ret; -} diff --git a/ldb-2.0.8/ldb_ldap/ldb_ldap.c b/ldb-2.0.8/ldb_ldap/ldb_ldap.c deleted file mode 100644 index d722299..0000000 --- a/ldb-2.0.8/ldb_ldap/ldb_ldap.c +++ /dev/null @@ -1,969 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Simo Sorce 2006 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb_ldap - * - * Component: ldb ldap backend - * - * Description: core files for LDAP backend - * - * Author: Andrew Tridgell - * - * Modifications: - * - * - description: make the module use asynchronous calls - * date: Feb 2006 - * author: Simo Sorce - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb_module.h" -#include "ldb_private.h" - -#define LDAP_DEPRECATED 1 -#include - -struct lldb_private { - LDAP *ldap; -}; - -struct lldb_context { - struct ldb_module *module; - struct ldb_request *req; - - struct lldb_private *lldb; - - struct ldb_control **controls; - int msgid; -}; - -static int lldb_ldap_to_ldb(int err) { - /* Ldap errors and ldb errors are defined to the same values */ - return err; -} - -/* - convert a ldb_message structure to a list of LDAPMod structures - ready for ldap_add() or ldap_modify() -*/ -static LDAPMod **lldb_msg_to_mods(void *mem_ctx, const struct ldb_message *msg, int use_flags) -{ - LDAPMod **mods; - unsigned int i, j; - int num_mods = 0; - - /* allocate maximum number of elements needed */ - mods = talloc_array(mem_ctx, LDAPMod *, msg->num_elements+1); - if (!mods) { - errno = ENOMEM; - return NULL; - } - mods[0] = NULL; - - for (i=0;inum_elements;i++) { - const struct ldb_message_element *el = &msg->elements[i]; - - mods[num_mods] = talloc(mods, LDAPMod); - if (!mods[num_mods]) { - goto failed; - } - mods[num_mods+1] = NULL; - mods[num_mods]->mod_op = LDAP_MOD_BVALUES; - if (use_flags) { - switch (el->flags & LDB_FLAG_MOD_MASK) { - case LDB_FLAG_MOD_ADD: - mods[num_mods]->mod_op |= LDAP_MOD_ADD; - break; - case LDB_FLAG_MOD_DELETE: - mods[num_mods]->mod_op |= LDAP_MOD_DELETE; - break; - case LDB_FLAG_MOD_REPLACE: - mods[num_mods]->mod_op |= LDAP_MOD_REPLACE; - break; - } - } - mods[num_mods]->mod_type = discard_const_p(char, el->name); - mods[num_mods]->mod_vals.modv_bvals = talloc_array(mods[num_mods], - struct berval *, - 1+el->num_values); - if (!mods[num_mods]->mod_vals.modv_bvals) { - goto failed; - } - - for (j=0;jnum_values;j++) { - mods[num_mods]->mod_vals.modv_bvals[j] = talloc(mods[num_mods]->mod_vals.modv_bvals, - struct berval); - if (!mods[num_mods]->mod_vals.modv_bvals[j]) { - goto failed; - } - mods[num_mods]->mod_vals.modv_bvals[j]->bv_val = (char *)el->values[j].data; - mods[num_mods]->mod_vals.modv_bvals[j]->bv_len = el->values[j].length; - } - mods[num_mods]->mod_vals.modv_bvals[j] = NULL; - num_mods++; - } - - return mods; - -failed: - talloc_free(mods); - return NULL; -} - -/* - add a single set of ldap message values to a ldb_message -*/ -static int lldb_add_msg_attr(struct ldb_context *ldb, - struct ldb_message *msg, - const char *attr, struct berval **bval) -{ - int count, i, ret; - struct ldb_message_element *el; - - count = ldap_count_values_len(bval); - - if (count <= 0) { - return -1; - } - - ret = ldb_msg_add_empty(msg, attr, 0, &el); - if (ret != LDB_SUCCESS) { - errno = ENOMEM; - return -1; - } - - el->values = talloc_array(msg->elements, struct ldb_val, count); - if (!el->values) { - errno = ENOMEM; - return -1; - } - - for (i=0;ivalues[i].data = talloc_size(el->values, bval[i]->bv_len+1); - if (!el->values[i].data) { - errno = ENOMEM; - return -1; - } - memcpy(el->values[i].data, bval[i]->bv_val, bval[i]->bv_len); - el->values[i].data[bval[i]->bv_len] = 0; - el->values[i].length = bval[i]->bv_len; - el->num_values++; - } - - msg->num_elements++; - - return 0; -} - -/* - search for matching records -*/ -static int lldb_search(struct lldb_context *lldb_ac) -{ - struct ldb_context *ldb; - struct lldb_private *lldb = lldb_ac->lldb; - struct ldb_module *module = lldb_ac->module; - struct ldb_request *req = lldb_ac->req; - struct timeval tv; - int ldap_scope; - char *search_base; - char *expression; - int ret; - - ldb = ldb_module_get_ctx(module); - - if (!req->callback || !req->context) { - ldb_set_errstring(ldb, "Async interface called with NULL callback function or NULL context"); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (req->op.search.tree == NULL) { - ldb_set_errstring(ldb, "Invalid expression parse tree"); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (req->controls != NULL) { - ldb_debug(ldb, LDB_DEBUG_WARNING, "Controls are not yet supported by ldb_ldap backend!"); - } - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - search_base = ldb_dn_alloc_linearized(lldb_ac, req->op.search.base); - if (req->op.search.base == NULL) { - search_base = talloc_strdup(lldb_ac, ""); - } - if (search_base == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - expression = ldb_filter_from_tree(lldb_ac, req->op.search.tree); - if (expression == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - switch (req->op.search.scope) { - case LDB_SCOPE_BASE: - ldap_scope = LDAP_SCOPE_BASE; - break; - case LDB_SCOPE_ONELEVEL: - ldap_scope = LDAP_SCOPE_ONELEVEL; - break; - default: - ldap_scope = LDAP_SCOPE_SUBTREE; - break; - } - - tv.tv_sec = 0; - tv.tv_usec = 0; - if (req->timeout > 0) { - tv.tv_sec = req->timeout; - } - - ret = ldap_search_ext(lldb->ldap, search_base, ldap_scope, - expression, - discard_const_p(char *, req->op.search.attrs), - 0, - NULL, - NULL, - &tv, - LDAP_NO_LIMIT, - &lldb_ac->msgid); - - if (ret != LDAP_SUCCESS) { - ldb_set_errstring(ldb, ldap_err2string(ret)); - } - - return lldb_ldap_to_ldb(ret); -} - -/* - add a record -*/ -static int lldb_add(struct lldb_context *lldb_ac) -{ - struct ldb_context *ldb; - struct lldb_private *lldb = lldb_ac->lldb; - struct ldb_module *module = lldb_ac->module; - struct ldb_request *req = lldb_ac->req; - LDAPMod **mods; - char *dn; - int ret; - - ldb = ldb_module_get_ctx(module); - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - mods = lldb_msg_to_mods(lldb_ac, req->op.add.message, 0); - if (mods == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - dn = ldb_dn_alloc_linearized(lldb_ac, req->op.add.message->dn); - if (dn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldap_add_ext(lldb->ldap, dn, mods, - NULL, - NULL, - &lldb_ac->msgid); - - if (ret != LDAP_SUCCESS) { - ldb_set_errstring(ldb, ldap_err2string(ret)); - } - - return lldb_ldap_to_ldb(ret); -} - -/* - modify a record -*/ -static int lldb_modify(struct lldb_context *lldb_ac) -{ - struct ldb_context *ldb; - struct lldb_private *lldb = lldb_ac->lldb; - struct ldb_module *module = lldb_ac->module; - struct ldb_request *req = lldb_ac->req; - LDAPMod **mods; - char *dn; - int ret; - - ldb = ldb_module_get_ctx(module); - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - mods = lldb_msg_to_mods(lldb_ac, req->op.mod.message, 1); - if (mods == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - dn = ldb_dn_alloc_linearized(lldb_ac, req->op.mod.message->dn); - if (dn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldap_modify_ext(lldb->ldap, dn, mods, - NULL, - NULL, - &lldb_ac->msgid); - - if (ret != LDAP_SUCCESS) { - ldb_set_errstring(ldb, ldap_err2string(ret)); - } - - return lldb_ldap_to_ldb(ret); -} - -/* - delete a record -*/ -static int lldb_delete(struct lldb_context *lldb_ac) -{ - struct ldb_context *ldb; - struct lldb_private *lldb = lldb_ac->lldb; - struct ldb_module *module = lldb_ac->module; - struct ldb_request *req = lldb_ac->req; - char *dnstr; - int ret; - - ldb = ldb_module_get_ctx(module); - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - dnstr = ldb_dn_alloc_linearized(lldb_ac, req->op.del.dn); - - ret = ldap_delete_ext(lldb->ldap, dnstr, - NULL, - NULL, - &lldb_ac->msgid); - - if (ret != LDAP_SUCCESS) { - ldb_set_errstring(ldb, ldap_err2string(ret)); - } - - return lldb_ldap_to_ldb(ret); -} - -/* - rename a record -*/ -static int lldb_rename(struct lldb_context *lldb_ac) -{ - struct ldb_context *ldb; - struct lldb_private *lldb = lldb_ac->lldb; - struct ldb_module *module = lldb_ac->module; - struct ldb_request *req = lldb_ac->req; - const char *rdn_name; - const struct ldb_val *rdn_val; - char *old_dn; - char *newrdn; - char *parentdn; - int ret; - - ldb = ldb_module_get_ctx(module); - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - old_dn = ldb_dn_alloc_linearized(lldb_ac, req->op.rename.olddn); - if (old_dn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - rdn_name = ldb_dn_get_rdn_name(req->op.rename.newdn); - rdn_val = ldb_dn_get_rdn_val(req->op.rename.newdn); - - if ((rdn_name != NULL) && (rdn_val != NULL)) { - newrdn = talloc_asprintf(lldb_ac, "%s=%s", rdn_name, - rdn_val->length > 0 ? ldb_dn_escape_value(lldb, *rdn_val) : ""); - } else { - newrdn = talloc_strdup(lldb_ac, ""); - } - if (!newrdn) { - return LDB_ERR_OPERATIONS_ERROR; - } - - parentdn = ldb_dn_alloc_linearized(lldb_ac, ldb_dn_get_parent(lldb_ac, req->op.rename.newdn)); - if (!parentdn) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldap_rename(lldb->ldap, old_dn, newrdn, parentdn, - 1, NULL, NULL, - &lldb_ac->msgid); - - if (ret != LDAP_SUCCESS) { - ldb_set_errstring(ldb, ldap_err2string(ret)); - } - - return lldb_ldap_to_ldb(ret); -} - -static int lldb_start_trans(struct ldb_module *module) -{ - /* TODO implement a local transaction mechanism here */ - - return LDB_SUCCESS; -} - -static int lldb_end_trans(struct ldb_module *module) -{ - /* TODO implement a local transaction mechanism here */ - - return LDB_SUCCESS; -} - -static int lldb_del_trans(struct ldb_module *module) -{ - /* TODO implement a local transaction mechanism here */ - - return LDB_SUCCESS; -} - -static void lldb_request_done(struct lldb_context *ac, - struct ldb_control **ctrls, int error) -{ - struct ldb_request *req; - struct ldb_reply *ares; - - req = ac->req; - - ares = talloc_zero(req, struct ldb_reply); - if (!ares) { - ldb_oom(ldb_module_get_ctx(ac->module)); - req->callback(req, NULL); - return; - } - ares->type = LDB_REPLY_DONE; - ares->controls = talloc_steal(ares, ctrls); - ares->error = error; - - req->callback(req, ares); -} - -/* return false if the request is still in progress - * return true if the request is completed - */ -static bool lldb_parse_result(struct lldb_context *ac, LDAPMessage *result) -{ - struct ldb_context *ldb; - struct lldb_private *lldb = ac->lldb; - LDAPControl **serverctrlsp = NULL; - char **referralsp = NULL; - char *matcheddnp = NULL; - char *errmsgp = NULL; - LDAPMessage *msg; - int type; - struct ldb_message *ldbmsg = NULL; - char *referral; - bool callback_failed; - bool request_done; - bool lret; - unsigned int i; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - type = ldap_msgtype(result); - callback_failed = false; - request_done = false; - - switch (type) { - case LDAP_RES_SEARCH_ENTRY: - - msg = ldap_first_entry(lldb->ldap, result); - if (msg != NULL) { - BerElement *berptr = NULL; - char *attr, *dn; - - ldbmsg = ldb_msg_new(ac); - if (!ldbmsg) { - ldb_oom(ldb); - ret = LDB_ERR_OPERATIONS_ERROR; - break; - } - - dn = ldap_get_dn(lldb->ldap, msg); - if (!dn) { - ldb_oom(ldb); - talloc_free(ldbmsg); - ret = LDB_ERR_OPERATIONS_ERROR; - break; - } - ldbmsg->dn = ldb_dn_new(ldbmsg, ldb, dn); - if ( ! ldb_dn_validate(ldbmsg->dn)) { - ldb_asprintf_errstring(ldb, "Invalid DN '%s' in reply", dn); - talloc_free(ldbmsg); - ret = LDB_ERR_OPERATIONS_ERROR; - ldap_memfree(dn); - break; - } - ldap_memfree(dn); - /* loop over all attributes */ - for (attr=ldap_first_attribute(lldb->ldap, msg, &berptr); - attr; - attr=ldap_next_attribute(lldb->ldap, msg, berptr)) { - struct berval **bval; - bval = ldap_get_values_len(lldb->ldap, msg, attr); - - if (bval) { - lldb_add_msg_attr(ldb, ldbmsg, attr, bval); - ldap_value_free_len(bval); - } - } - if (berptr) ber_free(berptr, 0); - - ret = ldb_module_send_entry(ac->req, ldbmsg, NULL /* controls not yet supported */); - if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb, "entry send failed: %s", - ldb_errstring(ldb)); - callback_failed = true; - } - } else { - ret = LDB_ERR_OPERATIONS_ERROR; - } - break; - - case LDAP_RES_SEARCH_REFERENCE: - - ret = ldap_parse_reference(lldb->ldap, result, - &referralsp, &serverctrlsp, 0); - if (ret != LDAP_SUCCESS) { - ldb_asprintf_errstring(ldb, "ldap reference parse error: %s : %s", - ldap_err2string(ret), errmsgp); - ret = LDB_ERR_OPERATIONS_ERROR; - break; - } - if (referralsp == NULL) { - ldb_asprintf_errstring(ldb, "empty ldap referrals list"); - ret = LDB_ERR_PROTOCOL_ERROR; - break; - } - - for (i = 0; referralsp[i]; i++) { - referral = talloc_strdup(ac, referralsp[i]); - - ret = ldb_module_send_referral(ac->req, referral); - if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb, "referral send failed: %s", - ldb_errstring(ldb)); - callback_failed = true; - break; - } - } - break; - - case LDAP_RES_SEARCH_RESULT: - case LDAP_RES_MODIFY: - case LDAP_RES_ADD: - case LDAP_RES_DELETE: - case LDAP_RES_MODDN: - - if (ldap_parse_result(lldb->ldap, result, &ret, - &matcheddnp, &errmsgp, - &referralsp, &serverctrlsp, 0) != LDAP_SUCCESS) { - ret = LDB_ERR_OPERATIONS_ERROR; - } - if (ret != LDB_SUCCESS) { - ldb_asprintf_errstring(ldb, "ldap parse error for type %d: %s : %s", - type, ldap_err2string(ret), errmsgp); - break; - } - - if (serverctrlsp != NULL) { - /* FIXME: transform the LDAPControl list into an ldb_control one */ - ac->controls = NULL; - } - - request_done = true; - break; - - default: - ldb_asprintf_errstring(ldb, "unknown ldap return type: %d", type); - ret = LDB_ERR_PROTOCOL_ERROR; - break; - } - - if (ret != LDB_SUCCESS) { - - /* if the callback failed the caller will have freed the - * request. Just return and don't try to use it */ - if (callback_failed) { - - /* tell lldb_wait to remove the request from the - * queue */ - lret = true; - goto free_and_return; - } - - request_done = true; - } - - if (request_done) { - lldb_request_done(ac, ac->controls, ret); - lret = true; - goto free_and_return; - } - - lret = false; - -free_and_return: - - if (matcheddnp) ldap_memfree(matcheddnp); - if (errmsgp && *errmsgp) { - ldb_set_errstring(ldb, errmsgp); - } - if (errmsgp) { - ldap_memfree(errmsgp); - } - if (referralsp) ldap_value_free(referralsp); - if (serverctrlsp) ldap_controls_free(serverctrlsp); - - ldap_msgfree(result); - - return lret; -} - -static void lldb_timeout(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval t, - void *private_data) -{ - struct lldb_context *ac; - ac = talloc_get_type(private_data, struct lldb_context); - - lldb_request_done(ac, NULL, LDB_ERR_TIME_LIMIT_EXCEEDED); -} - -static void lldb_callback(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval t, - void *private_data) -{ - struct lldb_context *ac; - struct tevent_timer *lte; - struct timeval tv; - LDAPMessage *result; - int lret; - - ac = talloc_get_type(private_data, struct lldb_context); - - if (!ac->msgid) { - lldb_request_done(ac, NULL, LDB_ERR_OPERATIONS_ERROR); - return; - } - - tv.tv_sec = 0; - tv.tv_usec = 0; - lret = ldap_result(ac->lldb->ldap, ac->msgid, 0, &tv, &result); - if (lret == 0) { - goto respin; - } - if (lret == -1) { - lldb_request_done(ac, NULL, LDB_ERR_OPERATIONS_ERROR); - return; - } - - if ( ! lldb_parse_result(ac, result)) { - goto respin; - } - - return; - -respin: - tv.tv_sec = 0; - tv.tv_usec = 100; - lte = tevent_add_timer(ev, ac, tv, lldb_callback, ac); - if (NULL == lte) { - lldb_request_done(ac, NULL, LDB_ERR_OPERATIONS_ERROR); - } -} - -static bool lldb_dn_is_special(struct ldb_request *req) -{ - struct ldb_dn *dn = NULL; - - switch (req->operation) { - case LDB_ADD: - dn = req->op.add.message->dn; - break; - case LDB_MODIFY: - dn = req->op.mod.message->dn; - break; - case LDB_DELETE: - dn = req->op.del.dn; - break; - case LDB_RENAME: - dn = req->op.rename.olddn; - break; - default: - break; - } - - if (dn && ldb_dn_is_special(dn)) { - return true; - } - return false; -} - -static void lldb_auto_done_callback(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval t, - void *private_data) -{ - struct lldb_context *ac; - - ac = talloc_get_type(private_data, struct lldb_context); - lldb_request_done(ac, NULL, LDB_SUCCESS); -} - -static int lldb_handle_request(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - struct lldb_private *lldb; - struct lldb_context *ac; - struct tevent_context *ev; - struct tevent_timer *te; - struct timeval tv; - int ret; - - lldb = talloc_get_type(ldb_module_get_private(module), struct lldb_private); - ldb = ldb_module_get_ctx(module); - - if (req->starttime == 0 || req->timeout == 0) { - ldb_set_errstring(ldb, "Invalid timeout settings"); - return LDB_ERR_TIME_LIMIT_EXCEEDED; - } - - ev = ldb_get_event_context(ldb); - if (NULL == ev) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac = talloc_zero(ldb, struct lldb_context); - if (ac == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - ac->lldb = lldb; - ac->msgid = 0; - - if (lldb_dn_is_special(req)) { - tv.tv_sec = 0; - tv.tv_usec = 0; - te = tevent_add_timer(ev, ac, tv, - lldb_auto_done_callback, ac); - if (NULL == te) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return LDB_SUCCESS; - } - - switch (ac->req->operation) { - case LDB_SEARCH: - ret = lldb_search(ac); - break; - case LDB_ADD: - ret = lldb_add(ac); - break; - case LDB_MODIFY: - ret = lldb_modify(ac); - break; - case LDB_DELETE: - ret = lldb_delete(ac); - break; - case LDB_RENAME: - ret = lldb_rename(ac); - break; - default: - /* no other op supported */ - ret = LDB_ERR_PROTOCOL_ERROR; - break; - } - - if (ret != LDB_SUCCESS) { - lldb_request_done(ac, NULL, ret); - return ret; - } - - tv.tv_sec = 0; - tv.tv_usec = 0; - te = tevent_add_timer(ev, ac, tv, lldb_callback, ac); - if (NULL == te) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (req->timeout > 0) { - tv.tv_sec = req->starttime + req->timeout; - tv.tv_usec = 0; - te = tevent_add_timer(ev, ac, tv, lldb_timeout, ac); - if (NULL == te) { - return LDB_ERR_OPERATIONS_ERROR; - } - } - - return LDB_SUCCESS; -} - -static const struct ldb_module_ops lldb_ops = { - .name = "ldap", - .search = lldb_handle_request, - .add = lldb_handle_request, - .modify = lldb_handle_request, - .del = lldb_handle_request, - .rename = lldb_handle_request, - .request = lldb_handle_request, - .start_transaction = lldb_start_trans, - .end_transaction = lldb_end_trans, - .del_transaction = lldb_del_trans, -}; - - -static int lldb_destructor(struct lldb_private *lldb) -{ - ldap_unbind(lldb->ldap); - return 0; -} - - -/* - optionally perform a bind - */ -static int lldb_bind(struct ldb_module *module, - const char *options[]) -{ - const char *bind_mechanism; - struct lldb_private *lldb; - struct ldb_context *ldb = ldb_module_get_ctx(module); - int ret; - - bind_mechanism = ldb_options_find(ldb, options, "bindMech"); - if (bind_mechanism == NULL) { - /* no bind wanted */ - return LDB_SUCCESS; - } - - lldb = talloc_get_type(ldb_module_get_private(module), struct lldb_private); - - if (strcmp(bind_mechanism, "simple") == 0) { - const char *bind_id, *bind_secret; - - bind_id = ldb_options_find(ldb, options, "bindID"); - bind_secret = ldb_options_find(ldb, options, "bindSecret"); - if (bind_id == NULL || bind_secret == NULL) { - ldb_asprintf_errstring(ldb, "simple bind requires bindID and bindSecret"); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldap_simple_bind_s(lldb->ldap, bind_id, bind_secret); - if (ret != LDAP_SUCCESS) { - ldb_asprintf_errstring(ldb, "bind failed: %s", ldap_err2string(ret)); - return ret; - } - return LDB_SUCCESS; - } - - ldb_asprintf_errstring(ldb, "bind failed: unknown mechanism %s", bind_mechanism); - return LDB_ERR_INAPPROPRIATE_AUTHENTICATION; -} - -/* - connect to the database -*/ -static int lldb_connect(struct ldb_context *ldb, - const char *url, - unsigned int flags, - const char *options[], - struct ldb_module **_module) -{ - struct ldb_module *module; - struct lldb_private *lldb; - int version = 3; - int ret; - - module = ldb_module_new(ldb, ldb, "ldb_ldap backend", &lldb_ops); - if (!module) return LDB_ERR_OPERATIONS_ERROR; - - lldb = talloc_zero(module, struct lldb_private); - if (!lldb) { - ldb_oom(ldb); - goto failed; - } - ldb_module_set_private(module, lldb); - - ret = ldap_initialize(&lldb->ldap, url); - if (ret != LDAP_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_initialize failed for URL '%s' - %s", - url, ldap_err2string(ret)); - goto failed; - } - - talloc_set_destructor(lldb, lldb_destructor); - - ret = ldap_set_option(lldb->ldap, LDAP_OPT_PROTOCOL_VERSION, &version); - if (ret != LDAP_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_FATAL, "ldap_set_option failed - %s", - ldap_err2string(ret)); - goto failed; - } - - *_module = module; - - ret = lldb_bind(module, options); - if (ret != LDB_SUCCESS) { - goto failed; - } - - - return LDB_SUCCESS; - -failed: - talloc_free(module); - return LDB_ERR_OPERATIONS_ERROR; -} - -/* - initialise the module - */ -int ldb_ldap_init(const char *version) -{ - int ret, i; - const char *names[] = { "ldap", "ldaps", "ldapi", NULL }; - LDB_MODULE_CHECK_VERSION(version); - for (i=0; names[i]; i++) { - ret = ldb_register_backend(names[i], lldb_connect, false); - if (ret != LDB_SUCCESS) { - return ret; - } - } - return LDB_SUCCESS; -} diff --git a/ldb-2.0.8/ldb_ldb/ldb_ldb.c b/ldb-2.0.8/ldb_ldb/ldb_ldb.c deleted file mode 100644 index a5a3612..0000000 --- a/ldb-2.0.8/ldb_ldb/ldb_ldb.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * ldb connection and module initialisation - * - * Copyright (C) Andrew Bartlett 2018 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -#include "ldb_private.h" -#include "../ldb_tdb/ldb_tdb.h" -#ifdef HAVE_LMDB -#include "../ldb_mdb/ldb_mdb.h" -#endif /* HAVE_LMDB */ - -/* - connect to the database -*/ -static int lldb_connect(struct ldb_context *ldb, - const char *url, - unsigned int flags, - const char *options[], - struct ldb_module **module) -{ - const char *path; - int ret; - - /* - * Check and remove the url prefix - */ - if (strchr(url, ':')) { - if (strncmp(url, "ldb://", 6) != 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Invalid ldb URL '%s'", url); - return LDB_ERR_OPERATIONS_ERROR; - } - path = url+6; - } else { - path = url; - } - - /* - * Don't create the database if it's not there - */ - flags |= LDB_FLG_DONT_CREATE_DB; -#ifdef HAVE_LMDB - /* - * Try opening the database as an lmdb - */ - ret = lmdb_connect(ldb, path, flags, options, module); - if (ret == LDB_SUCCESS) { - return ret; - } - if (ret != LDB_ERR_UNAVAILABLE) { - return ret; - } - - /* - * Not mdb so try as tdb - */ -#endif /* HAVE_LMDB */ - ret = ltdb_connect(ldb, path, flags, options, module); - return ret; -} - -int ldb_ldb_init(const char *version) -{ - LDB_MODULE_CHECK_VERSION(version); - return ldb_register_backend("ldb", lldb_connect, false); -} diff --git a/ldb-2.0.8/ldb_map/ldb_map.c b/ldb-2.0.8/ldb_map/ldb_map.c deleted file mode 100644 index b453dff..0000000 --- a/ldb-2.0.8/ldb_map/ldb_map.c +++ /dev/null @@ -1,1156 +0,0 @@ -/* - ldb database mapping module - - Copyright (C) Jelmer Vernooij 2005 - Copyright (C) Martin Kuehl 2006 - Copyright (C) Simo Sorce 2008 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -/* - * Name: ldb - * - * Component: ldb ldb_map module - * - * Description: Map portions of data into a different format on a - * remote partition. - * - * Author: Jelmer Vernooij, Martin Kuehl - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb_map.h" -#include "ldb_map_private.h" - -#ifndef _PUBLIC_ -#define _PUBLIC_ -#endif - -/* Description of the provided ldb requests: - - special attribute 'isMapped' - - - search: - - if parse tree can be split - - search remote records w/ remote attrs and parse tree - - otherwise - - enumerate all remote records - - for each remote result - - map remote result to local message - - search local result - - is present - - merge local into remote result - - run callback on merged result - - otherwise - - run callback on remote result - - - add: - - split message into local and remote part - - if local message is not empty - - add isMapped to local message - - add local message - - add remote message - - - modify: - - split message into local and remote part - - if local message is not empty - - add isMapped to local message - - search for local record - - if present - - modify local record - - otherwise - - add local message - - modify remote record - - - delete: - - search for local record - - if present - - delete local record - - delete remote record - - - rename: - - search for local record - - if present - - rename local record - - modify local isMapped - - rename remote record -*/ - - - -/* Private data structures - * ======================= */ - -/* Global private data */ -/* Extract mappings from private data. */ -const struct ldb_map_context *map_get_context(struct ldb_module *module) -{ - const struct map_private *data = talloc_get_type(ldb_module_get_private(module), struct map_private); - return data->context; -} - -/* Create a generic request context. */ -struct map_context *map_init_context(struct ldb_module *module, - struct ldb_request *req) -{ - struct ldb_context *ldb; - struct map_context *ac; - - ldb = ldb_module_get_ctx(module); - - ac = talloc_zero(req, struct map_context); - if (ac == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return NULL; - } - - ac->module = module; - ac->req = req; - - return ac; -} - -/* Dealing with DNs for different partitions - * ========================================= */ - -/* Check whether any data should be stored in the local partition. */ -bool map_check_local_db(struct ldb_module *module) -{ - const struct ldb_map_context *data = map_get_context(module); - - if (!data->remote_base_dn || !data->local_base_dn) { - return false; - } - - return true; -} - -/* Copy a DN with the base DN of the local partition. */ -static struct ldb_dn *ldb_dn_rebase_local(void *mem_ctx, const struct ldb_map_context *data, struct ldb_dn *dn) -{ - struct ldb_dn *new_dn; - - new_dn = ldb_dn_copy(mem_ctx, dn); - if ( ! ldb_dn_validate(new_dn)) { - talloc_free(new_dn); - return NULL; - } - - /* may be we don't need to rebase at all */ - if ( ! data->remote_base_dn || ! data->local_base_dn) { - return new_dn; - } - - if ( ! ldb_dn_remove_base_components(new_dn, ldb_dn_get_comp_num(data->remote_base_dn))) { - talloc_free(new_dn); - return NULL; - } - - if ( ! ldb_dn_add_base(new_dn, data->local_base_dn)) { - talloc_free(new_dn); - return NULL; - } - - return new_dn; -} - -/* Copy a DN with the base DN of the remote partition. */ -static struct ldb_dn *ldb_dn_rebase_remote(void *mem_ctx, const struct ldb_map_context *data, struct ldb_dn *dn) -{ - struct ldb_dn *new_dn; - - new_dn = ldb_dn_copy(mem_ctx, dn); - if ( ! ldb_dn_validate(new_dn)) { - talloc_free(new_dn); - return NULL; - } - - /* may be we don't need to rebase at all */ - if ( ! data->remote_base_dn || ! data->local_base_dn) { - return new_dn; - } - - if ( ! ldb_dn_remove_base_components(new_dn, ldb_dn_get_comp_num(data->local_base_dn))) { - talloc_free(new_dn); - return NULL; - } - - if ( ! ldb_dn_add_base(new_dn, data->remote_base_dn)) { - talloc_free(new_dn); - return NULL; - } - - return new_dn; -} - -/* Run a request and make sure it targets the remote partition. */ -/* TODO: free old DNs and messages? */ -int ldb_next_remote_request(struct ldb_module *module, struct ldb_request *request) -{ - const struct ldb_map_context *data = map_get_context(module); - struct ldb_context *ldb; - struct ldb_message *msg; - - ldb = ldb_module_get_ctx(module); - - switch (request->operation) { - case LDB_SEARCH: - if (request->op.search.base) { - request->op.search.base = ldb_dn_rebase_remote(request, data, request->op.search.base); - } else { - request->op.search.base = data->remote_base_dn; - /* TODO: adjust scope? */ - } - break; - - case LDB_ADD: - msg = ldb_msg_copy_shallow(request, request->op.add.message); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - msg->dn = ldb_dn_rebase_remote(msg, data, msg->dn); - request->op.add.message = msg; - break; - - case LDB_MODIFY: - msg = ldb_msg_copy_shallow(request, request->op.mod.message); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - msg->dn = ldb_dn_rebase_remote(msg, data, msg->dn); - request->op.mod.message = msg; - break; - - case LDB_DELETE: - request->op.del.dn = ldb_dn_rebase_remote(request, data, request->op.del.dn); - break; - - case LDB_RENAME: - request->op.rename.olddn = ldb_dn_rebase_remote(request, data, request->op.rename.olddn); - request->op.rename.newdn = ldb_dn_rebase_remote(request, data, request->op.rename.newdn); - break; - - default: - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "Invalid remote request!"); - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_request(module, request); -} - - -/* Finding mappings for attributes and objectClasses - * ================================================= */ - -/* Find an objectClass mapping by the local name. */ -static const struct ldb_map_objectclass *map_objectclass_find_local(const struct ldb_map_context *data, const char *name) -{ - unsigned int i; - - for (i = 0; data->objectclass_maps && data->objectclass_maps[i].local_name; i++) { - if (ldb_attr_cmp(data->objectclass_maps[i].local_name, name) == 0) { - return &data->objectclass_maps[i]; - } - } - - return NULL; -} - -/* Find an objectClass mapping by the remote name. */ -static const struct ldb_map_objectclass *map_objectclass_find_remote(const struct ldb_map_context *data, const char *name) -{ - unsigned int i; - - for (i = 0; data->objectclass_maps && data->objectclass_maps[i].remote_name; i++) { - if (ldb_attr_cmp(data->objectclass_maps[i].remote_name, name) == 0) { - return &data->objectclass_maps[i]; - } - } - - return NULL; -} - -/* Find an attribute mapping by the local name. */ -const struct ldb_map_attribute *map_attr_find_local(const struct ldb_map_context *data, const char *name) -{ - unsigned int i; - - for (i = 0; data->attribute_maps[i].local_name; i++) { - if (ldb_attr_cmp(data->attribute_maps[i].local_name, name) == 0) { - return &data->attribute_maps[i]; - } - } - for (i = 0; data->attribute_maps[i].local_name; i++) { - if (ldb_attr_cmp(data->attribute_maps[i].local_name, "*") == 0) { - return &data->attribute_maps[i]; - } - } - - return NULL; -} - -/* Find an attribute mapping by the remote name. */ -const struct ldb_map_attribute *map_attr_find_remote(const struct ldb_map_context *data, const char *name) -{ - const struct ldb_map_attribute *map; - const struct ldb_map_attribute *wildcard = NULL; - unsigned int i, j; - - for (i = 0; data->attribute_maps[i].local_name; i++) { - map = &data->attribute_maps[i]; - if (ldb_attr_cmp(map->local_name, "*") == 0) { - wildcard = &data->attribute_maps[i]; - } - - switch (map->type) { - case LDB_MAP_IGNORE: - break; - - case LDB_MAP_KEEP: - if (ldb_attr_cmp(map->local_name, name) == 0) { - return map; - } - break; - - case LDB_MAP_RENAME: - case LDB_MAP_RENDROP: - case LDB_MAP_CONVERT: - if (ldb_attr_cmp(map->u.rename.remote_name, name) == 0) { - return map; - } - break; - - case LDB_MAP_GENERATE: - for (j = 0; map->u.generate.remote_names[j]; j++) { - if (ldb_attr_cmp(map->u.generate.remote_names[j], name) == 0) { - return map; - } - } - break; - } - } - - /* We didn't find it, so return the wildcard record if one was configured */ - return wildcard; -} - - -/* Mapping attributes - * ================== */ - -/* Check whether an attribute will be mapped into the remote partition. */ -bool map_attr_check_remote(const struct ldb_map_context *data, const char *attr) -{ - const struct ldb_map_attribute *map = map_attr_find_local(data, attr); - - if (map == NULL) { - return false; - } - if (map->type == LDB_MAP_IGNORE) { - return false; - } - - return true; -} - -/* Map an attribute name into the remote partition. */ -const char *map_attr_map_local(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr) -{ - if (map == NULL) { - return talloc_strdup(mem_ctx, attr); - } - - switch (map->type) { - case LDB_MAP_KEEP: - return talloc_strdup(mem_ctx, attr); - - case LDB_MAP_RENAME: - case LDB_MAP_RENDROP: - case LDB_MAP_CONVERT: - return talloc_strdup(mem_ctx, map->u.rename.remote_name); - - default: - return NULL; - } -} - -/* Map an attribute name back into the local partition. */ -const char *map_attr_map_remote(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr) -{ - if (map == NULL) { - return talloc_strdup(mem_ctx, attr); - } - - if (map->type == LDB_MAP_KEEP) { - return talloc_strdup(mem_ctx, attr); - } - - return talloc_strdup(mem_ctx, map->local_name); -} - - -/* Merge two lists of attributes into a single one. */ -int map_attrs_merge(struct ldb_module *module, void *mem_ctx, - const char ***attrs, const char * const *more_attrs) -{ - unsigned int i, j, k; - - for (i = 0; *attrs && (*attrs)[i]; i++) /* noop */ ; - for (j = 0; more_attrs && more_attrs[j]; j++) /* noop */ ; - - *attrs = talloc_realloc(mem_ctx, *attrs, const char *, i+j+1); - if (*attrs == NULL) { - map_oom(module); - return -1; - } - - for (k = 0; k < j; k++) { - (*attrs)[i + k] = more_attrs[k]; - } - - (*attrs)[i+k] = NULL; - - return 0; -} - -/* Mapping ldb values - * ================== */ - -/* Map an ldb value into the remote partition. */ -struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, - const struct ldb_map_attribute *map, const struct ldb_val *val) -{ - if (map && (map->type == LDB_MAP_CONVERT) && (map->u.convert.convert_local)) { - return map->u.convert.convert_local(module, mem_ctx, val); - } - - return ldb_val_dup(mem_ctx, val); -} - -/* Map an ldb value back into the local partition. */ -struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, - const struct ldb_map_attribute *map, const struct ldb_val *val) -{ - if (map && (map->type == LDB_MAP_CONVERT) && (map->u.convert.convert_remote)) { - return map->u.convert.convert_remote(module, mem_ctx, val); - } - - return ldb_val_dup(mem_ctx, val); -} - - -/* Mapping DNs - * =========== */ - -/* Check whether a DN is below the local baseDN. */ -bool ldb_dn_check_local(struct ldb_module *module, struct ldb_dn *dn) -{ - const struct ldb_map_context *data = map_get_context(module); - - if (!data->local_base_dn) { - return true; - } - - return ldb_dn_compare_base(data->local_base_dn, dn) == 0; -} - -/* Map a DN into the remote partition. */ -struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn) -{ - const struct ldb_map_context *data = map_get_context(module); - struct ldb_context *ldb; - struct ldb_dn *newdn; - const struct ldb_map_attribute *map; - enum ldb_map_attr_type map_type; - const char *name; - struct ldb_val value; - int i, ret; - - if (dn == NULL) { - return NULL; - } - - ldb = ldb_module_get_ctx(module); - - newdn = ldb_dn_copy(mem_ctx, dn); - if (newdn == NULL) { - map_oom(module); - return NULL; - } - - /* For each RDN, map the component name and possibly the value */ - for (i = 0; i < ldb_dn_get_comp_num(newdn); i++) { - map = map_attr_find_local(data, ldb_dn_get_component_name(dn, i)); - - /* Unknown attribute - leave this RDN as is and hope the best... */ - if (map == NULL) { - map_type = LDB_MAP_KEEP; - } else { - map_type = map->type; - } - - switch (map_type) { - case LDB_MAP_IGNORE: - case LDB_MAP_GENERATE: - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "LDB_MAP_IGNORE/LDB_MAP_GENERATE attribute '%s' " - "used in DN!", ldb_dn_get_component_name(dn, i)); - goto failed; - - case LDB_MAP_CONVERT: - if (map->u.convert.convert_local == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "'convert_local' not set for attribute '%s' " - "used in DN!", ldb_dn_get_component_name(dn, i)); - goto failed; - } - - FALL_THROUGH; - case LDB_MAP_KEEP: - case LDB_MAP_RENAME: - case LDB_MAP_RENDROP: - name = map_attr_map_local(newdn, map, ldb_dn_get_component_name(dn, i)); - if (name == NULL) goto failed; - - value = ldb_val_map_local(module, newdn, map, ldb_dn_get_component_val(dn, i)); - if (value.data == NULL) goto failed; - - ret = ldb_dn_set_component(newdn, i, name, value); - if (ret != LDB_SUCCESS) { - goto failed; - } - - break; - } - } - - return newdn; - -failed: - talloc_free(newdn); - return NULL; -} - -/* Map a DN into the local partition. */ -struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn) -{ - const struct ldb_map_context *data = map_get_context(module); - struct ldb_context *ldb; - struct ldb_dn *newdn; - const struct ldb_map_attribute *map; - enum ldb_map_attr_type map_type; - const char *name; - struct ldb_val value; - int i, ret; - - if (dn == NULL) { - return NULL; - } - - ldb = ldb_module_get_ctx(module); - - newdn = ldb_dn_copy(mem_ctx, dn); - if (newdn == NULL) { - map_oom(module); - return NULL; - } - - /* For each RDN, map the component name and possibly the value */ - for (i = 0; i < ldb_dn_get_comp_num(newdn); i++) { - map = map_attr_find_remote(data, ldb_dn_get_component_name(dn, i)); - - /* Unknown attribute - leave this RDN as is and hope the best... */ - if (map == NULL) { - map_type = LDB_MAP_KEEP; - } else { - map_type = map->type; - } - - switch (map_type) { - case LDB_MAP_IGNORE: - case LDB_MAP_GENERATE: - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "LDB_MAP_IGNORE/LDB_MAP_GENERATE attribute '%s' " - "used in DN!", ldb_dn_get_component_name(dn, i)); - goto failed; - - case LDB_MAP_CONVERT: - if (map->u.convert.convert_remote == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "'convert_remote' not set for attribute '%s' " - "used in DN!", ldb_dn_get_component_name(dn, i)); - goto failed; - } - - FALL_THROUGH; - case LDB_MAP_KEEP: - case LDB_MAP_RENAME: - case LDB_MAP_RENDROP: - name = map_attr_map_remote(newdn, map, ldb_dn_get_component_name(dn, i)); - if (name == NULL) goto failed; - - value = ldb_val_map_remote(module, newdn, map, ldb_dn_get_component_val(dn, i)); - if (value.data == NULL) goto failed; - - ret = ldb_dn_set_component(newdn, i, name, value); - if (ret != LDB_SUCCESS) { - goto failed; - } - - break; - } - } - - return newdn; - -failed: - talloc_free(newdn); - return NULL; -} - -/* Map a DN and its base into the local partition. */ -/* TODO: This should not be required with GUIDs. */ -struct ldb_dn *ldb_dn_map_rebase_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn) -{ - const struct ldb_map_context *data = map_get_context(module); - struct ldb_dn *dn1, *dn2; - - dn1 = ldb_dn_rebase_local(mem_ctx, data, dn); - dn2 = ldb_dn_map_remote(module, mem_ctx, dn1); - - talloc_free(dn1); - return dn2; -} - - -/* Converting DNs and objectClasses (as ldb values) - * ================================================ */ - -/* Map a DN contained in an ldb value into the remote partition. */ -static struct ldb_val ldb_dn_convert_local(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) -{ - struct ldb_context *ldb; - struct ldb_dn *dn, *newdn; - struct ldb_val newval; - - ldb = ldb_module_get_ctx(module); - - dn = ldb_dn_from_ldb_val(mem_ctx, ldb, val); - if (! ldb_dn_validate(dn)) { - newval.length = 0; - newval.data = NULL; - talloc_free(dn); - return newval; - } - newdn = ldb_dn_map_local(module, mem_ctx, dn); - talloc_free(dn); - - newval.length = 0; - newval.data = (uint8_t *)ldb_dn_alloc_linearized(mem_ctx, newdn); - if (newval.data) { - newval.length = strlen((char *)newval.data); - } - talloc_free(newdn); - - return newval; -} - -/* Map a DN contained in an ldb value into the local partition. */ -static struct ldb_val ldb_dn_convert_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) -{ - struct ldb_context *ldb; - struct ldb_dn *dn, *newdn; - struct ldb_val newval; - - ldb = ldb_module_get_ctx(module); - - dn = ldb_dn_from_ldb_val(mem_ctx, ldb, val); - if (! ldb_dn_validate(dn)) { - newval.length = 0; - newval.data = NULL; - talloc_free(dn); - return newval; - } - newdn = ldb_dn_map_remote(module, mem_ctx, dn); - talloc_free(dn); - - newval.length = 0; - newval.data = (uint8_t *)ldb_dn_alloc_linearized(mem_ctx, newdn); - if (newval.data) { - newval.length = strlen((char *)newval.data); - } - talloc_free(newdn); - - return newval; -} - -/* Map an objectClass into the remote partition. */ -static struct ldb_val map_objectclass_convert_local(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) -{ - const struct ldb_map_context *data = map_get_context(module); - const char *name = (char *)val->data; - const struct ldb_map_objectclass *map = map_objectclass_find_local(data, name); - struct ldb_val newval; - - if (map) { - newval.data = (uint8_t*)talloc_strdup(mem_ctx, map->remote_name); - newval.length = strlen((char *)newval.data); - return newval; - } - - return ldb_val_dup(mem_ctx, val); -} - -/* Generate a remote message with a mapped objectClass. */ -static void map_objectclass_generate_remote(struct ldb_module *module, const char *local_attr, const struct ldb_message *old, struct ldb_message *remote, struct ldb_message *local) -{ - const struct ldb_map_context *data = map_get_context(module); - struct ldb_context *ldb; - struct ldb_message_element *el, *oc; - struct ldb_val val; - bool found_extensibleObject = false; - unsigned int i; - int ret; - - ldb = ldb_module_get_ctx(module); - - /* Find old local objectClass */ - oc = ldb_msg_find_element(old, "objectClass"); - if (oc == NULL) { - return; - } - - /* Prepare new element */ - el = talloc_zero(remote, struct ldb_message_element); - if (el == NULL) { - ldb_oom(ldb); - return; /* TODO: fail? */ - } - - /* Copy local objectClass element, reverse space for an extra value */ - el->num_values = oc->num_values + 1; - el->values = talloc_array(el, struct ldb_val, el->num_values); - if (el->values == NULL) { - talloc_free(el); - ldb_oom(ldb); - return; /* TODO: fail? */ - } - - /* Copy local element name "objectClass" */ - el->name = talloc_strdup(el, local_attr); - - /* Convert all local objectClasses */ - for (i = 0; i < el->num_values - 1; i++) { - el->values[i] = map_objectclass_convert_local(module, el->values, &oc->values[i]); - if (ldb_attr_cmp((char *)el->values[i].data, data->add_objectclass) == 0) { - found_extensibleObject = true; - } - } - - if (!found_extensibleObject) { - val.data = (uint8_t *)talloc_strdup(el->values, data->add_objectclass); - val.length = strlen((char *)val.data); - - /* Append additional objectClass data->add_objectclass */ - el->values[i] = val; - } else { - el->num_values--; - } - - /* Add new objectClass to remote message */ - ret = ldb_msg_add(remote, el, 0); - if (ret != LDB_SUCCESS) { - ldb_oom(ldb); - return; - } -} - -/* Map an objectClass into the local partition. */ -static struct ldb_val map_objectclass_convert_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_val *val) -{ - const struct ldb_map_context *data = map_get_context(module); - const char *name = (char *)val->data; - const struct ldb_map_objectclass *map = map_objectclass_find_remote(data, name); - struct ldb_val newval; - - if (map) { - newval.data = (uint8_t*)talloc_strdup(mem_ctx, map->local_name); - newval.length = strlen((char *)newval.data); - return newval; - } - - return ldb_val_dup(mem_ctx, val); -} - -/* Generate a local message with a mapped objectClass. */ -static struct ldb_message_element *map_objectclass_generate_local(struct ldb_module *module, void *mem_ctx, const char *local_attr, const struct ldb_message *remote) -{ - const struct ldb_map_context *data = map_get_context(module); - struct ldb_context *ldb; - struct ldb_message_element *el, *oc; - struct ldb_val val; - unsigned int i; - - ldb = ldb_module_get_ctx(module); - - /* Find old remote objectClass */ - oc = ldb_msg_find_element(remote, "objectClass"); - if (oc == NULL) { - return NULL; - } - - /* Prepare new element */ - el = talloc_zero(mem_ctx, struct ldb_message_element); - if (el == NULL) { - ldb_oom(ldb); - return NULL; - } - - /* Copy remote objectClass element */ - el->num_values = oc->num_values; - el->values = talloc_array(el, struct ldb_val, el->num_values); - if (el->values == NULL) { - talloc_free(el); - ldb_oom(ldb); - return NULL; - } - - /* Copy remote element name "objectClass" */ - el->name = talloc_strdup(el, local_attr); - - /* Convert all remote objectClasses */ - for (i = 0; i < el->num_values; i++) { - el->values[i] = map_objectclass_convert_remote(module, el->values, &oc->values[i]); - } - - val.data = (uint8_t *)talloc_strdup(el->values, data->add_objectclass); - val.length = strlen((char *)val.data); - - /* Remove last value if it was the string in data->add_objectclass (eg samba4top, extensibleObject) */ - if (ldb_val_equal_exact(&val, &el->values[i-1])) { - el->num_values--; - el->values = talloc_realloc(el, el->values, struct ldb_val, el->num_values); - if (el->values == NULL) { - talloc_free(el); - ldb_oom(ldb); - return NULL; - } - } - - return el; -} - -static const struct ldb_map_attribute objectclass_convert_map = { - .local_name = "objectClass", - .type = LDB_MAP_CONVERT, - .u = { - .convert = { - .remote_name = "objectClass", - .convert_local = map_objectclass_convert_local, - .convert_remote = map_objectclass_convert_remote, - }, - }, -}; - - -/* Mappings for searches on objectClass= assuming a one-to-one - * mapping. Needed because this is a generate operator for the - * add/modify code */ -static int map_objectclass_convert_operator(struct ldb_module *module, void *mem_ctx, - struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - - return map_subtree_collect_remote_simple(module, mem_ctx, new, tree, &objectclass_convert_map); -} - -/* Auxiliary request construction - * ============================== */ - -/* Build a request to search a record by its DN. */ -struct ldb_request *map_search_base_req(struct map_context *ac, struct ldb_dn *dn, const char * const *attrs, struct ldb_parse_tree *tree, void *context, ldb_map_callback_t callback) -{ - struct ldb_parse_tree *search_tree; - struct ldb_context *ldb; - struct ldb_request *req; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - if (tree) { - search_tree = tree; - } else { - search_tree = ldb_parse_tree(ac, NULL); - if (search_tree == NULL) { - return NULL; - } - } - - ret = ldb_build_search_req_ex(&req, ldb, ac, - dn, LDB_SCOPE_BASE, - search_tree, attrs, - NULL, - context, callback, - ac->req); - LDB_REQ_SET_LOCATION(req); - if (ret != LDB_SUCCESS) { - return NULL; - } - - return req; -} - -/* Build a request to update the 'IS_MAPPED' attribute */ -struct ldb_request *map_build_fixup_req(struct map_context *ac, - struct ldb_dn *olddn, - struct ldb_dn *newdn, - void *context, - ldb_map_callback_t callback) -{ - struct ldb_context *ldb; - struct ldb_request *req; - struct ldb_message *msg; - const char *dn; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - /* Prepare message */ - msg = ldb_msg_new(ac); - if (msg == NULL) { - map_oom(ac->module); - return NULL; - } - - /* Update local 'IS_MAPPED' to the new remote DN */ - msg->dn = ldb_dn_copy(msg, olddn); - dn = ldb_dn_alloc_linearized(msg, newdn); - if ( ! dn || ! ldb_dn_validate(msg->dn)) { - goto failed; - } - if (ldb_msg_add_empty(msg, IS_MAPPED, LDB_FLAG_MOD_REPLACE, NULL) != 0) { - goto failed; - } - if (ldb_msg_add_string(msg, IS_MAPPED, dn) != 0) { - goto failed; - } - - /* Prepare request */ - ret = ldb_build_mod_req(&req, ldb, - ac, msg, NULL, - context, callback, - ac->req); - LDB_REQ_SET_LOCATION(req); - if (ret != LDB_SUCCESS) { - goto failed; - } - talloc_steal(req, msg); - - return req; -failed: - talloc_free(msg); - return NULL; -} - -/* Module initialization - * ===================== */ - - -/* Builtin mappings for DNs and objectClasses */ -static const struct ldb_map_attribute builtin_attribute_maps[] = { - { - .local_name = "dn", - .type = LDB_MAP_CONVERT, - .u = { - .convert = { - .remote_name = "dn", - .convert_local = ldb_dn_convert_local, - .convert_remote = ldb_dn_convert_remote, - }, - }, - }, - { - .local_name = NULL, - } -}; - -static const struct ldb_map_attribute objectclass_attribute_map = { - .local_name = "objectClass", - .type = LDB_MAP_GENERATE, - .convert_operator = map_objectclass_convert_operator, - .u = { - .generate = { - .remote_names = { "objectClass", NULL }, - .generate_local = map_objectclass_generate_local, - .generate_remote = map_objectclass_generate_remote, - }, - }, -}; - - -/* Find the special 'MAP_DN_NAME' record and store local and remote - * base DNs in private data. */ -static int map_init_dns(struct ldb_module *module, struct ldb_map_context *data, const char *name) -{ - static const char * const attrs[] = { MAP_DN_FROM, MAP_DN_TO, NULL }; - struct ldb_context *ldb; - struct ldb_dn *dn; - struct ldb_message *msg; - struct ldb_result *res; - int ret; - - if (!name) { - data->local_base_dn = NULL; - data->remote_base_dn = NULL; - return LDB_SUCCESS; - } - - ldb = ldb_module_get_ctx(module); - - dn = ldb_dn_new_fmt(data, ldb, "%s=%s", MAP_DN_NAME, name); - if ( ! ldb_dn_validate(dn)) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "Failed to construct '%s' DN!", MAP_DN_NAME); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_search(ldb, data, &res, dn, LDB_SCOPE_BASE, attrs, NULL); - talloc_free(dn); - if (ret != LDB_SUCCESS) { - return ret; - } - if (res->count == 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "No results for '%s=%s'!", MAP_DN_NAME, name); - talloc_free(res); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - if (res->count > 1) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "Too many results for '%s=%s'!", MAP_DN_NAME, name); - talloc_free(res); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - - msg = res->msgs[0]; - data->local_base_dn = ldb_msg_find_attr_as_dn(ldb, data, msg, MAP_DN_FROM); - data->remote_base_dn = ldb_msg_find_attr_as_dn(ldb, data, msg, MAP_DN_TO); - talloc_free(res); - - return LDB_SUCCESS; -} - -/* Store attribute maps and objectClass maps in private data. */ -static int map_init_maps(struct ldb_module *module, struct ldb_map_context *data, - const struct ldb_map_attribute *attrs, - const struct ldb_map_objectclass *ocls, - const char * const *wildcard_attributes) -{ - unsigned int i, j, last; - last = 0; - - /* Count specified attribute maps */ - for (i = 0; attrs[i].local_name; i++) /* noop */ ; - /* Count built-in attribute maps */ - for (j = 0; builtin_attribute_maps[j].local_name; j++) /* noop */ ; - - /* Store list of attribute maps */ - data->attribute_maps = talloc_array(data, struct ldb_map_attribute, i+j+2); - if (data->attribute_maps == NULL) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Specified ones go first */ - for (i = 0; attrs[i].local_name; i++) { - data->attribute_maps[last] = attrs[i]; - last++; - } - - /* Built-in ones go last */ - for (i = 0; builtin_attribute_maps[i].local_name; i++) { - data->attribute_maps[last] = builtin_attribute_maps[i]; - last++; - } - - if (data->add_objectclass) { - /* ObjectClass one is very last, if required */ - data->attribute_maps[last] = objectclass_attribute_map; - last++; - } else if (ocls) { - data->attribute_maps[last] = objectclass_convert_map; - last++; - } - - /* Ensure 'local_name == NULL' for the last entry */ - memset(&data->attribute_maps[last], 0, sizeof(struct ldb_map_attribute)); - - /* Store list of objectClass maps */ - data->objectclass_maps = ocls; - - data->wildcard_attributes = wildcard_attributes; - - return LDB_SUCCESS; -} - -/* Initialize global private data. */ -_PUBLIC_ int ldb_map_init(struct ldb_module *module, const struct ldb_map_attribute *attrs, - const struct ldb_map_objectclass *ocls, - const char * const *wildcard_attributes, - const char *add_objectclass, - const char *name) -{ - struct map_private *data; - int ret; - - /* Prepare private data */ - data = talloc_zero(module, struct map_private); - if (data == NULL) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - ldb_module_set_private(module, data); - - data->context = talloc_zero(data, struct ldb_map_context); - if (!data->context) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Store local and remote baseDNs */ - ret = map_init_dns(module, data->context, name); - if (ret != LDB_SUCCESS) { - talloc_free(data); - return ret; - } - - data->context->add_objectclass = add_objectclass; - - /* Store list of attribute and objectClass maps */ - ret = map_init_maps(module, data->context, attrs, ocls, wildcard_attributes); - if (ret != LDB_SUCCESS) { - talloc_free(data); - return ret; - } - - return LDB_SUCCESS; -} diff --git a/ldb-2.0.8/ldb_map/ldb_map.h b/ldb-2.0.8/ldb_map/ldb_map.h deleted file mode 100644 index 46ef3cc..0000000 --- a/ldb-2.0.8/ldb_map/ldb_map.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - ldb database mapping module - - Copyright (C) Jelmer Vernooij 2005 - Copyright (C) Martin Kuehl 2006 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifndef __LDB_MAP_H__ -#define __LDB_MAP_H__ - -#include "ldb_module.h" - -/* ldb_map is a skeleton LDB module that can be used for any other modules - * that need to map attributes. - * - * The term 'remote' in this header refers to the connection where the - * original schema is used on while 'local' means the local connection - * that any upper layers will use. - * - * All local attributes will have to have a definition. Not all remote - * attributes need a definition as LDB is a lot less strict than LDAP - * (in other words, sending unknown attributes to an LDAP server hurts us, - * while returning too many attributes in ldb_search() doesn't) - */ - - -/* Name of the internal attribute pointing from the local to the - * remote part of a record */ -#define IS_MAPPED "isMapped" - - -struct ldb_map_context; - -/* convert a local ldb_val to a remote ldb_val */ -typedef struct ldb_val (*ldb_map_convert_func) (struct ldb_module *module, void *mem_ctx, const struct ldb_val *val); - -#define LDB_MAP_MAX_REMOTE_NAMES 10 - -/* map from local to remote attribute */ -struct ldb_map_attribute { - const char *local_name; /* local name */ - - enum ldb_map_attr_type { - LDB_MAP_IGNORE, /* Ignore this local attribute. Doesn't exist remotely. */ - LDB_MAP_KEEP, /* Keep as is. Same name locally and remotely. */ - LDB_MAP_RENAME, /* Simply rename the attribute. Name changes, data is the same */ - LDB_MAP_CONVERT, /* Rename + convert data */ - LDB_MAP_GENERATE, /* Use generate function for generating new name/data. - Used for generating attributes based on - multiple remote attributes. */ - LDB_MAP_RENDROP /* Rename the attribute. Strip from Add requests. */ - } type; - - /* if set, will be called for search expressions that contain this attribute */ - int (*convert_operator)(struct ldb_module *, TALLOC_CTX *ctx, struct ldb_parse_tree **ntree, const struct ldb_parse_tree *otree); - - union { - struct { - const char *remote_name; - } rename; - - struct { - const char *remote_name; - - /* Convert local to remote data */ - ldb_map_convert_func convert_local; - - /* Convert remote to local data */ - /* an entry can have convert_remote set to NULL, as long as there as an entry with the same local_name - * that is non-NULL before it. */ - ldb_map_convert_func convert_remote; - } convert; - - struct { - /* Generate the local attribute from remote message */ - struct ldb_message_element *(*generate_local)(struct ldb_module *, TALLOC_CTX *mem_ctx, const char *remote_attr, const struct ldb_message *remote); - - /* Update remote message with information from local message */ - void (*generate_remote)(struct ldb_module *, const char *local_attr, const struct ldb_message *old, struct ldb_message *remote, struct ldb_message *local); - - /* Name(s) for this attribute on the remote server. This is an array since - * one local attribute's data can be split up into several attributes - * remotely */ - const char *remote_names[LDB_MAP_MAX_REMOTE_NAMES]; - - /* Names of additional remote attributes - * required for the generation. NULL - * indicates that `local_attr' suffices. */ - /* -#define LDB_MAP_MAX_SELF_ATTRIBUTES 10 - const char *self_attrs[LDB_MAP_MAX_SELF_ATTRIBUTES]; - */ - } generate; - } u; -}; - - -#define LDB_MAP_MAX_SUBCLASSES 10 -#define LDB_MAP_MAX_MUSTS 10 -#define LDB_MAP_MAX_MAYS 50 - -/* map from local to remote objectClass */ -struct ldb_map_objectclass { - const char *local_name; - const char *remote_name; - const char *base_classes[LDB_MAP_MAX_SUBCLASSES]; - const char *musts[LDB_MAP_MAX_MUSTS]; - const char *mays[LDB_MAP_MAX_MAYS]; -}; - - -/* private context data */ -struct ldb_map_context { - struct ldb_map_attribute *attribute_maps; - /* NOTE: Always declare base classes first here */ - const struct ldb_map_objectclass *objectclass_maps; - - /* Remote (often operational) attributes that should be added - * to any wildcard search */ - const char * const *wildcard_attributes; - - /* ObjectClass (if any) to be added to remote attributes on add */ - const char *add_objectclass; - - /* struct ldb_context *mapped_ldb; */ - struct ldb_dn *local_base_dn; - struct ldb_dn *remote_base_dn; -}; - -/* Global private data */ -struct map_private { - void *caller_private; - struct ldb_map_context *context; -}; - -/* Initialize global private data. */ -int ldb_map_init(struct ldb_module *module, const struct ldb_map_attribute *attrs, - const struct ldb_map_objectclass *ocls, - const char * const *wildcard_attributes, - const char *add_objectclass, - const char *name); - -int ldb_map_add(struct ldb_module *module, struct ldb_request *req); -int ldb_map_search(struct ldb_module *module, struct ldb_request *req); -int ldb_map_rename(struct ldb_module *module, struct ldb_request *req); -int ldb_map_delete(struct ldb_module *module, struct ldb_request *req); -int ldb_map_modify(struct ldb_module *module, struct ldb_request *req); - -#define LDB_MAP_OPS \ - .add = ldb_map_add, \ - .modify = ldb_map_modify, \ - .del = ldb_map_delete, \ - .rename = ldb_map_rename, \ - .search = ldb_map_search, - -#endif /* __LDB_MAP_H__ */ diff --git a/ldb-2.0.8/ldb_map/ldb_map_inbound.c b/ldb-2.0.8/ldb_map/ldb_map_inbound.c deleted file mode 100644 index 861c4c1..0000000 --- a/ldb-2.0.8/ldb_map/ldb_map_inbound.c +++ /dev/null @@ -1,846 +0,0 @@ -/* - ldb database mapping module - - Copyright (C) Jelmer Vernooij 2005 - Copyright (C) Martin Kuehl 2006 - Copyright (C) Simo Sorce 2008 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb_map.h" -#include "ldb_map_private.h" - - -/* Mapping message elements - * ======================== */ - -/* Map a message element into the remote partition. */ -static struct ldb_message_element *ldb_msg_el_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_message_element *old) -{ - struct ldb_message_element *el; - unsigned int i; - - el = talloc_zero(mem_ctx, struct ldb_message_element); - if (el == NULL) { - map_oom(module); - return NULL; - } - - el->num_values = old->num_values; - el->values = talloc_array(el, struct ldb_val, el->num_values); - if (el->values == NULL) { - talloc_free(el); - map_oom(module); - return NULL; - } - - el->name = map_attr_map_local(el, map, old->name); - - for (i = 0; i < el->num_values; i++) { - el->values[i] = ldb_val_map_local(module, el->values, map, &old->values[i]); - } - - return el; -} - -/* Add a message element either to a local or to a remote message, - * depending on whether it goes into the local or remote partition. */ -static int ldb_msg_el_partition(struct ldb_module *module, enum ldb_request_type optype, struct ldb_message *local, struct ldb_message *remote, const struct ldb_message *msg, const char *attr_name, /* const char * const names[], */ const struct ldb_message_element *old) -{ - const struct ldb_map_context *data = map_get_context(module); - const struct ldb_map_attribute *map = map_attr_find_local(data, attr_name); - struct ldb_message_element *el=NULL; - struct ldb_context *ldb = ldb_module_get_ctx(module); - - /* Unknown attribute: ignore */ - if (map == NULL) { - ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " - "Not mapping attribute '%s': no mapping found", - old->name); - goto local; - } - - switch (map->type) { - case LDB_MAP_RENDROP: - if (optype != LDB_ADD) { - /* do the same as LDB_MAP_RENAME */ - el = ldb_msg_el_map_local(module, remote, map, old); - break; - } - - FALL_THROUGH; - case LDB_MAP_IGNORE: - goto local; - - case LDB_MAP_CONVERT: - if (map->u.convert.convert_local == NULL) { - ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " - "Not mapping attribute '%s': " - "'convert_local' not set", - map->local_name); - goto local; - } - - FALL_THROUGH; - case LDB_MAP_KEEP: - case LDB_MAP_RENAME: - el = ldb_msg_el_map_local(module, remote, map, old); - break; - - case LDB_MAP_GENERATE: - if (map->u.generate.generate_remote == NULL) { - ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " - "Not mapping attribute '%s': " - "'generate_remote' not set", - map->local_name); - goto local; - } - - /* TODO: if this attr requires context: - * make sure all context attrs are mappable (in 'names') - * make sure all context attrs have already been mapped? - * maybe postpone generation until they have been mapped? - */ - - map->u.generate.generate_remote(module, map->local_name, msg, remote, local); - return 0; - } - - if (el == NULL) { - return -1; - } - - return ldb_msg_add(remote, el, old->flags); - -local: - el = talloc(local, struct ldb_message_element); - if (el == NULL) { - map_oom(module); - return -1; - } - - *el = *old; /* copy the old element */ - - return ldb_msg_add(local, el, old->flags); -} - -/* Mapping messages - * ================ */ - -/* Check whether a message will be (partially) mapped into the remote partition. */ -static bool ldb_msg_check_remote(struct ldb_module *module, const struct ldb_message *msg) -{ - const struct ldb_map_context *data = map_get_context(module); - bool ret; - unsigned int i; - - for (i = 0; i < msg->num_elements; i++) { - ret = map_attr_check_remote(data, msg->elements[i].name); - if (ret) { - return ret; - } - } - - return false; -} - -/* Split message elements that stay in the local partition from those - * that are mapped into the remote partition. */ -static int ldb_msg_partition(struct ldb_module *module, enum ldb_request_type optype, struct ldb_message *local, struct ldb_message *remote, const struct ldb_message *msg) -{ - /* const char * const names[]; */ - struct ldb_context *ldb; - unsigned int i; - int ret; - - ldb = ldb_module_get_ctx(module); - - for (i = 0; i < msg->num_elements; i++) { - /* Skip 'IS_MAPPED' */ - if (ldb_attr_cmp(msg->elements[i].name, IS_MAPPED) == 0) { - ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " - "Skipping attribute '%s'", - msg->elements[i].name); - continue; - } - - ret = ldb_msg_el_partition(module, optype, local, remote, msg, msg->elements[i].name, &msg->elements[i]); - if (ret) { - return ret; - } - } - - return 0; -} - - -static int map_add_do_local(struct map_context *ac); -static int map_modify_do_local(struct map_context *ac); -static int map_delete_do_local(struct map_context *ac); -static int map_rename_do_local(struct map_context *ac); -static int map_rename_do_fixup(struct map_context *ac); -static int map_rename_local_callback(struct ldb_request *req, - struct ldb_reply *ares); - - -/***************************************************************************** - * COMMON INBOUND functions -*****************************************************************************/ - -/* Store the DN of a single search result in context. */ -static int map_search_self_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct ldb_context *ldb; - struct map_context *ac; - int ret; - - ac = talloc_get_type(req->context, struct map_context); - ldb = ldb_module_get_ctx(ac->module); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - /* We are interested only in the single reply */ - switch(ares->type) { - case LDB_REPLY_ENTRY: - /* We have already found a remote DN */ - if (ac->local_dn) { - ldb_set_errstring(ldb, - "Too many results!"); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - /* Store local DN */ - ac->local_dn = talloc_steal(ac, ares->message->dn); - break; - - case LDB_REPLY_DONE: - - switch (ac->req->operation) { - case LDB_MODIFY: - ret = map_modify_do_local(ac); - break; - case LDB_DELETE: - ret = map_delete_do_local(ac); - break; - case LDB_RENAME: - ret = map_rename_do_local(ac); - break; - default: - /* if we get here we have definitely a problem */ - ret = LDB_ERR_OPERATIONS_ERROR; - } - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - default: - /* ignore referrals */ - break; - } - - talloc_free(ares); - return LDB_SUCCESS; -} - -/* Build a request to search the local record by its DN. */ -static int map_search_self_req(struct ldb_request **req, - struct map_context *ac, - struct ldb_dn *dn) -{ - /* attrs[] is returned from this function in - * ac->search_req->op.search.attrs, so it must be static, as - * otherwise the compiler can put it on the stack */ - static const char * const attrs[] = { IS_MAPPED, NULL }; - struct ldb_parse_tree *tree; - - /* Limit search to records with 'IS_MAPPED' present */ - tree = ldb_parse_tree(ac, "(" IS_MAPPED "=*)"); - if (tree == NULL) { - map_oom(ac->module); - return LDB_ERR_OPERATIONS_ERROR; - } - - *req = map_search_base_req(ac, dn, attrs, tree, - ac, map_search_self_callback); - if (*req == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return LDB_SUCCESS; -} - -static int map_op_local_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct ldb_context *ldb; - struct map_context *ac; - int ret; - - ac = talloc_get_type(req->context, struct map_context); - ldb = ldb_module_get_ctx(ac->module); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - if (ares->type != LDB_REPLY_DONE) { - ldb_asprintf_errstring(ldb, "Invalid LDB reply type %d", ares->type); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - /* Do the remote request. */ - ret = ldb_next_remote_request(ac->module, ac->remote_req); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - return LDB_SUCCESS; -} - -static int map_op_remote_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct ldb_context *ldb; - struct map_context *ac; - - ac = talloc_get_type(req->context, struct map_context); - ldb = ldb_module_get_ctx(ac->module); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - if (ares->type != LDB_REPLY_DONE) { - ldb_asprintf_errstring(ldb, "Invalid LDB reply type %d", ares->type); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); -} - - -/***************************************************************************** - * ADD operations -*****************************************************************************/ - - -/* Add a record. */ -int ldb_map_add(struct ldb_module *module, struct ldb_request *req) -{ - const struct ldb_message *msg = req->op.add.message; - struct ldb_context *ldb; - struct map_context *ac; - struct ldb_message *remote_msg; - int ret; - - ldb = ldb_module_get_ctx(module); - - /* Do not manipulate our control entries */ - if (ldb_dn_is_special(msg->dn)) { - return ldb_next_request(module, req); - } - - /* No mapping requested (perhaps no DN mapping specified), skip to next module */ - if (!ldb_dn_check_local(module, msg->dn)) { - return ldb_next_request(module, req); - } - - /* No mapping needed, fail */ - if (!ldb_msg_check_remote(module, msg)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Prepare context and handle */ - ac = map_init_context(module, req); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - - /* Prepare the local message */ - ac->local_msg = ldb_msg_new(ac); - if (ac->local_msg == NULL) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - ac->local_msg->dn = msg->dn; - - /* Prepare the remote message */ - remote_msg = ldb_msg_new(ac); - if (remote_msg == NULL) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - remote_msg->dn = ldb_dn_map_local(ac->module, remote_msg, msg->dn); - - /* Split local from remote message */ - ldb_msg_partition(module, req->operation, ac->local_msg, remote_msg, msg); - - /* Prepare the remote operation */ - ret = ldb_build_add_req(&ac->remote_req, ldb, - ac, remote_msg, - req->controls, - ac, map_op_remote_callback, - req); - LDB_REQ_SET_LOCATION(ac->remote_req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if ((ac->local_msg->num_elements == 0) || - ( ! map_check_local_db(ac->module))) { - /* No local data or db, just run the remote request */ - return ldb_next_remote_request(ac->module, ac->remote_req); - } - - /* Store remote DN in 'IS_MAPPED' */ - /* TODO: use GUIDs here instead */ - ret = ldb_msg_add_linearized_dn(ac->local_msg, IS_MAPPED, - remote_msg->dn); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return map_add_do_local(ac); -} - -/* Add the local record. */ -static int map_add_do_local(struct map_context *ac) -{ - struct ldb_request *local_req; - struct ldb_context *ldb; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - /* Prepare the local operation */ - ret = ldb_build_add_req(&local_req, ldb, ac, - ac->local_msg, - ac->req->controls, - ac, - map_op_local_callback, - ac->req); - LDB_REQ_SET_LOCATION(local_req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - return ldb_next_request(ac->module, local_req); -} - -/***************************************************************************** - * MODIFY operations -*****************************************************************************/ - -/* Modify a record. */ -int ldb_map_modify(struct ldb_module *module, struct ldb_request *req) -{ - const struct ldb_message *msg = req->op.mod.message; - struct ldb_request *search_req = NULL; - struct ldb_message *remote_msg; - struct ldb_context *ldb; - struct map_context *ac; - int ret; - - ldb = ldb_module_get_ctx(module); - - /* Do not manipulate our control entries */ - if (ldb_dn_is_special(msg->dn)) { - return ldb_next_request(module, req); - } - - /* No mapping requested (perhaps no DN mapping specified), skip to next module */ - if (!ldb_dn_check_local(module, msg->dn)) { - return ldb_next_request(module, req); - } - - /* No mapping needed, skip to next module */ - /* TODO: What if the remote part exists, the local doesn't, - * and this request wants to modify local data and thus - * add the local record? */ - if (!ldb_msg_check_remote(module, msg)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Prepare context and handle */ - ac = map_init_context(module, req); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Prepare the local message */ - ac->local_msg = ldb_msg_new(ac); - if (ac->local_msg == NULL) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - ac->local_msg->dn = msg->dn; - - /* Prepare the remote message */ - remote_msg = ldb_msg_new(ac->remote_req); - if (remote_msg == NULL) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - remote_msg->dn = ldb_dn_map_local(ac->module, remote_msg, msg->dn); - - /* Split local from remote message */ - ldb_msg_partition(module, req->operation, ac->local_msg, remote_msg, msg); - - /* Prepare the remote operation */ - ret = ldb_build_mod_req(&ac->remote_req, ldb, - ac, remote_msg, - req->controls, - ac, map_op_remote_callback, - req); - LDB_REQ_SET_LOCATION(ac->remote_req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if ((ac->local_msg->num_elements == 0) || - ( ! map_check_local_db(ac->module))) { - /* No local data or db, just run the remote request */ - return ldb_next_remote_request(ac->module, ac->remote_req); - } - - /* prepare the search operation */ - ret = map_search_self_req(&search_req, ac, msg->dn); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_request(module, search_req); -} - -/* Modify the local record. */ -static int map_modify_do_local(struct map_context *ac) -{ - struct ldb_request *local_req; - struct ldb_context *ldb; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - if (ac->local_dn == NULL) { - /* No local record present, add it instead */ - /* Add local 'IS_MAPPED' */ - /* TODO: use GUIDs here instead */ - if (ldb_msg_add_empty(ac->local_msg, IS_MAPPED, - LDB_FLAG_MOD_ADD, NULL) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - ret = ldb_msg_add_linearized_dn(ac->local_msg, IS_MAPPED, - ac->remote_req->op.mod.message->dn); - if (ret != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Prepare the local operation */ - ret = ldb_build_add_req(&local_req, ldb, ac, - ac->local_msg, - ac->req->controls, - ac, - map_op_local_callback, - ac->req); - LDB_REQ_SET_LOCATION(local_req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - } else { - /* Prepare the local operation */ - ret = ldb_build_mod_req(&local_req, ldb, ac, - ac->local_msg, - ac->req->controls, - ac, - map_op_local_callback, - ac->req); - LDB_REQ_SET_LOCATION(local_req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - } - - return ldb_next_request(ac->module, local_req); -} - -/***************************************************************************** - * DELETE operations -*****************************************************************************/ - -/* Delete a record. */ -int ldb_map_delete(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_request *search_req; - struct ldb_context *ldb; - struct map_context *ac; - int ret; - - ldb = ldb_module_get_ctx(module); - - /* Do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.del.dn)) { - return ldb_next_request(module, req); - } - - /* No mapping requested (perhaps no DN mapping specified). - * Skip to next module */ - if (!ldb_dn_check_local(module, req->op.del.dn)) { - return ldb_next_request(module, req); - } - - /* Prepare context and handle */ - ac = map_init_context(module, req); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Prepare the remote operation */ - ret = ldb_build_del_req(&ac->remote_req, ldb, ac, - ldb_dn_map_local(module, ac, req->op.del.dn), - req->controls, - ac, - map_op_remote_callback, - req); - LDB_REQ_SET_LOCATION(ac->remote_req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* No local db, just run the remote request */ - if (!map_check_local_db(ac->module)) { - /* Do the remote request. */ - return ldb_next_remote_request(ac->module, ac->remote_req); - } - - /* Prepare the search operation */ - ret = map_search_self_req(&search_req, ac, req->op.del.dn); - if (ret != LDB_SUCCESS) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_request(module, search_req); -} - -/* Delete the local record. */ -static int map_delete_do_local(struct map_context *ac) -{ - struct ldb_request *local_req; - struct ldb_context *ldb; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - /* No local record, continue remotely */ - if (ac->local_dn == NULL) { - /* Do the remote request. */ - return ldb_next_remote_request(ac->module, ac->remote_req); - } - - /* Prepare the local operation */ - ret = ldb_build_del_req(&local_req, ldb, ac, - ac->req->op.del.dn, - ac->req->controls, - ac, - map_op_local_callback, - ac->req); - LDB_REQ_SET_LOCATION(local_req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - return ldb_next_request(ac->module, local_req); -} - -/***************************************************************************** - * RENAME operations -*****************************************************************************/ - -/* Rename a record. */ -int ldb_map_rename(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_request *search_req = NULL; - struct ldb_context *ldb; - struct map_context *ac; - int ret; - - ldb = ldb_module_get_ctx(module); - - /* Do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.rename.olddn)) { - return ldb_next_request(module, req); - } - - /* No mapping requested (perhaps no DN mapping specified). - * Skip to next module */ - if ((!ldb_dn_check_local(module, req->op.rename.olddn)) && - (!ldb_dn_check_local(module, req->op.rename.newdn))) { - return ldb_next_request(module, req); - } - - /* Rename into/out of the mapped partition requested, bail out */ - if (!ldb_dn_check_local(module, req->op.rename.olddn) || - !ldb_dn_check_local(module, req->op.rename.newdn)) { - return LDB_ERR_AFFECTS_MULTIPLE_DSAS; - } - - /* Prepare context and handle */ - ac = map_init_context(module, req); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Prepare the remote operation */ - ret = ldb_build_rename_req(&ac->remote_req, ldb, ac, - ldb_dn_map_local(module, ac, req->op.rename.olddn), - ldb_dn_map_local(module, ac, req->op.rename.newdn), - req->controls, - ac, map_op_remote_callback, - req); - LDB_REQ_SET_LOCATION(ac->remote_req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* No local db, just run the remote request */ - if (!map_check_local_db(ac->module)) { - /* Do the remote request. */ - return ldb_next_remote_request(ac->module, ac->remote_req); - } - - /* Prepare the search operation */ - ret = map_search_self_req(&search_req, ac, req->op.rename.olddn); - if (ret != LDB_SUCCESS) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_request(module, search_req); -} - -/* Rename the local record. */ -static int map_rename_do_local(struct map_context *ac) -{ - struct ldb_request *local_req; - struct ldb_context *ldb; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - /* No local record, continue remotely */ - if (ac->local_dn == NULL) { - /* Do the remote request. */ - return ldb_next_remote_request(ac->module, ac->remote_req); - } - - /* Prepare the local operation */ - ret = ldb_build_rename_req(&local_req, ldb, ac, - ac->req->op.rename.olddn, - ac->req->op.rename.newdn, - ac->req->controls, - ac, - map_rename_local_callback, - ac->req); - LDB_REQ_SET_LOCATION(local_req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_request(ac->module, local_req); -} - -static int map_rename_local_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct ldb_context *ldb; - struct map_context *ac; - int ret; - - ac = talloc_get_type(req->context, struct map_context); - ldb = ldb_module_get_ctx(ac->module); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - if (ares->type != LDB_REPLY_DONE) { - ldb_asprintf_errstring(ldb, "Invalid LDB reply type %d", ares->type); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - /* proceed with next step */ - ret = map_rename_do_fixup(ac); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - return LDB_SUCCESS; -} - -/* Update the local 'IS_MAPPED' attribute. */ -static int map_rename_do_fixup(struct map_context *ac) -{ - struct ldb_request *local_req; - - /* Prepare the fixup operation */ - /* TODO: use GUIDs here instead -- or skip it when GUIDs are used. */ - local_req = map_build_fixup_req(ac, - ac->req->op.rename.newdn, - ac->remote_req->op.rename.newdn, - ac, - map_op_local_callback); - if (local_req == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_request(ac->module, local_req); -} diff --git a/ldb-2.0.8/ldb_map/ldb_map_outbound.c b/ldb-2.0.8/ldb_map/ldb_map_outbound.c deleted file mode 100644 index c823ba4..0000000 --- a/ldb-2.0.8/ldb_map/ldb_map_outbound.c +++ /dev/null @@ -1,1417 +0,0 @@ -/* - ldb database mapping module - - Copyright (C) Jelmer Vernooij 2005 - Copyright (C) Martin Kuehl 2006 - Copyright (C) Andrew Bartlett 2006 - Copyright (C) Simo Sorce 2008 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb_map.h" -#include "ldb_map_private.h" - - -/* Mapping attributes - * ================== */ - -/* Select attributes that stay in the local partition. */ -static const char **map_attrs_select_local(struct ldb_module *module, void *mem_ctx, const char * const *attrs) -{ - const struct ldb_map_context *data = map_get_context(module); - const char **result; - unsigned int i, last; - - if (attrs == NULL) - return NULL; - - last = 0; - result = talloc_array(mem_ctx, const char *, 1); - if (result == NULL) { - goto failed; - } - result[0] = NULL; - - for (i = 0; attrs[i]; i++) { - /* Wildcards and ignored attributes are kept locally */ - if ((ldb_attr_cmp(attrs[i], "*") == 0) || - (!map_attr_check_remote(data, attrs[i]))) { - result = talloc_realloc(mem_ctx, result, const char *, last+2); - if (result == NULL) { - goto failed; - } - - result[last] = talloc_strdup(result, attrs[i]); - result[last+1] = NULL; - last++; - } - } - - return result; - -failed: - talloc_free(result); - map_oom(module); - return NULL; -} - -/* Collect attributes that are mapped into the remote partition. */ -static const char **map_attrs_collect_remote(struct ldb_module *module, void *mem_ctx, - const char * const *attrs) -{ - const struct ldb_map_context *data = map_get_context(module); - const char **result; - const struct ldb_map_attribute *map; - const char *name=NULL; - unsigned int i, j, last; - int ret; - - last = 0; - result = talloc_array(mem_ctx, const char *, 1); - if (result == NULL) { - goto failed; - } - result[0] = NULL; - - for (i = 0; attrs[i]; i++) { - /* Wildcards are kept remotely, too */ - if (ldb_attr_cmp(attrs[i], "*") == 0) { - const char **new_attrs = NULL; - ret = map_attrs_merge(module, mem_ctx, &new_attrs, attrs); - if (ret != LDB_SUCCESS) { - goto failed; - } - ret = map_attrs_merge(module, mem_ctx, &new_attrs, data->wildcard_attributes); - if (ret != LDB_SUCCESS) { - goto failed; - } - - attrs = new_attrs; - break; - } - } - - for (i = 0; attrs[i]; i++) { - /* Wildcards are kept remotely, too */ - if (ldb_attr_cmp(attrs[i], "*") == 0) { - /* Add all 'include in wildcard' attributes */ - name = attrs[i]; - goto named; - } - - /* Add remote names of mapped attrs */ - map = map_attr_find_local(data, attrs[i]); - if (map == NULL) { - continue; - } - - switch (map->type) { - case LDB_MAP_IGNORE: - continue; - - case LDB_MAP_KEEP: - name = attrs[i]; - goto named; - - case LDB_MAP_RENAME: - case LDB_MAP_RENDROP: - case LDB_MAP_CONVERT: - name = map->u.rename.remote_name; - goto named; - - case LDB_MAP_GENERATE: - /* Add all remote names of "generate" attrs */ - for (j = 0; map->u.generate.remote_names[j]; j++) { - result = talloc_realloc(mem_ctx, result, const char *, last+2); - if (result == NULL) { - goto failed; - } - - result[last] = talloc_strdup(result, map->u.generate.remote_names[j]); - result[last+1] = NULL; - last++; - } - continue; - } - - named: /* We found a single remote name, add that */ - result = talloc_realloc(mem_ctx, result, const char *, last+2); - if (result == NULL) { - goto failed; - } - - result[last] = talloc_strdup(result, name); - result[last+1] = NULL; - last++; - } - - return result; - -failed: - talloc_free(result); - map_oom(module); - return NULL; -} - -/* Split attributes that stay in the local partition from those that - * are mapped into the remote partition. */ -static int map_attrs_partition(struct ldb_module *module, void *mem_ctx, const char ***local_attrs, const char ***remote_attrs, const char * const *attrs) -{ - *local_attrs = map_attrs_select_local(module, mem_ctx, attrs); - *remote_attrs = map_attrs_collect_remote(module, mem_ctx, attrs); - - return 0; -} - -/* Mapping message elements - * ======================== */ - -/* Add an element to a message, overwriting any old identically named elements. */ -static int ldb_msg_replace(struct ldb_message *msg, const struct ldb_message_element *el) -{ - struct ldb_message_element *old; - unsigned j; - old = ldb_msg_find_element(msg, el->name); - - /* no local result, add as new element */ - if (old == NULL) { - if (ldb_msg_add_empty(msg, el->name, 0, &old) != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - } - else { - talloc_free(old->values); - } - - old->values = talloc_array(msg->elements, struct ldb_val, el->num_values); - old->num_values = el->num_values; - if (old->values == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - /* copy the values into the element */ - for (j=0;jnum_values;j++) { - old->values[j] = ldb_val_dup(old->values, &el->values[j]); - if (old->values[j].data == NULL && el->values[j].length != 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - } - - return 0; -} - -/* Map a message element back into the local partition. */ -static struct ldb_message_element *ldb_msg_el_map_remote(struct ldb_module *module, - void *mem_ctx, - const struct ldb_map_attribute *map, - const char *attr_name, - const struct ldb_message_element *old) -{ - const struct ldb_map_context *data = map_get_context(module); - const char *local_attr_name = attr_name; - struct ldb_message_element *el; - unsigned int i; - - el = talloc_zero(mem_ctx, struct ldb_message_element); - if (el == NULL) { - map_oom(module); - return NULL; - } - - el->values = talloc_array(el, struct ldb_val, old->num_values); - if (el->values == NULL) { - talloc_free(el); - map_oom(module); - return NULL; - } - - for (i = 0; data->attribute_maps[i].local_name; i++) { - struct ldb_map_attribute *am = &data->attribute_maps[i]; - if (((am->type == LDB_MAP_RENAME || am->type == LDB_MAP_RENDROP) && - !strcmp(am->u.rename.remote_name, attr_name)) - || (am->type == LDB_MAP_CONVERT && - !strcmp(am->u.convert.remote_name, attr_name))) { - - local_attr_name = am->local_name; - break; - } - } - - el->name = talloc_strdup(el, local_attr_name); - if (el->name == NULL) { - talloc_free(el); - map_oom(module); - return NULL; - } - - for (i = 0; i < old->num_values; i++) { - el->values[i] = ldb_val_map_remote(module, el->values, map, &old->values[i]); - /* Conversions might fail, in which case bail */ - if (!el->values[i].data) { - talloc_free(el); - return NULL; - } - el->num_values++; - } - - return el; -} - -/* Merge a remote message element into a local message. */ -static int ldb_msg_el_merge(struct ldb_module *module, struct ldb_message *local, - struct ldb_message *remote, const char *attr_name) -{ - const struct ldb_map_context *data = map_get_context(module); - const struct ldb_map_attribute *map; - struct ldb_message_element *old, *el=NULL; - const char *remote_name = NULL; - struct ldb_context *ldb; - - ldb = ldb_module_get_ctx(module); - - /* We handle wildcards in ldb_msg_el_merge_wildcard */ - if (ldb_attr_cmp(attr_name, "*") == 0) { - return LDB_SUCCESS; - } - - map = map_attr_find_local(data, attr_name); - - /* Unknown attribute in remote message: - * skip, attribute was probably auto-generated */ - if (map == NULL) { - return LDB_SUCCESS; - } - - switch (map->type) { - case LDB_MAP_IGNORE: - break; - case LDB_MAP_CONVERT: - remote_name = map->u.convert.remote_name; - break; - case LDB_MAP_KEEP: - remote_name = attr_name; - break; - case LDB_MAP_RENAME: - case LDB_MAP_RENDROP: - remote_name = map->u.rename.remote_name; - break; - case LDB_MAP_GENERATE: - break; - } - - switch (map->type) { - case LDB_MAP_IGNORE: - return LDB_SUCCESS; - - case LDB_MAP_CONVERT: - if (map->u.convert.convert_remote == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "Skipping attribute '%s': " - "'convert_remote' not set", - attr_name); - return LDB_SUCCESS; - } - - FALL_THROUGH; - case LDB_MAP_KEEP: - case LDB_MAP_RENAME: - case LDB_MAP_RENDROP: - old = ldb_msg_find_element(remote, remote_name); - if (old) { - el = ldb_msg_el_map_remote(module, local, map, attr_name, old); - } else { - return LDB_ERR_NO_SUCH_ATTRIBUTE; - } - break; - - case LDB_MAP_GENERATE: - if (map->u.generate.generate_local == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "ldb_map: " - "Skipping attribute '%s': " - "'generate_local' not set", - attr_name); - return LDB_SUCCESS; - } - - el = map->u.generate.generate_local(module, local, attr_name, remote); - if (!el) { - /* Generation failure is probably due to lack of source attributes */ - return LDB_ERR_NO_SUCH_ATTRIBUTE; - } - break; - } - - if (el == NULL) { - return LDB_ERR_NO_SUCH_ATTRIBUTE; - } - - return ldb_msg_replace(local, el); -} - -/* Handle wildcard parts of merging a remote message element into a local message. */ -static int ldb_msg_el_merge_wildcard(struct ldb_module *module, struct ldb_message *local, - struct ldb_message *remote) -{ - const struct ldb_map_context *data = map_get_context(module); - const struct ldb_map_attribute *map = map_attr_find_local(data, "*"); - struct ldb_message_element *el=NULL; - unsigned int i; - int ret; - - /* Perhaps we have a mapping for "*" */ - if (map && map->type == LDB_MAP_KEEP) { - /* We copy everything over, and hope that anything with a - more specific rule is overwritten */ - for (i = 0; i < remote->num_elements; i++) { - el = ldb_msg_el_map_remote(module, local, map, remote->elements[i].name, - &remote->elements[i]); - if (el == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_msg_replace(local, el); - if (ret) { - return ret; - } - } - } - - /* Now walk the list of possible mappings, and apply each */ - for (i = 0; data->attribute_maps[i].local_name; i++) { - ret = ldb_msg_el_merge(module, local, remote, - data->attribute_maps[i].local_name); - if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { - continue; - } else if (ret) { - return ret; - } else { - continue; - } - } - - return LDB_SUCCESS; -} - -/* Mapping messages - * ================ */ - -/* Merge two local messages into a single one. */ -static int ldb_msg_merge_local(struct ldb_module *module, struct ldb_message *msg1, struct ldb_message *msg2) -{ - unsigned int i; - int ret; - - for (i = 0; i < msg2->num_elements; i++) { - ret = ldb_msg_replace(msg1, &msg2->elements[i]); - if (ret) { - return ret; - } - } - - return LDB_SUCCESS; -} - -/* Merge a local and a remote message into a single local one. */ -static int ldb_msg_merge_remote(struct map_context *ac, struct ldb_message *local, - struct ldb_message *remote) -{ - unsigned int i; - int ret; - const char * const *attrs = ac->all_attrs; - if (!attrs) { - ret = ldb_msg_el_merge_wildcard(ac->module, local, remote); - if (ret) { - return ret; - } - } - - for (i = 0; attrs && attrs[i]; i++) { - if (ldb_attr_cmp(attrs[i], "*") == 0) { - ret = ldb_msg_el_merge_wildcard(ac->module, local, remote); - if (ret) { - return ret; - } - break; - } - } - - /* Try to map each attribute back; - * Add to local message is possible, - * Overwrite old local attribute if necessary */ - for (i = 0; attrs && attrs[i]; i++) { - ret = ldb_msg_el_merge(ac->module, local, remote, - attrs[i]); - if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { - } else if (ret) { - return ret; - } - } - - return LDB_SUCCESS; -} - -/* Mapping search results - * ====================== */ - -/* Map a search result back into the local partition. */ -static int map_reply_remote(struct map_context *ac, struct ldb_reply *ares) -{ - struct ldb_message *msg; - struct ldb_dn *dn; - int ret; - - /* There is no result message, skip */ - if (ares->type != LDB_REPLY_ENTRY) { - return 0; - } - - /* Create a new result message */ - msg = ldb_msg_new(ares); - if (msg == NULL) { - map_oom(ac->module); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Merge remote message into new message */ - ret = ldb_msg_merge_remote(ac, msg, ares->message); - if (ret) { - talloc_free(msg); - return ret; - } - - /* Create corresponding local DN */ - dn = ldb_dn_map_rebase_remote(ac->module, msg, ares->message->dn); - if (dn == NULL) { - talloc_free(msg); - return LDB_ERR_OPERATIONS_ERROR; - } - msg->dn = dn; - - /* Store new message with new DN as the result */ - talloc_free(ares->message); - ares->message = msg; - - return 0; -} - -/* Mapping parse trees - * =================== */ - -/* Check whether a parse tree can safely be split in two. */ -static bool ldb_parse_tree_check_splittable(const struct ldb_parse_tree *tree) -{ - const struct ldb_parse_tree *subtree = tree; - bool negate = false; - - while (subtree) { - switch (subtree->operation) { - case LDB_OP_NOT: - negate = !negate; - subtree = subtree->u.isnot.child; - continue; - - case LDB_OP_AND: - return !negate; /* if negate: False */ - - case LDB_OP_OR: - return negate; /* if negate: True */ - - default: - return true; /* simple parse tree */ - } - } - - return true; /* no parse tree */ -} - -/* Collect a list of attributes required to match a given parse tree. */ -static int ldb_parse_tree_collect_attrs(struct ldb_module *module, void *mem_ctx, const char ***attrs, const struct ldb_parse_tree *tree) -{ - const char **new_attrs; - unsigned int i; - int ret; - - if (tree == NULL) { - return 0; - } - - switch (tree->operation) { - case LDB_OP_OR: - case LDB_OP_AND: /* attributes stored in list of subtrees */ - for (i = 0; i < tree->u.list.num_elements; i++) { - ret = ldb_parse_tree_collect_attrs(module, mem_ctx, - attrs, tree->u.list.elements[i]); - if (ret) { - return ret; - } - } - return 0; - - case LDB_OP_NOT: /* attributes stored in single subtree */ - return ldb_parse_tree_collect_attrs(module, mem_ctx, attrs, tree->u.isnot.child); - - default: /* single attribute in tree */ - new_attrs = ldb_attr_list_copy_add(mem_ctx, *attrs, tree->u.equality.attr); - talloc_free(*attrs); - *attrs = new_attrs; - return 0; - } -} - -static int map_subtree_select_local(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree); - -/* Select a negated subtree that queries attributes in the local partition */ -static int map_subtree_select_local_not(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - struct ldb_parse_tree *child; - int ret; - - /* Prepare new tree */ - *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); - if (*new == NULL) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Generate new subtree */ - ret = map_subtree_select_local(module, *new, &child, tree->u.isnot.child); - if (ret) { - talloc_free(*new); - return ret; - } - - /* Prune tree without subtree */ - if (child == NULL) { - talloc_free(*new); - *new = NULL; - return 0; - } - - (*new)->u.isnot.child = child; - - return ret; -} - -/* Select a list of subtrees that query attributes in the local partition */ -static int map_subtree_select_local_list(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - unsigned int i, j; - int ret=0; - - /* Prepare new tree */ - *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); - if (*new == NULL) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Prepare list of subtrees */ - (*new)->u.list.num_elements = 0; - (*new)->u.list.elements = talloc_array(*new, struct ldb_parse_tree *, tree->u.list.num_elements); - if ((*new)->u.list.elements == NULL) { - map_oom(module); - talloc_free(*new); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Generate new list of subtrees */ - j = 0; - for (i = 0; i < tree->u.list.num_elements; i++) { - struct ldb_parse_tree *child = NULL; - ret = map_subtree_select_local(module, *new, &child, tree->u.list.elements[i]); - if (ret) { - talloc_free(*new); - return ret; - } - - if (child) { - (*new)->u.list.elements[j] = child; - j++; - } - } - - /* Prune tree without subtrees */ - if (j == 0) { - talloc_free(*new); - *new = NULL; - return 0; - } - - /* Fix subtree list size */ - (*new)->u.list.num_elements = j; - (*new)->u.list.elements = talloc_realloc(*new, (*new)->u.list.elements, struct ldb_parse_tree *, (*new)->u.list.num_elements); - - return ret; -} - -/* Select a simple subtree that queries attributes in the local partition */ -static int map_subtree_select_local_simple(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - /* Prepare new tree */ - *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); - if (*new == NULL) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - return 0; -} - -/* Select subtrees that query attributes in the local partition */ -static int map_subtree_select_local(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - const struct ldb_map_context *data = map_get_context(module); - - if (tree == NULL) { - return 0; - } - - if (tree->operation == LDB_OP_NOT) { - return map_subtree_select_local_not(module, mem_ctx, new, tree); - } - - if (tree->operation == LDB_OP_AND || tree->operation == LDB_OP_OR) { - return map_subtree_select_local_list(module, mem_ctx, new, tree); - } - - if (map_attr_check_remote(data, tree->u.equality.attr)) { - *new = NULL; - return 0; - } - - return map_subtree_select_local_simple(module, mem_ctx, new, tree); -} - -static int map_subtree_collect_remote(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree); - -/* Collect a negated subtree that queries attributes in the remote partition */ -static int map_subtree_collect_remote_not(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - struct ldb_parse_tree *child; - int ret; - - /* Prepare new tree */ - *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); - if (*new == NULL) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Generate new subtree */ - ret = map_subtree_collect_remote(module, *new, &child, tree->u.isnot.child); - if (ret) { - talloc_free(*new); - return ret; - } - - /* Prune tree without subtree */ - if (child == NULL) { - talloc_free(*new); - *new = NULL; - return 0; - } - - (*new)->u.isnot.child = child; - - return ret; -} - -/* Collect a list of subtrees that query attributes in the remote partition */ -static int map_subtree_collect_remote_list(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - unsigned int i, j; - int ret=0; - - /* Prepare new tree */ - *new = talloc_memdup(mem_ctx, tree, sizeof(struct ldb_parse_tree)); - if (*new == NULL) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Prepare list of subtrees */ - (*new)->u.list.num_elements = 0; - (*new)->u.list.elements = talloc_array(*new, struct ldb_parse_tree *, tree->u.list.num_elements); - if ((*new)->u.list.elements == NULL) { - map_oom(module); - talloc_free(*new); - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Generate new list of subtrees */ - j = 0; - for (i = 0; i < tree->u.list.num_elements; i++) { - struct ldb_parse_tree *child; - ret = map_subtree_collect_remote(module, *new, &child, tree->u.list.elements[i]); - if (ret) { - talloc_free(*new); - return ret; - } - - if (child) { - (*new)->u.list.elements[j] = child; - j++; - } - } - - /* Prune tree without subtrees */ - if (j == 0) { - talloc_free(*new); - *new = NULL; - return 0; - } - - /* Fix subtree list size */ - (*new)->u.list.num_elements = j; - (*new)->u.list.elements = talloc_realloc(*new, (*new)->u.list.elements, struct ldb_parse_tree *, (*new)->u.list.num_elements); - - return ret; -} - -/* Collect a simple subtree that queries attributes in the remote partition */ -int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree, const struct ldb_map_attribute *map) -{ - const char *attr; - - /* Prepare new tree */ - *new = talloc(mem_ctx, struct ldb_parse_tree); - if (*new == NULL) { - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; - } - **new = *tree; - - if (map->type == LDB_MAP_KEEP) { - /* Nothing to do here */ - return 0; - } - - /* Store attribute and value in new tree */ - switch (tree->operation) { - case LDB_OP_PRESENT: - attr = map_attr_map_local(*new, map, tree->u.present.attr); - (*new)->u.present.attr = attr; - break; - case LDB_OP_SUBSTRING: - { - attr = map_attr_map_local(*new, map, tree->u.substring.attr); - (*new)->u.substring.attr = attr; - break; - } - case LDB_OP_EQUALITY: - attr = map_attr_map_local(*new, map, tree->u.equality.attr); - (*new)->u.equality.attr = attr; - break; - case LDB_OP_LESS: - case LDB_OP_GREATER: - case LDB_OP_APPROX: - attr = map_attr_map_local(*new, map, tree->u.comparison.attr); - (*new)->u.comparison.attr = attr; - break; - case LDB_OP_EXTENDED: - attr = map_attr_map_local(*new, map, tree->u.extended.attr); - (*new)->u.extended.attr = attr; - break; - default: /* unknown kind of simple subtree */ - talloc_free(*new); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (attr == NULL) { - talloc_free(*new); - *new = NULL; - return 0; - } - - if (map->type == LDB_MAP_RENAME || map->type == LDB_MAP_RENDROP) { - /* Nothing more to do here, the attribute has been renamed */ - return 0; - } - - /* Store attribute and value in new tree */ - switch (tree->operation) { - case LDB_OP_PRESENT: - break; - case LDB_OP_SUBSTRING: - { - int i; - /* Map value */ - (*new)->u.substring.chunks = NULL; - for (i=0; tree->u.substring.chunks && tree->u.substring.chunks[i]; i++) { - (*new)->u.substring.chunks = talloc_realloc(*new, (*new)->u.substring.chunks, struct ldb_val *, i+2); - if (!(*new)->u.substring.chunks) { - talloc_free(*new); - *new = NULL; - return 0; - } - (*new)->u.substring.chunks[i] = talloc(*new, struct ldb_val); - if (!(*new)->u.substring.chunks[i]) { - talloc_free(*new); - *new = NULL; - return 0; - } - *(*new)->u.substring.chunks[i] = ldb_val_map_local(module, *new, map, tree->u.substring.chunks[i]); - (*new)->u.substring.chunks[i+1] = NULL; - } - break; - } - case LDB_OP_EQUALITY: - (*new)->u.equality.value = ldb_val_map_local(module, *new, map, &tree->u.equality.value); - break; - case LDB_OP_LESS: - case LDB_OP_GREATER: - case LDB_OP_APPROX: - (*new)->u.comparison.value = ldb_val_map_local(module, *new, map, &tree->u.comparison.value); - break; - case LDB_OP_EXTENDED: - (*new)->u.extended.value = ldb_val_map_local(module, *new, map, &tree->u.extended.value); - (*new)->u.extended.rule_id = talloc_strdup(*new, tree->u.extended.rule_id); - break; - default: /* unknown kind of simple subtree */ - talloc_free(*new); - return LDB_ERR_OPERATIONS_ERROR; - } - - return 0; -} - -/* Collect subtrees that query attributes in the remote partition */ -static int map_subtree_collect_remote(struct ldb_module *module, void *mem_ctx, struct ldb_parse_tree **new, const struct ldb_parse_tree *tree) -{ - const struct ldb_map_context *data = map_get_context(module); - const struct ldb_map_attribute *map; - struct ldb_context *ldb; - - ldb = ldb_module_get_ctx(module); - - if (tree == NULL) { - return 0; - } - - if (tree->operation == LDB_OP_NOT) { - return map_subtree_collect_remote_not(module, mem_ctx, new, tree); - } - - if ((tree->operation == LDB_OP_AND) || (tree->operation == LDB_OP_OR)) { - return map_subtree_collect_remote_list(module, mem_ctx, new, tree); - } - - if (!map_attr_check_remote(data, tree->u.equality.attr)) { - *new = NULL; - return 0; - } - - map = map_attr_find_local(data, tree->u.equality.attr); - if (map == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - if (map->convert_operator) { - return map->convert_operator(module, mem_ctx, new, tree); - } - - if (map->type == LDB_MAP_GENERATE) { - ldb_debug(ldb, LDB_DEBUG_WARNING, "ldb_map: " - "Skipping attribute '%s': " - "'convert_operator' not set", - tree->u.equality.attr); - *new = NULL; - return 0; - } - - return map_subtree_collect_remote_simple(module, mem_ctx, new, tree, map); -} - -/* Split subtrees that query attributes in the local partition from - * those that query the remote partition. */ -static int ldb_parse_tree_partition(struct ldb_module *module, - void *mem_ctx, - struct ldb_parse_tree **local_tree, - struct ldb_parse_tree **remote_tree, - const struct ldb_parse_tree *tree) -{ - int ret; - - *local_tree = NULL; - *remote_tree = NULL; - - /* No original tree */ - if (tree == NULL) { - return 0; - } - - /* Generate local tree */ - ret = map_subtree_select_local(module, mem_ctx, local_tree, tree); - if (ret) { - return ret; - } - - /* Generate remote tree */ - ret = map_subtree_collect_remote(module, mem_ctx, remote_tree, tree); - if (ret) { - talloc_free(*local_tree); - return ret; - } - - return 0; -} - -/* Collect a list of attributes required either explicitly from a - * given list or implicitly from a given parse tree; split the - * collected list into local and remote parts. */ -static int map_attrs_collect_and_partition(struct ldb_module *module, struct map_context *ac, - const char * const *search_attrs, - const struct ldb_parse_tree *tree) -{ - void *tmp_ctx; - const char **tree_attrs; - const char **remote_attrs; - const char **local_attrs; - int ret; - - /* There is no tree, just partition the searched attributes */ - if (tree == NULL) { - ret = map_attrs_partition(module, ac, - &local_attrs, &remote_attrs, search_attrs); - if (ret == 0) { - ac->local_attrs = local_attrs; - ac->remote_attrs = remote_attrs; - ac->all_attrs = search_attrs; - } - return ret; - } - - /* Create context for temporary memory */ - tmp_ctx = talloc_new(ac); - if (tmp_ctx == NULL) { - goto oom; - } - - /* Prepare list of attributes from tree */ - tree_attrs = talloc_array(tmp_ctx, const char *, 1); - if (tree_attrs == NULL) { - talloc_free(tmp_ctx); - goto oom; - } - tree_attrs[0] = NULL; - - /* Collect attributes from tree */ - ret = ldb_parse_tree_collect_attrs(module, tmp_ctx, &tree_attrs, tree); - if (ret) { - goto done; - } - - /* Merge attributes from search operation */ - ret = map_attrs_merge(module, tmp_ctx, &tree_attrs, search_attrs); - if (ret) { - goto done; - } - - /* Split local from remote attributes */ - ret = map_attrs_partition(module, ac, &local_attrs, - &remote_attrs, tree_attrs); - - if (ret == 0) { - ac->local_attrs = local_attrs; - ac->remote_attrs = remote_attrs; - talloc_steal(ac, tree_attrs); - ac->all_attrs = tree_attrs; - } -done: - /* Free temporary memory */ - talloc_free(tmp_ctx); - return ret; - -oom: - map_oom(module); - return LDB_ERR_OPERATIONS_ERROR; -} - - -/* Outbound requests: search - * ========================= */ - -static int map_remote_search_callback(struct ldb_request *req, - struct ldb_reply *ares); -static int map_local_merge_callback(struct ldb_request *req, - struct ldb_reply *ares); -static int map_search_local(struct map_context *ac); - -static int map_save_entry(struct map_context *ac, struct ldb_reply *ares) -{ - struct map_reply *mr; - - mr = talloc_zero(ac, struct map_reply); - if (mr == NULL) { - map_oom(ac->module); - return LDB_ERR_OPERATIONS_ERROR; - } - mr->remote = talloc_steal(mr, ares); - if (ac->r_current) { - ac->r_current->next = mr; - } else { - /* first entry */ - ac->r_list = mr; - } - ac->r_current = mr; - - return LDB_SUCCESS; -} - -/* Pass a merged search result up the callback chain. */ -int map_return_entry(struct map_context *ac, struct ldb_reply *ares) -{ - struct ldb_message_element *el; - const char * const *attrs; - struct ldb_context *ldb; - unsigned int i; - int ret; - bool matched; - - ldb = ldb_module_get_ctx(ac->module); - - /* Merged result doesn't match original query, skip */ - ret = ldb_match_msg_error(ldb, ares->message, - ac->req->op.search.tree, - ac->req->op.search.base, - ac->req->op.search.scope, - &matched); - if (ret != LDB_SUCCESS) return ret; - if (!matched) { - ldb_debug(ldb, LDB_DEBUG_TRACE, "ldb_map: " - "Skipping record '%s': " - "doesn't match original search", - ldb_dn_get_linearized(ares->message->dn)); - return LDB_SUCCESS; - } - - /* Limit result to requested attrs */ - if (ac->req->op.search.attrs && - (! ldb_attr_in_list(ac->req->op.search.attrs, "*"))) { - - attrs = ac->req->op.search.attrs; - i = 0; - - while (i < ares->message->num_elements) { - - el = &ares->message->elements[i]; - if ( ! ldb_attr_in_list(attrs, el->name)) { - ldb_msg_remove_element(ares->message, el); - } else { - i++; - } - } - } - - return ldb_module_send_entry(ac->req, ares->message, ares->controls); -} - -/* Search a record. */ -int ldb_map_search(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_parse_tree *remote_tree; - struct ldb_parse_tree *local_tree; - struct ldb_request *remote_req; - struct ldb_context *ldb; - struct map_context *ac; - int ret; - - const char *wildcard[] = { "*", NULL }; - const char * const *attrs; - - ldb = ldb_module_get_ctx(module); - - /* if we're not yet initialized, go to the next module */ - if (!ldb_module_get_private(module)) - return ldb_next_request(module, req); - - /* Do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.search.base)) { - return ldb_next_request(module, req); - } - - /* No mapping requested, skip to next module */ - if ((req->op.search.base) && (!ldb_dn_check_local(module, req->op.search.base))) { - return ldb_next_request(module, req); - } - - /* TODO: How can we be sure about which partition we are - * targetting when there is no search base? */ - - /* Prepare context and handle */ - ac = map_init_context(module, req); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* It is easier to deal with the two different ways of - * expressing the wildcard in the same codepath */ - attrs = req->op.search.attrs; - if (attrs == NULL) { - attrs = wildcard; - } - - /* Split local from remote attrs */ - ret = map_attrs_collect_and_partition(module, ac, - attrs, req->op.search.tree); - if (ret) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Split local from remote tree */ - ret = ldb_parse_tree_partition(module, ac, - &local_tree, &remote_tree, - req->op.search.tree); - if (ret) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (((local_tree != NULL) && (remote_tree != NULL)) && - (!ldb_parse_tree_check_splittable(req->op.search.tree))) { - /* The query can't safely be split, enumerate the remote partition */ - local_tree = NULL; - remote_tree = NULL; - } - - if (local_tree == NULL) { - /* Construct default local parse tree */ - local_tree = talloc_zero(ac, struct ldb_parse_tree); - if (local_tree == NULL) { - map_oom(ac->module); - return LDB_ERR_OPERATIONS_ERROR; - } - - local_tree->operation = LDB_OP_PRESENT; - local_tree->u.present.attr = talloc_strdup(local_tree, IS_MAPPED); - } - if (remote_tree == NULL) { - /* Construct default remote parse tree */ - remote_tree = ldb_parse_tree(ac, NULL); - if (remote_tree == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - } - - ac->local_tree = local_tree; - - /* Prepare the remote operation */ - ret = ldb_build_search_req_ex(&remote_req, ldb, ac, - req->op.search.base, - req->op.search.scope, - remote_tree, - ac->remote_attrs, - req->controls, - ac, map_remote_search_callback, - req); - LDB_REQ_SET_LOCATION(remote_req); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_remote_request(module, remote_req); -} - -/* Now, search the local part of a remote search result. */ -static int map_remote_search_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct map_context *ac; - int ret; - - ac = talloc_get_type(req->context, struct map_context); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - switch (ares->type) { - case LDB_REPLY_REFERRAL: - - /* ignore referrals */ - talloc_free(ares); - return LDB_SUCCESS; - - case LDB_REPLY_ENTRY: - - /* Map result record into a local message */ - ret = map_reply_remote(ac, ares); - if (ret) { - talloc_free(ares); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - /* if we have no local db, then we can just return the reply to - * the upper layer, otherwise we must save it and process it - * when all replies ahve been gathered */ - if ( ! map_check_local_db(ac->module)) { - ret = map_return_entry(ac, ares); - } else { - ret = map_save_entry(ac,ares); - } - - if (ret != LDB_SUCCESS) { - talloc_free(ares); - return ldb_module_done(ac->req, NULL, NULL, ret); - } - break; - - case LDB_REPLY_DONE: - - if ( ! map_check_local_db(ac->module)) { - return ldb_module_done(ac->req, ares->controls, - ares->response, LDB_SUCCESS); - } - - /* reset the pointer to the start of the list */ - ac->r_current = ac->r_list; - - /* no entry just return */ - if (ac->r_current == NULL) { - ret = ldb_module_done(ac->req, ares->controls, - ares->response, LDB_SUCCESS); - talloc_free(ares); - return ret; - } - - ac->remote_done_ares = talloc_steal(ac, ares); - - ret = map_search_local(ac); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - } - - return LDB_SUCCESS; -} - -static int map_search_local(struct map_context *ac) -{ - struct ldb_request *search_req; - - if (ac->r_current == NULL || ac->r_current->remote == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* Prepare local search request */ - /* TODO: use GUIDs here instead? */ - search_req = map_search_base_req(ac, - ac->r_current->remote->message->dn, - NULL, NULL, - ac, map_local_merge_callback); - if (search_req == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_request(ac->module, search_req); -} - -/* Merge the remote and local parts of a search result. */ -int map_local_merge_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct ldb_context *ldb; - struct map_context *ac; - int ret; - - ac = talloc_get_type(req->context, struct map_context); - ldb = ldb_module_get_ctx(ac->module); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - /* We have already found a local record */ - if (ac->r_current->local) { - talloc_free(ares); - ldb_set_errstring(ldb, "ldb_map: Too many results!"); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - /* Store local result */ - ac->r_current->local = talloc_steal(ac->r_current, ares); - - break; - - case LDB_REPLY_REFERRAL: - /* ignore referrals */ - talloc_free(ares); - break; - - case LDB_REPLY_DONE: - /* We don't need the local 'ares', but we will use the remote one from below */ - talloc_free(ares); - - /* No local record found, map and send remote record */ - if (ac->r_current->local != NULL) { - /* Merge remote into local message */ - ret = ldb_msg_merge_local(ac->module, - ac->r_current->local->message, - ac->r_current->remote->message); - if (ret == LDB_SUCCESS) { - ret = map_return_entry(ac, ac->r_current->local); - } - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - } else { - ret = map_return_entry(ac, ac->r_current->remote); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, - NULL, NULL, ret); - } - } - - if (ac->r_current->next != NULL) { - ac->r_current = ac->r_current->next; - if (ac->r_current->remote->type == LDB_REPLY_ENTRY) { - ret = map_search_local(ac); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, - NULL, NULL, ret); - } - break; - } - } - - /* ok we are done with all search, finally it is time to - * finish operations for this module */ - return ldb_module_done(ac->req, - ac->remote_done_ares->controls, - ac->remote_done_ares->response, - ac->remote_done_ares->error); - } - - return LDB_SUCCESS; -} diff --git a/ldb-2.0.8/ldb_map/ldb_map_private.h b/ldb-2.0.8/ldb_map/ldb_map_private.h deleted file mode 100644 index 6e4a9dd..0000000 --- a/ldb-2.0.8/ldb_map/ldb_map_private.h +++ /dev/null @@ -1,96 +0,0 @@ -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" - -/* A handy macro to report Out of Memory conditions */ -#define map_oom(module) ldb_set_errstring(ldb_module_get_ctx(module), talloc_asprintf(module, "Out of Memory")); - -/* The type of search callback functions */ -typedef int (*ldb_map_callback_t)(struct ldb_request *, struct ldb_reply *); - -/* The special DN from which the local and remote base DNs are fetched */ -#define MAP_DN_NAME "@MAP" -#define MAP_DN_FROM "@FROM" -#define MAP_DN_TO "@TO" - -/* Private data structures - * ======================= */ - -struct map_reply { - struct map_reply *next; - struct ldb_reply *remote; - struct ldb_reply *local; -}; - -/* Context data for mapped requests */ -struct map_context { - - struct ldb_module *module; - struct ldb_request *req; - - struct ldb_dn *local_dn; - const struct ldb_parse_tree *local_tree; - const char * const *local_attrs; - const char * const *remote_attrs; - const char * const *all_attrs; - - struct ldb_message *local_msg; - struct ldb_request *remote_req; - - struct map_reply *r_list; - struct map_reply *r_current; - - /* The response continaing any controls the remote server gave */ - struct ldb_reply *remote_done_ares; -}; - -/* Common operations - * ================= */ - -/* The following definitions come from lib/ldb/modules/ldb_map.c */ -const struct ldb_map_context *map_get_context(struct ldb_module *module); -struct map_context *map_init_context(struct ldb_module *module, - struct ldb_request *req); - -int ldb_next_remote_request(struct ldb_module *module, struct ldb_request *request); - -bool map_check_local_db(struct ldb_module *module); -bool map_attr_check_remote(const struct ldb_map_context *data, const char *attr); -bool ldb_dn_check_local(struct ldb_module *module, struct ldb_dn *dn); - -const struct ldb_map_attribute *map_attr_find_local(const struct ldb_map_context *data, const char *name); -const struct ldb_map_attribute *map_attr_find_remote(const struct ldb_map_context *data, const char *name); - -const char *map_attr_map_local(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr); -const char *map_attr_map_remote(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr); -int map_attrs_merge(struct ldb_module *module, void *mem_ctx, const char ***attrs, const char * const *more_attrs); - -struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val); -struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val); - -struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn); -struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn); -struct ldb_dn *ldb_dn_map_rebase_remote(struct ldb_module *module, void *mem_ctx, struct ldb_dn *dn); - -struct ldb_request *map_search_base_req(struct map_context *ac, - struct ldb_dn *dn, - const char * const *attrs, - struct ldb_parse_tree *tree, - void *context, - ldb_map_callback_t callback); -struct ldb_request *map_build_fixup_req(struct map_context *ac, - struct ldb_dn *olddn, - struct ldb_dn *newdn, - void *context, - ldb_map_callback_t callback); -int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx, - struct ldb_parse_tree **new, - const struct ldb_parse_tree *tree, - const struct ldb_map_attribute *map); -int map_return_fatal_error(struct ldb_request *req, - struct ldb_reply *ares); -int map_return_normal_error(struct ldb_request *req, - struct ldb_reply *ares, - int error); - -int map_return_entry(struct map_context *ac, struct ldb_reply *ares); diff --git a/ldb-2.0.8/ldb_mdb/ldb_mdb.c b/ldb-2.0.8/ldb_mdb/ldb_mdb.c deleted file mode 100644 index 6c679c2..0000000 --- a/ldb-2.0.8/ldb_mdb/ldb_mdb.c +++ /dev/null @@ -1,1126 +0,0 @@ -/* - ldb database library using mdb back end - - Copyright (C) Jakub Hrozek 2014 - Copyright (C) Catalyst.Net Ltd 2017 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "ldb_mdb.h" -#include "../ldb_key_value/ldb_kv.h" -#include "include/dlinklist.h" - -#define MDB_URL_PREFIX "mdb://" -#define MDB_URL_PREFIX_SIZE (sizeof(MDB_URL_PREFIX)-1) - -#define LDB_MDB_MAX_KEY_LENGTH 511 - -#define GIGABYTE (1024*1024*1024) - -int ldb_mdb_err_map(int lmdb_err) -{ - switch (lmdb_err) { - case MDB_SUCCESS: - return LDB_SUCCESS; - case EIO: - return LDB_ERR_OPERATIONS_ERROR; -#ifdef EBADE - case EBADE: -#endif - case MDB_INCOMPATIBLE: - case MDB_CORRUPTED: - case MDB_INVALID: - return LDB_ERR_UNAVAILABLE; - case MDB_BAD_TXN: - case MDB_BAD_VALSIZE: -#ifdef MDB_BAD_DBI - case MDB_BAD_DBI: -#endif - case MDB_PANIC: - case EINVAL: - return LDB_ERR_PROTOCOL_ERROR; - case MDB_MAP_FULL: - case MDB_DBS_FULL: - case MDB_READERS_FULL: - case MDB_TLS_FULL: - case MDB_TXN_FULL: - case EAGAIN: - return LDB_ERR_BUSY; - case MDB_KEYEXIST: - return LDB_ERR_ENTRY_ALREADY_EXISTS; - case MDB_NOTFOUND: - case ENOENT: - return LDB_ERR_NO_SUCH_OBJECT; - case EACCES: - return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; - default: - break; - } - return LDB_ERR_OTHER; -} - -#define ldb_mdb_error(ldb, ecode) lmdb_error_at(ldb, ecode, __FILE__, __LINE__) -static int lmdb_error_at(struct ldb_context *ldb, - int ecode, - const char *file, - int line) -{ - int ldb_err = ldb_mdb_err_map(ecode); - char *reason = mdb_strerror(ecode); - ldb_asprintf_errstring(ldb, - "(%d) - %s at %s:%d", - ecode, - reason, - file, - line); - return ldb_err; -} - -static bool lmdb_transaction_active(struct ldb_kv_private *ldb_kv) -{ - return ldb_kv->lmdb_private->txlist != NULL; -} - -static MDB_txn *lmdb_trans_get_tx(struct lmdb_trans *ltx) -{ - if (ltx == NULL) { - return NULL; - } - - return ltx->tx; -} - -static void trans_push(struct lmdb_private *lmdb, struct lmdb_trans *ltx) -{ - if (lmdb->txlist) { - talloc_steal(lmdb->txlist, ltx); - } - - DLIST_ADD(lmdb->txlist, ltx); -} - -static void trans_finished(struct lmdb_private *lmdb, struct lmdb_trans *ltx) -{ - DLIST_REMOVE(lmdb->txlist, ltx); - talloc_free(ltx); -} - - -static struct lmdb_trans *lmdb_private_trans_head(struct lmdb_private *lmdb) -{ - struct lmdb_trans *ltx; - - ltx = lmdb->txlist; - return ltx; -} - - -static MDB_txn *get_current_txn(struct lmdb_private *lmdb) -{ - MDB_txn *txn = NULL; - - txn = lmdb_trans_get_tx(lmdb_private_trans_head(lmdb)); - if (txn != NULL) { - return txn; - } - if (lmdb->read_txn != NULL) { - return lmdb->read_txn; - } - lmdb->error = MDB_BAD_TXN; - ldb_set_errstring(lmdb->ldb, __location__":No active transaction\n"); - return NULL; -} - -static int lmdb_store(struct ldb_kv_private *ldb_kv, - struct ldb_val key, - struct ldb_val data, - int flags) -{ - struct lmdb_private *lmdb = ldb_kv->lmdb_private; - MDB_val mdb_key; - MDB_val mdb_data; - int mdb_flags; - MDB_txn *txn = NULL; - MDB_dbi dbi = 0; - - if (ldb_kv->read_only) { - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - txn = lmdb_trans_get_tx(lmdb_private_trans_head(lmdb)); - if (txn == NULL) { - ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction"); - lmdb->error = MDB_PANIC; - return ldb_mdb_error(lmdb->ldb, lmdb->error); - } - - lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi); - if (lmdb->error != MDB_SUCCESS) { - return ldb_mdb_error(lmdb->ldb, lmdb->error); - } - - mdb_key.mv_size = key.length; - mdb_key.mv_data = key.data; - - mdb_data.mv_size = data.length; - mdb_data.mv_data = data.data; - - if (flags == TDB_INSERT) { - mdb_flags = MDB_NOOVERWRITE; - } else if ((flags == TDB_MODIFY)) { - /* - * Modifying a record, ensure that it exists. - * This mimics the TDB semantics - */ - MDB_val value; - lmdb->error = mdb_get(txn, dbi, &mdb_key, &value); - if (lmdb->error != MDB_SUCCESS) { - return ldb_mdb_error(lmdb->ldb, lmdb->error); - } - mdb_flags = 0; - } else { - mdb_flags = 0; - } - - lmdb->error = mdb_put(txn, dbi, &mdb_key, &mdb_data, mdb_flags); - if (lmdb->error != MDB_SUCCESS) { - return ldb_mdb_error(lmdb->ldb, lmdb->error); - } - - return ldb_mdb_err_map(lmdb->error); -} - -static int lmdb_delete(struct ldb_kv_private *ldb_kv, struct ldb_val key) -{ - struct lmdb_private *lmdb = ldb_kv->lmdb_private; - MDB_val mdb_key; - MDB_txn *txn = NULL; - MDB_dbi dbi = 0; - - if (ldb_kv->read_only) { - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - txn = lmdb_trans_get_tx(lmdb_private_trans_head(lmdb)); - if (txn == NULL) { - ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction"); - lmdb->error = MDB_PANIC; - return ldb_mdb_error(lmdb->ldb, lmdb->error); - } - - lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi); - if (lmdb->error != MDB_SUCCESS) { - return ldb_mdb_error(lmdb->ldb, lmdb->error); - } - - mdb_key.mv_size = key.length; - mdb_key.mv_data = key.data; - - lmdb->error = mdb_del(txn, dbi, &mdb_key, NULL); - if (lmdb->error != MDB_SUCCESS) { - return ldb_mdb_error(lmdb->ldb, lmdb->error); - } - return ldb_mdb_err_map(lmdb->error); -} - -static int lmdb_traverse_fn(struct ldb_kv_private *ldb_kv, - ldb_kv_traverse_fn fn, - void *ctx) -{ - struct lmdb_private *lmdb = ldb_kv->lmdb_private; - MDB_val mdb_key; - MDB_val mdb_data; - MDB_txn *txn = NULL; - MDB_dbi dbi = 0; - MDB_cursor *cursor = NULL; - int ret; - - txn = get_current_txn(lmdb); - if (txn == NULL) { - ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction"); - lmdb->error = MDB_PANIC; - return ldb_mdb_error(lmdb->ldb, lmdb->error); - } - - lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi); - if (lmdb->error != MDB_SUCCESS) { - return ldb_mdb_error(lmdb->ldb, lmdb->error); - } - - lmdb->error = mdb_cursor_open(txn, dbi, &cursor); - if (lmdb->error != MDB_SUCCESS) { - goto done; - } - - while ((lmdb->error = mdb_cursor_get( - cursor, &mdb_key, - &mdb_data, MDB_NEXT)) == MDB_SUCCESS) { - - struct ldb_val key = { - .length = mdb_key.mv_size, - .data = mdb_key.mv_data, - }; - struct ldb_val data = { - .length = mdb_data.mv_size, - .data = mdb_data.mv_data, - }; - - ret = fn(ldb_kv, key, data, ctx); - if (ret != 0) { - /* - * NOTE: This DOES NOT set lmdb->error! - * - * This means that the caller will get success. - * This matches TDB traverse behaviour, where callbacks - * may terminate the traverse, but do not change the - * return code from success. - * - * Callers SHOULD store their own error codes. - */ - goto done; - } - } - if (lmdb->error == MDB_NOTFOUND) { - lmdb->error = MDB_SUCCESS; - } -done: - if (cursor != NULL) { - mdb_cursor_close(cursor); - } - - if (lmdb->error != MDB_SUCCESS) { - return ldb_mdb_error(lmdb->ldb, lmdb->error); - } - return ldb_mdb_err_map(lmdb->error); -} - -static int lmdb_update_in_iterate(struct ldb_kv_private *ldb_kv, - struct ldb_val key, - struct ldb_val key2, - struct ldb_val data, - void *state) -{ - struct lmdb_private *lmdb = ldb_kv->lmdb_private; - struct ldb_val copy; - int ret = LDB_SUCCESS; - - /* - * Need to take a copy of the data as the delete operation alters the - * data, as it is in private lmdb memory. - */ - copy.length = data.length; - copy.data = talloc_memdup(ldb_kv, data.data, data.length); - if (copy.data == NULL) { - lmdb->error = MDB_PANIC; - return ldb_oom(lmdb->ldb); - } - - lmdb->error = lmdb_delete(ldb_kv, key); - if (lmdb->error != MDB_SUCCESS) { - ldb_debug( - lmdb->ldb, - LDB_DEBUG_ERROR, - "Failed to delete %*.*s " - "for rekey as %*.*s: %s", - (int)key.length, (int)key.length, - (const char *)key.data, - (int)key2.length, (int)key2.length, - (const char *)key.data, - mdb_strerror(lmdb->error)); - ret = ldb_mdb_error(lmdb->ldb, lmdb->error); - goto done; - } - - lmdb->error = lmdb_store(ldb_kv, key2, copy, 0); - if (lmdb->error != MDB_SUCCESS) { - ldb_debug( - lmdb->ldb, - LDB_DEBUG_ERROR, - "Failed to rekey %*.*s as %*.*s: %s", - (int)key.length, (int)key.length, - (const char *)key.data, - (int)key2.length, (int)key2.length, - (const char *)key.data, - mdb_strerror(lmdb->error)); - ret = ldb_mdb_error(lmdb->ldb, lmdb->error); - goto done; - } - -done: - if (copy.data != NULL) { - TALLOC_FREE(copy.data); - copy.length = 0; - } - - /* - * Explicity invalidate the data, as the delete has done this - */ - data.length = 0; - data.data = NULL; - - return ret; -} - -/* Handles only a single record */ -static int lmdb_parse_record(struct ldb_kv_private *ldb_kv, - struct ldb_val key, - int (*parser)(struct ldb_val key, - struct ldb_val data, - void *private_data), - void *ctx) -{ - struct lmdb_private *lmdb = ldb_kv->lmdb_private; - MDB_val mdb_key; - MDB_val mdb_data; - MDB_txn *txn = NULL; - MDB_dbi dbi; - struct ldb_val data; - - txn = get_current_txn(lmdb); - if (txn == NULL) { - ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction active"); - lmdb->error = MDB_PANIC; - return ldb_mdb_error(lmdb->ldb, lmdb->error); - } - - lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi); - if (lmdb->error != MDB_SUCCESS) { - return ldb_mdb_error(lmdb->ldb, lmdb->error); - } - - mdb_key.mv_size = key.length; - mdb_key.mv_data = key.data; - - lmdb->error = mdb_get(txn, dbi, &mdb_key, &mdb_data); - if (lmdb->error != MDB_SUCCESS) { - /* TODO closing a handle should not even be necessary */ - mdb_dbi_close(lmdb->env, dbi); - if (lmdb->error == MDB_NOTFOUND) { - return LDB_ERR_NO_SUCH_OBJECT; - } - return ldb_mdb_error(lmdb->ldb, lmdb->error); - } - data.data = mdb_data.mv_data; - data.length = mdb_data.mv_size; - - /* TODO closing a handle should not even be necessary */ - mdb_dbi_close(lmdb->env, dbi); - - return parser(key, data, ctx); -} - -/* - * Exactly the same as iterate, except we have a start key and an end key - * (which are both included in the results if present). - * - * If start > end, return MDB_PANIC. - */ -static int lmdb_iterate_range(struct ldb_kv_private *ldb_kv, - struct ldb_val start_key, - struct ldb_val end_key, - ldb_kv_traverse_fn fn, - void *ctx) -{ - struct lmdb_private *lmdb = ldb_kv->lmdb_private; - MDB_val mdb_key; - MDB_val mdb_data; - MDB_txn *txn = NULL; - MDB_dbi dbi = 0; - MDB_cursor *cursor = NULL; - int ret; - - MDB_val mdb_s_key; - MDB_val mdb_e_key; - - txn = get_current_txn(lmdb); - if (txn == NULL) { - ldb_debug(lmdb->ldb, LDB_DEBUG_FATAL, "No transaction"); - lmdb->error = MDB_PANIC; - return ldb_mdb_error(lmdb->ldb, lmdb->error); - } - - lmdb->error = mdb_dbi_open(txn, NULL, 0, &dbi); - if (lmdb->error != MDB_SUCCESS) { - return ldb_mdb_error(lmdb->ldb, lmdb->error); - } - - mdb_s_key.mv_size = start_key.length; - mdb_s_key.mv_data = start_key.data; - - mdb_e_key.mv_size = end_key.length; - mdb_e_key.mv_data = end_key.data; - - if (mdb_cmp(txn, dbi, &mdb_s_key, &mdb_e_key) > 0) { - lmdb->error = MDB_PANIC; - return ldb_mdb_error(lmdb->ldb, lmdb->error); - } - - lmdb->error = mdb_cursor_open(txn, dbi, &cursor); - if (lmdb->error != MDB_SUCCESS) { - goto done; - } - - lmdb->error = mdb_cursor_get(cursor, &mdb_s_key, &mdb_data, MDB_SET_RANGE); - - if (lmdb->error != MDB_SUCCESS) { - if (lmdb->error == MDB_NOTFOUND) { - lmdb->error = MDB_SUCCESS; - } - goto done; - } else { - struct ldb_val key = { - .length = mdb_s_key.mv_size, - .data = mdb_s_key.mv_data, - }; - struct ldb_val data = { - .length = mdb_data.mv_size, - .data = mdb_data.mv_data, - }; - - if (mdb_cmp(txn, dbi, &mdb_s_key, &mdb_e_key) > 0) { - goto done; - } - - ret = fn(ldb_kv, key, data, ctx); - if (ret != 0) { - /* - * NOTE: This DOES NOT set lmdb->error! - * - * This means that the caller will get success. - * This matches TDB traverse behaviour, where callbacks - * may terminate the traverse, but do not change the - * return code from success. - * - * Callers SHOULD store their own error codes. - */ - goto done; - } - } - - while ((lmdb->error = mdb_cursor_get( - cursor, &mdb_key, - &mdb_data, MDB_NEXT)) == MDB_SUCCESS) { - - struct ldb_val key = { - .length = mdb_key.mv_size, - .data = mdb_key.mv_data, - }; - struct ldb_val data = { - .length = mdb_data.mv_size, - .data = mdb_data.mv_data, - }; - - if (mdb_cmp(txn, dbi, &mdb_key, &mdb_e_key) > 0) { - goto done; - } - - ret = fn(ldb_kv, key, data, ctx); - if (ret != 0) { - /* - * NOTE: This DOES NOT set lmdb->error! - * - * This means that the caller will get success. - * This matches TDB traverse behaviour, where callbacks - * may terminate the traverse, but do not change the - * return code from success. - * - * Callers SHOULD store their own error codes. - */ - goto done; - } - } - if (lmdb->error == MDB_NOTFOUND) { - lmdb->error = MDB_SUCCESS; - } -done: - if (cursor != NULL) { - mdb_cursor_close(cursor); - } - - if (lmdb->error != MDB_SUCCESS) { - return ldb_mdb_error(lmdb->ldb, lmdb->error); - } - return ldb_mdb_err_map(lmdb->error); -} - -static int lmdb_lock_read(struct ldb_module *module) -{ - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - struct lmdb_private *lmdb = ldb_kv->lmdb_private; - pid_t pid = getpid(); - - if (pid != lmdb->pid) { - ldb_asprintf_errstring( - lmdb->ldb, - __location__": Reusing ldb opened by pid %d in " - "process %d\n", - lmdb->pid, - pid); - lmdb->error = MDB_BAD_TXN; - return LDB_ERR_PROTOCOL_ERROR; - } - - lmdb->error = MDB_SUCCESS; - if (lmdb_transaction_active(ldb_kv) == false && - ldb_kv->read_lock_count == 0) { - lmdb->error = mdb_txn_begin(lmdb->env, - NULL, - MDB_RDONLY, - &lmdb->read_txn); - } - if (lmdb->error != MDB_SUCCESS) { - return ldb_mdb_error(lmdb->ldb, lmdb->error); - } - - ldb_kv->read_lock_count++; - return ldb_mdb_err_map(lmdb->error); -} - -static int lmdb_unlock_read(struct ldb_module *module) -{ - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - - if (lmdb_transaction_active(ldb_kv) == false && - ldb_kv->read_lock_count == 1) { - struct lmdb_private *lmdb = ldb_kv->lmdb_private; - mdb_txn_commit(lmdb->read_txn); - lmdb->read_txn = NULL; - ldb_kv->read_lock_count--; - return LDB_SUCCESS; - } - ldb_kv->read_lock_count--; - return LDB_SUCCESS; -} - -static int lmdb_transaction_start(struct ldb_kv_private *ldb_kv) -{ - struct lmdb_private *lmdb = ldb_kv->lmdb_private; - struct lmdb_trans *ltx; - struct lmdb_trans *ltx_head; - MDB_txn *tx_parent; - pid_t pid = getpid(); - - /* Do not take out the transaction lock on a read-only DB */ - if (ldb_kv->read_only) { - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - ltx = talloc_zero(lmdb, struct lmdb_trans); - if (ltx == NULL) { - return ldb_oom(lmdb->ldb); - } - - if (pid != lmdb->pid) { - ldb_asprintf_errstring( - lmdb->ldb, - __location__": Reusing ldb opened by pid %d in " - "process %d\n", - lmdb->pid, - pid); - lmdb->error = MDB_BAD_TXN; - return LDB_ERR_PROTOCOL_ERROR; - } - - ltx_head = lmdb_private_trans_head(lmdb); - - tx_parent = lmdb_trans_get_tx(ltx_head); - - lmdb->error = mdb_txn_begin(lmdb->env, tx_parent, 0, <x->tx); - if (lmdb->error != MDB_SUCCESS) { - return ldb_mdb_error(lmdb->ldb, lmdb->error); - } - - trans_push(lmdb, ltx); - - return ldb_mdb_err_map(lmdb->error); -} - -static int lmdb_transaction_cancel(struct ldb_kv_private *ldb_kv) -{ - struct lmdb_trans *ltx; - struct lmdb_private *lmdb = ldb_kv->lmdb_private; - - ltx = lmdb_private_trans_head(lmdb); - if (ltx == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - mdb_txn_abort(ltx->tx); - trans_finished(lmdb, ltx); - return LDB_SUCCESS; -} - -static int lmdb_transaction_prepare_commit(struct ldb_kv_private *ldb_kv) -{ - /* No need to prepare a commit */ - return LDB_SUCCESS; -} - -static int lmdb_transaction_commit(struct ldb_kv_private *ldb_kv) -{ - struct lmdb_trans *ltx; - struct lmdb_private *lmdb = ldb_kv->lmdb_private; - - ltx = lmdb_private_trans_head(lmdb); - if (ltx == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - lmdb->error = mdb_txn_commit(ltx->tx); - trans_finished(lmdb, ltx); - - return lmdb->error; -} - -static int lmdb_error(struct ldb_kv_private *ldb_kv) -{ - return ldb_mdb_err_map(ldb_kv->lmdb_private->error); -} - -static const char *lmdb_errorstr(struct ldb_kv_private *ldb_kv) -{ - return mdb_strerror(ldb_kv->lmdb_private->error); -} - -static const char *lmdb_name(struct ldb_kv_private *ldb_kv) -{ - return "lmdb"; -} - -static bool lmdb_changed(struct ldb_kv_private *ldb_kv) -{ - /* - * lmdb does no provide a quick way to determine if the database - * has changed. This function always returns true. - * - * Note that tdb uses a sequence number that allows this function - * to be implemented efficiently. - */ - return true; -} - -/* - * Get the number of records in the database. - * - * The mdb_env_stat call returns an accurate count, so we return the actual - * number of records in the database rather than an estimate. - */ -static size_t lmdb_get_size(struct ldb_kv_private *ldb_kv) -{ - - struct MDB_stat stats = {0}; - struct lmdb_private *lmdb = ldb_kv->lmdb_private; - int ret = 0; - - ret = mdb_env_stat(lmdb->env, &stats); - if (ret != 0) { - return 0; - } - return stats.ms_entries; -} - -/* - * Start a sub transaction - * As lmdb supports nested transactions we can start a new transaction - */ -static int lmdb_nested_transaction_start(struct ldb_kv_private *ldb_kv) -{ - int ret = lmdb_transaction_start(ldb_kv); - return ret; -} - -/* - * Commit a sub transaction - * As lmdb supports nested transactions we can commit the nested transaction - */ -static int lmdb_nested_transaction_commit(struct ldb_kv_private *ldb_kv) -{ - int ret = lmdb_transaction_commit(ldb_kv); - return ret; -} - -/* - * Cancel a sub transaction - * As lmdb supports nested transactions we can cancel the nested transaction - */ -static int lmdb_nested_transaction_cancel(struct ldb_kv_private *ldb_kv) -{ - int ret = lmdb_transaction_cancel(ldb_kv); - return ret; -} - -static struct kv_db_ops lmdb_key_value_ops = { - .options = LDB_KV_OPTION_STABLE_READ_LOCK, - - .store = lmdb_store, - .delete = lmdb_delete, - .iterate = lmdb_traverse_fn, - .update_in_iterate = lmdb_update_in_iterate, - .fetch_and_parse = lmdb_parse_record, - .iterate_range = lmdb_iterate_range, - .lock_read = lmdb_lock_read, - .unlock_read = lmdb_unlock_read, - .begin_write = lmdb_transaction_start, - .prepare_write = lmdb_transaction_prepare_commit, - .finish_write = lmdb_transaction_commit, - .abort_write = lmdb_transaction_cancel, - .error = lmdb_error, - .errorstr = lmdb_errorstr, - .name = lmdb_name, - .has_changed = lmdb_changed, - .transaction_active = lmdb_transaction_active, - .get_size = lmdb_get_size, - .begin_nested_write = lmdb_nested_transaction_start, - .finish_nested_write = lmdb_nested_transaction_commit, - .abort_nested_write = lmdb_nested_transaction_cancel, -}; - -static const char *lmdb_get_path(const char *url) -{ - const char *path; - - /* parse the url */ - if (strchr(url, ':')) { - if (strncmp(url, MDB_URL_PREFIX, MDB_URL_PREFIX_SIZE) != 0) { - return NULL; - } - path = url + MDB_URL_PREFIX_SIZE; - } else { - path = url; - } - - return path; -} - -static int lmdb_pvt_destructor(struct lmdb_private *lmdb) -{ - struct lmdb_trans *ltx = NULL; - - /* Check if this is a forked child */ - if (getpid() != lmdb->pid) { - int fd = 0; - /* - * We cannot call mdb_env_close or commit any transactions, - * otherwise they might appear finished in the parent. - * - */ - - if (mdb_env_get_fd(lmdb->env, &fd) == 0) { - close(fd); - } - - /* Remove the pointer, so that no access should occur */ - lmdb->env = NULL; - - return 0; - } - - /* - * Close the read transaction if it's open - */ - if (lmdb->read_txn != NULL) { - mdb_txn_abort(lmdb->read_txn); - } - - if (lmdb->env == NULL) { - return 0; - } - - /* - * Abort any currently active transactions - */ - ltx = lmdb_private_trans_head(lmdb); - while (ltx != NULL) { - mdb_txn_abort(ltx->tx); - trans_finished(lmdb, ltx); - ltx = lmdb_private_trans_head(lmdb); - } - lmdb->env = NULL; - - return 0; -} - -struct mdb_env_wrap { - struct mdb_env_wrap *next, *prev; - dev_t device; - ino_t inode; - MDB_env *env; - pid_t pid; -}; - -static struct mdb_env_wrap *mdb_list; - -/* destroy the last connection to an mdb */ -static int mdb_env_wrap_destructor(struct mdb_env_wrap *w) -{ - mdb_env_close(w->env); - DLIST_REMOVE(mdb_list, w); - return 0; -} - -static int lmdb_open_env(TALLOC_CTX *mem_ctx, - MDB_env **env, - struct ldb_context *ldb, - const char *path, - const size_t env_map_size, - unsigned int flags) -{ - int ret; - unsigned int mdb_flags = MDB_NOSUBDIR|MDB_NOTLS; - /* - * MDB_NOSUBDIR implies there is a separate file called path and a - * separate lockfile called path-lock - */ - - struct mdb_env_wrap *w; - struct stat st; - pid_t pid = getpid(); - int fd = 0; - unsigned v; - - if (stat(path, &st) == 0) { - for (w=mdb_list;w;w=w->next) { - if (st.st_dev == w->device && - st.st_ino == w->inode && - pid == w->pid) { - /* - * We must have only one MDB_env per process - */ - if (!talloc_reference(mem_ctx, w)) { - return ldb_oom(ldb); - } - *env = w->env; - return LDB_SUCCESS; - } - } - } - - w = talloc(mem_ctx, struct mdb_env_wrap); - if (w == NULL) { - return ldb_oom(ldb); - } - - ret = mdb_env_create(env); - if (ret != 0) { - ldb_asprintf_errstring( - ldb, - "Could not create MDB environment %s: %s\n", - path, - mdb_strerror(ret)); - return ldb_mdb_err_map(ret); - } - - if (env_map_size > 0) { - ret = mdb_env_set_mapsize(*env, env_map_size); - if (ret != 0) { - ldb_asprintf_errstring( - ldb, - "Could not set MDB mmap() size to %llu " - "on %s: %s\n", - (unsigned long long)(env_map_size), - path, - mdb_strerror(ret)); - TALLOC_FREE(w); - return ldb_mdb_err_map(ret); - } - } - - mdb_env_set_maxreaders(*env, 100000); - /* - * As we ensure that there is only one MDB_env open per database per - * process. We can not use the MDB_RDONLY flag, as another ldb may be - * opened in read write mode - */ - if (flags & LDB_FLG_NOSYNC) { - mdb_flags |= MDB_NOSYNC; - } - ret = mdb_env_open(*env, path, mdb_flags, 0644); - if (ret != 0) { - ldb_asprintf_errstring(ldb, - "Could not open DB %s: %s\n", - path, mdb_strerror(ret)); - TALLOC_FREE(w); - return ldb_mdb_err_map(ret); - } - - { - MDB_envinfo stat = {0}; - ret = mdb_env_info (*env, &stat); - if (ret != 0) { - ldb_asprintf_errstring( - ldb, - "Could not get MDB environment stats %s: %s\n", - path, - mdb_strerror(ret)); - return ldb_mdb_err_map(ret); - } - } - - ret = mdb_env_get_fd(*env, &fd); - if (ret != 0) { - ldb_asprintf_errstring(ldb, - "Could not obtain DB FD %s: %s\n", - path, mdb_strerror(ret)); - TALLOC_FREE(w); - return ldb_mdb_err_map(ret); - } - - /* Just as for TDB: on exec, don't inherit the fd */ - v = fcntl(fd, F_GETFD, 0); - if (v == -1) { - TALLOC_FREE(w); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = fcntl(fd, F_SETFD, v | FD_CLOEXEC); - if (ret == -1) { - TALLOC_FREE(w); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (fstat(fd, &st) != 0) { - ldb_asprintf_errstring( - ldb, - "Could not stat %s:\n", - path); - TALLOC_FREE(w); - return LDB_ERR_OPERATIONS_ERROR; - } - w->env = *env; - w->device = st.st_dev; - w->inode = st.st_ino; - w->pid = pid; - - talloc_set_destructor(w, mdb_env_wrap_destructor); - - DLIST_ADD(mdb_list, w); - - return LDB_SUCCESS; - -} - -static int lmdb_pvt_open(struct lmdb_private *lmdb, - struct ldb_context *ldb, - const char *path, - const size_t env_map_size, - unsigned int flags) -{ - int ret; - int lmdb_max_key_length; - - if (flags & LDB_FLG_DONT_CREATE_DB) { - struct stat st; - if (stat(path, &st) != 0) { - return LDB_ERR_UNAVAILABLE; - } - } - - ret = lmdb_open_env(lmdb, &lmdb->env, ldb, path, env_map_size, flags); - if (ret != 0) { - return ret; - } - - /* Close when lmdb is released */ - talloc_set_destructor(lmdb, lmdb_pvt_destructor); - - /* Store the original pid during the LMDB open */ - lmdb->pid = getpid(); - - lmdb_max_key_length = mdb_env_get_maxkeysize(lmdb->env); - - /* This will never happen, but if it does make sure to freak out */ - if (lmdb_max_key_length < LDB_MDB_MAX_KEY_LENGTH) { - return ldb_operr(ldb); - } - - return LDB_SUCCESS; -} - -int lmdb_connect(struct ldb_context *ldb, - const char *url, - unsigned int flags, - const char *options[], - struct ldb_module **_module) -{ - const char *path = NULL; - struct lmdb_private *lmdb = NULL; - struct ldb_kv_private *ldb_kv = NULL; - int ret; - size_t env_map_size = 0; - - /* - * We hold locks, so we must use a private event context - * on each returned handle - */ - ldb_set_require_private_event_context(ldb); - - path = lmdb_get_path(url); - if (path == NULL) { - ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid mdb URL '%s'", url); - return LDB_ERR_OPERATIONS_ERROR; - } - - ldb_kv = talloc_zero(ldb, struct ldb_kv_private); - if (!ldb_kv) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - lmdb = talloc_zero(ldb_kv, struct lmdb_private); - if (lmdb == NULL) { - TALLOC_FREE(ldb_kv); - return ldb_oom(ldb); - } - lmdb->ldb = ldb; - ldb_kv->kv_ops = &lmdb_key_value_ops; - - { - const char *size = ldb_options_find( - ldb, ldb->options, "lmdb_env_size"); - if (size != NULL) { - env_map_size = strtoull(size, NULL, 0); - } - } - - ret = lmdb_pvt_open(lmdb, ldb, path, env_map_size, flags); - if (ret != LDB_SUCCESS) { - TALLOC_FREE(ldb_kv); - return ret; - } - - ldb_kv->lmdb_private = lmdb; - if (flags & LDB_FLG_RDONLY) { - ldb_kv->read_only = true; - } - - /* - * This maximum length becomes encoded in the index values so - * must never change even if LMDB starts to allow longer keys. - * The override option is max_key_len_for_self_test, and is - * used for testing only. - */ - ldb_kv->max_key_length = LDB_MDB_MAX_KEY_LENGTH; - - return ldb_kv_init_store( - ldb_kv, "ldb_mdb backend", ldb, options, _module); -} diff --git a/ldb-2.0.8/ldb_mdb/ldb_mdb.h b/ldb-2.0.8/ldb_mdb/ldb_mdb.h deleted file mode 100644 index 8f21493..0000000 --- a/ldb-2.0.8/ldb_mdb/ldb_mdb.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - ldb database library using mdb back end - transaction operations - - Copyright (C) Jakub Hrozek 2015 - Copyright (C) Catalyst.Net Ltd 2017 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#ifndef _LDB_MDB_H_ -#define _LDB_MDB_H_ - -#include "ldb_private.h" -#include - -struct lmdb_private { - struct ldb_context *ldb; - MDB_env *env; - - struct lmdb_trans *txlist; - - struct ldb_mdb_metadata { - struct ldb_message *attributes; - unsigned seqnum; - } *meta; - int error; - MDB_txn *read_txn; - - pid_t pid; - -}; - -struct lmdb_trans { - struct lmdb_trans *next; - struct lmdb_trans *prev; - - MDB_txn *tx; -}; - -int ldb_mdb_err_map(int lmdb_err); -int lmdb_connect(struct ldb_context *ldb, const char *url, - unsigned int flags, const char *options[], - struct ldb_module **_module); - -#endif /* _LDB_MDB_H_ */ diff --git a/ldb-2.0.8/ldb_mdb/ldb_mdb_init.c b/ldb-2.0.8/ldb_mdb/ldb_mdb_init.c deleted file mode 100644 index 339c3f2..0000000 --- a/ldb-2.0.8/ldb_mdb/ldb_mdb_init.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - ldb database library using mdb back end - - Copyright (C) Jakub Hrozek 2014 - Copyright (C) Catalyst.Net Ltd 2017 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "ldb_mdb.h" - -int ldb_mdb_init(const char *version) -{ - LDB_MODULE_CHECK_VERSION(version); - return ldb_register_backend("mdb", lmdb_connect, false); -} diff --git a/ldb-2.0.8/ldb_sqlite3/README b/ldb-2.0.8/ldb_sqlite3/README deleted file mode 100644 index 6cda0a7..0000000 --- a/ldb-2.0.8/ldb_sqlite3/README +++ /dev/null @@ -1,7 +0,0 @@ -trees.ps contains an explanation of the Genealogical Representation of Trees -in Databases which is being used in ldb_sqlite3. Note that we use fgID -representation with 4 bytes per level, so we can represent 6.5E+08 subclasses -of any object class. This should be adequate for our purposes. :-) - -The following document is the primary basis for the schema currently being -used here: http://www.research.ibm.com/journal/sj/392/shi.html diff --git a/ldb-2.0.8/ldb_sqlite3/base160.c b/ldb-2.0.8/ldb_sqlite3/base160.c deleted file mode 100644 index 7ad39f7..0000000 --- a/ldb-2.0.8/ldb_sqlite3/base160.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - base160 code used by ldb_sqlite3 - - Copyright (C) 2004 Derrell Lipman - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - - -/* - * ldb_sqlite3_base160() - * - * Convert an integer value to a string containing the base 160 representation - * of the integer. We always convert to a string representation that is 4 - * bytes in length, and we always null terminate. - * - * Parameters: - * val -- - * The value to be converted - * - * result -- - * Buffer in which the result is to be placed - * - * Returns: - * nothing - */ -static unsigned char base160tab[161] = -{ - 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , /* 0-9 */ - 58 , 59 , 65 , 66 , 67 , 68 , 69 , 70 , 71 , 72 , /* : ; A-H */ - 73 , 74 , 75 , 76 , 77 , 78 , 79 , 80 , 81 , 82 , /* I-R */ - 83 , 84 , 85 , 86 , 87 , 88 , 89 , 90 , 97 , 98 , /* S-Z , a-b */ - 99 , 100, 101, 102, 103, 104, 105, 106, 107, 108, /* c-l */ - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, /* m-v */ - 119, 120, 121, 122, 160, 161, 162, 163, 164, 165, /* w-z, latin1 */ - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, /* latin1 */ - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, /* latin1 */ - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, /* latin1 */ - 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, /* latin1 */ - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, /* latin1 */ - 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, /* latin1 */ - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, /* latin1 */ - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, /* latin1 */ - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, /* latin1 */ - '\0' -}; - - -/* - * lsqlite3_base160() - * - * Convert an unsigned long integer into a base160 representation of the - * number. - * - * Parameters: - * val -- - * value to be converted - * - * result -- - * character array, 5 bytes long, into which the base160 representation - * will be placed. The result will be a four-digit representation of the - * number (with leading zeros prepended as necessary), and null - * terminated. - * - * Returns: - * Nothing - */ -void -lsqlite3_base160(unsigned long val, - unsigned char result[5]) -{ - int i; - - for (i = 3; i >= 0; i--) { - - result[i] = base160tab[val % 160]; - val /= 160; - } - - result[4] = '\0'; -} - - -/* - * lsqlite3_base160Next() - * - * Retrieve the next-greater number in the base160 sequence for the terminal - * tree node (the last four digits). Only one tree level (four digits) are - * operated on. - * - * Parameters: - * base160 -- a character array containing either an empty string (in which - * case no operation is performed), or a string of base160 digits - * with a length of a multiple of four digits. - * - * Upon return, the trailing four digits (one tree level) will - * have been incremented by 1. - * - * Returns: - * base160 -- the modified array - */ -char * -lsqlite3_base160Next(char base160[]) -{ - int i; - int len; - unsigned char * pTab; - char * pBase160 = base160; - - /* - * We need a minimum of four digits, and we will always get a multiple of - * four digits. - */ - if ((len = strlen(pBase160)) >= 4) - { - pBase160 += strlen(pBase160) - 1; - - /* We only carry through four digits: one level in the tree */ - for (i = 0; i < 4; i++) { - - /* What base160 value does this digit have? */ - pTab = strchr(base160tab, *pBase160); - - /* Is there a carry? */ - if (pTab < base160tab + sizeof(base160tab) - 1) { - - /* Nope. Just increment this value and we're done. */ - *pBase160 = *++pTab; - break; - } else { - - /* - * There's a carry. This value gets base160tab[0], we - * decrement the buffer pointer to get the next higher-order - * digit, and continue in the loop. - */ - *pBase160-- = base160tab[0]; - } - } - } - - return base160; -} diff --git a/ldb-2.0.8/ldb_sqlite3/ldb_sqlite3.c b/ldb-2.0.8/ldb_sqlite3/ldb_sqlite3.c deleted file mode 100644 index 0f5abf8..0000000 --- a/ldb-2.0.8/ldb_sqlite3/ldb_sqlite3.c +++ /dev/null @@ -1,1958 +0,0 @@ -/* - ldb database library - - Copyright (C) Derrell Lipman 2005 - Copyright (C) Simo Sorce 2005-2009 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb sqlite3 backend - * - * Description: core files for SQLITE3 backend - * - * Author: Derrell Lipman (based on Andrew Tridgell's LDAP backend) - */ - -#include "ldb_module.h" - -#include - -struct lsqlite3_private { - int trans_count; - char **options; - sqlite3 *sqlite; -}; - -struct lsql_context { - struct ldb_module *module; - struct ldb_request *req; - - /* search stuff */ - long long current_eid; - const char * const * attrs; - struct ldb_reply *ares; - - bool callback_failed; - struct tevent_timer *timeout_event; -}; - -/* - * Macros used throughout - */ - -#ifndef FALSE -# define FALSE (0) -# define TRUE (! FALSE) -#endif - -#define RESULT_ATTR_TABLE "temp_result_attrs" - - -/* for testing, define to nothing, (create non-temporary table) */ -#define TEMPTAB "TEMPORARY" - -/* - * Static variables - */ -sqlite3_stmt * stmtGetEID = NULL; - -static char *lsqlite3_tprintf(TALLOC_CTX *mem_ctx, const char *fmt, ...) -{ - char *str, *ret; - va_list ap; - - va_start(ap, fmt); - str = sqlite3_vmprintf(fmt, ap); - va_end(ap); - - if (str == NULL) return NULL; - - ret = talloc_strdup(mem_ctx, str); - if (ret == NULL) { - sqlite3_free(str); - return NULL; - } - - sqlite3_free(str); - return ret; -} - -static char base160tab[161] = { - 48 ,49 ,50 ,51 ,52 ,53 ,54 ,55 ,56 ,57 , /* 0-9 */ - 58 ,59 ,65 ,66 ,67 ,68 ,69 ,70 ,71 ,72 , /* : ; A-H */ - 73 ,74 ,75 ,76 ,77 ,78 ,79 ,80 ,81 ,82 , /* I-R */ - 83 ,84 ,85 ,86 ,87 ,88 ,89 ,90 ,97 ,98 , /* S-Z , a-b */ - 99 ,100,101,102,103,104,105,106,107,108, /* c-l */ - 109,110,111,112,113,114,115,116,117,118, /* m-v */ - 119,120,121,122,160,161,162,163,164,165, /* w-z, latin1 */ - 166,167,168,169,170,171,172,173,174,175, /* latin1 */ - 176,177,178,179,180,181,182,183,184,185, /* latin1 */ - 186,187,188,189,190,191,192,193,194,195, /* latin1 */ - 196,197,198,199,200,201,202,203,204,205, /* latin1 */ - 206,207,208,209,210,211,212,213,214,215, /* latin1 */ - 216,217,218,219,220,221,222,223,224,225, /* latin1 */ - 226,227,228,229,230,231,232,233,234,235, /* latin1 */ - 236,237,238,239,240,241,242,243,244,245, /* latin1 */ - 246,247,248,249,250,251,252,253,254,255, /* latin1 */ - '\0' -}; - - -/* - * base160() - * - * Convert an unsigned long integer into a base160 representation of the - * number. - * - * Parameters: - * val -- - * value to be converted - * - * result -- - * character array, 5 bytes long, into which the base160 representation - * will be placed. The result will be a four-digit representation of the - * number (with leading zeros prepended as necessary), and null - * terminated. - * - * Returns: - * Nothing - */ -static void -base160_sql(sqlite3_context * hContext, - int argc, - sqlite3_value ** argv) -{ - int i; - long long val; - char result[5]; - - val = sqlite3_value_int64(argv[0]); - - for (i = 3; i >= 0; i--) { - - result[i] = base160tab[val % 160]; - val /= 160; - } - - result[4] = '\0'; - - sqlite3_result_text(hContext, result, -1, SQLITE_TRANSIENT); -} - - -/* - * base160next_sql() - * - * This function enhances sqlite by adding a "base160_next()" function which is - * accessible via queries. - * - * Retrieve the next-greater number in the base160 sequence for the terminal - * tree node (the last four digits). Only one tree level (four digits) is - * operated on. - * - * Input: - * A character string: either an empty string (in which case no operation is - * performed), or a string of base160 digits with a length of a multiple of - * four digits. - * - * Output: - * Upon return, the trailing four digits (one tree level) will have been - * incremented by 1. - */ -static void -base160next_sql(sqlite3_context * hContext, - int argc, - sqlite3_value ** argv) -{ - int i; - int len; - char * pTab; - char * pBase160 = strdup((const char *)sqlite3_value_text(argv[0])); - char * pStart = pBase160; - - /* - * We need a minimum of four digits, and we will always get a multiple - * of four digits. - */ - if (pBase160 != NULL && - (len = strlen(pBase160)) >= 4 && - len % 4 == 0) { - - if (pBase160 == NULL) { - - sqlite3_result_null(hContext); - return; - } - - pBase160 += strlen(pBase160) - 1; - - /* We only carry through four digits: one level in the tree */ - for (i = 0; i < 4; i++) { - - /* What base160 value does this digit have? */ - pTab = strchr(base160tab, *pBase160); - - /* Is there a carry? */ - if (pTab < base160tab + sizeof(base160tab) - 1) { - - /* - * Nope. Just increment this value and we're - * done. - */ - *pBase160 = *++pTab; - break; - } else { - - /* - * There's a carry. This value gets - * base160tab[0], we decrement the buffer - * pointer to get the next higher-order digit, - * and continue in the loop. - */ - *pBase160-- = base160tab[0]; - } - } - - sqlite3_result_text(hContext, - pStart, - strlen(pStart), - free); - } else { - sqlite3_result_value(hContext, argv[0]); - if (pBase160 != NULL) { - free(pBase160); - } - } -} - -static char *parsetree_to_sql(struct ldb_module *module, - void *mem_ctx, - const struct ldb_parse_tree *t) -{ - struct ldb_context *ldb; - const struct ldb_schema_attribute *a; - struct ldb_val value, subval; - char *wild_card_string; - char *child, *tmp; - char *ret = NULL; - char *attr; - unsigned int i; - - ldb = ldb_module_get_ctx(module); - - switch(t->operation) { - case LDB_OP_AND: - - tmp = parsetree_to_sql(module, mem_ctx, t->u.list.elements[0]); - if (tmp == NULL) return NULL; - - for (i = 1; i < t->u.list.num_elements; i++) { - - child = parsetree_to_sql(module, mem_ctx, t->u.list.elements[i]); - if (child == NULL) return NULL; - - tmp = talloc_asprintf_append(tmp, " INTERSECT %s ", child); - if (tmp == NULL) return NULL; - } - - ret = talloc_asprintf(mem_ctx, "SELECT * FROM ( %s )\n", tmp); - - return ret; - - case LDB_OP_OR: - - tmp = parsetree_to_sql(module, mem_ctx, t->u.list.elements[0]); - if (tmp == NULL) return NULL; - - for (i = 1; i < t->u.list.num_elements; i++) { - - child = parsetree_to_sql(module, mem_ctx, t->u.list.elements[i]); - if (child == NULL) return NULL; - - tmp = talloc_asprintf_append(tmp, " UNION %s ", child); - if (tmp == NULL) return NULL; - } - - return talloc_asprintf(mem_ctx, "SELECT * FROM ( %s ) ", tmp); - - case LDB_OP_NOT: - - child = parsetree_to_sql(module, mem_ctx, t->u.isnot.child); - if (child == NULL) return NULL; - - return talloc_asprintf(mem_ctx, - "SELECT eid FROM ldb_entry " - "WHERE eid NOT IN ( %s ) ", child); - - case LDB_OP_EQUALITY: - /* - * For simple searches, we want to retrieve the list of EIDs that - * match the criteria. - */ - attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); - if (attr == NULL) return NULL; - a = ldb_schema_attribute_by_name(ldb, attr); - - /* Get a canonicalised copy of the data */ - a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.equality.value), &value); - if (value.data == NULL) { - return NULL; - } - - if (strcasecmp(t->u.equality.attr, "dn") == 0) { - /* DN query is a special ldb case */ - const char *cdn = ldb_dn_get_casefold( - ldb_dn_new(mem_ctx, ldb, - (const char *)value.data)); - if (cdn == NULL) { - return NULL; - } - - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_entry " - "WHERE norm_dn = '%q'", cdn); - - } else { - /* A normal query. */ - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_attribute_values " - "WHERE norm_attr_name = '%q' " - "AND norm_attr_value = '%q'", - attr, - value.data); - - } - - case LDB_OP_SUBSTRING: - - wild_card_string = talloc_strdup(mem_ctx, - (t->u.substring.start_with_wildcard)?"*":""); - if (wild_card_string == NULL) return NULL; - - for (i = 0; t->u.substring.chunks[i]; i++) { - wild_card_string = talloc_asprintf_append(wild_card_string, "%s*", - t->u.substring.chunks[i]->data); - if (wild_card_string == NULL) return NULL; - } - - if ( ! t->u.substring.end_with_wildcard ) { - /* remove last wildcard */ - wild_card_string[strlen(wild_card_string) - 1] = '\0'; - } - - attr = ldb_attr_casefold(mem_ctx, t->u.substring.attr); - if (attr == NULL) return NULL; - a = ldb_schema_attribute_by_name(ldb, attr); - - subval.data = (void *)wild_card_string; - subval.length = strlen(wild_card_string) + 1; - - /* Get a canonicalised copy of the data */ - a->syntax->canonicalise_fn(ldb, mem_ctx, &(subval), &value); - if (value.data == NULL) { - return NULL; - } - - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_attribute_values " - "WHERE norm_attr_name = '%q' " - "AND norm_attr_value GLOB '%q'", - attr, - value.data); - - case LDB_OP_GREATER: - attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); - if (attr == NULL) return NULL; - a = ldb_schema_attribute_by_name(ldb, attr); - - /* Get a canonicalised copy of the data */ - a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.equality.value), &value); - if (value.data == NULL) { - return NULL; - } - - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_attribute_values " - "WHERE norm_attr_name = '%q' " - "AND ldap_compare(norm_attr_value, '>=', '%q', '%q') ", - attr, - value.data, - attr); - - case LDB_OP_LESS: - attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); - if (attr == NULL) return NULL; - a = ldb_schema_attribute_by_name(ldb, attr); - - /* Get a canonicalised copy of the data */ - a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.equality.value), &value); - if (value.data == NULL) { - return NULL; - } - - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_attribute_values " - "WHERE norm_attr_name = '%q' " - "AND ldap_compare(norm_attr_value, '<=', '%q', '%q') ", - attr, - value.data, - attr); - - case LDB_OP_PRESENT: - if (strcasecmp(t->u.present.attr, "dn") == 0) { - return talloc_strdup(mem_ctx, "SELECT eid FROM ldb_entry"); - } - - attr = ldb_attr_casefold(mem_ctx, t->u.present.attr); - if (attr == NULL) return NULL; - - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_attribute_values " - "WHERE norm_attr_name = '%q' ", - attr); - - case LDB_OP_APPROX: - attr = ldb_attr_casefold(mem_ctx, t->u.equality.attr); - if (attr == NULL) return NULL; - a = ldb_schema_attribute_by_name(ldb, attr); - - /* Get a canonicalised copy of the data */ - a->syntax->canonicalise_fn(ldb, mem_ctx, &(t->u.equality.value), &value); - if (value.data == NULL) { - return NULL; - } - - return lsqlite3_tprintf(mem_ctx, - "SELECT eid FROM ldb_attribute_values " - "WHERE norm_attr_name = '%q' " - "AND ldap_compare(norm_attr_value, '~%', 'q', '%q') ", - attr, - value.data, - attr); - - case LDB_OP_EXTENDED: -#warning "work out how to handle bitops" - return NULL; - - default: - break; - }; - - /* should never occur */ - abort(); - return NULL; -} - -/* - * query_int() - * - * This function is used for the common case of queries that return a single - * integer value. - * - * NOTE: If more than one value is returned by the query, all but the first - * one will be ignored. - */ -static int -query_int(const struct lsqlite3_private * lsqlite3, - long long * pRet, - const char * pSql, - ...) -{ - int ret; - int bLoop; - char * p; - sqlite3_stmt * pStmt; - va_list args; - - /* Begin access to variable argument list */ - va_start(args, pSql); - - /* Format the query */ - if ((p = sqlite3_vmprintf(pSql, args)) == NULL) { - va_end(args); - return SQLITE_NOMEM; - } - - /* - * Prepare and execute the SQL statement. Loop allows retrying on - * certain errors, e.g. SQLITE_SCHEMA occurs if the schema changes, - * requiring retrying the operation. - */ - for (bLoop = TRUE; bLoop; ) { - - /* Compile the SQL statement into sqlite virtual machine */ - if ((ret = sqlite3_prepare(lsqlite3->sqlite, - p, - -1, - &pStmt, - NULL)) == SQLITE_SCHEMA) { - if (stmtGetEID != NULL) { - sqlite3_finalize(stmtGetEID); - stmtGetEID = NULL; - } - continue; - } else if (ret != SQLITE_OK) { - break; - } - - /* One row expected */ - if ((ret = sqlite3_step(pStmt)) == SQLITE_SCHEMA) { - if (stmtGetEID != NULL) { - sqlite3_finalize(stmtGetEID); - stmtGetEID = NULL; - } - (void) sqlite3_finalize(pStmt); - continue; - } else if (ret != SQLITE_ROW) { - (void) sqlite3_finalize(pStmt); - break; - } - - /* Get the value to be returned */ - *pRet = sqlite3_column_int64(pStmt, 0); - - /* Free the virtual machine */ - if ((ret = sqlite3_finalize(pStmt)) == SQLITE_SCHEMA) { - if (stmtGetEID != NULL) { - sqlite3_finalize(stmtGetEID); - stmtGetEID = NULL; - } - continue; - } else if (ret != SQLITE_OK) { - (void) sqlite3_finalize(pStmt); - break; - } - - /* - * Normal condition is only one time through loop. Loop is - * rerun in error conditions, via "continue", above. - */ - bLoop = FALSE; - } - - /* All done with variable argument list */ - va_end(args); - - - /* Free the memory we allocated for our query string */ - sqlite3_free(p); - - return ret; -} - -/* - * This is a bad hack to support ldap style comparisons within sqlite. - * val is the attribute in the row currently under test - * func is the desired test "<=" ">=" "~" ":" - * cmp is the value to compare against (eg: "test") - * attr is the attribute name the value of which we want to test - */ - -static void lsqlite3_compare(sqlite3_context *ctx, int argc, - sqlite3_value **argv) -{ - struct ldb_context *ldb = (struct ldb_context *)sqlite3_user_data(ctx); - const char *val = (const char *)sqlite3_value_text(argv[0]); - const char *func = (const char *)sqlite3_value_text(argv[1]); - const char *cmp = (const char *)sqlite3_value_text(argv[2]); - const char *attr = (const char *)sqlite3_value_text(argv[3]); - const struct ldb_schema_attribute *a; - struct ldb_val valX; - struct ldb_val valY; - int ret; - - switch (func[0]) { - /* greater */ - case '>': /* >= */ - a = ldb_schema_attribute_by_name(ldb, attr); - valX.data = (uint8_t *)cmp; - valX.length = strlen(cmp); - valY.data = (uint8_t *)val; - valY.length = strlen(val); - ret = a->syntax->comparison_fn(ldb, ldb, &valY, &valX); - if (ret >= 0) - sqlite3_result_int(ctx, 1); - else - sqlite3_result_int(ctx, 0); - return; - - /* lesser */ - case '<': /* <= */ - a = ldb_schema_attribute_by_name(ldb, attr); - valX.data = (uint8_t *)cmp; - valX.length = strlen(cmp); - valY.data = (uint8_t *)val; - valY.length = strlen(val); - ret = a->syntax->comparison_fn(ldb, ldb, &valY, &valX); - if (ret <= 0) - sqlite3_result_int(ctx, 1); - else - sqlite3_result_int(ctx, 0); - return; - - /* approx */ - case '~': - /* TODO */ - sqlite3_result_int(ctx, 0); - return; - - /* bitops */ - case ':': - /* TODO */ - sqlite3_result_int(ctx, 0); - return; - - default: - break; - } - - sqlite3_result_error(ctx, "Value must start with a special operation char (<>~:)!", -1); - return; -} - - -/* rename a record */ -static int lsqlite3_safe_rollback(sqlite3 *sqlite) -{ - char *errmsg; - int ret; - - /* execute */ - ret = sqlite3_exec(sqlite, "ROLLBACK;", NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3_safe_rollback: Error: %s\n", errmsg); - free(errmsg); - } - return -1; - } - - return 0; -} - -/* return an eid as result */ -static int lsqlite3_eid_callback(void *result, int col_num, char **cols, char **names) -{ - long long *eid = (long long *)result; - - if (col_num != 1) return SQLITE_ABORT; - if (strcasecmp(names[0], "eid") != 0) return SQLITE_ABORT; - - *eid = atoll(cols[0]); - return SQLITE_OK; -} - -/* - * add a single set of ldap message values to a ldb_message - */ -static int lsqlite3_search_callback(void *result, int col_num, char **cols, char **names) -{ - struct ldb_context *ldb; - struct lsql_context *ac; - struct ldb_message *msg; - long long eid; - unsigned int i; - int ret; - - ac = talloc_get_type(result, struct lsql_context); - ldb = ldb_module_get_ctx(ac->module); - - /* eid, dn, attr_name, attr_value */ - if (col_num != 4) return SQLITE_ABORT; - - eid = atoll(cols[0]); - - if (ac->ares) { - msg = ac->ares->message; - } - - if (eid != ac->current_eid) { /* here begin a new entry */ - - /* call the async callback for the last entry - * except the first time */ - if (ac->current_eid != 0) { - ret = ldb_msg_normalize(ldb, ac->req, msg, &msg); - if (ret != LDB_SUCCESS) { - return SQLITE_ABORT; - } - - ret = ldb_module_send_entry(ac->req, msg, NULL); - if (ret != LDB_SUCCESS) { - ac->callback_failed = true; - /* free msg object */ - TALLOC_FREE(msg); - return SQLITE_ABORT; - } - - /* free msg object */ - TALLOC_FREE(msg); - } - - /* start over */ - ac->ares = talloc_zero(ac, struct ldb_reply); - if (!ac->ares) return SQLITE_ABORT; - - msg = ldb_msg_new(ac->ares); - if (!msg) return SQLITE_ABORT; - - ac->ares->type = LDB_REPLY_ENTRY; - ac->current_eid = eid; - } - - if (msg->dn == NULL) { - msg->dn = ldb_dn_new(msg, ldb, cols[1]); - if (msg->dn == NULL) - return SQLITE_ABORT; - } - - if (ac->attrs) { - int found = 0; - for (i = 0; ac->attrs[i]; i++) { - if (strcasecmp(cols[2], ac->attrs[i]) == 0) { - found = 1; - break; - } - } - if (!found) goto done; - } - - if (ldb_msg_add_string(msg, cols[2], cols[3]) != 0) { - return SQLITE_ABORT; - } - -done: - ac->ares->message = msg; - return SQLITE_OK; -} - - -/* - * lsqlite3_get_eid() - * lsqlite3_get_eid_ndn() - * - * These functions are used for the very common case of retrieving an EID value - * given a (normalized) DN. - */ - -static long long lsqlite3_get_eid_ndn(sqlite3 *sqlite, void *mem_ctx, const char *norm_dn) -{ - char *errmsg; - char *query; - long long eid = -1; - long long ret; - - /* get object eid */ - query = lsqlite3_tprintf(mem_ctx, "SELECT eid " - "FROM ldb_entry " - "WHERE norm_dn = '%q';", norm_dn); - if (query == NULL) return -1; - - ret = sqlite3_exec(sqlite, query, lsqlite3_eid_callback, &eid, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3_get_eid: Fatal Error: %s\n", errmsg); - free(errmsg); - } - return -1; - } - - return eid; -} - -static long long lsqlite3_get_eid(struct lsqlite3_private *lsqlite3, - struct ldb_dn *dn) -{ - TALLOC_CTX *local_ctx; - long long eid = -1; - char *cdn; - - /* ignore ltdb specials */ - if (ldb_dn_is_special(dn)) { - return -1; - } - - /* create a local ctx */ - local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_get_eid local context"); - if (local_ctx == NULL) { - return -1; - } - - cdn = ldb_dn_alloc_casefold(local_ctx, dn); - if (!cdn) goto done; - - eid = lsqlite3_get_eid_ndn(lsqlite3->sqlite, local_ctx, cdn); - -done: - talloc_free(local_ctx); - return eid; -} - -/* - * Interface functions referenced by lsqlite3_ops - */ - -/* search for matching records, by tree */ -int lsql_search(struct lsql_context *ctx) -{ - struct ldb_module *module = ctx->module; - struct ldb_request *req = ctx->req; - struct lsqlite3_private *lsqlite3; - struct ldb_context *ldb; - char *norm_basedn; - char *sqlfilter; - char *errmsg; - char *query = NULL; - int ret; - - ldb = ldb_module_get_ctx(module); - lsqlite3 = talloc_get_type(ldb_module_get_private(module), - struct lsqlite3_private); - - if ((( ! ldb_dn_is_valid(req->op.search.base)) || - ldb_dn_is_null(req->op.search.base)) && - (req->op.search.scope == LDB_SCOPE_BASE || - req->op.search.scope == LDB_SCOPE_ONELEVEL)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (req->op.search.base) { - norm_basedn = ldb_dn_alloc_casefold(ctx, req->op.search.base); - if (norm_basedn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - } else norm_basedn = talloc_strdup(ctx, ""); - - /* Convert filter into a series of SQL conditions (constraints) */ - sqlfilter = parsetree_to_sql(module, ctx, req->op.search.tree); - - switch(req->op.search.scope) { - case LDB_SCOPE_DEFAULT: - case LDB_SCOPE_SUBTREE: - if (*norm_basedn != '\0') { - query = lsqlite3_tprintf(ctx, - "SELECT entry.eid,\n" - " entry.dn,\n" - " av.attr_name,\n" - " av.attr_value\n" - " FROM ldb_entry AS entry\n" - - " LEFT OUTER JOIN ldb_attribute_values AS av\n" - " ON av.eid = entry.eid\n" - - " WHERE entry.eid IN\n" - " (SELECT DISTINCT ldb_entry.eid\n" - " FROM ldb_entry\n" - " WHERE (ldb_entry.norm_dn GLOB('*,%q')\n" - " OR ldb_entry.norm_dn = '%q')\n" - " AND ldb_entry.eid IN\n" - " (%s)\n" - " )\n" - - " ORDER BY entry.eid ASC;", - norm_basedn, - norm_basedn, - sqlfilter); - } else { - query = lsqlite3_tprintf(ctx, - "SELECT entry.eid,\n" - " entry.dn,\n" - " av.attr_name,\n" - " av.attr_value\n" - " FROM ldb_entry AS entry\n" - - " LEFT OUTER JOIN ldb_attribute_values AS av\n" - " ON av.eid = entry.eid\n" - - " WHERE entry.eid IN\n" - " (SELECT DISTINCT ldb_entry.eid\n" - " FROM ldb_entry\n" - " WHERE ldb_entry.eid IN\n" - " (%s)\n" - " )\n" - - " ORDER BY entry.eid ASC;", - sqlfilter); - } - - break; - - case LDB_SCOPE_BASE: - query = lsqlite3_tprintf(ctx, - "SELECT entry.eid,\n" - " entry.dn,\n" - " av.attr_name,\n" - " av.attr_value\n" - " FROM ldb_entry AS entry\n" - - " LEFT OUTER JOIN ldb_attribute_values AS av\n" - " ON av.eid = entry.eid\n" - - " WHERE entry.eid IN\n" - " (SELECT DISTINCT ldb_entry.eid\n" - " FROM ldb_entry\n" - " WHERE ldb_entry.norm_dn = '%q'\n" - " AND ldb_entry.eid IN\n" - " (%s)\n" - " )\n" - - " ORDER BY entry.eid ASC;", - norm_basedn, - sqlfilter); - break; - - case LDB_SCOPE_ONELEVEL: - query = lsqlite3_tprintf(ctx, - "SELECT entry.eid,\n" - " entry.dn,\n" - " av.attr_name,\n" - " av.attr_value\n" - " FROM ldb_entry AS entry\n" - - " LEFT OUTER JOIN ldb_attribute_values AS av\n" - " ON av.eid = entry.eid\n" - - " WHERE entry.eid IN\n" - " (SELECT DISTINCT ldb_entry.eid\n" - " FROM ldb_entry\n" - " WHERE norm_dn GLOB('*,%q')\n" - " AND NOT norm_dn GLOB('*,*,%q')\n" - " AND ldb_entry.eid IN\n(%s)\n" - " )\n" - - " ORDER BY entry.eid ASC;", - norm_basedn, - norm_basedn, - sqlfilter); - break; - } - - if (query == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* * / - printf ("%s\n", query); - / * */ - - ctx->current_eid = 0; - ctx->attrs = req->op.search.attrs; - ctx->ares = NULL; - - ldb_request_set_state(req, LDB_ASYNC_PENDING); - - ret = sqlite3_exec(lsqlite3->sqlite, query, lsqlite3_search_callback, ctx, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(ldb, errmsg); - free(errmsg); - } - return LDB_ERR_OPERATIONS_ERROR; - } - - /* complete the last message if any */ - if (ctx->ares) { - ret = ldb_msg_normalize(ldb, ctx->ares, - ctx->ares->message, - &ctx->ares->message); - if (ret != LDB_SUCCESS) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_module_send_entry(req, ctx->ares->message, NULL); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - - return LDB_SUCCESS; -} - -/* add a record */ -static int lsql_add(struct lsql_context *ctx) -{ - struct ldb_module *module = ctx->module; - struct ldb_request *req = ctx->req; - struct lsqlite3_private *lsqlite3; - struct ldb_context *ldb; - struct ldb_message *msg = req->op.add.message; - long long eid; - char *dn, *ndn; - char *errmsg; - char *query; - unsigned int i; - int ret; - - ldb = ldb_module_get_ctx(module); - lsqlite3 = talloc_get_type(ldb_module_get_private(module), - struct lsqlite3_private); - - /* See if this is an ltdb special */ - if (ldb_dn_is_special(msg->dn)) { -/* - struct ldb_dn *c; - c = ldb_dn_new(local_ctx, ldb, "@INDEXLIST"); - if (ldb_dn_compare(ldb, msg->dn, c) == 0) { -#warning "should we handle indexes somehow ?" - ret = LDB_ERR_UNWILLING_TO_PERFORM; - goto done; - } -*/ - /* Others return an error */ - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - /* create linearized and normalized dns */ - dn = ldb_dn_alloc_linearized(ctx, msg->dn); - ndn = ldb_dn_alloc_casefold(ctx, msg->dn); - if (dn == NULL || ndn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - query = lsqlite3_tprintf(ctx, - /* Add new entry */ - "INSERT OR ABORT INTO ldb_entry " - "('dn', 'norm_dn') " - "VALUES ('%q', '%q');", - dn, ndn); - if (query == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(ldb, errmsg); - free(errmsg); - } - return LDB_ERR_OPERATIONS_ERROR; - } - - eid = lsqlite3_get_eid_ndn(lsqlite3->sqlite, ctx, ndn); - if (eid == -1) { - return LDB_ERR_OPERATIONS_ERROR; - } - - for (i = 0; i < msg->num_elements; i++) { - const struct ldb_message_element *el = &msg->elements[i]; - const struct ldb_schema_attribute *a; - char *attr; - unsigned int j; - - /* Get a case-folded copy of the attribute name */ - attr = ldb_attr_casefold(ctx, el->name); - if (attr == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - a = ldb_schema_attribute_by_name(ldb, el->name); - - if (el->num_value == 0) { - ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illegal)", - el->name, ldb_dn_get_linearized(msg->dn)); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - - /* For each value of the specified attribute name... */ - for (j = 0; j < el->num_values; j++) { - struct ldb_val value; - char *insert; - - /* Get a canonicalised copy of the data */ - a->syntax->canonicalise_fn(ldb, ctx, &(el->values[j]), &value); - if (value.data == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - insert = lsqlite3_tprintf(ctx, - "INSERT OR ROLLBACK INTO ldb_attribute_values " - "('eid', 'attr_name', 'norm_attr_name'," - " 'attr_value', 'norm_attr_value') " - "VALUES ('%lld', '%q', '%q', '%q', '%q');", - eid, el->name, attr, - el->values[j].data, value.data); - if (insert == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = sqlite3_exec(lsqlite3->sqlite, insert, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(ldb, errmsg); - free(errmsg); - } - return LDB_ERR_OPERATIONS_ERROR; - } - } - } - - return LDB_SUCCESS; -} - -/* modify a record */ -static int lsql_modify(struct lsql_context *ctx) -{ - struct ldb_module *module = ctx->module; - struct ldb_request *req = ctx->req; - struct lsqlite3_private *lsqlite3; - struct ldb_context *ldb; - struct ldb_message *msg = req->op.mod.message; - long long eid; - char *errmsg; - unsigned int i; - int ret; - - ldb = ldb_module_get_ctx(module); - lsqlite3 = talloc_get_type(ldb_module_get_private(module), - struct lsqlite3_private); - - /* See if this is an ltdb special */ - if (ldb_dn_is_special(msg->dn)) { - /* Others return an error */ - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - eid = lsqlite3_get_eid(lsqlite3, msg->dn); - if (eid == -1) { - return LDB_ERR_OPERATIONS_ERROR; - } - - for (i = 0; i < msg->num_elements; i++) { - const struct ldb_message_element *el = &msg->elements[i]; - const struct ldb_schema_attribute *a; - unsigned int flags = el->flags & LDB_FLAG_MOD_MASK; - char *attr; - char *mod; - unsigned int j; - - /* Get a case-folded copy of the attribute name */ - attr = ldb_attr_casefold(ctx, el->name); - if (attr == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - a = ldb_schema_attribute_by_name(ldb, el->name); - - switch (flags) { - - case LDB_FLAG_MOD_REPLACE: - struct ldb_val *duplicate = NULL; - - ret = ldb_msg_find_duplicate_val(ldb, el, el, - &duplicate, 0); - if (ret != LDB_SUCCESS) { - return ret; - } - if (duplicate != NULL) { - ldb_asprintf_errstring( - ldb, - "attribute '%s': value '%.*s' " - "on '%s' provided more than " - "once in REPLACE", - el->name, - (int)duplicate->length, - duplicate->data, - ldb_dn_get_linearized(msg2->dn)); - return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; - } - - /* remove all attributes before adding the replacements */ - mod = lsqlite3_tprintf(ctx, - "DELETE FROM ldb_attribute_values " - "WHERE eid = '%lld' " - "AND norm_attr_name = '%q';", - eid, attr); - if (mod == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(ldb, errmsg); - free(errmsg); - } - return LDB_ERR_OPERATIONS_ERROR; - } - - /* MISSING break is INTENTIONAL */ - - case LDB_FLAG_MOD_ADD: - - if (el->num_values == 0) { - ldb_asprintf_errstring(ldb, "attribute %s on %s specified, but with 0 values (illigal)", - el->name, ldb_dn_get_linearized(msg->dn)); - return LDB_ERR_CONSTRAINT_VIOLATION; - } - - /* For each value of the specified attribute name... */ - for (j = 0; j < el->num_values; j++) { - struct ldb_val value; - - /* Get a canonicalised copy of the data */ - a->syntax->canonicalise_fn(ldb, ctx, &(el->values[j]), &value); - if (value.data == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - mod = lsqlite3_tprintf(ctx, - "INSERT OR ROLLBACK INTO ldb_attribute_values " - "('eid', 'attr_name', 'norm_attr_name'," - " 'attr_value', 'norm_attr_value') " - "VALUES ('%lld', '%q', '%q', '%q', '%q');", - eid, el->name, attr, - el->values[j].data, value.data); - - if (mod == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(ldb, errmsg); - free(errmsg); - } - return LDB_ERR_OPERATIONS_ERROR; - } - } - - break; - - case LDB_FLAG_MOD_DELETE: -#warning "We should throw an error if the attribute we are trying to delete does not exist!" - if (el->num_values == 0) { - mod = lsqlite3_tprintf(ctx, - "DELETE FROM ldb_attribute_values " - "WHERE eid = '%lld' " - "AND norm_attr_name = '%q';", - eid, attr); - if (mod == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(ldb, errmsg); - free(errmsg); - } - return LDB_ERR_OPERATIONS_ERROR; - } - } - - /* For each value of the specified attribute name... */ - for (j = 0; j < el->num_values; j++) { - struct ldb_val value; - - /* Get a canonicalised copy of the data */ - a->syntax->canonicalise_fn(ldb, ctx, &(el->values[j]), &value); - if (value.data == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - mod = lsqlite3_tprintf(ctx, - "DELETE FROM ldb_attribute_values " - "WHERE eid = '%lld' " - "AND norm_attr_name = '%q' " - "AND norm_attr_value = '%q';", - eid, attr, value.data); - - if (mod == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(ldb, errmsg); - free(errmsg); - } - return LDB_ERR_OPERATIONS_ERROR; - } - } - - break; - } - } - - return LDB_SUCCESS; -} - -/* delete a record */ -static int lsql_delete(struct lsql_context *ctx) -{ - struct ldb_module *module = ctx->module; - struct ldb_request *req = ctx->req; - struct lsqlite3_private *lsqlite3; - struct ldb_context *ldb; - long long eid; - char *errmsg; - char *query; - int ret; - - ldb = ldb_module_get_ctx(module); - lsqlite3 = talloc_get_type(ldb_module_get_private(module), - struct lsqlite3_private); - - eid = lsqlite3_get_eid(lsqlite3, req->op.del.dn); - if (eid == -1) { - return LDB_ERR_OPERATIONS_ERROR; - } - - query = lsqlite3_tprintf(ctx, - /* Delete entry */ - "DELETE FROM ldb_entry WHERE eid = %lld; " - /* Delete attributes */ - "DELETE FROM ldb_attribute_values WHERE eid = %lld; ", - eid, eid); - if (query == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(ldb, errmsg); - free(errmsg); - } - return LDB_ERR_OPERATIONS_ERROR; - } - - return LDB_SUCCESS; -} - -/* rename a record */ -static int lsql_rename(struct lsql_context *ctx) -{ - struct ldb_module *module = ctx->module; - struct ldb_request *req = ctx->req; - struct lsqlite3_private *lsqlite3; - struct ldb_context *ldb; - char *new_dn, *new_cdn, *old_cdn; - char *errmsg; - char *query; - int ret; - - ldb = ldb_module_get_ctx(module); - lsqlite3 = talloc_get_type(ldb_module_get_private(module), - struct lsqlite3_private); - - /* create linearized and normalized dns */ - old_cdn = ldb_dn_alloc_casefold(ctx, req->op.rename.olddn); - new_cdn = ldb_dn_alloc_casefold(ctx, req->op.rename.newdn); - new_dn = ldb_dn_alloc_linearized(ctx, req->op.rename.newdn); - if (old_cdn == NULL || new_cdn == NULL || new_dn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* build the SQL query */ - query = lsqlite3_tprintf(ctx, - "UPDATE ldb_entry SET dn = '%q', norm_dn = '%q' " - "WHERE norm_dn = '%q';", - new_dn, new_cdn, old_cdn); - if (query == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* execute */ - ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - ldb_set_errstring(ldb, errmsg); - free(errmsg); - } - return LDB_ERR_OPERATIONS_ERROR; - } - - return LDB_SUCCESS; -} - -static int lsql_start_trans(struct ldb_module * module) -{ - int ret; - char *errmsg; - struct lsqlite3_private *lsqlite3; - - lsqlite3 = talloc_get_type(ldb_module_get_private(module), - struct lsqlite3_private); - - if (lsqlite3->trans_count == 0) { - ret = sqlite3_exec(lsqlite3->sqlite, "BEGIN IMMEDIATE;", NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3_start_trans: error: %s\n", errmsg); - free(errmsg); - } - return -1; - } - }; - - lsqlite3->trans_count++; - - return 0; -} - -static int lsql_end_trans(struct ldb_module *module) -{ - int ret; - char *errmsg; - struct lsqlite3_private *lsqlite3; - - lsqlite3 = talloc_get_type(ldb_module_get_private(module), - struct lsqlite3_private); - - if (lsqlite3->trans_count > 0) { - lsqlite3->trans_count--; - } else return -1; - - if (lsqlite3->trans_count == 0) { - ret = sqlite3_exec(lsqlite3->sqlite, "COMMIT;", NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3_end_trans: error: %s\n", errmsg); - free(errmsg); - } - return -1; - } - } - - return 0; -} - -static int lsql_del_trans(struct ldb_module *module) -{ - struct lsqlite3_private *lsqlite3; - - lsqlite3 = talloc_get_type(ldb_module_get_private(module), - struct lsqlite3_private); - - if (lsqlite3->trans_count > 0) { - lsqlite3->trans_count--; - } else return -1; - - if (lsqlite3->trans_count == 0) { - return lsqlite3_safe_rollback(lsqlite3->sqlite); - } - - return -1; -} - -static int destructor(struct lsqlite3_private *lsqlite3) -{ - if (lsqlite3->sqlite) { - sqlite3_close(lsqlite3->sqlite); - } - return 0; -} - -static void lsql_request_done(struct lsql_context *ctx, int error) -{ - struct ldb_context *ldb; - struct ldb_request *req; - struct ldb_reply *ares; - - ldb = ldb_module_get_ctx(ctx->module); - req = ctx->req; - - /* if we already returned an error just return */ - if (ldb_request_get_status(req) != LDB_SUCCESS) { - return; - } - - ares = talloc_zero(req, struct ldb_reply); - if (!ares) { - ldb_oom(ldb); - req->callback(req, NULL); - return; - } - ares->type = LDB_REPLY_DONE; - ares->error = error; - - req->callback(req, ares); -} - -static void lsql_timeout(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval t, - void *private_data) -{ - struct lsql_context *ctx; - ctx = talloc_get_type(private_data, struct lsql_context); - - lsql_request_done(ctx, LDB_ERR_TIME_LIMIT_EXCEEDED); -} - -static void lsql_callback(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval t, - void *private_data) -{ - struct lsql_context *ctx; - int ret; - - ctx = talloc_get_type(private_data, struct lsql_context); - - switch (ctx->req->operation) { - case LDB_SEARCH: - ret = lsql_search(ctx); - break; - case LDB_ADD: - ret = lsql_add(ctx); - break; - case LDB_MODIFY: - ret = lsql_modify(ctx); - break; - case LDB_DELETE: - ret = lsql_delete(ctx); - break; - case LDB_RENAME: - ret = lsql_rename(ctx); - break; -/* TODO: - case LDB_EXTENDED: - ret = lsql_extended(ctx); - break; - */ - default: - /* no other op supported */ - ret = LDB_ERR_PROTOCOL_ERROR; - } - - if (!ctx->callback_failed) { - /* Once we are done, we do not need timeout events */ - talloc_free(ctx->timeout_event); - lsql_request_done(ctx, ret); - } -} - -static int lsql_handle_request(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - struct tevent_context *ev; - struct lsql_context *ac; - struct tevent_timer *te; - struct timeval tv; - - if (ldb_check_critical_controls(req->controls)) { - return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION; - } - - if (req->starttime == 0 || req->timeout == 0) { - ldb_set_errstring(ldb, "Invalid timeout settings"); - return LDB_ERR_TIME_LIMIT_EXCEEDED; - } - - ldb = ldb_module_get_ctx(module); - ev = ldb_get_event_context(ldb); - - ac = talloc_zero(req, struct lsql_context); - if (ac == NULL) { - ldb_set_errstring(ldb, "Out of Memory"); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - - tv.tv_sec = 0; - tv.tv_usec = 0; - te = tevent_add_timer(ev, ac, tv, lsql_callback, ac); - if (NULL == te) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (req->timeout > 0) { - tv.tv_sec = req->starttime + req->timeout; - tv.tv_usec = 0; - ac->timeout_event = tevent_add_timer(ev, ac, tv, lsql_timeout, ac); - if (NULL == ac->timeout_event) { - return LDB_ERR_OPERATIONS_ERROR; - } - } - - return LDB_SUCCESS; -} - -/* - * Table of operations for the sqlite3 backend - */ -static const struct ldb_module_ops lsqlite3_ops = { - .name = "sqlite", - .search = lsql_handle_request, - .add = lsql_handle_request, - .modify = lsql_handle_request, - .del = lsql_handle_request, - .rename = lsql_handle_request, - .extended = lsql_handle_request, - .start_transaction = lsql_start_trans, - .end_transaction = lsql_end_trans, - .del_transaction = lsql_del_trans, -}; - -/* - * Static functions - */ - -static int initialize(struct lsqlite3_private *lsqlite3, - struct ldb_context *ldb, const char *url, - unsigned int flags) -{ - TALLOC_CTX *local_ctx; - long long queryInt; - int rollback = 0; - char *errmsg; - char *schema; - int ret; - - /* create a local ctx */ - local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_rename local context"); - if (local_ctx == NULL) { - return -1; - } - - schema = lsqlite3_tprintf(local_ctx, - - - "CREATE TABLE ldb_info AS " - " SELECT 'LDB' AS database_type," - " '1.0' AS version;" - - /* - * The entry table holds the information about an entry. - * This table is used to obtain the EID of the entry and to - * support scope=one and scope=base. The parent and child - * table is included in the entry table since all the other - * attributes are dependent on EID. - */ - "CREATE TABLE ldb_entry " - "(" - " eid INTEGER PRIMARY KEY AUTOINCREMENT," - " dn TEXT UNIQUE NOT NULL," - " norm_dn TEXT UNIQUE NOT NULL" - ");" - - - "CREATE TABLE ldb_object_classes" - "(" - " class_name TEXT PRIMARY KEY," - " parent_class_name TEXT," - " tree_key TEXT UNIQUE," - " max_child_num INTEGER DEFAULT 0" - ");" - - /* - * We keep a full listing of attribute/value pairs here - */ - "CREATE TABLE ldb_attribute_values" - "(" - " eid INTEGER REFERENCES ldb_entry," - " attr_name TEXT," - " norm_attr_name TEXT," - " attr_value TEXT," - " norm_attr_value TEXT " - ");" - - - /* - * Indexes - */ - "CREATE INDEX ldb_attribute_values_eid_idx " - " ON ldb_attribute_values (eid);" - - "CREATE INDEX ldb_attribute_values_name_value_idx " - " ON ldb_attribute_values (attr_name, norm_attr_value);" - - - - /* - * Triggers - */ - - "CREATE TRIGGER ldb_object_classes_insert_tr" - " AFTER INSERT" - " ON ldb_object_classes" - " FOR EACH ROW" - " BEGIN" - " UPDATE ldb_object_classes" - " SET tree_key = COALESCE(tree_key, " - " (" - " SELECT tree_key || " - " (SELECT base160(max_child_num + 1)" - " FROM ldb_object_classes" - " WHERE class_name = " - " new.parent_class_name)" - " FROM ldb_object_classes " - " WHERE class_name = new.parent_class_name " - " ));" - " UPDATE ldb_object_classes " - " SET max_child_num = max_child_num + 1" - " WHERE class_name = new.parent_class_name;" - " END;" - - /* - * Table initialization - */ - - "INSERT INTO ldb_object_classes " - " (class_name, tree_key) " - " VALUES " - " ('TOP', '0001');"); - - /* Skip protocol indicator of url */ - if (strncmp(url, "sqlite3://", 10) != 0) { - return SQLITE_MISUSE; - } - - /* Update pointer to just after the protocol indicator */ - url += 10; - - /* Try to open the (possibly empty/non-existent) database */ - if ((ret = sqlite3_open(url, &lsqlite3->sqlite)) != SQLITE_OK) { - return ret; - } - - /* In case this is a new database, enable auto_vacuum */ - ret = sqlite3_exec(lsqlite3->sqlite, "PRAGMA auto_vacuum = 1;", NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3 initializaion error: %s\n", errmsg); - free(errmsg); - } - goto failed; - } - - if (flags & LDB_FLG_NOSYNC) { - /* DANGEROUS */ - ret = sqlite3_exec(lsqlite3->sqlite, "PRAGMA synchronous = OFF;", NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3 initializaion error: %s\n", errmsg); - free(errmsg); - } - goto failed; - } - } - - /* */ - - /* Establish a busy timeout of 30 seconds */ - if ((ret = sqlite3_busy_timeout(lsqlite3->sqlite, - 30000)) != SQLITE_OK) { - return ret; - } - - /* Create a function, callable from sql, to increment a tree_key */ - if ((ret = - sqlite3_create_function(lsqlite3->sqlite,/* handle */ - "base160_next", /* function name */ - 1, /* number of args */ - SQLITE_ANY, /* preferred text type */ - NULL, /* user data */ - base160next_sql, /* called func */ - NULL, /* step func */ - NULL /* final func */ - )) != SQLITE_OK) { - return ret; - } - - /* Create a function, callable from sql, to convert int to base160 */ - if ((ret = - sqlite3_create_function(lsqlite3->sqlite,/* handle */ - "base160", /* function name */ - 1, /* number of args */ - SQLITE_ANY, /* preferred text type */ - NULL, /* user data */ - base160_sql, /* called func */ - NULL, /* step func */ - NULL /* final func */ - )) != SQLITE_OK) { - return ret; - } - - /* Create a function, callable from sql, to perform various comparisons */ - if ((ret = - sqlite3_create_function(lsqlite3->sqlite, /* handle */ - "ldap_compare", /* function name */ - 4, /* number of args */ - SQLITE_ANY, /* preferred text type */ - ldb , /* user data */ - lsqlite3_compare, /* called func */ - NULL, /* step func */ - NULL /* final func */ - )) != SQLITE_OK) { - return ret; - } - - /* Begin a transaction */ - ret = sqlite3_exec(lsqlite3->sqlite, "BEGIN EXCLUSIVE;", NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3: initialization error: %s\n", errmsg); - free(errmsg); - } - goto failed; - } - rollback = 1; - - /* Determine if this is a new database. No tables means it is. */ - if (query_int(lsqlite3, - &queryInt, - "SELECT COUNT(*)\n" - " FROM sqlite_master\n" - " WHERE type = 'table';") != 0) { - goto failed; - } - - if (queryInt == 0) { - /* - * Create the database schema - */ - ret = sqlite3_exec(lsqlite3->sqlite, schema, NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3 initializaion error: %s\n", errmsg); - free(errmsg); - } - goto failed; - } - } else { - /* - * Ensure that the database we opened is one of ours - */ - if (query_int(lsqlite3, - &queryInt, - "SELECT " - " (SELECT COUNT(*) = 2" - " FROM sqlite_master " - " WHERE type = 'table' " - " AND name IN " - " (" - " 'ldb_entry', " - " 'ldb_object_classes' " - " ) " - " ) " - " AND " - " (SELECT 1 " - " FROM ldb_info " - " WHERE database_type = 'LDB' " - " AND version = '1.0'" - " );") != 0 || - queryInt != 1) { - - /* It's not one that we created. See ya! */ - goto failed; - } - } - - /* Commit the transaction */ - ret = sqlite3_exec(lsqlite3->sqlite, "COMMIT;", NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - if (errmsg) { - printf("lsqlite3: iniialization error: %s\n", errmsg); - free(errmsg); - } - goto failed; - } - - return SQLITE_OK; - -failed: - if (rollback) lsqlite3_safe_rollback(lsqlite3->sqlite); - sqlite3_close(lsqlite3->sqlite); - return -1; -} - -/* - * connect to the database - */ -static int lsqlite3_connect(struct ldb_context *ldb, - const char *url, - unsigned int flags, - const char *options[], - struct ldb_module **_module) -{ - struct ldb_module *module; - struct lsqlite3_private *lsqlite3; - unsigned int i; - int ret; - - module = ldb_module_new(ldb, ldb, "ldb_sqlite3 backend", &lsqlite3_ops); - if (!module) return LDB_ERR_OPERATIONS_ERROR; - - lsqlite3 = talloc(module, struct lsqlite3_private); - if (!lsqlite3) { - goto failed; - } - - lsqlite3->sqlite = NULL; - lsqlite3->options = NULL; - lsqlite3->trans_count = 0; - - ret = initialize(lsqlite3, ldb, url, flags); - if (ret != SQLITE_OK) { - goto failed; - } - - talloc_set_destructor(lsqlite3, destructor); - - ldb_module_set_private(module, lsqlite3); - - if (options) { - /* - * take a copy of the options array, so we don't have to rely - * on the caller keeping it around (it might be dynamic) - */ - for (i=0;options[i];i++) ; - - lsqlite3->options = talloc_array(lsqlite3, char *, i+1); - if (!lsqlite3->options) { - goto failed; - } - - for (i=0;options[i];i++) { - - lsqlite3->options[i+1] = NULL; - lsqlite3->options[i] = - talloc_strdup(lsqlite3->options, options[i]); - if (!lsqlite3->options[i]) { - goto failed; - } - } - } - - *_module = module; - return LDB_SUCCESS; - -failed: - if (lsqlite3 && lsqlite3->sqlite != NULL) { - (void) sqlite3_close(lsqlite3->sqlite); - } - talloc_free(lsqlite3); - return LDB_ERR_OPERATIONS_ERROR; -} - -int ldb_sqlite3_init(const char *version) -{ - LDB_MODULE_CHECK_VERSION(version); - return ldb_register_backend("sqlite3", lsqlite3_connect, false); -} diff --git a/ldb-2.0.8/ldb_sqlite3/schema b/ldb-2.0.8/ldb_sqlite3/schema deleted file mode 100644 index ab7c5cc..0000000 --- a/ldb-2.0.8/ldb_sqlite3/schema +++ /dev/null @@ -1,328 +0,0 @@ - -- ------------------------------------------------------ - - PRAGMA auto_vacuum=1; - - -- ------------------------------------------------------ - - BEGIN EXCLUSIVE; - - -- ------------------------------------------------------ - - CREATE TABLE ldb_info AS - SELECT 'LDB' AS database_type, - '1.0' AS version; - - /* - * Get the next USN value with: - * BEGIN EXCLUSIVE; - * UPDATE usn SET value = value + 1; - * SELECT value FROM usn; - * COMMIT; - */ - CREATE TABLE usn - ( - value INTEGER - ); - - CREATE TABLE ldb_object - ( - /* tree_key is auto-generated by the insert trigger */ - tree_key TEXT PRIMARY KEY, - - parent_tree_key TEXT, - dn TEXT, - - attr_name TEXT REFERENCES ldb_attributes, - attr_value TEXT, - - /* - * object_type can take on these values (to date): - * 1: object is a node of a DN - * 2: object is an attribute/value pair of its parent DN - */ - object_type INTEGER, - - /* - * if object_type is 1, the node can have children. - * this tracks the maximum previously assigned child - * number so we can generate a new unique tree key for - * a new child object. note that this is always incremented, - * so if children are deleted, this will not represent - * the _number_ of children. - */ - max_child_num INTEGER, - - /* - * Automatically maintained meta-data (a gift for metze) - */ - object_guid TEXT UNIQUE, - timestamp INTEGER, -- originating_time - invoke_id TEXT, -- GUID: originating_invocation_id - usn INTEGER, -- hyper: originating_usn - - /* do not allow duplicate name/value pairs */ - UNIQUE (parent_tree_key, attr_name, attr_value, object_type) - ); - - CREATE TABLE ldb_attributes - ( - attr_name TEXT PRIMARY KEY, - parent_tree_key TEXT, - - objectclass_p BOOLEAN DEFAULT 0, - - case_insensitive_p BOOLEAN DEFAULT 0, - wildcard_p BOOLEAN DEFAULT 0, - hidden_p BOOLEAN DEFAULT 0, - integer_p BOOLEAN DEFAULT 0, - - /* tree_key is auto-generated by the insert trigger */ - tree_key TEXT, -- null if not a object/sub class - -- level 1 if an objectclass - -- level 1-n if a subclass - max_child_num INTEGER - ); - - -- ------------------------------------------------------ - - CREATE INDEX ldb_object_dn_idx - ON ldb_object (dn); - - CREATE INDEX ldb_attributes_tree_key_ids - ON ldb_attributes (tree_key); - - -- ------------------------------------------------------ - - /* Gifts for metze. Automatically updated meta-data */ - CREATE TRIGGER ldb_object_insert_tr - AFTER INSERT - ON ldb_object - FOR EACH ROW - BEGIN - UPDATE ldb_object - SET max_child_num = max_child_num + 1 - WHERE tree_key = new.parent_tree_key; - UPDATE usn SET value = value + 1; - UPDATE ldb_object - SET tree_key = - (SELECT - new.tree_key || - base160(SELECT max_child_num - FROM ldb_object - WHERE tree_key = - new.parent_tree_key)); - max_child_num = 0, - object_guid = random_guid(), - timestamp = strftime('%s', 'now'), - usn = (SELECT value FROM usn); - WHERE tree_key = new.tree_key; - END; - - CREATE TRIGGER ldb_object_update_tr - AFTER UPDATE - ON ldb_object - FOR EACH ROW - BEGIN - UPDATE usn SET value = value + 1; - UPDATE ldb_object - SET timestamp = strftime('%s', 'now'), - usn = (SELECT value FROM usn); - WHERE tree_key = new.tree_key; - END; - - CREATE TRIGGER ldb_attributes_insert_tr - AFTER INSERT - ON ldb_attributes - FOR EACH ROW - BEGIN - UPDATE ldb_attributes - SET max_child_num = max_child_num + 1 - WHERE tree_key = new.parent_tree_key; - UPDATE ldb_attributes - SET tree_key = - (SELECT - new.tree_key || - base160(SELECT max_child_num - FROM ldb_attributes - WHERE tree_key = - new.parent_tree_key)); - max_child_num = 0 - WHERE tree_key = new.tree_key; - END; - - - -- ------------------------------------------------------ - - /* Initialize usn */ - INSERT INTO usn (value) VALUES (0); - - /* Create root object */ - INSERT INTO ldb_object - (tree_key, parent_tree_key, - dn, - object_type, max_child_num) - VALUES ('', NULL, - '', - 1, 0); - - /* We need an implicit "top" level object class */ - INSERT INTO ldb_attributes (attr_name, - parent_tree_key) - SELECT 'top', ''; - - -- ------------------------------------------------------ - - COMMIT; - - -- ------------------------------------------------------ - -/* - * dn: o=University of Michigan,c=US - * objectclass: organization - * objectclass: domainRelatedObject - */ --- newDN -BEGIN; - -INSERT OR IGNORE INTO ldb_object - (parent_tree_key - dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('', - 'c=US', - 'c', 'US', 1, 0); - -INSERT INTO ldb_object - (parent_tree_key, - dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('0001', - 'o=University of Michigan,c=US', - 'o', 'University of Michigan', 1, 0); - --- newObjectClass -INSERT OR IGNORE INTO ldb_attributes - (attr_name, parent_tree_key, objectclass_p) - VALUES - ('objectclass', '', 1); - -INSERT INTO ldb_object - (parent_tree_key, - dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', - NULL, - 'objectclass', 'organization', 2, 0); - -INSERT OR IGNORE INTO ldb_attributes - (attr_name, parent_tree_key, objectclass_p) - VALUES - ('objectclass', '', 1); - -INSERT INTO ldb_object - (parent_tree_key, - dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', - NULL, - 'objectclass', 'domainRelatedObject', 2, 0); - -COMMIT; - - -/* - * dn: o=University of Michigan,c=US - * l: Ann Arbor, Michigan - * st: Michigan - * o: University of Michigan - * o: UMICH - * seeAlso: - * telephonenumber: +1 313 764-1817 - */ --- addAttrValuePair -BEGIN; - -INSERT INTO ldb_object - (parent_tree_key, dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', NULL, - 'l', 'Ann Arbor, Michigan', 2, 0); - -INSERT INTO ldb_object - (parent_tree_key, dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', NULL, - 'st', 'Michigan', 2, 0); - -INSERT INTO ldb_object - (parent_tree_key, dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', NULL, - 'o', 'University of Michigan', 2, 0); - -INSERT INTO ldb_object - (parent_tree_key, dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', NULL, - 'o', 'UMICH', 2, 0); - -INSERT INTO ldb_object - (parent_tree_key, dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', NULL, - 'seeAlso', '', 2, 0); - -INSERT INTO ldb_object - (parent_tree_key, dn, - attr_name, attr_value, object_type, max_child_num) - VALUES ('00010001', NULL, - 'telephonenumber', '+1 313 764-1817', 2, 0); - -COMMIT; - --- ---------------------------------------------------------------------- - -/* - * dn: @ATTRIBUTES - * uid: CASE_INSENSITIVE WILDCARD - * cn: CASE_INSENSITIVE - * ou: CASE_INSENSITIVE - * dn: CASE_INSENSITIVE - */ --- newAttribute - -BEGIN; - -INSERT OR IGNORE INTO ldb_attributes - (attr_name, parent_tree_key, objectclass_p) - VALUES - ('uid', '', 0); - -UPDATE ldb_attributes - SET case_insensitive_p = 1, - wildcard_p = 1, - hidden_p = 0, - integer_p = 0 - WHERE attr_name = 'uid' - -UPDATE ldb_attributes - SET case_insensitive_p = 1, - wildcard_p = 0, - hidden_p = 0, - integer_p = 0 - WHERE attr_name = 'cn' - -UPDATE ldb_attributes - SET case_insensitive_p = 1, - wildcard_p = 0, - hidden_p = 0, - integer_p = 0 - WHERE attr_name = 'ou' - -UPDATE ldb_attributes - SET case_insensitive_p = 1, - wildcard_p = 0, - hidden_p = 0, - integer_p = 0 - WHERE attr_name = 'dn' - diff --git a/ldb-2.0.8/ldb_sqlite3/trees.ps b/ldb-2.0.8/ldb_sqlite3/trees.ps deleted file mode 100644 index 433a064..0000000 --- a/ldb-2.0.8/ldb_sqlite3/trees.ps +++ /dev/null @@ -1,1760 +0,0 @@ -%!PS-Adobe-2.0 -%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software -%%Title: trees.dvi -%%Pages: 7 -%%PageOrder: Ascend -%%BoundingBox: 0 0 596 842 -%%EndComments -%DVIPSWebPage: (www.radicaleye.com) -%DVIPSCommandLine: dvips -f trees.dvi -%DVIPSParameters: dpi=600, compressed -%DVIPSSource: TeX output 2000.05.06:2055 -%%BeginProcSet: texc.pro -%! -/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S -N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 -mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 -0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ -landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize -mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ -matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round -exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ -statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] -N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin -/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array -/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 -array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N -df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A -definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get -}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} -B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr -1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 -1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx -0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx -sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ -rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp -gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B -/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ -/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ -A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy -get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} -ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp -fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 -{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add -chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ -1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} -forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn -/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put -}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ -bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A -mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ -SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ -userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X -1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 -index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N -/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ -/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) -(LaserWriter 16/600)]{A length product length le{A length product exch 0 -exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse -end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask -grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} -imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round -exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto -fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p -delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} -B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ -p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S -rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end - -%%EndProcSet -TeXDict begin 39158280 55380996 1000 600 600 (trees.dvi) -@start -%DVIPSBitmapFont: Fa cmr10 10 6 -/Fa 6 55 df<146014E0EB01C0EB0380EB0700130E131E5B5BA25B485AA2485AA212075B -120F90C7FCA25A121EA2123EA35AA65AB2127CA67EA3121EA2121F7EA27F12077F1203A2 -6C7EA26C7E1378A27F7F130E7FEB0380EB01C0EB00E01460135278BD20>40 -D<12C07E12707E7E7E120F6C7E6C7EA26C7E6C7EA21378A2137C133C133E131EA2131F7F -A21480A3EB07C0A6EB03E0B2EB07C0A6EB0F80A31400A25B131EA2133E133C137C1378A2 -5BA2485A485AA2485A48C7FC120E5A5A5A5A5A13527CBD20>I<15301578B3A6007FB812 -F8B912FCA26C17F8C80078C8FCB3A6153036367BAF41>43 D48 DI54 D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fb cmr7 7 3 -/Fb 3 55 df48 D<13381378EA01F8121F12FE12E01200B3AB487EB512F8A2 -15267BA521>I54 D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fc cmmi10 10 1 -/Fc 1 69 df<0103B7FC4916E018F8903B0007F80007FE4BEB00FFF03F80020FED1FC018 -0F4B15E0F007F0021F1503A24B15F81801143F19FC5DA2147FA292C8FCA25C18035CA213 -0119F84A1507A2130319F04A150FA2010717E0181F4A16C0A2010FEE3F80A24AED7F0018 -7E011F16FE4D5A4A5D4D5A013F4B5A4D5A4A4A5A057FC7FC017F15FEEE03FC91C7EA0FF0 -49EC7FC0B8C8FC16FC16C03E397DB845>68 D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fd ectt1000 10 73 -/Fd 73 126 df37 -D39 -D<143814FC13011303EB07F8EB0FF0EB1FC0EB3F80EB7F0013FE485A485A5B12075B120F -5B485AA2123F90C7FCA25A127EA312FE5AAC7E127EA3127F7EA27F121FA26C7E7F12077F -12037F6C7E6C7E137FEB3F80EB1FC0EB0FF0EB07F8EB03FC130113001438164272B92C> -I<127012FC7E7E6C7E6C7EEA0FE06C7E6C7E6C7E6C7E137F7F1480131F14C0130FEB07E0 -A214F01303A214F81301A314FC1300AC130114F8A3130314F0A2130714E0A2EB0FC0131F -1480133F14005B13FE485A485A485A485AEA3FC0485A48C7FC5A5A1270164279B92C>I< -EB0380497EA60020140800F8143E00FE14FE00FF13C1EBC7C7EBE7CF003FB512F8000F14 -E0000314806C140038007FFCA248B5FC481480000F14E0003F14F839FFE7CFFEEBC7C7EB -07C100FE13C000F8143E0020140800001400A66D5A1F247AAA2C>I<147014F8AF003FB6 -12E0B712F8A4C700F8C7FCB0147025267DAB2C>II<121FEA3F80EA7FC0EAFFE0A5EA7FC0EA3F80EA1F000B0B708A2C>46 -D<1507ED0F80A2151F16005D153E157E157CA215FC5D14015D14035D14075D140F5D141F -92C7FC5C143EA2147E147C14FC5C13015C13035C13075C130F5C131F91C8FC5B133EA213 -7E137C13FC5B12015B12035B12075B120F5B121F90C9FCA25A123E127E127C12FC5AA212 -7021417BB92C>II<1307497EA2131F -A2133F137F13FF5A1207127FB5FC13DF139FEA7C1F1200B3AE007FB512E0B612F0A36C14 -E01C3477B32C>II<000FB512FE4880A35D0180C8FCADEB83FE90389FFF8090B512E015F881 -9038FE03FE9038F000FF01C07F49EB3F8090C7121F6C15C0C8120FA2ED07E0A4123C127E -B4FC150F16C0A248141F007EEC3F80007FEC7F006C6C5B6D485A391FF80FFC6CB55A6C5C -000114C06C6C90C7FCEB0FF823347CB22C>53 DI<1278B712C016E0A316C000FCC7EA3F80ED7F0015FE00785CC712014A -5A4A5A5D140F5D4A5A143F92C7FC5C147E14FE5C13015CA2495AA213075CA3495AA4495A -A5133F91C8FCAA131E23357CB32C>I59 D<1502ED0F80151F157F15 -FF913803FE00EC0FFCEC1FF0EC7FE0ECFF80D903FEC7FC495AEB1FF0495AEBFF80000390 -C8FCEA07FCEA1FF8EA3FE0EAFF8090C9FCA27FEA3FE0EA1FF8EA07FC6CB4FCC67FEB3FE0 -6D7EEB07FC6D7E903800FF80EC7FE0EC1FF0EC0FFCEC03FE913800FF80157F151F150FED -0200212A7BAD2C>I<007FB612F0B712F8A36C15F0CAFCA8007FB612F0B712F8A36C15F0 -25127DA12C>I<122012F87EB4FC7FEA3FE0EA1FF8EA07FC6CB4FCC67FEB3FE06D7EEB07 -FC6D7E903800FF80EC7FE0EC1FF0EC0FFCEC03FE913800FF80157FA215FF913803FE00EC -0FFCEC1FF0EC7FE0ECFF80D903FEC7FC495AEB1FF0495AEBFF80000390C8FCEA07FCEA1F -F8EA3FE0EAFF8090C9FC12FC5A1220212A7BAD2C>I<14FE497EA4497FA214EFA2130781 -A214C7A2010F7FA314C390381F83F0A590383F01F8A490387E00FCA549137E90B512FEA3 -4880A29038F8003FA34848EB1F80A4000715C049130FD87FFEEBFFFC6D5AB514FE6C15FC -497E27347EB32C>65 D<007FB512E015F8B612FE6C8016C03903F0003FED0FE0ED07F015 -03A2ED01F8A6ED03F0A21507ED0FE0ED1FC0EDFF8090B612005D5D15FF16C09039F0001F -E0ED07F0ED03F81501ED00FCA216FE167EA616FE16FC1501ED03F8150FED3FF0007FB612 -E016C0B712806CECFE0015F027337FB22C>I<02FF13700107EBE0F84913F9013F13FD49 -13FFEBFF813901FE007F4848131FD807F0130F1507485A491303485A150148C7FCA25A00 -7EEC00F01600A212FE5AAB7E127EA3007F15F06CEC01F8A26C7EA26C6C13036D14F06C6C -130716E0D803FC131F6C6CEB3FC03A00FF81FF806DB512006D5B010F5B6D13F001001380 -25357DB32C>I<007FB5FCB612C015F0816C803907E003FEEC00FFED7F80153FED1FC0ED -0FE0A2150716F0150316F81501A4ED00FCACED01F8A3150316F0A2150716E0150FED1FC0 -153FED7F80EDFF00EC03FE007FB55AB65A5D15C06C91C7FC26337EB22C>I<007FB612F0 -B712F8A37E3903F00001A7ED00F01600A4EC01E04A7EA490B5FCA5EBF003A46E5A91C8FC -A5163C167EA8007FB612FEB7FCA36C15FC27337EB22C>I<007FB612F8B712FCA37ED803 -F0C7FCA716781600A515F04A7EA490B5FCA5EBF001A46E5A92C7FCAD387FFFE0B5FC805C -7E26337EB22C>I<903901FC038090390FFF87C04913EF017F13FF90B6FC4813073803FC -01497E4848137F4848133F49131F121F5B003F140F90C7FCA2127EED078092C7FCA212FE -5AA8913803FFF84A13FCA27E007E6D13F89138000FC0A36C141FA27F121F6D133F120F6D -137F6C7E6C6C13FF6D5A3801FF076C90B5FC6D13EF011F13CF6DEB0780D901FCC7FC2635 -7DB32C>II<007FB512F8B612FCA36C14 -F839000FC000B3B3A5007FB512F8B612FCA36C14F81E3379B22C>I75 D<387FFFE0B57EA36C5BD803F0C8FCB3AE16F0 -ED01F8A8007FB6FCB7FCA36C15F025337DB22C>IIII<007FB512C0B612 -F88115FF6C15802603F00013C0153FED0FE0ED07F0A2150316F81501A6150316F01507A2 -ED0FE0ED3FC015FF90B61280160015FC5D15C001F0C8FCB0387FFF80B57EA36C5B25337E -B22C>II<387FFFFCB67E15E015F86C803907E007FE1401EC007F6F7E151FA2 -6F7EA64B5AA2153F4BC7FCEC01FE140790B55A5D15E081819038E007FCEC01FE1400157F -81A8160FEE1F80A5D87FFEEB1FBFB5ECFF00815E6C486D5AC8EA01F029347EB22C>I<90 -381FF80790B5EA0F804814CF000714FF5A381FF01F383FC003497E48C7FC007E147F00FE -143F5A151FA46CEC0F00007E91C7FC127F7FEA3FE0EA1FFCEBFFC06C13FC0003EBFFC06C -14F06C6C7F01077F9038007FFEEC07FF02001380153FED1FC0A2ED0FE0A20078140712FC -A56CEC0FC0A26CEC1F806D133F01E0EB7F009038FE01FF90B55A5D00F914F0D8F83F13C0 -D8700790C7FC23357CB32C>I<007FB612FCB712FEA43AFC007E007EA70078153CC71400 -B3AF90383FFFFCA2497F6D5BA227337EB22C>I<3B7FFF803FFFC0B56C4813E0A36C496C -13C03B03F00001F800B3AF6D130300015DA26D130700005D6D130F017F495A6D6C485AEC -E0FF6DB5C7FC6D5B010313F86D5B9038003F802B3480B22C>III<3A3FFF03FFE0484913F0148714076C6D13E03A01 -F800FE007F0000495A13FE017E5BEB7F03013F5B1487011F5B14CF010F5B14FF6D5BA26D -90C7FCA26D5AA26D5AA2497EA2497EA2497F81EB0FCF81EB1FC7EC87F0EB3F83EC03F8EB -7F01017E7FEBFE00497F0001147E49137F000380491480151FD87FFEEBFFFC6D5AB514FE -6C15FC497E27337EB22C>II<387FFFFCB512FEA314FC00FCC7FCB3B3B3B512FC14FEA36C13FC -17416FB92C>91 D<127012F8A27E127C127E123E123F7EA27F120F7F12077F12037F1201 -7F12007F137C137E133EA2133F7F80130F80130780130380130180130080147C147E143E -A2143F8081140F81140781140381140181140081157CA2157E153E153F811680150FA2ED -070021417BB92C>I<387FFFFCB512FEA37EC7127EB3B3B3387FFFFEB5FCA36C13FC1741 -7DB92C>II<007FB6FCB71280A46C150021067B7D -2C>I<1338137CEA01FC1203EA07F813F0EA0FC0EA1F80A2EA3F00123E127E127CA212FC -5AA3EAFFC013E013F013F8A2127FA2123F13F0EA1FE0EA07C00E1D72B82C>I<3801FFF0 -000713FE001F6D7E15E048809038C01FF81407EC01FC381F80000006C77EC8127EA3ECFF -FE131F90B5FC1203120F48EB807E383FF800EA7FC090C7FC12FE5AA47E007F14FEEB8003 -383FE01F6CB612FC6C15FE6C14BF0001EBFE1F3A003FF007FC27247CA32C>II<90 -3803FFE0011F13F8017F13FE48B5FC48804848C6FCEA0FF0485A49137E4848131890C9FC -5A127EA25AA8127EA2127F6C140F6DEB1F806C7E6D133F6C6CEB7F003907FE03FF6CB55A -6C5C6C6C5B011F13E0010390C7FC21247AA32C>III103 -DI< -1307EB1FC0A2497EA36D5AA20107C7FC90C8FCA7387FFFC080B5FC7EA2EA0007B3A8007F -B512FCB612FEA36C14FC1F3479B32C>I107 D<387FFFE0B57EA37EEA0003B3B3A5007F -B61280B712C0A36C158022337BB22C>I<3A7F83F007E09039CFFC1FF83AFFDFFE3FFCD8 -7FFF13FF91B57E3A07FE1FFC3E01FCEBF83F496C487E01F013E001E013C0A301C01380B3 -3B7FFC3FF87FF0027F13FFD8FFFE6D13F8D87FFC4913F0023F137F2D2481A32C>I<397F -F01FE039FFF87FFC9038F9FFFE01FB7F6CB6FC00019038F03F80ECC01F02807FEC000F5B -5BA25BB3267FFFE0B5FCB500F11480A36C01E0140029247FA32C>II<397FF01FE0 -39FFF8FFF801FB13FE90B6FC6C158000019038F07FC09138801FE091380007F049EB03F8 -5BED01FC491300A216FE167EA816FE6D14FCA2ED01F86D13036DEB07F0150F9138801FE0 -9138E07FC091B51280160001FB5B01F813F8EC3FC091C8FCAD387FFFE0B57EA36C5B2736 -7FA32C>I<903903FC078090391FFF0FC0017F13CF48B512EF4814FF3807FE07380FF001 -48487E49137F4848133F90C7FC48141F127E150F5AA87E007E141FA26C143F7F6C6C137F -6D13FF380FF0033807FC0F6CB6FC6C14EF6C6C138F6D130FEB07F890C7FCAD0203B5FC4A -1480A36E140029367DA32C>II<90387FF8700003B512F8120F5A5A387FC00F387E00034813015AA36CEB -00F0007F140013F0383FFFC06C13FE6CEBFF80000314E0C66C13F8010113FCEB0007EC00 -FE0078147F00FC143F151F7EA26C143F6D133E6D13FE9038F007FC90B5FC15F815E000F8 -148039701FFC0020247AA32C>I<131E133FA9007FB6FCB71280A36C1500D8003FC8FCB1 -ED03C0ED07E0A5EC800F011FEB1FC0ECE07F6DB51280160001035B6D13F89038003FE023 -2E7EAD2C>I<3A7FF003FF80486C487FA3007F7F0001EB000FB3A3151FA2153F6D137F39 -00FE03FF90B7FC6D15807F6D13CF902603FE07130029247FA32C>I<3A3FFF03FFF04801 -8713F8A36C010313F03A00FC007E005D90387E01F8013F5BEB1F83EC87E090380FCFC090 -3807EF80EB03FF6D90C7FC5C6D5A147C14FE130180903803EF80903807CFC0EB0FC7EC83 -E090381F01F0013F7FEB7E00017C137C49137E0001803A7FFF01FFFC1483B514FE6C15FC -140127247EA32C>120 D<3A7FFF01FFFCB5008113FE148314816C010113FC3A03E0000F -806C7E151F6D140012005D6D133E137C017E137E013E137CA2013F13FC6D5BA2EB0F815D -A2EB07C1ECC3E0A2EB03E3ECE7C0130114F75DEB00FFA292C7FC80A2143EA2147E147CA2 -14FC5CA2EA0C01003F5BEA7F83EB87E0EA7E0F495A387FFF806C90C8FC6C5A6C5AEA07E0 -27367EA32C>I<15FF02071380141F147F91B512004913C04AC7FCEB03F85CB31307EB1F -E013FF007F5BB55A49C8FC6D7E6C7FC67F131FEB07F01303B380EB01FEECFFC06D13FF6E -1380141F14070200130021417BB92C>123 D<127812FCB3B3B3A9127806416DB92C>II E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fe ecti1000 10 33 -/Fe 33 122 df28 D<150C151C153815F0EC01E0EC03C0EC0780EC0F00141E5C147C5C5C495A1303 -495A5C130F49C7FCA2133EA25BA25BA2485AA212035B12075BA2120F5BA2121FA290C8FC -A25AA2123EA2127EA2127CA412FC5AAD1278A57EA3121C121EA2120E7EA26C7E6C7EA212 -001E5274BD22>40 D<140C140E80EC0380A2EC01C015E0A2140015F0A21578A4157C153C -AB157CA715FCA215F8A21401A215F0A21403A215E0A21407A215C0140F1580A2141F1500 -A2143EA25CA25CA2495AA2495A5C1307495A91C7FC5B133E133C5B5B485A12035B48C8FC -120E5A12785A12C01E527FBD22>I<4B7EA3150393C8FCA35D1506A3150E150CA3151C15 -18A315381530A31570B912E0A2C80060C8FC15E05DA314015DA3140392C9FCA35C1406A3 -140E140CA3141C1418A2333275AD40>43 DI<120E -EA3F80127F12FFA31300127E123C0909778819>46 D<0103B612FEEFFFC018F0903B0007 -F8000FF84BEB03FCEF00FE020F157FF03F804B141F19C0021F150F19E05D1807143F19F0 -5DA2147FA292C8FCA25C180F5CA2130119E04A151FA2130319C04A153FA201071780187F -4A1600A2010F16FEA24A4A5A60011F15034D5A4A5D4D5A013F4B5A173F4A4AC7FC17FC01 -7FEC03F84C5A91C7EA1FC04949B45A007F90B548C8FCB712F016803C397CB83F>68 -D<0103B512F8A390390007F8005DA2140FA25DA2141FA25DA2143FA25DA2147FA292C7FC -A25CA25CA21301A25CA21303A25CA21307A25CA2130FA25CA2131FA25CA2133FA25CA213 -7FA291C8FC497EB6FCA25C25397CB820>73 D<0107B512FCA25E9026000FF8C7FC5D5D14 -1FA25DA2143FA25DA2147FA292C8FCA25CA25CA21301A25CA21303A25CA21307A25CA213 -0F170C4A141CA2011F153C17384A1478A2013F157017F04A14E01601017F140317C091C7 -1207160F49EC1F80163F4914FF000102071300B8FCA25E2E397BB834>76 -D79 -D81 D<92383FC00E913901FFF01C020713FC91 -391FC07E3C91393F001F7C027CEB0FF84A130749481303495A4948EB01F0A2495AA2011F -15E091C7FCA34915C0A36E90C7FCA2806D7E14FCECFF806D13F015FE6D6D7E6D14E00100 -80023F7F14079138007FFC150F15031501A21500A2167C120EA3001E15FC5EA3003E4A5A -A24B5AA2007F4A5A4B5A6D49C7FC6D133ED8F9F013FC39F8FC03F839F07FFFE0D8E01F13 -8026C003FCC8FC2F3D7ABA2F>83 D<0007B812E0A25AD9F800EB001F01C049EB07C0485A -D900011403121E001C5C003C17801403123800785C00701607140700F01700485CA2140F -C792C7FC5DA2141FA25DA2143FA25DA2147FA292C9FCA25CA25CA21301A25CA21303A25C -A21307A25CA2130FA25CEB3FF0007FB512F8B6FCA2333971B83B>I<14F8EB07FE90381F -871C90383E03FE137CEBF801120148486C5A485A120FEBC001001F5CA2EA3F801403007F -5C1300A21407485C5AA2140F5D48ECC1C0A2141F15831680143F1587007C017F1300ECFF -076C485B9038038F8E391F0F079E3907FE03FC3901F000F0222677A42A>97 -D<133FEA1FFFA3C67E137EA313FE5BA312015BA312035BA31207EBE0F8EBE7FE9038EF0F -80390FFC07C013F89038F003E013E0D81FC013F0A21380A2123F1300A214075A127EA214 -0F12FE4814E0A2141F15C05AEC3F80A215005C147E5C387801F8007C5B383C03E0383E07 -C0381E1F80D80FFEC7FCEA01F01C3B77B926>I<147F903803FFC090380FC1E090381F00 -70017E13784913383901F801F83803F003120713E0120FD81FC013F091C7FC485AA2127F -90C8FCA35A5AA45AA3153015381578007C14F0007EEB01E0003EEB03C0EC0F806CEB3E00 -380F81F83803FFE0C690C7FC1D2677A426>II<147F903803FFC090380FC1E09038 -3F00F0017E13785B485A485A485A120F4913F8001F14F0383F8001EC07E0EC1F80397F81 -FF00EBFFF8148090C8FC5A5AA55AA21530007C14381578007E14F0003EEB01E0EC03C06C -EB0F806CEB3E00380781F83803FFE0C690C7FC1D2677A426>IIIII108 -DII<147F903803FFC090380FC1F090381F00F8 -017E137C5B4848137E4848133E0007143F5B120F485AA2485A157F127F90C7FCA215FF5A -4814FEA2140115FC5AEC03F8A2EC07F015E0140F007C14C0007EEB1F80003EEB3F00147E -6C13F8380F83F03803FFC0C648C7FC202677A42A>I<9039078007C090391FE03FF09039 -3CF0787C903938F8E03E9038787FC00170497EECFF00D9F0FE148013E05CEA01E113C15C -A2D80003143FA25CA20107147FA24A1400A2010F5C5E5C4B5A131F5EEC80035E013F495A -6E485A5E6E48C7FC017F133EEC70FC90387E3FF0EC0F8001FEC9FCA25BA21201A25BA212 -03A25B1207B512C0A3293580A42A>I<3903C003F0390FF01FFC391E783C0F381C7C703A -3C3EE03F8038383FC0EB7F800078150000701300151CD8F07E90C7FCEAE0FE5BA2120012 -015BA312035BA312075BA3120F5BA3121F5BA3123F90C9FC120E212679A423>114 -D<14FE903807FF8090380F83C090383E00E04913F00178137001F813F00001130313F0A2 -15E00003EB01C06DC7FC7FEBFFC06C13F814FE6C7F6D13807F010F13C01300143F141F14 -0F123E127E00FE1480A348EB1F0012E06C133E00705B6C5B381E03E06CB45AD801FEC7FC -1C267AA422>II<01F013 -0ED803FC133FD8071EEB7F80EA0E1F121C123C0038143F49131F0070140FA25BD8F07E14 -0000E08013FEC6485B150E12015B151E0003141C5BA2153C000714385B5DA35DA24A5A14 -0300035C6D48C7FC0001130E3800F83CEB7FF8EB0FC0212679A426>118 -D<903907E007C090391FF81FF89039787C383C9038F03E703A01E01EE0FE3803C01F0180 -13C0D8070014FC481480000E1570023F1300001E91C7FC121CA2C75AA2147EA214FEA25C -A21301A24A1370A2010314F016E0001C5B007E1401010714C000FEEC0380010F1307010E -EB0F0039781CF81E9038387C3C393FF03FF03907C00FC027267CA427>120 -D<13F0D803FCEB01C0D8071EEB03E0D80E1F1307121C123C0038140F4914C01270A24913 -1FD8F07E148012E013FEC648133F160012015B5D0003147E5BA215FE00075C5BA214015D -A314035D14070003130FEBF01F3901F87FE038007FF7EB1FC7EB000F5DA2141F003F5C48 -133F92C7FC147E147C007E13FC387001F8EB03E06C485A383C1F80D80FFEC8FCEA03F023 -3679A428>I E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Ff cmsy10 10 1 -/Ff 1 16 df15 -D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fg ecbx1000 10 36 -/Fg 36 119 df<913803FFC0027F13F00103B512FC010FEB00FED93FF8133FD97FE0EBFF -8049485A5A1480484A13C04A6C1380A36F1300167E93C7FCA592383FFFC0B8FCA4000390 -C7FCB3ABB5D8FC3F13FFA4303A7EB935>28 D45 -DI<141E143E -14FE1307137FB5FCA3138FEA000FB3B3A5007FB61280A4213679B530>49 -DI54 D58 D66 DII73 -D76 DII< -EDFFF8020FEBFF80027F14F0903A01FFC01FFC010790380007FFD91FFC010113C0D93FF0 -6D6C7E49486E7E49486E7E48496E7E48834890C86C7EA248486F1380A248486F13C0A200 -3F18E0A348486F13F0A400FF18F8AC007F18F06D5DA3003F18E0A26D5D001F18C0A26C6C -4B13806C18006E5C6C6D4A5A6C5F6C6D4A5A6D6C4A5AD93FFC49485A6DB401075B0107D9 -C01F90C7FC010190B512FC6D6C14F0020F1480020001F8C8FC3D3B7BB948>III83 D85 DII<13 -FFB5FCA412077EAF4AB47E020F13F0023F13FC9138FE03FFDAF00013804AEB7FC00280EB -3FE091C713F0EE1FF8A217FC160FA217FEAA17FCA3EE1FF8A217F06E133F6EEB7FE06E14 -C0903AFDF001FF80903AF8FC07FE009039F03FFFF8D9E00F13E0D9C00390C7FC2F3A7EB9 -35>98 D100 -D<903803FF80011F13F0017F13FC3901FF83FE3A03FE007F804848133F484814C0001FEC -1FE05B003FEC0FF0A2485A16F8150712FFA290B6FCA301E0C8FCA4127FA36C7E1678121F -6C6C14F86D14F000071403D801FFEB0FE06C9038C07FC06DB51200010F13FC010113E025 -257DA42C>II<161FD907FEEBFFC090387FFFE348B6EAEFE02607FE07138F260FF801131F48486C13 -8F003F15CF4990387FC7C0EEC000007F81A6003F5DA26D13FF001F5D6C6C4890C7FC3907 -FE07FE48B512F86D13E0261E07FEC8FC90CAFCA2123E123F7F6C7E90B512F8EDFF8016E0 -6C15F86C816C815A001F81393FC0000F48C8138048157F5A163FA36C157F6C16006D5C6C -6C495AD81FF0EB07FCD807FEEB3FF00001B612C06C6C91C7FC010713F02B377DA530>I< -EA01F0EA07FC487EA2487EA56C5AA26C5AEA01F0C8FCA913FF127FA412077EB3A9B512F8 -A4153B7DBA1B>105 D<13FFB5FCA412077EAF92380FFFE0A4923803FC0016F0ED0FE0ED -1F804BC7FC157E5DEC03F8EC07E04A5A141FEC7FE04A7E8181A2ECCFFEEC0FFF496C7F80 -6E7F6E7F82157F6F7E6F7E82150F82B5D8F83F13F8A42D3A7EB932>107 -D<13FFB5FCA412077EB3B3ACB512FCA4163A7DB91B>I<01FED97FE0EB0FFC00FF902601 -FFFC90383FFF80020701FF90B512E0DA1F81903983F03FF0DA3C00903887801F000749DA -CF007F00034914DE6D48D97FFC6D7E4A5CA24A5CA291C75BB3A3B5D8FC1FB50083B512F0 -A44C257DA451>I<01FEEB7FC000FF903803FFF8020F13FE91381F03FFDA3C0113800007 -13780003497E6D4814C05CA25CA291C7FCB3A3B5D8FC3F13FFA430257DA435>I<903801 -FFC0010F13F8017F13FFD9FF807F3A03FE003FE048486D7E48486D7E48486D7EA2003F81 -491303007F81A300FF1680A9007F1600A3003F5D6D1307001F5DA26C6C495A6C6C495A6C -6C495A6C6C6CB45A6C6CB5C7FC011F13FC010113C029257DA430>I<9038FE03F000FFEB -0FFEEC3FFF91387C7F809138F8FFC000075B6C6C5A5CA29138807F80ED3F00150C92C7FC -91C8FCB3A2B512FEA422257EA427>114 D<90383FF0383903FFFEF8000F13FF381FC00F -383F0003007E1301007C130012FC15787E7E6D130013FCEBFFE06C13FCECFF806C14C06C -14F06C14F81203C614FC131F9038007FFE140700F0130114007E157E7E157C6C14FC6C14 -F8EB80019038F007F090B512C000F8140038E01FF81F257DA426>I<130FA55BA45BA25B -5BA25A1207001FEBFFE0B6FCA3000390C7FCB21578A815F86CEB80F014816CEBC3E09038 -3FFFC06D1380903803FE001D357EB425>I118 D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fh ecrm1000 10 89 -/Fh 89 126 df<486C1360000314E039070001C0000EEB038048EB070000181306003813 -0E0030130C0070131C00601318A200E01338481330A400CEEB338039FF803FE001C013F0 -A3007F131FA2393F800FE0390E0003801C1981B91C>16 D<001C1307007FEB1FC039FF80 -3FE0A201C013F0A3007F131F001CEB073000001300A400011470491360A2000314E090C7 -12C048130100061480000E130348EB070048130E485B006013181C1980B91C>I21 D27 -DI30 D36 D<141FEC7FC0903801F0 -E0903803C0600107137090380F803090381F00381518A25BA2133E133F15381530A21570 -5D5D140190381F838092CAFC1487148E02DC49B51280EB0FF85C4A9039003FF8000107ED -0FC06E5D71C7FC6E140E010F150CD91DFC141C01391518D970FE143801E015302601C07F -1470D803805D00076D6C5BD80F00EBC00148011F5C4890380FE003003E6E48C8FC007E90 -3807F8060203130E00FE6E5A6E6C5A1400ED7F706C4B13036F5A6F7E6C6C6D6C5B701306 -6C6C496C130E6DD979FE5B281FF001F07F133C3C07F80FE03FC0F86CB539800FFFF0C690 -26FE000313C0D91FF0D9007FC7FC393E7DBB41>38 D<121C127FEAFF80A213C0A3127F12 -1C1200A412011380A2120313005A1206120E5A5A5A12600A1979B917>I<146014E0EB01 -C0EB0380EB0700130E131E5B5BA25B485AA2485AA212075B120F90C7FCA25A121EA2123E -A35AA65AB2127CA67EA3121EA2121F7EA27F12077F1203A26C7EA26C7E1378A27F7F130E -7FEB0380EB01C0EB00E01460135278BD20>I<12C07E12707E7E7E120F6C7E6C7EA26C7E -6C7EA21378A2137C133C133E131EA2131F7FA21480A3EB07C0A6EB03E0B2EB07C0A6EB0F -80A31400A25B131EA2133E133C137C1378A25BA2485A485AA2485A48C7FC120E5A5A5A5A -5A13527CBD20>I<1530B3A8B912FCA2C80030C8FCB3A836367BAF41>43 -D<121C127FEAFF80A213C0A3127F121C1200A412011380A2120313005A1206120E5A5A5A -12600A19798817>II<121C127FEAFF80A5EA7F00121C09097988 -17>I<1506A2150E150CA2151C151815381530A215701560A215E015C0A214011580A214 -0315005C1406A2140E140CA2141C1418A214381430A21470146014E05CA213015CA21303 -91C7FCA25B1306A2130E130C131C1318A213381330A213701360A213E05BA212015B1203 -90C8FCA25A1206A2120E120CA2121C1218A21238123012701260A212E05AA21F537BBD2A ->II -III<1538A2157815F8A214011403 -1407A2140F141F141B14331473146314C313011483EB030313071306130C131C13181330 -1370136013C01201EA038013005A120E120C5A123812305A12E0B712F8A3C73803F800AA -4A7E0103B512F8A325387EB72A>I<0006140CD80780133C9038F003F890B5FC5D5D1580 -92C7FC14FC38067FE090C9FCAAEB07F8EB1FFE9038780F809038E007E03907C003F0496C -7E130000066D7E81C8FC8181A21680A4121C127F5A7FA390C713005D12FC00605C12704A -5A6C5C6C1303001E495A6C6C485A3907E03F800001B5C7FC38007FFCEB1FE021397CB62A ->II<12301238123E003FB612E0A316C05A168016 -000070C712060060140E5D5D00E014304814705D5DC712014A5A4AC7FC1406140E5CA25C -1478147014F05C1301A213035C1307A2130FA3131F5CA2133FA5137FA96DC8FC131E233A -7BB72A>III<121C127FEAFF80A5 -EA7F00121CC7FCB2121C127FEAFF80A5EA7F00121C092479A317>I<121C127FEAFF80A5 -EA7F00121CC7FCB2121C127FEAFF80A213C0A3127F121C1200A412011380A2120313005A -1206120E5A5A5A12600A3479A317>II<007FB812F8B912FCCCFCB0B912FC6C17F836147B9E41>I<12E01278121EEA07C0 -EA01F0EA003C130FEB03C0EB00F0143C140FEC03E0EC00F8151EED0780ED01E0ED007816 -1EEE07C0EE01F0EE003C170FEF03C0A2EF0F00173CEE01F0EE07C0041EC7FC1678ED01E0 -ED0780031EC8FC15F8EC03E0020FC9FC143C14F0EB03C0010FCAFC133CEA01F0EA07C000 -1ECBFC127812E0322E79AB41>II<1538A3157CA315FEA34A7EA34A6C7EA202077FEC063FA202 -0E7FEC0C1FA2021C7FEC180FA202387FEC3007A202707FEC6003A202C07F1501A2D90180 -7F81A249C77F167FA20106810107B6FCA24981010CC7121FA2496E7EA3496E7EA3496E7E -A213E0707E1201486C81D80FFC02071380B56C90B512FEA3373C7DBB3E>65 -DI<913A01FF800180020FEBE003027F13F8903A01FF807E07903A03 -FC000F0FD90FF0EB039F4948EB01DFD93F80EB00FF49C8127F01FE153F12014848151F48 -48150FA248481507A2485A1703123F5B007F1601A35B00FF93C7FCAD127F6DED0180A312 -3F7F001F160318006C7E5F6C7E17066C6C150E6C6C5D00001618017F15386D6C5CD91FE0 -5C6D6CEB03C0D903FCEB0F80902701FF803FC7FC9039007FFFFC020F13F002011380313D -7BBA3C>IIIIIII<013FB512 -E0A39039001FFC00EC07F8B3B3A3123FEA7F80EAFFC0A44A5A1380D87F005B0070131F6C -5C6C495A6C49C7FC380781FC3801FFF038007F80233B7DB82B>IIIIIIIII< -D90FF813C090383FFE0190B512813903F807E33907E000F74848137F4848133F48C7121F -003E140F007E1407A2007C140312FC1501A36C1400A37E6D14006C7E7F13F86CB47E6C13 -F8ECFF806C14E06C14F86C14FEC680013F1480010714C0EB007F020713E0EC007FED3FF0 -151F150FED07F8A200C01403A21501A37EA216F07E15036C15E06C14076C15C06C140F6D -EB1F80D8FBF0EB3F00D8F0FE13FE39E03FFFF8010F13E0D8C00190C7FC253D7CBA2E>I< -003FB812E0A3D9C003EB001F273E0001FE130348EE01F00078160000701770A300601730 -A400E01738481718A4C71600B3B0913807FF80011FB612E0A335397DB83C>IIII89 D<003FB7FCA39039FC0001FE -01C0130349495A003EC7FC003C4A5A5E0038141F00784A5A12704B5A5E006014FF4A90C7 -FCA24A5A5DC712074A5AA24A5A5D143F4A5AA24A5A92C8FC5B495AA2495A5C130F4948EB -0180A2495A5C137F495A16034890C7FC5B1203485AEE0700485A495C001F5D48485C5E48 -48495A49130FB8FCA329397BB833>II93 D<007FB81280B912C0A26C17 -803204797041>95 D97 DIIII<147E903803FF8090 -380FC1E0EB1F8790383F0FF0137EA213FCA23901F803C091C7FCADB512FCA3D801F8C7FC -B3AB487E387FFFF8A31C3B7FBA19>IIIIIII<2703F00FF0EB1FE000FFD93FFCEB -7FF8913AF03F01E07E903BF1C01F83803F3D0FF3800FC7001F802603F70013CE01FE14DC -49D907F8EB0FC0A2495CA3495CB3A3486C496CEB1FE0B500C1B50083B5FCA340257EA445 ->I<3903F00FF000FFEB3FFCECF03F9039F1C01F803A0FF3800FC03803F70013FE496D7E -A25BA35BB3A3486C497EB500C1B51280A329257EA42E>II<3903F01F -E000FFEB7FF89038F1E07E9039F3801F803A07F7000FC0D803FEEB07E049EB03F04914F8 -49130116FC150016FEA3167FAA16FEA3ED01FCA26DEB03F816F06D13076DEB0FE001F614 -C09039F7803F009038F1E07E9038F0FFF8EC1FC091C8FCAB487EB512C0A328357EA42E> -II<3807E01F00FFEB7FC09038E1E3E09038E387F0380FE707EA03E613EE9038EC03E0 -9038FC0080491300A45BB3A2487EB512F0A31C257EA421>II<1318A51338A31378A313F812011203 -1207001FB5FCB6FCA2D801F8C7FCB215C0A93800FC011580EB7C03017E13006D5AEB0FFE -EB01F81A347FB220>IIIIII<003FB512FCA2EB8003D83E0013F8003CEB07F00038 -EB0FE012300070EB1FC0EC3F800060137F150014FE495AA2C6485A495AA2495A495A495A -A290387F000613FEA2485A485A0007140E5B4848130C4848131CA24848133C48C7127C48 -EB03FC90B5FCA21F247EA325>II<126012F0B3B3B3 -B3A91260045377BD17>I<12FCEAFFC0EA07F0EA01FCEA007E7F80131F80130FB3A78013 -07806D7E6D7EEB007EEC1FF0EC07F8EC1FF0EC7E00495A495A495A5C130F5CB3A7131F5C -133F91C7FC137E485AEA07F0EAFFC000FCC8FC1D537ABD2A>I E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fi ecbx1440 14.4 34 -/Fi 34 118 df28 D45 D<151E153E15FE1403140F147FEB07FF00 -03B5FCB6FCA3EBF87FEAFC00C7FCB3B3B3A6007FB712FCA52E4E76CD42>49 -DI<913807FFC0027F13FC0103B67E010F15E090 -261FF80313F890267FC0007F01FEC7EA3FFE48488148486E138013FE486C6C6D13C08048 -17E080A66C5B18C06C5B6C90C75AD80038168090C8FC4C1300A24C5A5F4C5A4B5B4B13C0 -030F5BDB7FFEC7FC91387FFFF816C016FCEEFF80DA000313E09238007FF8EE3FFE707E70 -138018C07013E018F07013F8A218FC82A218FEA3EA03C0EA0FF0EA3FFC487EA2B5FCA218 -FCA25E18F8A26C4816F0495C4916E0D83FE04A13C06C485CD80FF04A1380D807FE91387F -FE003B03FFE003FFFC6C90B65A6C6C15E0010F92C7FC010114FCD9001F1380374F7BCD42 ->I<17FC1601A216031607160FA2161F163F167FA216FF5D5DA25D5D5D167F153E157E15 -FC15F8EC01F01403EC07E015C0EC0F80141FEC3F00143E5C14FC495A5C495A1307495A5C -49C7FC5B137E137C5B1201485A5B485A120F485A90C8FC123E127E5ABA1280A5C901FCC7 -FCAF021FB71280A5394F7CCE42>I<486C150601F0153E01FEEC01FED9FFF0133F91B65A -5F5F5F5F5F94C7FC16FC5E16E093C8FC15FC01F0138091CAFCAC913807FF80023F13F891 -B512FE01F36E7E9026FFFC0113E09139E0007FF891C76C7E496E7E01F86E7E5B70138049 -16C0C9FC18E08218F0A418F8A31203EA0FE0EA3FF8487EA212FF7FA218F0A25B5E6C4816 -E05B01C016C06CC85A18806C6C4A13007FD80FF04A5A6C6CECFFFCD803FE4913F02701FF -E00F5B6C6CB612806D92C7FC010F14F8010114C09026003FFCC8FC354F7ACD42>I58 -D<932603FFF01407047F01FF5C0307B600E05B033F03F85B92B700FE5B02039126C003FF -5B020F01F8C7EA3FC1023F01C0EC0FE391B5C80003B5FC4901FC814949814901E082011F -498249498292CA7E4948834948835A4A83485B4885A2484984A2485B87A2485B87A25AA2 -98C8FC91CFFCA2B5FCAE7E067FB7128080A37E95C76C90C7FC807EA36C7FA26C7FA26C7F -7E806C7F137F6D7E816D6D93B5FC01077F6D01F85D6D7F6D01FF5D023F01E0EC0FEF020F -01FCEC3FE30203903AFFE001FF81020091B6C6FC033F03FC133F030703F0130FDB007F02 -801303040301F8CAFC595479D267>71 D73 D76 -D78 D80 D<93381FFF800303B512FC033FECFFC0 -92B712F00207D9F80113FE021F903AC0003FFF804A48C700077FDAFFF8020113F049496E -7F49496F7E49496F7E49496F7E4990C96C7F4948707F4948707F01FF854849707F4A8248 -86A24849717E48864A83A2481B80A248497113C0A4481BE0A291CB7EA3B51AF0AF6C1BE0 -A36E5FA26C1BC0A36C1B806E5FA26C1B006E5F6C62A26C6DD903FC4A5A6CDB0FFF5D6E49 -EBC0016C4B01E05C6D6C90277E07F0035B6E9039F801F807902A3FFF01F000780F5B6D04 -7C5C6DD981E06D4890C7FC6D01E191381F7FFE010101F1EDFFF86DD9F9F06D5BDA3FFF16 -C06E6D013F5B02079027FE01FFFEC8FC020190B612F8DA003F4B141003071838DB001FEB -83F893C7EA03FC1C7885726C14F8F2C003F2F01F97B512F084A31CE085A27314C01C8085 -1C00735B735B735B735B9638003FC0556A79D263>III<003FBB12FCA59126C0007FEB000301FCC7ED003FD87FF0F00FFE491807 -49180349180190C81600A2007E1A7EA3007C1A3EA500FC1A3F481A1FA6C91700B3B3AC49 -B912C0A550517BD05B>I97 D<913803FFE0023F13FE91B67E010315E0010F9038003FF8D93FFCEB -07FC4948497E4948131F4849497E485B485BA24890C7FC5A5B003F6F5A705A705A007F92 -C8FC5BA312FFAD127F7FA3123F7F6CEE0F80A26C6D141F18006C6D5C6C6D143E6C6D147E -6C6D5C6D6C495A6DB4EB07F0010F9038C01FE06D90B5128001014AC7FCD9003F13F80203 -138031387CB63A>99 D<943803FF80040FB5FCA5EE003F170FB3A4913803FF80023F13F8 -49B512FE0107ECFF8F011F9038C03FEF90273FFE0007B5FCD97FF8130149487F48498048 -4980484980488291C8FC5A5B123FA2127F5BA312FFAD127FA37F123FA3121F7F6C5E6C6D -5C5F6C6D91B5FC6C6D5B6C6D4914E0D97FFCD90FEFEBFF80D91FFFEB7F8F010790B5120F -010114FC6D6C13E00207010049C7FC41547CD249>I<913807FF80027F13F849B512FE01 -076E7E011F010313E0903A3FFC007FF0D97FF06D7E49486D7E4849130F48496D7E488248 -90C77E1880485A82003F17C0A3485A18E082A212FFA290B8FCA401FCCAFCA6127FA37F12 -3FA2EF03E06C7E17076C17C06C6D140F18806C6D141F6C6DEC3F006C6D147ED97FFC495A -D91FFFEB07F86D9038E03FF0010390B512C001005D023F01FCC7FC020113E033387CB63C ->IIII<133FEBFFC0 -487F487FA2487FA66C5BA26C5B6C5B013FC7FC90C8FCAEEB1FF8B5FCA512017EB3B3A6B6 -12F0A51C547CD324>I108 -DII<913801FFC0023F13FE91B67E010315E001 -0F018013F8903A3FFC001FFED97FF0EB07FF49486D7F48496D7F48496D7F91C8127F4883 -488349153F001F83A2003F8349151FA2007F83A400FF1880AC007F1800A3003F5F6D153F -A2001F5FA26C6C4B5AA26C6D4A5A6C5F6C6D495B6C6D495B6D6C4990C7FCD93FFCEB1FFE -6DB46CB45A010790B512F0010115C0D9003F49C8FC020313E039387CB642>II<90393FF001FCB590 -380FFF804B13E0037F13F09238FE1FF89138F1F83F00019138F07FFC6CEBF3E015C0ECF7 -80A2ECFF00EE3FF84AEB1FF0EE0FE093C7FC5CA45CB3ABB612FEA52E367DB535>114 -D<903903FFC00E011FEBFC1E90B6127E000315FE3907FE003FD80FF0130F484813034848 -1301491300127F90C8127EA248153EA27FA27F01F091C7FC13FCEBFF806C13FEECFFF06C -14FE6F7E6C15E06C816C15FC6C81C681133F010F15801301D9000F14C0EC003F030713E0 -150100F880167F6C153FA2161F7EA217C07E6D143F17807F6DEC7F0001F85C6DEB03FE90 -39FF801FFC486CB512F0D8F81F14C0D8F00791C7FC39E0007FF02B387CB634>I<147CA6 -14FCA41301A31303A21307A2130F131F133F137F13FF1203000F90B512FEB7FCA426007F -FCC8FCB3A9EE0F80ABEE1F006D7EA2011F143E806D6D5A6DEBC1F86DEBFFF001005C023F -1380DA03FEC7FC294D7ECB33>II E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fj ecrm0900 9 5 -/Fj 5 109 df<123C127E12FFA4127E123C08087A8715>46 D97 DI104 -D108 -D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fk ecbx0900 9 7 -/Fk 7 117 df65 D97 DI<903807FF80013F13F090B512FC3903FE01FE4848487EEA0FF8EA1FF0EA3FE0 -A2007F6D5A496C5A153000FF91C7FCA9127F7FA2003FEC07807F6C6C130F000FEC1F00D8 -07FE133E3903FF80FCC6EBFFF8013F13E0010790C7FC21217DA027>I<3901F81F8000FF -EB7FF0ECFFF89038F9E3FC9038FBC7FE380FFF876C1307A213FEEC03FCEC01F8EC006049 -1300B1B512F0A41F217EA024>114 D<9038FFE1C0000713FF5A383F803F387E000F1407 -5A14037EA26C6CC7FC13FCEBFFE06C13FC806CEBFF80000F14C06C14E0C6FC010F13F0EB -007F140F00F0130714037EA26C14E06C13076CEB0FC09038C01F8090B5120000F913FC38 -E03FE01C217DA023>I<133CA5137CA313FCA21201A212031207001FB51280B6FCA3D807 -FCC7FCB0EC03C0A79038FE078012033901FF0F006C13FEEB3FFCEB0FF01A2F7EAE22>I -E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fl ecrm1200 12 25 -/Fl 25 122 df<121EEA7F8012FF13C0A213E0A3127FEA1E601200A413E013C0A3120113 -80120313005A1206120E5A5A5A12600B1D78891B>44 D<14FF010713E090381F81F89038 -3E007C01FC133F4848EB1F8049130F4848EB07C04848EB03E0A2000F15F0491301001F15 -F8A2003F15FCA390C8FC4815FEA54815FFB3A46C15FEA56D1301003F15FCA3001F15F8A2 -6C6CEB03F0A36C6CEB07E0000315C06D130F6C6CEB1F806C6CEB3F00013E137C90381F81 -F8903807FFE0010090C7FC28447CC131>48 D50 D54 D<16C04B7EA34B7EA34B7EA34B7EA3ED -19FEA3ED30FFA203707FED607FA203E07FEDC03FA2020180ED801FA2DA03007F160FA202 -06801607A24A6D7EA34A6D7EA34A6D7EA20270810260147FA202E08191B7FCA249820280 -C7121FA249C87F170FA20106821707A2496F7EA3496F7EA3496F7EA201788313F8486C83 -D80FFF03037FB500E0027FEBFFC0A342477DC649>65 DI68 D77 -D<003FB912F8A3903BF0001FF8001F01806D481303003EC7150048187C0078183CA20070 -181CA30060180CA5481806A5C81600B3B3A54B7EED7FFE49B77EA33F447DC346>84 -D -I97 -D99 D<167FED3FFFA315018182B3EC7F80903803 -FFF090380FC07C90383F000E017E1307496D5AD803F87F48487F5B000F81485AA2485AA2 -127FA290C8FC5AAB7E7FA2123FA26C7EA2000F5D7F6C6C5B00035C6C6C9038077F806C6C -010E13C0013F011C13FE90380FC0F8903803FFE09026007F0013002F467DC436>II103 D105 D108 D<3901FC01FE00FF903807FFC091381E -07F091383801F8000701707F0003EBE0002601FDC07F5C01FF147F91C7FCA25BA35BB3A8 -486CECFF80B5D8F83F13FEA32F2C7DAB36>110 DI<3903F803F000FFEB1FFCEC3C3EEC707F0007EBE0FF3803F9C000015B13FBEC00 -7E153C01FF13005BA45BB3A748B4FCB512FEA3202C7DAB26>114 -D<90383FE0183901FFFC383907E01F78390F0003F8001E1301481300007C1478127800F8 -1438A21518A27EA27E6C6C13006C7E13FC383FFFE06C13FC6C13FF6C14C06C14E0C614F0 -011F13F81300EC0FFC140300C0EB01FE1400157E7E153EA27EA36C143C6C147C15786C14 -F86CEB01F039F38003E039F1F00F8039E07FFE0038C00FF01F2E7DAC26>I<1306A5130E -A4131EA3133E137EA213FE12011207001FB512F0B6FCA2C648C7FCB3A4150CAA017E131C -017F1318A26D133890381F8030ECC070903807E0E0903801FFC09038007F001E3E7EBC26 ->III< -B539F001FFFCA3000790C7EA7FE06C48EC1F8000011600160E0000150C6D141C6D1418A2 -6E1338013F1430A26D6C5BA26E13E0010F5CA26D6C485AA2ECF803010391C7FCA2903801 -FC06A2ECFE0E0100130CA2EC7F18A215B8EC3FB0A2EC1FE0A36E5AA26E5AA36EC8FCA214 -06A35CA25CA2123C007E5BB4FC5CA25CEAFE01387C0380D87007C9FCEA3C1EEA0FFCEA03 -F02E3F7EAA33>121 D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fm ecbx1200 12 47 -/Fm 47 123 df<0118140C017C143E01FC147E48485C4848495A495C4848495A4848495A -001F140F90C75B003E4AC7FCA2003C141E007C143E0078143CA200F8147CA2481478D8F1 -F014F8D8F7FCEB7BFEB46CEB7FFF6D1580028014C0A36C80A36C806C496C13806C486D13 -006C486D5AD801F0EB00F82A2283C427>16 DI28 D46 D48 DIII<163FA25E5E5D5DA25D5D5D5DA25D92B5FCEC01F7EC03E7140715 -C7EC0F87EC1F07143E147E147C14F8EB01F0EB03E0130714C0EB0F80EB1F00133E5BA25B -485A485A485A120F5B48C7FC123E5A12FCB91280A5C8000F90C7FCAC027FB61280A53141 -7DC038>I<0007150301E0143F01FFEB07FF91B6FC5E5E5E5E5E16804BC7FC5D15E092C8 -FC01C0C9FCAAEC3FF001C1B5FC01C714C001DF14F09039FFE03FFC9138000FFE01FC6D7E -01F06D13804915C0497F6C4815E0C8FC6F13F0A317F8A4EA0F80EA3FE0487E12FF7FA317 -F05B5D6C4815E05B007EC74813C0123E003F4A1380D81FC0491300D80FF0495AD807FEEB -FFFC6CB612F0C65D013F1480010F01FCC7FC010113C02D427BC038>I<4AB47E021F13F0 -027F13FC49B6FC01079038807F8090390FFC001FD93FF014C04948137F4948EBFFE04849 -5A5A1400485A120FA248486D13C0EE7F80EE1E00003F92C7FCA25B127FA2EC07FC91381F -FF8000FF017F13E091B512F89039F9F01FFC9039FBC007FE9039FF8003FF17804A6C13C0 -5B6F13E0A24915F0A317F85BA4127FA5123FA217F07F121FA2000F4A13E0A26C6C15C06D -4913806C018014006C6D485A6C9038E01FFC6DB55A011F5C010714C0010191C7FC903800 -3FF02D427BC038>I<121E121F13FC90B712FEA45A17FC17F817F017E017C0A248168000 -7EC8EA3F00007C157E5E00785D15014B5A00F84A5A484A5A5E151FC848C7FC157E5DA24A -5A14035D14074A5AA2141F5D143FA2147F5D14FFA25BA35B92C8FCA35BA55BAA6D5A6D5A -6D5A2F447AC238>I58 D<1A60F101F01907191FF17FC0953801FF00F007FCF01FF0F07FC04D48C7FCEF07 -FCEF3FF0EFFFC0040390C8FCEE0FFCEE3FE0EEFF80DB03FEC9FCED0FF8ED3FE0EDFF80DA -07FECAFCEC1FF8EC7FE0903801FF80D907FCCBFCEB1FF0EB7FC04848CCFCEA07FCEA1FF0 -EA7FC048CDFCA2EA7FC0EA1FF0EA07FCEA01FF38007FC0EB1FF0EB07FC903801FF809038 -007FE0EC1FF8EC07FE913800FF80ED3FE0ED0FF8ED03FE923800FF80EE3FE0EE0FFCEE03 -FF040013C0EF3FF0EF07FCEF01FF9438007FC0F01FF0F007FCF001FF9538007FC0F11FF0 -19071901F10060444277B957>60 D<126012F812FE6C7EEA3FE0EA0FF8EA03FEC66C7EEB -3FE0EB0FF8EB03FE903800FFC0EC3FF0EC0FFCEC03FF9138007FC0ED1FF0ED07FCED01FF -9238007FC0EE1FF0EE07FE933801FF809338007FE0EF1FF8EF03FE943800FF80F03FE0F0 -0FF8F003FE953800FF80F13FE0F10FF0A2F13FE0F1FF80953803FE00F00FF8F03FE0F0FF -80DD03FEC7FCEF1FF8EF7FE0933801FF80DC07FEC8FCEE1FF0EE7FC04B48C9FCED07FCED -1FF0ED7FC0DA03FFCAFCEC0FFCEC3FF0ECFFC0D903FECBFCEB0FF8EB3FE0EBFF80D803FE -CCFCEA0FF8EA3FE0EAFF8048CDFC12F81260444277B957>62 D<923803FFF0037FEBFF80 -0203B612F0020F15FC913A3FFC000FFFDAFFC0010013C0D903FEC8EA1FF0D907F0ED03F8 -D91FC0ED00FE4948167F017ECAEA1F8049717E4848717E49DAFF8013034848010F01F06D -7E4848013F01FC6D7E92B6FC4848489026C07F80137C49489026001FC0133C484948D907 -E0133E001E49486D6C131E003E49480101141F023F913800FFE0003C4A82007C017F1880 -007819074A5AA300F81AC04848491603AB6C6C7F12781B801A076E7E127C003C133F003E -6E1700021F4A5C001E6D6C5B001F6D6C49EBF01E6C6D6C011F143E6D6CD9C07F6D5A6C6C -6C90B5383FFFF8033FD9FC0F5B6C6C010FD9F0035B6C6C0100903980007F806D91CBFC6C -7E137E6D7E6D6CEF7FC0D907F0EE03FFD903FE043F1300902600FFC0913803FFF8DA3FFC -49B512C0020FB748C7FC020316E0DA007F02FCC8FC030349C9FC4A477AC557>64 -DIIII73 D77 D<923807FFC092B512FE0207ECFFC0021F15F0 -91267FFE0013FC902601FFF0EB1FFF01070180010313C04990C76C7FD91FFC6E6C7E4948 -6F7E49486F7E01FF8348496F7E48496F1380A248496F13C0A24890C96C13E0A24819F049 -82003F19F8A3007F19FC49177FA400FF19FEAD007F19FC6D17FFA3003F19F8A26D5E6C19 -F0A26E5D6C19E0A26C6D4B13C06C19806E5D6C6D4B13006C6D4B5A6D6C4B5A6D6C4B5A6D -6C4A5B6D01C001075B6D01F0011F5B010101FE90B5C7FC6D90B65A023F15F8020715C002 -004AC8FC030713C047467AC454>79 D83 D<007FBA12E0BB12F0A46C19E04406776757>95 D<903801FFE0011F13FE017F6D -7E48B612E03A03FE007FF84848EB1FFC6D6D7E486C6D7EA26F7FA36F7F6C5A6C5AEA00F0 -90C7FCA40203B5FC91B6FC1307013F13F19038FFFC01000313E0481380381FFE00485A5B -127F5B12FF5BA35DA26D5B6C6C5B4B13F0D83FFE013EEBFFC03A1FFF80FC7F0007EBFFF8 -6CECE01FC66CEB8007D90FFCC9FC322F7DAD36>97 DIIIIIII<137C48B4FC4813804813C0A24813E0A56C13 -C0A26C13806C1300EA007C90C7FCAAEB7FC0EA7FFFA512037EB3AFB6FCA518467CC520> -I108 D<90277F8007FEEC0FFC -B590263FFFC090387FFF8092B5D8F001B512E002816E4880913D87F01FFC0FE03FF8913D -8FC00FFE1F801FFC0003D99F009026FF3E007F6C019E6D013C130F02BC5D02F86D496D7E -A24A5D4A5DA34A5DB3A7B60081B60003B512FEA5572D7CAC5E>I<90397F8007FEB59038 -3FFF8092B512E0028114F8913987F03FFC91388F801F000390399F000FFE6C139E14BC02 -F86D7E5CA25CA35CB3A7B60083B512FEA5372D7CAC3E>II<90397FC00FF8B590B57E02C314E002CF14F89139DFC03F -FC9139FF001FFE000301FCEB07FF6C496D13804A15C04A6D13E05C7013F0A2EF7FF8A4EF -3FFCACEF7FF8A318F017FFA24C13E06E15C06E5B6E4913806E4913006E495A9139DFC07F -FC02CFB512F002C314C002C091C7FCED1FF092C9FCADB67EA536407DAC3E>II<90387F807FB53881FFE002 -8313F0028F13F8ED8FFC91389F1FFE000313BE6C13BC14F8A214F0ED0FFC9138E007F8ED -01E092C7FCA35CB3A5B612E0A5272D7DAC2E>I<90391FFC038090B51287000314FF120F -381FF003383FC00049133F48C7121F127E00FE140FA215077EA27F01E090C7FC13FE387F -FFF014FF6C14C015F06C14FC6C800003806C15806C7E010F14C0EB003F020313E0140000 -F0143FA26C141F150FA27EA26C15C06C141FA26DEB3F8001E0EB7F009038F803FE90B55A -00FC5CD8F03F13E026E007FEC7FC232F7CAD2C>II< -D97FC049B4FCB50103B5FCA50003EC000F6C81B3A85EA25EA25E7E6E491380017FD901F7 -13FE9138F807E76DB512C7010F1407010313FE9026007FF0EBFC00372E7CAC3E>I -I120 -D<001FB71280A49026FC001F130001E0495A5B49495A90C7485A48495B123E4A5B4A5B00 -3C495BA24A90C7FC4A5A4A5AC7FC4A5A495B495BA2495B499038800780491300A2495A49 -48130F49481400A2485B48495B485BA248495B4890C75A48485C15034848EB1FFEB7FCA4 -292C7DAB32>122 D E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fn ecrm1728 17.28 8 -/Fn 8 117 df68 D70 D97 D102 D<1378EA01FE487E487FA66C -90C7FC6C5AEA007890C8FCB3A2EB0780EA0FFFB5FCA41203C6FCA2137FB3B3AC497E487F -B61280A4195F7BDE25>105 D<010FEB07F8D80FFFEB1FFEB590387FFF809238F81FC091 -3801E03F913903C07FE00003EB0780C6EB0F00140E6D5A0218EB3FC00238EB1F800230EB -0600027090C7FCA2146014E0A25CA55CB3B0497E4813F0B612F8A42B3F7BBE34>114 -D<9138FFC003010FEBF807017FEBFE0F3A01FF003F9FD803F0EB07DF48486DB4FCD80F80 -1300001F8148C8FC003E81007E81127C00FC81A4827EA27E7F6C7E6D91C7FC13F8EA3FFE -381FFFE06C13FF15F0000314FE6C6E7E6C6C14E0011F14F801078001008002077FDA003F -13801507030113C0ED007F00E0ED3FE0161F17F06C150F1607A36C1503A37EA26C16E016 -077E17C06D140F6D15806D141FD8FDF0EC3F00D8F8F8147E017C495A3AF01F801FF06DB5 -12C0D8E00391C7FC39C0007FF02C417CBF35>I<1470A714F0A51301A31303A21307A213 -0FA2131F133F137F13FF1203000F90B6FCB8FCA326000FF0C8FCB3AEEE01C0AE6D6CEB03 -80A316076D6C14005E6D6C130E6D6C131E6E6C5A91383FE0F86EB45A020713C0020090C7 -FC2A597ED734>I E -%EndDVIPSBitmapFont -%DVIPSBitmapFont: Fo ecbx1728 17.28 18 -/Fo 18 117 df68 D<942603FFF8151C94B66C -143C040F03F0147C047F03FC14FC0303B81301030FDAC00113C0033F01F8C7381FF00392 -B500C0913807F807020349C83801FE0F020F01F89238007F1F4A01E0EE3FBF4A49EE0FFF -91B5CA7E494983494983494983495B4949187F4B183F491A1F495B90B5CC120FA2484919 -075A4A19035A4A19015AA24A19005AA348491A7CA35A9AC8FCA35CA2B5FCB07EA26E043F -B81280A47E96C7000701FCC7FCA26C7FA37E80A27E807E807E6C7FA26D7F6D7F7F816D7F -6D6D5F6D7F6D6D5F6D6D7E023F6D5E6E01F05E6E6DEEFE7F020301FF923801FC3F020002 -C0913807F80F033F01FC91381FF007030F903BFFE001FFC001030391B6EA8000DB007F4B -C7123C040F03F8140C040003C091C8FC050301F8CBFC696677E37A>71 -D82 D<001FBD12F0A59126F8000191C7123F4801C0 -060713F849C71700491A7F01F01A1F491A0F491A07A2491A03A290C81801A2007EF300FC -A4007C1C7CA7481C3EA5C91900B3B3B3A5023FB912F8A55F617AE06C>84 -D<913803FFF0027F13FF0103B612E0010F15F890263FFC0013FED97FC090381FFF8049C7 -6C7F4801C06D7F486D6D7F6E6D7F48836E7F84177F84A36C496E7FA26C5B6C5B013FC8FC -90C9FCA75F0307B6FC4AB7FC141F91B5EAF03F0103EBFE00010F13F0013F1380D9FFFEC7 -FC485B485B485B485B485B485BA24890C8FC1A7CA2485AA35FA394B5FC7F6C5D6EEB03DF -6CDB07CFEBC0F86C6DEB0F8F6C6DD91F07EBF3F06C01F8017E14FF6C9027FE01FC0314E0 -C690B5D8F00114C0013F9126C0007F1380010791C7383FFE009026003FF8EC07F846437B -C14D>97 D<903807FF80B6FCA5C6FC7F7FB3A9933801FFE0041F13FE047FEBFFC00381B6 -12F0922687FC0113FC923A9FE0003FFEDBBF8090380FFF8003FEC76C7F4B6E7F4B6E7F4B -6E7F4B824B157F4B82737EA21B80851BC0A31BE085A41BF0AE1BE0A44F13C0A31B80A24F -1300A262197F6F5E6F4B5A4E5B6F4A5BDAFCF84A5BDAF87E4A5B4A6C4A90C7FC9126E01F -C0EB7FFC913BC00FF803FFF8DA8003B612E091C71580013E023F01FCC8FC90C800031380 -4C657CE356>II101 DII105 D<903807FF80B6FCA5C6FC7F7FB3B3B3B3AFB7 -12E0A523647CE32A>108 D110 D<92381FFF804AB512F8020F -14FF023F15C09126FFFC0313F001039039E0007FFC490180EB1FFED91FFEC73807FF8049 -486E7F49486E7F49486E7F48496F7EA248496F7E4884A248496F7EA2481980A24819C091 -C97EA24819E0A5B518F0AD6C19E0A46C6D4B13C0A36C1980A26C6D4B1300A26C606E157F -6C606C6D4B5A6C606D6C4A5B6D6C4A5B6D6C4A5B6D6C6C011F90C7FC010301E0EB7FFC6D -9039FC03FFF86D6CB612E0020F92C8FC020114F8DA001F138044437CC14D>I<903B07FF -8001FFE0B6011F13FE047FEBFFC00381B612F0922687FC0313FC923A9FE0007FFEC6DABF -806D6C7E6D01FEC7000F7F6D496E7F4B824B6E7F4B6E7F4B804B82737EA21B80851BC0A2 -851BE0A4851BF0AE4F13E0A41BC061A21B80A24F1300A24F5AA26F4A5B6F4A5B626F4A5B -6F4A5B03FE4A5B03BF027F90C7FCDB9FC0EBFFFC92268FF8075B0383B612E00380158004 -3F01FCC8FC0403138093CBFCB3A4B712E0A54C5D7CC056>I114 DII E -%EndDVIPSBitmapFont -end -%%EndProlog -%%BeginSetup -%%Feature: *Resolution 600dpi -TeXDict begin -%%PaperSize: A4 - -%%EndSetup -%%Page: 1 1 -1 0 bop 290 639 a Fo(Genealogical)56 b(Represen)l(tation)e(of)f(T)-13 -b(rees)52 b(in)g(Databases)1686 822 y Fn(First)46 b(Draft)1247 -1063 y Fm(Miguel)36 b(Sofer)i()1359 1179 -y Fl(Univ)m(ersidad)33 b(T)-8 b(orcuato)33 b(Di)f(T)-8 -b(ella)1728 1295 y(Buenos)33 b(Aires)1797 1411 y(Argen)m(tina)1746 -1606 y(Ma)m(y)h(6,)e(2000)1839 1905 y Fk(Abstract)441 -2035 y Fj(blah)25 b(blah)h(.)13 b(.)g(.)118 2310 y Fi(1)131 -b(In)l(tro)t(duction)118 2491 y Fh(T)-7 b(rees)28 b(are)h(a)g(v)n(ery)f -(frequen)n(t)h(data)f(structure.)41 b(They)30 b(are)e(the)h(natural)g -(represen)n(tation)e(for)i(instance)g(for)f(organiza-)118 -2591 y(tional)f(c)n(harts,)g(threaded)g(discussion)g(groups,)f(some)h -(bills)g(of)h(materials,)e(.)14 b(.)g(.)243 2691 y(A)n(t)28 -b(least)f(t)n(w)n(o)f(alternativ)n(e)h(represen)n(tations)e(for)i -(trees)g(in)h(RDBMs)g(are)e(kno)n(wn)h(and)h(used:)220 -2857 y(1.)41 b Fg(P)m(oin)m(ters:)k Fh(a)31 b(\034eld)h(in)h(the)f(c)n -(hild)g(record)e(references)h(the)h(paren)n(t)f(no)r(de.)50 -b(This)32 b(seems)g(to)f(b)r(e)i(the)f(canonical)326 -2956 y(represen)n(tation.)38 b(Some)29 b(DB)g(engines)f(pro)n(vide)g -(sp)r(ecial)g(SQL)g(extensions)g(to)h(simplify)g(tree)g(searc)n(hes;)e -(Oracle)326 3056 y(tree)d(extensions)g(are)g(an)h(example)f(\(see)h -(for)f(instance)g([1]\);)i(DB2's)f(WITH)g(can)f(b)r(e)i(used)e(for)h -(this)g(purp)r(ose)f(to)r(o)326 3156 y(\(see)j([3],)g(pp)h(139-162\).) -220 3322 y(2.)41 b Fg(Nested)35 b(Sets:)43 b Fh(t)n(w)n(o)30 -b(n)n(umeric)h(\034elds)g(in)g(ev)n(ery)f(no)r(de)h(record)f(co)r(de)h -(the)g(tree)g(structure.)47 b(I)31 b(can't)g(pro)n(vide)f(a)326 -3421 y(b)r(etter)e(or)e(briefer)h(description)g(of)h(this)g(metho)r(d)g -(than)f(the)h(four)f(articles)g([2].)118 3587 y(These)g(t)n(w)n(o)g -(metho)r(ds)h(o\033er)f(di\033eren)n(t)h(adv)-5 b(an)n(tages)25 -b(and)j(disadv)-5 b(an)n(tages:)243 3753 y Ff(\017)41 -b Fh(P)n(oin)n(ters)30 b(are)g(extremely)g(e\036cien)n(t)h(for)f(no)r -(de)h(insertion)f(and/or)g(deletion,)h(but)h(require)e(recursiv)n(e)f -(table)i(ac-)326 3853 y(cesses)e(to)h(searc)n(h)f(the)h(tree)g(\(I)h -(do)f(not)g(kno)n(w)f(the)i(implemen)n(tation)f(details)g(of)g(the)h -(Oracle)e(tree)g(extensions,)326 3953 y(whic)n(h)e(as)g(far)g(as)g(I)g -(kno)n(w)g(ma)n(y)g(solv)n(e)f(this)i(problem)f(in)n(ternally;)g(they)g -(de\034nitely)h(solv)n(e)f(it)g(for)g(the)h(end)g(user\).)243 -4119 y Ff(\017)41 b Fh(Nested)30 b(sets)g(are)f(v)n(ery)f(e\036cien)n -(t)i(for)g(tree)f(searc)n(hes,)g(but)i(are)e(rather)f(exp)r(ensiv)n(e)i -(for)f(no)r(de)h(insertion)f(and/or)326 4218 y(deletion:)37 -b(they)27 b(require)g(up)r(dating)g(p)r(oten)n(tially)h(man)n(y)f(no)r -(des.)243 4384 y(W)-7 b(e)30 b(prop)r(ose)f(here)h(a)g(di\033eren)n(t)h -(represen)n(tation,)e(based)g(on)i(no)r(de)f(iden)n(ti\034ers)g(whic)n -(h)g(are)f(\020genealogical)f(iden)n(ti-)118 4484 y(\034ers\021:)44 -b(they)32 b(con)n(tain)f(the)h(complete)f(genealogy)f(of)h(the)h(no)r -(de,)h(i.e.,)g(the)f(list)g(of)g(ancestors)d(up)j(to)g(the)g(ro)r(ot)f -(of)g(the)118 4584 y(tree.)243 4683 y(This)j(allo)n(ws)f(to)i(replace)e -(man)n(y)h(searc)n(hes)f(in)h(database)g(tables)g(with)h(string)f(op)r -(erations)f(on)h(the)h(index.)58 b(The)118 4783 y(result,)24 -b(as)f(explained)h(in)g(Section)g(3)f(is)h(that)g(tree)f(searc)n(hes)f -(pro)r(ceed)h(at)h(\020nested)f(sets\021)30 b(sp)r(eed,)25 -b(while)f(no)r(de)g(insertions)118 4882 y(and)k(deletions)f(are)f(as)h -(fast)h(as)f(with)h(p)r(oin)n(ters.)243 4982 y(The)i(ob)n(vious)f(do)n -(wnside)h(of)h(the)g(metho)r(d)g(is)f(that)h(the)g(primary)f(k)n(ey)f -(in)i(the)g(tree)f(needs)h(to)f(b)r(e)h(a)g(v)-5 b(ariable)29 -b(size)118 5082 y(text)j(\034eld,)h(and)f(that)g(the)g(iden)n -(ti\034ers)f(ma)n(y)g(b)r(e)i(extremelly)e(long)g(for)g(deep)h(trees.) -49 b(W)-7 b(e)32 b(will)g(pro)n(vide)e(estimates)i(of)118 -5181 y(the)c(size)f(required)g(as)g(a)g(function)h(of)g(the)f -(magnitude)h(of)f(the)h(tree.)1987 5653 y(1)p eop -%%Page: 2 2 -2 1 bop 118 291 a Fi(2)131 b(Genealogical)45 b(iden)l(ti\034ers)g(for)f -(trees)118 489 y Fm(2.1)112 b(De\034nition)118 642 y -Fh(W)-7 b(e)28 b(de\034ne)g Fe(gene)l(alo)l(gic)l(al)k(identi\034ers)j -Fh(recursiv)n(ely)25 b(as)i(follo)n(ws:)326 808 y Fg(De\034nition:)59 -b Fe(The)42 b(gene)l(alo)l(gic)l(al)h(identi\034er)f(\(gID\))e(of)i(a)f -(no)l(de)h(is)f(obtaine)l(d)h(by)g(app)l(ending)g(a)f(child)326 -908 y(identi\034er)30 b(to)g(the)g(gene)l(alo)l(gic)l(al)h -(identi\034er)g(of)f(the)g(p)l(ar)l(ent)f(no)l(de.)243 -1074 y Fh(Remark)40 b(that)h(genealogical)e(iden)n(ti\034ers)i(are)f -(rather)g(w)n(ell)h(kno)n(wn)f(and)h(used;)48 b(common)41 -b(examples)f(are)g(the)118 1174 y(\020path+\034le-name\021)33 -b(in)28 b(a)f(computer)g(\034le)h(system)f(and)h(the)f(URLs)h(within)g -(a)f(WWW.)243 1273 y(The)d(name)g(\020genealogical)e(iden)n -(ti\034er\021)30 b(is)24 b(suggested)g(b)n(y)g(the)g(fact)h(that)f(the) -h(v)-5 b(alue)24 b(of)g(the)h(iden)n(ti\034er)f(con)n(tains)f(the)118 -1373 y(complete)30 b(genealogy)d(of)j(the)g(no)r(de:)41 -b(it)30 b(con)n(tains)e(as)h(a)h(substring)f(the)h(gID)f(of)h(its)g -(father,)g(whic)n(h)f(in)h(turn)g(con)n(tains)118 1472 -y(as)d(a)g(substring)g(the)h(gID)g(of)f(the)h(grandfather,)e(.)14 -b(.)g(.)243 1572 y(The)27 b(ro)r(ot)g(no)r(de)h(of)f(the)h(tree)f(has)g -(a)h(gID)f(with)h(v)-5 b(alue)28 b(\021)34 b(\(the)28 -b(empt)n(y)g(string\),)f(as)g(it)h(has)f(no)g(paren)n(t.)118 -1804 y Fm(2.2)112 b(Child)36 b(iden)m(ti\034ers)118 1958 -y Fh(The)26 b(ob)n(vious)e(c)n(hild)i(iden)n(ti\034er)g(is)f(a)h -(zero-based)d(coun)n(ter:)35 b(iden)n(tify)26 b(the)h(c)n(hild)e(b)n(y) -h(the)g(n)n(um)n(b)r(er)f(of)h(older)f(brethren)g(it)118 -2057 y(has.)243 2157 y(W)-7 b(e)25 b(could)f(represen)n(t)g(the)h(coun) -n(ter)f(in)h(base)f(10;)h(this)g(ho)n(w)n(ev)n(er)e(is)i(extremely)f(w) -n(asteful)g(of)h(resources.)34 b(It)25 b(is)g(m)n(uc)n(h)118 -2257 y(b)r(etter)33 b(to)f(represen)n(t)f(the)h(coun)n(ter)g(in)g(as)g -(large)e(a)i(base)g(as)f(p)r(ossible:)46 b(in)n(terpret)32 -b(as)f(n)n(um)n(b)r(ers)h(a)g(set)g(of)g(c)n(haracters)118 -2356 y(larger)26 b(than)h({0,1,.)14 b(.)g(.)g(9}.)243 -2456 y(As)26 b(tree)f(op)r(erations)f(will)i(in)n(v)n(olv)n(e)f(string) -g(op)r(erations)f(on)i(the)g(indices,)g(in)g(order)f(to)g(a)n(v)n(oid)g -(a)g(\020quoting)g(hell\021)33 b(it)26 b(is)118 2555 -y(desirable)d(to)h(a)n(v)n(oid)e(using)h(an)n(y)g(c)n(haracter)f(with)i -(a)g(sp)r(ecial)f(meaning)h(in)g(LIKE)g(expressions)e(or)g(regular)g -(expressions;)118 2655 y(i.e.,)28 b(w)n(e)f(will)h(not)f(use)h(an)n(y)f -(of)g(the)h(sym)n(b)r(ols)70 b Fd(.)44 b(*)f(^)g(\\)g([)g(])g({)h(})f -(\()g(\))g(<)g(>)71 b Fh(?)37 b(|)28 b(&)f($)243 2755 -y(W)-7 b(e)28 b(prop)r(ose)e(to)h(reserv)n(e)f(also)g(/)i(as)f(a)g -(separator)e(\(see)i(\020V)-7 b(ariable)27 b(Sized)g(gID\021)34 -b(b)r(elo)n(w\).)243 2854 y(If)g(w)n(e)f(limit)i(ourselv)n(es)d(to)i -(ascii)f(c)n(haracters,)g(and)h(a)n(v)n(oid)e(to)i(b)r(e)g(safe)f(a)h -(lot)g(of)g(other)f(c)n(haracters,)g(w)n(e)g(can)h(use)118 -2954 y(n)n(um)n(b)r(ers)27 b(in)h(base)f(64)g(b)n(y)g(represen)n(ting) -243 3120 y Ff(\017)41 b Fh(0-9)26 b(with)i('0'-'9')f(\(dec)g(ascii)g -(co)r(de)h(48-57\))243 3286 y Ff(\017)41 b Fh(10)26 b(with)i(':')37 -b(\(dec)28 b(ascii)f(co)r(de)h(58\))243 3452 y Ff(\017)41 -b Fh(11)26 b(with)i(';')g(\(dec)g(ascii)f(co)r(de)g(59\))243 -3618 y Ff(\017)41 b Fh(12-37)25 b(with)j('A'-'Z')g(\(dec)f(ascii)g(co)r -(de)h(65-90\))243 3784 y Ff(\017)41 b Fh(38-63)25 b(with)j('a'-'z')f -(\(dec)h(ascii)f(co)r(de)g(97-122\))118 3950 y(By)g(using)g(base)f(64,) -h(up)g(to)h(4096)d(c)n(hildren)i(can)f(b)r(e)i(represen)n(ted)e(using)h -(t)n(w)n(o)f(suc)n(h)h(digits,)g(up)h(to)f(262144)d(with)k(three)118 -4050 y(digits,)g(and)f(up)h(to)f(16777216)d(with)k(four)f(digits.)243 -4149 y(If)37 b(the)g(RDBMs)g(supp)r(orts)f(in)n(ternational)g(c)n -(haracters,)h(it)g(is)g(p)r(ossible)f(to)h(further)f(increase)g(the)h -(base;)k(as)36 b(an)118 4249 y(example,)30 b(b)n(y)f(using)g(the)h(95)f -(additional)g(c)n(haracters)e(of)i(the)h(latin-1)f(c)n(haracter)e(set,) -k(w)n(e)e(could)g(co)r(de)g(n)n(um)n(b)r(ers)g(in)h(a)118 -4349 y(base)f(up)g(to)g(160)f(\025)g(remark)g(that)h(ev)n(ery)f(single) -h(digit)g(is)g(still)h(one)e(b)n(yte)h(in)h(this)f(represen)n(tation.) -40 b(This)29 b(means)f(that)118 4448 y(w)n(e)f(expand)h(the)f(sym)n(b)r -(ols)g(ab)r(o)n(v)n(e)f(b)n(y)i(represen)n(ting)243 4614 -y Ff(\017)41 b Fh(64-159)25 b(with)j(dec)f(latin1)g(co)r(de)h(160-255) -243 4780 y(In)23 b(base)g(160,)g(up)g(to)h(25600)d(c)n(hildren)i(can)f -(b)r(e)i(represen)n(ted)e(using)h(t)n(w)n(o)g(digits,)h(up)g(to)f -(4096000)d(with)k(three)f(digits,)118 4880 y(and)28 b(up)f(to)h -(6.5E+08)e(with)i(four)f(digits.)243 4980 y(Remark)g(that)h(base)f(con) -n(v)n(ersions)f(only)h(need)i(to)e(b)r(e)i(p)r(erformed)e(at)h -(insertion)g(time,)g(when)h(the)f(index)g(of)g(a)g(new)118 -5079 y(no)r(de)g(is)f(computed.)37 b(They)28 b(will)f(therefore)g(only) -g(ha)n(v)n(e)f(an)i(impact)f(on)h(insertion)f(timings.)1987 -5653 y(2)p eop -%%Page: 3 3 -3 2 bop 118 291 a Fm(2.3)112 b(Coun)m(ters:)50 b(\020delimited\021)44 -b(vs.)51 b(\020\034xed)38 b(size\021)118 444 y Fh(The)33 -b(standard)g(represen)n(tation)e(of)i(gID)h(uses)e(a)h(v)-5 -b(ariable)32 b(size)h(c)n(hild)h(iden)n(ti\034er,)g(and)f(delimiters)g -(to)h(separate)d(the)118 543 y(gID)f(of)g(the)h(c)n(hild)f(no)r(de)g -(from)f(the)i(gID)f(of)g(its)g(paren)n(t.)43 b(F)-7 b(or)30 -b(example,)g(w)n(e)g(can)f(represen)n(t)g(the)i(\034fth)g(c)n(hild)f -(of)g(no)r(de)118 643 y('/23/27/1')24 b(as)j('/23/27/1/4'.)32 -b(Let)c(us)f(call)g(this)h(a)f Fg(vgID)h Fh(represen)n(tation)e(\(V)-7 -b(ariable)27 b(Size)h(Genealogical)d(ID\).)243 743 y(This)30 -b(represen)n(tation)f(allo)n(ws)f(for)i(an)n(y)g(n)n(um)n(b)r(er)g(of)g -(c)n(hildren)g(of)h(a)f(no)r(de,)h(sub)5 b(ject)30 b(only)g(to)g(the)h -(limitations)f(the)118 842 y(RDBMS)e(ma)n(y)f(ha)n(v)n(e)f(as)h(to)h -(the)g(length)f(of)h(a)f(v)-5 b(ariable)27 b(sized)g(string.)243 -942 y(Alternativ)n(ely)-7 b(,)24 b(w)n(e)f(could)h(c)n(ho)r(ose)f(to)h -(limit)g(from)g(the)g(outset)g(the)g(quan)n(tit)n(y)g(of)f(c)n(hildren) -h(that)g(a)g(no)r(de)g(ma)n(y)f(ha)n(v)n(e;)118 1042 -y(this)28 b(limit)g(w)n(ould)f(dep)r(end)i(of)e(course)f(on)i(the)g -(application.)36 b(Let)27 b(us)h(call)f(this)h(a)f Fg(fgID)h -Fh(represen)n(tation.)243 1141 y(F)-7 b(or)25 b(example,)h(if)g(no)g -(no)r(de)f(is)h(allo)n(w)n(ed)f(to)g(ha)n(v)n(e)g(more)g(than)h(25600)d -(c)n(hildren,)j(w)n(e)g(could)f(represen)n(t)g(the)h(coun)n(ters)118 -1241 y(alw)n(a)n(ys)36 b(with)i(2)f(digits.)67 b(The)38 -b(no)r(de)f(whic)n(h)h(w)n(as)f(previously)f('/23/27/1/4')d(is)k(no)n -(w)g('23270104'.)64 b(If)38 b(w)n(e)f(require)118 1340 -y(a)g(three)g(digit)h(represen)n(tation)d(of)i(no)r(des)g(\(up)h(to)f -(ab)r(out)h(4)f(million)g(c)n(hildren\),)j(then)d(it)h(will)g(b)r(e)f -(represen)n(ted)f(as)118 1440 y('023027001004'.)118 1672 -y Fm(2.4)112 b(Ordering)37 b(of)h(no)s(des)118 1825 y -Fh(F)-7 b(or)35 b(some)g(applications)g(it)h(is)f(necessary)f(to)i -(obtain)f(subtrees)g(ordered)f(according)g(to)i(some)f(sp)r(ecial)g -(rules.)60 b(F)-7 b(or)118 1925 y(instance:)220 2090 -y(1.)41 b(the)34 b(complete)g(subtree)f(starting)g(at)h(a)f(no)r(de)h -(is)g(listed)g(immediately)g(after)f(the)i(no)r(de)f(in)g(question)f -(\(\020depth)326 2189 y(\034rst\021\))220 2354 y(2.)41 -b(no)r(des)27 b(with)h(a)f(common)g(paren)n(t)g(are)g(listed)g(c)n -(hronologically)243 2519 y(F)-7 b(or)39 b(instance,)k(the)d(displa)n(y) -f(of)h(an)f(organization)f(c)n(hart)h(is)g(usually)h(required)e(to)i -(satisfy)g(at)f(least)h(the)g(\034rst)118 2619 y(condition.)h(In)29 -b(a)g(threaded)f(discussion)h(group)e(one)i(wishes)g(to)f(satisfy)h(b)r -(oth)h(conditions)e(to)h(displa)n(y)f(the)h(messages)118 -2718 y(in)20 b(a)g(thread)g(\025)f(the)i(threads)e(themselv)n(es)h -(\(i.e.,)i(c)n(hildren)e(of)g(the)g(ro)r(ot)f(no)r(de\))i(are)e -(usually)g(listed)i(in)f(in)n(v)n(erse)f(c)n(hronolical)118 -2818 y(order.)243 2917 y(T)-7 b(o)35 b(mak)n(e)f(a)h(particular)f -(ordering)g(e\036cien)n(t,)j(it)f(w)n(ould)f(b)r(e)h(a)f(nice)g -(feature)g(if)h(it)g(could)f(b)r(e)h(made)f(to)g(coincide)118 -3017 y(with)28 b(a)f(lexicographic)f(ordering)f(of)j(the)g(indices)f -(\025i.e.,)g(as)g(pro)r(duced)g(b)n(y)h(an)f(\020ORDER)h(BY)f(id)h -(ASC\021)35 b(in)27 b(SQL.)h(The)118 3117 y(lexicographic)d(ordering)h -(of)h(fgID)h(satis\034es)e(b)r(oth)i(conditions.)36 b(The)27 -b(lexicographic)f(ordering)f(of)i(vgID)g(as)g(describ)r(ed)118 -3216 y(ab)r(o)n(v)n(e)34 b(satis\034es)g(the)h(\034rst)g(requisite)f -(if)i(the)f(separator)d(has)j(the)g(minimal)g(binary)g(represen)n -(tation)e(of)i(all)f(allo)n(w)n(ed)118 3316 y(sym)n(b)r(ols)c(in)h(an)f -(index)h(\025)f(this)h(is)g(wh)n(y)f(w)n(e)g(reserv)n(ed)f(/)h(for)g -(the)i(separator.)43 b(But)31 b(the)g(second)f(prop)r(ert)n(y)g(is)g -(missing:)118 3416 y(for)d(instance,)g(the)h(index)g('/1/10')d(is)j -(lexicographically)d(b)r(efore)i('/1/2'.)243 3515 y(If)c(the)h(second)e -(prop)r(ert)n(y)g(is)i(also)e(required)g(for)h(vgID,)g(w)n(e)f(can)h -(sp)r(ecify)h(the)f(c)n(hild)h(iden)n(ti\034ers)e(with)i(coun)n(ters)e -(built)118 3615 y(in)28 b(the)g(follo)n(wing)e(w)n(a)n(y:)36 -b(represen)n(t)26 b(a)h(n)n(um)n(b)r(er)h(b)n(y)f(a)g(string)g(of)g -(digits,)h(where)243 3779 y Ff(\017)41 b Fh(the)25 b(\034rst)g(digit)h -Fc(D)896 3791 y Fb(0)958 3779 y Fh(represen)n(ts)e(the)i(length)f(in)h -(digits)f(of)g(the)h(decimal)f(expansion)f(of)i(the)f(n)n(um)n(b)r(er,) -h(min)n(us)f(one)243 3945 y Ff(\017)41 b Fh(the)28 b(follo)n(wing)e -Fa(\()p Fc(D)920 3957 y Fb(0)976 3945 y Fa(+)18 b(1\))27 -b Fh(digits)h(are)e(the)i(decimal)g(expansion)e(of)i(the)g(n)n(um)n(b)r -(er)118 4109 y(Let)g(us)f(call)h(these)f(iden)n(ti\034ers)g -Fg(m-vgID)p Fh(,)g(\020m\021)34 b(for)27 b(mo)r(di\034ed.)243 -4209 y(As)e(an)f(example,)h(the)g(no)r(de)g(whic)n(h)g(w)n(as)f -(previously)f(represen)n(ted)h(b)n(y)g(/15/3/182)d(will,)k(after)g -(this)g(mo)r(di\034cation,)118 4309 y(ha)n(v)n(e)h(the)i(index)g -(/115/03/2182.)243 4408 y(The)37 b(lexicographic)f(ordering)g(of)i -(m-vgID)f(is)h(the)g(desired)f(ordering)f(of)h(the)h(tree)g(no)r(des.) -67 b(The)38 b(cost)f(of)g(this)118 4508 y(prop)r(ert)n(y)31 -b(is)i(that)f(\(a\))h(the)g(ID)f(are)g(no)n(w)g(longer,)g(\(b\))h(no)f -(no)r(de)g(can)g(ha)n(v)n(e)g(more)f(than)i Fa(160)3106 -4478 y Fb(160)3240 4508 y Fh(c)n(hildren)f(\(actually)-7 -b(,)118 4607 y(this)32 b(is)g(a)f(non-issue\),)h(and)f(\(c\))h(the)g -(index)g(structure)f(is)h(redundan)n(t,)g(some)f(formally)f(correct)h -(indices)g(are)g(in)n(v)-5 b(alid)118 4707 y(\025e.g.,)24 -b(/316/013/11.)30 b(The)24 b(third)g(issue)g(can)g(b)r(e)g(addressed)f -(b)n(y)g(k)n(eeping)g(a)h(strict)g(con)n(trol)e(on)i(the)g(generation)f -(of)h(new)118 4807 y(indices)k(to)f(insure)g(that)h(all)f(indices)h -(are)e(formally)h(correct.)243 4906 y(The)32 b(issue)f(of)h(the)g(rev)n -(erse)e(c)n(hronological)f(indexing)j(of)f(threads)h(in)g(threaded)f -(discussion)g(groups)g(can)g(b)r(e)h(ad-)118 5006 y(dressed)d(easily)f -(enough)h(in)h(fgID:)f(coun)n(t)g(\020do)n(wn\021)36 -b(instead)29 b(of)g(\020up\021)36 b(the)30 b(c)n(hildren)f(of)g(the)h -(ro)r(ot)e(no)r(de)i(\025)f(this)h(implies)118 5106 y(only)e(an)g -(inconsequen)n(tial)f(mo)r(di\034cation)h(of)g(the)g(no)r(de)h -(insertion)e(routine,)h(as)g(sho)n(wn)f(b)r(elo)n(w.)38 -b(The)29 b(problem)e(is)h(less)118 5205 y(trivial)i(with)g(vgID;)h(in)f -(this)h(case,)f(ma)n(yb)r(e)f(a)h(thread)g(iden)n(ti\034er)g(should)g -(b)r(e)h(k)n(ept)f(in)g(a)g(di\033eren)n(t)g(\034eld)h(-)f(i.e.,)h -(repre-)118 5305 y(sen)n(ting)h(the)h(structure)f(as)g(a)h(forest)f -(rather)f(than)i(a)f(tree,)i(where)e(the)h(thread_id)f(\034eld)h -(selects)f(the)h(\020tree\021)38 b(in)33 b(the)118 5404 -y(forest.)1987 5653 y(3)p eop -%%Page: 4 4 -4 3 bop 118 291 a Fi(3)131 b(T)-11 b(ree)45 b(op)t(erations)e(using)h -(genealogical)g(indices)118 472 y Fh(In)32 b(this)f(section)g(w)n(e)g -(sho)n(w)g(ho)n(w)g(to)g(implemen)n(t)h(v)-5 b(arious)30 -b(tree)h(op)r(erations)f(using)h(gID)g(as)g(the)h(primary)e(k)n(ey)h -(in)g(the)118 572 y(no)r(de)d(table.)243 672 y(Some)h(implemen)n -(tation)h(issues)g(are)f(relev)-5 b(an)n(t)29 b(here,)h(esp)r(ecially)f -(concerning)g(the)h(utilisation)g(of)g(indices)g(b)n(y)f(the)118 -771 y(DB)f(engine.)243 871 y(W)-7 b(e)28 b(discuss)f(a)g(tree)g -(represen)n(ted)f(in)i(a)f(table)h(of)f(the)h(form)326 -1034 y Fd(CREATE)41 b(TABLE)g(tree)h(\()456 1134 y(gid)304 -b(text)42 b(PRIMARY)f(KEY,)456 1234 y(nchildren)f(integer)h(DEFAULT)f -(0,)456 1333 y(\\ldots)h(the)i(actual)e(node)h(data)326 -1433 y(\);)118 1597 y Fh(The)26 b(\034eld)g(\020nc)n(hildren\021)32 -b(is)26 b(a)f(coun)n(ter)g(for)g(the)i(n)n(um)n(b)r(er)e(of)h(c)n -(hildren)f(that)h(the)h(no)r(de)f(has)f Fe(ever)35 b -Fh(had;)27 b(w)n(e)e(assume)g(here)118 1696 y(it)j(is)g(not)f(up)r -(dated)h(when)g(no)r(des)f(or)g(subtrees)g(are)f(deleted.)243 -1796 y(Section)h(4)g(pro)n(vides)f(a)i(complete)f(implemen)n(tation)h -(of)f(these)h(op)r(erations)e(for)h(fgID)h(in)g(P)n(ostgreSQL.)118 -2028 y Fm(3.1)112 b(Computing)37 b(the)g(lev)m(el)f(of)h(a)h(no)s(de) -118 2181 y Fg(Cost:)f Fe(string)30 b(op)l(er)l(ations)g(\(no)g(table)g -(ac)l(c)l(ess\))243 2280 y Fh(This)d(is)h(a)f(pure)g(string)g(op)r -(eration,)f(no)i(table)f(access)g(is)g(required.)243 -2460 y Ff(\017)41 b Fg(vgID:)27 b Fh(coun)n(t)h(the)g(n)n(um)n(b)r(er)f -(of)g(separators)e(\('/'\))j(in)g(the)g(PK)243 2625 y -Ff(\017)41 b Fg(fgID:)27 b Fh(coun)n(t)g(the)h(n)n(um)n(b)r(er)g(of)f -(c)n(haracters)e(in)j(the)g(PK,)g(divide)g(b)n(y)f(the)h(\034xed)f -(size)h(of)f(the)h(coun)n(ters.)118 2857 y Fm(3.2)112 -b(Selecting)36 b(or)h(deleting)f(a)i(subtree)118 3010 -y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l(e)l(e)243 -3173 y Ff(\017)41 b Fg(vgID:)27 b Fh(The)h(subtree)f(ro)r(oted)g(at)g -(/26/5/7)e(is)i(selected)g(b)n(y)508 3338 y Fd(...)43 -b(WHERE)e(id)i(LIKE)f('/26/5/7\045')d(AND)j(id)h(<)g('/26/5/70')243 -3503 y Ff(\017)e Fg(m-vgID:)26 b Fh(The)h(subtree)h(ro)r(oted)e(at)i -(/126/05/07)22 b(is)28 b(selected)f(b)n(y)508 3668 y -Fd(...)43 b(WHERE)e(id)i(LIKE)f('/126/06/07\045')243 -3833 y Ff(\017)f Fg(fgID:)27 b Fh(The)h(subtree)f(ro)r(oted)g(at)g -(260507)e(is)i(selected)h(b)n(y)508 3997 y Fd(...)43 -b(WHERE)e(id)i(LIKE)f('260507\045')118 4229 y Fm(3.3)112 -b(Selecting)36 b(the)h(direct)f(c)m(hildren)g(of)i(a)g(no)s(de)118 -4382 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l(e)l(e)243 -4562 y Ff(\017)41 b Fg(vgID:)27 b Fh(The)h(direct)f(c)n(hildren)g(of)h -(/26/5/7)c(are)j(selected)g(b)n(y)508 4727 y Fd(...)43 -b(WHERE)e(id)i(LIKE)f('/26/5/7/\045')d(AND)j(id)h(NOT)f(LIKE)g -('26/5/7/\045/\045')243 4892 y Ff(\017)f Fg(m-vgID:)26 -b Fh(The)h(direct)h(c)n(hildren)f(of)g(/26/5/7)e(are)h(selected)i(b)n -(y)508 5056 y Fd(...)43 b(WHERE)e(id)i(LIKE)f('/126/06/07/\045')37 -b(AND)43 b(id)f(NOT)h(LIKE)f('/126/05/07/\045/\045)o(')243 -5221 y Ff(\017)f Fg(fgID:)27 b Fh(The)h(direct)f(c)n(hildren)g(of)h -(260507)c(are)j(selected)g(b)n(y)508 5386 y Fd(...)43 -b(WHERE)e(id)i(LIKE)f('260507\045')d(AND)k(char_length\(id\))37 -b(=)43 b(\(char_length\('26)o(05)o(07')o(\)+)o(2\))1987 -5653 y Fh(4)p eop -%%Page: 5 5 -5 4 bop 118 291 a Fm(3.4)112 b(Inserting)37 b(a)h(no)s(de)g(or)f(a)h -(subtree)118 444 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l -(e)l(e)f(+)h(string)f(and)h(math)g(op)l(er)l(ations)243 -543 y Fh(Insertion)f(is)g(a)h(pro)r(cedural)e(op)r(eration.)42 -b(As)30 b(eac)n(h)f(RDBMS)h(has)f(a)h(di\033eren)n(t)f(w)n(a)n(y)g(of)g -(de\034ning)h(pro)r(cedures,)f(w)n(e)118 643 y(will)f(just)g(describ)r -(e)f(here)g(the)h(necessary)e(steps.)37 b(Examples)27 -b(for)g(P)n(ostgreSQL)f(are)h(pro)n(vided)f(in)i(4.)243 -743 y(In)22 b(order)f(to)h(insert)g(a)g(new)g(c)n(hild)h(of)f -(\020daddy\021)28 b(\(either)23 b(one)f(of)g(/26/5/7,)e(/126/05/07)d -(or)22 b(260507)d(in)k(the)f(examples)118 842 y(ab)r(o)n(v)n(e\))27 -b(y)n(ou)f(ha)n(v)n(e)h(to)220 1008 y(1.)41 b(add)27 -b(one)g(to)h(the)g(n)n(um)n(b)r(er)f(of)g(c)n(hildren)h(of)f -(\020daddy\021)508 1174 y Fd(UPDATE)41 b(tree)h(SET)h(nchildren)c(=)k -(\(nchildren)d(+)j(1\))g(WHERE)e(ID)i(=)g(``daddy'';)220 -1340 y Fh(2.)e(enco)r(de)27 b(the)h(n)n(um)n(b)r(er)f(of)g(c)n(hildren) -g(of)h(\020daddy\021)33 b(in)28 b(base)f(160,)f(bring)h(it)h(to)f(the)h -(correct)e(format)h(dep)r(ending)h(on)326 1440 y(the)c(v)-5 -b(arian)n(t)23 b(of)h(gID)g(\(pad)g(with)h(0)e(or)g(not,)i(prep)r(end)f -(a)g(digit)g(coun)n(ter)f(or)g(not,)i(prep)r(end)f(/)g(or)f(not,)i -(coun)n(t)e(do)n(wn)326 1540 y(or)j(up,)i(.)14 b(.)g(.)g(\))37 -b(and)28 b(app)r(end)f(it)h(to)g(daddy's)f(gID)g(to)h(obtain)f(the)h -(new)g(no)r(de's)f(gID.)220 1706 y(3.)41 b(insert)27 -b(the)h(new)f(no)r(de)243 1872 y(When)35 b(inserting)g(a)f(subtree,)j -(the)e(index)g(of)g(the)h(ro)r(ot)e(of)h(the)g(subtree)g(has)f(to)h(b)r -(e)h(computed)f(as)f(ab)r(o)n(v)n(e,)i(and)118 1971 y(prep)r(ended)28 -b(to)f(the)h(index)g(of)f(eac)n(h)g(no)r(de)h(of)f(the)h(subtree)f(b)r -(efore)h(insertion.)243 2071 y(Remark)e(that)i(only)f(the)h(paren)n(t)f -(no)r(de)h(has)f(to)g(b)r(e)h(up)r(dated)g(on)f(insertion.)118 -2303 y Fm(3.5)112 b(Selecting)36 b(the)h(ancestors)h(of)g(a)g(no)s(de) -118 2457 y Fg(Cost:)f Fe(index)30 b(sc)l(an)g(of)g(the)g(tr)l(e)l(e)243 -2556 y Fh(Y)-7 b(ou)27 b(can)g(sp)r(ecify)h(all)g(ancestors)d(of)j(a)f -(no)r(de)h(in)f(a)h(single)f(SQL)g(statemen)n(t;)g(for)g(instance)h -(for)f(vgID)326 2722 y Fd(...)42 b(WHERE)f('/25/6/7')f(LIKE)i(\(id)g -(||)h('/\045'\))f(AND)g(id)h(<)g('/25/6/7')118 2888 y -Fh(The)31 b(second)e(part)h(of)h(the)g(clause,)f(while)h(logically)e -(redundan)n(t,)h(is)h(a)f(\020hin)n(t\021)37 b(to)30 -b(the)h(optimizer.)45 b(A)n(t)31 b(least)f(in)g(P)n(ost-)118 -2988 y(greSQL,)c(without)i(it)g(the)g(optimizer)f(will)h(c)n(ho)r(ose)e -(a)i(sequen)n(tial)e(scan)h(of)h(the)g(table)f(and)h(disregard)d(the)j -(index.)118 3220 y Fm(3.6)112 b(Selecting)36 b(all)g(lea)m(v)m(es)118 -3374 y Fg(Cost:)h Fe(sc)l(an)30 b(of)g(the)g(tr)l(e)l(e)243 -3473 y Fh(A)e(leaf)f(is)g(a)h(no)r(de)f(without)h(descendan)n(ts:)36 -b(it)28 b(has)f(0)g(c)n(hildren.)37 b(Hence)326 3639 -y Fd(...)42 b(WHERE)f(nchildren)f(=)j(0)118 3805 y Fh(If)28 -b(this)g(t)n(yp)r(e)g(of)f(query)g(is)h(often)f(necessary)-7 -b(,)26 b(y)n(ou)h(ma)n(y)g(b)r(e)h(w)n(ell)f(advised)g(to)g(k)n(eep)g -(an)h(index)f(on)h(tree\(nc)n(hildren\).)118 4038 y Fm(3.7)112 -b(Determining)35 b(if)i(A)g(is)g(a)h(descendan)m(t)g(of)g(B)118 -4191 y Fg(Cost:)f Fe(string)30 b(op)l(er)l(ations,)h(no)f(table)g(ac)l -(c)l(ess)243 4291 y Fh(This)d(is)h(a)f(pure)g(string)g(op)r(eration)f -(on)i(the)g(indices,)f(no)g(table)h(access)e(is)i(necessary)-7 -b(.)118 4565 y Fi(4)131 b(Putting)45 b(it)f(all)h(together:)57 -b(a)44 b(P)l(ostgreSQL)f(implemen)l(tation)118 4747 y -Fh(h)n(ttp://www.p)r(ostgresql.org/mhonarc/pgsq)o(l-sql/)o(20)o(00)o -(-0)o(4/)o(msg0)o(02)o(67)o(.h)n(tml)243 4847 y(W)-7 -b(e)30 b(describ)r(e)g(here)g(a)g(small)f(pac)n(k)-5 -b(age)29 b(that)i(can)e(b)r(e)i(used)f(for)g(implemen)n(ting)g(gID)g -(on)g(P)n(ostgreSQL.)f(It)i(can)e(b)r(e)118 4946 y(found)f(at)f()243 5046 y(The)21 b(pac)n(k)-5 b(age)21 b(uses)g(the)h(pro) -r(cedural)e(language)h(PL/PGsql.)35 b(A)22 b(b)r(etter)g(implemen)n -(tation)g(w)n(ould)f(probably)g(de\034ne)118 5145 y(the)28 -b(gID)g(as)f(new)g(P)n(ostgres)f(t)n(yp)r(es,)i(and)f(co)r(de)g(all)h -(this)g(in)f(C.)243 5245 y(The)g(\034les)h(should)f(b)r(e)h(loaded)f -(in)h(alphab)r(etical)f(order.)1987 5653 y(5)p eop -%%Page: 6 6 -6 5 bop 118 291 a Fm(4.1)112 b(tree0_enco)s(ding.sql)118 -444 y Fh(This)28 b(\034le)f(de\034nes)h(and)f(p)r(opulates)h(the)f -(table)h(_b160_digits)d(of)j(\020digits\021)33 b(in)28 -b(base)f(160,)326 604 y Fd(CREATE)41 b(TABLE)g(\\_b160\\_digits)d -(\(deci)j(integer,)f(code)i(char\);)118 764 y Fh(and)28 -b(the)f(t)n(w)n(o)g(functions)326 924 y Fd(CREATE)41 -b(FUNCTION)f(\\_b160\\_encode\(i)o(nt)o(eg)o(er\))d(RETURNS)j(string) -413 1024 y(AS)j('....')e(LANGUAGE)f('plpgsql';)326 1124 -y(CREATE)h(FUNCTION)f(\\_b160\\_encode\(i)o(nt)o(eg)o(er,)o(in)o(te)o -(ger)o(\))d(RETURNS)k(string)413 1223 y(AS)i('....')e(LANGUAGE)f -('plpgsql';)118 1384 y Fh(The)22 b(\034rst)h(function)f(returns)g(a)g -(v)-5 b(ariable)21 b(size)h(enco)r(ding;)i(the)f(second)e(a)h(\034xed)h -(size)f(enco)r(ding)g(\(the)h(second)e(parameter)118 -1483 y(is)g(the)h(size\),)g(and)f(raises)e(an)i(exception)g(if)h(the)f -(n)n(um)n(b)r(er)g(is)g(to)r(o)g(large)e(to)i(b)r(e)h(represen)n(ted)e -(with)h(the)h(requested)e(n)n(um)n(b)r(er)118 1583 y(of)28 -b(digits.)118 1814 y Fm(4.2)112 b(tree1_de\034ne.sql)118 -1967 y Fh(This)28 b(\034le)f(pro)n(vides)f(a)i(function)326 -2127 y Fd(CREATE)41 b(FUNCTION)f(_tree_create\(tex)o(t,)o(in)o(teg)o -(er)o(,t)o(ext)o(,t)o(ex)o(t\))d(RETURNS)k(bpchar)413 -2227 y(AS)i('....')e(LANGUAGE)f('plpgsql';)118 2387 y -Fh(that)e(creates)f(a)h(tree)f(infrastructure)g(of)h(either)g(fgID)g -(or)f(vgID.)h(Assuming)f(y)n(ou)g(ha)n(v)n(e)g(a)h(table)f(\020m)n -(ytable\021)44 b(with)118 2487 y(primary)26 b(k)n(ey)h(\020m)n -(yid\021,)g(then)h(calling)326 2647 y Fd(SELECT)41 b(_tree_create\('m)o -(yt)o(ree)o(',)o(2,')o(my)o(ta)o(ble)o(',)o('m)o(yid)o('\))o(;)118 -2807 y Fh(will)28 b(cause:)220 2967 y(1.)41 b(the)28 -b(creation)e(of)i(a)f(table)508 3131 y Fd(CREATE)41 b(TABLE)h -(mytree_bkg\()683 3230 y(gid)g(text)g(PRIMARY)e(KEY,)683 -3330 y(nchildren)f(int,)683 3429 y(sid)j(integer)f(REFERENCES)e -(mytable\(myid\))508 3529 y(\);)508 3629 y(CREATE)i(UNIQUE)g(INDEX)h -(mytree_bkg_sid)37 b(ON)43 b(mytree_bkg\(sid\);)326 3792 -y Fh(for)27 b(the)h(tree)f(structure.)220 3955 y(2.)41 -b(the)28 b(creation)e(of)i(a)f(view)508 4118 y Fd(CREATE)41 -b(VIEW)h(mytree)f(AS)639 4218 y(SELECT)g(t.gid,n.*)900 -4317 y(FROM)h(mytable)f(n,)i(mytree_bkg)c(t)900 4417 -y(WHERE)j(t.sid=n.myid;)326 4580 y Fh(with:)35 b(a)23 -b(trigger)e(on)i(UPD)n(A)-7 b(TE)25 b(that)e(blo)r(c)n(ks)g(up)r -(dating)g(the)h(gid)f(and)g(allo)n(ws)f(up)r(dating)h(the)g(no)r(de)h -(data,)f(a)g(rule)326 4680 y(on)k(DELETE)i(that)f(deletes)f(the)h -(corresp)r(onding)e(en)n(try)h(b)r(oth)h(in)g(m)n(ytree_bkg)d(and)j(m)n -(ytable,)f(and)g(a)g(trigger)326 4779 y(ON)h(INSER)-7 -b(T)30 b(that)f(raises)e(an)h(exception)g(and)g(informs)h(the)f(user)g -(to)h(use)f(the)h(insertion)f(function)h(describ)r(ed)326 -4879 y(b)r(elo)n(w.)220 5042 y(3.)41 b(t)n(w)n(o)26 b(insertion)h -(functions)h(that)g(compute)g(automatically)e(the)i(gID)g(of)f(the)h -(new)g(no)r(de:)425 5205 y Ff(\017)41 b Fh(a)27 b(function)i(m)n -(ytree_insert\(text,text,in)n(teger,text\))d(for)h(insertion)g(sim)n -(ultaneosly)f(in)i(b)r(oth)g(tables:)508 5305 y(m)n -(ytree_insert\('2201','hello',0,'not)15 b(m)n(uc)n(h'\))j(inserts)g(a)g -(new)g(c)n(hild)h(of)f(2201)f(with)h(data1='hello',)h(data2=0)508 -5404 y(and)28 b(data3='not)e(m)n(uc)n(h')1987 5653 y(6)p -eop -%%Page: 7 7 -7 6 bop 425 291 a Ff(\017)41 b Fh(a)27 b(function)i(m)n -(ytree_insert_no)r(de\(text,in)n(teger\))c(for)i(insertion)g(in)h(m)n -(ytree_bkg)508 390 y(m)n(ytree_insert\('2201',25\))c(inserts)j(in)h(m)n -(ytree_bkg)e(a)h(new)h(c)n(hild)f(of)h(2201)d(with)j(sid=25)220 -556 y(4.)41 b(a)27 b(function)h(m)n(ytree_mo)n(v)n(e\(text,text\))e -(that)i(mo)n(v)n(es)e(subtrees:)326 656 y(m)n(ytree_mo)n(v)n -(e\('2201','23'\))d(mo)n(v)n(es)j(the)i(subtree)f(ro)r(oted)g(at)g -(2201)f(to)h(a)h(place)f(b)r(elo)n(w)g(23)f(\(ma)n(yb)r(e)i(2307\))220 -822 y(5.)41 b(a)c(function)g(m)n(ytree_len\(\))g(that)h(returns)e(the)i -(length)f(of)g(the)h(enco)r(dings)f(used)g(in)h(the)f(gID)g(\(2)h -(here;)j(0)c(if)326 922 y(v)-5 b(ariable)26 b(size\).)118 -1196 y Fi(5)131 b(Non-tree)44 b(hierarc)l(hies)118 1378 -y Fh(sequence)22 b(as)f(id,)j(table)e(with)h(\(id,g-index\))f(with)g(p) -r(ossibly)g(man)n(y)g(g-indices)f(for)h(eac)n(h)f(id)h(\(if)h(TOO)f -(man)n(y)-7 b(,)23 b(bad)f(mo)r(del:)118 1478 y(list)28 -b(all)f(genealogies,)f(i.e.,)h(paths)h(from)f(the)h(ro)r(ot\))118 -1752 y Fi(References)160 1934 y Fh([1])41 b(Philip)28 -b(Greenspun,)g Fe(T)-6 b(r)l(e)l(es)29 b(in)h(Or)l(acle)g(SQL)p -Fh(,)d(in)h Fg(SQL)k(for)g(W)-8 b(eb)31 b(Nerds)289 2033 -y Fh()160 2200 -y([2])41 b(Jo)r(e)27 b(Celk)n(o,)f Fe(SQL)j(for)i(Smarties)p -Fh(,)d(in)g Fg(DBMS)j(Online)p Fh(,)26 b(Marc)n(h)h(to)g(June)h(1996) -289 2299 y()289 -2399 y()289 -2498 y()289 -2598 y()160 -2764 y([3])41 b(Graeme)26 b(Birc)n(hall,)h Fg(DB2)32 -b(UDB)g(V6.1)f(SQL)h(Co)s(okb)s(o)s(ok)p Fh(,)289 2864 -y()1987 5653 -y(7)p eop -%%Trailer -end -userdict /end-hook known{end-hook}if -%%EOF diff --git a/ldb-2.0.8/ldb_tdb/ldb_tdb.c b/ldb-2.0.8/ldb_tdb/ldb_tdb.c deleted file mode 100644 index 77cd5e9..0000000 --- a/ldb-2.0.8/ldb_tdb/ldb_tdb.c +++ /dev/null @@ -1,593 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 2006-2008 - Copyright (C) Matthias Dieter Wallnöfer 2009-2010 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb_tdb - * - * Component: ldb tdb backend - * - * Description: core functions for tdb backend - * - * Author: Andrew Tridgell - * Author: Stefan Metzmacher - * - * Modifications: - * - * - description: make the module use asynchronous calls - * date: Feb 2006 - * Author: Simo Sorce - * - * - description: make it possible to use event contexts - * date: Jan 2008 - * Author: Simo Sorce - * - * - description: fix up memory leaks and small bugs - * date: Oct 2009 - * Author: Matthias Dieter Wallnöfer - */ - -#include "ldb_tdb.h" -#include "ldb_private.h" -#include "../ldb_key_value/ldb_kv.h" -#include - -/* - lock the database for read - use by ltdb_search and ltdb_sequence_number -*/ -static int ltdb_lock_read(struct ldb_module *module) -{ - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - int tdb_ret = 0; - int ret; - pid_t pid = getpid(); - - if (ldb_kv->pid != pid) { - ldb_asprintf_errstring(ldb_module_get_ctx(module), - __location__ - ": Reusing ldb opend by pid %d in " - "process %d\n", - ldb_kv->pid, - pid); - return LDB_ERR_PROTOCOL_ERROR; - } - - if (tdb_transaction_active(ldb_kv->tdb) == false && - ldb_kv->read_lock_count == 0) { - tdb_ret = tdb_lockall_read(ldb_kv->tdb); - } - if (tdb_ret == 0) { - ldb_kv->read_lock_count++; - return LDB_SUCCESS; - } - ret = ltdb_err_map(tdb_error(ldb_kv->tdb)); - if (ret == LDB_SUCCESS) { - ret = LDB_ERR_OPERATIONS_ERROR; - } - ldb_debug_set(ldb_module_get_ctx(module), - LDB_DEBUG_FATAL, - "Failure during ltdb_lock_read(): %s -> %s", - tdb_errorstr(ldb_kv->tdb), - ldb_strerror(ret)); - return ret; -} - -/* - unlock the database after a ltdb_lock_read() -*/ -static int ltdb_unlock_read(struct ldb_module *module) -{ - void *data = ldb_module_get_private(module); - struct ldb_kv_private *ldb_kv = - talloc_get_type(data, struct ldb_kv_private); - pid_t pid = getpid(); - - if (ldb_kv->pid != pid) { - ldb_asprintf_errstring(ldb_module_get_ctx(module), - __location__ - ": Reusing ldb opend by pid %d in " - "process %d\n", - ldb_kv->pid, - pid); - return LDB_ERR_PROTOCOL_ERROR; - } - if (!tdb_transaction_active(ldb_kv->tdb) && - ldb_kv->read_lock_count == 1) { - tdb_unlockall_read(ldb_kv->tdb); - ldb_kv->read_lock_count--; - return 0; - } - ldb_kv->read_lock_count--; - return 0; -} - -static int ltdb_store(struct ldb_kv_private *ldb_kv, - struct ldb_val ldb_key, - struct ldb_val ldb_data, - int flags) -{ - TDB_DATA key = { - .dptr = ldb_key.data, - .dsize = ldb_key.length - }; - TDB_DATA data = { - .dptr = ldb_data.data, - .dsize = ldb_data.length - }; - bool transaction_active = tdb_transaction_active(ldb_kv->tdb); - if (transaction_active == false){ - return LDB_ERR_PROTOCOL_ERROR; - } - return tdb_store(ldb_kv->tdb, key, data, flags); -} - -static int ltdb_error(struct ldb_kv_private *ldb_kv) -{ - return ltdb_err_map(tdb_error(ldb_kv->tdb)); -} - -static const char *ltdb_errorstr(struct ldb_kv_private *ldb_kv) -{ - return tdb_errorstr(ldb_kv->tdb); -} - -static int ltdb_delete(struct ldb_kv_private *ldb_kv, struct ldb_val ldb_key) -{ - TDB_DATA tdb_key = { - .dptr = ldb_key.data, - .dsize = ldb_key.length - }; - bool transaction_active = tdb_transaction_active(ldb_kv->tdb); - if (transaction_active == false){ - return LDB_ERR_PROTOCOL_ERROR; - } - return tdb_delete(ldb_kv->tdb, tdb_key); -} - -static int ltdb_transaction_start(struct ldb_kv_private *ldb_kv) -{ - pid_t pid = getpid(); - - if (ldb_kv->pid != pid) { - ldb_asprintf_errstring(ldb_module_get_ctx(ldb_kv->module), - __location__ - ": Reusing ldb opend by pid %d in " - "process %d\n", - ldb_kv->pid, - pid); - return LDB_ERR_PROTOCOL_ERROR; - } - - return tdb_transaction_start(ldb_kv->tdb); -} - -static int ltdb_transaction_cancel(struct ldb_kv_private *ldb_kv) -{ - pid_t pid = getpid(); - - if (ldb_kv->pid != pid) { - ldb_asprintf_errstring(ldb_module_get_ctx(ldb_kv->module), - __location__ - ": Reusing ldb opend by pid %d in " - "process %d\n", - ldb_kv->pid, - pid); - return LDB_ERR_PROTOCOL_ERROR; - } - - return tdb_transaction_cancel(ldb_kv->tdb); -} - -static int ltdb_transaction_prepare_commit(struct ldb_kv_private *ldb_kv) -{ - pid_t pid = getpid(); - - if (ldb_kv->pid != pid) { - ldb_asprintf_errstring(ldb_module_get_ctx(ldb_kv->module), - __location__ - ": Reusing ldb opend by pid %d in " - "process %d\n", - ldb_kv->pid, - pid); - return LDB_ERR_PROTOCOL_ERROR; - } - - return tdb_transaction_prepare_commit(ldb_kv->tdb); -} - -static int ltdb_transaction_commit(struct ldb_kv_private *ldb_kv) -{ - pid_t pid = getpid(); - - if (ldb_kv->pid != pid) { - ldb_asprintf_errstring(ldb_module_get_ctx(ldb_kv->module), - __location__ - ": Reusing ldb opend by pid %d in " - "process %d\n", - ldb_kv->pid, - pid); - return LDB_ERR_PROTOCOL_ERROR; - } - - return tdb_transaction_commit(ldb_kv->tdb); -} -struct kv_ctx { - ldb_kv_traverse_fn kv_traverse_fn; - void *ctx; - struct ldb_kv_private *ldb_kv; - int (*parser)(struct ldb_val key, - struct ldb_val data, - void *private_data); - int parser_ret; -}; - -static int ltdb_traverse_fn_wrapper(struct tdb_context *tdb, - TDB_DATA tdb_key, - TDB_DATA tdb_data, - void *ctx) -{ - struct kv_ctx *kv_ctx = ctx; - struct ldb_val key = { - .length = tdb_key.dsize, - .data = tdb_key.dptr, - }; - struct ldb_val data = { - .length = tdb_data.dsize, - .data = tdb_data.dptr, - }; - return kv_ctx->kv_traverse_fn(kv_ctx->ldb_kv, key, data, kv_ctx->ctx); -} - -static int ltdb_traverse_fn(struct ldb_kv_private *ldb_kv, - ldb_kv_traverse_fn fn, - void *ctx) -{ - struct kv_ctx kv_ctx = { - .kv_traverse_fn = fn, .ctx = ctx, .ldb_kv = ldb_kv}; - if (tdb_transaction_active(ldb_kv->tdb)) { - return tdb_traverse( - ldb_kv->tdb, ltdb_traverse_fn_wrapper, &kv_ctx); - } else { - return tdb_traverse_read( - ldb_kv->tdb, ltdb_traverse_fn_wrapper, &kv_ctx); - } -} - -static int ltdb_update_in_iterate(struct ldb_kv_private *ldb_kv, - struct ldb_val ldb_key, - struct ldb_val ldb_key2, - struct ldb_val ldb_data, - void *state) -{ - int tdb_ret; - struct ldb_context *ldb; - struct ldb_kv_reindex_context *ctx = - (struct ldb_kv_reindex_context *)state; - struct ldb_module *module = ldb_kv->module; - TDB_DATA key = { - .dptr = ldb_key.data, - .dsize = ldb_key.length - }; - TDB_DATA key2 = { - .dptr = ldb_key2.data, - .dsize = ldb_key2.length - }; - TDB_DATA data = { - .dptr = ldb_data.data, - .dsize = ldb_data.length - }; - - ldb = ldb_module_get_ctx(module); - - tdb_ret = tdb_delete(ldb_kv->tdb, key); - if (tdb_ret != 0) { - ldb_debug(ldb, - LDB_DEBUG_ERROR, - "Failed to delete %*.*s " - "for rekey as %*.*s: %s", - (int)key.dsize, - (int)key.dsize, - (const char *)key.dptr, - (int)key2.dsize, - (int)key2.dsize, - (const char *)key.dptr, - tdb_errorstr(ldb_kv->tdb)); - ctx->error = ltdb_err_map(tdb_error(ldb_kv->tdb)); - return -1; - } - tdb_ret = tdb_store(ldb_kv->tdb, key2, data, 0); - if (tdb_ret != 0) { - ldb_debug(ldb, - LDB_DEBUG_ERROR, - "Failed to rekey %*.*s as %*.*s: %s", - (int)key.dsize, - (int)key.dsize, - (const char *)key.dptr, - (int)key2.dsize, - (int)key2.dsize, - (const char *)key.dptr, - tdb_errorstr(ldb_kv->tdb)); - ctx->error = ltdb_err_map(tdb_error(ldb_kv->tdb)); - return -1; - } - return tdb_ret; -} - -static int ltdb_parse_record_wrapper(TDB_DATA tdb_key, - TDB_DATA tdb_data, - void *ctx) -{ - struct kv_ctx *kv_ctx = ctx; - struct ldb_val key = { - .length = tdb_key.dsize, - .data = tdb_key.dptr, - }; - struct ldb_val data = { - .length = tdb_data.dsize, - .data = tdb_data.dptr, - }; - - kv_ctx->parser_ret = kv_ctx->parser(key, data, kv_ctx->ctx); - return kv_ctx->parser_ret; -} - -static int ltdb_parse_record(struct ldb_kv_private *ldb_kv, - struct ldb_val ldb_key, - int (*parser)(struct ldb_val key, - struct ldb_val data, - void *private_data), - void *ctx) -{ - struct kv_ctx kv_ctx = {.parser = parser, .ctx = ctx, .ldb_kv = ldb_kv}; - TDB_DATA key = { - .dptr = ldb_key.data, - .dsize = ldb_key.length - }; - int ret; - - if (tdb_transaction_active(ldb_kv->tdb) == false && - ldb_kv->read_lock_count == 0) { - return LDB_ERR_PROTOCOL_ERROR; - } - - ret = tdb_parse_record( - ldb_kv->tdb, key, ltdb_parse_record_wrapper, &kv_ctx); - if (kv_ctx.parser_ret != LDB_SUCCESS) { - return kv_ctx.parser_ret; - } else if (ret == 0) { - return LDB_SUCCESS; - } - return ltdb_err_map(tdb_error(ldb_kv->tdb)); -} - -static int ltdb_iterate_range(struct ldb_kv_private *ldb_kv, - struct ldb_val start_key, - struct ldb_val end_key, - ldb_kv_traverse_fn fn, - void *ctx) -{ - /* - * We do not implement this operation because we do not know how to - * iterate from one key to the next (in a sorted fashion). - * - * We could mimic it potentially, but it would violate boundaries of - * knowledge (data type representation). - */ - return LDB_ERR_OPERATIONS_ERROR; -} - -static const char *ltdb_name(struct ldb_kv_private *ldb_kv) -{ - return tdb_name(ldb_kv->tdb); -} - -static bool ltdb_changed(struct ldb_kv_private *ldb_kv) -{ - int seq = tdb_get_seqnum(ldb_kv->tdb); - bool has_changed = (seq != ldb_kv->tdb_seqnum); - - ldb_kv->tdb_seqnum = seq; - - return has_changed; -} - -static bool ltdb_transaction_active(struct ldb_kv_private *ldb_kv) -{ - return tdb_transaction_active(ldb_kv->tdb); -} - -/* - * Get an estimate of the number of records in a tdb database. - * - * This implementation will overestimate the number of records in a sparsely - * populated database. The size estimate is only used for allocating - * an in memory tdb to cache index records during a reindex, overestimating - * the contents is acceptable, and preferable to underestimating - */ -#define RECORD_SIZE 500 -static size_t ltdb_get_size(struct ldb_kv_private *ldb_kv) -{ - size_t map_size = tdb_map_size(ldb_kv->tdb); - size_t size = map_size / RECORD_SIZE; - - return size; -} - -/* - * Start a sub transaction - * As TDB does not currently support nested transactions, we do nothing and - * return LDB_SUCCESS - */ -static int ltdb_nested_transaction_start(struct ldb_kv_private *ldb_kv) -{ - return LDB_SUCCESS; -} - -/* - * Commit a sub transaction - * As TDB does not currently support nested transactions, we do nothing and - * return LDB_SUCCESS - */ -static int ltdb_nested_transaction_commit(struct ldb_kv_private *ldb_kv) -{ - return LDB_SUCCESS; -} - -/* - * Cancel a sub transaction - * As TDB does not currently support nested transactions, we do nothing and - * return LDB_SUCCESS - */ -static int ltdb_nested_transaction_cancel(struct ldb_kv_private *ldb_kv) -{ - return LDB_SUCCESS; -} - -static const struct kv_db_ops key_value_ops = { - /* No support for any additional features */ - .options = 0, - - .store = ltdb_store, - .delete = ltdb_delete, - .iterate = ltdb_traverse_fn, - .update_in_iterate = ltdb_update_in_iterate, - .fetch_and_parse = ltdb_parse_record, - .iterate_range = ltdb_iterate_range, - .lock_read = ltdb_lock_read, - .unlock_read = ltdb_unlock_read, - .begin_write = ltdb_transaction_start, - .prepare_write = ltdb_transaction_prepare_commit, - .finish_write = ltdb_transaction_commit, - .abort_write = ltdb_transaction_cancel, - .error = ltdb_error, - .errorstr = ltdb_errorstr, - .name = ltdb_name, - .has_changed = ltdb_changed, - .transaction_active = ltdb_transaction_active, - .get_size = ltdb_get_size, - .begin_nested_write = ltdb_nested_transaction_start, - .finish_nested_write = ltdb_nested_transaction_commit, - .abort_nested_write = ltdb_nested_transaction_cancel, -}; - -/* - connect to the database -*/ -int ltdb_connect(struct ldb_context *ldb, const char *url, - unsigned int flags, const char *options[], - struct ldb_module **_module) -{ - const char *path; - int tdb_flags, open_flags; - struct ldb_kv_private *ldb_kv; - - /* - * We hold locks, so we must use a private event context - * on each returned handle - */ - ldb_set_require_private_event_context(ldb); - - /* parse the url */ - if (strchr(url, ':')) { - if (strncmp(url, "tdb://", 6) != 0) { - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Invalid tdb URL '%s'", url); - return LDB_ERR_OPERATIONS_ERROR; - } - path = url+6; - } else { - path = url; - } - - tdb_flags = TDB_DEFAULT | TDB_SEQNUM | TDB_DISALLOW_NESTING; - - /* check for the 'nosync' option */ - if (flags & LDB_FLG_NOSYNC) { - tdb_flags |= TDB_NOSYNC; - } - - /* and nommap option */ - if (flags & LDB_FLG_NOMMAP) { - tdb_flags |= TDB_NOMMAP; - } - - ldb_kv = talloc_zero(ldb, struct ldb_kv_private); - if (!ldb_kv) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - if (flags & LDB_FLG_RDONLY) { - /* - * This is weird, but because we can only have one tdb - * in this process, and the other one could be - * read-write, we can't use the tdb readonly. Plus a - * read only tdb prohibits the all-record lock. - */ - open_flags = O_RDWR; - - ldb_kv->read_only = true; - - } else if (flags & LDB_FLG_DONT_CREATE_DB) { - /* - * This is used by ldbsearch to prevent creation of the database - * if the name is wrong - */ - open_flags = O_RDWR; - } else { - /* - * This is the normal case - */ - open_flags = O_CREAT | O_RDWR; - } - - ldb_kv->kv_ops = &key_value_ops; - - errno = 0; - /* note that we use quite a large default hash size */ - ldb_kv->tdb = ltdb_wrap_open(ldb_kv, - path, - 10000, - tdb_flags, - open_flags, - ldb_get_create_perms(ldb), - ldb); - if (!ldb_kv->tdb) { - ldb_asprintf_errstring(ldb, - "Unable to open tdb '%s': %s", path, strerror(errno)); - ldb_debug(ldb, LDB_DEBUG_ERROR, - "Unable to open tdb '%s': %s", path, strerror(errno)); - talloc_free(ldb_kv); - if (errno == EACCES || errno == EPERM) { - return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; - } - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_kv_init_store( - ldb_kv, "ldb_tdb backend", ldb, options, _module); -} diff --git a/ldb-2.0.8/ldb_tdb/ldb_tdb.h b/ldb-2.0.8/ldb_tdb/ldb_tdb.h deleted file mode 100644 index 5395d42..0000000 --- a/ldb-2.0.8/ldb_tdb/ldb_tdb.h +++ /dev/null @@ -1,16 +0,0 @@ -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "tdb.h" -#include "ldb_module.h" - -TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn); -int ltdb_err_map(enum TDB_ERROR tdb_code); - -struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, - const char *path, int hash_size, int tdb_flags, - int open_flags, mode_t mode, - struct ldb_context *ldb); -int ltdb_connect(struct ldb_context *ldb, const char *url, - unsigned int flags, const char *options[], - struct ldb_module **_module); diff --git a/ldb-2.0.8/ldb_tdb/ldb_tdb_err_map.c b/ldb-2.0.8/ldb_tdb/ldb_tdb_err_map.c deleted file mode 100644 index 41e5318..0000000 --- a/ldb-2.0.8/ldb_tdb/ldb_tdb_err_map.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 2006-2008 - Copyright (C) Matthias Dieter Wallnöfer 2009-2010 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb_tdb - * - * Component: ldb tdb backend - * - * Description: core functions for tdb backend - * - * Author: Andrew Tridgell - * Author: Stefan Metzmacher - * - * Modifications: - * - * - description: make the module use asynchronous calls - * date: Feb 2006 - * Author: Simo Sorce - * - * - description: make it possible to use event contexts - * date: Jan 2008 - * Author: Simo Sorce - * - * - description: fix up memory leaks and small bugs - * date: Oct 2009 - * Author: Matthias Dieter Wallnöfer - */ - -#include "ldb_tdb.h" -#include - -/* - map a tdb error code to a ldb error code -*/ -int ltdb_err_map(enum TDB_ERROR tdb_code) -{ - switch (tdb_code) { - case TDB_SUCCESS: - return LDB_SUCCESS; - case TDB_ERR_CORRUPT: - case TDB_ERR_OOM: - case TDB_ERR_EINVAL: - return LDB_ERR_OPERATIONS_ERROR; - case TDB_ERR_IO: - return LDB_ERR_PROTOCOL_ERROR; - case TDB_ERR_LOCK: - case TDB_ERR_NOLOCK: - return LDB_ERR_BUSY; - case TDB_ERR_LOCK_TIMEOUT: - return LDB_ERR_TIME_LIMIT_EXCEEDED; - case TDB_ERR_EXISTS: - return LDB_ERR_ENTRY_ALREADY_EXISTS; - case TDB_ERR_NOEXIST: - return LDB_ERR_NO_SUCH_OBJECT; - case TDB_ERR_RDONLY: - return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS; - default: - break; - } - return LDB_ERR_OTHER; -} diff --git a/ldb-2.0.8/ldb_tdb/ldb_tdb_init.c b/ldb-2.0.8/ldb_tdb/ldb_tdb_init.c deleted file mode 100644 index b18c98a..0000000 --- a/ldb-2.0.8/ldb_tdb/ldb_tdb_init.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 2006-2008 - Copyright (C) Matthias Dieter Wallnöfer 2009-2010 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb_tdb - * - * Component: ldb tdb backend - * - * Description: core functions for tdb backend - * - * Author: Andrew Tridgell - * Author: Stefan Metzmacher - * - * Modifications: - * - * - description: make the module use asynchronous calls - * date: Feb 2006 - * Author: Simo Sorce - * - * - description: make it possible to use event contexts - * date: Jan 2008 - * Author: Simo Sorce - * - * - description: fix up memory leaks and small bugs - * date: Oct 2009 - * Author: Matthias Dieter Wallnöfer - */ - -#include "ldb_tdb.h" -#include "ldb_private.h" - -int ldb_tdb_init(const char *version) -{ - LDB_MODULE_CHECK_VERSION(version); - return ldb_register_backend("tdb", ltdb_connect, false); -} diff --git a/ldb-2.0.8/ldb_tdb/ldb_tdb_wrap.c b/ldb-2.0.8/ldb_tdb/ldb_tdb_wrap.c deleted file mode 100644 index bc702a2..0000000 --- a/ldb-2.0.8/ldb_tdb/ldb_tdb_wrap.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "ldb_tdb.h" -#include "dlinklist.h" - -static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); -static void ltdb_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) -{ - va_list ap; - const char *name = tdb_name(tdb); - struct ldb_context *ldb = talloc_get_type(tdb_get_logging_private(tdb), struct ldb_context); - enum ldb_debug_level ldb_level; - char *message; - - if (ldb == NULL) - return; - - va_start(ap, fmt); - message = talloc_vasprintf(ldb, fmt, ap); - va_end(ap); - - switch (level) { - case TDB_DEBUG_FATAL: - ldb_level = LDB_DEBUG_FATAL; - break; - case TDB_DEBUG_ERROR: - ldb_level = LDB_DEBUG_ERROR; - break; - case TDB_DEBUG_WARNING: - ldb_level = LDB_DEBUG_WARNING; - break; - case TDB_DEBUG_TRACE: - ldb_level = LDB_DEBUG_TRACE; - break; - default: - ldb_level = LDB_DEBUG_FATAL; - } - - ldb_debug(ldb, ldb_level, "ltdb: tdb(%s): %s", name, message); - talloc_free(message); -} - -/* - the purpose of this code is to work around the braindead posix locking - rules, to allow us to have a ldb open more than once while allowing - locking to work - - TDB2 handles multiple opens, so we don't have this problem there. -*/ - -struct ltdb_wrap { - struct ltdb_wrap *next, *prev; - struct tdb_context *tdb; - dev_t device; - ino_t inode; - pid_t pid; -}; - -static struct ltdb_wrap *tdb_list; - -/* destroy the last connection to a tdb */ -static int ltdb_wrap_destructor(struct ltdb_wrap *w) -{ - tdb_close(w->tdb); - DLIST_REMOVE(tdb_list, w); - return 0; -} - -/* - wrapped connection to a tdb database. The caller should _not_ free - this as it is not a talloc structure (as tdb does not use talloc - yet). It will auto-close when the caller frees the mem_ctx that is - passed to this call - */ -struct tdb_context *ltdb_wrap_open(TALLOC_CTX *mem_ctx, - const char *path, int hash_size, - int tdb_flags, - int open_flags, mode_t mode, - struct ldb_context *ldb) -{ - struct ltdb_wrap *w; - struct tdb_logging_context lctx; - struct stat st; - - if (stat(path, &st) == 0) { - for (w=tdb_list;w;w=w->next) { - if (st.st_dev == w->device && st.st_ino == w->inode) { - pid_t pid = getpid(); - int ret; - if (!talloc_reference(mem_ctx, w)) { - return NULL; - } - if (w->pid != pid) { - ret = tdb_reopen(w->tdb); - if (ret != 0) { - /* - * Avoid use-after-free: - * on fail the TDB - * is closed! - */ - DLIST_REMOVE(tdb_list, - w); - return NULL; - } - w->pid = pid; - } - return w->tdb; - } - } - } - - w = talloc(mem_ctx, struct ltdb_wrap); - if (w == NULL) { - return NULL; - } - - lctx.log_fn = ltdb_log_fn; - lctx.log_private = ldb; - w->tdb = tdb_open_ex(path, hash_size, tdb_flags, open_flags, mode, - &lctx, NULL); - if (w->tdb == NULL) { - talloc_free(w); - return NULL; - } - - if (fstat(tdb_fd(w->tdb), &st) != 0) { - tdb_close(w->tdb); - talloc_free(w); - return NULL; - } - - w->device = st.st_dev; - w->inode = st.st_ino; - w->pid = getpid(); - - talloc_set_destructor(w, ltdb_wrap_destructor); - - DLIST_ADD(tdb_list, w); - - return w->tdb; -} diff --git a/ldb-2.0.8/lib/replace/.checker_innocent b/ldb-2.0.8/lib/replace/.checker_innocent deleted file mode 100644 index e619176..0000000 --- a/ldb-2.0.8/lib/replace/.checker_innocent +++ /dev/null @@ -1,4 +0,0 @@ ->>>MISTAKE21_create_files_6a9e68ada99a97cb ->>>MISTAKE21_os2_delete_9b2bfa7f38711d09 ->>>MISTAKE21_os2_delete_2fcc29aaa99a97cb ->>>SECURITY2_os2_delete_9b2bfa7f1c9396ca diff --git a/ldb-2.0.8/lib/replace/Makefile b/ldb-2.0.8/lib/replace/Makefile deleted file mode 100644 index a123a37..0000000 --- a/ldb-2.0.8/lib/replace/Makefile +++ /dev/null @@ -1,64 +0,0 @@ -# simple makefile wrapper to run waf - -WAF_BINARY=$(PYTHON) ../../buildtools/bin/waf -WAF=PYTHONHASHSEED=1 WAF_MAKE=1 $(WAF_BINARY) - -all: - $(WAF) build - -install: - $(WAF) install - -uninstall: - $(WAF) uninstall - -test: - $(WAF) test $(TEST_OPTIONS) - -testenv: - $(WAF) test --testenv $(TEST_OPTIONS) - -quicktest: - $(WAF) test --quick $(TEST_OPTIONS) - -dist: - touch .tmplock - WAFLOCK=.tmplock $(WAF) dist - -distcheck: - touch .tmplock - WAFLOCK=.tmplock $(WAF) distcheck - -clean: - $(WAF) clean - -distclean: - $(WAF) distclean - -reconfigure: configure - $(WAF) reconfigure - -show_waf_options: - $(WAF) --help - -# some compatibility make targets -everything: all - -testsuite: all - -check: test - -torture: all - -# this should do an install as well, once install is finished -installcheck: test - -etags: - $(WAF) etags - -ctags: - $(WAF) ctags - -bin/%:: FORCE - $(WAF) --targets=`basename $@` -FORCE: diff --git a/ldb-2.0.8/lib/replace/README b/ldb-2.0.8/lib/replace/README deleted file mode 100644 index 6612eab..0000000 --- a/ldb-2.0.8/lib/replace/README +++ /dev/null @@ -1,128 +0,0 @@ -This subsystem ensures that we can always use a certain core set of -functions and types, that are either provided by the OS or by replacement -functions / definitions in this subsystem. The aim is to try to stick -to POSIX functions in here as much as possible. Convenience functions -that are available on no platform at all belong in other subsystems -(such as LIBUTIL). - -The following functions are guaranteed: - -ftruncate -strlcpy -strlcat -mktime -rename -initgroups -memmove -strdup -setlinebuf -vsyslog -timegm -setenv -unsetenv -strndup -strnlen -waitpid -seteuid -setegid -asprintf -snprintf -vasprintf -vsnprintf -opendir -readdir -telldir -seekdir -clock_gettime -closedir -dlopen -dlclose -dlsym -dlerror -chroot -bzero -strerror -errno -mkdtemp -mkstemp (a secure one!) -pread -pwrite -chown -lchown -readline (the library) -inet_ntoa -inet_ntop -inet_pton -inet_aton -strtoll -strtoull -socketpair -strptime -getaddrinfo -freeaddrinfo -getnameinfo -gai_strerror -getifaddrs -freeifaddrs -utime -utimes -dup2 -link -readlink -symlink -realpath -poll -setproctitle -memset_s - -Types: -bool -socklen_t -uint{8,16,32,64}_t -int{8,16,32,64}_t -intptr_t -sig_atomic_t -blksize_t -blkcnt_t - -Constants: -PATH_NAME_MAX -UINT{16,32,64}_MAX -INT32_MAX -RTLD_LAZY -HOST_NAME_MAX -UINT16_MAX -UINT32_MAX -UINT64_MAX -CHAR_BIT - -Macros: -va_copy -__FUNCTION__ -__FILE__ -__LINE__ -__LINESTR__ -__location__ -__STRING -__STRINGSTRING -MIN -MAX -QSORT_CAST -ZERO_STRUCT -ZERO_STRUCTP -ZERO_STRUCTPN -ZERO_ARRAY -ARRAY_SIZE -PTR_DIFF - -Headers: -stdint.h -stdbool.h - -Optional C keywords: -volatile - -Prerequisites: -memset (for bzero) -syslog (for vsyslog) -mktemp (for mkstemp and mkdtemp) diff --git a/ldb-2.0.8/lib/replace/closefrom.c b/ldb-2.0.8/lib/replace/closefrom.c deleted file mode 100644 index a61a80f..0000000 --- a/ldb-2.0.8/lib/replace/closefrom.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * Samba utility functions - * Copyright (C) Volker Lendecke 2016 - * - * ** NOTE! The following LGPL license applies to the replace - * ** library. This does NOT imply that all of Samba is released - * ** under the LGPL - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - */ - -#include "replace.h" -#include -#include -#include - -static int closefrom_sysconf(int lower) -{ - long max_files, fd; - - max_files = sysconf(_SC_OPEN_MAX); - if (max_files == -1) { - max_files = 65536; - } - - for (fd=lower; fdd_name, &endptr, 10); - if ((fd == 0) && (errno == EINVAL)) { - continue; - } - if ((fd == ULLONG_MAX) && (errno == ERANGE)) { - continue; - } - if (*endptr != '\0') { - continue; - } - if (fd == dir_fd) { - continue; - } - if (fd > INT_MAX) { - continue; - } - if (fd < lower) { - continue; - } - - if (num_fds >= (fd_array_size / sizeof(int))) { - void *tmp; - - if (fd_array_size == 0) { - fd_array_size = 16 * sizeof(int); - } else { - if (fd_array_size + fd_array_size < - fd_array_size) { - /* overflow */ - goto fail; - } - fd_array_size = fd_array_size + fd_array_size; - } - - tmp = realloc(fds, fd_array_size); - if (tmp == NULL) { - goto fail; - } - fds = tmp; - } - - fds[num_fds++] = fd; - } - - for (i=0; i - that this crypt routine may sometimes get the wrong answer. Only - use UFC_CRYT if you really need it. - -*/ - -#include "replace.h" - -#ifndef HAVE_CRYPT - -/* - * UFC-crypt: ultra fast crypt(3) implementation - * - * Copyright (C) 1991-1998, Free Software Foundation, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - * - * @(#)crypt_util.c 2.31 02/08/92 - * - * Support routines - * - */ - - -#ifndef long32 -#define long32 int32_t -#endif - -#ifndef long64 -#define long64 int64_t -#endif - -#ifndef ufc_long -#define ufc_long unsigned -#endif - -#ifndef _UFC_64_ -#define _UFC_32_ -#endif - -/* - * Permutation done once on the 56 bit - * key derived from the original 8 byte ASCII key. - */ -static int pc1[56] = { - 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, - 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, - 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, - 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 -}; - -/* - * How much to rotate each 28 bit half of the pc1 permutated - * 56 bit key before using pc2 to give the i' key - */ -static int rots[16] = { - 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 -}; - -/* - * Permutation giving the key - * of the i' DES round - */ -static int pc2[48] = { - 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, - 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, - 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, - 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 -}; - -/* - * The E expansion table which selects - * bits from the 32 bit intermediate result. - */ -static int esel[48] = { - 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, - 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, - 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, - 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1 -}; -static int e_inverse[64]; - -/* - * Permutation done on the - * result of sbox lookups - */ -static int perm32[32] = { - 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, - 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 -}; - -/* - * The sboxes - */ -static int sbox[8][4][16]= { - { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 }, - { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 }, - { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 }, - { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 } - }, - - { { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 }, - { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 }, - { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 }, - { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 } - }, - - { { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 }, - { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 }, - { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 }, - { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 } - }, - - { { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 }, - { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 }, - { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 }, - { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 } - }, - - { { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 }, - { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 }, - { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 }, - { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 } - }, - - { { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 }, - { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 }, - { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 }, - { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 } - }, - - { { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 }, - { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 }, - { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 }, - { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 } - }, - - { { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 }, - { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 }, - { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 }, - { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } - } -}; - -/* - * This is the final - * permutation matrix - */ -static int final_perm[64] = { - 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, - 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, - 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, - 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25 -}; - -/* - * The 16 DES keys in BITMASK format - */ -#ifdef _UFC_32_ -long32 _ufc_keytab[16][2]; -#endif - -#ifdef _UFC_64_ -long64 _ufc_keytab[16]; -#endif - - -#define ascii_to_bin(c) ((c)>='a'?(c-59):(c)>='A'?((c)-53):(c)-'.') -#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.') - -/* Macro to set a bit (0..23) */ -#define BITMASK(i) ( (1<<(11-(i)%12+3)) << ((i)<12?16:0) ) - -/* - * sb arrays: - * - * Workhorses of the inner loop of the DES implementation. - * They do sbox lookup, shifting of this value, 32 bit - * permutation and E permutation for the next round. - * - * Kept in 'BITMASK' format. - */ - -#ifdef _UFC_32_ -long32 _ufc_sb0[8192], _ufc_sb1[8192], _ufc_sb2[8192], _ufc_sb3[8192]; -static long32 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3}; -#endif - -#ifdef _UFC_64_ -long64 _ufc_sb0[4096], _ufc_sb1[4096], _ufc_sb2[4096], _ufc_sb3[4096]; -static long64 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3}; -#endif - -/* - * eperm32tab: do 32 bit permutation and E selection - * - * The first index is the byte number in the 32 bit value to be permuted - * - second - is the value of this byte - * - third - selects the two 32 bit values - * - * The table is used and generated internally in init_des to speed it up - */ -static ufc_long eperm32tab[4][256][2]; - -/* - * do_pc1: permform pc1 permutation in the key schedule generation. - * - * The first index is the byte number in the 8 byte ASCII key - * - second - - the two 28 bits halfs of the result - * - third - selects the 7 bits actually used of each byte - * - * The result is kept with 28 bit per 32 bit with the 4 most significant - * bits zero. - */ -static ufc_long do_pc1[8][2][128]; - -/* - * do_pc2: permform pc2 permutation in the key schedule generation. - * - * The first index is the septet number in the two 28 bit intermediate values - * - second - - - septet values - * - * Knowledge of the structure of the pc2 permutation is used. - * - * The result is kept with 28 bit per 32 bit with the 4 most significant - * bits zero. - */ -static ufc_long do_pc2[8][128]; - -/* - * efp: undo an extra e selection and do final - * permutation giving the DES result. - * - * Invoked 6 bit a time on two 48 bit values - * giving two 32 bit longs. - */ -static ufc_long efp[16][64][2]; - -static unsigned char bytemask[8] = { - 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 -}; - -static ufc_long longmask[32] = { - 0x80000000, 0x40000000, 0x20000000, 0x10000000, - 0x08000000, 0x04000000, 0x02000000, 0x01000000, - 0x00800000, 0x00400000, 0x00200000, 0x00100000, - 0x00080000, 0x00040000, 0x00020000, 0x00010000, - 0x00008000, 0x00004000, 0x00002000, 0x00001000, - 0x00000800, 0x00000400, 0x00000200, 0x00000100, - 0x00000080, 0x00000040, 0x00000020, 0x00000010, - 0x00000008, 0x00000004, 0x00000002, 0x00000001 -}; - - -/* - * Silly rewrite of 'bzero'. I do so - * because some machines don't have - * bzero and some don't have memset. - */ - -static void clearmem(char *start, int cnt) - { while(cnt--) - *start++ = '\0'; - } - -static int initialized = 0; - -/* lookup a 6 bit value in sbox */ - -#define s_lookup(i,s) sbox[(i)][(((s)>>4) & 0x2)|((s) & 0x1)][((s)>>1) & 0xf]; - -/* - * Initialize unit - may be invoked directly - * by fcrypt users. - */ - -static void ufc_init_des(void) - { int comes_from_bit; - int bit, sg; - ufc_long j; - ufc_long mask1, mask2; - - /* - * Create the do_pc1 table used - * to affect pc1 permutation - * when generating keys - */ - for(bit = 0; bit < 56; bit++) { - comes_from_bit = pc1[bit] - 1; - mask1 = bytemask[comes_from_bit % 8 + 1]; - mask2 = longmask[bit % 28 + 4]; - for(j = 0; j < 128; j++) { - if(j & mask1) - do_pc1[comes_from_bit / 8][bit / 28][j] |= mask2; - } - } - - /* - * Create the do_pc2 table used - * to affect pc2 permutation when - * generating keys - */ - for(bit = 0; bit < 48; bit++) { - comes_from_bit = pc2[bit] - 1; - mask1 = bytemask[comes_from_bit % 7 + 1]; - mask2 = BITMASK(bit % 24); - for(j = 0; j < 128; j++) { - if(j & mask1) - do_pc2[comes_from_bit / 7][j] |= mask2; - } - } - - /* - * Now generate the table used to do combined - * 32 bit permutation and e expansion - * - * We use it because we have to permute 16384 32 bit - * longs into 48 bit in order to initialize sb. - * - * Looping 48 rounds per permutation becomes - * just too slow... - * - */ - - clearmem((char*)eperm32tab, sizeof(eperm32tab)); - - for(bit = 0; bit < 48; bit++) { - ufc_long inner_mask1,comes_from; - - comes_from = perm32[esel[bit]-1]-1; - inner_mask1 = bytemask[comes_from % 8]; - - for(j = 256; j--;) { - if(j & inner_mask1) - eperm32tab[comes_from / 8][j][bit / 24] |= BITMASK(bit % 24); - } - } - - /* - * Create the sb tables: - * - * For each 12 bit segment of an 48 bit intermediate - * result, the sb table precomputes the two 4 bit - * values of the sbox lookups done with the two 6 - * bit halves, shifts them to their proper place, - * sends them through perm32 and finally E expands - * them so that they are ready for the next - * DES round. - * - */ - for(sg = 0; sg < 4; sg++) { - int j1, j2; - int s1, s2; - - for(j1 = 0; j1 < 64; j1++) { - s1 = s_lookup(2 * sg, j1); - for(j2 = 0; j2 < 64; j2++) { - ufc_long to_permute, inx; - - s2 = s_lookup(2 * sg + 1, j2); - to_permute = ((s1 << 4) | s2) << (24 - 8 * sg); - -#ifdef _UFC_32_ - inx = ((j1 << 6) | j2) << 1; - sb[sg][inx ] = eperm32tab[0][(to_permute >> 24) & 0xff][0]; - sb[sg][inx+1] = eperm32tab[0][(to_permute >> 24) & 0xff][1]; - sb[sg][inx ] |= eperm32tab[1][(to_permute >> 16) & 0xff][0]; - sb[sg][inx+1] |= eperm32tab[1][(to_permute >> 16) & 0xff][1]; - sb[sg][inx ] |= eperm32tab[2][(to_permute >> 8) & 0xff][0]; - sb[sg][inx+1] |= eperm32tab[2][(to_permute >> 8) & 0xff][1]; - sb[sg][inx ] |= eperm32tab[3][(to_permute) & 0xff][0]; - sb[sg][inx+1] |= eperm32tab[3][(to_permute) & 0xff][1]; -#endif -#ifdef _UFC_64_ - inx = ((j1 << 6) | j2); - sb[sg][inx] = - ((long64)eperm32tab[0][(to_permute >> 24) & 0xff][0] << 32) | - (long64)eperm32tab[0][(to_permute >> 24) & 0xff][1]; - sb[sg][inx] |= - ((long64)eperm32tab[1][(to_permute >> 16) & 0xff][0] << 32) | - (long64)eperm32tab[1][(to_permute >> 16) & 0xff][1]; - sb[sg][inx] |= - ((long64)eperm32tab[2][(to_permute >> 8) & 0xff][0] << 32) | - (long64)eperm32tab[2][(to_permute >> 8) & 0xff][1]; - sb[sg][inx] |= - ((long64)eperm32tab[3][(to_permute) & 0xff][0] << 32) | - (long64)eperm32tab[3][(to_permute) & 0xff][1]; -#endif - } - } - } - - /* - * Create an inverse matrix for esel telling - * where to plug out bits if undoing it - */ - for(bit=48; bit--;) { - e_inverse[esel[bit] - 1 ] = bit; - e_inverse[esel[bit] - 1 + 32] = bit + 48; - } - - /* - * create efp: the matrix used to - * undo the E expansion and effect final permutation - */ - clearmem((char*)efp, sizeof efp); - for(bit = 0; bit < 64; bit++) { - int o_bit, o_long; - ufc_long word_value, inner_mask1, inner_mask2; - int comes_from_f_bit, comes_from_e_bit; - int comes_from_word, bit_within_word; - - /* See where bit i belongs in the two 32 bit long's */ - o_long = bit / 32; /* 0..1 */ - o_bit = bit % 32; /* 0..31 */ - - /* - * And find a bit in the e permutated value setting this bit. - * - * Note: the e selection may have selected the same bit several - * times. By the initialization of e_inverse, we only look - * for one specific instance. - */ - comes_from_f_bit = final_perm[bit] - 1; /* 0..63 */ - comes_from_e_bit = e_inverse[comes_from_f_bit]; /* 0..95 */ - comes_from_word = comes_from_e_bit / 6; /* 0..15 */ - bit_within_word = comes_from_e_bit % 6; /* 0..5 */ - - inner_mask1 = longmask[bit_within_word + 26]; - inner_mask2 = longmask[o_bit]; - - for(word_value = 64; word_value--;) { - if(word_value & inner_mask1) - efp[comes_from_word][word_value][o_long] |= inner_mask2; - } - } - initialized++; - } - -/* - * Process the elements of the sb table permuting the - * bits swapped in the expansion by the current salt. - */ - -#ifdef _UFC_32_ -static void shuffle_sb(long32 *k, ufc_long saltbits) - { ufc_long j; - long32 x; - for(j=4096; j--;) { - x = (k[0] ^ k[1]) & (long32)saltbits; - *k++ ^= x; - *k++ ^= x; - } - } -#endif - -#ifdef _UFC_64_ -static void shuffle_sb(long64 *k, ufc_long saltbits) - { ufc_long j; - long64 x; - for(j=4096; j--;) { - x = ((*k >> 32) ^ *k) & (long64)saltbits; - *k++ ^= (x << 32) | x; - } - } -#endif - -/* - * Setup the unit for a new salt - * Hopefully we'll not see a new salt in each crypt call. - */ - -static unsigned char current_salt[3] = "&&"; /* invalid value */ -static ufc_long current_saltbits = 0; -static int direction = 0; - -static void setup_salt(const char *s1) - { ufc_long i, j, saltbits; - const unsigned char *s2 = (const unsigned char *)s1; - - if(!initialized) - ufc_init_des(); - - if(s2[0] == current_salt[0] && s2[1] == current_salt[1]) - return; - current_salt[0] = s2[0]; current_salt[1] = s2[1]; - - /* - * This is the only crypt change to DES: - * entries are swapped in the expansion table - * according to the bits set in the salt. - */ - saltbits = 0; - for(i = 0; i < 2; i++) { - long c=ascii_to_bin(s2[i]); - if(c < 0 || c > 63) - c = 0; - for(j = 0; j < 6; j++) { - if((c >> j) & 0x1) - saltbits |= BITMASK(6 * i + j); - } - } - - /* - * Permute the sb table values - * to reflect the changed e - * selection table - */ - shuffle_sb(_ufc_sb0, current_saltbits ^ saltbits); - shuffle_sb(_ufc_sb1, current_saltbits ^ saltbits); - shuffle_sb(_ufc_sb2, current_saltbits ^ saltbits); - shuffle_sb(_ufc_sb3, current_saltbits ^ saltbits); - - current_saltbits = saltbits; - } - -static void ufc_mk_keytab(char *key) - { ufc_long v1, v2, *k1; - int i; -#ifdef _UFC_32_ - long32 v, *k2 = &_ufc_keytab[0][0]; -#endif -#ifdef _UFC_64_ - long64 v, *k2 = &_ufc_keytab[0]; -#endif - - v1 = v2 = 0; k1 = &do_pc1[0][0][0]; - for(i = 8; i--;) { - v1 |= k1[*key & 0x7f]; k1 += 128; - v2 |= k1[*key++ & 0x7f]; k1 += 128; - } - - for(i = 0; i < 16; i++) { - k1 = &do_pc2[0][0]; - - v1 = (v1 << rots[i]) | (v1 >> (28 - rots[i])); - v = k1[(v1 >> 21) & 0x7f]; k1 += 128; - v |= k1[(v1 >> 14) & 0x7f]; k1 += 128; - v |= k1[(v1 >> 7) & 0x7f]; k1 += 128; - v |= k1[(v1 ) & 0x7f]; k1 += 128; - -#ifdef _UFC_32_ - *k2++ = v; - v = 0; -#endif -#ifdef _UFC_64_ - v <<= 32; -#endif - - v2 = (v2 << rots[i]) | (v2 >> (28 - rots[i])); - v |= k1[(v2 >> 21) & 0x7f]; k1 += 128; - v |= k1[(v2 >> 14) & 0x7f]; k1 += 128; - v |= k1[(v2 >> 7) & 0x7f]; k1 += 128; - v |= k1[(v2 ) & 0x7f]; - - *k2++ = v; - } - - direction = 0; - } - -/* - * Undo an extra E selection and do final permutations - */ - -ufc_long *_ufc_dofinalperm(ufc_long l1, ufc_long l2, ufc_long r1, ufc_long r2) - { ufc_long v1, v2, x; - static ufc_long ary[2]; - - x = (l1 ^ l2) & current_saltbits; l1 ^= x; l2 ^= x; - x = (r1 ^ r2) & current_saltbits; r1 ^= x; r2 ^= x; - - v1=v2=0; l1 >>= 3; l2 >>= 3; r1 >>= 3; r2 >>= 3; - - v1 |= efp[15][ r2 & 0x3f][0]; v2 |= efp[15][ r2 & 0x3f][1]; - v1 |= efp[14][(r2 >>= 6) & 0x3f][0]; v2 |= efp[14][ r2 & 0x3f][1]; - v1 |= efp[13][(r2 >>= 10) & 0x3f][0]; v2 |= efp[13][ r2 & 0x3f][1]; - v1 |= efp[12][(r2 >>= 6) & 0x3f][0]; v2 |= efp[12][ r2 & 0x3f][1]; - - v1 |= efp[11][ r1 & 0x3f][0]; v2 |= efp[11][ r1 & 0x3f][1]; - v1 |= efp[10][(r1 >>= 6) & 0x3f][0]; v2 |= efp[10][ r1 & 0x3f][1]; - v1 |= efp[ 9][(r1 >>= 10) & 0x3f][0]; v2 |= efp[ 9][ r1 & 0x3f][1]; - v1 |= efp[ 8][(r1 >>= 6) & 0x3f][0]; v2 |= efp[ 8][ r1 & 0x3f][1]; - - v1 |= efp[ 7][ l2 & 0x3f][0]; v2 |= efp[ 7][ l2 & 0x3f][1]; - v1 |= efp[ 6][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 6][ l2 & 0x3f][1]; - v1 |= efp[ 5][(l2 >>= 10) & 0x3f][0]; v2 |= efp[ 5][ l2 & 0x3f][1]; - v1 |= efp[ 4][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 4][ l2 & 0x3f][1]; - - v1 |= efp[ 3][ l1 & 0x3f][0]; v2 |= efp[ 3][ l1 & 0x3f][1]; - v1 |= efp[ 2][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 2][ l1 & 0x3f][1]; - v1 |= efp[ 1][(l1 >>= 10) & 0x3f][0]; v2 |= efp[ 1][ l1 & 0x3f][1]; - v1 |= efp[ 0][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 0][ l1 & 0x3f][1]; - - ary[0] = v1; ary[1] = v2; - return ary; - } - -/* - * crypt only: convert from 64 bit to 11 bit ASCII - * prefixing with the salt - */ - -static char *output_conversion(ufc_long v1, ufc_long v2, const char *salt) - { static char outbuf[14]; - int i, s; - - outbuf[0] = salt[0]; - outbuf[1] = salt[1] ? salt[1] : salt[0]; - - for(i = 0; i < 5; i++) - outbuf[i + 2] = bin_to_ascii((v1 >> (26 - 6 * i)) & 0x3f); - - s = (v2 & 0xf) << 2; - v2 = (v2 >> 2) | ((v1 & 0x3) << 30); - - for(i = 5; i < 10; i++) - outbuf[i + 2] = bin_to_ascii((v2 >> (56 - 6 * i)) & 0x3f); - - outbuf[12] = bin_to_ascii(s); - outbuf[13] = 0; - - return outbuf; - } - -/* - * UNIX crypt function - */ - -static ufc_long *_ufc_doit(ufc_long , ufc_long, ufc_long, ufc_long, ufc_long); - -char *ufc_crypt(const char *key,const char *salt) - { ufc_long *s; - char ktab[9]; - - /* - * Hack DES tables according to salt - */ - setup_salt(salt); - - /* - * Setup key schedule - */ - clearmem(ktab, sizeof ktab); - strncpy(ktab, key, 8); - ufc_mk_keytab(ktab); - - /* - * Go for the 25 DES encryptions - */ - s = _ufc_doit((ufc_long)0, (ufc_long)0, - (ufc_long)0, (ufc_long)0, (ufc_long)25); - - /* - * And convert back to 6 bit ASCII - */ - return output_conversion(s[0], s[1], salt); - } - - -#ifdef _UFC_32_ - -/* - * 32 bit version - */ - -extern long32 _ufc_keytab[16][2]; -extern long32 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[]; - -#define SBA(sb, v) (*(long32*)((char*)(sb)+(v))) - -static ufc_long *_ufc_doit(ufc_long l1, ufc_long l2, ufc_long r1, ufc_long r2, ufc_long itr) - { int i; - long32 s, *k; - - while(itr--) { - k = &_ufc_keytab[0][0]; - for(i=8; i--; ) { - s = *k++ ^ r1; - l1 ^= SBA(_ufc_sb1, s & 0xffff); l2 ^= SBA(_ufc_sb1, (s & 0xffff)+4); - l1 ^= SBA(_ufc_sb0, s >>= 16); l2 ^= SBA(_ufc_sb0, (s) +4); - s = *k++ ^ r2; - l1 ^= SBA(_ufc_sb3, s & 0xffff); l2 ^= SBA(_ufc_sb3, (s & 0xffff)+4); - l1 ^= SBA(_ufc_sb2, s >>= 16); l2 ^= SBA(_ufc_sb2, (s) +4); - - s = *k++ ^ l1; - r1 ^= SBA(_ufc_sb1, s & 0xffff); r2 ^= SBA(_ufc_sb1, (s & 0xffff)+4); - r1 ^= SBA(_ufc_sb0, s >>= 16); r2 ^= SBA(_ufc_sb0, (s) +4); - s = *k++ ^ l2; - r1 ^= SBA(_ufc_sb3, s & 0xffff); r2 ^= SBA(_ufc_sb3, (s & 0xffff)+4); - r1 ^= SBA(_ufc_sb2, s >>= 16); r2 ^= SBA(_ufc_sb2, (s) +4); - } - s=l1; l1=r1; r1=s; s=l2; l2=r2; r2=s; - } - return _ufc_dofinalperm(l1, l2, r1, r2); - } - -#endif - -#ifdef _UFC_64_ - -/* - * 64 bit version - */ - -extern long64 _ufc_keytab[16]; -extern long64 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[]; - -#define SBA(sb, v) (*(long64*)((char*)(sb)+(v))) - -static ufc_long *_ufc_doit(ufc_long l1, ufc_long l2, ufc_long r1, ufc_long r2, ufc_long itr) - { int i; - long64 l, r, s, *k; - - l = (((long64)l1) << 32) | ((long64)l2); - r = (((long64)r1) << 32) | ((long64)r2); - - while(itr--) { - k = &_ufc_keytab[0]; - for(i=8; i--; ) { - s = *k++ ^ r; - l ^= SBA(_ufc_sb3, (s >> 0) & 0xffff); - l ^= SBA(_ufc_sb2, (s >> 16) & 0xffff); - l ^= SBA(_ufc_sb1, (s >> 32) & 0xffff); - l ^= SBA(_ufc_sb0, (s >> 48) & 0xffff); - - s = *k++ ^ l; - r ^= SBA(_ufc_sb3, (s >> 0) & 0xffff); - r ^= SBA(_ufc_sb2, (s >> 16) & 0xffff); - r ^= SBA(_ufc_sb1, (s >> 32) & 0xffff); - r ^= SBA(_ufc_sb0, (s >> 48) & 0xffff); - } - s=l; l=r; r=s; - } - - l1 = l >> 32; l2 = l & 0xffffffff; - r1 = r >> 32; r2 = r & 0xffffffff; - return _ufc_dofinalperm(l1, l2, r1, r2); - } - -#endif - - -#else - int ufc_dummy_procedure(void); - int ufc_dummy_procedure(void) {return 0;} -#endif diff --git a/ldb-2.0.8/lib/replace/cwrap.c b/ldb-2.0.8/lib/replace/cwrap.c deleted file mode 100644 index adc5c1e..0000000 --- a/ldb-2.0.8/lib/replace/cwrap.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * Replaceable functions by cwrap - * - * Copyright (c) 2014 Andreas Schneider - * - * ** NOTE! The following LGPL license applies to the replace - * ** library. This does NOT imply that all of Samba is released - * ** under the LGPL - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - */ - -#include "replace.h" - -bool nss_wrapper_enabled(void) -{ - return false; -} - -bool nss_wrapper_hosts_enabled(void) -{ - return false; -} - -bool socket_wrapper_enabled(void) -{ - return false; -} - -bool uid_wrapper_enabled(void) -{ - return false; -} diff --git a/ldb-2.0.8/lib/replace/dlfcn.c b/ldb-2.0.8/lib/replace/dlfcn.c deleted file mode 100644 index 88431ed..0000000 --- a/ldb-2.0.8/lib/replace/dlfcn.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba system utilities - Copyright (C) Andrew Tridgell 1992-1998 - Copyright (C) Jeremy Allison 1998-2002 - Copyright (C) Jelmer Vernooij 2006 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#ifdef HAVE_DL_H -#include -#endif - -#ifndef HAVE_DLOPEN -#ifdef DLOPEN_TAKES_UNSIGNED_FLAGS -void *rep_dlopen(const char *name, unsigned int flags) -#else -void *rep_dlopen(const char *name, int flags) -#endif -{ -#ifdef HAVE_SHL_LOAD - if (name == NULL) - return PROG_HANDLE; - return (void *)shl_load(name, flags, 0); -#else - return NULL; -#endif -} -#endif - -#ifndef HAVE_DLSYM -void *rep_dlsym(void *handle, const char *symbol) -{ -#ifdef HAVE_SHL_FINDSYM - void *sym_addr; - if (!shl_findsym((shl_t *)&handle, symbol, TYPE_UNDEFINED, &sym_addr)) - return sym_addr; -#endif - return NULL; -} -#endif - -#ifndef HAVE_DLERROR -char *rep_dlerror(void) -{ - return "dynamic loading of objects not supported on this platform"; -} -#endif - -#ifndef HAVE_DLCLOSE -int rep_dlclose(void *handle) -{ -#ifdef HAVE_SHL_CLOSE - return shl_unload((shl_t)handle); -#else - return 0; -#endif -} -#endif diff --git a/ldb-2.0.8/lib/replace/getaddrinfo.c b/ldb-2.0.8/lib/replace/getaddrinfo.c deleted file mode 100644 index 8440d8e..0000000 --- a/ldb-2.0.8/lib/replace/getaddrinfo.c +++ /dev/null @@ -1,493 +0,0 @@ -/* -PostgreSQL Database Management System -(formerly known as Postgres, then as Postgres95) - -Portions Copyright (c) 1996-2005, The PostgreSQL Global Development Group - -Portions Copyright (c) 1994, The Regents of the University of California - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose, without fee, and without a written agreement -is hereby granted, provided that the above copyright notice and this paragraph -and the following two paragraphs appear in all copies. - -IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR -DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING -LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, -EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. - -THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS -TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - -*/ - -/*------------------------------------------------------------------------- - * - * getaddrinfo.c - * Support getaddrinfo() on platforms that don't have it. - * - * We also supply getnameinfo() here, assuming that the platform will have - * it if and only if it has getaddrinfo(). If this proves false on some - * platform, we'll need to split this file and provide a separate configure - * test for getnameinfo(). - * - * Copyright (c) 2003-2007, PostgreSQL Global Development Group - * - * Copyright (C) 2007 Jeremy Allison. - * Modified to return multiple IPv4 addresses for Samba. - * - *------------------------------------------------------------------------- - */ - -#include "replace.h" -#include "system/network.h" - -#ifndef SMB_MALLOC -#define SMB_MALLOC(s) malloc(s) -#endif - -#ifndef SMB_STRDUP -#define SMB_STRDUP(s) strdup(s) -#endif - -static int check_hostent_err(struct hostent *hp) -{ - if (!hp) { - switch (h_errno) { - case HOST_NOT_FOUND: - case NO_DATA: - return EAI_NONAME; - case TRY_AGAIN: - return EAI_AGAIN; - case NO_RECOVERY: - default: - return EAI_FAIL; - } - } - if (!hp->h_name || hp->h_addrtype != AF_INET) { - return EAI_FAIL; - } - return 0; -} - -static char *canon_name_from_hostent(struct hostent *hp, - int *perr) -{ - char *ret = NULL; - - *perr = check_hostent_err(hp); - if (*perr) { - return NULL; - } - ret = SMB_STRDUP(hp->h_name); - if (!ret) { - *perr = EAI_MEMORY; - } - return ret; -} - -static char *get_my_canon_name(int *perr) -{ - char name[HOST_NAME_MAX+1]; - - if (gethostname(name, HOST_NAME_MAX) == -1) { - *perr = EAI_FAIL; - return NULL; - } - /* Ensure null termination. */ - name[HOST_NAME_MAX] = '\0'; - return canon_name_from_hostent(gethostbyname(name), perr); -} - -static char *get_canon_name_from_addr(struct in_addr ip, - int *perr) -{ - return canon_name_from_hostent( - gethostbyaddr(&ip, sizeof(ip), AF_INET), - perr); -} - -static struct addrinfo *alloc_entry(const struct addrinfo *hints, - struct in_addr ip, - unsigned short port) -{ - struct sockaddr_in *psin = NULL; - struct addrinfo *ai = SMB_MALLOC(sizeof(*ai)); - - if (!ai) { - return NULL; - } - memset(ai, '\0', sizeof(*ai)); - - psin = SMB_MALLOC(sizeof(*psin)); - if (!psin) { - free(ai); - return NULL; - } - - memset(psin, '\0', sizeof(*psin)); - - psin->sin_family = AF_INET; - psin->sin_port = htons(port); - psin->sin_addr = ip; - - ai->ai_flags = 0; - ai->ai_family = AF_INET; - ai->ai_socktype = hints->ai_socktype; - ai->ai_protocol = hints->ai_protocol; - ai->ai_addrlen = sizeof(*psin); - ai->ai_addr = (struct sockaddr *) psin; - ai->ai_canonname = NULL; - ai->ai_next = NULL; - - return ai; -} - -/* - * get address info for a single ipv4 address. - * - * Bugs: - servname can only be a number, not text. - */ - -static int getaddr_info_single_addr(const char *service, - uint32_t addr, - const struct addrinfo *hints, - struct addrinfo **res) -{ - - struct addrinfo *ai = NULL; - struct in_addr ip; - unsigned short port = 0; - - if (service) { - port = (unsigned short)atoi(service); - } - ip.s_addr = htonl(addr); - - ai = alloc_entry(hints, ip, port); - if (!ai) { - return EAI_MEMORY; - } - - /* If we're asked for the canonical name, - * make sure it returns correctly. */ - if (!(hints->ai_flags & AI_NUMERICSERV) && - hints->ai_flags & AI_CANONNAME) { - int err; - if (addr == INADDR_LOOPBACK || addr == INADDR_ANY) { - ai->ai_canonname = get_my_canon_name(&err); - } else { - ai->ai_canonname = - get_canon_name_from_addr(ip,&err); - } - if (ai->ai_canonname == NULL) { - freeaddrinfo(ai); - return err; - } - } - - *res = ai; - return 0; -} - -/* - * get address info for multiple ipv4 addresses. - * - * Bugs: - servname can only be a number, not text. - */ - -static int getaddr_info_name(const char *node, - const char *service, - const struct addrinfo *hints, - struct addrinfo **res) -{ - struct addrinfo *listp = NULL, *prevp = NULL; - char **pptr = NULL; - int err; - struct hostent *hp = NULL; - unsigned short port = 0; - - if (service) { - port = (unsigned short)atoi(service); - } - - hp = gethostbyname(node); - err = check_hostent_err(hp); - if (err) { - return err; - } - - for(pptr = hp->h_addr_list; *pptr; pptr++) { - struct in_addr ip = *(struct in_addr *)*pptr; - struct addrinfo *ai = alloc_entry(hints, ip, port); - - if (!ai) { - freeaddrinfo(listp); - return EAI_MEMORY; - } - - if (!listp) { - listp = ai; - prevp = ai; - ai->ai_canonname = SMB_STRDUP(hp->h_name); - if (!ai->ai_canonname) { - freeaddrinfo(listp); - return EAI_MEMORY; - } - } else { - prevp->ai_next = ai; - prevp = ai; - } - } - *res = listp; - return 0; -} - -/* - * get address info for ipv4 sockets. - * - * Bugs: - servname can only be a number, not text. - */ - -int rep_getaddrinfo(const char *node, - const char *service, - const struct addrinfo * hintp, - struct addrinfo ** res) -{ - struct addrinfo hints; - - /* Setup the hints struct. */ - if (hintp == NULL) { - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - } else { - memcpy(&hints, hintp, sizeof(hints)); - } - - if (hints.ai_family != AF_INET && hints.ai_family != AF_UNSPEC) { - return EAI_FAMILY; - } - - if (hints.ai_socktype == 0) { - hints.ai_socktype = SOCK_STREAM; - } - - if (!node && !service) { - return EAI_NONAME; - } - - if (node) { - if (node[0] == '\0') { - return getaddr_info_single_addr(service, - INADDR_ANY, - &hints, - res); - } else if (hints.ai_flags & AI_NUMERICHOST) { - struct in_addr ip; - if (!inet_aton(node, &ip)) { - return EAI_FAIL; - } - return getaddr_info_single_addr(service, - ntohl(ip.s_addr), - &hints, - res); - } else { - return getaddr_info_name(node, - service, - &hints, - res); - } - } else if (hints.ai_flags & AI_PASSIVE) { - return getaddr_info_single_addr(service, - INADDR_ANY, - &hints, - res); - } - return getaddr_info_single_addr(service, - INADDR_LOOPBACK, - &hints, - res); -} - - -void rep_freeaddrinfo(struct addrinfo *res) -{ - struct addrinfo *next = NULL; - - for (;res; res = next) { - next = res->ai_next; - free(res->ai_canonname); - free(res->ai_addr); - free(res); - } -} - - -const char *rep_gai_strerror(int errcode) -{ -#ifdef HAVE_HSTRERROR - int hcode; - - switch (errcode) - { - case EAI_NONAME: - hcode = HOST_NOT_FOUND; - break; - case EAI_AGAIN: - hcode = TRY_AGAIN; - break; - case EAI_FAIL: - default: - hcode = NO_RECOVERY; - break; - } - - return hstrerror(hcode); -#else /* !HAVE_HSTRERROR */ - - switch (errcode) - { - case EAI_NONAME: - return "Unknown host"; - case EAI_AGAIN: - return "Host name lookup failure"; -#ifdef EAI_BADFLAGS - case EAI_BADFLAGS: - return "Invalid argument"; -#endif -#ifdef EAI_FAMILY - case EAI_FAMILY: - return "Address family not supported"; -#endif -#ifdef EAI_MEMORY - case EAI_MEMORY: - return "Not enough memory"; -#endif -#ifdef EAI_NODATA - case EAI_NODATA: - return "No host data of that type was found"; -#endif -#ifdef EAI_SERVICE - case EAI_SERVICE: - return "Class type not found"; -#endif -#ifdef EAI_SOCKTYPE - case EAI_SOCKTYPE: - return "Socket type not supported"; -#endif - default: - return "Unknown server error"; - } -#endif /* HAVE_HSTRERROR */ -} - -static int gethostnameinfo(const struct sockaddr *sa, - char *node, - size_t nodelen, - int flags) -{ - int ret = -1; - char *p = NULL; - - if (!(flags & NI_NUMERICHOST)) { - struct hostent *hp = gethostbyaddr( - &((struct sockaddr_in *)sa)->sin_addr, - sizeof(struct in_addr), - sa->sa_family); - ret = check_hostent_err(hp); - if (ret == 0) { - /* Name looked up successfully. */ - ret = snprintf(node, nodelen, "%s", hp->h_name); - if (ret < 0 || (size_t)ret >= nodelen) { - return EAI_MEMORY; - } - if (flags & NI_NOFQDN) { - p = strchr(node,'.'); - if (p) { - *p = '\0'; - } - } - return 0; - } - - if (flags & NI_NAMEREQD) { - /* If we require a name and didn't get one, - * automatically fail. */ - return ret; - } - /* Otherwise just fall into the numeric host code... */ - } - p = inet_ntoa(((struct sockaddr_in *)sa)->sin_addr); - ret = snprintf(node, nodelen, "%s", p); - if (ret < 0 || (size_t)ret >= nodelen) { - return EAI_MEMORY; - } - return 0; -} - -static int getservicenameinfo(const struct sockaddr *sa, - char *service, - size_t servicelen, - int flags) -{ - int ret = -1; - int port = ntohs(((struct sockaddr_in *)sa)->sin_port); - - if (!(flags & NI_NUMERICSERV)) { - struct servent *se = getservbyport( - port, - (flags & NI_DGRAM) ? "udp" : "tcp"); - if (se && se->s_name) { - /* Service name looked up successfully. */ - ret = snprintf(service, servicelen, "%s", se->s_name); - if (ret < 0 || (size_t)ret >= servicelen) { - return EAI_MEMORY; - } - return 0; - } - /* Otherwise just fall into the numeric service code... */ - } - ret = snprintf(service, servicelen, "%d", port); - if (ret < 0 || (size_t)ret >= servicelen) { - return EAI_MEMORY; - } - return 0; -} - -/* - * Convert an ipv4 address to a hostname. - * - * Bugs: - No IPv6 support. - */ -int rep_getnameinfo(const struct sockaddr *sa, socklen_t salen, - char *node, size_t nodelen, - char *service, size_t servicelen, int flags) -{ - - /* Invalid arguments. */ - if (sa == NULL || (node == NULL && service == NULL)) { - return EAI_FAIL; - } - - if (sa->sa_family != AF_INET) { - return EAI_FAIL; - } - - if (salen < sizeof(struct sockaddr_in)) { - return EAI_FAIL; - } - - if (node) { - return gethostnameinfo(sa, node, nodelen, flags); - } - - if (service) { - return getservicenameinfo(sa, service, servicelen, flags); - } - return 0; -} diff --git a/ldb-2.0.8/lib/replace/getaddrinfo.h b/ldb-2.0.8/lib/replace/getaddrinfo.h deleted file mode 100644 index cf040da..0000000 --- a/ldb-2.0.8/lib/replace/getaddrinfo.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -PostgreSQL Database Management System -(formerly known as Postgres, then as Postgres95) - -Portions Copyright (c) 1996-2005, The PostgreSQL Global Development Group - -Portions Copyright (c) 1994, The Regents of the University of California - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose, without fee, and without a written agreement -is hereby granted, provided that the above copyright notice and this paragraph -and the following two paragraphs appear in all copies. - -IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR -DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING -LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, -EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. - -THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS -TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - -*/ - -/*------------------------------------------------------------------------- - * - * getaddrinfo.h - * Support getaddrinfo() on platforms that don't have it. - * - * Note: we use our own routines on platforms that don't HAVE_STRUCT_ADDRINFO, - * whether or not the library routine getaddrinfo() can be found. This - * policy is needed because on some platforms a manually installed libbind.a - * may provide getaddrinfo(), yet the system headers may not provide the - * struct definitions needed to call it. To avoid conflict with the libbind - * definition in such cases, we rename our routines to pg_xxx() via macros. - * - -in lib/replace we use rep_xxx() - - * This code will also work on platforms where struct addrinfo is defined - * in the system headers but no getaddrinfo() can be located. - * - * Copyright (c) 2003-2007, PostgreSQL Global Development Group - * - *------------------------------------------------------------------------- - */ -#ifndef GETADDRINFO_H -#define GETADDRINFO_H - -#ifndef HAVE_GETADDRINFO - -/* Rename private copies per comments above */ -#ifdef getaddrinfo -#undef getaddrinfo -#endif -#define getaddrinfo rep_getaddrinfo -#define HAVE_GETADDRINFO - -#ifdef freeaddrinfo -#undef freeaddrinfo -#endif -#define freeaddrinfo rep_freeaddrinfo -#define HAVE_FREEADDRINFO - -#ifdef gai_strerror -#undef gai_strerror -#endif -#define gai_strerror rep_gai_strerror -#define HAVE_GAI_STRERROR - -#ifdef getnameinfo -#undef getnameinfo -#endif -#define getnameinfo rep_getnameinfo -#ifndef HAVE_GETNAMEINFO -#define HAVE_GETNAMEINFO -#endif - -extern int rep_getaddrinfo(const char *node, const char *service, - const struct addrinfo * hints, struct addrinfo ** res); -extern void rep_freeaddrinfo(struct addrinfo * res); -extern const char *rep_gai_strerror(int errcode); -extern int rep_getnameinfo(const struct sockaddr * sa, socklen_t salen, - char *node, size_t nodelen, - char *service, size_t servicelen, int flags); -#endif /* HAVE_GETADDRINFO */ - -#endif /* GETADDRINFO_H */ diff --git a/ldb-2.0.8/lib/replace/getifaddrs.c b/ldb-2.0.8/lib/replace/getifaddrs.c deleted file mode 100644 index a55ef7e..0000000 --- a/ldb-2.0.8/lib/replace/getifaddrs.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba utility functions - Copyright (C) Andrew Tridgell 1998 - Copyright (C) Jeremy Allison 2007 - Copyright (C) Jelmer Vernooij 2007 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#include "system/network.h" - -#include -#include -#include - -#ifdef HAVE_SYS_TIME_H -#include -#endif - -#ifndef SIOCGIFCONF -#ifdef HAVE_SYS_SOCKIO_H -#include -#endif -#endif - -#ifdef HAVE_IFACE_GETIFADDRS -#define _FOUND_IFACE_ANY -#else - -void rep_freeifaddrs(struct ifaddrs *ifp) -{ - if (ifp != NULL) { - free(ifp->ifa_name); - free(ifp->ifa_addr); - free(ifp->ifa_netmask); - free(ifp->ifa_dstaddr); - freeifaddrs(ifp->ifa_next); - free(ifp); - } -} - -static struct sockaddr *sockaddr_dup(struct sockaddr *sa) -{ - struct sockaddr *ret; - socklen_t socklen; -#ifdef HAVE_SOCKADDR_SA_LEN - socklen = sa->sa_len; -#else - socklen = sizeof(struct sockaddr_storage); -#endif - ret = calloc(1, socklen); - if (ret == NULL) - return NULL; - memcpy(ret, sa, socklen); - return ret; -} -#endif - -#ifdef HAVE_IFACE_IFCONF - -/* this works for Linux 2.2, Solaris 2.5, SunOS4, HPUX 10.20, OSF1 - V4.0, Ultrix 4.4, SCO Unix 3.2, IRIX 6.4 and FreeBSD 3.2. - - It probably also works on any BSD style system. */ - -int rep_getifaddrs(struct ifaddrs **ifap) -{ - struct ifconf ifc; - char buff[8192]; - int fd, i, n; - struct ifreq *ifr=NULL; - struct ifaddrs *curif; - struct ifaddrs *lastif = NULL; - - *ifap = NULL; - - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { - return -1; - } - - ifc.ifc_len = sizeof(buff); - ifc.ifc_buf = buff; - - if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) { - close(fd); - return -1; - } - - ifr = ifc.ifc_req; - - n = ifc.ifc_len / sizeof(struct ifreq); - - /* Loop through interfaces, looking for given IP address */ - for (i=n-1; i>=0; i--) { - if (ioctl(fd, SIOCGIFFLAGS, &ifr[i]) == -1) { - freeifaddrs(*ifap); - close(fd); - return -1; - } - - curif = calloc(1, sizeof(struct ifaddrs)); - if (curif == NULL) { - freeifaddrs(*ifap); - close(fd); - return -1; - } - curif->ifa_name = strdup(ifr[i].ifr_name); - if (curif->ifa_name == NULL) { - free(curif); - freeifaddrs(*ifap); - close(fd); - return -1; - } - curif->ifa_flags = ifr[i].ifr_flags; - curif->ifa_dstaddr = NULL; - curif->ifa_data = NULL; - curif->ifa_next = NULL; - - curif->ifa_addr = NULL; - if (ioctl(fd, SIOCGIFADDR, &ifr[i]) != -1) { - curif->ifa_addr = sockaddr_dup(&ifr[i].ifr_addr); - if (curif->ifa_addr == NULL) { - free(curif->ifa_name); - free(curif); - freeifaddrs(*ifap); - close(fd); - return -1; - } - } - - curif->ifa_netmask = NULL; - if (ioctl(fd, SIOCGIFNETMASK, &ifr[i]) != -1) { - curif->ifa_netmask = sockaddr_dup(&ifr[i].ifr_addr); - if (curif->ifa_netmask == NULL) { - if (curif->ifa_addr != NULL) { - free(curif->ifa_addr); - } - free(curif->ifa_name); - free(curif); - freeifaddrs(*ifap); - close(fd); - return -1; - } - } - - if (lastif == NULL) { - *ifap = curif; - } else { - lastif->ifa_next = curif; - } - lastif = curif; - } - - close(fd); - - return 0; -} - -#define _FOUND_IFACE_ANY -#endif /* HAVE_IFACE_IFCONF */ -#ifdef HAVE_IFACE_IFREQ - -#ifndef I_STR -#include -#endif - -/**************************************************************************** -this should cover most of the streams based systems -Thanks to Andrej.Borsenkow@mow.siemens.ru for several ideas in this code -****************************************************************************/ -int rep_getifaddrs(struct ifaddrs **ifap) -{ - struct ifreq ifreq; - struct strioctl strioctl; - char buff[8192]; - int fd, i, n; - struct ifreq *ifr=NULL; - struct ifaddrs *curif; - struct ifaddrs *lastif = NULL; - - *ifap = NULL; - - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { - return -1; - } - - strioctl.ic_cmd = SIOCGIFCONF; - strioctl.ic_dp = buff; - strioctl.ic_len = sizeof(buff); - if (ioctl(fd, I_STR, &strioctl) < 0) { - close(fd); - return -1; - } - - /* we can ignore the possible sizeof(int) here as the resulting - number of interface structures won't change */ - n = strioctl.ic_len / sizeof(struct ifreq); - - /* we will assume that the kernel returns the length as an int - at the start of the buffer if the offered size is a - multiple of the structure size plus an int */ - if (n*sizeof(struct ifreq) + sizeof(int) == strioctl.ic_len) { - ifr = (struct ifreq *)(buff + sizeof(int)); - } else { - ifr = (struct ifreq *)buff; - } - - /* Loop through interfaces */ - - for (i = 0; iifa_next = curif; - } - - strioctl.ic_cmd = SIOCGIFFLAGS; - strioctl.ic_dp = (char *)&ifreq; - strioctl.ic_len = sizeof(struct ifreq); - if (ioctl(fd, I_STR, &strioctl) != 0) { - freeifaddrs(*ifap); - return -1; - } - - curif->ifa_flags = ifreq.ifr_flags; - - strioctl.ic_cmd = SIOCGIFADDR; - strioctl.ic_dp = (char *)&ifreq; - strioctl.ic_len = sizeof(struct ifreq); - if (ioctl(fd, I_STR, &strioctl) != 0) { - freeifaddrs(*ifap); - return -1; - } - - curif->ifa_name = strdup(ifreq.ifr_name); - curif->ifa_addr = sockaddr_dup(&ifreq.ifr_addr); - curif->ifa_dstaddr = NULL; - curif->ifa_data = NULL; - curif->ifa_next = NULL; - curif->ifa_netmask = NULL; - - strioctl.ic_cmd = SIOCGIFNETMASK; - strioctl.ic_dp = (char *)&ifreq; - strioctl.ic_len = sizeof(struct ifreq); - if (ioctl(fd, I_STR, &strioctl) != 0) { - freeifaddrs(*ifap); - return -1; - } - - curif->ifa_netmask = sockaddr_dup(&ifreq.ifr_addr); - - lastif = curif; - } - - close(fd); - - return 0; -} - -#define _FOUND_IFACE_ANY -#endif /* HAVE_IFACE_IFREQ */ -#ifdef HAVE_IFACE_AIX - -/**************************************************************************** -this one is for AIX (tested on 4.2) -****************************************************************************/ -int rep_getifaddrs(struct ifaddrs **ifap) -{ - char buff[8192]; - int fd, i; - struct ifconf ifc; - struct ifreq *ifr=NULL; - struct ifaddrs *curif; - struct ifaddrs *lastif = NULL; - - *ifap = NULL; - - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { - return -1; - } - - ifc.ifc_len = sizeof(buff); - ifc.ifc_buf = buff; - - if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) { - close(fd); - return -1; - } - - ifr = ifc.ifc_req; - - /* Loop through interfaces */ - i = ifc.ifc_len; - - while (i > 0) { - unsigned int inc; - - inc = ifr->ifr_addr.sa_len; - - if (ioctl(fd, SIOCGIFADDR, ifr) != 0) { - freeaddrinfo(*ifap); - return -1; - } - - curif = calloc(1, sizeof(struct ifaddrs)); - if (lastif == NULL) { - *ifap = curif; - } else { - lastif->ifa_next = curif; - } - - curif->ifa_name = strdup(ifr->ifr_name); - curif->ifa_addr = sockaddr_dup(&ifr->ifr_addr); - curif->ifa_dstaddr = NULL; - curif->ifa_data = NULL; - curif->ifa_netmask = NULL; - curif->ifa_next = NULL; - - if (ioctl(fd, SIOCGIFFLAGS, ifr) != 0) { - freeaddrinfo(*ifap); - return -1; - } - - curif->ifa_flags = ifr->ifr_flags; - - if (ioctl(fd, SIOCGIFNETMASK, ifr) != 0) { - freeaddrinfo(*ifap); - return -1; - } - - curif->ifa_netmask = sockaddr_dup(&ifr->ifr_addr); - - lastif = curif; - - next: - /* - * Patch from Archie Cobbs (archie@whistle.com). The - * addresses in the SIOCGIFCONF interface list have a - * minimum size. Usually this doesn't matter, but if - * your machine has tunnel interfaces, etc. that have - * a zero length "link address", this does matter. */ - - if (inc < sizeof(ifr->ifr_addr)) - inc = sizeof(ifr->ifr_addr); - inc += IFNAMSIZ; - - ifr = (struct ifreq*) (((char*) ifr) + inc); - i -= inc; - } - - close(fd); - return 0; -} - -#define _FOUND_IFACE_ANY -#endif /* HAVE_IFACE_AIX */ -#ifndef _FOUND_IFACE_ANY -int rep_getifaddrs(struct ifaddrs **ifap) -{ - errno = ENOSYS; - return -1; -} -#endif diff --git a/ldb-2.0.8/lib/replace/hdr_replace.h b/ldb-2.0.8/lib/replace/hdr_replace.h deleted file mode 100644 index 6cfa50f..0000000 --- a/ldb-2.0.8/lib/replace/hdr_replace.h +++ /dev/null @@ -1,2 +0,0 @@ -/* this is a replacement header for a missing system header */ -#include "replace.h" diff --git a/ldb-2.0.8/lib/replace/inet_aton.c b/ldb-2.0.8/lib/replace/inet_aton.c deleted file mode 100644 index c6b3bb1..0000000 --- a/ldb-2.0.8/lib/replace/inet_aton.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * replacement functions - * Copyright (C) Michael Adam 2008 - * - * ** NOTE! The following LGPL license applies to the replace - * ** library. This does NOT imply that all of Samba is released - * ** under the LGPL - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - */ - -#include "replace.h" -#include "system/network.h" - -/** - * We know that we have inet_pton from earlier libreplace checks. - */ -int rep_inet_aton(const char *src, struct in_addr *dst) -{ - return (inet_pton(AF_INET, src, dst) > 0) ? 1 : 0; -} diff --git a/ldb-2.0.8/lib/replace/inet_ntoa.c b/ldb-2.0.8/lib/replace/inet_ntoa.c deleted file mode 100644 index e3b80eb..0000000 --- a/ldb-2.0.8/lib/replace/inet_ntoa.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * replacement routines for broken systems - * Copyright (C) Andrew Tridgell 2003 - * Copyright (C) Michael Adam 2008 - * - * ** NOTE! The following LGPL license applies to the replace - * ** library. This does NOT imply that all of Samba is released - * ** under the LGPL - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - */ - -#include "replace.h" -#include "system/network.h" - -/** - * NOTE: this is not thread safe, but it can't be, either - * since it returns a pointer to static memory. - */ -char *rep_inet_ntoa(struct in_addr ip) -{ - uint8_t *p = (uint8_t *)&ip.s_addr; - static char buf[18]; - slprintf(buf, 17, "%d.%d.%d.%d", - (int)p[0], (int)p[1], (int)p[2], (int)p[3]); - return buf; -} diff --git a/ldb-2.0.8/lib/replace/inet_ntop.c b/ldb-2.0.8/lib/replace/inet_ntop.c deleted file mode 100644 index fb3d8e9..0000000 --- a/ldb-2.0.8/lib/replace/inet_ntop.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (C) 1996-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING - * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - - -#include "replace.h" -#include "system/network.h" - -#define NS_INT16SZ 2 -#define NS_IN6ADDRSZ 16 - -/* - * WARNING: Don't even consider trying to compile this on a system where - * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. - */ - -static const char *inet_ntop4(const unsigned char *src, char *dst, - socklen_t size); - -#ifdef AF_INET6 -static const char *inet_ntop6(const unsigned char *src, char *dst, - socklen_t size); -#endif - -/* char * - * isc_net_ntop(af, src, dst, size) - * convert a network format address to presentation format. - * return: - * pointer to presentation format address (`dst'), or NULL (see errno). - * author: - * Paul Vixie, 1996. - */ -const char * -rep_inet_ntop(int af, const void *src, char *dst, socklen_t size) -{ - switch (af) { - case AF_INET: - return (inet_ntop4(src, dst, size)); -#ifdef AF_INET6 - case AF_INET6: - return (inet_ntop6(src, dst, size)); -#endif - default: - errno = EAFNOSUPPORT; - return (NULL); - } - /* NOTREACHED */ -} - -/* const char * - * inet_ntop4(src, dst, size) - * format an IPv4 address - * return: - * `dst' (as a const) - * notes: - * (1) uses no statics - * (2) takes a unsigned char* not an in_addr as input - * author: - * Paul Vixie, 1996. - */ -static const char * -inet_ntop4(const unsigned char *src, char *dst, socklen_t size) -{ - static const char *fmt = "%u.%u.%u.%u"; - char tmp[sizeof "255.255.255.255"]; - size_t len; - - len = snprintf(tmp, sizeof tmp, fmt, src[0], src[1], src[2], src[3]); - if (len >= size) { - errno = ENOSPC; - return (NULL); - } - memcpy(dst, tmp, len + 1); - - return (dst); -} - -/* const char * - * isc_inet_ntop6(src, dst, size) - * convert IPv6 binary address into presentation (printable) format - * author: - * Paul Vixie, 1996. - */ -#ifdef AF_INET6 -static const char * -inet_ntop6(const unsigned char *src, char *dst, socklen_t size) -{ - /* - * Note that int32_t and int16_t need only be "at least" large enough - * to contain a value of the specified size. On some systems, like - * Crays, there is no such thing as an integer variable with 16 bits. - * Keep this in mind if you think this function should have been coded - * to use pointer overlays. All the world's not a VAX. - */ - char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; - struct { int base, len; } best, cur; - unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ]; - int i, inc; - - /* - * Preprocess: - * Copy the input (bytewise) array into a wordwise array. - * Find the longest run of 0x00's in src[] for :: shorthanding. - */ - memset(words, '\0', sizeof words); - for (i = 0; i < NS_IN6ADDRSZ; i++) - words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); - best.base = -1; - best.len = 0; - cur.base = -1; - cur.len = 0; - for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { - if (words[i] == 0) { - if (cur.base == -1) - cur.base = i, cur.len = 1; - else - cur.len++; - } else { - if (cur.base != -1) { - if (best.base == -1 || cur.len > best.len) - best = cur; - cur.base = -1; - } - } - } - if (cur.base != -1) { - if (best.base == -1 || cur.len > best.len) - best = cur; - } - if (best.base != -1 && best.len < 2) - best.base = -1; - - /* - * Format the result. - */ - tp = tmp; - for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { - /* Are we inside the best run of 0x00's? */ - if (best.base != -1 && i >= best.base && - i < (best.base + best.len)) { - if (i == best.base) - *tp++ = ':'; - continue; - } - /* Are we following an initial run of 0x00s or any real hex? */ - if (i != 0) - *tp++ = ':'; - /* Is this address an encapsulated IPv4? */ - if (i == 6 && best.base == 0 && - (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { - if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) - return (NULL); - tp += strlen(tp); - break; - } - inc = snprintf(tp, 5, "%x", words[i]); - if (inc >= 5) { - abort(); - } - tp += inc; - } - /* Was it a trailing run of 0x00's? */ - if (best.base != -1 && (best.base + best.len) == - (NS_IN6ADDRSZ / NS_INT16SZ)) - *tp++ = ':'; - *tp++ = '\0'; - - /* - * Check for overflow, copy, and we're done. - */ - if ((size_t)(tp - tmp) > size) { - errno = ENOSPC; - return (NULL); - } - memcpy(dst, tmp, tp - tmp); - return (dst); -} -#endif /* AF_INET6 */ diff --git a/ldb-2.0.8/lib/replace/inet_pton.c b/ldb-2.0.8/lib/replace/inet_pton.c deleted file mode 100644 index 80e4865..0000000 --- a/ldb-2.0.8/lib/replace/inet_pton.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (C) 1996-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING - * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "replace.h" -#include "system/network.h" - -#define NS_INT16SZ 2 -#define NS_INADDRSZ 4 -#define NS_IN6ADDRSZ 16 - -/* - * WARNING: Don't even consider trying to compile this on a system where - * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. - */ - -static int inet_pton4(const char *src, unsigned char *dst); -#ifdef AF_INET6 -static int inet_pton6(const char *src, unsigned char *dst); -#endif - -/* int - * inet_pton(af, src, dst) - * convert from presentation format (which usually means ASCII printable) - * to network format (which is usually some kind of binary format). - * return: - * 1 if the address was valid for the specified address family - * 0 if the address wasn't valid (`dst' is untouched in this case) - * -1 if some other error occurred (`dst' is untouched in this case, too) - * author: - * Paul Vixie, 1996. - */ -int -rep_inet_pton(int af, - const char *src, - void *dst) -{ - switch (af) { - case AF_INET: - return (inet_pton4(src, dst)); -#ifdef AF_INET6 - case AF_INET6: - return (inet_pton6(src, dst)); -#endif - default: - errno = EAFNOSUPPORT; - return (-1); - } - /* NOTREACHED */ -} - -/* int - * inet_pton4(src, dst) - * like inet_aton() but without all the hexadecimal and shorthand. - * return: - * 1 if `src' is a valid dotted quad, else 0. - * notice: - * does not touch `dst' unless it's returning 1. - * author: - * Paul Vixie, 1996. - */ -static int -inet_pton4(src, dst) - const char *src; - unsigned char *dst; -{ - static const char digits[] = "0123456789"; - int saw_digit, octets, ch; - unsigned char tmp[NS_INADDRSZ], *tp; - - saw_digit = 0; - octets = 0; - *(tp = tmp) = 0; - while ((ch = *src++) != '\0') { - const char *pch; - - if ((pch = strchr(digits, ch)) != NULL) { - unsigned int new = *tp * 10 + (pch - digits); - - if (new > 255) - return (0); - *tp = new; - if (! saw_digit) { - if (++octets > 4) - return (0); - saw_digit = 1; - } - } else if (ch == '.' && saw_digit) { - if (octets == 4) - return (0); - *++tp = 0; - saw_digit = 0; - } else - return (0); - } - if (octets < 4) - return (0); - memcpy(dst, tmp, NS_INADDRSZ); - return (1); -} - -/* int - * inet_pton6(src, dst) - * convert presentation level address to network order binary form. - * return: - * 1 if `src' is a valid [RFC1884 2.2] address, else 0. - * notice: - * (1) does not touch `dst' unless it's returning 1. - * (2) :: in a full address is silently ignored. - * credit: - * inspired by Mark Andrews. - * author: - * Paul Vixie, 1996. - */ -#ifdef AF_INET6 -static int -inet_pton6(src, dst) - const char *src; - unsigned char *dst; -{ - static const char xdigits_l[] = "0123456789abcdef", - xdigits_u[] = "0123456789ABCDEF"; - unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; - const char *xdigits, *curtok; - int ch, saw_xdigit; - unsigned int val; - - memset((tp = tmp), '\0', NS_IN6ADDRSZ); - endp = tp + NS_IN6ADDRSZ; - colonp = NULL; - /* Leading :: requires some special handling. */ - if (*src == ':') - if (*++src != ':') - return (0); - curtok = src; - saw_xdigit = 0; - val = 0; - while ((ch = *src++) != '\0') { - const char *pch; - - if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) - pch = strchr((xdigits = xdigits_u), ch); - if (pch != NULL) { - val <<= 4; - val |= (pch - xdigits); - if (val > 0xffff) - return (0); - saw_xdigit = 1; - continue; - } - if (ch == ':') { - curtok = src; - if (!saw_xdigit) { - if (colonp) - return (0); - colonp = tp; - continue; - } - if (tp + NS_INT16SZ > endp) - return (0); - *tp++ = (unsigned char) (val >> 8) & 0xff; - *tp++ = (unsigned char) val & 0xff; - saw_xdigit = 0; - val = 0; - continue; - } - if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && - inet_pton4(curtok, tp) > 0) { - tp += NS_INADDRSZ; - saw_xdigit = 0; - break; /* '\0' was seen by inet_pton4(). */ - } - return (0); - } - if (saw_xdigit) { - if (tp + NS_INT16SZ > endp) - return (0); - *tp++ = (unsigned char) (val >> 8) & 0xff; - *tp++ = (unsigned char) val & 0xff; - } - if (colonp != NULL) { - /* - * Since some memmove()'s erroneously fail to handle - * overlapping regions, we'll do the shift by hand. - */ - const int n = tp - colonp; - int i; - - for (i = 1; i <= n; i++) { - endp[- i] = colonp[n - i]; - colonp[n - i] = 0; - } - tp = endp; - } - if (tp != endp) - return (0); - memcpy(dst, tmp, NS_IN6ADDRSZ); - return (1); -} -#endif diff --git a/ldb-2.0.8/lib/replace/poll.c b/ldb-2.0.8/lib/replace/poll.c deleted file mode 100644 index 1105617..0000000 --- a/ldb-2.0.8/lib/replace/poll.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - Unix SMB/CIFS implementation. - poll.c - poll wrapper - - This file is based on code from libssh (LGPLv2.1+ at the time it - was downloaded), thus the following copyrights: - - Copyright (c) 2009-2010 by Andreas Schneider - Copyright (c) 2003-2009 by Aris Adamantiadis - Copyright (c) 2009 Aleksandar Kanchev - Copyright (C) Volker Lendecke 2011 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - */ - -#include "replace.h" -#include "system/select.h" -#ifdef HAVE_SYS_TIME_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - - -int rep_poll(struct pollfd *fds, nfds_t nfds, int timeout) -{ - fd_set rfds, wfds, efds; - struct timeval tv, *ptv; - int max_fd; - int rc; - nfds_t i; - - if ((fds == NULL) && (nfds != 0)) { - errno = EFAULT; - return -1; - } - - FD_ZERO(&rfds); - FD_ZERO(&wfds); - FD_ZERO(&efds); - - rc = 0; - max_fd = 0; - - /* compute fd_sets and find largest descriptor */ - for (i = 0; i < nfds; i++) { - if ((fds[i].fd < 0) || (fds[i].fd >= FD_SETSIZE)) { - fds[i].revents = POLLNVAL; - continue; - } - - if (fds[i].events & (POLLIN | POLLRDNORM)) { - FD_SET(fds[i].fd, &rfds); - } - if (fds[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND)) { - FD_SET(fds[i].fd, &wfds); - } - if (fds[i].events & (POLLPRI | POLLRDBAND)) { - FD_SET(fds[i].fd, &efds); - } - if (fds[i].fd > max_fd && - (fds[i].events & (POLLIN | POLLOUT | POLLPRI | - POLLRDNORM | POLLRDBAND | - POLLWRNORM | POLLWRBAND))) { - max_fd = fds[i].fd; - } - } - - if (timeout < 0) { - ptv = NULL; - } else { - ptv = &tv; - if (timeout == 0) { - tv.tv_sec = 0; - tv.tv_usec = 0; - } else { - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000; - } - } - - rc = select(max_fd + 1, &rfds, &wfds, &efds, ptv); - if (rc < 0) { - return -1; - } - - for (rc = 0, i = 0; i < nfds; i++) { - if ((fds[i].fd < 0) || (fds[i].fd >= FD_SETSIZE)) { - continue; - } - - fds[i].revents = 0; - - if (FD_ISSET(fds[i].fd, &rfds)) { - int err = errno; - int available = 0; - int ret; - - /* support for POLLHUP */ - ret = ioctl(fds[i].fd, FIONREAD, &available); - if ((ret == -1) || (available == 0)) { - fds[i].revents |= POLLHUP; - } else { - fds[i].revents |= fds[i].events - & (POLLIN | POLLRDNORM); - } - - errno = err; - } - if (FD_ISSET(fds[i].fd, &wfds)) { - fds[i].revents |= fds[i].events - & (POLLOUT | POLLWRNORM | POLLWRBAND); - } - if (FD_ISSET(fds[i].fd, &efds)) { - fds[i].revents |= fds[i].events - & (POLLPRI | POLLRDBAND); - } - if (fds[i].revents & ~POLLHUP) { - rc++; - } - } - return rc; -} diff --git a/ldb-2.0.8/lib/replace/replace-test.h b/ldb-2.0.8/lib/replace/replace-test.h deleted file mode 100644 index ed8e75e..0000000 --- a/ldb-2.0.8/lib/replace/replace-test.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __LIB_REPLACE_REPLACE_TEST_H__ -#define __LIB_REPLACE_REPLACE_TEST_H__ - -int libreplace_test_strptime(void); -int test_readdir_os2_delete(void); -int getifaddrs_test(void); - -#endif /* __LIB_REPLACE_REPLACE_TEST_H__ */ - diff --git a/ldb-2.0.8/lib/replace/replace-testsuite.h b/ldb-2.0.8/lib/replace/replace-testsuite.h deleted file mode 100644 index b28dbec..0000000 --- a/ldb-2.0.8/lib/replace/replace-testsuite.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __LIB_REPLACE_REPLACE_TESTSUITE_H__ -#define __LIB_REPLACE_REPLACE_TESTSUITE_H__ - -#include -struct torture_context; - -bool torture_local_replace(struct torture_context *ctx); - -#endif /* __LIB_REPLACE_REPLACE_TESTSUITE_H__ */ - diff --git a/ldb-2.0.8/lib/replace/replace.c b/ldb-2.0.8/lib/replace/replace.c deleted file mode 100644 index a14322b..0000000 --- a/ldb-2.0.8/lib/replace/replace.c +++ /dev/null @@ -1,1058 +0,0 @@ -/* - Unix SMB/CIFS implementation. - replacement routines for broken systems - Copyright (C) Andrew Tridgell 1992-1998 - Copyright (C) Jelmer Vernooij 2005-2008 - Copyright (C) Matthieu Patou 2010 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" - -#include "system/filesys.h" -#include "system/time.h" -#include "system/network.h" -#include "system/passwd.h" -#include "system/syslog.h" -#include "system/locale.h" -#include "system/wait.h" - -#ifdef _WIN32 -#define mkdir(d,m) _mkdir(d) -#endif - -void replace_dummy(void); -void replace_dummy(void) {} - -#ifndef HAVE_FTRUNCATE - /******************************************************************* -ftruncate for operating systems that don't have it -********************************************************************/ -int rep_ftruncate(int f, off_t l) -{ -#ifdef HAVE_CHSIZE - return chsize(f,l); -#elif defined(F_FREESP) - struct flock fl; - - fl.l_whence = 0; - fl.l_len = 0; - fl.l_start = l; - fl.l_type = F_WRLCK; - return fcntl(f, F_FREESP, &fl); -#else -#error "you must have a ftruncate function" -#endif -} -#endif /* HAVE_FTRUNCATE */ - - -#ifndef HAVE_STRLCPY -/* - * Like strncpy but does not 0 fill the buffer and always null - * terminates. bufsize is the size of the destination buffer. - * Returns the length of s. - */ -size_t rep_strlcpy(char *d, const char *s, size_t bufsize) -{ - size_t len = strlen(s); - size_t ret = len; - - if (bufsize <= 0) { - return 0; - } - if (len >= bufsize) { - len = bufsize - 1; - } - memcpy(d, s, len); - d[len] = 0; - return ret; -} -#endif - -#ifndef HAVE_STRLCAT -/* like strncat but does not 0 fill the buffer and always null - terminates. bufsize is the length of the buffer, which should - be one more than the maximum resulting string length */ -size_t rep_strlcat(char *d, const char *s, size_t bufsize) -{ - size_t len1 = strnlen(d, bufsize); - size_t len2 = strlen(s); - size_t ret = len1 + len2; - - if (len1+len2 >= bufsize) { - if (bufsize < (len1+1)) { - return ret; - } - len2 = bufsize - (len1+1); - } - if (len2 > 0) { - memcpy(d+len1, s, len2); - d[len1+len2] = 0; - } - return ret; -} -#endif - -#ifndef HAVE_MKTIME -/******************************************************************* -a mktime() replacement for those who don't have it - contributed by -C.A. Lademann -Corrections by richard.kettlewell@kewill.com -********************************************************************/ - -#define MINUTE 60 -#define HOUR 60*MINUTE -#define DAY 24*HOUR -#define YEAR 365*DAY -time_t rep_mktime(struct tm *t) -{ - struct tm *u; - time_t epoch = 0; - int n; - int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, - y, m, i; - - if(t->tm_year < 70) - return((time_t)-1); - - n = t->tm_year + 1900 - 1; - epoch = (t->tm_year - 70) * YEAR + - ((n / 4 - n / 100 + n / 400) - (1969 / 4 - 1969 / 100 + 1969 / 400)) * DAY; - - y = t->tm_year + 1900; - m = 0; - - for(i = 0; i < t->tm_mon; i++) { - epoch += mon [m] * DAY; - if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) - epoch += DAY; - - if(++m > 11) { - m = 0; - y++; - } - } - - epoch += (t->tm_mday - 1) * DAY; - epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec; - - if((u = localtime(&epoch)) != NULL) { - t->tm_sec = u->tm_sec; - t->tm_min = u->tm_min; - t->tm_hour = u->tm_hour; - t->tm_mday = u->tm_mday; - t->tm_mon = u->tm_mon; - t->tm_year = u->tm_year; - t->tm_wday = u->tm_wday; - t->tm_yday = u->tm_yday; - t->tm_isdst = u->tm_isdst; - } - - return(epoch); -} -#endif /* !HAVE_MKTIME */ - - -#ifndef HAVE_INITGROUPS -/**************************************************************************** - some systems don't have an initgroups call -****************************************************************************/ -int rep_initgroups(char *name, gid_t id) -{ -#ifndef HAVE_SETGROUPS - /* yikes! no SETGROUPS or INITGROUPS? how can this work? */ - errno = ENOSYS; - return -1; -#else /* HAVE_SETGROUPS */ - -#include - - gid_t *grouplst = NULL; - int max_gr = NGROUPS_MAX; - int ret; - int i,j; - struct group *g; - char *gr; - - if((grouplst = malloc(sizeof(gid_t) * max_gr)) == NULL) { - errno = ENOMEM; - return -1; - } - - grouplst[0] = id; - i = 1; - while (i < max_gr && ((g = (struct group *)getgrent()) != (struct group *)NULL)) { - if (g->gr_gid == id) - continue; - j = 0; - gr = g->gr_mem[0]; - while (gr && (*gr != (char)NULL)) { - if (strcmp(name,gr) == 0) { - grouplst[i] = g->gr_gid; - i++; - gr = (char *)NULL; - break; - } - gr = g->gr_mem[++j]; - } - } - endgrent(); - ret = setgroups(i, grouplst); - free(grouplst); - return ret; -#endif /* HAVE_SETGROUPS */ -} -#endif /* HAVE_INITGROUPS */ - - -#ifndef HAVE_MEMMOVE -/******************************************************************* -safely copies memory, ensuring no overlap problems. -this is only used if the machine does not have its own memmove(). -this is not the fastest algorithm in town, but it will do for our -needs. -********************************************************************/ -void *rep_memmove(void *dest,const void *src,int size) -{ - unsigned long d,s; - int i; - if (dest==src || !size) return(dest); - - d = (unsigned long)dest; - s = (unsigned long)src; - - if ((d >= (s+size)) || (s >= (d+size))) { - /* no overlap */ - memcpy(dest,src,size); - return(dest); - } - - if (d < s) { - /* we can forward copy */ - if (s-d >= sizeof(int) && - !(s%sizeof(int)) && - !(d%sizeof(int)) && - !(size%sizeof(int))) { - /* do it all as words */ - int *idest = (int *)dest; - int *isrc = (int *)src; - size /= sizeof(int); - for (i=0;i= sizeof(int) && - !(s%sizeof(int)) && - !(d%sizeof(int)) && - !(size%sizeof(int))) { - /* do it all as words */ - int *idest = (int *)dest; - int *isrc = (int *)src; - size /= sizeof(int); - for (i=size-1;i>=0;i--) idest[i] = isrc[i]; - } else { - /* simplest */ - char *cdest = (char *)dest; - char *csrc = (char *)src; - for (i=size-1;i>=0;i--) cdest[i] = csrc[i]; - } - } - return(dest); -} -#endif /* HAVE_MEMMOVE */ - -#ifndef HAVE_STRDUP -/**************************************************************************** -duplicate a string -****************************************************************************/ -char *rep_strdup(const char *s) -{ - size_t len; - char *ret; - - if (!s) return(NULL); - - len = strlen(s)+1; - ret = (char *)malloc(len); - if (!ret) return(NULL); - memcpy(ret,s,len); - return(ret); -} -#endif /* HAVE_STRDUP */ - -#ifndef HAVE_SETLINEBUF -void rep_setlinebuf(FILE *stream) -{ - setvbuf(stream, (char *)NULL, _IOLBF, 0); -} -#endif /* HAVE_SETLINEBUF */ - -#ifndef HAVE_VSYSLOG -#ifdef HAVE_SYSLOG -void rep_vsyslog (int facility_priority, const char *format, va_list arglist) -{ - char *msg = NULL; - vasprintf(&msg, format, arglist); - if (!msg) - return; - syslog(facility_priority, "%s", msg); - free(msg); -} -#endif /* HAVE_SYSLOG */ -#endif /* HAVE_VSYSLOG */ - -#ifndef HAVE_STRNLEN -/** - Some platforms don't have strnlen -**/ - size_t rep_strnlen(const char *s, size_t max) -{ - size_t len; - - for (len = 0; len < max; len++) { - if (s[len] == '\0') { - break; - } - } - return len; -} -#endif - -#ifndef HAVE_STRNDUP -/** - Some platforms don't have strndup. -**/ -char *rep_strndup(const char *s, size_t n) -{ - char *ret; - - n = strnlen(s, n); - ret = malloc(n+1); - if (!ret) - return NULL; - memcpy(ret, s, n); - ret[n] = 0; - - return ret; -} -#endif - -#if !defined(HAVE_WAITPID) && defined(HAVE_WAIT4) -int rep_waitpid(pid_t pid,int *status,int options) -{ - return wait4(pid, status, options, NULL); -} -#endif - -#ifndef HAVE_SETEUID -int rep_seteuid(uid_t euid) -{ -#ifdef HAVE_SETRESUID - return setresuid(-1, euid, -1); -#else - errno = ENOSYS; - return -1; -#endif -} -#endif - -#ifndef HAVE_SETEGID -int rep_setegid(gid_t egid) -{ -#ifdef HAVE_SETRESGID - return setresgid(-1, egid, -1); -#else - errno = ENOSYS; - return -1; -#endif -} -#endif - -/******************************************************************* -os/2 also doesn't have chroot -********************************************************************/ -#ifndef HAVE_CHROOT -int rep_chroot(const char *dname) -{ - errno = ENOSYS; - return -1; -} -#endif - -/***************************************************************** - Possibly replace mkstemp if it is broken. -*****************************************************************/ - -#ifndef HAVE_SECURE_MKSTEMP -int rep_mkstemp(char *template) -{ - /* have a reasonable go at emulating it. Hope that - the system mktemp() isn't completely hopeless */ - mktemp(template); - if (template[0] == 0) - return -1; - return open(template, O_CREAT|O_EXCL|O_RDWR, 0600); -} -#endif - -#ifndef HAVE_MKDTEMP -char *rep_mkdtemp(char *template) -{ - char *dname; - - if ((dname = mktemp(template))) { - if (mkdir(dname, 0700) >= 0) { - return dname; - } - } - - return NULL; -} -#endif - -/***************************************************************** - Watch out: this is not thread safe. -*****************************************************************/ - -#ifndef HAVE_PREAD -ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset) -{ - if (lseek(__fd, __offset, SEEK_SET) != __offset) { - return -1; - } - return read(__fd, __buf, __nbytes); -} -#endif - -/***************************************************************** - Watch out: this is not thread safe. -*****************************************************************/ - -#ifndef HAVE_PWRITE -ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset) -{ - if (lseek(__fd, __offset, SEEK_SET) != __offset) { - return -1; - } - return write(__fd, __buf, __nbytes); -} -#endif - -#ifndef HAVE_STRCASESTR -char *rep_strcasestr(const char *haystack, const char *needle) -{ - const char *s; - size_t nlen = strlen(needle); - for (s=haystack;*s;s++) { - if (toupper(*needle) == toupper(*s) && - strncasecmp(s, needle, nlen) == 0) { - return (char *)((uintptr_t)s); - } - } - return NULL; -} -#endif - -#ifndef HAVE_STRSEP -char *rep_strsep(char **pps, const char *delim) -{ - char *ret = *pps; - char *p = *pps; - - if (p == NULL) { - return NULL; - } - p += strcspn(p, delim); - if (*p == '\0') { - *pps = NULL; - } else { - *p = '\0'; - *pps = p + 1; - } - return ret; -} -#endif - -#ifndef HAVE_STRTOK_R -/* based on GLIBC version, copyright Free Software Foundation */ -char *rep_strtok_r(char *s, const char *delim, char **save_ptr) -{ - char *token; - - if (s == NULL) s = *save_ptr; - - s += strspn(s, delim); - if (*s == '\0') { - *save_ptr = s; - return NULL; - } - - token = s; - s = strpbrk(token, delim); - if (s == NULL) { - *save_ptr = token + strlen(token); - } else { - *s = '\0'; - *save_ptr = s + 1; - } - - return token; -} -#endif - - -#ifndef HAVE_STRTOLL -long long int rep_strtoll(const char *str, char **endptr, int base) -{ -#ifdef HAVE_STRTOQ - return strtoq(str, endptr, base); -#elif defined(HAVE___STRTOLL) - return __strtoll(str, endptr, base); -#elif SIZEOF_LONG == SIZEOF_LONG_LONG - return (long long int) strtol(str, endptr, base); -#else -# error "You need a strtoll function" -#endif -} -#else -#ifdef HAVE_BSD_STRTOLL -#undef strtoll -long long int rep_strtoll(const char *str, char **endptr, int base) -{ - int saved_errno = errno; - long long int nb = strtoll(str, endptr, base); - /* With glibc EINVAL is only returned if base is not ok */ - if (errno == EINVAL) { - if (base == 0 || (base >1 && base <37)) { - /* Base was ok so it's because we were not - * able to make the convertion. - * Let's reset errno. - */ - errno = saved_errno; - } - } - return nb; -} -#endif /* HAVE_BSD_STRTOLL */ -#endif /* HAVE_STRTOLL */ - - -#ifndef HAVE_STRTOULL -unsigned long long int rep_strtoull(const char *str, char **endptr, int base) -{ -#ifdef HAVE_STRTOUQ - return strtouq(str, endptr, base); -#elif defined(HAVE___STRTOULL) - return __strtoull(str, endptr, base); -#elif SIZEOF_LONG == SIZEOF_LONG_LONG - return (unsigned long long int) strtoul(str, endptr, base); -#else -# error "You need a strtoull function" -#endif -} -#else -#ifdef HAVE_BSD_STRTOLL -#undef strtoull -unsigned long long int rep_strtoull(const char *str, char **endptr, int base) -{ - int saved_errno = errno; - unsigned long long int nb = strtoull(str, endptr, base); - /* With glibc EINVAL is only returned if base is not ok */ - if (errno == EINVAL) { - if (base == 0 || (base >1 && base <37)) { - /* Base was ok so it's because we were not - * able to make the convertion. - * Let's reset errno. - */ - errno = saved_errno; - } - } - return nb; -} -#endif /* HAVE_BSD_STRTOLL */ -#endif /* HAVE_STRTOULL */ - -#ifndef HAVE_SETENV -int rep_setenv(const char *name, const char *value, int overwrite) -{ - char *p; - size_t l1, l2; - int ret; - - if (!overwrite && getenv(name)) { - return 0; - } - - l1 = strlen(name); - l2 = strlen(value); - - p = malloc(l1+l2+2); - if (p == NULL) { - return -1; - } - memcpy(p, name, l1); - p[l1] = '='; - memcpy(p+l1+1, value, l2); - p[l1+l2+1] = 0; - - ret = putenv(p); - if (ret != 0) { - free(p); - } - - return ret; -} -#endif - -#ifndef HAVE_UNSETENV -int rep_unsetenv(const char *name) -{ - extern char **environ; - size_t len = strlen(name); - size_t i, count; - - if (environ == NULL || getenv(name) == NULL) { - return 0; - } - - for (i=0;environ[i];i++) /* noop */ ; - - count=i; - - for (i=0;i= needlelen) { - char *p = (char *)memchr(haystack, *(const char *)needle, - haystacklen-(needlelen-1)); - if (!p) return NULL; - if (memcmp(p, needle, needlelen) == 0) { - return p; - } - haystack = p+1; - haystacklen -= (p - (const char *)haystack) + 1; - } - return NULL; -} -#endif - -#if !defined(HAVE_VDPRINTF) || !defined(HAVE_C99_VSNPRINTF) -int rep_vdprintf(int fd, const char *format, va_list ap) -{ - char *s = NULL; - int ret; - - vasprintf(&s, format, ap); - if (s == NULL) { - errno = ENOMEM; - return -1; - } - ret = write(fd, s, strlen(s)); - free(s); - return ret; -} -#endif - -#if !defined(HAVE_DPRINTF) || !defined(HAVE_C99_VSNPRINTF) -int rep_dprintf(int fd, const char *format, ...) -{ - int ret; - va_list ap; - - va_start(ap, format); - ret = vdprintf(fd, format, ap); - va_end(ap); - - return ret; -} -#endif - -#ifndef HAVE_GET_CURRENT_DIR_NAME -char *rep_get_current_dir_name(void) -{ - char buf[PATH_MAX+1]; - char *p; - p = getcwd(buf, sizeof(buf)); - if (p == NULL) { - return NULL; - } - return strdup(p); -} -#endif - -#ifndef HAVE_STRERROR_R -int rep_strerror_r(int errnum, char *buf, size_t buflen) -{ - char *s = strerror(errnum); - if (strlen(s)+1 > buflen) { - errno = ERANGE; - return -1; - } - strncpy(buf, s, buflen); - return 0; -} -#elif (!defined(STRERROR_R_XSI_NOT_GNU)) -#undef strerror_r -int rep_strerror_r(int errnum, char *buf, size_t buflen) -{ - char *s = strerror_r(errnum, buf, buflen); - if (s == NULL) { - /* Shouldn't happen, should always get a string */ - return EINVAL; - } - if (s != buf) { - strlcpy(buf, s, buflen); - if (strlen(s) > buflen - 1) { - return ERANGE; - } - } - return 0; - -} -#endif - -#ifndef HAVE_CLOCK_GETTIME -int rep_clock_gettime(clockid_t clk_id, struct timespec *tp) -{ - struct timeval tval; - switch (clk_id) { - case 0: /* CLOCK_REALTIME :*/ -#if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID) - gettimeofday(&tval,NULL); -#else - gettimeofday(&tval); -#endif - tp->tv_sec = tval.tv_sec; - tp->tv_nsec = tval.tv_usec * 1000; - break; - default: - errno = EINVAL; - return -1; - } - return 0; -} -#endif - -#ifndef HAVE_MEMALIGN -void *rep_memalign( size_t align, size_t size ) -{ -#if defined(HAVE_POSIX_MEMALIGN) - void *p = NULL; - int ret = posix_memalign( &p, align, size ); - if ( ret == 0 ) - return p; - - return NULL; -#else - /* On *BSD systems memaligns doesn't exist, but memory will - * be aligned on allocations of > pagesize. */ -#if defined(SYSCONF_SC_PAGESIZE) - size_t pagesize = (size_t)sysconf(_SC_PAGESIZE); -#elif defined(HAVE_GETPAGESIZE) - size_t pagesize = (size_t)getpagesize(); -#else - size_t pagesize = (size_t)-1; -#endif - if (pagesize == (size_t)-1) { - errno = ENOSYS; - return NULL; - } - if (size < pagesize) { - size = pagesize; - } - return malloc(size); -#endif -} -#endif - -#ifndef HAVE_GETPEEREID -int rep_getpeereid(int s, uid_t *uid, gid_t *gid) -{ -#if defined(HAVE_PEERCRED) - struct ucred cred; - socklen_t cred_len = sizeof(struct ucred); - int ret; - -#undef getsockopt - ret = getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void *)&cred, &cred_len); - if (ret != 0) { - return -1; - } - - if (cred_len != sizeof(struct ucred)) { - errno = EINVAL; - return -1; - } - - *uid = cred.uid; - *gid = cred.gid; - return 0; -#else - errno = ENOSYS; - return -1; -#endif -} -#endif - -#ifndef HAVE_USLEEP -int rep_usleep(useconds_t sec) -{ - struct timeval tval; - /* - * Fake it with select... - */ - tval.tv_sec = 0; - tval.tv_usec = usecs/1000; - select(0,NULL,NULL,NULL,&tval); - return 0; -} -#endif /* HAVE_USLEEP */ - -#ifndef HAVE_SETPROCTITLE -void rep_setproctitle(const char *fmt, ...) -{ -} -#endif -#ifndef HAVE_SETPROCTITLE_INIT -void rep_setproctitle_init(int argc, char *argv[], char *envp[]) -{ -} -#endif - -#ifndef HAVE_MEMSET_S -# ifndef RSIZE_MAX -# define RSIZE_MAX (SIZE_MAX >> 1) -# endif - -int rep_memset_s(void *dest, size_t destsz, int ch, size_t count) -{ - if (dest == NULL) { - return EINVAL; - } - - if (destsz > RSIZE_MAX || - count > RSIZE_MAX || - count > destsz) { - return ERANGE; - } - -#if defined(HAVE_MEMSET_EXPLICIT) - memset_explicit(dest, destsz, ch, count); -#else /* HAVE_MEMSET_EXPLICIT */ - memset(dest, ch, count); -# if defined(HAVE_GCC_VOLATILE_MEMORY_PROTECTION) - /* See http://llvm.org/bugs/show_bug.cgi?id=15495 */ - __asm__ volatile("" : : "g"(dest) : "memory"); -# endif /* HAVE_GCC_VOLATILE_MEMORY_PROTECTION */ -#endif /* HAVE_MEMSET_EXPLICIT */ - - return 0; -} -#endif /* HAVE_MEMSET_S */ - -#ifndef HAVE_GETPROGNAME -# ifndef HAVE_PROGRAM_INVOCATION_SHORT_NAME -# define PROGNAME_SIZE 32 -static char rep_progname[PROGNAME_SIZE]; -# endif /* HAVE_PROGRAM_INVOCATION_SHORT_NAME */ - -const char *rep_getprogname(void) -{ -#ifdef HAVE_PROGRAM_INVOCATION_SHORT_NAME - return program_invocation_short_name; -#else /* HAVE_PROGRAM_INVOCATION_SHORT_NAME */ - FILE *fp = NULL; - char cmdline[4096] = {0}; - char *p = NULL; - pid_t pid; - size_t nread; - int len; - int rc; - - if (rep_progname[0] != '\0') { - return rep_progname; - } - - len = snprintf(rep_progname, sizeof(rep_progname), "%s", ""); - if (len <= 0) { - return NULL; - } - - pid = getpid(); - if (pid <= 1 || pid == (pid_t)-1) { - return NULL; - } - - len = snprintf(cmdline, - sizeof(cmdline), - "/proc/%u/cmdline", - (unsigned int)pid); - if (len <= 0 || len == sizeof(cmdline)) { - return NULL; - } - - fp = fopen(cmdline, "r"); - if (fp == NULL) { - return NULL; - } - - nread = fread(cmdline, 1, sizeof(cmdline) - 1, fp); - - rc = fclose(fp); - if (rc != 0) { - return NULL; - } - - if (nread == 0) { - return NULL; - } - - cmdline[nread] = '\0'; - - p = strrchr(cmdline, '/'); - if (p != NULL) { - p++; - } else { - p = cmdline; - } - - len = strlen(p); - if (len > PROGNAME_SIZE) { - p[PROGNAME_SIZE - 1] = '\0'; - } - - (void)snprintf(rep_progname, sizeof(rep_progname), "%s", p); - - return rep_progname; -#endif /* HAVE_PROGRAM_INVOCATION_SHORT_NAME */ -} -#endif /* HAVE_GETPROGNAME */ diff --git a/ldb-2.0.8/lib/replace/replace.h b/ldb-2.0.8/lib/replace/replace.h deleted file mode 100644 index 1658465..0000000 --- a/ldb-2.0.8/lib/replace/replace.h +++ /dev/null @@ -1,976 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - macros to go along with the lib/replace/ portability layer code - - Copyright (C) Andrew Tridgell 2005 - Copyright (C) Jelmer Vernooij 2006-2008 - Copyright (C) Jeremy Allison 2007. - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#ifndef _LIBREPLACE_REPLACE_H -#define _LIBREPLACE_REPLACE_H - -#ifndef NO_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_STANDARDS_H -#include -#endif - -/* - * Needs to be defined before std*.h and string*.h are included - * As it's also needed when Python.h is the first header we - * require a global -D__STDC_WANT_LIB_EXT1__=1 - */ -#ifndef __STDC_WANT_LIB_EXT1__ -#error -D__STDC_WANT_LIB_EXT1__=1 required -#endif - -#include -#include -#include -#include - -#ifndef HAVE_DECL_EWOULDBLOCK -#define EWOULDBLOCK EAGAIN -#endif - -#if defined(_MSC_VER) || defined(__MINGW32__) -#include "win32_replace.h" -#endif - - -#ifdef HAVE_INTTYPES_H -#define __STDC_FORMAT_MACROS -#include -#elif defined(HAVE_STDINT_H) -#include -/* force off HAVE_INTTYPES_H so that roken doesn't try to include both, - which causes a warning storm on irix */ -#undef HAVE_INTTYPES_H -#endif - -#ifdef HAVE_MALLOC_H -#include -#endif - -#ifndef __PRI64_PREFIX -# if __WORDSIZE == 64 && ! defined __APPLE__ -# define __PRI64_PREFIX "l" -# else -# define __PRI64_PREFIX "ll" -# endif -#endif - -/* Decimal notation. */ -#ifndef PRId8 -# define PRId8 "d" -#endif -#ifndef PRId16 -# define PRId16 "d" -#endif -#ifndef PRId32 -# define PRId32 "d" -#endif -#ifndef PRId64 -# define PRId64 __PRI64_PREFIX "d" -#endif - -#ifndef PRIi8 -# define PRIi8 "i" -#endif -#ifndef PRIi16 -# define PRIi16 "i" -#endif -#ifndef PRIi32 -# define PRIi32 "i" -#endif -#ifndef PRIi64 -# define PRIi64 __PRI64_PREFIX "i" -#endif - -#ifndef PRIu8 -# define PRIu8 "u" -#endif -#ifndef PRIu16 -# define PRIu16 "u" -#endif -#ifndef PRIu32 -# define PRIu32 "u" -#endif -#ifndef PRIu64 -# define PRIu64 __PRI64_PREFIX "u" -#endif - -#ifndef SCNd8 -# define SCNd8 "hhd" -#endif -#ifndef SCNd16 -# define SCNd16 "hd" -#endif -#ifndef SCNd32 -# define SCNd32 "d" -#endif -#ifndef SCNd64 -# define SCNd64 __PRI64_PREFIX "d" -#endif - -#ifndef SCNi8 -# define SCNi8 "hhi" -#endif -#ifndef SCNi16 -# define SCNi16 "hi" -#endif -#ifndef SCNi32 -# define SCNi32 "i" -#endif -#ifndef SCNi64 -# define SCNi64 __PRI64_PREFIX "i" -#endif - -#ifndef SCNu8 -# define SCNu8 "hhu" -#endif -#ifndef SCNu16 -# define SCNu16 "hu" -#endif -#ifndef SCNu32 -# define SCNu32 "u" -#endif -#ifndef SCNu64 -# define SCNu64 __PRI64_PREFIX "u" -#endif - -#ifdef HAVE_BSD_STRING_H -#include -#endif - -#ifdef HAVE_BSD_UNISTD_H -#include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef HAVE_STRING_H -#include -#endif - -#ifdef HAVE_STRINGS_H -#include -#endif - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef HAVE_SYS_SYSMACROS_H -#include -#endif - -#ifdef HAVE_SETPROCTITLE_H -#include -#endif - -#if STDC_HEADERS -#include -#include -#endif - -#ifdef HAVE_LINUX_TYPES_H -/* - * This is needed as some broken header files require this to be included early - */ -#include -#endif - -#ifndef HAVE_STRERROR -extern char *sys_errlist[]; -#define strerror(i) sys_errlist[i] -#endif - -#ifndef HAVE_ERRNO_DECL -extern int errno; -#endif - -#ifndef HAVE_STRDUP -#define strdup rep_strdup -char *rep_strdup(const char *s); -#endif - -#ifndef HAVE_MEMMOVE -#define memmove rep_memmove -void *rep_memmove(void *dest,const void *src,int size); -#endif - -#ifndef HAVE_MEMMEM -#define memmem rep_memmem -void *rep_memmem(const void *haystack, size_t haystacklen, - const void *needle, size_t needlelen); -#endif - -#ifndef HAVE_MEMALIGN -#define memalign rep_memalign -void *rep_memalign(size_t boundary, size_t size); -#endif - -#ifndef HAVE_MKTIME -#define mktime rep_mktime -/* prototype is in "system/time.h" */ -#endif - -#ifndef HAVE_TIMEGM -#define timegm rep_timegm -/* prototype is in "system/time.h" */ -#endif - -#ifndef HAVE_UTIME -#define utime rep_utime -/* prototype is in "system/time.h" */ -#endif - -#ifndef HAVE_UTIMES -#define utimes rep_utimes -/* prototype is in "system/time.h" */ -#endif - -#ifndef HAVE_STRLCPY -#define strlcpy rep_strlcpy -size_t rep_strlcpy(char *d, const char *s, size_t bufsize); -#endif - -#ifndef HAVE_STRLCAT -#define strlcat rep_strlcat -size_t rep_strlcat(char *d, const char *s, size_t bufsize); -#endif - -#ifndef HAVE_CLOSEFROM -#define closefrom rep_closefrom -int rep_closefrom(int lower); -#endif - - -#if (defined(BROKEN_STRNDUP) || !defined(HAVE_STRNDUP)) -#undef HAVE_STRNDUP -#define strndup rep_strndup -char *rep_strndup(const char *s, size_t n); -#endif - -#if (defined(BROKEN_STRNLEN) || !defined(HAVE_STRNLEN)) -#undef HAVE_STRNLEN -#define strnlen rep_strnlen -size_t rep_strnlen(const char *s, size_t n); -#endif - -#if !defined(HAVE_DECL_ENVIRON) -# ifdef __APPLE__ -# include -# define environ (*_NSGetEnviron()) -# else /* __APPLE__ */ -extern char **environ; -# endif /* __APPLE */ -#endif /* !defined(HAVE_DECL_ENVIRON) */ - -#ifndef HAVE_SETENV -#define setenv rep_setenv -int rep_setenv(const char *name, const char *value, int overwrite); -#else -#ifndef HAVE_SETENV_DECL -int setenv(const char *name, const char *value, int overwrite); -#endif -#endif - -#ifndef HAVE_UNSETENV -#define unsetenv rep_unsetenv -int rep_unsetenv(const char *name); -#endif - -#ifndef HAVE_SETEUID -#define seteuid rep_seteuid -int rep_seteuid(uid_t); -#endif - -#ifndef HAVE_SETEGID -#define setegid rep_setegid -int rep_setegid(gid_t); -#endif - -#if (defined(USE_SETRESUID) && !defined(HAVE_SETRESUID_DECL)) -/* stupid glibc */ -int setresuid(uid_t ruid, uid_t euid, uid_t suid); -#endif -#if (defined(USE_SETRESUID) && !defined(HAVE_SETRESGID_DECL)) -int setresgid(gid_t rgid, gid_t egid, gid_t sgid); -#endif - -#ifndef HAVE_CHOWN -#define chown rep_chown -int rep_chown(const char *path, uid_t uid, gid_t gid); -#endif - -#ifndef HAVE_CHROOT -#define chroot rep_chroot -int rep_chroot(const char *dirname); -#endif - -#ifndef HAVE_LINK -#define link rep_link -int rep_link(const char *oldpath, const char *newpath); -#endif - -#ifndef HAVE_READLINK -#define readlink rep_readlink -ssize_t rep_readlink(const char *path, char *buf, size_t bufsize); -#endif - -#ifndef HAVE_SYMLINK -#define symlink rep_symlink -int rep_symlink(const char *oldpath, const char *newpath); -#endif - -#ifndef HAVE_REALPATH -#define realpath rep_realpath -char *rep_realpath(const char *path, char *resolved_path); -#endif - -#ifndef HAVE_LCHOWN -#define lchown rep_lchown -int rep_lchown(const char *fname,uid_t uid,gid_t gid); -#endif - -#ifdef HAVE_UNIX_H -#include -#endif - -#ifndef HAVE_SETLINEBUF -#define setlinebuf rep_setlinebuf -void rep_setlinebuf(FILE *); -#endif - -#ifndef HAVE_STRCASESTR -#define strcasestr rep_strcasestr -char *rep_strcasestr(const char *haystack, const char *needle); -#endif - -#ifndef HAVE_STRSEP -#define strsep rep_strsep -char *rep_strsep(char **pps, const char *delim); -#endif - -#ifndef HAVE_STRTOK_R -#define strtok_r rep_strtok_r -char *rep_strtok_r(char *s, const char *delim, char **save_ptr); -#endif - - - -#ifndef HAVE_STRTOLL -#define strtoll rep_strtoll -long long int rep_strtoll(const char *str, char **endptr, int base); -#else -#ifdef HAVE_BSD_STRTOLL -#define strtoll rep_strtoll -long long int rep_strtoll(const char *str, char **endptr, int base); -#endif -#endif - -#ifndef HAVE_STRTOULL -#define strtoull rep_strtoull -unsigned long long int rep_strtoull(const char *str, char **endptr, int base); -#else -#ifdef HAVE_BSD_STRTOLL /* yes, it's not HAVE_BSD_STRTOULL */ -#define strtoull rep_strtoull -unsigned long long int rep_strtoull(const char *str, char **endptr, int base); -#endif -#endif - -#ifndef HAVE_FTRUNCATE -#define ftruncate rep_ftruncate -int rep_ftruncate(int,off_t); -#endif - -#ifndef HAVE_INITGROUPS -#define initgroups rep_initgroups -int rep_initgroups(char *name, gid_t id); -#endif - -#if !defined(HAVE_BZERO) && defined(HAVE_MEMSET) -#define bzero(a,b) memset((a),'\0',(b)) -#endif - -#ifndef HAVE_DLERROR -#define dlerror rep_dlerror -char *rep_dlerror(void); -#endif - -#ifndef HAVE_DLOPEN -#define dlopen rep_dlopen -#ifdef DLOPEN_TAKES_UNSIGNED_FLAGS -void *rep_dlopen(const char *name, unsigned int flags); -#else -void *rep_dlopen(const char *name, int flags); -#endif -#endif - -#ifndef HAVE_DLSYM -#define dlsym rep_dlsym -void *rep_dlsym(void *handle, const char *symbol); -#endif - -#ifndef HAVE_DLCLOSE -#define dlclose rep_dlclose -int rep_dlclose(void *handle); -#endif - -#ifndef HAVE_SOCKETPAIR -#define socketpair rep_socketpair -/* prototype is in system/network.h */ -#endif - -#ifndef PRINTF_ATTRIBUTE -#ifdef HAVE___ATTRIBUTE__ -/** Use gcc attribute to check printf fns. a1 is the 1-based index of - * the parameter containing the format, and a2 the index of the first - * argument. Note that some gcc 2.x versions don't handle this - * properly **/ -#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) -#else -#define PRINTF_ATTRIBUTE(a1, a2) -#endif -#endif - -#ifndef _DEPRECATED_ -#ifdef HAVE___ATTRIBUTE__ -#define _DEPRECATED_ __attribute__ ((deprecated)) -#else -#define _DEPRECATED_ -#endif -#endif - -#if !defined(HAVE_VDPRINTF) || !defined(HAVE_C99_VSNPRINTF) -#define vdprintf rep_vdprintf -int rep_vdprintf(int fd, const char *format, va_list ap) PRINTF_ATTRIBUTE(2,0); -#endif - -#if !defined(HAVE_DPRINTF) || !defined(HAVE_C99_VSNPRINTF) -#define dprintf rep_dprintf -int rep_dprintf(int fd, const char *format, ...) PRINTF_ATTRIBUTE(2,3); -#endif - -#if !defined(HAVE_VASPRINTF) || !defined(HAVE_C99_VSNPRINTF) -#define vasprintf rep_vasprintf -int rep_vasprintf(char **ptr, const char *format, va_list ap) PRINTF_ATTRIBUTE(2,0); -#endif - -#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF) -#define snprintf rep_snprintf -int rep_snprintf(char *,size_t ,const char *, ...) PRINTF_ATTRIBUTE(3,4); -#endif - -#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF) -#define vsnprintf rep_vsnprintf -int rep_vsnprintf(char *,size_t ,const char *, va_list ap) PRINTF_ATTRIBUTE(3,0); -#endif - -#if !defined(HAVE_ASPRINTF) || !defined(HAVE_C99_VSNPRINTF) -#define asprintf rep_asprintf -int rep_asprintf(char **,const char *, ...) PRINTF_ATTRIBUTE(2,3); -#endif - -#if !defined(HAVE_C99_VSNPRINTF) -#ifdef REPLACE_BROKEN_PRINTF -/* - * We do not redefine printf by default - * as it breaks the build if system headers - * use __attribute__((format(printf, 3, 0))) - * instead of __attribute__((format(__printf__, 3, 0))) - */ -#define printf rep_printf -#endif -int rep_printf(const char *, ...) PRINTF_ATTRIBUTE(1,2); -#endif - -#if !defined(HAVE_C99_VSNPRINTF) -#define fprintf rep_fprintf -int rep_fprintf(FILE *stream, const char *, ...) PRINTF_ATTRIBUTE(2,3); -#endif - -#ifndef HAVE_VSYSLOG -#ifdef HAVE_SYSLOG -#define vsyslog rep_vsyslog -void rep_vsyslog (int facility_priority, const char *format, va_list arglist) PRINTF_ATTRIBUTE(2,0); -#endif -#endif - -/* we used to use these fns, but now we have good replacements - for snprintf and vsnprintf */ -#define slprintf snprintf - - -#ifndef HAVE_VA_COPY -#undef va_copy -#ifdef HAVE___VA_COPY -#define va_copy(dest, src) __va_copy(dest, src) -#else -#define va_copy(dest, src) (dest) = (src) -#endif -#endif - -#ifndef HAVE_VOLATILE -#define volatile -#endif - -#ifndef HAVE_COMPARISON_FN_T -typedef int (*comparison_fn_t)(const void *, const void *); -#endif - -#ifndef HAVE_WORKING_STRPTIME -#define strptime rep_strptime -struct tm; -char *rep_strptime(const char *buf, const char *format, struct tm *tm); -#endif - -#ifndef HAVE_DUP2 -#define dup2 rep_dup2 -int rep_dup2(int oldfd, int newfd); -#endif - -/* Load header file for dynamic linking stuff */ -#ifdef HAVE_DLFCN_H -#include -#endif - -#ifndef RTLD_LAZY -#define RTLD_LAZY 0 -#endif -#ifndef RTLD_NOW -#define RTLD_NOW 0 -#endif -#ifndef RTLD_GLOBAL -#define RTLD_GLOBAL 0 -#endif - -#ifndef HAVE_SECURE_MKSTEMP -#define mkstemp(path) rep_mkstemp(path) -int rep_mkstemp(char *temp); -#endif - -#ifndef HAVE_MKDTEMP -#define mkdtemp rep_mkdtemp -char *rep_mkdtemp(char *template); -#endif - -#ifndef HAVE_PREAD -#define pread rep_pread -ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset); -#define LIBREPLACE_PREAD_REPLACED 1 -#else -#define LIBREPLACE_PREAD_NOT_REPLACED 1 -#endif - -#ifndef HAVE_PWRITE -#define pwrite rep_pwrite -ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset); -#define LIBREPLACE_PWRITE_REPLACED 1 -#else -#define LIBREPLACE_PWRITE_NOT_REPLACED 1 -#endif - -#if !defined(HAVE_INET_NTOA) || defined(REPLACE_INET_NTOA) -#define inet_ntoa rep_inet_ntoa -/* prototype is in "system/network.h" */ -#endif - -#ifndef HAVE_INET_PTON -#define inet_pton rep_inet_pton -/* prototype is in "system/network.h" */ -#endif - -#ifndef HAVE_INET_NTOP -#define inet_ntop rep_inet_ntop -/* prototype is in "system/network.h" */ -#endif - -#ifndef HAVE_INET_ATON -#define inet_aton rep_inet_aton -/* prototype is in "system/network.h" */ -#endif - -#ifndef HAVE_CONNECT -#define connect rep_connect -/* prototype is in "system/network.h" */ -#endif - -#ifndef HAVE_GETHOSTBYNAME -#define gethostbyname rep_gethostbyname -/* prototype is in "system/network.h" */ -#endif - -#ifndef HAVE_GETIFADDRS -#define getifaddrs rep_getifaddrs -/* prototype is in "system/network.h" */ -#endif - -#ifndef HAVE_FREEIFADDRS -#define freeifaddrs rep_freeifaddrs -/* prototype is in "system/network.h" */ -#endif - -#ifndef HAVE_GET_CURRENT_DIR_NAME -#define get_current_dir_name rep_get_current_dir_name -char *rep_get_current_dir_name(void); -#endif - -#if (!defined(HAVE_STRERROR_R) || !defined(STRERROR_R_XSI_NOT_GNU)) -#define strerror_r rep_strerror_r -int rep_strerror_r(int errnum, char *buf, size_t buflen); -#endif - -#if !defined(HAVE_CLOCK_GETTIME) -#define clock_gettime rep_clock_gettime -#endif - -#ifdef HAVE_LIMITS_H -#include -#endif - -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -/* The extra casts work around common compiler bugs. */ -#define _TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) -/* The outer cast is needed to work around a bug in Cray C 5.0.3.0. - It is necessary at least when t == time_t. */ -#define _TYPE_MINIMUM(t) ((t) (_TYPE_SIGNED (t) \ - ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0)) -#define _TYPE_MAXIMUM(t) ((t) (~ (t) 0 - _TYPE_MINIMUM (t))) - -#ifndef UINT16_MAX -#define UINT16_MAX 65535 -#endif - -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#ifndef UINT64_MAX -#define UINT64_MAX ((uint64_t)-1) -#endif - -#ifndef INT64_MAX -#define INT64_MAX 9223372036854775807LL -#endif - -#ifndef CHAR_BIT -#define CHAR_BIT 8 -#endif - -#ifndef INT32_MAX -#define INT32_MAX _TYPE_MAXIMUM(int32_t) -#endif - -#ifdef HAVE_STDBOOL_H -#include -#endif - -#if !defined(HAVE_BOOL) -#ifdef HAVE__Bool -#define bool _Bool -#else -typedef int bool; -#endif -#endif - -#if !defined(HAVE_INTPTR_T) -typedef long long intptr_t ; -#define __intptr_t_defined -#endif - -#if !defined(HAVE_UINTPTR_T) -typedef unsigned long long uintptr_t ; -#define __uintptr_t_defined -#endif - -#if !defined(HAVE_PTRDIFF_T) -typedef unsigned long long ptrdiff_t ; -#endif - -/* - * to prevent from doing a redefine of 'bool' - * - * IRIX, HPUX, MacOS 10 and Solaris need BOOL_DEFINED - * Tru64 needs _BOOL_EXISTS - * AIX needs _BOOL,_TRUE,_FALSE - */ -#ifndef BOOL_DEFINED -#define BOOL_DEFINED -#endif -#ifndef _BOOL_EXISTS -#define _BOOL_EXISTS -#endif -#ifndef _BOOL -#define _BOOL -#endif - -#ifndef __bool_true_false_are_defined -#define __bool_true_false_are_defined -#endif - -#ifndef true -#define true (1) -#endif -#ifndef false -#define false (0) -#endif - -#ifndef _TRUE -#define _TRUE true -#endif -#ifndef _FALSE -#define _FALSE false -#endif - -#ifndef HAVE_FUNCTION_MACRO -#ifdef HAVE_func_MACRO -#define __FUNCTION__ __func__ -#else -#define __FUNCTION__ ("") -#endif -#endif - - -#ifndef MIN -#define MIN(a,b) ((a)<(b)?(a):(b)) -#endif - -#ifndef MAX -#define MAX(a,b) ((a)>(b)?(a):(b)) -#endif - -#if !defined(HAVE_VOLATILE) -#define volatile -#endif - -/** - this is a warning hack. The idea is to use this everywhere that we - get the "discarding const" warning from gcc. That doesn't actually - fix the problem of course, but it means that when we do get to - cleaning them up we can do it by searching the code for - discard_const. - - It also means that other error types aren't as swamped by the noise - of hundreds of const warnings, so we are more likely to notice when - we get new errors. - - Please only add more uses of this macro when you find it - _really_ hard to fix const warnings. Our aim is to eventually use - this function in only a very few places. - - Also, please call this via the discard_const_p() macro interface, as that - makes the return type safe. -*/ -#define discard_const(ptr) ((void *)((uintptr_t)(ptr))) - -/** Type-safe version of discard_const */ -#define discard_const_p(type, ptr) ((type *)discard_const(ptr)) - -#ifndef __STRING -#define __STRING(x) #x -#endif - -#ifndef __STRINGSTRING -#define __STRINGSTRING(x) __STRING(x) -#endif - -#ifndef __LINESTR__ -#define __LINESTR__ __STRINGSTRING(__LINE__) -#endif - -#ifndef __location__ -#define __location__ __FILE__ ":" __LINESTR__ -#endif - -/** - * Zero a structure. - */ -#define ZERO_STRUCT(x) memset_s((char *)&(x), sizeof(x), 0, sizeof(x)) - -/** - * Zero a structure given a pointer to the structure. - */ -#define ZERO_STRUCTP(x) do { \ - if ((x) != NULL) { \ - memset_s((char *)(x), sizeof(*(x)), 0, sizeof(*(x))); \ - } \ -} while(0) - -/** - * Zero a structure given a pointer to the structure - no zero check - */ -#define ZERO_STRUCTPN(x) memset_s((char *)(x), sizeof(*(x)), 0, sizeof(*(x))) - -/** - * Zero an array - note that sizeof(array) must work - ie. it must not be a - * pointer - */ -#define ZERO_ARRAY(x) memset_s((char *)(x), sizeof(x), 0, sizeof(x)) - -/** - * Zero a given len of an array - */ -#define ZERO_ARRAY_LEN(x, l) memset_s((char *)(x), (l), 0, (l)) - -/** - * Work out how many elements there are in a static array. - */ -#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) - -/** - * Pointer difference macro - */ -#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((const char *)(p1)) - (const char *)(p2))) - -#ifdef __COMPAR_FN_T -#define QSORT_CAST (__compar_fn_t) -#endif - -#ifndef QSORT_CAST -#define QSORT_CAST (int (*)(const void *, const void *)) -#endif - -#ifndef PATH_MAX -#define PATH_MAX 1024 -#endif - -#ifndef MAX_DNS_NAME_LENGTH -#define MAX_DNS_NAME_LENGTH 256 /* Actually 255 but +1 for terminating null. */ -#endif - -#ifndef HAVE_CRYPT -char *ufc_crypt(const char *key, const char *salt); -#define crypt ufc_crypt -#else -#ifdef HAVE_CRYPT_H -#include -#endif -#endif - -/* these macros gain us a few percent of speed on gcc */ -#if (__GNUC__ >= 3) -/* the strange !! is to ensure that __builtin_expect() takes either 0 or 1 - as its first argument */ -#ifndef likely -#define likely(x) __builtin_expect(!!(x), 1) -#endif -#ifndef unlikely -#define unlikely(x) __builtin_expect(!!(x), 0) -#endif -#else -#ifndef likely -#define likely(x) (x) -#endif -#ifndef unlikely -#define unlikely(x) (x) -#endif -#endif - -#ifndef HAVE_FDATASYNC -#define fdatasync(fd) fsync(fd) -#elif !defined(HAVE_DECL_FDATASYNC) -int fdatasync(int ); -#endif - -/* these are used to mark symbols as local to a shared lib, or - * publicly available via the shared lib API */ -#ifndef _PUBLIC_ -#ifdef HAVE_VISIBILITY_ATTR -#define _PUBLIC_ __attribute__((visibility("default"))) -#else -#define _PUBLIC_ -#endif -#endif - -#ifndef _PRIVATE_ -#ifdef HAVE_VISIBILITY_ATTR -# define _PRIVATE_ __attribute__((visibility("hidden"))) -#else -# define _PRIVATE_ -#endif -#endif - -#ifndef HAVE_POLL -#define poll rep_poll -/* prototype is in "system/network.h" */ -#endif - -#ifndef HAVE_GETPEEREID -#define getpeereid rep_getpeereid -int rep_getpeereid(int s, uid_t *uid, gid_t *gid); -#endif - -#ifndef HAVE_USLEEP -#define usleep rep_usleep -typedef long useconds_t; -int usleep(useconds_t); -#endif - -#ifndef HAVE_SETPROCTITLE -#define setproctitle rep_setproctitle -void rep_setproctitle(const char *fmt, ...) PRINTF_ATTRIBUTE(1, 2); -#endif - -#ifndef HAVE_SETPROCTITLE_INIT -#define setproctitle_init rep_setproctitle_init -void rep_setproctitle_init(int argc, char *argv[], char *envp[]); -#endif - -#ifndef HAVE_MEMSET_S -#define memset_s rep_memset_s -int rep_memset_s(void *dest, size_t destsz, int ch, size_t count); -#endif - -#ifndef HAVE_GETPROGNAME -#define getprogname rep_getprogname -const char *rep_getprogname(void); -#endif - -#ifndef FALL_THROUGH -# ifdef HAVE_FALLTHROUGH_ATTRIBUTE -# define FALL_THROUGH __attribute__ ((fallthrough)) -# else /* HAVE_FALLTHROUGH_ATTRIBUTE */ -# define FALL_THROUGH ((void)0) -# endif /* HAVE_FALLTHROUGH_ATTRIBUTE */ -#endif /* FALL_THROUGH */ - -bool nss_wrapper_enabled(void); -bool nss_wrapper_hosts_enabled(void); -bool socket_wrapper_enabled(void); -bool uid_wrapper_enabled(void); - -/* Needed for Solaris atomic_add_XX functions. */ -#if defined(HAVE_SYS_ATOMIC_H) -#include -#endif - -#endif /* _LIBREPLACE_REPLACE_H */ diff --git a/ldb-2.0.8/lib/replace/snprintf.c b/ldb-2.0.8/lib/replace/snprintf.c deleted file mode 100644 index 6e4424b..0000000 --- a/ldb-2.0.8/lib/replace/snprintf.c +++ /dev/null @@ -1,1534 +0,0 @@ -/* - * NOTE: If you change this file, please merge it into rsync, samba, etc. - */ - -/* - * Copyright Patrick Powell 1995 - * This code is based on code written by Patrick Powell (papowell@astart.com) - * It may be used for any purpose as long as this notice remains intact - * on all source code distributions - */ - -/************************************************************** - * Original: - * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 - * A bombproof version of doprnt (dopr) included. - * Sigh. This sort of thing is always nasty do deal with. Note that - * the version here does not include floating point... - * - * snprintf() is used instead of sprintf() as it does limit checks - * for string length. This covers a nasty loophole. - * - * The other functions are there to prevent NULL pointers from - * causing nast effects. - * - * More Recently: - * Brandon Long 9/15/96 for mutt 0.43 - * This was ugly. It is still ugly. I opted out of floating point - * numbers, but the formatter understands just about everything - * from the normal C string format, at least as far as I can tell from - * the Solaris 2.5 printf(3S) man page. - * - * Brandon Long 10/22/97 for mutt 0.87.1 - * Ok, added some minimal floating point support, which means this - * probably requires libm on most operating systems. Don't yet - * support the exponent (e,E) and sigfig (g,G). Also, fmtint() - * was pretty badly broken, it just wasn't being exercised in ways - * which showed it, so that's been fixed. Also, formatted the code - * to mutt conventions, and removed dead code left over from the - * original. Also, there is now a builtin-test, just compile with: - * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm - * and run snprintf for results. - * - * Thomas Roessler 01/27/98 for mutt 0.89i - * The PGP code was using unsigned hexadecimal formats. - * Unfortunately, unsigned formats simply didn't work. - * - * Michael Elkins 03/05/98 for mutt 0.90.8 - * The original code assumed that both snprintf() and vsnprintf() were - * missing. Some systems only have snprintf() but not vsnprintf(), so - * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. - * - * Andrew Tridgell (tridge@samba.org) Oct 1998 - * fixed handling of %.0f - * added test for HAVE_LONG_DOUBLE - * - * tridge@samba.org, idra@samba.org, April 2001 - * got rid of fcvt code (twas buggy and made testing harder) - * added C99 semantics - * - * date: 2002/12/19 19:56:31; author: herb; state: Exp; lines: +2 -0 - * actually print args for %g and %e - * - * date: 2002/06/03 13:37:52; author: jmcd; state: Exp; lines: +8 -0 - * Since includes.h isn't included here, VA_COPY has to be defined here. I don't - * see any include file that is guaranteed to be here, so I'm defining it - * locally. Fixes AIX and Solaris builds. - * - * date: 2002/06/03 03:07:24; author: tridge; state: Exp; lines: +5 -13 - * put the ifdef for HAVE_VA_COPY in one place rather than in lots of - * functions - * - * date: 2002/05/17 14:51:22; author: jmcd; state: Exp; lines: +21 -4 - * Fix usage of va_list passed as an arg. Use __va_copy before using it - * when it exists. - * - * date: 2002/04/16 22:38:04; author: idra; state: Exp; lines: +20 -14 - * Fix incorrect zpadlen handling in fmtfp. - * Thanks to Ollie Oldham for spotting it. - * few mods to make it easier to compile the tests. - * addedd the "Ollie" test to the floating point ones. - * - * Martin Pool (mbp@samba.org) April 2003 - * Remove NO_CONFIG_H so that the test case can be built within a source - * tree with less trouble. - * Remove unnecessary SAFE_FREE() definition. - * - * Martin Pool (mbp@samba.org) May 2003 - * Put in a prototype for dummy_snprintf() to quiet compiler warnings. - * - * Move #endif to make sure VA_COPY, LDOUBLE, etc are defined even - * if the C library has some snprintf functions already. - * - * Darren Tucker (dtucker@zip.com.au) 2005 - * Fix bug allowing read overruns of the source string with "%.*s" - * Usually harmless unless the read runs outside the process' allocation - * (eg if your malloc does guard pages) in which case it will segfault. - * From OpenSSH. Also added test for same. - * - * Simo Sorce (idra@samba.org) Jan 2006 - * - * Add support for position independent parameters - * fix fmtstr now it conforms to sprintf wrt min.max - * - **************************************************************/ - -#include "replace.h" -#include "system/locale.h" - -#ifdef TEST_SNPRINTF /* need math library headers for testing */ - -/* In test mode, we pretend that this system doesn't have any snprintf - * functions, regardless of what config.h says. */ -# undef HAVE_SNPRINTF -# undef HAVE_VSNPRINTF -# undef HAVE_C99_VSNPRINTF -# undef HAVE_ASPRINTF -# undef HAVE_VASPRINTF -# include -#endif /* TEST_SNPRINTF */ - -#if defined(HAVE_SNPRINTF) && defined(HAVE_VSNPRINTF) && defined(HAVE_C99_VSNPRINTF) -/* only include stdio.h if we are not re-defining snprintf or vsnprintf */ -#include - /* make the compiler happy with an empty file */ - void dummy_snprintf(void); - void dummy_snprintf(void) {} -#endif /* HAVE_SNPRINTF, etc */ - -/* yes this really must be a ||. Don't muck with this (tridge) */ -#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF) - -#ifdef HAVE_LONG_DOUBLE -#define LDOUBLE long double -#else -#define LDOUBLE double -#endif - -#ifdef HAVE_LONG_LONG -#define LLONG long long -#else -#define LLONG long -#endif - -#ifndef VA_COPY -#ifdef HAVE_VA_COPY -#define VA_COPY(dest, src) va_copy(dest, src) -#else -#ifdef HAVE___VA_COPY -#define VA_COPY(dest, src) __va_copy(dest, src) -#else -#define VA_COPY(dest, src) (dest) = (src) -#endif -#endif - -/* - * dopr(): poor man's version of doprintf - */ - -/* format read states */ -#define DP_S_DEFAULT 0 -#define DP_S_FLAGS 1 -#define DP_S_MIN 2 -#define DP_S_DOT 3 -#define DP_S_MAX 4 -#define DP_S_MOD 5 -#define DP_S_CONV 6 -#define DP_S_DONE 7 - -/* format flags - Bits */ -#define DP_F_MINUS (1 << 0) -#define DP_F_PLUS (1 << 1) -#define DP_F_SPACE (1 << 2) -#define DP_F_NUM (1 << 3) -#define DP_F_ZERO (1 << 4) -#define DP_F_UP (1 << 5) -#define DP_F_UNSIGNED (1 << 6) - -/* Conversion Flags */ -#define DP_C_CHAR 1 -#define DP_C_SHORT 2 -#define DP_C_LONG 3 -#define DP_C_LDOUBLE 4 -#define DP_C_LLONG 5 -#define DP_C_SIZET 6 - -/* Chunk types */ -#define CNK_FMT_STR 0 -#define CNK_INT 1 -#define CNK_OCTAL 2 -#define CNK_UINT 3 -#define CNK_HEX 4 -#define CNK_FLOAT 5 -#define CNK_CHAR 6 -#define CNK_STRING 7 -#define CNK_PTR 8 -#define CNK_NUM 9 -#define CNK_PRCNT 10 - -#define char_to_int(p) ((p)- '0') -#ifndef MAX -#define MAX(p,q) (((p) >= (q)) ? (p) : (q)) -#endif - -struct pr_chunk { - int type; /* chunk type */ - int num; /* parameter number */ - int min; - int max; - int flags; - int cflags; - int start; - int len; - LLONG value; - LDOUBLE fvalue; - char *strvalue; - void *pnum; - struct pr_chunk *min_star; - struct pr_chunk *max_star; - struct pr_chunk *next; -}; - -struct pr_chunk_x { - struct pr_chunk **chunks; - int num; -}; - -static int dopr(char *buffer, size_t maxlen, const char *format, - va_list args_in); -static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, - char *value, int flags, int min, int max); -static void fmtint(char *buffer, size_t *currlen, size_t maxlen, - LLONG value, int base, int min, int max, int flags); -static void fmtfp(char *buffer, size_t *currlen, size_t maxlen, - LDOUBLE fvalue, int min, int max, int flags); -static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); -static struct pr_chunk *new_chunk(void); -static int add_cnk_list_entry(struct pr_chunk_x **list, - int max_num, struct pr_chunk *chunk); - -static int dopr(char *buffer, size_t maxlen, const char *format, va_list args_in) -{ - char ch; - int state; - int pflag; - int pnum; - int pfirst; - size_t currlen; - va_list args; - const char *base; - struct pr_chunk *chunks = NULL; - struct pr_chunk *cnk = NULL; - struct pr_chunk_x *clist = NULL; - int max_pos; - int ret = -1; - - VA_COPY(args, args_in); - - state = DP_S_DEFAULT; - pfirst = 1; - pflag = 0; - pnum = 0; - - max_pos = 0; - base = format; - ch = *format++; - - /* retrieve the string structure as chunks */ - while (state != DP_S_DONE) { - if (ch == '\0') - state = DP_S_DONE; - - switch(state) { - case DP_S_DEFAULT: - - if (cnk) { - cnk->next = new_chunk(); - cnk = cnk->next; - } else { - cnk = new_chunk(); - } - if (!cnk) goto done; - if (!chunks) chunks = cnk; - - if (ch == '%') { - state = DP_S_FLAGS; - ch = *format++; - } else { - cnk->type = CNK_FMT_STR; - cnk->start = format - base -1; - while ((ch != '\0') && (ch != '%')) ch = *format++; - cnk->len = format - base - cnk->start -1; - } - break; - case DP_S_FLAGS: - switch (ch) { - case '-': - cnk->flags |= DP_F_MINUS; - ch = *format++; - break; - case '+': - cnk->flags |= DP_F_PLUS; - ch = *format++; - break; - case ' ': - cnk->flags |= DP_F_SPACE; - ch = *format++; - break; - case '#': - cnk->flags |= DP_F_NUM; - ch = *format++; - break; - case '0': - cnk->flags |= DP_F_ZERO; - ch = *format++; - break; - case 'I': - /* internationalization not supported yet */ - ch = *format++; - break; - default: - state = DP_S_MIN; - break; - } - break; - case DP_S_MIN: - if (isdigit((unsigned char)ch)) { - cnk->min = 10 * cnk->min + char_to_int (ch); - ch = *format++; - } else if (ch == '$') { - if (!pfirst && !pflag) { - /* parameters must be all positioned or none */ - goto done; - } - if (pfirst) { - pfirst = 0; - pflag = 1; - } - if (cnk->min == 0) /* what ?? */ - goto done; - cnk->num = cnk->min; - cnk->min = 0; - ch = *format++; - } else if (ch == '*') { - if (pfirst) pfirst = 0; - cnk->min_star = new_chunk(); - if (!cnk->min_star) /* out of memory :-( */ - goto done; - cnk->min_star->type = CNK_INT; - if (pflag) { - int num; - ch = *format++; - if (!isdigit((unsigned char)ch)) { - /* parameters must be all positioned or none */ - goto done; - } - for (num = 0; isdigit((unsigned char)ch); ch = *format++) { - num = 10 * num + char_to_int(ch); - } - cnk->min_star->num = num; - if (ch != '$') /* what ?? */ - goto done; - } else { - cnk->min_star->num = ++pnum; - } - max_pos = add_cnk_list_entry(&clist, max_pos, cnk->min_star); - if (max_pos == 0) /* out of memory :-( */ - goto done; - ch = *format++; - state = DP_S_DOT; - } else { - if (pfirst) pfirst = 0; - state = DP_S_DOT; - } - break; - case DP_S_DOT: - if (ch == '.') { - state = DP_S_MAX; - ch = *format++; - } else { - state = DP_S_MOD; - } - break; - case DP_S_MAX: - if (isdigit((unsigned char)ch)) { - if (cnk->max < 0) - cnk->max = 0; - cnk->max = 10 * cnk->max + char_to_int (ch); - ch = *format++; - } else if (ch == '$') { - if (!pfirst && !pflag) { - /* parameters must be all positioned or none */ - goto done; - } - if (cnk->max <= 0) /* what ?? */ - goto done; - cnk->num = cnk->max; - cnk->max = -1; - ch = *format++; - } else if (ch == '*') { - cnk->max_star = new_chunk(); - if (!cnk->max_star) /* out of memory :-( */ - goto done; - cnk->max_star->type = CNK_INT; - if (pflag) { - int num; - ch = *format++; - if (!isdigit((unsigned char)ch)) { - /* parameters must be all positioned or none */ - goto done; - } - for (num = 0; isdigit((unsigned char)ch); ch = *format++) { - num = 10 * num + char_to_int(ch); - } - cnk->max_star->num = num; - if (ch != '$') /* what ?? */ - goto done; - } else { - cnk->max_star->num = ++pnum; - } - max_pos = add_cnk_list_entry(&clist, max_pos, cnk->max_star); - if (max_pos == 0) /* out of memory :-( */ - goto done; - - ch = *format++; - state = DP_S_MOD; - } else { - state = DP_S_MOD; - } - break; - case DP_S_MOD: - switch (ch) { - case 'h': - cnk->cflags = DP_C_SHORT; - ch = *format++; - if (ch == 'h') { - cnk->cflags = DP_C_CHAR; - ch = *format++; - } - break; - case 'l': - cnk->cflags = DP_C_LONG; - ch = *format++; - if (ch == 'l') { /* It's a long long */ - cnk->cflags = DP_C_LLONG; - ch = *format++; - } - break; - case 'j': - cnk->cflags = DP_C_LLONG; - ch = *format++; - break; - case 'L': - cnk->cflags = DP_C_LDOUBLE; - ch = *format++; - break; - case 'z': - cnk->cflags = DP_C_SIZET; - ch = *format++; - break; - default: - break; - } - state = DP_S_CONV; - break; - case DP_S_CONV: - if (cnk->num == 0) cnk->num = ++pnum; - max_pos = add_cnk_list_entry(&clist, max_pos, cnk); - if (max_pos == 0) /* out of memory :-( */ - goto done; - - switch (ch) { - case 'd': - case 'i': - cnk->type = CNK_INT; - break; - case 'o': - cnk->type = CNK_OCTAL; - cnk->flags |= DP_F_UNSIGNED; - break; - case 'u': - cnk->type = CNK_UINT; - cnk->flags |= DP_F_UNSIGNED; - break; - case 'X': - cnk->flags |= DP_F_UP; - case 'x': - cnk->type = CNK_HEX; - cnk->flags |= DP_F_UNSIGNED; - break; - case 'A': - /* hex float not supported yet */ - case 'E': - case 'G': - case 'F': - cnk->flags |= DP_F_UP; - case 'a': - /* hex float not supported yet */ - case 'e': - case 'f': - case 'g': - cnk->type = CNK_FLOAT; - break; - case 'c': - cnk->type = CNK_CHAR; - break; - case 's': - cnk->type = CNK_STRING; - break; - case 'p': - cnk->type = CNK_PTR; - cnk->flags |= DP_F_UNSIGNED; - break; - case 'n': - cnk->type = CNK_NUM; - break; - case '%': - cnk->type = CNK_PRCNT; - break; - default: - /* Unknown, bail out*/ - goto done; - } - ch = *format++; - state = DP_S_DEFAULT; - break; - case DP_S_DONE: - break; - default: - /* hmm? */ - break; /* some picky compilers need this */ - } - } - - /* retrieve the format arguments */ - for (pnum = 0; pnum < max_pos; pnum++) { - int i; - - if (clist[pnum].num == 0) { - /* ignoring a parameter should not be permitted - * all parameters must be matched at least once - * BUT seem some system ignore this rule ... - * at least my glibc based system does --SSS - */ -#ifdef DEBUG_SNPRINTF - printf("parameter at position %d not used\n", pnum+1); -#endif - /* eat the parameter */ - va_arg (args, int); - continue; - } - for (i = 1; i < clist[pnum].num; i++) { - if (clist[pnum].chunks[0]->type != clist[pnum].chunks[i]->type) { - /* nooo noo no! - * all the references to a parameter - * must be of the same type - */ - goto done; - } - } - cnk = clist[pnum].chunks[0]; - switch (cnk->type) { - case CNK_INT: - if (cnk->cflags == DP_C_SHORT) - cnk->value = va_arg (args, int); - else if (cnk->cflags == DP_C_LONG) - cnk->value = va_arg (args, long int); - else if (cnk->cflags == DP_C_LLONG) - cnk->value = va_arg (args, LLONG); - else if (cnk->cflags == DP_C_SIZET) - cnk->value = va_arg (args, ssize_t); - else - cnk->value = va_arg (args, int); - - for (i = 1; i < clist[pnum].num; i++) { - clist[pnum].chunks[i]->value = cnk->value; - } - break; - - case CNK_OCTAL: - case CNK_UINT: - case CNK_HEX: - if (cnk->cflags == DP_C_SHORT) - cnk->value = va_arg (args, unsigned int); - else if (cnk->cflags == DP_C_LONG) - cnk->value = (unsigned long int)va_arg (args, unsigned long int); - else if (cnk->cflags == DP_C_LLONG) - cnk->value = (LLONG)va_arg (args, unsigned LLONG); - else if (cnk->cflags == DP_C_SIZET) - cnk->value = (size_t)va_arg (args, size_t); - else - cnk->value = (unsigned int)va_arg (args, unsigned int); - - for (i = 1; i < clist[pnum].num; i++) { - clist[pnum].chunks[i]->value = cnk->value; - } - break; - - case CNK_FLOAT: - if (cnk->cflags == DP_C_LDOUBLE) - cnk->fvalue = va_arg (args, LDOUBLE); - else - cnk->fvalue = va_arg (args, double); - - for (i = 1; i < clist[pnum].num; i++) { - clist[pnum].chunks[i]->fvalue = cnk->fvalue; - } - break; - - case CNK_CHAR: - cnk->value = va_arg (args, int); - - for (i = 1; i < clist[pnum].num; i++) { - clist[pnum].chunks[i]->value = cnk->value; - } - break; - - case CNK_STRING: - cnk->strvalue = va_arg (args, char *); - if (!cnk->strvalue) cnk->strvalue = "(NULL)"; - - for (i = 1; i < clist[pnum].num; i++) { - clist[pnum].chunks[i]->strvalue = cnk->strvalue; - } - break; - - case CNK_PTR: - cnk->strvalue = va_arg (args, void *); - for (i = 1; i < clist[pnum].num; i++) { - clist[pnum].chunks[i]->strvalue = cnk->strvalue; - } - break; - - case CNK_NUM: - if (cnk->cflags == DP_C_CHAR) - cnk->pnum = va_arg (args, char *); - else if (cnk->cflags == DP_C_SHORT) - cnk->pnum = va_arg (args, short int *); - else if (cnk->cflags == DP_C_LONG) - cnk->pnum = va_arg (args, long int *); - else if (cnk->cflags == DP_C_LLONG) - cnk->pnum = va_arg (args, LLONG *); - else if (cnk->cflags == DP_C_SIZET) - cnk->pnum = va_arg (args, ssize_t *); - else - cnk->pnum = va_arg (args, int *); - - for (i = 1; i < clist[pnum].num; i++) { - clist[pnum].chunks[i]->pnum = cnk->pnum; - } - break; - - case CNK_PRCNT: - break; - - default: - /* what ?? */ - goto done; - } - } - /* print out the actual string from chunks */ - currlen = 0; - cnk = chunks; - while (cnk) { - int len, min, max; - - if (cnk->min_star) min = cnk->min_star->value; - else min = cnk->min; - if (cnk->max_star) max = cnk->max_star->value; - else max = cnk->max; - - switch (cnk->type) { - - case CNK_FMT_STR: - if (maxlen != 0 && maxlen > currlen) { - if (maxlen > (currlen + cnk->len)) len = cnk->len; - else len = maxlen - currlen; - - memcpy(&(buffer[currlen]), &(base[cnk->start]), len); - } - currlen += cnk->len; - - break; - - case CNK_INT: - case CNK_UINT: - fmtint (buffer, &currlen, maxlen, cnk->value, 10, min, max, cnk->flags); - break; - - case CNK_OCTAL: - fmtint (buffer, &currlen, maxlen, cnk->value, 8, min, max, cnk->flags); - break; - - case CNK_HEX: - fmtint (buffer, &currlen, maxlen, cnk->value, 16, min, max, cnk->flags); - break; - - case CNK_FLOAT: - fmtfp (buffer, &currlen, maxlen, cnk->fvalue, min, max, cnk->flags); - break; - - case CNK_CHAR: - dopr_outch (buffer, &currlen, maxlen, cnk->value); - break; - - case CNK_STRING: - if (max == -1) { - max = strlen(cnk->strvalue); - } - fmtstr (buffer, &currlen, maxlen, cnk->strvalue, cnk->flags, min, max); - break; - - case CNK_PTR: - fmtint (buffer, &currlen, maxlen, (long)(cnk->strvalue), 16, min, max, cnk->flags); - break; - - case CNK_NUM: - if (cnk->cflags == DP_C_CHAR) - *((char *)(cnk->pnum)) = (char)currlen; - else if (cnk->cflags == DP_C_SHORT) - *((short int *)(cnk->pnum)) = (short int)currlen; - else if (cnk->cflags == DP_C_LONG) - *((long int *)(cnk->pnum)) = (long int)currlen; - else if (cnk->cflags == DP_C_LLONG) - *((LLONG *)(cnk->pnum)) = (LLONG)currlen; - else if (cnk->cflags == DP_C_SIZET) - *((ssize_t *)(cnk->pnum)) = (ssize_t)currlen; - else - *((int *)(cnk->pnum)) = (int)currlen; - break; - - case CNK_PRCNT: - dopr_outch (buffer, &currlen, maxlen, '%'); - break; - - default: - /* what ?? */ - goto done; - } - cnk = cnk->next; - } - if (maxlen != 0) { - if (currlen < maxlen - 1) - buffer[currlen] = '\0'; - else if (maxlen > 0) - buffer[maxlen - 1] = '\0'; - } - ret = currlen; - -done: - va_end(args); - - while (chunks) { - cnk = chunks->next; - free(chunks); - chunks = cnk; - } - if (clist) { - for (pnum = 0; pnum < max_pos; pnum++) { - if (clist[pnum].chunks) free(clist[pnum].chunks); - } - free(clist); - } - return ret; -} - -static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, - char *value, int flags, int min, int max) -{ - int padlen, strln; /* amount to pad */ - int cnt = 0; - -#ifdef DEBUG_SNPRINTF - printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value); -#endif - if (value == 0) { - value = ""; - } - - for (strln = 0; strln < max && value[strln]; ++strln); /* strlen */ - padlen = min - strln; - if (padlen < 0) - padlen = 0; - if (flags & DP_F_MINUS) - padlen = -padlen; /* Left Justify */ - - while (padlen > 0) { - dopr_outch (buffer, currlen, maxlen, ' '); - --padlen; - } - while (*value && (cnt < max)) { - dopr_outch (buffer, currlen, maxlen, *value++); - ++cnt; - } - while (padlen < 0) { - dopr_outch (buffer, currlen, maxlen, ' '); - ++padlen; - } -} - -/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ - -static void fmtint(char *buffer, size_t *currlen, size_t maxlen, - LLONG value, int base, int min, int max, int flags) -{ - int signvalue = 0; - unsigned LLONG uvalue; - char convert[22+1]; /* 64-bit value in octal: 22 digits + \0 */ - int place = 0; - int spadlen = 0; /* amount to space pad */ - int zpadlen = 0; /* amount to zero pad */ - int caps = 0; - - if (max < 0) - max = 0; - - uvalue = value; - - if(!(flags & DP_F_UNSIGNED)) { - if( value < 0 ) { - signvalue = '-'; - uvalue = -value; - } else { - if (flags & DP_F_PLUS) /* Do a sign (+/i) */ - signvalue = '+'; - else if (flags & DP_F_SPACE) - signvalue = ' '; - } - } - - if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ - - do { - convert[place++] = - (caps? "0123456789ABCDEF":"0123456789abcdef") - [uvalue % (unsigned)base ]; - uvalue = (uvalue / (unsigned)base ); - } while(uvalue && (place < sizeof(convert))); - if (place == sizeof(convert)) place--; - convert[place] = 0; - - zpadlen = max - place; - spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); - if (zpadlen < 0) zpadlen = 0; - if (spadlen < 0) spadlen = 0; - if (flags & DP_F_ZERO) { - zpadlen = MAX(zpadlen, spadlen); - spadlen = 0; - } - if (flags & DP_F_MINUS) - spadlen = -spadlen; /* Left Justifty */ - -#ifdef DEBUG_SNPRINTF - printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", - zpadlen, spadlen, min, max, place); -#endif - - /* Spaces */ - while (spadlen > 0) { - dopr_outch (buffer, currlen, maxlen, ' '); - --spadlen; - } - - /* Sign */ - if (signvalue) - dopr_outch (buffer, currlen, maxlen, signvalue); - - /* Zeros */ - if (zpadlen > 0) { - while (zpadlen > 0) { - dopr_outch (buffer, currlen, maxlen, '0'); - --zpadlen; - } - } - - /* Digits */ - while (place > 0) - dopr_outch (buffer, currlen, maxlen, convert[--place]); - - /* Left Justified spaces */ - while (spadlen < 0) { - dopr_outch (buffer, currlen, maxlen, ' '); - ++spadlen; - } -} - -static LDOUBLE abs_val(LDOUBLE value) -{ - LDOUBLE result = value; - - if (value < 0) - result = -value; - - return result; -} - -static LDOUBLE POW10(int exp) -{ - LDOUBLE result = 1; - - while (exp) { - result *= 10; - exp--; - } - - return result; -} - -static LLONG ROUND(LDOUBLE value) -{ - LLONG intpart; - - intpart = (LLONG)value; - value = value - intpart; - if (value >= 0.5) intpart++; - - return intpart; -} - -/* a replacement for modf that doesn't need the math library. Should - be portable, but slow */ -static double my_modf(double x0, double *iptr) -{ - int i; - LLONG l=0; - double x = x0; - double f = 1.0; - - for (i=0;i<100;i++) { - l = (long)x; - if (l <= (x+1) && l >= (x-1)) break; - x *= 0.1; - f *= 10.0; - } - - if (i == 100) { - /* yikes! the number is beyond what we can handle. What do we do? */ - (*iptr) = 0; - return 0; - } - - if (i != 0) { - double i2; - double ret; - - ret = my_modf(x0-l*f, &i2); - (*iptr) = l*f + i2; - return ret; - } - - (*iptr) = l; - return x - (*iptr); -} - - -static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, - LDOUBLE fvalue, int min, int max, int flags) -{ - int signvalue = 0; - double ufvalue; - char iconvert[311]; - char fconvert[311]; - int iplace = 0; - int fplace = 0; - int padlen = 0; /* amount to pad */ - int zpadlen = 0; - int caps = 0; - int idx; - double intpart; - double fracpart; - double temp; - - /* - * AIX manpage says the default is 0, but Solaris says the default - * is 6, and sprintf on AIX defaults to 6 - */ - if (max < 0) - max = 6; - - ufvalue = abs_val (fvalue); - - if (fvalue < 0) { - signvalue = '-'; - } else { - if (flags & DP_F_PLUS) { /* Do a sign (+/i) */ - signvalue = '+'; - } else { - if (flags & DP_F_SPACE) - signvalue = ' '; - } - } - -#if 0 - if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ -#endif - -#if 0 - if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */ -#endif - - /* - * Sorry, we only support 9 digits past the decimal because of our - * conversion method - */ - if (max > 9) - max = 9; - - /* We "cheat" by converting the fractional part to integer by - * multiplying by a factor of 10 - */ - - temp = ufvalue; - my_modf(temp, &intpart); - - fracpart = ROUND((POW10(max)) * (ufvalue - intpart)); - - if (fracpart >= POW10(max)) { - intpart++; - fracpart -= POW10(max); - } - - - /* Convert integer part */ - do { - temp = intpart*0.1; - my_modf(temp, &intpart); - idx = (int) ((temp -intpart +0.05)* 10.0); - /* idx = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */ - /* printf ("%llf, %f, %x\n", temp, intpart, idx); */ - iconvert[iplace++] = - (caps? "0123456789ABCDEF":"0123456789abcdef")[idx]; - } while (intpart && (iplace < 311)); - if (iplace == 311) iplace--; - iconvert[iplace] = 0; - - /* Convert fractional part */ - if (fracpart) - { - do { - temp = fracpart*0.1; - my_modf(temp, &fracpart); - idx = (int) ((temp -fracpart +0.05)* 10.0); - /* idx = (int) ((((temp/10) -fracpart) +0.05) *10); */ - /* printf ("%lf, %lf, %ld\n", temp, fracpart, idx ); */ - fconvert[fplace++] = - (caps? "0123456789ABCDEF":"0123456789abcdef")[idx]; - } while(fracpart && (fplace < 311)); - if (fplace == 311) fplace--; - } - fconvert[fplace] = 0; - - /* -1 for decimal point, another -1 if we are printing a sign */ - padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); - zpadlen = max - fplace; - if (zpadlen < 0) zpadlen = 0; - if (padlen < 0) - padlen = 0; - if (flags & DP_F_MINUS) - padlen = -padlen; /* Left Justifty */ - - if ((flags & DP_F_ZERO) && (padlen > 0)) { - if (signvalue) { - dopr_outch (buffer, currlen, maxlen, signvalue); - --padlen; - signvalue = 0; - } - while (padlen > 0) { - dopr_outch (buffer, currlen, maxlen, '0'); - --padlen; - } - } - while (padlen > 0) { - dopr_outch (buffer, currlen, maxlen, ' '); - --padlen; - } - if (signvalue) - dopr_outch (buffer, currlen, maxlen, signvalue); - - while (iplace > 0) - dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); - -#ifdef DEBUG_SNPRINTF - printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen); -#endif - - /* - * Decimal point. This should probably use locale to find the correct - * char to print out. - */ - if (max > 0) { - dopr_outch (buffer, currlen, maxlen, '.'); - - while (zpadlen > 0) { - dopr_outch (buffer, currlen, maxlen, '0'); - --zpadlen; - } - - while (fplace > 0) - dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); - } - - while (padlen < 0) { - dopr_outch (buffer, currlen, maxlen, ' '); - ++padlen; - } -} - -static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) -{ - if (*currlen < maxlen) { - buffer[(*currlen)] = c; - } - (*currlen)++; -} - -static struct pr_chunk *new_chunk(void) { - struct pr_chunk *new_c = (struct pr_chunk *)malloc(sizeof(struct pr_chunk)); - - if (!new_c) - return NULL; - - new_c->type = 0; - new_c->num = 0; - new_c->min = 0; - new_c->min_star = NULL; - new_c->max = -1; - new_c->max_star = NULL; - new_c->flags = 0; - new_c->cflags = 0; - new_c->start = 0; - new_c->len = 0; - new_c->value = 0; - new_c->fvalue = 0; - new_c->strvalue = NULL; - new_c->pnum = NULL; - new_c->next = NULL; - - return new_c; -} - -static int add_cnk_list_entry(struct pr_chunk_x **list, - int max_num, struct pr_chunk *chunk) { - struct pr_chunk_x *l; - struct pr_chunk **c; - int max; - int cnum; - int i, pos; - - if (chunk->num > max_num) { - max = chunk->num; - - if (*list == NULL) { - l = (struct pr_chunk_x *)malloc(sizeof(struct pr_chunk_x) * max); - pos = 0; - } else { - l = (struct pr_chunk_x *)realloc(*list, sizeof(struct pr_chunk_x) * max); - pos = max_num; - } - if (l == NULL) { - for (i = 0; i < max; i++) { - if ((*list)[i].chunks) free((*list)[i].chunks); - } - return 0; - } - for (i = pos; i < max; i++) { - l[i].chunks = NULL; - l[i].num = 0; - } - } else { - l = *list; - max = max_num; - } - - i = chunk->num - 1; - cnum = l[i].num + 1; - if (l[i].chunks == NULL) { - c = (struct pr_chunk **)malloc(sizeof(struct pr_chunk *) * cnum); - } else { - c = (struct pr_chunk **)realloc(l[i].chunks, sizeof(struct pr_chunk *) * cnum); - } - if (c == NULL) { - for (i = 0; i < max; i++) { - if (l[i].chunks) free(l[i].chunks); - } - return 0; - } - c[l[i].num] = chunk; - l[i].chunks = c; - l[i].num = cnum; - - *list = l; - return max; -} - - int rep_vsnprintf (char *str, size_t count, const char *fmt, va_list args) -{ - return dopr(str, count, fmt, args); -} -#endif - -/* yes this really must be a ||. Don't muck with this (tridge) - * - * The logic for these two is that we need our own definition if the - * OS *either* has no definition of *sprintf, or if it does have one - * that doesn't work properly according to the autoconf test. - */ -#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF) - int rep_snprintf(char *str,size_t count,const char *fmt,...) -{ - size_t ret; - va_list ap; - - va_start(ap, fmt); - ret = vsnprintf(str, count, fmt, ap); - va_end(ap); - return ret; -} -#endif - -#ifndef HAVE_C99_VSNPRINTF - int rep_printf(const char *fmt, ...) -{ - va_list ap; - int ret; - char *s; - - s = NULL; - va_start(ap, fmt); - ret = vasprintf(&s, fmt, ap); - va_end(ap); - - if (s) { - fwrite(s, 1, strlen(s), stdout); - } - free(s); - - return ret; -} -#endif - -#ifndef HAVE_C99_VSNPRINTF - int rep_fprintf(FILE *stream, const char *fmt, ...) -{ - va_list ap; - int ret; - char *s; - - s = NULL; - va_start(ap, fmt); - ret = vasprintf(&s, fmt, ap); - va_end(ap); - - if (s) { - fwrite(s, 1, strlen(s), stream); - } - free(s); - - return ret; -} -#endif - -#endif - -#if !defined(HAVE_VASPRINTF) || !defined(HAVE_C99_VSNPRINTF) - int rep_vasprintf(char **ptr, const char *format, va_list ap) -{ - int ret; - va_list ap2; - - VA_COPY(ap2, ap); - ret = vsnprintf(NULL, 0, format, ap2); - va_end(ap2); - if (ret < 0) return ret; - - (*ptr) = (char *)malloc(ret+1); - if (!*ptr) return -1; - - VA_COPY(ap2, ap); - ret = vsnprintf(*ptr, ret+1, format, ap2); - va_end(ap2); - - return ret; -} -#endif - -#if !defined(HAVE_ASPRINTF) || !defined(HAVE_C99_VSNPRINTF) - int rep_asprintf(char **ptr, const char *format, ...) -{ - va_list ap; - int ret; - - *ptr = NULL; - va_start(ap, format); - ret = vasprintf(ptr, format, ap); - va_end(ap); - - return ret; -} -#endif - -#ifdef TEST_SNPRINTF - - int sprintf(char *str,const char *fmt,...); - int printf(const char *fmt,...); - - int main (void) -{ - char buf1[1024]; - char buf2[1024]; - char *buf3; - char *fp_fmt[] = { - "%1.1f", - "%-1.5f", - "%1.5f", - "%123.9f", - "%10.5f", - "% 10.5f", - "%+22.9f", - "%+4.9f", - "%01.3f", - "%4f", - "%3.1f", - "%3.2f", - "%.0f", - "%f", - "%-8.8f", - "%-9.9f", - NULL - }; - double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 203.9, 0.96, 0.996, - 0.9996, 1.996, 4.136, 5.030201, 0.00205, - /* END LIST */ 0}; - char *int_fmt[] = { - "%-1.5d", - "%1.5d", - "%123.9d", - "%5.5d", - "%10.5d", - "% 10.5d", - "%+22.33d", - "%01.3d", - "%4d", - "%d", - NULL - }; - long int_nums[] = { -1, 134, 91340, 341, 0203, 1234567890, 0}; - char *str_fmt[] = { - "%10.5s", - "%-10.5s", - "%5.10s", - "%-5.10s", - "%10.1s", - "%0.10s", - "%10.0s", - "%1.10s", - "%s", - "%.1s", - "%.10s", - "%10s", - NULL - }; - char *str_vals[] = {"hello", "a", "", "a longer string", NULL}; -#ifdef HAVE_LONG_LONG - char *ll_fmt[] = { - "%llu", - NULL - }; - LLONG ll_nums[] = { 134, 91340, 341, 0203, 1234567890, 128006186140000000LL, 0}; -#endif - int x, y; - int fail = 0; - int num = 0; - int l1, l2; - char *ss_fmt[] = { - "%zd", - "%zu", - NULL - }; - size_t ss_nums[] = {134, 91340, 123456789, 0203, 1234567890, 0}; - - printf ("Testing snprintf format codes against system sprintf...\n"); - - for (x = 0; fp_fmt[x] ; x++) { - for (y = 0; fp_nums[y] != 0 ; y++) { - buf1[0] = buf2[0] = '\0'; - l1 = snprintf(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]); - l2 = sprintf (buf2, fp_fmt[x], fp_nums[y]); - buf1[1023] = buf2[1023] = '\0'; - if (strcmp (buf1, buf2) || (l1 != l2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", - fp_fmt[x], l1, buf1, l2, buf2); - fail++; - } - num++; - } - } - - for (x = 0; int_fmt[x] ; x++) { - for (y = 0; int_nums[y] != 0 ; y++) { - buf1[0] = buf2[0] = '\0'; - l1 = snprintf(buf1, sizeof(buf1), int_fmt[x], int_nums[y]); - l2 = sprintf (buf2, int_fmt[x], int_nums[y]); - buf1[1023] = buf2[1023] = '\0'; - if (strcmp (buf1, buf2) || (l1 != l2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", - int_fmt[x], l1, buf1, l2, buf2); - fail++; - } - num++; - } - } - - for (x = 0; str_fmt[x] ; x++) { - for (y = 0; str_vals[y] != 0 ; y++) { - buf1[0] = buf2[0] = '\0'; - l1 = snprintf(buf1, sizeof(buf1), str_fmt[x], str_vals[y]); - l2 = sprintf (buf2, str_fmt[x], str_vals[y]); - buf1[1023] = buf2[1023] = '\0'; - if (strcmp (buf1, buf2) || (l1 != l2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", - str_fmt[x], l1, buf1, l2, buf2); - fail++; - } - num++; - } - } - -#ifdef HAVE_LONG_LONG - for (x = 0; ll_fmt[x] ; x++) { - for (y = 0; ll_nums[y] != 0 ; y++) { - buf1[0] = buf2[0] = '\0'; - l1 = snprintf(buf1, sizeof(buf1), ll_fmt[x], ll_nums[y]); - l2 = sprintf (buf2, ll_fmt[x], ll_nums[y]); - buf1[1023] = buf2[1023] = '\0'; - if (strcmp (buf1, buf2) || (l1 != l2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", - ll_fmt[x], l1, buf1, l2, buf2); - fail++; - } - num++; - } - } -#endif - -#define BUFSZ 2048 - - buf1[0] = buf2[0] = '\0'; - if ((buf3 = malloc(BUFSZ)) == NULL) { - fail++; - } else { - num++; - memset(buf3, 'a', BUFSZ); - snprintf(buf1, sizeof(buf1), "%.*s", 1, buf3); - buf1[1023] = '\0'; - if (strcmp(buf1, "a") != 0) { - printf("length limit buf1 '%s' expected 'a'\n", buf1); - fail++; - } - } - - buf1[0] = buf2[0] = '\0'; - l1 = snprintf(buf1, sizeof(buf1), "%4$*1$d %2$s %3$*1$.*1$f", 3, "pos test", 12.3456, 9); - l2 = sprintf(buf2, "%4$*1$d %2$s %3$*1$.*1$f", 3, "pos test", 12.3456, 9); - buf1[1023] = buf2[1023] = '\0'; - if (strcmp(buf1, buf2) || (l1 != l2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", - "%4$*1$d %2$s %3$*1$.*1$f", l1, buf1, l2, buf2); - fail++; - } - - buf1[0] = buf2[0] = '\0'; - l1 = snprintf(buf1, sizeof(buf1), "%4$*4$d %2$s %3$*4$.*4$f", 3, "pos test", 12.3456, 9); - l2 = sprintf(buf2, "%4$*4$d %2$s %3$*4$.*4$f", 3, "pos test", 12.3456, 9); - buf1[1023] = buf2[1023] = '\0'; - if (strcmp(buf1, buf2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", - "%4$*1$d %2$s %3$*1$.*1$f", l1, buf1, l2, buf2); - fail++; - } - - for (x = 0; ss_fmt[x] ; x++) { - for (y = 0; ss_nums[y] != 0 ; y++) { - buf1[0] = buf2[0] = '\0'; - l1 = snprintf(buf1, sizeof(buf1), ss_fmt[x], ss_nums[y]); - l2 = sprintf (buf2, ss_fmt[x], ss_nums[y]); - buf1[1023] = buf2[1023] = '\0'; - if (strcmp (buf1, buf2) || (l1 != l2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", - ss_fmt[x], l1, buf1, l2, buf2); - fail++; - } - num++; - } - } -#if 0 - buf1[0] = buf2[0] = '\0'; - l1 = snprintf(buf1, sizeof(buf1), "%lld", (LLONG)1234567890); - l2 = sprintf(buf2, "%lld", (LLONG)1234567890); - buf1[1023] = buf2[1023] = '\0'; - if (strcmp(buf1, buf2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", - "%lld", l1, buf1, l2, buf2); - fail++; - } - - buf1[0] = buf2[0] = '\0'; - l1 = snprintf(buf1, sizeof(buf1), "%Lf", (LDOUBLE)890.1234567890123); - l2 = sprintf(buf2, "%Lf", (LDOUBLE)890.1234567890123); - buf1[1023] = buf2[1023] = '\0'; - if (strcmp(buf1, buf2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf(%d) = [%s]\n\t sprintf(%d) = [%s]\n", - "%Lf", l1, buf1, l2, buf2); - fail++; - } -#endif - printf ("%d tests failed out of %d.\n", fail, num); - - printf("seeing how many digits we support\n"); - { - double v0 = 0.12345678901234567890123456789012345678901; - for (x=0; x<100; x++) { - double p = pow(10, x); - double r = v0*p; - snprintf(buf1, sizeof(buf1), "%1.1f", r); - sprintf(buf2, "%1.1f", r); - if (strcmp(buf1, buf2)) { - printf("we seem to support %d digits\n", x-1); - break; - } - } - } - - return 0; -} -#endif /* TEST_SNPRINTF */ diff --git a/ldb-2.0.8/lib/replace/socket.c b/ldb-2.0.8/lib/replace/socket.c deleted file mode 100644 index 4cd9d2e..0000000 --- a/ldb-2.0.8/lib/replace/socket.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * Dummy replacements for socket functions. - * - * Copyright (C) Michael Adam 2008 - * - * ** NOTE! The following LGPL license applies to the replace - * ** library. This does NOT imply that all of Samba is released - * ** under the LGPL - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - */ - -#include "replace.h" -#include "system/network.h" - -int rep_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen) -{ - errno = ENOSYS; - return -1; -} - -struct hostent *rep_gethostbyname(const char *name) -{ - errno = ENOSYS; - return NULL; -} diff --git a/ldb-2.0.8/lib/replace/socketpair.c b/ldb-2.0.8/lib/replace/socketpair.c deleted file mode 100644 index c775730..0000000 --- a/ldb-2.0.8/lib/replace/socketpair.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * replacement routines for broken systems - * Copyright (C) Jelmer Vernooij 2006 - * Copyright (C) Michael Adam 2008 - * - * ** NOTE! The following LGPL license applies to the replace - * ** library. This does NOT imply that all of Samba is released - * ** under the LGPL - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - */ - -#include "replace.h" -#include "system/network.h" - -int rep_socketpair(int d, int type, int protocol, int sv[2]) -{ - if (d != AF_UNIX) { - errno = EAFNOSUPPORT; - return -1; - } - - if (protocol != 0) { - errno = EPROTONOSUPPORT; - return -1; - } - - if (type != SOCK_STREAM) { - errno = EOPNOTSUPP; - return -1; - } - - return pipe(sv); -} diff --git a/ldb-2.0.8/lib/replace/strptime.c b/ldb-2.0.8/lib/replace/strptime.c deleted file mode 100644 index bbc7422..0000000 --- a/ldb-2.0.8/lib/replace/strptime.c +++ /dev/null @@ -1,995 +0,0 @@ -/* Convert a string representation of time to a time value. - Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 1996. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 3 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - see . */ - -/* XXX This version of the implementation is not really complete. - Some of the fields cannot add information alone. But if seeing - some of them in the same format (such as year, week and weekday) - this is enough information for determining the date. */ - -#include "replace.h" -#include "system/locale.h" -#include "system/time.h" - -#ifndef __P -# if defined (__GNUC__) || (defined (__STDC__) && __STDC__) -# define __P(args) args -# else -# define __P(args) () -# endif /* GCC. */ -#endif /* Not __P. */ - -#if ! HAVE_LOCALTIME_R && ! defined localtime_r -# ifdef _LIBC -# define localtime_r __localtime_r -# else -/* Approximate localtime_r as best we can in its absence. */ -# define localtime_r my_localtime_r -static struct tm *localtime_r __P ((const time_t *, struct tm *)); -static struct tm * -localtime_r (t, tp) - const time_t *t; - struct tm *tp; -{ - struct tm *l = localtime (t); - if (! l) - return 0; - *tp = *l; - return tp; -} -# endif /* ! _LIBC */ -#endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */ - - -#define match_char(ch1, ch2) if (ch1 != ch2) return NULL -#if defined __GNUC__ && __GNUC__ >= 2 -# define match_string(cs1, s2) \ - ({ size_t len = strlen (cs1); \ - int result = strncasecmp ((cs1), (s2), len) == 0; \ - if (result) (s2) += len; \ - result; }) -#else -/* Oh come on. Get a reasonable compiler. */ -# define match_string(cs1, s2) \ - (strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1)) -#endif -/* We intentionally do not use isdigit() for testing because this will - lead to problems with the wide character version. */ -#define get_number(from, to, n) \ - do { \ - int __n = n; \ - val = 0; \ - while (*rp == ' ') \ - ++rp; \ - if (*rp < '0' || *rp > '9') \ - return NULL; \ - do { \ - val *= 10; \ - val += *rp++ - '0'; \ - } while (--__n > 0 && val * 10 <= to && *rp >= '0' && *rp <= '9'); \ - if (val < from || val > to) \ - return NULL; \ - } while (0) -#ifdef _NL_CURRENT -# define get_alt_number(from, to, n) \ - ({ \ - __label__ do_normal; \ - if (*decided != raw) \ - { \ - const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \ - int __n = n; \ - int any = 0; \ - while (*rp == ' ') \ - ++rp; \ - val = 0; \ - do { \ - val *= 10; \ - while (*alts != '\0') \ - { \ - size_t len = strlen (alts); \ - if (strncasecmp (alts, rp, len) == 0) \ - break; \ - alts += len + 1; \ - ++val; \ - } \ - if (*alts == '\0') \ - { \ - if (*decided == not && ! any) \ - goto do_normal; \ - /* If we haven't read anything it's an error. */ \ - if (! any) \ - return NULL; \ - /* Correct the premature multiplication. */ \ - val /= 10; \ - break; \ - } \ - else \ - *decided = loc; \ - } while (--__n > 0 && val * 10 <= to); \ - if (val < from || val > to) \ - return NULL; \ - } \ - else \ - { \ - do_normal: \ - get_number (from, to, n); \ - } \ - 0; \ - }) -#else -# define get_alt_number(from, to, n) \ - /* We don't have the alternate representation. */ \ - get_number(from, to, n) -#endif -#define recursive(new_fmt) \ - (*(new_fmt) != '\0' \ - && (rp = strptime_internal (rp, (new_fmt), tm, decided, era_cnt)) != NULL) - - -#ifdef _LIBC -/* This is defined in locale/C-time.c in the GNU libc. */ -extern const struct locale_data _nl_C_LC_TIME; -extern const unsigned short int __mon_yday[2][13]; - -# define weekday_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (DAY_1)].string) -# define ab_weekday_name \ - (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string) -# define month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string) -# define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string) -# define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string) -# define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_FMT)].string) -# define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string) -# define HERE_PM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (PM_STR)].string) -# define HERE_T_FMT_AMPM \ - (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT_AMPM)].string) -# define HERE_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT)].string) - -# define strncasecmp(s1, s2, n) __strncasecmp (s1, s2, n) -#else -static char const weekday_name[][10] = - { - "Sunday", "Monday", "Tuesday", "Wednesday", - "Thursday", "Friday", "Saturday" - }; -static char const ab_weekday_name[][4] = - { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" - }; -static char const month_name[][10] = - { - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December" - }; -static char const ab_month_name[][4] = - { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }; -# define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y" -# define HERE_D_FMT "%m/%d/%y" -# define HERE_AM_STR "AM" -# define HERE_PM_STR "PM" -# define HERE_T_FMT_AMPM "%I:%M:%S %p" -# define HERE_T_FMT "%H:%M:%S" - -static const unsigned short int __mon_yday[2][13] = - { - /* Normal years. */ - { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, - /* Leap years. */ - { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } - }; -#endif - -/* Status of lookup: do we use the locale data or the raw data? */ -enum locale_status { not, loc, raw }; - - -#ifndef __isleap -/* Nonzero if YEAR is a leap year (every 4 years, - except every 100th isn't, and every 400th is). */ -# define __isleap(year) \ - ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) -#endif - -/* Compute the day of the week. */ -static void -day_of_the_week (struct tm *tm) -{ - /* We know that January 1st 1970 was a Thursday (= 4). Compute the - the difference between this data in the one on TM and so determine - the weekday. */ - int corr_year = 1900 + tm->tm_year - (tm->tm_mon < 2); - int wday = (-473 - + (365 * (tm->tm_year - 70)) - + (corr_year / 4) - - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0) - + (((corr_year / 4) / 25) / 4) - + __mon_yday[0][tm->tm_mon] - + tm->tm_mday - 1); - tm->tm_wday = ((wday % 7) + 7) % 7; -} - -/* Compute the day of the year. */ -static void -day_of_the_year (struct tm *tm) -{ - tm->tm_yday = (__mon_yday[__isleap (1900 + tm->tm_year)][tm->tm_mon] - + (tm->tm_mday - 1)); -} - -static char * -#ifdef _LIBC -internal_function -#endif -strptime_internal __P ((const char *rp, const char *fmt, struct tm *tm, - enum locale_status *decided, int era_cnt)); - -static char * -#ifdef _LIBC -internal_function -#endif -strptime_internal (rp, fmt, tm, decided, era_cnt) - const char *rp; - const char *fmt; - struct tm *tm; - enum locale_status *decided; - int era_cnt; -{ - int cnt; - size_t val; - int have_I, is_pm; - int century, want_century; - int want_era; - int have_wday, want_xday; - int have_yday; - int have_mon, have_mday; -#ifdef _NL_CURRENT - const char *rp_backup; - size_t num_eras; - struct era_entry *era; - - era = NULL; -#endif - - have_I = is_pm = 0; - century = -1; - want_century = 0; - want_era = 0; - - have_wday = want_xday = have_yday = have_mon = have_mday = 0; - - while (*fmt != '\0') - { - /* A white space in the format string matches 0 more or white - space in the input string. */ - if (isspace (*fmt)) - { - while (isspace (*rp)) - ++rp; - ++fmt; - continue; - } - - /* Any character but `%' must be matched by the same character - in the iput string. */ - if (*fmt != '%') - { - match_char (*fmt++, *rp++); - continue; - } - - ++fmt; -#ifndef _NL_CURRENT - /* We need this for handling the `E' modifier. */ - start_over: -#endif - -#ifdef _NL_CURRENT - /* Make back up of current processing pointer. */ - rp_backup = rp; -#endif - - switch (*fmt++) - { - case '%': - /* Match the `%' character itself. */ - match_char ('%', *rp++); - break; - case 'a': - case 'A': - /* Match day of week. */ - for (cnt = 0; cnt < 7; ++cnt) - { -#ifdef _NL_CURRENT - if (*decided !=raw) - { - if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp)) - { - if (*decided == not - && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt), - weekday_name[cnt])) - *decided = loc; - break; - } - if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp)) - { - if (*decided == not - && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), - ab_weekday_name[cnt])) - *decided = loc; - break; - } - } -#endif - if (*decided != loc - && (match_string (weekday_name[cnt], rp) - || match_string (ab_weekday_name[cnt], rp))) - { - *decided = raw; - break; - } - } - if (cnt == 7) - /* Does not match a weekday name. */ - return NULL; - tm->tm_wday = cnt; - have_wday = 1; - break; - case 'b': - case 'B': - case 'h': - /* Match month name. */ - for (cnt = 0; cnt < 12; ++cnt) - { -#ifdef _NL_CURRENT - if (*decided !=raw) - { - if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp)) - { - if (*decided == not - && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt), - month_name[cnt])) - *decided = loc; - break; - } - if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp)) - { - if (*decided == not - && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), - ab_month_name[cnt])) - *decided = loc; - break; - } - } -#endif - if (match_string (month_name[cnt], rp) - || match_string (ab_month_name[cnt], rp)) - { - *decided = raw; - break; - } - } - if (cnt == 12) - /* Does not match a month name. */ - return NULL; - tm->tm_mon = cnt; - want_xday = 1; - break; - case 'c': - /* Match locale's date and time format. */ -#ifdef _NL_CURRENT - if (*decided != raw) - { - if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT))) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (*decided == not && - strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT)) - *decided = loc; - want_xday = 1; - break; - } - *decided = raw; - } -#endif - if (!recursive (HERE_D_T_FMT)) - return NULL; - want_xday = 1; - break; - case 'C': - /* Match century number. */ -#ifdef _NL_CURRENT - match_century: -#endif - get_number (0, 99, 2); - century = val; - want_xday = 1; - break; - case 'd': - case 'e': - /* Match day of month. */ - get_number (1, 31, 2); - tm->tm_mday = val; - have_mday = 1; - want_xday = 1; - break; - case 'F': - if (!recursive ("%Y-%m-%d")) - return NULL; - want_xday = 1; - break; - case 'x': -#ifdef _NL_CURRENT - if (*decided != raw) - { - if (!recursive (_NL_CURRENT (LC_TIME, D_FMT))) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (*decided == not - && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT)) - *decided = loc; - want_xday = 1; - break; - } - *decided = raw; - } -#endif - - FALL_THROUGH; - case 'D': - /* Match standard day format. */ - if (!recursive (HERE_D_FMT)) - return NULL; - want_xday = 1; - break; - case 'k': - case 'H': - /* Match hour in 24-hour clock. */ - get_number (0, 23, 2); - tm->tm_hour = val; - have_I = 0; - break; - case 'I': - /* Match hour in 12-hour clock. */ - get_number (1, 12, 2); - tm->tm_hour = val % 12; - have_I = 1; - break; - case 'j': - /* Match day number of year. */ - get_number (1, 366, 3); - tm->tm_yday = val - 1; - have_yday = 1; - break; - case 'm': - /* Match number of month. */ - get_number (1, 12, 2); - tm->tm_mon = val - 1; - have_mon = 1; - want_xday = 1; - break; - case 'M': - /* Match minute. */ - get_number (0, 59, 2); - tm->tm_min = val; - break; - case 'n': - case 't': - /* Match any white space. */ - while (isspace (*rp)) - ++rp; - break; - case 'p': - /* Match locale's equivalent of AM/PM. */ -#ifdef _NL_CURRENT - if (*decided != raw) - { - if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp)) - { - if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR)) - *decided = loc; - break; - } - if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp)) - { - if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR)) - *decided = loc; - is_pm = 1; - break; - } - *decided = raw; - } -#endif - if (!match_string (HERE_AM_STR, rp)) { - if (match_string (HERE_PM_STR, rp)) { - is_pm = 1; - } else { - return NULL; - } - } - break; - case 'r': -#ifdef _NL_CURRENT - if (*decided != raw) - { - if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM))) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (*decided == not && - strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM), - HERE_T_FMT_AMPM)) - *decided = loc; - break; - } - *decided = raw; - } -#endif - if (!recursive (HERE_T_FMT_AMPM)) - return NULL; - break; - case 'R': - if (!recursive ("%H:%M")) - return NULL; - break; - case 's': - { - /* The number of seconds may be very high so we cannot use - the `get_number' macro. Instead read the number - character for character and construct the result while - doing this. */ - time_t secs = 0; - if (*rp < '0' || *rp > '9') - /* We need at least one digit. */ - return NULL; - - do - { - secs *= 10; - secs += *rp++ - '0'; - } - while (*rp >= '0' && *rp <= '9'); - - if (localtime_r (&secs, tm) == NULL) - /* Error in function. */ - return NULL; - } - break; - case 'S': - get_number (0, 61, 2); - tm->tm_sec = val; - break; - case 'X': -#ifdef _NL_CURRENT - if (*decided != raw) - { - if (!recursive (_NL_CURRENT (LC_TIME, T_FMT))) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT)) - *decided = loc; - break; - } - *decided = raw; - } -#endif - - FALL_THROUGH; - case 'T': - if (!recursive (HERE_T_FMT)) - return NULL; - break; - case 'u': - get_number (1, 7, 1); - tm->tm_wday = val % 7; - have_wday = 1; - break; - case 'g': - get_number (0, 99, 2); - /* XXX This cannot determine any field in TM. */ - break; - case 'G': - if (*rp < '0' || *rp > '9') - return NULL; - /* XXX Ignore the number since we would need some more - information to compute a real date. */ - do - ++rp; - while (*rp >= '0' && *rp <= '9'); - break; - case 'U': - case 'V': - case 'W': - get_number (0, 53, 2); - /* XXX This cannot determine any field in TM without some - information. */ - break; - case 'w': - /* Match number of weekday. */ - get_number (0, 6, 1); - tm->tm_wday = val; - have_wday = 1; - break; - case 'y': -#ifdef _NL_CURRENT - match_year_in_century: -#endif - /* Match year within century. */ - get_number (0, 99, 2); - /* The "Year 2000: The Millennium Rollover" paper suggests that - values in the range 69-99 refer to the twentieth century. */ - tm->tm_year = val >= 69 ? val : val + 100; - /* Indicate that we want to use the century, if specified. */ - want_century = 1; - want_xday = 1; - break; - case 'Y': - /* Match year including century number. */ - get_number (0, 9999, 4); - tm->tm_year = val - 1900; - want_century = 0; - want_xday = 1; - break; - case 'Z': - /* XXX How to handle this? */ - break; - case 'E': -#ifdef _NL_CURRENT - switch (*fmt++) - { - case 'c': - /* Match locale's alternate date and time format. */ - if (*decided != raw) - { - const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT); - - if (*fmt == '\0') - fmt = _NL_CURRENT (LC_TIME, D_T_FMT); - - if (!recursive (fmt)) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (strcmp (fmt, HERE_D_T_FMT)) - *decided = loc; - want_xday = 1; - break; - } - *decided = raw; - } - /* The C locale has no era information, so use the - normal representation. */ - if (!recursive (HERE_D_T_FMT)) - return NULL; - want_xday = 1; - break; - case 'C': - if (*decided != raw) - { - if (era_cnt >= 0) - { - era = _nl_select_era_entry (era_cnt); - if (match_string (era->era_name, rp)) - { - *decided = loc; - break; - } - else - return NULL; - } - else - { - num_eras = _NL_CURRENT_WORD (LC_TIME, - _NL_TIME_ERA_NUM_ENTRIES); - for (era_cnt = 0; era_cnt < (int) num_eras; - ++era_cnt, rp = rp_backup) - { - era = _nl_select_era_entry (era_cnt); - if (match_string (era->era_name, rp)) - { - *decided = loc; - break; - } - } - if (era_cnt == (int) num_eras) - { - era_cnt = -1; - if (*decided == loc) - return NULL; - } - else - break; - } - - *decided = raw; - } - /* The C locale has no era information, so use the - normal representation. */ - goto match_century; - case 'y': - if (*decided == raw) - goto match_year_in_century; - - get_number(0, 9999, 4); - tm->tm_year = val; - want_era = 1; - want_xday = 1; - break; - case 'Y': - if (*decided != raw) - { - num_eras = _NL_CURRENT_WORD (LC_TIME, - _NL_TIME_ERA_NUM_ENTRIES); - for (era_cnt = 0; era_cnt < (int) num_eras; - ++era_cnt, rp = rp_backup) - { - era = _nl_select_era_entry (era_cnt); - if (recursive (era->era_format)) - break; - } - if (era_cnt == (int) num_eras) - { - era_cnt = -1; - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - *decided = loc; - era_cnt = -1; - break; - } - - *decided = raw; - } - get_number (0, 9999, 4); - tm->tm_year = val - 1900; - want_century = 0; - want_xday = 1; - break; - case 'x': - if (*decided != raw) - { - const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT); - - if (*fmt == '\0') - fmt = _NL_CURRENT (LC_TIME, D_FMT); - - if (!recursive (fmt)) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (strcmp (fmt, HERE_D_FMT)) - *decided = loc; - break; - } - *decided = raw; - } - if (!recursive (HERE_D_FMT)) - return NULL; - break; - case 'X': - if (*decided != raw) - { - const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT); - - if (*fmt == '\0') - fmt = _NL_CURRENT (LC_TIME, T_FMT); - - if (!recursive (fmt)) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (strcmp (fmt, HERE_T_FMT)) - *decided = loc; - break; - } - *decided = raw; - } - if (!recursive (HERE_T_FMT)) - return NULL; - break; - default: - return NULL; - } - break; -#else - /* We have no information about the era format. Just use - the normal format. */ - if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y' - && *fmt != 'x' && *fmt != 'X') - /* This is an illegal format. */ - return NULL; - - goto start_over; -#endif - case 'O': - switch (*fmt++) - { - case 'd': - case 'e': - /* Match day of month using alternate numeric symbols. */ - get_alt_number (1, 31, 2); - tm->tm_mday = val; - have_mday = 1; - want_xday = 1; - break; - case 'H': - /* Match hour in 24-hour clock using alternate numeric - symbols. */ - get_alt_number (0, 23, 2); - tm->tm_hour = val; - have_I = 0; - break; - case 'I': - /* Match hour in 12-hour clock using alternate numeric - symbols. */ - get_alt_number (1, 12, 2); - tm->tm_hour = val - 1; - have_I = 1; - break; - case 'm': - /* Match month using alternate numeric symbols. */ - get_alt_number (1, 12, 2); - tm->tm_mon = val - 1; - have_mon = 1; - want_xday = 1; - break; - case 'M': - /* Match minutes using alternate numeric symbols. */ - get_alt_number (0, 59, 2); - tm->tm_min = val; - break; - case 'S': - /* Match seconds using alternate numeric symbols. */ - get_alt_number (0, 61, 2); - tm->tm_sec = val; - break; - case 'U': - case 'V': - case 'W': - get_alt_number (0, 53, 2); - /* XXX This cannot determine any field in TM without - further information. */ - break; - case 'w': - /* Match number of weekday using alternate numeric symbols. */ - get_alt_number (0, 6, 1); - tm->tm_wday = val; - have_wday = 1; - break; - case 'y': - /* Match year within century using alternate numeric symbols. */ - get_alt_number (0, 99, 2); - tm->tm_year = val >= 69 ? val : val + 100; - want_xday = 1; - break; - default: - return NULL; - } - break; - default: - return NULL; - } - } - - if (have_I && is_pm) - tm->tm_hour += 12; - - if (century != -1) - { - if (want_century) - tm->tm_year = tm->tm_year % 100 + (century - 19) * 100; - else - /* Only the century, but not the year. Strange, but so be it. */ - tm->tm_year = (century - 19) * 100; - } - -#ifdef _NL_CURRENT - if (era_cnt != -1) - { - era = _nl_select_era_entry(era_cnt); - if (want_era) - tm->tm_year = (era->start_date[0] - + ((tm->tm_year - era->offset) - * era->absolute_direction)); - else - /* Era start year assumed. */ - tm->tm_year = era->start_date[0]; - } - else -#endif - if (want_era) - return NULL; - - if (want_xday && !have_wday) - { - if ( !(have_mon && have_mday) && have_yday) - { - /* We don't have tm_mon and/or tm_mday, compute them. */ - int t_mon = 0; - while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday) - t_mon++; - if (!have_mon) - tm->tm_mon = t_mon - 1; - if (!have_mday) - tm->tm_mday = - (tm->tm_yday - - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1); - } - day_of_the_week (tm); - } - if (want_xday && !have_yday) - day_of_the_year (tm); - - return discard_const_p(char, rp); -} - - -char *rep_strptime(const char *buf, const char *format, struct tm *tm) -{ - enum locale_status decided; - -#ifdef _NL_CURRENT - decided = not; -#else - decided = raw; -#endif - return strptime_internal (buf, format, tm, &decided, -1); -} diff --git a/ldb-2.0.8/lib/replace/system/README b/ldb-2.0.8/lib/replace/system/README deleted file mode 100644 index 69a2b80..0000000 --- a/ldb-2.0.8/lib/replace/system/README +++ /dev/null @@ -1,4 +0,0 @@ -This directory contains wrappers around logical groups of system -include files. The idea is to avoid #ifdef blocks in the main code, -and instead put all the necessary conditional includes in subsystem -specific header files in this directory. diff --git a/ldb-2.0.8/lib/replace/system/aio.h b/ldb-2.0.8/lib/replace/system/aio.h deleted file mode 100644 index 784d77f..0000000 --- a/ldb-2.0.8/lib/replace/system/aio.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _system_aio_h -#define _system_aio_h -/* - Unix SMB/CIFS implementation. - - AIO system include wrappers - - Copyright (C) Andrew Tridgell 2006 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#ifdef HAVE_LIBAIO_H -#include -#endif - -#endif diff --git a/ldb-2.0.8/lib/replace/system/capability.h b/ldb-2.0.8/lib/replace/system/capability.h deleted file mode 100644 index 44b8d51..0000000 --- a/ldb-2.0.8/lib/replace/system/capability.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef _system_capability_h -#define _system_capability_h -/* - Unix SMB/CIFS implementation. - - capability system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#ifdef HAVE_SYS_CAPABILITY_H - -#if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H) && !defined(_PPC_STATFS_H) -#define _I386_STATFS_H -#define _PPC_STATFS_H -#define BROKEN_REDHAT_7_STATFS_WORKAROUND -#endif - -#if defined(BROKEN_RHEL5_SYS_CAP_HEADER) && !defined(_LINUX_TYPES_H) -#define BROKEN_RHEL5_SYS_CAP_HEADER_WORKAROUND -#endif - -#ifdef HAVE_POSIX_CAPABILITIES -#include -#endif - -#ifdef BROKEN_RHEL5_SYS_CAP_HEADER_WORKAROUND -#undef _LINUX_TYPES_H -#undef BROKEN_RHEL5_SYS_CAP_HEADER_WORKAROUND -#endif - -#ifdef BROKEN_REDHAT_7_STATFS_WORKAROUND -#undef _PPC_STATFS_H -#undef _I386_STATFS_H -#undef BROKEN_REDHAT_7_STATFS_WORKAROUND -#endif - -#endif - -#endif diff --git a/ldb-2.0.8/lib/replace/system/dir.h b/ldb-2.0.8/lib/replace/system/dir.h deleted file mode 100644 index 497b5a7..0000000 --- a/ldb-2.0.8/lib/replace/system/dir.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef _system_dir_h -#define _system_dir_h -/* - Unix SMB/CIFS implementation. - - directory system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#ifdef HAVE_DIRENT_H -# include -# define NAMLEN(dirent) strlen((dirent)->d_name) -#else -# define dirent direct -# define NAMLEN(dirent) (dirent)->d_namlen -# if HAVE_SYS_NDIR_H -# include -# endif -# if HAVE_SYS_DIR_H -# include -# endif -# if HAVE_NDIR_H -# include -# endif -#endif - -#ifndef HAVE_MKDIR_MODE -#define mkdir(dir, mode) mkdir(dir) -#endif - -#ifdef HAVE_LIBGEN_H -# include -#endif - -/* Test whether a file name is the "." or ".." directory entries. - * These really should be inline functions. - */ -#ifndef ISDOT -#define ISDOT(path) ( \ - *((const char *)(path)) == '.' && \ - *(((const char *)(path)) + 1) == '\0' \ - ) -#endif - -#ifndef ISDOTDOT -#define ISDOTDOT(path) ( \ - *((const char *)(path)) == '.' && \ - *(((const char *)(path)) + 1) == '.' && \ - *(((const char *)(path)) + 2) == '\0' \ - ) -#endif - -#endif diff --git a/ldb-2.0.8/lib/replace/system/filesys.h b/ldb-2.0.8/lib/replace/system/filesys.h deleted file mode 100644 index 1a8cb68..0000000 --- a/ldb-2.0.8/lib/replace/system/filesys.h +++ /dev/null @@ -1,242 +0,0 @@ -#ifndef _system_filesys_h -#define _system_filesys_h -/* - Unix SMB/CIFS implementation. - - filesystem system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include - -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -#ifdef HAVE_SYS_MOUNT_H -#include -#endif - -#ifdef HAVE_MNTENT_H -#include -#endif - -#ifdef HAVE_SYS_VFS_H -#include -#endif - -#ifdef HAVE_SYS_ACL_H -#include -#endif - -#ifdef HAVE_ACL_LIBACL_H -#include -#endif - -#ifdef HAVE_SYS_FS_S5PARAM_H -#include -#endif - -#if defined (HAVE_SYS_FILSYS_H) && !defined (_CRAY) -#include -#endif - -#ifdef HAVE_SYS_STATFS_H -# include -#endif - -#ifdef HAVE_DUSTAT_H -#include -#endif - -#ifdef HAVE_SYS_STATVFS_H -#include -#endif - -#ifdef HAVE_SYS_FILIO_H -#include -#endif - -#ifdef HAVE_SYS_FILE_H -#include -#endif - -#ifdef HAVE_FCNTL_H -#include -#else -#ifdef HAVE_SYS_FCNTL_H -#include -#endif -#endif - -#ifdef HAVE_SYS_MODE_H -/* apparently AIX needs this for S_ISLNK */ -#ifndef S_ISLNK -#include -#endif -#endif - -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -#ifdef HAVE_SYS_UIO_H -#include -#endif - -#if defined(HAVE_SYS_ATTRIBUTES_H) -#include -#elif defined(HAVE_ATTR_ATTRIBUTES_H) -#include -#endif - -/* mutually exclusive (SuSE 8.2) */ -#if defined(HAVE_ATTR_XATTR_H) -#include -#elif defined(HAVE_SYS_XATTR_H) -#include -#endif - -#ifdef HAVE_SYS_EA_H -#include -#endif - -#ifdef HAVE_SYS_EXTATTR_H -#include -#endif - -#ifdef HAVE_SYS_RESOURCE_H -#include -#endif - -#ifndef XATTR_CREATE -#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */ -#endif - -#ifndef XATTR_REPLACE -#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */ -#endif - -/* Some POSIX definitions for those without */ - -#ifndef S_IFDIR -#define S_IFDIR 0x4000 -#endif -#ifndef S_ISDIR -#define S_ISDIR(mode) ((mode & 0xF000) == S_IFDIR) -#endif -#ifndef S_IRWXU -#define S_IRWXU 00700 /* read, write, execute: owner */ -#endif -#ifndef S_IRUSR -#define S_IRUSR 00400 /* read permission: owner */ -#endif -#ifndef S_IWUSR -#define S_IWUSR 00200 /* write permission: owner */ -#endif -#ifndef S_IXUSR -#define S_IXUSR 00100 /* execute permission: owner */ -#endif -#ifndef S_IRWXG -#define S_IRWXG 00070 /* read, write, execute: group */ -#endif -#ifndef S_IRGRP -#define S_IRGRP 00040 /* read permission: group */ -#endif -#ifndef S_IWGRP -#define S_IWGRP 00020 /* write permission: group */ -#endif -#ifndef S_IXGRP -#define S_IXGRP 00010 /* execute permission: group */ -#endif -#ifndef S_IRWXO -#define S_IRWXO 00007 /* read, write, execute: other */ -#endif -#ifndef S_IROTH -#define S_IROTH 00004 /* read permission: other */ -#endif -#ifndef S_IWOTH -#define S_IWOTH 00002 /* write permission: other */ -#endif -#ifndef S_IXOTH -#define S_IXOTH 00001 /* execute permission: other */ -#endif - -#ifndef O_ACCMODE -#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR) -#endif - -#ifndef MAXPATHLEN -#define MAXPATHLEN 256 -#endif - -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif - -#ifdef _WIN32 -#define mkdir(d,m) _mkdir(d) -#endif - -/* - this allows us to use a uniform error handling for our xattr - wrappers -*/ -#ifndef ENOATTR -#define ENOATTR ENODATA -#endif - - -#if !defined(HAVE_XATTR_XATTR) || defined(XATTR_ADDITIONAL_OPTIONS) - -ssize_t rep_getxattr (const char *path, const char *name, void *value, size_t size); -#define getxattr(path, name, value, size) rep_getxattr(path, name, value, size) -/* define is in "replace.h" */ -ssize_t rep_fgetxattr (int filedes, const char *name, void *value, size_t size); -#define fgetxattr(filedes, name, value, size) rep_fgetxattr(filedes, name, value, size) -/* define is in "replace.h" */ -ssize_t rep_listxattr (const char *path, char *list, size_t size); -#define listxattr(path, list, size) rep_listxattr(path, list, size) -/* define is in "replace.h" */ -ssize_t rep_flistxattr (int filedes, char *list, size_t size); -#define flistxattr(filedes, value, size) rep_flistxattr(filedes, value, size) -/* define is in "replace.h" */ -int rep_removexattr (const char *path, const char *name); -#define removexattr(path, name) rep_removexattr(path, name) -/* define is in "replace.h" */ -int rep_fremovexattr (int filedes, const char *name); -#define fremovexattr(filedes, name) rep_fremovexattr(filedes, name) -/* define is in "replace.h" */ -int rep_setxattr (const char *path, const char *name, const void *value, size_t size, int flags); -#define setxattr(path, name, value, size, flags) rep_setxattr(path, name, value, size, flags) -/* define is in "replace.h" */ -int rep_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags); -#define fsetxattr(filedes, name, value, size, flags) rep_fsetxattr(filedes, name, value, size, flags) -/* define is in "replace.h" */ - -#endif /* !defined(HAVE_XATTR_XATTR) || defined(XATTR_ADDITIONAL_OPTIONS) */ - -#endif diff --git a/ldb-2.0.8/lib/replace/system/glob.h b/ldb-2.0.8/lib/replace/system/glob.h deleted file mode 100644 index 3e23db6..0000000 --- a/ldb-2.0.8/lib/replace/system/glob.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _system_glob_h -#define _system_glob_h -/* - Unix SMB/CIFS implementation. - - glob system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef HAVE_GLOB_H -#include -#endif - -#ifdef HAVE_FNMATCH_H -#include -#endif - -#endif diff --git a/ldb-2.0.8/lib/replace/system/gssapi.h b/ldb-2.0.8/lib/replace/system/gssapi.h deleted file mode 100644 index d8632d7..0000000 --- a/ldb-2.0.8/lib/replace/system/gssapi.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef _system_gssapi_h -#define _system_gssapi_h - -/* - Unix SMB/CIFS implementation. - - GSSAPI system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef HAVE_GSSAPI - -#ifdef HAVE_GSSAPI_GSSAPI_EXT_H -#include -#elif defined(HAVE_GSSAPI_GSSAPI_H) -#include -#elif defined(HAVE_GSSAPI_GSSAPI_GENERIC_H) -#include -#elif defined(HAVE_GSSAPI_H) -#include -#endif - -#ifdef HAVE_GSSAPI_GSSAPI_KRB5_H -#include -#endif - -#ifdef HAVE_GSSAPI_GSSAPI_SPNEGO_H -#include -#elif defined(HAVE_GSSAPI_SPNEGO_H) -#include -#endif - -#endif -#endif diff --git a/ldb-2.0.8/lib/replace/system/iconv.h b/ldb-2.0.8/lib/replace/system/iconv.h deleted file mode 100644 index 3c8a71f..0000000 --- a/ldb-2.0.8/lib/replace/system/iconv.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef _system_iconv_h -#define _system_iconv_h -/* - Unix SMB/CIFS implementation. - - iconv memory system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#if !defined(HAVE_ICONV) && defined(HAVE_ICONV_H) -#define HAVE_ICONV -#endif - -#if !defined(HAVE_GICONV) && defined(HAVE_GICONV_H) -#define HAVE_GICONV -#endif - -#if !defined(HAVE_BICONV) && defined(HAVE_BICONV_H) -#define HAVE_BICONV -#endif - -#ifdef HAVE_NATIVE_ICONV -#if defined(HAVE_ICONV) -#include -#elif defined(HAVE_GICONV) -#include -#elif defined(HAVE_BICONV) -#include -#endif -#endif /* HAVE_NATIVE_ICONV */ - -/* needed for some systems without iconv. Doesn't really matter - what error code we use */ -#ifndef EILSEQ -#define EILSEQ EIO -#endif - -#endif diff --git a/ldb-2.0.8/lib/replace/system/kerberos.h b/ldb-2.0.8/lib/replace/system/kerberos.h deleted file mode 100644 index ebd8657..0000000 --- a/ldb-2.0.8/lib/replace/system/kerberos.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _system_kerberos_h -#define _system_kerberos_h - -/* - Unix SMB/CIFS implementation. - - kerberos system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef HAVE_KRB5 - -#ifdef HAVE_KRB5_H -#include -#endif - -#ifdef HAVE_COM_ERR_H -#include -#endif - -#endif -#endif diff --git a/ldb-2.0.8/lib/replace/system/locale.h b/ldb-2.0.8/lib/replace/system/locale.h deleted file mode 100644 index 504a3bb..0000000 --- a/ldb-2.0.8/lib/replace/system/locale.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef _system_locale_h -#define _system_locale_h - -/* - Unix SMB/CIFS implementation. - - locale include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef HAVE_CTYPE_H -#include -#endif - -#ifdef HAVE_LOCALE_H -#include -#endif - -#ifdef HAVE_LANGINFO_H -#include -#endif - -#endif diff --git a/ldb-2.0.8/lib/replace/system/network.h b/ldb-2.0.8/lib/replace/system/network.h deleted file mode 100644 index 8254551..0000000 --- a/ldb-2.0.8/lib/replace/system/network.h +++ /dev/null @@ -1,372 +0,0 @@ -#ifndef _system_network_h -#define _system_network_h -/* - Unix SMB/CIFS implementation. - - networking system include wrappers - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Jelmer Vernooij 2007 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifndef LIBREPLACE_NETWORK_CHECKS -#error "AC_LIBREPLACE_NETWORK_CHECKS missing in configure" -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef HAVE_SYS_SOCKET_H -#include -#endif - -#ifdef HAVE_UNIXSOCKET -#include -#endif - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif - -#ifdef HAVE_NETDB_H -#include -#endif - -#ifdef HAVE_NETINET_TCP_H -#include -#endif - -/* - * The next three defines are needed to access the IPTOS_* options - * on some systems. - */ - -#ifdef HAVE_NETINET_IN_SYSTM_H -#include -#endif - -#ifdef HAVE_NETINET_IN_IP_H -#include -#endif - -#ifdef HAVE_NETINET_IP_H -#include -#endif - -#ifdef HAVE_NET_IF_H -#include -#endif - -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -#ifdef HAVE_SYS_UIO_H -#include -#endif - -#ifdef HAVE_STROPTS_H -#include -#endif - -#ifndef HAVE_SOCKLEN_T -#define HAVE_SOCKLEN_T -typedef int socklen_t; -#endif - -#if !defined (HAVE_INET_NTOA) || defined(REPLACE_INET_NTOA) -/* define is in "replace.h" */ -char *rep_inet_ntoa(struct in_addr ip); -#endif - -#ifndef HAVE_INET_PTON -/* define is in "replace.h" */ -int rep_inet_pton(int af, const char *src, void *dst); -#endif - -#ifndef HAVE_INET_NTOP -/* define is in "replace.h" */ -const char *rep_inet_ntop(int af, const void *src, char *dst, socklen_t size); -#endif - -#ifndef HAVE_INET_ATON -/* define is in "replace.h" */ -int rep_inet_aton(const char *src, struct in_addr *dst); -#endif - -#ifndef HAVE_CONNECT -/* define is in "replace.h" */ -int rep_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); -#endif - -#ifndef HAVE_GETHOSTBYNAME -/* define is in "replace.h" */ -struct hostent *rep_gethostbyname(const char *name); -#endif - -#ifdef HAVE_IFADDRS_H -#include -#endif - -#ifndef HAVE_STRUCT_IFADDRS -struct ifaddrs { - struct ifaddrs *ifa_next; /* Pointer to next struct */ - char *ifa_name; /* Interface name */ - unsigned int ifa_flags; /* Interface flags */ - struct sockaddr *ifa_addr; /* Interface address */ - struct sockaddr *ifa_netmask; /* Interface netmask */ -#undef ifa_dstaddr - struct sockaddr *ifa_dstaddr; /* P2P interface destination */ - void *ifa_data; /* Address specific data */ -}; -#endif - -#ifndef HAVE_GETIFADDRS -int rep_getifaddrs(struct ifaddrs **); -#endif - -#ifndef HAVE_FREEIFADDRS -void rep_freeifaddrs(struct ifaddrs *); -#endif - -#ifndef HAVE_SOCKETPAIR -/* define is in "replace.h" */ -int rep_socketpair(int d, int type, int protocol, int sv[2]); -#endif - -/* - * Some systems have getaddrinfo but not the - * defines needed to use it. - */ - -/* Various macros that ought to be in , but might not be */ - -#ifndef EAI_FAIL -#define EAI_BADFLAGS (-1) -#define EAI_NONAME (-2) -#define EAI_AGAIN (-3) -#define EAI_FAIL (-4) -#define EAI_FAMILY (-6) -#define EAI_SOCKTYPE (-7) -#define EAI_SERVICE (-8) -#define EAI_MEMORY (-10) -#define EAI_SYSTEM (-11) -#endif /* !EAI_FAIL */ - -#ifndef AI_PASSIVE -#define AI_PASSIVE 0x0001 -#endif - -#ifndef AI_CANONNAME -#define AI_CANONNAME 0x0002 -#endif - -#ifndef AI_NUMERICHOST -/* - * some platforms don't support AI_NUMERICHOST; define as zero if using - * the system version of getaddrinfo... - */ -#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO) -#define AI_NUMERICHOST 0 -#else -#define AI_NUMERICHOST 0x0004 -#endif -#endif - -/* - * Some of the functions in source3/lib/util_sock.c use AI_ADDRCONFIG. On QNX - * 6.3.0, this macro is defined but, if it's used, getaddrinfo will fail. This - * prevents smbd from opening any sockets. - * - * If I undefine AI_ADDRCONFIG on such systems and define it to be 0, - * this works around the issue. - */ -#ifdef __QNX__ -#include -#if _NTO_VERSION == 630 -#undef AI_ADDRCONFIG -#endif -#endif -#ifndef AI_ADDRCONFIG -/* - * logic copied from AI_NUMERICHOST - */ -#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO) -#define AI_ADDRCONFIG 0 -#else -#define AI_ADDRCONFIG 0x0020 -#endif -#endif - -#ifndef AI_NUMERICSERV -/* - * logic copied from AI_NUMERICHOST - */ -#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO) -#define AI_NUMERICSERV 0 -#else -#define AI_NUMERICSERV 0x0400 -#endif -#endif - -#ifndef NI_NUMERICHOST -#define NI_NUMERICHOST 1 -#endif - -#ifndef NI_NUMERICSERV -#define NI_NUMERICSERV 2 -#endif - -#ifndef NI_NOFQDN -#define NI_NOFQDN 4 -#endif - -#ifndef NI_NAMEREQD -#define NI_NAMEREQD 8 -#endif - -#ifndef NI_DGRAM -#define NI_DGRAM 16 -#endif - - -#ifndef NI_MAXHOST -#define NI_MAXHOST 1025 -#endif - -#ifndef NI_MAXSERV -#define NI_MAXSERV 32 -#endif - -/* - * glibc on linux doesn't seem to have MSG_WAITALL - * defined. I think the kernel has it though.. - */ -#ifndef MSG_WAITALL -#define MSG_WAITALL 0 -#endif - -#ifndef INADDR_LOOPBACK -#define INADDR_LOOPBACK 0x7f000001 -#endif - -#ifndef INADDR_NONE -#define INADDR_NONE 0xffffffff -#endif - -#ifndef EAFNOSUPPORT -#define EAFNOSUPPORT EINVAL -#endif - -#ifndef INET_ADDRSTRLEN -#define INET_ADDRSTRLEN 16 -#endif - -#ifndef INET6_ADDRSTRLEN -#define INET6_ADDRSTRLEN 46 -#endif - -#ifndef HOST_NAME_MAX -#define HOST_NAME_MAX 255 -#endif - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN HOST_NAME_MAX -#endif - -#ifndef HAVE_SA_FAMILY_T -#define HAVE_SA_FAMILY_T -typedef unsigned short int sa_family_t; -#endif - -#ifndef HAVE_STRUCT_SOCKADDR_STORAGE -#define HAVE_STRUCT_SOCKADDR_STORAGE -#ifdef HAVE_STRUCT_SOCKADDR_IN6 -#define sockaddr_storage sockaddr_in6 -#define ss_family sin6_family -#define HAVE_SS_FAMILY 1 -#else /*HAVE_STRUCT_SOCKADDR_IN6*/ -#define sockaddr_storage sockaddr_in -#define ss_family sin_family -#define HAVE_SS_FAMILY 1 -#endif /*HAVE_STRUCT_SOCKADDR_IN6*/ -#endif /*HAVE_STRUCT_SOCKADDR_STORAGE*/ - -#ifndef HAVE_SS_FAMILY -#ifdef HAVE___SS_FAMILY -#define ss_family __ss_family -#define HAVE_SS_FAMILY 1 -#endif -#endif - -#ifndef IOV_MAX -# ifdef UIO_MAXIOV -# define IOV_MAX UIO_MAXIOV -# else -# ifdef __sgi - /* - * IRIX 6.5 has sysconf(_SC_IOV_MAX) - * which might return 512 or bigger - */ -# define IOV_MAX 512 -# endif -# endif -#endif - -#ifndef HAVE_STRUCT_ADDRINFO -#define HAVE_STRUCT_ADDRINFO -struct addrinfo { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - socklen_t ai_addrlen; - struct sockaddr *ai_addr; - char *ai_canonname; - struct addrinfo *ai_next; -}; -#endif /* HAVE_STRUCT_ADDRINFO */ - -#if !defined(HAVE_GETADDRINFO) -#include "getaddrinfo.h" -#endif - -/* Needed for some systems that don't define it (Solaris). */ -#ifndef ifr_netmask -#define ifr_netmask ifr_addr -#endif - -/* Some old Linux systems have broken header files */ -#ifdef HAVE_IPV6 -#ifdef HAVE_LINUX_IPV6_V6ONLY_26 -#define IPV6_V6ONLY 26 -#endif /* HAVE_LINUX_IPV6_V6ONLY_26 */ -#endif /* HAVE_IPV6 */ - -#ifndef SCOPE_DELIMITER -#define SCOPE_DELIMITER '%' -#endif - -#endif diff --git a/ldb-2.0.8/lib/replace/system/nis.h b/ldb-2.0.8/lib/replace/system/nis.h deleted file mode 100644 index 7213b15..0000000 --- a/ldb-2.0.8/lib/replace/system/nis.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - nis system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#ifndef _nis_passwd_h -#define _nis_passwd_h - -#if defined(HAVE_RPC_RPC_H) -/* - * Check for AUTH_ERROR define conflict with rpc/rpc.h in prot.h. - */ -#if defined(HAVE_SYS_SECURITY_H) && defined(HAVE_RPC_AUTH_ERROR_CONFLICT) -#undef AUTH_ERROR -#endif /* HAVE_SYS_SECURITY_H && HAVE_RPC_AUTH_ERROR_CONFLICT */ - -#include -#endif /* HAVE_RPC_RPC_H */ - - -#if defined (HAVE_NETGROUP) - -#if defined(HAVE_RPCSVC_YP_PROT_H) - -#include - -#endif /* HAVE_RPCSVC_YP_PROT_H */ - -#if defined(HAVE_RPCSVC_YPCLNT_H) -#include -#endif /* HAVE_RPCSVC_YPCLNT_H */ - -#endif /* HAVE_NETGROUP */ - -#endif /* _nis_passwd_h */ diff --git a/ldb-2.0.8/lib/replace/system/passwd.h b/ldb-2.0.8/lib/replace/system/passwd.h deleted file mode 100644 index ecc9f60..0000000 --- a/ldb-2.0.8/lib/replace/system/passwd.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef _system_passwd_h -#define _system_passwd_h - -/* - Unix SMB/CIFS implementation. - - passwd system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef HAVE_PWD_H -#include -#endif -#ifdef HAVE_GRP_H -#include -#endif -#ifdef HAVE_SYS_PRIV_H -#include -#endif -#ifdef HAVE_SYS_ID_H -#include -#endif - -#ifdef HAVE_CRYPT_H -#include -#endif - -#ifdef HAVE_SHADOW_H -#include -#endif - -#ifdef HAVE_SYS_SECURITY_H -#include -#include -#define PASSWORD_LENGTH 16 -#endif /* HAVE_SYS_SECURITY_H */ - -#ifdef HAVE_GETPWANAM -#include -#include -#include -#endif - -#ifdef HAVE_COMPAT_H -#include -#endif - -#ifndef NGROUPS_MAX -#define NGROUPS_MAX 32 /* Guess... */ -#endif - -/* what is the longest significant password available on your system? - Knowing this speeds up password searches a lot */ -#ifndef PASSWORD_LENGTH -#define PASSWORD_LENGTH 8 -#endif - - -#ifndef ALLOW_CHANGE_PASSWORD -#if (defined(HAVE_TERMIOS_H) && defined(HAVE_DUP2) && defined(HAVE_SETSID)) -#define ALLOW_CHANGE_PASSWORD 1 -#endif -#endif - -#if defined(HAVE_CRYPT16) && defined(HAVE_GETAUTHUID) -#define ULTRIX_AUTH 1 -#endif - -#endif diff --git a/ldb-2.0.8/lib/replace/system/readline.h b/ldb-2.0.8/lib/replace/system/readline.h deleted file mode 100644 index 2937962..0000000 --- a/ldb-2.0.8/lib/replace/system/readline.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef _system_readline_h -#define _system_readline_h -/* - Unix SMB/CIFS implementation. - - Readline wrappers - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef HAVE_LIBREADLINE -# ifdef HAVE_READLINE_READLINE_H -# ifdef HAVE_READLINE_READLINE_WORKAROUND -# define _FUNCTION_DEF -# endif -# include -# ifdef HAVE_READLINE_HISTORY_H -# include -# endif -# else -# ifdef HAVE_READLINE_H -# include -# ifdef HAVE_HISTORY_H -# include -# endif -# else -# undef HAVE_LIBREADLINE -# endif -# endif -#endif - -#ifdef HAVE_NEW_LIBREADLINE -#ifdef HAVE_CPPFUNCTION -# define RL_COMPLETION_CAST (CPPFunction *) -#elif defined(HAVE_RL_COMPLETION_T) -# define RL_COMPLETION_CAST (rl_completion_t *) -#else -# define RL_COMPLETION_CAST -#endif -#else -/* This type is missing from libreadline<4.0 (approximately) */ -# define RL_COMPLETION_CAST -#endif /* HAVE_NEW_LIBREADLINE */ - -#endif diff --git a/ldb-2.0.8/lib/replace/system/select.h b/ldb-2.0.8/lib/replace/system/select.h deleted file mode 100644 index 9e945c3..0000000 --- a/ldb-2.0.8/lib/replace/system/select.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef _system_select_h -#define _system_select_h -/* - Unix SMB/CIFS implementation. - - select system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef HAVE_SYS_SELECT_H -#include -#endif - -#ifdef HAVE_SYS_EPOLL_H -#include -#endif - -#ifdef HAVE_SOLARIS_PORTS -#include -#endif - -#ifndef SELECT_CAST -#define SELECT_CAST -#endif - -#ifdef HAVE_POLL - -#include - -#else - -/* Type used for the number of file descriptors. */ -typedef unsigned long int nfds_t; - -/* Data structure describing a polling request. */ -struct pollfd -{ - int fd; /* File descriptor to poll. */ - short int events; /* Types of events poller cares about. */ - short int revents; /* Types of events that actually occurred. */ -}; - -/* Event types that can be polled for. These bits may be set in `events' - to indicate the interesting event types; they will appear in `revents' - to indicate the status of the file descriptor. */ -#define POLLIN 0x001 /* There is data to read. */ -#define POLLPRI 0x002 /* There is urgent data to read. */ -#define POLLOUT 0x004 /* Writing now will not block. */ -#define POLLRDNORM 0x040 /* Normal data may be read. */ -#define POLLRDBAND 0x080 /* Priority data may be read. */ -#define POLLWRNORM 0x100 /* Writing now will not block. */ -#define POLLWRBAND 0x200 /* Priority data may be written. */ -#define POLLERR 0x008 /* Error condition. */ -#define POLLHUP 0x010 /* Hung up. */ -#define POLLNVAL 0x020 /* Invalid polling request. */ - -/* define is in "replace.h" */ -int rep_poll(struct pollfd *fds, nfds_t nfds, int timeout); - -#endif - -#endif diff --git a/ldb-2.0.8/lib/replace/system/shmem.h b/ldb-2.0.8/lib/replace/system/shmem.h deleted file mode 100644 index 64fe39b..0000000 --- a/ldb-2.0.8/lib/replace/system/shmem.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef _system_shmem_h -#define _system_shmem_h -/* - Unix SMB/CIFS implementation. - - shared memory system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#if defined(HAVE_SYS_IPC_H) -#include -#endif /* HAVE_SYS_IPC_H */ - -#if defined(HAVE_SYS_SHM_H) -#include -#endif /* HAVE_SYS_SHM_H */ - -#ifdef HAVE_SYS_MMAN_H -#include -#endif - -/* NetBSD doesn't have these */ -#ifndef SHM_R -#define SHM_R 0400 -#endif - -#ifndef SHM_W -#define SHM_W 0200 -#endif - - -#ifndef MAP_FILE -#define MAP_FILE 0 -#endif - -#ifndef MAP_FAILED -#define MAP_FAILED ((void *)-1) -#endif - -#endif diff --git a/ldb-2.0.8/lib/replace/system/syslog.h b/ldb-2.0.8/lib/replace/system/syslog.h deleted file mode 100644 index 104be1d..0000000 --- a/ldb-2.0.8/lib/replace/system/syslog.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef _system_syslog_h -#define _system_syslog_h -/* - Unix SMB/CIFS implementation. - - syslog system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef HAVE_SYSLOG_H -#include -#else -#ifdef HAVE_SYS_SYSLOG_H -#include -#endif -#endif - -/* For sys_adminlog(). */ -#ifndef LOG_EMERG -#define LOG_EMERG 0 /* system is unusable */ -#endif - -#ifndef LOG_ALERT -#define LOG_ALERT 1 /* action must be taken immediately */ -#endif - -#ifndef LOG_CRIT -#define LOG_CRIT 2 /* critical conditions */ -#endif - -#ifndef LOG_ERR -#define LOG_ERR 3 /* error conditions */ -#endif - -#ifndef LOG_WARNING -#define LOG_WARNING 4 /* warning conditions */ -#endif - -#ifndef LOG_NOTICE -#define LOG_NOTICE 5 /* normal but significant condition */ -#endif - -#ifndef LOG_INFO -#define LOG_INFO 6 /* informational */ -#endif - -#ifndef LOG_DEBUG -#define LOG_DEBUG 7 /* debug-level messages */ -#endif - -#endif diff --git a/ldb-2.0.8/lib/replace/system/terminal.h b/ldb-2.0.8/lib/replace/system/terminal.h deleted file mode 100644 index 9ad601a..0000000 --- a/ldb-2.0.8/lib/replace/system/terminal.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _system_terminal_h -#define _system_terminal_h -/* - Unix SMB/CIFS implementation. - - terminal system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef SUNOS4 -/* on SUNOS4 termios.h conflicts with sys/ioctl.h */ -#undef HAVE_TERMIOS_H -#endif - - -#if defined(HAVE_TERMIOS_H) -/* POSIX terminal handling. */ -#include -#elif defined(HAVE_TERMIO_H) -/* Older SYSV terminal handling - don't use if we can avoid it. */ -#include -#elif defined(HAVE_SYS_TERMIO_H) -/* Older SYSV terminal handling - don't use if we can avoid it. */ -#include -#endif - -#endif diff --git a/ldb-2.0.8/lib/replace/system/threads.h b/ldb-2.0.8/lib/replace/system/threads.h deleted file mode 100644 index d189ed6..0000000 --- a/ldb-2.0.8/lib/replace/system/threads.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef _system_threads_h -#define _system_threads_h -/* - Unix SMB/CIFS implementation. - - macros to go along with the lib/replace/ portability layer code - - Copyright (C) Volker Lendecke 2012 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include - -#if defined(HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP) && \ - !defined(HAVE_PTHREAD_MUTEXATTR_SETROBUST) -#define pthread_mutexattr_setrobust pthread_mutexattr_setrobust_np -#endif - -#if defined(HAVE_DECL_PTHREAD_MUTEX_ROBUST_NP) && \ - !defined(HAVE_DECL_PTHREAD_MUTEX_ROBUST) -#define PTHREAD_MUTEX_ROBUST PTHREAD_MUTEX_ROBUST_NP -#endif - -#if defined(HAVE_PTHREAD_MUTEX_CONSISTENT_NP) && \ - !defined(HAVE_PTHREAD_MUTEX_CONSISTENT) -#define pthread_mutex_consistent pthread_mutex_consistent_np -#endif - -#ifdef HAVE_STDATOMIC_H -#include -#endif - -#ifndef HAVE_ATOMIC_THREAD_FENCE -#ifdef HAVE___ATOMIC_THREAD_FENCE -#define atomic_thread_fence(__ignore_order) __atomic_thread_fence(__ATOMIC_SEQ_CST) -#define HAVE_ATOMIC_THREAD_FENCE 1 -#endif /* HAVE___ATOMIC_THREAD_FENCE */ -#endif /* not HAVE_ATOMIC_THREAD_FENCE */ - -#ifndef HAVE_ATOMIC_THREAD_FENCE -#ifdef HAVE___SYNC_SYNCHRONIZE -#define atomic_thread_fence(__ignore_order) __sync_synchronize() -#define HAVE_ATOMIC_THREAD_FENCE 1 -#endif /* HAVE___SYNC_SYNCHRONIZE */ -#endif /* not HAVE_ATOMIC_THREAD_FENCE */ - -#ifndef HAVE_ATOMIC_THREAD_FENCE -#ifdef HAVE_ATOMIC_THREAD_FENCE_SUPPORT -#error mismatch_error_between_configure_test_and_header -#endif -/* make sure the build fails if someone uses it without checking the define */ -#define atomic_thread_fence(__order) \ - __function__atomic_thread_fence_not_available_on_this_platform__() -#endif /* not HAVE_ATOMIC_THREAD_FENCE */ - -#endif diff --git a/ldb-2.0.8/lib/replace/system/time.h b/ldb-2.0.8/lib/replace/system/time.h deleted file mode 100644 index 00f0d7f..0000000 --- a/ldb-2.0.8/lib/replace/system/time.h +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef _system_time_h -#define _system_time_h -/* - Unix SMB/CIFS implementation. - - time system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef TIME_WITH_SYS_TIME -#include -#include -#else -#ifdef HAVE_SYS_TIME_H -#include -#else -#include -#endif -#endif - -#ifdef HAVE_UTIME_H -#include -#else -struct utimbuf { - time_t actime; /* access time */ - time_t modtime; /* modification time */ -}; -#endif - -#ifndef HAVE_STRUCT_TIMESPEC -struct timespec { - time_t tv_sec; /* Seconds. */ - long tv_nsec; /* Nanoseconds. */ -}; -#endif - -#ifndef HAVE_MKTIME -/* define is in "replace.h" */ -time_t rep_mktime(struct tm *t); -#endif - -#ifndef HAVE_TIMEGM -/* define is in "replace.h" */ -time_t rep_timegm(struct tm *tm); -#endif - -#ifndef HAVE_UTIME -/* define is in "replace.h" */ -int rep_utime(const char *filename, const struct utimbuf *buf); -#endif - -#ifndef HAVE_UTIMES -/* define is in "replace.h" */ -int rep_utimes(const char *filename, const struct timeval tv[2]); -#endif - -#ifndef HAVE_CLOCK_GETTIME -/* CLOCK_REALTIME is required by POSIX */ -#define CLOCK_REALTIME 0 -typedef int clockid_t; -int rep_clock_gettime(clockid_t clk_id, struct timespec *tp); -#endif -/* make sure we have a best effort CUSTOM_CLOCK_MONOTONIC we can rely on. - * - * on AIX the values of CLOCK_* are cast expressions, not integer constants, - * this prevents them from being compared against in a preprocessor directive. - * The following ...IS_* macros can be used to check which clock is in use. - */ -#if defined(CLOCK_MONOTONIC) -#define CUSTOM_CLOCK_MONOTONIC CLOCK_MONOTONIC -#define CUSTOM_CLOCK_MONOTONIC_IS_MONOTONIC -#elif defined(CLOCK_HIGHRES) -#define CUSTOM_CLOCK_MONOTONIC CLOCK_HIGHRES -#define CUSTOM_CLOCK_MONOTONIC_IS_HIGHRES -#else -#define CUSTOM_CLOCK_MONOTONIC CLOCK_REALTIME -#define CUSTOM_CLOCK_MONOTONIC_IS_REALTIME -#endif - -#endif diff --git a/ldb-2.0.8/lib/replace/system/wait.h b/ldb-2.0.8/lib/replace/system/wait.h deleted file mode 100644 index 1f5fcd9..0000000 --- a/ldb-2.0.8/lib/replace/system/wait.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef _system_wait_h -#define _system_wait_h -/* - Unix SMB/CIFS implementation. - - waitpid system include wrappers - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . - -*/ - -#ifdef HAVE_SYS_WAIT_H -#include -#endif - -#include - -#ifndef SIGCLD -#define SIGCLD SIGCHLD -#endif - -#ifdef HAVE_SETJMP_H -#include -#endif - -#ifdef HAVE_SYS_UCONTEXT_H -#include -#endif - -#if !defined(HAVE_SIG_ATOMIC_T_TYPE) -typedef int sig_atomic_t; -#endif - -#if !defined(HAVE_WAITPID) && defined(HAVE_WAIT4) -int rep_waitpid(pid_t pid,int *status,int options); -#endif - -#endif diff --git a/ldb-2.0.8/lib/replace/system/wscript_configure b/ldb-2.0.8/lib/replace/system/wscript_configure deleted file mode 100644 index ecd9964..0000000 --- a/ldb-2.0.8/lib/replace/system/wscript_configure +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env python - -# solaris varients of getXXent_r -conf.CHECK_C_PROTOTYPE('getpwent_r', - 'struct passwd *getpwent_r(struct passwd *src, char *buf, int buflen)', - define='SOLARIS_GETPWENT_R', headers='pwd.h') -conf.CHECK_C_PROTOTYPE('getgrent_r', - 'struct group *getgrent_r(struct group *src, char *buf, int buflen)', - define='SOLARIS_GETGRENT_R', headers='grp.h') - -# the irix varients -conf.CHECK_C_PROTOTYPE('getpwent_r', - 'struct passwd *getpwent_r(struct passwd *src, char *buf, size_t buflen)', - define='SOLARIS_GETPWENT_R', headers='pwd.h') -conf.CHECK_C_PROTOTYPE('getgrent_r', - 'struct group *getgrent_r(struct group *src, char *buf, size_t buflen)', - define='SOLARIS_GETGRENT_R', headers='grp.h') - diff --git a/ldb-2.0.8/lib/replace/tests/getifaddrs.c b/ldb-2.0.8/lib/replace/tests/getifaddrs.c deleted file mode 100644 index 8d575af..0000000 --- a/ldb-2.0.8/lib/replace/tests/getifaddrs.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * libreplace getifaddrs test - * - * Copyright (C) Michael Adam 2008 - * - * ** NOTE! The following LGPL license applies to the replace - * ** library. This does NOT imply that all of Samba is released - * ** under the LGPL - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - */ - -#ifndef AUTOCONF_TEST -#include "replace.h" -#include "system/network.h" -#include "replace-test.h" -#endif - -#ifdef HAVE_INET_NTOP -#define rep_inet_ntop inet_ntop -#endif - -static const char *format_sockaddr(struct sockaddr *addr, - char *addrstring, - socklen_t addrlen) -{ - const char *result = NULL; - - if (addr->sa_family == AF_INET) { - result = rep_inet_ntop(AF_INET, - &((struct sockaddr_in *)addr)->sin_addr, - addrstring, - addrlen); -#ifdef HAVE_STRUCT_SOCKADDR_IN6 - } else if (addr->sa_family == AF_INET6) { - result = rep_inet_ntop(AF_INET6, - &((struct sockaddr_in6 *)addr)->sin6_addr, - addrstring, - addrlen); -#endif - } - return result; -} - -int getifaddrs_test(void) -{ - struct ifaddrs *ifs = NULL; - struct ifaddrs *ifs_head = NULL; - int ret; - - ret = getifaddrs(&ifs); - ifs_head = ifs; - if (ret != 0) { - fprintf(stderr, "getifaddrs() failed: %s\n", strerror(errno)); - return 1; - } - - while (ifs) { - printf("%-10s ", ifs->ifa_name); - if (ifs->ifa_addr != NULL) { - char addrstring[INET6_ADDRSTRLEN]; - const char *result; - - result = format_sockaddr(ifs->ifa_addr, - addrstring, - sizeof(addrstring)); - if (result != NULL) { - printf("IP=%s ", addrstring); - } - - if (ifs->ifa_netmask != NULL) { - result = format_sockaddr(ifs->ifa_netmask, - addrstring, - sizeof(addrstring)); - if (result != NULL) { - printf("NETMASK=%s", addrstring); - } - } else { - printf("AF=%d ", ifs->ifa_addr->sa_family); - } - } else { - printf(""); - } - - printf("\n"); - ifs = ifs->ifa_next; - } - - freeifaddrs(ifs_head); - - return 0; -} diff --git a/ldb-2.0.8/lib/replace/tests/incoherent_mmap.c b/ldb-2.0.8/lib/replace/tests/incoherent_mmap.c deleted file mode 100644 index ee288fd..0000000 --- a/ldb-2.0.8/lib/replace/tests/incoherent_mmap.c +++ /dev/null @@ -1,83 +0,0 @@ -/* In OpenBSD, if you write to a file, another process doesn't see it - * in its mmap. Returns with exit status 0 if that is the case, 1 if - * it's coherent, and other if there's a problem. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DATA "coherent.mmap" - -int main(int argc, char *argv[]) -{ - int tochild[2], toparent[2]; - int fd; - volatile unsigned char *map; - unsigned char *page; - const char *fname = argv[1]; - char c = 0; - - if (pipe(tochild) != 0 || pipe(toparent) != 0) - err(2, "Creating pipe"); - - if (!fname) - fname = DATA; - - fd = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0600); - if (fd < 0) - err(2, "opening %s", fname); - unlink(fname); - - switch (fork()) { - case -1: - err(2, "Fork"); - case 0: - close(tochild[1]); - close(toparent[0]); - - /* Wait for parent to create file. */ - if (read(tochild[0], &c, 1) != 1) - err(2, "reading from parent"); - - /* Alter first byte. */ - pwrite(fd, &c, 1, 0); - - if (write(toparent[1], &c, 1) != 1) - err(2, "writing to parent"); - exit(0); - - default: - close(tochild[0]); - close(toparent[1]); - - /* Create a file and mmap it. */ - page = malloc(getpagesize()); - memset(page, 0x42, getpagesize()); - if (write(fd, page, getpagesize()) != getpagesize()) - err(2, "writing first page"); - map = mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE, - MAP_SHARED, fd, 0); - if (map == MAP_FAILED) - err(2, "mapping file"); - - if (*map != 0x42) - errx(2, "first byte isn't 0x42!"); - - /* Tell child to alter file. */ - if (write(tochild[1], &c, 1) != 1) - err(2, "writing to child"); - - if (read(toparent[0], &c, 1) != 1) - err(2, "reading from child"); - - if (*map) - errx(0, "mmap incoherent: first byte isn't 0."); - - exit(1); - } -} diff --git a/ldb-2.0.8/lib/replace/tests/main.c b/ldb-2.0.8/lib/replace/tests/main.c deleted file mode 100644 index 94264d7..0000000 --- a/ldb-2.0.8/lib/replace/tests/main.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - libreplace tests - - Copyright (C) Jelmer Vernooij 2006 - - ** NOTE! The following LGPL license applies to the talloc - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#include "replace-testsuite.h" - -int main(void) -{ - bool ret = torture_local_replace(NULL); - if (ret) - return 0; - return -1; -} diff --git a/ldb-2.0.8/lib/replace/tests/os2_delete.c b/ldb-2.0.8/lib/replace/tests/os2_delete.c deleted file mode 100644 index 4b99ccf..0000000 --- a/ldb-2.0.8/lib/replace/tests/os2_delete.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - test readdir/unlink pattern that OS/2 uses - tridge@samba.org July 2005 -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "replace-test.h" - -#define NUM_FILES 700 -#define READDIR_SIZE 100 -#define DELETE_SIZE 4 - -#define TESTDIR "test.dir" - -static int test_readdir_os2_delete_ret; - -#define FAILED(d) (printf("failure: readdir [\nFailed for %s - %d = %s\n]\n", d, errno, strerror(errno)), test_readdir_os2_delete_ret = 1) - -#ifndef MIN -#define MIN(a,b) ((a)<(b)?(a):(b)) -#endif - -#ifdef _WIN32 -#define mkdir(d,m) _mkdir(d) -#endif - -static void cleanup(void) -{ - /* I'm a lazy bastard */ - if (system("rm -rf " TESTDIR)) { - FAILED("system"); - } - mkdir(TESTDIR, 0700) == 0 || FAILED("mkdir"); -} - -static void create_files(void) -{ - int i; - for (i=0;id_name); - } - - if (i == 0) { - return 0; - } - - /* delete the first few */ - for (j=0; jd_name, ".") == 0 || FAILED("match ."); - de = readdir(d); - strcmp(de->d_name, "..") == 0 || FAILED("match .."); - - while (1) { - int n = os2_delete(d); - if (n == 0) break; - total_deleted += n; - } - closedir(d); - - fprintf(stderr, "Deleted %d files of %d\n", total_deleted, NUM_FILES); - - rmdir(TESTDIR) == 0 || FAILED("rmdir"); - - if (system("rm -rf " TESTDIR) == -1) { - FAILED("system"); - } - - return test_readdir_os2_delete_ret; -} diff --git a/ldb-2.0.8/lib/replace/tests/shared_mmap.c b/ldb-2.0.8/lib/replace/tests/shared_mmap.c deleted file mode 100644 index 9d6e3fc..0000000 --- a/ldb-2.0.8/lib/replace/tests/shared_mmap.c +++ /dev/null @@ -1,71 +0,0 @@ -/* this tests whether we can use a shared writeable mmap on a file - - as needed for the mmap variant of FAST_SHARE_MODES */ - -#if defined(HAVE_UNISTD_H) -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#include -#include -#include -#include - -#define DATA "conftest.mmap" - -#ifndef MAP_FILE -#define MAP_FILE 0 -#endif - -int main(void) -{ - int *buf; - int i; - int fd = open(DATA,O_RDWR|O_CREAT|O_TRUNC,0666); - int count=7; - - if (fd == -1) exit(1); - - for (i=0;i<10000;i++) { - write(fd,&i,sizeof(i)); - } - - close(fd); - - if (fork() == 0) { - fd = open(DATA,O_RDWR); - if (fd == -1) exit(1); - - buf = (int *)mmap(NULL, 10000*sizeof(int), - (PROT_READ | PROT_WRITE), - MAP_FILE | MAP_SHARED, - fd, 0); - - while (count-- && buf[9124] != 55732) sleep(1); - - if (count <= 0) exit(1); - - buf[1763] = 7268; - exit(0); - } - - fd = open(DATA,O_RDWR); - if (fd == -1) exit(1); - - buf = (int *)mmap(NULL, 10000*sizeof(int), - (PROT_READ | PROT_WRITE), - MAP_FILE | MAP_SHARED, - fd, 0); - - if (buf == (int *)-1) exit(1); - - buf[9124] = 55732; - - while (count-- && buf[1763] != 7268) sleep(1); - - unlink(DATA); - - if (count > 0) exit(0); - exit(1); -} diff --git a/ldb-2.0.8/lib/replace/tests/shared_mremap.c b/ldb-2.0.8/lib/replace/tests/shared_mremap.c deleted file mode 100644 index 08040e2..0000000 --- a/ldb-2.0.8/lib/replace/tests/shared_mremap.c +++ /dev/null @@ -1,51 +0,0 @@ -/* this tests whether we can use mremap */ - -#if defined(HAVE_UNISTD_H) -#include -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#include -#include -#include -#include - -#define DATA "conftest.mmap" - -#ifndef MAP_FILE -#define MAP_FILE 0 -#endif - -#ifndef MAP_FAILED -#define MAP_FAILED (int *)-1 -#endif - -int main(void) -{ - int *buf; - int fd; - int err = 1; - - fd = open(DATA, O_RDWR|O_CREAT|O_TRUNC, 0666); - if (fd == -1) { - exit(1); - } - - buf = (int *)mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, - MAP_FILE | MAP_SHARED, fd, 0); - if (buf == MAP_FAILED) { - goto done; - } - - buf = mremap(buf, 0x1000, 0x2000, MREMAP_MAYMOVE); - if (buf == MAP_FAILED) { - goto done; - } - - err = 0; -done: - close(fd); - unlink(DATA); - exit(err); -} diff --git a/ldb-2.0.8/lib/replace/tests/snprintf.c b/ldb-2.0.8/lib/replace/tests/snprintf.c deleted file mode 100644 index 77473f0..0000000 --- a/ldb-2.0.8/lib/replace/tests/snprintf.c +++ /dev/null @@ -1,29 +0,0 @@ -void foo(const char *format, ...) -{ - va_list ap; - int len; - char buf[20]; - long long l = 1234567890; - l *= 100; - - va_start(ap, format); - len = vsnprintf(buf, 0, format, ap); - va_end(ap); - if (len != 5) exit(1); - - va_start(ap, format); - len = vsnprintf(0, 0, format, ap); - va_end(ap); - if (len != 5) exit(2); - - if (snprintf(buf, 3, "hello") != 5 || strcmp(buf, "he") != 0) exit(3); - - if (snprintf(buf, 20, "%lld", l) != 12 || strcmp(buf, "123456789000") != 0) exit(4); - if (snprintf(buf, 20, "%zu", 123456789) != 9 || strcmp(buf, "123456789") != 0) exit(5); - if (snprintf(buf, 20, "%2\$d %1\$d", 3, 4) != 3 || strcmp(buf, "4 3") != 0) exit(6); - if (snprintf(buf, 20, "%s", 0) < 3) exit(7); - - printf("1"); - exit(0); -} -int main(void) { foo("hello"); } diff --git a/ldb-2.0.8/lib/replace/tests/strptime.c b/ldb-2.0.8/lib/replace/tests/strptime.c deleted file mode 100644 index 5bf03f5..0000000 --- a/ldb-2.0.8/lib/replace/tests/strptime.c +++ /dev/null @@ -1,173 +0,0 @@ - -#ifdef LIBREPLACE_CONFIGURE_TEST_STRPTIME - -#include -#include -#include - -#define true 1 -#define false 0 - -#ifndef __STRING -#define __STRING(x) #x -#endif - -/* make printf a no-op */ -#define printf if(0) printf - -#else /* LIBREPLACE_CONFIGURE_TEST_STRPTIME */ - -#include "replace.h" -#include "system/time.h" -#include "replace-test.h" - -#endif /* LIBREPLACE_CONFIGURE_TEST_STRPTIME */ - -int libreplace_test_strptime(void) -{ - const char *s = "20070414101546Z"; - char *ret; - struct tm t, t2; - - memset(&t, 0, sizeof(t)); - memset(&t2, 0, sizeof(t2)); - - printf("test: strptime\n"); - - ret = strptime(s, "%Y%m%d%H%M%S", &t); - if ( ret == NULL ) { - printf("failure: strptime [\n" - "returned NULL\n" - "]\n"); - return false; - } - - if ( *ret != 'Z' ) { - printf("failure: strptime [\n" - "ret doesn't point to 'Z'\n" - "]\n"); - return false; - } - - ret = strptime(s, "%Y%m%d%H%M%SZ", &t2); - if ( ret == NULL ) { - printf("failure: strptime [\n" - "returned NULL with Z\n" - "]\n"); - return false; - } - - if ( *ret != '\0' ) { - printf("failure: strptime [\n" - "ret doesn't point to '\\0'\n" - "]\n"); - return false; - } - -#define CMP_TM_ELEMENT(t1,t2,elem) \ - if (t1.elem != t2.elem) { \ - printf("failure: strptime [\n" \ - "result differs if the format string has a 'Z' at the end\n" \ - "element: %s %d != %d\n" \ - "]\n", \ - __STRING(elen), t1.elem, t2.elem); \ - return false; \ - } - - CMP_TM_ELEMENT(t,t2,tm_sec); - CMP_TM_ELEMENT(t,t2,tm_min); - CMP_TM_ELEMENT(t,t2,tm_hour); - CMP_TM_ELEMENT(t,t2,tm_mday); - CMP_TM_ELEMENT(t,t2,tm_mon); - CMP_TM_ELEMENT(t,t2,tm_year); - CMP_TM_ELEMENT(t,t2,tm_wday); - CMP_TM_ELEMENT(t,t2,tm_yday); - CMP_TM_ELEMENT(t,t2,tm_isdst); - - if (t.tm_sec != 46) { - printf("failure: strptime [\n" - "tm_sec: expected: 46, got: %d\n" - "]\n", - t.tm_sec); - return false; - } - - if (t.tm_min != 15) { - printf("failure: strptime [\n" - "tm_min: expected: 15, got: %d\n" - "]\n", - t.tm_min); - return false; - } - - if (t.tm_hour != 10) { - printf("failure: strptime [\n" - "tm_hour: expected: 10, got: %d\n" - "]\n", - t.tm_hour); - return false; - } - - if (t.tm_mday != 14) { - printf("failure: strptime [\n" - "tm_mday: expected: 14, got: %d\n" - "]\n", - t.tm_mday); - return false; - } - - if (t.tm_mon != 3) { - printf("failure: strptime [\n" - "tm_mon: expected: 3, got: %d\n" - "]\n", - t.tm_mon); - return false; - } - - if (t.tm_year != 107) { - printf("failure: strptime [\n" - "tm_year: expected: 107, got: %d\n" - "]\n", - t.tm_year); - return false; - } - - if (t.tm_wday != 6) { /* saturday */ - printf("failure: strptime [\n" - "tm_wday: expected: 6, got: %d\n" - "]\n", - t.tm_wday); - return false; - } - - if (t.tm_yday != 103) { - printf("failure: strptime [\n" - "tm_yday: expected: 103, got: %d\n" - "]\n", - t.tm_yday); - return false; - } - - /* we don't test this as it depends on the host configuration - if (t.tm_isdst != 0) { - printf("failure: strptime [\n" - "tm_isdst: expected: 0, got: %d\n" - "]\n", - t.tm_isdst); - return false; - }*/ - - printf("success: strptime\n"); - - return true; -} - -#ifdef LIBREPLACE_CONFIGURE_TEST_STRPTIME -int main (void) -{ - int ret; - ret = libreplace_test_strptime(); - if (ret == false) return 1; - return 0; -} -#endif diff --git a/ldb-2.0.8/lib/replace/tests/testsuite.c b/ldb-2.0.8/lib/replace/tests/testsuite.c deleted file mode 100644 index dba545e..0000000 --- a/ldb-2.0.8/lib/replace/tests/testsuite.c +++ /dev/null @@ -1,1151 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - libreplace tests - - Copyright (C) Jelmer Vernooij 2006 - - ** NOTE! The following LGPL license applies to the talloc - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#include "replace-test.h" -#include "replace-testsuite.h" - -/* - we include all the system/ include files here so that libreplace tests - them in the build farm -*/ -#include "system/capability.h" -#include "system/dir.h" -#include "system/filesys.h" -#include "system/glob.h" -#include "system/iconv.h" -#include "system/locale.h" -#include "system/network.h" -#include "system/passwd.h" -#include "system/readline.h" -#include "system/select.h" -#include "system/shmem.h" -#include "system/syslog.h" -#include "system/terminal.h" -#include "system/time.h" -#include "system/wait.h" -#include "system/aio.h" - -#define TESTFILE "testfile.dat" - - -/* - test ftruncate() function - */ -static int test_ftruncate(void) -{ - struct stat st; - int fd; - const int size = 1234; - printf("test: ftruncate\n"); - unlink(TESTFILE); - fd = open(TESTFILE, O_RDWR|O_CREAT, 0600); - if (fd == -1) { - printf("failure: ftruncate [\n" - "creating '%s' failed - %s\n]\n", TESTFILE, strerror(errno)); - return false; - } - if (ftruncate(fd, size) != 0) { - printf("failure: ftruncate [\n%s\n]\n", strerror(errno)); - close(fd); - return false; - } - if (fstat(fd, &st) != 0) { - printf("failure: ftruncate [\nfstat failed - %s\n]\n", strerror(errno)); - close(fd); - return false; - } - if (st.st_size != size) { - printf("failure: ftruncate [\ngave wrong size %d - expected %d\n]\n", - (int)st.st_size, size); - close(fd); - return false; - } - unlink(TESTFILE); - printf("success: ftruncate\n"); - close(fd); - return true; -} - -/* - test strlcpy() function. - see http://www.gratisoft.us/todd/papers/strlcpy.html - */ -static int test_strlcpy(void) -{ - char buf[4]; - const struct { - const char *src; - size_t result; - } tests[] = { - { "abc", 3 }, - { "abcdef", 6 }, - { "abcd", 4 }, - { "", 0 }, - { NULL, 0 } - }; - int i; - printf("test: strlcpy\n"); - for (i=0;tests[i].src;i++) { - if (strlcpy(buf, tests[i].src, sizeof(buf)) != tests[i].result) { - printf("failure: strlcpy [\ntest %d failed\n]\n", i); - return false; - } - } - printf("success: strlcpy\n"); - return true; -} - -static int test_strlcat(void) -{ - char tmp[10]; - printf("test: strlcat\n"); - strlcpy(tmp, "", sizeof(tmp)); - if (strlcat(tmp, "bla", 3) != 3) { - printf("failure: strlcat [\ninvalid return code\n]\n"); - return false; - } - if (strcmp(tmp, "bl") != 0) { - printf("failure: strlcat [\nexpected \"bl\", got \"%s\"\n]\n", - tmp); - return false; - } - - strlcpy(tmp, "da", sizeof(tmp)); - if (strlcat(tmp, "me", 4) != 4) { - printf("failure: strlcat [\nexpected \"dam\", got \"%s\"\n]\n", - tmp); - return false; - } - - printf("success: strlcat\n"); - return true; -} - -static int test_mktime(void) -{ - /* FIXME */ - return true; -} - -static int test_initgroups(void) -{ - /* FIXME */ - return true; -} - -static int test_memmove(void) -{ - /* FIXME */ - return true; -} - -static int test_strdup(void) -{ - char *x; - printf("test: strdup\n"); - x = strdup("bla"); - if (strcmp("bla", x) != 0) { - printf("failure: strdup [\nfailed: expected \"bla\", got \"%s\"\n]\n", - x); - return false; - } - free(x); - printf("success: strdup\n"); - return true; -} - -static int test_setlinebuf(void) -{ - printf("test: setlinebuf\n"); - setlinebuf(stdout); - printf("success: setlinebuf\n"); - return true; -} - -static int test_vsyslog(void) -{ - /* FIXME */ - return true; -} - -static int test_timegm(void) -{ - /* FIXME */ - return true; -} - -static int test_setenv(void) -{ -#define TEST_SETENV(key, value, overwrite, result) do { \ - int _ret; \ - char *_v; \ - _ret = setenv(key, value, overwrite); \ - if (_ret != 0) { \ - printf("failure: setenv [\n" \ - "setenv(%s, %s, %d) failed\n" \ - "]\n", \ - key, value, overwrite); \ - return false; \ - } \ - _v=getenv(key); \ - if (!_v) { \ - printf("failure: setenv [\n" \ - "getenv(%s) returned NULL\n" \ - "]\n", \ - key); \ - return false; \ - } \ - if (strcmp(result, _v) != 0) { \ - printf("failure: setenv [\n" \ - "getenv(%s): '%s' != '%s'\n" \ - "]\n", \ - key, result, _v); \ - return false; \ - } \ -} while(0) - -#define TEST_UNSETENV(key) do { \ - char *_v; \ - unsetenv(key); \ - _v=getenv(key); \ - if (_v) { \ - printf("failure: setenv [\n" \ - "getenv(%s): NULL != '%s'\n" \ - "]\n", \ - SETENVTEST_KEY, _v); \ - return false; \ - } \ -} while (0) - -#define SETENVTEST_KEY "SETENVTESTKEY" -#define SETENVTEST_VAL "SETENVTESTVAL" - - printf("test: setenv\n"); - TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"1", 0, SETENVTEST_VAL"1"); - TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"2", 0, SETENVTEST_VAL"1"); - TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"3", 1, SETENVTEST_VAL"3"); - TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"4", 1, SETENVTEST_VAL"4"); - TEST_UNSETENV(SETENVTEST_KEY); - TEST_UNSETENV(SETENVTEST_KEY); - TEST_SETENV(SETENVTEST_KEY, SETENVTEST_VAL"5", 0, SETENVTEST_VAL"5"); - TEST_UNSETENV(SETENVTEST_KEY); - TEST_UNSETENV(SETENVTEST_KEY); - printf("success: setenv\n"); - return true; -} - -static int test_strndup(void) -{ - char *x; - printf("test: strndup\n"); - x = strndup("bla", 0); - if (strcmp(x, "") != 0) { - printf("failure: strndup [\ninvalid\n]\n"); - return false; - } - free(x); - x = strndup("bla", 2); - if (strcmp(x, "bl") != 0) { - printf("failure: strndup [\ninvalid\n]\n"); - return false; - } - free(x); - x = strndup("bla", 10); - if (strcmp(x, "bla") != 0) { - printf("failure: strndup [\ninvalid\n]\n"); - free(x); - return false; - } - free(x); - printf("success: strndup\n"); - return true; -} - -static int test_strnlen(void) -{ - printf("test: strnlen\n"); - if (strnlen("bla", 2) != 2) { - printf("failure: strnlen [\nunexpected length\n]\n"); - return false; - } - - if (strnlen("some text\n", 0) != 0) { - printf("failure: strnlen [\nunexpected length\n]\n"); - return false; - } - - if (strnlen("some text", 20) != 9) { - printf("failure: strnlen [\nunexpected length\n]\n"); - return false; - } - - printf("success: strnlen\n"); - return true; -} - -static int test_waitpid(void) -{ - /* FIXME */ - return true; -} - -static int test_seteuid(void) -{ - /* FIXME */ - return true; -} - -static int test_setegid(void) -{ - /* FIXME */ - return true; -} - -static int test_asprintf(void) -{ - char *x; - printf("test: asprintf\n"); - if (asprintf(&x, "%d", 9) != 1) { - printf("failure: asprintf [\ngenerate asprintf\n]\n"); - return false; - } - if (strcmp(x, "9") != 0) { - printf("failure: asprintf [\ngenerate asprintf\n]\n"); - return false; - } - if (asprintf(&x, "dat%s", "a") != 4) { - printf("failure: asprintf [\ngenerate asprintf\n]\n"); - return false; - } - if (strcmp(x, "data") != 0) { - printf("failure: asprintf [\ngenerate asprintf\n]\n"); - return false; - } - printf("success: asprintf\n"); - return true; -} - -static int test_snprintf(void) -{ - char tmp[10]; - printf("test: snprintf\n"); - if (snprintf(tmp, 3, "foo%d", 9) != 4) { - printf("failure: snprintf [\nsnprintf return code failed\n]\n"); - return false; - } - - if (strcmp(tmp, "fo") != 0) { - printf("failure: snprintf [\nsnprintf failed\n]\n"); - return false; - } - - printf("success: snprintf\n"); - return true; -} - -static int test_vasprintf(void) -{ - /* FIXME */ - return true; -} - -static int test_vsnprintf(void) -{ - /* FIXME */ - return true; -} - -static int test_opendir(void) -{ - /* FIXME */ - return true; -} - -static int test_readdir(void) -{ - printf("test: readdir\n"); - if (test_readdir_os2_delete() != 0) { - return false; - } - printf("success: readdir\n"); - return true; -} - -static int test_telldir(void) -{ - /* FIXME */ - return true; -} - -static int test_seekdir(void) -{ - /* FIXME */ - return true; -} - -static int test_dlopen(void) -{ - /* FIXME: test dlopen, dlsym, dlclose, dlerror */ - return true; -} - - -static int test_chroot(void) -{ - /* FIXME: chroot() */ - return true; -} - -static int test_bzero(void) -{ - /* FIXME: bzero */ - return true; -} - -static int test_strerror(void) -{ - /* FIXME */ - return true; -} - -static int test_errno(void) -{ - printf("test: errno\n"); - errno = 3; - if (errno != 3) { - printf("failure: errno [\nerrno failed\n]\n"); - return false; - } - - printf("success: errno\n"); - return true; -} - -static int test_mkdtemp(void) -{ - /* FIXME */ - return true; -} - -static int test_mkstemp(void) -{ - /* FIXME */ - return true; -} - -static int test_pread(void) -{ - /* FIXME */ - return true; -} - -static int test_pwrite(void) -{ - /* FIXME */ - return true; -} - -static int test_inet_ntoa(void) -{ - /* FIXME */ - return true; -} - -#define TEST_STRTO_X(type,fmt,func,str,base,res,diff,rrnoo) do {\ - type _v; \ - char _s[64]; \ - char *_p = NULL;\ - char *_ep = NULL; \ - strlcpy(_s, str, sizeof(_s));\ - if (diff >= 0) { \ - _ep = &_s[diff]; \ - } \ - errno = 0; \ - _v = func(_s, &_p, base); \ - if (errno != rrnoo) { \ - printf("failure: %s [\n" \ - "\t%s\n" \ - "\t%s(\"%s\",%d,%d): " fmt " (=/!)= " fmt "\n" \ - "\terrno: %d != %d\n" \ - "]\n", \ - __STRING(func), __location__, __STRING(func), \ - str, diff, base, res, _v, rrnoo, errno); \ - return false; \ - } else if (_v != res) { \ - printf("failure: %s [\n" \ - "\t%s\n" \ - "\t%s(\"%s\",%d,%d): " fmt " != " fmt "\n" \ - "]\n", \ - __STRING(func), __location__, __STRING(func), \ - str, diff, base, res, _v); \ - return false; \ - } else if (_p != _ep) { \ - printf("failure: %s [\n" \ - "\t%s\n" \ - "\t%s(\"%s\",%d,%d): " fmt " (=/!)= " fmt "\n" \ - "\tptr: %p - %p = %d != %d\n" \ - "]\n", \ - __STRING(func), __location__, __STRING(func), \ - str, diff, base, res, _v, _ep, _p, (int)(diff - (_ep - _p)), diff); \ - return false; \ - } \ -} while (0) - -static int test_strtoll(void) -{ - printf("test: strtoll\n"); - -#define TEST_STRTOLL(str,base,res,diff,errnoo) TEST_STRTO_X(long long int, "%lld", strtoll,str,base,res,diff,errnoo) - - TEST_STRTOLL("15", 10, 15LL, 2, 0); - TEST_STRTOLL(" 15", 10, 15LL, 4, 0); - TEST_STRTOLL("15", 0, 15LL, 2, 0); - TEST_STRTOLL(" 15 ", 0, 15LL, 3, 0); - TEST_STRTOLL("+15", 10, 15LL, 3, 0); - TEST_STRTOLL(" +15", 10, 15LL, 5, 0); - TEST_STRTOLL("+15", 0, 15LL, 3, 0); - TEST_STRTOLL(" +15 ", 0, 15LL, 4, 0); - TEST_STRTOLL("-15", 10, -15LL, 3, 0); - TEST_STRTOLL(" -15", 10, -15LL, 5, 0); - TEST_STRTOLL("-15", 0, -15LL, 3, 0); - TEST_STRTOLL(" -15 ", 0, -15LL, 4, 0); - TEST_STRTOLL("015", 10, 15LL, 3, 0); - TEST_STRTOLL(" 015", 10, 15LL, 5, 0); - TEST_STRTOLL("015", 0, 13LL, 3, 0); - TEST_STRTOLL(" 015", 0, 13LL, 5, 0); - TEST_STRTOLL("0x15", 10, 0LL, 1, 0); - TEST_STRTOLL(" 0x15", 10, 0LL, 3, 0); - TEST_STRTOLL("0x15", 0, 21LL, 4, 0); - TEST_STRTOLL(" 0x15", 0, 21LL, 6, 0); - - TEST_STRTOLL("10", 16, 16LL, 2, 0); - TEST_STRTOLL(" 10 ", 16, 16LL, 4, 0); - TEST_STRTOLL("0x10", 16, 16LL, 4, 0); - TEST_STRTOLL("0x10", 0, 16LL, 4, 0); - TEST_STRTOLL(" 0x10 ", 0, 16LL, 5, 0); - TEST_STRTOLL("+10", 16, 16LL, 3, 0); - TEST_STRTOLL(" +10 ", 16, 16LL, 5, 0); - TEST_STRTOLL("+0x10", 16, 16LL, 5, 0); - TEST_STRTOLL("+0x10", 0, 16LL, 5, 0); - TEST_STRTOLL(" +0x10 ", 0, 16LL, 6, 0); - TEST_STRTOLL("-10", 16, -16LL, 3, 0); - TEST_STRTOLL(" -10 ", 16, -16LL, 5, 0); - TEST_STRTOLL("-0x10", 16, -16LL, 5, 0); - TEST_STRTOLL("-0x10", 0, -16LL, 5, 0); - TEST_STRTOLL(" -0x10 ", 0, -16LL, 6, 0); - TEST_STRTOLL("010", 16, 16LL, 3, 0); - TEST_STRTOLL(" 010 ", 16, 16LL, 5, 0); - TEST_STRTOLL("-010", 16, -16LL, 4, 0); - - TEST_STRTOLL("11", 8, 9LL, 2, 0); - TEST_STRTOLL("011", 8, 9LL, 3, 0); - TEST_STRTOLL("011", 0, 9LL, 3, 0); - TEST_STRTOLL("-11", 8, -9LL, 3, 0); - TEST_STRTOLL("-011", 8, -9LL, 4, 0); - TEST_STRTOLL("-011", 0, -9LL, 4, 0); - - TEST_STRTOLL("011", 8, 9LL, 3, 0); - TEST_STRTOLL("011", 0, 9LL, 3, 0); - TEST_STRTOLL("-11", 8, -9LL, 3, 0); - TEST_STRTOLL("-011", 8, -9LL, 4, 0); - TEST_STRTOLL("-011", 0, -9LL, 4, 0); - - TEST_STRTOLL("Text", 0, 0LL, 0, 0); - - TEST_STRTOLL("9223372036854775807", 10, 9223372036854775807LL, 19, 0); - TEST_STRTOLL("9223372036854775807", 0, 9223372036854775807LL, 19, 0); - TEST_STRTOLL("9223372036854775808", 0, 9223372036854775807LL, 19, ERANGE); - TEST_STRTOLL("9223372036854775808", 10, 9223372036854775807LL, 19, ERANGE); - TEST_STRTOLL("0x7FFFFFFFFFFFFFFF", 0, 9223372036854775807LL, 18, 0); - TEST_STRTOLL("0x7FFFFFFFFFFFFFFF", 16, 9223372036854775807LL, 18, 0); - TEST_STRTOLL("7FFFFFFFFFFFFFFF", 16, 9223372036854775807LL, 16, 0); - TEST_STRTOLL("0x8000000000000000", 0, 9223372036854775807LL, 18, ERANGE); - TEST_STRTOLL("0x8000000000000000", 16, 9223372036854775807LL, 18, ERANGE); - TEST_STRTOLL("80000000000000000", 16, 9223372036854775807LL, 17, ERANGE); - TEST_STRTOLL("0777777777777777777777", 0, 9223372036854775807LL, 22, 0); - TEST_STRTOLL("0777777777777777777777", 8, 9223372036854775807LL, 22, 0); - TEST_STRTOLL("777777777777777777777", 8, 9223372036854775807LL, 21, 0); - TEST_STRTOLL("01000000000000000000000", 0, 9223372036854775807LL, 23, ERANGE); - TEST_STRTOLL("01000000000000000000000", 8, 9223372036854775807LL, 23, ERANGE); - TEST_STRTOLL("1000000000000000000000", 8, 9223372036854775807LL, 22, ERANGE); - - TEST_STRTOLL("-9223372036854775808", 10, -9223372036854775807LL -1, 20, 0); - TEST_STRTOLL("-9223372036854775808", 0, -9223372036854775807LL -1, 20, 0); - TEST_STRTOLL("-9223372036854775809", 0, -9223372036854775807LL -1, 20, ERANGE); - TEST_STRTOLL("-9223372036854775809", 10, -9223372036854775807LL -1, 20, ERANGE); - TEST_STRTOLL("-0x8000000000000000", 0, -9223372036854775807LL -1, 19, 0); - TEST_STRTOLL("-0x8000000000000000", 16, -9223372036854775807LL -1, 19, 0); - TEST_STRTOLL("-8000000000000000", 16, -9223372036854775807LL -1, 17, 0); - TEST_STRTOLL("-0x8000000000000001", 0, -9223372036854775807LL -1, 19, ERANGE); - TEST_STRTOLL("-0x8000000000000001", 16, -9223372036854775807LL -1, 19, ERANGE); - TEST_STRTOLL("-80000000000000001", 16, -9223372036854775807LL -1, 18, ERANGE); - TEST_STRTOLL("-01000000000000000000000",0, -9223372036854775807LL -1, 24, 0); - TEST_STRTOLL("-01000000000000000000000",8, -9223372036854775807LL -1, 24, 0); - TEST_STRTOLL("-1000000000000000000000", 8, -9223372036854775807LL -1, 23, 0); - TEST_STRTOLL("-01000000000000000000001",0, -9223372036854775807LL -1, 24, ERANGE); - TEST_STRTOLL("-01000000000000000000001",8, -9223372036854775807LL -1, 24, ERANGE); - TEST_STRTOLL("-1000000000000000000001", 8, -9223372036854775807LL -1, 23, ERANGE); - - printf("success: strtoll\n"); - return true; -} - -static int test_strtoull(void) -{ - printf("test: strtoull\n"); - -#define TEST_STRTOULL(str,base,res,diff,errnoo) TEST_STRTO_X(long long unsigned int,"%llu",strtoull,str,base,res,diff,errnoo) - - TEST_STRTOULL("15", 10, 15LLU, 2, 0); - TEST_STRTOULL(" 15", 10, 15LLU, 4, 0); - TEST_STRTOULL("15", 0, 15LLU, 2, 0); - TEST_STRTOULL(" 15 ", 0, 15LLU, 3, 0); - TEST_STRTOULL("+15", 10, 15LLU, 3, 0); - TEST_STRTOULL(" +15", 10, 15LLU, 5, 0); - TEST_STRTOULL("+15", 0, 15LLU, 3, 0); - TEST_STRTOULL(" +15 ", 0, 15LLU, 4, 0); - TEST_STRTOULL("-15", 10, 18446744073709551601LLU, 3, 0); - TEST_STRTOULL(" -15", 10, 18446744073709551601LLU, 5, 0); - TEST_STRTOULL("-15", 0, 18446744073709551601LLU, 3, 0); - TEST_STRTOULL(" -15 ", 0, 18446744073709551601LLU, 4, 0); - TEST_STRTOULL("015", 10, 15LLU, 3, 0); - TEST_STRTOULL(" 015", 10, 15LLU, 5, 0); - TEST_STRTOULL("015", 0, 13LLU, 3, 0); - TEST_STRTOULL(" 015", 0, 13LLU, 5, 0); - TEST_STRTOULL("0x15", 10, 0LLU, 1, 0); - TEST_STRTOULL(" 0x15", 10, 0LLU, 3, 0); - TEST_STRTOULL("0x15", 0, 21LLU, 4, 0); - TEST_STRTOULL(" 0x15", 0, 21LLU, 6, 0); - - TEST_STRTOULL("10", 16, 16LLU, 2, 0); - TEST_STRTOULL(" 10 ", 16, 16LLU, 4, 0); - TEST_STRTOULL("0x10", 16, 16LLU, 4, 0); - TEST_STRTOULL("0x10", 0, 16LLU, 4, 0); - TEST_STRTOULL(" 0x10 ", 0, 16LLU, 5, 0); - TEST_STRTOULL("+10", 16, 16LLU, 3, 0); - TEST_STRTOULL(" +10 ", 16, 16LLU, 5, 0); - TEST_STRTOULL("+0x10", 16, 16LLU, 5, 0); - TEST_STRTOULL("+0x10", 0, 16LLU, 5, 0); - TEST_STRTOULL(" +0x10 ", 0, 16LLU, 6, 0); - TEST_STRTOULL("-10", 16, -16LLU, 3, 0); - TEST_STRTOULL(" -10 ", 16, -16LLU, 5, 0); - TEST_STRTOULL("-0x10", 16, -16LLU, 5, 0); - TEST_STRTOULL("-0x10", 0, -16LLU, 5, 0); - TEST_STRTOULL(" -0x10 ", 0, -16LLU, 6, 0); - TEST_STRTOULL("010", 16, 16LLU, 3, 0); - TEST_STRTOULL(" 010 ", 16, 16LLU, 5, 0); - TEST_STRTOULL("-010", 16, -16LLU, 4, 0); - - TEST_STRTOULL("11", 8, 9LLU, 2, 0); - TEST_STRTOULL("011", 8, 9LLU, 3, 0); - TEST_STRTOULL("011", 0, 9LLU, 3, 0); - TEST_STRTOULL("-11", 8, -9LLU, 3, 0); - TEST_STRTOULL("-011", 8, -9LLU, 4, 0); - TEST_STRTOULL("-011", 0, -9LLU, 4, 0); - - TEST_STRTOULL("011", 8, 9LLU, 3, 0); - TEST_STRTOULL("011", 0, 9LLU, 3, 0); - TEST_STRTOULL("-11", 8, -9LLU, 3, 0); - TEST_STRTOULL("-011", 8, -9LLU, 4, 0); - TEST_STRTOULL("-011", 0, -9LLU, 4, 0); - - TEST_STRTOULL("Text", 0, 0LLU, 0, 0); - - TEST_STRTOULL("9223372036854775807", 10, 9223372036854775807LLU, 19, 0); - TEST_STRTOULL("9223372036854775807", 0, 9223372036854775807LLU, 19, 0); - TEST_STRTOULL("9223372036854775808", 0, 9223372036854775808LLU, 19, 0); - TEST_STRTOULL("9223372036854775808", 10, 9223372036854775808LLU, 19, 0); - TEST_STRTOULL("0x7FFFFFFFFFFFFFFF", 0, 9223372036854775807LLU, 18, 0); - TEST_STRTOULL("0x7FFFFFFFFFFFFFFF", 16, 9223372036854775807LLU, 18, 0); - TEST_STRTOULL("7FFFFFFFFFFFFFFF", 16, 9223372036854775807LLU, 16, 0); - TEST_STRTOULL("0x8000000000000000", 0, 9223372036854775808LLU, 18, 0); - TEST_STRTOULL("0x8000000000000000", 16, 9223372036854775808LLU, 18, 0); - TEST_STRTOULL("8000000000000000", 16, 9223372036854775808LLU, 16, 0); - TEST_STRTOULL("0777777777777777777777", 0, 9223372036854775807LLU, 22, 0); - TEST_STRTOULL("0777777777777777777777", 8, 9223372036854775807LLU, 22, 0); - TEST_STRTOULL("777777777777777777777", 8, 9223372036854775807LLU, 21, 0); - TEST_STRTOULL("01000000000000000000000",0, 9223372036854775808LLU, 23, 0); - TEST_STRTOULL("01000000000000000000000",8, 9223372036854775808LLU, 23, 0); - TEST_STRTOULL("1000000000000000000000", 8, 9223372036854775808LLU, 22, 0); - - TEST_STRTOULL("-9223372036854775808", 10, 9223372036854775808LLU, 20, 0); - TEST_STRTOULL("-9223372036854775808", 0, 9223372036854775808LLU, 20, 0); - TEST_STRTOULL("-9223372036854775809", 0, 9223372036854775807LLU, 20, 0); - TEST_STRTOULL("-9223372036854775809", 10, 9223372036854775807LLU, 20, 0); - TEST_STRTOULL("-0x8000000000000000", 0, 9223372036854775808LLU, 19, 0); - TEST_STRTOULL("-0x8000000000000000", 16, 9223372036854775808LLU, 19, 0); - TEST_STRTOULL("-8000000000000000", 16, 9223372036854775808LLU, 17, 0); - TEST_STRTOULL("-0x8000000000000001", 0, 9223372036854775807LLU, 19, 0); - TEST_STRTOULL("-0x8000000000000001", 16, 9223372036854775807LLU, 19, 0); - TEST_STRTOULL("-8000000000000001", 16, 9223372036854775807LLU, 17, 0); - TEST_STRTOULL("-01000000000000000000000",0, 9223372036854775808LLU, 24, 0); - TEST_STRTOULL("-01000000000000000000000",8, 9223372036854775808LLU, 24, 0); - TEST_STRTOULL("-1000000000000000000000",8, 9223372036854775808LLU, 23, 0); - TEST_STRTOULL("-01000000000000000000001",0, 9223372036854775807LLU, 24, 0); - TEST_STRTOULL("-01000000000000000000001",8, 9223372036854775807LLU, 24, 0); - TEST_STRTOULL("-1000000000000000000001",8, 9223372036854775807LLU, 23, 0); - - TEST_STRTOULL("18446744073709551615", 0, 18446744073709551615LLU, 20, 0); - TEST_STRTOULL("18446744073709551615", 10, 18446744073709551615LLU, 20, 0); - TEST_STRTOULL("18446744073709551616", 0, 18446744073709551615LLU, 20, ERANGE); - TEST_STRTOULL("18446744073709551616", 10, 18446744073709551615LLU, 20, ERANGE); - TEST_STRTOULL("0xFFFFFFFFFFFFFFFF", 0, 18446744073709551615LLU, 18, 0); - TEST_STRTOULL("0xFFFFFFFFFFFFFFFF", 16, 18446744073709551615LLU, 18, 0); - TEST_STRTOULL("FFFFFFFFFFFFFFFF", 16, 18446744073709551615LLU, 16, 0); - TEST_STRTOULL("0x10000000000000000", 0, 18446744073709551615LLU, 19, ERANGE); - TEST_STRTOULL("0x10000000000000000", 16, 18446744073709551615LLU, 19, ERANGE); - TEST_STRTOULL("10000000000000000", 16, 18446744073709551615LLU, 17, ERANGE); - TEST_STRTOULL("01777777777777777777777",0, 18446744073709551615LLU, 23, 0); - TEST_STRTOULL("01777777777777777777777",8, 18446744073709551615LLU, 23, 0); - TEST_STRTOULL("1777777777777777777777", 8, 18446744073709551615LLU, 22, 0); - TEST_STRTOULL("02000000000000000000000",0, 18446744073709551615LLU, 23, ERANGE); - TEST_STRTOULL("02000000000000000000000",8, 18446744073709551615LLU, 23, ERANGE); - TEST_STRTOULL("2000000000000000000000", 8, 18446744073709551615LLU, 22, ERANGE); - - TEST_STRTOULL("-18446744073709551615", 0, 1LLU, 21, 0); - TEST_STRTOULL("-18446744073709551615", 10, 1LLU, 21, 0); - TEST_STRTOULL("-18446744073709551616", 0, 18446744073709551615LLU, 21, ERANGE); - TEST_STRTOULL("-18446744073709551616", 10, 18446744073709551615LLU, 21, ERANGE); - TEST_STRTOULL("-0xFFFFFFFFFFFFFFFF", 0, 1LLU, 19, 0); - TEST_STRTOULL("-0xFFFFFFFFFFFFFFFF", 16, 1LLU, 19, 0); - TEST_STRTOULL("-FFFFFFFFFFFFFFFF", 16, 1LLU, 17, 0); - TEST_STRTOULL("-0x10000000000000000", 0, 18446744073709551615LLU, 20, ERANGE); - TEST_STRTOULL("-0x10000000000000000", 16, 18446744073709551615LLU, 20, ERANGE); - TEST_STRTOULL("-10000000000000000", 16, 18446744073709551615LLU, 18, ERANGE); - TEST_STRTOULL("-01777777777777777777777",0, 1LLU, 24, 0); - TEST_STRTOULL("-01777777777777777777777",8, 1LLU, 24, 0); - TEST_STRTOULL("-1777777777777777777777",8, 1LLU, 23, 0); - TEST_STRTOULL("-02000000000000000000000",0, 18446744073709551615LLU, 24, ERANGE); - TEST_STRTOULL("-02000000000000000000000",8, 18446744073709551615LLU, 24, ERANGE); - TEST_STRTOULL("-2000000000000000000000",8, 18446744073709551615LLU, 23, ERANGE); - - printf("success: strtoull\n"); - return true; -} - -/* -FIXME: -Types: -bool -socklen_t -uint{8,16,32,64}_t -int{8,16,32,64}_t -intptr_t - -Constants: -PATH_NAME_MAX -UINT{16,32,64}_MAX -INT32_MAX -*/ - -static int test_va_copy(void) -{ - /* FIXME */ - return true; -} - -static int test_FUNCTION(void) -{ - printf("test: FUNCTION\n"); - if (strcmp(__FUNCTION__, "test_FUNCTION") != 0) { - printf("failure: FUNCTION [\nFUNCTION invalid\n]\n"); - return false; - } - printf("success: FUNCTION\n"); - return true; -} - -static int test_MIN(void) -{ - printf("test: MIN\n"); - if (MIN(20, 1) != 1) { - printf("failure: MIN [\nMIN invalid\n]\n"); - return false; - } - if (MIN(1, 20) != 1) { - printf("failure: MIN [\nMIN invalid\n]\n"); - return false; - } - printf("success: MIN\n"); - return true; -} - -static int test_MAX(void) -{ - printf("test: MAX\n"); - if (MAX(20, 1) != 20) { - printf("failure: MAX [\nMAX invalid\n]\n"); - return false; - } - if (MAX(1, 20) != 20) { - printf("failure: MAX [\nMAX invalid\n]\n"); - return false; - } - printf("success: MAX\n"); - return true; -} - -static int test_socketpair(void) -{ - int sock[2]; - char buf[20]; - - printf("test: socketpair\n"); - - if (socketpair(AF_UNIX, SOCK_STREAM, 0, sock) == -1) { - printf("failure: socketpair [\n" - "socketpair() failed\n" - "]\n"); - return false; - } - - if (write(sock[1], "automatisch", 12) == -1) { - printf("failure: socketpair [\n" - "write() failed: %s\n" - "]\n", strerror(errno)); - return false; - } - - if (read(sock[0], buf, 12) == -1) { - printf("failure: socketpair [\n" - "read() failed: %s\n" - "]\n", strerror(errno)); - return false; - } - - if (strcmp(buf, "automatisch") != 0) { - printf("failure: socketpair [\n" - "expected: automatisch, got: %s\n" - "]\n", buf); - return false; - } - - printf("success: socketpair\n"); - - return true; -} - -extern int libreplace_test_strptime(void); - -static int test_strptime(void) -{ - return libreplace_test_strptime(); -} - -extern int getifaddrs_test(void); - -static int test_getifaddrs(void) -{ - - printf("test: getifaddrs\n"); - - if (getifaddrs_test() != 0) { - printf("failure: getifaddrs\n"); - return false; - } - - printf("success: getifaddrs\n"); - return true; -} - -static int test_utime(void) -{ - struct utimbuf u; - struct stat st1, st2, st3; - int fd; - - printf("test: utime\n"); - unlink(TESTFILE); - - fd = open(TESTFILE, O_RDWR|O_CREAT, 0600); - if (fd == -1) { - printf("failure: utime [\n" - "creating '%s' failed - %s\n]\n", - TESTFILE, strerror(errno)); - return false; - } - - if (fstat(fd, &st1) != 0) { - printf("failure: utime [\n" - "fstat (1) failed - %s\n]\n", - strerror(errno)); - close(fd); - return false; - } - - u.actime = st1.st_atime + 300; - u.modtime = st1.st_mtime - 300; - if (utime(TESTFILE, &u) != 0) { - printf("failure: utime [\n" - "utime(&u) failed - %s\n]\n", - strerror(errno)); - close(fd); - return false; - } - - if (fstat(fd, &st2) != 0) { - printf("failure: utime [\n" - "fstat (2) failed - %s\n]\n", - strerror(errno)); - close(fd); - return false; - } - - if (utime(TESTFILE, NULL) != 0) { - printf("failure: utime [\n" - "utime(NULL) failed - %s\n]\n", - strerror(errno)); - close(fd); - return false; - } - - if (fstat(fd, &st3) != 0) { - printf("failure: utime [\n" - "fstat (3) failed - %s\n]\n", - strerror(errno)); - close(fd); - return false; - } - -#define CMP_VAL(a,c,b) do { \ - if (a c b) { \ - printf("failure: utime [\n" \ - "%s: %s(%d) %s %s(%d)\n]\n", \ - __location__, \ - #a, (int)a, #c, #b, (int)b); \ - close(fd); \ - return false; \ - } \ -} while(0) -#define EQUAL_VAL(a,b) CMP_VAL(a,!=,b) -#define GREATER_VAL(a,b) CMP_VAL(a,<=,b) -#define LESSER_VAL(a,b) CMP_VAL(a,>=,b) - - EQUAL_VAL(st2.st_atime, st1.st_atime + 300); - EQUAL_VAL(st2.st_mtime, st1.st_mtime - 300); - LESSER_VAL(st3.st_atime, st2.st_atime); - GREATER_VAL(st3.st_mtime, st2.st_mtime); - -#undef CMP_VAL -#undef EQUAL_VAL -#undef GREATER_VAL -#undef LESSER_VAL - - unlink(TESTFILE); - printf("success: utime\n"); - close(fd); - return true; -} - -static int test_utimes(void) -{ - struct timeval tv[2]; - struct stat st1, st2; - int fd; - - printf("test: utimes\n"); - unlink(TESTFILE); - - fd = open(TESTFILE, O_RDWR|O_CREAT, 0600); - if (fd == -1) { - printf("failure: utimes [\n" - "creating '%s' failed - %s\n]\n", - TESTFILE, strerror(errno)); - return false; - } - - if (fstat(fd, &st1) != 0) { - printf("failure: utimes [\n" - "fstat (1) failed - %s\n]\n", - strerror(errno)); - close(fd); - return false; - } - - ZERO_STRUCT(tv); - tv[0].tv_sec = st1.st_atime + 300; - tv[1].tv_sec = st1.st_mtime - 300; - if (utimes(TESTFILE, tv) != 0) { - printf("failure: utimes [\n" - "utimes(tv) failed - %s\n]\n", - strerror(errno)); - close(fd); - return false; - } - - if (fstat(fd, &st2) != 0) { - printf("failure: utimes [\n" - "fstat (2) failed - %s\n]\n", - strerror(errno)); - close(fd); - return false; - } - -#define EQUAL_VAL(a,b) do { \ - if (a != b) { \ - printf("failure: utimes [\n" \ - "%s: %s(%d) != %s(%d)\n]\n", \ - __location__, \ - #a, (int)a, #b, (int)b); \ - close(fd); \ - return false; \ - } \ -} while(0) - - EQUAL_VAL(st2.st_atime, st1.st_atime + 300); - EQUAL_VAL(st2.st_mtime, st1.st_mtime - 300); - -#undef EQUAL_VAL - - unlink(TESTFILE); - printf("success: utimes\n"); - close(fd); - return true; -} - -static int test_memmem(void) -{ - char *s; - - printf("test: memmem\n"); - - s = (char *)memmem("foo", 3, "fo", 2); - if (strcmp(s, "foo") != 0) { - printf(__location__ ": Failed memmem\n"); - return false; - } - - s = (char *)memmem("foo", 3, "", 0); - /* it is allowable for this to return NULL (as happens on - FreeBSD) */ - if (s && strcmp(s, "foo") != 0) { - printf(__location__ ": Failed memmem\n"); - return false; - } - - s = (char *)memmem("foo", 4, "o", 1); - if (strcmp(s, "oo") != 0) { - printf(__location__ ": Failed memmem\n"); - return false; - } - - s = (char *)memmem("foobarfodx", 11, "fod", 3); - if (strcmp(s, "fodx") != 0) { - printf(__location__ ": Failed memmem\n"); - return false; - } - - printf("success: memmem\n"); - - return true; -} - -static bool test_closefrom(void) -{ - int i, fd; - - for (i=0; i<100; i++) { - fd = dup(0); - if (fd == -1) { - perror("dup failed"); - return false; - } - - /* 1000 is just an arbitrarily chosen upper bound */ - - if (fd >= 1000) { - printf("fd=%d\n", fd); - return false; - } - } - - closefrom(3); - - for (i=3; i<=fd; i++) { - off_t off; - off = lseek(i, 0, SEEK_CUR); - if ((off != (off_t)-1) || (errno != EBADF)) { - printf("fd %d not closed\n", i); - return false; - } - } - - return true; -} - -bool torture_local_replace(struct torture_context *ctx) -{ - bool ret = true; - ret &= test_ftruncate(); - ret &= test_strlcpy(); - ret &= test_strlcat(); - ret &= test_mktime(); - ret &= test_initgroups(); - ret &= test_memmove(); - ret &= test_strdup(); - ret &= test_setlinebuf(); - ret &= test_vsyslog(); - ret &= test_timegm(); - ret &= test_setenv(); - ret &= test_strndup(); - ret &= test_strnlen(); - ret &= test_waitpid(); - ret &= test_seteuid(); - ret &= test_setegid(); - ret &= test_asprintf(); - ret &= test_snprintf(); - ret &= test_vasprintf(); - ret &= test_vsnprintf(); - ret &= test_opendir(); - ret &= test_readdir(); - ret &= test_telldir(); - ret &= test_seekdir(); - ret &= test_dlopen(); - ret &= test_chroot(); - ret &= test_bzero(); - ret &= test_strerror(); - ret &= test_errno(); - ret &= test_mkdtemp(); - ret &= test_mkstemp(); - ret &= test_pread(); - ret &= test_pwrite(); - ret &= test_inet_ntoa(); - ret &= test_strtoll(); - ret &= test_strtoull(); - ret &= test_va_copy(); - ret &= test_FUNCTION(); - ret &= test_MIN(); - ret &= test_MAX(); - ret &= test_socketpair(); - ret &= test_strptime(); - ret &= test_getifaddrs(); - ret &= test_utime(); - ret &= test_utimes(); - ret &= test_memmem(); - ret &= test_closefrom(); - - return ret; -} diff --git a/ldb-2.0.8/lib/replace/timegm.c b/ldb-2.0.8/lib/replace/timegm.c deleted file mode 100644 index 395c684..0000000 --- a/ldb-2.0.8/lib/replace/timegm.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 1997 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - adapted for Samba4 by Andrew Tridgell -*/ - -#include "replace.h" -#include "system/time.h" - -static int is_leap(unsigned y) -{ - y += 1900; - return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0); -} - -time_t rep_timegm(struct tm *tm) -{ - static const unsigned ndays[2][12] ={ - {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, - {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; - time_t res = 0; - unsigned i; - - if (tm->tm_mon > 12 || - tm->tm_mon < 0 || - tm->tm_mday > 31 || - tm->tm_min > 60 || - tm->tm_sec > 60 || - tm->tm_hour > 24) { - /* invalid tm structure */ - return 0; - } - - for (i = 70; i < tm->tm_year; ++i) - res += is_leap(i) ? 366 : 365; - - for (i = 0; i < tm->tm_mon; ++i) - res += ndays[is_leap(tm->tm_year)][i]; - res += tm->tm_mday - 1; - res *= 24; - res += tm->tm_hour; - res *= 60; - res += tm->tm_min; - res *= 60; - res += tm->tm_sec; - return res; -} diff --git a/ldb-2.0.8/lib/replace/win32_replace.h b/ldb-2.0.8/lib/replace/win32_replace.h deleted file mode 100644 index 9901e72..0000000 --- a/ldb-2.0.8/lib/replace/win32_replace.h +++ /dev/null @@ -1,159 +0,0 @@ -#ifndef _WIN32_REPLACE_H -#define _WIN32_REPLACE_H - -#ifdef HAVE_WINSOCK2_H -#include -#endif - -#ifdef HAVE_WS2TCPIP_H -#include -#endif - -#ifdef HAVE_WINDOWS_H -#include -#endif - -/* Map BSD Socket errorcodes to the WSA errorcodes (if possible) */ - -#define EAFNOSUPPORT WSAEAFNOSUPPORT -#define ECONNREFUSED WSAECONNREFUSED -#define EINPROGRESS WSAEINPROGRESS -#define EMSGSIZE WSAEMSGSIZE -#define ENOBUFS WSAENOBUFS -#define ENOTSOCK WSAENOTSOCK -#define ENETUNREACH WSAENETUNREACH -#define ENOPROTOOPT WSAENOPROTOOPT -#define ENOTCONN WSAENOTCONN -#define ENOTSUP 134 - -/* We undefine the following constants due to conflicts with the w32api headers - * and the Windows Platform SDK/DDK. - */ - -#undef interface - -#undef ERROR_INVALID_PARAMETER -#undef ERROR_INSUFFICIENT_BUFFER -#undef ERROR_INVALID_DATATYPE - -#undef FILE_GENERIC_READ -#undef FILE_GENERIC_WRITE -#undef FILE_GENERIC_EXECUTE -#undef FILE_ATTRIBUTE_READONLY -#undef FILE_ATTRIBUTE_HIDDEN -#undef FILE_ATTRIBUTE_SYSTEM -#undef FILE_ATTRIBUTE_DIRECTORY -#undef FILE_ATTRIBUTE_ARCHIVE -#undef FILE_ATTRIBUTE_DEVICE -#undef FILE_ATTRIBUTE_NORMAL -#undef FILE_ATTRIBUTE_TEMPORARY -#undef FILE_ATTRIBUTE_REPARSE_POINT -#undef FILE_ATTRIBUTE_COMPRESSED -#undef FILE_ATTRIBUTE_OFFLINE -#undef FILE_ATTRIBUTE_ENCRYPTED -#undef FILE_FLAG_WRITE_THROUGH -#undef FILE_FLAG_NO_BUFFERING -#undef FILE_FLAG_RANDOM_ACCESS -#undef FILE_FLAG_SEQUENTIAL_SCAN -#undef FILE_FLAG_DELETE_ON_CLOSE -#undef FILE_FLAG_BACKUP_SEMANTICS -#undef FILE_FLAG_POSIX_SEMANTICS -#undef FILE_TYPE_DISK -#undef FILE_TYPE_UNKNOWN -#undef FILE_CASE_SENSITIVE_SEARCH -#undef FILE_CASE_PRESERVED_NAMES -#undef FILE_UNICODE_ON_DISK -#undef FILE_PERSISTENT_ACLS -#undef FILE_FILE_COMPRESSION -#undef FILE_VOLUME_QUOTAS -#undef FILE_VOLUME_IS_COMPRESSED -#undef FILE_NOTIFY_CHANGE_FILE_NAME -#undef FILE_NOTIFY_CHANGE_DIR_NAME -#undef FILE_NOTIFY_CHANGE_ATTRIBUTES -#undef FILE_NOTIFY_CHANGE_SIZE -#undef FILE_NOTIFY_CHANGE_LAST_WRITE -#undef FILE_NOTIFY_CHANGE_LAST_ACCESS -#undef FILE_NOTIFY_CHANGE_CREATION -#undef FILE_NOTIFY_CHANGE_EA -#undef FILE_NOTIFY_CHANGE_SECURITY -#undef FILE_NOTIFY_CHANGE_STREAM_NAME -#undef FILE_NOTIFY_CHANGE_STREAM_SIZE -#undef FILE_NOTIFY_CHANGE_STREAM_WRITE -#undef FILE_NOTIFY_CHANGE_NAME - -#undef PRINTER_ATTRIBUTE_QUEUED -#undef PRINTER_ATTRIBUTE_DIRECT -#undef PRINTER_ATTRIBUTE_DEFAULT -#undef PRINTER_ATTRIBUTE_SHARED -#undef PRINTER_ATTRIBUTE_NETWORK -#undef PRINTER_ATTRIBUTE_HIDDEN -#undef PRINTER_ATTRIBUTE_LOCAL -#undef PRINTER_ATTRIBUTE_ENABLE_DEVQ -#undef PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS -#undef PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST -#undef PRINTER_ATTRIBUTE_WORK_OFFLINE -#undef PRINTER_ATTRIBUTE_ENABLE_BIDI -#undef PRINTER_ATTRIBUTE_RAW_ONLY -#undef PRINTER_ATTRIBUTE_PUBLISHED -#undef PRINTER_ENUM_DEFAULT -#undef PRINTER_ENUM_LOCAL -#undef PRINTER_ENUM_CONNECTIONS -#undef PRINTER_ENUM_FAVORITE -#undef PRINTER_ENUM_NAME -#undef PRINTER_ENUM_REMOTE -#undef PRINTER_ENUM_SHARED -#undef PRINTER_ENUM_NETWORK -#undef PRINTER_ENUM_EXPAND -#undef PRINTER_ENUM_CONTAINER -#undef PRINTER_ENUM_ICON1 -#undef PRINTER_ENUM_ICON2 -#undef PRINTER_ENUM_ICON3 -#undef PRINTER_ENUM_ICON4 -#undef PRINTER_ENUM_ICON5 -#undef PRINTER_ENUM_ICON6 -#undef PRINTER_ENUM_ICON7 -#undef PRINTER_ENUM_ICON8 -#undef PRINTER_STATUS_PAUSED -#undef PRINTER_STATUS_ERROR -#undef PRINTER_STATUS_PENDING_DELETION -#undef PRINTER_STATUS_PAPER_JAM -#undef PRINTER_STATUS_PAPER_OUT -#undef PRINTER_STATUS_MANUAL_FEED -#undef PRINTER_STATUS_PAPER_PROBLEM -#undef PRINTER_STATUS_OFFLINE -#undef PRINTER_STATUS_IO_ACTIVE -#undef PRINTER_STATUS_BUSY -#undef PRINTER_STATUS_PRINTING -#undef PRINTER_STATUS_OUTPUT_BIN_FULL -#undef PRINTER_STATUS_NOT_AVAILABLE -#undef PRINTER_STATUS_WAITING -#undef PRINTER_STATUS_PROCESSING -#undef PRINTER_STATUS_INITIALIZING -#undef PRINTER_STATUS_WARMING_UP -#undef PRINTER_STATUS_TONER_LOW -#undef PRINTER_STATUS_NO_TONER -#undef PRINTER_STATUS_PAGE_PUNT -#undef PRINTER_STATUS_USER_INTERVENTION -#undef PRINTER_STATUS_OUT_OF_MEMORY -#undef PRINTER_STATUS_DOOR_OPEN -#undef PRINTER_STATUS_SERVER_UNKNOWN -#undef PRINTER_STATUS_POWER_SAVE - -#undef DWORD -#undef HKEY_CLASSES_ROOT -#undef HKEY_CURRENT_USER -#undef HKEY_LOCAL_MACHINE -#undef HKEY_USERS -#undef HKEY_PERFORMANCE_DATA -#undef HKEY_CURRENT_CONFIG -#undef HKEY_DYN_DATA -#undef REG_DWORD -#undef REG_QWORD - -#undef SERVICE_STATE_ALL - -#undef SE_GROUP_MANDATORY -#undef SE_GROUP_ENABLED_BY_DEFAULT -#undef SE_GROUP_ENABLED - -#endif /* _WIN32_REPLACE_H */ diff --git a/ldb-2.0.8/lib/replace/wscript b/ldb-2.0.8/lib/replace/wscript deleted file mode 100644 index 56e2a22..0000000 --- a/ldb-2.0.8/lib/replace/wscript +++ /dev/null @@ -1,955 +0,0 @@ -#!/usr/bin/env python - -APPNAME = 'libreplace' -VERSION = '1.2.1' - -import sys -import os - -# find the buildtools directory -top = '.' -while not os.path.exists(top+'/buildtools') and len(top.split('/')) < 5: - top = top + '/..' -sys.path.insert(0, top + '/buildtools/wafsamba') - -out = 'bin' - -import wafsamba -from wafsamba import samba_dist -from waflib import Options, Utils, Logs, Context - -samba_dist.DIST_DIRS('lib/replace buildtools:buildtools third_party/waf:third_party/waf') - -def options(opt): - opt.BUILTIN_DEFAULT('NONE') - opt.PRIVATE_EXTENSION_DEFAULT('') - opt.RECURSE('buildtools/wafsamba') - -@Utils.run_once -def configure(conf): - conf.RECURSE('buildtools/wafsamba') - - conf.env.standalone_replace = conf.IN_LAUNCH_DIR() - - conf.DEFINE('HAVE_LIBREPLACE', 1) - conf.DEFINE('LIBREPLACE_NETWORK_CHECKS', 1) - - conf.CHECK_HEADERS('linux/types.h crypt.h locale.h acl/libacl.h compat.h') - conf.CHECK_HEADERS('acl/libacl.h attr/xattr.h compat.h ctype.h dustat.h') - conf.CHECK_HEADERS('fcntl.h fnmatch.h glob.h history.h krb5.h langinfo.h') - conf.CHECK_HEADERS('libaio.h locale.h ndir.h pwd.h') - conf.CHECK_HEADERS('shadow.h sys/acl.h') - conf.CHECK_HEADERS('sys/attributes.h attr/attributes.h sys/capability.h sys/dir.h sys/epoll.h') - conf.CHECK_HEADERS('port.h') - conf.CHECK_HEADERS('sys/fcntl.h sys/filio.h sys/filsys.h sys/fs/s5param.h') - conf.CHECK_HEADERS('sys/id.h sys/ioctl.h sys/ipc.h sys/mman.h sys/mode.h sys/ndir.h sys/priv.h') - conf.CHECK_HEADERS('sys/resource.h sys/security.h sys/shm.h sys/statfs.h sys/statvfs.h sys/termio.h') - conf.CHECK_HEADERS('sys/vfs.h sys/xattr.h termio.h termios.h sys/file.h') - conf.CHECK_HEADERS('sys/ucontext.h sys/wait.h sys/stat.h') - - if not conf.CHECK_DECLS('malloc', headers='stdlib.h'): - conf.CHECK_HEADERS('malloc.h') - - conf.CHECK_HEADERS('grp.h') - conf.CHECK_HEADERS('sys/select.h setjmp.h utime.h sys/syslog.h syslog.h') - conf.CHECK_HEADERS('stdarg.h vararg.h sys/mount.h mntent.h') - conf.CHECK_HEADERS('stropts.h unix.h string.h strings.h sys/param.h limits.h') - conf.CHECK_HEADERS('''sys/socket.h netinet/in.h netdb.h arpa/inet.h netinet/in_systm.h - netinet/ip.h netinet/tcp.h netinet/in_ip.h - sys/sockio.h sys/un.h''', together=True) - conf.CHECK_HEADERS('sys/uio.h ifaddrs.h direct.h dirent.h') - conf.CHECK_HEADERS('windows.h winsock2.h ws2tcpip.h') - conf.CHECK_HEADERS('errno.h') - conf.CHECK_HEADERS('getopt.h iconv.h') - conf.CHECK_HEADERS('memory.h nss.h sasl/sasl.h') - - conf.CHECK_FUNCS_IN('inotify_init', 'inotify', checklibc=True, - headers='sys/inotify.h') - - conf.CHECK_HEADERS('security/pam_appl.h zlib.h asm/unistd.h') - conf.CHECK_HEADERS('aio.h sys/unistd.h alloca.h float.h') - - conf.SET_TARGET_TYPE('tirpc', 'EMPTY') - - if conf.CHECK_CODE( - '\n#ifndef _TIRPC_RPC_H\n#error "no tirpc headers in system path"\n#endif\n', - 'HAVE_RPC_RPC_HEADERS', - headers=['rpc/rpc.h', 'rpc/nettype.h'], - msg='Checking for tirpc rpc headers in default system path'): - if conf.CONFIG_SET('HAVE_RPC_RPC_H'): - conf.undefine('HAVE_RPC_RPC_H') - - if not conf.CONFIG_SET('HAVE_RPC_RPC_H'): - if conf.CHECK_CFG(package='libtirpc', args='--cflags --libs', - msg='Checking for libtirpc headers', - uselib_store='TIRPC'): - conf.CHECK_HEADERS('rpc/rpc.h rpc/nettype.h', lib='tirpc', together=True) - conf.SET_TARGET_TYPE('tirpc', 'SYSLIB') - if not conf.CONFIG_SET('HAVE_RPC_RPC_H'): - if conf.CHECK_CFG(package='libntirpc', args='--cflags', - msg='Checking for libntirpc headers', - uselib_store='TIRPC'): - conf.CHECK_HEADERS('rpc/rpc.h rpc/nettype.h', lib='tirpc', together=True) - conf.SET_TARGET_TYPE('tirpc', 'SYSLIB') - if not conf.CONFIG_SET('HAVE_RPC_RPC_H'): - Logs.warn('No rpc/rpc.h header found, tirpc or libntirpc missing?') - - conf.SET_TARGET_TYPE('nsl', 'EMPTY') - conf.CHECK_HEADERS('rpc/rpc.h rpcsvc/yp_prot.h', lib='tirpc') - if not conf.CONFIG_SET('HAVE_RPCSVC_YP_PROT_H'): - if conf.CHECK_CFG(package='libnsl', args='--cflags --libs', - msg='Checking for libnsl', - uselib_store='NSL'): - conf.SET_TARGET_TYPE('nsl', 'SYSLIB') - conf.CHECK_HEADERS('rpc/rpc.h rpcsvc/yp_prot.h', lib='tirpc nsl') - else: - conf.SET_TARGET_TYPE('nsl', 'SYSLIB') - conf.CHECK_HEADERS('rpcsvc/nis.h rpcsvc/ypclnt.h', lib='tirpc nsl') - - conf.CHECK_HEADERS('sys/sysctl.h') - conf.CHECK_HEADERS('sys/fileio.h sys/filesys.h sys/dustat.h sys/sysmacros.h') - conf.CHECK_HEADERS('xfs/libxfs.h netgroup.h') - - conf.CHECK_HEADERS('valgrind.h valgrind/valgrind.h') - conf.CHECK_HEADERS('valgrind/memcheck.h valgrind/helgrind.h') - conf.CHECK_HEADERS('nss_common.h nsswitch.h ns_api.h') - conf.CHECK_HEADERS('sys/extattr.h sys/ea.h sys/proplist.h sys/cdefs.h') - conf.CHECK_HEADERS('utmp.h utmpx.h lastlog.h') - conf.CHECK_HEADERS('syscall.h sys/syscall.h inttypes.h') - conf.CHECK_HEADERS('sys/atomic.h stdatomic.h') - conf.CHECK_HEADERS('libgen.h') - - if conf.CHECK_CFLAGS('-Wno-format-truncation'): - conf.define('HAVE_WNO_FORMAT_TRUNCATION', '1') - - if conf.CHECK_CFLAGS('-Wno-unused-function'): - conf.define('HAVE_WNO_UNUSED_FUNCTION', '1') - - if conf.CHECK_CFLAGS('-Wno-strict-overflow'): - conf.define('HAVE_WNO_STRICT_OVERFLOW', '1') - - # Check for process set name support - conf.CHECK_CODE(''' - #include - int main(void) { - prctl(0); - return 0; - } - ''', - 'HAVE_PRCTL', - headers='sys/prctl.h', - msg='Checking for prctl syscall') - - conf.CHECK_CODE(''' - #include - #ifdef HAVE_FCNTL_H - #include - #endif - int main(void) { int fd = open("/dev/null", O_DIRECT); } - ''', - define='HAVE_OPEN_O_DIRECT', - addmain=False, - msg='Checking for O_DIRECT flag to open(2)') - - conf.CHECK_TYPES('"long long" intptr_t uintptr_t ptrdiff_t comparison_fn_t') - conf.CHECK_TYPE('_Bool', define='HAVE__Bool') - conf.CHECK_TYPE('bool', define='HAVE_BOOL') - - conf.CHECK_TYPE('int8_t', 'char') - conf.CHECK_TYPE('uint8_t', 'unsigned char') - conf.CHECK_TYPE('int16_t', 'short') - conf.CHECK_TYPE('uint16_t', 'unsigned short') - conf.CHECK_TYPE('int32_t', 'int') - conf.CHECK_TYPE('uint32_t', 'unsigned') - conf.CHECK_TYPE('int64_t', 'long long') - conf.CHECK_TYPE('uint64_t', 'unsigned long long') - conf.CHECK_TYPE('size_t', 'unsigned int') - conf.CHECK_TYPE('ssize_t', 'int') - conf.CHECK_TYPE('ino_t', 'unsigned') - conf.CHECK_TYPE('loff_t', 'off_t') - conf.CHECK_TYPE('offset_t', 'loff_t') - conf.CHECK_TYPE('volatile int', define='HAVE_VOLATILE') - conf.CHECK_TYPE('uint_t', 'unsigned int') - conf.CHECK_TYPE('blksize_t', 'long', headers='sys/types.h sys/stat.h unistd.h') - conf.CHECK_TYPE('blkcnt_t', 'long', headers='sys/types.h sys/stat.h unistd.h') - - conf.CHECK_SIZEOF('bool char int "long long" long short size_t ssize_t') - conf.CHECK_SIZEOF('int8_t uint8_t int16_t uint16_t int32_t uint32_t int64_t uint64_t') - conf.CHECK_SIZEOF('void*', define='SIZEOF_VOID_P') - conf.CHECK_SIZEOF('off_t dev_t ino_t time_t') - - conf.CHECK_TYPES('socklen_t', headers='sys/socket.h') - conf.CHECK_TYPE_IN('struct ifaddrs', 'ifaddrs.h') - conf.CHECK_TYPE_IN('struct addrinfo', 'netdb.h') - conf.CHECK_TYPE_IN('struct sockaddr', 'sys/socket.h') - conf.CHECK_CODE('struct sockaddr_in6 x', define='HAVE_STRUCT_SOCKADDR_IN6', - headers='sys/socket.h netdb.h netinet/in.h') - conf.CHECK_TYPE_IN('struct sockaddr_storage', 'sys/socket.h') - conf.CHECK_TYPE_IN('sa_family_t', 'sys/socket.h') - - conf.CHECK_TYPE_IN('sig_atomic_t', 'signal.h', define='HAVE_SIG_ATOMIC_T_TYPE') - conf.CHECK_FUNCS('sigsetmask siggetmask sigprocmask sigblock sigaction sigset') - - # Those functions are normally available in libc - if not conf.CHECK_FUNCS(''' - inet_ntoa - inet_aton - inet_ntop - inet_pton - connect - gethostbyname - getaddrinfo - getnameinfo - freeaddrinfo - gai_strerror - socketpair''', - headers='sys/socket.h netinet/in.h arpa/inet.h netdb.h'): - conf.CHECK_FUNCS_IN(''' - inet_ntoa - inet_aton - inet_ntop - inet_pton - connect - gethostbyname - getaddrinfo - getnameinfo - freeaddrinfo - gai_strerror - socketpair''', - 'socket nsl', - headers='sys/socket.h netinet/in.h arpa/inet.h netdb.h') - conf.DEFINE('REPLACE_REQUIRES_LIBSOCKET_LIBNSL', 1) - - conf.CHECK_FUNCS('memset_s memset_explicit') - - conf.CHECK_CODE(''' - #include - - int main(void) - { - char buf[] = "This is some content"; - memset(buf, '\0', sizeof(buf)); __asm__ volatile("" : : "g"(&buf) : "memory"); - return 0; - } - ''', - define='HAVE_GCC_VOLATILE_MEMORY_PROTECTION', - addmain=False, - msg='Checking for volatile memory protection', - local_include=False) - - # Some old Linux systems have broken header files and - # miss the IPV6_V6ONLY define in netinet/in.h, - # but have it in linux/in6.h. - # We can't include both files so we just check if the value - # if defined and do the replacement in system/network.h - if not conf.CHECK_VARIABLE('IPV6_V6ONLY', - headers='sys/socket.h netdb.h netinet/in.h'): - conf.CHECK_CODE(''' - #include - #if (IPV6_V6ONLY != 26) - #error no IPV6_V6ONLY support on linux - #endif - int main(void) { return IPV6_V6ONLY; } - ''', - define='HAVE_LINUX_IPV6_V6ONLY_26', - addmain=False, - msg='Checking for IPV6_V6ONLY in linux/in6.h', - local_include=False) - - conf.CHECK_CODE(''' - struct sockaddr_storage sa_store; - struct addrinfo *ai = NULL; - struct in6_addr in6addr; - int idx = if_nametoindex("iface1"); - int s = socket(AF_INET6, SOCK_STREAM, 0); - int ret = getaddrinfo(NULL, NULL, NULL, &ai); - if (ret != 0) { - const char *es = gai_strerror(ret); - } - freeaddrinfo(ai); - { - int val = 1; - #ifdef HAVE_LINUX_IPV6_V6ONLY_26 - #define IPV6_V6ONLY 26 - #endif - ret = setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, - (const void *)&val, sizeof(val)); - } - ''', - define='HAVE_IPV6', - lib='nsl socket', - headers='sys/socket.h netdb.h netinet/in.h net/if.h') - - if conf.CONFIG_SET('HAVE_SYS_UCONTEXT_H') and conf.CONFIG_SET('HAVE_SIGNAL_H'): - conf.CHECK_CODE(''' - ucontext_t uc; - sigaddset(&uc.uc_sigmask, SIGUSR1); - ''', - 'HAVE_UCONTEXT_T', - msg="Checking whether we have ucontext_t", - headers='signal.h sys/ucontext.h') - - # Check for atomic builtins. */ - conf.CHECK_CODE(''' - int i; - (void)__sync_fetch_and_add(&i, 1); - ''', - 'HAVE___SYNC_FETCH_AND_ADD', - msg='Checking for __sync_fetch_and_add compiler builtin') - - conf.CHECK_CODE(''' - int32_t i; - atomic_add_32(&i, 1); - ''', - 'HAVE_ATOMIC_ADD_32', - headers='stdint.h sys/atomic.h', - msg='Checking for atomic_add_32 compiler builtin') - - # Check for thread fence. */ - tf = conf.CHECK_CODE('atomic_thread_fence(memory_order_seq_cst);', - 'HAVE_ATOMIC_THREAD_FENCE', - headers='stdatomic.h', - msg='Checking for atomic_thread_fence(memory_order_seq_cst) in stdatomic.h') - if not tf: - tf = conf.CHECK_CODE('__atomic_thread_fence(__ATOMIC_SEQ_CST);', - 'HAVE___ATOMIC_THREAD_FENCE', - msg='Checking for __atomic_thread_fence(__ATOMIC_SEQ_CST)') - if not tf: - # __sync_synchronize() is available since 2005 in gcc. - tf = conf.CHECK_CODE('__sync_synchronize();', - 'HAVE___SYNC_SYNCHRONIZE', - msg='Checking for __sync_synchronize') - if tf: - conf.DEFINE('HAVE_ATOMIC_THREAD_FENCE_SUPPORT', 1) - - conf.CHECK_CODE(''' - #define FALL_THROUGH __attribute__((fallthrough)) - - enum direction_e { - UP = 0, - DOWN, - }; - - int main(void) { - enum direction_e key = UP; - int i = 10; - int j = 0; - - switch (key) { - case UP: - i = 5; - FALL_THROUGH; - case DOWN: - j = i * 2; - break; - default: - break; - } - - if (j < i) { - return 1; - } - - return 0; - } - ''', - 'HAVE_FALLTHROUGH_ATTRIBUTE', - addmain=False, - strict=True, - cflags=['-Werror=missing-declarations'], - msg='Checking for fallthrough attribute') - - # these may be builtins, so we need the link=False strategy - conf.CHECK_FUNCS('strdup memmem printf memset memcpy memmove strcpy strncpy bzero', link=False) - - # See https://bugzilla.samba.org/show_bug.cgi?id=1097 - # - # Ported in from autoconf where it was added with this commit: - # commit 804cfb20a067b4b687089dc72a8271b3abf20f31 - # Author: Simo Sorce - # Date: Wed Aug 25 14:24:16 2004 +0000 - # r2070: Let's try to overload srnlen and strndup for AIX where they are natly broken. - - host_os = sys.platform - if host_os.rfind('aix') > -1: - conf.DEFINE('BROKEN_STRNLEN', 1) - conf.DEFINE('BROKEN_STRNDUP', 1) - - conf.CHECK_FUNCS('shl_load shl_unload shl_findsym') - conf.CHECK_FUNCS('pipe strftime srandom random srand rand usleep setbuffer') - conf.CHECK_FUNCS('lstat getpgrp utime utimes setuid seteuid setreuid setresuid setgid setegid') - conf.CHECK_FUNCS('setregid setresgid chroot strerror vsyslog setlinebuf mktime') - conf.CHECK_FUNCS('ftruncate chsize rename waitpid wait4') - conf.CHECK_FUNCS('initgroups pread pwrite strndup strcasestr strsep') - conf.CHECK_FUNCS('strtok_r mkdtemp dup2 dprintf vdprintf isatty chown lchown') - conf.CHECK_FUNCS('link readlink symlink realpath snprintf vsnprintf') - conf.CHECK_FUNCS('asprintf vasprintf setenv unsetenv strnlen strtoull __strtoull') - conf.CHECK_FUNCS('strtouq strtoll __strtoll strtoq memalign posix_memalign') - conf.CHECK_FUNCS('fmemopen') - - if conf.CONFIG_SET('HAVE_MEMALIGN'): - conf.CHECK_DECLS('memalign', headers='malloc.h') - - # glibc up to 2.3.6 had dangerously broken posix_fallocate(). DON'T USE IT. - if conf.CHECK_CODE(''' -#define _XOPEN_SOURCE 600 -#include -#if defined(__GLIBC__) && ((__GLIBC__ < 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 4)) -#error probably broken posix_fallocate -#endif -''', - '_POSIX_FALLOCATE_CAPABLE_LIBC', - msg='Checking for posix_fallocate-capable libc'): - conf.CHECK_FUNCS('posix_fallocate') - - conf.CHECK_FUNCS('prctl dirname basename') - - strlcpy_in_bsd = False - - # libbsd on some platforms provides strlcpy and strlcat - if not conf.CHECK_FUNCS('strlcpy strlcat'): - if conf.CHECK_FUNCS_IN('strlcpy strlcat', 'bsd', headers='bsd/string.h', - checklibc=True): - strlcpy_in_bsd = True - if not conf.CHECK_FUNCS('getpeereid'): - conf.CHECK_FUNCS_IN('getpeereid', 'bsd', headers='sys/types.h bsd/unistd.h') - if not conf.CHECK_FUNCS_IN('setproctitle', 'setproctitle', headers='setproctitle.h'): - conf.CHECK_FUNCS_IN('setproctitle', 'bsd', headers='sys/types.h bsd/unistd.h') - if not conf.CHECK_FUNCS('setproctitle_init'): - conf.CHECK_FUNCS_IN('setproctitle_init', 'bsd', headers='sys/types.h bsd/unistd.h') - - if not conf.CHECK_FUNCS('closefrom'): - conf.CHECK_FUNCS_IN('closefrom', 'bsd', headers='bsd/unistd.h') - - conf.CHECK_CODE(''' - struct ucred cred; - socklen_t cred_len; - int ret = getsockopt(0, SOL_SOCKET, SO_PEERCRED, &cred, &cred_len);''', - 'HAVE_PEERCRED', - msg="Checking whether we can use SO_PEERCRED to get socket credentials", - headers='sys/types.h sys/socket.h') - - #Some OS (ie. freebsd) return EINVAL if the convertion could not be done, it's not what we expect - #Let's detect those cases - if conf.CONFIG_SET('HAVE_STRTOLL'): - conf.CHECK_CODE(''' - long long nb = strtoll("Text", NULL, 0); - if (errno == EINVAL) { - return 0; - } else { - return 1; - } - ''', - msg="Checking correct behavior of strtoll", - headers = 'errno.h', - execute = True, - define = 'HAVE_BSD_STRTOLL', - ) - conf.CHECK_FUNCS('if_nametoindex strerror_r') - conf.CHECK_FUNCS('getdirentries getdents syslog') - conf.CHECK_FUNCS('gai_strerror get_current_dir_name') - conf.CHECK_FUNCS('timegm getifaddrs freeifaddrs mmap setgroups syscall setsid') - conf.CHECK_FUNCS('getgrent_r getgrgid_r getgrnam_r getgrouplist getpagesize') - conf.CHECK_FUNCS('getpwent_r getpwnam_r getpwuid_r epoll_create') - conf.CHECK_FUNCS('port_create') - conf.CHECK_FUNCS('getprogname') - - conf.SET_TARGET_TYPE('attr', 'EMPTY') - - xattr_headers='sys/attributes.h attr/xattr.h sys/xattr.h' - - # default to 1, we set it to 0 if we don't find any EA implementation below: - conf.DEFINE('HAVE_XATTR_SUPPORT', 1) - if conf.CHECK_FUNCS_IN('getxattr', 'attr', checklibc=True, headers=xattr_headers): - conf.DEFINE('HAVE_XATTR_XATTR', 1) - # Darwin has extra options to xattr-family functions - conf.CHECK_CODE('getxattr(NULL, NULL, NULL, 0, 0, 0)', - headers=xattr_headers, local_include=False, - define='XATTR_ADDITIONAL_OPTIONS', - msg="Checking whether xattr interface takes additional options") - elif conf.CHECK_FUNCS_IN('attr_listf', 'attr', checklibc=True, headers=xattr_headers): - conf.DEFINE('HAVE_XATTR_ATTR', 1) - elif conf.CHECK_FUNCS('extattr_list_fd'): - conf.DEFINE('HAVE_XATTR_EXTATTR', 1) - elif conf.CHECK_FUNCS('flistea'): - conf.DEFINE('HAVE_XATTR_EA', 1) - elif not conf.CHECK_FUNCS('attropen'): - conf.DEFINE('HAVE_XATTR_SUPPORT', 0) - - - conf.CHECK_FUNCS_IN('dlopen dlsym dlerror dlclose', 'dl', - checklibc=True, headers='dlfcn.h dl.h') - - conf.CHECK_C_PROTOTYPE('dlopen', 'void *dlopen(const char* filename, unsigned int flags)', - define='DLOPEN_TAKES_UNSIGNED_FLAGS', headers='dlfcn.h dl.h') - - # - # Check for clock_gettime and fdatasync - # - # First check libc to avoid linking libreplace against librt. - # - if conf.CHECK_FUNCS('fdatasync'): - # some systems are missing the declaration - conf.CHECK_DECLS('fdatasync') - else: - if conf.CHECK_FUNCS_IN('fdatasync', 'rt'): - # some systems are missing the declaration - conf.CHECK_DECLS('fdatasync') - - has_clock_gettime = False - if conf.CHECK_FUNCS('clock_gettime'): - has_clock_gettime = True - - if not has_clock_gettime: - if conf.CHECK_FUNCS_IN('clock_gettime', 'rt', checklibc=True): - has_clock_gettime = True - - if has_clock_gettime: - for c in ['CLOCK_MONOTONIC', 'CLOCK_PROCESS_CPUTIME_ID', 'CLOCK_REALTIME']: - conf.CHECK_CODE(''' - #if TIME_WITH_SYS_TIME - # include - # include - #else - # if HAVE_SYS_TIME_H - # include - # else - # include - # endif - #endif - clockid_t clk = %s''' % c, - 'HAVE_%s' % c, - msg='Checking whether the clock_gettime clock ID %s is available' % c) - - conf.CHECK_TYPE('struct timespec', headers='sys/time.h time.h') - - # these headers need to be tested as a group on freebsd - conf.CHECK_HEADERS(headers='sys/socket.h net/if.h', together=True) - conf.CHECK_HEADERS(headers='netinet/in.h arpa/nameser.h resolv.h', together=True) - conf.CHECK_FUNCS_IN('res_search', 'resolv', checklibc=True, - headers='netinet/in.h arpa/nameser.h resolv.h') - - - # try to find libintl (if --without-gettext is not given) - conf.env.intl_libs='' - if not Options.options.disable_gettext: - conf.CHECK_HEADERS('libintl.h') - conf.CHECK_LIB('intl') - conf.CHECK_DECLS('dgettext gettext bindtextdomain textdomain bind_textdomain_codeset', headers="libintl.h") - # *textdomain functions are not strictly necessary - conf.CHECK_FUNCS_IN('bindtextdomain textdomain bind_textdomain_codeset', - '', checklibc=True, headers='libintl.h') - # gettext and dgettext must exist - # on some systems (the ones with glibc, those are in libc) - if conf.CHECK_FUNCS_IN('dgettext gettext', '', checklibc=True, headers='libintl.h'): - # save for dependency definitions - conf.env.intl_libs='' - # others (e.g. FreeBSD) have separate libintl - elif conf.CHECK_FUNCS_IN('dgettext gettext', 'intl', checklibc=False, headers='libintl.h'): - # save for dependency definitions - conf.env.intl_libs='intl' - # recheck with libintl - conf.CHECK_FUNCS_IN('bindtextdomain textdomain bind_textdomain_codeset', - 'intl', checklibc=False, headers='libintl.h') - else: - # Some hosts need lib iconv for linking with lib intl - # So we try with flags just in case it helps. - oldflags = list(conf.env['EXTRA_LDFLAGS']); - conf.env['EXTRA_LDFLAGS'].extend(["-liconv"]) - conf.CHECK_FUNCS_IN('dgettext gettext bindtextdomain textdomain bind_textdomain_codeset', - 'intl', checklibc=False, headers='libintl.h') - conf.env['EXTRA_LDFLAGS'] = oldflags - if conf.env['HAVE_GETTEXT'] and conf.env['HAVE_DGETTEXT']: - # save for dependency definitions - conf.env.intl_libs='iconv intl' - - # did we find both prototypes and a library to link against? - # if not, unset the detected values (see Bug #9911) - if not (conf.env['HAVE_GETTEXT'] and conf.env['HAVE_DECL_GETTEXT']): - conf.undefine('HAVE_GETTEXT') - conf.undefine('HAVE_DECL_GETTEXT') - if not (conf.env['HAVE_DGETTEXT'] and conf.env['HAVE_DECL_DGETTEXT']): - conf.undefine('HAVE_DGETTEXT') - conf.undefine('HAVE_DECL_DGETTEXT') - - conf.CHECK_FUNCS_IN('pthread_create', 'pthread', checklibc=True, headers='pthread.h') - - PTHREAD_CFLAGS='error' - PTHREAD_LDFLAGS='error' - - if PTHREAD_LDFLAGS == 'error': - # Check if pthread_attr_init() is provided by libc first! - if conf.CHECK_FUNCS('pthread_attr_init'): - PTHREAD_CFLAGS='-D_REENTRANT' - PTHREAD_LDFLAGS='' - if PTHREAD_LDFLAGS == 'error': - if conf.CHECK_FUNCS_IN('pthread_attr_init', 'pthread'): - PTHREAD_CFLAGS='-D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS' - PTHREAD_LDFLAGS='-lpthread' - if PTHREAD_LDFLAGS == 'error': - if conf.CHECK_FUNCS_IN('pthread_attr_init', 'pthreads'): - PTHREAD_CFLAGS='-D_THREAD_SAFE' - PTHREAD_LDFLAGS='-lpthreads' - if PTHREAD_LDFLAGS == 'error': - if conf.CHECK_FUNCS_IN('pthread_attr_init', 'c_r'): - PTHREAD_CFLAGS='-D_THREAD_SAFE -pthread' - PTHREAD_LDFLAGS='-pthread' - - # especially for HP-UX, where the CHECK_FUNC macro fails to test for - # pthread_attr_init. On pthread_mutex_lock it works there... - if PTHREAD_LDFLAGS == 'error': - if conf.CHECK_FUNCS_IN('pthread_mutex_lock', 'pthread'): - PTHREAD_CFLAGS='-D_REENTRANT' - PTHREAD_LDFLAGS='-lpthread' - - if PTHREAD_CFLAGS != 'error' and PTHREAD_LDFLAGS != 'error': - if conf.CONFIG_SET('replace_add_global_pthread'): - conf.ADD_CFLAGS(PTHREAD_CFLAGS) - conf.ADD_LDFLAGS(PTHREAD_LDFLAGS) - conf.CHECK_HEADERS('pthread.h') - conf.DEFINE('HAVE_PTHREAD', '1') - - if conf.CONFIG_SET('HAVE_PTHREAD'): - - conf.CHECK_FUNCS_IN('pthread_mutexattr_setrobust', 'pthread', - checklibc=True, headers='pthread.h') - if not conf.CONFIG_SET('HAVE_PTHREAD_MUTEXATTR_SETROBUST'): - conf.CHECK_FUNCS_IN('pthread_mutexattr_setrobust_np', 'pthread', - checklibc=True, headers='pthread.h') - - conf.CHECK_DECLS('PTHREAD_MUTEX_ROBUST', headers='pthread.h') - if not conf.CONFIG_SET('HAVE_DECL_PTHREAD_MUTEX_ROBUST'): - conf.CHECK_DECLS('PTHREAD_MUTEX_ROBUST_NP', headers='pthread.h') - - conf.CHECK_FUNCS_IN('pthread_mutex_consistent', 'pthread', - checklibc=True, headers='pthread.h') - if not conf.CONFIG_SET('HAVE_PTHREAD_MUTEX_CONSISTENT'): - conf.CHECK_FUNCS_IN('pthread_mutex_consistent_np', 'pthread', - checklibc=True, headers='pthread.h') - - if ((conf.CONFIG_SET('HAVE_PTHREAD_MUTEXATTR_SETROBUST') or - conf.CONFIG_SET('HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP')) and - (conf.CONFIG_SET('HAVE_DECL_PTHREAD_MUTEX_ROBUST') or - conf.CONFIG_SET('HAVE_DECL_PTHREAD_MUTEX_ROBUST_NP')) and - (conf.CONFIG_SET('HAVE_PTHREAD_MUTEX_CONSISTENT') or - conf.CONFIG_SET('HAVE_PTHREAD_MUTEX_CONSISTENT_NP'))): - conf.DEFINE('HAVE_ROBUST_MUTEXES', 1) - - # __thread is available since 2002 in gcc. - conf.CHECK_CODE(''' - __thread int tls; - - int main(void) { - return 0; - } - ''', - 'HAVE___THREAD', - addmain=False, - msg='Checking for __thread local storage') - - conf.CHECK_FUNCS_IN('crypt', 'crypt', checklibc=True) - conf.CHECK_FUNCS_IN('crypt_r', 'crypt', checklibc=True) - - conf.CHECK_VARIABLE('rl_event_hook', define='HAVE_DECL_RL_EVENT_HOOK', always=True, - headers='readline.h readline/readline.h readline/history.h') - conf.CHECK_VARIABLE('program_invocation_short_name', headers='errno.h') - - conf.CHECK_DECLS('snprintf vsnprintf asprintf vasprintf') - - conf.CHECK_DECLS('errno', headers='errno.h', reverse=True) - conf.CHECK_DECLS('EWOULDBLOCK', headers='errno.h') - conf.CHECK_DECLS('environ', reverse=True, headers='unistd.h') - conf.CHECK_DECLS('getgrent_r getpwent_r', reverse=True, headers='pwd.h grp.h') - conf.CHECK_DECLS('pread pwrite setenv setresgid setresuid', reverse=True) - - if conf.CONFIG_SET('HAVE_EPOLL_CREATE') and conf.CONFIG_SET('HAVE_SYS_EPOLL_H'): - conf.DEFINE('HAVE_EPOLL', 1) - - if conf.CONFIG_SET('HAVE_PORT_CREATE') and conf.CONFIG_SET('HAVE_PORT_H'): - conf.DEFINE('HAVE_SOLARIS_PORTS', 1) - - if conf.CHECK_FUNCS('eventfd', headers='sys/eventfd.h'): - conf.DEFINE('HAVE_EVENTFD', 1) - - conf.CHECK_HEADERS('poll.h') - conf.CHECK_FUNCS('poll') - - conf.CHECK_FUNCS('strptime') - conf.CHECK_DECLS('strptime', headers='time.h') - conf.CHECK_CODE('''#define LIBREPLACE_CONFIGURE_TEST_STRPTIME - #include "tests/strptime.c"''', - define='HAVE_WORKING_STRPTIME', - execute=True, - addmain=False, - msg='Checking for working strptime') - - conf.CHECK_C_PROTOTYPE('gettimeofday', - 'int gettimeofday(struct timeval *tv, struct timezone *tz)', - define='HAVE_GETTIMEOFDAY_TZ', headers='sys/time.h') - - conf.CHECK_C_PROTOTYPE('gettimeofday', - 'int gettimeofday(struct timeval *tv, void *tz)', - define='HAVE_GETTIMEOFDAY_TZ_VOID', - headers='sys/time.h') - - conf.CHECK_CODE('#include "tests/snprintf.c"', - define="HAVE_C99_VSNPRINTF", - execute=True, - addmain=False, - msg="Checking for C99 vsnprintf") - - conf.CHECK_CODE('#include "tests/shared_mmap.c"', - addmain=False, add_headers=False, execute=True, - define='HAVE_SHARED_MMAP', - msg="Checking for HAVE_SHARED_MMAP") - - conf.CHECK_CODE('#include "tests/shared_mremap.c"', - addmain=False, add_headers=False, execute=True, - define='HAVE_MREMAP', - msg="Checking for HAVE_MREMAP") - - # OpenBSD (and I've heard HPUX) doesn't sync between mmap and write. - # FIXME: Anything other than a 0 or 1 exit code should abort configure! - conf.CHECK_CODE('#include "tests/incoherent_mmap.c"', - addmain=False, add_headers=False, execute=True, - define='HAVE_INCOHERENT_MMAP', - msg="Checking for HAVE_INCOHERENT_MMAP") - - conf.SAMBA_BUILD_ENV() - - conf.CHECK_CODE(''' - typedef struct {unsigned x;} FOOBAR; - #define X_FOOBAR(x) ((FOOBAR) { x }) - #define FOO_ONE X_FOOBAR(1) - FOOBAR f = FOO_ONE; - static const struct { - FOOBAR y; - } f2[] = { - {FOO_ONE} - }; - static const FOOBAR f3[] = {FOO_ONE}; - ''', - define='HAVE_IMMEDIATE_STRUCTURES') - - conf.CHECK_CODE('mkdir("foo",0777)', define='HAVE_MKDIR_MODE', headers='sys/stat.h') - - conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_mtim.tv_nsec', define='HAVE_STAT_TV_NSEC', - headers='sys/stat.h') - # we need the st_rdev test under two names - conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_rdev', - define='HAVE_STRUCT_STAT_ST_RDEV', - headers='sys/stat.h') - conf.CHECK_STRUCTURE_MEMBER('struct stat', 'st_rdev', define='HAVE_ST_RDEV', - headers='sys/stat.h') - conf.CHECK_STRUCTURE_MEMBER('struct sockaddr_storage', 'ss_family', - headers='sys/socket.h netinet/in.h') - conf.CHECK_STRUCTURE_MEMBER('struct sockaddr_storage', '__ss_family', - headers='sys/socket.h netinet/in.h') - - - if conf.CHECK_STRUCTURE_MEMBER('struct sockaddr', 'sa_len', - headers='sys/socket.h netinet/in.h', - define='HAVE_SOCKADDR_SA_LEN'): - # the old build system produced both defines - conf.DEFINE('HAVE_STRUCT_SOCKADDR_SA_LEN', 1) - - conf.CHECK_STRUCTURE_MEMBER('struct sockaddr_in', 'sin_len', - headers='sys/socket.h netinet/in.h', - define='HAVE_SOCK_SIN_LEN') - - conf.CHECK_STRUCTURE_MEMBER('struct sockaddr_in6', 'sin6_len', - headers='sys/socket.h netinet/in.h', - define='HAVE_SOCK_SIN6_LEN') - - conf.CHECK_CODE('struct sockaddr_un sunaddr; sunaddr.sun_family = AF_UNIX;', - define='HAVE_UNIXSOCKET', headers='sys/socket.h sys/un.h') - - - conf.CHECK_CODE(''' - struct stat st; - char tpl[20]="/tmp/test.XXXXXX"; - char tpl2[20]="/tmp/test.XXXXXX"; - int fd = mkstemp(tpl); - int fd2 = mkstemp(tpl2); - if (fd == -1) { - if (fd2 != -1) { - unlink(tpl2); - } - exit(1); - } - if (fd2 == -1) exit(1); - unlink(tpl); - unlink(tpl2); - if (fstat(fd, &st) != 0) exit(1); - if ((st.st_mode & 0777) != 0600) exit(1); - if (strcmp(tpl, "/tmp/test.XXXXXX") == 0) { - exit(1); - } - if (strcmp(tpl, tpl2) == 0) { - exit(1); - } - exit(0); - ''', - define='HAVE_SECURE_MKSTEMP', - execute=True, - mandatory=True) # lets see if we get a mandatory failure for this one - - # look for a method of finding the list of network interfaces - for method in ['HAVE_IFACE_GETIFADDRS', 'HAVE_IFACE_AIX', 'HAVE_IFACE_IFCONF', 'HAVE_IFACE_IFREQ']: - bsd_for_strlcpy = '' - if strlcpy_in_bsd: - bsd_for_strlcpy = ' bsd' - if conf.CHECK_CODE(''' - #define %s 1 - #define NO_CONFIG_H 1 - #define AUTOCONF_TEST 1 - #include "replace.c" - #include "inet_ntop.c" - #include "snprintf.c" - #include "getifaddrs.c" - #define getifaddrs_test main - #include "tests/getifaddrs.c" - ''' % method, - method, - lib='nsl socket' + bsd_for_strlcpy, - addmain=False, - execute=True): - break - - conf.RECURSE('system') - conf.SAMBA_CONFIG_H() - if conf.CHECK_FUNCS('strerror_r'): - # Check if strerror_r is XSI-Compatable, the default GNU implementation - # is not - conf.CHECK_CODE('int strerror_r(int errnum, char *buf, size_t buflen);', - 'STRERROR_R_XSI_NOT_GNU', - headers='string.h', addmain=False, link=False, - msg="Checking for XSI (rather than GNU) prototype for strerror_r") - - -REPLACEMENT_FUNCTIONS = { - 'replace.c': ['ftruncate', 'strlcpy', 'strlcat', 'mktime', 'initgroups', - 'memmove', 'strdup', 'setlinebuf', 'vsyslog', 'strnlen', - 'strndup', 'waitpid', 'seteuid', 'setegid', 'chroot', - 'mkstemp', 'mkdtemp', 'pread', 'pwrite', 'strcasestr', - 'strsep', 'strtok_r', 'strtoll', 'strtoull', 'setenv', 'unsetenv', - 'utime', 'utimes', 'dup2', 'chown', 'link', 'readlink', - 'symlink', 'lchown', 'realpath', 'memmem', 'vdprintf', - 'dprintf', 'get_current_dir_name', - 'strerror_r', 'clock_gettime', 'memset_s'], - 'timegm.c': ['timegm'], - # Note: C99_VSNPRINTF is not a function, but a special condition - # for replacement - 'snprintf.c': ['C99_VSNPRINTF', 'snprintf', 'vsnprintf', 'asprintf', 'vasprintf'], - # Note: WORKING_STRPTIME is not a function, but a special condition - # for replacement - 'strptime.c': ['WORKING_STRPTIME', 'strptime'], - } - - -def build(bld): - bld.RECURSE('buildtools/wafsamba') - - REPLACE_HOSTCC_SOURCE = '' - - for filename in REPLACEMENT_FUNCTIONS.keys(): - for function in REPLACEMENT_FUNCTIONS[filename]: - if not bld.CONFIG_SET('HAVE_%s' % function.upper()): - REPLACE_HOSTCC_SOURCE += ' %s' % filename - break - - extra_libs = '' - if bld.CONFIG_SET('HAVE_LIBBSD'): extra_libs += ' bsd' - if bld.CONFIG_SET('HAVE_LIBRT'): extra_libs += ' rt' - if bld.CONFIG_SET('REPLACE_REQUIRES_LIBSOCKET_LIBNSL'): extra_libs += ' socket nsl' - - bld.SAMBA_SUBSYSTEM('LIBREPLACE_HOSTCC', - REPLACE_HOSTCC_SOURCE, - use_hostcc=True, - use_global_deps=False, - cflags='-D_SAMBA_HOSTCC_', - group='compiler_libraries', - deps = extra_libs - ) - - REPLACE_SOURCE = REPLACE_HOSTCC_SOURCE - REPLACE_SOURCE += ' cwrap.c' - - if not bld.CONFIG_SET('HAVE_CRYPT'): REPLACE_SOURCE += ' crypt.c' - if not bld.CONFIG_SET('HAVE_DLOPEN'): REPLACE_SOURCE += ' dlfcn.c' - if not bld.CONFIG_SET('HAVE_POLL'): REPLACE_SOURCE += ' poll.c' - - if not bld.CONFIG_SET('HAVE_SOCKETPAIR'): REPLACE_SOURCE += ' socketpair.c' - if not bld.CONFIG_SET('HAVE_CONNECT'): REPLACE_SOURCE += ' socket.c' - if not bld.CONFIG_SET('HAVE_GETIFADDRS'): REPLACE_SOURCE += ' getifaddrs.c' - if not bld.CONFIG_SET('HAVE_GETADDRINFO'): REPLACE_SOURCE += ' getaddrinfo.c' - if not bld.CONFIG_SET('HAVE_INET_NTOA'): REPLACE_SOURCE += ' inet_ntoa.c' - if not bld.CONFIG_SET('HAVE_INET_ATON'): REPLACE_SOURCE += ' inet_aton.c' - if not bld.CONFIG_SET('HAVE_INET_NTOP'): REPLACE_SOURCE += ' inet_ntop.c' - if not bld.CONFIG_SET('HAVE_INET_PTON'): REPLACE_SOURCE += ' inet_pton.c' - if not bld.CONFIG_SET('HAVE_GETXATTR') or bld.CONFIG_SET('XATTR_ADDITIONAL_OPTIONS'): - REPLACE_SOURCE += ' xattr.c' - - if not bld.CONFIG_SET('HAVE_CLOSEFROM'): - REPLACE_SOURCE += ' closefrom.c' - - bld.SAMBA_LIBRARY('replace', - source=REPLACE_SOURCE, - group='base_libraries', - # FIXME: Ideally symbols should be hidden here so they - # don't appear in the global namespace when Samba - # libraries are loaded, but this doesn't appear to work - # at the moment: - # hide_symbols=bld.BUILTIN_LIBRARY('replace'), - private_library=True, - deps='crypt dl attr' + extra_libs) - - replace_test_cflags = '' - if bld.CONFIG_SET('HAVE_WNO_FORMAT_TRUNCATION'): - replace_test_cflags += " -Wno-format-truncation" - bld.SAMBA_SUBSYSTEM('replace-test', - source='''tests/testsuite.c tests/strptime.c - tests/os2_delete.c tests/getifaddrs.c''', - deps='replace', - cflags=replace_test_cflags) - - bld.SAMBA_BINARY('replace_testsuite', - source='tests/main.c', - deps='replace replace-test', - install=False) - - # build replacements for stdint.h and stdbool.h if needed - bld.SAMBA_GENERATOR('replace_stdint_h', - rule='cp ${SRC} ${TGT}', - source='hdr_replace.h', - target='stdint.h', - enabled = not bld.CONFIG_SET('HAVE_STDINT_H')) - bld.SAMBA_GENERATOR('replace_stdbool_h', - rule='cp ${SRC} ${TGT}', - source='hdr_replace.h', - target='stdbool.h', - enabled = not bld.CONFIG_SET('HAVE_STDBOOL_H')) - - bld.SAMBA_SUBSYSTEM('samba_intl', source='', use_global_deps=False,deps=bld.env.intl_libs) - -def testonly(ctx): - '''run talloc testsuite''' - import samba_utils - - samba_utils.ADD_LD_LIBRARY_PATH('bin/shared') - samba_utils.ADD_LD_LIBRARY_PATH('bin/shared/private') - - cmd = os.path.join(Context.g_module.out, 'replace_testsuite') - ret = samba_utils.RUN_COMMAND(cmd) - print("testsuite returned %d" % ret) - sys.exit(ret) - -# WAF doesn't build the unit tests for this, maybe because they don't link with talloc? -# This forces it -def test(ctx): - Options.commands.append('build') - Options.commands.append('testonly') - -def dist(): - '''makes a tarball for distribution''' - samba_dist.dist() diff --git a/ldb-2.0.8/lib/replace/xattr.c b/ldb-2.0.8/lib/replace/xattr.c deleted file mode 100644 index 2420ee1..0000000 --- a/ldb-2.0.8/lib/replace/xattr.c +++ /dev/null @@ -1,785 +0,0 @@ -/* - Unix SMB/CIFS implementation. - replacement routines for xattr implementations - Copyright (C) Jeremy Allison 1998-2005 - Copyright (C) Timur Bakeyev 2005 - Copyright (C) Bjoern Jacke 2006-2007 - Copyright (C) Herb Lewis 2003 - Copyright (C) Andrew Bartlett 2012 - - ** NOTE! The following LGPL license applies to the replace - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#define UID_WRAPPER_NOT_REPLACE -#include "replace.h" -#include "system/filesys.h" -#include "system/dir.h" - -/******** Solaris EA helper function prototypes ********/ -#ifdef HAVE_ATTROPEN -#define SOLARIS_ATTRMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP -static int solaris_write_xattr(int attrfd, const char *value, size_t size); -static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size); -static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size); -static int solaris_unlinkat(int attrdirfd, const char *name); -static int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode); -static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode); -#endif - -/************************************************************************** - Wrappers for extented attribute calls. Based on the Linux package with - support for IRIX and (Net|Free)BSD also. Expand as other systems have them. -****************************************************************************/ - -ssize_t rep_getxattr (const char *path, const char *name, void *value, size_t size) -{ -#if defined(HAVE_XATTR_XATTR) -#ifndef XATTR_ADDITIONAL_OPTIONS - return getxattr(path, name, value, size); -#else - -/* So that we do not recursivly call this function */ -#undef getxattr - int options = 0; - return getxattr(path, name, value, size, 0, options); -#endif -#elif defined(HAVE_XATTR_EA) - return getea(path, name, value, size); -#elif defined(HAVE_XATTR_EXTATTR) - ssize_t retval; - int attrnamespace; - const char *attrname; - - if (strncmp(name, "system.", 7) == 0) { - attrnamespace = EXTATTR_NAMESPACE_SYSTEM; - attrname = name + 7; - } else if (strncmp(name, "user.", 5) == 0) { - attrnamespace = EXTATTR_NAMESPACE_USER; - attrname = name + 5; - } else { - errno = EINVAL; - return -1; - } - - /* - * The BSD implementation has a nasty habit of silently truncating - * the returned value to the size of the buffer, so we have to check - * that the buffer is large enough to fit the returned value. - */ - if((retval=extattr_get_file(path, attrnamespace, attrname, NULL, 0)) >= 0) { - if (size == 0) { - return retval; - } else if (retval > size) { - errno = ERANGE; - return -1; - } - if((retval=extattr_get_file(path, attrnamespace, attrname, value, size)) >= 0) - return retval; - } - - return -1; -#elif defined(HAVE_XATTR_ATTR) - int retval, flags = 0; - int valuelength = (int)size; - char *attrname = strchr(name,'.') + 1; - - if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; - - retval = attr_get(path, attrname, (char *)value, &valuelength, flags); - if (size == 0 && retval == -1 && errno == E2BIG) { - return valuelength; - } - - return retval ? retval : valuelength; -#elif defined(HAVE_ATTROPEN) - ssize_t ret = -1; - int attrfd = solaris_attropen(path, name, O_RDONLY, 0); - if (attrfd >= 0) { - ret = solaris_read_xattr(attrfd, value, size); - close(attrfd); - } - return ret; -#else - errno = ENOSYS; - return -1; -#endif -} - -ssize_t rep_fgetxattr (int filedes, const char *name, void *value, size_t size) -{ -#if defined(HAVE_XATTR_XATTR) -#ifndef XATTR_ADDITIONAL_OPTIONS - return fgetxattr(filedes, name, value, size); -#else - -/* So that we do not recursivly call this function */ -#undef fgetxattr - int options = 0; - return fgetxattr(filedes, name, value, size, 0, options); -#endif -#elif defined(HAVE_XATTR_EA) - return fgetea(filedes, name, value, size); -#elif defined(HAVE_XATTR_EXTATTR) - ssize_t retval; - int attrnamespace; - const char *attrname; - - if (strncmp(name, "system.", 7) == 0) { - attrnamespace = EXTATTR_NAMESPACE_SYSTEM; - attrname = name + 7; - } else if (strncmp(name, "user.", 5) == 0) { - attrnamespace = EXTATTR_NAMESPACE_USER; - attrname = name + 5; - } else { - errno = EINVAL; - return -1; - } - - if((retval=extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0)) >= 0) { - if (size == 0) { - return retval; - } else if (retval > size) { - errno = ERANGE; - return -1; - } - if((retval=extattr_get_fd(filedes, attrnamespace, attrname, value, size)) >= 0) - return retval; - } - - return -1; -#elif defined(HAVE_XATTR_ATTR) - int retval, flags = 0; - int valuelength = (int)size; - char *attrname = strchr(name,'.') + 1; - - if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; - - retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags); - if (size == 0 && retval == -1 && errno == E2BIG) { - return valuelength; - } - return retval ? retval : valuelength; -#elif defined(HAVE_ATTROPEN) - ssize_t ret = -1; - int attrfd = solaris_openat(filedes, name, O_RDONLY|O_XATTR, 0); - if (attrfd >= 0) { - ret = solaris_read_xattr(attrfd, value, size); - close(attrfd); - } - return ret; -#else - errno = ENOSYS; - return -1; -#endif -} - -#if defined(HAVE_XATTR_EXTATTR) - -#define EXTATTR_PREFIX(s) (s), (sizeof((s))-1) - -static struct { - int space; - const char *name; - size_t len; -} -extattr[] = { - { EXTATTR_NAMESPACE_SYSTEM, EXTATTR_PREFIX("system.") }, - { EXTATTR_NAMESPACE_USER, EXTATTR_PREFIX("user.") }, -}; - -typedef union { - const char *path; - int filedes; -} extattr_arg; - -static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size) -{ - ssize_t list_size, total_size = 0; - int i, t, len; - char *buf; - /* Iterate through extattr(2) namespaces */ - for(t = 0; t < ARRAY_SIZE(extattr); t++) { - if (t != EXTATTR_NAMESPACE_USER && geteuid() != 0) { - /* ignore all but user namespace when we are not root, see bug 10247 */ - continue; - } - switch(type) { - case 0: - list_size = extattr_list_file(arg.path, extattr[t].space, list, size); - break; - case 1: - list_size = extattr_list_link(arg.path, extattr[t].space, list, size); - break; - case 2: - list_size = extattr_list_fd(arg.filedes, extattr[t].space, list, size); - break; - default: - errno = ENOSYS; - return -1; - } - /* Some error happend. Errno should be set by the previous call */ - if(list_size < 0) - return -1; - /* No attributes */ - if(list_size == 0) - continue; - /* XXX: Call with an empty buffer may be used to calculate - necessary buffer size. Unfortunately, we can't say, how - many attributes were returned, so here is the potential - problem with the emulation. - */ - if(list == NULL) { - /* Take the worse case of one char attribute names - - two bytes per name plus one more for sanity. - */ - total_size += list_size + (list_size/2 + 1)*extattr[t].len; - continue; - } - /* Count necessary offset to fit namespace prefixes */ - len = 0; - for(i = 0; i < list_size; i += list[i] + 1) - len += extattr[t].len; - - total_size += list_size + len; - /* Buffer is too small to fit the results */ - if(total_size > size) { - errno = ERANGE; - return -1; - } - /* Shift results back, so we can prepend prefixes */ - buf = (char *)memmove(list + len, list, list_size); - - for(i = 0; i < list_size; i += len + 1) { - len = buf[i]; - strncpy(list, extattr[t].name, extattr[t].len + 1); - list += extattr[t].len; - strncpy(list, buf + i + 1, len); - list[len] = '\0'; - list += len + 1; - } - size -= total_size; - } - return total_size; -} - -#endif - -#if defined(HAVE_XATTR_ATTR) && (defined(HAVE_SYS_ATTRIBUTES_H) || defined(HAVE_ATTR_ATTRIBUTES_H)) -static char attr_buffer[ATTR_MAX_VALUELEN]; - -static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t size, int flags) -{ - int retval = 0, index; - attrlist_cursor_t *cursor = 0; - int total_size = 0; - attrlist_t * al = (attrlist_t *)attr_buffer; - attrlist_ent_t *ae; - size_t ent_size, left = size; - char *bp = list; - - while (true) { - if (filedes) - retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor); - else - retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor); - if (retval) break; - for (index = 0; index < al->al_count; index++) { - ae = ATTR_ENTRY(attr_buffer, index); - ent_size = strlen(ae->a_name) + sizeof("user."); - if (left >= ent_size) { - strncpy(bp, "user.", sizeof("user.")); - strncat(bp, ae->a_name, ent_size - sizeof("user.")); - bp += ent_size; - left -= ent_size; - } else if (size) { - errno = ERANGE; - retval = -1; - break; - } - total_size += ent_size; - } - if (al->al_more == 0) break; - } - if (retval == 0) { - flags |= ATTR_ROOT; - cursor = 0; - while (true) { - if (filedes) - retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor); - else - retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor); - if (retval) break; - for (index = 0; index < al->al_count; index++) { - ae = ATTR_ENTRY(attr_buffer, index); - ent_size = strlen(ae->a_name) + sizeof("system."); - if (left >= ent_size) { - strncpy(bp, "system.", sizeof("system.")); - strncat(bp, ae->a_name, ent_size - sizeof("system.")); - bp += ent_size; - left -= ent_size; - } else if (size) { - errno = ERANGE; - retval = -1; - break; - } - total_size += ent_size; - } - if (al->al_more == 0) break; - } - } - return (ssize_t)(retval ? retval : total_size); -} - -#endif - -ssize_t rep_listxattr (const char *path, char *list, size_t size) -{ -#if defined(HAVE_XATTR_XATTR) -#ifndef XATTR_ADDITIONAL_OPTIONS - return listxattr(path, list, size); -#else -/* So that we do not recursivly call this function */ -#undef listxattr - int options = 0; - return listxattr(path, list, size, options); -#endif -#elif defined(HAVE_XATTR_EA) - return listea(path, list, size); -#elif defined(HAVE_XATTR_EXTATTR) - extattr_arg arg; - arg.path = path; - return bsd_attr_list(0, arg, list, size); -#elif defined(HAVE_XATTR_ATTR) && defined(HAVE_SYS_ATTRIBUTES_H) - return irix_attr_list(path, 0, list, size, 0); -#elif defined(HAVE_ATTROPEN) - ssize_t ret = -1; - int attrdirfd = solaris_attropen(path, ".", O_RDONLY, 0); - if (attrdirfd >= 0) { - ret = solaris_list_xattr(attrdirfd, list, size); - close(attrdirfd); - } - return ret; -#else - errno = ENOSYS; - return -1; -#endif -} - -ssize_t rep_flistxattr (int filedes, char *list, size_t size) -{ -#if defined(HAVE_XATTR_XATTR) -#ifndef XATTR_ADDITIONAL_OPTIONS - return flistxattr(filedes, list, size); -#else -/* So that we do not recursivly call this function */ -#undef flistxattr - int options = 0; - return flistxattr(filedes, list, size, options); -#endif -#elif defined(HAVE_XATTR_EA) - return flistea(filedes, list, size); -#elif defined(HAVE_XATTR_EXTATTR) - extattr_arg arg; - arg.filedes = filedes; - return bsd_attr_list(2, arg, list, size); -#elif defined(HAVE_XATTR_ATTR) - return irix_attr_list(NULL, filedes, list, size, 0); -#elif defined(HAVE_ATTROPEN) - ssize_t ret = -1; - int attrdirfd = solaris_openat(filedes, ".", O_RDONLY|O_XATTR, 0); - if (attrdirfd >= 0) { - ret = solaris_list_xattr(attrdirfd, list, size); - close(attrdirfd); - } - return ret; -#else - errno = ENOSYS; - return -1; -#endif -} - -int rep_removexattr (const char *path, const char *name) -{ -#if defined(HAVE_XATTR_XATTR) -#ifndef XATTR_ADDITIONAL_OPTIONS - return removexattr(path, name); -#else -/* So that we do not recursivly call this function */ -#undef removexattr - int options = 0; - return removexattr(path, name, options); -#endif -#elif defined(HAVE_XATTR_EA) - return removeea(path, name); -#elif defined(HAVE_XATTR_EXTATTR) - int attrnamespace; - const char *attrname; - - if (strncmp(name, "system.", 7) == 0) { - attrnamespace = EXTATTR_NAMESPACE_SYSTEM; - attrname = name + 7; - } else if (strncmp(name, "user.", 5) == 0) { - attrnamespace = EXTATTR_NAMESPACE_USER; - attrname = name + 5; - } else { - errno = EINVAL; - return -1; - } - - return extattr_delete_file(path, attrnamespace, attrname); -#elif defined(HAVE_XATTR_ATTR) - int flags = 0; - char *attrname = strchr(name,'.') + 1; - - if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; - - return attr_remove(path, attrname, flags); -#elif defined(HAVE_ATTROPEN) - int ret = -1; - int attrdirfd = solaris_attropen(path, ".", O_RDONLY, 0); - if (attrdirfd >= 0) { - ret = solaris_unlinkat(attrdirfd, name); - close(attrdirfd); - } - return ret; -#else - errno = ENOSYS; - return -1; -#endif -} - -int rep_fremovexattr (int filedes, const char *name) -{ -#if defined(HAVE_XATTR_XATTR) -#ifndef XATTR_ADDITIONAL_OPTIONS - return fremovexattr(filedes, name); -#else -/* So that we do not recursivly call this function */ -#undef fremovexattr - int options = 0; - return fremovexattr(filedes, name, options); -#endif -#elif defined(HAVE_XATTR_EA) - return fremoveea(filedes, name); -#elif defined(HAVE_XATTR_EXTATTR) - int attrnamespace; - const char *attrname; - - if (strncmp(name, "system.", 7) == 0) { - attrnamespace = EXTATTR_NAMESPACE_SYSTEM; - attrname = name + 7; - } else if (strncmp(name, "user.", 5) == 0) { - attrnamespace = EXTATTR_NAMESPACE_USER; - attrname = name + 5; - } else { - errno = EINVAL; - return -1; - } - - return extattr_delete_fd(filedes, attrnamespace, attrname); -#elif defined(HAVE_XATTR_ATTR) - int flags = 0; - char *attrname = strchr(name,'.') + 1; - - if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT; - - return attr_removef(filedes, attrname, flags); -#elif defined(HAVE_ATTROPEN) - int ret = -1; - int attrdirfd = solaris_openat(filedes, ".", O_RDONLY|O_XATTR, 0); - if (attrdirfd >= 0) { - ret = solaris_unlinkat(attrdirfd, name); - close(attrdirfd); - } - return ret; -#else - errno = ENOSYS; - return -1; -#endif -} - -int rep_setxattr (const char *path, const char *name, const void *value, size_t size, int flags) -{ -#if defined(HAVE_XATTR_XATTR) -#ifndef XATTR_ADDITIONAL_OPTIONS - return setxattr(path, name, value, size, flags); -#else -/* So that we do not recursivly call this function */ -#undef setxattr - int options = 0; - return setxattr(path, name, value, size, 0, options); -#endif -#elif defined(HAVE_XATTR_EA) - return setea(path, name, value, size, flags); -#elif defined(HAVE_XATTR_EXTATTR) - int retval = 0; - int attrnamespace; - const char *attrname; - - if (strncmp(name, "system.", 7) == 0) { - attrnamespace = EXTATTR_NAMESPACE_SYSTEM; - attrname = name + 7; - } else if (strncmp(name, "user.", 5) == 0) { - attrnamespace = EXTATTR_NAMESPACE_USER; - attrname = name + 5; - } else { - errno = EINVAL; - return -1; - } - - if (flags) { - /* Check attribute existence */ - retval = extattr_get_file(path, attrnamespace, attrname, NULL, 0); - if (retval < 0) { - /* REPLACE attribute, that doesn't exist */ - if (flags & XATTR_REPLACE && errno == ENOATTR) { - errno = ENOATTR; - return -1; - } - /* Ignore other errors */ - } - else { - /* CREATE attribute, that already exists */ - if (flags & XATTR_CREATE) { - errno = EEXIST; - return -1; - } - } - } - retval = extattr_set_file(path, attrnamespace, attrname, value, size); - return (retval < 0) ? -1 : 0; -#elif defined(HAVE_XATTR_ATTR) - int myflags = 0; - char *attrname = strchr(name,'.') + 1; - - if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT; - if (flags & XATTR_CREATE) myflags |= ATTR_CREATE; - if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE; - - return attr_set(path, attrname, (const char *)value, size, myflags); -#elif defined(HAVE_ATTROPEN) - int ret = -1; - int myflags = O_RDWR; - int attrfd; - if (flags & XATTR_CREATE) myflags |= O_EXCL; - if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT; - attrfd = solaris_attropen(path, name, myflags, (mode_t) SOLARIS_ATTRMODE); - if (attrfd >= 0) { - ret = solaris_write_xattr(attrfd, value, size); - close(attrfd); - } - return ret; -#else - errno = ENOSYS; - return -1; -#endif -} - -int rep_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags) -{ -#if defined(HAVE_XATTR_XATTR) -#ifndef XATTR_ADDITIONAL_OPTIONS - return fsetxattr(filedes, name, value, size, flags); -#else -/* So that we do not recursivly call this function */ -#undef fsetxattr - int options = 0; - return fsetxattr(filedes, name, value, size, 0, options); -#endif -#elif defined(HAVE_XATTR_EA) - return fsetea(filedes, name, value, size, flags); -#elif defined(HAVE_XATTR_EXTATTR) - int retval = 0; - int attrnamespace; - const char *attrname; - - if (strncmp(name, "system.", 7) == 0) { - attrnamespace = EXTATTR_NAMESPACE_SYSTEM; - attrname = name + 7; - } else if (strncmp(name, "user.", 5) == 0) { - attrnamespace = EXTATTR_NAMESPACE_USER; - attrname = name + 5; - } else { - errno = EINVAL; - return -1; - } - - if (flags) { - /* Check attribute existence */ - retval = extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0); - if (retval < 0) { - /* REPLACE attribute, that doesn't exist */ - if (flags & XATTR_REPLACE && errno == ENOATTR) { - errno = ENOATTR; - return -1; - } - /* Ignore other errors */ - } - else { - /* CREATE attribute, that already exists */ - if (flags & XATTR_CREATE) { - errno = EEXIST; - return -1; - } - } - } - retval = extattr_set_fd(filedes, attrnamespace, attrname, value, size); - return (retval < 0) ? -1 : 0; -#elif defined(HAVE_XATTR_ATTR) - int myflags = 0; - char *attrname = strchr(name,'.') + 1; - - if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT; - if (flags & XATTR_CREATE) myflags |= ATTR_CREATE; - if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE; - - return attr_setf(filedes, attrname, (const char *)value, size, myflags); -#elif defined(HAVE_ATTROPEN) - int ret = -1; - int myflags = O_RDWR | O_XATTR; - int attrfd; - if (flags & XATTR_CREATE) myflags |= O_EXCL; - if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT; - attrfd = solaris_openat(filedes, name, myflags, (mode_t) SOLARIS_ATTRMODE); - if (attrfd >= 0) { - ret = solaris_write_xattr(attrfd, value, size); - close(attrfd); - } - return ret; -#else - errno = ENOSYS; - return -1; -#endif -} - -/************************************************************************** - helper functions for Solaris' EA support -****************************************************************************/ -#ifdef HAVE_ATTROPEN -static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size) -{ - struct stat sbuf; - - if (fstat(attrfd, &sbuf) == -1) { - errno = ENOATTR; - return -1; - } - - /* This is to return the current size of the named extended attribute */ - if (size == 0) { - return sbuf.st_size; - } - - /* check size and read xattr */ - if (sbuf.st_size > size) { - errno = ERANGE; - return -1; - } - - return read(attrfd, value, sbuf.st_size); -} - -static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size) -{ - ssize_t len = 0; - DIR *dirp; - struct dirent *de; - int newfd = dup(attrdirfd); - /* CAUTION: The originating file descriptor should not be - used again following the call to fdopendir(). - For that reason we dup() the file descriptor - here to make things more clear. */ - dirp = fdopendir(newfd); - - while ((de = readdir(dirp))) { - size_t listlen = strlen(de->d_name) + 1; - if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) { - /* we don't want "." and ".." here: */ - continue; - } - - if (size == 0) { - /* return the current size of the list of extended attribute names*/ - len += listlen; - } else { - /* check size and copy entrieÑ• + nul into list. */ - if ((len + listlen) > size) { - errno = ERANGE; - len = -1; - break; - } else { - strlcpy(list + len, de->d_name, listlen); - len += listlen; - } - } - } - - if (closedir(dirp) == -1) { - return -1; - } - return len; -} - -static int solaris_unlinkat(int attrdirfd, const char *name) -{ - if (unlinkat(attrdirfd, name, 0) == -1) { - if (errno == ENOENT) { - errno = ENOATTR; - } - return -1; - } - return 0; -} - -static int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode) -{ - int filedes = attropen(path, attrpath, oflag, mode); - if (filedes == -1) { - if (errno == EINVAL) { - errno = ENOTSUP; - } else { - errno = ENOATTR; - } - } - return filedes; -} - -static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode) -{ - int filedes = openat(fildes, path, oflag, mode); - if (filedes == -1) { - if (errno == EINVAL) { - errno = ENOTSUP; - } else { - errno = ENOATTR; - } - } - return filedes; -} - -static int solaris_write_xattr(int attrfd, const char *value, size_t size) -{ - if ((ftruncate(attrfd, 0) == 0) && (write(attrfd, value, size) == size)) { - return 0; - } else { - return -1; - } -} -#endif /*HAVE_ATTROPEN*/ - - diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.6.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.6.sigs deleted file mode 100644 index 961c1a8..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.6.sigs +++ /dev/null @@ -1,6 +0,0 @@ -pytalloc_CObject_FromTallocPtr: PyObject *(void *) -pytalloc_Check: int (PyObject *) -pytalloc_GetObjectType: PyTypeObject *(void) -pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) -pytalloc_steal: PyObject *(PyTypeObject *, void *) -pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.7.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.7.sigs deleted file mode 100644 index 961c1a8..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.7.sigs +++ /dev/null @@ -1,6 +0,0 @@ -pytalloc_CObject_FromTallocPtr: PyObject *(void *) -pytalloc_Check: int (PyObject *) -pytalloc_GetObjectType: PyTypeObject *(void) -pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) -pytalloc_steal: PyObject *(PyTypeObject *, void *) -pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.8.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.8.sigs deleted file mode 100644 index 961c1a8..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.0.8.sigs +++ /dev/null @@ -1,6 +0,0 @@ -pytalloc_CObject_FromTallocPtr: PyObject *(void *) -pytalloc_Check: int (PyObject *) -pytalloc_GetObjectType: PyTypeObject *(void) -pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) -pytalloc_steal: PyObject *(PyTypeObject *, void *) -pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.0.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.0.sigs deleted file mode 100644 index 961c1a8..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.0.sigs +++ /dev/null @@ -1,6 +0,0 @@ -pytalloc_CObject_FromTallocPtr: PyObject *(void *) -pytalloc_Check: int (PyObject *) -pytalloc_GetObjectType: PyTypeObject *(void) -pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) -pytalloc_steal: PyObject *(PyTypeObject *, void *) -pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.1.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.1.sigs deleted file mode 100644 index 961c1a8..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.1.sigs +++ /dev/null @@ -1,6 +0,0 @@ -pytalloc_CObject_FromTallocPtr: PyObject *(void *) -pytalloc_Check: int (PyObject *) -pytalloc_GetObjectType: PyTypeObject *(void) -pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) -pytalloc_steal: PyObject *(PyTypeObject *, void *) -pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.10.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.10.sigs deleted file mode 100644 index 9d4d4d1..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.10.sigs +++ /dev/null @@ -1,16 +0,0 @@ -_pytalloc_check_type: int (PyObject *, const char *) -_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) -_pytalloc_get_ptr: void *(PyObject *) -_pytalloc_get_type: void *(PyObject *, const char *) -pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) -pytalloc_BaseObject_check: int (PyObject *) -pytalloc_BaseObject_size: size_t (void) -pytalloc_CObject_FromTallocPtr: PyObject *(void *) -pytalloc_Check: int (PyObject *) -pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *) -pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *) -pytalloc_GetBaseObjectType: PyTypeObject *(void) -pytalloc_GetObjectType: PyTypeObject *(void) -pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) -pytalloc_steal: PyObject *(PyTypeObject *, void *) -pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.11.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.11.sigs deleted file mode 100644 index 9d4d4d1..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.11.sigs +++ /dev/null @@ -1,16 +0,0 @@ -_pytalloc_check_type: int (PyObject *, const char *) -_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) -_pytalloc_get_ptr: void *(PyObject *) -_pytalloc_get_type: void *(PyObject *, const char *) -pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) -pytalloc_BaseObject_check: int (PyObject *) -pytalloc_BaseObject_size: size_t (void) -pytalloc_CObject_FromTallocPtr: PyObject *(void *) -pytalloc_Check: int (PyObject *) -pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *) -pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *) -pytalloc_GetBaseObjectType: PyTypeObject *(void) -pytalloc_GetObjectType: PyTypeObject *(void) -pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) -pytalloc_steal: PyObject *(PyTypeObject *, void *) -pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.12.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.12.sigs deleted file mode 100644 index 9d4d4d1..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.12.sigs +++ /dev/null @@ -1,16 +0,0 @@ -_pytalloc_check_type: int (PyObject *, const char *) -_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) -_pytalloc_get_ptr: void *(PyObject *) -_pytalloc_get_type: void *(PyObject *, const char *) -pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) -pytalloc_BaseObject_check: int (PyObject *) -pytalloc_BaseObject_size: size_t (void) -pytalloc_CObject_FromTallocPtr: PyObject *(void *) -pytalloc_Check: int (PyObject *) -pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *) -pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *) -pytalloc_GetBaseObjectType: PyTypeObject *(void) -pytalloc_GetObjectType: PyTypeObject *(void) -pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) -pytalloc_steal: PyObject *(PyTypeObject *, void *) -pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.13.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.13.sigs deleted file mode 100644 index 9d4d4d1..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.13.sigs +++ /dev/null @@ -1,16 +0,0 @@ -_pytalloc_check_type: int (PyObject *, const char *) -_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) -_pytalloc_get_ptr: void *(PyObject *) -_pytalloc_get_type: void *(PyObject *, const char *) -pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) -pytalloc_BaseObject_check: int (PyObject *) -pytalloc_BaseObject_size: size_t (void) -pytalloc_CObject_FromTallocPtr: PyObject *(void *) -pytalloc_Check: int (PyObject *) -pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *) -pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *) -pytalloc_GetBaseObjectType: PyTypeObject *(void) -pytalloc_GetObjectType: PyTypeObject *(void) -pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) -pytalloc_steal: PyObject *(PyTypeObject *, void *) -pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.14.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.14.sigs deleted file mode 100644 index 9d4d4d1..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.14.sigs +++ /dev/null @@ -1,16 +0,0 @@ -_pytalloc_check_type: int (PyObject *, const char *) -_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) -_pytalloc_get_ptr: void *(PyObject *) -_pytalloc_get_type: void *(PyObject *, const char *) -pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) -pytalloc_BaseObject_check: int (PyObject *) -pytalloc_BaseObject_size: size_t (void) -pytalloc_CObject_FromTallocPtr: PyObject *(void *) -pytalloc_Check: int (PyObject *) -pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *) -pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *) -pytalloc_GetBaseObjectType: PyTypeObject *(void) -pytalloc_GetObjectType: PyTypeObject *(void) -pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) -pytalloc_steal: PyObject *(PyTypeObject *, void *) -pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.15.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.15.sigs deleted file mode 100644 index 9d4d4d1..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.15.sigs +++ /dev/null @@ -1,16 +0,0 @@ -_pytalloc_check_type: int (PyObject *, const char *) -_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) -_pytalloc_get_ptr: void *(PyObject *) -_pytalloc_get_type: void *(PyObject *, const char *) -pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) -pytalloc_BaseObject_check: int (PyObject *) -pytalloc_BaseObject_size: size_t (void) -pytalloc_CObject_FromTallocPtr: PyObject *(void *) -pytalloc_Check: int (PyObject *) -pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *) -pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *) -pytalloc_GetBaseObjectType: PyTypeObject *(void) -pytalloc_GetObjectType: PyTypeObject *(void) -pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) -pytalloc_steal: PyObject *(PyTypeObject *, void *) -pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.16.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.16.sigs deleted file mode 100644 index 9d4d4d1..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.16.sigs +++ /dev/null @@ -1,16 +0,0 @@ -_pytalloc_check_type: int (PyObject *, const char *) -_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) -_pytalloc_get_ptr: void *(PyObject *) -_pytalloc_get_type: void *(PyObject *, const char *) -pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) -pytalloc_BaseObject_check: int (PyObject *) -pytalloc_BaseObject_size: size_t (void) -pytalloc_CObject_FromTallocPtr: PyObject *(void *) -pytalloc_Check: int (PyObject *) -pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *) -pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *) -pytalloc_GetBaseObjectType: PyTypeObject *(void) -pytalloc_GetObjectType: PyTypeObject *(void) -pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) -pytalloc_steal: PyObject *(PyTypeObject *, void *) -pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.2.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.2.sigs deleted file mode 100644 index 961c1a8..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.2.sigs +++ /dev/null @@ -1,6 +0,0 @@ -pytalloc_CObject_FromTallocPtr: PyObject *(void *) -pytalloc_Check: int (PyObject *) -pytalloc_GetObjectType: PyTypeObject *(void) -pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) -pytalloc_steal: PyObject *(PyTypeObject *, void *) -pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.3.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.3.sigs deleted file mode 100644 index 961c1a8..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.3.sigs +++ /dev/null @@ -1,6 +0,0 @@ -pytalloc_CObject_FromTallocPtr: PyObject *(void *) -pytalloc_Check: int (PyObject *) -pytalloc_GetObjectType: PyTypeObject *(void) -pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) -pytalloc_steal: PyObject *(PyTypeObject *, void *) -pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.4.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.4.sigs deleted file mode 100644 index 961c1a8..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.4.sigs +++ /dev/null @@ -1,6 +0,0 @@ -pytalloc_CObject_FromTallocPtr: PyObject *(void *) -pytalloc_Check: int (PyObject *) -pytalloc_GetObjectType: PyTypeObject *(void) -pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) -pytalloc_steal: PyObject *(PyTypeObject *, void *) -pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.5.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.5.sigs deleted file mode 100644 index 961c1a8..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.5.sigs +++ /dev/null @@ -1,6 +0,0 @@ -pytalloc_CObject_FromTallocPtr: PyObject *(void *) -pytalloc_Check: int (PyObject *) -pytalloc_GetObjectType: PyTypeObject *(void) -pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) -pytalloc_steal: PyObject *(PyTypeObject *, void *) -pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.6.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.6.sigs deleted file mode 100644 index 666fec0..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.6.sigs +++ /dev/null @@ -1,13 +0,0 @@ -_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) -_pytalloc_get_ptr: void *(PyObject *) -_pytalloc_get_type: void *(PyObject *, const char *) -pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) -pytalloc_BaseObject_check: int (PyObject *) -pytalloc_BaseObject_size: size_t (void) -pytalloc_CObject_FromTallocPtr: PyObject *(void *) -pytalloc_Check: int (PyObject *) -pytalloc_GetBaseObjectType: PyTypeObject *(void) -pytalloc_GetObjectType: PyTypeObject *(void) -pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) -pytalloc_steal: PyObject *(PyTypeObject *, void *) -pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.7.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.7.sigs deleted file mode 100644 index 666fec0..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.7.sigs +++ /dev/null @@ -1,13 +0,0 @@ -_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) -_pytalloc_get_ptr: void *(PyObject *) -_pytalloc_get_type: void *(PyObject *, const char *) -pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) -pytalloc_BaseObject_check: int (PyObject *) -pytalloc_BaseObject_size: size_t (void) -pytalloc_CObject_FromTallocPtr: PyObject *(void *) -pytalloc_Check: int (PyObject *) -pytalloc_GetBaseObjectType: PyTypeObject *(void) -pytalloc_GetObjectType: PyTypeObject *(void) -pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) -pytalloc_steal: PyObject *(PyTypeObject *, void *) -pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.8.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.8.sigs deleted file mode 100644 index 666fec0..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.8.sigs +++ /dev/null @@ -1,13 +0,0 @@ -_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) -_pytalloc_get_ptr: void *(PyObject *) -_pytalloc_get_type: void *(PyObject *, const char *) -pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) -pytalloc_BaseObject_check: int (PyObject *) -pytalloc_BaseObject_size: size_t (void) -pytalloc_CObject_FromTallocPtr: PyObject *(void *) -pytalloc_Check: int (PyObject *) -pytalloc_GetBaseObjectType: PyTypeObject *(void) -pytalloc_GetObjectType: PyTypeObject *(void) -pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) -pytalloc_steal: PyObject *(PyTypeObject *, void *) -pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.9.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.9.sigs deleted file mode 100644 index 9d4d4d1..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.1.9.sigs +++ /dev/null @@ -1,16 +0,0 @@ -_pytalloc_check_type: int (PyObject *, const char *) -_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) -_pytalloc_get_ptr: void *(PyObject *) -_pytalloc_get_type: void *(PyObject *, const char *) -pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) -pytalloc_BaseObject_check: int (PyObject *) -pytalloc_BaseObject_size: size_t (void) -pytalloc_CObject_FromTallocPtr: PyObject *(void *) -pytalloc_Check: int (PyObject *) -pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *) -pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *) -pytalloc_GetBaseObjectType: PyTypeObject *(void) -pytalloc_GetObjectType: PyTypeObject *(void) -pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) -pytalloc_steal: PyObject *(PyTypeObject *, void *) -pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.2.0.sigs b/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.2.0.sigs deleted file mode 100644 index 62f066f..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/pytalloc-util-2.2.0.sigs +++ /dev/null @@ -1,15 +0,0 @@ -_pytalloc_check_type: int (PyObject *, const char *) -_pytalloc_get_mem_ctx: TALLOC_CTX *(PyObject *) -_pytalloc_get_ptr: void *(PyObject *) -_pytalloc_get_type: void *(PyObject *, const char *) -pytalloc_BaseObject_PyType_Ready: int (PyTypeObject *) -pytalloc_BaseObject_check: int (PyObject *) -pytalloc_BaseObject_size: size_t (void) -pytalloc_Check: int (PyObject *) -pytalloc_GenericObject_reference_ex: PyObject *(TALLOC_CTX *, void *) -pytalloc_GenericObject_steal_ex: PyObject *(TALLOC_CTX *, void *) -pytalloc_GetBaseObjectType: PyTypeObject *(void) -pytalloc_GetObjectType: PyTypeObject *(void) -pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) -pytalloc_steal: PyObject *(PyTypeObject *, void *) -pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.2.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.2.sigs deleted file mode 100644 index 6e236d5..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.2.sigs +++ /dev/null @@ -1,62 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.3.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.3.sigs deleted file mode 100644 index 6e236d5..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.3.sigs +++ /dev/null @@ -1,62 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.4.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.4.sigs deleted file mode 100644 index 6e236d5..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.4.sigs +++ /dev/null @@ -1,62 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.5.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.5.sigs deleted file mode 100644 index 6e236d5..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.5.sigs +++ /dev/null @@ -1,62 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.6.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.6.sigs deleted file mode 100644 index 6e236d5..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.6.sigs +++ /dev/null @@ -1,62 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.7.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.7.sigs deleted file mode 100644 index 6e236d5..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.7.sigs +++ /dev/null @@ -1,62 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.8.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.8.sigs deleted file mode 100644 index 15a9e95..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.0.8.sigs +++ /dev/null @@ -1,63 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_memlimit: int (const void *, size_t) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.0.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.0.sigs deleted file mode 100644 index eae12cc..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.0.sigs +++ /dev/null @@ -1,64 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_memlimit: int (const void *, size_t) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.1.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.1.sigs deleted file mode 100644 index eae12cc..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.1.sigs +++ /dev/null @@ -1,64 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_memlimit: int (const void *, size_t) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.10.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.10.sigs deleted file mode 100644 index 9969ce3..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.10.sigs +++ /dev/null @@ -1,65 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_memlimit: int (const void *, size_t) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_test_get_magic: int (void) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.11.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.11.sigs deleted file mode 100644 index 9969ce3..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.11.sigs +++ /dev/null @@ -1,65 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_memlimit: int (const void *, size_t) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_test_get_magic: int (void) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.12.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.12.sigs deleted file mode 100644 index 9969ce3..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.12.sigs +++ /dev/null @@ -1,65 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_memlimit: int (const void *, size_t) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_test_get_magic: int (void) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.13.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.13.sigs deleted file mode 100644 index 9969ce3..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.13.sigs +++ /dev/null @@ -1,65 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_memlimit: int (const void *, size_t) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_test_get_magic: int (void) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.14.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.14.sigs deleted file mode 100644 index 9969ce3..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.14.sigs +++ /dev/null @@ -1,65 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_memlimit: int (const void *, size_t) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_test_get_magic: int (void) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.15.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.15.sigs deleted file mode 100644 index 9969ce3..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.15.sigs +++ /dev/null @@ -1,65 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_memlimit: int (const void *, size_t) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_test_get_magic: int (void) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.16.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.16.sigs deleted file mode 100644 index 9969ce3..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.16.sigs +++ /dev/null @@ -1,65 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_memlimit: int (const void *, size_t) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_test_get_magic: int (void) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.2.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.2.sigs deleted file mode 100644 index eae12cc..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.2.sigs +++ /dev/null @@ -1,64 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_memlimit: int (const void *, size_t) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.3.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.3.sigs deleted file mode 100644 index eae12cc..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.3.sigs +++ /dev/null @@ -1,64 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_memlimit: int (const void *, size_t) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.4.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.4.sigs deleted file mode 100644 index 9969ce3..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.4.sigs +++ /dev/null @@ -1,65 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_memlimit: int (const void *, size_t) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_test_get_magic: int (void) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.5.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.5.sigs deleted file mode 100644 index 9969ce3..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.5.sigs +++ /dev/null @@ -1,65 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_memlimit: int (const void *, size_t) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_test_get_magic: int (void) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.6.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.6.sigs deleted file mode 100644 index 9969ce3..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.6.sigs +++ /dev/null @@ -1,65 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_memlimit: int (const void *, size_t) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_test_get_magic: int (void) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.7.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.7.sigs deleted file mode 100644 index 9969ce3..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.7.sigs +++ /dev/null @@ -1,65 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_memlimit: int (const void *, size_t) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_test_get_magic: int (void) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.8.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.8.sigs deleted file mode 100644 index 9969ce3..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.8.sigs +++ /dev/null @@ -1,65 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_memlimit: int (const void *, size_t) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_test_get_magic: int (void) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.9.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.9.sigs deleted file mode 100644 index 9969ce3..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.1.9.sigs +++ /dev/null @@ -1,65 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_memlimit: int (const void *, size_t) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_test_get_magic: int (void) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/ABI/talloc-2.2.0.sigs b/ldb-2.0.8/lib/talloc/ABI/talloc-2.2.0.sigs deleted file mode 100644 index 9969ce3..0000000 --- a/ldb-2.0.8/lib/talloc/ABI/talloc-2.2.0.sigs +++ /dev/null @@ -1,65 +0,0 @@ -_talloc: void *(const void *, size_t) -_talloc_array: void *(const void *, size_t, unsigned int, const char *) -_talloc_free: int (void *, const char *) -_talloc_get_type_abort: void *(const void *, const char *, const char *) -_talloc_memdup: void *(const void *, const void *, size_t, const char *) -_talloc_move: void *(const void *, const void *) -_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) -_talloc_realloc: void *(const void *, void *, size_t, const char *) -_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) -_talloc_reference_loc: void *(const void *, const void *, const char *) -_talloc_set_destructor: void (const void *, int (*)(void *)) -_talloc_steal_loc: void *(const void *, const void *, const char *) -_talloc_zero: void *(const void *, size_t, const char *) -_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) -talloc_asprintf: char *(const void *, const char *, ...) -talloc_asprintf_append: char *(char *, const char *, ...) -talloc_asprintf_append_buffer: char *(char *, const char *, ...) -talloc_autofree_context: void *(void) -talloc_check_name: void *(const void *, const char *) -talloc_disable_null_tracking: void (void) -talloc_enable_leak_report: void (void) -talloc_enable_leak_report_full: void (void) -talloc_enable_null_tracking: void (void) -talloc_enable_null_tracking_no_autofree: void (void) -talloc_find_parent_byname: void *(const void *, const char *) -talloc_free_children: void (void *) -talloc_get_name: const char *(const void *) -talloc_get_size: size_t (const void *) -talloc_increase_ref_count: int (const void *) -talloc_init: void *(const char *, ...) -talloc_is_parent: int (const void *, const void *) -talloc_named: void *(const void *, size_t, const char *, ...) -talloc_named_const: void *(const void *, size_t, const char *) -talloc_parent: void *(const void *) -talloc_parent_name: const char *(const void *) -talloc_pool: void *(const void *, size_t) -talloc_realloc_fn: void *(const void *, void *, size_t) -talloc_reference_count: size_t (const void *) -talloc_reparent: void *(const void *, const void *, const void *) -talloc_report: void (const void *, FILE *) -talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) -talloc_report_depth_file: void (const void *, int, int, FILE *) -talloc_report_full: void (const void *, FILE *) -talloc_set_abort_fn: void (void (*)(const char *)) -talloc_set_log_fn: void (void (*)(const char *)) -talloc_set_log_stderr: void (void) -talloc_set_memlimit: int (const void *, size_t) -talloc_set_name: const char *(const void *, const char *, ...) -talloc_set_name_const: void (const void *, const char *) -talloc_show_parents: void (const void *, FILE *) -talloc_strdup: char *(const void *, const char *) -talloc_strdup_append: char *(char *, const char *) -talloc_strdup_append_buffer: char *(char *, const char *) -talloc_strndup: char *(const void *, const char *, size_t) -talloc_strndup_append: char *(char *, const char *, size_t) -talloc_strndup_append_buffer: char *(char *, const char *, size_t) -talloc_test_get_magic: int (void) -talloc_total_blocks: size_t (const void *) -talloc_total_size: size_t (const void *) -talloc_unlink: int (const void *, void *) -talloc_vasprintf: char *(const void *, const char *, va_list) -talloc_vasprintf_append: char *(char *, const char *, va_list) -talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) -talloc_version_major: int (void) -talloc_version_minor: int (void) diff --git a/ldb-2.0.8/lib/talloc/Makefile b/ldb-2.0.8/lib/talloc/Makefile deleted file mode 100644 index db2275c..0000000 --- a/ldb-2.0.8/lib/talloc/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -# simple makefile wrapper to run waf - -WAF_BIN=`PATH=buildtools/bin:../../buildtools/bin:$$PATH which waf` -WAF_BINARY=$(PYTHON) $(WAF_BIN) -WAF=PYTHONHASHSEED=1 WAF_MAKE=1 $(WAF_BINARY) - -all: - $(WAF) build - -install: - $(WAF) install - -uninstall: - $(WAF) uninstall - -test: - $(WAF) test $(TEST_OPTIONS) - -testenv: - $(WAF) test --testenv $(TEST_OPTIONS) - -quicktest: - $(WAF) test --quick $(TEST_OPTIONS) - -dist: - touch .tmplock - WAFLOCK=.tmplock $(WAF) dist - -distcheck: - touch .tmplock - WAFLOCK=.tmplock $(WAF) distcheck - -clean: - $(WAF) clean - -distclean: - $(WAF) distclean - -reconfigure: configure - $(WAF) reconfigure - -show_waf_options: - $(WAF) --help - -# some compatibility make targets -everything: all - -testsuite: all - -check: test - -torture: all - -# this should do an install as well, once install is finished -installcheck: test - -etags: - $(WAF) etags - -ctags: - $(WAF) ctags - -pydoctor: - $(WAF) pydoctor - -bin/%:: FORCE - $(WAF) --targets=`basename $@` -FORCE: diff --git a/ldb-2.0.8/lib/talloc/NEWS b/ldb-2.0.8/lib/talloc/NEWS deleted file mode 100644 index e5b3aa0..0000000 --- a/ldb-2.0.8/lib/talloc/NEWS +++ /dev/null @@ -1,13 +0,0 @@ -1.0.1 26 May 2007 - - BUGS - - * Set name of correctly when using talloc_append_string() (metze) - - LICENSE - - * Change license of files in lib/replace to LGPL (was GPL). (jelmer) - -1.0.0 30 April 2007 - - Initial release. diff --git a/ldb-2.0.8/lib/talloc/compat/talloc_compat1.c b/ldb-2.0.8/lib/talloc/compat/talloc_compat1.c deleted file mode 100644 index 519e8c3..0000000 --- a/ldb-2.0.8/lib/talloc/compat/talloc_compat1.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - Samba trivial allocation library - compat functions - - Copyright (C) Stefan Metzmacher 2009 - - ** NOTE! The following LGPL license applies to the talloc - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * This file contains only function to build a - * compat talloc.so.1 library on top of talloc.so.2 - */ - -#include "replace.h" -#include "talloc.h" - -void *_talloc_reference(const void *context, const void *ptr); -void *_talloc_reference(const void *context, const void *ptr) { - return _talloc_reference_loc(context, ptr, - "Called from talloc compat1 " - "_talloc_reference"); -} - -void *_talloc_steal(const void *new_ctx, const void *ptr); -void *_talloc_steal(const void *new_ctx, const void *ptr) -{ - return talloc_reparent(talloc_parent(ptr), new_ctx, ptr); -} - -#undef talloc_free -int talloc_free(void *ptr); -int talloc_free(void *ptr) -{ - return talloc_unlink(talloc_parent(ptr), ptr); -} - diff --git a/ldb-2.0.8/lib/talloc/compat/talloc_compat1.mk b/ldb-2.0.8/lib/talloc/compat/talloc_compat1.mk deleted file mode 100644 index d1817f0..0000000 --- a/ldb-2.0.8/lib/talloc/compat/talloc_compat1.mk +++ /dev/null @@ -1,21 +0,0 @@ -talloccompatdir := $(tallocdir)/compat - -TALLOC_COMPAT1_VERSION_MAJOR = 1 -TALLOC_COMPAT1_OBJ = $(talloccompatdir)/talloc_compat1.o - -TALLOC_COMPAT1_SOLIB = libtalloc-compat1-$(TALLOC_VERSION).$(SHLIBEXT) -TALLOC_COMPAT1_SONAME = libtalloc.$(SHLIBEXT).$(TALLOC_COMPAT1_VERSION_MAJOR) - -$(TALLOC_COMPAT1_SOLIB): $(TALLOC_COMPAT1_OBJ) $(TALLOC_SOLIB) - $(SHLD) $(SHLD_FLAGS) -o $@ $(TALLOC_COMPAT1_OBJ) \ - $(TALLOC_SOLIB) $(SONAMEFLAG)$(TALLOC_COMPAT1_SONAME) - -all:: $(TALLOC_COMPAT1_SOLIB) - -install:: - ${INSTALLCMD} -d $(DESTDIR)$(libdir) - ${INSTALLCMD} -m 755 $(TALLOC_COMPAT1_SOLIB) $(DESTDIR)$(libdir) - -clean:: - rm -f $(TALLOC_COMPAT1_OBJ) $(TALLOC_COMPAT1_SOLIB) - diff --git a/ldb-2.0.8/lib/talloc/configure b/ldb-2.0.8/lib/talloc/configure deleted file mode 100755 index d8a8d2a..0000000 --- a/ldb-2.0.8/lib/talloc/configure +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -PREVPATH=`dirname $0` - -if [ -f $PREVPATH/../../buildtools/bin/waf ]; then - WAF=../../buildtools/bin/waf -elif [ -f $PREVPATH/buildtools/bin/waf ]; then - WAF=./buildtools/bin/waf -else - echo "replace: Unable to find waf" - exit 1 -fi - -# using JOBS=1 gives maximum compatibility with -# systems like AIX which have broken threading in python -JOBS=1 -export JOBS - -cd . || exit 1 -$PYTHON $WAF configure "$@" || exit 1 -cd $PREVPATH diff --git a/ldb-2.0.8/lib/talloc/doc/context.png b/ldb-2.0.8/lib/talloc/doc/context.png deleted file mode 100644 index 48a6ca0e6a0ecce971f1867a960681a3b157cc3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4715 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 diff --git a/ldb-2.0.8/lib/talloc/doc/mainpage.dox b/ldb-2.0.8/lib/talloc/doc/mainpage.dox deleted file mode 100644 index ece6ccb..0000000 --- a/ldb-2.0.8/lib/talloc/doc/mainpage.dox +++ /dev/null @@ -1,111 +0,0 @@ -/** - * @mainpage - * - * talloc is a hierarchical, reference counted memory pool system with - * destructors. It is the core memory allocator used in Samba. - * - * @section talloc_download Download - * - * You can download the latest releases of talloc from the - * talloc directory - * on the samba public source archive. - * - * @section main-tutorial Tutorial - * - * You should start by reading @subpage libtalloc_tutorial, then reading the documentation of - * the interesting functions as you go. - - * @section talloc_bugs Discussion and bug reports - * - * talloc does not currently have its own mailing list or bug tracking system. - * For now, please use the - * samba-technical - * mailing list, and the - * Samba bugzilla - * bug tracking system. - * - * @section talloc_devel Development - * You can download the latest code either via git or rsync. - * - * To fetch via git see the following guide: - * - * Using Git for Samba Development - * - * Once you have cloned the tree switch to the master branch and cd into the - * lib/tevent directory. - * - * To fetch via rsync use this command: - * - * rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/talloc . - * - * @section talloc_preample Preamble - * - * talloc is a hierarchical, reference counted memory pool system with - * destructors. - * - * Perhaps the biggest difference from other memory pool systems is that there - * is no distinction between a "talloc context" and a "talloc pointer". Any - * pointer returned from talloc() is itself a valid talloc context. This means - * you can do this: - * - * @code - * struct foo *X = talloc(mem_ctx, struct foo); - * X->name = talloc_strdup(X, "foo"); - * @endcode - * - * The pointer X->name would be a "child" of the talloc context "X" which is - * itself a child of mem_ctx. So if you do talloc_free(mem_ctx) then it is all - * destroyed, whereas if you do talloc_free(X) then just X and X->name are - * destroyed, and if you do talloc_free(X->name) then just the name element of - * X is destroyed. - * - * If you think about this, then what this effectively gives you is an n-ary - * tree, where you can free any part of the tree with talloc_free(). - * - * If you find this confusing, then run the testsuite to watch talloc in - * action. You may also like to add your own tests to testsuite.c to clarify - * how some particular situation is handled. - * - * @section talloc_performance Performance - * - * All the additional features of talloc() over malloc() do come at a price. We - * have a simple performance test in Samba4 that measures talloc() versus - * malloc() performance, and it seems that talloc() is about 4% slower than - * malloc() on my x86 Debian Linux box. For Samba, the great reduction in code - * complexity that we get by using talloc makes this worthwhile, especially as - * the total overhead of talloc/malloc in Samba is already quite small. - * - * @section talloc_named Named blocks - * - * Every talloc chunk has a name that can be used as a dynamic type-checking - * system. If for some reason like a callback function you had to cast a - * "struct foo *" to a "void *" variable, later you can safely reassign the - * "void *" pointer to a "struct foo *" by using the talloc_get_type() or - * talloc_get_type_abort() macros. - * - * @code - * struct foo *X = talloc_get_type_abort(ptr, struct foo); - * @endcode - * - * This will abort if "ptr" does not contain a pointer that has been created - * with talloc(mem_ctx, struct foo). - * - * @section talloc_threading Multi-threading - * - * talloc itself does not deal with threads. It is thread-safe (assuming the - * underlying "malloc" is), as long as each thread uses different memory - * contexts. - * - * If two threads uses the same context then they need to synchronize in order - * to be safe. In particular: - * - * - when using talloc_enable_leak_report(), giving directly NULL as a parent - * context implicitly refers to a hidden "null context" global variable, so - * this should not be used in a multi-threaded environment without proper - * synchronization. In threaded code turn off null tracking using - * talloc_disable_null_tracking(). - * - the context returned by talloc_autofree_context() is also global so - * shouldn't be used by several threads simultaneously without - * synchronization. - * - */ diff --git a/ldb-2.0.8/lib/talloc/doc/stealing.png b/ldb-2.0.8/lib/talloc/doc/stealing.png deleted file mode 100644 index 8833e06a187709fe650ed436e8da8c02eaa68134..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6994 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 OgOHU}lqeB14*nm1k&3YZ diff --git a/ldb-2.0.8/lib/talloc/doc/tutorial_bestpractices.dox b/ldb-2.0.8/lib/talloc/doc/tutorial_bestpractices.dox deleted file mode 100644 index 3634446..0000000 --- a/ldb-2.0.8/lib/talloc/doc/tutorial_bestpractices.dox +++ /dev/null @@ -1,192 +0,0 @@ -/** -@page libtalloc_bestpractices Chapter 7: Best practises - -The following sections contain several best practices and good manners that were -found by the Samba and -SSSD developers over the years. -These will help you to write code which is better, easier to debug and with as -few (hopefully none) memory leaks as possible. - -@section bp-hierarchy Keep the context hierarchy steady - -The talloc is a hierarchy memory allocator. The hierarchy nature is what makes -the programming more error proof. It makes the memory easier to manage and to -free. Therefore, the first thing we should have on our mind is: always project -your data structures into the talloc context hierarchy. - -That means if we have a structure, we should always use it as a parent context -for its elements. This way we will not encounter any troubles when freeing the -structure or when changing its parent. The same rule applies for arrays. - -For example, the structure user from section @ref context-hierarchy -should be created with the context hierarchy illustrated on the next image. - -@image html context_tree.png - -@section bp-tmpctx Every function should use its own context - -It is a good practice to create a temporary talloc context at the function -beginning and free the context just before the return statement. All the data -must be allocated on this context or on its children. This ensures that no -memory leaks are created as long as we do not forget to free the temporary -context. - -This pattern applies to both situations - when a function does not return any -dynamically allocated value and when it does. However, it needs a little -extension for the latter case. - -@subsection bp-tmpctx-1 Functions that do not return any dynamically allocated -value - -If the function does not return any value created on the heap, we will just obey -the aforementioned pattern. - -@code -int bar() -{ - int ret; - TALLOC_CTX *tmp_ctx = talloc_new(NULL); - if (tmp_ctx == NULL) { - ret = ENOMEM; - goto done; - } - /* allocate data on tmp_ctx or on its descendants */ - ret = EOK; -done: - talloc_free(tmp_ctx); - return ret; -} -@endcode - -@subsection bp-tmpctx-2 Functions returning dynamically allocated values - -If our function returns any dynamically allocated data, its first parameter -should always be the destination talloc context. This context serves as a parent -for the output values. But again, we will create the output values as the -descendants of the temporary context. If everything goes well, we will change -the parent of the output values from the temporary to the destination talloc -context. - -This pattern ensures that if an error occurs (e.g. I/O error or insufficient -amount of the memory), all allocated data is freed and no garbage appears on -the destination context. - -@code -int struct_foo_init(TALLOC_CTX *mem_ctx, struct foo **_foo) -{ - int ret; - struct foo *foo = NULL; - TALLOC_CTX *tmp_ctx = talloc_new(NULL); - if (tmp_ctx == NULL) { - ret = ENOMEM; - goto done; - } - foo = talloc_zero(tmp_ctx, struct foo); - /* ... */ - *_foo = talloc_steal(mem_ctx, foo); - ret = EOK; -done: - talloc_free(tmp_ctx); - return ret; -} -@endcode - -@section bp-null Allocate temporary contexts on NULL - -As it can be seen on the previous listing, instead of allocating the temporary -context directly on mem_ctx, we created a new top level context -using NULL as the parameter for talloc_new() function. -Take a look at the following example: - -@code -char *create_user_filter(TALLOC_CTX *mem_ctx, - uid_t uid, const char *username) -{ - char *filter = NULL; - char *sanitized_username = NULL; - /* tmp_ctx is a child of mem_ctx */ - TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); - if (tmp_ctx == NULL) { - return NULL; - } - - sanitized_username = sanitize_string(tmp_ctx, username); - if (sanitized_username == NULL) { - talloc_free(tmp_ctx); - return NULL; - } - - filter = talloc_aprintf(tmp_ctx,"(|(uid=%llu)(uname=%s))", - uid, sanitized_username); - if (filter == NULL) { - return NULL; /* tmp_ctx is not freed */ (*@\label{lst:tmp-ctx-3:leak}@*) - } - - /* filter becomes a child of mem_ctx */ - filter = talloc_steal(mem_ctx, filter); - talloc_free(tmp_ctx); - return filter; -} -@endcode - -We forgot to free tmp_ctx before the return statement -in the filter == NULL condition. However, it is created as a child -of mem_ctx context and as such it will be freed as soon as the -mem_ctx is freed. Therefore, no detectable memory leak is created. - -On the other hand, we do not have any way to access the allocated data -and for all we know mem_ctx may exist for the lifetime of our -application. For these reasons this should be considered as a memory leak. How -can we detect if it is unreferenced but still attached to its parent context? -The only way is to notice the mistake in the source code. - -But if we create the temporary context as a top level context, it will not be -freed and memory diagnostic tools -(e.g. valgrind) are able to do their job. - -@section bp-pool Temporary contexts and the talloc pool - -If we want to take the advantage of the talloc pool but also keep to the -pattern introduced in the previous section, we are unable to do it directly. The -best thing to do is to create a conditional build where we can decide how do we -want to create the temporary context. For example, we can create the following -macros: - -@code -#ifdef USE_POOL_CONTEXT - #define CREATE_POOL_CTX(ctx, size) talloc_pool(ctx, size) - #define CREATE_TMP_CTX(ctx) talloc_new(ctx) -#else - #define CREATE_POOL_CTX(ctx, size) talloc_new(ctx) - #define CREATE_TMP_CTX(ctx) talloc_new(NULL) -#endif -@endcode - -Now if our application is under development, we will build it with macro -USE_POOL_CONTEXT undefined. This way, we can use memory diagnostic -utilities to detect memory leaks. - -The release version will be compiled with the macro defined. This will enable -pool contexts and therefore reduce the malloc() calls, which will -end up in a little bit faster processing. - -@code -int struct_foo_init(TALLOC_CTX *mem_ctx, struct foo **_foo) -{ - int ret; - struct foo *foo = NULL; - TALLOC_CTX *tmp_ctx = CREATE_TMP_CTX(mem_ctx); - /* ... */ -} - -errno_t handle_request(TALLOC_CTX mem_ctx) -{ - int ret; - struct foo *foo = NULL; - TALLOC_CTX *pool_ctx = CREATE_POOL_CTX(NULL, 1024); - ret = struct_foo_init(mem_ctx, &foo); - /* ... */ -} -@endcode - -*/ diff --git a/ldb-2.0.8/lib/talloc/doc/tutorial_context.dox b/ldb-2.0.8/lib/talloc/doc/tutorial_context.dox deleted file mode 100644 index b8bfe26..0000000 --- a/ldb-2.0.8/lib/talloc/doc/tutorial_context.dox +++ /dev/null @@ -1,198 +0,0 @@ -/** -@page libtalloc_context Chapter 1: Talloc context -@section context Talloc context - -The talloc context is the most important part of this library and is -responsible for every single feature of this memory allocator. It is a logical -unit which represents a memory space managed by talloc. - -From the programmer's point of view, the talloc context is completely -equivalent to a pointer that would be returned by the memory routines from the -C standard library. This means that every context that is returned from the -talloc library can be used directly in functions that do not use talloc -internally. For example we can do the following: - -@code -char *str1 = strdup("I am NOT a talloc context"); -char *str2 = talloc_strdup(NULL, "I AM a talloc context"); - -printf("%d\n", strcmp(str1, str2) == 0); - -free(str1); -talloc_free(str2); /* we can not use free() on str2 */ -@endcode - -This is possible because the context is internally handled as a special -fixed-length structure called talloc chunk. Each chunk stores context metadata -followed by the memory space requested by the programmer. When a talloc -function returns a context (pointer), it will in fact return a pointer to the user -space portion of the talloc chunk. If we to manipulate this context using -talloc functions, the talloc library transforms the user-space pointer back to -the starting address of the chunk. This is also the reason why we were unable -to use free(str2) in the previous example - because -str2 does not point at the beginning of the allocated block of -memory. This is illustrated on the next image: - -@image html context.png - -The type TALLOC_CTX is defined in talloc.h to identify a talloc context in -function parameters. However, this type is just an alias for void -and exists only for semantical reasons - thus we can differentiate between -void * (arbitrary data) and TALLOC_CTX * (talloc -context). - -@subsection metadata Context meta data - -Every talloc context carries several pieces of internal information along with -the allocated memory: - - - name - which is used in reports of context hierarchy and to simulate - a dynamic type system, - - size of the requested memory in bytes - this can be used to determine - the number of elements in arrays, - - attached destructor - which is executed just before the memory block is - about to be freed, - - references to the context - - children and parent contexts - create the hierarchical view on the - memory. - -@section context-hierarchy Hierarchy of talloc context - -Every talloc context contains information about its parent and children. Talloc -uses this information to create a hierarchical model of memory or to be more -precise, it creates an n-ary tree where each node represents a single talloc -context. The root node of the tree is referred to as a top level context - a -context without any parent. - -This approach has several advantages: - - - as a consequence of freeing a talloc context, all of its children - will be properly deallocated as well, - - the parent of a context can be changed at any time, which - results in moving the whole subtree under another node, - - it creates a more natural way of managing data structures. - -@subsection Example - -We have a structure that stores basic information about a user - his/her name, -identification number and groups he/she is a member of: - -@code -struct user { - uid_t uid; - char *username; - size_t num_groups; - char **groups; -}; -@endcode - -We will allocate this structure using talloc. The result will be the following -context tree: - -@image html context_tree.png - -@code -/* create new top level context */ -struct user *user = talloc(NULL, struct user); - -user->uid = 1000; -user->num_groups = N; - -/* make user the parent of following contexts */ -user->username = talloc_strdup(user, "Test user"); -user->groups = talloc_array(user, char*, user->num_groups); - -for (i = 0; i < user->num_groups; i++) { - /* make user->groups the parent of following context */ - user->groups[i] = talloc_asprintf(user->groups, - "Test group %d", i); -} -@endcode - -This way, we have gained a lot of additional capabilities, one of which is -very simple deallocation of the structure and all of its elements. - -With the C standard library we need first to iterate over the array of groups -and free every element separately. Then we must deallocate the array that stores -them. Next we deallocate the username and as the last step free the structure -itself. But with talloc, the only operation we need to execute is freeing the -structure context. Its descendants will be freed automatically. - -@code -talloc_free(user); -@endcode - -@section keep-hierarchy Always keep the hieararchy steady! - -The talloc is a hierarchy memory allocator. The hierarchy nature is what makes -the programming more error proof. It makes the memory easier to manage and to -free. Therefore, the first thing we should have on our mind is: always -project our data structures into the talloc context hierarchy. - -That means if we have a structure, we should always use it as a parent context -for its elements. This way we will not encounter any troubles when freeing this -structure or when changing its parent. The same rule applies for arrays. - -@section creating-context Creating a talloc context - -Here are the most important functions that create a new talloc context. - -@subsection type-safe Type-safe functions - -It allocates the size that is necessary for the given type and returns a new, -properly-casted pointer. This is the preferred way to create a new context as -we can rely on the compiler to detect type mismatches. - -The name of the context is automatically set to the name of the data type which -is used to simulate a dynamic type system. - -@code -struct user *user = talloc(ctx, struct user); - -/* initialize to default values */ -user->uid = 0; -user->name = NULL; -user->num_groups = 0; -user->groups = NULL; - -/* or we can achieve the same result with */ -struct user *user_zero = talloc_zero(ctx, struct user); -@endcode - -@subsection zero-length Zero-length contexts - -The zero-length context is basically a context without any special semantical -meaning. We can use it the same way as any other context. The only difference -is that it consists only of the meta data about the context. Therefore, it is -strictly of type TALLOC_CTX*. It is often used in cases where we -want to aggregate several data structures under one parent (zero-length) -context, such as a temporary context to contain memory needed within a single -function that is not interesting to the caller. Allocating on a zero-length -temporary context will make clean-up of the function simpler. - -@code -TALLOC_CTX *tmp_ctx = NULL; -struct foo *foo = NULL; -struct bar *bar = NULL; - -/* new zero-length top level context */ -tmp_ctx = talloc_new(NULL); -if (tmp_ctx == NULL) { - return ENOMEM; -} - -foo = talloc(tmp_ctx, struct foo); -bar = talloc(tmp_ctx, struct bar); - -/* free everything at once */ -talloc_free(tmp_ctx); -@endcode - -@subsection context-see-also See also - -- talloc_size() -- talloc_named() -- @ref talloc_array -- @ref talloc_string - -*/ diff --git a/ldb-2.0.8/lib/talloc/doc/tutorial_debugging.dox b/ldb-2.0.8/lib/talloc/doc/tutorial_debugging.dox deleted file mode 100644 index aadbb0d..0000000 --- a/ldb-2.0.8/lib/talloc/doc/tutorial_debugging.dox +++ /dev/null @@ -1,116 +0,0 @@ -/** -@page libtalloc_debugging Chapter 6: Debugging - -Although talloc makes memory management significantly easier than the C standard -library, developers are still only humans and can make mistakes. Therefore, it -can be handy to know some tools for the inspection of talloc memory usage. - -@section log-abort Talloc log and abort - -We have already encountered the abort function in section @ref dts. -In that case it was used when a type mismatch was detected. However, talloc -calls this abort function in several more situations: - -- when the provided pointer is not a valid talloc context, -- when the meta data is invalid - probably due to memory corruption, -- and when an access after free is detected. - -The third one is probably the most interesting. It can help us with detecting -an attempt to double-free a context or any other manipulation with it via -talloc functions (using it as a parent, stealing it, etc.). - -Before the context is freed talloc sets a flag in the meta data. This is then -used to detect the access after free. It basically works on the assumption that -the memory stays unchanged (at least for a while) even when it is properly -deallocated. This will work even if the memory is filled with the value -specified in TALLOC_FREE_FILL environment variable, because it -fills only the data part and leaves the meta data intact. - -Apart from the abort function, talloc uses a log function to provide additional -information to the aforementioned violations. To enable logging we shall set the -log function with one of: - -- talloc_set_log_fn() -- talloc_set_log_stderr() - -The following code is a sample output of accessing a context after it has been -freed: - -@code -talloc_set_log_stderr(); -TALLOC_CTX *ctx = talloc_new(NULL); - -talloc_free(ctx); -talloc_free(ctx); - -results in: -talloc: access after free error - first free may be at ../src/main.c:55 -Bad talloc magic value - access after free -@endcode - -Another example is an invalid context: - -@code -talloc_set_log_stderr(); -TALLOC_CTX *ctx = talloc_new(NULL); -char *str = strdup("not a talloc context"); -talloc_steal(ctx, str); - -results in: -Bad talloc magic value - unknown value -@endcode - -@section reports Memory usage reports - -Talloc can print reports of memory usage of a specified talloc context to a -file (to stdout or stderr). The report can be -simple or full. The simple report provides information only about the context -itself and its direct descendants. The full report goes recursively through the -entire context tree. See: - -- talloc_report() -- talloc_report_full() - -We will use the following code to retrieve the sample report: - -@code -struct foo { - char *str; -}; - -TALLOC_CTX *ctx = talloc_new(NULL); -char *str = talloc_strdup(ctx, "my string"); -struct foo *foo = talloc_zero(ctx, struct foo); -foo->str = talloc_strdup(foo, "I am Foo"); -char *str2 = talloc_strdup(foo, "Foo is my parent"); - -/* print full report */ -talloc_report_full(ctx, stdout); -@endcode - -It will print a full report of ctx to the standard output. -The message should be similar to: - -@code -full talloc report on 'talloc_new: ../src/main.c:82' (total 46 bytes in 5 blocks) - struct foo contains 34 bytes in 3 blocks (ref 0) 0x1495130 - Foo is my parent contains 17 bytes in 1 blocks (ref 0) 0x1495200 - I am Foo contains 9 bytes in 1 blocks (ref 0) 0x1495190 - my string contains 10 bytes in 1 blocks (ref 0) 0x14950c0 -@endcode - -We can notice in this report that something is wrong with the context containing -struct foo. We know that the structure has only one string element. -However, we can see in the report that it has two children. This indicates that -we have either violated the memory hierarchy or forgotten to free it as -temporary data. Looking into the code, we can see that "Foo is my parent" - should be attached to ctx. - -See also: - -- talloc_enable_null_tracking() -- talloc_disable_null_tracking() -- talloc_enable_leak_report() -- talloc_enable_leak_report_full() - -*/ diff --git a/ldb-2.0.8/lib/talloc/doc/tutorial_destructors.dox b/ldb-2.0.8/lib/talloc/doc/tutorial_destructors.dox deleted file mode 100644 index ed06387..0000000 --- a/ldb-2.0.8/lib/talloc/doc/tutorial_destructors.dox +++ /dev/null @@ -1,82 +0,0 @@ -/** -@page libtalloc_destructors Chapter 4: Using destructors - -@section destructors Using destructors - -Destructors are well known methods in the world of object oriented programming. -A destructor is a method of an object that is automatically run when the object -is destroyed. It is usually used to return resources taken by the object back to -the system (e.g. closing file descriptors, terminating connection to a database, -deallocating memory). - -With talloc we can take the advantage of destructors even in C. We can easily -attach our own destructor to a talloc context. When the context is freed, the -destructor will run automatically. - -To attach/detach a destructor to a talloc context use: talloc_set_destructor(). - -@section destructors-example Example - -Imagine that we have a dynamically created linked list. Before we deallocate an -element of the list, we need to make sure that we have successfully removed it -from the list. Normally, this would be done by two commands in the exact order: -remove it from the list and then free the element. With talloc, we can do this -at once by setting a destructor on the element which will remove it from the -list and talloc_free() will do the rest. - -The destructor would be: - -@code -int list_remove(void *ctx) -{ - struct list_el *el = NULL; - el = talloc_get_type_abort(ctx, struct list_el); - /* remove element from the list */ -} -@endcode - -GCC version 3 and newer can check for the types during the compilation. So if -it is our major compiler, we can use a more advanced destructor: - -@code -int list_remove(struct list_el *el) -{ - /* remove element from the list */ -} -@endcode - -Now we will assign the destructor to the list element. We can do this directly -in the function that inserts it. - -@code -struct list_el* list_insert(TALLOC_CTX *mem_ctx, - struct list_el *where, - void *ptr) -{ - struct list_el *el = talloc(mem_ctx, struct list_el); - el->data = ptr; - /* insert into list */ - - talloc_set_destructor(el, list_remove); - return el; -} -@endcode - -Because talloc is a hierarchical memory allocator, we can go a step further and -free the data with the element as well: - -@code -struct list_el* list_insert_free(TALLOC_CTX *mem_ctx, - struct list_el *where, - void *ptr) -{ - struct list_el *el = NULL; - el = list_insert(mem_ctx, where, ptr); - - talloc_steal(el, ptr); - - return el; -} -@endcode - -*/ diff --git a/ldb-2.0.8/lib/talloc/doc/tutorial_dts.dox b/ldb-2.0.8/lib/talloc/doc/tutorial_dts.dox deleted file mode 100644 index 75b5172..0000000 --- a/ldb-2.0.8/lib/talloc/doc/tutorial_dts.dox +++ /dev/null @@ -1,109 +0,0 @@ -/** -@page libtalloc_dts Chapter 3: Dynamic type system - -@section dts Dynamic type system - -Generic programming in the C language is very difficult. There is no inheritance -nor templates known from object oriented languages. There is no dynamic type -system. Therefore, generic programming in this language is usually done by -type-casting a variable to void* and transferring it through -a generic function to a specialized callback as illustrated on the next listing. - -@code -void generic_function(callback_fn cb, void *pvt) -{ - /* do some stuff and call the callback */ - cb(pvt); -} - -void specific_callback(void *pvt) -{ - struct specific_struct *data; - data = (struct specific_struct*)pvt; - /* ... */ -} - -void specific_function() -{ - struct specific_struct data; - generic_function(callback, &data); -} -@endcode - -Unfortunately, the type information is lost as a result of this type cast. The -compiler cannot check the type during the compilation nor are we able to do it -at runtime. Providing an invalid data type to the callback will result in -unexpected behaviour (not necessarily a crash) of the application. This mistake -is usually hard to detect because it is not the first thing which comes the -mind. - -As we already know, every talloc context contains a name. This name is available -at any time and it can be used to determine the type of a context even if we -lose the type of a variable. - -Although the name of the context can be set to any arbitrary string, the best -way of using it to simulate the dynamic type system is to set it directly to the -type of the variable. - -It is recommended to use one of talloc() and talloc_array() (or its -variants) to create the context as they set its name to the name of the -given type automatically. - -If we have a context with such as a name, we can use two similar functions that -do both the type check and the type cast for us: - -- talloc_get_type() -- talloc_get_type_abort() - -@section dts-examples Examples - -The following example will show how generic programming with talloc is handled - -if we provide invalid data to the callback, the program will be aborted. This -is a sufficient reaction for such an error in most applications. - -@code -void foo_callback(void *pvt) -{ - struct foo *data = talloc_get_type_abort(pvt, struct foo); - /* ... */ -} - -int do_foo() -{ - struct foo *data = talloc_zero(NULL, struct foo); - /* ... */ - return generic_function(foo_callback, data); -} -@endcode - -But what if we are creating a service application that should be running for the -uptime of a server, we may want to abort the application during the development -process (to make sure the error is not overlooked) and try to recover from the -error in the customer release. This can be achieved by creating a custom abort -function with a conditional build. - -@code -void my_abort(const char *reason) -{ - fprintf(stderr, "talloc abort: %s\n", reason); -#ifdef ABORT_ON_TYPE_MISMATCH - abort(); -#endif -} -@endcode - -The usage of talloc_get_type_abort() would be then: - -@code -talloc_set_abort_fn(my_abort); - -TALLOC_CTX *ctx = talloc_new(NULL); -char *str = talloc_get_type_abort(ctx, char); -if (str == NULL) { - /* recovery code */ -} -/* talloc abort: ../src/main.c:25: Type mismatch: - name[talloc_new: ../src/main.c:24] expected[char] */ -@endcode - -*/ diff --git a/ldb-2.0.8/lib/talloc/doc/tutorial_introduction.dox b/ldb-2.0.8/lib/talloc/doc/tutorial_introduction.dox deleted file mode 100644 index 418c38b..0000000 --- a/ldb-2.0.8/lib/talloc/doc/tutorial_introduction.dox +++ /dev/null @@ -1,45 +0,0 @@ -/** -@page libtalloc_tutorial The Tutorial -@section introduction Introduction - -Talloc is a hierarchical, reference counted memory pool system with destructors. -It is built atop the C standard library and it defines a set of utility -functions that altogether simplifies allocation and deallocation of data, -especially for complex structures that contain many dynamically allocated -elements such as strings and arrays. - -The main goals of this library are: removing the needs for creating a cleanup -function for every complex structure, providing a logical organization of -allocated memory blocks and reducing the likelihood of creating memory leaks in -long-running applications. All of this is achieved by allocating memory in a -hierarchical structure of talloc contexts such that deallocating one context -recursively frees all of its descendants as well. - -@section main-features Main features -- An open source project -- A hierarchical memory model -- Natural projection of data structures into the memory space -- Simplifies memory management of large data structures -- Automatic execution of a destructor before the memory is freed -- Simulates a dynamic type system -- Implements a transparent memory pool - -@section toc Table of contents: - -@subpage libtalloc_context - -@subpage libtalloc_stealing - -@subpage libtalloc_dts - -@subpage libtalloc_destructors - -@subpage libtalloc_pools - -@subpage libtalloc_debugging - -@subpage libtalloc_bestpractices - -@subpage libtalloc_threads - -*/ diff --git a/ldb-2.0.8/lib/talloc/doc/tutorial_pools.dox b/ldb-2.0.8/lib/talloc/doc/tutorial_pools.dox deleted file mode 100644 index a0d1e1a..0000000 --- a/ldb-2.0.8/lib/talloc/doc/tutorial_pools.dox +++ /dev/null @@ -1,93 +0,0 @@ -/** -@page libtalloc_pools Chapter 5: Memory pools - -@section pools Memory pools - -Allocation of a new memory is an expensive operation and large programs can -contain thousands of calls of malloc() for a single computation, where every -call allocates only a very small amount of the memory. This can result in an -undesirable slowdown of the application. We can avoid this slowdown by -decreasing the number of malloc() calls by using a memory pool. - -A memory pool is a preallocated memory space with a fixed size. If we need to -allocate new data we will take the desired amount of the memory from the pool -instead of requesting a new memory from the system. This is done by creating a -pointer that points inside the preallocated memory. Such a pool must not be -reallocated as it would change its location - pointers that were pointing -inside the pool would become invalid. Therefore, a memory pool requires a very -good estimate of the required memory space. - -The talloc library contains its own implementation of a memory pool. It is -highly transparent for the programmer. The only thing that needs to be done is -an initialization of a new pool context using talloc_pool() - -which can be used in the same way as any other context. - -Refactoring of existing code (that uses talloc) to take the advantage of a -memory pool is quite simple due to the following properties of the pool context: - -- if we are allocating data on a pool context, it takes the desired - amount of memory from the pool, -- if the context is a descendant of the pool context, it takes the space - from the pool as well, -- if the pool does not have sufficient portion of memory left, it will - create a new non-pool context, leaving the pool intact - -@code -/* allocate 1KiB in a pool */ -TALLOC_CTX *pool_ctx = talloc_pool(NULL, 1024); - -/* Take 512B from the pool, 512B is left there */ -void *ptr = talloc_size(pool_ctx, 512); - -/* 1024B > 512B, this will create new talloc chunk outside - the pool */ -void *ptr2 = talloc_size(ptr, 1024); - -/* The pool still contains 512 free bytes - * this will take 200B from them. */ -void *ptr3 = talloc_size(ptr, 200); - -/* This will destroy context 'ptr3' but the memory - * is not freed, the available space in the pool - * will increase to 512B. */ -talloc_free(ptr3); - -/* This will free memory taken by 'pool_ctx' - * and 'ptr2' as well. */ -talloc_free(pool_ctx); -@endcode - -The above given is very convenient, but there is one big issue to be kept in -mind. If the parent of a talloc pool child is changed to a parent that is -outside of this pool, the whole pool memory will not be freed until the child is -freed. For this reason we must be very careful when stealing a descendant of a -pool context. - -@code -TALLOC_CTX *mem_ctx = talloc_new(NULL); -TALLOC_CTX *pool_ctx = talloc_pool(NULL, 1024); -struct foo *foo = talloc(pool_ctx, struct foo); - -/* mem_ctx is not in the pool */ -talloc_steal(mem_ctx, foo); - -/* pool_ctx is marked as freed but the memory is not - deallocated, accessing the pool_ctx again will cause - an error */ -talloc_free(pool_ctx); - -/* This deallocates the pool_ctx. */ -talloc_free(mem_ctx); -@endcode - -It may often be better to copy the memory we want instead of stealing it to -avoid this problem. If we do not need to retain the context name (to keep the -type information), we can use talloc_memdup() to do this. - -Copying the memory out of the pool may, however, discard all the performance -boost given by the pool, depending on the size of the copied memory. Therefore, -the code should be well profiled before taking this path. In general, the -golden rule is: if we need to steal from the pool context, we should not -use a pool context. - -*/ diff --git a/ldb-2.0.8/lib/talloc/doc/tutorial_stealing.dox b/ldb-2.0.8/lib/talloc/doc/tutorial_stealing.dox deleted file mode 100644 index 67eae1d..0000000 --- a/ldb-2.0.8/lib/talloc/doc/tutorial_stealing.dox +++ /dev/null @@ -1,55 +0,0 @@ -/** -@page libtalloc_stealing Chapter 2: Stealing a context - -@section stealing Stealing a context - -Talloc has the ability to change the parent of a talloc context to another -one. This operation is commonly referred to as stealing and it is one of -the most important actions performed with talloc contexts. - -Stealing a context is necessary if we want the pointer to outlive the context it -is created on. This has many possible use cases, for instance stealing a result -of a database search to an in-memory cache context, changing the parent of a -field of a generic structure to a more specific one or vice-versa. The most -common scenario, at least in Samba, is to steal output data from a function-specific -context to the output context given as an argument of that function. - -@code -struct foo { - char *a1; - char *a2; - char *a3; -}; - -struct bar { - char *wurst; - struct foo *foo; -}; - -struct foo *foo = talloc_zero(ctx, struct foo); -foo->a1 = talloc_strdup(foo, "a1"); -foo->a2 = talloc_strdup(foo, "a2"); -foo->a3 = talloc_strdup(foo, "a3"); - -struct bar *bar = talloc_zero(NULL, struct bar); -/* change parent of foo from ctx to bar */ -bar->foo = talloc_steal(bar, foo); - -/* or do the same but assign foo = NULL */ -bar->foo = talloc_move(bar, &foo); -@endcode - -The talloc_move() function is similar to the talloc_steal() function but -additionally sets the source pointer to NULL. - -In general, the source pointer itself is not changed (it only replaces the -parent in the meta data). But the common usage is that the result is -assigned to another variable, thus further accessing the pointer from the -original variable should be avoided unless it is necessary. In this case -talloc_move() is the preferred way of stealing a context. Additionally sets the -source pointer to NULL, thus.protects the pointer from being accidentally freed -and accessed using the old variable after its parent has been changed. - -@image html stealing.png - -*/ diff --git a/ldb-2.0.8/lib/talloc/doc/tutorial_threads.dox b/ldb-2.0.8/lib/talloc/doc/tutorial_threads.dox deleted file mode 100644 index 111bbf5..0000000 --- a/ldb-2.0.8/lib/talloc/doc/tutorial_threads.dox +++ /dev/null @@ -1,203 +0,0 @@ -/** -@page libtalloc_threads Chapter 8: Using threads with talloc - -@section Talloc and thread safety - -The talloc library is not internally thread-safe, in that accesses -to variables on a talloc context are not controlled by mutexes or -other thread-safe primitives. - -However, so long as talloc_disable_null_tracking() is called from -the main thread to disable global variable access within talloc, -then each thread can safely use its own top level talloc context -allocated off the NULL context. - -For example: - -@code -static void *thread_fn(void *arg) -{ - const char *ctx_name = (const char *)arg; - /* - * Create a new top level talloc hierarchy in - * this thread. - */ - void *top_ctx = talloc_named_const(NULL, 0, "top"); - if (top_ctx == NULL) { - return NULL; - } - sub_ctx = talloc_named_const(top_ctx, 100, ctx_name); - if (sub_ctx == NULL) { - return NULL; - } - - /* - * Do more processing/talloc calls on top_ctx - * and its children. - */ - ...... - - talloc_free(top_ctx); - return value; -} -@endcode - -is a perfectly safe use of talloc within a thread. - -The problem comes when one thread wishes to move some -memory allocated on its local top level talloc context -to another thread. Care must be taken to add data access -exclusion to prevent memory corruption. One method would -be to lock a mutex before any talloc call on each thread, -but this would push the burden of total talloc thread-safety -on the poor user of the library. - -A much easier way to transfer talloced memory between -threads is by the use of an intermediate, mutex locked, -intermediate variable. - -An example of this is below - taken from test code inside -the talloc testsuite. - -The main thread creates 1000 sub-threads, and then accepts -the transfer of some thread-talloc'ed memory onto its top -level context from each thread in turn. - -A pthread mutex and condition variable are used to -synchronize the transfer via the intermediate_ptr -variable. - -@code -/* Required sync variables. */ -static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t condvar = PTHREAD_COND_INITIALIZER; - -/* Intermediate talloc pointer for transfer. */ -static void *intermediate_ptr; - -/* Subthread. */ -static void *thread_fn(void *arg) -{ - int ret; - const char *ctx_name = (const char *)arg; - void *sub_ctx = NULL; - /* - * Do stuff that creates a new talloc hierarchy in - * this thread. - */ - void *top_ctx = talloc_named_const(NULL, 0, "top"); - if (top_ctx == NULL) { - return NULL; - } - sub_ctx = talloc_named_const(top_ctx, 100, ctx_name); - if (sub_ctx == NULL) { - return NULL; - } - - /* - * Now transfer a pointer from our hierarchy - * onto the intermediate ptr. - */ - ret = pthread_mutex_lock(&mtx); - if (ret != 0) { - talloc_free(top_ctx); - return NULL; - } - - /* Wait for intermediate_ptr to be free. */ - while (intermediate_ptr != NULL) { - ret = pthread_cond_wait(&condvar, &mtx); - if (ret != 0) { - talloc_free(top_ctx); - return NULL; - } - } - - /* and move our memory onto it from our toplevel hierarchy. */ - intermediate_ptr = talloc_move(NULL, &sub_ctx); - - /* Tell the main thread it's ready for pickup. */ - pthread_cond_broadcast(&condvar); - pthread_mutex_unlock(&mtx); - - talloc_free(top_ctx); - return NULL; -} - -/* Main thread. */ - -#define NUM_THREADS 1000 - -static bool test_pthread_talloc_passing(void) -{ - int i; - int ret; - char str_array[NUM_THREADS][20]; - pthread_t thread_id; - void *mem_ctx; - - /* - * Important ! Null tracking breaks threaded talloc. - * It *must* be turned off. - */ - talloc_disable_null_tracking(); - - /* Main thread toplevel context. */ - mem_ctx = talloc_named_const(NULL, 0, "toplevel"); - if (mem_ctx == NULL) { - return false; - } - - /* - * Spin off NUM_THREADS threads. - * They will use their own toplevel contexts. - */ - for (i = 0; i < NUM_THREADS; i++) { - (void)snprintf(str_array[i], - 20, - "thread:%d", - i); - if (str_array[i] == NULL) { - return false; - } - ret = pthread_create(&thread_id, - NULL, - thread_fn, - str_array[i]); - if (ret != 0) { - return false; - } - } - - /* Now wait for NUM_THREADS transfers of the talloc'ed memory. */ - for (i = 0; i < NUM_THREADS; i++) { - ret = pthread_mutex_lock(&mtx); - if (ret != 0) { - talloc_free(mem_ctx); - return false; - } - - /* Wait for intermediate_ptr to have our data. */ - while (intermediate_ptr == NULL) { - ret = pthread_cond_wait(&condvar, &mtx); - if (ret != 0) { - talloc_free(mem_ctx); - return false; - } - } - - /* and move it onto our toplevel hierarchy. */ - (void)talloc_move(mem_ctx, &intermediate_ptr); - - /* Tell the sub-threads we're ready for another. */ - pthread_cond_broadcast(&condvar); - pthread_mutex_unlock(&mtx); - } - - /* Dump the hierarchy. */ - talloc_report(mem_ctx, stdout); - talloc_free(mem_ctx); - return true; -} -@endcode -*/ diff --git a/ldb-2.0.8/lib/talloc/doxy.config b/ldb-2.0.8/lib/talloc/doxy.config deleted file mode 100644 index 0e27d61..0000000 --- a/ldb-2.0.8/lib/talloc/doxy.config +++ /dev/null @@ -1,1807 +0,0 @@ -# Doxyfile 1.8.0 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" "). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or sequence of words) that should -# identify the project. Note that if you do not use Doxywizard you need -# to put quotes around the project name if it contains spaces. - -PROJECT_NAME = talloc - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = 2.0 - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer -# a quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = - -# With the PROJECT_LOGO tag one can specify an logo or icon that is -# included in the documentation. The maximum height of the logo should not -# exceed 55 pixels and the maximum width should not exceed 200 pixels. -# Doxygen will copy the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = doc - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful if your file system -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = YES - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding -# "class=itcl::class" will allow you to use the command class in the -# itcl::class meaning. - -TCL_SUBST = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this -# tag. The format is ext=language, where ext is a file extension, and language -# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, -# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions -# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all -# comments according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you -# can mix doxygen, HTML, and XML commands with Markdown formatting. -# Disable only in case of backward compatibilities issues. - -MARKDOWN_SUPPORT = YES - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also makes the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and -# unions are shown inside the group in which they are included (e.g. using -# @ingroup) instead of on a separate page (for HTML and Man pages) or -# section (for LaTeX and RTF). - -INLINE_GROUPED_CLASSES = NO - -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and -# unions with only public data fields will be shown inline in the documentation -# of the scope in which they are defined (i.e. file, namespace, or group -# documentation), provided this scope is documented. If set to NO (the default), -# structs, classes, and unions are shown on a separate page (for HTML and Man -# pages) or section (for LaTeX and RTF). - -INLINE_SIMPLE_STRUCTS = NO - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penalty. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will roughly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols. - -SYMBOL_CACHE_SIZE = 0 - -# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be -# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given -# their name and scope. Since this can be an expensive process and often the -# same symbol appear multiple times in the code, doxygen keeps a cache of -# pre-resolved symbols. If the cache is too small doxygen will become slower. -# If the cache is too large, memory is wasted. The cache size is given by this -# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols. - -LOOKUP_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal scope will be included in the documentation. - -EXTRACT_PACKAGE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = NO - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespaces are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = YES - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = YES - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO -# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to -# do proper type resolution of all parameters of a function it will reject a -# match between the prototype and the implementation of a member function even -# if there is only one candidate or it is obvious which candidate to choose -# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen -# will still accept a match between prototype and implementation in such cases. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or macro consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and macros in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. The create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted -# DoxygenLayout.xml will be used as the name of the layout file. - -LAYOUT_FILE = - -# The CITE_BIB_FILES tag can be used to specify one or more bib files -# containing the references data. This must be a list of .bib files. The -# .bib extension is automatically appended if omitted. Using this command -# requires the bibtex tool to be installed. See also -# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style -# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this -# feature you need bibtex and perl available in the search path. - -CITE_BIB_FILES = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# The WARN_NO_PARAMDOC option can be enabled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = . \ - doc - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh -# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py -# *.f90 *.f *.for *.vhd *.vhdl - -FILE_PATTERNS = *.cpp \ - *.cc \ - *.c \ - *.h \ - *.hh \ - *.hpp \ - *.dox - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = */.git/* - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = doc - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. -# If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. -# Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. -# The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty or if -# non of the patterns match the file name, INPUT_FILTER is applied. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) -# and it is also possible to disable source filtering for a specific pattern -# using *.ext= (so without naming a filter). This option only has effect when -# FILTER_SOURCE_FILES is enabled. - -FILTER_SOURCE_PATTERNS = - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. -# Otherwise they will link to the documentation. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. Note that when using a custom header you are responsible -# for the proper inclusion of any scripts and style sheets that doxygen -# needs, which is dependent on the configuration options used. -# It is advised to generate a default header using "doxygen -w html -# header.html footer.html stylesheet.css YourConfigFile" and then modify -# that header. Note that the header is subject to change so you typically -# have to redo this when upgrading to a newer version of doxygen or when -# changing the value of configuration settings such as GENERATE_TREEVIEW! - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# style sheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that -# the files will be copied as-is; there are no commands or markers available. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the style sheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. -# The allowed range is 0 to 359. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use -# grayscales only. A value of 255 will produce the most vivid colors. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, -# and 100 does not change the gamma. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. - -HTML_TIMESTAMP = NO - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = NO - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# -# Qt Help Project / Custom Filters. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# -# Qt Help Project / Filter Attributes. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) -# at top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. Since the tabs have the same information as the -# navigation tree you can set this option to NO if you already set -# GENERATE_TREEVIEW to YES. - -DISABLE_INDEX = NO - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. -# Since the tree basically has the same information as the tab index you -# could consider to set DISABLE_INDEX to NO when enabling this option. - -GENERATE_TREEVIEW = NONE - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values -# (range [0,1..20]) that doxygen will group on one line in the generated HTML -# documentation. Note that a value of 0 will completely suppress the enum -# values from appearing in the overview section. - -ENUM_VALUES_PER_LINE = 4 - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open -# links to external symbols imported via tag files in a separate window. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files -# in the HTML output before the changes have effect. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax -# (see http://www.mathjax.org) which uses client side Javascript for the -# rendering instead of using prerendered bitmaps. Use this if you do not -# have LaTeX installed or if you want to formulas look prettier in the HTML -# output. When enabled you may also need to install MathJax separately and -# configure the path to it using the MATHJAX_RELPATH option. - -USE_MATHJAX = NO - -# When MathJax is enabled you need to specify the location relative to the -# HTML output directory using the MATHJAX_RELPATH option. The destination -# directory should contain the MathJax.js script. For instance, if the mathjax -# directory is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to -# the MathJax Content Delivery Network so you can quickly see the result without -# installing MathJax. -# However, it is strongly recommended to install a local -# copy of MathJax from http://www.mathjax.org before deployment. - -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest - -# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension -# names that should be enabled during MathJax rendering. - -MATHJAX_EXTENSIONS = - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. - -SEARCHENGINE = NO - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a PHP enabled web server instead of at the web client -# using Javascript. Doxygen will generate the search PHP script and index -# file to put on the web server. The advantage of the server -# based approach is that it scales better to large projects and allows -# full text search. The disadvantages are that it is more difficult to setup -# and does not have live searching capabilities. - -SERVER_BASED_SEARCH = NO - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = YES - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the -# Makefile that is written to the output directory. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for -# the generated latex document. The footer should contain everything after -# the last chapter. If it is left blank doxygen will generate a -# standard footer. Notice: only use this tag if you know what you are doing! - -LATEX_FOOTER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include -# source code with syntax highlighting in the LaTeX output. -# Note that which sources are shown also depends on other settings -# such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = NO - -# The LATEX_BIB_STYLE tag can be used to specify the style to use for the -# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See -# http://en.wikipedia.org/wiki/BibTeX for more info. - -LATEX_BIB_STYLE = plain - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load style sheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = YES - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. -# This is useful -# if you want to understand what is going on. -# On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = YES - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = YES - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# pointed to by INCLUDE_PATH will be searched when a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = DOXYGEN \ - PRINTF_ATTRIBUTE(x,y)= - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition that -# overrules the definition found in the source code. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all references to function-like macros -# that are alone on a line, have an all uppercase name, and do not end with a -# semicolon, because these will confuse the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. For each -# tag file the location of the external documentation should be added. The -# format of a tag file without this location is as follows: -# -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths -# or URLs. Note that each tag file must have a unique name (where the name does -# NOT include the path). If a tag file is not located in the directory in which -# doxygen is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option also works with HAVE_DOT disabled, but it is recommended to -# install and use dot, since it yields more powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is -# allowed to run in parallel. When set to 0 (the default) doxygen will -# base this on the number of processors available in the system. You can set it -# explicitly to a value larger than 0 to get control over the balance -# between CPU load and processing speed. - -DOT_NUM_THREADS = 0 - -# By default doxygen will use the Helvetica font for all dot files that -# doxygen generates. When you want a differently looking font you can specify -# the font name using DOT_FONTNAME. You need to make sure dot is able to find -# the font, which can be done by putting it in a standard location or by setting -# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the -# directory containing the font. - -DOT_FONTNAME = FreeSans - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the Helvetica font. -# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to -# set the path where dot can find it. - -DOT_FONTPATH = - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If the UML_LOOK tag is enabled, the fields and methods are shown inside -# the class node. If there are many fields or methods and many nodes the -# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS -# threshold limits the number of items for each type to make the size more -# managable. Set this to 0 for no limit. Note that the threshold may be -# exceeded by 50% before the limit is enforced. - -UML_LIMIT_NUM_FIELDS = 10 - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will generate a graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are svg, png, jpg, or gif. -# If left blank png will be used. If you choose svg you need to set -# HTML_FILE_EXTENSION to xhtml in order to make the SVG files -# visible in IE 9+ (other browsers do not have this requirement). - -DOT_IMAGE_FORMAT = png - -# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to -# enable generation of interactive SVG images that allow zooming and panning. -# Note that this requires a modern browser other than Internet Explorer. -# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you -# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files -# visible. Older versions of IE do not have SVG support. - -INTERACTIVE_SVG = NO - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the -# \mscfile command). - -MSCFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = YES - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES diff --git a/ldb-2.0.8/lib/talloc/man/talloc.3.xml b/ldb-2.0.8/lib/talloc/man/talloc.3.xml deleted file mode 100644 index c51061f..0000000 --- a/ldb-2.0.8/lib/talloc/man/talloc.3.xml +++ /dev/null @@ -1,814 +0,0 @@ - - - - 2015-04-10 - - talloc - 3 - Samba - System Administration tools - 4.0 - - - talloc -hierarchical reference counted memory pool system with destructors - - -#include <talloc.h> - - DESCRIPTION - - If you are used to talloc from Samba3 then please read this - carefully, as talloc has changed a lot. - - - The new talloc is a hierarchical, reference counted memory pool - system with destructors. Quite a mouthful really, but not too bad - once you get used to it. - - - Perhaps the biggest change from Samba3 is that there is no - distinction between a "talloc context" and a "talloc pointer". Any - pointer returned from talloc() is itself a valid talloc context. - This means you can do this: - - - struct foo *X = talloc(mem_ctx, struct foo); - X->name = talloc_strdup(X, "foo"); - - - and the pointer X->name - would be a "child" of the talloc context X which is itself a child of - mem_ctx. So if you do - talloc_free(mem_ctx) then - it is all destroyed, whereas if you do talloc_free(X) then just X and X->name are destroyed, and if - you do talloc_free(X->name) then just - the name element of X is - destroyed. - - - If you think about this, then what this effectively gives you is an - n-ary tree, where you can free any part of the tree with - talloc_free(). - - - If you find this confusing, then I suggest you run the testsuite program to watch talloc - in action. You may also like to add your own tests to testsuite.c to clarify how some - particular situation is handled. - - - TALLOC API - - The following is a complete guide to the talloc API. Read it all at - least twice. - - (type *)talloc(const void *ctx, type); - - The talloc() macro is the core of the talloc library. It takes a - memory ctx and a type, and returns a pointer to a new - area of memory of the given type. - - - The returned pointer is itself a talloc context, so you can use - it as the ctx argument to more - calls to talloc() if you wish. - - - The returned pointer is a "child" of the supplied context. This - means that if you talloc_free() the ctx then the new child disappears as - well. Alternatively you can free just the child. - - - The ctx argument to talloc() - can be NULL, in which case a new top level context is created. - - - void *talloc_size(const void *ctx, size_t size); - - The function talloc_size() should be used when you don't have a - convenient type to pass to talloc(). Unlike talloc(), it is not - type safe (as it returns a void *), so you are on your own for - type checking. - - - (typeof(ptr)) talloc_ptrtype(const void *ctx, ptr); - - The talloc_ptrtype() macro should be used when you have a pointer and - want to allocate memory to point at with this pointer. When compiling - with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size() - and talloc_get_name() will return the current location in the source file. - and not the type. - - - int talloc_free(void *ptr); - - The talloc_free() function frees a piece of talloc memory, and - all its children. You can call talloc_free() on any pointer - returned by talloc(). - - - The return value of talloc_free() indicates success or failure, - with 0 returned for success and -1 for failure. The only - possible failure condition is if ptr had a destructor attached to it and - the destructor returned -1. See talloc_set_destructor() - for details on destructors. - - - If this pointer has an additional parent when talloc_free() is - called then the memory is not actually released, but instead the - most recently established parent is destroyed. See talloc_reference() - for details on establishing additional parents. - - - For more control on which parent is removed, see talloc_unlink(). - - - talloc_free() operates recursively on its children. - - - From the 2.0 version of talloc, as a special case, - talloc_free() is refused on pointers that have more than one - parent, as talloc would have no way of knowing which parent - should be removed. To free a pointer that has more than one - parent please use talloc_unlink(). - - - To help you find problems in your code caused by this behaviour, if - you do try and free a pointer with more than one parent then the - talloc logging function will be called to give output like this: - - - - ERROR: talloc_free with references at some_dir/source/foo.c:123 - reference at some_dir/source/other.c:325 - reference at some_dir/source/third.c:121 - - - - Please see the documentation for talloc_set_log_fn() and - talloc_set_log_stderr() for more information on talloc logging - functions. - - - void *talloc_reference(const void *ctx, const void *ptr); - - The talloc_reference() function makes ctx an additional parent of ptr. - - - The return value of talloc_reference() is always the original - pointer ptr, unless talloc ran - out of memory in creating the reference in which case it will - return NULL (each additional reference consumes around 48 bytes - of memory on intel x86 platforms). - - - If ptr is NULL, then the - function is a no-op, and simply returns NULL. - - - After creating a reference you can free it in one of the - following ways: - - - - - - you can talloc_free() any parent of the original pointer. - That will reduce the number of parents of this pointer by 1, - and will cause this pointer to be freed if it runs out of - parents. - - - - - you can talloc_free() the pointer itself if it has at maximum one - parent. This behaviour has been changed since the release of version - 2.0. Further information in the description of "talloc_free". - - - - - - For more control on which parent to remove, see talloc_unlink(). - - - int talloc_unlink(const void *ctx, void *ptr); - - The talloc_unlink() function removes a specific parent from - ptr. The ctx passed must either be a context used - in talloc_reference() with this pointer, or must be a direct - parent of ptr. - - - Note that if the parent has already been removed using - talloc_free() then this function will fail and will return -1. - Likewise, if ptr is NULL, then - the function will make no modifications and return -1. - - - Usually you can just use talloc_free() instead of - talloc_unlink(), but sometimes it is useful to have the - additional control on which parent is removed. - - - void talloc_set_destructor(const void *ptr, int (*destructor)(void *)); - - The function talloc_set_destructor() sets the destructor for the pointer ptr. A destructor is a function that is called - when the memory used by a pointer is about to be released. The - destructor receives ptr as an - argument, and should return 0 for success and -1 for failure. - - - The destructor can do anything - it wants to, including freeing other pieces of memory. A common - use for destructors is to clean up operating system resources - (such as open file descriptors) contained in the structure the - destructor is placed on. - - - You can only place one destructor on a pointer. If you need more - than one destructor then you can create a zero-length child of - the pointer and place an additional destructor on that. - - - To remove a destructor call talloc_set_destructor() with NULL for - the destructor. - - - If your destructor attempts to talloc_free() the pointer that it - is the destructor for then talloc_free() will return -1 and the - free will be ignored. This would be a pointless operation - anyway, as the destructor is only called when the memory is just - about to go away. - - - int talloc_increase_ref_count(const void *<emphasis role="italic">ptr</emphasis>); - - The talloc_increase_ref_count(ptr) function is exactly equivalent to: - - talloc_reference(NULL, ptr); - - You can use either syntax, depending on which you think is - clearer in your code. - - - It returns 0 on success and -1 on failure. - - - size_t talloc_reference_count(const void *<emphasis role="italic">ptr</emphasis>); - - Return the number of references to the pointer. - - - void talloc_set_name(const void *ptr, const char *fmt, ...); - - Each talloc pointer has a "name". The name is used principally - for debugging purposes, although it is also possible to set and - get the name on a pointer in as a way of "marking" pointers in - your code. - - - The main use for names on pointer is for "talloc reports". See - talloc_report_depth_cb(), - talloc_report_depth_file(), - talloc_report() - talloc_report() - and talloc_report_full() - for details. Also see talloc_enable_leak_report() - and talloc_enable_leak_report_full(). - - - The talloc_set_name() function allocates memory as a child of the - pointer. It is logically equivalent to: - - talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...)); - - Note that multiple calls to talloc_set_name() will allocate more - memory without releasing the name. All of the memory is released - when the ptr is freed using talloc_free(). - - - void talloc_set_name_const(const void *<emphasis role="italic">ptr</emphasis>, const char *<emphasis role="italic">name</emphasis>); - - The function talloc_set_name_const() is just like - talloc_set_name(), but it takes a string constant, and is much - faster. It is extensively used by the "auto naming" macros, such - as talloc_p(). - - - This function does not allocate any memory. It just copies the - supplied pointer into the internal representation of the talloc - ptr. This means you must not pass a name pointer to memory that will - disappear before ptr is freed - with talloc_free(). - - - void *talloc_named(const void *<emphasis role="italic">ctx</emphasis>, size_t <emphasis role="italic">size</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, ...); - - The talloc_named() function creates a named talloc pointer. It - is equivalent to: - - ptr = talloc_size(ctx, size); -talloc_set_name(ptr, fmt, ....); - - void *talloc_named_const(const void *<emphasis role="italic">ctx</emphasis>, size_t <emphasis role="italic">size</emphasis>, const char *<emphasis role="italic">name</emphasis>); - - This is equivalent to: - - ptr = talloc_size(ctx, size); -talloc_set_name_const(ptr, name); - - const char *talloc_get_name(const void *<emphasis role="italic">ptr</emphasis>); - - This returns the current name for the given talloc pointer, - ptr. See talloc_set_name() - for details. - - - void *talloc_init(const char *<emphasis role="italic">fmt</emphasis>, ...); - - This function creates a zero length named talloc context as a top - level context. It is equivalent to: - - talloc_named(NULL, 0, fmt, ...); - - void *talloc_new(void *<emphasis role="italic">ctx</emphasis>); - - This is a utility macro that creates a new memory context hanging - off an existing context, automatically naming it "talloc_new: - __location__" where __location__ is the source line it is called - from. It is particularly useful for creating a new temporary - working context. - - - (<emphasis role="italic">type</emphasis> *)talloc_realloc(const void *<emphasis role="italic">ctx</emphasis>, void *<emphasis role="italic">ptr</emphasis>, <emphasis role="italic">type</emphasis>, <emphasis role="italic">count</emphasis>); - - The talloc_realloc() macro changes the size of a talloc pointer. - It has the following equivalences: - - talloc_realloc(ctx, NULL, type, 1) ==> talloc(ctx, type); -talloc_realloc(ctx, ptr, type, 0) ==> talloc_free(ptr); - - The ctx argument is only used - if ptr is not NULL, otherwise - it is ignored. - - - talloc_realloc() returns the new pointer, or NULL on failure. - The call will fail either due to a lack of memory, or because the - pointer has more than one parent (see talloc_reference()). - - - void *talloc_realloc_size(const void *ctx, void *ptr, size_t size); - - the talloc_realloc_size() function is useful when the type is not - known so the type-safe talloc_realloc() cannot be used. - - - TYPE *talloc_steal(const void *<emphasis role="italic">new_ctx</emphasis>, const TYPE *<emphasis role="italic">ptr</emphasis>); - - The talloc_steal() function changes the parent context of a - talloc pointer. It is typically used when the context that the - pointer is currently a child of is going to be freed and you wish - to keep the memory for a longer time. - - - The talloc_steal() function returns the pointer that you pass it. - It does not have any failure modes. - - - It is possible to produce loops in the parent/child - relationship if you are not careful with talloc_steal(). No - guarantees are provided as to your sanity or the safety of your - data if you do this. - - - Note that if you try and call talloc_steal() on a pointer that has - more than one parent then the result is ambiguous. Talloc will choose - to remove the parent that is currently indicated by talloc_parent() - and replace it with the chosen parent. You will also get a message - like this via the talloc logging functions: - - - - WARNING: talloc_steal with references at some_dir/source/foo.c:123 - reference at some_dir/source/other.c:325 - reference at some_dir/source/third.c:121 - - - - To unambiguously change the parent of a pointer please see - the - function talloc_reparent(). See - the talloc_set_log_fn() documentation for more information - on talloc logging. - - - TYPE *talloc_reparent(const void *<emphasis role="italic">old_parent</emphasis>, const void *<emphasis role="italic">new_parent</emphasis>, const TYPE *<emphasis role="italic">ptr</emphasis>); - - The talloc_reparent() function changes the parent context of a talloc - pointer. It is typically used when the context that the pointer is - currently a child of is going to be freed and you wish to keep the - memory for a longer time. - - - The talloc_reparent() function returns the pointer that you pass it. It - does not have any failure modes. - - - The difference between talloc_reparent() and talloc_steal() is that - talloc_reparent() can specify which parent you wish to change. This is - useful when a pointer has multiple parents via references. - - - TYPE *talloc_move(const void *<emphasis role="italic">new_ctx</emphasis>, TYPE **<emphasis role="italic">ptr</emphasis>); - - The talloc_move() function is a wrapper around - talloc_steal() which zeros the source pointer after the - move. This avoids a potential source of bugs where a - programmer leaves a pointer in two structures, and uses the - pointer from the old structure after it has been moved to a - new one. - - - size_t talloc_total_size(const void *<emphasis role="italic">ptr</emphasis>); - - The talloc_total_size() function returns the total size in bytes - used by this pointer and all child pointers. Mostly useful for - debugging. - - - Passing NULL is allowed, but it will only give a meaningful - result if talloc_enable_leak_report() or - talloc_enable_leak_report_full() has been called. - - - size_t talloc_total_blocks(const void *<emphasis role="italic">ptr</emphasis>); - - The talloc_total_blocks() function returns the total memory block - count used by this pointer and all child pointers. Mostly useful - for debugging. - - - Passing NULL is allowed, but it will only give a meaningful - result if talloc_enable_leak_report() or - talloc_enable_leak_report_full() has been called. - - - void talloc_report(const void *ptr, FILE *f); - - The talloc_report() function prints a summary report of all - memory used by ptr. One line - of report is printed for each immediate child of ptr, showing the - total memory and number of blocks used by that child. - - - You can pass NULL for the pointer, in which case a report is - printed for the top level memory context, but only if - talloc_enable_leak_report() or talloc_enable_leak_report_full() - has been called. - - - void talloc_report_full(const void *<emphasis role="italic">ptr</emphasis>, FILE *<emphasis role="italic">f</emphasis>); - - This provides a more detailed report than talloc_report(). It - will recursively print the entire tree of memory referenced by - the pointer. References in the tree are shown by giving the name - of the pointer that is referenced. - - - You can pass NULL for the pointer, in which case a report is - printed for the top level memory context, but only if - talloc_enable_leak_report() or talloc_enable_leak_report_full() - has been called. - - - - - void talloc_report_depth_cb - const void *ptr - int depth - int max_depth - void (*callback)(const void *ptr, int depth, int max_depth, int is_ref, void *priv) - void *priv - - - This provides a more flexible reports than talloc_report(). It - will recursively call the callback for the entire tree of memory - referenced by the pointer. References in the tree are passed with - is_ref = 1 and the pointer that is referenced. - - - You can pass NULL for the pointer, in which case a report is - printed for the top level memory context, but only if - talloc_enable_leak_report() or talloc_enable_leak_report_full() - has been called. - - - The recursion is stopped when depth >= max_depth. - max_depth = -1 means only stop at leaf nodes. - - - - - void talloc_report_depth_file - const void *ptr - int depth - int max_depth - FILE *f - - - This provides a more flexible reports than talloc_report(). It - will let you specify the depth and max_depth. - - - void talloc_enable_leak_report(void); - - This enables calling of talloc_report(NULL, stderr) when the - program exits. In Samba4 this is enabled by using the - --leak-report command line option. - - - For it to be useful, this function must be called before any - other talloc function as it establishes a "null context" that - acts as the top of the tree. If you don't call this function - first then passing NULL to talloc_report() or - talloc_report_full() won't give you the full tree printout. - - - Here is a typical talloc report: - - talloc report on 'null_context' (total 267 bytes in 15 blocks) -libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks -libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks -iconv(UTF8,CP850) contains 42 bytes in 2 blocks -libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks -iconv(CP850,UTF8) contains 42 bytes in 2 blocks -iconv(UTF8,UTF-16LE) contains 45 bytes in 2 blocks -iconv(UTF-16LE,UTF8) contains 45 bytes in 2 blocks - - - void talloc_enable_leak_report_full(void); - - This enables calling of talloc_report_full(NULL, stderr) when the - program exits. In Samba4 this is enabled by using the - --leak-report-full command line option. - - - For it to be useful, this function must be called before any - other talloc function as it establishes a "null context" that - acts as the top of the tree. If you don't call this function - first then passing NULL to talloc_report() or - talloc_report_full() won't give you the full tree printout. - - - Here is a typical full report: - - full talloc report on 'root' (total 18 bytes in 8 blocks) -p1 contains 18 bytes in 7 blocks (ref 0) - r1 contains 13 bytes in 2 blocks (ref 0) - reference to: p2 - p2 contains 1 bytes in 1 blocks (ref 1) - x3 contains 1 bytes in 1 blocks (ref 0) - x2 contains 1 bytes in 1 blocks (ref 0) - x1 contains 1 bytes in 1 blocks (ref 0) - - - (<emphasis role="italic">type</emphasis> *)talloc_zero(const void *<emphasis role="italic">ctx</emphasis>, <emphasis role="italic">type</emphasis>); - - The talloc_zero() macro is equivalent to: - - ptr = talloc(ctx, type); -if (ptr) memset(ptr, 0, sizeof(type)); - - void *talloc_zero_size(const void *<emphasis role="italic">ctx</emphasis>, size_t <emphasis role="italic">size</emphasis>) - - The talloc_zero_size() function is useful when you don't have a - known type. - - - void *talloc_memdup(const void *<emphasis role="italic">ctx</emphasis>, const void *<emphasis role="italic">p</emphasis>, size_t size); - - The talloc_memdup() function is equivalent to: - - ptr = talloc_size(ctx, size); -if (ptr) memcpy(ptr, p, size); - - char *talloc_strdup(const void *<emphasis role="italic">ctx</emphasis>, const char *<emphasis role="italic">p</emphasis>); - - The talloc_strdup() function is equivalent to: - - ptr = talloc_size(ctx, strlen(p)+1); -if (ptr) memcpy(ptr, p, strlen(p)+1); - - This function sets the name of the new pointer to the passed - string. This is equivalent to: - - talloc_set_name_const(ptr, ptr) - - char *talloc_strndup(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">p</emphasis>, size_t <emphasis role="italic">n</emphasis>); - - The talloc_strndup() function is the talloc equivalent of the C - library function strndup(3). - - - This function sets the name of the new pointer to the passed - string. This is equivalent to: - - talloc_set_name_const(ptr, ptr) - - char *talloc_vasprintf(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, va_list <emphasis role="italic">ap</emphasis>); - - The talloc_vasprintf() function is the talloc equivalent of the C - library function vasprintf(3). - - - This function sets the name of the new pointer to the new - string. This is equivalent to: - - talloc_set_name_const(ptr, ptr) - - char *talloc_asprintf(const void *<emphasis role="italic">t</emphasis>, const char *<emphasis role="italic">fmt</emphasis>, ...); - - The talloc_asprintf() function is the talloc equivalent of the C - library function asprintf(3). - - - This function sets the name of the new pointer to the passed - string. This is equivalent to: - - talloc_set_name_const(ptr, ptr) - - char *talloc_asprintf_append(char *s, const char *fmt, ...); - - The talloc_asprintf_append() function appends the given formatted - string to the given string. - - - This function sets the name of the new pointer to the new - string. This is equivalent to: - - talloc_set_name_const(ptr, ptr) - - (type *)talloc_array(const void *ctx, type, unsigned int count); - - The talloc_array() macro is equivalent to: - - (type *)talloc_size(ctx, sizeof(type) * count); - - except that it provides integer overflow protection for the - multiply, returning NULL if the multiply overflows. - - - void *talloc_array_size(const void *ctx, size_t size, unsigned int count); - - The talloc_array_size() function is useful when the type is not - known. It operates in the same way as talloc_array(), but takes a - size instead of a type. - - - (typeof(ptr)) talloc_array_ptrtype(const void *ctx, ptr, unsigned int count); - - The talloc_ptrtype() macro should be used when you have a pointer to an array - and want to allocate memory of an array to point at with this pointer. When compiling - with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_array_size() - and talloc_get_name() will return the current location in the source file. - and not the type. - - - void *talloc_realloc_fn(const void *ctx, void *ptr, size_t size) - - This is a non-macro version of talloc_realloc(), which is useful - as libraries sometimes want a realloc function pointer. A - realloc(3) implementation encapsulates the functionality of - malloc(3), free(3) and realloc(3) in one call, which is why it is - useful to be able to pass around a single function pointer. - - - void *talloc_autofree_context(void); - - This is a handy utility function that returns a talloc context - which will be automatically freed on program exit. This can be - used to reduce the noise in memory leak reports. - - - void *talloc_check_name(const void *ptr, const char *name); - - This function checks if a pointer has the specified name. If it does then the pointer is - returned. It it doesn't then NULL is returned. - - - (type *)talloc_get_type(const void *ptr, type); - - This macro allows you to do type checking on talloc pointers. It - is particularly useful for void* private pointers. It is - equivalent to this: - - (type *)talloc_check_name(ptr, #type) - - talloc_set_type(const void *ptr, type); - - This macro allows you to force the name of a pointer to be a - particular type. This can be - used in conjunction with talloc_get_type() to do type checking on - void* pointers. - - - It is equivalent to this: - - talloc_set_name_const(ptr, #type) - - talloc_set_log_fn(void (*log_fn)(const char *message)); - - This function sets a logging function that talloc will use for - warnings and errors. By default talloc will not print any warnings or - errors. - - - talloc_set_log_stderr(void); - - This sets the talloc log function to write log messages to stderr - - - - PERFORMANCE - - All the additional features of talloc(3) over malloc(3) do come at a - price. We have a simple performance test in Samba4 that measures - talloc() versus malloc() performance, and it seems that talloc() is - about 10% slower than malloc() on my x86 Debian Linux box. For - Samba, the great reduction in code complexity that we get by using - talloc makes this worthwhile, especially as the total overhead of - talloc/malloc in Samba is already quite small. - - - SEE ALSO - - malloc(3), strndup(3), vasprintf(3), asprintf(3), - - - - - AUTHOR - The original Samba software and related utilities were - created by Andrew Tridgell. Samba is now developed by the - Samba Team as an Open Source project similar to the way the - Linux kernel is developed. - - - - COPYRIGHT/LICENSE - - Copyright (C) Andrew Tridgell 2004 - - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 3 of the - License, or (at your option) any later version. - - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - - You should have received a copy of the GNU General Public License - along with this program; if not, see http://www.gnu.org/licenses/. - - - diff --git a/ldb-2.0.8/lib/talloc/pytalloc-util.pc.in b/ldb-2.0.8/lib/talloc/pytalloc-util.pc.in deleted file mode 100644 index 06f83e2..0000000 --- a/ldb-2.0.8/lib/talloc/pytalloc-util.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: pytalloc-util@PYTHON_SO_ABI_FLAG@ -Description: Utility functions for using talloc objects with Python -Version: @TALLOC_VERSION@ -Libs: @LIB_RPATH@ -L${libdir} -lpytalloc-util@PYTHON_LIBNAME_SO_ABI_FLAG@ -Cflags: -I${includedir} -URL: http://talloc.samba.org/ diff --git a/ldb-2.0.8/lib/talloc/pytalloc.c b/ldb-2.0.8/lib/talloc/pytalloc.c deleted file mode 100644 index 12c7325..0000000 --- a/ldb-2.0.8/lib/talloc/pytalloc.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Python Talloc Module - Copyright (C) Jelmer Vernooij 2010-2011 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include -#include -#include -#include "pytalloc_private.h" - -static PyTypeObject TallocObject_Type; - -/* print a talloc tree report for a talloc python object */ -static PyObject *pytalloc_report_full(PyObject *self, PyObject *args) -{ - PyObject *py_obj = Py_None; - - if (!PyArg_ParseTuple(args, "|O", &py_obj)) - return NULL; - - if (py_obj == Py_None) { - talloc_report_full(NULL, stdout); - } else { - talloc_report_full(pytalloc_get_mem_ctx(py_obj), stdout); - } - return Py_None; -} - -/* enable null tracking */ -static PyObject *pytalloc_enable_null_tracking(PyObject *self, - PyObject *Py_UNUSED(ignored)) -{ - talloc_enable_null_tracking(); - return Py_None; -} - -/* return the number of talloc blocks */ -static PyObject *pytalloc_total_blocks(PyObject *self, PyObject *args) -{ - PyObject *py_obj = Py_None; - - if (!PyArg_ParseTuple(args, "|O", &py_obj)) - return NULL; - - if (py_obj == Py_None) { - return PyLong_FromLong(talloc_total_blocks(NULL)); - } - - return PyLong_FromLong(talloc_total_blocks(pytalloc_get_mem_ctx(py_obj))); -} - -static PyMethodDef talloc_methods[] = { - { "report_full", (PyCFunction)pytalloc_report_full, METH_VARARGS, - "show a talloc tree for an object"}, - { "enable_null_tracking", (PyCFunction)pytalloc_enable_null_tracking, METH_NOARGS, - "enable tracking of the NULL object"}, - { "total_blocks", (PyCFunction)pytalloc_total_blocks, METH_VARARGS, - "return talloc block count"}, - { NULL } -}; - -/** - * Default (but only slightly more useful than the default) implementation of Repr(). - */ -static PyObject *pytalloc_default_repr(PyObject *obj) -{ - pytalloc_Object *talloc_obj = (pytalloc_Object *)obj; - PyTypeObject *type = (PyTypeObject*)PyObject_Type(obj); - - return PyUnicode_FromFormat("<%s talloc object at %p>", - type->tp_name, talloc_obj->ptr); -} - -/** - * Simple dealloc for talloc-wrapping PyObjects - */ -static void pytalloc_dealloc(PyObject* self) -{ - pytalloc_Object *obj = (pytalloc_Object *)self; - assert(talloc_unlink(NULL, obj->talloc_ctx) != -1); - obj->talloc_ctx = NULL; - self->ob_type->tp_free(self); -} - -/** - * Default (but only slightly more useful than the default) implementation of cmp. - */ -#if PY_MAJOR_VERSION >= 3 -static PyObject *pytalloc_default_richcmp(PyObject *obj1, PyObject *obj2, int op) -{ - void *ptr1; - void *ptr2; - if (Py_TYPE(obj1) == Py_TYPE(obj2)) { - /* When types match, compare pointers */ - ptr1 = pytalloc_get_ptr(obj1); - ptr2 = pytalloc_get_ptr(obj2); - } else if (PyObject_TypeCheck(obj2, &TallocObject_Type)) { - /* Otherwise, compare types */ - ptr1 = Py_TYPE(obj1); - ptr2 = Py_TYPE(obj2); - } else { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - switch (op) { - case Py_EQ: return PyBool_FromLong(ptr1 == ptr2); - case Py_NE: return PyBool_FromLong(ptr1 != ptr2); - case Py_LT: return PyBool_FromLong(ptr1 < ptr2); - case Py_GT: return PyBool_FromLong(ptr1 > ptr2); - case Py_LE: return PyBool_FromLong(ptr1 <= ptr2); - case Py_GE: return PyBool_FromLong(ptr1 >= ptr2); - } - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; -} -#else -static int pytalloc_default_cmp(PyObject *_obj1, PyObject *_obj2) -{ - pytalloc_Object *obj1 = (pytalloc_Object *)_obj1, - *obj2 = (pytalloc_Object *)_obj2; - if (obj1->ob_type != obj2->ob_type) - return ((char *)obj1->ob_type - (char *)obj2->ob_type); - - return ((char *)pytalloc_get_ptr(obj1) - (char *)pytalloc_get_ptr(obj2)); -} -#endif - -static PyTypeObject TallocObject_Type = { - .tp_name = "talloc.Object", - .tp_doc = "Python wrapper for a talloc-maintained object.", - .tp_basicsize = sizeof(pytalloc_Object), - .tp_dealloc = (destructor)pytalloc_dealloc, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - .tp_repr = pytalloc_default_repr, -#if PY_MAJOR_VERSION >= 3 - .tp_richcompare = pytalloc_default_richcmp, -#else - .tp_compare = pytalloc_default_cmp, -#endif -}; - -/** - * Default (but only slightly more useful than the default) implementation of Repr(). - */ -static PyObject *pytalloc_base_default_repr(PyObject *obj) -{ - pytalloc_BaseObject *talloc_obj = (pytalloc_BaseObject *)obj; - PyTypeObject *type = (PyTypeObject*)PyObject_Type(obj); - - return PyUnicode_FromFormat("<%s talloc based object at %p>", - type->tp_name, talloc_obj->ptr); -} - -/** - * Simple dealloc for talloc-wrapping PyObjects - */ -static void pytalloc_base_dealloc(PyObject* self) -{ - pytalloc_BaseObject *obj = (pytalloc_BaseObject *)self; - assert(talloc_unlink(NULL, obj->talloc_ctx) != -1); - obj->talloc_ctx = NULL; - self->ob_type->tp_free(self); -} - -/** - * Default (but only slightly more useful than the default) implementation of cmp. - */ -#if PY_MAJOR_VERSION >= 3 -static PyObject *pytalloc_base_default_richcmp(PyObject *obj1, PyObject *obj2, int op) -{ - void *ptr1; - void *ptr2; - if (Py_TYPE(obj1) == Py_TYPE(obj2)) { - /* When types match, compare pointers */ - ptr1 = pytalloc_get_ptr(obj1); - ptr2 = pytalloc_get_ptr(obj2); - } else if (PyObject_TypeCheck(obj2, &TallocObject_Type)) { - /* Otherwise, compare types */ - ptr1 = Py_TYPE(obj1); - ptr2 = Py_TYPE(obj2); - } else { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - switch (op) { - case Py_EQ: return PyBool_FromLong(ptr1 == ptr2); - case Py_NE: return PyBool_FromLong(ptr1 != ptr2); - case Py_LT: return PyBool_FromLong(ptr1 < ptr2); - case Py_GT: return PyBool_FromLong(ptr1 > ptr2); - case Py_LE: return PyBool_FromLong(ptr1 <= ptr2); - case Py_GE: return PyBool_FromLong(ptr1 >= ptr2); - } - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; -} -#else -static int pytalloc_base_default_cmp(PyObject *_obj1, PyObject *_obj2) -{ - pytalloc_BaseObject *obj1 = (pytalloc_BaseObject *)_obj1, - *obj2 = (pytalloc_BaseObject *)_obj2; - if (obj1->ob_type != obj2->ob_type) - return ((char *)obj1->ob_type - (char *)obj2->ob_type); - - return ((char *)pytalloc_get_ptr(obj1) - (char *)pytalloc_get_ptr(obj2)); -} -#endif - -static PyTypeObject TallocBaseObject_Type = { - .tp_name = "talloc.BaseObject", - .tp_doc = "Python wrapper for a talloc-maintained object.", - .tp_basicsize = sizeof(pytalloc_BaseObject), - .tp_dealloc = (destructor)pytalloc_base_dealloc, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - .tp_repr = pytalloc_base_default_repr, -#if PY_MAJOR_VERSION >= 3 - .tp_richcompare = pytalloc_base_default_richcmp, -#else - .tp_compare = pytalloc_base_default_cmp, -#endif -}; - -static PyTypeObject TallocGenericObject_Type = { - .tp_name = "talloc.GenericObject", - .tp_doc = "Python wrapper for a talloc-maintained object.", - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - .tp_base = &TallocBaseObject_Type, - .tp_basicsize = sizeof(pytalloc_BaseObject), -}; - -#define MODULE_DOC PyDoc_STR("Python wrapping of talloc-maintained objects.") - -#if PY_MAJOR_VERSION >= 3 -static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - .m_name = "talloc", - .m_doc = MODULE_DOC, - .m_size = -1, - .m_methods = talloc_methods, -}; -#endif - -static PyObject *module_init(void); -static PyObject *module_init(void) -{ - PyObject *m; - - if (PyType_Ready(&TallocObject_Type) < 0) - return NULL; - - if (PyType_Ready(&TallocBaseObject_Type) < 0) - return NULL; - - if (PyType_Ready(&TallocGenericObject_Type) < 0) - return NULL; - -#if PY_MAJOR_VERSION >= 3 - m = PyModule_Create(&moduledef); -#else - m = Py_InitModule3("talloc", talloc_methods, MODULE_DOC); -#endif - if (m == NULL) - return NULL; - - Py_INCREF(&TallocObject_Type); - if (PyModule_AddObject(m, "Object", (PyObject *)&TallocObject_Type)) { - goto err; - } - Py_INCREF(&TallocBaseObject_Type); - if (PyModule_AddObject(m, "BaseObject", (PyObject *)&TallocBaseObject_Type)) { - goto err; - } - Py_INCREF(&TallocGenericObject_Type); - if (PyModule_AddObject(m, "GenericObject", (PyObject *)&TallocGenericObject_Type)) { - goto err; - } - return m; - -err: - Py_DECREF(m); - return NULL; -} - -#if PY_MAJOR_VERSION >= 3 -PyMODINIT_FUNC PyInit_talloc(void); -PyMODINIT_FUNC PyInit_talloc(void) -{ - return module_init(); -} -#else -void inittalloc(void); -void inittalloc(void) -{ - module_init(); -} -#endif diff --git a/ldb-2.0.8/lib/talloc/pytalloc.h b/ldb-2.0.8/lib/talloc/pytalloc.h deleted file mode 100644 index 7db6c33..0000000 --- a/ldb-2.0.8/lib/talloc/pytalloc.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba utility functions - Copyright (C) Jelmer Vernooij 2008 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef _PYTALLOC_H_ -#define _PYTALLOC_H_ - -#include -#include - -typedef struct { - PyObject_HEAD - TALLOC_CTX *talloc_ctx; - void *ptr; /* eg the array element */ -} pytalloc_Object; - -/* Return the PyTypeObject for pytalloc_Object. Returns a borrowed reference. */ -PyTypeObject *pytalloc_GetObjectType(void); - -/* Return the PyTypeObject for pytalloc_BaseObject. Returns a borrowed reference. */ -PyTypeObject *pytalloc_GetBaseObjectType(void); - -/* Check whether a specific object is a talloc Object. */ -int pytalloc_Check(PyObject *); - -int pytalloc_BaseObject_check(PyObject *); - -int _pytalloc_check_type(PyObject *py_obj, const char *type_name); -#define pytalloc_check_type(py_obj, type) \ - _pytalloc_check_type((PyObject *)(py_obj), #type) - -/* Retrieve the pointer for a pytalloc_object. Like talloc_get_type() - * but for pytalloc_Objects. */ -void *_pytalloc_get_type(PyObject *py_obj, const char *type_name); -#define pytalloc_get_type(py_obj, type) ((type *)_pytalloc_get_type((PyObject *)(py_obj), #type)) - -void *_pytalloc_get_ptr(PyObject *py_obj); -#define pytalloc_get_ptr(py_obj) _pytalloc_get_ptr((PyObject *)(py_obj)) -TALLOC_CTX *_pytalloc_get_mem_ctx(PyObject *py_obj); -#define pytalloc_get_mem_ctx(py_obj) _pytalloc_get_mem_ctx((PyObject *)(py_obj)) - -PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr); -PyObject *pytalloc_steal(PyTypeObject *py_type, void *ptr); -PyObject *pytalloc_reference_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr); -#define pytalloc_reference(py_type, talloc_ptr) pytalloc_reference_ex(py_type, talloc_ptr, talloc_ptr) - -#define pytalloc_new(type, typeobj) pytalloc_steal(typeobj, talloc_zero(NULL, type)) - -/* - * Wrap a generic talloc pointer into a talloc.GenericObject, - * this is a subclass of talloc.BaseObject. - */ -PyObject *pytalloc_GenericObject_steal_ex(TALLOC_CTX *mem_ctx, void *ptr); -#define pytalloc_GenericObject_steal(talloc_ptr) \ - pytalloc_GenericObject_steal_ex(talloc_ptr, talloc_ptr) -PyObject *pytalloc_GenericObject_reference_ex(TALLOC_CTX *mem_ctx, void *ptr); -#define pytalloc_GenericObject_reference(talloc_ptr) \ - pytalloc_GenericObject_reference_ex(talloc_ptr, talloc_ptr) - -size_t pytalloc_BaseObject_size(void); - -int pytalloc_BaseObject_PyType_Ready(PyTypeObject *type); - -#endif /* _PYTALLOC_H_ */ diff --git a/ldb-2.0.8/lib/talloc/pytalloc_guide.txt b/ldb-2.0.8/lib/talloc/pytalloc_guide.txt deleted file mode 100644 index bd2b68c..0000000 --- a/ldb-2.0.8/lib/talloc/pytalloc_guide.txt +++ /dev/null @@ -1,252 +0,0 @@ -Using talloc in Samba4 -====================== - -.. contents:: - -Jelmer Vernooij -August 2013 - -The most current version of this document is available at - http://samba.org/ftp/unpacked/talloc/pytalloc_guide.txt - -pytalloc is a small library that provides glue for wrapping -talloc-allocated objects from C in Python objects. - -What is pytalloc, and what is it not? -------------------------------------- - -pytalloc is merely a helper library - it provides a convenient base type object -for objects that wrap talloc-maintained memory in C. It won't write your -bindings for you but it will make it easier to write C bindings that involve -talloc, and take away some of the boiler plate. - -Python 3 --------- - -pytalloc can be used with Python 3. Usage from Python extension remains -the same, but for the C utilities, the library to link to is tagged with -Python's PEP3149 ABI tag, for example "pytalloc.cpython34m". -To make a build for Python 3, configure with PYTHON=/usr/bin/python3. -. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -pytalloc_Object / pytalloc_BaseObject - -This is the new base class that all Python objects that wrap talloc pointers -derive from. It is itself a subclass of the "Object" type that all objects -in Python derive from. - -Note that you will almost never create objects of the pytalloc_Object type -itself, as they are just opaque pointers that can not be accessed from -Python. A common pattern is other objects that subclass pytalloc_Object and -rely on it for their memory management. - -Each `pytalloc_Object` wraps two core of information - a talloc context -and a pointer. The pointer is the actual data that is wrapped. The talloc -context is used for memory management purposes only; when the wrapping Python object -goes away, it unlinks the talloc context. The talloc context pointer and the ptr -can (and often do) have the same value. - -Each pytalloc_Object has a custom __repr__ implementation that -describes that it is a talloc object and the location of the -pointer it is wrapping. it also has a custom __cmp__/__eq__/__neq__ method that -compares the pointers the object is wrapping rather than the objects -themselves (since there can be multiple objects that wrap the same talloc -pointer). - -It is preferred to use pytalloc_BaseObject as this implementation -exposes less in the C ABI and correctly supports pointers in C arrays -in the way needed by PIDL. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -PyTypeObject *pytalloc_GetObjectType(void) - -Obtain a pointer to the PyTypeObject for `pytalloc_Object`. The -reference counter for the object will be NOT incremented, so the -caller MUST NOT decrement it when it no longer needs it (eg by using -`Py_DECREF`). - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -PyTypeObject *pytalloc_GetBaseObjectType(void) - -Obtain a pointer to the PyTypeObject for `pytalloc_BaseObject`. The -reference counter for the object will be NOT incremented, so the -caller MUST NOT decrement it when it no longer needs it (eg by using -`Py_DECREF`). - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -int pytalloc_BaseObject_PyType_Ready(PyTypeObject *type); - -Wrapper for PyType_Ready() that will set the correct values into -the PyTypeObject to create a BaseObject - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=- -int pytalloc_Check(PyObject *) - -Check whether a specific object is a talloc Object. Returns non-zero if it is -a pytalloc_Object and zero otherwise. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=- -int pytalloc_BaseObject_Check(PyObject *) - -Check whether a specific object is a talloc BaseObject. Returns non-zero if it is -a pytalloc_BaseObject and zero otherwise. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -int pytalloc_check_type(PyObject *py_obj, type) - -Check if the object based on `pytalloc_*Object` py_obj. type should be a -C type, similar to a type passed to `talloc_get_type`. -This can be used as a check before using pytalloc_get_type() -or an alternative codepath. Returns non-zero if it is -an object of the expected type and zero otherwise. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -type *pytalloc_get_type(PyObject *py_obj, type) - -Retrieve the pointer from a `pytalloc_Object` py_obj. type should be a -C type, similar to a type passed to `talloc_get_type`. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -pytalloc_get_ptr(PyObject *py_obj) - -Retrieve the pointer from a `pytalloc_Object` or `pytalloc_BaseObject` -py_obj. There is no type checking - use `pytalloc_get_type` if -possible. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -TALLOC_CTX *pytalloc_get_mem_ctx(PyObject *py_obj) - -Retrieve the talloc context associated with a pytalloc_Object or pytalloc_BaseObject. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr) - -Create a new Python wrapping object for a talloc pointer and context, with -py_type as associated Python sub type object. This typically used -when `mem_ctx` and `ptr` differ, e.g. a pointer to an array element. -`pytalloc_get_ptr()` can be used to get the pointer out of the object again. - -This will *not* increment the reference counter for the talloc context, -so the caller should make sure such an increment has happened. When the Python -object goes away, it will unreference the talloc context. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -PyObject *pytalloc_steal(PyTypeObject *py_type, void *ptr) - -Create a new Python wrapping object for a talloc pointer and context, with -py_type as associated Python sub type object. The pointer will also be used -as the talloc context. `pytalloc_get_type()` can be used to get -the pointer out of the object again. - -This will *not* increment the reference counter for the talloc context, -so the caller should make sure such an increment has happened. When the Python -object goes away, it will unreference the talloc context. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -PyObject *pytalloc_reference_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr) - -Create a new Python wrapping object for a talloc pointer and context, with -py_type as associated Python sub type object. This typically used -when `mem_ctx` and `ptr` differ, e.g. a pointer to an array element. -`pytalloc_get_ptr()` can be used to get the pointer out of the object again. - -This will increment the reference counter for the talloc context. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -PyObject *pytalloc_reference(PyTypeObject *py_type, void *talloc_ptr) - -Create a new Python wrapping object for a talloc pointer, with -py_type as associated Python sub type object. The pointer will also be used -as the talloc context. `pytalloc_get_type()` can be used to get -the pointer out of the object again. - -This will increment the reference counter for the talloc context. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -PyObject *pytalloc_new(type, PyTypeObject *typeobj) - -Create a new, empty pytalloc_Object with the specified Python type object. type -should be a C type, similar to talloc_new(). - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -PyObject *pytalloc_GenericObject_steal_ex(void *ptr) - -Create a new Python wrapping object for a generic talloc pointer, -as sub type of `pytalloc_BaseObject`. This typically used -when `mem_ctx` and `ptr` differ, e.g. a pointer to an array element. -`pytalloc_get_ptr()` can be used to get the pointer out of the object again. - -This will *not* increment the reference counter for the talloc context, -so the caller should make sure such an increment has happened. When the Python -object goes away, it will unreference the talloc context. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -PyObject *pytalloc_GenericObject_steal(void *ptr) - -Create a new Python wrapping object for a generic talloc pointer, -as sub type of `pytalloc_BaseObject`. The pointer will also be used -as the talloc context. `pytalloc_get_type()` can be used to get -the pointer out of the object again. - -This will *not* increment the reference counter for the talloc context, -so the caller should make sure such an increment has happened. When the Python -object goes away, it will unreference the talloc context. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -PyObject *pytalloc_GenericObject_reference_ex(void *ptr) - -Create a new Python wrapping object for a generic talloc pointer, -as sub type of `pytalloc_BaseObject`. This typically used -when `mem_ctx` and `ptr` differ, e.g. a pointer to an array element. -`pytalloc_get_ptr()` can be used to get the pointer out of the object again. - -This will increment the reference counter for the talloc context. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -PyObject *pytalloc_GenericObject_reference(void *ptr) - -Create a new Python wrapping object for a generic talloc pointer, -as sub type of `pytalloc_BaseObject`. The pointer will also be used -as the talloc context. `pytalloc_get_type()` can be used to get -the pointer out of the object again. - -This will increment the reference counter for the talloc context. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -DEPRECATED! PyObject *pytalloc_CObject_FromTallocPtr(void *); - -Create a new pytalloc_Object for an abitrary talloc-maintained C pointer. This will -use a generic VoidPtr Python type, which just provides an opaque object in -Python. The caller is responsible for incrementing the talloc reference count before calling -this function - it will dereference the talloc pointer when it is garbage collected. - -This function is deprecated and only available on Python 2. -Use pytalloc_GenericObject_{reference,steal}[_ex]() instead. - -Debug function for talloc in Python ------------------------------------ - -The "talloc" module in Python provides a couple of functions that can be used -to debug issues with objects wrapped by pytalloc. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -report_full(obj?) - -Print a full report on a specific object or on all allocated objects by Python. -Same behaviour as the `talloc_report_full()` function that is provided by -C talloc. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -enable_null_tracking() - -This enables tracking of the NULL memory context without enabling leak -reporting on exit. Useful for when you want to do your own leak -reporting call via talloc_report_null_full(). - -This must be done in the top level script, not an imported module. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -pytalloc_total_blocks(obj?) - -Return the talloc block count for all allocated objects or a specific object if -specified. diff --git a/ldb-2.0.8/lib/talloc/pytalloc_private.h b/ldb-2.0.8/lib/talloc/pytalloc_private.h deleted file mode 100644 index b23cdfc..0000000 --- a/ldb-2.0.8/lib/talloc/pytalloc_private.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba utility functions - Copyright (C) Jelmer Vernooij 2008 - Copyright (C) Andrew Bartlett 2016 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -typedef struct { - PyObject_HEAD - TALLOC_CTX *talloc_ctx; - TALLOC_CTX *talloc_ptr_ctx; /* eg the start of the array */ - void *ptr; /* eg the array element */ -} pytalloc_BaseObject; diff --git a/ldb-2.0.8/lib/talloc/pytalloc_util.c b/ldb-2.0.8/lib/talloc/pytalloc_util.c deleted file mode 100644 index 7a426d6..0000000 --- a/ldb-2.0.8/lib/talloc/pytalloc_util.c +++ /dev/null @@ -1,333 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Python/Talloc glue - Copyright (C) Jelmer Vernooij 2008 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include -#include "replace.h" -#include -#include "pytalloc.h" -#include -#include "pytalloc_private.h" - -static PyObject *pytalloc_steal_or_reference(PyTypeObject *py_type, - TALLOC_CTX *mem_ctx, void *ptr, bool steal); - -_PUBLIC_ PyTypeObject *pytalloc_GetObjectType(void) -{ - static PyTypeObject *type = NULL; - PyObject *mod; - - if (type != NULL) { - return type; - } - - mod = PyImport_ImportModule("talloc"); - if (mod == NULL) { - return NULL; - } - - type = (PyTypeObject *)PyObject_GetAttrString(mod, "Object"); - Py_DECREF(mod); - - return type; -} - -_PUBLIC_ PyTypeObject *pytalloc_GetBaseObjectType(void) -{ - static PyTypeObject *type = NULL; - PyObject *mod; - - if (type != NULL) { - return type; - } - - mod = PyImport_ImportModule("talloc"); - if (mod == NULL) { - return NULL; - } - - type = (PyTypeObject *)PyObject_GetAttrString(mod, "BaseObject"); - Py_DECREF(mod); - - return type; -} - -static PyTypeObject *pytalloc_GetGenericObjectType(void) -{ - static PyTypeObject *type = NULL; - PyObject *mod; - - if (type != NULL) { - return type; - } - - mod = PyImport_ImportModule("talloc"); - if (mod == NULL) { - return NULL; - } - - type = (PyTypeObject *)PyObject_GetAttrString(mod, "GenericObject"); - Py_DECREF(mod); - - return type; -} - -/** - * Import an existing talloc pointer into a Python object. - */ -_PUBLIC_ PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, - void *ptr) -{ - return pytalloc_steal_or_reference(py_type, mem_ctx, ptr, true); -} - -/** - * Import an existing talloc pointer into a Python object. - */ -_PUBLIC_ PyObject *pytalloc_steal(PyTypeObject *py_type, void *ptr) -{ - return pytalloc_steal_or_reference(py_type, ptr, ptr, true); -} - - -/** - * Import an existing talloc pointer into a Python object, leaving the - * original parent, and creating a reference to the object in the python - * object. - * - * We remember the object we hold the reference to (a - * possibly-non-talloc pointer), the existing parent (typically the - * start of the array) and the new referenced parent. That way we can - * cope with the fact that we will have multiple parents, one per time - * python sees the object. - */ -_PUBLIC_ PyObject *pytalloc_reference_ex(PyTypeObject *py_type, - TALLOC_CTX *mem_ctx, void *ptr) -{ - return pytalloc_steal_or_reference(py_type, mem_ctx, ptr, false); -} - - -/** - * Internal function that either steals or referecences the talloc - * pointer into a new talloc context. - */ -static PyObject *pytalloc_steal_or_reference(PyTypeObject *py_type, - TALLOC_CTX *mem_ctx, void *ptr, bool steal) -{ - bool ok = false; - TALLOC_CTX *talloc_ctx = NULL; - bool is_baseobject = false; - PyObject *obj = NULL; - PyTypeObject *BaseObjectType = NULL, *ObjectType = NULL; - - BaseObjectType = pytalloc_GetBaseObjectType(); - if (BaseObjectType == NULL) { - goto err; - } - ObjectType = pytalloc_GetObjectType(); - if (ObjectType == NULL) { - goto err; - } - - /* this should have been tested by caller */ - if (mem_ctx == NULL) { - return PyErr_NoMemory(); - } - - is_baseobject = PyType_IsSubtype(py_type, BaseObjectType); - if (!is_baseobject) { - if (!PyType_IsSubtype(py_type, ObjectType)) { - PyErr_SetString(PyExc_TypeError, - "Expected type based on talloc"); - return NULL; - } - } - - obj = py_type->tp_alloc(py_type, 0); - if (obj == NULL) { - goto err; - } - - talloc_ctx = talloc_new(NULL); - if (talloc_ctx == NULL) { - PyErr_NoMemory(); - goto err; - } - - if (steal) { - ok = (talloc_steal(talloc_ctx, mem_ctx) != NULL); - } else { - ok = (talloc_reference(talloc_ctx, mem_ctx) != NULL); - } - if (!ok) { - goto err; - } - talloc_set_name_const(talloc_ctx, py_type->tp_name); - - if (is_baseobject) { - pytalloc_BaseObject *ret = (pytalloc_BaseObject*)obj; - ret->talloc_ctx = talloc_ctx; - ret->talloc_ptr_ctx = mem_ctx; - ret->ptr = ptr; - } else { - pytalloc_Object *ret = (pytalloc_Object*)obj; - ret->talloc_ctx = talloc_ctx; - ret->ptr = ptr; - } - return obj; - -err: - TALLOC_FREE(talloc_ctx); - Py_XDECREF(obj); - return NULL; -} - -/* - * Wrap a generic talloc pointer into a talloc.GenericObject, - * this is a subclass of talloc.BaseObject. - */ -_PUBLIC_ PyObject *pytalloc_GenericObject_steal_ex(TALLOC_CTX *mem_ctx, void *ptr) -{ - PyTypeObject *tp = pytalloc_GetGenericObjectType(); - return pytalloc_steal_ex(tp, mem_ctx, ptr); -} - -/* - * Wrap a generic talloc pointer into a talloc.GenericObject, - * this is a subclass of talloc.BaseObject. - */ -_PUBLIC_ PyObject *pytalloc_GenericObject_reference_ex(TALLOC_CTX *mem_ctx, void *ptr) -{ - PyTypeObject *tp = pytalloc_GetGenericObjectType(); - return pytalloc_reference_ex(tp, mem_ctx, ptr); -} - -_PUBLIC_ int pytalloc_Check(PyObject *obj) -{ - PyTypeObject *tp = pytalloc_GetObjectType(); - - return PyObject_TypeCheck(obj, tp); -} - -_PUBLIC_ int pytalloc_BaseObject_check(PyObject *obj) -{ - PyTypeObject *tp = pytalloc_GetBaseObjectType(); - - return PyObject_TypeCheck(obj, tp); -} - -_PUBLIC_ size_t pytalloc_BaseObject_size(void) -{ - return sizeof(pytalloc_BaseObject); -} - -static void *_pytalloc_get_checked_type(PyObject *py_obj, const char *type_name, - bool check_only, const char *function) -{ - TALLOC_CTX *mem_ctx; - void *ptr = NULL; - void *type_obj = talloc_check_name(ptr, type_name); - - mem_ctx = _pytalloc_get_mem_ctx(py_obj); - ptr = _pytalloc_get_ptr(py_obj); - - if (mem_ctx != ptr) { - if (check_only) { - return NULL; - } - - PyErr_Format(PyExc_TypeError, "%s: expected %s, " - "but the pointer is no talloc pointer, " - "pytalloc_get_ptr() would get the raw pointer.", - function, type_name); - return NULL; - } - - type_obj = talloc_check_name(ptr, type_name); - if (type_obj == NULL) { - const char *name = NULL; - - if (check_only) { - return NULL; - } - - name = talloc_get_name(ptr); - PyErr_Format(PyExc_TypeError, "%s: expected %s, got %s", - function, type_name, name); - return NULL; - } - - return ptr; -} - -_PUBLIC_ int _pytalloc_check_type(PyObject *py_obj, const char *type_name) -{ - void *ptr = NULL; - - ptr = _pytalloc_get_checked_type(py_obj, type_name, - true, /* check_only */ - "pytalloc_check_type"); - if (ptr == NULL) { - return 0; - } - - return 1; -} - -_PUBLIC_ void *_pytalloc_get_type(PyObject *py_obj, const char *type_name) -{ - return _pytalloc_get_checked_type(py_obj, type_name, - false, /* not check_only */ - "pytalloc_get_type"); -} - -_PUBLIC_ void *_pytalloc_get_ptr(PyObject *py_obj) -{ - if (pytalloc_BaseObject_check(py_obj)) { - return ((pytalloc_BaseObject *)py_obj)->ptr; - } - if (pytalloc_Check(py_obj)) { - return ((pytalloc_Object *)py_obj)->ptr; - } - return NULL; -} - -_PUBLIC_ TALLOC_CTX *_pytalloc_get_mem_ctx(PyObject *py_obj) -{ - if (pytalloc_BaseObject_check(py_obj)) { - return ((pytalloc_BaseObject *)py_obj)->talloc_ptr_ctx; - } - if (pytalloc_Check(py_obj)) { - return ((pytalloc_Object *)py_obj)->talloc_ctx; - } - return NULL; -} - -_PUBLIC_ int pytalloc_BaseObject_PyType_Ready(PyTypeObject *type) -{ - PyTypeObject *talloc_type = pytalloc_GetBaseObjectType(); - if (talloc_type == NULL) { - return -1; - } - - type->tp_base = talloc_type; - type->tp_basicsize = pytalloc_BaseObject_size(); - - return PyType_Ready(type); -} diff --git a/ldb-2.0.8/lib/talloc/talloc.c b/ldb-2.0.8/lib/talloc/talloc.c deleted file mode 100644 index 518ffbd..0000000 --- a/ldb-2.0.8/lib/talloc/talloc.c +++ /dev/null @@ -1,3050 +0,0 @@ -/* - Samba Unix SMB/CIFS implementation. - - Samba trivial allocation library - new interface - - NOTE: Please read talloc_guide.txt for full documentation - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Stefan Metzmacher 2006 - - ** NOTE! The following LGPL license applies to the talloc - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - inspired by http://swapped.cc/halloc/ -*/ - -#include "replace.h" -#include "talloc.h" - -#ifdef HAVE_SYS_AUXV_H -#include -#endif - -#if (TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR) -#error "TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR" -#endif - -#if (TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR) -#error "TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR" -#endif - -/* Special macros that are no-ops except when run under Valgrind on - * x86. They've moved a little bit from valgrind 1.0.4 to 1.9.4 */ -#ifdef HAVE_VALGRIND_MEMCHECK_H - /* memcheck.h includes valgrind.h */ -#include -#elif defined(HAVE_VALGRIND_H) -#include -#endif - -/* use this to force every realloc to change the pointer, to stress test - code that might not cope */ -#define ALWAYS_REALLOC 0 - - -#define MAX_TALLOC_SIZE 0x10000000 - -#define TALLOC_FLAG_FREE 0x01 -#define TALLOC_FLAG_LOOP 0x02 -#define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */ -#define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */ - -/* - * Bits above this are random, used to make it harder to fake talloc - * headers during an attack. Try not to change this without good reason. - */ -#define TALLOC_FLAG_MASK 0x0F - -#define TALLOC_MAGIC_REFERENCE ((const char *)1) - -#define TALLOC_MAGIC_BASE 0xe814ec70 -#define TALLOC_MAGIC_NON_RANDOM ( \ - ~TALLOC_FLAG_MASK & ( \ - TALLOC_MAGIC_BASE + \ - (TALLOC_BUILD_VERSION_MAJOR << 24) + \ - (TALLOC_BUILD_VERSION_MINOR << 16) + \ - (TALLOC_BUILD_VERSION_RELEASE << 8))) -static unsigned int talloc_magic = TALLOC_MAGIC_NON_RANDOM; - -/* by default we abort when given a bad pointer (such as when talloc_free() is called - on a pointer that came from malloc() */ -#ifndef TALLOC_ABORT -#define TALLOC_ABORT(reason) abort() -#endif - -#ifndef discard_const_p -#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) -# define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr))) -#else -# define discard_const_p(type, ptr) ((type *)(ptr)) -#endif -#endif - -/* these macros gain us a few percent of speed on gcc */ -#if (__GNUC__ >= 3) -/* the strange !! is to ensure that __builtin_expect() takes either 0 or 1 - as its first argument */ -#ifndef likely -#define likely(x) __builtin_expect(!!(x), 1) -#endif -#ifndef unlikely -#define unlikely(x) __builtin_expect(!!(x), 0) -#endif -#else -#ifndef likely -#define likely(x) (x) -#endif -#ifndef unlikely -#define unlikely(x) (x) -#endif -#endif - -/* this null_context is only used if talloc_enable_leak_report() or - talloc_enable_leak_report_full() is called, otherwise it remains - NULL -*/ -static void *null_context; -static bool talloc_report_null; -static bool talloc_report_null_full; -static void *autofree_context; - -static void talloc_setup_atexit(void); - -/* used to enable fill of memory on free, which can be useful for - * catching use after free errors when valgrind is too slow - */ -static struct { - bool initialised; - bool enabled; - uint8_t fill_value; -} talloc_fill; - -#define TALLOC_FILL_ENV "TALLOC_FREE_FILL" - -/* - * do not wipe the header, to allow the - * double-free logic to still work - */ -#define TC_INVALIDATE_FULL_FILL_CHUNK(_tc) do { \ - if (unlikely(talloc_fill.enabled)) { \ - size_t _flen = (_tc)->size; \ - char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \ - memset(_fptr, talloc_fill.fill_value, _flen); \ - } \ -} while (0) - -#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) -/* Mark the whole chunk as not accessable */ -#define TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc) do { \ - size_t _flen = TC_HDR_SIZE + (_tc)->size; \ - char *_fptr = (char *)(_tc); \ - VALGRIND_MAKE_MEM_NOACCESS(_fptr, _flen); \ -} while(0) -#else -#define TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc) do { } while (0) -#endif - -#define TC_INVALIDATE_FULL_CHUNK(_tc) do { \ - TC_INVALIDATE_FULL_FILL_CHUNK(_tc); \ - TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc); \ -} while (0) - -#define TC_INVALIDATE_SHRINK_FILL_CHUNK(_tc, _new_size) do { \ - if (unlikely(talloc_fill.enabled)) { \ - size_t _flen = (_tc)->size - (_new_size); \ - char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \ - _fptr += (_new_size); \ - memset(_fptr, talloc_fill.fill_value, _flen); \ - } \ -} while (0) - -#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) -/* Mark the unused bytes not accessable */ -#define TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { \ - size_t _flen = (_tc)->size - (_new_size); \ - char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \ - _fptr += (_new_size); \ - VALGRIND_MAKE_MEM_NOACCESS(_fptr, _flen); \ -} while (0) -#else -#define TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { } while (0) -#endif - -#define TC_INVALIDATE_SHRINK_CHUNK(_tc, _new_size) do { \ - TC_INVALIDATE_SHRINK_FILL_CHUNK(_tc, _new_size); \ - TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size); \ -} while (0) - -#define TC_UNDEFINE_SHRINK_FILL_CHUNK(_tc, _new_size) do { \ - if (unlikely(talloc_fill.enabled)) { \ - size_t _flen = (_tc)->size - (_new_size); \ - char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \ - _fptr += (_new_size); \ - memset(_fptr, talloc_fill.fill_value, _flen); \ - } \ -} while (0) - -#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) -/* Mark the unused bytes as undefined */ -#define TC_UNDEFINE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { \ - size_t _flen = (_tc)->size - (_new_size); \ - char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \ - _fptr += (_new_size); \ - VALGRIND_MAKE_MEM_UNDEFINED(_fptr, _flen); \ -} while (0) -#else -#define TC_UNDEFINE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { } while (0) -#endif - -#define TC_UNDEFINE_SHRINK_CHUNK(_tc, _new_size) do { \ - TC_UNDEFINE_SHRINK_FILL_CHUNK(_tc, _new_size); \ - TC_UNDEFINE_SHRINK_VALGRIND_CHUNK(_tc, _new_size); \ -} while (0) - -#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) -/* Mark the new bytes as undefined */ -#define TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size) do { \ - size_t _old_used = TC_HDR_SIZE + (_tc)->size; \ - size_t _new_used = TC_HDR_SIZE + (_new_size); \ - size_t _flen = _new_used - _old_used; \ - char *_fptr = _old_used + (char *)(_tc); \ - VALGRIND_MAKE_MEM_UNDEFINED(_fptr, _flen); \ -} while (0) -#else -#define TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size) do { } while (0) -#endif - -#define TC_UNDEFINE_GROW_CHUNK(_tc, _new_size) do { \ - TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size); \ -} while (0) - -struct talloc_reference_handle { - struct talloc_reference_handle *next, *prev; - void *ptr; - const char *location; -}; - -struct talloc_memlimit { - struct talloc_chunk *parent; - struct talloc_memlimit *upper; - size_t max_size; - size_t cur_size; -}; - -static inline bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size); -static inline void talloc_memlimit_grow(struct talloc_memlimit *limit, - size_t size); -static inline void talloc_memlimit_shrink(struct talloc_memlimit *limit, - size_t size); -static inline void tc_memlimit_update_on_free(struct talloc_chunk *tc); - -static inline void _tc_set_name_const(struct talloc_chunk *tc, - const char *name); -static struct talloc_chunk *_vasprintf_tc(const void *t, - const char *fmt, - va_list ap); - -typedef int (*talloc_destructor_t)(void *); - -struct talloc_pool_hdr; - -struct talloc_chunk { - /* - * flags includes the talloc magic, which is randomised to - * make overwrite attacks harder - */ - unsigned flags; - - /* - * If you have a logical tree like: - * - * - * / | \ - * / | \ - * / | \ - * - * - * The actual talloc tree is: - * - * - * | - * - - - * - * The children are linked with next/prev pointers, and - * child 1 is linked to the parent with parent/child - * pointers. - */ - - struct talloc_chunk *next, *prev; - struct talloc_chunk *parent, *child; - struct talloc_reference_handle *refs; - talloc_destructor_t destructor; - const char *name; - size_t size; - - /* - * limit semantics: - * if 'limit' is set it means all *new* children of the context will - * be limited to a total aggregate size ox max_size for memory - * allocations. - * cur_size is used to keep track of the current use - */ - struct talloc_memlimit *limit; - - /* - * For members of a pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool" - * is a pointer to the struct talloc_chunk of the pool that it was - * allocated from. This way children can quickly find the pool to chew - * from. - */ - struct talloc_pool_hdr *pool; -}; - -union talloc_chunk_cast_u { - uint8_t *ptr; - struct talloc_chunk *chunk; -}; - -/* 16 byte alignment seems to keep everyone happy */ -#define TC_ALIGN16(s) (((s)+15)&~15) -#define TC_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_chunk)) -#define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc)) - -_PUBLIC_ int talloc_version_major(void) -{ - return TALLOC_VERSION_MAJOR; -} - -_PUBLIC_ int talloc_version_minor(void) -{ - return TALLOC_VERSION_MINOR; -} - -_PUBLIC_ int talloc_test_get_magic(void) -{ - return talloc_magic; -} - -static inline void _talloc_chunk_set_free(struct talloc_chunk *tc, - const char *location) -{ - /* - * Mark this memory as free, and also over-stamp the talloc - * magic with the old-style magic. - * - * Why? This tries to avoid a memory read use-after-free from - * disclosing our talloc magic, which would then allow an - * attacker to prepare a valid header and so run a destructor. - * - */ - tc->flags = TALLOC_MAGIC_NON_RANDOM | TALLOC_FLAG_FREE - | (tc->flags & TALLOC_FLAG_MASK); - - /* we mark the freed memory with where we called the free - * from. This means on a double free error we can report where - * the first free came from - */ - if (location) { - tc->name = location; - } -} - -static inline void _talloc_chunk_set_not_free(struct talloc_chunk *tc) -{ - /* - * Mark this memory as not free. - * - * Why? This is memory either in a pool (and so available for - * talloc's re-use or after the realloc(). We need to mark - * the memory as free() before any realloc() call as we can't - * write to the memory after that. - * - * We put back the normal magic instead of the 'not random' - * magic. - */ - - tc->flags = talloc_magic | - ((tc->flags & TALLOC_FLAG_MASK) & ~TALLOC_FLAG_FREE); -} - -static void (*talloc_log_fn)(const char *message); - -_PUBLIC_ void talloc_set_log_fn(void (*log_fn)(const char *message)) -{ - talloc_log_fn = log_fn; -} - -#ifdef HAVE_CONSTRUCTOR_ATTRIBUTE -void talloc_lib_init(void) __attribute__((constructor)); -void talloc_lib_init(void) -{ - uint32_t random_value; -#if defined(HAVE_GETAUXVAL) && defined(AT_RANDOM) - uint8_t *p; - /* - * Use the kernel-provided random values used for - * ASLR. This won't change per-exec, which is ideal for us - */ - p = (uint8_t *) getauxval(AT_RANDOM); - if (p) { - /* - * We get 16 bytes from getauxval. By calling rand(), - * a totally insecure PRNG, but one that will - * deterministically have a different value when called - * twice, we ensure that if two talloc-like libraries - * are somehow loaded in the same address space, that - * because we choose different bytes, we will keep the - * protection against collision of multiple talloc - * libs. - * - * This protection is important because the effects of - * passing a talloc pointer from one to the other may - * be very hard to determine. - */ - int offset = rand() % (16 - sizeof(random_value)); - memcpy(&random_value, p + offset, sizeof(random_value)); - } else -#endif - { - /* - * Otherwise, hope the location we are loaded in - * memory is randomised by someone else - */ - random_value = ((uintptr_t)talloc_lib_init & 0xFFFFFFFF); - } - talloc_magic = random_value & ~TALLOC_FLAG_MASK; -} -#else -#warning "No __attribute__((constructor)) support found on this platform, additional talloc security measures not available" -#endif - -static void talloc_lib_atexit(void) -{ - TALLOC_FREE(autofree_context); - - if (talloc_total_size(null_context) == 0) { - return; - } - - if (talloc_report_null_full) { - talloc_report_full(null_context, stderr); - } else if (talloc_report_null) { - talloc_report(null_context, stderr); - } -} - -static void talloc_setup_atexit(void) -{ - static bool done; - - if (done) { - return; - } - - atexit(talloc_lib_atexit); - done = true; -} - -static void talloc_log(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2); -static void talloc_log(const char *fmt, ...) -{ - va_list ap; - char *message; - - if (!talloc_log_fn) { - return; - } - - va_start(ap, fmt); - message = talloc_vasprintf(NULL, fmt, ap); - va_end(ap); - - talloc_log_fn(message); - talloc_free(message); -} - -static void talloc_log_stderr(const char *message) -{ - fprintf(stderr, "%s", message); -} - -_PUBLIC_ void talloc_set_log_stderr(void) -{ - talloc_set_log_fn(talloc_log_stderr); -} - -static void (*talloc_abort_fn)(const char *reason); - -_PUBLIC_ void talloc_set_abort_fn(void (*abort_fn)(const char *reason)) -{ - talloc_abort_fn = abort_fn; -} - -static void talloc_abort(const char *reason) -{ - talloc_log("%s\n", reason); - - if (!talloc_abort_fn) { - TALLOC_ABORT(reason); - } - - talloc_abort_fn(reason); -} - -static void talloc_abort_access_after_free(void) -{ - talloc_abort("Bad talloc magic value - access after free"); -} - -static void talloc_abort_unknown_value(void) -{ - talloc_abort("Bad talloc magic value - unknown value"); -} - -/* panic if we get a bad magic value */ -static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr) -{ - const char *pp = (const char *)ptr; - struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE); - if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~TALLOC_FLAG_MASK)) != talloc_magic)) { - if ((tc->flags & (TALLOC_FLAG_FREE | ~TALLOC_FLAG_MASK)) - == (TALLOC_MAGIC_NON_RANDOM | TALLOC_FLAG_FREE)) { - talloc_log("talloc: access after free error - first free may be at %s\n", tc->name); - talloc_abort_access_after_free(); - return NULL; - } - - talloc_abort_unknown_value(); - return NULL; - } - return tc; -} - -/* hook into the front of the list */ -#define _TLIST_ADD(list, p) \ -do { \ - if (!(list)) { \ - (list) = (p); \ - (p)->next = (p)->prev = NULL; \ - } else { \ - (list)->prev = (p); \ - (p)->next = (list); \ - (p)->prev = NULL; \ - (list) = (p); \ - }\ -} while (0) - -/* remove an element from a list - element doesn't have to be in list. */ -#define _TLIST_REMOVE(list, p) \ -do { \ - if ((p) == (list)) { \ - (list) = (p)->next; \ - if (list) (list)->prev = NULL; \ - } else { \ - if ((p)->prev) (p)->prev->next = (p)->next; \ - if ((p)->next) (p)->next->prev = (p)->prev; \ - } \ - if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \ -} while (0) - - -/* - return the parent chunk of a pointer -*/ -static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr) -{ - struct talloc_chunk *tc; - - if (unlikely(ptr == NULL)) { - return NULL; - } - - tc = talloc_chunk_from_ptr(ptr); - while (tc->prev) tc=tc->prev; - - return tc->parent; -} - -_PUBLIC_ void *talloc_parent(const void *ptr) -{ - struct talloc_chunk *tc = talloc_parent_chunk(ptr); - return tc? TC_PTR_FROM_CHUNK(tc) : NULL; -} - -/* - find parents name -*/ -_PUBLIC_ const char *talloc_parent_name(const void *ptr) -{ - struct talloc_chunk *tc = talloc_parent_chunk(ptr); - return tc? tc->name : NULL; -} - -/* - A pool carries an in-pool object count count in the first 16 bytes. - bytes. This is done to support talloc_steal() to a parent outside of the - pool. The count includes the pool itself, so a talloc_free() on a pool will - only destroy the pool if the count has dropped to zero. A talloc_free() of a - pool member will reduce the count, and eventually also call free(3) on the - pool memory. - - The object count is not put into "struct talloc_chunk" because it is only - relevant for talloc pools and the alignment to 16 bytes would increase the - memory footprint of each talloc chunk by those 16 bytes. -*/ - -struct talloc_pool_hdr { - void *end; - unsigned int object_count; - size_t poolsize; -}; - -union talloc_pool_hdr_cast_u { - uint8_t *ptr; - struct talloc_pool_hdr *hdr; -}; - -#define TP_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_pool_hdr)) - -static inline struct talloc_pool_hdr *talloc_pool_from_chunk(struct talloc_chunk *c) -{ - union talloc_chunk_cast_u tcc = { .chunk = c }; - union talloc_pool_hdr_cast_u tphc = { tcc.ptr - TP_HDR_SIZE }; - return tphc.hdr; -} - -static inline struct talloc_chunk *talloc_chunk_from_pool(struct talloc_pool_hdr *h) -{ - union talloc_pool_hdr_cast_u tphc = { .hdr = h }; - union talloc_chunk_cast_u tcc = { .ptr = tphc.ptr + TP_HDR_SIZE }; - return tcc.chunk; -} - -static inline void *tc_pool_end(struct talloc_pool_hdr *pool_hdr) -{ - struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr); - return (char *)tc + TC_HDR_SIZE + pool_hdr->poolsize; -} - -static inline size_t tc_pool_space_left(struct talloc_pool_hdr *pool_hdr) -{ - return (char *)tc_pool_end(pool_hdr) - (char *)pool_hdr->end; -} - -/* If tc is inside a pool, this gives the next neighbour. */ -static inline void *tc_next_chunk(struct talloc_chunk *tc) -{ - return (char *)tc + TC_ALIGN16(TC_HDR_SIZE + tc->size); -} - -static inline void *tc_pool_first_chunk(struct talloc_pool_hdr *pool_hdr) -{ - struct talloc_chunk *tc = talloc_chunk_from_pool(pool_hdr); - return tc_next_chunk(tc); -} - -/* Mark the whole remaining pool as not accessable */ -static inline void tc_invalidate_pool(struct talloc_pool_hdr *pool_hdr) -{ - size_t flen = tc_pool_space_left(pool_hdr); - - if (unlikely(talloc_fill.enabled)) { - memset(pool_hdr->end, talloc_fill.fill_value, flen); - } - -#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS) - VALGRIND_MAKE_MEM_NOACCESS(pool_hdr->end, flen); -#endif -} - -/* - Allocate from a pool -*/ - -static inline struct talloc_chunk *tc_alloc_pool(struct talloc_chunk *parent, - size_t size, size_t prefix_len) -{ - struct talloc_pool_hdr *pool_hdr = NULL; - union talloc_chunk_cast_u tcc; - size_t space_left; - struct talloc_chunk *result; - size_t chunk_size; - - if (parent == NULL) { - return NULL; - } - - if (parent->flags & TALLOC_FLAG_POOL) { - pool_hdr = talloc_pool_from_chunk(parent); - } - else if (parent->flags & TALLOC_FLAG_POOLMEM) { - pool_hdr = parent->pool; - } - - if (pool_hdr == NULL) { - return NULL; - } - - space_left = tc_pool_space_left(pool_hdr); - - /* - * Align size to 16 bytes - */ - chunk_size = TC_ALIGN16(size + prefix_len); - - if (space_left < chunk_size) { - return NULL; - } - - tcc = (union talloc_chunk_cast_u) { - .ptr = ((uint8_t *)pool_hdr->end) + prefix_len - }; - result = tcc.chunk; - -#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) - VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, chunk_size); -#endif - - pool_hdr->end = (void *)((char *)pool_hdr->end + chunk_size); - - result->flags = talloc_magic | TALLOC_FLAG_POOLMEM; - result->pool = pool_hdr; - - pool_hdr->object_count++; - - return result; -} - -/* - Allocate a bit of memory as a child of an existing pointer -*/ -static inline void *__talloc_with_prefix(const void *context, - size_t size, - size_t prefix_len, - struct talloc_chunk **tc_ret) -{ - struct talloc_chunk *tc = NULL; - struct talloc_memlimit *limit = NULL; - size_t total_len = TC_HDR_SIZE + size + prefix_len; - struct talloc_chunk *parent = NULL; - - if (unlikely(context == NULL)) { - context = null_context; - } - - if (unlikely(size >= MAX_TALLOC_SIZE)) { - return NULL; - } - - if (unlikely(total_len < TC_HDR_SIZE)) { - return NULL; - } - - if (likely(context != NULL)) { - parent = talloc_chunk_from_ptr(context); - - if (parent->limit != NULL) { - limit = parent->limit; - } - - tc = tc_alloc_pool(parent, TC_HDR_SIZE+size, prefix_len); - } - - if (tc == NULL) { - uint8_t *ptr = NULL; - union talloc_chunk_cast_u tcc; - - /* - * Only do the memlimit check/update on actual allocation. - */ - if (!talloc_memlimit_check(limit, total_len)) { - errno = ENOMEM; - return NULL; - } - - ptr = malloc(total_len); - if (unlikely(ptr == NULL)) { - return NULL; - } - tcc = (union talloc_chunk_cast_u) { .ptr = ptr + prefix_len }; - tc = tcc.chunk; - tc->flags = talloc_magic; - tc->pool = NULL; - - talloc_memlimit_grow(limit, total_len); - } - - tc->limit = limit; - tc->size = size; - tc->destructor = NULL; - tc->child = NULL; - tc->name = NULL; - tc->refs = NULL; - - if (likely(context != NULL)) { - if (parent->child) { - parent->child->parent = NULL; - tc->next = parent->child; - tc->next->prev = tc; - } else { - tc->next = NULL; - } - tc->parent = parent; - tc->prev = NULL; - parent->child = tc; - } else { - tc->next = tc->prev = tc->parent = NULL; - } - - *tc_ret = tc; - return TC_PTR_FROM_CHUNK(tc); -} - -static inline void *__talloc(const void *context, - size_t size, - struct talloc_chunk **tc) -{ - return __talloc_with_prefix(context, size, 0, tc); -} - -/* - * Create a talloc pool - */ - -static inline void *_talloc_pool(const void *context, size_t size) -{ - struct talloc_chunk *tc; - struct talloc_pool_hdr *pool_hdr; - void *result; - - result = __talloc_with_prefix(context, size, TP_HDR_SIZE, &tc); - - if (unlikely(result == NULL)) { - return NULL; - } - - pool_hdr = talloc_pool_from_chunk(tc); - - tc->flags |= TALLOC_FLAG_POOL; - tc->size = 0; - - pool_hdr->object_count = 1; - pool_hdr->end = result; - pool_hdr->poolsize = size; - - tc_invalidate_pool(pool_hdr); - - return result; -} - -_PUBLIC_ void *talloc_pool(const void *context, size_t size) -{ - return _talloc_pool(context, size); -} - -/* - * Create a talloc pool correctly sized for a basic size plus - * a number of subobjects whose total size is given. Essentially - * a custom allocator for talloc to reduce fragmentation. - */ - -_PUBLIC_ void *_talloc_pooled_object(const void *ctx, - size_t type_size, - const char *type_name, - unsigned num_subobjects, - size_t total_subobjects_size) -{ - size_t poolsize, subobjects_slack, tmp; - struct talloc_chunk *tc; - struct talloc_pool_hdr *pool_hdr; - void *ret; - - poolsize = type_size + total_subobjects_size; - - if ((poolsize < type_size) || (poolsize < total_subobjects_size)) { - goto overflow; - } - - if (num_subobjects == UINT_MAX) { - goto overflow; - } - num_subobjects += 1; /* the object body itself */ - - /* - * Alignment can increase the pool size by at most 15 bytes per object - * plus alignment for the object itself - */ - subobjects_slack = (TC_HDR_SIZE + TP_HDR_SIZE + 15) * num_subobjects; - if (subobjects_slack < num_subobjects) { - goto overflow; - } - - tmp = poolsize + subobjects_slack; - if ((tmp < poolsize) || (tmp < subobjects_slack)) { - goto overflow; - } - poolsize = tmp; - - ret = _talloc_pool(ctx, poolsize); - if (ret == NULL) { - return NULL; - } - - tc = talloc_chunk_from_ptr(ret); - tc->size = type_size; - - pool_hdr = talloc_pool_from_chunk(tc); - -#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) - VALGRIND_MAKE_MEM_UNDEFINED(pool_hdr->end, type_size); -#endif - - pool_hdr->end = ((char *)pool_hdr->end + TC_ALIGN16(type_size)); - - _tc_set_name_const(tc, type_name); - return ret; - -overflow: - return NULL; -} - -/* - setup a destructor to be called on free of a pointer - the destructor should return 0 on success, or -1 on failure. - if the destructor fails then the free is failed, and the memory can - be continued to be used -*/ -_PUBLIC_ void _talloc_set_destructor(const void *ptr, int (*destructor)(void *)) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - tc->destructor = destructor; -} - -/* - increase the reference count on a piece of memory. -*/ -_PUBLIC_ int talloc_increase_ref_count(const void *ptr) -{ - if (unlikely(!talloc_reference(null_context, ptr))) { - return -1; - } - return 0; -} - -/* - helper for talloc_reference() - - this is referenced by a function pointer and should not be inline -*/ -static int talloc_reference_destructor(struct talloc_reference_handle *handle) -{ - struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr); - _TLIST_REMOVE(ptr_tc->refs, handle); - return 0; -} - -/* - more efficient way to add a name to a pointer - the name must point to a - true string constant -*/ -static inline void _tc_set_name_const(struct talloc_chunk *tc, - const char *name) -{ - tc->name = name; -} - -/* - internal talloc_named_const() -*/ -static inline void *_talloc_named_const(const void *context, size_t size, const char *name) -{ - void *ptr; - struct talloc_chunk *tc; - - ptr = __talloc(context, size, &tc); - if (unlikely(ptr == NULL)) { - return NULL; - } - - _tc_set_name_const(tc, name); - - return ptr; -} - -/* - make a secondary reference to a pointer, hanging off the given context. - the pointer remains valid until both the original caller and this given - context are freed. - - the major use for this is when two different structures need to reference the - same underlying data, and you want to be able to free the two instances separately, - and in either order -*/ -_PUBLIC_ void *_talloc_reference_loc(const void *context, const void *ptr, const char *location) -{ - struct talloc_chunk *tc; - struct talloc_reference_handle *handle; - if (unlikely(ptr == NULL)) return NULL; - - tc = talloc_chunk_from_ptr(ptr); - handle = (struct talloc_reference_handle *)_talloc_named_const(context, - sizeof(struct talloc_reference_handle), - TALLOC_MAGIC_REFERENCE); - if (unlikely(handle == NULL)) return NULL; - - /* note that we hang the destructor off the handle, not the - main context as that allows the caller to still setup their - own destructor on the context if they want to */ - talloc_set_destructor(handle, talloc_reference_destructor); - handle->ptr = discard_const_p(void, ptr); - handle->location = location; - _TLIST_ADD(tc->refs, handle); - return handle->ptr; -} - -static void *_talloc_steal_internal(const void *new_ctx, const void *ptr); - -static inline void _tc_free_poolmem(struct talloc_chunk *tc, - const char *location) -{ - struct talloc_pool_hdr *pool; - struct talloc_chunk *pool_tc; - void *next_tc; - - pool = tc->pool; - pool_tc = talloc_chunk_from_pool(pool); - next_tc = tc_next_chunk(tc); - - _talloc_chunk_set_free(tc, location); - - TC_INVALIDATE_FULL_CHUNK(tc); - - if (unlikely(pool->object_count == 0)) { - talloc_abort("Pool object count zero!"); - return; - } - - pool->object_count--; - - if (unlikely(pool->object_count == 1 - && !(pool_tc->flags & TALLOC_FLAG_FREE))) { - /* - * if there is just one object left in the pool - * and pool->flags does not have TALLOC_FLAG_FREE, - * it means this is the pool itself and - * the rest is available for new objects - * again. - */ - pool->end = tc_pool_first_chunk(pool); - tc_invalidate_pool(pool); - return; - } - - if (unlikely(pool->object_count == 0)) { - /* - * we mark the freed memory with where we called the free - * from. This means on a double free error we can report where - * the first free came from - */ - pool_tc->name = location; - - if (pool_tc->flags & TALLOC_FLAG_POOLMEM) { - _tc_free_poolmem(pool_tc, location); - } else { - /* - * The tc_memlimit_update_on_free() - * call takes into account the - * prefix TP_HDR_SIZE allocated before - * the pool talloc_chunk. - */ - tc_memlimit_update_on_free(pool_tc); - TC_INVALIDATE_FULL_CHUNK(pool_tc); - free(pool); - } - return; - } - - if (pool->end == next_tc) { - /* - * if pool->pool still points to end of - * 'tc' (which is stored in the 'next_tc' variable), - * we can reclaim the memory of 'tc'. - */ - pool->end = tc; - return; - } - - /* - * Do nothing. The memory is just "wasted", waiting for the pool - * itself to be freed. - */ -} - -static inline void _tc_free_children_internal(struct talloc_chunk *tc, - void *ptr, - const char *location); - -static inline int _talloc_free_internal(void *ptr, const char *location); - -/* - internal free call that takes a struct talloc_chunk *. -*/ -static inline int _tc_free_internal(struct talloc_chunk *tc, - const char *location) -{ - void *ptr_to_free; - void *ptr = TC_PTR_FROM_CHUNK(tc); - - if (unlikely(tc->refs)) { - int is_child; - /* check if this is a reference from a child or - * grandchild back to it's parent or grandparent - * - * in that case we need to remove the reference and - * call another instance of talloc_free() on the current - * pointer. - */ - is_child = talloc_is_parent(tc->refs, ptr); - _talloc_free_internal(tc->refs, location); - if (is_child) { - return _talloc_free_internal(ptr, location); - } - return -1; - } - - if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) { - /* we have a free loop - stop looping */ - return 0; - } - - if (unlikely(tc->destructor)) { - talloc_destructor_t d = tc->destructor; - - /* - * Protect the destructor against some overwrite - * attacks, by explicitly checking it has the right - * magic here. - */ - if (talloc_chunk_from_ptr(ptr) != tc) { - /* - * This can't actually happen, the - * call itself will panic. - */ - TALLOC_ABORT("talloc_chunk_from_ptr failed!"); - } - - if (d == (talloc_destructor_t)-1) { - return -1; - } - tc->destructor = (talloc_destructor_t)-1; - if (d(ptr) == -1) { - /* - * Only replace the destructor pointer if - * calling the destructor didn't modify it. - */ - if (tc->destructor == (talloc_destructor_t)-1) { - tc->destructor = d; - } - return -1; - } - tc->destructor = NULL; - } - - if (tc->parent) { - _TLIST_REMOVE(tc->parent->child, tc); - if (tc->parent->child) { - tc->parent->child->parent = tc->parent; - } - } else { - if (tc->prev) tc->prev->next = tc->next; - if (tc->next) tc->next->prev = tc->prev; - tc->prev = tc->next = NULL; - } - - tc->flags |= TALLOC_FLAG_LOOP; - - _tc_free_children_internal(tc, ptr, location); - - _talloc_chunk_set_free(tc, location); - - if (tc->flags & TALLOC_FLAG_POOL) { - struct talloc_pool_hdr *pool; - - pool = talloc_pool_from_chunk(tc); - - if (unlikely(pool->object_count == 0)) { - talloc_abort("Pool object count zero!"); - return 0; - } - - pool->object_count--; - - if (likely(pool->object_count != 0)) { - return 0; - } - - /* - * With object_count==0, a pool becomes a normal piece of - * memory to free. If it's allocated inside a pool, it needs - * to be freed as poolmem, else it needs to be just freed. - */ - ptr_to_free = pool; - } else { - ptr_to_free = tc; - } - - if (tc->flags & TALLOC_FLAG_POOLMEM) { - _tc_free_poolmem(tc, location); - return 0; - } - - tc_memlimit_update_on_free(tc); - - TC_INVALIDATE_FULL_CHUNK(tc); - free(ptr_to_free); - return 0; -} - -/* - internal talloc_free call -*/ -static inline int _talloc_free_internal(void *ptr, const char *location) -{ - struct talloc_chunk *tc; - - if (unlikely(ptr == NULL)) { - return -1; - } - - /* possibly initialised the talloc fill value */ - if (unlikely(!talloc_fill.initialised)) { - const char *fill = getenv(TALLOC_FILL_ENV); - if (fill != NULL) { - talloc_fill.enabled = true; - talloc_fill.fill_value = strtoul(fill, NULL, 0); - } - talloc_fill.initialised = true; - } - - tc = talloc_chunk_from_ptr(ptr); - return _tc_free_internal(tc, location); -} - -static inline size_t _talloc_total_limit_size(const void *ptr, - struct talloc_memlimit *old_limit, - struct talloc_memlimit *new_limit); - -/* - move a lump of memory from one talloc context to another return the - ptr on success, or NULL if it could not be transferred. - passing NULL as ptr will always return NULL with no side effects. -*/ -static void *_talloc_steal_internal(const void *new_ctx, const void *ptr) -{ - struct talloc_chunk *tc, *new_tc; - size_t ctx_size = 0; - - if (unlikely(!ptr)) { - return NULL; - } - - if (unlikely(new_ctx == NULL)) { - new_ctx = null_context; - } - - tc = talloc_chunk_from_ptr(ptr); - - if (tc->limit != NULL) { - - ctx_size = _talloc_total_limit_size(ptr, NULL, NULL); - - /* Decrement the memory limit from the source .. */ - talloc_memlimit_shrink(tc->limit->upper, ctx_size); - - if (tc->limit->parent == tc) { - tc->limit->upper = NULL; - } else { - tc->limit = NULL; - } - } - - if (unlikely(new_ctx == NULL)) { - if (tc->parent) { - _TLIST_REMOVE(tc->parent->child, tc); - if (tc->parent->child) { - tc->parent->child->parent = tc->parent; - } - } else { - if (tc->prev) tc->prev->next = tc->next; - if (tc->next) tc->next->prev = tc->prev; - } - - tc->parent = tc->next = tc->prev = NULL; - return discard_const_p(void, ptr); - } - - new_tc = talloc_chunk_from_ptr(new_ctx); - - if (unlikely(tc == new_tc || tc->parent == new_tc)) { - return discard_const_p(void, ptr); - } - - if (tc->parent) { - _TLIST_REMOVE(tc->parent->child, tc); - if (tc->parent->child) { - tc->parent->child->parent = tc->parent; - } - } else { - if (tc->prev) tc->prev->next = tc->next; - if (tc->next) tc->next->prev = tc->prev; - tc->prev = tc->next = NULL; - } - - tc->parent = new_tc; - if (new_tc->child) new_tc->child->parent = NULL; - _TLIST_ADD(new_tc->child, tc); - - if (tc->limit || new_tc->limit) { - ctx_size = _talloc_total_limit_size(ptr, tc->limit, - new_tc->limit); - /* .. and increment it in the destination. */ - if (new_tc->limit) { - talloc_memlimit_grow(new_tc->limit, ctx_size); - } - } - - return discard_const_p(void, ptr); -} - -/* - move a lump of memory from one talloc context to another return the - ptr on success, or NULL if it could not be transferred. - passing NULL as ptr will always return NULL with no side effects. -*/ -_PUBLIC_ void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const char *location) -{ - struct talloc_chunk *tc; - - if (unlikely(ptr == NULL)) { - return NULL; - } - - tc = talloc_chunk_from_ptr(ptr); - - if (unlikely(tc->refs != NULL) && talloc_parent(ptr) != new_ctx) { - struct talloc_reference_handle *h; - - talloc_log("WARNING: talloc_steal with references at %s\n", - location); - - for (h=tc->refs; h; h=h->next) { - talloc_log("\treference at %s\n", - h->location); - } - } - -#if 0 - /* this test is probably too expensive to have on in the - normal build, but it useful for debugging */ - if (talloc_is_parent(new_ctx, ptr)) { - talloc_log("WARNING: stealing into talloc child at %s\n", location); - } -#endif - - return _talloc_steal_internal(new_ctx, ptr); -} - -/* - this is like a talloc_steal(), but you must supply the old - parent. This resolves the ambiguity in a talloc_steal() which is - called on a context that has more than one parent (via references) - - The old parent can be either a reference or a parent -*/ -_PUBLIC_ void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr) -{ - struct talloc_chunk *tc; - struct talloc_reference_handle *h; - - if (unlikely(ptr == NULL)) { - return NULL; - } - - if (old_parent == talloc_parent(ptr)) { - return _talloc_steal_internal(new_parent, ptr); - } - - tc = talloc_chunk_from_ptr(ptr); - for (h=tc->refs;h;h=h->next) { - if (talloc_parent(h) == old_parent) { - if (_talloc_steal_internal(new_parent, h) != h) { - return NULL; - } - return discard_const_p(void, ptr); - } - } - - /* it wasn't a parent */ - return NULL; -} - -/* - remove a secondary reference to a pointer. This undo's what - talloc_reference() has done. The context and pointer arguments - must match those given to a talloc_reference() -*/ -static inline int talloc_unreference(const void *context, const void *ptr) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - struct talloc_reference_handle *h; - - if (unlikely(context == NULL)) { - context = null_context; - } - - for (h=tc->refs;h;h=h->next) { - struct talloc_chunk *p = talloc_parent_chunk(h); - if (p == NULL) { - if (context == NULL) break; - } else if (TC_PTR_FROM_CHUNK(p) == context) { - break; - } - } - if (h == NULL) { - return -1; - } - - return _talloc_free_internal(h, __location__); -} - -/* - remove a specific parent context from a pointer. This is a more - controlled variant of talloc_free() -*/ -_PUBLIC_ int talloc_unlink(const void *context, void *ptr) -{ - struct talloc_chunk *tc_p, *new_p, *tc_c; - void *new_parent; - - if (ptr == NULL) { - return -1; - } - - if (context == NULL) { - context = null_context; - } - - if (talloc_unreference(context, ptr) == 0) { - return 0; - } - - if (context != NULL) { - tc_c = talloc_chunk_from_ptr(context); - } else { - tc_c = NULL; - } - if (tc_c != talloc_parent_chunk(ptr)) { - return -1; - } - - tc_p = talloc_chunk_from_ptr(ptr); - - if (tc_p->refs == NULL) { - return _talloc_free_internal(ptr, __location__); - } - - new_p = talloc_parent_chunk(tc_p->refs); - if (new_p) { - new_parent = TC_PTR_FROM_CHUNK(new_p); - } else { - new_parent = NULL; - } - - if (talloc_unreference(new_parent, ptr) != 0) { - return -1; - } - - _talloc_steal_internal(new_parent, ptr); - - return 0; -} - -/* - add a name to an existing pointer - va_list version -*/ -static inline const char *tc_set_name_v(struct talloc_chunk *tc, - const char *fmt, - va_list ap) PRINTF_ATTRIBUTE(2,0); - -static inline const char *tc_set_name_v(struct talloc_chunk *tc, - const char *fmt, - va_list ap) -{ - struct talloc_chunk *name_tc = _vasprintf_tc(TC_PTR_FROM_CHUNK(tc), - fmt, - ap); - if (likely(name_tc)) { - tc->name = TC_PTR_FROM_CHUNK(name_tc); - _tc_set_name_const(name_tc, ".name"); - } else { - tc->name = NULL; - } - return tc->name; -} - -/* - add a name to an existing pointer -*/ -_PUBLIC_ const char *talloc_set_name(const void *ptr, const char *fmt, ...) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - const char *name; - va_list ap; - va_start(ap, fmt); - name = tc_set_name_v(tc, fmt, ap); - va_end(ap); - return name; -} - - -/* - create a named talloc pointer. Any talloc pointer can be named, and - talloc_named() operates just like talloc() except that it allows you - to name the pointer. -*/ -_PUBLIC_ void *talloc_named(const void *context, size_t size, const char *fmt, ...) -{ - va_list ap; - void *ptr; - const char *name; - struct talloc_chunk *tc; - - ptr = __talloc(context, size, &tc); - if (unlikely(ptr == NULL)) return NULL; - - va_start(ap, fmt); - name = tc_set_name_v(tc, fmt, ap); - va_end(ap); - - if (unlikely(name == NULL)) { - _talloc_free_internal(ptr, __location__); - return NULL; - } - - return ptr; -} - -/* - return the name of a talloc ptr, or "UNNAMED" -*/ -static inline const char *__talloc_get_name(const void *ptr) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) { - return ".reference"; - } - if (likely(tc->name)) { - return tc->name; - } - return "UNNAMED"; -} - -_PUBLIC_ const char *talloc_get_name(const void *ptr) -{ - return __talloc_get_name(ptr); -} - -/* - check if a pointer has the given name. If it does, return the pointer, - otherwise return NULL -*/ -_PUBLIC_ void *talloc_check_name(const void *ptr, const char *name) -{ - const char *pname; - if (unlikely(ptr == NULL)) return NULL; - pname = __talloc_get_name(ptr); - if (likely(pname == name || strcmp(pname, name) == 0)) { - return discard_const_p(void, ptr); - } - return NULL; -} - -static void talloc_abort_type_mismatch(const char *location, - const char *name, - const char *expected) -{ - const char *reason; - - reason = talloc_asprintf(NULL, - "%s: Type mismatch: name[%s] expected[%s]", - location, - name?name:"NULL", - expected); - if (!reason) { - reason = "Type mismatch"; - } - - talloc_abort(reason); -} - -_PUBLIC_ void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location) -{ - const char *pname; - - if (unlikely(ptr == NULL)) { - talloc_abort_type_mismatch(location, NULL, name); - return NULL; - } - - pname = __talloc_get_name(ptr); - if (likely(pname == name || strcmp(pname, name) == 0)) { - return discard_const_p(void, ptr); - } - - talloc_abort_type_mismatch(location, pname, name); - return NULL; -} - -/* - this is for compatibility with older versions of talloc -*/ -_PUBLIC_ void *talloc_init(const char *fmt, ...) -{ - va_list ap; - void *ptr; - const char *name; - struct talloc_chunk *tc; - - ptr = __talloc(NULL, 0, &tc); - if (unlikely(ptr == NULL)) return NULL; - - va_start(ap, fmt); - name = tc_set_name_v(tc, fmt, ap); - va_end(ap); - - if (unlikely(name == NULL)) { - _talloc_free_internal(ptr, __location__); - return NULL; - } - - return ptr; -} - -static inline void _tc_free_children_internal(struct talloc_chunk *tc, - void *ptr, - const char *location) -{ - while (tc->child) { - /* we need to work out who will own an abandoned child - if it cannot be freed. In priority order, the first - choice is owner of any remaining reference to this - pointer, the second choice is our parent, and the - final choice is the null context. */ - void *child = TC_PTR_FROM_CHUNK(tc->child); - const void *new_parent = null_context; - if (unlikely(tc->child->refs)) { - struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs); - if (p) new_parent = TC_PTR_FROM_CHUNK(p); - } - if (unlikely(_tc_free_internal(tc->child, location) == -1)) { - if (talloc_parent_chunk(child) != tc) { - /* - * Destructor already reparented this child. - * No further reparenting needed. - */ - continue; - } - if (new_parent == null_context) { - struct talloc_chunk *p = talloc_parent_chunk(ptr); - if (p) new_parent = TC_PTR_FROM_CHUNK(p); - } - _talloc_steal_internal(new_parent, child); - } - } -} - -/* - this is a replacement for the Samba3 talloc_destroy_pool functionality. It - should probably not be used in new code. It's in here to keep the talloc - code consistent across Samba 3 and 4. -*/ -_PUBLIC_ void talloc_free_children(void *ptr) -{ - struct talloc_chunk *tc_name = NULL; - struct talloc_chunk *tc; - - if (unlikely(ptr == NULL)) { - return; - } - - tc = talloc_chunk_from_ptr(ptr); - - /* we do not want to free the context name if it is a child .. */ - if (likely(tc->child)) { - for (tc_name = tc->child; tc_name; tc_name = tc_name->next) { - if (tc->name == TC_PTR_FROM_CHUNK(tc_name)) break; - } - if (tc_name) { - _TLIST_REMOVE(tc->child, tc_name); - if (tc->child) { - tc->child->parent = tc; - } - } - } - - _tc_free_children_internal(tc, ptr, __location__); - - /* .. so we put it back after all other children have been freed */ - if (tc_name) { - if (tc->child) { - tc->child->parent = NULL; - } - tc_name->parent = tc; - _TLIST_ADD(tc->child, tc_name); - } -} - -/* - Allocate a bit of memory as a child of an existing pointer -*/ -_PUBLIC_ void *_talloc(const void *context, size_t size) -{ - struct talloc_chunk *tc; - return __talloc(context, size, &tc); -} - -/* - externally callable talloc_set_name_const() -*/ -_PUBLIC_ void talloc_set_name_const(const void *ptr, const char *name) -{ - _tc_set_name_const(talloc_chunk_from_ptr(ptr), name); -} - -/* - create a named talloc pointer. Any talloc pointer can be named, and - talloc_named() operates just like talloc() except that it allows you - to name the pointer. -*/ -_PUBLIC_ void *talloc_named_const(const void *context, size_t size, const char *name) -{ - return _talloc_named_const(context, size, name); -} - -/* - free a talloc pointer. This also frees all child pointers of this - pointer recursively - - return 0 if the memory is actually freed, otherwise -1. The memory - will not be freed if the ref_count is > 1 or the destructor (if - any) returns non-zero -*/ -_PUBLIC_ int _talloc_free(void *ptr, const char *location) -{ - struct talloc_chunk *tc; - - if (unlikely(ptr == NULL)) { - return -1; - } - - tc = talloc_chunk_from_ptr(ptr); - - if (unlikely(tc->refs != NULL)) { - struct talloc_reference_handle *h; - - if (talloc_parent(ptr) == null_context && tc->refs->next == NULL) { - /* in this case we do know which parent should - get this pointer, as there is really only - one parent */ - return talloc_unlink(null_context, ptr); - } - - talloc_log("ERROR: talloc_free with references at %s\n", - location); - - for (h=tc->refs; h; h=h->next) { - talloc_log("\treference at %s\n", - h->location); - } - return -1; - } - - return _talloc_free_internal(ptr, location); -} - - - -/* - A talloc version of realloc. The context argument is only used if - ptr is NULL -*/ -_PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name) -{ - struct talloc_chunk *tc; - void *new_ptr; - bool malloced = false; - struct talloc_pool_hdr *pool_hdr = NULL; - size_t old_size = 0; - size_t new_size = 0; - - /* size zero is equivalent to free() */ - if (unlikely(size == 0)) { - talloc_unlink(context, ptr); - return NULL; - } - - if (unlikely(size >= MAX_TALLOC_SIZE)) { - return NULL; - } - - /* realloc(NULL) is equivalent to malloc() */ - if (ptr == NULL) { - return _talloc_named_const(context, size, name); - } - - tc = talloc_chunk_from_ptr(ptr); - - /* don't allow realloc on referenced pointers */ - if (unlikely(tc->refs)) { - return NULL; - } - - /* don't let anybody try to realloc a talloc_pool */ - if (unlikely(tc->flags & TALLOC_FLAG_POOL)) { - return NULL; - } - - if (tc->limit && (size > tc->size)) { - if (!talloc_memlimit_check(tc->limit, (size - tc->size))) { - errno = ENOMEM; - return NULL; - } - } - - /* handle realloc inside a talloc_pool */ - if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) { - pool_hdr = tc->pool; - } - -#if (ALWAYS_REALLOC == 0) - /* don't shrink if we have less than 1k to gain */ - if (size < tc->size && tc->limit == NULL) { - if (pool_hdr) { - void *next_tc = tc_next_chunk(tc); - TC_INVALIDATE_SHRINK_CHUNK(tc, size); - tc->size = size; - if (next_tc == pool_hdr->end) { - /* note: tc->size has changed, so this works */ - pool_hdr->end = tc_next_chunk(tc); - } - return ptr; - } else if ((tc->size - size) < 1024) { - /* - * if we call TC_INVALIDATE_SHRINK_CHUNK() here - * we would need to call TC_UNDEFINE_GROW_CHUNK() - * after each realloc call, which slows down - * testing a lot :-(. - * - * That is why we only mark memory as undefined here. - */ - TC_UNDEFINE_SHRINK_CHUNK(tc, size); - - /* do not shrink if we have less than 1k to gain */ - tc->size = size; - return ptr; - } - } else if (tc->size == size) { - /* - * do not change the pointer if it is exactly - * the same size. - */ - return ptr; - } -#endif - - /* - * by resetting magic we catch users of the old memory - * - * We mark this memory as free, and also over-stamp the talloc - * magic with the old-style magic. - * - * Why? This tries to avoid a memory read use-after-free from - * disclosing our talloc magic, which would then allow an - * attacker to prepare a valid header and so run a destructor. - * - * What else? We have to re-stamp back a valid normal magic - * on this memory once realloc() is done, as it will have done - * a memcpy() into the new valid memory. We can't do this in - * reverse as that would be a real use-after-free. - */ - _talloc_chunk_set_free(tc, NULL); - -#if ALWAYS_REALLOC - if (pool_hdr) { - new_ptr = tc_alloc_pool(tc, size + TC_HDR_SIZE, 0); - pool_hdr->object_count--; - - if (new_ptr == NULL) { - new_ptr = malloc(TC_HDR_SIZE+size); - malloced = true; - new_size = size; - } - - if (new_ptr) { - memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE); - TC_INVALIDATE_FULL_CHUNK(tc); - } - } else { - /* We're doing malloc then free here, so record the difference. */ - old_size = tc->size; - new_size = size; - new_ptr = malloc(size + TC_HDR_SIZE); - if (new_ptr) { - memcpy(new_ptr, tc, MIN(tc->size, size) + TC_HDR_SIZE); - free(tc); - } - } -#else - if (pool_hdr) { - struct talloc_chunk *pool_tc; - void *next_tc = tc_next_chunk(tc); - size_t old_chunk_size = TC_ALIGN16(TC_HDR_SIZE + tc->size); - size_t new_chunk_size = TC_ALIGN16(TC_HDR_SIZE + size); - size_t space_needed; - size_t space_left; - unsigned int chunk_count = pool_hdr->object_count; - - pool_tc = talloc_chunk_from_pool(pool_hdr); - if (!(pool_tc->flags & TALLOC_FLAG_FREE)) { - chunk_count -= 1; - } - - if (chunk_count == 1) { - /* - * optimize for the case where 'tc' is the only - * chunk in the pool. - */ - char *start = tc_pool_first_chunk(pool_hdr); - space_needed = new_chunk_size; - space_left = (char *)tc_pool_end(pool_hdr) - start; - - if (space_left >= space_needed) { - size_t old_used = TC_HDR_SIZE + tc->size; - size_t new_used = TC_HDR_SIZE + size; - new_ptr = start; - -#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED) - { - /* - * The area from - * start -> tc may have - * been freed and thus been marked as - * VALGRIND_MEM_NOACCESS. Set it to - * VALGRIND_MEM_UNDEFINED so we can - * copy into it without valgrind errors. - * We can't just mark - * new_ptr -> new_ptr + old_used - * as this may overlap on top of tc, - * (which is why we use memmove, not - * memcpy below) hence the MIN. - */ - size_t undef_len = MIN((((char *)tc) - ((char *)new_ptr)),old_used); - VALGRIND_MAKE_MEM_UNDEFINED(new_ptr, undef_len); - } -#endif - - memmove(new_ptr, tc, old_used); - - tc = (struct talloc_chunk *)new_ptr; - TC_UNDEFINE_GROW_CHUNK(tc, size); - - /* - * first we do not align the pool pointer - * because we want to invalidate the padding - * too. - */ - pool_hdr->end = new_used + (char *)new_ptr; - tc_invalidate_pool(pool_hdr); - - /* now the aligned pointer */ - pool_hdr->end = new_chunk_size + (char *)new_ptr; - goto got_new_ptr; - } - - next_tc = NULL; - } - - if (new_chunk_size == old_chunk_size) { - TC_UNDEFINE_GROW_CHUNK(tc, size); - _talloc_chunk_set_not_free(tc); - tc->size = size; - return ptr; - } - - if (next_tc == pool_hdr->end) { - /* - * optimize for the case where 'tc' is the last - * chunk in the pool. - */ - space_needed = new_chunk_size - old_chunk_size; - space_left = tc_pool_space_left(pool_hdr); - - if (space_left >= space_needed) { - TC_UNDEFINE_GROW_CHUNK(tc, size); - _talloc_chunk_set_not_free(tc); - tc->size = size; - pool_hdr->end = tc_next_chunk(tc); - return ptr; - } - } - - new_ptr = tc_alloc_pool(tc, size + TC_HDR_SIZE, 0); - - if (new_ptr == NULL) { - new_ptr = malloc(TC_HDR_SIZE+size); - malloced = true; - new_size = size; - } - - if (new_ptr) { - memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE); - - _tc_free_poolmem(tc, __location__ "_talloc_realloc"); - } - } - else { - /* We're doing realloc here, so record the difference. */ - old_size = tc->size; - new_size = size; - new_ptr = realloc(tc, size + TC_HDR_SIZE); - } -got_new_ptr: -#endif - if (unlikely(!new_ptr)) { - /* - * Ok, this is a strange spot. We have to put back - * the old talloc_magic and any flags, except the - * TALLOC_FLAG_FREE as this was not free'ed by the - * realloc() call after all - */ - _talloc_chunk_set_not_free(tc); - return NULL; - } - - /* - * tc is now the new value from realloc(), the old memory we - * can't access any more and was preemptively marked as - * TALLOC_FLAG_FREE before the call. Now we mark it as not - * free again - */ - tc = (struct talloc_chunk *)new_ptr; - _talloc_chunk_set_not_free(tc); - if (malloced) { - tc->flags &= ~TALLOC_FLAG_POOLMEM; - } - if (tc->parent) { - tc->parent->child = tc; - } - if (tc->child) { - tc->child->parent = tc; - } - - if (tc->prev) { - tc->prev->next = tc; - } - if (tc->next) { - tc->next->prev = tc; - } - - if (new_size > old_size) { - talloc_memlimit_grow(tc->limit, new_size - old_size); - } else if (new_size < old_size) { - talloc_memlimit_shrink(tc->limit, old_size - new_size); - } - - tc->size = size; - _tc_set_name_const(tc, name); - - return TC_PTR_FROM_CHUNK(tc); -} - -/* - a wrapper around talloc_steal() for situations where you are moving a pointer - between two structures, and want the old pointer to be set to NULL -*/ -_PUBLIC_ void *_talloc_move(const void *new_ctx, const void *_pptr) -{ - const void **pptr = discard_const_p(const void *,_pptr); - void *ret = talloc_steal(new_ctx, discard_const_p(void, *pptr)); - (*pptr) = NULL; - return ret; -} - -enum talloc_mem_count_type { - TOTAL_MEM_SIZE, - TOTAL_MEM_BLOCKS, - TOTAL_MEM_LIMIT, -}; - -static inline size_t _talloc_total_mem_internal(const void *ptr, - enum talloc_mem_count_type type, - struct talloc_memlimit *old_limit, - struct talloc_memlimit *new_limit) -{ - size_t total = 0; - struct talloc_chunk *c, *tc; - - if (ptr == NULL) { - ptr = null_context; - } - if (ptr == NULL) { - return 0; - } - - tc = talloc_chunk_from_ptr(ptr); - - if (old_limit || new_limit) { - if (tc->limit && tc->limit->upper == old_limit) { - tc->limit->upper = new_limit; - } - } - - /* optimize in the memlimits case */ - if (type == TOTAL_MEM_LIMIT && - tc->limit != NULL && - tc->limit != old_limit && - tc->limit->parent == tc) { - return tc->limit->cur_size; - } - - if (tc->flags & TALLOC_FLAG_LOOP) { - return 0; - } - - tc->flags |= TALLOC_FLAG_LOOP; - - if (old_limit || new_limit) { - if (old_limit == tc->limit) { - tc->limit = new_limit; - } - } - - switch (type) { - case TOTAL_MEM_SIZE: - if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) { - total = tc->size; - } - break; - case TOTAL_MEM_BLOCKS: - total++; - break; - case TOTAL_MEM_LIMIT: - if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) { - /* - * Don't count memory allocated from a pool - * when calculating limits. Only count the - * pool itself. - */ - if (!(tc->flags & TALLOC_FLAG_POOLMEM)) { - if (tc->flags & TALLOC_FLAG_POOL) { - /* - * If this is a pool, the allocated - * size is in the pool header, and - * remember to add in the prefix - * length. - */ - struct talloc_pool_hdr *pool_hdr - = talloc_pool_from_chunk(tc); - total = pool_hdr->poolsize + - TC_HDR_SIZE + - TP_HDR_SIZE; - } else { - total = tc->size + TC_HDR_SIZE; - } - } - } - break; - } - for (c = tc->child; c; c = c->next) { - total += _talloc_total_mem_internal(TC_PTR_FROM_CHUNK(c), type, - old_limit, new_limit); - } - - tc->flags &= ~TALLOC_FLAG_LOOP; - - return total; -} - -/* - return the total size of a talloc pool (subtree) -*/ -_PUBLIC_ size_t talloc_total_size(const void *ptr) -{ - return _talloc_total_mem_internal(ptr, TOTAL_MEM_SIZE, NULL, NULL); -} - -/* - return the total number of blocks in a talloc pool (subtree) -*/ -_PUBLIC_ size_t talloc_total_blocks(const void *ptr) -{ - return _talloc_total_mem_internal(ptr, TOTAL_MEM_BLOCKS, NULL, NULL); -} - -/* - return the number of external references to a pointer -*/ -_PUBLIC_ size_t talloc_reference_count(const void *ptr) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr); - struct talloc_reference_handle *h; - size_t ret = 0; - - for (h=tc->refs;h;h=h->next) { - ret++; - } - return ret; -} - -/* - report on memory usage by all children of a pointer, giving a full tree view -*/ -_PUBLIC_ void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, - void (*callback)(const void *ptr, - int depth, int max_depth, - int is_ref, - void *private_data), - void *private_data) -{ - struct talloc_chunk *c, *tc; - - if (ptr == NULL) { - ptr = null_context; - } - if (ptr == NULL) return; - - tc = talloc_chunk_from_ptr(ptr); - - if (tc->flags & TALLOC_FLAG_LOOP) { - return; - } - - callback(ptr, depth, max_depth, 0, private_data); - - if (max_depth >= 0 && depth >= max_depth) { - return; - } - - tc->flags |= TALLOC_FLAG_LOOP; - for (c=tc->child;c;c=c->next) { - if (c->name == TALLOC_MAGIC_REFERENCE) { - struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c); - callback(h->ptr, depth + 1, max_depth, 1, private_data); - } else { - talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data); - } - } - tc->flags &= ~TALLOC_FLAG_LOOP; -} - -static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f) -{ - const char *name = __talloc_get_name(ptr); - struct talloc_chunk *tc; - FILE *f = (FILE *)_f; - - if (is_ref) { - fprintf(f, "%*sreference to: %s\n", depth*4, "", name); - return; - } - - tc = talloc_chunk_from_ptr(ptr); - if (tc->limit && tc->limit->parent == tc) { - fprintf(f, "%*s%-30s is a memlimit context" - " (max_size = %lu bytes, cur_size = %lu bytes)\n", - depth*4, "", - name, - (unsigned long)tc->limit->max_size, - (unsigned long)tc->limit->cur_size); - } - - if (depth == 0) { - fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", - (max_depth < 0 ? "full " :""), name, - (unsigned long)talloc_total_size(ptr), - (unsigned long)talloc_total_blocks(ptr)); - return; - } - - fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n", - depth*4, "", - name, - (unsigned long)talloc_total_size(ptr), - (unsigned long)talloc_total_blocks(ptr), - (int)talloc_reference_count(ptr), ptr); - -#if 0 - fprintf(f, "content: "); - if (talloc_total_size(ptr)) { - int tot = talloc_total_size(ptr); - int i; - - for (i = 0; i < tot; i++) { - if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) { - fprintf(f, "%c", ((char *)ptr)[i]); - } else { - fprintf(f, "~%02x", ((char *)ptr)[i]); - } - } - } - fprintf(f, "\n"); -#endif -} - -/* - report on memory usage by all children of a pointer, giving a full tree view -*/ -_PUBLIC_ void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f) -{ - if (f) { - talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f); - fflush(f); - } -} - -/* - report on memory usage by all children of a pointer, giving a full tree view -*/ -_PUBLIC_ void talloc_report_full(const void *ptr, FILE *f) -{ - talloc_report_depth_file(ptr, 0, -1, f); -} - -/* - report on memory usage by all children of a pointer -*/ -_PUBLIC_ void talloc_report(const void *ptr, FILE *f) -{ - talloc_report_depth_file(ptr, 0, 1, f); -} - -/* - enable tracking of the NULL context -*/ -_PUBLIC_ void talloc_enable_null_tracking(void) -{ - if (null_context == NULL) { - null_context = _talloc_named_const(NULL, 0, "null_context"); - if (autofree_context != NULL) { - talloc_reparent(NULL, null_context, autofree_context); - } - } -} - -/* - enable tracking of the NULL context, not moving the autofree context - into the NULL context. This is needed for the talloc testsuite -*/ -_PUBLIC_ void talloc_enable_null_tracking_no_autofree(void) -{ - if (null_context == NULL) { - null_context = _talloc_named_const(NULL, 0, "null_context"); - } -} - -/* - disable tracking of the NULL context -*/ -_PUBLIC_ void talloc_disable_null_tracking(void) -{ - if (null_context != NULL) { - /* we have to move any children onto the real NULL - context */ - struct talloc_chunk *tc, *tc2; - tc = talloc_chunk_from_ptr(null_context); - for (tc2 = tc->child; tc2; tc2=tc2->next) { - if (tc2->parent == tc) tc2->parent = NULL; - if (tc2->prev == tc) tc2->prev = NULL; - } - for (tc2 = tc->next; tc2; tc2=tc2->next) { - if (tc2->parent == tc) tc2->parent = NULL; - if (tc2->prev == tc) tc2->prev = NULL; - } - tc->child = NULL; - tc->next = NULL; - } - talloc_free(null_context); - null_context = NULL; -} - -/* - enable leak reporting on exit -*/ -_PUBLIC_ void talloc_enable_leak_report(void) -{ - talloc_enable_null_tracking(); - talloc_report_null = true; - talloc_setup_atexit(); -} - -/* - enable full leak reporting on exit -*/ -_PUBLIC_ void talloc_enable_leak_report_full(void) -{ - talloc_enable_null_tracking(); - talloc_report_null_full = true; - talloc_setup_atexit(); -} - -/* - talloc and zero memory. -*/ -_PUBLIC_ void *_talloc_zero(const void *ctx, size_t size, const char *name) -{ - void *p = _talloc_named_const(ctx, size, name); - - if (p) { - memset(p, '\0', size); - } - - return p; -} - -/* - memdup with a talloc. -*/ -_PUBLIC_ void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name) -{ - void *newp = NULL; - - if (likely(size > 0) && unlikely(p == NULL)) { - return NULL; - } - - newp = _talloc_named_const(t, size, name); - if (likely(newp != NULL) && likely(size > 0)) { - memcpy(newp, p, size); - } - - return newp; -} - -static inline char *__talloc_strlendup(const void *t, const char *p, size_t len) -{ - char *ret; - struct talloc_chunk *tc; - - ret = (char *)__talloc(t, len + 1, &tc); - if (unlikely(!ret)) return NULL; - - memcpy(ret, p, len); - ret[len] = 0; - - _tc_set_name_const(tc, ret); - return ret; -} - -/* - strdup with a talloc -*/ -_PUBLIC_ char *talloc_strdup(const void *t, const char *p) -{ - if (unlikely(!p)) return NULL; - return __talloc_strlendup(t, p, strlen(p)); -} - -/* - strndup with a talloc -*/ -_PUBLIC_ char *talloc_strndup(const void *t, const char *p, size_t n) -{ - if (unlikely(!p)) return NULL; - return __talloc_strlendup(t, p, strnlen(p, n)); -} - -static inline char *__talloc_strlendup_append(char *s, size_t slen, - const char *a, size_t alen) -{ - char *ret; - - ret = talloc_realloc(NULL, s, char, slen + alen + 1); - if (unlikely(!ret)) return NULL; - - /* append the string and the trailing \0 */ - memcpy(&ret[slen], a, alen); - ret[slen+alen] = 0; - - _tc_set_name_const(talloc_chunk_from_ptr(ret), ret); - return ret; -} - -/* - * Appends at the end of the string. - */ -_PUBLIC_ char *talloc_strdup_append(char *s, const char *a) -{ - if (unlikely(!s)) { - return talloc_strdup(NULL, a); - } - - if (unlikely(!a)) { - return s; - } - - return __talloc_strlendup_append(s, strlen(s), a, strlen(a)); -} - -/* - * Appends at the end of the talloc'ed buffer, - * not the end of the string. - */ -_PUBLIC_ char *talloc_strdup_append_buffer(char *s, const char *a) -{ - size_t slen; - - if (unlikely(!s)) { - return talloc_strdup(NULL, a); - } - - if (unlikely(!a)) { - return s; - } - - slen = talloc_get_size(s); - if (likely(slen > 0)) { - slen--; - } - - return __talloc_strlendup_append(s, slen, a, strlen(a)); -} - -/* - * Appends at the end of the string. - */ -_PUBLIC_ char *talloc_strndup_append(char *s, const char *a, size_t n) -{ - if (unlikely(!s)) { - return talloc_strndup(NULL, a, n); - } - - if (unlikely(!a)) { - return s; - } - - return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n)); -} - -/* - * Appends at the end of the talloc'ed buffer, - * not the end of the string. - */ -_PUBLIC_ char *talloc_strndup_append_buffer(char *s, const char *a, size_t n) -{ - size_t slen; - - if (unlikely(!s)) { - return talloc_strndup(NULL, a, n); - } - - if (unlikely(!a)) { - return s; - } - - slen = talloc_get_size(s); - if (likely(slen > 0)) { - slen--; - } - - return __talloc_strlendup_append(s, slen, a, strnlen(a, n)); -} - -#ifndef HAVE_VA_COPY -#ifdef HAVE___VA_COPY -#define va_copy(dest, src) __va_copy(dest, src) -#else -#define va_copy(dest, src) (dest) = (src) -#endif -#endif - -static struct talloc_chunk *_vasprintf_tc(const void *t, - const char *fmt, - va_list ap) PRINTF_ATTRIBUTE(2,0); - -static struct talloc_chunk *_vasprintf_tc(const void *t, - const char *fmt, - va_list ap) -{ - int vlen; - size_t len; - char *ret; - va_list ap2; - struct talloc_chunk *tc; - char buf[1024]; - - /* this call looks strange, but it makes it work on older solaris boxes */ - va_copy(ap2, ap); - vlen = vsnprintf(buf, sizeof(buf), fmt, ap2); - va_end(ap2); - if (unlikely(vlen < 0)) { - return NULL; - } - len = vlen; - if (unlikely(len + 1 < len)) { - return NULL; - } - - ret = (char *)__talloc(t, len+1, &tc); - if (unlikely(!ret)) return NULL; - - if (len < sizeof(buf)) { - memcpy(ret, buf, len+1); - } else { - va_copy(ap2, ap); - vsnprintf(ret, len+1, fmt, ap2); - va_end(ap2); - } - - _tc_set_name_const(tc, ret); - return tc; -} - -_PUBLIC_ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) -{ - struct talloc_chunk *tc = _vasprintf_tc(t, fmt, ap); - if (tc == NULL) { - return NULL; - } - return TC_PTR_FROM_CHUNK(tc); -} - - -/* - Perform string formatting, and return a pointer to newly allocated - memory holding the result, inside a memory pool. - */ -_PUBLIC_ char *talloc_asprintf(const void *t, const char *fmt, ...) -{ - va_list ap; - char *ret; - - va_start(ap, fmt); - ret = talloc_vasprintf(t, fmt, ap); - va_end(ap); - return ret; -} - -static inline char *__talloc_vaslenprintf_append(char *s, size_t slen, - const char *fmt, va_list ap) - PRINTF_ATTRIBUTE(3,0); - -static inline char *__talloc_vaslenprintf_append(char *s, size_t slen, - const char *fmt, va_list ap) -{ - ssize_t alen; - va_list ap2; - char c; - - va_copy(ap2, ap); - alen = vsnprintf(&c, 1, fmt, ap2); - va_end(ap2); - - if (alen <= 0) { - /* Either the vsnprintf failed or the format resulted in - * no characters being formatted. In the former case, we - * ought to return NULL, in the latter we ought to return - * the original string. Most current callers of this - * function expect it to never return NULL. - */ - return s; - } - - s = talloc_realloc(NULL, s, char, slen + alen + 1); - if (!s) return NULL; - - va_copy(ap2, ap); - vsnprintf(s + slen, alen + 1, fmt, ap2); - va_end(ap2); - - _tc_set_name_const(talloc_chunk_from_ptr(s), s); - return s; -} - -/** - * Realloc @p s to append the formatted result of @p fmt and @p ap, - * and return @p s, which may have moved. Good for gradually - * accumulating output into a string buffer. Appends at the end - * of the string. - **/ -_PUBLIC_ char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) -{ - if (unlikely(!s)) { - return talloc_vasprintf(NULL, fmt, ap); - } - - return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap); -} - -/** - * Realloc @p s to append the formatted result of @p fmt and @p ap, - * and return @p s, which may have moved. Always appends at the - * end of the talloc'ed buffer, not the end of the string. - **/ -_PUBLIC_ char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) -{ - size_t slen; - - if (unlikely(!s)) { - return talloc_vasprintf(NULL, fmt, ap); - } - - slen = talloc_get_size(s); - if (likely(slen > 0)) { - slen--; - } - - return __talloc_vaslenprintf_append(s, slen, fmt, ap); -} - -/* - Realloc @p s to append the formatted result of @p fmt and return @p - s, which may have moved. Good for gradually accumulating output - into a string buffer. - */ -_PUBLIC_ char *talloc_asprintf_append(char *s, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - s = talloc_vasprintf_append(s, fmt, ap); - va_end(ap); - return s; -} - -/* - Realloc @p s to append the formatted result of @p fmt and return @p - s, which may have moved. Good for gradually accumulating output - into a buffer. - */ -_PUBLIC_ char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - s = talloc_vasprintf_append_buffer(s, fmt, ap); - va_end(ap); - return s; -} - -/* - alloc an array, checking for integer overflow in the array size -*/ -_PUBLIC_ void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name) -{ - if (count >= MAX_TALLOC_SIZE/el_size) { - return NULL; - } - return _talloc_named_const(ctx, el_size * count, name); -} - -/* - alloc an zero array, checking for integer overflow in the array size -*/ -_PUBLIC_ void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name) -{ - if (count >= MAX_TALLOC_SIZE/el_size) { - return NULL; - } - return _talloc_zero(ctx, el_size * count, name); -} - -/* - realloc an array, checking for integer overflow in the array size -*/ -_PUBLIC_ void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name) -{ - if (count >= MAX_TALLOC_SIZE/el_size) { - return NULL; - } - return _talloc_realloc(ctx, ptr, el_size * count, name); -} - -/* - a function version of talloc_realloc(), so it can be passed as a function pointer - to libraries that want a realloc function (a realloc function encapsulates - all the basic capabilities of an allocation library, which is why this is useful) -*/ -_PUBLIC_ void *talloc_realloc_fn(const void *context, void *ptr, size_t size) -{ - return _talloc_realloc(context, ptr, size, NULL); -} - - -static int talloc_autofree_destructor(void *ptr) -{ - autofree_context = NULL; - return 0; -} - -/* - return a context which will be auto-freed on exit - this is useful for reducing the noise in leak reports -*/ -_PUBLIC_ void *talloc_autofree_context(void) -{ - if (autofree_context == NULL) { - autofree_context = _talloc_named_const(NULL, 0, "autofree_context"); - talloc_set_destructor(autofree_context, talloc_autofree_destructor); - talloc_setup_atexit(); - } - return autofree_context; -} - -_PUBLIC_ size_t talloc_get_size(const void *context) -{ - struct talloc_chunk *tc; - - if (context == NULL) { - return 0; - } - - tc = talloc_chunk_from_ptr(context); - - return tc->size; -} - -/* - find a parent of this context that has the given name, if any -*/ -_PUBLIC_ void *talloc_find_parent_byname(const void *context, const char *name) -{ - struct talloc_chunk *tc; - - if (context == NULL) { - return NULL; - } - - tc = talloc_chunk_from_ptr(context); - while (tc) { - if (tc->name && strcmp(tc->name, name) == 0) { - return TC_PTR_FROM_CHUNK(tc); - } - while (tc && tc->prev) tc = tc->prev; - if (tc) { - tc = tc->parent; - } - } - return NULL; -} - -/* - show the parentage of a context -*/ -_PUBLIC_ void talloc_show_parents(const void *context, FILE *file) -{ - struct talloc_chunk *tc; - - if (context == NULL) { - fprintf(file, "talloc no parents for NULL\n"); - return; - } - - tc = talloc_chunk_from_ptr(context); - fprintf(file, "talloc parents of '%s'\n", __talloc_get_name(context)); - while (tc) { - fprintf(file, "\t'%s'\n", __talloc_get_name(TC_PTR_FROM_CHUNK(tc))); - while (tc && tc->prev) tc = tc->prev; - if (tc) { - tc = tc->parent; - } - } - fflush(file); -} - -/* - return 1 if ptr is a parent of context -*/ -static int _talloc_is_parent(const void *context, const void *ptr, int depth) -{ - struct talloc_chunk *tc; - - if (context == NULL) { - return 0; - } - - tc = talloc_chunk_from_ptr(context); - while (tc) { - if (depth <= 0) { - return 0; - } - if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1; - while (tc && tc->prev) tc = tc->prev; - if (tc) { - tc = tc->parent; - depth--; - } - } - return 0; -} - -/* - return 1 if ptr is a parent of context -*/ -_PUBLIC_ int talloc_is_parent(const void *context, const void *ptr) -{ - return _talloc_is_parent(context, ptr, TALLOC_MAX_DEPTH); -} - -/* - return the total size of memory used by this context and all children -*/ -static inline size_t _talloc_total_limit_size(const void *ptr, - struct talloc_memlimit *old_limit, - struct talloc_memlimit *new_limit) -{ - return _talloc_total_mem_internal(ptr, TOTAL_MEM_LIMIT, - old_limit, new_limit); -} - -static inline bool talloc_memlimit_check(struct talloc_memlimit *limit, size_t size) -{ - struct talloc_memlimit *l; - - for (l = limit; l != NULL; l = l->upper) { - if (l->max_size != 0 && - ((l->max_size <= l->cur_size) || - (l->max_size - l->cur_size < size))) { - return false; - } - } - - return true; -} - -/* - Update memory limits when freeing a talloc_chunk. -*/ -static void tc_memlimit_update_on_free(struct talloc_chunk *tc) -{ - size_t limit_shrink_size; - - if (!tc->limit) { - return; - } - - /* - * Pool entries don't count. Only the pools - * themselves are counted as part of the memory - * limits. Note that this also takes care of - * nested pools which have both flags - * TALLOC_FLAG_POOLMEM|TALLOC_FLAG_POOL set. - */ - if (tc->flags & TALLOC_FLAG_POOLMEM) { - return; - } - - /* - * If we are part of a memory limited context hierarchy - * we need to subtract the memory used from the counters - */ - - limit_shrink_size = tc->size+TC_HDR_SIZE; - - /* - * If we're deallocating a pool, take into - * account the prefix size added for the pool. - */ - - if (tc->flags & TALLOC_FLAG_POOL) { - limit_shrink_size += TP_HDR_SIZE; - } - - talloc_memlimit_shrink(tc->limit, limit_shrink_size); - - if (tc->limit->parent == tc) { - free(tc->limit); - } - - tc->limit = NULL; -} - -/* - Increase memory limit accounting after a malloc/realloc. -*/ -static void talloc_memlimit_grow(struct talloc_memlimit *limit, - size_t size) -{ - struct talloc_memlimit *l; - - for (l = limit; l != NULL; l = l->upper) { - size_t new_cur_size = l->cur_size + size; - if (new_cur_size < l->cur_size) { - talloc_abort("logic error in talloc_memlimit_grow\n"); - return; - } - l->cur_size = new_cur_size; - } -} - -/* - Decrease memory limit accounting after a free/realloc. -*/ -static void talloc_memlimit_shrink(struct talloc_memlimit *limit, - size_t size) -{ - struct talloc_memlimit *l; - - for (l = limit; l != NULL; l = l->upper) { - if (l->cur_size < size) { - talloc_abort("logic error in talloc_memlimit_shrink\n"); - return; - } - l->cur_size = l->cur_size - size; - } -} - -_PUBLIC_ int talloc_set_memlimit(const void *ctx, size_t max_size) -{ - struct talloc_chunk *tc = talloc_chunk_from_ptr(ctx); - struct talloc_memlimit *orig_limit; - struct talloc_memlimit *limit = NULL; - - if (tc->limit && tc->limit->parent == tc) { - tc->limit->max_size = max_size; - return 0; - } - orig_limit = tc->limit; - - limit = malloc(sizeof(struct talloc_memlimit)); - if (limit == NULL) { - return 1; - } - limit->parent = tc; - limit->max_size = max_size; - limit->cur_size = _talloc_total_limit_size(ctx, tc->limit, limit); - - if (orig_limit) { - limit->upper = orig_limit; - } else { - limit->upper = NULL; - } - - return 0; -} diff --git a/ldb-2.0.8/lib/talloc/talloc.h b/ldb-2.0.8/lib/talloc/talloc.h deleted file mode 100644 index 34fe772..0000000 --- a/ldb-2.0.8/lib/talloc/talloc.h +++ /dev/null @@ -1,1945 +0,0 @@ -#ifndef _TALLOC_H_ -#define _TALLOC_H_ -/* - Unix SMB/CIFS implementation. - Samba temporary memory allocation functions - - Copyright (C) Andrew Tridgell 2004-2005 - Copyright (C) Stefan Metzmacher 2006 - - ** NOTE! The following LGPL license applies to the talloc - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup talloc The talloc API - * - * talloc is a hierarchical, reference counted memory pool system with - * destructors. It is the core memory allocator used in Samba. - * - * @{ - */ - -#define TALLOC_VERSION_MAJOR 2 -#define TALLOC_VERSION_MINOR 2 - -int talloc_version_major(void); -int talloc_version_minor(void); -/* This is mostly useful only for testing */ -int talloc_test_get_magic(void); - -/** - * @brief Define a talloc parent type - * - * As talloc is a hierarchial memory allocator, every talloc chunk is a - * potential parent to other talloc chunks. So defining a separate type for a - * talloc chunk is not strictly necessary. TALLOC_CTX is defined nevertheless, - * as it provides an indicator for function arguments. You will frequently - * write code like - * - * @code - * struct foo *foo_create(TALLOC_CTX *mem_ctx) - * { - * struct foo *result; - * result = talloc(mem_ctx, struct foo); - * if (result == NULL) return NULL; - * ... initialize foo ... - * return result; - * } - * @endcode - * - * In this type of allocating functions it is handy to have a general - * TALLOC_CTX type to indicate which parent to put allocated structures on. - */ -typedef void TALLOC_CTX; - -/* - this uses a little trick to allow __LINE__ to be stringified -*/ -#ifndef __location__ -#define __TALLOC_STRING_LINE1__(s) #s -#define __TALLOC_STRING_LINE2__(s) __TALLOC_STRING_LINE1__(s) -#define __TALLOC_STRING_LINE3__ __TALLOC_STRING_LINE2__(__LINE__) -#define __location__ __FILE__ ":" __TALLOC_STRING_LINE3__ -#endif - -#ifndef TALLOC_DEPRECATED -#define TALLOC_DEPRECATED 0 -#endif - -#ifndef PRINTF_ATTRIBUTE -#if (__GNUC__ >= 3) -/** Use gcc attribute to check printf fns. a1 is the 1-based index of - * the parameter containing the format, and a2 the index of the first - * argument. Note that some gcc 2.x versions don't handle this - * properly **/ -#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) -#else -#define PRINTF_ATTRIBUTE(a1, a2) -#endif -#endif - -#ifndef _DEPRECATED_ -#ifdef HAVE___ATTRIBUTE__ -#define _DEPRECATED_ __attribute__ ((deprecated)) -#else -#define _DEPRECATED_ -#endif -#endif -#ifdef DOXYGEN - -/** - * @brief Create a new talloc context. - * - * The talloc() macro is the core of the talloc library. It takes a memory - * context and a type, and returns a pointer to a new area of memory of the - * given type. - * - * The returned pointer is itself a talloc context, so you can use it as the - * context argument to more calls to talloc if you wish. - * - * The returned pointer is a "child" of the supplied context. This means that if - * you talloc_free() the context then the new child disappears as well. - * Alternatively you can free just the child. - * - * @param[in] ctx A talloc context to create a new reference on or NULL to - * create a new top level context. - * - * @param[in] type The type of memory to allocate. - * - * @return A type casted talloc context or NULL on error. - * - * @code - * unsigned int *a, *b; - * - * a = talloc(NULL, unsigned int); - * b = talloc(a, unsigned int); - * @endcode - * - * @see talloc_zero - * @see talloc_array - * @see talloc_steal - * @see talloc_free - */ -void *talloc(const void *ctx, #type); -#else -#define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type) -void *_talloc(const void *context, size_t size); -#endif - -/** - * @brief Create a new top level talloc context. - * - * This function creates a zero length named talloc context as a top level - * context. It is equivalent to: - * - * @code - * talloc_named(NULL, 0, fmt, ...); - * @endcode - * @param[in] fmt Format string for the name. - * - * @param[in] ... Additional printf-style arguments. - * - * @return The allocated memory chunk, NULL on error. - * - * @see talloc_named() - */ -void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2); - -#ifdef DOXYGEN -/** - * @brief Free a chunk of talloc memory. - * - * The talloc_free() function frees a piece of talloc memory, and all its - * children. You can call talloc_free() on any pointer returned by - * talloc(). - * - * The return value of talloc_free() indicates success or failure, with 0 - * returned for success and -1 for failure. A possible failure condition - * is if the pointer had a destructor attached to it and the destructor - * returned -1. See talloc_set_destructor() for details on - * destructors. Likewise, if "ptr" is NULL, then the function will make - * no modifications and return -1. - * - * From version 2.0 and onwards, as a special case, talloc_free() is - * refused on pointers that have more than one parent associated, as talloc - * would have no way of knowing which parent should be removed. This is - * different from older versions in the sense that always the reference to - * the most recently established parent has been destroyed. Hence to free a - * pointer that has more than one parent please use talloc_unlink(). - * - * To help you find problems in your code caused by this behaviour, if - * you do try and free a pointer with more than one parent then the - * talloc logging function will be called to give output like this: - * - * @code - * ERROR: talloc_free with references at some_dir/source/foo.c:123 - * reference at some_dir/source/other.c:325 - * reference at some_dir/source/third.c:121 - * @endcode - * - * Please see the documentation for talloc_set_log_fn() and - * talloc_set_log_stderr() for more information on talloc logging - * functions. - * - * If TALLOC_FREE_FILL environment variable is set, - * the memory occupied by the context is filled with the value of this variable. - * The value should be a numeric representation of the character you want to - * use. - * - * talloc_free() operates recursively on its children. - * - * @param[in] ptr The chunk to be freed. - * - * @return Returns 0 on success and -1 on error. A possible - * failure condition is if the pointer had a destructor - * attached to it and the destructor returned -1. Likewise, - * if "ptr" is NULL, then the function will make no - * modifications and returns -1. - * - * Example: - * @code - * unsigned int *a, *b; - * a = talloc(NULL, unsigned int); - * b = talloc(a, unsigned int); - * - * talloc_free(a); // Frees a and b - * @endcode - * - * @see talloc_set_destructor() - * @see talloc_unlink() - */ -int talloc_free(void *ptr); -#else -#define talloc_free(ctx) _talloc_free(ctx, __location__) -int _talloc_free(void *ptr, const char *location); -#endif - -/** - * @brief Free a talloc chunk's children. - * - * The function walks along the list of all children of a talloc context and - * talloc_free()s only the children, not the context itself. - * - * A NULL argument is handled as no-op. - * - * @param[in] ptr The chunk that you want to free the children of - * (NULL is allowed too) - */ -void talloc_free_children(void *ptr); - -#ifdef DOXYGEN -/** - * @brief Assign a destructor function to be called when a chunk is freed. - * - * The function talloc_set_destructor() sets the "destructor" for the pointer - * "ptr". A destructor is a function that is called when the memory used by a - * pointer is about to be released. The destructor receives the pointer as an - * argument, and should return 0 for success and -1 for failure. - * - * The destructor can do anything it wants to, including freeing other pieces - * of memory. A common use for destructors is to clean up operating system - * resources (such as open file descriptors) contained in the structure the - * destructor is placed on. - * - * You can only place one destructor on a pointer. If you need more than one - * destructor then you can create a zero-length child of the pointer and place - * an additional destructor on that. - * - * To remove a destructor call talloc_set_destructor() with NULL for the - * destructor. - * - * If your destructor attempts to talloc_free() the pointer that it is the - * destructor for then talloc_free() will return -1 and the free will be - * ignored. This would be a pointless operation anyway, as the destructor is - * only called when the memory is just about to go away. - * - * @param[in] ptr The talloc chunk to add a destructor to. - * - * @param[in] destructor The destructor function to be called. NULL to remove - * it. - * - * Example: - * @code - * static int destroy_fd(int *fd) { - * close(*fd); - * return 0; - * } - * - * int *open_file(const char *filename) { - * int *fd = talloc(NULL, int); - * *fd = open(filename, O_RDONLY); - * if (*fd < 0) { - * talloc_free(fd); - * return NULL; - * } - * // Whenever they free this, we close the file. - * talloc_set_destructor(fd, destroy_fd); - * return fd; - * } - * @endcode - * - * @see talloc() - * @see talloc_free() - */ -void talloc_set_destructor(const void *ptr, int (*destructor)(void *)); - -/** - * @brief Change a talloc chunk's parent. - * - * The talloc_steal() function changes the parent context of a talloc - * pointer. It is typically used when the context that the pointer is - * currently a child of is going to be freed and you wish to keep the - * memory for a longer time. - * - * To make the changed hierarchy less error-prone, you might consider to use - * talloc_move(). - * - * If you try and call talloc_steal() on a pointer that has more than one - * parent then the result is ambiguous. Talloc will choose to remove the - * parent that is currently indicated by talloc_parent() and replace it with - * the chosen parent. You will also get a message like this via the talloc - * logging functions: - * - * @code - * WARNING: talloc_steal with references at some_dir/source/foo.c:123 - * reference at some_dir/source/other.c:325 - * reference at some_dir/source/third.c:121 - * @endcode - * - * To unambiguously change the parent of a pointer please see the function - * talloc_reparent(). See the talloc_set_log_fn() documentation for more - * information on talloc logging. - * - * @param[in] new_ctx The new parent context. - * - * @param[in] ptr The talloc chunk to move. - * - * @return Returns the pointer that you pass it. It does not have - * any failure modes. - * - * @note It is possible to produce loops in the parent/child relationship - * if you are not careful with talloc_steal(). No guarantees are provided - * as to your sanity or the safety of your data if you do this. - */ -void *talloc_steal(const void *new_ctx, const void *ptr); -#else /* DOXYGEN */ -/* try to make talloc_set_destructor() and talloc_steal() type safe, - if we have a recent gcc */ -#if (__GNUC__ >= 3) -#define _TALLOC_TYPEOF(ptr) __typeof__(ptr) -#define talloc_set_destructor(ptr, function) \ - do { \ - int (*_talloc_destructor_fn)(_TALLOC_TYPEOF(ptr)) = (function); \ - _talloc_set_destructor((ptr), (int (*)(void *))_talloc_destructor_fn); \ - } while(0) -/* this extremely strange macro is to avoid some braindamaged warning - stupidity in gcc 4.1.x */ -#define talloc_steal(ctx, ptr) ({ _TALLOC_TYPEOF(ptr) __talloc_steal_ret = (_TALLOC_TYPEOF(ptr))_talloc_steal_loc((ctx),(ptr), __location__); __talloc_steal_ret; }) -#else /* __GNUC__ >= 3 */ -#define talloc_set_destructor(ptr, function) \ - _talloc_set_destructor((ptr), (int (*)(void *))(function)) -#define _TALLOC_TYPEOF(ptr) void * -#define talloc_steal(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_steal_loc((ctx),(ptr), __location__) -#endif /* __GNUC__ >= 3 */ -void _talloc_set_destructor(const void *ptr, int (*_destructor)(void *)); -void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const char *location); -#endif /* DOXYGEN */ - -/** - * @brief Assign a name to a talloc chunk. - * - * Each talloc pointer has a "name". The name is used principally for - * debugging purposes, although it is also possible to set and get the name on - * a pointer in as a way of "marking" pointers in your code. - * - * The main use for names on pointer is for "talloc reports". See - * talloc_report() and talloc_report_full() for details. Also see - * talloc_enable_leak_report() and talloc_enable_leak_report_full(). - * - * The talloc_set_name() function allocates memory as a child of the - * pointer. It is logically equivalent to: - * - * @code - * talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...)); - * @endcode - * - * @param[in] ptr The talloc chunk to assign a name to. - * - * @param[in] fmt Format string for the name. - * - * @param[in] ... Add printf-style additional arguments. - * - * @return The assigned name, NULL on error. - * - * @note Multiple calls to talloc_set_name() will allocate more memory without - * releasing the name. All of the memory is released when the ptr is freed - * using talloc_free(). - */ -const char *talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); - -#ifdef DOXYGEN -/** - * @brief Change a talloc chunk's parent. - * - * This function has the same effect as talloc_steal(), and additionally sets - * the source pointer to NULL. You would use it like this: - * - * @code - * struct foo *X = talloc(tmp_ctx, struct foo); - * struct foo *Y; - * Y = talloc_move(new_ctx, &X); - * @endcode - * - * @param[in] new_ctx The new parent context. - * - * @param[in] pptr Pointer to a pointer to the talloc chunk to move. - * - * @return The pointer to the talloc chunk that moved. - * It does not have any failure modes. - * - */ -void *talloc_move(const void *new_ctx, void **pptr); -#else -#define talloc_move(ctx, pptr) (_TALLOC_TYPEOF(*(pptr)))_talloc_move((ctx),(void *)(pptr)) -void *_talloc_move(const void *new_ctx, const void *pptr); -#endif - -/** - * @brief Assign a name to a talloc chunk. - * - * The function is just like talloc_set_name(), but it takes a string constant, - * and is much faster. It is extensively used by the "auto naming" macros, such - * as talloc_p(). - * - * This function does not allocate any memory. It just copies the supplied - * pointer into the internal representation of the talloc ptr. This means you - * must not pass a name pointer to memory that will disappear before the ptr - * is freed with talloc_free(). - * - * @param[in] ptr The talloc chunk to assign a name to. - * - * @param[in] name Format string for the name. - */ -void talloc_set_name_const(const void *ptr, const char *name); - -/** - * @brief Create a named talloc chunk. - * - * The talloc_named() function creates a named talloc pointer. It is - * equivalent to: - * - * @code - * ptr = talloc_size(context, size); - * talloc_set_name(ptr, fmt, ....); - * @endcode - * - * @param[in] context The talloc context to hang the result off. - * - * @param[in] size Number of char's that you want to allocate. - * - * @param[in] fmt Format string for the name. - * - * @param[in] ... Additional printf-style arguments. - * - * @return The allocated memory chunk, NULL on error. - * - * @see talloc_set_name() - */ -void *talloc_named(const void *context, size_t size, - const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); - -/** - * @brief Basic routine to allocate a chunk of memory. - * - * This is equivalent to: - * - * @code - * ptr = talloc_size(context, size); - * talloc_set_name_const(ptr, name); - * @endcode - * - * @param[in] context The parent context. - * - * @param[in] size The number of char's that we want to allocate. - * - * @param[in] name The name the talloc block has. - * - * @return The allocated memory chunk, NULL on error. - */ -void *talloc_named_const(const void *context, size_t size, const char *name); - -#ifdef DOXYGEN -/** - * @brief Untyped allocation. - * - * The function should be used when you don't have a convenient type to pass to - * talloc(). Unlike talloc(), it is not type safe (as it returns a void *), so - * you are on your own for type checking. - * - * Best to use talloc() or talloc_array() instead. - * - * @param[in] ctx The talloc context to hang the result off. - * - * @param[in] size Number of char's that you want to allocate. - * - * @return The allocated memory chunk, NULL on error. - * - * Example: - * @code - * void *mem = talloc_size(NULL, 100); - * @endcode - */ -void *talloc_size(const void *ctx, size_t size); -#else -#define talloc_size(ctx, size) talloc_named_const(ctx, size, __location__) -#endif - -#ifdef DOXYGEN -/** - * @brief Allocate into a typed pointer. - * - * The talloc_ptrtype() macro should be used when you have a pointer and want - * to allocate memory to point at with this pointer. When compiling with - * gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size() and - * talloc_get_name() will return the current location in the source file and - * not the type. - * - * @param[in] ctx The talloc context to hang the result off. - * - * @param[in] type The pointer you want to assign the result to. - * - * @return The properly casted allocated memory chunk, NULL on - * error. - * - * Example: - * @code - * unsigned int *a = talloc_ptrtype(NULL, a); - * @endcode - */ -void *talloc_ptrtype(const void *ctx, #type); -#else -#define talloc_ptrtype(ctx, ptr) (_TALLOC_TYPEOF(ptr))talloc_size(ctx, sizeof(*(ptr))) -#endif - -#ifdef DOXYGEN -/** - * @brief Allocate a new 0-sized talloc chunk. - * - * This is a utility macro that creates a new memory context hanging off an - * existing context, automatically naming it "talloc_new: __location__" where - * __location__ is the source line it is called from. It is particularly - * useful for creating a new temporary working context. - * - * @param[in] ctx The talloc parent context. - * - * @return A new talloc chunk, NULL on error. - */ -void *talloc_new(const void *ctx); -#else -#define talloc_new(ctx) talloc_named_const(ctx, 0, "talloc_new: " __location__) -#endif - -#ifdef DOXYGEN -/** - * @brief Allocate a 0-initizialized structure. - * - * The macro is equivalent to: - * - * @code - * ptr = talloc(ctx, type); - * if (ptr) memset(ptr, 0, sizeof(type)); - * @endcode - * - * @param[in] ctx The talloc context to hang the result off. - * - * @param[in] type The type that we want to allocate. - * - * @return Pointer to a piece of memory, properly cast to 'type *', - * NULL on error. - * - * Example: - * @code - * unsigned int *a, *b; - * a = talloc_zero(NULL, unsigned int); - * b = talloc_zero(a, unsigned int); - * @endcode - * - * @see talloc() - * @see talloc_zero_size() - * @see talloc_zero_array() - */ -void *talloc_zero(const void *ctx, #type); - -/** - * @brief Allocate untyped, 0-initialized memory. - * - * @param[in] ctx The talloc context to hang the result off. - * - * @param[in] size Number of char's that you want to allocate. - * - * @return The allocated memory chunk. - */ -void *talloc_zero_size(const void *ctx, size_t size); -#else -#define talloc_zero(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type) -#define talloc_zero_size(ctx, size) _talloc_zero(ctx, size, __location__) -void *_talloc_zero(const void *ctx, size_t size, const char *name); -#endif - -/** - * @brief Return the name of a talloc chunk. - * - * @param[in] ptr The talloc chunk. - * - * @return The current name for the given talloc pointer. - * - * @see talloc_set_name() - */ -const char *talloc_get_name(const void *ptr); - -/** - * @brief Verify that a talloc chunk carries a specified name. - * - * This function checks if a pointer has the specified name. If it does - * then the pointer is returned. - * - * @param[in] ptr The talloc chunk to check. - * - * @param[in] name The name to check against. - * - * @return The pointer if the name matches, NULL if it doesn't. - */ -void *talloc_check_name(const void *ptr, const char *name); - -/** - * @brief Get the parent chunk of a pointer. - * - * @param[in] ptr The talloc pointer to inspect. - * - * @return The talloc parent of ptr, NULL on error. - */ -void *talloc_parent(const void *ptr); - -/** - * @brief Get a talloc chunk's parent name. - * - * @param[in] ptr The talloc pointer to inspect. - * - * @return The name of ptr's parent chunk. - */ -const char *talloc_parent_name(const void *ptr); - -/** - * @brief Get the total size of a talloc chunk including its children. - * - * The function returns the total size in bytes used by this pointer and all - * child pointers. Mostly useful for debugging. - * - * Passing NULL is allowed, but it will only give a meaningful result if - * talloc_enable_leak_report() or talloc_enable_leak_report_full() has - * been called. - * - * @param[in] ptr The talloc chunk. - * - * @return The total size. - */ -size_t talloc_total_size(const void *ptr); - -/** - * @brief Get the number of talloc chunks hanging off a chunk. - * - * The talloc_total_blocks() function returns the total memory block - * count used by this pointer and all child pointers. Mostly useful for - * debugging. - * - * Passing NULL is allowed, but it will only give a meaningful result if - * talloc_enable_leak_report() or talloc_enable_leak_report_full() has - * been called. - * - * @param[in] ptr The talloc chunk. - * - * @return The total size. - */ -size_t talloc_total_blocks(const void *ptr); - -#ifdef DOXYGEN -/** - * @brief Duplicate a memory area into a talloc chunk. - * - * The function is equivalent to: - * - * @code - * ptr = talloc_size(ctx, size); - * if (ptr) memcpy(ptr, p, size); - * @endcode - * - * @param[in] t The talloc context to hang the result off. - * - * @param[in] p The memory chunk you want to duplicate. - * - * @param[in] size Number of char's that you want copy. - * - * @return The allocated memory chunk. - * - * @see talloc_size() - */ -void *talloc_memdup(const void *t, const void *p, size_t size); -#else -#define talloc_memdup(t, p, size) _talloc_memdup(t, p, size, __location__) -void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name); -#endif - -#ifdef DOXYGEN -/** - * @brief Assign a type to a talloc chunk. - * - * This macro allows you to force the name of a pointer to be of a particular - * type. This can be used in conjunction with talloc_get_type() to do type - * checking on void* pointers. - * - * It is equivalent to this: - * - * @code - * talloc_set_name_const(ptr, #type) - * @endcode - * - * @param[in] ptr The talloc chunk to assign the type to. - * - * @param[in] type The type to assign. - */ -void talloc_set_type(const char *ptr, #type); - -/** - * @brief Get a typed pointer out of a talloc pointer. - * - * This macro allows you to do type checking on talloc pointers. It is - * particularly useful for void* private pointers. It is equivalent to - * this: - * - * @code - * (type *)talloc_check_name(ptr, #type) - * @endcode - * - * @param[in] ptr The talloc pointer to check. - * - * @param[in] type The type to check against. - * - * @return The properly casted pointer given by ptr, NULL on error. - */ -type *talloc_get_type(const void *ptr, #type); -#else -#define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type) -#define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type) -#endif - -#ifdef DOXYGEN -/** - * @brief Safely turn a void pointer into a typed pointer. - * - * This macro is used together with talloc(mem_ctx, struct foo). If you had to - * assign the talloc chunk pointer to some void pointer variable, - * talloc_get_type_abort() is the recommended way to get the convert the void - * pointer back to a typed pointer. - * - * @param[in] ptr The void pointer to convert. - * - * @param[in] type The type that this chunk contains - * - * @return The same value as ptr, type-checked and properly cast. - */ -void *talloc_get_type_abort(const void *ptr, #type); -#else -#ifdef TALLOC_GET_TYPE_ABORT_NOOP -#define talloc_get_type_abort(ptr, type) (type *)(ptr) -#else -#define talloc_get_type_abort(ptr, type) (type *)_talloc_get_type_abort(ptr, #type, __location__) -#endif -void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location); -#endif - -/** - * @brief Find a parent context by name. - * - * Find a parent memory context of the current context that has the given - * name. This can be very useful in complex programs where it may be - * difficult to pass all information down to the level you need, but you - * know the structure you want is a parent of another context. - * - * @param[in] ctx The talloc chunk to start from. - * - * @param[in] name The name of the parent we look for. - * - * @return The memory context we are looking for, NULL if not - * found. - */ -void *talloc_find_parent_byname(const void *ctx, const char *name); - -#ifdef DOXYGEN -/** - * @brief Find a parent context by type. - * - * Find a parent memory context of the current context that has the given - * name. This can be very useful in complex programs where it may be - * difficult to pass all information down to the level you need, but you - * know the structure you want is a parent of another context. - * - * Like talloc_find_parent_byname() but takes a type, making it typesafe. - * - * @param[in] ptr The talloc chunk to start from. - * - * @param[in] type The type of the parent to look for. - * - * @return The memory context we are looking for, NULL if not - * found. - */ -void *talloc_find_parent_bytype(const void *ptr, #type); -#else -#define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type) -#endif - -/** - * @brief Allocate a talloc pool. - * - * A talloc pool is a pure optimization for specific situations. In the - * release process for Samba 3.2 we found out that we had become considerably - * slower than Samba 3.0 was. Profiling showed that malloc(3) was a large CPU - * consumer in benchmarks. For Samba 3.2 we have internally converted many - * static buffers to dynamically allocated ones, so malloc(3) being beaten - * more was no surprise. But it made us slower. - * - * talloc_pool() is an optimization to call malloc(3) a lot less for the use - * pattern Samba has: The SMB protocol is mainly a request/response protocol - * where we have to allocate a certain amount of memory per request and free - * that after the SMB reply is sent to the client. - * - * talloc_pool() creates a talloc chunk that you can use as a talloc parent - * exactly as you would use any other ::TALLOC_CTX. The difference is that - * when you talloc a child of this pool, no malloc(3) is done. Instead, talloc - * just increments a pointer inside the talloc_pool. This also works - * recursively. If you use the child of the talloc pool as a parent for - * grand-children, their memory is also taken from the talloc pool. - * - * If there is not enough memory in the pool to allocate the new child, - * it will create a new talloc chunk as if the parent was a normal talloc - * context. - * - * If you talloc_free() children of a talloc pool, the memory is not given - * back to the system. Instead, free(3) is only called if the talloc_pool() - * itself is released with talloc_free(). - * - * The downside of a talloc pool is that if you talloc_move() a child of a - * talloc pool to a talloc parent outside the pool, the whole pool memory is - * not free(3)'ed until that moved chunk is also talloc_free()ed. - * - * @param[in] context The talloc context to hang the result off. - * - * @param[in] size Size of the talloc pool. - * - * @return The allocated talloc pool, NULL on error. - */ -void *talloc_pool(const void *context, size_t size); - -#ifdef DOXYGEN -/** - * @brief Allocate a talloc object as/with an additional pool. - * - * This is like talloc_pool(), but's it's more flexible - * and allows an object to be a pool for its children. - * - * @param[in] ctx The talloc context to hang the result off. - * - * @param[in] type The type that we want to allocate. - * - * @param[in] num_subobjects The expected number of subobjects, which will - * be allocated within the pool. This allocates - * space for talloc_chunk headers. - * - * @param[in] total_subobjects_size The size that all subobjects can use in total. - * - * - * @return The allocated talloc object, NULL on error. - */ -void *talloc_pooled_object(const void *ctx, #type, - unsigned num_subobjects, - size_t total_subobjects_size); -#else -#define talloc_pooled_object(_ctx, _type, \ - _num_subobjects, \ - _total_subobjects_size) \ - (_type *)_talloc_pooled_object((_ctx), sizeof(_type), #_type, \ - (_num_subobjects), \ - (_total_subobjects_size)) -void *_talloc_pooled_object(const void *ctx, - size_t type_size, - const char *type_name, - unsigned num_subobjects, - size_t total_subobjects_size); -#endif - -/** - * @brief Free a talloc chunk and NULL out the pointer. - * - * TALLOC_FREE() frees a pointer and sets it to NULL. Use this if you want - * immediate feedback (i.e. crash) if you use a pointer after having free'ed - * it. - * - * @param[in] ctx The chunk to be freed. - */ -#define TALLOC_FREE(ctx) do { if (ctx != NULL) { talloc_free(ctx); ctx=NULL; } } while(0) - -/* @} ******************************************************************/ - -/** - * \defgroup talloc_ref The talloc reference function. - * @ingroup talloc - * - * This module contains the definitions around talloc references - * - * @{ - */ - -/** - * @brief Increase the reference count of a talloc chunk. - * - * The talloc_increase_ref_count(ptr) function is exactly equivalent to: - * - * @code - * talloc_reference(NULL, ptr); - * @endcode - * - * You can use either syntax, depending on which you think is clearer in - * your code. - * - * @param[in] ptr The pointer to increase the reference count. - * - * @return 0 on success, -1 on error. - */ -int talloc_increase_ref_count(const void *ptr); - -/** - * @brief Get the number of references to a talloc chunk. - * - * @param[in] ptr The pointer to retrieve the reference count from. - * - * @return The number of references. - */ -size_t talloc_reference_count(const void *ptr); - -#ifdef DOXYGEN -/** - * @brief Create an additional talloc parent to a pointer. - * - * The talloc_reference() function makes "context" an additional parent of - * ptr. Each additional reference consumes around 48 bytes of memory on intel - * x86 platforms. - * - * If ptr is NULL, then the function is a no-op, and simply returns NULL. - * - * After creating a reference you can free it in one of the following ways: - * - * - you can talloc_free() any parent of the original pointer. That - * will reduce the number of parents of this pointer by 1, and will - * cause this pointer to be freed if it runs out of parents. - * - * - you can talloc_free() the pointer itself if it has at maximum one - * parent. This behaviour has been changed since the release of version - * 2.0. Further information in the description of "talloc_free". - * - * For more control on which parent to remove, see talloc_unlink() - * @param[in] ctx The additional parent. - * - * @param[in] ptr The pointer you want to create an additional parent for. - * - * @return The original pointer 'ptr', NULL if talloc ran out of - * memory in creating the reference. - * - * @warning You should try to avoid using this interface. It turns a beautiful - * talloc-tree into a graph. It is often really hard to debug if you - * screw something up by accident. - * - * Example: - * @code - * unsigned int *a, *b, *c; - * a = talloc(NULL, unsigned int); - * b = talloc(NULL, unsigned int); - * c = talloc(a, unsigned int); - * // b also serves as a parent of c. - * talloc_reference(b, c); - * @endcode - * - * @see talloc_unlink() - */ -void *talloc_reference(const void *ctx, const void *ptr); -#else -#define talloc_reference(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_reference_loc((ctx),(ptr), __location__) -void *_talloc_reference_loc(const void *context, const void *ptr, const char *location); -#endif - -/** - * @brief Remove a specific parent from a talloc chunk. - * - * The function removes a specific parent from ptr. The context passed must - * either be a context used in talloc_reference() with this pointer, or must be - * a direct parent of ptr. - * - * You can just use talloc_free() instead of talloc_unlink() if there - * is at maximum one parent. This behaviour has been changed since the - * release of version 2.0. Further information in the description of - * "talloc_free". - * - * @param[in] context The talloc parent to remove. - * - * @param[in] ptr The talloc ptr you want to remove the parent from. - * - * @return 0 on success, -1 on error. - * - * @note If the parent has already been removed using talloc_free() then - * this function will fail and will return -1. Likewise, if ptr is NULL, - * then the function will make no modifications and return -1. - * - * @warning You should try to avoid using this interface. It turns a beautiful - * talloc-tree into a graph. It is often really hard to debug if you - * screw something up by accident. - * - * Example: - * @code - * unsigned int *a, *b, *c; - * a = talloc(NULL, unsigned int); - * b = talloc(NULL, unsigned int); - * c = talloc(a, unsigned int); - * // b also serves as a parent of c. - * talloc_reference(b, c); - * talloc_unlink(b, c); - * @endcode - */ -int talloc_unlink(const void *context, void *ptr); - -/** - * @brief Provide a talloc context that is freed at program exit. - * - * This is a handy utility function that returns a talloc context - * which will be automatically freed on program exit. This can be used - * to reduce the noise in memory leak reports. - * - * Never use this in code that might be used in objects loaded with - * dlopen and unloaded with dlclose. talloc_autofree_context() - * internally uses atexit(3). Some platforms like modern Linux handles - * this fine, but for example FreeBSD does not deal well with dlopen() - * and atexit() used simultaneously: dlclose() does not clean up the - * list of atexit-handlers, so when the program exits the code that - * was registered from within talloc_autofree_context() is gone, the - * program crashes at exit. - * - * @return A talloc context, NULL on error. - */ -void *talloc_autofree_context(void) _DEPRECATED_; - -/** - * @brief Get the size of a talloc chunk. - * - * This function lets you know the amount of memory allocated so far by - * this context. It does NOT account for subcontext memory. - * This can be used to calculate the size of an array. - * - * @param[in] ctx The talloc chunk. - * - * @return The size of the talloc chunk. - */ -size_t talloc_get_size(const void *ctx); - -/** - * @brief Show the parentage of a context. - * - * @param[in] context The talloc context to look at. - * - * @param[in] file The output to use, a file, stdout or stderr. - */ -void talloc_show_parents(const void *context, FILE *file); - -/** - * @brief Check if a context is parent of a talloc chunk. - * - * This checks if context is referenced in the talloc hierarchy above ptr. - * - * @param[in] context The assumed talloc context. - * - * @param[in] ptr The talloc chunk to check. - * - * @return Return 1 if this is the case, 0 if not. - */ -int talloc_is_parent(const void *context, const void *ptr); - -/** - * @brief Change the parent context of a talloc pointer. - * - * The function changes the parent context of a talloc pointer. It is typically - * used when the context that the pointer is currently a child of is going to be - * freed and you wish to keep the memory for a longer time. - * - * The difference between talloc_reparent() and talloc_steal() is that - * talloc_reparent() can specify which parent you wish to change. This is - * useful when a pointer has multiple parents via references. - * - * @param[in] old_parent - * @param[in] new_parent - * @param[in] ptr - * - * @return Return the pointer you passed. It does not have any - * failure modes. - */ -void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr); - -/* @} ******************************************************************/ - -/** - * @defgroup talloc_array The talloc array functions - * @ingroup talloc - * - * Talloc contains some handy helpers for handling Arrays conveniently - * - * @{ - */ - -#ifdef DOXYGEN -/** - * @brief Allocate an array. - * - * The macro is equivalent to: - * - * @code - * (type *)talloc_size(ctx, sizeof(type) * count); - * @endcode - * - * except that it provides integer overflow protection for the multiply, - * returning NULL if the multiply overflows. - * - * @param[in] ctx The talloc context to hang the result off. - * - * @param[in] type The type that we want to allocate. - * - * @param[in] count The number of 'type' elements you want to allocate. - * - * @return The allocated result, properly cast to 'type *', NULL on - * error. - * - * Example: - * @code - * unsigned int *a, *b; - * a = talloc_zero(NULL, unsigned int); - * b = talloc_array(a, unsigned int, 100); - * @endcode - * - * @see talloc() - * @see talloc_zero_array() - */ -void *talloc_array(const void *ctx, #type, unsigned count); -#else -#define talloc_array(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type) -void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name); -#endif - -#ifdef DOXYGEN -/** - * @brief Allocate an array. - * - * @param[in] ctx The talloc context to hang the result off. - * - * @param[in] size The size of an array element. - * - * @param[in] count The number of elements you want to allocate. - * - * @return The allocated result, NULL on error. - */ -void *talloc_array_size(const void *ctx, size_t size, unsigned count); -#else -#define talloc_array_size(ctx, size, count) _talloc_array(ctx, size, count, __location__) -#endif - -#ifdef DOXYGEN -/** - * @brief Allocate an array into a typed pointer. - * - * The macro should be used when you have a pointer to an array and want to - * allocate memory of an array to point at with this pointer. When compiling - * with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_array_size() - * and talloc_get_name() will return the current location in the source file - * and not the type. - * - * @param[in] ctx The talloc context to hang the result off. - * - * @param[in] ptr The pointer you want to assign the result to. - * - * @param[in] count The number of elements you want to allocate. - * - * @return The allocated memory chunk, properly casted. NULL on - * error. - */ -void *talloc_array_ptrtype(const void *ctx, const void *ptr, unsigned count); -#else -#define talloc_array_ptrtype(ctx, ptr, count) (_TALLOC_TYPEOF(ptr))talloc_array_size(ctx, sizeof(*(ptr)), count) -#endif - -#ifdef DOXYGEN -/** - * @brief Get the number of elements in a talloc'ed array. - * - * A talloc chunk carries its own size, so for talloc'ed arrays it is not - * necessary to store the number of elements explicitly. - * - * @param[in] ctx The allocated array. - * - * @return The number of elements in ctx. - */ -size_t talloc_array_length(const void *ctx); -#else -#define talloc_array_length(ctx) (talloc_get_size(ctx)/sizeof(*ctx)) -#endif - -#ifdef DOXYGEN -/** - * @brief Allocate a zero-initialized array - * - * @param[in] ctx The talloc context to hang the result off. - * - * @param[in] type The type that we want to allocate. - * - * @param[in] count The number of "type" elements you want to allocate. - * - * @return The allocated result casted to "type *", NULL on error. - * - * The talloc_zero_array() macro is equivalent to: - * - * @code - * ptr = talloc_array(ctx, type, count); - * if (ptr) memset(ptr, 0, sizeof(type) * count); - * @endcode - */ -void *talloc_zero_array(const void *ctx, #type, unsigned count); -#else -#define talloc_zero_array(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type) -void *_talloc_zero_array(const void *ctx, - size_t el_size, - unsigned count, - const char *name); -#endif - -#ifdef DOXYGEN -/** - * @brief Change the size of a talloc array. - * - * The macro changes the size of a talloc pointer. The 'count' argument is the - * number of elements of type 'type' that you want the resulting pointer to - * hold. - * - * talloc_realloc() has the following equivalences: - * - * @code - * talloc_realloc(ctx, NULL, type, 1) ==> talloc(ctx, type); - * talloc_realloc(ctx, NULL, type, N) ==> talloc_array(ctx, type, N); - * talloc_realloc(ctx, ptr, type, 0) ==> talloc_free(ptr); - * @endcode - * - * The "context" argument is only used if "ptr" is NULL, otherwise it is - * ignored. - * - * @param[in] ctx The parent context used if ptr is NULL. - * - * @param[in] ptr The chunk to be resized. - * - * @param[in] type The type of the array element inside ptr. - * - * @param[in] count The intended number of array elements. - * - * @return The new array, NULL on error. The call will fail either - * due to a lack of memory, or because the pointer has more - * than one parent (see talloc_reference()). - */ -void *talloc_realloc(const void *ctx, void *ptr, #type, size_t count); -#else -#define talloc_realloc(ctx, p, type, count) (type *)_talloc_realloc_array(ctx, p, sizeof(type), count, #type) -void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name); -#endif - -#ifdef DOXYGEN -/** - * @brief Untyped realloc to change the size of a talloc array. - * - * The macro is useful when the type is not known so the typesafe - * talloc_realloc() cannot be used. - * - * @param[in] ctx The parent context used if 'ptr' is NULL. - * - * @param[in] ptr The chunk to be resized. - * - * @param[in] size The new chunk size. - * - * @return The new array, NULL on error. - */ -void *talloc_realloc_size(const void *ctx, void *ptr, size_t size); -#else -#define talloc_realloc_size(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__) -void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name); -#endif - -/** - * @brief Provide a function version of talloc_realloc_size. - * - * This is a non-macro version of talloc_realloc(), which is useful as - * libraries sometimes want a ralloc function pointer. A realloc() - * implementation encapsulates the functionality of malloc(), free() and - * realloc() in one call, which is why it is useful to be able to pass around - * a single function pointer. - * - * @param[in] context The parent context used if ptr is NULL. - * - * @param[in] ptr The chunk to be resized. - * - * @param[in] size The new chunk size. - * - * @return The new chunk, NULL on error. - */ -void *talloc_realloc_fn(const void *context, void *ptr, size_t size); - -/* @} ******************************************************************/ - -/** - * @defgroup talloc_string The talloc string functions. - * @ingroup talloc - * - * talloc string allocation and manipulation functions. - * @{ - */ - -/** - * @brief Duplicate a string into a talloc chunk. - * - * This function is equivalent to: - * - * @code - * ptr = talloc_size(ctx, strlen(p)+1); - * if (ptr) memcpy(ptr, p, strlen(p)+1); - * @endcode - * - * This functions sets the name of the new pointer to the passed - * string. This is equivalent to: - * - * @code - * talloc_set_name_const(ptr, ptr) - * @endcode - * - * @param[in] t The talloc context to hang the result off. - * - * @param[in] p The string you want to duplicate. - * - * @return The duplicated string, NULL on error. - */ -char *talloc_strdup(const void *t, const char *p); - -/** - * @brief Append a string to given string. - * - * The destination string is reallocated to take - * strlen(s) + strlen(a) + 1 characters. - * - * This functions sets the name of the new pointer to the new - * string. This is equivalent to: - * - * @code - * talloc_set_name_const(ptr, ptr) - * @endcode - * - * If s == NULL then new context is created. - * - * @param[in] s The destination to append to. - * - * @param[in] a The string you want to append. - * - * @return The concatenated strings, NULL on error. - * - * @see talloc_strdup() - * @see talloc_strdup_append_buffer() - */ -char *talloc_strdup_append(char *s, const char *a); - -/** - * @brief Append a string to a given buffer. - * - * This is a more efficient version of talloc_strdup_append(). It determines the - * length of the destination string by the size of the talloc context. - * - * Use this very carefully as it produces a different result than - * talloc_strdup_append() when a zero character is in the middle of the - * destination string. - * - * @code - * char *str_a = talloc_strdup(NULL, "hello world"); - * char *str_b = talloc_strdup(NULL, "hello world"); - * str_a[5] = str_b[5] = '\0' - * - * char *app = talloc_strdup_append(str_a, ", hello"); - * char *buf = talloc_strdup_append_buffer(str_b, ", hello"); - * - * printf("%s\n", app); // hello, hello (app = "hello, hello") - * printf("%s\n", buf); // hello (buf = "hello\0world, hello") - * @endcode - * - * If s == NULL then new context is created. - * - * @param[in] s The destination buffer to append to. - * - * @param[in] a The string you want to append. - * - * @return The concatenated strings, NULL on error. - * - * @see talloc_strdup() - * @see talloc_strdup_append() - * @see talloc_array_length() - */ -char *talloc_strdup_append_buffer(char *s, const char *a); - -/** - * @brief Duplicate a length-limited string into a talloc chunk. - * - * This function is the talloc equivalent of the C library function strndup(3). - * - * This functions sets the name of the new pointer to the passed string. This is - * equivalent to: - * - * @code - * talloc_set_name_const(ptr, ptr) - * @endcode - * - * @param[in] t The talloc context to hang the result off. - * - * @param[in] p The string you want to duplicate. - * - * @param[in] n The maximum string length to duplicate. - * - * @return The duplicated string, NULL on error. - */ -char *talloc_strndup(const void *t, const char *p, size_t n); - -/** - * @brief Append at most n characters of a string to given string. - * - * The destination string is reallocated to take - * strlen(s) + strnlen(a, n) + 1 characters. - * - * This functions sets the name of the new pointer to the new - * string. This is equivalent to: - * - * @code - * talloc_set_name_const(ptr, ptr) - * @endcode - * - * If s == NULL then new context is created. - * - * @param[in] s The destination string to append to. - * - * @param[in] a The source string you want to append. - * - * @param[in] n The number of characters you want to append from the - * string. - * - * @return The concatenated strings, NULL on error. - * - * @see talloc_strndup() - * @see talloc_strndup_append_buffer() - */ -char *talloc_strndup_append(char *s, const char *a, size_t n); - -/** - * @brief Append at most n characters of a string to given buffer - * - * This is a more efficient version of talloc_strndup_append(). It determines - * the length of the destination string by the size of the talloc context. - * - * Use this very carefully as it produces a different result than - * talloc_strndup_append() when a zero character is in the middle of the - * destination string. - * - * @code - * char *str_a = talloc_strdup(NULL, "hello world"); - * char *str_b = talloc_strdup(NULL, "hello world"); - * str_a[5] = str_b[5] = '\0' - * - * char *app = talloc_strndup_append(str_a, ", hello", 7); - * char *buf = talloc_strndup_append_buffer(str_b, ", hello", 7); - * - * printf("%s\n", app); // hello, hello (app = "hello, hello") - * printf("%s\n", buf); // hello (buf = "hello\0world, hello") - * @endcode - * - * If s == NULL then new context is created. - * - * @param[in] s The destination buffer to append to. - * - * @param[in] a The source string you want to append. - * - * @param[in] n The number of characters you want to append from the - * string. - * - * @return The concatenated strings, NULL on error. - * - * @see talloc_strndup() - * @see talloc_strndup_append() - * @see talloc_array_length() - */ -char *talloc_strndup_append_buffer(char *s, const char *a, size_t n); - -/** - * @brief Format a string given a va_list. - * - * This function is the talloc equivalent of the C library function - * vasprintf(3). - * - * This functions sets the name of the new pointer to the new string. This is - * equivalent to: - * - * @code - * talloc_set_name_const(ptr, ptr) - * @endcode - * - * @param[in] t The talloc context to hang the result off. - * - * @param[in] fmt The format string. - * - * @param[in] ap The parameters used to fill fmt. - * - * @return The formatted string, NULL on error. - */ -char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); - -/** - * @brief Format a string given a va_list and append it to the given destination - * string. - * - * @param[in] s The destination string to append to. - * - * @param[in] fmt The format string. - * - * @param[in] ap The parameters used to fill fmt. - * - * @return The formatted string, NULL on error. - * - * @see talloc_vasprintf() - */ -char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); - -/** - * @brief Format a string given a va_list and append it to the given destination - * buffer. - * - * @param[in] s The destination buffer to append to. - * - * @param[in] fmt The format string. - * - * @param[in] ap The parameters used to fill fmt. - * - * @return The formatted string, NULL on error. - * - * @see talloc_vasprintf() - */ -char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); - -/** - * @brief Format a string. - * - * This function is the talloc equivalent of the C library function asprintf(3). - * - * This functions sets the name of the new pointer to the new string. This is - * equivalent to: - * - * @code - * talloc_set_name_const(ptr, ptr) - * @endcode - * - * @param[in] t The talloc context to hang the result off. - * - * @param[in] fmt The format string. - * - * @param[in] ... The parameters used to fill fmt. - * - * @return The formatted string, NULL on error. - */ -char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); - -/** - * @brief Append a formatted string to another string. - * - * This function appends the given formatted string to the given string. Use - * this variant when the string in the current talloc buffer may have been - * truncated in length. - * - * This functions sets the name of the new pointer to the new - * string. This is equivalent to: - * - * @code - * talloc_set_name_const(ptr, ptr) - * @endcode - * - * If s == NULL then new context is created. - * - * @param[in] s The string to append to. - * - * @param[in] fmt The format string. - * - * @param[in] ... The parameters used to fill fmt. - * - * @return The formatted string, NULL on error. - */ -char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); - -/** - * @brief Append a formatted string to another string. - * - * This is a more efficient version of talloc_asprintf_append(). It determines - * the length of the destination string by the size of the talloc context. - * - * Use this very carefully as it produces a different result than - * talloc_asprintf_append() when a zero character is in the middle of the - * destination string. - * - * @code - * char *str_a = talloc_strdup(NULL, "hello world"); - * char *str_b = talloc_strdup(NULL, "hello world"); - * str_a[5] = str_b[5] = '\0' - * - * char *app = talloc_asprintf_append(str_a, "%s", ", hello"); - * char *buf = talloc_strdup_append_buffer(str_b, "%s", ", hello"); - * - * printf("%s\n", app); // hello, hello (app = "hello, hello") - * printf("%s\n", buf); // hello (buf = "hello\0world, hello") - * @endcode - * - * If s == NULL then new context is created. - * - * @param[in] s The string to append to - * - * @param[in] fmt The format string. - * - * @param[in] ... The parameters used to fill fmt. - * - * @return The formatted string, NULL on error. - * - * @see talloc_asprintf() - * @see talloc_asprintf_append() - */ -char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); - -/* @} ******************************************************************/ - -/** - * @defgroup talloc_debug The talloc debugging support functions - * @ingroup talloc - * - * To aid memory debugging, talloc contains routines to inspect the currently - * allocated memory hierarchy. - * - * @{ - */ - -/** - * @brief Walk a complete talloc hierarchy. - * - * This provides a more flexible reports than talloc_report(). It - * will recursively call the callback for the entire tree of memory - * referenced by the pointer. References in the tree are passed with - * is_ref = 1 and the pointer that is referenced. - * - * You can pass NULL for the pointer, in which case a report is - * printed for the top level memory context, but only if - * talloc_enable_leak_report() or talloc_enable_leak_report_full() - * has been called. - * - * The recursion is stopped when depth >= max_depth. - * max_depth = -1 means only stop at leaf nodes. - * - * @param[in] ptr The talloc chunk. - * - * @param[in] depth Internal parameter to control recursion. Call with 0. - * - * @param[in] max_depth Maximum recursion level. - * - * @param[in] callback Function to be called on every chunk. - * - * @param[in] private_data Private pointer passed to callback. - */ -void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, - void (*callback)(const void *ptr, - int depth, int max_depth, - int is_ref, - void *private_data), - void *private_data); - -/** - * @brief Print a talloc hierarchy. - * - * This provides a more flexible reports than talloc_report(). It - * will let you specify the depth and max_depth. - * - * @param[in] ptr The talloc chunk. - * - * @param[in] depth Internal parameter to control recursion. Call with 0. - * - * @param[in] max_depth Maximum recursion level. - * - * @param[in] f The file handle to print to. - */ -void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f); - -/** - * @brief Print a summary report of all memory used by ptr. - * - * This provides a more detailed report than talloc_report(). It will - * recursively print the entire tree of memory referenced by the - * pointer. References in the tree are shown by giving the name of the - * pointer that is referenced. - * - * You can pass NULL for the pointer, in which case a report is printed - * for the top level memory context, but only if - * talloc_enable_leak_report() or talloc_enable_leak_report_full() has - * been called. - * - * @param[in] ptr The talloc chunk. - * - * @param[in] f The file handle to print to. - * - * Example: - * @code - * unsigned int *a, *b; - * a = talloc(NULL, unsigned int); - * b = talloc(a, unsigned int); - * fprintf(stderr, "Dumping memory tree for a:\n"); - * talloc_report_full(a, stderr); - * @endcode - * - * @see talloc_report() - */ -void talloc_report_full(const void *ptr, FILE *f); - -/** - * @brief Print a summary report of all memory used by ptr. - * - * This function prints a summary report of all memory used by ptr. One line of - * report is printed for each immediate child of ptr, showing the total memory - * and number of blocks used by that child. - * - * You can pass NULL for the pointer, in which case a report is printed - * for the top level memory context, but only if talloc_enable_leak_report() - * or talloc_enable_leak_report_full() has been called. - * - * @param[in] ptr The talloc chunk. - * - * @param[in] f The file handle to print to. - * - * Example: - * @code - * unsigned int *a, *b; - * a = talloc(NULL, unsigned int); - * b = talloc(a, unsigned int); - * fprintf(stderr, "Summary of memory tree for a:\n"); - * talloc_report(a, stderr); - * @endcode - * - * @see talloc_report_full() - */ -void talloc_report(const void *ptr, FILE *f); - -/** - * @brief Enable tracking the use of NULL memory contexts. - * - * This enables tracking of the NULL memory context without enabling leak - * reporting on exit. Useful for when you want to do your own leak - * reporting call via talloc_report_null_full(); - */ -void talloc_enable_null_tracking(void); - -/** - * @brief Enable tracking the use of NULL memory contexts. - * - * This enables tracking of the NULL memory context without enabling leak - * reporting on exit. Useful for when you want to do your own leak - * reporting call via talloc_report_null_full(); - */ -void talloc_enable_null_tracking_no_autofree(void); - -/** - * @brief Disable tracking of the NULL memory context. - * - * This disables tracking of the NULL memory context. - */ -void talloc_disable_null_tracking(void); - -/** - * @brief Enable leak report when a program exits. - * - * This enables calling of talloc_report(NULL, stderr) when the program - * exits. In Samba4 this is enabled by using the --leak-report command - * line option. - * - * For it to be useful, this function must be called before any other - * talloc function as it establishes a "null context" that acts as the - * top of the tree. If you don't call this function first then passing - * NULL to talloc_report() or talloc_report_full() won't give you the - * full tree printout. - * - * Here is a typical talloc report: - * - * @code - * talloc report on 'null_context' (total 267 bytes in 15 blocks) - * libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks - * libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks - * iconv(UTF8,CP850) contains 42 bytes in 2 blocks - * libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks - * iconv(CP850,UTF8) contains 42 bytes in 2 blocks - * iconv(UTF8,UTF-16LE) contains 45 bytes in 2 blocks - * iconv(UTF-16LE,UTF8) contains 45 bytes in 2 blocks - * @endcode - */ -void talloc_enable_leak_report(void); - -/** - * @brief Enable full leak report when a program exits. - * - * This enables calling of talloc_report_full(NULL, stderr) when the - * program exits. In Samba4 this is enabled by using the - * --leak-report-full command line option. - * - * For it to be useful, this function must be called before any other - * talloc function as it establishes a "null context" that acts as the - * top of the tree. If you don't call this function first then passing - * NULL to talloc_report() or talloc_report_full() won't give you the - * full tree printout. - * - * Here is a typical full report: - * - * @code - * full talloc report on 'root' (total 18 bytes in 8 blocks) - * p1 contains 18 bytes in 7 blocks (ref 0) - * r1 contains 13 bytes in 2 blocks (ref 0) - * reference to: p2 - * p2 contains 1 bytes in 1 blocks (ref 1) - * x3 contains 1 bytes in 1 blocks (ref 0) - * x2 contains 1 bytes in 1 blocks (ref 0) - * x1 contains 1 bytes in 1 blocks (ref 0) - * @endcode - */ -void talloc_enable_leak_report_full(void); - -/** - * @brief Set a custom "abort" function that is called on serious error. - * - * The default "abort" function is abort(). - * - * The "abort" function is called when: - * - *
        - *
      • talloc_get_type_abort() fails
      • - *
      • the provided pointer is not a valid talloc context
      • - *
      • when the context meta data are invalid
      • - *
      • when access after free is detected
      • - *
      - * - * Example: - * - * @code - * void my_abort(const char *reason) - * { - * fprintf(stderr, "talloc abort: %s\n", reason); - * abort(); - * } - * - * talloc_set_abort_fn(my_abort); - * @endcode - * - * @param[in] abort_fn The new "abort" function. - * - * @see talloc_set_log_fn() - * @see talloc_get_type() - */ -void talloc_set_abort_fn(void (*abort_fn)(const char *reason)); - -/** - * @brief Set a logging function. - * - * @param[in] log_fn The logging function. - * - * @see talloc_set_log_stderr() - * @see talloc_set_abort_fn() - */ -void talloc_set_log_fn(void (*log_fn)(const char *message)); - -/** - * @brief Set stderr as the output for logs. - * - * @see talloc_set_log_fn() - * @see talloc_set_abort_fn() - */ -void talloc_set_log_stderr(void); - -/** - * @brief Set a max memory limit for the current context hierarchy - * This affects all children of this context and constrain any - * allocation in the hierarchy to never exceed the limit set. - * The limit can be removed by setting 0 (unlimited) as the - * max_size by calling the function again on the same context. - * Memory limits can also be nested, meaning a child can have - * a stricter memory limit than a parent. - * Memory limits are enforced only at memory allocation time. - * Stealing a context into a 'limited' hierarchy properly - * updates memory usage but does *not* cause failure if the - * move causes the new parent to exceed its limits. However - * any further allocation on that hierarchy will then fail. - * - * @warning talloc memlimit functionality is deprecated. Please - * consider using cgroup memory limits instead. - * - * @param[in] ctx The talloc context to set the limit on - * @param[in] max_size The (new) max_size - */ -int talloc_set_memlimit(const void *ctx, size_t max_size) _DEPRECATED_; - -/* @} ******************************************************************/ - -#if TALLOC_DEPRECATED -#define talloc_zero_p(ctx, type) talloc_zero(ctx, type) -#define talloc_p(ctx, type) talloc(ctx, type) -#define talloc_array_p(ctx, type, count) talloc_array(ctx, type, count) -#define talloc_realloc_p(ctx, p, type, count) talloc_realloc(ctx, p, type, count) -#define talloc_destroy(ctx) talloc_free(ctx) -#define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a)) -#endif - -#ifndef TALLOC_MAX_DEPTH -#define TALLOC_MAX_DEPTH 10000 -#endif - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -#endif diff --git a/ldb-2.0.8/lib/talloc/talloc.pc.in b/ldb-2.0.8/lib/talloc/talloc.pc.in deleted file mode 100644 index 437281a..0000000 --- a/ldb-2.0.8/lib/talloc/talloc.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: talloc -Description: A hierarchical pool based memory system with destructors -Version: @TALLOC_VERSION@ -Libs: @LIB_RPATH@ -L${libdir} -ltalloc -Cflags: -I${includedir} -URL: http://talloc.samba.org/ diff --git a/ldb-2.0.8/lib/talloc/talloc_guide.txt b/ldb-2.0.8/lib/talloc/talloc_guide.txt deleted file mode 100644 index dedda6c..0000000 --- a/ldb-2.0.8/lib/talloc/talloc_guide.txt +++ /dev/null @@ -1,768 +0,0 @@ -Using talloc in Samba4 -====================== - -.. contents:: - -Andrew Tridgell -August 2009 - -The most current version of this document is available at - http://samba.org/ftp/unpacked/talloc/talloc_guide.txt - -If you are used to the "old" talloc from Samba3 before 3.0.20 then please read -this carefully, as talloc has changed a lot. With 3.0.20 (or 3.0.14?) the -Samba4 talloc has been ported back to Samba3, so this guide applies to both. - -The new talloc is a hierarchical, reference counted memory pool system -with destructors. Quite a mouthful really, but not too bad once you -get used to it. - -Perhaps the biggest change from Samba3 is that there is no distinction -between a "talloc context" and a "talloc pointer". Any pointer -returned from talloc() is itself a valid talloc context. This means -you can do this:: - - struct foo *X = talloc(mem_ctx, struct foo); - X->name = talloc_strdup(X, "foo"); - -and the pointer X->name would be a "child" of the talloc context "X" -which is itself a child of "mem_ctx". So if you do talloc_free(mem_ctx) -then it is all destroyed, whereas if you do talloc_free(X) then just X -and X->name are destroyed, and if you do talloc_free(X->name) then -just the name element of X is destroyed. - -If you think about this, then what this effectively gives you is an -n-ary tree, where you can free any part of the tree with -talloc_free(). - -If you find this confusing, then I suggest you run the testsuite to -watch talloc in action. You may also like to add your own tests to -testsuite.c to clarify how some particular situation is handled. - - -Performance ------------ - -All the additional features of talloc() over malloc() do come at a -price. We have a simple performance test in Samba4 that measures -talloc() versus malloc() performance, and it seems that talloc() is -about 4% slower than malloc() on my x86 Debian Linux box. For Samba, -the great reduction in code complexity that we get by using talloc -makes this worthwhile, especially as the total overhead of -talloc/malloc in Samba is already quite small. - - -talloc API ----------- - -The following is a complete guide to the talloc API. Read it all at -least twice. - -Multi-threading ---------------- - -talloc itself does not deal with threads. It is thread-safe (assuming -the underlying "malloc" is), as long as each thread uses different -memory contexts. -If two threads use the same context then they need to synchronize in -order to be safe. In particular: -- when using talloc_enable_leak_report(), giving directly NULL as a -parent context implicitly refers to a hidden "null context" global -variable, so this should not be used in a multi-threaded environment -without proper synchronization. In threaded code turn off null tracking using -talloc_disable_null_tracking(). ; -- the context returned by talloc_autofree_context() is also global so -shouldn't be used by several threads simultaneously without -synchronization. - -talloc and shared objects -------------------------- - -talloc can be used in shared objects. Special care needs to be taken -to never use talloc_autofree_context() in code that might be loaded -with dlopen() and unloaded with dlclose(), as talloc_autofree_context() -internally uses atexit(3). Some platforms like modern Linux handles -this fine, but for example FreeBSD does not deal well with dlopen() -and atexit() used simultaneously: dlclose() does not clean up the list -of atexit-handlers, so when the program exits the code that was -registered from within talloc_autofree_context() is gone, the program -crashes at exit. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(type *)talloc(const void *context, type); - -The talloc() macro is the core of the talloc library. It takes a -memory context and a type, and returns a pointer to a new area of -memory of the given type. - -The returned pointer is itself a talloc context, so you can use it as -the context argument to more calls to talloc if you wish. - -The returned pointer is a "child" of the supplied context. This means -that if you talloc_free() the context then the new child disappears as -well. Alternatively you can free just the child. - -The context argument to talloc() can be NULL, in which case a new top -level context is created. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_size(const void *context, size_t size); - -The function talloc_size() should be used when you don't have a -convenient type to pass to talloc(). Unlike talloc(), it is not type -safe (as it returns a void *), so you are on your own for type checking. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(typeof(ptr)) talloc_ptrtype(const void *ctx, ptr); - -The talloc_ptrtype() macro should be used when you have a pointer and -want to allocate memory to point at with this pointer. When compiling -with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_size() -and talloc_get_name() will return the current location in the source file. -and not the type. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -int talloc_free(void *ptr); - -The talloc_free() function frees a piece of talloc memory, and all its -children. You can call talloc_free() on any pointer returned by -talloc(). - -The return value of talloc_free() indicates success or failure, with 0 -returned for success and -1 for failure. A possible failure condition -is if the pointer had a destructor attached to it and the destructor -returned -1. See talloc_set_destructor() for details on -destructors. Likewise, if "ptr" is NULL, then the function will make -no modifications and returns -1. - -From version 2.0 and onwards, as a special case, talloc_free() is -refused on pointers that have more than one parent associated, as talloc -would have no way of knowing which parent should be removed. This is -different from older versions in the sense that always the reference to -the most recently established parent has been destroyed. Hence to free a -pointer that has more than one parent please use talloc_unlink(). - -To help you find problems in your code caused by this behaviour, if -you do try and free a pointer with more than one parent then the -talloc logging function will be called to give output like this: - - ERROR: talloc_free with references at some_dir/source/foo.c:123 - reference at some_dir/source/other.c:325 - reference at some_dir/source/third.c:121 - -Please see the documentation for talloc_set_log_fn() and -talloc_set_log_stderr() for more information on talloc logging -functions. - -talloc_free() operates recursively on its children. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_free_children(void *ptr); - -The talloc_free_children() walks along the list of all children of a -talloc context and talloc_free()s only the children, not the context -itself. - -A NULL argument is handled as no-op. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_reference(const void *context, const void *ptr); - -The talloc_reference() function makes "context" an additional parent -of "ptr". - -The return value of talloc_reference() is always the original pointer -"ptr", unless talloc ran out of memory in creating the reference in -which case it will return NULL (each additional reference consumes -around 48 bytes of memory on intel x86 platforms). - -If "ptr" is NULL, then the function is a no-op, and simply returns NULL. - -After creating a reference you can free it in one of the following -ways: - - - you can talloc_free() any parent of the original pointer. That - will reduce the number of parents of this pointer by 1, and will - cause this pointer to be freed if it runs out of parents. - - - you can talloc_free() the pointer itself if it has at maximum one - parent. This behaviour has been changed since the release of version - 2.0. Further information in the description of "talloc_free". - -For more control on which parent to remove, see talloc_unlink() - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -int talloc_unlink(const void *context, void *ptr); - -The talloc_unlink() function removes a specific parent from ptr. The -context passed must either be a context used in talloc_reference() -with this pointer, or must be a direct parent of ptr. - -Note that if the parent has already been removed using talloc_free() -then this function will fail and will return -1. Likewise, if "ptr" -is NULL, then the function will make no modifications and return -1. - -You can just use talloc_free() instead of talloc_unlink() if there -is at maximum one parent. This behaviour has been changed since the -release of version 2.0. Further information in the description of -"talloc_free". - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_set_destructor(const void *ptr, int (*destructor)(void *)); - -The function talloc_set_destructor() sets the "destructor" for the -pointer "ptr". A destructor is a function that is called when the -memory used by a pointer is about to be released. The destructor -receives the pointer as an argument, and should return 0 for success -and -1 for failure. - -The destructor can do anything it wants to, including freeing other -pieces of memory. A common use for destructors is to clean up -operating system resources (such as open file descriptors) contained -in the structure the destructor is placed on. - -You can only place one destructor on a pointer. If you need more than -one destructor then you can create a zero-length child of the pointer -and place an additional destructor on that. - -To remove a destructor call talloc_set_destructor() with NULL for the -destructor. - -If your destructor attempts to talloc_free() the pointer that it is -the destructor for then talloc_free() will return -1 and the free will -be ignored. This would be a pointless operation anyway, as the -destructor is only called when the memory is just about to go away. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -int talloc_increase_ref_count(const void *ptr); - -The talloc_increase_ref_count(ptr) function is exactly equivalent to: - - talloc_reference(NULL, ptr); - -You can use either syntax, depending on which you think is clearer in -your code. - -It returns 0 on success and -1 on failure. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -size_t talloc_reference_count(const void *ptr); - -Return the number of references to the pointer. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_set_name(const void *ptr, const char *fmt, ...); - -Each talloc pointer has a "name". The name is used principally for -debugging purposes, although it is also possible to set and get the -name on a pointer in as a way of "marking" pointers in your code. - -The main use for names on pointer is for "talloc reports". See -talloc_report() and talloc_report_full() for details. Also see -talloc_enable_leak_report() and talloc_enable_leak_report_full(). - -The talloc_set_name() function allocates memory as a child of the -pointer. It is logically equivalent to: - talloc_set_name_const(ptr, talloc_asprintf(ptr, fmt, ...)); - -Note that multiple calls to talloc_set_name() will allocate more -memory without releasing the name. All of the memory is released when -the ptr is freed using talloc_free(). - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_set_name_const(const void *ptr, const char *name); - -The function talloc_set_name_const() is just like talloc_set_name(), -but it takes a string constant, and is much faster. It is extensively -used by the "auto naming" macros, such as talloc_p(). - -This function does not allocate any memory. It just copies the -supplied pointer into the internal representation of the talloc -ptr. This means you must not pass a name pointer to memory that will -disappear before the ptr is freed with talloc_free(). - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_named(const void *context, size_t size, const char *fmt, ...); - -The talloc_named() function creates a named talloc pointer. It is -equivalent to: - - ptr = talloc_size(context, size); - talloc_set_name(ptr, fmt, ....); - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_named_const(const void *context, size_t size, const char *name); - -This is equivalent to:: - - ptr = talloc_size(context, size); - talloc_set_name_const(ptr, name); - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -const char *talloc_get_name(const void *ptr); - -This returns the current name for the given talloc pointer. See -talloc_set_name() for details. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_init(const char *fmt, ...); - -This function creates a zero length named talloc context as a top -level context. It is equivalent to:: - - talloc_named(NULL, 0, fmt, ...); - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_new(void *ctx); - -This is a utility macro that creates a new memory context hanging -off an exiting context, automatically naming it "talloc_new: __location__" -where __location__ is the source line it is called from. It is -particularly useful for creating a new temporary working context. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(type *)talloc_realloc(const void *context, void *ptr, type, count); - -The talloc_realloc() macro changes the size of a talloc -pointer. The "count" argument is the number of elements of type "type" -that you want the resulting pointer to hold. - -talloc_realloc() has the following equivalences:: - - talloc_realloc(context, NULL, type, 1) ==> talloc(context, type); - talloc_realloc(context, NULL, type, N) ==> talloc_array(context, type, N); - talloc_realloc(context, ptr, type, 0) ==> talloc_free(ptr); - -The "context" argument is only used if "ptr" is NULL, otherwise it is -ignored. - -talloc_realloc() returns the new pointer, or NULL on failure. The call -will fail either due to a lack of memory, or because the pointer has -more than one parent (see talloc_reference()). - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_realloc_size(const void *context, void *ptr, size_t size); - -the talloc_realloc_size() function is useful when the type is not -known so the typesafe talloc_realloc() cannot be used. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_steal(const void *new_ctx, const void *ptr); - -The talloc_steal() function changes the parent context of a talloc -pointer. It is typically used when the context that the pointer is -currently a child of is going to be freed and you wish to keep the -memory for a longer time. - -The talloc_steal() function returns the pointer that you pass it. It -does not have any failure modes. - -NOTE: It is possible to produce loops in the parent/child relationship -if you are not careful with talloc_steal(). No guarantees are provided -as to your sanity or the safety of your data if you do this. - -talloc_steal (new_ctx, NULL) will return NULL with no sideeffects. - -Note that if you try and call talloc_steal() on a pointer that has -more than one parent then the result is ambiguous. Talloc will choose -to remove the parent that is currently indicated by talloc_parent() -and replace it with the chosen parent. You will also get a message -like this via the talloc logging functions: - - WARNING: talloc_steal with references at some_dir/source/foo.c:123 - reference at some_dir/source/other.c:325 - reference at some_dir/source/third.c:121 - -To unambiguously change the parent of a pointer please see the -function talloc_reparent(). See the talloc_set_log_fn() documentation -for more information on talloc logging. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr); - -The talloc_reparent() function changes the parent context of a talloc -pointer. It is typically used when the context that the pointer is -currently a child of is going to be freed and you wish to keep the -memory for a longer time. - -The talloc_reparent() function returns the pointer that you pass it. It -does not have any failure modes. - -The difference between talloc_reparent() and talloc_steal() is that -talloc_reparent() can specify which parent you wish to change. This is -useful when a pointer has multiple parents via references. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_parent(const void *ptr); - -The talloc_parent() function returns the current talloc parent. This -is usually the pointer under which this memory was originally created, -but it may have changed due to a talloc_steal() or talloc_reparent() - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -size_t talloc_total_size(const void *ptr); - -The talloc_total_size() function returns the total size in bytes used -by this pointer and all child pointers. Mostly useful for debugging. - -Passing NULL is allowed, but it will only give a meaningful result if -talloc_enable_leak_report() or talloc_enable_leak_report_full() has -been called. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -size_t talloc_total_blocks(const void *ptr); - -The talloc_total_blocks() function returns the total memory block -count used by this pointer and all child pointers. Mostly useful for -debugging. - -Passing NULL is allowed, but it will only give a meaningful result if -talloc_enable_leak_report() or talloc_enable_leak_report_full() has -been called. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_report_depth_cb(const void *ptr, int depth, int max_depth, - void (*callback)(const void *ptr, - int depth, int max_depth, - int is_ref, - void *priv), - void *priv); - -This provides a more flexible reports than talloc_report(). It -will recursively call the callback for the entire tree of memory -referenced by the pointer. References in the tree are passed with -is_ref = 1 and the pointer that is referenced. - -You can pass NULL for the pointer, in which case a report is -printed for the top level memory context, but only if -talloc_enable_leak_report() or talloc_enable_leak_report_full() -has been called. - -The recursion is stopped when depth >= max_depth. -max_depth = -1 means only stop at leaf nodes. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f); - -This provides a more flexible reports than talloc_report(). It -will let you specify the depth and max_depth. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_report(const void *ptr, FILE *f); - -The talloc_report() function prints a summary report of all memory -used by ptr. One line of report is printed for each immediate child of -ptr, showing the total memory and number of blocks used by that child. - -You can pass NULL for the pointer, in which case a report is printed -for the top level memory context, but only if -talloc_enable_leak_report() or talloc_enable_leak_report_full() has -been called. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_report_full(const void *ptr, FILE *f); - -This provides a more detailed report than talloc_report(). It will -recursively print the entire tree of memory referenced by the -pointer. References in the tree are shown by giving the name of the -pointer that is referenced. - -You can pass NULL for the pointer, in which case a report is printed -for the top level memory context, but only if -talloc_enable_leak_report() or talloc_enable_leak_report_full() has -been called. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_enable_leak_report(void); - -This enables calling of talloc_report(NULL, stderr) when the program -exits. In Samba4 this is enabled by using the --leak-report command -line option. - -For it to be useful, this function must be called before any other -talloc function as it establishes a "null context" that acts as the -top of the tree. If you don't call this function first then passing -NULL to talloc_report() or talloc_report_full() won't give you the -full tree printout. - -Here is a typical talloc report: - -talloc report on 'null_context' (total 267 bytes in 15 blocks) - libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks - libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks - iconv(UTF8,CP850) contains 42 bytes in 2 blocks - libcli/auth/spnego_parse.c:55 contains 31 bytes in 2 blocks - iconv(CP850,UTF8) contains 42 bytes in 2 blocks - iconv(UTF8,UTF-16LE) contains 45 bytes in 2 blocks - iconv(UTF-16LE,UTF8) contains 45 bytes in 2 blocks - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_enable_leak_report_full(void); - -This enables calling of talloc_report_full(NULL, stderr) when the -program exits. In Samba4 this is enabled by using the ---leak-report-full command line option. - -For it to be useful, this function must be called before any other -talloc function as it establishes a "null context" that acts as the -top of the tree. If you don't call this function first then passing -NULL to talloc_report() or talloc_report_full() won't give you the -full tree printout. - -Here is a typical full report: - -full talloc report on 'root' (total 18 bytes in 8 blocks) - p1 contains 18 bytes in 7 blocks (ref 0) - r1 contains 13 bytes in 2 blocks (ref 0) - reference to: p2 - p2 contains 1 bytes in 1 blocks (ref 1) - x3 contains 1 bytes in 1 blocks (ref 0) - x2 contains 1 bytes in 1 blocks (ref 0) - x1 contains 1 bytes in 1 blocks (ref 0) - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_enable_null_tracking(void); - -This enables tracking of the NULL memory context without enabling leak -reporting on exit. Useful for when you want to do your own leak -reporting call via talloc_report_null_full(); - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_disable_null_tracking(void); - -This disables tracking of the NULL memory context. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(type *)talloc_zero(const void *ctx, type); - -The talloc_zero() macro is equivalent to:: - - ptr = talloc(ctx, type); - if (ptr) memset(ptr, 0, sizeof(type)); - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_zero_size(const void *ctx, size_t size) - -The talloc_zero_size() function is useful when you don't have a known type - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_memdup(const void *ctx, const void *p, size_t size); - -The talloc_memdup() function is equivalent to:: - - ptr = talloc_size(ctx, size); - if (ptr) memcpy(ptr, p, size); - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_strdup(const void *ctx, const char *p); - -The talloc_strdup() function is equivalent to:: - - ptr = talloc_size(ctx, strlen(p)+1); - if (ptr) memcpy(ptr, p, strlen(p)+1); - -This functions sets the name of the new pointer to the passed -string. This is equivalent to:: - - talloc_set_name_const(ptr, ptr) - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_strndup(const void *t, const char *p, size_t n); - -The talloc_strndup() function is the talloc equivalent of the C -library function strndup() - -This functions sets the name of the new pointer to the passed -string. This is equivalent to: - talloc_set_name_const(ptr, ptr) - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_append_string(const void *t, char *orig, const char *append); - -The talloc_append_string() function appends the given formatted -string to the given string. - -This function sets the name of the new pointer to the new -string. This is equivalent to:: - - talloc_set_name_const(ptr, ptr) - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_vasprintf(const void *t, const char *fmt, va_list ap); - -The talloc_vasprintf() function is the talloc equivalent of the C -library function vasprintf() - -This functions sets the name of the new pointer to the new -string. This is equivalent to:: - - talloc_set_name_const(ptr, ptr) - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_asprintf(const void *t, const char *fmt, ...); - -The talloc_asprintf() function is the talloc equivalent of the C -library function asprintf() - -This functions sets the name of the new pointer to the new -string. This is equivalent to:: - - talloc_set_name_const(ptr, ptr) - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_asprintf_append(char *s, const char *fmt, ...); - -The talloc_asprintf_append() function appends the given formatted -string to the given string. -Use this variant when the string in the current talloc buffer may -have been truncated in length. - -This functions sets the name of the new pointer to the new -string. This is equivalent to:: - - talloc_set_name_const(ptr, ptr) - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...); - -The talloc_asprintf_append() function appends the given formatted -string to the end of the currently allocated talloc buffer. -Use this variant when the string in the current talloc buffer has -not been changed. - -This functions sets the name of the new pointer to the new -string. This is equivalent to:: - - talloc_set_name_const(ptr, ptr) - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -((type *)talloc_array(const void *ctx, type, unsigned int count); - -The talloc_array() macro is equivalent to:: - - (type *)talloc_size(ctx, sizeof(type) * count); - -except that it provides integer overflow protection for the multiply, -returning NULL if the multiply overflows. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_array_size(const void *ctx, size_t size, unsigned int count); - -The talloc_array_size() function is useful when the type is not -known. It operates in the same way as talloc_array(), but takes a size -instead of a type. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(typeof(ptr)) talloc_array_ptrtype(const void *ctx, ptr, unsigned int count); - -The talloc_ptrtype() macro should be used when you have a pointer to an array -and want to allocate memory of an array to point at with this pointer. When compiling -with gcc >= 3 it is typesafe. Note this is a wrapper of talloc_array_size() -and talloc_get_name() will return the current location in the source file. -and not the type. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_realloc_fn(const void *ctx, void *ptr, size_t size); - -This is a non-macro version of talloc_realloc(), which is useful -as libraries sometimes want a ralloc function pointer. A realloc() -implementation encapsulates the functionality of malloc(), free() and -realloc() in one call, which is why it is useful to be able to pass -around a single function pointer. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_autofree_context(void); - -This is a handy utility function that returns a talloc context -which will be automatically freed on program exit. This can be used -to reduce the noise in memory leak reports. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_check_name(const void *ptr, const char *name); - -This function checks if a pointer has the specified name. If it does -then the pointer is returned. It it doesn't then NULL is returned. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(type *)talloc_get_type(const void *ptr, type); - -This macro allows you to do type checking on talloc pointers. It is -particularly useful for void* private pointers. It is equivalent to -this:: - - (type *)talloc_check_name(ptr, #type) - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -talloc_set_type(const void *ptr, type); - -This macro allows you to force the name of a pointer to be of a -particular type. This can be used in conjunction with -talloc_get_type() to do type checking on void* pointers. - -It is equivalent to this:: - - talloc_set_name_const(ptr, #type) - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -talloc_get_size(const void *ctx); - -This function lets you know the amount of memory allocated so far by -this context. It does NOT account for subcontext memory. -This can be used to calculate the size of an array. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void *talloc_find_parent_byname(const void *ctx, const char *name); - -Find a parent memory context of the current context that has the given -name. This can be very useful in complex programs where it may be -difficult to pass all information down to the level you need, but you -know the structure you want is a parent of another context. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(type *)talloc_find_parent_bytype(ctx, type); - -Like talloc_find_parent_byname() but takes a type, making it typesafe. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_set_log_fn(void (*log_fn)(const char *message)); - -This function sets a logging function that talloc will use for -warnings and errors. By default talloc will not print any warnings or -errors. - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -void talloc_set_log_stderr(void) - -This sets the talloc log function to write log messages to stderr. diff --git a/ldb-2.0.8/lib/talloc/talloc_testsuite.h b/ldb-2.0.8/lib/talloc/talloc_testsuite.h deleted file mode 100644 index acb9701..0000000 --- a/ldb-2.0.8/lib/talloc/talloc_testsuite.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __LIB_TALLOC_TALLOC_TESTSUITE_H__ -#define __LIB_TALLOC_TALLOC_TESTSUITE_H__ - -struct torture_context; -bool torture_local_talloc(struct torture_context *tctx); - -#endif diff --git a/ldb-2.0.8/lib/talloc/test_magic_differs.sh b/ldb-2.0.8/lib/talloc/test_magic_differs.sh deleted file mode 100755 index 1b6ba2e..0000000 --- a/ldb-2.0.8/lib/talloc/test_magic_differs.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -# This test ensures that two different talloc processes do not use the same -# magic value to lessen the opportunity for transferrable attacks. - -echo "test: magic differs" - -helper=$1 -m1=$($helper) -m2=$($helper) - -if [ $m1 -eq $m2 ]; then - echo "failure: magic remained the same between executions ($m1 vs $m2)" - exit 1 -fi - -echo "success: magic differs" diff --git a/ldb-2.0.8/lib/talloc/test_magic_differs_helper.c b/ldb-2.0.8/lib/talloc/test_magic_differs_helper.c deleted file mode 100644 index 6798827..0000000 --- a/ldb-2.0.8/lib/talloc/test_magic_differs_helper.c +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include "talloc.h" - -/* - * This program is called by a testing shell script in order to ensure that - * if the library is loaded into different processes it uses different magic - * values in order to thwart security attacks. - */ -int main(int argc, char *argv[]) { - printf("%i\n", talloc_test_get_magic()); - return 0; -} diff --git a/ldb-2.0.8/lib/talloc/test_pytalloc.c b/ldb-2.0.8/lib/talloc/test_pytalloc.c deleted file mode 100644 index 6797b98..0000000 --- a/ldb-2.0.8/lib/talloc/test_pytalloc.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - Samba Unix SMB/CIFS implementation. - - C utilities for the pytalloc test suite. - Provides the "_test_pytalloc" Python module. - - NOTE: Please read talloc_guide.txt for full documentation - - Copyright (C) Petr Viktorin 2015 - - ** NOTE! The following LGPL license applies to the talloc - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include -#include -#include - -static PyObject *testpytalloc_new(PyTypeObject *mod, - PyObject *Py_UNUSED(ignored)) -{ - char *obj = talloc_strdup(NULL, "This is a test string");; - return pytalloc_steal(pytalloc_GetObjectType(), obj); -} - -static PyObject *testpytalloc_get_object_type(PyObject *mod, - PyObject *Py_UNUSED(ignored)) -{ - PyObject *type = (PyObject *)pytalloc_GetObjectType(); - Py_INCREF(type); - return type; -} - -static PyObject *testpytalloc_base_new(PyTypeObject *mod, - PyObject *Py_UNUSED(ignored)) -{ - char *obj = talloc_strdup(NULL, "This is a test string for a BaseObject");; - return pytalloc_steal(pytalloc_GetBaseObjectType(), obj); -} - -static PyObject *testpytalloc_base_get_object_type(PyObject *mod, - PyObject *Py_UNUSED(ignored)) -{ - PyObject *type = (PyObject *)pytalloc_GetBaseObjectType(); - Py_INCREF(type); - return type; -} - -static PyObject *testpytalloc_reference(PyObject *mod, PyObject *args) { - PyObject *source = NULL; - void *ptr; - - if (!PyArg_ParseTuple(args, "O!", pytalloc_GetObjectType(), &source)) - return NULL; - - ptr = pytalloc_get_ptr(source); - return pytalloc_reference_ex(pytalloc_GetObjectType(), ptr, ptr); -} - -static PyObject *testpytalloc_base_reference(PyObject *mod, PyObject *args) { - PyObject *source = NULL; - void *mem_ctx; - - if (!PyArg_ParseTuple(args, "O!", pytalloc_GetBaseObjectType(), &source)) { - return NULL; - } - mem_ctx = pytalloc_get_mem_ctx(source); - return pytalloc_reference_ex(pytalloc_GetBaseObjectType(), mem_ctx, mem_ctx); -} - -static PyMethodDef test_talloc_methods[] = { - { "new", (PyCFunction)testpytalloc_new, METH_NOARGS, - "create a talloc Object with a testing string"}, - { "get_object_type", (PyCFunction)testpytalloc_get_object_type, METH_NOARGS, - "call pytalloc_GetObjectType"}, - { "base_new", (PyCFunction)testpytalloc_base_new, METH_NOARGS, - "create a talloc BaseObject with a testing string"}, - { "base_get_object_type", (PyCFunction)testpytalloc_base_get_object_type, METH_NOARGS, - "call pytalloc_GetBaseObjectType"}, - { "reference", (PyCFunction)testpytalloc_reference, METH_VARARGS, - "call pytalloc_reference_ex"}, - { "base_reference", (PyCFunction)testpytalloc_base_reference, METH_VARARGS, - "call pytalloc_reference_ex"}, - { NULL } -}; - -static PyTypeObject DObject_Type; - -static int dobject_destructor(void *ptr) -{ - PyObject *destructor_func = *talloc_get_type(ptr, PyObject*); - PyObject *ret; - ret = PyObject_CallObject(destructor_func, NULL); - Py_DECREF(destructor_func); - if (ret == NULL) { - PyErr_Print(); - } else { - Py_DECREF(ret); - } - return 0; -} - -static PyObject *dobject_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyObject *destructor_func = NULL; - PyObject **obj; - - if (!PyArg_ParseTuple(args, "O", &destructor_func)) - return NULL; - Py_INCREF(destructor_func); - - obj = talloc(NULL, PyObject*); - *obj = destructor_func; - - talloc_set_destructor((void*)obj, dobject_destructor); - return pytalloc_steal(&DObject_Type, obj); -} - -static PyTypeObject DObject_Type = { - .tp_name = "_test_pytalloc.DObject", - .tp_basicsize = sizeof(pytalloc_Object), - .tp_methods = NULL, - .tp_new = dobject_new, - .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_doc = "test talloc object that calls a function when underlying data is freed\n", -}; - -static PyTypeObject DBaseObject_Type; - -static int d_base_object_destructor(void *ptr) -{ - PyObject *destructor_func = *talloc_get_type(ptr, PyObject*); - PyObject *ret; - ret = PyObject_CallObject(destructor_func, NULL); - Py_DECREF(destructor_func); - if (ret == NULL) { - PyErr_Print(); - } else { - Py_DECREF(ret); - } - return 0; -} - -static PyObject *d_base_object_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyObject *destructor_func = NULL; - PyObject **obj; - - if (!PyArg_ParseTuple(args, "O", &destructor_func)) - return NULL; - Py_INCREF(destructor_func); - - obj = talloc(NULL, PyObject*); - *obj = destructor_func; - - talloc_set_destructor((void*)obj, d_base_object_destructor); - return pytalloc_steal(&DBaseObject_Type, obj); -} - -static PyTypeObject DBaseObject_Type = { - .tp_name = "_test_pytalloc.DBaseObject", - .tp_methods = NULL, - .tp_new = d_base_object_new, - .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_doc = "test talloc object that calls a function when underlying data is freed\n", -}; - -#define MODULE_DOC PyDoc_STR("Test utility module for pytalloc") - -#if PY_MAJOR_VERSION >= 3 -static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - .m_name = "_test_pytalloc", - .m_doc = PyDoc_STR("Test utility module for pytalloc"), - .m_size = -1, - .m_methods = test_talloc_methods, -}; -#endif - -static PyObject *module_init(void); -static PyObject *module_init(void) -{ - PyObject *m; - - DObject_Type.tp_base = pytalloc_GetObjectType(); - if (PyType_Ready(&DObject_Type) < 0) { - return NULL; - } - - DBaseObject_Type.tp_basicsize = pytalloc_BaseObject_size(); - DBaseObject_Type.tp_base = pytalloc_GetBaseObjectType(); - if (PyType_Ready(&DBaseObject_Type) < 0) { - return NULL; - } - -#if PY_MAJOR_VERSION >= 3 - m = PyModule_Create(&moduledef); -#else - m = Py_InitModule3("_test_pytalloc", test_talloc_methods, MODULE_DOC); -#endif - - if (m == NULL) { - return NULL; - } - - Py_INCREF(&DObject_Type); - Py_INCREF(DObject_Type.tp_base); - PyModule_AddObject(m, "DObject", (PyObject *)&DObject_Type); - - Py_INCREF(&DBaseObject_Type); - Py_INCREF(DBaseObject_Type.tp_base); - PyModule_AddObject(m, "DBaseObject", (PyObject *)&DBaseObject_Type); - - return m; -} - - -#if PY_MAJOR_VERSION >= 3 -PyMODINIT_FUNC PyInit__test_pytalloc(void); -PyMODINIT_FUNC PyInit__test_pytalloc(void) -{ - return module_init(); -} -#else -void init_test_pytalloc(void); -void init_test_pytalloc(void) -{ - module_init(); -} -#endif diff --git a/ldb-2.0.8/lib/talloc/test_pytalloc.py b/ldb-2.0.8/lib/talloc/test_pytalloc.py deleted file mode 100644 index 809510f..0000000 --- a/ldb-2.0.8/lib/talloc/test_pytalloc.py +++ /dev/null @@ -1,189 +0,0 @@ -#!/usr/bin/env python3 -# Simple tests for the talloc python bindings. -# Copyright (C) 2015 Petr Viktorin - -import unittest -import subprocess -import sys -import gc - -import talloc -import _test_pytalloc - - -def dummy_func(): - pass - - -class TallocTests(unittest.TestCase): - - def test_report_full(self): - # report_full is hardcoded to print to stdout, so use a subprocess - process = subprocess.Popen([ - sys.executable, '-c', - """if True: - import talloc, _test_pytalloc - obj = _test_pytalloc.new() - talloc.report_full(obj) - """ - ], stdout=subprocess.PIPE) - output, stderr = process.communicate() - output = str(output) - self.assertTrue("full talloc report on 'talloc.Object" in output) - self.assertTrue("This is a test string" in output) - - def test_totalblocks(self): - obj = _test_pytalloc.new() - # Two blocks: the string, and the name - self.assertEqual(talloc.total_blocks(obj), 2) - - def test_repr(self): - obj = _test_pytalloc.new() - prefix = '= obj1) - self.assertFalse(obj1 > obj1) - - def test_compare_different(self): - # object comparison is consistent - obj1, obj2 = sorted([ - _test_pytalloc.new(), - _test_pytalloc.new()]) - self.assertFalse(obj1 == obj2) - self.assertTrue(obj1 != obj2) - self.assertTrue(obj1 <= obj2) - self.assertTrue(obj1 < obj2) - self.assertFalse(obj1 >= obj2) - self.assertFalse(obj1 > obj2) - - def test_compare_different_types(self): - # object comparison falls back to comparing types - if sys.version_info >= (3, 0): - # In Python 3, types are unorderable -- nothing to test - return - if talloc.Object < _test_pytalloc.DObject: - obj1 = _test_pytalloc.new() - obj2 = _test_pytalloc.DObject(dummy_func) - else: - obj2 = _test_pytalloc.new() - obj1 = _test_pytalloc.DObject(dummy_func) - self.assertFalse(obj1 == obj2) - self.assertTrue(obj1 != obj2) - self.assertTrue(obj1 <= obj2) - self.assertTrue(obj1 < obj2) - self.assertFalse(obj1 >= obj2) - self.assertFalse(obj1 > obj2) - - -class TallocBaseComparisonTests(unittest.TestCase): - - def test_compare_same(self): - obj1 = _test_pytalloc.base_new() - self.assertTrue(obj1 == obj1) - self.assertFalse(obj1 != obj1) - self.assertTrue(obj1 <= obj1) - self.assertFalse(obj1 < obj1) - self.assertTrue(obj1 >= obj1) - self.assertFalse(obj1 > obj1) - - def test_compare_different(self): - # object comparison is consistent - obj1, obj2 = sorted([ - _test_pytalloc.base_new(), - _test_pytalloc.base_new()]) - self.assertFalse(obj1 == obj2) - self.assertTrue(obj1 != obj2) - self.assertTrue(obj1 <= obj2) - self.assertTrue(obj1 < obj2) - self.assertFalse(obj1 >= obj2) - self.assertFalse(obj1 > obj2) - - def test_compare_different_types(self): - # object comparison falls back to comparing types - if sys.version_info >= (3, 0): - # In Python 3, types are unorderable -- nothing to test - return - if talloc.BaseObject < _test_pytalloc.DBaseObject: - obj1 = _test_pytalloc.base_new() - obj2 = _test_pytalloc.DBaseObject(dummy_func) - else: - obj2 = _test_pytalloc.base_new() - obj1 = _test_pytalloc.DBaseObject(dummy_func) - self.assertFalse(obj1 == obj2) - self.assertTrue(obj1 != obj2) - self.assertTrue(obj1 <= obj2) - self.assertTrue(obj1 < obj2) - self.assertFalse(obj1 >= obj2) - self.assertFalse(obj1 > obj2) - - -class TallocUtilTests(unittest.TestCase): - - def test_get_type(self): - self.assertTrue(talloc.Object is _test_pytalloc.get_object_type()) - - def test_reference(self): - # Check correct lifetime of the talloc'd data with multiple references - lst = [] - obj = _test_pytalloc.DObject(lambda: lst.append('dead')) - ref = _test_pytalloc.reference(obj) - del obj - gc.collect() - self.assertEqual(lst, []) - del ref - gc.collect() - self.assertEqual(lst, ['dead']) - - def test_get_base_type(self): - self.assertTrue(talloc.BaseObject is _test_pytalloc.base_get_object_type()) - - def test_base_reference(self): - # Check correct lifetime of the talloc'd data with multiple references - lst = [] - obj = _test_pytalloc.DBaseObject(lambda: lst.append('dead')) - ref = _test_pytalloc.base_reference(obj) - del obj - gc.collect() - self.assertEqual(lst, []) - del ref - gc.collect() - self.assertEqual(lst, ['dead']) - - -if __name__ == '__main__': - unittest.TestProgram() diff --git a/ldb-2.0.8/lib/talloc/testsuite.c b/ldb-2.0.8/lib/talloc/testsuite.c deleted file mode 100644 index a76a647..0000000 --- a/ldb-2.0.8/lib/talloc/testsuite.c +++ /dev/null @@ -1,2169 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - local testing of talloc routines. - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the talloc - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#include "system/time.h" -#include - -#ifdef HAVE_PTHREAD -#include -#endif - -#include -#include - -#ifdef NDEBUG -#undef NDEBUG -#endif - -#include - -#include "talloc_testsuite.h" - -static struct timeval private_timeval_current(void) -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return tv; -} - -static double private_timeval_elapsed(struct timeval *tv) -{ - struct timeval tv2 = private_timeval_current(); - return (tv2.tv_sec - tv->tv_sec) + - (tv2.tv_usec - tv->tv_usec)*1.0e-6; -} - -#define torture_assert(test, expr, str) if (!(expr)) { \ - printf("failure: %s [\n%s: Expression %s failed: %s\n]\n", \ - test, __location__, #expr, str); \ - return false; \ -} - -#define torture_assert_str_equal(test, arg1, arg2, desc) \ - if (arg1 == NULL && arg2 == NULL) { /* OK, both NULL == equal */ \ - } else if (arg1 == NULL || arg2 == NULL) { \ - return false; \ - } else if (strcmp(arg1, arg2)) { \ - printf("failure: %s [\n%s: Expected %s, got %s: %s\n]\n", \ - test, __location__, arg1, arg2, desc); \ - return false; \ - } - -#define CHECK_SIZE(test, ptr, tsize) do { \ - if (talloc_total_size(ptr) != (tsize)) { \ - printf("failed: %s [\n%s: wrong '%s' tree size: got %u expected %u\n]\n", \ - test, __location__, #ptr, \ - (unsigned)talloc_total_size(ptr), \ - (unsigned)tsize); \ - talloc_report_full(ptr, stdout); \ - return false; \ - } \ -} while (0) - -#define CHECK_BLOCKS(test, ptr, tblocks) do { \ - if (talloc_total_blocks(ptr) != (tblocks)) { \ - printf("failed: %s [\n%s: wrong '%s' tree blocks: got %u expected %u\n]\n", \ - test, __location__, #ptr, \ - (unsigned)talloc_total_blocks(ptr), \ - (unsigned)tblocks); \ - talloc_report_full(ptr, stdout); \ - return false; \ - } \ -} while (0) - -#define CHECK_PARENT(test, ptr, parent) do { \ - if (talloc_parent(ptr) != (parent)) { \ - printf("failed: %s [\n%s: '%s' has wrong parent: got %p expected %p\n]\n", \ - test, __location__, #ptr, \ - talloc_parent(ptr), \ - (parent)); \ - talloc_report_full(ptr, stdout); \ - talloc_report_full(parent, stdout); \ - talloc_report_full(NULL, stdout); \ - return false; \ - } \ -} while (0) - -static unsigned int test_abort_count; - -#if 0 -static void test_abort_fn(const char *reason) -{ - printf("# test_abort_fn(%s)\n", reason); - test_abort_count++; -} - -static void test_abort_start(void) -{ - test_abort_count = 0; - talloc_set_abort_fn(test_abort_fn); -} -#endif - -static void test_abort_stop(void) -{ - test_abort_count = 0; - talloc_set_abort_fn(NULL); -} - -static void test_log_stdout(const char *message) -{ - fprintf(stdout, "%s", message); -} - -/* - test references -*/ -static bool test_ref1(void) -{ - void *root, *p1, *p2, *ref, *r1; - - printf("test: ref1\n# SINGLE REFERENCE FREE\n"); - - root = talloc_named_const(NULL, 0, "root"); - p1 = talloc_named_const(root, 1, "p1"); - p2 = talloc_named_const(p1, 1, "p2"); - talloc_named_const(p1, 1, "x1"); - talloc_named_const(p1, 2, "x2"); - talloc_named_const(p1, 3, "x3"); - - r1 = talloc_named_const(root, 1, "r1"); - ref = talloc_reference(r1, p2); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref1", p1, 5); - CHECK_BLOCKS("ref1", p2, 1); - CHECK_BLOCKS("ref1", ref, 1); - CHECK_BLOCKS("ref1", r1, 2); - - fprintf(stderr, "Freeing p2\n"); - talloc_unlink(r1, p2); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref1", p1, 5); - CHECK_BLOCKS("ref1", p2, 1); - CHECK_BLOCKS("ref1", r1, 1); - - fprintf(stderr, "Freeing p1\n"); - talloc_free(p1); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref1", r1, 1); - - fprintf(stderr, "Freeing r1\n"); - talloc_free(r1); - talloc_report_full(NULL, stderr); - - fprintf(stderr, "Testing NULL\n"); - if (talloc_reference(root, NULL)) { - return false; - } - - CHECK_BLOCKS("ref1", root, 1); - - CHECK_SIZE("ref1", root, 0); - - talloc_free(root); - printf("success: ref1\n"); - return true; -} - -/* - test references -*/ -static bool test_ref2(void) -{ - void *root, *p1, *p2, *ref, *r1; - - printf("test: ref2\n# DOUBLE REFERENCE FREE\n"); - root = talloc_named_const(NULL, 0, "root"); - p1 = talloc_named_const(root, 1, "p1"); - talloc_named_const(p1, 1, "x1"); - talloc_named_const(p1, 1, "x2"); - talloc_named_const(p1, 1, "x3"); - p2 = talloc_named_const(p1, 1, "p2"); - - r1 = talloc_named_const(root, 1, "r1"); - ref = talloc_reference(r1, p2); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref2", p1, 5); - CHECK_BLOCKS("ref2", p2, 1); - CHECK_BLOCKS("ref2", r1, 2); - - fprintf(stderr, "Freeing ref\n"); - talloc_unlink(r1, ref); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref2", p1, 5); - CHECK_BLOCKS("ref2", p2, 1); - CHECK_BLOCKS("ref2", r1, 1); - - fprintf(stderr, "Freeing p2\n"); - talloc_free(p2); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref2", p1, 4); - CHECK_BLOCKS("ref2", r1, 1); - - fprintf(stderr, "Freeing p1\n"); - talloc_free(p1); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref2", r1, 1); - - fprintf(stderr, "Freeing r1\n"); - talloc_free(r1); - talloc_report_full(root, stderr); - - CHECK_SIZE("ref2", root, 0); - - talloc_free(root); - printf("success: ref2\n"); - return true; -} - -/* - test references -*/ -static bool test_ref3(void) -{ - void *root, *p1, *p2, *ref, *r1; - - printf("test: ref3\n# PARENT REFERENCE FREE\n"); - - root = talloc_named_const(NULL, 0, "root"); - p1 = talloc_named_const(root, 1, "p1"); - p2 = talloc_named_const(root, 1, "p2"); - r1 = talloc_named_const(p1, 1, "r1"); - ref = talloc_reference(p2, r1); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref3", p1, 2); - CHECK_BLOCKS("ref3", p2, 2); - CHECK_BLOCKS("ref3", r1, 1); - CHECK_BLOCKS("ref3", ref, 1); - - fprintf(stderr, "Freeing p1\n"); - talloc_free(p1); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref3", p2, 2); - CHECK_BLOCKS("ref3", r1, 1); - - fprintf(stderr, "Freeing p2\n"); - talloc_free(p2); - talloc_report_full(root, stderr); - - CHECK_SIZE("ref3", root, 0); - - talloc_free(root); - - printf("success: ref3\n"); - return true; -} - -/* - test references -*/ -static bool test_ref4(void) -{ - void *root, *p1, *p2, *ref, *r1; - - printf("test: ref4\n# REFERRER REFERENCE FREE\n"); - - root = talloc_named_const(NULL, 0, "root"); - p1 = talloc_named_const(root, 1, "p1"); - talloc_named_const(p1, 1, "x1"); - talloc_named_const(p1, 1, "x2"); - talloc_named_const(p1, 1, "x3"); - p2 = talloc_named_const(p1, 1, "p2"); - - r1 = talloc_named_const(root, 1, "r1"); - ref = talloc_reference(r1, p2); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref4", p1, 5); - CHECK_BLOCKS("ref4", p2, 1); - CHECK_BLOCKS("ref4", ref, 1); - CHECK_BLOCKS("ref4", r1, 2); - - fprintf(stderr, "Freeing r1\n"); - talloc_free(r1); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref4", p1, 5); - CHECK_BLOCKS("ref4", p2, 1); - - fprintf(stderr, "Freeing p2\n"); - talloc_free(p2); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("ref4", p1, 4); - - fprintf(stderr, "Freeing p1\n"); - talloc_free(p1); - talloc_report_full(root, stderr); - - CHECK_SIZE("ref4", root, 0); - - talloc_free(root); - - printf("success: ref4\n"); - return true; -} - - -/* - test references -*/ -static bool test_unlink1(void) -{ - void *root, *p1, *p2, *ref, *r1; - - printf("test: unlink\n# UNLINK\n"); - - root = talloc_named_const(NULL, 0, "root"); - p1 = talloc_named_const(root, 1, "p1"); - talloc_named_const(p1, 1, "x1"); - talloc_named_const(p1, 1, "x2"); - talloc_named_const(p1, 1, "x3"); - p2 = talloc_named_const(p1, 1, "p2"); - - r1 = talloc_named_const(p1, 1, "r1"); - ref = talloc_reference(r1, p2); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("unlink", p1, 7); - CHECK_BLOCKS("unlink", p2, 1); - CHECK_BLOCKS("unlink", ref, 1); - CHECK_BLOCKS("unlink", r1, 2); - - fprintf(stderr, "Unreferencing r1\n"); - talloc_unlink(r1, p2); - talloc_report_full(root, stderr); - - CHECK_BLOCKS("unlink", p1, 6); - CHECK_BLOCKS("unlink", p2, 1); - CHECK_BLOCKS("unlink", r1, 1); - - fprintf(stderr, "Freeing p1\n"); - talloc_free(p1); - talloc_report_full(root, stderr); - - CHECK_SIZE("unlink", root, 0); - - talloc_free(root); - - printf("success: unlink\n"); - return true; -} - -static int fail_destructor(void *ptr) -{ - return -1; -} - -/* - miscellaneous tests to try to get a higher test coverage percentage -*/ -static bool test_misc(void) -{ - void *root, *p1; - char *p2; - double *d; - const char *name; - - printf("test: misc\n# MISCELLANEOUS\n"); - - root = talloc_new(NULL); - - p1 = talloc_size(root, 0x7fffffff); - torture_assert("misc", !p1, "failed: large talloc allowed\n"); - - p1 = talloc_strdup(root, "foo"); - talloc_increase_ref_count(p1); - talloc_increase_ref_count(p1); - talloc_increase_ref_count(p1); - CHECK_BLOCKS("misc", p1, 1); - CHECK_BLOCKS("misc", root, 2); - talloc_unlink(NULL, p1); - CHECK_BLOCKS("misc", p1, 1); - CHECK_BLOCKS("misc", root, 2); - talloc_unlink(NULL, p1); - CHECK_BLOCKS("misc", p1, 1); - CHECK_BLOCKS("misc", root, 2); - p2 = talloc_strdup(p1, "foo"); - torture_assert("misc", talloc_unlink(root, p2) == -1, - "failed: talloc_unlink() of non-reference context should return -1\n"); - torture_assert("misc", talloc_unlink(p1, p2) == 0, - "failed: talloc_unlink() of parent should succeed\n"); - talloc_unlink(NULL, p1); - CHECK_BLOCKS("misc", p1, 1); - CHECK_BLOCKS("misc", root, 2); - - name = talloc_set_name(p1, "my name is %s", "foo"); - torture_assert_str_equal("misc", talloc_get_name(p1), "my name is foo", - "failed: wrong name after talloc_set_name(my name is foo)"); - torture_assert_str_equal("misc", talloc_get_name(p1), name, - "failed: wrong name after talloc_set_name(my name is foo)"); - CHECK_BLOCKS("misc", p1, 2); - CHECK_BLOCKS("misc", root, 3); - - talloc_set_name_const(p1, NULL); - torture_assert_str_equal ("misc", talloc_get_name(p1), "UNNAMED", - "failed: wrong name after talloc_set_name(NULL)"); - CHECK_BLOCKS("misc", p1, 2); - CHECK_BLOCKS("misc", root, 3); - - torture_assert("misc", talloc_free(NULL) == -1, - "talloc_free(NULL) should give -1\n"); - - talloc_set_destructor(p1, fail_destructor); - torture_assert("misc", talloc_free(p1) == -1, - "Failed destructor should cause talloc_free to fail\n"); - talloc_set_destructor(p1, NULL); - - talloc_report(root, stderr); - - - p2 = (char *)talloc_zero_size(p1, 20); - torture_assert("misc", p2[19] == 0, "Failed to give zero memory\n"); - talloc_free(p2); - - torture_assert("misc", talloc_strdup(root, NULL) == NULL, - "failed: strdup on NULL should give NULL\n"); - - p2 = talloc_strndup(p1, "foo", 2); - torture_assert("misc", strcmp("fo", p2) == 0, - "strndup doesn't work\n"); - p2 = talloc_asprintf_append_buffer(p2, "o%c", 'd'); - torture_assert("misc", strcmp("food", p2) == 0, - "talloc_asprintf_append_buffer doesn't work\n"); - CHECK_BLOCKS("misc", p2, 1); - CHECK_BLOCKS("misc", p1, 3); - - p2 = talloc_asprintf_append_buffer(NULL, "hello %s", "world"); - torture_assert("misc", strcmp("hello world", p2) == 0, - "talloc_asprintf_append_buffer doesn't work\n"); - CHECK_BLOCKS("misc", p2, 1); - CHECK_BLOCKS("misc", p1, 3); - talloc_free(p2); - - d = talloc_array(p1, double, 0x20000000); - torture_assert("misc", !d, "failed: integer overflow not detected\n"); - - d = talloc_realloc(p1, d, double, 0x20000000); - torture_assert("misc", !d, "failed: integer overflow not detected\n"); - - talloc_free(p1); - CHECK_BLOCKS("misc", root, 1); - - p1 = talloc_named(root, 100, "%d bytes", 100); - CHECK_BLOCKS("misc", p1, 2); - CHECK_BLOCKS("misc", root, 3); - talloc_unlink(root, p1); - - p1 = talloc_init("%d bytes", 200); - p2 = talloc_asprintf(p1, "my test '%s'", "string"); - torture_assert_str_equal("misc", p2, "my test 'string'", - "failed: talloc_asprintf(\"my test '%%s'\", \"string\") gave: \"%s\""); - CHECK_BLOCKS("misc", p1, 3); - CHECK_SIZE("misc", p2, 17); - CHECK_BLOCKS("misc", root, 1); - talloc_unlink(NULL, p1); - - p1 = talloc_named_const(root, 10, "p1"); - p2 = (char *)talloc_named_const(root, 20, "p2"); - (void)talloc_reference(p1, p2); - talloc_report_full(root, stderr); - talloc_unlink(root, p2); - talloc_report_full(root, stderr); - CHECK_BLOCKS("misc", p2, 1); - CHECK_BLOCKS("misc", p1, 2); - CHECK_BLOCKS("misc", root, 3); - talloc_unlink(p1, p2); - talloc_unlink(root, p1); - - p1 = talloc_named_const(root, 10, "p1"); - p2 = (char *)talloc_named_const(root, 20, "p2"); - (void)talloc_reference(NULL, p2); - talloc_report_full(root, stderr); - talloc_unlink(root, p2); - talloc_report_full(root, stderr); - CHECK_BLOCKS("misc", p2, 1); - CHECK_BLOCKS("misc", p1, 1); - CHECK_BLOCKS("misc", root, 2); - talloc_unlink(NULL, p2); - talloc_unlink(root, p1); - - /* Test that talloc_unlink is a no-op */ - - torture_assert("misc", talloc_unlink(root, NULL) == -1, - "failed: talloc_unlink(root, NULL) == -1\n"); - - talloc_report(root, stderr); - talloc_report(NULL, stderr); - - CHECK_SIZE("misc", root, 0); - - talloc_free(root); - - CHECK_SIZE("misc", NULL, 0); - - talloc_enable_null_tracking_no_autofree(); - talloc_enable_leak_report(); - talloc_enable_leak_report_full(); - - printf("success: misc\n"); - - return true; -} - - -/* - test realloc -*/ -static bool test_realloc(void) -{ - void *root, *p1, *p2; - - printf("test: realloc\n# REALLOC\n"); - - root = talloc_new(NULL); - - p1 = talloc_size(root, 10); - CHECK_SIZE("realloc", p1, 10); - - p1 = talloc_realloc_size(NULL, p1, 20); - CHECK_SIZE("realloc", p1, 20); - - talloc_new(p1); - - p2 = talloc_realloc_size(p1, NULL, 30); - - talloc_new(p1); - - p2 = talloc_realloc_size(p1, p2, 40); - - CHECK_SIZE("realloc", p2, 40); - CHECK_SIZE("realloc", root, 60); - CHECK_BLOCKS("realloc", p1, 4); - - p1 = talloc_realloc_size(NULL, p1, 20); - CHECK_SIZE("realloc", p1, 60); - - talloc_increase_ref_count(p2); - torture_assert("realloc", talloc_realloc_size(NULL, p2, 5) == NULL, - "failed: talloc_realloc() on a referenced pointer should fail\n"); - CHECK_BLOCKS("realloc", p1, 4); - - talloc_realloc_size(NULL, p2, 0); - talloc_realloc_size(NULL, p2, 0); - CHECK_BLOCKS("realloc", p1, 4); - talloc_realloc_size(p1, p2, 0); - CHECK_BLOCKS("realloc", p1, 3); - - torture_assert("realloc", talloc_realloc_size(NULL, p1, 0x7fffffff) == NULL, - "failed: oversize talloc should fail\n"); - - talloc_realloc_size(NULL, p1, 0); - CHECK_BLOCKS("realloc", root, 4); - talloc_realloc_size(root, p1, 0); - CHECK_BLOCKS("realloc", root, 1); - - CHECK_SIZE("realloc", root, 0); - - talloc_free(root); - - printf("success: realloc\n"); - - return true; -} - -/* - test realloc with a child -*/ -static bool test_realloc_child(void) -{ - void *root; - struct el2 { - const char *name; - } *el2, *el2_2, *el2_3, **el_list_save; - struct el1 { - int count; - struct el2 **list, **list2, **list3; - } *el1; - - printf("test: REALLOC WITH CHILD\n"); - - root = talloc_new(NULL); - - el1 = talloc(root, struct el1); - el1->list = talloc(el1, struct el2 *); - el1->list[0] = talloc(el1->list, struct el2); - el1->list[0]->name = talloc_strdup(el1->list[0], "testing"); - - el1->list2 = talloc(el1, struct el2 *); - el1->list2[0] = talloc(el1->list2, struct el2); - el1->list2[0]->name = talloc_strdup(el1->list2[0], "testing2"); - - el1->list3 = talloc(el1, struct el2 *); - el1->list3[0] = talloc(el1->list3, struct el2); - el1->list3[0]->name = talloc_strdup(el1->list3[0], "testing2"); - - el2 = talloc(el1->list, struct el2); - CHECK_PARENT("el2", el2, el1->list); - el2_2 = talloc(el1->list2, struct el2); - CHECK_PARENT("el2", el2_2, el1->list2); - el2_3 = talloc(el1->list3, struct el2); - CHECK_PARENT("el2", el2_3, el1->list3); - - el_list_save = el1->list; - el1->list = talloc_realloc(el1, el1->list, struct el2 *, 100); - if (el1->list == el_list_save) { - printf("failure: talloc_realloc didn't move pointer"); - return false; - } - - CHECK_PARENT("el1_after_realloc", el1->list, el1); - el1->list2 = talloc_realloc(el1, el1->list2, struct el2 *, 200); - CHECK_PARENT("el1_after_realloc", el1->list2, el1); - el1->list3 = talloc_realloc(el1, el1->list3, struct el2 *, 300); - CHECK_PARENT("el1_after_realloc", el1->list3, el1); - - CHECK_PARENT("el2", el2, el1->list); - CHECK_PARENT("el2", el2_2, el1->list2); - CHECK_PARENT("el2", el2_3, el1->list3); - - /* Finally check realloc with multiple children */ - el1 = talloc_realloc(root, el1, struct el1, 100); - CHECK_PARENT("el1->list", el1->list, el1); - CHECK_PARENT("el1->list2", el1->list2, el1); - CHECK_PARENT("el1->list3", el1->list3, el1); - - talloc_free(root); - - printf("success: REALLOC WITH CHILD\n"); - return true; -} - -/* - test type checking -*/ -static bool test_type(void) -{ - void *root; - struct el1 { - int count; - }; - struct el2 { - int count; - }; - struct el1 *el1; - - printf("test: type\n# talloc type checking\n"); - - root = talloc_new(NULL); - - el1 = talloc(root, struct el1); - - el1->count = 1; - - torture_assert("type", talloc_get_type(el1, struct el1) == el1, - "type check failed on el1\n"); - torture_assert("type", talloc_get_type(el1, struct el2) == NULL, - "type check failed on el1 with el2\n"); - talloc_set_type(el1, struct el2); - torture_assert("type", talloc_get_type(el1, struct el2) == (struct el2 *)el1, - "type set failed on el1 with el2\n"); - - talloc_free(root); - - printf("success: type\n"); - return true; -} - -/* - test steal -*/ -static bool test_steal(void) -{ - void *root, *p1, *p2; - - printf("test: steal\n# STEAL\n"); - - root = talloc_new(NULL); - - p1 = talloc_array(root, char, 10); - CHECK_SIZE("steal", p1, 10); - - p2 = talloc_realloc(root, NULL, char, 20); - CHECK_SIZE("steal", p1, 10); - CHECK_SIZE("steal", root, 30); - - torture_assert("steal", talloc_steal(p1, NULL) == NULL, - "failed: stealing NULL should give NULL\n"); - - torture_assert("steal", talloc_steal(p1, p1) == p1, - "failed: stealing to ourselves is a nop\n"); - CHECK_BLOCKS("steal", root, 3); - CHECK_SIZE("steal", root, 30); - - talloc_steal(NULL, p1); - talloc_steal(NULL, p2); - CHECK_BLOCKS("steal", root, 1); - CHECK_SIZE("steal", root, 0); - - talloc_free(p1); - talloc_steal(root, p2); - CHECK_BLOCKS("steal", root, 2); - CHECK_SIZE("steal", root, 20); - - talloc_free(p2); - - CHECK_BLOCKS("steal", root, 1); - CHECK_SIZE("steal", root, 0); - - talloc_free(root); - - p1 = talloc_size(NULL, 3); - talloc_report_full(NULL, stderr); - CHECK_SIZE("steal", NULL, 3); - talloc_free(p1); - - printf("success: steal\n"); - return true; -} - -/* - test move -*/ -static bool test_move(void) -{ - void *root; - struct t_move { - char *p; - int *x; - } *t1, *t2; - - printf("test: move\n# MOVE\n"); - - root = talloc_new(NULL); - - t1 = talloc(root, struct t_move); - t2 = talloc(root, struct t_move); - t1->p = talloc_strdup(t1, "foo"); - t1->x = talloc(t1, int); - *t1->x = 42; - - t2->p = talloc_move(t2, &t1->p); - t2->x = talloc_move(t2, &t1->x); - torture_assert("move", t1->p == NULL && t1->x == NULL && - strcmp(t2->p, "foo") == 0 && *t2->x == 42, - "talloc move failed"); - - talloc_free(root); - - printf("success: move\n"); - - return true; -} - -/* - test talloc_realloc_fn -*/ -static bool test_realloc_fn(void) -{ - void *root, *p1; - - printf("test: realloc_fn\n# talloc_realloc_fn\n"); - - root = talloc_new(NULL); - - p1 = talloc_realloc_fn(root, NULL, 10); - CHECK_BLOCKS("realloc_fn", root, 2); - CHECK_SIZE("realloc_fn", root, 10); - p1 = talloc_realloc_fn(root, p1, 20); - CHECK_BLOCKS("realloc_fn", root, 2); - CHECK_SIZE("realloc_fn", root, 20); - p1 = talloc_realloc_fn(root, p1, 0); - CHECK_BLOCKS("realloc_fn", root, 1); - CHECK_SIZE("realloc_fn", root, 0); - - talloc_free(root); - - printf("success: realloc_fn\n"); - return true; -} - - -static bool test_unref_reparent(void) -{ - void *root, *p1, *p2, *c1; - - printf("test: unref_reparent\n# UNREFERENCE AFTER PARENT FREED\n"); - - root = talloc_named_const(NULL, 0, "root"); - p1 = talloc_named_const(root, 1, "orig parent"); - p2 = talloc_named_const(root, 1, "parent by reference"); - - c1 = talloc_named_const(p1, 1, "child"); - talloc_reference(p2, c1); - - CHECK_PARENT("unref_reparent", c1, p1); - - talloc_free(p1); - - CHECK_PARENT("unref_reparent", c1, p2); - - talloc_unlink(p2, c1); - - CHECK_SIZE("unref_reparent", root, 1); - - talloc_free(p2); - talloc_free(root); - - printf("success: unref_reparent\n"); - return true; -} - -/* - measure the speed of talloc versus malloc -*/ -static bool test_speed(void) -{ - void *ctx = talloc_new(NULL); - unsigned count; - const int loop = 1000; - int i; - struct timeval tv; - - printf("test: speed\n# TALLOC VS MALLOC SPEED\n"); - - tv = private_timeval_current(); - count = 0; - do { - void *p1, *p2, *p3; - for (i=0;ireq2 = talloc_strdup(req1, "req2"); - talloc_set_destructor(req1->req2, test_loop_destructor); - req1->req3 = talloc_strdup(req1, "req3"); - (void)talloc_reference(req1->req3, req1); - talloc_report_full(top, stderr); - talloc_free(parent); - talloc_report_full(top, stderr); - talloc_report_full(NULL, stderr); - talloc_free(top); - - torture_assert("loop", loop_destructor_count == 1, - "FAILED TO FIRE LOOP DESTRUCTOR\n"); - loop_destructor_count = 0; - - printf("success: loop\n"); - return true; -} - -static int realloc_parent_destructor_count; - -static int test_realloc_parent_destructor(char *ptr) -{ - realloc_parent_destructor_count++; - return 0; -} - -static bool test_realloc_on_destructor_parent(void) -{ - void *top = talloc_new(NULL); - char *parent; - char *a, *b, *C, *D; - realloc_parent_destructor_count = 0; - - printf("test: free_for_exit\n# TALLOC FREE FOR EXIT\n"); - - parent = talloc_strdup(top, "parent"); - a = talloc_strdup(parent, "a"); - b = talloc_strdup(a, "b"); - C = talloc_strdup(a, "C"); - D = talloc_strdup(b, "D"); - talloc_set_destructor(D, test_realloc_parent_destructor); - /* Capitalised ones have destructors. - * - * parent --> a -> b -> D - * -> c - */ - - a = talloc_realloc(parent, a, char, 2048); - - torture_assert("check talloc_realloc", a != NULL, "talloc_realloc failed"); - - talloc_set_destructor(C, test_realloc_parent_destructor); - /* - * parent --> a[2048] -> b -> D - * -> C - * - */ - - talloc_free(parent); - - torture_assert("check destructor realloc_parent_destructor", - realloc_parent_destructor_count == 2, - "FAILED TO FIRE free_for_exit_destructor\n"); - - - printf("success: free_for_exit\n"); - return true; -} - -static int fail_destructor_str(char *ptr) -{ - return -1; -} - -static bool test_free_parent_deny_child(void) -{ - void *top = talloc_new(NULL); - char *level1; - char *level2; - char *level3; - - printf("test: free_parent_deny_child\n# TALLOC FREE PARENT DENY CHILD\n"); - - level1 = talloc_strdup(top, "level1"); - level2 = talloc_strdup(level1, "level2"); - level3 = talloc_strdup(level2, "level3"); - - talloc_set_destructor(level3, fail_destructor_str); - talloc_free(level1); - talloc_set_destructor(level3, NULL); - - CHECK_PARENT("free_parent_deny_child", level3, top); - - talloc_free(top); - - printf("success: free_parent_deny_child\n"); - return true; -} - -struct new_parent { - void *new_parent; - char val[20]; -}; - -static int reparenting_destructor(struct new_parent *np) -{ - talloc_set_destructor(np, NULL); - (void)talloc_move(np->new_parent, &np); - return -1; -} - -static bool test_free_parent_reparent_child(void) -{ - void *top = talloc_new(NULL); - char *level1; - char *alternate_level1; - char *level2; - struct new_parent *level3; - - printf("test: free_parent_reparent_child\n# " - "TALLOC FREE PARENT REPARENT CHILD\n"); - - level1 = talloc_strdup(top, "level1"); - alternate_level1 = talloc_strdup(top, "alternate_level1"); - level2 = talloc_strdup(level1, "level2"); - level3 = talloc(level2, struct new_parent); - level3->new_parent = alternate_level1; - memset(level3->val, 'x', sizeof(level3->val)); - - talloc_set_destructor(level3, reparenting_destructor); - talloc_free(level1); - - CHECK_PARENT("free_parent_reparent_child", - level3, alternate_level1); - - talloc_free(top); - - printf("success: free_parent_reparent_child\n"); - return true; -} - -static bool test_free_parent_reparent_child_in_pool(void) -{ - void *top = talloc_new(NULL); - char *level1; - char *alternate_level1; - char *level2; - void *pool; - struct new_parent *level3; - - printf("test: free_parent_reparent_child_in_pool\n# " - "TALLOC FREE PARENT REPARENT CHILD IN POOL\n"); - - pool = talloc_pool(top, 1024); - level1 = talloc_strdup(pool, "level1"); - alternate_level1 = talloc_strdup(top, "alternate_level1"); - level2 = talloc_strdup(level1, "level2"); - level3 = talloc(level2, struct new_parent); - level3->new_parent = alternate_level1; - memset(level3->val, 'x', sizeof(level3->val)); - - talloc_set_destructor(level3, reparenting_destructor); - talloc_free(level1); - talloc_set_destructor(level3, NULL); - - CHECK_PARENT("free_parent_reparent_child_in_pool", - level3, alternate_level1); - - /* Even freeing alternate_level1 should leave pool alone. */ - talloc_free(alternate_level1); - talloc_free(top); - - printf("success: free_parent_reparent_child_in_pool\n"); - return true; -} - - -static bool test_talloc_ptrtype(void) -{ - void *top = talloc_new(NULL); - struct struct1 { - int foo; - int bar; - } *s1, *s2, **s3, ***s4; - const char *location1; - const char *location2; - const char *location3; - const char *location4; - - printf("test: ptrtype\n# TALLOC PTRTYPE\n"); - - s1 = talloc_ptrtype(top, s1);location1 = __location__; - - if (talloc_get_size(s1) != sizeof(struct struct1)) { - printf("failure: ptrtype [\n" - "talloc_ptrtype() allocated the wrong size %lu (should be %lu)\n" - "]\n", (unsigned long)talloc_get_size(s1), - (unsigned long)sizeof(struct struct1)); - return false; - } - - if (strcmp(location1, talloc_get_name(s1)) != 0) { - printf("failure: ptrtype [\n" - "talloc_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n", - talloc_get_name(s1), location1); - return false; - } - - s2 = talloc_array_ptrtype(top, s2, 10);location2 = __location__; - - if (talloc_get_size(s2) != (sizeof(struct struct1) * 10)) { - printf("failure: ptrtype [\n" - "talloc_array_ptrtype() allocated the wrong size " - "%lu (should be %lu)\n]\n", - (unsigned long)talloc_get_size(s2), - (unsigned long)(sizeof(struct struct1)*10)); - return false; - } - - if (strcmp(location2, talloc_get_name(s2)) != 0) { - printf("failure: ptrtype [\n" - "talloc_array_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n", - talloc_get_name(s2), location2); - return false; - } - - s3 = talloc_array_ptrtype(top, s3, 10);location3 = __location__; - - if (talloc_get_size(s3) != (sizeof(struct struct1 *) * 10)) { - printf("failure: ptrtype [\n" - "talloc_array_ptrtype() allocated the wrong size " - "%lu (should be %lu)\n]\n", - (unsigned long)talloc_get_size(s3), - (unsigned long)(sizeof(struct struct1 *)*10)); - return false; - } - - torture_assert_str_equal("ptrtype", location3, talloc_get_name(s3), - "talloc_array_ptrtype() sets the wrong name"); - - s4 = talloc_array_ptrtype(top, s4, 10);location4 = __location__; - - if (talloc_get_size(s4) != (sizeof(struct struct1 **) * 10)) { - printf("failure: ptrtype [\n" - "talloc_array_ptrtype() allocated the wrong size " - "%lu (should be %lu)\n]\n", - (unsigned long)talloc_get_size(s4), - (unsigned long)(sizeof(struct struct1 **)*10)); - return false; - } - - torture_assert_str_equal("ptrtype", location4, talloc_get_name(s4), - "talloc_array_ptrtype() sets the wrong name"); - - talloc_free(top); - - printf("success: ptrtype\n"); - return true; -} - -static int _test_talloc_free_in_destructor(void **ptr) -{ - talloc_free(*ptr); - return 0; -} - -static bool test_talloc_free_in_destructor(void) -{ - void *level0; - void *level1; - void *level2; - void *level3; - void *level4; - void **level5; - - printf("test: free_in_destructor\n# TALLOC FREE IN DESTRUCTOR\n"); - - level0 = talloc_new(NULL); - level1 = talloc_new(level0); - level2 = talloc_new(level1); - level3 = talloc_new(level2); - level4 = talloc_new(level3); - level5 = talloc(level4, void *); - - *level5 = level3; - (void)talloc_reference(level0, level3); - (void)talloc_reference(level3, level3); - (void)talloc_reference(level5, level3); - - talloc_set_destructor(level5, _test_talloc_free_in_destructor); - - talloc_free(level1); - - talloc_free(level0); - - printf("success: free_in_destructor\n"); - return true; -} - -static bool test_autofree(void) -{ -#if _SAMBA_BUILD_ < 4 - /* autofree test would kill smbtorture */ - void *p; - printf("test: autofree\n# TALLOC AUTOFREE CONTEXT\n"); - - p = talloc_autofree_context(); - talloc_free(p); - - p = talloc_autofree_context(); - talloc_free(p); - - printf("success: autofree\n"); -#endif - return true; -} - -static bool test_pool(void) -{ - void *pool; - void *p1, *p2, *p3, *p4; - void *p2_2; - - pool = talloc_pool(NULL, 1024); - - p1 = talloc_size(pool, 80); - memset(p1, 0x11, talloc_get_size(p1)); - p2 = talloc_size(pool, 20); - memset(p2, 0x11, talloc_get_size(p2)); - p3 = talloc_size(p1, 50); - memset(p3, 0x11, talloc_get_size(p3)); - p4 = talloc_size(p3, 1000); - memset(p4, 0x11, talloc_get_size(p4)); - -#if 1 /* this relies on ALWAYS_REALLOC == 0 in talloc.c */ - p2_2 = talloc_realloc_size(pool, p2, 20+1); - torture_assert("pool realloc 20+1", p2_2 == p2, "failed: pointer changed"); - memset(p2, 0x11, talloc_get_size(p2)); - p2_2 = talloc_realloc_size(pool, p2, 20-1); - torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed"); - memset(p2, 0x11, talloc_get_size(p2)); - p2_2 = talloc_realloc_size(pool, p2, 20-1); - torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed"); - memset(p2, 0x11, talloc_get_size(p2)); - - talloc_free(p3); - - /* this should reclaim the memory of p4 and p3 */ - p2_2 = talloc_realloc_size(pool, p2, 400); - torture_assert("pool realloc 400", p2_2 == p2, "failed: pointer changed"); - memset(p2, 0x11, talloc_get_size(p2)); - - talloc_free(p1); - - /* this should reclaim the memory of p1 */ - p2_2 = talloc_realloc_size(pool, p2, 800); - torture_assert("pool realloc 800", p2_2 == p1, "failed: pointer not changed"); - p2 = p2_2; - memset(p2, 0x11, talloc_get_size(p2)); - - /* this should do a malloc */ - p2_2 = talloc_realloc_size(pool, p2, 1800); - torture_assert("pool realloc 1800", p2_2 != p2, "failed: pointer not changed"); - p2 = p2_2; - memset(p2, 0x11, talloc_get_size(p2)); - - /* this should reclaim the memory from the pool */ - p3 = talloc_size(pool, 80); - torture_assert("pool alloc 80", p3 == p1, "failed: pointer changed"); - memset(p3, 0x11, talloc_get_size(p3)); - - talloc_free(p2); - talloc_free(p3); - - p1 = talloc_size(pool, 80); - memset(p1, 0x11, talloc_get_size(p1)); - p2 = talloc_size(pool, 20); - memset(p2, 0x11, talloc_get_size(p2)); - - talloc_free(p1); - - p2_2 = talloc_realloc_size(pool, p2, 20-1); - torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed"); - memset(p2, 0x11, talloc_get_size(p2)); - p2_2 = talloc_realloc_size(pool, p2, 20-1); - torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed"); - memset(p2, 0x11, talloc_get_size(p2)); - - /* this should do a malloc */ - p2_2 = talloc_realloc_size(pool, p2, 1800); - torture_assert("pool realloc 1800", p2_2 != p2, "failed: pointer not changed"); - p2 = p2_2; - memset(p2, 0x11, talloc_get_size(p2)); - - /* this should reclaim the memory from the pool */ - p3 = talloc_size(pool, 800); - torture_assert("pool alloc 800", p3 == p1, "failed: pointer changed"); - memset(p3, 0x11, talloc_get_size(p3)); - -#endif /* this relies on ALWAYS_REALLOC == 0 in talloc.c */ - - talloc_free(pool); - - return true; -} - -static bool test_pool_steal(void) -{ - void *root; - void *pool; - void *p1, *p2; - void *p1_2, *p2_2; - size_t hdr; - size_t ofs1, ofs2; - - root = talloc_new(NULL); - pool = talloc_pool(root, 1024); - - p1 = talloc_size(pool, 4 * 16); - torture_assert("pool allocate 4 * 16", p1 != NULL, "failed "); - memset(p1, 0x11, talloc_get_size(p1)); - p2 = talloc_size(pool, 4 * 16); - torture_assert("pool allocate 4 * 16", p2 > p1, "failed: !(p2 > p1) "); - memset(p2, 0x11, talloc_get_size(p2)); - - ofs1 = PTR_DIFF(p2, p1); - hdr = ofs1 - talloc_get_size(p1); - - talloc_steal(root, p1); - talloc_steal(root, p2); - - talloc_free(pool); - - p1_2 = p1; - -#if 1 /* this relies on ALWAYS_REALLOC == 0 in talloc.c */ - p1_2 = talloc_realloc_size(root, p1, 5 * 16); - torture_assert("pool realloc 5 * 16", p1_2 > p2, "failed: pointer not changed"); - memset(p1_2, 0x11, talloc_get_size(p1_2)); - ofs1 = PTR_DIFF(p1_2, p2); - ofs2 = talloc_get_size(p2) + hdr; - - torture_assert("pool realloc ", ofs1 == ofs2, "failed: pointer offset unexpected"); - - p2_2 = talloc_realloc_size(root, p2, 3 * 16); - torture_assert("pool realloc 5 * 16", p2_2 == p2, "failed: pointer changed"); - memset(p2_2, 0x11, talloc_get_size(p2_2)); -#endif /* this relies on ALWAYS_REALLOC == 0 in talloc.c */ - - talloc_free(p1_2); - - p2_2 = p2; - -#if 1 /* this relies on ALWAYS_REALLOC == 0 in talloc.c */ - /* now we should reclaim the full pool */ - p2_2 = talloc_realloc_size(root, p2, 8 * 16); - torture_assert("pool realloc 8 * 16", p2_2 == p1, "failed: pointer not expected"); - p2 = p2_2; - memset(p2_2, 0x11, talloc_get_size(p2_2)); - - /* now we malloc and free the full pool space */ - p2_2 = talloc_realloc_size(root, p2, 2 * 1024); - torture_assert("pool realloc 2 * 1024", p2_2 != p1, "failed: pointer not expected"); - memset(p2_2, 0x11, talloc_get_size(p2_2)); - -#endif /* this relies on ALWAYS_REALLOC == 0 in talloc.c */ - - talloc_free(p2_2); - - talloc_free(root); - - return true; -} - -static bool test_pool_nest(void) -{ - void *p1, *p2, *p3; - void *e = talloc_new(NULL); - - p1 = talloc_pool(NULL, 1024); - torture_assert("talloc_pool", p1 != NULL, "failed"); - - p2 = talloc_pool(p1, 500); - torture_assert("talloc_pool", p2 != NULL, "failed"); - - p3 = talloc_size(p2, 10); - - talloc_steal(e, p3); - - talloc_free(p2); - - talloc_free(p3); - - talloc_free(p1); - - return true; -} - -struct pooled { - char *s1; - char *s2; - char *s3; -}; - -static bool test_pooled_object(void) -{ - struct pooled *p; - const char *s1 = "hello"; - const char *s2 = "world"; - const char *s3 = ""; - - p = talloc_pooled_object(NULL, struct pooled, 3, - strlen(s1)+strlen(s2)+strlen(s3)+3); - - if (talloc_get_size(p) != sizeof(struct pooled)) { - return false; - } - - p->s1 = talloc_strdup(p, s1); - - TALLOC_FREE(p->s1); - p->s1 = talloc_strdup(p, s2); - TALLOC_FREE(p->s1); - - p->s1 = talloc_strdup(p, s1); - p->s2 = talloc_strdup(p, s2); - p->s3 = talloc_strdup(p, s3); - - TALLOC_FREE(p); - return true; -} - -static bool test_free_ref_null_context(void) -{ - void *p1, *p2, *p3; - int ret; - - talloc_disable_null_tracking(); - p1 = talloc_new(NULL); - p2 = talloc_new(NULL); - - p3 = talloc_reference(p2, p1); - torture_assert("reference", p3 == p1, "failed: reference on null"); - - ret = talloc_free(p1); - torture_assert("ref free with null parent", ret == 0, "failed: free with null parent"); - talloc_free(p2); - - talloc_enable_null_tracking_no_autofree(); - p1 = talloc_new(NULL); - p2 = talloc_new(NULL); - - p3 = talloc_reference(p2, p1); - torture_assert("reference", p3 == p1, "failed: reference on null"); - - ret = talloc_free(p1); - torture_assert("ref free with null tracked parent", ret == 0, "failed: free with null parent"); - talloc_free(p2); - - return true; -} - -static bool test_rusty(void) -{ - void *root; - const char *p1; - - talloc_enable_null_tracking(); - root = talloc_new(NULL); - p1 = talloc_strdup(root, "foo"); - talloc_increase_ref_count(p1); - talloc_report_full(root, stdout); - talloc_free(root); - CHECK_BLOCKS("null_context", NULL, 2); - return true; -} - -static bool test_free_children(void) -{ - void *root; - char *p1, *p2; - const char *name, *name2; - - talloc_enable_null_tracking(); - root = talloc_new(NULL); - p1 = talloc_strdup(root, "foo1"); - p2 = talloc_strdup(p1, "foo2"); - (void)p2; - - talloc_set_name(p1, "%s", "testname"); - talloc_free_children(p1); - /* check its still a valid talloc ptr */ - talloc_get_size(talloc_get_name(p1)); - if (strcmp(talloc_get_name(p1), "testname") != 0) { - return false; - } - - talloc_set_name(p1, "%s", "testname"); - name = talloc_get_name(p1); - talloc_free_children(p1); - /* check its still a valid talloc ptr */ - talloc_get_size(talloc_get_name(p1)); - torture_assert("name", name == talloc_get_name(p1), "name ptr changed"); - torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname") == 0, - "wrong name"); - CHECK_BLOCKS("name1", p1, 2); - - /* note that this does not free the old child name */ - talloc_set_name_const(p1, "testname2"); - name2 = talloc_get_name(p1); - /* but this does */ - talloc_free_children(p1); - (void)name2; - torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname2") == 0, - "wrong name"); - CHECK_BLOCKS("name1", p1, 1); - - talloc_report_full(root, stdout); - talloc_free(root); - return true; -} - -static bool test_memlimit(void) -{ - void *root; - char *l1, *l2, *l3, *l4, *l5, *t; - char *pool; - int i; - - printf("test: memlimit\n# MEMORY LIMITS\n"); - - printf("==== talloc_new(NULL)\n"); - root = talloc_new(NULL); - - talloc_report_full(root, stdout); - - printf("==== talloc_size(root, 2048)\n"); - l1 = talloc_size(root, 2048); - torture_assert("memlimit", l1 != NULL, - "failed: alloc should not fail due to memory limit\n"); - - talloc_report_full(root, stdout); - - printf("==== talloc_free(l1)\n"); - talloc_free(l1); - - talloc_report_full(root, stdout); - - printf("==== talloc_strdup(root, level 1)\n"); - l1 = talloc_strdup(root, "level 1"); - torture_assert("memlimit", l1 != NULL, - "failed: alloc should not fail due to memory limit\n"); - - talloc_report_full(root, stdout); - - printf("==== talloc_set_memlimit(l1, 2048)\n"); - torture_assert("memlimit", talloc_set_memlimit(l1, 2048) == 0, - "failed: setting memlimit should never fail\n"); - - talloc_report_full(root, stdout); - - printf("==== talloc_size(root, 2048)\n"); - l2 = talloc_size(l1, 2048); - torture_assert("memlimit", l2 == NULL, - "failed: alloc should fail due to memory limit\n"); - - talloc_report_full(root, stdout); - - printf("==== talloc_strdup(l1, level 2)\n"); - l2 = talloc_strdup(l1, "level 2"); - torture_assert("memlimit", l2 != NULL, - "failed: alloc should not fail due to memory limit\n"); - - talloc_report_full(root, stdout); - - printf("==== talloc_free(l2)\n"); - talloc_free(l2); - - talloc_report_full(root, stdout); - - printf("==== talloc_size(NULL, 2048)\n"); - l2 = talloc_size(NULL, 2048); - - talloc_report_full(root, stdout); - - printf("==== talloc_steal(l1, l2)\n"); - talloc_steal(l1, l2); - - talloc_report_full(root, stdout); - - printf("==== talloc_strdup(l2, level 3)\n"); - l3 = talloc_strdup(l2, "level 3"); - torture_assert("memlimit", l3 == NULL, - "failed: alloc should fail due to memory limit\n"); - - talloc_report_full(root, stdout); - - printf("==== talloc_free(l2)\n"); - talloc_free(l2); - - talloc_report_full(root, stdout); - - printf("==== talloc_strdup(NULL, level 2)\n"); - l2 = talloc_strdup(NULL, "level 2"); - talloc_steal(l1, l2); - - talloc_report_full(root, stdout); - - printf("==== talloc_strdup(l2, level 3)\n"); - l3 = talloc_strdup(l2, "level 3"); - torture_assert("memlimit", l3 != NULL, - "failed: alloc should not fail due to memory limit\n"); - - talloc_report_full(root, stdout); - - printf("==== talloc_set_memlimit(l3, 1024)\n"); - torture_assert("memlimit", talloc_set_memlimit(l3, 1024) == 0, - "failed: setting memlimit should never fail\n"); - - talloc_report_full(root, stdout); - - printf("==== talloc_strdup(l3, level 4)\n"); - l4 = talloc_strdup(l3, "level 4"); - torture_assert("memlimit", l4 != NULL, - "failed: alloc should not fail due to memory limit\n"); - - talloc_report_full(root, stdout); - - printf("==== talloc_set_memlimit(l4, 512)\n"); - torture_assert("memlimit", talloc_set_memlimit(l4, 512) == 0, - "failed: setting memlimit should never fail\n"); - - talloc_report_full(root, stdout); - - printf("==== talloc_strdup(l4, level 5)\n"); - l5 = talloc_strdup(l4, "level 5"); - torture_assert("memlimit", l5 != NULL, - "failed: alloc should not fail due to memory limit\n"); - - talloc_report_full(root, stdout); - - printf("==== talloc_realloc(NULL, l5, char, 600)\n"); - t = talloc_realloc(NULL, l5, char, 600); - torture_assert("memlimit", t == NULL, - "failed: alloc should fail due to memory limit\n"); - - talloc_report_full(root, stdout); - - printf("==== talloc_realloc(NULL, l5, char, 5)\n"); - l5 = talloc_realloc(NULL, l5, char, 5); - torture_assert("memlimit", l5 != NULL, - "failed: alloc should not fail due to memory limit\n"); - - talloc_report_full(root, stdout); - - printf("==== talloc_strdup(l3, level 4)\n"); - l4 = talloc_strdup(l3, "level 4"); - torture_assert("memlimit", l4 != NULL, - "failed: alloc should not fail due to memory limit\n"); - - talloc_report_full(root, stdout); - - printf("==== talloc_set_memlimit(l4, 512)\n"); - torture_assert("memlimit", talloc_set_memlimit(l4, 512) == 0, - "failed: setting memlimit should never fail\n"); - - talloc_report_full(root, stdout); - - printf("==== talloc_strdup(l4, level 5)\n"); - l5 = talloc_strdup(l4, "level 5"); - torture_assert("memlimit", l5 != NULL, - "failed: alloc should not fail due to memory limit\n"); - - talloc_report_full(root, stdout); - - printf("==== Make new temp context and steal l5\n"); - t = talloc_new(root); - talloc_steal(t, l5); - - talloc_report_full(root, stdout); - - printf("==== talloc_size(t, 2048)\n"); - l1 = talloc_size(t, 2048); - torture_assert("memlimit", l1 != NULL, - "failed: alloc should not fail due to memory limit\n"); - - talloc_report_full(root, stdout); - talloc_free(root); - - /* Test memlimits with pools. */ - pool = talloc_pool(NULL, 10*1024); - torture_assert("memlimit", pool != NULL, - "failed: alloc should not fail due to memory limit\n"); - talloc_set_memlimit(pool, 10*1024); - for (i = 0; i < 9; i++) { - l1 = talloc_size(pool, 1024); - torture_assert("memlimit", l1 != NULL, - "failed: alloc should not fail due to memory limit\n"); - } - /* The next alloc should fail. */ - l2 = talloc_size(pool, 1024); - torture_assert("memlimit", l2 == NULL, - "failed: alloc should fail due to memory limit\n"); - - /* Moving one of the children shouldn't change the limit, - as it's still inside the pool. */ - root = talloc_new(NULL); - talloc_steal(root, l1); - l2 = talloc_size(pool, 1024); - torture_assert("memlimit", l2 == NULL, - "failed: alloc should fail due to memory limit\n"); - - talloc_free(pool); - talloc_free(root); - printf("success: memlimit\n"); - - return true; -} - -#ifdef HAVE_PTHREAD - -#define NUM_THREADS 100 - -/* Sync variables. */ -static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t condvar = PTHREAD_COND_INITIALIZER; -static void *intermediate_ptr; - -/* Subthread. */ -static void *thread_fn(void *arg) -{ - int ret; - const char *ctx_name = (const char *)arg; - void *sub_ctx = NULL; - /* - * Do stuff that creates a new talloc hierarchy in - * this thread. - */ - void *top_ctx = talloc_named_const(NULL, 0, "top"); - if (top_ctx == NULL) { - return NULL; - } - sub_ctx = talloc_named_const(top_ctx, 100, ctx_name); - if (sub_ctx == NULL) { - return NULL; - } - - /* - * Now transfer a pointer from our hierarchy - * onto the intermediate ptr. - */ - ret = pthread_mutex_lock(&mtx); - if (ret != 0) { - talloc_free(top_ctx); - return NULL; - } - /* Wait for intermediate_ptr to be free. */ - while (intermediate_ptr != NULL) { - ret = pthread_cond_wait(&condvar, &mtx); - if (ret != 0) { - talloc_free(top_ctx); - ret = pthread_mutex_unlock(&mtx); - assert(ret == 0); - return NULL; - } - } - - /* and move our memory onto it from our toplevel hierarchy. */ - intermediate_ptr = talloc_move(NULL, &sub_ctx); - - /* Tell the main thread it's ready for pickup. */ - pthread_cond_broadcast(&condvar); - ret = pthread_mutex_unlock(&mtx); - assert(ret == 0); - - talloc_free(top_ctx); - return NULL; -} - -/* Main thread. */ -static bool test_pthread_talloc_passing(void) -{ - int i; - int ret; - char str_array[NUM_THREADS][20]; - pthread_t thread_id; - void *mem_ctx; - - /* - * Important ! Null tracking breaks threaded talloc. - * It *must* be turned off. - */ - talloc_disable_null_tracking(); - - printf("test: pthread_talloc_passing\n# PTHREAD TALLOC PASSING\n"); - - /* Main thread toplevel context. */ - mem_ctx = talloc_named_const(NULL, 0, "toplevel"); - if (mem_ctx == NULL) { - printf("failed to create toplevel context\n"); - return false; - } - - /* - * Spin off NUM_THREADS threads. - * They will use their own toplevel contexts. - */ - for (i = 0; i < NUM_THREADS; i++) { - ret = snprintf(str_array[i], - 20, - "thread:%d", - i); - if (ret < 0) { - printf("snprintf %d failed\n", i); - return false; - } - ret = pthread_create(&thread_id, - NULL, - thread_fn, - str_array[i]); - if (ret != 0) { - printf("failed to create thread %d (%d)\n", i, ret); - return false; - } - } - - printf("Created %d threads\n", NUM_THREADS); - - /* Now wait for NUM_THREADS transfers of the talloc'ed memory. */ - for (i = 0; i < NUM_THREADS; i++) { - ret = pthread_mutex_lock(&mtx); - if (ret != 0) { - printf("pthread_mutex_lock %d failed (%d)\n", i, ret); - talloc_free(mem_ctx); - return false; - } - - /* Wait for intermediate_ptr to have our data. */ - while (intermediate_ptr == NULL) { - ret = pthread_cond_wait(&condvar, &mtx); - if (ret != 0) { - printf("pthread_cond_wait %d failed (%d)\n", i, - ret); - talloc_free(mem_ctx); - ret = pthread_mutex_unlock(&mtx); - assert(ret == 0); - } - } - - /* and move it onto our toplevel hierarchy. */ - (void)talloc_move(mem_ctx, &intermediate_ptr); - - /* Tell the sub-threads we're ready for another. */ - pthread_cond_broadcast(&condvar); - ret = pthread_mutex_unlock(&mtx); - assert(ret == 0); - } - - CHECK_SIZE("pthread_talloc_passing", mem_ctx, NUM_THREADS * 100); -#if 1 - /* Dump the hierarchy. */ - talloc_report(mem_ctx, stdout); -#endif - talloc_free(mem_ctx); - printf("success: pthread_talloc_passing\n"); - return true; -} -#endif - -static void test_magic_protection_abort(const char *reason) -{ - /* exit with errcode 42 to communicate successful test to the parent process */ - if (strcmp(reason, "Bad talloc magic value - unknown value") == 0) { - _exit(42); - } else { - printf("talloc aborted for an unexpected reason\n"); - } -} - -static int test_magic_protection_destructor(int *ptr) -{ - _exit(404); /* Not 42 */ -} - -static bool test_magic_protection(void) -{ - void *pool = talloc_pool(NULL, 1024); - int *p1, *p2; - pid_t pid; - int exit_status; - - printf("test: magic_protection\n"); - p1 = talloc(pool, int); - p2 = talloc(pool, int); - - /* To avoid complaints from the compiler assign values to the p1 & p2. */ - *p1 = 6; - *p2 = 9; - - pid = fork(); - if (pid == 0) { - talloc_set_abort_fn(test_magic_protection_abort); - talloc_set_destructor(p2, test_magic_protection_destructor); - - /* - * Simulate a security attack - * by triggering a buffer overflow in memset to overwrite the - * constructor in the next pool chunk. - * - * Real attacks would attempt to set a real destructor. - */ - memset(p1, '\0', 32); - - /* Then the attack takes effect when the memory's freed. */ - talloc_free(pool); - - /* Never reached. Make compilers happy */ - return true; - } - - while (wait(&exit_status) != pid); - - if (!WIFEXITED(exit_status)) { - printf("Child exited through unexpected abnormal means\n"); - return false; - } - if (WEXITSTATUS(exit_status) != 42) { - printf("Child exited with wrong exit status\n"); - return false; - } - if (WIFSIGNALED(exit_status)) { - printf("Child recieved unexpected signal\n"); - return false; - } - - printf("success: magic_protection\n"); - return true; -} - -static void test_magic_free_protection_abort(const char *reason) -{ - /* exit with errcode 42 to communicate successful test to the parent process */ - if (strcmp(reason, "Bad talloc magic value - access after free") == 0) { - _exit(42); - } - /* not 42 */ - _exit(404); -} - -static bool test_magic_free_protection(void) -{ - void *pool = talloc_pool(NULL, 1024); - int *p1, *p2, *p3; - pid_t pid; - int exit_status; - - printf("test: magic_free_protection\n"); - p1 = talloc(pool, int); - p2 = talloc(pool, int); - - /* To avoid complaints from the compiler assign values to the p1 & p2. */ - *p1 = 6; - *p2 = 9; - - p3 = talloc_realloc(pool, p2, int, 2048); - torture_assert("pool realloc 2048", - p3 != p2, - "failed: pointer not changed"); - - /* - * Now access the memory in the pool after the realloc(). It - * should be marked as free, so use of the old pointer should - * trigger the abort function - */ - pid = fork(); - if (pid == 0) { - talloc_set_abort_fn(test_magic_free_protection_abort); - - talloc_get_name(p2); - - /* Never reached. Make compilers happy */ - return true; - } - - while (wait(&exit_status) != pid); - - if (!WIFEXITED(exit_status)) { - printf("Child exited through unexpected abnormal means\n"); - return false; - } - if (WEXITSTATUS(exit_status) != 42) { - printf("Child exited with wrong exit status\n"); - return false; - } - if (WIFSIGNALED(exit_status)) { - printf("Child recieved unexpected signal\n"); - return false; - } - - talloc_free(pool); - - printf("success: magic_free_protection\n"); - return true; -} - -static void test_reset(void) -{ - talloc_set_log_fn(test_log_stdout); - test_abort_stop(); - talloc_disable_null_tracking(); - talloc_enable_null_tracking_no_autofree(); -} - -bool torture_local_talloc(struct torture_context *tctx) -{ - bool ret = true; - - setlinebuf(stdout); - - test_reset(); - ret &= test_pooled_object(); - test_reset(); - ret &= test_pool_nest(); - test_reset(); - ret &= test_ref1(); - test_reset(); - ret &= test_ref2(); - test_reset(); - ret &= test_ref3(); - test_reset(); - ret &= test_ref4(); - test_reset(); - ret &= test_unlink1(); - test_reset(); - ret &= test_misc(); - test_reset(); - ret &= test_realloc(); - test_reset(); - ret &= test_realloc_child(); - test_reset(); - ret &= test_steal(); - test_reset(); - ret &= test_move(); - test_reset(); - ret &= test_unref_reparent(); - test_reset(); - ret &= test_realloc_fn(); - test_reset(); - ret &= test_type(); - test_reset(); - ret &= test_lifeless(); - test_reset(); - ret &= test_loop(); - test_reset(); - ret &= test_free_parent_deny_child(); - test_reset(); - ret &= test_realloc_on_destructor_parent(); - test_reset(); - ret &= test_free_parent_reparent_child(); - test_reset(); - ret &= test_free_parent_reparent_child_in_pool(); - test_reset(); - ret &= test_talloc_ptrtype(); - test_reset(); - ret &= test_talloc_free_in_destructor(); - test_reset(); - ret &= test_pool(); - test_reset(); - ret &= test_pool_steal(); - test_reset(); - ret &= test_free_ref_null_context(); - test_reset(); - ret &= test_rusty(); - test_reset(); - ret &= test_free_children(); - test_reset(); - ret &= test_memlimit(); -#ifdef HAVE_PTHREAD - test_reset(); - ret &= test_pthread_talloc_passing(); -#endif - - - if (ret) { - test_reset(); - ret &= test_speed(); - } - test_reset(); - ret &= test_autofree(); - test_reset(); - ret &= test_magic_protection(); - test_reset(); - ret &= test_magic_free_protection(); - - test_reset(); - talloc_disable_null_tracking(); - return ret; -} diff --git a/ldb-2.0.8/lib/talloc/testsuite_main.c b/ldb-2.0.8/lib/talloc/testsuite_main.c deleted file mode 100644 index 50ce0f8..0000000 --- a/ldb-2.0.8/lib/talloc/testsuite_main.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - local testing of talloc routines. - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the talloc - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" - -#include "talloc_testsuite.h" - -int main(void) -{ - bool ret = torture_local_talloc(NULL); - if (!ret) - return -1; - return 0; -} diff --git a/ldb-2.0.8/lib/talloc/web/index.html b/ldb-2.0.8/lib/talloc/web/index.html deleted file mode 100644 index 388ec2c..0000000 --- a/ldb-2.0.8/lib/talloc/web/index.html +++ /dev/null @@ -1,51 +0,0 @@ - - - -talloc - - - -

      talloc

      - -talloc is a hierarchical pool based memory allocator with -destructors. It is the core memory allocator used in Samba, and has -made a huge difference in many aspects of Samba4 development.

      - -To get started with talloc, I would recommend you read the talloc guide. - -

      Download

      -You can download the latest releases of talloc from the talloc directory on the samba public -source archive. - -

      Discussion and bug reports

      - -talloc does not currently have its own mailing list or bug tracking -system. For now, please use the samba-technical -mailing list, and the Samba -bugzilla bug tracking system. - -

      Development

      - -You can download the latest code either via git or rsync.
      -
      -To fetch via git see the following guide:
      -Using Git for Samba Development
      -Once you have cloned the tree switch to the master branch and cd into the lib/talloc directory.
      -
      -To fetch via rsync use this command: - -
      -  rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/talloc .
      -
      - -
      - -Andrew Tridgell
      -talloc AT tridgell.net -
      - - - diff --git a/ldb-2.0.8/lib/talloc/wscript b/ldb-2.0.8/lib/talloc/wscript deleted file mode 100644 index eda62d1..0000000 --- a/ldb-2.0.8/lib/talloc/wscript +++ /dev/null @@ -1,198 +0,0 @@ -#!/usr/bin/env python - -APPNAME = 'talloc' -VERSION = '2.2.0' - -import os -import sys - -# find the buildtools directory -top = '.' -while not os.path.exists(top+'/buildtools') and len(top.split('/')) < 5: - top = top + '/..' -sys.path.insert(0, top + '/buildtools/wafsamba') - -out = 'bin' - -import wafsamba -from wafsamba import samba_dist, samba_utils -from waflib import Logs, Options, Context - -# setup what directories to put in a tarball -samba_dist.DIST_DIRS("""lib/talloc:. lib/replace:lib/replace -buildtools:buildtools third_party/waf:third_party/waf""") - - -def options(opt): - opt.BUILTIN_DEFAULT('replace') - opt.PRIVATE_EXTENSION_DEFAULT('talloc', noextension='talloc') - opt.RECURSE('lib/replace') - if opt.IN_LAUNCH_DIR(): - opt.add_option('--enable-talloc-compat1', - help=("Build talloc 1.x.x compat library [False]"), - action="store_true", dest='TALLOC_COMPAT1', default=False) - - -def configure(conf): - conf.RECURSE('lib/replace') - - conf.env.standalone_talloc = conf.IN_LAUNCH_DIR() - - conf.define('TALLOC_BUILD_VERSION_MAJOR', int(VERSION.split('.')[0])) - conf.define('TALLOC_BUILD_VERSION_MINOR', int(VERSION.split('.')[1])) - conf.define('TALLOC_BUILD_VERSION_RELEASE', int(VERSION.split('.')[2])) - - conf.env.TALLOC_COMPAT1 = False - if conf.env.standalone_talloc: - conf.env.TALLOC_COMPAT1 = Options.options.TALLOC_COMPAT1 - conf.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig' - conf.env.TALLOC_VERSION = VERSION - - conf.CHECK_XSLTPROC_MANPAGES() - - conf.CHECK_HEADERS('sys/auxv.h') - conf.CHECK_FUNCS('getauxval') - - conf.SAMBA_CONFIG_H() - - conf.SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS() - - conf.SAMBA_CHECK_PYTHON() - conf.SAMBA_CHECK_PYTHON_HEADERS() - - if not conf.env.standalone_talloc: - if conf.CHECK_BUNDLED_SYSTEM_PKG('talloc', minversion=VERSION, - implied_deps='replace'): - conf.define('USING_SYSTEM_TALLOC', 1) - - if conf.env.disable_python: - using_system_pytalloc_util = False - else: - using_system_pytalloc_util = True - name = 'pytalloc-util' + conf.all_envs['default']['PYTHON_SO_ABI_FLAG'] - if not conf.CHECK_BUNDLED_SYSTEM_PKG(name, minversion=VERSION, - implied_deps='talloc replace'): - using_system_pytalloc_util = False - - if using_system_pytalloc_util: - conf.define('USING_SYSTEM_PYTALLOC_UTIL', 1) - - -def build(bld): - bld.RECURSE('lib/replace') - - if bld.env.standalone_talloc: - private_library = False - - # should we also install the symlink to libtalloc1.so here? - bld.SAMBA_LIBRARY('talloc-compat1-%s' % (VERSION), - 'compat/talloc_compat1.c', - public_deps='talloc', - soname='libtalloc.so.1', - pc_files=[], - public_headers=[], - enabled=bld.env.TALLOC_COMPAT1) - - testsuite_deps = 'talloc' - if bld.CONFIG_SET('HAVE_PTHREAD'): - testsuite_deps += ' pthread' - - bld.SAMBA_BINARY('talloc_testsuite', - 'testsuite_main.c testsuite.c', - testsuite_deps, - install=False) - - bld.SAMBA_BINARY('talloc_test_magic_differs_helper', - 'test_magic_differs_helper.c', - 'talloc', install=False) - - else: - private_library = True - - if not bld.CONFIG_SET('USING_SYSTEM_TALLOC'): - - bld.SAMBA_LIBRARY('talloc', - 'talloc.c', - deps='replace', - abi_directory='ABI', - abi_match='talloc* _talloc*', - hide_symbols=True, - vnum=VERSION, - public_headers=('' if private_library else 'talloc.h'), - pc_files='talloc.pc', - public_headers_install=not private_library, - private_library=private_library, - manpages='man/talloc.3') - - if not bld.CONFIG_SET('USING_SYSTEM_PYTALLOC_UTIL'): - name = bld.pyembed_libname('pytalloc-util') - - bld.SAMBA_LIBRARY(name, - source='pytalloc_util.c', - public_deps='talloc', - pyembed=True, - vnum=VERSION, - hide_symbols=True, - abi_directory='ABI', - abi_match='pytalloc_* _pytalloc_*', - private_library=private_library, - public_headers=('' if private_library else 'pytalloc.h'), - pc_files='pytalloc-util.pc', - enabled=bld.PYTHON_BUILD_IS_ENABLED() - ) - bld.SAMBA_PYTHON('pytalloc', - 'pytalloc.c', - deps='talloc ' + name, - enabled=bld.PYTHON_BUILD_IS_ENABLED(), - realname='talloc.so') - - bld.SAMBA_PYTHON('test_pytalloc', - 'test_pytalloc.c', - deps=name, - enabled=bld.PYTHON_BUILD_IS_ENABLED(), - realname='_test_pytalloc.so', - install=False) - - -def testonly(ctx): - '''run talloc testsuite''' - import samba_utils - - samba_utils.ADD_LD_LIBRARY_PATH('bin/shared') - samba_utils.ADD_LD_LIBRARY_PATH('bin/shared/private') - - cmd = os.path.join(Context.g_module.out, 'talloc_testsuite') - ret = samba_utils.RUN_COMMAND(cmd) - print("testsuite returned %d" % ret) - magic_helper_cmd = os.path.join(Context.g_module.out, 'talloc_test_magic_differs_helper') - magic_cmd = os.path.join(Context.g_module.top, 'lib', 'talloc', - 'test_magic_differs.sh') - if not os.path.exists(magic_cmd): - magic_cmd = os.path.join(Context.g_module.top, 'test_magic_differs.sh') - - magic_ret = samba_utils.RUN_COMMAND(magic_cmd + " " + magic_helper_cmd) - print("magic differs test returned %d" % magic_ret) - pyret = samba_utils.RUN_PYTHON_TESTS(['test_pytalloc.py']) - print("python testsuite returned %d" % pyret) - sys.exit(ret or magic_ret or pyret) - -# WAF doesn't build the unit tests for this, maybe because they don't link with talloc? -# This forces it -def test(ctx): - Options.commands.append('build') - Options.commands.append('testonly') - -def dist(): - '''makes a tarball for distribution''' - samba_dist.dist() - -def reconfigure(ctx): - '''reconfigure if config scripts have changed''' - samba_utils.reconfigure(ctx) - - -def pydoctor(ctx): - '''build python apidocs''' - cmd='PYTHONPATH=bin/python pydoctor --project-name=talloc --project-url=http://talloc.samba.org/ --make-html --docformat=restructuredtext --introspect-c-modules --add-module bin/python/talloc.*' - print("Running: %s" % cmd) - os.system(cmd) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.1.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.1.sigs deleted file mode 100644 index 84f2007..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.1.sigs +++ /dev/null @@ -1,95 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_alloc_read: unsigned char *(struct tdb_context *, tdb_off_t, tdb_len_t) -tdb_allocate: tdb_off_t (struct tdb_context *, tdb_len_t, struct tdb_record *) -tdb_allrecord_lock: int (struct tdb_context *, int, enum tdb_lock_flags, bool) -tdb_allrecord_unlock: int (struct tdb_context *, int, bool) -tdb_allrecord_upgrade: int (struct tdb_context *) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_brlock: int (struct tdb_context *, int, tdb_off_t, size_t, enum tdb_lock_flags) -tdb_brunlock: int (struct tdb_context *, int, tdb_off_t, size_t) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_convert: void *(void *, uint32_t) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_do_delete: int (struct tdb_context *, tdb_off_t, struct tdb_record *) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_expand: int (struct tdb_context *, tdb_off_t) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_find_lock_hash: tdb_off_t (struct tdb_context *, TDB_DATA, uint32_t, int, struct tdb_record *) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_free: int (struct tdb_context *, tdb_off_t, struct tdb_record *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_have_extra_locks: bool (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_io_init: void (struct tdb_context *) -tdb_lock: int (struct tdb_context *, int, int) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lock_record: int (struct tdb_context *, tdb_off_t) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_mmap: void (struct tdb_context *) -tdb_munmap: int (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_needs_recovery: bool (struct tdb_context *) -tdb_nest_lock: int (struct tdb_context *, uint32_t, int, enum tdb_lock_flags) -tdb_nest_unlock: int (struct tdb_context *, uint32_t, int, bool) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_ofs_read: int (struct tdb_context *, tdb_off_t, tdb_off_t *) -tdb_ofs_write: int (struct tdb_context *, tdb_off_t, tdb_off_t *) -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_data: int (struct tdb_context *, TDB_DATA, tdb_off_t, tdb_len_t, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_rec_free_read: int (struct tdb_context *, tdb_off_t, struct tdb_record *) -tdb_rec_read: int (struct tdb_context *, tdb_off_t, struct tdb_record *) -tdb_rec_write: int (struct tdb_context *, tdb_off_t, struct tdb_record *) -tdb_release_transaction_locks: void (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_lock: int (struct tdb_context *, int, enum tdb_lock_flags) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_recover: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_unlock: int (struct tdb_context *, int) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlock_record: int (struct tdb_context *, tdb_off_t) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) -tdb_write_lock_record: int (struct tdb_context *, tdb_off_t) -tdb_write_unlock_record: int (struct tdb_context *, tdb_off_t) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.10.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.10.sigs deleted file mode 100644 index 61f6c19..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.10.sigs +++ /dev/null @@ -1,66 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.11.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.11.sigs deleted file mode 100644 index d727f21..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.11.sigs +++ /dev/null @@ -1,67 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.12.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.12.sigs deleted file mode 100644 index d727f21..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.12.sigs +++ /dev/null @@ -1,67 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.13.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.13.sigs deleted file mode 100644 index d727f21..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.13.sigs +++ /dev/null @@ -1,67 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.2.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.2.sigs deleted file mode 100644 index 043790d..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.2.sigs +++ /dev/null @@ -1,60 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.3.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.3.sigs deleted file mode 100644 index 043790d..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.3.sigs +++ /dev/null @@ -1,60 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.4.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.4.sigs deleted file mode 100644 index 043790d..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.4.sigs +++ /dev/null @@ -1,60 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.5.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.5.sigs deleted file mode 100644 index 1e01f3b..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.5.sigs +++ /dev/null @@ -1,61 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.6.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.6.sigs deleted file mode 100644 index 1e01f3b..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.6.sigs +++ /dev/null @@ -1,61 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.7.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.7.sigs deleted file mode 100644 index 1e01f3b..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.7.sigs +++ /dev/null @@ -1,61 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.8.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.8.sigs deleted file mode 100644 index 1e01f3b..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.8.sigs +++ /dev/null @@ -1,61 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.9.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.9.sigs deleted file mode 100644 index 9e4149b..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.2.9.sigs +++ /dev/null @@ -1,62 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.0.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.0.sigs deleted file mode 100644 index 7d3e469..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.0.sigs +++ /dev/null @@ -1,68 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.1.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.1.sigs deleted file mode 100644 index 7d3e469..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.1.sigs +++ /dev/null @@ -1,68 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.10.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.10.sigs deleted file mode 100644 index 2545c99..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.10.sigs +++ /dev/null @@ -1,69 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.11.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.11.sigs deleted file mode 100644 index 48f4278..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.11.sigs +++ /dev/null @@ -1,70 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.12.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.12.sigs deleted file mode 100644 index 48f4278..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.12.sigs +++ /dev/null @@ -1,70 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.13.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.13.sigs deleted file mode 100644 index 48f4278..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.13.sigs +++ /dev/null @@ -1,70 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.14.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.14.sigs deleted file mode 100644 index 61ce5e6..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.14.sigs +++ /dev/null @@ -1,71 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_active: bool (struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.15.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.15.sigs deleted file mode 100644 index 61ce5e6..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.15.sigs +++ /dev/null @@ -1,71 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_active: bool (struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.16.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.16.sigs deleted file mode 100644 index 61ce5e6..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.16.sigs +++ /dev/null @@ -1,71 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_active: bool (struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.17.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.17.sigs deleted file mode 100644 index e2b0427..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.17.sigs +++ /dev/null @@ -1,73 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_active: bool (struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_chain: int (struct tdb_context *, unsigned int, tdb_traverse_func, void *) -tdb_traverse_key_chain: int (struct tdb_context *, TDB_DATA, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.18.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.18.sigs deleted file mode 100644 index e2b0427..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.18.sigs +++ /dev/null @@ -1,73 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_active: bool (struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_chain: int (struct tdb_context *, unsigned int, tdb_traverse_func, void *) -tdb_traverse_key_chain: int (struct tdb_context *, TDB_DATA, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.2.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.2.sigs deleted file mode 100644 index 7d3e469..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.2.sigs +++ /dev/null @@ -1,68 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.3.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.3.sigs deleted file mode 100644 index 7d3e469..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.3.sigs +++ /dev/null @@ -1,68 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.4.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.4.sigs deleted file mode 100644 index 7d3e469..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.4.sigs +++ /dev/null @@ -1,68 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.5.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.5.sigs deleted file mode 100644 index 2545c99..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.5.sigs +++ /dev/null @@ -1,69 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.6.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.6.sigs deleted file mode 100644 index 2545c99..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.6.sigs +++ /dev/null @@ -1,69 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.7.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.7.sigs deleted file mode 100644 index 2545c99..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.7.sigs +++ /dev/null @@ -1,69 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.8.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.8.sigs deleted file mode 100644 index 2545c99..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.8.sigs +++ /dev/null @@ -1,69 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.9.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.9.sigs deleted file mode 100644 index 2545c99..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.3.9.sigs +++ /dev/null @@ -1,69 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.4.0.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.4.0.sigs deleted file mode 100644 index e2b0427..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.4.0.sigs +++ /dev/null @@ -1,73 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_active: bool (struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_chain: int (struct tdb_context *, unsigned int, tdb_traverse_func, void *) -tdb_traverse_key_chain: int (struct tdb_context *, TDB_DATA, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.4.1.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.4.1.sigs deleted file mode 100644 index e2b0427..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.4.1.sigs +++ /dev/null @@ -1,73 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_active: bool (struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_chain: int (struct tdb_context *, unsigned int, tdb_traverse_func, void *) -tdb_traverse_key_chain: int (struct tdb_context *, TDB_DATA, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/ABI/tdb-1.4.2.sigs b/ldb-2.0.8/lib/tdb/ABI/tdb-1.4.2.sigs deleted file mode 100644 index e2b0427..0000000 --- a/ldb-2.0.8/lib/tdb/ABI/tdb-1.4.2.sigs +++ /dev/null @@ -1,73 +0,0 @@ -tdb_add_flags: void (struct tdb_context *, unsigned int) -tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) -tdb_chainlock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) -tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock: int (struct tdb_context *, TDB_DATA) -tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) -tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_close: int (struct tdb_context *) -tdb_delete: int (struct tdb_context *, TDB_DATA) -tdb_dump_all: void (struct tdb_context *) -tdb_enable_seqnum: void (struct tdb_context *) -tdb_error: enum TDB_ERROR (struct tdb_context *) -tdb_errorstr: const char *(struct tdb_context *) -tdb_exists: int (struct tdb_context *, TDB_DATA) -tdb_fd: int (struct tdb_context *) -tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_firstkey: TDB_DATA (struct tdb_context *) -tdb_freelist_size: int (struct tdb_context *) -tdb_get_flags: int (struct tdb_context *) -tdb_get_logging_private: void *(struct tdb_context *) -tdb_get_seqnum: int (struct tdb_context *) -tdb_hash_size: int (struct tdb_context *) -tdb_increment_seqnum_nonblock: void (struct tdb_context *) -tdb_jenkins_hash: unsigned int (TDB_DATA *) -tdb_lock_nonblock: int (struct tdb_context *, int, int) -tdb_lockall: int (struct tdb_context *) -tdb_lockall_mark: int (struct tdb_context *) -tdb_lockall_nonblock: int (struct tdb_context *) -tdb_lockall_read: int (struct tdb_context *) -tdb_lockall_read_nonblock: int (struct tdb_context *) -tdb_lockall_unmark: int (struct tdb_context *) -tdb_log_fn: tdb_log_func (struct tdb_context *) -tdb_map_size: size_t (struct tdb_context *) -tdb_name: const char *(struct tdb_context *) -tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) -tdb_null: dptr = 0xXXXX, dsize = 0 -tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) -tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) -tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_printfreelist: int (struct tdb_context *) -tdb_remove_flags: void (struct tdb_context *, unsigned int) -tdb_reopen: int (struct tdb_context *) -tdb_reopen_all: int (int) -tdb_repack: int (struct tdb_context *) -tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) -tdb_runtime_check_for_robust_mutexes: bool (void) -tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) -tdb_set_max_dead: void (struct tdb_context *, int) -tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) -tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) -tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) -tdb_summary: char *(struct tdb_context *) -tdb_transaction_active: bool (struct tdb_context *) -tdb_transaction_cancel: int (struct tdb_context *) -tdb_transaction_commit: int (struct tdb_context *) -tdb_transaction_prepare_commit: int (struct tdb_context *) -tdb_transaction_start: int (struct tdb_context *) -tdb_transaction_start_nonblock: int (struct tdb_context *) -tdb_transaction_write_lock_mark: int (struct tdb_context *) -tdb_transaction_write_lock_unmark: int (struct tdb_context *) -tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_traverse_chain: int (struct tdb_context *, unsigned int, tdb_traverse_func, void *) -tdb_traverse_key_chain: int (struct tdb_context *, TDB_DATA, tdb_traverse_func, void *) -tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) -tdb_unlock: int (struct tdb_context *, int, int) -tdb_unlockall: int (struct tdb_context *) -tdb_unlockall_read: int (struct tdb_context *) -tdb_validate_freelist: int (struct tdb_context *, int *) -tdb_wipe_all: int (struct tdb_context *) diff --git a/ldb-2.0.8/lib/tdb/Makefile b/ldb-2.0.8/lib/tdb/Makefile deleted file mode 100644 index 8fd56c8..0000000 --- a/ldb-2.0.8/lib/tdb/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -# simple makefile wrapper to run waf - -WAF_BIN=`PATH=buildtools/bin:../../buildtools/bin:$$PATH which waf` -WAF_BINARY=$(PYTHON) $(WAF_BIN) -WAF=PYTHONHASHSEED=1 WAF_MAKE=1 $(WAF_BINARY) - -all: - $(WAF) build - -install: - $(WAF) install - -uninstall: - $(WAF) uninstall - -test: FORCE - $(WAF) test $(TEST_OPTIONS) - -testenv: - $(WAF) test --testenv $(TEST_OPTIONS) - -quicktest: - $(WAF) test --quick $(TEST_OPTIONS) - -dist: - touch .tmplock - WAFLOCK=.tmplock $(WAF) dist - -distcheck: - touch .tmplock - WAFLOCK=.tmplock $(WAF) distcheck - -clean: - $(WAF) clean - -distclean: - $(WAF) distclean - -reconfigure: configure - $(WAF) reconfigure - -show_waf_options: - $(WAF) --help - -# some compatibility make targets -everything: all - -testsuite: all - -check: test - -torture: all - -# this should do an install as well, once install is finished -installcheck: test - -etags: - $(WAF) etags - -ctags: - $(WAF) ctags - -pydoctor: - $(WAF) pydoctor - -bin/%:: FORCE - $(WAF) --targets=`basename $@` -FORCE: diff --git a/ldb-2.0.8/lib/tdb/_tdb_text.py b/ldb-2.0.8/lib/tdb/_tdb_text.py deleted file mode 100644 index f3caa53..0000000 --- a/ldb-2.0.8/lib/tdb/_tdb_text.py +++ /dev/null @@ -1,137 +0,0 @@ -# Text wrapper for tdb bindings -# -# Copyright (C) 2015 Petr Viktorin -# Published under the GNU LGPLv3 or later - -import sys - -import tdb - - -class TdbTextWrapper(object): - """Text interface for a TDB file""" - - def __init__(self, tdb): - self._tdb = tdb - - @property - def raw(self): - return self._tdb - - def get(self, key): - key = key.encode('utf-8') - result = self._tdb.get(key) - if result is not None: - return result.decode('utf-8') - - def append(self, key, value): - key = key.encode('utf-8') - value = value.encode('utf-8') - self._tdb.append(key, value) - - def firstkey(self): - result = self._tdb.firstkey() - if result: - return result.decode('utf-8') - - def nextkey(self, key): - key = key.encode('utf-8') - result = self._tdb.nextkey(key) - if result is not None: - return result.decode('utf-8') - - def delete(self, key): - key = key.encode('utf-8') - self._tdb.delete(key) - - def store(self, key, value): - key = key.encode('utf-8') - value = value.encode('utf-8') - self._tdb.store(key, value) - - def __iter__(self): - for key in iter(self._tdb): - yield key.decode('utf-8') - - def __getitem__(self, key): - key = key.encode('utf-8') - result = self._tdb[key] - return result.decode('utf-8') - - def __contains__(self, key): - key = key.encode('utf-8') - return key in self._tdb - - def __repr__(self): - return '' % self._tdb - - def __setitem__(self, key, value): - key = key.encode('utf-8') - value = value.encode('utf-8') - self._tdb[key] = value - - def __delitem__(self, key): - key = key.encode('utf-8') - del self._tdb[key] - - if sys.version_info > (3, 0): - keys = __iter__ - else: - iterkeys = __iter__ - has_key = __contains__ - - -## Add wrappers for functions and getters that don't deal with text - -def _add_wrapper(name): - orig = getattr(tdb.Tdb, name) - - def wrapper(self, *args, **kwargs): - return orig(self._tdb, *args, **kwargs) - wrapper.__name__ = orig.__name__ - wrapper.__doc__ = orig.__doc__ - - setattr(TdbTextWrapper, name, wrapper) - -for name in ("transaction_cancel", - "transaction_commit", - "transaction_prepare_commit", - "transaction_start", - "reopen", - "lock_all", - "unlock_all", - "read_lock_all", - "read_unlock_all", - "close", - "add_flags", - "remove_flags", - "clear", - "repack", - "enable_seqnum", - "increment_seqnum_nonblock", - ): - _add_wrapper(name) - - -def _add_getter(name): - orig = getattr(tdb.Tdb, name) - doc = orig.__doc__ - - def getter(self): - return getattr(self._tdb, name) - - def setter(self, value): - return setattr(self._tdb, name, value) - - setattr(TdbTextWrapper, name, property(getter, setter, doc=doc)) - -for name in ("hash_size", - "map_size", - "freelist_size", - "flags", - "max_dead", - "filename", - "seqnum", - "text", - ): - _add_getter(name) diff --git a/ldb-2.0.8/lib/tdb/common/check.c b/ldb-2.0.8/lib/tdb/common/check.c deleted file mode 100644 index d7741f6..0000000 --- a/ldb-2.0.8/lib/tdb/common/check.c +++ /dev/null @@ -1,489 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Rusty Russell 2009 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ -#include "tdb_private.h" - -/* Since we opened it, these shouldn't fail unless it's recent corruption. */ -static bool tdb_check_header(struct tdb_context *tdb, tdb_off_t *recovery) -{ - struct tdb_header hdr; - uint32_t h1, h2; - - if (tdb->methods->tdb_read(tdb, 0, &hdr, sizeof(hdr), 0) == -1) - return false; - if (strcmp(hdr.magic_food, TDB_MAGIC_FOOD) != 0) - goto corrupt; - - CONVERT(hdr); - if (hdr.version != TDB_VERSION) - goto corrupt; - - if (hdr.rwlocks != 0 && - hdr.rwlocks != TDB_FEATURE_FLAG_MAGIC && - hdr.rwlocks != TDB_HASH_RWLOCK_MAGIC) - goto corrupt; - - tdb_header_hash(tdb, &h1, &h2); - if (hdr.magic1_hash && hdr.magic2_hash && - (hdr.magic1_hash != h1 || hdr.magic2_hash != h2)) - goto corrupt; - - if (hdr.hash_size == 0) - goto corrupt; - - if (hdr.hash_size != tdb->hash_size) - goto corrupt; - - if (hdr.recovery_start != 0 && - hdr.recovery_start < TDB_DATA_START(tdb->hash_size)) - goto corrupt; - - *recovery = hdr.recovery_start; - return true; - -corrupt: - tdb->ecode = TDB_ERR_CORRUPT; - TDB_LOG((tdb, TDB_DEBUG_ERROR, "Header is corrupt\n")); - return false; -} - -/* Generic record header check. */ -static bool tdb_check_record(struct tdb_context *tdb, - tdb_off_t off, - const struct tdb_record *rec) -{ - tdb_off_t tailer; - - /* Check rec->next: 0 or points to record offset, aligned. */ - if (rec->next > 0 && rec->next < TDB_DATA_START(tdb->hash_size)){ - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "Record offset %u too small next %u\n", - off, rec->next)); - goto corrupt; - } - if (rec->next + sizeof(*rec) < rec->next) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "Record offset %u too large next %u\n", - off, rec->next)); - goto corrupt; - } - if ((rec->next % TDB_ALIGNMENT) != 0) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "Record offset %u misaligned next %u\n", - off, rec->next)); - goto corrupt; - } - if (tdb_oob(tdb, rec->next, sizeof(*rec), 0)) - goto corrupt; - - /* Check rec_len: similar to rec->next, implies next record. */ - if ((rec->rec_len % TDB_ALIGNMENT) != 0) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "Record offset %u misaligned length %u\n", - off, rec->rec_len)); - goto corrupt; - } - /* Must fit tailer. */ - if (rec->rec_len < sizeof(tailer)) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "Record offset %u too short length %u\n", - off, rec->rec_len)); - goto corrupt; - } - /* OOB allows "right at the end" access, so this works for last rec. */ - if (tdb_oob(tdb, off, sizeof(*rec)+rec->rec_len, 0)) - goto corrupt; - - /* Check tailer. */ - if (tdb_ofs_read(tdb, off+sizeof(*rec)+rec->rec_len-sizeof(tailer), - &tailer) == -1) - goto corrupt; - if (tailer != sizeof(*rec) + rec->rec_len) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "Record offset %u invalid tailer\n", off)); - goto corrupt; - } - - return true; - -corrupt: - tdb->ecode = TDB_ERR_CORRUPT; - return false; -} - -/* Grab some bytes: may copy if can't use mmap. - Caller has already done bounds check. */ -static TDB_DATA get_bytes(struct tdb_context *tdb, - tdb_off_t off, tdb_len_t len) -{ - TDB_DATA d; - - d.dsize = len; - - if (tdb->transaction == NULL && tdb->map_ptr != NULL) - d.dptr = (unsigned char *)tdb->map_ptr + off; - else - d.dptr = tdb_alloc_read(tdb, off, d.dsize); - return d; -} - -/* Frees data if we're not able to simply use mmap. */ -static void put_bytes(struct tdb_context *tdb, TDB_DATA d) -{ - if (tdb->transaction == NULL && tdb->map_ptr != NULL) - return; - free(d.dptr); -} - -/* We use the excellent Jenkins lookup3 hash; this is based on hash_word2. - * See: http://burtleburtle.net/bob/c/lookup3.c - */ -#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) -static void hash(uint32_t key, uint32_t *pc, uint32_t *pb) -{ - uint32_t a,b,c; - - /* Set up the internal state */ - a = b = c = 0xdeadbeef + *pc; - c += *pb; - a += key; - c ^= b; c -= rot(b,14); - a ^= c; a -= rot(c,11); - b ^= a; b -= rot(a,25); - c ^= b; c -= rot(b,16); - a ^= c; a -= rot(c,4); - b ^= a; b -= rot(a,14); - c ^= b; c -= rot(b,24); - *pc=c; *pb=b; -} - -/* - We want to check that all free records are in the free list - (only once), and all free list entries are free records. Similarly - for each hash chain of used records. - - Doing that naively (without walking hash chains, since we want to be - linear) means keeping a list of records which have been seen in each - hash chain, and another of records pointed to (ie. next pointers - from records and the initial hash chain heads). These two lists - should be equal. This will take 8 bytes per record, and require - sorting at the end. - - So instead, we record each offset in a bitmap such a way that - recording it twice will cancel out. Since each offset should appear - exactly twice, the bitmap should be zero at the end. - - The approach was inspired by Bloom Filters (see Wikipedia). For - each value, we flip K bits in a bitmap of size N. The number of - distinct arrangements is: - - N! / (K! * (N-K)!) - - Of course, not all arrangements are actually distinct, but testing - shows this formula to be close enough. - - So, if K == 8 and N == 256, the probability of two things flipping the same - bits is 1 in 409,663,695,276,000. - - Given that ldb uses a hash size of 10000, using 32 bytes per hash chain - (320k) seems reasonable. -*/ -#define NUM_HASHES 8 -#define BITMAP_BITS 256 - -static void bit_flip(unsigned char bits[], unsigned int idx) -{ - bits[idx / CHAR_BIT] ^= (1 << (idx % CHAR_BIT)); -} - -/* We record offsets in a bitmap for the particular chain it should be in. */ -static void record_offset(unsigned char bits[], tdb_off_t off) -{ - uint32_t h1 = off, h2 = 0; - unsigned int i; - - /* We get two good hash values out of jhash2, so we use both. Then - * we keep going to produce further hash values. */ - for (i = 0; i < NUM_HASHES / 2; i++) { - hash(off, &h1, &h2); - bit_flip(bits, h1 % BITMAP_BITS); - bit_flip(bits, h2 % BITMAP_BITS); - h2++; - } -} - -/* Check that an in-use record is valid. */ -static bool tdb_check_used_record(struct tdb_context *tdb, - tdb_off_t off, - const struct tdb_record *rec, - unsigned char **hashes, - int (*check)(TDB_DATA, TDB_DATA, void *), - void *private_data) -{ - TDB_DATA key, data; - tdb_len_t len; - - if (!tdb_check_record(tdb, off, rec)) - return false; - - /* key + data + tailer must fit in record */ - len = rec->key_len; - len += rec->data_len; - if (len < rec->data_len) { - /* overflow */ - TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record lengths overflow\n")); - return false; - } - len += sizeof(tdb_off_t); - if (len < sizeof(tdb_off_t)) { - /* overflow */ - TDB_LOG((tdb, TDB_DEBUG_ERROR, "Record lengths overflow\n")); - return false; - } - - if (len > rec->rec_len) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "Record offset %u too short for contents\n", off)); - return false; - } - - key = get_bytes(tdb, off + sizeof(*rec), rec->key_len); - if (!key.dptr) - return false; - - if (tdb->hash_fn(&key) != rec->full_hash) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "Record offset %u has incorrect hash\n", off)); - goto fail_put_key; - } - - /* Mark this offset as a known value for this hash bucket. */ - record_offset(hashes[BUCKET(rec->full_hash)+1], off); - /* And similarly if the next pointer is valid. */ - if (rec->next) - record_offset(hashes[BUCKET(rec->full_hash)+1], rec->next); - - /* If they supply a check function and this record isn't dead, - get data and feed it. */ - if (check && rec->magic != TDB_DEAD_MAGIC) { - data = get_bytes(tdb, off + sizeof(*rec) + rec->key_len, - rec->data_len); - if (!data.dptr) - goto fail_put_key; - - if (check(key, data, private_data) == -1) - goto fail_put_data; - put_bytes(tdb, data); - } - - put_bytes(tdb, key); - return true; - -fail_put_data: - put_bytes(tdb, data); -fail_put_key: - put_bytes(tdb, key); - return false; -} - -/* Check that an unused record is valid. */ -static bool tdb_check_free_record(struct tdb_context *tdb, - tdb_off_t off, - const struct tdb_record *rec, - unsigned char **hashes) -{ - if (!tdb_check_record(tdb, off, rec)) - return false; - - /* Mark this offset as a known value for the free list. */ - record_offset(hashes[0], off); - /* And similarly if the next pointer is valid. */ - if (rec->next) - record_offset(hashes[0], rec->next); - return true; -} - -/* Slow, but should be very rare. */ -size_t tdb_dead_space(struct tdb_context *tdb, tdb_off_t off) -{ - size_t len; - - for (len = 0; off + len < tdb->map_size; len++) { - char c; - if (tdb->methods->tdb_read(tdb, off, &c, 1, 0)) - return 0; - if (c != 0 && c != 0x42) - break; - } - return len; -} - -_PUBLIC_ int tdb_check(struct tdb_context *tdb, - int (*check)(TDB_DATA key, TDB_DATA data, void *private_data), - void *private_data) -{ - unsigned int h; - unsigned char **hashes; - tdb_off_t off, recovery_start; - struct tdb_record rec; - bool found_recovery = false; - tdb_len_t dead; - bool locked; - - /* Read-only databases use no locking at all: it's best-effort. - * We may have a write lock already, so skip that case too. */ - if (tdb->read_only || tdb->allrecord_lock.count != 0) { - locked = false; - } else { - if (tdb_lockall_read(tdb) == -1) - return -1; - locked = true; - } - - /* Make sure we know true size of the underlying file. */ - tdb_oob(tdb, tdb->map_size, 1, 1); - - /* Header must be OK: also gets us the recovery ptr, if any. */ - if (!tdb_check_header(tdb, &recovery_start)) - goto unlock; - - /* We should have the whole header, too. */ - if (tdb->map_size < TDB_DATA_START(tdb->hash_size)) { - tdb->ecode = TDB_ERR_CORRUPT; - TDB_LOG((tdb, TDB_DEBUG_ERROR, "File too short for hashes\n")); - goto unlock; - } - - /* One big malloc: pointers then bit arrays. */ - hashes = (unsigned char **)calloc( - 1, sizeof(hashes[0]) * (1+tdb->hash_size) - + BITMAP_BITS / CHAR_BIT * (1+tdb->hash_size)); - if (!hashes) { - tdb->ecode = TDB_ERR_OOM; - goto unlock; - } - - /* Initialize pointers */ - hashes[0] = (unsigned char *)(&hashes[1+tdb->hash_size]); - for (h = 1; h < 1+tdb->hash_size; h++) - hashes[h] = hashes[h-1] + BITMAP_BITS / CHAR_BIT; - - /* Freelist and hash headers are all in a row: read them. */ - for (h = 0; h < 1+tdb->hash_size; h++) { - if (tdb_ofs_read(tdb, FREELIST_TOP + h*sizeof(tdb_off_t), - &off) == -1) - goto free; - if (off) - record_offset(hashes[h], off); - } - - /* For each record, read it in and check it's ok. */ - for (off = TDB_DATA_START(tdb->hash_size); - off < tdb->map_size; - off += sizeof(rec) + rec.rec_len) { - if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), - DOCONV()) == -1) - goto free; - switch (rec.magic) { - case TDB_MAGIC: - case TDB_DEAD_MAGIC: - if (!tdb_check_used_record(tdb, off, &rec, hashes, - check, private_data)) - goto free; - break; - case TDB_FREE_MAGIC: - if (!tdb_check_free_record(tdb, off, &rec, hashes)) - goto free; - break; - /* If we crash after ftruncate, we can get zeroes or fill. */ - case TDB_RECOVERY_INVALID_MAGIC: - case 0x42424242: - if (recovery_start == off) { - found_recovery = true; - break; - } - dead = tdb_dead_space(tdb, off); - if (dead < sizeof(rec)) - goto corrupt; - - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "Dead space at %u-%u (of %u)\n", - off, off + dead, tdb->map_size)); - rec.rec_len = dead - sizeof(rec); - break; - case TDB_RECOVERY_MAGIC: - if (recovery_start != off) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "Unexpected recovery record at offset %u\n", - off)); - goto free; - } - found_recovery = true; - break; - default: ; - corrupt: - tdb->ecode = TDB_ERR_CORRUPT; - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "Bad magic 0x%x at offset %u\n", - rec.magic, off)); - goto free; - } - } - - /* Now, hashes should all be empty: each record exists and is referred - * to by one other. */ - for (h = 0; h < 1+tdb->hash_size; h++) { - unsigned int i; - for (i = 0; i < BITMAP_BITS / CHAR_BIT; i++) { - if (hashes[h][i] != 0) { - tdb->ecode = TDB_ERR_CORRUPT; - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "Hashes do not match records\n")); - goto free; - } - } - } - - /* We must have found recovery area if there was one. */ - if (recovery_start != 0 && !found_recovery) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "Expected a recovery area at %u\n", - recovery_start)); - goto free; - } - - free(hashes); - if (locked) { - tdb_unlockall_read(tdb); - } - return 0; - -free: - free(hashes); -unlock: - if (locked) { - tdb_unlockall_read(tdb); - } - return -1; -} diff --git a/ldb-2.0.8/lib/tdb/common/dump.c b/ldb-2.0.8/lib/tdb/common/dump.c deleted file mode 100644 index adcf591..0000000 --- a/ldb-2.0.8/lib/tdb/common/dump.c +++ /dev/null @@ -1,149 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "tdb_private.h" - -static tdb_off_t tdb_dump_record(struct tdb_context *tdb, int hash, - tdb_off_t offset) -{ - struct tdb_record rec; - tdb_off_t tailer_ofs, tailer; - - if (tdb->methods->tdb_read(tdb, offset, (char *)&rec, - sizeof(rec), DOCONV()) == -1) { - printf("ERROR: failed to read record at %u\n", offset); - return 0; - } - - printf(" rec: hash=%d offset=0x%08x next=0x%08x rec_len=%u " - "key_len=%u data_len=%u full_hash=0x%08x magic=0x%08x\n", - hash, offset, rec.next, rec.rec_len, rec.key_len, rec.data_len, - rec.full_hash, rec.magic); - - tailer_ofs = offset + sizeof(rec) + rec.rec_len - sizeof(tdb_off_t); - - if (tdb_ofs_read(tdb, tailer_ofs, &tailer) == -1) { - printf("ERROR: failed to read tailer at %u\n", tailer_ofs); - return rec.next; - } - - if (tailer != rec.rec_len + sizeof(rec)) { - printf("ERROR: tailer does not match record! tailer=%u totalsize=%u\n", - (unsigned int)tailer, (unsigned int)(rec.rec_len + sizeof(rec))); - } - return rec.next; -} - -static int tdb_dump_chain(struct tdb_context *tdb, int i) -{ - struct tdb_chainwalk_ctx chainwalk; - tdb_off_t rec_ptr, top; - - if (i == -1) { - top = FREELIST_TOP; - } else { - top = TDB_HASH_TOP(i); - } - - if (tdb_lock(tdb, i, F_WRLCK) != 0) - return -1; - - if (tdb_ofs_read(tdb, top, &rec_ptr) == -1) - return tdb_unlock(tdb, i, F_WRLCK); - - tdb_chainwalk_init(&chainwalk, rec_ptr); - - if (rec_ptr) - printf("hash=%d\n", i); - - while (rec_ptr) { - bool ok; - rec_ptr = tdb_dump_record(tdb, i, rec_ptr); - ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); - if (!ok) { - printf("circular hash chain %d\n", i); - break; - } - } - - return tdb_unlock(tdb, i, F_WRLCK); -} - -_PUBLIC_ void tdb_dump_all(struct tdb_context *tdb) -{ - uint32_t i; - for (i=0;ihash_size;i++) { - tdb_dump_chain(tdb, i); - } - printf("freelist:\n"); - tdb_dump_chain(tdb, -1); -} - -_PUBLIC_ int tdb_printfreelist(struct tdb_context *tdb) -{ - int ret; - long total_free = 0; - tdb_off_t offset, rec_ptr; - struct tdb_record rec; - - if ((ret = tdb_lock(tdb, -1, F_WRLCK)) != 0) - return ret; - - offset = FREELIST_TOP; - - /* read in the freelist top */ - if (tdb_ofs_read(tdb, offset, &rec_ptr) == -1) { - tdb_unlock(tdb, -1, F_WRLCK); - return 0; - } - - printf("freelist top=[0x%08x]\n", rec_ptr ); - while (rec_ptr) { - if (tdb->methods->tdb_read(tdb, rec_ptr, (char *)&rec, - sizeof(rec), DOCONV()) == -1) { - tdb_unlock(tdb, -1, F_WRLCK); - return -1; - } - - if (rec.magic != TDB_FREE_MAGIC) { - printf("bad magic 0x%08x in free list\n", rec.magic); - tdb_unlock(tdb, -1, F_WRLCK); - return -1; - } - - printf("entry offset=[0x%08x], rec.rec_len = [0x%08x (%u)] (end = 0x%08x)\n", - rec_ptr, rec.rec_len, rec.rec_len, rec_ptr + rec.rec_len); - total_free += rec.rec_len; - - /* move to the next record */ - rec_ptr = rec.next; - } - printf("total rec_len = [0x%08lx (%lu)]\n", total_free, total_free); - - return tdb_unlock(tdb, -1, F_WRLCK); -} - diff --git a/ldb-2.0.8/lib/tdb/common/error.c b/ldb-2.0.8/lib/tdb/common/error.c deleted file mode 100644 index 478eb88..0000000 --- a/ldb-2.0.8/lib/tdb/common/error.c +++ /dev/null @@ -1,57 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "tdb_private.h" - -_PUBLIC_ enum TDB_ERROR tdb_error(struct tdb_context *tdb) -{ - return tdb->ecode; -} - -static struct tdb_errname { - enum TDB_ERROR ecode; const char *estring; -} emap[] = { {TDB_SUCCESS, "Success"}, - {TDB_ERR_CORRUPT, "Corrupt database"}, - {TDB_ERR_IO, "IO Error"}, - {TDB_ERR_LOCK, "Locking error"}, - {TDB_ERR_OOM, "Out of memory"}, - {TDB_ERR_EXISTS, "Record exists"}, - {TDB_ERR_NOLOCK, "Lock exists on other keys"}, - {TDB_ERR_EINVAL, "Invalid parameter"}, - {TDB_ERR_NOEXIST, "Record does not exist"}, - {TDB_ERR_RDONLY, "write not permitted"} }; - -/* Error string for the last tdb error */ -_PUBLIC_ const char *tdb_errorstr(struct tdb_context *tdb) -{ - uint32_t i; - for (i = 0; i < sizeof(emap) / sizeof(struct tdb_errname); i++) - if (tdb->ecode == emap[i].ecode) - return emap[i].estring; - return "Invalid error code"; -} - diff --git a/ldb-2.0.8/lib/tdb/common/freelist.c b/ldb-2.0.8/lib/tdb/common/freelist.c deleted file mode 100644 index 046c747..0000000 --- a/ldb-2.0.8/lib/tdb/common/freelist.c +++ /dev/null @@ -1,747 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "tdb_private.h" - -/* read a freelist record and check for simple errors */ -int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, struct tdb_record *rec) -{ - if (tdb->methods->tdb_read(tdb, off, rec, sizeof(*rec),DOCONV()) == -1) - return -1; - - if (rec->magic == TDB_MAGIC) { - /* this happens when a app is showdown while deleting a record - we should - not completely fail when this happens */ - TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read non-free magic 0x%x at offset=%u - fixing\n", - rec->magic, off)); - rec->magic = TDB_FREE_MAGIC; - if (tdb_rec_write(tdb, off, rec) == -1) - return -1; - } - - if (rec->magic != TDB_FREE_MAGIC) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_CORRUPT; - TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_rec_free_read bad magic 0x%x at offset=%u\n", - rec->magic, off)); - return -1; - } - if (tdb_oob(tdb, rec->next, sizeof(*rec), 0) != 0) - return -1; - return 0; -} - -/* update a record tailer (must hold allocation lock) */ -static int update_tailer(struct tdb_context *tdb, tdb_off_t offset, - const struct tdb_record *rec) -{ - tdb_off_t totalsize; - - /* Offset of tailer from record header */ - totalsize = sizeof(*rec) + rec->rec_len; - return tdb_ofs_write(tdb, offset + totalsize - sizeof(tdb_off_t), - &totalsize); -} - -/** - * Read the record directly on the left. - * Fail if there is no record on the left. - */ -static int read_record_on_left(struct tdb_context *tdb, tdb_off_t rec_ptr, - tdb_off_t *left_p, - struct tdb_record *left_r) -{ - tdb_off_t left_ptr; - tdb_off_t left_size; - struct tdb_record left_rec; - int ret; - - left_ptr = rec_ptr - sizeof(tdb_off_t); - - if (left_ptr <= TDB_DATA_START(tdb->hash_size)) { - /* no record on the left */ - return -1; - } - - /* Read in tailer and jump back to header */ - ret = tdb_ofs_read(tdb, left_ptr, &left_size); - if (ret == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, - "tdb_free: left offset read failed at %u\n", left_ptr)); - return -1; - } - - /* it could be uninitialised data */ - if (left_size == 0 || left_size == TDB_PAD_U32) { - return -1; - } - - if (left_size > rec_ptr) { - return -1; - } - - left_ptr = rec_ptr - left_size; - - if (left_ptr < TDB_DATA_START(tdb->hash_size)) { - return -1; - } - - /* Now read in the left record */ - ret = tdb->methods->tdb_read(tdb, left_ptr, &left_rec, - sizeof(left_rec), DOCONV()); - if (ret == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, - "tdb_free: left read failed at %u (%u)\n", - left_ptr, left_size)); - return -1; - } - - *left_p = left_ptr; - *left_r = left_rec; - - return 0; -} - -/** - * Merge new freelist record with the direct left neighbour. - * This assumes that left_rec represents the record - * directly to the left of right_rec and that this is - * a freelist record. - */ -static int merge_with_left_record(struct tdb_context *tdb, - tdb_off_t left_ptr, - struct tdb_record *left_rec, - struct tdb_record *right_rec) -{ - int ret; - - left_rec->rec_len += sizeof(*right_rec) + right_rec->rec_len; - - ret = tdb_rec_write(tdb, left_ptr, left_rec); - if (ret == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, - "merge_with_left_record: update_left failed at %u\n", - left_ptr)); - return -1; - } - - ret = update_tailer(tdb, left_ptr, left_rec); - if (ret == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, - "merge_with_left_record: update_tailer failed at %u\n", - left_ptr)); - return -1; - } - - return 0; -} - -/** - * Check whether the record left of a given freelist record is - * also a freelist record, and if so, merge the two records. - * - * Return code: - * -1 upon error - * 0 if left was not a free record - * 1 if left was free and successfully merged. - * - * The current record is handed in with pointer and fully read record. - * - * The left record pointer and struct can be retrieved as result - * in lp and lr; - */ -static int check_merge_with_left_record(struct tdb_context *tdb, - tdb_off_t rec_ptr, - struct tdb_record *rec, - tdb_off_t *lp, - struct tdb_record *lr) -{ - tdb_off_t left_ptr; - struct tdb_record left_rec; - int ret; - - ret = read_record_on_left(tdb, rec_ptr, &left_ptr, &left_rec); - if (ret != 0) { - return 0; - } - - if (left_rec.magic != TDB_FREE_MAGIC) { - return 0; - } - - /* It's free - expand to include it. */ - ret = merge_with_left_record(tdb, left_ptr, &left_rec, rec); - if (ret != 0) { - return -1; - } - - if (lp != NULL) { - *lp = left_ptr; - } - - if (lr != NULL) { - *lr = left_rec; - } - - return 1; -} - -/** - * Check whether the record left of a given freelist record is - * also a freelist record, and if so, merge the two records. - * - * Return code: - * -1 upon error - * 0 if left was not a free record - * 1 if left was free and successfully merged. - * - * In this variant, the input record is specified just as the pointer - * and is read from the database if needed. - * - * next_ptr will contain the original record's next pointer after - * successful merging (which will be lost after merging), so that - * the caller can update the last pointer. - */ -static int check_merge_ptr_with_left_record(struct tdb_context *tdb, - tdb_off_t rec_ptr, - tdb_off_t *next_ptr) -{ - tdb_off_t left_ptr; - struct tdb_record rec, left_rec; - int ret; - - ret = read_record_on_left(tdb, rec_ptr, &left_ptr, &left_rec); - if (ret != 0) { - return 0; - } - - if (left_rec.magic != TDB_FREE_MAGIC) { - return 0; - } - - /* It's free - expand to include it. */ - - ret = tdb->methods->tdb_read(tdb, rec_ptr, &rec, - sizeof(rec), DOCONV()); - if (ret != 0) { - return -1; - } - - ret = merge_with_left_record(tdb, left_ptr, &left_rec, &rec); - if (ret != 0) { - return -1; - } - - if (next_ptr != NULL) { - *next_ptr = rec.next; - } - - return 1; -} - -/** - * Add an element into the freelist. - * - * We merge the new record into the left record if it is also a - * free record, but not with the right one. This makes the - * operation O(1) instead of O(n): merging with the right record - * requires a traverse of the freelist to find the previous - * record in the free list. - * - * This prevents db traverses from being O(n^2) after a lot of deletes. - */ -int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec) -{ - int ret; - - /* Allocation and tailer lock */ - if (tdb_lock(tdb, -1, F_WRLCK) != 0) - return -1; - - /* set an initial tailer, so if we fail we don't leave a bogus record */ - if (update_tailer(tdb, offset, rec) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed!\n")); - goto fail; - } - - ret = check_merge_with_left_record(tdb, offset, rec, NULL, NULL); - if (ret == -1) { - goto fail; - } - if (ret == 1) { - /* merged */ - goto done; - } - - /* Nothing to merge, prepend to free list */ - - rec->magic = TDB_FREE_MAGIC; - - if (tdb_ofs_read(tdb, FREELIST_TOP, &rec->next) == -1 || - tdb_rec_write(tdb, offset, rec) == -1 || - tdb_ofs_write(tdb, FREELIST_TOP, &offset) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free record write failed at offset=%u\n", offset)); - goto fail; - } - -done: - /* And we're done. */ - tdb_unlock(tdb, -1, F_WRLCK); - return 0; - - fail: - tdb_unlock(tdb, -1, F_WRLCK); - return -1; -} - - - -/* - the core of tdb_allocate - called when we have decided which - free list entry to use - - Note that we try to allocate by grabbing data from the end of an existing record, - not the beginning. This is so the left merge in a free is more likely to be - able to free up the record without fragmentation - */ -static tdb_off_t tdb_allocate_ofs(struct tdb_context *tdb, - tdb_len_t length, tdb_off_t rec_ptr, - struct tdb_record *rec, tdb_off_t last_ptr) -{ -#define MIN_REC_SIZE (sizeof(struct tdb_record) + sizeof(tdb_off_t) + 8) - - if (rec->rec_len < length + MIN_REC_SIZE) { - /* we have to grab the whole record */ - - /* unlink it from the previous record */ - if (tdb_ofs_write(tdb, last_ptr, &rec->next) == -1) { - return 0; - } - - /* mark it not free */ - rec->magic = TDB_MAGIC; - if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { - return 0; - } - return rec_ptr; - } - - /* we're going to just shorten the existing record */ - rec->rec_len -= (length + sizeof(*rec)); - if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { - return 0; - } - if (update_tailer(tdb, rec_ptr, rec) == -1) { - return 0; - } - - /* and setup the new record */ - rec_ptr += sizeof(*rec) + rec->rec_len; - - memset(rec, '\0', sizeof(*rec)); - rec->rec_len = length; - rec->magic = TDB_MAGIC; - - if (tdb_rec_write(tdb, rec_ptr, rec) == -1) { - return 0; - } - - if (update_tailer(tdb, rec_ptr, rec) == -1) { - return 0; - } - - return rec_ptr; -} - -/* allocate some space from the free list. The offset returned points - to a unconnected tdb_record within the database with room for at - least length bytes of total data - - 0 is returned if the space could not be allocated - */ -static tdb_off_t tdb_allocate_from_freelist( - struct tdb_context *tdb, tdb_len_t length, struct tdb_record *rec) -{ - tdb_off_t rec_ptr, last_ptr, newrec_ptr; - struct tdb_chainwalk_ctx chainwalk; - bool modified; - struct { - tdb_off_t rec_ptr, last_ptr; - tdb_len_t rec_len; - } bestfit; - float multiplier = 1.0; - bool merge_created_candidate; - - /* over-allocate to reduce fragmentation */ - length *= 1.25; - - /* Extra bytes required for tailer */ - length += sizeof(tdb_off_t); - length = TDB_ALIGN(length, TDB_ALIGNMENT); - - again: - merge_created_candidate = false; - last_ptr = FREELIST_TOP; - - /* read in the freelist top */ - if (tdb_ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) - return 0; - - modified = false; - tdb_chainwalk_init(&chainwalk, rec_ptr); - - bestfit.rec_ptr = 0; - bestfit.last_ptr = 0; - bestfit.rec_len = 0; - - /* - this is a best fit allocation strategy. Originally we used - a first fit strategy, but it suffered from massive fragmentation - issues when faced with a slowly increasing record size. - */ - while (rec_ptr) { - int ret; - tdb_off_t left_ptr; - struct tdb_record left_rec; - - if (tdb_rec_free_read(tdb, rec_ptr, rec) == -1) { - return 0; - } - - ret = check_merge_with_left_record(tdb, rec_ptr, rec, - &left_ptr, &left_rec); - if (ret == -1) { - return 0; - } - if (ret == 1) { - /* merged */ - rec_ptr = rec->next; - ret = tdb_ofs_write(tdb, last_ptr, &rec->next); - if (ret == -1) { - return 0; - } - - /* - * We have merged the current record into the left - * neighbour. So our traverse of the freelist will - * skip it and consider the next record in the chain. - * - * But the enlarged left neighbour may be a candidate. - * If it is, we can not directly use it, though. - * The only thing we can do and have to do here is to - * update the current best fit size in the chain if the - * current best fit is the left record. (By that we may - * worsen the best fit we already had, bit this is not a - * problem.) - * - * If the current best fit is not the left record, - * all we can do is remember the fact that a merge - * created a new candidate so that we can trigger - * a second walk of the freelist if at the end of - * the first walk we have not found any fit. - * This way we can avoid expanding the database. - */ - - if (bestfit.rec_ptr == left_ptr) { - bestfit.rec_len = left_rec.rec_len; - } - - if (left_rec.rec_len > length) { - merge_created_candidate = true; - } - - modified = true; - - continue; - } - - if (rec->rec_len >= length) { - if (bestfit.rec_ptr == 0 || - rec->rec_len < bestfit.rec_len) { - bestfit.rec_len = rec->rec_len; - bestfit.rec_ptr = rec_ptr; - bestfit.last_ptr = last_ptr; - } - } - - /* move to the next record */ - last_ptr = rec_ptr; - rec_ptr = rec->next; - - if (!modified) { - bool ok; - ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); - if (!ok) { - return 0; - } - } - - /* if we've found a record that is big enough, then - stop searching if its also not too big. The - definition of 'too big' changes as we scan - through */ - if (bestfit.rec_len > 0 && - bestfit.rec_len < length * multiplier) { - break; - } - - /* this multiplier means we only extremely rarely - search more than 50 or so records. At 50 records we - accept records up to 11 times larger than what we - want */ - multiplier *= 1.05; - } - - if (bestfit.rec_ptr != 0) { - if (tdb_rec_free_read(tdb, bestfit.rec_ptr, rec) == -1) { - return 0; - } - - newrec_ptr = tdb_allocate_ofs(tdb, length, bestfit.rec_ptr, - rec, bestfit.last_ptr); - return newrec_ptr; - } - - if (merge_created_candidate) { - goto again; - } - - /* we didn't find enough space. See if we can expand the - database and if we can then try again */ - if (tdb_expand(tdb, length + sizeof(*rec)) == 0) - goto again; - - return 0; -} - -static bool tdb_alloc_dead( - struct tdb_context *tdb, int hash, tdb_len_t length, - tdb_off_t *rec_ptr, struct tdb_record *rec) -{ - tdb_off_t last_ptr; - - *rec_ptr = tdb_find_dead(tdb, hash, rec, length, &last_ptr); - if (*rec_ptr == 0) { - return false; - } - /* - * Unlink the record from the hash chain, it's about to be moved into - * another one. - */ - return (tdb_ofs_write(tdb, last_ptr, &rec->next) == 0); -} - -static void tdb_purge_dead(struct tdb_context *tdb, uint32_t hash) -{ - int max_dead_records = tdb->max_dead_records; - - tdb->max_dead_records = 0; - - tdb_trim_dead(tdb, hash); - - tdb->max_dead_records = max_dead_records; -} - -/* - * Chain "hash" is assumed to be locked - */ - -tdb_off_t tdb_allocate(struct tdb_context *tdb, int hash, tdb_len_t length, - struct tdb_record *rec) -{ - tdb_off_t ret; - uint32_t i; - - if (tdb->max_dead_records == 0) { - /* - * No dead records to expect anywhere. Do the blocking - * freelist lock without trying to steal from others - */ - goto blocking_freelist_allocate; - } - - /* - * The following loop tries to get the freelist lock nonblocking. If - * it gets the lock, allocate from there. If the freelist is busy, - * instead of waiting we try to steal dead records from other hash - * chains. - * - * Be aware that we do nonblocking locks on the other hash chains as - * well and fail gracefully. This way we avoid deadlocks (we block two - * hash chains, something which is pretty bad normally) - */ - - for (i=0; ihash_size; i++) { - - int list; - - list = BUCKET(hash+i); - - if (tdb_lock_nonblock(tdb, list, F_WRLCK) == 0) { - bool got_dead; - - got_dead = tdb_alloc_dead(tdb, list, length, &ret, rec); - tdb_unlock(tdb, list, F_WRLCK); - - if (got_dead) { - return ret; - } - } - - if (tdb_lock_nonblock(tdb, -1, F_WRLCK) == 0) { - /* - * Under the freelist lock take the chance to give - * back our dead records. - */ - tdb_purge_dead(tdb, hash); - - ret = tdb_allocate_from_freelist(tdb, length, rec); - tdb_unlock(tdb, -1, F_WRLCK); - return ret; - } - } - -blocking_freelist_allocate: - - if (tdb_lock(tdb, -1, F_WRLCK) == -1) { - return 0; - } - /* - * Dead records can happen even if max_dead_records==0, they - * are older than the max_dead_records concept: They happen if - * tdb_delete happens concurrently with a traverse. - */ - tdb_purge_dead(tdb, hash); - ret = tdb_allocate_from_freelist(tdb, length, rec); - tdb_unlock(tdb, -1, F_WRLCK); - return ret; -} - -/** - * Merge adjacent records in the freelist. - */ -static int tdb_freelist_merge_adjacent(struct tdb_context *tdb, - int *count_records, int *count_merged) -{ - tdb_off_t cur, next; - int count = 0; - int merged = 0; - int ret; - - ret = tdb_lock(tdb, -1, F_RDLCK); - if (ret == -1) { - return -1; - } - - cur = FREELIST_TOP; - while (tdb_ofs_read(tdb, cur, &next) == 0 && next != 0) { - tdb_off_t next2; - - count++; - - ret = check_merge_ptr_with_left_record(tdb, next, &next2); - if (ret == -1) { - goto done; - } - if (ret == 1) { - /* - * merged: - * now let cur->next point to next2 instead of next - */ - - ret = tdb_ofs_write(tdb, cur, &next2); - if (ret != 0) { - goto done; - } - - next = next2; - merged++; - } - - cur = next; - } - - if (count_records != NULL) { - *count_records = count; - } - - if (count_merged != NULL) { - *count_merged = merged; - } - - ret = 0; - -done: - tdb_unlock(tdb, -1, F_RDLCK); - return ret; -} - -/** - * return the size of the freelist - no merging done - */ -static int tdb_freelist_size_no_merge(struct tdb_context *tdb) -{ - tdb_off_t ptr; - int count=0; - - if (tdb_lock(tdb, -1, F_RDLCK) == -1) { - return -1; - } - - ptr = FREELIST_TOP; - while (tdb_ofs_read(tdb, ptr, &ptr) == 0 && ptr != 0) { - count++; - } - - tdb_unlock(tdb, -1, F_RDLCK); - return count; -} - -/** - * return the size of the freelist - used to decide if we should repack - * - * As a side effect, adjacent records are merged unless the - * database is read-only, in order to reduce the fragmentation - * without repacking. - */ -_PUBLIC_ int tdb_freelist_size(struct tdb_context *tdb) -{ - - int count = 0; - - if (tdb->read_only) { - count = tdb_freelist_size_no_merge(tdb); - } else { - int ret; - ret = tdb_freelist_merge_adjacent(tdb, &count, NULL); - if (ret != 0) { - return -1; - } - } - - return count; -} diff --git a/ldb-2.0.8/lib/tdb/common/freelistcheck.c b/ldb-2.0.8/lib/tdb/common/freelistcheck.c deleted file mode 100644 index 2f1e6eb..0000000 --- a/ldb-2.0.8/lib/tdb/common/freelistcheck.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Jeremy Allison 2006 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "tdb_private.h" - -/* Check the freelist is good and contains no loops. - Very memory intensive - only do this as a consistency - checker. Heh heh - uses an in memory tdb as the storage - for the "seen" record list. For some reason this strikes - me as extremely clever as I don't have to write another tree - data structure implementation :-). - */ - -static int seen_insert(struct tdb_context *mem_tdb, tdb_off_t rec_ptr) -{ - TDB_DATA key; - - key.dptr = (unsigned char *)&rec_ptr; - key.dsize = sizeof(rec_ptr); - return tdb_store(mem_tdb, key, tdb_null, TDB_INSERT); -} - -_PUBLIC_ int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries) -{ - struct tdb_context *mem_tdb = NULL; - struct tdb_record rec; - tdb_off_t rec_ptr, last_ptr; - int ret = -1; - - *pnum_entries = 0; - - mem_tdb = tdb_open("flval", tdb->hash_size, - TDB_INTERNAL, O_RDWR, 0600); - if (!mem_tdb) { - return -1; - } - - if (tdb_lock(tdb, -1, F_WRLCK) == -1) { - tdb_close(mem_tdb); - return 0; - } - - last_ptr = FREELIST_TOP; - - /* Store the FREELIST_TOP record. */ - if (seen_insert(mem_tdb, last_ptr) == -1) { - tdb->ecode = TDB_ERR_CORRUPT; - ret = -1; - goto fail; - } - - /* read in the freelist top */ - if (tdb_ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) { - goto fail; - } - - while (rec_ptr) { - - /* If we can't store this record (we've seen it - before) then the free list has a loop and must - be corrupt. */ - - if (seen_insert(mem_tdb, rec_ptr)) { - tdb->ecode = TDB_ERR_CORRUPT; - ret = -1; - goto fail; - } - - if (tdb_rec_free_read(tdb, rec_ptr, &rec) == -1) { - goto fail; - } - - /* move to the next record */ - rec_ptr = rec.next; - *pnum_entries += 1; - } - - ret = 0; - - fail: - - tdb_close(mem_tdb); - tdb_unlock(tdb, -1, F_WRLCK); - return ret; -} diff --git a/ldb-2.0.8/lib/tdb/common/hash.c b/ldb-2.0.8/lib/tdb/common/hash.c deleted file mode 100644 index 4de7ba9..0000000 --- a/ldb-2.0.8/lib/tdb/common/hash.c +++ /dev/null @@ -1,345 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Rusty Russell 2010 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ -#include "tdb_private.h" - -/* This is based on the hash algorithm from gdbm */ -unsigned int tdb_old_hash(TDB_DATA *key) -{ - uint32_t value; /* Used to compute the hash value. */ - uint32_t i; /* Used to cycle through random values. */ - - /* Set the initial value from the key size. */ - for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++) - value = (value + (key->dptr[i] << (i*5 % 24))); - - return (1103515243 * value + 12345); -} - -#ifndef WORDS_BIGENDIAN -# define HASH_LITTLE_ENDIAN 1 -# define HASH_BIG_ENDIAN 0 -#else -# define HASH_LITTLE_ENDIAN 0 -# define HASH_BIG_ENDIAN 1 -#endif - -/* -------------------------------------------------------------------------------- -lookup3.c, by Bob Jenkins, May 2006, Public Domain. - -These are functions for producing 32-bit hashes for hash table lookup. -hash_word(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() -are externally useful functions. Routines to test the hash are included -if SELF_TEST is defined. You can use this free for any purpose. It's in -the public domain. It has no warranty. - -You probably want to use hashlittle(). hashlittle() and hashbig() -hash byte arrays. hashlittle() is is faster than hashbig() on -little-endian machines. Intel and AMD are little-endian machines. -On second thought, you probably want hashlittle2(), which is identical to -hashlittle() except it returns two 32-bit hashes for the price of one. -You could implement hashbig2() if you wanted but I haven't bothered here. - -If you want to find a hash of, say, exactly 7 integers, do - a = i1; b = i2; c = i3; - mix(a,b,c); - a += i4; b += i5; c += i6; - mix(a,b,c); - a += i7; - final(a,b,c); -then use c as the hash value. If you have a variable length array of -4-byte integers to hash, use hash_word(). If you have a byte array (like -a character string), use hashlittle(). If you have several byte arrays, or -a mix of things, see the comments above hashlittle(). - -Why is this so big? I read 12 bytes at a time into 3 4-byte integers, -then mix those integers. This is fast (you can do a lot more thorough -mixing with 12*3 instructions on 3 integers than you can with 3 instructions -on 1 byte), but shoehorning those bytes into integers efficiently is messy. -*/ - -#define hashsize(n) ((uint32_t)1<<(n)) -#define hashmask(n) (hashsize(n)-1) -#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) - -/* -------------------------------------------------------------------------------- -mix -- mix 3 32-bit values reversibly. - -This is reversible, so any information in (a,b,c) before mix() is -still in (a,b,c) after mix(). - -If four pairs of (a,b,c) inputs are run through mix(), or through -mix() in reverse, there are at least 32 bits of the output that -are sometimes the same for one pair and different for another pair. -This was tested for: -* pairs that differed by one bit, by two bits, in any combination - of top bits of (a,b,c), or in any combination of bottom bits of - (a,b,c). -* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed - the output delta to a Gray code (a^(a>>1)) so a string of 1's (as - is commonly produced by subtraction) look like a single 1-bit - difference. -* the base values were pseudorandom, all zero but one bit set, or - all zero plus a counter that starts at zero. - -Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that -satisfy this are - 4 6 8 16 19 4 - 9 15 3 18 27 15 - 14 9 3 7 17 3 -Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing -for "differ" defined as + with a one-bit base and a two-bit delta. I -used http://burtleburtle.net/bob/hash/avalanche.html to choose -the operations, constants, and arrangements of the variables. - -This does not achieve avalanche. There are input bits of (a,b,c) -that fail to affect some output bits of (a,b,c), especially of a. The -most thoroughly mixed value is c, but it doesn't really even achieve -avalanche in c. - -This allows some parallelism. Read-after-writes are good at doubling -the number of bits affected, so the goal of mixing pulls in the opposite -direction as the goal of parallelism. I did what I could. Rotates -seem to cost as much as shifts on every machine I could lay my hands -on, and rotates are much kinder to the top and bottom bits, so I used -rotates. -------------------------------------------------------------------------------- -*/ -#define mix(a,b,c) \ -{ \ - a -= c; a ^= rot(c, 4); c += b; \ - b -= a; b ^= rot(a, 6); a += c; \ - c -= b; c ^= rot(b, 8); b += a; \ - a -= c; a ^= rot(c,16); c += b; \ - b -= a; b ^= rot(a,19); a += c; \ - c -= b; c ^= rot(b, 4); b += a; \ -} - -/* -------------------------------------------------------------------------------- -final -- final mixing of 3 32-bit values (a,b,c) into c - -Pairs of (a,b,c) values differing in only a few bits will usually -produce values of c that look totally different. This was tested for -* pairs that differed by one bit, by two bits, in any combination - of top bits of (a,b,c), or in any combination of bottom bits of - (a,b,c). -* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed - the output delta to a Gray code (a^(a>>1)) so a string of 1's (as - is commonly produced by subtraction) look like a single 1-bit - difference. -* the base values were pseudorandom, all zero but one bit set, or - all zero plus a counter that starts at zero. - -These constants passed: - 14 11 25 16 4 14 24 - 12 14 25 16 4 14 24 -and these came close: - 4 8 15 26 3 22 24 - 10 8 15 26 3 22 24 - 11 8 15 26 3 22 24 -------------------------------------------------------------------------------- -*/ -#define final(a,b,c) \ -{ \ - c ^= b; c -= rot(b,14); \ - a ^= c; a -= rot(c,11); \ - b ^= a; b -= rot(a,25); \ - c ^= b; c -= rot(b,16); \ - a ^= c; a -= rot(c,4); \ - b ^= a; b -= rot(a,14); \ - c ^= b; c -= rot(b,24); \ -} - - -/* -------------------------------------------------------------------------------- -hashlittle() -- hash a variable-length key into a 32-bit value - k : the key (the unaligned variable-length array of bytes) - length : the length of the key, counting by bytes - val2 : IN: can be any 4-byte value OUT: second 32 bit hash. -Returns a 32-bit value. Every bit of the key affects every bit of -the return value. Two keys differing by one or two bits will have -totally different hash values. Note that the return value is better -mixed than val2, so use that first. - -The best hash table sizes are powers of 2. There is no need to do -mod a prime (mod is sooo slow!). If you need less than 32 bits, -use a bitmask. For example, if you need only 10 bits, do - h = (h & hashmask(10)); -In which case, the hash table should have hashsize(10) elements. - -If you are hashing n strings (uint8_t **)k, do it like this: - for (i=0, h=0; i 12) - { - a += k[0]; - b += k[1]; - c += k[2]; - mix(a,b,c); - length -= 12; - k += 3; - } - - /*----------------------------- handle the last (probably partial) block */ - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; - case 11: c+=((uint32_t)k8[10])<<16; FALL_THROUGH; - case 10: c+=((uint32_t)k8[9])<<8; FALL_THROUGH; - case 9 : c+=k8[8]; FALL_THROUGH; - case 8 : b+=k[1]; a+=k[0]; break; - case 7 : b+=((uint32_t)k8[6])<<16; FALL_THROUGH; - case 6 : b+=((uint32_t)k8[5])<<8; FALL_THROUGH; - case 5 : b+=k8[4]; FALL_THROUGH; - case 4 : a+=k[0]; break; - case 3 : a+=((uint32_t)k8[2])<<16; FALL_THROUGH; - case 2 : a+=((uint32_t)k8[1])<<8; FALL_THROUGH; - case 1 : a+=k8[0]; break; - case 0 : return c; - } - } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { - const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ - const uint8_t *k8; - - /*--------------- all but last block: aligned reads and different mixing */ - while (length > 12) - { - a += k[0] + (((uint32_t)k[1])<<16); - b += k[2] + (((uint32_t)k[3])<<16); - c += k[4] + (((uint32_t)k[5])<<16); - mix(a,b,c); - length -= 12; - k += 6; - } - - /*----------------------------- handle the last (probably partial) block */ - k8 = (const uint8_t *)k; - switch(length) - { - case 12: c+=k[4]+(((uint32_t)k[5])<<16); - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 11: c+=((uint32_t)k8[10])<<16; FALL_THROUGH; - case 10: c+=k[4]; - b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 9 : c+=k8[8]; FALL_THROUGH; - case 8 : b+=k[2]+(((uint32_t)k[3])<<16); - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 7 : b+=((uint32_t)k8[6])<<16; FALL_THROUGH; - case 6 : b+=k[2]; - a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 5 : b+=k8[4]; FALL_THROUGH; - case 4 : a+=k[0]+(((uint32_t)k[1])<<16); - break; - case 3 : a+=((uint32_t)k8[2])<<16; FALL_THROUGH; - case 2 : a+=k[0]; - break; - case 1 : a+=k8[0]; - break; - case 0 : return c; /* zero length requires no mixing */ - } - - } else { /* need to read the key one byte at a time */ - const uint8_t *k = (const uint8_t *)key; - - /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ - while (length > 12) - { - a += k[0]; - a += ((uint32_t)k[1])<<8; - a += ((uint32_t)k[2])<<16; - a += ((uint32_t)k[3])<<24; - b += k[4]; - b += ((uint32_t)k[5])<<8; - b += ((uint32_t)k[6])<<16; - b += ((uint32_t)k[7])<<24; - c += k[8]; - c += ((uint32_t)k[9])<<8; - c += ((uint32_t)k[10])<<16; - c += ((uint32_t)k[11])<<24; - mix(a,b,c); - length -= 12; - k += 12; - } - - /*-------------------------------- last block: affect all 32 bits of (c) */ - switch(length) - { - case 12: c+=((uint32_t)k[11])<<24; FALL_THROUGH; - case 11: c+=((uint32_t)k[10])<<16; FALL_THROUGH; - case 10: c+=((uint32_t)k[9])<<8; FALL_THROUGH; - case 9 : c+=k[8]; FALL_THROUGH; - case 8 : b+=((uint32_t)k[7])<<24; FALL_THROUGH; - case 7 : b+=((uint32_t)k[6])<<16; FALL_THROUGH; - case 6 : b+=((uint32_t)k[5])<<8; FALL_THROUGH; - case 5 : b+=k[4]; FALL_THROUGH; - case 4 : a+=((uint32_t)k[3])<<24; FALL_THROUGH; - case 3 : a+=((uint32_t)k[2])<<16; FALL_THROUGH; - case 2 : a+=((uint32_t)k[1])<<8; FALL_THROUGH; - case 1 : a+=k[0]; - break; - case 0 : return c; - } - } - - final(a,b,c); - return c; -} - -_PUBLIC_ unsigned int tdb_jenkins_hash(TDB_DATA *key) -{ - return hashlittle(key->dptr, key->dsize); -} diff --git a/ldb-2.0.8/lib/tdb/common/io.c b/ldb-2.0.8/lib/tdb/common/io.c deleted file mode 100644 index 0de0dab..0000000 --- a/ldb-2.0.8/lib/tdb/common/io.c +++ /dev/null @@ -1,806 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - - -#include "tdb_private.h" - -/* - * We prepend the mutex area, so fixup offsets. See mutex.c for details. - * tdb->hdr_ofs is 0 or header.mutex_size. - * - * Note: that we only have the 4GB limit of tdb_off_t for - * tdb->map_size. The file size on disk can be 4GB + tdb->hdr_ofs! - */ - -static bool tdb_adjust_offset(struct tdb_context *tdb, off_t *off) -{ - off_t tmp = tdb->hdr_ofs + *off; - - if ((tmp < tdb->hdr_ofs) || (tmp < *off)) { - errno = EIO; - return false; - } - - *off = tmp; - return true; -} - -static ssize_t tdb_pwrite(struct tdb_context *tdb, const void *buf, - size_t count, off_t offset) -{ - ssize_t ret; - - if (!tdb_adjust_offset(tdb, &offset)) { - return -1; - } - - do { - ret = pwrite(tdb->fd, buf, count, offset); - } while ((ret == -1) && (errno == EINTR)); - - return ret; -} - -static ssize_t tdb_pread(struct tdb_context *tdb, void *buf, - size_t count, off_t offset) -{ - ssize_t ret; - - if (!tdb_adjust_offset(tdb, &offset)) { - return -1; - } - - do { - ret = pread(tdb->fd, buf, count, offset); - } while ((ret == -1) && (errno == EINTR)); - - return ret; -} - -static int tdb_ftruncate(struct tdb_context *tdb, off_t length) -{ - ssize_t ret; - - if (!tdb_adjust_offset(tdb, &length)) { - return -1; - } - - do { - ret = ftruncate(tdb->fd, length); - } while ((ret == -1) && (errno == EINTR)); - - return ret; -} - -#ifdef HAVE_POSIX_FALLOCATE -static int tdb_posix_fallocate(struct tdb_context *tdb, off_t offset, - off_t len) -{ - ssize_t ret; - - if (!tdb_adjust_offset(tdb, &offset)) { - return -1; - } - - do { - ret = posix_fallocate(tdb->fd, offset, len); - } while ((ret == -1) && (errno == EINTR)); - - return ret; -} -#endif - -static int tdb_fstat(struct tdb_context *tdb, struct stat *buf) -{ - int ret; - - ret = fstat(tdb->fd, buf); - if (ret == -1) { - return -1; - } - - if (buf->st_size < tdb->hdr_ofs) { - errno = EIO; - return -1; - } - buf->st_size -= tdb->hdr_ofs; - - return ret; -} - -/* check for an out of bounds access - if it is out of bounds then - see if the database has been expanded by someone else and expand - if necessary -*/ -static int tdb_notrans_oob( - struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe) -{ - struct stat st; - if (len + off < len) { - if (!probe) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob off %u len %u wrap\n", - off, len)); - } - return -1; - } - - /* - * This duplicates functionality from tdb_oob(). Don't remove: - * we still have direct callers of tdb->methods->tdb_oob() - * inside transaction.c. - */ - if (off + len <= tdb->map_size) - return 0; - if (tdb->flags & TDB_INTERNAL) { - if (!probe) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %u beyond internal malloc size %u\n", - (int)(off + len), (int)tdb->map_size)); - } - return -1; - } - - if (tdb_fstat(tdb, &st) == -1) { - tdb->ecode = TDB_ERR_IO; - return -1; - } - - /* Beware >4G files! */ - if ((tdb_off_t)st.st_size != st.st_size) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_oob len %llu too large!\n", - (long long)st.st_size)); - return -1; - } - - /* Unmap, update size, remap. We do this unconditionally, to handle - * the unusual case where the db is truncated. - * - * This can happen to a child using tdb_reopen_all(true) on a - * TDB_CLEAR_IF_FIRST tdb whose parent crashes: the next - * opener will truncate the database. */ - if (tdb_munmap(tdb) == -1) { - tdb->ecode = TDB_ERR_IO; - return -1; - } - tdb->map_size = st.st_size; - if (tdb_mmap(tdb) != 0) { - return -1; - } - - if (st.st_size < (size_t)off + len) { - if (!probe) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_oob len %u beyond eof at %u\n", - (int)(off + len), (int)st.st_size)); - } - return -1; - } - return 0; -} - -/* write a lump of data at a specified offset */ -static int tdb_write(struct tdb_context *tdb, tdb_off_t off, - const void *buf, tdb_len_t len) -{ - if (len == 0) { - return 0; - } - - if (tdb->read_only || tdb->traverse_read) { - tdb->ecode = TDB_ERR_RDONLY; - return -1; - } - - if (tdb_oob(tdb, off, len, 0) != 0) - return -1; - - if (tdb->map_ptr) { - memcpy(off + (char *)tdb->map_ptr, buf, len); - } else { -#ifdef HAVE_INCOHERENT_MMAP - tdb->ecode = TDB_ERR_IO; - return -1; -#else - ssize_t written; - - written = tdb_pwrite(tdb, buf, len, off); - - if ((written != (ssize_t)len) && (written != -1)) { - /* try once more */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_write: wrote only " - "%zi of %u bytes at %u, trying once more\n", - written, len, off)); - written = tdb_pwrite(tdb, (const char *)buf+written, - len-written, off+written); - } - if (written == -1) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_write failed at %u " - "len=%u (%s)\n", off, len, strerror(errno))); - return -1; - } else if (written != (ssize_t)len) { - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_write: failed to " - "write %u bytes at %u in two attempts\n", - len, off)); - return -1; - } -#endif - } - return 0; -} - -/* Endian conversion: we only ever deal with 4 byte quantities */ -void *tdb_convert(void *buf, uint32_t size) -{ - uint32_t i, *p = (uint32_t *)buf; - for (i = 0; i < size / 4; i++) - p[i] = TDB_BYTEREV(p[i]); - return buf; -} - - -/* read a lump of data at a specified offset, maybe convert */ -static int tdb_read(struct tdb_context *tdb, tdb_off_t off, void *buf, - tdb_len_t len, int cv) -{ - if (tdb_oob(tdb, off, len, 0) != 0) { - return -1; - } - - if (tdb->map_ptr) { - memcpy(buf, off + (char *)tdb->map_ptr, len); - } else { -#ifdef HAVE_INCOHERENT_MMAP - tdb->ecode = TDB_ERR_IO; - return -1; -#else - ssize_t ret; - - ret = tdb_pread(tdb, buf, len, off); - if (ret != (ssize_t)len) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_read failed at %u " - "len=%u ret=%zi (%s) map_size=%u\n", - off, len, ret, strerror(errno), - tdb->map_size)); - return -1; - } -#endif - } - if (cv) { - tdb_convert(buf, len); - } - return 0; -} - - - -/* - do an unlocked scan of the hash table heads to find the next non-zero head. The value - will then be confirmed with the lock held -*/ -static void tdb_next_hash_chain(struct tdb_context *tdb, uint32_t *chain) -{ - uint32_t h = *chain; - if (tdb->map_ptr) { - for (;h < tdb->hash_size;h++) { - if (0 != *(uint32_t *)(TDB_HASH_TOP(h) + (unsigned char *)tdb->map_ptr)) { - break; - } - } - } else { - uint32_t off=0; - for (;h < tdb->hash_size;h++) { - if (tdb_ofs_read(tdb, TDB_HASH_TOP(h), &off) != 0 || off != 0) { - break; - } - } - } - (*chain) = h; -} - - -int tdb_munmap(struct tdb_context *tdb) -{ - if (tdb->flags & TDB_INTERNAL) - return 0; - -#ifdef HAVE_MMAP - if (tdb->map_ptr) { - int ret; - - ret = munmap(tdb->map_ptr, tdb->map_size); - if (ret != 0) - return ret; - } -#endif - tdb->map_ptr = NULL; - return 0; -} - -/* If mmap isn't coherent, *everyone* must always mmap. */ -static bool should_mmap(const struct tdb_context *tdb) -{ -#ifdef HAVE_INCOHERENT_MMAP - return true; -#else - return !(tdb->flags & TDB_NOMMAP); -#endif -} - -int tdb_mmap(struct tdb_context *tdb) -{ - if (tdb->flags & TDB_INTERNAL) - return 0; - -#ifdef HAVE_MMAP - if (should_mmap(tdb)) { - tdb->map_ptr = mmap(NULL, tdb->map_size, - PROT_READ|(tdb->read_only? 0:PROT_WRITE), - MAP_SHARED|MAP_FILE, tdb->fd, - tdb->hdr_ofs); - - /* - * NB. When mmap fails it returns MAP_FAILED *NOT* NULL !!!! - */ - - if (tdb->map_ptr == MAP_FAILED) { - tdb->map_ptr = NULL; - TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_mmap failed for size %u (%s)\n", - tdb->map_size, strerror(errno))); -#ifdef HAVE_INCOHERENT_MMAP - tdb->ecode = TDB_ERR_IO; - return -1; -#endif - } - } else { - tdb->map_ptr = NULL; - } -#else - tdb->map_ptr = NULL; -#endif - return 0; -} - -/* expand a file. we prefer to use ftruncate, as that is what posix - says to use for mmap expansion */ -static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t addition) -{ - char buf[8192]; - tdb_off_t new_size; - int ret; - - if (tdb->read_only || tdb->traverse_read) { - tdb->ecode = TDB_ERR_RDONLY; - return -1; - } - - if (!tdb_add_off_t(size, addition, &new_size)) { - tdb->ecode = TDB_ERR_OOM; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write " - "overflow detected current size[%u] addition[%u]!\n", - (unsigned)size, (unsigned)addition)); - errno = ENOSPC; - return -1; - } - -#ifdef HAVE_POSIX_FALLOCATE - ret = tdb_posix_fallocate(tdb, size, addition); - if (ret == 0) { - return 0; - } - if (ret == ENOSPC) { - /* - * The Linux glibc (at least as of 2.24) fallback if - * the file system does not support fallocate does not - * reset the file size back to where it was. Also, to - * me it is unclear from the posix spec of - * posix_fallocate whether this is allowed or - * not. Better be safe than sorry and "goto fail" but - * "return -1" here, leaving the EOF pointer too - * large. - */ - goto fail; - } - - /* - * Retry the "old" way. Possibly unnecessary, but looking at - * our configure script there seem to be weird failure modes - * for posix_fallocate. See commit 3264a98ff16de, which - * probably refers to - * https://sourceware.org/bugzilla/show_bug.cgi?id=1083. - */ -#endif - - ret = tdb_ftruncate(tdb, new_size); - if (ret == -1) { - char b = 0; - ssize_t written = tdb_pwrite(tdb, &b, 1, new_size - 1); - if (written == 0) { - /* try once more, potentially revealing errno */ - written = tdb_pwrite(tdb, &b, 1, new_size - 1); - } - if (written == 0) { - /* again - give up, guessing errno */ - errno = ENOSPC; - } - if (written != 1) { - tdb->ecode = TDB_ERR_OOM; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file to %u failed (%s)\n", - (unsigned)new_size, strerror(errno))); - return -1; - } - } - - /* now fill the file with something. This ensures that the - file isn't sparse, which would be very bad if we ran out of - disk. This must be done with write, not via mmap */ - memset(buf, TDB_PAD_BYTE, sizeof(buf)); - while (addition) { - size_t n = addition>sizeof(buf)?sizeof(buf):addition; - ssize_t written = tdb_pwrite(tdb, buf, n, size); - if (written == 0) { - /* prevent infinite loops: try _once_ more */ - written = tdb_pwrite(tdb, buf, n, size); - } - if (written == 0) { - /* give up, trying to provide a useful errno */ - tdb->ecode = TDB_ERR_OOM; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write " - "returned 0 twice: giving up!\n")); - errno = ENOSPC; - goto fail; - } - if (written == -1) { - tdb->ecode = TDB_ERR_OOM; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write of " - "%u bytes failed (%s)\n", (int)n, - strerror(errno))); - goto fail; - } - if (written != n) { - TDB_LOG((tdb, TDB_DEBUG_WARNING, "expand_file: wrote " - "only %zu of %zi bytes - retrying\n", written, - n)); - } - addition -= written; - size += written; - } - return 0; - -fail: - { - int err = errno; - - /* - * We're holding the freelist lock or are inside a - * transaction. Cutting the file is safe, the space we - * tried to allocate can't have been used anywhere in - * the meantime. - */ - - ret = tdb_ftruncate(tdb, size); - if (ret == -1) { - TDB_LOG((tdb, TDB_DEBUG_WARNING, "expand_file: " - "retruncate to %ju failed\n", - (uintmax_t)size)); - } - errno = err; - } - - return -1; -} - - -/* You need 'size', this tells you how much you should expand by. */ -tdb_off_t tdb_expand_adjust(tdb_off_t map_size, tdb_off_t size, int page_size) -{ - tdb_off_t new_size, top_size, increment; - tdb_off_t max_size = UINT32_MAX - map_size; - - if (size > max_size) { - /* - * We can't round up anymore, just give back - * what we're asked for. - * - * The caller has to take care of the ENOSPC handling. - */ - return size; - } - - /* limit size in order to avoid using up huge amounts of memory for - * in memory tdbs if an oddball huge record creeps in */ - if (size > 100 * 1024) { - increment = size * 2; - } else { - increment = size * 100; - } - if (increment < size) { - goto overflow; - } - - if (!tdb_add_off_t(map_size, increment, &top_size)) { - goto overflow; - } - - /* always make room for at least top_size more records, and at - least 25% more space. if the DB is smaller than 100MiB, - otherwise grow it by 10% only. */ - if (map_size > 100 * 1024 * 1024) { - new_size = map_size * 1.10; - } else { - new_size = map_size * 1.25; - } - if (new_size < map_size) { - goto overflow; - } - - /* Round the database up to a multiple of the page size */ - new_size = MAX(top_size, new_size); - - if (new_size + page_size < new_size) { - /* There's a "+" in TDB_ALIGN that might overflow... */ - goto overflow; - } - - return TDB_ALIGN(new_size, page_size) - map_size; - -overflow: - /* - * Somewhere in between we went over 4GB. Make one big jump to - * exactly 4GB database size. - */ - return max_size; -} - -/* expand the database at least size bytes by expanding the underlying - file and doing the mmap again if necessary */ -int tdb_expand(struct tdb_context *tdb, tdb_off_t size) -{ - struct tdb_record rec; - tdb_off_t offset; - tdb_off_t new_size; - - if (tdb_lock(tdb, -1, F_WRLCK) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "lock failed in tdb_expand\n")); - return -1; - } - - /* must know about any previous expansions by another process */ - tdb_oob(tdb, tdb->map_size, 1, 1); - - /* - * Note: that we don't care about tdb->hdr_ofs != 0 here - * - * The 4GB limitation is just related to tdb->map_size - * and the offset calculation in the records. - * - * The file on disk can be up to 4GB + tdb->hdr_ofs - */ - size = tdb_expand_adjust(tdb->map_size, size, tdb->page_size); - - if (!tdb_add_off_t(tdb->map_size, size, &new_size)) { - tdb->ecode = TDB_ERR_OOM; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_expand " - "overflow detected current map_size[%u] size[%u]!\n", - (unsigned)tdb->map_size, (unsigned)size)); - goto fail; - } - - /* form a new freelist record */ - offset = tdb->map_size; - memset(&rec,'\0',sizeof(rec)); - rec.rec_len = size - sizeof(rec); - - if (tdb->flags & TDB_INTERNAL) { - char *new_map_ptr; - - new_map_ptr = (char *)realloc(tdb->map_ptr, new_size); - if (!new_map_ptr) { - tdb->ecode = TDB_ERR_OOM; - goto fail; - } - tdb->map_ptr = new_map_ptr; - tdb->map_size = new_size; - } else { - int ret; - - /* - * expand the file itself - */ - ret = tdb->methods->tdb_expand_file(tdb, tdb->map_size, size); - if (ret != 0) { - goto fail; - } - - /* Explicitly remap: if we're in a transaction, this won't - * happen automatically! */ - tdb_munmap(tdb); - tdb->map_size = new_size; - if (tdb_mmap(tdb) != 0) { - goto fail; - } - } - - /* link it into the free list */ - if (tdb_free(tdb, offset, &rec) == -1) - goto fail; - - tdb_unlock(tdb, -1, F_WRLCK); - return 0; - fail: - tdb_unlock(tdb, -1, F_WRLCK); - return -1; -} - -int _tdb_oob(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe) -{ - int ret = tdb->methods->tdb_oob(tdb, off, len, probe); - return ret; -} - -/* read/write a tdb_off_t */ -int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d) -{ - return tdb->methods->tdb_read(tdb, offset, (char*)d, sizeof(*d), DOCONV()); -} - -int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d) -{ - tdb_off_t off = *d; - return tdb->methods->tdb_write(tdb, offset, CONVERT(off), sizeof(*d)); -} - - -/* read a lump of data, allocating the space for it */ -unsigned char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len) -{ - unsigned char *buf; - - /* some systems don't like zero length malloc */ - - if (!(buf = (unsigned char *)malloc(len ? len : 1))) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_OOM; - TDB_LOG((tdb, TDB_DEBUG_ERROR,"tdb_alloc_read malloc failed len=%u (%s)\n", - len, strerror(errno))); - return NULL; - } - if (tdb->methods->tdb_read(tdb, offset, buf, len, 0) == -1) { - SAFE_FREE(buf); - return NULL; - } - return buf; -} - -/* Give a piece of tdb data to a parser */ - -int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key, - tdb_off_t offset, tdb_len_t len, - int (*parser)(TDB_DATA key, TDB_DATA data, - void *private_data), - void *private_data) -{ - TDB_DATA data; - int result; - - data.dsize = len; - - if ((tdb->transaction == NULL) && (tdb->map_ptr != NULL)) { - /* - * Optimize by avoiding the malloc/memcpy/free, point the - * parser directly at the mmap area. - */ - if (tdb_oob(tdb, offset, len, 0) != 0) { - return -1; - } - data.dptr = offset + (unsigned char *)tdb->map_ptr; - return parser(key, data, private_data); - } - - if (!(data.dptr = tdb_alloc_read(tdb, offset, len))) { - return -1; - } - - result = parser(key, data, private_data); - free(data.dptr); - return result; -} - -/* read/write a record */ -int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec) -{ - int ret; - tdb_len_t overall_len; - - if (tdb->methods->tdb_read(tdb, offset, rec, sizeof(*rec),DOCONV()) == -1) - return -1; - if (TDB_BAD_MAGIC(rec)) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_CORRUPT; - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_rec_read bad magic 0x%x at offset=%u\n", rec->magic, offset)); - return -1; - } - - overall_len = rec->key_len + rec->data_len; - if (overall_len < rec->data_len) { - /* overflow */ - return -1; - } - - if (overall_len > rec->rec_len) { - /* invalid record */ - return -1; - } - - ret = tdb_oob(tdb, offset, rec->key_len, 1); - if (ret == -1) { - return -1; - } - ret = tdb_oob(tdb, offset, rec->data_len, 1); - if (ret == -1) { - return -1; - } - ret = tdb_oob(tdb, offset, rec->rec_len, 1); - if (ret == -1) { - return -1; - } - - return tdb_oob(tdb, rec->next, sizeof(*rec), 0); -} - -int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec) -{ - struct tdb_record r = *rec; - return tdb->methods->tdb_write(tdb, offset, CONVERT(r), sizeof(r)); -} - -static const struct tdb_methods io_methods = { - tdb_read, - tdb_write, - tdb_next_hash_chain, - tdb_notrans_oob, - tdb_expand_file, -}; - -/* - initialise the default methods table -*/ -void tdb_io_init(struct tdb_context *tdb) -{ - tdb->methods = &io_methods; -} diff --git a/ldb-2.0.8/lib/tdb/common/lock.c b/ldb-2.0.8/lib/tdb/common/lock.c deleted file mode 100644 index 5fba02f..0000000 --- a/ldb-2.0.8/lib/tdb/common/lock.c +++ /dev/null @@ -1,1031 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "tdb_private.h" - -_PUBLIC_ void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *ptr) -{ - tdb->interrupt_sig_ptr = ptr; -} - -static int fcntl_lock(struct tdb_context *tdb, - int rw, off_t off, off_t len, bool waitflag) -{ - struct flock fl; - int cmd; - -#ifdef USE_TDB_MUTEX_LOCKING - { - int ret; - if (tdb_mutex_lock(tdb, rw, off, len, waitflag, &ret)) { - return ret; - } - } -#endif - - fl.l_type = rw; - fl.l_whence = SEEK_SET; - fl.l_start = off; - fl.l_len = len; - fl.l_pid = 0; - - cmd = waitflag ? F_SETLKW : F_SETLK; - - return fcntl(tdb->fd, cmd, &fl); -} - -static int fcntl_unlock(struct tdb_context *tdb, int rw, off_t off, off_t len) -{ - struct flock fl; -#if 0 /* Check they matched up locks and unlocks correctly. */ - char line[80]; - FILE *locks; - bool found = false; - - locks = fopen("/proc/locks", "r"); - - while (fgets(line, 80, locks)) { - char *p; - int type, start, l; - - /* eg. 1: FLOCK ADVISORY WRITE 2440 08:01:2180826 0 EOF */ - p = strchr(line, ':') + 1; - if (strncmp(p, " POSIX ADVISORY ", strlen(" POSIX ADVISORY "))) - continue; - p += strlen(" FLOCK ADVISORY "); - if (strncmp(p, "READ ", strlen("READ ")) == 0) - type = F_RDLCK; - else if (strncmp(p, "WRITE ", strlen("WRITE ")) == 0) - type = F_WRLCK; - else - abort(); - p += 6; - if (atoi(p) != getpid()) - continue; - p = strchr(strchr(p, ' ') + 1, ' ') + 1; - start = atoi(p); - p = strchr(p, ' ') + 1; - if (strncmp(p, "EOF", 3) == 0) - l = 0; - else - l = atoi(p) - start + 1; - - if (off == start) { - if (len != l) { - fprintf(stderr, "Len %u should be %u: %s", - (int)len, l, line); - abort(); - } - if (type != rw) { - fprintf(stderr, "Type %s wrong: %s", - rw == F_RDLCK ? "READ" : "WRITE", line); - abort(); - } - found = true; - break; - } - } - - if (!found) { - fprintf(stderr, "Unlock on %u@%u not found!\n", - (int)off, (int)len); - abort(); - } - - fclose(locks); -#endif - -#ifdef USE_TDB_MUTEX_LOCKING - { - int ret; - if (tdb_mutex_unlock(tdb, rw, off, len, &ret)) { - return ret; - } - } -#endif - - fl.l_type = F_UNLCK; - fl.l_whence = SEEK_SET; - fl.l_start = off; - fl.l_len = len; - fl.l_pid = 0; - - return fcntl(tdb->fd, F_SETLKW, &fl); -} - -/* - * Calculate the lock offset for a list - * - * list -1 is the freelist, otherwise a hash chain. - * - * Note that we consistently (but without real reason) lock hash chains at an - * offset that is 4 bytes below the real offset of the corresponding list head - * in the db. - * - * This is the memory layout of the hashchain array: - * - * FREELIST_TOP + 0 = freelist - * FREELIST_TOP + 4 = hashtable list 0 - * FREELIST_TOP + 8 = hashtable list 1 - * ... - * - * Otoh lock_offset computes: - * - * freelist = FREELIST_TOP - 4 - * list 0 = FREELIST_TOP + 0 - * list 1 = FREELIST_TOP + 4 - * ... - * - * Unfortunately we can't change this calculation in order to align the locking - * offset with the memory layout, as that would make the locking incompatible - * between different tdb versions. - */ -static tdb_off_t lock_offset(int list) -{ - return FREELIST_TOP + 4*list; -} - -/* a byte range locking function - return 0 on success - this functions locks/unlocks "len" byte at the specified offset. - - On error, errno is also set so that errors are passed back properly - through tdb_open(). - - note that a len of zero means lock to end of file -*/ -int tdb_brlock(struct tdb_context *tdb, - int rw_type, tdb_off_t offset, size_t len, - enum tdb_lock_flags flags) -{ - int ret; - - if (tdb->flags & TDB_NOLOCK) { - return 0; - } - - if (flags & TDB_LOCK_MARK_ONLY) { - return 0; - } - - if ((rw_type == F_WRLCK) && (tdb->read_only || tdb->traverse_read)) { - tdb->ecode = TDB_ERR_RDONLY; - return -1; - } - - do { - ret = fcntl_lock(tdb, rw_type, offset, len, - flags & TDB_LOCK_WAIT); - /* Check for a sigalarm break. */ - if (ret == -1 && errno == EINTR && - tdb->interrupt_sig_ptr && - *tdb->interrupt_sig_ptr) { - break; - } - } while (ret == -1 && errno == EINTR); - - if (ret == -1) { - tdb->ecode = TDB_ERR_LOCK; - /* Generic lock error. errno set by fcntl. - * EAGAIN is an expected return from non-blocking - * locks. */ - if (!(flags & TDB_LOCK_PROBE) && errno != EAGAIN) { - TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock failed (fd=%d) at offset %u rw_type=%d flags=%d len=%zu\n", - tdb->fd, offset, rw_type, flags, len)); - } - return -1; - } - return 0; -} - -int tdb_brunlock(struct tdb_context *tdb, - int rw_type, tdb_off_t offset, size_t len) -{ - int ret; - - if (tdb->flags & TDB_NOLOCK) { - return 0; - } - - do { - ret = fcntl_unlock(tdb, rw_type, offset, len); - } while (ret == -1 && errno == EINTR); - - if (ret == -1) { - TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brunlock failed (fd=%d) at offset %u rw_type=%u len=%zu\n", - tdb->fd, offset, rw_type, len)); - } - return ret; -} - -/* - * Do a tdb_brlock in a loop. Some OSes (such as solaris) have too - * conservative deadlock detection and claim a deadlock when progress can be - * made. For those OSes we may loop for a while. - */ - -static int tdb_brlock_retry(struct tdb_context *tdb, - int rw_type, tdb_off_t offset, size_t len, - enum tdb_lock_flags flags) -{ - int count = 1000; - - while (count--) { - struct timeval tv; - int ret; - - ret = tdb_brlock(tdb, rw_type, offset, len, flags); - if (ret == 0) { - return 0; - } - if (errno != EDEADLK) { - break; - } - /* sleep for as short a time as we can - more portable than usleep() */ - tv.tv_sec = 0; - tv.tv_usec = 1; - select(0, NULL, NULL, NULL, &tv); - } - return -1; -} - -/* - upgrade a read lock to a write lock. -*/ -int tdb_allrecord_upgrade(struct tdb_context *tdb) -{ - int ret; - - if (tdb->allrecord_lock.count != 1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "tdb_allrecord_upgrade failed: count %u too high\n", - tdb->allrecord_lock.count)); - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - - if (tdb->allrecord_lock.off != 1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "tdb_allrecord_upgrade failed: already upgraded?\n")); - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - - if (tdb_have_mutexes(tdb)) { - ret = tdb_mutex_allrecord_upgrade(tdb); - if (ret == -1) { - goto fail; - } - ret = tdb_brlock_retry(tdb, F_WRLCK, lock_offset(tdb->hash_size), - 0, TDB_LOCK_WAIT|TDB_LOCK_PROBE); - if (ret == -1) { - tdb_mutex_allrecord_downgrade(tdb); - } - } else { - ret = tdb_brlock_retry(tdb, F_WRLCK, FREELIST_TOP, 0, - TDB_LOCK_WAIT|TDB_LOCK_PROBE); - } - - if (ret == 0) { - tdb->allrecord_lock.ltype = F_WRLCK; - tdb->allrecord_lock.off = 0; - return 0; - } -fail: - TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_allrecord_upgrade failed\n")); - return -1; -} - -static struct tdb_lock_type *find_nestlock(struct tdb_context *tdb, - tdb_off_t offset) -{ - int i; - - for (i=0; inum_lockrecs; i++) { - if (tdb->lockrecs[i].off == offset) { - return &tdb->lockrecs[i]; - } - } - return NULL; -} - -/* lock an offset in the database. */ -int tdb_nest_lock(struct tdb_context *tdb, uint32_t offset, int ltype, - enum tdb_lock_flags flags) -{ - struct tdb_lock_type *new_lck; - - if (offset >= lock_offset(tdb->hash_size)) { - tdb->ecode = TDB_ERR_LOCK; - TDB_LOG((tdb, TDB_DEBUG_ERROR,"tdb_lock: invalid offset %u for ltype=%d\n", - offset, ltype)); - return -1; - } - if (tdb->flags & TDB_NOLOCK) - return 0; - - new_lck = find_nestlock(tdb, offset); - if (new_lck) { - if ((new_lck->ltype == F_RDLCK) && (ltype == F_WRLCK)) { - if (!tdb_have_mutexes(tdb)) { - int ret; - /* - * Upgrade the underlying fcntl - * lock. Mutexes don't do readlocks, - * so this only applies to fcntl - * locking. - */ - ret = tdb_brlock(tdb, ltype, offset, 1, flags); - if (ret != 0) { - return ret; - } - } - new_lck->ltype = F_WRLCK; - } - /* - * Just increment the in-memory struct, posix locks - * don't stack. - */ - new_lck->count++; - return 0; - } - - if (tdb->num_lockrecs == tdb->lockrecs_array_length) { - new_lck = (struct tdb_lock_type *)realloc( - tdb->lockrecs, - sizeof(*tdb->lockrecs) * (tdb->num_lockrecs+1)); - if (new_lck == NULL) { - errno = ENOMEM; - return -1; - } - tdb->lockrecs_array_length = tdb->num_lockrecs+1; - tdb->lockrecs = new_lck; - } - - /* Since fcntl locks don't nest, we do a lock for the first one, - and simply bump the count for future ones */ - if (tdb_brlock(tdb, ltype, offset, 1, flags)) { - return -1; - } - - new_lck = &tdb->lockrecs[tdb->num_lockrecs]; - - new_lck->off = offset; - new_lck->count = 1; - new_lck->ltype = ltype; - tdb->num_lockrecs++; - - return 0; -} - -static int tdb_lock_and_recover(struct tdb_context *tdb) -{ - int ret; - - /* We need to match locking order in transaction commit. */ - if (tdb_brlock(tdb, F_WRLCK, FREELIST_TOP, 0, TDB_LOCK_WAIT)) { - return -1; - } - - if (tdb_brlock(tdb, F_WRLCK, OPEN_LOCK, 1, TDB_LOCK_WAIT)) { - tdb_brunlock(tdb, F_WRLCK, FREELIST_TOP, 0); - return -1; - } - - ret = tdb_transaction_recover(tdb); - - tdb_brunlock(tdb, F_WRLCK, OPEN_LOCK, 1); - tdb_brunlock(tdb, F_WRLCK, FREELIST_TOP, 0); - - return ret; -} - -static bool have_data_locks(const struct tdb_context *tdb) -{ - int i; - - for (i = 0; i < tdb->num_lockrecs; i++) { - if (tdb->lockrecs[i].off >= lock_offset(-1)) - return true; - } - return false; -} - -/* - * A allrecord lock allows us to avoid per chain locks. Check if the allrecord - * lock is strong enough. - */ -static int tdb_lock_covered_by_allrecord_lock(struct tdb_context *tdb, - int ltype) -{ - if (ltype == F_RDLCK) { - /* - * The allrecord_lock is equal (F_RDLCK) or stronger - * (F_WRLCK). Pass. - */ - return 0; - } - - if (tdb->allrecord_lock.ltype == F_RDLCK) { - /* - * We ask for ltype==F_WRLCK, but the allrecord_lock - * is too weak. We can't upgrade here, so fail. - */ - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - - /* - * Asking for F_WRLCK, allrecord is F_WRLCK as well. Pass. - */ - return 0; -} - -static int tdb_lock_list(struct tdb_context *tdb, int list, int ltype, - enum tdb_lock_flags waitflag) -{ - int ret; - bool check = false; - - if (tdb->allrecord_lock.count) { - return tdb_lock_covered_by_allrecord_lock(tdb, ltype); - } - - /* - * Check for recoveries: Someone might have kill -9'ed a process - * during a commit. - */ - check = !have_data_locks(tdb); - ret = tdb_nest_lock(tdb, lock_offset(list), ltype, waitflag); - - if (ret == 0 && check && tdb_needs_recovery(tdb)) { - tdb_nest_unlock(tdb, lock_offset(list), ltype, false); - - if (tdb_lock_and_recover(tdb) == -1) { - return -1; - } - return tdb_lock_list(tdb, list, ltype, waitflag); - } - return ret; -} - -/* lock a list in the database. list -1 is the alloc list */ -int tdb_lock(struct tdb_context *tdb, int list, int ltype) -{ - int ret; - - ret = tdb_lock_list(tdb, list, ltype, TDB_LOCK_WAIT); - if (ret) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_lock failed on list %d " - "ltype=%d (%s)\n", list, ltype, strerror(errno))); - } - return ret; -} - -/* lock a list in the database. list -1 is the alloc list. non-blocking lock */ -_PUBLIC_ int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype) -{ - return tdb_lock_list(tdb, list, ltype, TDB_LOCK_NOWAIT); -} - - -int tdb_nest_unlock(struct tdb_context *tdb, uint32_t offset, int ltype, - bool mark_lock) -{ - int ret = -1; - struct tdb_lock_type *lck; - - if (tdb->flags & TDB_NOLOCK) - return 0; - - /* Sanity checks */ - if (offset >= lock_offset(tdb->hash_size)) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: offset %u invalid (%d)\n", offset, tdb->hash_size)); - return ret; - } - - lck = find_nestlock(tdb, offset); - if ((lck == NULL) || (lck->count == 0)) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: count is 0\n")); - return -1; - } - - if (lck->count > 1) { - lck->count--; - return 0; - } - - /* - * This lock has count==1 left, so we need to unlock it in the - * kernel. We don't bother with decrementing the in-memory array - * element, we're about to overwrite it with the last array element - * anyway. - */ - - if (mark_lock) { - ret = 0; - } else { - ret = tdb_brunlock(tdb, ltype, offset, 1); - } - - /* - * Shrink the array by overwriting the element just unlocked with the - * last array element. - */ - *lck = tdb->lockrecs[--tdb->num_lockrecs]; - - /* - * We don't bother with realloc when the array shrinks, but if we have - * a completely idle tdb we should get rid of the locked array. - */ - - if (ret) - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlock: An error occurred unlocking!\n")); - return ret; -} - -_PUBLIC_ int tdb_unlock(struct tdb_context *tdb, int list, int ltype) -{ - /* a global lock allows us to avoid per chain locks */ - if (tdb->allrecord_lock.count) { - return tdb_lock_covered_by_allrecord_lock(tdb, ltype); - } - - return tdb_nest_unlock(tdb, lock_offset(list), ltype, false); -} - -/* - get the transaction lock - */ -int tdb_transaction_lock(struct tdb_context *tdb, int ltype, - enum tdb_lock_flags lockflags) -{ - return tdb_nest_lock(tdb, TRANSACTION_LOCK, ltype, lockflags); -} - -/* - release the transaction lock - */ -int tdb_transaction_unlock(struct tdb_context *tdb, int ltype) -{ - return tdb_nest_unlock(tdb, TRANSACTION_LOCK, ltype, false); -} - -/* Returns 0 if all done, -1 if error, 1 if ok. */ -static int tdb_allrecord_check(struct tdb_context *tdb, int ltype, - enum tdb_lock_flags flags, bool upgradable) -{ - /* There are no locks on read-only dbs */ - if (tdb->read_only || tdb->traverse_read) { - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - - if (tdb->allrecord_lock.count && - tdb->allrecord_lock.ltype == (uint32_t)ltype) { - tdb->allrecord_lock.count++; - return 0; - } - - if (tdb->allrecord_lock.count) { - /* a global lock of a different type exists */ - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - - if (tdb_have_extra_locks(tdb)) { - /* can't combine global and chain locks */ - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - - if (upgradable && ltype != F_RDLCK) { - /* tdb error: you can't upgrade a write lock! */ - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - return 1; -} - -/* We only need to lock individual bytes, but Linux merges consecutive locks - * so we lock in contiguous ranges. */ -static int tdb_chainlock_gradual(struct tdb_context *tdb, - int ltype, enum tdb_lock_flags flags, - size_t off, size_t len) -{ - int ret; - enum tdb_lock_flags nb_flags = (flags & ~TDB_LOCK_WAIT); - - if (len <= 4) { - /* Single record. Just do blocking lock. */ - return tdb_brlock(tdb, ltype, off, len, flags); - } - - /* First we try non-blocking. */ - ret = tdb_brlock(tdb, ltype, off, len, nb_flags); - if (ret == 0) { - return 0; - } - - /* Try locking first half, then second. */ - ret = tdb_chainlock_gradual(tdb, ltype, flags, off, len / 2); - if (ret == -1) - return -1; - - ret = tdb_chainlock_gradual(tdb, ltype, flags, - off + len / 2, len - len / 2); - if (ret == -1) { - tdb_brunlock(tdb, ltype, off, len / 2); - return -1; - } - return 0; -} - -/* lock/unlock entire database. It can only be upgradable if you have some - * other way of guaranteeing exclusivity (ie. transaction write lock). - * We do the locking gradually to avoid being starved by smaller locks. */ -int tdb_allrecord_lock(struct tdb_context *tdb, int ltype, - enum tdb_lock_flags flags, bool upgradable) -{ - int ret; - - switch (tdb_allrecord_check(tdb, ltype, flags, upgradable)) { - case -1: - return -1; - case 0: - return 0; - } - - /* We cover two kinds of locks: - * 1) Normal chain locks. Taken for almost all operations. - * 2) Individual records locks. Taken after normal or free - * chain locks. - * - * It is (1) which cause the starvation problem, so we're only - * gradual for that. */ - - if (tdb_have_mutexes(tdb)) { - ret = tdb_mutex_allrecord_lock(tdb, ltype, flags); - } else { - ret = tdb_chainlock_gradual(tdb, ltype, flags, FREELIST_TOP, - tdb->hash_size * 4); - } - - if (ret == -1) { - return -1; - } - - /* Grab individual record locks. */ - if (tdb_brlock(tdb, ltype, lock_offset(tdb->hash_size), 0, - flags) == -1) { - if (tdb_have_mutexes(tdb)) { - tdb_mutex_allrecord_unlock(tdb); - } else { - tdb_brunlock(tdb, ltype, FREELIST_TOP, - tdb->hash_size * 4); - } - return -1; - } - - tdb->allrecord_lock.count = 1; - /* If it's upgradable, it's actually exclusive so we can treat - * it as a write lock. */ - tdb->allrecord_lock.ltype = upgradable ? F_WRLCK : ltype; - tdb->allrecord_lock.off = upgradable; - - if (tdb_needs_recovery(tdb)) { - bool mark = flags & TDB_LOCK_MARK_ONLY; - tdb_allrecord_unlock(tdb, ltype, mark); - if (mark) { - tdb->ecode = TDB_ERR_LOCK; - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "tdb_lockall_mark cannot do recovery\n")); - return -1; - } - if (tdb_lock_and_recover(tdb) == -1) { - return -1; - } - return tdb_allrecord_lock(tdb, ltype, flags, upgradable); - } - - return 0; -} - - - -/* unlock entire db */ -int tdb_allrecord_unlock(struct tdb_context *tdb, int ltype, bool mark_lock) -{ - /* There are no locks on read-only dbs */ - if (tdb->read_only || tdb->traverse_read) { - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - - if (tdb->allrecord_lock.count == 0) { - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - - /* Upgradable locks are marked as write locks. */ - if (tdb->allrecord_lock.ltype != (uint32_t)ltype - && (!tdb->allrecord_lock.off || ltype != F_RDLCK)) { - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - - if (tdb->allrecord_lock.count > 1) { - tdb->allrecord_lock.count--; - return 0; - } - - if (!mark_lock) { - int ret; - - if (tdb_have_mutexes(tdb)) { - ret = tdb_mutex_allrecord_unlock(tdb); - if (ret == 0) { - ret = tdb_brunlock(tdb, ltype, - lock_offset(tdb->hash_size), - 0); - } - } else { - ret = tdb_brunlock(tdb, ltype, FREELIST_TOP, 0); - } - - if (ret != 0) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_unlockall failed " - "(%s)\n", strerror(errno))); - return -1; - } - } - - tdb->allrecord_lock.count = 0; - tdb->allrecord_lock.ltype = 0; - - return 0; -} - -/* lock entire database with write lock */ -_PUBLIC_ int tdb_lockall(struct tdb_context *tdb) -{ - tdb_trace(tdb, "tdb_lockall"); - return tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); -} - -/* lock entire database with write lock - mark only */ -_PUBLIC_ int tdb_lockall_mark(struct tdb_context *tdb) -{ - tdb_trace(tdb, "tdb_lockall_mark"); - return tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_MARK_ONLY, false); -} - -/* unlock entire database with write lock - unmark only */ -_PUBLIC_ int tdb_lockall_unmark(struct tdb_context *tdb) -{ - tdb_trace(tdb, "tdb_lockall_unmark"); - return tdb_allrecord_unlock(tdb, F_WRLCK, true); -} - -/* lock entire database with write lock - nonblocking varient */ -_PUBLIC_ int tdb_lockall_nonblock(struct tdb_context *tdb) -{ - int ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_NOWAIT, false); - tdb_trace_ret(tdb, "tdb_lockall_nonblock", ret); - return ret; -} - -/* unlock entire database with write lock */ -_PUBLIC_ int tdb_unlockall(struct tdb_context *tdb) -{ - tdb_trace(tdb, "tdb_unlockall"); - return tdb_allrecord_unlock(tdb, F_WRLCK, false); -} - -/* lock entire database with read lock */ -_PUBLIC_ int tdb_lockall_read(struct tdb_context *tdb) -{ - tdb_trace(tdb, "tdb_lockall_read"); - return tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, false); -} - -/* lock entire database with read lock - nonblock varient */ -_PUBLIC_ int tdb_lockall_read_nonblock(struct tdb_context *tdb) -{ - int ret = tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_NOWAIT, false); - tdb_trace_ret(tdb, "tdb_lockall_read_nonblock", ret); - return ret; -} - -/* unlock entire database with read lock */ -_PUBLIC_ int tdb_unlockall_read(struct tdb_context *tdb) -{ - tdb_trace(tdb, "tdb_unlockall_read"); - return tdb_allrecord_unlock(tdb, F_RDLCK, false); -} - -/* lock/unlock one hash chain. This is meant to be used to reduce - contention - it cannot guarantee how many records will be locked */ -_PUBLIC_ int tdb_chainlock(struct tdb_context *tdb, TDB_DATA key) -{ - int ret = tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); - tdb_trace_1rec(tdb, "tdb_chainlock", key); - return ret; -} - -/* lock/unlock one hash chain, non-blocking. This is meant to be used - to reduce contention - it cannot guarantee how many records will be - locked */ -_PUBLIC_ int tdb_chainlock_nonblock(struct tdb_context *tdb, TDB_DATA key) -{ - int ret = tdb_lock_nonblock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); - tdb_trace_1rec_ret(tdb, "tdb_chainlock_nonblock", key, ret); - return ret; -} - -/* mark a chain as locked without actually locking it. Warning! use with great caution! */ -_PUBLIC_ int tdb_chainlock_mark(struct tdb_context *tdb, TDB_DATA key) -{ - int ret = tdb_nest_lock(tdb, lock_offset(BUCKET(tdb->hash_fn(&key))), - F_WRLCK, TDB_LOCK_MARK_ONLY); - tdb_trace_1rec(tdb, "tdb_chainlock_mark", key); - return ret; -} - -/* unmark a chain as locked without actually locking it. Warning! use with great caution! */ -_PUBLIC_ int tdb_chainlock_unmark(struct tdb_context *tdb, TDB_DATA key) -{ - tdb_trace_1rec(tdb, "tdb_chainlock_unmark", key); - return tdb_nest_unlock(tdb, lock_offset(BUCKET(tdb->hash_fn(&key))), - F_WRLCK, true); -} - -_PUBLIC_ int tdb_chainunlock(struct tdb_context *tdb, TDB_DATA key) -{ - tdb_trace_1rec(tdb, "tdb_chainunlock", key); - return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); -} - -_PUBLIC_ int tdb_chainlock_read(struct tdb_context *tdb, TDB_DATA key) -{ - int ret; - ret = tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); - tdb_trace_1rec(tdb, "tdb_chainlock_read", key); - return ret; -} - -_PUBLIC_ int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key) -{ - tdb_trace_1rec(tdb, "tdb_chainunlock_read", key); - return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); -} - -_PUBLIC_ int tdb_chainlock_read_nonblock(struct tdb_context *tdb, TDB_DATA key) -{ - int ret = tdb_lock_nonblock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); - tdb_trace_1rec_ret(tdb, "tdb_chainlock_read_nonblock", key, ret); - return ret; -} - -/* record lock stops delete underneath */ -int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off) -{ - if (tdb->allrecord_lock.count) { - return 0; - } - return off ? tdb_brlock(tdb, F_RDLCK, off, 1, TDB_LOCK_WAIT) : 0; -} - -/* - Write locks override our own fcntl readlocks, so check it here. - Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not - an error to fail to get the lock here. -*/ -int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off) -{ - struct tdb_traverse_lock *i; - if (tdb == NULL) { - return -1; - } - for (i = &tdb->travlocks; i; i = i->next) - if (i->off == off) - return -1; - if (tdb->allrecord_lock.count) { - if (tdb->allrecord_lock.ltype == F_WRLCK) { - return 0; - } - return -1; - } - return tdb_brlock(tdb, F_WRLCK, off, 1, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE); -} - -int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off) -{ - if (tdb->allrecord_lock.count) { - return 0; - } - return tdb_brunlock(tdb, F_WRLCK, off, 1); -} - -/* fcntl locks don't stack: avoid unlocking someone else's */ -int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off) -{ - struct tdb_traverse_lock *i; - uint32_t count = 0; - - if (tdb->allrecord_lock.count) { - return 0; - } - - if (off == 0) - return 0; - for (i = &tdb->travlocks; i; i = i->next) - if (i->off == off) - count++; - return (count == 1 ? tdb_brunlock(tdb, F_RDLCK, off, 1) : 0); -} - -bool tdb_have_extra_locks(struct tdb_context *tdb) -{ - unsigned int extra = tdb->num_lockrecs; - - /* A transaction holds the lock for all records. */ - if (!tdb->transaction && tdb->allrecord_lock.count) { - return true; - } - - /* We always hold the active lock if CLEAR_IF_FIRST. */ - if (find_nestlock(tdb, ACTIVE_LOCK)) { - extra--; - } - - /* In a transaction, we expect to hold the transaction lock */ - if (tdb->transaction && find_nestlock(tdb, TRANSACTION_LOCK)) { - extra--; - } - - return extra; -} - -/* The transaction code uses this to remove all locks. */ -void tdb_release_transaction_locks(struct tdb_context *tdb) -{ - int i; - unsigned int active = 0; - - if (tdb->allrecord_lock.count != 0) { - tdb_allrecord_unlock(tdb, tdb->allrecord_lock.ltype, false); - tdb->allrecord_lock.count = 0; - } - - for (i=0;inum_lockrecs;i++) { - struct tdb_lock_type *lck = &tdb->lockrecs[i]; - - /* Don't release the active lock! Copy it to first entry. */ - if (lck->off == ACTIVE_LOCK) { - tdb->lockrecs[active++] = *lck; - } else { - tdb_brunlock(tdb, lck->ltype, lck->off, 1); - } - } - tdb->num_lockrecs = active; -} - -/* Following functions are added specifically to support CTDB. */ - -/* Don't do actual fcntl locking, just mark tdb locked */ -int tdb_transaction_write_lock_mark(struct tdb_context *tdb); -_PUBLIC_ int tdb_transaction_write_lock_mark(struct tdb_context *tdb) -{ - return tdb_transaction_lock(tdb, F_WRLCK, TDB_LOCK_MARK_ONLY); -} - -/* Don't do actual fcntl unlocking, just mark tdb unlocked */ -int tdb_transaction_write_lock_unmark(struct tdb_context *tdb); -_PUBLIC_ int tdb_transaction_write_lock_unmark(struct tdb_context *tdb) -{ - return tdb_nest_unlock(tdb, TRANSACTION_LOCK, F_WRLCK, true); -} diff --git a/ldb-2.0.8/lib/tdb/common/mutex.c b/ldb-2.0.8/lib/tdb/common/mutex.c deleted file mode 100644 index 8a122d5..0000000 --- a/ldb-2.0.8/lib/tdb/common/mutex.c +++ /dev/null @@ -1,1077 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Volker Lendecke 2012,2013 - Copyright (C) Stefan Metzmacher 2013,2014 - Copyright (C) Michael Adam 2014 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ -#include "tdb_private.h" -#include "system/threads.h" - -#ifdef USE_TDB_MUTEX_LOCKING - -/* - * If we run with mutexes, we store the "struct tdb_mutexes" at the - * beginning of the file. We store an additional tdb_header right - * beyond the mutex area, page aligned. All the offsets within the tdb - * are relative to the area behind the mutex area. tdb->map_ptr points - * behind the mmap area as well, so the read and write path in the - * mutex case can remain unchanged. - * - * Early in the mutex development the mutexes were placed between the hash - * chain pointers and the real tdb data. This had two drawbacks: First, it - * made pointer calculations more complex. Second, we had to mmap the mutex - * area twice. One was the normal map_ptr in the tdb. This frequently changed - * from within tdb_oob. At least the Linux glibc robust mutex code assumes - * constant pointers in memory, so a constantly changing mmap area destroys - * the mutex list. So we had to mmap the first bytes of the file with a second - * mmap call. With that scheme, very weird errors happened that could be - * easily fixed by doing the mutex mmap in a second file. It seemed that - * mapping the same memory area twice does not end up in accessing the same - * physical page, looking at the mutexes in gdb it seemed that old data showed - * up after some re-mapping. To avoid a separate mutex file, the code now puts - * the real content of the tdb file after the mutex area. This way we do not - * have overlapping mmap areas, the mutex area is mmapped once and not - * changed, the tdb data area's mmap is constantly changed but does not - * overlap. - */ - -struct tdb_mutexes { - struct tdb_header hdr; - - /* protect allrecord_lock */ - pthread_mutex_t allrecord_mutex; - - /* - * F_UNLCK: free, - * F_RDLCK: shared, - * F_WRLCK: exclusive - */ - short int allrecord_lock; - - /* - * Index 0 is the freelist mutex, followed by - * one mutex per hashchain. - */ - pthread_mutex_t hashchains[1]; -}; - -bool tdb_have_mutexes(struct tdb_context *tdb) -{ - return ((tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) != 0); -} - -size_t tdb_mutex_size(struct tdb_context *tdb) -{ - size_t mutex_size; - - if (!tdb_have_mutexes(tdb)) { - return 0; - } - - mutex_size = sizeof(struct tdb_mutexes); - mutex_size += tdb->hash_size * sizeof(pthread_mutex_t); - - return TDB_ALIGN(mutex_size, tdb->page_size); -} - -/* - * Get the index for a chain mutex - */ -static bool tdb_mutex_index(struct tdb_context *tdb, off_t off, off_t len, - unsigned *idx) -{ - /* - * Weird but true: We fcntl lock 1 byte at an offset 4 bytes before - * the 4 bytes of the freelist start and the hash chain that is about - * to be locked. See lock_offset() where the freelist is -1 vs the - * "+1" in TDB_HASH_TOP(). Because the mutex array is represented in - * the tdb file itself as data, we need to adjust the offset here. - */ - const off_t freelist_lock_ofs = FREELIST_TOP - sizeof(tdb_off_t); - - if (!tdb_have_mutexes(tdb)) { - return false; - } - if (len != 1) { - /* Possibly the allrecord lock */ - return false; - } - if (off < freelist_lock_ofs) { - /* One of the special locks */ - return false; - } - if (tdb->hash_size == 0) { - /* tdb not initialized yet, called from tdb_open_ex() */ - return false; - } - if (off >= TDB_DATA_START(tdb->hash_size)) { - /* Single record lock from traverses */ - return false; - } - - /* - * Now we know it's a freelist or hash chain lock. Those are always 4 - * byte aligned. Paranoia check. - */ - if ((off % sizeof(tdb_off_t)) != 0) { - abort(); - } - - /* - * Re-index the fcntl offset into an offset into the mutex array - */ - off -= freelist_lock_ofs; /* rebase to index 0 */ - off /= sizeof(tdb_off_t); /* 0 for freelist 1-n for hashchain */ - - *idx = off; - return true; -} - -static bool tdb_have_mutex_chainlocks(struct tdb_context *tdb) -{ - size_t i; - - for (i=0; i < tdb->num_lockrecs; i++) { - bool ret; - unsigned idx; - - ret = tdb_mutex_index(tdb, - tdb->lockrecs[i].off, - tdb->lockrecs[i].count, - &idx); - if (!ret) { - continue; - } - - if (idx == 0) { - /* this is the freelist mutex */ - continue; - } - - return true; - } - - return false; -} - -static int chain_mutex_lock(pthread_mutex_t *m, bool waitflag) -{ - int ret; - - if (waitflag) { - ret = pthread_mutex_lock(m); - } else { - ret = pthread_mutex_trylock(m); - } - if (ret != EOWNERDEAD) { - return ret; - } - - /* - * For chainlocks, we don't do any cleanup (yet?) - */ - return pthread_mutex_consistent(m); -} - -static int allrecord_mutex_lock(struct tdb_mutexes *m, bool waitflag) -{ - int ret; - - if (waitflag) { - ret = pthread_mutex_lock(&m->allrecord_mutex); - } else { - ret = pthread_mutex_trylock(&m->allrecord_mutex); - } - if (ret != EOWNERDEAD) { - return ret; - } - - /* - * The allrecord lock holder died. We need to reset the allrecord_lock - * to F_UNLCK. This should also be the indication for - * tdb_needs_recovery. - */ - m->allrecord_lock = F_UNLCK; - - return pthread_mutex_consistent(&m->allrecord_mutex); -} - -bool tdb_mutex_lock(struct tdb_context *tdb, int rw, off_t off, off_t len, - bool waitflag, int *pret) -{ - struct tdb_mutexes *m = tdb->mutexes; - pthread_mutex_t *chain; - int ret; - unsigned idx; - bool allrecord_ok; - - if (!tdb_mutex_index(tdb, off, len, &idx)) { - return false; - } - chain = &m->hashchains[idx]; - -again: - ret = chain_mutex_lock(chain, waitflag); - if (ret == EBUSY) { - ret = EAGAIN; - } - if (ret != 0) { - errno = ret; - goto fail; - } - - if (idx == 0) { - /* - * This is a freelist lock, which is independent to - * the allrecord lock. So we're done once we got the - * freelist mutex. - */ - *pret = 0; - return true; - } - - if (tdb_have_mutex_chainlocks(tdb)) { - /* - * We can only check the allrecord lock once. If we do it with - * one chain mutex locked, we will deadlock with the allrecord - * locker process in the following way: We lock the first hash - * chain, we check for the allrecord lock. We keep the hash - * chain locked. Then the allrecord locker locks the - * allrecord_mutex. It walks the list of chain mutexes, - * locking them all in sequence. Meanwhile, we have the chain - * mutex locked, so the allrecord locker blocks trying to lock - * our chain mutex. Then we come in and try to lock the second - * chain lock, which in most cases will be the freelist. We - * see that the allrecord lock is locked and put ourselves on - * the allrecord_mutex. This will never be signalled though - * because the allrecord locker waits for us to give up the - * chain lock. - */ - - *pret = 0; - return true; - } - - /* - * Check if someone is has the allrecord lock: queue if so. - */ - - allrecord_ok = false; - - if (m->allrecord_lock == F_UNLCK) { - /* - * allrecord lock not taken - */ - allrecord_ok = true; - } - - if ((m->allrecord_lock == F_RDLCK) && (rw == F_RDLCK)) { - /* - * allrecord shared lock taken, but we only want to read - */ - allrecord_ok = true; - } - - if (allrecord_ok) { - *pret = 0; - return true; - } - - ret = pthread_mutex_unlock(chain); - if (ret != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" - "(chain_mutex) failed: %s\n", strerror(ret))); - errno = ret; - goto fail; - } - ret = allrecord_mutex_lock(m, waitflag); - if (ret == EBUSY) { - ret = EAGAIN; - } - if (ret != 0) { - if (waitflag || (ret != EAGAIN)) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_%slock" - "(allrecord_mutex) failed: %s\n", - waitflag ? "" : "try_", strerror(ret))); - } - errno = ret; - goto fail; - } - ret = pthread_mutex_unlock(&m->allrecord_mutex); - if (ret != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" - "(allrecord_mutex) failed: %s\n", strerror(ret))); - errno = ret; - goto fail; - } - goto again; - -fail: - *pret = -1; - return true; -} - -bool tdb_mutex_unlock(struct tdb_context *tdb, int rw, off_t off, off_t len, - int *pret) -{ - struct tdb_mutexes *m = tdb->mutexes; - pthread_mutex_t *chain; - int ret; - unsigned idx; - - if (!tdb_mutex_index(tdb, off, len, &idx)) { - return false; - } - chain = &m->hashchains[idx]; - - ret = pthread_mutex_unlock(chain); - if (ret == 0) { - *pret = 0; - return true; - } - errno = ret; - *pret = -1; - return true; -} - -int tdb_mutex_allrecord_lock(struct tdb_context *tdb, int ltype, - enum tdb_lock_flags flags) -{ - struct tdb_mutexes *m = tdb->mutexes; - int ret; - uint32_t i; - bool waitflag = (flags & TDB_LOCK_WAIT); - int saved_errno; - - if (tdb->flags & TDB_NOLOCK) { - return 0; - } - - if (flags & TDB_LOCK_MARK_ONLY) { - return 0; - } - - ret = allrecord_mutex_lock(m, waitflag); - if (!waitflag && (ret == EBUSY)) { - errno = EAGAIN; - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - if (ret != 0) { - if (!(flags & TDB_LOCK_PROBE)) { - TDB_LOG((tdb, TDB_DEBUG_TRACE, - "allrecord_mutex_lock() failed: %s\n", - strerror(ret))); - } - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - - if (m->allrecord_lock != F_UNLCK) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "allrecord_lock == %d\n", - (int)m->allrecord_lock)); - goto fail_unlock_allrecord_mutex; - } - m->allrecord_lock = (ltype == F_RDLCK) ? F_RDLCK : F_WRLCK; - - for (i=0; ihash_size; i++) { - - /* ignore hashchains[0], the freelist */ - pthread_mutex_t *chain = &m->hashchains[i+1]; - - ret = chain_mutex_lock(chain, waitflag); - if (!waitflag && (ret == EBUSY)) { - errno = EAGAIN; - goto fail_unroll_allrecord_lock; - } - if (ret != 0) { - if (!(flags & TDB_LOCK_PROBE)) { - TDB_LOG((tdb, TDB_DEBUG_TRACE, - "chain_mutex_lock() failed: %s\n", - strerror(ret))); - } - errno = ret; - goto fail_unroll_allrecord_lock; - } - - ret = pthread_mutex_unlock(chain); - if (ret != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" - "(chainlock) failed: %s\n", strerror(ret))); - errno = ret; - goto fail_unroll_allrecord_lock; - } - } - /* - * We leave this routine with m->allrecord_mutex locked - */ - return 0; - -fail_unroll_allrecord_lock: - m->allrecord_lock = F_UNLCK; - -fail_unlock_allrecord_mutex: - saved_errno = errno; - ret = pthread_mutex_unlock(&m->allrecord_mutex); - if (ret != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" - "(allrecord_mutex) failed: %s\n", strerror(ret))); - } - errno = saved_errno; - tdb->ecode = TDB_ERR_LOCK; - return -1; -} - -int tdb_mutex_allrecord_upgrade(struct tdb_context *tdb) -{ - struct tdb_mutexes *m = tdb->mutexes; - int ret; - uint32_t i; - - if (tdb->flags & TDB_NOLOCK) { - return 0; - } - - /* - * Our only caller tdb_allrecord_upgrade() - * garantees that we already own the allrecord lock. - * - * Which means m->allrecord_mutex is still locked by us. - */ - - if (m->allrecord_lock != F_RDLCK) { - tdb->ecode = TDB_ERR_LOCK; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "allrecord_lock == %d\n", - (int)m->allrecord_lock)); - return -1; - } - - m->allrecord_lock = F_WRLCK; - - for (i=0; ihash_size; i++) { - - /* ignore hashchains[0], the freelist */ - pthread_mutex_t *chain = &m->hashchains[i+1]; - - ret = chain_mutex_lock(chain, true); - if (ret != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_lock" - "(chainlock) failed: %s\n", strerror(ret))); - goto fail_unroll_allrecord_lock; - } - - ret = pthread_mutex_unlock(chain); - if (ret != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" - "(chainlock) failed: %s\n", strerror(ret))); - goto fail_unroll_allrecord_lock; - } - } - - return 0; - -fail_unroll_allrecord_lock: - m->allrecord_lock = F_RDLCK; - tdb->ecode = TDB_ERR_LOCK; - return -1; -} - -void tdb_mutex_allrecord_downgrade(struct tdb_context *tdb) -{ - struct tdb_mutexes *m = tdb->mutexes; - - /* - * Our only caller tdb_allrecord_upgrade() (in the error case) - * garantees that we already own the allrecord lock. - * - * Which means m->allrecord_mutex is still locked by us. - */ - - if (m->allrecord_lock != F_WRLCK) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "allrecord_lock == %d\n", - (int)m->allrecord_lock)); - return; - } - - m->allrecord_lock = F_RDLCK; - return; -} - - -int tdb_mutex_allrecord_unlock(struct tdb_context *tdb) -{ - struct tdb_mutexes *m = tdb->mutexes; - short old; - int ret; - - if (tdb->flags & TDB_NOLOCK) { - return 0; - } - - /* - * Our only callers tdb_allrecord_unlock() and - * tdb_allrecord_lock() (in the error path) - * garantee that we already own the allrecord lock. - * - * Which means m->allrecord_mutex is still locked by us. - */ - - if ((m->allrecord_lock != F_RDLCK) && (m->allrecord_lock != F_WRLCK)) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "allrecord_lock == %d\n", - (int)m->allrecord_lock)); - return -1; - } - - old = m->allrecord_lock; - m->allrecord_lock = F_UNLCK; - - ret = pthread_mutex_unlock(&m->allrecord_mutex); - if (ret != 0) { - m->allrecord_lock = old; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "pthread_mutex_unlock" - "(allrecord_mutex) failed: %s\n", strerror(ret))); - return -1; - } - return 0; -} - -int tdb_mutex_init(struct tdb_context *tdb) -{ - struct tdb_mutexes *m; - pthread_mutexattr_t ma; - int i, ret; - - ret = tdb_mutex_mmap(tdb); - if (ret == -1) { - return -1; - } - m = tdb->mutexes; - - ret = pthread_mutexattr_init(&ma); - if (ret != 0) { - goto fail_munmap; - } - ret = pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK); - if (ret != 0) { - goto fail; - } - ret = pthread_mutexattr_setpshared(&ma, PTHREAD_PROCESS_SHARED); - if (ret != 0) { - goto fail; - } - ret = pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST); - if (ret != 0) { - goto fail; - } - - for (i=0; ihash_size+1; i++) { - pthread_mutex_t *chain = &m->hashchains[i]; - - ret = pthread_mutex_init(chain, &ma); - if (ret != 0) { - goto fail; - } - } - - m->allrecord_lock = F_UNLCK; - - ret = pthread_mutex_init(&m->allrecord_mutex, &ma); - if (ret != 0) { - goto fail; - } - ret = 0; -fail: - pthread_mutexattr_destroy(&ma); -fail_munmap: - - if (ret == 0) { - return 0; - } - - tdb_mutex_munmap(tdb); - - errno = ret; - return -1; -} - -int tdb_mutex_mmap(struct tdb_context *tdb) -{ - size_t len; - void *ptr; - - len = tdb_mutex_size(tdb); - if (len == 0) { - return 0; - } - - if (tdb->mutexes != NULL) { - return 0; - } - - ptr = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FILE, - tdb->fd, 0); - if (ptr == MAP_FAILED) { - return -1; - } - tdb->mutexes = (struct tdb_mutexes *)ptr; - - return 0; -} - -int tdb_mutex_munmap(struct tdb_context *tdb) -{ - size_t len; - int ret; - - len = tdb_mutex_size(tdb); - if (len == 0) { - return 0; - } - - ret = munmap(tdb->mutexes, len); - if (ret == -1) { - return -1; - } - tdb->mutexes = NULL; - - return 0; -} - -static bool tdb_mutex_locking_cached; - -static bool tdb_mutex_locking_supported(void) -{ - pthread_mutexattr_t ma; - pthread_mutex_t m; - int ret; - static bool initialized; - - if (initialized) { - return tdb_mutex_locking_cached; - } - - initialized = true; - - ret = pthread_mutexattr_init(&ma); - if (ret != 0) { - return false; - } - ret = pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK); - if (ret != 0) { - goto cleanup_ma; - } - ret = pthread_mutexattr_setpshared(&ma, PTHREAD_PROCESS_SHARED); - if (ret != 0) { - goto cleanup_ma; - } - ret = pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST); - if (ret != 0) { - goto cleanup_ma; - } - ret = pthread_mutex_init(&m, &ma); - if (ret != 0) { - goto cleanup_ma; - } - ret = pthread_mutex_lock(&m); - if (ret != 0) { - goto cleanup_m; - } - /* - * This makes sure we have real mutexes - * from a threading library instead of just - * stubs from libc. - */ - ret = pthread_mutex_lock(&m); - if (ret != EDEADLK) { - goto cleanup_lock; - } - ret = pthread_mutex_unlock(&m); - if (ret != 0) { - goto cleanup_m; - } - - tdb_mutex_locking_cached = true; - goto cleanup_m; - -cleanup_lock: - pthread_mutex_unlock(&m); -cleanup_m: - pthread_mutex_destroy(&m); -cleanup_ma: - pthread_mutexattr_destroy(&ma); - return tdb_mutex_locking_cached; -} - -static void (*tdb_robust_mutext_old_handler)(int) = SIG_ERR; -static pid_t tdb_robust_mutex_pid = -1; - -static bool tdb_robust_mutex_setup_sigchild(void (*handler)(int), - void (**p_old_handler)(int)) -{ -#ifdef HAVE_SIGACTION - struct sigaction act; - struct sigaction oldact; - - memset(&act, '\0', sizeof(act)); - - act.sa_handler = handler; -#ifdef SA_RESTART - act.sa_flags = SA_RESTART; -#endif - sigemptyset(&act.sa_mask); - sigaddset(&act.sa_mask, SIGCHLD); - sigaction(SIGCHLD, &act, &oldact); - if (p_old_handler) { - *p_old_handler = oldact.sa_handler; - } - return true; -#else /* !HAVE_SIGACTION */ - return false; -#endif -} - -static void tdb_robust_mutex_handler(int sig) -{ - pid_t child_pid = tdb_robust_mutex_pid; - - if (child_pid != -1) { - pid_t pid; - - pid = waitpid(child_pid, NULL, WNOHANG); - if (pid == -1) { - switch (errno) { - case ECHILD: - tdb_robust_mutex_pid = -1; - return; - - default: - return; - } - } - if (pid == child_pid) { - tdb_robust_mutex_pid = -1; - return; - } - } - - if (tdb_robust_mutext_old_handler == SIG_DFL) { - return; - } - if (tdb_robust_mutext_old_handler == SIG_IGN) { - return; - } - if (tdb_robust_mutext_old_handler == SIG_ERR) { - return; - } - - tdb_robust_mutext_old_handler(sig); -} - -static void tdb_robust_mutex_wait_for_child(pid_t *child_pid) -{ - int options = WNOHANG; - - if (*child_pid == -1) { - return; - } - - while (tdb_robust_mutex_pid > 0) { - pid_t pid; - - /* - * First we try with WNOHANG, as the process might not exist - * anymore. Once we've sent SIGKILL we block waiting for the - * exit. - */ - pid = waitpid(*child_pid, NULL, options); - if (pid == -1) { - if (errno == EINTR) { - continue; - } else if (errno == ECHILD) { - break; - } else { - abort(); - } - } - if (pid == *child_pid) { - break; - } - - kill(*child_pid, SIGKILL); - options = 0; - } - - tdb_robust_mutex_pid = -1; - *child_pid = -1; -} - -_PUBLIC_ bool tdb_runtime_check_for_robust_mutexes(void) -{ - void *ptr = NULL; - pthread_mutex_t *m = NULL; - pthread_mutexattr_t ma; - int ret = 1; - int pipe_down[2] = { -1, -1 }; - int pipe_up[2] = { -1, -1 }; - ssize_t nread; - char c = 0; - bool ok; - static bool initialized; - pid_t saved_child_pid = -1; - bool cleanup_ma = false; - - if (initialized) { - return tdb_mutex_locking_cached; - } - - initialized = true; - - ok = tdb_mutex_locking_supported(); - if (!ok) { - return false; - } - - tdb_mutex_locking_cached = false; - - ptr = mmap(NULL, sizeof(pthread_mutex_t), PROT_READ|PROT_WRITE, - MAP_SHARED|MAP_ANON, -1 /* fd */, 0); - if (ptr == MAP_FAILED) { - return false; - } - - ret = pipe(pipe_down); - if (ret != 0) { - goto cleanup; - } - ret = pipe(pipe_up); - if (ret != 0) { - goto cleanup; - } - - ret = pthread_mutexattr_init(&ma); - if (ret != 0) { - goto cleanup; - } - cleanup_ma = true; - ret = pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_ERRORCHECK); - if (ret != 0) { - goto cleanup; - } - ret = pthread_mutexattr_setpshared(&ma, PTHREAD_PROCESS_SHARED); - if (ret != 0) { - goto cleanup; - } - ret = pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST); - if (ret != 0) { - goto cleanup; - } - ret = pthread_mutex_init(ptr, &ma); - if (ret != 0) { - goto cleanup; - } - m = (pthread_mutex_t *)ptr; - - if (tdb_robust_mutex_setup_sigchild(tdb_robust_mutex_handler, - &tdb_robust_mutext_old_handler) == false) { - goto cleanup; - } - - tdb_robust_mutex_pid = fork(); - saved_child_pid = tdb_robust_mutex_pid; - if (tdb_robust_mutex_pid == 0) { - size_t nwritten; - close(pipe_down[1]); - close(pipe_up[0]); - ret = pthread_mutex_lock(m); - nwritten = write(pipe_up[1], &ret, sizeof(ret)); - if (nwritten != sizeof(ret)) { - _exit(1); - } - if (ret != 0) { - _exit(1); - } - nread = read(pipe_down[0], &c, 1); - if (nread != 1) { - _exit(1); - } - /* leave locked */ - _exit(0); - } - if (tdb_robust_mutex_pid == -1) { - goto cleanup; - } - close(pipe_down[0]); - pipe_down[0] = -1; - close(pipe_up[1]); - pipe_up[1] = -1; - - nread = read(pipe_up[0], &ret, sizeof(ret)); - if (nread != sizeof(ret)) { - goto cleanup; - } - - ret = pthread_mutex_trylock(m); - if (ret != EBUSY) { - if (ret == 0) { - pthread_mutex_unlock(m); - } - goto cleanup; - } - - if (write(pipe_down[1], &c, 1) != 1) { - goto cleanup; - } - - nread = read(pipe_up[0], &c, 1); - if (nread != 0) { - goto cleanup; - } - - tdb_robust_mutex_wait_for_child(&saved_child_pid); - - ret = pthread_mutex_trylock(m); - if (ret != EOWNERDEAD) { - if (ret == 0) { - pthread_mutex_unlock(m); - } - goto cleanup; - } - - ret = pthread_mutex_consistent(m); - if (ret != 0) { - goto cleanup; - } - - ret = pthread_mutex_trylock(m); - if (ret != EDEADLK && ret != EBUSY) { - pthread_mutex_unlock(m); - goto cleanup; - } - - ret = pthread_mutex_unlock(m); - if (ret != 0) { - goto cleanup; - } - - tdb_mutex_locking_cached = true; - -cleanup: - /* - * Note that we don't reset the signal handler we just reset - * tdb_robust_mutex_pid to -1. This is ok as this code path is only - * called once per process. - * - * Leaving our signal handler avoids races with other threads potentialy - * setting up their SIGCHLD handlers. - * - * The worst thing that can happen is that the other newer signal - * handler will get the SIGCHLD signal for our child and/or reap the - * child with a wait() function. tdb_robust_mutex_wait_for_child() - * handles the case where waitpid returns ECHILD. - */ - tdb_robust_mutex_wait_for_child(&saved_child_pid); - - if (m != NULL) { - pthread_mutex_destroy(m); - } - if (cleanup_ma) { - pthread_mutexattr_destroy(&ma); - } - if (pipe_down[0] != -1) { - close(pipe_down[0]); - } - if (pipe_down[1] != -1) { - close(pipe_down[1]); - } - if (pipe_up[0] != -1) { - close(pipe_up[0]); - } - if (pipe_up[1] != -1) { - close(pipe_up[1]); - } - if (ptr != NULL) { - munmap(ptr, sizeof(pthread_mutex_t)); - } - - return tdb_mutex_locking_cached; -} - -#else - -size_t tdb_mutex_size(struct tdb_context *tdb) -{ - return 0; -} - -bool tdb_have_mutexes(struct tdb_context *tdb) -{ - return false; -} - -int tdb_mutex_allrecord_lock(struct tdb_context *tdb, int ltype, - enum tdb_lock_flags flags) -{ - tdb->ecode = TDB_ERR_LOCK; - return -1; -} - -int tdb_mutex_allrecord_unlock(struct tdb_context *tdb) -{ - return -1; -} - -int tdb_mutex_allrecord_upgrade(struct tdb_context *tdb) -{ - tdb->ecode = TDB_ERR_LOCK; - return -1; -} - -void tdb_mutex_allrecord_downgrade(struct tdb_context *tdb) -{ - return; -} - -int tdb_mutex_mmap(struct tdb_context *tdb) -{ - errno = ENOSYS; - return -1; -} - -int tdb_mutex_munmap(struct tdb_context *tdb) -{ - errno = ENOSYS; - return -1; -} - -int tdb_mutex_init(struct tdb_context *tdb) -{ - errno = ENOSYS; - return -1; -} - -_PUBLIC_ bool tdb_runtime_check_for_robust_mutexes(void) -{ - return false; -} - -#endif diff --git a/ldb-2.0.8/lib/tdb/common/open.c b/ldb-2.0.8/lib/tdb/common/open.c deleted file mode 100644 index f7f65b0..0000000 --- a/ldb-2.0.8/lib/tdb/common/open.c +++ /dev/null @@ -1,962 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "tdb_private.h" - -/* all contexts, to ensure no double-opens (fcntl locks don't nest!) */ -static struct tdb_context *tdbs = NULL; - -/* We use two hashes to double-check they're using the right hash function. */ -void tdb_header_hash(struct tdb_context *tdb, - uint32_t *magic1_hash, uint32_t *magic2_hash) -{ - TDB_DATA hash_key; - uint32_t tdb_magic = TDB_MAGIC; - - hash_key.dptr = discard_const_p(unsigned char, TDB_MAGIC_FOOD); - hash_key.dsize = sizeof(TDB_MAGIC_FOOD); - *magic1_hash = tdb->hash_fn(&hash_key); - - hash_key.dptr = (unsigned char *)CONVERT(tdb_magic); - hash_key.dsize = sizeof(tdb_magic); - *magic2_hash = tdb->hash_fn(&hash_key); - - /* Make sure at least one hash is non-zero! */ - if (*magic1_hash == 0 && *magic2_hash == 0) - *magic1_hash = 1; -} - -/* initialise a new database with a specified hash size */ -static int tdb_new_database(struct tdb_context *tdb, struct tdb_header *header, - int hash_size) -{ - struct tdb_header *newdb; - size_t size; - int ret = -1; - - /* We make it up in memory, then write it out if not internal */ - size = sizeof(struct tdb_header) + (hash_size+1)*sizeof(tdb_off_t); - if (!(newdb = (struct tdb_header *)calloc(size, 1))) { - tdb->ecode = TDB_ERR_OOM; - return -1; - } - - /* Fill in the header */ - newdb->version = TDB_VERSION; - newdb->hash_size = hash_size; - - tdb_header_hash(tdb, &newdb->magic1_hash, &newdb->magic2_hash); - - /* Make sure older tdbs (which don't check the magic hash fields) - * will refuse to open this TDB. */ - if (tdb->flags & TDB_INCOMPATIBLE_HASH) - newdb->rwlocks = TDB_HASH_RWLOCK_MAGIC; - - /* - * We create a tdb with TDB_FEATURE_FLAG_MUTEX support, - * the flag combination and runtime feature checks - * are done by the caller already. - */ - if (tdb->flags & TDB_MUTEX_LOCKING) { - newdb->feature_flags |= TDB_FEATURE_FLAG_MUTEX; - } - - /* - * If we have any features we add the FEATURE_FLAG_MAGIC, overwriting the - * TDB_HASH_RWLOCK_MAGIC above. - */ - if (newdb->feature_flags != 0) { - newdb->rwlocks = TDB_FEATURE_FLAG_MAGIC; - } - - /* - * It's required for some following code pathes - * to have the fields on 'tdb' up-to-date. - * - * E.g. tdb_mutex_size() requires it - */ - tdb->feature_flags = newdb->feature_flags; - tdb->hash_size = newdb->hash_size; - - if (tdb->flags & TDB_INTERNAL) { - tdb->map_size = size; - tdb->map_ptr = (char *)newdb; - memcpy(header, newdb, sizeof(*header)); - /* Convert the `ondisk' version if asked. */ - CONVERT(*newdb); - return 0; - } - if (lseek(tdb->fd, 0, SEEK_SET) == -1) - goto fail; - - if (ftruncate(tdb->fd, 0) == -1) - goto fail; - - if (newdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) { - newdb->mutex_size = tdb_mutex_size(tdb); - tdb->hdr_ofs = newdb->mutex_size; - } - - /* This creates an endian-converted header, as if read from disk */ - CONVERT(*newdb); - memcpy(header, newdb, sizeof(*header)); - /* Don't endian-convert the magic food! */ - memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1); - - if (!tdb_write_all(tdb->fd, newdb, size)) - goto fail; - - if (newdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) { - - /* - * Now we init the mutex area - * followed by a second header. - */ - - ret = ftruncate( - tdb->fd, - newdb->mutex_size + sizeof(struct tdb_header)); - if (ret == -1) { - goto fail; - } - ret = tdb_mutex_init(tdb); - if (ret == -1) { - goto fail; - } - - /* - * Write a second header behind the mutexes. That's the area - * that will be mmapp'ed. - */ - ret = lseek(tdb->fd, newdb->mutex_size, SEEK_SET); - if (ret == -1) { - goto fail; - } - if (!tdb_write_all(tdb->fd, newdb, size)) { - goto fail; - } - } - - ret = 0; - fail: - SAFE_FREE(newdb); - return ret; -} - - - -static int tdb_already_open(dev_t device, - ino_t ino) -{ - struct tdb_context *i; - - for (i = tdbs; i; i = i->next) { - if (i->device == device && i->inode == ino) { - return 1; - } - } - - return 0; -} - -/* open the database, creating it if necessary - - The open_flags and mode are passed straight to the open call on the - database file. A flags value of O_WRONLY is invalid. The hash size - is advisory, use zero for a default value. - - Return is NULL on error, in which case errno is also set. Don't - try to call tdb_error or tdb_errname, just do strerror(errno). - - @param name may be NULL for internal databases. */ -_PUBLIC_ struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode) -{ - return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL, NULL); -} - -/* a default logging function */ -static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4); -static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) -{ -} - -static bool check_header_hash(struct tdb_context *tdb, - struct tdb_header *header, - bool default_hash, uint32_t *m1, uint32_t *m2) -{ - tdb_header_hash(tdb, m1, m2); - if (header->magic1_hash == *m1 && - header->magic2_hash == *m2) { - return true; - } - - /* If they explicitly set a hash, always respect it. */ - if (!default_hash) - return false; - - /* Otherwise, try the other inbuilt hash. */ - if (tdb->hash_fn == tdb_old_hash) - tdb->hash_fn = tdb_jenkins_hash; - else - tdb->hash_fn = tdb_old_hash; - return check_header_hash(tdb, header, false, m1, m2); -} - -static bool tdb_mutex_open_ok(struct tdb_context *tdb, - const struct tdb_header *header) -{ - if (tdb->flags & TDB_NOLOCK) { - /* - * We don't look at locks, so it does not matter to have a - * compatible mutex implementation. Allow the open. - */ - return true; - } - - if (!(tdb->flags & TDB_MUTEX_LOCKING)) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_mutex_open_ok[%s]: " - "Can use mutexes only with " - "MUTEX_LOCKING or NOLOCK\n", - tdb->name)); - return false; - } - - if (tdb_mutex_size(tdb) != header->mutex_size) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_mutex_open_ok[%s]: " - "Mutex size changed from %"PRIu32" to %zu\n.", - tdb->name, - header->mutex_size, - tdb_mutex_size(tdb))); - return false; - } - - return true; -} - -_PUBLIC_ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode, - const struct tdb_logging_context *log_ctx, - tdb_hash_func hash_fn) -{ - int orig_errno = errno; - struct tdb_header header = { - .version = 0, - }; - struct tdb_context *tdb; - struct stat st; - int rev = 0; - bool locked = false; - unsigned char *vp; - uint32_t vertest; - unsigned v; - const char *hash_alg; - uint32_t magic1, magic2; - int ret; - - if (!(tdb = (struct tdb_context *)calloc(1, sizeof *tdb))) { - /* Can't log this */ - errno = ENOMEM; - goto fail; - } - tdb_io_init(tdb); - - if (tdb_flags & TDB_INTERNAL) { - tdb_flags |= TDB_INCOMPATIBLE_HASH; - } - if (tdb_flags & TDB_MUTEX_LOCKING) { - tdb_flags |= TDB_INCOMPATIBLE_HASH; - } - - tdb->fd = -1; -#ifdef TDB_TRACE - tdb->tracefd = -1; -#endif - tdb->name = NULL; - tdb->map_ptr = NULL; - tdb->flags = tdb_flags; - tdb->open_flags = open_flags; - if (log_ctx) { - tdb->log = *log_ctx; - } else { - tdb->log.log_fn = null_log_fn; - tdb->log.log_private = NULL; - } - - if (name == NULL && (tdb_flags & TDB_INTERNAL)) { - name = "__TDB_INTERNAL__"; - } - - if (name == NULL) { - tdb->name = discard_const_p(char, "__NULL__"); - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: called with name == NULL\n")); - tdb->name = NULL; - errno = EINVAL; - goto fail; - } - - /* now make a copy of the name, as the caller memory might go away */ - if (!(tdb->name = (char *)strdup(name))) { - /* - * set the name as the given string, so that tdb_name() will - * work in case of an error. - */ - tdb->name = discard_const_p(char, name); - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't strdup(%s)\n", - name)); - tdb->name = NULL; - errno = ENOMEM; - goto fail; - } - - if (hash_fn) { - tdb->hash_fn = hash_fn; - hash_alg = "the user defined"; - } else { - /* This controls what we use when creating a tdb. */ - if (tdb->flags & TDB_INCOMPATIBLE_HASH) { - tdb->hash_fn = tdb_jenkins_hash; - } else { - tdb->hash_fn = tdb_old_hash; - } - hash_alg = "either default"; - } - - /* cache the page size */ - tdb->page_size = getpagesize(); - if (tdb->page_size <= 0) { - tdb->page_size = 0x2000; - } - - tdb->max_dead_records = (tdb_flags & TDB_VOLATILE) ? 5 : 0; - - if ((open_flags & O_ACCMODE) == O_WRONLY) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't open tdb %s write-only\n", - name)); - errno = EINVAL; - goto fail; - } - - if (hash_size == 0) - hash_size = DEFAULT_HASH_SIZE; - if ((open_flags & O_ACCMODE) == O_RDONLY) { - tdb->read_only = 1; - /* read only databases don't do locking or clear if first */ - tdb->flags |= TDB_NOLOCK; - tdb->flags &= ~(TDB_CLEAR_IF_FIRST|TDB_MUTEX_LOCKING); - } - - if ((tdb->flags & TDB_ALLOW_NESTING) && - (tdb->flags & TDB_DISALLOW_NESTING)) { - tdb->ecode = TDB_ERR_NESTING; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " - "allow_nesting and disallow_nesting are not allowed together!")); - errno = EINVAL; - goto fail; - } - - if (tdb->flags & TDB_MUTEX_LOCKING) { - /* - * Here we catch bugs in the callers, - * the runtime check for existing tdb's comes later. - */ - - if (tdb->flags & TDB_INTERNAL) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " - "invalid flags for %s - TDB_MUTEX_LOCKING and " - "TDB_INTERNAL are not allowed together\n", name)); - errno = EINVAL; - goto fail; - } - - if (tdb->flags & TDB_NOMMAP) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " - "invalid flags for %s - TDB_MUTEX_LOCKING and " - "TDB_NOMMAP are not allowed together\n", name)); - errno = EINVAL; - goto fail; - } - - if (tdb->read_only) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " - "invalid flags for %s - TDB_MUTEX_LOCKING " - "not allowed read only\n", name)); - errno = EINVAL; - goto fail; - } - - /* - * The callers should have called - * tdb_runtime_check_for_robust_mutexes() - * before using TDB_MUTEX_LOCKING! - * - * This makes sure the caller understands - * that the locking may behave a bit differently - * than with pure fcntl locking. E.g. multiple - * read locks are not supported. - */ - if (!tdb_runtime_check_for_robust_mutexes()) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " - "invalid flags for %s - TDB_MUTEX_LOCKING " - "requires support for robust_mutexes\n", - name)); - errno = ENOSYS; - goto fail; - } - } - - if (getenv("TDB_NO_FSYNC")) { - tdb->flags |= TDB_NOSYNC; - } - - /* - * TDB_ALLOW_NESTING is the default behavior. - * Note: this may change in future versions! - */ - if (!(tdb->flags & TDB_DISALLOW_NESTING)) { - tdb->flags |= TDB_ALLOW_NESTING; - } - - /* internal databases don't mmap or lock, and start off cleared */ - if (tdb->flags & TDB_INTERNAL) { - tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP); - tdb->flags &= ~TDB_CLEAR_IF_FIRST; - if (tdb_new_database(tdb, &header, hash_size) != 0) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: tdb_new_database failed!")); - goto fail; - } - tdb->hash_size = hash_size; - goto internal; - } - - if ((tdb->fd = open(name, open_flags, mode)) == -1) { - TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_open_ex: could not open file %s: %s\n", - name, strerror(errno))); - goto fail; /* errno set by open(2) */ - } - - /* on exec, don't inherit the fd */ - v = fcntl(tdb->fd, F_GETFD, 0); - fcntl(tdb->fd, F_SETFD, v | FD_CLOEXEC); - - /* ensure there is only one process initialising at once */ - if (tdb_nest_lock(tdb, OPEN_LOCK, F_WRLCK, TDB_LOCK_WAIT) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to get open lock on %s: %s\n", - name, strerror(errno))); - goto fail; /* errno set by tdb_brlock */ - } - - /* we need to zero database if we are the only one with it open */ - if ((tdb_flags & TDB_CLEAR_IF_FIRST) && - (!tdb->read_only)) { - ret = tdb_nest_lock(tdb, ACTIVE_LOCK, F_WRLCK, - TDB_LOCK_NOWAIT|TDB_LOCK_PROBE); - locked = (ret == 0); - - if (locked) { - ret = tdb_brlock(tdb, F_WRLCK, FREELIST_TOP, 0, - TDB_LOCK_WAIT); - if (ret == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " - "tdb_brlock failed for %s: %s\n", - name, strerror(errno))); - goto fail; - } - ret = tdb_new_database(tdb, &header, hash_size); - if (ret == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " - "tdb_new_database failed for " - "%s: %s\n", name, strerror(errno))); - tdb_unlockall(tdb); - goto fail; - } - ret = tdb_brunlock(tdb, F_WRLCK, FREELIST_TOP, 0); - if (ret == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " - "tdb_unlockall failed for %s: %s\n", - name, strerror(errno))); - goto fail; - } - ret = lseek(tdb->fd, 0, SEEK_SET); - if (ret == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " - "lseek failed for %s: %s\n", - name, strerror(errno))); - goto fail; - } - } - } - - errno = 0; - if (read(tdb->fd, &header, sizeof(header)) != sizeof(header) - || strcmp(header.magic_food, TDB_MAGIC_FOOD) != 0) { - if (!(open_flags & O_CREAT) || - tdb_new_database(tdb, &header, hash_size) == -1) { - if (errno == 0) { - errno = EIO; /* ie bad format or something */ - } - goto fail; - } - rev = (tdb->flags & TDB_CONVERT); - } else if (header.version != TDB_VERSION - && !(rev = (header.version==TDB_BYTEREV(TDB_VERSION)))) { - /* wrong version */ - errno = EIO; - goto fail; - } - vp = (unsigned char *)&header.version; - vertest = (((uint32_t)vp[0]) << 24) | (((uint32_t)vp[1]) << 16) | - (((uint32_t)vp[2]) << 8) | (uint32_t)vp[3]; - tdb->flags |= (vertest==TDB_VERSION) ? TDB_BIGENDIAN : 0; - if (!rev) - tdb->flags &= ~TDB_CONVERT; - else { - tdb->flags |= TDB_CONVERT; - tdb_convert(&header, sizeof(header)); - } - - /* - * We only use st.st_dev and st.st_ino from the raw fstat() - * call, everything else needs to use tdb_fstat() in order - * to skip tdb->hdr_ofs! - */ - if (fstat(tdb->fd, &st) == -1) { - goto fail; - } - tdb->device = st.st_dev; - tdb->inode = st.st_ino; - ZERO_STRUCT(st); - - if (header.rwlocks != 0 && - header.rwlocks != TDB_FEATURE_FLAG_MAGIC && - header.rwlocks != TDB_HASH_RWLOCK_MAGIC) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: spinlocks no longer supported\n")); - errno = ENOSYS; - goto fail; - } - - if (header.hash_size == 0) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: invalid database: 0 hash_size\n")); - errno = ENOSYS; - goto fail; - } - - tdb->hash_size = header.hash_size; - - if (header.rwlocks == TDB_FEATURE_FLAG_MAGIC) { - tdb->feature_flags = header.feature_flags; - } - - if (tdb->feature_flags & ~TDB_SUPPORTED_FEATURE_FLAGS) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: unsupported " - "features in tdb %s: 0x%08x (supported: 0x%08x)\n", - name, (unsigned)tdb->feature_flags, - (unsigned)TDB_SUPPORTED_FEATURE_FLAGS)); - errno = ENOSYS; - goto fail; - } - - if (tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) { - if (!tdb_mutex_open_ok(tdb, &header)) { - errno = EINVAL; - goto fail; - } - - /* - * We need to remember the hdr_ofs - * also for the TDB_NOLOCK case - * if the current library doesn't support - * mutex locking. - */ - tdb->hdr_ofs = header.mutex_size; - - if ((!(tdb_flags & TDB_CLEAR_IF_FIRST)) && (!tdb->read_only)) { - /* - * Open an existing mutexed tdb, but without - * CLEAR_IF_FIRST. We need to initialize the - * mutex array and keep the CLEAR_IF_FIRST - * lock locked. - */ - ret = tdb_nest_lock(tdb, ACTIVE_LOCK, F_WRLCK, - TDB_LOCK_NOWAIT|TDB_LOCK_PROBE); - locked = (ret == 0); - - if (locked) { - ret = tdb_mutex_init(tdb); - if (ret == -1) { - TDB_LOG((tdb, - TDB_DEBUG_FATAL, - "tdb_open_ex: tdb_mutex_init " - "failed for ""%s: %s\n", - name, strerror(errno))); - goto fail; - } - } - } - } - - if ((header.magic1_hash == 0) && (header.magic2_hash == 0)) { - /* older TDB without magic hash references */ - tdb->hash_fn = tdb_old_hash; - } else if (!check_header_hash(tdb, &header, !hash_fn, - &magic1, &magic2)) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " - "%s was not created with %s hash function we are using\n" - "magic1_hash[0x%08X %s 0x%08X] " - "magic2_hash[0x%08X %s 0x%08X]\n", - name, hash_alg, - header.magic1_hash, - (header.magic1_hash == magic1) ? "==" : "!=", - magic1, - header.magic2_hash, - (header.magic2_hash == magic2) ? "==" : "!=", - magic2)); - errno = EINVAL; - goto fail; - } - - /* Is it already in the open list? If so, fail. */ - if (tdb_already_open(tdb->device, tdb->inode)) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " - "%s (%d,%d) is already open in this process\n", - name, (int)tdb->device, (int)tdb->inode)); - errno = EBUSY; - goto fail; - } - - /* - * We had tdb_mmap(tdb) here before, - * but we need to use tdb_fstat(), - * which is triggered from tdb_oob() before calling tdb_mmap(). - * As this skips tdb->hdr_ofs. - */ - tdb->map_size = 0; - ret = tdb_oob(tdb, 0, 1, 0); - if (ret == -1) { - errno = EIO; - goto fail; - } - - if (tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) { - if (!(tdb->flags & TDB_NOLOCK)) { - ret = tdb_mutex_mmap(tdb); - if (ret != 0) { - goto fail; - } - } - } - - if (tdb->hash_size > UINT32_MAX/4) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " - "hash size %"PRIu32" too large\n", tdb->hash_size)); - errno = EINVAL; - goto fail; - } - - ret = tdb_oob(tdb, FREELIST_TOP, 4*tdb->hash_size, 1); - if (ret == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " - "hash size %"PRIu32" does not fit\n", tdb->hash_size)); - errno = EINVAL; - goto fail; - } - - if (locked) { - if (tdb_nest_unlock(tdb, ACTIVE_LOCK, F_WRLCK, false) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: " - "failed to release ACTIVE_LOCK on %s: %s\n", - name, strerror(errno))); - goto fail; - } - - - } - - if (locked || (tdb_flags & TDB_CLEAR_IF_FIRST)) { - /* - * We always need to do this if the CLEAR_IF_FIRST - * flag is set, even if we didn't get the initial - * exclusive lock as we need to let all other users - * know we're using it. - */ - - ret = tdb_nest_lock(tdb, ACTIVE_LOCK, F_RDLCK, TDB_LOCK_WAIT); - if (ret == -1) { - goto fail; - } - } - - /* if needed, run recovery */ - if (tdb_transaction_recover(tdb) == -1) { - goto fail; - } - -#ifdef TDB_TRACE - { - char tracefile[strlen(name) + 32]; - - snprintf(tracefile, sizeof(tracefile), - "%s.trace.%li", name, (long)getpid()); - tdb->tracefd = open(tracefile, O_WRONLY|O_CREAT|O_EXCL, 0600); - if (tdb->tracefd >= 0) { - tdb_enable_seqnum(tdb); - tdb_trace_open(tdb, "tdb_open", hash_size, tdb_flags, - open_flags); - } else - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to open trace file %s!\n", tracefile)); - } -#endif - - internal: - /* Internal (memory-only) databases skip all the code above to - * do with disk files, and resume here by releasing their - * open lock and hooking into the active list. */ - if (tdb_nest_unlock(tdb, OPEN_LOCK, F_WRLCK, false) == -1) { - goto fail; - } - tdb->next = tdbs; - tdbs = tdb; - errno = orig_errno; - return tdb; - - fail: - { int save_errno = errno; - - if (!tdb) - return NULL; - -#ifdef TDB_TRACE - close(tdb->tracefd); -#endif - if (tdb->map_ptr) { - if (tdb->flags & TDB_INTERNAL) - SAFE_FREE(tdb->map_ptr); - else - tdb_munmap(tdb); - } - if (tdb->fd != -1) - if (close(tdb->fd) != 0) - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to close tdb->fd on error!\n")); - SAFE_FREE(tdb->lockrecs); - SAFE_FREE(tdb->name); - SAFE_FREE(tdb); - errno = save_errno; - return NULL; - } -} - -/* - * Set the maximum number of dead records per hash chain - */ - -_PUBLIC_ void tdb_set_max_dead(struct tdb_context *tdb, int max_dead) -{ - tdb->max_dead_records = max_dead; -} - -/** - * Close a database. - * - * @returns -1 for error; 0 for success. - **/ -_PUBLIC_ int tdb_close(struct tdb_context *tdb) -{ - struct tdb_context **i; - int ret = 0; - - if (tdb->transaction) { - tdb_transaction_cancel(tdb); - } - tdb_trace(tdb, "tdb_close"); - - if (tdb->map_ptr) { - if (tdb->flags & TDB_INTERNAL) - SAFE_FREE(tdb->map_ptr); - else - tdb_munmap(tdb); - } - - tdb_mutex_munmap(tdb); - - SAFE_FREE(tdb->name); - if (tdb->fd != -1) { - ret = close(tdb->fd); - tdb->fd = -1; - } - SAFE_FREE(tdb->lockrecs); - - /* Remove from contexts list */ - for (i = &tdbs; *i; i = &(*i)->next) { - if (*i == tdb) { - *i = tdb->next; - break; - } - } - -#ifdef TDB_TRACE - close(tdb->tracefd); -#endif - memset(tdb, 0, sizeof(*tdb)); - SAFE_FREE(tdb); - - return ret; -} - -/* register a loging function */ -_PUBLIC_ void tdb_set_logging_function(struct tdb_context *tdb, - const struct tdb_logging_context *log_ctx) -{ - tdb->log = *log_ctx; -} - -_PUBLIC_ void *tdb_get_logging_private(struct tdb_context *tdb) -{ - return tdb->log.log_private; -} - -static int tdb_reopen_internal(struct tdb_context *tdb, bool active_lock) -{ -#if !defined(LIBREPLACE_PREAD_NOT_REPLACED) || \ - !defined(LIBREPLACE_PWRITE_NOT_REPLACED) - struct stat st; -#endif - - if (tdb->flags & TDB_INTERNAL) { - return 0; /* Nothing to do. */ - } - - if (tdb_have_extra_locks(tdb)) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed with locks held\n")); - goto fail; - } - - if (tdb->transaction != 0) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed inside a transaction\n")); - goto fail; - } - -/* If we have real pread & pwrite, we can skip reopen. */ -#if !defined(LIBREPLACE_PREAD_NOT_REPLACED) || \ - !defined(LIBREPLACE_PWRITE_NOT_REPLACED) - if (tdb_munmap(tdb) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: munmap failed (%s)\n", strerror(errno))); - goto fail; - } - if (close(tdb->fd) != 0) - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: WARNING closing tdb->fd failed!\n")); - tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0); - if (tdb->fd == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: open failed (%s)\n", strerror(errno))); - goto fail; - } - /* - * We only use st.st_dev and st.st_ino from the raw fstat() - * call, everything else needs to use tdb_fstat() in order - * to skip tdb->hdr_ofs! - */ - if (fstat(tdb->fd, &st) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: fstat failed (%s)\n", strerror(errno))); - goto fail; - } - if (st.st_ino != tdb->inode || st.st_dev != tdb->device) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: file dev/inode has changed!\n")); - goto fail; - } - ZERO_STRUCT(st); - - /* - * We had tdb_mmap(tdb) here before, - * but we need to use tdb_fstat(), - * which is triggered from tdb_oob() before calling tdb_mmap(). - * As this skips tdb->hdr_ofs. - */ - tdb->map_size = 0; - if (tdb_oob(tdb, 0, 1, 0) != 0) { - goto fail; - } -#endif /* fake pread or pwrite */ - - /* We may still think we hold the active lock. */ - tdb->num_lockrecs = 0; - SAFE_FREE(tdb->lockrecs); - tdb->lockrecs_array_length = 0; - - if (active_lock && tdb_nest_lock(tdb, ACTIVE_LOCK, F_RDLCK, TDB_LOCK_WAIT) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: failed to obtain active lock\n")); - goto fail; - } - - return 0; - -fail: - tdb_close(tdb); - return -1; -} - -/* reopen a tdb - this can be used after a fork to ensure that we have an independent - seek pointer from our parent and to re-establish locks */ -_PUBLIC_ int tdb_reopen(struct tdb_context *tdb) -{ - bool active_lock; - active_lock = (tdb->flags & (TDB_CLEAR_IF_FIRST|TDB_MUTEX_LOCKING)); - - return tdb_reopen_internal(tdb, active_lock); -} - -/* reopen all tdb's */ -_PUBLIC_ int tdb_reopen_all(int parent_longlived) -{ - struct tdb_context *tdb; - - for (tdb=tdbs; tdb; tdb = tdb->next) { - bool active_lock; - - active_lock = - (tdb->flags & (TDB_CLEAR_IF_FIRST|TDB_MUTEX_LOCKING)); - - /* - * If the parent is longlived (ie. a - * parent daemon architecture), we know - * it will keep it's active lock on a - * tdb opened with CLEAR_IF_FIRST. Thus - * for child processes we don't have to - * add an active lock. This is essential - * to improve performance on systems that - * keep POSIX locks as a non-scalable data - * structure in the kernel. - */ - if (parent_longlived) { - /* Ensure no clear-if-first. */ - active_lock = false; - } - - if (tdb_reopen_internal(tdb, active_lock) != 0) - return -1; - } - - return 0; -} diff --git a/ldb-2.0.8/lib/tdb/common/rescue.c b/ldb-2.0.8/lib/tdb/common/rescue.c deleted file mode 100644 index 7a85ebc..0000000 --- a/ldb-2.0.8/lib/tdb/common/rescue.c +++ /dev/null @@ -1,351 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library, rescue attempt code. - - Copyright (C) Rusty Russell 2012 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ -#include "tdb_private.h" -#include - - -struct found { - tdb_off_t head; /* 0 -> invalid. */ - struct tdb_record rec; - TDB_DATA key; - bool in_hash; - bool in_free; -}; - -struct found_table { - /* As an ordered array (by head offset). */ - struct found *arr; - unsigned int num, max; -}; - -static bool looks_like_valid_record(struct tdb_context *tdb, - tdb_off_t off, - const struct tdb_record *rec, - TDB_DATA *key) -{ - unsigned int hval; - - if (rec->magic != TDB_MAGIC) - return false; - - if (rec->key_len + rec->data_len > rec->rec_len) - return false; - - if (rec->rec_len % TDB_ALIGNMENT) - return false; - - /* Next pointer must make some sense. */ - if (rec->next > 0 && rec->next < TDB_DATA_START(tdb->hash_size)) - return false; - - if (tdb_oob(tdb, rec->next, sizeof(*rec), 1)) - return false; - - key->dsize = rec->key_len; - key->dptr = tdb_alloc_read(tdb, off + sizeof(*rec), key->dsize); - if (!key->dptr) - return false; - - hval = tdb->hash_fn(key); - if (hval != rec->full_hash) { - free(key->dptr); - return false; - } - - /* Caller frees up key->dptr */ - return true; -} - -static bool add_to_table(struct found_table *found, - tdb_off_t off, - struct tdb_record *rec, - TDB_DATA key) -{ - if (found->num + 1 > found->max) { - struct found *new; - found->max = (found->max ? found->max * 2 : 128); - new = realloc(found->arr, found->max * sizeof(found->arr[0])); - if (!new) - return false; - found->arr = new; - } - - found->arr[found->num].head = off; - found->arr[found->num].rec = *rec; - found->arr[found->num].key = key; - found->arr[found->num].in_hash = false; - found->arr[found->num].in_free = false; - - found->num++; - return true; -} - -static bool walk_record(struct tdb_context *tdb, - const struct found *f, - void (*walk)(TDB_DATA, TDB_DATA, void *private_data), - void *private_data) -{ - TDB_DATA data; - - data.dsize = f->rec.data_len; - data.dptr = tdb_alloc_read(tdb, - f->head + sizeof(f->rec) + f->rec.key_len, - data.dsize); - if (!data.dptr) { - if (tdb->ecode == TDB_ERR_OOM) - return false; - /* I/O errors are expected. */ - return true; - } - - walk(f->key, data, private_data); - free(data.dptr); - return true; -} - -/* First entry which has offset >= this one. */ -static unsigned int find_entry(struct found_table *found, tdb_off_t off) -{ - unsigned int start = 0, end = found->num; - - while (start < end) { - /* We can't overflow here. */ - unsigned int mid = (start + end) / 2; - - if (off < found->arr[mid].head) { - end = mid; - } else if (off > found->arr[mid].head) { - start = mid + 1; - } else { - return mid; - } - } - - assert(start == end); - return end; -} - -static void found_in_hashchain(struct found_table *found, tdb_off_t head) -{ - unsigned int match; - - match = find_entry(found, head); - if (match < found->num && found->arr[match].head == head) { - found->arr[match].in_hash = true; - } -} - -static void mark_free_area(struct found_table *found, tdb_off_t head, - tdb_len_t len) -{ - unsigned int match; - - match = find_entry(found, head); - /* Mark everything within this free entry. */ - while (match < found->num) { - if (found->arr[match].head >= head + len) { - break; - } - found->arr[match].in_free = true; - match++; - } -} - -static int cmp_key(const void *a, const void *b) -{ - const struct found *fa = a, *fb = b; - - if (fa->key.dsize < fb->key.dsize) { - return -1; - } else if (fa->key.dsize > fb->key.dsize) { - return 1; - } - return memcmp(fa->key.dptr, fb->key.dptr, fa->key.dsize); -} - -static bool key_eq(TDB_DATA a, TDB_DATA b) -{ - return a.dsize == b.dsize - && memcmp(a.dptr, b.dptr, a.dsize) == 0; -} - -static void free_table(struct found_table *found) -{ - unsigned int i; - - for (i = 0; i < found->num; i++) { - free(found->arr[i].key.dptr); - } - free(found->arr); -} - -static void logging_suppressed(struct tdb_context *tdb, - enum tdb_debug_level level, const char *fmt, ...) -{ -} - -_PUBLIC_ int tdb_rescue(struct tdb_context *tdb, - void (*walk)(TDB_DATA, TDB_DATA, void *private_data), - void *private_data) -{ - struct found_table found = { NULL, 0, 0 }; - tdb_off_t h, off, i; - tdb_log_func oldlog = tdb->log.log_fn; - struct tdb_record rec; - TDB_DATA key; - bool locked; - - /* Read-only databases use no locking at all: it's best-effort. - * We may have a write lock already, so skip that case too. */ - if (tdb->read_only || tdb->allrecord_lock.count != 0) { - locked = false; - } else { - if (tdb_lockall_read(tdb) == -1) - return -1; - locked = true; - } - - /* Make sure we know true size of the underlying file. */ - tdb_oob(tdb, tdb->map_size, 1, 1); - - /* Suppress logging, since we anticipate errors. */ - tdb->log.log_fn = logging_suppressed; - - /* Now walk entire db looking for records. */ - for (off = TDB_DATA_START(tdb->hash_size); - off < tdb->map_size; - off += TDB_ALIGNMENT) { - if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), - DOCONV()) == -1) - continue; - - if (looks_like_valid_record(tdb, off, &rec, &key)) { - if (!add_to_table(&found, off, &rec, key)) { - goto oom; - } - } - } - - /* Walk hash chains to positive vet. */ - for (h = 0; h < 1+tdb->hash_size; h++) { - bool slow_chase = false; - tdb_off_t slow_off = FREELIST_TOP + h*sizeof(tdb_off_t); - - if (tdb_ofs_read(tdb, FREELIST_TOP + h*sizeof(tdb_off_t), - &off) == -1) - continue; - - while (off && off != slow_off) { - if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), - DOCONV()) != 0) { - break; - } - - /* 0 is the free list, rest are hash chains. */ - if (h == 0) { - /* Don't mark garbage as free. */ - if (rec.magic != TDB_FREE_MAGIC) { - break; - } - mark_free_area(&found, off, - sizeof(rec) + rec.rec_len); - } else { - found_in_hashchain(&found, off); - } - - off = rec.next; - - /* Loop detection using second pointer at half-speed */ - if (slow_chase) { - /* First entry happens to be next ptr */ - tdb_ofs_read(tdb, slow_off, &slow_off); - } - slow_chase = !slow_chase; - } - } - - /* Recovery area: must be marked as free, since it often has old - * records in there! */ - if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &off) == 0 && off != 0) { - if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), - DOCONV()) == 0) { - mark_free_area(&found, off, sizeof(rec) + rec.rec_len); - } - } - - /* Now sort by key! */ - if (found.arr != NULL) { - qsort(found.arr, found.num, sizeof(found.arr[0]), cmp_key); - } - - for (i = 0; (found.arr != NULL) && i < found.num; ) { - unsigned int num, num_in_hash = 0; - - /* How many are identical? */ - for (num = 0; num < found.num - i; num++) { - if (!key_eq(found.arr[i].key, found.arr[i+num].key)) { - break; - } - if (found.arr[i+num].in_hash) { - if (!walk_record(tdb, &found.arr[i+num], - walk, private_data)) - goto oom; - num_in_hash++; - } - } - assert(num); - - /* If none were in the hash, we print any not in free list. */ - if (num_in_hash == 0) { - unsigned int j; - - for (j = i; j < i + num; j++) { - if (!found.arr[j].in_free) { - if (!walk_record(tdb, &found.arr[j], - walk, private_data)) - goto oom; - } - } - } - - i += num; - } - - tdb->log.log_fn = oldlog; - if (locked) { - tdb_unlockall_read(tdb); - } - return 0; - -oom: - tdb->log.log_fn = oldlog; - tdb->ecode = TDB_ERR_OOM; - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_rescue: failed allocating\n")); - free_table(&found); - if (locked) { - tdb_unlockall_read(tdb); - } - return -1; -} diff --git a/ldb-2.0.8/lib/tdb/common/summary.c b/ldb-2.0.8/lib/tdb/common/summary.c deleted file mode 100644 index a93eb93..0000000 --- a/ldb-2.0.8/lib/tdb/common/summary.c +++ /dev/null @@ -1,219 +0,0 @@ - /* - Trivial Database: human-readable summary code - Copyright (C) Rusty Russell 2010 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ -#include "tdb_private.h" - -#define SUMMARY_FORMAT \ - "Size of file/data: %llu/%zu\n" \ - "Header offset/logical size: %zu/%zu\n" \ - "Number of records: %zu\n" \ - "Incompatible hash: %s\n" \ - "Active/supported feature flags: 0x%08x/0x%08x\n" \ - "Robust mutexes locking: %s\n" \ - "Smallest/average/largest keys: %zu/%zu/%zu\n" \ - "Smallest/average/largest data: %zu/%zu/%zu\n" \ - "Smallest/average/largest padding: %zu/%zu/%zu\n" \ - "Number of dead records: %zu\n" \ - "Smallest/average/largest dead records: %zu/%zu/%zu\n" \ - "Number of free records: %zu\n" \ - "Smallest/average/largest free records: %zu/%zu/%zu\n" \ - "Number of hash chains: %zu\n" \ - "Smallest/average/largest hash chains: %zu/%zu/%zu\n" \ - "Number of uncoalesced records: %zu\n" \ - "Smallest/average/largest uncoalesced runs: %zu/%zu/%zu\n" \ - "Percentage keys/data/padding/free/dead/rechdrs&tailers/hashes: %.0f/%.0f/%.0f/%.0f/%.0f/%.0f/%.0f\n" - -/* We don't use tally module, to keep upstream happy. */ -struct tally { - size_t min, max, total; - size_t num; -}; - -static void tally_init(struct tally *tally) -{ - tally->total = 0; - tally->num = 0; - tally->min = tally->max = 0; -} - -static void tally_add(struct tally *tally, size_t len) -{ - if (tally->num == 0) - tally->max = tally->min = len; - else if (len > tally->max) - tally->max = len; - else if (len < tally->min) - tally->min = len; - tally->num++; - tally->total += len; -} - -static size_t tally_mean(const struct tally *tally) -{ - if (!tally->num) - return 0; - return tally->total / tally->num; -} - -static size_t get_hash_length(struct tdb_context *tdb, unsigned int i) -{ - tdb_off_t rec_ptr; - struct tdb_chainwalk_ctx chainwalk; - size_t count = 0; - - if (tdb_ofs_read(tdb, TDB_HASH_TOP(i), &rec_ptr) == -1) - return 0; - - tdb_chainwalk_init(&chainwalk, rec_ptr); - - /* keep looking until we find the right record */ - while (rec_ptr) { - struct tdb_record r; - bool ok; - ++count; - if (tdb_rec_read(tdb, rec_ptr, &r) == -1) - return 0; - rec_ptr = r.next; - ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); - if (!ok) { - return SIZE_MAX; - } - } - return count; -} - -_PUBLIC_ char *tdb_summary(struct tdb_context *tdb) -{ - off_t file_size; - tdb_off_t off, rec_off; - struct tally freet, keys, data, dead, extra, hashval, uncoal; - struct tdb_record rec; - char *ret = NULL; - bool locked; - size_t unc = 0; - int len; - struct tdb_record recovery; - - /* Read-only databases use no locking at all: it's best-effort. - * We may have a write lock already, so skip that case too. */ - if (tdb->read_only || tdb->allrecord_lock.count != 0) { - locked = false; - } else { - if (tdb_lockall_read(tdb) == -1) - return NULL; - locked = true; - } - - if (tdb_recovery_area(tdb, tdb->methods, &rec_off, &recovery) != 0) { - goto unlock; - } - - tally_init(&freet); - tally_init(&keys); - tally_init(&data); - tally_init(&dead); - tally_init(&extra); - tally_init(&hashval); - tally_init(&uncoal); - - for (off = TDB_DATA_START(tdb->hash_size); - off < tdb->map_size - 1; - off += sizeof(rec) + rec.rec_len) { - if (tdb->methods->tdb_read(tdb, off, &rec, sizeof(rec), - DOCONV()) == -1) - goto unlock; - switch (rec.magic) { - case TDB_MAGIC: - tally_add(&keys, rec.key_len); - tally_add(&data, rec.data_len); - tally_add(&extra, rec.rec_len - (rec.key_len - + rec.data_len)); - if (unc > 1) - tally_add(&uncoal, unc - 1); - unc = 0; - break; - case TDB_FREE_MAGIC: - tally_add(&freet, rec.rec_len); - unc++; - break; - /* If we crash after ftruncate, we can get zeroes or fill. */ - case TDB_RECOVERY_INVALID_MAGIC: - case 0x42424242: - unc++; - /* If it's a valid recovery, we can trust rec_len. */ - if (off != rec_off) { - rec.rec_len = tdb_dead_space(tdb, off) - - sizeof(rec); - } - - FALL_THROUGH; - case TDB_DEAD_MAGIC: - tally_add(&dead, rec.rec_len); - break; - default: - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "Unexpected record magic 0x%x at offset %u\n", - rec.magic, off)); - goto unlock; - } - } - if (unc > 1) - tally_add(&uncoal, unc - 1); - - for (off = 0; off < tdb->hash_size; off++) - tally_add(&hashval, get_hash_length(tdb, off)); - - file_size = tdb->hdr_ofs + tdb->map_size; - - len = asprintf(&ret, SUMMARY_FORMAT, - (unsigned long long)file_size, keys.total+data.total, - (size_t)tdb->hdr_ofs, (size_t)tdb->map_size, - keys.num, - (tdb->hash_fn == tdb_jenkins_hash)?"yes":"no", - (unsigned)tdb->feature_flags, TDB_SUPPORTED_FEATURE_FLAGS, - (tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX)?"yes":"no", - keys.min, tally_mean(&keys), keys.max, - data.min, tally_mean(&data), data.max, - extra.min, tally_mean(&extra), extra.max, - dead.num, - dead.min, tally_mean(&dead), dead.max, - freet.num, - freet.min, tally_mean(&freet), freet.max, - hashval.num, - hashval.min, tally_mean(&hashval), hashval.max, - uncoal.total, - uncoal.min, tally_mean(&uncoal), uncoal.max, - keys.total * 100.0 / file_size, - data.total * 100.0 / file_size, - extra.total * 100.0 / file_size, - freet.total * 100.0 / file_size, - dead.total * 100.0 / file_size, - (keys.num + freet.num + dead.num) - * (sizeof(struct tdb_record) + sizeof(uint32_t)) - * 100.0 / file_size, - tdb->hash_size * sizeof(tdb_off_t) - * 100.0 / file_size); - if (len == -1) { - goto unlock; - } - -unlock: - if (locked) { - tdb_unlockall_read(tdb); - } - return ret; -} diff --git a/ldb-2.0.8/lib/tdb/common/tdb.c b/ldb-2.0.8/lib/tdb/common/tdb.c deleted file mode 100644 index c56b37b..0000000 --- a/ldb-2.0.8/lib/tdb/common/tdb.c +++ /dev/null @@ -1,1324 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "tdb_private.h" - -_PUBLIC_ TDB_DATA tdb_null; - -/* - non-blocking increment of the tdb sequence number if the tdb has been opened using - the TDB_SEQNUM flag -*/ -_PUBLIC_ void tdb_increment_seqnum_nonblock(struct tdb_context *tdb) -{ - tdb_off_t seqnum=0; - - if (!(tdb->flags & TDB_SEQNUM)) { - return; - } - - /* we ignore errors from this, as we have no sane way of - dealing with them. - */ - tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum); - seqnum++; - tdb_ofs_write(tdb, TDB_SEQNUM_OFS, &seqnum); -} - -/* - increment the tdb sequence number if the tdb has been opened using - the TDB_SEQNUM flag -*/ -static void tdb_increment_seqnum(struct tdb_context *tdb) -{ - if (!(tdb->flags & TDB_SEQNUM)) { - return; - } - - if (tdb->transaction != NULL) { - tdb_increment_seqnum_nonblock(tdb); - return; - } - - if (tdb_nest_lock(tdb, TDB_SEQNUM_OFS, F_WRLCK, - TDB_LOCK_WAIT|TDB_LOCK_PROBE) != 0) { - return; - } - - tdb_increment_seqnum_nonblock(tdb); - - tdb_nest_unlock(tdb, TDB_SEQNUM_OFS, F_WRLCK, false); -} - -static int tdb_key_compare(TDB_DATA key, TDB_DATA data, void *private_data) -{ - return memcmp(data.dptr, key.dptr, data.dsize); -} - -void tdb_chainwalk_init(struct tdb_chainwalk_ctx *ctx, tdb_off_t ptr) -{ - *ctx = (struct tdb_chainwalk_ctx) { .slow_ptr = ptr }; -} - -bool tdb_chainwalk_check(struct tdb_context *tdb, - struct tdb_chainwalk_ctx *ctx, - tdb_off_t next_ptr) -{ - int ret; - - if (ctx->slow_chase) { - ret = tdb_ofs_read(tdb, ctx->slow_ptr, &ctx->slow_ptr); - if (ret == -1) { - return false; - } - } - ctx->slow_chase = !ctx->slow_chase; - - if (next_ptr == ctx->slow_ptr) { - tdb->ecode = TDB_ERR_CORRUPT; - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "tdb_chainwalk_check: circular chain\n")); - return false; - } - - return true; -} - -/* Returns 0 on fail. On success, return offset of record, and fills - in rec */ -static tdb_off_t tdb_find(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, - struct tdb_record *r) -{ - tdb_off_t rec_ptr; - struct tdb_chainwalk_ctx chainwalk; - - /* read in the hash top */ - if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) - return 0; - - tdb_chainwalk_init(&chainwalk, rec_ptr); - - /* keep looking until we find the right record */ - while (rec_ptr) { - bool ok; - - if (tdb_rec_read(tdb, rec_ptr, r) == -1) - return 0; - - if (!TDB_DEAD(r) && hash==r->full_hash - && key.dsize==r->key_len - && tdb_parse_data(tdb, key, rec_ptr + sizeof(*r), - r->key_len, tdb_key_compare, - NULL) == 0) { - return rec_ptr; - } - rec_ptr = r->next; - - ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); - if (!ok) { - return 0; - } - } - tdb->ecode = TDB_ERR_NOEXIST; - return 0; -} - -/* As tdb_find, but if you succeed, keep the lock */ -tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype, - struct tdb_record *rec) -{ - uint32_t rec_ptr; - - if (tdb_lock(tdb, BUCKET(hash), locktype) == -1) - return 0; - if (!(rec_ptr = tdb_find(tdb, key, hash, rec))) - tdb_unlock(tdb, BUCKET(hash), locktype); - return rec_ptr; -} - -static TDB_DATA _tdb_fetch(struct tdb_context *tdb, TDB_DATA key); - -struct tdb_update_hash_state { - const TDB_DATA *dbufs; - int num_dbufs; - tdb_len_t dbufs_len; -}; - -static int tdb_update_hash_cmp(TDB_DATA key, TDB_DATA data, void *private_data) -{ - struct tdb_update_hash_state *state = private_data; - unsigned char *dptr = data.dptr; - int i; - - if (state->dbufs_len != data.dsize) { - return -1; - } - - for (i=0; inum_dbufs; i++) { - TDB_DATA dbuf = state->dbufs[i]; - if( dbuf.dsize > 0) { - int ret; - ret = memcmp(dptr, dbuf.dptr, dbuf.dsize); - if (ret != 0) { - return -1; - } - dptr += dbuf.dsize; - } - } - - return 0; -} - -/* update an entry in place - this only works if the new data size - is <= the old data size and the key exists. - on failure return -1. -*/ -static int tdb_update_hash(struct tdb_context *tdb, TDB_DATA key, - uint32_t hash, - const TDB_DATA *dbufs, int num_dbufs, - tdb_len_t dbufs_len) -{ - struct tdb_record rec; - tdb_off_t rec_ptr, ofs; - int i; - - /* find entry */ - if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) - return -1; - - /* it could be an exact duplicate of what is there - this is - * surprisingly common (eg. with a ldb re-index). */ - if (rec.data_len == dbufs_len) { - struct tdb_update_hash_state state = { - .dbufs = dbufs, .num_dbufs = num_dbufs, - .dbufs_len = dbufs_len - }; - int ret; - - ret = tdb_parse_record(tdb, key, tdb_update_hash_cmp, &state); - if (ret == 0) { - return 0; - } - } - - /* must be long enough key, data and tailer */ - if (rec.rec_len < key.dsize + dbufs_len + sizeof(tdb_off_t)) { - tdb->ecode = TDB_SUCCESS; /* Not really an error */ - return -1; - } - - ofs = rec_ptr + sizeof(rec) + rec.key_len; - - for (i=0; imethods->tdb_write(tdb, ofs, dbuf.dptr, dbuf.dsize); - if (ret == -1) { - return -1; - } - ofs += dbuf.dsize; - } - - if (dbufs_len != rec.data_len) { - /* update size */ - rec.data_len = dbufs_len; - return tdb_rec_write(tdb, rec_ptr, &rec); - } - - return 0; -} - -/* find an entry in the database given a key */ -/* If an entry doesn't exist tdb_err will be set to - * TDB_ERR_NOEXIST. If a key has no data attached - * then the TDB_DATA will have zero length but - * a non-zero pointer - */ -static TDB_DATA _tdb_fetch(struct tdb_context *tdb, TDB_DATA key) -{ - tdb_off_t rec_ptr; - struct tdb_record rec; - TDB_DATA ret; - uint32_t hash; - - /* find which hash bucket it is in */ - hash = tdb->hash_fn(&key); - if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) - return tdb_null; - - ret.dptr = tdb_alloc_read(tdb, rec_ptr + sizeof(rec) + rec.key_len, - rec.data_len); - ret.dsize = rec.data_len; - tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); - return ret; -} - -_PUBLIC_ TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key) -{ - TDB_DATA ret = _tdb_fetch(tdb, key); - - tdb_trace_1rec_retrec(tdb, "tdb_fetch", key, ret); - return ret; -} - -/* - * Find an entry in the database and hand the record's data to a parsing - * function. The parsing function is executed under the chain read lock, so it - * should be fast and should not block on other syscalls. - * - * DON'T CALL OTHER TDB CALLS FROM THE PARSER, THIS MIGHT LEAD TO SEGFAULTS. - * - * For mmapped tdb's that do not have a transaction open it points the parsing - * function directly at the mmap area, it avoids the malloc/memcpy in this - * case. If a transaction is open or no mmap is available, it has to do - * malloc/read/parse/free. - * - * This is interesting for all readers of potentially large data structures in - * the tdb records, ldb indexes being one example. - * - * Return -1 if the record was not found. - */ - -_PUBLIC_ int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, - int (*parser)(TDB_DATA key, TDB_DATA data, - void *private_data), - void *private_data) -{ - tdb_off_t rec_ptr; - struct tdb_record rec; - int ret; - uint32_t hash; - - /* find which hash bucket it is in */ - hash = tdb->hash_fn(&key); - - if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) { - /* record not found */ - tdb_trace_1rec_ret(tdb, "tdb_parse_record", key, -1); - tdb->ecode = TDB_ERR_NOEXIST; - return -1; - } - tdb_trace_1rec_ret(tdb, "tdb_parse_record", key, 0); - - ret = tdb_parse_data(tdb, key, rec_ptr + sizeof(rec) + rec.key_len, - rec.data_len, parser, private_data); - - tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); - - return ret; -} - -/* check if an entry in the database exists - - note that 1 is returned if the key is found and 0 is returned if not found - this doesn't match the conventions in the rest of this module, but is - compatible with gdbm -*/ -static int tdb_exists_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash) -{ - struct tdb_record rec; - - if (tdb_find_lock_hash(tdb, key, hash, F_RDLCK, &rec) == 0) - return 0; - tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); - return 1; -} - -_PUBLIC_ int tdb_exists(struct tdb_context *tdb, TDB_DATA key) -{ - uint32_t hash = tdb->hash_fn(&key); - int ret; - - ret = tdb_exists_hash(tdb, key, hash); - tdb_trace_1rec_ret(tdb, "tdb_exists", key, ret); - return ret; -} - -/* - * Move a dead record to the freelist. The hash chain and freelist - * must be locked. - */ -static int tdb_del_dead(struct tdb_context *tdb, - uint32_t last_ptr, - uint32_t rec_ptr, - struct tdb_record *rec, - bool *deleted) -{ - int ret; - - ret = tdb_write_lock_record(tdb, rec_ptr); - if (ret == -1) { - /* Someone traversing here: Just leave it dead */ - return 0; - } - ret = tdb_write_unlock_record(tdb, rec_ptr); - if (ret == -1) { - return -1; - } - ret = tdb_ofs_write(tdb, last_ptr, &rec->next); - if (ret == -1) { - return -1; - } - - *deleted = true; - - ret = tdb_free(tdb, rec_ptr, rec); - return ret; -} - -/* - * Walk the hash chain and leave tdb->max_dead_records around. Move - * the rest of dead records to the freelist. - */ -int tdb_trim_dead(struct tdb_context *tdb, uint32_t hash) -{ - struct tdb_chainwalk_ctx chainwalk; - struct tdb_record rec; - tdb_off_t last_ptr, rec_ptr; - bool locked_freelist = false; - int num_dead = 0; - int ret; - - last_ptr = TDB_HASH_TOP(hash); - - /* - * Init chainwalk with the pointer to the hash top. It might - * be that the very first record in the chain is a dead one - * that we have to delete. - */ - tdb_chainwalk_init(&chainwalk, last_ptr); - - ret = tdb_ofs_read(tdb, last_ptr, &rec_ptr); - if (ret == -1) { - return -1; - } - - while (rec_ptr != 0) { - bool deleted = false; - uint32_t next; - - ret = tdb_rec_read(tdb, rec_ptr, &rec); - if (ret == -1) { - goto fail; - } - - /* - * Make a copy of rec.next: Further down we might - * delete and put the record on the freelist. Make - * sure that modifications in that code path can't - * break the chainwalk here. - */ - next = rec.next; - - if (rec.magic == TDB_DEAD_MAGIC) { - num_dead += 1; - - if (num_dead > tdb->max_dead_records) { - - if (!locked_freelist) { - /* - * Lock the freelist only if - * it's really required. - */ - ret = tdb_lock(tdb, -1, F_WRLCK); - if (ret == -1) { - goto fail; - }; - locked_freelist = true; - } - - ret = tdb_del_dead( - tdb, - last_ptr, - rec_ptr, - &rec, - &deleted); - - if (ret == -1) { - goto fail; - } - } - } - - /* - * Don't do the chainwalk check if "rec_ptr" was - * deleted. We reduced the chain, and the chainwalk - * check might catch up early. Imagine a valid chain - * with just dead records: We never can bump the - * "slow" pointer in chainwalk_check, as there isn't - * anything left to jump to and compare. - */ - if (!deleted) { - bool ok; - - last_ptr = rec_ptr; - - ok = tdb_chainwalk_check(tdb, &chainwalk, next); - if (!ok) { - ret = -1; - goto fail; - } - } - rec_ptr = next; - } - ret = 0; -fail: - if (locked_freelist) { - tdb_unlock(tdb, -1, F_WRLCK); - } - return ret; -} - -/* delete an entry in the database given a key */ -static int tdb_delete_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash) -{ - tdb_off_t rec_ptr; - struct tdb_record rec; - int ret; - - if (tdb->read_only || tdb->traverse_read) { - tdb->ecode = TDB_ERR_RDONLY; - return -1; - } - - rec_ptr = tdb_find_lock_hash(tdb, key, hash, F_WRLCK, &rec); - if (rec_ptr == 0) { - return -1; - } - - /* - * Mark the record dead - */ - rec.magic = TDB_DEAD_MAGIC; - ret = tdb_rec_write(tdb, rec_ptr, &rec); - if (ret == -1) { - goto done; - } - - tdb_increment_seqnum(tdb); - - ret = tdb_trim_dead(tdb, hash); -done: - if (tdb_unlock(tdb, BUCKET(hash), F_WRLCK) != 0) - TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_delete: WARNING tdb_unlock failed!\n")); - return ret; -} - -_PUBLIC_ int tdb_delete(struct tdb_context *tdb, TDB_DATA key) -{ - uint32_t hash = tdb->hash_fn(&key); - int ret; - - ret = tdb_delete_hash(tdb, key, hash); - tdb_trace_1rec_ret(tdb, "tdb_delete", key, ret); - return ret; -} - -/* - * See if we have a dead record around with enough space - */ -tdb_off_t tdb_find_dead(struct tdb_context *tdb, uint32_t hash, - struct tdb_record *r, tdb_len_t length, - tdb_off_t *p_last_ptr) -{ - tdb_off_t rec_ptr, last_ptr; - struct tdb_chainwalk_ctx chainwalk; - tdb_off_t best_rec_ptr = 0; - tdb_off_t best_last_ptr = 0; - struct tdb_record best = { .rec_len = UINT32_MAX }; - - length += sizeof(tdb_off_t); /* tailer */ - - last_ptr = TDB_HASH_TOP(hash); - - /* read in the hash top */ - if (tdb_ofs_read(tdb, last_ptr, &rec_ptr) == -1) - return 0; - - tdb_chainwalk_init(&chainwalk, rec_ptr); - - /* keep looking until we find the right record */ - while (rec_ptr) { - bool ok; - - if (tdb_rec_read(tdb, rec_ptr, r) == -1) - return 0; - - if (TDB_DEAD(r) && (r->rec_len >= length) && - (r->rec_len < best.rec_len)) { - best_rec_ptr = rec_ptr; - best_last_ptr = last_ptr; - best = *r; - } - last_ptr = rec_ptr; - rec_ptr = r->next; - - ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); - if (!ok) { - return 0; - } - } - - if (best.rec_len == UINT32_MAX) { - return 0; - } - - *r = best; - *p_last_ptr = best_last_ptr; - return best_rec_ptr; -} - -static int _tdb_storev(struct tdb_context *tdb, TDB_DATA key, - const TDB_DATA *dbufs, int num_dbufs, - int flag, uint32_t hash) -{ - struct tdb_record rec; - tdb_off_t rec_ptr, ofs; - tdb_len_t rec_len, dbufs_len; - int i; - int ret = -1; - - dbufs_len = 0; - - for (i=0; iecode = TDB_ERR_EINVAL; - goto fail; - } - - dbufs_len += dsize; - if (dbufs_len < dsize) { - tdb->ecode = TDB_ERR_OOM; - goto fail; - } - } - - rec_len = key.dsize + dbufs_len; - if ((rec_len < key.dsize) || (rec_len < dbufs_len)) { - tdb->ecode = TDB_ERR_OOM; - goto fail; - } - - /* check for it existing, on insert. */ - if (flag == TDB_INSERT) { - if (tdb_exists_hash(tdb, key, hash)) { - tdb->ecode = TDB_ERR_EXISTS; - goto fail; - } - } else { - /* first try in-place update, on modify or replace. */ - if (tdb_update_hash(tdb, key, hash, dbufs, num_dbufs, - dbufs_len) == 0) { - goto done; - } - if (tdb->ecode == TDB_ERR_NOEXIST && - flag == TDB_MODIFY) { - /* if the record doesn't exist and we are in TDB_MODIFY mode then - we should fail the store */ - goto fail; - } - } - /* reset the error code potentially set by the tdb_update_hash() */ - tdb->ecode = TDB_SUCCESS; - - /* delete any existing record - if it doesn't exist we don't - care. Doing this first reduces fragmentation, and avoids - coalescing with `allocated' block before it's updated. */ - if (flag != TDB_INSERT) - tdb_delete_hash(tdb, key, hash); - - /* we have to allocate some space */ - rec_ptr = tdb_allocate(tdb, hash, rec_len, &rec); - - if (rec_ptr == 0) { - goto fail; - } - - /* Read hash top into next ptr */ - if (tdb_ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1) - goto fail; - - rec.key_len = key.dsize; - rec.data_len = dbufs_len; - rec.full_hash = hash; - rec.magic = TDB_MAGIC; - - ofs = rec_ptr; - - /* write out and point the top of the hash chain at it */ - ret = tdb_rec_write(tdb, ofs, &rec); - if (ret == -1) { - goto fail; - } - ofs += sizeof(rec); - - ret = tdb->methods->tdb_write(tdb, ofs, key.dptr, key.dsize); - if (ret == -1) { - goto fail; - } - ofs += key.dsize; - - for (i=0; imethods->tdb_write(tdb, ofs, dbufs[i].dptr, - dbufs[i].dsize); - if (ret == -1) { - goto fail; - } - ofs += dbufs[i].dsize; - } - - ret = tdb_ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr); - if (ret == -1) { - /* Need to tdb_unallocate() here */ - goto fail; - } - - done: - ret = 0; - fail: - if (ret == 0) { - tdb_increment_seqnum(tdb); - } - return ret; -} - -static int _tdb_store(struct tdb_context *tdb, TDB_DATA key, - TDB_DATA dbuf, int flag, uint32_t hash) -{ - return _tdb_storev(tdb, key, &dbuf, 1, flag, hash); -} - -/* store an element in the database, replacing any existing element - with the same key - - return 0 on success, -1 on failure -*/ -_PUBLIC_ int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) -{ - uint32_t hash; - int ret; - - if (tdb->read_only || tdb->traverse_read) { - tdb->ecode = TDB_ERR_RDONLY; - tdb_trace_2rec_flag_ret(tdb, "tdb_store", key, dbuf, flag, -1); - return -1; - } - - /* find which hash bucket it is in */ - hash = tdb->hash_fn(&key); - if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) - return -1; - - ret = _tdb_store(tdb, key, dbuf, flag, hash); - tdb_trace_2rec_flag_ret(tdb, "tdb_store", key, dbuf, flag, ret); - tdb_unlock(tdb, BUCKET(hash), F_WRLCK); - return ret; -} - -_PUBLIC_ int tdb_storev(struct tdb_context *tdb, TDB_DATA key, - const TDB_DATA *dbufs, int num_dbufs, int flag) -{ - uint32_t hash; - int ret; - - if (tdb->read_only || tdb->traverse_read) { - tdb->ecode = TDB_ERR_RDONLY; - tdb_trace_1plusn_rec_flag_ret(tdb, "tdb_storev", key, - dbufs, num_dbufs, flag, -1); - return -1; - } - - /* find which hash bucket it is in */ - hash = tdb->hash_fn(&key); - if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) - return -1; - - ret = _tdb_storev(tdb, key, dbufs, num_dbufs, flag, hash); - tdb_trace_1plusn_rec_flag_ret(tdb, "tdb_storev", key, - dbufs, num_dbufs, flag, -1); - tdb_unlock(tdb, BUCKET(hash), F_WRLCK); - return ret; -} - -/* Append to an entry. Create if not exist. */ -_PUBLIC_ int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf) -{ - uint32_t hash; - TDB_DATA dbufs[2]; - int ret = -1; - - /* find which hash bucket it is in */ - hash = tdb->hash_fn(&key); - if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) - return -1; - - dbufs[0] = _tdb_fetch(tdb, key); - dbufs[1] = new_dbuf; - - ret = _tdb_storev(tdb, key, dbufs, 2, 0, hash); - tdb_trace_2rec_retrec(tdb, "tdb_append", key, dbufs[0], dbufs[1]); - - tdb_unlock(tdb, BUCKET(hash), F_WRLCK); - SAFE_FREE(dbufs[0].dptr); - return ret; -} - - -/* - return the name of the current tdb file - useful for external logging functions -*/ -_PUBLIC_ const char *tdb_name(struct tdb_context *tdb) -{ - return tdb->name; -} - -/* - return the underlying file descriptor being used by tdb, or -1 - useful for external routines that want to check the device/inode - of the fd -*/ -_PUBLIC_ int tdb_fd(struct tdb_context *tdb) -{ - return tdb->fd; -} - -/* - return the current logging function - useful for external tdb routines that wish to log tdb errors -*/ -_PUBLIC_ tdb_log_func tdb_log_fn(struct tdb_context *tdb) -{ - return tdb->log.log_fn; -} - - -/* - get the tdb sequence number. Only makes sense if the writers opened - with TDB_SEQNUM set. Note that this sequence number will wrap quite - quickly, so it should only be used for a 'has something changed' - test, not for code that relies on the count of the number of changes - made. If you want a counter then use a tdb record. - - The aim of this sequence number is to allow for a very lightweight - test of a possible tdb change. -*/ -_PUBLIC_ int tdb_get_seqnum(struct tdb_context *tdb) -{ - tdb_off_t seqnum=0; - - tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum); - return seqnum; -} - -_PUBLIC_ int tdb_hash_size(struct tdb_context *tdb) -{ - return tdb->hash_size; -} - -_PUBLIC_ size_t tdb_map_size(struct tdb_context *tdb) -{ - return tdb->map_size; -} - -_PUBLIC_ int tdb_get_flags(struct tdb_context *tdb) -{ - return tdb->flags; -} - -_PUBLIC_ void tdb_add_flags(struct tdb_context *tdb, unsigned flags) -{ - if ((flags & TDB_ALLOW_NESTING) && - (flags & TDB_DISALLOW_NESTING)) { - tdb->ecode = TDB_ERR_NESTING; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_add_flags: " - "allow_nesting and disallow_nesting are not allowed together!")); - return; - } - - if (flags & TDB_ALLOW_NESTING) { - tdb->flags &= ~TDB_DISALLOW_NESTING; - } - if (flags & TDB_DISALLOW_NESTING) { - tdb->flags &= ~TDB_ALLOW_NESTING; - } - - tdb->flags |= flags; -} - -_PUBLIC_ void tdb_remove_flags(struct tdb_context *tdb, unsigned flags) -{ - if ((flags & TDB_ALLOW_NESTING) && - (flags & TDB_DISALLOW_NESTING)) { - tdb->ecode = TDB_ERR_NESTING; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_remove_flags: " - "allow_nesting and disallow_nesting are not allowed together!")); - return; - } - - if ((flags & TDB_NOLOCK) && - (tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) && - (tdb->mutexes == NULL)) { - tdb->ecode = TDB_ERR_LOCK; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_remove_flags: " - "Can not remove NOLOCK flag on mutexed databases")); - return; - } - - if (flags & TDB_ALLOW_NESTING) { - tdb->flags |= TDB_DISALLOW_NESTING; - } - if (flags & TDB_DISALLOW_NESTING) { - tdb->flags |= TDB_ALLOW_NESTING; - } - - tdb->flags &= ~flags; -} - - -/* - enable sequence number handling on an open tdb -*/ -_PUBLIC_ void tdb_enable_seqnum(struct tdb_context *tdb) -{ - tdb->flags |= TDB_SEQNUM; -} - - -/* - add a region of the file to the freelist. Length is the size of the region in bytes, - which includes the free list header that needs to be added - */ -static int tdb_free_region(struct tdb_context *tdb, tdb_off_t offset, ssize_t length) -{ - struct tdb_record rec; - if (length <= sizeof(rec)) { - /* the region is not worth adding */ - return 0; - } - if (length + offset > tdb->map_size) { - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_free_region: adding region beyond end of file\n")); - return -1; - } - memset(&rec,'\0',sizeof(rec)); - rec.rec_len = length - sizeof(rec); - if (tdb_free(tdb, offset, &rec) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_free_region: failed to add free record\n")); - return -1; - } - return 0; -} - -/* - wipe the entire database, deleting all records. This can be done - very fast by using a allrecord lock. The entire data portion of the - file becomes a single entry in the freelist. - - This code carefully steps around the recovery area, leaving it alone - */ -_PUBLIC_ int tdb_wipe_all(struct tdb_context *tdb) -{ - uint32_t i; - tdb_off_t offset = 0; - ssize_t data_len; - tdb_off_t recovery_head; - tdb_len_t recovery_size = 0; - - if (tdb_lockall(tdb) != 0) { - return -1; - } - - tdb_trace(tdb, "tdb_wipe_all"); - - /* see if the tdb has a recovery area, and remember its size - if so. We don't want to lose this as otherwise each - tdb_wipe_all() in a transaction will increase the size of - the tdb by the size of the recovery area */ - if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_wipe_all: failed to read recovery head\n")); - goto failed; - } - - if (recovery_head != 0) { - struct tdb_record rec; - if (tdb->methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_wipe_all: failed to read recovery record\n")); - return -1; - } - recovery_size = rec.rec_len + sizeof(rec); - } - - /* wipe the hashes */ - for (i=0;ihash_size;i++) { - if (tdb_ofs_write(tdb, TDB_HASH_TOP(i), &offset) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write hash %d\n", i)); - goto failed; - } - } - - /* wipe the freelist */ - if (tdb_ofs_write(tdb, FREELIST_TOP, &offset) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write freelist\n")); - goto failed; - } - - /* add all the rest of the file to the freelist, possibly leaving a gap - for the recovery area */ - if (recovery_size == 0) { - /* the simple case - the whole file can be used as a freelist */ - data_len = (tdb->map_size - TDB_DATA_START(tdb->hash_size)); - if (tdb_free_region(tdb, TDB_DATA_START(tdb->hash_size), data_len) != 0) { - goto failed; - } - } else { - /* we need to add two freelist entries - one on either - side of the recovery area - - Note that we cannot shift the recovery area during - this operation. Only the transaction.c code may - move the recovery area or we risk subtle data - corruption - */ - data_len = (recovery_head - TDB_DATA_START(tdb->hash_size)); - if (tdb_free_region(tdb, TDB_DATA_START(tdb->hash_size), data_len) != 0) { - goto failed; - } - /* and the 2nd free list entry after the recovery area - if any */ - data_len = tdb->map_size - (recovery_head+recovery_size); - if (tdb_free_region(tdb, recovery_head+recovery_size, data_len) != 0) { - goto failed; - } - } - - tdb_increment_seqnum_nonblock(tdb); - - if (tdb_unlockall(tdb) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to unlock\n")); - goto failed; - } - - return 0; - -failed: - tdb_unlockall(tdb); - return -1; -} - -struct traverse_state { - bool error; - struct tdb_context *dest_db; -}; - -/* - traverse function for repacking - */ -static int repack_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *private_data) -{ - struct traverse_state *state = (struct traverse_state *)private_data; - if (tdb_store(state->dest_db, key, data, TDB_INSERT) != 0) { - state->error = true; - return -1; - } - return 0; -} - -/* - repack a tdb - */ -_PUBLIC_ int tdb_repack(struct tdb_context *tdb) -{ - struct tdb_context *tmp_db; - struct traverse_state state; - - tdb_trace(tdb, "tdb_repack"); - - if (tdb_transaction_start(tdb) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to start transaction\n")); - return -1; - } - - tmp_db = tdb_open("tmpdb", tdb_hash_size(tdb), TDB_INTERNAL, O_RDWR|O_CREAT, 0); - if (tmp_db == NULL) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to create tmp_db\n")); - tdb_transaction_cancel(tdb); - return -1; - } - - state.error = false; - state.dest_db = tmp_db; - - if (tdb_traverse_read(tdb, repack_traverse, &state) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to traverse copying out\n")); - tdb_transaction_cancel(tdb); - tdb_close(tmp_db); - return -1; - } - - if (state.error) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Error during traversal\n")); - tdb_transaction_cancel(tdb); - tdb_close(tmp_db); - return -1; - } - - if (tdb_wipe_all(tdb) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to wipe database\n")); - tdb_transaction_cancel(tdb); - tdb_close(tmp_db); - return -1; - } - - state.error = false; - state.dest_db = tdb; - - if (tdb_traverse_read(tmp_db, repack_traverse, &state) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to traverse copying back\n")); - tdb_transaction_cancel(tdb); - tdb_close(tmp_db); - return -1; - } - - if (state.error) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Error during second traversal\n")); - tdb_transaction_cancel(tdb); - tdb_close(tmp_db); - return -1; - } - - tdb_close(tmp_db); - - if (tdb_transaction_commit(tdb) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, __location__ " Failed to commit\n")); - return -1; - } - - return 0; -} - -/* Even on files, we can get partial writes due to signals. */ -bool tdb_write_all(int fd, const void *buf, size_t count) -{ - while (count) { - ssize_t ret; - ret = write(fd, buf, count); - if (ret < 0) - return false; - buf = (const char *)buf + ret; - count -= ret; - } - return true; -} - -bool tdb_add_off_t(tdb_off_t a, tdb_off_t b, tdb_off_t *pret) -{ - tdb_off_t ret = a + b; - - if ((ret < a) || (ret < b)) { - return false; - } - *pret = ret; - return true; -} - -#ifdef TDB_TRACE -static void tdb_trace_write(struct tdb_context *tdb, const char *str) -{ - if (!tdb_write_all(tdb->tracefd, str, strlen(str))) { - close(tdb->tracefd); - tdb->tracefd = -1; - } -} - -static void tdb_trace_start(struct tdb_context *tdb) -{ - tdb_off_t seqnum=0; - char msg[sizeof(tdb_off_t) * 4 + 1]; - - tdb_ofs_read(tdb, TDB_SEQNUM_OFS, &seqnum); - snprintf(msg, sizeof(msg), "%u ", seqnum); - tdb_trace_write(tdb, msg); -} - -static void tdb_trace_end(struct tdb_context *tdb) -{ - tdb_trace_write(tdb, "\n"); -} - -static void tdb_trace_end_ret(struct tdb_context *tdb, int ret) -{ - char msg[sizeof(ret) * 4 + 4]; - snprintf(msg, sizeof(msg), " = %i\n", ret); - tdb_trace_write(tdb, msg); -} - -static void tdb_trace_record(struct tdb_context *tdb, TDB_DATA rec) -{ - char msg[20 + rec.dsize*2], *p; - unsigned int i; - - /* We differentiate zero-length records from non-existent ones. */ - if (rec.dptr == NULL) { - tdb_trace_write(tdb, " NULL"); - return; - } - - /* snprintf here is purely cargo-cult programming. */ - p = msg; - p += snprintf(p, sizeof(msg), " %zu:", rec.dsize); - for (i = 0; i < rec.dsize; i++) - p += snprintf(p, 2, "%02x", rec.dptr[i]); - - tdb_trace_write(tdb, msg); -} - -void tdb_trace(struct tdb_context *tdb, const char *op) -{ - tdb_trace_start(tdb); - tdb_trace_write(tdb, op); - tdb_trace_end(tdb); -} - -void tdb_trace_seqnum(struct tdb_context *tdb, uint32_t seqnum, const char *op) -{ - char msg[sizeof(tdb_off_t) * 4 + 1]; - - snprintf(msg, sizeof(msg), "%u ", seqnum); - tdb_trace_write(tdb, msg); - tdb_trace_write(tdb, op); - tdb_trace_end(tdb); -} - -void tdb_trace_open(struct tdb_context *tdb, const char *op, - unsigned hash_size, unsigned tdb_flags, unsigned open_flags) -{ - char msg[128]; - - snprintf(msg, sizeof(msg), - "%s %u 0x%x 0x%x", op, hash_size, tdb_flags, open_flags); - tdb_trace_start(tdb); - tdb_trace_write(tdb, msg); - tdb_trace_end(tdb); -} - -void tdb_trace_ret(struct tdb_context *tdb, const char *op, int ret) -{ - tdb_trace_start(tdb); - tdb_trace_write(tdb, op); - tdb_trace_end_ret(tdb, ret); -} - -void tdb_trace_retrec(struct tdb_context *tdb, const char *op, TDB_DATA ret) -{ - tdb_trace_start(tdb); - tdb_trace_write(tdb, op); - tdb_trace_write(tdb, " ="); - tdb_trace_record(tdb, ret); - tdb_trace_end(tdb); -} - -void tdb_trace_1rec(struct tdb_context *tdb, const char *op, - TDB_DATA rec) -{ - tdb_trace_start(tdb); - tdb_trace_write(tdb, op); - tdb_trace_record(tdb, rec); - tdb_trace_end(tdb); -} - -void tdb_trace_1rec_ret(struct tdb_context *tdb, const char *op, - TDB_DATA rec, int ret) -{ - tdb_trace_start(tdb); - tdb_trace_write(tdb, op); - tdb_trace_record(tdb, rec); - tdb_trace_end_ret(tdb, ret); -} - -void tdb_trace_1rec_retrec(struct tdb_context *tdb, const char *op, - TDB_DATA rec, TDB_DATA ret) -{ - tdb_trace_start(tdb); - tdb_trace_write(tdb, op); - tdb_trace_record(tdb, rec); - tdb_trace_write(tdb, " ="); - tdb_trace_record(tdb, ret); - tdb_trace_end(tdb); -} - -void tdb_trace_2rec_flag_ret(struct tdb_context *tdb, const char *op, - TDB_DATA rec1, TDB_DATA rec2, unsigned flag, - int ret) -{ - char msg[1 + sizeof(ret) * 4]; - - snprintf(msg, sizeof(msg), " %#x", flag); - tdb_trace_start(tdb); - tdb_trace_write(tdb, op); - tdb_trace_record(tdb, rec1); - tdb_trace_record(tdb, rec2); - tdb_trace_write(tdb, msg); - tdb_trace_end_ret(tdb, ret); -} - -void tdb_trace_1plusn_rec_flag_ret(struct tdb_context *tdb, const char *op, - TDB_DATA rec, - const TDB_DATA *recs, int num_recs, - unsigned flag, int ret) -{ - char msg[1 + sizeof(ret) * 4]; - int i; - - snprintf(msg, sizeof(msg), " %#x", flag); - tdb_trace_start(tdb); - tdb_trace_write(tdb, op); - tdb_trace_record(tdb, rec); - for (i=0; if) -#endif - -#define TDB_MAGIC_FOOD "TDB file\n" -#define TDB_VERSION (0x26011967 + 6) -#define TDB_MAGIC (0x26011999U) -#define TDB_FREE_MAGIC (~TDB_MAGIC) -#define TDB_DEAD_MAGIC (0xFEE1DEAD) -#define TDB_RECOVERY_MAGIC (0xf53bc0e7U) -#define TDB_RECOVERY_INVALID_MAGIC (0x0) -#define TDB_HASH_RWLOCK_MAGIC (0xbad1a51U) -#define TDB_FEATURE_FLAG_MAGIC (0xbad1a52U) -#define TDB_ALIGNMENT 4 -#define DEFAULT_HASH_SIZE 131 -#define FREELIST_TOP (sizeof(struct tdb_header)) -#define TDB_ALIGN(x,a) (((x) + (a)-1) & ~((a)-1)) -#define TDB_BYTEREV(x) (((((x)&0xff)<<24)|((x)&0xFF00)<<8)|(((x)>>8)&0xFF00)|((x)>>24)) -#define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC) -#define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r)) -#define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off_t)) -#define TDB_HASHTABLE_SIZE(tdb) ((tdb->hash_size+1)*sizeof(tdb_off_t)) -#define TDB_DATA_START(hash_size) (TDB_HASH_TOP(hash_size-1) + sizeof(tdb_off_t)) -#define TDB_RECOVERY_HEAD offsetof(struct tdb_header, recovery_start) -#define TDB_SEQNUM_OFS offsetof(struct tdb_header, sequence_number) -#define TDB_PAD_BYTE 0x42 -#define TDB_PAD_U32 0x42424242 - -#define TDB_FEATURE_FLAG_MUTEX 0x00000001 - -#define TDB_SUPPORTED_FEATURE_FLAGS ( \ - TDB_FEATURE_FLAG_MUTEX | \ - 0) - -/* NB assumes there is a local variable called "tdb" that is the - * current context, also takes doubly-parenthesized print-style - * argument. */ -#define TDB_LOG(x) tdb->log.log_fn x - -#ifdef TDB_TRACE -void tdb_trace(struct tdb_context *tdb, const char *op); -void tdb_trace_seqnum(struct tdb_context *tdb, uint32_t seqnum, const char *op); -void tdb_trace_open(struct tdb_context *tdb, const char *op, - unsigned hash_size, unsigned tdb_flags, unsigned open_flags); -void tdb_trace_ret(struct tdb_context *tdb, const char *op, int ret); -void tdb_trace_retrec(struct tdb_context *tdb, const char *op, TDB_DATA ret); -void tdb_trace_1rec(struct tdb_context *tdb, const char *op, - TDB_DATA rec); -void tdb_trace_1rec_ret(struct tdb_context *tdb, const char *op, - TDB_DATA rec, int ret); -void tdb_trace_1rec_retrec(struct tdb_context *tdb, const char *op, - TDB_DATA rec, TDB_DATA ret); -void tdb_trace_2rec_flag_ret(struct tdb_context *tdb, const char *op, - TDB_DATA rec1, TDB_DATA rec2, unsigned flag, - int ret); -void tdb_trace_1plusn_rec_flag_ret(struct tdb_context *tdb, const char *op, - TDB_DATA rec, - const TDB_DATA *recs, int num_recs, - unsigned flag, int ret); -void tdb_trace_2rec_retrec(struct tdb_context *tdb, const char *op, - TDB_DATA rec1, TDB_DATA rec2, TDB_DATA ret); -#else -#define tdb_trace(tdb, op) -#define tdb_trace_seqnum(tdb, seqnum, op) -#define tdb_trace_open(tdb, op, hash_size, tdb_flags, open_flags) -#define tdb_trace_ret(tdb, op, ret) -#define tdb_trace_retrec(tdb, op, ret) -#define tdb_trace_1rec(tdb, op, rec) -#define tdb_trace_1rec_ret(tdb, op, rec, ret) -#define tdb_trace_1rec_retrec(tdb, op, rec, ret) -#define tdb_trace_2rec_flag_ret(tdb, op, rec1, rec2, flag, ret) -#define tdb_trace_1plusn_rec_flag_ret(tdb, op, rec, recs, num_recs, flag, ret); -#define tdb_trace_2rec_retrec(tdb, op, rec1, rec2, ret) -#endif /* !TDB_TRACE */ - -/* lock offsets */ -#define OPEN_LOCK 0 -#define ACTIVE_LOCK 4 -#define TRANSACTION_LOCK 8 - -/* free memory if the pointer is valid and zero the pointer */ -#ifndef SAFE_FREE -#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0) -#endif - -/* - * Note: the BUCKET macro is broken as it returns an unexpected result when - * called as BUCKET(-1) for the freelist: - * - * -1 is sign converted to an unsigned int 4294967295 and then the modulo - * tdb->hashtable_size is computed. So with a hashtable_size of 10 the result - * is - * - * 4294967295 % hashtable_size = 5. - * - * where it should be -1 (C uses symmetric modulo). - * - * As all callers will lock the same wrong list consistently locking is still - * consistent. We can not change this without an incompatible on-disk format - * change, otherwise different tdb versions would use incompatible locking. - */ -#define BUCKET(hash) ((hash) % tdb->hash_size) - -#define DOCONV() (tdb->flags & TDB_CONVERT) -#define CONVERT(x) (DOCONV() ? tdb_convert(&x, sizeof(x)) : &x) - - -/* the body of the database is made of one tdb_record for the free space - plus a separate data list for each hash value */ -struct tdb_record { - tdb_off_t next; /* offset of the next record in the list */ - tdb_len_t rec_len; /* total byte length of record */ - tdb_len_t key_len; /* byte length of key */ - tdb_len_t data_len; /* byte length of data */ - uint32_t full_hash; /* the full 32 bit hash of the key */ - uint32_t magic; /* try to catch errors */ - /* the following union is implied: - union { - char record[rec_len]; - struct { - char key[key_len]; - char data[data_len]; - } - uint32_t totalsize; (tailer) - } - */ -}; - - -/* this is stored at the front of every database */ -struct tdb_header { - char magic_food[32]; /* for /etc/magic */ - uint32_t version; /* version of the code */ - uint32_t hash_size; /* number of hash entries */ - tdb_off_t rwlocks; /* obsolete - kept to detect old formats */ - tdb_off_t recovery_start; /* offset of transaction recovery region */ - tdb_off_t sequence_number; /* used when TDB_SEQNUM is set */ - uint32_t magic1_hash; /* hash of TDB_MAGIC_FOOD. */ - uint32_t magic2_hash; /* hash of TDB_MAGIC. */ - uint32_t feature_flags; - tdb_len_t mutex_size; /* set if TDB_FEATURE_FLAG_MUTEX is set */ - tdb_off_t reserved[25]; -}; - -struct tdb_lock_type { - uint32_t off; - uint32_t count; - uint32_t ltype; -}; - -struct tdb_chainwalk_ctx { - tdb_off_t slow_ptr; - bool slow_chase; -}; - -struct tdb_traverse_lock { - struct tdb_traverse_lock *next; - uint32_t off; - uint32_t list; - int lock_rw; -}; - -void tdb_chainwalk_init(struct tdb_chainwalk_ctx *ctx, tdb_off_t ptr); -bool tdb_chainwalk_check(struct tdb_context *tdb, - struct tdb_chainwalk_ctx *ctx, - tdb_off_t next_ptr); - -enum tdb_lock_flags { - /* WAIT == F_SETLKW, NOWAIT == F_SETLK */ - TDB_LOCK_NOWAIT = 0, - TDB_LOCK_WAIT = 1, - /* If set, don't log an error on failure. */ - TDB_LOCK_PROBE = 2, - /* If set, don't actually lock at all. */ - TDB_LOCK_MARK_ONLY = 4, -}; - -struct tdb_methods { - int (*tdb_read)(struct tdb_context *, tdb_off_t , void *, tdb_len_t , int ); - int (*tdb_write)(struct tdb_context *, tdb_off_t, const void *, tdb_len_t); - void (*next_hash_chain)(struct tdb_context *, uint32_t *); - int (*tdb_oob)(struct tdb_context *, tdb_off_t , tdb_len_t, int ); - int (*tdb_expand_file)(struct tdb_context *, tdb_off_t , tdb_off_t ); -}; - -struct tdb_mutexes; - -struct tdb_context { - char *name; /* the name of the database */ - void *map_ptr; /* where it is currently mapped */ - int fd; /* open file descriptor for the database */ - tdb_len_t map_size; /* how much space has been mapped */ - int read_only; /* opened read-only */ - int traverse_read; /* read-only traversal */ - int traverse_write; /* read-write traversal */ - struct tdb_lock_type allrecord_lock; /* .offset == upgradable */ - int num_lockrecs; - struct tdb_lock_type *lockrecs; /* only real locks, all with count>0 */ - int lockrecs_array_length; - - tdb_off_t hdr_ofs; /* this is 0 or header.mutex_size */ - struct tdb_mutexes *mutexes; /* mmap of the mutex area */ - - enum TDB_ERROR ecode; /* error code for last tdb error */ - uint32_t hash_size; - uint32_t feature_flags; - uint32_t flags; /* the flags passed to tdb_open */ - struct tdb_traverse_lock travlocks; /* current traversal locks */ - struct tdb_context *next; /* all tdbs to avoid multiple opens */ - dev_t device; /* uniquely identifies this tdb */ - ino_t inode; /* uniquely identifies this tdb */ - struct tdb_logging_context log; - unsigned int (*hash_fn)(TDB_DATA *key); - int open_flags; /* flags used in the open - needed by reopen */ - const struct tdb_methods *methods; - struct tdb_transaction *transaction; - int page_size; - int max_dead_records; -#ifdef TDB_TRACE - int tracefd; -#endif - volatile sig_atomic_t *interrupt_sig_ptr; -}; - - -/* - internal prototypes -*/ -int tdb_munmap(struct tdb_context *tdb); -int tdb_mmap(struct tdb_context *tdb); -int tdb_lock(struct tdb_context *tdb, int list, int ltype); -int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype); -int tdb_nest_lock(struct tdb_context *tdb, uint32_t offset, int ltype, - enum tdb_lock_flags flags); -int tdb_nest_unlock(struct tdb_context *tdb, uint32_t offset, int ltype, - bool mark_lock); -int tdb_unlock(struct tdb_context *tdb, int list, int ltype); -int tdb_brlock(struct tdb_context *tdb, - int rw_type, tdb_off_t offset, size_t len, - enum tdb_lock_flags flags); -int tdb_brunlock(struct tdb_context *tdb, - int rw_type, tdb_off_t offset, size_t len); -bool tdb_have_extra_locks(struct tdb_context *tdb); -void tdb_release_transaction_locks(struct tdb_context *tdb); -int tdb_transaction_lock(struct tdb_context *tdb, int ltype, - enum tdb_lock_flags lockflags); -int tdb_transaction_unlock(struct tdb_context *tdb, int ltype); -int tdb_recovery_area(struct tdb_context *tdb, - const struct tdb_methods *methods, - tdb_off_t *recovery_offset, - struct tdb_record *rec); -int tdb_allrecord_lock(struct tdb_context *tdb, int ltype, - enum tdb_lock_flags flags, bool upgradable); -int tdb_allrecord_unlock(struct tdb_context *tdb, int ltype, bool mark_lock); -int tdb_allrecord_upgrade(struct tdb_context *tdb); -int tdb_write_lock_record(struct tdb_context *tdb, tdb_off_t off); -int tdb_write_unlock_record(struct tdb_context *tdb, tdb_off_t off); -int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); -int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); -void *tdb_convert(void *buf, uint32_t size); -int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec); -tdb_off_t tdb_allocate(struct tdb_context *tdb, int hash, tdb_len_t length, - struct tdb_record *rec); - -int _tdb_oob(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe); - -static inline int tdb_oob( - struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe) -{ - if (likely((off + len >= off) && (off + len <= tdb->map_size))) { - return 0; - } - return _tdb_oob(tdb, off, len, probe); -} - - -int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); -int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); -int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off); -int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off); -bool tdb_needs_recovery(struct tdb_context *tdb); -int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec); -int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec); -unsigned char *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len); -int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key, - tdb_off_t offset, tdb_len_t len, - int (*parser)(TDB_DATA key, TDB_DATA data, - void *private_data), - void *private_data); -tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype, - struct tdb_record *rec); -tdb_off_t tdb_find_dead(struct tdb_context *tdb, uint32_t hash, - struct tdb_record *r, tdb_len_t length, - tdb_off_t *p_last_ptr); -int tdb_trim_dead(struct tdb_context *tdb, uint32_t hash); -void tdb_io_init(struct tdb_context *tdb); -int tdb_expand(struct tdb_context *tdb, tdb_off_t size); -tdb_off_t tdb_expand_adjust(tdb_off_t map_size, tdb_off_t size, int page_size); -int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, - struct tdb_record *rec); -bool tdb_write_all(int fd, const void *buf, size_t count); -int tdb_transaction_recover(struct tdb_context *tdb); -void tdb_header_hash(struct tdb_context *tdb, - uint32_t *magic1_hash, uint32_t *magic2_hash); -unsigned int tdb_old_hash(TDB_DATA *key); -size_t tdb_dead_space(struct tdb_context *tdb, tdb_off_t off); -bool tdb_add_off_t(tdb_off_t a, tdb_off_t b, tdb_off_t *pret); - -/* tdb_off_t and tdb_len_t right now are both uint32_t */ -#define tdb_add_len_t tdb_add_off_t - -size_t tdb_mutex_size(struct tdb_context *tdb); -bool tdb_have_mutexes(struct tdb_context *tdb); -int tdb_mutex_init(struct tdb_context *tdb); -int tdb_mutex_mmap(struct tdb_context *tdb); -int tdb_mutex_munmap(struct tdb_context *tdb); -bool tdb_mutex_lock(struct tdb_context *tdb, int rw, off_t off, off_t len, - bool waitflag, int *pret); -bool tdb_mutex_unlock(struct tdb_context *tdb, int rw, off_t off, off_t len, - int *pret); -int tdb_mutex_allrecord_lock(struct tdb_context *tdb, int ltype, - enum tdb_lock_flags flags); -int tdb_mutex_allrecord_unlock(struct tdb_context *tdb); -int tdb_mutex_allrecord_upgrade(struct tdb_context *tdb); -void tdb_mutex_allrecord_downgrade(struct tdb_context *tdb); - -#endif /* TDB_PRIVATE_H */ diff --git a/ldb-2.0.8/lib/tdb/common/transaction.c b/ldb-2.0.8/lib/tdb/common/transaction.c deleted file mode 100644 index 4f8d1f8..0000000 --- a/ldb-2.0.8/lib/tdb/common/transaction.c +++ /dev/null @@ -1,1387 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 2005 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "tdb_private.h" - -/* - transaction design: - - - only allow a single transaction at a time per database. This makes - using the transaction API simpler, as otherwise the caller would - have to cope with temporary failures in transactions that conflict - with other current transactions - - - keep the transaction recovery information in the same file as the - database, using a special 'transaction recovery' record pointed at - by the header. This removes the need for extra journal files as - used by some other databases - - - dynamically allocated the transaction recover record, re-using it - for subsequent transactions. If a larger record is needed then - tdb_free() the old record to place it on the normal tdb freelist - before allocating the new record - - - during transactions, keep a linked list of all writes that have - been performed by intercepting all tdb_write() calls. The hooked - transaction versions of tdb_read() and tdb_write() check this - linked list and try to use the elements of the list in preference - to the real database. - - - don't allow any locks to be held when a transaction starts, - otherwise we can end up with deadlock (plus lack of lock nesting - in posix locks would mean the lock is lost) - - - if the caller gains a lock during the transaction but doesn't - release it then fail the commit - - - allow for nested calls to tdb_transaction_start(), re-using the - existing transaction record. If the inner transaction is cancelled - then a subsequent commit will fail - - - keep a mirrored copy of the tdb hash chain heads to allow for the - fast hash heads scan on traverse, updating the mirrored copy in - the transaction version of tdb_write - - - allow callers to mix transaction and non-transaction use of tdb, - although once a transaction is started then an exclusive lock is - gained until the transaction is committed or cancelled - - - the commit stategy involves first saving away all modified data - into a linearised buffer in the transaction recovery area, then - marking the transaction recovery area with a magic value to - indicate a valid recovery record. In total 4 fsync/msync calls are - needed per commit to prevent race conditions. It might be possible - to reduce this to 3 or even 2 with some more work. - - - check for a valid recovery record on open of the tdb, while the - open lock is held. Automatically recover from the transaction - recovery area if needed, then continue with the open as - usual. This allows for smooth crash recovery with no administrator - intervention. - - - if TDB_NOSYNC is passed to flags in tdb_open then transactions are - still available, but no fsync/msync calls are made. This means we - are still proof against a process dying during transaction commit, - but not against machine reboot. - - - if TDB_ALLOW_NESTING is passed to flags in tdb open, or added using - tdb_add_flags() transaction nesting is enabled. - It resets the TDB_DISALLOW_NESTING flag, as both cannot be used together. - The default is that transaction nesting is allowed. - Note: this default may change in future versions of tdb. - - Beware. when transactions are nested a transaction successfully - completed with tdb_transaction_commit() can be silently unrolled later. - - - if TDB_DISALLOW_NESTING is passed to flags in tdb open, or added using - tdb_add_flags() transaction nesting is disabled. - It resets the TDB_ALLOW_NESTING flag, as both cannot be used together. - An attempt create a nested transaction will fail with TDB_ERR_NESTING. - The default is that transaction nesting is allowed. - Note: this default may change in future versions of tdb. -*/ - - -/* - hold the context of any current transaction -*/ -struct tdb_transaction { - /* we keep a mirrored copy of the tdb hash heads here so - tdb_next_hash_chain() can operate efficiently */ - uint32_t *hash_heads; - - /* the original io methods - used to do IOs to the real db */ - const struct tdb_methods *io_methods; - - /* the list of transaction blocks. When a block is first - written to, it gets created in this list */ - uint8_t **blocks; - uint32_t num_blocks; - uint32_t block_size; /* bytes in each block */ - uint32_t last_block_size; /* number of valid bytes in the last block */ - - /* non-zero when an internal transaction error has - occurred. All write operations will then fail until the - transaction is ended */ - int transaction_error; - - /* when inside a transaction we need to keep track of any - nested tdb_transaction_start() calls, as these are allowed, - but don't create a new transaction */ - int nesting; - - /* set when a prepare has already occurred */ - bool prepared; - tdb_off_t magic_offset; - - /* old file size before transaction */ - tdb_len_t old_map_size; - - /* did we expand in this transaction */ - bool expanded; -}; - - -/* - read while in a transaction. We need to check first if the data is in our list - of transaction elements, then if not do a real read -*/ -static int transaction_read(struct tdb_context *tdb, tdb_off_t off, void *buf, - tdb_len_t len, int cv) -{ - uint32_t blk; - - /* break it down into block sized ops */ - while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { - tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); - if (transaction_read(tdb, off, buf, len2, cv) != 0) { - return -1; - } - len -= len2; - off += len2; - buf = (void *)(len2 + (char *)buf); - } - - if (len == 0) { - return 0; - } - - blk = off / tdb->transaction->block_size; - - /* see if we have it in the block list */ - if (tdb->transaction->num_blocks <= blk || - tdb->transaction->blocks[blk] == NULL) { - /* nope, do a real read */ - if (tdb->transaction->io_methods->tdb_read(tdb, off, buf, len, cv) != 0) { - goto fail; - } - return 0; - } - - /* it is in the block list. Now check for the last block */ - if (blk == tdb->transaction->num_blocks-1) { - if (len > tdb->transaction->last_block_size) { - goto fail; - } - } - - /* now copy it out of this block */ - memcpy(buf, tdb->transaction->blocks[blk] + (off % tdb->transaction->block_size), len); - if (cv) { - tdb_convert(buf, len); - } - return 0; - -fail: - TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_read: failed at off=%u len=%u\n", off, len)); - tdb->ecode = TDB_ERR_IO; - tdb->transaction->transaction_error = 1; - return -1; -} - - -/* - write while in a transaction -*/ -static int transaction_write(struct tdb_context *tdb, tdb_off_t off, - const void *buf, tdb_len_t len) -{ - uint32_t blk; - - if (buf == NULL) { - return -1; - } - - /* Only a commit is allowed on a prepared transaction */ - if (tdb->transaction->prepared) { - tdb->ecode = TDB_ERR_EINVAL; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: transaction already prepared, write not allowed\n")); - tdb->transaction->transaction_error = 1; - return -1; - } - - /* if the write is to a hash head, then update the transaction - hash heads */ - if (len == sizeof(tdb_off_t) && off >= FREELIST_TOP && - off < FREELIST_TOP+TDB_HASHTABLE_SIZE(tdb)) { - uint32_t chain = (off-FREELIST_TOP) / sizeof(tdb_off_t); - memcpy(&tdb->transaction->hash_heads[chain], buf, len); - } - - /* break it up into block sized chunks */ - while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { - tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); - if (transaction_write(tdb, off, buf, len2) != 0) { - return -1; - } - len -= len2; - off += len2; - buf = (const void *)(len2 + (const char *)buf); - } - - if (len == 0) { - return 0; - } - - blk = off / tdb->transaction->block_size; - off = off % tdb->transaction->block_size; - - if (tdb->transaction->num_blocks <= blk) { - uint8_t **new_blocks; - /* expand the blocks array */ - new_blocks = (uint8_t **)realloc(tdb->transaction->blocks, - (blk+1)*sizeof(uint8_t *)); - if (new_blocks == NULL) { - tdb->ecode = TDB_ERR_OOM; - goto fail; - } - memset(&new_blocks[tdb->transaction->num_blocks], 0, - (1+(blk - tdb->transaction->num_blocks))*sizeof(uint8_t *)); - tdb->transaction->blocks = new_blocks; - tdb->transaction->num_blocks = blk+1; - tdb->transaction->last_block_size = 0; - } - - /* allocate and fill a block? */ - if (tdb->transaction->blocks[blk] == NULL) { - tdb->transaction->blocks[blk] = (uint8_t *)calloc(tdb->transaction->block_size, 1); - if (tdb->transaction->blocks[blk] == NULL) { - tdb->ecode = TDB_ERR_OOM; - tdb->transaction->transaction_error = 1; - return -1; - } - if (tdb->transaction->old_map_size > blk * tdb->transaction->block_size) { - tdb_len_t len2 = tdb->transaction->block_size; - if (len2 + (blk * tdb->transaction->block_size) > tdb->transaction->old_map_size) { - len2 = tdb->transaction->old_map_size - (blk * tdb->transaction->block_size); - } - if (tdb->transaction->io_methods->tdb_read(tdb, blk * tdb->transaction->block_size, - tdb->transaction->blocks[blk], - len2, 0) != 0) { - SAFE_FREE(tdb->transaction->blocks[blk]); - tdb->ecode = TDB_ERR_IO; - goto fail; - } - if (blk == tdb->transaction->num_blocks-1) { - tdb->transaction->last_block_size = len2; - } - } - } - - /* overwrite part of an existing block */ - memcpy(tdb->transaction->blocks[blk] + off, buf, len); - if (blk == tdb->transaction->num_blocks-1) { - if (len + off > tdb->transaction->last_block_size) { - tdb->transaction->last_block_size = len + off; - } - } - - return 0; - -fail: - TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%u len=%u\n", - (blk*tdb->transaction->block_size) + off, len)); - tdb->transaction->transaction_error = 1; - return -1; -} - - -/* - write while in a transaction - this variant never expands the transaction blocks, it only - updates existing blocks. This means it cannot change the recovery size -*/ -static int transaction_write_existing(struct tdb_context *tdb, tdb_off_t off, - const void *buf, tdb_len_t len) -{ - uint32_t blk; - - /* break it up into block sized chunks */ - while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { - tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); - if (transaction_write_existing(tdb, off, buf, len2) != 0) { - return -1; - } - len -= len2; - off += len2; - if (buf != NULL) { - buf = (const void *)(len2 + (const char *)buf); - } - } - - if (len == 0 || buf == NULL) { - return 0; - } - - blk = off / tdb->transaction->block_size; - off = off % tdb->transaction->block_size; - - if (tdb->transaction->num_blocks <= blk || - tdb->transaction->blocks[blk] == NULL) { - return 0; - } - - if (blk == tdb->transaction->num_blocks-1 && - off + len > tdb->transaction->last_block_size) { - if (off >= tdb->transaction->last_block_size) { - return 0; - } - len = tdb->transaction->last_block_size - off; - } - - /* overwrite part of an existing block */ - memcpy(tdb->transaction->blocks[blk] + off, buf, len); - - return 0; -} - - -/* - accelerated hash chain head search, using the cached hash heads -*/ -static void transaction_next_hash_chain(struct tdb_context *tdb, uint32_t *chain) -{ - uint32_t h = *chain; - for (;h < tdb->hash_size;h++) { - /* the +1 takes account of the freelist */ - if (0 != tdb->transaction->hash_heads[h+1]) { - break; - } - } - (*chain) = h; -} - -/* - out of bounds check during a transaction -*/ -static int transaction_oob(struct tdb_context *tdb, tdb_off_t off, - tdb_len_t len, int probe) -{ - /* - * This duplicates functionality from tdb_oob(). Don't remove: - * we still have direct callers of tdb->methods->tdb_oob() - * inside transaction.c. - */ - if (off + len >= off && off + len <= tdb->map_size) { - return 0; - } - tdb->ecode = TDB_ERR_IO; - return -1; -} - -/* - transaction version of tdb_expand(). -*/ -static int transaction_expand_file(struct tdb_context *tdb, tdb_off_t size, - tdb_off_t addition) -{ - const char buf_zero[8192] = {0}; - size_t buf_len = sizeof(buf_zero); - - while (addition > 0) { - size_t n = MIN(addition, buf_len); - int ret; - - ret = transaction_write(tdb, size, buf_zero, n); - if (ret != 0) { - return ret; - } - - addition -= n; - size += n; - } - - tdb->transaction->expanded = true; - - return 0; -} - -static const struct tdb_methods transaction_methods = { - transaction_read, - transaction_write, - transaction_next_hash_chain, - transaction_oob, - transaction_expand_file, -}; - -/* - * Is a transaction currently active on this context? - * - */ -_PUBLIC_ bool tdb_transaction_active(struct tdb_context *tdb) -{ - return (tdb->transaction != NULL); -} - -/* - start a tdb transaction. No token is returned, as only a single - transaction is allowed to be pending per tdb_context -*/ -static int _tdb_transaction_start(struct tdb_context *tdb, - enum tdb_lock_flags lockflags) -{ - /* some sanity checks */ - if (tdb->read_only || (tdb->flags & TDB_INTERNAL) - || tdb->traverse_read) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction on a read-only or internal db\n")); - tdb->ecode = TDB_ERR_EINVAL; - return -1; - } - - /* cope with nested tdb_transaction_start() calls */ - if (tdb->transaction != NULL) { - if (!(tdb->flags & TDB_ALLOW_NESTING)) { - tdb->ecode = TDB_ERR_NESTING; - return -1; - } - tdb->transaction->nesting++; - TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_start: nesting %d\n", - tdb->transaction->nesting)); - return 0; - } - - if (tdb_have_extra_locks(tdb)) { - /* the caller must not have any locks when starting a - transaction as otherwise we'll be screwed by lack - of nested locks in posix */ - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction with locks held\n")); - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - - if (tdb->travlocks.next != NULL) { - /* you cannot use transactions inside a traverse (although you can use - traverse inside a transaction) as otherwise you can end up with - deadlock */ - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: cannot start a transaction within a traverse\n")); - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - - tdb->transaction = (struct tdb_transaction *) - calloc(sizeof(struct tdb_transaction), 1); - if (tdb->transaction == NULL) { - tdb->ecode = TDB_ERR_OOM; - return -1; - } - - /* a page at a time seems like a reasonable compromise between compactness and efficiency */ - tdb->transaction->block_size = tdb->page_size; - - /* get the transaction write lock. This is a blocking lock. As - discussed with Volker, there are a number of ways we could - make this async, which we will probably do in the future */ - if (tdb_transaction_lock(tdb, F_WRLCK, lockflags) == -1) { - SAFE_FREE(tdb->transaction->blocks); - SAFE_FREE(tdb->transaction); - if ((lockflags & TDB_LOCK_WAIT) == 0) { - tdb->ecode = TDB_ERR_NOLOCK; - } else { - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "tdb_transaction_start: " - "failed to get transaction lock\n")); - } - return -1; - } - - /* get a read lock from the freelist to the end of file. This - is upgraded to a write lock during the commit */ - if (tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, true) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to get hash locks\n")); - goto fail_allrecord_lock; - } - - /* setup a copy of the hash table heads so the hash scan in - traverse can be fast */ - tdb->transaction->hash_heads = (uint32_t *) - calloc(tdb->hash_size+1, sizeof(uint32_t)); - if (tdb->transaction->hash_heads == NULL) { - tdb->ecode = TDB_ERR_OOM; - goto fail; - } - if (tdb->methods->tdb_read(tdb, FREELIST_TOP, tdb->transaction->hash_heads, - TDB_HASHTABLE_SIZE(tdb), 0) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_start: failed to read hash heads\n")); - tdb->ecode = TDB_ERR_IO; - goto fail; - } - - /* make sure we know about any file expansions already done by - anyone else */ - tdb_oob(tdb, tdb->map_size, 1, 1); - tdb->transaction->old_map_size = tdb->map_size; - - /* finally hook the io methods, replacing them with - transaction specific methods */ - tdb->transaction->io_methods = tdb->methods; - tdb->methods = &transaction_methods; - - /* Trace at the end, so we get sequence number correct. */ - tdb_trace(tdb, "tdb_transaction_start"); - return 0; - -fail: - tdb_allrecord_unlock(tdb, F_RDLCK, false); -fail_allrecord_lock: - tdb_transaction_unlock(tdb, F_WRLCK); - SAFE_FREE(tdb->transaction->blocks); - SAFE_FREE(tdb->transaction->hash_heads); - SAFE_FREE(tdb->transaction); - return -1; -} - -_PUBLIC_ int tdb_transaction_start(struct tdb_context *tdb) -{ - return _tdb_transaction_start(tdb, TDB_LOCK_WAIT); -} - -_PUBLIC_ int tdb_transaction_start_nonblock(struct tdb_context *tdb) -{ - return _tdb_transaction_start(tdb, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE); -} - -/* - sync to disk -*/ -static int transaction_sync(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t length) -{ - if (tdb->flags & TDB_NOSYNC) { - return 0; - } - -#ifdef HAVE_FDATASYNC - if (fdatasync(tdb->fd) != 0) { -#else - if (fsync(tdb->fd) != 0) { -#endif - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction: fsync failed\n")); - return -1; - } -#ifdef HAVE_MMAP - if (tdb->map_ptr) { - tdb_off_t moffset = offset & ~(tdb->page_size-1); - if (msync(moffset + (char *)tdb->map_ptr, - length + (offset - moffset), MS_SYNC) != 0) { - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction: msync failed - %s\n", - strerror(errno))); - return -1; - } - } -#endif - return 0; -} - - -static int _tdb_transaction_cancel(struct tdb_context *tdb) -{ - uint32_t i; - int ret = 0; - - if (tdb->transaction == NULL) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_cancel: no transaction\n")); - return -1; - } - - if (tdb->transaction->nesting != 0) { - tdb->transaction->transaction_error = 1; - tdb->transaction->nesting--; - return 0; - } - - tdb->map_size = tdb->transaction->old_map_size; - - /* free all the transaction blocks */ - for (i=0;itransaction->num_blocks;i++) { - if ((tdb->transaction->blocks != NULL) && - tdb->transaction->blocks[i] != NULL) { - free(tdb->transaction->blocks[i]); - } - } - SAFE_FREE(tdb->transaction->blocks); - - if (tdb->transaction->magic_offset) { - const struct tdb_methods *methods = tdb->transaction->io_methods; - const uint32_t invalid = TDB_RECOVERY_INVALID_MAGIC; - - /* remove the recovery marker */ - if (methods->tdb_write(tdb, tdb->transaction->magic_offset, &invalid, 4) == -1 || - transaction_sync(tdb, tdb->transaction->magic_offset, 4) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_cancel: failed to remove recovery magic\n")); - ret = -1; - } - } - - /* This also removes the OPEN_LOCK, if we have it. */ - tdb_release_transaction_locks(tdb); - - /* restore the normal io methods */ - tdb->methods = tdb->transaction->io_methods; - - SAFE_FREE(tdb->transaction->hash_heads); - SAFE_FREE(tdb->transaction); - - return ret; -} - -/* - cancel the current transaction -*/ -_PUBLIC_ int tdb_transaction_cancel(struct tdb_context *tdb) -{ - tdb_trace(tdb, "tdb_transaction_cancel"); - return _tdb_transaction_cancel(tdb); -} - -/* - work out how much space the linearised recovery data will consume -*/ -static bool tdb_recovery_size(struct tdb_context *tdb, tdb_len_t *result) -{ - tdb_len_t recovery_size = 0; - uint32_t i; - - recovery_size = sizeof(uint32_t); - for (i=0;itransaction->num_blocks;i++) { - tdb_len_t block_size; - if (i * tdb->transaction->block_size >= tdb->transaction->old_map_size) { - break; - } - if (tdb->transaction->blocks[i] == NULL) { - continue; - } - if (!tdb_add_len_t(recovery_size, 2*sizeof(tdb_off_t), - &recovery_size)) { - return false; - } - if (i == tdb->transaction->num_blocks-1) { - block_size = tdb->transaction->last_block_size; - } else { - block_size = tdb->transaction->block_size; - } - if (!tdb_add_len_t(recovery_size, block_size, - &recovery_size)) { - return false; - } - } - - *result = recovery_size; - return true; -} - -int tdb_recovery_area(struct tdb_context *tdb, - const struct tdb_methods *methods, - tdb_off_t *recovery_offset, - struct tdb_record *rec) -{ - int ret; - - if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, recovery_offset) == -1) { - return -1; - } - - if (*recovery_offset == 0) { - rec->rec_len = 0; - return 0; - } - - if (methods->tdb_read(tdb, *recovery_offset, rec, sizeof(*rec), - DOCONV()) == -1) { - return -1; - } - - /* ignore invalid recovery regions: can happen in crash */ - if (rec->magic != TDB_RECOVERY_MAGIC && - rec->magic != TDB_RECOVERY_INVALID_MAGIC) { - *recovery_offset = 0; - rec->rec_len = 0; - } - - ret = methods->tdb_oob(tdb, *recovery_offset, rec->rec_len, 1); - if (ret == -1) { - *recovery_offset = 0; - rec->rec_len = 0; - } - - return 0; -} - -/* - allocate the recovery area, or use an existing recovery area if it is - large enough -*/ -static int tdb_recovery_allocate(struct tdb_context *tdb, - tdb_len_t *recovery_size, - tdb_off_t *recovery_offset, - tdb_len_t *recovery_max_size) -{ - struct tdb_record rec; - const struct tdb_methods *methods = tdb->transaction->io_methods; - tdb_off_t recovery_head, new_end; - - if (tdb_recovery_area(tdb, methods, &recovery_head, &rec) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to read recovery head\n")); - return -1; - } - - if (!tdb_recovery_size(tdb, recovery_size)) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: " - "overflow recovery size\n")); - return -1; - } - - /* Existing recovery area? */ - if (recovery_head != 0 && *recovery_size <= rec.rec_len) { - /* it fits in the existing area */ - *recovery_max_size = rec.rec_len; - *recovery_offset = recovery_head; - return 0; - } - - /* If recovery area in middle of file, we need a new one. */ - if (recovery_head == 0 - || recovery_head + sizeof(rec) + rec.rec_len != tdb->map_size) { - /* we need to free up the old recovery area, then allocate a - new one at the end of the file. Note that we cannot use - tdb_allocate() to allocate the new one as that might return - us an area that is being currently used (as of the start of - the transaction) */ - if (recovery_head) { - if (tdb_free(tdb, recovery_head, &rec) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, - "tdb_recovery_allocate: failed to" - " free previous recovery area\n")); - return -1; - } - - /* the tdb_free() call might have increased - * the recovery size */ - if (!tdb_recovery_size(tdb, recovery_size)) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, - "tdb_recovery_allocate: " - "overflow recovery size\n")); - return -1; - } - } - - /* New head will be at end of file. */ - recovery_head = tdb->map_size; - } - - /* Now we know where it will be. */ - *recovery_offset = recovery_head; - - /* Expand by more than we need, so we don't do it often. */ - *recovery_max_size = tdb_expand_adjust(tdb->map_size, - *recovery_size, - tdb->page_size) - - sizeof(rec); - - if (!tdb_add_off_t(recovery_head, sizeof(rec), &new_end) || - !tdb_add_off_t(new_end, *recovery_max_size, &new_end)) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: " - "overflow recovery area\n")); - return -1; - } - - if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size, - new_end - tdb->transaction->old_map_size) - == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to create recovery area\n")); - return -1; - } - - /* remap the file (if using mmap) */ - methods->tdb_oob(tdb, tdb->map_size, 1, 1); - - /* we have to reset the old map size so that we don't try to expand the file - again in the transaction commit, which would destroy the recovery area */ - tdb->transaction->old_map_size = tdb->map_size; - - /* write the recovery header offset and sync - we can sync without a race here - as the magic ptr in the recovery record has not been set */ - CONVERT(recovery_head); - if (methods->tdb_write(tdb, TDB_RECOVERY_HEAD, - &recovery_head, sizeof(tdb_off_t)) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n")); - return -1; - } - if (transaction_write_existing(tdb, TDB_RECOVERY_HEAD, &recovery_head, sizeof(tdb_off_t)) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n")); - return -1; - } - - return 0; -} - - -/* - setup the recovery data that will be used on a crash during commit -*/ -static int transaction_setup_recovery(struct tdb_context *tdb, - tdb_off_t *magic_offset) -{ - tdb_len_t recovery_size; - unsigned char *data, *p; - const struct tdb_methods *methods = tdb->transaction->io_methods; - struct tdb_record *rec; - tdb_off_t recovery_offset, recovery_max_size; - tdb_off_t old_map_size = tdb->transaction->old_map_size; - uint32_t magic, tailer; - uint32_t i; - - /* - check that the recovery area has enough space - */ - if (tdb_recovery_allocate(tdb, &recovery_size, - &recovery_offset, &recovery_max_size) == -1) { - return -1; - } - - rec = malloc(recovery_size + sizeof(*rec)); - if (rec == NULL) { - tdb->ecode = TDB_ERR_OOM; - return -1; - } - - memset(rec, 0, sizeof(*rec)); - - rec->magic = TDB_RECOVERY_INVALID_MAGIC; - rec->data_len = recovery_size; - rec->rec_len = recovery_max_size; - rec->key_len = old_map_size; - CONVERT(*rec); - - data = (unsigned char *)rec; - - /* build the recovery data into a single blob to allow us to do a single - large write, which should be more efficient */ - p = data + sizeof(*rec); - for (i=0;itransaction->num_blocks;i++) { - tdb_off_t offset; - tdb_len_t length; - - if (tdb->transaction->blocks[i] == NULL) { - continue; - } - - offset = i * tdb->transaction->block_size; - length = tdb->transaction->block_size; - if (i == tdb->transaction->num_blocks-1) { - length = tdb->transaction->last_block_size; - } - - if (offset >= old_map_size) { - continue; - } - if (offset + length > tdb->transaction->old_map_size) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: transaction data over new region boundary\n")); - free(data); - tdb->ecode = TDB_ERR_CORRUPT; - return -1; - } - memcpy(p, &offset, 4); - memcpy(p+4, &length, 4); - if (DOCONV()) { - tdb_convert(p, 8); - } - /* the recovery area contains the old data, not the - new data, so we have to call the original tdb_read - method to get it */ - if (methods->tdb_read(tdb, offset, p + 8, length, 0) != 0) { - free(data); - tdb->ecode = TDB_ERR_IO; - return -1; - } - p += 8 + length; - } - - /* and the tailer */ - tailer = sizeof(*rec) + recovery_max_size; - memcpy(p, &tailer, 4); - if (DOCONV()) { - tdb_convert(p, 4); - } - - /* write the recovery data to the recovery area */ - if (methods->tdb_write(tdb, recovery_offset, data, sizeof(*rec) + recovery_size) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write recovery data\n")); - free(data); - tdb->ecode = TDB_ERR_IO; - return -1; - } - if (transaction_write_existing(tdb, recovery_offset, data, sizeof(*rec) + recovery_size) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write secondary recovery data\n")); - free(data); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - /* as we don't have ordered writes, we have to sync the recovery - data before we update the magic to indicate that the recovery - data is present */ - if (transaction_sync(tdb, recovery_offset, sizeof(*rec) + recovery_size) == -1) { - free(data); - return -1; - } - - free(data); - - magic = TDB_RECOVERY_MAGIC; - CONVERT(magic); - - *magic_offset = recovery_offset + offsetof(struct tdb_record, magic); - - if (methods->tdb_write(tdb, *magic_offset, &magic, sizeof(magic)) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write recovery magic\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - if (transaction_write_existing(tdb, *magic_offset, &magic, sizeof(magic)) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write secondary recovery magic\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - /* ensure the recovery magic marker is on disk */ - if (transaction_sync(tdb, *magic_offset, sizeof(magic)) == -1) { - return -1; - } - - return 0; -} - -static int _tdb_transaction_prepare_commit(struct tdb_context *tdb) -{ - const struct tdb_methods *methods; - - if (tdb->transaction == NULL) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: no transaction\n")); - return -1; - } - - if (tdb->transaction->prepared) { - tdb->ecode = TDB_ERR_EINVAL; - _tdb_transaction_cancel(tdb); - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: transaction already prepared\n")); - return -1; - } - - if (tdb->transaction->transaction_error) { - tdb->ecode = TDB_ERR_IO; - _tdb_transaction_cancel(tdb); - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: transaction error pending\n")); - return -1; - } - - - if (tdb->transaction->nesting != 0) { - return 0; - } - - /* check for a null transaction */ - if (tdb->transaction->blocks == NULL) { - return 0; - } - - methods = tdb->transaction->io_methods; - - /* if there are any locks pending then the caller has not - nested their locks properly, so fail the transaction */ - if (tdb_have_extra_locks(tdb)) { - tdb->ecode = TDB_ERR_LOCK; - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: locks pending on commit\n")); - _tdb_transaction_cancel(tdb); - return -1; - } - - /* upgrade the main transaction lock region to a write lock */ - if (tdb_allrecord_upgrade(tdb) == -1) { - if (tdb->ecode == TDB_ERR_RDONLY && tdb->read_only) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "tdb_transaction_prepare_commit: " - "failed to upgrade hash locks: " - "database is read only\n")); - } else if (tdb->ecode == TDB_ERR_RDONLY - && tdb->traverse_read) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "tdb_transaction_prepare_commit: " - "failed to upgrade hash locks: " - "a database traverse is in progress\n")); - } else { - TDB_LOG((tdb, TDB_DEBUG_ERROR, - "tdb_transaction_prepare_commit: " - "failed to upgrade hash locks: %s\n", - tdb_errorstr(tdb))); - } - _tdb_transaction_cancel(tdb); - return -1; - } - - /* get the open lock - this prevents new users attaching to the database - during the commit */ - if (tdb_nest_lock(tdb, OPEN_LOCK, F_WRLCK, TDB_LOCK_WAIT) == -1) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: failed to get open lock\n")); - _tdb_transaction_cancel(tdb); - return -1; - } - - /* write the recovery data to the end of the file */ - if (transaction_setup_recovery(tdb, &tdb->transaction->magic_offset) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_prepare_commit: failed to setup recovery data\n")); - _tdb_transaction_cancel(tdb); - return -1; - } - - tdb->transaction->prepared = true; - - /* expand the file to the new size if needed */ - if (tdb->map_size != tdb->transaction->old_map_size) { - if (methods->tdb_expand_file(tdb, tdb->transaction->old_map_size, - tdb->map_size - - tdb->transaction->old_map_size) == -1) { - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_prepare_commit: expansion failed\n")); - _tdb_transaction_cancel(tdb); - return -1; - } - tdb->map_size = tdb->transaction->old_map_size; - methods->tdb_oob(tdb, tdb->map_size, 1, 1); - } - - /* Keep the open lock until the actual commit */ - - return 0; -} - -/* - prepare to commit the current transaction -*/ -_PUBLIC_ int tdb_transaction_prepare_commit(struct tdb_context *tdb) -{ - tdb_trace(tdb, "tdb_transaction_prepare_commit"); - return _tdb_transaction_prepare_commit(tdb); -} - -/* A repack is worthwhile if the largest is less than half total free. */ -static bool repack_worthwhile(struct tdb_context *tdb) -{ - tdb_off_t ptr; - struct tdb_record rec; - tdb_len_t total = 0, largest = 0; - - if (tdb_ofs_read(tdb, FREELIST_TOP, &ptr) == -1) { - return false; - } - - while (ptr != 0 && tdb_rec_free_read(tdb, ptr, &rec) == 0) { - total += rec.rec_len; - if (rec.rec_len > largest) { - largest = rec.rec_len; - } - ptr = rec.next; - } - - return total > largest * 2; -} - -/* - commit the current transaction -*/ -_PUBLIC_ int tdb_transaction_commit(struct tdb_context *tdb) -{ - const struct tdb_methods *methods; - uint32_t i; - bool need_repack = false; - - if (tdb->transaction == NULL) { - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: no transaction\n")); - return -1; - } - - tdb_trace(tdb, "tdb_transaction_commit"); - - if (tdb->transaction->transaction_error) { - tdb->ecode = TDB_ERR_IO; - _tdb_transaction_cancel(tdb); - TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: transaction error pending\n")); - return -1; - } - - - if (tdb->transaction->nesting != 0) { - tdb->transaction->nesting--; - return 0; - } - - /* check for a null transaction */ - if (tdb->transaction->blocks == NULL) { - _tdb_transaction_cancel(tdb); - return 0; - } - - if (!tdb->transaction->prepared) { - int ret = _tdb_transaction_prepare_commit(tdb); - if (ret) - return ret; - } - - methods = tdb->transaction->io_methods; - - /* perform all the writes */ - for (i=0;itransaction->num_blocks;i++) { - tdb_off_t offset; - tdb_len_t length; - - if (tdb->transaction->blocks[i] == NULL) { - continue; - } - - offset = i * tdb->transaction->block_size; - length = tdb->transaction->block_size; - if (i == tdb->transaction->num_blocks-1) { - length = tdb->transaction->last_block_size; - } - - if (methods->tdb_write(tdb, offset, tdb->transaction->blocks[i], length) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed during commit\n")); - - /* we've overwritten part of the data and - possibly expanded the file, so we need to - run the crash recovery code */ - tdb->methods = methods; - tdb_transaction_recover(tdb); - - _tdb_transaction_cancel(tdb); - - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed\n")); - return -1; - } - SAFE_FREE(tdb->transaction->blocks[i]); - } - - /* Do this before we drop lock or blocks. */ - if (tdb->transaction->expanded) { - need_repack = repack_worthwhile(tdb); - } - - SAFE_FREE(tdb->transaction->blocks); - tdb->transaction->num_blocks = 0; - - /* ensure the new data is on disk */ - if (transaction_sync(tdb, 0, tdb->map_size) == -1) { - return -1; - } - - /* - TODO: maybe write to some dummy hdr field, or write to magic - offset without mmap, before the last sync, instead of the - utime() call - */ - - /* on some systems (like Linux 2.6.x) changes via mmap/msync - don't change the mtime of the file, this means the file may - not be backed up (as tdb rounding to block sizes means that - file size changes are quite rare too). The following forces - mtime changes when a transaction completes */ -#ifdef HAVE_UTIME - utime(tdb->name, NULL); -#endif - - /* use a transaction cancel to free memory and remove the - transaction locks */ - _tdb_transaction_cancel(tdb); - - if (need_repack) { - int ret = tdb_repack(tdb); - if (ret != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, - __location__ " Failed to repack database (not fatal)\n")); - } - /* - * Ignore the error. - * - * Why? - * - * We just committed to the DB above, so anything - * written during the transaction is committed, the - * caller needs to know that the long-term state was - * successfully modified. - * - * tdb_repack is an optimization that can fail for - * reasons like lock ordering and we cannot recover - * the transaction lock at this point, having released - * it above. - * - * If we return a failure the caller thinks the - * transaction was rolled back. - */ - } - - return 0; -} - - -/* - recover from an aborted transaction. Must be called with exclusive - database write access already established (including the open - lock to prevent new processes attaching) -*/ -int tdb_transaction_recover(struct tdb_context *tdb) -{ - tdb_off_t recovery_head, recovery_eof; - unsigned char *data, *p; - uint32_t zero = 0; - struct tdb_record rec; - - /* find the recovery area */ - if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery head\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - if (recovery_head == 0) { - /* we have never allocated a recovery record */ - return 0; - } - - /* read the recovery record */ - if (tdb->methods->tdb_read(tdb, recovery_head, &rec, - sizeof(rec), DOCONV()) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery record\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - if (rec.magic != TDB_RECOVERY_MAGIC) { - /* there is no valid recovery data */ - return 0; - } - - if (tdb->read_only) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: attempt to recover read only database\n")); - tdb->ecode = TDB_ERR_CORRUPT; - return -1; - } - - recovery_eof = rec.key_len; - - data = (unsigned char *)malloc(rec.data_len); - if (data == NULL) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to allocate recovery data\n")); - tdb->ecode = TDB_ERR_OOM; - return -1; - } - - /* read the full recovery data */ - if (tdb->methods->tdb_read(tdb, recovery_head + sizeof(rec), data, - rec.data_len, 0) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to read recovery data\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - /* recover the file data */ - p = data; - while (p+8 < data + rec.data_len) { - uint32_t ofs, len; - if (DOCONV()) { - tdb_convert(p, 8); - } - memcpy(&ofs, p, 4); - memcpy(&len, p+4, 4); - - if (tdb->methods->tdb_write(tdb, ofs, p+8, len) == -1) { - free(data); - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to recover %u bytes at offset %u\n", len, ofs)); - tdb->ecode = TDB_ERR_IO; - return -1; - } - p += 8 + len; - } - - free(data); - - if (transaction_sync(tdb, 0, tdb->map_size) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to sync recovery\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - /* if the recovery area is after the recovered eof then remove it */ - if (recovery_eof <= recovery_head) { - if (tdb_ofs_write(tdb, TDB_RECOVERY_HEAD, &zero) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to remove recovery head\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - } - - /* remove the recovery magic */ - if (tdb_ofs_write(tdb, recovery_head + offsetof(struct tdb_record, magic), - &zero) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to remove recovery magic\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - if (transaction_sync(tdb, 0, recovery_eof) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_recover: failed to sync2 recovery\n")); - tdb->ecode = TDB_ERR_IO; - return -1; - } - - TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_transaction_recover: recovered %u byte database\n", - recovery_eof)); - - /* all done */ - return 0; -} - -/* Any I/O failures we say "needs recovery". */ -bool tdb_needs_recovery(struct tdb_context *tdb) -{ - tdb_off_t recovery_head; - struct tdb_record rec; - - /* find the recovery area */ - if (tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &recovery_head) == -1) { - return true; - } - - if (recovery_head == 0) { - /* we have never allocated a recovery record */ - return false; - } - - /* read the recovery record */ - if (tdb->methods->tdb_read(tdb, recovery_head, &rec, - sizeof(rec), DOCONV()) == -1) { - return true; - } - - return (rec.magic == TDB_RECOVERY_MAGIC); -} diff --git a/ldb-2.0.8/lib/tdb/common/traverse.c b/ldb-2.0.8/lib/tdb/common/traverse.c deleted file mode 100644 index d69e7df..0000000 --- a/ldb-2.0.8/lib/tdb/common/traverse.c +++ /dev/null @@ -1,510 +0,0 @@ - /* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2005 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-2003 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "tdb_private.h" - -#define TDB_NEXT_LOCK_ERR ((tdb_off_t)-1) - -/* Uses traverse lock: 0 = finish, TDB_NEXT_LOCK_ERR = error, - other = record offset */ -static tdb_off_t tdb_next_lock(struct tdb_context *tdb, struct tdb_traverse_lock *tlock, - struct tdb_record *rec) -{ - int want_next = (tlock->off != 0); - - /* Lock each chain from the start one. */ - for (; tlock->list < tdb->hash_size; tlock->list++) { - if (!tlock->off && tlock->list != 0) { - /* this is an optimisation for the common case where - the hash chain is empty, which is particularly - common for the use of tdb with ldb, where large - hashes are used. In that case we spend most of our - time in tdb_brlock(), locking empty hash chains. - - To avoid this, we do an unlocked pre-check to see - if the hash chain is empty before starting to look - inside it. If it is empty then we can avoid that - hash chain. If it isn't empty then we can't believe - the value we get back, as we read it without a - lock, so instead we get the lock and re-fetch the - value below. - - Notice that not doing this optimisation on the - first hash chain is critical. We must guarantee - that we have done at least one fcntl lock at the - start of a search to guarantee that memory is - coherent on SMP systems. If records are added by - others during the search then thats OK, and we - could possibly miss those with this trick, but we - could miss them anyway without this trick, so the - semantics don't change. - - With a non-indexed ldb search this trick gains us a - factor of around 80 in speed on a linux 2.6.x - system (testing using ldbtest). - */ - tdb->methods->next_hash_chain(tdb, &tlock->list); - if (tlock->list == tdb->hash_size) { - continue; - } - } - - if (tdb_lock(tdb, tlock->list, tlock->lock_rw) == -1) - return TDB_NEXT_LOCK_ERR; - - /* No previous record? Start at top of chain. */ - if (!tlock->off) { - if (tdb_ofs_read(tdb, TDB_HASH_TOP(tlock->list), - &tlock->off) == -1) - goto fail; - } else { - /* Otherwise unlock the previous record. */ - if (tdb_unlock_record(tdb, tlock->off) != 0) - goto fail; - } - - if (want_next) { - /* We have offset of old record: grab next */ - if (tdb_rec_read(tdb, tlock->off, rec) == -1) - goto fail; - tlock->off = rec->next; - } - - /* Iterate through chain */ - while( tlock->off) { - if (tdb_rec_read(tdb, tlock->off, rec) == -1) - goto fail; - - /* Detect infinite loops. From "Shlomi Yaakobovich" . */ - if (tlock->off == rec->next) { - tdb->ecode = TDB_ERR_CORRUPT; - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_next_lock: loop detected.\n")); - goto fail; - } - - if (!TDB_DEAD(rec)) { - /* Woohoo: we found one! */ - if (tdb_lock_record(tdb, tlock->off) != 0) - goto fail; - return tlock->off; - } - - tlock->off = rec->next; - } - tdb_unlock(tdb, tlock->list, tlock->lock_rw); - want_next = 0; - } - /* We finished iteration without finding anything */ - tdb->ecode = TDB_SUCCESS; - return 0; - - fail: - tlock->off = 0; - if (tdb_unlock(tdb, tlock->list, tlock->lock_rw) != 0) - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_next_lock: On error unlock failed!\n")); - return TDB_NEXT_LOCK_ERR; -} - -/* traverse the entire database - calling fn(tdb, key, data) on each element. - return -1 on error or the record count traversed - if fn is NULL then it is not called - a non-zero return value from fn() indicates that the traversal should stop - */ -static int tdb_traverse_internal(struct tdb_context *tdb, - tdb_traverse_func fn, void *private_data, - struct tdb_traverse_lock *tl) -{ - TDB_DATA key, dbuf; - struct tdb_record rec; - int ret = 0, count = 0; - tdb_off_t off; - size_t recbuf_len; - - recbuf_len = 4096; - key.dptr = malloc(recbuf_len); - if (key.dptr == NULL) { - return -1; - } - - /* This was in the initialization, above, but the IRIX compiler - * did not like it. crh - */ - tl->next = tdb->travlocks.next; - - /* fcntl locks don't stack: beware traverse inside traverse */ - tdb->travlocks.next = tl; - - /* tdb_next_lock places locks on the record returned, and its chain */ - while ((off = tdb_next_lock(tdb, tl, &rec)) != 0) { - tdb_len_t full_len; - int nread; - - if (off == TDB_NEXT_LOCK_ERR) { - ret = -1; - goto out; - } - - full_len = rec.key_len + rec.data_len; - - if (full_len > recbuf_len) { - recbuf_len = full_len; - - /* - * No realloc, we don't need the old data and thus can - * do without the memcpy - */ - free(key.dptr); - key.dptr = malloc(recbuf_len); - - if (key.dptr == NULL) { - ret = -1; - if (tdb_unlock(tdb, tl->list, tl->lock_rw) - != 0) { - goto out; - } - if (tdb_unlock_record(tdb, tl->off) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, - "tdb_traverse: malloc " - "failed and unlock_record " - "failed!\n")); - } - goto out; - } - } - - count++; - /* now read the full record */ - nread = tdb->methods->tdb_read(tdb, tl->off + sizeof(rec), - key.dptr, full_len, 0); - if (nread == -1) { - ret = -1; - if (tdb_unlock(tdb, tl->list, tl->lock_rw) != 0) - goto out; - if (tdb_unlock_record(tdb, tl->off) != 0) - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_traverse: key.dptr == NULL and unlock_record failed!\n")); - goto out; - } - key.dsize = rec.key_len; - dbuf.dptr = key.dptr + rec.key_len; - dbuf.dsize = rec.data_len; - - tdb_trace_1rec_retrec(tdb, "traverse", key, dbuf); - - /* Drop chain lock, call out */ - if (tdb_unlock(tdb, tl->list, tl->lock_rw) != 0) { - ret = -1; - goto out; - } - if (fn && fn(tdb, key, dbuf, private_data)) { - /* They want us to terminate traversal */ - tdb_trace_ret(tdb, "tdb_traverse_end", count); - if (tdb_unlock_record(tdb, tl->off) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_traverse: unlock_record failed!\n"));; - ret = -1; - } - goto out; - } - } - tdb_trace(tdb, "tdb_traverse_end"); -out: - SAFE_FREE(key.dptr); - tdb->travlocks.next = tl->next; - if (ret < 0) - return -1; - else - return count; -} - - -/* - a read style traverse - temporarily marks each record read only -*/ -_PUBLIC_ int tdb_traverse_read(struct tdb_context *tdb, - tdb_traverse_func fn, void *private_data) -{ - struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK }; - int ret; - - tdb->traverse_read++; - tdb_trace(tdb, "tdb_traverse_read_start"); - ret = tdb_traverse_internal(tdb, fn, private_data, &tl); - tdb->traverse_read--; - - return ret; -} - -/* - a write style traverse - needs to get the transaction lock to - prevent deadlocks - - WARNING: The data buffer given to the callback fn does NOT meet the - alignment guarantees malloc gives you. -*/ -_PUBLIC_ int tdb_traverse(struct tdb_context *tdb, - tdb_traverse_func fn, void *private_data) -{ - struct tdb_traverse_lock tl = { NULL, 0, 0, F_WRLCK }; - enum tdb_lock_flags lock_flags; - int ret; - - if (tdb->read_only || tdb->traverse_read) { - return tdb_traverse_read(tdb, fn, private_data); - } - - lock_flags = TDB_LOCK_WAIT; - - if (tdb->allrecord_lock.count != 0) { - /* - * This avoids a deadlock between tdb_lockall() and - * tdb_traverse(). See - * https://bugzilla.samba.org/show_bug.cgi?id=11381 - */ - lock_flags = TDB_LOCK_NOWAIT; - } - - if (tdb_transaction_lock(tdb, F_WRLCK, lock_flags)) { - return -1; - } - - tdb->traverse_write++; - tdb_trace(tdb, "tdb_traverse_start"); - ret = tdb_traverse_internal(tdb, fn, private_data, &tl); - tdb->traverse_write--; - - tdb_transaction_unlock(tdb, F_WRLCK); - - return ret; -} - - -/* find the first entry in the database and return its key */ -_PUBLIC_ TDB_DATA tdb_firstkey(struct tdb_context *tdb) -{ - TDB_DATA key; - struct tdb_record rec; - tdb_off_t off; - - /* release any old lock */ - if (tdb_unlock_record(tdb, tdb->travlocks.off) != 0) - return tdb_null; - tdb->travlocks.off = tdb->travlocks.list = 0; - tdb->travlocks.lock_rw = F_RDLCK; - - /* Grab first record: locks chain and returned record. */ - off = tdb_next_lock(tdb, &tdb->travlocks, &rec); - if (off == 0 || off == TDB_NEXT_LOCK_ERR) { - tdb_trace_retrec(tdb, "tdb_firstkey", tdb_null); - return tdb_null; - } - /* now read the key */ - key.dsize = rec.key_len; - key.dptr =tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),key.dsize); - - tdb_trace_retrec(tdb, "tdb_firstkey", key); - - /* Unlock the hash chain of the record we just read. */ - if (tdb_unlock(tdb, tdb->travlocks.list, tdb->travlocks.lock_rw) != 0) - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_firstkey: error occurred while tdb_unlocking!\n")); - return key; -} - -/* find the next entry in the database, returning its key */ -_PUBLIC_ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey) -{ - uint32_t oldlist; - TDB_DATA key = tdb_null; - struct tdb_record rec; - unsigned char *k = NULL; - tdb_off_t off; - - /* Is locked key the old key? If so, traverse will be reliable. */ - if (tdb->travlocks.off) { - if (tdb_lock(tdb,tdb->travlocks.list,tdb->travlocks.lock_rw)) - return tdb_null; - if (tdb_rec_read(tdb, tdb->travlocks.off, &rec) == -1 - || !(k = tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec), - rec.key_len)) - || memcmp(k, oldkey.dptr, oldkey.dsize) != 0) { - /* No, it wasn't: unlock it and start from scratch */ - if (tdb_unlock_record(tdb, tdb->travlocks.off) != 0) { - tdb_trace_1rec_retrec(tdb, "tdb_nextkey", - oldkey, tdb_null); - SAFE_FREE(k); - return tdb_null; - } - if (tdb_unlock(tdb, tdb->travlocks.list, tdb->travlocks.lock_rw) != 0) { - SAFE_FREE(k); - return tdb_null; - } - tdb->travlocks.off = 0; - } - - SAFE_FREE(k); - } - - if (!tdb->travlocks.off) { - /* No previous element: do normal find, and lock record */ - tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb->hash_fn(&oldkey), tdb->travlocks.lock_rw, &rec); - if (!tdb->travlocks.off) { - tdb_trace_1rec_retrec(tdb, "tdb_nextkey", oldkey, tdb_null); - return tdb_null; - } - tdb->travlocks.list = BUCKET(rec.full_hash); - if (tdb_lock_record(tdb, tdb->travlocks.off) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: lock_record failed (%s)!\n", strerror(errno))); - return tdb_null; - } - } - oldlist = tdb->travlocks.list; - - /* Grab next record: locks chain and returned record, - unlocks old record */ - off = tdb_next_lock(tdb, &tdb->travlocks, &rec); - if (off != TDB_NEXT_LOCK_ERR && off != 0) { - key.dsize = rec.key_len; - key.dptr = tdb_alloc_read(tdb, tdb->travlocks.off+sizeof(rec), - key.dsize); - /* Unlock the chain of this new record */ - if (tdb_unlock(tdb, tdb->travlocks.list, tdb->travlocks.lock_rw) != 0) - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n")); - } - /* Unlock the chain of old record */ - if (tdb_unlock(tdb, oldlist, tdb->travlocks.lock_rw) != 0) - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n")); - tdb_trace_1rec_retrec(tdb, "tdb_nextkey", oldkey, key); - return key; -} - -_PUBLIC_ int tdb_traverse_chain(struct tdb_context *tdb, - unsigned chain, - tdb_traverse_func fn, - void *private_data) -{ - tdb_off_t rec_ptr; - struct tdb_chainwalk_ctx chainwalk; - int count = 0; - int ret; - - if (chain >= tdb->hash_size) { - tdb->ecode = TDB_ERR_EINVAL; - return -1; - } - - if (tdb->traverse_read != 0) { - tdb->ecode = TDB_ERR_LOCK; - return -1; - } - - ret = tdb_lock(tdb, chain, F_RDLCK); - if (ret == -1) { - return -1; - } - - tdb->traverse_read += 1; - - ret = tdb_ofs_read(tdb, TDB_HASH_TOP(chain), &rec_ptr); - if (ret == -1) { - goto fail; - } - - tdb_chainwalk_init(&chainwalk, rec_ptr); - - while (rec_ptr != 0) { - struct tdb_record rec; - bool ok; - - ret = tdb_rec_read(tdb, rec_ptr, &rec); - if (ret == -1) { - goto fail; - } - - if (!TDB_DEAD(&rec)) { - /* no overflow checks, tdb_rec_read checked it */ - tdb_off_t key_ofs = rec_ptr + sizeof(rec); - size_t full_len = rec.key_len + rec.data_len; - uint8_t *buf = NULL; - - TDB_DATA key = { .dsize = rec.key_len }; - TDB_DATA data = { .dsize = rec.data_len }; - - if ((tdb->transaction == NULL) && - (tdb->map_ptr != NULL)) { - ret = tdb_oob(tdb, key_ofs, full_len, 0); - if (ret == -1) { - goto fail; - } - key.dptr = (uint8_t *)tdb->map_ptr + key_ofs; - } else { - buf = tdb_alloc_read(tdb, key_ofs, full_len); - if (buf == NULL) { - goto fail; - } - key.dptr = buf; - } - data.dptr = key.dptr + key.dsize; - - ret = fn(tdb, key, data, private_data); - free(buf); - - count += 1; - - if (ret != 0) { - break; - } - } - - rec_ptr = rec.next; - - ok = tdb_chainwalk_check(tdb, &chainwalk, rec_ptr); - if (!ok) { - goto fail; - } - } - tdb->traverse_read -= 1; - tdb_unlock(tdb, chain, F_RDLCK); - return count; - -fail: - tdb->traverse_read -= 1; - tdb_unlock(tdb, chain, F_RDLCK); - return -1; -} - -_PUBLIC_ int tdb_traverse_key_chain(struct tdb_context *tdb, - TDB_DATA key, - tdb_traverse_func fn, - void *private_data) -{ - uint32_t hash, chain; - int ret; - - hash = tdb->hash_fn(&key); - chain = BUCKET(hash); - ret = tdb_traverse_chain(tdb, chain, fn, private_data); - - return ret; -} diff --git a/ldb-2.0.8/lib/tdb/configure b/ldb-2.0.8/lib/tdb/configure deleted file mode 100755 index d8a8d2a..0000000 --- a/ldb-2.0.8/lib/tdb/configure +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -PREVPATH=`dirname $0` - -if [ -f $PREVPATH/../../buildtools/bin/waf ]; then - WAF=../../buildtools/bin/waf -elif [ -f $PREVPATH/buildtools/bin/waf ]; then - WAF=./buildtools/bin/waf -else - echo "replace: Unable to find waf" - exit 1 -fi - -# using JOBS=1 gives maximum compatibility with -# systems like AIX which have broken threading in python -JOBS=1 -export JOBS - -cd . || exit 1 -$PYTHON $WAF configure "$@" || exit 1 -cd $PREVPATH diff --git a/ldb-2.0.8/lib/tdb/docs/README b/ldb-2.0.8/lib/tdb/docs/README deleted file mode 100644 index 86d46a3..0000000 --- a/ldb-2.0.8/lib/tdb/docs/README +++ /dev/null @@ -1,273 +0,0 @@ -tdb - a trivial database system -tridge@linuxcare.com December 1999 -================================== - -This is a simple database API. It was inspired by the realisation that -in Samba we have several ad-hoc bits of code that essentially -implement small databases for sharing structures between parts of -Samba. As I was about to add another I realised that a generic -database module was called for to replace all the ad-hoc bits. - -I based the interface on gdbm. I couldn't use gdbm as we need to be -able to have multiple writers to the databases at one time. - -Compilation ------------ - -add HAVE_MMAP=1 to use mmap instead of read/write -add NOLOCK=1 to disable locking code - -Testing -------- - -Compile tdbtest.c and link with gdbm for testing. tdbtest will perform -identical operations via tdb and gdbm then make sure the result is the -same - -Also included is tdbtool, which allows simple database manipulation -on the commandline. - -tdbtest and tdbtool are not built as part of Samba, but are included -for completeness. - -Interface ---------- - -The interface is very similar to gdbm except for the following: - -- different open interface. The tdb_open call is more similar to a - traditional open() -- no tdbm_reorganise() function -- no tdbm_sync() function. No operations are cached in the library anyway -- added a tdb_traverse() function for traversing the whole database -- added transactions support - -A general rule for using tdb is that the caller frees any returned -TDB_DATA structures. Just call free(p.dptr) to free a TDB_DATA -return value called p. This is the same as gdbm. - -here is a full list of tdb functions with brief descriptions. - - ----------------------------------------------------------------------- -TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode) - - open the database, creating it if necessary - - The open_flags and mode are passed straight to the open call on the database - file. A flags value of O_WRONLY is invalid - - The hash size is advisory, use zero for a default value. - - return is NULL on error - - possible tdb_flags are: - TDB_CLEAR_IF_FIRST - clear database if we are the only one with it open - TDB_INTERNAL - don't use a file, instead store the data in - memory. The filename is ignored in this case. - TDB_NOLOCK - don't do any locking - TDB_NOMMAP - don't use mmap - TDB_NOSYNC - don't synchronise transactions to disk - TDB_SEQNUM - maintain a sequence number - TDB_VOLATILE - activate the per-hashchain freelist, default 5 - TDB_ALLOW_NESTING - allow transactions to nest - TDB_DISALLOW_NESTING - disallow transactions to nest - ----------------------------------------------------------------------- -TDB_CONTEXT *tdb_open_ex(char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode, - const struct tdb_logging_context *log_ctx, - tdb_hash_func hash_fn) - -This is like tdb_open(), but allows you to pass an initial logging and -hash function. Be careful when passing a hash function - all users of -the database must use the same hash function or you will get data -corruption. - - ----------------------------------------------------------------------- -char *tdb_error(TDB_CONTEXT *tdb); - - return a error string for the last tdb error - ----------------------------------------------------------------------- -int tdb_close(TDB_CONTEXT *tdb); - - close a database - ----------------------------------------------------------------------- -TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key); - - fetch an entry in the database given a key - if the return value has a null dptr then a error occurred - - caller must free the resulting data - ----------------------------------------------------------------------- -int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, - int (*parser)(TDB_DATA key, TDB_DATA data, - void *private_data), - void *private_data); - - Hand a record to a parser function without allocating it. - - This function is meant as a fast tdb_fetch alternative for large records - that are frequently read. The "key" and "data" arguments point directly - into the tdb shared memory, they are not aligned at any boundary. - - WARNING: The parser is called while tdb holds a lock on the record. DO NOT - call other tdb routines from within the parser. Also, for good performance - you should make the parser fast to allow parallel operations. - - tdb_parse_record returns -1 if the record was not found. If the record was - found, the return value of "parser" is passed up to the caller. - ----------------------------------------------------------------------- -int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key); - - check if an entry in the database exists - - note that 1 is returned if the key is found and 0 is returned if not found - this doesn't match the conventions in the rest of this module, but is - compatible with gdbm - ----------------------------------------------------------------------- -int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, - TDB_DATA key, TDB_DATA dbuf, void *state), void *state); - - traverse the entire database - calling fn(tdb, key, data, state) on each - element. - - return -1 on error or the record count traversed - - if fn is NULL then it is not called - - a non-zero return value from fn() indicates that the traversal - should stop. Traversal callbacks may not start transactions. - - WARNING: The data buffer given to the callback fn does NOT meet the - alignment restrictions malloc gives you. - ----------------------------------------------------------------------- -int tdb_traverse_read(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, - TDB_DATA key, TDB_DATA dbuf, void *state), void *state); - - traverse the entire database - calling fn(tdb, key, data, state) on - each element, but marking the database read only during the - traversal, so any write operations will fail. This allows tdb to - use read locks, which increases the parallelism possible during the - traversal. - - return -1 on error or the record count traversed - - if fn is NULL then it is not called - - a non-zero return value from fn() indicates that the traversal - should stop. Traversal callbacks may not start transactions. - ----------------------------------------------------------------------- -TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb); - - find the first entry in the database and return its key - - the caller must free the returned data - ----------------------------------------------------------------------- -TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key); - - find the next entry in the database, returning its key - - the caller must free the returned data - ----------------------------------------------------------------------- -int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key); - - delete an entry in the database given a key - ----------------------------------------------------------------------- -int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); - - store an element in the database, replacing any existing element - with the same key - - If flag==TDB_INSERT then don't overwrite an existing entry - If flag==TDB_MODIFY then don't create a new entry - - return 0 on success, -1 on failure - ----------------------------------------------------------------------- -int tdb_writelock(TDB_CONTEXT *tdb); - - lock the database. If we already have it locked then don't do anything - ----------------------------------------------------------------------- -int tdb_writeunlock(TDB_CONTEXT *tdb); - unlock the database - ----------------------------------------------------------------------- -int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key); - - lock one hash chain. This is meant to be used to reduce locking - contention - it cannot guarantee how many records will be locked - ----------------------------------------------------------------------- -int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key); - - unlock one hash chain - ----------------------------------------------------------------------- -int tdb_transaction_start(TDB_CONTEXT *tdb) - - start a transaction. All operations after the transaction start can - either be committed with tdb_transaction_commit() or cancelled with - tdb_transaction_cancel(). - - If you call tdb_transaction_start() again on the same tdb context - while a transaction is in progress, then the same transaction - buffer is re-used. The number of tdb_transaction_{commit,cancel} - operations must match the number of successful - tdb_transaction_start() calls. - - Note that transactions are by default disk synchronous, and use a - recover area in the database to automatically recover the database - on the next open if the system crashes during a transaction. You - can disable the synchronous transaction recovery setup using the - TDB_NOSYNC flag, which will greatly speed up operations at the risk - of corrupting your database if the system crashes. - - Operations made within a transaction are not visible to other users - of the database until a successful commit. - ----------------------------------------------------------------------- -int tdb_transaction_cancel(TDB_CONTEXT *tdb) - - cancel a current transaction, discarding all write and lock - operations that have been made since the transaction started. - - ----------------------------------------------------------------------- -int tdb_transaction_commit(TDB_CONTEXT *tdb) - - commit a current transaction, updating the database and releasing - the transaction locks. - ----------------------------------------------------------------------- -int tdb_transaction_prepare_commit(TDB_CONTEXT *tdb) - - prepare to commit a current transaction, for two-phase commits. - Once prepared for commit, the only allowed calls are - tdb_transaction_commit() or tdb_transaction_cancel(). Preparing - allocates disk space for the pending updates, so a subsequent - commit should succeed (barring any hardware failures). - ----------------------------------------------------------------------- -int tdb_check(TDB_CONTEXT *tdb, - int (*check)(TDB_DATA key, TDB_DATA data, void *private_data), - void *private_data);) - - check the consistency of the database, calling back the check function - (if non-NULL) with each record. If some consistency check fails, or - the supplied check function returns -1, tdb_check returns -1, otherwise - 0. Note that logging function (if set) will be called with additional - information on the corruption found. diff --git a/ldb-2.0.8/lib/tdb/docs/mainpage.dox b/ldb-2.0.8/lib/tdb/docs/mainpage.dox deleted file mode 100644 index d130769..0000000 --- a/ldb-2.0.8/lib/tdb/docs/mainpage.dox +++ /dev/null @@ -1,61 +0,0 @@ -/** - -@mainpage - -This is a simple database API. It was inspired by the realisation that in Samba -we have several ad-hoc bits of code that essentially implement small databases -for sharing structures between parts of Samba. - -The interface is based on gdbm. gdbm couldn't be use as we needed to be able to -have multiple writers to the databases at one time. - -@section tdb_download Download - -You can download the latest releases of tdb from the -tdb directory on the samba public source -archive. - -You can download the latest code either via git or rsync. - -To fetch via git see the following guide: - -Using Git for Samba Development -Once you have cloned the tree switch to the master branch and cd into the source/lib/tdb directory. - -To fetch via rsync use these commands: - -
      -  rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/tdb .
      -  rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/replace .
      -
      - -and build in tdb. It will find the replace library in the directory above -automatically. - -@section tdb_bugs Discussion and bug reports - -tdb does not currently have its own mailing list or bug tracking system. For now, -please use the -samba-technical -mailing list, and the Samba bugzilla bug -tracking system. - - -@section tdb_compilation Compilation - -add HAVE_MMAP=1 to use mmap instead of read/write -add NOLOCK=1 to disable locking code - -@section tdb_testing Testing - -Compile tdbtest.c and link with gdbm for testing. tdbtest will perform -identical operations via tdb and gdbm then make sure the result is the -same - -Also included is tdbtool, which allows simple database manipulation -on the commandline. - -tdbtest and tdbtool are not built as part of Samba, but are included -for completeness. - -*/ diff --git a/ldb-2.0.8/lib/tdb/docs/mutex.txt b/ldb-2.0.8/lib/tdb/docs/mutex.txt deleted file mode 100644 index a5a7542..0000000 --- a/ldb-2.0.8/lib/tdb/docs/mutex.txt +++ /dev/null @@ -1,136 +0,0 @@ -Tdb is a hashtable database with multiple concurrent writer and external -record lock support. For speed reasons, wherever possible tdb uses a shared -memory mapped area for data access. In its currently released form, it uses -fcntl byte-range locks to coordinate access to the data itself. - -The tdb data is organized as a hashtable. Hash collisions are dealt with by -forming a linked list of records that share a hash value. The individual -linked lists are protected across processes with 1-byte fcntl locks on the -starting pointer of the linked list representing a hash value. - -The external locking API of tdb allows one to lock individual records. Instead of -really locking individual records, the tdb API locks a complete linked list -with a fcntl lock. - -The external locking API of tdb also allows one to lock the complete database, and -ctdb uses this facility to freeze databases during a recovery. While the -so-called allrecord lock is held, all linked lists and all individual records -are frozen alltogether. Tdb achieves this by locking the complete file range -with a single fcntl lock. Individual 1-byte locks for the linked lists -conflict with this. Access to records is prevented by the one large fnctl byte -range lock. - -Fcntl locks have been chosen for tdb for two reasons: First they are portable -across all current unixes. Secondly they provide auto-cleanup. If a process -dies while holding a fcntl lock, the lock is given up as if it was explicitly -unlocked. Thus fcntl locks provide a very robust locking scheme, if a process -dies for any reason the database will not stay blocked until reboot. This -robustness is very important for long-running services, a reboot is not an -option for most users of tdb. - -Unfortunately, during stress testing, fcntl locks have turned out to be a major -problem for performance. The particular problem that was seen happens when -ctdb on a busy server does a recovery. A recovery means that ctdb has to -freeze all tdb databases for some time, usually a few seconds. This is done -with the allrecord lock. During the recovery phase on a busy server many smbd -processes try to access the tdb file with blocking fcntl calls. The specific -test in question easily reproduces 7,000 processes piling up waiting for -1-byte fcntl locks. When ctdb is done with the recovery, it gives up the -allrecord lock, covering the whole file range. All 7,000 processes waiting for -1-byte fcntl locks are woken up, trying to acquire their lock. The special -implementation of fcntl locks in Linux (up to 2013-02-12 at least) protects -all fcntl lock operations with a single system-wide spinlock. If 7,000 process -waiting for the allrecord lock to become released this leads to a thundering -herd condition, all CPUs are spinning on that single spinlock. - -Functionally the kernel is fine, eventually the thundering herd slows down and -every process correctly gets his share and locking range, but the performance -of the system while the herd is active is worse than expected. - -The thundering herd is only the worst case scenario for fcntl lock use. The -single spinlock for fcntl operations is also a performance penalty for normal -operations. In the cluster case, every read and write SMB request has to do -two fcntl calls to provide correct SMB mandatory locks. The single spinlock -is one source of serialization for the SMB read/write requests, limiting the -parallelism that can be achieved in a multi-core system. - -While trying to tune his servers, Ira Cooper, Samba Team member, found fcntl -locks to be a problem on Solaris as well. Ira pointed out that there is a -potential alternative locking mechanism that might be more scalable: Process -shared robust mutexes, as defined by Posix 2008 for example via - -http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_setpshared.html -http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_setrobust.html - -Pthread mutexes provide one of the core mechanisms in posix threads to protect -in-process data structures from concurrent access by multiple threads. In the -Linux implementation, a pthread_mutex_t is represented by a data structure in -user space that requires no kernel calls in the uncontended case for locking -and unlocking. Locking and unlocking in the uncontended case is implemented -purely in user space with atomic CPU instructions and thus are very fast. - -The setpshared functions indicate to the kernel that the mutex is about to be -shared between processes in a common shared memory area. - -The process shared posix mutexes have the potential to replace fcntl locking -to coordinate mmap access for tdbs. However, they are missing the criticial -auto-cleanup property that fcntl provides when a process dies. A process that -dies hard while holding a shared mutex has no chance to clean up the protected -data structures and unlock the shared mutex. Thus with a pure process shared -mutex the mutex will remain locked forever until the data structures are -re-initialized from scratch. - -With the robust mutexes defined by Posix the process shared mutexes have been -extended with a limited auto-cleanup property. If a mutex has been declared -robust, when a process exits while holding that mutex, the next process trying -to lock the mutex will get the special error message EOWNERDEAD. This informs -the caller that the data structures the mutex protects are potentially corrupt -and need to be cleaned up. - -The error message EOWNERDEAD when trying to lock a mutex is an extension over -the fcntl functionality. A process that does a blocking fcntl lock call is not -informed about whether the lock was explicitly freed by a process still alive -or due to an unplanned process exit. At the time of this writing (February -2013), at least Linux and OpenSolaris also implement the robustness feature of -process-shared mutexes. - -Converting the tdb locking mechanism from fcntl to mutexes has to take care of -both types of locks that are used on tdb files. - -The easy part is to use mutexes to replace the 1-byte linked list locks -covering the individual hashes. Those can be represented by a mutex each. - -Covering the allrecord lock is more difficult. The allrecord lock uses a fcntl -lock spanning all hash list locks simultaneously. This basic functionality is -not easily possible with mutexes. A mutex carries 1 bit of information, a -fcntl lock can carry an arbitrary amount of information. - -In order to support the allrecord lock, we have an allrecord_lock variable -protected by an allrecord_mutex. The coordination between the allrecord lock -and the chainlocks works like this: - -- Getting a chain lock works like this: - - 1. get chain mutex - 2. return success if allrecord_lock is F_UNLCK (not locked) - 3. return success if allrecord_lock is F_RDLCK (locked readonly) - and we only need a read lock. - 4. release chain mutex - 5. wait for allrecord_mutex - 6. unlock allrecord_mutex - 7. goto 1. - -- Getting the allrecord lock: - - 1. get the allrecord mutex - 2. return error if allrecord_lock is not F_UNLCK (it's locked) - 3. set allrecord_lock to the desired value. - 4. in a loop: lock(blocking) / unlock each chain mutex. - 5. return success. - -- allrecord lock upgrade: - - 1. check we already have the allrecord lock with F_RDLCK. - 3. set allrecord_lock to F_WRLCK - 4. in a loop: lock(blocking) / unlock each chain mutex. - 5. return success. diff --git a/ldb-2.0.8/lib/tdb/docs/tdb.magic b/ldb-2.0.8/lib/tdb/docs/tdb.magic deleted file mode 100644 index f5619e7..0000000 --- a/ldb-2.0.8/lib/tdb/docs/tdb.magic +++ /dev/null @@ -1,10 +0,0 @@ -# Magic file(1) information about tdb files. -# -# Install this into /etc/magic or the corresponding location for your -# system, or pass as a -m argument to file(1). - -# You may use and redistribute this file without restriction. - -0 string TDB\ file TDB database ->32 lelong =0x2601196D version 6, little-endian ->>36 lelong x hash size %d bytes diff --git a/ldb-2.0.8/lib/tdb/docs/tracing.txt b/ldb-2.0.8/lib/tdb/docs/tracing.txt deleted file mode 100644 index 98c5db9..0000000 --- a/ldb-2.0.8/lib/tdb/docs/tracing.txt +++ /dev/null @@ -1,46 +0,0 @@ -How And Why To Use TDB Tracing -============================== - -You can trace all TDB operations, using TDB_TRACE. It is not complete -(error conditions which expect to the logged will not always be traced -correctly, so you should set up a logging function too), but is designed -to collect benchmark-style traces to allow us to optimize TDB. - -Note: tracing is not efficient, and the trace files are huge: a -traverse of the database is particularly large! But they compress very -well with rzip (http://rzip.samba.org) - -How to gather trace files: --------------------------- -1) Uncomment /* #define TDB_TRACE 1 */ in tdb_private.h. -2) Rebuild TDB, and everything that uses it. -3) Run something. - -Your trace files will be called .trace.. These files -will not be overwritten: if the same process reopens the same TDB, an -error will be logged and tracing will be disabled. - -How to replay trace files: --------------------------- -1) For benchmarking, remember to rebuild tdb with #define TDB_TRACE commented - out again! -2) Grab the latest "replace_trace.c" from CCAN's tdb module (tools/ dir): - http://ccan.ozlabs.org/tarballs/tdb.tar.bz2 -3) Compile up replay_trace, munging as necessary. -4) Run replay_trace ... - -If given more than one trace file (presumably from the same tdb) -replay_trace will try to figure out the dependencies between the operations -and fire off a child to run each trace. Occasionally it gets stuck, in -which case it will add another dependency and retry. Eventually it will -give a speed value. - -replay_trace can intuit the existence of previous data in the tdb (ie. -activity prior to the trace(s) supplied) and will prepopulate as -neccessary. - -You can run --quiet for straight benchmark results, and -n to run multiple -times (this saves time, since it need only calculate dependencies once). - -Good luck! -Rusty Russell diff --git a/ldb-2.0.8/lib/tdb/doxy.config b/ldb-2.0.8/lib/tdb/doxy.config deleted file mode 100644 index f55e9c3..0000000 --- a/ldb-2.0.8/lib/tdb/doxy.config +++ /dev/null @@ -1,1697 +0,0 @@ -# Doxyfile 1.7.3 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" "). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = tdb - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = 1.2.9 - -# Using the PROJECT_BRIEF tag one can provide an optional one line description for a project that appears at the top of each page and should give viewer a quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = - -# With the PROJECT_LOGO tag one can specify an logo or icon that is -# included in the documentation. The maximum height of the logo should not -# exceed 55 pixels and the maximum width should not exceed 200 pixels. -# Doxygen will copy the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = docs - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful if your file system -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = YES - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this -# tag. The format is ext=language, where ext is a file extension, and language -# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, -# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions -# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also makes the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penalty. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will roughly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = NO - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespaces are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = YES - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = YES - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO -# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper type resolution of all parameters of a function it will reject a -# match between the prototype and the implementation of a member function even if there is only one candidate or it is obvious which candidate to choose by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen -# will still accept a match between prototype and implementation in such cases. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or macro consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and macros in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. The create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted -# DoxygenLayout.xml will be used as the name of the layout file. - -LAYOUT_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# The WARN_NO_PARAMDOC option can be enabled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = include \ - docs - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh -# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py -# *.f90 *.f *.for *.vhd *.vhdl - -FILE_PATTERNS = *.cpp \ - *.cc \ - *.c \ - *.h \ - *.hh \ - *.hpp \ - *.dox - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = */.git/* - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. -# If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. -# Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. -# The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty or if -# non of the patterns match the file name, INPUT_FILTER is applied. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) -# and it is also possible to disable source filtering for a specific pattern -# using *.ext= (so without naming a filter). This option only has effect when -# FILTER_SOURCE_FILES is enabled. - -FILTER_SOURCE_PATTERNS = - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. -# Otherwise they will link to the documentation. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the stylesheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. -# The allowed range is 0 to 359. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use -# grayscales only. A value of 255 will produce the most vivid colors. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, -# and 100 does not change the gamma. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. - -HTML_TIMESTAMP = NO - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = NO - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# -# Qt Help Project / Custom Filters. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# -# Qt Help Project / Filter Attributes. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [0,1..20]) -# that doxygen will group on one line in the generated HTML documentation. -# Note that a value of 0 will completely suppress the enum values from appearing in the overview section. - -ENUM_VALUES_PER_LINE = 4 - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NONE - -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. - -USE_INLINE_TREES = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open -# links to external symbols imported via tag files in a separate window. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files -# in the HTML output before the changes have effect. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax -# (see http://www.mathjax.org) which uses client side Javascript for the -# rendering instead of using prerendered bitmaps. Use this if you do not -# have LaTeX installed or if you want to formulas look prettier in the HTML -# output. When enabled you also need to install MathJax separately and -# configure the path to it using the MATHJAX_RELPATH option. - -USE_MATHJAX = NO - -# When MathJax is enabled you need to specify the location relative to the -# HTML output directory using the MATHJAX_RELPATH option. The destination -# directory should contain the MathJax.js script. For instance, if the mathjax -# directory is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the mathjax.org site, so you can quickly see the result without installing -# MathJax, but it is strongly recommended to install a local copy of MathJax -# before deployment. - -MATHJAX_RELPATH = http://www.mathjax.org/mathjax - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. - -SEARCHENGINE = NO - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a PHP enabled web server instead of at the web client -# using Javascript. Doxygen will generate the search PHP script and index -# file to put on the web server. The advantage of the server -# based approach is that it scales better to large projects and allows -# full text search. The disadvantages are that it is more difficult to setup -# and does not have live searching capabilities. - -SERVER_BASED_SEARCH = NO - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = YES - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the -# Makefile that is written to the output directory. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include -# source code with syntax highlighting in the LaTeX output. -# Note that which sources are shown also depends on other settings -# such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = YES - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. -# This is useful -# if you want to understand what is going on. -# On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = YES - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = YES - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = DOXYGEN \ - PRINTF_ATTRIBUTE(x,y)= - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition that overrules the definition found in the source code. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all references to function-like macros -# that are alone on a line, have an all uppercase name, and do not end with a -# semicolon, because these will confuse the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option also works with HAVE_DOT disabled, but it is recommended to -# install and use dot, since it yields more powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is -# allowed to run in parallel. When set to 0 (the default) doxygen will -# base this on the number of processors available in the system. You can set it -# explicitly to a value larger than 0 to get control over the balance -# between CPU load and processing speed. - -DOT_NUM_THREADS = 0 - -# By default doxygen will write a font called Helvetica to the output -# directory and reference it in all dot files that doxygen generates. -# When you want a differently looking font you can specify the font name -# using DOT_FONTNAME. You need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory -# containing the font. - -DOT_FONTNAME = FreeSans - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot -# can find it using this tag. - -DOT_FONTPATH = - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will generate a graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, svg, gif or svg. -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the -# \mscfile command). - -MSCFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = YES - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES diff --git a/ldb-2.0.8/lib/tdb/include/tdb.h b/ldb-2.0.8/lib/tdb/include/tdb.h deleted file mode 100644 index 825ceed..0000000 --- a/ldb-2.0.8/lib/tdb/include/tdb.h +++ /dev/null @@ -1,1025 +0,0 @@ -#ifndef __TDB_H__ -#define __TDB_H__ - -/* - Unix SMB/CIFS implementation. - - trivial database library - - Copyright (C) Andrew Tridgell 1999-2004 - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -/** - * @defgroup tdb The tdb API - * - * tdb is a Trivial database. In concept, it is very much like GDBM, and BSD's - * DB except that it allows multiple simultaneous writers and uses locking - * internally to keep writers from trampling on each other. tdb is also - * extremely small. - * - * @section tdb_interface Interface - * - * The interface is very similar to gdbm except for the following: - * - *
        - *
      • different open interface. The tdb_open call is more similar to a - * traditional open()
      • - *
      • no tdbm_reorganise() function
      • - *
      • no tdbm_sync() function. No operations are cached in the library - * anyway
      • - *
      • added a tdb_traverse() function for traversing the whole database
      • - *
      • added transactions support
      • - *
      - * - * A general rule for using tdb is that the caller frees any returned TDB_DATA - * structures. Just call free(p.dptr) to free a TDB_DATA return value called p. - * This is the same as gdbm. - * - * @{ - */ - -/** Flags to tdb_store() */ -#define TDB_REPLACE 1 /** Unused */ -#define TDB_INSERT 2 /** Don't overwrite an existing entry */ -#define TDB_MODIFY 3 /** Don't create an existing entry */ - -/** Flags for tdb_open() */ -#define TDB_DEFAULT 0 /** just a readability place holder */ -#define TDB_CLEAR_IF_FIRST 1 /** If this is the first open, wipe the db */ -#define TDB_INTERNAL 2 /** Don't store on disk */ -#define TDB_NOLOCK 4 /** Don't do any locking */ -#define TDB_NOMMAP 8 /** Don't use mmap */ -#define TDB_CONVERT 16 /** Convert endian (internal use) */ -#define TDB_BIGENDIAN 32 /** Header is big-endian (internal use) */ -#define TDB_NOSYNC 64 /** Don't use synchronous transactions */ -#define TDB_SEQNUM 128 /** Maintain a sequence number */ -#define TDB_VOLATILE 256 /** Activate the per-hashchain freelist, default 5 */ -#define TDB_ALLOW_NESTING 512 /** Allow transactions to nest */ -#define TDB_DISALLOW_NESTING 1024 /** Disallow transactions to nest */ -#define TDB_INCOMPATIBLE_HASH 2048 /** Better hashing: can't be opened by tdb < 1.2.6. */ -#define TDB_MUTEX_LOCKING 4096 /** optimized locking using robust mutexes if supported, - only with tdb >= 1.3.0 and TDB_CLEAR_IF_FIRST - after checking tdb_runtime_check_for_robust_mutexes() */ - -/** The tdb error codes */ -enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK, - TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT, - TDB_ERR_NOEXIST, TDB_ERR_EINVAL, TDB_ERR_RDONLY, - TDB_ERR_NESTING}; - -/** Debugging uses one of the following levels */ -enum tdb_debug_level {TDB_DEBUG_FATAL = 0, TDB_DEBUG_ERROR, - TDB_DEBUG_WARNING, TDB_DEBUG_TRACE}; - -/** The tdb data structure */ -typedef struct TDB_DATA { - unsigned char *dptr; - size_t dsize; -} TDB_DATA; - -#ifndef PRINTF_ATTRIBUTE -#if (__GNUC__ >= 3) -/** Use gcc attribute to check printf fns. a1 is the 1-based index of - * the parameter containing the format, and a2 the index of the first - * argument. Note that some gcc 2.x versions don't handle this - * properly **/ -#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) -#else -#define PRINTF_ATTRIBUTE(a1, a2) -#endif -#endif - -/** This is the context structure that is returned from a db open. */ -typedef struct tdb_context TDB_CONTEXT; - -typedef int (*tdb_traverse_func)(struct tdb_context *, TDB_DATA, TDB_DATA, void *); -typedef void (*tdb_log_func)(struct tdb_context *, enum tdb_debug_level, const char *, ...) PRINTF_ATTRIBUTE(3, 4); -typedef unsigned int (*tdb_hash_func)(TDB_DATA *key); - -struct tdb_logging_context { - tdb_log_func log_fn; - void *log_private; -}; - -/** - * @brief Open the database and creating it if necessary. - * - * @param[in] name The name of the db to open. - * - * @param[in] hash_size The hash size is advisory, use zero for a default - * value. - * - * @param[in] tdb_flags The flags to use to open the db:\n\n - * TDB_CLEAR_IF_FIRST - Clear database if we are the - * only one with it open\n - * TDB_INTERNAL - Don't use a file, instead store the - * data in memory. The filename is - * ignored in this case.\n - * TDB_NOLOCK - Don't do any locking\n - * TDB_NOMMAP - Don't use mmap\n - * TDB_NOSYNC - Don't synchronise transactions to disk\n - * TDB_SEQNUM - Maintain a sequence number\n - * TDB_VOLATILE - activate the per-hashchain freelist, - * default 5.\n - * TDB_ALLOW_NESTING - Allow transactions to nest.\n - * TDB_DISALLOW_NESTING - Disallow transactions to nest.\n - * TDB_INCOMPATIBLE_HASH - Better hashing: can't be opened by tdb < 1.2.6.\n - * TDB_MUTEX_LOCKING - Optimized locking using robust mutexes if supported, - * can't be opened by tdb < 1.3.0. - * Only valid in combination with TDB_CLEAR_IF_FIRST - * after checking tdb_runtime_check_for_robust_mutexes()\n - * - * @param[in] open_flags Flags for the open(2) function. - * - * @param[in] mode The mode for the open(2) function. - * - * @return A tdb context structure, NULL on error. - */ -struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode); - -/** - * @brief Open the database and creating it if necessary. - * - * This is like tdb_open(), but allows you to pass an initial logging and - * hash function. Be careful when passing a hash function - all users of the - * database must use the same hash function or you will get data corruption. - * - * @param[in] name The name of the db to open. - * - * @param[in] hash_size The hash size is advisory, use zero for a default - * value. - * - * @param[in] tdb_flags The flags to use to open the db:\n\n - * TDB_CLEAR_IF_FIRST - Clear database if we are the - * only one with it open\n - * TDB_INTERNAL - Don't use a file, instead store the - * data in memory. The filename is - * ignored in this case.\n - * TDB_NOLOCK - Don't do any locking\n - * TDB_NOMMAP - Don't use mmap\n - * TDB_NOSYNC - Don't synchronise transactions to disk\n - * TDB_SEQNUM - Maintain a sequence number\n - * TDB_VOLATILE - activate the per-hashchain freelist, - * default 5.\n - * TDB_ALLOW_NESTING - Allow transactions to nest.\n - * TDB_DISALLOW_NESTING - Disallow transactions to nest.\n - * TDB_INCOMPATIBLE_HASH - Better hashing: can't be opened by tdb < 1.2.6.\n - * TDB_MUTEX_LOCKING - Optimized locking using robust mutexes if supported, - * can't be opened by tdb < 1.3.0. - * Only valid in combination with TDB_CLEAR_IF_FIRST - * after checking tdb_runtime_check_for_robust_mutexes()\n - * - * @param[in] open_flags Flags for the open(2) function. - * - * @param[in] mode The mode for the open(2) function. - * - * @param[in] log_ctx The logging function to use. - * - * @param[in] hash_fn The hash function you want to use. - * - * @return A tdb context structure, NULL on error. - * - * @see tdb_open() - */ -struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode, - const struct tdb_logging_context *log_ctx, - tdb_hash_func hash_fn); - -/** - * @brief Set the maximum number of dead records per hash chain. - * - * @param[in] tdb The database handle to set the maximum. - * - * @param[in] max_dead The maximum number of dead records per hash chain. - */ -void tdb_set_max_dead(struct tdb_context *tdb, int max_dead); - -/** - * @brief Reopen a tdb. - * - * This can be used after a fork to ensure that we have an independent seek - * pointer from our parent and to re-establish locks. - * - * @param[in] tdb The database to reopen. It will be free'd on error! - * - * @return 0 on success, -1 on error. - * - * @note Don't call tdb_error() after this function cause the tdb context will - * be freed on error. - */ -int tdb_reopen(struct tdb_context *tdb); - -/** - * @brief Reopen all tdb's - * - * If the parent is longlived (ie. a parent daemon architecture), we know it - * will keep it's active lock on a tdb opened with CLEAR_IF_FIRST. Thus for - * child processes we don't have to add an active lock. This is essential to - * improve performance on systems that keep POSIX locks as a non-scalable data - * structure in the kernel. - * - * @param[in] parent_longlived Whether the parent is longlived or not. - * - * @return 0 on success, -1 on error. - */ -int tdb_reopen_all(int parent_longlived); - -/** - * @brief Set a different tdb logging function. - * - * @param[in] tdb The tdb to set the logging function. - * - * @param[in] log_ctx The logging function to set. - */ -void tdb_set_logging_function(struct tdb_context *tdb, const struct tdb_logging_context *log_ctx); - -/** - * @brief Get the tdb last error code. - * - * @param[in] tdb The tdb to get the error code from. - * - * @return A TDB_ERROR code. - * - * @see TDB_ERROR - */ -enum TDB_ERROR tdb_error(struct tdb_context *tdb); - -/** - * @brief Get a error string for the last tdb error - * - * @param[in] tdb The tdb to get the error code from. - * - * @return An error string. - */ -const char *tdb_errorstr(struct tdb_context *tdb); - -/** - * @brief Fetch an entry in the database given a key. - * - * The caller must free the resulting data. - * - * @param[in] tdb The tdb to fetch the key. - * - * @param[in] key The key to fetch. - * - * @return The key entry found in the database, NULL on error with - * TDB_ERROR set. - * - * @see tdb_error() - * @see tdb_errorstr() - */ -TDB_DATA tdb_fetch(struct tdb_context *tdb, TDB_DATA key); - -/** - * @brief Hand a record to a parser function without allocating it. - * - * This function is meant as a fast tdb_fetch alternative for large records - * that are frequently read. The "key" and "data" arguments point directly - * into the tdb shared memory, they are not aligned at any boundary. - * - * @warning The parser is called while tdb holds a lock on the record. DO NOT - * call other tdb routines from within the parser. Also, for good performance - * you should make the parser fast to allow parallel operations. - * - * @param[in] tdb The tdb to parse the record. - * - * @param[in] key The key to parse. - * - * @param[in] parser The parser to use to parse the data. - * - * @param[in] private_data A private data pointer which is passed to the parser - * function. - * - * @return -1 if the record was not found. If the record was found, - * the return value of "parser" is passed up to the caller. - */ -int tdb_parse_record(struct tdb_context *tdb, TDB_DATA key, - int (*parser)(TDB_DATA key, TDB_DATA data, - void *private_data), - void *private_data); - -/** - * @brief Delete an entry in the database given a key. - * - * @param[in] tdb The tdb to delete the key. - * - * @param[in] key The key to delete. - * - * @return 0 on success, -1 if the key doesn't exist. - */ -int tdb_delete(struct tdb_context *tdb, TDB_DATA key); - -/** - * @brief Store an element in the database. - * - * This replaces any existing element with the same key. - * - * @param[in] tdb The tdb to store the entry. - * - * @param[in] key The key to use to store the entry. - * - * @param[in] dbuf The data to store under the key. - * - * @param[in] flag The flags to store the key:\n\n - * TDB_INSERT: Don't overwrite an existing entry.\n - * TDB_MODIFY: Don't create a new entry\n - * - * @return 0 on success, -1 on error with error code set. - * - * @see tdb_error() - * @see tdb_errorstr() - */ -int tdb_store(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); - - -/** - * @brief Store an element in the database. - * - * This replaces any existing element with the same key. - * - * @param[in] tdb The tdb to store the entry. - * - * @param[in] key The key to use to store the entry. - * - * @param[in] dbufs A vector of memory chunks to write - * - * @param[in] num_dbufs Length of the dbufs vector - * - * @param[in] flag The flags to store the key:\n\n - * TDB_INSERT: Don't overwrite an existing entry.\n - * TDB_MODIFY: Don't create a new entry\n - * - * @return 0 on success, -1 on error with error code set. - * - * @see tdb_error() - * @see tdb_errorstr() - */ -int tdb_storev(struct tdb_context *tdb, TDB_DATA key, - const TDB_DATA *dbufs, int num_dbufs, int flag); - -/** - * @brief Append data to an entry. - * - * If the entry doesn't exist, it will create a new one. - * - * @param[in] tdb The database to use. - * - * @param[in] key The key to append the data. - * - * @param[in] new_dbuf The data to append to the key. - * - * @return 0 on success, -1 on error with error code set. - * - * @see tdb_error() - * @see tdb_errorstr() - */ -int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf); - -/** - * @brief Close a database. - * - * @param[in] tdb The database to close. The context will be free'd. - * - * @return 0 for success, -1 on error. - * - * @note Don't call tdb_error() after this function cause the tdb context will - * be freed on error. - */ -int tdb_close(struct tdb_context *tdb); - -/** - * @brief Find the first entry in the database and return its key. - * - * The caller must free the returned data. - * - * @param[in] tdb The database to use. - * - * @return The first entry of the database, an empty TDB_DATA entry - * if the database is empty. - */ -TDB_DATA tdb_firstkey(struct tdb_context *tdb); - -/** - * @brief Find the next entry in the database, returning its key. - * - * The caller must free the returned data. - * - * @param[in] tdb The database to use. - * - * @param[in] key The key from which you want the next key. - * - * @return The next entry of the current key, an empty TDB_DATA - * entry if there is no entry. - */ -TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA key); - -/** - * @brief Traverse the entire database. - * - * While traversing the function fn(tdb, key, data, state) is called on each - * element. If fn is NULL then it is not called. A non-zero return value from - * fn() indicates that the traversal should stop. Traversal callbacks may not - * start transactions. - * - * @warning The data buffer given to the callback fn does NOT meet the alignment - * restrictions malloc gives you. - * - * @param[in] tdb The database to traverse. - * - * @param[in] fn The function to call on each entry. - * - * @param[in] private_data The private data which should be passed to the - * traversing function. - * - * @return The record count traversed, -1 on error. - */ -int tdb_traverse(struct tdb_context *tdb, tdb_traverse_func fn, void *private_data); - -/** - * @brief Traverse the entire database. - * - * While traversing the database the function fn(tdb, key, data, state) is - * called on each element, but marking the database read only during the - * traversal, so any write operations will fail. This allows tdb to use read - * locks, which increases the parallelism possible during the traversal. - * - * @param[in] tdb The database to traverse. - * - * @param[in] fn The function to call on each entry. - * - * @param[in] private_data The private data which should be passed to the - * traversing function. - * - * @return The record count traversed, -1 on error. - */ -int tdb_traverse_read(struct tdb_context *tdb, tdb_traverse_func fn, void *private_data); - -/** - * @brief Traverse a single hash chain - * - * Traverse a single hash chain under a single lock operation. No - * database modification is possible in the callback. - * - * This exists for background cleanup of databases. In normal - * operations, traversing a complete database can be much too - * expensive. Databases can have many chains, which will all have to - * be looked at before tdb_traverse finishes. Also tdb_traverse does a - * lot of fcntl activity to protect against concurrent record deletes. - * - * With this you can walk a fraction of the whole tdb, collect the - * entries you want to prune, leave the traverse, and then modify or - * delete the records in a subsequent step. - * - * To walk the entire database, call this function tdb_hash_size() - * times, with 0<=chain - - -2015-04-25 - - - tdbbackup - 8 - Samba - System Administration tools - 3.6 - - - - - tdbbackup - tool for backing up and for validating the integrity of samba .tdb files - - - - - tdbbackup - -s suffix - -v - -h - -n hashsize - -l - - - - - DESCRIPTION - - This tool is part of the samba - 1 suite. - - tdbbackup is a tool that may be used to backup samba .tdb - files. This tool may also be used to verify the integrity of the .tdb files prior - to samba startup or during normal operation. If it finds file damage and it finds - a prior backup the backup file will be restored. - - - - - - OPTIONS - - - - - -h - - Get help information. - - - - - -s suffix - - The -s option allows the administrator to specify a file - backup extension. This way it is possible to keep a history of tdb backup - files by using a new suffix for each backup. - - - - - -v - - The -v will check the database for damages (corrupt data) - which if detected causes the backup to be restored. - - - - - -n hashsize - - The -n option sets the hash size for the new backup tdb. - - - - - -l - - This options disables any locking, by passing TDB_NOLOCK - to tdb_open_ex(). Only use this for database files which - are not used by any other process! And also only if it is otherwise not - possible to open the database, e.g. databases which were created with - mutex locking. - - - - - - - - - COMMANDS - - GENERAL INFORMATION - - - The tdbbackup utility can safely be run at any time. It was designed so - that it can be used at any time to validate the integrity of tdb files, even during Samba - operation. Typical usage for the command will be: - - - tdbbackup [-s suffix] *.tdb - - - Before restarting samba the following command may be run to validate .tdb files: - - - tdbbackup -v [-s suffix] *.tdb - - - Samba .tdb files are stored in various locations, be sure to run backup all - .tdb file on the system. Important files includes: - - - - - secrets.tdb - usual location is in the /usr/local/samba/private - directory, or on some systems in /etc/samba. - - - - passdb.tdb - usual location is in the /usr/local/samba/private - directory, or on some systems in /etc/samba. - - - - *.tdb located in the /usr/local/samba/var directory or on some - systems in the /var/cache or /var/lib/samba directories. - - - - - - - VERSION - - This man page is correct for version 3 of the Samba suite. - - - - AUTHOR - - - The original Samba software and related utilities were created by Andrew Tridgell. - Samba is now developed by the Samba Team as an Open Source project similar to the way - the Linux kernel is developed. - - - The tdbbackup man page was written by John H Terpstra. - - - diff --git a/ldb-2.0.8/lib/tdb/man/tdbdump.8.xml b/ldb-2.0.8/lib/tdb/man/tdbdump.8.xml deleted file mode 100644 index 31e6888..0000000 --- a/ldb-2.0.8/lib/tdb/man/tdbdump.8.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - -2015-04-25 - - - tdbdump - 8 - Samba - System Administration tools - 3.6 - - - - - tdbdump - tool for printing the contents of a TDB file - - - - - tdbdump - -k keyname - -e - -h - filename - - - - - DESCRIPTION - - This tool is part of the samba - 1 suite. - - tdbdump is a very simple utility that 'dumps' the - contents of a TDB (Trivial DataBase) file to standard output in a - human-readable format. - - - This tool can be used when debugging problems with TDB files. It is - intended for those who are somewhat familiar with Samba internals. - - - - - OPTIONS - - - - - -h - - Get help information. - - - - - -k keyname - - The -k option restricts dumping to a single key, if found. - - - - - -e - - The -e tries to dump out from a corrupt database. Naturally, such a dump is unreliable, at best. - - - - - - - - VERSION - - This man page is correct for version 3 of the Samba suite. - - - - AUTHOR - - - The original Samba software and related utilities were created by Andrew Tridgell. - Samba is now developed by the Samba Team as an Open Source project similar to the way - the Linux kernel is developed. - - - The tdbdump man page was written by Jelmer Vernooij. - - - diff --git a/ldb-2.0.8/lib/tdb/man/tdbrestore.8.xml b/ldb-2.0.8/lib/tdb/man/tdbrestore.8.xml deleted file mode 100644 index 034db53..0000000 --- a/ldb-2.0.8/lib/tdb/man/tdbrestore.8.xml +++ /dev/null @@ -1,67 +0,0 @@ - - - -2015-04-25 - - - tdbrestore - 8 - Samba - System Administration tools - 3.6 - - - - - tdbrestore - tool for creating a TDB file out of a tdbdump output - - - - - tdbrestore - tdbfilename - - - - - DESCRIPTION - - This tool is part of the samba - 1 suite. - - tdbrestore is a very simple utility that 'restores' the - contents of dump file into TDB (Trivial DataBase) file. The dump file is obtained from the tdbdump - command. - - - This tool wait on the standard input for the content of the dump and will write the tdb in the tdbfilename - parameter. - - This tool can be used for unpacking the content of tdb as backup mean. - - - - - - VERSION - - This man page is correct for version 3 of the Samba suite. - - - - AUTHOR - - - The original Samba software and related utilities were created by Andrew Tridgell. - Samba is now developed by the Samba Team as an Open Source project similar to the way - the Linux kernel is developed. - - This tool was initially written by Volker Lendecke based on an - idea by Simon McVittie. - - - The tdbrestore man page was written by Matthieu Patou. - - - diff --git a/ldb-2.0.8/lib/tdb/man/tdbtool.8.xml b/ldb-2.0.8/lib/tdb/man/tdbtool.8.xml deleted file mode 100644 index 045cbde..0000000 --- a/ldb-2.0.8/lib/tdb/man/tdbtool.8.xml +++ /dev/null @@ -1,275 +0,0 @@ - - - -2015-04-25 - - - tdbtool - 8 - Samba - System Administration tools - 4.0 - - - - - tdbtool - manipulate the contents TDB files - - - - - - tdbtool - - - - tdbtool - -l - - TDBFILE - - - COMMANDS - - - - - - - DESCRIPTION - - This tool is part of the - samba - 1 suite. - - tdbtool a tool for displaying and - altering the contents of Samba TDB (Trivial DataBase) files. Each - of the commands listed below can be entered interactively or - provided on the command line. - - - - - OPTIONS - - - - - -l - - This options disables any locking, by passing TDB_NOLOCK - to tdb_open_ex(). Only use this for database files which - are not used by any other process! And also only if it is otherwise not - possible to open the database, e.g. databases which were created with - mutex locking. - - - - - - - - - - COMMANDS - - - - - - TDBFILE - Create a new database named - TDBFILE. - - - - - - TDBFILE - Open an existing database named - TDBFILE. - - - - - - Erase the current database. - - - - - - Dump the current database as strings. - - - - - - Dump the current database as connection records. - - - - - - Dump the current database keys as strings. - - - - - - Dump the current database keys as hex values. - - - - - - Print summary information about the - current database. - - - - - - KEY - DATA - - Insert a record into the - current database. - - - - - - KEY - TDBFILE - - Move a record from the - current database into TDBFILE. - - - - - - KEY - DATA - - Store (replace) a record in the - current database. - - - - - - KEY - DATA - - Store (replace) a record in the - current database where key and data are in hex format. - - - - - - KEY - - Show a record by key. - - - - - - KEY - - Delete a record by key. - - - - - - - Print the current database hash table and free list. - - - - - - - Print the current database and free list. - - - - - - COMMAND - - Execute the given system command. - - - - - - - - Print the first record in the current database. - - - - - - - - Print the next record in the current database. - - - - - - - - Check the integrity of the current database. - - - - - - - - Repack a database using a temporary file to remove fragmentation. - - - - - - - - Exit tdbtool. - - - - - - - - CAVEATS - The contents of the Samba TDB files are private - to the implementation and should not be altered with - tdbtool. - - - - - VERSION - This man page is correct for version 3.6 of the Samba suite. - - - - AUTHOR - - The original Samba software and related utilities were - created by Andrew Tridgell. Samba is now developed by the - Samba Team as an Open Source project similar to the way the - Linux kernel is developed. - - - diff --git a/ldb-2.0.8/lib/tdb/pytdb.c b/ldb-2.0.8/lib/tdb/pytdb.c deleted file mode 100644 index 74e80f9..0000000 --- a/ldb-2.0.8/lib/tdb/pytdb.c +++ /dev/null @@ -1,830 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Python interface to tdb. - - Copyright (C) 2004-2006 Tim Potter - Copyright (C) 2007-2008 Jelmer Vernooij - - ** NOTE! The following LGPL license applies to the tdb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include -#include "replace.h" -#include "system/filesys.h" - -/* Include tdb headers */ -#include - -#if PY_MAJOR_VERSION >= 3 -#define PyInt_FromLong PyLong_FromLong -#define PyInt_Check PyLong_Check -#define PyInt_AsLong PyLong_AsLong -#define Py_TPFLAGS_HAVE_ITER 0 -#endif - -/* discard signature of 'func' in favour of 'target_sig' */ -#define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func - -typedef struct { - PyObject_HEAD - TDB_CONTEXT *ctx; - bool closed; -} PyTdbObject; - -static PyTypeObject PyTdb; - -static void PyErr_SetTDBError(TDB_CONTEXT *tdb) -{ - PyErr_SetObject(PyExc_RuntimeError, - Py_BuildValue("(i,s)", tdb_error(tdb), tdb_errorstr(tdb))); -} - -static TDB_DATA PyBytes_AsTDB_DATA(PyObject *data) -{ - TDB_DATA ret; - ret.dptr = (unsigned char *)PyBytes_AsString(data); - ret.dsize = PyBytes_Size(data); - return ret; -} - -static PyObject *PyBytes_FromTDB_DATA(TDB_DATA data) -{ - if (data.dptr == NULL && data.dsize == 0) { - Py_RETURN_NONE; - } else { - PyObject *ret = PyBytes_FromStringAndSize((const char *)data.dptr, - data.dsize); - free(data.dptr); - return ret; - } -} - -#define PyErr_TDB_ERROR_IS_ERR_RAISE(ret, tdb) \ - if (ret != 0) { \ - PyErr_SetTDBError(tdb); \ - return NULL; \ - } - -#define PyErr_TDB_RAISE_IF_CLOSED(self) \ - if (self->closed) { \ - PyErr_SetObject(PyExc_RuntimeError, \ - Py_BuildValue("(i,s)", TDB_ERR_IO, "Database is already closed")); \ - return NULL; \ - } - -#define PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED(self) \ - if (self->closed) { \ - PyErr_SetObject(PyExc_RuntimeError, \ - Py_BuildValue("(i,s)", TDB_ERR_IO, "Database is already closed")); \ - return -1; \ - } - -static PyObject *py_tdb_open(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - char *name = NULL; - int hash_size = 0, tdb_flags = TDB_DEFAULT, flags = O_RDWR, mode = 0600; - TDB_CONTEXT *ctx; - PyTdbObject *ret; - const char *_kwnames[] = { "name", "hash_size", "tdb_flags", "flags", "mode", NULL }; - char **kwnames = discard_const_p(char *, _kwnames); - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|siiii", kwnames, &name, &hash_size, &tdb_flags, &flags, &mode)) - return NULL; - - if (name == NULL) { - tdb_flags |= TDB_INTERNAL; - } - - ctx = tdb_open(name, hash_size, tdb_flags, flags, mode); - if (ctx == NULL) { - PyErr_SetFromErrno(PyExc_IOError); - return NULL; - } - - ret = PyObject_New(PyTdbObject, &PyTdb); - if (!ret) { - tdb_close(ctx); - return NULL; - } - - ret->ctx = ctx; - ret->closed = false; - return (PyObject *)ret; -} - -static PyObject *obj_transaction_cancel(PyTdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - int ret; - - PyErr_TDB_RAISE_IF_CLOSED(self); - - ret = tdb_transaction_cancel(self->ctx); - PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); - Py_RETURN_NONE; -} - -static PyObject *obj_transaction_commit(PyTdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - int ret; - PyErr_TDB_RAISE_IF_CLOSED(self); - ret = tdb_transaction_commit(self->ctx); - PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); - Py_RETURN_NONE; -} - -static PyObject *obj_transaction_prepare_commit(PyTdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - int ret; - PyErr_TDB_RAISE_IF_CLOSED(self); - ret = tdb_transaction_prepare_commit(self->ctx); - PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); - Py_RETURN_NONE; -} - -static PyObject *obj_transaction_start(PyTdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - int ret; - PyErr_TDB_RAISE_IF_CLOSED(self); - ret = tdb_transaction_start(self->ctx); - PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); - Py_RETURN_NONE; -} - -static PyObject *obj_reopen(PyTdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - int ret; - PyErr_TDB_RAISE_IF_CLOSED(self); - ret = tdb_reopen(self->ctx); - if (ret != 0) { - self->closed = true; - PyErr_SetObject(PyExc_RuntimeError, - Py_BuildValue("(i,s)", - TDB_ERR_IO, - "Failed to reopen database")); - return NULL; - } - Py_RETURN_NONE; -} - -static PyObject *obj_lockall(PyTdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - int ret; - PyErr_TDB_RAISE_IF_CLOSED(self); - ret = tdb_lockall(self->ctx); - PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); - Py_RETURN_NONE; -} - -static PyObject *obj_unlockall(PyTdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - int ret; - PyErr_TDB_RAISE_IF_CLOSED(self); - ret = tdb_unlockall(self->ctx); - PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); - Py_RETURN_NONE; -} - -static PyObject *obj_lockall_read(PyTdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - int ret; - PyErr_TDB_RAISE_IF_CLOSED(self); - ret = tdb_lockall_read(self->ctx); - PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); - Py_RETURN_NONE; -} - -static PyObject *obj_unlockall_read(PyTdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - int ret = tdb_unlockall_read(self->ctx); - PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); - Py_RETURN_NONE; -} - -static PyObject *obj_close(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) -{ - int ret; - if (self->closed) - Py_RETURN_NONE; - ret = tdb_close(self->ctx); - self->closed = true; - if (ret != 0) { - PyErr_SetObject(PyExc_RuntimeError, - Py_BuildValue("(i,s)", - TDB_ERR_IO, - "Failed to close database")); - return NULL; - } - Py_RETURN_NONE; -} - -static PyObject *obj_get(PyTdbObject *self, PyObject *args) -{ - TDB_DATA key; - PyObject *py_key; - - PyErr_TDB_RAISE_IF_CLOSED(self); - - if (!PyArg_ParseTuple(args, "O", &py_key)) - return NULL; - - key = PyBytes_AsTDB_DATA(py_key); - if (!key.dptr) - return NULL; - - return PyBytes_FromTDB_DATA(tdb_fetch(self->ctx, key)); -} - -static PyObject *obj_append(PyTdbObject *self, PyObject *args) -{ - TDB_DATA key, data; - PyObject *py_key, *py_data; - int ret; - - PyErr_TDB_RAISE_IF_CLOSED(self); - - if (!PyArg_ParseTuple(args, "OO", &py_key, &py_data)) - return NULL; - - key = PyBytes_AsTDB_DATA(py_key); - if (!key.dptr) - return NULL; - data = PyBytes_AsTDB_DATA(py_data); - if (!data.dptr) - return NULL; - - ret = tdb_append(self->ctx, key, data); - PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); - Py_RETURN_NONE; -} - -static PyObject *obj_firstkey(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyErr_TDB_RAISE_IF_CLOSED(self); - - return PyBytes_FromTDB_DATA(tdb_firstkey(self->ctx)); -} - -static PyObject *obj_nextkey(PyTdbObject *self, PyObject *args) -{ - TDB_DATA key; - PyObject *py_key; - PyErr_TDB_RAISE_IF_CLOSED(self); - - if (!PyArg_ParseTuple(args, "O", &py_key)) - return NULL; - - key = PyBytes_AsTDB_DATA(py_key); - if (!key.dptr) - return NULL; - - return PyBytes_FromTDB_DATA(tdb_nextkey(self->ctx, key)); -} - -static PyObject *obj_delete(PyTdbObject *self, PyObject *args) -{ - TDB_DATA key; - PyObject *py_key; - int ret; - PyErr_TDB_RAISE_IF_CLOSED(self); - - if (!PyArg_ParseTuple(args, "O", &py_key)) - return NULL; - - key = PyBytes_AsTDB_DATA(py_key); - if (!key.dptr) - return NULL; - ret = tdb_delete(self->ctx, key); - PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); - Py_RETURN_NONE; -} - -static int obj_contains(PyTdbObject *self, PyObject *py_key) -{ - TDB_DATA key; - int ret; - PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED(self); - - key = PyBytes_AsTDB_DATA(py_key); - if (!key.dptr) { - PyErr_BadArgument(); - return -1; - } - ret = tdb_exists(self->ctx, key); - if (ret) - return 1; - return 0; -} - -#if PY_MAJOR_VERSION < 3 -static PyObject *obj_has_key(PyTdbObject *self, PyObject *args) -{ - int ret; - PyObject *py_key; - PyErr_TDB_RAISE_IF_CLOSED(self); - - if (!PyArg_ParseTuple(args, "O", &py_key)) - return NULL; - - ret = obj_contains(self, py_key); - if (ret == -1) - return NULL; - if (ret) - Py_RETURN_TRUE; - Py_RETURN_FALSE; - -} -#endif - -static PyObject *obj_store(PyTdbObject *self, PyObject *args) -{ - TDB_DATA key, value; - int ret; - int flag = TDB_REPLACE; - PyObject *py_key, *py_value; - - PyErr_TDB_RAISE_IF_CLOSED(self); - - if (!PyArg_ParseTuple(args, "OO|i", &py_key, &py_value, &flag)) - return NULL; - - key = PyBytes_AsTDB_DATA(py_key); - if (!key.dptr) - return NULL; - value = PyBytes_AsTDB_DATA(py_value); - if (!value.dptr) - return NULL; - - ret = tdb_store(self->ctx, key, value, flag); - PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); - Py_RETURN_NONE; -} - -static PyObject *obj_add_flags(PyTdbObject *self, PyObject *args) -{ - unsigned flags; - - PyErr_TDB_RAISE_IF_CLOSED(self); - - if (!PyArg_ParseTuple(args, "I", &flags)) - return NULL; - - tdb_add_flags(self->ctx, flags); - Py_RETURN_NONE; -} - -static PyObject *obj_remove_flags(PyTdbObject *self, PyObject *args) -{ - unsigned flags; - - PyErr_TDB_RAISE_IF_CLOSED(self); - - if (!PyArg_ParseTuple(args, "I", &flags)) - return NULL; - - tdb_remove_flags(self->ctx, flags); - Py_RETURN_NONE; -} - -typedef struct { - PyObject_HEAD - TDB_DATA current; - PyTdbObject *iteratee; -} PyTdbIteratorObject; - -static PyObject *tdb_iter_next(PyTdbIteratorObject *self) -{ - TDB_DATA current; - PyObject *ret; - if (self->current.dptr == NULL && self->current.dsize == 0) - return NULL; - current = self->current; - self->current = tdb_nextkey(self->iteratee->ctx, self->current); - ret = PyBytes_FromTDB_DATA(current); - return ret; -} - -static void tdb_iter_dealloc(PyTdbIteratorObject *self) -{ - Py_DECREF(self->iteratee); - PyObject_Del(self); -} - -PyTypeObject PyTdbIterator = { - .tp_name = "Iterator", - .tp_basicsize = sizeof(PyTdbIteratorObject), - .tp_iternext = (iternextfunc)tdb_iter_next, - .tp_dealloc = (destructor)tdb_iter_dealloc, - .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_iter = PyObject_SelfIter, -}; - -static PyObject *tdb_object_iter(PyTdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - PyTdbIteratorObject *ret; - - PyErr_TDB_RAISE_IF_CLOSED(self); - - ret = PyObject_New(PyTdbIteratorObject, &PyTdbIterator); - if (!ret) - return NULL; - ret->current = tdb_firstkey(self->ctx); - ret->iteratee = self; - Py_INCREF(self); - return (PyObject *)ret; -} - -static PyObject *obj_clear(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) -{ - int ret; - PyErr_TDB_RAISE_IF_CLOSED(self); - ret = tdb_wipe_all(self->ctx); - PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); - Py_RETURN_NONE; -} - -static PyObject *obj_repack(PyTdbObject *self, PyObject *Py_UNUSED(ignored)) -{ - int ret; - PyErr_TDB_RAISE_IF_CLOSED(self); - ret = tdb_repack(self->ctx); - PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); - Py_RETURN_NONE; -} - -static PyObject *obj_enable_seqnum(PyTdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - PyErr_TDB_RAISE_IF_CLOSED(self); - tdb_enable_seqnum(self->ctx); - Py_RETURN_NONE; -} - -static PyObject *obj_increment_seqnum_nonblock(PyTdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - PyErr_TDB_RAISE_IF_CLOSED(self); - tdb_increment_seqnum_nonblock(self->ctx); - Py_RETURN_NONE; -} - -static PyMethodDef tdb_object_methods[] = { - { "transaction_cancel", (PyCFunction)obj_transaction_cancel, METH_NOARGS, - "S.transaction_cancel() -> None\n" - "Cancel the currently active transaction." }, - { "transaction_commit", (PyCFunction)obj_transaction_commit, METH_NOARGS, - "S.transaction_commit() -> None\n" - "Commit the currently active transaction." }, - { "transaction_prepare_commit", (PyCFunction)obj_transaction_prepare_commit, METH_NOARGS, - "S.transaction_prepare_commit() -> None\n" - "Prepare to commit the currently active transaction" }, - { "transaction_start", (PyCFunction)obj_transaction_start, METH_NOARGS, - "S.transaction_start() -> None\n" - "Start a new transaction." }, - { "reopen", (PyCFunction)obj_reopen, METH_NOARGS, "Reopen this file." }, - { "lock_all", (PyCFunction)obj_lockall, METH_NOARGS, NULL }, - { "unlock_all", (PyCFunction)obj_unlockall, METH_NOARGS, NULL }, - { "read_lock_all", (PyCFunction)obj_lockall_read, METH_NOARGS, NULL }, - { "read_unlock_all", (PyCFunction)obj_unlockall_read, METH_NOARGS, NULL }, - { "close", (PyCFunction)obj_close, METH_NOARGS, NULL }, - { "get", (PyCFunction)obj_get, METH_VARARGS, "S.get(key) -> value\n" - "Fetch a value." }, - { "append", (PyCFunction)obj_append, METH_VARARGS, "S.append(key, value) -> None\n" - "Append data to an existing key." }, - { "firstkey", (PyCFunction)obj_firstkey, METH_NOARGS, "S.firstkey() -> data\n" - "Return the first key in this database." }, - { "nextkey", (PyCFunction)obj_nextkey, METH_VARARGS, "S.nextkey(key) -> data\n" - "Return the next key in this database." }, - { "delete", (PyCFunction)obj_delete, METH_VARARGS, "S.delete(key) -> None\n" - "Delete an entry." }, -#if PY_MAJOR_VERSION < 3 - { "has_key", (PyCFunction)obj_has_key, METH_VARARGS, "S.has_key(key) -> None\n" - "Check whether key exists in this database." }, -#endif - { "store", (PyCFunction)obj_store, METH_VARARGS, "S.store(key, data, flag=REPLACE) -> None" - "Store data." }, - { "add_flags", (PyCFunction)obj_add_flags, METH_VARARGS, "S.add_flags(flags) -> None" }, - { "remove_flags", (PyCFunction)obj_remove_flags, METH_VARARGS, "S.remove_flags(flags) -> None" }, -#if PY_MAJOR_VERSION >= 3 - { "keys", (PyCFunction)tdb_object_iter, METH_NOARGS, "S.iterkeys() -> iterator" }, -#else - { "iterkeys", (PyCFunction)tdb_object_iter, METH_NOARGS, "S.iterkeys() -> iterator" }, -#endif - { "clear", (PyCFunction)obj_clear, METH_NOARGS, "S.clear() -> None\n" - "Wipe the entire database." }, - { "repack", (PyCFunction)obj_repack, METH_NOARGS, "S.repack() -> None\n" - "Repack the entire database." }, - { "enable_seqnum", (PyCFunction)obj_enable_seqnum, METH_NOARGS, - "S.enable_seqnum() -> None" }, - { "increment_seqnum_nonblock", (PyCFunction)obj_increment_seqnum_nonblock, METH_NOARGS, - "S.increment_seqnum_nonblock() -> None" }, - { NULL } -}; - -static PyObject *obj_get_hash_size(PyTdbObject *self, void *closure) -{ - PyErr_TDB_RAISE_IF_CLOSED(self); - return PyInt_FromLong(tdb_hash_size(self->ctx)); -} - -static int obj_set_max_dead(PyTdbObject *self, PyObject *max_dead, void *closure) -{ - PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED(self); - if (!PyInt_Check(max_dead)) - return -1; - tdb_set_max_dead(self->ctx, PyInt_AsLong(max_dead)); - return 0; -} - -static PyObject *obj_get_map_size(PyTdbObject *self, void *closure) -{ - PyErr_TDB_RAISE_IF_CLOSED(self); - return PyInt_FromLong(tdb_map_size(self->ctx)); -} - -static PyObject *obj_get_freelist_size(PyTdbObject *self, void *closure) -{ - PyErr_TDB_RAISE_IF_CLOSED(self); - return PyInt_FromLong(tdb_freelist_size(self->ctx)); -} - -static PyObject *obj_get_flags(PyTdbObject *self, void *closure) -{ - PyErr_TDB_RAISE_IF_CLOSED(self); - return PyInt_FromLong(tdb_get_flags(self->ctx)); -} - -static PyObject *obj_get_filename(PyTdbObject *self, void *closure) -{ - PyErr_TDB_RAISE_IF_CLOSED(self); - return PyBytes_FromString(tdb_name(self->ctx)); -} - -static PyObject *obj_get_seqnum(PyTdbObject *self, void *closure) -{ - PyErr_TDB_RAISE_IF_CLOSED(self); - return PyInt_FromLong(tdb_get_seqnum(self->ctx)); -} - -static PyObject *obj_get_text(PyTdbObject *self, void *closure) -{ - PyObject *mod, *cls, *inst; - mod = PyImport_ImportModule("_tdb_text"); - if (mod == NULL) - return NULL; - cls = PyObject_GetAttrString(mod, "TdbTextWrapper"); - if (cls == NULL) { - Py_DECREF(mod); - return NULL; - } - inst = PyObject_CallFunction(cls, discard_const_p(char, "O"), self); - Py_DECREF(mod); - Py_DECREF(cls); - return inst; -} - -static PyGetSetDef tdb_object_getsetters[] = { - { - .name = discard_const_p(char, "hash_size"), - .get = (getter)obj_get_hash_size, - }, - { - .name = discard_const_p(char, "map_size"), - .get = (getter)obj_get_map_size, - }, - { - .name = discard_const_p(char, "freelist_size"), - .get = (getter)obj_get_freelist_size, - }, - { - .name = discard_const_p(char, "flags"), - .get = (getter)obj_get_flags, - }, - { - .name = discard_const_p(char, "max_dead"), - .set = (setter)obj_set_max_dead, - }, - { - .name = discard_const_p(char, "filename"), - .get = (getter)obj_get_filename, - .doc = discard_const_p(char, "The filename of this TDB file."), - }, - { - .name = discard_const_p(char, "seqnum"), - .get = (getter)obj_get_seqnum, - }, - { - .name = discard_const_p(char, "text"), - .get = (getter)obj_get_text, - }, - { .name = NULL } -}; - -static PyObject *tdb_object_repr(PyTdbObject *self) -{ - PyErr_TDB_RAISE_IF_CLOSED(self); - if (tdb_get_flags(self->ctx) & TDB_INTERNAL) { - return PyUnicode_FromString("Tdb()"); - } else { - return PyUnicode_FromFormat("Tdb('%s')", tdb_name(self->ctx)); - } -} - -static void tdb_object_dealloc(PyTdbObject *self) -{ - if (!self->closed) - tdb_close(self->ctx); - Py_TYPE(self)->tp_free(self); -} - -static PyObject *obj_getitem(PyTdbObject *self, PyObject *key) -{ - TDB_DATA tkey, val; - PyErr_TDB_RAISE_IF_CLOSED(self); - if (!PyBytes_Check(key)) { - PyErr_SetString(PyExc_TypeError, "Expected bytestring as key"); - return NULL; - } - - tkey.dptr = (unsigned char *)PyBytes_AsString(key); - tkey.dsize = PyBytes_Size(key); - - val = tdb_fetch(self->ctx, tkey); - if (val.dptr == NULL) { - /* - * if the key doesn't exist raise KeyError(key) to be - * consistent with python dict - */ - PyErr_SetObject(PyExc_KeyError, key); - return NULL; - } else { - return PyBytes_FromTDB_DATA(val); - } -} - -static int obj_setitem(PyTdbObject *self, PyObject *key, PyObject *value) -{ - TDB_DATA tkey, tval; - int ret; - PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED(self); - if (!PyBytes_Check(key)) { - PyErr_SetString(PyExc_TypeError, "Expected bytestring as key"); - return -1; - } - - tkey = PyBytes_AsTDB_DATA(key); - - if (value == NULL) { - ret = tdb_delete(self->ctx, tkey); - } else { - if (!PyBytes_Check(value)) { - PyErr_SetString(PyExc_TypeError, "Expected string as value"); - return -1; - } - - tval = PyBytes_AsTDB_DATA(value); - - ret = tdb_store(self->ctx, tkey, tval, TDB_REPLACE); - } - - if (ret != 0) { - PyErr_SetTDBError(self->ctx); - return -1; - } - - return ret; -} - -static PyMappingMethods tdb_object_mapping = { - .mp_subscript = (binaryfunc)obj_getitem, - .mp_ass_subscript = (objobjargproc)obj_setitem, -}; -static PySequenceMethods tdb_object_seq = { - .sq_contains = (objobjproc)obj_contains, -}; -static PyTypeObject PyTdb = { - .tp_name = "tdb.Tdb", - .tp_basicsize = sizeof(PyTdbObject), - .tp_methods = tdb_object_methods, - .tp_getset = tdb_object_getsetters, - .tp_new = py_tdb_open, - .tp_doc = "A TDB file", - .tp_repr = (reprfunc)tdb_object_repr, - .tp_dealloc = (destructor)tdb_object_dealloc, - .tp_as_mapping = &tdb_object_mapping, - .tp_as_sequence = &tdb_object_seq, - .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_ITER, - .tp_iter = PY_DISCARD_FUNC_SIG(getiterfunc,tdb_object_iter), -}; - -static PyMethodDef tdb_methods[] = { - { - .ml_name = "open", - .ml_meth = PY_DISCARD_FUNC_SIG(PyCFunction, py_tdb_open), - .ml_flags = METH_VARARGS|METH_KEYWORDS, - .ml_doc = "open(name, hash_size=0, tdb_flags=TDB_DEFAULT, " - "flags=O_RDWR, mode=0600)\nOpen a TDB file." - }, - { .ml_name = NULL } -}; - -#define MODULE_DOC "simple key-value database that supports multiple writers." - -#if PY_MAJOR_VERSION >= 3 -static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - .m_name = "tdb", - .m_doc = MODULE_DOC, - .m_size = -1, - .m_methods = tdb_methods, -}; -#endif - -PyObject* module_init(void); -PyObject* module_init(void) -{ - PyObject *m; - - if (PyType_Ready(&PyTdb) < 0) - return NULL; - - if (PyType_Ready(&PyTdbIterator) < 0) - return NULL; - -#if PY_MAJOR_VERSION >= 3 - m = PyModule_Create(&moduledef); -#else - m = Py_InitModule3("tdb", tdb_methods, MODULE_DOC); -#endif - if (m == NULL) - return NULL; - - PyModule_AddIntConstant(m, "REPLACE", TDB_REPLACE); - PyModule_AddIntConstant(m, "INSERT", TDB_INSERT); - PyModule_AddIntConstant(m, "MODIFY", TDB_MODIFY); - - PyModule_AddIntConstant(m, "DEFAULT", TDB_DEFAULT); - PyModule_AddIntConstant(m, "CLEAR_IF_FIRST", TDB_CLEAR_IF_FIRST); - PyModule_AddIntConstant(m, "INTERNAL", TDB_INTERNAL); - PyModule_AddIntConstant(m, "NOLOCK", TDB_NOLOCK); - PyModule_AddIntConstant(m, "NOMMAP", TDB_NOMMAP); - PyModule_AddIntConstant(m, "CONVERT", TDB_CONVERT); - PyModule_AddIntConstant(m, "BIGENDIAN", TDB_BIGENDIAN); - PyModule_AddIntConstant(m, "NOSYNC", TDB_NOSYNC); - PyModule_AddIntConstant(m, "SEQNUM", TDB_SEQNUM); - PyModule_AddIntConstant(m, "VOLATILE", TDB_VOLATILE); - PyModule_AddIntConstant(m, "ALLOW_NESTING", TDB_ALLOW_NESTING); - PyModule_AddIntConstant(m, "DISALLOW_NESTING", TDB_DISALLOW_NESTING); - PyModule_AddIntConstant(m, "INCOMPATIBLE_HASH", TDB_INCOMPATIBLE_HASH); - - PyModule_AddStringConstant(m, "__docformat__", "restructuredText"); - - PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION); - - Py_INCREF(&PyTdb); - PyModule_AddObject(m, "Tdb", (PyObject *)&PyTdb); - - Py_INCREF(&PyTdbIterator); - - return m; -} - - -#if PY_MAJOR_VERSION >= 3 -PyMODINIT_FUNC PyInit_tdb(void); -PyMODINIT_FUNC PyInit_tdb(void) -{ - return module_init(); -} -#else -void inittdb(void); -void inittdb(void) -{ - module_init(); -} -#endif diff --git a/ldb-2.0.8/lib/tdb/python/tdbdump.py b/ldb-2.0.8/lib/tdb/python/tdbdump.py deleted file mode 100644 index 306a950..0000000 --- a/ldb-2.0.8/lib/tdb/python/tdbdump.py +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env python3 -# Trivial reimplementation of tdbdump in Python - -from __future__ import print_function -import tdb, sys - -if len(sys.argv) < 2: - print("Usage: tdbdump.py ") - sys.exit(1) - -db = tdb.Tdb(sys.argv[1]) -for (k, v) in db.items(): - print("{\nkey(%d) = %r\ndata(%d) = %r\n}" % (len(k), k, len(v), v)) diff --git a/ldb-2.0.8/lib/tdb/python/tests/simple.py b/ldb-2.0.8/lib/tdb/python/tests/simple.py deleted file mode 100644 index 312d587..0000000 --- a/ldb-2.0.8/lib/tdb/python/tests/simple.py +++ /dev/null @@ -1,311 +0,0 @@ -#!/usr/bin/env python3 -# Some simple tests for the Python bindings for TDB -# Note that this tests the interface of the Python bindings -# It does not test tdb itself. -# -# Copyright (C) 2007-2008 Jelmer Vernooij -# Published under the GNU LGPLv3 or later - -import sys -import os -import tempfile -from unittest import TestCase - -import tdb - - -class OpenTdbTests(TestCase): - - def test_nonexistent_read(self): - self.assertRaises(IOError, tdb.Tdb, "/some/nonexistent/file", 0, - tdb.DEFAULT, os.O_RDWR) - -class CloseTdbTests(TestCase): - - def test_double_close(self): - self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, - os.O_CREAT|os.O_RDWR) - self.assertNotEqual(None, self.tdb) - - # ensure that double close does not crash python - self.tdb.close() - self.tdb.close() - - # Check that further operations do not crash python - self.assertRaises(RuntimeError, lambda: self.tdb.transaction_start()) - - self.assertRaises(RuntimeError, lambda: self.tdb["bar"]) - - -class InternalTdbTests(TestCase): - - def test_repr(self): - self.tdb = tdb.Tdb() - - # repr used to crash on internal db - self.assertEqual(repr(self.tdb), "Tdb()") - - -class CommonTdbTests(TestCase): - """Tests common to both the text & bytes interfaces""" - - use_text = False - - def setUp(self): - super(CommonTdbTests, self).setUp() - self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, - os.O_CREAT|os.O_RDWR) - self.assertNotEqual(None, self.tdb) - if self.use_text: - self.tdb = self.tdb.text - - def test_lockall(self): - self.tdb.lock_all() - - def test_max_dead(self): - self.tdb.max_dead = 20 - - def test_unlockall(self): - self.tdb.lock_all() - self.tdb.unlock_all() - - def test_lockall_read(self): - self.tdb.read_lock_all() - self.tdb.read_unlock_all() - - def test_reopen(self): - self.tdb.reopen() - - def test_hash_size(self): - self.tdb.hash_size - - def test_map_size(self): - self.tdb.map_size - - def test_freelist_size(self): - self.tdb.freelist_size - - def test_name(self): - self.tdb.filename - - def test_add_flags(self): - self.tdb.add_flags(tdb.NOMMAP) - self.tdb.remove_flags(tdb.NOMMAP) - - -class TextCommonTdbTests(CommonTdbTests): - - use_text = True - - -class SimpleTdbTests(TestCase): - - def setUp(self): - super(SimpleTdbTests, self).setUp() - self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, - os.O_CREAT|os.O_RDWR) - self.assertNotEqual(None, self.tdb) - - def test_repr(self): - self.assertTrue(repr(self.tdb).startswith("Tdb('")) - - def test_store(self): - self.tdb.store(b"bar", b"bla") - self.assertEqual(b"bla", self.tdb.get(b"bar")) - - def test_getitem(self): - self.tdb[b"bar"] = b"foo" - self.tdb.reopen() - self.assertEqual(b"foo", self.tdb[b"bar"]) - - def test_delete(self): - self.tdb[b"bar"] = b"foo" - del self.tdb[b"bar"] - self.assertRaises(KeyError, lambda: self.tdb[b"bar"]) - - def test_contains(self): - self.tdb[b"bla"] = b"bloe" - self.assertTrue(b"bla" in self.tdb) - self.assertFalse(b"qwertyuiop" in self.tdb) - if sys.version_info < (3, 0): - self.assertTrue(self.tdb.has_key(b"bla")) - self.assertFalse(self.tdb.has_key(b"qwertyuiop")) - - def test_keyerror(self): - self.assertRaises(KeyError, lambda: self.tdb[b"bla"]) - - def test_iterator(self): - self.tdb[b"bla"] = b"1" - self.tdb[b"brainslug"] = b"2" - l = list(self.tdb) - l.sort() - self.assertEqual([b"bla", b"brainslug"], l) - - def test_transaction_cancel(self): - self.tdb[b"bloe"] = b"2" - self.tdb.transaction_start() - self.tdb[b"bloe"] = b"1" - self.tdb.transaction_cancel() - self.assertEqual(b"2", self.tdb[b"bloe"]) - - def test_transaction_commit(self): - self.tdb[b"bloe"] = b"2" - self.tdb.transaction_start() - self.tdb[b"bloe"] = b"1" - self.tdb.transaction_commit() - self.assertEqual(b"1", self.tdb[b"bloe"]) - - def test_transaction_prepare_commit(self): - self.tdb[b"bloe"] = b"2" - self.tdb.transaction_start() - self.tdb[b"bloe"] = b"1" - self.tdb.transaction_prepare_commit() - self.tdb.transaction_commit() - self.assertEqual(b"1", self.tdb[b"bloe"]) - - def test_iterkeys(self): - self.tdb[b"bloe"] = b"2" - self.tdb[b"bla"] = b"25" - if sys.version_info >= (3, 0): - i = self.tdb.keys() - else: - i = self.tdb.iterkeys() - self.assertEqual(set([b"bloe", b"bla"]), set([next(i), next(i)])) - - def test_clear(self): - self.tdb[b"bloe"] = b"2" - self.tdb[b"bla"] = b"25" - self.assertEqual(2, len(list(self.tdb))) - self.tdb.clear() - self.assertEqual(0, len(list(self.tdb))) - - def test_repack(self): - self.tdb[b"foo"] = b"abc" - self.tdb[b"bar"] = b"def" - del self.tdb[b"foo"] - self.tdb.repack() - - def test_seqnum(self): - self.tdb.enable_seqnum() - seq1 = self.tdb.seqnum - self.tdb.increment_seqnum_nonblock() - seq2 = self.tdb.seqnum - self.assertEqual(seq2-seq1, 1) - - def test_len(self): - self.assertEqual(0, len(list(self.tdb))) - self.tdb[b"entry"] = b"value" - self.assertEqual(1, len(list(self.tdb))) - - -class TdbTextTests(TestCase): - - def setUp(self): - super(TdbTextTests, self).setUp() - self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, - os.O_CREAT|os.O_RDWR) - self.assertNotEqual(None, self.tdb) - - def test_repr(self): - self.assertTrue(repr(self.tdb).startswith("Tdb('")) - - def test_store(self): - self.tdb.text.store("bar", "bla") - self.assertEqual("bla", self.tdb.text.get("bar")) - - def test_getitem(self): - self.tdb.text["bar"] = "foo" - self.tdb.reopen() - self.assertEqual("foo", self.tdb.text["bar"]) - - def test_delete(self): - self.tdb.text["bar"] = "foo" - del self.tdb.text["bar"] - self.assertRaises(KeyError, lambda: self.tdb.text["bar"]) - - def test_contains(self): - self.tdb.text["bla"] = "bloe" - self.assertTrue("bla" in self.tdb.text) - self.assertFalse("qwertyuiop" in self.tdb.text) - if sys.version_info < (3, 0): - self.assertTrue(self.tdb.text.has_key("bla")) - self.assertFalse(self.tdb.text.has_key("qwertyuiop")) - - def test_keyerror(self): - self.assertRaises(KeyError, lambda: self.tdb.text["bla"]) - - def test_iterator(self): - self.tdb.text["bla"] = "1" - self.tdb.text["brainslug"] = "2" - l = list(self.tdb.text) - l.sort() - self.assertEqual(["bla", "brainslug"], l) - - def test_transaction_cancel(self): - self.tdb.text["bloe"] = "2" - self.tdb.transaction_start() - self.tdb.text["bloe"] = "1" - self.tdb.transaction_cancel() - self.assertEqual("2", self.tdb.text["bloe"]) - - def test_transaction_commit(self): - self.tdb.text["bloe"] = "2" - self.tdb.transaction_start() - self.tdb.text["bloe"] = "1" - self.tdb.transaction_commit() - self.assertEqual("1", self.tdb.text["bloe"]) - - def test_transaction_prepare_commit(self): - self.tdb.text["bloe"] = "2" - self.tdb.transaction_start() - self.tdb.text["bloe"] = "1" - self.tdb.transaction_prepare_commit() - self.tdb.transaction_commit() - self.assertEqual("1", self.tdb.text["bloe"]) - - def test_iterkeys(self): - self.tdb.text["bloe"] = "2" - self.tdb.text["bla"] = "25" - if sys.version_info >= (3, 0): - i = self.tdb.text.keys() - else: - i = self.tdb.text.iterkeys() - self.assertEqual(set(["bloe", "bla"]), set([next(i), next(i)])) - - def test_clear(self): - self.tdb.text["bloe"] = "2" - self.tdb.text["bla"] = "25" - self.assertEqual(2, len(list(self.tdb))) - self.tdb.clear() - self.assertEqual(0, len(list(self.tdb))) - - def test_repack(self): - self.tdb.text["foo"] = "abc" - self.tdb.text["bar"] = "def" - del self.tdb.text["foo"] - self.tdb.repack() - - def test_len(self): - self.assertEqual(0, len(list(self.tdb.text))) - self.tdb.text["entry"] = "value" - self.assertEqual(1, len(list(self.tdb.text))) - - def test_text_and_binary(self): - text = u'\xfa\u0148\xef\xe7\xf8\xf0\xea' - bytestr = text.encode('utf-8') - self.tdb[b"entry"] = bytestr - self.tdb.text[u"entry2"] = text - self.assertEqual(self.tdb.text["entry"], text) - self.assertEqual(self.tdb[b"entry2"], bytestr) - assert self.tdb.text.raw == self.tdb - - -class VersionTests(TestCase): - - def test_present(self): - self.assertTrue(isinstance(tdb.__version__, str)) - - -if __name__ == '__main__': - import unittest - unittest.TestProgram() diff --git a/ldb-2.0.8/lib/tdb/tdb.pc.in b/ldb-2.0.8/lib/tdb/tdb.pc.in deleted file mode 100644 index b78419e..0000000 --- a/ldb-2.0.8/lib/tdb/tdb.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: tdb -Description: A trivial database -Version: @PACKAGE_VERSION@ -Libs: @LIB_RPATH@ -L${libdir} -ltdb -Cflags: -I${includedir} -URL: http://tdb.samba.org/ diff --git a/ldb-2.0.8/lib/tdb/test/circular_chain.tdb b/ldb-2.0.8/lib/tdb/test/circular_chain.tdb deleted file mode 100644 index 1e143d347af21eb3cf717ae6b4b67502a2d4eca8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 272 zcmWG>aZ*Uj%t_^9zz%XH8PyokqaZ*Uj%t_^9zz%XH8Pyokq(k>3DRgDk(F|9THde{wQJ{sNl3R@~fkApI#R u5cv;i@>AC&3xM>erb6Te(ClaUtr-N;pOyxZH$aom_WUpzq(40!A`bw1o-39B diff --git a/ldb-2.0.8/lib/tdb/test/external-agent.c b/ldb-2.0.8/lib/tdb/test/external-agent.c deleted file mode 100644 index 3c59c06..0000000 --- a/ldb-2.0.8/lib/tdb/test/external-agent.c +++ /dev/null @@ -1,224 +0,0 @@ -#include "external-agent.h" -#include "lock-tracking.h" -#include "logging.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include "../common/tdb_private.h" -#include "tap-interface.h" -#include -#include - -static struct tdb_context *tdb; - -static enum agent_return do_operation(enum operation op, const char *name) -{ - TDB_DATA k; - enum agent_return ret; - TDB_DATA data; - - if (op != OPEN && op != OPEN_WITH_CLEAR_IF_FIRST && !tdb) { - diag("external: No tdb open!"); - return OTHER_FAILURE; - } - - k.dptr = discard_const_p(uint8_t, name); - k.dsize = strlen(name); - - locking_would_block = 0; - switch (op) { - case OPEN: - if (tdb) { - diag("Already have tdb %s open", tdb_name(tdb)); - return OTHER_FAILURE; - } - tdb = tdb_open_ex(name, 0, TDB_DEFAULT, O_RDWR, 0, - &taplogctx, NULL); - if (!tdb) { - if (!locking_would_block) - diag("Opening tdb gave %s", strerror(errno)); - ret = OTHER_FAILURE; - } else - ret = SUCCESS; - break; - case OPEN_WITH_CLEAR_IF_FIRST: - if (tdb) - return OTHER_FAILURE; - tdb = tdb_open_ex(name, 0, TDB_CLEAR_IF_FIRST, O_RDWR, 0, - &taplogctx, NULL); - ret = tdb ? SUCCESS : OTHER_FAILURE; - break; - case TRANSACTION_START: - ret = tdb_transaction_start(tdb) == 0 ? SUCCESS : OTHER_FAILURE; - break; - case FETCH: - data = tdb_fetch(tdb, k); - if (data.dptr == NULL) { - if (tdb_error(tdb) == TDB_ERR_NOEXIST) - ret = FAILED; - else - ret = OTHER_FAILURE; - } else if (data.dsize != k.dsize - || memcmp(data.dptr, k.dptr, k.dsize) != 0) { - ret = OTHER_FAILURE; - } else { - ret = SUCCESS; - } - free(data.dptr); - break; - case STORE: - ret = tdb_store(tdb, k, k, 0) == 0 ? SUCCESS : OTHER_FAILURE; - break; - case TRANSACTION_COMMIT: - ret = tdb_transaction_commit(tdb)==0 ? SUCCESS : OTHER_FAILURE; - break; - case CHECK: - ret = tdb_check(tdb, NULL, NULL) == 0 ? SUCCESS : OTHER_FAILURE; - break; - case NEEDS_RECOVERY: - ret = tdb_needs_recovery(tdb) ? SUCCESS : FAILED; - break; - case CLOSE: - ret = tdb_close(tdb) == 0 ? SUCCESS : OTHER_FAILURE; - tdb = NULL; - break; - case PING: - ret = SUCCESS; - break; - case UNMAP: - ret = tdb_munmap(tdb) == 0 ? SUCCESS : OTHER_FAILURE; - if (ret == SUCCESS) { - tdb->flags |= TDB_NOMMAP; - } - break; - default: - ret = OTHER_FAILURE; - } - - if (locking_would_block) - ret = WOULD_HAVE_BLOCKED; - - return ret; -} - -struct agent { - int cmdfd, responsefd; - pid_t pid; -}; - -/* Do this before doing any tdb stuff. Return handle, or NULL. */ -struct agent *prepare_external_agent(void) -{ - int ret; - int command[2], response[2]; - char name[1+PATH_MAX]; - struct agent *agent = malloc(sizeof(*agent)); - - if (pipe(command) != 0 || pipe(response) != 0) { - fprintf(stderr, "pipe failed: %s\n", strerror(errno)); - exit(1); - } - - agent->pid = fork(); - if (agent->pid < 0) { - fprintf(stderr, "fork failed: %s\n", strerror(errno)); - exit(1); - } - - if (agent->pid != 0) { - close(command[0]); - close(response[1]); - agent->cmdfd = command[1]; - agent->responsefd = response[0]; - return agent; - } - - close(command[1]); - close(response[0]); - - /* We want to fail, not block. */ - nonblocking_locks = true; - log_prefix = "external: "; - while ((ret = read(command[0], name, sizeof(name))) > 0) { - enum agent_return result; - - result = do_operation(name[0], name+1); - if (write(response[1], &result, sizeof(result)) - != sizeof(result)) - abort(); - } - exit(0); -} - -void shutdown_agent(struct agent *agent) -{ - pid_t p; - - close(agent->cmdfd); - close(agent->responsefd); - p = waitpid(agent->pid, NULL, WNOHANG); - if (p == 0) { - kill(agent->pid, SIGKILL); - } - waitpid(agent->pid, NULL, 0); - free(agent); -} - -/* Ask the external agent to try to do an operation. */ -enum agent_return external_agent_operation(struct agent *agent, - enum operation op, - const char *name) -{ - enum agent_return res; - unsigned int len; - char *string; - - if (!name) - name = ""; - len = 1 + strlen(name) + 1; - string = malloc(len); - - string[0] = op; - strncpy(string+1, name, len - 1); - string[len-1] = '\0'; - - if (write(agent->cmdfd, string, len) != len - || read(agent->responsefd, &res, sizeof(res)) != sizeof(res)) - res = AGENT_DIED; - - free(string); - return res; -} - -const char *agent_return_name(enum agent_return ret) -{ - return ret == SUCCESS ? "SUCCESS" - : ret == WOULD_HAVE_BLOCKED ? "WOULD_HAVE_BLOCKED" - : ret == AGENT_DIED ? "AGENT_DIED" - : ret == FAILED ? "FAILED" - : ret == OTHER_FAILURE ? "OTHER_FAILURE" - : "**INVALID**"; -} - -const char *operation_name(enum operation op) -{ - switch (op) { - case OPEN: return "OPEN"; - case OPEN_WITH_CLEAR_IF_FIRST: return "OPEN_WITH_CLEAR_IF_FIRST"; - case TRANSACTION_START: return "TRANSACTION_START"; - case FETCH: return "FETCH"; - case STORE: return "STORE"; - case TRANSACTION_COMMIT: return "TRANSACTION_COMMIT"; - case CHECK: return "CHECK"; - case NEEDS_RECOVERY: return "NEEDS_RECOVERY"; - case CLOSE: return "CLOSE"; - case PING: return "PING"; - case UNMAP: return "UNMAP"; - } - return "**INVALID**"; -} diff --git a/ldb-2.0.8/lib/tdb/test/external-agent.h b/ldb-2.0.8/lib/tdb/test/external-agent.h deleted file mode 100644 index de9d0ac..0000000 --- a/ldb-2.0.8/lib/tdb/test/external-agent.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef TDB_TEST_EXTERNAL_AGENT_H -#define TDB_TEST_EXTERNAL_AGENT_H - -/* For locking tests, we need a different process to try things at - * various times. */ -enum operation { - OPEN, - OPEN_WITH_CLEAR_IF_FIRST, - TRANSACTION_START, - FETCH, - STORE, - TRANSACTION_COMMIT, - CHECK, - NEEDS_RECOVERY, - CLOSE, - PING, - UNMAP, -}; - -/* Do this before doing any tdb stuff. Return handle, or -1. */ -struct agent *prepare_external_agent(void); -void shutdown_agent(struct agent *agent); - -enum agent_return { - SUCCESS, - WOULD_HAVE_BLOCKED, - AGENT_DIED, - FAILED, /* For fetch, or NEEDS_RECOVERY */ - OTHER_FAILURE, -}; - -/* Ask the external agent to try to do an operation. - * name == tdb name for OPEN/OPEN_WITH_CLEAR_IF_FIRST, - * record name for FETCH/STORE (store stores name as data too) - */ -enum agent_return external_agent_operation(struct agent *handle, - enum operation op, - const char *name); - -/* Mapping enum -> string. */ -const char *agent_return_name(enum agent_return ret); -const char *operation_name(enum operation op); - -#endif /* TDB_TEST_EXTERNAL_AGENT_H */ diff --git a/ldb-2.0.8/lib/tdb/test/jenkins-be-hash.tdb b/ldb-2.0.8/lib/tdb/test/jenkins-be-hash.tdb deleted file mode 100644 index b652840414857969987a986c848ede159804166e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 696 ucmWG>aZ*Uj%t_^9zz)aZ*Uj%t_^9zz%XH8P%H6q@GUMcAd{ -#include -#include -#include -#include "tap-interface.h" -#include "lock-tracking.h" - -struct testlock { - struct testlock *next; - unsigned int off; - unsigned int len; - int type; -}; -static struct testlock *testlocks; -int locking_errors = 0; -bool suppress_lockcheck = false; -bool nonblocking_locks; -int locking_would_block = 0; -void (*unlock_callback)(int fd); - -int fcntl_with_lockcheck(int fd, int cmd, ... /* arg */ ) -{ - va_list ap; - int ret, arg3; - struct flock *fl; - bool may_block = false; - - if (cmd != F_SETLK && cmd != F_SETLKW) { - /* This may be totally bogus, but we don't know in general. */ - va_start(ap, cmd); - arg3 = va_arg(ap, int); - va_end(ap); - - return fcntl(fd, cmd, arg3); - } - - va_start(ap, cmd); - fl = va_arg(ap, struct flock *); - va_end(ap); - - if (cmd == F_SETLKW && nonblocking_locks) { - cmd = F_SETLK; - may_block = true; - } - ret = fcntl(fd, cmd, fl); - - /* Detect when we failed, but might have been OK if we waited. */ - if (may_block && ret == -1 && (errno == EAGAIN || errno == EACCES)) { - locking_would_block++; - } - - if (fl->l_type == F_UNLCK) { - struct testlock **l; - struct testlock *old = NULL; - - for (l = &testlocks; *l; l = &(*l)->next) { - if ((*l)->off == fl->l_start - && (*l)->len == fl->l_len) { - if (ret == 0) { - old = *l; - *l = (*l)->next; - free(old); - } - break; - } - if (((*l)->off == fl->l_start) - && ((*l)->len == 0) - && (ret == 0)) { - /* - * Remove a piece from the start of the - * allrecord_lock - */ - old = *l; - (*l)->off += fl->l_len; - break; - } - } - if (!old && !suppress_lockcheck) { - diag("Unknown unlock %u@%u - %i", - (int)fl->l_len, (int)fl->l_start, ret); - locking_errors++; - } - } else { - struct testlock *new, *i; - unsigned int fl_end = fl->l_start + fl->l_len; - if (fl->l_len == 0) - fl_end = (unsigned int)-1; - - /* Check for overlaps: we shouldn't do this. */ - for (i = testlocks; i; i = i->next) { - unsigned int i_end = i->off + i->len; - if (i->len == 0) - i_end = (unsigned int)-1; - - if (fl->l_start >= i->off && fl->l_start < i_end) - break; - if (fl_end >= i->off && fl_end < i_end) - break; - - /* tdb_allrecord_lock does this, handle adjacent: */ - if (fl->l_start == i_end && fl->l_type == i->type) { - if (ret == 0) { - i->len = fl->l_len - ? i->len + fl->l_len - : 0; - } - goto done; - } - } - if (i) { - /* Special case: upgrade of allrecord lock. */ - if (i->type == F_RDLCK && fl->l_type == F_WRLCK - && i->off == FREELIST_TOP - && fl->l_start == FREELIST_TOP - && i->len == 0 - && fl->l_len == 0) { - if (ret == 0) - i->type = F_WRLCK; - goto done; - } - if (!suppress_lockcheck) { - diag("%s testlock %u@%u overlaps %u@%u", - fl->l_type == F_WRLCK ? "write" : "read", - (int)fl->l_len, (int)fl->l_start, - i->len, (int)i->off); - locking_errors++; - } - } - - if (ret == 0) { - new = malloc(sizeof *new); - new->off = fl->l_start; - new->len = fl->l_len; - new->type = fl->l_type; - new->next = testlocks; - testlocks = new; - } - } -done: - if (ret == 0 && fl->l_type == F_UNLCK && unlock_callback) - unlock_callback(fd); - return ret; -} - -unsigned int forget_locking(void) -{ - unsigned int num = 0; - while (testlocks) { - struct testlock *next = testlocks->next; - free(testlocks); - testlocks = next; - num++; - } - return num; -} diff --git a/ldb-2.0.8/lib/tdb/test/lock-tracking.h b/ldb-2.0.8/lib/tdb/test/lock-tracking.h deleted file mode 100644 index f2c9c44..0000000 --- a/ldb-2.0.8/lib/tdb/test/lock-tracking.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef LOCK_TRACKING_H -#define LOCK_TRACKING_H -#include - -/* Set this if you want a callback after fnctl unlock. */ -extern void (*unlock_callback)(int fd); - -/* Replacement fcntl. */ -int fcntl_with_lockcheck(int fd, int cmd, ... /* arg */ ); - -/* Discard locking info: returns number of locks outstanding. */ -unsigned int forget_locking(void); - -/* Number of errors in locking. */ -extern int locking_errors; - -/* Suppress lock checking. */ -extern bool suppress_lockcheck; - -/* Make all locks non-blocking. */ -extern bool nonblocking_locks; - -/* Number of times we failed a lock because we made it non-blocking. */ -extern int locking_would_block; -#endif /* LOCK_TRACKING_H */ diff --git a/ldb-2.0.8/lib/tdb/test/logging.c b/ldb-2.0.8/lib/tdb/test/logging.c deleted file mode 100644 index dfab486..0000000 --- a/ldb-2.0.8/lib/tdb/test/logging.c +++ /dev/null @@ -1,33 +0,0 @@ -#include "logging.h" -#include "tap-interface.h" -#include -#include -#include -#include - -bool suppress_logging = false; -const char *log_prefix = ""; - -/* Turn log messages into tap diag messages. */ -static void taplog(struct tdb_context *tdb, - enum tdb_debug_level level, - const char *fmt, ...) -{ - va_list ap; - char line[200]; - - if (suppress_logging) - return; - - va_start(ap, fmt); - vsprintf(line, fmt, ap); - va_end(ap); - - /* Strip trailing \n: diag adds it. */ - if (line[0] && line[strlen(line)-1] == '\n') - diag("%s%.*s", log_prefix, (unsigned)strlen(line)-1, line); - else - diag("%s%s", log_prefix, line); -} - -struct tdb_logging_context taplogctx = { taplog, NULL }; diff --git a/ldb-2.0.8/lib/tdb/test/logging.h b/ldb-2.0.8/lib/tdb/test/logging.h deleted file mode 100644 index 89e77b2..0000000 --- a/ldb-2.0.8/lib/tdb/test/logging.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef TDB_TEST_LOGGING_H -#define TDB_TEST_LOGGING_H -#include "replace.h" -#include "../include/tdb.h" -#include - -extern bool suppress_logging; -extern const char *log_prefix; -extern struct tdb_logging_context taplogctx; - -#endif /* TDB_TEST_LOGGING_H */ diff --git a/ldb-2.0.8/lib/tdb/test/old-nohash-be.tdb b/ldb-2.0.8/lib/tdb/test/old-nohash-be.tdb deleted file mode 100644 index 1c49116c1d94ba64c90e6b36651fc5bb41e9b16c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 696 jcmWG>aZ*Uj%t_^9zz)aZ*Uj%t_^9zz%XH8P%GxOO1+-hQNS@0020x1JwWk diff --git a/ldb-2.0.8/lib/tdb/test/run-3G-file.c b/ldb-2.0.8/lib/tdb/test/run-3G-file.c deleted file mode 100644 index 79e291b..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-3G-file.c +++ /dev/null @@ -1,145 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include "logging.h" - -static int tdb_expand_file_sparse(struct tdb_context *tdb, - tdb_off_t size, - tdb_off_t addition) -{ - if (tdb->read_only || tdb->traverse_read) { - tdb->ecode = TDB_ERR_RDONLY; - return -1; - } - - if (tdb_ftruncate(tdb, size+addition) == -1) { - char b = 0; - ssize_t written = tdb_pwrite(tdb, &b, 1, (size+addition) - 1); - if (written == 0) { - /* try once more, potentially revealing errno */ - written = tdb_pwrite(tdb, &b, 1, (size+addition) - 1); - } - if (written == 0) { - /* again - give up, guessing errno */ - errno = ENOSPC; - } - if (written != 1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file to %d failed (%s)\n", - size+addition, strerror(errno))); - return -1; - } - } - - return 0; -} - -static const struct tdb_methods large_io_methods = { - tdb_read, - tdb_write, - tdb_next_hash_chain, - tdb_notrans_oob, - tdb_expand_file_sparse -}; - -static int test_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, - void *_data) -{ - TDB_DATA *expect = _data; - ok1(key.dsize == strlen("hi")); - ok1(memcmp(key.dptr, "hi", strlen("hi")) == 0); - ok1(data.dsize == expect->dsize); - ok1(memcmp(data.dptr, expect->dptr, data.dsize) == 0); - return 0; -} - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - TDB_DATA key, orig_data, data; - uint32_t hashval; - tdb_off_t rec_ptr; - struct tdb_record rec; - int ret; - - plan_tests(24); - tdb = tdb_open_ex("run-36-file.tdb", 1024, TDB_CLEAR_IF_FIRST, - O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); - - ok1(tdb); - tdb->methods = &large_io_methods; - - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - orig_data.dsize = strlen("world"); - orig_data.dptr = discard_const_p(uint8_t, "world"); - - /* Enlarge the file (internally multiplies by 2). */ - ret = tdb_expand(tdb, 1500000000); -#ifdef HAVE_INCOHERENT_MMAP - /* This can fail due to mmap failure on 32 bit systems. */ - if (ret == -1) { - /* These should now fail. */ - ok1(tdb_store(tdb, key, orig_data, TDB_INSERT) == -1); - data = tdb_fetch(tdb, key); - ok1(data.dptr == NULL); - ok1(tdb_traverse(tdb, test_traverse, &orig_data) == -1); - ok1(tdb_delete(tdb, key) == -1); - ok1(tdb_traverse(tdb, test_traverse, NULL) == -1); - /* Skip the rest... */ - for (ret = 0; ret < 24 - 6; ret++) - ok1(1); - tdb_close(tdb); - return exit_status(); - } -#endif - ok1(ret == 0); - - /* Put an entry in, and check it. */ - ok1(tdb_store(tdb, key, orig_data, TDB_INSERT) == 0); - - data = tdb_fetch(tdb, key); - ok1(data.dsize == strlen("world")); - ok1(memcmp(data.dptr, "world", strlen("world")) == 0); - free(data.dptr); - - /* That currently fills at the end, make sure that's true. */ - hashval = tdb->hash_fn(&key); - rec_ptr = tdb_find_lock_hash(tdb, key, hashval, F_RDLCK, &rec); - ok1(rec_ptr); - ok1(rec_ptr > 2U*1024*1024*1024); - tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); - - /* Traverse must work. */ - ok1(tdb_traverse(tdb, test_traverse, &orig_data) == 1); - - /* Delete should work. */ - ok1(tdb_delete(tdb, key) == 0); - - ok1(tdb_traverse(tdb, test_traverse, NULL) == 0); - - /* Transactions should work. */ - ok1(tdb_transaction_start(tdb) == 0); - ok1(tdb_store(tdb, key, orig_data, TDB_INSERT) == 0); - - data = tdb_fetch(tdb, key); - ok1(data.dsize == strlen("world")); - ok1(memcmp(data.dptr, "world", strlen("world")) == 0); - free(data.dptr); - ok1(tdb_transaction_commit(tdb) == 0); - - ok1(tdb_traverse(tdb, test_traverse, &orig_data) == 1); - tdb_close(tdb); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-allrecord-traverse-deadlock.c b/ldb-2.0.8/lib/tdb/test/run-allrecord-traverse-deadlock.c deleted file mode 100644 index 2c58206..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-allrecord-traverse-deadlock.c +++ /dev/null @@ -1,203 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include -#include -#include -#include "logging.h" - -static void do_allrecord_lock(const char *name, int tdb_flags, int up, - int down) -{ - struct tdb_context *tdb; - int ret; - ssize_t nread, nwritten; - char c = 0; - - tdb = tdb_open_ex(name, 3, tdb_flags, - O_RDWR|O_CREAT, 0755, &taplogctx, NULL); - ok(tdb, "tdb_open_ex should succeed"); - - ret = tdb_lockall(tdb); - ok(ret == 0, "tdb_lockall should succeed"); - - nwritten = write(up, &c, sizeof(c)); - ok(nwritten == sizeof(c), "write should succeed"); - - nread = read(down, &c, sizeof(c)); - ok(nread == sizeof(c), "read should succeed"); - - ret = tdb_traverse(tdb, NULL, NULL); - ok(ret == -1, "do_allrecord_lock: traverse should fail"); - - nwritten = write(up, &c, sizeof(c)); - ok(nwritten == sizeof(c), "write should succeed"); - - exit(0); -} - -static void do_traverse(const char *name, int tdb_flags, int up, int down) -{ - struct tdb_context *tdb; - int ret; - ssize_t nread, nwritten; - char c = 0; - - tdb = tdb_open_ex(name, 3, tdb_flags, - O_RDWR|O_CREAT, 0755, &taplogctx, NULL); - ok(tdb, "tdb_open_ex should succeed"); - - ret = tdb_traverse(tdb, NULL, NULL); - ok(ret == 1, "do_traverse: tdb_traverse should return 1 record"); - - nwritten = write(up, &c, sizeof(c)); - ok(nwritten == sizeof(c), "write should succeed"); - - nread = read(down, &c, sizeof(c)); - ok(nread == sizeof(c), "read should succeed"); - - exit(0); -} - -/* - * Process 1: get the allrecord_lock on a tdb. - * Process 2: start a traverse, this will stall waiting for the - * first chainlock: That is taken by the allrecord_lock - * Process 1: start a traverse: This will get EDEADLK in trying to - * get the TRANSACTION_LOCK. It will deadlock for mutexes, - * which don't have built-in deadlock detection. - */ - -static int do_tests(const char *name, int tdb_flags) -{ - struct tdb_context *tdb; - int ret; - pid_t traverse_child, allrecord_child; - int traverse_down[2]; - int traverse_up[2]; - int allrecord_down[2]; - int allrecord_up[2]; - char c; - ssize_t nread, nwritten; - TDB_DATA key, data; - - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - data.dsize = strlen("world"); - data.dptr = discard_const_p(uint8_t, "world"); - - tdb = tdb_open_ex(name, 3, tdb_flags, - O_RDWR|O_CREAT, 0755, &taplogctx, NULL); - ok(tdb, "tdb_open_ex should succeed"); - - ret = tdb_store(tdb, key, data, TDB_INSERT); - ok(ret == 0, "tdb_store should succeed"); - - ret = pipe(traverse_down); - ok(ret == 0, "pipe should succeed"); - - ret = pipe(traverse_up); - ok(ret == 0, "pipe should succeed"); - - ret = pipe(allrecord_down); - ok(ret == 0, "pipe should succeed"); - - ret = pipe(allrecord_up); - ok(ret == 0, "pipe should succeed"); - - allrecord_child = fork(); - ok(allrecord_child != -1, "fork should succeed"); - - if (allrecord_child == 0) { - tdb_close(tdb); - close(traverse_up[0]); - close(traverse_up[1]); - close(traverse_down[0]); - close(traverse_down[1]); - close(allrecord_up[0]); - close(allrecord_down[1]); - do_allrecord_lock(name, tdb_flags, - allrecord_up[1], allrecord_down[0]); - exit(0); - } - close(allrecord_up[1]); - close(allrecord_down[0]); - - nread = read(allrecord_up[0], &c, sizeof(c)); - ok(nread == sizeof(c), "read should succeed"); - - traverse_child = fork(); - ok(traverse_child != -1, "fork should succeed"); - - if (traverse_child == 0) { - tdb_close(tdb); - close(traverse_up[0]); - close(traverse_down[1]); - close(allrecord_up[0]); - close(allrecord_down[1]); - do_traverse(name, tdb_flags, - traverse_up[1], traverse_down[0]); - exit(0); - } - close(traverse_up[1]); - close(traverse_down[0]); - - poll(NULL, 0, 1000); - - nwritten = write(allrecord_down[1], &c, sizeof(c)); - ok(nwritten == sizeof(c), "write should succeed"); - - nread = read(traverse_up[0], &c, sizeof(c)); - ok(nread == sizeof(c), "read should succeed"); - - nwritten = write(traverse_down[1], &c, sizeof(c)); - ok(nwritten == sizeof(c), "write should succeed"); - - nread = read(allrecord_up[0], &c, sizeof(c)); - ok(nread == sizeof(c), "ret should succeed"); - - close(traverse_up[0]); - close(traverse_down[1]); - close(allrecord_up[0]); - close(allrecord_down[1]); - diag("%s tests done", name); - return exit_status(); -} - -int main(int argc, char *argv[]) -{ - int ret; - bool mutex_support; - - mutex_support = tdb_runtime_check_for_robust_mutexes(); - - ret = do_tests("marklock-deadlock-fcntl.tdb", - TDB_CLEAR_IF_FIRST | - TDB_INCOMPATIBLE_HASH); - ok(ret == 0, "marklock-deadlock-fcntl.tdb tests should succeed"); - - if (!mutex_support) { - skip(1, "No robust mutex support, " - "skipping marklock-deadlock-mutex.tdb tests"); - return exit_status(); - } - - ret = do_tests("marklock-deadlock-mutex.tdb", - TDB_CLEAR_IF_FIRST | - TDB_MUTEX_LOCKING | - TDB_INCOMPATIBLE_HASH); - ok(ret == 0, "marklock-deadlock-mutex.tdb tests should succeed"); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-bad-tdb-header.c b/ldb-2.0.8/lib/tdb/test/run-bad-tdb-header.c deleted file mode 100644 index 9d29fdf..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-bad-tdb-header.c +++ /dev/null @@ -1,59 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include "logging.h" - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - struct tdb_header hdr; - int fd; - - plan_tests(11); - /* Can open fine if complete crap, as long as O_CREAT. */ - fd = open("run-bad-tdb-header.tdb", O_RDWR|O_CREAT|O_TRUNC, 0600); - ok1(fd >= 0); - ok1(write(fd, "hello world", 11) == 11); - close(fd); - tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, O_RDWR, 0, - &taplogctx, NULL); - ok1(!tdb); - tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, O_CREAT|O_RDWR, - 0600, &taplogctx, NULL); - ok1(tdb); - tdb_close(tdb); - - /* Now, with wrong version it should *not* overwrite. */ - fd = open("run-bad-tdb-header.tdb", O_RDWR); - ok1(fd >= 0); - ok1(read(fd, &hdr, sizeof(hdr)) == sizeof(hdr)); - ok1(hdr.version == TDB_VERSION); - hdr.version++; - lseek(fd, 0, SEEK_SET); - ok1(write(fd, &hdr, sizeof(hdr)) == sizeof(hdr)); - close(fd); - - tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, O_RDWR|O_CREAT, - 0600, &taplogctx, NULL); - ok1(errno == EIO); - ok1(!tdb); - - /* With truncate, will be fine. */ - tdb = tdb_open_ex("run-bad-tdb-header.tdb", 1024, 0, - O_RDWR|O_CREAT|O_TRUNC, 0600, &taplogctx, NULL); - ok1(tdb); - tdb_close(tdb); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-check.c b/ldb-2.0.8/lib/tdb/test/run-check.c deleted file mode 100644 index ce389a2..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-check.c +++ /dev/null @@ -1,65 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include "logging.h" - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - TDB_DATA key, data; - - plan_tests(13); - tdb = tdb_open_ex("run-check.tdb", 1, TDB_CLEAR_IF_FIRST, - O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); - - ok1(tdb); - ok1(tdb_check(tdb, NULL, NULL) == 0); - - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - data.dsize = strlen("world"); - data.dptr = discard_const_p(uint8_t, "world"); - - ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); - ok1(tdb_check(tdb, NULL, NULL) == 0); - tdb_close(tdb); - - tdb = tdb_open_ex("run-check.tdb", 1024, 0, O_RDWR, 0, - &taplogctx, NULL); - ok1(tdb); - ok1(tdb_check(tdb, NULL, NULL) == 0); - tdb_close(tdb); - - tdb = tdb_open_ex("test/tdb.corrupt", 1024, 0, O_RDWR, 0, - &taplogctx, NULL); - ok1(tdb); - ok1(tdb_check(tdb, NULL, NULL) == -1); - ok1(tdb_error(tdb) == TDB_ERR_CORRUPT); - tdb_close(tdb); - - /* Big and little endian should work! */ - tdb = tdb_open_ex("test/old-nohash-le.tdb", 1024, 0, O_RDWR, 0, - &taplogctx, NULL); - ok1(tdb); - ok1(tdb_check(tdb, NULL, NULL) == 0); - tdb_close(tdb); - - tdb = tdb_open_ex("test/old-nohash-be.tdb", 1024, 0, O_RDWR, 0, - &taplogctx, NULL); - ok1(tdb); - ok1(tdb_check(tdb, NULL, NULL) == 0); - tdb_close(tdb); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-circular-chain.c b/ldb-2.0.8/lib/tdb/test/run-circular-chain.c deleted file mode 100644 index 4fb32a2..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-circular-chain.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include "logging.h" - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - TDB_DATA key; - - plan_tests(3); - tdb = tdb_open_ex( - "test/circular_chain.tdb", - 0, - TDB_DEFAULT, - O_RDONLY, - 0600, - &taplogctx, - NULL); - - ok1(tdb); - key.dsize = strlen("x"); - key.dptr = discard_const_p(uint8_t, "x"); - - ok1(tdb_exists(tdb, key) == 0); - ok1(tdb_error(tdb) == TDB_ERR_CORRUPT); - - tdb_close(tdb); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-circular-freelist.c b/ldb-2.0.8/lib/tdb/test/run-circular-freelist.c deleted file mode 100644 index f1bec87..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-circular-freelist.c +++ /dev/null @@ -1,50 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include "logging.h" - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - TDB_DATA key, data; - - plan_tests(3); - tdb = tdb_open_ex( - "test/circular_freelist.tdb", - 0, - TDB_DEFAULT, - O_RDWR, - 0600, - &taplogctx, - NULL); - - ok1(tdb); - - /* - * All freelist records are just 1 byte key and value. Insert - * something that will walk the whole freelist and hit the - * circle. - */ - key.dsize = strlen("x"); - key.dptr = discard_const_p(uint8_t, "x"); - data.dsize = strlen("too long"); - data.dptr = discard_const_p(uint8_t, "too long"); - - ok1(tdb_store(tdb, key, data, TDB_INSERT) == -1); - ok1(tdb_error(tdb) == TDB_ERR_CORRUPT); - - tdb_close(tdb); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-corrupt.c b/ldb-2.0.8/lib/tdb/test/run-corrupt.c deleted file mode 100644 index e6fc751..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-corrupt.c +++ /dev/null @@ -1,132 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include "logging.h" - -static int check(TDB_DATA key, TDB_DATA data, void *private) -{ - unsigned int *sizes = private; - - if (key.dsize > strlen("hello")) - return -1; - if (memcmp(key.dptr, "hello", key.dsize) != 0) - return -1; - - if (data.dsize != strlen("world")) - return -1; - if (memcmp(data.dptr, "world", data.dsize) != 0) - return -1; - - sizes[0] += key.dsize; - sizes[1] += data.dsize; - return 0; -} - -static void tdb_flip_bit(struct tdb_context *tdb, unsigned int bit) -{ - unsigned int off = bit / CHAR_BIT; - unsigned char mask = (1 << (bit % CHAR_BIT)); - - if (tdb->map_ptr) - ((unsigned char *)tdb->map_ptr)[off] ^= mask; - else { - unsigned char c; - if (pread(tdb->fd, &c, 1, off) != 1) { - fprintf(stderr, "pread: %s\n", strerror(errno)); - exit(1); - } - c ^= mask; - if (pwrite(tdb->fd, &c, 1, off) != 1) { - fprintf(stderr, "pwrite: %s\n", strerror(errno)); - exit(1); - } - } -} - -static void check_test(struct tdb_context *tdb) -{ - TDB_DATA key, data; - unsigned int i, verifiable, corrupt, sizes[2], dsize, ksize; - - ok1(tdb_check(tdb, NULL, NULL) == 0); - - key.dptr = discard_const_p(uint8_t, "hello"); - data.dsize = strlen("world"); - data.dptr = discard_const_p(uint8_t, "world"); - - /* Key and data size respectively. */ - dsize = ksize = 0; - - /* 5 keys in hash size 2 means we'll have multichains. */ - for (key.dsize = 1; key.dsize <= 5; key.dsize++) { - ksize += key.dsize; - dsize += data.dsize; - if (tdb_store(tdb, key, data, TDB_INSERT) != 0) - abort(); - } - - /* This is how many bytes we expect to be verifiable. */ - /* From the file header. */ - verifiable = strlen(TDB_MAGIC_FOOD) + 1 - + 2 * sizeof(uint32_t) + 2 * sizeof(tdb_off_t) - + 2 * sizeof(uint32_t); - /* From the free list chain and hash chains. */ - verifiable += 3 * sizeof(tdb_off_t); - /* From the record headers & tailer */ - verifiable += 5 * (sizeof(struct tdb_record) + sizeof(uint32_t)); - /* The free block: we ignore datalen, keylen, full_hash. */ - verifiable += sizeof(struct tdb_record) - 3*sizeof(uint32_t) + - sizeof(uint32_t); - /* Our check function verifies the key and data. */ - verifiable += ksize + dsize; - - /* Flip one bit at a time, make sure it detects verifiable bytes. */ - for (i = 0, corrupt = 0; i < tdb->map_size * CHAR_BIT; i++) { - tdb_flip_bit(tdb, i); - memset(sizes, 0, sizeof(sizes)); - if (tdb_check(tdb, check, sizes) != 0) - corrupt++; - else if (sizes[0] != ksize || sizes[1] != dsize) - corrupt++; - tdb_flip_bit(tdb, i); - } - ok(corrupt == verifiable * CHAR_BIT, "corrupt %u should be %u", - corrupt, verifiable * CHAR_BIT); -} - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - - plan_tests(4); - /* This should use mmap. */ - tdb = tdb_open_ex("run-corrupt.tdb", 2, TDB_CLEAR_IF_FIRST, - O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); - - if (!tdb) - abort(); - check_test(tdb); - tdb_close(tdb); - - /* This should not. */ - tdb = tdb_open_ex("run-corrupt.tdb", 2, TDB_CLEAR_IF_FIRST|TDB_NOMMAP, - O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); - - if (!tdb) - abort(); - check_test(tdb); - tdb_close(tdb); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-die-during-transaction.c b/ldb-2.0.8/lib/tdb/test/run-die-during-transaction.c deleted file mode 100644 index c636d87..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-die-during-transaction.c +++ /dev/null @@ -1,232 +0,0 @@ -#include "../common/tdb_private.h" -#include "lock-tracking.h" -static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset); -static ssize_t write_check(int fd, const void *buf, size_t count); -static int ftruncate_check(int fd, off_t length); - -#define pwrite pwrite_check -#define write write_check -#define fcntl fcntl_with_lockcheck -#define ftruncate ftruncate_check - -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include -#include -#include -#include "external-agent.h" -#include "logging.h" - -#undef write -#undef pwrite -#undef fcntl -#undef ftruncate - -static bool in_transaction; -static int target, current; -static jmp_buf jmpbuf; -#define TEST_DBNAME "run-die-during-transaction.tdb" -#define KEY_STRING "helloworld" - -static void maybe_die(int fd) -{ - if (in_transaction && current++ == target) { - longjmp(jmpbuf, 1); - } -} - -static ssize_t pwrite_check(int fd, - const void *buf, size_t count, off_t offset) -{ - ssize_t ret; - - maybe_die(fd); - - ret = pwrite(fd, buf, count, offset); - if (ret != count) - return ret; - - maybe_die(fd); - return ret; -} - -static ssize_t write_check(int fd, const void *buf, size_t count) -{ - ssize_t ret; - - maybe_die(fd); - - ret = write(fd, buf, count); - if (ret != count) - return ret; - - maybe_die(fd); - return ret; -} - -static int ftruncate_check(int fd, off_t length) -{ - int ret; - - maybe_die(fd); - - ret = ftruncate(fd, length); - - maybe_die(fd); - return ret; -} - -static bool test_death(enum operation op, struct agent *agent) -{ - struct tdb_context *tdb = NULL; - TDB_DATA key; - enum agent_return ret; - int needed_recovery = 0; - - current = target = 0; -reset: - unlink(TEST_DBNAME); - tdb = tdb_open_ex(TEST_DBNAME, 1024, TDB_NOMMAP, - O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); - - if (setjmp(jmpbuf) != 0) { - /* We're partway through. Simulate our death. */ - close(tdb->fd); - forget_locking(); - in_transaction = false; - - ret = external_agent_operation(agent, NEEDS_RECOVERY, ""); - if (ret == SUCCESS) - needed_recovery++; - else if (ret != FAILED) { - diag("Step %u agent NEEDS_RECOVERY = %s", current, - agent_return_name(ret)); - return false; - } - - ret = external_agent_operation(agent, op, KEY_STRING); - if (ret != SUCCESS) { - diag("Step %u op %s failed = %s", current, - operation_name(op), - agent_return_name(ret)); - return false; - } - - ret = external_agent_operation(agent, NEEDS_RECOVERY, ""); - if (ret != FAILED) { - diag("Still needs recovery after step %u = %s", - current, agent_return_name(ret)); - return false; - } - - ret = external_agent_operation(agent, CHECK, ""); - if (ret != SUCCESS) { - diag("Step %u check failed = %s", current, - agent_return_name(ret)); - return false; - } - - ret = external_agent_operation(agent, CLOSE, ""); - if (ret != SUCCESS) { - diag("Step %u close failed = %s", current, - agent_return_name(ret)); - return false; - } - - /* Suppress logging as this tries to use closed fd. */ - suppress_logging = true; - suppress_lockcheck = true; - tdb_close(tdb); - suppress_logging = false; - suppress_lockcheck = false; - target++; - current = 0; - goto reset; - } - - /* Put key for agent to fetch. */ - key.dsize = strlen(KEY_STRING); - key.dptr = discard_const_p(uint8_t, KEY_STRING); - if (tdb_store(tdb, key, key, TDB_INSERT) != 0) - return false; - - /* This is the key we insert in transaction. */ - key.dsize--; - - ret = external_agent_operation(agent, OPEN, TEST_DBNAME); - if (ret != SUCCESS) { - fprintf(stderr, "Agent failed to open: %s\n", - agent_return_name(ret)); - exit(1); - } - - ret = external_agent_operation(agent, FETCH, KEY_STRING); - if (ret != SUCCESS) { - fprintf(stderr, "Agent failed find key: %s\n", - agent_return_name(ret)); - exit(1); - } - - in_transaction = true; - if (tdb_transaction_start(tdb) != 0) - return false; - - if (tdb_store(tdb, key, key, TDB_INSERT) != 0) - return false; - - if (tdb_transaction_commit(tdb) != 0) - return false; - - in_transaction = false; - - /* We made it! */ - diag("Completed %u runs", current); - tdb_close(tdb); - ret = external_agent_operation(agent, CLOSE, ""); - if (ret != SUCCESS) { - diag("Step %u close failed = %s", current, - agent_return_name(ret)); - return false; - } - -#ifdef HAVE_INCOHERENT_MMAP - /* This means we always mmap, which makes this test a noop. */ - ok1(1); -#else - ok1(needed_recovery); -#endif - ok1(locking_errors == 0); - ok1(forget_locking() == 0); - locking_errors = 0; - return true; -} - -int main(int argc, char *argv[]) -{ - enum operation ops[] = { FETCH, STORE, TRANSACTION_START }; - struct agent *agent; - int i; - - plan_tests(12); - unlock_callback = maybe_die; - - agent = prepare_external_agent(); - - for (i = 0; i < sizeof(ops)/sizeof(ops[0]); i++) { - diag("Testing %s after death", operation_name(ops[i])); - ok1(test_death(ops[i], agent)); - } - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-endian.c b/ldb-2.0.8/lib/tdb/test/run-endian.c deleted file mode 100644 index 9d4d5f5..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-endian.c +++ /dev/null @@ -1,64 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include "logging.h" - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - TDB_DATA key, data; - - plan_tests(13); - tdb = tdb_open_ex("run-endian.tdb", 1024, - TDB_CLEAR_IF_FIRST|TDB_CONVERT, - O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); - - ok1(tdb); - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - data.dsize = strlen("world"); - data.dptr = discard_const_p(uint8_t, "world"); - - ok1(tdb_store(tdb, key, data, TDB_MODIFY) < 0); - ok1(tdb_error(tdb) == TDB_ERR_NOEXIST); - ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); - ok1(tdb_store(tdb, key, data, TDB_INSERT) < 0); - ok1(tdb_error(tdb) == TDB_ERR_EXISTS); - ok1(tdb_store(tdb, key, data, TDB_MODIFY) == 0); - - data = tdb_fetch(tdb, key); - ok1(data.dsize == strlen("world")); - ok1(memcmp(data.dptr, "world", strlen("world")) == 0); - free(data.dptr); - - key.dsize++; - data = tdb_fetch(tdb, key); - ok1(data.dptr == NULL); - tdb_close(tdb); - - /* Reopen: should read it */ - tdb = tdb_open_ex("run-endian.tdb", 1024, 0, O_RDWR, 0, - &taplogctx, NULL); - ok1(tdb); - - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - data = tdb_fetch(tdb, key); - ok1(data.dsize == strlen("world")); - ok1(memcmp(data.dptr, "world", strlen("world")) == 0); - free(data.dptr); - tdb_close(tdb); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-fcntl-deadlock.c b/ldb-2.0.8/lib/tdb/test/run-fcntl-deadlock.c deleted file mode 100644 index 0a328af..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-fcntl-deadlock.c +++ /dev/null @@ -1,202 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include -#include "tap-interface.h" - -/* - * This tests the low level locking requirement - * for the allrecord lock/prepare_commit and traverse_read interaction. - * - * The pattern with the traverse_read and prepare_commit interaction is - * the following: - * - * 1. transaction_start got the allrecord lock with F_RDLCK. - * - * 2. the traverse_read code walks the database in a sequence like this - * (per chain): - * 2.1 chainlock(chainX, F_RDLCK) - * 2.2 recordlock(chainX.record1, F_RDLCK) - * 2.3 chainunlock(chainX, F_RDLCK) - * 2.4 callback(chainX.record1) - * 2.5 chainlock(chainX, F_RDLCK) - * 2.6 recordunlock(chainX.record1, F_RDLCK) - * 2.7 recordlock(chainX.record2, F_RDLCK) - * 2.8 chainunlock(chainX, F_RDLCK) - * 2.9 callback(chainX.record2) - * 2.10 chainlock(chainX, F_RDLCK) - * 2.11 recordunlock(chainX.record2, F_RDLCK) - * 2.12 chainunlock(chainX, F_RDLCK) - * 2.13 goto next chain - * - * So it has always one record locked in F_RDLCK mode and tries to - * get the 2nd one before it releases the first one. - * - * 3. prepare_commit tries to upgrade the allrecord lock to F_RWLCK - * If that happens at the time of 2.4, the operation of - * 2.5 may deadlock with the allrecord lock upgrade. - * On Linux step 2.5 works in order to make some progress with the - * locking, but on solaris it might fail because the kernel - * wants to satisfy the 1st lock requester before the 2nd one. - * - * I think the first step is a standalone test that does this: - * - * process1: F_RDLCK for ofs=0 len=2 - * process2: F_RDLCK for ofs=0 len=1 - * process1: upgrade ofs=0 len=2 to F_RWLCK (in blocking mode) - * process2: F_RDLCK for ofs=1 len=1 - * process2: unlock ofs=0 len=2 - * process1: should continue at that point - * - * Such a test follows here... - */ - -static int raw_fcntl_lock(int fd, int rw, off_t off, off_t len, bool waitflag) -{ - struct flock fl; - int cmd; - fl.l_type = rw; - fl.l_whence = SEEK_SET; - fl.l_start = off; - fl.l_len = len; - fl.l_pid = 0; - - cmd = waitflag ? F_SETLKW : F_SETLK; - - return fcntl(fd, cmd, &fl); -} - -static int raw_fcntl_unlock(int fd, off_t off, off_t len) -{ - struct flock fl; - fl.l_type = F_UNLCK; - fl.l_whence = SEEK_SET; - fl.l_start = off; - fl.l_len = len; - fl.l_pid = 0; - - return fcntl(fd, F_SETLKW, &fl); -} - - -int pipe_r; -int pipe_w; -char buf[2]; - -static void expect_char(char c) -{ - read(pipe_r, buf, 1); - if (*buf != c) { - fail("We were expecting %c, but got %c", c, buf[0]); - } -} - -static void send_char(char c) -{ - write(pipe_w, &c, 1); -} - - -int main(int argc, char *argv[]) -{ - int process; - int fd; - const char *filename = "run-fcntl-deadlock.lck"; - int pid; - int pipes_1_2[2]; - int pipes_2_1[2]; - int ret; - - pipe(pipes_1_2); - pipe(pipes_2_1); - fd = open(filename, O_RDWR | O_CREAT, 0755); - - pid = fork(); - if (pid == 0) { - pipe_r = pipes_1_2[0]; - pipe_w = pipes_2_1[1]; - process = 2; - alarm(15); - } else { - pipe_r = pipes_2_1[0]; - pipe_w = pipes_1_2[1]; - process = 1; - alarm(15); - } - - /* a: process1: F_RDLCK for ofs=0 len=2 */ - if (process == 1) { - ret = raw_fcntl_lock(fd, F_RDLCK, 0, 2, true); - ok(ret == 0, - "process 1 lock ofs=0 len=2: %d - %s", - ret, strerror(errno)); - diag("process 1 took read lock on range 0,2"); - send_char('a'); - } - - /* process2: F_RDLCK for ofs=0 len=1 */ - if (process == 2) { - expect_char('a'); - ret = raw_fcntl_lock(fd, F_RDLCK, 0, 1, true); - ok(ret == 0, - "process 2 lock ofs=0 len=1: %d - %s", - ret, strerror(errno));; - diag("process 2 took read lock on range 0,1"); - send_char('b'); - } - - /* process1: upgrade ofs=0 len=2 to F_RWLCK (in blocking mode) */ - if (process == 1) { - expect_char('b'); - send_char('c'); - diag("process 1 starts upgrade on range 0,2"); - ret = raw_fcntl_lock(fd, F_WRLCK, 0, 2, true); - ok(ret == 0, - "process 1 RW lock ofs=0 len=2: %d - %s", - ret, strerror(errno)); - diag("process 1 got read upgrade done"); - /* at this point process 1 is blocked on 2 releasing the - read lock */ - } - - /* - * process2: F_RDLCK for ofs=1 len=1 - * process2: unlock ofs=0 len=2 - */ - if (process == 2) { - expect_char('c'); /* we know process 1 is *about* to lock */ - sleep(1); - ret = raw_fcntl_lock(fd, F_RDLCK, 1, 1, true); - ok(ret == 0, - "process 2 lock ofs=1 len=1: %d - %s", - ret, strerror(errno)); - diag("process 2 got read lock on 1,1\n"); - ret = raw_fcntl_unlock(fd, 0, 2); - ok(ret == 0, - "process 2 unlock ofs=0 len=2: %d - %s", - ret, strerror(errno)); - diag("process 2 released read lock on 0,2\n"); - sleep(1); - send_char('d'); - } - - if (process == 1) { - expect_char('d'); - } - - diag("process %d has got to the end\n", process); - - return 0; -} diff --git a/ldb-2.0.8/lib/tdb/test/run-incompatible.c b/ldb-2.0.8/lib/tdb/test/run-incompatible.c deleted file mode 100644 index 5f1b586..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-incompatible.c +++ /dev/null @@ -1,188 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include - -static unsigned int tdb_dumb_hash(TDB_DATA *key) -{ - return key->dsize; -} - -static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) -{ - unsigned int *count = tdb_get_logging_private(tdb); - if (strstr(fmt, "hash")) - (*count)++; -} - -static unsigned int hdr_rwlocks(const char *fname) -{ - struct tdb_header hdr; - ssize_t nread; - - int fd = open(fname, O_RDONLY); - if (fd == -1) - return -1; - - nread = read(fd, &hdr, sizeof(hdr)); - close(fd); - if (nread != sizeof(hdr)) { - return -1; - } - return hdr.rwlocks; -} - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - unsigned int log_count, flags; - TDB_DATA d, r; - struct tdb_logging_context log_ctx = { log_fn, &log_count }; - - plan_tests(38 * 2); - - for (flags = 0; flags <= TDB_CONVERT; flags += TDB_CONVERT) { - unsigned int rwmagic = TDB_HASH_RWLOCK_MAGIC; - - if (flags & TDB_CONVERT) - tdb_convert(&rwmagic, sizeof(rwmagic)); - - /* Create an old-style hash. */ - log_count = 0; - tdb = tdb_open_ex("run-incompatible.tdb", 0, flags, - O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx, - NULL); - ok1(tdb); - ok1(log_count == 0); - d.dptr = discard_const_p(uint8_t, "Hello"); - d.dsize = 5; - ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0); - tdb_close(tdb); - - /* Should not have marked rwlocks field. */ - ok1(hdr_rwlocks("run-incompatible.tdb") == 0); - - /* We can still open any old-style with incompat flag. */ - log_count = 0; - tdb = tdb_open_ex("run-incompatible.tdb", 0, - TDB_INCOMPATIBLE_HASH, - O_RDWR, 0600, &log_ctx, NULL); - ok1(tdb); - ok1(log_count == 0); - r = tdb_fetch(tdb, d); - ok1(r.dsize == 5); - free(r.dptr); - ok1(tdb_check(tdb, NULL, NULL) == 0); - tdb_close(tdb); - - log_count = 0; - tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDONLY, - 0, &log_ctx, tdb_jenkins_hash); - ok1(tdb); - ok1(log_count == 0); - ok1(tdb_check(tdb, NULL, NULL) == 0); - tdb_close(tdb); - - log_count = 0; - tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDONLY, - 0, &log_ctx, tdb_jenkins_hash); - ok1(tdb); - ok1(log_count == 0); - ok1(tdb_check(tdb, NULL, NULL) == 0); - tdb_close(tdb); - - /* OK, now create with incompatible flag, default hash. */ - log_count = 0; - tdb = tdb_open_ex("run-incompatible.tdb", 0, - flags|TDB_INCOMPATIBLE_HASH, - O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx, - NULL); - ok1(tdb); - ok1(log_count == 0); - d.dptr = discard_const_p(uint8_t, "Hello"); - d.dsize = 5; - ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0); - tdb_close(tdb); - - /* Should have marked rwlocks field. */ - ok1(hdr_rwlocks("run-incompatible.tdb") == rwmagic); - - /* Cannot open with old hash. */ - log_count = 0; - tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, - O_RDWR, 0600, &log_ctx, tdb_old_hash); - ok1(!tdb); - ok1(log_count == 1); - - /* Can open with jenkins hash. */ - log_count = 0; - tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, - O_RDWR, 0600, &log_ctx, tdb_jenkins_hash); - ok1(tdb); - ok1(log_count == 0); - r = tdb_fetch(tdb, d); - ok1(r.dsize == 5); - free(r.dptr); - ok1(tdb_check(tdb, NULL, NULL) == 0); - tdb_close(tdb); - - /* Can open by letting it figure it out itself. */ - log_count = 0; - tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, - O_RDWR, 0600, &log_ctx, NULL); - ok1(tdb); - ok1(log_count == 0); - r = tdb_fetch(tdb, d); - ok1(r.dsize == 5); - free(r.dptr); - ok1(tdb_check(tdb, NULL, NULL) == 0); - tdb_close(tdb); - - /* We can also use incompatible hash with other hashes. */ - log_count = 0; - tdb = tdb_open_ex("run-incompatible.tdb", 0, - flags|TDB_INCOMPATIBLE_HASH, - O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx, - tdb_dumb_hash); - ok1(tdb); - ok1(log_count == 0); - d.dptr = discard_const_p(uint8_t, "Hello"); - d.dsize = 5; - ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0); - tdb_close(tdb); - - /* Should have marked rwlocks field. */ - ok1(hdr_rwlocks("run-incompatible.tdb") == rwmagic); - - /* It should not open if we don't specify. */ - log_count = 0; - tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0, - &log_ctx, NULL); - ok1(!tdb); - ok1(log_count == 1); - - /* Should reopen with correct hash. */ - log_count = 0; - tdb = tdb_open_ex("run-incompatible.tdb", 0, 0, O_RDWR, 0, - &log_ctx, tdb_dumb_hash); - ok1(tdb); - ok1(log_count == 0); - r = tdb_fetch(tdb, d); - ok1(r.dsize == 5); - free(r.dptr); - ok1(tdb_check(tdb, NULL, NULL) == 0); - tdb_close(tdb); - } - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-marklock-deadlock.c b/ldb-2.0.8/lib/tdb/test/run-marklock-deadlock.c deleted file mode 100644 index 37e959f..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-marklock-deadlock.c +++ /dev/null @@ -1,278 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include -#include -#include -#include "logging.h" - -static TDB_DATA key, data; - -static void do_chainlock(const char *name, int tdb_flags, int up, int down) -{ - struct tdb_context *tdb; - int ret; - ssize_t nread, nwritten; - char c = 0; - - tdb = tdb_open_ex(name, 3, tdb_flags, - O_RDWR|O_CREAT, 0755, &taplogctx, NULL); - ok(tdb, "tdb_open_ex should succeed"); - - ret = tdb_chainlock(tdb, key); - ok(ret == 0, "tdb_chainlock should succeed"); - - nwritten = write(up, &c, sizeof(c)); - ok(nwritten == sizeof(c), "write should succeed"); - - nread = read(down, &c, sizeof(c)); - ok(nread == sizeof(c), "read should succeed"); - - exit(0); -} - -static void do_allrecord_lock(const char *name, int tdb_flags, int up, int down) -{ - struct tdb_context *tdb; - int ret; - ssize_t nread, nwritten; - char c = 0; - - tdb = tdb_open_ex(name, 3, tdb_flags, - O_RDWR|O_CREAT, 0755, &taplogctx, NULL); - ok(tdb, "tdb_open_ex should succeed"); - - ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); - ok(ret == 0, "tdb_allrecord_lock should succeed"); - - nwritten = write(up, &c, sizeof(c)); - ok(nwritten == sizeof(c), "write should succeed"); - - nread = read(down, &c, sizeof(c)); - ok(nread == sizeof(c), "read should succeed"); - - exit(0); -} - -/* The code should barf on TDBs created with rwlocks. */ -static int do_tests(const char *name, int tdb_flags) -{ - struct tdb_context *tdb; - int ret; - pid_t chainlock_child, allrecord_child; - int chainlock_down[2]; - int chainlock_up[2]; - int allrecord_down[2]; - int allrecord_up[2]; - char c; - ssize_t nread, nwritten; - - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - data.dsize = strlen("world"); - data.dptr = discard_const_p(uint8_t, "world"); - - ret = pipe(chainlock_down); - ok(ret == 0, "pipe should succeed"); - - ret = pipe(chainlock_up); - ok(ret == 0, "pipe should succeed"); - - ret = pipe(allrecord_down); - ok(ret == 0, "pipe should succeed"); - - ret = pipe(allrecord_up); - ok(ret == 0, "pipe should succeed"); - - chainlock_child = fork(); - ok(chainlock_child != -1, "fork should succeed"); - - if (chainlock_child == 0) { - close(chainlock_up[0]); - close(chainlock_down[1]); - close(allrecord_up[0]); - close(allrecord_up[1]); - close(allrecord_down[0]); - close(allrecord_down[1]); - do_chainlock(name, tdb_flags, - chainlock_up[1], chainlock_down[0]); - exit(0); - } - close(chainlock_up[1]); - close(chainlock_down[0]); - - nread = read(chainlock_up[0], &c, sizeof(c)); - ok(nread == sizeof(c), "read should succeed"); - - /* - * Now we have a process holding a chainlock. Start another process - * trying the allrecord lock. This will block. - */ - - allrecord_child = fork(); - ok(allrecord_child != -1, "fork should succeed"); - - if (allrecord_child == 0) { - close(chainlock_up[0]); - close(chainlock_up[1]); - close(chainlock_down[0]); - close(chainlock_down[1]); - close(allrecord_up[0]); - close(allrecord_down[1]); - do_allrecord_lock(name, tdb_flags, - allrecord_up[1], allrecord_down[0]); - exit(0); - } - close(allrecord_up[1]); - close(allrecord_down[0]); - - poll(NULL, 0, 500); - - tdb = tdb_open_ex(name, 3, tdb_flags, - O_RDWR|O_CREAT, 0755, &taplogctx, NULL); - ok(tdb, "tdb_open_ex should succeed"); - - /* - * Someone already holds a chainlock, but we're able to get the - * freelist lock. - * - * The freelist lock/mutex is independent from the allrecord lock/mutex. - */ - - ret = tdb_chainlock_nonblock(tdb, key); - ok(ret == -1, "tdb_chainlock_nonblock should not succeed"); - - ret = tdb_lock_nonblock(tdb, -1, F_WRLCK); - ok(ret == 0, "tdb_lock_nonblock should succeed"); - - ret = tdb_unlock(tdb, -1, F_WRLCK); - ok(ret == 0, "tdb_unlock should succeed"); - - /* - * We have someone else having done the lock for us. Just mark it. - */ - - ret = tdb_chainlock_mark(tdb, key); - ok(ret == 0, "tdb_chainlock_mark should succeed"); - - /* - * The tdb_store below will block the freelist. In one version of the - * mutex patches, the freelist was already blocked here by the - * allrecord child, which was waiting for the chainlock child to give - * up its chainlock. Make sure that we don't run into this - * deadlock. To exercise the deadlock, just comment out the "ok" - * line. - * - * The freelist lock/mutex is independent from the allrecord lock/mutex. - */ - - ret = tdb_lock_nonblock(tdb, -1, F_WRLCK); - ok(ret == 0, "tdb_lock_nonblock should succeed"); - - ret = tdb_unlock(tdb, -1, F_WRLCK); - ok(ret == 0, "tdb_unlock should succeed"); - - ret = tdb_store(tdb, key, data, TDB_INSERT); - ok(ret == 0, "tdb_store should succeed"); - - ret = tdb_chainlock_unmark(tdb, key); - ok(ret == 0, "tdb_chainlock_unmark should succeed"); - - nwritten = write(chainlock_down[1], &c, sizeof(c)); - ok(nwritten == sizeof(c), "write should succeed"); - - nread = read(chainlock_up[0], &c, sizeof(c)); - ok(nread == 0, "read should succeed"); - - nread = read(allrecord_up[0], &c, sizeof(c)); - ok(nread == sizeof(c), "read should succeed"); - - /* - * Someone already holds the allrecord lock, but we're able to get the - * freelist lock. - * - * The freelist lock/mutex is independent from the allrecord lock/mutex. - */ - - ret = tdb_chainlock_nonblock(tdb, key); - ok(ret == -1, "tdb_chainlock_nonblock should not succeed"); - - ret = tdb_lockall_nonblock(tdb); - ok(ret == -1, "tdb_lockall_nonblock should not succeed"); - - ret = tdb_lock_nonblock(tdb, -1, F_WRLCK); - ok(ret == 0, "tdb_lock_nonblock should succeed"); - - ret = tdb_unlock(tdb, -1, F_WRLCK); - ok(ret == 0, "tdb_unlock should succeed"); - - /* - * We have someone else having done the lock for us. Just mark it. - */ - - ret = tdb_lockall_mark(tdb); - ok(ret == 0, "tdb_lockall_mark should succeed"); - - ret = tdb_lock_nonblock(tdb, -1, F_WRLCK); - ok(ret == 0, "tdb_lock_nonblock should succeed"); - - ret = tdb_unlock(tdb, -1, F_WRLCK); - ok(ret == 0, "tdb_unlock should succeed"); - - ret = tdb_store(tdb, key, data, TDB_REPLACE); - ok(ret == 0, "tdb_store should succeed"); - - ret = tdb_lockall_unmark(tdb); - ok(ret == 0, "tdb_lockall_unmark should succeed"); - - nwritten = write(allrecord_down[1], &c, sizeof(c)); - ok(nwritten == sizeof(c), "write should succeed"); - - nread = read(allrecord_up[0], &c, sizeof(c)); - ok(nread == 0, "read should succeed"); - - close(chainlock_up[0]); - close(chainlock_down[1]); - close(allrecord_up[0]); - close(allrecord_down[1]); - diag("%s tests done", name); - return exit_status(); -} - -int main(int argc, char *argv[]) -{ - int ret; - bool mutex_support; - - mutex_support = tdb_runtime_check_for_robust_mutexes(); - - ret = do_tests("marklock-deadlock-fcntl.tdb", - TDB_CLEAR_IF_FIRST | - TDB_INCOMPATIBLE_HASH); - ok(ret == 0, "marklock-deadlock-fcntl.tdb tests should succeed"); - - if (!mutex_support) { - skip(1, "No robust mutex support, " - "skipping marklock-deadlock-mutex.tdb tests"); - return exit_status(); - } - - ret = do_tests("marklock-deadlock-mutex.tdb", - TDB_CLEAR_IF_FIRST | - TDB_MUTEX_LOCKING | - TDB_INCOMPATIBLE_HASH); - ok(ret == 0, "marklock-deadlock-mutex.tdb tests should succeed"); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-bench.c b/ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-bench.c deleted file mode 100644 index b81e597..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-bench.c +++ /dev/null @@ -1,82 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include -#include -#include - -static TDB_DATA key, data; - -static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, - const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); -} - -static double timeval_elapsed2(const struct timeval *tv1, const struct timeval *tv2) -{ - return (tv2->tv_sec - tv1->tv_sec) + - (tv2->tv_usec - tv1->tv_usec)*1.0e-6; -} - -static double timeval_elapsed(const struct timeval *tv) -{ - struct timeval tv2; - gettimeofday(&tv2, NULL); - return timeval_elapsed2(tv, &tv2); -} - -/* The code should barf on TDBs created with rwlocks. */ -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - unsigned int log_count; - struct tdb_logging_context log_ctx = { log_fn, &log_count }; - int ret; - struct timeval start; - double elapsed; - bool runtime_support; - - runtime_support = tdb_runtime_check_for_robust_mutexes(); - - if (!runtime_support) { - skip(1, "No robust mutex support"); - return exit_status(); - } - - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - data.dsize = strlen("world"); - data.dptr = discard_const_p(uint8_t, "world"); - - tdb = tdb_open_ex("mutex-allrecord-bench.tdb", 1000000, - TDB_INCOMPATIBLE_HASH| - TDB_MUTEX_LOCKING| - TDB_CLEAR_IF_FIRST, - O_RDWR|O_CREAT, 0755, &log_ctx, NULL); - ok(tdb, "tdb_open_ex should succeed"); - - gettimeofday(&start, NULL); - ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); - elapsed = timeval_elapsed(&start); - - ok(ret == 0, "tdb_allrecord_lock should succeed"); - - diag("allrecord_lock took %f seconds", elapsed); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-block.c b/ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-block.c deleted file mode 100644 index fcd3b4f..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-block.c +++ /dev/null @@ -1,120 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include -#include -#include - -static TDB_DATA key, data; - -static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, - const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); -} - -static int do_child(int tdb_flags, int to, int from) -{ - struct tdb_context *tdb; - unsigned int log_count; - struct tdb_logging_context log_ctx = { log_fn, &log_count }; - int ret; - char c = 0; - - tdb = tdb_open_ex("mutex-allrecord-block.tdb", 3, tdb_flags, - O_RDWR|O_CREAT, 0755, &log_ctx, NULL); - ok(tdb, "tdb_open_ex should succeed"); - - ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); - ok(ret == 0, "tdb_allrecord_lock should succeed"); - - write(to, &c, sizeof(c)); - - read(from, &c, sizeof(c)); - - ret = tdb_allrecord_unlock(tdb, F_WRLCK, false); - ok(ret == 0, "tdb_allrecord_unlock should succeed"); - - return 0; -} - -/* The code should barf on TDBs created with rwlocks. */ -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - unsigned int log_count; - struct tdb_logging_context log_ctx = { log_fn, &log_count }; - int ret, status; - pid_t child, wait_ret; - int fromchild[2]; - int tochild[2]; - char c; - int tdb_flags; - bool runtime_support; - - runtime_support = tdb_runtime_check_for_robust_mutexes(); - - if (!runtime_support) { - skip(1, "No robust mutex support"); - return exit_status(); - } - - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - data.dsize = strlen("world"); - data.dptr = discard_const_p(uint8_t, "world"); - - pipe(fromchild); - pipe(tochild); - - tdb_flags = TDB_INCOMPATIBLE_HASH| - TDB_MUTEX_LOCKING| - TDB_CLEAR_IF_FIRST; - - child = fork(); - if (child == 0) { - close(fromchild[0]); - close(tochild[1]); - return do_child(tdb_flags, fromchild[1], tochild[0]); - } - close(fromchild[1]); - close(tochild[0]); - - read(fromchild[0], &c, sizeof(c)); - - tdb = tdb_open_ex("mutex-allrecord-block.tdb", 0, - tdb_flags, O_RDWR|O_CREAT, 0755, - &log_ctx, NULL); - ok(tdb, "tdb_open_ex should succeed"); - - ret = tdb_chainlock_nonblock(tdb, key); - ok(ret == -1, "tdb_chainlock_nonblock should not succeed"); - - write(tochild[1], &c, sizeof(c)); - - ret = tdb_chainlock(tdb, key); - ok(ret == 0, "tdb_chainlock should not succeed"); - - ret = tdb_chainunlock(tdb, key); - ok(ret == 0, "tdb_chainunlock should succeed"); - - wait_ret = wait(&status); - ok(wait_ret == child, "child should have exited correctly"); - - diag("done"); - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-trylock.c b/ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-trylock.c deleted file mode 100644 index 4b683db..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-mutex-allrecord-trylock.c +++ /dev/null @@ -1,113 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include -#include -#include - -static TDB_DATA key, data; - -static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, - const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); -} - -static int do_child(int tdb_flags, int to, int from) -{ - struct tdb_context *tdb; - unsigned int log_count; - struct tdb_logging_context log_ctx = { log_fn, &log_count }; - int ret; - char c = 0; - - tdb = tdb_open_ex("mutex-allrecord-trylock.tdb", 3, tdb_flags, - O_RDWR|O_CREAT, 0755, &log_ctx, NULL); - ok(tdb, "tdb_open_ex should succeed"); - - ret = tdb_chainlock(tdb, key); - ok(ret == 0, "tdb_chainlock should succeed"); - - write(to, &c, sizeof(c)); - - read(from, &c, sizeof(c)); - - ret = tdb_chainunlock(tdb, key); - ok(ret == 0, "tdb_chainunlock should succeed"); - - return 0; -} - -/* The code should barf on TDBs created with rwlocks. */ -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - unsigned int log_count; - struct tdb_logging_context log_ctx = { log_fn, &log_count }; - int ret, status; - pid_t child, wait_ret; - int fromchild[2]; - int tochild[2]; - char c; - int tdb_flags; - bool runtime_support; - - runtime_support = tdb_runtime_check_for_robust_mutexes(); - - if (!runtime_support) { - skip(1, "No robust mutex support"); - return exit_status(); - } - - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - data.dsize = strlen("world"); - data.dptr = discard_const_p(uint8_t, "world"); - - pipe(fromchild); - pipe(tochild); - - tdb_flags = TDB_INCOMPATIBLE_HASH| - TDB_MUTEX_LOCKING| - TDB_CLEAR_IF_FIRST; - - child = fork(); - if (child == 0) { - close(fromchild[0]); - close(tochild[1]); - return do_child(tdb_flags, fromchild[1], tochild[0]); - } - close(fromchild[1]); - close(tochild[0]); - - read(fromchild[0], &c, sizeof(c)); - - tdb = tdb_open_ex("mutex-allrecord-trylock.tdb", 0, tdb_flags, - O_RDWR|O_CREAT, 0755, &log_ctx, NULL); - ok(tdb, "tdb_open_ex should succeed"); - - ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_NOWAIT, false); - ok(ret == -1, "tdb_allrecord_lock (nowait) should not succeed"); - - write(tochild[1], &c, sizeof(c)); - - wait_ret = wait(&status); - ok(wait_ret == child, "child should have exited correctly"); - - diag("done"); - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-mutex-die.c b/ldb-2.0.8/lib/tdb/test/run-mutex-die.c deleted file mode 100644 index 4b8eac1..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-mutex-die.c +++ /dev/null @@ -1,269 +0,0 @@ -#include "../common/tdb_private.h" -#include "lock-tracking.h" -static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset); -static ssize_t write_check(int fd, const void *buf, size_t count); -static int ftruncate_check(int fd, off_t length); - -#define pwrite pwrite_check -#define write write_check -#define fcntl fcntl_with_lockcheck -#define ftruncate ftruncate_check - -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include -#include -#include "external-agent.h" -#include "logging.h" - -#undef write -#undef pwrite -#undef fcntl -#undef ftruncate - -static int target, current; -#define TEST_DBNAME "run-mutex-die.tdb" -#define KEY_STRING "helloworld" - -static void maybe_die(int fd) -{ - if (target == 0) { - return; - } - current += 1; - if (current == target) { - _exit(1); - } -} - -static ssize_t pwrite_check(int fd, - const void *buf, size_t count, off_t offset) -{ - ssize_t ret; - - maybe_die(fd); - - ret = pwrite(fd, buf, count, offset); - if (ret != count) - return ret; - - maybe_die(fd); - return ret; -} - -static ssize_t write_check(int fd, const void *buf, size_t count) -{ - ssize_t ret; - - maybe_die(fd); - - ret = write(fd, buf, count); - if (ret != count) - return ret; - - maybe_die(fd); - return ret; -} - -static int ftruncate_check(int fd, off_t length) -{ - int ret; - - maybe_die(fd); - - ret = ftruncate(fd, length); - - maybe_die(fd); - return ret; -} - -static enum agent_return flakey_ops(struct agent *a) -{ - enum agent_return ret; - - /* - * Run in the external agent child - */ - - ret = external_agent_operation(a, OPEN_WITH_CLEAR_IF_FIRST, TEST_DBNAME); - if (ret != SUCCESS) { - fprintf(stderr, "Agent failed to open: %s\n", - agent_return_name(ret)); - return ret; - } - ret = external_agent_operation(a, UNMAP, ""); - if (ret != SUCCESS) { - fprintf(stderr, "Agent failed to unmap: %s\n", - agent_return_name(ret)); - return ret; - } - ret = external_agent_operation(a, STORE, "xyz"); - if (ret != SUCCESS) { - fprintf(stderr, "Agent failed to store: %s\n", - agent_return_name(ret)); - return ret; - } - ret = external_agent_operation(a, STORE, KEY_STRING); - if (ret != SUCCESS) { - fprintf(stderr, "Agent failed store: %s\n", - agent_return_name(ret)); - return ret; - } - ret = external_agent_operation(a, FETCH, KEY_STRING); - if (ret != SUCCESS) { - fprintf(stderr, "Agent failed find key: %s\n", - agent_return_name(ret)); - return ret; - } - ret = external_agent_operation(a, PING, ""); - if (ret != SUCCESS) { - fprintf(stderr, "Agent failed ping: %s\n", - agent_return_name(ret)); - return ret; - } - return ret; -} - -static bool prep_db(void) { - struct tdb_context *tdb; - TDB_DATA key; - TDB_DATA data; - - key.dptr = discard_const_p(uint8_t, KEY_STRING); - key.dsize = strlen((char *)key.dptr); - data.dptr = discard_const_p(uint8_t, "foo"); - data.dsize = strlen((char *)data.dptr); - - unlink(TEST_DBNAME); - - tdb = tdb_open_ex( - TEST_DBNAME, 2, - TDB_INCOMPATIBLE_HASH|TDB_MUTEX_LOCKING|TDB_CLEAR_IF_FIRST, - O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); - if (tdb == NULL) { - return false; - } - - if (tdb_store(tdb, key, data, TDB_INSERT) != 0) { - return false; - } - - tdb_close(tdb); - tdb = NULL; - - forget_locking(); - - return true; -} - -static bool test_db(void) { - struct tdb_context *tdb; - int ret; - - tdb = tdb_open_ex( - TEST_DBNAME, 1024, TDB_INCOMPATIBLE_HASH, - O_RDWR, 0600, &taplogctx, NULL); - - if (tdb == NULL) { - perror("tdb_open_ex failed"); - return false; - } - - ret = tdb_traverse(tdb, NULL, NULL); - if (ret == -1) { - perror("traverse failed"); - goto fail; - } - - tdb_close(tdb); - - forget_locking(); - - return true; - -fail: - tdb_close(tdb); - return false; -} - -static bool test_one(void) -{ - enum agent_return ret; - - ret = AGENT_DIED; - target = 19; - - while (ret != SUCCESS) { - struct agent *agent; - - { - int child_target = target; - bool pret; - target = 0; - pret = prep_db(); - ok1(pret); - target = child_target; - } - - agent = prepare_external_agent(); - - ret = flakey_ops(agent); - - diag("Agent (target=%d) returns %s", - target, agent_return_name(ret)); - - if (ret == SUCCESS) { - ok((target > 19), "At least one AGENT_DIED expected"); - } else { - ok(ret == AGENT_DIED, "AGENT_DIED expected"); - } - - shutdown_agent(agent); - - { - int child_target = target; - bool tret; - target = 0; - tret = test_db(); - ok1(tret); - target = child_target; - } - - target += 1; - } - - return true; -} - -int main(int argc, char *argv[]) -{ - bool ret; - bool runtime_support; - - runtime_support = tdb_runtime_check_for_robust_mutexes(); - - if (!runtime_support) { - skip(1, "No robust mutex support"); - return exit_status(); - } - - plan_tests(12); - unlock_callback = maybe_die; - - ret = test_one(); - ok1(ret); - - diag("done"); - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-mutex-openflags2.c b/ldb-2.0.8/lib/tdb/test/run-mutex-openflags2.c deleted file mode 100644 index 89603e6..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-mutex-openflags2.c +++ /dev/null @@ -1,146 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include -#include -#include -#include - -static TDB_DATA key, data; - -static void log_void(struct tdb_context *tdb, enum tdb_debug_level level, - const char *fmt, ...) -{ -} - -static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, - const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); -} - -static int do_child(int fd) -{ - struct tdb_context *tdb; - unsigned int log_count; - struct tdb_logging_context log_ctx = { log_fn, &log_count }; - struct tdb_logging_context nolog_ctx = { log_void, NULL }; - char c; - - read(fd, &c, 1); - - tdb = tdb_open_ex("mutex-openflags2.tdb", 0, - TDB_DEFAULT, - O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL); - ok((tdb == NULL) && (errno == EINVAL), "TDB_DEFAULT without " - "TDB_MUTEX_LOCKING should fail with EINVAL - %d", errno); - - tdb = tdb_open_ex("mutex-openflags2.tdb", 0, - TDB_CLEAR_IF_FIRST, - O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL); - ok((tdb == NULL) && (errno == EINVAL), "TDB_CLEAR_IF_FIRST without " - "TDB_MUTEX_LOCKING should fail with EINVAL - %d", errno); - - tdb = tdb_open_ex("mutex-openflags2.tdb", 0, - TDB_CLEAR_IF_FIRST | - TDB_MUTEX_LOCKING | - TDB_INTERNAL, - O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL); - ok((tdb == NULL) && (errno == EINVAL), "TDB_MUTEX_LOCKING with " - "TDB_INTERNAL should fail with EINVAL - %d", errno); - - tdb = tdb_open_ex("mutex-openflags2.tdb", 0, - TDB_CLEAR_IF_FIRST | - TDB_MUTEX_LOCKING | - TDB_NOMMAP, - O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL); - ok((tdb == NULL) && (errno == EINVAL), "TDB_MUTEX_LOCKING with " - "TDB_NOMMAP should fail with EINVAL - %d", errno); - - tdb = tdb_open_ex("mutex-openflags2.tdb", 0, - TDB_CLEAR_IF_FIRST | - TDB_MUTEX_LOCKING, - O_RDONLY, 0755, &nolog_ctx, NULL); - ok((tdb != NULL), "TDB_MUTEX_LOCKING with " - "O_RDONLY should work - %d", errno); - tdb_close(tdb); - - tdb = tdb_open_ex("mutex-openflags2.tdb", 0, - TDB_CLEAR_IF_FIRST | - TDB_MUTEX_LOCKING, - O_RDWR|O_CREAT, 0755, &log_ctx, NULL); - ok((tdb != NULL), "TDB_MUTEX_LOCKING with TDB_CLEAR_IF_FIRST" - "TDB_NOMMAP should work - %d", errno); - - return 0; -} - -/* The code should barf on TDBs created with rwlocks. */ -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - unsigned int log_count; - struct tdb_logging_context log_ctx = { log_fn, &log_count }; - struct tdb_logging_context nolog_ctx = { log_void, NULL }; - int ret, status; - pid_t child, wait_ret; - int pipefd[2]; - char c = 0; - bool runtime_support; - - runtime_support = tdb_runtime_check_for_robust_mutexes(); - - ret = pipe(pipefd); - ok1(ret == 0); - - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - data.dsize = strlen("world"); - data.dptr = discard_const_p(uint8_t, "world"); - - if (!runtime_support) { - tdb = tdb_open_ex("mutex-openflags2.tdb", 0, - TDB_CLEAR_IF_FIRST| - TDB_MUTEX_LOCKING, - O_RDWR|O_CREAT, 0755, &nolog_ctx, NULL); - ok((tdb == NULL) && (errno == ENOSYS), "TDB_MUTEX_LOCKING without " - "runtime support should fail with ENOSYS - %d", errno); - - skip(1, "No robust mutex support"); - return exit_status(); - } - - child = fork(); - if (child == 0) { - return do_child(pipefd[0]); - } - - tdb = tdb_open_ex("mutex-openflags2.tdb", 0, - TDB_CLEAR_IF_FIRST| - TDB_MUTEX_LOCKING, - O_RDWR|O_CREAT, 0755, &log_ctx, NULL); - ok((tdb != NULL), "tdb_open_ex with mutexes should succeed"); - - write(pipefd[1], &c, 1); - - wait_ret = wait(&status); - ok((wait_ret == child) && (status == 0), - "child should have exited correctly"); - - diag("done"); - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-mutex-transaction1.c b/ldb-2.0.8/lib/tdb/test/run-mutex-transaction1.c deleted file mode 100644 index 7b9f7b1..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-mutex-transaction1.c +++ /dev/null @@ -1,236 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include -#include -#include - -static TDB_DATA key, data; - -static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, - const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); -} - -static int do_child(int tdb_flags, int to, int from) -{ - struct tdb_context *tdb; - unsigned int log_count; - struct tdb_logging_context log_ctx = { log_fn, &log_count }; - int ret; - char c = 0; - - tdb = tdb_open_ex("mutex-transaction1.tdb", 3, tdb_flags, - O_RDWR|O_CREAT, 0755, &log_ctx, NULL); - ok(tdb, "tdb_open_ex should succeed"); - - ret = tdb_transaction_start(tdb); - ok(ret == 0, "tdb_transaction_start should succeed"); - - ret = tdb_store(tdb, key, data, TDB_INSERT); - ok(ret == 0, "tdb_store(tdb, key, data, TDB_INSERT) should succeed"); - - write(to, &c, sizeof(c)); - read(from, &c, sizeof(c)); - - ret = tdb_transaction_cancel(tdb); - ok(ret == 0, "tdb_transaction_cancel should succeed"); - - write(to, &c, sizeof(c)); - read(from, &c, sizeof(c)); - - ret = tdb_transaction_start(tdb); - ok(ret == 0, "tdb_transaction_start should succeed"); - - ret = tdb_store(tdb, key, data, TDB_INSERT); - ok(ret == 0, "tdb_store(tdb, key, data, TDB_INSERT) should succeed"); - - write(to, &c, sizeof(c)); - read(from, &c, sizeof(c)); - - ret = tdb_transaction_commit(tdb); - ok(ret == 0, "tdb_transaction_commit should succeed"); - - write(to, &c, sizeof(c)); - read(from, &c, sizeof(c)); - - ret = tdb_transaction_start(tdb); - ok(ret == 0, "tdb_transaction_start should succeed"); - - ret = tdb_store(tdb, key, key, TDB_REPLACE); - ok(ret == 0, "tdb_store(tdb, key, data, TDB_REPLACE) should succeed"); - - write(to, &c, sizeof(c)); - read(from, &c, sizeof(c)); - - ret = tdb_transaction_commit(tdb); - ok(ret == 0, "tdb_transaction_commit should succeed"); - - write(to, &c, sizeof(c)); - read(from, &c, sizeof(c)); - - return 0; -} - -/* The code should barf on TDBs created with rwlocks. */ -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - unsigned int log_count; - struct tdb_logging_context log_ctx = { log_fn, &log_count }; - int ret, status; - pid_t child, wait_ret; - int fromchild[2]; - int tochild[2]; - TDB_DATA val; - char c; - int tdb_flags; - bool runtime_support; - - runtime_support = tdb_runtime_check_for_robust_mutexes(); - - if (!runtime_support) { - skip(1, "No robust mutex support"); - return exit_status(); - } - - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - data.dsize = strlen("world"); - data.dptr = discard_const_p(uint8_t, "world"); - - pipe(fromchild); - pipe(tochild); - - tdb_flags = TDB_INCOMPATIBLE_HASH| - TDB_MUTEX_LOCKING| - TDB_CLEAR_IF_FIRST; - - child = fork(); - if (child == 0) { - close(fromchild[0]); - close(tochild[1]); - return do_child(tdb_flags, fromchild[1], tochild[0]); - } - close(fromchild[1]); - close(tochild[0]); - - read(fromchild[0], &c, sizeof(c)); - - tdb = tdb_open_ex("mutex-transaction1.tdb", 0, - tdb_flags, O_RDWR|O_CREAT, 0755, - &log_ctx, NULL); - ok(tdb, "tdb_open_ex should succeed"); - - /* - * The child has the transaction running - */ - ret = tdb_transaction_start_nonblock(tdb); - ok(ret == -1, "tdb_transaction_start_nonblock not succeed"); - - ret = tdb_chainlock_nonblock(tdb, key); - ok(ret == -1, "tdb_chainlock_nonblock should not succeed"); - - /* - * We can still read - */ - ret = tdb_exists(tdb, key); - ok(ret == 0, "tdb_exists(tdb, key) should return 0"); - - val = tdb_fetch(tdb, key); - ok(val.dsize == 0, "tdb_fetch(tdb, key) should return an empty value"); - - write(tochild[1], &c, sizeof(c)); - - /* - * When the child canceled we can start... - */ - ret = tdb_transaction_start(tdb); - ok(ret == 0, "tdb_transaction_start should succeed"); - - read(fromchild[0], &c, sizeof(c)); - write(tochild[1], &c, sizeof(c)); - - ret = tdb_transaction_cancel(tdb); - ok(ret == 0, "tdb_transaction_cancel should succeed"); - - /* - * When we canceled the child can start and store... - */ - read(fromchild[0], &c, sizeof(c)); - - /* - * We still see the old values before the child commits... - */ - ret = tdb_exists(tdb, key); - ok(ret == 0, "tdb_exists(tdb, key) should return 0"); - - val = tdb_fetch(tdb, key); - ok(val.dsize == 0, "tdb_fetch(tdb, key) should return an empty value"); - - write(tochild[1], &c, sizeof(c)); - read(fromchild[0], &c, sizeof(c)); - - /* - * We see the new values after the commit... - */ - ret = tdb_exists(tdb, key); - ok(ret == 1, "tdb_exists(tdb, key) should return 1"); - - val = tdb_fetch(tdb, key); - ok(val.dsize != 0, "tdb_fetch(tdb, key) should return a value"); - ok(val.dsize == data.dsize, "tdb_fetch(tdb, key) should return a value"); - ok(memcmp(val.dptr, data.dptr, data.dsize) == 0, "tdb_fetch(tdb, key) should return a value"); - - write(tochild[1], &c, sizeof(c)); - read(fromchild[0], &c, sizeof(c)); - - /* - * The child started a new transaction and replaces the value, - * but we still see the old values before the child commits... - */ - ret = tdb_exists(tdb, key); - ok(ret == 1, "tdb_exists(tdb, key) should return 1"); - - val = tdb_fetch(tdb, key); - ok(val.dsize != 0, "tdb_fetch(tdb, key) should return a value"); - ok(val.dsize == data.dsize, "tdb_fetch(tdb, key) should return a value"); - ok(memcmp(val.dptr, data.dptr, data.dsize) == 0, "tdb_fetch(tdb, key) should return a value"); - - write(tochild[1], &c, sizeof(c)); - read(fromchild[0], &c, sizeof(c)); - - /* - * We see the new values after the commit... - */ - ret = tdb_exists(tdb, key); - ok(ret == 1, "tdb_exists(tdb, key) should return 1"); - - val = tdb_fetch(tdb, key); - ok(val.dsize != 0, "tdb_fetch(tdb, key) should return a value"); - ok(val.dsize == key.dsize, "tdb_fetch(tdb, key) should return a value"); - ok(memcmp(val.dptr, key.dptr, key.dsize) == 0, "tdb_fetch(tdb, key) should return a value"); - - write(tochild[1], &c, sizeof(c)); - - wait_ret = wait(&status); - ok(wait_ret == child, "child should have exited correctly"); - - diag("done"); - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-mutex-trylock.c b/ldb-2.0.8/lib/tdb/test/run-mutex-trylock.c deleted file mode 100644 index c96b635..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-mutex-trylock.c +++ /dev/null @@ -1,122 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include -#include -#include - -static TDB_DATA key, data; - -static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, - const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); -} - -static int do_child(int tdb_flags, int to, int from) -{ - struct tdb_context *tdb; - unsigned int log_count; - struct tdb_logging_context log_ctx = { log_fn, &log_count }; - int ret; - char c = 0; - - tdb = tdb_open_ex("mutex-trylock.tdb", 0, tdb_flags, - O_RDWR|O_CREAT, 0755, &log_ctx, NULL); - ok(tdb, "tdb_open_ex should succeed"); - - ret = tdb_chainlock(tdb, key); - ok(ret == 0, "tdb_chainlock should succeed"); - - write(to, &c, sizeof(c)); - - read(from, &c, sizeof(c)); - - ret = tdb_chainunlock(tdb, key); - ok(ret == 0, "tdb_chainunlock should succeed"); - - write(to, &c, sizeof(c)); - - return 0; -} - -/* The code should barf on TDBs created with rwlocks. */ -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - unsigned int log_count; - struct tdb_logging_context log_ctx = { log_fn, &log_count }; - int ret, status; - pid_t child, wait_ret; - int fromchild[2]; - int tochild[2]; - char c; - int tdb_flags; - bool runtime_support; - - runtime_support = tdb_runtime_check_for_robust_mutexes(); - - if (!runtime_support) { - skip(1, "No robust mutex support"); - return exit_status(); - } - - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - data.dsize = strlen("world"); - data.dptr = discard_const_p(uint8_t, "world"); - - pipe(fromchild); - pipe(tochild); - - tdb_flags = TDB_INCOMPATIBLE_HASH| - TDB_MUTEX_LOCKING| - TDB_CLEAR_IF_FIRST; - - child = fork(); - if (child == 0) { - close(fromchild[0]); - close(tochild[1]); - return do_child(tdb_flags, fromchild[1], tochild[0]); - } - close(fromchild[1]); - close(tochild[0]); - - read(fromchild[0], &c, sizeof(c)); - - tdb = tdb_open_ex("mutex-trylock.tdb", 0, tdb_flags, - O_RDWR|O_CREAT, 0755, &log_ctx, NULL); - ok(tdb, "tdb_open_ex should succeed"); - - ret = tdb_chainlock_nonblock(tdb, key); - ok(ret == -1, "tdb_chainlock_nonblock should not succeed"); - - write(tochild[1], &c, sizeof(c)); - - read(fromchild[0], &c, sizeof(c)); - - ret = tdb_chainlock_nonblock(tdb, key); - ok(ret == 0, "tdb_chainlock_nonblock should succeed"); - ret = tdb_chainunlock(tdb, key); - ok(ret == 0, "tdb_chainunlock should succeed"); - - wait_ret = wait(&status); - ok(wait_ret == child, "child should have exited correctly"); - - diag("done"); - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-mutex1.c b/ldb-2.0.8/lib/tdb/test/run-mutex1.c deleted file mode 100644 index eb75946..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-mutex1.c +++ /dev/null @@ -1,138 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include -#include -#include - -static TDB_DATA key, data; - -static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, - const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); -} - -static int do_child(int tdb_flags, int to, int from) -{ - struct tdb_context *tdb; - unsigned int log_count; - struct tdb_logging_context log_ctx = { log_fn, &log_count }; - int ret; - char c = 0; - - tdb = tdb_open_ex("mutex1.tdb", 0, tdb_flags, - O_RDWR|O_CREAT, 0755, &log_ctx, NULL); - ok(tdb, "tdb_open_ex should succeed"); - - ret = tdb_chainlock(tdb, key); - ok(ret == 0, "tdb_chainlock should succeed"); - - write(to, &c, sizeof(c)); - read(from, &c, sizeof(c)); - - ret = tdb_chainunlock(tdb, key); - ok(ret == 0, "tdb_chainunlock should succeed"); - - write(to, &c, sizeof(c)); - read(from, &c, sizeof(c)); - - ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); - ok(ret == 0, "tdb_allrecord_lock should succeed"); - - write(to, &c, sizeof(c)); - read(from, &c, sizeof(c)); - - ret = tdb_allrecord_unlock(tdb, F_WRLCK, false); - ok(ret == 0, "tdb_allrecord_lock should succeed"); - - return 0; -} - -/* The code should barf on TDBs created with rwlocks. */ -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - unsigned int log_count; - struct tdb_logging_context log_ctx = { log_fn, &log_count }; - int ret, status; - pid_t child, wait_ret; - int fromchild[2]; - int tochild[2]; - char c; - int tdb_flags; - bool runtime_support; - - runtime_support = tdb_runtime_check_for_robust_mutexes(); - - if (!runtime_support) { - skip(1, "No robust mutex support"); - return exit_status(); - } - - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - data.dsize = strlen("world"); - data.dptr = discard_const_p(uint8_t, "world"); - - pipe(fromchild); - pipe(tochild); - - tdb_flags = TDB_INCOMPATIBLE_HASH| - TDB_MUTEX_LOCKING| - TDB_CLEAR_IF_FIRST; - - child = fork(); - if (child == 0) { - close(fromchild[0]); - close(tochild[1]); - return do_child(tdb_flags, fromchild[1], tochild[0]); - } - close(fromchild[1]); - close(tochild[0]); - - read(fromchild[0], &c, sizeof(c)); - - tdb = tdb_open_ex("mutex1.tdb", 0, tdb_flags, - O_RDWR|O_CREAT, 0755, &log_ctx, NULL); - ok(tdb, "tdb_open_ex should succeed"); - - write(tochild[1], &c, sizeof(c)); - read(fromchild[0], &c, sizeof(c)); - - ret = tdb_allrecord_lock(tdb, F_WRLCK, TDB_LOCK_WAIT, false); - ok(ret == 0, "tdb_allrecord_lock should succeed"); - - ret = tdb_store(tdb, key, data, 0); - ok(ret == 0, "tdb_store should succeed"); - - ret = tdb_allrecord_unlock(tdb, F_WRLCK, false); - ok(ret == 0, "tdb_allrecord_unlock should succeed"); - - write(tochild[1], &c, sizeof(c)); - read(fromchild[0], &c, sizeof(c)); - write(tochild[1], &c, sizeof(c)); - - ret = tdb_delete(tdb, key); - ok(ret == 0, "tdb_delete should succeed"); - - wait_ret = wait(&status); - ok(wait_ret == child, "child should have exited correctly"); - - diag("done"); - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-nested-transactions.c b/ldb-2.0.8/lib/tdb/test/run-nested-transactions.c deleted file mode 100644 index 864adf2..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-nested-transactions.c +++ /dev/null @@ -1,79 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include -#include "logging.h" - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - TDB_DATA key, data; - - plan_tests(27); - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - - tdb = tdb_open_ex("run-nested-transactions.tdb", - 1024, TDB_CLEAR_IF_FIRST|TDB_DISALLOW_NESTING, - O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); - ok1(tdb); - - /* Nesting disallowed. */ - ok1(tdb_transaction_start(tdb) == 0); - data.dptr = discard_const_p(uint8_t, "world"); - data.dsize = strlen("world"); - ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); - data = tdb_fetch(tdb, key); - ok1(data.dsize == strlen("world")); - ok1(memcmp(data.dptr, "world", strlen("world")) == 0); - free(data.dptr); - ok1(tdb_transaction_start(tdb) != 0); - ok1(tdb_error(tdb) == TDB_ERR_NESTING); - - data = tdb_fetch(tdb, key); - ok1(data.dsize == strlen("world")); - ok1(memcmp(data.dptr, "world", strlen("world")) == 0); - free(data.dptr); - ok1(tdb_transaction_commit(tdb) == 0); - data = tdb_fetch(tdb, key); - ok1(data.dsize == strlen("world")); - ok1(memcmp(data.dptr, "world", strlen("world")) == 0); - free(data.dptr); - tdb_close(tdb); - - /* Nesting allowed by default */ - tdb = tdb_open_ex("run-nested-transactions.tdb", - 1024, TDB_DEFAULT, O_RDWR, 0, &taplogctx, NULL); - ok1(tdb); - - ok1(tdb_transaction_start(tdb) == 0); - ok1(tdb_transaction_start(tdb) == 0); - ok1(tdb_delete(tdb, key) == 0); - ok1(tdb_transaction_commit(tdb) == 0); - ok1(!tdb_exists(tdb, key)); - ok1(tdb_transaction_cancel(tdb) == 0); - /* Surprise! Kills inner "committed" transaction. */ - ok1(tdb_exists(tdb, key)); - - ok1(tdb_transaction_start(tdb) == 0); - ok1(tdb_transaction_start(tdb) == 0); - ok1(tdb_delete(tdb, key) == 0); - ok1(tdb_transaction_commit(tdb) == 0); - ok1(!tdb_exists(tdb, key)); - ok1(tdb_transaction_commit(tdb) == 0); - ok1(!tdb_exists(tdb, key)); - tdb_close(tdb); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-nested-traverse.c b/ldb-2.0.8/lib/tdb/test/run-nested-traverse.c deleted file mode 100644 index aeaa085..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-nested-traverse.c +++ /dev/null @@ -1,111 +0,0 @@ -#include "../common/tdb_private.h" -#include "lock-tracking.h" -#define fcntl fcntl_with_lockcheck -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#undef fcntl -#include -#include -#include "external-agent.h" -#include "logging.h" - -static struct agent *agent; - -static bool correct_key(TDB_DATA key) -{ - return key.dsize == strlen("hi") - && memcmp(key.dptr, "hi", key.dsize) == 0; -} - -static bool correct_data(TDB_DATA data) -{ - return data.dsize == strlen("world") - && memcmp(data.dptr, "world", data.dsize) == 0; -} - -static int traverse2(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, - void *p) -{ - ok1(correct_key(key)); - ok1(correct_data(data)); - return 0; -} - -static int traverse1r(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, - void *p) -{ - ok1(correct_key(key)); - ok1(correct_data(data)); - ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) - == SUCCESS); - ok1(external_agent_operation(agent, STORE, tdb_name(tdb)) - == SUCCESS); - ok1(external_agent_operation(agent, TRANSACTION_COMMIT, tdb_name(tdb)) - == WOULD_HAVE_BLOCKED); - tdb_traverse(tdb, traverse2, NULL); - - /* That should *not* release the all-records lock! */ - ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) - == SUCCESS); - ok1(external_agent_operation(agent, STORE, tdb_name(tdb)) - == SUCCESS); - ok1(external_agent_operation(agent, TRANSACTION_COMMIT, tdb_name(tdb)) - == WOULD_HAVE_BLOCKED); - return 0; -} - -static int traverse1w(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, - void *p) -{ - ok1(correct_key(key)); - ok1(correct_data(data)); - ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) - == WOULD_HAVE_BLOCKED); - tdb_traverse(tdb, traverse2, NULL); - - /* That should *not* release the all-records lock! */ - ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) - == WOULD_HAVE_BLOCKED); - return 0; -} - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - TDB_DATA key, data; - - plan_tests(17); - agent = prepare_external_agent(); - - tdb = tdb_open_ex("run-nested-traverse.tdb", 1024, TDB_CLEAR_IF_FIRST, - O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); - ok1(tdb); - - ok1(external_agent_operation(agent, OPEN, tdb_name(tdb)) == SUCCESS); - ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) - == SUCCESS); - ok1(external_agent_operation(agent, TRANSACTION_COMMIT, tdb_name(tdb)) - == SUCCESS); - - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - data.dptr = discard_const_p(uint8_t, "world"); - data.dsize = strlen("world"); - - ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); - tdb_traverse(tdb, traverse1w, NULL); - tdb_traverse_read(tdb, traverse1r, NULL); - tdb_close(tdb); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-no-lock-during-traverse.c b/ldb-2.0.8/lib/tdb/test/run-no-lock-during-traverse.c deleted file mode 100644 index 737a32f..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-no-lock-during-traverse.c +++ /dev/null @@ -1,114 +0,0 @@ -#include "../common/tdb_private.h" -#include "lock-tracking.h" - -#define fcntl fcntl_with_lockcheck - -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include "logging.h" - -#undef fcntl - -#define NUM_ENTRIES 10 - -static bool prepare_entries(struct tdb_context *tdb) -{ - unsigned int i; - TDB_DATA key, data; - - for (i = 0; i < NUM_ENTRIES; i++) { - key.dsize = sizeof(i); - key.dptr = (void *)&i; - data.dsize = strlen("world"); - data.dptr = discard_const_p(uint8_t, "world"); - - if (tdb_store(tdb, key, data, 0) != 0) - return false; - } - return true; -} - -static void delete_entries(struct tdb_context *tdb) -{ - unsigned int i; - TDB_DATA key; - - for (i = 0; i < NUM_ENTRIES; i++) { - key.dsize = sizeof(i); - key.dptr = (void *)&i; - - ok1(tdb_delete(tdb, key) == 0); - } -} - -/* We don't know how many times this will run. */ -static int delete_other(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, - void *private_data) -{ - unsigned int i; - memcpy(&i, key.dptr, 4); - i = (i + 1) % NUM_ENTRIES; - key.dptr = (void *)&i; - if (tdb_delete(tdb, key) != 0) - (*(int *)private_data)++; - return 0; -} - -static int delete_self(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, - void *private_data) -{ - ok1(tdb_delete(tdb, key) == 0); - return 0; -} - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - int errors = 0; - - plan_tests(41); - tdb = tdb_open_ex("run-no-lock-during-traverse.tdb", - 1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, - 0600, &taplogctx, NULL); - - ok1(tdb); - ok1(prepare_entries(tdb)); - ok1(locking_errors == 0); - ok1(tdb_lockall(tdb) == 0); - ok1(locking_errors == 0); - tdb_traverse(tdb, delete_other, &errors); - ok1(errors == 0); - ok1(locking_errors == 0); - ok1(tdb_unlockall(tdb) == 0); - - ok1(prepare_entries(tdb)); - ok1(locking_errors == 0); - ok1(tdb_lockall(tdb) == 0); - ok1(locking_errors == 0); - tdb_traverse(tdb, delete_self, NULL); - ok1(locking_errors == 0); - ok1(tdb_unlockall(tdb) == 0); - - ok1(prepare_entries(tdb)); - ok1(locking_errors == 0); - ok1(tdb_lockall(tdb) == 0); - ok1(locking_errors == 0); - delete_entries(tdb); - ok1(locking_errors == 0); - ok1(tdb_unlockall(tdb) == 0); - - ok1(tdb_close(tdb) == 0); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-oldhash.c b/ldb-2.0.8/lib/tdb/test/run-oldhash.c deleted file mode 100644 index aaee6f6..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-oldhash.c +++ /dev/null @@ -1,50 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include "logging.h" - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - - plan_tests(8); - - /* Old format (with zeroes in the hash magic fields) should - * open with any hash (since we don't know what hash they used). */ - tdb = tdb_open_ex("test/old-nohash-le.tdb", 0, 0, O_RDWR, 0, - &taplogctx, NULL); - ok1(tdb); - ok1(tdb_check(tdb, NULL, NULL) == 0); - tdb_close(tdb); - - tdb = tdb_open_ex("test/old-nohash-be.tdb", 0, 0, O_RDWR, 0, - &taplogctx, NULL); - ok1(tdb); - ok1(tdb_check(tdb, NULL, NULL) == 0); - tdb_close(tdb); - - tdb = tdb_open_ex("test/old-nohash-le.tdb", 0, 0, O_RDWR, 0, - &taplogctx, tdb_jenkins_hash); - ok1(tdb); - ok1(tdb_check(tdb, NULL, NULL) == 0); - tdb_close(tdb); - - tdb = tdb_open_ex("test/old-nohash-be.tdb", 0, 0, O_RDWR, 0, - &taplogctx, tdb_jenkins_hash); - ok1(tdb); - ok1(tdb_check(tdb, NULL, NULL) == 0); - tdb_close(tdb); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-open-during-transaction.c b/ldb-2.0.8/lib/tdb/test/run-open-during-transaction.c deleted file mode 100644 index 9a6c6c1..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-open-during-transaction.c +++ /dev/null @@ -1,183 +0,0 @@ -#include "../common/tdb_private.h" -#include "lock-tracking.h" - -static ssize_t pwrite_check(int fd, const void *buf, size_t count, off_t offset); -static ssize_t write_check(int fd, const void *buf, size_t count); -static int ftruncate_check(int fd, off_t length); - -#define pwrite pwrite_check -#define write write_check -#define fcntl fcntl_with_lockcheck -#define ftruncate ftruncate_check - -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include -#include -#include "external-agent.h" -#include "logging.h" - -static struct agent *agent; -static bool opened; -static int errors = 0; -static bool clear_if_first; -#define TEST_DBNAME "run-open-during-transaction.tdb" - -#undef write -#undef pwrite -#undef fcntl -#undef ftruncate - -static bool is_same(const char *snapshot, const char *latest, off_t len) -{ - unsigned i; - - for (i = 0; i < len; i++) { - if (snapshot[i] != latest[i]) - return false; - } - return true; -} - -static bool compare_file(int fd, const char *snapshot, off_t snapshot_len) -{ - char *contents; - bool same; - - /* over-length read serves as length check. */ - contents = malloc(snapshot_len+1); - same = pread(fd, contents, snapshot_len+1, 0) == snapshot_len - && is_same(snapshot, contents, snapshot_len); - free(contents); - return same; -} - -static void check_file_intact(int fd) -{ - enum agent_return ret; - struct stat st; - char *contents; - - fstat(fd, &st); - contents = malloc(st.st_size); - if (pread(fd, contents, st.st_size, 0) != st.st_size) { - diag("Read fail"); - errors++; - free(contents); - return; - } - - /* Ask agent to open file. */ - ret = external_agent_operation(agent, clear_if_first ? - OPEN_WITH_CLEAR_IF_FIRST : - OPEN, - TEST_DBNAME); - - /* It's OK to open it, but it must not have changed! */ - if (!compare_file(fd, contents, st.st_size)) { - diag("Agent changed file after opening %s", - agent_return_name(ret)); - errors++; - } - - if (ret == SUCCESS) { - ret = external_agent_operation(agent, CLOSE, NULL); - if (ret != SUCCESS) { - diag("Agent failed to close tdb: %s", - agent_return_name(ret)); - errors++; - } - } else if (ret != WOULD_HAVE_BLOCKED) { - diag("Agent opening file gave %s", - agent_return_name(ret)); - errors++; - } - - free(contents); -} - -static void after_unlock(int fd) -{ - if (opened) - check_file_intact(fd); -} - -static ssize_t pwrite_check(int fd, - const void *buf, size_t count, off_t offset) -{ - if (opened) - check_file_intact(fd); - - return pwrite(fd, buf, count, offset); -} - -static ssize_t write_check(int fd, const void *buf, size_t count) -{ - if (opened) - check_file_intact(fd); - - return write(fd, buf, count); -} - -static int ftruncate_check(int fd, off_t length) -{ - if (opened) - check_file_intact(fd); - - return ftruncate(fd, length); - -} - -int main(int argc, char *argv[]) -{ - const int flags[] = { TDB_DEFAULT, - TDB_CLEAR_IF_FIRST, - TDB_NOMMAP, - TDB_CLEAR_IF_FIRST | TDB_NOMMAP }; - int i; - struct tdb_context *tdb; - TDB_DATA key, data; - - plan_tests(20); - agent = prepare_external_agent(); - - unlock_callback = after_unlock; - for (i = 0; i < sizeof(flags)/sizeof(flags[0]); i++) { - clear_if_first = (flags[i] & TDB_CLEAR_IF_FIRST); - diag("Test with %s and %s", - clear_if_first ? "CLEAR" : "DEFAULT", - (flags[i] & TDB_NOMMAP) ? "no mmap" : "mmap"); - unlink(TEST_DBNAME); - tdb = tdb_open_ex(TEST_DBNAME, 1024, flags[i], - O_CREAT|O_TRUNC|O_RDWR, 0600, - &taplogctx, NULL); - ok1(tdb); - - opened = true; - ok1(tdb_transaction_start(tdb) == 0); - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - data.dptr = discard_const_p(uint8_t, "world"); - data.dsize = strlen("world"); - - ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); - ok1(tdb_transaction_commit(tdb) == 0); - ok(!errors, "We had %u open errors", errors); - - opened = false; - tdb_close(tdb); - } - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-rdlock-upgrade.c b/ldb-2.0.8/lib/tdb/test/run-rdlock-upgrade.c deleted file mode 100644 index 042001b..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-rdlock-upgrade.c +++ /dev/null @@ -1,166 +0,0 @@ -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include -#include -#include -#include "logging.h" - -static TDB_DATA key, data; - -static void do_chainlock(const char *name, int tdb_flags, int up, int down) -{ - struct tdb_context *tdb; - int ret; - ssize_t nread, nwritten; - char c = 0; - - tdb = tdb_open_ex(name, 3, tdb_flags, - O_RDWR|O_CREAT, 0755, &taplogctx, NULL); - ok(tdb, "tdb_open_ex should succeed"); - - ret = tdb_chainlock_read(tdb, key); - ok(ret == 0, "tdb_chainlock_read should succeed"); - - nwritten = write(up, &c, sizeof(c)); - ok(nwritten == sizeof(c), "write should succeed"); - - nread = read(down, &c, sizeof(c)); - ok(nread == 0, "read should succeed"); - - exit(0); -} - -static void do_trylock(const char *name, int tdb_flags, int up, int down) -{ - struct tdb_context *tdb; - int ret; - ssize_t nread, nwritten; - char c = 0; - - tdb = tdb_open_ex(name, 3, tdb_flags, - O_RDWR|O_CREAT, 0755, &taplogctx, NULL); - ok(tdb, "tdb_open_ex should succeed"); - - /* - * tdb used to have a bug where with fcntl locks an upgrade - * from a readlock to writelock did not check for the - * underlying fcntl lock. Mutexes don't distinguish between - * readlocks and writelocks, so that bug does not apply here. - */ - - ret = tdb_chainlock_read(tdb, key); - ok(ret == 0, "tdb_chainlock_read should succeed"); - - ret = tdb_chainlock_nonblock(tdb, key); - ok(ret == -1, "tdb_chainlock_nonblock should fail"); - - nwritten = write(up, &c, sizeof(c)); - ok(nwritten == sizeof(c), "write should succeed"); - - nread = read(down, &c, sizeof(c)); - ok(nread == 0, "read should succeed"); - - exit(0); -} - -static int do_tests(const char *name, int tdb_flags) -{ - int ret; - pid_t chainlock_child, store_child; - int chainlock_down[2]; - int chainlock_up[2]; - int store_down[2]; - int store_up[2]; - char c; - ssize_t nread; - - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - data.dsize = strlen("world"); - data.dptr = discard_const_p(uint8_t, "world"); - - ret = pipe(chainlock_down); - ok(ret == 0, "pipe should succeed"); - - ret = pipe(chainlock_up); - ok(ret == 0, "pipe should succeed"); - - ret = pipe(store_down); - ok(ret == 0, "pipe should succeed"); - - ret = pipe(store_up); - ok(ret == 0, "pipe should succeed"); - - chainlock_child = fork(); - ok(chainlock_child != -1, "fork should succeed"); - - if (chainlock_child == 0) { - close(chainlock_up[0]); - close(chainlock_down[1]); - close(store_up[0]); - close(store_up[1]); - close(store_down[0]); - close(store_down[1]); - do_chainlock(name, tdb_flags, - chainlock_up[1], chainlock_down[0]); - exit(0); - } - close(chainlock_up[1]); - close(chainlock_down[0]); - - nread = read(chainlock_up[0], &c, sizeof(c)); - ok(nread == sizeof(c), "read should succeed"); - - /* - * Now we have a process holding a chain read lock. Start - * another process trying to write lock. This should fail. - */ - - store_child = fork(); - ok(store_child != -1, "fork should succeed"); - - if (store_child == 0) { - close(chainlock_up[0]); - close(chainlock_down[1]); - close(store_up[0]); - close(store_down[1]); - do_trylock(name, tdb_flags, - store_up[1], store_down[0]); - exit(0); - } - close(store_up[1]); - close(store_down[0]); - - nread = read(store_up[0], &c, sizeof(c)); - ok(nread == sizeof(c), "read should succeed"); - - close(chainlock_up[0]); - close(chainlock_down[1]); - close(store_up[0]); - close(store_down[1]); - diag("%s tests done", name); - return exit_status(); -} - -int main(int argc, char *argv[]) -{ - int ret; - - ret = do_tests("rdlock-upgrade.tdb", - TDB_CLEAR_IF_FIRST | - TDB_INCOMPATIBLE_HASH); - ok(ret == 0, "rdlock-upgrade.tdb tests should succeed"); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-readonly-check.c b/ldb-2.0.8/lib/tdb/test/run-readonly-check.c deleted file mode 100644 index c5e0f7d..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-readonly-check.c +++ /dev/null @@ -1,53 +0,0 @@ -/* We should be able to tdb_check a O_RDONLY tdb, and we were previously allowed - * to tdb_check() inside a transaction (though that's paranoia!). */ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include "logging.h" - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - TDB_DATA key, data; - - plan_tests(11); - tdb = tdb_open_ex("run-readonly-check.tdb", 1024, - TDB_DEFAULT, - O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); - - ok1(tdb); - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - data.dsize = strlen("world"); - data.dptr = discard_const_p(uint8_t, "world"); - - ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); - ok1(tdb_check(tdb, NULL, NULL) == 0); - - /* We are also allowed to do a check inside a transaction. */ - ok1(tdb_transaction_start(tdb) == 0); - ok1(tdb_check(tdb, NULL, NULL) == 0); - ok1(tdb_close(tdb) == 0); - - tdb = tdb_open_ex("run-readonly-check.tdb", 1024, - TDB_DEFAULT, O_RDONLY, 0, &taplogctx, NULL); - - ok1(tdb); - ok1(tdb_store(tdb, key, data, TDB_MODIFY) == -1); - ok1(tdb_error(tdb) == TDB_ERR_RDONLY); - ok1(tdb_check(tdb, NULL, NULL) == 0); - ok1(tdb_close(tdb) == 0); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-rescue-find_entry.c b/ldb-2.0.8/lib/tdb/test/run-rescue-find_entry.c deleted file mode 100644 index 5d6f8f7..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-rescue-find_entry.c +++ /dev/null @@ -1,51 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/rescue.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include "logging.h" - -#define NUM 20 - -/* Binary searches are deceptively simple: easy to screw up! */ -int main(int argc, char *argv[]) -{ - unsigned int i, j, n; - struct found f[NUM+1]; - struct found_table table; - - /* Set up array for searching. */ - for (i = 0; i < NUM+1; i++) { - f[i].head = i * 3; - } - table.arr = f; - - for (i = 0; i < NUM; i++) { - table.num = i; - for (j = 0; j < (i + 2) * 3; j++) { - n = find_entry(&table, j); - ok1(n <= i); - - /* If we were searching for something too large... */ - if (j > i*3) - ok1(n == i); - else { - /* It must give us something after j */ - ok1(f[n].head >= j); - ok1(n == 0 || f[n-1].head < j); - } - } - } - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-rescue.c b/ldb-2.0.8/lib/tdb/test/run-rescue.c deleted file mode 100644 index e43f53b..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-rescue.c +++ /dev/null @@ -1,127 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/rescue.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include "logging.h" - -struct walk_data { - TDB_DATA key; - TDB_DATA data; - bool fail; - unsigned count; -}; - -static inline bool tdb_deq(TDB_DATA a, TDB_DATA b) -{ - return a.dsize == b.dsize && memcmp(a.dptr, b.dptr, a.dsize) == 0; -} - -static inline TDB_DATA tdb_mkdata(const void *p, size_t len) -{ - TDB_DATA d; - d.dptr = discard_const_p(uint8_t, p); - d.dsize = len; - return d; -} - -static void walk(TDB_DATA key, TDB_DATA data, void *_wd) -{ - struct walk_data *wd = _wd; - - if (!tdb_deq(key, wd->key)) { - wd->fail = true; - } - - if (!tdb_deq(data, wd->data)) { - wd->fail = true; - } - wd->count++; -} - -static void count_records(TDB_DATA key, TDB_DATA data, void *_wd) -{ - struct walk_data *wd = _wd; - - if (!tdb_deq(key, wd->key) || !tdb_deq(data, wd->data)) - diag("%.*s::%.*s", - (int)key.dsize, key.dptr, (int)data.dsize, data.dptr); - wd->count++; -} - -static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) -{ - unsigned int *count = tdb_get_logging_private(tdb); - (*count)++; -} - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - struct walk_data wd; - unsigned int i, size, log_count = 0; - struct tdb_logging_context log_ctx = { log_fn, &log_count }; - - plan_tests(8); - tdb = tdb_open_ex("run-rescue.tdb", 1, TDB_CLEAR_IF_FIRST, - O_CREAT|O_TRUNC|O_RDWR, 0600, &log_ctx, NULL); - - wd.key.dsize = strlen("hi"); - wd.key.dptr = discard_const_p(uint8_t, "hi"); - wd.data.dsize = strlen("world"); - wd.data.dptr = discard_const_p(uint8_t, "world"); - wd.count = 0; - wd.fail = false; - - ok1(tdb_store(tdb, wd.key, wd.data, TDB_INSERT) == 0); - - ok1(tdb_rescue(tdb, walk, &wd) == 0); - ok1(!wd.fail); - ok1(wd.count == 1); - - /* Corrupt the database, walk should either get it or not. */ - size = tdb->map_size; - for (i = sizeof(struct tdb_header); i < size; i++) { - char c; - if (tdb->methods->tdb_read(tdb, i, &c, 1, false) != 0) - fail("Reading offset %i", i); - if (tdb->methods->tdb_write(tdb, i, "X", 1) != 0) - fail("Writing X at offset %i", i); - - wd.count = 0; - if (tdb_rescue(tdb, count_records, &wd) != 0) { - wd.fail = true; - break; - } - /* Could be 0 or 1. */ - if (wd.count > 1) { - wd.fail = true; - break; - } - if (tdb->methods->tdb_write(tdb, i, &c, 1) != 0) - fail("Restoring offset %i", i); - } - ok1(log_count == 0); - ok1(!wd.fail); - tdb_close(tdb); - - /* Now try our known-corrupt db. */ - tdb = tdb_open_ex("test/tdb.corrupt", 1024, 0, O_RDWR, 0, - &taplogctx, NULL); - wd.count = 0; - ok1(tdb_rescue(tdb, count_records, &wd) == 0); - ok1(wd.count == 1627); - tdb_close(tdb); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-rwlock-check.c b/ldb-2.0.8/lib/tdb/test/run-rwlock-check.c deleted file mode 100644 index 2ac9dc3..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-rwlock-check.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include - -static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) -{ - unsigned int *count = tdb_get_logging_private(tdb); - if (strstr(fmt, "spinlocks")) - (*count)++; -} - -/* The code should barf on TDBs created with rwlocks. */ -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - unsigned int log_count; - struct tdb_logging_context log_ctx = { log_fn, &log_count }; - - plan_tests(4); - - /* We should fail to open rwlock-using tdbs of either endian. */ - log_count = 0; - tdb = tdb_open_ex("test/rwlock-le.tdb", 0, 0, O_RDWR, 0, - &log_ctx, NULL); - ok1(!tdb); - ok1(log_count == 1); - - log_count = 0; - tdb = tdb_open_ex("test/rwlock-be.tdb", 0, 0, O_RDWR, 0, - &log_ctx, NULL); - ok1(!tdb); - ok1(log_count == 1); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-summary.c b/ldb-2.0.8/lib/tdb/test/run-summary.c deleted file mode 100644 index 8b9a1a0..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-summary.c +++ /dev/null @@ -1,65 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/summary.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include - -int main(int argc, char *argv[]) -{ - unsigned int i, j; - struct tdb_context *tdb; - int flags[] = { TDB_INTERNAL, TDB_DEFAULT, TDB_NOMMAP, - TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT, - TDB_NOMMAP|TDB_CONVERT }; - TDB_DATA key = { (unsigned char *)&j, sizeof(j) }; - TDB_DATA data = { (unsigned char *)&j, sizeof(j) }; - char *summary; - - plan_tests(sizeof(flags) / sizeof(flags[0]) * 14); - for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) { - tdb = tdb_open("run-summary.tdb", 131, flags[i], - O_RDWR|O_CREAT|O_TRUNC, 0600); - ok1(tdb); - if (!tdb) - continue; - - /* Put some stuff in there. */ - for (j = 0; j < 500; j++) { - /* Make sure padding varies to we get some graphs! */ - data.dsize = j % (sizeof(j) + 1); - if (tdb_store(tdb, key, data, TDB_REPLACE) != 0) - fail("Storing in tdb"); - } - - summary = tdb_summary(tdb); - diag("%s", summary); - ok1(strstr(summary, "Size of file/data: ")); - ok1(strstr(summary, "Number of records: 500\n")); - ok1(strstr(summary, "Smallest/average/largest keys: 4/4/4\n")); - ok1(strstr(summary, "Smallest/average/largest data: 0/2/4\n")); - ok1(strstr(summary, "Smallest/average/largest padding: ")); - ok1(strstr(summary, "Number of dead records: 0\n")); - ok1(strstr(summary, "Number of free records: 1\n")); - ok1(strstr(summary, "Smallest/average/largest free records: ")); - ok1(strstr(summary, "Number of hash chains: 131\n")); - ok1(strstr(summary, "Smallest/average/largest hash chains: ")); - ok1(strstr(summary, "Number of uncoalesced records: 0\n")); - ok1(strstr(summary, "Smallest/average/largest uncoalesced runs: 0/0/0\n")); - ok1(strstr(summary, "Percentage keys/data/padding/free/dead/rechdrs&tailers/hashes: ")); - - free(summary); - tdb_close(tdb); - } - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-transaction-expand.c b/ldb-2.0.8/lib/tdb/test/run-transaction-expand.c deleted file mode 100644 index d36b894..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-transaction-expand.c +++ /dev/null @@ -1,125 +0,0 @@ -#include "../common/tdb_private.h" - -/* Speed up the tests, but do the actual sync tests. */ -static unsigned int sync_counts = 0; -static inline int fake_fsync(int fd) -{ - sync_counts++; - return 0; -} -#define fsync fake_fsync - -#ifdef MS_SYNC -static inline int fake_msync(void *addr, size_t length, int flags) -{ - sync_counts++; - return 0; -} -#define msync fake_msync -#endif - -#ifdef HAVE_FDATASYNC -static inline int fake_fdatasync(int fd) -{ - sync_counts++; - return 0; -} -#define fdatasync fake_fdatasync -#endif - -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include "logging.h" - -static void write_record(struct tdb_context *tdb, size_t extra_len, - TDB_DATA *data) -{ - TDB_DATA key; - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - - data->dsize += extra_len; - tdb_transaction_start(tdb); - tdb_store(tdb, key, *data, TDB_REPLACE); - tdb_transaction_commit(tdb); -} - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - size_t i; - TDB_DATA data; - struct tdb_record rec; - tdb_off_t off; - - /* Do *not* suppress sync for this test; we do it ourselves. */ - unsetenv("TDB_NO_FSYNC"); - - plan_tests(5); - tdb = tdb_open_ex("run-transaction-expand.tdb", - 1024, TDB_CLEAR_IF_FIRST, - O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); - ok1(tdb); - - data.dsize = 0; - data.dptr = calloc(1000, getpagesize()); - if (data.dptr == NULL) { - diag("Unable to allocate memory for data.dptr"); - tdb_close(tdb); - exit(1); - } - - /* Simulate a slowly growing record. */ - for (i = 0; i < 1000; i++) - write_record(tdb, getpagesize(), &data); - - tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &off); - tdb_read(tdb, off, &rec, sizeof(rec), DOCONV()); - diag("TDB size = %zu, recovery = %llu-%llu", - (size_t)tdb->map_size, (unsigned long long)off, (unsigned long long)(off + sizeof(rec) + rec.rec_len)); - - /* We should only be about 5 times larger than largest record. */ - ok1(tdb->map_size < 6 * i * getpagesize()); - tdb_close(tdb); - - tdb = tdb_open_ex("run-transaction-expand.tdb", - 1024, TDB_CLEAR_IF_FIRST, - O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); - ok1(tdb); - - data.dsize = 0; - - /* Simulate a slowly growing record, repacking to keep - * recovery area at end. */ - for (i = 0; i < 1000; i++) { - write_record(tdb, getpagesize(), &data); - if (i % 10 == 0) - tdb_repack(tdb); - } - - tdb_ofs_read(tdb, TDB_RECOVERY_HEAD, &off); - tdb_read(tdb, off, &rec, sizeof(rec), DOCONV()); - diag("TDB size = %zu, recovery = %llu-%llu", - (size_t)tdb->map_size, (unsigned long long)off, (unsigned long long)(off + sizeof(rec) + rec.rec_len)); - - /* We should only be about 4 times larger than largest record. */ - ok1(tdb->map_size < 5 * i * getpagesize()); - - /* We should have synchronized multiple times. */ - ok1(sync_counts); - tdb_close(tdb); - free(data.dptr); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-traverse-chain.c b/ldb-2.0.8/lib/tdb/test/run-traverse-chain.c deleted file mode 100644 index 2a25bec..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-traverse-chain.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include "logging.h" - -static char keystr0[] = "x"; -static TDB_DATA key0 = { .dptr = (uint8_t *)keystr0, - .dsize = sizeof(keystr0) }; -static char valuestr0[] = "y"; -static TDB_DATA value0 = { .dptr = (uint8_t *)valuestr0, - .dsize = sizeof(valuestr0) }; - -static char keystr1[] = "aaa"; -static TDB_DATA key1 = { .dptr = (uint8_t *)keystr1, - .dsize = sizeof(keystr1) }; -static char valuestr1[] = "bbbbb"; -static TDB_DATA value1 = { .dptr = (uint8_t *)valuestr1, - .dsize = sizeof(valuestr1) }; - -static TDB_DATA *keys[] = { &key0, &key1 }; -static TDB_DATA *values[] = { &value0, &value1 }; - -static bool tdb_data_same(TDB_DATA d1, TDB_DATA d2) -{ - if (d1.dsize != d2.dsize) { - return false; - } - return (memcmp(d1.dptr, d2.dptr, d1.dsize) == 0); -} - -struct traverse_chain_state { - size_t idx; - bool ok; -}; - -static int traverse_chain_fn(struct tdb_context *tdb, - TDB_DATA key, - TDB_DATA data, - void *private_data) -{ - struct traverse_chain_state *state = private_data; - - state->ok &= tdb_data_same(key, *keys[state->idx]); - state->ok &= tdb_data_same(data, *values[state->idx]); - state->idx += 1; - - return 0; -} - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - struct traverse_chain_state state = { .ok = true }; - int ret; - - plan_tests(4); - - tdb = tdb_open_ex( - "traverse_chain.tdb", - 1, - TDB_CLEAR_IF_FIRST, - O_RDWR|O_CREAT, - 0600, - &taplogctx, - NULL); - ok1(tdb); - - /* add in reverse order, tdb_store adds to the front of the list */ - ret = tdb_store(tdb, key1, value1, TDB_INSERT); - ok1(ret == 0); - ret = tdb_store(tdb, key0, value0, TDB_INSERT); - ok1(ret == 0); - - ret = tdb_traverse_key_chain(tdb, key0, traverse_chain_fn, &state); - ok1(ret == 2); - ok1(state.ok); - - unlink(tdb_name(tdb)); - - tdb_close(tdb); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-traverse-in-transaction.c b/ldb-2.0.8/lib/tdb/test/run-traverse-in-transaction.c deleted file mode 100644 index d187b9b..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-traverse-in-transaction.c +++ /dev/null @@ -1,90 +0,0 @@ -#include "lock-tracking.h" -#include "../common/tdb_private.h" -#define fcntl fcntl_with_lockcheck -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#undef fcntl_with_lockcheck -#include -#include -#include "external-agent.h" -#include "logging.h" - -static struct agent *agent; - -static bool correct_key(TDB_DATA key) -{ - return key.dsize == strlen("hi") - && memcmp(key.dptr, "hi", key.dsize) == 0; -} - -static bool correct_data(TDB_DATA data) -{ - return data.dsize == strlen("world") - && memcmp(data.dptr, "world", data.dsize) == 0; -} - -static int traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, - void *p) -{ - ok1(correct_key(key)); - ok1(correct_data(data)); - return 0; -} - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - TDB_DATA key, data; - - plan_tests(13); - agent = prepare_external_agent(); - - tdb = tdb_open_ex("run-traverse-in-transaction.tdb", - 1024, TDB_CLEAR_IF_FIRST, O_CREAT|O_TRUNC|O_RDWR, - 0600, &taplogctx, NULL); - ok1(tdb); - - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - data.dptr = discard_const_p(uint8_t, "world"); - data.dsize = strlen("world"); - - ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); - - ok1(external_agent_operation(agent, OPEN, tdb_name(tdb)) == SUCCESS); - - ok1(tdb_transaction_active(tdb) == 0); - ok1(tdb_transaction_start(tdb) == 0); - ok1(tdb_transaction_active(tdb) == 1); - ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) - == WOULD_HAVE_BLOCKED); - tdb_traverse(tdb, traverse, NULL); - - /* That should *not* release the transaction lock! */ - ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) - == WOULD_HAVE_BLOCKED); - tdb_traverse_read(tdb, traverse, NULL); - - /* That should *not* release the transaction lock! */ - ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) - == WOULD_HAVE_BLOCKED); - ok1(tdb_transaction_commit(tdb) == 0); - ok1(tdb_transaction_active(tdb) == 0); - /* Now we should be fine. */ - ok1(external_agent_operation(agent, TRANSACTION_START, tdb_name(tdb)) - == SUCCESS); - - tdb_close(tdb); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-wronghash-fail.c b/ldb-2.0.8/lib/tdb/test/run-wronghash-fail.c deleted file mode 100644 index c44b0f5..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-wronghash-fail.c +++ /dev/null @@ -1,121 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include - -static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) -{ - unsigned int *count = tdb_get_logging_private(tdb); - if (strstr(fmt, "hash")) - (*count)++; -} - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - unsigned int log_count; - TDB_DATA d; - struct tdb_logging_context log_ctx = { log_fn, &log_count }; - - plan_tests(28); - - /* Create with default hash. */ - log_count = 0; - tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, - O_CREAT|O_RDWR|O_TRUNC, 0600, &log_ctx, NULL); - ok1(tdb); - ok1(log_count == 0); - d.dptr = discard_const_p(uint8_t, "Hello"); - d.dsize = 5; - ok1(tdb_store(tdb, d, d, TDB_INSERT) == 0); - tdb_close(tdb); - - /* Fail to open with different hash. */ - tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_RDWR, 0, - &log_ctx, tdb_jenkins_hash); - ok1(!tdb); - ok1(log_count == 1); - - /* Create with different hash. */ - log_count = 0; - tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, - O_CREAT|O_RDWR|O_TRUNC, - 0600, &log_ctx, tdb_jenkins_hash); - ok1(tdb); - ok1(log_count == 0); - tdb_close(tdb); - - /* Endian should be no problem. */ - log_count = 0; - tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDWR, 0, - &log_ctx, tdb_old_hash); - ok1(!tdb); - ok1(log_count == 1); - - log_count = 0; - tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDWR, 0, - &log_ctx, tdb_old_hash); - ok1(!tdb); - ok1(log_count == 1); - - log_count = 0; - /* Fail to open with old default hash. */ - tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_RDWR, 0, - &log_ctx, tdb_old_hash); - ok1(!tdb); - ok1(log_count == 1); - - log_count = 0; - tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDONLY, - 0, &log_ctx, tdb_jenkins_hash); - ok1(tdb); - ok1(log_count == 0); - ok1(tdb_check(tdb, NULL, NULL) == 0); - tdb_close(tdb); - - log_count = 0; - tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDONLY, - 0, &log_ctx, tdb_jenkins_hash); - ok1(tdb); - ok1(log_count == 0); - ok1(tdb_check(tdb, NULL, NULL) == 0); - tdb_close(tdb); - - /* It should open with jenkins hash if we don't specify. */ - log_count = 0; - tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDWR, 0, - &log_ctx, NULL); - ok1(tdb); - ok1(log_count == 0); - ok1(tdb_check(tdb, NULL, NULL) == 0); - tdb_close(tdb); - - log_count = 0; - tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDWR, 0, - &log_ctx, NULL); - ok1(tdb); - ok1(log_count == 0); - ok1(tdb_check(tdb, NULL, NULL) == 0); - tdb_close(tdb); - - log_count = 0; - tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_RDONLY, - 0, &log_ctx, NULL); - ok1(tdb); - ok1(log_count == 0); - ok1(tdb_check(tdb, NULL, NULL) == 0); - tdb_close(tdb); - - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run-zero-append.c b/ldb-2.0.8/lib/tdb/test/run-zero-append.c deleted file mode 100644 index f9eba1b..0000000 --- a/ldb-2.0.8/lib/tdb/test/run-zero-append.c +++ /dev/null @@ -1,41 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include "logging.h" - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - TDB_DATA key, data; - - plan_tests(4); - tdb = tdb_open_ex(NULL, 1024, TDB_INTERNAL, O_CREAT|O_TRUNC|O_RDWR, - 0600, &taplogctx, NULL); - ok1(tdb); - - /* Tickle bug on appending zero length buffer to zero length buffer. */ - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - data.dptr = discard_const_p(uint8_t, "world"); - data.dsize = 0; - - ok1(tdb_append(tdb, key, data) == 0); - ok1(tdb_append(tdb, key, data) == 0); - data = tdb_fetch(tdb, key); - ok1(data.dsize == 0); - tdb_close(tdb); - free(data.dptr); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/run.c b/ldb-2.0.8/lib/tdb/test/run.c deleted file mode 100644 index c744c4d..0000000 --- a/ldb-2.0.8/lib/tdb/test/run.c +++ /dev/null @@ -1,50 +0,0 @@ -#include "../common/tdb_private.h" -#include "../common/io.c" -#include "../common/tdb.c" -#include "../common/lock.c" -#include "../common/freelist.c" -#include "../common/traverse.c" -#include "../common/transaction.c" -#include "../common/error.c" -#include "../common/open.c" -#include "../common/check.c" -#include "../common/hash.c" -#include "../common/mutex.c" -#include "tap-interface.h" -#include -#include "logging.h" - -int main(int argc, char *argv[]) -{ - struct tdb_context *tdb; - TDB_DATA key, data; - - plan_tests(10); - tdb = tdb_open_ex("run.tdb", 1024, TDB_CLEAR_IF_FIRST, - O_CREAT|O_TRUNC|O_RDWR, 0600, &taplogctx, NULL); - - ok1(tdb); - key.dsize = strlen("hi"); - key.dptr = discard_const_p(uint8_t, "hi"); - data.dsize = strlen("world"); - data.dptr = discard_const_p(uint8_t, "world"); - - ok1(tdb_store(tdb, key, data, TDB_MODIFY) < 0); - ok1(tdb_error(tdb) == TDB_ERR_NOEXIST); - ok1(tdb_store(tdb, key, data, TDB_INSERT) == 0); - ok1(tdb_store(tdb, key, data, TDB_INSERT) < 0); - ok1(tdb_error(tdb) == TDB_ERR_EXISTS); - ok1(tdb_store(tdb, key, data, TDB_MODIFY) == 0); - - data = tdb_fetch(tdb, key); - ok1(data.dsize == strlen("world")); - ok1(memcmp(data.dptr, "world", strlen("world")) == 0); - free(data.dptr); - - key.dsize++; - data = tdb_fetch(tdb, key); - ok1(data.dptr == NULL); - tdb_close(tdb); - - return exit_status(); -} diff --git a/ldb-2.0.8/lib/tdb/test/rwlock-be.tdb b/ldb-2.0.8/lib/tdb/test/rwlock-be.tdb deleted file mode 100644 index 45b5f09a1b619b4f79201057dd811781d4151d33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 696 ncmWG>aZ*Uj%t_^9zz%XH8P%GBQt3za#j&dx6&(!$`iB4j>yiaW diff --git a/ldb-2.0.8/lib/tdb/test/rwlock-le.tdb b/ldb-2.0.8/lib/tdb/test/rwlock-le.tdb deleted file mode 100644 index 45b5f09a1b619b4f79201057dd811781d4151d33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 696 ncmWG>aZ*Uj%t_^9zz%XH8P%GBQt3za#j&dx6&(!$`iB4j>yiaW diff --git a/ldb-2.0.8/lib/tdb/test/sample_tdb.tdb b/ldb-2.0.8/lib/tdb/test/sample_tdb.tdb deleted file mode 100644 index a40e50c4f9a1984b7d7ddcf7914e829c53484025..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI1&1(}u7{;f9@w?WG+WHBic+u|H?9PZtC>1<-Q1MX3Dx2L62_~D6jVZ-~1$!4n zpO6@qLq>HcKZ>t*!Jh18?5hncZif{q4*Ib}kMM z9L(km!Db>a#on$Xx1sBN-^>4zr(sze~2LBSk9KoL*`6ahs*5l{pa0YyL&Py`eK zMPO+J#&$N(`vM6!L=HiOmnNnjz&=T(>|Kk3N-d}m?ij}n-Eu5u+LqI=Ym7RYZR)1O zY=={m8;w(ROPaRtRL^J|3p{{k`D3 zWf=sz*n={utHeFU!5CCF!d}f3WaNJr0{P>;*EE0diKX87CB%Z<4Y3>IYw1@C$4^+Q z=Ch;6d^aeTLc+PxZ<~xm7$$|G#7&!W7GIC)Y+T2-?GU{X>)#)Kjano5Fq04c`Bwph z&|rp5EyK~N#vR6)r8%)eGo6F=_Pxai2 zP}gfa@#M<^Tsl{NfNl=xqcmjU_sZywI{F. -*/ -#include - -#ifndef __location__ -#define __TAP_STRING_LINE1__(s) #s -#define __TAP_STRING_LINE2__(s) __TAP_STRING_LINE1__(s) -#define __TAP_STRING_LINE3__ __TAP_STRING_LINE2__(__LINE__) -#define __location__ __FILE__ ":" __TAP_STRING_LINE3__ -#endif - -#define plan_tests(num) -#define fail(...) do { \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - fflush(stderr); \ - exit(1); \ -} while(0) -#define diag(...) do { \ - fprintf(stdout, __VA_ARGS__); \ - fprintf(stdout, "\n"); \ - fflush(stdout); \ -} while(0) -#define pass(...) do { \ - fprintf(stdout, "."); \ - fflush(stdout); \ -} while(0) -#define ok(e, ...) do { \ - if (e) { \ - pass(); \ - } else { \ - fail(__VA_ARGS__); \ - } \ -} while(0) -#define ok1(e) ok((e), "%s:%s", __location__, #e) -#define skip(n, ...) diag(__VA_ARGS__) -#define exit_status() 0 diff --git a/ldb-2.0.8/lib/tdb/test/tap-to-subunit.h b/ldb-2.0.8/lib/tdb/test/tap-to-subunit.h deleted file mode 100644 index a5cf74f..0000000 --- a/ldb-2.0.8/lib/tdb/test/tap-to-subunit.h +++ /dev/null @@ -1,155 +0,0 @@ -#ifndef TAP_TO_SUBUNIT_H -#define TAP_TO_SUBUNIT_H -/* - * tap-style wrapper for subunit. - * - * Copyright (c) 2011 Rusty Russell - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -#include "replace.h" - -/** - * plan_tests - announce the number of tests you plan to run - * @tests: the number of tests - * - * This should be the first call in your test program: it allows tracing - * of failures which mean that not all tests are run. - * - * If you don't know how many tests will actually be run, assume all of them - * and use skip() if you don't actually run some tests. - * - * Example: - * plan_tests(13); - */ -void plan_tests(unsigned int tests); - -/** - * ok1 - Simple conditional test - * @e: the expression which we expect to be true. - * - * This is the simplest kind of test: if the expression is true, the - * test passes. The name of the test which is printed will simply be - * file name, line number, and the expression itself. - * - * Example: - * ok1(somefunc() == 1); - */ -# define ok1(e) ((e) ? \ - _gen_result(1, __func__, __FILE__, __LINE__, "%s", #e) : \ - _gen_result(0, __func__, __FILE__, __LINE__, "%s", #e)) - -/** - * ok - Conditional test with a name - * @e: the expression which we expect to be true. - * @...: the printf-style name of the test. - * - * If the expression is true, the test passes. The name of the test will be - * the filename, line number, and the printf-style string. This can be clearer - * than simply the expression itself. - * - * Example: - * ok1(somefunc() == 1); - * ok(somefunc() == 0, "Second somefunc() should fail"); - */ -# define ok(e, ...) ((e) ? \ - _gen_result(1, __func__, __FILE__, __LINE__, \ - __VA_ARGS__) : \ - _gen_result(0, __func__, __FILE__, __LINE__, \ - __VA_ARGS__)) - -/** - * pass - Note that a test passed - * @...: the printf-style name of the test. - * - * For complicated code paths, it can be easiest to simply call pass() in one - * branch and fail() in another. - * - * Example: - * int x = somefunc(); - * if (x > 0) - * pass("somefunc() returned a valid value"); - * else - * fail("somefunc() returned an invalid value"); - */ -# define pass(...) ok(1, __VA_ARGS__) - -/** - * fail - Note that a test failed - * @...: the printf-style name of the test. - * - * For complicated code paths, it can be easiest to simply call pass() in one - * branch and fail() in another. - */ -# define fail(...) ok(0, __VA_ARGS__) - -unsigned int _gen_result(int, const char *, const char *, unsigned int, - const char *, ...) PRINTF_ATTRIBUTE(5, 6); - -/** - * diag - print a diagnostic message (use instead of printf/fprintf) - * @fmt: the format of the printf-style message - * - * diag ensures that the output will not be considered to be a test - * result by the TAP test harness. It will append '\n' for you. - * - * Example: - * diag("Now running complex tests"); - */ -void diag(const char *fmt, ...) PRINTF_ATTRIBUTE(1, 2); - -/** - * skip - print a diagnostic message (use instead of printf/fprintf) - * @n: number of tests you're skipping. - * @fmt: the format of the reason you're skipping the tests. - * - * Sometimes tests cannot be run because the test system lacks some feature: - * you should explicitly document that you're skipping tests using skip(). - * - * From the Test::More documentation: - * If it's something the user might not be able to do, use SKIP. This - * includes optional modules that aren't installed, running under an OS that - * doesn't have some feature (like fork() or symlinks), or maybe you need an - * Internet connection and one isn't available. - * - * Example: - * #ifdef HAVE_SOME_FEATURE - * ok1(somefunc()); - * #else - * skip(1, "Don't have SOME_FEATURE"); - * #endif - */ -void skip(unsigned int n, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3); - -/** - * exit_status - the value that main should return. - * - * For maximum compatibility your test program should return a particular exit - * code (ie. 0 if all tests were run, and every test which was expected to - * succeed succeeded). - * - * Example: - * exit(exit_status()); - */ -int exit_status(void); -#endif /* CCAN_TAP_H */ diff --git a/ldb-2.0.8/lib/tdb/test/tdb.corrupt b/ldb-2.0.8/lib/tdb/test/tdb.corrupt deleted file mode 100644 index 83d6677454300a5173f80dcbcfec15fc636aed24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 192512 zcmce93z*eY_y4K*6^Rgq(jbhNna=mzPee0QDm67~N@z5tm}n|p2t_WDDCu>HuI{}^ zxi(TNg{X+vC6sb~6RB4&y@>x>d#!!;WxmIpea`dz&-0v$nzhzvueH}+d+oK?F7H^J zcgfIULkjyTT90*K=KUXH|2l6Kc0{dMHKew@7;E%R}z~mW$z|F72 z&y0t^-vs<#sTb&QNBuyHRe?Z%kYW1u^#f}UuNTOJf46aDAduJ$a=lhRP;+~|K$q(S zf&6;{fsSkI1y)Y3ADB3$exS>&Kp=Qy{XqG;dVz!Tf$u4Sz*le83ycH06Q2$QwgHZV ziUNUg1L_5yf}dZ1I>>Sj$T~0(=x`m#IuUs8svr2{9KbZAejxB9@Er;~9}WZ-oE8X_ zbq@rdIwKI+bXUE=;)~$l++07f_ZPr&BK-W4KwvS@mm{9uFqHL?r4JBtyw~5Pz~D77oTDfnrd7U_tkK0p!;nzDL6Ml5?(F zr1$}^5b$)RY)F-oRqz8Af*;~To^!_ZOelU9zDNpRBp425E`=8f$D+vq;u~`S@jDa# zjQASgJnVDD&lw+6mH>rV3@{@20Sgn~+-ILu{49K7fe(cB!qITh0UszmNcbc_iErzf zKRl!Ox#J_sh%Y4;;|tfqhtqt{+9O&keipt^N`G$l>4lTQK(Vlw$xF#TaW0_#l5c;0 zz2fJN4=GFS385HWi1{^&62H{^`*GY1#m~a$F{w~A5sf&^zep$+1b}Ftl~30<=HEq^ zc}FOI&iIHj0c5Edphx@`gI_fKOUupsD}EL}Yp62!FNuhkB!0WEB!1GrOo^7ir1&}G ziwVkp3gq#GAx+^!``r2RZ=WcBCcbdeG=+@ud68g@?PcPdq(5n&Mfo?cRQ#Or3Cce3 zKvbF!IzAlJonKei4;CZ{~3)0BjjHuE~D|3{^h2h#_dx4-0=}*iBR*O;e_xn zn_DXV34DjFTBZ0|_~L{w7*7IOC;yoYCCHyGXhQQ{;`_8!vtJZHcYL0pEbvLOXaa`g zwfraA%+6$+sN!egi%I_yiABT7%-09-0v^wY@omiccij2XYoShJzC;^&NyC`tceGRd-0=y@5}%NY^~dpGE&VMiy;JeC z@KOAdMf@2}MtD8ieweAhX|eq`D1OfPAnXIm5}&TWaBce({^j$<^%Xx0AIC4jcqkkR zI;`&=m?s!0>TmbUq(A9jmaP3`o8sq;k0}d)QY=OXW>&L<+eV=VMoF9 z;irR4|8i!xlde+yobeH5sXu*rV0)=$pV6znRs1Y`GJXk%VMi2on1A435@auVcboI? zu-|_AhvMgq5B-Z=m02oQAN%W#rNj^8&vx)_|G_=4D1Iiskc?m06K5R1L_L@d6i?*8 zNBYB93FGVc-(7N<;^&MHDUVcQKM9<#_#r;vnYm>UWkyI*Kj{x-75@5<c zX!I}Be=hB_X@}zHtUscxGzd}=zL2)QN5D?dKG9y5$hHzwGd_JBHkv5R38Ej{60^Re%1b_*wYa7J@M^kxV$m{V>Ym81dWoz8QDy z`u8UVieEPPkTU6y#bSI>fBl`6-$(JY@X5GJ43yixEewG%+RNT@Q-8arF4OiIS>Xf9 zj1Tn}lu6dwaTV&X`j&tHnhqaq^^AeacwH9yiwS(&p0V_I!cS`zzpU`ZQp-&U@)se- z=d&*r`1ad(uHt9vFP!q9NXT*i#c2L@`N{Gx)vNwg{IbCp0m@?7y%32-_6frJ`IqV& zPkKu6v+(g+Bj#T+k@>oeUM^1d5?pHP@0fqzujNUz!UvRtK$-BdSgb#P|Jh_n$tK0m#0R-!B9ur(oa2``<@FLPP5V6NrinKz ze%a_R0+bE02ps;IB(3iUS@GG3F=Zbqe%atd%8ZZ1 zVtlk7!IGDXuW@~7GVoq4?ziyCfr`U9N5s*82FYJH<-B?-K3i7)TyFRvr7i7~#A1B4 z&$R@;tt-A!{49LDFNHuB(s~YgJzU>mD~$GXN6fU(T@{TlSNyWlpG*fxu^3;_*FGy2 z6tz|SOnkxA{vjBRIO;D9iD$&u=rGHF?tSBT#V;#-K$-muiADH8SikvKQTFy9il2oq zWe8dLPmU+H-Dc`<#0k%6@orZ5WLO3I6Kjm1-rC zVAcydgJ}FwmSf>Nf7f5)T)szfdE26ng?+mgmGmqvgzpJn3AqW_1|)+J-FmTDVLV=# zh!uMAc4655d#KN{8|nuz2X!iZTfz7F%LcxHav{CqK9E!DRNSXy$MXxzih325_UzN6 zywKzlN?{H`3L+-Cc=1qSGSV&>7z{M=qmSX1hU+IO?B*CkIfrm=5jUA_qf;CM376uyVR_kvlcYiF-g9!Vh-ipPSXwor40=cY9i>IH_u z?=n8v_1T41Uf$V1!I1{7F9}GS1*0;>m<(K8RXA{P;gv%NUOb|@5WazeK=IAMdpevA z=<ILI|e$)AWqG6#NE$PZ<3aC9Pk9h9X7?*FyP2&@U~U37Najy+3@kS>1k z_e0@}<8xp4kv={@nX()?KuCW-sL#XS@#m0!?}wUSg0e~aU3;|cT2?NNC6tVW!fnS6 zA3Emh;a3kF91Il>9XUovTwD$`@}O?8Bm532ZZT(q`KKR_G;z-K>Cv_P{2u2Qb%dV< z!uo{Nr;3=6Fh@dOVJH|Z3?*Qy6!!;u_~`&&q}>9(cMTm-gtUt~4(Q#ryi<>&(oSMr zNN$ZhK!||&$yhv;j3TCjKD`TioL>TttRK+95BiVe;CljmkKgr(s9*4*YfNyHERZZ2 zIBe)8BSsA$I1RR|{I8T7>7xI|@wm8Q zzdh;4!z8Q?LJU3LY3u@#Zg;4oM0z;qU@8U1t$DD4Zg()grR9Bl06`D*20nK(#c>!D zBgRqRbhqlSoaR|929rw=$5Z1-Fe=k*P>vBFiSj@lC(0@LJvQp(CWxErAJMls@rx&e za$0*H^RdWf<2)(t)4O-4?!}#oO1k{b zic)Lc0?Nf=o@|8L*bYGRDEQ{V_p|+%^^)@T=v3aZQ(tXv7;7Pv6sT1yT+45lTqw zDK4%AdShU6>h`mI%)WV&erd1XHpV?y_iQT8&qW;7y$r0= zg*KRdG%ARr5AXL=Js~&J&4ce@~+(>_BYT7&Ts>%+6O zAHnes!?)Lm!|s=3Qr5lb{G#4{di@>o5F8oOfZ(Wmo~JuT@xNd#!srkN3jNS{FdEdg zj4xIXxHQN7ScvntSXUd3#$|jF_0O+Vy!~rm#7BNl#u6Mp8To0q{CgP64-nsi9VWgJ zFKr*I_&NJo%xuWQ21=WwXA~dG7e4|qBaSDoXXx9Pzt*OK;%DNME><2CI^}Qqd~Yq( z`Rn@IHTRe0ieFavfHK90e5^|NKv*2l{!l=n`H1bCvte^f` z9W_cj?>6y4X|rJnZvKVrrR63wzq#w!Rrjj#%+9}9(}wiNb=Y6kH}zNj)NR^%qKPle zTTV&@JJh|2{4~wKnl2W;eeEC25no8oKan<<>mLZ~tG}VQYvd=e`GHm&NKB_aouMxtMN4P$y^Zlmjp!BZvKVm!^j$I z{?!c9{B>6Nlv^ON2%mKiNv`kJg_T-8jfpQT6T#Wk@4)>X)ZgSSrvE(Vv!h$8@yrHa zMBWTC>vup{U;F%S;Bdvy#21nNGw!~=hxt5l{C`dR9FhOkt%_eZ_>i*C`VPX{_|Aaw ztvKY%e<^-47e^|G5-~xD?j1VJzi1*T>*()*AQ0DEj0G{T@WnO1yr=jfKH!3kjT9g=;X*1@#T#^r~Iy{F1!IN|d=L0JM6 zVlhB}`>eS5U(?g#QyCbjkk|AVg6l`1qEIYW;KksOG!#k1!v$U_ne-xYNEj4^qLC!= zo4?S+Hz;(LmYb}lzYHl$d_pY7r_P7;_^e{;LHnh}#|vpK{naf+5?qp)4}1BZoZSDl zd!S&6;+F+JL0RI{^+)T&MA+mS_?C>gO7XMoQ>K)~y8pzz3G0 zhF#ZR?e!h~%fi0Xx~IbzmlK;q1L%LgzVM0iu;ORoljpOx{_2z>?8PD!pKU*b)<3yEOqsn^kd{n2>V!uRLVM=O4o{^Z%PJ3g>a@}JW$H}M_#?IG7He(v}}g0dezs%L8n$$Q;@ zF3i7fs^VwiOBcUnV4vW7C|&q?f6Bk592$IQT#0ZrHfzc^y2XtoIVMEJ@Y!# zzs#GoN1N}p@MT8X4<7UT!?w@I9{*2Td}<*zGvXInzXSQtI;HRu&}c!-zc#O$_zv6i(0>&_cYH)y z;)7`;FFwU7epv>a6y3k<8*xfd@iXypA$lYc4#LHB?fyoc_`+c*6BhXTeQNs8R}P(U zsp993k0>L)lvuO?ay@g^UpXAUc>Z^NcXlKqsI&#eyMffhqX6+zJh0RdC=aEKF% z)IP)si$k2^VmxQu-G|OJ@thma>K5;<{sMXVoc~e%(14Pjy~<1h0BxOzg2<}_3?7~d zwq{JejykFk}6g;RX&0(H*GcnHctym7!McpK>p&$7`j-W%2LEQ_!2(Viwl zCRQT!)n&DsW4H$FyZ?@dkr%~$)*MUKCpq>$io@9(-wh33Nc?1sIpeVzk1Bq(=2%@_ zm58$DLgW!xjQ1n}Ddj^1zSX<5nBBr>#Ly0BD2b>SgDOMJ=`@4Mj6O@^`=;&719QMf zl>P8=F9sbS^4zzx*A&Ii!Y5;B<8EkXXJAmQBz$D>J~IZp^VFi4;^(YC$bKVb0?1;q zkEAo&Wv!I{1it1k?o<3Md`1lIpg-Uk=Q}7(o0#~P+}KjP3+|4ODEld}_8k;qpG8Mq zkrtndp~G=F%+B}>B@&LnL7cG9P2AI()702clr3Q6hBLU zMhxwszgPt9i15u{Mf#KTZ%TA>bH&dYA5oV0AVf*|7xrhfp*TXuC_;btY&}o$v+zkn z7kfNMe5}9xlT7_hc`JFY;+GXZ%j>cJIEL2!i@>*{c%9;B;ZrfR7%2z)j3(sWdgy1U z`_ES%D!)hZbH)et+d$b*e?Gk}gn#+=(K8i43!jRi;fj=&1FUP6fMI)etDna^ydECC9!Sb?>3fQYa3wl$)D)Ng%<_I;9&oBq5Y^k|?MdOP<QtG8Q{I_cn|qOnZ^|!Z-XF&jlaueQ4UG z#A19jp5On&!q@PJYQ@jOC*v2aVs-0H=|!Mq8{@NJsj0u`zBy7mGj-QrL{OIc)0*d` zsWB_{&edv$EPN_{am5FRo;3gRFEahh)}J2EC5H=#Q%KnlAH^?cz$Qi7C$0~r7d~H} zR(~>nag9I0i_4sU)tkf*=K`K#&e&SIM)7mjA5kWFM)(OS58pF}(n-y=8VO5(G*Br+ z&)mOY2T(H}l=E-vb-hKMYnC~9k0>L+lvq6fYUcoje_3?R>1sSJeAY^uIX>uu%ln6Z zvrYSq*Ia$2;^(YCI44EQ(mu5Sjn8brL`?hqc+1m@pM@{m_yr2=p-@rSOQR)b{Bq`- zU)`wqIpZVBe(=)7FQpBNw0PdamqYvlNiyL-pDHo^XTzxn9+3k+h+mMh1gOO?e5T(Y zitcs)GUuTIzbbwvK3QW%XM8U4HS}hdy_Oy}_Yar6@Y-0#&s~3lvV^CZC&*gMzo7q| zv;I}BX2HUjZTy10r+NR7*VM%K&5rN2USL__^W8r{i=kTh(7(+2<;2g_cv|=rCCBwI z=-~v!_5G{WrhjR>-`*LDpEEwVVS<#U0=4y>&rE@3%030YyxX+>n1xTpFOK^M=wKJ7 zd`M!BiEl~q)E{!eN0cQ#ZT>}w-}-#I%YiuM$FGk%Ty-c8!arEE#`J&hd3jHm@@uKX|pU|8))kBWc;_ytdCI3BEg%iP~g z8StHU9_oybDEr_8S$*TrE#4xnrqIHdL;Mnfn>;w4Gr4!PoPXh_A8uCm;*1X>Bc$vH zkm8rkK}&xZ9`=ypXW_F5W$a&Yl-XaeJ(}j9Tpten$C}3#KWBVI*$o z1MfL(xZ;3=AG7QSrb7qCuvVnocp`Bo3dJGWi)mg47(k16{p zkj@M5*3L(SeKwdkLh-ZkWgEXhA+wCncE4)s@1hA0UZD6n<0Hy`@c8^3%rmwA;hf)6 zP+z;#V&Tg=eu>60!H4s2a>82Qdxm%AfX^e!egJF7FQ~r_r?k`V#G7~6vOb@LBR2WA zT-B+j|9pE@Bdb2gDgQ#0Yr_l5J0C4UX?lL5dU5P>HJ&CuNMQ*|S@js;{PSsi9xB(r z5zoI+qWGbGI^o0Hw=(}M#S#t%&Ygw5fXWPf71wwp6+aVSs@YyPcM$nbXWn|6e-huW zAD2C%_+^DphE+ipi}3Mz{pL<4zU6Pe+e7g)@xglptUtVC>DJ>g!ug5q`-q>!H!J@X z(ep-~Z@KCZDH~!DJ`fh?dqne}=wDjhH%qGzF!4dklL#f^a0l3>M>E!d(|&sIwWfdR z-0Oe0sPS~yA5k{MB7B^mwe54u4Qt<2{4D>O?fwBy5hDrOuarY$G(GE13*QfioUiP~-9B;TEV0NwJ&Kn)Tx8;_ z?zcLj_?h^)S$8A~55e7}>7V?z=t!Y~r8|0<_o0?8h52!PMNdov_Pc-bo zc*9E-ry)O|`vV#h!aex79DL{!C*B;wRG)!!Zv$LbiJ_{1Kk; z4ix@lk)WmB<0$G#n!^UR@Q!NR>an9o4;eOS$iP~CNZ~XX@6wFBmwLLjfT*hbIbjcta-*!r!gtLRp4elu z&Y<6*rZlVjVCsw$fP}obcdd7XM-QyKp7)McwZrJ>cBJxm&fV(IAPTtW&R&F7QjYu087L$OvsnqiSwpKS`Xz zvIq70@9GI%!`4I0-!HqwMUD@3-K7Y7k#^~M_Sto{xrUSzI9|PhDD+SaV)I_qbw_Y! zI5%)U;JDq;=efrahtIgFJA`#wtI=^;^z$5d8TFS$n>r1?U+sGK1k0v0y}*JeJSf=I z$brKz9y4Ni;mBbFuO2vh>?rH@TYsRHcQvg|*pn3f-0zFlZjid@(doQ`;$9s~z^Kq> z?JJ7x<{}ZeqmJ$T^gfetMKKtt1bP8@&k1cz(m#DVo&BL6%8GiFl=tjWD1|p~Af}se zvT0>7z+I_DYwBUZqs5Pe1>+XPa^QU%Uzb?A_v|A;)NbS|`H-$XXq2n>%fzV-?t|9Z zgUD{tr{=>Kdska}Fk3)tGyLz{Ob3BWaj~$ehBOz^ZqcTGU6C*DyZhLb|FC5;GkM@J zwmfJeVZu1bgYVb>H!>BQm|%>ir9s)oHPz2rgp*o_Yw9^KFl{TQJGN-MsF&^^za!qj zK^y2+)T47R=sDl3bDvJV>aYaXkZEbq(G*M!z`w9MTEKKo~PNdFcSH$BDVW@c8^i?0-XUJuacu zk%$-P^ZCS?zzg-VYjl&rXlL2yXOObm|AJV&Kcw@lWeF2stAGBW)gPPqBAmYnI_GCF z%SZW(-IIu)#5baRyLJ8oJe_u)NSW}lScDIRMH`>p*~GWJ)y$|GPZM9NnPfKkLw@^s z^8YM+2h=}Q@ylv|2$WfW)LM=3aZgQvXy!-vUZ9wL0Q8?Y@s`FY;my^nZh%6>j;; z2=~Yc&Nb)5F{9V_$ps(2rYNT=i^cwo>Wx-jVB)Jd>GInYKNDZ-aXQEbK|;dKt8$N% zE@4xDBfh==ImORif3Ok&Wzrvu#q*ukzcmM%_?q1QKdqk1#3x@>fb}-&p0A|!p#{Iq zE$82?1$(soXg2udeY>a>i|}zh)outLalXrVVtMD^7pUntE~G5 zz|+n0p>>51KJKB55Ow`+m=Ms;2TgoX@{EM=;+JTCpSl0^lGr&P$8&8>y}%gw9rraD zLwf_qih4#Zr;v6pkoj&9q{NLQ^@x*OAk0`%Y8W=YcL4AH5!&OoaRx?r}~?+xqrte6UwNwjT6XM%bC~U+M3nC( zOuparlLOlQ%Zl59r!!?kELsP+55Y>9)DqtrFs4n;Ias^rVd0Z?H{8WBV?RP2AVuD7 zLD2M*Uz~KU7T4lBVBo8>YZrBOBz)X5k?_SS4jVT|;lq9NzM}g@e#}RIPy)&NbG}y& zr}NMl9sT6)fu{bp-d))M?Ni0k2EICXJVaUIQ}@nLSmd|Os;k|1`5#9qeunj$y7nt$bD_XDWTKcOCA5j+Yh8?@$`ed4(e~&*(Sby_Y9b- z_*wen`4>#Y5>ZIzWj_C4MddolZB||8wC793nwF(~Mg?WYM^dr=eEP0jc{p8AyH=Z=pk`{AQJOD%jaw_L6GS@?LL?!Nv(oXPh}D&fo!*CV-4 z`1HL3Z9cf;Bg%gGxX$NRr9bp9`&PUva^1e`gWNE>`cLoz(Cb*t_qE+j|9RQwM~+kD z>5Pvk3wW0Q^yv$L_%{6YVOPb^+9&Y*law;{FUe?F-Ye+GV)4!BFdV<({DF5k% zk0}#CaAGJH`4{dpWaC>tZ}_L_^d~QHP=Tjoo`w7VwD`r0&vp&h?{PZo59?~V?+@f5 zs9cor@jVtDAKGW>Z5=iHH2e#cwUGaW3Kw{N#$kPj#>&w4N7&2Clg;&gNBzl5)p$D3 zKcYebDMI&g?qgO;(PA#Ws0ALPj2{ae9&$#0guEc3ld%=8cil5k%Cwl zp7Tt=Yvlzo(erK?(5||;p5T>)KVxim@|DlMt$5YKRyS2YTo5NAuld|R32_O%Z8=bz zcNQ)=?`&LkMTfCiMBYc(d!OkyFPhYA>)&9@jItj-z7I69hguiVmz6dg{;=X_;gjp0 z-Lt(eDez?xj$6vA&2{hgA7a`(sHM9MDGPv9Ps{bD^8S0}RSKWbpZBhof4A^)qD>OY z*l#A`dH~0{EgG8odu7-D+theE<0Hy`@Hoz$$me@#pF)2ZMy4o!7CyD_gBm?8|6b?r z6Rv&m`B&2`P5ph-;wN#wtkwnKsaBi}DfR?4r0| z)9(HzzIHpl(e|0O^j9Z7qU?u{^0yOtJX88x^qY3y!qT72OW5--BPodA`%Nr-4{W$j z*-Li#tYPPcf%2*Q9ia3l=HJH^UnzbTK8`zU&A&Q3<9i|5bN?r(&&0S|#%1#+{r3UI zuNJ<{DEq08-yvqO#gE7ck3@x{IbA@l>P9r zKbsGWI*zBb&p8imJx%d5@tOUoT>J~ZfkkoWdPqX+`=VE#eM_q!sD-a?%NLY=0P>rM z6QO^*fp2~B{IvKuZmFfex}|^?{WKpY@_j?O?;CVuzue}ZpzMc_&TA_BTKIl>^zgL! zEK5kOe|6%cYmb=cY4M?{zjn=z_`AGWhLrvA(Z0R%7KIP}%bdIewEIq$eWr_F>huEe zriaW6?q|-w)-NBet+%!8Gc(G5@Z|mC^A$eyX>-mQ_FG#0rHfzc9_2`k?^o5#Abiq3 z+dVPNQ~YY-%aF1kK$`EHCMbMDe`DUMR{SjerHfzc9A)S(#rvX0i%tEFes#y2ieD{! znNjwGm!==foVg*bKElFhEu?PqkJk6fMb`XV^LvxO!B@Bb;HtDG7On5xf3+zbR7(FT z^tbjNQPb#`S27z{YU@LtqYUR}Jf2nmBz|&z@A=VVxBU&i%qaWmkMme9;UL(+_v79- z6hBLUS;sHnUpSuc@QR7A^+`j^6hC+S6qNn&as1NZGKEk0mzMptdPECfy7;9|D+-07 zW0%M)RsO@wD_wNWv$4Oymmy_8fK+c%Sz+Sa`SLYQ6+aW7d~@4peaFj2P_-HVjni1^9*_s)aYYv+u$@MT8X4<4UWodE^la{eLDore@@c~(n* zS;sH9OQZc}UVYO(+nw|Lmufs~;j7y|1!X^g6uynW?{v8-AwvS@^P!Ur>K^E+wfnIM|JnHNClx;npJC`O_^>M| z$Dhkhe2YqkY*GAb>90>_ylD?d=$S#u2cAM{nfzpR)NA#m~ZL#4ir`plA{f9qHT_CIij~>0cTQdG{8@&lw+6_5(=q%QCpgrq93j zz0cC>oh^Ju{Njp_;)#)PC}-fCl+^Oc+2OOqqV=8o>A+B$_$EBGN{y$5&xl`~@IgOn z!ngY|Gyc5w($fx8{Ib9&DEsM;_G5$jJV55J+dsa)mT$H28S#q)KJ3TO``fZdO#kxD z^>eNIap0-WkLp?9MN<~ss zxd)+_fT(v*(}!nVKeFr8cwRW;qqO766B61ycu=X5xwpb9C^$$!d^5{TKe77ll3eSn zfHI9Ii^bzfet!FFY93)6vSrfG=cL8Qem*OF{Ep4qpDcWLpEghNbDs||azNP+AMI10 z`c3H%{UFr;J+Jtg^FdB5I5mb!G>5)h@gzLNMsaJG`os^%@<{kzIq?gfn%H#)G zDpH@UuWEF?!iPMY47^v%gPHhJh5$*QXxybf4yt5h6i0SA)tc`+F8ol9r!zi$w+bke z{#Yym$n#(&^3*s z_mosT{W#CwsIkI#I^rw1v4!Gi;p2gVeH2JKD5t*4fA&@ekMMMB~tnehaBQaxGmvvolgEF;wRVJ`z9^Y z#?u`iQ8vUPgdi;X>&ai4{C~4IZc*?#*Y594{jGcR z)*BQ*cYH+I5R3H3eV%JLuP^mi@aE`Yil2cG?>G@55Y~eio*ncDr(G0JEdIg7H@fc) zS1Eq(_~6oR>Yg);Mfw9_QGa{6u0-OS5bKi;UnnN+(*t)A4LRV0ZBB^r&Ah|3&tHGt zoRfbc%4DA`7VD4fbMJGOeOA_Jb-#xGLUJL6vRX%ckwk>^3=_MX`kS@(3@u*DLVtp? zA3pMDEtZ=23R<=6t?b3X=gEczfDg_+9NvBRBGBxB{8^)OP5rfAH2!DBFAIEvvcxCE zV*4chZTieyA6gwXYNq06;0vYdNhH{79buSyPpUiJ2C@>csVF@yYnb86S9Y?yD6%$kgASybJDD{M_*oWj}m0-}As&&|ai{E}vEO zn&M~Z56qGV3jP3hL!9Pc7@}XHzXe0g`Pc2>1D;X*vcZRxrF{yq$UZ?>VK4X6c&6}O z@tJn+WZ{#cIy~b6?@2nWe-UV^K>R9qn)+M)aT~2JHVb@$GT~#f7$41tO-XZoSUB;D zN;RHFo-Z8d`G@O6IPQ{v!EQ#BXFm-t59$8p_Nt4nRQwPh@N^hCqRjY6EP)S&Mg46G znfMA?EuF0R8Tt$9>z^Awh=LO|o@ikz=Q2T*vUQ<5q=kA{f{QTV}4kq-M7vLA5s?hf-DyKPd-=ca;&Mp36+T_(%^$y z8#$39v8Wq9EC&aj`FHv3V{*dhC1I#ptOPvY7vn+*c^`S)Lngk0&U3W>ABO%s z)i5g#UB8|7f8Yfu9;}>i;#+;nnOfap7WxyENq=x%5XB<@!uqRfW8#}IZSCAN`opIw z+0dimNX%{jkl_7oht4Lxbw@qeQt@-ghxuqAR!iPDZh53ILD1Mgz zl=)rg9{~>`W$xvm3$U!y89AHq$^7S;o30(F_#r+g|4Edk`h-;MKKUGP=5mD(c`ocV z@Il4T!Y3!PD?Z52!xlo!zsUy^KN+93J@~ANik~w+rtAlh_|<%4`p<>q*ECc7EPOK1 zbH)c*SYF?|^fmD-!!H-(x3h>z{>><1;uIaN7QYDAw4MatsCDm z=ijK+`8maBf--qMBf%^C(@$d^?w-^6Ls;Gu4y-WsH}Cyj);%yc z{Xu3&?vJEc0v`&C^L=l?!q;=R)}O|}r@tWLK{GQq{c+v>-v5!k$n{~}bCWcGmX-eG z^#k0$qgbpz@-H*HTKKN+t@Wp|@X7d7?2lZ|A216`@!57Oe>VD?zphjE;*O6flY?Qg z7$5Q5>zVi}%HG!M08M=I0Ut#32d(Z~H5a)LzaVR-~dtEO05)rOn8W%P39n)w)j`I&GBfgYa0v`&Cz2Ale;c<+%Wil2!u)u%d^ zOeUQCC(IJqupqwfQ1qhbcS}Aw>7R;UHuzH8wjhf|`r|&;<2YWD>tDr!BCYR;g-^!U zF)XilnSY3n^tXGTX`dzSe(IkqK6ZN$e+sb}ANlLq@0|I%BYSBy$Mi3){yF>##m~U!sdr}}ZRK=+i}^FMmvM)g z_Icl<$8A>p-0=}*!iP-6dz)}65{1S2-sOH%e;fYlo9=v5_1B9hVN>al|Agcq%zg6L zR)56NH(d5^PWS|6!pC9>{h_dkuiwKazU8kyl2H6i{iWVSgyN@=Q~d;ZagGP`4lv`F z=AXZCx#H)pKcXz~!RfRRi|~Q4Vm;cY>{HZ#F50B+r%im2gGNFTn0@e&l*9akE}Jmj zMgDBT8^jOyVxoTcijLZT(-|L8Hl!kWGGD&(OLPC%>brp-tMN4O!K(l={)AcWx!Gre z`>XH%$kgAugS)p;{G9QD@kK&2%KQQMXyi2ClqnP;QyJTSK;V?Af&m13A zX>$MLMz5IubJve2@5u!pQD*&-ScH%3rE01yd|wWmqxf0)QikA)59-f&{i|GN+UKm6 z4YYh~7WxyE{qWIw|EB&XzUuwa6^gil2cGLNeB0JQ)i|9M*S?&tSpD@!ZzUTp#wF`l)pf6L`8< zhM-LPW3k9S`98u(?H;DUH}v*!T6{7;m=!*<&&BIZ``q*CsvPTEV+olSGVxJ3HUhy;Wr4DKmUJx3>yI2uasgV9QzF^{8{q3f=6+d@;Sh*+l$6^saKCfDEuZ6Gw z$X$w`g-_-u-0_9sDM&H@7V~=pGCo^3u32vNXM!^6&%{Uj%|=rdKHNV{E&es#{sA5z zWd9O{Ob5J7pYi$^i$J_e`-hQyzA5()k4@6=T|4WKC=)!Eirgp2D)uWiPh0rzT|Od> z{(`AOws;8c?>d~Xz_ABD2!;MLxP|O9g>U+K_bYzR_=qyQPm+r9aUY(Q)#myzb!DD* z9$?rfzA?cQ+4X)SRKan55s({08v;m9~PSSx#hV@>F)n| z@_ipjPeG{X;9qc;&F{umO`-WN@vU21FfS*3f->P_u?Qc(@3VHc>0e5>9H{Nb%=#=@ z{{s8lpws>+5ev$E$T;@b(mu~jJfX$&s6XJDxo0NIWS=aRfENZ?g+JTG=lyd2RToyK zJO6`6Zpjdw@j<-|EVqJR{sJ0LiSL||YyOvm{)lpId?>5n*Y6;uKjc~6Z*{u!KY06- z4Lu6ag~VLq7s#S>esKFQW_&%m-n<;^vyd{`CyON%h{EFhoA{aOU#f3Bsks_Y!@uAa z1{x{wpK#wab1TAETzG$!&*uSh{*5RM^-}!Y{R>ex#A19DU$-c?^!LC|=Q-8azn^vj#WrYtY`{5)1xptI^Z^9P`mnnV*zSR4DF#i%k$MYk&kSy%w zpw=e7&ND8`F@J`X2_K6^{*%ue$K{#$rWRlIN;-V0_%i`*W8tmSjN?yOAL1UZe@(4E z@~!{6C&&FQQWp4Nt0crCd>|~&znLRVeDE&(fHe3*GXH}83&L*w3*h9D@*$OHnekak zo3PdA3v9+^Yi7gFeXDDtzYpuI+E(zMI4T0pk~rC(2$j@qKw;Gi(3gw7xTC zwomB03}OjYYWEv?vV z6hFl0I{%O|;bXCQ{*iy_mv7>O_xsY>XDIc4AJkdG!>SHm9A^pV&$gQQ-l*3wr~X+) zneee#0v`%1?DKvL-<$8gq{h>*PuR4}`3DaHI@O0j{u&5& zZ%Y3;_1^Z6Dt@N^q$Bp=rYhKl%P1$HOojX>_ve%Nc7<;{Lh;K2pP(%8NwG+OydG_` z;+Ltz^!GX~eCqrbo-=jIzd*!F_!f*d?X%?0d&M2GXk%qcoC=k3sm{>{r9S`&Hej*9gfSXK9VR4fKn_12*RTN7R<5m z-T9bSuVLXMLkD~j2w+_DXE6Wxd~D?JrhTqHwj!tf15svtBo^bN`QG9=6JM*6J|Cvh zAC_#hSJ|VJ2%7$119}0{58#&tapRJDi zaggF?=nvYDFd@8+nQ+;^V?#fRmnQRlLy2$1`Nuq^__^aF%7l-_Vtizui?`8ym+M25 z+y8f&;%DGP6H5&gB-32hcc}6s{Vn)E(>~W-G-QS1=Z+8de?Zv~i|v#0yK5(!_Sxix z{+}s+7CxCM2K#iz$N9R&51R3Hx5$c3ieFavfU+Mx%12J*dd!smwysFmzXx7}Awt;S zEfjRoALN&0{(76~KU*I$OuLWnj*ln{d{QjdALVx^SDX5)xbCx))OeculZ9T;6E7M| zxcN_y>+81FnEGqp=d}%rpF2KSA7t646pQe2y<1c6mxubp^?gInkw+_j20kyU>=P8| zu)Zgw(2$tc_wDzR{^a_8(#{8tSNxpu5oKwfLMn1EAghQcCf{i4Z|a)T!HS=WFDciD zI9$b!yX6Pt94~#p!}Krn+8oeH@pHxp>jP3IfGidP1YvP~*z~-Kuho6WELZ$Ye5v~@ zP-p@xpp*ZE^-}OFd)Bnid23GB@~zq7OPLjkMfmvs%KY2S^>6u`=iZzSpUh9d`3gJ_ z=#qbdDnIW3+0^P!^hV3~wDU%Hd_aX#9 zh5T87``gI%z4g`tt)9;vA5oV0gjj@+`;~OK*wkOeBh8LVr$5=~&x8Jv!Gwcd^O{Xe;20l;r$3*`E7jPZo7qn;Mmw%pVpRGTbt<`I|>yIcC zJ{F7g$Ndr--D2XaIO+1A(%^$DjXaUD(MrszegcjjX@A?a2l+Fpzvh)^=Tu(~`-jxE z8WxN7NBqWjG1rIc#V^iJgU^$Nh!CH_{?8>pkGCvo{p%1i{bzIUo&Qt(-1SG4$$zp~ zq(835+%(hFU-c(PY5nU=`%DcKtn^So=wP3Cip=ZnA`{=byWh#}{6SEb_=H%DkMy_p zY7^ho2X^dM<7wi9E5eeHU zTE5lPUyRR>pjg!lI^7S)T@0^B@0kAOjrBE+a=}NGh5n>iq(2ZA$FswGG#_OAvSrd( zZ9bUzw2MB$kjwc4wlm^>zx|Fg^*8$7rCW2sN0bR)JSoH?d>}01Td>#kp9S-pYW1`x zKG`T03fUkZ=Hfpg%gp-Q&Gn{oeHi_JRhqqIW1mQw^+#e6KJFJg@_kc(1$#c!#?!*b z`CX{53&WddF8&juU>eWqgH8MV?#Px}J~<0~f-?CR7K`!G{%`Rb6JPaH2lP?)V&a1q z!E6X{{lO`}1hXVY>qFUL=K9dN^Ej=Z)*T;FHpC))+|M}w0n>jri9gpP9X{EJ3lgb` zkYoLz?9W$ovo-&|`S&%7pF2LBe=6-P#3Fp$k1Y6(slTZ$nx)-8B-zlx5yQiZPWfGY z@k7k_m2a5(+f@+E>HIb#D3g7%ScDIRMgOwa>aWpc;E}JY@igsIzORP*gMu=b`3I>3 z!Z+V~AK|{9J@XYmcl|;936vQhiN*S(^>6z_rhRTHsQ;znXX1k=ILOcwNjRZ)(H}5IJ`!dL@5h4O zO#9q(=P3^kqQ?(D2#CKErYLXCpr~ z@wGl@ytdxD^QqUJy--Pugcz_-H+nFPASYH=U zU8^zi(R|r;^%IkMA;CF z@bP{#_?R{S%6e%1R89S*`qMhUzXE|F*N1fAcq!#S&w6KXZupQg`4{8;74AVcxHu9>JOgf6~oT>$bSYuG}pg^Zs%y@Y3eVv5rO8I zZs%iQpL~D1`z{mTyca&#>h<065oKYY*s~MGB7D3b+jObvUkb)9)an^5d@?@>&7R>h zyu`;)4=#8Yrli3x?hB zVU`5f+fCn_`@hyhCgmx9S?N#aUxF+a;p2Mt1izOh^Ai)=-FTzoXW^3*86J;|!9z7J z@fn=Q2z+;ZW9qN<3v*vq{IbI*!wwdU@zH)W7*qPgGqMSTzy4YAv+(KrqnN|`4qfIT z_buu*s_GFwSs!wCpPF3OccLtp2Y6PQuUC2S+@RpM{R(sbO_p&T+b* z173jN$J_S0xxUXkV1bs;%1VFg*qp>-{n7mEGT*{?&?qe)wD8ILIyi`edSf^HTz6 zy>?H9;+GY^RQ)H5#rVjdE&D{_6ZKh-f0?fTpeG9vAwQ7>51P6DV3x@G>wbJ5Am`sT zTOK(j2Yf_X&Oad)!2?;v{A+Q)8J}%<_w1F5pQ%5%B1P*1G;)fDT=Jig<$~f1Tpvyg znd?L6&8MtU{M_|Nlnt>MAmt+;nP=hq{a;$WjfF2&=miVB)BR02Pvd@FO|ATH$%@eS zT<{TP#z$f?KFYt$wDN-+PHghH;%DKL{sqH4r}IBJALH}Q?Q=~1t=n^Cj{A3{%=kzw z#>e~VzH0vAoY;9t(IAD-y5Gp_JJc`5p`%jf^AGz&L-QZB&w#Z)G@jB%%a@~ly4`Oi z$^xGhOW+Iheah~ioA{c1`MtK@n)*v!qz}QFo74QmQ!K)_Hb(rU|7?B4%-hs>y3aqN zO!{N7NPpZI0W)@t~nUc+-OLVgG`lQ+*Hgt6=+_f1DY=Tz=l*|Kx;EP$v7-^MfcX z&WDlTn)s^w?|w<~Gw?yyTIw$XX;r8EHQeu~__~XA{?P5t^G7Ov+1MviCi{d-Z73G$ zkMFD1EHmx1`j*}Wil2oqAZ7M1Bo^bN^>)F3 z&GoN(zX`Xd#g|&&gJHPK>oETSANTK>yw;q5tB-zXl;Y>EKcYF>tJK3DuK{qg<*&c___ z!Mx}GXA|d{`fGjXb?X#AcYH+I4we20kV zXRaZBa{tg{(Vf5MfR8BC^kb<=eKKD#bEs*b%UiX$T=6sYmwIRqHd=6D(apbb{nE_V zrvEHCV0l9EbJritY+1jA`&$%?0P=h6+b^^5b-p&;{W0i4AQu`}d=Ou=e`!=`;_J5S zq;|RBBg&*e6Ce4Pr#@5o&_0{oc~ZLiR?m~`I~3A5_1A!1C_H~F?6Yi)X`jDrd|SIO zDLQXj}F_*D&8_;5}%dFeLIUz_%sx~K(DB0~c^2m6F7V!r>^(#j9cDs8tS zC;bV^JON282FU9>zeg+cpG|JRI^FrEmrC@Aa2^{x;8yp<%ADw z3V7PESd5SOO`dM)?}g0^6hBLUv_8O1b9lbdF+UF%b_Krq?XC6Utw}8vKWF=dlSQPA z`b&w$_-K8Yd5^h1>`XrLf#PTFZ#mElCg9GpOaC6|(JAl${qZi1r(7RidExbI6+gu1 zw7(_FY@Q^QfER}HT`~Xi?@;idE!Ghn!g`_`; zZ&b5mwfXL>KcXz~!LCh6CGerF`$2h9hGulZfG zH!6Pa_=qy$gB$^hMe~pE-!>X&;ajjO?fukLpumJOKR-e#$iGxt{n?v8vtLfoa_^#DDLO6_6c+Tt?P1ePW2%~nH&s@#rSCc&A-sZ zH}!|0Ru5+23v&GnTzd=0LT>K|Kzn_%m&yM#@!i+%-amPoL5noCy#>e@r8Rq=k z^4$LO6h9MRs=qfs)SbD1f%uc}hqv%d{mp8=u}blC$48V&fBO63LGH)-(+U$`#gY+U zD1Ju#5=tfFqHvtx6kiA7Iu?!R;ww!5a>%fs?p6E{pHut-W)Dv%(y|N-d?=da{a=Xf z1zd`F?^D|6!oJg%D1IisIOlg^{<-7h`+wVyvc_}jL0UbL$xqf3Nx?I>7ebBe`}SFi zAI4`3C;s;zY4P#?4{SXabvfS*!ETZJPpswl)nt73VuMcuil4Loh%&iPmP$-Nd@fnU zXO#!jd`JBuzAam-($z0P+9hQOZuxnrYk)&6!LP%A%=q)1-y*Y3d@$!T-&qo6!e^xC zK~}+U?@~*D?=Lx2@iXm(>$4*8yeRatcc|}y$tvFqnS3qrllt4yrk6G!ob^YPh5M9J zvHm!|-t@AC@6V&P`Ya0{ogZa~kL`2JY7^gOyZ-UM8qcioQC2-A72{)jX>_-VZ%f1V z8a``%p!0_mrHto0B$na1Phl^KCrx}0?K$FT6Q7fP66Mdy%uQ#Qn+^_}}Q?|rIXARllw zgYO~m{o%)dE>-*td;(k~279?k+-qA9DDD9NzTbVY$AaJ0&!463SM{H#;N1TCl~0-L zQ^9eU4o$-!QW07DH>{72Qhb;nA$`jI*}CC7zg7I)$CoIJ@s-D-G``%=V1A{AuiIOj z6+eA^f^gM=@j*Wl&*^<{IHl))%KiQ%eiGlF)BpFQ;^&T!C=)&wi}8`YZmdxF#QNm5 z)#@ose6l~a9H@-ve=?eo>&48I%=v%P>W{Q~CTDy^*++dKtME6QPf+-9{%^T(#xOOW z7Ct`zhkZ~Go>I$vmBjm_{Qg8!>;0uYr!La=yUzHSG67_!u=x}V-=v?ldJzks zJYU6wXxI8vzJIul&*P zDAwv1Eqt6Gp@DL$Pl5M8iC@slFW>s^lv8rShwp#N{JGGd?7z+ZPG|m8;S>I4QNP}b zpJksi(c)U40>zwgwjk#F#s!wWeEaCX6hCV`Q~A(f2>O4yXcg)y$X+%+ZQ9F)&2Oqv z{IakYL7C5qi
    2. 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%0D;B{e9TTu0g|3*k?HPjWZaHd%ZIR!~gXDzVJoq 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 OTV%~k$Hy(v-~S&FX3gOM diff --git a/ldb-2.0.8/lib/tdb/test/test_tdbbackup.sh b/ldb-2.0.8/lib/tdb/test/test_tdbbackup.sh deleted file mode 100755 index cf87921..0000000 --- a/ldb-2.0.8/lib/tdb/test/test_tdbbackup.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/sh -# Blackbox test for tdbbackup of given ldb or tdb database -# Copyright (C) 2018 Andrew Bartlett - -if [ $# -lt 1 ]; then - echo "Usage: $0 LDBFILE" - exit 1; -fi - -LDBFILE=$1 - -timestamp() { - date -u +'time: %Y-%m-%d %H:%M:%S.%6NZ' | sed 's/\..*NZ$/.000000Z/' -} - -subunit_fail_test () { - timestamp - printf 'failure: %s [\n' "$1" - cat - - echo "]" -} - -testit () { - name="$1" - shift - cmdline="$@" - timestamp - printf 'test: %s\n' "$1" - output=`$cmdline 2>&1` - status=$? - if [ x$status = x0 ]; then - timestamp - printf 'success: %s\n' "$name" - else - echo "$output" | subunit_fail_test "$name" - fi - return $status -} - -$BINDIR/tdbdump $LDBFILE | sort > orig_dump - -testit "normal tdbbackup on tdb file" $BINDIR/tdbbackup $LDBFILE -s .bak -$BINDIR/tdbdump $LDBFILE.bak | sort > bak_dump -testit "cmp between tdbdumps of original and backup" cmp orig_dump bak_dump -rm $LDBFILE.bak -rm bak_dump - -testit "readonly tdbbackup on tdb file" $BINDIR/tdbbackup $LDBFILE -s .bak -r -$BINDIR/tdbdump $LDBFILE.bak | sort > bak_dump -testit "cmp between tdbdumps of original and back dbs" cmp orig_dump bak_dump -rm $LDBFILE.bak -rm bak_dump - -rm orig_dump diff --git a/ldb-2.0.8/lib/tdb/tools/tdbbackup.c b/ldb-2.0.8/lib/tdb/tools/tdbbackup.c deleted file mode 100644 index 1125987..0000000 --- a/ldb-2.0.8/lib/tdb/tools/tdbbackup.c +++ /dev/null @@ -1,370 +0,0 @@ -/* - Unix SMB/CIFS implementation. - low level tdb backup and restore utility - Copyright (C) Andrew Tridgell 2002 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/* - - This program is meant for backup/restore of tdb databases. Typical usage would be: - tdbbackup *.tdb - when Samba shuts down cleanly, which will make a backup of all the local databases - to *.bak files. Then on Samba startup you would use: - tdbbackup -v *.tdb - and this will check the databases for corruption and if corruption is detected then - the backup will be restored. - - You may also like to do a backup on a regular basis while Samba is - running, perhaps using cron. - - The reason this program is needed is to cope with power failures - while Samba is running. A power failure could lead to database - corruption and Samba will then not start correctly. - - Note that many of the databases in Samba are transient and thus - don't need to be backed up, so you can optimise the above a little - by only running the backup on the critical databases. - - */ - -#include "replace.h" -#include "system/locale.h" -#include "system/time.h" -#include "system/filesys.h" -#include "system/wait.h" -#include "tdb.h" - -#ifdef HAVE_GETOPT_H -#include -#endif - -static int failed; - -static struct tdb_logging_context log_ctx; - -#ifdef PRINTF_ATTRIBUTE -static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); -#endif -static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - vfprintf(stdout, format, ap); - va_end(ap); - fflush(stdout); -} - -static char *add_suffix(const char *name, const char *suffix) -{ - char *ret; - int len = strlen(name) + strlen(suffix) + 1; - ret = (char *)malloc(len); - if (!ret) { - fprintf(stderr,"Out of memory!\n"); - exit(1); - } - snprintf(ret, len, "%s%s", name, suffix); - return ret; -} - -static int copy_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - TDB_CONTEXT *tdb_new = (TDB_CONTEXT *)state; - - if (tdb_store(tdb_new, key, dbuf, TDB_INSERT) != 0) { - fprintf(stderr,"Failed to insert into %s\n", tdb_name(tdb_new)); - failed = 1; - return 1; - } - return 0; -} - - -static int test_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - return 0; -} - -/* - carefully backup a tdb, validating the contents and - only doing the backup if its OK - this function is also used for restore -*/ -static int backup_tdb(const char *old_name, const char *new_name, - int hash_size, int nolock, bool readonly) -{ - TDB_CONTEXT *tdb; - TDB_CONTEXT *tdb_new; - char *tmp_name; - struct stat st; - int count1, count2; - - tmp_name = add_suffix(new_name, ".tmp"); - - /* stat the old tdb to find its permissions */ - if (stat(old_name, &st) != 0) { - perror(old_name); - free(tmp_name); - return 1; - } - - /* open the old tdb */ - tdb = tdb_open_ex(old_name, 0, - TDB_DEFAULT | (nolock ? TDB_NOLOCK : 0), - O_RDWR, 0, &log_ctx, NULL); - if (!tdb) { - printf("Failed to open %s\n", old_name); - free(tmp_name); - return 1; - } - - /* create the new tdb */ - unlink(tmp_name); - tdb_new = tdb_open_ex(tmp_name, - hash_size ? hash_size : tdb_hash_size(tdb), - TDB_DEFAULT, - O_RDWR|O_CREAT|O_EXCL, st.st_mode & 0777, - &log_ctx, NULL); - if (!tdb_new) { - perror(tmp_name); - free(tmp_name); - return 1; - } - - if (readonly) { - if (tdb_lockall_read(tdb) != 0) { - printf("Failed to obtain read only lock on old tdb\n"); - tdb_close(tdb); - tdb_close(tdb_new); - unlink(tmp_name); - free(tmp_name); - return 1; - } - } else if (tdb_transaction_start(tdb) != 0) { - printf("Failed to start transaction on db\n"); - tdb_close(tdb); - tdb_close(tdb_new); - unlink(tmp_name); - free(tmp_name); - return 1; - } - - /* lock the backup tdb so that nobody else can change it */ - if (tdb_lockall(tdb_new) != 0) { - printf("Failed to lock backup tdb\n"); - tdb_close(tdb); - tdb_close(tdb_new); - unlink(tmp_name); - free(tmp_name); - return 1; - } - - failed = 0; - - /* traverse and copy */ - if (readonly) { - count1 = tdb_traverse_read(tdb, - copy_fn, - (void *)tdb_new); - } else { - count1 = tdb_traverse(tdb, - copy_fn, - (void *)tdb_new); - } - if (count1 < 0 || failed) { - fprintf(stderr,"failed to copy %s\n", old_name); - tdb_close(tdb); - tdb_close(tdb_new); - unlink(tmp_name); - free(tmp_name); - return 1; - } - - /* close the old tdb */ - tdb_close(tdb); - - /* copy done, unlock the backup tdb */ - tdb_unlockall(tdb_new); - -#ifdef HAVE_FDATASYNC - if (fdatasync(tdb_fd(tdb_new)) != 0) { -#else - if (fsync(tdb_fd(tdb_new)) != 0) { -#endif - /* not fatal */ - fprintf(stderr, "failed to fsync backup file\n"); - } - - /* close the new tdb and re-open read-only */ - tdb_close(tdb_new); - tdb_new = tdb_open_ex(tmp_name, - 0, - TDB_DEFAULT, - O_RDONLY, 0, - &log_ctx, NULL); - if (!tdb_new) { - fprintf(stderr,"failed to reopen %s\n", tmp_name); - unlink(tmp_name); - perror(tmp_name); - free(tmp_name); - return 1; - } - - /* traverse the new tdb to confirm */ - count2 = tdb_traverse(tdb_new, test_fn, NULL); - if (count2 != count1) { - fprintf(stderr,"failed to copy %s\n", old_name); - tdb_close(tdb_new); - unlink(tmp_name); - free(tmp_name); - return 1; - } - - /* close the new tdb and rename it to .bak */ - tdb_close(tdb_new); - if (rename(tmp_name, new_name) != 0) { - perror(new_name); - free(tmp_name); - return 1; - } - - free(tmp_name); - - return 0; -} - -/* - verify a tdb and if it is corrupt then restore from *.bak -*/ -static int verify_tdb(const char *fname, const char *bak_name) -{ - TDB_CONTEXT *tdb; - int count = -1; - - /* open the tdb */ - tdb = tdb_open_ex(fname, 0, 0, - O_RDONLY, 0, &log_ctx, NULL); - - /* traverse the tdb, then close it */ - if (tdb) { - count = tdb_traverse(tdb, test_fn, NULL); - tdb_close(tdb); - } - - /* count is < 0 means an error */ - if (count < 0) { - printf("restoring %s\n", fname); - return backup_tdb(bak_name, fname, 0, 0, 0); - } - - printf("%s : %d records\n", fname, count); - - return 0; -} - -/* - see if one file is newer than another -*/ -static int file_newer(const char *fname1, const char *fname2) -{ - struct stat st1, st2; - if (stat(fname1, &st1) != 0) { - return 0; - } - if (stat(fname2, &st2) != 0) { - return 1; - } - return (st1.st_mtime > st2.st_mtime); -} - -static void usage(void) -{ - printf("Usage: tdbbackup [options] \n\n"); - printf(" -h this help message\n"); - printf(" -s suffix set the backup suffix\n"); - printf(" -v verify mode (restore if corrupt)\n"); - printf(" -n hashsize set the new hash size for the backup\n"); - printf(" -l open without locking to back up mutex dbs\n"); - printf(" -r open with read only locking\n"); -} - - int main(int argc, char *argv[]) -{ - int i; - int ret = 0; - int c; - int verify = 0; - int hashsize = 0; - int nolock = 0; - bool readonly = false; - const char *suffix = ".bak"; - - log_ctx.log_fn = tdb_log; - - while ((c = getopt(argc, argv, "vhs:n:lr")) != -1) { - switch (c) { - case 'h': - usage(); - exit(0); - case 'v': - verify = 1; - break; - case 's': - suffix = optarg; - break; - case 'n': - hashsize = atoi(optarg); - break; - case 'l': - nolock = 1; - break; - case 'r': - readonly = true; - } - } - - argc -= optind; - argv += optind; - - if (argc < 1) { - usage(); - exit(1); - } - - for (i=0; i. -*/ - -#include "replace.h" -#include "system/locale.h" -#include "system/time.h" -#include "system/filesys.h" -#include "system/wait.h" -#include "tdb.h" - -static void print_data(TDB_DATA d) -{ - unsigned char *p = (unsigned char *)d.dptr; - int len = d.dsize; - while (len--) { - if (isprint(*p) && !strchr("\"\\", *p)) { - fputc(*p, stdout); - } else { - printf("\\%02X", *p); - } - p++; - } -} - -static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - printf("{\n"); - printf("key(%zu) = \"", key.dsize); - print_data(key); - printf("\"\n"); - printf("data(%zu) = \"", dbuf.dsize); - print_data(dbuf); - printf("\"\n"); - printf("}\n"); - return 0; -} - -static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level, - const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); - -static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level, - const char *fmt, ...) -{ - va_list ap; - const char *name = tdb_name(tdb); - const char *prefix = ""; - - if (!name) - name = "unnamed"; - - switch (level) { - case TDB_DEBUG_ERROR: - prefix = "ERROR: "; - break; - case TDB_DEBUG_WARNING: - prefix = "WARNING: "; - break; - case TDB_DEBUG_TRACE: - return; - - default: - case TDB_DEBUG_FATAL: - prefix = "FATAL: "; - break; - } - - va_start(ap, fmt); - fprintf(stderr, "tdb(%s): %s", name, prefix); - vfprintf(stderr, fmt, ap); - va_end(ap); -} - -static void emergency_walk(TDB_DATA key, TDB_DATA dbuf, void *keyname) -{ - if (keyname) { - if (key.dsize != strlen(keyname)) - return; - if (memcmp(key.dptr, keyname, key.dsize) != 0) - return; - } - traverse_fn(NULL, key, dbuf, NULL); -} - -static int dump_tdb(const char *fname, const char *keyname, bool emergency) -{ - TDB_CONTEXT *tdb; - TDB_DATA key, value; - struct tdb_logging_context logfn = { - .log_fn = log_stderr, - }; - int tdb_flags = TDB_DEFAULT; - - /* - * Note: that O_RDONLY implies TDB_NOLOCK, but we want to make it - * explicit as it's important when working on databases which were - * created with mutex locking. - */ - tdb_flags |= TDB_NOLOCK; - - tdb = tdb_open_ex(fname, 0, tdb_flags, O_RDONLY, 0, &logfn, NULL); - if (!tdb) { - printf("Failed to open %s\n", fname); - return 1; - } - - if (emergency) { - return tdb_rescue(tdb, emergency_walk, discard_const(keyname)) == 0; - } - if (!keyname) { - return tdb_traverse(tdb, traverse_fn, NULL) == -1 ? 1 : 0; - } else { - key.dptr = discard_const_p(uint8_t, keyname); - key.dsize = strlen(keyname); - value = tdb_fetch(tdb, key); - if (!value.dptr) { - return 1; - } else { - print_data(value); - free(value.dptr); - } - } - - return 0; -} - -static void usage( void) -{ - printf( "Usage: tdbdump [options] \n\n"); - printf( " -h this help message\n"); - printf( " -k keyname dumps value of keyname\n"); - printf( " -e emergency dump, for corrupt databases\n"); -} - - int main(int argc, char *argv[]) -{ - char *fname, *keyname=NULL; - bool emergency = false; - int c; - - if (argc < 2) { - printf("Usage: tdbdump \n"); - exit(1); - } - - while ((c = getopt( argc, argv, "hk:e")) != -1) { - switch (c) { - case 'h': - usage(); - exit( 0); - case 'k': - keyname = optarg; - break; - case 'e': - emergency = true; - break; - default: - usage(); - exit( 1); - } - } - - fname = argv[optind]; - - return dump_tdb(fname, keyname, emergency); -} diff --git a/ldb-2.0.8/lib/tdb/tools/tdbrestore.c b/ldb-2.0.8/lib/tdb/tools/tdbrestore.c deleted file mode 100644 index 81c986c..0000000 --- a/ldb-2.0.8/lib/tdb/tools/tdbrestore.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - tdbrestore -- construct a tdb from tdbdump output. - Copyright (C) Volker Lendecke 2010 - Copyright (C) Simon McVittie 2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "replace.h" -#include -#include "system/locale.h" -#include "system/time.h" -#include "system/filesys.h" -#include "system/wait.h" -#include "tdb.h" - -static int read_linehead(FILE *f) -{ - int i, c; - int num_bytes; - char prefix[128]; - - while (1) { - c = getc(f); - if (c == EOF) { - return -1; - } - if (c == '(') { - break; - } - } - for (i=0; idptr = (unsigned char *)malloc(size); - if (d->dptr == NULL) { - return -1; - } - d->dsize = size; - - for (i=0; idptr[i] = (low|high); - } else { - d->dptr[i] = c; - } - } - return 0; -} - -static int swallow(FILE *f, const char *s, int *eof) -{ - char line[128]; - - if (fgets(line, sizeof(line), f) == NULL) { - if (eof != NULL) { - *eof = 1; - } - return -1; - } - if (strcmp(line, s) != 0) { - return -1; - } - return 0; -} - -static int read_rec(FILE *f, TDB_CONTEXT *tdb, int *eof) -{ - int length; - TDB_DATA key, data; - int ret = -1; - - key.dptr = NULL; - data.dptr = NULL; - - if (swallow(f, "{\n", eof) == -1) { - goto fail; - } - length = read_linehead(f); - if (length == -1) { - goto fail; - } - if (read_data(f, &key, length) == -1) { - goto fail; - } - if (swallow(f, "\"\n", NULL) == -1) { - goto fail; - } - length = read_linehead(f); - if (length == -1) { - goto fail; - } - if (read_data(f, &data, length) == -1) { - goto fail; - } - if ((swallow(f, "\"\n", NULL) == -1) - || (swallow(f, "}\n", NULL) == -1)) { - goto fail; - } - if (tdb_store(tdb, key, data, TDB_INSERT) != 0) { - fprintf(stderr, "TDB error: %s\n", tdb_errorstr(tdb)); - goto fail; - } - - ret = 0; -fail: - free(key.dptr); - free(data.dptr); - return ret; -} - -static int restore_tdb(const char *fname) -{ - TDB_CONTEXT *tdb; - - tdb = tdb_open(fname, 0, 0, O_RDWR|O_CREAT|O_EXCL, 0666); - if (!tdb) { - perror("tdb_open"); - fprintf(stderr, "Failed to open %s\n", fname); - return 1; - } - - while (1) { - int eof = 0; - if (read_rec(stdin, tdb, &eof) == -1) { - if (eof) { - break; - } - return 1; - } - } - if (tdb_close(tdb)) { - fprintf(stderr, "Error closing tdb\n"); - return 1; - } - return 0; -} - -int main(int argc, char *argv[]) -{ - char *fname; - - if (argc < 2) { - printf("Usage: %s dbname < tdbdump_output\n", argv[0]); - exit(1); - } - - fname = argv[1]; - - return restore_tdb(fname); -} diff --git a/ldb-2.0.8/lib/tdb/tools/tdbtest.c b/ldb-2.0.8/lib/tdb/tools/tdbtest.c deleted file mode 100644 index 0be35dc..0000000 --- a/ldb-2.0.8/lib/tdb/tools/tdbtest.c +++ /dev/null @@ -1,290 +0,0 @@ -/* a test program for tdb - the trivial database */ - -#include "replace.h" -#include "tdb.h" -#include "system/filesys.h" -#include "system/time.h" - -#include - - -#define DELETE_PROB 7 -#define STORE_PROB 5 - -static struct tdb_context *db; -static GDBM_FILE gdbm; - -struct timeval tp1,tp2; - -static void _start_timer(void) -{ - gettimeofday(&tp1,NULL); -} - -static double _end_timer(void) -{ - gettimeofday(&tp2,NULL); - return((tp2.tv_sec - tp1.tv_sec) + - (tp2.tv_usec - tp1.tv_usec)*1.0e-6); -} - -static void fatal(const char *why) -{ - perror(why); - exit(1); -} - -#ifdef PRINTF_ATTRIBUTE -static void tdb_log(struct tdb_context *tdb, int level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); -#endif -static void tdb_log(struct tdb_context *tdb, int level, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - vfprintf(stdout, format, ap); - va_end(ap); - fflush(stdout); -} - -static void compare_db(void) -{ - TDB_DATA d, key, nextkey; - datum gd, gkey, gnextkey; - - key = tdb_firstkey(db); - while (key.dptr) { - d = tdb_fetch(db, key); - gkey.dptr = key.dptr; - gkey.dsize = key.dsize; - - gd = gdbm_fetch(gdbm, gkey); - - if (!gd.dptr) fatal("key not in gdbm"); - if (gd.dsize != d.dsize) fatal("data sizes differ"); - if (memcmp(gd.dptr, d.dptr, d.dsize)) { - fatal("data differs"); - } - - nextkey = tdb_nextkey(db, key); - free(key.dptr); - free(d.dptr); - free(gd.dptr); - key = nextkey; - } - - gkey = gdbm_firstkey(gdbm); - while (gkey.dptr) { - gd = gdbm_fetch(gdbm, gkey); - key.dptr = gkey.dptr; - key.dsize = gkey.dsize; - - d = tdb_fetch(db, key); - - if (!d.dptr) fatal("key not in db"); - if (d.dsize != gd.dsize) fatal("data sizes differ"); - if (memcmp(d.dptr, gd.dptr, gd.dsize)) { - fatal("data differs"); - } - - gnextkey = gdbm_nextkey(gdbm, gkey); - free(gkey.dptr); - free(gd.dptr); - free(d.dptr); - gkey = gnextkey; - } -} - -static char *randbuf(int len) -{ - char *buf; - int i; - buf = (char *)malloc(len+1); - - for (i=0;i. -*/ - -#include "replace.h" -#include "system/locale.h" -#include "system/time.h" -#include "system/filesys.h" -#include "system/wait.h" -#include "tdb.h" - -static int do_command(void); -const char *cmdname; -char *arg1, *arg2; -size_t arg1len, arg2len; -int bIterate = 0; -char *line; -TDB_DATA iterate_kbuf; -char cmdline[1024]; -static int disable_mmap; -static int _disable_lock; - -enum commands { - CMD_CREATE_TDB, - CMD_OPEN_TDB, - CMD_TRANSACTION_START, - CMD_TRANSACTION_COMMIT, - CMD_TRANSACTION_CANCEL, - CMD_ERASE, - CMD_DUMP, - CMD_INSERT, - CMD_MOVE, - CMD_STOREHEX, - CMD_STORE, - CMD_SHOW, - CMD_KEYS, - CMD_HEXKEYS, - CMD_DELETE, - CMD_LIST_HASH_FREE, - CMD_LIST_FREE, - CMD_FREELIST_SIZE, - CMD_INFO, - CMD_MMAP, - CMD_SPEED, - CMD_FIRST, - CMD_NEXT, - CMD_SYSTEM, - CMD_CHECK, - CMD_REPACK, - CMD_QUIT, - CMD_HELP -}; - -typedef struct { - const char *name; - enum commands cmd; -} COMMAND_TABLE; - -COMMAND_TABLE cmd_table[] = { - {"create", CMD_CREATE_TDB}, - {"open", CMD_OPEN_TDB}, - {"transaction_start", CMD_TRANSACTION_START}, - {"transaction_commit", CMD_TRANSACTION_COMMIT}, - {"transaction_cancel", CMD_TRANSACTION_CANCEL}, - {"erase", CMD_ERASE}, - {"dump", CMD_DUMP}, - {"insert", CMD_INSERT}, - {"move", CMD_MOVE}, - {"storehex", CMD_STOREHEX}, - {"store", CMD_STORE}, - {"show", CMD_SHOW}, - {"keys", CMD_KEYS}, - {"hexkeys", CMD_HEXKEYS}, - {"delete", CMD_DELETE}, - {"list", CMD_LIST_HASH_FREE}, - {"free", CMD_LIST_FREE}, - {"freelist_size", CMD_FREELIST_SIZE}, - {"info", CMD_INFO}, - {"speed", CMD_SPEED}, - {"mmap", CMD_MMAP}, - {"first", CMD_FIRST}, - {"1", CMD_FIRST}, - {"next", CMD_NEXT}, - {"n", CMD_NEXT}, - {"check", CMD_CHECK}, - {"quit", CMD_QUIT}, - {"q", CMD_QUIT}, - {"!", CMD_SYSTEM}, - {"repack", CMD_REPACK}, - {NULL, CMD_HELP} -}; - -struct timeval tp1,tp2; - -static void _start_timer(void) -{ - gettimeofday(&tp1,NULL); -} - -static double _end_timer(void) -{ - gettimeofday(&tp2,NULL); - return((tp2.tv_sec - tp1.tv_sec) + - (tp2.tv_usec - tp1.tv_usec)*1.0e-6); -} - -#ifdef PRINTF_ATTRIBUTE -static void tdb_log_open(struct tdb_context *tdb, enum tdb_debug_level level, - const char *format, ...) PRINTF_ATTRIBUTE(3,4); -#endif -static void tdb_log_open(struct tdb_context *tdb, enum tdb_debug_level level, - const char *format, ...) -{ - const char *mutex_msg = - "Can use mutexes only with MUTEX_LOCKING or NOLOCK\n"; - char *p; - va_list ap; - - p = strstr(format, mutex_msg); - if (p != NULL) { - /* - * Yes, this is a hack, but we don't want to see this - * message on first open, but we want to see - * everything else. - */ - return; - } - - va_start(ap, format); - vfprintf(stderr, format, ap); - va_end(ap); -} - -#ifdef PRINTF_ATTRIBUTE -static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); -#endif -static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - vfprintf(stderr, format, ap); - va_end(ap); -} - -/* a tdb tool for manipulating a tdb database */ - -static TDB_CONTEXT *tdb; - -static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); -static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); -static int print_hexkey(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); - -static void print_asc(const char *buf,int len) -{ - int i; - - /* We're probably printing ASCII strings so don't try to display - the trailing NULL character. */ - - if (buf[len - 1] == 0) - len--; - - for (i=0;i8) printf(" "); - while (n--) printf(" "); - - n = i%16; - if (n > 8) n = 8; - print_asc(&buf[i-(i%16)],n); printf(" "); - n = (i%16) - n; - if (n>0) print_asc(&buf[i-n],n); - printf("\n"); - } -} - -static void help(void) -{ - printf("\n" -"tdbtool: \n" -" create dbname : create a database\n" -" open dbname : open an existing database\n" -" transaction_start : start a transaction\n" -" transaction_commit : commit a transaction\n" -" transaction_cancel : cancel a transaction\n" -" erase : erase the database\n" -" dump : dump the database as strings\n" -" keys : dump the database keys as strings\n" -" hexkeys : dump the database keys as hex values\n" -" info : print summary info about the database\n" -" insert key data : insert a record\n" -" move key file : move a record to a destination tdb\n" -" storehex key data : store a record (replace), key/value in hex format\n" -" store key data : store a record (replace)\n" -" show key : show a record by key\n" -" delete key : delete a record by key\n" -" list : print the database hash table and freelist\n" -" free : print the database freelist\n" -" freelist_size : print the number of records in the freelist\n" -" check : check the integrity of an opened database\n" -" repack : repack the database\n" -" speed : perform speed tests on the database\n" -" ! command : execute system command\n" -" 1 | first : print the first record\n" -" n | next : print the next record\n" -" q | quit : terminate\n" -" \\n : repeat 'next' command\n" -"\n"); -} - -static void terror(const char *why) -{ - printf("%s\n", why); -} - -static void create_tdb(const char *tdbname) -{ - struct tdb_logging_context log_ctx = { NULL, NULL}; - log_ctx.log_fn = tdb_log; - - if (tdb) tdb_close(tdb); - tdb = tdb_open_ex(tdbname, 0, - TDB_CLEAR_IF_FIRST | - (disable_mmap?TDB_NOMMAP:0) | - (_disable_lock?TDB_NOLOCK:0), - O_RDWR | O_CREAT | O_TRUNC, 0600, &log_ctx, NULL); - if (!tdb) { - printf("Could not create %s: %s\n", tdbname, strerror(errno)); - } -} - -static void open_tdb(const char *tdbname) -{ - struct tdb_logging_context log_ctx = { NULL, NULL }; - log_ctx.log_fn = tdb_log_open; - - if (tdb) tdb_close(tdb); - tdb = tdb_open_ex(tdbname, 0, - (disable_mmap?TDB_NOMMAP:0) | - (_disable_lock?TDB_NOLOCK:0), - O_RDWR, 0600, - &log_ctx, NULL); - - log_ctx.log_fn = tdb_log; - if (tdb != NULL) { - tdb_set_logging_function(tdb, &log_ctx); - } - - if ((tdb == NULL) && (errno == EINVAL)) { - /* - * Retry NOLOCK and readonly. There we want to see all - * error messages. - */ - tdb = tdb_open_ex(tdbname, 0, - (disable_mmap?TDB_NOMMAP:0) |TDB_NOLOCK, - O_RDONLY, 0600, - &log_ctx, NULL); - } - - if (!tdb) { - printf("Could not open %s: %s\n", tdbname, strerror(errno)); - } -} - -static void insert_tdb(char *keyname, size_t keylen, char* data, size_t datalen) -{ - TDB_DATA key, dbuf; - - if ((keyname == NULL) || (keylen == 0)) { - terror("need key"); - return; - } - - key.dptr = (unsigned char *)keyname; - key.dsize = keylen; - dbuf.dptr = (unsigned char *)data; - dbuf.dsize = datalen; - - if (tdb_store(tdb, key, dbuf, TDB_INSERT) != 0) { - terror("insert failed"); - } -} - -static void store_tdb(char *keyname, size_t keylen, char* data, size_t datalen) -{ - TDB_DATA key, dbuf; - - if ((keyname == NULL) || (keylen == 0)) { - terror("need key"); - return; - } - - if ((data == NULL) || (datalen == 0)) { - terror("need data"); - return; - } - - key.dptr = (unsigned char *)keyname; - key.dsize = keylen; - dbuf.dptr = (unsigned char *)data; - dbuf.dsize = datalen; - - printf("Storing key:\n"); - print_rec(tdb, key, dbuf, NULL); - - if (tdb_store(tdb, key, dbuf, TDB_REPLACE) != 0) { - terror("store failed"); - } -} - -static bool hexchar(char c, uint8_t *v) -{ - if ((c >= '0') && (c <= '9')) { - *v = (c - '0'); - return true; - } - if ((c >= 'A') && (c <= 'F')) { - *v = (c - 'A' + 10); - return true; - } - if ((c >= 'a') && (c <= 'f')) { - *v = (c - 'a' + 10); - return true; - } - return false; -} - -static bool parse_hex(const char *src, size_t srclen, uint8_t *dst) -{ - size_t i=0; - - if ((srclen % 2) != 0) { - return false; - } - - while (iname) { - cmd_len = strlen(ctp->name); - if (strncmp(ctp->name,cmdname,cmd_len) == 0) { - mycmd = ctp->cmd; - break; - } - ctp++; - } - } - } - - switch (mycmd) { - case CMD_CREATE_TDB: - bIterate = 0; - create_tdb(arg1); - return 0; - case CMD_OPEN_TDB: - bIterate = 0; - open_tdb(arg1); - return 0; - case CMD_SYSTEM: - /* Shell command */ - if (system(arg1) == -1) { - terror("system() call failed\n"); - } - return 0; - case CMD_QUIT: - return 1; - default: - /* all the rest require a open database */ - if (!tdb) { - bIterate = 0; - terror("database not open"); - help(); - return 0; - } - switch (mycmd) { - case CMD_TRANSACTION_START: - bIterate = 0; - tdb_transaction_start(tdb); - return 0; - case CMD_TRANSACTION_COMMIT: - bIterate = 0; - tdb_transaction_commit(tdb); - return 0; - case CMD_REPACK: - bIterate = 0; - tdb_repack(tdb); - return 0; - case CMD_TRANSACTION_CANCEL: - bIterate = 0; - tdb_transaction_cancel(tdb); - return 0; - case CMD_ERASE: - bIterate = 0; - tdb_wipe_all(tdb); - return 0; - case CMD_DUMP: - bIterate = 0; - tdb_traverse(tdb, print_rec, NULL); - return 0; - case CMD_INSERT: - bIterate = 0; - insert_tdb(arg1, arg1len,arg2,arg2len); - return 0; - case CMD_MOVE: - bIterate = 0; - move_rec(arg1,arg1len,arg2); - return 0; - case CMD_STORE: - bIterate = 0; - store_tdb(arg1,arg1len,arg2,arg2len); - return 0; - case CMD_STOREHEX: - bIterate = 0; - store_hex_tdb(arg1,arg1len,arg2,arg2len); - return 0; - case CMD_SHOW: - bIterate = 0; - show_tdb(arg1, arg1len); - return 0; - case CMD_KEYS: - tdb_traverse(tdb, print_key, NULL); - return 0; - case CMD_HEXKEYS: - tdb_traverse(tdb, print_hexkey, NULL); - return 0; - case CMD_DELETE: - bIterate = 0; - delete_tdb(arg1,arg1len); - return 0; - case CMD_LIST_HASH_FREE: - tdb_dump_all(tdb); - return 0; - case CMD_LIST_FREE: - tdb_printfreelist(tdb); - return 0; - case CMD_FREELIST_SIZE: { - int size; - - size = tdb_freelist_size(tdb); - if (size < 0) { - printf("Error getting freelist size.\n"); - } else { - printf("freelist size: %d\n", size); - } - - return 0; - } - case CMD_INFO: - info_tdb(); - return 0; - case CMD_SPEED: - speed_tdb(arg1); - return 0; - case CMD_MMAP: - toggle_mmap(); - return 0; - case CMD_FIRST: - bIterate = 1; - first_record(tdb, &iterate_kbuf); - return 0; - case CMD_NEXT: - if (bIterate) - next_record(tdb, &iterate_kbuf); - return 0; - case CMD_CHECK: - check_db(tdb); - return 0; - case CMD_HELP: - help(); - return 0; - case CMD_CREATE_TDB: - case CMD_OPEN_TDB: - case CMD_SYSTEM: - case CMD_QUIT: - /* - * unhandled commands. cases included here to avoid compiler - * warnings. - */ - return 0; - } - } - - return 0; -} - -static char *tdb_convert_string(char *instring, size_t *sizep) -{ - size_t length = 0; - char *outp, *inp; - char temp[3]; - - outp = inp = instring; - - while (*inp) { - if (*inp == '\\') { - inp++; - if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) { - temp[0] = *inp++; - temp[1] = '\0'; - if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) { - temp[1] = *inp++; - temp[2] = '\0'; - } - *outp++ = (char)strtol((const char *)temp,NULL,16); - } else { - *outp++ = *inp++; - } - } else { - *outp++ = *inp++; - } - length++; - } - *sizep = length; - return instring; -} - -int main(int argc, char *argv[]) -{ - cmdname = ""; - arg1 = NULL; - arg1len = 0; - arg2 = NULL; - arg2len = 0; - - if (argv[1] && (strcmp(argv[1], "-l") == 0)) { - _disable_lock = 1; - argv[1] = argv[0]; - argv += 1; - argc -= 1; - } - - if (argv[1]) { - cmdname = "open"; - arg1 = argv[1]; - do_command(); - cmdname = ""; - arg1 = NULL; - } - - switch (argc) { - case 1: - case 2: - /* Interactive mode */ - while ((cmdname = tdb_getline("tdb> "))) { - arg2 = arg1 = NULL; - if ((arg1 = strchr((const char *)cmdname,' ')) != NULL) { - arg1++; - arg2 = arg1; - while (*arg2) { - if (*arg2 == ' ') { - *arg2++ = '\0'; - break; - } - if ((*arg2++ == '\\') && (*arg2 == ' ')) { - arg2++; - } - } - } - if (arg1) arg1 = tdb_convert_string(arg1,&arg1len); - if (arg2) arg2 = tdb_convert_string(arg2,&arg2len); - if (do_command()) break; - } - break; - case 5: - arg2 = tdb_convert_string(argv[4],&arg2len); - FALL_THROUGH; - case 4: - arg1 = tdb_convert_string(argv[3],&arg1len); - FALL_THROUGH; - case 3: - cmdname = argv[2]; - FALL_THROUGH; - default: - do_command(); - break; - } - - if (tdb) tdb_close(tdb); - - return 0; -} diff --git a/ldb-2.0.8/lib/tdb/tools/tdbtorture.c b/ldb-2.0.8/lib/tdb/tools/tdbtorture.c deleted file mode 100644 index 7d08d4f..0000000 --- a/ldb-2.0.8/lib/tdb/tools/tdbtorture.c +++ /dev/null @@ -1,501 +0,0 @@ -/* this tests tdb by doing lots of ops from several simultaneous - writers - that stresses the locking code. -*/ - -#include "replace.h" -#include "system/time.h" -#include "system/wait.h" -#include "system/filesys.h" -#include "tdb.h" - -#ifdef HAVE_GETOPT_H -#include -#endif - - -#define REOPEN_PROB 30 -#define DELETE_PROB 8 -#define STORE_PROB 4 -#define APPEND_PROB 6 -#define TRANSACTION_PROB 10 -#define TRANSACTION_PREPARE_PROB 2 -#define LOCKSTORE_PROB 5 -#define TRAVERSE_PROB 20 -#define TRAVERSE_READ_PROB 20 -#define CULL_PROB 100 -#define KEYLEN 3 -#define DATALEN 100 - -static struct tdb_context *db; -static int in_transaction; -static int error_count; -static int always_transaction = 0; -static int hash_size = 2; -static unsigned loopnum; -static int count_pipe; -static bool mutex = false; -static struct tdb_logging_context log_ctx; - -#ifdef PRINTF_ATTRIBUTE -static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) PRINTF_ATTRIBUTE(3,4); -#endif -static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) -{ - va_list ap; - - /* trace level messages do not indicate an error */ - if (level != TDB_DEBUG_TRACE) { - error_count++; - } - - va_start(ap, format); - vfprintf(stdout, format, ap); - va_end(ap); - fflush(stdout); -#if 0 - if (level != TDB_DEBUG_TRACE) { - char *ptr; - signal(SIGUSR1, SIG_IGN); - asprintf(&ptr,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid()); - system(ptr); - free(ptr); - } -#endif -} - -static void fatal(const char *why) -{ - perror(why); - error_count++; -} - -static char *randbuf(int len) -{ - char *buf; - int i; - buf = (char *)malloc(len+1); - - for (i=0;i - - -ldb - - - -

      tdb

      - -TDB is a Trivial Database. In concept, it is very much like GDBM, and BSD's DB -except that it allows multiple simultaneous writers and uses locking -internally to keep writers from trampling on each other. TDB is also extremely -small. - -

      Download

      -You can download the latest releases of tdb from the
      tdb directory on the samba public -source archive. - - -

      Discussion and bug reports

      - -tdb does not currently have its own mailing list or bug tracking -system. For now, please use the samba-technical -mailing list, and the Samba -bugzilla bug tracking system. - -

      Download

      - -You can download the latest code either via git or rsync.
      -
      -To fetch via git see the following guide:
      -Using Git for Samba Development
      -Once you have cloned the tree switch to the master branch and cd into the source/lib/tdb directory.
      -
      -To fetch via rsync use these commands: - -
      -  rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/tdb .
      -  rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/replace .
      -
      - -and build in tdb. It will find the replace library in the directory -above automatically. - - - diff --git a/ldb-2.0.8/lib/tdb/wscript b/ldb-2.0.8/lib/tdb/wscript deleted file mode 100644 index 1ab0e8d..0000000 --- a/ldb-2.0.8/lib/tdb/wscript +++ /dev/null @@ -1,259 +0,0 @@ -#!/usr/bin/env python - -APPNAME = 'tdb' -VERSION = '1.4.2' - -import sys, os - -# find the buildtools directory -top = '.' -while not os.path.exists(top+'/buildtools') and len(top.split('/')) < 5: - top = top + '/..' -sys.path.insert(0, top + '/buildtools/wafsamba') - -out = 'bin' - -import wafsamba -from wafsamba import samba_dist, samba_utils -from waflib import Options, Logs, Context -import shutil - -samba_dist.DIST_DIRS('lib/tdb:. lib/replace:lib/replace buildtools:buildtools third_party/waf:third_party/waf') - -tdb1_unit_tests = [ - 'run-3G-file', - 'run-bad-tdb-header', - 'run', - 'run-check', - 'run-corrupt', - 'run-die-during-transaction', - 'run-endian', - 'run-incompatible', - 'run-nested-transactions', - 'run-nested-traverse', - 'run-no-lock-during-traverse', - 'run-oldhash', - 'run-open-during-transaction', - 'run-readonly-check', - 'run-rescue', - 'run-rescue-find_entry', - 'run-rdlock-upgrade', - 'run-rwlock-check', - 'run-summary', - 'run-transaction-expand', - 'run-traverse-in-transaction', - 'run-wronghash-fail', - 'run-zero-append', - 'run-fcntl-deadlock', - 'run-marklock-deadlock', - 'run-allrecord-traverse-deadlock', - 'run-mutex-openflags2', - 'run-mutex-trylock', - 'run-mutex-allrecord-bench', - 'run-mutex-allrecord-trylock', - 'run-mutex-allrecord-block', - 'run-mutex-transaction1', - 'run-mutex-die', - 'run-mutex1', - 'run-circular-chain', - 'run-circular-freelist', - 'run-traverse-chain', -] - -def options(opt): - opt.BUILTIN_DEFAULT('replace') - opt.PRIVATE_EXTENSION_DEFAULT('tdb', noextension='tdb') - opt.RECURSE('lib/replace') - opt.add_option('--disable-tdb-mutex-locking', - help=("Disable the use of pthread robust mutexes"), - action="store_true", dest='disable_tdb_mutex_locking', - default=False) - - -def configure(conf): - conf.env.disable_tdb_mutex_locking = getattr(Options.options, - 'disable_tdb_mutex_locking', - False) - if not conf.env.disable_tdb_mutex_locking: - conf.env.replace_add_global_pthread = True - conf.RECURSE('lib/replace') - - conf.env.standalone_tdb = conf.IN_LAUNCH_DIR() - conf.env.building_tdb = True - - if not conf.env.standalone_tdb: - if conf.CHECK_BUNDLED_SYSTEM_PKG('tdb', minversion=VERSION, - implied_deps='replace'): - conf.define('USING_SYSTEM_TDB', 1) - conf.env.building_tdb = False - if not conf.env.disable_python and \ - conf.CHECK_BUNDLED_SYSTEM_PYTHON('pytdb', 'tdb', minversion=VERSION): - conf.define('USING_SYSTEM_PYTDB', 1) - - if (conf.CONFIG_SET('HAVE_ROBUST_MUTEXES') and - conf.env.building_tdb and - not conf.env.disable_tdb_mutex_locking): - conf.define('USE_TDB_MUTEX_LOCKING', 1) - - conf.CHECK_XSLTPROC_MANPAGES() - - conf.SAMBA_CHECK_PYTHON() - conf.SAMBA_CHECK_PYTHON_HEADERS() - - conf.SAMBA_CONFIG_H() - - conf.SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS() - -def build(bld): - bld.RECURSE('lib/replace') - - COMMON_FILES='''check.c error.c tdb.c traverse.c - freelistcheck.c lock.c dump.c freelist.c - io.c open.c transaction.c hash.c summary.c rescue.c - mutex.c''' - - COMMON_SRC = bld.SUBDIR('common', COMMON_FILES) - - if bld.env.standalone_tdb: - bld.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig' - private_library = False - else: - private_library = True - - if not bld.CONFIG_SET('USING_SYSTEM_TDB'): - - tdb_deps = 'replace' - - if bld.CONFIG_SET('USE_TDB_MUTEX_LOCKING'): - tdb_deps += ' pthread' - - bld.SAMBA_LIBRARY('tdb', - COMMON_SRC, - deps=tdb_deps, - includes='include', - abi_directory='ABI', - abi_match='tdb_*', - hide_symbols=True, - vnum=VERSION, - public_headers=('' if private_library else 'include/tdb.h'), - public_headers_install=not private_library, - pc_files='tdb.pc', - private_library=private_library) - - bld.SAMBA_BINARY('tdbtorture', - 'tools/tdbtorture.c', - 'tdb', - install=False) - - bld.SAMBA_BINARY('tdbrestore', - 'tools/tdbrestore.c', - 'tdb', manpages='man/tdbrestore.8') - - bld.SAMBA_BINARY('tdbdump', - 'tools/tdbdump.c', - 'tdb', manpages='man/tdbdump.8') - - bld.SAMBA_BINARY('tdbbackup', - 'tools/tdbbackup.c', - 'tdb', - manpages='man/tdbbackup.8') - - bld.SAMBA_BINARY('tdbtool', - 'tools/tdbtool.c', - 'tdb', manpages='man/tdbtool.8') - - if bld.env.standalone_tdb: - # FIXME: This hardcoded list is stupid, stupid, stupid. - bld.SAMBA_SUBSYSTEM('tdb-test-helpers', - 'test/external-agent.c test/lock-tracking.c test/logging.c', - tdb_deps, - includes='include') - - for t in tdb1_unit_tests: - b = "tdb1-" + t - s = "test/" + t + ".c" - bld.SAMBA_BINARY(b, s, 'replace tdb-test-helpers', - includes='include', install=False) - - if not bld.CONFIG_SET('USING_SYSTEM_PYTDB'): - bld.SAMBA_PYTHON('pytdb', - 'pytdb.c', - deps='tdb', - enabled=not bld.env.disable_python, - realname='tdb.so', - cflags='-DPACKAGE_VERSION=\"%s\"' % VERSION) - - if not bld.env.disable_python: - bld.SAMBA_SCRIPT('_tdb_text.py', - pattern='_tdb_text.py', - installdir='python') - - bld.INSTALL_FILES('${PYTHONARCHDIR}', '_tdb_text.py') - -def testonly(ctx): - '''run tdb testsuite''' - ecode = 0 - - blddir = Context.g_module.out - test_prefix = "%s/st" % (blddir) - shutil.rmtree(test_prefix, ignore_errors=True) - os.makedirs(test_prefix) - os.environ['TEST_DATA_PREFIX'] = test_prefix - - env = samba_utils.LOAD_ENVIRONMENT() - # FIXME: This is horrible :( - if env.building_tdb: - # Create scratch directory for tests. - testdir = os.path.join(test_prefix, 'tdb-tests') - samba_utils.mkdir_p(testdir) - # Symlink back to source dir so it can find tests in test/ - link = os.path.join(testdir, 'test') - if not os.path.exists(link): - os.symlink(ctx.path.make_node('test').abspath(), link) - - sh_tests = ["test/test_tdbbackup.sh test/jenkins-be-hash.tdb"] - - for sh_test in sh_tests: - cmd = "BINDIR=%s %s" % (blddir, sh_test) - print("shell test: " + cmd) - ret = samba_utils.RUN_COMMAND(cmd) - if ret != 0: - print("%s sh test failed" % cmd) - ecode = ret - break - - for t in tdb1_unit_tests: - f = "tdb1-" + t - cmd = "cd " + testdir + " && " + os.path.abspath(os.path.join(blddir, f)) + " > test-output 2>&1" - print("..." + f) - ret = samba_utils.RUN_COMMAND(cmd) - if ret != 0: - print("%s failed:" % f) - samba_utils.RUN_COMMAND("cat " + os.path.join(testdir, 'test-output')) - ecode = ret - break - - if ecode == 0: - cmd = os.path.join(blddir, 'tdbtorture') - ret = samba_utils.RUN_COMMAND(cmd) - print("testsuite returned %d" % ret) - if ret != 0: - ecode = ret - - pyret = samba_utils.RUN_PYTHON_TESTS(['python/tests/simple.py']) - print("python testsuite returned %d" % pyret) - sys.exit(ecode or pyret) - -# WAF doesn't build the unit tests for this, maybe because they don't link with tdb? -# This forces it -def test(ctx): - Options.commands.append('build') - Options.commands.append('testonly') - -def dist(): - '''makes a tarball for distribution''' - samba_dist.dist() - -def reconfigure(ctx): - '''reconfigure if config scripts have changed''' - samba_utils.reconfigure(ctx) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.10.0.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.10.0.sigs deleted file mode 100644 index f6227db..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.10.0.sigs +++ /dev/null @@ -1,126 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_context_pop_use: void (struct tevent_context *, const char *) -_tevent_context_push_use: bool (struct tevent_context *, const char *) -_tevent_context_wrapper_create: struct tevent_context *(struct tevent_context *, TALLOC_CTX *, const struct tevent_wrapper_ops *, void *, size_t, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_abort: void (struct tevent_context *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_double_free: void (TALLOC_CTX *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_have_events: bool (struct tevent_context *) -tevent_common_invoke_fd_handler: int (struct tevent_fd *, uint16_t, bool *) -tevent_common_invoke_immediate_handler: int (struct tevent_immediate *, bool *) -tevent_common_invoke_signal_handler: int (struct tevent_signal *, int, int, void *, bool *) -tevent_common_invoke_timer_handler: int (struct tevent_timer *, struct timeval, bool *) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_common_threaded_activate_immediate: void (struct tevent_context *) -tevent_common_wakeup: int (struct tevent_context *) -tevent_common_wakeup_fd: int (int) -tevent_common_wakeup_init: int (struct tevent_context *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_context_is_wrapper: bool (struct tevent_context *) -tevent_context_same_loop: bool (struct tevent_context *, struct tevent_context *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_num_signals: size_t (void) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_entry_untrigger: void (struct tevent_queue_entry *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_queue_wait_recv: bool (struct tevent_req *) -tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_get_profile: const struct tevent_req_profile *(struct tevent_req *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_move_profile: struct tevent_req_profile *(struct tevent_req *, TALLOC_CTX *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_profile_append_sub: void (struct tevent_req_profile *, struct tevent_req_profile **) -tevent_req_profile_create: struct tevent_req_profile *(TALLOC_CTX *) -tevent_req_profile_get_name: void (const struct tevent_req_profile *, const char **) -tevent_req_profile_get_start: void (const struct tevent_req_profile *, const char **, struct timeval *) -tevent_req_profile_get_status: void (const struct tevent_req_profile *, pid_t *, enum tevent_req_state *, uint64_t *) -tevent_req_profile_get_stop: void (const struct tevent_req_profile *, const char **, struct timeval *) -tevent_req_profile_get_subprofiles: const struct tevent_req_profile *(const struct tevent_req_profile *) -tevent_req_profile_next: const struct tevent_req_profile *(const struct tevent_req_profile *) -tevent_req_profile_set_name: bool (struct tevent_req_profile *, const char *) -tevent_req_profile_set_start: bool (struct tevent_req_profile *, const char *, struct timeval) -tevent_req_profile_set_status: void (struct tevent_req_profile *, pid_t, enum tevent_req_state, uint64_t) -tevent_req_profile_set_stop: bool (struct tevent_req_profile *, const char *, struct timeval) -tevent_req_received: void (struct tevent_req *) -tevent_req_reset_endtime: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_req_set_profile: bool (struct tevent_req *) -tevent_sa_info_queue_count: size_t (void) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) -tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) -tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_update_timer: void (struct tevent_timer *, struct timeval) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.10.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.10.sigs deleted file mode 100644 index 9adaba5..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.10.sigs +++ /dev/null @@ -1,73 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_signal_support: bool (struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.11.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.11.sigs deleted file mode 100644 index 9adaba5..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.11.sigs +++ /dev/null @@ -1,73 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_signal_support: bool (struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.12.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.12.sigs deleted file mode 100644 index df9b08d..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.12.sigs +++ /dev/null @@ -1,74 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_signal_support: bool (struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.13.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.13.sigs deleted file mode 100644 index 888ca0e..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.13.sigs +++ /dev/null @@ -1,75 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_signal_support: bool (struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.14.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.14.sigs deleted file mode 100644 index 13c461c..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.14.sigs +++ /dev/null @@ -1,78 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_signal_support: bool (struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.15.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.15.sigs deleted file mode 100644 index 13c461c..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.15.sigs +++ /dev/null @@ -1,78 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_signal_support: bool (struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.16.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.16.sigs deleted file mode 100644 index ea7f944..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.16.sigs +++ /dev/null @@ -1,82 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.17.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.17.sigs deleted file mode 100644 index ea7f944..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.17.sigs +++ /dev/null @@ -1,82 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.18.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.18.sigs deleted file mode 100644 index 70d20b6..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.18.sigs +++ /dev/null @@ -1,83 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.19.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.19.sigs deleted file mode 100644 index 70d20b6..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.19.sigs +++ /dev/null @@ -1,83 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.20.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.20.sigs deleted file mode 100644 index 7b9c77d..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.20.sigs +++ /dev/null @@ -1,87 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_num_signals: size_t (void) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_queue_wait_recv: bool (struct tevent_req *) -tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_sa_info_queue_count: size_t (void) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.21.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.21.sigs deleted file mode 100644 index d8b9f4b..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.21.sigs +++ /dev/null @@ -1,88 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_num_signals: size_t (void) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_queue_wait_recv: bool (struct tevent_req *) -tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_sa_info_queue_count: size_t (void) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.22.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.22.sigs deleted file mode 100644 index d8b9f4b..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.22.sigs +++ /dev/null @@ -1,88 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_num_signals: size_t (void) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_queue_wait_recv: bool (struct tevent_req *) -tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_sa_info_queue_count: size_t (void) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.23.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.23.sigs deleted file mode 100644 index d8b9f4b..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.23.sigs +++ /dev/null @@ -1,88 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_num_signals: size_t (void) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_queue_wait_recv: bool (struct tevent_req *) -tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_sa_info_queue_count: size_t (void) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.24.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.24.sigs deleted file mode 100644 index d8b9f4b..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.24.sigs +++ /dev/null @@ -1,88 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_num_signals: size_t (void) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_queue_wait_recv: bool (struct tevent_req *) -tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_sa_info_queue_count: size_t (void) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.25.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.25.sigs deleted file mode 100644 index d8b9f4b..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.25.sigs +++ /dev/null @@ -1,88 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_num_signals: size_t (void) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_queue_wait_recv: bool (struct tevent_req *) -tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_sa_info_queue_count: size_t (void) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.26.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.26.sigs deleted file mode 100644 index 1357751..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.26.sigs +++ /dev/null @@ -1,90 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_num_signals: size_t (void) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_queue_wait_recv: bool (struct tevent_req *) -tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_sa_info_queue_count: size_t (void) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) -tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.27.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.27.sigs deleted file mode 100644 index 1357751..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.27.sigs +++ /dev/null @@ -1,90 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_num_signals: size_t (void) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_queue_wait_recv: bool (struct tevent_req *) -tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_sa_info_queue_count: size_t (void) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) -tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.28.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.28.sigs deleted file mode 100644 index 1357751..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.28.sigs +++ /dev/null @@ -1,90 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_num_signals: size_t (void) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_queue_wait_recv: bool (struct tevent_req *) -tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_sa_info_queue_count: size_t (void) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) -tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.29.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.29.sigs deleted file mode 100644 index 1357751..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.29.sigs +++ /dev/null @@ -1,90 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_num_signals: size_t (void) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_queue_wait_recv: bool (struct tevent_req *) -tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_sa_info_queue_count: size_t (void) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) -tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.30.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.30.sigs deleted file mode 100644 index 9b8bfa1..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.30.sigs +++ /dev/null @@ -1,96 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_have_events: bool (struct tevent_context *) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_common_threaded_activate_immediate: void (struct tevent_context *) -tevent_common_wakeup: int (struct tevent_context *) -tevent_common_wakeup_init: int (struct tevent_context *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_num_signals: size_t (void) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_queue_wait_recv: bool (struct tevent_req *) -tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_sa_info_queue_count: size_t (void) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) -tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) -tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.31.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.31.sigs deleted file mode 100644 index 7a6a236..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.31.sigs +++ /dev/null @@ -1,99 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_have_events: bool (struct tevent_context *) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_common_threaded_activate_immediate: void (struct tevent_context *) -tevent_common_wakeup: int (struct tevent_context *) -tevent_common_wakeup_fd: int (int) -tevent_common_wakeup_init: int (struct tevent_context *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_num_signals: size_t (void) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_queue_wait_recv: bool (struct tevent_req *) -tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_reset_endtime: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_sa_info_queue_count: size_t (void) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) -tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) -tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_update_timer: void (struct tevent_timer *, struct timeval) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.32.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.32.sigs deleted file mode 100644 index 7a6a236..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.32.sigs +++ /dev/null @@ -1,99 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_have_events: bool (struct tevent_context *) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_common_threaded_activate_immediate: void (struct tevent_context *) -tevent_common_wakeup: int (struct tevent_context *) -tevent_common_wakeup_fd: int (int) -tevent_common_wakeup_init: int (struct tevent_context *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_num_signals: size_t (void) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_queue_wait_recv: bool (struct tevent_req *) -tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_reset_endtime: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_sa_info_queue_count: size_t (void) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) -tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) -tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_update_timer: void (struct tevent_timer *, struct timeval) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.33.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.33.sigs deleted file mode 100644 index 7a6a236..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.33.sigs +++ /dev/null @@ -1,99 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_have_events: bool (struct tevent_context *) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_common_threaded_activate_immediate: void (struct tevent_context *) -tevent_common_wakeup: int (struct tevent_context *) -tevent_common_wakeup_fd: int (int) -tevent_common_wakeup_init: int (struct tevent_context *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_num_signals: size_t (void) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_queue_wait_recv: bool (struct tevent_req *) -tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_reset_endtime: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_sa_info_queue_count: size_t (void) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) -tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) -tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_update_timer: void (struct tevent_timer *, struct timeval) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.34.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.34.sigs deleted file mode 100644 index 7a6a236..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.34.sigs +++ /dev/null @@ -1,99 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_have_events: bool (struct tevent_context *) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_common_threaded_activate_immediate: void (struct tevent_context *) -tevent_common_wakeup: int (struct tevent_context *) -tevent_common_wakeup_fd: int (int) -tevent_common_wakeup_init: int (struct tevent_context *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_num_signals: size_t (void) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_queue_wait_recv: bool (struct tevent_req *) -tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_reset_endtime: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_sa_info_queue_count: size_t (void) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) -tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) -tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_update_timer: void (struct tevent_timer *, struct timeval) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.35.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.35.sigs deleted file mode 100644 index 7a6a236..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.35.sigs +++ /dev/null @@ -1,99 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_have_events: bool (struct tevent_context *) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_common_threaded_activate_immediate: void (struct tevent_context *) -tevent_common_wakeup: int (struct tevent_context *) -tevent_common_wakeup_fd: int (int) -tevent_common_wakeup_init: int (struct tevent_context *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_num_signals: size_t (void) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_queue_wait_recv: bool (struct tevent_req *) -tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_reset_endtime: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_sa_info_queue_count: size_t (void) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) -tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) -tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_update_timer: void (struct tevent_timer *, struct timeval) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.36.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.36.sigs deleted file mode 100644 index 8a579c8..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.36.sigs +++ /dev/null @@ -1,100 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_have_events: bool (struct tevent_context *) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_common_threaded_activate_immediate: void (struct tevent_context *) -tevent_common_wakeup: int (struct tevent_context *) -tevent_common_wakeup_fd: int (int) -tevent_common_wakeup_init: int (struct tevent_context *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_num_signals: size_t (void) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_entry_untrigger: void (struct tevent_queue_entry *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_queue_wait_recv: bool (struct tevent_req *) -tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_reset_endtime: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_sa_info_queue_count: size_t (void) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) -tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) -tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_update_timer: void (struct tevent_timer *, struct timeval) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.37.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.37.sigs deleted file mode 100644 index f6227db..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.37.sigs +++ /dev/null @@ -1,126 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_context_pop_use: void (struct tevent_context *, const char *) -_tevent_context_push_use: bool (struct tevent_context *, const char *) -_tevent_context_wrapper_create: struct tevent_context *(struct tevent_context *, TALLOC_CTX *, const struct tevent_wrapper_ops *, void *, size_t, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_abort: void (struct tevent_context *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_double_free: void (TALLOC_CTX *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_have_events: bool (struct tevent_context *) -tevent_common_invoke_fd_handler: int (struct tevent_fd *, uint16_t, bool *) -tevent_common_invoke_immediate_handler: int (struct tevent_immediate *, bool *) -tevent_common_invoke_signal_handler: int (struct tevent_signal *, int, int, void *, bool *) -tevent_common_invoke_timer_handler: int (struct tevent_timer *, struct timeval, bool *) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_common_threaded_activate_immediate: void (struct tevent_context *) -tevent_common_wakeup: int (struct tevent_context *) -tevent_common_wakeup_fd: int (int) -tevent_common_wakeup_init: int (struct tevent_context *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_context_is_wrapper: bool (struct tevent_context *) -tevent_context_same_loop: bool (struct tevent_context *, struct tevent_context *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_num_signals: size_t (void) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_entry_untrigger: void (struct tevent_queue_entry *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_queue_wait_recv: bool (struct tevent_req *) -tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_get_profile: const struct tevent_req_profile *(struct tevent_req *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_move_profile: struct tevent_req_profile *(struct tevent_req *, TALLOC_CTX *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_profile_append_sub: void (struct tevent_req_profile *, struct tevent_req_profile **) -tevent_req_profile_create: struct tevent_req_profile *(TALLOC_CTX *) -tevent_req_profile_get_name: void (const struct tevent_req_profile *, const char **) -tevent_req_profile_get_start: void (const struct tevent_req_profile *, const char **, struct timeval *) -tevent_req_profile_get_status: void (const struct tevent_req_profile *, pid_t *, enum tevent_req_state *, uint64_t *) -tevent_req_profile_get_stop: void (const struct tevent_req_profile *, const char **, struct timeval *) -tevent_req_profile_get_subprofiles: const struct tevent_req_profile *(const struct tevent_req_profile *) -tevent_req_profile_next: const struct tevent_req_profile *(const struct tevent_req_profile *) -tevent_req_profile_set_name: bool (struct tevent_req_profile *, const char *) -tevent_req_profile_set_start: bool (struct tevent_req_profile *, const char *, struct timeval) -tevent_req_profile_set_status: void (struct tevent_req_profile *, pid_t, enum tevent_req_state, uint64_t) -tevent_req_profile_set_stop: bool (struct tevent_req_profile *, const char *, struct timeval) -tevent_req_received: void (struct tevent_req *) -tevent_req_reset_endtime: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_req_set_profile: bool (struct tevent_req *) -tevent_sa_info_queue_count: size_t (void) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) -tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) -tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_update_timer: void (struct tevent_timer *, struct timeval) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.38.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.38.sigs deleted file mode 100644 index f6227db..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.38.sigs +++ /dev/null @@ -1,126 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_context_pop_use: void (struct tevent_context *, const char *) -_tevent_context_push_use: bool (struct tevent_context *, const char *) -_tevent_context_wrapper_create: struct tevent_context *(struct tevent_context *, TALLOC_CTX *, const struct tevent_wrapper_ops *, void *, size_t, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_abort: void (struct tevent_context *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_double_free: void (TALLOC_CTX *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_have_events: bool (struct tevent_context *) -tevent_common_invoke_fd_handler: int (struct tevent_fd *, uint16_t, bool *) -tevent_common_invoke_immediate_handler: int (struct tevent_immediate *, bool *) -tevent_common_invoke_signal_handler: int (struct tevent_signal *, int, int, void *, bool *) -tevent_common_invoke_timer_handler: int (struct tevent_timer *, struct timeval, bool *) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_common_threaded_activate_immediate: void (struct tevent_context *) -tevent_common_wakeup: int (struct tevent_context *) -tevent_common_wakeup_fd: int (int) -tevent_common_wakeup_init: int (struct tevent_context *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_context_is_wrapper: bool (struct tevent_context *) -tevent_context_same_loop: bool (struct tevent_context *, struct tevent_context *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_num_signals: size_t (void) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_entry_untrigger: void (struct tevent_queue_entry *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_queue_wait_recv: bool (struct tevent_req *) -tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_get_profile: const struct tevent_req_profile *(struct tevent_req *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_move_profile: struct tevent_req_profile *(struct tevent_req *, TALLOC_CTX *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_profile_append_sub: void (struct tevent_req_profile *, struct tevent_req_profile **) -tevent_req_profile_create: struct tevent_req_profile *(TALLOC_CTX *) -tevent_req_profile_get_name: void (const struct tevent_req_profile *, const char **) -tevent_req_profile_get_start: void (const struct tevent_req_profile *, const char **, struct timeval *) -tevent_req_profile_get_status: void (const struct tevent_req_profile *, pid_t *, enum tevent_req_state *, uint64_t *) -tevent_req_profile_get_stop: void (const struct tevent_req_profile *, const char **, struct timeval *) -tevent_req_profile_get_subprofiles: const struct tevent_req_profile *(const struct tevent_req_profile *) -tevent_req_profile_next: const struct tevent_req_profile *(const struct tevent_req_profile *) -tevent_req_profile_set_name: bool (struct tevent_req_profile *, const char *) -tevent_req_profile_set_start: bool (struct tevent_req_profile *, const char *, struct timeval) -tevent_req_profile_set_status: void (struct tevent_req_profile *, pid_t, enum tevent_req_state, uint64_t) -tevent_req_profile_set_stop: bool (struct tevent_req_profile *, const char *, struct timeval) -tevent_req_received: void (struct tevent_req *) -tevent_req_reset_endtime: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_req_set_profile: bool (struct tevent_req *) -tevent_sa_info_queue_count: size_t (void) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) -tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) -tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_update_timer: void (struct tevent_timer *, struct timeval) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.39.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.39.sigs deleted file mode 100644 index f6227db..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.39.sigs +++ /dev/null @@ -1,126 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_context_pop_use: void (struct tevent_context *, const char *) -_tevent_context_push_use: bool (struct tevent_context *, const char *) -_tevent_context_wrapper_create: struct tevent_context *(struct tevent_context *, TALLOC_CTX *, const struct tevent_wrapper_ops *, void *, size_t, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_req_oom: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_abort: void (struct tevent_context *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_double_free: void (TALLOC_CTX *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_have_events: bool (struct tevent_context *) -tevent_common_invoke_fd_handler: int (struct tevent_fd *, uint16_t, bool *) -tevent_common_invoke_immediate_handler: int (struct tevent_immediate *, bool *) -tevent_common_invoke_signal_handler: int (struct tevent_signal *, int, int, void *, bool *) -tevent_common_invoke_timer_handler: int (struct tevent_timer *, struct timeval, bool *) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_common_threaded_activate_immediate: void (struct tevent_context *) -tevent_common_wakeup: int (struct tevent_context *) -tevent_common_wakeup_fd: int (int) -tevent_common_wakeup_init: int (struct tevent_context *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) -tevent_context_is_wrapper: bool (struct tevent_context *) -tevent_context_same_loop: bool (struct tevent_context *, struct tevent_context *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_num_signals: size_t (void) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_entry_untrigger: void (struct tevent_queue_entry *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_running: bool (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_queue_wait_recv: bool (struct tevent_req *) -tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) -tevent_req_get_profile: const struct tevent_req_profile *(struct tevent_req *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_move_profile: struct tevent_req_profile *(struct tevent_req *, TALLOC_CTX *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_profile_append_sub: void (struct tevent_req_profile *, struct tevent_req_profile **) -tevent_req_profile_create: struct tevent_req_profile *(TALLOC_CTX *) -tevent_req_profile_get_name: void (const struct tevent_req_profile *, const char **) -tevent_req_profile_get_start: void (const struct tevent_req_profile *, const char **, struct timeval *) -tevent_req_profile_get_status: void (const struct tevent_req_profile *, pid_t *, enum tevent_req_state *, uint64_t *) -tevent_req_profile_get_stop: void (const struct tevent_req_profile *, const char **, struct timeval *) -tevent_req_profile_get_subprofiles: const struct tevent_req_profile *(const struct tevent_req_profile *) -tevent_req_profile_next: const struct tevent_req_profile *(const struct tevent_req_profile *) -tevent_req_profile_set_name: bool (struct tevent_req_profile *, const char *) -tevent_req_profile_set_start: bool (struct tevent_req_profile *, const char *, struct timeval) -tevent_req_profile_set_status: void (struct tevent_req_profile *, pid_t, enum tevent_req_state, uint64_t) -tevent_req_profile_set_stop: bool (struct tevent_req_profile *, const char *, struct timeval) -tevent_req_received: void (struct tevent_req *) -tevent_req_reset_endtime: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_req_set_profile: bool (struct tevent_req *) -tevent_sa_info_queue_count: size_t (void) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) -tevent_signal_support: bool (struct tevent_context *) -tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) -tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) -tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) -tevent_update_timer: void (struct tevent_timer *, struct timeval) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.9.sigs b/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.9.sigs deleted file mode 100644 index 9adaba5..0000000 --- a/ldb-2.0.8/lib/tevent/ABI/tevent-0.9.9.sigs +++ /dev/null @@ -1,73 +0,0 @@ -_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) -_tevent_loop_once: int (struct tevent_context *, const char *) -_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) -_tevent_loop_wait: int (struct tevent_context *, const char *) -_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) -_tevent_req_callback_data: void *(struct tevent_req *) -_tevent_req_cancel: bool (struct tevent_req *, const char *) -_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) -_tevent_req_data: void *(struct tevent_req *) -_tevent_req_done: void (struct tevent_req *, const char *) -_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) -_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) -_tevent_req_notify_callback: void (struct tevent_req *, const char *) -_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_backend_list: const char **(TALLOC_CTX *) -tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) -tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) -tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) -tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) -tevent_common_check_signal: int (struct tevent_context *) -tevent_common_context_destructor: int (struct tevent_context *) -tevent_common_fd_destructor: int (struct tevent_fd *) -tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_common_loop_immediate: bool (struct tevent_context *) -tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) -tevent_common_loop_wait: int (struct tevent_context *, const char *) -tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) -tevent_context_init: struct tevent_context *(TALLOC_CTX *) -tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) -tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) -tevent_fd_get_flags: uint16_t (struct tevent_fd *) -tevent_fd_set_auto_close: void (struct tevent_fd *) -tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) -tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) -tevent_loop_allow_nesting: void (struct tevent_context *) -tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) -tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) -tevent_queue_length: size_t (struct tevent_queue *) -tevent_queue_start: void (struct tevent_queue *) -tevent_queue_stop: void (struct tevent_queue *) -tevent_re_initialise: int (struct tevent_context *) -tevent_register_backend: bool (const char *, const struct tevent_ops *) -tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) -tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) -tevent_req_is_in_progress: bool (struct tevent_req *) -tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) -tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) -tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) -tevent_req_received: void (struct tevent_req *) -tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) -tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) -tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) -tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) -tevent_set_abort_fn: void (void (*)(const char *)) -tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) -tevent_set_debug_stderr: int (struct tevent_context *) -tevent_set_default_backend: void (const char *) -tevent_signal_support: bool (struct tevent_context *) -tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) -tevent_timeval_compare: int (const struct timeval *, const struct timeval *) -tevent_timeval_current: struct timeval (void) -tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) -tevent_timeval_is_zero: bool (const struct timeval *) -tevent_timeval_set: struct timeval (uint32_t, uint32_t) -tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) -tevent_timeval_zero: struct timeval (void) -tevent_wakeup_recv: bool (struct tevent_req *) -tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/ldb-2.0.8/lib/tevent/Makefile b/ldb-2.0.8/lib/tevent/Makefile deleted file mode 100644 index 6a3aab0..0000000 --- a/ldb-2.0.8/lib/tevent/Makefile +++ /dev/null @@ -1,52 +0,0 @@ -# simple makefile wrapper to run waf -WAF_BIN=`PATH=buildtools/bin:../../buildtools/bin:$$PATH which waf` -WAF_BINARY=$(PYTHON) $(WAF_BIN) -WAF=PYTHONHASHSEED=1 WAF_MAKE=1 $(WAF_BINARY) - -all: - $(WAF) build - -install: - $(WAF) install - -uninstall: - $(WAF) uninstall - -test: - $(WAF) test $(TEST_OPTIONS) - -dist: - touch .tmplock - WAFLOCK=.tmplock $(WAF) dist - -distcheck: - touch .tmplock - WAFLOCK=.tmplock $(WAF) distcheck - -clean: - $(WAF) clean - -distclean: - $(WAF) distclean - -reconfigure: configure - $(WAF) reconfigure - -show_waf_options: - $(WAF) --help - -# some compatibility make targets -everything: all - -testsuite: all - -check: test - -# this should do an install as well, once install is finished -installcheck: test - -etags: - $(WAF) etags - -ctags: - $(WAF) ctags diff --git a/ldb-2.0.8/lib/tevent/bindings.py b/ldb-2.0.8/lib/tevent/bindings.py deleted file mode 100644 index f5e1499..0000000 --- a/ldb-2.0.8/lib/tevent/bindings.py +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/python -# -# Python integration for tevent - tests -# -# Copyright (C) Jelmer Vernooij 2010 -# -# ** NOTE! The following LGPL license applies to the tevent -# ** library. This does NOT imply that all of Samba is released -# ** under the LGPL -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 3 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, see . - -import signal -from unittest import TestCase, TestProgram -import gc - -import _tevent - - -class BackendListTests(TestCase): - - def test_backend_list(self): - self.assertTrue(isinstance(_tevent.backend_list(), list)) - - -class CreateContextTests(TestCase): - - def test_by_name(self): - ctx = _tevent.Context(_tevent.backend_list()[0]) - self.assertTrue(ctx is not None) - - def test_no_name(self): - ctx = _tevent.Context() - self.assertTrue(ctx is not None) - - -class ContextTests(TestCase): - - def setUp(self): - super(ContextTests, self).setUp() - self.ctx = _tevent.Context() - - def test_signal_support(self): - self.assertTrue(type(self.ctx.signal_support) is bool) - - def test_reinitialise(self): - self.ctx.reinitialise() - - def test_loop_wait(self): - self.ctx.loop_wait() - - def test_add_signal(self): - sig = self.ctx.add_signal(signal.SIGINT, 0, lambda callback: None) - self.assertTrue(isinstance(sig, _tevent.Signal)) - - def test_timer(self): - """Test a timer is can be scheduled""" - collecting_list = [] - # time "0" has already passed, callback will be scheduled immediately - timer = self.ctx.add_timer(0, lambda t: collecting_list.append(True)) - self.assertTrue(timer.active) - self.assertEqual(collecting_list, []) - self.ctx.loop_once() - self.assertFalse(timer.active) - self.assertEqual(collecting_list, [True]) - - def test_timer_deallocate_timer(self): - """Test timer is scheduled even if reference to it isn't held""" - collecting_list = [] - - def callback(t): - collecting_list.append(True) - timer = self.ctx.add_timer(0, lambda t: collecting_list.append(True)) - gc.collect() - self.assertEqual(collecting_list, []) - self.ctx.loop_once() - self.assertEqual(collecting_list, [True]) - - def test_timer_deallocate_context(self): - """Test timer is unscheduled when context is freed""" - collecting_list = [] - - def callback(t): - collecting_list.append(True) - timer = self.ctx.add_timer(0, lambda t: collecting_list.append(True)) - self.assertTrue(timer.active) - del self.ctx - gc.collect() - self.assertEqual(collecting_list, []) - self.assertFalse(timer.active) - - def test_timer_offset(self): - """Test scheduling timer with an offset""" - collecting_list = [] - self.ctx.add_timer_offset(0.2, lambda t: collecting_list.append(2)) - self.ctx.add_timer_offset(0.1, lambda t: collecting_list.append(1)) - self.assertEqual(collecting_list, []) - self.ctx.loop_once() - self.assertEqual(collecting_list, [1]) - self.ctx.loop_once() - self.assertEqual(collecting_list, [1, 2]) - - -if __name__ == '__main__': - TestProgram() diff --git a/ldb-2.0.8/lib/tevent/configure b/ldb-2.0.8/lib/tevent/configure deleted file mode 100755 index c3c4447..0000000 --- a/ldb-2.0.8/lib/tevent/configure +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -PREVPATH=`dirname $0` - -if [ -f $PREVPATH/../../buildtools/bin/waf ]; then - WAF=../../buildtools/bin/waf -elif [ -f $PREVPATH/buildtools/bin/waf ]; then - WAF=./buildtools/bin/waf -else - echo "tevent: Unable to find waf" - exit 1 -fi - -# using JOBS=1 gives maximum compatibility with -# systems like AIX which have broken threading in python -JOBS=1 -export JOBS - -cd . || exit 1 -$PYTHON $WAF configure "$@" || exit 1 -cd $PREVPATH diff --git a/ldb-2.0.8/lib/tevent/doc/img/tevent_context_stucture.png b/ldb-2.0.8/lib/tevent/doc/img/tevent_context_stucture.png deleted file mode 100644 index fba8161572d5af6b18e266e88cc2eb20ac76c495..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21888 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 diff --git a/ldb-2.0.8/lib/tevent/doc/img/tevent_subrequest.png b/ldb-2.0.8/lib/tevent/doc/img/tevent_subrequest.png deleted file mode 100644 index ea79223d4dc1f6c524d40b566e9895003ec4df34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22453 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 directory - * on the samba public source archive. - * - * @section main_tevent_bugs Discussion and bug reports - * - * tevent does not currently have its own mailing list or bug tracking system. - * For now, please use the - * samba-technical - * mailing list, and the - * Samba bugzilla - * bug tracking system. - * - * @section main_tevent_devel Development - * You can download the latest code either via git or rsync. - * - * To fetch via git see the following guide: - * - * Using Git for Samba Development - * - * Once you have cloned the tree switch to the master branch and cd into the - * lib/tevent directory. - * - * To fetch via rsync use this command: - * - * rsync -Pavz samba.org::ftp/unpacked/standalone_projects/lib/tevent . - * - */ diff --git a/ldb-2.0.8/lib/tevent/doc/tevent_context.dox b/ldb-2.0.8/lib/tevent/doc/tevent_context.dox deleted file mode 100644 index 39eb85e..0000000 --- a/ldb-2.0.8/lib/tevent/doc/tevent_context.dox +++ /dev/null @@ -1,75 +0,0 @@ -/** -@page tevent_context Chapter 1: Tevent context - -@section context Tevent context - -Tevent context is an essential logical unit of tevent library. For working with -events at least one such context has to be created - allocated, initialized. -Then, events which are meant to be caught and handled have to be registered -within this specific context. Reason for subordinating events to a tevent -context structure rises from the fact that several context can be created and -each of them is processed at different time. So, there can be 1 context -containing just file descriptor events, another one taking care of signal and -time events and the third one which keeps information about the rest. - -Tevent loops are the part of the library which represents the mechanism where -noticing events and triggering handlers actually happens. They accept just one -argument - tevent context structure. Therefore if theoretically an infinity -loop (tevent_loop_wait) was called, only those arguments which belong to the -passed tevent context structure can be caught and invoked within this call. -Although some more signal events were registered (but within some other -context) they will not be noticed. - -@subsection Example - -First lines which handle mem_ctx belong to talloc library -knowledge but because of the fact that tevent uses the talloc library for its -mechanisms it is necessary to understand a bit talloc as well. For more -information about working with talloc, please visit talloc website where tutorial and -documentation are located. - -Tevent context structure *event_ctx represents the unit which will -further contain information about registered events. It is created via calling -tevent_context_init(). - -@code -TALLOC_CTX *mem_ctx = talloc_new(NULL); -if (mem_ctx == NULL) { - // error handling -} - -struct tevent_context *ev_ctx = tevent_context_init(mem_ctx); -if(ev_ctx == NULL) { - // error handling -} -@endcode - -Tevent context has a structure containing lots of information. It include lists -of all events which are divided according their type and are in order showing -the sequence as they came. - -@image html tevent_context_stucture.png - -In addition to the lists shown in the diagram, the tevent context also contains -many other data (e.g. information about the available system mechanism for -triggering callbacks). - -@section tevent_loops Tevent loops - -Tevent loops are the dispatcher for events. They catch them and trigger the -handlers. In the case of longer processes, the program spends most of its time -at this point waiting for events, invoking handlers and waiting for another -event again. There are 2 types of loop available for use in tevent library: - -
        -
      • int tevent_loop_wait()
      • -
      • int tevent_loop_once()
      • -
      - -Both of functions accept just one parameter (tevent context) and the only -difference lies in the fact that the first loop can theoretically last for ever -but the second one will wait just for a single one event to catch and then the -loop breaks and the program continue. - -*/ diff --git a/ldb-2.0.8/lib/tevent/doc/tevent_data.dox b/ldb-2.0.8/lib/tevent/doc/tevent_data.dox deleted file mode 100644 index dbe7a04..0000000 --- a/ldb-2.0.8/lib/tevent/doc/tevent_data.dox +++ /dev/null @@ -1,137 +0,0 @@ -/** -@page tevent_data Chapter 3: Accessing data -@section data Accessing data with tevent - -A tevent request is (usually) created together with a structure for storing the -data necessary for an asynchronous computation. For these private data, tevent -library uses void (generic) pointers, therefore any data type can be very -simply pointed at. However, this attitude requires clear and guaranteed -knowledge of the data type that will be handled, in advance. Private data can -be of 2 types: connected with a request itself or given as an individual -argument to a callback. It is necessary to differentiate these types, because -there is a slightly different method of data access for each. There are two -possibilities how to access data that is given as an argument directly to a -callback. The difference lies in the pointer that is returned. In one case it -is the data type specified in the function’s argument, in another void* is -returned. - -@code -void tevent_req_callback_data (struct tevent_req *req, #type) -void tevent_req_callback_data_void (struct tevent_req *req) -@endcode - - -To obtain data that are strictly bound to a request, this function is the only -direct procedure. - -@code -void *tevent_req_data (struct tevent_req *req, #type) -@endcode - -Example with both calls which differs between private data within tevent -request and data handed over as an argument. - -@code -#include -#include -#include - -struct foo_state { - int x; -}; - -struct testA { - int y; -}; - - -static void foo_done(struct tevent_req *req) { - // a->x contains 10 since it came from foo_send - struct foo_state *a = tevent_req_data(req, struct foo_state); - - // b->y contains 9 since it came from run - struct testA *b = tevent_req_callback_data(req, struct testA); - - // c->y contains 9 since it came from run we just used a different way - // of getting it. - struct testA *c = (struct testA *)tevent_req_callback_data_void(req); - - printf("a->x: %d\n", a->x); - printf("b->y: %d\n", b->y); - printf("c->y: %d\n", c->y); -} - - -struct tevent_req * foo_send(TALLOC_CTX *mem_ctx, struct tevent_context *event_ctx) { - -printf("_send\n"); -struct tevent_req *req; -struct foo_state *state; - -req = tevent_req_create(event_ctx, &state, struct foo_state); -state->x = 10; - -return req; -} - -static void run(struct tevent_context *ev, struct tevent_timer *te, - struct timeval current_time, void *private_data) { - struct tevent_req *req; - struct testA *tmp = talloc(ev, struct testA); - - // Note that we did not use the private data passed in - - tmp->y = 9; - req = foo_send(ev, ev); - - tevent_req_set_callback(req, foo_done, tmp); - tevent_req_done(req); - -} - -int main (int argc, char **argv) { - - struct tevent_context *event_ctx; - struct testA *data; - TALLOC_CTX *mem_ctx; - struct tevent_timer *time_event; - - mem_ctx = talloc_new(NULL); //parent - if (mem_ctx == NULL) - return EXIT_FAILURE; - - event_ctx = tevent_context_init(mem_ctx); - if (event_ctx == NULL) - return EXIT_FAILURE; - - data = talloc(mem_ctx, struct testA); - data->y = 11; - - time_event = tevent_add_timer(event_ctx, - mem_ctx, - tevent_timeval_current(), - run, - data); - if (time_event == NULL) { - fprintf(stderr, " FAILED\n"); - return EXIT_FAILURE; - } - - tevent_loop_once(event_ctx); - - talloc_free(mem_ctx); - - printf("Quit\n"); - return EXIT_SUCCESS; -} -@endcode - -Output of this example is: - -@code -a->x: 10 -b->y: 9 -c->y: 9 -@endcode - -*/ diff --git a/ldb-2.0.8/lib/tevent/doc/tevent_events.dox b/ldb-2.0.8/lib/tevent/doc/tevent_events.dox deleted file mode 100644 index d56af25..0000000 --- a/ldb-2.0.8/lib/tevent/doc/tevent_events.dox +++ /dev/null @@ -1,341 +0,0 @@ -/** -@page tevent_events Chapter 2: Tevent events -@section pools Tevent events - -Ok, after reading previous chapter we can start doing something useful. So, the -way of creating events is similar for all types - signals, file descriptors, -time or immediate events. At the beginning it is good to know about some -typedefs which are set in tevent library and which specify the arguments for -each callback. These callbacks are: - -- tevent_timer_handler_t() - -- tevent_immediate_handler_t() - -- tevent_signal_handler_t() - -- tevent_fd_handler_t() - -According their names it is obvious that for creating callback for e.g. time -event, tevent_timer_handler_t will be used. - -The best way how to introduce registering an event and setting up a callback -would be example, so examples describing all the types of events follow. - -@subsection Time Time event - -This example shows how to set up an event which will be repeated for a minute -with interval of 2 seconds (will be triggered 30 times). After exceeding this -limit, the event loop will finish and all the memory resources will be freed. -This is just example describing repeated activity, nothing usefull is done -within foo function - -@code -#include -#include -#include -#include - -struct state { - struct timeval endtime; - int counter; - TALLOC_CTX *ctx; -}; - -static void callback(struct tevent_context *ev, struct tevent_timer *tim, - struct timeval current_time, void *private_data) -{ - struct state *data = talloc_get_type_abort(private_data, struct state); - struct tevent_timer *time_event; - struct timeval schedule; - - printf("Data value: %d\n", data->counter); - data->counter += 1; // increase counter - - // if time has not reached its limit, set another event - if (tevent_timeval_compare(¤t_time, &(data->endtime)) < 0) { - // do something - // set repeat with delay 2 seconds - schedule = tevent_timeval_current_ofs(2, 0); - time_event = tevent_add_timer(ev, data->ctx, schedule, callback, data); - if (time_event == NULL) { // error ... - fprintf(stderr, "MEMORY PROBLEM\n"); - return; - } - } else { - // time limit exceeded - } -} - -int main(void) { - struct tevent_context *event_ctx; - TALLOC_CTX *mem_ctx; - struct tevent_timer *time_event; - struct timeval schedule; - - mem_ctx = talloc_new(NULL); // parent - event_ctx = tevent_context_init(mem_ctx); - - struct state *data = talloc(mem_ctx, struct state); - - schedule = tevent_timeval_current_ofs(2, 0); // +2 second time value - data->endtime = tevent_timeval_add(&schedule, 60, 0); // one minute time limit - data->ctx = mem_ctx; - data->counter = 0; - - // add time event - time_event = tevent_add_timer(event_ctx, mem_ctx, schedule, callback, data); - if (time_event == NULL) { - fprintf(stderr, "FAILED\n"); - return EXIT_FAILURE; - } - - tevent_loop_wait(event_ctx); - talloc_free(mem_ctx); - return EXIT_SUCCESS; -} -@endcode - -Variable counter is only used for counting the number of triggered -functions. List of all available functions which tevent offers for working with -time are listed -here together -with their description. More detailed view at these functions is unnecessary -because their purpose and usage is quite simple and clear. - -@subsection Immediate Immediate event - -These events are, as their name indicates, activated and performed immediately. -It means that this kind of events have priority over others (except signal -events). So if there is a bulk of events registered and after that a -tevent loop is launched, then all the immediate events will be triggered before -the other events. Except other immediate events (and signal events) because -they are also processed sequentially - according the order they were scheduled. -Signals have the highest priority and therefore they are processed -preferentially. Therefore the expression immediate may not correspond exactly -to the dictionary definition of "something without delay" but rather "as soon -as possible" after all preceding immediate events. - -For creating an immediate event there is a small different which lies in the -fact that the creation of such event is done in 2 steps. One represents the -creation (memory allocation), the second one represents registering as the -event within some tevent context. - -@code -struct tevent_immediate *run(TALLOC_CTX* mem_ctx, - struct tevent_context event_ctx, - void * data) -{ - struct tevent_immediate *im; - - im = tevent_create_immediate(mem_ctx); - if (im == NULL) { - return NULL; - } - tevent_schedule_immediate(im, event_ctx, foo, data); - - return im; -} -@endcode - -Example which may be compiled and run representing the creation of immediate event. - -@code - -#include -#include -#include - -struct info_struct { - int counter; -}; - -static void foo(struct tevent_context *ev, struct tevent_immediate *im, - void *private_data) -{ - struct info_struct *data = talloc_get_type_abort(private_data, struct info_struct); - printf("Data value: %d\n", data->counter); -} - -int main (void) { - struct tevent_context *event_ctx; - TALLOC_CTX *mem_ctx; - struct tevent_immediate *im; - - printf("INIT\n"); - - mem_ctx = talloc_new(NULL); - event_ctx = tevent_context_init(mem_ctx); - - struct info_struct *data = talloc(mem_ctx, struct info_struct); - - // setting up private data - data->counter = 1; - - // first immediate event - im = tevent_create_immediate(mem_ctx); - if (im == NULL) { - fprintf(stderr, "FAILED\n"); - return EXIT_FAILURE; - } - tevent_schedule_immediate(im, event_ctx, foo, data); - - tevent_loop_wait(event_ctx); - talloc_free(mem_ctx); - - return 0; -} -@endcode - -@subsection Signal Signal event - -This is an alternative to standard C library functions signal() or sigaction(). -The main difference that distinguishes these ways of treating signals is their -setting up of handlers for different time intervals of the running program. - -While standard C library methods for dealing with signals offer sufficient -tools for most cases, they are inadequate for handling signals within the -tevent loop. It could be necessary to finish certain tevent requests within the -tevent loop without interruption. If a signal was sent to a program at a moment -when the tevent loop is in progress, a standard signal handler would not return -processing to the application at the very same place and it would quit the -tevent loop for ever. In such cases, tevent signal handlers offer the -possibility of dealing with these signals by masking them from the rest of -application and not quitting the loop, so the other events can still be -processed. - -Tevent offers also a control function, which enables us to verify whether it is -possible to handle signals via tevent, is defined within tevent library and it -returns a boolean value revealing the result of the verification. - -@code -bool tevent_signal_support (struct tevent_context *ev) -@endcode - -Checking for signal support is not necessary, but if it is not guaranteed, this -is a good and easy control to prevent unexpected behaviour or failure of the -program occurring. Such a test of course does not have to be run every single -time you wish to create a signal handler, but simply at the beginning - during -the initialization procedures of the program. Afterthat, simply adapt to each -situation that arises. - -@code - -#include -#include -#include - -static void handler(struct tevent_context *ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - void *private_data) -{ - - // Do something usefull - - printf("handling signal...\n"); - exit(EXIT_SUCCESS); -} - -int main (void) -{ - struct tevent_context *event_ctx; - TALLOC_CTX *mem_ctx; - struct tevent_signal *sig; - - mem_ctx = talloc_new(NULL); //parent - if (mem_ctx == NULL) { - fprintf(stderr, "FAILED\n"); - return EXIT_FAILURE; - } - - event_ctx = tevent_context_init(mem_ctx); - if (event_ctx == NULL) { - fprintf(stderr, "FAILED\n"); - return EXIT_FAILURE; - } - - if (tevent_signal_support(event_ctx)) { - // create signal event - sig = tevent_add_signal(event_ctx, mem_ctx, SIGINT, 0, handler, NULL); - if (sig == NULL) { - fprintf(stderr, "FAILED\n"); - return EXIT_FAILURE; - } - tevent_loop_wait(event_ctx); - } - - talloc_free(mem_ctx); - return EXIT_SUCCESS; -} -@endcode - - -@subsection File File descriptor event - -Support of events on file descriptors is mainly useful for socket communication -but it certainly works flawlessly with standard streams (stdin, stdout, stderr) - as well. Working asynchronously with file descriptors enables switching - within processing I/O operations. This ability may rise with a greater - number of I/O operations and such overlapping leads to enhancement of the - throughput. - -There are several other functions included in tevent API related to handling -file descriptors (there are too many functions defined within tevent therefore -just some of them are fully described within this thesis. The -declaration of the rest can be easily found on the library’s website or -directly from the source code): - -
        -
      • tevent_fd_set_close_fn() - can add another function to be called at the - moment when a structure tevent fd is freed.
      • -
      • tevent_fd_set_auto_close() - calling this function can simplify the - maintenance of file descriptors, because it instructs tevent to close the - appropriate file descriptor when the tevent fd structure is about to be - freed.
      • -
      • tevent_fd_get_flags() - returns flags which are set on the file descriptor - connected with this tevent fd structure.
      • -
      • tevent_fd_set_flags() - sets specified flags on the event’s file - descriptor.
      • -
      - -@code - -static void close_fd(struct tevent_context *ev, struct tevent_fd *fd_event, - int fd, void *private_data) -{ - // processing when fd_event is freed -} - -struct static void handler(struct tevent_context *ev, - struct tevent_fd *fde, - uint16_t flags, - void *private_data) -{ - // handling event; reading from a file descriptor - tevent_fd_set_close_fn (fd_event, close_fd); -} - -int run(TALLOC_CTX *mem_ctx, struct tevent_context *event_ctx, - int fd, uint16_t flags, char *buffer) -{ - struct tevent_fd* fd_event = NULL; - - if (flags & TEVENT_FD_READ) { - fd_event = tevent_add_fd(event_ctx, - mem_ctx, - fd, - flags, - handler, - buffer); - } - if (fd_event == NULL) { - // error handling - } - return tevent_loop_once(); -} -@endcode - -*/ diff --git a/ldb-2.0.8/lib/tevent/doc/tevent_queue.dox b/ldb-2.0.8/lib/tevent/doc/tevent_queue.dox deleted file mode 100644 index 9c247e5..0000000 --- a/ldb-2.0.8/lib/tevent/doc/tevent_queue.dox +++ /dev/null @@ -1,275 +0,0 @@ -/** -@page tevent_queue Chapter 5: Tevent queue -@section queue Tevent queue - -There is a possibility that the dispatcher and its handlers may not be able to -handle all the incoming events as quickly as they arrive. One way to deal with -this situation is to buffer the received events by introducing an event queue -into the events stream, between the events generator and the dispatcher. Events -are added to the queue as they arrive, and the dispatcher pops them off the -beginning of the queue as fast as possible. In tevent library it is -similar, but the queue is not automatically set for any event. The queue has to -be created on purpose, and events which should follow the order of the FIFO -queue have to be explicitly pinpointed. Creating such a queue is crucial in -situations when sequential processing is absolutely essential for the -successful -completion of a task, e.g. for a large quantity of data that are about to be -written from a buffer into a socket. The tevent library has its own queue -structure that is ready to use after it has been initialized and started up -once. - -@subsection cr_queue Creation of Queues - -The first and most important step is the creation of the tevent queue -(represented by struct tevent_queue), which will then be in running mode. - -@code -struct tevent_queue* tevent_queue_create (TALLOC_CTX *mem_ctx, const char *name) -@endcode - -When the program returns from this function, the allocated memory, set -destructor and labeled queue as running has been done and the structure is -ready to be filled with entries. Stopping and starting queues on the run. If -you need to stop a queue from processing its entries, and then turn it on -again, a couple of functions which serve this purpose are: - -- bool tevent_queue_stop() -- bool tevent_queue_start() - -These functions actually only provide for the simple setting of a variable, -which indicates that the queue has been stopped/started. Returned value -indicates result. - -@subsection add_queue Adding Requests to a Queue - -Tevent in fact offers 3 possible ways of inserting a request into a queue. -There are no vast differences between them, but still there might be situations -where one of them is more suitable and desired than another. - -@code -bool tevent_queue_add(struct tevent_queue *queue, - struct tevent_context *ev, - struct tevent_req *req, - tevent_queue_trigger_fn_t trigger, - void *private_data) -@endcode - -This call is the simplest of all three. It offers only boolean verification of -whether the operation of adding the request into a queue was successful or not. -No additional deletion of an item from the queue is possible, i.e. it is only -possible to deallocate the whole tevent request, which would cause triggering -of destructor handling and also dropping the request from the queue. - -Extended Options - -Both of the following functions have a feature in common - they return tevent -queue entry structure representing the item in a queue. There is no further -possible handling with this structure except the use of the structure’s pointer -for its deallocation (which leads also its removal from the queue). The -difference lies in the possibility that with the following functions it is -possible to remove the tevent request from a queue without its deallocation. -The previous function can only deallocate the tevent request as it was from -memory, and thereby logically cause its removal from the queue as well. There -is no other utilization of this structure via API at this stage of tevent -library. The possibility of easier debugging while developing with tevent could -be considered to be an advantage of this returned pointer. - -@code -struct tevent_queue_entry *tevent_queue_add_entry(struct tevent_queue *queue, - struct tevent_context *ev, - struct tevent_req *req, - tevent_queue_trigger_fn_t trigger, - void *private_data) -@endcode - -The feature that allows for the optimized addition of entries to a queue is -that a check for an empty queue with no items is first of all carried out. If -it is found that the queue is empty, then the request for inserting the entry -into a queue will be omitted and directly triggered. - -@code -struct tevent_queue_entry *tevent_queue_add_optimize_empty(struct tevent_queue *queue, - struct tevent_context *ev, - struct tevent_req *req, - tevent_queue_trigger_fn_t trigger, - void *private_data) -@endcode - -When calling any of the functions serving for inserting an item into a queue, -it is possible to leave out the fourth argument (trigger) and instead of a -function pass a NULL pointer. This usage sets so-called blocking entries. -These entries, since they do not have any trigger operation to be activated, -just sit in their position until they are labeled as a done by another -function. Their purpose is to block other items in the queue from being -triggered. - -@subsection example_q Example of tevent queue - -@code -#include -#include -#include - -struct foo_state { - int local_var; - int x; -}; - -struct juststruct { - TALLOC_CTX * ctx; - struct tevent_context *ev; - int y; -}; - -int created = 0; - -static void timer_handler(struct tevent_context *ev, struct tevent_timer *te, - struct timeval current_time, void *private_data) -{ - // time event which after all sets request as done. Following item from - // the queue may be invoked. - struct tevent_req *req = private_data; - struct foo_state *stateX = tevent_req_data(req, struct foo_state); - - // processing some stuff - - printf("time_handler\n"); - - tevent_req_done(req); - talloc_free(req); - - printf("Request #%d set as done.\n", stateX->x); -} - -static void trigger(struct tevent_req *req, void *private_data) -{ - struct juststruct *priv = tevent_req_callback_data (req, struct juststruct); - struct foo_state *in = tevent_req_data(req, struct foo_state); - struct timeval schedule; - struct tevent_timer *tim; - schedule = tevent_timeval_current_ofs(1, 0); - printf("Processing request #%d\n", in->x); - - if (in->x % 3 == 0) { // just example; third request does not contain - // any further operation and will be finished right - // away. - tim = NULL; - } else { - tim = tevent_add_timer(priv->ev, req, schedule, timer_handler, req); - } - - if (tim == NULL) { - tevent_req_done(req); - talloc_free(req); - printf("Request #%d set as done.\n", in->x); - } -} - -struct tevent_req *foo_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - const char *name, int num) -{ - struct tevent_req *req; - struct foo_state *state; - struct foo_state *in; - struct tevent_timer *tim; - - printf("foo_send\n"); - req = tevent_req_create(mem_ctx, &state, struct foo_state); - if (req == NULL) { // check for appropriate allocation - tevent_req_error(req, 1); - return NULL; - } - - // exemplary filling of variables - state->local_var = 1; - state->x = num; - - return req; -} - -static void foo_done(struct tevent_req *req) { - - enum tevent_req_state state; - uint64_t err; - - if (tevent_req_is_error(req, &state, &err)) { - printf("ERROR WAS SET %d\n", state); - return; - } else { - // processing some stuff - printf("Callback is done...\n"); - } -} - -int main (int argc, char **argv) -{ - TALLOC_CTX *mem_ctx; - struct tevent_req* req[6]; - struct tevent_req* tmp; - struct tevent_context *ev; - struct tevent_queue *fronta = NULL; - struct juststruct *data; - int ret; - int i = 0; - - const char * const names[] = { - "first", "second", "third", "fourth", "fifth" - }; - - printf("INIT\n"); - - mem_ctx = talloc_new(NULL); //parent - talloc_parent(mem_ctx); - ev = tevent_context_init(mem_ctx); - if (ev == NULL) { - fprintf(stderr, "MEMORY ERROR\n"); - return EXIT_FAILURE; - } - - // setting up queue - fronta = tevent_queue_create(mem_ctx, "test_queue"); - tevent_queue_stop(fronta); - tevent_queue_start(fronta); - if (tevent_queue_running(fronta)) { - printf ("Queue is runnning (length: %d)\n", tevent_queue_length(fronta)); - } else { - printf ("Queue is not runnning\n"); - } - - data = talloc(ev, struct juststruct); - data->ctx = mem_ctx; - data->ev = ev; - - - // create 4 requests - for (i = 1; i < 5; i++) { - req[i] = foo_send(mem_ctx, ev, names[i], i); - tmp = req[i]; - if (req[i] == NULL) { - fprintf(stderr, "Request error! %d \n", ret); - break; - } - tevent_req_set_callback(req[i], foo_done, data); - created++; - } - - // add item to a queue - tevent_queue_add(fronta, ev, req[1], trigger, data); - tevent_queue_add(fronta, ev, req[2], trigger, data); - tevent_queue_add(fronta, ev, req[3], trigger, data); - tevent_queue_add(fronta, ev, req[4], trigger, data); - - printf("Queue length: %d\n", tevent_queue_length(fronta)); - while(tevent_queue_length(fronta) > 0) { - tevent_loop_once(ev); - printf("Queue: %d items left\n", tevent_queue_length(fronta)); - } - - talloc_free(mem_ctx); - printf("FINISH\n"); - - return EXIT_SUCCESS; -} -@endcode - -*/ diff --git a/ldb-2.0.8/lib/tevent/doc/tevent_request.dox b/ldb-2.0.8/lib/tevent/doc/tevent_request.dox deleted file mode 100644 index e1e45b1..0000000 --- a/ldb-2.0.8/lib/tevent/doc/tevent_request.dox +++ /dev/null @@ -1,189 +0,0 @@ -/** -@page tevent_request Chapter 4: Tevent request -@section request Tevent request - -A specific feature of the library is the tevent request API that provides for -asynchronous computation and allows much more interconnected working and -cooperation among functions and events. When working with tevent request it -is possible to nest one event under another and handle them bit by bit. This -enables the creation of sequences of steps, and provides an opportunity to -prepare for all problems which may unexpectedly happen within the different -phases. One way or another, subrequests split bigger tasks into smaller ones -which allow a clearer view of each task as a whole. - -@subsection name Naming conventions - -There is a naming convention which is not obligatory but it is followed in this -tutorial: - -- Functions triggered before the event happens. These establish a request. -- \b foo_send(...) - this function is called first and it includes the - creation of tevent request - tevent req structure. It does not block - anything, it simply creates a request, sets a callback (foo done) and lets - the program continue -- Functions as a result of event. -- \b foo_done(...) - this function contains code providing for handling itself - and based upon its results, the request is set either as a done or, if an - error occurs, the request is set as a failure. -- \b foo_recv(...) - this function contains code which should, if demanded, - access the result data and make them further visible. The foo state should - be deallocated from memory when the request’s processing is over and - therefore all computed data up to this point would be lost. - -As was already mentioned, specific naming subsumes not only functions but also -the data themselves: - -- \b foo_state - this is a structure. It contains all the data necessary for - the asynchronous task. - -@subsection cr_req Creating a New Asynchronous Request - -The first step for working asynchronously is the allocation of memory -requirements. As in previous cases, the talloc context is required, upon which -the asynchronous request will be tied. The next step is the creation of the -request itself. - -@code -struct tevent_req* tevent_req_create (TALLOC_CTX *mem_ctx, void **pstate, #type) -@endcode - -The pstate is the pointer to the private data. The necessary amount of memory -(based on data type) is allocated during this call. Within this same memory -area all the data from the asynchronous request that need to be preserved for -some time should be kept. - -Dealing with a lack of memory - -The verification of the returned pointer against NULL is necessary in order to -identify a potential lack of memory. There is a special function which helps -with this check tevent_req_nomem(). - -It handles verification both of the talloc memory allocation and of the -associated tevent request, and is therefore a very useful function for avoiding -unexpected situations. It can easily be used when checking the availability of -further memory resources that are required for a tevent request. Imagine an -example where additional memory needs arise although no memory resources are -currently available. - -@code -bar = talloc(mem_ctx, struct foo); -if(tevent_req_nomem (bar, req)) { - // handling a problem -} -@endcode - -This code ensures that the variable bar, which contains NULL as a result of the -unsuccessful satisfaction of its memory requirements, is noticed, and also that -the tevent request req declares it exceeds memory capacity, which implies the -impossibility of finishing the request as originally programmed. - - -@subsection fini_req Finishing a Request - -Marking each request as finished is an essential principle of the tevent -library. Without marking the request as completed - either successfully or with -an error - the tevent loop could not let the appropriate callback be triggered. -It is important to understand that this would be a significant threat, because -it is not usually a question of one single function which prints some text on a -screen, but rather the request is itself probably just a link in a series of -other requests. Stopping one request would stop the others, memory resources -would not be freed, file descriptors might remain open, communication via -socket could be interrupted, and so on. Therefore it is important to think -about finishing requests, either successfully or not, and also to prepare -functions for all possible scenarios, so that the the callbacks do not process -data that are actually invalid or, even worse, in fact non-existent meaning -that a segmentation fault may arise. - -
        -
      • \b Manually - This is the most common type of finishing request. Calling -this function sets the request as a TEVENT_REQ_DONE. This is the only purpose -of this function and it should be used when everything went well. Typically it -is used within the done functions. - -@code -void tevent_req_done (struct tevent_req *req) -@endcode -Alternatively, the request can end up being unsuccessful. -@code -bool tevent_req_error (struct tevent_req *req, uint64_t error) -@endcode - -The second argument takes the number of an error (declared by the programmer, -for example in an enumerated variable). The function tevent_req_error() sets -the status of the request as a TEVENT_REQ_USER_ERROR and also stores the code -of error within the structure so it can be used, for example for debugging. The -function returns true, if marking the request as an error was processed with no -problem - value error passed to this function is not equal to 1.
      • - -
      • -Setting up a timeout for request - A request can be finished virtually, -or if the process takes too much time, it can be timed out. This is considered -as an error of the request and it leads to calling callback. In the -background, this timeout is set through a time event (described in -@subpage tevent_events ) which eventually triggers an operation marking the -request as a TEVENT_REQ_TIMED_OUT (can not be considered as successfully -finished). In case a time out was already set, this operation will overwrite it -with a new time value (so the timeout may be lengthened) and if everything is -set properly, it returns true. - -@code -bool tevent_req_set_endtime(struct tevent_req *req, - struct tevent_context *ev, - struct timeval endtime); -@endcode -
      • - - -
      • Premature Triggering - Imagine a situation in which some part of a -nested subrequest ended up with a failure and it is still required to trigger a -callback. Such as example might result from lack of memory leading to the -impossibility of allocating enough memory requirements for the event to start -processing another subrequest, or from a clear intention to skip other -procedures and trigger the callback regardless of other progress. In these -cases, the function tevent_req_post() is very handy and offers this option. - -@code -struct tevent_req* tevent_req_post (struct tevent_req *req, - struct tevent_context *ev); -@endcode - -A request finished in this way does not behave as a time event nor as a file -descriptor event but as a immediately scheduled event, and therefore it will be -treated according the description laid down in @subpage tevent_events . -
      • -
      - - -@section nested Subrequests - Nested Requests - -To create more complex and interconnected asynchronous operations, it is -possible to submerge a request into another and thus create a so-called -subrequest. Subrequests are not represented by any other special structure but -they are created from tevent_req_create(). This diagram shows the nesting and -life time of each request. The table below describes the same in words, and -shows the triggering of functions during the application run. - -Wrapper represents the trigger of the whole cascade of (sub)requests. It -may be e.g. a time or file descriptor event, or another request that was -created at a specific time by the function tevent_wakeup_send() which is a -slightly exceptional method of creating - -@code -struct tevent_req *tevent_wakeup_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct timeval wakeup_time); -@endcode - -By calling this function, it is possible to create a tevent request which is -actually the return value of this function. In summary, it sets the time value -of the tevent request’s creation. While using this function it is necessary to -use another function in the subrequest’s callback to check for any problems -tevent_wakeup_recv() ) - -@image html tevent_subrequest.png - -A comprehensive example of nested subrequests can be found in the file -echo_server.c. It implements a complete, self-contained echo server with no -dependencies but libevent and libtalloc. - -*/ diff --git a/ldb-2.0.8/lib/tevent/doc/tevent_thread.dox b/ldb-2.0.8/lib/tevent/doc/tevent_thread.dox deleted file mode 100644 index 875dae8..0000000 --- a/ldb-2.0.8/lib/tevent/doc/tevent_thread.dox +++ /dev/null @@ -1,322 +0,0 @@ -/** -@page tevent_thread Chapter 6: Tevent with threads - -@section threads Tevent with threads - -In order to use tevent with threads, you must first understand -how to use the talloc library in threaded programs. For more -information about working with talloc, please visit talloc website where tutorial and -documentation are located. - -If a tevent context structure is talloced from a NULL, thread-safe talloc -context, then it can be safe to use in a threaded program. The function -talloc_disable_null_tracking() must be called from the initial -program thread before any talloc calls are made to ensure talloc is thread-safe. - -Each thread must create it's own tevent context structure as follows -tevent_context_init(NULL) and no talloc memory contexts -can be shared between threads. - -Separate threads using tevent in this way can communicate -by writing data into file descriptors that are being monitored -by a tevent context on another thread. For example (simplified -with no error handling): - -@code -Main thread: - -main() -{ - talloc_disable_null_tracking(); - - struct tevent_context *master_ev = tevent_context_init(NULL); - void *mem_ctx = talloc_new(master_ev); - - // Create file descriptor to monitor. - int pipefds[2]; - - pipe(pipefds); - - struct tevent_fd *fde = tevent_add_fd(master_ev, - mem_ctx, - pipefds[0], // read side of pipe - TEVENT_FD_READ, - pipe_read_handler, // callback function - private_data_pointer); - - // Create sub thread, pass pipefds[1] write side of pipe to it. - // The above code not shown here.. - - // Process events. - tevent_loop_wait(master_ev); - - // Cleanup if loop exits. - talloc_free(master_ev); -} - -@endcode - -When the subthread writes to pipefds[1], the function -pipe_read_handler() will be called in the main thread. - -@subsection More sophisticated use - -A popular way to use an event library within threaded programs -is to allow a sub-thread to asynchronously schedule a tevent_immediate -function call from the event loop of another thread. This can be built -out of the basic functions and isolation mechanisms of tevent, -but tevent also comes with some utility functions that make -this easier, so long as you understand the limitations that -using threads with talloc and tevent impose. - -To allow a tevent context to receive an asynchronous tevent_immediate -function callback from another thread, create a struct tevent_thread_proxy * -by calling @code - -struct tevent_thread_proxy *tevent_thread_proxy_create( - struct tevent_context *dest_ev_ctx); - -@endcode - -This function allocates the internal data structures to -allow asynchronous callbacks as a talloc child of the -struct tevent_context *, and returns a struct tevent_thread_proxy * -that can be passed to another thread. - -When you have finished receiving asynchronous callbacks, simply -talloc_free the struct tevent_thread_proxy *, or talloc_free -the struct tevent_context *, which will deallocate the resources -used. - -To schedule an asynchronous tevent_immediate function call from one -thread on the tevent loop of another thread, use -@code - -void tevent_thread_proxy_schedule(struct tevent_thread_proxy *tp, - struct tevent_immediate **pp_im, - tevent_immediate_handler_t handler, - void **pp_private_data); - -@endcode - -This function causes the function handler() -to be invoked as a tevent_immediate callback from the event loop -of the thread that created the struct tevent_thread_proxy * -(so the owning struct tevent_context * should be -long-lived and not in the process of being torn down). - -The struct tevent_thread_proxy object being -used here is a child of the event context of the target -thread. So external synchronization mechanisms must be -used to ensure that the target object is still in use -at the time of the tevent_thread_proxy_schedule() -call. In the example below, the request/response nature -of the communication ensures this. - -The struct tevent_immediate **pp_im passed into this function -should be a struct tevent_immediate * allocated on a talloc context -local to this thread, and will be reparented via talloc_move -to be owned by struct tevent_thread_proxy *tp. -*pp_im will be set to NULL on successful scheduling -of the tevent_immediate call. - -handler() will be called as a normal tevent_immediate -callback from the struct tevent_context * of the destination -event loop that created the struct tevent_thread_proxy * - -Returning from this functions does not mean that the handler -has been invoked, merely that it has been scheduled to be called in the -destination event loop. - -Because the calling thread does not wait for the -callback to be scheduled and run on the destination -thread, this is a fire-and-forget call. If you wish -confirmation of the handler() being -successfully invoked, you must ensure it replies to the -caller in some way. - -Because of asynchronous nature of this call, the nature -of the parameter passed to the destination thread has some -restructions. If you don't need parameters, merely pass -NULL as the value of -void **pp_private_data. - -If you wish to pass a pointer to data between the threads, -it MUST be a pointer to a talloced pointer, which is -not part of a talloc-pool, and it must not have a destructor -attached. The ownership of the memory pointed to will -be passed from the calling thread to the tevent library, -and if the receiving thread does not talloc-reparent -it to its own contexts, it will be freed once the -handler is called. - -On success, *pp_private will be NULL -to signify the talloc memory ownership has been moved. - -In practice for message passing between threads in -event loops these restrictions are not very onerous. - -The easiest way to to a request-reply pair between -tevent loops on different threads is to pass the -parameter block of memory back and forth using -a reply tevent_thread_proxy_schedule() -call. - -Here is an example (without error checking for -simplicity): - -@code ------------------------------------------------- -// Master thread. - -main() -{ - // Make talloc thread-safe. - - talloc_disable_null_tracking(); - - // Create the master event context. - - struct tevent_context *master_ev = tevent_context_init(NULL); - - // Create the master thread proxy to allow it to receive - // async callbacks from other threads. - - struct tevent_thread_proxy *master_tp = - tevent_thread_proxy_create(master_ev); - - // Create sub-threads, passing master_tp in - // some way to them. - // This code not shown.. - - // Process events. - // Function master_callback() below - // will be invoked on this thread on - // master_ev event context. - - tevent_loop_wait(master_ev); - - // Cleanup if loop exits. - - talloc_free(master_ev); -} - -// Data passed between threads. -struct reply_state { - struct tevent_thread_proxy *reply_tp; - pthread_t thread_id; - bool *p_finished; -}; - -// Callback Called in child thread context. - -static void thread_callback(struct tevent_context *ev, - struct tevent_immediate *im, - void *private_ptr) -{ - // Move the ownership of what private_ptr - // points to from the tevent library back to this thread. - - struct reply_state *rsp = - talloc_get_type_abort(private_ptr, struct reply_state); - - talloc_steal(ev, rsp); - - *rsp->p_finished = true; - - // im will be talloc_freed on return from this call. - // but rsp will not. -} - -// Callback Called in master thread context. - -static void master_callback(struct tevent_context *ev, - struct tevent_immediate *im, - void *private_ptr) -{ - // Move the ownership of what private_ptr - // points to from the tevent library to this thread. - - struct reply_state *rsp = - talloc_get_type_abort(private_ptr, struct reply_state); - - talloc_steal(ev, rsp); - - printf("Callback from thread %s\n", thread_id_to_string(rsp->thread_id)); - - /* Now reply to the thread ! */ - tevent_thread_proxy_schedule(rsp->reply_tp, - &im, - thread_callback, - &rsp); - - // Note - rsp and im are now NULL as the tevent library - // owns the memory. -} - -// Child thread. - -static void *thread_fn(void *private_ptr) -{ - struct tevent_thread_proxy *master_tp = - talloc_get_type_abort(private_ptr, struct tevent_thread_proxy); - bool finished = false; - int ret; - - // Create our own event context. - - struct tevent_context *ev = tevent_context_init(NULL); - - // Create the local thread proxy to allow us to receive - // async callbacks from other threads. - - struct tevent_thread_proxy *local_tp = - tevent_thread_proxy_create(master_ev); - - // Setup the data to send. - - struct reply_state *rsp = talloc(ev, struct reply_state); - - rsp->reply_tp = local_tp; - rsp->thread_id = pthread_self(); - rsp->p_finished = &finished; - - // Create the immediate event to use. - - struct tevent_immediate *im = tevent_create_immediate(ev); - - // Call the master thread. - - tevent_thread_proxy_schedule(master_tp, - &im, - master_callback, - &rsp); - - // Note - rsp and im are now NULL as the tevent library - // owns the memory. - - // Wait for the reply. - - while (!finished) { - tevent_loop_once(ev); - } - - // Cleanup. - - talloc_free(ev); - return NULL; -} - -@endcode - -Note this doesn't have to be a master-subthread communication. -Any thread that has access to the struct tevent_thread_proxy * -pointer of another thread that has called tevent_thread_proxy_create() - can send an async tevent_immediate request. - -But remember the caveat that external synchronization must be used -to ensure the target struct tevent_thread_proxy * object -exists at the time of the tevent_thread_proxy_schedule() -call or unreproducible crashes will result. -*/ diff --git a/ldb-2.0.8/lib/tevent/doc/tevent_tutorial.dox b/ldb-2.0.8/lib/tevent/doc/tevent_tutorial.dox deleted file mode 100644 index 207a244..0000000 --- a/ldb-2.0.8/lib/tevent/doc/tevent_tutorial.dox +++ /dev/null @@ -1,22 +0,0 @@ -/** -@page tevent_tutorial The Tutorial - -@section tevent_tutorial_introduction Introduction - -Tutorial describing working with tevent library. - -@section tevent_tutorial_toc Table of contents - -@subpage tevent_context - -@subpage tevent_events - -@subpage tevent_data - -@subpage tevent_request - -@subpage tevent_queue - -@subpage tevent_thread - -*/ diff --git a/ldb-2.0.8/lib/tevent/doc/tutorials.dox b/ldb-2.0.8/lib/tevent/doc/tutorials.dox deleted file mode 100644 index e8beed7..0000000 --- a/ldb-2.0.8/lib/tevent/doc/tutorials.dox +++ /dev/null @@ -1,43 +0,0 @@ -/** - * @page tevent_queue_tutorial The tevent_queue tutorial - * - * @section Introduction - * - * A tevent_queue is used to queue up async requests that must be - * serialized. For example writing buffers into a socket must be - * serialized. Writing a large lump of data into a socket can require - * multiple write(2) or send(2) system calls. If more than one async - * request is outstanding to write large buffers into a socket, every - * request must individually be completed before the next one begins, - * even if multiple syscalls are required. - * - * To do this, every socket gets assigned a tevent_queue struct. - * - * Creating a serialized async request follows the usual convention to - * return a tevent_req structure with an embedded state structure. To - * serialize the work the requests is about to so, instead of directly - * starting or doing that work, tevent_queue_add must be called. When it - * is time for the serialized async request to do its work, the trigger - * callback function tevent_queue_add was given is called. In the example - * of writing to a socket, the trigger is called when the write request - * can begin accessing the socket. - * - * How does this engine work behind the scenes? When the queue is empty, - * tevent_queue_add schedules an immediate call to the trigger - * callback. The trigger callback starts its work, likely by starting - * other async subrequests. While these async subrequests are working, - * more requests can accumulate in the queue by tevent_queue_add. While - * there is no function to explicitly trigger the next waiter in line, it - * still works: When the active request in the queue is done, it will be - * destroyed by talloc_free. Talloc_free of an serialized async request - * that had been added to a queue will trigger the next request in the - * queue via a talloc destructor attached to a child of the serialized - * request. This way the queue will be kept busy when an async request - * finishes. - * - * @section Example - * - * @code - * Metze: Please add a code example here. - * @endcode - */ diff --git a/ldb-2.0.8/lib/tevent/doxy.config b/ldb-2.0.8/lib/tevent/doxy.config deleted file mode 100644 index 76d8b4c..0000000 --- a/ldb-2.0.8/lib/tevent/doxy.config +++ /dev/null @@ -1,1908 +0,0 @@ -# Doxyfile 1.8.4 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a double hash (##) is considered a comment and is placed -# in front of the TAG it is preceding . -# All text after a hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" "). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or sequence of words) that should -# identify the project. Note that if you do not use Doxywizard you need -# to put quotes around the project name if it contains spaces. - -PROJECT_NAME = tevent - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = 0.9.8 - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer -# a quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = - -# With the PROJECT_LOGO tag one can specify an logo or icon that is -# included in the documentation. The maximum height of the logo should not -# exceed 55 pixels and the maximum width should not exceed 200 pixels. -# Doxygen will copy the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = doc - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian, -# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, -# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. Note that you specify absolute paths here, but also -# relative paths, which will be relative from the directory where doxygen is -# started. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful if your file system -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = YES - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding -# "class=itcl::class" will allow you to use the command class in the -# itcl::class meaning. - -TCL_SUBST = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given -# extension. Doxygen has a built-in mapping, but you can override or extend it -# using this tag. The format is ext=language, where ext is a file extension, -# and language is one of the parsers supported by doxygen: IDL, Java, -# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, -# C++. For instance to make doxygen treat .inc files as Fortran files (default -# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note -# that for custom extensions you also need to set FILE_PATTERNS otherwise the -# files are not read by doxygen. - -EXTENSION_MAPPING = - -# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all -# comments according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you -# can mix doxygen, HTML, and XML commands with Markdown formatting. -# Disable only in case of backward compatibilities issues. - -MARKDOWN_SUPPORT = YES - -# When enabled doxygen tries to link words that correspond to documented -# classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by by putting a % sign in front of the word -# or globally by setting AUTOLINK_SUPPORT to NO. - -AUTOLINK_SUPPORT = YES - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also makes the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate -# getter and setter methods for a property. Setting this option to YES (the -# default) will make doxygen replace the get and set methods by a property in -# the documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and -# unions are shown inside the group in which they are included (e.g. using -# @ingroup) instead of on a separate page (for HTML and Man pages) or -# section (for LaTeX and RTF). - -INLINE_GROUPED_CLASSES = NO - -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and -# unions with only public data fields or simple typedef fields will be shown -# inline in the documentation of the scope in which they are defined (i.e. file, -# namespace, or group documentation), provided this scope is documented. If set -# to NO (the default), structs, classes, and unions are shown on a separate -# page (for HTML and Man pages) or section (for LaTeX and RTF). - -INLINE_SIMPLE_STRUCTS = NO - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This -# cache is used to resolve symbols given their name and scope. Since this can -# be an expensive process and often the same symbol appear multiple times in -# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too -# small doxygen will become slower. If the cache is too large, memory is wasted. -# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid -# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536 -# symbols. - -LOOKUP_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal -# scope will be included in the documentation. - -EXTRACT_PACKAGE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = NO - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespaces are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = YES - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = YES - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO -# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to -# do proper type resolution of all parameters of a function it will reject a -# match between the prototype and the implementation of a member function even -# if there is only one candidate or it is obvious which candidate to choose -# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen -# will still accept a match between prototype and implementation in such cases. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if section-label ... \endif -# and \cond section-label ... \endcond blocks. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or macro consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and macros in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted -# DoxygenLayout.xml will be used as the name of the layout file. - -LAYOUT_FILE = - -# The CITE_BIB_FILES tag can be used to specify one or more bib files -# containing the references data. This must be a list of .bib files. The -# .bib extension is automatically appended if omitted. Using this command -# requires the bibtex tool to be installed. See also -# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style -# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this -# feature you need bibtex and perl available in the search path. Do not use -# file names with spaces, bibtex cannot handle them. - -CITE_BIB_FILES = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# The WARN_NO_PARAMDOC option can be enabled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = . \ - doc - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh -# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py -# *.f90 *.f *.for *.vhd *.vhdl - -FILE_PATTERNS = *.cpp \ - *.cc \ - *.c \ - *.h \ - *.hh \ - *.hpp \ - *.dox - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = */.git/* - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = doc/img - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. -# If FILTER_PATTERNS is specified, this tag will be ignored. -# Note that the filter must not add or remove lines; it is applied before the -# code is scanned, but not when the output code is generated. If lines are added -# or removed, the anchors will not be placed correctly. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. -# Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. -# The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty or if -# non of the patterns match the file name, INPUT_FILTER is applied. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) -# and it is also possible to disable source filtering for a specific pattern -# using *.ext= (so without naming a filter). This option only has effect when -# FILTER_SOURCE_FILES is enabled. - -FILTER_SOURCE_PATTERNS = - -# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that -# is part of the input, its contents will be placed on the main page -# (index.html). This can be useful if you have a project on for instance GitHub -# and want reuse the introduction page also for the doxygen output. - -USE_MDFILE_AS_MAINPAGE = - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C, C++ and Fortran comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. -# Otherwise they will link to the documentation. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. Note that when using a custom header you are responsible -# for the proper inclusion of any scripts and style sheets that doxygen -# needs, which is dependent on the configuration options used. -# It is advised to generate a default header using "doxygen -w html -# header.html footer.html stylesheet.css YourConfigFile" and then modify -# that header. Note that the header is subject to change so you typically -# have to redo this when upgrading to a newer version of doxygen or when -# changing the value of configuration settings such as GENERATE_TREEVIEW! - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If left blank doxygen will -# generate a default style sheet. Note that it is recommended to use -# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this -# tag will in the future become obsolete. - -HTML_STYLESHEET = - -# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional -# user-defined cascading style sheet that is included after the standard -# style sheets created by doxygen. Using this option one can overrule -# certain style aspects. This is preferred over using HTML_STYLESHEET -# since it does not replace the standard style sheet and is therefor more -# robust against future updates. Doxygen will copy the style sheet file to -# the output directory. - -HTML_EXTRA_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that -# the files will be copied as-is; there are no commands or markers available. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the style sheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. -# The allowed range is 0 to 359. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use -# grayscales only. A value of 255 will produce the most vivid colors. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, -# and 100 does not change the gamma. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. - -HTML_TIMESTAMP = NO - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. - -HTML_DYNAMIC_SECTIONS = NO - -# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of -# entries shown in the various tree structured indices initially; the user -# can expand and collapse entries dynamically later on. Doxygen will expand -# the tree to such a level that at most the specified number of entries are -# visible (unless a fully collapsed tree already exceeds this amount). -# So setting the number of entries 1 will produce a full collapsed tree by -# default. 0 is a special value representing an infinite number of entries -# and will result in a full expanded tree by default. - -HTML_INDEX_NUM_ENTRIES = 100 - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely -# identify the documentation publisher. This should be a reverse domain-name -# style string, e.g. com.mycompany.MyDocSet.documentation. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# -# Qt Help Project / Custom Filters. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# -# Qt Help Project / Filter Attributes. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) -# at top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. Since the tabs have the same information as the -# navigation tree you can set this option to NO if you already set -# GENERATE_TREEVIEW to YES. - -DISABLE_INDEX = NO - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. -# Since the tree basically has the same information as the tab index you -# could consider to set DISABLE_INDEX to NO when enabling this option. - -GENERATE_TREEVIEW = NONE - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values -# (range [0,1..20]) that doxygen will group on one line in the generated HTML -# documentation. Note that a value of 0 will completely suppress the enum -# values from appearing in the overview section. - -ENUM_VALUES_PER_LINE = 4 - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open -# links to external symbols imported via tag files in a separate window. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files -# in the HTML output before the changes have effect. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax -# (see http://www.mathjax.org) which uses client side Javascript for the -# rendering instead of using prerendered bitmaps. Use this if you do not -# have LaTeX installed or if you want to formulas look prettier in the HTML -# output. When enabled you may also need to install MathJax separately and -# configure the path to it using the MATHJAX_RELPATH option. - -USE_MATHJAX = NO - -# When MathJax is enabled you can set the default output format to be used for -# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and -# SVG. The default value is HTML-CSS, which is slower, but has the best -# compatibility. - -MATHJAX_FORMAT = HTML-CSS - -# When MathJax is enabled you need to specify the location relative to the -# HTML output directory using the MATHJAX_RELPATH option. The destination -# directory should contain the MathJax.js script. For instance, if the mathjax -# directory is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to -# the MathJax Content Delivery Network so you can quickly see the result without -# installing MathJax. -# However, it is strongly recommended to install a local -# copy of MathJax from http://www.mathjax.org before deployment. - -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest - -# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension -# names that should be enabled during MathJax rendering. - -MATHJAX_EXTENSIONS = - -# The MATHJAX_CODEFILE tag can be used to specify a file with javascript -# pieces of code that will be used on startup of the MathJax code. - -MATHJAX_CODEFILE = - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. - -SEARCHENGINE = NO - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a web server instead of a web client using Javascript. -# There are two flavours of web server based search depending on the -# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for -# searching and an index file used by the script. When EXTERNAL_SEARCH is -# enabled the indexing and searching needs to be provided by external tools. -# See the manual for details. - -SERVER_BASED_SEARCH = NO - -# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP -# script for searching. Instead the search results are written to an XML file -# which needs to be processed by an external indexer. Doxygen will invoke an -# external search engine pointed to by the SEARCHENGINE_URL option to obtain -# the search results. Doxygen ships with an example indexer (doxyindexer) and -# search engine (doxysearch.cgi) which are based on the open source search -# engine library Xapian. See the manual for configuration details. - -EXTERNAL_SEARCH = NO - -# The SEARCHENGINE_URL should point to a search engine hosted by a web server -# which will returned the search results when EXTERNAL_SEARCH is enabled. -# Doxygen ships with an example search engine (doxysearch) which is based on -# the open source search engine library Xapian. See the manual for configuration -# details. - -SEARCHENGINE_URL = - -# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed -# search data is written to a file for indexing by an external tool. With the -# SEARCHDATA_FILE tag the name of this file can be specified. - -SEARCHDATA_FILE = searchdata.xml - -# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the -# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is -# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple -# projects and redirect the results back to the right project. - -EXTERNAL_SEARCH_ID = - -# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen -# projects other than the one defined by this configuration file, but that are -# all added to the same external search index. Each project needs to have a -# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id -# of to a relative location where the documentation can be found. -# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... - -EXTRA_SEARCH_MAPPINGS = - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = YES - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the -# Makefile that is written to the output directory. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, letter, legal and -# executive. If left blank a4 will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for -# the generated latex document. The footer should contain everything after -# the last chapter. If it is left blank doxygen will generate a -# standard footer. Notice: only use this tag if you know what you are doing! - -LATEX_FOOTER = - -# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images -# or other source files which should be copied to the LaTeX output directory. -# Note that the files will be copied as-is; there are no commands or markers -# available. - -LATEX_EXTRA_FILES = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include -# source code with syntax highlighting in the LaTeX output. -# Note that which sources are shown also depends on other settings -# such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = NO - -# The LATEX_BIB_STYLE tag can be used to specify the style to use for the -# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See -# http://en.wikipedia.org/wiki/BibTeX for more info. - -LATEX_BIB_STYLE = plain - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load style sheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = YES - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options related to the DOCBOOK output -#--------------------------------------------------------------------------- - -# If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files -# that can be used to generate PDF. - -GENERATE_DOCBOOK = NO - -# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in -# front of it. If left blank docbook will be used as the default path. - -DOCBOOK_OUTPUT = docbook - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. -# This is useful -# if you want to understand what is going on. -# On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = YES - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = YES - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# pointed to by INCLUDE_PATH will be searched when a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = DOXYGEN \ - PRINTF_ATTRIBUTE(x,y)= - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition that -# overrules the definition found in the source code. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all references to function-like macros -# that are alone on a line, have an all uppercase name, and do not end with a -# semicolon, because these will confuse the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. For each -# tag file the location of the external documentation should be added. The -# format of a tag file without this location is as follows: -# -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths -# or URLs. Note that each tag file must have a unique name (where the name does -# NOT include the path). If a tag file is not located in the directory in which -# doxygen is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed -# in the related pages index. If set to NO, only the current project's -# pages will be listed. - -EXTERNAL_PAGES = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option also works with HAVE_DOT disabled, but it is recommended to -# install and use dot, since it yields more powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is -# allowed to run in parallel. When set to 0 (the default) doxygen will -# base this on the number of processors available in the system. You can set it -# explicitly to a value larger than 0 to get control over the balance -# between CPU load and processing speed. - -DOT_NUM_THREADS = 0 - -# By default doxygen will use the Helvetica font for all dot files that -# doxygen generates. When you want a differently looking font you can specify -# the font name using DOT_FONTNAME. You need to make sure dot is able to find -# the font, which can be done by putting it in a standard location or by setting -# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the -# directory containing the font. - -DOT_FONTNAME = FreeSans - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the Helvetica font. -# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to -# set the path where dot can find it. - -DOT_FONTPATH = - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If the UML_LOOK tag is enabled, the fields and methods are shown inside -# the class node. If there are many fields or methods and many nodes the -# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS -# threshold limits the number of items for each type to make the size more -# manageable. Set this to 0 for no limit. Note that the threshold may be -# exceeded by 50% before the limit is enforced. - -UML_LIMIT_NUM_FIELDS = 10 - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will generate a graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are svg, png, jpg, or gif. -# If left blank png will be used. If you choose svg you need to set -# HTML_FILE_EXTENSION to xhtml in order to make the SVG files -# visible in IE 9+ (other browsers do not have this requirement). - -DOT_IMAGE_FORMAT = png - -# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to -# enable generation of interactive SVG images that allow zooming and panning. -# Note that this requires a modern browser other than Internet Explorer. -# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you -# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files -# visible. Older versions of IE do not have SVG support. - -INTERACTIVE_SVG = NO - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the -# \mscfile command). - -MSCFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = YES - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES diff --git a/ldb-2.0.8/lib/tevent/echo_server.c b/ldb-2.0.8/lib/tevent/echo_server.c deleted file mode 100644 index f93d8bc..0000000 --- a/ldb-2.0.8/lib/tevent/echo_server.c +++ /dev/null @@ -1,667 +0,0 @@ -/** - ** NOTE! The following liberal license applies to this sample file only. - ** This does NOT imply that all of Samba is released under this license. - ** - ** This file is meant as a starting point for libtevent users to be used - ** in any program linking against the LGPL licensed libtevent. - **/ - -/* - * This file is being made available by the Samba Team under the following - * license: - * - * Permission to use, copy, modify, and distribute this sample file for any - * purpose is hereby granted without fee. - * - * This work is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "tevent.h" -#include "talloc.h" - -/** - * @brief Helper function to get a useful unix error from tevent_req - */ - -static bool tevent_req_is_unix_error(struct tevent_req *req, int *perrno) -{ - enum tevent_req_state state; - uint64_t err; - - if (!tevent_req_is_error(req, &state, &err)) { - return false; - } - switch (state) { - case TEVENT_REQ_TIMED_OUT: - *perrno = ETIMEDOUT; - break; - case TEVENT_REQ_NO_MEMORY: - *perrno = ENOMEM; - break; - case TEVENT_REQ_USER_ERROR: - *perrno = err; - break; - default: - *perrno = EINVAL; - break; - } - return true; -} - -/** - * @brief Wrapper around accept(2) - */ - -struct accept_state { - struct tevent_fd *fde; - int listen_sock; - socklen_t addrlen; - struct sockaddr_storage addr; - int sock; -}; - -static void accept_handler(struct tevent_context *ev, struct tevent_fd *fde, - uint16_t flags, void *private_data); - -static struct tevent_req *accept_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - int listen_sock) -{ - struct tevent_req *req; - struct accept_state *state; - - req = tevent_req_create(mem_ctx, &state, struct accept_state); - if (req == NULL) { - return NULL; - } - - state->listen_sock = listen_sock; - - state->fde = tevent_add_fd(ev, state, listen_sock, TEVENT_FD_READ, - accept_handler, req); - if (tevent_req_nomem(state->fde, req)) { - return tevent_req_post(req, ev); - } - return req; -} - -static void accept_handler(struct tevent_context *ev, struct tevent_fd *fde, - uint16_t flags, void *private_data) -{ - struct tevent_req *req = talloc_get_type_abort( - private_data, struct tevent_req); - struct accept_state *state = tevent_req_data(req, struct accept_state); - int ret; - - TALLOC_FREE(state->fde); - - if ((flags & TEVENT_FD_READ) == 0) { - tevent_req_error(req, EIO); - return; - } - state->addrlen = sizeof(state->addr); - - ret = accept(state->listen_sock, - (struct sockaddr *)&state->addr, - &state->addrlen); - if (ret == -1) { - tevent_req_error(req, errno); - return; - } - smb_set_close_on_exec(ret); - state->sock = ret; - tevent_req_done(req); -} - -static int accept_recv(struct tevent_req *req, struct sockaddr *paddr, - socklen_t *paddrlen, int *perr) -{ - struct accept_state *state = tevent_req_data(req, struct accept_state); - int err; - - if (tevent_req_is_unix_error(req, &err)) { - if (perr != NULL) { - *perr = err; - } - return -1; - } - if (paddr != NULL) { - memcpy(paddr, &state->addr, state->addrlen); - } - if (paddrlen != NULL) { - *paddrlen = state->addrlen; - } - return state->sock; -} - -/** - * @brief Wrapper around read(2) - */ - -struct read_state { - struct tevent_fd *fde; - int fd; - void *buf; - size_t count; - - ssize_t nread; -}; - -static void read_handler(struct tevent_context *ev, struct tevent_fd *fde, - uint16_t flags, void *private_data); - -static struct tevent_req *read_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - int fd, void *buf, size_t count) -{ - struct tevent_req *req; - struct read_state *state; - - req = tevent_req_create(mem_ctx, &state, struct read_state); - if (req == NULL) { - return NULL; - } - - state->fd = fd; - state->buf = buf; - state->count = count; - - state->fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, - read_handler, req); - if (tevent_req_nomem(state->fde, req)) { - return tevent_req_post(req, ev); - } - return req; -} - -static void read_handler(struct tevent_context *ev, struct tevent_fd *fde, - uint16_t flags, void *private_data) -{ - struct tevent_req *req = talloc_get_type_abort( - private_data, struct tevent_req); - struct read_state *state = tevent_req_data(req, struct read_state); - ssize_t ret; - - TALLOC_FREE(state->fde); - - if ((flags & TEVENT_FD_READ) == 0) { - tevent_req_error(req, EIO); - return; - } - - ret = read(state->fd, state->buf, state->count); - if (ret == -1) { - tevent_req_error(req, errno); - return; - } - state->nread = ret; - tevent_req_done(req); -} - -static ssize_t read_recv(struct tevent_req *req, int *perr) -{ - struct read_state *state = tevent_req_data(req, struct read_state); - int err; - - if (tevent_req_is_unix_error(req, &err)) { - if (perr != NULL) { - *perr = err; - } - return -1; - } - return state->nread; -} - -/** - * @brief Wrapper around write(2) - */ - -struct write_state { - struct tevent_fd *fde; - int fd; - const void *buf; - size_t count; - - ssize_t nwritten; -}; - -static void write_handler(struct tevent_context *ev, struct tevent_fd *fde, - uint16_t flags, void *private_data); - -static struct tevent_req *write_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - int fd, const void *buf, size_t count) -{ - struct tevent_req *req; - struct write_state *state; - - req = tevent_req_create(mem_ctx, &state, struct write_state); - if (req == NULL) { - return NULL; - } - - state->fd = fd; - state->buf = buf; - state->count = count; - - state->fde = tevent_add_fd(ev, state, fd, TEVENT_FD_WRITE, - write_handler, req); - if (tevent_req_nomem(state->fde, req)) { - return tevent_req_post(req, ev); - } - return req; -} - -static void write_handler(struct tevent_context *ev, struct tevent_fd *fde, - uint16_t flags, void *private_data) -{ - struct tevent_req *req = talloc_get_type_abort( - private_data, struct tevent_req); - struct write_state *state = tevent_req_data(req, struct write_state); - ssize_t ret; - - TALLOC_FREE(state->fde); - - if ((flags & TEVENT_FD_WRITE) == 0) { - tevent_req_error(req, EIO); - return; - } - - ret = write(state->fd, state->buf, state->count); - if (ret == -1) { - tevent_req_error(req, errno); - return; - } - state->nwritten = ret; - tevent_req_done(req); -} - -static ssize_t write_recv(struct tevent_req *req, int *perr) -{ - struct write_state *state = tevent_req_data(req, struct write_state); - int err; - - if (tevent_req_is_unix_error(req, &err)) { - if (perr != NULL) { - *perr = err; - } - return -1; - } - return state->nwritten; -} - -/** - * @brief Wrapper function that deals with short writes - */ - -struct writeall_state { - struct tevent_context *ev; - int fd; - const void *buf; - size_t count; - size_t nwritten; -}; - -static void writeall_done(struct tevent_req *subreq); - -static struct tevent_req *writeall_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - int fd, const void *buf, size_t count) -{ - struct tevent_req *req, *subreq; - struct writeall_state *state; - - req = tevent_req_create(mem_ctx, &state, struct writeall_state); - if (req == NULL) { - return NULL; - } - state->ev = ev; - state->fd = fd; - state->buf = buf; - state->count = count; - state->nwritten = 0; - - subreq = write_send(state, state->ev, state->fd, - ((char *)state->buf)+state->nwritten, - state->count - state->nwritten); - if (tevent_req_nomem(subreq, req)) { - return tevent_req_post(req, ev); - } - tevent_req_set_callback(subreq, writeall_done, req); - return req; -} - -static void writeall_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct writeall_state *state = tevent_req_data( - req, struct writeall_state); - ssize_t nwritten; - int err = 0; - - nwritten = write_recv(subreq, &err); - TALLOC_FREE(subreq); - if (nwritten == -1) { - tevent_req_error(req, err); - return; - } - - state->nwritten += nwritten; - - if (state->nwritten < state->count) { - subreq = write_send(state, state->ev, state->fd, - ((char *)state->buf)+state->nwritten, - state->count - state->nwritten); - if (tevent_req_nomem(subreq, req)) { - return; - } - tevent_req_set_callback(subreq, writeall_done, req); - return; - } - tevent_req_done(req); -} - -static ssize_t writeall_recv(struct tevent_req *req, int *perr) -{ - struct writeall_state *state = tevent_req_data( - req, struct writeall_state); - int err; - - if (tevent_req_is_unix_error(req, &err)) { - if (perr != NULL) { - *perr = err; - } - return -1; - } - return state->nwritten; -} - -/** - * @brief Async echo handler code dealing with one client - */ - -struct echo_state { - struct tevent_context *ev; - int fd; - uint8_t *buf; -}; - -static int echo_state_destructor(struct echo_state *s); -static void echo_read_done(struct tevent_req *subreq); -static void echo_writeall_done(struct tevent_req *subreq); - -static struct tevent_req *echo_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - int fd, size_t bufsize) -{ - struct tevent_req *req, *subreq; - struct echo_state *state; - - req = tevent_req_create(mem_ctx, &state, struct echo_state); - if (req == NULL) { - return NULL; - } - state->ev = ev; - state->fd = fd; - - talloc_set_destructor(state, echo_state_destructor); - - state->buf = talloc_array(state, uint8_t, bufsize); - if (tevent_req_nomem(state->buf, req)) { - return tevent_req_post(req, ev); - } - - subreq = read_send(state, state->ev, state->fd, - state->buf, talloc_get_size(state->buf)); - if (tevent_req_nomem(subreq, req)) { - return tevent_req_post(req, ev); - } - tevent_req_set_callback(subreq, echo_read_done, req); - return req; -} - -static int echo_state_destructor(struct echo_state *s) -{ - if (s->fd != -1) { - printf("Closing client fd %d\n", s->fd); - close(s->fd); - s->fd = -1; - } - return 0; -} - -static void echo_read_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct echo_state *state = tevent_req_data( - req, struct echo_state); - ssize_t nread; - int err; - - nread = read_recv(subreq, &err); - TALLOC_FREE(subreq); - if (nread == -1) { - tevent_req_error(req, err); - return; - } - if (nread == 0) { - tevent_req_done(req); - return; - } - - subreq = writeall_send(state, state->ev, state->fd, state->buf, nread); - if (tevent_req_nomem(subreq, req)) { - return; - } - tevent_req_set_callback(subreq, echo_writeall_done, req); -} - -static void echo_writeall_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct echo_state *state = tevent_req_data( - req, struct echo_state); - ssize_t nwritten; - int err; - - nwritten = writeall_recv(subreq, &err); - TALLOC_FREE(subreq); - if (nwritten == -1) { - if (err == EPIPE) { - tevent_req_done(req); - return; - } - tevent_req_error(req, err); - return; - } - - subreq = read_send(state, state->ev, state->fd, - state->buf, talloc_get_size(state->buf)); - if (tevent_req_nomem(subreq, req)) { - return; - } - tevent_req_set_callback(subreq, echo_read_done, req); -} - -static bool echo_recv(struct tevent_req *req, int *perr) -{ - int err; - - if (tevent_req_is_unix_error(req, &err)) { - *perr = err; - return false; - } - return true; -} - -/** - * @brief Full echo handler code accepting and handling clients - */ - -struct echo_server_state { - struct tevent_context *ev; - int listen_sock; -}; - -static void echo_server_accepted(struct tevent_req *subreq); -static void echo_server_client_done(struct tevent_req *subreq); - -static struct tevent_req *echo_server_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - int listen_sock) -{ - struct tevent_req *req, *subreq; - struct echo_server_state *state; - - req = tevent_req_create(mem_ctx, &state, - struct echo_server_state); - if (req == NULL) { - return NULL; - } - state->ev = ev; - state->listen_sock = listen_sock; - - subreq = accept_send(state, state->ev, state->listen_sock); - if (tevent_req_nomem(subreq, req)) { - return tevent_req_post(req, ev); - } - tevent_req_set_callback(subreq, echo_server_accepted, req); - return req; -} - -static void echo_server_accepted(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct echo_server_state *state = tevent_req_data( - req, struct echo_server_state); - int sock, err; - - sock = accept_recv(subreq, NULL, NULL, &err); - TALLOC_FREE(subreq); - if (sock == -1) { - tevent_req_error(req, err); - return; - } - - printf("new client fd %d\n", sock); - - subreq = echo_send(state, state->ev, sock, 100); - if (tevent_req_nomem(subreq, req)) { - return; - } - tevent_req_set_callback(subreq, echo_server_client_done, req); - - subreq = accept_send(state, state->ev, state->listen_sock); - if (tevent_req_nomem(subreq, req)) { - return; - } - tevent_req_set_callback(subreq, echo_server_accepted, req); -} - -static void echo_server_client_done(struct tevent_req *subreq) -{ - bool ret; - int err; - - ret = echo_recv(subreq, &err); - TALLOC_FREE(subreq); - - if (ret) { - printf("Client done\n"); - } else { - printf("Client failed: %s\n", strerror(err)); - } -} - -static bool echo_server_recv(struct tevent_req *req, int *perr) -{ - int err; - - if (tevent_req_is_unix_error(req, &err)) { - *perr = err; - return false; - } - return true; -} - -int main(int argc, const char **argv) -{ - int ret, port, listen_sock, err; - struct tevent_context *ev; - struct sockaddr_in addr; - struct tevent_req *req; - bool result; - - if (argc != 2) { - fprintf(stderr, "Usage: %s \n", argv[0]); - exit(1); - } - - port = atoi(argv[1]); - - printf("listening on port %d\n", port); - - listen_sock = socket(AF_INET, SOCK_STREAM, 0); - - if (listen_sock == -1) { - perror("socket() failed"); - exit(1); - } - - addr = (struct sockaddr_in) { - .sin_family = AF_INET, - .sin_port = htons(port) - }; - - ret = bind(listen_sock, (struct sockaddr *)&addr, sizeof(addr)); - if (ret == -1) { - perror("bind() failed"); - exit(1); - } - - ret = listen(listen_sock, 5); - if (ret == -1) { - perror("listen() failed"); - exit(1); - } - - ev = tevent_context_init(NULL); - if (ev == NULL) { - fprintf(stderr, "tevent_context_init failed\n"); - exit(1); - } - - req = echo_server_send(ev, ev, listen_sock); - if (req == NULL) { - fprintf(stderr, "echo_server_send failed\n"); - exit(1); - } - - if (!tevent_req_poll(req, ev)) { - perror("tevent_req_poll() failed"); - exit(1); - } - - result = echo_server_recv(req, &err); - TALLOC_FREE(req); - if (!result) { - fprintf(stderr, "echo_server failed: %s\n", strerror(err)); - exit(1); - } - - return 0; -} diff --git a/ldb-2.0.8/lib/tevent/pytevent.c b/ldb-2.0.8/lib/tevent/pytevent.c deleted file mode 100644 index 73a9bd7..0000000 --- a/ldb-2.0.8/lib/tevent/pytevent.c +++ /dev/null @@ -1,945 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Python bindings for tevent - - Copyright (C) Jelmer Vernooij 2010 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include -#include "replace.h" -#include - -#if PY_MAJOR_VERSION >= 3 -#define PyInt_FromLong PyLong_FromLong -#endif - -/* discard signature of 'func' in favour of 'target_sig' */ -#define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func - -void init_tevent(void); - -typedef struct { - PyObject_HEAD - struct tevent_context *ev; -} TeventContext_Object; - -typedef struct { - PyObject_HEAD - struct tevent_queue *queue; -} TeventQueue_Object; - -typedef struct { - PyObject_HEAD - struct tevent_req *req; -} TeventReq_Object; - -typedef struct { - PyObject_HEAD - struct tevent_signal *signal; -} TeventSignal_Object; - -typedef struct { - PyObject_HEAD - struct tevent_timer *timer; - PyObject *callback; -} TeventTimer_Object; - -typedef struct { - PyObject_HEAD - struct tevent_fd *fd; -} TeventFd_Object; - -static PyTypeObject TeventContext_Type; -static PyTypeObject TeventReq_Type; -static PyTypeObject TeventQueue_Type; -static PyTypeObject TeventSignal_Type; -static PyTypeObject TeventTimer_Type; -static PyTypeObject TeventFd_Type; - -static int py_context_init(struct tevent_context *ev) -{ - /* FIXME */ - return 0; -} - -static struct tevent_fd *py_add_fd(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - int fd, uint16_t flags, - tevent_fd_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ - /* FIXME */ - return NULL; -} - -static void py_set_fd_close_fn(struct tevent_fd *fde, - tevent_fd_close_fn_t close_fn) -{ - /* FIXME */ -} - -static uint16_t py_get_fd_flags(struct tevent_fd *fde) -{ - /* FIXME */ - return 0; -} - -static void py_set_fd_flags(struct tevent_fd *fde, uint16_t flags) -{ - /* FIXME */ -} - -/* timed_event functions */ -static struct tevent_timer *py_add_timer(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - struct timeval next_event, - tevent_timer_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ - /* FIXME */ - return NULL; -} - -/* immediate event functions */ -static void py_schedule_immediate(struct tevent_immediate *im, - struct tevent_context *ev, - tevent_immediate_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ - /* FIXME */ -} - -/* signal functions */ -static struct tevent_signal *py_add_signal(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - int signum, int sa_flags, - tevent_signal_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ - /* FIXME */ - return NULL; -} - -/* loop functions */ -static int py_loop_once(struct tevent_context *ev, const char *location) -{ - /* FIXME */ - return 0; -} - -static int py_loop_wait(struct tevent_context *ev, const char *location) -{ - /* FIXME */ - return 0; -} - -const static struct tevent_ops py_tevent_ops = { - .context_init = py_context_init, - .add_fd = py_add_fd, - .set_fd_close_fn = py_set_fd_close_fn, - .get_fd_flags = py_get_fd_flags, - .set_fd_flags = py_set_fd_flags, - .add_timer = py_add_timer, - .schedule_immediate = py_schedule_immediate, - .add_signal = py_add_signal, - .loop_wait = py_loop_wait, - .loop_once = py_loop_once, -}; - -static PyObject *py_register_backend(PyObject *self, PyObject *args) -{ - PyObject *name, *py_backend; - - if (!PyArg_ParseTuple(args, "O", &py_backend)) - return NULL; - - name = PyObject_GetAttrString(py_backend, "name"); - if (name == NULL) { - PyErr_SetNone(PyExc_AttributeError); - return NULL; - } - - if (!PyUnicode_Check(name)) { - PyErr_SetNone(PyExc_TypeError); - Py_DECREF(name); - return NULL; - } - - if (!tevent_register_backend(PyUnicode_AsUTF8(name), &py_tevent_ops)) { /* FIXME: What to do with backend */ - PyErr_SetNone(PyExc_RuntimeError); - Py_DECREF(name); - return NULL; - } - - Py_DECREF(name); - - Py_RETURN_NONE; -} - -static PyObject *py_tevent_context_reinitialise(TeventContext_Object *self, - PyObject *Py_UNUSED(ignored)) -{ - int ret = tevent_re_initialise(self->ev); - if (ret != 0) { - PyErr_SetNone(PyExc_RuntimeError); - return NULL; - } - Py_RETURN_NONE; -} - -static PyObject *py_tevent_queue_stop(TeventQueue_Object *self, - PyObject *Py_UNUSED(ignored)) -{ - tevent_queue_stop(self->queue); - Py_RETURN_NONE; -} - -static PyObject *py_tevent_queue_start(TeventQueue_Object *self, - PyObject *Py_UNUSED(ignored)) -{ - tevent_queue_start(self->queue); - Py_RETURN_NONE; -} - -static void py_queue_trigger(struct tevent_req *req, void *private_data) -{ - PyObject *callback = private_data, *ret; - - ret = PyObject_CallFunction(callback, discard_const_p(char, "")); - Py_XDECREF(ret); -} - -static PyObject *py_tevent_queue_add(TeventQueue_Object *self, PyObject *args) -{ - TeventContext_Object *py_ev; - TeventReq_Object *py_req; - PyObject *trigger; - bool ret; - - if (!PyArg_ParseTuple(args, "O!O!O", - &TeventContext_Type, &py_ev, - &TeventReq_Type, &py_req, - &trigger)) - return NULL; - - Py_INCREF(trigger); - - ret = tevent_queue_add(self->queue, py_ev->ev, py_req->req, - py_queue_trigger, trigger); - if (!ret) { - PyErr_SetString(PyExc_RuntimeError, "queue add failed"); - Py_DECREF(trigger); - return NULL; - } - - Py_RETURN_NONE; -} - -static PyMethodDef py_tevent_queue_methods[] = { - { "stop", (PyCFunction)py_tevent_queue_stop, - METH_NOARGS, - "S.stop()" }, - { "start", (PyCFunction)py_tevent_queue_start, - METH_NOARGS, - "S.start()" }, - { "add", (PyCFunction)py_tevent_queue_add, METH_VARARGS, - "S.add(ctx, req, trigger, baton)" }, - { NULL }, -}; - -static PyObject *py_tevent_context_wakeup_send(PyObject *self, PyObject *args) -{ - /* FIXME */ - - Py_RETURN_NONE; -} - -static PyObject *py_tevent_context_loop_wait(TeventContext_Object *self, - PyObject *Py_UNUSED(ignored)) -{ - if (tevent_loop_wait(self->ev) != 0) { - PyErr_SetNone(PyExc_RuntimeError); - return NULL; - } - Py_RETURN_NONE; -} - -static PyObject *py_tevent_context_loop_once(TeventContext_Object *self, - PyObject *Py_UNUSED(ignored)) -{ - if (tevent_loop_once(self->ev) != 0) { - PyErr_SetNone(PyExc_RuntimeError); - return NULL; - } - Py_RETURN_NONE; -} - -static void py_tevent_signal_handler(struct tevent_context *ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - void *private_data) -{ - PyObject *callback = (PyObject *)private_data, *ret; - - ret = PyObject_CallFunction(callback, discard_const_p(char, "ii"), signum, count); - Py_XDECREF(ret); -} - -static void py_tevent_signal_dealloc(TeventSignal_Object *self) -{ - talloc_free(self->signal); - PyObject_Del(self); -} - -static PyTypeObject TeventSignal_Type = { - .tp_name = "tevent.Signal", - .tp_basicsize = sizeof(TeventSignal_Object), - .tp_dealloc = (destructor)py_tevent_signal_dealloc, - .tp_flags = Py_TPFLAGS_DEFAULT, -}; - -static PyObject *py_tevent_context_add_signal(TeventContext_Object *self, PyObject *args) -{ - int signum, sa_flags; - PyObject *handler; - struct tevent_signal *sig; - TeventSignal_Object *ret; - - if (!PyArg_ParseTuple(args, "iiO", &signum, &sa_flags, &handler)) - return NULL; - - Py_INCREF(handler); - sig = tevent_add_signal(self->ev, NULL, signum, sa_flags, - py_tevent_signal_handler, handler); - - ret = PyObject_New(TeventSignal_Object, &TeventSignal_Type); - if (ret == NULL) { - PyErr_NoMemory(); - talloc_free(sig); - return NULL; - } - - ret->signal = sig; - - return (PyObject *)ret; -} - -static void py_timer_handler(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval current_time, - void *private_data) -{ - TeventTimer_Object *self = private_data; - PyObject *ret; - - ret = PyObject_CallFunction(self->callback, discard_const_p(char, "l"), te); - if (ret == NULL) { - /* No Python stack to propagate exception to; just print traceback */ - PyErr_PrintEx(0); - } - Py_XDECREF(ret); -} - -static void py_tevent_timer_dealloc(TeventTimer_Object *self) -{ - if (self->timer) { - talloc_free(self->timer); - } - Py_DECREF(self->callback); - PyObject_Del(self); -} - -static int py_tevent_timer_traverse(TeventTimer_Object *self, visitproc visit, void *arg) -{ - Py_VISIT(self->callback); - return 0; -} - -static PyObject* py_tevent_timer_get_active(TeventTimer_Object *self, - PyObject *Py_UNUSED(ignored)) -{ - return PyBool_FromLong(self->timer != NULL); -} - -struct PyGetSetDef py_tevent_timer_getset[] = { - { - .name = discard_const_p(char, "active"), - .get = (getter)py_tevent_timer_get_active, - .doc = discard_const_p(char, "true if the timer is scheduled to run"), - }, - {NULL}, -}; - -static PyTypeObject TeventTimer_Type = { - .tp_name = "tevent.Timer", - .tp_basicsize = sizeof(TeventTimer_Object), - .tp_dealloc = (destructor)py_tevent_timer_dealloc, - .tp_traverse = (traverseproc)py_tevent_timer_traverse, - .tp_getset = py_tevent_timer_getset, - .tp_flags = Py_TPFLAGS_DEFAULT, -}; - -struct TeventTimer_Object_ref { - TeventTimer_Object *obj; -}; - -static int TeventTimer_Object_ref_destructor(struct TeventTimer_Object_ref *ref) -{ - ref->obj->timer = NULL; - Py_DECREF(ref->obj); - return 0; -} - -static PyObject *py_tevent_context_add_timer_internal(TeventContext_Object *self, - struct timeval next_event, - PyObject *callback) -{ - /* Ownership notes: - * - * There are 5 pieces in play; two tevent contexts and 3 Python objects: - * - The tevent timer - * - The tevent context - * - The Python context -- "self" - * - The Python timer (TeventTimer_Object) -- "ret" - * - The Python callback function -- "callback" - * - * We only use the Python context for getting the tevent context, - * afterwards it can be destroyed. - * - * The tevent context owns the tevent timer. - * - * The tevent timer holds a reference to the Python timer, so the Python - * timer must always outlive the tevent timer. - * The Python timer has a pointer to the tevent timer; a destructor is - * used to set this to NULL when the tevent timer is deallocated. - * - * The tevent timer can be deallocated in these cases: - * 1) when the context is destroyed - * 2) after the event fires - * Posssibly, API might be added to cancel (free the tevent timer). - * - * The Python timer holds a reference to the callback. - */ - TeventTimer_Object *ret; - struct TeventTimer_Object_ref *ref; - - ret = PyObject_New(TeventTimer_Object, &TeventTimer_Type); - if (ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - Py_INCREF(callback); - ret->callback = callback; - ret->timer = tevent_add_timer(self->ev, NULL, next_event, py_timer_handler, - ret); - if (ret->timer == NULL) { - Py_DECREF(ret); - PyErr_SetString(PyExc_RuntimeError, "Could not initialize timer"); - return NULL; - } - ref = talloc(ret->timer, struct TeventTimer_Object_ref); - if (ref == NULL) { - talloc_free(ret->timer); - Py_DECREF(ret); - PyErr_SetString(PyExc_RuntimeError, "Could not initialize timer"); - return NULL; - } - Py_INCREF(ret); - ref->obj = ret; - - talloc_set_destructor(ref, TeventTimer_Object_ref_destructor); - - return (PyObject *)ret; -} - -static PyObject *py_tevent_context_add_timer(TeventContext_Object *self, PyObject *args) -{ - struct timeval next_event; - PyObject *callback; - double secs, usecs; - if (!PyArg_ParseTuple(args, "dO", &secs, &callback)){ - return NULL; - } - next_event.tv_sec = secs; - usecs = (secs - next_event.tv_sec) * 1000000.0; - next_event.tv_usec = usecs; - return py_tevent_context_add_timer_internal(self, next_event, callback); -} - -static PyObject *py_tevent_context_add_timer_offset(TeventContext_Object *self, PyObject *args) -{ - struct timeval next_event; - double offset; - int seconds; - PyObject *callback; - if (!PyArg_ParseTuple(args, "dO", &offset, &callback)) - return NULL; - - seconds = offset; - offset -= seconds; - next_event = tevent_timeval_current_ofs(seconds, (int)(offset*1000000)); - return py_tevent_context_add_timer_internal(self, next_event, callback); -} - -static void py_fd_handler(struct tevent_context *ev, - struct tevent_fd *fde, - uint16_t flags, - void *private_data) -{ - PyObject *callback = private_data, *ret; - - ret = PyObject_CallFunction(callback, discard_const_p(char, "i"), flags); - Py_XDECREF(ret); -} - -static void py_tevent_fp_dealloc(TeventFd_Object *self) -{ - talloc_free(self->fd); - PyObject_Del(self); -} - -static PyTypeObject TeventFd_Type = { - .tp_name = "tevent.Fd", - .tp_basicsize = sizeof(TeventFd_Object), - .tp_dealloc = (destructor)py_tevent_fp_dealloc, - .tp_flags = Py_TPFLAGS_DEFAULT, -}; - -static PyObject *py_tevent_context_add_fd(TeventContext_Object *self, PyObject *args) -{ - int fd, flags; - PyObject *handler; - struct tevent_fd *tfd; - TeventFd_Object *ret; - - if (!PyArg_ParseTuple(args, "iiO", &fd, &flags, &handler)) - return NULL; - - tfd = tevent_add_fd(self->ev, NULL, fd, flags, py_fd_handler, handler); - if (tfd == NULL) { - PyErr_SetNone(PyExc_RuntimeError); - return NULL; - } - - ret = PyObject_New(TeventFd_Object, &TeventFd_Type); - if (ret == NULL) { - talloc_free(tfd); - return NULL; - } - ret->fd = tfd; - - return (PyObject *)ret; -} - -static PyMethodDef py_tevent_context_methods[] = { - { "reinitialise", (PyCFunction)py_tevent_context_reinitialise, - METH_NOARGS, - "S.reinitialise()" }, - { "wakeup_send", (PyCFunction)py_tevent_context_wakeup_send, - METH_VARARGS, "S.wakeup_send(wakeup_time) -> req" }, - { "loop_wait", (PyCFunction)py_tevent_context_loop_wait, - METH_NOARGS, "S.loop_wait()" }, - { "loop_once", (PyCFunction)py_tevent_context_loop_once, - METH_NOARGS, "S.loop_once()" }, - { "add_signal", (PyCFunction)py_tevent_context_add_signal, - METH_VARARGS, "S.add_signal(signum, sa_flags, handler) -> signal" }, - { "add_timer", (PyCFunction)py_tevent_context_add_timer, - METH_VARARGS, "S.add_timer(next_event, handler) -> timer" }, - { "add_timer_offset", (PyCFunction)py_tevent_context_add_timer_offset, - METH_VARARGS, "S.add_timer(offset_seconds, handler) -> timer" }, - { "add_fd", (PyCFunction)py_tevent_context_add_fd, - METH_VARARGS, "S.add_fd(fd, flags, handler) -> fd" }, - { NULL }, -}; - -static PyObject *py_tevent_req_wakeup_recv(PyObject *self, - PyObject *Py_UNUSED(ignored)) -{ - /* FIXME */ - Py_RETURN_NONE; -} - -static PyObject *py_tevent_req_received(PyObject *self, - PyObject *Py_UNUSED(ignored)) -{ - /* FIXME */ - Py_RETURN_NONE; -} - -static PyObject *py_tevent_req_is_error(PyObject *self, - PyObject *Py_UNUSED(ignored)) -{ - /* FIXME */ - Py_RETURN_NONE; -} - -static PyObject *py_tevent_req_poll(PyObject *self, - PyObject *Py_UNUSED(ignored)) -{ - /* FIXME */ - Py_RETURN_NONE; -} - -static PyObject *py_tevent_req_is_in_progress(PyObject *self, - PyObject *Py_UNUSED(ignored)) -{ - /* FIXME */ - Py_RETURN_NONE; -} - -static PyGetSetDef py_tevent_req_getsetters[] = { - { - .name = discard_const_p(char, "in_progress"), - .get = (getter)py_tevent_req_is_in_progress, - .doc = discard_const_p(char, "Whether the request is in progress"), - }, - { NULL } -}; - -static PyObject *py_tevent_req_post(PyObject *self, PyObject *args) -{ - /* FIXME */ - Py_RETURN_NONE; -} - -static PyObject *py_tevent_req_set_error(PyObject *self, PyObject *args) -{ - /* FIXME */ - Py_RETURN_NONE; -} - -static PyObject *py_tevent_req_done(PyObject *self, - PyObject *Py_UNUSED(ignored)) -{ - /* FIXME */ - Py_RETURN_NONE; -} - -static PyObject *py_tevent_req_notify_callback(PyObject *self, - PyObject *Py_UNUSED(ignored)) -{ - /* FIXME */ - Py_RETURN_NONE; -} - -static PyObject *py_tevent_req_set_endtime(PyObject *self, PyObject *args) -{ - /* FIXME */ - Py_RETURN_NONE; -} - -static PyObject *py_tevent_req_cancel(TeventReq_Object *self, - PyObject *Py_UNUSED(ignored)) -{ - if (!tevent_req_cancel(self->req)) { - PyErr_SetNone(PyExc_RuntimeError); - return NULL; - } - Py_RETURN_NONE; -} - -static PyMethodDef py_tevent_req_methods[] = { - { "wakeup_recv", (PyCFunction)py_tevent_req_wakeup_recv, - METH_NOARGS, - "Wakeup received" }, - { "received", (PyCFunction)py_tevent_req_received, - METH_NOARGS, - "Receive finished" }, - { "is_error", (PyCFunction)py_tevent_req_is_error, METH_NOARGS, - "is_error() -> (error, state)" }, - { "poll", (PyCFunction)py_tevent_req_poll, METH_VARARGS, - "poll(ctx)" }, - { "post", (PyCFunction)py_tevent_req_post, METH_VARARGS, - "post(ctx) -> req" }, - { "set_error", (PyCFunction)py_tevent_req_set_error, METH_VARARGS, - "set_error(error)" }, - { "done", (PyCFunction)py_tevent_req_done, METH_NOARGS, - "done()" }, - { "notify_callback", (PyCFunction)py_tevent_req_notify_callback, - METH_NOARGS, "notify_callback()" }, - { "set_endtime", (PyCFunction)py_tevent_req_set_endtime, - METH_VARARGS, "set_endtime(ctx, endtime)" }, - { "cancel", (PyCFunction)py_tevent_req_cancel, - METH_NOARGS, "cancel()" }, - { NULL } -}; - -static void py_tevent_req_dealloc(TeventReq_Object *self) -{ - talloc_free(self->req); - PyObject_DEL(self); -} - -static PyTypeObject TeventReq_Type = { - .tp_name = "tevent.Request", - .tp_basicsize = sizeof(TeventReq_Object), - .tp_methods = py_tevent_req_methods, - .tp_dealloc = (destructor)py_tevent_req_dealloc, - .tp_getset = py_tevent_req_getsetters, - /* FIXME: .tp_new = py_tevent_req_new, */ -}; - -static PyObject *py_tevent_queue_get_length(TeventQueue_Object *self, - PyObject *Py_UNUSED(ignored)) -{ - return PyInt_FromLong(tevent_queue_length(self->queue)); -} - -static PyGetSetDef py_tevent_queue_getsetters[] = { - { - .name = discard_const_p(char, "length"), - .get = (getter)py_tevent_queue_get_length, - .doc = discard_const_p(char, "The number of elements in the queue."), - }, - { NULL }, -}; - -static void py_tevent_queue_dealloc(TeventQueue_Object *self) -{ - talloc_free(self->queue); - PyObject_Del(self); -} - -static PyTypeObject TeventQueue_Type = { - .tp_name = "tevent.Queue", - .tp_basicsize = sizeof(TeventQueue_Object), - .tp_dealloc = (destructor)py_tevent_queue_dealloc, - .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_getset = py_tevent_queue_getsetters, - .tp_methods = py_tevent_queue_methods, -}; - -static PyObject *py_tevent_context_signal_support(PyObject *_self, - PyObject *Py_UNUSED(ignored)) -{ - TeventContext_Object *self = (TeventContext_Object *)_self; - return PyBool_FromLong(tevent_signal_support(self->ev)); -} - -static PyGetSetDef py_tevent_context_getsetters[] = { - { - .name = discard_const_p(char, "signal_support"), - .get = PY_DISCARD_FUNC_SIG(getter, - py_tevent_context_signal_support), - .doc = discard_const_p(char, "if this platform and tevent context support signal handling"), - }, - { NULL } -}; - -static void py_tevent_context_dealloc(TeventContext_Object *self) -{ - talloc_free(self->ev); - PyObject_Del(self); -} - -static PyObject *py_tevent_context_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - const char * const kwnames[] = { "name", NULL }; - char *name = NULL; - struct tevent_context *ev; - TeventContext_Object *ret; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", discard_const_p(char *, kwnames), &name)) - return NULL; - - if (name == NULL) { - ev = tevent_context_init(NULL); - } else { - ev = tevent_context_init_byname(NULL, name); - } - - if (ev == NULL) { - PyErr_SetNone(PyExc_RuntimeError); - return NULL; - } - - ret = PyObject_New(TeventContext_Object, type); - if (ret == NULL) { - PyErr_NoMemory(); - talloc_free(ev); - return NULL; - } - - ret->ev = ev; - return (PyObject *)ret; -} - -static PyTypeObject TeventContext_Type = { - .tp_name = "tevent.Context", - .tp_new = py_tevent_context_new, - .tp_basicsize = sizeof(TeventContext_Object), - .tp_dealloc = (destructor)py_tevent_context_dealloc, - .tp_methods = py_tevent_context_methods, - .tp_getset = py_tevent_context_getsetters, - .tp_flags = Py_TPFLAGS_DEFAULT, -}; - -static PyObject *py_set_default_backend(PyObject *self, PyObject *args) -{ - char *backend_name; - if (!PyArg_ParseTuple(args, "s", &backend_name)) - return NULL; - - tevent_set_default_backend(backend_name); - - Py_RETURN_NONE; -} - -static PyObject *py_backend_list(PyObject *self, - PyObject *Py_UNUSED(ignored)) -{ - PyObject *ret = NULL; - PyObject *string = NULL; - int i, result; - const char **backends = NULL; - - ret = PyList_New(0); - if (ret == NULL) { - return NULL; - } - - backends = tevent_backend_list(NULL); - if (backends == NULL) { - PyErr_SetNone(PyExc_RuntimeError); - goto err; - } - for (i = 0; backends[i]; i++) { - string = PyUnicode_FromString(backends[i]); - if (!string) { - goto err; - } - result = PyList_Append(ret, string); - if (result) { - goto err; - } - Py_DECREF(string); - string = NULL; - } - - talloc_free(backends); - - return ret; - -err: - Py_XDECREF(ret); - Py_XDECREF(string); - talloc_free(backends); - return NULL; -} - -static PyMethodDef tevent_methods[] = { - { "register_backend", (PyCFunction)py_register_backend, METH_VARARGS, - "register_backend(backend)" }, - { "set_default_backend", (PyCFunction)py_set_default_backend, - METH_VARARGS, "set_default_backend(backend)" }, - { "backend_list", (PyCFunction)py_backend_list, - METH_NOARGS, "backend_list() -> list" }, - { NULL }, -}; - -#define MODULE_DOC PyDoc_STR("Python wrapping of talloc-maintained objects.") - -#if PY_MAJOR_VERSION >= 3 -static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - .m_name = "_tevent", - .m_doc = MODULE_DOC, - .m_size = -1, - .m_methods = tevent_methods, -}; -#endif - -PyObject * module_init(void); -PyObject * module_init(void) -{ - PyObject *m; - - if (PyType_Ready(&TeventContext_Type) < 0) - return NULL; - - if (PyType_Ready(&TeventQueue_Type) < 0) - return NULL; - - if (PyType_Ready(&TeventReq_Type) < 0) - return NULL; - - if (PyType_Ready(&TeventSignal_Type) < 0) - return NULL; - - if (PyType_Ready(&TeventTimer_Type) < 0) - return NULL; - - if (PyType_Ready(&TeventFd_Type) < 0) - return NULL; - -#if PY_MAJOR_VERSION >= 3 - m = PyModule_Create(&moduledef); -#else - m = Py_InitModule3("_tevent", tevent_methods, MODULE_DOC); -#endif - if (m == NULL) - return NULL; - - Py_INCREF(&TeventContext_Type); - PyModule_AddObject(m, "Context", (PyObject *)&TeventContext_Type); - - Py_INCREF(&TeventQueue_Type); - PyModule_AddObject(m, "Queue", (PyObject *)&TeventQueue_Type); - - Py_INCREF(&TeventReq_Type); - PyModule_AddObject(m, "Request", (PyObject *)&TeventReq_Type); - - Py_INCREF(&TeventSignal_Type); - PyModule_AddObject(m, "Signal", (PyObject *)&TeventSignal_Type); - - Py_INCREF(&TeventTimer_Type); - PyModule_AddObject(m, "Timer", (PyObject *)&TeventTimer_Type); - - Py_INCREF(&TeventFd_Type); - PyModule_AddObject(m, "Fd", (PyObject *)&TeventFd_Type); - - PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION); - - return m; -} - -#if PY_MAJOR_VERSION >= 3 -PyMODINIT_FUNC PyInit__tevent(void); -PyMODINIT_FUNC PyInit__tevent(void) -{ - return module_init(); -} -#else -void init_tevent(void); -void init_tevent(void) -{ - module_init(); -} -#endif diff --git a/ldb-2.0.8/lib/tevent/test_req.c b/ldb-2.0.8/lib/tevent/test_req.c deleted file mode 100644 index 2274a8c..0000000 --- a/ldb-2.0.8/lib/tevent/test_req.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * testing of some tevent_req aspects - * - * Copyright (C) Volker Lendecke 2018 - * - * ** NOTE! The following LGPL license applies to the tevent - * ** library. This does NOT imply that all of Samba is released - * ** under the LGPL - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - */ - -#include "includes.h" -#include "tevent.h" -#include "torture/torture.h" -#include "torture/local/proto.h" -#include "lib/util/tevent_unix.h" -#include "lib/util/tevent_req_profile.h" -#include "lib/util/time_basic.h" - -struct tevent_req_create_state { - uint8_t val; -}; - -static bool test_tevent_req_create(struct torture_context *tctx, - const void *test_data) -{ - struct tevent_req *req; - struct tevent_req_create_state *state; - - req = tevent_req_create(tctx, &state, - struct tevent_req_create_state); - torture_assert_not_null(tctx, req, "tevent_req_create failed\n"); - torture_assert_int_equal(tctx, state->val, 0, "state not initialized\n"); - - TALLOC_FREE(req); - - return true; -} - -struct profile1_state { - uint8_t dummy; -}; - -static bool test_tevent_req_profile1(struct torture_context *tctx, - const void *test_data) -{ - struct tevent_req *req; - struct profile1_state *state; - const struct tevent_req_profile *p1; - struct tevent_req_profile *p2; - struct timeval start, stop; - bool ok; - int cmp; - - req = tevent_req_create(tctx, &state, struct profile1_state); - torture_assert_not_null(tctx, req, "tevent_req_create failed\n"); - - p1 = tevent_req_get_profile(req); - torture_assert(tctx, p1 == NULL, "profile not initialized to NULL\n"); - - ok = tevent_req_set_profile(req); - torture_assert(tctx, ok, "set_profile failed\n"); - - tevent_req_done(req); - - p2 = tevent_req_move_profile(req, tctx); - torture_assert_not_null(tctx, p2, "get_profile failed\n"); - - /* Demonstrate sure "p2" outlives req */ - TALLOC_FREE(req); - - tevent_req_profile_get_start(p2, NULL, &start); - tevent_req_profile_get_stop(p2, NULL, &stop); - - cmp = tevent_timeval_compare(&start, &stop); - torture_assert(tctx, cmp <= 0, "stop before start\n"); - - TALLOC_FREE(p2); - - return true; -} - -struct profile2_state { - uint8_t dummy; -}; - -static void profile2_done(struct tevent_req *subreq); - -static struct tevent_req *profile2_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev) -{ - struct tevent_req *req, *subreq; - struct profile2_state *state; - bool ok; - - req = tevent_req_create(mem_ctx, &state, struct profile2_state); - if (req == NULL) { - return NULL; - } - - ok = tevent_req_set_profile(req); - if (!ok) { - return tevent_req_post(req, ev); - } - - subreq = tevent_wakeup_send( - state, - ev, - tevent_timeval_current_ofs(0, 1)); - if (tevent_req_nomem(subreq, req)) { - return tevent_req_post(req, ev); - } - tevent_req_set_callback(subreq, profile2_done, req); - - return req; -} - -static void profile2_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - bool ok; - - ok = tevent_wakeup_recv(subreq); - if (!ok) { - tevent_req_oom(req); - return; - } - tevent_req_done(req); -} - -static int profile2_recv(struct tevent_req *req, - TALLOC_CTX *mem_ctx, - struct tevent_req_profile **profile) -{ - int err; - - if (tevent_req_is_unix_error(req, &err)) { - return err; - } - - *profile = tevent_req_move_profile(req, mem_ctx); - - return 0; -} - -static bool test_tevent_req_profile2(struct torture_context *tctx, - const void *test_data) -{ - struct tevent_context *ev; - struct tevent_req *req; - struct tevent_req_profile *p1 = NULL; - struct tevent_req_profile *p2 = NULL; - const char *str1, *str2; - struct timeval tv1, tv2; - pid_t pid1, pid2; - enum tevent_req_state state1, state2; - uint64_t err1, err2; - char *printstring; - ssize_t pack_len; - int err; - bool ok; - - ev = samba_tevent_context_init(tctx); - torture_assert_not_null(tctx, ev, "samba_tevent_context_init failed\n"); - - req = profile2_send(tctx, ev); - torture_assert_not_null(tctx, req, "profile2_send failed\n"); - - ok = tevent_req_poll_unix(req, ev, &err); - torture_assert(tctx, ok, "tevent_req_poll_unix failed\n"); - - err = profile2_recv(req, tctx, &p1); - torture_assert_int_equal(tctx, err, 0, "profile2_recv failed\n"); - - TALLOC_FREE(req); - TALLOC_FREE(ev); - - printstring = tevent_req_profile_string(tctx, p1, 0, UINT_MAX); - torture_assert_not_null( - tctx, - printstring, - "tevent_req_profile_string failed\n"); - printf("%s\n", printstring); - - pack_len = tevent_req_profile_pack(p1, NULL, 0); - torture_assert(tctx, pack_len>0, "profile_pack failed\n"); - - { - uint8_t buf[pack_len]; - ssize_t unpack_len; - - tevent_req_profile_pack(p1, buf, sizeof(buf)); - dump_data(10, buf, sizeof(buf)); - - unpack_len = tevent_req_profile_unpack( - buf, - pack_len, - tctx, - &p2); - torture_assert_int_equal(tctx, - pack_len, - unpack_len, - "profile_unpack failed\n"); - } - - printstring = tevent_req_profile_string(tctx, p2, 0, UINT_MAX); - torture_assert_not_null( - tctx, - printstring, - "tevent_req_profile_string failed\n"); - printf("%s\n", printstring); - - tevent_req_profile_get_name(p1, &str1); - tevent_req_profile_get_name(p2, &str2); - torture_assert_str_equal(tctx, str1, str2, "names differ\n"); - - tevent_req_profile_get_start(p1, &str1, &tv1); - tevent_req_profile_get_start(p2, &str2, &tv2); - torture_assert_str_equal(tctx, str1, str2, "start strings differ\n"); - torture_assert(tctx, - tevent_timeval_compare(&tv1, &tv2) == 0, - "start times differ\n"); - - tevent_req_profile_get_stop(p1, &str1, &tv1); - tevent_req_profile_get_stop(p2, &str2, &tv2); - torture_assert_str_equal(tctx, str1, str2, "stop strings differ\n"); - torture_assert(tctx, - tevent_timeval_compare(&tv1, &tv2) == 0, - "stop times differ\n"); - - tevent_req_profile_get_status(p1, &pid1, &state1, &err1); - tevent_req_profile_get_status(p2, &pid2, &state2, &err2); - torture_assert_int_equal(tctx, pid1, pid2, "pids differ\n"); - torture_assert_int_equal(tctx, state1, state2, "states differ\n"); - torture_assert_int_equal(tctx, err1, err2, "user errors differ\n"); - - str1 = tevent_req_profile_string(p1, p1, 0, UINT_MAX); - torture_assert_not_null(tctx, str1, "profile_string failed\n"); - str2 = tevent_req_profile_string(p2, p2, 0, UINT_MAX); - torture_assert_not_null(tctx, str2, "profile_string failed\n"); - - torture_assert_str_equal(tctx, str1, str2, "result strings differ\n"); - - TALLOC_FREE(p1); - TALLOC_FREE(p2); - - return true; -} - -struct torture_suite *torture_local_tevent_req(TALLOC_CTX *mem_ctx) -{ - struct torture_suite *suite; - - suite = torture_suite_create(mem_ctx, "tevent_req"); - - torture_suite_add_simple_tcase_const( - suite, - "create", - test_tevent_req_create, - NULL); - torture_suite_add_simple_tcase_const( - suite, - "profile1", - test_tevent_req_profile1, - NULL); - torture_suite_add_simple_tcase_const( - suite, - "profile2", - test_tevent_req_profile2, - NULL); - - return suite; -} diff --git a/ldb-2.0.8/lib/tevent/testsuite.c b/ldb-2.0.8/lib/tevent/testsuite.c deleted file mode 100644 index ee4c285..0000000 --- a/ldb-2.0.8/lib/tevent/testsuite.c +++ /dev/null @@ -1,1821 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - testing of the events subsystem - - Copyright (C) Stefan Metzmacher 2006-2009 - Copyright (C) Jeremy Allison 2013 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "includes.h" -#define TEVENT_DEPRECATED 1 -#include "tevent.h" -#include "system/filesys.h" -#include "system/select.h" -#include "system/network.h" -#include "torture/torture.h" -#include "torture/local/proto.h" -#ifdef HAVE_PTHREAD -#include "system/threads.h" -#include -#endif - -static int fde_count; - -static void do_read(int fd, void *buf, size_t count) -{ - ssize_t ret; - - do { - ret = read(fd, buf, count); - } while (ret == -1 && errno == EINTR); -} - -static void fde_handler_read(struct tevent_context *ev_ctx, struct tevent_fd *f, - uint16_t flags, void *private_data) -{ - int *fd = (int *)private_data; - char c; -#ifdef SA_SIGINFO - kill(getpid(), SIGUSR1); -#endif - kill(getpid(), SIGALRM); - - do_read(fd[0], &c, 1); - fde_count++; -} - -static void do_write(int fd, void *buf, size_t count) -{ - ssize_t ret; - - do { - ret = write(fd, buf, count); - } while (ret == -1 && errno == EINTR); -} - -static void fde_handler_write(struct tevent_context *ev_ctx, struct tevent_fd *f, - uint16_t flags, void *private_data) -{ - int *fd = (int *)private_data; - char c = 0; - - do_write(fd[1], &c, 1); -} - - -/* This will only fire if the fd's returned from pipe() are bi-directional. */ -static void fde_handler_read_1(struct tevent_context *ev_ctx, struct tevent_fd *f, - uint16_t flags, void *private_data) -{ - int *fd = (int *)private_data; - char c; -#ifdef SA_SIGINFO - kill(getpid(), SIGUSR1); -#endif - kill(getpid(), SIGALRM); - - do_read(fd[1], &c, 1); - fde_count++; -} - -/* This will only fire if the fd's returned from pipe() are bi-directional. */ -static void fde_handler_write_1(struct tevent_context *ev_ctx, struct tevent_fd *f, - uint16_t flags, void *private_data) -{ - int *fd = (int *)private_data; - char c = 0; - do_write(fd[0], &c, 1); -} - -static void finished_handler(struct tevent_context *ev_ctx, struct tevent_timer *te, - struct timeval tval, void *private_data) -{ - int *finished = (int *)private_data; - (*finished) = 1; -} - -static void count_handler(struct tevent_context *ev_ctx, struct tevent_signal *te, - int signum, int count, void *info, void *private_data) -{ - int *countp = (int *)private_data; - (*countp) += count; -} - -static bool test_event_context(struct torture_context *test, - const void *test_data) -{ - struct tevent_context *ev_ctx; - int fd[2] = { -1, -1 }; - const char *backend = (const char *)test_data; - int alarm_count=0, info_count=0; - struct tevent_fd *fde_read; - struct tevent_fd *fde_read_1; - struct tevent_fd *fde_write; - struct tevent_fd *fde_write_1; -#ifdef SA_RESTART - struct tevent_signal *se1 = NULL; -#endif -#ifdef SA_RESETHAND - struct tevent_signal *se2 = NULL; -#endif -#ifdef SA_SIGINFO - struct tevent_signal *se3 = NULL; -#endif - int finished=0; - struct timeval t; - int ret; - - ev_ctx = tevent_context_init_byname(test, backend); - if (ev_ctx == NULL) { - torture_comment(test, "event backend '%s' not supported\n", backend); - return true; - } - - torture_comment(test, "backend '%s' - %s\n", - backend, __FUNCTION__); - - /* reset globals */ - fde_count = 0; - - /* create a pipe */ - ret = pipe(fd); - torture_assert_int_equal(test, ret, 0, "pipe failed"); - - fde_read = tevent_add_fd(ev_ctx, ev_ctx, fd[0], TEVENT_FD_READ, - fde_handler_read, fd); - fde_write_1 = tevent_add_fd(ev_ctx, ev_ctx, fd[0], TEVENT_FD_WRITE, - fde_handler_write_1, fd); - - fde_write = tevent_add_fd(ev_ctx, ev_ctx, fd[1], TEVENT_FD_WRITE, - fde_handler_write, fd); - fde_read_1 = tevent_add_fd(ev_ctx, ev_ctx, fd[1], TEVENT_FD_READ, - fde_handler_read_1, fd); - - tevent_fd_set_auto_close(fde_read); - tevent_fd_set_auto_close(fde_write); - - tevent_add_timer(ev_ctx, ev_ctx, timeval_current_ofs(2,0), - finished_handler, &finished); - -#ifdef SA_RESTART - se1 = tevent_add_signal(ev_ctx, ev_ctx, SIGALRM, SA_RESTART, count_handler, &alarm_count); - torture_assert(test, se1 != NULL, "failed to setup se1"); -#endif -#ifdef SA_RESETHAND - se2 = tevent_add_signal(ev_ctx, ev_ctx, SIGALRM, SA_RESETHAND, count_handler, &alarm_count); - torture_assert(test, se2 != NULL, "failed to setup se2"); -#endif -#ifdef SA_SIGINFO - se3 = tevent_add_signal(ev_ctx, ev_ctx, SIGUSR1, SA_SIGINFO, count_handler, &info_count); - torture_assert(test, se3 != NULL, "failed to setup se3"); -#endif - - t = timeval_current(); - while (!finished) { - errno = 0; - if (tevent_loop_once(ev_ctx) == -1) { - TALLOC_FREE(ev_ctx); - torture_fail(test, talloc_asprintf(test, "Failed event loop %s\n", strerror(errno))); - return false; - } - } - - talloc_free(fde_read_1); - talloc_free(fde_write_1); - talloc_free(fde_read); - talloc_free(fde_write); - - while (alarm_count < fde_count+1) { - if (tevent_loop_once(ev_ctx) == -1) { - break; - } - } - - torture_comment(test, "Got %.2f pipe events/sec\n", fde_count/timeval_elapsed(&t)); - -#ifdef SA_RESTART - talloc_free(se1); -#endif - - torture_assert_int_equal(test, alarm_count, 1+fde_count, "alarm count mismatch"); - -#ifdef SA_RESETHAND - /* - * we do not call talloc_free(se2) - * because it is already gone, - * after triggering the event handler. - */ -#endif - -#ifdef SA_SIGINFO - talloc_free(se3); - torture_assert_int_equal(test, info_count, fde_count, "info count mismatch"); -#endif - - talloc_free(ev_ctx); - - return true; -} - -struct test_event_fd1_state { - struct torture_context *tctx; - const char *backend; - struct tevent_context *ev; - int sock[2]; - struct tevent_timer *te; - struct tevent_fd *fde0; - struct tevent_fd *fde1; - bool got_write; - bool got_read; - bool drain; - bool drain_done; - unsigned loop_count; - bool finished; - const char *error; -}; - -static void test_event_fd1_fde_handler(struct tevent_context *ev_ctx, - struct tevent_fd *fde, - uint16_t flags, - void *private_data) -{ - struct test_event_fd1_state *state = - (struct test_event_fd1_state *)private_data; - - if (state->drain_done) { - state->finished = true; - state->error = __location__; - return; - } - - if (state->drain) { - ssize_t ret; - uint8_t c = 0; - - if (!(flags & TEVENT_FD_READ)) { - state->finished = true; - state->error = __location__; - return; - } - - ret = read(state->sock[0], &c, 1); - if (ret == 1) { - return; - } - - /* - * end of test... - */ - tevent_fd_set_flags(fde, 0); - state->drain_done = true; - return; - } - - if (!state->got_write) { - uint8_t c = 0; - - if (flags != TEVENT_FD_WRITE) { - state->finished = true; - state->error = __location__; - return; - } - state->got_write = true; - - /* - * we write to the other socket... - */ - do_write(state->sock[1], &c, 1); - TEVENT_FD_NOT_WRITEABLE(fde); - TEVENT_FD_READABLE(fde); - return; - } - - if (!state->got_read) { - if (flags != TEVENT_FD_READ) { - state->finished = true; - state->error = __location__; - return; - } - state->got_read = true; - - TEVENT_FD_NOT_READABLE(fde); - return; - } - - state->finished = true; - state->error = __location__; - return; -} - -static void test_event_fd1_finished(struct tevent_context *ev_ctx, - struct tevent_timer *te, - struct timeval tval, - void *private_data) -{ - struct test_event_fd1_state *state = - (struct test_event_fd1_state *)private_data; - - if (state->drain_done) { - state->finished = true; - return; - } - - if (!state->got_write) { - state->finished = true; - state->error = __location__; - return; - } - - if (!state->got_read) { - state->finished = true; - state->error = __location__; - return; - } - - state->loop_count++; - if (state->loop_count > 3) { - state->finished = true; - state->error = __location__; - return; - } - - state->got_write = false; - state->got_read = false; - - tevent_fd_set_flags(state->fde0, TEVENT_FD_WRITE); - - if (state->loop_count > 2) { - state->drain = true; - TALLOC_FREE(state->fde1); - TEVENT_FD_READABLE(state->fde0); - } - - state->te = tevent_add_timer(state->ev, state->ev, - timeval_current_ofs(0,2000), - test_event_fd1_finished, state); -} - -static bool test_event_fd1(struct torture_context *tctx, - const void *test_data) -{ - struct test_event_fd1_state state; - int ret; - - ZERO_STRUCT(state); - state.tctx = tctx; - state.backend = (const char *)test_data; - - state.ev = tevent_context_init_byname(tctx, state.backend); - if (state.ev == NULL) { - torture_skip(tctx, talloc_asprintf(tctx, - "event backend '%s' not supported\n", - state.backend)); - return true; - } - - tevent_set_debug_stderr(state.ev); - torture_comment(tctx, "backend '%s' - %s\n", - state.backend, __FUNCTION__); - - /* - * This tests the following: - * - * It monitors the state of state.sock[0] - * with tevent_fd, but we never read/write on state.sock[0] - * while state.sock[1] * is only used to write a few bytes. - * - * We have a loop: - * - we wait only for TEVENT_FD_WRITE on state.sock[0] - * - we write 1 byte to state.sock[1] - * - we wait only for TEVENT_FD_READ on state.sock[0] - * - we disable events on state.sock[0] - * - the timer event restarts the loop - * Then we close state.sock[1] - * We have a loop: - * - we wait for TEVENT_FD_READ/WRITE on state.sock[0] - * - we try to read 1 byte - * - if the read gets an error of returns 0 - * we disable the event handler - * - the timer finishes the test - */ - state.sock[0] = -1; - state.sock[1] = -1; - - ret = socketpair(AF_UNIX, SOCK_STREAM, 0, state.sock); - torture_assert(tctx, ret == 0, "socketpair() failed"); - - state.te = tevent_add_timer(state.ev, state.ev, - timeval_current_ofs(0,1000), - test_event_fd1_finished, &state); - state.fde0 = tevent_add_fd(state.ev, state.ev, - state.sock[0], TEVENT_FD_WRITE, - test_event_fd1_fde_handler, &state); - /* state.fde1 is only used to auto close */ - state.fde1 = tevent_add_fd(state.ev, state.ev, - state.sock[1], 0, - test_event_fd1_fde_handler, &state); - - tevent_fd_set_auto_close(state.fde0); - tevent_fd_set_auto_close(state.fde1); - - while (!state.finished) { - errno = 0; - if (tevent_loop_once(state.ev) == -1) { - talloc_free(state.ev); - torture_fail(tctx, talloc_asprintf(tctx, - "Failed event loop %s\n", - strerror(errno))); - } - } - - talloc_free(state.ev); - - torture_assert(tctx, state.error == NULL, talloc_asprintf(tctx, - "%s", state.error)); - - return true; -} - -struct test_event_fd2_state { - struct torture_context *tctx; - const char *backend; - struct tevent_context *ev; - struct tevent_timer *te; - struct test_event_fd2_sock { - struct test_event_fd2_state *state; - int fd; - struct tevent_fd *fde; - size_t num_written; - size_t num_read; - bool got_full; - } sock0, sock1; - bool finished; - const char *error; -}; - -static void test_event_fd2_sock_handler(struct tevent_context *ev_ctx, - struct tevent_fd *fde, - uint16_t flags, - void *private_data) -{ - struct test_event_fd2_sock *cur_sock = - (struct test_event_fd2_sock *)private_data; - struct test_event_fd2_state *state = cur_sock->state; - struct test_event_fd2_sock *oth_sock = NULL; - uint8_t v = 0, c; - ssize_t ret; - - if (cur_sock == &state->sock0) { - oth_sock = &state->sock1; - } else { - oth_sock = &state->sock0; - } - - if (oth_sock->num_written == 1) { - if (flags != (TEVENT_FD_READ | TEVENT_FD_WRITE)) { - state->finished = true; - state->error = __location__; - return; - } - } - - if (cur_sock->num_read == oth_sock->num_written) { - state->finished = true; - state->error = __location__; - return; - } - - if (!(flags & TEVENT_FD_READ)) { - state->finished = true; - state->error = __location__; - return; - } - - if (oth_sock->num_read >= PIPE_BUF) { - /* - * On Linux we become writable once we've read - * one byte. On Solaris we only become writable - * again once we've read 4096 bytes. PIPE_BUF - * is probably a safe bet to test against. - * - * There should be room to write a byte again - */ - if (!(flags & TEVENT_FD_WRITE)) { - state->finished = true; - state->error = __location__; - return; - } - } - - if ((flags & TEVENT_FD_WRITE) && !cur_sock->got_full) { - v = (uint8_t)cur_sock->num_written; - ret = write(cur_sock->fd, &v, 1); - if (ret != 1) { - state->finished = true; - state->error = __location__; - return; - } - cur_sock->num_written++; - if (cur_sock->num_written > 0x80000000) { - state->finished = true; - state->error = __location__; - return; - } - return; - } - - if (!cur_sock->got_full) { - cur_sock->got_full = true; - - if (!oth_sock->got_full) { - /* - * cur_sock is full, - * lets wait for oth_sock - * to be filled - */ - tevent_fd_set_flags(cur_sock->fde, 0); - return; - } - - /* - * oth_sock waited for cur_sock, - * lets restart it - */ - tevent_fd_set_flags(oth_sock->fde, - TEVENT_FD_READ|TEVENT_FD_WRITE); - } - - ret = read(cur_sock->fd, &v, 1); - if (ret != 1) { - state->finished = true; - state->error = __location__; - return; - } - c = (uint8_t)cur_sock->num_read; - if (c != v) { - state->finished = true; - state->error = __location__; - return; - } - cur_sock->num_read++; - - if (cur_sock->num_read < oth_sock->num_written) { - /* there is more to read */ - return; - } - /* - * we read everything, we need to remove TEVENT_FD_WRITE - * to avoid spinning - */ - TEVENT_FD_NOT_WRITEABLE(cur_sock->fde); - - if (oth_sock->num_read == cur_sock->num_written) { - /* - * both directions are finished - */ - state->finished = true; - } - - return; -} - -static void test_event_fd2_finished(struct tevent_context *ev_ctx, - struct tevent_timer *te, - struct timeval tval, - void *private_data) -{ - struct test_event_fd2_state *state = - (struct test_event_fd2_state *)private_data; - - /* - * this should never be triggered - */ - state->finished = true; - state->error = __location__; -} - -static bool test_event_fd2(struct torture_context *tctx, - const void *test_data) -{ - struct test_event_fd2_state state; - int sock[2]; - uint8_t c = 0; - - ZERO_STRUCT(state); - state.tctx = tctx; - state.backend = (const char *)test_data; - - state.ev = tevent_context_init_byname(tctx, state.backend); - if (state.ev == NULL) { - torture_skip(tctx, talloc_asprintf(tctx, - "event backend '%s' not supported\n", - state.backend)); - return true; - } - - tevent_set_debug_stderr(state.ev); - torture_comment(tctx, "backend '%s' - %s\n", - state.backend, __FUNCTION__); - - /* - * This tests the following - * - * - We write 1 byte to each socket - * - We wait for TEVENT_FD_READ/WRITE on both sockets - * - When we get TEVENT_FD_WRITE we write 1 byte - * until both socket buffers are full, which - * means both sockets only get TEVENT_FD_READ. - * - Then we read 1 byte until we have consumed - * all bytes the other end has written. - */ - sock[0] = -1; - sock[1] = -1; - socketpair(AF_UNIX, SOCK_STREAM, 0, sock); - - /* - * the timer should never expire - */ - state.te = tevent_add_timer(state.ev, state.ev, - timeval_current_ofs(600, 0), - test_event_fd2_finished, &state); - state.sock0.state = &state; - state.sock0.fd = sock[0]; - state.sock0.fde = tevent_add_fd(state.ev, state.ev, - state.sock0.fd, - TEVENT_FD_READ | TEVENT_FD_WRITE, - test_event_fd2_sock_handler, - &state.sock0); - state.sock1.state = &state; - state.sock1.fd = sock[1]; - state.sock1.fde = tevent_add_fd(state.ev, state.ev, - state.sock1.fd, - TEVENT_FD_READ | TEVENT_FD_WRITE, - test_event_fd2_sock_handler, - &state.sock1); - - tevent_fd_set_auto_close(state.sock0.fde); - tevent_fd_set_auto_close(state.sock1.fde); - - do_write(state.sock0.fd, &c, 1); - state.sock0.num_written++; - do_write(state.sock1.fd, &c, 1); - state.sock1.num_written++; - - while (!state.finished) { - errno = 0; - if (tevent_loop_once(state.ev) == -1) { - talloc_free(state.ev); - torture_fail(tctx, talloc_asprintf(tctx, - "Failed event loop %s\n", - strerror(errno))); - } - } - - talloc_free(state.ev); - - torture_assert(tctx, state.error == NULL, talloc_asprintf(tctx, - "%s", state.error)); - - return true; -} - -struct test_wrapper_state { - struct torture_context *tctx; - int num_events; - int num_wrap_handlers; -}; - -static bool test_wrapper_before_use(struct tevent_context *wrap_ev, - void *private_data, - struct tevent_context *main_ev, - const char *location) -{ - struct test_wrapper_state *state = - talloc_get_type_abort(private_data, - struct test_wrapper_state); - - torture_comment(state->tctx, "%s\n", __func__); - state->num_wrap_handlers++; - return true; -} - -static void test_wrapper_after_use(struct tevent_context *wrap_ev, - void *private_data, - struct tevent_context *main_ev, - const char *location) -{ - struct test_wrapper_state *state = - talloc_get_type_abort(private_data, - struct test_wrapper_state); - - torture_comment(state->tctx, "%s\n", __func__); - state->num_wrap_handlers++; -} - -static void test_wrapper_before_fd_handler(struct tevent_context *wrap_ev, - void *private_data, - struct tevent_context *main_ev, - struct tevent_fd *fde, - uint16_t flags, - const char *handler_name, - const char *location) -{ - struct test_wrapper_state *state = - talloc_get_type_abort(private_data, - struct test_wrapper_state); - - torture_comment(state->tctx, "%s\n", __func__); - state->num_wrap_handlers++; -} - -static void test_wrapper_after_fd_handler(struct tevent_context *wrap_ev, - void *private_data, - struct tevent_context *main_ev, - struct tevent_fd *fde, - uint16_t flags, - const char *handler_name, - const char *location) -{ - struct test_wrapper_state *state = - talloc_get_type_abort(private_data, - struct test_wrapper_state); - - torture_comment(state->tctx, "%s\n", __func__); - state->num_wrap_handlers++; -} - -static void test_wrapper_before_timer_handler(struct tevent_context *wrap_ev, - void *private_data, - struct tevent_context *main_ev, - struct tevent_timer *te, - struct timeval requested_time, - struct timeval trigger_time, - const char *handler_name, - const char *location) -{ - struct test_wrapper_state *state = - talloc_get_type_abort(private_data, - struct test_wrapper_state); - - torture_comment(state->tctx, "%s\n", __func__); - state->num_wrap_handlers++; -} - -static void test_wrapper_after_timer_handler(struct tevent_context *wrap_ev, - void *private_data, - struct tevent_context *main_ev, - struct tevent_timer *te, - struct timeval requested_time, - struct timeval trigger_time, - const char *handler_name, - const char *location) -{ - struct test_wrapper_state *state = - talloc_get_type_abort(private_data, - struct test_wrapper_state); - - torture_comment(state->tctx, "%s\n", __func__); - state->num_wrap_handlers++; -} - -static void test_wrapper_before_immediate_handler(struct tevent_context *wrap_ev, - void *private_data, - struct tevent_context *main_ev, - struct tevent_immediate *im, - const char *handler_name, - const char *location) -{ - struct test_wrapper_state *state = - talloc_get_type_abort(private_data, - struct test_wrapper_state); - - torture_comment(state->tctx, "%s\n", __func__); - state->num_wrap_handlers++; -} - -static void test_wrapper_after_immediate_handler(struct tevent_context *wrap_ev, - void *private_data, - struct tevent_context *main_ev, - struct tevent_immediate *im, - const char *handler_name, - const char *location) -{ - struct test_wrapper_state *state = - talloc_get_type_abort(private_data, - struct test_wrapper_state); - - torture_comment(state->tctx, "%s\n", __func__); - state->num_wrap_handlers++; -} - -static void test_wrapper_before_signal_handler(struct tevent_context *wrap_ev, - void *private_data, - struct tevent_context *main_ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - const char *handler_name, - const char *location) -{ - struct test_wrapper_state *state = - talloc_get_type_abort(private_data, - struct test_wrapper_state); - - torture_comment(state->tctx, "%s\n", __func__); - state->num_wrap_handlers++; -} - -static void test_wrapper_after_signal_handler(struct tevent_context *wrap_ev, - void *private_data, - struct tevent_context *main_ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - const char *handler_name, - const char *location) -{ - struct test_wrapper_state *state = - talloc_get_type_abort(private_data, - struct test_wrapper_state); - - torture_comment(state->tctx, "%s\n", __func__); - state->num_wrap_handlers++; -} - -static const struct tevent_wrapper_ops test_wrapper_ops = { - .name = "test_wrapper", - .before_use = test_wrapper_before_use, - .after_use = test_wrapper_after_use, - .before_fd_handler = test_wrapper_before_fd_handler, - .after_fd_handler = test_wrapper_after_fd_handler, - .before_timer_handler = test_wrapper_before_timer_handler, - .after_timer_handler = test_wrapper_after_timer_handler, - .before_immediate_handler = test_wrapper_before_immediate_handler, - .after_immediate_handler = test_wrapper_after_immediate_handler, - .before_signal_handler = test_wrapper_before_signal_handler, - .after_signal_handler = test_wrapper_after_signal_handler, -}; - -static void test_wrapper_timer_handler(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval tv, - void *private_data) -{ - struct test_wrapper_state *state = - (struct test_wrapper_state *)private_data; - - - torture_comment(state->tctx, "timer handler\n"); - - state->num_events++; - talloc_free(te); - return; -} - -static void test_wrapper_fd_handler(struct tevent_context *ev, - struct tevent_fd *fde, - unsigned short fd_flags, - void *private_data) -{ - struct test_wrapper_state *state = - (struct test_wrapper_state *)private_data; - - torture_comment(state->tctx, "fd handler\n"); - - state->num_events++; - talloc_free(fde); - return; -} - -static void test_wrapper_immediate_handler(struct tevent_context *ev, - struct tevent_immediate *im, - void *private_data) -{ - struct test_wrapper_state *state = - (struct test_wrapper_state *)private_data; - - state->num_events++; - talloc_free(im); - - torture_comment(state->tctx, "immediate handler\n"); - return; -} - -static void test_wrapper_signal_handler(struct tevent_context *ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - void *private_data) -{ - struct test_wrapper_state *state = - (struct test_wrapper_state *)private_data; - - torture_comment(state->tctx, "signal handler\n"); - - state->num_events++; - talloc_free(se); - return; -} - -static bool test_wrapper(struct torture_context *tctx, - const void *test_data) -{ - struct test_wrapper_state *state = NULL; - int sock[2] = { -1, -1}; - uint8_t c = 0; - const int num_events = 4; - const char *backend = (const char *)test_data; - struct tevent_context *ev = NULL; - struct tevent_context *wrap_ev = NULL; - struct tevent_fd *fde = NULL; - struct tevent_timer *te = NULL; - struct tevent_signal *se = NULL; - struct tevent_immediate *im = NULL; - int ret; - bool ok = false; - bool ret2; - - ev = tevent_context_init_byname(tctx, backend); - if (ev == NULL) { - torture_skip(tctx, talloc_asprintf(tctx, - "event backend '%s' not supported\n", - backend)); - return true; - } - - tevent_set_debug_stderr(ev); - torture_comment(tctx, "tevent backend '%s'\n", backend); - - wrap_ev = tevent_context_wrapper_create( - ev, ev, &test_wrapper_ops, &state, struct test_wrapper_state); - torture_assert_not_null_goto(tctx, wrap_ev, ok, done, - "tevent_context_wrapper_create failed\n"); - *state = (struct test_wrapper_state) { - .tctx = tctx, - }; - - ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sock); - torture_assert_goto(tctx, ret == 0, ok, done, "socketpair failed\n"); - - te = tevent_add_timer(wrap_ev, wrap_ev, - timeval_current_ofs(0, 0), - test_wrapper_timer_handler, state); - torture_assert_not_null_goto(tctx, te, ok, done, - "tevent_add_timer failed\n"); - - fde = tevent_add_fd(wrap_ev, wrap_ev, - sock[1], - TEVENT_FD_READ, - test_wrapper_fd_handler, - state); - torture_assert_not_null_goto(tctx, fde, ok, done, - "tevent_add_fd failed\n"); - - im = tevent_create_immediate(wrap_ev); - torture_assert_not_null_goto(tctx, im, ok, done, - "tevent_create_immediate failed\n"); - - se = tevent_add_signal(wrap_ev, wrap_ev, - SIGUSR1, - 0, - test_wrapper_signal_handler, - state); - torture_assert_not_null_goto(tctx, se, ok, done, - "tevent_add_signal failed\n"); - - do_write(sock[0], &c, 1); - kill(getpid(), SIGUSR1); - tevent_schedule_immediate(im, - wrap_ev, - test_wrapper_immediate_handler, - state); - - ret2 = tevent_context_push_use(wrap_ev); - torture_assert_goto(tctx, ret2, ok, done, "tevent_context_push_use(wrap_ev) failed\n"); - ret2 = tevent_context_push_use(ev); - torture_assert_goto(tctx, ret2, ok, pop_use, "tevent_context_push_use(ev) failed\n"); - tevent_context_pop_use(ev); - tevent_context_pop_use(wrap_ev); - - ret = tevent_loop_wait(ev); - torture_assert_int_equal_goto(tctx, ret, 0, ok, done, "tevent_loop_wait failed\n"); - - torture_comment(tctx, "Num events: %d\n", state->num_events); - torture_comment(tctx, "Num wrap handlers: %d\n", - state->num_wrap_handlers); - - torture_assert_int_equal_goto(tctx, state->num_events, num_events, ok, done, - "Wrong event count\n"); - torture_assert_int_equal_goto(tctx, state->num_wrap_handlers, - num_events*2+2, - ok, done, "Wrong wrapper count\n"); - - ok = true; - -done: - TALLOC_FREE(wrap_ev); - TALLOC_FREE(ev); - - if (sock[0] != -1) { - close(sock[0]); - } - if (sock[1] != -1) { - close(sock[1]); - } - return ok; -pop_use: - tevent_context_pop_use(wrap_ev); - goto done; -} - -static void test_free_wrapper_signal_handler(struct tevent_context *ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - void *private_data) -{ - struct torture_context *tctx = - talloc_get_type_abort(private_data, - struct torture_context); - - torture_comment(tctx, "signal handler\n"); - - talloc_free(se); - - /* - * signal handlers have highest priority in tevent, so this signal - * handler will always be started before the other handlers - * below. Freeing the (wrapper) event context here tests that the - * wrapper implementation correclty handles the wrapper ev going away - * with pending events. - */ - talloc_free(ev); - return; -} - -static void test_free_wrapper_fd_handler(struct tevent_context *ev, - struct tevent_fd *fde, - unsigned short fd_flags, - void *private_data) -{ - /* - * This should never be called as - * test_free_wrapper_signal_handler() - * already destroyed the wrapper tevent_context. - */ - abort(); -} - -static void test_free_wrapper_immediate_handler(struct tevent_context *ev, - struct tevent_immediate *im, - void *private_data) -{ - /* - * This should never be called as - * test_free_wrapper_signal_handler() - * already destroyed the wrapper tevent_context. - */ - abort(); -} - -static void test_free_wrapper_timer_handler(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval tv, - void *private_data) -{ - /* - * This should never be called as - * test_free_wrapper_signal_handler() - * already destroyed the wrapper tevent_context. - */ - abort(); -} - -static bool test_free_wrapper(struct torture_context *tctx, - const void *test_data) -{ - struct test_wrapper_state *state = NULL; - int sock[2] = { -1, -1}; - uint8_t c = 0; - const char *backend = (const char *)test_data; - TALLOC_CTX *frame = talloc_stackframe(); - struct tevent_context *ev = NULL; - struct tevent_context *wrap_ev = NULL; - struct tevent_fd *fde = NULL; - struct tevent_timer *te = NULL; - struct tevent_signal *se = NULL; - struct tevent_immediate *im = NULL; - int ret; - bool ok = false; - - ev = tevent_context_init_byname(frame, backend); - if (ev == NULL) { - torture_skip(tctx, talloc_asprintf(tctx, - "event backend '%s' not supported\n", - backend)); - return true; - } - - tevent_set_debug_stderr(ev); - torture_comment(tctx, "tevent backend '%s'\n", backend); - - wrap_ev = tevent_context_wrapper_create( - ev, ev, &test_wrapper_ops, &state, struct test_wrapper_state); - torture_assert_not_null_goto(tctx, wrap_ev, ok, done, - "tevent_context_wrapper_create failed\n"); - *state = (struct test_wrapper_state) { - .tctx = tctx, - }; - - ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sock); - torture_assert_goto(tctx, ret == 0, ok, done, "socketpair failed\n"); - - fde = tevent_add_fd(wrap_ev, frame, - sock[1], - TEVENT_FD_READ, - test_free_wrapper_fd_handler, - NULL); - torture_assert_not_null_goto(tctx, fde, ok, done, - "tevent_add_fd failed\n"); - - te = tevent_add_timer(wrap_ev, frame, - timeval_current_ofs(0, 0), - test_free_wrapper_timer_handler, NULL); - torture_assert_not_null_goto(tctx, te, ok, done, - "tevent_add_timer failed\n"); - - im = tevent_create_immediate(frame); - torture_assert_not_null_goto(tctx, im, ok, done, - "tevent_create_immediate failed\n"); - - se = tevent_add_signal(wrap_ev, frame, - SIGUSR1, - 0, - test_free_wrapper_signal_handler, - tctx); - torture_assert_not_null_goto(tctx, se, ok, done, - "tevent_add_signal failed\n"); - - do_write(sock[0], &c, 1); - kill(getpid(), SIGUSR1); - tevent_schedule_immediate(im, - wrap_ev, - test_free_wrapper_immediate_handler, - NULL); - - ret = tevent_loop_wait(ev); - torture_assert_goto(tctx, ret == 0, ok, done, "tevent_loop_wait failed\n"); - - ok = true; - -done: - TALLOC_FREE(frame); - - if (sock[0] != -1) { - close(sock[0]); - } - if (sock[1] != -1) { - close(sock[1]); - } - return ok; -} - -#ifdef HAVE_PTHREAD - -static pthread_mutex_t threaded_mutex = PTHREAD_MUTEX_INITIALIZER; -static bool do_shutdown = false; - -static void test_event_threaded_lock(void) -{ - int ret; - ret = pthread_mutex_lock(&threaded_mutex); - assert(ret == 0); -} - -static void test_event_threaded_unlock(void) -{ - int ret; - ret = pthread_mutex_unlock(&threaded_mutex); - assert(ret == 0); -} - -static void test_event_threaded_trace(enum tevent_trace_point point, - void *private_data) -{ - switch (point) { - case TEVENT_TRACE_BEFORE_WAIT: - test_event_threaded_unlock(); - break; - case TEVENT_TRACE_AFTER_WAIT: - test_event_threaded_lock(); - break; - case TEVENT_TRACE_BEFORE_LOOP_ONCE: - case TEVENT_TRACE_AFTER_LOOP_ONCE: - break; - } -} - -static void test_event_threaded_timer(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval current_time, - void *private_data) -{ - return; -} - -static void *test_event_poll_thread(void *private_data) -{ - struct tevent_context *ev = (struct tevent_context *)private_data; - - test_event_threaded_lock(); - - while (true) { - int ret; - ret = tevent_loop_once(ev); - assert(ret == 0); - if (do_shutdown) { - test_event_threaded_unlock(); - return NULL; - } - } - -} - -static void test_event_threaded_read_handler(struct tevent_context *ev, - struct tevent_fd *fde, - uint16_t flags, - void *private_data) -{ - int *pfd = (int *)private_data; - char c; - ssize_t nread; - - if ((flags & TEVENT_FD_READ) == 0) { - return; - } - - do { - nread = read(*pfd, &c, 1); - } while ((nread == -1) && (errno == EINTR)); - - assert(nread == 1); -} - -static bool test_event_context_threaded(struct torture_context *test, - const void *test_data) -{ - struct tevent_context *ev; - struct tevent_timer *te; - struct tevent_fd *fde; - pthread_t poll_thread; - int fds[2]; - int ret; - char c = 0; - - ev = tevent_context_init_byname(test, "poll_mt"); - torture_assert(test, ev != NULL, "poll_mt not supported"); - - tevent_set_trace_callback(ev, test_event_threaded_trace, NULL); - - te = tevent_add_timer(ev, ev, timeval_current_ofs(5, 0), - test_event_threaded_timer, NULL); - torture_assert(test, te != NULL, "Could not add timer"); - - ret = pthread_create(&poll_thread, NULL, test_event_poll_thread, ev); - torture_assert(test, ret == 0, "Could not create poll thread"); - - ret = pipe(fds); - torture_assert(test, ret == 0, "Could not create pipe"); - - poll(NULL, 0, 100); - - test_event_threaded_lock(); - - fde = tevent_add_fd(ev, ev, fds[0], TEVENT_FD_READ, - test_event_threaded_read_handler, &fds[0]); - torture_assert(test, fde != NULL, "Could not add fd event"); - - test_event_threaded_unlock(); - - poll(NULL, 0, 100); - - do_write(fds[1], &c, 1); - - poll(NULL, 0, 100); - - test_event_threaded_lock(); - do_shutdown = true; - test_event_threaded_unlock(); - - do_write(fds[1], &c, 1); - - ret = pthread_join(poll_thread, NULL); - torture_assert(test, ret == 0, "pthread_join failed"); - - return true; -} - -#define NUM_TEVENT_THREADS 100 - -/* Ugly, but needed for torture_comment... */ -static struct torture_context *thread_test_ctx; -static pthread_t thread_map[NUM_TEVENT_THREADS]; -static unsigned thread_counter; - -/* Called in master thread context */ -static void callback_nowait(struct tevent_context *ev, - struct tevent_immediate *im, - void *private_ptr) -{ - pthread_t *thread_id_ptr = - talloc_get_type_abort(private_ptr, pthread_t); - unsigned i; - - for (i = 0; i < NUM_TEVENT_THREADS; i++) { - if (pthread_equal(*thread_id_ptr, - thread_map[i])) { - break; - } - } - torture_comment(thread_test_ctx, - "Callback %u from thread %u\n", - thread_counter, - i); - thread_counter++; -} - -/* Blast the master tevent_context with a callback, no waiting. */ -static void *thread_fn_nowait(void *private_ptr) -{ - struct tevent_thread_proxy *master_tp = - talloc_get_type_abort(private_ptr, struct tevent_thread_proxy); - struct tevent_immediate *im; - pthread_t *thread_id_ptr; - - im = tevent_create_immediate(NULL); - if (im == NULL) { - return NULL; - } - thread_id_ptr = talloc(NULL, pthread_t); - if (thread_id_ptr == NULL) { - return NULL; - } - *thread_id_ptr = pthread_self(); - - tevent_thread_proxy_schedule(master_tp, - &im, - callback_nowait, - &thread_id_ptr); - return NULL; -} - -static void timeout_fn(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval tv, void *p) -{ - thread_counter = NUM_TEVENT_THREADS * 10; -} - -static bool test_multi_tevent_threaded(struct torture_context *test, - const void *test_data) -{ - unsigned i; - struct tevent_context *master_ev; - struct tevent_thread_proxy *tp; - - talloc_disable_null_tracking(); - - /* Ugly global stuff. */ - thread_test_ctx = test; - thread_counter = 0; - - master_ev = tevent_context_init(NULL); - if (master_ev == NULL) { - return false; - } - tevent_set_debug_stderr(master_ev); - - tp = tevent_thread_proxy_create(master_ev); - if (tp == NULL) { - torture_fail(test, - talloc_asprintf(test, - "tevent_thread_proxy_create failed\n")); - talloc_free(master_ev); - return false; - } - - for (i = 0; i < NUM_TEVENT_THREADS; i++) { - int ret = pthread_create(&thread_map[i], - NULL, - thread_fn_nowait, - tp); - if (ret != 0) { - torture_fail(test, - talloc_asprintf(test, - "Failed to create thread %i, %d\n", - i, ret)); - return false; - } - } - - /* Ensure we don't wait more than 10 seconds. */ - tevent_add_timer(master_ev, - master_ev, - timeval_current_ofs(10,0), - timeout_fn, - NULL); - - while (thread_counter < NUM_TEVENT_THREADS) { - int ret = tevent_loop_once(master_ev); - torture_assert(test, ret == 0, "tevent_loop_once failed"); - } - - torture_assert(test, thread_counter == NUM_TEVENT_THREADS, - "thread_counter fail\n"); - - talloc_free(master_ev); - return true; -} - -struct reply_state { - struct tevent_thread_proxy *reply_tp; - pthread_t thread_id; - int *p_finished; -}; - -static void thread_timeout_fn(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval tv, void *p) -{ - int *p_finished = (int *)p; - - *p_finished = 2; -} - -/* Called in child-thread context */ -static void thread_callback(struct tevent_context *ev, - struct tevent_immediate *im, - void *private_ptr) -{ - struct reply_state *rsp = - talloc_get_type_abort(private_ptr, struct reply_state); - - talloc_steal(ev, rsp); - *rsp->p_finished = 1; -} - -/* Called in master thread context */ -static void master_callback(struct tevent_context *ev, - struct tevent_immediate *im, - void *private_ptr) -{ - struct reply_state *rsp = - talloc_get_type_abort(private_ptr, struct reply_state); - unsigned i; - - talloc_steal(ev, rsp); - - for (i = 0; i < NUM_TEVENT_THREADS; i++) { - if (pthread_equal(rsp->thread_id, - thread_map[i])) { - break; - } - } - torture_comment(thread_test_ctx, - "Callback %u from thread %u\n", - thread_counter, - i); - /* Now reply to the thread ! */ - tevent_thread_proxy_schedule(rsp->reply_tp, - &im, - thread_callback, - &rsp); - - thread_counter++; -} - -static void *thread_fn_1(void *private_ptr) -{ - struct tevent_thread_proxy *master_tp = - talloc_get_type_abort(private_ptr, struct tevent_thread_proxy); - struct tevent_thread_proxy *tp; - struct tevent_immediate *im; - struct tevent_context *ev; - struct reply_state *rsp; - int finished = 0; - int ret; - - ev = tevent_context_init(NULL); - if (ev == NULL) { - return NULL; - } - - tp = tevent_thread_proxy_create(ev); - if (tp == NULL) { - talloc_free(ev); - return NULL; - } - - im = tevent_create_immediate(ev); - if (im == NULL) { - talloc_free(ev); - return NULL; - } - - rsp = talloc(ev, struct reply_state); - if (rsp == NULL) { - talloc_free(ev); - return NULL; - } - - rsp->thread_id = pthread_self(); - rsp->reply_tp = tp; - rsp->p_finished = &finished; - - /* Introduce a little randomness into the mix.. */ - usleep(random() % 7000); - - tevent_thread_proxy_schedule(master_tp, - &im, - master_callback, - &rsp); - - /* Ensure we don't wait more than 10 seconds. */ - tevent_add_timer(ev, - ev, - timeval_current_ofs(10,0), - thread_timeout_fn, - &finished); - - while (finished == 0) { - ret = tevent_loop_once(ev); - assert(ret == 0); - } - - if (finished > 1) { - /* Timeout ! */ - abort(); - } - - /* - * NB. We should talloc_free(ev) here, but if we do - * we currently get hit by helgrind Fix #323432 - * "When calling pthread_cond_destroy or pthread_mutex_destroy - * with initializers as argument Helgrind (incorrectly) reports errors." - * - * http://valgrind.10908.n7.nabble.com/Helgrind-3-9-0-false-positive- - * with-pthread-mutex-destroy-td47757.html - * - * Helgrind doesn't understand that the request/reply - * messages provide synchronization between the lock/unlock - * in tevent_thread_proxy_schedule(), and the pthread_destroy() - * when the struct tevent_thread_proxy object is talloc_free'd. - * - * As a work-around for now return ev for the parent thread to free. - */ - return ev; -} - -static bool test_multi_tevent_threaded_1(struct torture_context *test, - const void *test_data) -{ - unsigned i; - struct tevent_context *master_ev; - struct tevent_thread_proxy *master_tp; - int ret; - - talloc_disable_null_tracking(); - - /* Ugly global stuff. */ - thread_test_ctx = test; - thread_counter = 0; - - master_ev = tevent_context_init(NULL); - if (master_ev == NULL) { - return false; - } - tevent_set_debug_stderr(master_ev); - - master_tp = tevent_thread_proxy_create(master_ev); - if (master_tp == NULL) { - torture_fail(test, - talloc_asprintf(test, - "tevent_thread_proxy_create failed\n")); - talloc_free(master_ev); - return false; - } - - for (i = 0; i < NUM_TEVENT_THREADS; i++) { - ret = pthread_create(&thread_map[i], - NULL, - thread_fn_1, - master_tp); - if (ret != 0) { - torture_fail(test, - talloc_asprintf(test, - "Failed to create thread %i, %d\n", - i, ret)); - return false; - } - } - - while (thread_counter < NUM_TEVENT_THREADS) { - ret = tevent_loop_once(master_ev); - torture_assert(test, ret == 0, "tevent_loop_once failed"); - } - - /* Wait for all the threads to finish - join 'em. */ - for (i = 0; i < NUM_TEVENT_THREADS; i++) { - void *retval; - ret = pthread_join(thread_map[i], &retval); - torture_assert(test, ret == 0, "pthread_join failed"); - /* Free the child thread event context. */ - talloc_free(retval); - } - - talloc_free(master_ev); - return true; -} - -struct threaded_test_2 { - struct tevent_threaded_context *tctx; - struct tevent_immediate *im; - pthread_t thread_id; -}; - -static void master_callback_2(struct tevent_context *ev, - struct tevent_immediate *im, - void *private_data); - -static void *thread_fn_2(void *private_data) -{ - struct threaded_test_2 *state = private_data; - - state->thread_id = pthread_self(); - - usleep(random() % 7000); - - tevent_threaded_schedule_immediate( - state->tctx, state->im, master_callback_2, state); - - return NULL; -} - -static void master_callback_2(struct tevent_context *ev, - struct tevent_immediate *im, - void *private_data) -{ - struct threaded_test_2 *state = private_data; - int i; - - for (i = 0; i < NUM_TEVENT_THREADS; i++) { - if (pthread_equal(state->thread_id, thread_map[i])) { - break; - } - } - torture_comment(thread_test_ctx, - "Callback_2 %u from thread %u\n", - thread_counter, - i); - thread_counter++; -} - -static bool test_multi_tevent_threaded_2(struct torture_context *test, - const void *test_data) -{ - unsigned i; - - struct tevent_context *ev; - struct tevent_threaded_context *tctx; - int ret; - - thread_test_ctx = test; - thread_counter = 0; - - ev = tevent_context_init(test); - torture_assert(test, ev != NULL, "tevent_context_init failed"); - - /* - * tevent_re_initialise used to have a bug where it did not - * re-initialise the thread support after taking it - * down. Exercise that code path. - */ - ret = tevent_re_initialise(ev); - torture_assert(test, ret == 0, "tevent_re_initialise failed"); - - tctx = tevent_threaded_context_create(ev, ev); - torture_assert(test, tctx != NULL, - "tevent_threaded_context_create failed"); - - for (i=0; itctx = tctx; - state->im = tevent_create_immediate(state); - torture_assert(test, state->im != NULL, - "tevent_create_immediate failed"); - - ret = pthread_create(&thread_map[i], NULL, thread_fn_2, state); - torture_assert(test, ret == 0, "pthread_create failed"); - } - - while (thread_counter < NUM_TEVENT_THREADS) { - ret = tevent_loop_once(ev); - torture_assert(test, ret == 0, "tevent_loop_once failed"); - } - - /* Wait for all the threads to finish - join 'em. */ - for (i = 0; i < NUM_TEVENT_THREADS; i++) { - void *retval; - ret = pthread_join(thread_map[i], &retval); - torture_assert(test, ret == 0, "pthread_join failed"); - /* Free the child thread event context. */ - } - - talloc_free(tctx); - talloc_free(ev); - return true; -} -#endif - -struct torture_suite *torture_local_event(TALLOC_CTX *mem_ctx) -{ - struct torture_suite *suite = torture_suite_create(mem_ctx, "event"); - const char **list = tevent_backend_list(suite); - int i; - - for (i=0;list && list[i];i++) { - struct torture_suite *backend_suite; - - backend_suite = torture_suite_create(mem_ctx, list[i]); - - torture_suite_add_simple_tcase_const(backend_suite, - "context", - test_event_context, - (const void *)list[i]); - torture_suite_add_simple_tcase_const(backend_suite, - "fd1", - test_event_fd1, - (const void *)list[i]); - torture_suite_add_simple_tcase_const(backend_suite, - "fd2", - test_event_fd2, - (const void *)list[i]); - torture_suite_add_simple_tcase_const(backend_suite, - "wrapper", - test_wrapper, - (const void *)list[i]); - torture_suite_add_simple_tcase_const(backend_suite, - "free_wrapper", - test_free_wrapper, - (const void *)list[i]); - - torture_suite_add_suite(suite, backend_suite); - } - -#ifdef HAVE_PTHREAD - torture_suite_add_simple_tcase_const(suite, "threaded_poll_mt", - test_event_context_threaded, - NULL); - - torture_suite_add_simple_tcase_const(suite, "multi_tevent_threaded", - test_multi_tevent_threaded, - NULL); - - torture_suite_add_simple_tcase_const(suite, "multi_tevent_threaded_1", - test_multi_tevent_threaded_1, - NULL); - - torture_suite_add_simple_tcase_const(suite, "multi_tevent_threaded_2", - test_multi_tevent_threaded_2, - NULL); - -#endif - - return suite; -} diff --git a/ldb-2.0.8/lib/tevent/tevent.c b/ldb-2.0.8/lib/tevent/tevent.c deleted file mode 100644 index dbec182..0000000 --- a/ldb-2.0.8/lib/tevent/tevent.c +++ /dev/null @@ -1,1037 +0,0 @@ -/* - Unix SMB/CIFS implementation. - main select loop and event handling - Copyright (C) Andrew Tridgell 2003 - Copyright (C) Stefan Metzmacher 2009 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - PLEASE READ THIS BEFORE MODIFYING! - - This module is a general abstraction for the main select loop and - event handling. Do not ever put any localised hacks in here, instead - register one of the possible event types and implement that event - somewhere else. - - There are 2 types of event handling that are handled in this module: - - 1) a file descriptor becoming readable or writeable. This is mostly - used for network sockets, but can be used for any type of file - descriptor. You may only register one handler for each file - descriptor/io combination or you will get unpredictable results - (this means that you can have a handler for read events, and a - separate handler for write events, but not two handlers that are - both handling read events) - - 2) a timed event. You can register an event that happens at a - specific time. You can register as many of these as you - like. They are single shot - add a new timed event in the event - handler to get another event. - - To setup a set of events you first need to create a event_context - structure using the function tevent_context_init(); This returns a - 'struct tevent_context' that you use in all subsequent calls. - - After that you can add/remove events that you are interested in - using tevent_add_*() and talloc_free() - - Finally, you call tevent_loop_wait_once() to block waiting for one of the - events to occor or tevent_loop_wait() which will loop - forever. - -*/ -#include "replace.h" -#include "system/filesys.h" -#ifdef HAVE_PTHREAD -#include "system/threads.h" -#endif -#define TEVENT_DEPRECATED 1 -#include "tevent.h" -#include "tevent_internal.h" -#include "tevent_util.h" -#ifdef HAVE_EVENTFD -#include -#endif - -struct tevent_ops_list { - struct tevent_ops_list *next, *prev; - const char *name; - const struct tevent_ops *ops; -}; - -/* list of registered event backends */ -static struct tevent_ops_list *tevent_backends = NULL; -static char *tevent_default_backend = NULL; - -/* - register an events backend -*/ -bool tevent_register_backend(const char *name, const struct tevent_ops *ops) -{ - struct tevent_ops_list *e; - - for (e = tevent_backends; e != NULL; e = e->next) { - if (0 == strcmp(e->name, name)) { - /* already registered, skip it */ - return true; - } - } - - e = talloc(NULL, struct tevent_ops_list); - if (e == NULL) return false; - - e->name = name; - e->ops = ops; - DLIST_ADD(tevent_backends, e); - - return true; -} - -/* - set the default event backend - */ -void tevent_set_default_backend(const char *backend) -{ - talloc_free(tevent_default_backend); - tevent_default_backend = talloc_strdup(NULL, backend); -} - -/* - initialise backends if not already done -*/ -static void tevent_backend_init(void) -{ - static bool done; - - if (done) { - return; - } - - done = true; - - tevent_poll_init(); - tevent_poll_mt_init(); -#if defined(HAVE_EPOLL) - tevent_epoll_init(); -#elif defined(HAVE_SOLARIS_PORTS) - tevent_port_init(); -#endif - - tevent_standard_init(); -} - -_PRIVATE_ const struct tevent_ops *tevent_find_ops_byname(const char *name) -{ - struct tevent_ops_list *e; - - tevent_backend_init(); - - if (name == NULL) { - name = tevent_default_backend; - } - if (name == NULL) { - name = "standard"; - } - - for (e = tevent_backends; e != NULL; e = e->next) { - if (0 == strcmp(e->name, name)) { - return e->ops; - } - } - - return NULL; -} - -/* - list available backends -*/ -const char **tevent_backend_list(TALLOC_CTX *mem_ctx) -{ - const char **list = NULL; - struct tevent_ops_list *e; - - tevent_backend_init(); - - for (e=tevent_backends;e;e=e->next) { - list = ev_str_list_add(list, e->name); - } - - talloc_steal(mem_ctx, list); - - return list; -} - -static void tevent_common_wakeup_fini(struct tevent_context *ev); - -#ifdef HAVE_PTHREAD - -static pthread_mutex_t tevent_contexts_mutex = PTHREAD_MUTEX_INITIALIZER; -static struct tevent_context *tevent_contexts = NULL; -static pthread_once_t tevent_atfork_initialized = PTHREAD_ONCE_INIT; - -static void tevent_atfork_prepare(void) -{ - struct tevent_context *ev; - int ret; - - ret = pthread_mutex_lock(&tevent_contexts_mutex); - if (ret != 0) { - abort(); - } - - for (ev = tevent_contexts; ev != NULL; ev = ev->next) { - struct tevent_threaded_context *tctx; - - for (tctx = ev->threaded_contexts; tctx != NULL; - tctx = tctx->next) { - ret = pthread_mutex_lock(&tctx->event_ctx_mutex); - if (ret != 0) { - tevent_abort(ev, "pthread_mutex_lock failed"); - } - } - - ret = pthread_mutex_lock(&ev->scheduled_mutex); - if (ret != 0) { - tevent_abort(ev, "pthread_mutex_lock failed"); - } - } -} - -static void tevent_atfork_parent(void) -{ - struct tevent_context *ev; - int ret; - - for (ev = DLIST_TAIL(tevent_contexts); ev != NULL; - ev = DLIST_PREV(ev)) { - struct tevent_threaded_context *tctx; - - ret = pthread_mutex_unlock(&ev->scheduled_mutex); - if (ret != 0) { - tevent_abort(ev, "pthread_mutex_unlock failed"); - } - - for (tctx = DLIST_TAIL(ev->threaded_contexts); tctx != NULL; - tctx = DLIST_PREV(tctx)) { - ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); - if (ret != 0) { - tevent_abort( - ev, "pthread_mutex_unlock failed"); - } - } - } - - ret = pthread_mutex_unlock(&tevent_contexts_mutex); - if (ret != 0) { - abort(); - } -} - -static void tevent_atfork_child(void) -{ - struct tevent_context *ev; - int ret; - - for (ev = DLIST_TAIL(tevent_contexts); ev != NULL; - ev = DLIST_PREV(ev)) { - struct tevent_threaded_context *tctx; - - for (tctx = DLIST_TAIL(ev->threaded_contexts); tctx != NULL; - tctx = DLIST_PREV(tctx)) { - tctx->event_ctx = NULL; - - ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); - if (ret != 0) { - tevent_abort( - ev, "pthread_mutex_unlock failed"); - } - } - - ev->threaded_contexts = NULL; - - ret = pthread_mutex_unlock(&ev->scheduled_mutex); - if (ret != 0) { - tevent_abort(ev, "pthread_mutex_unlock failed"); - } - } - - ret = pthread_mutex_unlock(&tevent_contexts_mutex); - if (ret != 0) { - abort(); - } -} - -static void tevent_prep_atfork(void) -{ - int ret; - - ret = pthread_atfork(tevent_atfork_prepare, - tevent_atfork_parent, - tevent_atfork_child); - if (ret != 0) { - abort(); - } -} - -#endif - -int tevent_common_context_destructor(struct tevent_context *ev) -{ - struct tevent_fd *fd, *fn; - struct tevent_timer *te, *tn; - struct tevent_immediate *ie, *in; - struct tevent_signal *se, *sn; - struct tevent_wrapper_glue *gl, *gn; -#ifdef HAVE_PTHREAD - int ret; -#endif - - if (ev->wrapper.glue != NULL) { - tevent_abort(ev, - "tevent_common_context_destructor() active on wrapper"); - } - -#ifdef HAVE_PTHREAD - ret = pthread_mutex_lock(&tevent_contexts_mutex); - if (ret != 0) { - abort(); - } - - DLIST_REMOVE(tevent_contexts, ev); - - ret = pthread_mutex_unlock(&tevent_contexts_mutex); - if (ret != 0) { - abort(); - } - - while (ev->threaded_contexts != NULL) { - struct tevent_threaded_context *tctx = ev->threaded_contexts; - - ret = pthread_mutex_lock(&tctx->event_ctx_mutex); - if (ret != 0) { - abort(); - } - - /* - * Indicate to the thread that the tevent_context is - * gone. The counterpart of this is in - * _tevent_threaded_schedule_immediate, there we read - * this under the threaded_context's mutex. - */ - - tctx->event_ctx = NULL; - - ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); - if (ret != 0) { - abort(); - } - - DLIST_REMOVE(ev->threaded_contexts, tctx); - } - - ret = pthread_mutex_destroy(&ev->scheduled_mutex); - if (ret != 0) { - abort(); - } -#endif - - for (gl = ev->wrapper.list; gl; gl = gn) { - gn = gl->next; - - gl->main_ev = NULL; - DLIST_REMOVE(ev->wrapper.list, gl); - } - - tevent_common_wakeup_fini(ev); - - for (fd = ev->fd_events; fd; fd = fn) { - fn = fd->next; - fd->wrapper = NULL; - fd->event_ctx = NULL; - DLIST_REMOVE(ev->fd_events, fd); - } - - ev->last_zero_timer = NULL; - for (te = ev->timer_events; te; te = tn) { - tn = te->next; - te->wrapper = NULL; - te->event_ctx = NULL; - DLIST_REMOVE(ev->timer_events, te); - } - - for (ie = ev->immediate_events; ie; ie = in) { - in = ie->next; - ie->wrapper = NULL; - ie->event_ctx = NULL; - ie->cancel_fn = NULL; - DLIST_REMOVE(ev->immediate_events, ie); - } - - for (se = ev->signal_events; se; se = sn) { - sn = se->next; - se->wrapper = NULL; - se->event_ctx = NULL; - DLIST_REMOVE(ev->signal_events, se); - /* - * This is important, Otherwise signals - * are handled twice in child. eg, SIGHUP. - * one added in parent, and another one in - * the child. -- BoYang - */ - tevent_cleanup_pending_signal_handlers(se); - } - - /* removing nesting hook or we get an abort when nesting is - * not allowed. -- SSS - * Note that we need to leave the allowed flag at its current - * value, otherwise the use in tevent_re_initialise() will - * leave the event context with allowed forced to false, which - * will break users that expect nesting to be allowed - */ - ev->nesting.level = 0; - ev->nesting.hook_fn = NULL; - ev->nesting.hook_private = NULL; - - return 0; -} - -static int tevent_common_context_constructor(struct tevent_context *ev) -{ - int ret; - -#ifdef HAVE_PTHREAD - - ret = pthread_once(&tevent_atfork_initialized, tevent_prep_atfork); - if (ret != 0) { - return ret; - } - - ret = pthread_mutex_init(&ev->scheduled_mutex, NULL); - if (ret != 0) { - return ret; - } - - ret = pthread_mutex_lock(&tevent_contexts_mutex); - if (ret != 0) { - pthread_mutex_destroy(&ev->scheduled_mutex); - return ret; - } - - DLIST_ADD(tevent_contexts, ev); - - ret = pthread_mutex_unlock(&tevent_contexts_mutex); - if (ret != 0) { - abort(); - } -#endif - - talloc_set_destructor(ev, tevent_common_context_destructor); - - return 0; -} - -void tevent_common_check_double_free(TALLOC_CTX *ptr, const char *reason) -{ - void *parent_ptr = talloc_parent(ptr); - size_t parent_blocks = talloc_total_blocks(parent_ptr); - - if (parent_ptr != NULL && parent_blocks == 0) { - /* - * This is an implicit talloc free, as we still have a parent - * but it's already being destroyed. Note that - * talloc_total_blocks(ptr) also just returns 0 if a - * talloc_free(ptr) is still in progress of freeing all - * children. - */ - return; - } - - tevent_abort(NULL, reason); -} - -/* - create a event_context structure for a specific implemementation. - This must be the first events call, and all subsequent calls pass - this event_context as the first element. Event handlers also - receive this as their first argument. - - This function is for allowing third-party-applications to hook in gluecode - to their own event loop code, so that they can make async usage of our client libs - - NOTE: use tevent_context_init() inside of samba! -*/ -struct tevent_context *tevent_context_init_ops(TALLOC_CTX *mem_ctx, - const struct tevent_ops *ops, - void *additional_data) -{ - struct tevent_context *ev; - int ret; - - ev = talloc_zero(mem_ctx, struct tevent_context); - if (!ev) return NULL; - - ret = tevent_common_context_constructor(ev); - if (ret != 0) { - talloc_free(ev); - return NULL; - } - - ev->ops = ops; - ev->additional_data = additional_data; - - ret = ev->ops->context_init(ev); - if (ret != 0) { - talloc_free(ev); - return NULL; - } - - return ev; -} - -/* - create a event_context structure. This must be the first events - call, and all subsequent calls pass this event_context as the first - element. Event handlers also receive this as their first argument. -*/ -struct tevent_context *tevent_context_init_byname(TALLOC_CTX *mem_ctx, - const char *name) -{ - const struct tevent_ops *ops; - - ops = tevent_find_ops_byname(name); - if (ops == NULL) { - return NULL; - } - - return tevent_context_init_ops(mem_ctx, ops, NULL); -} - - -/* - create a event_context structure. This must be the first events - call, and all subsequent calls pass this event_context as the first - element. Event handlers also receive this as their first argument. -*/ -struct tevent_context *tevent_context_init(TALLOC_CTX *mem_ctx) -{ - return tevent_context_init_byname(mem_ctx, NULL); -} - -/* - add a fd based event - return NULL on failure (memory allocation error) -*/ -struct tevent_fd *_tevent_add_fd(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - int fd, - uint16_t flags, - tevent_fd_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ - return ev->ops->add_fd(ev, mem_ctx, fd, flags, handler, private_data, - handler_name, location); -} - -/* - set a close function on the fd event -*/ -void tevent_fd_set_close_fn(struct tevent_fd *fde, - tevent_fd_close_fn_t close_fn) -{ - if (!fde) return; - if (!fde->event_ctx) return; - fde->event_ctx->ops->set_fd_close_fn(fde, close_fn); -} - -static void tevent_fd_auto_close_fn(struct tevent_context *ev, - struct tevent_fd *fde, - int fd, - void *private_data) -{ - close(fd); -} - -void tevent_fd_set_auto_close(struct tevent_fd *fde) -{ - tevent_fd_set_close_fn(fde, tevent_fd_auto_close_fn); -} - -/* - return the fd event flags -*/ -uint16_t tevent_fd_get_flags(struct tevent_fd *fde) -{ - if (!fde) return 0; - if (!fde->event_ctx) return 0; - return fde->event_ctx->ops->get_fd_flags(fde); -} - -/* - set the fd event flags -*/ -void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags) -{ - if (!fde) return; - if (!fde->event_ctx) return; - fde->event_ctx->ops->set_fd_flags(fde, flags); -} - -bool tevent_signal_support(struct tevent_context *ev) -{ - if (ev->ops->add_signal) { - return true; - } - return false; -} - -static void (*tevent_abort_fn)(const char *reason); - -void tevent_set_abort_fn(void (*abort_fn)(const char *reason)) -{ - tevent_abort_fn = abort_fn; -} - -void tevent_abort(struct tevent_context *ev, const char *reason) -{ - if (ev != NULL) { - tevent_debug(ev, TEVENT_DEBUG_FATAL, - "abort: %s\n", reason); - } - - if (!tevent_abort_fn) { - abort(); - } - - tevent_abort_fn(reason); -} - -/* - add a timer event - return NULL on failure -*/ -struct tevent_timer *_tevent_add_timer(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - struct timeval next_event, - tevent_timer_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ - return ev->ops->add_timer(ev, mem_ctx, next_event, handler, private_data, - handler_name, location); -} - -/* - allocate an immediate event - return NULL on failure (memory allocation error) -*/ -struct tevent_immediate *_tevent_create_immediate(TALLOC_CTX *mem_ctx, - const char *location) -{ - struct tevent_immediate *im; - - im = talloc(mem_ctx, struct tevent_immediate); - if (im == NULL) return NULL; - - *im = (struct tevent_immediate) { .create_location = location }; - - return im; -} - -/* - schedule an immediate event -*/ -void _tevent_schedule_immediate(struct tevent_immediate *im, - struct tevent_context *ev, - tevent_immediate_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ - ev->ops->schedule_immediate(im, ev, handler, private_data, - handler_name, location); -} - -/* - add a signal event - - sa_flags are flags to sigaction(2) - - return NULL on failure -*/ -struct tevent_signal *_tevent_add_signal(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - int signum, - int sa_flags, - tevent_signal_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ - return ev->ops->add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data, - handler_name, location); -} - -void tevent_loop_allow_nesting(struct tevent_context *ev) -{ - if (ev->wrapper.glue != NULL) { - tevent_abort(ev, "tevent_loop_allow_nesting() on wrapper"); - return; - } - - if (ev->wrapper.list != NULL) { - tevent_abort(ev, "tevent_loop_allow_nesting() with wrapper"); - return; - } - - ev->nesting.allowed = true; -} - -void tevent_loop_set_nesting_hook(struct tevent_context *ev, - tevent_nesting_hook hook, - void *private_data) -{ - if (ev->nesting.hook_fn && - (ev->nesting.hook_fn != hook || - ev->nesting.hook_private != private_data)) { - /* the way the nesting hook code is currently written - we cannot support two different nesting hooks at the - same time. */ - tevent_abort(ev, "tevent: Violation of nesting hook rules\n"); - } - ev->nesting.hook_fn = hook; - ev->nesting.hook_private = private_data; -} - -static void tevent_abort_nesting(struct tevent_context *ev, const char *location) -{ - const char *reason; - - reason = talloc_asprintf(NULL, "tevent_loop_once() nesting at %s", - location); - if (!reason) { - reason = "tevent_loop_once() nesting"; - } - - tevent_abort(ev, reason); -} - -/* - do a single event loop using the events defined in ev -*/ -int _tevent_loop_once(struct tevent_context *ev, const char *location) -{ - int ret; - void *nesting_stack_ptr = NULL; - - ev->nesting.level++; - - if (ev->nesting.level > 1) { - if (!ev->nesting.allowed) { - tevent_abort_nesting(ev, location); - errno = ELOOP; - return -1; - } - } - if (ev->nesting.level > 0) { - if (ev->nesting.hook_fn) { - int ret2; - ret2 = ev->nesting.hook_fn(ev, - ev->nesting.hook_private, - ev->nesting.level, - true, - (void *)&nesting_stack_ptr, - location); - if (ret2 != 0) { - ret = ret2; - goto done; - } - } - } - - tevent_trace_point_callback(ev, TEVENT_TRACE_BEFORE_LOOP_ONCE); - ret = ev->ops->loop_once(ev, location); - tevent_trace_point_callback(ev, TEVENT_TRACE_AFTER_LOOP_ONCE); - - if (ev->nesting.level > 0) { - if (ev->nesting.hook_fn) { - int ret2; - ret2 = ev->nesting.hook_fn(ev, - ev->nesting.hook_private, - ev->nesting.level, - false, - (void *)&nesting_stack_ptr, - location); - if (ret2 != 0) { - ret = ret2; - goto done; - } - } - } - -done: - ev->nesting.level--; - return ret; -} - -/* - this is a performance optimization for the samba4 nested event loop problems -*/ -int _tevent_loop_until(struct tevent_context *ev, - bool (*finished)(void *private_data), - void *private_data, - const char *location) -{ - int ret = 0; - void *nesting_stack_ptr = NULL; - - ev->nesting.level++; - - if (ev->nesting.level > 1) { - if (!ev->nesting.allowed) { - tevent_abort_nesting(ev, location); - errno = ELOOP; - return -1; - } - } - if (ev->nesting.level > 0) { - if (ev->nesting.hook_fn) { - int ret2; - ret2 = ev->nesting.hook_fn(ev, - ev->nesting.hook_private, - ev->nesting.level, - true, - (void *)&nesting_stack_ptr, - location); - if (ret2 != 0) { - ret = ret2; - goto done; - } - } - } - - while (!finished(private_data)) { - tevent_trace_point_callback(ev, TEVENT_TRACE_BEFORE_LOOP_ONCE); - ret = ev->ops->loop_once(ev, location); - tevent_trace_point_callback(ev, TEVENT_TRACE_AFTER_LOOP_ONCE); - if (ret != 0) { - break; - } - } - - if (ev->nesting.level > 0) { - if (ev->nesting.hook_fn) { - int ret2; - ret2 = ev->nesting.hook_fn(ev, - ev->nesting.hook_private, - ev->nesting.level, - false, - (void *)&nesting_stack_ptr, - location); - if (ret2 != 0) { - ret = ret2; - goto done; - } - } - } - -done: - ev->nesting.level--; - return ret; -} - -bool tevent_common_have_events(struct tevent_context *ev) -{ - if (ev->fd_events != NULL) { - if (ev->fd_events != ev->wakeup_fde) { - return true; - } - if (ev->fd_events->next != NULL) { - return true; - } - - /* - * At this point we just have the wakeup pipe event as - * the only fd_event. That one does not count as a - * regular event, so look at the other event types. - */ - } - - return ((ev->timer_events != NULL) || - (ev->immediate_events != NULL) || - (ev->signal_events != NULL)); -} - -/* - return on failure or (with 0) if all fd events are removed -*/ -int tevent_common_loop_wait(struct tevent_context *ev, - const char *location) -{ - /* - * loop as long as we have events pending - */ - while (tevent_common_have_events(ev)) { - int ret; - ret = _tevent_loop_once(ev, location); - if (ret != 0) { - tevent_debug(ev, TEVENT_DEBUG_FATAL, - "_tevent_loop_once() failed: %d - %s\n", - ret, strerror(errno)); - return ret; - } - } - - tevent_debug(ev, TEVENT_DEBUG_WARNING, - "tevent_common_loop_wait() out of events\n"); - return 0; -} - -/* - return on failure or (with 0) if all fd events are removed -*/ -int _tevent_loop_wait(struct tevent_context *ev, const char *location) -{ - return ev->ops->loop_wait(ev, location); -} - - -/* - re-initialise a tevent context. This leaves you with the same - event context, but all events are wiped and the structure is - re-initialised. This is most useful after a fork() - - zero is returned on success, non-zero on failure -*/ -int tevent_re_initialise(struct tevent_context *ev) -{ - tevent_common_context_destructor(ev); - - tevent_common_context_constructor(ev); - - return ev->ops->context_init(ev); -} - -static void wakeup_pipe_handler(struct tevent_context *ev, - struct tevent_fd *fde, - uint16_t flags, void *_private) -{ - ssize_t ret; - - do { - /* - * This is the boilerplate for eventfd, but it works - * for pipes too. And as we don't care about the data - * we read, we're fine. - */ - uint64_t val; - ret = read(fde->fd, &val, sizeof(val)); - } while (ret == -1 && errno == EINTR); -} - -/* - * Initialize the wakeup pipe and pipe fde - */ - -int tevent_common_wakeup_init(struct tevent_context *ev) -{ - int ret, read_fd; - - if (ev->wakeup_fde != NULL) { - return 0; - } - -#ifdef HAVE_EVENTFD - ret = eventfd(0, EFD_NONBLOCK); - if (ret == -1) { - return errno; - } - read_fd = ev->wakeup_fd = ret; -#else - { - int pipe_fds[2]; - ret = pipe(pipe_fds); - if (ret == -1) { - return errno; - } - ev->wakeup_fd = pipe_fds[1]; - ev->wakeup_read_fd = pipe_fds[0]; - - ev_set_blocking(ev->wakeup_fd, false); - ev_set_blocking(ev->wakeup_read_fd, false); - - read_fd = ev->wakeup_read_fd; - } -#endif - - ev->wakeup_fde = tevent_add_fd(ev, ev, read_fd, TEVENT_FD_READ, - wakeup_pipe_handler, NULL); - if (ev->wakeup_fde == NULL) { - close(ev->wakeup_fd); -#ifndef HAVE_EVENTFD - close(ev->wakeup_read_fd); -#endif - return ENOMEM; - } - - return 0; -} - -int tevent_common_wakeup_fd(int fd) -{ - ssize_t ret; - - do { -#ifdef HAVE_EVENTFD - uint64_t val = 1; - ret = write(fd, &val, sizeof(val)); -#else - char c = '\0'; - ret = write(fd, &c, 1); -#endif - } while ((ret == -1) && (errno == EINTR)); - - return 0; -} - -int tevent_common_wakeup(struct tevent_context *ev) -{ - if (ev->wakeup_fde == NULL) { - return ENOTCONN; - } - - return tevent_common_wakeup_fd(ev->wakeup_fd); -} - -static void tevent_common_wakeup_fini(struct tevent_context *ev) -{ - if (ev->wakeup_fde == NULL) { - return; - } - - TALLOC_FREE(ev->wakeup_fde); - - close(ev->wakeup_fd); -#ifndef HAVE_EVENTFD - close(ev->wakeup_read_fd); -#endif -} diff --git a/ldb-2.0.8/lib/tevent/tevent.h b/ldb-2.0.8/lib/tevent/tevent.h deleted file mode 100644 index 3c3e3cc..0000000 --- a/ldb-2.0.8/lib/tevent/tevent.h +++ /dev/null @@ -1,2511 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - generalised event loop handling - - Copyright (C) Andrew Tridgell 2005 - Copyright (C) Stefan Metzmacher 2005-2009 - Copyright (C) Volker Lendecke 2008 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#ifndef __TEVENT_H__ -#define __TEVENT_H__ - -#include -#include -#include -#include - -struct tevent_context; -struct tevent_ops; -struct tevent_fd; -struct tevent_timer; -struct tevent_immediate; -struct tevent_signal; -struct tevent_thread_proxy; -struct tevent_threaded_context; - -/** - * @defgroup tevent The tevent API - * - * The tevent low-level API - * - * This API provides the public interface to manage events in the tevent - * mainloop. Functions are provided for managing low-level events such - * as timer events, fd events and signal handling. - * - * @{ - */ - -/* event handler types */ -/** - * Called when a file descriptor monitored by tevent has - * data to be read or written on it. - */ -typedef void (*tevent_fd_handler_t)(struct tevent_context *ev, - struct tevent_fd *fde, - uint16_t flags, - void *private_data); - -/** - * Called when tevent is ceasing the monitoring of a file descriptor. - */ -typedef void (*tevent_fd_close_fn_t)(struct tevent_context *ev, - struct tevent_fd *fde, - int fd, - void *private_data); - -/** - * Called when a tevent timer has fired. - */ -typedef void (*tevent_timer_handler_t)(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval current_time, - void *private_data); - -/** - * Called when a tevent immediate event is invoked. - */ -typedef void (*tevent_immediate_handler_t)(struct tevent_context *ctx, - struct tevent_immediate *im, - void *private_data); - -/** - * Called after tevent detects the specified signal. - */ -typedef void (*tevent_signal_handler_t)(struct tevent_context *ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - void *private_data); - -/** - * @brief Create a event_context structure. - * - * This must be the first events call, and all subsequent calls pass this - * event_context as the first element. Event handlers also receive this as - * their first argument. - * - * @param[in] mem_ctx The memory context to use. - * - * @return An allocated tevent context, NULL on error. - * - * @see tevent_context_init() - */ -struct tevent_context *tevent_context_init(TALLOC_CTX *mem_ctx); - -/** - * @brief Create a event_context structure and select a specific backend. - * - * This must be the first events call, and all subsequent calls pass this - * event_context as the first element. Event handlers also receive this as - * their first argument. - * - * @param[in] mem_ctx The memory context to use. - * - * @param[in] name The name of the backend to use. - * - * @return An allocated tevent context, NULL on error. - */ -struct tevent_context *tevent_context_init_byname(TALLOC_CTX *mem_ctx, const char *name); - -/** - * @brief Create a custom event context - * - * @param[in] mem_ctx The memory context to use. - * @param[in] ops The function pointer table of the backend. - * @param[in] additional_data The additional/private data to this instance - * - * @return An allocated tevent context, NULL on error. - * - */ -struct tevent_context *tevent_context_init_ops(TALLOC_CTX *mem_ctx, - const struct tevent_ops *ops, - void *additional_data); - -/** - * @brief List available backends. - * - * @param[in] mem_ctx The memory context to use. - * - * @return A string vector with a terminating NULL element, NULL - * on error. - */ -const char **tevent_backend_list(TALLOC_CTX *mem_ctx); - -/** - * @brief Set the default tevent backend. - * - * @param[in] backend The name of the backend to set. - */ -void tevent_set_default_backend(const char *backend); - -#ifdef DOXYGEN -/** - * @brief Add a file descriptor based event. - * - * @param[in] ev The event context to work on. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] fd The file descriptor to base the event on. - * - * @param[in] flags #TEVENT_FD_READ or #TEVENT_FD_WRITE - * - * @param[in] handler The callback handler for the event. - * - * @param[in] private_data The private data passed to the callback handler. - * - * @return The file descriptor based event, NULL on error. - * - * @note To cancel the monitoring of a file descriptor, call talloc_free() - * on the object returned by this function. - * - * @note The caller should avoid closing the file descriptor before - * calling talloc_free()! Otherwise the behaviour is undefined which - * might result in crashes. See https://bugzilla.samba.org/show_bug.cgi?id=11141 - * for an example. - */ -struct tevent_fd *tevent_add_fd(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - int fd, - uint16_t flags, - tevent_fd_handler_t handler, - void *private_data); -#else -struct tevent_fd *_tevent_add_fd(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - int fd, - uint16_t flags, - tevent_fd_handler_t handler, - void *private_data, - const char *handler_name, - const char *location); -#define tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data) \ - _tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data, \ - #handler, __location__) -#endif - -#ifdef DOXYGEN -/** - * @brief Add a timed event - * - * @param[in] ev The event context to work on. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] next_event Timeval specifying the absolute time to fire this - * event. This is not an offset. - * - * @param[in] handler The callback handler for the event. - * - * @param[in] private_data The private data passed to the callback handler. - * - * @return The newly-created timer event, or NULL on error. - * - * @note To cancel a timer event before it fires, call talloc_free() on the - * event returned from this function. This event is automatically - * talloc_free()-ed after its event handler files, if it hasn't been freed yet. - * - * @note Unlike some mainloops, tevent timers are one-time events. To set up - * a recurring event, it is necessary to call tevent_add_timer() again during - * the handler processing. - * - * @note Due to the internal mainloop processing, a timer set to run - * immediately will do so after any other pending timers fire, but before - * any further file descriptor or signal handling events fire. Callers should - * not rely on this behavior! - */ -struct tevent_timer *tevent_add_timer(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - struct timeval next_event, - tevent_timer_handler_t handler, - void *private_data); -#else -struct tevent_timer *_tevent_add_timer(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - struct timeval next_event, - tevent_timer_handler_t handler, - void *private_data, - const char *handler_name, - const char *location); -#define tevent_add_timer(ev, mem_ctx, next_event, handler, private_data) \ - _tevent_add_timer(ev, mem_ctx, next_event, handler, private_data, \ - #handler, __location__) -#endif - -/** - * @brief Set the time a tevent_timer fires - * - * @param[in] te The timer event to reset - * - * @param[in] next_event Timeval specifying the absolute time to fire this - * event. This is not an offset. - */ -void tevent_update_timer(struct tevent_timer *te, struct timeval next_event); - -#ifdef DOXYGEN -/** - * Initialize an immediate event object - * - * This object can be used to trigger an event to occur immediately after - * returning from the current event (before any other event occurs) - * - * @param[in] mem_ctx The talloc memory context to use as the parent - * - * @return An empty tevent_immediate object. Use tevent_schedule_immediate - * to populate and use it. - * - * @note Available as of tevent 0.9.8 - */ -struct tevent_immediate *tevent_create_immediate(TALLOC_CTX *mem_ctx); -#else -struct tevent_immediate *_tevent_create_immediate(TALLOC_CTX *mem_ctx, - const char *location); -#define tevent_create_immediate(mem_ctx) \ - _tevent_create_immediate(mem_ctx, __location__) -#endif - -#ifdef DOXYGEN - -/** - * Schedule an event for immediate execution. This event will occur - * immediately after returning from the current event (before any other - * event occurs) - * - * @param[in] im The tevent_immediate object to populate and use - * @param[in] ctx The tevent_context to run this event - * @param[in] handler The event handler to run when this event fires - * @param[in] private_data Data to pass to the event handler - */ -void tevent_schedule_immediate(struct tevent_immediate *im, - struct tevent_context *ctx, - tevent_immediate_handler_t handler, - void *private_data); -#else -void _tevent_schedule_immediate(struct tevent_immediate *im, - struct tevent_context *ctx, - tevent_immediate_handler_t handler, - void *private_data, - const char *handler_name, - const char *location); -#define tevent_schedule_immediate(im, ctx, handler, private_data) \ - _tevent_schedule_immediate(im, ctx, handler, private_data, \ - #handler, __location__); -#endif - -#ifdef DOXYGEN -/** - * @brief Add a tevent signal handler - * - * tevent_add_signal() creates a new event for handling a signal the next - * time through the mainloop. It implements a very simple traditional signal - * handler whose only purpose is to add the handler event into the mainloop. - * - * @param[in] ev The event context to work on. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] signum The signal to trap - * - * @param[in] handler The callback handler for the signal. - * - * @param[in] sa_flags sigaction flags for this signal handler. - * - * @param[in] private_data The private data passed to the callback handler. - * - * @return The newly-created signal handler event, or NULL on error. - * - * @note To cancel a signal handler, call talloc_free() on the event returned - * from this function. - * - * @see tevent_num_signals, tevent_sa_info_queue_count - */ -struct tevent_signal *tevent_add_signal(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - int signum, - int sa_flags, - tevent_signal_handler_t handler, - void *private_data); -#else -struct tevent_signal *_tevent_add_signal(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - int signum, - int sa_flags, - tevent_signal_handler_t handler, - void *private_data, - const char *handler_name, - const char *location); -#define tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data) \ - _tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data, \ - #handler, __location__) -#endif - -/** - * @brief the number of supported signals - * - * This returns value of the configure time TEVENT_NUM_SIGNALS constant. - * - * The 'signum' argument of tevent_add_signal() must be less than - * TEVENT_NUM_SIGNALS. - * - * @see tevent_add_signal - */ -size_t tevent_num_signals(void); - -/** - * @brief the number of pending realtime signals - * - * This returns value of TEVENT_SA_INFO_QUEUE_COUNT. - * - * The tevent internals remember the last TEVENT_SA_INFO_QUEUE_COUNT - * siginfo_t structures for SA_SIGINFO signals. If the system generates - * more some signals get lost. - * - * @see tevent_add_signal - */ -size_t tevent_sa_info_queue_count(void); - -#ifdef DOXYGEN -/** - * @brief Pass a single time through the mainloop - * - * This will process any appropriate signal, immediate, fd and timer events - * - * @param[in] ev The event context to process - * - * @return Zero on success, nonzero if an internal error occurred - */ -int tevent_loop_once(struct tevent_context *ev); -#else -int _tevent_loop_once(struct tevent_context *ev, const char *location); -#define tevent_loop_once(ev) \ - _tevent_loop_once(ev, __location__) -#endif - -#ifdef DOXYGEN -/** - * @brief Run the mainloop - * - * The mainloop will run until there are no events remaining to be processed - * - * @param[in] ev The event context to process - * - * @return Zero if all events have been processed. Nonzero if an internal - * error occurred. - */ -int tevent_loop_wait(struct tevent_context *ev); -#else -int _tevent_loop_wait(struct tevent_context *ev, const char *location); -#define tevent_loop_wait(ev) \ - _tevent_loop_wait(ev, __location__) -#endif - - -/** - * Assign a function to run when a tevent_fd is freed - * - * This function is a destructor for the tevent_fd. It does not automatically - * close the file descriptor. If this is the desired behavior, then it must be - * performed by the close_fn. - * - * @param[in] fde File descriptor event on which to set the destructor - * @param[in] close_fn Destructor to execute when fde is freed - * - * @note That the close_fn() on tevent_fd is *NOT* wrapped on contexts - * created by tevent_context_wrapper_create()! - * - * @see tevent_fd_set_close_fn - * @see tevent_context_wrapper_create - */ -void tevent_fd_set_close_fn(struct tevent_fd *fde, - tevent_fd_close_fn_t close_fn); - -/** - * Automatically close the file descriptor when the tevent_fd is freed - * - * This function calls close(fd) internally. - * - * @param[in] fde File descriptor event to auto-close - * - * @see tevent_fd_set_close_fn - */ -void tevent_fd_set_auto_close(struct tevent_fd *fde); - -/** - * Return the flags set on this file descriptor event - * - * @param[in] fde File descriptor event to query - * - * @return The flags set on the event. See #TEVENT_FD_READ and - * #TEVENT_FD_WRITE - */ -uint16_t tevent_fd_get_flags(struct tevent_fd *fde); - -/** - * Set flags on a file descriptor event - * - * @param[in] fde File descriptor event to set - * @param[in] flags Flags to set on the event. See #TEVENT_FD_READ and - * #TEVENT_FD_WRITE - */ -void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags); - -/** - * Query whether tevent supports signal handling - * - * @param[in] ev An initialized tevent context - * - * @return True if this platform and tevent context support signal handling - */ -bool tevent_signal_support(struct tevent_context *ev); - -void tevent_set_abort_fn(void (*abort_fn)(const char *reason)); - -/* bits for file descriptor event flags */ - -/** - * Monitor a file descriptor for data to be read - */ -#define TEVENT_FD_READ 1 -/** - * Monitor a file descriptor for writeability - */ -#define TEVENT_FD_WRITE 2 - -/** - * Convenience function for declaring a tevent_fd writable - */ -#define TEVENT_FD_WRITEABLE(fde) \ - tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) | TEVENT_FD_WRITE) - -/** - * Convenience function for declaring a tevent_fd readable - */ -#define TEVENT_FD_READABLE(fde) \ - tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) | TEVENT_FD_READ) - -/** - * Convenience function for declaring a tevent_fd non-writable - */ -#define TEVENT_FD_NOT_WRITEABLE(fde) \ - tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) & ~TEVENT_FD_WRITE) - -/** - * Convenience function for declaring a tevent_fd non-readable - */ -#define TEVENT_FD_NOT_READABLE(fde) \ - tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) & ~TEVENT_FD_READ) - -/** - * Debug level of tevent - */ -enum tevent_debug_level { - TEVENT_DEBUG_FATAL, - TEVENT_DEBUG_ERROR, - TEVENT_DEBUG_WARNING, - TEVENT_DEBUG_TRACE -}; - -/** - * @brief The tevent debug callbac. - * - * @param[in] context The memory context to use. - * - * @param[in] level The debug level. - * - * @param[in] fmt The format string. - * - * @param[in] ap The arguments for the format string. - */ -typedef void (*tevent_debug_fn)(void *context, - enum tevent_debug_level level, - const char *fmt, - va_list ap) PRINTF_ATTRIBUTE(3,0); - -/** - * Set destination for tevent debug messages - * - * @param[in] ev Event context to debug - * @param[in] debug Function to handle output printing - * @param[in] context The context to pass to the debug function. - * - * @return Always returns 0 as of version 0.9.8 - * - * @note Default is to emit no debug messages - */ -int tevent_set_debug(struct tevent_context *ev, - tevent_debug_fn debug, - void *context); - -/** - * Designate stderr for debug message output - * - * @param[in] ev Event context to debug - * - * @note This function will only output TEVENT_DEBUG_FATAL, TEVENT_DEBUG_ERROR - * and TEVENT_DEBUG_WARNING messages. For TEVENT_DEBUG_TRACE, please define a - * function for tevent_set_debug() - */ -int tevent_set_debug_stderr(struct tevent_context *ev); - -enum tevent_trace_point { - /** - * Corresponds to a trace point just before waiting - */ - TEVENT_TRACE_BEFORE_WAIT, - /** - * Corresponds to a trace point just after waiting - */ - TEVENT_TRACE_AFTER_WAIT, -#define TEVENT_HAS_LOOP_ONCE_TRACE_POINTS 1 - /** - * Corresponds to a trace point just before calling - * the loop_once() backend function. - */ - TEVENT_TRACE_BEFORE_LOOP_ONCE, - /** - * Corresponds to a trace point right after the - * loop_once() backend function has returned. - */ - TEVENT_TRACE_AFTER_LOOP_ONCE, -}; - -typedef void (*tevent_trace_callback_t)(enum tevent_trace_point, - void *private_data); - -/** - * Register a callback to be called at certain trace points - * - * @param[in] ev Event context - * @param[in] cb Trace callback - * @param[in] private_data Data to be passed to callback - * - * @note The callback will be called at trace points defined by - * tevent_trace_point. Call with NULL to reset. - */ -void tevent_set_trace_callback(struct tevent_context *ev, - tevent_trace_callback_t cb, - void *private_data); - -/** - * Retrieve the current trace callback - * - * @param[in] ev Event context - * @param[out] cb Registered trace callback - * @param[out] private_data Registered data to be passed to callback - * - * @note This can be used to allow one component that wants to - * register a callback to respect the callback that another component - * has already registered. - */ -void tevent_get_trace_callback(struct tevent_context *ev, - tevent_trace_callback_t *cb, - void *private_data); - -/** - * @} - */ - -/** - * @defgroup tevent_request The tevent request functions. - * @ingroup tevent - * - * A tevent_req represents an asynchronous computation. - * - * The tevent_req group of API calls is the recommended way of - * programming async computations within tevent. In particular the - * file descriptor (tevent_add_fd) and timer (tevent_add_timed) events - * are considered too low-level to be used in larger computations. To - * read and write from and to sockets, Samba provides two calls on top - * of tevent_add_fd: tstream_read_packet_send/recv and tstream_writev_send/recv. - * These requests are much easier to compose than the low-level event - * handlers called from tevent_add_fd. - * - * A lot of the simplicity tevent_req has brought to the notoriously - * hairy async programming came via a set of conventions that every - * async computation programmed should follow. One central piece of - * these conventions is the naming of routines and variables. - * - * Every async computation needs a name (sensibly called "computation" - * down from here). From this name quite a few naming conventions are - * derived. - * - * Every computation that requires local state needs a - * @code - * struct computation_state { - * int local_var; - * }; - * @endcode - * Even if no local variables are required, such a state struct should - * be created containing a dummy variable. Quite a few helper - * functions and macros (for example tevent_req_create()) assume such - * a state struct. - * - * An async computation is started by a computation_send - * function. When it is finished, its result can be received by a - * computation_recv function. For an example how to set up an async - * computation, see the code example in the documentation for - * tevent_req_create() and tevent_req_post(). The prototypes for _send - * and _recv functions should follow some conventions: - * - * @code - * struct tevent_req *computation_send(TALLOC_CTX *mem_ctx, - * struct tevent_req *ev, - * ... further args); - * int computation_recv(struct tevent_req *req, ... further output args); - * @endcode - * - * The "int" result of computation_recv() depends on the result the - * sync version of the function would have, "int" is just an example - * here. - * - * Another important piece of the conventions is that the program flow - * is interrupted as little as possible. Because a blocking - * sub-computation requires that the flow needs to continue in a - * separate function that is the logical sequel of some computation, - * it should lexically follow sending off the blocking - * sub-computation. Setting the callback function via - * tevent_req_set_callback() requires referencing a function lexically - * below the call to tevent_req_set_callback(), forward declarations - * are required. A lot of the async computations thus begin with a - * sequence of declarations such as - * - * @code - * static void computation_step1_done(struct tevent_req *subreq); - * static void computation_step2_done(struct tevent_req *subreq); - * static void computation_step3_done(struct tevent_req *subreq); - * @endcode - * - * It really helps readability a lot to do these forward declarations, - * because the lexically sequential program flow makes the async - * computations almost as clear to read as a normal, sync program - * flow. - * - * It is up to the user of the async computation to talloc_free it - * after it has finished. If an async computation should be aborted, - * the tevent_req structure can be talloc_free'ed. After it has - * finished, it should talloc_free'ed by the API user. - * - * tevent_req variable naming conventions: - * - * The name of the variable pointing to the tevent_req structure - * returned by a _send() function SHOULD be named differently between - * implementation and caller. - * - * From the point of view of the implementation (of the _send() and - * _recv() functions) the variable returned by tevent_req_create() is - * always called @em req. - * - * While the caller of the _send() function should use @em subreq to - * hold the result. - * - * @see tevent_req_create() - * @see tevent_req_fn() - * - * @{ - */ - -/** - * An async request moves from TEVENT_REQ_INIT to - * TEVENT_REQ_IN_PROGRESS. All other states are valid after a request - * has finished. - */ -enum tevent_req_state { - /** - * We are creating the request - */ - TEVENT_REQ_INIT, - /** - * We are waiting the request to complete - */ - TEVENT_REQ_IN_PROGRESS, - /** - * The request is finished successfully - */ - TEVENT_REQ_DONE, - /** - * A user error has occurred. The user error has been - * indicated by tevent_req_error(), it can be retrieved via - * tevent_req_is_error(). - */ - TEVENT_REQ_USER_ERROR, - /** - * Request timed out after the timeout set by tevent_req_set_endtime. - */ - TEVENT_REQ_TIMED_OUT, - /** - * An internal allocation has failed, or tevent_req_nomem has - * been given a NULL pointer as the first argument. - */ - TEVENT_REQ_NO_MEMORY, - /** - * The request has been received by the caller. No further - * action is valid. - */ - TEVENT_REQ_RECEIVED -}; - -/** - * @brief An async request - */ -struct tevent_req; - -/** - * @brief A tevent request callback function. - * - * @param[in] subreq The tevent async request which executed this callback. - */ -typedef void (*tevent_req_fn)(struct tevent_req *subreq); - -/** - * @brief Set an async request callback. - * - * See the documentation of tevent_req_post() for an example how this - * is supposed to be used. - * - * @param[in] req The async request to set the callback. - * - * @param[in] fn The callback function to set. - * - * @param[in] pvt A pointer to private data to pass to the async request - * callback. - */ -void tevent_req_set_callback(struct tevent_req *req, tevent_req_fn fn, void *pvt); - -#ifdef DOXYGEN -/** - * @brief Get the private data cast to the given type for a callback from - * a tevent request structure. - * - * @code - * static void computation_done(struct tevent_req *subreq) { - * struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); - * struct computation_state *state = tevent_req_data(req, struct computation_state); - * .... more things, eventually maybe call tevent_req_done(req); - * } - * @endcode - * - * @param[in] req The structure to get the callback data from. - * - * @param[in] type The type of the private callback data to get. - * - * @return The type casted private data set NULL if not set. - */ -void *tevent_req_callback_data(struct tevent_req *req, #type); -#else -void *_tevent_req_callback_data(struct tevent_req *req); -#define tevent_req_callback_data(_req, _type) \ - talloc_get_type_abort(_tevent_req_callback_data(_req), _type) -#endif - -#ifdef DOXYGEN -/** - * @brief Get the private data for a callback from a tevent request structure. - * - * @param[in] req The structure to get the callback data from. - * - * @return The private data or NULL if not set. - */ -void *tevent_req_callback_data_void(struct tevent_req *req); -#else -#define tevent_req_callback_data_void(_req) \ - _tevent_req_callback_data(_req) -#endif - -#ifdef DOXYGEN -/** - * @brief Get the private data from a tevent request structure. - * - * When the tevent_req has been created by tevent_req_create, the - * result of tevent_req_data() is the state variable created by - * tevent_req_create() as a child of the req. - * - * @param[in] req The structure to get the private data from. - * - * @param[in] type The type of the private data - * - * @return The private data or NULL if not set. - */ -void *tevent_req_data(struct tevent_req *req, #type); -#else -void *_tevent_req_data(struct tevent_req *req); -#define tevent_req_data(_req, _type) \ - talloc_get_type_abort(_tevent_req_data(_req), _type) -#endif - -/** - * @brief The print function which can be set for a tevent async request. - * - * @param[in] req The tevent async request. - * - * @param[in] ctx A talloc memory context which can be uses to allocate - * memory. - * - * @return An allocated string buffer to print. - * - * Example: - * @code - * static char *my_print(struct tevent_req *req, TALLOC_CTX *mem_ctx) - * { - * struct my_data *data = tevent_req_data(req, struct my_data); - * char *result; - * - * result = tevent_req_default_print(mem_ctx, req); - * if (result == NULL) { - * return NULL; - * } - * - * return talloc_asprintf_append_buffer(result, "foo=%d, bar=%d", - * data->foo, data->bar); - * } - * @endcode - */ -typedef char *(*tevent_req_print_fn)(struct tevent_req *req, TALLOC_CTX *ctx); - -/** - * @brief This function sets a print function for the given request. - * - * This function can be used to setup a print function for the given request. - * This will be triggered if the tevent_req_print() function was - * called on the given request. - * - * @param[in] req The request to use. - * - * @param[in] fn A pointer to the print function - * - * @note This function should only be used for debugging. - */ -void tevent_req_set_print_fn(struct tevent_req *req, tevent_req_print_fn fn); - -/** - * @brief The default print function for creating debug messages. - * - * The function should not be used by users of the async API, - * but custom print function can use it and append custom text - * to the string. - * - * @param[in] req The request to be printed. - * - * @param[in] mem_ctx The memory context for the result. - * - * @return Text representation of request. - * - */ -char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx); - -/** - * @brief Print an tevent_req structure in debug messages. - * - * This function should be used by callers of the async API. - * - * @param[in] mem_ctx The memory context for the result. - * - * @param[in] req The request to be printed. - * - * @return Text representation of request. - */ -char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req); - -/** - * @brief A typedef for a cancel function for a tevent request. - * - * @param[in] req The tevent request calling this function. - * - * @return True if the request could be canceled, false if not. - */ -typedef bool (*tevent_req_cancel_fn)(struct tevent_req *req); - -/** - * @brief This function sets a cancel function for the given tevent request. - * - * This function can be used to setup a cancel function for the given request. - * This will be triggered if the tevent_req_cancel() function was - * called on the given request. - * - * @param[in] req The request to use. - * - * @param[in] fn A pointer to the cancel function. - */ -void tevent_req_set_cancel_fn(struct tevent_req *req, tevent_req_cancel_fn fn); - -#ifdef DOXYGEN -/** - * @brief Try to cancel the given tevent request. - * - * This function can be used to cancel the given request. - * - * It is only possible to cancel a request when the implementation - * has registered a cancel function via the tevent_req_set_cancel_fn(). - * - * @param[in] req The request to use. - * - * @return This function returns true if the request is - * cancelable, otherwise false is returned. - * - * @note Even if the function returns true, the caller need to wait - * for the function to complete normally. - * Only the _recv() function of the given request indicates - * if the request was really canceled. - */ -bool tevent_req_cancel(struct tevent_req *req); -#else -bool _tevent_req_cancel(struct tevent_req *req, const char *location); -#define tevent_req_cancel(req) \ - _tevent_req_cancel(req, __location__) -#endif - -/** - * @brief A typedef for a cleanup function for a tevent request. - * - * @param[in] req The tevent request calling this function. - * - * @param[in] req_state The current tevent_req_state. - * - */ -typedef void (*tevent_req_cleanup_fn)(struct tevent_req *req, - enum tevent_req_state req_state); - -/** - * @brief This function sets a cleanup function for the given tevent request. - * - * This function can be used to setup a cleanup function for the given request. - * This will be triggered when the tevent_req_done() or tevent_req_error() - * function was called, before notifying the callers callback function, - * and also before scheduling the deferred trigger. - * - * This might be useful if more than one tevent_req belong together - * and need to finish both requests at the same time. - * - * The cleanup function is able to call tevent_req_done() or tevent_req_error() - * recursively, the cleanup function is only triggered the first time. - * - * The cleanup function is also called by tevent_req_received() - * (possibly triggered from tevent_req_destructor()) before destroying - * the private data of the tevent_req. - * - * @param[in] req The request to use. - * - * @param[in] fn A pointer to the cancel function. - */ -void tevent_req_set_cleanup_fn(struct tevent_req *req, tevent_req_cleanup_fn fn); - -#ifdef DOXYGEN -/** - * @brief Create an async tevent request. - * - * The new async request will be initialized in state TEVENT_REQ_IN_PROGRESS. - * - * @code - * struct tevent_req *req; - * struct computation_state *state; - * req = tevent_req_create(mem_ctx, &state, struct computation_state); - * @endcode - * - * Tevent_req_create() allocates and zeros the state variable as a talloc - * child of its result. The state variable should be used as the talloc - * parent for all temporary variables that are allocated during the async - * computation. This way, when the user of the async computation frees - * the request, the state as a talloc child will be free'd along with - * all the temporary variables hanging off the state. - * - * @param[in] mem_ctx The memory context for the result. - * @param[in] pstate Pointer to the private request state. - * @param[in] type The name of the request. - * - * @return A new async request. NULL on error. - */ -struct tevent_req *tevent_req_create(TALLOC_CTX *mem_ctx, - void **pstate, #type); -#else -struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, - void *pstate, - size_t state_size, - const char *type, - const char *location); - -#define tevent_req_create(_mem_ctx, _pstate, _type) \ - _tevent_req_create((_mem_ctx), (_pstate), sizeof(_type), \ - #_type, __location__) -#endif - -/** - * @brief Set a timeout for an async request. On failure, "req" is already - * set to state TEVENT_REQ_NO_MEMORY. - * - * @param[in] req The request to set the timeout for. - * - * @param[in] ev The event context to use for the timer. - * - * @param[in] endtime The endtime of the request. - * - * @return True if succeeded, false if not. - */ -bool tevent_req_set_endtime(struct tevent_req *req, - struct tevent_context *ev, - struct timeval endtime); - -/** - * @brief Reset the timer set by tevent_req_set_endtime. - * - * @param[in] req The request to reset the timeout for - */ -void tevent_req_reset_endtime(struct tevent_req *req); - -#ifdef DOXYGEN -/** - * @brief Call the notify callback of the given tevent request manually. - * - * @param[in] req The tevent request to call the notify function from. - * - * @see tevent_req_set_callback() - */ -void tevent_req_notify_callback(struct tevent_req *req); -#else -void _tevent_req_notify_callback(struct tevent_req *req, const char *location); -#define tevent_req_notify_callback(req) \ - _tevent_req_notify_callback(req, __location__) -#endif - -#ifdef DOXYGEN -/** - * @brief An async request has successfully finished. - * - * This function is to be used by implementors of async requests. When a - * request is successfully finished, this function calls the user's completion - * function. - * - * @param[in] req The finished request. - */ -void tevent_req_done(struct tevent_req *req); -#else -void _tevent_req_done(struct tevent_req *req, - const char *location); -#define tevent_req_done(req) \ - _tevent_req_done(req, __location__) -#endif - -#ifdef DOXYGEN -/** - * @brief An async request has seen an error. - * - * This function is to be used by implementors of async requests. When a - * request can not successfully completed, the implementation should call this - * function with the appropriate status code. - * - * If error is 0 the function returns false and does nothing more. - * - * @param[in] req The request with an error. - * - * @param[in] error The error code. - * - * @return On success true is returned, false if error is 0. - * - * @code - * int error = first_function(); - * if (tevent_req_error(req, error)) { - * return; - * } - * - * error = second_function(); - * if (tevent_req_error(req, error)) { - * return; - * } - * - * tevent_req_done(req); - * return; - * @endcode - */ -bool tevent_req_error(struct tevent_req *req, - uint64_t error); -#else -bool _tevent_req_error(struct tevent_req *req, - uint64_t error, - const char *location); -#define tevent_req_error(req, error) \ - _tevent_req_error(req, error, __location__) -#endif - -#ifdef DOXYGEN -/** - * @brief Helper function for nomem check. - * - * Convenience helper to easily check alloc failure within a callback - * implementing the next step of an async request. - * - * @param[in] p The pointer to be checked. - * - * @param[in] req The request being processed. - * - * @code - * p = talloc(mem_ctx, bla); - * if (tevent_req_nomem(p, req)) { - * return; - * } - * @endcode - */ -bool tevent_req_nomem(const void *p, - struct tevent_req *req); -#else -bool _tevent_req_nomem(const void *p, - struct tevent_req *req, - const char *location); -#define tevent_req_nomem(p, req) \ - _tevent_req_nomem(p, req, __location__) -#endif - -#ifdef DOXYGEN -/** - * @brief Indicate out of memory to a request - * - * @param[in] req The request being processed. - */ -void tevent_req_oom(struct tevent_req *req); -#else -void _tevent_req_oom(struct tevent_req *req, - const char *location); -#define tevent_req_oom(req) \ - _tevent_req_oom(req, __location__) -#endif - -/** - * @brief Finish a request before the caller had a chance to set the callback. - * - * An implementation of an async request might find that it can either finish - * the request without waiting for an external event, or it can not even start - * the engine. To present the illusion of a callback to the user of the API, - * the implementation can call this helper function which triggers an - * immediate event. This way the caller can use the same calling - * conventions, independent of whether the request was actually deferred. - * - * @code - * struct tevent_req *computation_send(TALLOC_CTX *mem_ctx, - * struct tevent_context *ev) - * { - * struct tevent_req *req, *subreq; - * struct computation_state *state; - * req = tevent_req_create(mem_ctx, &state, struct computation_state); - * if (req == NULL) { - * return NULL; - * } - * subreq = subcomputation_send(state, ev); - * if (tevent_req_nomem(subreq, req)) { - * return tevent_req_post(req, ev); - * } - * tevent_req_set_callback(subreq, computation_done, req); - * return req; - * } - * @endcode - * - * @param[in] req The finished request. - * - * @param[in] ev The tevent_context for the immediate event. - * - * @return The given request will be returned. - */ -struct tevent_req *tevent_req_post(struct tevent_req *req, - struct tevent_context *ev); - -/** - * @brief Finish multiple requests within one function - * - * Normally tevent_req_notify_callback() and all wrappers - * (e.g. tevent_req_done() and tevent_req_error()) - * need to be the last thing an event handler should call. - * This is because the callback is likely to destroy the - * context of the current function. - * - * If a function wants to notify more than one caller, - * it is dangerous if it just triggers multiple callbacks - * in a row. With tevent_req_defer_callback() it is possible - * to set an event context that will be used to defer the callback - * via an immediate event (similar to tevent_req_post()). - * - * @code - * struct complete_state { - * struct tevent_context *ev; - * - * struct tevent_req **reqs; - * }; - * - * void complete(struct complete_state *state) - * { - * size_t i, c = talloc_array_length(state->reqs); - * - * for (i=0; i < c; i++) { - * tevent_req_defer_callback(state->reqs[i], state->ev); - * tevent_req_done(state->reqs[i]); - * } - * } - * @endcode - * - * @param[in] req The finished request. - * - * @param[in] ev The tevent_context for the immediate event. - * - * @return The given request will be returned. - */ -void tevent_req_defer_callback(struct tevent_req *req, - struct tevent_context *ev); - -/** - * @brief Check if the given request is still in progress. - * - * It is typically used by sync wrapper functions. - * - * @param[in] req The request to poll. - * - * @return The boolean form of "is in progress". - */ -bool tevent_req_is_in_progress(struct tevent_req *req); - -/** - * @brief Actively poll for the given request to finish. - * - * This function is typically used by sync wrapper functions. - * - * @param[in] req The request to poll. - * - * @param[in] ev The tevent_context to be used. - * - * @return On success true is returned. If a critical error has - * happened in the tevent loop layer false is returned. - * This is not the return value of the given request! - * - * @note This should only be used if the given tevent context was created by the - * caller, to avoid event loop nesting. - * - * @code - * req = tstream_writev_queue_send(mem_ctx, - * ev_ctx, - * tstream, - * send_queue, - * iov, 2); - * ok = tevent_req_poll(req, tctx->ev); - * rc = tstream_writev_queue_recv(req, &sys_errno); - * TALLOC_FREE(req); - * @endcode - */ -bool tevent_req_poll(struct tevent_req *req, - struct tevent_context *ev); - -/** - * @brief Get the tevent request state and the actual error set by - * tevent_req_error. - * - * @code - * int computation_recv(struct tevent_req *req, uint64_t *perr) - * { - * enum tevent_req_state state; - * uint64_t err; - * if (tevent_req_is_error(req, &state, &err)) { - * *perr = err; - * return -1; - * } - * return 0; - * } - * @endcode - * - * @param[in] req The tevent request to get the error from. - * - * @param[out] state A pointer to store the tevent request error state. - * - * @param[out] error A pointer to store the error set by tevent_req_error(). - * - * @return True if the function could set error and state, false - * otherwise. - * - * @see tevent_req_error() - */ -bool tevent_req_is_error(struct tevent_req *req, - enum tevent_req_state *state, - uint64_t *error); - -/** - * @brief Use as the last action of a _recv() function. - * - * This function destroys the attached private data. - * - * @param[in] req The finished request. - */ -void tevent_req_received(struct tevent_req *req); - -/** - * @brief Mark a tevent_req for profiling - * - * This will turn on profiling for this tevent_req an all subreqs that - * are directly started as helper requests off this - * tevent_req. subreqs are chained by walking up the talloc_parent - * hierarchy at a subreq's tevent_req_create. This means to get the - * profiling chain right the subreq that needs to be profiled as part - * of this tevent_req's profile must be a talloc child of the requests - * state variable. - * - * @param[in] req The request to do tracing for - * - * @return False if the profile could not be activated - */ -bool tevent_req_set_profile(struct tevent_req *req); - -struct tevent_req_profile; - -/** - * @brief Get the a request's profile for inspection - * - * @param[in] req The request to get the profile from - * - * @return The request's profile - */ -const struct tevent_req_profile *tevent_req_get_profile( - struct tevent_req *req); - -/** - * @brief Move the profile out of a request - * - * This function detaches the request's profile from the request, so - * that the profile can outlive the request in a _recv function. - * - * @param[in] req The request to move the profile out of - * @param[in] mem_ctx The new talloc context for the profile - * - * @return The moved profile - */ - -struct tevent_req_profile *tevent_req_move_profile(struct tevent_req *req, - TALLOC_CTX *mem_ctx); - -/** - * @brief Get a profile description - * - * @param[in] profile The profile to be queried - * @param[in] req_name The name of the request (state's name) - * - * "req_name" after this call is still in talloc-posession of "profile" - */ -void tevent_req_profile_get_name(const struct tevent_req_profile *profile, - const char **req_name); - -/** - * @brief Get a profile's start event data - * - * @param[in] profile The profile to be queried - * @param[in] start_location The location where this event started - * @param[in] start_time The time this event started - * - * "start_location" after this call is still in talloc-posession of "profile" - */ -void tevent_req_profile_get_start(const struct tevent_req_profile *profile, - const char **start_location, - struct timeval *start_time); - -/** - * @brief Get a profile's stop event data - * - * @param[in] profile The profile to be queried - * @param[in] stop_location The location where this event stopped - * @param[in] stop_time The time this event stopped - * - * "stop_location" after this call is still in talloc-posession of "profile" - */ -void tevent_req_profile_get_stop(const struct tevent_req_profile *profile, - const char **stop_location, - struct timeval *stop_time); - -/** - * @brief Get a profile's result data - * - * @param[in] pid The process where this profile was taken - * @param[in] state The status the profile's tevent_req finished with - * @param[in] user_error The user error of the profile's tevent_req - */ -void tevent_req_profile_get_status(const struct tevent_req_profile *profile, - pid_t *pid, - enum tevent_req_state *state, - uint64_t *user_error); - -/** - * @brief Retrieve the first subreq's profile from a profile - * - * @param[in] profile The profile to query - * - * @return The first tevent subreq's profile - */ -const struct tevent_req_profile *tevent_req_profile_get_subprofiles( - const struct tevent_req_profile *profile); - -/** - * @brief Walk the chain of subreqs - * - * @param[in] profile The subreq's profile to walk - * - * @return The next subprofile in the list - */ -const struct tevent_req_profile *tevent_req_profile_next( - const struct tevent_req_profile *profile); - -/** - * @brief Create a fresh tevent_req_profile - * - * @param[in] mem_ctx The talloc context to hang the fresh struct off - * - * @return The fresh struct - */ -struct tevent_req_profile *tevent_req_profile_create(TALLOC_CTX *mem_ctx); - -/** - * @brief Set a profile's name - * - * @param[in] profile The profile to set the name for - * @param[in] name The new name for the profile - * - * @return True if the internal talloc_strdup succeeded - */ -bool tevent_req_profile_set_name(struct tevent_req_profile *profile, - const char *name); - -/** - * @brief Set a profile's start event - * - * @param[in] profile The profile to set the start data for - * @param[in] start_location The new start location - * @param[in] start_time The new start time - * - * @return True if the internal talloc_strdup succeeded - */ -bool tevent_req_profile_set_start(struct tevent_req_profile *profile, - const char *start_location, - struct timeval start_time); - -/** - * @brief Set a profile's stop event - * - * @param[in] profile The profile to set the stop data for - * @param[in] stop_location The new stop location - * @param[in] stop_time The new stop time - * - * @return True if the internal talloc_strdup succeeded - */ -bool tevent_req_profile_set_stop(struct tevent_req_profile *profile, - const char *stop_location, - struct timeval stop_time); - -/** - * @brief Set a profile's exit status - * - * @param[in] profile The profile to set the exit status for - * @param[in] pid The process where this profile was taken - * @param[in] state The status the profile's tevent_req finished with - * @param[in] user_error The user error of the profile's tevent_req - */ -void tevent_req_profile_set_status(struct tevent_req_profile *profile, - pid_t pid, - enum tevent_req_state state, - uint64_t user_error); - -/** - * @brief Add a subprofile to a profile - * - * @param[in] parent_profile The profile to be modified - * @param[in] sub_profile The subreqs profile profile to be added - * - * "subreq" is talloc_move'ed into "parent_profile", so the talloc - * ownership of "sub_profile" changes - */ - -void tevent_req_profile_append_sub(struct tevent_req_profile *parent_profile, - struct tevent_req_profile **sub_profile); - -/** - * @brief Create a tevent subrequest at a given time. - * - * The idea is that always the same syntax for tevent requests. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] ev The event handle to setup the request. - * - * @param[in] wakeup_time The time to wakeup and execute the request. - * - * @return The new subrequest, NULL on error. - * - * Example: - * @code - * static void my_callback_wakeup_done(tevent_req *subreq) - * { - * struct tevent_req *req = tevent_req_callback_data(subreq, - * struct tevent_req); - * bool ok; - * - * ok = tevent_wakeup_recv(subreq); - * TALLOC_FREE(subreq); - * if (!ok) { - * tevent_req_error(req, -1); - * return; - * } - * ... - * } - * @endcode - * - * @code - * subreq = tevent_wakeup_send(mem_ctx, ev, wakeup_time); - * if (tevent_req_nomem(subreq, req)) { - * return false; - * } - * tevent_set_callback(subreq, my_callback_wakeup_done, req); - * @endcode - * - * @see tevent_wakeup_recv() - */ -struct tevent_req *tevent_wakeup_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct timeval wakeup_time); - -/** - * @brief Check if the wakeup has been correctly executed. - * - * This function needs to be called in the callback function set after calling - * tevent_wakeup_send(). - * - * @param[in] req The tevent request to check. - * - * @return True on success, false otherwise. - * - * @see tevent_wakeup_recv() - */ -bool tevent_wakeup_recv(struct tevent_req *req); - -/* @} */ - -/** - * @defgroup tevent_helpers The tevent helper functions - * @ingroup tevent - * - * @todo description - * - * @{ - */ - -/** - * @brief Compare two timeval values. - * - * @param[in] tv1 The first timeval value to compare. - * - * @param[in] tv2 The second timeval value to compare. - * - * @return 0 if they are equal. - * 1 if the first time is greater than the second. - * -1 if the first time is smaller than the second. - */ -int tevent_timeval_compare(const struct timeval *tv1, - const struct timeval *tv2); - -/** - * @brief Get a zero timeval value. - * - * @return A zero timeval value. - */ -struct timeval tevent_timeval_zero(void); - -/** - * @brief Get a timeval value for the current time. - * - * @return A timeval value with the current time. - */ -struct timeval tevent_timeval_current(void); - -/** - * @brief Get a timeval structure with the given values. - * - * @param[in] secs The seconds to set. - * - * @param[in] usecs The microseconds to set. - * - * @return A timeval structure with the given values. - */ -struct timeval tevent_timeval_set(uint32_t secs, uint32_t usecs); - -/** - * @brief Get the difference between two timeval values. - * - * @param[in] tv1 The first timeval. - * - * @param[in] tv2 The second timeval. - * - * @return A timeval structure with the difference between the - * first and the second value. - */ -struct timeval tevent_timeval_until(const struct timeval *tv1, - const struct timeval *tv2); - -/** - * @brief Check if a given timeval structure is zero. - * - * @param[in] tv The timeval to check if it is zero. - * - * @return True if it is zero, false otherwise. - */ -bool tevent_timeval_is_zero(const struct timeval *tv); - -/** - * @brief Add the given amount of time to a timeval structure. - * - * @param[in] tv The timeval structure to add the time. - * - * @param[in] secs The seconds to add to the timeval. - * - * @param[in] usecs The microseconds to add to the timeval. - * - * @return The timeval structure with the new time. - */ -struct timeval tevent_timeval_add(const struct timeval *tv, uint32_t secs, - uint32_t usecs); - -/** - * @brief Get a timeval in the future with a specified offset from now. - * - * @param[in] secs The seconds of the offset from now. - * - * @param[in] usecs The microseconds of the offset from now. - * - * @return A timeval with the given offset in the future. - */ -struct timeval tevent_timeval_current_ofs(uint32_t secs, uint32_t usecs); - -/* @} */ - - -/** - * @defgroup tevent_queue The tevent queue functions - * @ingroup tevent - * - * A tevent_queue is used to queue up async requests that must be - * serialized. For example writing buffers into a socket must be - * serialized. Writing a large lump of data into a socket can require - * multiple write(2) or send(2) system calls. If more than one async - * request is outstanding to write large buffers into a socket, every - * request must individually be completed before the next one begins, - * even if multiple syscalls are required. - * - * Take a look at @ref tevent_queue_tutorial for more details. - * @{ - */ - -struct tevent_queue; -struct tevent_queue_entry; - -#ifdef DOXYGEN -/** - * @brief Create and start a tevent queue. - * - * @param[in] mem_ctx The talloc memory context to allocate the queue. - * - * @param[in] name The name to use to identify the queue. - * - * @return An allocated tevent queue on success, NULL on error. - * - * @see tevent_queue_start() - * @see tevent_queue_stop() - */ -struct tevent_queue *tevent_queue_create(TALLOC_CTX *mem_ctx, - const char *name); -#else -struct tevent_queue *_tevent_queue_create(TALLOC_CTX *mem_ctx, - const char *name, - const char *location); - -#define tevent_queue_create(_mem_ctx, _name) \ - _tevent_queue_create((_mem_ctx), (_name), __location__) -#endif - -/** - * @brief A callback trigger function run by the queue. - * - * @param[in] req The tevent request the trigger function is executed on. - * - * @param[in] private_data The private data pointer specified by - * tevent_queue_add(). - * - * @see tevent_queue_add() - * @see tevent_queue_add_entry() - * @see tevent_queue_add_optimize_empty() - */ -typedef void (*tevent_queue_trigger_fn_t)(struct tevent_req *req, - void *private_data); - -/** - * @brief Add a tevent request to the queue. - * - * @param[in] queue The queue to add the request. - * - * @param[in] ev The event handle to use for the request. - * - * @param[in] req The tevent request to add to the queue. - * - * @param[in] trigger The function triggered by the queue when the request - * is called. Since tevent 0.9.14 it's possible to - * pass NULL, in order to just add a "blocker" to the - * queue. - * - * @param[in] private_data The private data passed to the trigger function. - * - * @return True if the request has been successfully added, false - * otherwise. - */ -bool tevent_queue_add(struct tevent_queue *queue, - struct tevent_context *ev, - struct tevent_req *req, - tevent_queue_trigger_fn_t trigger, - void *private_data); - -/** - * @brief Add a tevent request to the queue. - * - * The request can be removed from the queue by calling talloc_free() - * (or a similar function) on the returned queue entry. This - * is the only difference to tevent_queue_add(). - * - * @param[in] queue The queue to add the request. - * - * @param[in] ev The event handle to use for the request. - * - * @param[in] req The tevent request to add to the queue. - * - * @param[in] trigger The function triggered by the queue when the request - * is called. Since tevent 0.9.14 it's possible to - * pass NULL, in order to just add a "blocker" to the - * queue. - * - * @param[in] private_data The private data passed to the trigger function. - * - * @return a pointer to the tevent_queue_entry if the request - * has been successfully added, NULL otherwise. - * - * @see tevent_queue_add() - * @see tevent_queue_add_optimize_empty() - */ -struct tevent_queue_entry *tevent_queue_add_entry( - struct tevent_queue *queue, - struct tevent_context *ev, - struct tevent_req *req, - tevent_queue_trigger_fn_t trigger, - void *private_data); - -/** - * @brief Add a tevent request to the queue using a possible optimization. - * - * This tries to optimize for the empty queue case and may calls - * the trigger function directly. This is the only difference compared - * to tevent_queue_add_entry(). - * - * The caller needs to be prepared that the trigger function has - * already called tevent_req_notify_callback(), tevent_req_error(), - * tevent_req_done() or a similar function. - * - * The trigger function has no chance to see the returned - * queue_entry in the optimized case. - * - * The request can be removed from the queue by calling talloc_free() - * (or a similar function) on the returned queue entry. - * - * @param[in] queue The queue to add the request. - * - * @param[in] ev The event handle to use for the request. - * - * @param[in] req The tevent request to add to the queue. - * - * @param[in] trigger The function triggered by the queue when the request - * is called. Since tevent 0.9.14 it's possible to - * pass NULL, in order to just add a "blocker" to the - * queue. - * - * @param[in] private_data The private data passed to the trigger function. - * - * @return a pointer to the tevent_queue_entry if the request - * has been successfully added, NULL otherwise. - * - * @see tevent_queue_add() - * @see tevent_queue_add_entry() - */ -struct tevent_queue_entry *tevent_queue_add_optimize_empty( - struct tevent_queue *queue, - struct tevent_context *ev, - struct tevent_req *req, - tevent_queue_trigger_fn_t trigger, - void *private_data); - -/** - * @brief Untrigger an already triggered queue entry. - * - * If a trigger function detects that it needs to remain - * in the queue, it needs to call tevent_queue_stop() - * followed by tevent_queue_entry_untrigger(). - * - * @note In order to call tevent_queue_entry_untrigger() - * the queue must be already stopped and the given queue_entry - * must be the first one in the queue! Otherwise it calls abort(). - * - * @note You can't use this together with tevent_queue_add_optimize_empty() - * because the trigger function don't have access to the quene entry - * in the case of an empty queue. - * - * @param[in] queue_entry The queue entry to rearm. - * - * @see tevent_queue_add_entry() - * @see tevent_queue_stop() - */ -void tevent_queue_entry_untrigger(struct tevent_queue_entry *entry); - -/** - * @brief Start a tevent queue. - * - * The queue is started by default. - * - * @param[in] queue The queue to start. - */ -void tevent_queue_start(struct tevent_queue *queue); - -/** - * @brief Stop a tevent queue. - * - * The queue is started by default. - * - * @param[in] queue The queue to stop. - */ -void tevent_queue_stop(struct tevent_queue *queue); - -/** - * @brief Get the length of the queue. - * - * @param[in] queue The queue to get the length from. - * - * @return The number of elements. - */ -size_t tevent_queue_length(struct tevent_queue *queue); - -/** - * @brief Is the tevent queue running. - * - * The queue is started by default. - * - * @param[in] queue The queue. - * - * @return Whether the queue is running or not.. - */ -bool tevent_queue_running(struct tevent_queue *queue); - -/** - * @brief Create a tevent subrequest that waits in a tevent_queue - * - * The idea is that always the same syntax for tevent requests. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] ev The event handle to setup the request. - * - * @param[in] queue The queue to wait in. - * - * @return The new subrequest, NULL on error. - * - * @see tevent_queue_wait_recv() - */ -struct tevent_req *tevent_queue_wait_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct tevent_queue *queue); - -/** - * @brief Check if we no longer need to wait in the queue. - * - * This function needs to be called in the callback function set after calling - * tevent_queue_wait_send(). - * - * @param[in] req The tevent request to check. - * - * @return True on success, false otherwise. - * - * @see tevent_queue_wait_send() - */ -bool tevent_queue_wait_recv(struct tevent_req *req); - -typedef int (*tevent_nesting_hook)(struct tevent_context *ev, - void *private_data, - uint32_t level, - bool begin, - void *stack_ptr, - const char *location); - -/** - * @brief Create a tevent_thread_proxy for message passing between threads. - * - * The tevent_context must have been allocated on the NULL - * talloc context, and talloc_disable_null_tracking() must - * have been called. - * - * @param[in] dest_ev_ctx The tevent_context to receive events. - * - * @return An allocated tevent_thread_proxy, NULL on error. - * If tevent was compiled without PTHREAD support - * NULL is always returned and errno set to ENOSYS. - * - * @see tevent_thread_proxy_schedule() - */ -struct tevent_thread_proxy *tevent_thread_proxy_create( - struct tevent_context *dest_ev_ctx); - -/** - * @brief Schedule an immediate event on an event context from another thread. - * - * Causes dest_ev_ctx, being run by another thread, to receive an - * immediate event calling the handler with the *pp_private parameter. - * - * *pp_im must be a pointer to an immediate event talloced on a context owned - * by the calling thread, or the NULL context. Ownership will - * be transferred to the tevent_thread_proxy and *pp_im will be returned as NULL. - * - * *pp_private_data must be a talloced area of memory with no destructors. - * Ownership of this memory will be transferred to the tevent library and - * *pp_private_data will be set to NULL on successful completion of - * the call. Set pp_private to NULL if no parameter transfer - * needed (a pure callback). This is an asynchronous request, caller - * does not wait for callback to be completed before returning. - * - * @param[in] tp The tevent_thread_proxy to use. - * - * @param[in] pp_im Pointer to immediate event pointer. - * - * @param[in] handler The function that will be called. - * - * @param[in] pp_private_data The talloced memory to transfer. - * - * @see tevent_thread_proxy_create() - */ -void tevent_thread_proxy_schedule(struct tevent_thread_proxy *tp, - struct tevent_immediate **pp_im, - tevent_immediate_handler_t handler, - void *pp_private_data); - -/* - * @brief Create a context for threaded activation of immediates - * - * A tevent_treaded_context provides a link into an event - * context. Using tevent_threaded_schedule_immediate, it is possible - * to activate an immediate event from within a thread. - * - * It is the duty of the caller of tevent_threaded_context_create() to - * keep the event context around longer than any - * tevent_threaded_context. tevent will abort if ev is talloc_free'ed - * with an active tevent_threaded_context. - * - * If tevent is build without pthread support, this always returns - * NULL with errno=ENOSYS. - * - * @param[in] mem_ctx The talloc memory context to use. - * @param[in] ev The event context to link this to. - * @return The threaded context, or NULL with errno set. - * - * @see tevent_threaded_schedule_immediate() - * - * @note Available as of tevent 0.9.30 - */ -struct tevent_threaded_context *tevent_threaded_context_create( - TALLOC_CTX *mem_ctx, struct tevent_context *ev); - -#ifdef DOXYGEN -/* - * @brief Activate an immediate from a thread - * - * Activate an immediate from within a thread. - * - * This routine does not watch out for talloc hierarchies. This means - * that it is highly recommended to create the tevent_immediate in the - * thread owning tctx, allocate a threaded job description for the - * thread, hand over both pointers to a helper thread and not touch it - * in the main thread at all anymore. - * - * tevent_threaded_schedule_immediate is intended as a job completion - * indicator for simple threaded helpers. - * - * Please be aware that tevent_threaded_schedule_immediate is very - * picky about its arguments: An immediate may not already be - * activated and the handler must exist. With - * tevent_threaded_schedule_immediate memory ownership is transferred - * to the main thread holding the tevent context behind tctx, the - * helper thread can't access it anymore. - * - * @param[in] tctx The threaded context to go through - * @param[in] im The immediate event to activate - * @param[in] handler The immediate handler to call in the main thread - * @param[in] private_data Pointer for the immediate handler - * - * @see tevent_threaded_context_create() - * - * @note Available as of tevent 0.9.30 - */ -void tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx, - struct tevent_immediate *im, - tevent_immediate_handler_t handler, - void *private_data); -#else -void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx, - struct tevent_immediate *im, - tevent_immediate_handler_t handler, - void *private_data, - const char *handler_name, - const char *location); -#define tevent_threaded_schedule_immediate(tctx, im, handler, private_data) \ - _tevent_threaded_schedule_immediate(tctx, im, handler, private_data, \ - #handler, __location__); -#endif - -#ifdef TEVENT_DEPRECATED -#ifndef _DEPRECATED_ -#ifdef HAVE___ATTRIBUTE__ -#define _DEPRECATED_ __attribute__ ((deprecated)) -#else -#define _DEPRECATED_ -#endif -#endif -void tevent_loop_allow_nesting(struct tevent_context *ev) _DEPRECATED_; -void tevent_loop_set_nesting_hook(struct tevent_context *ev, - tevent_nesting_hook hook, - void *private_data) _DEPRECATED_; -int _tevent_loop_until(struct tevent_context *ev, - bool (*finished)(void *private_data), - void *private_data, - const char *location) _DEPRECATED_; -#define tevent_loop_until(ev, finished, private_data) \ - _tevent_loop_until(ev, finished, private_data, __location__) -#endif - -int tevent_re_initialise(struct tevent_context *ev); - -/* @} */ - -/** - * @defgroup tevent_ops The tevent operation functions - * @ingroup tevent - * - * The following structure and registration functions are exclusively - * needed for people writing and pluggin a different event engine. - * There is nothing useful for normal tevent user in here. - * @{ - */ - -struct tevent_ops { - /* context init */ - int (*context_init)(struct tevent_context *ev); - - /* fd_event functions */ - struct tevent_fd *(*add_fd)(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - int fd, uint16_t flags, - tevent_fd_handler_t handler, - void *private_data, - const char *handler_name, - const char *location); - void (*set_fd_close_fn)(struct tevent_fd *fde, - tevent_fd_close_fn_t close_fn); - uint16_t (*get_fd_flags)(struct tevent_fd *fde); - void (*set_fd_flags)(struct tevent_fd *fde, uint16_t flags); - - /* timed_event functions */ - struct tevent_timer *(*add_timer)(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - struct timeval next_event, - tevent_timer_handler_t handler, - void *private_data, - const char *handler_name, - const char *location); - - /* immediate event functions */ - void (*schedule_immediate)(struct tevent_immediate *im, - struct tevent_context *ev, - tevent_immediate_handler_t handler, - void *private_data, - const char *handler_name, - const char *location); - - /* signal functions */ - struct tevent_signal *(*add_signal)(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - int signum, int sa_flags, - tevent_signal_handler_t handler, - void *private_data, - const char *handler_name, - const char *location); - - /* loop functions */ - int (*loop_once)(struct tevent_context *ev, const char *location); - int (*loop_wait)(struct tevent_context *ev, const char *location); -}; - -bool tevent_register_backend(const char *name, const struct tevent_ops *ops); - -/* @} */ - -#ifdef TEVENT_DEPRECATED -/** - * @defgroup tevent_wrapper_ops The tevent wrapper operation functions - * @ingroup tevent - * - * The following structure and registration functions are exclusively - * needed for people writing wrapper functions for event handlers - * e.g. wrappers can be used for debugging/profiling or impersonation. - * - * There is nothing useful for normal tevent user in here. - * - * @note That the close_fn() on tevent_fd is *NOT* wrapped! - * - * @see tevent_context_wrapper_create - * @see tevent_fd_set_auto_close - * @{ - */ - -struct tevent_wrapper_ops { - const char *name; - - bool (*before_use)(struct tevent_context *wrap_ev, - void *private_state, - struct tevent_context *main_ev, - const char *location); - void (*after_use)(struct tevent_context *wrap_ev, - void *private_state, - struct tevent_context *main_ev, - const char *location); - - void (*before_fd_handler)(struct tevent_context *wrap_ev, - void *private_state, - struct tevent_context *main_ev, - struct tevent_fd *fde, - uint16_t flags, - const char *handler_name, - const char *location); - void (*after_fd_handler)(struct tevent_context *wrap_ev, - void *private_state, - struct tevent_context *main_ev, - struct tevent_fd *fde, - uint16_t flags, - const char *handler_name, - const char *location); - - void (*before_timer_handler)(struct tevent_context *wrap_ev, - void *private_state, - struct tevent_context *main_ev, - struct tevent_timer *te, - struct timeval requested_time, - struct timeval trigger_time, - const char *handler_name, - const char *location); - void (*after_timer_handler)(struct tevent_context *wrap_ev, - void *private_state, - struct tevent_context *main_ev, - struct tevent_timer *te, - struct timeval requested_time, - struct timeval trigger_time, - const char *handler_name, - const char *location); - - void (*before_immediate_handler)(struct tevent_context *wrap_ev, - void *private_state, - struct tevent_context *main_ev, - struct tevent_immediate *im, - const char *handler_name, - const char *location); - void (*after_immediate_handler)(struct tevent_context *wrap_ev, - void *private_state, - struct tevent_context *main_ev, - struct tevent_immediate *im, - const char *handler_name, - const char *location); - - void (*before_signal_handler)(struct tevent_context *wrap_ev, - void *private_state, - struct tevent_context *main_ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - const char *handler_name, - const char *location); - void (*after_signal_handler)(struct tevent_context *wrap_ev, - void *private_state, - struct tevent_context *main_ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - const char *handler_name, - const char *location); -}; - -#ifdef DOXYGEN -/** - * @brief Create a wrapper tevent_context. - * - * @param[in] main_ev The main event context to work on. - * - * @param[in] mem_ctx The talloc memory context to use. - * - * @param[in] ops The tevent_wrapper_ops function table. - * - * @param[out] private_state The private state use by the wrapper functions. - * - * @param[in] private_type The talloc type of the private_state. - * - * @return The wrapper event context, NULL on error. - * - * @note Available as of tevent 0.9.37 - * @note Deprecated as of tevent 0.9.38 - */ -struct tevent_context *tevent_context_wrapper_create(struct tevent_context *main_ev, - TALLOC_CTX *mem_ctx, - const struct tevent_wrapper_ops *ops, - void **private_state, - const char *private_type); -#else -struct tevent_context *_tevent_context_wrapper_create(struct tevent_context *main_ev, - TALLOC_CTX *mem_ctx, - const struct tevent_wrapper_ops *ops, - void *pstate, - size_t psize, - const char *type, - const char *location) _DEPRECATED_; -#define tevent_context_wrapper_create(main_ev, mem_ctx, ops, state, type) \ - _tevent_context_wrapper_create(main_ev, mem_ctx, ops, \ - state, sizeof(type), #type, __location__) -#endif - -/** - * @brief Check if the event context is a wrapper event context. - * - * @param[in] ev The event context to work on. - * - * @return Is a wrapper (true), otherwise (false). - * - * @see tevent_context_wrapper_create() - * - * @note Available as of tevent 0.9.37 - * @note Deprecated as of tevent 0.9.38 - */ -bool tevent_context_is_wrapper(struct tevent_context *ev) _DEPRECATED_; - -#ifdef DOXYGEN -/** - * @brief Prepare the environment of a (wrapper) event context. - * - * A caller might call this before passing a wrapper event context - * to a tevent_req based *_send() function. - * - * The wrapper event context might do something like impersonation. - * - * tevent_context_push_use() must always be used in combination - * with tevent_context_pop_use(). - * - * There is a global stack of currently active/busy wrapper event contexts. - * Each wrapper can only appear once on that global stack! - * The stack size is limited to 32 elements, which should be enough - * for all useful scenarios. - * - * In addition to an explicit tevent_context_push_use() also - * the invocation of an immediate, timer or fd handler implicitly - * pushes the wrapper on the stack. - * - * Therefore there are some strict constraints for the usage of - * tevent_context_push_use(): - * - It must not be called from within an event handler - * that already acts on the wrapper. - * - tevent_context_pop_use() must be called before - * leaving the code block that called tevent_context_push_use(). - * - The caller is responsible ensure the correct stack ordering - * - Any violation of these constraints results in calling - * the abort handler of the given tevent context. - * - * Calling tevent_context_push_use() on a raw event context - * still consumes an element on the stack, but it's otherwise - * a no-op. - * - * If tevent_context_push_use() returns false, it means - * that the wrapper's before_use() hook returned this failure, - * in that case you must not call tevent_context_pop_use() as - * the wrapper is not pushed onto the stack. - * - * @param[in] ev The event context to work on. - * - * @return Success (true) or failure (false). - * - * @note This is only needed if wrapper event contexts are in use. - * - * @see tevent_context_pop_use - * - * @note Available as of tevent 0.9.37 - * @note Deprecated as of tevent 0.9.38 - */ -bool tevent_context_push_use(struct tevent_context *ev); -#else -bool _tevent_context_push_use(struct tevent_context *ev, - const char *location) _DEPRECATED_; -#define tevent_context_push_use(ev) \ - _tevent_context_push_use(ev, __location__) -#endif - -#ifdef DOXYGEN -/** - * @brief Release the environment of a (wrapper) event context. - * - * The wrapper event context might undo something like impersonation. - * - * This must be called after a succesful tevent_context_push_use(). - * Any ordering violation results in calling - * the abort handler of the given tevent context. - * - * This basically calls the wrapper's after_use() hook. - * - * @param[in] ev The event context to work on. - * - * @note This is only needed if wrapper event contexts are in use. - * - * @see tevent_context_push_use - * - * @note Available as of tevent 0.9.37 - * @note Deprecated as of tevent 0.9.38 - */ -void tevent_context_pop_use(struct tevent_context *ev); -#else -void _tevent_context_pop_use(struct tevent_context *ev, - const char *location) _DEPRECATED_; -#define tevent_context_pop_use(ev) \ - _tevent_context_pop_use(ev, __location__) -#endif - -/** - * @brief Check is the two context pointers belong to the same low level loop - * - * With the introduction of wrapper contexts it's not trivial - * to check if two context pointers belong to the same low level - * event loop. Some code may need to know this in order - * to make some caching decisions. - * - * @param[in] ev1 The first event context. - * @param[in] ev2 The second event context. - * - * @return true if both contexts belong to the same (still existing) context - * loop, false otherwise. - * - * @see tevent_context_wrapper_create - * - * @note Available as of tevent 0.9.37 - * @note Deprecated as of tevent 0.9.38 - */ -bool tevent_context_same_loop(struct tevent_context *ev1, - struct tevent_context *ev2) _DEPRECATED_; - -/* @} */ -#endif /* TEVENT_DEPRECATED */ - -/** - * @defgroup tevent_compat The tevent compatibility functions - * @ingroup tevent - * - * The following definitions are usueful only for compatibility with the - * implementation originally developed within the samba4 code and will be - * soon removed. Please NEVER use in new code. - * - * @todo Ignore it? - * - * @{ - */ - -#ifdef TEVENT_COMPAT_DEFINES - -#define event_context tevent_context -#define event_ops tevent_ops -#define fd_event tevent_fd -#define timed_event tevent_timer -#define signal_event tevent_signal - -#define event_fd_handler_t tevent_fd_handler_t -#define event_timed_handler_t tevent_timer_handler_t -#define event_signal_handler_t tevent_signal_handler_t - -#define event_context_init(mem_ctx) \ - tevent_context_init(mem_ctx) - -#define event_context_init_byname(mem_ctx, name) \ - tevent_context_init_byname(mem_ctx, name) - -#define event_backend_list(mem_ctx) \ - tevent_backend_list(mem_ctx) - -#define event_set_default_backend(backend) \ - tevent_set_default_backend(backend) - -#define event_add_fd(ev, mem_ctx, fd, flags, handler, private_data) \ - tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data) - -#define event_add_timed(ev, mem_ctx, next_event, handler, private_data) \ - tevent_add_timer(ev, mem_ctx, next_event, handler, private_data) - -#define event_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data) \ - tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data) - -#define event_loop_once(ev) \ - tevent_loop_once(ev) - -#define event_loop_wait(ev) \ - tevent_loop_wait(ev) - -#define event_get_fd_flags(fde) \ - tevent_fd_get_flags(fde) - -#define event_set_fd_flags(fde, flags) \ - tevent_fd_set_flags(fde, flags) - -#define EVENT_FD_READ TEVENT_FD_READ -#define EVENT_FD_WRITE TEVENT_FD_WRITE - -#define EVENT_FD_WRITEABLE(fde) \ - TEVENT_FD_WRITEABLE(fde) - -#define EVENT_FD_READABLE(fde) \ - TEVENT_FD_READABLE(fde) - -#define EVENT_FD_NOT_WRITEABLE(fde) \ - TEVENT_FD_NOT_WRITEABLE(fde) - -#define EVENT_FD_NOT_READABLE(fde) \ - TEVENT_FD_NOT_READABLE(fde) - -#define ev_debug_level tevent_debug_level - -#define EV_DEBUG_FATAL TEVENT_DEBUG_FATAL -#define EV_DEBUG_ERROR TEVENT_DEBUG_ERROR -#define EV_DEBUG_WARNING TEVENT_DEBUG_WARNING -#define EV_DEBUG_TRACE TEVENT_DEBUG_TRACE - -#define ev_set_debug(ev, debug, context) \ - tevent_set_debug(ev, debug, context) - -#define ev_set_debug_stderr(_ev) tevent_set_debug_stderr(ev) - -#endif /* TEVENT_COMPAT_DEFINES */ - -/* @} */ - -#endif /* __TEVENT_H__ */ diff --git a/ldb-2.0.8/lib/tevent/tevent.pc.in b/ldb-2.0.8/lib/tevent/tevent.pc.in deleted file mode 100644 index eb0e564..0000000 --- a/ldb-2.0.8/lib/tevent/tevent.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: tevent -Description: An event system library -Version: @PACKAGE_VERSION@ -Requires: talloc -Libs: @LIB_RPATH@ -L${libdir} -ltevent -Cflags: -I${includedir} -URL: http://samba.org/ diff --git a/ldb-2.0.8/lib/tevent/tevent.py b/ldb-2.0.8/lib/tevent/tevent.py deleted file mode 100644 index 14aa27d..0000000 --- a/ldb-2.0.8/lib/tevent/tevent.py +++ /dev/null @@ -1,28 +0,0 @@ -# -# Python integration for tevent -# -# Copyright (C) Jelmer Vernooij 2011 -# -# ** NOTE! The following LGPL license applies to the tevent -# ** library. This does NOT imply that all of Samba is released -# ** under the LGPL -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 3 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, see . - -from _tevent import ( - __version__, - backend_list, - Context, - Signal, -) diff --git a/ldb-2.0.8/lib/tevent/tevent_debug.c b/ldb-2.0.8/lib/tevent/tevent_debug.c deleted file mode 100644 index 0a57639..0000000 --- a/ldb-2.0.8/lib/tevent/tevent_debug.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Andrew Tridgell 2005 - Copyright (C) Jelmer Vernooij 2005 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#include "tevent.h" -#include "tevent_internal.h" - -/******************************************************************** - * Debug wrapper functions, modeled (with lot's of code copied as is) - * after the ev debug wrapper functions - ********************************************************************/ - -/* - this allows the user to choose their own debug function -*/ -int tevent_set_debug(struct tevent_context *ev, - void (*debug)(void *context, - enum tevent_debug_level level, - const char *fmt, - va_list ap) PRINTF_ATTRIBUTE(3,0), - void *context) -{ - if (ev->wrapper.glue != NULL) { - ev = tevent_wrapper_main_ev(ev); - tevent_abort(ev, "tevent_set_debug() on wrapper"); - errno = EINVAL; - return -1; - } - - ev->debug_ops.debug = debug; - ev->debug_ops.context = context; - return 0; -} - -/* - debug function for ev_set_debug_stderr -*/ -static void tevent_debug_stderr(void *private_data, - enum tevent_debug_level level, - const char *fmt, - va_list ap) PRINTF_ATTRIBUTE(3,0); -static void tevent_debug_stderr(void *private_data, - enum tevent_debug_level level, - const char *fmt, va_list ap) -{ - if (level <= TEVENT_DEBUG_WARNING) { - vfprintf(stderr, fmt, ap); - } -} - -/* - convenience function to setup debug messages on stderr - messages of level TEVENT_DEBUG_WARNING and higher are printed -*/ -int tevent_set_debug_stderr(struct tevent_context *ev) -{ - return tevent_set_debug(ev, tevent_debug_stderr, ev); -} - -/* - * log a message - * - * The default debug action is to ignore debugging messages. - * This is the most appropriate action for a library. - * Applications using the library must decide where to - * redirect debugging messages -*/ -void tevent_debug(struct tevent_context *ev, enum tevent_debug_level level, - const char *fmt, ...) -{ - va_list ap; - if (!ev) { - return; - } - if (ev->wrapper.glue != NULL) { - ev = tevent_wrapper_main_ev(ev); - } - if (ev->debug_ops.debug == NULL) { - return; - } - va_start(ap, fmt); - ev->debug_ops.debug(ev->debug_ops.context, level, fmt, ap); - va_end(ap); -} - -void tevent_set_trace_callback(struct tevent_context *ev, - tevent_trace_callback_t cb, - void *private_data) -{ - if (ev->wrapper.glue != NULL) { - ev = tevent_wrapper_main_ev(ev); - tevent_abort(ev, "tevent_set_trace_callback() on wrapper"); - return; - } - - ev->tracing.callback = cb; - ev->tracing.private_data = private_data; -} - -void tevent_get_trace_callback(struct tevent_context *ev, - tevent_trace_callback_t *cb, - void *private_data) -{ - *cb = ev->tracing.callback; - *(void**)private_data = ev->tracing.private_data; -} - -void tevent_trace_point_callback(struct tevent_context *ev, - enum tevent_trace_point tp) -{ - if (ev->tracing.callback != NULL) { - ev->tracing.callback(tp, ev->tracing.private_data); - } -} diff --git a/ldb-2.0.8/lib/tevent/tevent_epoll.c b/ldb-2.0.8/lib/tevent/tevent_epoll.c deleted file mode 100644 index 9cbe505..0000000 --- a/ldb-2.0.8/lib/tevent/tevent_epoll.c +++ /dev/null @@ -1,956 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - main select loop and event handling - epoll implementation - - Copyright (C) Andrew Tridgell 2003-2005 - Copyright (C) Stefan Metzmacher 2005-2013 - Copyright (C) Jeremy Allison 2013 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#include "system/filesys.h" -#include "system/select.h" -#include "tevent.h" -#include "tevent_internal.h" -#include "tevent_util.h" - -struct epoll_event_context { - /* a pointer back to the generic event_context */ - struct tevent_context *ev; - - /* when using epoll this is the handle from epoll_create */ - int epoll_fd; - - pid_t pid; - - bool panic_force_replay; - bool *panic_state; - bool (*panic_fallback)(struct tevent_context *ev, bool replay); -}; - -#define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT (1<<0) -#define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1) -#define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2) -#define EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX (1<<3) - -#ifdef TEST_PANIC_FALLBACK - -static int epoll_create_panic_fallback(struct epoll_event_context *epoll_ev, - int size) -{ - if (epoll_ev->panic_fallback == NULL) { - return epoll_create(size); - } - - /* 50% of the time, fail... */ - if ((random() % 2) == 0) { - errno = EINVAL; - return -1; - } - - return epoll_create(size); -} - -static int epoll_ctl_panic_fallback(struct epoll_event_context *epoll_ev, - int epfd, int op, int fd, - struct epoll_event *event) -{ - if (epoll_ev->panic_fallback == NULL) { - return epoll_ctl(epfd, op, fd, event); - } - - /* 50% of the time, fail... */ - if ((random() % 2) == 0) { - errno = EINVAL; - return -1; - } - - return epoll_ctl(epfd, op, fd, event); -} - -static int epoll_wait_panic_fallback(struct epoll_event_context *epoll_ev, - int epfd, - struct epoll_event *events, - int maxevents, - int timeout) -{ - if (epoll_ev->panic_fallback == NULL) { - return epoll_wait(epfd, events, maxevents, timeout); - } - - /* 50% of the time, fail... */ - if ((random() % 2) == 0) { - errno = EINVAL; - return -1; - } - - return epoll_wait(epfd, events, maxevents, timeout); -} - -#define epoll_create(_size) \ - epoll_create_panic_fallback(epoll_ev, _size) -#define epoll_ctl(_epfd, _op, _fd, _event) \ - epoll_ctl_panic_fallback(epoll_ev,_epfd, _op, _fd, _event) -#define epoll_wait(_epfd, _events, _maxevents, _timeout) \ - epoll_wait_panic_fallback(epoll_ev, _epfd, _events, _maxevents, _timeout) -#endif - -/* - called to set the panic fallback function. -*/ -_PRIVATE_ void tevent_epoll_set_panic_fallback(struct tevent_context *ev, - bool (*panic_fallback)(struct tevent_context *ev, - bool replay)) -{ - struct epoll_event_context *epoll_ev = - talloc_get_type_abort(ev->additional_data, - struct epoll_event_context); - - epoll_ev->panic_fallback = panic_fallback; -} - -/* - called when a epoll call fails -*/ -static void epoll_panic(struct epoll_event_context *epoll_ev, - const char *reason, bool replay) -{ - struct tevent_context *ev = epoll_ev->ev; - bool (*panic_fallback)(struct tevent_context *ev, bool replay); - - panic_fallback = epoll_ev->panic_fallback; - - if (epoll_ev->panic_state != NULL) { - *epoll_ev->panic_state = true; - } - - if (epoll_ev->panic_force_replay) { - replay = true; - } - - TALLOC_FREE(ev->additional_data); - - if (panic_fallback == NULL) { - tevent_debug(ev, TEVENT_DEBUG_FATAL, - "%s (%s) replay[%u] - calling abort()\n", - reason, strerror(errno), (unsigned)replay); - abort(); - } - - tevent_debug(ev, TEVENT_DEBUG_ERROR, - "%s (%s) replay[%u] - calling panic_fallback\n", - reason, strerror(errno), (unsigned)replay); - - if (!panic_fallback(ev, replay)) { - /* Fallback failed. */ - tevent_debug(ev, TEVENT_DEBUG_FATAL, - "%s (%s) replay[%u] - calling abort()\n", - reason, strerror(errno), (unsigned)replay); - abort(); - } -} - -/* - map from TEVENT_FD_* to EPOLLIN/EPOLLOUT -*/ -static uint32_t epoll_map_flags(uint16_t flags) -{ - uint32_t ret = 0; - if (flags & TEVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP); - if (flags & TEVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP); - return ret; -} - -/* - free the epoll fd -*/ -static int epoll_ctx_destructor(struct epoll_event_context *epoll_ev) -{ - close(epoll_ev->epoll_fd); - epoll_ev->epoll_fd = -1; - return 0; -} - -/* - init the epoll fd -*/ -static int epoll_init_ctx(struct epoll_event_context *epoll_ev) -{ - epoll_ev->epoll_fd = epoll_create(64); - if (epoll_ev->epoll_fd == -1) { - tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL, - "Failed to create epoll handle.\n"); - return -1; - } - - if (!ev_set_close_on_exec(epoll_ev->epoll_fd)) { - tevent_debug(epoll_ev->ev, TEVENT_DEBUG_WARNING, - "Failed to set close-on-exec, file descriptor may be leaked to children.\n"); - } - - epoll_ev->pid = getpid(); - talloc_set_destructor(epoll_ev, epoll_ctx_destructor); - - return 0; -} - -static void epoll_update_event(struct epoll_event_context *epoll_ev, struct tevent_fd *fde); - -/* - reopen the epoll handle when our pid changes - see http://junkcode.samba.org/ftp/unpacked/junkcode/epoll_fork.c for an - demonstration of why this is needed - */ -static void epoll_check_reopen(struct epoll_event_context *epoll_ev) -{ - struct tevent_fd *fde; - bool *caller_panic_state = epoll_ev->panic_state; - bool panic_triggered = false; - - if (epoll_ev->pid == getpid()) { - return; - } - - close(epoll_ev->epoll_fd); - epoll_ev->epoll_fd = epoll_create(64); - if (epoll_ev->epoll_fd == -1) { - epoll_panic(epoll_ev, "epoll_create() failed", false); - return; - } - - if (!ev_set_close_on_exec(epoll_ev->epoll_fd)) { - tevent_debug(epoll_ev->ev, TEVENT_DEBUG_WARNING, - "Failed to set close-on-exec, file descriptor may be leaked to children.\n"); - } - - epoll_ev->pid = getpid(); - epoll_ev->panic_state = &panic_triggered; - for (fde=epoll_ev->ev->fd_events;fde;fde=fde->next) { - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; - epoll_update_event(epoll_ev, fde); - - if (panic_triggered) { - if (caller_panic_state != NULL) { - *caller_panic_state = true; - } - return; - } - } - epoll_ev->panic_state = NULL; -} - -/* - epoll cannot add the same file descriptor twice, once - with read, once with write which is allowed by the - tevent backend. Multiplex the existing fde, flag it - as such so we can search for the correct fde on - event triggering. -*/ - -static int epoll_add_multiplex_fd(struct epoll_event_context *epoll_ev, - struct tevent_fd *add_fde) -{ - struct epoll_event event; - struct tevent_fd *mpx_fde; - int ret; - - /* Find the existing fde that caused the EEXIST error. */ - for (mpx_fde = epoll_ev->ev->fd_events; mpx_fde; mpx_fde = mpx_fde->next) { - if (mpx_fde->fd != add_fde->fd) { - continue; - } - - if (mpx_fde == add_fde) { - continue; - } - - break; - } - if (mpx_fde == NULL) { - tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL, - "can't find multiplex fde for fd[%d]", - add_fde->fd); - return -1; - } - - if (mpx_fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) { - /* Logic error. Can't have more than 2 multiplexed fde's. */ - tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL, - "multiplex fde for fd[%d] is already multiplexed\n", - mpx_fde->fd); - return -1; - } - - /* - * The multiplex fde must have the same fd, and also - * already have an epoll event attached. - */ - if (!(mpx_fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT)) { - /* Logic error. Can't have more than 2 multiplexed fde's. */ - tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL, - "multiplex fde for fd[%d] has no event\n", - mpx_fde->fd); - return -1; - } - - /* Modify the mpx_fde to add in the new flags. */ - ZERO_STRUCT(event); - event.events = epoll_map_flags(mpx_fde->flags); - event.events |= epoll_map_flags(add_fde->flags); - event.data.ptr = mpx_fde; - ret = epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_MOD, mpx_fde->fd, &event); - if (ret != 0 && errno == EBADF) { - tevent_debug(epoll_ev->ev, TEVENT_DEBUG_ERROR, - "EPOLL_CTL_MOD EBADF for " - "add_fde[%p] mpx_fde[%p] fd[%d] - disabling\n", - add_fde, mpx_fde, add_fde->fd); - DLIST_REMOVE(epoll_ev->ev->fd_events, mpx_fde); - mpx_fde->wrapper = NULL; - mpx_fde->event_ctx = NULL; - DLIST_REMOVE(epoll_ev->ev->fd_events, add_fde); - add_fde->wrapper = NULL; - add_fde->event_ctx = NULL; - return 0; - } else if (ret != 0) { - return ret; - } - - /* - * Make each fde->additional_data pointers point at each other - * so we can look them up from each other. They are now paired. - */ - mpx_fde->additional_data = (struct tevent_fd *)add_fde; - add_fde->additional_data = (struct tevent_fd *)mpx_fde; - - /* Now flag both fde's as being multiplexed. */ - mpx_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX; - add_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX; - - /* we need to keep the GOT_ERROR flag */ - if (mpx_fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR) { - add_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR; - } - - return 0; -} - -/* - add the epoll event to the given fd_event -*/ -static void epoll_add_event(struct epoll_event_context *epoll_ev, struct tevent_fd *fde) -{ - struct epoll_event event; - int ret; - struct tevent_fd *mpx_fde = NULL; - - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - - if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) { - /* - * This is a multiplexed fde, we need to include both - * flags in the modified event. - */ - mpx_fde = talloc_get_type_abort(fde->additional_data, - struct tevent_fd); - - mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; - mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - } - - ZERO_STRUCT(event); - event.events = epoll_map_flags(fde->flags); - if (mpx_fde != NULL) { - event.events |= epoll_map_flags(mpx_fde->flags); - } - event.data.ptr = fde; - ret = epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_ADD, fde->fd, &event); - if (ret != 0 && errno == EBADF) { - tevent_debug(epoll_ev->ev, TEVENT_DEBUG_ERROR, - "EPOLL_CTL_ADD EBADF for " - "fde[%p] mpx_fde[%p] fd[%d] - disabling\n", - fde, mpx_fde, fde->fd); - DLIST_REMOVE(epoll_ev->ev->fd_events, fde); - fde->wrapper = NULL; - fde->event_ctx = NULL; - if (mpx_fde != NULL) { - DLIST_REMOVE(epoll_ev->ev->fd_events, mpx_fde); - mpx_fde->wrapper = NULL; - mpx_fde->event_ctx = NULL; - } - return; - } else if (ret != 0 && errno == EEXIST && mpx_fde == NULL) { - ret = epoll_add_multiplex_fd(epoll_ev, fde); - if (ret != 0) { - epoll_panic(epoll_ev, "epoll_add_multiplex_fd failed", - false); - return; - } - } else if (ret != 0) { - epoll_panic(epoll_ev, "EPOLL_CTL_ADD failed", false); - return; - } - - fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; - /* only if we want to read we want to tell the event handler about errors */ - if (fde->flags & TEVENT_FD_READ) { - fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - } - - if (mpx_fde == NULL) { - return; - } - - mpx_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; - /* only if we want to read we want to tell the event handler about errors */ - if (mpx_fde->flags & TEVENT_FD_READ) { - mpx_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - } -} - -/* - delete the epoll event for given fd_event -*/ -static void epoll_del_event(struct epoll_event_context *epoll_ev, struct tevent_fd *fde) -{ - struct epoll_event event; - int ret; - struct tevent_fd *mpx_fde = NULL; - - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - - if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) { - /* - * This is a multiplexed fde, we need to modify both events. - */ - mpx_fde = talloc_get_type_abort(fde->additional_data, - struct tevent_fd); - - mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; - mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - } - - ZERO_STRUCT(event); - ret = epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_DEL, fde->fd, &event); - if (ret != 0 && errno == ENOENT) { - /* - * This can happen after a epoll_check_reopen - * within epoll_event_fd_destructor. - */ - tevent_debug(epoll_ev->ev, TEVENT_DEBUG_TRACE, - "EPOLL_CTL_DEL ignoring ENOENT for fd[%d]\n", - fde->fd); - return; - } else if (ret != 0 && errno == EBADF) { - tevent_debug(epoll_ev->ev, TEVENT_DEBUG_WARNING, - "EPOLL_CTL_DEL EBADF for " - "fde[%p] mpx_fde[%p] fd[%d] - disabling\n", - fde, mpx_fde, fde->fd); - DLIST_REMOVE(epoll_ev->ev->fd_events, fde); - fde->wrapper = NULL; - fde->event_ctx = NULL; - if (mpx_fde != NULL) { - DLIST_REMOVE(epoll_ev->ev->fd_events, mpx_fde); - mpx_fde->wrapper = NULL; - mpx_fde->event_ctx = NULL; - } - return; - } else if (ret != 0) { - epoll_panic(epoll_ev, "EPOLL_CTL_DEL failed", false); - return; - } -} - -/* - change the epoll event to the given fd_event -*/ -static void epoll_mod_event(struct epoll_event_context *epoll_ev, struct tevent_fd *fde) -{ - struct tevent_fd *mpx_fde = NULL; - struct epoll_event event; - int ret; - - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - - if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) { - /* - * This is a multiplexed fde, we need to include both - * flags in the modified event. - */ - mpx_fde = talloc_get_type_abort(fde->additional_data, - struct tevent_fd); - - mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; - mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - } - - ZERO_STRUCT(event); - event.events = epoll_map_flags(fde->flags); - if (mpx_fde != NULL) { - event.events |= epoll_map_flags(mpx_fde->flags); - } - event.data.ptr = fde; - ret = epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_MOD, fde->fd, &event); - if (ret != 0 && errno == EBADF) { - tevent_debug(epoll_ev->ev, TEVENT_DEBUG_ERROR, - "EPOLL_CTL_MOD EBADF for " - "fde[%p] mpx_fde[%p] fd[%d] - disabling\n", - fde, mpx_fde, fde->fd); - DLIST_REMOVE(epoll_ev->ev->fd_events, fde); - fde->wrapper = NULL; - fde->event_ctx = NULL; - if (mpx_fde != NULL) { - DLIST_REMOVE(epoll_ev->ev->fd_events, mpx_fde); - mpx_fde->wrapper = NULL; - mpx_fde->event_ctx = NULL; - } - return; - } else if (ret != 0) { - epoll_panic(epoll_ev, "EPOLL_CTL_MOD failed", false); - return; - } - - fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; - /* only if we want to read we want to tell the event handler about errors */ - if (fde->flags & TEVENT_FD_READ) { - fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - } - - if (mpx_fde == NULL) { - return; - } - - mpx_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; - /* only if we want to read we want to tell the event handler about errors */ - if (mpx_fde->flags & TEVENT_FD_READ) { - mpx_fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR; - } -} - -static void epoll_update_event(struct epoll_event_context *epoll_ev, struct tevent_fd *fde) -{ - bool got_error = (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR); - bool want_read = (fde->flags & TEVENT_FD_READ); - bool want_write= (fde->flags & TEVENT_FD_WRITE); - struct tevent_fd *mpx_fde = NULL; - - if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) { - /* - * work out what the multiplexed fde wants. - */ - mpx_fde = talloc_get_type_abort(fde->additional_data, - struct tevent_fd); - - if (mpx_fde->flags & TEVENT_FD_READ) { - want_read = true; - } - - if (mpx_fde->flags & TEVENT_FD_WRITE) { - want_write = true; - } - } - - /* there's already an event */ - if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT) { - if (want_read || (want_write && !got_error)) { - epoll_mod_event(epoll_ev, fde); - return; - } - /* - * if we want to match the select behavior, we need to remove the epoll_event - * when the caller isn't interested in events. - * - * this is because epoll reports EPOLLERR and EPOLLHUP, even without asking for them - */ - epoll_del_event(epoll_ev, fde); - return; - } - - /* there's no epoll_event attached to the fde */ - if (want_read || (want_write && !got_error)) { - epoll_add_event(epoll_ev, fde); - return; - } -} - -/* - Cope with epoll returning EPOLLHUP|EPOLLERR on an event. - Return true if there's nothing else to do, false if - this event needs further handling. -*/ -static bool epoll_handle_hup_or_err(struct epoll_event_context *epoll_ev, - struct tevent_fd *fde) -{ - if (fde == NULL) { - /* Nothing to do if no event. */ - return true; - } - - fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR; - /* - * if we only wait for TEVENT_FD_WRITE, we should not tell the - * event handler about it, and remove the epoll_event, - * as we only report errors when waiting for read events, - * to match the select() behavior - */ - if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR)) { - /* - * Do the same as the poll backend and - * remove the writeable flag. - */ - fde->flags &= ~TEVENT_FD_WRITE; - return true; - } - /* This has TEVENT_FD_READ set, we're not finished. */ - return false; -} - -/* - event loop handling using epoll -*/ -static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval *tvalp) -{ - int ret, i; -#define MAXEVENTS 1 - struct epoll_event events[MAXEVENTS]; - int timeout = -1; - int wait_errno; - - if (tvalp) { - /* it's better to trigger timed events a bit later than too early */ - timeout = ((tvalp->tv_usec+999) / 1000) + (tvalp->tv_sec*1000); - } - - if (epoll_ev->ev->signal_events && - tevent_common_check_signal(epoll_ev->ev)) { - return 0; - } - - tevent_trace_point_callback(epoll_ev->ev, TEVENT_TRACE_BEFORE_WAIT); - ret = epoll_wait(epoll_ev->epoll_fd, events, MAXEVENTS, timeout); - wait_errno = errno; - tevent_trace_point_callback(epoll_ev->ev, TEVENT_TRACE_AFTER_WAIT); - - if (ret == -1 && wait_errno == EINTR && epoll_ev->ev->signal_events) { - if (tevent_common_check_signal(epoll_ev->ev)) { - return 0; - } - } - - if (ret == -1 && wait_errno != EINTR) { - epoll_panic(epoll_ev, "epoll_wait() failed", true); - return -1; - } - - if (ret == 0 && tvalp) { - /* we don't care about a possible delay here */ - tevent_common_loop_timer_delay(epoll_ev->ev); - return 0; - } - - for (i=0;iadditional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) { - /* - * Save off the multiplexed event in case we need - * to use it to call the handler function. - */ - mpx_fde = talloc_get_type_abort(fde->additional_data, - struct tevent_fd); - } - if (events[i].events & (EPOLLHUP|EPOLLERR)) { - bool handled_fde = epoll_handle_hup_or_err(epoll_ev, fde); - bool handled_mpx = epoll_handle_hup_or_err(epoll_ev, mpx_fde); - - if (handled_fde && handled_mpx) { - epoll_update_event(epoll_ev, fde); - continue; - } - - if (!handled_mpx) { - /* - * If the mpx event was the one that needs - * further handling, it's the TEVENT_FD_READ - * event so switch over and call that handler. - */ - fde = mpx_fde; - mpx_fde = NULL; - } - flags |= TEVENT_FD_READ; - } - if (events[i].events & EPOLLIN) flags |= TEVENT_FD_READ; - if (events[i].events & EPOLLOUT) flags |= TEVENT_FD_WRITE; - - if (flags & TEVENT_FD_WRITE) { - if (fde->flags & TEVENT_FD_WRITE) { - mpx_fde = NULL; - } - if (mpx_fde && mpx_fde->flags & TEVENT_FD_WRITE) { - fde = mpx_fde; - mpx_fde = NULL; - } - } - - if (mpx_fde) { - /* Ensure we got the right fde. */ - if ((flags & fde->flags) == 0) { - fde = mpx_fde; - mpx_fde = NULL; - } - } - - /* - * make sure we only pass the flags - * the handler is expecting. - */ - flags &= fde->flags; - if (flags) { - return tevent_common_invoke_fd_handler(fde, flags, NULL); - } - } - - return 0; -} - -/* - create a epoll_event_context structure. -*/ -static int epoll_event_context_init(struct tevent_context *ev) -{ - int ret; - struct epoll_event_context *epoll_ev; - - /* - * We might be called during tevent_re_initialise() - * which means we need to free our old additional_data. - */ - TALLOC_FREE(ev->additional_data); - - epoll_ev = talloc_zero(ev, struct epoll_event_context); - if (!epoll_ev) return -1; - epoll_ev->ev = ev; - epoll_ev->epoll_fd = -1; - - ret = epoll_init_ctx(epoll_ev); - if (ret != 0) { - talloc_free(epoll_ev); - return ret; - } - - ev->additional_data = epoll_ev; - return 0; -} - -/* - destroy an fd_event -*/ -static int epoll_event_fd_destructor(struct tevent_fd *fde) -{ - struct tevent_context *ev = fde->event_ctx; - struct epoll_event_context *epoll_ev = NULL; - bool panic_triggered = false; - struct tevent_fd *mpx_fde = NULL; - int flags = fde->flags; - - if (ev == NULL) { - return tevent_common_fd_destructor(fde); - } - - epoll_ev = talloc_get_type_abort(ev->additional_data, - struct epoll_event_context); - - /* - * we must remove the event from the list - * otherwise a panic fallback handler may - * reuse invalid memory - */ - DLIST_REMOVE(ev->fd_events, fde); - - if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX) { - mpx_fde = talloc_get_type_abort(fde->additional_data, - struct tevent_fd); - - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX; - mpx_fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_MPX; - - fde->additional_data = NULL; - mpx_fde->additional_data = NULL; - - fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; - } - - epoll_ev->panic_state = &panic_triggered; - epoll_check_reopen(epoll_ev); - if (panic_triggered) { - return tevent_common_fd_destructor(fde); - } - - if (mpx_fde != NULL) { - epoll_update_event(epoll_ev, mpx_fde); - if (panic_triggered) { - return tevent_common_fd_destructor(fde); - } - } - - fde->flags = 0; - epoll_update_event(epoll_ev, fde); - fde->flags = flags; - if (panic_triggered) { - return tevent_common_fd_destructor(fde); - } - epoll_ev->panic_state = NULL; - - return tevent_common_fd_destructor(fde); -} - -/* - add a fd based event - return NULL on failure (memory allocation error) -*/ -static struct tevent_fd *epoll_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx, - int fd, uint16_t flags, - tevent_fd_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ - struct epoll_event_context *epoll_ev = - talloc_get_type_abort(ev->additional_data, - struct epoll_event_context); - struct tevent_fd *fde; - bool panic_triggered = false; - - fde = tevent_common_add_fd(ev, mem_ctx, fd, flags, - handler, private_data, - handler_name, location); - if (!fde) return NULL; - - talloc_set_destructor(fde, epoll_event_fd_destructor); - - epoll_ev->panic_state = &panic_triggered; - epoll_check_reopen(epoll_ev); - if (panic_triggered) { - return fde; - } - epoll_ev->panic_state = NULL; - - epoll_update_event(epoll_ev, fde); - - return fde; -} - -/* - set the fd event flags -*/ -static void epoll_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags) -{ - struct tevent_context *ev; - struct epoll_event_context *epoll_ev; - bool panic_triggered = false; - - if (fde->flags == flags) return; - - ev = fde->event_ctx; - epoll_ev = talloc_get_type_abort(ev->additional_data, - struct epoll_event_context); - - fde->flags = flags; - - epoll_ev->panic_state = &panic_triggered; - epoll_check_reopen(epoll_ev); - if (panic_triggered) { - return; - } - epoll_ev->panic_state = NULL; - - epoll_update_event(epoll_ev, fde); -} - -/* - do a single event loop using the events defined in ev -*/ -static int epoll_event_loop_once(struct tevent_context *ev, const char *location) -{ - struct epoll_event_context *epoll_ev = - talloc_get_type_abort(ev->additional_data, - struct epoll_event_context); - struct timeval tval; - bool panic_triggered = false; - - if (ev->signal_events && - tevent_common_check_signal(ev)) { - return 0; - } - - if (ev->threaded_contexts != NULL) { - tevent_common_threaded_activate_immediate(ev); - } - - if (ev->immediate_events && - tevent_common_loop_immediate(ev)) { - return 0; - } - - tval = tevent_common_loop_timer_delay(ev); - if (tevent_timeval_is_zero(&tval)) { - return 0; - } - - epoll_ev->panic_state = &panic_triggered; - epoll_ev->panic_force_replay = true; - epoll_check_reopen(epoll_ev); - if (panic_triggered) { - errno = EINVAL; - return -1; - } - epoll_ev->panic_force_replay = false; - epoll_ev->panic_state = NULL; - - return epoll_event_loop(epoll_ev, &tval); -} - -static const struct tevent_ops epoll_event_ops = { - .context_init = epoll_event_context_init, - .add_fd = epoll_event_add_fd, - .set_fd_close_fn = tevent_common_fd_set_close_fn, - .get_fd_flags = tevent_common_fd_get_flags, - .set_fd_flags = epoll_event_set_fd_flags, - .add_timer = tevent_common_add_timer_v2, - .schedule_immediate = tevent_common_schedule_immediate, - .add_signal = tevent_common_add_signal, - .loop_once = epoll_event_loop_once, - .loop_wait = tevent_common_loop_wait, -}; - -_PRIVATE_ bool tevent_epoll_init(void) -{ - return tevent_register_backend("epoll", &epoll_event_ops); -} diff --git a/ldb-2.0.8/lib/tevent/tevent_fd.c b/ldb-2.0.8/lib/tevent/tevent_fd.c deleted file mode 100644 index a0557fe..0000000 --- a/ldb-2.0.8/lib/tevent/tevent_fd.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - common events code for fd events - - Copyright (C) Stefan Metzmacher 2009 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#define TEVENT_DEPRECATED 1 -#include "tevent.h" -#include "tevent_internal.h" -#include "tevent_util.h" - -int tevent_common_fd_destructor(struct tevent_fd *fde) -{ - if (fde->destroyed) { - tevent_common_check_double_free(fde, "tevent_fd double free"); - goto done; - } - fde->destroyed = true; - - if (fde->event_ctx) { - DLIST_REMOVE(fde->event_ctx->fd_events, fde); - } - - if (fde->close_fn) { - fde->close_fn(fde->event_ctx, fde, fde->fd, fde->private_data); - fde->fd = -1; - fde->close_fn = NULL; - } - - fde->event_ctx = NULL; -done: - if (fde->busy) { - return -1; - } - fde->wrapper = NULL; - - return 0; -} - -struct tevent_fd *tevent_common_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx, - int fd, uint16_t flags, - tevent_fd_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ - struct tevent_fd *fde; - - /* tevent will crash later on select() if we save - * a negative file descriptor. Better to fail here - * so that consumers will be able to debug it - */ - if (fd < 0) return NULL; - - fde = talloc(mem_ctx?mem_ctx:ev, struct tevent_fd); - if (!fde) return NULL; - - *fde = (struct tevent_fd) { - .event_ctx = ev, - .fd = fd, - .flags = flags, - .handler = handler, - .private_data = private_data, - .handler_name = handler_name, - .location = location, - }; - - DLIST_ADD(ev->fd_events, fde); - - talloc_set_destructor(fde, tevent_common_fd_destructor); - - return fde; -} -uint16_t tevent_common_fd_get_flags(struct tevent_fd *fde) -{ - return fde->flags; -} - -void tevent_common_fd_set_flags(struct tevent_fd *fde, uint16_t flags) -{ - if (fde->flags == flags) return; - fde->flags = flags; -} - -void tevent_common_fd_set_close_fn(struct tevent_fd *fde, - tevent_fd_close_fn_t close_fn) -{ - fde->close_fn = close_fn; -} - -int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags, - bool *removed) -{ - struct tevent_context *handler_ev = fde->event_ctx; - - if (removed != NULL) { - *removed = false; - } - - if (fde->event_ctx == NULL) { - return 0; - } - - fde->busy = true; - if (fde->wrapper != NULL) { - handler_ev = fde->wrapper->wrap_ev; - - tevent_wrapper_push_use_internal(handler_ev, fde->wrapper); - fde->wrapper->ops->before_fd_handler( - fde->wrapper->wrap_ev, - fde->wrapper->private_state, - fde->wrapper->main_ev, - fde, - flags, - fde->handler_name, - fde->location); - } - fde->handler(handler_ev, fde, flags, fde->private_data); - if (fde->wrapper != NULL) { - fde->wrapper->ops->after_fd_handler( - fde->wrapper->wrap_ev, - fde->wrapper->private_state, - fde->wrapper->main_ev, - fde, - flags, - fde->handler_name, - fde->location); - tevent_wrapper_pop_use_internal(handler_ev, fde->wrapper); - } - fde->busy = false; - - if (fde->destroyed) { - talloc_set_destructor(fde, NULL); - TALLOC_FREE(fde); - if (removed != NULL) { - *removed = true; - } - } - - return 0; -} diff --git a/ldb-2.0.8/lib/tevent/tevent_immediate.c b/ldb-2.0.8/lib/tevent/tevent_immediate.c deleted file mode 100644 index d7f8dcc..0000000 --- a/ldb-2.0.8/lib/tevent/tevent_immediate.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - common events code for immediate events - - Copyright (C) Stefan Metzmacher 2009 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#define TEVENT_DEPRECATED 1 -#include "tevent.h" -#include "tevent_internal.h" -#include "tevent_util.h" - -static void tevent_common_immediate_cancel(struct tevent_immediate *im) -{ - const char *create_location = im->create_location; - bool busy = im->busy; - - if (im->destroyed) { - tevent_abort(im->event_ctx, "tevent_immediate use after free"); - return; - } - - if (!im->event_ctx) { - return; - } - - if (im->handler_name != NULL) { - tevent_debug(im->event_ctx, TEVENT_DEBUG_TRACE, - "Cancel immediate event %p \"%s\"\n", - im, im->handler_name); - } - - /* let the backend free im->additional_data */ - if (im->cancel_fn) { - im->cancel_fn(im); - } - - DLIST_REMOVE(im->event_ctx->immediate_events, im); - - *im = (struct tevent_immediate) { - .create_location = create_location, - .busy = busy, - }; - - if (!busy) { - talloc_set_destructor(im, NULL); - } -} - -/* - destroy an immediate event -*/ -static int tevent_common_immediate_destructor(struct tevent_immediate *im) -{ - if (im->destroyed) { - tevent_common_check_double_free(im, - "tevent_immediate double free"); - goto done; - } - - tevent_common_immediate_cancel(im); - - im->destroyed = true; - -done: - if (im->busy) { - return -1; - } - - return 0; -} - -/* - * schedule an immediate event on - */ -void tevent_common_schedule_immediate(struct tevent_immediate *im, - struct tevent_context *ev, - tevent_immediate_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ - const char *create_location = im->create_location; - bool busy = im->busy; - struct tevent_wrapper_glue *glue = im->wrapper; - - tevent_common_immediate_cancel(im); - - if (!handler) { - return; - } - - *im = (struct tevent_immediate) { - .event_ctx = ev, - .wrapper = glue, - .handler = handler, - .private_data = private_data, - .handler_name = handler_name, - .create_location = create_location, - .schedule_location = location, - .busy = busy, - }; - - DLIST_ADD_END(ev->immediate_events, im); - talloc_set_destructor(im, tevent_common_immediate_destructor); - - tevent_debug(ev, TEVENT_DEBUG_TRACE, - "Schedule immediate event \"%s\": %p\n", - handler_name, im); -} - -int tevent_common_invoke_immediate_handler(struct tevent_immediate *im, - bool *removed) -{ - struct tevent_context *handler_ev = im->event_ctx; - struct tevent_context *ev = im->event_ctx; - struct tevent_immediate cur = *im; - - if (removed != NULL) { - *removed = false; - } - - tevent_debug(ev, TEVENT_DEBUG_TRACE, - "Run immediate event \"%s\": %p\n", - im->handler_name, im); - - /* - * remember the handler and then clear the event - * the handler might reschedule the event - */ - - im->busy = true; - im->handler_name = NULL; - tevent_common_immediate_cancel(im); - if (cur.wrapper != NULL) { - handler_ev = cur.wrapper->wrap_ev; - - tevent_wrapper_push_use_internal(handler_ev, cur.wrapper); - cur.wrapper->ops->before_immediate_handler( - cur.wrapper->wrap_ev, - cur.wrapper->private_state, - cur.wrapper->main_ev, - im, - cur.handler_name, - cur.schedule_location); - } - cur.handler(handler_ev, im, cur.private_data); - if (cur.wrapper != NULL) { - cur.wrapper->ops->after_immediate_handler( - cur.wrapper->wrap_ev, - cur.wrapper->private_state, - cur.wrapper->main_ev, - im, - cur.handler_name, - cur.schedule_location); - tevent_wrapper_pop_use_internal(handler_ev, cur.wrapper); - } - im->busy = false; - - if (im->destroyed) { - talloc_set_destructor(im, NULL); - TALLOC_FREE(im); - if (removed != NULL) { - *removed = true; - } - } - - return 0; -} - -/* - trigger the first immediate event and return true - if no event was triggered return false -*/ -bool tevent_common_loop_immediate(struct tevent_context *ev) -{ - struct tevent_immediate *im = ev->immediate_events; - int ret; - - if (!im) { - return false; - } - - ret = tevent_common_invoke_immediate_handler(im, NULL); - if (ret != 0) { - tevent_abort(ev, "tevent_common_invoke_immediate_handler() failed"); - } - - return true; -} - diff --git a/ldb-2.0.8/lib/tevent/tevent_internal.h b/ldb-2.0.8/lib/tevent/tevent_internal.h deleted file mode 100644 index 5365fce..0000000 --- a/ldb-2.0.8/lib/tevent/tevent_internal.h +++ /dev/null @@ -1,471 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - generalised event loop handling - - INTERNAL STRUCTS. THERE ARE NO API GUARANTEES. - External users should only ever have to include this header when - implementing new tevent backends. - - Copyright (C) Stefan Metzmacher 2005-2009 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -struct tevent_req { - /** - * @brief What to do on completion - * - * This is used for the user of an async request, fn is called when - * the request completes, either successfully or with an error. - */ - struct { - /** - * @brief Completion function - * Completion function, to be filled by the API user - */ - tevent_req_fn fn; - /** - * @brief Private data for the completion function - */ - void *private_data; - } async; - - /** - * @brief Private state pointer for the actual implementation - * - * The implementation doing the work for the async request needs to - * keep around current data like for example a fd event. The user of - * an async request should not touch this. - */ - void *data; - - /** - * @brief A function to overwrite the default print function - * - * The implementation doing the work may want to implement a - * custom function to print the text representation of the async - * request. - */ - tevent_req_print_fn private_print; - - /** - * @brief A function to cancel the request - * - * The implementation might want to set a function - * that is called when the tevent_req_cancel() function - * was called. - */ - tevent_req_cancel_fn private_cancel; - - /** - * @brief A function to cleanup the request - * - * The implementation might want to set a function - * that is called before the tevent_req_done() and tevent_req_error() - * trigger the callers callback function. - */ - struct { - tevent_req_cleanup_fn fn; - enum tevent_req_state state; - } private_cleanup; - - /** - * @brief Internal state of the request - * - * Callers should only access this via functions and never directly. - */ - struct { - /** - * @brief The talloc type of the data pointer - * - * This is filled by the tevent_req_create() macro. - * - * This for debugging only. - */ - const char *private_type; - - /** - * @brief The location where the request was created - * - * This uses the __location__ macro via the tevent_req_create() - * macro. - * - * This for debugging only. - */ - const char *create_location; - - /** - * @brief The location where the request was finished - * - * This uses the __location__ macro via the tevent_req_done(), - * tevent_req_error() or tevent_req_nomem() macro. - * - * This for debugging only. - */ - const char *finish_location; - - /** - * @brief The location where the request was canceled - * - * This uses the __location__ macro via the - * tevent_req_cancel() macro. - * - * This for debugging only. - */ - const char *cancel_location; - - /** - * @brief The external state - will be queried by the caller - * - * While the async request is being processed, state will remain in - * TEVENT_REQ_IN_PROGRESS. A request is finished if - * req->state>=TEVENT_REQ_DONE. - */ - enum tevent_req_state state; - - /** - * @brief status code when finished - * - * This status can be queried in the async completion function. It - * will be set to 0 when everything went fine. - */ - uint64_t error; - - /** - * @brief the immediate event used by tevent_req_post - * - */ - struct tevent_immediate *trigger; - - /** - * @brief An event context which will be used to - * defer the _tevent_req_notify_callback(). - */ - struct tevent_context *defer_callback_ev; - - /** - * @brief the timer event if tevent_req_set_endtime was used - * - */ - struct tevent_timer *timer; - - /** - * @brief The place where profiling data is kept - */ - struct tevent_req_profile *profile; - } internal; -}; - -struct tevent_req_profile { - struct tevent_req_profile *prev, *next; - struct tevent_req_profile *parent; - const char *req_name; - pid_t pid; - const char *start_location; - struct timeval start_time; - const char *stop_location; - struct timeval stop_time; - enum tevent_req_state state; - uint64_t user_error; - struct tevent_req_profile *subprofiles; -}; - -struct tevent_fd { - struct tevent_fd *prev, *next; - struct tevent_context *event_ctx; - struct tevent_wrapper_glue *wrapper; - bool busy; - bool destroyed; - int fd; - uint16_t flags; /* see TEVENT_FD_* flags */ - tevent_fd_handler_t handler; - tevent_fd_close_fn_t close_fn; - /* this is private for the specific handler */ - void *private_data; - /* this is for debugging only! */ - const char *handler_name; - const char *location; - /* this is private for the events_ops implementation */ - uint64_t additional_flags; - void *additional_data; -}; - -struct tevent_timer { - struct tevent_timer *prev, *next; - struct tevent_context *event_ctx; - struct tevent_wrapper_glue *wrapper; - bool busy; - bool destroyed; - struct timeval next_event; - tevent_timer_handler_t handler; - /* this is private for the specific handler */ - void *private_data; - /* this is for debugging only! */ - const char *handler_name; - const char *location; - /* this is private for the events_ops implementation */ - void *additional_data; -}; - -struct tevent_immediate { - struct tevent_immediate *prev, *next; - struct tevent_context *event_ctx; - struct tevent_wrapper_glue *wrapper; - bool busy; - bool destroyed; - tevent_immediate_handler_t handler; - /* this is private for the specific handler */ - void *private_data; - /* this is for debugging only! */ - const char *handler_name; - const char *create_location; - const char *schedule_location; - /* this is private for the events_ops implementation */ - void (*cancel_fn)(struct tevent_immediate *im); - void *additional_data; -}; - -struct tevent_signal { - struct tevent_signal *prev, *next; - struct tevent_context *event_ctx; - struct tevent_wrapper_glue *wrapper; - bool busy; - bool destroyed; - int signum; - int sa_flags; - tevent_signal_handler_t handler; - /* this is private for the specific handler */ - void *private_data; - /* this is for debugging only! */ - const char *handler_name; - const char *location; - /* this is private for the events_ops implementation */ - void *additional_data; -}; - -struct tevent_threaded_context { - struct tevent_threaded_context *next, *prev; - -#ifdef HAVE_PTHREAD - pthread_mutex_t event_ctx_mutex; -#endif - struct tevent_context *event_ctx; -}; - -struct tevent_debug_ops { - void (*debug)(void *context, enum tevent_debug_level level, - const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); - void *context; -}; - -void tevent_debug(struct tevent_context *ev, enum tevent_debug_level level, - const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); - -void tevent_abort(struct tevent_context *ev, const char *reason); - -void tevent_common_check_double_free(TALLOC_CTX *ptr, const char *reason); - -struct tevent_context { - /* the specific events implementation */ - const struct tevent_ops *ops; - - /* - * The following three pointers are queried on every loop_once - * in the order in which they appear here. Not measured, but - * hopefully putting them at the top together with "ops" - * should make tevent a *bit* more cache-friendly than before. - */ - - /* list of signal events - used by common code */ - struct tevent_signal *signal_events; - - /* List of threaded job indicators */ - struct tevent_threaded_context *threaded_contexts; - - /* list of immediate events - used by common code */ - struct tevent_immediate *immediate_events; - - /* list of fd events - used by common code */ - struct tevent_fd *fd_events; - - /* list of timed events - used by common code */ - struct tevent_timer *timer_events; - - /* List of scheduled immediates */ - pthread_mutex_t scheduled_mutex; - struct tevent_immediate *scheduled_immediates; - - /* this is private for the events_ops implementation */ - void *additional_data; - - /* pipe hack used with signal handlers */ - struct tevent_fd *wakeup_fde; - int wakeup_fd; /* fd to write into */ -#ifndef HAVE_EVENT_FD - int wakeup_read_fd; -#endif - - /* debugging operations */ - struct tevent_debug_ops debug_ops; - - /* info about the nesting status */ - struct { - bool allowed; - uint32_t level; - tevent_nesting_hook hook_fn; - void *hook_private; - } nesting; - - struct { - tevent_trace_callback_t callback; - void *private_data; - } tracing; - - struct { - /* - * This is used on the main event context - */ - struct tevent_wrapper_glue *list; - - /* - * This is used on the wrapper event context - */ - struct tevent_wrapper_glue *glue; - } wrapper; - - /* - * an optimization pointer into timer_events - * used by used by common code via - * tevent_common_add_timer_v2() - */ - struct tevent_timer *last_zero_timer; - -#ifdef HAVE_PTHREAD - struct tevent_context *prev, *next; -#endif -}; - -const struct tevent_ops *tevent_find_ops_byname(const char *name); - -int tevent_common_context_destructor(struct tevent_context *ev); -int tevent_common_loop_wait(struct tevent_context *ev, - const char *location); - -int tevent_common_fd_destructor(struct tevent_fd *fde); -struct tevent_fd *tevent_common_add_fd(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - int fd, - uint16_t flags, - tevent_fd_handler_t handler, - void *private_data, - const char *handler_name, - const char *location); -void tevent_common_fd_set_close_fn(struct tevent_fd *fde, - tevent_fd_close_fn_t close_fn); -uint16_t tevent_common_fd_get_flags(struct tevent_fd *fde); -void tevent_common_fd_set_flags(struct tevent_fd *fde, uint16_t flags); -int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags, - bool *removed); - -struct tevent_timer *tevent_common_add_timer(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - struct timeval next_event, - tevent_timer_handler_t handler, - void *private_data, - const char *handler_name, - const char *location); -struct tevent_timer *tevent_common_add_timer_v2(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - struct timeval next_event, - tevent_timer_handler_t handler, - void *private_data, - const char *handler_name, - const char *location); -struct timeval tevent_common_loop_timer_delay(struct tevent_context *); -int tevent_common_invoke_timer_handler(struct tevent_timer *te, - struct timeval current_time, - bool *removed); - -void tevent_common_schedule_immediate(struct tevent_immediate *im, - struct tevent_context *ev, - tevent_immediate_handler_t handler, - void *private_data, - const char *handler_name, - const char *location); -int tevent_common_invoke_immediate_handler(struct tevent_immediate *im, - bool *removed); -bool tevent_common_loop_immediate(struct tevent_context *ev); -void tevent_common_threaded_activate_immediate(struct tevent_context *ev); - -bool tevent_common_have_events(struct tevent_context *ev); -int tevent_common_wakeup_init(struct tevent_context *ev); -int tevent_common_wakeup_fd(int fd); -int tevent_common_wakeup(struct tevent_context *ev); - -struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - int signum, - int sa_flags, - tevent_signal_handler_t handler, - void *private_data, - const char *handler_name, - const char *location); -int tevent_common_check_signal(struct tevent_context *ev); -void tevent_cleanup_pending_signal_handlers(struct tevent_signal *se); -int tevent_common_invoke_signal_handler(struct tevent_signal *se, - int signum, int count, void *siginfo, - bool *removed); - -struct tevent_context *tevent_wrapper_main_ev(struct tevent_context *ev); - -struct tevent_wrapper_ops; - -struct tevent_wrapper_glue { - struct tevent_wrapper_glue *prev, *next; - struct tevent_context *wrap_ev; - struct tevent_context *main_ev; - bool busy; - bool destroyed; - const struct tevent_wrapper_ops *ops; - void *private_state; -}; - -void tevent_wrapper_push_use_internal(struct tevent_context *ev, - struct tevent_wrapper_glue *wrapper); -void tevent_wrapper_pop_use_internal(const struct tevent_context *__ev_ptr, - struct tevent_wrapper_glue *wrapper); - -bool tevent_standard_init(void); -bool tevent_poll_init(void); -bool tevent_poll_event_add_fd_internal(struct tevent_context *ev, - struct tevent_fd *fde); -bool tevent_poll_mt_init(void); -#ifdef HAVE_EPOLL -bool tevent_epoll_init(void); -void tevent_epoll_set_panic_fallback(struct tevent_context *ev, - bool (*panic_fallback)(struct tevent_context *ev, - bool replay)); -#endif -#ifdef HAVE_SOLARIS_PORTS -bool tevent_port_init(void); -#endif - - -void tevent_trace_point_callback(struct tevent_context *ev, - enum tevent_trace_point); diff --git a/ldb-2.0.8/lib/tevent/tevent_liboop.c b/ldb-2.0.8/lib/tevent/tevent_liboop.c deleted file mode 100644 index 68be76b..0000000 --- a/ldb-2.0.8/lib/tevent/tevent_liboop.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - Unix SMB/CIFS implementation. - main select loop and event handling - wrapper for http://git.lysator.liu.se/liboop/ - - Copyright (C) Stefan Metzmacher 2005 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "events.h" -#include "events_internal.h" - -#include - -/* - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - NOTE: this code compiles fine, but is completely *UNTESTED* - and is only committed as an example - - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -*/ - -static int oop_event_context_destructor(struct tevent_context *ev) -{ - oop_source_sys *oop_sys = ev->additional_data; - - oop_sys_delete(oop_sys); - - return 0; -} - -/* - create a oop_event_context structure. -*/ -static int oop_event_context_init(struct tevent_context *ev, void *private_data) -{ - oop_source_sys *oop_sys = private_data; - - if (!oop_sys) { - oop_sys = oop_sys_new(); - if (!oop_sys) { - return -1; - } - - talloc_set_destructor(ev, oop_event_context_destructor); - } - - ev->additional_data = oop_sys; - - return 0; -} - -static void *oop_event_fd_handler(oop_source *oop, int fd, oop_event oop_type, void *ptr) -{ - struct tevent_fd *fde = ptr; - - if (fd != fde->fd) return OOP_ERROR; - - switch(oop_type) { - case OOP_READ: - fde->handler(fde->event_ctx, fde, EVENT_FD_READ, fde->private_data); - return OOP_CONTINUE; - case OOP_WRITE: - fde->handler(fde->event_ctx, fde, EVENT_FD_WRITE, fde->private_data); - return OOP_CONTINUE; - case OOP_EXCEPTION: - return OOP_ERROR; - case OOP_NUM_EVENTS: - return OOP_ERROR; - } - - return OOP_ERROR; -} - -/* - destroy an fd_event -*/ -static int oop_event_fd_destructor(struct tevent_fd *fde) -{ - struct tevent_context *ev = fde->event_ctx; - oop_source_sys *oop_sys = ev->additional_data; - oop_source *oop = oop_sys_source(oop_sys); - - if (fde->flags & EVENT_FD_READ) - oop->cancel_fd(oop, fde->fd, OOP_READ); - if (fde->flags & EVENT_FD_WRITE) - oop->cancel_fd(oop, fde->fd, OOP_WRITE); - - if (fde->flags & EVENT_FD_AUTOCLOSE) { - close(fde->fd); - fde->fd = -1; - } - - return 0; -} - -/* - add a fd based event - return NULL on failure (memory allocation error) -*/ -static struct tevent_fd *oop_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx, - int fd, uint16_t flags, - event_fd_handler_t handler, - void *private_data) -{ - struct tevent_fd *fde; - oop_source_sys *oop_sys = ev->additional_data; - oop_source *oop = oop_sys_source(oop_sys); - - fde = talloc(mem_ctx?mem_ctx:ev, struct tevent_fd); - if (!fde) return NULL; - - fde->event_ctx = ev; - fde->fd = fd; - fde->flags = flags; - fde->handler = handler; - fde->private_data = private_data; - fde->additional_flags = 0; - fde->additional_data = NULL; - - if (fde->flags & EVENT_FD_READ) - oop->on_fd(oop, fde->fd, OOP_READ, oop_event_fd_handler, fde); - if (fde->flags & EVENT_FD_WRITE) - oop->on_fd(oop, fde->fd, OOP_WRITE, oop_event_fd_handler, fde); - - talloc_set_destructor(fde, oop_event_fd_destructor); - - return fde; -} - -/* - return the fd event flags -*/ -static uint16_t oop_event_get_fd_flags(struct tevent_fd *fde) -{ - return fde->flags; -} - -/* - set the fd event flags -*/ -static void oop_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags) -{ - oop_source_sys *oop_sys; - oop_source *oop; - - oop_sys = fde->event_ctx->additional_data; - oop = oop_sys_source(oop_sys); - - if ((fde->flags & EVENT_FD_READ)&&(!(flags & EVENT_FD_READ))) - oop->cancel_fd(oop, fde->fd, OOP_READ); - - if ((!(fde->flags & EVENT_FD_READ))&&(flags & EVENT_FD_READ)) - oop->on_fd(oop, fde->fd, OOP_READ, oop_event_fd_handler, fde); - - if ((fde->flags & EVENT_FD_WRITE)&&(!(flags & EVENT_FD_WRITE))) - oop->cancel_fd(oop, fde->fd, OOP_WRITE); - - if ((!(fde->flags & EVENT_FD_WRITE))&&(flags & EVENT_FD_WRITE)) - oop->on_fd(oop, fde->fd, OOP_WRITE, oop_event_fd_handler, fde); - - fde->flags = flags; -} - -static int oop_event_timed_destructor(struct tevent_timer *te); - -static int oop_event_timed_deny_destructor(struct tevent_timer *te) -{ - return -1; -} - -static void *oop_event_timed_handler(oop_source *oop, struct timeval t, void *ptr) -{ - struct tevent_timer *te = ptr; - - /* deny the handler to free the event */ - talloc_set_destructor(te, oop_event_timed_deny_destructor); - te->handler(te->event_ctx, te, t, te->private_data); - - talloc_set_destructor(te, oop_event_timed_destructor); - talloc_free(te); - - return OOP_CONTINUE; -} - -/* - destroy a timed event -*/ -static int oop_event_timed_destructor(struct tevent_timer *te) -{ - struct tevent_context *ev = te->event_ctx; - oop_source_sys *oop_sys = ev->additional_data; - oop_source *oop = oop_sys_source(oop_sys); - - oop->cancel_time(oop, te->next_event, oop_event_timed_handler, te); - - return 0; -} - -/* - add a timed event - return NULL on failure (memory allocation error) -*/ -static struct tevent_timer *oop_event_add_timed(struct tevent_context *ev, TALLOC_CTX *mem_ctx, - struct timeval next_event, - event_timed_handler_t handler, - void *private_data) -{ - oop_source_sys *oop_sys = ev->additional_data; - oop_source *oop = oop_sys_source(oop_sys); - struct tevent_timer *te; - - te = talloc(mem_ctx?mem_ctx:ev, struct tevent_timer); - if (te == NULL) return NULL; - - te->event_ctx = ev; - te->next_event = next_event; - te->handler = handler; - te->private_data = private_data; - te->additional_data = NULL; - - oop->on_time(oop, te->next_event, oop_event_timed_handler, te); - - talloc_set_destructor(te, oop_event_timed_destructor); - - return te; -} - -/* - do a single event loop using the events defined in ev -*/ -static int oop_event_loop_once(struct tevent_context *ev) -{ - void *oop_ret; - oop_source_sys *oop_sys = ev->additional_data; - - oop_ret = oop_sys_run_once(oop_sys); - if (oop_ret == OOP_CONTINUE) { - return 0; - } - - return -1; -} - -/* - return on failure or (with 0) if all fd events are removed -*/ -static int oop_event_loop_wait(struct tevent_context *ev) -{ - void *oop_ret; - oop_source_sys *oop_sys = ev->additional_data; - - oop_ret = oop_sys_run(oop_sys); - if (oop_ret == OOP_CONTINUE) { - return 0; - } - - return -1; -} - -static const struct event_ops event_oop_ops = { - .context_init = oop_event_context_init, - .add_fd = oop_event_add_fd, - .get_fd_flags = oop_event_get_fd_flags, - .set_fd_flags = oop_event_set_fd_flags, - .add_timer = oop_event_add_timed, - .add_signal = common_event_add_signal, - .loop_once = oop_event_loop_once, - .loop_wait = oop_event_loop_wait, -}; - -const struct event_ops *event_liboop_get_ops(void) -{ - return &event_oop_ops; -} diff --git a/ldb-2.0.8/lib/tevent/tevent_poll.c b/ldb-2.0.8/lib/tevent/tevent_poll.c deleted file mode 100644 index f4c6c2d..0000000 --- a/ldb-2.0.8/lib/tevent/tevent_poll.c +++ /dev/null @@ -1,663 +0,0 @@ -/* - Unix SMB/CIFS implementation. - main select loop and event handling - Copyright (C) Andrew Tridgell 2003-2005 - Copyright (C) Stefan Metzmacher 2005-2009 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#include "system/filesys.h" -#include "system/select.h" -#include "tevent.h" -#include "tevent_util.h" -#include "tevent_internal.h" - -struct poll_event_context { - /* a pointer back to the generic event_context */ - struct tevent_context *ev; - - /* - * one or more events were deleted or disabled - */ - bool deleted; - - /* - * These two arrays are maintained together. - * - * The following is always true: - * num_fds <= num_fdes - * - * new 'fresh' elements are added at the end - * of the 'fdes' array and picked up later - * to the 'fds' array in poll_event_sync_arrays() - * before the poll() syscall. - */ - struct pollfd *fds; - size_t num_fds; - struct tevent_fd **fdes; - size_t num_fdes; - - /* - * use tevent_common_wakeup(ev) to wake the poll() thread - */ - bool use_mt_mode; -}; - -/* - create a poll_event_context structure. -*/ -static int poll_event_context_init(struct tevent_context *ev) -{ - struct poll_event_context *poll_ev; - - /* - * we might be called during tevent_re_initialise() - * which means we need to free our old additional_data - * in order to detach old fd events from the - * poll_ev->fresh list - */ - TALLOC_FREE(ev->additional_data); - - poll_ev = talloc_zero(ev, struct poll_event_context); - if (poll_ev == NULL) { - return -1; - } - poll_ev->ev = ev; - ev->additional_data = poll_ev; - return 0; -} - -static int poll_event_context_init_mt(struct tevent_context *ev) -{ - struct poll_event_context *poll_ev; - int ret; - - ret = poll_event_context_init(ev); - if (ret == -1) { - return ret; - } - - poll_ev = talloc_get_type_abort( - ev->additional_data, struct poll_event_context); - - ret = tevent_common_wakeup_init(ev); - if (ret != 0) { - return ret; - } - - poll_ev->use_mt_mode = true; - - return 0; -} - -static void poll_event_wake_pollthread(struct poll_event_context *poll_ev) -{ - if (!poll_ev->use_mt_mode) { - return; - } - tevent_common_wakeup(poll_ev->ev); -} - -/* - destroy an fd_event -*/ -static int poll_event_fd_destructor(struct tevent_fd *fde) -{ - struct tevent_context *ev = fde->event_ctx; - struct poll_event_context *poll_ev; - uint64_t del_idx = fde->additional_flags; - - if (ev == NULL) { - goto done; - } - - poll_ev = talloc_get_type_abort( - ev->additional_data, struct poll_event_context); - - if (del_idx == UINT64_MAX) { - goto done; - } - - poll_ev->fdes[del_idx] = NULL; - poll_ev->deleted = true; - poll_event_wake_pollthread(poll_ev); -done: - return tevent_common_fd_destructor(fde); -} - -static void poll_event_schedule_immediate(struct tevent_immediate *im, - struct tevent_context *ev, - tevent_immediate_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ - struct poll_event_context *poll_ev = talloc_get_type_abort( - ev->additional_data, struct poll_event_context); - - tevent_common_schedule_immediate(im, ev, handler, private_data, - handler_name, location); - poll_event_wake_pollthread(poll_ev); -} - -/* - Private function called by "standard" backend fallback. - Note this only allows fallback to "poll" backend, not "poll-mt". -*/ -_PRIVATE_ bool tevent_poll_event_add_fd_internal(struct tevent_context *ev, - struct tevent_fd *fde) -{ - struct poll_event_context *poll_ev = talloc_get_type_abort( - ev->additional_data, struct poll_event_context); - uint64_t fde_idx = UINT64_MAX; - size_t num_fdes; - - fde->additional_flags = UINT64_MAX; - talloc_set_destructor(fde, poll_event_fd_destructor); - - if (fde->flags == 0) { - /* - * Nothing more to do... - */ - return true; - } - - /* - * We need to add it to the end of the 'fdes' array. - */ - num_fdes = poll_ev->num_fdes + 1; - if (num_fdes > talloc_array_length(poll_ev->fdes)) { - struct tevent_fd **tmp_fdes = NULL; - size_t array_length; - - array_length = (num_fdes + 15) & ~15; /* round up to 16 */ - - tmp_fdes = talloc_realloc(poll_ev, - poll_ev->fdes, - struct tevent_fd *, - array_length); - if (tmp_fdes == NULL) { - return false; - } - poll_ev->fdes = tmp_fdes; - } - - fde_idx = poll_ev->num_fdes; - fde->additional_flags = fde_idx; - poll_ev->fdes[fde_idx] = fde; - poll_ev->num_fdes++; - - return true; -} - -/* - add a fd based event - return NULL on failure (memory allocation error) -*/ -static struct tevent_fd *poll_event_add_fd(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - int fd, uint16_t flags, - tevent_fd_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ - struct poll_event_context *poll_ev = talloc_get_type_abort( - ev->additional_data, struct poll_event_context); - struct tevent_fd *fde; - bool ok; - - if (fd < 0) { - return NULL; - } - - fde = tevent_common_add_fd(ev, - mem_ctx, - fd, - flags, - handler, - private_data, - handler_name, - location); - if (fde == NULL) { - return NULL; - } - - ok = tevent_poll_event_add_fd_internal(ev, fde); - if (!ok) { - TALLOC_FREE(fde); - return NULL; - } - poll_event_wake_pollthread(poll_ev); - - /* - * poll_event_loop_poll will take care of the rest in - * poll_event_setup_fresh - */ - return fde; -} - -/* - set the fd event flags -*/ -static void poll_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags) -{ - struct tevent_context *ev = fde->event_ctx; - struct poll_event_context *poll_ev; - uint64_t idx = fde->additional_flags; - uint16_t pollflags; - - if (ev == NULL) { - return; - } - - if (fde->flags == flags) { - return; - } - - poll_ev = talloc_get_type_abort( - ev->additional_data, struct poll_event_context); - - fde->flags = flags; - - if (idx == UINT64_MAX) { - /* - * We move it between the fresh and disabled lists. - */ - tevent_poll_event_add_fd_internal(ev, fde); - poll_event_wake_pollthread(poll_ev); - return; - } - - if (fde->flags == 0) { - /* - * We need to remove it from the array - * and move it to the disabled list. - */ - poll_ev->fdes[idx] = NULL; - poll_ev->deleted = true; - fde->additional_flags = UINT64_MAX; - poll_event_wake_pollthread(poll_ev); - return; - } - - if (idx >= poll_ev->num_fds) { - /* - * Not yet added to the - * poll_ev->fds array. - */ - poll_event_wake_pollthread(poll_ev); - return; - } - - pollflags = 0; - - if (flags & TEVENT_FD_READ) { - pollflags |= (POLLIN|POLLHUP); - } - if (flags & TEVENT_FD_WRITE) { - pollflags |= (POLLOUT); - } - poll_ev->fds[idx].events = pollflags; - - poll_event_wake_pollthread(poll_ev); -} - -static bool poll_event_sync_arrays(struct tevent_context *ev, - struct poll_event_context *poll_ev) -{ - size_t i; - size_t array_length; - - if (poll_ev->deleted) { - - for (i=0; i < poll_ev->num_fds;) { - struct tevent_fd *fde = poll_ev->fdes[i]; - size_t ci; - - if (fde != NULL) { - i++; - continue; - } - - /* - * This fde was talloc_free()'ed. Delete it - * from the arrays - */ - poll_ev->num_fds -= 1; - ci = poll_ev->num_fds; - if (ci > i) { - poll_ev->fds[i] = poll_ev->fds[ci]; - poll_ev->fdes[i] = poll_ev->fdes[ci]; - if (poll_ev->fdes[i] != NULL) { - poll_ev->fdes[i]->additional_flags = i; - } - } - poll_ev->fds[ci] = (struct pollfd) { .fd = -1 }; - poll_ev->fdes[ci] = NULL; - } - poll_ev->deleted = false; - } - - if (poll_ev->num_fds == poll_ev->num_fdes) { - return true; - } - - /* - * Recheck the size of both arrays and make sure - * poll_fd->fds array has at least the size of the - * in use poll_ev->fdes array. - */ - if (poll_ev->num_fdes > talloc_array_length(poll_ev->fds)) { - struct pollfd *tmp_fds = NULL; - - /* - * Make sure both allocated the same length. - */ - array_length = talloc_array_length(poll_ev->fdes); - - tmp_fds = talloc_realloc(poll_ev, - poll_ev->fds, - struct pollfd, - array_length); - if (tmp_fds == NULL) { - return false; - } - poll_ev->fds = tmp_fds; - } - - /* - * Now setup the new elements. - */ - for (i = poll_ev->num_fds; i < poll_ev->num_fdes; i++) { - struct tevent_fd *fde = poll_ev->fdes[i]; - struct pollfd *pfd = &poll_ev->fds[poll_ev->num_fds]; - - if (fde == NULL) { - continue; - } - - if (i > poll_ev->num_fds) { - poll_ev->fdes[poll_ev->num_fds] = fde; - fde->additional_flags = poll_ev->num_fds; - poll_ev->fdes[i] = NULL; - } - - pfd->fd = fde->fd; - pfd->events = 0; - pfd->revents = 0; - - if (fde->flags & TEVENT_FD_READ) { - pfd->events |= (POLLIN|POLLHUP); - } - if (fde->flags & TEVENT_FD_WRITE) { - pfd->events |= (POLLOUT); - } - - poll_ev->num_fds += 1; - } - /* Both are in sync again */ - poll_ev->num_fdes = poll_ev->num_fds; - - /* - * Check if we should shrink the arrays - * But keep at least 16 elements. - */ - - array_length = (poll_ev->num_fds + 15) & ~15; /* round up to 16 */ - array_length = MAX(array_length, 16); - if (array_length < talloc_array_length(poll_ev->fdes)) { - struct tevent_fd **tmp_fdes = NULL; - struct pollfd *tmp_fds = NULL; - - tmp_fdes = talloc_realloc(poll_ev, - poll_ev->fdes, - struct tevent_fd *, - array_length); - if (tmp_fdes == NULL) { - return false; - } - poll_ev->fdes = tmp_fdes; - - tmp_fds = talloc_realloc(poll_ev, - poll_ev->fds, - struct pollfd, - array_length); - if (tmp_fds == NULL) { - return false; - } - poll_ev->fds = tmp_fds; - } - - return true; -} - -/* - event loop handling using poll() -*/ -static int poll_event_loop_poll(struct tevent_context *ev, - struct timeval *tvalp) -{ - struct poll_event_context *poll_ev = talloc_get_type_abort( - ev->additional_data, struct poll_event_context); - int pollrtn; - int timeout = -1; - int poll_errno; - struct tevent_fd *fde = NULL; - struct tevent_fd *next = NULL; - unsigned i; - bool ok; - - if (ev->signal_events && tevent_common_check_signal(ev)) { - return 0; - } - - if (tvalp != NULL) { - timeout = tvalp->tv_sec * 1000; - timeout += (tvalp->tv_usec + 999) / 1000; - } - - ok = poll_event_sync_arrays(ev, poll_ev); - if (!ok) { - return -1; - } - - tevent_trace_point_callback(poll_ev->ev, TEVENT_TRACE_BEFORE_WAIT); - pollrtn = poll(poll_ev->fds, poll_ev->num_fds, timeout); - poll_errno = errno; - tevent_trace_point_callback(poll_ev->ev, TEVENT_TRACE_AFTER_WAIT); - - if (pollrtn == -1 && poll_errno == EINTR && ev->signal_events) { - tevent_common_check_signal(ev); - return 0; - } - - if (pollrtn == 0 && tvalp) { - /* we don't care about a possible delay here */ - tevent_common_loop_timer_delay(ev); - return 0; - } - - if (pollrtn <= 0) { - /* - * No fd's ready - */ - return 0; - } - - /* at least one file descriptor is ready - check - which ones and call the handler, being careful to allow - the handler to remove itself when called */ - - for (fde = ev->fd_events; fde; fde = next) { - uint64_t idx = fde->additional_flags; - struct pollfd *pfd; - uint16_t flags = 0; - - next = fde->next; - - if (idx == UINT64_MAX) { - continue; - } - - pfd = &poll_ev->fds[idx]; - - if (pfd->revents & POLLNVAL) { - /* - * the socket is dead! this should never - * happen as the socket should have first been - * made readable and that should have removed - * the event, so this must be a bug. - * - * We ignore it here to match the epoll - * behavior. - */ - tevent_debug(ev, TEVENT_DEBUG_ERROR, - "POLLNVAL on fde[%p] fd[%d] - disabling\n", - fde, pfd->fd); - poll_ev->fdes[idx] = NULL; - poll_ev->deleted = true; - DLIST_REMOVE(ev->fd_events, fde); - fde->wrapper = NULL; - fde->event_ctx = NULL; - continue; - } - - if (pfd->revents & (POLLHUP|POLLERR)) { - /* If we only wait for TEVENT_FD_WRITE, we - should not tell the event handler about it, - and remove the writable flag, as we only - report errors when waiting for read events - to match the select behavior. */ - if (!(fde->flags & TEVENT_FD_READ)) { - TEVENT_FD_NOT_WRITEABLE(fde); - continue; - } - flags |= TEVENT_FD_READ; - } - if (pfd->revents & POLLIN) { - flags |= TEVENT_FD_READ; - } - if (pfd->revents & POLLOUT) { - flags |= TEVENT_FD_WRITE; - } - /* - * Note that fde->flags could be changed when using - * the poll_mt backend together with threads, - * that why we need to check pfd->revents and fde->flags - */ - flags &= fde->flags; - if (flags != 0) { - DLIST_DEMOTE(ev->fd_events, fde); - return tevent_common_invoke_fd_handler(fde, flags, NULL); - } - } - - for (i = 0; i < poll_ev->num_fds; i++) { - if (poll_ev->fds[i].revents & POLLNVAL) { - /* - * the socket is dead! this should never - * happen as the socket should have first been - * made readable and that should have removed - * the event, so this must be a bug or - * a race in the poll_mt usage. - */ - fde = poll_ev->fdes[i]; - tevent_debug(ev, TEVENT_DEBUG_WARNING, - "POLLNVAL on dangling fd[%d] fde[%p] - disabling\n", - poll_ev->fds[i].fd, fde); - poll_ev->fdes[i] = NULL; - poll_ev->deleted = true; - if (fde != NULL) { - DLIST_REMOVE(ev->fd_events, fde); - fde->wrapper = NULL; - fde->event_ctx = NULL; - } - } - } - - return 0; -} - -/* - do a single event loop using the events defined in ev -*/ -static int poll_event_loop_once(struct tevent_context *ev, - const char *location) -{ - struct timeval tval; - - if (ev->signal_events && - tevent_common_check_signal(ev)) { - return 0; - } - - if (ev->threaded_contexts != NULL) { - tevent_common_threaded_activate_immediate(ev); - } - - if (ev->immediate_events && - tevent_common_loop_immediate(ev)) { - return 0; - } - - tval = tevent_common_loop_timer_delay(ev); - if (tevent_timeval_is_zero(&tval)) { - return 0; - } - - return poll_event_loop_poll(ev, &tval); -} - -static const struct tevent_ops poll_event_ops = { - .context_init = poll_event_context_init, - .add_fd = poll_event_add_fd, - .set_fd_close_fn = tevent_common_fd_set_close_fn, - .get_fd_flags = tevent_common_fd_get_flags, - .set_fd_flags = poll_event_set_fd_flags, - .add_timer = tevent_common_add_timer_v2, - .schedule_immediate = tevent_common_schedule_immediate, - .add_signal = tevent_common_add_signal, - .loop_once = poll_event_loop_once, - .loop_wait = tevent_common_loop_wait, -}; - -_PRIVATE_ bool tevent_poll_init(void) -{ - return tevent_register_backend("poll", &poll_event_ops); -} - -static const struct tevent_ops poll_event_mt_ops = { - .context_init = poll_event_context_init_mt, - .add_fd = poll_event_add_fd, - .set_fd_close_fn = tevent_common_fd_set_close_fn, - .get_fd_flags = tevent_common_fd_get_flags, - .set_fd_flags = poll_event_set_fd_flags, - .add_timer = tevent_common_add_timer_v2, - .schedule_immediate = poll_event_schedule_immediate, - .add_signal = tevent_common_add_signal, - .loop_once = poll_event_loop_once, - .loop_wait = tevent_common_loop_wait, -}; - -_PRIVATE_ bool tevent_poll_mt_init(void) -{ - return tevent_register_backend("poll_mt", &poll_event_mt_ops); -} diff --git a/ldb-2.0.8/lib/tevent/tevent_port.c b/ldb-2.0.8/lib/tevent/tevent_port.c deleted file mode 100644 index e91d442..0000000 --- a/ldb-2.0.8/lib/tevent/tevent_port.c +++ /dev/null @@ -1,803 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Main select loop and event handling - Solaris port implementation. - Losely based on the Linux epoll backend. - - Copyright (C) Jeremy Allison 2013 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#include "system/filesys.h" -#include "system/select.h" -#include "tevent.h" -#include "tevent_internal.h" -#include "tevent_util.h" - -struct port_associate_vals { - struct port_associate_vals *prev, *next; - struct port_event_context *port_ev; - int events; - struct tevent_fd *fde; - bool associated_event; -}; - -struct port_event_context { - /* a pointer back to the generic event_context */ - struct tevent_context *ev; - - /* This is the handle from port_create */ - int port_fd; - - pid_t pid; - - /* List of associations. */ - struct port_associate_vals *po_vals; -}; - -#define PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION (1<<0) -#define PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1) -#define PORT_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2) -#define PORT_ADDITIONAL_FD_FLAG_HAS_MPX (1<<3) - -/* - Map from TEVENT_FD_* to POLLIN/POLLOUT -*/ -static int port_map_flags(uint16_t flags) -{ - int ret = 0; - if (flags & TEVENT_FD_READ) ret |= (POLLIN | POLLERR | POLLHUP); - if (flags & TEVENT_FD_WRITE) ret |= (POLLOUT | POLLERR | POLLHUP); - return ret; -} - -/* - Free the port fd -*/ -static int port_ctx_destructor(struct port_event_context *port_ev) -{ - close(port_ev->port_fd); - port_ev->port_fd = -1; - return 0; -} - -/* - Init the port fd -*/ -static int port_init_ctx(struct port_event_context *port_ev) -{ - port_ev->port_fd = port_create(); - if (port_ev->port_fd == -1) { - tevent_debug(port_ev->ev, TEVENT_DEBUG_FATAL, - "Failed to create port handle.\n"); - return -1; - } - - if (!ev_set_close_on_exec(port_ev->port_fd)) { - tevent_debug(port_ev->ev, TEVENT_DEBUG_WARNING, - "Failed to set close-on-exec, file descriptor may be leaked to children.\n"); - } - - port_ev->pid = getpid(); - talloc_set_destructor(port_ev, port_ctx_destructor); - - return 0; -} - -/* - Functions to manage the lower level cache of associated events on the port_fd. -*/ - -static int port_associate_vals_destructor(struct port_associate_vals *val) -{ - DLIST_REMOVE(val->port_ev->po_vals, val); - memset(val, '\0', sizeof(struct port_associate_vals)); - return 0; -} - -/* - * TODO: As the port_association is per-fde, it should be possible to store it - * directly in fde->additional_data, alongside any multiplexed-fde. That way the - * lookup on store and delete would be avoided, and associate_all_events() could - * walk the ev->fd_events list. - */ -static bool store_port_association(struct port_event_context *port_ev, - struct tevent_fd *fde, - int events) -{ - struct port_associate_vals *val; - - for (val = port_ev->po_vals; val; val = val->next) { - if (val->fde->fd == fde->fd) { - /* Association already attached to fd. */ - if (val->events != events) { - val->events = events; - val->associated_event = false; - } - return true; - } - } - - val = talloc_zero(port_ev, struct port_associate_vals); - if (val == NULL) { - return false; - } - - val->port_ev = port_ev; - val->fde = fde; - val->events = events; - val->associated_event = false; - - DLIST_ADD(port_ev->po_vals, val); - talloc_set_destructor(val, port_associate_vals_destructor); - - return true; -} - -static void delete_port_association(struct port_event_context *port_ev, - struct tevent_fd *fde) -{ - struct port_associate_vals *val; - - for (val = port_ev->po_vals; val; val = val->next) { - if (val->fde == fde) { - if (val->associated_event) { - (void)port_dissociate(port_ev->port_fd, - PORT_SOURCE_FD, - fde->fd); - } - talloc_free(val); - return; - } - } -} - -static int associate_all_events(struct port_event_context *port_ev) -{ - struct port_associate_vals *val; - - for (val = port_ev->po_vals; val; val = val->next) { - int ret; - if (val->associated_event) { - continue; - } - ret = port_associate(port_ev->port_fd, - PORT_SOURCE_FD, - (uintptr_t)val->fde->fd, - val->events, - (void *)val); - if (ret != 0) { - return -1; - } - val->associated_event = true; - } - return 0; -} - -static int port_update_event(struct port_event_context *port_ev, struct tevent_fd *fde); - -/* - Reopen the port handle when our pid changes. - */ -static int port_check_reopen(struct port_event_context *port_ev) -{ - struct tevent_fd *fde; - - if (port_ev->pid == getpid()) { - return 0; - } - - close(port_ev->port_fd); - port_ev->port_fd = port_create(); - if (port_ev->port_fd == -1) { - tevent_debug(port_ev->ev, TEVENT_DEBUG_FATAL, - "port_create() failed"); - return -1; - } - - if (!ev_set_close_on_exec(port_ev->port_fd)) { - tevent_debug(port_ev->ev, TEVENT_DEBUG_WARNING, - "Failed to set close-on-exec, file descriptor may be leaked to children.\n"); - } - - port_ev->pid = getpid(); - for (fde=port_ev->ev->fd_events;fde;fde=fde->next) { - fde->additional_flags &= PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; - if (port_update_event(port_ev, fde) != 0) { - return -1; - } - } - return 0; -} - -/* - * Solaris ports cannot add the same file descriptor twice, once - * with read, once with write which is allowed by the tevent backend. - * Multiplex the existing fde, flag it as such so we can search for the - * correct fde on event triggering. - */ - -static void port_setup_multiplex_fd(struct port_event_context *port_ev, - struct tevent_fd *add_fde, - struct tevent_fd *mpx_fde) -{ - /* - * Make each fde->additional_data pointers point at each other - * so we can look them up from each other. They are now paired. - */ - mpx_fde->additional_data = add_fde; - add_fde->additional_data = mpx_fde; - - /* Now flag both fde's as being multiplexed. */ - mpx_fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_HAS_MPX; - add_fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_HAS_MPX; - - /* We need to keep the GOT_ERROR flag. */ - if (mpx_fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_GOT_ERROR) { - add_fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_GOT_ERROR; - } -} - -/* - Add the port event to the given fd_event, - Or modify an existing event. -*/ - -static int port_add_event(struct port_event_context *port_ev, struct tevent_fd *fde) -{ - int flags = port_map_flags(fde->flags); - struct tevent_fd *mpx_fde = NULL; - - fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; - fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; - - if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { - /* - * This is already a multiplexed fde, we need to include both - * flags in the modified event. - */ - mpx_fde = talloc_get_type_abort(fde->additional_data, - struct tevent_fd); - - mpx_fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; - mpx_fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; - - flags |= port_map_flags(mpx_fde->flags); - } else { - /* - * Not (yet) a multiplexed event. See if there - * is already an event with the same fd. - */ - for (mpx_fde = port_ev->ev->fd_events; mpx_fde; mpx_fde = mpx_fde->next) { - if (mpx_fde->fd != fde->fd) { - continue; - } - if (mpx_fde == fde) { - continue; - } - /* Same fd. */ - break; - } - if (mpx_fde) { - if (mpx_fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { - /* Logic error. Can't have more then 2 multiplexed fde's. */ - tevent_debug(port_ev->ev, TEVENT_DEBUG_FATAL, - "multiplex fde for fd[%d] is already multiplexed\n", - mpx_fde->fd); - return -1; - } - flags |= port_map_flags(mpx_fde->flags); - } - } - - if (!store_port_association(port_ev, - fde, - flags)) { - tevent_debug(port_ev->ev, TEVENT_DEBUG_FATAL, - "store_port_association failed for fd[%d]\n", - fde->fd); - return -1; - } - - /* Note we have an association now. */ - fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; - /* Only if we want to read do we tell the event handler about errors. */ - if (fde->flags & TEVENT_FD_READ) { - fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; - } - if (mpx_fde == NULL) { - return 0; - } - /* Set up the multiplex pointer. Does no harm if already multiplexed. */ - port_setup_multiplex_fd(port_ev, - fde, - mpx_fde); - - mpx_fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; - /* Only if we want to read do we tell the event handler about errors. */ - if (mpx_fde->flags & TEVENT_FD_READ) { - mpx_fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; - } - - return 0; -} - -/* - Delete the port association for the given fd_event. -*/ - -static void port_del_event(struct port_event_context *port_ev, struct tevent_fd *fde) -{ - struct tevent_fd *mpx_fde = NULL; - - fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; - fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; - - if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { - /* - * This is a multiplexed fde, we need to remove - * both associations. - */ - mpx_fde = talloc_get_type_abort(fde->additional_data, - struct tevent_fd); - - mpx_fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; - mpx_fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; - mpx_fde->additional_data = NULL; - - fde->additional_data = NULL; - } - delete_port_association(port_ev, fde); -} - -/* - Add or remove the port event from the given fd_event -*/ -static int port_update_event(struct port_event_context *port_ev, struct tevent_fd *fde) -{ - bool got_error = (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_GOT_ERROR); - bool want_read = (fde->flags & TEVENT_FD_READ); - bool want_write = (fde->flags & TEVENT_FD_WRITE); - struct tevent_fd *mpx_fde = NULL; - - if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { - /* - * work out what the multiplexed fde wants. - */ - mpx_fde = talloc_get_type_abort(fde->additional_data, - struct tevent_fd); - if (mpx_fde->flags & TEVENT_FD_READ) { - want_read = true; - } - if (mpx_fde->flags & TEVENT_FD_WRITE) { - want_write = true; - } - } - - if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION) { - /* There's already an association. */ - if (want_read || (want_write && !got_error)) { - return port_add_event(port_ev, fde); - } - /* - * If we want to match the select behavior, we need to remove the port event - * when the caller isn't interested in events. - */ - port_del_event(port_ev, fde); - return 0; - } - - /* There's no port event attached to the fde. */ - if (want_read || (want_write && !got_error)) { - return port_add_event(port_ev, fde); - } - return 0; -} - -/* - Cope with port_get returning EPOLLHP|EPOLLERR on an association. - Return true if there's nothing else to do, false if this event - needs further handling. -*/ - -static bool port_handle_hup_or_err(struct port_event_context *port_ev, - struct tevent_fd *fde) -{ - if (fde == NULL) { - return true; - } - - fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_GOT_ERROR; - /* - * If we only wait for TEVENT_FD_WRITE, we should not tell the - * event handler about it, and remove the port association, - * as we only report error when waiting for read events, - * to match the select() behavior. - */ - if (!(fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR)) { - /* - * Do the same as the poll backend and - * remove the writable flag. - */ - fde->flags &= ~TEVENT_FD_WRITE; - return true; - } - /* This has TEVENT_FD_READ set, we're not finished. */ - return false; -} - -/* - Event loop handling using Solaris ports. -*/ -static int port_event_loop(struct port_event_context *port_ev, struct timeval *tvalp) -{ - int ret; -#define MAXEVENTS 1 - port_event_t events[MAXEVENTS]; - uint_t nget = 1; - uint_t max_events = MAXEVENTS; - uint_t i; - int port_errno; - struct timespec ts; - struct tevent_context *ev = port_ev->ev; - - if (tvalp) { - ts.tv_sec = tvalp->tv_sec; - ts.tv_nsec = tvalp->tv_usec * 1000; - } - - if (port_ev->ev->signal_events && - tevent_common_check_signal(ev)) { - return 0; - } - - /* - * Solaris triggers sending the event to the port - * at the time the port association is done. Postpone - * associating fd's until just before we get the events, - * otherwise we can deadlock. - */ - - if (associate_all_events(port_ev) != 0) { - return -1; - } - - tevent_trace_point_callback(ev, TEVENT_TRACE_BEFORE_WAIT); - ret = port_getn(port_ev->port_fd, events, max_events, &nget, &ts); - port_errno = errno; - tevent_trace_point_callback(ev, TEVENT_TRACE_AFTER_WAIT); - - if (ret == -1 && port_errno == EINTR) { - if (ev->signal_events) { - tevent_common_check_signal(ev); - } - /* - * If no signal handlers we got an unsolicited - * signal wakeup. This can happen with epoll - * too. Just return and ignore. - */ - return 0; - } - - if (ret == -1 && port_errno == ETIME) { - /* - * If errno is set to ETIME it is possible that we still got an event. - * In that case we need to go through the processing loop so that we - * reassociate the received event with the port or the association will - * be lost so check the value of nget is 0 before returning. - */ - if (nget == 0) { - /* we don't care about a possible delay here */ - tevent_common_loop_timer_delay(ev); - return 0; - } - /* - * Set the return value to 0 since we do not actually have an error and we - * do have events that need to be processed. This keeps us from getting - * caught in the generic error test. - */ - ret = 0; - } - - if (ret == -1) { - tevent_debug(ev, TEVENT_DEBUG_ERROR, - "port_get failed (%s)\n", - strerror(errno)); - return -1; - } - - for (i = 0; i < nget; i++) { - struct tevent_fd *mpx_fde = NULL; - struct tevent_fd *fde = NULL; - uint16_t flags = 0; - struct port_associate_vals *val = talloc_get_type(events[i].portev_user, - struct port_associate_vals); - if (val == NULL) { - tevent_debug(ev, TEVENT_DEBUG_ERROR, - "port_getn() gave bad data"); - return -1; - } - - /* Mark this event as needing to be re-associated. */ - val->associated_event = false; - - fde = val->fde; - - if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { - /* - * Save off the multiplexed event in case we need - * to use it to call the handler function. - */ - mpx_fde = talloc_get_type_abort(fde->additional_data, - struct tevent_fd); - } - - if (events[i].portev_events & (POLLHUP|POLLERR)) { - bool handled_fde = port_handle_hup_or_err(port_ev, fde); - bool handled_mpx = port_handle_hup_or_err(port_ev, mpx_fde); - - if (handled_fde && handled_mpx) { - return port_update_event(port_ev, fde); - } - - if (!handled_mpx) { - /* - * If the mpx event was the one that needs - * further handling, it's the TEVENT_FD_READ - * event so switch over and call that handler. - */ - fde = mpx_fde; - mpx_fde = NULL; - } - flags |= TEVENT_FD_READ; - } - - if (events[i].portev_events & POLLIN) { - flags |= TEVENT_FD_READ; - } - if (events[i].portev_events & POLLOUT) { - flags |= TEVENT_FD_WRITE; - } - - if (flags & TEVENT_FD_WRITE) { - if (fde->flags & TEVENT_FD_WRITE) { - mpx_fde = NULL; - } - if (mpx_fde && (mpx_fde->flags & TEVENT_FD_WRITE)) { - fde = mpx_fde; - mpx_fde = NULL; - } - - if (mpx_fde) { - /* Ensure we got the right fde. */ - if ((flags & fde->flags) == 0) { - fde = mpx_fde; - mpx_fde = NULL; - } - } - } - - /* - * Make sure we only pass the flags - * the handler is expecting. - */ - flags &= fde->flags; - if (flags) { - return tevent_common_invoke_fd_handler(fde, flags, NULL); - } - } - - return 0; -} - - -/* - create a port_event_context structure. -*/ -static int port_event_context_init(struct tevent_context *ev) -{ - int ret; - struct port_event_context *port_ev; - - /* - * We might be called during tevent_re_initialise() - * which means we need to free our old additional_data. - */ - TALLOC_FREE(ev->additional_data); - - port_ev = talloc_zero(ev, struct port_event_context); - if (!port_ev) { - return -1; - } - port_ev->ev = ev; - port_ev->port_fd = -1; - port_ev->pid = (pid_t)-1; - - ret = port_init_ctx(port_ev); - if (ret != 0) { - talloc_free(port_ev); - return ret; - } - - ev->additional_data = port_ev; - return 0; -} - -/* - destroy an fd_event -*/ -static int port_event_fd_destructor(struct tevent_fd *fde) -{ - struct tevent_context *ev = fde->event_ctx; - struct port_event_context *port_ev = NULL; - struct tevent_fd *mpx_fde = NULL; - int flags = (int)fde->flags; - - if (ev == NULL) { - return tevent_common_fd_destructor(fde); - } - - port_ev = talloc_get_type_abort(ev->additional_data, - struct port_event_context); - - DLIST_REMOVE(ev->fd_events, fde); - - if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { - mpx_fde = talloc_get_type_abort(fde->additional_data, - struct tevent_fd); - - fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_MPX; - mpx_fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_MPX; - - fde->additional_data = NULL; - mpx_fde->additional_data = NULL; - - fde->additional_flags &= PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; - } - - (void)port_check_reopen(port_ev); - - if (mpx_fde != NULL) { - (void)port_update_event(port_ev, mpx_fde); - } - - fde->flags = 0; - (void)port_update_event(port_ev, fde); - fde->flags = flags; - - return tevent_common_fd_destructor(fde); -} - -/* - add a fd based event - return NULL on failure (memory allocation error) -*/ -static struct tevent_fd *port_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx, - int fd, uint16_t flags, - tevent_fd_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ - struct port_event_context *port_ev = - talloc_get_type_abort(ev->additional_data, - struct port_event_context); - struct tevent_fd *fde; - - fde = tevent_common_add_fd(ev, mem_ctx, fd, flags, - handler, private_data, - handler_name, location); - if (!fde) { - return NULL; - } - - talloc_set_destructor(fde, port_event_fd_destructor); - - if (port_check_reopen(port_ev) != 0) { - TALLOC_FREE(fde); - return NULL; - } - - if (port_update_event(port_ev, fde) != 0) { - TALLOC_FREE(fde); - return NULL; - } - - return fde; -} - -/* - set the fd event flags -*/ -static void port_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags) -{ - struct tevent_context *ev; - struct port_event_context *port_ev; - - if (fde->flags == flags) { - return; - } - - ev = fde->event_ctx; - port_ev = talloc_get_type_abort(ev->additional_data, - struct port_event_context); - - fde->flags = flags; - - (void)port_check_reopen(port_ev); - (void)port_update_event(port_ev, fde); -} - -/* - do a single event loop using the events defined in ev -*/ -static int port_event_loop_once(struct tevent_context *ev, const char *location) -{ - struct port_event_context *port_ev = talloc_get_type(ev->additional_data, - struct port_event_context); - struct timeval tval; - - if (ev->signal_events && - tevent_common_check_signal(ev)) { - return 0; - } - - if (ev->threaded_contexts != NULL) { - tevent_common_threaded_activate_immediate(ev); - } - - if (ev->immediate_events && - tevent_common_loop_immediate(ev)) { - return 0; - } - - tval = tevent_common_loop_timer_delay(ev); - if (tevent_timeval_is_zero(&tval)) { - return 0; - } - - if (port_check_reopen(port_ev) != 0) { - errno = EINVAL; - return -1; - } - return port_event_loop(port_ev, &tval); -} - -static const struct tevent_ops port_event_ops = { - .context_init = port_event_context_init, - .add_fd = port_event_add_fd, - .set_fd_close_fn = tevent_common_fd_set_close_fn, - .get_fd_flags = tevent_common_fd_get_flags, - .set_fd_flags = port_event_set_fd_flags, - .add_timer = tevent_common_add_timer_v2, - .schedule_immediate = tevent_common_schedule_immediate, - .add_signal = tevent_common_add_signal, - .loop_once = port_event_loop_once, - .loop_wait = tevent_common_loop_wait, -}; - -_PRIVATE_ bool tevent_port_init(void) -{ - if (!tevent_register_backend("port", &port_event_ops)) { - return false; - } - tevent_set_default_backend("port"); - return true; -} diff --git a/ldb-2.0.8/lib/tevent/tevent_queue.c b/ldb-2.0.8/lib/tevent/tevent_queue.c deleted file mode 100644 index 9c3973b..0000000 --- a/ldb-2.0.8/lib/tevent/tevent_queue.c +++ /dev/null @@ -1,370 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Infrastructure for async requests - Copyright (C) Volker Lendecke 2008 - Copyright (C) Stefan Metzmacher 2009 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#include "tevent.h" -#include "tevent_internal.h" -#include "tevent_util.h" - -struct tevent_queue_entry { - struct tevent_queue_entry *prev, *next; - struct tevent_queue *queue; - - bool triggered; - - struct tevent_req *req; - struct tevent_context *ev; - - tevent_queue_trigger_fn_t trigger; - void *private_data; -}; - -struct tevent_queue { - const char *name; - const char *location; - - bool running; - struct tevent_immediate *immediate; - - size_t length; - struct tevent_queue_entry *list; -}; - -static void tevent_queue_immediate_trigger(struct tevent_context *ev, - struct tevent_immediate *im, - void *private_data); - -static int tevent_queue_entry_destructor(struct tevent_queue_entry *e) -{ - struct tevent_queue *q = e->queue; - - if (!q) { - return 0; - } - - DLIST_REMOVE(q->list, e); - q->length--; - - if (!q->running) { - return 0; - } - - if (!q->list) { - return 0; - } - - if (q->list->triggered) { - return 0; - } - - tevent_schedule_immediate(q->immediate, - q->list->ev, - tevent_queue_immediate_trigger, - q); - - return 0; -} - -static int tevent_queue_destructor(struct tevent_queue *q) -{ - q->running = false; - - while (q->list) { - struct tevent_queue_entry *e = q->list; - talloc_free(e); - } - - return 0; -} - -struct tevent_queue *_tevent_queue_create(TALLOC_CTX *mem_ctx, - const char *name, - const char *location) -{ - struct tevent_queue *queue; - - queue = talloc_zero(mem_ctx, struct tevent_queue); - if (!queue) { - return NULL; - } - - queue->name = talloc_strdup(queue, name); - if (!queue->name) { - talloc_free(queue); - return NULL; - } - queue->immediate = tevent_create_immediate(queue); - if (!queue->immediate) { - talloc_free(queue); - return NULL; - } - - queue->location = location; - - /* queue is running by default */ - queue->running = true; - - talloc_set_destructor(queue, tevent_queue_destructor); - return queue; -} - -static void tevent_queue_immediate_trigger(struct tevent_context *ev, - struct tevent_immediate *im, - void *private_data) -{ - struct tevent_queue *q = - talloc_get_type_abort(private_data, - struct tevent_queue); - - if (!q->running) { - return; - } - - if (!q->list) { - return; - } - - q->list->triggered = true; - q->list->trigger(q->list->req, q->list->private_data); -} - -static struct tevent_queue_entry *tevent_queue_add_internal( - struct tevent_queue *queue, - struct tevent_context *ev, - struct tevent_req *req, - tevent_queue_trigger_fn_t trigger, - void *private_data, - bool allow_direct) -{ - struct tevent_queue_entry *e; - - e = talloc_zero(req, struct tevent_queue_entry); - if (e == NULL) { - return NULL; - } - - e->queue = queue; - e->req = req; - e->ev = ev; - e->trigger = trigger; - e->private_data = private_data; - - /* - * if there is no trigger, it is just a blocker - */ - if (trigger == NULL) { - e->triggered = true; - } - - if (queue->length > 0) { - /* - * if there are already entries in the - * queue do not optimize. - */ - allow_direct = false; - } - - if (req->async.fn != NULL) { - /* - * If the caller wants to optimize for the - * empty queue case, call the trigger only - * if there is no callback defined for the - * request yet. - */ - allow_direct = false; - } - - DLIST_ADD_END(queue->list, e); - queue->length++; - talloc_set_destructor(e, tevent_queue_entry_destructor); - - if (!queue->running) { - return e; - } - - if (queue->list->triggered) { - return e; - } - - /* - * If allowed we directly call the trigger - * avoiding possible delays caused by - * an immediate event. - */ - if (allow_direct) { - queue->list->triggered = true; - queue->list->trigger(queue->list->req, - queue->list->private_data); - return e; - } - - tevent_schedule_immediate(queue->immediate, - queue->list->ev, - tevent_queue_immediate_trigger, - queue); - - return e; -} - -bool tevent_queue_add(struct tevent_queue *queue, - struct tevent_context *ev, - struct tevent_req *req, - tevent_queue_trigger_fn_t trigger, - void *private_data) -{ - struct tevent_queue_entry *e; - - e = tevent_queue_add_internal(queue, ev, req, - trigger, private_data, false); - if (e == NULL) { - return false; - } - - return true; -} - -struct tevent_queue_entry *tevent_queue_add_entry( - struct tevent_queue *queue, - struct tevent_context *ev, - struct tevent_req *req, - tevent_queue_trigger_fn_t trigger, - void *private_data) -{ - return tevent_queue_add_internal(queue, ev, req, - trigger, private_data, false); -} - -struct tevent_queue_entry *tevent_queue_add_optimize_empty( - struct tevent_queue *queue, - struct tevent_context *ev, - struct tevent_req *req, - tevent_queue_trigger_fn_t trigger, - void *private_data) -{ - return tevent_queue_add_internal(queue, ev, req, - trigger, private_data, true); -} - -void tevent_queue_entry_untrigger(struct tevent_queue_entry *entry) -{ - if (entry->queue->running) { - abort(); - } - - if (entry->queue->list != entry) { - abort(); - } - - entry->triggered = false; -} - -void tevent_queue_start(struct tevent_queue *queue) -{ - if (queue->running) { - /* already started */ - return; - } - - queue->running = true; - - if (!queue->list) { - return; - } - - if (queue->list->triggered) { - return; - } - - tevent_schedule_immediate(queue->immediate, - queue->list->ev, - tevent_queue_immediate_trigger, - queue); -} - -void tevent_queue_stop(struct tevent_queue *queue) -{ - queue->running = false; -} - -size_t tevent_queue_length(struct tevent_queue *queue) -{ - return queue->length; -} - -bool tevent_queue_running(struct tevent_queue *queue) -{ - return queue->running; -} - -struct tevent_queue_wait_state { - uint8_t dummy; -}; - -static void tevent_queue_wait_trigger(struct tevent_req *req, - void *private_data); - -struct tevent_req *tevent_queue_wait_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct tevent_queue *queue) -{ - struct tevent_req *req; - struct tevent_queue_wait_state *state; - bool ok; - - req = tevent_req_create(mem_ctx, &state, - struct tevent_queue_wait_state); - if (req == NULL) { - return NULL; - } - - ok = tevent_queue_add(queue, ev, req, - tevent_queue_wait_trigger, - NULL); - if (!ok) { - tevent_req_oom(req); - return tevent_req_post(req, ev); - } - - return req; -} - -static void tevent_queue_wait_trigger(struct tevent_req *req, - void *private_data) -{ - tevent_req_done(req); -} - -bool tevent_queue_wait_recv(struct tevent_req *req) -{ - enum tevent_req_state state; - uint64_t err; - - if (tevent_req_is_error(req, &state, &err)) { - tevent_req_received(req); - return false; - } - - tevent_req_received(req); - return true; -} diff --git a/ldb-2.0.8/lib/tevent/tevent_req.c b/ldb-2.0.8/lib/tevent/tevent_req.c deleted file mode 100644 index 7821d9a..0000000 --- a/ldb-2.0.8/lib/tevent/tevent_req.c +++ /dev/null @@ -1,570 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Infrastructure for async requests - Copyright (C) Volker Lendecke 2008 - Copyright (C) Stefan Metzmacher 2009 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#include "tevent.h" -#include "tevent_internal.h" -#include "tevent_util.h" - -char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx) -{ - return talloc_asprintf(mem_ctx, - "tevent_req[%p/%s]: state[%d] error[%lld (0x%llX)] " - " state[%s (%p)] timer[%p] finish[%s]", - req, req->internal.create_location, - req->internal.state, - (unsigned long long)req->internal.error, - (unsigned long long)req->internal.error, - req->internal.private_type, - req->data, - req->internal.timer, - req->internal.finish_location - ); -} - -char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req) -{ - if (req == NULL) { - return talloc_strdup(mem_ctx, "tevent_req[NULL]"); - } - - if (!req->private_print) { - return tevent_req_default_print(req, mem_ctx); - } - - return req->private_print(req, mem_ctx); -} - -static int tevent_req_destructor(struct tevent_req *req); - -struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, - void *pdata, - size_t data_size, - const char *type, - const char *location) -{ - struct tevent_req *req; - struct tevent_req *parent; - void **ppdata = (void **)pdata; - void *data; - size_t payload; - - payload = sizeof(struct tevent_immediate) + data_size; - if (payload < sizeof(struct tevent_immediate)) { - /* overflow */ - return NULL; - } - - req = talloc_pooled_object( - mem_ctx, struct tevent_req, 2, - sizeof(struct tevent_immediate) + data_size); - if (req == NULL) { - return NULL; - } - - *req = (struct tevent_req) { - .internal = { - .private_type = type, - .create_location = location, - .state = TEVENT_REQ_IN_PROGRESS, - .trigger = tevent_create_immediate(req), - }, - }; - - data = talloc_zero_size(req, data_size); - - /* - * No need to check for req->internal.trigger!=NULL or - * data!=NULL, this can't fail: talloc_pooled_object has - * already allocated sufficient memory. - */ - - talloc_set_name_const(data, type); - - req->data = data; - - talloc_set_destructor(req, tevent_req_destructor); - - parent = talloc_get_type(talloc_parent(mem_ctx), struct tevent_req); - if ((parent != NULL) && (parent->internal.profile != NULL)) { - bool ok = tevent_req_set_profile(req); - - if (!ok) { - TALLOC_FREE(req); - return NULL; - } - req->internal.profile->parent = parent->internal.profile; - DLIST_ADD_END(parent->internal.profile->subprofiles, - req->internal.profile); - } - - *ppdata = data; - return req; -} - -static int tevent_req_destructor(struct tevent_req *req) -{ - tevent_req_received(req); - return 0; -} - -void _tevent_req_notify_callback(struct tevent_req *req, const char *location) -{ - req->internal.finish_location = location; - if (req->internal.defer_callback_ev) { - (void)tevent_req_post(req, req->internal.defer_callback_ev); - req->internal.defer_callback_ev = NULL; - return; - } - if (req->async.fn != NULL) { - req->async.fn(req); - } -} - -static void tevent_req_cleanup(struct tevent_req *req) -{ - if (req->private_cleanup.fn == NULL) { - return; - } - - if (req->private_cleanup.state >= req->internal.state) { - /* - * Don't call the cleanup_function multiple times for the same - * state recursively - */ - return; - } - - req->private_cleanup.state = req->internal.state; - req->private_cleanup.fn(req, req->internal.state); -} - -static void tevent_req_finish(struct tevent_req *req, - enum tevent_req_state state, - const char *location) -{ - struct tevent_req_profile *p; - /* - * make sure we do not timeout after - * the request was already finished - */ - TALLOC_FREE(req->internal.timer); - - req->internal.state = state; - req->internal.finish_location = location; - - tevent_req_cleanup(req); - - p = req->internal.profile; - - if (p != NULL) { - p->stop_location = location; - p->stop_time = tevent_timeval_current(); - p->state = state; - p->user_error = req->internal.error; - - if (p->parent != NULL) { - talloc_steal(p->parent, p); - req->internal.profile = NULL; - } - } - - _tevent_req_notify_callback(req, location); -} - -void _tevent_req_done(struct tevent_req *req, - const char *location) -{ - tevent_req_finish(req, TEVENT_REQ_DONE, location); -} - -bool _tevent_req_error(struct tevent_req *req, - uint64_t error, - const char *location) -{ - if (error == 0) { - return false; - } - - req->internal.error = error; - tevent_req_finish(req, TEVENT_REQ_USER_ERROR, location); - return true; -} - -void _tevent_req_oom(struct tevent_req *req, const char *location) -{ - tevent_req_finish(req, TEVENT_REQ_NO_MEMORY, location); -} - -bool _tevent_req_nomem(const void *p, - struct tevent_req *req, - const char *location) -{ - if (p != NULL) { - return false; - } - _tevent_req_oom(req, location); - return true; -} - -/** - * @internal - * - * @brief Immediate event callback. - * - * @param[in] ev The event context to use. - * - * @param[in] im The immediate event. - * - * @param[in] priv The async request to be finished. - */ -static void tevent_req_trigger(struct tevent_context *ev, - struct tevent_immediate *im, - void *private_data) -{ - struct tevent_req *req = - talloc_get_type_abort(private_data, - struct tevent_req); - - tevent_req_finish(req, req->internal.state, - req->internal.finish_location); -} - -struct tevent_req *tevent_req_post(struct tevent_req *req, - struct tevent_context *ev) -{ - tevent_schedule_immediate(req->internal.trigger, - ev, tevent_req_trigger, req); - return req; -} - -void tevent_req_defer_callback(struct tevent_req *req, - struct tevent_context *ev) -{ - req->internal.defer_callback_ev = ev; -} - -bool tevent_req_is_in_progress(struct tevent_req *req) -{ - if (req->internal.state == TEVENT_REQ_IN_PROGRESS) { - return true; - } - - return false; -} - -void tevent_req_received(struct tevent_req *req) -{ - talloc_set_destructor(req, NULL); - - req->private_print = NULL; - req->private_cancel = NULL; - - TALLOC_FREE(req->internal.trigger); - TALLOC_FREE(req->internal.timer); - - req->internal.state = TEVENT_REQ_RECEIVED; - - tevent_req_cleanup(req); - - TALLOC_FREE(req->data); -} - -bool tevent_req_poll(struct tevent_req *req, - struct tevent_context *ev) -{ - while (tevent_req_is_in_progress(req)) { - int ret; - - ret = tevent_loop_once(ev); - if (ret != 0) { - return false; - } - } - - return true; -} - -bool tevent_req_is_error(struct tevent_req *req, enum tevent_req_state *state, - uint64_t *error) -{ - if (req->internal.state == TEVENT_REQ_DONE) { - return false; - } - if (req->internal.state == TEVENT_REQ_USER_ERROR) { - *error = req->internal.error; - } - *state = req->internal.state; - return true; -} - -static void tevent_req_timedout(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval now, - void *private_data) -{ - struct tevent_req *req = - talloc_get_type_abort(private_data, - struct tevent_req); - - TALLOC_FREE(req->internal.timer); - - tevent_req_finish(req, TEVENT_REQ_TIMED_OUT, __FUNCTION__); -} - -bool tevent_req_set_endtime(struct tevent_req *req, - struct tevent_context *ev, - struct timeval endtime) -{ - TALLOC_FREE(req->internal.timer); - - req->internal.timer = tevent_add_timer(ev, req, endtime, - tevent_req_timedout, - req); - if (tevent_req_nomem(req->internal.timer, req)) { - return false; - } - - return true; -} - -void tevent_req_reset_endtime(struct tevent_req *req) -{ - TALLOC_FREE(req->internal.timer); -} - -void tevent_req_set_callback(struct tevent_req *req, tevent_req_fn fn, void *pvt) -{ - req->async.fn = fn; - req->async.private_data = pvt; -} - -void *_tevent_req_callback_data(struct tevent_req *req) -{ - return req->async.private_data; -} - -void *_tevent_req_data(struct tevent_req *req) -{ - return req->data; -} - -void tevent_req_set_print_fn(struct tevent_req *req, tevent_req_print_fn fn) -{ - req->private_print = fn; -} - -void tevent_req_set_cancel_fn(struct tevent_req *req, tevent_req_cancel_fn fn) -{ - req->private_cancel = fn; -} - -bool _tevent_req_cancel(struct tevent_req *req, const char *location) -{ - if (req->private_cancel == NULL) { - return false; - } - - return req->private_cancel(req); -} - -void tevent_req_set_cleanup_fn(struct tevent_req *req, tevent_req_cleanup_fn fn) -{ - req->private_cleanup.state = req->internal.state; - req->private_cleanup.fn = fn; -} - -static int tevent_req_profile_destructor(struct tevent_req_profile *p); - -bool tevent_req_set_profile(struct tevent_req *req) -{ - struct tevent_req_profile *p; - - if (req->internal.profile != NULL) { - tevent_req_error(req, EINVAL); - return false; - } - - p = tevent_req_profile_create(req); - - if (tevent_req_nomem(p, req)) { - return false; - } - - p->req_name = talloc_get_name(req->data); - p->start_location = req->internal.create_location; - p->start_time = tevent_timeval_current(); - - req->internal.profile = p; - - return true; -} - -static int tevent_req_profile_destructor(struct tevent_req_profile *p) -{ - if (p->parent != NULL) { - DLIST_REMOVE(p->parent->subprofiles, p); - p->parent = NULL; - } - - while (p->subprofiles != NULL) { - p->subprofiles->parent = NULL; - DLIST_REMOVE(p->subprofiles, p->subprofiles); - } - - return 0; -} - -struct tevent_req_profile *tevent_req_move_profile(struct tevent_req *req, - TALLOC_CTX *mem_ctx) -{ - return talloc_move(mem_ctx, &req->internal.profile); -} - -const struct tevent_req_profile *tevent_req_get_profile( - struct tevent_req *req) -{ - return req->internal.profile; -} - -void tevent_req_profile_get_name(const struct tevent_req_profile *profile, - const char **req_name) -{ - if (req_name != NULL) { - *req_name = profile->req_name; - } -} - -void tevent_req_profile_get_start(const struct tevent_req_profile *profile, - const char **start_location, - struct timeval *start_time) -{ - if (start_location != NULL) { - *start_location = profile->start_location; - } - if (start_time != NULL) { - *start_time = profile->start_time; - } -} - -void tevent_req_profile_get_stop(const struct tevent_req_profile *profile, - const char **stop_location, - struct timeval *stop_time) -{ - if (stop_location != NULL) { - *stop_location = profile->stop_location; - } - if (stop_time != NULL) { - *stop_time = profile->stop_time; - } -} - -void tevent_req_profile_get_status(const struct tevent_req_profile *profile, - pid_t *pid, - enum tevent_req_state *state, - uint64_t *user_error) -{ - if (pid != NULL) { - *pid = profile->pid; - } - if (state != NULL) { - *state = profile->state; - } - if (user_error != NULL) { - *user_error = profile->user_error; - } -} - -const struct tevent_req_profile *tevent_req_profile_get_subprofiles( - const struct tevent_req_profile *profile) -{ - return profile->subprofiles; -} - -const struct tevent_req_profile *tevent_req_profile_next( - const struct tevent_req_profile *profile) -{ - return profile->next; -} - -struct tevent_req_profile *tevent_req_profile_create(TALLOC_CTX *mem_ctx) -{ - struct tevent_req_profile *result; - - result = talloc_zero(mem_ctx, struct tevent_req_profile); - if (result == NULL) { - return NULL; - } - talloc_set_destructor(result, tevent_req_profile_destructor); - - return result; -} - -bool tevent_req_profile_set_name(struct tevent_req_profile *profile, - const char *req_name) -{ - profile->req_name = talloc_strdup(profile, req_name); - return (profile->req_name != NULL); -} - -bool tevent_req_profile_set_start(struct tevent_req_profile *profile, - const char *start_location, - struct timeval start_time) -{ - profile->start_time = start_time; - - profile->start_location = talloc_strdup(profile, start_location); - return (profile->start_location != NULL); -} - -bool tevent_req_profile_set_stop(struct tevent_req_profile *profile, - const char *stop_location, - struct timeval stop_time) -{ - profile->stop_time = stop_time; - - profile->stop_location = talloc_strdup(profile, stop_location); - return (profile->stop_location != NULL); -} - -void tevent_req_profile_set_status(struct tevent_req_profile *profile, - pid_t pid, - enum tevent_req_state state, - uint64_t user_error) -{ - profile->pid = pid; - profile->state = state; - profile->user_error = user_error; -} - -void tevent_req_profile_append_sub(struct tevent_req_profile *parent_profile, - struct tevent_req_profile **sub_profile) -{ - struct tevent_req_profile *sub; - - sub = talloc_move(parent_profile, sub_profile); - - sub->parent = parent_profile; - DLIST_ADD_END(parent_profile->subprofiles, sub); -} diff --git a/ldb-2.0.8/lib/tevent/tevent_signal.c b/ldb-2.0.8/lib/tevent/tevent_signal.c deleted file mode 100644 index 7ebb13d..0000000 --- a/ldb-2.0.8/lib/tevent/tevent_signal.c +++ /dev/null @@ -1,518 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - common events code for signal events - - Copyright (C) Andrew Tridgell 2007 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#include "system/filesys.h" -#include "system/wait.h" -#define TEVENT_DEPRECATED 1 -#include "tevent.h" -#include "tevent_internal.h" -#include "tevent_util.h" - -/* maximum number of SA_SIGINFO signals to hold in the queue. - NB. This *MUST* be a power of 2, in order for the ring buffer - wrap to work correctly. Thanks to Petr Vandrovec - for this. */ - -#define TEVENT_SA_INFO_QUEUE_COUNT 256 - -size_t tevent_num_signals(void) -{ - return TEVENT_NUM_SIGNALS; -} - -size_t tevent_sa_info_queue_count(void) -{ - return TEVENT_SA_INFO_QUEUE_COUNT; -} - -struct tevent_sigcounter { - uint32_t count; - uint32_t seen; -}; - -#if defined(HAVE___SYNC_FETCH_AND_ADD) -#define TEVENT_SIG_INCREMENT(s) __sync_fetch_and_add(&((s).count), 1) -#elif defined(HAVE_ATOMIC_ADD_32) -#define TEVENT_SIG_INCREMENT(s) atomic_add_32(&((s).count), 1) -#else -#define TEVENT_SIG_INCREMENT(s) (s).count++ -#endif -#define TEVENT_SIG_SEEN(s, n) (s).seen += (n) -#define TEVENT_SIG_PENDING(s) ((s).seen != (s).count) - -struct tevent_common_signal_list { - struct tevent_common_signal_list *prev, *next; - struct tevent_signal *se; -}; - -/* - the poor design of signals means that this table must be static global -*/ -static struct tevent_sig_state { - struct tevent_common_signal_list *sig_handlers[TEVENT_NUM_SIGNALS+1]; - struct sigaction *oldact[TEVENT_NUM_SIGNALS+1]; - struct tevent_sigcounter signal_count[TEVENT_NUM_SIGNALS+1]; - struct tevent_sigcounter got_signal; -#ifdef SA_SIGINFO - /* with SA_SIGINFO we get quite a lot of info per signal */ - siginfo_t *sig_info[TEVENT_NUM_SIGNALS+1]; - struct tevent_sigcounter sig_blocked[TEVENT_NUM_SIGNALS+1]; -#endif -} *sig_state; - -/* - return number of sigcounter events not processed yet -*/ -static uint32_t tevent_sig_count(struct tevent_sigcounter s) -{ - return s.count - s.seen; -} - -/* - signal handler - redirects to registered signals -*/ -static void tevent_common_signal_handler(int signum) -{ - struct tevent_common_signal_list *sl; - struct tevent_context *ev = NULL; - int saved_errno = errno; - - TEVENT_SIG_INCREMENT(sig_state->signal_count[signum]); - TEVENT_SIG_INCREMENT(sig_state->got_signal); - - /* Write to each unique event context. */ - for (sl = sig_state->sig_handlers[signum]; sl; sl = sl->next) { - if (sl->se->event_ctx && sl->se->event_ctx != ev) { - ev = sl->se->event_ctx; - tevent_common_wakeup(ev); - } - } - - errno = saved_errno; -} - -#ifdef SA_SIGINFO -/* - signal handler with SA_SIGINFO - redirects to registered signals -*/ -static void tevent_common_signal_handler_info(int signum, siginfo_t *info, - void *uctx) -{ - uint32_t count = tevent_sig_count(sig_state->signal_count[signum]); - /* sig_state->signal_count[signum].seen % TEVENT_SA_INFO_QUEUE_COUNT - * is the base of the unprocessed signals in the ringbuffer. */ - uint32_t ofs = (sig_state->signal_count[signum].seen + count) % - TEVENT_SA_INFO_QUEUE_COUNT; - sig_state->sig_info[signum][ofs] = *info; - - tevent_common_signal_handler(signum); - - /* handle SA_SIGINFO */ - if (count+1 == TEVENT_SA_INFO_QUEUE_COUNT) { - /* we've filled the info array - block this signal until - these ones are delivered */ -#ifdef HAVE_UCONTEXT_T - /* - * This is the only way for this to work. - * By default signum is blocked inside this - * signal handler using a temporary mask, - * but what we really need to do now is - * block it in the callers mask, so it - * stays blocked when the temporary signal - * handler mask is replaced when we return - * from here. The callers mask can be found - * in the ucontext_t passed in as the - * void *uctx argument. - */ - ucontext_t *ucp = (ucontext_t *)uctx; - sigaddset(&ucp->uc_sigmask, signum); -#else - /* - * WARNING !!! WARNING !!!! - * - * This code doesn't work. - * By default signum is blocked inside this - * signal handler, but calling sigprocmask - * modifies the temporary signal mask being - * used *inside* this handler, which will be - * replaced by the callers signal mask once - * we return from here. See Samba - * bug #9550 for details. - */ - sigset_t set; - sigemptyset(&set); - sigaddset(&set, signum); - sigprocmask(SIG_BLOCK, &set, NULL); -#endif - TEVENT_SIG_INCREMENT(sig_state->sig_blocked[signum]); - } -} -#endif - -static int tevent_common_signal_list_destructor(struct tevent_common_signal_list *sl) -{ - if (sig_state->sig_handlers[sl->se->signum]) { - DLIST_REMOVE(sig_state->sig_handlers[sl->se->signum], sl); - } - return 0; -} - -/* - destroy a signal event -*/ -static int tevent_signal_destructor(struct tevent_signal *se) -{ - if (se->destroyed) { - tevent_common_check_double_free(se, "tevent_signal double free"); - goto done; - } - se->destroyed = true; - - TALLOC_FREE(se->additional_data); - - if (se->event_ctx != NULL) { - DLIST_REMOVE(se->event_ctx->signal_events, se); - } - - if (sig_state->sig_handlers[se->signum] == NULL) { - /* restore old handler, if any */ - if (sig_state->oldact[se->signum]) { - sigaction(se->signum, sig_state->oldact[se->signum], NULL); - TALLOC_FREE(sig_state->oldact[se->signum]); - } -#ifdef SA_SIGINFO - if (se->sa_flags & SA_SIGINFO) { - if (sig_state->sig_info[se->signum]) { - TALLOC_FREE(sig_state->sig_info[se->signum]); - } - } -#endif - } - - se->event_ctx = NULL; -done: - if (se->busy) { - return -1; - } - se->wrapper = NULL; - - return 0; -} - -/* - add a signal event - return NULL on failure (memory allocation error) -*/ -struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - int signum, - int sa_flags, - tevent_signal_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ - struct tevent_signal *se; - struct tevent_common_signal_list *sl; - sigset_t set, oldset; - int ret; - - ret = tevent_common_wakeup_init(ev); - if (ret != 0) { - errno = ret; - return NULL; - } - - if (signum >= TEVENT_NUM_SIGNALS) { - errno = EINVAL; - return NULL; - } - - /* the sig_state needs to be on a global context as it can last across - multiple event contexts */ - if (sig_state == NULL) { - sig_state = talloc_zero(NULL, struct tevent_sig_state); - if (sig_state == NULL) { - return NULL; - } - } - - se = talloc_zero(mem_ctx?mem_ctx:ev, struct tevent_signal); - if (se == NULL) return NULL; - - sl = talloc_zero(se, struct tevent_common_signal_list); - if (!sl) { - talloc_free(se); - return NULL; - } - sl->se = se; - - *se = (struct tevent_signal) { - .event_ctx = ev, - .signum = signum, - .sa_flags = sa_flags, - .handler = handler, - .private_data = private_data, - .handler_name = handler_name, - .location = location, - .additional_data= sl, - }; - - /* Ensure, no matter the destruction order, that we always have a handle on the global sig_state */ - if (!talloc_reference(se, sig_state)) { - talloc_free(se); - return NULL; - } - - /* only install a signal handler if not already installed */ - if (sig_state->sig_handlers[signum] == NULL) { - struct sigaction act; - ZERO_STRUCT(act); - act.sa_handler = tevent_common_signal_handler; - act.sa_flags = sa_flags; -#ifdef SA_SIGINFO - if (sa_flags & SA_SIGINFO) { - act.sa_handler = NULL; - act.sa_sigaction = tevent_common_signal_handler_info; - if (sig_state->sig_info[signum] == NULL) { - sig_state->sig_info[signum] = - talloc_zero_array(sig_state, siginfo_t, - TEVENT_SA_INFO_QUEUE_COUNT); - if (sig_state->sig_info[signum] == NULL) { - talloc_free(se); - return NULL; - } - } - } -#endif - sig_state->oldact[signum] = talloc_zero(sig_state, struct sigaction); - if (sig_state->oldact[signum] == NULL) { - talloc_free(se); - return NULL; - } - if (sigaction(signum, &act, sig_state->oldact[signum]) == -1) { - talloc_free(sig_state->oldact[signum]); - sig_state->oldact[signum] = NULL; - talloc_free(se); - return NULL; - } - } - - DLIST_ADD(se->event_ctx->signal_events, se); - - /* Make sure the signal doesn't come in while we're mangling list. */ - sigemptyset(&set); - sigaddset(&set, signum); - sigprocmask(SIG_BLOCK, &set, &oldset); - DLIST_ADD(sig_state->sig_handlers[signum], sl); - sigprocmask(SIG_SETMASK, &oldset, NULL); - - talloc_set_destructor(se, tevent_signal_destructor); - talloc_set_destructor(sl, tevent_common_signal_list_destructor); - - return se; -} - -int tevent_common_invoke_signal_handler(struct tevent_signal *se, - int signum, int count, void *siginfo, - bool *removed) -{ - struct tevent_context *handler_ev = se->event_ctx; - bool remove = false; - - if (removed != NULL) { - *removed = false; - } - - if (se->event_ctx == NULL) { - return 0; - } - - se->busy = true; - if (se->wrapper != NULL) { - handler_ev = se->wrapper->wrap_ev; - - tevent_wrapper_push_use_internal(handler_ev, se->wrapper); - se->wrapper->ops->before_signal_handler( - se->wrapper->wrap_ev, - se->wrapper->private_state, - se->wrapper->main_ev, - se, - signum, - count, - siginfo, - se->handler_name, - se->location); - } - se->handler(handler_ev, se, signum, count, siginfo, se->private_data); - if (se->wrapper != NULL) { - se->wrapper->ops->after_signal_handler( - se->wrapper->wrap_ev, - se->wrapper->private_state, - se->wrapper->main_ev, - se, - signum, - count, - siginfo, - se->handler_name, - se->location); - tevent_wrapper_pop_use_internal(handler_ev, se->wrapper); - } - se->busy = false; - -#ifdef SA_RESETHAND - if (se->sa_flags & SA_RESETHAND) { - remove = true; - } -#endif - - if (se->destroyed) { - talloc_set_destructor(se, NULL); - remove = true; - } - - if (remove) { - TALLOC_FREE(se); - if (removed != NULL) { - *removed = true; - } - } - - return 0; -} - -/* - check if a signal is pending - return != 0 if a signal was pending -*/ -int tevent_common_check_signal(struct tevent_context *ev) -{ - int i; - - if (!sig_state || !TEVENT_SIG_PENDING(sig_state->got_signal)) { - return 0; - } - - for (i=0;isignal_count[i]; - uint32_t count = tevent_sig_count(counter); - int ret; -#ifdef SA_SIGINFO - /* Ensure we null out any stored siginfo_t entries - * after processing for debugging purposes. */ - bool clear_processed_siginfo = false; -#endif - - if (count == 0) { - continue; - } - for (sl=sig_state->sig_handlers[i];sl;sl=next) { - struct tevent_signal *se = sl->se; - - next = sl->next; - -#ifdef SA_SIGINFO - if (se->sa_flags & SA_SIGINFO) { - uint32_t j; - - clear_processed_siginfo = true; - - for (j=0;jsignal_count[i].seen - * % TEVENT_SA_INFO_QUEUE_COUNT is - * the base position of the unprocessed - * signals in the ringbuffer. */ - uint32_t ofs = (counter.seen + j) - % TEVENT_SA_INFO_QUEUE_COUNT; - bool removed = false; - - ret = tevent_common_invoke_signal_handler( - se, i, 1, - (void*)&sig_state->sig_info[i][ofs], - &removed); - if (ret != 0) { - tevent_abort(ev, "tevent_common_invoke_signal_handler() failed"); - } - if (removed) { - break; - } - } - continue; - } -#endif - - ret = tevent_common_invoke_signal_handler(se, i, count, - NULL, NULL); - if (ret != 0) { - tevent_abort(ev, "tevent_common_invoke_signal_handler() failed"); - } - } - -#ifdef SA_SIGINFO - if (clear_processed_siginfo && sig_state->sig_info[i] != NULL) { - uint32_t j; - for (j=0;jsig_info[i][ofs], - '\0', - sizeof(siginfo_t)); - } - } -#endif - - TEVENT_SIG_SEEN(sig_state->signal_count[i], count); - TEVENT_SIG_SEEN(sig_state->got_signal, count); - -#ifdef SA_SIGINFO - if (TEVENT_SIG_PENDING(sig_state->sig_blocked[i])) { - /* We'd filled the queue, unblock the - signal now the queue is empty again. - Note we MUST do this after the - TEVENT_SIG_SEEN(sig_state->signal_count[i], count) - call to prevent a new signal running - out of room in the sig_state->sig_info[i][] - ring buffer. */ - sigset_t set; - sigemptyset(&set); - sigaddset(&set, i); - TEVENT_SIG_SEEN(sig_state->sig_blocked[i], - tevent_sig_count(sig_state->sig_blocked[i])); - sigprocmask(SIG_UNBLOCK, &set, NULL); - } -#endif - } - - return 1; -} - -void tevent_cleanup_pending_signal_handlers(struct tevent_signal *se) -{ - tevent_signal_destructor(se); - talloc_set_destructor(se, NULL); - return; -} diff --git a/ldb-2.0.8/lib/tevent/tevent_standard.c b/ldb-2.0.8/lib/tevent/tevent_standard.c deleted file mode 100644 index 3872020..0000000 --- a/ldb-2.0.8/lib/tevent/tevent_standard.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - Unix SMB/CIFS implementation. - main select loop and event handling - Copyright (C) Stefan Metzmacher 2013 - Copyright (C) Jeremy Allison 2013 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - This is SAMBA's default event loop code - - - we try to use epoll if configure detected support for it - otherwise we use poll() - - if epoll is broken on the system or the kernel doesn't support it - at runtime we fallback to poll() -*/ - -#include "replace.h" -#include "tevent.h" -#include "tevent_util.h" -#include "tevent_internal.h" - -struct std_event_glue { - const struct tevent_ops *epoll_ops; - const struct tevent_ops *poll_ops; - struct tevent_ops *glue_ops; - bool fallback_replay; -}; - -static int std_event_context_init(struct tevent_context *ev); - -static const struct tevent_ops std_event_ops = { - .context_init = std_event_context_init, -}; - -/* - If this function gets called. epoll failed at runtime. - Move us to using poll instead. If we return false here, - caller should abort(). -*/ -#ifdef HAVE_EPOLL -static bool std_fallback_to_poll(struct tevent_context *ev, bool replay) -{ - void *glue_ptr = talloc_parent(ev->ops); - struct std_event_glue *glue = - talloc_get_type_abort(glue_ptr, - struct std_event_glue); - int ret; - struct tevent_fd *fde; - - glue->fallback_replay = replay; - - /* First switch all the ops to poll. */ - glue->epoll_ops = NULL; - - /* - * Set custom_ops the same as poll. - */ - *glue->glue_ops = *glue->poll_ops; - glue->glue_ops->context_init = std_event_context_init; - - /* Next initialize the poll backend. */ - ret = glue->poll_ops->context_init(ev); - if (ret != 0) { - return false; - } - - /* - * Now we have to change all the existing file descriptor - * events from the epoll backend to the poll backend. - */ - for (fde = ev->fd_events; fde; fde = fde->next) { - bool ok; - - /* Re-add this event as a poll backend event. */ - ok = tevent_poll_event_add_fd_internal(ev, fde); - if (!ok) { - return false; - } - } - - return true; -} -#endif - -static int std_event_loop_once(struct tevent_context *ev, const char *location) -{ - void *glue_ptr = talloc_parent(ev->ops); - struct std_event_glue *glue = - talloc_get_type_abort(glue_ptr, - struct std_event_glue); - int ret; - - ret = glue->epoll_ops->loop_once(ev, location); - /* - * If the above hasn't panicked due to an epoll interface failure, - * std_fallback_to_poll() wasn't called, and hasn't cleared epoll_ops to - * signify fallback to poll_ops. - */ - if (glue->epoll_ops != NULL) { - /* No fallback */ - return ret; - } - - if (!glue->fallback_replay) { - /* - * The problem happened while modifying an event. - * An event handler was triggered in this case - * and there is no need to call loop_once() again. - */ - return ret; - } - - return glue->poll_ops->loop_once(ev, location); -} - -static int std_event_loop_wait(struct tevent_context *ev, const char *location) -{ - void *glue_ptr = talloc_parent(ev->ops); - struct std_event_glue *glue = - talloc_get_type_abort(glue_ptr, - struct std_event_glue); - int ret; - - ret = glue->epoll_ops->loop_wait(ev, location); - /* - * If the above hasn't panicked due to an epoll interface failure, - * std_fallback_to_poll() wasn't called, and hasn't cleared epoll_ops to - * signify fallback to poll_ops. - */ - if (glue->epoll_ops != NULL) { - /* No fallback */ - return ret; - } - - return glue->poll_ops->loop_wait(ev, location); -} -/* - Initialize the epoll backend and allow it to call a - switch function if epoll fails at runtime. -*/ -static int std_event_context_init(struct tevent_context *ev) -{ - struct std_event_glue *glue; - int ret; - - /* - * If this is the first initialization - * we need to set up the allocated ops - * pointers. - */ - - if (ev->ops == &std_event_ops) { - glue = talloc_zero(ev, struct std_event_glue); - if (glue == NULL) { - return -1; - } - - glue->epoll_ops = tevent_find_ops_byname("epoll"); - - glue->poll_ops = tevent_find_ops_byname("poll"); - if (glue->poll_ops == NULL) { - return -1; - } - - /* - * Allocate space for our custom ops. - * Allocate as a child of our epoll_ops pointer - * so we can easily get to it using talloc_parent. - */ - glue->glue_ops = talloc_zero(glue, struct tevent_ops); - if (glue->glue_ops == NULL) { - talloc_free(glue); - return -1; - } - - ev->ops = glue->glue_ops; - } else { - void *glue_ptr = talloc_parent(ev->ops); - glue = talloc_get_type_abort(glue_ptr, struct std_event_glue); - } - - if (glue->epoll_ops != NULL) { - /* - * Set custom_ops the same as epoll, - * except re-init using std_event_context_init() - * and use std_event_loop_once() to add the - * ability to fallback to a poll backend on - * epoll runtime error. - */ - *glue->glue_ops = *glue->epoll_ops; - glue->glue_ops->context_init = std_event_context_init; - glue->glue_ops->loop_once = std_event_loop_once; - glue->glue_ops->loop_wait = std_event_loop_wait; - - ret = glue->epoll_ops->context_init(ev); - if (ret == -1) { - goto fallback; - } -#ifdef HAVE_EPOLL - tevent_epoll_set_panic_fallback(ev, std_fallback_to_poll); -#endif - - return ret; - } - -fallback: - glue->epoll_ops = NULL; - - /* - * Set custom_ops the same as poll. - */ - *glue->glue_ops = *glue->poll_ops; - glue->glue_ops->context_init = std_event_context_init; - - return glue->poll_ops->context_init(ev); -} - -_PRIVATE_ bool tevent_standard_init(void) -{ - return tevent_register_backend("standard", &std_event_ops); -} diff --git a/ldb-2.0.8/lib/tevent/tevent_threads.c b/ldb-2.0.8/lib/tevent/tevent_threads.c deleted file mode 100644 index a89990f..0000000 --- a/ldb-2.0.8/lib/tevent/tevent_threads.c +++ /dev/null @@ -1,601 +0,0 @@ -/* - tevent event library. - - Copyright (C) Jeremy Allison 2015 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#include "system/filesys.h" -#include "talloc.h" -#include "tevent.h" -#include "tevent_internal.h" -#include "tevent_util.h" - -#ifdef HAVE_PTHREAD -#include "system/threads.h" - -struct tevent_immediate_list { - struct tevent_immediate_list *next, *prev; - tevent_immediate_handler_t handler; - struct tevent_immediate *im; - void *private_ptr; -}; - -struct tevent_thread_proxy { - pthread_mutex_t mutex; - struct tevent_context *dest_ev_ctx; - int read_fd; - int write_fd; - struct tevent_fd *pipe_read_fde; - /* Pending events list. */ - struct tevent_immediate_list *im_list; - /* Completed events list. */ - struct tevent_immediate_list *tofree_im_list; - struct tevent_immediate *free_im; -}; - -static void free_im_list(struct tevent_immediate_list **pp_list_head) -{ - struct tevent_immediate_list *im_entry = NULL; - struct tevent_immediate_list *im_next = NULL; - - for (im_entry = *pp_list_head; im_entry; im_entry = im_next) { - im_next = im_entry->next; - DLIST_REMOVE(*pp_list_head, im_entry); - TALLOC_FREE(im_entry); - } -} - -static void free_list_handler(struct tevent_context *ev, - struct tevent_immediate *im, - void *private_ptr) -{ - struct tevent_thread_proxy *tp = - talloc_get_type_abort(private_ptr, struct tevent_thread_proxy); - int ret; - - ret = pthread_mutex_lock(&tp->mutex); - if (ret != 0) { - abort(); - /* Notreached. */ - return; - } - - free_im_list(&tp->tofree_im_list); - - ret = pthread_mutex_unlock(&tp->mutex); - if (ret != 0) { - abort(); - /* Notreached. */ - return; - } -} - -static void schedule_immediate_functions(struct tevent_thread_proxy *tp) -{ - struct tevent_immediate_list *im_entry = NULL; - struct tevent_immediate_list *im_next = NULL; - - for (im_entry = tp->im_list; im_entry; im_entry = im_next) { - im_next = im_entry->next; - DLIST_REMOVE(tp->im_list, im_entry); - - tevent_schedule_immediate(im_entry->im, - tp->dest_ev_ctx, - im_entry->handler, - im_entry->private_ptr); - - /* Move from pending list to free list. */ - DLIST_ADD(tp->tofree_im_list, im_entry); - } - if (tp->tofree_im_list != NULL) { - /* - * Once the current immediate events - * are processed, we need to reschedule - * ourselves to free them. This works - * as tevent_schedule_immediate() - * always adds events to the *END* of - * the immediate events list. - */ - tevent_schedule_immediate(tp->free_im, - tp->dest_ev_ctx, - free_list_handler, - tp); - } -} - -static void pipe_read_handler(struct tevent_context *ev, - struct tevent_fd *fde, - uint16_t flags, - void *private_ptr) -{ - struct tevent_thread_proxy *tp = - talloc_get_type_abort(private_ptr, struct tevent_thread_proxy); - ssize_t len = 64; - int ret; - - ret = pthread_mutex_lock(&tp->mutex); - if (ret != 0) { - abort(); - /* Notreached. */ - return; - } - - /* - * Clear out all data in the pipe. We - * don't really care if this returns -1. - */ - while (len == 64) { - char buf[64]; - len = read(tp->read_fd, buf, 64); - }; - - schedule_immediate_functions(tp); - - ret = pthread_mutex_unlock(&tp->mutex); - if (ret != 0) { - abort(); - /* Notreached. */ - return; - } -} - -static int tevent_thread_proxy_destructor(struct tevent_thread_proxy *tp) -{ - int ret; - - ret = pthread_mutex_lock(&tp->mutex); - if (ret != 0) { - abort(); - /* Notreached. */ - return 0; - } - - TALLOC_FREE(tp->pipe_read_fde); - - if (tp->read_fd != -1) { - (void)close(tp->read_fd); - tp->read_fd = -1; - } - if (tp->write_fd != -1) { - (void)close(tp->write_fd); - tp->write_fd = -1; - } - - /* Hmmm. It's probably an error if we get here with - any non-NULL immediate entries.. */ - - free_im_list(&tp->im_list); - free_im_list(&tp->tofree_im_list); - - TALLOC_FREE(tp->free_im); - - ret = pthread_mutex_unlock(&tp->mutex); - if (ret != 0) { - abort(); - /* Notreached. */ - return 0; - } - - ret = pthread_mutex_destroy(&tp->mutex); - if (ret != 0) { - abort(); - /* Notreached. */ - return 0; - } - - return 0; -} - -/* - * Create a struct that can be passed to other threads - * to allow them to signal the struct tevent_context * - * passed in. - */ - -struct tevent_thread_proxy *tevent_thread_proxy_create( - struct tevent_context *dest_ev_ctx) -{ - int ret; - int pipefds[2]; - struct tevent_thread_proxy *tp; - - if (dest_ev_ctx->wrapper.glue != NULL) { - /* - * stacking of wrappers is not supported - */ - tevent_debug(dest_ev_ctx->wrapper.glue->main_ev, - TEVENT_DEBUG_FATAL, - "%s() not allowed on a wrapper context\n", - __func__); - errno = EINVAL; - return NULL; - } - - tp = talloc_zero(dest_ev_ctx, struct tevent_thread_proxy); - if (tp == NULL) { - return NULL; - } - - ret = pthread_mutex_init(&tp->mutex, NULL); - if (ret != 0) { - goto fail; - } - - tp->dest_ev_ctx = dest_ev_ctx; - tp->read_fd = -1; - tp->write_fd = -1; - - talloc_set_destructor(tp, tevent_thread_proxy_destructor); - - ret = pipe(pipefds); - if (ret == -1) { - goto fail; - } - - tp->read_fd = pipefds[0]; - tp->write_fd = pipefds[1]; - - ret = ev_set_blocking(pipefds[0], false); - if (ret != 0) { - goto fail; - } - ret = ev_set_blocking(pipefds[1], false); - if (ret != 0) { - goto fail; - } - if (!ev_set_close_on_exec(pipefds[0])) { - goto fail; - } - if (!ev_set_close_on_exec(pipefds[1])) { - goto fail; - } - - tp->pipe_read_fde = tevent_add_fd(dest_ev_ctx, - tp, - tp->read_fd, - TEVENT_FD_READ, - pipe_read_handler, - tp); - if (tp->pipe_read_fde == NULL) { - goto fail; - } - - /* - * Create an immediate event to free - * completed lists. - */ - tp->free_im = tevent_create_immediate(tp); - if (tp->free_im == NULL) { - goto fail; - } - - return tp; - - fail: - - TALLOC_FREE(tp); - return NULL; -} - -/* - * This function schedules an immediate event to be called with argument - * *pp_private in the thread context of dest_ev_ctx. Caller doesn't - * wait for activation to take place, this is simply fire-and-forget. - * - * pp_im must be a pointer to an immediate event talloced on - * a context owned by the calling thread, or the NULL context. - * Ownership of *pp_im will be transfered to the tevent library. - * - * pp_private can be null, or contents of *pp_private must be - * talloc'ed memory on a context owned by the calling thread - * or the NULL context. If non-null, ownership of *pp_private will - * be transfered to the tevent library. - * - * If you want to return a message, have the destination use the - * same function call to send back to the caller. - */ - - -void tevent_thread_proxy_schedule(struct tevent_thread_proxy *tp, - struct tevent_immediate **pp_im, - tevent_immediate_handler_t handler, - void *pp_private_data) -{ - struct tevent_immediate_list *im_entry; - int ret; - char c; - ssize_t written; - - ret = pthread_mutex_lock(&tp->mutex); - if (ret != 0) { - abort(); - /* Notreached. */ - return; - } - - if (tp->write_fd == -1) { - /* In the process of being destroyed. Ignore. */ - goto end; - } - - /* Create a new immediate_list entry. MUST BE ON THE NULL CONTEXT */ - im_entry = talloc_zero(NULL, struct tevent_immediate_list); - if (im_entry == NULL) { - goto end; - } - - im_entry->handler = handler; - im_entry->im = talloc_move(im_entry, pp_im); - - if (pp_private_data != NULL) { - void **pptr = (void **)pp_private_data; - im_entry->private_ptr = talloc_move(im_entry, pptr); - } - - DLIST_ADD(tp->im_list, im_entry); - - /* And notify the dest_ev_ctx to wake up. */ - c = '\0'; - do { - written = write(tp->write_fd, &c, 1); - } while (written == -1 && errno == EINTR); - - end: - - ret = pthread_mutex_unlock(&tp->mutex); - if (ret != 0) { - abort(); - /* Notreached. */ - } -} -#else -/* !HAVE_PTHREAD */ -struct tevent_thread_proxy *tevent_thread_proxy_create( - struct tevent_context *dest_ev_ctx) -{ - errno = ENOSYS; - return NULL; -} - -void tevent_thread_proxy_schedule(struct tevent_thread_proxy *tp, - struct tevent_immediate **pp_im, - tevent_immediate_handler_t handler, - void *pp_private_data) -{ - ; -} -#endif - -static int tevent_threaded_context_destructor( - struct tevent_threaded_context *tctx) -{ - struct tevent_context *main_ev = tevent_wrapper_main_ev(tctx->event_ctx); - int ret; - - if (main_ev != NULL) { - DLIST_REMOVE(main_ev->threaded_contexts, tctx); - } - - /* - * We have to coordinate with _tevent_threaded_schedule_immediate's - * unlock of the event_ctx_mutex. We're in the main thread here, - * and we can be scheduled before the helper thread finalizes its - * call _tevent_threaded_schedule_immediate. This means we would - * pthreadpool_destroy a locked mutex, which is illegal. - */ - ret = pthread_mutex_lock(&tctx->event_ctx_mutex); - if (ret != 0) { - abort(); - } - - ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); - if (ret != 0) { - abort(); - } - - ret = pthread_mutex_destroy(&tctx->event_ctx_mutex); - if (ret != 0) { - abort(); - } - - return 0; -} - -struct tevent_threaded_context *tevent_threaded_context_create( - TALLOC_CTX *mem_ctx, struct tevent_context *ev) -{ -#ifdef HAVE_PTHREAD - struct tevent_context *main_ev = tevent_wrapper_main_ev(ev); - struct tevent_threaded_context *tctx; - int ret; - - ret = tevent_common_wakeup_init(main_ev); - if (ret != 0) { - errno = ret; - return NULL; - } - - tctx = talloc(mem_ctx, struct tevent_threaded_context); - if (tctx == NULL) { - return NULL; - } - tctx->event_ctx = ev; - - ret = pthread_mutex_init(&tctx->event_ctx_mutex, NULL); - if (ret != 0) { - TALLOC_FREE(tctx); - return NULL; - } - - DLIST_ADD(main_ev->threaded_contexts, tctx); - talloc_set_destructor(tctx, tevent_threaded_context_destructor); - - return tctx; -#else - errno = ENOSYS; - return NULL; -#endif -} - -static int tevent_threaded_schedule_immediate_destructor(struct tevent_immediate *im) -{ - if (im->event_ctx != NULL) { - abort(); - } - return 0; -} - -void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx, - struct tevent_immediate *im, - tevent_immediate_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ -#ifdef HAVE_PTHREAD - const char *create_location = im->create_location; - struct tevent_context *main_ev = NULL; - struct tevent_wrapper_glue *glue = NULL; - int ret, wakeup_fd; - - ret = pthread_mutex_lock(&tctx->event_ctx_mutex); - if (ret != 0) { - abort(); - } - - if (tctx->event_ctx == NULL) { - /* - * Our event context is already gone. - */ - ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); - if (ret != 0) { - abort(); - } - return; - } - - glue = tctx->event_ctx->wrapper.glue; - - if ((im->event_ctx != NULL) || (handler == NULL)) { - abort(); - } - if (im->destroyed) { - abort(); - } - if (im->busy) { - abort(); - } - - main_ev = tevent_wrapper_main_ev(tctx->event_ctx); - - *im = (struct tevent_immediate) { - .event_ctx = tctx->event_ctx, - .wrapper = glue, - .handler = handler, - .private_data = private_data, - .handler_name = handler_name, - .create_location = create_location, - .schedule_location = location, - }; - - /* - * Make sure the event won't be destroyed while - * it's part of the ev->scheduled_immediates list. - * _tevent_schedule_immediate() will reset the destructor - * in tevent_common_threaded_activate_immediate(). - */ - talloc_set_destructor(im, tevent_threaded_schedule_immediate_destructor); - - ret = pthread_mutex_lock(&main_ev->scheduled_mutex); - if (ret != 0) { - abort(); - } - - DLIST_ADD_END(main_ev->scheduled_immediates, im); - wakeup_fd = main_ev->wakeup_fd; - - ret = pthread_mutex_unlock(&main_ev->scheduled_mutex); - if (ret != 0) { - abort(); - } - - ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); - if (ret != 0) { - abort(); - } - - /* - * We might want to wake up the main thread under the lock. We - * had a slightly similar situation in pthreadpool, changed - * with 1c4284c7395f23. This is not exactly the same, as the - * wakeup is only a last-resort thing in case the main thread - * is sleeping. Doing the wakeup under the lock can easily - * lead to a contended mutex, which is much more expensive - * than a noncontended one. So I'd opt for the lower footprint - * initially. Maybe we have to change that later. - */ - tevent_common_wakeup_fd(wakeup_fd); -#else - /* - * tevent_threaded_context_create() returned NULL with ENOSYS... - */ - abort(); -#endif -} - -void tevent_common_threaded_activate_immediate(struct tevent_context *ev) -{ -#ifdef HAVE_PTHREAD - int ret; - ret = pthread_mutex_lock(&ev->scheduled_mutex); - if (ret != 0) { - abort(); - } - - while (ev->scheduled_immediates != NULL) { - struct tevent_immediate *im = ev->scheduled_immediates; - struct tevent_immediate copy = *im; - - DLIST_REMOVE(ev->scheduled_immediates, im); - - tevent_debug(ev, TEVENT_DEBUG_TRACE, - "Schedule immediate event \"%s\": %p from thread into main\n", - im->handler_name, im); - im->handler_name = NULL; - _tevent_schedule_immediate(im, - ev, - copy.handler, - copy.private_data, - copy.handler_name, - copy.schedule_location); - } - - ret = pthread_mutex_unlock(&ev->scheduled_mutex); - if (ret != 0) { - abort(); - } -#else - /* - * tevent_threaded_context_create() returned NULL with ENOSYS... - */ - abort(); -#endif -} diff --git a/ldb-2.0.8/lib/tevent/tevent_timed.c b/ldb-2.0.8/lib/tevent/tevent_timed.c deleted file mode 100644 index a78d286..0000000 --- a/ldb-2.0.8/lib/tevent/tevent_timed.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - common events code for timed events - - Copyright (C) Andrew Tridgell 2003-2006 - Copyright (C) Stefan Metzmacher 2005-2009 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#include "system/time.h" -#define TEVENT_DEPRECATED 1 -#include "tevent.h" -#include "tevent_internal.h" -#include "tevent_util.h" - -/** - compare two timeval structures. - Return -1 if tv1 < tv2 - Return 0 if tv1 == tv2 - Return 1 if tv1 > tv2 -*/ -int tevent_timeval_compare(const struct timeval *tv1, const struct timeval *tv2) -{ - if (tv1->tv_sec > tv2->tv_sec) return 1; - if (tv1->tv_sec < tv2->tv_sec) return -1; - if (tv1->tv_usec > tv2->tv_usec) return 1; - if (tv1->tv_usec < tv2->tv_usec) return -1; - return 0; -} - -/** - return a zero timeval -*/ -struct timeval tevent_timeval_zero(void) -{ - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 0; - return tv; -} - -/** - return a timeval for the current time -*/ -struct timeval tevent_timeval_current(void) -{ - struct timeval tv; - gettimeofday(&tv, NULL); - return tv; -} - -/** - return a timeval struct with the given elements -*/ -struct timeval tevent_timeval_set(uint32_t secs, uint32_t usecs) -{ - struct timeval tv; - tv.tv_sec = secs; - tv.tv_usec = usecs; - return tv; -} - -/** - return the difference between two timevals as a timeval - if tv1 comes after tv2, then return a zero timeval - (this is *tv2 - *tv1) -*/ -struct timeval tevent_timeval_until(const struct timeval *tv1, - const struct timeval *tv2) -{ - struct timeval t; - if (tevent_timeval_compare(tv1, tv2) >= 0) { - return tevent_timeval_zero(); - } - t.tv_sec = tv2->tv_sec - tv1->tv_sec; - if (tv1->tv_usec > tv2->tv_usec) { - t.tv_sec--; - t.tv_usec = 1000000 - (tv1->tv_usec - tv2->tv_usec); - } else { - t.tv_usec = tv2->tv_usec - tv1->tv_usec; - } - return t; -} - -/** - return true if a timeval is zero -*/ -bool tevent_timeval_is_zero(const struct timeval *tv) -{ - return tv->tv_sec == 0 && tv->tv_usec == 0; -} - -struct timeval tevent_timeval_add(const struct timeval *tv, uint32_t secs, - uint32_t usecs) -{ - struct timeval tv2 = *tv; - tv2.tv_sec += secs; - tv2.tv_usec += usecs; - tv2.tv_sec += tv2.tv_usec / 1000000; - tv2.tv_usec = tv2.tv_usec % 1000000; - - return tv2; -} - -/** - return a timeval in the future with a specified offset -*/ -struct timeval tevent_timeval_current_ofs(uint32_t secs, uint32_t usecs) -{ - struct timeval tv = tevent_timeval_current(); - return tevent_timeval_add(&tv, secs, usecs); -} - -/* - destroy a timed event -*/ -static int tevent_common_timed_destructor(struct tevent_timer *te) -{ - if (te->destroyed) { - tevent_common_check_double_free(te, "tevent_timer double free"); - goto done; - } - te->destroyed = true; - - if (te->event_ctx == NULL) { - return 0; - } - - tevent_debug(te->event_ctx, TEVENT_DEBUG_TRACE, - "Destroying timer event %p \"%s\"\n", - te, te->handler_name); - - if (te->event_ctx->last_zero_timer == te) { - te->event_ctx->last_zero_timer = DLIST_PREV(te); - } - DLIST_REMOVE(te->event_ctx->timer_events, te); - - te->event_ctx = NULL; -done: - if (te->busy) { - return -1; - } - te->wrapper = NULL; - - return 0; -} - -static void tevent_common_insert_timer(struct tevent_context *ev, - struct tevent_timer *te, - bool optimize_zero) -{ - struct tevent_timer *prev_te = NULL; - - if (te->destroyed) { - tevent_abort(ev, "tevent_timer use after free"); - return; - } - - /* keep the list ordered */ - if (optimize_zero && tevent_timeval_is_zero(&te->next_event)) { - /* - * Some callers use zero tevent_timer - * instead of tevent_immediate events. - * - * As these can happen very often, - * we remember the last zero timer - * in the list. - */ - prev_te = ev->last_zero_timer; - ev->last_zero_timer = te; - } else { - struct tevent_timer *cur_te; - - /* - * we traverse the list from the tail - * because it's much more likely that - * timers are added at the end of the list - */ - for (cur_te = DLIST_TAIL(ev->timer_events); - cur_te != NULL; - cur_te = DLIST_PREV(cur_te)) - { - int ret; - - /* - * if the new event comes before the current - * we continue searching - */ - ret = tevent_timeval_compare(&te->next_event, - &cur_te->next_event); - if (ret < 0) { - continue; - } - - break; - } - - prev_te = cur_te; - } - - DLIST_ADD_AFTER(ev->timer_events, te, prev_te); -} - -/* - add a timed event - return NULL on failure (memory allocation error) -*/ -static struct tevent_timer *tevent_common_add_timer_internal( - struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - struct timeval next_event, - tevent_timer_handler_t handler, - void *private_data, - const char *handler_name, - const char *location, - bool optimize_zero) -{ - struct tevent_timer *te; - - te = talloc(mem_ctx?mem_ctx:ev, struct tevent_timer); - if (te == NULL) return NULL; - - *te = (struct tevent_timer) { - .event_ctx = ev, - .next_event = next_event, - .handler = handler, - .private_data = private_data, - .handler_name = handler_name, - .location = location, - }; - - if (ev->timer_events == NULL) { - ev->last_zero_timer = NULL; - } - - tevent_common_insert_timer(ev, te, optimize_zero); - - talloc_set_destructor(te, tevent_common_timed_destructor); - - tevent_debug(ev, TEVENT_DEBUG_TRACE, - "Added timed event \"%s\": %p\n", - handler_name, te); - return te; -} - -struct tevent_timer *tevent_common_add_timer(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - struct timeval next_event, - tevent_timer_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ - /* - * do not use optimization, there are broken Samba - * versions which use tevent_common_add_timer() - * without using tevent_common_loop_timer_delay(), - * it just uses DLIST_REMOVE(ev->timer_events, te) - * and would leave ev->last_zero_timer behind. - */ - return tevent_common_add_timer_internal(ev, mem_ctx, next_event, - handler, private_data, - handler_name, location, - false); -} - -struct tevent_timer *tevent_common_add_timer_v2(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - struct timeval next_event, - tevent_timer_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ - /* - * Here we turn on last_zero_timer optimization - */ - return tevent_common_add_timer_internal(ev, mem_ctx, next_event, - handler, private_data, - handler_name, location, - true); -} - -void tevent_update_timer(struct tevent_timer *te, struct timeval next_event) -{ - struct tevent_context *ev = te->event_ctx; - - if (ev->last_zero_timer == te) { - te->event_ctx->last_zero_timer = DLIST_PREV(te); - } - DLIST_REMOVE(ev->timer_events, te); - - te->next_event = next_event; - - /* - * Not doing the zero_timer optimization. This is for new code - * that should know about immediates. - */ - tevent_common_insert_timer(ev, te, false); -} - -int tevent_common_invoke_timer_handler(struct tevent_timer *te, - struct timeval current_time, - bool *removed) -{ - struct tevent_context *handler_ev = te->event_ctx; - - if (removed != NULL) { - *removed = false; - } - - if (te->event_ctx == NULL) { - return 0; - } - - /* - * We need to remove the timer from the list before calling the - * handler because in a semi-async inner event loop called from the - * handler we don't want to come across this event again -- vl - */ - if (te->event_ctx->last_zero_timer == te) { - te->event_ctx->last_zero_timer = DLIST_PREV(te); - } - DLIST_REMOVE(te->event_ctx->timer_events, te); - - tevent_debug(te->event_ctx, TEVENT_DEBUG_TRACE, - "Running timer event %p \"%s\"\n", - te, te->handler_name); - - /* - * If the timed event was registered for a zero current_time, - * then we pass a zero timeval here too! To avoid the - * overhead of gettimeofday() calls. - * - * otherwise we pass the current time - */ - te->busy = true; - if (te->wrapper != NULL) { - handler_ev = te->wrapper->wrap_ev; - - tevent_wrapper_push_use_internal(handler_ev, te->wrapper); - te->wrapper->ops->before_timer_handler( - te->wrapper->wrap_ev, - te->wrapper->private_state, - te->wrapper->main_ev, - te, - te->next_event, - current_time, - te->handler_name, - te->location); - } - te->handler(handler_ev, te, current_time, te->private_data); - if (te->wrapper != NULL) { - te->wrapper->ops->after_timer_handler( - te->wrapper->wrap_ev, - te->wrapper->private_state, - te->wrapper->main_ev, - te, - te->next_event, - current_time, - te->handler_name, - te->location); - tevent_wrapper_pop_use_internal(handler_ev, te->wrapper); - } - te->busy = false; - - tevent_debug(te->event_ctx, TEVENT_DEBUG_TRACE, - "Ending timer event %p \"%s\"\n", - te, te->handler_name); - - te->wrapper = NULL; - te->event_ctx = NULL; - talloc_set_destructor(te, NULL); - TALLOC_FREE(te); - - if (removed != NULL) { - *removed = true; - } - - return 0; -} -/* - do a single event loop using the events defined in ev - - return the delay until the next timed event, - or zero if a timed event was triggered -*/ -struct timeval tevent_common_loop_timer_delay(struct tevent_context *ev) -{ - struct timeval current_time = tevent_timeval_zero(); - struct tevent_timer *te = ev->timer_events; - int ret; - - if (!te) { - /* have a default tick time of 30 seconds. This guarantees - that code that uses its own timeout checking will be - able to proceed eventually */ - return tevent_timeval_set(30, 0); - } - - /* - * work out the right timeout for the next timed event - * - * avoid the syscall to gettimeofday() if the timed event should - * be triggered directly - * - * if there's a delay till the next timed event, we're done - * with just returning the delay - */ - if (!tevent_timeval_is_zero(&te->next_event)) { - struct timeval delay; - - current_time = tevent_timeval_current(); - - delay = tevent_timeval_until(¤t_time, &te->next_event); - if (!tevent_timeval_is_zero(&delay)) { - return delay; - } - } - - /* - * ok, we have a timed event that we'll process ... - */ - ret = tevent_common_invoke_timer_handler(te, current_time, NULL); - if (ret != 0) { - tevent_abort(ev, "tevent_common_invoke_timer_handler() failed"); - } - - return tevent_timeval_zero(); -} - diff --git a/ldb-2.0.8/lib/tevent/tevent_util.c b/ldb-2.0.8/lib/tevent/tevent_util.c deleted file mode 100644 index 16af8f3..0000000 --- a/ldb-2.0.8/lib/tevent/tevent_util.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Andrew Tridgell 2005 - Copyright (C) Jelmer Vernooij 2005 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#include "talloc.h" -#include "tevent.h" -#include "tevent_internal.h" -#include "tevent_util.h" -#include - -/** - return the number of elements in a string list -*/ -size_t ev_str_list_length(const char **list) -{ - size_t ret; - for (ret=0;list && list[ret];ret++) /* noop */ ; - return ret; -} - -/** - add an entry to a string list -*/ -const char **ev_str_list_add(const char **list, const char *s) -{ - size_t len = ev_str_list_length(list); - const char **ret; - - ret = talloc_realloc(NULL, list, const char *, len+2); - if (ret == NULL) return NULL; - - ret[len] = talloc_strdup(ret, s); - if (ret[len] == NULL) return NULL; - - ret[len+1] = NULL; - - return ret; -} - - -/** - Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available, - else - if SYSV use O_NDELAY - if BSD use FNDELAY -**/ - -int ev_set_blocking(int fd, bool set) -{ - int val; -#ifdef O_NONBLOCK -#define FLAG_TO_SET O_NONBLOCK -#else -#ifdef SYSV -#define FLAG_TO_SET O_NDELAY -#else /* BSD */ -#define FLAG_TO_SET FNDELAY -#endif -#endif - - if((val = fcntl(fd, F_GETFL, 0)) == -1) - return -1; - if(set) /* Turn blocking on - ie. clear nonblock flag */ - val &= ~FLAG_TO_SET; - else - val |= FLAG_TO_SET; - return fcntl( fd, F_SETFL, val); -#undef FLAG_TO_SET -} - -bool ev_set_close_on_exec(int fd) -{ -#ifdef FD_CLOEXEC - int val; - - val = fcntl(fd, F_GETFD, 0); - if (val >= 0) { - val |= FD_CLOEXEC; - val = fcntl(fd, F_SETFD, val); - if (val != -1) { - return true; - } - } -#endif - return false; -} diff --git a/ldb-2.0.8/lib/tevent/tevent_util.h b/ldb-2.0.8/lib/tevent/tevent_util.h deleted file mode 100644 index eef4a00..0000000 --- a/ldb-2.0.8/lib/tevent/tevent_util.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Andrew Tridgell 1998-2010 - Copyright (C) Jelmer Vernooij 2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/* To use these macros you must have a structure containing a next and - prev pointer */ - -#ifndef _DLINKLIST_H -#define _DLINKLIST_H - -/* - February 2010 - changed list format to have a prev pointer from the - list head. This makes DLIST_ADD_END() O(1) even though we only have - one list pointer. - - The scheme is as follows: - - 1) with no entries in the list: - list_head == NULL - - 2) with 1 entry in the list: - list_head->next == NULL - list_head->prev == list_head - - 3) with 2 entries in the list: - list_head->next == element2 - list_head->prev == element2 - element2->prev == list_head - element2->next == NULL - - 4) with N entries in the list: - list_head->next == element2 - list_head->prev == elementN - elementN->prev == element{N-1} - elementN->next == NULL - - This allows us to find the tail of the list by using - list_head->prev, which means we can add to the end of the list in - O(1) time - */ - - -/* - add an element at the front of a list -*/ -#define DLIST_ADD(list, p) \ -do { \ - if (!(list)) { \ - (p)->prev = (list) = (p); \ - (p)->next = NULL; \ - } else { \ - (p)->prev = (list)->prev; \ - (list)->prev = (p); \ - (p)->next = (list); \ - (list) = (p); \ - } \ -} while (0) - -/* - remove an element from a list - Note that the element doesn't have to be in the list. If it - isn't then this is a no-op -*/ -#define DLIST_REMOVE(list, p) \ -do { \ - if ((p) == (list)) { \ - if ((p)->next) (p)->next->prev = (p)->prev; \ - (list) = (p)->next; \ - } else if ((p)->prev && (list) && (p) == (list)->prev) { \ - (p)->prev->next = NULL; \ - (list)->prev = (p)->prev; \ - } else { \ - if ((p)->prev) (p)->prev->next = (p)->next; \ - if ((p)->next) (p)->next->prev = (p)->prev; \ - } \ - if ((p) != (list)) (p)->next = (p)->prev = NULL; \ -} while (0) - -/* - find the head of the list given any element in it. - Note that this costs O(N), so you should avoid this macro - if at all possible! -*/ -#define DLIST_HEAD(p, result_head) \ -do { \ - (result_head) = (p); \ - while (DLIST_PREV(result_head)) (result_head) = (result_head)->prev; \ -} while(0) - -/* return the last element in the list */ -#define DLIST_TAIL(list) ((list)?(list)->prev:NULL) - -/* return the previous element in the list. */ -#define DLIST_PREV(p) (((p)->prev && (p)->prev->next != NULL)?(p)->prev:NULL) - -/* insert 'p' after the given element 'el' in a list. If el is NULL then - this is the same as a DLIST_ADD() */ -#define DLIST_ADD_AFTER(list, p, el) \ -do { \ - if (!(list) || !(el)) { \ - DLIST_ADD(list, p); \ - } else { \ - (p)->prev = (el); \ - (p)->next = (el)->next; \ - (el)->next = (p); \ - if ((p)->next) (p)->next->prev = (p); \ - if ((list)->prev == (el)) (list)->prev = (p); \ - }\ -} while (0) - - -/* - add to the end of a list. -*/ -#define DLIST_ADD_END(list, p) \ -do { \ - if (!(list)) { \ - DLIST_ADD(list, p); \ - } else { \ - DLIST_ADD_AFTER(list, p, (list)->prev); \ - } \ -} while (0) - -/* promote an element to the front of a list */ -#define DLIST_PROMOTE(list, p) \ -do { \ - DLIST_REMOVE(list, p); \ - DLIST_ADD(list, p); \ -} while (0) - -/* - demote an element to the end of a list. -*/ -#define DLIST_DEMOTE(list, p) \ -do { \ - DLIST_REMOVE(list, p); \ - DLIST_ADD_END(list, p); \ -} while (0) - -/* - concatenate two lists - putting all elements of the 2nd list at the - end of the first list. -*/ -#define DLIST_CONCATENATE(list1, list2) \ -do { \ - if (!(list1)) { \ - (list1) = (list2); \ - } else { \ - (list1)->prev->next = (list2); \ - if (list2) { \ - void *_tmplist = (void *)(list1)->prev; \ - (list1)->prev = (list2)->prev; \ - (list2)->prev = _tmplist; \ - } \ - } \ -} while (0) - -#endif /* _DLINKLIST_H */ - -const char **ev_str_list_add(const char **list, const char *s); -int ev_set_blocking(int fd, bool set); -size_t ev_str_list_length(const char **list); -bool ev_set_close_on_exec(int fd); - -/* Defined here so we can build against older talloc versions that don't - * have this define yet. */ -#ifndef TALLOC_FREE -#define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0) -#endif diff --git a/ldb-2.0.8/lib/tevent/tevent_wakeup.c b/ldb-2.0.8/lib/tevent/tevent_wakeup.c deleted file mode 100644 index e217f33..0000000 --- a/ldb-2.0.8/lib/tevent/tevent_wakeup.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Infrastructure for async requests - Copyright (C) Volker Lendecke 2008 - Copyright (C) Stefan Metzmacher 2009 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#include "tevent.h" -#include "tevent_internal.h" -#include "tevent_util.h" - -struct tevent_wakeup_state { - struct timeval wakeup_time; -}; - -struct tevent_req *tevent_wakeup_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct timeval wakeup_time) -{ - struct tevent_req *req; - struct tevent_wakeup_state *state; - - req = tevent_req_create(mem_ctx, &state, - struct tevent_wakeup_state); - if (!req) { - return NULL; - } - state->wakeup_time = wakeup_time; - - if (!tevent_req_set_endtime(req, ev, wakeup_time)) { - return tevent_req_post(req, ev); - } - return req; -} - -bool tevent_wakeup_recv(struct tevent_req *req) -{ - enum tevent_req_state state; - uint64_t error; - - if (tevent_req_is_error(req, &state, &error)) { - if (state == TEVENT_REQ_TIMED_OUT) { - return true; - } - } - - return false; -} - diff --git a/ldb-2.0.8/lib/tevent/tevent_wrapper.c b/ldb-2.0.8/lib/tevent/tevent_wrapper.c deleted file mode 100644 index a0e915f..0000000 --- a/ldb-2.0.8/lib/tevent/tevent_wrapper.c +++ /dev/null @@ -1,571 +0,0 @@ -/* - Infrastructure for event context wrappers - - Copyright (C) Stefan Metzmacher 2014 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#ifdef HAVE_PTHREAD -#include "system/threads.h" -#endif -#define TEVENT_DEPRECATED 1 -#include "tevent.h" -#include "tevent_internal.h" -#include "tevent_util.h" - -static int tevent_wrapper_glue_context_init(struct tevent_context *ev) -{ - tevent_abort(ev, "tevent_wrapper_glue_context_init() called"); - errno = ENOSYS; - return -1; -} - -static struct tevent_fd *tevent_wrapper_glue_add_fd(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - int fd, uint16_t flags, - tevent_fd_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ - struct tevent_wrapper_glue *glue = ev->wrapper.glue; - struct tevent_fd *fde = NULL; - - if (glue->destroyed) { - tevent_abort(ev, "add_fd wrapper use after free"); - return NULL; - } - - if (glue->main_ev == NULL) { - errno = EINVAL; - return NULL; - } - - fde = _tevent_add_fd(glue->main_ev, mem_ctx, fd, flags, - handler, private_data, - handler_name, location); - if (fde == NULL) { - return NULL; - } - - fde->wrapper = glue; - - return fde; -} - -static struct tevent_timer *tevent_wrapper_glue_add_timer(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - struct timeval next_event, - tevent_timer_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ - struct tevent_wrapper_glue *glue = ev->wrapper.glue; - struct tevent_timer *te = NULL; - - if (glue->destroyed) { - tevent_abort(ev, "add_timer wrapper use after free"); - return NULL; - } - - if (glue->main_ev == NULL) { - errno = EINVAL; - return NULL; - } - - te = _tevent_add_timer(glue->main_ev, mem_ctx, next_event, - handler, private_data, - handler_name, location); - if (te == NULL) { - return NULL; - } - - te->wrapper = glue; - - return te; -} - -static void tevent_wrapper_glue_schedule_immediate(struct tevent_immediate *im, - struct tevent_context *ev, - tevent_immediate_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ - struct tevent_wrapper_glue *glue = ev->wrapper.glue; - - if (glue->destroyed) { - tevent_abort(ev, "scheduke_immediate wrapper use after free"); - return; - } - - if (glue->main_ev == NULL) { - tevent_abort(ev, location); - errno = EINVAL; - return; - } - - _tevent_schedule_immediate(im, glue->main_ev, - handler, private_data, - handler_name, location); - - im->wrapper = glue; - - return; -} - -static struct tevent_signal *tevent_wrapper_glue_add_signal(struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - int signum, int sa_flags, - tevent_signal_handler_t handler, - void *private_data, - const char *handler_name, - const char *location) -{ - struct tevent_wrapper_glue *glue = ev->wrapper.glue; - struct tevent_signal *se = NULL; - - if (glue->destroyed) { - tevent_abort(ev, "add_signal wrapper use after free"); - return NULL; - } - - if (glue->main_ev == NULL) { - errno = EINVAL; - return NULL; - } - - se = _tevent_add_signal(glue->main_ev, mem_ctx, - signum, sa_flags, - handler, private_data, - handler_name, location); - if (se == NULL) { - return NULL; - } - - se->wrapper = glue; - - return se; -} - -static int tevent_wrapper_glue_loop_once(struct tevent_context *ev, const char *location) -{ - tevent_abort(ev, "tevent_wrapper_glue_loop_once() called"); - errno = ENOSYS; - return -1; -} - -static int tevent_wrapper_glue_loop_wait(struct tevent_context *ev, const char *location) -{ - tevent_abort(ev, "tevent_wrapper_glue_loop_wait() called"); - errno = ENOSYS; - return -1; -} - -static const struct tevent_ops tevent_wrapper_glue_ops = { - .context_init = tevent_wrapper_glue_context_init, - .add_fd = tevent_wrapper_glue_add_fd, - .set_fd_close_fn = tevent_common_fd_set_close_fn, - .get_fd_flags = tevent_common_fd_get_flags, - .set_fd_flags = tevent_common_fd_set_flags, - .add_timer = tevent_wrapper_glue_add_timer, - .schedule_immediate = tevent_wrapper_glue_schedule_immediate, - .add_signal = tevent_wrapper_glue_add_signal, - .loop_once = tevent_wrapper_glue_loop_once, - .loop_wait = tevent_wrapper_glue_loop_wait, -}; - -static int tevent_wrapper_context_destructor(struct tevent_context *wrap_ev) -{ - struct tevent_wrapper_glue *glue = wrap_ev->wrapper.glue; - struct tevent_context *main_ev = NULL; - struct tevent_fd *fd = NULL, *fn = NULL; - struct tevent_timer *te = NULL, *tn = NULL; - struct tevent_immediate *ie = NULL, *in = NULL; - struct tevent_signal *se = NULL, *sn = NULL; -#ifdef HAVE_PTHREAD - struct tevent_threaded_context *tctx = NULL, *tctxn = NULL; -#endif - - if (glue == NULL) { - tevent_abort(wrap_ev, - "tevent_wrapper_context_destructor() active on main"); - /* static checker support, return below is never reached */ - return -1; - } - - if (glue->destroyed && glue->busy) { - tevent_common_check_double_free(wrap_ev, - "tevent_context wrapper double free"); - } - glue->destroyed = true; - - if (glue->busy) { - return -1; - } - - main_ev = glue->main_ev; - if (main_ev == NULL) { - return 0; - } - - tevent_debug(wrap_ev, TEVENT_DEBUG_TRACE, - "Destroying wrapper context %p \"%s\"\n", - wrap_ev, talloc_get_name(glue->private_state)); - - glue->main_ev = NULL; - DLIST_REMOVE(main_ev->wrapper.list, glue); - -#ifdef HAVE_PTHREAD - for (tctx = main_ev->threaded_contexts; tctx != NULL; tctx = tctxn) { - int ret; - - tctxn = tctx->next; - - if (tctx->event_ctx != glue->wrap_ev) { - continue; - } - - ret = pthread_mutex_lock(&tctx->event_ctx_mutex); - if (ret != 0) { - abort(); - } - - /* - * Indicate to the thread that the tevent_context is - * gone. The counterpart of this is in - * _tevent_threaded_schedule_immediate, there we read - * this under the threaded_context's mutex. - */ - - tctx->event_ctx = NULL; - - ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); - if (ret != 0) { - abort(); - } - - DLIST_REMOVE(main_ev->threaded_contexts, tctx); - } -#endif - - for (fd = main_ev->fd_events; fd; fd = fn) { - fn = fd->next; - - if (fd->wrapper != glue) { - continue; - } - - tevent_fd_set_flags(fd, 0); - - fd->wrapper = NULL; - fd->event_ctx = NULL; - DLIST_REMOVE(main_ev->fd_events, fd); - } - - for (te = main_ev->timer_events; te; te = tn) { - tn = te->next; - - if (te->wrapper != glue) { - continue; - } - - te->wrapper = NULL; - te->event_ctx = NULL; - - if (main_ev->last_zero_timer == te) { - main_ev->last_zero_timer = DLIST_PREV(te); - } - DLIST_REMOVE(main_ev->timer_events, te); - } - - for (ie = main_ev->immediate_events; ie; ie = in) { - in = ie->next; - - if (ie->wrapper != glue) { - continue; - } - - ie->wrapper = NULL; - ie->event_ctx = NULL; - ie->cancel_fn = NULL; - DLIST_REMOVE(main_ev->immediate_events, ie); - } - - for (se = main_ev->signal_events; se; se = sn) { - sn = se->next; - - if (se->wrapper != glue) { - continue; - } - - se->wrapper = NULL; - tevent_cleanup_pending_signal_handlers(se); - } - - return 0; -} - -struct tevent_context *_tevent_context_wrapper_create(struct tevent_context *main_ev, - TALLOC_CTX *mem_ctx, - const struct tevent_wrapper_ops *ops, - void *pstate, - size_t psize, - const char *type, - const char *location) -{ - void **ppstate = (void **)pstate; - struct tevent_context *ev = NULL; - - if (main_ev->wrapper.glue != NULL) { - /* - * stacking of wrappers is not supported - */ - tevent_debug(main_ev->wrapper.glue->main_ev, TEVENT_DEBUG_FATAL, - "%s: %s() stacking not allowed\n", - __func__, location); - errno = EINVAL; - return NULL; - } - - if (main_ev->nesting.allowed) { - /* - * wrappers conflict with nesting - */ - tevent_debug(main_ev, TEVENT_DEBUG_FATAL, - "%s: %s() conflicts with nesting\n", - __func__, location); - errno = EINVAL; - return NULL; - } - - ev = talloc_zero(mem_ctx, struct tevent_context); - if (ev == NULL) { - return NULL; - } - ev->ops = &tevent_wrapper_glue_ops; - - ev->wrapper.glue = talloc_zero(ev, struct tevent_wrapper_glue); - if (ev->wrapper.glue == NULL) { - talloc_free(ev); - return NULL; - } - - talloc_set_destructor(ev, tevent_wrapper_context_destructor); - - ev->wrapper.glue->wrap_ev = ev; - ev->wrapper.glue->main_ev = main_ev; - ev->wrapper.glue->ops = ops; - ev->wrapper.glue->private_state = talloc_zero_size(ev->wrapper.glue, psize); - if (ev->wrapper.glue->private_state == NULL) { - talloc_free(ev); - return NULL; - } - talloc_set_name_const(ev->wrapper.glue->private_state, type); - - DLIST_ADD_END(main_ev->wrapper.list, ev->wrapper.glue); - - *ppstate = ev->wrapper.glue->private_state; - return ev; -} - -bool tevent_context_is_wrapper(struct tevent_context *ev) -{ - if (ev->wrapper.glue != NULL) { - return true; - } - - return false; -} - -_PRIVATE_ -struct tevent_context *tevent_wrapper_main_ev(struct tevent_context *ev) -{ - if (ev == NULL) { - return NULL; - } - - if (ev->wrapper.glue == NULL) { - return ev; - } - - return ev->wrapper.glue->main_ev; -} - -/* - * 32 stack elements should be more than enough - * - * e.g. Samba uses just 8 elements for [un]become_{root,user}() - */ -#define TEVENT_WRAPPER_STACK_SIZE 32 - -static struct tevent_wrapper_stack { - const void *ev_ptr; - const struct tevent_wrapper_glue *wrapper; -} wrapper_stack[TEVENT_WRAPPER_STACK_SIZE]; - -static size_t wrapper_stack_idx; - -_PRIVATE_ -void tevent_wrapper_push_use_internal(struct tevent_context *ev, - struct tevent_wrapper_glue *wrapper) -{ - /* - * ev and wrapper need to belong together! - * It's also fine to only have a raw ev - * without a wrapper. - */ - if (unlikely(ev->wrapper.glue != wrapper)) { - tevent_abort(ev, "tevent_wrapper_push_use_internal() invalid arguments"); - return; - } - - if (wrapper != NULL) { - if (unlikely(wrapper->busy)) { - tevent_abort(ev, "wrapper already busy!"); - return; - } - wrapper->busy = true; - } - - if (unlikely(wrapper_stack_idx >= TEVENT_WRAPPER_STACK_SIZE)) { - tevent_abort(ev, "TEVENT_WRAPPER_STACK_SIZE overflow"); - return; - } - - wrapper_stack[wrapper_stack_idx] = (struct tevent_wrapper_stack) { - .ev_ptr = ev, - .wrapper = wrapper, - }; - wrapper_stack_idx++; -} - -_PRIVATE_ -void tevent_wrapper_pop_use_internal(const struct tevent_context *__ev_ptr, - struct tevent_wrapper_glue *wrapper) -{ - struct tevent_context *main_ev = NULL; - - /* - * Note that __ev_ptr might a a stale pointer and should not - * be touched, we just compare the pointer value in order - * to enforce the stack order. - */ - - if (wrapper != NULL) { - main_ev = wrapper->main_ev; - } - - if (unlikely(wrapper_stack_idx == 0)) { - tevent_abort(main_ev, "tevent_wrapper stack already empty"); - return; - } - wrapper_stack_idx--; - - if (wrapper != NULL) { - wrapper->busy = false; - } - - if (wrapper_stack[wrapper_stack_idx].ev_ptr != __ev_ptr) { - tevent_abort(main_ev, "tevent_wrapper_pop_use mismatch ev!"); - return; - } - if (wrapper_stack[wrapper_stack_idx].wrapper != wrapper) { - tevent_abort(main_ev, "tevent_wrapper_pop_use mismatch wrap!"); - return; - } - - if (wrapper == NULL) { - return; - } - - if (wrapper->destroyed) { - /* - * Notice that we can't use TALLOC_FREE() - * here because wrapper is a talloc child - * of wrapper->wrap_ev. - */ - talloc_free(wrapper->wrap_ev); - } -} - -bool _tevent_context_push_use(struct tevent_context *ev, - const char *location) -{ - bool ok; - - if (ev->wrapper.glue == NULL) { - tevent_wrapper_push_use_internal(ev, NULL); - return true; - } - - if (ev->wrapper.glue->main_ev == NULL) { - return false; - } - - tevent_wrapper_push_use_internal(ev, ev->wrapper.glue); - ok = ev->wrapper.glue->ops->before_use(ev->wrapper.glue->wrap_ev, - ev->wrapper.glue->private_state, - ev->wrapper.glue->main_ev, - location); - if (!ok) { - tevent_wrapper_pop_use_internal(ev, ev->wrapper.glue); - return false; - } - - return true; -} - -void _tevent_context_pop_use(struct tevent_context *ev, - const char *location) -{ - tevent_wrapper_pop_use_internal(ev, ev->wrapper.glue); - - if (ev->wrapper.glue == NULL) { - return; - } - - if (ev->wrapper.glue->main_ev == NULL) { - return; - } - - ev->wrapper.glue->ops->after_use(ev->wrapper.glue->wrap_ev, - ev->wrapper.glue->private_state, - ev->wrapper.glue->main_ev, - location); -} - -bool tevent_context_same_loop(struct tevent_context *ev1, - struct tevent_context *ev2) -{ - struct tevent_context *main_ev1 = tevent_wrapper_main_ev(ev1); - struct tevent_context *main_ev2 = tevent_wrapper_main_ev(ev2); - - if (main_ev1 == NULL) { - return false; - } - - if (main_ev1 == main_ev2) { - return true; - } - - return false; -} diff --git a/ldb-2.0.8/lib/tevent/wscript b/ldb-2.0.8/lib/tevent/wscript deleted file mode 100644 index ded182a..0000000 --- a/ldb-2.0.8/lib/tevent/wscript +++ /dev/null @@ -1,142 +0,0 @@ -#!/usr/bin/env python - -APPNAME = 'tevent' -VERSION = '0.10.0' - -import sys, os - -# find the buildtools directory -top = '.' -while not os.path.exists(top+'/buildtools') and len(top.split('/')) < 5: - top = top + '/..' -sys.path.insert(0, top + '/buildtools/wafsamba') - -out = 'bin' - -import wafsamba -from wafsamba import samba_dist, samba_utils -from waflib import Options, Logs, Context - -samba_dist.DIST_DIRS('lib/tevent:. lib/replace:lib/replace lib/talloc:lib/talloc buildtools:buildtools third_party/waf:third_party/waf') - -def options(opt): - opt.BUILTIN_DEFAULT('replace') - opt.PRIVATE_EXTENSION_DEFAULT('tevent', noextension='tevent') - opt.RECURSE('lib/replace') - opt.RECURSE('lib/talloc') - - -def configure(conf): - conf.RECURSE('lib/replace') - conf.RECURSE('lib/talloc') - - conf.env.standalone_tevent = conf.IN_LAUNCH_DIR() - - if not conf.env.standalone_tevent: - if conf.CHECK_BUNDLED_SYSTEM_PKG('tevent', minversion=VERSION, - onlyif='talloc', implied_deps='replace talloc'): - conf.define('USING_SYSTEM_TEVENT', 1) - if not conf.env.disable_python and \ - conf.CHECK_BUNDLED_SYSTEM_PYTHON('pytevent', 'tevent', minversion=VERSION): - conf.define('USING_SYSTEM_PYTEVENT', 1) - - if conf.CHECK_FUNCS('epoll_create', headers='sys/epoll.h'): - conf.DEFINE('HAVE_EPOLL', 1) - - tevent_num_signals = 64 - v = conf.CHECK_VALUEOF('NSIG', headers='signal.h') - if v is not None: - tevent_num_signals = max(tevent_num_signals, v) - v = conf.CHECK_VALUEOF('_NSIG', headers='signal.h') - if v is not None: - tevent_num_signals = max(tevent_num_signals, v) - v = conf.CHECK_VALUEOF('SIGRTMAX', headers='signal.h') - if v is not None: - tevent_num_signals = max(tevent_num_signals, v) - v = conf.CHECK_VALUEOF('SIGRTMIN', headers='signal.h') - if v is not None: - tevent_num_signals = max(tevent_num_signals, v*2) - - if not conf.CONFIG_SET('USING_SYSTEM_TEVENT'): - conf.DEFINE('TEVENT_NUM_SIGNALS', tevent_num_signals) - - conf.SAMBA_CHECK_PYTHON() - conf.SAMBA_CHECK_PYTHON_HEADERS() - - conf.SAMBA_CONFIG_H() - - conf.SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS() - -def build(bld): - bld.RECURSE('lib/replace') - bld.RECURSE('lib/talloc') - - SRC = '''tevent.c tevent_debug.c tevent_fd.c tevent_immediate.c - tevent_queue.c tevent_req.c tevent_wrapper.c - tevent_poll.c tevent_threads.c - tevent_signal.c tevent_standard.c tevent_timed.c tevent_util.c tevent_wakeup.c''' - - if bld.CONFIG_SET('HAVE_EPOLL'): - SRC += ' tevent_epoll.c' - - if bld.CONFIG_SET('HAVE_SOLARIS_PORTS'): - SRC += ' tevent_port.c' - - if bld.env.standalone_tevent: - bld.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig' - private_library = False - else: - private_library = True - - if not bld.CONFIG_SET('USING_SYSTEM_TEVENT'): - tevent_deps = 'replace talloc' - if bld.CONFIG_SET('HAVE_PTHREAD'): - tevent_deps += ' pthread' - - bld.SAMBA_LIBRARY('tevent', - SRC, - deps=tevent_deps, - enabled= not bld.CONFIG_SET('USING_SYSTEM_TEVENT'), - includes='.', - abi_directory='ABI', - abi_match='tevent_* _tevent_*', - vnum=VERSION, - public_headers=('' if private_library else 'tevent.h'), - public_headers_install=not private_library, - pc_files='tevent.pc', - private_library=private_library) - - if not bld.CONFIG_SET('USING_SYSTEM_PYTEVENT') and not bld.env.disable_python: - bld.SAMBA_PYTHON('_tevent', - 'pytevent.c', - deps='tevent', - realname='_tevent.so', - cflags='-DPACKAGE_VERSION=\"%s\"' % VERSION) - - - bld.INSTALL_WILDCARD('${PYTHONARCHDIR}', 'tevent.py', flat=False) - - # install out various python scripts for use by make test - bld.SAMBA_SCRIPT('tevent_python', - pattern='tevent.py', - installdir='python') - - -def test(ctx): - '''test tevent''' - print("The tevent testsuite is part of smbtorture in samba4") - - samba_utils.ADD_LD_LIBRARY_PATH('bin/shared') - samba_utils.ADD_LD_LIBRARY_PATH('bin/shared/private') - - pyret = samba_utils.RUN_PYTHON_TESTS(['bindings.py']) - sys.exit(pyret) - - -def dist(): - '''makes a tarball for distribution''' - samba_dist.dist() - -def reconfigure(ctx): - '''reconfigure if config scripts have changed''' - samba_utils.reconfigure(ctx) diff --git a/ldb-2.0.8/lib/util/attr.h b/ldb-2.0.8/lib/util/attr.h deleted file mode 100644 index 8e542c1..0000000 --- a/ldb-2.0.8/lib/util/attr.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba utility functions - Copyright (C) Jelmer Vernooij 2007 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef __UTIL_ATTR_H__ -#define __UTIL_ATTR_H__ - -#ifndef _UNUSED_ -#ifdef __GNUC__ -/** gcc attribute used on function parameters so that it does not emit - * warnings about them being unused. **/ -# define _UNUSED_ __attribute__ ((unused)) -#else -# define _UNUSED_ -/** Feel free to add definitions for other compilers here. */ -#endif -#endif -#ifndef UNUSED -#define UNUSED(param) param _UNUSED_ -#endif - -#ifndef _DEPRECATED_ -#ifdef HAVE___ATTRIBUTE__ -#define _DEPRECATED_ __attribute__ ((deprecated)) -#else -#define _DEPRECATED_ -#endif -#endif - -#ifndef _WARN_UNUSED_RESULT_ -#ifdef HAVE___ATTRIBUTE__ -#define _WARN_UNUSED_RESULT_ __attribute__ ((warn_unused_result)) -#else -#define _WARN_UNUSED_RESULT_ -#endif -#endif - -#ifndef _NORETURN_ -#ifdef HAVE___ATTRIBUTE__ -#define _NORETURN_ __attribute__ ((noreturn)) -#else -#define _NORETURN_ -#endif -#endif - -#ifndef _PURE_ -#ifdef HAVE___ATTRIBUTE__ -#define _PURE_ __attribute__((pure)) -#else -#define _PURE_ -#endif -#endif - -#ifndef NONNULL -#ifdef HAVE___ATTRIBUTE__ -#define NONNULL(param) param __attribute__((nonnull)) -#else -#define NONNULL(param) param -#endif -#endif - -#ifndef PRINTF_ATTRIBUTE -#ifdef HAVE___ATTRIBUTE__ -/** Use gcc attribute to check printf fns. a1 is the 1-based index of - * the parameter containing the format, and a2 the index of the first - * argument. Note that some gcc 2.x versions don't handle this - * properly **/ -#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) -#else -#define PRINTF_ATTRIBUTE(a1, a2) -#endif -#endif - -#ifndef FORMAT_ATTRIBUTE -#ifdef HAVE___ATTRIBUTE__ -/** Use gcc attribute to check printf fns. a1 is argument to format() - * in the above macro. This is needed to support Heimdal's printf - * decorations. Note that some gcc 2.x versions don't handle this - * properly. **/ -#define FORMAT_ATTRIBUTE(a) __attribute__ ((format a)) -#else -#define FORMAT_ATTRIBUTE(a) -#endif -#endif - -#endif /* __UTIL_ATTR_H__ */ diff --git a/ldb-2.0.8/lib/util/binsearch.h b/ldb-2.0.8/lib/util/binsearch.h deleted file mode 100644 index 8ae9da2..0000000 --- a/ldb-2.0.8/lib/util/binsearch.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - a generic binary search macro - - Copyright (C) Andrew Tridgell 2009 - - ** NOTE! The following LGPL license applies to the binsearch.h - ** header. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#ifndef _BINSEARCH_H -#define _BINSEARCH_H - -/* a binary array search, where the array is an array of pointers to structures, - and we want to find a match for 'target' on 'field' in those structures. - - Inputs: - array: base pointer to an array of structures - arrray_size: number of elements in the array - field: the name of the field in the structure we are keying off - target: the field value we are looking for - comparison_fn: the comparison function - result: where the result of the search is put - - if the element is found, then 'result' is set to point to the found array element. If not, - then 'result' is set to NULL. - - The array is assumed to be sorted by the same comparison_fn as the - search (with, for example, qsort) - */ -#define BINARY_ARRAY_SEARCH_P(array, array_size, field, target, comparison_fn, result) do { \ - int32_t _b, _e; \ - (result) = NULL; \ - if (array_size) { for (_b = 0, _e = (array_size)-1; _b <= _e; ) { \ - int32_t _i = (_b+_e)/2; \ - int _r = comparison_fn(target, array[_i]->field); \ - if (_r == 0) { (result) = array[_i]; break; } \ - if (_r < 0) _e = _i - 1; else _b = _i + 1; \ - }} } while (0) - -/* - like BINARY_ARRAY_SEARCH_P, but assumes that the array is an array - of structures, rather than pointers to structures - - result points to the found structure, or NULL - */ -#define BINARY_ARRAY_SEARCH(array, array_size, field, target, comparison_fn, result) do { \ - int32_t _b, _e; \ - (result) = NULL; \ - if (array_size) { for (_b = 0, _e = (array_size)-1; _b <= _e; ) { \ - int32_t _i = (_b+_e)/2; \ - int _r = comparison_fn(target, array[_i].field); \ - if (_r == 0) { (result) = &array[_i]; break; } \ - if (_r < 0) _e = _i - 1; else _b = _i + 1; \ - }} } while (0) - -/* - like BINARY_ARRAY_SEARCH_P, but assumes that the array is an array - of elements, rather than pointers to structures - - result points to the found structure, or NULL - */ -#define BINARY_ARRAY_SEARCH_V(array, array_size, target, comparison_fn, result) do { \ - int32_t _b, _e; \ - (result) = NULL; \ - if (array_size) { for (_b = 0, _e = (array_size)-1; _b <= _e; ) { \ - int32_t _i = (_b+_e)/2; \ - int _r = comparison_fn(target, array[_i]); \ - if (_r == 0) { (result) = &array[_i]; break; } \ - if (_r < 0) _e = _i - 1; else _b = _i + 1; \ - }} } while (0) - - -/* - like BINARY_ARRAY_SEARCH_V, but if an exact result is not found, the 'next' - argument will point to the element after the place where the exact result - would have been. If an exact result is found, 'next' will be NULL. If the - target is beyond the end of the list, both 'exact' and 'next' will be NULL. - Unlike other binsearch macros, where there are several elements that compare - the same, the exact result will always point to the first one. - - If you don't care to distinguish between the 'greater than' and 'equals' - cases, you can use the same pointer for both 'exact' and 'next'. - - As with all the binsearch macros, the comparison function is always called - with the search term first. - */ -#define BINARY_ARRAY_SEARCH_GTE(array, array_size, target, comparison_fn, \ - exact, next) do { \ - int32_t _b, _e; \ - (exact) = NULL; (next) = NULL; \ - if ((array_size) > 0) { \ - for (_b = 0, _e = (array_size)-1; _b <= _e; ) { \ - int32_t _i = (_b + _e) / 2; \ - int _r = comparison_fn(target, &array[_i]); \ - if (_r == 0) { \ - (exact) = &array[_i]; \ - _e = _i - 1; \ - } else if (_r < 0) { _e = _i - 1; \ - } else { _b = _i + 1; } \ - } \ - if ((exact) == NULL &&_b < (array_size)) { \ - (next) = &array[_b]; \ - } } } while (0) - -#endif diff --git a/ldb-2.0.8/mainpage.dox b/ldb-2.0.8/mainpage.dox deleted file mode 100644 index bbd8d9c..0000000 --- a/ldb-2.0.8/mainpage.dox +++ /dev/null @@ -1,80 +0,0 @@ -/** - -\mainpage ldb - -\section Overview - -ldb is a LDAP-like embedded database. It is not at all LDAP standards -compliant, so if you want a standards compliant database then please -see the excellent OpenLDAP -project.

      - -What ldb does is provide a fast database with an LDAP-like API -designed to be used within an application. In some ways it can be seen -as a intermediate solution between key-value pair databases and a real -LDAP database.

      - -ldb is the database engine used in Samba4. - -\section Features - -The main features that separate ldb from other solutions are: - - Safe multi-reader, multi-writer, using byte range locking - - LDAP-like API - - fast operation - - choice of local tdb, local sqlite3 or remote LDAP backends - - integration with talloc - - schema-less operation, for trivial setup - - modules for extensions (such as schema support) - - easy setup of indexes and attribute properties - - ldbedit tool for database editing (reminiscent of 'vipw') - - ldif for import/export - -\section Documentation - -ldb has limited programmer and administrator documentation: - - a list of functions - - a list of examples - - a list of data structures - - a list of constants - -If you need more information than is presented in this document, you -may wish to look at the source code, especially the source code in the -tools directory. - -ldb makes use of the LDAP Data Interchange Format (LDIF), which is -documented in RFC -2849. - -\section Support - -ldb does not currently have its own mailing list or bug tracking -system. For now, please use the samba-technical -mailing list, and the Samba -bugzilla bug tracking system. - -\section Download - -You can download the latest release either via rsync or anonymous -svn. To fetch via svn use the following commands: - -\verbatim - svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/ldb ldb - svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/tdb tdb - svn co svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/talloc talloc -\endverbatim - -To fetch via rsync use these commands: - -\verbatim - rsync -Pavz samba.org::ftp/unpacked/samba4/source/lib/ldb . - rsync -Pavz samba.org::ftp/unpacked/samba4/source/lib/tdb . - rsync -Pavz samba.org::ftp/unpacked/samba4/source/lib/talloc . -\endverbatim - -\section Credits - -ldb is another product of the prolific Andrew Tridgell. - -*/ diff --git a/ldb-2.0.8/man/ldb.3.xml b/ldb-2.0.8/man/ldb.3.xml deleted file mode 100644 index b832d0c..0000000 --- a/ldb-2.0.8/man/ldb.3.xml +++ /dev/null @@ -1,265 +0,0 @@ - - - - - - ldb - 3 - LDB - System Administration tools - 1.1 - - - - ldb - The Samba Project - A light-weight database library - - - - #include <ldb.h> - - - - description - - -ldb is a light weight embedded database library and API. With a -programming interface that is very similar to LDAP, ldb can store its -data either in a tdb(3) database or in a real LDAP database. - - - -When used with the tdb backend ldb does not require any database -daemon. Instead, ldb function calls are processed immediately by the -ldb library, which does IO directly on the database, while allowing -multiple readers/writers using operating system byte range locks. This -leads to an API with very low overheads, often resulting in speeds of -more than 10x what can be achieved with a more traditional LDAP -architecture. - - - -In a taxonomy of databases ldb would sit half way between key/value -pair databases (such as berkley db or tdb) and a full LDAP -database. With a structured attribute oriented API like LDAP and good -indexing capabilities, ldb can be used for quite sophisticated -applications that need a light weight database, without the -administrative overhead of a full LDAP installation. - - - -Included with ldb are a number of useful command line tools for -manipulating a ldb database. These tools are similar in style to the -equivalent ldap command line tools. - - - -In its default mode of operation with a tdb backend, ldb can also be -seen as a "schema-less LDAP". By default ldb does not require a -schema, which greatly reduces the complexity of getting started with -ldb databases. As the complexity of you application grows you can take -advantage of some of the optional schema-like attributes that ldb -offers, or you can migrate to using the full LDAP api while keeping -your exiting ldb code. - - - -If you are new to ldb, then I suggest starting with the manual pages -for ldbsearch(1) and ldbedit(1), and experimenting with a local -database. Then I suggest you look at the ldb_connect(3) and -ldb_search(3) manual pages. - - - - - TOOLS - - - - ldbsearch(1) - - command line ldb search utility - - - - ldbedit(1) - - edit all or part of a ldb database using your favourite editor - - - - ldbadd(1) - - add records to a ldb database using LDIF formatted input - - - - ldbdel(1) - - delete records from a ldb database - - - - ldbmodify(1) - - modify records in a ldb database using LDIF formatted input - - - - - - FUNCTIONS - - - - ldb_connect(3) - - connect to a ldb backend - - - - ldb_search(3) - - perform a database search - - - - ldb_add(3) - - add a record to the database - - - - ldb_delete(3) - - delete a record from the database - - - - ldb_modify(3) - - modify a record in the database - - - - ldb_errstring(3) - - retrieve extended error information from the last operation - - - - ldb_ldif_write(3) - - write a LDIF formatted message - - - - ldb_ldif_write_file(3) - - write a LDIF formatted message to a file - - - - ldb_ldif_read(3) - - read a LDIF formatted message - - - - ldb_ldif_read_free(3) - - free the result of a ldb_ldif_read() - - - - ldb_ldif_read_file(3) - - read a LDIF message from a file - - - - ldb_ldif_read_string(3) - - read a LDIF message from a string - - - - ldb_msg_find_element(3) - - find an element in a ldb_message - - - - ldb_val_equal_exact(3) - - compare two ldb_val structures - - - - ldb_msg_find_val(3) - - find an element by value - - - - ldb_msg_add_empty(3) - - add an empty message element to a ldb_message - - - - - ldb_msg_add(3) - - add a non-empty message element to a ldb_message - - - - - ldb_msg_element_compare(3) - - compare two ldb_message_element structures - - - - - ldb_msg_find_int(3) - - return an integer value from a ldb_message - - - - - ldb_msg_find_uint(3) - - return an unsigned integer value from a ldb_message - - - - - ldb_msg_find_double(3) - - return a double value from a ldb_message - - - - - ldb_msg_find_string(3) - - return a string value from a ldb_message - - - - - ldb_set_alloc(3) - - set the memory allocation function to be used by ldb - - - - - ldb_set_debug(3) - - set a debug handler to be used by ldb - - - - - ldb_set_debug_stderr(3) - - set a debug handler for stderr output - - - - - - Author - - - ldb was written by - Andrew Tridgell. - - - -If you wish to report a problem or make a suggestion then please see -the web site for -current contact and maintainer information. - - - -ldb is released under the GNU Lesser General Public License version 2 -or later. Please see the file COPYING for license details. - - - diff --git a/ldb-2.0.8/man/ldbadd.1.xml b/ldb-2.0.8/man/ldbadd.1.xml deleted file mode 100644 index 4736b3b..0000000 --- a/ldb-2.0.8/man/ldbadd.1.xml +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - ldbadd - 1 - LDB - System Administration tools - 1.1 - - - - - ldbadd - Command-line utility for adding records to an LDB - - - - - ldbadd - -h - -H LDB-URL - ldif-file1 - ldif-file2 - ... - - - - - DESCRIPTION - - ldbadd adds records to an ldb(3) database. It reads - the ldif(5) files specified on the command line and adds - the records from these files to the LDB database, which is specified - by the -H option or the LDB_URL environment variable. - - - If - is specified as a ldb file, the ldif input is read from - standard input. - - - - - - OPTIONS - - - - -h - - Show list of available options. - - - - -H <ldb-url> - - LDB URL to connect to. See ldb(3) for details. - - - - - - - - - ENVIRONMENT - - - LDB_URL - LDB URL to connect to (can be overridden by using the - -H command-line option.) - - - - - - - VERSION - - This man page is correct for version 1.1 of LDB. - - - - SEE ALSO - - ldb(3), ldbmodify, ldbdel, ldif(5) - - - - - AUTHOR - - ldb was written by - Andrew Tridgell. - - - -If you wish to report a problem or make a suggestion then please see -the web site for -current contact and maintainer information. - - - This manpage was written by Jelmer Vernooij. - - - - diff --git a/ldb-2.0.8/man/ldbdel.1.xml b/ldb-2.0.8/man/ldbdel.1.xml deleted file mode 100644 index c4cd450..0000000 --- a/ldb-2.0.8/man/ldbdel.1.xml +++ /dev/null @@ -1,108 +0,0 @@ - - - - - - ldbdel - 1 - LDB - System Administration tools - 1.1 - - - - - ldbdel - Command-line program for deleting LDB records - - - - - ldbdel - -h - -H LDB-URL - dn - ... - - - - - DESCRIPTION - - ldbdel deletes records from an ldb(3) database. - It deletes the records identified by the dn's specified - on the command-line. - - ldbdel uses either the database that is specified with - the -H option or the database specified by the LDB_URL environment - variable. - - - - - - OPTIONS - - - - -h - - Show list of available options. - - - - -H <ldb-url> - - LDB URL to connect to. See ldb(3) for details. - - - - - - - - - ENVIRONMENT - - - LDB_URL - LDB URL to connect to (can be overridden by using the - -H command-line option.) - - - - - - - VERSION - - This man page is correct for version 1.1 of LDB. - - - - SEE ALSO - - ldb(3), ldbmodify, ldbadd, ldif(5) - - - - - AUTHOR - - ldb was written by - Andrew Tridgell. - - - -If you wish to report a problem or make a suggestion then please see -the web site for -current contact and maintainer information. - - - ldbdel was written by Andrew Tridgell. - - This manpage was written by Jelmer Vernooij. - - - - diff --git a/ldb-2.0.8/man/ldbedit.1.xml b/ldb-2.0.8/man/ldbedit.1.xml deleted file mode 100644 index 627d20c..0000000 --- a/ldb-2.0.8/man/ldbedit.1.xml +++ /dev/null @@ -1,203 +0,0 @@ - - - - - - ldbedit - 1 - LDB - System Administration tools - 1.1 - - - - - ldbedit - Edit LDB databases using your preferred editor - - - - - ldbedit - -? - --usage - -s base|one|sub - -b basedn - -a - -e editor - -H LDB-URL - expression - attributes - - - - - DESCRIPTION - - ldbedit is a utility that allows you to edit LDB entries (in - tdb files, sqlite files or LDAP servers) using your preferred editor. - ldbedit generates an LDIF file based on your query, allows you to edit - the LDIF, and then merges that LDIF back into the LDB backend. - - - - - - - OPTIONS - - - - -? - --help - - - Show list of available options, and a phrase describing what that option - does. - - - - - - --usage - - - Show list of available options. This is similar to the help option, - however it does not provide any description, and is hence shorter. - - - - - - -H <ldb-url> - - - LDB URL to connect to. For a tdb database, - this will be of the form - tdb://filename. - For a LDAP connection over unix domain - sockets, this will be of the form - ldapi://socket. For - a (potentially remote) LDAP connection over - TCP, this will be of the form - ldap://hostname. For - an SQLite database, this will be of the form - sqlite://filename. - - - - - - -s one|sub|base - Search scope to use. One-level, subtree or base. - - - - -a - -all - - Edit all records. This allows you to - apply the same change to a number of records - at once. You probably want to combine this - with an expression of the form - "objectclass=*". - - - - - - -e editor - --editor editor - - Specify the editor that should be used (overrides - the VISUAL and EDITOR environment - variables). If this option is not used, and - neither VISUAL nor EDITOR environment variables - are set, then the vi editor will be used. - - - - - - -b basedn - Specify Base Distinguished Name to use. - - - - -v - --verbose - - Make ldbedit more verbose about the - operations that are being performed. Without - this option, ldbedit will only provide a - summary change line. - - - - - - - - - - ENVIRONMENT - - - - LDB_URL - - LDB URL to connect to. This can be - overridden by using the -H command-line option.) - - - - - VISUAL and EDITOR - - - Environment variables used to determine what - editor to use. VISUAL takes precedence over - EDITOR, and both are overridden by the - -e command-line option. - - - - - - - - - VERSION - - This man page is correct for version 1.1 of LDB. - - - - SEE ALSO - - ldb(3), ldbmodify(1), ldbdel(1), ldif(5), vi(1) - - - - - AUTHOR - - - ldb was written by - Andrew Tridgell. - - - - If you wish to report a problem or make a suggestion then please see - the web site for - current contact and maintainer information. - - - - This manpage was written by Jelmer Vernooij and updated - by Brad Hards. - - - - - diff --git a/ldb-2.0.8/man/ldbmodify.1.xml b/ldb-2.0.8/man/ldbmodify.1.xml deleted file mode 100644 index ddeeee7..0000000 --- a/ldb-2.0.8/man/ldbmodify.1.xml +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - ldbmodify - 1 - LDB - System Administration tools - 1.1 - - - - - ldbmodify - Modify records in a LDB database - - - - - ldbmodify - -H LDB-URL - ldif-file - - - - - DESCRIPTION - - - ldbmodify changes, adds and deletes records in a LDB database. - The changes that should be made to the LDB database are read from - the specified LDIF-file. If - is specified as the filename, input is read from stdin. - - - For now, see ldapmodify(1) for details on the LDIF file format. - - - - - - OPTIONS - - - - -H <ldb-url> - - LDB URL to connect to. See ldb(3) for details. - - - - - - - ENVIRONMENT - - - LDB_URL - LDB URL to connect to (can be overridden by using the - -H command-line option.) - - - - - - - VERSION - - This man page is correct for version 1.1 of LDB. - - - - SEE ALSO - - ldb(3), ldbedit - - - - - AUTHOR - - ldb was written by - Andrew Tridgell. - - - -If you wish to report a problem or make a suggestion then please see -the web site for -current contact and maintainer information. - - - This manpage was written by Jelmer Vernooij. - - - - diff --git a/ldb-2.0.8/man/ldbrename.1.xml b/ldb-2.0.8/man/ldbrename.1.xml deleted file mode 100644 index 897c40e..0000000 --- a/ldb-2.0.8/man/ldbrename.1.xml +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - ldbrename - 1 - LDB - System Administration tools - 1.1 - - - - - ldbrename - Edit LDB databases using your favorite editor - - - - - ldbrename - -h - -o options - olddn - newdn - - - - - DESCRIPTION - - ldbrename is a utility that allows you to rename trees in - an LDB database based by DN. This utility takes - two arguments: the original - DN name of the top element and the DN to change it to. - - - - - - - OPTIONS - - - - -h - - Show list of available options. - - - - -H <ldb-url> - - LDB URL to connect to. See ldb(3) for details. - - - - - -o options - Extra ldb options, such as - modules. - - - - - - - - ENVIRONMENT - - - LDB_URL - LDB URL to connect to (can be overridden by using the - -H command-line option.) - - - - - - - VERSION - - This man page is correct for version 1.1 of LDB. - - - - SEE ALSO - - ldb(3), ldbmodify, ldbdel, ldif(5) - - - - - AUTHOR - - ldb was written by - Andrew Tridgell. - - - -If you wish to report a problem or make a suggestion then please see -the web site for -current contact and maintainer information. - - - This manpage was written by Jelmer Vernooij. - - - - diff --git a/ldb-2.0.8/man/ldbsearch.1.xml b/ldb-2.0.8/man/ldbsearch.1.xml deleted file mode 100644 index b853992..0000000 --- a/ldb-2.0.8/man/ldbsearch.1.xml +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - ldbsearch - 1 - LDB - System Administration tools - 1.1 - - - - - ldbsearch - Search for records in a LDB database - - - - - ldbsearch - -h - -s base|one|sub - -b basedn - -i - -H LDB-URL - expression - attributes - - - - - DESCRIPTION - - ldbsearch searches a LDB database for records matching the - specified expression (see the ldapsearch(1) manpage for - a description of the expression format). For each - record, the specified attributes are printed. - - - - - - - OPTIONS - - - - -h - - Show list of available options. - - - - -H <ldb-url> - - LDB URL to connect to. See ldb(3) for details. - - - - - -s one|sub|base - Search scope to use. One-level, subtree or base. - - - - -i - Read search expressions from stdin. - - - - -b basedn - Specify Base DN to use. - - - - - - - - ENVIRONMENT - - - LDB_URL - LDB URL to connect to (can be overridden by using the - -H command-line option.) - - - - - - - VERSION - - This man page is correct for version 1.1 of LDB. - - - - SEE ALSO - - ldb(3), ldbedit(1) - - - - - AUTHOR - - ldb was written by - Andrew Tridgell. - - - -If you wish to report a problem or make a suggestion then please see -the web site for -current contact and maintainer information. - - - This manpage was written by Jelmer Vernooij. - - - - diff --git a/ldb-2.0.8/modules/asq.c b/ldb-2.0.8/modules/asq.c deleted file mode 100644 index 7482de8..0000000 --- a/ldb-2.0.8/modules/asq.c +++ /dev/null @@ -1,416 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005-2008 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb attribute scoped query control module - * - * Description: this module searches all the objects pointed by - * the DNs contained in the references attribute - * - * Author: Simo Sorce - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb_module.h" - -struct asq_context { - - enum {ASQ_SEARCH_BASE, ASQ_SEARCH_MULTI} step; - - struct ldb_module *module; - struct ldb_request *req; - - struct ldb_asq_control *asq_ctrl; - - const char * const *req_attrs; - char *req_attribute; - enum { - ASQ_CTRL_SUCCESS = 0, - ASQ_CTRL_INVALID_ATTRIBUTE_SYNTAX = 21, - ASQ_CTRL_UNWILLING_TO_PERFORM = 53, - ASQ_CTRL_AFFECTS_MULTIPLE_DSA = 71 - } asq_ret; - - struct ldb_reply *base_res; - - struct ldb_request **reqs; - unsigned int num_reqs; - unsigned int cur_req; - - struct ldb_control **controls; -}; - -static struct asq_context *asq_context_init(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - struct asq_context *ac; - - ldb = ldb_module_get_ctx(module); - - ac = talloc_zero(req, struct asq_context); - if (ac == NULL) { - ldb_oom(ldb); - return NULL; - } - - ac->module = module; - ac->req = req; - - return ac; -} - -static int asq_search_continue(struct asq_context *ac); - -static int asq_search_terminate(struct asq_context *ac) -{ - struct ldb_asq_control *asq; - unsigned int i; - - if (ac->controls) { - for (i = 0; ac->controls[i]; i++) /* count em */ ; - } else { - i = 0; - } - - ac->controls = talloc_realloc(ac, ac->controls, struct ldb_control *, i + 2); - - if (ac->controls == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->controls[i] = talloc(ac->controls, struct ldb_control); - if (ac->controls[i] == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->controls[i]->oid = LDB_CONTROL_ASQ_OID; - ac->controls[i]->critical = 0; - - asq = talloc_zero(ac->controls[i], struct ldb_asq_control); - if (asq == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - asq->result = ac->asq_ret; - - ac->controls[i]->data = asq; - - ac->controls[i + 1] = NULL; - - return ldb_module_done(ac->req, ac->controls, NULL, LDB_SUCCESS); -} - -static int asq_base_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct asq_context *ac; - int ret; - - ac = talloc_get_type(req->context, struct asq_context); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - ac->base_res = talloc_move(ac, &ares); - break; - - case LDB_REPLY_REFERRAL: - /* ignore referrals */ - talloc_free(ares); - break; - - case LDB_REPLY_DONE: - - talloc_free(ares); - - /* next step */ - ret = asq_search_continue(ac); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - break; - - } - return LDB_SUCCESS; -} - -static int asq_reqs_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct asq_context *ac; - int ret; - - ac = talloc_get_type(req->context, struct asq_context); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - /* pass the message up to the original callback as we - * do not have to elaborate on it any further */ - ret = ldb_module_send_entry(ac->req, ares->message, ares->controls); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - talloc_free(ares); - break; - - case LDB_REPLY_REFERRAL: - /* ignore referrals */ - talloc_free(ares); - break; - - case LDB_REPLY_DONE: - - talloc_free(ares); - - ret = asq_search_continue(ac); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - break; - } - - return LDB_SUCCESS; -} - -static int asq_build_first_request(struct asq_context *ac, struct ldb_request **base_req) -{ - struct ldb_context *ldb; - const char **base_attrs; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - ac->req_attrs = ac->req->op.search.attrs; - ac->req_attribute = talloc_strdup(ac, ac->asq_ctrl->source_attribute); - if (ac->req_attribute == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - base_attrs = talloc_array(ac, const char *, 2); - if (base_attrs == NULL) return LDB_ERR_OPERATIONS_ERROR; - - base_attrs[0] = talloc_strdup(base_attrs, ac->asq_ctrl->source_attribute); - if (base_attrs[0] == NULL) return LDB_ERR_OPERATIONS_ERROR; - - base_attrs[1] = NULL; - - ret = ldb_build_search_req(base_req, ldb, ac, - ac->req->op.search.base, - LDB_SCOPE_BASE, - NULL, - (const char * const *)base_attrs, - NULL, - ac, asq_base_callback, - ac->req); - if (ret != LDB_SUCCESS) { - return ret; - } - - return LDB_SUCCESS; -} - -static int asq_build_multiple_requests(struct asq_context *ac, bool *terminated) -{ - struct ldb_context *ldb; - struct ldb_control **saved_controls; - struct ldb_control *control; - struct ldb_dn *dn; - struct ldb_message_element *el; - unsigned int i; - int ret; - - if (ac->base_res == NULL) { - return LDB_ERR_NO_SUCH_OBJECT; - } - - ldb = ldb_module_get_ctx(ac->module); - - el = ldb_msg_find_element(ac->base_res->message, ac->req_attribute); - /* no values found */ - if (el == NULL) { - ac->asq_ret = ASQ_CTRL_SUCCESS; - *terminated = true; - return asq_search_terminate(ac); - } - - ac->num_reqs = el->num_values; - ac->cur_req = 0; - ac->reqs = talloc_array(ac, struct ldb_request *, ac->num_reqs); - if (ac->reqs == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - for (i = 0; i < el->num_values; i++) { - - dn = ldb_dn_new(ac, ldb, - (const char *)el->values[i].data); - if ( ! ldb_dn_validate(dn)) { - ac->asq_ret = ASQ_CTRL_INVALID_ATTRIBUTE_SYNTAX; - *terminated = true; - return asq_search_terminate(ac); - } - - ret = ldb_build_search_req_ex(&ac->reqs[i], - ldb, ac, - dn, LDB_SCOPE_BASE, - ac->req->op.search.tree, - ac->req_attrs, - ac->req->controls, - ac, asq_reqs_callback, - ac->req); - if (ret != LDB_SUCCESS) { - return ret; - } - - /* remove the ASQ control itself */ - control = ldb_request_get_control(ac->req, LDB_CONTROL_ASQ_OID); - if (!ldb_save_controls(control, ac->reqs[i], &saved_controls)) { - return LDB_ERR_OPERATIONS_ERROR; - } - } - - return LDB_SUCCESS; -} - -static int asq_search_continue(struct asq_context *ac) -{ - struct ldb_context *ldb; - bool terminated = false; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - switch (ac->step) { - case ASQ_SEARCH_BASE: - - /* build up the requests call chain */ - ret = asq_build_multiple_requests(ac, &terminated); - if (ret != LDB_SUCCESS || terminated) { - return ret; - } - - ac->step = ASQ_SEARCH_MULTI; - - return ldb_request(ldb, ac->reqs[ac->cur_req]); - - case ASQ_SEARCH_MULTI: - - ac->cur_req++; - - if (ac->cur_req == ac->num_reqs) { - /* done */ - return asq_search_terminate(ac); - } - - return ldb_request(ldb, ac->reqs[ac->cur_req]); - } - - return LDB_ERR_OPERATIONS_ERROR; -} - -static int asq_search(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - struct ldb_request *base_req; - struct ldb_control *control; - struct asq_context *ac; - int ret; - - ldb = ldb_module_get_ctx(module); - - /* check if there's an ASQ control */ - control = ldb_request_get_control(req, LDB_CONTROL_ASQ_OID); - if (control == NULL) { - /* not found go on */ - return ldb_next_request(module, req); - } - - ac = asq_context_init(module, req); - if (!ac) { - return LDB_ERR_OPERATIONS_ERROR; - } - - /* check the search is well formed */ - if (req->op.search.scope != LDB_SCOPE_BASE) { - ac->asq_ret = ASQ_CTRL_UNWILLING_TO_PERFORM; - return asq_search_terminate(ac); - } - - ac->asq_ctrl = talloc_get_type(control->data, struct ldb_asq_control); - if (!ac->asq_ctrl) { - return LDB_ERR_PROTOCOL_ERROR; - } - - ret = asq_build_first_request(ac, &base_req); - if (ret != LDB_SUCCESS) { - return ret; - } - - ac->step = ASQ_SEARCH_BASE; - - return ldb_request(ldb, base_req); -} - -static int asq_init(struct ldb_module *module) -{ - struct ldb_context *ldb; - int ret; - - ldb = ldb_module_get_ctx(module); - - ret = ldb_mod_register_control(module, LDB_CONTROL_ASQ_OID); - if (ret != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_WARNING, "asq: Unable to register control with rootdse!"); - } - - return ldb_next_init(module); -} - -static const struct ldb_module_ops ldb_asq_module_ops = { - .name = "asq", - .search = asq_search, - .init_context = asq_init -}; - -int ldb_asq_init(const char *version) -{ - LDB_MODULE_CHECK_VERSION(version); - return ldb_register_module(&ldb_asq_module_ops); -} diff --git a/ldb-2.0.8/modules/paged_searches.c b/ldb-2.0.8/modules/paged_searches.c deleted file mode 100644 index f8f3895..0000000 --- a/ldb-2.0.8/modules/paged_searches.c +++ /dev/null @@ -1,391 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005-2008 - Copyright (C) Andrew Bartlett 2009 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: paged_searches - * - * Component: ldb paged searches module - * - * Description: this module detects if the remote ldap server supports - * paged results and use them to transparently access all objects - * - * Author: Simo Sorce - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb_module.h" - -#define PS_DEFAULT_PAGE_SIZE 500 -/* 500 objects per query seem to be a decent compromise - * the default AD limit per request is 1000 entries */ - -struct private_data { - - bool paged_supported; -}; - -struct ps_context { - struct ldb_module *module; - struct ldb_request *req; - - bool pending; - - char **saved_referrals; - unsigned int num_referrals; - - struct ldb_request *down_req; -}; - -static int check_ps_continuation(struct ps_context *ac, struct ldb_request *req, struct ldb_reply *ares) -{ - struct ldb_context *ldb; - struct ldb_control *rep_control, *req_control; - struct ldb_paged_control *paged_rep_control = NULL, *paged_req_control = NULL; - ldb = ldb_module_get_ctx(ac->module); - - rep_control = ldb_reply_get_control(ares, LDB_CONTROL_PAGED_RESULTS_OID); - if (rep_control) { - paged_rep_control = talloc_get_type(rep_control->data, struct ldb_paged_control); - } - - req_control = ldb_request_get_control(req, LDB_CONTROL_PAGED_RESULTS_OID); - if (req_control == NULL) { - ldb_set_errstring(ldb, "paged_searches: control is missing"); - return LDB_ERR_OPERATIONS_ERROR; - } - - paged_req_control = talloc_get_type(req_control->data, struct ldb_paged_control); - - if (!rep_control || !paged_rep_control) { - if (paged_req_control->cookie) { - /* something wrong here - why give us a control back befre, but not one now? */ - ldb_set_errstring(ldb, "paged_searches: ERROR: We got back a control from a previous page, but this time no control was returned!"); - return LDB_ERR_OPERATIONS_ERROR; - } else { - /* No cookie received yet, valid to just return the full data set */ - - /* we are done */ - ac->pending = false; - return LDB_SUCCESS; - } - } - - if (paged_rep_control->cookie_len == 0) { - /* we are done */ - ac->pending = false; - return LDB_SUCCESS; - } - - /* more processing required */ - /* let's fill in the request control with the new cookie */ - /* if there's a reply control we must find a request - * control matching it */ - - if (paged_req_control->cookie) { - talloc_free(paged_req_control->cookie); - } - - paged_req_control->cookie = talloc_memdup(req_control, - paged_rep_control->cookie, - paged_rep_control->cookie_len); - paged_req_control->cookie_len = paged_rep_control->cookie_len; - - ac->pending = true; - return LDB_SUCCESS; -} - -static int store_referral(struct ps_context *ac, char *referral) -{ - ac->saved_referrals = talloc_realloc(ac, ac->saved_referrals, char *, ac->num_referrals + 2); - if (!ac->saved_referrals) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->saved_referrals[ac->num_referrals] = talloc_strdup(ac->saved_referrals, referral); - if (!ac->saved_referrals[ac->num_referrals]) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->num_referrals++; - ac->saved_referrals[ac->num_referrals] = NULL; - - return LDB_SUCCESS; -} - -static int send_referrals(struct ps_context *ac) -{ - struct ldb_reply *ares; - int ret; - unsigned int i; - - for (i = 0; i < ac->num_referrals; i++) { - ares = talloc_zero(ac->req, struct ldb_reply); - if (!ares) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ares->type = LDB_REPLY_REFERRAL; - ares->referral = ac->saved_referrals[i]; - - ret = ldb_module_send_referral(ac->req, ares->referral); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - return LDB_SUCCESS; -} - -static int ps_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct ps_context *ac; - int ret; - - ac = talloc_get_type(req->context, struct ps_context); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - ret = ldb_module_send_entry(ac->req, ares->message, ares->controls); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - break; - - case LDB_REPLY_REFERRAL: - ret = store_referral(ac, ares->referral); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - break; - - case LDB_REPLY_DONE: - - ret = check_ps_continuation(ac, req, ares); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - - if (ac->pending) { - - ret = ldb_next_request(ac->module, ac->down_req); - - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, - NULL, NULL, ret); - } - - } else { - - /* send referrals */ - ret = send_referrals(ac); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, - NULL, NULL, ret); - } - - /* send REPLY_DONE */ - return ldb_module_done(ac->req, ares->controls, - ares->response, LDB_SUCCESS); - } - break; - } - - talloc_free(ares); - return LDB_SUCCESS; -} - -static int ps_search(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - struct private_data *private_data; - struct ps_context *ac; - struct ldb_paged_control *control; - int ret; - - private_data = talloc_get_type(ldb_module_get_private(module), struct private_data); - ldb = ldb_module_get_ctx(module); - - /* check if paging is supported */ - if (!private_data || !private_data->paged_supported) { - /* do not touch this request paged controls not - * supported or we - * are just not setup yet */ - return ldb_next_request(module, req); - } - - ac = talloc_zero(req, struct ps_context); - if (ac == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - ac->pending = false; - ac->saved_referrals = NULL; - ac->num_referrals = 0; - - ldb = ldb_module_get_ctx(ac->module); - - control = talloc(ac, struct ldb_paged_control); - if (!control) { - return LDB_ERR_OPERATIONS_ERROR; - } - - control->size = PS_DEFAULT_PAGE_SIZE; - control->cookie = NULL; - control->cookie_len = 0; - - ret = ldb_build_search_req_ex(&ac->down_req, ldb, ac, - ac->req->op.search.base, - ac->req->op.search.scope, - ac->req->op.search.tree, - ac->req->op.search.attrs, - ac->req->controls, - ac, - ps_callback, - ac->req); - LDB_REQ_SET_LOCATION(ac->down_req); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_request_add_control(ac->down_req, LDB_CONTROL_PAGED_RESULTS_OID, - true, control); - if (ret != LDB_SUCCESS) { - return ret; - } - - talloc_steal(ac->down_req, control); - - return ldb_next_request(ac->module, ac->down_req); -} - -static int check_supported_paged(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct private_data *data; - - data = talloc_get_type(req->context, struct private_data); - - if (!ares) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - if (ldb_msg_check_string_attribute(ares->message, - "supportedControl", - LDB_CONTROL_PAGED_RESULTS_OID)) { - data->paged_supported = true; - } - break; - - case LDB_REPLY_REFERRAL: - /* ignore */ - break; - - case LDB_REPLY_DONE: - return ldb_request_done(req, LDB_SUCCESS); - } - - talloc_free(ares); - return LDB_SUCCESS; -} - -static int ps_init(struct ldb_module *module) -{ - struct ldb_context *ldb; - static const char *attrs[] = { "supportedControl", NULL }; - struct private_data *data; - struct ldb_dn *base; - int ret; - struct ldb_request *req; - - ldb = ldb_module_get_ctx(module); - - data = talloc(module, struct private_data); - if (data == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - data->paged_supported = false; - - ldb_module_set_private(module, data); - - base = ldb_dn_new(module, ldb, ""); - if (base == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - ret = ldb_build_search_req(&req, ldb, module, - base, LDB_SCOPE_BASE, - "(objectClass=*)", - attrs, NULL, - data, check_supported_paged, - NULL); - LDB_REQ_SET_LOCATION(req); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_next_request(module, req); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - if (ret != LDB_SUCCESS) { - return ret; - } - - talloc_free(base); - talloc_free(req); - - return ldb_next_init(module); -} - -static const struct ldb_module_ops ldb_paged_searches_module_ops = { - .name = "paged_searches", - .search = ps_search, - .init_context = ps_init -}; - -int ldb_paged_searches_init(const char *version) -{ - LDB_MODULE_CHECK_VERSION(version); - return ldb_register_module(&ldb_paged_searches_module_ops); -} diff --git a/ldb-2.0.8/modules/rdn_name.c b/ldb-2.0.8/modules/rdn_name.c deleted file mode 100644 index e69ad93..0000000 --- a/ldb-2.0.8/modules/rdn_name.c +++ /dev/null @@ -1,610 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Bartlett 2005-2009 - Copyright (C) Simo Sorce 2006-2008 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: rdn_name - * - * Component: ldb rdn name module - * - * Description: keep a consistent name attribute on objects manpulations - * - * Author: Andrew Bartlett - * - * Modifications: - * - made the module async - * Simo Sorce Mar 2006 - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb_module.h" - -struct rename_context { - struct ldb_module *module; - struct ldb_request *req; - - struct ldb_reply *ares; -}; - -static int rdn_name_add_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct rename_context *ac; - - ac = talloc_get_type(req->context, struct rename_context); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - if (ares->type == LDB_REPLY_REFERRAL) { - return ldb_module_send_referral(ac->req, ares->referral); - } - - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - if (ares->type != LDB_REPLY_DONE) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - return ldb_module_done(ac->req, ares->controls, - ares->response, LDB_SUCCESS); -} - -static int rdn_name_add(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - struct ldb_request *down_req; - struct rename_context *ac; - struct ldb_message *msg; - struct ldb_message_element *attribute; - const struct ldb_schema_attribute *a; - const char *rdn_name; - const struct ldb_val *rdn_val_p; - struct ldb_val rdn_val; - unsigned int i; - int ret; - - ldb = ldb_module_get_ctx(module); - - /* do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.add.message->dn)) { - return ldb_next_request(module, req); - } - - ac = talloc_zero(req, struct rename_context); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - - msg = ldb_msg_copy_shallow(req, req->op.add.message); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - rdn_name = ldb_dn_get_rdn_name(msg->dn); - if (rdn_name == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - rdn_val_p = ldb_dn_get_rdn_val(msg->dn); - if (rdn_val_p == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - if (rdn_val_p->length == 0) { - ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", - ldb_dn_get_linearized(req->op.add.message->dn)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - rdn_val = ldb_val_dup(msg, rdn_val_p); - - /* Perhaps someone above us tried to set this? Then ignore it */ - ldb_msg_remove_attr(msg, "name"); - - ret = ldb_msg_add_value(msg, "name", &rdn_val, NULL); - if (ret != LDB_SUCCESS) { - return ret; - } - - a = ldb_schema_attribute_by_name(ldb, rdn_name); - if (a == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - attribute = ldb_msg_find_element(msg, rdn_name); - if (!attribute) { - /* add entry with normalised RDN information if possible */ - if (a->name != NULL && strcmp(a->name, "*") != 0) { - ret = ldb_msg_add_value(msg, a->name, &rdn_val, NULL); - } else { - ret = ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL); - } - if (ret != LDB_SUCCESS) { - return ret; - } - } else { - /* normalise attribute name if possible */ - if (a->name != NULL && strcmp(a->name, "*") != 0) { - attribute->name = a->name; - } - /* normalise attribute value */ - for (i = 0; i < attribute->num_values; i++) { - bool matched; - if (a->syntax->operator_fn) { - ret = a->syntax->operator_fn(ldb, LDB_OP_EQUALITY, a, - &rdn_val, &attribute->values[i], &matched); - if (ret != LDB_SUCCESS) return ret; - } else { - matched = (a->syntax->comparison_fn(ldb, msg, - &rdn_val, &attribute->values[i]) == 0); - } - if (matched) { - /* overwrite so it matches in case */ - attribute->values[i] = rdn_val; - break; - } - } - if (i == attribute->num_values) { - char *rdn_errstring = talloc_asprintf(ac, - "RDN mismatch on %s: %s (%.*s) should match one of:", - ldb_dn_get_linearized(msg->dn), rdn_name, - (int)rdn_val.length, (const char *)rdn_val.data); - for (i = 0; i < attribute->num_values; i++) { - rdn_errstring = talloc_asprintf_append( - rdn_errstring, " (%.*s)", - (int)attribute->values[i].length, - (const char *)attribute->values[i].data); - } - ldb_set_errstring(ldb, rdn_errstring); - /* Match AD's error here */ - return LDB_ERR_INVALID_DN_SYNTAX; - } - } - - ret = ldb_build_add_req(&down_req, ldb, req, - msg, - req->controls, - ac, rdn_name_add_callback, - req); - if (ret != LDB_SUCCESS) { - return ret; - } - - talloc_steal(down_req, msg); - - /* go on with the call chain */ - return ldb_next_request(module, down_req); -} - -static int rdn_modify_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct rename_context *ac; - - ac = talloc_get_type(req->context, struct rename_context); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - if (ares->type == LDB_REPLY_REFERRAL) { - return ldb_module_send_referral(ac->req, ares->referral); - } - - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - /* the only supported reply right now is a LDB_REPLY_DONE */ - if (ares->type != LDB_REPLY_DONE) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - /* send saved controls eventually */ - return ldb_module_done(ac->req, ac->ares->controls, - ac->ares->response, LDB_SUCCESS); -} - -static int rdn_rename_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct ldb_context *ldb; - struct rename_context *ac; - struct ldb_request *mod_req; - const char *rdn_name; - const struct ldb_schema_attribute *a = NULL; - const struct ldb_val *rdn_val_p; - struct ldb_val rdn_val; - struct ldb_message *msg; - int ret; - - ac = talloc_get_type(req->context, struct rename_context); - ldb = ldb_module_get_ctx(ac->module); - - if (!ares) { - goto error; - } - - if (ares->type == LDB_REPLY_REFERRAL) { - return ldb_module_send_referral(ac->req, ares->referral); - } - - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - /* the only supported reply right now is a LDB_REPLY_DONE */ - if (ares->type != LDB_REPLY_DONE) { - goto error; - } - - /* save reply for caller */ - ac->ares = talloc_steal(ac, ares); - - msg = ldb_msg_new(ac); - if (msg == NULL) { - goto error; - } - msg->dn = ldb_dn_copy(msg, ac->req->op.rename.newdn); - if (msg->dn == NULL) { - goto error; - } - - rdn_name = ldb_dn_get_rdn_name(ac->req->op.rename.newdn); - if (rdn_name == NULL) { - goto error; - } - - a = ldb_schema_attribute_by_name(ldb, rdn_name); - if (a == NULL) { - goto error; - } - - if (a->name != NULL && strcmp(a->name, "*") != 0) { - rdn_name = a->name; - } - - rdn_val_p = ldb_dn_get_rdn_val(msg->dn); - if (rdn_val_p == NULL) { - goto error; - } - if (rdn_val_p->length == 0) { - ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", - ldb_dn_get_linearized(req->op.rename.olddn)); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_NAMING_VIOLATION); - } - rdn_val = ldb_val_dup(msg, rdn_val_p); - - if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) { - goto error; - } - if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) { - goto error; - } - if (ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_REPLACE, NULL) != 0) { - goto error; - } - if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) { - goto error; - } - - ret = ldb_build_mod_req(&mod_req, ldb, - ac, msg, NULL, - ac, rdn_modify_callback, - req); - if (ret != LDB_SUCCESS) { - return ldb_module_done(ac->req, NULL, NULL, ret); - } - talloc_steal(mod_req, msg); - - /* go on with the call chain */ - return ldb_next_request(ac->module, mod_req); - -error: - return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); -} - -static int rdn_name_rename(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - struct rename_context *ac; - struct ldb_request *down_req; - int ret; - - ldb = ldb_module_get_ctx(module); - - /* do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.rename.newdn)) { - return ldb_next_request(module, req); - } - - ac = talloc_zero(req, struct rename_context); - if (ac == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - - ret = ldb_build_rename_req(&down_req, - ldb, - ac, - req->op.rename.olddn, - req->op.rename.newdn, - req->controls, - ac, - rdn_rename_callback, - req); - - if (ret != LDB_SUCCESS) { - return ret; - } - - /* rename first, modify "name" if rename is ok */ - return ldb_next_request(module, down_req); -} - -static int rdn_recalculate_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct ldb_request *up_req = talloc_get_type(req->context, struct ldb_request); - - talloc_steal(up_req, req); - return up_req->callback(up_req, ares); -} - -static int rdn_name_modify(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - const struct ldb_val *rdn_val_p; - struct ldb_message_element *e = NULL; - struct ldb_control *recalculate_rdn_control = NULL; - - ldb = ldb_module_get_ctx(module); - - /* do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.mod.message->dn)) { - return ldb_next_request(module, req); - } - - recalculate_rdn_control = ldb_request_get_control(req, - LDB_CONTROL_RECALCULATE_RDN_OID); - if (recalculate_rdn_control != NULL) { - struct ldb_message *msg = NULL; - const char *rdn_name = NULL; - struct ldb_val rdn_val; - const struct ldb_schema_attribute *a = NULL; - struct ldb_request *mod_req = NULL; - int ret; - struct ldb_message_element *rdn_del = NULL; - struct ldb_message_element *name_del = NULL; - - recalculate_rdn_control->critical = false; - - msg = ldb_msg_copy_shallow(req, req->op.mod.message); - if (msg == NULL) { - return ldb_module_oom(module); - } - - /* - * The caller must pass a dummy 'name' attribute - * in order to bypass some high level checks. - * - * We just remove it and check nothing is left. - */ - ldb_msg_remove_attr(msg, "name"); - - if (msg->num_elements != 0) { - return ldb_module_operr(module); - } - - rdn_name = ldb_dn_get_rdn_name(msg->dn); - if (rdn_name == NULL) { - return ldb_module_oom(module); - } - - a = ldb_schema_attribute_by_name(ldb, rdn_name); - if (a == NULL) { - return ldb_module_operr(module); - } - - if (a->name != NULL && strcmp(a->name, "*") != 0) { - rdn_name = a->name; - } - - rdn_val_p = ldb_dn_get_rdn_val(msg->dn); - if (rdn_val_p == NULL) { - return ldb_module_oom(module); - } - rdn_val = ldb_val_dup(msg, rdn_val_p); - if (rdn_val.length == 0) { - return ldb_module_oom(module); - } - - /* - * This is a bit tricky: - * - * We want _DELETE elements (as "rdn_del" and "name_del" without - * values) first, followed by _ADD (with the real names) - * elements (with values). Then we fix up the "rdn_del" and - * "name_del" attributes. - */ - - ret = ldb_msg_add_empty(msg, "rdn_del", LDB_FLAG_MOD_DELETE, NULL); - if (ret != 0) { - return ldb_module_oom(module); - } - ret = ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_ADD, NULL); - if (ret != 0) { - return ldb_module_oom(module); - } - ret = ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL); - if (ret != 0) { - return ldb_module_oom(module); - } - - ret = ldb_msg_add_empty(msg, "name_del", LDB_FLAG_MOD_DELETE, NULL); - if (ret != 0) { - return ldb_module_oom(module); - } - ret = ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_ADD, NULL); - if (ret != 0) { - return ldb_module_oom(module); - } - ret = ldb_msg_add_value(msg, "name", &rdn_val, NULL); - if (ret != 0) { - return ldb_module_oom(module); - } - - rdn_del = ldb_msg_find_element(msg, "rdn_del"); - if (rdn_del == NULL) { - return ldb_module_operr(module); - } - rdn_del->name = talloc_strdup(msg->elements, rdn_name); - if (rdn_del->name == NULL) { - return ldb_module_oom(module); - } - name_del = ldb_msg_find_element(msg, "name_del"); - if (name_del == NULL) { - return ldb_module_operr(module); - } - name_del->name = talloc_strdup(msg->elements, "name"); - if (name_del->name == NULL) { - return ldb_module_oom(module); - } - - ret = ldb_build_mod_req(&mod_req, ldb, - req, msg, NULL, - req, rdn_recalculate_callback, - req); - if (ret != LDB_SUCCESS) { - return ldb_module_done(req, NULL, NULL, ret); - } - talloc_steal(mod_req, msg); - - ret = ldb_request_add_control(mod_req, - LDB_CONTROL_RECALCULATE_RDN_OID, - false, NULL); - if (ret != LDB_SUCCESS) { - return ldb_module_done(req, NULL, NULL, ret); - } - ret = ldb_request_add_control(mod_req, - LDB_CONTROL_PERMISSIVE_MODIFY_OID, - false, NULL); - if (ret != LDB_SUCCESS) { - return ldb_module_done(req, NULL, NULL, ret); - } - - /* go on with the call chain */ - return ldb_next_request(module, mod_req); - } - - rdn_val_p = ldb_dn_get_rdn_val(req->op.mod.message->dn); - if (rdn_val_p == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - if (rdn_val_p->length == 0) { - ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", - ldb_dn_get_linearized(req->op.mod.message->dn)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - e = ldb_msg_find_element(req->op.mod.message, "distinguishedName"); - if (e != NULL) { - ldb_asprintf_errstring(ldb, "Modify of 'distinguishedName' on %s not permitted, must use 'rename' operation instead", - ldb_dn_get_linearized(req->op.mod.message->dn)); - if (e->flags == LDB_FLAG_MOD_REPLACE) { - return LDB_ERR_CONSTRAINT_VIOLATION; - } else { - return LDB_ERR_UNWILLING_TO_PERFORM; - } - } - - if (ldb_msg_find_element(req->op.mod.message, "name")) { - ldb_asprintf_errstring(ldb, "Modify of 'name' on %s not permitted, must use 'rename' operation instead", - ldb_dn_get_linearized(req->op.mod.message->dn)); - return LDB_ERR_NOT_ALLOWED_ON_RDN; - } - - if (ldb_msg_find_element(req->op.mod.message, ldb_dn_get_rdn_name(req->op.mod.message->dn))) { - ldb_asprintf_errstring(ldb, "Modify of RDN '%s' on %s not permitted, must use 'rename' operation instead", - ldb_dn_get_rdn_name(req->op.mod.message->dn), ldb_dn_get_linearized(req->op.mod.message->dn)); - return LDB_ERR_NOT_ALLOWED_ON_RDN; - } - - /* All OK, they kept their fingers out of the special attributes */ - return ldb_next_request(module, req); -} - -static int rdn_name_search(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_context *ldb; - const char *rdn_name; - const struct ldb_val *rdn_val_p; - - ldb = ldb_module_get_ctx(module); - - /* do not manipulate our control entries */ - if (ldb_dn_is_special(req->op.search.base)) { - return ldb_next_request(module, req); - } - - rdn_name = ldb_dn_get_rdn_name(req->op.search.base); - rdn_val_p = ldb_dn_get_rdn_val(req->op.search.base); - if ((rdn_name != NULL) && (rdn_val_p == NULL)) { - return LDB_ERR_OPERATIONS_ERROR; - } - if ((rdn_val_p != NULL) && (rdn_val_p->length == 0)) { - ldb_asprintf_errstring(ldb, "Empty RDN value on %s not permitted!", - ldb_dn_get_linearized(req->op.search.base)); - return LDB_ERR_INVALID_DN_SYNTAX; - } - - return ldb_next_request(module, req); -} - -static const struct ldb_module_ops ldb_rdn_name_module_ops = { - .name = "rdn_name", - .add = rdn_name_add, - .modify = rdn_name_modify, - .rename = rdn_name_rename, - .search = rdn_name_search -}; - -int ldb_rdn_name_init(const char *version) -{ - LDB_MODULE_CHECK_VERSION(version); - return ldb_register_module(&ldb_rdn_name_module_ops); -} diff --git a/ldb-2.0.8/modules/skel.c b/ldb-2.0.8/modules/skel.c deleted file mode 100644 index 1ce3ec1..0000000 --- a/ldb-2.0.8/modules/skel.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb skel module - * - * Description: example module - * - * Author: Simo Sorce - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb_module.h" - -struct private_data { - - char *some_private_data; -}; - -/* search */ -static int skel_search(struct ldb_module *module, struct ldb_request *req) -{ - return ldb_next_request(module, req); -} - -/* add */ -static int skel_add(struct ldb_module *module, struct ldb_request *req){ - return ldb_next_request(module, req); -} - -/* modify */ -static int skel_modify(struct ldb_module *module, struct ldb_request *req) -{ - return ldb_next_request(module, req); -} - -/* delete */ -static int skel_delete(struct ldb_module *module, struct ldb_request *req) -{ - return ldb_next_request(module, req); -} - -/* rename */ -static int skel_rename(struct ldb_module *module, struct ldb_request *req) -{ - return ldb_next_request(module, req); -} - -/* start a transaction */ -static int skel_start_trans(struct ldb_module *module) -{ - return ldb_next_start_trans(module); -} - -/* end a transaction */ -static int skel_end_trans(struct ldb_module *module) -{ - return ldb_next_end_trans(module); -} - -/* delete a transaction */ -static int skel_del_trans(struct ldb_module *module) -{ - return ldb_next_del_trans(module); -} - -static int skel_destructor(struct ldb_module *ctx) -{ - struct private_data *data; - - data = talloc_get_type(ldb_module_get_private(ctx), struct private_data); - - /* put your clean-up functions here */ - if (data->some_private_data) talloc_free(data->some_private_data); - - return 0; -} - -static int skel_request(struct ldb_module *module, struct ldb_request *req) -{ - return ldb_next_request(module, req); -} - -static int skel_init(struct ldb_module *module) -{ - struct ldb_context *ldb; - struct private_data *data; - - ldb = ldb_module_get_ctx(module); - - data = talloc(module, struct private_data); - if (data == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - data->some_private_data = NULL; - ldb_module_set_private(module, data); - - talloc_set_destructor (module, skel_destructor); - - return ldb_next_init(module); -} - -static const struct ldb_module_ops ldb_skel_module_ops = { - .name = "skel", - .init_context = skel_init, - .search = skel_search, - .add = skel_add, - .modify = skel_modify, - .del = skel_delete, - .rename = skel_rename, - .request = skel_request, - .start_transaction = skel_start_trans, - .end_transaction = skel_end_trans, - .del_transaction = skel_del_trans, -}; - -int ldb_skel_init(const char *version) -{ - LDB_MODULE_CHECK_VERSION(version); - return ldb_register_module(&ldb_skel_module_ops); -} diff --git a/ldb-2.0.8/modules/sort.c b/ldb-2.0.8/modules/sort.c deleted file mode 100644 index cb6f8df..0000000 --- a/ldb-2.0.8/modules/sort.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - ldb database library - - Copyright (C) Simo Sorce 2005-2008 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldb server side sort control module - * - * Description: this module sorts the results of a search - * - * Author: Simo Sorce - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb_module.h" - -struct opaque { - struct ldb_context *ldb; - const struct ldb_attrib_handler *h; - const char *attribute; - int reverse; - int result; -}; - -struct sort_context { - struct ldb_module *module; - - const char *attributeName; - const char *orderingRule; - int reverse; - - struct ldb_request *req; - struct ldb_message **msgs; - char **referrals; - unsigned int num_msgs; - unsigned int num_refs; - const char *extra_sort_key; - - const struct ldb_schema_attribute *a; - int sort_result; -}; - -static int build_response(void *mem_ctx, struct ldb_control ***ctrls, int result, const char *desc) -{ - struct ldb_control **controls; - struct ldb_sort_resp_control *resp; - unsigned int i; - - if (*ctrls) { - controls = *ctrls; - for (i = 0; controls[i]; i++); - controls = talloc_realloc(mem_ctx, controls, struct ldb_control *, i + 2); - } else { - i = 0; - controls = talloc_array(mem_ctx, struct ldb_control *, 2); - } - if (! controls ) - return LDB_ERR_OPERATIONS_ERROR; - - *ctrls = controls; - - controls[i+1] = NULL; - controls[i] = talloc(controls, struct ldb_control); - if (! controls[i] ) - return LDB_ERR_OPERATIONS_ERROR; - - controls[i]->oid = LDB_CONTROL_SORT_RESP_OID; - controls[i]->critical = 0; - - resp = talloc(controls[i], struct ldb_sort_resp_control); - if (! resp ) - return LDB_ERR_OPERATIONS_ERROR; - - resp->result = result; - resp->attr_desc = talloc_strdup(resp, desc); - - if (! resp->attr_desc ) - return LDB_ERR_OPERATIONS_ERROR; - - controls[i]->data = resp; - - return LDB_SUCCESS; -} - -static int sort_compare(struct ldb_message **msg1, struct ldb_message **msg2, void *opaque) -{ - struct sort_context *ac = talloc_get_type(opaque, struct sort_context); - struct ldb_message_element *el1, *el2; - struct ldb_context *ldb; - - ldb = ldb_module_get_ctx(ac->module); - - if (ac->sort_result != 0) { - /* an error occurred previously, - * let's exit the sorting by returning always 0 */ - return 0; - } - - el1 = ldb_msg_find_element(*msg1, ac->attributeName); - el2 = ldb_msg_find_element(*msg2, ac->attributeName); - - if (!el1 && el2) { - return 1; - } - if (el1 && !el2) { - return -1; - } - if (!el1 && !el2) { - return 0; - } - - if (ac->reverse) - return ac->a->syntax->comparison_fn(ldb, ac, &el2->values[0], &el1->values[0]); - - return ac->a->syntax->comparison_fn(ldb, ac, &el1->values[0], &el2->values[0]); -} - -static int server_sort_results(struct sort_context *ac) -{ - struct ldb_context *ldb; - struct ldb_reply *ares; - unsigned int i; - int ret; - - ldb = ldb_module_get_ctx(ac->module); - - ac->a = ldb_schema_attribute_by_name(ldb, ac->attributeName); - ac->sort_result = 0; - - LDB_TYPESAFE_QSORT(ac->msgs, ac->num_msgs, ac, sort_compare); - - if (ac->sort_result != LDB_SUCCESS) { - return ac->sort_result; - } - - for (i = 0; i < ac->num_msgs; i++) { - ares = talloc_zero(ac, struct ldb_reply); - if (!ares) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ares->type = LDB_REPLY_ENTRY; - ares->message = talloc_move(ares, &ac->msgs[i]); - if (ac->extra_sort_key) { - ldb_msg_remove_attr(ares->message, ac->extra_sort_key); - } - ret = ldb_module_send_entry(ac->req, ares->message, ares->controls); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - for (i = 0; i < ac->num_refs; i++) { - ares = talloc_zero(ac, struct ldb_reply); - if (!ares) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ares->type = LDB_REPLY_REFERRAL; - ares->referral = talloc_move(ares, &ac->referrals[i]); - - ret = ldb_module_send_referral(ac->req, ares->referral); - if (ret != LDB_SUCCESS) { - return ret; - } - } - - return LDB_SUCCESS; -} - -static int server_sort_search_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct sort_context *ac; - struct ldb_context *ldb; - int ret; - - ac = talloc_get_type(req->context, struct sort_context); - ldb = ldb_module_get_ctx(ac->module); - - if (!ares) { - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(ac->req, ares->controls, - ares->response, ares->error); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - ac->msgs = talloc_realloc(ac, ac->msgs, struct ldb_message *, ac->num_msgs + 2); - if (! ac->msgs) { - talloc_free(ares); - ldb_oom(ldb); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - ac->msgs[ac->num_msgs] = talloc_steal(ac->msgs, ares->message); - ac->num_msgs++; - ac->msgs[ac->num_msgs] = NULL; - - break; - - case LDB_REPLY_REFERRAL: - ac->referrals = talloc_realloc(ac, ac->referrals, char *, ac->num_refs + 2); - if (! ac->referrals) { - talloc_free(ares); - ldb_oom(ldb); - return ldb_module_done(ac->req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - ac->referrals[ac->num_refs] = talloc_steal(ac->referrals, ares->referral); - ac->num_refs++; - ac->referrals[ac->num_refs] = NULL; - - break; - - case LDB_REPLY_DONE: - - ret = server_sort_results(ac); - return ldb_module_done(ac->req, ares->controls, - ares->response, ret); - } - - talloc_free(ares); - return LDB_SUCCESS; -} - -static int server_sort_search(struct ldb_module *module, struct ldb_request *req) -{ - struct ldb_control *control; - struct ldb_server_sort_control **sort_ctrls; - struct ldb_control **saved_controls; - struct ldb_request *down_req; - struct sort_context *ac; - struct ldb_context *ldb; - int ret; - const char * const *attrs; - size_t n_attrs, i; - const char *sort_attr; - - ldb = ldb_module_get_ctx(module); - - /* check if there's a server sort control */ - control = ldb_request_get_control(req, LDB_CONTROL_SERVER_SORT_OID); - if (control == NULL) { - /* not found go on */ - return ldb_next_request(module, req); - } - - ac = talloc_zero(req, struct sort_context); - if (ac == NULL) { - ldb_oom(ldb); - return LDB_ERR_OPERATIONS_ERROR; - } - - ac->module = module; - ac->req = req; - - sort_ctrls = talloc_get_type(control->data, struct ldb_server_sort_control *); - if (!sort_ctrls) { - return LDB_ERR_PROTOCOL_ERROR; - } - - /* FIXME: we do not support more than one attribute for sorting right now */ - /* FIXME: we need to check if the attribute type exist or return an error */ - - if (sort_ctrls[1] != NULL) { - if (control->critical) { - struct ldb_control **controls = NULL; - - /* callback immediately */ - ret = build_response(req, &controls, - LDB_ERR_UNWILLING_TO_PERFORM, - "sort control is not complete yet"); - if (ret != LDB_SUCCESS) { - return ldb_module_done(req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - return ldb_module_done(req, controls, NULL, ret); - } else { - /* just pass the call down and don't do any sorting */ - return ldb_next_request(module, req); - } - } - - control->critical = 0; - - /* We are asked to sort on an attribute, and if that attribute is not - already in the search attributes we need to add it (and later - remove it on the return journey). - */ - sort_attr = sort_ctrls[0]->attributeName; - if (req->op.search.attrs == NULL) { - /* This means all non-operational attributes, which means - there's nothing to add. */ - attrs = NULL; - } else { - n_attrs = 0; - while (req->op.search.attrs[n_attrs] != NULL) { - if (sort_attr && - strcmp(req->op.search.attrs[n_attrs], sort_attr) == 0) { - sort_attr = NULL; - } - n_attrs++; - } - - if (sort_attr == NULL) { - attrs = req->op.search.attrs; - } else { - const char **tmp = talloc_array(ac, const char *, n_attrs + 2); - - for (i = 0; i < n_attrs; i++) { - tmp[i] = req->op.search.attrs[i]; - } - ac->extra_sort_key = sort_attr; - tmp[n_attrs] = sort_attr; - tmp[n_attrs + 1] = NULL; - attrs = tmp; - } - } - - ac->attributeName = sort_ctrls[0]->attributeName; - ac->orderingRule = sort_ctrls[0]->orderingRule; - ac->reverse = sort_ctrls[0]->reverse; - - ret = ldb_build_search_req_ex(&down_req, ldb, ac, - req->op.search.base, - req->op.search.scope, - req->op.search.tree, - attrs, - req->controls, - ac, - server_sort_search_callback, - req); - if (ret != LDB_SUCCESS) { - return ret; - } - - /* save it locally and remove it from the list */ - /* we do not need to replace them later as we - * are keeping the original req intact */ - if (!ldb_save_controls(control, down_req, &saved_controls)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - return ldb_next_request(module, down_req); -} - -static int server_sort_init(struct ldb_module *module) -{ - struct ldb_context *ldb; - int ret; - - ldb = ldb_module_get_ctx(module); - - ret = ldb_mod_register_control(module, LDB_CONTROL_SERVER_SORT_OID); - if (ret != LDB_SUCCESS) { - ldb_debug(ldb, LDB_DEBUG_WARNING, - "server_sort:" - "Unable to register control with rootdse!"); - } - - return ldb_next_init(module); -} - -static const struct ldb_module_ops ldb_server_sort_module_ops = { - .name = "server_sort", - .search = server_sort_search, - .init_context = server_sort_init -}; - -int ldb_server_sort_init(const char *version) -{ - LDB_MODULE_CHECK_VERSION(version); - return ldb_register_module(&ldb_server_sort_module_ops); -} diff --git a/ldb-2.0.8/nssldb/README.txt b/ldb-2.0.8/nssldb/README.txt deleted file mode 100644 index ddba62b..0000000 --- a/ldb-2.0.8/nssldb/README.txt +++ /dev/null @@ -1,34 +0,0 @@ - -This test code requires a tdb that is configured for to use the asq module. -You can do that adding the following record to a tdb: - -dn: @MODULES -@LIST: asq - -Other modules can be used as well (like rdn_name for example) - -The uidNumber 0 and the gidNumber 0 are considered invalid. - -The user records should contain the followin attributes: -uid (required) the user name -userPassword (optional) the user password (if not present "LDB" is - returned in the password field) -uidNumber (required) the user uid -gidNumber (required) the user primary gid -gecos (optional) the GECOS -homeDirectory (required) the home directory -loginShell (required) the login shell -memberOf (required) all the groups the user is member of should - be reported here using their DNs. The - primary group as well. - -The group accounts should contain the following attributes: -cn (required) the group name -uesrPassword (optional) the group password (if not present "LDB" is - returned in the password field) -gidNumber (required) the group gid -member (optional) the DNs of the member users, also the ones - that have this group as primary - - -SSS diff --git a/ldb-2.0.8/nssldb/ldb-grp.c b/ldb-2.0.8/nssldb/ldb-grp.c deleted file mode 100644 index 5e7556d..0000000 --- a/ldb-2.0.8/nssldb/ldb-grp.c +++ /dev/null @@ -1,429 +0,0 @@ -/* - LDB nsswitch module - - Copyright (C) Simo Sorce 2006 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "ldb-nss.h" - -extern struct _ldb_nss_context *_ldb_nss_ctx; - -const char *_ldb_nss_gr_attrs[] = { - "cn", - "userPassword", - "gidNumber", - NULL -}; - -const char *_ldb_nss_mem_attrs[] = { - "uid", - NULL -}; - -#define _NSS_LDB_ENOMEM(amem) \ - do { \ - if ( ! amem) { \ - errno = ENOMEM; \ - talloc_free(memctx); \ - return NSS_STATUS_UNAVAIL; \ - } \ - } while(0) - -/* This setgrent, getgrent, endgrent is not very efficient */ - -NSS_STATUS _nss_ldb_setgrent(void) -{ - int ret; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - _ldb_nss_ctx->gr_cur = 0; - if (_ldb_nss_ctx->gr_res != NULL) { - talloc_free(_ldb_nss_ctx->gr_res); - _ldb_nss_ctx->gr_res = NULL; - } - - ret = ldb_search(_ldb_nss_ctx->ldb, - _ldb_nss_ctx->ldb, - &_ldb_nss_ctx->gr_res, - _ldb_nss_ctx->base, - LDB_SCOPE_SUBTREE, - _ldb_nss_gr_attrs, - _LDB_NSS_GRENT_FILTER); - if (ret != LDB_SUCCESS) { - return NSS_STATUS_UNAVAIL; - } - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _nss_ldb_endgrent(void) -{ - int ret; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - _ldb_nss_ctx->gr_cur = 0; - if (_ldb_nss_ctx->gr_res) { - talloc_free(_ldb_nss_ctx->gr_res); - _ldb_nss_ctx->gr_res = NULL; - } - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _nss_ldb_getgrent_r(struct group *result_buf, char *buffer, size_t buflen, int *errnop) -{ - int ret; - struct ldb_result *res; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - *errnop = 0; - - if (_ldb_nss_ctx->gr_cur >= _ldb_nss_ctx->gr_res->count) { - /* already returned all entries */ - return NSS_STATUS_NOTFOUND; - } - - res = talloc_zero(_ldb_nss_ctx->gr_res, struct ldb_result); - if ( ! res) { - errno = *errnop = ENOMEM; - _ldb_nss_ctx->gr_cur++; /* skip this entry */ - return NSS_STATUS_UNAVAIL; - } - - ret = _ldb_nss_group_request(&res, - _ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur]->dn, - _ldb_nss_mem_attrs, - "member"); - - if (ret != NSS_STATUS_SUCCESS) { - *errnop = errno; - talloc_free(res); - _ldb_nss_ctx->gr_cur++; /* skip this entry */ - return ret; - } - - ret = _ldb_nss_fill_group(result_buf, - buffer, - buflen, - errnop, - _ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur], - res); - - talloc_free(res); - - if (ret != NSS_STATUS_SUCCESS) { - if (ret != NSS_STATUS_TRYAGAIN) { - _ldb_nss_ctx->gr_cur++; /* skip this entry */ - } - return ret; - } - - /* this entry is ok, increment counter to nex entry */ - _ldb_nss_ctx->gr_cur++; - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _nss_ldb_getgrnam_r(const char *name, struct group *result_buf, char *buffer, size_t buflen, int *errnop) -{ - int ret; - char *filter; - TALLOC_CTX *ctx; - struct ldb_result *gr_res; - struct ldb_result *mem_res; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - ctx = talloc_new(_ldb_nss_ctx->ldb); - if ( ! ctx) { - *errnop = errno = ENOMEM; - return NSS_STATUS_UNAVAIL; - } - - /* build the filter for this uid */ - filter = talloc_asprintf(ctx, _LDB_NSS_GRNAM_FILTER, name); - if (filter == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOMEM; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* search the entry */ - ret = ldb_search(_ldb_nss_ctx->ldb, - _ldb_nss_ctx->ldb, - &gr_res, - _ldb_nss_ctx->base, - LDB_SCOPE_SUBTREE, - _ldb_nss_gr_attrs, - filter); - if (ret != LDB_SUCCESS) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - talloc_steal(ctx, gr_res); - - /* if none found return */ - if (gr_res->count == 0) { - *errnop = errno = ENOENT; - ret = NSS_STATUS_NOTFOUND; - goto done; - } - - if (gr_res->count != 1) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - mem_res = talloc_zero(ctx, struct ldb_result); - if ( ! mem_res) { - errno = *errnop = ENOMEM; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - ret = _ldb_nss_group_request(&mem_res, - gr_res->msgs[0]->dn, - _ldb_nss_mem_attrs, - "member"); - - if (ret != NSS_STATUS_SUCCESS) { - *errnop = errno; - goto done; - } - - ret = _ldb_nss_fill_group(result_buf, - buffer, - buflen, - errnop, - gr_res->msgs[0], - mem_res); - - if (ret != NSS_STATUS_SUCCESS) { - goto done; - } - - ret = NSS_STATUS_SUCCESS; -done: - talloc_free(ctx); - return ret; -} - -NSS_STATUS _nss_ldb_getgrgid_r(gid_t gid, struct group *result_buf, char *buffer, size_t buflen, int *errnop) -{ - int ret; - char *filter; - TALLOC_CTX *ctx; - struct ldb_result *gr_res; - struct ldb_result *mem_res; - - if (gid == 0) { /* we don't serve root gid by policy */ - *errnop = errno = ENOENT; - return NSS_STATUS_NOTFOUND; - } - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - ctx = talloc_new(_ldb_nss_ctx->ldb); - if ( ! ctx) { - *errnop = errno = ENOMEM; - return NSS_STATUS_UNAVAIL; - } - - /* build the filter for this uid */ - filter = talloc_asprintf(ctx, _LDB_NSS_GRGID_FILTER, gid); - if (filter == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOMEM; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* search the entry */ - ret = ldb_search(_ldb_nss_ctx->ldb, - _ldb_nss_ctx->ldb, - &gr_res, - _ldb_nss_ctx->base, - LDB_SCOPE_SUBTREE, - _ldb_nss_gr_attrs, - filter); - if (ret != LDB_SUCCESS) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - talloc_steal(ctx, gr_res); - - /* if none found return */ - if (gr_res->count == 0) { - *errnop = errno = ENOENT; - ret = NSS_STATUS_NOTFOUND; - goto done; - } - - if (gr_res->count != 1) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - mem_res = talloc_zero(ctx, struct ldb_result); - if ( ! mem_res) { - errno = *errnop = ENOMEM; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - ret = _ldb_nss_group_request(&mem_res, - gr_res->msgs[0]->dn, - _ldb_nss_mem_attrs, - "member"); - - if (ret != NSS_STATUS_SUCCESS) { - *errnop = errno; - goto done; - } - - ret = _ldb_nss_fill_group(result_buf, - buffer, - buflen, - errnop, - gr_res->msgs[0], - mem_res); - - if (ret != NSS_STATUS_SUCCESS) { - goto done; - } - - ret = NSS_STATUS_SUCCESS; -done: - talloc_free(ctx); - return ret; -} - -NSS_STATUS _nss_ldb_initgroups_dyn(const char *user, gid_t group, long int *start, long int *size, gid_t **groups, long int limit, int *errnop) -{ - int ret; - char *filter; - const char * attrs[] = { "uidNumber", "gidNumber", NULL }; - struct ldb_result *uid_res; - struct ldb_result *mem_res; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - mem_res = talloc_zero(_ldb_nss_ctx, struct ldb_result); - if ( ! mem_res) { - errno = *errnop = ENOMEM; - return NSS_STATUS_UNAVAIL; - } - - /* build the filter for this name */ - filter = talloc_asprintf(mem_res, _LDB_NSS_PWNAM_FILTER, user); - if (filter == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* search the entry */ - ret = ldb_search(_ldb_nss_ctx->ldb, - _ldb_nss_ctx->ldb, - &uid_res, - _ldb_nss_ctx->base, - LDB_SCOPE_SUBTREE, - attrs, - filter); - if (ret != LDB_SUCCESS) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - talloc_steal(mem_res, uid_res); - - /* if none found return */ - if (uid_res->count == 0) { - *errnop = errno = ENOENT; - ret = NSS_STATUS_NOTFOUND; - goto done; - } - - if (uid_res->count != 1) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - ret = _ldb_nss_group_request(&mem_res, - uid_res->msgs[0]->dn, - attrs, - "memberOf"); - - if (ret != NSS_STATUS_SUCCESS) { - *errnop = errno; - goto done; - } - - ret = _ldb_nss_fill_initgr(group, - limit, - start, - size, - groups, - errnop, - mem_res); - - if (ret != NSS_STATUS_SUCCESS) { - goto done; - } - - ret = NSS_STATUS_SUCCESS; - -done: - talloc_free(mem_res); - return ret; -} diff --git a/ldb-2.0.8/nssldb/ldb-nss.c b/ldb-2.0.8/nssldb/ldb-nss.c deleted file mode 100644 index 92b0635..0000000 --- a/ldb-2.0.8/nssldb/ldb-nss.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - LDB nsswitch module - - Copyright (C) Simo Sorce 2006 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "ldb-nss.h" - -struct _ldb_nss_context *_ldb_nss_ctx = NULL; - -NSS_STATUS _ldb_nss_init(void) -{ - int ret; - - pid_t mypid = getpid(); - - if (_ldb_nss_ctx != NULL) { - if (_ldb_nss_ctx->pid == mypid) { - /* already initialized */ - return NSS_STATUS_SUCCESS; - } else { - /* we are in a forked child now, reinitialize */ - talloc_free(_ldb_nss_ctx); - _ldb_nss_ctx = NULL; - } - } - - _ldb_nss_ctx = talloc_named(NULL, 0, "_ldb_nss_ctx(%u)", mypid); - if (_ldb_nss_ctx == NULL) { - return NSS_STATUS_UNAVAIL; - } - - _ldb_nss_ctx->pid = mypid; - - _ldb_nss_ctx->ldb = ldb_init(_ldb_nss_ctx, NULL); - if (_ldb_nss_ctx->ldb == NULL) { - goto failed; - } - - ret = ldb_connect(_ldb_nss_ctx->ldb, _LDB_NSS_URL, LDB_FLG_RDONLY, NULL); - if (ret != LDB_SUCCESS) { - goto failed; - } - - _ldb_nss_ctx->base = ldb_dn_new(_ldb_nss_ctx, _ldb_nss_ctx->ldb, _LDB_NSS_BASEDN); - if ( ! ldb_dn_validate(_ldb_nss_ctx->base)) { - goto failed; - } - - _ldb_nss_ctx->pw_cur = 0; - _ldb_nss_ctx->pw_res = NULL; - _ldb_nss_ctx->gr_cur = 0; - _ldb_nss_ctx->gr_res = NULL; - - return NSS_STATUS_SUCCESS; - -failed: - /* talloc_free(_ldb_nss_ctx); */ - _ldb_nss_ctx = NULL; - return NSS_STATUS_UNAVAIL; -} - -NSS_STATUS _ldb_nss_fill_passwd(struct passwd *result, - char *buffer, - int buflen, - int *errnop, - struct ldb_message *msg) -{ - int len; - int bufpos; - const char *tmp; - - bufpos = 0; - - /* get username */ - tmp = ldb_msg_find_attr_as_string(msg, "uid", NULL); - if (tmp == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - return NSS_STATUS_UNAVAIL; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->pw_name = &buffer[bufpos]; - bufpos += len; - - /* get userPassword */ - tmp = ldb_msg_find_attr_as_string(msg, "userPassword", NULL); - if (tmp == NULL) { - tmp = "LDB"; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->pw_passwd = &buffer[bufpos]; - bufpos += len; - - /* this backend never serves an uid 0 user */ - result->pw_uid = ldb_msg_find_attr_as_int(msg, "uidNumber", 0); - if (result->pw_uid == 0) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - return NSS_STATUS_UNAVAIL; - } - - result->pw_gid = ldb_msg_find_attr_as_int(msg, "gidNumber", 0); - if (result->pw_gid == 0) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - return NSS_STATUS_UNAVAIL; - } - - /* get gecos */ - tmp = ldb_msg_find_attr_as_string(msg, "gecos", NULL); - if (tmp == NULL) { - tmp = ""; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->pw_gecos = &buffer[bufpos]; - bufpos += len; - - /* get homeDirectory */ - tmp = ldb_msg_find_attr_as_string(msg, "homeDirectory", NULL); - if (tmp == NULL) { - tmp = ""; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->pw_dir = &buffer[bufpos]; - bufpos += len; - - /* get shell */ - tmp = ldb_msg_find_attr_as_string(msg, "loginShell", NULL); - if (tmp == NULL) { - tmp = ""; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->pw_shell = &buffer[bufpos]; - bufpos += len; - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _ldb_nss_fill_group(struct group *result, - char *buffer, - int buflen, - int *errnop, - struct ldb_message *group, - struct ldb_result *members) -{ - const char *tmp; - size_t len; - size_t bufpos; - size_t lsize; - unsigned int i; - - bufpos = 0; - - /* get group name */ - tmp = ldb_msg_find_attr_as_string(group, "cn", NULL); - if (tmp == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - return NSS_STATUS_UNAVAIL; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->gr_name = &buffer[bufpos]; - bufpos += len; - - /* get userPassword */ - tmp = ldb_msg_find_attr_as_string(group, "userPassword", NULL); - if (tmp == NULL) { - tmp = "LDB"; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->gr_passwd = &buffer[bufpos]; - bufpos += len; - - result->gr_gid = ldb_msg_find_attr_as_int(group, "gidNumber", 0); - if (result->gr_gid == 0) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - return NSS_STATUS_UNAVAIL; - } - - /* check if there is enough memory for the list of pointers */ - lsize = (members->count + 1) * sizeof(char *); - - /* align buffer on pointer boundary */ - bufpos += (sizeof(char*) - ((unsigned long)(buffer) % sizeof(char*))); - if ((buflen - bufpos) < lsize) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - - result->gr_mem = (char **)&buffer[bufpos]; - bufpos += lsize; - - for (i = 0; i < members->count; i++) { - tmp = ldb_msg_find_attr_as_string(members->msgs[i], "uid", NULL); - if (tmp == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - return NSS_STATUS_UNAVAIL; - } - len = strlen(tmp)+1; - if (bufpos + len > buflen) { - /* buffer too small */ - *errnop = errno = EAGAIN; - return NSS_STATUS_TRYAGAIN; - } - memcpy(&buffer[bufpos], tmp, len); - result->gr_mem[i] = &buffer[bufpos]; - bufpos += len; - } - - result->gr_mem[i] = NULL; - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _ldb_nss_fill_initgr(gid_t group, - long int limit, - long int *start, - long int *size, - gid_t **groups, - int *errnop, - struct ldb_result *grlist) -{ - NSS_STATUS ret; - unsigned int i; - - for (i = 0; i < grlist->count; i++) { - - if (limit && (*start > limit)) { - /* TODO: warn no all groups were reported */ - *errnop = 0; - ret = NSS_STATUS_SUCCESS; - goto done; - } - - if (*start == *size) { - /* buffer full, enlarge it */ - long int gs; - gid_t *gm; - - gs = (*size) + 32; - if (limit && (gs > limit)) { - gs = limit; - } - - gm = (gid_t *)realloc((*groups), gs * sizeof(gid_t)); - if ( ! gm) { - *errnop = ENOMEM; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - *groups = gm; - *size = gs; - } - - (*groups)[*start] = ldb_msg_find_attr_as_int(grlist->msgs[i], "gidNumber", 0); - if ((*groups)[*start] == 0 || (*groups)[*start] == group) { - /* skip root group or primary group */ - continue; - } - (*start)++; - - } - - *errnop = 0; - ret = NSS_STATUS_SUCCESS; -done: - return ret; -} - -#define _LDB_NSS_ALLOC_CHECK(mem) do { if (!mem) { errno = ENOMEM; return NSS_STATUS_UNAVAIL; } } while(0) - -NSS_STATUS _ldb_nss_group_request(struct ldb_result **_res, - struct ldb_dn *group_dn, - const char * const *attrs, - const char *mattr) -{ - struct ldb_control **ctrls; - struct ldb_control *ctrl; - struct ldb_asq_control *asqc; - struct ldb_request *req; - int ret; - struct ldb_result *res = *_res; - - ctrls = talloc_array(res, struct ldb_control *, 2); - _LDB_NSS_ALLOC_CHECK(ctrls); - - ctrl = talloc(ctrls, struct ldb_control); - _LDB_NSS_ALLOC_CHECK(ctrl); - - asqc = talloc(ctrl, struct ldb_asq_control); - _LDB_NSS_ALLOC_CHECK(asqc); - - asqc->source_attribute = talloc_strdup(asqc, mattr); - _LDB_NSS_ALLOC_CHECK(asqc->source_attribute); - - asqc->request = 1; - asqc->src_attr_len = strlen(asqc->source_attribute); - ctrl->oid = LDB_CONTROL_ASQ_OID; - ctrl->critical = 1; - ctrl->data = asqc; - ctrls[0] = ctrl; - ctrls[1] = NULL; - - ret = ldb_build_search_req( - &req, - _ldb_nss_ctx->ldb, - res, - group_dn, - LDB_SCOPE_BASE, - "(objectClass=*)", - attrs, - ctrls, - res, - ldb_search_default_callback); - - if (ret != LDB_SUCCESS) { - errno = ENOENT; - return NSS_STATUS_UNAVAIL; - } - - ldb_set_timeout(_ldb_nss_ctx->ldb, req, 0); - - ret = ldb_request(_ldb_nss_ctx->ldb, req); - - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } else { - talloc_free(req); - return NSS_STATUS_UNAVAIL; - } - - talloc_free(req); - return NSS_STATUS_SUCCESS; -} - diff --git a/ldb-2.0.8/nssldb/ldb-nss.h b/ldb-2.0.8/nssldb/ldb-nss.h deleted file mode 100644 index 583876f..0000000 --- a/ldb-2.0.8/nssldb/ldb-nss.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - LDB nsswitch module - - Copyright (C) Simo Sorce 2006 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#ifndef _LDB_NSS -#define _LDB_NSS - -#include "includes.h" -#include "ldb/include/includes.h" - -#include -#include -#include - -#define _LDB_NSS_URL "etc/users.ldb" -#define _LDB_NSS_BASEDN "CN=Users,CN=System" -#define _LDB_NSS_PWENT_FILTER "(&(objectClass=posixAccount)(!(uidNumber=0))(!(gidNumber=0)))" -#define _LDB_NSS_PWUID_FILTER "(&(objectClass=posixAccount)(uidNumber=%d)(!(gidNumber=0)))" -#define _LDB_NSS_PWNAM_FILTER "(&(objectClass=posixAccount)(uid=%s)(!(uidNumber=0))(!(gidNumber=0)))" - -#define _LDB_NSS_GRENT_FILTER "(&(objectClass=posixGroup)(!(gidNumber=0)))" -#define _LDB_NSS_GRGID_FILTER "(&(objectClass=posixGroup)(gidNumber=%d)))" -#define _LDB_NSS_GRNAM_FILTER "(&(objectClass=posixGroup)(cn=%s)(!(gidNumber=0)))" - -typedef enum nss_status NSS_STATUS; - -struct _ldb_nss_context { - - pid_t pid; - - struct ldb_context *ldb; - struct ldb_dn *base; - - int pw_cur; - struct ldb_result *pw_res; - - int gr_cur; - struct ldb_result *gr_res; -}; - -NSS_STATUS _ldb_nss_init(void); - -NSS_STATUS _ldb_nss_fill_passwd(struct passwd *result, - char *buffer, - int buflen, - int *errnop, - struct ldb_message *msg); - -NSS_STATUS _ldb_nss_fill_group(struct group *result, - char *buffer, - int buflen, - int *errnop, - struct ldb_message *group, - struct ldb_result *members); - -NSS_STATUS _ldb_nss_fill_initgr(gid_t group, - long int limit, - long int *start, - long int *size, - gid_t **groups, - int *errnop, - struct ldb_result *grlist); - -NSS_STATUS _ldb_nss_group_request(struct ldb_result **res, - struct ldb_dn *group_dn, - const char * const *attrs, - const char *mattr); - -#endif /* _LDB_NSS */ diff --git a/ldb-2.0.8/nssldb/ldb-pwd.c b/ldb-2.0.8/nssldb/ldb-pwd.c deleted file mode 100644 index 6ab103a..0000000 --- a/ldb-2.0.8/nssldb/ldb-pwd.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - LDB nsswitch module - - Copyright (C) Simo Sorce 2006 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see . -*/ - -#include "ldb-nss.h" - -extern struct _ldb_nss_context *_ldb_nss_ctx; - -const char *_ldb_nss_pw_attrs[] = { - "uid", - "userPassword", - "uidNumber", - "gidNumber", - "gecos", - "homeDirectory", - "loginShell", - NULL -}; - -NSS_STATUS _nss_ldb_setpwent(void) -{ - int ret; - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - _ldb_nss_ctx->pw_cur = 0; - if (_ldb_nss_ctx->pw_res != NULL) { - talloc_free(_ldb_nss_ctx->pw_res); - _ldb_nss_ctx->pw_res = NULL; - } - - ret = ldb_search(_ldb_nss_ctx->ldb, - _ldb_nss_ctx->ldb, - &_ldb_nss_ctx->pw_res, - _ldb_nss_ctx->base, - LDB_SCOPE_SUBTREE, - _ldb_nss_pw_attrs, - _LDB_NSS_PWENT_FILTER); - if (ret != LDB_SUCCESS) { - return NSS_STATUS_UNAVAIL; - } - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _nss_ldb_endpwent(void) -{ - int ret; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - _ldb_nss_ctx->pw_cur = 0; - if (_ldb_nss_ctx->pw_res) { - talloc_free(_ldb_nss_ctx->pw_res); - _ldb_nss_ctx->pw_res = NULL; - } - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _nss_ldb_getpwent_r(struct passwd *result_buf, - char *buffer, - int buflen, - int *errnop) -{ - int ret; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - *errnop = 0; - - if (_ldb_nss_ctx->pw_cur >= _ldb_nss_ctx->pw_res->count) { - /* already returned all entries */ - return NSS_STATUS_NOTFOUND; - } - - ret = _ldb_nss_fill_passwd(result_buf, - buffer, - buflen, - errnop, - _ldb_nss_ctx->pw_res->msgs[_ldb_nss_ctx->pw_cur]); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - _ldb_nss_ctx->pw_cur++; - - return NSS_STATUS_SUCCESS; -} - -NSS_STATUS _nss_ldb_getpwuid_r(uid_t uid, struct passwd *result_buf, char *buffer, size_t buflen, int *errnop) -{ - int ret; - char *filter; - struct ldb_result *res; - - if (uid == 0) { /* we don't serve root uid by policy */ - *errnop = errno = ENOENT; - return NSS_STATUS_NOTFOUND; - } - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - /* build the filter for this uid */ - filter = talloc_asprintf(_ldb_nss_ctx, _LDB_NSS_PWUID_FILTER, uid); - if (filter == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOMEM; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* search the entry */ - ret = ldb_search(_ldb_nss_ctx->ldb, - _ldb_nss_ctx->ldb, - &res, - _ldb_nss_ctx->base, - LDB_SCOPE_SUBTREE, - _ldb_nss_pw_attrs, - filter); - if (ret != LDB_SUCCESS) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* if none found return */ - if (res->count == 0) { - *errnop = errno = ENOENT; - ret = NSS_STATUS_NOTFOUND; - goto done; - } - - if (res->count != 1) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* fill in the passwd struct */ - ret = _ldb_nss_fill_passwd(result_buf, - buffer, - buflen, - errnop, - res->msgs[0]); - -done: - talloc_free(filter); - talloc_free(res); - return ret; -} - -NSS_STATUS _nss_ldb_getpwnam_r(const char *name, struct passwd *result_buf, char *buffer, size_t buflen, int *errnop) -{ - int ret; - char *filter; - struct ldb_result *res; - - ret = _ldb_nss_init(); - if (ret != NSS_STATUS_SUCCESS) { - return ret; - } - - /* build the filter for this name */ - filter = talloc_asprintf(_ldb_nss_ctx, _LDB_NSS_PWNAM_FILTER, name); - if (filter == NULL) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* search the entry */ - ret = ldb_search(_ldb_nss_ctx->ldb, - _ldb_nss_ctx->ldb, - &res, - _ldb_nss_ctx->base, - LDB_SCOPE_SUBTREE, - _ldb_nss_pw_attrs, - filter); - if (ret != LDB_SUCCESS) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* if none found return */ - if (res->count == 0) { - *errnop = errno = ENOENT; - ret = NSS_STATUS_NOTFOUND; - goto done; - } - - if (res->count != 1) { - /* this is a fatal error */ - *errnop = errno = ENOENT; - ret = NSS_STATUS_UNAVAIL; - goto done; - } - - /* fill in the passwd struct */ - ret = _ldb_nss_fill_passwd(result_buf, - buffer, - buflen, - errnop, - res->msgs[0]); - -done: - talloc_free(filter); - talloc_free(res); - return ret; -} - diff --git a/ldb-2.0.8/pyldb-util.pc.in b/ldb-2.0.8/pyldb-util.pc.in deleted file mode 100644 index 60ec702..0000000 --- a/ldb-2.0.8/pyldb-util.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ -modulesdir=@LDB_MODULESDIR@ - -Name: pyldb-util@PYTHON_SO_ABI_FLAG@ -Description: Python bindings for LDB -Version: @PACKAGE_VERSION@ -Requires: ldb -Libs: @LIB_RPATH@ -L${libdir} -lpyldb-util@PYTHON_LIBNAME_SO_ABI_FLAG@ -Cflags: -I${includedir} -URL: http://ldb.samba.org/ diff --git a/ldb-2.0.8/pyldb.c b/ldb-2.0.8/pyldb.c deleted file mode 100644 index 868e366..0000000 --- a/ldb-2.0.8/pyldb.c +++ /dev/null @@ -1,4470 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Python interface to ldb. - - Copyright (C) 2005,2006 Tim Potter - Copyright (C) 2006 Simo Sorce - Copyright (C) 2007-2010 Jelmer Vernooij - Copyright (C) 2009-2010 Matthias Dieter Wallnöfer - Copyright (C) 2009-2011 Andrew Tridgell - Copyright (C) 2009-2011 Andrew Bartlett - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include -#include "ldb_private.h" -#include "ldb_handlers.h" -#include "pyldb.h" -#include "dlinklist.h" - -/* discard signature of 'func' in favour of 'target_sig' */ -#define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func - -struct py_ldb_search_iterator_reply; - -typedef struct { - PyObject_HEAD - TALLOC_CTX *mem_ctx; - PyLdbObject *ldb; - struct { - struct ldb_request *req; - struct py_ldb_search_iterator_reply *next; - struct py_ldb_search_iterator_reply *result; - PyObject *exception; - } state; -} PyLdbSearchIteratorObject; - -struct py_ldb_search_iterator_reply { - struct py_ldb_search_iterator_reply *prev, *next; - PyLdbSearchIteratorObject *py_iter; - PyObject *obj; -}; - -void initldb(void); -static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg); -static PyObject *PyExc_LdbError; - -static PyTypeObject PyLdbControl; -static PyTypeObject PyLdbResult; -static PyTypeObject PyLdbSearchIterator; -static PyTypeObject PyLdbMessage; -#define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage) -static PyTypeObject PyLdbModule; -static PyTypeObject PyLdbDn; -#define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn) -static PyTypeObject PyLdb; -#define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb) -static PyTypeObject PyLdbMessageElement; -#define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement) - -static PyTypeObject PyLdbTree; -static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx); -static PyObject *PyLdbModule_FromModule(struct ldb_module *mod); -static struct ldb_message_element *PyObject_AsMessageElement( - TALLOC_CTX *mem_ctx, - PyObject *set_obj, - unsigned int flags, - const char *attr_name); -static PyTypeObject PyLdbBytesType; - -#if PY_MAJOR_VERSION >= 3 -#define PyInt_FromLong PyLong_FromLong - -#define PYARG_STR_UNI "es" - -static PyObject *PyLdbBytes_FromStringAndSize(const char *msg, int size) -{ - PyObject* result = NULL; - PyObject* args = NULL; - args = Py_BuildValue("(y#)", msg, size); - result = PyLdbBytesType.tp_new(&PyLdbBytesType, args, NULL); - Py_DECREF(args); - return result; -} -#else -#define PyLdbBytes_FromStringAndSize PyString_FromStringAndSize - -#define PYARG_STR_UNI "et" - -#endif - -static PyObject *richcmp(int cmp_val, int op) -{ - int ret; - switch (op) { - case Py_LT: ret = cmp_val < 0; break; - case Py_LE: ret = cmp_val <= 0; break; - case Py_EQ: ret = cmp_val == 0; break; - case Py_NE: ret = cmp_val != 0; break; - case Py_GT: ret = cmp_val > 0; break; - case Py_GE: ret = cmp_val >= 0; break; - default: - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - return PyBool_FromLong(ret); -} - - -static PyObject *py_ldb_control_str(PyLdbControlObject *self) -{ - if (self->data != NULL) { - char* control = ldb_control_to_string(self->mem_ctx, self->data); - if (control == NULL) { - PyErr_NoMemory(); - return NULL; - } - return PyUnicode_FromString(control); - } else { - return PyUnicode_FromString("ldb control"); - } -} - -static void py_ldb_control_dealloc(PyLdbControlObject *self) -{ - if (self->mem_ctx != NULL) { - talloc_free(self->mem_ctx); - } - self->data = NULL; - Py_TYPE(self)->tp_free(self); -} - -/* Create a text (rather than bytes) interface for a LDB result object */ -static PyObject *wrap_text(const char *type, PyObject *wrapped) -{ - PyObject *mod, *cls, *constructor, *inst; - mod = PyImport_ImportModule("_ldb_text"); - if (mod == NULL) - return NULL; - cls = PyObject_GetAttrString(mod, type); - Py_DECREF(mod); - if (cls == NULL) { - Py_DECREF(mod); - return NULL; - } - constructor = PyObject_GetAttrString(cls, "_wrap"); - Py_DECREF(cls); - if (constructor == NULL) { - return NULL; - } - inst = PyObject_CallFunction(constructor, discard_const_p(char, "O"), wrapped); - Py_DECREF(constructor); - return inst; -} - -static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self, - PyObject *Py_UNUSED(ignored)) -{ - return PyUnicode_FromString(self->data->oid); -} - -static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self, - PyObject *Py_UNUSED(ignored)) -{ - return PyBool_FromLong(self->data->critical); -} - -static int py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure) -{ - if (PyObject_IsTrue(value)) { - self->data->critical = true; - } else { - self->data->critical = false; - } - return 0; -} - -static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - char *data = NULL; - const char * const kwnames[] = { "ldb", "data", NULL }; - struct ldb_control *parsed_controls; - PyLdbControlObject *ret; - PyObject *py_ldb; - TALLOC_CTX *mem_ctx; - struct ldb_context *ldb_ctx; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!s", - discard_const_p(char *, kwnames), - &PyLdb, &py_ldb, &data)) - return NULL; - - mem_ctx = talloc_new(NULL); - if (mem_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - - ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb); - parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data); - - if (!parsed_controls) { - talloc_free(mem_ctx); - PyErr_SetString(PyExc_ValueError, "unable to parse control string"); - return NULL; - } - - ret = PyObject_New(PyLdbControlObject, type); - if (ret == NULL) { - PyErr_NoMemory(); - talloc_free(mem_ctx); - return NULL; - } - - ret->mem_ctx = mem_ctx; - - ret->data = talloc_move(mem_ctx, &parsed_controls); - if (ret->data == NULL) { - Py_DECREF(ret); - PyErr_NoMemory(); - talloc_free(mem_ctx); - return NULL; - } - - return (PyObject *)ret; -} - -static PyGetSetDef py_ldb_control_getset[] = { - { - .name = discard_const_p(char, "oid"), - .get = (getter)py_ldb_control_get_oid, - }, - { - .name = discard_const_p(char, "critical"), - .get = (getter)py_ldb_control_get_critical, - .set = (setter)py_ldb_control_set_critical, - }, - { .name = NULL }, -}; - -static PyTypeObject PyLdbControl = { - .tp_name = "ldb.control", - .tp_dealloc = (destructor)py_ldb_control_dealloc, - .tp_getattro = PyObject_GenericGetAttr, - .tp_basicsize = sizeof(PyLdbControlObject), - .tp_getset = py_ldb_control_getset, - .tp_doc = "LDB control.", - .tp_str = (reprfunc)py_ldb_control_str, - .tp_new = py_ldb_control_new, - .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, -}; - -static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx) -{ - if (ret == LDB_ERR_PYTHON_EXCEPTION) - return; /* Python exception should already be set, just keep that */ - - PyErr_SetObject(error, - Py_BuildValue(discard_const_p(char, "(i,s)"), ret, - ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx))); -} -static PyObject *py_ldb_bytes_str(PyBytesObject *self) -{ - char *msg = NULL; - Py_ssize_t size; - int result = 0; - if (!PyBytes_Check(self)) { - PyErr_Format(PyExc_TypeError,"Unexpected type"); - return NULL; - } - result = PyBytes_AsStringAndSize((PyObject *)self, &msg, &size); - if (result != 0) { - PyErr_Format(PyExc_TypeError, "Failed to extract bytes"); - return NULL; - } - return PyUnicode_FromStringAndSize(msg, size); -} - -static PyTypeObject PyLdbBytesType = { - PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "ldb.bytes", - .tp_doc = "str/bytes (with custom str)", - .tp_str = (reprfunc)py_ldb_bytes_str, - .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, -}; - -static PyObject *PyObject_FromLdbValue(const struct ldb_val *val) -{ - return PyLdbBytes_FromStringAndSize((const char *)val->data, val->length); -} - -static PyObject *PyStr_FromLdbValue(const struct ldb_val *val) -{ - return PyUnicode_FromStringAndSize((const char *)val->data, val->length); -} - -/** - * Create a Python object from a ldb_result. - * - * @param result LDB result to convert - * @return Python object with converted result (a list object) - */ -static PyObject *PyLdbControl_FromControl(struct ldb_control *control) -{ - TALLOC_CTX *ctl_ctx = talloc_new(NULL); - PyLdbControlObject *ctrl; - if (ctl_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - - ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0); - if (ctrl == NULL) { - talloc_free(ctl_ctx); - PyErr_NoMemory(); - return NULL; - } - ctrl->mem_ctx = ctl_ctx; - ctrl->data = talloc_steal(ctrl->mem_ctx, control); - if (ctrl->data == NULL) { - Py_DECREF(ctrl); - PyErr_NoMemory(); - return NULL; - } - return (PyObject*) ctrl; -} - -/** - * Create a Python object from a ldb_result. - * - * @param result LDB result to convert - * @return Python object with converted result (a list object) - */ -static PyObject *PyLdbResult_FromResult(struct ldb_result *result) -{ - PyLdbResultObject *ret; - PyObject *list, *controls, *referals; - Py_ssize_t i; - - if (result == NULL) { - Py_RETURN_NONE; - } - - ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0); - if (ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - - list = PyList_New(result->count); - if (list == NULL) { - PyErr_NoMemory(); - Py_DECREF(ret); - return NULL; - } - - for (i = 0; i < result->count; i++) { - PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i])); - } - - ret->mem_ctx = talloc_new(NULL); - if (ret->mem_ctx == NULL) { - Py_DECREF(list); - Py_DECREF(ret); - PyErr_NoMemory(); - return NULL; - } - - ret->msgs = list; - - if (result->controls) { - i = 0; - while (result->controls[i]) { - i++; - } - controls = PyList_New(i); - if (controls == NULL) { - Py_DECREF(ret); - PyErr_NoMemory(); - return NULL; - } - for (i=0; result->controls[i]; i++) { - PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]); - if (ctrl == NULL) { - Py_DECREF(ret); - Py_DECREF(controls); - PyErr_NoMemory(); - return NULL; - } - PyList_SetItem(controls, i, ctrl); - } - } else { - /* - * No controls so we keep an empty list - */ - controls = PyList_New(0); - if (controls == NULL) { - Py_DECREF(ret); - PyErr_NoMemory(); - return NULL; - } - } - - ret->controls = controls; - - i = 0; - - while (result->refs && result->refs[i]) { - i++; - } - - referals = PyList_New(i); - if (referals == NULL) { - Py_DECREF(ret); - PyErr_NoMemory(); - return NULL; - } - - for (i = 0;result->refs && result->refs[i]; i++) { - PyList_SetItem(referals, i, PyUnicode_FromString(result->refs[i])); - } - ret->referals = referals; - return (PyObject *)ret; -} - -/** - * Create a LDB Result from a Python object. - * If conversion fails, NULL will be returned and a Python exception set. - * - * Note: the result object only includes the messages at the moment; extended - * result, controls and referrals are ignored. - * - * @param mem_ctx Memory context in which to allocate the LDB Result - * @param obj Python object to convert - * @return a ldb_result, or NULL if the conversion failed - */ -static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx, - PyObject *obj) -{ - struct ldb_result *res; - Py_ssize_t i; - - if (obj == Py_None) - return NULL; - - res = talloc_zero(mem_ctx, struct ldb_result); - res->count = PyList_Size(obj); - res->msgs = talloc_array(res, struct ldb_message *, res->count); - for (i = 0; i < res->count; i++) { - PyObject *item = PyList_GetItem(obj, i); - res->msgs[i] = pyldb_Message_AsMessage(item); - } - return res; -} - -static PyObject *py_ldb_dn_validate(PyLdbDnObject *self, - PyObject *Py_UNUSED(ignored)) -{ - return PyBool_FromLong(ldb_dn_validate(self->dn)); -} - -static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self, - PyObject *Py_UNUSED(ignored)) -{ - return PyBool_FromLong(ldb_dn_is_valid(self->dn)); -} - -static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self, - PyObject *Py_UNUSED(ignored)) -{ - return PyBool_FromLong(ldb_dn_is_special(self->dn)); -} - -static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self, - PyObject *Py_UNUSED(ignored)) -{ - return PyBool_FromLong(ldb_dn_is_null(self->dn)); -} - -static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self, - PyObject *Py_UNUSED(ignored)) -{ - return PyUnicode_FromString(ldb_dn_get_casefold(self->dn)); -} - -static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self) -{ - return PyUnicode_FromString(ldb_dn_get_linearized(self->dn)); -} - -static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self, - PyObject *Py_UNUSED(ignored)) -{ - return PyUnicode_FromString(ldb_dn_canonical_string(self->dn, self->dn)); -} - -static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self, - PyObject *Py_UNUSED(ignored)) -{ - return PyUnicode_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn)); -} - -static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs) -{ - const char * const kwnames[] = { "mode", NULL }; - int mode = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", - discard_const_p(char *, kwnames), - &mode)) - return NULL; - return PyUnicode_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode)); -} - -static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args) -{ - char *name; - const struct ldb_val *val; - - if (!PyArg_ParseTuple(args, "s", &name)) - return NULL; - val = ldb_dn_get_extended_component(self->dn, name); - if (val == NULL) { - Py_RETURN_NONE; - } - - return PyBytes_FromStringAndSize((const char *)val->data, val->length); -} - -static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args) -{ - char *name; - int err; - uint8_t *value = NULL; - Py_ssize_t size = 0; - - if (!PyArg_ParseTuple(args, "sz#", &name, (char **)&value, &size)) - return NULL; - - if (value == NULL) { - err = ldb_dn_set_extended_component(self->dn, name, NULL); - } else { - struct ldb_val val; - val.data = (uint8_t *)value; - val.length = size; - err = ldb_dn_set_extended_component(self->dn, name, &val); - } - - if (err != LDB_SUCCESS) { - PyErr_SetString(PyExc_TypeError, "Failed to set extended component"); - return NULL; - } - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_dn_repr(PyLdbDnObject *self) -{ - PyObject *str = PyUnicode_FromString(ldb_dn_get_linearized(self->dn)); - PyObject *repr, *result; - if (str == NULL) - return NULL; - repr = PyObject_Repr(str); - if (repr == NULL) { - Py_DECREF(str); - return NULL; - } - result = PyUnicode_FromFormat("Dn(%s)", PyUnicode_AsUTF8(repr)); - Py_DECREF(str); - Py_DECREF(repr); - return result; -} - -static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args) -{ - char *name; - - if (!PyArg_ParseTuple(args, "s", &name)) - return NULL; - - return PyBool_FromLong(ldb_dn_check_special(self->dn, name)); -} - -static PyObject *py_ldb_dn_richcmp(PyObject *dn1, PyObject *dn2, int op) -{ - int ret; - if (!pyldb_Dn_Check(dn2)) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - ret = ldb_dn_compare(pyldb_Dn_AsDn(dn1), pyldb_Dn_AsDn(dn2)); - return richcmp(ret, op); -} - -static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self, - PyObject *Py_UNUSED(ignored)) -{ - struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self); - struct ldb_dn *parent; - PyLdbDnObject *py_ret; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - - parent = ldb_dn_get_parent(mem_ctx, dn); - if (parent == NULL) { - talloc_free(mem_ctx); - Py_RETURN_NONE; - } - - py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0); - if (py_ret == NULL) { - PyErr_NoMemory(); - talloc_free(mem_ctx); - return NULL; - } - py_ret->mem_ctx = mem_ctx; - py_ret->dn = parent; - return (PyObject *)py_ret; -} - -static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args) -{ - PyObject *py_other; - struct ldb_dn *dn, *other; - if (!PyArg_ParseTuple(args, "O", &py_other)) - return NULL; - - dn = pyldb_Dn_AsDn((PyObject *)self); - - if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other)) - return NULL; - - return PyBool_FromLong(ldb_dn_add_child(dn, other)); -} - -static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args) -{ - PyObject *py_other; - struct ldb_dn *other, *dn; - if (!PyArg_ParseTuple(args, "O", &py_other)) - return NULL; - - dn = pyldb_Dn_AsDn((PyObject *)self); - - if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other)) - return NULL; - - return PyBool_FromLong(ldb_dn_add_base(dn, other)); -} - -static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args) -{ - struct ldb_dn *dn; - int i; - if (!PyArg_ParseTuple(args, "i", &i)) - return NULL; - - dn = pyldb_Dn_AsDn((PyObject *)self); - - return PyBool_FromLong(ldb_dn_remove_base_components(dn, i)); -} - -static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args) -{ - PyObject *py_base; - struct ldb_dn *dn, *base; - if (!PyArg_ParseTuple(args, "O", &py_base)) - return NULL; - - dn = pyldb_Dn_AsDn((PyObject *)self); - - if (!pyldb_Object_AsDn(NULL, py_base, ldb_dn_get_ldb_context(dn), &base)) - return NULL; - - return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0); -} - -static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args) -{ - struct ldb_dn *dn; - const char *name; - unsigned int num = 0; - - if (!PyArg_ParseTuple(args, "I", &num)) - return NULL; - - dn = pyldb_Dn_AsDn((PyObject *)self); - - name = ldb_dn_get_component_name(dn, num); - if (name == NULL) { - Py_RETURN_NONE; - } - - return PyUnicode_FromString(name); -} - -static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args) -{ - struct ldb_dn *dn; - const struct ldb_val *val; - unsigned int num = 0; - - if (!PyArg_ParseTuple(args, "I", &num)) - return NULL; - - dn = pyldb_Dn_AsDn((PyObject *)self); - - val = ldb_dn_get_component_val(dn, num); - if (val == NULL) { - Py_RETURN_NONE; - } - - return PyStr_FromLdbValue(val); -} - -static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args) -{ - unsigned int num = 0; - char *name = NULL, *value = NULL; - struct ldb_val val = { NULL, }; - int err; - Py_ssize_t size = 0; - - if (!PyArg_ParseTuple(args, "Iss#", &num, &name, &value, &size)) - return NULL; - - val.data = (unsigned char*) value; - val.length = size; - - err = ldb_dn_set_component(self->dn, num, name, val); - if (err != LDB_SUCCESS) { - PyErr_SetString(PyExc_TypeError, "Failed to set component"); - return NULL; - } - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self, - PyObject *Py_UNUSED(ignored)) -{ - struct ldb_dn *dn; - const char *name; - - dn = pyldb_Dn_AsDn((PyObject *)self); - - name = ldb_dn_get_rdn_name(dn); - if (name == NULL) { - Py_RETURN_NONE; - } - - return PyUnicode_FromString(name); -} - -static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self, - PyObject *Py_UNUSED(ignored)) -{ - struct ldb_dn *dn; - const struct ldb_val *val; - - dn = pyldb_Dn_AsDn((PyObject *)self); - - val = ldb_dn_get_rdn_val(dn); - if (val == NULL) { - Py_RETURN_NONE; - } - - return PyStr_FromLdbValue(val); -} - -static PyMethodDef py_ldb_dn_methods[] = { - { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS, - "S.validate() -> bool\n" - "Validate DN is correct." }, - { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS, - "S.is_valid() -> bool\n" }, - { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS, - "S.is_special() -> bool\n" - "Check whether this is a special LDB DN." }, - { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS, - "Check whether this is a null DN." }, - { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS, - NULL }, - { "get_linearized", PY_DISCARD_FUNC_SIG(PyCFunction, - py_ldb_dn_get_linearized), - METH_NOARGS, - NULL }, - { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS, - "S.canonical_str() -> string\n" - "Canonical version of this DN (like a posix path)." }, - { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS, - "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"}, - { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS, - "S.canonical_ex_str() -> string\n" - "Canonical version of this DN (like a posix path, with terminating newline)." }, - { "extended_str", PY_DISCARD_FUNC_SIG(PyCFunction, - py_ldb_dn_extended_str), - METH_VARARGS | METH_KEYWORDS, - "S.extended_str(mode=1) -> string\n" - "Extended version of this DN" }, - { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS, - "S.parent() -> dn\n" - "Get the parent for this DN." }, - { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS, - "S.add_child(dn) -> None\n" - "Add a child DN to this DN." }, - { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS, - "S.add_base(dn) -> None\n" - "Add a base DN to this DN." }, - { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS, - "S.remove_base_components(int) -> bool\n" - "Remove a number of DN components from the base of this DN." }, - { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS, - "S.check_special(name) -> bool\n\n" - "Check if name is a special DN name"}, - { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS, - "S.get_extended_component(name) -> string\n\n" - "returns a DN extended component as a binary string"}, - { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS, - "S.set_extended_component(name, value) -> None\n\n" - "set a DN extended component as a binary string"}, - { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS, - "S.get_component_name(num) -> string\n" - "get the attribute name of the specified component" }, - { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS, - "S.get_component_value(num) -> string\n" - "get the attribute value of the specified component as a binary string" }, - { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS, - "S.get_component_value(num, name, value) -> None\n" - "set the attribute name and value of the specified component" }, - { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS, - "S.get_rdn_name() -> string\n" - "get the RDN attribute name" }, - { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS, - "S.get_rdn_value() -> string\n" - "get the RDN attribute value as a binary string" }, - { NULL } -}; - -static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self) -{ - return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self)); -} - -/* - copy a DN as a python object - */ -static PyObject *py_ldb_dn_copy(struct ldb_dn *dn) -{ - PyLdbDnObject *py_ret; - - py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0); - if (py_ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - py_ret->mem_ctx = talloc_new(NULL); - py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn); - return (PyObject *)py_ret; -} - -static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other) -{ - struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self), - *other; - PyLdbDnObject *py_ret; - - if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other)) - return NULL; - - py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0); - if (py_ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - py_ret->mem_ctx = talloc_new(NULL); - py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn); - ldb_dn_add_base(py_ret->dn, other); - return (PyObject *)py_ret; -} - -static PySequenceMethods py_ldb_dn_seq = { - .sq_length = (lenfunc)py_ldb_dn_len, - .sq_concat = (binaryfunc)py_ldb_dn_concat, -}; - -static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - struct ldb_dn *ret = NULL; - char *str = NULL; - PyObject *py_ldb = NULL; - struct ldb_context *ldb_ctx = NULL; - TALLOC_CTX *mem_ctx = NULL; - PyLdbDnObject *py_ret = NULL; - const char * const kwnames[] = { "ldb", "dn", NULL }; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O"PYARG_STR_UNI, - discard_const_p(char *, kwnames), - &py_ldb, "utf8", &str)) - goto out; - - if (!PyLdb_Check(py_ldb)) { - PyErr_SetString(PyExc_TypeError, "Expected Ldb"); - goto out; - } - - ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb); - - mem_ctx = talloc_new(NULL); - if (mem_ctx == NULL) { - PyErr_NoMemory(); - goto out; - } - - ret = ldb_dn_new(mem_ctx, ldb_ctx, str); - if (!ldb_dn_validate(ret)) { - talloc_free(mem_ctx); - PyErr_SetString(PyExc_ValueError, "unable to parse dn string"); - goto out; - } - - py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0); - if (py_ret == NULL) { - talloc_free(mem_ctx); - PyErr_NoMemory(); - goto out; - } - py_ret->mem_ctx = mem_ctx; - py_ret->dn = ret; -out: - if (str != NULL) { - PyMem_Free(discard_const_p(char, str)); - } - return (PyObject *)py_ret; -} - -static void py_ldb_dn_dealloc(PyLdbDnObject *self) -{ - talloc_free(self->mem_ctx); - PyObject_Del(self); -} - -static PyTypeObject PyLdbDn = { - .tp_name = "ldb.Dn", - .tp_methods = py_ldb_dn_methods, - .tp_str = (reprfunc)py_ldb_dn_get_linearized, - .tp_repr = (reprfunc)py_ldb_dn_repr, - .tp_richcompare = (richcmpfunc)py_ldb_dn_richcmp, - .tp_as_sequence = &py_ldb_dn_seq, - .tp_doc = "A LDB distinguished name.", - .tp_new = py_ldb_dn_new, - .tp_dealloc = (destructor)py_ldb_dn_dealloc, - .tp_basicsize = sizeof(PyLdbDnObject), - .tp_flags = Py_TPFLAGS_DEFAULT, -}; - -/* Debug */ -static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0); -static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) -{ - PyObject *fn = (PyObject *)context; - PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyUnicode_FromFormatV(fmt, ap)); -} - -static PyObject *py_ldb_debug_func; - -static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args) -{ - PyObject *cb; - struct ldb_context *ldb_ctx; - - if (!PyArg_ParseTuple(args, "O", &cb)) - return NULL; - - if (py_ldb_debug_func != NULL) { - Py_DECREF(py_ldb_debug_func); - } - - Py_INCREF(cb); - /* FIXME: DECREF cb when exiting program */ - py_ldb_debug_func = cb; - ldb_ctx = pyldb_Ldb_AsLdbContext(self); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, - ldb_set_debug(ldb_ctx, py_ldb_debug, cb), - ldb_ctx); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args) -{ - unsigned int perms; - if (!PyArg_ParseTuple(args, "I", &perms)) - return NULL; - - ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args) -{ - char *modules_dir; - if (!PyArg_ParseTuple(args, "s", &modules_dir)) - return NULL; - - ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_transaction_start(PyLdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); - int ldb_err; - ldb_err = ldb_transaction_start(ldb_ctx); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx); - Py_RETURN_NONE; -} - -static PyObject *py_ldb_transaction_commit(PyLdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); - int ldb_err; - ldb_err = ldb_transaction_commit(ldb_ctx); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx); - Py_RETURN_NONE; -} - -static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); - int ldb_err; - ldb_err = ldb_transaction_prepare_commit(ldb_ctx); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx); - Py_RETURN_NONE; -} - -static PyObject *py_ldb_transaction_cancel(PyLdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); - int ldb_err; - ldb_err = ldb_transaction_cancel(ldb_ctx); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx); - Py_RETURN_NONE; -} - -static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); - int ldb_err; - ldb_err = ldb_setup_wellknown_attributes(ldb_ctx); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx); - Py_RETURN_NONE; -} - -static PyObject *py_ldb_repr(PyLdbObject *self) -{ - return PyUnicode_FromString(""); -} - -static PyObject *py_ldb_get_root_basedn(PyLdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self)); - if (dn == NULL) - Py_RETURN_NONE; - return py_ldb_dn_copy(dn); -} - - -static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self)); - if (dn == NULL) - Py_RETURN_NONE; - return py_ldb_dn_copy(dn); -} - -static PyObject *py_ldb_get_config_basedn(PyLdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self)); - if (dn == NULL) - Py_RETURN_NONE; - return py_ldb_dn_copy(dn); -} - -static PyObject *py_ldb_get_default_basedn(PyLdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self)); - if (dn == NULL) - Py_RETURN_NONE; - return py_ldb_dn_copy(dn); -} - -static const char **PyList_AsStrList(TALLOC_CTX *mem_ctx, PyObject *list, - const char *paramname) -{ - const char **ret; - Py_ssize_t i; - if (!PyList_Check(list)) { - PyErr_Format(PyExc_TypeError, "%s is not a list", paramname); - return NULL; - } - ret = talloc_array(NULL, const char *, PyList_Size(list)+1); - if (ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - - for (i = 0; i < PyList_Size(list); i++) { - const char *str = NULL; - Py_ssize_t size; - PyObject *item = PyList_GetItem(list, i); - if (!PyUnicode_Check(item)) { - PyErr_Format(PyExc_TypeError, "%s should be strings", paramname); - talloc_free(ret); - return NULL; - } - str = PyUnicode_AsUTF8AndSize(item, &size); - if (str == NULL) { - talloc_free(ret); - return NULL; - } - ret[i] = talloc_strndup(ret, str, size); - } - ret[i] = NULL; - return ret; -} - -static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs) -{ - const char * const kwnames[] = { "url", "flags", "options", NULL }; - char *url = NULL; - PyObject *py_options = Py_None; - const char **options; - unsigned int flags = 0; - int ret; - struct ldb_context *ldb; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__", - discard_const_p(char *, kwnames), - &url, &flags, &py_options)) - return -1; - - ldb = pyldb_Ldb_AsLdbContext(self); - - if (py_options == Py_None) { - options = NULL; - } else { - options = PyList_AsStrList(ldb, py_options, "options"); - if (options == NULL) - return -1; - } - - if (url != NULL) { - ret = ldb_connect(ldb, url, flags, options); - if (ret != LDB_SUCCESS) { - PyErr_SetLdbError(PyExc_LdbError, ret, ldb); - return -1; - } - } else { - ldb_set_flags(ldb, flags); - } - - talloc_free(options); - return 0; -} - -static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyLdbObject *ret; - struct ldb_context *ldb; - ret = (PyLdbObject *)type->tp_alloc(type, 0); - if (ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - ret->mem_ctx = talloc_new(NULL); - ldb = ldb_init(ret->mem_ctx, NULL); - - if (ldb == NULL) { - PyErr_NoMemory(); - return NULL; - } - - ret->ldb_ctx = ldb; - return (PyObject *)ret; -} - -static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs) -{ - char *url = NULL; - unsigned int flags = 0; - PyObject *py_options = Py_None; - int ret; - const char **options; - const char * const kwnames[] = { "url", "flags", "options", NULL }; - struct ldb_context *ldb_ctx; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|IO", - discard_const_p(char *, kwnames), - &url, &flags, &py_options)) - return NULL; - - if (py_options == Py_None) { - options = NULL; - } else { - options = PyList_AsStrList(NULL, py_options, "options"); - if (options == NULL) - return NULL; - } - - ldb_ctx = pyldb_Ldb_AsLdbContext(self); - ret = ldb_connect(ldb_ctx, url, flags, options); - talloc_free(options); - - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *py_msg; - PyObject *py_controls = Py_None; - struct ldb_context *ldb_ctx; - struct ldb_request *req; - struct ldb_control **parsed_controls; - struct ldb_message *msg; - int ret; - TALLOC_CTX *mem_ctx; - bool validate=true; - const char * const kwnames[] = { "message", "controls", "validate", NULL }; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob", - discard_const_p(char *, kwnames), - &py_msg, &py_controls, &validate)) - return NULL; - - mem_ctx = talloc_new(NULL); - if (mem_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - ldb_ctx = pyldb_Ldb_AsLdbContext(self); - - if (py_controls == Py_None) { - parsed_controls = NULL; - } else { - const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls"); - if (controls == NULL) { - talloc_free(mem_ctx); - return NULL; - } - parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); - talloc_free(controls); - } - - if (!PyLdbMessage_Check(py_msg)) { - PyErr_SetString(PyExc_TypeError, "Expected Ldb Message"); - talloc_free(mem_ctx); - return NULL; - } - msg = pyldb_Message_AsMessage(py_msg); - - if (validate) { - ret = ldb_msg_sanity_check(ldb_ctx, msg); - if (ret != LDB_SUCCESS) { - PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); - talloc_free(mem_ctx); - return NULL; - } - } - - ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls, - NULL, ldb_op_default_callback, NULL); - if (ret != LDB_SUCCESS) { - PyErr_SetString(PyExc_TypeError, "failed to build request"); - talloc_free(mem_ctx); - return NULL; - } - - /* do request and autostart a transaction */ - /* Then let's LDB handle the message error in case of pb as they are meaningful */ - - ret = ldb_transaction_start(ldb_ctx); - if (ret != LDB_SUCCESS) { - talloc_free(mem_ctx); - PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); - return NULL; - } - - ret = ldb_request(ldb_ctx, req); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - - if (ret == LDB_SUCCESS) { - ret = ldb_transaction_commit(ldb_ctx); - } else { - ldb_transaction_cancel(ldb_ctx); - } - - talloc_free(mem_ctx); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); - - Py_RETURN_NONE; -} - - -/** - * Obtain a ldb message from a Python Dictionary object. - * - * @param mem_ctx Memory context - * @param py_obj Python Dictionary object - * @param ldb_ctx LDB context - * @param mod_flags Flags to be set on every message element - * @return ldb_message on success or NULL on failure - */ -static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx, - PyObject *py_obj, - struct ldb_context *ldb_ctx, - unsigned int mod_flags) -{ - struct ldb_message *msg; - unsigned int msg_pos = 0; - Py_ssize_t dict_pos = 0; - PyObject *key, *value; - struct ldb_message_element *msg_el; - PyObject *dn_value = PyDict_GetItemString(py_obj, "dn"); - - msg = ldb_msg_new(mem_ctx); - if (msg == NULL) { - PyErr_NoMemory(); - return NULL; - } - msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj)); - - if (dn_value) { - if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) { - PyErr_SetString(PyExc_TypeError, "unable to import dn object"); - return NULL; - } - if (msg->dn == NULL) { - PyErr_SetString(PyExc_TypeError, "dn set but not found"); - return NULL; - } - } else { - PyErr_SetString(PyExc_TypeError, "no dn set"); - return NULL; - } - - while (PyDict_Next(py_obj, &dict_pos, &key, &value)) { - const char *key_str = PyUnicode_AsUTF8(key); - if (ldb_attr_cmp(key_str, "dn") != 0) { - msg_el = PyObject_AsMessageElement(msg->elements, value, - mod_flags, key_str); - if (msg_el == NULL) { - PyErr_Format(PyExc_TypeError, "unable to import element '%s'", key_str); - return NULL; - } - memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el)); - msg_pos++; - } - } - - msg->num_elements = msg_pos; - - return msg; -} - -static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *py_obj; - int ret; - struct ldb_context *ldb_ctx; - struct ldb_request *req; - struct ldb_message *msg = NULL; - PyObject *py_controls = Py_None; - TALLOC_CTX *mem_ctx; - struct ldb_control **parsed_controls; - const char * const kwnames[] = { "message", "controls", NULL }; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", - discard_const_p(char *, kwnames), - &py_obj, &py_controls)) - return NULL; - - mem_ctx = talloc_new(NULL); - if (mem_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - ldb_ctx = pyldb_Ldb_AsLdbContext(self); - - if (py_controls == Py_None) { - parsed_controls = NULL; - } else { - const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls"); - if (controls == NULL) { - talloc_free(mem_ctx); - return NULL; - } - parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); - talloc_free(controls); - } - - if (PyLdbMessage_Check(py_obj)) { - msg = pyldb_Message_AsMessage(py_obj); - } else if (PyDict_Check(py_obj)) { - msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD); - } else { - PyErr_SetString(PyExc_TypeError, - "Dictionary or LdbMessage object expected!"); - } - - if (!msg) { - /* we should have a PyErr already set */ - talloc_free(mem_ctx); - return NULL; - } - - ret = ldb_msg_sanity_check(ldb_ctx, msg); - if (ret != LDB_SUCCESS) { - PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); - talloc_free(mem_ctx); - return NULL; - } - - ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls, - NULL, ldb_op_default_callback, NULL); - if (ret != LDB_SUCCESS) { - PyErr_SetString(PyExc_TypeError, "failed to build request"); - talloc_free(mem_ctx); - return NULL; - } - - /* do request and autostart a transaction */ - /* Then let's LDB handle the message error in case of pb as they are meaningful */ - - ret = ldb_transaction_start(ldb_ctx); - if (ret != LDB_SUCCESS) { - talloc_free(mem_ctx); - PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); - return NULL; - } - - ret = ldb_request(ldb_ctx, req); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - - if (ret == LDB_SUCCESS) { - ret = ldb_transaction_commit(ldb_ctx); - } else { - ldb_transaction_cancel(ldb_ctx); - } - - talloc_free(mem_ctx); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *py_dn; - struct ldb_dn *dn; - int ret; - struct ldb_context *ldb_ctx; - struct ldb_request *req; - PyObject *py_controls = Py_None; - TALLOC_CTX *mem_ctx; - struct ldb_control **parsed_controls; - const char * const kwnames[] = { "dn", "controls", NULL }; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", - discard_const_p(char *, kwnames), - &py_dn, &py_controls)) - return NULL; - - mem_ctx = talloc_new(NULL); - if (mem_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - ldb_ctx = pyldb_Ldb_AsLdbContext(self); - - if (py_controls == Py_None) { - parsed_controls = NULL; - } else { - const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls"); - if (controls == NULL) { - talloc_free(mem_ctx); - return NULL; - } - parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); - talloc_free(controls); - } - - if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) { - talloc_free(mem_ctx); - return NULL; - } - - ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls, - NULL, ldb_op_default_callback, NULL); - if (ret != LDB_SUCCESS) { - PyErr_SetString(PyExc_TypeError, "failed to build request"); - talloc_free(mem_ctx); - return NULL; - } - - /* do request and autostart a transaction */ - /* Then let's LDB handle the message error in case of pb as they are meaningful */ - - ret = ldb_transaction_start(ldb_ctx); - if (ret != LDB_SUCCESS) { - talloc_free(mem_ctx); - PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); - return NULL; - } - - ret = ldb_request(ldb_ctx, req); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - - if (ret == LDB_SUCCESS) { - ret = ldb_transaction_commit(ldb_ctx); - } else { - ldb_transaction_cancel(ldb_ctx); - } - - talloc_free(mem_ctx); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *py_dn1, *py_dn2; - struct ldb_dn *dn1, *dn2; - int ret; - TALLOC_CTX *mem_ctx; - PyObject *py_controls = Py_None; - struct ldb_control **parsed_controls; - struct ldb_context *ldb_ctx; - struct ldb_request *req; - const char * const kwnames[] = { "dn1", "dn2", "controls", NULL }; - - ldb_ctx = pyldb_Ldb_AsLdbContext(self); - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O", - discard_const_p(char *, kwnames), - &py_dn1, &py_dn2, &py_controls)) - return NULL; - - - mem_ctx = talloc_new(NULL); - if (mem_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - - if (py_controls == Py_None) { - parsed_controls = NULL; - } else { - const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls"); - if (controls == NULL) { - talloc_free(mem_ctx); - return NULL; - } - parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); - talloc_free(controls); - } - - - if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) { - talloc_free(mem_ctx); - return NULL; - } - - if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) { - talloc_free(mem_ctx); - return NULL; - } - - ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls, - NULL, ldb_op_default_callback, NULL); - if (ret != LDB_SUCCESS) { - PyErr_SetString(PyExc_TypeError, "failed to build request"); - talloc_free(mem_ctx); - return NULL; - } - - /* do request and autostart a transaction */ - /* Then let's LDB handle the message error in case of pb as they are meaningful */ - - ret = ldb_transaction_start(ldb_ctx); - if (ret != LDB_SUCCESS) { - talloc_free(mem_ctx); - PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); - return NULL; - } - - ret = ldb_request(ldb_ctx, req); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - - if (ret == LDB_SUCCESS) { - ret = ldb_transaction_commit(ldb_ctx); - } else { - ldb_transaction_cancel(ldb_ctx); - } - - talloc_free(mem_ctx); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args) -{ - char *name; - if (!PyArg_ParseTuple(args, "s", &name)) - return NULL; - - ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args) -{ - char *attribute, *syntax; - unsigned int flags; - int ret; - struct ldb_context *ldb_ctx; - - if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax)) - return NULL; - - ldb_ctx = pyldb_Ldb_AsLdbContext(self); - ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax); - - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx); - - Py_RETURN_NONE; -} - -static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif) -{ - if (ldif == NULL) { - Py_RETURN_NONE; - } else { - /* We don't want this attached to the 'ldb' any more */ - PyObject *obj = PyLdbMessage_FromMessage(ldif->msg); - PyObject *result = - Py_BuildValue(discard_const_p(char, "(iO)"), - ldif->changetype, - obj); - Py_CLEAR(obj); - return result; - } -} - - -static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args) -{ - int changetype; - PyObject *py_msg; - struct ldb_ldif ldif; - PyObject *ret; - char *string; - TALLOC_CTX *mem_ctx; - - if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype)) - return NULL; - - if (!PyLdbMessage_Check(py_msg)) { - PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg"); - return NULL; - } - - ldif.msg = pyldb_Message_AsMessage(py_msg); - ldif.changetype = changetype; - - mem_ctx = talloc_new(NULL); - - string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif); - if (!string) { - PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF"); - return NULL; - } - - ret = PyUnicode_FromString(string); - - talloc_free(mem_ctx); - - return ret; -} - -static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args) -{ - PyObject *list, *ret; - struct ldb_ldif *ldif; - const char *s; - struct ldb_dn *last_dn = NULL; - - TALLOC_CTX *mem_ctx; - - if (!PyArg_ParseTuple(args, "s", &s)) - return NULL; - - mem_ctx = talloc_new(NULL); - if (!mem_ctx) { - Py_RETURN_NONE; - } - - list = PyList_New(0); - while (s && *s != '\0') { - ldif = ldb_ldif_read_string(self->ldb_ctx, &s); - talloc_steal(mem_ctx, ldif); - if (ldif) { - int res = 0; - PyObject *py_ldif = ldb_ldif_to_pyobject(ldif); - if (py_ldif == NULL) { - Py_CLEAR(list); - PyErr_BadArgument(); - talloc_free(mem_ctx); - return NULL; - } - res = PyList_Append(list, py_ldif); - Py_CLEAR(py_ldif); - if (res == -1) { - Py_CLEAR(list); - talloc_free(mem_ctx); - return NULL; - } - last_dn = ldif->msg->dn; - } else { - const char *last_dn_str = NULL; - const char *err_string = NULL; - if (last_dn == NULL) { - PyErr_SetString(PyExc_ValueError, - "unable to parse LDIF " - "string at first chunk"); - Py_CLEAR(list); - talloc_free(mem_ctx); - return NULL; - } - - last_dn_str - = ldb_dn_get_linearized(last_dn); - - err_string - = talloc_asprintf(mem_ctx, - "unable to parse ldif " - "string AFTER %s", - last_dn_str); - - PyErr_SetString(PyExc_ValueError, - err_string); - talloc_free(mem_ctx); - Py_CLEAR(list); - return NULL; - } - } - talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */ - ret = PyObject_GetIter(list); - Py_DECREF(list); - return ret; -} - -static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args) -{ - int ldb_ret; - PyObject *py_msg_old; - PyObject *py_msg_new; - struct ldb_message *diff; - struct ldb_context *ldb; - PyObject *py_ret; - - if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new)) - return NULL; - - if (!PyLdbMessage_Check(py_msg_old)) { - PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message"); - return NULL; - } - - if (!PyLdbMessage_Check(py_msg_new)) { - PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message"); - return NULL; - } - - ldb = pyldb_Ldb_AsLdbContext(self); - ldb_ret = ldb_msg_difference(ldb, ldb, - pyldb_Message_AsMessage(py_msg_old), - pyldb_Message_AsMessage(py_msg_new), - &diff); - if (ldb_ret != LDB_SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff"); - return NULL; - } - - py_ret = PyLdbMessage_FromMessage(diff); - - talloc_unlink(ldb, diff); - - return py_ret; -} - -static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args) -{ - const struct ldb_schema_attribute *a; - struct ldb_val old_val; - struct ldb_val new_val; - TALLOC_CTX *mem_ctx; - PyObject *ret; - char *element_name; - PyObject *val; - Py_ssize_t size; - int result; - - if (!PyArg_ParseTuple(args, "sO", &element_name, &val)) - return NULL; - - result = PyBytes_AsStringAndSize(val, (char **)&old_val.data, &size); - old_val.length = size; - - if (result != 0) { - PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String"); - return NULL; - } - - a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name); - - if (a == NULL) { - Py_RETURN_NONE; - } - - mem_ctx = talloc_new(NULL); - if (mem_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - - if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) { - talloc_free(mem_ctx); - Py_RETURN_NONE; - } - - ret = PyBytes_FromStringAndSize((const char *)new_val.data, new_val.length); - - talloc_free(mem_ctx); - - return ret; -} - -static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *py_base = Py_None; - int scope = LDB_SCOPE_DEFAULT; - char *expr = NULL; - PyObject *py_attrs = Py_None; - PyObject *py_controls = Py_None; - const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL }; - int ret; - struct ldb_result *res; - struct ldb_request *req; - const char **attrs; - struct ldb_context *ldb_ctx; - struct ldb_control **parsed_controls; - struct ldb_dn *base; - PyObject *py_ret; - TALLOC_CTX *mem_ctx; - - /* type "int" rather than "enum" for "scope" is intentional */ - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO", - discard_const_p(char *, kwnames), - &py_base, &scope, &expr, &py_attrs, &py_controls)) - return NULL; - - - mem_ctx = talloc_new(NULL); - if (mem_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - ldb_ctx = pyldb_Ldb_AsLdbContext(self); - - if (py_attrs == Py_None) { - attrs = NULL; - } else { - attrs = PyList_AsStrList(mem_ctx, py_attrs, "attrs"); - if (attrs == NULL) { - talloc_free(mem_ctx); - return NULL; - } - } - - if (py_base == Py_None) { - base = ldb_get_default_basedn(ldb_ctx); - } else { - if (!pyldb_Object_AsDn(mem_ctx, py_base, ldb_ctx, &base)) { - talloc_free(mem_ctx); - return NULL; - } - } - - if (py_controls == Py_None) { - parsed_controls = NULL; - } else { - const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls"); - if (controls == NULL) { - talloc_free(mem_ctx); - return NULL; - } - parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls); - talloc_free(controls); - } - - res = talloc_zero(mem_ctx, struct ldb_result); - if (res == NULL) { - PyErr_NoMemory(); - talloc_free(mem_ctx); - return NULL; - } - - ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx, - base, - scope, - expr, - attrs, - parsed_controls, - res, - ldb_search_default_callback, - NULL); - - if (ret != LDB_SUCCESS) { - talloc_free(mem_ctx); - PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); - return NULL; - } - - talloc_steal(req, attrs); - - ret = ldb_request(ldb_ctx, req); - - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - - if (ret != LDB_SUCCESS) { - talloc_free(mem_ctx); - PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); - return NULL; - } - - py_ret = PyLdbResult_FromResult(res); - - talloc_free(mem_ctx); - - return py_ret; -} - -static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply *reply) -{ - if (reply->py_iter != NULL) { - DLIST_REMOVE(reply->py_iter->state.next, reply); - if (reply->py_iter->state.result == reply) { - reply->py_iter->state.result = NULL; - } - reply->py_iter = NULL; - } - - if (reply->obj != NULL) { - Py_DECREF(reply->obj); - reply->obj = NULL; - } - - return 0; -} - -static int py_ldb_search_iterator_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - PyLdbSearchIteratorObject *py_iter = (PyLdbSearchIteratorObject *)req->context; - struct ldb_result result = { .msgs = NULL }; - struct py_ldb_search_iterator_reply *reply = NULL; - - if (ares == NULL) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - - if (ares->error != LDB_SUCCESS) { - int ret = ares->error; - TALLOC_FREE(ares); - return ldb_request_done(req, ret); - } - - reply = talloc_zero(py_iter->mem_ctx, - struct py_ldb_search_iterator_reply); - if (reply == NULL) { - TALLOC_FREE(ares); - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - reply->py_iter = py_iter; - talloc_set_destructor(reply, py_ldb_search_iterator_reply_destructor); - - switch (ares->type) { - case LDB_REPLY_ENTRY: - reply->obj = PyLdbMessage_FromMessage(ares->message); - if (reply->obj == NULL) { - TALLOC_FREE(ares); - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - DLIST_ADD_END(py_iter->state.next, reply); - TALLOC_FREE(ares); - return LDB_SUCCESS; - - case LDB_REPLY_REFERRAL: - reply->obj = PyUnicode_FromString(ares->referral); - if (reply->obj == NULL) { - TALLOC_FREE(ares); - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - DLIST_ADD_END(py_iter->state.next, reply); - TALLOC_FREE(ares); - return LDB_SUCCESS; - - case LDB_REPLY_DONE: - result = (struct ldb_result) { .controls = ares->controls }; - reply->obj = PyLdbResult_FromResult(&result); - if (reply->obj == NULL) { - TALLOC_FREE(ares); - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - py_iter->state.result = reply; - TALLOC_FREE(ares); - return ldb_request_done(req, LDB_SUCCESS); - } - - TALLOC_FREE(ares); - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); -} - -static PyObject *py_ldb_search_iterator(PyLdbObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *py_base = Py_None; - int scope = LDB_SCOPE_DEFAULT; - int timeout = 0; - char *expr = NULL; - PyObject *py_attrs = Py_None; - PyObject *py_controls = Py_None; - const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL }; - int ret; - const char **attrs; - struct ldb_context *ldb_ctx; - struct ldb_control **parsed_controls; - struct ldb_dn *base; - PyLdbSearchIteratorObject *py_iter; - - /* type "int" rather than "enum" for "scope" is intentional */ - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOOi", - discard_const_p(char *, kwnames), - &py_base, &scope, &expr, &py_attrs, &py_controls, &timeout)) - return NULL; - - py_iter = (PyLdbSearchIteratorObject *)PyLdbSearchIterator.tp_alloc(&PyLdbSearchIterator, 0); - if (py_iter == NULL) { - PyErr_NoMemory(); - return NULL; - } - py_iter->ldb = self; - Py_INCREF(self); - ZERO_STRUCT(py_iter->state); - py_iter->mem_ctx = talloc_new(NULL); - if (py_iter->mem_ctx == NULL) { - Py_DECREF(py_iter); - PyErr_NoMemory(); - return NULL; - } - - ldb_ctx = pyldb_Ldb_AsLdbContext(self); - - if (py_attrs == Py_None) { - attrs = NULL; - } else { - attrs = PyList_AsStrList(py_iter->mem_ctx, py_attrs, "attrs"); - if (attrs == NULL) { - Py_DECREF(py_iter); - PyErr_NoMemory(); - return NULL; - } - } - - if (py_base == Py_None) { - base = ldb_get_default_basedn(ldb_ctx); - } else { - if (!pyldb_Object_AsDn(py_iter->mem_ctx, py_base, ldb_ctx, &base)) { - Py_DECREF(py_iter); - PyErr_NoMemory(); - return NULL; - } - } - - if (py_controls == Py_None) { - parsed_controls = NULL; - } else { - const char **controls = NULL; - - controls = PyList_AsStrList(py_iter->mem_ctx, - py_controls, "controls"); - if (controls == NULL) { - Py_DECREF(py_iter); - PyErr_NoMemory(); - return NULL; - } - - parsed_controls = ldb_parse_control_strings(ldb_ctx, - py_iter->mem_ctx, - controls); - if (controls[0] != NULL && parsed_controls == NULL) { - Py_DECREF(py_iter); - PyErr_NoMemory(); - return NULL; - } - talloc_free(controls); - } - - ret = ldb_build_search_req(&py_iter->state.req, - ldb_ctx, - py_iter->mem_ctx, - base, - scope, - expr, - attrs, - parsed_controls, - py_iter, - py_ldb_search_iterator_callback, - NULL); - if (ret != LDB_SUCCESS) { - Py_DECREF(py_iter); - PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); - return NULL; - } - - ldb_set_timeout(ldb_ctx, py_iter->state.req, timeout); - - ret = ldb_request(ldb_ctx, py_iter->state.req); - if (ret != LDB_SUCCESS) { - Py_DECREF(py_iter); - PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); - return NULL; - } - - return (PyObject *)py_iter; -} - -static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args) -{ - char *name; - void *data; - - if (!PyArg_ParseTuple(args, "s", &name)) - return NULL; - - data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name); - - if (data == NULL) - Py_RETURN_NONE; - - /* FIXME: More interpretation */ - - Py_RETURN_TRUE; -} - -static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args) -{ - char *name; - PyObject *data; - - if (!PyArg_ParseTuple(args, "sO", &name, &data)) - return NULL; - - /* FIXME: More interpretation */ - - ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_modules(PyLdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self); - PyObject *ret = PyList_New(0); - struct ldb_module *mod; - - if (ret == NULL) { - return PyErr_NoMemory(); - } - for (mod = ldb->modules; mod; mod = mod->next) { - PyObject *item = PyLdbModule_FromModule(mod); - int res = 0; - if (item == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "Failed to load LdbModule"); - Py_CLEAR(ret); - return NULL; - } - res = PyList_Append(ret, item); - Py_CLEAR(item); - if (res == -1) { - Py_CLEAR(ret); - return NULL; - } - } - - return ret; -} - -static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args) -{ - struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self); - int type, ret; - uint64_t value; - - if (!PyArg_ParseTuple(args, "i", &type)) - return NULL; - - /* FIXME: More interpretation */ - - ret = ldb_sequence_number(ldb, type, &value); - - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb); - - return PyLong_FromLongLong(value); -} - - -static const struct ldb_dn_extended_syntax test_dn_syntax = { - .name = "TEST", - .read_fn = ldb_handler_copy, - .write_clear_fn = ldb_handler_copy, - .write_hex_fn = ldb_handler_copy, -}; - -static PyObject *py_ldb_register_test_extensions(PyLdbObject *self, - PyObject *Py_UNUSED(ignored)) -{ - struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self); - int ret; - - ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &test_dn_syntax); - - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb); - - Py_RETURN_NONE; -} - - -static PyMethodDef py_ldb_methods[] = { - { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS, - "S.set_debug(callback) -> None\n" - "Set callback for LDB debug messages.\n" - "The callback should accept a debug level and debug text." }, - { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS, - "S.set_create_perms(mode) -> None\n" - "Set mode to use when creating new LDB files." }, - { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS, - "S.set_modules_dir(path) -> None\n" - "Set path LDB should search for modules" }, - { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS, - "S.transaction_start() -> None\n" - "Start a new transaction." }, - { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS, - "S.transaction_prepare_commit() -> None\n" - "prepare to commit a new transaction (2-stage commit)." }, - { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS, - "S.transaction_commit() -> None\n" - "commit a new transaction." }, - { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS, - "S.transaction_cancel() -> None\n" - "cancel a new transaction." }, - { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS, - NULL }, - { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS, - NULL }, - { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS, - NULL }, - { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS, - NULL }, - { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS, - NULL }, - { "connect", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_connect), - METH_VARARGS|METH_KEYWORDS, - "S.connect(url, flags=0, options=None) -> None\n" - "Connect to a LDB URL." }, - { "modify", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_modify), - METH_VARARGS|METH_KEYWORDS, - "S.modify(message, controls=None, validate=False) -> None\n" - "Modify an entry." }, - { "add", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_add), - METH_VARARGS|METH_KEYWORDS, - "S.add(message, controls=None) -> None\n" - "Add an entry." }, - { "delete", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_delete), - METH_VARARGS|METH_KEYWORDS, - "S.delete(dn, controls=None) -> None\n" - "Remove an entry." }, - { "rename", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_rename), - METH_VARARGS|METH_KEYWORDS, - "S.rename(old_dn, new_dn, controls=None) -> None\n" - "Rename an entry." }, - { "search", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_search), - METH_VARARGS|METH_KEYWORDS, - "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n" - "Search in a database.\n" - "\n" - ":param base: Optional base DN to search\n" - ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n" - ":param expression: Optional search expression\n" - ":param attrs: Attributes to return (defaults to all)\n" - ":param controls: Optional list of controls\n" - ":return: ldb.Result object\n" - }, - { "search_iterator", PY_DISCARD_FUNC_SIG(PyCFunction, - py_ldb_search_iterator), - METH_VARARGS|METH_KEYWORDS, - "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n" - "Search in a database.\n" - "\n" - ":param base: Optional base DN to search\n" - ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n" - ":param expression: Optional search expression\n" - ":param attrs: Attributes to return (defaults to all)\n" - ":param controls: Optional list of controls\n" - ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n" - ":return: ldb.SearchIterator object that provides results when they arrive\n" - }, - { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS, - NULL }, - { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS, - NULL }, - { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS, - NULL }, - { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS, - "S.parse_ldif(ldif) -> iter(messages)\n" - "Parse a string formatted using LDIF." }, - { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS, - "S.write_ldif(message, changetype) -> ldif\n" - "Print the message as a string formatted using LDIF." }, - { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS, - "S.msg_diff(Message) -> Message\n" - "Return an LDB Message of the difference between two Message objects." }, - { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS, - "S.get_opaque(name) -> value\n" - "Get an opaque value set on this LDB connection. \n" - ":note: The returned value may not be useful in Python." - }, - { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS, - "S.set_opaque(name, value) -> None\n" - "Set an opaque value on this LDB connection. \n" - ":note: Passing incorrect values may cause crashes." }, - { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS, - "S.modules() -> list\n" - "Return the list of modules on this LDB connection " }, - { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS, - "S.sequence_number(type) -> value\n" - "Return the value of the sequence according to the requested type" }, - { "_register_test_extensions", (PyCFunction)py_ldb_register_test_extensions, METH_NOARGS, - "S._register_test_extensions() -> None\n" - "Register internal extensions used in testing" }, - { NULL }, -}; - -static PyObject *PyLdbModule_FromModule(struct ldb_module *mod) -{ - PyLdbModuleObject *ret; - - ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0); - if (ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - ret->mem_ctx = talloc_new(NULL); - ret->mod = talloc_reference(ret->mem_ctx, mod); - return (PyObject *)ret; -} - -static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure) -{ - struct ldb_module *mod = pyldb_Ldb_AsLdbContext(self)->modules; - if (mod == NULL) { - Py_RETURN_NONE; - } - return PyLdbModule_FromModule(mod); -} - -static PyGetSetDef py_ldb_getset[] = { - { - .name = discard_const_p(char, "firstmodule"), - .get = (getter)py_ldb_get_firstmodule, - }, - { .name = NULL }, -}; - -static int py_ldb_contains(PyLdbObject *self, PyObject *obj) -{ - struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self); - struct ldb_dn *dn; - struct ldb_result *result; - unsigned int count; - int ret; - - if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) { - return -1; - } - - ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL, - NULL); - if (ret != LDB_SUCCESS) { - PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx); - return -1; - } - - count = result->count; - - talloc_free(result); - - if (count > 1) { - PyErr_Format(PyExc_RuntimeError, - "Searching for [%s] dn gave %u results!", - ldb_dn_get_linearized(dn), - count); - return -1; - } - - return count; -} - -static PySequenceMethods py_ldb_seq = { - .sq_contains = (objobjproc)py_ldb_contains, -}; - -static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx) -{ - PyLdbObject *ret; - - ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0); - if (ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - ret->mem_ctx = talloc_new(NULL); - ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx); - return (PyObject *)ret; -} - -static void py_ldb_dealloc(PyLdbObject *self) -{ - talloc_free(self->mem_ctx); - Py_TYPE(self)->tp_free(self); -} - -static PyTypeObject PyLdb = { - .tp_name = "ldb.Ldb", - .tp_methods = py_ldb_methods, - .tp_repr = (reprfunc)py_ldb_repr, - .tp_new = py_ldb_new, - .tp_init = (initproc)py_ldb_init, - .tp_dealloc = (destructor)py_ldb_dealloc, - .tp_getset = py_ldb_getset, - .tp_getattro = PyObject_GenericGetAttr, - .tp_basicsize = sizeof(PyLdbObject), - .tp_doc = "Connection to a LDB database.", - .tp_as_sequence = &py_ldb_seq, - .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, -}; - -static void py_ldb_result_dealloc(PyLdbResultObject *self) -{ - talloc_free(self->mem_ctx); - Py_DECREF(self->msgs); - Py_DECREF(self->referals); - Py_DECREF(self->controls); - Py_TYPE(self)->tp_free(self); -} - -static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure) -{ - Py_INCREF(self->msgs); - return self->msgs; -} - -static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure) -{ - Py_INCREF(self->controls); - return self->controls; -} - -static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure) -{ - Py_INCREF(self->referals); - return self->referals; -} - -static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure) -{ - Py_ssize_t size; - if (self->msgs == NULL) { - PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context"); - return NULL; - } - size = PyList_Size(self->msgs); - return PyInt_FromLong(size); -} - -static PyGetSetDef py_ldb_result_getset[] = { - { - .name = discard_const_p(char, "controls"), - .get = (getter)py_ldb_result_get_controls, - }, - { - .name = discard_const_p(char, "msgs"), - .get = (getter)py_ldb_result_get_msgs, - }, - { - .name = discard_const_p(char, "referals"), - .get = (getter)py_ldb_result_get_referals, - }, - { - .name = discard_const_p(char, "count"), - .get = (getter)py_ldb_result_get_count, - }, - { .name = NULL }, -}; - -static PyObject *py_ldb_result_iter(PyLdbResultObject *self) -{ - return PyObject_GetIter(self->msgs); -} - -static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self) -{ - return PySequence_Size(self->msgs); -} - -static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx) -{ - return PySequence_GetItem(self->msgs, idx); -} - -static PySequenceMethods py_ldb_result_seq = { - .sq_length = (lenfunc)py_ldb_result_len, - .sq_item = (ssizeargfunc)py_ldb_result_find, -}; - -static PyObject *py_ldb_result_repr(PyLdbObject *self) -{ - return PyUnicode_FromString(""); -} - - -static PyTypeObject PyLdbResult = { - .tp_name = "ldb.Result", - .tp_repr = (reprfunc)py_ldb_result_repr, - .tp_dealloc = (destructor)py_ldb_result_dealloc, - .tp_iter = (getiterfunc)py_ldb_result_iter, - .tp_getset = py_ldb_result_getset, - .tp_getattro = PyObject_GenericGetAttr, - .tp_basicsize = sizeof(PyLdbResultObject), - .tp_as_sequence = &py_ldb_result_seq, - .tp_doc = "LDB result.", - .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, -}; - -static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject *self) -{ - Py_XDECREF(self->state.exception); - TALLOC_FREE(self->mem_ctx); - ZERO_STRUCT(self->state); - Py_DECREF(self->ldb); - Py_TYPE(self)->tp_free(self); -} - -static PyObject *py_ldb_search_iterator_next(PyLdbSearchIteratorObject *self) -{ - PyObject *py_ret = NULL; - - if (self->state.req == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "ldb.SearchIterator request already finished"); - return NULL; - } - - /* - * TODO: do we want a non-blocking mode? - * In future we may add an optional 'nonblocking' - * argument to search_iterator(). - * - * For now we keep it simple and wait for at - * least one reply. - */ - - while (self->state.next == NULL) { - int ret; - - if (self->state.result != NULL) { - /* - * We (already) got a final result from the server. - * - * We stop the iteration and let - * py_ldb_search_iterator_result() will deliver - * the result details. - */ - TALLOC_FREE(self->state.req); - PyErr_SetNone(PyExc_StopIteration); - return NULL; - } - - ret = ldb_wait(self->state.req->handle, LDB_WAIT_NONE); - if (ret != LDB_SUCCESS) { - struct ldb_context *ldb_ctx; - TALLOC_FREE(self->state.req); - ldb_ctx = pyldb_Ldb_AsLdbContext(self->ldb); - /* - * We stop the iteration and let - * py_ldb_search_iterator_result() will deliver - * the exception. - */ - self->state.exception = Py_BuildValue(discard_const_p(char, "(i,s)"), - ret, ldb_errstring(ldb_ctx)); - PyErr_SetNone(PyExc_StopIteration); - return NULL; - } - } - - py_ret = self->state.next->obj; - self->state.next->obj = NULL; - /* no TALLOC_FREE() as self->state.next is a list */ - talloc_free(self->state.next); - return py_ret; -} - -static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self, - PyObject *Py_UNUSED(ignored)) -{ - PyObject *py_ret = NULL; - - if (self->state.req != NULL) { - PyErr_SetString(PyExc_RuntimeError, - "ldb.SearchIterator request running"); - return NULL; - } - - if (self->state.next != NULL) { - PyErr_SetString(PyExc_RuntimeError, - "ldb.SearchIterator not fully consumed."); - return NULL; - } - - if (self->state.exception != NULL) { - PyErr_SetObject(PyExc_LdbError, self->state.exception); - self->state.exception = NULL; - return NULL; - } - - if (self->state.result == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "ldb.SearchIterator result already consumed"); - return NULL; - } - - py_ret = self->state.result->obj; - self->state.result->obj = NULL; - TALLOC_FREE(self->state.result); - return py_ret; -} - -static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self, - PyObject *Py_UNUSED(ignored)) -{ - if (self->state.req == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "ldb.SearchIterator request already finished"); - return NULL; - } - - Py_XDECREF(self->state.exception); - TALLOC_FREE(self->mem_ctx); - ZERO_STRUCT(self->state); - Py_RETURN_NONE; -} - -static PyMethodDef py_ldb_search_iterator_methods[] = { - { "result", (PyCFunction)py_ldb_search_iterator_result, METH_NOARGS, - "S.result() -> ldb.Result (without msgs and referrals)\n" }, - { "abandon", (PyCFunction)py_ldb_search_iterator_abandon, METH_NOARGS, - "S.abandon()\n" }, - { NULL } -}; - -static PyObject *py_ldb_search_iterator_repr(PyLdbSearchIteratorObject *self) -{ - return PyUnicode_FromString(""); -} - -static PyTypeObject PyLdbSearchIterator = { - .tp_name = "ldb.SearchIterator", - .tp_repr = (reprfunc)py_ldb_search_iterator_repr, - .tp_dealloc = (destructor)py_ldb_search_iterator_dealloc, - .tp_iter = PyObject_SelfIter, - .tp_iternext = (iternextfunc)py_ldb_search_iterator_next, - .tp_methods = py_ldb_search_iterator_methods, - .tp_basicsize = sizeof(PyLdbSearchIteratorObject), - .tp_doc = "LDB search_iterator.", - .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, -}; - -static PyObject *py_ldb_module_repr(PyLdbModuleObject *self) -{ - return PyUnicode_FromFormat("", - pyldb_Module_AsModule(self)->ops->name); -} - -static PyObject *py_ldb_module_str(PyLdbModuleObject *self) -{ - return PyUnicode_FromString(pyldb_Module_AsModule(self)->ops->name); -} - -static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self, - PyObject *Py_UNUSED(ignored)) -{ - pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self)); - Py_RETURN_NONE; -} - -static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self, - PyObject *Py_UNUSED(ignored)) -{ - pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self)); - Py_RETURN_NONE; -} - -static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self, - PyObject *Py_UNUSED(ignored)) -{ - pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self)); - Py_RETURN_NONE; -} - -static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *py_base, *py_tree, *py_attrs, *py_ret; - int ret, scope; - struct ldb_request *req; - const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL }; - struct ldb_module *mod; - const char * const*attrs; - - /* type "int" rather than "enum" for "scope" is intentional */ - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO", - discard_const_p(char *, kwnames), - &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs)) - return NULL; - - mod = self->mod; - - if (py_attrs == Py_None) { - attrs = NULL; - } else { - attrs = PyList_AsStrList(NULL, py_attrs, "attrs"); - if (attrs == NULL) - return NULL; - } - - ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base), - scope, NULL /* expr */, attrs, - NULL /* controls */, NULL, NULL, NULL); - - talloc_steal(req, attrs); - - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb); - - req->op.search.res = NULL; - - ret = mod->ops->search(mod, req); - - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb); - - py_ret = PyLdbResult_FromResult(req->op.search.res); - - talloc_free(req); - - return py_ret; -} - - -static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args) -{ - struct ldb_request *req; - PyObject *py_message; - int ret; - struct ldb_module *mod; - - if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message)) - return NULL; - - req = talloc_zero(NULL, struct ldb_request); - req->operation = LDB_ADD; - req->op.add.message = pyldb_Message_AsMessage(py_message); - - mod = pyldb_Module_AsModule(self); - ret = mod->ops->add(mod, req); - - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args) -{ - int ret; - struct ldb_request *req; - PyObject *py_message; - struct ldb_module *mod; - - if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message)) - return NULL; - - req = talloc_zero(NULL, struct ldb_request); - req->operation = LDB_MODIFY; - req->op.mod.message = pyldb_Message_AsMessage(py_message); - - mod = pyldb_Module_AsModule(self); - ret = mod->ops->modify(mod, req); - - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args) -{ - int ret; - struct ldb_request *req; - PyObject *py_dn; - - if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn)) - return NULL; - - req = talloc_zero(NULL, struct ldb_request); - req->operation = LDB_DELETE; - req->op.del.dn = pyldb_Dn_AsDn(py_dn); - - ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req); - - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args) -{ - int ret; - struct ldb_request *req; - PyObject *py_dn1, *py_dn2; - - if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2)) - return NULL; - - req = talloc_zero(NULL, struct ldb_request); - - req->operation = LDB_RENAME; - req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1); - req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2); - - ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req); - - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); - - Py_RETURN_NONE; -} - -static PyMethodDef py_ldb_module_methods[] = { - { "search", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_module_search), - METH_VARARGS|METH_KEYWORDS, NULL }, - { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL }, - { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL }, - { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL }, - { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL }, - { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL }, - { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL }, - { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL }, - { NULL }, -}; - -static void py_ldb_module_dealloc(PyLdbModuleObject *self) -{ - talloc_free(self->mem_ctx); - PyObject_Del(self); -} - -static PyTypeObject PyLdbModule = { - .tp_name = "ldb.LdbModule", - .tp_methods = py_ldb_module_methods, - .tp_repr = (reprfunc)py_ldb_module_repr, - .tp_str = (reprfunc)py_ldb_module_str, - .tp_basicsize = sizeof(PyLdbModuleObject), - .tp_dealloc = (destructor)py_ldb_module_dealloc, - .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_doc = "LDB module (extension)", -}; - - -/** - * Create a ldb_message_element from a Python object. - * - * This will accept any sequence objects that contains strings, or - * a string object. - * - * A reference to set_obj will be borrowed. - * - * @param mem_ctx Memory context - * @param set_obj Python object to convert - * @param flags ldb_message_element flags to set - * @param attr_name Name of the attribute - * @return New ldb_message_element, allocated as child of mem_ctx - */ -static struct ldb_message_element *PyObject_AsMessageElement( - TALLOC_CTX *mem_ctx, - PyObject *set_obj, - unsigned int flags, - const char *attr_name) -{ - struct ldb_message_element *me; - const char *msg = NULL; - Py_ssize_t size; - int result; - - if (pyldb_MessageElement_Check(set_obj)) { - PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj; - /* We have to talloc_reference() the memory context, not the pointer - * which may not actually be it's own context */ - if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) { - return pyldb_MessageElement_AsMessageElement(set_obj); - } - return NULL; - } - - me = talloc(mem_ctx, struct ldb_message_element); - if (me == NULL) { - PyErr_NoMemory(); - return NULL; - } - - me->name = talloc_strdup(me, attr_name); - me->flags = flags; - if (PyBytes_Check(set_obj) || PyUnicode_Check(set_obj)) { - me->num_values = 1; - me->values = talloc_array(me, struct ldb_val, me->num_values); - if (PyBytes_Check(set_obj)) { - char *_msg = NULL; - result = PyBytes_AsStringAndSize(set_obj, &_msg, &size); - if (result != 0) { - talloc_free(me); - return NULL; - } - msg = _msg; - } else { - msg = PyUnicode_AsUTF8AndSize(set_obj, &size); - if (msg == NULL) { - talloc_free(me); - return NULL; - } - } - me->values[0].data = talloc_memdup(me, - (const uint8_t *)msg, - size+1); - me->values[0].length = size; - } else if (PySequence_Check(set_obj)) { - Py_ssize_t i; - me->num_values = PySequence_Size(set_obj); - me->values = talloc_array(me, struct ldb_val, me->num_values); - for (i = 0; i < me->num_values; i++) { - PyObject *obj = PySequence_GetItem(set_obj, i); - if (PyBytes_Check(obj)) { - char *_msg = NULL; - result = PyBytes_AsStringAndSize(obj, &_msg, &size); - if (result != 0) { - talloc_free(me); - return NULL; - } - msg = _msg; - } else if (PyUnicode_Check(obj)) { - msg = PyUnicode_AsUTF8AndSize(obj, &size); - if (msg == NULL) { - talloc_free(me); - return NULL; - } - } else { - PyErr_Format(PyExc_TypeError, - "Expected string as element %zd in list", i); - talloc_free(me); - return NULL; - } - me->values[i].data = talloc_memdup(me, - (const uint8_t *)msg, - size+1); - me->values[i].length = size; - } - } else { - PyErr_Format(PyExc_TypeError, - "String or List type expected for '%s' attribute", attr_name); - talloc_free(me); - me = NULL; - } - - return me; -} - - -static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx, - struct ldb_message_element *me) -{ - Py_ssize_t i; - PyObject *result; - - /* Python << 2.5 doesn't have PySet_New and PySet_Add. */ - result = PyList_New(me->num_values); - - for (i = 0; i < me->num_values; i++) { - PyList_SetItem(result, i, - PyObject_FromLdbValue(&me->values[i])); - } - - return result; -} - -static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args) -{ - unsigned int i; - if (!PyArg_ParseTuple(args, "I", &i)) - return NULL; - if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values) - Py_RETURN_NONE; - - return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i])); -} - -static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args) -{ - struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self); - return PyInt_FromLong(el->flags); -} - -static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args) -{ - unsigned int flags; - struct ldb_message_element *el; - if (!PyArg_ParseTuple(args, "I", &flags)) - return NULL; - - el = pyldb_MessageElement_AsMessageElement(self); - el->flags = flags; - Py_RETURN_NONE; -} - -static PyMethodDef py_ldb_msg_element_methods[] = { - { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL }, - { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL }, - { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL }, - { NULL }, -}; - -static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self) -{ - return pyldb_MessageElement_AsMessageElement(self)->num_values; -} - -static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx) -{ - struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self); - if (idx < 0 || idx >= el->num_values) { - PyErr_SetString(PyExc_IndexError, "Out of range"); - return NULL; - } - return PyLdbBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length); -} - -static PySequenceMethods py_ldb_msg_element_seq = { - .sq_length = (lenfunc)py_ldb_msg_element_len, - .sq_item = (ssizeargfunc)py_ldb_msg_element_find, -}; - -static PyObject *py_ldb_msg_element_richcmp(PyObject *self, PyObject *other, int op) -{ - int ret; - if (!pyldb_MessageElement_Check(other)) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self), - pyldb_MessageElement_AsMessageElement(other)); - return richcmp(ret, op); -} - -static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self) -{ - PyObject *el = ldb_msg_element_to_set(NULL, - pyldb_MessageElement_AsMessageElement(self)); - PyObject *ret = PyObject_GetIter(el); - Py_DECREF(el); - return ret; -} - -static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx) -{ - PyLdbMessageElementObject *ret; - ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement); - if (ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - ret->mem_ctx = talloc_new(NULL); - if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) { - PyErr_NoMemory(); - return NULL; - } - ret->el = el; - return (PyObject *)ret; -} - -static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - PyObject *py_elements = NULL; - struct ldb_message_element *el; - unsigned int flags = 0; - char *name = NULL; - const char * const kwnames[] = { "elements", "flags", "name", NULL }; - PyLdbMessageElementObject *ret; - TALLOC_CTX *mem_ctx; - const char *msg = NULL; - Py_ssize_t size; - int result; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs", - discard_const_p(char *, kwnames), - &py_elements, &flags, &name)) - return NULL; - - mem_ctx = talloc_new(NULL); - if (mem_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - - el = talloc_zero(mem_ctx, struct ldb_message_element); - if (el == NULL) { - PyErr_NoMemory(); - talloc_free(mem_ctx); - return NULL; - } - - if (py_elements != NULL) { - Py_ssize_t i; - if (PyBytes_Check(py_elements) || PyUnicode_Check(py_elements)) { - char *_msg = NULL; - el->num_values = 1; - el->values = talloc_array(el, struct ldb_val, 1); - if (el->values == NULL) { - talloc_free(mem_ctx); - PyErr_NoMemory(); - return NULL; - } - if (PyBytes_Check(py_elements)) { - result = PyBytes_AsStringAndSize(py_elements, &_msg, &size); - msg = _msg; - } else { - msg = PyUnicode_AsUTF8AndSize(py_elements, &size); - result = (msg == NULL) ? -1 : 0; - } - if (result != 0) { - talloc_free(mem_ctx); - return NULL; - } - el->values[0].data = talloc_memdup(el->values, - (const uint8_t *)msg, size + 1); - el->values[0].length = size; - } else if (PySequence_Check(py_elements)) { - el->num_values = PySequence_Size(py_elements); - el->values = talloc_array(el, struct ldb_val, el->num_values); - if (el->values == NULL) { - talloc_free(mem_ctx); - PyErr_NoMemory(); - return NULL; - } - for (i = 0; i < el->num_values; i++) { - PyObject *item = PySequence_GetItem(py_elements, i); - if (item == NULL) { - talloc_free(mem_ctx); - return NULL; - } - if (PyBytes_Check(item)) { - char *_msg = NULL; - result = PyBytes_AsStringAndSize(item, &_msg, &size); - msg = _msg; - } else if (PyUnicode_Check(item)) { - msg = PyUnicode_AsUTF8AndSize(item, &size); - result = (msg == NULL) ? -1 : 0; - } else { - PyErr_Format(PyExc_TypeError, - "Expected string as element %zd in list", i); - result = -1; - } - if (result != 0) { - talloc_free(mem_ctx); - return NULL; - } - el->values[i].data = talloc_memdup(el, - (const uint8_t *)msg, size+1); - el->values[i].length = size; - } - } else { - PyErr_SetString(PyExc_TypeError, - "Expected string or list"); - talloc_free(mem_ctx); - return NULL; - } - } - - el->flags = flags; - el->name = talloc_strdup(el, name); - - ret = PyObject_New(PyLdbMessageElementObject, type); - if (ret == NULL) { - talloc_free(mem_ctx); - return NULL; - } - - ret->mem_ctx = mem_ctx; - ret->el = el; - return (PyObject *)ret; -} - -static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self) -{ - char *element_str = NULL; - Py_ssize_t i; - struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self); - PyObject *ret, *repr; - - for (i = 0; i < el->num_values; i++) { - PyObject *o = py_ldb_msg_element_find(self, i); - repr = PyObject_Repr(o); - if (element_str == NULL) - element_str = talloc_strdup(NULL, PyUnicode_AsUTF8(repr)); - else - element_str = talloc_asprintf_append(element_str, ",%s", PyUnicode_AsUTF8(repr)); - Py_DECREF(repr); - } - - if (element_str != NULL) { - ret = PyUnicode_FromFormat("MessageElement([%s])", element_str); - talloc_free(element_str); - } else { - ret = PyUnicode_FromString("MessageElement([])"); - } - - return ret; -} - -static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self) -{ - struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self); - - if (el->num_values == 1) - return PyUnicode_FromStringAndSize((char *)el->values[0].data, el->values[0].length); - else - Py_RETURN_NONE; -} - -static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self) -{ - talloc_free(self->mem_ctx); - PyObject_Del(self); -} - -static PyObject *py_ldb_msg_element_get_text(PyObject *self, void *closure) -{ - return wrap_text("MessageElementTextWrapper", self); -} - -static PyGetSetDef py_ldb_msg_element_getset[] = { - { - .name = discard_const_p(char, "text"), - .get = (getter)py_ldb_msg_element_get_text, - }, - { .name = NULL } -}; - -static PyTypeObject PyLdbMessageElement = { - .tp_name = "ldb.MessageElement", - .tp_basicsize = sizeof(PyLdbMessageElementObject), - .tp_dealloc = (destructor)py_ldb_msg_element_dealloc, - .tp_repr = (reprfunc)py_ldb_msg_element_repr, - .tp_str = (reprfunc)py_ldb_msg_element_str, - .tp_methods = py_ldb_msg_element_methods, - .tp_getset = py_ldb_msg_element_getset, - .tp_richcompare = (richcmpfunc)py_ldb_msg_element_richcmp, - .tp_iter = (getiterfunc)py_ldb_msg_element_iter, - .tp_as_sequence = &py_ldb_msg_element_seq, - .tp_new = py_ldb_msg_element_new, - .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_doc = "An element of a Message", -}; - - -static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args) -{ - PyObject *py_ldb; - PyObject *py_dict; - PyObject *py_ret; - struct ldb_message *msg; - struct ldb_context *ldb_ctx; - unsigned int mod_flags = LDB_FLAG_MOD_REPLACE; - - if (!PyArg_ParseTuple(args, "O!O!|I", - &PyLdb, &py_ldb, &PyDict_Type, &py_dict, - &mod_flags)) { - return NULL; - } - - if (!PyLdb_Check(py_ldb)) { - PyErr_SetString(PyExc_TypeError, "Expected Ldb"); - return NULL; - } - - /* mask only flags we are going to use */ - mod_flags = LDB_FLAG_MOD_TYPE(mod_flags); - if (!mod_flags) { - PyErr_SetString(PyExc_ValueError, - "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE" - " expected as mod_flag value"); - return NULL; - } - - ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb); - - msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags); - if (!msg) { - return NULL; - } - - py_ret = PyLdbMessage_FromMessage(msg); - - talloc_unlink(ldb_ctx, msg); - - return py_ret; -} - -static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args) -{ - char *name; - if (!PyArg_ParseTuple(args, "s", &name)) - return NULL; - - ldb_msg_remove_attr(self->msg, name); - - Py_RETURN_NONE; -} - -static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self, - PyObject *Py_UNUSED(ignored)) -{ - struct ldb_message *msg = pyldb_Message_AsMessage(self); - Py_ssize_t i, j = 0; - PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0)); - if (msg->dn != NULL) { - PyList_SetItem(obj, j, PyUnicode_FromString("dn")); - j++; - } - for (i = 0; i < msg->num_elements; i++) { - PyList_SetItem(obj, j, PyUnicode_FromString(msg->elements[i].name)); - j++; - } - return obj; -} - -static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name) -{ - struct ldb_message_element *el; - const char *name; - struct ldb_message *msg = pyldb_Message_AsMessage(self); - name = PyUnicode_AsUTF8(py_name); - if (name == NULL) { - PyErr_SetNone(PyExc_TypeError); - return NULL; - } - if (!ldb_attr_cmp(name, "dn")) - return pyldb_Dn_FromDn(msg->dn); - el = ldb_msg_find_element(msg, name); - if (el == NULL) { - return NULL; - } - return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements); -} - -static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name) -{ - PyObject *ret = py_ldb_msg_getitem_helper(self, py_name); - if (ret == NULL) { - PyErr_SetString(PyExc_KeyError, "No such element"); - return NULL; - } - return ret; -} - -static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *def = NULL; - const char *kwnames[] = { "name", "default", "idx", NULL }; - const char *name = NULL; - int idx = -1; - struct ldb_message *msg = pyldb_Message_AsMessage(self); - struct ldb_message_element *el; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg", - discard_const_p(char *, kwnames), &name, &def, &idx)) { - return NULL; - } - - if (strcasecmp(name, "dn") == 0) { - return pyldb_Dn_FromDn(msg->dn); - } - - el = ldb_msg_find_element(msg, name); - - if (el == NULL || (idx != -1 && el->num_values <= idx)) { - if (def != NULL) { - Py_INCREF(def); - return def; - } - Py_RETURN_NONE; - } - - if (idx == -1) { - return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements); - } - - return PyObject_FromLdbValue(&el->values[idx]); -} - -static PyObject *py_ldb_msg_items(PyLdbMessageObject *self, - PyObject *Py_UNUSED(ignored)) -{ - struct ldb_message *msg = pyldb_Message_AsMessage(self); - Py_ssize_t i, j = 0; - PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1)); - if (l == NULL) { - return PyErr_NoMemory(); - } - if (msg->dn != NULL) { - PyObject *value = NULL; - PyObject *obj = pyldb_Dn_FromDn(msg->dn); - int res = 0; - value = Py_BuildValue("(sO)", "dn", obj); - Py_CLEAR(obj); - if (value == NULL) { - Py_CLEAR(l); - return NULL; - } - res = PyList_SetItem(l, 0, value); - if (res == -1) { - Py_CLEAR(l); - return NULL; - } - j++; - } - for (i = 0; i < msg->num_elements; i++, j++) { - PyObject *value = NULL; - PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements); - int res = 0; - Py_CLEAR(py_el); - value = Py_BuildValue("(sO)", msg->elements[i].name, py_el); - if (value == NULL ) { - Py_CLEAR(l); - return NULL; - } - res = PyList_SetItem(l, 0, value); - if (res == -1) { - Py_CLEAR(l); - return NULL; - } - } - return l; -} - -static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self, - PyObject *Py_UNUSED(ignored)) -{ - struct ldb_message *msg = pyldb_Message_AsMessage(self); - Py_ssize_t i = 0; - PyObject *l = PyList_New(msg->num_elements); - for (i = 0; i < msg->num_elements; i++) { - PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements)); - } - return l; -} - -static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args) -{ - struct ldb_message *msg = pyldb_Message_AsMessage(self); - PyLdbMessageElementObject *py_element; - int i, ret; - struct ldb_message_element *el; - struct ldb_message_element *el_new; - - if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element)) - return NULL; - - el = py_element->el; - if (el == NULL) { - PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object"); - return NULL; - } - if (el->name == NULL) { - PyErr_SetString(PyExc_ValueError, - "The element has no name"); - return NULL; - } - ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new); - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); - - /* now deep copy all attribute values */ - el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values); - if (el_new->values == NULL) { - PyErr_NoMemory(); - return NULL; - } - el_new->num_values = el->num_values; - - for (i = 0; i < el->num_values; i++) { - el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]); - if (el_new->values[i].data == NULL - && el->values[i].length != 0) { - PyErr_NoMemory(); - return NULL; - } - } - - Py_RETURN_NONE; -} - -static PyMethodDef py_ldb_msg_methods[] = { - { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS, - "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n" - "Class method to create ldb.Message object from Dictionary.\n" - "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."}, - { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, - "S.keys() -> list\n\n" - "Return sequence of all attribute names." }, - { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, - "S.remove(name)\n\n" - "Remove all entries for attributes with the specified name."}, - { "get", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_msg_get), - METH_VARARGS | METH_KEYWORDS, - "msg.get(name,default=None,idx=None) -> string\n" - "idx is the index into the values array\n" - "if idx is None, then a list is returned\n" - "if idx is not None, then the element with that index is returned\n" - "if you pass the special name 'dn' then the DN object is returned\n"}, - { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL }, - { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL }, - { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS, - "S.add(element)\n\n" - "Add an element to this message." }, - { NULL }, -}; - -static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self) -{ - PyObject *list, *iter; - - list = py_ldb_msg_keys(self, NULL); - iter = PyObject_GetIter(list); - Py_DECREF(list); - return iter; -} - -static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value) -{ - const char *attr_name; - - attr_name = PyUnicode_AsUTF8(name); - if (attr_name == NULL) { - PyErr_SetNone(PyExc_TypeError); - return -1; - } - - if (value == NULL) { - /* delitem */ - ldb_msg_remove_attr(self->msg, attr_name); - } else { - int ret; - struct ldb_message_element *el = PyObject_AsMessageElement(self->msg, - value, 0, attr_name); - if (el == NULL) { - return -1; - } - ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name); - ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags); - if (ret != LDB_SUCCESS) { - PyErr_SetLdbError(PyExc_LdbError, ret, NULL); - return -1; - } - } - return 0; -} - -static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self) -{ - return pyldb_Message_AsMessage(self)->num_elements; -} - -static PyMappingMethods py_ldb_msg_mapping = { - .mp_length = (lenfunc)py_ldb_msg_length, - .mp_subscript = (binaryfunc)py_ldb_msg_getitem, - .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem, -}; - -static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - const char * const kwnames[] = { "dn", NULL }; - struct ldb_message *ret; - TALLOC_CTX *mem_ctx; - PyObject *pydn = NULL; - PyLdbMessageObject *py_ret; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", - discard_const_p(char *, kwnames), - &pydn)) - return NULL; - - mem_ctx = talloc_new(NULL); - if (mem_ctx == NULL) { - PyErr_NoMemory(); - return NULL; - } - - ret = ldb_msg_new(mem_ctx); - if (ret == NULL) { - talloc_free(mem_ctx); - PyErr_NoMemory(); - return NULL; - } - - if (pydn != NULL) { - struct ldb_dn *dn; - if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) { - talloc_free(mem_ctx); - return NULL; - } - ret->dn = talloc_reference(ret, dn); - } - - py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0); - if (py_ret == NULL) { - PyErr_NoMemory(); - talloc_free(mem_ctx); - return NULL; - } - - py_ret->mem_ctx = mem_ctx; - py_ret->msg = ret; - return (PyObject *)py_ret; -} - -static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg) -{ - PyLdbMessageObject *ret; - - ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0); - if (ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - ret->mem_ctx = talloc_new(NULL); - ret->msg = talloc_reference(ret->mem_ctx, msg); - return (PyObject *)ret; -} - -static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure) -{ - struct ldb_message *msg = pyldb_Message_AsMessage(self); - return pyldb_Dn_FromDn(msg->dn); -} - -static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure) -{ - struct ldb_message *msg = pyldb_Message_AsMessage(self); - if (!pyldb_Dn_Check(value)) { - PyErr_SetString(PyExc_TypeError, "expected dn"); - return -1; - } - - msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value)); - return 0; -} - -static PyObject *py_ldb_msg_get_text(PyObject *self, void *closure) -{ - return wrap_text("MessageTextWrapper", self); -} - -static PyGetSetDef py_ldb_msg_getset[] = { - { - .name = discard_const_p(char, "dn"), - .get = (getter)py_ldb_msg_get_dn, - .set = (setter)py_ldb_msg_set_dn, - }, - { - .name = discard_const_p(char, "text"), - .get = (getter)py_ldb_msg_get_text, - }, - { .name = NULL }, -}; - -static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self) -{ - PyObject *dict = PyDict_New(), *ret, *repr; - if (PyDict_Update(dict, (PyObject *)self) != 0) - return NULL; - repr = PyObject_Repr(dict); - if (repr == NULL) { - Py_DECREF(dict); - return NULL; - } - ret = PyUnicode_FromFormat("Message(%s)", PyUnicode_AsUTF8(repr)); - Py_DECREF(repr); - Py_DECREF(dict); - return ret; -} - -static void py_ldb_msg_dealloc(PyLdbMessageObject *self) -{ - talloc_free(self->mem_ctx); - PyObject_Del(self); -} - -static PyObject *py_ldb_msg_richcmp(PyLdbMessageObject *py_msg1, - PyLdbMessageObject *py_msg2, int op) -{ - struct ldb_message *msg1, *msg2; - unsigned int i; - int ret; - - if (!PyLdbMessage_Check(py_msg2)) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - - msg1 = pyldb_Message_AsMessage(py_msg1), - msg2 = pyldb_Message_AsMessage(py_msg2); - - if ((msg1->dn != NULL) || (msg2->dn != NULL)) { - ret = ldb_dn_compare(msg1->dn, msg2->dn); - if (ret != 0) { - return richcmp(ret, op); - } - } - - ret = msg1->num_elements - msg2->num_elements; - if (ret != 0) { - return richcmp(ret, op); - } - - for (i = 0; i < msg1->num_elements; i++) { - ret = ldb_msg_element_compare_name(&msg1->elements[i], - &msg2->elements[i]); - if (ret != 0) { - return richcmp(ret, op); - } - - ret = ldb_msg_element_compare(&msg1->elements[i], - &msg2->elements[i]); - if (ret != 0) { - return richcmp(ret, op); - } - } - - return richcmp(0, op); -} - -static PyTypeObject PyLdbMessage = { - .tp_name = "ldb.Message", - .tp_methods = py_ldb_msg_methods, - .tp_getset = py_ldb_msg_getset, - .tp_as_mapping = &py_ldb_msg_mapping, - .tp_basicsize = sizeof(PyLdbMessageObject), - .tp_dealloc = (destructor)py_ldb_msg_dealloc, - .tp_new = py_ldb_msg_new, - .tp_repr = (reprfunc)py_ldb_msg_repr, - .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_iter = (getiterfunc)py_ldb_msg_iter, - .tp_richcompare = (richcmpfunc)py_ldb_msg_richcmp, - .tp_doc = "A LDB Message", -}; - -static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree) -{ - PyLdbTreeObject *ret; - - ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0); - if (ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - - ret->mem_ctx = talloc_new(NULL); - ret->tree = talloc_reference(ret->mem_ctx, tree); - return (PyObject *)ret; -} - -static void py_ldb_tree_dealloc(PyLdbTreeObject *self) -{ - talloc_free(self->mem_ctx); - PyObject_Del(self); -} - -static PyTypeObject PyLdbTree = { - .tp_name = "ldb.Tree", - .tp_basicsize = sizeof(PyLdbTreeObject), - .tp_dealloc = (destructor)py_ldb_tree_dealloc, - .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_doc = "A search tree", -}; - -/* Ldb_module */ -static int py_module_search(struct ldb_module *mod, struct ldb_request *req) -{ - PyObject *py_ldb = (PyObject *)mod->private_data; - PyObject *py_result, *py_base, *py_attrs, *py_tree; - - py_base = pyldb_Dn_FromDn(req->op.search.base); - - if (py_base == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - py_tree = PyLdbTree_FromTree(req->op.search.tree); - - if (py_tree == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - if (req->op.search.attrs == NULL) { - py_attrs = Py_None; - } else { - int i, len; - for (len = 0; req->op.search.attrs[len]; len++); - py_attrs = PyList_New(len); - for (i = 0; i < len; i++) - PyList_SetItem(py_attrs, i, PyUnicode_FromString(req->op.search.attrs[i])); - } - - py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"), - discard_const_p(char, "OiOO"), - py_base, req->op.search.scope, py_tree, py_attrs); - - Py_DECREF(py_attrs); - Py_DECREF(py_tree); - Py_DECREF(py_base); - - if (py_result == NULL) { - return LDB_ERR_PYTHON_EXCEPTION; - } - - req->op.search.res = PyLdbResult_AsResult(NULL, py_result); - if (req->op.search.res == NULL) { - return LDB_ERR_PYTHON_EXCEPTION; - } - - Py_DECREF(py_result); - - return LDB_SUCCESS; -} - -static int py_module_add(struct ldb_module *mod, struct ldb_request *req) -{ - PyObject *py_ldb = (PyObject *)mod->private_data; - PyObject *py_result, *py_msg; - - py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message)); - - if (py_msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"), - discard_const_p(char, "O"), - py_msg); - - Py_DECREF(py_msg); - - if (py_result == NULL) { - return LDB_ERR_PYTHON_EXCEPTION; - } - - Py_DECREF(py_result); - - return LDB_SUCCESS; -} - -static int py_module_modify(struct ldb_module *mod, struct ldb_request *req) -{ - PyObject *py_ldb = (PyObject *)mod->private_data; - PyObject *py_result, *py_msg; - - py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message)); - - if (py_msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"), - discard_const_p(char, "O"), - py_msg); - - Py_DECREF(py_msg); - - if (py_result == NULL) { - return LDB_ERR_PYTHON_EXCEPTION; - } - - Py_DECREF(py_result); - - return LDB_SUCCESS; -} - -static int py_module_del(struct ldb_module *mod, struct ldb_request *req) -{ - PyObject *py_ldb = (PyObject *)mod->private_data; - PyObject *py_result, *py_dn; - - py_dn = pyldb_Dn_FromDn(req->op.del.dn); - - if (py_dn == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"), - discard_const_p(char, "O"), - py_dn); - - if (py_result == NULL) { - return LDB_ERR_PYTHON_EXCEPTION; - } - - Py_DECREF(py_result); - - return LDB_SUCCESS; -} - -static int py_module_rename(struct ldb_module *mod, struct ldb_request *req) -{ - PyObject *py_ldb = (PyObject *)mod->private_data; - PyObject *py_result, *py_olddn, *py_newdn; - - py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn); - - if (py_olddn == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn); - - if (py_newdn == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"), - discard_const_p(char, "OO"), - py_olddn, py_newdn); - - Py_DECREF(py_olddn); - Py_DECREF(py_newdn); - - if (py_result == NULL) { - return LDB_ERR_PYTHON_EXCEPTION; - } - - Py_DECREF(py_result); - - return LDB_SUCCESS; -} - -static int py_module_request(struct ldb_module *mod, struct ldb_request *req) -{ - PyObject *py_ldb = (PyObject *)mod->private_data; - PyObject *py_result; - - py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"), - discard_const_p(char, "")); - - Py_XDECREF(py_result); - - return LDB_ERR_OPERATIONS_ERROR; -} - -static int py_module_extended(struct ldb_module *mod, struct ldb_request *req) -{ - PyObject *py_ldb = (PyObject *)mod->private_data; - PyObject *py_result; - - py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"), - discard_const_p(char, "")); - - Py_XDECREF(py_result); - - return LDB_ERR_OPERATIONS_ERROR; -} - -static int py_module_start_transaction(struct ldb_module *mod) -{ - PyObject *py_ldb = (PyObject *)mod->private_data; - PyObject *py_result; - - py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"), - discard_const_p(char, "")); - - if (py_result == NULL) { - return LDB_ERR_PYTHON_EXCEPTION; - } - - Py_DECREF(py_result); - - return LDB_SUCCESS; -} - -static int py_module_end_transaction(struct ldb_module *mod) -{ - PyObject *py_ldb = (PyObject *)mod->private_data; - PyObject *py_result; - - py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"), - discard_const_p(char, "")); - - if (py_result == NULL) { - return LDB_ERR_PYTHON_EXCEPTION; - } - - Py_DECREF(py_result); - - return LDB_SUCCESS; -} - -static int py_module_del_transaction(struct ldb_module *mod) -{ - PyObject *py_ldb = (PyObject *)mod->private_data; - PyObject *py_result; - - py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"), - discard_const_p(char, "")); - - if (py_result == NULL) { - return LDB_ERR_PYTHON_EXCEPTION; - } - - Py_DECREF(py_result); - - return LDB_SUCCESS; -} - -static int py_module_destructor(struct ldb_module *mod) -{ - Py_DECREF((PyObject *)mod->private_data); - return 0; -} - -static int py_module_init(struct ldb_module *mod) -{ - PyObject *py_class = (PyObject *)mod->ops->private_data; - PyObject *py_result, *py_next, *py_ldb; - - py_ldb = PyLdb_FromLdbContext(mod->ldb); - - if (py_ldb == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - py_next = PyLdbModule_FromModule(mod->next); - - if (py_next == NULL) - return LDB_ERR_OPERATIONS_ERROR; - - py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"), - py_ldb, py_next); - - if (py_result == NULL) { - return LDB_ERR_PYTHON_EXCEPTION; - } - - mod->private_data = py_result; - - talloc_set_destructor(mod, py_module_destructor); - - return ldb_next_init(mod); -} - -static PyObject *py_register_module(PyObject *module, PyObject *args) -{ - int ret; - struct ldb_module_ops *ops; - PyObject *input; - PyObject *tmp; - - if (!PyArg_ParseTuple(args, "O", &input)) - return NULL; - - ops = talloc_zero(NULL, struct ldb_module_ops); - if (ops == NULL) { - PyErr_NoMemory(); - return NULL; - } - - tmp = PyObject_GetAttrString(input, discard_const_p(char, "name")); - ops->name = talloc_strdup(ops, PyUnicode_AsUTF8(tmp)); - - Py_XDECREF(tmp); - Py_INCREF(input); - ops->private_data = input; - ops->init_context = py_module_init; - ops->search = py_module_search; - ops->add = py_module_add; - ops->modify = py_module_modify; - ops->del = py_module_del; - ops->rename = py_module_rename; - ops->request = py_module_request; - ops->extended = py_module_extended; - ops->start_transaction = py_module_start_transaction; - ops->end_transaction = py_module_end_transaction; - ops->del_transaction = py_module_del_transaction; - - ret = ldb_register_module(ops); - if (ret != LDB_SUCCESS) { - TALLOC_FREE(ops); - } - - PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL); - - Py_RETURN_NONE; -} - -static PyObject *py_timestring(PyObject *module, PyObject *args) -{ - /* most times "time_t" is a signed integer type with 32 or 64 bit: - * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */ - long int t_val; - char *tresult; - PyObject *ret; - if (!PyArg_ParseTuple(args, "l", &t_val)) - return NULL; - tresult = ldb_timestring(NULL, (time_t) t_val); - ret = PyUnicode_FromString(tresult); - talloc_free(tresult); - return ret; -} - -static PyObject *py_string_to_time(PyObject *module, PyObject *args) -{ - char *str; - if (!PyArg_ParseTuple(args, "s", &str)) - return NULL; - - return PyInt_FromLong(ldb_string_to_time(str)); -} - -static PyObject *py_valid_attr_name(PyObject *self, PyObject *args) -{ - char *name; - if (!PyArg_ParseTuple(args, "s", &name)) - return NULL; - return PyBool_FromLong(ldb_valid_attr_name(name)); -} - -/* - encode a string using RFC2254 rules - */ -static PyObject *py_binary_encode(PyObject *self, PyObject *args) -{ - char *str, *encoded; - Py_ssize_t size = 0; - struct ldb_val val; - PyObject *ret; - - if (!PyArg_ParseTuple(args, "s#", &str, &size)) - return NULL; - val.data = (uint8_t *)str; - val.length = size; - - encoded = ldb_binary_encode(NULL, val); - if (encoded == NULL) { - PyErr_SetString(PyExc_TypeError, "unable to encode binary string"); - return NULL; - } - ret = PyUnicode_FromString(encoded); - talloc_free(encoded); - return ret; -} - -/* - decode a string using RFC2254 rules - */ -static PyObject *py_binary_decode(PyObject *self, PyObject *args) -{ - char *str; - struct ldb_val val; - PyObject *ret; - - if (!PyArg_ParseTuple(args, "s", &str)) - return NULL; - - val = ldb_binary_decode(NULL, str); - if (val.data == NULL) { - PyErr_SetString(PyExc_TypeError, "unable to decode binary string"); - return NULL; - } - ret = PyBytes_FromStringAndSize((const char*)val.data, val.length); - talloc_free(val.data); - return ret; -} - -static PyMethodDef py_ldb_global_methods[] = { - { "register_module", py_register_module, METH_VARARGS, - "S.register_module(module) -> None\n\n" - "Register a LDB module."}, - { "timestring", py_timestring, METH_VARARGS, - "S.timestring(int) -> string\n\n" - "Generate a LDAP time string from a UNIX timestamp" }, - { "string_to_time", py_string_to_time, METH_VARARGS, - "S.string_to_time(string) -> int\n\n" - "Parse a LDAP time string into a UNIX timestamp." }, - { "valid_attr_name", py_valid_attr_name, METH_VARARGS, - "S.valid_attr_name(name) -> bool\n\nn" - "Check whether the supplied name is a valid attribute name." }, - { "open", PY_DISCARD_FUNC_SIG(PyCFunction,py_ldb_new), - METH_VARARGS|METH_KEYWORDS, - "S.open() -> Ldb\n\n" - "Open a new LDB context." }, - { "binary_encode", py_binary_encode, METH_VARARGS, - "S.binary_encode(string) -> string\n\n" - "Perform a RFC2254 binary encoding on a string" }, - { "binary_decode", py_binary_decode, METH_VARARGS, - "S.binary_decode(string) -> string\n\n" - "Perform a RFC2254 binary decode on a string" }, - { NULL } -}; - -#define MODULE_DOC "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server." - -#if PY_MAJOR_VERSION >= 3 -static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - .m_name = "ldb", - .m_doc = MODULE_DOC, - .m_size = -1, - .m_methods = py_ldb_global_methods, -}; -#endif - -static PyObject* module_init(void) -{ - PyObject *m; - - PyLdbBytesType.tp_base = &PyBytes_Type; - if (PyType_Ready(&PyLdbBytesType) < 0) { - return NULL; - } - - if (PyType_Ready(&PyLdbDn) < 0) - return NULL; - - if (PyType_Ready(&PyLdbMessage) < 0) - return NULL; - - if (PyType_Ready(&PyLdbMessageElement) < 0) - return NULL; - - if (PyType_Ready(&PyLdb) < 0) - return NULL; - - if (PyType_Ready(&PyLdbModule) < 0) - return NULL; - - if (PyType_Ready(&PyLdbTree) < 0) - return NULL; - - if (PyType_Ready(&PyLdbResult) < 0) - return NULL; - - if (PyType_Ready(&PyLdbSearchIterator) < 0) - return NULL; - - if (PyType_Ready(&PyLdbControl) < 0) - return NULL; - -#if PY_MAJOR_VERSION >= 3 - m = PyModule_Create(&moduledef); -#else - m = Py_InitModule3("ldb", py_ldb_global_methods, MODULE_DOC); -#endif - if (m == NULL) - return NULL; - -#define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val) - - ADD_LDB_INT(SEQ_HIGHEST_SEQ); - ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP); - ADD_LDB_INT(SEQ_NEXT); - ADD_LDB_INT(SCOPE_DEFAULT); - ADD_LDB_INT(SCOPE_BASE); - ADD_LDB_INT(SCOPE_ONELEVEL); - ADD_LDB_INT(SCOPE_SUBTREE); - - ADD_LDB_INT(CHANGETYPE_NONE); - ADD_LDB_INT(CHANGETYPE_ADD); - ADD_LDB_INT(CHANGETYPE_DELETE); - ADD_LDB_INT(CHANGETYPE_MODIFY); - - ADD_LDB_INT(FLAG_MOD_ADD); - ADD_LDB_INT(FLAG_MOD_REPLACE); - ADD_LDB_INT(FLAG_MOD_DELETE); - ADD_LDB_INT(FLAG_FORCE_NO_BASE64_LDIF); - - ADD_LDB_INT(ATTR_FLAG_HIDDEN); - ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX); - ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE); - ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF); - - ADD_LDB_INT(SUCCESS); - ADD_LDB_INT(ERR_OPERATIONS_ERROR); - ADD_LDB_INT(ERR_PROTOCOL_ERROR); - ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED); - ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED); - ADD_LDB_INT(ERR_COMPARE_FALSE); - ADD_LDB_INT(ERR_COMPARE_TRUE); - ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED); - ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED); - ADD_LDB_INT(ERR_REFERRAL); - ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED); - ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION); - ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED); - ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS); - ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE); - ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE); - ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING); - ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION); - ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS); - ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX); - ADD_LDB_INT(ERR_NO_SUCH_OBJECT); - ADD_LDB_INT(ERR_ALIAS_PROBLEM); - ADD_LDB_INT(ERR_INVALID_DN_SYNTAX); - ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM); - ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION); - ADD_LDB_INT(ERR_INVALID_CREDENTIALS); - ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS); - ADD_LDB_INT(ERR_BUSY); - ADD_LDB_INT(ERR_UNAVAILABLE); - ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM); - ADD_LDB_INT(ERR_LOOP_DETECT); - ADD_LDB_INT(ERR_NAMING_VIOLATION); - ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION); - ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF); - ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN); - ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS); - ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED); - ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS); - ADD_LDB_INT(ERR_OTHER); - - ADD_LDB_INT(FLG_RDONLY); - ADD_LDB_INT(FLG_NOSYNC); - ADD_LDB_INT(FLG_RECONNECT); - ADD_LDB_INT(FLG_NOMMAP); - ADD_LDB_INT(FLG_SHOW_BINARY); - ADD_LDB_INT(FLG_ENABLE_TRACING); - ADD_LDB_INT(FLG_DONT_CREATE_DB); - - ADD_LDB_INT(PACKING_FORMAT); - ADD_LDB_INT(PACKING_FORMAT_V2); - - /* Historical misspelling */ - PyModule_AddIntConstant(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM); - - PyModule_AddStringConstant(m, "__docformat__", "restructuredText"); - - PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL); - PyModule_AddObject(m, "LdbError", PyExc_LdbError); - - Py_INCREF(&PyLdb); - Py_INCREF(&PyLdbDn); - Py_INCREF(&PyLdbModule); - Py_INCREF(&PyLdbMessage); - Py_INCREF(&PyLdbMessageElement); - Py_INCREF(&PyLdbTree); - Py_INCREF(&PyLdbResult); - Py_INCREF(&PyLdbControl); - - PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb); - PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn); - PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage); - PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement); - PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule); - PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree); - PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl); - - PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION); - -#define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val) - - ADD_LDB_STRING(SYNTAX_DN); - ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING); - ADD_LDB_STRING(SYNTAX_INTEGER); - ADD_LDB_STRING(SYNTAX_ORDERED_INTEGER); - ADD_LDB_STRING(SYNTAX_BOOLEAN); - ADD_LDB_STRING(SYNTAX_OCTET_STRING); - ADD_LDB_STRING(SYNTAX_UTC_TIME); - ADD_LDB_STRING(OID_COMPARATOR_AND); - ADD_LDB_STRING(OID_COMPARATOR_OR); - - return m; -} - -#if PY_MAJOR_VERSION >= 3 -PyMODINIT_FUNC PyInit_ldb(void); -PyMODINIT_FUNC PyInit_ldb(void) -{ - return module_init(); -} -#else -void initldb(void); -void initldb(void) -{ - module_init(); -} -#endif diff --git a/ldb-2.0.8/pyldb.h b/ldb-2.0.8/pyldb.h deleted file mode 100644 index 4fc89ec..0000000 --- a/ldb-2.0.8/pyldb.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Python interface to ldb. - - Copyright (C) 2007-2008 Jelmer Vernooij - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#ifndef _PYLDB_H_ -#define _PYLDB_H_ - -#include - -typedef struct { - PyObject_HEAD - TALLOC_CTX *mem_ctx; - struct ldb_context *ldb_ctx; -} PyLdbObject; - -#define pyldb_Ldb_AsLdbContext(pyobj) ((PyLdbObject *)pyobj)->ldb_ctx - -typedef struct { - PyObject_HEAD - TALLOC_CTX *mem_ctx; - struct ldb_dn *dn; -} PyLdbDnObject; - -PyObject *pyldb_Dn_FromDn(struct ldb_dn *); -bool pyldb_Object_AsDn(TALLOC_CTX *mem_ctx, PyObject *object, struct ldb_context *ldb_ctx, struct ldb_dn **dn); -#define pyldb_Dn_AsDn(pyobj) ((PyLdbDnObject *)pyobj)->dn - -typedef struct { - PyObject_HEAD - TALLOC_CTX *mem_ctx; - struct ldb_message *msg; -} PyLdbMessageObject; -#define pyldb_Message_AsMessage(pyobj) ((PyLdbMessageObject *)pyobj)->msg - -typedef struct { - PyObject_HEAD - TALLOC_CTX *mem_ctx; - struct ldb_module *mod; -} PyLdbModuleObject; -#define pyldb_Module_AsModule(pyobj) ((PyLdbModuleObject *)pyobj)->mod - -/* - * NOTE: el (and so the return value of - * pyldb_MessageElement_AsMessageElement()) may not be a valid talloc - * context, it could be part of an array - */ - -typedef struct { - PyObject_HEAD - TALLOC_CTX *mem_ctx; - struct ldb_message_element *el; -} PyLdbMessageElementObject; - -#define pyldb_MessageElement_AsMessageElement(pyobj) ((PyLdbMessageElementObject *)pyobj)->el - -typedef struct { - PyObject_HEAD - TALLOC_CTX *mem_ctx; - struct ldb_parse_tree *tree; -} PyLdbTreeObject; -#define pyldb_Tree_AsTree(pyobj) ((PyLdbTreeObject *)pyobj)->tree - -typedef struct { - PyObject_HEAD - TALLOC_CTX *mem_ctx; - PyObject *msgs; - PyObject *referals; - PyObject *controls; -} PyLdbResultObject; - -typedef struct { - PyObject_HEAD - TALLOC_CTX *mem_ctx; - struct ldb_control *data; -} PyLdbControlObject; - -#define PyErr_LDB_ERROR_IS_ERR_RAISE(err,ret,ldb) do { \ - if (ret != LDB_SUCCESS) { \ - PyErr_SetLdbError(err, ret, ldb); \ - return NULL; \ - } \ -} while(0) - -/* Picked out of thin air. To do this properly, we should probably have some part of the - * errors in LDB be allocated to bindings ? */ -#define LDB_ERR_PYTHON_EXCEPTION 142 - -#endif /* _PYLDB_H_ */ diff --git a/ldb-2.0.8/pyldb_util.c b/ldb-2.0.8/pyldb_util.c deleted file mode 100644 index f8d0664..0000000 --- a/ldb-2.0.8/pyldb_util.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Python interface to ldb - utility functions. - - Copyright (C) 2007-2010 Jelmer Vernooij - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include -#include "ldb.h" -#include "pyldb.h" - -static PyObject *ldb_module = NULL; - -/** - * Find out PyTypeObject in ldb module for a given typename - */ -static PyTypeObject * PyLdb_GetPyType(const char *typename) -{ - PyObject *py_obj = NULL; - - if (ldb_module == NULL) { - ldb_module = PyImport_ImportModule("ldb"); - if (ldb_module == NULL) { - return NULL; - } - } - - py_obj = PyObject_GetAttrString(ldb_module, typename); - - return (PyTypeObject*)py_obj; -} - -/** - * Obtain a ldb DN from a Python object. - * - * @param mem_ctx Memory context - * @param object Python object - * @param ldb_ctx LDB context - * @return Whether or not the conversion succeeded - */ -bool pyldb_Object_AsDn(TALLOC_CTX *mem_ctx, PyObject *object, - struct ldb_context *ldb_ctx, struct ldb_dn **dn) -{ - struct ldb_dn *odn; - PyTypeObject *PyLdb_Dn_Type; - - if (ldb_ctx != NULL && (PyUnicode_Check(object))) { - odn = ldb_dn_new(mem_ctx, ldb_ctx, PyUnicode_AsUTF8(object)); - *dn = odn; - return true; - } - - if (ldb_ctx != NULL && PyBytes_Check(object)) { - odn = ldb_dn_new(mem_ctx, ldb_ctx, PyBytes_AsString(object)); - *dn = odn; - return true; - } - - PyLdb_Dn_Type = PyLdb_GetPyType("Dn"); - if (PyLdb_Dn_Type == NULL) { - return false; - } - - if (PyObject_TypeCheck(object, PyLdb_Dn_Type)) { - *dn = pyldb_Dn_AsDn(object); - return true; - } - - PyErr_SetString(PyExc_TypeError, "Expected DN"); - return false; -} - -PyObject *pyldb_Dn_FromDn(struct ldb_dn *dn) -{ - PyLdbDnObject *py_ret; - PyTypeObject *PyLdb_Dn_Type; - - if (dn == NULL) { - Py_RETURN_NONE; - } - - PyLdb_Dn_Type = PyLdb_GetPyType("Dn"); - if (PyLdb_Dn_Type == NULL) { - return NULL; - } - - py_ret = (PyLdbDnObject *)PyLdb_Dn_Type->tp_alloc(PyLdb_Dn_Type, 0); - if (py_ret == NULL) { - PyErr_NoMemory(); - return NULL; - } - py_ret->mem_ctx = talloc_new(NULL); - py_ret->dn = talloc_reference(py_ret->mem_ctx, dn); - return (PyObject *)py_ret; -} diff --git a/ldb-2.0.8/tests/guidindexpackv1.ldb b/ldb-2.0.8/tests/guidindexpackv1.ldb deleted file mode 100644 index 4c79dfeddddb95cdb46a044522ca4eae99f3a3d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1286144 zcmeI*U5H#)0SE9Kn}<+IjkbyvKNbsZ!Kkydp9x*rB%9QQxCz;f2CK#-JKILHNi>Gy zM?s_yLSKqRsZeO3FP1)Nu?4|a(p+S5}H6X!rWV5Nq2a<{;5aa>biD) zb9Rjzvvv5D8*^S~B|v}x0RjXF5FkK+009C72oNAZfB*pk1PBlyK!8A}3%vIioi3pN zODgd5B|V#y5g$ zxUBwOoB)BhFUd5FpUHz?qA!*HNQh;MAG=b!!9&5Fk)Y z;J%lN9e1-GwflEBTaP-kKN~J|X212C009C72oNAZptA(7_`bKZ0@qst1eQ$T$csyM zDkma9fB*pk1PFA5z`0*`L^pMk009C72oNB!WCEW%yJV+wA_4>m5FkK+Kt~8X|ErGZ zrcM$dK!5-N0t5&UAV7cs0RjXF5FkKc#R+uz+g2+s6AdD;Sb_h1p#BU~f4}~R`YqN7 z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV6TX3Ec6)nHEp1Ns4$f&xqD=6Xn1sNWc$9&!=oenc8zV{JhE+Qe9Nb{ZrK=~?AmjG@?bdXZJ|caVX^wB zx9=Gr-8Ghk*QqW&q0-2{>eJInY$)7#fSFu3W!!9$aksrvP)Qp0+8!+N=4y{BQl zw_&}nVZFa$eV}1|Ff?(|oEt)o#xo^H4@_68d*2@R)|@Okb~1BwI4ZYX zo;@N?e_0C4;jr{Q^VnVKu`@EZxvmd`sXkdy^n_JFLc&hG!hkD6uG zpP5y<$@y9JH_K`uJF8;DFDt7TPD~ExXVu?MR_RKuXVtfutZx7Mwa1!e)t8x7y2<%j z^)<_?KRc^p!!Ks_#BY=2-tZVdKmQn(`1u+CO;wT4&*5-^$5qgwtl`&fI8e_`EwzLDR*ayw%&U8(i{bwJ98|io18xuyPJ*0a`sp(_V$_^i?vx@o&L_c{H(g$$tqo`^{nDs zrclYs>gj(a*PCTk%FHU=vpCCTaV7{9Ola#&jVzH%w<%XEd;tiO?vzAqCFsVnj4bgKmR{7~iSwucTJeXufFeXVzfs^LD`rcz(IyHxHjmj^#q z`fPHd@|Ba7qlYSEC#MfqzFIvn-tp^R;G_Li*dI$2en(jD2+QOH7oVSN)0T;eJ)>Lq zhMQT{R)xLEaLu;3UM-&tU#~owBs;@n?Au4e68kpyv(TM z1UgROj5$>no%yLVi$2BTPVmK0-F<+?8LHj3z?BPaS5=V!0RjXF5FkK+009C7+7Wm> zRB|7n9XWLf5FkK+0D+rSpv&*NZqj6RtCIx=yXt!%{~lZY7Hb4LNZ==-ukHhMP~f^s zfB*pk1PBlyK!8BI0=v6rYSzxVVIINSIUmgTP2U+VYg&xO@+ ze9QCkMw9o)DLg`{om<9yf=y>)Zk#_iJvm?N*U|-MeVNH-?rYYy)O>=4vr13S*LqgP zCOiv)Wo2bP!NOUYPcUAWYvyy0zY1x%-Y+T|pDq9Z diff --git a/ldb-2.0.8/tests/init.ldif b/ldb-2.0.8/tests/init.ldif deleted file mode 100644 index 97b4561..0000000 --- a/ldb-2.0.8/tests/init.ldif +++ /dev/null @@ -1,41 +0,0 @@ -dn: o=University of Michigan,c=TEST -objectclass: organization -objectclass: domainRelatedObject -l: Ann Arbor, Michigan -st: Michigan -o: University of Michigan -o: UMICH -o: UM -o: U-M -o: U of M -description: The University of Michigan at Ann Arbor -postaladdress: University of Michigan $ 535 W. William St. $ Ann Arbor, MI 481 - 09 $ US -telephonenumber: +1 313 764-1817 -associateddomain: example.com - -# there was an empty "seeAlso" here - -dn: ou=People,o=University of Michigan,c=TEST -objectclass: organizationalUnit -objectclass: extensibleObject -ou: People -uidNumber: 0 -gidNumber: 0 - -dn: ou=Ldb Test,ou=People,o=University of Michigan,c=TEST -objectclass: organizationalUnit -objectclass: extensibleObject -ou: People -ou: Ldb Test -uidNumber: 0 -gidNumber: 0 - -dn: ou=LdbTspace,ou=People,o=University of Michigan,c=TEST -objectclass: organizationalUnit -objectclass: extensibleObject -ou: People -ou: LdbTspace -description: test white space removal in comparisons -uidNumber: 0 -gidNumber: 0 diff --git a/ldb-2.0.8/tests/init_slapd.sh b/ldb-2.0.8/tests/init_slapd.sh deleted file mode 100755 index cf06acd..0000000 --- a/ldb-2.0.8/tests/init_slapd.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/sh - -if [ -z "$LDBDIR" ]; then - LDBDIR=`dirname $0`/.. - export LDBDIR -fi - -rm -rf tests/tmp/db -mkdir -p tests/tmp/db - -if [ -f tests/tmp/slapd.pid ]; then - kill `cat tests/tmp/slapd.pid` - sleep 1 -fi -if [ -f tests/tmp/slapd.pid ]; then - kill -9 `cat tests/tmp/slapd.pid` - rm -f tests/tmp/slapd.pid -fi - -# we don't consider a slapadd failure as a test suite failure, as it -# has nothing to do with ldb - -MODCONF=tests/tmp/modules.conf -rm -f $MODCONF -touch $MODCONF || exit 1 - -slaptest -u -f $LDBDIR/tests/slapd.conf > /dev/null 2>&1 || { - echo "enabling sladp modules" -cat > $MODCONF < 2019 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/* - * from cmocka.c: - * These headers or their equivalents should be included prior to - * including - * this header file. - * - * #include - * #include - * #include - * - * This allows test applications to use custom definitions of C standard - * library functions and types. - */ -#include -#include -#include -#include -#include - -#include "../include/ldb.h" -#include "../include/ldb_module.h" - -struct ldbtest_ctx { - struct tevent_context *ev; - struct ldb_context *ldb; -}; - -/* - * NOTE WELL: - * - * This test checks the current behaviour of the function, however - * this is not in a public ABI and many of the tested behaviours are - * not ideal. If the behaviour is deliberatly improved, this test - * should be updated without worry to the new better behaviour. - * - * In particular the test is particularly to ensure the current - * behaviour is memory-safe. - */ - -static int setup(void **state) -{ - struct ldbtest_ctx *test_ctx; - - test_ctx = talloc_zero(NULL, struct ldbtest_ctx); - assert_non_null(test_ctx); - - test_ctx->ev = tevent_context_init(test_ctx); - assert_non_null(test_ctx->ev); - - test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev); - assert_non_null(test_ctx->ldb); - - *state = test_ctx; - return 0; -} - -static int teardown(void **state) -{ - talloc_free(*state); - return 0; -} - - -/* - * Test against a record with only one attribute, matching the one in - * the list - */ -static void test_filter_attrs_one_attr_matched(void **state) -{ - struct ldbtest_ctx *ctx = *state; - int ret; - - struct ldb_message *filtered_msg = ldb_msg_new(ctx); - - const char *attrs[] = {"foo", NULL}; - - uint8_t value[] = "The value.......end"; - struct ldb_val value_1 = { - .data = value, - .length = (sizeof(value)) - }; - struct ldb_message_element element_1 = { - .name = "foo", - .num_values = 1, - .values = &value_1 - }; - struct ldb_message in = { - .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), - .num_elements = 1, - .elements = &element_1, - }; - - assert_non_null(in.dn); - - ret = ldb_filter_attrs(ctx->ldb, - &in, - attrs, - filtered_msg); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(filtered_msg); - - /* - * assert the ldb_filter_attrs does not read or modify - * filtered_msg.dn in this case - */ - assert_null(filtered_msg->dn); - assert_int_equal(filtered_msg->num_elements, 1); - assert_string_equal(filtered_msg->elements[0].name, "foo"); - assert_int_equal(filtered_msg->elements[0].num_values, 1); - assert_int_equal(filtered_msg->elements[0].values[0].length, - sizeof(value)); - assert_memory_equal(filtered_msg->elements[0].values[0].data, - value, sizeof(value)); -} - -/* - * Test against a record with only one attribute, matching the one of - * the multiple attributes in the list - */ -static void test_filter_attrs_one_attr_matched_of_many(void **state) -{ - struct ldbtest_ctx *ctx = *state; - int ret; - - struct ldb_message *filtered_msg = ldb_msg_new(ctx); - - const char *attrs[] = {"foo", "bar", "baz", NULL}; - - uint8_t value[] = "The value.......end"; - struct ldb_val value_1 = { - .data = value, - .length = (sizeof(value)) - }; - struct ldb_message_element element_1 = { - .name = "foo", - .num_values = 1, - .values = &value_1 - }; - struct ldb_message in = { - .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), - .num_elements = 1, - .elements = &element_1, - }; - - assert_non_null(in.dn); - - ret = ldb_filter_attrs(ctx->ldb, - &in, - attrs, - filtered_msg); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(filtered_msg); - - /* - * assert the ldb_filter_attrs does not read or modify - * filtered_msg.dn in this case - */ - assert_null(filtered_msg->dn); - assert_int_equal(filtered_msg->num_elements, 1); - assert_string_equal(filtered_msg->elements[0].name, "foo"); - assert_int_equal(filtered_msg->elements[0].num_values, 1); - assert_int_equal(filtered_msg->elements[0].values[0].length, - sizeof(value)); - assert_memory_equal(filtered_msg->elements[0].values[0].data, - value, sizeof(value)); -} - -/* - * Test against a record with only one attribute, matching both - * attributes in the list - */ -static void test_filter_attrs_two_attr_matched_attrs(void **state) -{ - struct ldbtest_ctx *ctx = *state; - int ret; - - struct ldb_message *filtered_msg = ldb_msg_new(ctx); - - /* deliberatly the other order */ - const char *attrs[] = {"bar", "foo", NULL}; - - uint8_t value1[] = "The value.......end"; - uint8_t value2[] = "The value..MUST.end"; - struct ldb_val value_1 = { - .data = value1, - .length = (sizeof(value1)) - }; - struct ldb_val value_2 = { - .data = value2, - .length = (sizeof(value2)) - }; - - /* foo and bar are the other order to in attrs */ - struct ldb_message_element elements[] = { - { - .name = "foo", - .num_values = 1, - .values = &value_1 - }, - { - .name = "bar", - .num_values = 1, - .values = &value_2 - } - }; - struct ldb_message in = { - .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), - .num_elements = 2, - .elements = elements, - }; - - assert_non_null(in.dn); - - ret = ldb_filter_attrs(ctx->ldb, - &in, - attrs, - filtered_msg); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(filtered_msg); - assert_int_equal(filtered_msg->num_elements, 2); - - /* - * assert the ldb_filter_attrs does not read or modify - * filtered_msg.dn in this case - */ - assert_null(filtered_msg->dn); - - /* Assert that DB order is preserved */ - assert_string_equal(filtered_msg->elements[0].name, "foo"); - assert_int_equal(filtered_msg->elements[0].num_values, 1); - assert_int_equal(filtered_msg->elements[0].values[0].length, - sizeof(value1)); - assert_memory_equal(filtered_msg->elements[0].values[0].data, - value1, sizeof(value1)); - assert_string_equal(filtered_msg->elements[1].name, "bar"); - assert_int_equal(filtered_msg->elements[1].num_values, 1); - assert_int_equal(filtered_msg->elements[1].values[0].length, - sizeof(value2)); - assert_memory_equal(filtered_msg->elements[1].values[0].data, - value2, sizeof(value2)); -} - -/* - * Test against a record with two attributes, only of which is in - * the list - */ -static void test_filter_attrs_two_attr_matched_one_attr(void **state) -{ - struct ldbtest_ctx *ctx = *state; - int ret; - - struct ldb_message *filtered_msg = ldb_msg_new(ctx); - - /* deliberatly the other order */ - const char *attrs[] = {"bar", NULL}; - - uint8_t value1[] = "The value.......end"; - uint8_t value2[] = "The value..MUST.end"; - struct ldb_val value_1 = { - .data = value1, - .length = (sizeof(value1)) - }; - struct ldb_val value_2 = { - .data = value2, - .length = (sizeof(value2)) - }; - - /* foo and bar are the other order to in attrs */ - struct ldb_message_element elements[] = { - { - .name = "foo", - .num_values = 1, - .values = &value_1 - }, - { - .name = "bar", - .num_values = 1, - .values = &value_2 - } - }; - struct ldb_message in = { - .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), - .num_elements = 2, - .elements = elements, - }; - - assert_non_null(in.dn); - - ret = ldb_filter_attrs(ctx->ldb, - &in, - attrs, - filtered_msg); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(filtered_msg); - assert_int_equal(filtered_msg->num_elements, 1); - - /* - * assert the ldb_filter_attrs does not read or modify - * filtered_msg.dn in this case - */ - assert_null(filtered_msg->dn); - - /* Assert that DB order is preserved */ - assert_string_equal(filtered_msg->elements[0].name, "bar"); - assert_int_equal(filtered_msg->elements[0].num_values, 1); - assert_int_equal(filtered_msg->elements[0].values[0].length, - sizeof(value2)); - assert_memory_equal(filtered_msg->elements[0].values[0].data, - value2, sizeof(value2)); -} - -/* - * Test against a record with two attributes, both matching the one - * specified attribute in the list (a corrupt record) - */ -static void test_filter_attrs_two_dup_attr_matched_one_attr(void **state) -{ - struct ldbtest_ctx *ctx = *state; - int ret; - - struct ldb_message *filtered_msg = ldb_msg_new(ctx); - - /* deliberatly the other order */ - const char *attrs[] = {"bar", NULL}; - - uint8_t value1[] = "The value.......end"; - uint8_t value2[] = "The value..MUST.end"; - struct ldb_val value_1 = { - .data = value1, - .length = (sizeof(value1)) - }; - struct ldb_val value_2 = { - .data = value2, - .length = (sizeof(value2)) - }; - - /* foo and bar are the other order to in attrs */ - struct ldb_message_element elements[] = { - { - .name = "bar", - .num_values = 1, - .values = &value_1 - }, - { - .name = "bar", - .num_values = 1, - .values = &value_2 - } - }; - struct ldb_message in = { - .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), - .num_elements = 2, - .elements = elements, - }; - - assert_non_null(in.dn); - - ret = ldb_filter_attrs(ctx->ldb, - &in, - attrs, - filtered_msg); - - /* This should fail the pidgenhole test */ - assert_int_equal(ret, -1); - assert_null(filtered_msg->elements); -} - -/* - * Test against a record with two attributes, both matching the one - * specified attribute in the list (a corrupt record) - */ -static void test_filter_attrs_two_dup_attr_matched_dup(void **state) -{ - struct ldbtest_ctx *ctx = *state; - int ret; - - struct ldb_message *filtered_msg = ldb_msg_new(ctx); - - const char *attrs[] = {"bar", "bar", NULL}; - - uint8_t value1[] = "The value.......end"; - uint8_t value2[] = "The value..MUST.end"; - struct ldb_val value_1 = { - .data = value1, - .length = (sizeof(value1)) - }; - struct ldb_val value_2 = { - .data = value2, - .length = (sizeof(value2)) - }; - - /* foo and bar are the other order to in attrs */ - struct ldb_message_element elements[] = { - { - .name = "bar", - .num_values = 1, - .values = &value_1 - }, - { - .name = "bar", - .num_values = 1, - .values = &value_2 - } - }; - struct ldb_message in = { - .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), - .num_elements = 2, - .elements = elements, - }; - - assert_non_null(in.dn); - - ret = ldb_filter_attrs(ctx->ldb, - &in, - attrs, - filtered_msg); - - /* This does not fail the pidgenhole test */ - assert_int_equal(ret, LDB_SUCCESS); - assert_int_equal(filtered_msg->num_elements, 2); - - /* Assert that DB order is preserved */ - assert_string_equal(filtered_msg->elements[0].name, "bar"); - assert_int_equal(filtered_msg->elements[0].num_values, 1); - assert_int_equal(filtered_msg->elements[0].values[0].length, - sizeof(value1)); - assert_memory_equal(filtered_msg->elements[0].values[0].data, - value1, sizeof(value1)); - assert_string_equal(filtered_msg->elements[1].name, "bar"); - assert_int_equal(filtered_msg->elements[1].num_values, 1); - assert_int_equal(filtered_msg->elements[1].values[0].length, - sizeof(value2)); - assert_memory_equal(filtered_msg->elements[1].values[0].data, - value2, sizeof(value2)); -} - -/* - * Test against a record with two attributes, both matching one of the - * specified attributes in the list (a corrupt record) - */ -static void test_filter_attrs_two_dup_attr_matched_one_of_two(void **state) -{ - struct ldbtest_ctx *ctx = *state; - int ret; - - struct ldb_message *filtered_msg = ldb_msg_new(ctx); - - const char *attrs[] = {"bar", "foo", NULL}; - - uint8_t value1[] = "The value.......end"; - uint8_t value2[] = "The value..MUST.end"; - struct ldb_val value_1 = { - .data = value1, - .length = (sizeof(value1)) - }; - struct ldb_val value_2 = { - .data = value2, - .length = (sizeof(value2)) - }; - - /* foo and bar are the other order to in attrs */ - struct ldb_message_element elements[] = { - { - .name = "bar", - .num_values = 1, - .values = &value_1 - }, - { - .name = "bar", - .num_values = 1, - .values = &value_2 - } - }; - struct ldb_message in = { - .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), - .num_elements = 2, - .elements = elements, - }; - - assert_non_null(in.dn); - - ret = ldb_filter_attrs(ctx->ldb, - &in, - attrs, - filtered_msg); - - /* This does not fail the pidgenhole test */ - assert_int_equal(ret, LDB_SUCCESS); - assert_int_equal(filtered_msg->num_elements, 2); - - /* Assert that DB order is preserved */ - assert_string_equal(filtered_msg->elements[0].name, "bar"); - assert_int_equal(filtered_msg->elements[0].num_values, 1); - assert_int_equal(filtered_msg->elements[0].values[0].length, - sizeof(value1)); - assert_memory_equal(filtered_msg->elements[0].values[0].data, - value1, sizeof(value1)); - assert_string_equal(filtered_msg->elements[1].name, "bar"); - assert_int_equal(filtered_msg->elements[1].num_values, 1); - assert_int_equal(filtered_msg->elements[1].values[0].length, - sizeof(value2)); - assert_memory_equal(filtered_msg->elements[1].values[0].data, - value2, sizeof(value2)); -} - -/* - * Test against a record with two attributes against * (but not the - * other named attribute) (a corrupt record) - */ -static void test_filter_attrs_two_dup_attr_matched_star(void **state) -{ - struct ldbtest_ctx *ctx = *state; - int ret; - - struct ldb_message *filtered_msg = ldb_msg_new(ctx); - - const char *attrs[] = {"*", "foo", NULL}; - - uint8_t value1[] = "The value.......end"; - uint8_t value2[] = "The value..MUST.end"; - struct ldb_val value_1 = { - .data = value1, - .length = (sizeof(value1)) - }; - struct ldb_val value_2 = { - .data = value2, - .length = (sizeof(value2)) - }; - - /* foo and bar are the other order to in attrs */ - struct ldb_message_element elements[] = { - { - .name = "bar", - .num_values = 1, - .values = &value_1 - }, - { - .name = "bar", - .num_values = 1, - .values = &value_2 - } - }; - struct ldb_message in = { - .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), - .num_elements = 2, - .elements = elements, - }; - - assert_non_null(in.dn); - - /* Needed as * implies distinguishedName */ - filtered_msg->dn = in.dn; - - ret = ldb_filter_attrs(ctx->ldb, - &in, - attrs, - filtered_msg); - - /* This does not fail the pidgenhole test */ - assert_int_equal(ret, LDB_SUCCESS); - assert_int_equal(filtered_msg->num_elements, 3); - - /* Assert that DB order is preserved */ - assert_string_equal(filtered_msg->elements[0].name, "bar"); - assert_int_equal(filtered_msg->elements[0].num_values, 1); - assert_int_equal(filtered_msg->elements[0].values[0].length, - sizeof(value1)); - assert_memory_equal(filtered_msg->elements[0].values[0].data, - value1, sizeof(value1)); - assert_string_equal(filtered_msg->elements[1].name, "bar"); - assert_int_equal(filtered_msg->elements[1].num_values, 1); - assert_int_equal(filtered_msg->elements[1].values[0].length, - sizeof(value2)); - assert_memory_equal(filtered_msg->elements[1].values[0].data, - value2, sizeof(value2)); - /* - * assert the ldb_filter_attrs does not modify filtered_msg.dn - * in this case - */ - assert_ptr_equal(filtered_msg->dn, in.dn); - assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, - "distinguishedName", - NULL), - ldb_dn_get_linearized(in.dn)); -} - -/* - * Test against a record with only one attribute, matching the * in - * the list - */ -static void test_filter_attrs_one_attr_matched_star(void **state) -{ - struct ldbtest_ctx *ctx = *state; - int ret; - - struct ldb_message *filtered_msg = ldb_msg_new(ctx); - - const char *attrs[] = {"*", NULL}; - - uint8_t value[] = "The value.......end"; - struct ldb_val value_1 = { - .data = value, - .length = (sizeof(value)) - }; - struct ldb_message_element element_1 = { - .name = "foo", - .num_values = 1, - .values = &value_1 - }; - struct ldb_message in = { - .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), - .num_elements = 1, - .elements = &element_1, - }; - - assert_non_null(in.dn); - - /* Needed as * implies distinguishedName */ - filtered_msg->dn = in.dn; - - ret = ldb_filter_attrs(ctx->ldb, - &in, - attrs, - filtered_msg); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(filtered_msg); - assert_int_equal(filtered_msg->num_elements, 2); - - /* - * assert the ldb_filter_attrs does not modify filtered_msg.dn - * in this case - */ - assert_ptr_equal(filtered_msg->dn, in.dn); - assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, - "distinguishedName", - NULL), - ldb_dn_get_linearized(in.dn)); - assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, - "foo", - NULL), - value); -} - -/* - * Test against a record with two attributes, matching the * in - * the list - */ -static void test_filter_attrs_two_attr_matched_star(void **state) -{ - struct ldbtest_ctx *ctx = *state; - int ret; - - struct ldb_message *filtered_msg = ldb_msg_new(ctx); - - const char *attrs[] = {"*", NULL}; - - uint8_t value1[] = "The value.......end"; - uint8_t value2[] = "The value..MUST.end"; - struct ldb_val value_1 = { - .data = value1, - .length = (sizeof(value1)) - }; - struct ldb_val value_2 = { - .data = value2, - .length = (sizeof(value2)) - }; - struct ldb_message_element elements[] = { - { - .name = "foo", - .num_values = 1, - .values = &value_1 - }, - { - .name = "bar", - .num_values = 1, - .values = &value_2 - } - }; - struct ldb_message in = { - .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), - .num_elements = 2, - .elements = elements, - }; - - assert_non_null(in.dn); - - /* Needed as * implies distinguishedName */ - filtered_msg->dn = in.dn; - - ret = ldb_filter_attrs(ctx->ldb, - &in, - attrs, - filtered_msg); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(filtered_msg); - assert_int_equal(filtered_msg->num_elements, 3); - - /* - * assert the ldb_filter_attrs does not modify filtered_msg.dn - * in this case - */ - assert_ptr_equal(filtered_msg->dn, in.dn); - assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, - "distinguishedName", - NULL), - ldb_dn_get_linearized(in.dn)); - assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, - "foo", - NULL), - value1); - assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, - "bar", - NULL), - value2); -} - -/* - * Test against a record with only one attribute, matching the * in - * the list, but without the DN being pre-filled. Fails due to need - * to contstruct the distinguishedName - */ -static void test_filter_attrs_one_attr_matched_star_no_dn(void **state) -{ - struct ldbtest_ctx *ctx = *state; - int ret; - - struct ldb_message *filtered_msg = ldb_msg_new(ctx); - - const char *attrs[] = {"*", NULL}; - - uint8_t value[] = "The value.......end"; - struct ldb_val value_1 = { - .data = value, - .length = (sizeof(value)) - }; - struct ldb_message_element element_1 = { - .name = "foo", - .num_values = 1, - .values = &value_1 - }; - struct ldb_message in = { - .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), - .num_elements = 1, - .elements = &element_1, - }; - - assert_non_null(in.dn); - - ret = ldb_filter_attrs(ctx->ldb, - &in, - attrs, - filtered_msg); - assert_int_equal(ret, -1); - assert_null(filtered_msg->elements); -} - -/* - * Test against a record with only one attribute, matching the * in - * the list plus requsesting distinguishedName - */ -static void test_filter_attrs_one_attr_matched_star_dn(void **state) -{ - struct ldbtest_ctx *ctx = *state; - int ret; - - struct ldb_message *filtered_msg = ldb_msg_new(ctx); - - const char *attrs[] = {"*", "distinguishedName", NULL}; - - uint8_t value[] = "The value.......end"; - struct ldb_val value_1 = { - .data = value, - .length = (sizeof(value)) - }; - struct ldb_message_element element_1 = { - .name = "foo", - .num_values = 1, - .values = &value_1 - }; - struct ldb_message in = { - .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), - .num_elements = 1, - .elements = &element_1, - }; - - assert_non_null(in.dn); - - /* Needed for distinguishedName */ - filtered_msg->dn = in.dn; - - ret = ldb_filter_attrs(ctx->ldb, - &in, - attrs, - filtered_msg); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(filtered_msg); - assert_int_equal(filtered_msg->num_elements, 2); - - /* show that ldb_filter_attrs does not modify in.dn */ - assert_ptr_equal(filtered_msg->dn, in.dn); - - assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, - "distinguishedName", - NULL), - ldb_dn_get_linearized(in.dn)); - assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, - "foo", - NULL), - value); -} - -/* - * Test against a record with only one attribute, but returning - * distinguishedName from the list (only) - */ -static void test_filter_attrs_one_attr_matched_dn(void **state) -{ - struct ldbtest_ctx *ctx = *state; - int ret; - - struct ldb_message *filtered_msg = ldb_msg_new(ctx); - - const char *attrs[] = {"distinguishedName", NULL}; - - uint8_t value[] = "The value.......end"; - struct ldb_val value_1 = { - .data = value, - .length = (sizeof(value)) - }; - struct ldb_message_element element_1 = { - .name = "foo", - .num_values = 1, - .values = &value_1 - }; - struct ldb_message in = { - .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), - .num_elements = 1, - .elements = &element_1, - }; - - assert_non_null(in.dn); - - /* Needed for distinguishedName */ - filtered_msg->dn = in.dn; - - ret = ldb_filter_attrs(ctx->ldb, - &in, - attrs, - filtered_msg); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(filtered_msg); - assert_int_equal(filtered_msg->num_elements, 1); - - /* show that ldb_filter_attrs does not modify in.dn */ - assert_ptr_equal(filtered_msg->dn, in.dn); - assert_string_equal(filtered_msg->elements[0].name, "distinguishedName"); - assert_int_equal(filtered_msg->elements[0].num_values, 1); - assert_string_equal(filtered_msg->elements[0].values[0].data, - ldb_dn_get_linearized(in.dn)); -} - -/* - * Test against a record with only one attribute, not matching the - * empty attribute list - */ -static void test_filter_attrs_one_attr_empty_list(void **state) -{ - struct ldbtest_ctx *ctx = *state; - int ret; - - struct ldb_message *filtered_msg = ldb_msg_new(ctx); - - const char *attrs[] = {NULL}; - - uint8_t value[] = "The value.......end"; - struct ldb_val value_1 = { - .data = value, - .length = (sizeof(value)) - }; - struct ldb_message_element element_1 = { - .name = "foo", - .num_values = 1, - .values = &value_1 - }; - struct ldb_message in = { - .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), - .num_elements = 1, - .elements = &element_1, - }; - - assert_non_null(in.dn); - - ret = ldb_filter_attrs(ctx->ldb, - &in, - attrs, - filtered_msg); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(filtered_msg); - assert_int_equal(filtered_msg->num_elements, 0); - assert_null(filtered_msg->dn); - assert_null(filtered_msg->elements); -} - -int main(int argc, const char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown( - test_filter_attrs_one_attr_matched, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_filter_attrs_one_attr_matched_of_many, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_filter_attrs_two_attr_matched_attrs, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_filter_attrs_two_attr_matched_one_attr, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_filter_attrs_two_dup_attr_matched_one_attr, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_filter_attrs_two_dup_attr_matched_dup, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_filter_attrs_two_dup_attr_matched_one_of_two, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_filter_attrs_two_dup_attr_matched_star, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_filter_attrs_one_attr_matched_star, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_filter_attrs_two_attr_matched_star, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_filter_attrs_one_attr_matched_star_no_dn, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_filter_attrs_one_attr_matched_star_dn, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_filter_attrs_one_attr_matched_dn, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_filter_attrs_one_attr_empty_list, - setup, - teardown), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/ldb-2.0.8/tests/ldb_key_value_sub_txn_mdb_test.valgrind b/ldb-2.0.8/tests/ldb_key_value_sub_txn_mdb_test.valgrind deleted file mode 100644 index 1747076..0000000 --- a/ldb-2.0.8/tests/ldb_key_value_sub_txn_mdb_test.valgrind +++ /dev/null @@ -1,97 +0,0 @@ -{ - Memory allocated by setup - Memcheck:Leak - match-leak-kinds: possible - fun:malloc - ... - fun:setup -} -{ - Memory allocated by setup - Memcheck:Leak - match-leak-kinds: possible - fun:realloc - ... - fun:setup -} -{ - Memory allocated by ldb_init - Memcheck:Leak - match-leak-kinds: possible - fun:malloc - ... - fun:ldb_init -} -{ - Memory allocated by ldb_init - Memcheck:Leak - match-leak-kinds: possible - fun:realloc - ... - fun:ldb_init -} -{ - Memory allocated by noconn_setup - Memcheck:Leak - match-leak-kinds: possible - fun:malloc - ... - fun:noconn_setup -} -{ - Memory allocated by parse, which allocates on the NULL context - Memcheck:Leak - match-leak-kinds: all - fun:malloc - ... - fun:parse -} -{ - Memory allocated by tdb_parse_data - Memcheck:Leak - match-leak-kinds: all - fun:malloc - ... - fun:tdb_parse_data -} -{ - Memory allocated by ldb_connect - Memcheck:Leak - match-leak-kinds: possible - fun:malloc - ... - fun:ldb_connect -} -{ - Memory allocated by ldb_connect - Memcheck:Leak - match-leak-kinds: possible - fun:calloc - ... - fun:ldb_connect -} -{ - Memory allocated by ldb_kv_cache_load - Memcheck:Leak - match-leak-kinds: possible - fun:malloc - ... - fun:ldb_kv_cache_load -} -{ - Memory allocated by ldb_kv_index_load - Memcheck:Leak - match-leak-kinds: possible - fun:malloc - ... - fun:ldb_kv_index_load -} -{ - Memory allocated by ldb_asprintf_errstring - Memcheck:Leak - match-leak-kinds: possible - fun:malloc - ... - fun:ldb_asprintf_errstring -} - diff --git a/ldb-2.0.8/tests/ldb_key_value_sub_txn_test.c b/ldb-2.0.8/tests/ldb_key_value_sub_txn_test.c deleted file mode 100644 index e71f81b..0000000 --- a/ldb-2.0.8/tests/ldb_key_value_sub_txn_test.c +++ /dev/null @@ -1,843 +0,0 @@ -/* - * Tests exercising the ldb key value operations. - * - * Copyright (C) Andrew Bartlett 2018 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/* - * from cmocka.c: - * These headers or their equivalents should be included prior to - * including - * this header file. - * - * #include - * #include - * #include - * - * This allows test applications to use custom definitions of C standard - * library functions and types. - * - */ - -/* - */ -#include -#include -#include -#include - -#include -#define NO_FAILURE INT_MAX -#define FAILURE_LDB_ERR LDB_ERR_OTHER - -/* - * To test failure in ldb_kv_add, ldb_kv_delete, ldb_kv_modify and ldb_kv_rename - * we use the following global variables and macros to trigger a failure in - * the ldb_kv__internal functions. This allows testing of the sub - * transaction commits and roll backs in those operations. - * - * NOTE: Not all back ends support nested/sub transactions - */ -int cmocka_unit_test_fail_add_internal_after = NO_FAILURE; -#define CMOCKA_UNIT_TEST_ADD_INTERNAL_FAIL \ - {\ - cmocka_unit_test_fail_add_internal_after--;\ - if (cmocka_unit_test_fail_add_internal_after <= 0) {\ - assert_int_equal(LDB_SUCCESS, ret);\ - ret = FAILURE_LDB_ERR;\ - }\ - }\ - -int cmocka_unit_test_fail_delete_internal_after = NO_FAILURE; -#define CMOCKA_UNIT_TEST_DELETE_INTERNAL_FAIL \ - {\ - cmocka_unit_test_fail_delete_internal_after--;\ - if (cmocka_unit_test_fail_delete_internal_after <= 0) {\ - assert_int_equal(LDB_SUCCESS, ret);\ - ret = FAILURE_LDB_ERR;\ - }\ - }\ - -int cmocka_unit_test_fail_rename_internal_after = NO_FAILURE; -#define CMOCKA_UNIT_TEST_RENAME_INTERNAL_FAIL \ - {\ - cmocka_unit_test_fail_rename_internal_after--;\ - if (cmocka_unit_test_fail_rename_internal_after <= 0) {\ - assert_int_equal(LDB_SUCCESS, ret);\ - ret = FAILURE_LDB_ERR;\ - }\ - }\ - -int cmocka_unit_test_fail_modify_internal_after = NO_FAILURE; -#define CMOCKA_UNIT_TEST_MODIFY_INTERNAL_FAIL \ - {\ - cmocka_unit_test_fail_modify_internal_after--;\ - if (cmocka_unit_test_fail_modify_internal_after <= 0) {\ - assert_int_equal(LDB_SUCCESS, ret);\ - ret = FAILURE_LDB_ERR;\ - }\ - }\ - -#include "ldb_key_value/ldb_kv.c" - - -#define DEFAULT_BE "tdb" - -#ifndef TEST_BE -#define TEST_BE DEFAULT_BE -#endif /* TEST_BE */ - -#define NUM_RECS 1024 - - -struct test_ctx { - struct tevent_context *ev; - struct ldb_context *ldb; - - const char *dbfile; - const char *lockfile; /* lockfile is separate */ - - const char *dbpath; -}; - -/* - * Remove the database files - */ -static void unlink_old_db(struct test_ctx *test_ctx) -{ - int ret; - - errno = 0; - ret = unlink(test_ctx->lockfile); - if (ret == -1 && errno != ENOENT) { - fail(); - } - - errno = 0; - ret = unlink(test_ctx->dbfile); - if (ret == -1 && errno != ENOENT) { - fail(); - } -} - -/* - * Test setup - */ -static int noconn_setup(void **state) -{ - struct test_ctx *test_ctx; - cmocka_unit_test_fail_add_internal_after = NO_FAILURE; - cmocka_unit_test_fail_delete_internal_after = NO_FAILURE; - cmocka_unit_test_fail_rename_internal_after = NO_FAILURE; - cmocka_unit_test_fail_modify_internal_after = NO_FAILURE; - - test_ctx = talloc_zero(NULL, struct test_ctx); - assert_non_null(test_ctx); - - test_ctx->ev = tevent_context_init(test_ctx); - assert_non_null(test_ctx->ev); - - test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev); - assert_non_null(test_ctx->ldb); - - test_ctx->dbfile = talloc_strdup(test_ctx, "kvopstest.ldb"); - assert_non_null(test_ctx->dbfile); - - test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock", - test_ctx->dbfile); - assert_non_null(test_ctx->lockfile); - - test_ctx->dbpath = talloc_asprintf(test_ctx, - TEST_BE"://%s", test_ctx->dbfile); - assert_non_null(test_ctx->dbpath); - - unlink_old_db(test_ctx); - *state = test_ctx; - return 0; -} - -/* - * Test teardown - */ -static int noconn_teardown(void **state) -{ - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - - unlink_old_db(test_ctx); - talloc_free(test_ctx); - return 0; -} - -/* - * Test setup - */ -static int setup(void **state) -{ - struct test_ctx *test_ctx; - int ret; - struct ldb_ldif *ldif; - const char *index_ldif = \ - "dn: @INDEXLIST\n" - "@IDXGUID: objectUUID\n" - "@IDX_DN_GUID: GUID\n" - "\n"; - - noconn_setup((void **) &test_ctx); - - ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL); - assert_int_equal(ret, 0); - - while ((ldif = ldb_ldif_read_string(test_ctx->ldb, &index_ldif))) { - ret = ldb_add(test_ctx->ldb, ldif->msg); - assert_int_equal(ret, LDB_SUCCESS); - } - *state = test_ctx; - return 0; -} - -/* - * Test teardown - */ -static int teardown(void **state) -{ - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - noconn_teardown((void **) &test_ctx); - return 0; -} - -/* - * Build an ldb_kv_context that can be passed to the ldb_kv operation under test - */ -static struct ldb_kv_context* build_ldb_kv_context( - TALLOC_CTX *ctx, - struct ldb_module *module, - struct ldb_request *req) -{ - struct ldb_kv_context *ldb_kv_ctx = NULL; - - ldb_kv_ctx = talloc_zero(ctx, struct ldb_kv_context); - assert_non_null(ldb_kv_ctx); - - ldb_kv_ctx->module = module; - ldb_kv_ctx->req = req; - - return ldb_kv_ctx; -} - -/* - * Build an add request - */ -static struct ldb_request *build_add_request( - TALLOC_CTX *ctx, - struct ldb_context *ldb, - const char* dc, - const char* uuid, - const char* cn) -{ - int ret; - struct ldb_message *msg; - struct ldb_request *req; - - msg = ldb_msg_new(ctx); - assert_non_null(msg); - - msg->dn = ldb_dn_new_fmt(msg, ldb, "dc=%s", dc); - assert_non_null(msg->dn); - - ret = ldb_msg_add_string(msg, "cn", cn); - assert_int_equal(ret, 0); - - ret = ldb_msg_add_string(msg, "objectUUID", uuid); - assert_int_equal(ret, 0); - - ret = ldb_msg_sanity_check(ldb, msg); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_build_add_req( - &req, ldb, ldb, msg, NULL, NULL, ldb_op_default_callback, NULL); - assert_int_equal(ret, LDB_SUCCESS); - return req; -} - -/* - * Build a delete request - */ -static struct ldb_request *build_delete_request( - TALLOC_CTX *ctx, - struct ldb_context *ldb, - const char* dc) -{ - int ret = LDB_SUCCESS; - struct ldb_dn *dn = NULL; - struct ldb_request *req = NULL; - - dn = ldb_dn_new_fmt(ctx, ldb, "dc=%s", dc); - assert_non_null(dn); - - ret = ldb_build_del_req( - &req, ldb, ctx, dn, NULL, NULL, ldb_op_default_callback, NULL); - assert_int_equal(ret, LDB_SUCCESS); - return req; -} - -/* - * Build a rename request - */ -static struct ldb_request *build_rename_request( - TALLOC_CTX *ctx, - struct ldb_context *ldb, - const char* old_dc, - const char* new_dc) -{ - int ret = LDB_SUCCESS; - struct ldb_dn *old_dn = NULL; - struct ldb_dn *new_dn = NULL; - struct ldb_request *req = NULL; - - old_dn = ldb_dn_new_fmt(ctx, ldb, "dc=%s", old_dc); - assert_non_null(old_dn); - - new_dn = ldb_dn_new_fmt(ctx, ldb, "dc=%s", new_dc); - assert_non_null(new_dn); - - ret = ldb_build_rename_req( - &req, - ldb, - ctx, - old_dn, - new_dn, - NULL, - NULL, - ldb_op_default_callback, - NULL); - assert_int_equal(ret, LDB_SUCCESS); - return req; -} - -/* - * Build a ldb modify request - */ -static struct ldb_request *build_modify_request( - TALLOC_CTX *ctx, - struct ldb_context *ldb, - const char* dc, - const char* cn) -{ - int ret; - struct ldb_message *msg; - struct ldb_request *req; - - msg = ldb_msg_new(ctx); - assert_non_null(msg); - - msg->dn = ldb_dn_new_fmt(msg, ldb, "dc=%s", dc); - assert_non_null(msg->dn); - - ret = ldb_msg_add_empty(msg, "cn", LDB_FLAG_MOD_REPLACE, NULL); - assert_int_equal(ret, LDB_SUCCESS); - ret = ldb_msg_add_string(msg, "cn", cn); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_msg_sanity_check(ldb, msg); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_build_mod_req( - &req, ldb, ldb, msg, NULL, NULL, ldb_op_default_callback, NULL); - assert_int_equal(ret, LDB_SUCCESS); - return req; -} - -/* - * Delete a record from the database - */ -static void delete_record( - TALLOC_CTX *ctx, - struct ldb_context *ldb, - const char* dc) -{ - struct ldb_kv_context *ldb_kv_ctx = NULL; - struct ldb_dn *basedn = NULL; - struct ldb_result *result = NULL; - struct ldb_request *req = NULL; - int ret = LDB_SUCCESS; - - req = build_delete_request(ctx, ldb, dc); - ldb_kv_ctx = build_ldb_kv_context(ctx, ldb->modules, req); - - ret = ldb_transaction_start(ldb); - assert_int_equal(ret, LDB_SUCCESS); - - cmocka_unit_test_fail_delete_internal_after = NO_FAILURE; - cmocka_unit_test_fail_modify_internal_after = NO_FAILURE; - ret = ldb_kv_delete(ldb_kv_ctx); - assert_int_equal(ret, LDB_SUCCESS); - TALLOC_FREE(ldb_kv_ctx); - TALLOC_FREE(req); - - ret = ldb_transaction_commit(ldb); - assert_int_equal(ret, LDB_SUCCESS); - - /* - * Ensure that the record was actually deleted. - */ - basedn = ldb_dn_new_fmt(ctx, ldb, "dc=%s", dc); - assert_non_null(basedn); - - /* - * DN search, indexed - */ - ret = ldb_search(ldb, ctx, &result, basedn, LDB_SCOPE_BASE, NULL, NULL); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(result); - assert_int_equal(result->count, 0); - TALLOC_FREE(basedn); - TALLOC_FREE(result); -} - -/* - * Add a record to the database - */ -static void add_record( - TALLOC_CTX *ctx, - struct ldb_context *ldb, - const char* dc, - const char* uuid, - const char* cn) -{ - - struct ldb_request *req = NULL; - int ret = LDB_SUCCESS; - struct ldb_kv_context *ldb_kv_ctx = NULL; - struct ldb_dn *basedn = NULL; - struct ldb_result *result = NULL; - - req = build_add_request(ctx, ldb, dc, uuid, cn); - - ldb_req_set_location(req, "add_record"); - - assert_int_equal(ret, LDB_SUCCESS); - - - ldb_kv_ctx = build_ldb_kv_context(ctx, ldb->modules, req); - cmocka_unit_test_fail_add_internal_after = NO_FAILURE; - cmocka_unit_test_fail_modify_internal_after = NO_FAILURE; - - ret = ldb_transaction_start(ldb); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_kv_add(ldb_kv_ctx); - assert_int_equal(ret, LDB_SUCCESS); - TALLOC_FREE(ldb_kv_ctx); - TALLOC_FREE(req); - - ret = ldb_transaction_commit(ldb); - assert_int_equal(ret, LDB_SUCCESS); - - /* - * Ensure that the record was actually written. - */ - basedn = ldb_dn_new_fmt(ctx, ldb, "dc=%s", dc); - assert_non_null(basedn); - - /* - * DN search, indexed - */ - ret = ldb_search(ldb, ctx, &result, basedn, LDB_SCOPE_BASE, NULL, NULL); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(result); - assert_int_equal(result->count, 1); - TALLOC_FREE(result); - - - /* - * CN search unindexed - */ - ret = ldb_search( - ldb, - ctx, - &result, - basedn, - LDB_SCOPE_SUBTREE, - NULL, - "(cn=%s)", - cn); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(result); - assert_int_equal(result->count, 1); - TALLOC_FREE(result); - TALLOC_FREE(basedn); -} - -/* - * Test that a failed add operation does not change the database. - */ -static void test_add_failure(void **state) -{ - int ret = LDB_SUCCESS; - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - struct ldb_request *req = NULL; - struct ldb_dn *basedn = NULL; - struct ldb_result *result = NULL; - struct ldb_kv_context *ldb_kv_ctx = NULL; - - TALLOC_CTX *tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - req = build_add_request( - tmp_ctx, - test_ctx->ldb, - "test_add_failure", - "0123456789abcdef", - "test_add_failure_value"); - - ldb_req_set_location(req, "test_add_failure"); - - ldb_kv_ctx = build_ldb_kv_context(tmp_ctx, test_ctx->ldb->modules, req); - cmocka_unit_test_fail_add_internal_after = 1; - - ret = ldb_transaction_start(test_ctx->ldb); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_kv_add(ldb_kv_ctx); - - assert_int_equal(ret, FAILURE_LDB_ERR); - TALLOC_FREE(ldb_kv_ctx); - TALLOC_FREE(req); - - - /* - * a search for "cn=test_add_failure_value" should fail - * as the transaction containing the operation should have been - * rolled back leaving the database consistent - * - * This should be an un-indexed search so the index caches won't be - * used. - */ - basedn = ldb_dn_new_fmt( - tmp_ctx, - test_ctx->ldb, - "dc=%s", - "test_add_failure"); - assert_non_null(basedn); - - ret = ldb_search( - test_ctx->ldb, tmp_ctx, - &result, - basedn, - LDB_SCOPE_SUBTREE, - NULL, - "(cn=%s)", - "test_add_failure_value"); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(result); - assert_int_equal(result->count, 0); - TALLOC_FREE(basedn); - TALLOC_FREE(result); - - ldb_transaction_cancel(test_ctx->ldb); - TALLOC_FREE(tmp_ctx); -} - - -/* - * Test that a failed delete operation does not modify the database. - */ -static void test_delete_failure(void **state) -{ - int ret = LDB_SUCCESS; - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - struct ldb_request *req = NULL; - struct ldb_dn *basedn = NULL; - struct ldb_result *result = NULL; - struct ldb_kv_context *ldb_kv_ctx = NULL; - - TALLOC_CTX *tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - add_record( - tmp_ctx, - test_ctx->ldb, - "test_delete_failure", - "0123456789abcded", - "test_delete_failure_value"); - - req = build_delete_request( - tmp_ctx, - test_ctx->ldb, - "test_delete_failure"); - - ldb_kv_ctx = build_ldb_kv_context(tmp_ctx, test_ctx->ldb->modules, req); - cmocka_unit_test_fail_delete_internal_after = 1; - - ret = ldb_transaction_start(test_ctx->ldb); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_kv_delete(ldb_kv_ctx); - assert_int_equal(ret, FAILURE_LDB_ERR); - TALLOC_FREE(ldb_kv_ctx); - TALLOC_FREE(req); - - /* - * a search for "cn=test_add_failure_value" should succeed - * as the transaction containing the operation should have been - * rolled back leaving the database consistent - * - * This should be an un-indexed search so the index caches won't be - * used. - */ - basedn = ldb_dn_new_fmt( - tmp_ctx, - test_ctx->ldb, - "dc=%s", - "test_delete_failure"); - assert_non_null(basedn); - - ret = ldb_search( - test_ctx->ldb, tmp_ctx, - &result, - basedn, - LDB_SCOPE_SUBTREE, - NULL, - "(cn=%s)", - "test_delete_failure_value"); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(result); - assert_int_equal(result->count, 1); - TALLOC_FREE(basedn); - TALLOC_FREE(result); - - - ldb_transaction_cancel(test_ctx->ldb); - delete_record( - tmp_ctx, - test_ctx->ldb, - "test_delete_failure"); - TALLOC_FREE(tmp_ctx); -} - -/* - * Test that a failed rename operation dies not change the database - */ -static void test_rename_failure(void **state) -{ - int ret = LDB_SUCCESS; - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - struct ldb_request *req = NULL; - struct ldb_dn *basedn = NULL; - struct ldb_result *result = NULL; - struct ldb_kv_context *ldb_kv_ctx = NULL; - - TALLOC_CTX *tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - add_record( - tmp_ctx, - test_ctx->ldb, - "test_rename_failure", - "0123456789abcdec", - "test_rename_failure_value"); - - req = build_rename_request( - tmp_ctx, - test_ctx->ldb, - "test_rename_failure", - "test_rename_failure_renamed"); - - ldb_kv_ctx = build_ldb_kv_context(tmp_ctx, test_ctx->ldb->modules, req); - cmocka_unit_test_fail_rename_internal_after = 1; - - ret = ldb_transaction_start(test_ctx->ldb); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_kv_rename(ldb_kv_ctx); - assert_int_equal(ret, FAILURE_LDB_ERR); - TALLOC_FREE(ldb_kv_ctx); - TALLOC_FREE(req); - - /* - * The original record should be present - */ - basedn = ldb_dn_new_fmt( - tmp_ctx, - test_ctx->ldb, - "dc=%s", - "test_rename_failure"); - assert_non_null(basedn); - - ret = ldb_search( - test_ctx->ldb, tmp_ctx, - &result, - basedn, - LDB_SCOPE_SUBTREE, - NULL, - "(cn=%s)", - "test_rename_failure_value"); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(result); - assert_int_equal(result->count, 1); - TALLOC_FREE(basedn); - TALLOC_FREE(result); - - /* - * And the renamed record should not be present - */ - basedn = ldb_dn_new_fmt( - tmp_ctx, - test_ctx->ldb, - "dc=%s", - "test_rename_failure_renamed"); - assert_non_null(basedn); - - ret = ldb_search( - test_ctx->ldb, tmp_ctx, - &result, - basedn, - LDB_SCOPE_SUBTREE, - NULL, - "(cn=%s)", - "test_rename_failure_value"); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(result); - assert_int_equal(result->count, 0); - TALLOC_FREE(basedn); - TALLOC_FREE(result); - - ldb_transaction_cancel(test_ctx->ldb); - delete_record( - tmp_ctx, - test_ctx->ldb, - "test_rename_failure"); - TALLOC_FREE(tmp_ctx); -} - -/* - * Test that a failed modification operation does not change the database - */ -static void test_modify_failure(void **state) -{ - int ret = LDB_SUCCESS; - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - struct ldb_request *req = NULL; - struct ldb_dn *basedn = NULL; - struct ldb_result *result = NULL; - struct ldb_kv_context *ldb_kv_ctx = NULL; - - TALLOC_CTX *tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - add_record( - tmp_ctx, - test_ctx->ldb, - "test_modify_failure", - "0123456789abcdeb", - "test_modify_failure_value"); - - req = build_modify_request( - tmp_ctx, - test_ctx->ldb, - "test_modify_failure", - "test_modify_failure_value_modified"); - - ldb_kv_ctx = build_ldb_kv_context(tmp_ctx, test_ctx->ldb->modules, req); - cmocka_unit_test_fail_modify_internal_after = 2; - - ret = ldb_transaction_start(test_ctx->ldb); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_kv_modify(ldb_kv_ctx); - assert_int_equal(ret, FAILURE_LDB_ERR); - TALLOC_FREE(ldb_kv_ctx); - TALLOC_FREE(req); - - - /* - * The original value should be present - */ - basedn = ldb_dn_new_fmt( - tmp_ctx, - test_ctx->ldb, - "dc=%s", - "test_modify_failure"); - assert_non_null(basedn); - - ret = ldb_search( - test_ctx->ldb, tmp_ctx, - &result, - basedn, - LDB_SCOPE_SUBTREE, - NULL, - "(cn=%s)", - "test_modify_failure_value"); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(result); - assert_int_equal(result->count, 1); - TALLOC_FREE(result); - - /* - * And the modified record should not be present - */ - ret = ldb_search( - test_ctx->ldb, tmp_ctx, - &result, - basedn, - LDB_SCOPE_SUBTREE, - NULL, - "(cn=%s)", - "test_modify_failure_value_modified"); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(result); - assert_int_equal(result->count, 0); - TALLOC_FREE(basedn); - TALLOC_FREE(result); - - ldb_transaction_cancel(test_ctx->ldb); - delete_record( - tmp_ctx, - test_ctx->ldb, - "test_modify_failure"); - TALLOC_FREE(tmp_ctx); -} - -int main(int argc, const char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown( - test_add_failure, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_delete_failure, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_rename_failure, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_modify_failure, - setup, - teardown), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/ldb-2.0.8/tests/ldb_key_value_test.c b/ldb-2.0.8/tests/ldb_key_value_test.c deleted file mode 100644 index 3f31bb9..0000000 --- a/ldb-2.0.8/tests/ldb_key_value_test.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Tests exercising the ldb key value operations. - * - * Copyright (C) Andrew Bartlett 2019 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/* - * from cmocka.c: - * These headers or their equivalents should be included prior to - * including - * this header file. - * - * #include - * #include - * #include - * - * This allows test applications to use custom definitions of C standard - * library functions and types. - * - */ - -/* - * - * Tests for the ldb key value layer - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include "ldb_key_value/ldb_kv.c" -#include "ldb_key_value/ldb_kv_index.c" -#include "ldb_key_value/ldb_kv_search.c" - -#define DEFAULT_BE "tdb" - -#ifndef TEST_BE -#define TEST_BE DEFAULT_BE -#endif /* TEST_BE */ - -#define NUM_RECS 1024 -int ldb_kv_cache_reload(struct ldb_module *module) { - return LDB_SUCCESS; -} -int ldb_kv_cache_load(struct ldb_module *module) { - return LDB_SUCCESS; -} -int ldb_kv_check_at_attributes_values(const struct ldb_val *value) { - return LDB_SUCCESS; -} -int ldb_kv_increase_sequence_number(struct ldb_module *module) { - return LDB_SUCCESS; -} - -struct test_ctx { -}; - -static int setup(void **state) -{ - struct test_ctx *test_ctx; - - test_ctx = talloc_zero(NULL, struct test_ctx); - *state = test_ctx; - return 0; -} - -static int teardown(void **state) -{ - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - - talloc_free(test_ctx); - return 0; -} - -/* - * Test that the index cache is opened by ldb_kv_index_transaction_start - * and correctly initialised with the passed index cache size. - */ -static void test_index_cache_init(void **state) -{ - struct test_ctx *test_ctx = talloc_get_type_abort( - *state, - struct test_ctx); - struct ldb_module *module = NULL; - struct ldb_kv_private *ldb_kv = NULL; - int ret = LDB_SUCCESS; - - module = talloc_zero(test_ctx, struct ldb_module); - ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private); - ldb_module_set_private(module, ldb_kv); - - ret = ldb_kv_index_transaction_start(module, 191); - assert_int_equal(LDB_SUCCESS, ret); - - assert_non_null(ldb_kv->idxptr); - assert_non_null(ldb_kv->idxptr->itdb); - assert_int_equal(191, tdb_hash_size(ldb_kv->idxptr->itdb)); - - TALLOC_FREE(ldb_kv); - TALLOC_FREE(module); -} - -static int mock_begin_write(struct ldb_kv_private* ldb_kv) { - return LDB_SUCCESS; -} -static int mock_abort_write(struct ldb_kv_private* ldb_kv) { - return LDB_SUCCESS; -} - -/* - * Test that the index cache is set to the default cache size at the start of - * a transaction. - */ -static void test_default_index_cache_size(void **state) -{ - struct test_ctx *test_ctx = talloc_get_type_abort( - *state, - struct test_ctx); - struct ldb_module *module = NULL; - struct ldb_kv_private *ldb_kv = NULL; - int ret = LDB_SUCCESS; - const struct kv_db_ops ops = { - .begin_write = mock_begin_write, - .abort_write = mock_abort_write - }; - - module = talloc_zero(test_ctx, struct ldb_module); - ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private); - ldb_kv->pid = getpid(); - ldb_kv->kv_ops = &ops; - ldb_kv->index_transaction_cache_size = DEFAULT_INDEX_CACHE_SIZE; - ldb_module_set_private(module, ldb_kv); - - ret = ldb_kv_start_trans(module); - assert_int_equal(LDB_SUCCESS, ret); - - assert_int_equal( - DEFAULT_INDEX_CACHE_SIZE, - tdb_hash_size(ldb_kv->idxptr->itdb)); - - ret = ldb_kv_del_trans(module); - assert_int_equal(LDB_SUCCESS, ret); - - TALLOC_FREE(ldb_kv); - TALLOC_FREE(module); -} - -static int db_size = 0; -static size_t mock_get_size(struct ldb_kv_private *ldb_kv) { - return db_size; -} - -static int mock_iterate( - struct ldb_kv_private *ldb_kv, - ldb_kv_traverse_fn fn, - void *ctx) { - return 1; -} - -/* - * Test that the index cache is correctly sized by the re_index call - */ -static void test_reindex_cache_size(void **state) -{ - struct test_ctx *test_ctx = talloc_get_type_abort( - *state, - struct test_ctx); - struct ldb_module *module = NULL; - struct ldb_kv_private *ldb_kv = NULL; - int ret = LDB_SUCCESS; - const struct kv_db_ops ops = { - .iterate = mock_iterate, - .get_size = mock_get_size, - }; - - module = talloc_zero(test_ctx, struct ldb_module); - ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private); - ldb_kv->kv_ops = &ops; - ldb_module_set_private(module, ldb_kv); - - /* - * Use a value less than the DEFAULT_INDEX_CACHE_SIZE - * Should get the DEFAULT_INDEX_CACHE_SIZE - */ - db_size = DEFAULT_INDEX_CACHE_SIZE - 1; - ret = ldb_kv_reindex(module); - assert_int_equal(LDB_SUCCESS, ret); - - assert_int_equal( - DEFAULT_INDEX_CACHE_SIZE, - tdb_hash_size(ldb_kv->idxptr->itdb)); - - /* - * Use a value greater than the DEFAULT_INDEX_CACHE_SIZE - * Should get the value specified. - */ - db_size = DEFAULT_INDEX_CACHE_SIZE + 1; - ret = ldb_kv_reindex(module); - assert_int_equal(LDB_SUCCESS, ret); - - assert_int_equal(db_size, tdb_hash_size(ldb_kv->idxptr->itdb)); - - TALLOC_FREE(ldb_kv); - TALLOC_FREE(module); -} - -/* - * Test that ldb_kv_init_store sets the default index transaction cache size - * if the option is not supplied. - */ -static void test_init_store_default_index_cache_size(void **state) -{ - struct test_ctx *test_ctx = talloc_get_type_abort( - *state, - struct test_ctx); - struct ldb_module *module = NULL; - struct ldb_kv_private *ldb_kv = NULL; - struct ldb_context *ldb = NULL; - int ret = LDB_SUCCESS; - - module = talloc_zero(test_ctx, struct ldb_module); - ldb = talloc_zero(test_ctx, struct ldb_context); - ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private); - - ret = ldb_kv_init_store(ldb_kv, "test", ldb, NULL, &module); - assert_int_equal(LDB_SUCCESS, ret); - - assert_int_equal( - DEFAULT_INDEX_CACHE_SIZE, - ldb_kv->index_transaction_cache_size); - - TALLOC_FREE(ldb_kv); - TALLOC_FREE(module); - TALLOC_FREE(ldb); -} - -/* - * Test that ldb_kv_init_store sets the index transaction cache size - * to the value specified in the option. - */ -static void test_init_store_set_index_cache_size(void **state) -{ - struct test_ctx *test_ctx = talloc_get_type_abort( - *state, - struct test_ctx); - struct ldb_module *module = NULL; - struct ldb_kv_private *ldb_kv = NULL; - struct ldb_context *ldb = NULL; - const char *options[] = {"transaction_index_cache_size:1900", NULL}; - int ret = LDB_SUCCESS; - - module = talloc_zero(test_ctx, struct ldb_module); - ldb = talloc_zero(test_ctx, struct ldb_context); - ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private); - - ret = ldb_kv_init_store(ldb_kv, "test", ldb, options, &module); - assert_int_equal(LDB_SUCCESS, ret); - - assert_int_equal( 1900, ldb_kv->index_transaction_cache_size); - - TALLOC_FREE(ldb_kv); - TALLOC_FREE(module); - TALLOC_FREE(ldb); -} - -/* - * Test that ldb_kv_init_store sets the default index transaction cache size - * if the value specified in the option is not a number. - */ -static void test_init_store_set_index_cache_size_non_numeric(void **state) -{ - struct test_ctx *test_ctx = talloc_get_type_abort( - *state, - struct test_ctx); - struct ldb_module *module = NULL; - struct ldb_kv_private *ldb_kv = NULL; - struct ldb_context *ldb = NULL; - const char *options[] = {"transaction_index_cache_size:fred", NULL}; - int ret = LDB_SUCCESS; - - module = talloc_zero(test_ctx, struct ldb_module); - ldb = talloc_zero(test_ctx, struct ldb_context); - ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private); - - ret = ldb_kv_init_store(ldb_kv, "test", ldb, options, &module); - assert_int_equal(LDB_SUCCESS, ret); - - assert_int_equal( - DEFAULT_INDEX_CACHE_SIZE, - ldb_kv->index_transaction_cache_size); - - TALLOC_FREE(ldb_kv); - TALLOC_FREE(module); - TALLOC_FREE(ldb); -} - -/* - * Test that ldb_kv_init_store sets the default index transaction cache size - * if the value specified is too large - */ -static void test_init_store_set_index_cache_size_range(void **state) -{ - struct test_ctx *test_ctx = talloc_get_type_abort( - *state, - struct test_ctx); - struct ldb_module *module = NULL; - struct ldb_kv_private *ldb_kv = NULL; - struct ldb_context *ldb = NULL; - const char *options[] = { - "transaction_index_cache_size:0xfffffffffffffffffffffffffffff", - NULL}; - int ret = LDB_SUCCESS; - - module = talloc_zero(test_ctx, struct ldb_module); - ldb = talloc_zero(test_ctx, struct ldb_context); - ldb_kv = talloc_zero(test_ctx, struct ldb_kv_private); - - ret = ldb_kv_init_store(ldb_kv, "test", ldb, options, &module); - assert_int_equal(LDB_SUCCESS, ret); - - assert_int_equal( - DEFAULT_INDEX_CACHE_SIZE, - ldb_kv->index_transaction_cache_size); - - TALLOC_FREE(ldb_kv); - TALLOC_FREE(module); - TALLOC_FREE(ldb); -} - -int main(int argc, const char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown( - test_index_cache_init, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_default_index_cache_size, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_reindex_cache_size, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_init_store_default_index_cache_size, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_init_store_set_index_cache_size, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_init_store_set_index_cache_size_non_numeric, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_init_store_set_index_cache_size_range, - setup, - teardown), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/ldb-2.0.8/tests/ldb_kv_ops_test.c b/ldb-2.0.8/tests/ldb_kv_ops_test.c deleted file mode 100644 index 98b5a43..0000000 --- a/ldb-2.0.8/tests/ldb_kv_ops_test.c +++ /dev/null @@ -1,1804 +0,0 @@ -/* - * Tests exercising the ldb key value operations. - * - * Copyright (C) Andrew Bartlett 2018 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/* - * from cmocka.c: - * These headers or their equivalents should be included prior to - * including - * this header file. - * - * #include - * #include - * #include - * - * This allows test applications to use custom definitions of C standard - * library functions and types. - * - */ - -/* - * A KV module is expected to have the following behaviour - * - * - A transaction must be open to perform any read, write or delete operation - * - Writes and Deletes should not be visible until a transaction is commited - * - Nested transactions are not permitted - * - transactions can be rolled back and commited. - * - supports iteration over all records in the database - * - supports the update_in_iterate operation allowing entries to be - * re-keyed. - * - has a get_size implementation that returns an estimate of the number of - * records in the database. Note that this can be an estimate rather than - * an accurate size. - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "ldb_tdb/ldb_tdb.h" -#include "ldb_key_value/ldb_kv.h" - - -#define DEFAULT_BE "tdb" - -#ifndef TEST_BE -#define TEST_BE DEFAULT_BE -#endif /* TEST_BE */ - -#define NUM_RECS 1024 - - -struct test_ctx { - struct tevent_context *ev; - struct ldb_context *ldb; - - const char *dbfile; - const char *lockfile; /* lockfile is separate */ - - const char *dbpath; -}; - -static void unlink_old_db(struct test_ctx *test_ctx) -{ - int ret; - - errno = 0; - ret = unlink(test_ctx->lockfile); - if (ret == -1 && errno != ENOENT) { - fail(); - } - - errno = 0; - ret = unlink(test_ctx->dbfile); - if (ret == -1 && errno != ENOENT) { - fail(); - } -} - -static int noconn_setup(void **state) -{ - struct test_ctx *test_ctx; - - test_ctx = talloc_zero(NULL, struct test_ctx); - assert_non_null(test_ctx); - - test_ctx->ev = tevent_context_init(test_ctx); - assert_non_null(test_ctx->ev); - - test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev); - assert_non_null(test_ctx->ldb); - - test_ctx->dbfile = talloc_strdup(test_ctx, "kvopstest.ldb"); - assert_non_null(test_ctx->dbfile); - - test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock", - test_ctx->dbfile); - assert_non_null(test_ctx->lockfile); - - test_ctx->dbpath = talloc_asprintf(test_ctx, - TEST_BE"://%s", test_ctx->dbfile); - assert_non_null(test_ctx->dbpath); - - unlink_old_db(test_ctx); - *state = test_ctx; - return 0; -} - -static int noconn_teardown(void **state) -{ - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - - unlink_old_db(test_ctx); - talloc_free(test_ctx); - return 0; -} - -static int setup(void **state) -{ - struct test_ctx *test_ctx; - int ret; - struct ldb_ldif *ldif; - const char *index_ldif = \ - "dn: @INDEXLIST\n" - "@IDXGUID: objectUUID\n" - "@IDX_DN_GUID: GUID\n" - "\n"; - - noconn_setup((void **) &test_ctx); - - ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL); - assert_int_equal(ret, 0); - - while ((ldif = ldb_ldif_read_string(test_ctx->ldb, &index_ldif))) { - ret = ldb_add(test_ctx->ldb, ldif->msg); - assert_int_equal(ret, LDB_SUCCESS); - } - *state = test_ctx; - return 0; -} - -static int teardown(void **state) -{ - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - noconn_teardown((void **) &test_ctx); - return 0; -} - -static struct ldb_kv_private *get_ldb_kv(struct ldb_context *ldb) -{ - void *data = NULL; - struct ldb_kv_private *ldb_kv = NULL; - - data = ldb_module_get_private(ldb->modules); - assert_non_null(data); - - ldb_kv = talloc_get_type(data, struct ldb_kv_private); - assert_non_null(ldb_kv); - - return ldb_kv; -} - -static int parse(struct ldb_val key, - struct ldb_val data, - void *private_data) -{ - struct ldb_val* read = private_data; - - /* Yes, we leak this. That is OK */ - read->data = talloc_size(NULL, - data.length); - assert_non_null(read->data); - - memcpy(read->data, data.data, data.length); - read->length = data.length; - return LDB_SUCCESS; -} - -/* - * Parse function that just returns the int we pass it. - */ -static int parse_return(struct ldb_val key, - struct ldb_val data, - void *private_data) -{ - int *rcode = private_data; - return *rcode; -} - -/* - * Test that data can be written to the kv store and be read back. - */ -static void test_add_get(void **state) -{ - int ret; - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); - uint8_t key_val[] = "TheKey"; - struct ldb_val key = { - .data = key_val, - .length = sizeof(key_val) - }; - - uint8_t value[] = "The record contents"; - struct ldb_val data = { - .data = value, - .length = sizeof(value) - }; - - struct ldb_val read; - int rcode; - - int flags = 0; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - /* - * Begin a transaction - */ - ret = ldb_kv->kv_ops->begin_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * Write the record - */ - ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); - assert_int_equal(ret, 0); - - /* - * Commit the transaction - */ - ret = ldb_kv->kv_ops->finish_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * And now read it back - */ - ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); - assert_int_equal(ret, 0); - - ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); - assert_int_equal(ret, 0); - - assert_int_equal(sizeof(value), read.length); - assert_memory_equal(value, read.data, sizeof(value)); - - /* - * Now check that the error code we return in the - * parse function is returned by fetch_and_parse. - */ - for (rcode=0; rcode<50; rcode++) { - ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, - parse_return, - &rcode); - assert_int_equal(ret, rcode); - } - - ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); - assert_int_equal(ret, 0); - talloc_free(tmp_ctx); -} - -/* - * Test that attempts to read data without a read transaction fail. - */ -static void test_read_outside_transaction(void **state) -{ - int ret; - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); - uint8_t key_val[] = "TheKey"; - struct ldb_val key = { - .data = key_val, - .length = sizeof(key_val) - }; - - uint8_t value[] = "The record contents"; - struct ldb_val data = { - .data = value, - .length = sizeof(value) - }; - - struct ldb_val read; - - int flags = 0; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - /* - * Begin a transaction - */ - ret = ldb_kv->kv_ops->begin_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * Write the record - */ - ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); - assert_int_equal(ret, 0); - - /* - * Commit the transaction - */ - ret = ldb_kv->kv_ops->finish_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * And now read it back - * Note there is no read transaction active - */ - ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); - assert_int_equal(ret, LDB_ERR_PROTOCOL_ERROR); - - talloc_free(tmp_ctx); -} - -/* - * Test that data can be deleted from the kv store - */ -static void test_delete(void **state) -{ - int ret; - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); - uint8_t key_val[] = "TheKey"; - struct ldb_val key = { - .data = key_val, - .length = sizeof(key_val) - }; - - uint8_t value[] = "The record contents"; - struct ldb_val data = { - .data = value, - .length = sizeof(value) - }; - - struct ldb_val read; - - int flags = 0; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - /* - * Begin a transaction - */ - ret = ldb_kv->kv_ops->begin_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * Write the record - */ - ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); - assert_int_equal(ret, 0); - - /* - * Commit the transaction - */ - ret = ldb_kv->kv_ops->finish_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * And now read it back - */ - ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); - assert_int_equal(ret, 0); - ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); - assert_int_equal(ret, 0); - assert_int_equal(sizeof(value), read.length); - assert_memory_equal(value, read.data, sizeof(value)); - ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); - assert_int_equal(ret, 0); - - /* - * Begin a transaction - */ - ret = ldb_kv->kv_ops->begin_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * Now delete it. - */ - ret = ldb_kv->kv_ops->delete (ldb_kv, key); - assert_int_equal(ret, 0); - - /* - * Commit the transaction - */ - ret = ldb_kv->kv_ops->finish_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * And now try to read it back - */ - ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); - assert_int_equal(ret, 0); - ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); - assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT); - ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); - assert_int_equal(ret, 0); - - talloc_free(tmp_ctx); -} - -/* - * Check that writes are correctly rolled back when a transaction - * is rolled back. - */ -static void test_transaction_abort_write(void **state) -{ - int ret; - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); - uint8_t key_val[] = "TheKey"; - struct ldb_val key = { - .data = key_val, - .length = sizeof(key_val) - }; - - uint8_t value[] = "The record contents"; - struct ldb_val data = { - .data = value, - .length = sizeof(value) - }; - - struct ldb_val read; - - int flags = 0; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - /* - * Begin a transaction - */ - ret = ldb_kv->kv_ops->begin_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * Write the record - */ - ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); - assert_int_equal(ret, 0); - - /* - * And now read it back - */ - ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); - assert_int_equal(ret, 0); - assert_int_equal(sizeof(value), read.length); - assert_memory_equal(value, read.data, sizeof(value)); - - - /* - * Now abort the transaction - */ - ret = ldb_kv->kv_ops->abort_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * And now read it back, should not be there - */ - ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); - assert_int_equal(ret, 0); - ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); - assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT); - ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); - assert_int_equal(ret, 0); - - talloc_free(tmp_ctx); -} - -/* - * Check that deletes are correctly rolled back when a transaction is - * aborted. - */ -static void test_transaction_abort_delete(void **state) -{ - int ret; - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); - uint8_t key_val[] = "TheKey"; - struct ldb_val key = { - .data = key_val, - .length = sizeof(key_val) - }; - - uint8_t value[] = "The record contents"; - struct ldb_val data = { - .data = value, - .length = sizeof(value) - }; - - struct ldb_val read; - - int flags = 0; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - /* - * Begin a transaction - */ - ret = ldb_kv->kv_ops->begin_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * Write the record - */ - ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); - assert_int_equal(ret, 0); - - /* - * Commit the transaction - */ - ret = ldb_kv->kv_ops->finish_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * And now read it back - */ - ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); - assert_int_equal(ret, 0); - ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); - assert_int_equal(ret, 0); - assert_int_equal(sizeof(value), read.length); - assert_memory_equal(value, read.data, sizeof(value)); - ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); - assert_int_equal(ret, 0); - - /* - * Begin a transaction - */ - ret = ldb_kv->kv_ops->begin_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * Now delete it. - */ - ret = ldb_kv->kv_ops->delete (ldb_kv, key); - assert_int_equal(ret, 0); - - /* - * And now read it back - */ - ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); - assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT); - - /* - * Abort the transaction - */ - ret = ldb_kv->kv_ops->abort_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * And now try to read it back - */ - ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); - assert_int_equal(ret, 0); - ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); - assert_int_equal(ret, 0); - assert_int_equal(sizeof(value), read.length); - assert_memory_equal(value, read.data, sizeof(value)); - ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); - assert_int_equal(ret, 0); - - talloc_free(tmp_ctx); -} - -/* - * Test that writes outside a transaction fail - */ -static void test_write_outside_transaction(void **state) -{ - int ret; - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); - uint8_t key_val[] = "TheKey"; - struct ldb_val key = { - .data = key_val, - .length = sizeof(key_val) - }; - - uint8_t value[] = "The record contents"; - struct ldb_val data = { - .data = value, - .length = sizeof(value) - }; - - - int flags = 0; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - /* - * Attempt to write the record - */ - ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); - assert_int_equal(ret, LDB_ERR_PROTOCOL_ERROR); - - talloc_free(tmp_ctx); -} - -/* - * Test data can not be deleted outside a transaction - */ -static void test_delete_outside_transaction(void **state) -{ - int ret; - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); - uint8_t key_val[] = "TheKey"; - struct ldb_val key = { - .data = key_val, - .length = sizeof(key_val) - }; - - uint8_t value[] = "The record contents"; - struct ldb_val data = { - .data = value, - .length = sizeof(value) - }; - - struct ldb_val read; - - int flags = 0; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - /* - * Begin a transaction - */ - ret = ldb_kv->kv_ops->begin_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * Write the record - */ - ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); - assert_int_equal(ret, 0); - - /* - * Commit the transaction - */ - ret = ldb_kv->kv_ops->finish_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * And now read it back - */ - ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); - assert_int_equal(ret, 0); - ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); - assert_int_equal(ret, 0); - assert_int_equal(sizeof(value), read.length); - assert_memory_equal(value, read.data, sizeof(value)); - ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); - assert_int_equal(ret, 0); - - /* - * Now attempt to delete a record - */ - ret = ldb_kv->kv_ops->delete (ldb_kv, key); - assert_int_equal(ret, LDB_ERR_PROTOCOL_ERROR); - - /* - * And now read it back - */ - ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); - assert_int_equal(ret, 0); - ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &read); - assert_int_equal(ret, 0); - assert_int_equal(sizeof(value), read.length); - assert_memory_equal(value, read.data, sizeof(value)); - ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); - assert_int_equal(ret, 0); - - talloc_free(tmp_ctx); -} - -static int traverse_fn(struct ldb_kv_private *ldb_kv, - struct ldb_val key, - struct ldb_val data, - void *ctx) -{ - - int *visits = ctx; - int i; - - if (strncmp("key ", (char *) key.data, 4) == 0) { - i = strtol((char *) &key.data[4], NULL, 10); - visits[i]++; - } - return LDB_SUCCESS; -} - -/* - * Test that iterate visits all the records. - */ -static void test_iterate(void **state) -{ - int ret; - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); - int i; - int num_recs = 1024; - int visits[num_recs]; - - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - /* - * Begin a transaction - */ - ret = ldb_kv->kv_ops->begin_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * Write the records - */ - for (i = 0; i < num_recs; i++) { - struct ldb_val key; - struct ldb_val rec; - int flags = 0; - - visits[i] = 0; - key.data = (uint8_t *)talloc_asprintf(tmp_ctx, "key %04d", i); - key.length = strlen((char *)key.data) + 1; - - rec.data = (uint8_t *) talloc_asprintf(tmp_ctx, - "data for record (%04d)", - i); - rec.length = strlen((char *)rec.data) + 1; - - ret = ldb_kv->kv_ops->store(ldb_kv, key, rec, flags); - assert_int_equal(ret, 0); - - TALLOC_FREE(key.data); - TALLOC_FREE(rec.data); - } - - /* - * Commit the transaction - */ - ret = ldb_kv->kv_ops->finish_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * Now iterate over the kv store and ensure that all the - * records are visited. - */ - ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); - assert_int_equal(ret, 0); - ret = ldb_kv->kv_ops->iterate(ldb_kv, traverse_fn, visits); - for (i = 0; i kv_ops->unlock_read(test_ctx->ldb->modules); - assert_int_equal(ret, 0); - - TALLOC_FREE(tmp_ctx); -} - -static void do_iterate_range_test(void **state, int range_start, - int range_end, bool fail) -{ - int ret; - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); - int i; - int num_recs = 1024; - int skip_recs = 10; - int visits[num_recs]; - struct ldb_val sk, ek; - - TALLOC_CTX *tmp_ctx; - - for (i = 0; i < num_recs; i++){ - visits[i] = 0; - } - - /* - * No iterate_range on tdb - */ - if (strcmp(TEST_BE, "tdb") == 0) { - return; - } - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - /* - * Begin a transaction - */ - ret = ldb_kv->kv_ops->begin_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * Write the records - */ - for (i = skip_recs; i <= num_recs - skip_recs; i++) { - struct ldb_val key; - struct ldb_val rec; - int flags = 0; - - key.data = (uint8_t *)talloc_asprintf(tmp_ctx, - "key %04d", - i); - key.length = strlen((char *)key.data); - - rec.data = (uint8_t *)talloc_asprintf(tmp_ctx, - "data for record (%04d)", - i); - rec.length = strlen((char *)rec.data) + 1; - - ret = ldb_kv->kv_ops->store(ldb_kv, key, rec, flags); - assert_int_equal(ret, 0); - - TALLOC_FREE(key.data); - TALLOC_FREE(rec.data); - } - - /* - * Commit the transaction - */ - ret = ldb_kv->kv_ops->finish_write(ldb_kv); - assert_int_equal(ret, 0); - - sk.data = (uint8_t *)talloc_asprintf(tmp_ctx, "key %04d", range_start); - sk.length = strlen((char *)sk.data); - - ek.data = (uint8_t *)talloc_asprintf(tmp_ctx, "key %04d", range_end); - ek.length = strlen((char *)ek.data) + 1; - - ret = ldb_kv->kv_ops->lock_read(test_ctx->ldb->modules); - assert_int_equal(ret, 0); - ret = ldb_kv->kv_ops->iterate_range(ldb_kv, sk, ek, - traverse_fn, visits); - if (fail){ - assert_int_equal(ret, LDB_ERR_PROTOCOL_ERROR); - TALLOC_FREE(tmp_ctx); - return; - } else{ - assert_int_equal(ret, 0); - } - for (i = 0; i < num_recs; i++) { - if (i >= skip_recs && i <= num_recs - skip_recs && - i >= range_start && i <= range_end){ - assert_int_equal(1, visits[i]); - } else { - assert_int_equal(0, visits[i]); - } - } - - ret = ldb_kv->kv_ops->unlock_read(test_ctx->ldb->modules); - assert_int_equal(ret, 0); - - TALLOC_FREE(tmp_ctx); -} - -/* - * Test that iterate_range visits all the records between two keys. - */ -static void test_iterate_range(void **state) -{ - do_iterate_range_test(state, 300, 900, false); - - /* - * test start_key = end_key - */ - do_iterate_range_test(state, 20, 20, false); - - /* - * test reverse range fails - */ - do_iterate_range_test(state, 50, 40, true); - - /* - * keys are between 10-1014 so test with keys outside that range - */ - do_iterate_range_test(state, 0, 20, false); - do_iterate_range_test(state, 1010, 1030, false); - do_iterate_range_test(state, 0, 1030, false); -} - -struct update_context { - struct ldb_context* ldb; - int visits[NUM_RECS]; -}; - -static int update_fn(struct ldb_kv_private *ldb_kv, - struct ldb_val key, - struct ldb_val data, - void *ctx) -{ - - struct ldb_val new_key; - struct ldb_module *module = NULL; - struct update_context *context =NULL; - int ret = LDB_SUCCESS; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_new(ldb_kv); - assert_non_null(tmp_ctx); - - context = talloc_get_type_abort(ctx, struct update_context); - - module = talloc_zero(tmp_ctx, struct ldb_module); - module->ldb = context->ldb; - - if (strncmp("key ", (char *) key.data, 4) == 0) { - int i = strtol((char *) &key.data[4], NULL, 10); - context->visits[i]++; - new_key.data = talloc_memdup(tmp_ctx, key.data, key.length); - new_key.length = key.length; - new_key.data[0] = 'K'; - - ret = ldb_kv->kv_ops->update_in_iterate( - ldb_kv, key, new_key, data, &module); - } - TALLOC_FREE(tmp_ctx); - return ret; -} - -/* - * Test that update_in_iterate behaves as expected. - */ -static void test_update_in_iterate(void **state) -{ - int ret; - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); - int i; - struct update_context *context = NULL; - - - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - context = talloc_zero(tmp_ctx, struct update_context); - assert_non_null(context); - context->ldb = test_ctx->ldb; - /* - * Begin a transaction - */ - ret = ldb_kv->kv_ops->begin_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * Write the records - */ - for (i = 0; i < NUM_RECS; i++) { - struct ldb_val key; - struct ldb_val rec; - int flags = 0; - - key.data = (uint8_t *)talloc_asprintf(tmp_ctx, "key %04d", i); - key.length = strlen((char *)key.data) + 1; - - rec.data = (uint8_t *) talloc_asprintf(tmp_ctx, - "data for record (%04d)", - i); - rec.length = strlen((char *)rec.data) + 1; - - ret = ldb_kv->kv_ops->store(ldb_kv, key, rec, flags); - assert_int_equal(ret, 0); - - TALLOC_FREE(key.data); - TALLOC_FREE(rec.data); - } - - /* - * Commit the transaction - */ - ret = ldb_kv->kv_ops->finish_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * Now iterate over the kv store and ensure that all the - * records are visited. - */ - - /* - * Needs to be done inside a transaction - */ - ret = ldb_kv->kv_ops->begin_write(ldb_kv); - assert_int_equal(ret, 0); - - ret = ldb_kv->kv_ops->iterate(ldb_kv, update_fn, context); - for (i = 0; i < NUM_RECS; i++) { - assert_int_equal(1, context->visits[i]); - } - - ret = ldb_kv->kv_ops->finish_write(ldb_kv); - assert_int_equal(ret, 0); - - TALLOC_FREE(tmp_ctx); -} - -/* - * Ensure that writes are not visible until the transaction has been - * committed. - */ -static void test_write_transaction_isolation(void **state) -{ - int ret; - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); - struct ldb_val key; - struct ldb_val val; - - const char *KEY1 = "KEY01"; - const char *VAL1 = "VALUE01"; - - const char *KEY2 = "KEY02"; - const char *VAL2 = "VALUE02"; - - /* - * Pipes etc to co-ordinate the processes - */ - int to_child[2]; - int to_parent[2]; - char buf[2]; - pid_t pid, w_pid; - int wstatus; - - TALLOC_CTX *tmp_ctx; - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - - /* - * Add a record to the database - */ - ret = ldb_kv->kv_ops->begin_write(ldb_kv); - assert_int_equal(ret, 0); - - key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1); - key.length = strlen(KEY1) + 1; - - val.data = (uint8_t *)talloc_strdup(tmp_ctx, VAL1); - val.length = strlen(VAL1) + 1; - - ret = ldb_kv->kv_ops->store(ldb_kv, key, val, 0); - assert_int_equal(ret, 0); - - ret = ldb_kv->kv_ops->finish_write(ldb_kv); - assert_int_equal(ret, 0); - - - ret = pipe(to_child); - assert_int_equal(ret, 0); - ret = pipe(to_parent); - assert_int_equal(ret, 0); - /* - * Now fork a new process - */ - - pid = fork(); - if (pid == 0) { - - struct ldb_context *ldb = NULL; - close(to_child[1]); - close(to_parent[0]); - - /* - * Wait for the transaction to start - */ - ret = read(to_child[0], buf, 2); - if (ret != 2) { - print_error(__location__": read returned (%d)\n", - ret); - exit(LDB_ERR_OPERATIONS_ERROR); - } - ldb = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb, test_ctx->dbpath, 0, NULL); - if (ret != LDB_SUCCESS) { - print_error(__location__": ldb_connect returned (%d)\n", - ret); - exit(ret); - } - - ldb_kv = get_ldb_kv(ldb); - - ret = ldb_kv->kv_ops->lock_read(ldb->modules); - if (ret != LDB_SUCCESS) { - print_error(__location__": lock_read returned (%d)\n", - ret); - exit(ret); - } - - /* - * Check that KEY1 is there - */ - key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1); - key.length = strlen(KEY1) + 1; - - ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val); - if (ret != LDB_SUCCESS) { - print_error(__location__": fetch_and_parse returned " - "(%d)\n", - ret); - exit(ret); - } - - if ((strlen(VAL1) + 1) != val.length) { - print_error(__location__": KEY1 value lengths different" - ", expected (%d) actual(%d)\n", - (int)(strlen(VAL1) + 1), (int)val.length); - exit(LDB_ERR_OPERATIONS_ERROR); - } - if (memcmp(VAL1, val.data, strlen(VAL1)) != 0) { - print_error(__location__": KEY1 values different, " - "expected (%s) actual(%s)\n", - VAL1, - val.data); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ret = ldb_kv->kv_ops->unlock_read(ldb->modules); - if (ret != LDB_SUCCESS) { - print_error(__location__": unlock_read returned (%d)\n", - ret); - exit(ret); - } - - /* - * Check that KEY2 is not there - */ - key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2); - key.length = strlen(KEY2 + 1); - - ret = ldb_kv->kv_ops->lock_read(ldb->modules); - if (ret != LDB_SUCCESS) { - print_error(__location__": lock_read returned (%d)\n", - ret); - exit(ret); - } - - ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val); - if (ret != LDB_ERR_NO_SUCH_OBJECT) { - print_error(__location__": fetch_and_parse returned " - "(%d)\n", - ret); - exit(ret); - } - - ret = ldb_kv->kv_ops->unlock_read(ldb->modules); - if (ret != LDB_SUCCESS) { - print_error(__location__": unlock_read returned (%d)\n", - ret); - exit(ret); - } - - /* - * Signal the other process to commit the transaction - */ - ret = write(to_parent[1], "GO", 2); - if (ret != 2) { - print_error(__location__": write returned (%d)\n", - ret); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - /* - * Wait for the transaction to be commited - */ - ret = read(to_child[0], buf, 2); - if (ret != 2) { - print_error(__location__": read returned (%d)\n", - ret); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - /* - * Check that KEY1 is there - */ - ret = ldb_kv->kv_ops->lock_read(ldb->modules); - if (ret != LDB_SUCCESS) { - print_error(__location__": unlock_read returned (%d)\n", - ret); - exit(ret); - } - key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1); - key.length = strlen(KEY1) + 1; - - ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val); - if (ret != LDB_SUCCESS) { - print_error(__location__": fetch_and_parse returned " - "(%d)\n", - ret); - exit(ret); - } - - if ((strlen(VAL1) + 1) != val.length) { - print_error(__location__": KEY1 value lengths different" - ", expected (%d) actual(%d)\n", - (int)(strlen(VAL1) + 1), (int)val.length); - exit(LDB_ERR_OPERATIONS_ERROR); - } - if (memcmp(VAL1, val.data, strlen(VAL1)) != 0) { - print_error(__location__": KEY1 values different, " - "expected (%s) actual(%s)\n", - VAL1, - val.data); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ret = ldb_kv->kv_ops->unlock_read(ldb->modules); - if (ret != LDB_SUCCESS) { - print_error(__location__": unlock_read returned (%d)\n", - ret); - exit(ret); - } - - - /* - * Check that KEY2 is there - */ - ret = ldb_kv->kv_ops->lock_read(ldb->modules); - if (ret != LDB_SUCCESS) { - print_error(__location__": unlock_read returned (%d)\n", - ret); - exit(ret); - } - - key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2); - key.length = strlen(KEY2) + 1; - - ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val); - if (ret != LDB_SUCCESS) { - print_error(__location__": fetch_and_parse returned " - "(%d)\n", - ret); - exit(ret); - } - - if ((strlen(VAL2) + 1) != val.length) { - print_error(__location__": KEY2 value lengths different" - ", expected (%d) actual(%d)\n", - (int)(strlen(VAL2) + 1), (int)val.length); - exit(LDB_ERR_OPERATIONS_ERROR); - } - if (memcmp(VAL2, val.data, strlen(VAL2)) != 0) { - print_error(__location__": KEY2 values different, " - "expected (%s) actual(%s)\n", - VAL2, - val.data); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ret = ldb_kv->kv_ops->unlock_read(ldb->modules); - if (ret != LDB_SUCCESS) { - print_error(__location__": unlock_read returned (%d)\n", - ret); - exit(ret); - } - - exit(0); - } - close(to_child[0]); - close(to_parent[1]); - - /* - * Begin a transaction and add a record to the database - * but leave the transaction open - */ - ret = ldb_kv->kv_ops->begin_write(ldb_kv); - assert_int_equal(ret, 0); - - key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2); - key.length = strlen(KEY2) + 1; - - val.data = (uint8_t *)talloc_strdup(tmp_ctx, VAL2); - val.length = strlen(VAL2) + 1; - - ret = ldb_kv->kv_ops->store(ldb_kv, key, val, 0); - assert_int_equal(ret, 0); - - /* - * Signal the child process - */ - ret = write(to_child[1], "GO", 2); - assert_int_equal(2, ret); - - /* - * Wait for the child process to check the DB state while the - * transaction is active - */ - ret = read(to_parent[0], buf, 2); - assert_int_equal(2, ret); - - /* - * commit the transaction - */ - ret = ldb_kv->kv_ops->finish_write(ldb_kv); - assert_int_equal(0, ret); - - /* - * Signal the child process - */ - ret = write(to_child[1], "GO", 2); - assert_int_equal(2, ret); - - w_pid = waitpid(pid, &wstatus, 0); - assert_int_equal(pid, w_pid); - - assert_true(WIFEXITED(wstatus)); - - assert_int_equal(WEXITSTATUS(wstatus), 0); - - - TALLOC_FREE(tmp_ctx); -} - -/* - * Ensure that deletes are not visible until the transaction has been - * committed. - */ -static void test_delete_transaction_isolation(void **state) -{ - int ret; - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); - struct ldb_val key; - struct ldb_val val; - - const char *KEY1 = "KEY01"; - const char *VAL1 = "VALUE01"; - - const char *KEY2 = "KEY02"; - const char *VAL2 = "VALUE02"; - - /* - * Pipes etc to co-ordinate the processes - */ - int to_child[2]; - int to_parent[2]; - char buf[2]; - pid_t pid, w_pid; - int wstatus; - - TALLOC_CTX *tmp_ctx; - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - - /* - * Add records to the database - */ - ret = ldb_kv->kv_ops->begin_write(ldb_kv); - assert_int_equal(ret, 0); - - key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1); - key.length = strlen(KEY1) + 1; - - val.data = (uint8_t *)talloc_strdup(tmp_ctx, VAL1); - val.length = strlen(VAL1) + 1; - - ret = ldb_kv->kv_ops->store(ldb_kv, key, val, 0); - assert_int_equal(ret, 0); - - key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2); - key.length = strlen(KEY2) + 1; - - val.data = (uint8_t *)talloc_strdup(tmp_ctx, VAL2); - val.length = strlen(VAL2) + 1; - - ret = ldb_kv->kv_ops->store(ldb_kv, key, val, 0); - assert_int_equal(ret, 0); - - ret = ldb_kv->kv_ops->finish_write(ldb_kv); - assert_int_equal(ret, 0); - - - ret = pipe(to_child); - assert_int_equal(ret, 0); - ret = pipe(to_parent); - assert_int_equal(ret, 0); - /* - * Now fork a new process - */ - - pid = fork(); - if (pid == 0) { - - struct ldb_context *ldb = NULL; - close(to_child[1]); - close(to_parent[0]); - - /* - * Wait for the transaction to be started - */ - ret = read(to_child[0], buf, 2); - if (ret != 2) { - print_error(__location__": read returned (%d)\n", - ret); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ldb = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb, test_ctx->dbpath, 0, NULL); - if (ret != LDB_SUCCESS) { - print_error(__location__": ldb_connect returned (%d)\n", - ret); - exit(ret); - } - - ldb_kv = get_ldb_kv(ldb); - - ret = ldb_kv->kv_ops->lock_read(ldb->modules); - if (ret != LDB_SUCCESS) { - print_error(__location__": lock_read returned (%d)\n", - ret); - exit(ret); - } - - /* - * Check that KEY1 is there - */ - key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1); - key.length = strlen(KEY1) + 1; - - ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val); - if (ret != LDB_SUCCESS) { - print_error(__location__": fetch_and_parse returned " - "(%d)\n", - ret); - exit(ret); - } - - if ((strlen(VAL1) + 1) != val.length) { - print_error(__location__": KEY1 value lengths different" - ", expected (%d) actual(%d)\n", - (int)(strlen(VAL1) + 1), (int)val.length); - exit(LDB_ERR_OPERATIONS_ERROR); - } - if (memcmp(VAL1, val.data, strlen(VAL1)) != 0) { - print_error(__location__": KEY1 values different, " - "expected (%s) actual(%s)\n", - VAL1, - val.data); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - /* - * Check that KEY2 is there - */ - - key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2); - key.length = strlen(KEY2) + 1; - - ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val); - if (ret != LDB_SUCCESS) { - print_error(__location__": fetch_and_parse returned " - "(%d)\n", - ret); - exit(ret); - } - - if ((strlen(VAL2) + 1) != val.length) { - print_error(__location__": KEY2 value lengths different" - ", expected (%d) actual(%d)\n", - (int)(strlen(VAL2) + 1), (int)val.length); - exit(LDB_ERR_OPERATIONS_ERROR); - } - if (memcmp(VAL2, val.data, strlen(VAL2)) != 0) { - print_error(__location__": KEY2 values different, " - "expected (%s) actual(%s)\n", - VAL2, - val.data); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ret = ldb_kv->kv_ops->unlock_read(ldb->modules); - if (ret != LDB_SUCCESS) { - print_error(__location__": unlock_read returned (%d)\n", - ret); - exit(ret); - } - - /* - * Signal the other process to commit the transaction - */ - ret = write(to_parent[1], "GO", 2); - if (ret != 2) { - print_error(__location__": write returned (%d)\n", - ret); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - /* - * Wait for the transaction to be commited - */ - ret = read(to_child[0], buf, 2); - if (ret != 2) { - print_error(__location__": read returned (%d)\n", - ret); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - /* - * Check that KEY1 is there - */ - ret = ldb_kv->kv_ops->lock_read(ldb->modules); - if (ret != LDB_SUCCESS) { - print_error(__location__": unlock_read returned (%d)\n", - ret); - exit(ret); - } - key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY1); - key.length = strlen(KEY1) + 1; - - ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val); - if (ret != LDB_SUCCESS) { - print_error(__location__": fetch_and_parse returned " - "(%d)\n", - ret); - exit(ret); - } - - if ((strlen(VAL1) + 1) != val.length) { - print_error(__location__": KEY1 value lengths different" - ", expected (%d) actual(%d)\n", - (int)(strlen(VAL1) + 1), (int)val.length); - exit(LDB_ERR_OPERATIONS_ERROR); - } - if (memcmp(VAL1, val.data, strlen(VAL1)) != 0) { - print_error(__location__": KEY1 values different, " - "expected (%s) actual(%s)\n", - VAL1, - val.data); - exit(LDB_ERR_OPERATIONS_ERROR); - } - ret = ldb_kv->kv_ops->unlock_read(ldb->modules); - if (ret != LDB_SUCCESS) { - print_error(__location__": unlock_read returned (%d)\n", - ret); - exit(ret); - } - - /* - * Check that KEY2 is not there - */ - key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2); - key.length = strlen(KEY2 + 1); - - ret = ldb_kv->kv_ops->lock_read(ldb->modules); - if (ret != LDB_SUCCESS) { - print_error(__location__": lock_read returned (%d)\n", - ret); - exit(ret); - } - - ret = ldb_kv->kv_ops->fetch_and_parse(ldb_kv, key, parse, &val); - if (ret != LDB_ERR_NO_SUCH_OBJECT) { - print_error(__location__": fetch_and_parse returned " - "(%d)\n", - ret); - exit(ret); - } - - ret = ldb_kv->kv_ops->unlock_read(ldb->modules); - if (ret != LDB_SUCCESS) { - print_error(__location__": unlock_read returned (%d)\n", - ret); - exit(ret); - } - TALLOC_FREE(tmp_ctx); - exit(0); - } - close(to_child[0]); - close(to_parent[1]); - - /* - * Begin a transaction and delete a record from the database - * but leave the transaction open - */ - ret = ldb_kv->kv_ops->begin_write(ldb_kv); - assert_int_equal(ret, 0); - - key.data = (uint8_t *)talloc_strdup(tmp_ctx, KEY2); - key.length = strlen(KEY2) + 1; - - ret = ldb_kv->kv_ops->delete (ldb_kv, key); - assert_int_equal(ret, 0); - /* - * Signal the child process - */ - ret = write(to_child[1], "GO", 2); - assert_int_equal(2, ret); - - /* - * Wait for the child process to check the DB state while the - * transaction is active - */ - ret = read(to_parent[0], buf, 2); - assert_int_equal(2, ret); - - /* - * commit the transaction - */ - ret = ldb_kv->kv_ops->finish_write(ldb_kv); - assert_int_equal(0, ret); - - /* - * Signal the child process - */ - ret = write(to_child[1], "GO", 2); - assert_int_equal(2, ret); - - w_pid = waitpid(pid, &wstatus, 0); - assert_int_equal(pid, w_pid); - - assert_true(WIFEXITED(wstatus)); - - assert_int_equal(WEXITSTATUS(wstatus), 0); - - - TALLOC_FREE(tmp_ctx); -} - - -/* - * Test that get_size returns a sensible estimate of the number of records - * in the database. - */ -static void test_get_size(void **state) -{ - int ret; - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - struct ldb_kv_private *ldb_kv = get_ldb_kv(test_ctx->ldb); - uint8_t key_val[] = "TheKey"; - struct ldb_val key = { - .data = key_val, - .length = sizeof(key_val) - }; - - uint8_t value[] = "The record contents"; - struct ldb_val data = { - .data = value, - .length = sizeof(value) - }; - size_t size = 0; - - int flags = 0; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - size = ldb_kv->kv_ops->get_size(ldb_kv); -#if defined(TEST_LMDB) - assert_int_equal(2, size); -#else - /* - * The tdb implementation of get_size over estimates for sparse files - * which is perfectly acceptable for it's intended use. - */ - assert_true( size > 2500); -#endif - - /* - * Begin a transaction - */ - ret = ldb_kv->kv_ops->begin_write(ldb_kv); - assert_int_equal(ret, 0); - - /* - * Write the record - */ - ret = ldb_kv->kv_ops->store(ldb_kv, key, data, flags); - assert_int_equal(ret, 0); - - /* - * Commit the transaction - */ - ret = ldb_kv->kv_ops->finish_write(ldb_kv); - assert_int_equal(ret, 0); - - size = ldb_kv->kv_ops->get_size(ldb_kv); -#ifdef TEST_LMDB - assert_int_equal(3, size); -#endif - talloc_free(tmp_ctx); -} - -int main(int argc, const char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown( - test_add_get, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_delete, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_transaction_abort_write, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_transaction_abort_delete, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_read_outside_transaction, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_write_outside_transaction, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_delete_outside_transaction, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_iterate, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_iterate_range, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_update_in_iterate, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_write_transaction_isolation, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_delete_transaction_isolation, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_get_size, - setup, - teardown), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/ldb-2.0.8/tests/ldb_kv_ops_test.valgrind b/ldb-2.0.8/tests/ldb_kv_ops_test.valgrind deleted file mode 100644 index 1747076..0000000 --- a/ldb-2.0.8/tests/ldb_kv_ops_test.valgrind +++ /dev/null @@ -1,97 +0,0 @@ -{ - Memory allocated by setup - Memcheck:Leak - match-leak-kinds: possible - fun:malloc - ... - fun:setup -} -{ - Memory allocated by setup - Memcheck:Leak - match-leak-kinds: possible - fun:realloc - ... - fun:setup -} -{ - Memory allocated by ldb_init - Memcheck:Leak - match-leak-kinds: possible - fun:malloc - ... - fun:ldb_init -} -{ - Memory allocated by ldb_init - Memcheck:Leak - match-leak-kinds: possible - fun:realloc - ... - fun:ldb_init -} -{ - Memory allocated by noconn_setup - Memcheck:Leak - match-leak-kinds: possible - fun:malloc - ... - fun:noconn_setup -} -{ - Memory allocated by parse, which allocates on the NULL context - Memcheck:Leak - match-leak-kinds: all - fun:malloc - ... - fun:parse -} -{ - Memory allocated by tdb_parse_data - Memcheck:Leak - match-leak-kinds: all - fun:malloc - ... - fun:tdb_parse_data -} -{ - Memory allocated by ldb_connect - Memcheck:Leak - match-leak-kinds: possible - fun:malloc - ... - fun:ldb_connect -} -{ - Memory allocated by ldb_connect - Memcheck:Leak - match-leak-kinds: possible - fun:calloc - ... - fun:ldb_connect -} -{ - Memory allocated by ldb_kv_cache_load - Memcheck:Leak - match-leak-kinds: possible - fun:malloc - ... - fun:ldb_kv_cache_load -} -{ - Memory allocated by ldb_kv_index_load - Memcheck:Leak - match-leak-kinds: possible - fun:malloc - ... - fun:ldb_kv_index_load -} -{ - Memory allocated by ldb_asprintf_errstring - Memcheck:Leak - match-leak-kinds: possible - fun:malloc - ... - fun:ldb_asprintf_errstring -} - diff --git a/ldb-2.0.8/tests/ldb_lmdb_size_test.c b/ldb-2.0.8/tests/ldb_lmdb_size_test.c deleted file mode 100644 index af015fa..0000000 --- a/ldb-2.0.8/tests/ldb_lmdb_size_test.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * lmdb backend specific tests for ldb - * Tests for truncated index keys - * - * Copyright (C) Andrew Bartlett 2018 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/* - * These tests confirm that database sizes of > 4GB are supported - * Due to the disk space requirement they are not run as part of the normal - * self test runs. - * - * Setup and tear down code copied from ldb_mod_op_test.c - */ - -/* - * from cmocka.c: - * These headers or their equivalents should be included prior to - * including - * this header file. - * - * #include - * #include - * #include - * - * This allows test applications to use custom definitions of C standard - * library functions and types. - * - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - - -#define TEST_BE "mdb" - -struct ldbtest_ctx { - struct tevent_context *ev; - struct ldb_context *ldb; - - const char *dbfile; - const char *lockfile; /* lockfile is separate */ - - const char *dbpath; -}; - -static void unlink_old_db(struct ldbtest_ctx *test_ctx) -{ - int ret; - - errno = 0; - ret = unlink(test_ctx->lockfile); - if (ret == -1 && errno != ENOENT) { - fail(); - } - - errno = 0; - ret = unlink(test_ctx->dbfile); - if (ret == -1 && errno != ENOENT) { - fail(); - } -} - -static int ldbtest_noconn_setup(void **state) -{ - struct ldbtest_ctx *test_ctx; - - test_ctx = talloc_zero(NULL, struct ldbtest_ctx); - assert_non_null(test_ctx); - - test_ctx->ev = tevent_context_init(test_ctx); - assert_non_null(test_ctx->ev); - - test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev); - assert_non_null(test_ctx->ldb); - - test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb"); - assert_non_null(test_ctx->dbfile); - - test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock", - test_ctx->dbfile); - assert_non_null(test_ctx->lockfile); - - test_ctx->dbpath = talloc_asprintf(test_ctx, - TEST_BE"://%s", test_ctx->dbfile); - assert_non_null(test_ctx->dbpath); - - unlink_old_db(test_ctx); - *state = test_ctx; - return 0; -} - -static int ldbtest_noconn_teardown(void **state) -{ - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - - unlink_old_db(test_ctx); - talloc_free(test_ctx); - return 0; -} - -static int ldbtest_setup(void **state) -{ - struct ldbtest_ctx *test_ctx; - int ret; - - ldbtest_noconn_setup((void **) &test_ctx); - - ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL); - assert_int_equal(ret, 0); - - *state = test_ctx; - return 0; -} - -static int ldbtest_teardown(void **state) -{ - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - ldbtest_noconn_teardown((void **) &test_ctx); - return 0; -} - -static void test_db_size_gt_4GB(void **state) -{ - int ret, x; - struct ldb_message *msg; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - const int MB = 1024 * 1024; - char *blob = NULL; - - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - - blob = talloc_zero_size(tmp_ctx, (MB + 1)); - assert_non_null(blob); - memset(blob, 'x', MB); - - - for (x = 0; x < 6144; x++) { - msg = ldb_msg_new(tmp_ctx); - assert_non_null(msg); - - msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test%d", x); - assert_non_null(msg->dn); - - ldb_transaction_start(test_ctx->ldb); - ret = ldb_msg_add_string(msg, "blob", blob); - assert_int_equal(ret, 0); - - ret = ldb_add(test_ctx->ldb, msg); - assert_int_equal(ret, 0); - ldb_transaction_commit(test_ctx->ldb); - - TALLOC_FREE(msg); - } - talloc_free(tmp_ctx); - { - struct stat s; - ret = stat(test_ctx->dbfile, &s); - assert_int_equal(ret, 0); - assert_true(s.st_size > (6144LL * MB)); - } -} - -int main(int argc, const char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown( - test_db_size_gt_4GB, - ldbtest_setup, - ldbtest_teardown), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/ldb-2.0.8/tests/ldb_lmdb_test.c b/ldb-2.0.8/tests/ldb_lmdb_test.c deleted file mode 100644 index 78758bb..0000000 --- a/ldb-2.0.8/tests/ldb_lmdb_test.c +++ /dev/null @@ -1,589 +0,0 @@ -/* - * lmdb backend specific tests for ldb - * - * Copyright (C) Andrew Bartlett 2018 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/* - * lmdb backend specific tests for ldb - * - * Setup and tear down code copied from ldb_mod_op_test.c - */ - -/* - * from cmocka.c: - * These headers or their equivalents should be included prior to - * including - * this header file. - * - * #include - * #include - * #include - * - * This allows test applications to use custom definitions of C standard - * library functions and types. - * - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "../ldb_tdb/ldb_tdb.h" -#include "../ldb_mdb/ldb_mdb.h" -#include "../ldb_key_value/ldb_kv.h" - -#define TEST_BE "mdb" - -#define LMDB_MAX_KEY_SIZE 511 - -struct ldbtest_ctx { - struct tevent_context *ev; - struct ldb_context *ldb; - - const char *dbfile; - const char *lockfile; /* lockfile is separate */ - - const char *dbpath; -}; - -static void unlink_old_db(struct ldbtest_ctx *test_ctx) -{ - int ret; - - errno = 0; - ret = unlink(test_ctx->lockfile); - if (ret == -1 && errno != ENOENT) { - fail(); - } - - errno = 0; - ret = unlink(test_ctx->dbfile); - if (ret == -1 && errno != ENOENT) { - fail(); - } -} - -static int ldbtest_noconn_setup(void **state) -{ - struct ldbtest_ctx *test_ctx; - - test_ctx = talloc_zero(NULL, struct ldbtest_ctx); - assert_non_null(test_ctx); - - test_ctx->ev = tevent_context_init(test_ctx); - assert_non_null(test_ctx->ev); - - test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev); - assert_non_null(test_ctx->ldb); - - test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb"); - assert_non_null(test_ctx->dbfile); - - test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock", - test_ctx->dbfile); - assert_non_null(test_ctx->lockfile); - - test_ctx->dbpath = talloc_asprintf(test_ctx, - TEST_BE"://%s", test_ctx->dbfile); - assert_non_null(test_ctx->dbpath); - - unlink_old_db(test_ctx); - *state = test_ctx; - return 0; -} - -static int ldbtest_noconn_teardown(void **state) -{ - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - - unlink_old_db(test_ctx); - talloc_free(test_ctx); - return 0; -} - -static int ldbtest_setup(void **state) -{ - struct ldbtest_ctx *test_ctx; - int ret; - struct ldb_ldif *ldif; - const char *index_ldif = \ - "dn: @INDEXLIST\n" - "@IDXGUID: objectUUID\n" - "@IDX_DN_GUID: GUID\n" - "\n"; - - ldbtest_noconn_setup((void **) &test_ctx); - - ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL); - assert_int_equal(ret, 0); - - while ((ldif = ldb_ldif_read_string(test_ctx->ldb, &index_ldif))) { - ret = ldb_add(test_ctx->ldb, ldif->msg); - assert_int_equal(ret, LDB_SUCCESS); - } - *state = test_ctx; - return 0; -} - -static int ldbtest_teardown(void **state) -{ - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - ldbtest_noconn_teardown((void **) &test_ctx); - return 0; -} - -static void test_ldb_add_key_len_gt_max(void **state) -{ - int ret; - int xs_size = 0; - struct ldb_message *msg; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - char *xs = NULL; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - msg = ldb_msg_new(tmp_ctx); - assert_non_null(msg); - - /* - * The zero terminator is part of the key if we were not in - * GUID mode - */ - - xs_size = LMDB_MAX_KEY_SIZE - 7; /* "dn=dc=" and the zero terminator */ - xs_size += 1; /* want key on char too long */ - xs = talloc_zero_size(tmp_ctx, (xs_size + 1)); - memset(xs, 'x', xs_size); - - msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=%s", xs); - assert_non_null(msg->dn); - - ret = ldb_msg_add_string(msg, "cn", "test_cn_val"); - assert_int_equal(ret, 0); - - ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef"); - assert_int_equal(ret, 0); - - ret = ldb_add(test_ctx->ldb, msg); - assert_int_equal(ret, LDB_SUCCESS); - - talloc_free(tmp_ctx); -} - -static void test_ldb_add_key_len_2x_gt_max(void **state) -{ - int ret; - int xs_size = 0; - struct ldb_message *msg; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - char *xs = NULL; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - msg = ldb_msg_new(tmp_ctx); - assert_non_null(msg); - - /* - * The zero terminator is part of the key if we were not in - * GUID mode - */ - - xs_size = 2 * LMDB_MAX_KEY_SIZE; - xs = talloc_zero_size(tmp_ctx, (xs_size + 1)); - memset(xs, 'x', xs_size); - - msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=%s", xs); - assert_non_null(msg->dn); - - ret = ldb_msg_add_string(msg, "cn", "test_cn_val"); - assert_int_equal(ret, 0); - - ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef"); - assert_int_equal(ret, 0); - - ret = ldb_add(test_ctx->ldb, msg); - assert_int_equal(ret, LDB_SUCCESS); - - talloc_free(tmp_ctx); -} - -static void test_ldb_add_key_len_eq_max(void **state) -{ - int ret; - int xs_size = 0; - struct ldb_message *msg; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - char *xs = NULL; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - msg = ldb_msg_new(tmp_ctx); - assert_non_null(msg); - - /* - * The zero terminator is part of the key if we were not in - * GUID mode - */ - - xs_size = LMDB_MAX_KEY_SIZE - 7; /* "dn=dc=" and the zero terminator */ - xs = talloc_zero_size(tmp_ctx, (xs_size + 1)); - memset(xs, 'x', xs_size); - - msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=%s", xs); - assert_non_null(msg->dn); - - ret = ldb_msg_add_string(msg, "cn", "test_cn_val"); - assert_int_equal(ret, 0); - - ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef"); - assert_int_equal(ret, 0); - - ret = ldb_add(test_ctx->ldb, msg); - assert_int_equal(ret, 0); - - talloc_free(tmp_ctx); -} - -static int ldbtest_setup_noguid(void **state) -{ - struct ldbtest_ctx *test_ctx; - int ret; - - ldbtest_noconn_setup((void **) &test_ctx); - - ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL); - assert_int_equal(ret, 0); - - *state = test_ctx; - return 0; -} - -static void test_ldb_add_special_key_len_gt_max(void **state) -{ - int ret; - int xs_size = 0; - struct ldb_message *msg; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - char *xs = NULL; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - msg = ldb_msg_new(tmp_ctx); - assert_non_null(msg); - - /* - * The zero terminator is part of the key if we were not in - * GUID mode - */ - - xs_size = LMDB_MAX_KEY_SIZE - 5; /* "dn=@" and the zero terminator */ - xs_size += 1; /* want key on char too long */ - xs = talloc_zero_size(tmp_ctx, (xs_size + 1)); - memset(xs, 'x', xs_size); - - msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "@%s", xs); - assert_non_null(msg->dn); - - ret = ldb_msg_add_string(msg, "cn", "test_cn_val"); - assert_int_equal(ret, 0); - - ret = ldb_add(test_ctx->ldb, msg); - assert_int_equal(ret, LDB_ERR_PROTOCOL_ERROR); - - talloc_free(tmp_ctx); -} - -static void test_ldb_add_special_key_len_eq_max(void **state) -{ - int ret; - int xs_size = 0; - struct ldb_message *msg; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - char *xs = NULL; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - msg = ldb_msg_new(tmp_ctx); - assert_non_null(msg); - - /* - * The zero terminator is part of the key if we were not in - * GUID mode - */ - - xs_size = LMDB_MAX_KEY_SIZE - 5; /* "dn=@" and the zero terminator */ - xs = talloc_zero_size(tmp_ctx, (xs_size + 1)); - memset(xs, 'x', xs_size); - - msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "@%s", xs); - assert_non_null(msg->dn); - - ret = ldb_msg_add_string(msg, "cn", "test_cn_val"); - assert_int_equal(ret, 0); - - ret = ldb_add(test_ctx->ldb, msg); - assert_int_equal(ret, LDB_SUCCESS); - - talloc_free(tmp_ctx); -} - -static void test_ldb_add_dn_no_guid_mode(void **state) -{ - int ret; - int xs_size = 0; - struct ldb_message *msg; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - char *xs = NULL; - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - msg = ldb_msg_new(tmp_ctx); - assert_non_null(msg); - - /* - * The zero terminator is part of the key if we were not in - * GUID mode - */ - - xs_size = LMDB_MAX_KEY_SIZE - 7; /* "dn=dc=" and the zero terminator */ - xs_size += 1; /* want key on char too long */ - xs = talloc_zero_size(tmp_ctx, (xs_size + 1)); - memset(xs, 'x', xs_size); - - msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=%s", xs); - assert_non_null(msg->dn); - - ret = ldb_msg_add_string(msg, "cn", "test_cn_val"); - assert_int_equal(ret, 0); - - ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef"); - assert_int_equal(ret, 0); - - ret = ldb_add(test_ctx->ldb, msg); - assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM); - - talloc_free(tmp_ctx); -} - -static struct MDB_env *get_mdb_env(struct ldb_context *ldb) -{ - void *data = NULL; - struct ldb_kv_private *ldb_kv = NULL; - struct lmdb_private *lmdb = NULL; - struct MDB_env *env = NULL; - - data = ldb_module_get_private(ldb->modules); - assert_non_null(data); - - ldb_kv = talloc_get_type(data, struct ldb_kv_private); - assert_non_null(ldb_kv); - - lmdb = ldb_kv->lmdb_private; - assert_non_null(lmdb); - - env = lmdb->env; - assert_non_null(env); - - return env; -} - -static void test_multiple_opens(void **state) -{ - struct ldb_context *ldb1 = NULL; - struct ldb_context *ldb2 = NULL; - struct ldb_context *ldb3 = NULL; - struct MDB_env *env1 = NULL; - struct MDB_env *env2 = NULL; - struct MDB_env *env3 = NULL; - int ret; - struct ldbtest_ctx *test_ctx = NULL; - - test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); - - /* - * Open the database again - */ - ldb1 = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); - assert_int_equal(ret, 0); - - ldb2 = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb2, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); - assert_int_equal(ret, 0); - - ldb3 = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL); - assert_int_equal(ret, 0); - /* - * We now have 3 ldb's open pointing to the same on disk database - * they should all share the same MDB_env - */ - env1 = get_mdb_env(ldb1); - env2 = get_mdb_env(ldb2); - env3 = get_mdb_env(ldb3); - - assert_ptr_equal(env1, env2); - assert_ptr_equal(env1, env3); -} - -static void test_multiple_opens_across_fork(void **state) -{ - struct ldb_context *ldb1 = NULL; - struct ldb_context *ldb2 = NULL; - struct MDB_env *env1 = NULL; - struct MDB_env *env2 = NULL; - int ret; - struct ldbtest_ctx *test_ctx = NULL; - int pipes[2]; - char buf[2]; - int wstatus; - pid_t pid, child_pid; - - test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); - - /* - * Open the database again - */ - ldb1 = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); - assert_int_equal(ret, 0); - - ldb2 = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb2, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); - assert_int_equal(ret, 0); - - env1 = get_mdb_env(ldb1); - env2 = get_mdb_env(ldb2); - - ret = pipe(pipes); - assert_int_equal(ret, 0); - - child_pid = fork(); - if (child_pid == 0) { - struct ldb_context *ldb3 = NULL; - struct MDB_env *env3 = NULL; - - close(pipes[0]); - ldb3 = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL); - if (ret != 0) { - print_error(__location__": ldb_connect returned (%d)\n", - ret); - exit(ret); - } - env3 = get_mdb_env(ldb3); - if (env1 != env2) { - print_error(__location__": env1 != env2\n"); - exit(LDB_ERR_OPERATIONS_ERROR); - } - if (env1 == env3) { - print_error(__location__": env1 == env3\n"); - exit(LDB_ERR_OPERATIONS_ERROR); - } - ret = write(pipes[1], "GO", 2); - if (ret != 2) { - print_error(__location__ - " write returned (%d)", - ret); - exit(LDB_ERR_OPERATIONS_ERROR); - } - exit(LDB_SUCCESS); - } - close(pipes[1]); - ret = read(pipes[0], buf, 2); - assert_int_equal(ret, 2); - - pid = waitpid(child_pid, &wstatus, 0); - assert_int_equal(pid, child_pid); - - assert_true(WIFEXITED(wstatus)); - - assert_int_equal(WEXITSTATUS(wstatus), 0); -} - -int main(int argc, const char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown( - test_ldb_add_key_len_eq_max, - ldbtest_setup, - ldbtest_teardown), - cmocka_unit_test_setup_teardown( - test_ldb_add_key_len_gt_max, - ldbtest_setup, - ldbtest_teardown), - cmocka_unit_test_setup_teardown( - test_ldb_add_key_len_2x_gt_max, - ldbtest_setup, - ldbtest_teardown), - cmocka_unit_test_setup_teardown( - test_ldb_add_special_key_len_eq_max, - ldbtest_setup_noguid, - ldbtest_teardown), - cmocka_unit_test_setup_teardown( - test_ldb_add_special_key_len_gt_max, - ldbtest_setup_noguid, - ldbtest_teardown), - cmocka_unit_test_setup_teardown( - test_ldb_add_dn_no_guid_mode, - ldbtest_setup_noguid, - ldbtest_teardown), - cmocka_unit_test_setup_teardown( - test_multiple_opens, - ldbtest_setup, - ldbtest_teardown), - cmocka_unit_test_setup_teardown( - test_multiple_opens_across_fork, - ldbtest_setup, - ldbtest_teardown), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/ldb-2.0.8/tests/ldb_match_test.c b/ldb-2.0.8/tests/ldb_match_test.c deleted file mode 100644 index e09f50c..0000000 --- a/ldb-2.0.8/tests/ldb_match_test.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Tests exercising the ldb match operations. - * - * - * Copyright (C) Catalyst.NET Ltd 2017 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/* - * from cmocka.c: - * These headers or their equivalents should be included prior to - * including - * this header file. - * - * #include - * #include - * #include - * - * This allows test applications to use custom definitions of C standard - * library functions and types. - */ -#include -#include -#include -#include -#include - -#include "../common/ldb_match.c" - -#include "../include/ldb.h" - -struct ldbtest_ctx { - struct tevent_context *ev; - struct ldb_context *ldb; -}; - -static int ldb_test_canonicalise( - struct ldb_context *ldb, - void *mem_ctx, - const struct ldb_val *in, - struct ldb_val *out) -{ - out->length = in->length; - out->data = in->data; - return 0; -} - -static int setup(void **state) -{ - struct ldbtest_ctx *test_ctx; - struct ldb_schema_syntax *syntax = NULL; - int ret; - - test_ctx = talloc_zero(NULL, struct ldbtest_ctx); - assert_non_null(test_ctx); - - test_ctx->ev = tevent_context_init(test_ctx); - assert_non_null(test_ctx->ev); - - test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev); - assert_non_null(test_ctx->ldb); - - syntax = talloc_zero(test_ctx, struct ldb_schema_syntax); - assert_non_null(syntax); - syntax->canonicalise_fn = ldb_test_canonicalise; - - ret = ldb_schema_attribute_add_with_syntax( - test_ctx->ldb, "a", LDB_ATTR_FLAG_FIXED, syntax); - assert_int_equal(LDB_SUCCESS, ret); - - *state = test_ctx; - return 0; -} - -static int teardown(void **state) -{ - talloc_free(*state); - return 0; -} - - -/* - * The wild card pattern "attribute=*" is parsed as an LDB_OP_PRESENT operation - * rather than a LDB_OP_???? - * - * This test serves to document that behaviour, and to confirm that - * ldb_wildcard_compare handles this case appropriately. - */ -static void test_wildcard_match_star(void **state) -{ - struct ldbtest_ctx *ctx = *state; - bool matched = false; - int ret; - - uint8_t value[] = "The value.......end"; - struct ldb_val val = { - .data = value, - .length = (sizeof(value)) - }; - struct ldb_parse_tree *tree = ldb_parse_tree(ctx, "a=*"); - assert_non_null(tree); - - ret = ldb_wildcard_compare(ctx->ldb, tree, val, &matched); - assert_false(matched); - assert_int_equal(LDB_ERR_INAPPROPRIATE_MATCHING, ret); -} - -/* - * Test basic wild card matching - * - */ -static void test_wildcard_match(void **state) -{ - struct ldbtest_ctx *ctx = *state; - bool matched = false; - - uint8_t value[] = "The value.......end"; - struct ldb_val val = { - .data = value, - .length = (sizeof(value)) - }; - struct ldb_parse_tree *tree = ldb_parse_tree(ctx, "objectClass=*end"); - assert_non_null(tree); - - ldb_wildcard_compare(ctx->ldb, tree, val, &matched); - assert_true(matched); -} - - -/* - * ldb_handler_copy and ldb_val_dup over allocate by one and add a trailing '\0' - * to the data, to make them safe to use the C string functions on. - * - * However testing for the trailing '\0' is not the correct way to test for - * the end of a value, the length should be checked instead. - */ -static void test_wildcard_match_end_condition(void **state) -{ - struct ldbtest_ctx *ctx = *state; - bool matched = false; - - uint8_t value[] = "hellomynameisbobx"; - struct ldb_val val = { - .data = talloc_memdup(NULL, value, sizeof(value)), - .length = (sizeof(value) - 2) - }; - struct ldb_parse_tree *tree = ldb_parse_tree(ctx, "a=*hello*mynameis*bob"); - assert_non_null(tree); - - ldb_wildcard_compare(ctx->ldb, tree, val, &matched); - assert_true(matched); -} - -/* - * Note: to run under valgrind use: - * valgrind \ - * --suppressions=lib/ldb/tests/ldb_match_test.valgrind \ - * bin/ldb_match_test - */ -int main(int argc, const char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown( - test_wildcard_match_star, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_wildcard_match, - setup, - teardown), - cmocka_unit_test_setup_teardown( - test_wildcard_match_end_condition, - setup, - teardown), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/ldb-2.0.8/tests/ldb_match_test.valgrind b/ldb-2.0.8/tests/ldb_match_test.valgrind deleted file mode 100644 index 660bd5a..0000000 --- a/ldb-2.0.8/tests/ldb_match_test.valgrind +++ /dev/null @@ -1,16 +0,0 @@ -{ - Memory allocated in set-up - Memcheck:Leak - match-leak-kinds: possible - fun:malloc - ... - fun:setup -} -{ - Memory allocated by ldb_init - Memcheck:Leak - match-leak-kinds: possible - fun:malloc - ... - fun:ldb_init -} diff --git a/ldb-2.0.8/tests/ldb_mod_op_test.c b/ldb-2.0.8/tests/ldb_mod_op_test.c deleted file mode 100644 index b6a0d1e..0000000 --- a/ldb-2.0.8/tests/ldb_mod_op_test.c +++ /dev/null @@ -1,4721 +0,0 @@ -/* - * from cmocka.c: - * These headers or their equivalents should be included prior to - * including - * this header file. - * - * #include - * #include - * #include - * - * This allows test applications to use custom definitions of C standard - * library functions and types. - */ -#include -#include -#include -#include -#include - -#include -#include -#include - -#define TEVENT_DEPRECATED 1 -#include - -#include -#include -#include -#include -#include - -#include - - -#define DEFAULT_BE "tdb" - -#ifndef TEST_BE -#define TEST_BE DEFAULT_BE -#endif /* TEST_BE */ - -#ifdef TEST_LMDB -#include "lmdb.h" -#include "../ldb_tdb/ldb_tdb.h" -#include "../ldb_mdb/ldb_mdb.h" -#endif - -struct ldbtest_ctx { - struct tevent_context *ev; - struct ldb_context *ldb; - - const char *dbfile; - const char *lockfile; /* lockfile is separate */ - - const char *dbpath; -}; - -static void unlink_old_db(struct ldbtest_ctx *test_ctx) -{ - int ret; - - errno = 0; - ret = unlink(test_ctx->lockfile); - if (ret == -1 && errno != ENOENT) { - fail(); - } - - errno = 0; - ret = unlink(test_ctx->dbfile); - if (ret == -1 && errno != ENOENT) { - fail(); - } -} - -static int ldbtest_noconn_setup(void **state) -{ - struct ldbtest_ctx *test_ctx; - - test_ctx = talloc_zero(NULL, struct ldbtest_ctx); - assert_non_null(test_ctx); - - test_ctx->ev = tevent_context_init(test_ctx); - assert_non_null(test_ctx->ev); - - test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev); - assert_non_null(test_ctx->ldb); - - test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb"); - assert_non_null(test_ctx->dbfile); - - test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock", - test_ctx->dbfile); - assert_non_null(test_ctx->lockfile); - - test_ctx->dbpath = talloc_asprintf(test_ctx, - TEST_BE"://%s", test_ctx->dbfile); - assert_non_null(test_ctx->dbpath); - - unlink_old_db(test_ctx); - *state = test_ctx; - return 0; -} - -static int ldbtest_noconn_teardown(void **state) -{ - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - - unlink_old_db(test_ctx); - talloc_free(test_ctx); - return 0; -} - -static void test_connect(void **state) -{ - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - int ret; - - ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL); - assert_int_equal(ret, 0); -} - -static struct ldb_message *get_test_ldb_message(TALLOC_CTX *mem_ctx, - struct ldb_context *ldb) -{ - struct ldb_message *msg = ldb_msg_new(mem_ctx); - int ret; - assert_non_null(msg); - - msg->dn = ldb_dn_new(msg, ldb, "dc=samba,dc=org"); - assert_non_null(msg->dn); - ret = ldb_msg_add_string(msg, "public", "key"); - assert_int_equal(ret, LDB_SUCCESS); - ret = ldb_msg_add_string(msg, "supersecret", "password"); - assert_int_equal(ret, LDB_SUCCESS); - ret = ldb_msg_add_string(msg, "binary", "\xff\xff\0"); - assert_int_equal(ret, LDB_SUCCESS); - return msg; -} - -static void test_ldif_message(void **state) -{ - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - char *got_ldif; - const char *expected_ldif = - "dn: dc=samba,dc=org\n" - "changetype: add\n" - "public: key\n" - "supersecret: password\n" - "binary:: //8=\n" - "\n"; - - struct ldb_message *msg = get_test_ldb_message(test_ctx, - test_ctx->ldb); - - got_ldif = ldb_ldif_message_string(test_ctx->ldb, - test_ctx, - LDB_CHANGETYPE_ADD, - msg); - assert_string_equal(got_ldif, expected_ldif); - TALLOC_FREE(got_ldif); -} - -static void test_ldif_message_redacted(void **state) -{ - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - int ret; - char *got_ldif; - const char *expected_ldif = - "dn: dc=samba,dc=org\n" - "changetype: add\n" - "public: key\n" - "# supersecret::: REDACTED SECRET ATTRIBUTE\n" - "binary:: //8=\n" - "\n"; - - const char *secret_attrs[] = { - "supersecret", - NULL - }; - - struct ldb_message *msg = ldb_msg_new(test_ctx); - - ldb_set_opaque(test_ctx->ldb, - LDB_SECRET_ATTRIBUTE_LIST_OPAQUE, - secret_attrs); - - assert_non_null(msg); - - msg->dn = ldb_dn_new(msg, test_ctx->ldb, "dc=samba,dc=org"); - ret = ldb_msg_add_string(msg, "public", "key"); - assert_int_equal(ret, LDB_SUCCESS); - ret = ldb_msg_add_string(msg, "supersecret", "password"); - assert_int_equal(ret, LDB_SUCCESS); - ret = ldb_msg_add_string(msg, "binary", "\xff\xff\0"); - assert_int_equal(ret, LDB_SUCCESS); - got_ldif = ldb_ldif_message_redacted_string(test_ctx->ldb, - test_ctx, - LDB_CHANGETYPE_ADD, - msg); - assert_string_equal(got_ldif, expected_ldif); - TALLOC_FREE(got_ldif); - assert_int_equal(ret, 0); -} - -static int ldbtest_setup(void **state) -{ - struct ldbtest_ctx *test_ctx; - struct ldb_ldif *ldif; -#ifdef GUID_IDX - const char *index_ldif = \ - "dn: @INDEXLIST\n" - "@IDXGUID: objectUUID\n" - "@IDX_DN_GUID: GUID\n" - "\n"; -#else - const char *index_ldif = "\n"; -#endif - int ret; - - ldbtest_noconn_setup((void **) &test_ctx); - - ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL); - assert_int_equal(ret, 0); - - while ((ldif = ldb_ldif_read_string(test_ctx->ldb, &index_ldif))) { - ret = ldb_add(test_ctx->ldb, ldif->msg); - assert_int_equal(ret, LDB_SUCCESS); - } - *state = test_ctx; - return 0; -} - -static int ldbtest_teardown(void **state) -{ - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - ldbtest_noconn_teardown((void **) &test_ctx); - return 0; -} - -static void test_ldb_add(void **state) -{ - int ret; - struct ldb_message *msg; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - msg = ldb_msg_new(tmp_ctx); - assert_non_null(msg); - - msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test"); - assert_non_null(msg->dn); - - ret = ldb_msg_add_string(msg, "cn", "test_cn_val"); - assert_int_equal(ret, 0); - - ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcdef"); - assert_int_equal(ret, 0); - - ret = ldb_add(test_ctx->ldb, msg); - assert_int_equal(ret, 0); - - talloc_free(tmp_ctx); -} - -static void test_ldb_search(void **state) -{ - int ret; - struct ldb_message *msg; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - TALLOC_CTX *tmp_ctx; - struct ldb_dn *basedn; - struct ldb_dn *basedn2; - struct ldb_result *result = NULL; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test"); - assert_non_null(basedn); - - ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn, - LDB_SCOPE_BASE, NULL, NULL); - assert_int_equal(ret, 0); - assert_non_null(result); - assert_int_equal(result->count, 0); - - msg = ldb_msg_new(tmp_ctx); - assert_non_null(msg); - - msg->dn = basedn; - assert_non_null(msg->dn); - - ret = ldb_msg_add_string(msg, "cn", "test_cn_val1"); - assert_int_equal(ret, 0); - - ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcde1"); - assert_int_equal(ret, 0); - - ret = ldb_add(test_ctx->ldb, msg); - assert_int_equal(ret, 0); - - basedn2 = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test2"); - assert_non_null(basedn2); - - msg = ldb_msg_new(tmp_ctx); - assert_non_null(msg); - - msg->dn = basedn2; - assert_non_null(msg->dn); - - ret = ldb_msg_add_string(msg, "cn", "test_cn_val2"); - assert_int_equal(ret, 0); - - ret = ldb_msg_add_string(msg, "objectUUID", "0123456789abcde2"); - assert_int_equal(ret, 0); - - ret = ldb_add(test_ctx->ldb, msg); - assert_int_equal(ret, 0); - - ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn, - LDB_SCOPE_BASE, NULL, NULL); - assert_int_equal(ret, 0); - assert_non_null(result); - assert_int_equal(result->count, 1); - assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn), - ldb_dn_get_linearized(basedn)); - - ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn2, - LDB_SCOPE_BASE, NULL, NULL); - assert_int_equal(ret, 0); - assert_non_null(result); - assert_int_equal(result->count, 1); - assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn), - ldb_dn_get_linearized(basedn2)); - - talloc_free(tmp_ctx); -} - -static int base_search_count(struct ldbtest_ctx *test_ctx, const char *entry_dn) -{ - TALLOC_CTX *tmp_ctx; - struct ldb_dn *basedn; - struct ldb_result *result = NULL; - int ret; - int count; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", entry_dn); - assert_non_null(basedn); - - ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn, - LDB_SCOPE_BASE, NULL, NULL); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(result); - - count = result->count; - talloc_free(tmp_ctx); - return count; -} - -static int sub_search_count(struct ldbtest_ctx *test_ctx, - const char *base_dn, - const char *filter) -{ - TALLOC_CTX *tmp_ctx; - struct ldb_dn *basedn; - struct ldb_result *result = NULL; - int ret; - int count; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "%s", base_dn); - assert_non_null(basedn); - - ret = ldb_search(test_ctx->ldb, tmp_ctx, &result, basedn, - LDB_SCOPE_SUBTREE, NULL, "%s", filter); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(result); - - count = result->count; - talloc_free(tmp_ctx); - return count; -} - -/* In general it would be better if utility test functions didn't assert - * but only returned a value, then assert in the test shows correct - * line - */ -static void assert_dn_exists(struct ldbtest_ctx *test_ctx, - const char *entry_dn) -{ - int count; - - count = base_search_count(test_ctx, entry_dn); - assert_int_equal(count, 1); -} - -static void assert_dn_doesnt_exist(struct ldbtest_ctx *test_ctx, - const char *entry_dn) -{ - int count; - - count = base_search_count(test_ctx, entry_dn); - assert_int_equal(count, 0); -} - -static void add_dn_with_cn(struct ldbtest_ctx *test_ctx, - struct ldb_dn *dn, - const char *cn_value, - const char *uuid_value) -{ - int ret; - TALLOC_CTX *tmp_ctx; - struct ldb_message *msg; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - assert_dn_doesnt_exist(test_ctx, - ldb_dn_get_linearized(dn)); - - msg = ldb_msg_new(tmp_ctx); - assert_non_null(msg); - msg->dn = dn; - - ret = ldb_msg_add_string(msg, "cn", cn_value); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_msg_add_string(msg, "objectUUID", uuid_value); - assert_int_equal(ret, 0); - - ret = ldb_add(test_ctx->ldb, msg); - assert_int_equal(ret, LDB_SUCCESS); - - assert_dn_exists(test_ctx, - ldb_dn_get_linearized(dn)); - talloc_free(tmp_ctx); -} - -static void test_ldb_del(void **state) -{ - int ret; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - const char *basedn = "dc=ldb_del_test"; - struct ldb_dn *dn; - - dn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s", basedn); - assert_non_null(dn); - - add_dn_with_cn(test_ctx, dn, - "test_del_cn_val", - "0123456789abcdef"); - - ret = ldb_delete(test_ctx->ldb, dn); - assert_int_equal(ret, LDB_SUCCESS); - - assert_dn_doesnt_exist(test_ctx, basedn); -} - -static void test_ldb_del_noexist(void **state) -{ - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - struct ldb_dn *basedn; - int ret; - - basedn = ldb_dn_new(test_ctx, test_ctx->ldb, "dc=nosuchplace"); - assert_non_null(basedn); - - ret = ldb_delete(test_ctx->ldb, basedn); - assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT); -} - -static void test_ldb_handle(void **state) -{ - int ret; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - TALLOC_CTX *tmp_ctx; - struct ldb_dn *basedn; - struct ldb_request *request = NULL; - struct ldb_request *request2 = NULL; - struct ldb_result *res = NULL; - const char *attrs[] = { "cn", NULL }; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test"); - assert_non_null(basedn); - - res = talloc_zero(tmp_ctx, struct ldb_result); - assert_non_null(res); - - ret = ldb_build_search_req(&request, test_ctx->ldb, tmp_ctx, - basedn, LDB_SCOPE_BASE, - NULL, attrs, NULL, res, - ldb_search_default_callback, - NULL); - assert_int_equal(ret, 0); - - /* We are against ldb_tdb, so expect private event contexts */ - assert_ptr_not_equal(ldb_handle_get_event_context(request->handle), - ldb_get_event_context(test_ctx->ldb)); - - ret = ldb_build_search_req(&request2, test_ctx->ldb, tmp_ctx, - basedn, LDB_SCOPE_BASE, - NULL, attrs, NULL, res, - ldb_search_default_callback, - request); - assert_int_equal(ret, 0); - - /* Expect that same event context will be chained */ - assert_ptr_equal(ldb_handle_get_event_context(request->handle), - ldb_handle_get_event_context(request2->handle)); - - /* Now force this to use the global context */ - ldb_handle_use_global_event_context(request2->handle); - assert_ptr_equal(ldb_handle_get_event_context(request2->handle), - ldb_get_event_context(test_ctx->ldb)); - - talloc_free(tmp_ctx); -} - -static void test_ldb_build_search_req(void **state) -{ - int ret; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - TALLOC_CTX *tmp_ctx; - struct ldb_dn *basedn; - struct ldb_request *request = NULL; - struct ldb_request *request2 = NULL; - struct ldb_result *res = NULL; - const char *attrs[] = { "cn", NULL }; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - basedn = ldb_dn_new_fmt(tmp_ctx, test_ctx->ldb, "dc=test"); - assert_non_null(basedn); - - res = talloc_zero(tmp_ctx, struct ldb_result); - assert_non_null(res); - - ret = ldb_build_search_req(&request, test_ctx->ldb, tmp_ctx, - basedn, LDB_SCOPE_BASE, - NULL, attrs, NULL, res, - ldb_search_default_callback, - NULL); - assert_int_equal(ret, 0); - - assert_int_equal(request->operation, LDB_SEARCH); - assert_ptr_equal(request->op.search.base, basedn); - assert_int_equal(request->op.search.scope, LDB_SCOPE_BASE); - assert_non_null(request->op.search.tree); - assert_ptr_equal(request->op.search.attrs, attrs); - assert_ptr_equal(request->context, res); - assert_ptr_equal(request->callback, ldb_search_default_callback); - - ret = ldb_build_search_req(&request2, test_ctx->ldb, tmp_ctx, - basedn, LDB_SCOPE_BASE, - NULL, attrs, NULL, res, - ldb_search_default_callback, - request); - assert_int_equal(ret, 0); - assert_ptr_equal(request, request2->handle->parent); - assert_int_equal(request->starttime, request2->starttime); - assert_int_equal(request->timeout, request2->timeout); - - talloc_free(tmp_ctx); -} - -static void add_keyval(struct ldbtest_ctx *test_ctx, - const char *key, - const char *val, - const char *uuid) -{ - int ret; - struct ldb_message *msg; - - msg = ldb_msg_new(test_ctx); - assert_non_null(msg); - - msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s=%s", key, val); - assert_non_null(msg->dn); - - ret = ldb_msg_add_string(msg, key, val); - assert_int_equal(ret, 0); - - ret = ldb_msg_add_string(msg, "objectUUID", uuid); - assert_int_equal(ret, 0); - - ret = ldb_add(test_ctx->ldb, msg); - assert_int_equal(ret, 0); - - talloc_free(msg); -} - -static struct ldb_result *get_keyval(struct ldbtest_ctx *test_ctx, - const char *key, - const char *val) -{ - int ret; - struct ldb_result *result; - struct ldb_dn *basedn; - - basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "%s=%s", key, val); - assert_non_null(basedn); - - ret = ldb_search(test_ctx->ldb, test_ctx, &result, basedn, - LDB_SCOPE_BASE, NULL, NULL); - assert_int_equal(ret, 0); - - return result; -} - -static void test_transactions(void **state) -{ - int ret; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - struct ldb_result *res; - - /* start lev-0 transaction */ - ret = ldb_transaction_start(test_ctx->ldb); - assert_int_equal(ret, 0); - - add_keyval(test_ctx, "vegetable", "carrot", - "0123456789abcde0"); - - /* commit lev-0 transaction */ - ret = ldb_transaction_commit(test_ctx->ldb); - assert_int_equal(ret, 0); - - /* start another lev-1 nested transaction */ - ret = ldb_transaction_start(test_ctx->ldb); - assert_int_equal(ret, 0); - - add_keyval(test_ctx, "fruit", "apple", - "0123456789abcde1"); - - /* abort lev-1 nested transaction */ - ret = ldb_transaction_cancel(test_ctx->ldb); - assert_int_equal(ret, 0); - - res = get_keyval(test_ctx, "vegetable", "carrot"); - assert_non_null(res); - assert_int_equal(res->count, 1); - - res = get_keyval(test_ctx, "fruit", "apple"); - assert_non_null(res); - assert_int_equal(res->count, 0); -} - -static void test_nested_transactions(void **state) -{ - int ret; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - struct ldb_result *res; - - /* start lev-0 transaction */ - ret = ldb_transaction_start(test_ctx->ldb); - assert_int_equal(ret, 0); - - add_keyval(test_ctx, "vegetable", "carrot", - "0123456789abcde0"); - - - /* start another lev-1 nested transaction */ - ret = ldb_transaction_start(test_ctx->ldb); - assert_int_equal(ret, 0); - - add_keyval(test_ctx, "fruit", "apple", - "0123456789abcde1"); - - /* abort lev-1 nested transaction */ - ret = ldb_transaction_cancel(test_ctx->ldb); - assert_int_equal(ret, 0); - - /* commit lev-0 transaction */ - ret = ldb_transaction_commit(test_ctx->ldb); - assert_int_equal(ret, 0); - - res = get_keyval(test_ctx, "vegetable", "carrot"); - assert_non_null(res); - assert_int_equal(res->count, 1); - - /* This documents the current ldb behaviour, i.e. nested - * transactions are not supported. And the cancellation of the nested - * transaction has no effect. - */ - res = get_keyval(test_ctx, "fruit", "apple"); - assert_non_null(res); - assert_int_equal(res->count, 1); -} -struct ldb_mod_test_ctx { - struct ldbtest_ctx *ldb_test_ctx; - const char *entry_dn; -}; - -struct keyval { - const char *key; - const char *val; -}; - -static struct ldb_message *build_mod_msg(TALLOC_CTX *mem_ctx, - struct ldbtest_ctx *test_ctx, - const char *dn, - int modify_flags, - struct keyval *kvs) -{ - struct ldb_message *msg; - int ret; - int i; - - msg = ldb_msg_new(mem_ctx); - assert_non_null(msg); - - msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "%s", dn); - assert_non_null(msg->dn); - - for (i = 0; kvs[i].key != NULL; i++) { - if (modify_flags) { - ret = ldb_msg_add_empty(msg, kvs[i].key, - modify_flags, NULL); - assert_int_equal(ret, 0); - } - - if (kvs[i].val) { - ret = ldb_msg_add_string(msg, kvs[i].key, kvs[i].val); - assert_int_equal(ret, LDB_SUCCESS); - } - } - - return msg; -} - -static void ldb_test_add_data(TALLOC_CTX *mem_ctx, - struct ldbtest_ctx *ldb_test_ctx, - const char *basedn, - struct keyval *kvs) -{ - TALLOC_CTX *tmp_ctx; - struct ldb_message *msg; - struct ldb_result *result = NULL; - int ret; - - tmp_ctx = talloc_new(mem_ctx); - assert_non_null(tmp_ctx); - - msg = build_mod_msg(tmp_ctx, ldb_test_ctx, - basedn, 0, kvs); - assert_non_null(msg); - - ret = ldb_add(ldb_test_ctx->ldb, msg); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_search(ldb_test_ctx->ldb, tmp_ctx, &result, msg->dn, - LDB_SCOPE_BASE, NULL, NULL); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(result); - assert_int_equal(result->count, 1); - assert_string_equal(ldb_dn_get_linearized(result->msgs[0]->dn), - ldb_dn_get_linearized(msg->dn)); - - talloc_free(tmp_ctx); -} - -static void ldb_test_remove_data(TALLOC_CTX *mem_ctx, - struct ldbtest_ctx *ldb_test_ctx, - const char *strdn) -{ - TALLOC_CTX *tmp_ctx; - struct ldb_dn *basedn; - int ret; - size_t count; - - tmp_ctx = talloc_new(mem_ctx); - assert_non_null(tmp_ctx); - - basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb, - "%s", strdn); - assert_non_null(basedn); - - ret = ldb_delete(ldb_test_ctx->ldb, basedn); - assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_NO_SUCH_OBJECT); - - count = base_search_count(ldb_test_ctx, ldb_dn_get_linearized(basedn)); - assert_int_equal(count, 0); - - talloc_free(tmp_ctx); -} - -static void mod_test_add_data(struct ldb_mod_test_ctx *mod_test_ctx, - struct keyval *kvs) -{ - ldb_test_add_data(mod_test_ctx, - mod_test_ctx->ldb_test_ctx, - mod_test_ctx->entry_dn, - kvs); -} - -static void mod_test_remove_data(struct ldb_mod_test_ctx *mod_test_ctx) -{ - ldb_test_remove_data(mod_test_ctx, - mod_test_ctx->ldb_test_ctx, - mod_test_ctx->entry_dn); -} - -static struct ldb_result *run_mod_test(struct ldb_mod_test_ctx *mod_test_ctx, - int modify_flags, - struct keyval *kvs) -{ - TALLOC_CTX *tmp_ctx; - struct ldb_result *res; - struct ldb_message *mod_msg; - struct ldb_dn *basedn; - struct ldbtest_ctx *ldb_test_ctx; - int ret; - - ldb_test_ctx = mod_test_ctx->ldb_test_ctx; - - tmp_ctx = talloc_new(mod_test_ctx); - assert_non_null(tmp_ctx); - - mod_msg = build_mod_msg(tmp_ctx, ldb_test_ctx, mod_test_ctx->entry_dn, - modify_flags, kvs); - assert_non_null(mod_msg); - - ret = ldb_modify(ldb_test_ctx->ldb, mod_msg); - assert_int_equal(ret, LDB_SUCCESS); - - basedn = ldb_dn_new_fmt(tmp_ctx, ldb_test_ctx->ldb, - "%s", mod_test_ctx->entry_dn); - assert_non_null(basedn); - - ret = ldb_search(ldb_test_ctx->ldb, mod_test_ctx, &res, basedn, - LDB_SCOPE_BASE, NULL, NULL); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(res); - assert_int_equal(res->count, 1); - assert_string_equal(ldb_dn_get_linearized(res->msgs[0]->dn), - ldb_dn_get_linearized(mod_msg->dn)); - - talloc_free(tmp_ctx); - return res; -} - -static int ldb_modify_test_setup(void **state) -{ - struct ldbtest_ctx *ldb_test_ctx; - struct ldb_mod_test_ctx *mod_test_ctx; - struct keyval kvs[] = { - { "cn", "test_mod_cn" }, - { "objectUUID", "0123456789abcdef"}, - { NULL, NULL }, - }; - - ldbtest_setup((void **) &ldb_test_ctx); - - mod_test_ctx = talloc(ldb_test_ctx, struct ldb_mod_test_ctx); - assert_non_null(mod_test_ctx); - - mod_test_ctx->entry_dn = "dc=mod_test_entry"; - mod_test_ctx->ldb_test_ctx = ldb_test_ctx; - - mod_test_remove_data(mod_test_ctx); - mod_test_add_data(mod_test_ctx, kvs); - *state = mod_test_ctx; - return 0; -} - -static int ldb_modify_test_teardown(void **state) -{ - struct ldb_mod_test_ctx *mod_test_ctx = \ - talloc_get_type_abort(*state, - struct ldb_mod_test_ctx); - struct ldbtest_ctx *ldb_test_ctx; - - ldb_test_ctx = mod_test_ctx->ldb_test_ctx; - - mod_test_remove_data(mod_test_ctx); - talloc_free(mod_test_ctx); - - ldbtest_teardown((void **) &ldb_test_ctx); - return 0; -} - -static void test_ldb_modify_add_key(void **state) -{ - struct ldb_mod_test_ctx *mod_test_ctx = \ - talloc_get_type_abort(*state, - struct ldb_mod_test_ctx); - struct keyval mod_kvs[] = { - { "name", "test_mod_name" }, - { NULL, NULL }, - }; - struct ldb_result *res; - struct ldb_message_element *el; - - res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs); - assert_non_null(res); - - /* Check cn is intact and name was added */ - assert_int_equal(res->count, 1); - el = ldb_msg_find_element(res->msgs[0], "cn"); - assert_non_null(el); - assert_int_equal(el->num_values, 1); - assert_string_equal(el->values[0].data, "test_mod_cn"); - - el = ldb_msg_find_element(res->msgs[0], "name"); - assert_non_null(el); - assert_int_equal(el->num_values, 1); - assert_string_equal(el->values[0].data, "test_mod_name"); -} - -static void test_ldb_modify_extend_key(void **state) -{ - struct ldb_mod_test_ctx *mod_test_ctx = \ - talloc_get_type_abort(*state, - struct ldb_mod_test_ctx); - struct keyval mod_kvs[] = { - { "cn", "test_mod_cn2" }, - { NULL, NULL }, - }; - struct ldb_result *res; - struct ldb_message_element *el; - - res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_ADD, mod_kvs); - assert_non_null(res); - - /* Check cn was extended with another value */ - assert_int_equal(res->count, 1); - el = ldb_msg_find_element(res->msgs[0], "cn"); - assert_non_null(el); - assert_int_equal(el->num_values, 2); - assert_string_equal(el->values[0].data, "test_mod_cn"); - assert_string_equal(el->values[1].data, "test_mod_cn2"); -} - -static void test_ldb_modify_add_key_noval(void **state) -{ - struct ldb_mod_test_ctx *mod_test_ctx = \ - talloc_get_type_abort(*state, - struct ldb_mod_test_ctx); - struct ldb_message *mod_msg; - struct ldbtest_ctx *ldb_test_ctx; - struct ldb_message_element *el; - int ret; - - ldb_test_ctx = mod_test_ctx->ldb_test_ctx; - - mod_msg = ldb_msg_new(mod_test_ctx); - assert_non_null(mod_msg); - - mod_msg->dn = ldb_dn_new_fmt(mod_msg, ldb_test_ctx->ldb, - "%s", mod_test_ctx->entry_dn); - assert_non_null(mod_msg->dn); - - el = talloc_zero(mod_msg, struct ldb_message_element); - el->flags = LDB_FLAG_MOD_ADD; - assert_non_null(el); - el->name = talloc_strdup(el, "cn"); - assert_non_null(el->name); - - mod_msg->elements = el; - mod_msg->num_elements = 1; - - ret = ldb_modify(ldb_test_ctx->ldb, mod_msg); - assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION); -} - -static void test_ldb_modify_replace_key(void **state) -{ - struct ldb_mod_test_ctx *mod_test_ctx = \ - talloc_get_type_abort(*state, - struct ldb_mod_test_ctx); - const char *new_cn = "new_cn"; - struct keyval mod_kvs[] = { - { "cn", new_cn }, - { NULL, NULL }, - }; - struct ldb_result *res; - struct ldb_message_element *el; - - res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs); - assert_non_null(res); - - /* Check cn was replaced */ - assert_int_equal(res->count, 1); - el = ldb_msg_find_element(res->msgs[0], "cn"); - assert_non_null(el); - assert_int_equal(el->num_values, 1); - assert_string_equal(el->values[0].data, new_cn); -} - -static void test_ldb_modify_replace_noexist_key(void **state) -{ - struct ldb_mod_test_ctx *mod_test_ctx = \ - talloc_get_type_abort(*state, - struct ldb_mod_test_ctx); - struct keyval mod_kvs[] = { - { "name", "name_val" }, - { NULL, NULL }, - }; - struct ldb_result *res; - struct ldb_message_element *el; - - res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, mod_kvs); - assert_non_null(res); - - /* Check cn is intact and name was added */ - assert_int_equal(res->count, 1); - el = ldb_msg_find_element(res->msgs[0], "cn"); - assert_non_null(el); - assert_int_equal(el->num_values, 1); - assert_string_equal(el->values[0].data, "test_mod_cn"); - - el = ldb_msg_find_element(res->msgs[0], mod_kvs[0].key); - assert_non_null(el); - assert_int_equal(el->num_values, 1); - assert_string_equal(el->values[0].data, mod_kvs[0].val); -} - -static void test_ldb_modify_replace_zero_vals(void **state) -{ - struct ldb_mod_test_ctx *mod_test_ctx = \ - talloc_get_type_abort(*state, - struct ldb_mod_test_ctx); - struct ldb_message_element *el; - struct ldb_result *res; - struct keyval kvs[] = { - { "cn", NULL }, - { NULL, NULL }, - }; - - /* cn must be gone */ - res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs); - assert_non_null(res); - el = ldb_msg_find_element(res->msgs[0], "cn"); - assert_null(el); -} - -static void test_ldb_modify_replace_noexist_key_zero_vals(void **state) -{ - struct ldb_mod_test_ctx *mod_test_ctx = \ - talloc_get_type_abort(*state, - struct ldb_mod_test_ctx); - struct ldb_message_element *el; - struct ldb_result *res; - struct keyval kvs[] = { - { "noexist_key", NULL }, - { NULL, NULL }, - }; - - /* cn must be gone */ - res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_REPLACE, kvs); - assert_non_null(res); - - /* cn should be intact */ - el = ldb_msg_find_element(res->msgs[0], "cn"); - assert_non_null(el); -} - -static void test_ldb_modify_del_key(void **state) -{ - struct ldb_mod_test_ctx *mod_test_ctx = \ - talloc_get_type_abort(*state, - struct ldb_mod_test_ctx); - struct ldb_message_element *el; - struct ldb_result *res; - struct keyval kvs[] = { - { "cn", NULL }, - { NULL, NULL }, - }; - - /* cn must be gone */ - res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs); - assert_non_null(res); - - el = ldb_msg_find_element(res->msgs[0], "cn"); - assert_null(el); -} - -static void test_ldb_modify_del_keyval(void **state) -{ - struct ldb_mod_test_ctx *mod_test_ctx = \ - talloc_get_type_abort(*state, - struct ldb_mod_test_ctx); - struct ldb_message_element *el; - struct ldb_result *res; - struct keyval kvs[] = { - { "cn", "test_mod_cn" }, - { NULL, NULL }, - }; - - /* cn must be gone */ - res = run_mod_test(mod_test_ctx, LDB_FLAG_MOD_DELETE, kvs); - assert_non_null(res); - - el = ldb_msg_find_element(res->msgs[0], "cn"); - assert_null(el); -} - -struct search_test_ctx { - struct ldbtest_ctx *ldb_test_ctx; - const char *base_dn; -}; - -static char *get_full_dn(TALLOC_CTX *mem_ctx, - struct search_test_ctx *search_test_ctx, - const char *rdn) -{ - char *full_dn; - - full_dn = talloc_asprintf(mem_ctx, - "%s,%s", rdn, search_test_ctx->base_dn); - assert_non_null(full_dn); - - return full_dn; -} - -static void search_test_add_data(struct search_test_ctx *search_test_ctx, - const char *rdn, - struct keyval *kvs) -{ - char *full_dn; - - full_dn = get_full_dn(search_test_ctx, search_test_ctx, rdn); - - ldb_test_add_data(search_test_ctx, - search_test_ctx->ldb_test_ctx, - full_dn, - kvs); -} - -static void search_test_remove_data(struct search_test_ctx *search_test_ctx, - const char *rdn) -{ - char *full_dn; - - full_dn = talloc_asprintf(search_test_ctx, - "%s,%s", rdn, search_test_ctx->base_dn); - assert_non_null(full_dn); - - ldb_test_remove_data(search_test_ctx, - search_test_ctx->ldb_test_ctx, - full_dn); -} - -static int ldb_search_test_setup(void **state) -{ - struct ldbtest_ctx *ldb_test_ctx; - struct search_test_ctx *search_test_ctx; - struct keyval kvs[] = { - { "cn", "test_search_cn" }, - { "cn", "test_search_cn2" }, - { "uid", "test_search_uid" }, - { "uid", "test_search_uid2" }, - { "objectUUID", "0123456789abcde0"}, - { NULL, NULL }, - }; - struct keyval kvs2[] = { - { "cn", "test_search_2_cn" }, - { "cn", "test_search_2_cn2" }, - { "uid", "test_search_2_uid" }, - { "uid", "test_search_2_uid2" }, - { "objectUUID", "0123456789abcde1"}, - { NULL, NULL }, - }; - - ldbtest_setup((void **) &ldb_test_ctx); - - search_test_ctx = talloc(ldb_test_ctx, struct search_test_ctx); - assert_non_null(search_test_ctx); - - search_test_ctx->base_dn = "dc=search_test_entry"; - search_test_ctx->ldb_test_ctx = ldb_test_ctx; - - search_test_remove_data(search_test_ctx, "cn=test_search_cn"); - search_test_add_data(search_test_ctx, "cn=test_search_cn", kvs); - - search_test_remove_data(search_test_ctx, "cn=test_search_2_cn"); - search_test_add_data(search_test_ctx, "cn=test_search_2_cn", kvs2); - - *state = search_test_ctx; - return 0; -} - -static int ldb_search_test_teardown(void **state) -{ - struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, - struct search_test_ctx); - struct ldbtest_ctx *ldb_test_ctx; - - ldb_test_ctx = search_test_ctx->ldb_test_ctx; - - search_test_remove_data(search_test_ctx, "cn=test_search_cn"); - search_test_remove_data(search_test_ctx, "cn=test_search_2_cn"); - ldbtest_teardown((void **) &ldb_test_ctx); - return 0; -} - -static void assert_attr_has_vals(struct ldb_message *msg, - const char *attr, - const char *vals[], - const size_t nvals) -{ - struct ldb_message_element *el; - size_t i; - - el = ldb_msg_find_element(msg, attr); - assert_non_null(el); - - assert_int_equal(el->num_values, nvals); - for (i = 0; i < nvals; i++) { - assert_string_equal(el->values[i].data, - vals[i]); - } -} - -static void assert_has_no_attr(struct ldb_message *msg, - const char *attr) -{ - struct ldb_message_element *el; - - el = ldb_msg_find_element(msg, attr); - assert_null(el); -} - -static bool has_dn(struct ldb_message *msg, const char *dn) -{ - const char *msgdn; - - msgdn = ldb_dn_get_linearized(msg->dn); - if (strcmp(dn, msgdn) == 0) { - return true; - } - - return false; -} - -static void test_search_match_none(void **state) -{ - struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, - struct search_test_ctx); - size_t count; - - count = base_search_count(search_test_ctx->ldb_test_ctx, - "dc=no_such_entry"); - assert_int_equal(count, 0); -} - -static void test_search_match_one(void **state) -{ - struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, - struct search_test_ctx); - int ret; - struct ldb_dn *basedn; - struct ldb_result *result = NULL; - const char *cn_vals[] = { "test_search_cn", - "test_search_cn2" }; - const char *uid_vals[] = { "test_search_uid", - "test_search_uid2" }; - - basedn = ldb_dn_new_fmt(search_test_ctx, - search_test_ctx->ldb_test_ctx->ldb, - "%s", - search_test_ctx->base_dn); - assert_non_null(basedn); - - ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, - search_test_ctx, - &result, - basedn, - LDB_SCOPE_SUBTREE, NULL, - "cn=test_search_cn"); - assert_int_equal(ret, 0); - assert_non_null(result); - assert_int_equal(result->count, 1); - - assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2); - assert_attr_has_vals(result->msgs[0], "uid", uid_vals, 2); -} - -static void test_search_match_filter(void **state) -{ - struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, - struct search_test_ctx); - int ret; - struct ldb_dn *basedn; - struct ldb_result *result = NULL; - const char *cn_vals[] = { "test_search_cn", - "test_search_cn2" }; - const char *attrs[] = { "cn", NULL }; - - basedn = ldb_dn_new_fmt(search_test_ctx, - search_test_ctx->ldb_test_ctx->ldb, - "%s", - search_test_ctx->base_dn); - assert_non_null(basedn); - - ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, - search_test_ctx, - &result, - basedn, - LDB_SCOPE_SUBTREE, - attrs, - "cn=test_search_cn"); - assert_int_equal(ret, 0); - assert_non_null(result); - assert_int_equal(result->count, 1); - - assert_attr_has_vals(result->msgs[0], "cn", cn_vals, 2); - assert_has_no_attr(result->msgs[0], "uid"); -} - -static void assert_expected(struct search_test_ctx *search_test_ctx, - struct ldb_message *msg) -{ - char *full_dn1; - char *full_dn2; - const char *cn_vals[] = { "test_search_cn", - "test_search_cn2" }; - const char *uid_vals[] = { "test_search_uid", - "test_search_uid2" }; - const char *cn2_vals[] = { "test_search_2_cn", - "test_search_2_cn2" }; - const char *uid2_vals[] = { "test_search_2_uid", - "test_search_2_uid2" }; - - full_dn1 = get_full_dn(search_test_ctx, - search_test_ctx, - "cn=test_search_cn"); - - full_dn2 = get_full_dn(search_test_ctx, - search_test_ctx, - "cn=test_search_2_cn"); - - if (has_dn(msg, full_dn1) == true) { - assert_attr_has_vals(msg, "cn", cn_vals, 2); - assert_attr_has_vals(msg, "uid", uid_vals, 2); - } else if (has_dn(msg, full_dn2) == true) { - assert_attr_has_vals(msg, "cn", cn2_vals, 2); - assert_attr_has_vals(msg, "uid", uid2_vals, 2); - } else { - fail(); - } -} - -static void test_search_match_both(void **state) -{ - struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, - struct search_test_ctx); - int ret; - struct ldb_dn *basedn; - struct ldb_result *result = NULL; - - basedn = ldb_dn_new_fmt(search_test_ctx, - search_test_ctx->ldb_test_ctx->ldb, - "%s", - search_test_ctx->base_dn); - assert_non_null(basedn); - - ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, - search_test_ctx, - &result, - basedn, - LDB_SCOPE_SUBTREE, NULL, - "cn=test_search_*"); - assert_int_equal(ret, 0); - assert_non_null(result); - assert_int_equal(result->count, 2); - - assert_expected(search_test_ctx, result->msgs[0]); - assert_expected(search_test_ctx, result->msgs[1]); -} - -static void test_search_match_basedn(void **state) -{ - struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, - struct search_test_ctx); - int ret; - struct ldb_dn *basedn; - struct ldb_result *result = NULL; - struct ldb_message *msg; - - basedn = ldb_dn_new_fmt(search_test_ctx, - search_test_ctx->ldb_test_ctx->ldb, - "dc=nosuchdn"); - assert_non_null(basedn); - - ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, - search_test_ctx, - &result, - basedn, - LDB_SCOPE_SUBTREE, NULL, - "cn=*"); - assert_int_equal(ret, 0); - - /* Add 'checkBaseOnSearch' to @OPTIONS */ - msg = ldb_msg_new(search_test_ctx); - assert_non_null(msg); - - msg->dn = ldb_dn_new_fmt(msg, - search_test_ctx->ldb_test_ctx->ldb, - "@OPTIONS"); - assert_non_null(msg->dn); - - ret = ldb_msg_add_string(msg, "checkBaseOnSearch", "TRUE"); - assert_int_equal(ret, 0); - - ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb, msg); - assert_int_equal(ret, 0); - - /* Search again */ - /* The search should return LDB_ERR_NO_SUCH_OBJECT */ - ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, - search_test_ctx, - &result, - basedn, - LDB_SCOPE_SUBTREE, NULL, - "cn=*"); - assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT); - - ret = ldb_delete(search_test_ctx->ldb_test_ctx->ldb, msg->dn); - assert_int_equal(ret, 0); -} - - -/* - * This test is complex. - * The purpose is to test for a deadlock detected between ldb_search() - * and ldb_transaction_commit(). The deadlock happens if in process - * (1) and (2): - * - (1) the all-record lock is taken in ltdb_search() - * - (2) the ldb_transaction_start() call is made - * - (1) an un-indexed search starts (forced here by doing it in - * the callback - * - (2) the ldb_transaction_commit() is called. - * This returns LDB_ERR_BUSY if the deadlock is detected - * - * With ldb 1.1.31 and tdb 1.3.12 we avoid this only due to a missing - * lock call in ltdb_search() due to a refcounting bug in - * ltdb_lock_read() - */ - -struct search_against_transaction_ctx { - struct ldbtest_ctx *test_ctx; - int res_count; - pid_t child_pid; - struct ldb_dn *basedn; -}; - -static int test_ldb_search_against_transaction_callback2(struct ldb_request *req, - struct ldb_reply *ares) -{ - struct search_against_transaction_ctx *ctx = req->context; - switch (ares->type) { - case LDB_REPLY_ENTRY: - ctx->res_count++; - if (ctx->res_count != 1) { - return LDB_SUCCESS; - } - - break; - - case LDB_REPLY_REFERRAL: - break; - - case LDB_REPLY_DONE: - return ldb_request_done(req, LDB_SUCCESS); - } - - return 0; - -} - -/* - * This purpose of this callback is to trigger a transaction in - * the child process while the all-record lock is held, but before - * we take any locks in the tdb_traverse_read() handler. - * - * In tdb 1.3.12 tdb_traverse_read() take the read transaction lock - * however in ldb 1.1.31 ltdb_search() forgets to take the all-record - * lock (except the very first time) due to a ref-counting bug. - * - */ - -static int test_ldb_search_against_transaction_callback1(struct ldb_request *req, - struct ldb_reply *ares) -{ - int ret, ret2; - int pipes[2]; - char buf[2]; - struct search_against_transaction_ctx *ctx = req->context; - switch (ares->type) { - case LDB_REPLY_ENTRY: - break; - - case LDB_REPLY_REFERRAL: - return LDB_SUCCESS; - - case LDB_REPLY_DONE: - return ldb_request_done(req, LDB_SUCCESS); - } - - ret = pipe(pipes); - assert_int_equal(ret, 0); - - ctx->child_pid = fork(); - if (ctx->child_pid == 0) { - TALLOC_CTX *tmp_ctx = NULL; - struct ldb_message *msg; - TALLOC_FREE(ctx->test_ctx->ldb); - TALLOC_FREE(ctx->test_ctx->ev); - close(pipes[0]); - ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx); - if (ctx->test_ctx->ev == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ctx->test_ctx->ldb = ldb_init(ctx->test_ctx, - ctx->test_ctx->ev); - if (ctx->test_ctx->ldb == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ret = ldb_connect(ctx->test_ctx->ldb, - ctx->test_ctx->dbpath, 0, NULL); - if (ret != LDB_SUCCESS) { - exit(ret); - } - - tmp_ctx = talloc_new(ctx->test_ctx); - if (tmp_ctx == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - msg = ldb_msg_new(tmp_ctx); - if (msg == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb, - "dc=test"); - if (msg->dn == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ret = ldb_msg_add_string(msg, "cn", "test_cn_val"); - if (ret != 0) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ret = ldb_transaction_start(ctx->test_ctx->ldb); - if (ret != 0) { - exit(ret); - } - - ret = write(pipes[1], "GO", 2); - if (ret != 2) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ret = ldb_msg_add_string(msg, "objectUUID", - "0123456789abcdef"); - if (ret != 0) { - exit(ret); - } - - ret = ldb_add(ctx->test_ctx->ldb, msg); - if (ret != 0) { - exit(ret); - } - - ret = ldb_transaction_commit(ctx->test_ctx->ldb); - exit(ret); - } - close(pipes[1]); - ret = read(pipes[0], buf, 2); - assert_int_equal(ret, 2); - - /* This search must be unindexed (ie traverse in tdb) */ - ret = ldb_build_search_req(&req, - ctx->test_ctx->ldb, - ctx->test_ctx, - ctx->basedn, - LDB_SCOPE_SUBTREE, - "cn=*", NULL, - NULL, - ctx, - test_ldb_search_against_transaction_callback2, - NULL); - /* - * we don't assert on these return codes until after the search is - * finished, or the clean up will fail because we hold locks. - */ - - ret2 = ldb_request(ctx->test_ctx->ldb, req); - - if (ret2 == LDB_SUCCESS) { - ret2 = ldb_wait(req->handle, LDB_WAIT_ALL); - } - assert_int_equal(ret, 0); - assert_int_equal(ret2, 0); - assert_int_equal(ctx->res_count, 2); - - return LDB_SUCCESS; -} - -static void test_ldb_search_against_transaction(void **state) -{ - struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, - struct search_test_ctx); - struct search_against_transaction_ctx - ctx = - { .res_count = 0, - .test_ctx = search_test_ctx->ldb_test_ctx - }; - - int ret; - struct ldb_request *req; - pid_t pid; - int wstatus; - struct ldb_dn *base_search_dn; - - tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev); - - base_search_dn - = ldb_dn_new_fmt(search_test_ctx, - search_test_ctx->ldb_test_ctx->ldb, - "cn=test_search_cn,%s", - search_test_ctx->base_dn); - assert_non_null(base_search_dn); - - ctx.basedn - = ldb_dn_new_fmt(search_test_ctx, - search_test_ctx->ldb_test_ctx->ldb, - "%s", - search_test_ctx->base_dn); - assert_non_null(ctx.basedn); - - - /* This search must be indexed (ie no traverse in tdb) */ - ret = ldb_build_search_req(&req, - search_test_ctx->ldb_test_ctx->ldb, - search_test_ctx, - base_search_dn, - LDB_SCOPE_BASE, - "cn=*", NULL, - NULL, - &ctx, - test_ldb_search_against_transaction_callback1, - NULL); - assert_int_equal(ret, 0); - ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req); - - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - assert_int_equal(ret, 0); - assert_int_equal(ctx.res_count, 2); - - pid = waitpid(ctx.child_pid, &wstatus, 0); - assert_int_equal(pid, ctx.child_pid); - - assert_true(WIFEXITED(wstatus)); - - assert_int_equal(WEXITSTATUS(wstatus), 0); - - -} - -/* - * This test is also complex. - * The purpose is to test if a modify can occur during an ldb_search() - * This would be a failure if if in process - * (1) and (2): - * - (1) ltdb_search() starts and calls back for one entry - * - (2) one of the entries to be matched is modified - * - (1) the indexed search tries to return the modified entry, but - * it is no longer found, either: - * - despite it still matching (dn changed) - * - it no longer matching (attrs changed) - * - * We also try un-indexed to show that the behaviour differs on this - * point, which it should not (an index should only impact search - * speed). - */ - -struct modify_during_search_test_ctx { - struct ldbtest_ctx *test_ctx; - int res_count; - pid_t child_pid; - struct ldb_dn *basedn; - bool got_cn; - bool got_2_cn; - bool rename; -}; - -/* - * This purpose of this callback is to trigger a write in - * the child process while a search is in progress. - * - * In tdb 1.3.12 tdb_traverse_read() take the read transaction lock - * however in ldb 1.1.31 ltdb_search() forgets to take the all-record - * lock (except the very first time) due to a ref-counting bug. - * - * We assume that if the write will proceed, it will proceed in a 3 - * second window after the function is called. - */ - -static int test_ldb_modify_during_search_callback1(struct ldb_request *req, - struct ldb_reply *ares) -{ - int ret; - int pipes[2]; - char buf[2]; - struct modify_during_search_test_ctx *ctx = req->context; - switch (ares->type) { - case LDB_REPLY_ENTRY: - { - const struct ldb_val *cn_val - = ldb_dn_get_component_val(ares->message->dn, 0); - const char *cn = (char *)cn_val->data; - ctx->res_count++; - if (strcmp(cn, "test_search_cn") == 0) { - ctx->got_cn = true; - } else if (strcmp(cn, "test_search_2_cn") == 0) { - ctx->got_2_cn = true; - } - if (ctx->res_count == 2) { - return LDB_SUCCESS; - } - break; - } - case LDB_REPLY_REFERRAL: - return LDB_SUCCESS; - - case LDB_REPLY_DONE: - return ldb_request_done(req, LDB_SUCCESS); - } - - ret = pipe(pipes); - assert_int_equal(ret, 0); - - ctx->child_pid = fork(); - if (ctx->child_pid == 0 && ctx->rename) { - TALLOC_CTX *tmp_ctx = NULL; - struct ldb_dn *dn, *new_dn; - TALLOC_FREE(ctx->test_ctx->ldb); - TALLOC_FREE(ctx->test_ctx->ev); - close(pipes[0]); - ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx); - if (ctx->test_ctx->ev == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ctx->test_ctx->ldb = ldb_init(ctx->test_ctx, - ctx->test_ctx->ev); - if (ctx->test_ctx->ldb == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ret = ldb_connect(ctx->test_ctx->ldb, - ctx->test_ctx->dbpath, 0, NULL); - if (ret != LDB_SUCCESS) { - exit(ret); - } - - tmp_ctx = talloc_new(ctx->test_ctx); - if (tmp_ctx == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - if (ctx->got_cn) { - /* Modify the other one */ - dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb, - "cn=test_search_2_cn," - "dc=search_test_entry"); - } else { - dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb, - "cn=test_search_cn," - "dc=search_test_entry"); - } - if (dn == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - new_dn = ldb_dn_new_fmt(tmp_ctx, ctx->test_ctx->ldb, - "cn=test_search_cn_renamed," - "dc=search_test_entry"); - if (new_dn == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ret = ldb_transaction_start(ctx->test_ctx->ldb); - if (ret != 0) { - exit(ret); - } - - if (write(pipes[1], "GO", 2) != 2) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ret = ldb_rename(ctx->test_ctx->ldb, dn, new_dn); - if (ret != 0) { - exit(ret); - } - - ret = ldb_transaction_commit(ctx->test_ctx->ldb); - exit(ret); - - } else if (ctx->child_pid == 0) { - TALLOC_CTX *tmp_ctx = NULL; - struct ldb_message *msg; - struct ldb_message_element *el; - TALLOC_FREE(ctx->test_ctx->ldb); - TALLOC_FREE(ctx->test_ctx->ev); - close(pipes[0]); - ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx); - if (ctx->test_ctx->ev == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ctx->test_ctx->ldb = ldb_init(ctx->test_ctx, - ctx->test_ctx->ev); - if (ctx->test_ctx->ldb == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ret = ldb_connect(ctx->test_ctx->ldb, - ctx->test_ctx->dbpath, 0, NULL); - if (ret != LDB_SUCCESS) { - exit(ret); - } - - tmp_ctx = talloc_new(ctx->test_ctx); - if (tmp_ctx == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - msg = ldb_msg_new(tmp_ctx); - if (msg == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - if (ctx->got_cn) { - /* Modify the other one */ - msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb, - "cn=test_search_2_cn," - "dc=search_test_entry"); - } else { - msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb, - "cn=test_search_cn," - "dc=search_test_entry"); - } - if (msg->dn == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ret = ldb_msg_add_string(msg, "filterAttr", "TRUE"); - if (ret != 0) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - el = ldb_msg_find_element(msg, "filterAttr"); - if (el == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - el->flags = LDB_FLAG_MOD_REPLACE; - - ret = ldb_transaction_start(ctx->test_ctx->ldb); - if (ret != 0) { - exit(ret); - } - - if (write(pipes[1], "GO", 2) != 2) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ret = ldb_modify(ctx->test_ctx->ldb, msg); - if (ret != 0) { - exit(ret); - } - - ret = ldb_transaction_commit(ctx->test_ctx->ldb); - exit(ret); - } - - /* - * With TDB 1.3.13 and before "tdb: Remove locking from tdb_traverse_read()" - * we will hang here because the child process can not proceed to - * sending the "GO" as it is blocked at ldb_transaction_start(). - */ - - close(pipes[1]); - ret = read(pipes[0], buf, 2); - assert_int_equal(ret, 2); - - sleep(3); - - return LDB_SUCCESS; -} - -static void test_ldb_modify_during_search(void **state, bool add_index, - bool rename) -{ - struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, - struct search_test_ctx); - struct modify_during_search_test_ctx - ctx = - { .res_count = 0, - .test_ctx = search_test_ctx->ldb_test_ctx, - .rename = rename - }; - - int ret; - struct ldb_request *req; - pid_t pid; - int wstatus; - - if (add_index) { - struct ldb_message *msg; - struct ldb_dn *indexlist = ldb_dn_new(search_test_ctx, - search_test_ctx->ldb_test_ctx->ldb, - "@INDEXLIST"); - assert_non_null(indexlist); - - msg = ldb_msg_new(search_test_ctx); - assert_non_null(msg); - - msg->dn = indexlist; - - ret = ldb_msg_add_string(msg, "@IDXATTR", "cn"); - assert_int_equal(ret, LDB_SUCCESS); - ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb, - msg); - if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { - msg->elements[0].flags = LDB_FLAG_MOD_ADD; - ret = ldb_modify(search_test_ctx->ldb_test_ctx->ldb, - msg); - } - assert_int_equal(ret, LDB_SUCCESS); - } - - tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev); - - ctx.basedn - = ldb_dn_new_fmt(search_test_ctx, - search_test_ctx->ldb_test_ctx->ldb, - "%s", - search_test_ctx->base_dn); - assert_non_null(ctx.basedn); - - - /* - * This search must be over multiple items, and should include - * the new name after a rename, to show that it would match - * both before and after that modify - */ - ret = ldb_build_search_req(&req, - search_test_ctx->ldb_test_ctx->ldb, - search_test_ctx, - ctx.basedn, - LDB_SCOPE_SUBTREE, - "(&(!(filterAttr=*))" - "(|(cn=test_search_cn_renamed)" - "(cn=test_search_cn)" - "(cn=test_search_2_cn)" - "))", - NULL, - NULL, - &ctx, - test_ldb_modify_during_search_callback1, - NULL); - assert_int_equal(ret, 0); - ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req); - - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - assert_int_equal(ret, 0); - assert_int_equal(ctx.res_count, 2); - assert_int_equal(ctx.got_cn, true); - assert_int_equal(ctx.got_2_cn, true); - - pid = waitpid(ctx.child_pid, &wstatus, 0); - assert_int_equal(pid, ctx.child_pid); - - assert_true(WIFEXITED(wstatus)); - - assert_int_equal(WEXITSTATUS(wstatus), 0); - - -} - -static void test_ldb_modify_during_indexed_search(void **state) -{ - test_ldb_modify_during_search(state, true, false); -} - -static void test_ldb_modify_during_unindexed_search(void **state) -{ - test_ldb_modify_during_search(state, false, false); -} - -static void test_ldb_rename_during_indexed_search(void **state) -{ - test_ldb_modify_during_search(state, true, true); -} - -static void test_ldb_rename_during_unindexed_search(void **state) -{ - test_ldb_modify_during_search(state, false, true); -} - -/* - * This test is also complex. - * - * The purpose is to test if a modify can occur during an ldb_search() - * before the end of the callback - * - * This would be a failure if if in process - * (1) and (2): - * - (1) ldb_search() starts and calls back for a number of entries - * - (2) an entry in the DB is allowed to change before the callback returns - * - (1) the callback can see the modification - * - */ - -/* - * This purpose of this callback is to trigger a write in - * the child process while a search DONE callback is in progress. - * - * In ldb 1.1.31 ldb_search() omitted to take a all-record - * lock for the full duration of the search and callbacks - * - * We assume that if the write will proceed, it will proceed in a 3 - * second window after the function is called. - */ - -static int test_ldb_modify_during_whole_search_callback1(struct ldb_request *req, - struct ldb_reply *ares) -{ - int ret; - int pipes[2]; - char buf[2]; - struct modify_during_search_test_ctx *ctx = req->context; - struct ldb_dn *search_dn; - struct ldb_result *res2; - unsigned res_count; - switch (ares->type) { - case LDB_REPLY_ENTRY: - case LDB_REPLY_REFERRAL: - return LDB_SUCCESS; - - case LDB_REPLY_DONE: - break; - } - - ret = pipe(pipes); - assert_int_equal(ret, 0); - - ctx->child_pid = fork(); - if (ctx->child_pid == 0) { - TALLOC_CTX *tmp_ctx = NULL; - struct ldb_message *msg; - struct ldb_message_element *el; - TALLOC_FREE(ctx->test_ctx->ldb); - TALLOC_FREE(ctx->test_ctx->ev); - close(pipes[0]); - ctx->test_ctx->ev = tevent_context_init(ctx->test_ctx); - if (ctx->test_ctx->ev == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ctx->test_ctx->ldb = ldb_init(ctx->test_ctx, - ctx->test_ctx->ev); - if (ctx->test_ctx->ldb == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ret = ldb_connect(ctx->test_ctx->ldb, - ctx->test_ctx->dbpath, 0, NULL); - if (ret != LDB_SUCCESS) { - exit(ret); - } - - tmp_ctx = talloc_new(ctx->test_ctx); - if (tmp_ctx == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - msg = ldb_msg_new(tmp_ctx); - if (msg == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - msg->dn = ldb_dn_new_fmt(msg, ctx->test_ctx->ldb, - "cn=test_search_cn," - "dc=search_test_entry"); - if (msg->dn == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ret = ldb_msg_add_string(msg, "filterAttr", "TRUE"); - if (ret != 0) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - el = ldb_msg_find_element(msg, "filterAttr"); - if (el == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - el->flags = LDB_FLAG_MOD_REPLACE; - - ret = ldb_transaction_start(ctx->test_ctx->ldb); - if (ret != 0) { - exit(ret); - } - - if (write(pipes[1], "GO", 2) != 2) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ret = ldb_modify(ctx->test_ctx->ldb, msg); - if (ret != 0) { - exit(ret); - } - - ret = ldb_transaction_commit(ctx->test_ctx->ldb); - exit(ret); - } - - close(pipes[1]); - ret = read(pipes[0], buf, 2); - assert_int_equal(ret, 2); - - sleep(3); - - /* - * If writes are not blocked until after this function, we - * will be able to successfully search for this modification - * here - */ - - search_dn = ldb_dn_new_fmt(ares, ctx->test_ctx->ldb, - "cn=test_search_cn," - "dc=search_test_entry"); - - ret = ldb_search(ctx->test_ctx->ldb, ares, - &res2, search_dn, LDB_SCOPE_BASE, NULL, - "filterAttr=TRUE"); - - /* - * We do this in an unusual order, because if we fail an assert before - * ldb_request_done(), we will also fail to clean up as we hold locks. - */ - - res_count = res2->count; - ldb_request_done(req, LDB_SUCCESS); - assert_int_equal(ret, 0); - - /* We should not have got the result */ - assert_int_equal(res_count, 0); - - return ret; -} - -static void test_ldb_modify_during_whole_search(void **state) -{ - struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, - struct search_test_ctx); - struct modify_during_search_test_ctx - ctx = - { - .test_ctx = search_test_ctx->ldb_test_ctx, - }; - - int ret; - struct ldb_request *req; - pid_t pid; - int wstatus; - struct ldb_dn *search_dn; - struct ldb_result *res2; - - tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev); - - ctx.basedn - = ldb_dn_new_fmt(search_test_ctx, - search_test_ctx->ldb_test_ctx->ldb, - "%s", - search_test_ctx->base_dn); - assert_non_null(ctx.basedn); - - - /* - * The search just needs to call DONE, we don't care about the - * contents of the search for this test - */ - ret = ldb_build_search_req(&req, - search_test_ctx->ldb_test_ctx->ldb, - search_test_ctx, - ctx.basedn, - LDB_SCOPE_SUBTREE, - "(&(!(filterAttr=*))" - "(cn=test_search_cn))", - NULL, - NULL, - &ctx, - test_ldb_modify_during_whole_search_callback1, - NULL); - assert_int_equal(ret, 0); - ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req); - - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - assert_int_equal(ret, 0); - - pid = waitpid(ctx.child_pid, &wstatus, 0); - assert_int_equal(pid, ctx.child_pid); - - assert_true(WIFEXITED(wstatus)); - - assert_int_equal(WEXITSTATUS(wstatus), 0); - - /* - * If writes are blocked until after the search function, we - * will be able to successfully search for this modification - * now - */ - - search_dn = ldb_dn_new_fmt(search_test_ctx, - search_test_ctx->ldb_test_ctx->ldb, - "cn=test_search_cn," - "dc=search_test_entry"); - - ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, - search_test_ctx, - &res2, search_dn, LDB_SCOPE_BASE, NULL, - "filterAttr=TRUE"); - assert_int_equal(ret, 0); - - /* We got the result */ - assert_int_equal(res2->count, 1); -} - -/* - * This test is also complex. - * - * The purpose is to test if a modify can occur during an ldb_search() - * before the request is destroyed with TALLOC_FREE() - * - * This would be a failure if in process - * (1) and (2): - * - (1) ldb_search() starts and waits - * - (2) an entry in the DB is allowed to change before the ldb_wait() is called - * - (1) the original process can see the modification before the TALLOC_FREE() - * also we check that - * - (1) the original process can see the modification after the TALLOC_FREE() - * - */ - -/* - * This purpose of this callback is to trigger a write in - * the child process before the ldb_wait() is called - * - * In ldb 1.1.31 ldb_search() omitted to take a all-record - * lock for the full duration of the search and callbacks - * - * We assume that if the write will proceed, it will proceed in a 3 - * second window after the function is called. - */ - -static int test_ldb_modify_before_ldb_wait_callback1(struct ldb_request *req, - struct ldb_reply *ares) -{ - switch (ares->type) { - case LDB_REPLY_ENTRY: - case LDB_REPLY_REFERRAL: - return LDB_SUCCESS; - - case LDB_REPLY_DONE: - break; - } - - return ldb_request_done(req, LDB_SUCCESS); -} - -static void test_ldb_modify_before_ldb_wait(void **state) -{ - struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, - struct search_test_ctx); - int ret; - struct ldb_request *req; - pid_t pid; - int wstatus; - struct ldb_dn *search_dn; - struct ldb_dn *basedn; - struct ldb_result *res2; - int pipes[2]; - char buf[2]; - pid_t child_pid; - unsigned res_count; - - search_dn = ldb_dn_new_fmt(search_test_ctx, - search_test_ctx->ldb_test_ctx->ldb, - "cn=test_search_cn," - "dc=search_test_entry"); - assert_non_null(search_dn); - - basedn = ldb_dn_new_fmt(search_test_ctx, - search_test_ctx->ldb_test_ctx->ldb, - "%s", - search_test_ctx->base_dn); - assert_non_null(basedn); - - /* - * The search just needs to call DONE, we don't care about the - * contents of the search for this test - */ - ret = ldb_build_search_req(&req, - search_test_ctx->ldb_test_ctx->ldb, - search_test_ctx, - basedn, - LDB_SCOPE_SUBTREE, - "(&(!(filterAttr=*))" - "(cn=test_search_cn))", - NULL, - NULL, - NULL, - test_ldb_modify_before_ldb_wait_callback1, - NULL); - assert_int_equal(ret, 0); - ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req); - - ret = pipe(pipes); - assert_int_equal(ret, 0); - - child_pid = fork(); - if (child_pid == 0) { - TALLOC_CTX *tmp_ctx = NULL; - struct ldb_message *msg; - struct ldb_message_element *el; - TALLOC_FREE(search_test_ctx->ldb_test_ctx->ldb); - TALLOC_FREE(search_test_ctx->ldb_test_ctx->ev); - close(pipes[0]); - search_test_ctx->ldb_test_ctx->ev = tevent_context_init(search_test_ctx->ldb_test_ctx); - if (search_test_ctx->ldb_test_ctx->ev == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - search_test_ctx->ldb_test_ctx->ldb = ldb_init(search_test_ctx->ldb_test_ctx, - search_test_ctx->ldb_test_ctx->ev); - if (search_test_ctx->ldb_test_ctx->ldb == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ret = ldb_connect(search_test_ctx->ldb_test_ctx->ldb, - search_test_ctx->ldb_test_ctx->dbpath, 0, NULL); - if (ret != LDB_SUCCESS) { - exit(ret); - } - - tmp_ctx = talloc_new(search_test_ctx->ldb_test_ctx); - if (tmp_ctx == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - msg = ldb_msg_new(tmp_ctx); - if (msg == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - /* - * We must re-create this DN from a string to ensure - * it does not reference the now-gone LDB context of - * the parent - */ - msg->dn = ldb_dn_new_fmt(search_test_ctx, - search_test_ctx->ldb_test_ctx->ldb, - "cn=test_search_cn," - "dc=search_test_entry"); - - if (msg->dn == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ret = ldb_msg_add_string(msg, "filterAttr", "TRUE"); - if (ret != 0) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - el = ldb_msg_find_element(msg, "filterAttr"); - if (el == NULL) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - el->flags = LDB_FLAG_MOD_REPLACE; - - ret = ldb_transaction_start(search_test_ctx->ldb_test_ctx->ldb); - if (ret != 0) { - exit(ret); - } - - if (write(pipes[1], "GO", 2) != 2) { - exit(LDB_ERR_OPERATIONS_ERROR); - } - - ret = ldb_modify(search_test_ctx->ldb_test_ctx->ldb, msg); - if (ret != 0) { - exit(ret); - } - - ret = ldb_transaction_commit(search_test_ctx->ldb_test_ctx->ldb); - exit(ret); - } - close(pipes[1]); - - ret = read(pipes[0], buf, 2); - assert_int_equal(ret, 2); - - sleep(3); - - /* - * If writes are not blocked until after the (never called) ldb_wait(), we - * will be able to successfully search for this modification - * here - */ - - ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, search_test_ctx, - &res2, search_dn, LDB_SCOPE_BASE, NULL, - "filterAttr=TRUE"); - - /* - * We avoid making assertions before TALLOC_FREE()ing the request, - * lest the assert fail and mess with the clean-up because we still - * have locks. - */ - res_count = res2->count; - TALLOC_FREE(req); - - /* We should not have got the result */ - assert_int_equal(res_count, 0); - assert_int_equal(ret, 0); - - pid = waitpid(child_pid, &wstatus, 0); - assert_int_equal(pid, child_pid); - - assert_true(WIFEXITED(wstatus)); - - assert_int_equal(WEXITSTATUS(wstatus), 0); - - /* - * If writes are blocked until after the search request was freed, we - * will be able to successfully search for this modification - * now - */ - - search_dn = ldb_dn_new_fmt(search_test_ctx, - search_test_ctx->ldb_test_ctx->ldb, - "cn=test_search_cn," - "dc=search_test_entry"); - - ret = ldb_search(search_test_ctx->ldb_test_ctx->ldb, - search_test_ctx, - &res2, search_dn, LDB_SCOPE_BASE, NULL, - "filterAttr=TRUE"); - assert_int_equal(ret, 0); - - /* We got the result */ - assert_int_equal(res2->count, 1); -} - -/* - * This test is also complex. - * The purpose is to test if a modify can occur during an ldb_search() - * This would be a failure if if in process - * (1) and (2): - * - (1) ltdb_search() starts and calls back for one entry - * - (2) one of the entries to be matched is modified - * - (1) the indexed search tries to return the modified entry, but - * it is no longer found, either: - * - despite it still matching (dn changed) - * - it no longer matching (attrs changed) - * - * We also try un-indexed to show that the behaviour differs on this - * point, which it should not (an index should only impact search - * speed). - */ - -/* - * This purpose of this callback is to trigger a write in the callback - * so as to change in in-memory index code while looping over the - * index result. - */ - -static int test_ldb_callback_modify_during_search_callback1(struct ldb_request *req, - struct ldb_reply *ares) -{ - int ret; - struct modify_during_search_test_ctx *ctx = req->context; - struct ldb_dn *dn = NULL, *new_dn = NULL; - TALLOC_CTX *tmp_ctx = talloc_new(ctx->test_ctx); - struct ldb_message *msg = NULL; - - assert_non_null(tmp_ctx); - - switch (ares->type) { - case LDB_REPLY_ENTRY: - { - const struct ldb_val *cn_val - = ldb_dn_get_component_val(ares->message->dn, 0); - const char *cn = (char *)cn_val->data; - ctx->res_count++; - if (strcmp(cn, "test_search_cn") == 0) { - ctx->got_cn = true; - } else if (strcmp(cn, "test_search_2_cn") == 0) { - ctx->got_2_cn = true; - } - if (ctx->res_count == 2) { - return LDB_SUCCESS; - } - break; - } - case LDB_REPLY_REFERRAL: - return LDB_SUCCESS; - - case LDB_REPLY_DONE: - return ldb_request_done(req, LDB_SUCCESS); - } - - if (ctx->rename) { - if (ctx->got_2_cn) { - /* Modify this one */ - dn = ldb_dn_new_fmt(tmp_ctx, - ctx->test_ctx->ldb, - "cn=test_search_2_cn,%s", - ldb_dn_get_linearized(ctx->basedn)); - } else { - dn = ldb_dn_new_fmt(tmp_ctx, - ctx->test_ctx->ldb, - "cn=test_search_cn,%s", - ldb_dn_get_linearized(ctx->basedn)); - } - assert_non_null(dn); - - new_dn = ldb_dn_new_fmt(tmp_ctx, - ctx->test_ctx->ldb, - "cn=test_search_cn_renamed," - "dc=not_search_test_entry"); - assert_non_null(new_dn); - - ret = ldb_rename(ctx->test_ctx->ldb, dn, new_dn); - assert_int_equal(ret, 0); - - } else { - if (ctx->got_2_cn) { - /* Delete this one */ - dn = ldb_dn_new_fmt(tmp_ctx, - ctx->test_ctx->ldb, - "cn=test_search_2_cn,%s", - ldb_dn_get_linearized(ctx->basedn)); - } else { - dn = ldb_dn_new_fmt(tmp_ctx, - ctx->test_ctx->ldb, - "cn=test_search_cn,%s", - ldb_dn_get_linearized(ctx->basedn)); - } - assert_non_null(dn); - - ret = ldb_delete(ctx->test_ctx->ldb, dn); - assert_int_equal(ret, 0); - } - - /* - * Now fill in the position we just removed from the - * index to ensure we fail the test (otherwise we just read - * past the end of the array and find the value we wanted to - * skip) - */ - msg = ldb_msg_new(tmp_ctx); - assert_non_null(msg); - - /* We deliberatly use ou= not cn= here */ - msg->dn = ldb_dn_new_fmt(msg, - ctx->test_ctx->ldb, - "ou=test_search_cn_extra,%s", - ldb_dn_get_linearized(ctx->basedn)); - - ret = ldb_msg_add_string(msg, - "objectUUID", - "0123456789abcde3"); - - ret = ldb_add(ctx->test_ctx->ldb, - msg); - assert_int_equal(ret, LDB_SUCCESS); - - TALLOC_FREE(tmp_ctx); - return LDB_SUCCESS; -} - -static void test_ldb_callback_modify_during_search(void **state, bool add_index, - bool rename) -{ - struct search_test_ctx *search_test_ctx = talloc_get_type_abort(*state, - struct search_test_ctx); - struct modify_during_search_test_ctx - ctx = - { .res_count = 0, - .test_ctx = search_test_ctx->ldb_test_ctx, - .rename = rename - }; - - int ret; - struct ldb_request *req; - - ret = ldb_transaction_start(search_test_ctx->ldb_test_ctx->ldb); - assert_int_equal(ret, 0); - - if (add_index) { - struct ldb_message *msg; - struct ldb_dn *indexlist = ldb_dn_new(search_test_ctx, - search_test_ctx->ldb_test_ctx->ldb, - "@INDEXLIST"); - assert_non_null(indexlist); - - msg = ldb_msg_new(search_test_ctx); - assert_non_null(msg); - - msg->dn = indexlist; - - ret = ldb_msg_add_string(msg, "@IDXONE", "1"); - assert_int_equal(ret, LDB_SUCCESS); - ret = ldb_msg_add_string(msg, "@IDXATTR", "cn"); - assert_int_equal(ret, LDB_SUCCESS); - ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb, - msg); - if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { - msg->elements[0].flags = LDB_FLAG_MOD_ADD; - msg->elements[1].flags = LDB_FLAG_MOD_ADD; - ret = ldb_modify(search_test_ctx->ldb_test_ctx->ldb, - msg); - } - assert_int_equal(ret, LDB_SUCCESS); - - /* - * Now bring the IDXONE index into memory by modifying - * it. This exposes an issue in ldb_tdb - */ - msg = ldb_msg_new(search_test_ctx); - assert_non_null(msg); - - msg->dn = ldb_dn_new_fmt(search_test_ctx, - search_test_ctx->ldb_test_ctx->ldb, - "cn=test_search_cn_extra,%s", - search_test_ctx->base_dn); - - ret = ldb_msg_add_string(msg, - "objectUUID", - "0123456789abcde2"); - - ret = ldb_add(search_test_ctx->ldb_test_ctx->ldb, - msg); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_delete(search_test_ctx->ldb_test_ctx->ldb, - msg->dn); - assert_int_equal(ret, LDB_SUCCESS); - } - - tevent_loop_allow_nesting(search_test_ctx->ldb_test_ctx->ev); - - ctx.basedn - = ldb_dn_new_fmt(search_test_ctx, - search_test_ctx->ldb_test_ctx->ldb, - "%s", - search_test_ctx->base_dn); - assert_non_null(ctx.basedn); - - - /* - * This search must be over multiple items, and should include - * the new name after a rename, to show that it would match - * both before and after that modify - * - * This needs to be a search that isn't matched by an index so - * that we just use the one-level index. - */ - ret = ldb_build_search_req(&req, - search_test_ctx->ldb_test_ctx->ldb, - search_test_ctx, - ctx.basedn, - LDB_SCOPE_ONELEVEL, - "(cn=*)", - NULL, - NULL, - &ctx, - test_ldb_callback_modify_during_search_callback1, - NULL); - assert_int_equal(ret, 0); - - ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req); - - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - assert_int_equal(ret, 0); - - ret = ldb_transaction_commit(search_test_ctx->ldb_test_ctx->ldb); - assert_int_equal(ret, 0); - - assert_int_equal(ctx.res_count, 2); - assert_int_equal(ctx.got_cn, true); - assert_int_equal(ctx.got_2_cn, true); -} - -static void test_ldb_callback_delete_during_indexed_search(void **state) -{ - test_ldb_callback_modify_during_search(state, true, false); -} - -static void test_ldb_callback_delete_during_unindexed_search(void **state) -{ - test_ldb_callback_modify_during_search(state, false, false); -} - -static void test_ldb_callback_rename_during_indexed_search(void **state) -{ - test_ldb_callback_modify_during_search(state, true, true); -} - -static void test_ldb_callback_rename_during_unindexed_search(void **state) -{ - test_ldb_callback_modify_during_search(state, false, true); -} - -static int ldb_case_test_setup(void **state) -{ - int ret; - struct ldb_ldif *ldif; - struct ldbtest_ctx *ldb_test_ctx; - const char *attrs_ldif = \ - "dn: @ATTRIBUTES\n" - "cn: CASE_INSENSITIVE\n" - "\n"; - struct keyval kvs[] = { - { "cn", "CaseInsensitiveValue" }, - { "uid", "CaseSensitiveValue" }, - { "objectUUID", "0123456789abcdef" }, - { NULL, NULL }, - }; - - - ldbtest_setup((void **) &ldb_test_ctx); - - while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) { - ret = ldb_add(ldb_test_ctx->ldb, ldif->msg); - assert_int_equal(ret, LDB_SUCCESS); - } - - ldb_test_add_data(ldb_test_ctx, - ldb_test_ctx, - "cn=CaseInsensitiveValue", - kvs); - - *state = ldb_test_ctx; - return 0; -} - -static int ldb_case_test_teardown(void **state) -{ - int ret; - struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - - struct ldb_dn *del_dn; - - del_dn = ldb_dn_new_fmt(ldb_test_ctx, - ldb_test_ctx->ldb, - "@ATTRIBUTES"); - assert_non_null(del_dn); - - ret = ldb_delete(ldb_test_ctx->ldb, del_dn); - assert_int_equal(ret, LDB_SUCCESS); - - assert_dn_doesnt_exist(ldb_test_ctx, - "@ATTRIBUTES"); - - ldb_test_remove_data(ldb_test_ctx, ldb_test_ctx, - "cn=CaseInsensitiveValue"); - - ldbtest_teardown((void **) &ldb_test_ctx); - return 0; -} - -static void test_ldb_attrs_case_insensitive(void **state) -{ - int cnt; - struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - - /* cn matches exact case */ - cnt = sub_search_count(ldb_test_ctx, "", "cn=CaseInsensitiveValue"); - assert_int_equal(cnt, 1); - - /* cn matches lower case */ - cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); - assert_int_equal(cnt, 1); - - /* uid matches exact case */ - cnt = sub_search_count(ldb_test_ctx, "", "uid=CaseSensitiveValue"); - assert_int_equal(cnt, 1); - - /* uid does not match lower case */ - cnt = sub_search_count(ldb_test_ctx, "", "uid=casesensitivevalue"); - assert_int_equal(cnt, 0); -} - -static struct ldb_schema_attribute cn_attr_1; -static struct ldb_schema_attribute cn_attr_2; -static struct ldb_schema_attribute default_attr; - -/* - override the name to attribute handler function - */ -static const struct ldb_schema_attribute *ldb_test_attribute_handler_override(struct ldb_context *ldb, - void *private_data, - const char *name) -{ - if (private_data != NULL && ldb_attr_cmp(name, "cn") == 0) { - return &cn_attr_1; - } else if (private_data == NULL && ldb_attr_cmp(name, "cn") == 0) { - return &cn_attr_2; - } else if (ldb_attr_cmp(name, "uid") == 0) { - return &cn_attr_2; - } - return &default_attr; -} - -static void test_ldb_attrs_case_handler(void **state) -{ - int cnt; - int ret; - const struct ldb_schema_syntax *syntax; - - struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - struct ldb_context *ldb = ldb_test_ctx->ldb; - - /* cn matches lower case */ - cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); - assert_int_equal(cnt, 1); - - syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING); - assert_non_null(syntax); - - ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb, - "*", 0, - syntax, &default_attr); - assert_int_equal(ret, LDB_SUCCESS); - - syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING); - assert_non_null(syntax); - - ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb, - "cn", 0, - syntax, &cn_attr_1); - assert_int_equal(ret, LDB_SUCCESS); - - /* - * Set an attribute handler, which will fail to match as we - * force case sensitive - */ - ldb_schema_attribute_set_override_handler(ldb, - ldb_test_attribute_handler_override, - (void *)1); - - /* cn does not matche lower case */ - cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); - assert_int_equal(cnt, 0); - - syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING); - assert_non_null(syntax); - - ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb, - "cn", 0, - syntax, &cn_attr_2); - assert_int_equal(ret, LDB_SUCCESS); - - /* - * Set an attribute handler, which will match as we - * force case insensitive - */ - ldb_schema_attribute_set_override_handler(ldb, - ldb_test_attribute_handler_override, - NULL); - - /* cn matches lower case */ - cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); - assert_int_equal(cnt, 1); - -} - - -static void test_ldb_attrs_index_handler(void **state) -{ - int cnt; - int ret; - const struct ldb_schema_syntax *syntax; - struct ldb_ldif *ldif; - - const char *index_ldif = \ - "dn: @INDEXLIST\n" - "@IDXATTR: cn\n" - "\n"; - - struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - struct ldb_context *ldb = ldb_test_ctx->ldb; - - /* cn matches lower case */ - cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); - assert_int_equal(cnt, 1); - - syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING); - assert_non_null(syntax); - - ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb, - "cn", 0, - syntax, &cn_attr_1); - assert_int_equal(ret, LDB_SUCCESS); - - syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_DIRECTORY_STRING); - assert_non_null(syntax); - - ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb, - "cn", LDB_ATTR_FLAG_INDEXED, - syntax, &cn_attr_2); - assert_int_equal(ret, LDB_SUCCESS); - - syntax = ldb_standard_syntax_by_name(ldb, LDB_SYNTAX_OCTET_STRING); - assert_non_null(syntax); - - ret = ldb_schema_attribute_fill_with_syntax(ldb, ldb, - "", 0, - syntax, &default_attr); - assert_int_equal(ret, LDB_SUCCESS); - - /* - * Set an attribute handler - */ - ldb_schema_attribute_set_override_handler(ldb, - ldb_test_attribute_handler_override, - NULL); - - /* cn matches lower case */ - cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); - assert_int_equal(cnt, 1); - - /* Add the index (actually any modify will do) */ - while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) { - ret = ldb_add(ldb_test_ctx->ldb, ldif->msg); - if (ret == LDB_ERR_ENTRY_ALREADY_EXISTS) { - ldif->msg->elements[0].flags = LDB_FLAG_MOD_ADD; - ret = ldb_modify(ldb_test_ctx->ldb, - ldif->msg); - } - assert_int_equal(ret, LDB_SUCCESS); - } - - ldb_schema_set_override_indexlist(ldb, false); - - /* cn does match as there is an index now */ - cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); - assert_int_equal(cnt, 1); - - /* - * Set an attribute handler, which will later fail to match as we - * didn't re-index the DB - */ - ldb_schema_attribute_set_override_handler(ldb, - ldb_test_attribute_handler_override, - (void *)1); - - /* - * cn does not match as we changed the case sensitivity, but - * didn't re-index - * - * This shows that the override is in control - */ - cnt = sub_search_count(ldb_test_ctx, "", "cn=caseinsensitivevalue"); - assert_int_equal(cnt, 0); - -} - -static int ldb_case_attrs_index_test_teardown(void **state) -{ - int ret; - struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - struct ldb_dn *del_dn; - - del_dn = ldb_dn_new_fmt(ldb_test_ctx, - ldb_test_ctx->ldb, - "@INDEXLIST"); - assert_non_null(del_dn); - - ret = ldb_delete(ldb_test_ctx->ldb, del_dn); - if (ret != LDB_ERR_NO_SUCH_OBJECT) { - assert_int_equal(ret, LDB_SUCCESS); - } - - assert_dn_doesnt_exist(ldb_test_ctx, - "@INDEXLIST"); - - ldb_case_test_teardown(state); - return 0; -} - - -struct rename_test_ctx { - struct ldbtest_ctx *ldb_test_ctx; - - struct ldb_dn *basedn; - const char *str_basedn; - - const char *teardown_dn; -}; - -static int ldb_rename_test_setup(void **state) -{ - struct ldbtest_ctx *ldb_test_ctx; - struct rename_test_ctx *rename_test_ctx; - const char *strdn = "dc=rename_test_entry_from"; - - ldbtest_setup((void **) &ldb_test_ctx); - - rename_test_ctx = talloc(ldb_test_ctx, struct rename_test_ctx); - assert_non_null(rename_test_ctx); - rename_test_ctx->ldb_test_ctx = ldb_test_ctx; - assert_non_null(rename_test_ctx->ldb_test_ctx); - - rename_test_ctx->basedn = ldb_dn_new_fmt(rename_test_ctx, - rename_test_ctx->ldb_test_ctx->ldb, - "%s", strdn); - assert_non_null(rename_test_ctx->basedn); - - rename_test_ctx->str_basedn = strdn; - rename_test_ctx->teardown_dn = strdn; - - add_dn_with_cn(ldb_test_ctx, - rename_test_ctx->basedn, - "test_rename_cn_val", - "0123456789abcde0"); - - *state = rename_test_ctx; - return 0; -} - -static int ldb_rename_test_teardown(void **state) -{ - int ret; - struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort(*state, - struct rename_test_ctx); - struct ldbtest_ctx *ldb_test_ctx; - struct ldb_dn *del_dn; - - ldb_test_ctx = rename_test_ctx->ldb_test_ctx; - - del_dn = ldb_dn_new_fmt(rename_test_ctx, - rename_test_ctx->ldb_test_ctx->ldb, - "%s", rename_test_ctx->teardown_dn); - assert_non_null(del_dn); - - ret = ldb_delete(ldb_test_ctx->ldb, del_dn); - assert_int_equal(ret, LDB_SUCCESS); - - assert_dn_doesnt_exist(ldb_test_ctx, - rename_test_ctx->teardown_dn); - - ldbtest_teardown((void **) &ldb_test_ctx); - return 0; -} - -static void test_ldb_rename(void **state) -{ - struct rename_test_ctx *rename_test_ctx = - talloc_get_type_abort(*state, struct rename_test_ctx); - int ret; - const char *str_new_dn = "dc=rename_test_entry_to"; - struct ldb_dn *new_dn; - - new_dn = ldb_dn_new_fmt(rename_test_ctx, - rename_test_ctx->ldb_test_ctx->ldb, - "%s", str_new_dn); - assert_non_null(new_dn); - - ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb, - rename_test_ctx->basedn, - new_dn); - assert_int_equal(ret, LDB_SUCCESS); - - assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn); - assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx, - rename_test_ctx->str_basedn); - rename_test_ctx->teardown_dn = str_new_dn; - - /* FIXME - test the values which didn't change */ -} - -static void test_ldb_rename_from_doesnt_exist(void **state) -{ - struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort( - *state, - struct rename_test_ctx); - int ret; - const char *str_new_dn = "dc=rename_test_entry_to"; - const char *str_bad_old_dn = "dc=rename_test_no_such_entry"; - struct ldb_dn *new_dn; - struct ldb_dn *bad_old_dn; - - new_dn = ldb_dn_new_fmt(rename_test_ctx, - rename_test_ctx->ldb_test_ctx->ldb, - "%s", str_new_dn); - assert_non_null(new_dn); - - bad_old_dn = ldb_dn_new_fmt(rename_test_ctx, - rename_test_ctx->ldb_test_ctx->ldb, - "%s", str_bad_old_dn); - assert_non_null(bad_old_dn); - - assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx, - str_bad_old_dn); - - ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb, - bad_old_dn, new_dn); - assert_int_equal(ret, LDB_ERR_NO_SUCH_OBJECT); - - assert_dn_doesnt_exist(rename_test_ctx->ldb_test_ctx, - str_new_dn); -} - -static void test_ldb_rename_to_exists(void **state) -{ - struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort( - *state, - struct rename_test_ctx); - int ret; - const char *str_new_dn = "dc=rename_test_already_exists"; - struct ldb_dn *new_dn; - - new_dn = ldb_dn_new_fmt(rename_test_ctx, - rename_test_ctx->ldb_test_ctx->ldb, - "%s", str_new_dn); - assert_non_null(new_dn); - - add_dn_with_cn(rename_test_ctx->ldb_test_ctx, - new_dn, - "test_rename_cn_val", - "0123456789abcde1"); - - ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb, - rename_test_ctx->basedn, - new_dn); - assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS); - - /* Old object must still exist */ - assert_dn_exists(rename_test_ctx->ldb_test_ctx, - rename_test_ctx->str_basedn); - - ret = ldb_delete(rename_test_ctx->ldb_test_ctx->ldb, - new_dn); - assert_int_equal(ret, LDB_SUCCESS); - - assert_dn_exists(rename_test_ctx->ldb_test_ctx, - rename_test_ctx->teardown_dn); -} - -static void test_ldb_rename_self(void **state) -{ - struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort( - *state, - struct rename_test_ctx); - int ret; - - /* Oddly enough, this is a success in ldb.. */ - ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb, - rename_test_ctx->basedn, - rename_test_ctx->basedn); - assert_int_equal(ret, LDB_SUCCESS); - - /* Old object must still exist */ - assert_dn_exists(rename_test_ctx->ldb_test_ctx, - rename_test_ctx->str_basedn); -} - -static void test_ldb_rename_dn_case_change(void **state) -{ - struct rename_test_ctx *rename_test_ctx = talloc_get_type_abort( - *state, - struct rename_test_ctx); - int ret; - char *str_new_dn; - struct ldb_dn *new_dn; - unsigned i; - - str_new_dn = talloc_strdup(rename_test_ctx, rename_test_ctx->str_basedn); - assert_non_null(str_new_dn); - for (i = 0; str_new_dn[i]; i++) { - str_new_dn[i] = toupper(str_new_dn[i]); - } - - new_dn = ldb_dn_new_fmt(rename_test_ctx, - rename_test_ctx->ldb_test_ctx->ldb, - "%s", str_new_dn); - assert_non_null(new_dn); - - ret = ldb_rename(rename_test_ctx->ldb_test_ctx->ldb, - rename_test_ctx->basedn, - new_dn); - assert_int_equal(ret, LDB_SUCCESS); - - /* DNs are case insensitive, so both searches will match */ - assert_dn_exists(rename_test_ctx->ldb_test_ctx, str_new_dn); - assert_dn_exists(rename_test_ctx->ldb_test_ctx, - rename_test_ctx->str_basedn); - /* FIXME - test the values didn't change */ -} - -static int ldb_read_only_setup(void **state) -{ - struct ldbtest_ctx *test_ctx; - - ldbtest_setup((void **) &test_ctx); - - *state = test_ctx; - return 0; -} - -static int ldb_read_only_teardown(void **state) -{ - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - ldbtest_teardown((void **) &test_ctx); - return 0; -} - -static void test_read_only(void **state) -{ - struct ldb_context *ro_ldb = NULL; - struct ldb_context *rw_ldb = NULL; - int ret; - TALLOC_CTX *tmp_ctx = NULL; - - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - /* - * Close the ldb context freeing it this will ensure it exists on - * disk and can be opened in read only mode - */ - TALLOC_FREE(test_ctx->ldb); - - /* - * Open the database in read only and read write mode, - * ensure it's opend in read only mode first - */ - ro_ldb = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ro_ldb, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); - assert_int_equal(ret, 0); - - rw_ldb = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(rw_ldb, test_ctx->dbpath, 0, NULL); - assert_int_equal(ret, 0); - - - /* - * Set up a context for the temporary variables - */ - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - /* - * Ensure that we can search the read write database - */ - { - struct ldb_result *result = NULL; - struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb, - "dc=test"); - assert_non_null(dn); - - ret = ldb_search(rw_ldb, tmp_ctx, &result, dn, - LDB_SCOPE_BASE, NULL, NULL); - assert_int_equal(ret, LDB_SUCCESS); - TALLOC_FREE(result); - TALLOC_FREE(dn); - } - - /* - * Ensure that we can search the read only database - */ - { - struct ldb_result *result = NULL; - struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb, - "dc=test"); - assert_non_null(dn); - - ret = ldb_search(ro_ldb, tmp_ctx, &result, dn, - LDB_SCOPE_BASE, NULL, NULL); - assert_int_equal(ret, LDB_SUCCESS); - TALLOC_FREE(result); - TALLOC_FREE(dn); - } - /* - * Ensure that a write to the read only database fails - */ - { - struct ldb_message *msg = NULL; - msg = ldb_msg_new(tmp_ctx); - assert_non_null(msg); - - msg->dn = ldb_dn_new_fmt(msg, ro_ldb, "dc=test"); - assert_non_null(msg->dn); - - ret = ldb_msg_add_string(msg, "cn", "test_cn_val"); - assert_int_equal(ret, 0); - - ret = ldb_msg_add_string(msg, "objectUUID", - "0123456789abcde1"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_add(ro_ldb, msg); - assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM); - TALLOC_FREE(msg); - } - - /* - * Ensure that a write to the read write database succeeds - */ - { - struct ldb_message *msg = NULL; - msg = ldb_msg_new(tmp_ctx); - assert_non_null(msg); - - msg->dn = ldb_dn_new_fmt(msg, rw_ldb, "dc=test"); - assert_non_null(msg->dn); - - ret = ldb_msg_add_string(msg, "cn", "test_cn_val"); - assert_int_equal(ret, 0); - - ret = ldb_msg_add_string(msg, "objectUUID", - "0123456789abcde2"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_add(rw_ldb, msg); - assert_int_equal(ret, LDB_SUCCESS); - TALLOC_FREE(msg); - } - - /* - * Ensure that a delete from a read only database fails - */ - { - struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, ro_ldb, "dc=test"); - assert_non_null(dn); - - ret = ldb_delete(ro_ldb, dn); - assert_int_equal(ret, LDB_ERR_UNWILLING_TO_PERFORM); - TALLOC_FREE(dn); - } - - - /* - * Ensure that a delete from a read write succeeds - */ - { - struct ldb_dn *dn = ldb_dn_new_fmt(tmp_ctx, rw_ldb, "dc=test"); - assert_non_null(dn); - - ret = ldb_delete(rw_ldb, dn); - assert_int_equal(ret, LDB_SUCCESS); - TALLOC_FREE(dn); - } - TALLOC_FREE(tmp_ctx); -} - -static bool unique_values = false; - -static int unique_index_test_module_add( - struct ldb_module *module, - struct ldb_request *req) -{ - if (unique_values) { - struct ldb_message *msg = discard_const(req->op.add.message); - struct ldb_message_element *el = NULL; - el = ldb_msg_find_element(msg, "cn"); - if (el != NULL) { - el->flags |= LDB_FLAG_INTERNAL_FORCE_UNIQUE_INDEX; - } - } - - return ldb_next_request(module, req); -} - -static int unique_index_test_module_init(struct ldb_module *module) -{ - return ldb_next_init(module); -} - -static const struct ldb_module_ops ldb_unique_index_test_module_ops = { - .name = "unique_index_test", - .init_context = unique_index_test_module_init, - .add = unique_index_test_module_add, -}; - -static int ldb_unique_index_test_setup(void **state) -{ - int ret; - struct ldb_ldif *ldif; - struct ldbtest_ctx *ldb_test_ctx; - const char *attrs_ldif = \ - "dn: @ATTRIBUTES\n" - "cn: UNIQUE_INDEX\n" - "\n"; - const char *index_ldif = \ - "dn: @INDEXLIST\n" - "@IDXATTR: cn\n" -#ifdef GUID_IDX - "@IDXGUID: objectUUID\n" - "@IDX_DN_GUID: GUID\n" -#endif - "\n"; - const char *options[] = {"modules:unique_index_test", NULL}; - - - ret = ldb_register_module(&ldb_unique_index_test_module_ops); - assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_ENTRY_ALREADY_EXISTS); - ldbtest_noconn_setup((void **) &ldb_test_ctx); - - - ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options); - assert_int_equal(ret, 0); - - while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) { - ret = ldb_add(ldb_test_ctx->ldb, ldif->msg); - assert_int_equal(ret, LDB_SUCCESS); - } - - while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) { - ret = ldb_add(ldb_test_ctx->ldb, ldif->msg); - assert_int_equal(ret, LDB_SUCCESS); - } - - unique_values = true; - - *state = ldb_test_ctx; - return 0; -} - -static int ldb_unique_index_test_teardown(void **state) -{ - int ret; - struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - struct ldb_dn *del_dn; - - del_dn = ldb_dn_new_fmt(ldb_test_ctx, - ldb_test_ctx->ldb, - "@INDEXLIST"); - assert_non_null(del_dn); - - ret = ldb_delete(ldb_test_ctx->ldb, del_dn); - if (ret != LDB_ERR_NO_SUCH_OBJECT) { - assert_int_equal(ret, LDB_SUCCESS); - } - - assert_dn_doesnt_exist(ldb_test_ctx, - "@INDEXLIST"); - - TALLOC_FREE(del_dn); - - del_dn = ldb_dn_new_fmt(ldb_test_ctx, - ldb_test_ctx->ldb, - "@ATTRIBUTES"); - assert_non_null(del_dn); - - ret = ldb_delete(ldb_test_ctx->ldb, del_dn); - if (ret != LDB_ERR_NO_SUCH_OBJECT) { - assert_int_equal(ret, LDB_SUCCESS); - } - - assert_dn_doesnt_exist(ldb_test_ctx, - "@ATTRIBUTES"); - - ldbtest_teardown((void **) &ldb_test_ctx); - return 0; -} - - -static void test_ldb_add_unique_value_to_unique_index(void **state) -{ - int ret; - struct ldb_message *msg; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - msg = ldb_msg_new(tmp_ctx); - assert_non_null(msg); - - msg->dn = ldb_dn_new_fmt(msg, test_ctx->ldb, "dc=test"); - assert_non_null(msg->dn); - - ret = ldb_msg_add_string(msg, "cn", "test_unique_index"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_msg_add_string(msg, "objectUUID", - "0123456789abcde1"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_add(test_ctx->ldb, msg); - assert_int_equal(ret, LDB_SUCCESS); - - talloc_free(tmp_ctx); -} - -static int ldb_non_unique_index_test_setup(void **state) -{ - int ret; - struct ldb_ldif *ldif; - struct ldbtest_ctx *ldb_test_ctx; - const char *index_ldif = \ - "dn: @INDEXLIST\n" - "@IDXATTR: cn\n" -#ifdef GUID_IDX - "@IDXGUID: objectUUID\n" - "@IDX_DN_GUID: GUID\n" -#endif - "\n"; - const char *options[] = {"modules:unique_index_test", NULL}; - - - ret = ldb_register_module(&ldb_unique_index_test_module_ops); - assert_true(ret == LDB_SUCCESS || ret == LDB_ERR_ENTRY_ALREADY_EXISTS); - ldbtest_noconn_setup((void **) &ldb_test_ctx); - - - ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, options); - assert_int_equal(ret, 0); - - while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) { - ret = ldb_add(ldb_test_ctx->ldb, ldif->msg); - assert_int_equal(ret, LDB_SUCCESS); - } - - unique_values = true; - - *state = ldb_test_ctx; - return 0; -} - -static int ldb_non_unique_index_test_teardown(void **state) -{ - int ret; - struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - struct ldb_dn *del_dn; - - del_dn = ldb_dn_new_fmt(ldb_test_ctx, - ldb_test_ctx->ldb, - "@INDEXLIST"); - assert_non_null(del_dn); - - ret = ldb_delete(ldb_test_ctx->ldb, del_dn); - if (ret != LDB_ERR_NO_SUCH_OBJECT) { - assert_int_equal(ret, LDB_SUCCESS); - } - - assert_dn_doesnt_exist(ldb_test_ctx, - "@INDEXLIST"); - - TALLOC_FREE(del_dn); - - ldbtest_teardown((void **) &ldb_test_ctx); - return 0; -} - -static void test_ldb_add_duplicate_value_to_unique_index(void **state) -{ - int ret; - struct ldb_message *msg01; - struct ldb_message *msg02; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - TALLOC_CTX *tmp_ctx; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - msg01 = ldb_msg_new(tmp_ctx); - assert_non_null(msg01); - - msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01"); - assert_non_null(msg01->dn); - - ret = ldb_msg_add_string(msg01, "cn", "test_unique_index"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_msg_add_string(msg01, "objectUUID", - "0123456789abcde1"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_add(test_ctx->ldb, msg01); - assert_int_equal(ret, LDB_SUCCESS); - - msg02 = ldb_msg_new(tmp_ctx); - assert_non_null(msg02); - - msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02"); - assert_non_null(msg02->dn); - - ret = ldb_msg_add_string(msg02, "cn", "test_unique_index"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_msg_add_string(msg02, "objectUUID", - "0123456789abcde2"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_add(test_ctx->ldb, msg02); - assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION); - talloc_free(tmp_ctx); -} - -static void test_ldb_add_to_index_duplicates_allowed(void **state) -{ - int ret; - struct ldb_message *msg01; - struct ldb_message *msg02; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - TALLOC_CTX *tmp_ctx; - - unique_values = false; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - - msg01 = ldb_msg_new(tmp_ctx); - assert_non_null(msg01); - - msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01"); - assert_non_null(msg01->dn); - - ret = ldb_msg_add_string(msg01, "cn", "test_unique_index"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_msg_add_string(msg01, "objectUUID", - "0123456789abcde1"); - - ret = ldb_add(test_ctx->ldb, msg01); - assert_int_equal(ret, LDB_SUCCESS); - - msg02 = ldb_msg_new(tmp_ctx); - assert_non_null(msg02); - - msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02"); - assert_non_null(msg02->dn); - - ret = ldb_msg_add_string(msg02, "cn", "test_unique_index"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_msg_add_string(msg02, "objectUUID", - "0123456789abcde2"); - - ret = ldb_add(test_ctx->ldb, msg02); - assert_int_equal(ret, LDB_SUCCESS); - talloc_free(tmp_ctx); -} - -static void test_ldb_add_to_index_unique_values_required(void **state) -{ - int ret; - struct ldb_message *msg01; - struct ldb_message *msg02; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - TALLOC_CTX *tmp_ctx; - - unique_values = true; - - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - - msg01 = ldb_msg_new(tmp_ctx); - assert_non_null(msg01); - - msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01"); - assert_non_null(msg01->dn); - - ret = ldb_msg_add_string(msg01, "cn", "test_unique_index"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_msg_add_string(msg01, "objectUUID", - "0123456789abcde1"); - - ret = ldb_add(test_ctx->ldb, msg01); - assert_int_equal(ret, LDB_SUCCESS); - - msg02 = ldb_msg_new(tmp_ctx); - assert_non_null(msg02); - - msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02"); - assert_non_null(msg02->dn); - - ret = ldb_msg_add_string(msg02, "cn", "test_unique_index"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_msg_add_string(msg02, "objectUUID", - "0123456789abcde2"); - - ret = ldb_add(test_ctx->ldb, msg02); - assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION); - talloc_free(tmp_ctx); -} - -static void ldb_debug_string(void *context, enum ldb_debug_level level, - const char *fmt, va_list ap) -{ - - if (level <= LDB_DEBUG_WARNING) { - *((char **)context) = talloc_vasprintf(NULL, fmt, ap); - } -} - -static void test_ldb_unique_index_duplicate_logging(void **state) -{ - int ret; - struct ldb_message *msg01; - struct ldb_message *msg02; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - TALLOC_CTX *tmp_ctx; - char *debug_string = NULL; - char *p = NULL; - - /* The GUID mode is not compatible with this test */ -#ifdef GUID_IDX - return; -#endif - - ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string); - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - msg01 = ldb_msg_new(tmp_ctx); - assert_non_null(msg01); - - msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01"); - assert_non_null(msg01->dn); - - ret = ldb_msg_add_string(msg01, "cn", "test_unique_index"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_msg_add_string(msg01, "objectUUID", - "0123456789abcde1"); - - ret = ldb_add(test_ctx->ldb, msg01); - assert_int_equal(ret, LDB_SUCCESS); - - msg02 = ldb_msg_new(tmp_ctx); - assert_non_null(msg02); - - msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02"); - assert_non_null(msg02->dn); - - ret = ldb_msg_add_string(msg02, "cn", "test_unique_index"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_msg_add_string(msg02, "objectUUID", - "0123456789abcde2"); - - ret = ldb_add(test_ctx->ldb, msg02); - assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION); - - assert_non_null(debug_string); - p = strstr( - debug_string, - "unique index violation on cn " - "in dc=test02, conflicts with dc=test01 in " - "@INDEX:CN:test_unique_index"); - assert_non_null(p); - TALLOC_FREE(debug_string); - talloc_free(tmp_ctx); -} - -static void test_ldb_duplicate_dn_logging(void **state) -{ - int ret; - struct ldb_message *msg01; - struct ldb_message *msg02; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - TALLOC_CTX *tmp_ctx; - char *debug_string = NULL; - - /* The GUID mode is not compatible with this test */ -#ifdef GUID_IDX - return; -#endif - - ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string); - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - msg01 = ldb_msg_new(tmp_ctx); - assert_non_null(msg01); - - msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01"); - assert_non_null(msg01->dn); - - ret = ldb_msg_add_string(msg01, "cn", "test_unique_index01"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_msg_add_string(msg01, "objectUUID", - "0123456789abcde1"); - - ret = ldb_add(test_ctx->ldb, msg01); - assert_int_equal(ret, LDB_SUCCESS); - - msg02 = ldb_msg_new(tmp_ctx); - assert_non_null(msg02); - - msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test01"); - assert_non_null(msg02->dn); - - ret = ldb_msg_add_string(msg02, "cn", "test_unique_index02"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_msg_add_string(msg02, "objectUUID", - "0123456789abcde2"); - - ret = ldb_add(test_ctx->ldb, msg02); - assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS); - - assert_null(debug_string); - talloc_free(tmp_ctx); -} - -static int ldb_guid_index_test_setup(void **state) -{ - int ret; - struct ldb_ldif *ldif; - struct ldbtest_ctx *ldb_test_ctx; - const char *attrs_ldif = \ - "dn: @ATTRIBUTES\n" - "cn: UNIQUE_INDEX\n" - "\n"; - const char *index_ldif = \ - "dn: @INDEXLIST\n" - "@IDXATTR: cn\n" - "@IDXGUID: objectUUID\n" - "@IDX_DN_GUID: GUID\n" - "\n"; - - ldbtest_noconn_setup((void **) &ldb_test_ctx); - - - ret = ldb_connect(ldb_test_ctx->ldb, ldb_test_ctx->dbpath, 0, NULL); - assert_int_equal(ret, 0); - - while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &attrs_ldif))) { - ret = ldb_add(ldb_test_ctx->ldb, ldif->msg); - assert_int_equal(ret, LDB_SUCCESS); - } - - while ((ldif = ldb_ldif_read_string(ldb_test_ctx->ldb, &index_ldif))) { - ret = ldb_add(ldb_test_ctx->ldb, ldif->msg); - assert_int_equal(ret, LDB_SUCCESS); - } - - *state = ldb_test_ctx; - return 0; -} - -static int ldb_guid_index_test_teardown(void **state) -{ - int ret; - struct ldbtest_ctx *ldb_test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - struct ldb_dn *del_dn; - - del_dn = ldb_dn_new_fmt(ldb_test_ctx, - ldb_test_ctx->ldb, - "@INDEXLIST"); - assert_non_null(del_dn); - - ret = ldb_delete(ldb_test_ctx->ldb, del_dn); - if (ret != LDB_ERR_NO_SUCH_OBJECT) { - assert_int_equal(ret, LDB_SUCCESS); - } - - assert_dn_doesnt_exist(ldb_test_ctx, - "@INDEXLIST"); - - TALLOC_FREE(del_dn); - - del_dn = ldb_dn_new_fmt(ldb_test_ctx, - ldb_test_ctx->ldb, - "@ATTRIBUTES"); - assert_non_null(del_dn); - - ret = ldb_delete(ldb_test_ctx->ldb, del_dn); - if (ret != LDB_ERR_NO_SUCH_OBJECT) { - assert_int_equal(ret, LDB_SUCCESS); - } - - assert_dn_doesnt_exist(ldb_test_ctx, - "@ATTRIBUTES"); - - ldbtest_teardown((void **) &ldb_test_ctx); - return 0; -} - - -static void test_ldb_unique_index_duplicate_with_guid(void **state) -{ - int ret; - struct ldb_message *msg01; - struct ldb_message *msg02; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - TALLOC_CTX *tmp_ctx; - char *debug_string = NULL; - char *p = NULL; - - ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string); - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - msg01 = ldb_msg_new(tmp_ctx); - assert_non_null(msg01); - - msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01"); - assert_non_null(msg01->dn); - - ret = ldb_msg_add_string(msg01, "cn", "test_unique_index"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_msg_add_string(msg01, "objectUUID", "0123456789abcdef"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_add(test_ctx->ldb, msg01); - assert_int_equal(ret, LDB_SUCCESS); - - msg02 = ldb_msg_new(tmp_ctx); - assert_non_null(msg02); - - msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test02"); - assert_non_null(msg02->dn); - - ret = ldb_msg_add_string(msg02, "cn", "test_unique_index"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_msg_add_string(msg02, "objectUUID", "0123456789abcde0"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_add(test_ctx->ldb, msg02); - assert_int_equal(ret, LDB_ERR_CONSTRAINT_VIOLATION); - - assert_non_null(debug_string); - p = strstr( - debug_string, - "unique index violation on cn in dc=test02, conflicts with " - "objectUUID 0123456789abcdef in @INDEX:CN:test_unique_index"); - assert_non_null(p); - TALLOC_FREE(debug_string); - talloc_free(tmp_ctx); - ldb_set_debug(test_ctx->ldb, NULL, NULL); -} - -static void test_ldb_guid_index_duplicate_dn_logging(void **state) -{ - int ret; - struct ldb_message *msg01; - struct ldb_message *msg02; - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - TALLOC_CTX *tmp_ctx; - char *debug_string = NULL; - - ldb_set_debug(test_ctx->ldb, ldb_debug_string, &debug_string); - tmp_ctx = talloc_new(test_ctx); - assert_non_null(tmp_ctx); - - msg01 = ldb_msg_new(tmp_ctx); - assert_non_null(msg01); - - msg01->dn = ldb_dn_new_fmt(msg01, test_ctx->ldb, "dc=test01"); - assert_non_null(msg01->dn); - - ret = ldb_msg_add_string(msg01, "cn", "test_unique_index01"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_msg_add_string(msg01, "objectUUID", "0123456789abcdef"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_add(test_ctx->ldb, msg01); - assert_int_equal(ret, LDB_SUCCESS); - - msg02 = ldb_msg_new(tmp_ctx); - assert_non_null(msg02); - - msg02->dn = ldb_dn_new_fmt(msg02, test_ctx->ldb, "dc=test01"); - assert_non_null(msg02->dn); - - ret = ldb_msg_add_string(msg02, "cn", "test_unique_index02"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_msg_add_string(msg02, "objectUUID", "0123456789abcde1"); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_add(test_ctx->ldb, msg02); - assert_int_equal(ret, LDB_ERR_ENTRY_ALREADY_EXISTS); - - assert_null(debug_string); - talloc_free(tmp_ctx); - ldb_set_debug(test_ctx->ldb, NULL, NULL); -} - -static void test_ldb_talloc_destructor_transaction_cleanup(void **state) -{ - struct ldbtest_ctx *test_ctx = NULL; - - test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); - assert_non_null(test_ctx); - - ldb_transaction_start(test_ctx->ldb); - - /* - * Trigger the destructor - */ - TALLOC_FREE(test_ctx->ldb); - - /* - * Now ensure that a new connection can be opened - */ - { - TALLOC_CTX *tctx = talloc_new(test_ctx); - struct ldbtest_ctx *ctx = talloc_zero(tctx, struct ldbtest_ctx); - struct ldb_dn *basedn; - struct ldb_result *result = NULL; - int ret; - - ldbtest_setup((void *)&ctx); - - basedn = ldb_dn_new_fmt(tctx, ctx->ldb, "dc=test"); - assert_non_null(basedn); - - ret = ldb_search(ctx->ldb, - tctx, - &result, - basedn, - LDB_SCOPE_BASE, - NULL, - NULL); - assert_int_equal(ret, 0); - assert_non_null(result); - assert_int_equal(result->count, 0); - - ldbtest_teardown((void *)&ctx); - } -} - -#ifdef TEST_LMDB -static int test_ldb_multiple_connections_callback(struct ldb_request *req, - struct ldb_reply *ares) -{ - int ret; - int pipes[2]; - char buf[2]; - int pid, child_pid; - int wstatus; - - switch (ares->type) { - case LDB_REPLY_ENTRY: - break; - - case LDB_REPLY_REFERRAL: - return LDB_SUCCESS; - - case LDB_REPLY_DONE: - return ldb_request_done(req, LDB_SUCCESS); - } - - { - /* - * We open a new ldb on an ldb that is already open and - * then close it. - * - * If the multiple connection wrapping is correct the - * underlying MDB_env will be left open and we should see - * an active reader in the child we fork next - */ - struct ldb_context *ldb = NULL; - struct tevent_context *ev = NULL; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - - ev = tevent_context_init(mem_ctx); - assert_non_null(ev); - - ldb = ldb_init(mem_ctx, ev); - assert_non_null(ldb); - - ret = ldb_connect(ldb, TEST_BE"://apitest.ldb" , 0, NULL); - if (ret != LDB_SUCCESS) { - return ret; - } - TALLOC_FREE(ldb); - TALLOC_FREE(mem_ctx); - } - - ret = pipe(pipes); - assert_int_equal(ret, 0); - - child_pid = fork(); - if (child_pid == 0) { - struct MDB_env *env = NULL; - struct MDB_envinfo stat; - close(pipes[0]); - - /* - * Check that there are exactly two readers on the MDB file - * backing the ldb. - * - */ - ret = mdb_env_create(&env); - if (ret != 0) { - print_error(__location__ - " mdb_env_create returned (%d)", - ret); - exit(ret); - } - - ret = mdb_env_open(env, - "apitest.ldb", - MDB_NOSUBDIR | MDB_NOTLS, - 0644); - if (ret != 0) { - print_error(__location__ - " mdb_env_open returned (%d)", - ret); - exit(ret); - } - - ret = mdb_env_info(env, &stat); - if (ret != 0) { - print_error(__location__ - " mdb_env_info returned (%d)", - ret); - exit(ret); - } - if (stat.me_numreaders != 2) { - print_error(__location__ - " Incorrect number of readers (%d)", - stat.me_numreaders); - exit(LDB_ERR_CONSTRAINT_VIOLATION); - } - - ret = write(pipes[1], "GO", 2); - if (ret != 2) { - print_error(__location__ - " write returned (%d)", - ret); - exit(LDB_ERR_OPERATIONS_ERROR); - } - exit(LDB_SUCCESS); - } - close(pipes[1]); - ret = read(pipes[0], buf, 2); - assert_int_equal(ret, 2); - - pid = waitpid(child_pid, &wstatus, 0); - assert_int_equal(pid, child_pid); - - assert_true(WIFEXITED(wstatus)); - - assert_int_equal(WEXITSTATUS(wstatus), 0); - return LDB_SUCCESS; - -} - -static void test_ldb_close_with_multiple_connections(void **state) -{ - struct search_test_ctx *search_test_ctx = NULL; - struct ldb_dn *search_dn = NULL; - struct ldb_request *req = NULL; - int ret = 0; - - search_test_ctx = talloc_get_type_abort(*state, struct search_test_ctx); - assert_non_null(search_test_ctx); - - search_dn = ldb_dn_new_fmt(search_test_ctx, - search_test_ctx->ldb_test_ctx->ldb, - "cn=test_search_cn," - "dc=search_test_entry"); - assert_non_null(search_dn); - - /* - * The search just needs to call DONE, we don't care about the - * contents of the search for this test - */ - ret = ldb_build_search_req(&req, - search_test_ctx->ldb_test_ctx->ldb, - search_test_ctx, - search_dn, - LDB_SCOPE_SUBTREE, - "(&(!(filterAttr=*))" - "(cn=test_search_cn))", - NULL, - NULL, - NULL, - test_ldb_multiple_connections_callback, - NULL); - assert_int_equal(ret, 0); - - ret = ldb_request(search_test_ctx->ldb_test_ctx->ldb, req); - assert_int_equal(ret, 0); - - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - assert_int_equal(ret, 0); -} - -#endif - -static void test_transaction_start_across_fork(void **state) -{ - struct ldb_context *ldb1 = NULL; - int ret; - struct ldbtest_ctx *test_ctx = NULL; - int pipes[2]; - char buf[2]; - int wstatus; - pid_t pid, child_pid; - - test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); - - /* - * Open the database - */ - ldb1 = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb1, test_ctx->dbpath, 0, NULL); - assert_int_equal(ret, 0); - - ret = pipe(pipes); - assert_int_equal(ret, 0); - - child_pid = fork(); - if (child_pid == 0) { - close(pipes[0]); - ret = ldb_transaction_start(ldb1); - if (ret != LDB_ERR_PROTOCOL_ERROR) { - print_error(__location__": ldb_transaction_start " - "returned (%d) %s\n", - ret, - ldb1->err_string); - exit(LDB_ERR_OTHER); - } - - ret = write(pipes[1], "GO", 2); - if (ret != 2) { - print_error(__location__ - " write returned (%d)", - ret); - exit(LDB_ERR_OPERATIONS_ERROR); - } - exit(LDB_SUCCESS); - } - close(pipes[1]); - ret = read(pipes[0], buf, 2); - assert_int_equal(ret, 2); - - pid = waitpid(child_pid, &wstatus, 0); - assert_int_equal(pid, child_pid); - - assert_true(WIFEXITED(wstatus)); - - assert_int_equal(WEXITSTATUS(wstatus), 0); -} - -static void test_transaction_commit_across_fork(void **state) -{ - struct ldb_context *ldb1 = NULL; - int ret; - struct ldbtest_ctx *test_ctx = NULL; - int pipes[2]; - char buf[2]; - int wstatus; - pid_t pid, child_pid; - - test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); - - /* - * Open the database - */ - ldb1 = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb1, test_ctx->dbpath, 0, NULL); - assert_int_equal(ret, 0); - - ret = ldb_transaction_start(ldb1); - assert_int_equal(ret, 0); - - ret = pipe(pipes); - assert_int_equal(ret, 0); - - child_pid = fork(); - if (child_pid == 0) { - close(pipes[0]); - ret = ldb_transaction_commit(ldb1); - - if (ret != LDB_ERR_PROTOCOL_ERROR) { - print_error(__location__": ldb_transaction_commit " - "returned (%d) %s\n", - ret, - ldb1->err_string); - exit(LDB_ERR_OTHER); - } - - ret = write(pipes[1], "GO", 2); - if (ret != 2) { - print_error(__location__ - " write returned (%d)", - ret); - exit(LDB_ERR_OPERATIONS_ERROR); - } - exit(LDB_SUCCESS); - } - close(pipes[1]); - ret = read(pipes[0], buf, 2); - assert_int_equal(ret, 2); - - pid = waitpid(child_pid, &wstatus, 0); - assert_int_equal(pid, child_pid); - - assert_true(WIFEXITED(wstatus)); - - assert_int_equal(WEXITSTATUS(wstatus), 0); -} - -static void test_lock_read_across_fork(void **state) -{ - struct ldb_context *ldb1 = NULL; - int ret; - struct ldbtest_ctx *test_ctx = NULL; - int pipes[2]; - char buf[2]; - int wstatus; - pid_t pid, child_pid; - - test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); - - /* - * Open the database - */ - ldb1 = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb1, test_ctx->dbpath, 0, NULL); - assert_int_equal(ret, 0); - - ret = pipe(pipes); - assert_int_equal(ret, 0); - - child_pid = fork(); - if (child_pid == 0) { - struct ldb_dn *basedn; - struct ldb_result *result = NULL; - - close(pipes[0]); - - basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "dc=test"); - assert_non_null(basedn); - - ret = ldb_search(test_ctx->ldb, - test_ctx, - &result, - basedn, - LDB_SCOPE_BASE, - NULL, - NULL); - if (ret != LDB_ERR_PROTOCOL_ERROR) { - print_error(__location__": ldb_search " - "returned (%d) %s\n", - ret, - ldb1->err_string); - exit(LDB_ERR_OTHER); - } - - ret = write(pipes[1], "GO", 2); - if (ret != 2) { - print_error(__location__ - " write returned (%d)", - ret); - exit(LDB_ERR_OPERATIONS_ERROR); - } - exit(LDB_SUCCESS); - } - close(pipes[1]); - ret = read(pipes[0], buf, 2); - assert_int_equal(ret, 2); - - pid = waitpid(child_pid, &wstatus, 0); - assert_int_equal(pid, child_pid); - - assert_true(WIFEXITED(wstatus)); - - assert_int_equal(WEXITSTATUS(wstatus), 0); - - { - /* - * Ensure that the search actually succeeds on the opening - * pid - */ - struct ldb_dn *basedn; - struct ldb_result *result = NULL; - - close(pipes[0]); - - basedn = ldb_dn_new_fmt(test_ctx, test_ctx->ldb, "dc=test"); - assert_non_null(basedn); - - ret = ldb_search(test_ctx->ldb, - test_ctx, - &result, - basedn, - LDB_SCOPE_BASE, - NULL, - NULL); - assert_int_equal(0, ret); - } -} - -static void test_multiple_opens_across_fork(void **state) -{ - struct ldb_context *ldb1 = NULL; - struct ldb_context *ldb2 = NULL; - int ret; - struct ldbtest_ctx *test_ctx = NULL; - int pipes[2]; - char buf[2]; - int wstatus; - pid_t pid, child_pid; - - test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); - - /* - * Open the database again - */ - ldb1 = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); - assert_int_equal(ret, 0); - - ldb2 = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb2, test_ctx->dbpath, 0, NULL); - assert_int_equal(ret, 0); - - ret = pipe(pipes); - assert_int_equal(ret, 0); - - child_pid = fork(); - if (child_pid == 0) { - struct ldb_context *ldb3 = NULL; - - close(pipes[0]); - ldb3 = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL); - if (ret != 0) { - print_error(__location__": ldb_connect returned (%d)\n", - ret); - exit(ret); - } - ret = write(pipes[1], "GO", 2); - if (ret != 2) { - print_error(__location__ - " write returned (%d)", - ret); - exit(LDB_ERR_OPERATIONS_ERROR); - } - exit(LDB_SUCCESS); - } - close(pipes[1]); - ret = read(pipes[0], buf, 2); - assert_int_equal(ret, 2); - - pid = waitpid(child_pid, &wstatus, 0); - assert_int_equal(pid, child_pid); - - assert_true(WIFEXITED(wstatus)); - - assert_int_equal(WEXITSTATUS(wstatus), 0); -} - -int main(int argc, const char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(test_connect, - ldbtest_noconn_setup, - ldbtest_noconn_teardown), - cmocka_unit_test_setup_teardown(test_ldif_message, - ldbtest_noconn_setup, - ldbtest_noconn_teardown), - cmocka_unit_test_setup_teardown(test_ldif_message_redacted, - ldbtest_noconn_setup, - ldbtest_noconn_teardown), - cmocka_unit_test_setup_teardown(test_ldb_add, - ldbtest_setup, - ldbtest_teardown), - cmocka_unit_test_setup_teardown(test_ldb_search, - ldbtest_setup, - ldbtest_teardown), - cmocka_unit_test_setup_teardown(test_ldb_del, - ldbtest_setup, - ldbtest_teardown), - cmocka_unit_test_setup_teardown(test_ldb_del_noexist, - ldbtest_setup, - ldbtest_teardown), - cmocka_unit_test_setup_teardown(test_ldb_handle, - ldbtest_setup, - ldbtest_teardown), - cmocka_unit_test_setup_teardown(test_ldb_build_search_req, - ldbtest_setup, - ldbtest_teardown), - cmocka_unit_test_setup_teardown(test_transactions, - ldbtest_setup, - ldbtest_teardown), - cmocka_unit_test_setup_teardown(test_nested_transactions, - ldbtest_setup, - ldbtest_teardown), - cmocka_unit_test_setup_teardown(test_ldb_modify_add_key, - ldb_modify_test_setup, - ldb_modify_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_modify_extend_key, - ldb_modify_test_setup, - ldb_modify_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_modify_add_key_noval, - ldb_modify_test_setup, - ldb_modify_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_modify_replace_key, - ldb_modify_test_setup, - ldb_modify_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key, - ldb_modify_test_setup, - ldb_modify_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_modify_replace_zero_vals, - ldb_modify_test_setup, - ldb_modify_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_modify_replace_noexist_key_zero_vals, - ldb_modify_test_setup, - ldb_modify_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_modify_del_key, - ldb_modify_test_setup, - ldb_modify_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_modify_del_keyval, - ldb_modify_test_setup, - ldb_modify_test_teardown), - cmocka_unit_test_setup_teardown(test_search_match_none, - ldb_search_test_setup, - ldb_search_test_teardown), - cmocka_unit_test_setup_teardown(test_search_match_one, - ldb_search_test_setup, - ldb_search_test_teardown), - cmocka_unit_test_setup_teardown(test_search_match_filter, - ldb_search_test_setup, - ldb_search_test_teardown), - cmocka_unit_test_setup_teardown(test_search_match_both, - ldb_search_test_setup, - ldb_search_test_teardown), - cmocka_unit_test_setup_teardown(test_search_match_basedn, - ldb_search_test_setup, - ldb_search_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_search_against_transaction, - ldb_search_test_setup, - ldb_search_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_modify_during_unindexed_search, - ldb_search_test_setup, - ldb_search_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_modify_during_indexed_search, - ldb_search_test_setup, - ldb_search_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_rename_during_unindexed_search, - ldb_search_test_setup, - ldb_search_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_rename_during_indexed_search, - ldb_search_test_setup, - ldb_search_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_callback_rename_during_unindexed_search, - ldb_search_test_setup, - ldb_search_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_callback_rename_during_indexed_search, - ldb_search_test_setup, - ldb_search_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_callback_delete_during_unindexed_search, - ldb_search_test_setup, - ldb_search_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_callback_delete_during_indexed_search, - ldb_search_test_setup, - ldb_search_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_modify_during_whole_search, - ldb_search_test_setup, - ldb_search_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_modify_before_ldb_wait, - ldb_search_test_setup, - ldb_search_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_attrs_case_insensitive, - ldb_case_test_setup, - ldb_case_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_attrs_case_handler, - ldb_case_test_setup, - ldb_case_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_attrs_index_handler, - ldb_case_test_setup, - ldb_case_attrs_index_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_rename, - ldb_rename_test_setup, - ldb_rename_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_rename_from_doesnt_exist, - ldb_rename_test_setup, - ldb_rename_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_rename_to_exists, - ldb_rename_test_setup, - ldb_rename_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_rename_self, - ldb_rename_test_setup, - ldb_rename_test_teardown), - cmocka_unit_test_setup_teardown(test_ldb_rename_dn_case_change, - ldb_rename_test_setup, - ldb_rename_test_teardown), - cmocka_unit_test_setup_teardown(test_read_only, - ldb_read_only_setup, - ldb_read_only_teardown), - cmocka_unit_test_setup_teardown( - test_ldb_add_unique_value_to_unique_index, - ldb_unique_index_test_setup, - ldb_unique_index_test_teardown), - cmocka_unit_test_setup_teardown( - test_ldb_add_duplicate_value_to_unique_index, - ldb_unique_index_test_setup, - ldb_unique_index_test_teardown), - cmocka_unit_test_setup_teardown( - test_ldb_add_to_index_duplicates_allowed, - ldb_non_unique_index_test_setup, - ldb_non_unique_index_test_teardown), - cmocka_unit_test_setup_teardown( - test_ldb_add_to_index_unique_values_required, - ldb_non_unique_index_test_setup, - ldb_non_unique_index_test_teardown), - /* These tests are not compatible with mdb */ - cmocka_unit_test_setup_teardown( - test_ldb_unique_index_duplicate_logging, - ldb_unique_index_test_setup, - ldb_unique_index_test_teardown), - cmocka_unit_test_setup_teardown( - test_ldb_duplicate_dn_logging, - ldb_unique_index_test_setup, - ldb_unique_index_test_teardown), - cmocka_unit_test_setup_teardown( - test_ldb_guid_index_duplicate_dn_logging, - ldb_guid_index_test_setup, - ldb_guid_index_test_teardown), - cmocka_unit_test_setup_teardown( - test_ldb_unique_index_duplicate_with_guid, - ldb_guid_index_test_setup, - ldb_guid_index_test_teardown), - cmocka_unit_test_setup_teardown( - test_ldb_talloc_destructor_transaction_cleanup, - ldbtest_setup, - ldbtest_teardown), -#ifdef TEST_LMDB - cmocka_unit_test_setup_teardown( - test_ldb_close_with_multiple_connections, - ldb_search_test_setup, - ldb_search_test_teardown), -#endif - cmocka_unit_test_setup_teardown( - test_transaction_start_across_fork, - ldbtest_setup, - ldbtest_teardown), - cmocka_unit_test_setup_teardown( - test_transaction_commit_across_fork, - ldbtest_setup, - ldbtest_teardown), - cmocka_unit_test_setup_teardown( - test_lock_read_across_fork, - ldbtest_setup, - ldbtest_teardown), - cmocka_unit_test_setup_teardown( - test_multiple_opens_across_fork, - ldbtest_setup, - ldbtest_teardown), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/ldb-2.0.8/tests/ldb_msg.c b/ldb-2.0.8/tests/ldb_msg.c deleted file mode 100644 index 31786a9..0000000 --- a/ldb-2.0.8/tests/ldb_msg.c +++ /dev/null @@ -1,380 +0,0 @@ -/* - * from cmocka.c: - * These headers or their equivalents should be included prior to - * including - * this header file. - * - * #include - * #include - * #include - * - * This allows test applications to use custom definitions of C standard - * library functions and types. - */ -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -struct test_ctx { - struct ldb_message *msg; -}; - -static int ldb_msg_setup(void **state) -{ - struct test_ctx *test_ctx; - - test_ctx = talloc_zero(NULL, struct test_ctx); - assert_non_null(test_ctx); - - test_ctx->msg = ldb_msg_new(test_ctx); - - *state = test_ctx; - return 0; -} - -static int ldb_msg_teardown(void **state) -{ - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - - talloc_free(test_ctx); - return 0; -} - - -static void add_uint_value(struct test_ctx *test_ctx, - struct ldb_message *msg, - const char *attr, - unsigned int x) -{ - int ret; - struct ldb_val v, v_dup; - char s[5]; - snprintf(s, sizeof(s), "%04x", x); - v.data = (uint8_t *)s; - v.length = 4; - v_dup = ldb_val_dup(test_ctx, &v); - assert_non_null(v_dup.data); - assert_ptr_not_equal(v_dup.data, v.data); - assert_int_equal(v_dup.length, 4); - - ret = ldb_msg_add_value(msg, attr, &v_dup, NULL); - assert_int_equal(ret, LDB_SUCCESS); -} - - -static void test_ldb_msg_find_duplicate_val(void **state) -{ - int ret; - unsigned int i; - struct test_ctx *test_ctx = talloc_get_type_abort(*state, - struct test_ctx); - struct ldb_message *msg = test_ctx->msg; - struct ldb_message_element *el; - struct ldb_val dummy; - struct ldb_val *dupe = &dummy; /* so we can tell it was modified to NULL, not left as NULL */ - - ret = ldb_msg_add_empty(msg, "el1", 0, &el); - assert_int_equal(ret, LDB_SUCCESS); - - /* An empty message contains no duplicates */ - ret = ldb_msg_find_duplicate_val(NULL, test_ctx, el, &dupe, 0); - assert_int_equal(ret, LDB_SUCCESS); - assert_null(dupe); - - for (i = 0; i < 5; i++) { - add_uint_value(test_ctx, msg, "el1", i); - } - /* at this point there are no duplicates, and the check uses the naive - quadratic path */ - ret = ldb_msg_find_duplicate_val(NULL, test_ctx, el, &dupe, 0); - assert_int_equal(ret, LDB_SUCCESS); - assert_null(dupe); - - /* add a duplicate, still using quadratric path */ - add_uint_value(test_ctx, msg, "el1", 3); - ret = ldb_msg_find_duplicate_val(NULL, test_ctx, el, &dupe, 0); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(dupe); - assert_int_equal(dupe->length, 4); - assert_memory_equal(dupe->data, "0003", 4); - - /* add some more, triggering algorithmic jump */ - for (i = 2; i < 11; i++) { - add_uint_value(test_ctx, msg, "el1", i); - } - ret = ldb_msg_find_duplicate_val(NULL, test_ctx, el, &dupe, 0); - assert_int_equal(ret, LDB_SUCCESS); - assert_non_null(dupe); - assert_int_equal(dupe->length, 4); - /*XXX not really guaranteed by the API */ - assert_memory_equal(dupe->data, "0002", 4); - - /* start a new element without duplicates, for the clever algorithm */ - ldb_msg_add_empty(msg, "el2", 0, &el); - for (i = 0; i < 12; i++) { - add_uint_value(test_ctx, msg, "el2", i); - } - ret = ldb_msg_find_duplicate_val(NULL, test_ctx, el, &dupe, 0); - assert_int_equal(ret, LDB_SUCCESS); - assert_null(dupe); -} - - -static struct ldb_message_element *new_msg_element(TALLOC_CTX *mem_ctx, - const char *name, - unsigned int value_offset, - unsigned int num_values) -{ - unsigned int i, x; - struct ldb_message_element *el = talloc_zero(mem_ctx, - struct ldb_message_element); - - el->values = talloc_array(el, struct ldb_val, num_values); - for (i = 0; i < num_values; i++) { - struct ldb_val v; - char s[50]; - v.data = (uint8_t *)s; - /* % 3 is to ensure the values list is unsorted */ - x = i + value_offset; - v.length = snprintf(s, sizeof(s), "%u %u", x % 3, x); - el->values[i] = ldb_val_dup(mem_ctx, &v); - } - el->name = name; - el->num_values = num_values; - return el; -} - -static void _assert_element_equal(struct ldb_message_element *a, - struct ldb_message_element *b, - const char * const file, - const int line) -{ - unsigned int i; - _assert_int_equal(a->num_values, b->num_values, file, line); - _assert_int_equal(a->flags, b->flags, file, line); - _assert_string_equal(a->name, b->name, file, line); - for (i = 0; i < a->num_values; i++) { - struct ldb_val *v1 = &a->values[i]; - struct ldb_val *v2 = &b->values[i]; - _assert_int_equal(v1->length, v2->length, file, line); - _assert_memory_equal(v1->data, v2->data, v1->length, - file, line); - } -} - -#define assert_element_equal(a, b) \ - _assert_element_equal((a), (b), \ - __FILE__, __LINE__) - - -static void test_ldb_msg_find_common_values(void **state) -{ - /* we only use the state as a talloc context */ - struct ldb_message_element *el, *el2, *el3, *el4, *el2b, *empty; - struct ldb_message_element *orig, *orig2, *orig3, *orig4; - int ret; - const uint32_t remove_dupes = LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES; - el = new_msg_element(*state, "test", 0, 4); - el2 = new_msg_element(*state, "test", 4, 4); - el3 = new_msg_element(*state, "test", 6, 4); - empty = new_msg_element(*state, "test", 0, 0); - orig = new_msg_element(*state, "test", 0, 4); - orig2 = new_msg_element(*state, "test", 4, 4); - orig3 = new_msg_element(*state, "test", 6, 4); - - /* first round is with short value arrays, using quadratic method */ - /* we expect no collisions here */ - ret = ldb_msg_find_common_values(NULL, *state, el, el2, 0); - assert_int_equal(ret, LDB_SUCCESS); - - /*or here */ - ret = ldb_msg_find_common_values(NULL, *state, el, el3, 0); - assert_int_equal(ret, LDB_SUCCESS); - - /* the same elements in reverse order */ - ret = ldb_msg_find_common_values(NULL, *state, el2, el, 0); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_msg_find_common_values(NULL, *state, el3, el, 0); - assert_int_equal(ret, LDB_SUCCESS); - - /* 6, 7 collide */ - ret = ldb_msg_find_common_values(NULL, *state, el2, el3, 0); - assert_int_equal(ret, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS); - - /* and again */ - ret = ldb_msg_find_common_values(NULL, *state, el3, el2, 0); - assert_int_equal(ret, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS); - - /* make sure the arrays haven't changed */ - assert_element_equal(el, orig); - assert_element_equal(el2, orig2); - assert_element_equal(el3, orig3); - - /* now with the control permisive flag, the first element should be - modified to remove the overlap.*/ - - /* 6, 7 collide, so el2 will only have 4 and 5 */ - ret = ldb_msg_find_common_values(NULL, *state, el2, el3, remove_dupes); - assert_int_equal(ret, LDB_SUCCESS); - - assert_element_equal(el3, orig3); - assert_int_not_equal(el2->num_values, orig2->num_values); - assert_int_equal(el2->num_values, 2); - el2b = new_msg_element(*state, "test", 4, 2); - assert_element_equal(el2, el2b); - - /* now try the same things with a long and a short value list. - this should still trigger the quadratic path. - */ - el2 = new_msg_element(*state, "test", 4, 10); - orig2 = new_msg_element(*state, "test", 4, 10); - - /* no collisions */ - ret = ldb_msg_find_common_values(NULL, *state, el, el2, 0); - assert_int_equal(ret, LDB_SUCCESS); - ret = ldb_msg_find_common_values(NULL, *state, el2, el, 0); - assert_int_equal(ret, LDB_SUCCESS); - - /*collisions */ - ret = ldb_msg_find_common_values(NULL, *state, el3, el2, 0); - assert_int_equal(ret, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS); - - assert_element_equal(el, orig); - assert_element_equal(el2, orig2); - assert_element_equal(el3, orig3); - - /*collisions with permissive flag*/ - ret = ldb_msg_find_common_values(NULL, *state, el3, el2, remove_dupes); - assert_int_equal(ret, LDB_SUCCESS); - assert_element_equal(el2, orig2); - assert_int_equal(el3->num_values, 0); - - /* permutations involving empty elements. - everything should succeed. */ - ret = ldb_msg_find_common_values(NULL, *state, el3, el2, 0); - assert_int_equal(ret, LDB_SUCCESS); - ret = ldb_msg_find_common_values(NULL, *state, el3, el, 0); - assert_int_equal(ret, LDB_SUCCESS); - ret = ldb_msg_find_common_values(NULL, *state, el2, el3, 0); - assert_int_equal(ret, LDB_SUCCESS); - assert_int_equal(el2->num_values, orig2->num_values); - ret = ldb_msg_find_common_values(NULL, *state, el3, el2, remove_dupes); - assert_int_equal(ret, LDB_SUCCESS); - assert_int_equal(el2->num_values, orig2->num_values); - assert_int_equal(el3->num_values, 0); /* el3 is now empty */ - ret = ldb_msg_find_common_values(NULL, *state, el2, el3, remove_dupes); - assert_int_equal(ret, LDB_SUCCESS); - ret = ldb_msg_find_common_values(NULL, *state, el3, empty, 0); - assert_int_equal(ret, LDB_SUCCESS); - ret = ldb_msg_find_common_values(NULL, *state, empty, empty, 0); - assert_int_equal(ret, LDB_SUCCESS); - ret = ldb_msg_find_common_values(NULL, *state, empty, el3, 0); - assert_int_equal(ret, LDB_SUCCESS); - - assert_element_equal(el2, orig2); - assert_element_equal(el, orig); - assert_int_equal(el3->num_values, 0); - - /* now with two large value lists */ - el = new_msg_element(*state, "test", 0, 12); - orig = new_msg_element(*state, "test", 0, 12); - el4 = new_msg_element(*state, "test", 12, 12); - orig4 = new_msg_element(*state, "test", 12, 12); - - /* no collisions */ - ret = ldb_msg_find_common_values(NULL, *state, el, el4, 0); - assert_int_equal(ret, LDB_SUCCESS); - - ret = ldb_msg_find_common_values(NULL, *state, el4, el, 0); - assert_int_equal(ret, LDB_SUCCESS); - - /* collisions */ - ret = ldb_msg_find_common_values(NULL, *state, el4, el2, 0); - assert_int_equal(ret, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS); - ret = ldb_msg_find_common_values(NULL, *state, el2, el4, 0); - assert_int_equal(ret, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS); - ret = ldb_msg_find_common_values(NULL, *state, el2, el, 0); - assert_int_equal(ret, LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS); - - assert_element_equal(el, orig); - assert_element_equal(el2, orig2); - assert_element_equal(el4, orig4); - - /* with permissive control, but no collisions */ - ret = ldb_msg_find_common_values(NULL, *state, el, el4, remove_dupes); - assert_int_equal(ret, LDB_SUCCESS); - ret = ldb_msg_find_common_values(NULL, *state, el4, el, remove_dupes); - assert_int_equal(ret, LDB_SUCCESS); - - assert_element_equal(el, orig); - assert_element_equal(el4, orig4); - - /* now with collisions, thus modifications. - At this stage: - el is 0-11 (inclusive) - e2 is 4-13 - el3 is empty - el4 is 12-23 - */ - ret = ldb_msg_find_common_values(NULL, *state, el4, el2, remove_dupes); - assert_int_equal(ret, LDB_SUCCESS); - assert_element_equal(el2, orig2); - assert_int_not_equal(el4->num_values, orig4->num_values); - /* 4 should start at 14 */ - orig4 = new_msg_element(*state, "test", 14, 10); - assert_element_equal(el4, orig4); - - ret = ldb_msg_find_common_values(NULL, *state, el2, el, remove_dupes); - assert_int_equal(ret, LDB_SUCCESS); - assert_element_equal(el, orig); - assert_int_not_equal(el2->num_values, orig2->num_values); - orig2 = new_msg_element(*state, "test", 12, 2); - assert_element_equal(el2, orig2); - - /* test the empty el against the full elements */ - ret = ldb_msg_find_common_values(NULL, *state, el, empty, 0); - assert_int_equal(ret, LDB_SUCCESS); - ret = ldb_msg_find_common_values(NULL, *state, empty, el, 0); - assert_int_equal(ret, LDB_SUCCESS); - ret = ldb_msg_find_common_values(NULL, *state, el, empty, remove_dupes); - assert_int_equal(ret, LDB_SUCCESS); - ret = ldb_msg_find_common_values(NULL, *state, empty, el, remove_dupes); - assert_int_equal(ret, LDB_SUCCESS); - assert_element_equal(el, orig); - assert_element_equal(empty, el3); - - /* make sure an identical element with a different name is rejected */ - el2 = new_msg_element(*state, "fish", 12, 2); - ret = ldb_msg_find_common_values(NULL, *state, el2, el, remove_dupes); - assert_int_equal(ret, LDB_ERR_INAPPROPRIATE_MATCHING); -} - - - -int main(int argc, const char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(test_ldb_msg_find_duplicate_val, - ldb_msg_setup, - ldb_msg_teardown), - cmocka_unit_test_setup_teardown( - test_ldb_msg_find_common_values, - ldb_msg_setup, - ldb_msg_teardown), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/ldb-2.0.8/tests/ldb_no_lmdb_test.c b/ldb-2.0.8/tests/ldb_no_lmdb_test.c deleted file mode 100644 index 8e5a6ee..0000000 --- a/ldb-2.0.8/tests/ldb_no_lmdb_test.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Ensure lmdb backend is disabled - * - * Copyright (C) Mathieu Parent 2019 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/* - * Ensure lmdb backend is disabled - * - * Setup and tear down code copied from ldb_lmdb_test.c - */ - -/* - * from cmocka.c: - * These headers or their equivalents should be included prior to - * including - * this header file. - * - * #include - * #include - * #include - * - * This allows test applications to use custom definitions of C standard - * library functions and types. - * - */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define TEST_BE "mdb" - -struct ldbtest_ctx { - struct tevent_context *ev; - struct ldb_context *ldb; - - const char *dbfile; - const char *lockfile; /* lockfile is separate */ - - const char *dbpath; -}; - -static void unlink_old_db(struct ldbtest_ctx *test_ctx) -{ - int ret; - - errno = 0; - ret = unlink(test_ctx->lockfile); - if (ret == -1 && errno != ENOENT) { - fail(); - } - - errno = 0; - ret = unlink(test_ctx->dbfile); - if (ret == -1 && errno != ENOENT) { - fail(); - } -} - -static int ldbtest_noconn_setup(void **state) -{ - struct ldbtest_ctx *test_ctx; - - test_ctx = talloc_zero(NULL, struct ldbtest_ctx); - assert_non_null(test_ctx); - - test_ctx->ev = tevent_context_init(test_ctx); - assert_non_null(test_ctx->ev); - - test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev); - assert_non_null(test_ctx->ldb); - - test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb"); - assert_non_null(test_ctx->dbfile); - - test_ctx->lockfile = talloc_asprintf(test_ctx, "%s-lock", - test_ctx->dbfile); - assert_non_null(test_ctx->lockfile); - - test_ctx->dbpath = talloc_asprintf(test_ctx, - TEST_BE"://%s", test_ctx->dbfile); - assert_non_null(test_ctx->dbpath); - - unlink_old_db(test_ctx); - *state = test_ctx; - return 0; -} - -static int ldbtest_noconn_teardown(void **state) -{ - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - - unlink_old_db(test_ctx); - talloc_free(test_ctx); - return 0; -} - -static int ldbtest_setup(void **state) -{ - struct ldbtest_ctx *test_ctx; - int ret; - - ldbtest_noconn_setup((void **) &test_ctx); - - ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL); - assert_int_equal(ret, LDB_ERR_OTHER); - - *state = test_ctx; - return 0; -} - -static int ldbtest_teardown(void **state) -{ - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - ldbtest_noconn_teardown((void **) &test_ctx); - return 0; -} - -static void test_ldb_lmdb_not_found(void **state) -{ - // Actual test in ldbtest_setup - assert_int_equal(0, 0); -} - -int main(int argc, const char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown( - test_ldb_lmdb_not_found, - ldbtest_setup, - ldbtest_teardown), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/ldb-2.0.8/tests/ldb_parse_test.c b/ldb-2.0.8/tests/ldb_parse_test.c deleted file mode 100644 index a739d77..0000000 --- a/ldb-2.0.8/tests/ldb_parse_test.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Tests exercising the ldb parse operations. - * - * Copyright (C) Catalyst.NET Ltd 2017 - * Copyright (C) Michael Hanselmann 2019 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include -#include -#include -#include -#include - -#include "../include/ldb.h" - -struct test_ctx -{ -}; - -static int setup(void **state) -{ - struct test_ctx *ctx; - - ctx = talloc_zero(NULL, struct test_ctx); - assert_non_null(ctx); - - *state = ctx; - - return 0; -} - -static int teardown(void **state) -{ - struct test_ctx *ctx = - talloc_get_type_abort(*state, struct test_ctx); - - talloc_free(ctx); - - return 0; -} - -static void test_roundtrip(TALLOC_CTX *mem_ctx, const char *filter, const char *expected) -{ - struct ldb_parse_tree *tree; - char *serialized; - - assert_non_null(filter); - assert_non_null(expected); - - tree = ldb_parse_tree(mem_ctx, filter); - assert_non_null(tree); - - serialized = ldb_filter_from_tree(mem_ctx, tree); - assert_non_null(serialized); - - assert_string_equal(serialized, expected); -} - -static void test_parse_filtertype(void **state) -{ - struct test_ctx *ctx = - talloc_get_type_abort(*state, struct test_ctx); - - test_roundtrip(ctx, "", "(|(objectClass=*)(distinguishedName=*))"); - test_roundtrip(ctx, "a=value", "(a=value)"); - test_roundtrip(ctx, "(|(foo=bar)(baz=hello))", "(|(foo=bar)(baz=hello))"); - test_roundtrip(ctx, " ", "(|(objectClass=*)(distinguishedName=*))"); -} - -int main(int argc, const char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(test_parse_filtertype, setup, teardown), - }; - - cmocka_set_message_output(CM_OUTPUT_SUBUNIT); - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/ldb-2.0.8/tests/ldb_tdb_test.c b/ldb-2.0.8/tests/ldb_tdb_test.c deleted file mode 100644 index ef91ba5..0000000 --- a/ldb-2.0.8/tests/ldb_tdb_test.c +++ /dev/null @@ -1,389 +0,0 @@ -/* - * lmdb backend specific tests for ldb - * - * Copyright (C) Andrew Bartlett 2018 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -/* - * lmdb backend specific tests for ldb - * - * Setup and tear down code copied from ldb_mod_op_test.c - */ - -/* - * from cmocka.c: - * These headers or their equivalents should be included prior to - * including - * this header file. - * - * #include - * #include - * #include - * - * This allows test applications to use custom definitions of C standard - * library functions and types. - * - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "../ldb_tdb/ldb_tdb.h" -#include "../ldb_key_value/ldb_kv.h" - -#define TEST_BE "tdb" - -struct ldbtest_ctx { - struct tevent_context *ev; - struct ldb_context *ldb; - - const char *dbfile; - - const char *dbpath; -}; - -static void unlink_old_db(struct ldbtest_ctx *test_ctx) -{ - int ret; - - errno = 0; - ret = unlink(test_ctx->dbfile); - if (ret == -1 && errno != ENOENT) { - fail(); - } -} - -static int ldbtest_noconn_setup(void **state) -{ - struct ldbtest_ctx *test_ctx; - - test_ctx = talloc_zero(NULL, struct ldbtest_ctx); - assert_non_null(test_ctx); - - test_ctx->ev = tevent_context_init(test_ctx); - assert_non_null(test_ctx->ev); - - test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev); - assert_non_null(test_ctx->ldb); - - test_ctx->dbfile = talloc_strdup(test_ctx, "apitest.ldb"); - assert_non_null(test_ctx->dbfile); - - test_ctx->dbpath = talloc_asprintf(test_ctx, - TEST_BE"://%s", test_ctx->dbfile); - assert_non_null(test_ctx->dbpath); - - unlink_old_db(test_ctx); - *state = test_ctx; - return 0; -} - -static int ldbtest_noconn_teardown(void **state) -{ - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - - unlink_old_db(test_ctx); - talloc_free(test_ctx); - return 0; -} - -static int ldbtest_setup(void **state) -{ - struct ldbtest_ctx *test_ctx; - int ret; - struct ldb_ldif *ldif; - const char *index_ldif = \ - "dn: @INDEXLIST\n" - "@IDXGUID: objectUUID\n" - "@IDX_DN_GUID: GUID\n" - "\n"; - - ldbtest_noconn_setup((void **) &test_ctx); - - ret = ldb_connect(test_ctx->ldb, test_ctx->dbpath, 0, NULL); - assert_int_equal(ret, 0); - - while ((ldif = ldb_ldif_read_string(test_ctx->ldb, &index_ldif))) { - ret = ldb_add(test_ctx->ldb, ldif->msg); - assert_int_equal(ret, LDB_SUCCESS); - } - *state = test_ctx; - return 0; -} - -static int ldbtest_teardown(void **state) -{ - struct ldbtest_ctx *test_ctx = talloc_get_type_abort(*state, - struct ldbtest_ctx); - ldbtest_noconn_teardown((void **) &test_ctx); - return 0; -} - - -static TDB_CONTEXT *get_tdb_context(struct ldb_context *ldb) -{ - void *data = NULL; - struct ldb_kv_private *ldb_kv = NULL; - TDB_CONTEXT *tdb = NULL; - - data = ldb_module_get_private(ldb->modules); - assert_non_null(data); - - ldb_kv = talloc_get_type(data, struct ldb_kv_private); - assert_non_null(ldb_kv); - - tdb = ldb_kv->tdb; - assert_non_null(tdb); - - return tdb; -} - -static void test_multiple_opens(void **state) -{ - struct ldb_context *ldb1 = NULL; - struct ldb_context *ldb2 = NULL; - struct ldb_context *ldb3 = NULL; - TDB_CONTEXT *tdb1 = NULL; - TDB_CONTEXT *tdb2 = NULL; - TDB_CONTEXT *tdb3 = NULL; - int ret; - struct ldbtest_ctx *test_ctx = NULL; - - test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); - - /* - * Open the database again - */ - ldb1 = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); - assert_int_equal(ret, 0); - - ldb2 = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb2, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); - assert_int_equal(ret, 0); - - ldb3 = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL); - assert_int_equal(ret, 0); - /* - * We now have 3 ldb's open pointing to the same on disk database - * they should all share the same MDB_env - */ - tdb1 = get_tdb_context(ldb1); - tdb2 = get_tdb_context(ldb2); - tdb3 = get_tdb_context(ldb3); - - assert_ptr_equal(tdb1, tdb2); - assert_ptr_equal(tdb1, tdb3); -} - -static void test_multiple_opens_across_fork(void **state) -{ - struct ldb_context *ldb1 = NULL; - struct ldb_context *ldb2 = NULL; - TDB_CONTEXT *tdb1 = NULL; - TDB_CONTEXT *tdb2 = NULL; - int ret; - struct ldbtest_ctx *test_ctx = NULL; - int pipes[2]; - char buf[2]; - int wstatus; - pid_t pid, child_pid; - - test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); - - /* - * Open the database again - */ - ldb1 = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); - assert_int_equal(ret, 0); - - ldb2 = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb2, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); - assert_int_equal(ret, 0); - - tdb1 = get_tdb_context(ldb1); - tdb2 = get_tdb_context(ldb2); - - ret = pipe(pipes); - assert_int_equal(ret, 0); - - child_pid = fork(); - if (child_pid == 0) { - struct ldb_context *ldb3 = NULL; - TDB_CONTEXT *tdb3 = NULL; - - close(pipes[0]); - ldb3 = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL); - if (ret != 0) { - print_error(__location__": ldb_connect returned (%d)\n", - ret); - exit(ret); - } - tdb3 = get_tdb_context(ldb3); - if (tdb1 != tdb2) { - print_error(__location__": tdb1 != tdb2\n"); - exit(LDB_ERR_OPERATIONS_ERROR); - } - if (tdb1 != tdb3) { - print_error(__location__": tdb1 != tdb3\n"); - exit(LDB_ERR_OPERATIONS_ERROR); - } - ret = write(pipes[1], "GO", 2); - if (ret != 2) { - print_error(__location__ - " write returned (%d)", - ret); - exit(LDB_ERR_OPERATIONS_ERROR); - } - exit(LDB_SUCCESS); - } - close(pipes[1]); - ret = read(pipes[0], buf, 2); - assert_int_equal(ret, 2); - - pid = waitpid(child_pid, &wstatus, 0); - assert_int_equal(pid, child_pid); - - assert_true(WIFEXITED(wstatus)); - - assert_int_equal(WEXITSTATUS(wstatus), 0); -} - -static void test_multiple_opens_across_fork_triggers_reopen(void **state) -{ - struct ldb_context *ldb1 = NULL; - struct ldb_context *ldb2 = NULL; - TDB_CONTEXT *tdb1 = NULL; - TDB_CONTEXT *tdb2 = NULL; - int ret; - struct ldbtest_ctx *test_ctx = NULL; - int pipes[2]; - char buf[2]; - int wstatus; - pid_t pid, child_pid; - - test_ctx = talloc_get_type_abort(*state, struct ldbtest_ctx); - - /* - * Open the database again - */ - ldb1 = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb1, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); - assert_int_equal(ret, 0); - - ldb2 = ldb_init(test_ctx, test_ctx->ev); - ret = ldb_connect(ldb2, test_ctx->dbpath, LDB_FLG_RDONLY, NULL); - assert_int_equal(ret, 0); - - tdb1 = get_tdb_context(ldb1); - tdb2 = get_tdb_context(ldb2); - assert_ptr_equal(tdb1, tdb2); - - /* - * Break the internal tdb_reopen() by making a - * transaction - * - * This shows that the tdb_reopen() is called, which is - * essential if the host OS does not have pread() - */ - ret = tdb_transaction_start(tdb1); - assert_int_equal(ret, 0); - - ret = pipe(pipes); - assert_int_equal(ret, 0); - - child_pid = fork(); - if (child_pid == 0) { - struct ldb_context *ldb3 = NULL; - - close(pipes[0]); - ldb3 = ldb_init(test_ctx, test_ctx->ev); - - /* - * This should fail as we have taken out a lock - * against the raw TDB above, and tdb_reopen() - * will fail in that state. - * - * This check matters as tdb_reopen() is important - * if the host does not have pread() - */ - ret = ldb_connect(ldb3, test_ctx->dbpath, 0, NULL); - if (ret == 0) { - print_error(__location__": ldb_connect expected " - "LDB_ERR_OPERATIONS_ERROR " - "returned (%d)\n", - ret); - exit(5000); - } - ret = write(pipes[1], "GO", 2); - if (ret != 2) { - print_error(__location__ - " write returned (%d)", - ret); - exit(LDB_ERR_OPERATIONS_ERROR); - } - exit(LDB_SUCCESS); - } - close(pipes[1]); - ret = read(pipes[0], buf, 2); - assert_int_equal(ret, 2); - - pid = waitpid(child_pid, &wstatus, 0); - assert_int_equal(pid, child_pid); - - assert_true(WIFEXITED(wstatus)); - - assert_int_equal(WEXITSTATUS(wstatus), 0); -} - -int main(int argc, const char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown( - test_multiple_opens, - ldbtest_setup, - ldbtest_teardown), - cmocka_unit_test_setup_teardown( - test_multiple_opens_across_fork, - ldbtest_setup, - ldbtest_teardown), - cmocka_unit_test_setup_teardown( - test_multiple_opens_across_fork_triggers_reopen, - ldbtest_setup, - ldbtest_teardown), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/ldb-2.0.8/tests/photo.ldif b/ldb-2.0.8/tests/photo.ldif deleted file mode 100644 index 95ab065..0000000 --- a/ldb-2.0.8/tests/photo.ldif +++ /dev/null @@ -1,5 +0,0 @@ -dn: cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST -changetype: modify -add: jpegPhoto -jpegPhoto:< file://tests/samba4.png - diff --git a/ldb-2.0.8/tests/python/api.py b/ldb-2.0.8/tests/python/api.py deleted file mode 100755 index 4d55566..0000000 --- a/ldb-2.0.8/tests/python/api.py +++ /dev/null @@ -1,3326 +0,0 @@ -#!/usr/bin/env python3 -# Simple tests for the ldb python bindings. -# Copyright (C) 2007 Jelmer Vernooij - -import os -from unittest import TestCase -import sys -import gc -import time -import ldb -import shutil - -PY3 = sys.version_info > (3, 0) - -TDB_PREFIX = "tdb://" -MDB_PREFIX = "mdb://" - -MDB_INDEX_OBJ = { - "dn": "@INDEXLIST", - "@IDXONE": [b"1"], - "@IDXGUID": [b"objectUUID"], - "@IDX_DN_GUID": [b"GUID"] -} - - -def tempdir(): - import tempfile - try: - dir_prefix = os.path.join(os.environ["SELFTEST_PREFIX"], "tmp") - except KeyError: - dir_prefix = None - return tempfile.mkdtemp(dir=dir_prefix) - - -class NoContextTests(TestCase): - - def test_valid_attr_name(self): - self.assertTrue(ldb.valid_attr_name("foo")) - self.assertFalse(ldb.valid_attr_name("24foo")) - - def test_timestring(self): - self.assertEqual("19700101000000.0Z", ldb.timestring(0)) - self.assertEqual("20071119191012.0Z", ldb.timestring(1195499412)) - - def test_string_to_time(self): - self.assertEqual(0, ldb.string_to_time("19700101000000.0Z")) - self.assertEqual(1195499412, ldb.string_to_time("20071119191012.0Z")) - - def test_binary_encode(self): - encoded = ldb.binary_encode(b'test\\x') - decoded = ldb.binary_decode(encoded) - self.assertEqual(decoded, b'test\\x') - - encoded2 = ldb.binary_encode('test\\x') - self.assertEqual(encoded2, encoded) - - -class LdbBaseTest(TestCase): - def setUp(self): - super(LdbBaseTest, self).setUp() - try: - if self.prefix is None: - self.prefix = TDB_PREFIX - except AttributeError: - self.prefix = TDB_PREFIX - - def tearDown(self): - super(LdbBaseTest, self).tearDown() - - def url(self): - return self.prefix + self.filename - - def flags(self): - if self.prefix == MDB_PREFIX: - return ldb.FLG_NOSYNC - else: - return 0 - - -class SimpleLdb(LdbBaseTest): - - def setUp(self): - super(SimpleLdb, self).setUp() - self.testdir = tempdir() - self.filename = os.path.join(self.testdir, "test.ldb") - self.ldb = ldb.Ldb(self.url(), flags=self.flags()) - try: - self.ldb.add(self.index) - except AttributeError: - pass - - def tearDown(self): - shutil.rmtree(self.testdir) - super(SimpleLdb, self).tearDown() - # Ensure the LDB is closed now, so we close the FD - del(self.ldb) - - def test_connect(self): - ldb.Ldb(self.url(), flags=self.flags()) - - def test_connect_none(self): - ldb.Ldb() - - def test_connect_later(self): - x = ldb.Ldb() - x.connect(self.url(), flags=self.flags()) - - def test_repr(self): - x = ldb.Ldb() - self.assertTrue(repr(x).startswith("]", repr(x.modules())) - - def test_firstmodule_none(self): - x = ldb.Ldb() - self.assertEqual(x.firstmodule, None) - - def test_firstmodule_tdb(self): - x = ldb.Ldb(self.url(), flags=self.flags()) - mod = x.firstmodule - self.assertEqual(repr(mod), "") - - def test_search(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - self.assertEqual(len(l.search()), 0) - - def test_search_controls(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - self.assertEqual(len(l.search(controls=["paged_results:0:5"])), 0) - - def test_utf8_ldb_Dn(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - dn = ldb.Dn(l, (b'a=' + b'\xc4\x85\xc4\x87\xc4\x99\xc5\x82\xc5\x84\xc3\xb3\xc5\x9b\xc5\xba\xc5\xbc').decode('utf8')) - - def test_utf8_encoded_ldb_Dn(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - dn_encoded_utf8 = b'a=' + b'\xc4\x85\xc4\x87\xc4\x99\xc5\x82\xc5\x84\xc3\xb3\xc5\x9b\xc5\xba\xc5\xbc' - try: - dn = ldb.Dn(l, dn_encoded_utf8) - except UnicodeDecodeError as e: - raise - except TypeError as te: - if PY3: - p3errors = ["argument 2 must be str, not bytes", - "Can't convert 'bytes' object to str implicitly"] - self.assertIn(str(te), p3errors) - else: - raise - - def test_search_attrs(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - self.assertEqual(len(l.search(ldb.Dn(l, ""), ldb.SCOPE_SUBTREE, "(dc=*)", ["dc"])), 0) - - def test_search_string_dn(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - self.assertEqual(len(l.search("", ldb.SCOPE_SUBTREE, "(dc=*)", ["dc"])), 0) - - def test_search_attr_string(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - self.assertRaises(TypeError, l.search, attrs="dc") - self.assertRaises(TypeError, l.search, attrs=b"dc") - - def test_opaque(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - l.set_opaque("my_opaque", l) - self.assertTrue(l.get_opaque("my_opaque") is not None) - self.assertEqual(None, l.get_opaque("unknown")) - - def test_search_scope_base_empty_db(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - self.assertEqual(len(l.search(ldb.Dn(l, "dc=foo1"), - ldb.SCOPE_BASE)), 0) - - def test_search_scope_onelevel_empty_db(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - self.assertEqual(len(l.search(ldb.Dn(l, "dc=foo1"), - ldb.SCOPE_ONELEVEL)), 0) - - def test_delete(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - self.assertRaises(ldb.LdbError, lambda: l.delete(ldb.Dn(l, "dc=foo2"))) - - def test_delete_w_unhandled_ctrl(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=foo1") - m["b"] = [b"a"] - m["objectUUID"] = b"0123456789abcdef" - l.add(m) - self.assertRaises(ldb.LdbError, lambda: l.delete(m.dn, ["search_options:1:2"])) - l.delete(m.dn) - - def test_contains(self): - name = self.url() - l = ldb.Ldb(name, flags=self.flags()) - self.assertFalse(ldb.Dn(l, "dc=foo3") in l) - l = ldb.Ldb(name, flags=self.flags()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=foo3") - m["b"] = ["a"] - m["objectUUID"] = b"0123456789abcdef" - l.add(m) - try: - self.assertTrue(ldb.Dn(l, "dc=foo3") in l) - self.assertFalse(ldb.Dn(l, "dc=foo4") in l) - finally: - l.delete(m.dn) - - def test_get_config_basedn(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - self.assertEqual(None, l.get_config_basedn()) - - def test_get_root_basedn(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - self.assertEqual(None, l.get_root_basedn()) - - def test_get_schema_basedn(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - self.assertEqual(None, l.get_schema_basedn()) - - def test_get_default_basedn(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - self.assertEqual(None, l.get_default_basedn()) - - def test_add(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=foo4") - m["bla"] = b"bla" - m["objectUUID"] = b"0123456789abcdef" - self.assertEqual(len(l.search()), 0) - l.add(m) - try: - self.assertEqual(len(l.search()), 1) - finally: - l.delete(ldb.Dn(l, "dc=foo4")) - - def test_search_iterator(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - s = l.search_iterator() - s.abandon() - try: - for me in s: - self.fail() - self.fail() - except RuntimeError as re: - pass - try: - s.abandon() - self.fail() - except RuntimeError as re: - pass - try: - s.result() - self.fail() - except RuntimeError as re: - pass - - s = l.search_iterator() - count = 0 - for me in s: - self.assertTrue(isinstance(me, ldb.Message)) - count += 1 - r = s.result() - self.assertEqual(len(r), 0) - self.assertEqual(count, 0) - - m1 = ldb.Message() - m1.dn = ldb.Dn(l, "dc=foo4") - m1["bla"] = b"bla" - m1["objectUUID"] = b"0123456789abcdef" - l.add(m1) - try: - s = l.search_iterator() - msgs = [] - for me in s: - self.assertTrue(isinstance(me, ldb.Message)) - count += 1 - msgs.append(me) - r = s.result() - self.assertEqual(len(r), 0) - self.assertEqual(len(msgs), 1) - self.assertEqual(msgs[0].dn, m1.dn) - - m2 = ldb.Message() - m2.dn = ldb.Dn(l, "dc=foo5") - m2["bla"] = b"bla" - m2["objectUUID"] = b"0123456789abcdee" - l.add(m2) - - s = l.search_iterator() - msgs = [] - for me in s: - self.assertTrue(isinstance(me, ldb.Message)) - count += 1 - msgs.append(me) - r = s.result() - self.assertEqual(len(r), 0) - self.assertEqual(len(msgs), 2) - if msgs[0].dn == m1.dn: - self.assertEqual(msgs[0].dn, m1.dn) - self.assertEqual(msgs[1].dn, m2.dn) - else: - self.assertEqual(msgs[0].dn, m2.dn) - self.assertEqual(msgs[1].dn, m1.dn) - - s = l.search_iterator() - msgs = [] - for me in s: - self.assertTrue(isinstance(me, ldb.Message)) - count += 1 - msgs.append(me) - break - try: - s.result() - self.fail() - except RuntimeError as re: - pass - for me in s: - self.assertTrue(isinstance(me, ldb.Message)) - count += 1 - msgs.append(me) - break - for me in s: - self.fail() - - r = s.result() - self.assertEqual(len(r), 0) - self.assertEqual(len(msgs), 2) - if msgs[0].dn == m1.dn: - self.assertEqual(msgs[0].dn, m1.dn) - self.assertEqual(msgs[1].dn, m2.dn) - else: - self.assertEqual(msgs[0].dn, m2.dn) - self.assertEqual(msgs[1].dn, m1.dn) - finally: - l.delete(ldb.Dn(l, "dc=foo4")) - l.delete(ldb.Dn(l, "dc=foo5")) - - def test_add_text(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=foo4") - m["bla"] = "bla" - m["objectUUID"] = b"0123456789abcdef" - self.assertEqual(len(l.search()), 0) - l.add(m) - try: - self.assertEqual(len(l.search()), 1) - finally: - l.delete(ldb.Dn(l, "dc=foo4")) - - def test_add_w_unhandled_ctrl(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=foo4") - m["bla"] = b"bla" - self.assertEqual(len(l.search()), 0) - self.assertRaises(ldb.LdbError, lambda: l.add(m, ["search_options:1:2"])) - - def test_add_dict(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - m = {"dn": ldb.Dn(l, "dc=foo5"), - "bla": b"bla", - "objectUUID": b"0123456789abcdef"} - self.assertEqual(len(l.search()), 0) - l.add(m) - try: - self.assertEqual(len(l.search()), 1) - finally: - l.delete(ldb.Dn(l, "dc=foo5")) - - def test_add_dict_text(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - m = {"dn": ldb.Dn(l, "dc=foo5"), - "bla": "bla", - "objectUUID": b"0123456789abcdef"} - self.assertEqual(len(l.search()), 0) - l.add(m) - try: - self.assertEqual(len(l.search()), 1) - finally: - l.delete(ldb.Dn(l, "dc=foo5")) - - def test_add_dict_string_dn(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - m = {"dn": "dc=foo6", "bla": b"bla", - "objectUUID": b"0123456789abcdef"} - self.assertEqual(len(l.search()), 0) - l.add(m) - try: - self.assertEqual(len(l.search()), 1) - finally: - l.delete(ldb.Dn(l, "dc=foo6")) - - def test_add_dict_bytes_dn(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - m = {"dn": b"dc=foo6", "bla": b"bla", - "objectUUID": b"0123456789abcdef"} - self.assertEqual(len(l.search()), 0) - l.add(m) - try: - self.assertEqual(len(l.search()), 1) - finally: - l.delete(ldb.Dn(l, "dc=foo6")) - - def test_rename(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=foo7") - m["bla"] = b"bla" - m["objectUUID"] = b"0123456789abcdef" - self.assertEqual(len(l.search()), 0) - l.add(m) - try: - l.rename(ldb.Dn(l, "dc=foo7"), ldb.Dn(l, "dc=bar")) - self.assertEqual(len(l.search()), 1) - finally: - l.delete(ldb.Dn(l, "dc=bar")) - - def test_rename_string_dns(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=foo8") - m["bla"] = b"bla" - m["objectUUID"] = b"0123456789abcdef" - self.assertEqual(len(l.search()), 0) - l.add(m) - self.assertEqual(len(l.search()), 1) - try: - l.rename("dc=foo8", "dc=bar") - self.assertEqual(len(l.search()), 1) - finally: - l.delete(ldb.Dn(l, "dc=bar")) - - def test_rename_bad_string_dns(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=foo8") - m["bla"] = b"bla" - m["objectUUID"] = b"0123456789abcdef" - self.assertEqual(len(l.search()), 0) - l.add(m) - self.assertEqual(len(l.search()), 1) - self.assertRaises(ldb.LdbError,lambda: l.rename("dcXfoo8", "dc=bar")) - self.assertRaises(ldb.LdbError,lambda: l.rename("dc=foo8", "dcXbar")) - l.delete(ldb.Dn(l, "dc=foo8")) - - def test_empty_dn(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - self.assertEqual(0, len(l.search())) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=empty") - m["objectUUID"] = b"0123456789abcdef" - l.add(m) - rm = l.search() - self.assertEqual(1, len(rm)) - self.assertEqual(set(["dn", "distinguishedName", "objectUUID"]), - set(rm[0].keys())) - - rm = l.search(m.dn) - self.assertEqual(1, len(rm)) - self.assertEqual(set(["dn", "distinguishedName", "objectUUID"]), - set(rm[0].keys())) - rm = l.search(m.dn, attrs=["blah"]) - self.assertEqual(1, len(rm)) - self.assertEqual(0, len(rm[0])) - - def test_modify_delete(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=modifydelete") - m["bla"] = [b"1234"] - m["objectUUID"] = b"0123456789abcdef" - l.add(m) - rm = l.search(m.dn)[0] - self.assertEqual([b"1234"], list(rm["bla"])) - try: - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=modifydelete") - m["bla"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "bla") - self.assertEqual(ldb.FLAG_MOD_DELETE, m["bla"].flags()) - l.modify(m) - rm = l.search(m.dn) - self.assertEqual(1, len(rm)) - self.assertEqual(set(["dn", "distinguishedName", "objectUUID"]), - set(rm[0].keys())) - rm = l.search(m.dn, attrs=["bla"]) - self.assertEqual(1, len(rm)) - self.assertEqual(0, len(rm[0])) - finally: - l.delete(ldb.Dn(l, "dc=modifydelete")) - - def test_modify_delete_text(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=modifydelete") - m.text["bla"] = ["1234"] - m["objectUUID"] = b"0123456789abcdef" - l.add(m) - rm = l.search(m.dn)[0] - self.assertEqual(["1234"], list(rm.text["bla"])) - try: - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=modifydelete") - m["bla"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "bla") - self.assertEqual(ldb.FLAG_MOD_DELETE, m["bla"].flags()) - l.modify(m) - rm = l.search(m.dn) - self.assertEqual(1, len(rm)) - self.assertEqual(set(["dn", "distinguishedName", "objectUUID"]), - set(rm[0].keys())) - rm = l.search(m.dn, attrs=["bla"]) - self.assertEqual(1, len(rm)) - self.assertEqual(0, len(rm[0])) - finally: - l.delete(ldb.Dn(l, "dc=modifydelete")) - - def test_modify_add(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=add") - m["bla"] = [b"1234"] - m["objectUUID"] = b"0123456789abcdef" - l.add(m) - try: - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=add") - m["bla"] = ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla") - self.assertEqual(ldb.FLAG_MOD_ADD, m["bla"].flags()) - l.modify(m) - rm = l.search(m.dn)[0] - self.assertEqual(3, len(rm)) - self.assertEqual([b"1234", b"456"], list(rm["bla"])) - finally: - l.delete(ldb.Dn(l, "dc=add")) - - def test_modify_add_text(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=add") - m.text["bla"] = ["1234"] - m["objectUUID"] = b"0123456789abcdef" - l.add(m) - try: - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=add") - m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") - self.assertEqual(ldb.FLAG_MOD_ADD, m["bla"].flags()) - l.modify(m) - rm = l.search(m.dn)[0] - self.assertEqual(3, len(rm)) - self.assertEqual(["1234", "456"], list(rm.text["bla"])) - finally: - l.delete(ldb.Dn(l, "dc=add")) - - def test_modify_replace(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=modify2") - m["bla"] = [b"1234", b"456"] - m["objectUUID"] = b"0123456789abcdef" - l.add(m) - try: - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=modify2") - m["bla"] = ldb.MessageElement([b"789"], ldb.FLAG_MOD_REPLACE, "bla") - self.assertEqual(ldb.FLAG_MOD_REPLACE, m["bla"].flags()) - l.modify(m) - rm = l.search(m.dn)[0] - self.assertEqual(3, len(rm)) - self.assertEqual([b"789"], list(rm["bla"])) - rm = l.search(m.dn, attrs=["bla"])[0] - self.assertEqual(1, len(rm)) - finally: - l.delete(ldb.Dn(l, "dc=modify2")) - - def test_modify_replace_text(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=modify2") - m.text["bla"] = ["1234", "456"] - m["objectUUID"] = b"0123456789abcdef" - l.add(m) - try: - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=modify2") - m["bla"] = ldb.MessageElement(["789"], ldb.FLAG_MOD_REPLACE, "bla") - self.assertEqual(ldb.FLAG_MOD_REPLACE, m["bla"].flags()) - l.modify(m) - rm = l.search(m.dn)[0] - self.assertEqual(3, len(rm)) - self.assertEqual(["789"], list(rm.text["bla"])) - rm = l.search(m.dn, attrs=["bla"])[0] - self.assertEqual(1, len(rm)) - finally: - l.delete(ldb.Dn(l, "dc=modify2")) - - def test_modify_flags_change(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=add") - m["bla"] = [b"1234"] - m["objectUUID"] = b"0123456789abcdef" - l.add(m) - try: - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=add") - m["bla"] = ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla") - self.assertEqual(ldb.FLAG_MOD_ADD, m["bla"].flags()) - l.modify(m) - rm = l.search(m.dn)[0] - self.assertEqual(3, len(rm)) - self.assertEqual([b"1234", b"456"], list(rm["bla"])) - - # Now create another modify, but switch the flags before we do it - m["bla"] = ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla") - m["bla"].set_flags(ldb.FLAG_MOD_DELETE) - l.modify(m) - rm = l.search(m.dn, attrs=["bla"])[0] - self.assertEqual(1, len(rm)) - self.assertEqual([b"1234"], list(rm["bla"])) - finally: - l.delete(ldb.Dn(l, "dc=add")) - - def test_modify_flags_change_text(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=add") - m.text["bla"] = ["1234"] - m["objectUUID"] = b"0123456789abcdef" - l.add(m) - try: - m = ldb.Message() - m.dn = ldb.Dn(l, "dc=add") - m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") - self.assertEqual(ldb.FLAG_MOD_ADD, m["bla"].flags()) - l.modify(m) - rm = l.search(m.dn)[0] - self.assertEqual(3, len(rm)) - self.assertEqual(["1234", "456"], list(rm.text["bla"])) - - # Now create another modify, but switch the flags before we do it - m["bla"] = ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla") - m["bla"].set_flags(ldb.FLAG_MOD_DELETE) - l.modify(m) - rm = l.search(m.dn, attrs=["bla"])[0] - self.assertEqual(1, len(rm)) - self.assertEqual(["1234"], list(rm.text["bla"])) - finally: - l.delete(ldb.Dn(l, "dc=add")) - - def test_transaction_commit(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - l.transaction_start() - m = ldb.Message(ldb.Dn(l, "dc=foo9")) - m["foo"] = [b"bar"] - m["objectUUID"] = b"0123456789abcdef" - l.add(m) - l.transaction_commit() - l.delete(m.dn) - - def test_transaction_cancel(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - l.transaction_start() - m = ldb.Message(ldb.Dn(l, "dc=foo10")) - m["foo"] = [b"bar"] - m["objectUUID"] = b"0123456789abcdee" - l.add(m) - l.transaction_cancel() - self.assertEqual(0, len(l.search(ldb.Dn(l, "dc=foo10")))) - - def test_set_debug(self): - def my_report_fn(level, text): - pass - l = ldb.Ldb(self.url(), flags=self.flags()) - l.set_debug(my_report_fn) - - def test_zero_byte_string(self): - """Testing we do not get trapped in the \0 byte in a property string.""" - l = ldb.Ldb(self.url(), flags=self.flags()) - l.add({ - "dn": b"dc=somedn", - "objectclass": b"user", - "cN": b"LDAPtestUSER", - "givenname": b"ldap", - "displayname": b"foo\0bar", - "objectUUID": b"0123456789abcdef" - }) - res = l.search(expression="(dn=dc=somedn)") - self.assertEqual(b"foo\0bar", res[0]["displayname"][0]) - - def test_no_crash_broken_expr(self): - l = ldb.Ldb(self.url(), flags=self.flags()) - self.assertRaises(ldb.LdbError, lambda: l.search("", ldb.SCOPE_SUBTREE, "&(dc=*)(dn=*)", ["dc"])) - -# Run the SimpleLdb tests against an lmdb backend - - -class SimpleLdbLmdb(SimpleLdb): - - def setUp(self): - if os.environ.get('HAVE_LMDB', '1') == '0': - self.skipTest("No lmdb backend") - self.prefix = MDB_PREFIX - self.index = MDB_INDEX_OBJ - super(SimpleLdbLmdb, self).setUp() - - def tearDown(self): - super(SimpleLdbLmdb, self).tearDown() - - -class SimpleLdbNoLmdb(LdbBaseTest): - - def setUp(self): - if os.environ.get('HAVE_LMDB', '1') != '0': - self.skipTest("lmdb backend enabled") - self.prefix = MDB_PREFIX - self.index = MDB_INDEX_OBJ - super(SimpleLdbNoLmdb, self).setUp() - - def tearDown(self): - super(SimpleLdbNoLmdb, self).tearDown() - - def test_lmdb_disabled(self): - self.testdir = tempdir() - self.filename = os.path.join(self.testdir, "test.ldb") - try: - self.ldb = ldb.Ldb(self.url(), flags=self.flags()) - self.fail("Should have failed on missing LMDB") - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_OTHER) - - -class SearchTests(LdbBaseTest): - def tearDown(self): - shutil.rmtree(self.testdir) - super(SearchTests, self).tearDown() - - # Ensure the LDB is closed now, so we close the FD - del(self.l) - - def setUp(self): - super(SearchTests, self).setUp() - self.testdir = tempdir() - self.filename = os.path.join(self.testdir, "search_test.ldb") - options = ["modules:rdn_name"] - if hasattr(self, 'IDXCHECK'): - options.append("disable_full_db_scan_for_self_test:1") - self.l = ldb.Ldb(self.url(), - flags=self.flags(), - options=options) - try: - self.l.add(self.index) - except AttributeError: - pass - - self.l.add({"dn": "@ATTRIBUTES", - "DC": "CASE_INSENSITIVE"}) - - # Note that we can't use the name objectGUID here, as we - # want to stay clear of the objectGUID handler in LDB and - # instead use just the 16 bytes raw, which we just keep - # to printable chars here for ease of handling. - - self.l.add({"dn": "DC=SAMBA,DC=ORG", - "name": b"samba.org", - "objectUUID": b"0123456789abcdef"}) - self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"0123456789abcde1"}) - self.l.add({"dn": "OU=USERS,DC=SAMBA,DC=ORG", - "name": b"Users", - "x": "z", "y": "a", - "objectUUID": b"0123456789abcde2"}) - self.l.add({"dn": "OU=OU1,DC=SAMBA,DC=ORG", - "name": b"OU #1", - "x": "y", "y": "a", - "objectUUID": b"0123456789abcde3"}) - self.l.add({"dn": "OU=OU2,DC=SAMBA,DC=ORG", - "name": b"OU #2", - "x": "y", "y": "a", - "objectUUID": b"0123456789abcde4"}) - self.l.add({"dn": "OU=OU3,DC=SAMBA,DC=ORG", - "name": b"OU #3", - "x": "y", "y": "a", - "objectUUID": b"0123456789abcde5"}) - self.l.add({"dn": "OU=OU4,DC=SAMBA,DC=ORG", - "name": b"OU #4", - "x": "y", "y": "a", - "objectUUID": b"0123456789abcde6"}) - self.l.add({"dn": "OU=OU5,DC=SAMBA,DC=ORG", - "name": b"OU #5", - "x": "y", "y": "a", - "objectUUID": b"0123456789abcde7"}) - self.l.add({"dn": "OU=OU6,DC=SAMBA,DC=ORG", - "name": b"OU #6", - "x": "y", "y": "a", - "objectUUID": b"0123456789abcde8"}) - self.l.add({"dn": "OU=OU7,DC=SAMBA,DC=ORG", - "name": b"OU #7", - "x": "y", "y": "a", - "objectUUID": b"0123456789abcde9"}) - self.l.add({"dn": "OU=OU8,DC=SAMBA,DC=ORG", - "name": b"OU #8", - "x": "y", "y": "a", - "objectUUID": b"0123456789abcde0"}) - self.l.add({"dn": "OU=OU9,DC=SAMBA,DC=ORG", - "name": b"OU #9", - "x": "y", "y": "a", - "objectUUID": b"0123456789abcdea"}) - self.l.add({"dn": "OU=OU10,DC=SAMBA,DC=ORG", - "name": b"OU #10", - "x": "y", "y": "a", - "objectUUID": b"0123456789abcdeb"}) - self.l.add({"dn": "OU=OU11,DC=SAMBA,DC=ORG", - "name": b"OU #10", - "x": "y", "y": "a", - "objectUUID": b"0123456789abcdec"}) - self.l.add({"dn": "OU=OU12,DC=SAMBA,DC=ORG", - "name": b"OU #10", - "x": "y", "y": "b", - "objectUUID": b"0123456789abcded"}) - self.l.add({"dn": "OU=OU13,DC=SAMBA,DC=ORG", - "name": b"OU #10", - "x": "x", "y": "b", - "objectUUID": b"0123456789abcdee"}) - self.l.add({"dn": "OU=OU14,DC=SAMBA,DC=ORG", - "name": b"OU #10", - "x": "x", "y": "b", - "objectUUID": b"0123456789abcd01"}) - self.l.add({"dn": "OU=OU15,DC=SAMBA,DC=ORG", - "name": b"OU #10", - "x": "x", "y": "b", - "objectUUID": b"0123456789abcd02"}) - self.l.add({"dn": "OU=OU16,DC=SAMBA,DC=ORG", - "name": b"OU #10", - "x": "x", "y": "b", - "objectUUID": b"0123456789abcd03"}) - self.l.add({"dn": "OU=OU17,DC=SAMBA,DC=ORG", - "name": b"OU #10", - "x": "x", "y": "b", - "objectUUID": b"0123456789abcd04"}) - self.l.add({"dn": "OU=OU18,DC=SAMBA,DC=ORG", - "name": b"OU #10", - "x": "x", "y": "b", - "objectUUID": b"0123456789abcd05"}) - self.l.add({"dn": "OU=OU19,DC=SAMBA,DC=ORG", - "name": b"OU #10", - "x": "x", "y": "b", - "objectUUID": b"0123456789abcd06"}) - self.l.add({"dn": "OU=OU20,DC=SAMBA,DC=ORG", - "name": b"OU #10", - "x": "x", "y": "b", - "objectUUID": b"0123456789abcd07"}) - self.l.add({"dn": "OU=OU21,DC=SAMBA,DC=ORG", - "name": b"OU #10", - "x": "x", "y": "c", - "objectUUID": b"0123456789abcd08"}) - self.l.add({"dn": "OU=OU22,DC=SAMBA,DC=ORG", - "name": b"OU #10", - "x": "x", "y": "c", - "objectUUID": b"0123456789abcd09"}) - - def test_base(self): - """Testing a search""" - - res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_BASE) - self.assertEqual(len(res11), 1) - - def test_base_lower(self): - """Testing a search""" - - res11 = self.l.search(base="OU=OU11,DC=samba,DC=org", - scope=ldb.SCOPE_BASE) - self.assertEqual(len(res11), 1) - - def test_base_or(self): - """Testing a search""" - - res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_BASE, - expression="(|(ou=ou11)(ou=ou12))") - self.assertEqual(len(res11), 1) - - def test_base_or2(self): - """Testing a search""" - - res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_BASE, - expression="(|(x=y)(y=b))") - self.assertEqual(len(res11), 1) - - def test_base_and(self): - """Testing a search""" - - res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_BASE, - expression="(&(ou=ou11)(ou=ou12))") - self.assertEqual(len(res11), 0) - - def test_base_and2(self): - """Testing a search""" - - res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_BASE, - expression="(&(x=y)(y=a))") - self.assertEqual(len(res11), 1) - - def test_base_false(self): - """Testing a search""" - - res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_BASE, - expression="(|(ou=ou13)(ou=ou12))") - self.assertEqual(len(res11), 0) - - def test_check_base_false(self): - """Testing a search""" - res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_BASE, - expression="(|(ou=ou13)(ou=ou12))") - self.assertEqual(len(res11), 0) - - def test_check_base_error(self): - """Testing a search""" - checkbaseonsearch = {"dn": "@OPTIONS", - "checkBaseOnSearch": b"TRUE"} - try: - self.l.add(checkbaseonsearch) - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) - m = ldb.Message.from_dict(self.l, - checkbaseonsearch) - self.l.modify(m) - - try: - res11 = self.l.search(base="OU=OU11x,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_BASE, - expression="(|(ou=ou13)(ou=ou12))") - self.fail("Should have failed on missing base") - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_NO_SUCH_OBJECT) - - def test_subtree_and(self): - """Testing a search""" - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(&(ou=ou11)(ou=ou12))") - self.assertEqual(len(res11), 0) - - def test_subtree_and2(self): - """Testing a search""" - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(&(x=y)(|(y=b)(y=c)))") - self.assertEqual(len(res11), 1) - - def test_subtree_and2_lower(self): - """Testing a search""" - - res11 = self.l.search(base="DC=samba,DC=org", - scope=ldb.SCOPE_SUBTREE, - expression="(&(x=y)(|(y=b)(y=c)))") - self.assertEqual(len(res11), 1) - - def test_subtree_or(self): - """Testing a search""" - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(|(ou=ou11)(ou=ou12))") - self.assertEqual(len(res11), 2) - - def test_subtree_or2(self): - """Testing a search""" - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(|(x=y)(y=b))") - self.assertEqual(len(res11), 20) - - def test_subtree_or3(self): - """Testing a search""" - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(|(x=y)(y=b)(y=c))") - self.assertEqual(len(res11), 22) - - def test_one_and(self): - """Testing a search""" - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_ONELEVEL, - expression="(&(ou=ou11)(ou=ou12))") - self.assertEqual(len(res11), 0) - - def test_one_and2(self): - """Testing a search""" - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_ONELEVEL, - expression="(&(x=y)(y=b))") - self.assertEqual(len(res11), 1) - - def test_one_or(self): - """Testing a search""" - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_ONELEVEL, - expression="(|(ou=ou11)(ou=ou12))") - self.assertEqual(len(res11), 2) - - def test_one_or2(self): - """Testing a search""" - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_ONELEVEL, - expression="(|(x=y)(y=b))") - self.assertEqual(len(res11), 20) - - def test_one_or2_lower(self): - """Testing a search""" - - res11 = self.l.search(base="DC=samba,DC=org", - scope=ldb.SCOPE_ONELEVEL, - expression="(|(x=y)(y=b))") - self.assertEqual(len(res11), 20) - - def test_one_unindexable(self): - """Testing a search""" - - try: - res11 = self.l.search(base="DC=samba,DC=org", - scope=ldb.SCOPE_ONELEVEL, - expression="(y=b*)") - if hasattr(self, 'IDX') and \ - not hasattr(self, 'IDXONE') and \ - hasattr(self, 'IDXCHECK'): - self.fail("Should have failed as un-indexed search") - - self.assertEqual(len(res11), 9) - - except ldb.LdbError as err: - enum = err.args[0] - estr = err.args[1] - self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING) - self.assertIn(estr, "ldb FULL SEARCH disabled") - - def test_one_unindexable_presence(self): - """Testing a search""" - - try: - res11 = self.l.search(base="DC=samba,DC=org", - scope=ldb.SCOPE_ONELEVEL, - expression="(y=*)") - if hasattr(self, 'IDX') and \ - not hasattr(self, 'IDXONE') and \ - hasattr(self, 'IDXCHECK'): - self.fail("Should have failed as un-indexed search") - - self.assertEqual(len(res11), 24) - - except ldb.LdbError as err: - enum = err.args[0] - estr = err.args[1] - self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING) - self.assertIn(estr, "ldb FULL SEARCH disabled") - - def test_subtree_and_or(self): - """Testing a search""" - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(&(|(x=z)(y=b))(x=x)(y=c))") - self.assertEqual(len(res11), 0) - - def test_subtree_and_or2(self): - """Testing a search""" - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(&(x=x)(y=c)(|(x=z)(y=b)))") - self.assertEqual(len(res11), 0) - - def test_subtree_and_or3(self): - """Testing a search""" - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(&(|(ou=ou11)(ou=ou10))(|(x=y)(y=b)(y=c)))") - self.assertEqual(len(res11), 2) - - def test_subtree_and_or4(self): - """Testing a search""" - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(&(|(x=y)(y=b)(y=c))(|(ou=ou11)(ou=ou10)))") - self.assertEqual(len(res11), 2) - - def test_subtree_and_or5(self): - """Testing a search""" - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(&(|(x=y)(y=b)(y=c))(ou=ou11))") - self.assertEqual(len(res11), 1) - - def test_subtree_or_and(self): - """Testing a search""" - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(|(x=x)(y=c)(&(x=z)(y=b)))") - self.assertEqual(len(res11), 10) - - def test_subtree_large_and_unique(self): - """Testing a search""" - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(&(ou=ou10)(y=a))") - self.assertEqual(len(res11), 1) - - def test_subtree_and_none(self): - """Testing a search""" - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(&(ou=ouX)(y=a))") - self.assertEqual(len(res11), 0) - - def test_subtree_and_idx_record(self): - """Testing a search against the index record""" - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(@IDXDN=DC=SAMBA,DC=ORG)") - self.assertEqual(len(res11), 0) - - def test_subtree_and_idxone_record(self): - """Testing a search against the index record""" - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(@IDXONE=DC=SAMBA,DC=ORG)") - self.assertEqual(len(res11), 0) - - def test_subtree_unindexable(self): - """Testing a search""" - - try: - res11 = self.l.search(base="DC=samba,DC=org", - scope=ldb.SCOPE_SUBTREE, - expression="(y=b*)") - if hasattr(self, 'IDX') and \ - hasattr(self, 'IDXCHECK'): - self.fail("Should have failed as un-indexed search") - - self.assertEqual(len(res11), 9) - - except ldb.LdbError as err: - enum = err.args[0] - estr = err.args[1] - self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING) - self.assertIn(estr, "ldb FULL SEARCH disabled") - - def test_subtree_unindexable_presence(self): - """Testing a search""" - - try: - res11 = self.l.search(base="DC=samba,DC=org", - scope=ldb.SCOPE_SUBTREE, - expression="(y=*)") - if hasattr(self, 'IDX') and \ - hasattr(self, 'IDXCHECK'): - self.fail("Should have failed as un-indexed search") - - self.assertEqual(len(res11), 24) - - except ldb.LdbError as err: - enum = err.args[0] - estr = err.args[1] - self.assertEqual(enum, ldb.ERR_INAPPROPRIATE_MATCHING) - self.assertIn(estr, "ldb FULL SEARCH disabled") - - def test_dn_filter_one(self): - """Testing that a dn= filter succeeds - (or fails with disallowDNFilter - set and IDXGUID or (IDX and not IDXONE) mode) - when the scope is SCOPE_ONELEVEL. - - This should be made more consistent, but for now lock in - the behaviour - - """ - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_ONELEVEL, - expression="(dn=OU=OU1,DC=SAMBA,DC=ORG)") - if hasattr(self, 'disallowDNFilter') and \ - hasattr(self, 'IDX') and \ - (hasattr(self, 'IDXGUID') or - ((hasattr(self, 'IDXONE') == False and hasattr(self, 'IDX')))): - self.assertEqual(len(res11), 0) - else: - self.assertEqual(len(res11), 1) - - def test_dn_filter_subtree(self): - """Testing that a dn= filter succeeds - (or fails with disallowDNFilter set) - when the scope is SCOPE_SUBTREE""" - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(dn=OU=OU1,DC=SAMBA,DC=ORG)") - if hasattr(self, 'disallowDNFilter') \ - and hasattr(self, 'IDX'): - self.assertEqual(len(res11), 0) - else: - self.assertEqual(len(res11), 1) - - def test_dn_filter_base(self): - """Testing that (incorrectly) a dn= filter works - when the scope is SCOPE_BASE""" - - res11 = self.l.search(base="OU=OU1,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_BASE, - expression="(dn=OU=OU1,DC=SAMBA,DC=ORG)") - - # At some point we should fix this, but it isn't trivial - self.assertEqual(len(res11), 1) - - def test_distinguishedName_filter_one(self): - """Testing that a distinguishedName= filter succeeds - when the scope is SCOPE_ONELEVEL. - - This should be made more consistent, but for now lock in - the behaviour - - """ - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_ONELEVEL, - expression="(distinguishedName=OU=OU1,DC=SAMBA,DC=ORG)") - self.assertEqual(len(res11), 1) - - def test_distinguishedName_filter_subtree(self): - """Testing that a distinguishedName= filter succeeds - when the scope is SCOPE_SUBTREE""" - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(distinguishedName=OU=OU1,DC=SAMBA,DC=ORG)") - self.assertEqual(len(res11), 1) - - def test_distinguishedName_filter_base(self): - """Testing that (incorrectly) a distinguishedName= filter works - when the scope is SCOPE_BASE""" - - res11 = self.l.search(base="OU=OU1,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_BASE, - expression="(distinguishedName=OU=OU1,DC=SAMBA,DC=ORG)") - - # At some point we should fix this, but it isn't trivial - self.assertEqual(len(res11), 1) - - def test_bad_dn_filter_base(self): - """Testing that a dn= filter on an invalid DN works - when the scope is SCOPE_BASE but - returns zero results""" - - res11 = self.l.search(base="OU=OU1,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_BASE, - expression="(dn=OU=OU1,DC=SAMBA,DCXXXX)") - - # At some point we should fix this, but it isn't trivial - self.assertEqual(len(res11), 0) - - - def test_bad_dn_filter_one(self): - """Testing that a dn= filter succeeds but returns zero - results when the DN is not valid on a SCOPE_ONELEVEL search - - """ - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_ONELEVEL, - expression="(dn=OU=OU1,DC=SAMBA,DCXXXX)") - self.assertEqual(len(res11), 0) - - def test_bad_dn_filter_subtree(self): - """Testing that a dn= filter succeeds but returns zero - results when the DN is not valid on a SCOPE_SUBTREE search - - """ - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(dn=OU=OU1,DC=SAMBA,DCXXXX)") - self.assertEqual(len(res11), 0) - - def test_bad_distinguishedName_filter_base(self): - """Testing that a distinguishedName= filter on an invalid DN works - when the scope is SCOPE_BASE but - returns zero results""" - - res11 = self.l.search(base="OU=OU1,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_BASE, - expression="(distinguishedName=OU=OU1,DC=SAMBA,DCXXXX)") - - # At some point we should fix this, but it isn't trivial - self.assertEqual(len(res11), 0) - - - def test_bad_distinguishedName_filter_one(self): - """Testing that a distinguishedName= filter succeeds but returns zero - results when the DN is not valid on a SCOPE_ONELEVEL search - - """ - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_ONELEVEL, - expression="(distinguishedName=OU=OU1,DC=SAMBA,DCXXXX)") - self.assertEqual(len(res11), 0) - - def test_bad_distinguishedName_filter_subtree(self): - """Testing that a distinguishedName= filter succeeds but returns zero - results when the DN is not valid on a SCOPE_SUBTREE search - - """ - - res11 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(distinguishedName=OU=OU1,DC=SAMBA,DCXXXX)") - self.assertEqual(len(res11), 0) - - def test_bad_dn_search_base(self): - """Testing with a bad base DN (SCOPE_BASE)""" - - try: - res11 = self.l.search(base="OU=OU1,DC=SAMBA,DCXXX", - scope=ldb.SCOPE_BASE) - self.fail("Should have failed with ERR_INVALID_DN_SYNTAX") - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_INVALID_DN_SYNTAX) - - - def test_bad_dn_search_one(self): - """Testing with a bad base DN (SCOPE_ONELEVEL)""" - - try: - res11 = self.l.search(base="DC=SAMBA,DCXXXX", - scope=ldb.SCOPE_ONELEVEL) - self.fail("Should have failed with ERR_INVALID_DN_SYNTAX") - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_INVALID_DN_SYNTAX) - - def test_bad_dn_search_subtree(self): - """Testing with a bad base DN (SCOPE_SUBTREE)""" - - try: - res11 = self.l.search(base="DC=SAMBA,DCXXXX", - scope=ldb.SCOPE_SUBTREE) - self.fail("Should have failed with ERR_INVALID_DN_SYNTAX") - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_INVALID_DN_SYNTAX) - - - -# Run the search tests against an lmdb backend -class SearchTestsLmdb(SearchTests): - - def setUp(self): - if os.environ.get('HAVE_LMDB', '1') == '0': - self.skipTest("No lmdb backend") - self.prefix = MDB_PREFIX - self.index = MDB_INDEX_OBJ - super(SearchTestsLmdb, self).setUp() - - def tearDown(self): - super(SearchTestsLmdb, self).tearDown() - - -class IndexedSearchTests(SearchTests): - """Test searches using the index, to ensure the index doesn't - break things""" - - def setUp(self): - super(IndexedSearchTests, self).setUp() - self.l.add({"dn": "@INDEXLIST", - "@IDXATTR": [b"x", b"y", b"ou"]}) - self.IDX = True - - -class IndexedCheckSearchTests(IndexedSearchTests): - """Test searches using the index, to ensure the index doesn't - break things (full scan disabled)""" - - def setUp(self): - self.IDXCHECK = True - super(IndexedCheckSearchTests, self).setUp() - - -class IndexedSearchDnFilterTests(SearchTests): - """Test searches using the index, to ensure the index doesn't - break things""" - - def setUp(self): - super(IndexedSearchDnFilterTests, self).setUp() - self.l.add({"dn": "@OPTIONS", - "disallowDNFilter": "TRUE"}) - self.disallowDNFilter = True - - self.l.add({"dn": "@INDEXLIST", - "@IDXATTR": [b"x", b"y", b"ou"]}) - self.IDX = True - - -class IndexedAndOneLevelSearchTests(SearchTests): - """Test searches using the index including @IDXONE, to ensure - the index doesn't break things""" - - def setUp(self): - super(IndexedAndOneLevelSearchTests, self).setUp() - self.l.add({"dn": "@INDEXLIST", - "@IDXATTR": [b"x", b"y", b"ou"], - "@IDXONE": [b"1"]}) - self.IDX = True - self.IDXONE = True - - -class IndexedCheckedAndOneLevelSearchTests(IndexedAndOneLevelSearchTests): - """Test searches using the index including @IDXONE, to ensure - the index doesn't break things (full scan disabled)""" - - def setUp(self): - self.IDXCHECK = True - super(IndexedCheckedAndOneLevelSearchTests, self).setUp() - - -class IndexedAndOneLevelDNFilterSearchTests(SearchTests): - """Test searches using the index including @IDXONE, to ensure - the index doesn't break things""" - - def setUp(self): - super(IndexedAndOneLevelDNFilterSearchTests, self).setUp() - self.l.add({"dn": "@OPTIONS", - "disallowDNFilter": "TRUE", - "checkBaseOnSearch": "TRUE"}) - self.disallowDNFilter = True - self.checkBaseOnSearch = True - - self.l.add({"dn": "@INDEXLIST", - "@IDXATTR": [b"x", b"y", b"ou"], - "@IDXONE": [b"1"]}) - self.IDX = True - self.IDXONE = True - - -class GUIDIndexedSearchTests(SearchTests): - """Test searches using the index, to ensure the index doesn't - break things""" - - def setUp(self): - self.index = {"dn": "@INDEXLIST", - "@IDXATTR": [b"x", b"y", b"ou"], - "@IDXGUID": [b"objectUUID"], - "@IDX_DN_GUID": [b"GUID"]} - super(GUIDIndexedSearchTests, self).setUp() - - self.IDXGUID = True - self.IDXONE = True - - -class GUIDIndexedDNFilterSearchTests(SearchTests): - """Test searches using the index, to ensure the index doesn't - break things""" - - def setUp(self): - self.index = {"dn": "@INDEXLIST", - "@IDXATTR": [b"x", b"y", b"ou"], - "@IDXGUID": [b"objectUUID"], - "@IDX_DN_GUID": [b"GUID"]} - super(GUIDIndexedDNFilterSearchTests, self).setUp() - self.l.add({"dn": "@OPTIONS", - "disallowDNFilter": "TRUE", - "checkBaseOnSearch": "TRUE"}) - self.disallowDNFilter = True - self.checkBaseOnSearch = True - self.IDX = True - self.IDXGUID = True - - -class GUIDAndOneLevelIndexedSearchTests(SearchTests): - """Test searches using the index including @IDXONE, to ensure - the index doesn't break things""" - - def setUp(self): - self.index = {"dn": "@INDEXLIST", - "@IDXATTR": [b"x", b"y", b"ou"], - "@IDXGUID": [b"objectUUID"], - "@IDX_DN_GUID": [b"GUID"]} - super(GUIDAndOneLevelIndexedSearchTests, self).setUp() - self.l.add({"dn": "@OPTIONS", - "disallowDNFilter": "TRUE", - "checkBaseOnSearch": "TRUE"}) - self.disallowDNFilter = True - self.checkBaseOnSearch = True - self.IDX = True - self.IDXGUID = True - self.IDXONE = True - - -class GUIDIndexedSearchTestsLmdb(GUIDIndexedSearchTests): - - def setUp(self): - if os.environ.get('HAVE_LMDB', '1') == '0': - self.skipTest("No lmdb backend") - self.prefix = MDB_PREFIX - super(GUIDIndexedSearchTestsLmdb, self).setUp() - - def tearDown(self): - super(GUIDIndexedSearchTestsLmdb, self).tearDown() - - -class GUIDIndexedDNFilterSearchTestsLmdb(GUIDIndexedDNFilterSearchTests): - - def setUp(self): - if os.environ.get('HAVE_LMDB', '1') == '0': - self.skipTest("No lmdb backend") - self.prefix = MDB_PREFIX - super(GUIDIndexedDNFilterSearchTestsLmdb, self).setUp() - - def tearDown(self): - super(GUIDIndexedDNFilterSearchTestsLmdb, self).tearDown() - - -class GUIDAndOneLevelIndexedSearchTestsLmdb(GUIDAndOneLevelIndexedSearchTests): - - def setUp(self): - if os.environ.get('HAVE_LMDB', '1') == '0': - self.skipTest("No lmdb backend") - self.prefix = MDB_PREFIX - super(GUIDAndOneLevelIndexedSearchTestsLmdb, self).setUp() - - def tearDown(self): - super(GUIDAndOneLevelIndexedSearchTestsLmdb, self).tearDown() - - -class AddModifyTests(LdbBaseTest): - def tearDown(self): - shutil.rmtree(self.testdir) - super(AddModifyTests, self).tearDown() - - # Ensure the LDB is closed now, so we close the FD - del(self.l) - - def setUp(self): - super(AddModifyTests, self).setUp() - self.testdir = tempdir() - self.filename = os.path.join(self.testdir, "add_test.ldb") - self.l = ldb.Ldb(self.url(), - flags=self.flags(), - options=["modules:rdn_name"]) - try: - self.l.add(self.index) - except AttributeError: - pass - - self.l.add({"dn": "DC=SAMBA,DC=ORG", - "name": b"samba.org", - "objectUUID": b"0123456789abcdef"}) - self.l.add({"dn": "@ATTRIBUTES", - "objectUUID": "UNIQUE_INDEX"}) - - def test_add_dup(self): - self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"0123456789abcde1"}) - try: - self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"0123456789abcde2"}) - self.fail("Should have failed adding dupliate entry") - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) - - def test_add_bad(self): - try: - self.l.add({"dn": "BAD,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"0123456789abcde1"}) - self.fail("Should have failed adding entry with invalid DN") - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_INVALID_DN_SYNTAX) - - def test_add_del_add(self): - self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"0123456789abcde1"}) - self.l.delete("OU=DUP,DC=SAMBA,DC=ORG") - self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"0123456789abcde2"}) - - def test_add_move_add(self): - self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"0123456789abcde1"}) - self.l.rename("OU=DUP,DC=SAMBA,DC=ORG", - "OU=DUP2,DC=SAMBA,DC=ORG") - self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"0123456789abcde2"}) - - def test_add_move_fail_move_move(self): - self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"0123456789abcde1"}) - self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"0123456789abcde2"}) - - res2 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(objectUUID=0123456789abcde1)") - self.assertEqual(len(res2), 1) - self.assertEqual(str(res2[0].dn), "OU=DUP,DC=SAMBA,DC=ORG") - - res3 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(objectUUID=0123456789abcde2)") - self.assertEqual(len(res3), 1) - self.assertEqual(str(res3[0].dn), "OU=DUP2,DC=SAMBA,DC=ORG") - - try: - self.l.rename("OU=DUP,DC=SAMBA,DC=ORG", - "OU=DUP2,DC=SAMBA,DC=ORG") - self.fail("Should have failed on duplicate DN") - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) - - self.l.rename("OU=DUP2,DC=SAMBA,DC=ORG", - "OU=DUP3,DC=SAMBA,DC=ORG") - - self.l.rename("OU=DUP,DC=SAMBA,DC=ORG", - "OU=DUP2,DC=SAMBA,DC=ORG") - - res2 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(objectUUID=0123456789abcde1)") - self.assertEqual(len(res2), 1) - self.assertEqual(str(res2[0].dn), "OU=DUP2,DC=SAMBA,DC=ORG") - - res3 = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(objectUUID=0123456789abcde2)") - self.assertEqual(len(res3), 1) - self.assertEqual(str(res3[0].dn), "OU=DUP3,DC=SAMBA,DC=ORG") - - def test_move_missing(self): - try: - self.l.rename("OU=DUP,DC=SAMBA,DC=ORG", - "OU=DUP2,DC=SAMBA,DC=ORG") - self.fail("Should have failed on missing") - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_NO_SUCH_OBJECT) - - def test_move_missing2(self): - self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"0123456789abcde2"}) - - try: - self.l.rename("OU=DUP,DC=SAMBA,DC=ORG", - "OU=DUP2,DC=SAMBA,DC=ORG") - self.fail("Should have failed on missing") - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_NO_SUCH_OBJECT) - - def test_move_bad(self): - self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"0123456789abcde2"}) - - try: - self.l.rename("OUXDUP,DC=SAMBA,DC=ORG", - "OU=DUP2,DC=SAMBA,DC=ORG") - self.fail("Should have failed on invalid DN") - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_INVALID_DN_SYNTAX) - - def test_move_bad2(self): - self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"0123456789abcde2"}) - - try: - self.l.rename("OU=DUP,DC=SAMBA,DC=ORG", - "OUXDUP2,DC=SAMBA,DC=ORG") - self.fail("Should have failed on missing") - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_INVALID_DN_SYNTAX) - - def test_move_fail_move_add(self): - self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"0123456789abcde1"}) - self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"0123456789abcde2"}) - try: - self.l.rename("OU=DUP,DC=SAMBA,DC=ORG", - "OU=DUP2,DC=SAMBA,DC=ORG") - self.fail("Should have failed on duplicate DN") - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) - - self.l.rename("OU=DUP2,DC=SAMBA,DC=ORG", - "OU=DUP3,DC=SAMBA,DC=ORG") - - self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"0123456789abcde3"}) - - -class AddModifyTestsLmdb(AddModifyTests): - - def setUp(self): - if os.environ.get('HAVE_LMDB', '1') == '0': - self.skipTest("No lmdb backend") - self.prefix = MDB_PREFIX - self.index = MDB_INDEX_OBJ - super(AddModifyTestsLmdb, self).setUp() - - def tearDown(self): - super(AddModifyTestsLmdb, self).tearDown() - - -class IndexedAddModifyTests(AddModifyTests): - """Test searches using the index, to ensure the index doesn't - break things""" - - def setUp(self): - if not hasattr(self, 'index'): - self.index = {"dn": "@INDEXLIST", - "@IDXATTR": [b"x", b"y", b"ou", b"objectUUID", b"z"], - "@IDXONE": [b"1"]} - super(IndexedAddModifyTests, self).setUp() - - def test_duplicate_GUID(self): - try: - self.l.add({"dn": "OU=DUPGUID,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"0123456789abcdef"}) - self.fail("Should have failed adding dupliate GUID") - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_CONSTRAINT_VIOLATION) - - def test_duplicate_name_dup_GUID(self): - self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"a123456789abcdef"}) - try: - self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"a123456789abcdef"}) - self.fail("Should have failed adding dupliate GUID") - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) - - def test_duplicate_name_dup_GUID2(self): - self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"abc3456789abcdef"}) - try: - self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"aaa3456789abcdef"}) - self.fail("Should have failed adding dupliate DN") - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) - - # Checking the GUID didn't stick in the index - self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"aaa3456789abcdef"}) - - def test_add_dup_guid_add(self): - self.l.add({"dn": "OU=DUP,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"0123456789abcde1"}) - try: - self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"0123456789abcde1"}) - self.fail("Should have failed on duplicate GUID") - - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_CONSTRAINT_VIOLATION) - - self.l.add({"dn": "OU=DUP2,DC=SAMBA,DC=ORG", - "name": b"Admins", - "x": "z", "y": "a", - "objectUUID": b"0123456789abcde2"}) - - def test_duplicate_index_values(self): - self.l.add({"dn": "OU=DIV1,DC=SAMBA,DC=ORG", - "name": b"Admins", - "z": "1", - "objectUUID": b"0123456789abcdff"}) - self.l.add({"dn": "OU=DIV2,DC=SAMBA,DC=ORG", - "name": b"Admins", - "z": "1", - "objectUUID": b"0123456789abcdfd"}) - - -class GUIDIndexedAddModifyTests(IndexedAddModifyTests): - """Test searches using the index, to ensure the index doesn't - break things""" - - def setUp(self): - self.index = {"dn": "@INDEXLIST", - "@IDXATTR": [b"x", b"y", b"ou"], - "@IDXONE": [b"1"], - "@IDXGUID": [b"objectUUID"], - "@IDX_DN_GUID": [b"GUID"]} - super(GUIDIndexedAddModifyTests, self).setUp() - - -class GUIDTransIndexedAddModifyTests(GUIDIndexedAddModifyTests): - """Test GUID index behaviour insdie the transaction""" - - def setUp(self): - super(GUIDTransIndexedAddModifyTests, self).setUp() - self.l.transaction_start() - - def tearDown(self): - self.l.transaction_commit() - super(GUIDTransIndexedAddModifyTests, self).tearDown() - - -class TransIndexedAddModifyTests(IndexedAddModifyTests): - """Test index behaviour insdie the transaction""" - - def setUp(self): - super(TransIndexedAddModifyTests, self).setUp() - self.l.transaction_start() - - def tearDown(self): - self.l.transaction_commit() - super(TransIndexedAddModifyTests, self).tearDown() - - -class GuidIndexedAddModifyTestsLmdb(GUIDIndexedAddModifyTests): - - def setUp(self): - if os.environ.get('HAVE_LMDB', '1') == '0': - self.skipTest("No lmdb backend") - self.prefix = MDB_PREFIX - super(GuidIndexedAddModifyTestsLmdb, self).setUp() - - def tearDown(self): - super(GuidIndexedAddModifyTestsLmdb, self).tearDown() - - -class GuidTransIndexedAddModifyTestsLmdb(GUIDTransIndexedAddModifyTests): - - def setUp(self): - if os.environ.get('HAVE_LMDB', '1') == '0': - self.skipTest("No lmdb backend") - self.prefix = MDB_PREFIX - super(GuidTransIndexedAddModifyTestsLmdb, self).setUp() - - def tearDown(self): - super(GuidTransIndexedAddModifyTestsLmdb, self).tearDown() - - -class BadIndexTests(LdbBaseTest): - def setUp(self): - super(BadIndexTests, self).setUp() - self.testdir = tempdir() - self.filename = os.path.join(self.testdir, "test.ldb") - self.ldb = ldb.Ldb(self.url(), flags=self.flags()) - if hasattr(self, 'IDXGUID'): - self.ldb.add({"dn": "@INDEXLIST", - "@IDXATTR": [b"x", b"y", b"ou"], - "@IDXGUID": [b"objectUUID"], - "@IDX_DN_GUID": [b"GUID"]}) - else: - self.ldb.add({"dn": "@INDEXLIST", - "@IDXATTR": [b"x", b"y", b"ou"]}) - - super(BadIndexTests, self).setUp() - - def test_unique(self): - self.ldb.add({"dn": "x=x,dc=samba,dc=org", - "objectUUID": b"0123456789abcde1", - "y": "1"}) - self.ldb.add({"dn": "x=y,dc=samba,dc=org", - "objectUUID": b"0123456789abcde2", - "y": "1"}) - self.ldb.add({"dn": "x=z,dc=samba,dc=org", - "objectUUID": b"0123456789abcde3", - "y": "1"}) - - res = self.ldb.search(expression="(y=1)", - base="dc=samba,dc=org") - self.assertEqual(len(res), 3) - - # Now set this to unique index, but forget to check the result - try: - self.ldb.add({"dn": "@ATTRIBUTES", - "y": "UNIQUE_INDEX"}) - self.fail() - except ldb.LdbError: - pass - - # We must still have a working index - res = self.ldb.search(expression="(y=1)", - base="dc=samba,dc=org") - self.assertEqual(len(res), 3) - - def test_unique_transaction(self): - self.ldb.add({"dn": "x=x,dc=samba,dc=org", - "objectUUID": b"0123456789abcde1", - "y": "1"}) - self.ldb.add({"dn": "x=y,dc=samba,dc=org", - "objectUUID": b"0123456789abcde2", - "y": "1"}) - self.ldb.add({"dn": "x=z,dc=samba,dc=org", - "objectUUID": b"0123456789abcde3", - "y": "1"}) - - res = self.ldb.search(expression="(y=1)", - base="dc=samba,dc=org") - self.assertEqual(len(res), 3) - - self.ldb.transaction_start() - - # Now set this to unique index, but forget to check the result - try: - self.ldb.add({"dn": "@ATTRIBUTES", - "y": "UNIQUE_INDEX"}) - except ldb.LdbError: - pass - - try: - self.ldb.transaction_commit() - self.fail() - - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_OPERATIONS_ERROR) - - # We must still have a working index - res = self.ldb.search(expression="(y=1)", - base="dc=samba,dc=org") - - self.assertEqual(len(res), 3) - - def test_casefold(self): - self.ldb.add({"dn": "x=x,dc=samba,dc=org", - "objectUUID": b"0123456789abcde1", - "y": "a"}) - self.ldb.add({"dn": "x=y,dc=samba,dc=org", - "objectUUID": b"0123456789abcde2", - "y": "A"}) - self.ldb.add({"dn": "x=z,dc=samba,dc=org", - "objectUUID": b"0123456789abcde3", - "y": ["a", "A"]}) - - res = self.ldb.search(expression="(y=a)", - base="dc=samba,dc=org") - self.assertEqual(len(res), 2) - - self.ldb.add({"dn": "@ATTRIBUTES", - "y": "CASE_INSENSITIVE"}) - - # We must still have a working index - res = self.ldb.search(expression="(y=a)", - base="dc=samba,dc=org") - - if hasattr(self, 'IDXGUID'): - self.assertEqual(len(res), 3) - else: - # We should not return this entry twice, but sadly - # we have not yet fixed - # https://bugzilla.samba.org/show_bug.cgi?id=13361 - self.assertEqual(len(res), 4) - - def test_casefold_transaction(self): - self.ldb.add({"dn": "x=x,dc=samba,dc=org", - "objectUUID": b"0123456789abcde1", - "y": "a"}) - self.ldb.add({"dn": "x=y,dc=samba,dc=org", - "objectUUID": b"0123456789abcde2", - "y": "A"}) - self.ldb.add({"dn": "x=z,dc=samba,dc=org", - "objectUUID": b"0123456789abcde3", - "y": ["a", "A"]}) - - res = self.ldb.search(expression="(y=a)", - base="dc=samba,dc=org") - self.assertEqual(len(res), 2) - - self.ldb.transaction_start() - - self.ldb.add({"dn": "@ATTRIBUTES", - "y": "CASE_INSENSITIVE"}) - - self.ldb.transaction_commit() - - # We must still have a working index - res = self.ldb.search(expression="(y=a)", - base="dc=samba,dc=org") - - if hasattr(self, 'IDXGUID'): - self.assertEqual(len(res), 3) - else: - # We should not return this entry twice, but sadly - # we have not yet fixed - # https://bugzilla.samba.org/show_bug.cgi?id=13361 - self.assertEqual(len(res), 4) - - def test_modify_transaction(self): - self.ldb.add({"dn": "x=y,dc=samba,dc=org", - "objectUUID": b"0123456789abcde1", - "y": "2", - "z": "2"}) - - res = self.ldb.search(expression="(y=2)", - base="dc=samba,dc=org") - self.assertEqual(len(res), 1) - - self.ldb.add({"dn": "@ATTRIBUTES", - "y": "UNIQUE_INDEX"}) - - self.ldb.transaction_start() - - m = ldb.Message() - m.dn = ldb.Dn(self.ldb, "x=y,dc=samba,dc=org") - m["0"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "y") - m["1"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "not-here") - - try: - self.ldb.modify(m) - self.fail() - - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_NO_SUCH_ATTRIBUTE) - - try: - self.ldb.transaction_commit() - # We should fail here, but we want to be sure - # we fail below - - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_OPERATIONS_ERROR) - - # The index should still be pointing to x=y - res = self.ldb.search(expression="(y=2)", - base="dc=samba,dc=org") - self.assertEqual(len(res), 1) - - try: - self.ldb.add({"dn": "x=y2,dc=samba,dc=org", - "objectUUID": b"0123456789abcde2", - "y": "2"}) - self.fail("Added unique attribute twice") - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_CONSTRAINT_VIOLATION) - - res = self.ldb.search(expression="(y=2)", - base="dc=samba,dc=org") - self.assertEqual(len(res), 1) - self.assertEqual(str(res[0].dn), "x=y,dc=samba,dc=org") - - def tearDown(self): - super(BadIndexTests, self).tearDown() - - -class GUIDBadIndexTests(BadIndexTests): - """Test Bad index things with GUID index mode""" - - def setUp(self): - self.IDXGUID = True - - super(GUIDBadIndexTests, self).setUp() - - -class GUIDBadIndexTestsLmdb(BadIndexTests): - - def setUp(self): - if os.environ.get('HAVE_LMDB', '1') == '0': - self.skipTest("No lmdb backend") - self.prefix = MDB_PREFIX - self.index = MDB_INDEX_OBJ - self.IDXGUID = True - super(GUIDBadIndexTestsLmdb, self).setUp() - - def tearDown(self): - super(GUIDBadIndexTestsLmdb, self).tearDown() - - -class BatchModeTests(LdbBaseTest): - - def setUp(self): - super(BatchModeTests, self).setUp() - self.testdir = tempdir() - self.filename = os.path.join(self.testdir, "test.ldb") - self.ldb = ldb.Ldb(self.url(), - flags=self.flags(), - options=["batch_mode:1"]) - if hasattr(self, 'IDXGUID'): - self.ldb.add({"dn": "@INDEXLIST", - "@IDXATTR": [b"x", b"y", b"ou"], - "@IDXGUID": [b"objectUUID"], - "@IDX_DN_GUID": [b"GUID"]}) - else: - self.ldb.add({"dn": "@INDEXLIST", - "@IDXATTR": [b"x", b"y", b"ou"]}) - - def test_modify_transaction(self): - self.ldb.add({"dn": "x=y,dc=samba,dc=org", - "objectUUID": b"0123456789abcde1", - "y": "2", - "z": "2"}) - - res = self.ldb.search(expression="(y=2)", - base="dc=samba,dc=org") - self.assertEqual(len(res), 1) - - self.ldb.add({"dn": "@ATTRIBUTES", - "y": "UNIQUE_INDEX"}) - - self.ldb.transaction_start() - - m = ldb.Message() - m.dn = ldb.Dn(self.ldb, "x=y,dc=samba,dc=org") - m["0"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "y") - m["1"] = ldb.MessageElement([], ldb.FLAG_MOD_DELETE, "not-here") - - try: - self.ldb.modify(m) - self.fail() - - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_NO_SUCH_ATTRIBUTE) - - try: - self.ldb.transaction_commit() - self.fail("Commit should have failed as we were in batch mode") - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_OPERATIONS_ERROR) - - def tearDown(self): - super(BatchModeTests, self).tearDown() - - -class DnTests(TestCase): - - def setUp(self): - super(DnTests, self).setUp() - self.ldb = ldb.Ldb() - - def tearDown(self): - super(DnTests, self).tearDown() - del(self.ldb) - - def test_set_dn_invalid(self): - x = ldb.Message() - - def assign(): - x.dn = "astring" - self.assertRaises(TypeError, assign) - - def test_eq(self): - x = ldb.Dn(self.ldb, "dc=foo11,bar=bloe") - y = ldb.Dn(self.ldb, "dc=foo11,bar=bloe") - self.assertEqual(x, y) - y = ldb.Dn(self.ldb, "dc=foo11,bar=blie") - self.assertNotEqual(x, y) - - def test_str(self): - x = ldb.Dn(self.ldb, "dc=foo12,bar=bloe") - self.assertEqual(x.__str__(), "dc=foo12,bar=bloe") - - def test_repr(self): - x = ldb.Dn(self.ldb, "dc=foo13,bla=blie") - self.assertEqual(x.__repr__(), "Dn('dc=foo13,bla=blie')") - - def test_get_casefold_2(self): - x = ldb.Dn(self.ldb, "dc=foo14,bar=bloe") - self.assertEqual(x.get_casefold(), "DC=FOO14,BAR=bloe") - - def test_validate(self): - x = ldb.Dn(self.ldb, "dc=foo15,bar=bloe") - self.assertTrue(x.validate()) - - def test_parent(self): - x = ldb.Dn(self.ldb, "dc=foo16,bar=bloe") - self.assertEqual("bar=bloe", x.parent().__str__()) - - def test_parent_nonexistent(self): - x = ldb.Dn(self.ldb, "@BLA") - self.assertEqual(None, x.parent()) - - def test_is_valid(self): - x = ldb.Dn(self.ldb, "dc=foo18,dc=bloe") - self.assertTrue(x.is_valid()) - x = ldb.Dn(self.ldb, "") - self.assertTrue(x.is_valid()) - - def test_is_special(self): - x = ldb.Dn(self.ldb, "dc=foo19,bar=bloe") - self.assertFalse(x.is_special()) - x = ldb.Dn(self.ldb, "@FOOBAR") - self.assertTrue(x.is_special()) - - def test_check_special(self): - x = ldb.Dn(self.ldb, "dc=foo20,bar=bloe") - self.assertFalse(x.check_special("FOOBAR")) - x = ldb.Dn(self.ldb, "@FOOBAR") - self.assertTrue(x.check_special("@FOOBAR")) - - def test_len(self): - x = ldb.Dn(self.ldb, "dc=foo21,bar=bloe") - self.assertEqual(2, len(x)) - x = ldb.Dn(self.ldb, "dc=foo21") - self.assertEqual(1, len(x)) - - def test_add_child(self): - x = ldb.Dn(self.ldb, "dc=foo22,bar=bloe") - self.assertTrue(x.add_child(ldb.Dn(self.ldb, "bla=bloe"))) - self.assertEqual("bla=bloe,dc=foo22,bar=bloe", x.__str__()) - - def test_add_base(self): - x = ldb.Dn(self.ldb, "dc=foo23,bar=bloe") - base = ldb.Dn(self.ldb, "bla=bloe") - self.assertTrue(x.add_base(base)) - self.assertEqual("dc=foo23,bar=bloe,bla=bloe", x.__str__()) - - def test_add_child_str(self): - x = ldb.Dn(self.ldb, "dc=foo22,bar=bloe") - self.assertTrue(x.add_child("bla=bloe")) - self.assertEqual("bla=bloe,dc=foo22,bar=bloe", x.__str__()) - - def test_add_base_str(self): - x = ldb.Dn(self.ldb, "dc=foo23,bar=bloe") - base = "bla=bloe" - self.assertTrue(x.add_base(base)) - self.assertEqual("dc=foo23,bar=bloe,bla=bloe", x.__str__()) - - def test_add(self): - x = ldb.Dn(self.ldb, "dc=foo24") - y = ldb.Dn(self.ldb, "bar=bla") - self.assertEqual("dc=foo24,bar=bla", str(x + y)) - - def test_remove_base_components(self): - x = ldb.Dn(self.ldb, "dc=foo24,dc=samba,dc=org") - x.remove_base_components(len(x) - 1) - self.assertEqual("dc=foo24", str(x)) - - def test_parse_ldif(self): - msgs = self.ldb.parse_ldif("dn: foo=bar\n") - msg = next(msgs) - self.assertEqual("foo=bar", str(msg[1].dn)) - self.assertTrue(isinstance(msg[1], ldb.Message)) - ldif = self.ldb.write_ldif(msg[1], ldb.CHANGETYPE_NONE) - self.assertEqual("dn: foo=bar\n\n", ldif) - - def test_parse_ldif_more(self): - msgs = self.ldb.parse_ldif("dn: foo=bar\n\n\ndn: bar=bar") - msg = next(msgs) - self.assertEqual("foo=bar", str(msg[1].dn)) - msg = next(msgs) - self.assertEqual("bar=bar", str(msg[1].dn)) - - def test_print_ldif(self): - ldif = '''dn: dc=foo27 -foo: foo - -''' - self.msg = ldb.Message(ldb.Dn(self.ldb, "dc=foo27")) - self.msg["foo"] = [b"foo"] - self.assertEqual(ldif, - self.ldb.write_ldif(self.msg, - ldb.CHANGETYPE_NONE)) - - def test_print_ldif_binary(self): - # this also confirms that ldb flags are set even without a URL) - self.ldb = ldb.Ldb(flags=ldb.FLG_SHOW_BINARY) - ldif = '''dn: dc=foo27 -foo: f -öö - -''' - self.msg = ldb.Message(ldb.Dn(self.ldb, "dc=foo27")) - self.msg["foo"] = ["f\nöö"] - self.assertEqual(ldif, - self.ldb.write_ldif(self.msg, - ldb.CHANGETYPE_NONE)) - - - def test_print_ldif_no_base64_bad(self): - ldif = '''dn: dc=foo27 -foo: f -öö - -''' - self.msg = ldb.Message(ldb.Dn(self.ldb, "dc=foo27")) - self.msg["foo"] = ["f\nöö"] - self.msg["foo"].set_flags(ldb.FLAG_FORCE_NO_BASE64_LDIF) - self.assertEqual(ldif, - self.ldb.write_ldif(self.msg, - ldb.CHANGETYPE_NONE)) - - def test_print_ldif_no_base64_good(self): - ldif = '''dn: dc=foo27 -foo: föö - -''' - self.msg = ldb.Message(ldb.Dn(self.ldb, "dc=foo27")) - self.msg["foo"] = ["föö"] - self.msg["foo"].set_flags(ldb.FLAG_FORCE_NO_BASE64_LDIF) - self.assertEqual(ldif, - self.ldb.write_ldif(self.msg, - ldb.CHANGETYPE_NONE)) - - def test_canonical_string(self): - x = ldb.Dn(self.ldb, "dc=foo25,bar=bloe") - self.assertEqual("/bloe/foo25", x.canonical_str()) - - def test_canonical_ex_string(self): - x = ldb.Dn(self.ldb, "dc=foo26,bar=bloe") - self.assertEqual("/bloe\nfoo26", x.canonical_ex_str()) - - def test_ldb_is_child_of(self): - """Testing ldb_dn_compare_dn""" - dn1 = ldb.Dn(self.ldb, "dc=base") - dn2 = ldb.Dn(self.ldb, "cn=foo,dc=base") - dn3 = ldb.Dn(self.ldb, "cn=bar,dc=base") - dn4 = ldb.Dn(self.ldb, "cn=baz,cn=bar,dc=base") - - self.assertTrue(dn1.is_child_of(dn1)) - self.assertTrue(dn2.is_child_of(dn1)) - self.assertTrue(dn4.is_child_of(dn1)) - self.assertTrue(dn4.is_child_of(dn3)) - self.assertTrue(dn4.is_child_of(dn4)) - self.assertFalse(dn3.is_child_of(dn2)) - self.assertFalse(dn1.is_child_of(dn4)) - - def test_ldb_is_child_of_str(self): - """Testing ldb_dn_compare_dn""" - dn1_str = "dc=base" - dn2_str = "cn=foo,dc=base" - dn3_str = "cn=bar,dc=base" - dn4_str = "cn=baz,cn=bar,dc=base" - - dn1 = ldb.Dn(self.ldb, dn1_str) - dn2 = ldb.Dn(self.ldb, dn2_str) - dn3 = ldb.Dn(self.ldb, dn3_str) - dn4 = ldb.Dn(self.ldb, dn4_str) - - self.assertTrue(dn1.is_child_of(dn1_str)) - self.assertTrue(dn2.is_child_of(dn1_str)) - self.assertTrue(dn4.is_child_of(dn1_str)) - self.assertTrue(dn4.is_child_of(dn3_str)) - self.assertTrue(dn4.is_child_of(dn4_str)) - self.assertFalse(dn3.is_child_of(dn2_str)) - self.assertFalse(dn1.is_child_of(dn4_str)) - - def test_get_component_name(self): - dn = ldb.Dn(self.ldb, "cn=foo,dc=base") - self.assertEqual(dn.get_component_name(0), 'cn') - self.assertEqual(dn.get_component_name(1), 'dc') - self.assertEqual(dn.get_component_name(2), None) - self.assertEqual(dn.get_component_name(-1), None) - - def test_get_component_value(self): - dn = ldb.Dn(self.ldb, "cn=foo,dc=base") - self.assertEqual(dn.get_component_value(0), 'foo') - self.assertEqual(dn.get_component_value(1), 'base') - self.assertEqual(dn.get_component_name(2), None) - self.assertEqual(dn.get_component_name(-1), None) - - def test_set_component(self): - dn = ldb.Dn(self.ldb, "cn=foo,dc=base") - dn.set_component(0, 'cn', 'bar') - self.assertEqual(str(dn), "cn=bar,dc=base") - dn.set_component(1, 'o', 'asep') - self.assertEqual(str(dn), "cn=bar,o=asep") - self.assertRaises(TypeError, dn.set_component, 2, 'dc', 'base') - self.assertEqual(str(dn), "cn=bar,o=asep") - dn.set_component(1, 'o', 'a,b+c') - self.assertEqual(str(dn), r"cn=bar,o=a\,b\+c") - - def test_set_component_bytes(self): - dn = ldb.Dn(self.ldb, "cn=foo,dc=base") - dn.set_component(0, 'cn', b'bar') - self.assertEqual(str(dn), "cn=bar,dc=base") - dn.set_component(1, 'o', b'asep') - self.assertEqual(str(dn), "cn=bar,o=asep") - - def test_set_component_none(self): - dn = ldb.Dn(self.ldb, "cn=foo,cn=bar,dc=base") - self.assertRaises(TypeError, dn.set_component, 1, 'cn', None) - - def test_get_extended_component_null(self): - dn = ldb.Dn(self.ldb, "cn=foo,cn=bar,dc=base") - self.assertEqual(dn.get_extended_component("TEST"), None) - - def test_get_extended_component(self): - self.ldb._register_test_extensions() - dn = ldb.Dn(self.ldb, ";cn=bar,dc=base") - self.assertEqual(dn.get_extended_component("TEST"), b"foo") - - def test_set_extended_component(self): - self.ldb._register_test_extensions() - dn = ldb.Dn(self.ldb, "dc=base") - dn.set_extended_component("TEST", "foo") - self.assertEqual(dn.get_extended_component("TEST"), b"foo") - dn.set_extended_component("TEST", b"bar") - self.assertEqual(dn.get_extended_component("TEST"), b"bar") - - def test_extended_str(self): - self.ldb._register_test_extensions() - dn = ldb.Dn(self.ldb, ";cn=bar,dc=base") - self.assertEqual(dn.extended_str(), ";cn=bar,dc=base") - - def test_get_rdn_name(self): - dn = ldb.Dn(self.ldb, "cn=foo,dc=base") - self.assertEqual(dn.get_rdn_name(), 'cn') - - def test_get_rdn_value(self): - dn = ldb.Dn(self.ldb, "cn=foo,dc=base") - self.assertEqual(dn.get_rdn_value(), 'foo') - - def test_get_casefold(self): - dn = ldb.Dn(self.ldb, "cn=foo,dc=base") - self.assertEqual(dn.get_casefold(), 'CN=FOO,DC=BASE') - - def test_get_linearized(self): - dn = ldb.Dn(self.ldb, "cn=foo,dc=base") - self.assertEqual(dn.get_linearized(), 'cn=foo,dc=base') - - def test_is_null(self): - dn = ldb.Dn(self.ldb, "cn=foo,dc=base") - self.assertFalse(dn.is_null()) - - dn = ldb.Dn(self.ldb, '') - self.assertTrue(dn.is_null()) - - -class LdbMsgTests(TestCase): - - def setUp(self): - super(LdbMsgTests, self).setUp() - self.msg = ldb.Message() - - def test_init_dn(self): - self.msg = ldb.Message(ldb.Dn(ldb.Ldb(), "dc=foo27")) - self.assertEqual("dc=foo27", str(self.msg.dn)) - - def test_iter_items(self): - self.assertEqual(0, len(self.msg.items())) - self.msg.dn = ldb.Dn(ldb.Ldb(), "dc=foo28") - self.assertEqual(1, len(self.msg.items())) - - def test_repr(self): - self.msg.dn = ldb.Dn(ldb.Ldb(), "dc=foo29") - self.msg["dc"] = b"foo" - if PY3: - self.assertIn(repr(self.msg), [ - "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement([b'foo'])})", - "Message({'dc': MessageElement([b'foo']), 'dn': Dn('dc=foo29')})", - ]) - self.assertIn(repr(self.msg.text), [ - "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement([b'foo'])}).text", - "Message({'dc': MessageElement([b'foo']), 'dn': Dn('dc=foo29')}).text", - ]) - else: - self.assertIn(repr(self.msg), [ - "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement(['foo'])})", - "Message({'dc': MessageElement(['foo']), 'dn': Dn('dc=foo29')})", - ]) - self.assertIn(repr(self.msg.text), [ - "Message({'dn': Dn('dc=foo29'), 'dc': MessageElement(['foo'])}).text", - "Message({'dc': MessageElement(['foo']), 'dn': Dn('dc=foo29')}).text", - ]) - - def test_len(self): - self.assertEqual(0, len(self.msg)) - - def test_notpresent(self): - self.assertRaises(KeyError, lambda: self.msg["foo"]) - - def test_del(self): - del self.msg["foo"] - - def test_add(self): - self.msg.add(ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla")) - - def test_add_text(self): - self.msg.add(ldb.MessageElement(["456"], ldb.FLAG_MOD_ADD, "bla")) - - def test_elements_empty(self): - self.assertEqual([], self.msg.elements()) - - def test_elements(self): - el = ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla") - self.msg.add(el) - self.assertEqual([el], self.msg.elements()) - self.assertEqual([el.text], self.msg.text.elements()) - - def test_add_value(self): - self.assertEqual(0, len(self.msg)) - self.msg["foo"] = [b"foo"] - self.assertEqual(1, len(self.msg)) - - def test_add_value_text(self): - self.assertEqual(0, len(self.msg)) - self.msg["foo"] = ["foo"] - self.assertEqual(1, len(self.msg)) - - def test_add_value_multiple(self): - self.assertEqual(0, len(self.msg)) - self.msg["foo"] = [b"foo", b"bla"] - self.assertEqual(1, len(self.msg)) - self.assertEqual([b"foo", b"bla"], list(self.msg["foo"])) - - def test_add_value_multiple_text(self): - self.assertEqual(0, len(self.msg)) - self.msg["foo"] = ["foo", "bla"] - self.assertEqual(1, len(self.msg)) - self.assertEqual(["foo", "bla"], list(self.msg.text["foo"])) - - def test_set_value(self): - self.msg["foo"] = [b"fool"] - self.assertEqual([b"fool"], list(self.msg["foo"])) - self.msg["foo"] = [b"bar"] - self.assertEqual([b"bar"], list(self.msg["foo"])) - - def test_set_value_text(self): - self.msg["foo"] = ["fool"] - self.assertEqual(["fool"], list(self.msg.text["foo"])) - self.msg["foo"] = ["bar"] - self.assertEqual(["bar"], list(self.msg.text["foo"])) - - def test_keys(self): - self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO") - self.msg["foo"] = [b"bla"] - self.msg["bar"] = [b"bla"] - self.assertEqual(["dn", "foo", "bar"], list(self.msg.keys())) - - def test_keys_text(self): - self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO") - self.msg["foo"] = ["bla"] - self.msg["bar"] = ["bla"] - self.assertEqual(["dn", "foo", "bar"], list(self.msg.text.keys())) - - def test_dn(self): - self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO") - self.assertEqual("@BASEINFO", self.msg.dn.__str__()) - - def test_get_dn(self): - self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO") - self.assertEqual("@BASEINFO", self.msg.get("dn").__str__()) - - def test_dn_text(self): - self.msg.text.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO") - self.assertEqual("@BASEINFO", str(self.msg.dn)) - self.assertEqual("@BASEINFO", str(self.msg.text.dn)) - - def test_get_dn_text(self): - self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO") - self.assertEqual("@BASEINFO", str(self.msg.get("dn"))) - self.assertEqual("@BASEINFO", str(self.msg.text.get("dn"))) - - def test_get_invalid(self): - self.msg.dn = ldb.Dn(ldb.Ldb(), "@BASEINFO") - self.assertRaises(TypeError, self.msg.get, 42) - - def test_get_other(self): - self.msg["foo"] = [b"bar"] - self.assertEqual(b"bar", self.msg.get("foo")[0]) - self.assertEqual(b"bar", self.msg.get("foo", idx=0)) - self.assertEqual(None, self.msg.get("foo", idx=1)) - self.assertEqual("", self.msg.get("foo", default='', idx=1)) - - def test_get_other_text(self): - self.msg["foo"] = ["bar"] - self.assertEqual(["bar"], list(self.msg.text.get("foo"))) - self.assertEqual("bar", self.msg.text.get("foo")[0]) - self.assertEqual("bar", self.msg.text.get("foo", idx=0)) - self.assertEqual(None, self.msg.get("foo", idx=1)) - self.assertEqual("", self.msg.get("foo", default='', idx=1)) - - def test_get_default(self): - self.assertEqual(None, self.msg.get("tatayoyo", idx=0)) - self.assertEqual("anniecordie", self.msg.get("tatayoyo", "anniecordie")) - - def test_get_default_text(self): - self.assertEqual(None, self.msg.text.get("tatayoyo", idx=0)) - self.assertEqual("anniecordie", self.msg.text.get("tatayoyo", "anniecordie")) - - def test_get_unknown(self): - self.assertEqual(None, self.msg.get("lalalala")) - - def test_get_unknown_text(self): - self.assertEqual(None, self.msg.text.get("lalalala")) - - def test_msg_diff(self): - l = ldb.Ldb() - msgs = l.parse_ldif("dn: foo=bar\nfoo: bar\nbaz: do\n\ndn: foo=bar\nfoo: bar\nbaz: dont\n") - msg1 = next(msgs)[1] - msg2 = next(msgs)[1] - msgdiff = l.msg_diff(msg1, msg2) - self.assertEqual("foo=bar", msgdiff.get("dn").__str__()) - self.assertRaises(KeyError, lambda: msgdiff["foo"]) - self.assertEqual(1, len(msgdiff)) - - def test_equal_empty(self): - msg1 = ldb.Message() - msg2 = ldb.Message() - self.assertEqual(msg1, msg2) - - def test_equal_simplel(self): - db = ldb.Ldb() - msg1 = ldb.Message() - msg1.dn = ldb.Dn(db, "foo=bar") - msg2 = ldb.Message() - msg2.dn = ldb.Dn(db, "foo=bar") - self.assertEqual(msg1, msg2) - msg1['foo'] = b'bar' - msg2['foo'] = b'bar' - self.assertEqual(msg1, msg2) - msg2['foo'] = b'blie' - self.assertNotEqual(msg1, msg2) - msg2['foo'] = b'blie' - - def test_from_dict(self): - rec = {"dn": "dc=fromdict", - "a1": [b"a1-val1", b"a1-val1"]} - l = ldb.Ldb() - # check different types of input Flags - for flags in [ldb.FLAG_MOD_ADD, ldb.FLAG_MOD_REPLACE, ldb.FLAG_MOD_DELETE]: - m = ldb.Message.from_dict(l, rec, flags) - self.assertEqual(rec["a1"], list(m["a1"])) - self.assertEqual(flags, m["a1"].flags()) - # check input params - self.assertRaises(TypeError, ldb.Message.from_dict, dict(), rec, ldb.FLAG_MOD_REPLACE) - self.assertRaises(TypeError, ldb.Message.from_dict, l, list(), ldb.FLAG_MOD_REPLACE) - self.assertRaises(ValueError, ldb.Message.from_dict, l, rec, 0) - # Message.from_dict expects dictionary with 'dn' - err_rec = {"a1": [b"a1-val1", b"a1-val1"]} - self.assertRaises(TypeError, ldb.Message.from_dict, l, err_rec, ldb.FLAG_MOD_REPLACE) - - def test_from_dict_text(self): - rec = {"dn": "dc=fromdict", - "a1": ["a1-val1", "a1-val1"]} - l = ldb.Ldb() - # check different types of input Flags - for flags in [ldb.FLAG_MOD_ADD, ldb.FLAG_MOD_REPLACE, ldb.FLAG_MOD_DELETE]: - m = ldb.Message.from_dict(l, rec, flags) - self.assertEqual(rec["a1"], list(m.text["a1"])) - self.assertEqual(flags, m.text["a1"].flags()) - # check input params - self.assertRaises(TypeError, ldb.Message.from_dict, dict(), rec, ldb.FLAG_MOD_REPLACE) - self.assertRaises(TypeError, ldb.Message.from_dict, l, list(), ldb.FLAG_MOD_REPLACE) - self.assertRaises(ValueError, ldb.Message.from_dict, l, rec, 0) - # Message.from_dict expects dictionary with 'dn' - err_rec = {"a1": ["a1-val1", "a1-val1"]} - self.assertRaises(TypeError, ldb.Message.from_dict, l, err_rec, ldb.FLAG_MOD_REPLACE) - - def test_copy_add_message_element(self): - m = ldb.Message() - m["1"] = ldb.MessageElement([b"val 111"], ldb.FLAG_MOD_ADD, "1") - m["2"] = ldb.MessageElement([b"val 222"], ldb.FLAG_MOD_ADD, "2") - mto = ldb.Message() - mto["1"] = m["1"] - mto["2"] = m["2"] - self.assertEqual(mto["1"], m["1"]) - self.assertEqual(mto["2"], m["2"]) - mto = ldb.Message() - mto.add(m["1"]) - mto.add(m["2"]) - self.assertEqual(mto["1"], m["1"]) - self.assertEqual(mto["2"], m["2"]) - - def test_copy_add_message_element_text(self): - m = ldb.Message() - m["1"] = ldb.MessageElement(["val 111"], ldb.FLAG_MOD_ADD, "1") - m["2"] = ldb.MessageElement(["val 222"], ldb.FLAG_MOD_ADD, "2") - mto = ldb.Message() - mto["1"] = m["1"] - mto["2"] = m["2"] - self.assertEqual(mto["1"], m.text["1"]) - self.assertEqual(mto["2"], m.text["2"]) - mto = ldb.Message() - mto.add(m["1"]) - mto.add(m["2"]) - self.assertEqual(mto.text["1"], m.text["1"]) - self.assertEqual(mto.text["2"], m.text["2"]) - self.assertEqual(mto["1"], m["1"]) - self.assertEqual(mto["2"], m["2"]) - - -class MessageElementTests(TestCase): - - def test_cmp_element(self): - x = ldb.MessageElement([b"foo"]) - y = ldb.MessageElement([b"foo"]) - z = ldb.MessageElement([b"bzr"]) - self.assertEqual(x, y) - self.assertNotEqual(x, z) - - def test_cmp_element_text(self): - x = ldb.MessageElement([b"foo"]) - y = ldb.MessageElement(["foo"]) - self.assertEqual(x, y) - - def test_create_iterable(self): - x = ldb.MessageElement([b"foo"]) - self.assertEqual([b"foo"], list(x)) - self.assertEqual(["foo"], list(x.text)) - - def test_repr(self): - x = ldb.MessageElement([b"foo"]) - if PY3: - self.assertEqual("MessageElement([b'foo'])", repr(x)) - self.assertEqual("MessageElement([b'foo']).text", repr(x.text)) - else: - self.assertEqual("MessageElement(['foo'])", repr(x)) - self.assertEqual("MessageElement(['foo']).text", repr(x.text)) - x = ldb.MessageElement([b"foo", b"bla"]) - self.assertEqual(2, len(x)) - if PY3: - self.assertEqual("MessageElement([b'foo',b'bla'])", repr(x)) - self.assertEqual("MessageElement([b'foo',b'bla']).text", repr(x.text)) - else: - self.assertEqual("MessageElement(['foo','bla'])", repr(x)) - self.assertEqual("MessageElement(['foo','bla']).text", repr(x.text)) - - def test_get_item(self): - x = ldb.MessageElement([b"foo", b"bar"]) - self.assertEqual(b"foo", x[0]) - self.assertEqual(b"bar", x[1]) - self.assertEqual(b"bar", x[-1]) - self.assertRaises(IndexError, lambda: x[45]) - - def test_get_item_text(self): - x = ldb.MessageElement(["foo", "bar"]) - self.assertEqual("foo", x.text[0]) - self.assertEqual("bar", x.text[1]) - self.assertEqual("bar", x.text[-1]) - self.assertRaises(IndexError, lambda: x[45]) - - def test_len(self): - x = ldb.MessageElement([b"foo", b"bar"]) - self.assertEqual(2, len(x)) - - def test_eq(self): - x = ldb.MessageElement([b"foo", b"bar"]) - y = ldb.MessageElement([b"foo", b"bar"]) - self.assertEqual(y, x) - x = ldb.MessageElement([b"foo"]) - self.assertNotEqual(y, x) - y = ldb.MessageElement([b"foo"]) - self.assertEqual(y, x) - - def test_extended(self): - el = ldb.MessageElement([b"456"], ldb.FLAG_MOD_ADD, "bla") - if PY3: - self.assertEqual("MessageElement([b'456'])", repr(el)) - self.assertEqual("MessageElement([b'456']).text", repr(el.text)) - else: - self.assertEqual("MessageElement(['456'])", repr(el)) - self.assertEqual("MessageElement(['456']).text", repr(el.text)) - - def test_bad_text(self): - el = ldb.MessageElement(b'\xba\xdd') - self.assertRaises(UnicodeDecodeError, el.text.__getitem__, 0) - - -class ModuleTests(TestCase): - - def setUp(self): - super(ModuleTests, self).setUp() - self.testdir = tempdir() - self.filename = os.path.join(self.testdir, "test.ldb") - self.ldb = ldb.Ldb(self.filename) - - def tearDown(self): - shutil.rmtree(self.testdir) - super(ModuleTests, self).setUp() - - def test_register_module(self): - class ExampleModule: - name = "example" - ldb.register_module(ExampleModule) - - def test_use_module(self): - ops = [] - - class ExampleModule: - name = "bla" - - def __init__(self, ldb, next): - ops.append("init") - self.next = next - - def search(self, *args, **kwargs): - return self.next.search(*args, **kwargs) - - def request(self, *args, **kwargs): - pass - - ldb.register_module(ExampleModule) - l = ldb.Ldb(self.filename) - l.add({"dn": "@MODULES", "@LIST": "bla"}) - self.assertEqual([], ops) - l = ldb.Ldb(self.filename) - self.assertEqual(["init"], ops) - - -class LdbResultTests(LdbBaseTest): - - def setUp(self): - super(LdbResultTests, self).setUp() - self.testdir = tempdir() - self.filename = os.path.join(self.testdir, "test.ldb") - self.l = ldb.Ldb(self.url(), flags=self.flags()) - try: - self.l.add(self.index) - except AttributeError: - pass - self.l.add({"dn": "DC=SAMBA,DC=ORG", "name": b"samba.org", - "objectUUID": b"0123456789abcde0"}) - self.l.add({"dn": "OU=ADMIN,DC=SAMBA,DC=ORG", "name": b"Admins", - "objectUUID": b"0123456789abcde1"}) - self.l.add({"dn": "OU=USERS,DC=SAMBA,DC=ORG", "name": b"Users", - "objectUUID": b"0123456789abcde2"}) - self.l.add({"dn": "OU=OU1,DC=SAMBA,DC=ORG", "name": b"OU #1", - "objectUUID": b"0123456789abcde3"}) - self.l.add({"dn": "OU=OU2,DC=SAMBA,DC=ORG", "name": b"OU #2", - "objectUUID": b"0123456789abcde4"}) - self.l.add({"dn": "OU=OU3,DC=SAMBA,DC=ORG", "name": b"OU #3", - "objectUUID": b"0123456789abcde5"}) - self.l.add({"dn": "OU=OU4,DC=SAMBA,DC=ORG", "name": b"OU #4", - "objectUUID": b"0123456789abcde6"}) - self.l.add({"dn": "OU=OU5,DC=SAMBA,DC=ORG", "name": b"OU #5", - "objectUUID": b"0123456789abcde7"}) - self.l.add({"dn": "OU=OU6,DC=SAMBA,DC=ORG", "name": b"OU #6", - "objectUUID": b"0123456789abcde8"}) - self.l.add({"dn": "OU=OU7,DC=SAMBA,DC=ORG", "name": b"OU #7", - "objectUUID": b"0123456789abcde9"}) - self.l.add({"dn": "OU=OU8,DC=SAMBA,DC=ORG", "name": b"OU #8", - "objectUUID": b"0123456789abcdea"}) - self.l.add({"dn": "OU=OU9,DC=SAMBA,DC=ORG", "name": b"OU #9", - "objectUUID": b"0123456789abcdeb"}) - self.l.add({"dn": "OU=OU10,DC=SAMBA,DC=ORG", "name": b"OU #10", - "objectUUID": b"0123456789abcdec"}) - - def tearDown(self): - shutil.rmtree(self.testdir) - super(LdbResultTests, self).tearDown() - # Ensure the LDB is closed now, so we close the FD - del(self.l) - - def test_return_type(self): - res = self.l.search() - self.assertEqual(str(res), "") - - def test_get_msgs(self): - res = self.l.search() - list = res.msgs - - def test_get_controls(self): - res = self.l.search() - list = res.controls - - def test_get_referals(self): - res = self.l.search() - list = res.referals - - def test_iter_msgs(self): - found = False - for l in self.l.search().msgs: - if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": - found = True - self.assertTrue(found) - - def test_iter_msgs_count(self): - self.assertTrue(self.l.search().count > 0) - # 13 objects has been added to the DC=SAMBA, DC=ORG - self.assertEqual(self.l.search(base="DC=SAMBA,DC=ORG").count, 13) - - def test_iter_controls(self): - res = self.l.search().controls - it = iter(res) - - def test_create_control(self): - self.assertRaises(ValueError, ldb.Control, self.l, "tatayoyo:0") - c = ldb.Control(self.l, "relax:1") - self.assertEqual(c.critical, True) - self.assertEqual(c.oid, "1.3.6.1.4.1.4203.666.5.12") - - def test_iter_refs(self): - res = self.l.search().referals - it = iter(res) - - def test_search_sequence_msgs(self): - found = False - res = self.l.search().msgs - - for i in range(0, len(res)): - l = res[i] - if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": - found = True - self.assertTrue(found) - - def test_search_as_iter(self): - found = False - res = self.l.search() - - for l in res: - if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": - found = True - self.assertTrue(found) - - def test_search_iter(self): - found = False - res = self.l.search_iterator() - - for l in res: - if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": - found = True - self.assertTrue(found) - - # Show that search results can't see into a transaction - - def test_search_against_trans(self): - found11 = False - - (r1, w1) = os.pipe() - - (r2, w2) = os.pipe() - - # For the first element, fork a child that will - # write to the DB - pid = os.fork() - if pid == 0: - # In the child, re-open - del(self.l) - gc.collect() - - child_ldb = ldb.Ldb(self.url(), flags=self.flags()) - # start a transaction - child_ldb.transaction_start() - - # write to it - child_ldb.add({"dn": "OU=OU11,DC=SAMBA,DC=ORG", - "name": b"samba.org", - "objectUUID": b"o123456789acbdef"}) - - os.write(w1, b"added") - - # Now wait for the search to be done - os.read(r2, 6) - - # and commit - try: - child_ldb.transaction_commit() - except ldb.LdbError as err: - # We print this here to see what went wrong in the child - print(err) - os._exit(1) - - os.write(w1, b"transaction") - os._exit(0) - - self.assertEqual(os.read(r1, 5), b"added") - - # This should not turn up until the transaction is concluded - res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_BASE) - self.assertEqual(len(res11), 0) - - os.write(w2, b"search") - - # Now wait for the transaction to be done. This should - # deadlock, but the search doesn't hold a read lock for the - # iterator lifetime currently. - self.assertEqual(os.read(r1, 11), b"transaction") - - # This should now turn up, as the transaction is over - res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_BASE) - self.assertEqual(len(res11), 1) - - self.assertFalse(found11) - - (got_pid, status) = os.waitpid(pid, 0) - self.assertEqual(got_pid, pid) - - def test_search_iter_against_trans(self): - found = False - found11 = False - - # We need to hold this iterator open to hold the all-record - # lock - res = self.l.search_iterator() - - (r1, w1) = os.pipe() - - (r2, w2) = os.pipe() - - # For the first element, with the sequence open (which - # means with ldb locks held), fork a child that will - # write to the DB - pid = os.fork() - if pid == 0: - # In the child, re-open - del(res) - del(self.l) - gc.collect() - - child_ldb = ldb.Ldb(self.url(), flags=self.flags()) - # start a transaction - child_ldb.transaction_start() - - # write to it - child_ldb.add({"dn": "OU=OU11,DC=SAMBA,DC=ORG", - "name": b"samba.org", - "objectUUID": b"o123456789acbdef"}) - - os.write(w1, b"added") - - # Now wait for the search to be done - os.read(r2, 6) - - # and commit - try: - child_ldb.transaction_commit() - except ldb.LdbError as err: - # We print this here to see what went wrong in the child - print(err) - os._exit(1) - - os.write(w1, b"transaction") - os._exit(0) - - self.assertEqual(os.read(r1, 5), b"added") - - # This should not turn up until the transaction is concluded - res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_BASE) - self.assertEqual(len(res11), 0) - - os.write(w2, b"search") - - # allow the transaction to start - time.sleep(1) - - # This should not turn up until the search finishes and - # removed the read lock, but for ldb_tdb that happened as soon - # as we called the first res.next() - res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_BASE) - self.assertEqual(len(res11), 0) - - # These results are all collected at the first next(res) call - for l in res: - if str(l.dn) == "OU=OU10,DC=SAMBA,DC=ORG": - found = True - if str(l.dn) == "OU=OU11,DC=SAMBA,DC=ORG": - found11 = True - - # Now wait for the transaction to be done. - self.assertEqual(os.read(r1, 11), b"transaction") - - # This should now turn up, as the transaction is over and all - # read locks are gone - res11 = self.l.search(base="OU=OU11,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_BASE) - self.assertEqual(len(res11), 1) - - self.assertTrue(found) - self.assertFalse(found11) - - (got_pid, status) = os.waitpid(pid, 0) - self.assertEqual(got_pid, pid) - - -class LdbResultTestsLmdb(LdbResultTests): - - def setUp(self): - if os.environ.get('HAVE_LMDB', '1') == '0': - self.skipTest("No lmdb backend") - self.prefix = MDB_PREFIX - self.index = MDB_INDEX_OBJ - super(LdbResultTestsLmdb, self).setUp() - - def tearDown(self): - super(LdbResultTestsLmdb, self).tearDown() - - -class BadTypeTests(TestCase): - def test_control(self): - l = ldb.Ldb() - self.assertRaises(TypeError, ldb.Control, '', 'relax:1') - self.assertRaises(TypeError, ldb.Control, ldb, 1234) - - def test_modify(self): - l = ldb.Ldb() - dn = ldb.Dn(l, 'a=b') - m = ldb.Message(dn) - self.assertRaises(TypeError, l.modify, '') - self.assertRaises(TypeError, l.modify, m, '') - - def test_add(self): - l = ldb.Ldb() - dn = ldb.Dn(l, 'a=b') - m = ldb.Message(dn) - self.assertRaises(TypeError, l.add, '') - self.assertRaises(TypeError, l.add, m, '') - - def test_delete(self): - l = ldb.Ldb() - dn = ldb.Dn(l, 'a=b') - self.assertRaises(TypeError, l.add, '') - self.assertRaises(TypeError, l.add, dn, '') - - def test_rename(self): - l = ldb.Ldb() - dn = ldb.Dn(l, 'a=b') - self.assertRaises(TypeError, l.add, '', dn) - self.assertRaises(TypeError, l.add, dn, '') - self.assertRaises(TypeError, l.add, dn, dn, '') - - def test_search(self): - l = ldb.Ldb() - self.assertRaises(TypeError, l.search, base=1234) - self.assertRaises(TypeError, l.search, scope='') - self.assertRaises(TypeError, l.search, expression=1234) - self.assertRaises(TypeError, l.search, attrs='') - self.assertRaises(TypeError, l.search, controls='') - - -class VersionTests(TestCase): - - def test_version(self): - self.assertTrue(isinstance(ldb.__version__, str)) - -class NestedTransactionTests(LdbBaseTest): - def setUp(self): - super(NestedTransactionTests, self).setUp() - self.testdir = tempdir() - self.filename = os.path.join(self.testdir, "test.ldb") - self.ldb = ldb.Ldb(self.url(), flags=self.flags()) - self.ldb.add({"dn": "@INDEXLIST", - "@IDXATTR": [b"x", b"y", b"ou"], - "@IDXGUID": [b"objectUUID"], - "@IDX_DN_GUID": [b"GUID"]}) - - super(NestedTransactionTests, self).setUp() - - # - # This test documents that currently ldb does not support true nested - # transactions. - # - # Note: The test is written so that it treats failure as pass. - # It is done this way as standalone ldb builds do not use the samba - # known fail mechanism - # - def test_nested_transactions(self): - - self.ldb.transaction_start() - - self.ldb.add({"dn": "x=x1,dc=samba,dc=org", - "objectUUID": b"0123456789abcde1"}) - res = self.ldb.search(expression="(objectUUID=0123456789abcde1)", - base="dc=samba,dc=org") - self.assertEqual(len(res), 1) - - self.ldb.add({"dn": "x=x2,dc=samba,dc=org", - "objectUUID": b"0123456789abcde2"}) - res = self.ldb.search(expression="(objectUUID=0123456789abcde2)", - base="dc=samba,dc=org") - self.assertEqual(len(res), 1) - - self.ldb.transaction_start() - self.ldb.add({"dn": "x=x3,dc=samba,dc=org", - "objectUUID": b"0123456789abcde3"}) - res = self.ldb.search(expression="(objectUUID=0123456789abcde3)", - base="dc=samba,dc=org") - self.assertEqual(len(res), 1) - self.ldb.transaction_cancel() - # - # Check that we can not see the record added by the cancelled - # transaction. - # Currently this fails as ldb does not support true nested - # transactions, and only the outer commits and cancels have an effect - # - res = self.ldb.search(expression="(objectUUID=0123456789abcde3)", - base="dc=samba,dc=org") - # - # FIXME this test currently passes on a failure, i.e. if nested - # transaction support worked correctly the correct test would - # be. - # self.assertEqual(len(res), 0) - # as the add of objectUUID=0123456789abcde3 would reverted when - # the sub transaction it was nested in was rolled back. - # - # Currently this is not the case so the record is still present. - self.assertEqual(len(res), 1) - - - # Commit the outer transaction - # - self.ldb.transaction_commit() - # - # Now check we can still see the records added in the outer - # transaction. - # - res = self.ldb.search(expression="(objectUUID=0123456789abcde1)", - base="dc=samba,dc=org") - self.assertEqual(len(res), 1) - res = self.ldb.search(expression="(objectUUID=0123456789abcde2)", - base="dc=samba,dc=org") - self.assertEqual(len(res), 1) - # - # And that we can't see the records added by the nested transaction. - # - res = self.ldb.search(expression="(objectUUID=0123456789abcde3)", - base="dc=samba,dc=org") - # FIXME again if nested transactions worked correctly we would not - # see this record. The test should be. - # self.assertEqual(len(res), 0) - self.assertEqual(len(res), 1) - - def tearDown(self): - super(NestedTransactionTests, self).tearDown() - - -class LmdbNestedTransactionTests(NestedTransactionTests): - - def setUp(self): - if os.environ.get('HAVE_LMDB', '1') == '0': - self.skipTest("No lmdb backend") - self.prefix = MDB_PREFIX - self.index = MDB_INDEX_OBJ - super(LmdbNestedTransactionTests, self).setUp() - - def tearDown(self): - super(LmdbNestedTransactionTests, self).tearDown() - - -if __name__ == '__main__': - import unittest - unittest.TestProgram() diff --git a/ldb-2.0.8/tests/python/index.py b/ldb-2.0.8/tests/python/index.py deleted file mode 100755 index f957087..0000000 --- a/ldb-2.0.8/tests/python/index.py +++ /dev/null @@ -1,1455 +0,0 @@ -#!/usr/bin/env python3 -# -# Tests for truncated index keys -# -# Copyright (C) Andrew Bartlett 2018 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -# -"""Tests for truncated index keys - -Databases such as lmdb have a maximum key length, these tests ensure that -ldb behaves correctly in those circumstances. - -""" - -import os -from unittest import TestCase -import sys -import ldb -import shutil - -PY3 = sys.version_info > (3, 0) - -TDB_PREFIX = "tdb://" -MDB_PREFIX = "mdb://" - - -def tempdir(): - import tempfile - try: - dir_prefix = os.path.join(os.environ["SELFTEST_PREFIX"], "tmp") - except KeyError: - dir_prefix = None - return tempfile.mkdtemp(dir=dir_prefix) - - -def contains(result, dn): - if result is None: - return False - - for r in result: - if str(r["dn"]) == dn: - return True - return False - - -class LdbBaseTest(TestCase): - def setUp(self): - super(LdbBaseTest, self).setUp() - try: - if self.prefix is None: - self.prefix = TDB_PREFIX - except AttributeError: - self.prefix = TDB_PREFIX - - def tearDown(self): - super(LdbBaseTest, self).tearDown() - - def url(self): - return self.prefix + self.filename - - def flags(self): - if self.prefix == MDB_PREFIX: - return ldb.FLG_NOSYNC - else: - return 0 - - -class MaxIndexKeyLengthTests(LdbBaseTest): - def checkGuids(self, key, guids): - # - # This check relies on the current implementation where the indexes - # are in the same database as the data. - # - # It checks that the index record exists, unless guids is None then - # the record must not exist. And the it contains the expected guid - # entries. - # - # The caller needs to provide the GUID's in the expected order - # - res = self.l.search( - base=key, - scope=ldb.SCOPE_BASE) - if guids is None: - self.assertEqual(len(res), 0) - return - self.assertEqual(len(res), 1) - - # The GUID index format has only one value - index = res[0]["@IDX"][0] - self.assertEqual(len(guids), len(index)) - self.assertEqual(guids, index) - - def tearDown(self): - shutil.rmtree(self.testdir) - super(MaxIndexKeyLengthTests, self).tearDown() - - # Ensure the LDB is closed now, so we close the FD - del(self.l) - - def setUp(self): - super(MaxIndexKeyLengthTests, self).setUp() - self.testdir = tempdir() - self.filename = os.path.join(self.testdir, "key_len_test.ldb") - # Note that the maximum key length is set to 54 - # This accounts for the 4 bytes added by the dn formatting - # a leading dn=, and a trailing zero terminator - # - self.l = ldb.Ldb(self.url(), - options=[ - "modules:rdn_name", - "max_key_len_for_self_test:54"]) - self.l.add({"dn": "@ATTRIBUTES", - "uniqueThing": "UNIQUE_INDEX"}) - self.l.add({"dn": "@INDEXLIST", - "@IDXATTR": [ - b"uniqueThing", - b"notUnique", - b"base64____lt", - b"base64_____eq", - b"base64______gt"], - "@IDXONE": [b"1"], - "@IDXGUID": [b"objectUUID"], - "@IDX_DN_GUID": [b"GUID"]}) - - # Add a value to a unique index that exceeds the maximum key length - # This should be rejected. - def test_add_long_unique_add(self): - try: - self.l.add({"dn": "OU=UNIQUE_MAX_LEN,DC=SAMBA,DC=ORG", - "objectUUID": b"0123456789abcdef", - "uniqueThing": "01234567890123456789012345678901"}) - # index key will be - # "@INDEX:UNIQUETHING:01234567890123456789012345678901" - self.fail("Should have failed on long index key") - - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_CONSTRAINT_VIOLATION) - - # Test that DN's longer the maximum key length can be added - # and that duplicate DN's are rejected correctly - def test_add_long_dn_add(self): - # - # For all entries the DN index key gets truncated to - # @INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA - # - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG", - "objectUUID": b"0123456789abcdef"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcdef") - - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM", - "objectUUID": b"0123456789abcde0"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcde0" + b"0123456789abcdef") - - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV", - "objectUUID": b"0123456789abcde1"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcde0" + b"0123456789abcde1" + b"0123456789abcdef") - - # Key is equal to max length does not get inserted into the truncated - # key namespace - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - "objectUUID": b"0123456789abcde5"}) - self.checkGuids( - "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcde5") - - # This key should not get truncated, as it's one character less than - # max, and will not be in the truncate name space - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXX,DC=SAMBA", - "objectUUID": b"0123456789abcde7"}) - self.checkGuids( - "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcde7") - - try: - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG", - "objectUUID": b"0123456789abcde2"}) - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) - - try: - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM", - "objectUUID": b"0123456789abcde3"}) - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) - - try: - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV", - "objectUUID": b"0123456789abcde4"}) - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) - - try: - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - "objectUUID": b"0123456789abcde6"}) - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) - - try: - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXX,DC=SAMBA", - "objectUUID": b"0123456789abcde8"}) - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) - - def test_rename_truncated_dn_keys(self): - # For all entries the DN index key gets truncated to - # 0 1 2 3 4 5 - # 12345678901234567890123456789012345678901234567890 - # @INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG", - "objectUUID": b"0123456789abcdef"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcdef") - - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM", - "objectUUID": b"0123456789abcde0"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcde0" + b"0123456789abcdef") - - # Non conflicting rename, should succeed - self.l.rename("OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG", - "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV") - # Index should be unchanged. - self.checkGuids( - "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcde0" + b"0123456789abcdef") - - # Conflicting rename should fail - try: - self.l.rename("OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM", - "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV") - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_ENTRY_ALREADY_EXISTS) - - def test_delete_truncated_dn_keys(self): - # - # For all entries the DN index key gets truncated to - # 0 1 2 3 4 5 - # 12345678901234567890123456789012345678901234567890 - # @INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA - # - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG", - "objectUUID": b"0123456789abcdef"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcdef") - - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV", - "objectUUID": b"0123456789abcde1"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcde1" + b"0123456789abcdef") - - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - "objectUUID": b"0123456789abcde5"}) - self.checkGuids( - "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcde5") - - # Try to delete a non existent DN with a truncated key - try: - self.l.delete("OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM") - except ldb.LdbError as err: - enum = err.args[0] - self.assertEqual(enum, ldb.ERR_NO_SUCH_OBJECT) - # Ensure that non of the other truncated DN's got deleted - res = self.l.search( - base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG") - self.assertEqual(len(res), 1) - - res = self.l.search( - base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV") - self.assertEqual(len(res), 1) - - # Ensure that the non truncated DN did not get deleted - res = self.l.search( - base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA") - self.assertEqual(len(res), 1) - - # Check the indexes are correct - self.checkGuids( - "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcde1" + b"0123456789abcdef") - self.checkGuids( - "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcde5") - - # delete an existing entry - self.l.delete("OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG") - - # Ensure it got deleted - res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG") - self.assertEqual(len(res), 0) - - # Ensure that non of the other truncated DN's got deleted - res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV") - self.assertEqual(len(res), 1) - - # Ensure the non truncated entry did not get deleted. - res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA") - self.assertEqual(len(res), 1) - - # Check the indexes are correct - self.checkGuids( - "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcde1") - self.checkGuids( - "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcde5") - - # delete an existing entry - self.l.delete("OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV") - - # Ensure it got deleted - res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXX,DC=SAMBA,DC=GOV") - self.assertEqual(len(res), 0) - - # Ensure that non of the non truncated DN's got deleted - res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA") - self.assertEqual(len(res), 1) - # Check the indexes are correct - self.checkGuids( - "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - None) - self.checkGuids( - "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcde5") - - # delete an existing entry - self.l.delete("OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA") - - # Ensure it got deleted - res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBAxxx") - self.assertEqual(len(res), 0) - self.checkGuids( - "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - None) - - def test_search_truncated_dn_keys(self): - # - # For all entries the DN index key gets truncated to - # 0 1 2 3 4 5 - # 12345678901234567890123456789012345678901234567890 - # @INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA - # - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG", - "objectUUID": b"0123456789abcdef"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcdef") - - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV", - "objectUUID": b"0123456789abcde1"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcde1" + b"0123456789abcdef") - - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - "objectUUID": b"0123456789abcde5"}) - self.checkGuids( - "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcde5") - - res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG") - self.assertEqual(len(res), 1) - - res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV") - self.assertEqual(len(res), 1) - - res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA") - self.assertEqual(len(res), 1) - - res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM") - self.assertEqual(len(res), 0) - - res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXX,DC=SAMBA,DC=GOV") - self.assertEqual(len(res), 0) - - # Non existent, key one less than truncation limit - res = self.l.search(base="OU=A_LONG_DNXXXXXXXXXXXXXX,DC=SAMBA") - self.assertEqual(len(res), 0) - - def test_search_dn_filter_truncated_dn_keys(self): - # - # For all entries the DN index key gets truncated to - # 0 1 2 3 4 5 - # 12345678901234567890123456789012345678901234567890 - # @INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA - # - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG", - "objectUUID": b"0123456789abcdef"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcdef") - - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV", - "objectUUID": b"0123456789abcde1"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcde1" + b"0123456789abcdef") - - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - "objectUUID": b"0123456789abcde5"}) - self.checkGuids( - "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcde5") - - res = self.l.search( - expression="dn=OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG") - self.assertEqual(len(res), 1) - - res = self.l.search( - expression="dn=OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV") - self.assertEqual(len(res), 1) - - res = self.l.search( - expression="dn=OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA") - self.assertEqual(len(res), 1) - - res = self.l.search( - expression="dn=OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM") - self.assertEqual(len(res), 0) - - res = self.l.search( - expression="dn=OU=A_LONG_DNXXXXXXXXXXXX,DC=SAMBA,DC=GOV") - self.assertEqual(len(res), 0) - - # Non existent, key one less than truncation limit - res = self.l.search( - expression="dn=OU=A_LONG_DNXXXXXXXXXXXXXX,DC=SAMBA") - self.assertEqual(len(res), 0) - - def test_search_one_level_truncated_dn_keys(self): - # - # Except for the base DN's - # all entries the DN index key gets truncated to - # 0 1 2 3 4 5 - # 12345678901234567890123456789012345678901234567890 - # @INDEX:@IDXDN:OU=??,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA - # The base DN-s truncate to - # @INDEX:@IDXDN:OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR - # - self.l.add({"dn": "OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1", - "objectUUID": b"0123456789abcdef"}) - self.l.add({"dn": "OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2", - "objectUUID": b"0123456789abcd1f"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR", - b"0123456789abcd1f" + b"0123456789abcdef") - - self.l.add({"dn": "OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1", - "objectUUID": b"0123456789abcde1"}) - self.l.add({"dn": "OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2", - "objectUUID": b"0123456789abcd11"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA", - b"0123456789abcd11" + b"0123456789abcde1") - - self.l.add({"dn": "OU=02,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1", - "objectUUID": b"0123456789abcde2"}) - self.l.add({"dn": "OU=02,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2", - "objectUUID": b"0123456789abcdf2"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=02,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA", - b"0123456789abcde2" + b"0123456789abcdf2") - - self.l.add({"dn": "OU=03,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1", - "objectUUID": b"0123456789abcde3"}) - self.l.add({"dn": "OU=03,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2", - "objectUUID": b"0123456789abcd13"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=03,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA", - b"0123456789abcd13" + b"0123456789abcde3") - - # This key is not truncated as it's the max_key_len - self.l.add({"dn": "OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA", - "objectUUID": b"0123456789abcde7"}) - self.checkGuids( - "@INDEX:@IDXDN:OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA", - b"0123456789abcde7") - - res = self.l.search(base="OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1", - scope=ldb.SCOPE_ONELEVEL) - self.assertEqual(len(res), 3) - self.assertTrue( - contains(res, "OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1")) - self.assertTrue( - contains(res, "OU=02,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1")) - self.assertTrue( - contains(res, "OU=03,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR1")) - - res = self.l.search(base="OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2", - scope=ldb.SCOPE_ONELEVEL) - self.assertEqual(len(res), 3) - self.assertTrue( - contains(res, "OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2")) - self.assertTrue( - contains(res, "OU=02,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2")) - self.assertTrue( - contains(res, "OU=03,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA,DC=OR2")) - - res = self.l.search(base="OU=A_LONG_DN_ONE_LVLX,DC=SAMBA", - scope=ldb.SCOPE_ONELEVEL) - self.assertEqual(len(res), 1) - self.assertTrue( - contains(res, "OU=01,OU=A_LONG_DN_ONE_LVLX,DC=SAMBA")) - - def test_search_sub_tree_truncated_dn_keys(self): - # - # Except for the base DN's - # all entries the DN index key gets truncated to - # 0 1 2 3 4 5 - # 12345678901234567890123456789012345678901234567890 - # @INDEX:@IDXDN:OU=??,OU=A_LONG_DN_SUB_TREE,DC=SAMBA - # The base DN-s truncate to - # @INDEX:@IDXDN:OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR - # - self.l.add({"dn": "OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1", - "objectUUID": b"0123456789abcdef"}) - self.l.add({"dn": "OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2", - "objectUUID": b"0123456789abcde4"}) - self.l.add({"dn": "OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR3", - "objectUUID": b"0123456789abcde8"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR", - b"0123456789abcde4" + b"0123456789abcde8" + b"0123456789abcdef") - - self.l.add({"dn": "OU=01,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1", - "objectUUID": b"0123456789abcde1"}) - self.l.add({"dn": "OU=01,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2", - "objectUUID": b"0123456789abcde5"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=01,OU=A_LONG_DN_SUB_TREE,DC=SAMBA", - b"0123456789abcde1" + b"0123456789abcde5") - - self.l.add({"dn": "OU=02,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1", - "objectUUID": b"0123456789abcde2"}) - self.l.add({"dn": "OU=02,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2", - "objectUUID": b"0123456789abcde6"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=02,OU=A_LONG_DN_SUB_TREE,DC=SAMBA", - b"0123456789abcde2" + b"0123456789abcde6") - - self.l.add({"dn": "OU=03,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1", - "objectUUID": b"0123456789abcde3"}) - - self.l.add({"dn": "OU=03,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2", - "objectUUID": b"0123456789abcde7"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=03,OU=A_LONG_DN_SUB_TREE,DC=SAMBA", - b"0123456789abcde3" + b"0123456789abcde7") - - self.l.add({"dn": "OU=04,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR4", - "objectUUID": b"0123456789abcde9"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=04,OU=A_LONG_DN_SUB_TREE,DC=SAMBA", - b"0123456789abcde9") - - res = self.l.search(base="OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1", - scope=ldb.SCOPE_SUBTREE) - self.assertEqual(len(res), 4) - self.assertTrue( - contains(res, "OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1")) - self.assertTrue( - contains(res, "OU=01,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1")) - self.assertTrue( - contains(res, "OU=02,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1")) - self.assertTrue( - contains(res, "OU=03,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR1")) - - res = self.l.search(base="OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2", - scope=ldb.SCOPE_SUBTREE) - self.assertEqual(len(res), 4) - self.assertTrue( - contains(res, "OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2")) - self.assertTrue( - contains(res, "OU=01,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2")) - self.assertTrue( - contains(res, "OU=02,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2")) - self.assertTrue( - contains(res, "OU=03,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR2")) - - res = self.l.search(base="OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR3", - scope=ldb.SCOPE_SUBTREE) - self.assertEqual(len(res), 1) - self.assertTrue( - contains(res, "OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR3")) - - res = self.l.search(base="OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR4", - scope=ldb.SCOPE_SUBTREE) - self.assertEqual(len(res), 1) - self.assertTrue( - contains(res, "OU=04,OU=A_LONG_DN_SUB_TREE,DC=SAMBA,DC=OR4")) - - def test_search_base_truncated_dn_keys(self): - # - # For all entries the DN index key gets truncated to - # 0 1 2 3 4 5 - # 12345678901234567890123456789012345678901234567890 - # @INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA - # - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG", - "objectUUID": b"0123456789abcdef"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcdef") - - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV", - "objectUUID": b"0123456789abcde1"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcde1" + b"0123456789abcdef") - - self.l.add({"dn": "OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - "objectUUID": b"0123456789abcde5"}) - self.checkGuids( - "@INDEX:@IDXDN:OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - b"0123456789abcde5") - - res = self.l.search( - base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_BASE) - self.assertEqual(len(res), 1) - - res = self.l.search( - base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=GOV", - scope=ldb.SCOPE_BASE) - self.assertEqual(len(res), 1) - - res = self.l.search( - base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA", - scope=ldb.SCOPE_BASE) - self.assertEqual(len(res), 1) - - res = self.l.search( - base="OU=A_LONG_DNXXXXXXXXXXXXXXX,DC=SAMBA,DC=COM", - scope=ldb.SCOPE_BASE) - self.assertEqual(len(res), 0) - - res = self.l.search( - base="OU=A_LONG_DNXXXXXXXXXXXX,DC=SAMBA,DC=GOV", - scope=ldb.SCOPE_BASE) - self.assertEqual(len(res), 0) - - # Non existent, key one less than truncation limit - res = self.l.search( - base="OU=A_LONG_DNXXXXXXXXXXXXXX,DC=SAMBA", - scope=ldb.SCOPE_BASE) - self.assertEqual(len(res), 0) - - # - # Test non unique index searched with truncated keys - # - def test_index_truncated_keys(self): - # 0 1 2 3 4 5 - # 12345678901234567890123456789012345678901234567890 - # @INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - - eq_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - gt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - lt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - # > than max length and differs in values that will be truncated - gt_max_b = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab" - - # Add two entries with the same value, key length = max so no - # truncation. - self.l.add({"dn": "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", - "notUnique": eq_max, - "objectUUID": b"0123456789abcde0"}) - self.checkGuids( - "@INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - b"0123456789abcde0") - - self.l.add({"dn": "OU=02,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", - "notUnique": eq_max, - "objectUUID": b"0123456789abcde1"}) - self.checkGuids( - "@INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - b"0123456789abcde0" + b"0123456789abcde1") - - # - # An entry outside the tree - # - self.l.add({"dn": "OU=10,OU=SEARCH_NON_UNIQUE01,DC=SAMBA,DC=ORG", - "notUnique": eq_max, - "objectUUID": b"0123456789abcd11"}) - self.checkGuids( - "@INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - b"0123456789abcd11" + b"0123456789abcde0" + b"0123456789abcde1") - - # Key longer than max so should get truncated to same key as - # the previous two entries - self.l.add({"dn": "OU=03,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", - "notUnique": gt_max, - "objectUUID": b"0123456789abcde2"}) - # But in the truncated key space - self.checkGuids( - "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - b"0123456789abcde2") - - # Key longer than max so should get truncated to same key as - # the previous entries but differs in the chars after max length - self.l.add({"dn": "OU=23,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", - "notUnique": gt_max_b, - "objectUUID": b"0123456789abcd22"}) - # But in the truncated key space - self.checkGuids( - "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - b"0123456789abcd22" + b"0123456789abcde2") - # - # An entry outside the tree - # - self.l.add({"dn": "OU=11,OU=SEARCH_NON_UNIQUE01,DC=SAMBA,DC=ORG", - "notUnique": gt_max, - "objectUUID": b"0123456789abcd12"}) - self.checkGuids( - "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - b"0123456789abcd12" + b"0123456789abcd22" + b"0123456789abcde2") - - # Key shorter than max - # - self.l.add({"dn": "OU=04,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", - "notUnique": lt_max, - "objectUUID": b"0123456789abcde3"}) - self.checkGuids( - "@INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - b"0123456789abcde3") - # - # An entry outside the tree - # - self.l.add({"dn": "OU=12,OU=SEARCH_NON_UNIQUE01,DC=SAMBA,DC=ORG", - "notUnique": lt_max, - "objectUUID": b"0123456789abcd13"}) - self.checkGuids( - "@INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - b"0123456789abcd13" + b"0123456789abcde3") - - # - # search for target is max value not truncated - # should return ou's 01, 02 - # - expression = "(notUnique=" + eq_max.decode('ascii') + ")" - res = self.l.search(base="OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_ONELEVEL, - expression=expression) - self.assertEqual(len(res), 2) - self.assertTrue( - contains(res, "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) - self.assertTrue( - contains(res, "OU=02,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) - # - # search for target is max value not truncated - # search one level up the tree, scope is ONE_LEVEL - # So should get no matches - # - expression = "(notUnique=" + eq_max.decode('ascii') + ")" - res = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_ONELEVEL, - expression=expression) - self.assertEqual(len(res), 0) - # - # search for target is max value not truncated - # search one level up the tree, scope is SUBTREE - # So should get 3 matches - # - res = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression=expression) - self.assertEqual(len(res), 3) - self.assertTrue( - contains(res, "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) - self.assertTrue( - contains(res, "OU=02,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) - self.assertTrue( - contains(res, "OU=10,OU=SEARCH_NON_UNIQUE01,DC=SAMBA,DC=ORG")) - # - # search for target is max value + 1 so truncated - # should return ou 23 as it's gt_max_b being searched for - # - expression = "(notUnique=" + gt_max_b.decode('ascii') + ")" - res = self.l.search(base="OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_ONELEVEL, - expression=expression) - self.assertEqual(len(res), 1) - self.assertTrue( - contains(res, "OU=23,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) - - # - # search for target is max value + 1 so truncated - # should return ou 03 as it's gt_max being searched for - # - expression = "(notUnique=" + gt_max.decode('ascii') + ")" - res = self.l.search(base="OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_ONELEVEL, - expression=expression) - self.assertEqual(len(res), 1) - self.assertTrue( - contains(res, "OU=03,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) - - # - # scope one level and one level up one level up should get no matches - # - res = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_ONELEVEL, - expression=expression) - self.assertEqual(len(res), 0) - # - # scope sub tree and one level up one level up should get 2 matches - # - res = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression=expression) - self.assertEqual(len(res), 2) - self.assertTrue( - contains(res, "OU=03,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) - self.assertTrue( - contains(res, "OU=11,OU=SEARCH_NON_UNIQUE01,DC=SAMBA,DC=ORG")) - - # - # search for target is max value - 1 so not truncated - # should return ou 04 - # - expression = "(notUnique=" + lt_max.decode('ascii') + ")" - res = self.l.search(base="OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_ONELEVEL, - expression=expression) - self.assertEqual(len(res), 1) - self.assertTrue( - contains(res, "OU=04,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) - - # - # scope one level and one level up one level up should get no matches - # - res = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_ONELEVEL, - expression=expression) - self.assertEqual(len(res), 0) - - # - # scope sub tree and one level up one level up should get 2 matches - # - res = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression=expression) - self.assertEqual(len(res), 2) - self.assertTrue( - contains(res, "OU=04,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) - self.assertTrue( - contains(res, "OU=12,OU=SEARCH_NON_UNIQUE01,DC=SAMBA,DC=ORG")) - - # - # Test index key truncation for base64 encoded values - # - def test_index_truncated_base64_encoded_keys(self): - value = b"aaaaaaaaaaaaaaaaaaaa\x02" - # base64 encodes to "YWFhYWFhYWFhYWFhYWFhYWFhYWEC" - - # One less than max key length - self.l.add({"dn": "OU=01,OU=BASE64,DC=SAMBA,DC=ORG", - "base64____lt": value, - "objectUUID": b"0123456789abcde0"}) - self.checkGuids( - "@INDEX:BASE64____LT::YWFhYWFhYWFhYWFhYWFhYWFhYWEC", - b"0123456789abcde0") - - # Equal max key length - self.l.add({"dn": "OU=02,OU=BASE64,DC=SAMBA,DC=ORG", - "base64_____eq": value, - "objectUUID": b"0123456789abcde1"}) - self.checkGuids( - "@INDEX:BASE64_____EQ::YWFhYWFhYWFhYWFhYWFhYWFhYWEC", - b"0123456789abcde1") - - # One greater than max key length - self.l.add({"dn": "OU=03,OU=BASE64,DC=SAMBA,DC=ORG", - "base64______gt": value, - "objectUUID": b"0123456789abcde2"}) - self.checkGuids( - "@INDEX#BASE64______GT##YWFhYWFhYWFhYWFhYWFhYWFhYWE", - b"0123456789abcde2") - # - # Test adding to non unique index with identical multivalued index - # attributes - # - - def test_index_multi_valued_identical_keys(self): - # 0 1 2 3 4 5 - # 12345678901234567890123456789012345678901234567890 - # @INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - as_eq_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - bs_eq_max = b"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" - - try: - self.l.add({"dn": "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", - "notUnique": [bs_eq_max, as_eq_max, as_eq_max], - "objectUUID": b"0123456789abcde0"}) - self.fail("Exception not thrown") - except ldb.LdbError as e: - code = e.args[0] - self.assertEqual(ldb.ERR_ATTRIBUTE_OR_VALUE_EXISTS, code) - - # - # Test non unique index with multivalued index attributes - # searched with non truncated keys - # - def test_search_index_multi_valued_truncated_keys(self): - # 0 1 2 3 4 5 - # 12345678901234567890123456789012345678901234567890 - # @INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - - aa_gt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - ab_gt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab" - bb_gt_max = b"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" - - self.l.add({"dn": "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", - "notUnique": [aa_gt_max, ab_gt_max, bb_gt_max], - "objectUUID": b"0123456789abcde0"}) - self.checkGuids( - "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - b"0123456789abcde0" + b"0123456789abcde0") - self.checkGuids( - "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - b"0123456789abcde0") - - expression = "(notUnique=" + aa_gt_max.decode('ascii') + ")" - res = self.l.search(base="OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_ONELEVEL, - expression=expression) - self.assertEqual(len(res), 1) - self.assertTrue( - contains(res, "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) - - expression = "(notUnique=" + ab_gt_max.decode('ascii') + ")" - res = self.l.search(base="OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_ONELEVEL, - expression=expression) - self.assertEqual(len(res), 1) - self.assertTrue( - contains(res, "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) - - expression = "(notUnique=" + bb_gt_max.decode('ascii') + ")" - res = self.l.search(base="OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_ONELEVEL, - expression=expression) - self.assertEqual(len(res), 1) - self.assertTrue( - contains(res, "OU=01,OU=SEARCH_NON_UNIQUE,DC=SAMBA,DC=ORG")) - - # - # Test deletion of records with non unique index with multivalued index - # attributes - # replicate this to test modify with modify flags i.e. DELETE, REPLACE - # - def test_delete_index_multi_valued_truncated_keys(self): - # 0 1 2 3 4 5 - # 12345678901234567890123456789012345678901234567890 - # @INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - - aa_gt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - ab_gt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab" - bb_gt_max = b"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" - cc_gt_max = b"cccccccccccccccccccccccccccccccccc" - - self.l.add({"dn": "OU=01,OU=DELETE_NON_UNIQUE,DC=SAMBA,DC=ORG", - "notUnique": [aa_gt_max, ab_gt_max, bb_gt_max], - "objectUUID": b"0123456789abcde0"}) - self.l.add({"dn": "OU=02,OU=DELETE_NON_UNIQUE,DC=SAMBA,DC=ORG", - "notUnique": [aa_gt_max, ab_gt_max, cc_gt_max], - "objectUUID": b"0123456789abcde1"}) - self.checkGuids( - "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - b"0123456789abcde0" + b"0123456789abcde0" + - b"0123456789abcde1" + b"0123456789abcde1") - self.checkGuids( - "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - b"0123456789abcde0") - self.checkGuids( - "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc", - b"0123456789abcde1") - - res = self.l.search( - base="DC=SAMBA,DC=ORG", - expression="(notUnique=" + aa_gt_max.decode("ascii") + ")") - self.assertEqual(2, len(res)) - self.assertTrue( - contains(res, "OU=01,OU=DELETE_NON_UNIQUE,DC=SAMBA,DC=ORG")) - self.assertTrue( - contains(res, "OU=02,OU=DELETE_NON_UNIQUE,DC=SAMBA,DC=ORG")) - - self.l.delete("OU=02,OU=DELETE_NON_UNIQUE,DC=SAMBA,DC=ORG") - self.checkGuids( - "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - b"0123456789abcde0" + b"0123456789abcde0") - self.checkGuids( - "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - b"0123456789abcde0") - self.checkGuids( - "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc", - None) - - self.l.delete("OU=01,OU=DELETE_NON_UNIQUE,DC=SAMBA,DC=ORG") - self.checkGuids( - "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - None) - self.checkGuids( - "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - None) - self.checkGuids( - "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc", - None) - - # - # Test modification of records with non unique index with multivalued index - # attributes - # - def test_modify_index_multi_valued_truncated_keys(self): - # 0 1 2 3 4 5 - # 12345678901234567890123456789012345678901234567890 - # @INDEX:NOTUNIQUE:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - - aa_gt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - ab_gt_max = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab" - bb_gt_max = b"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" - cc_gt_max = b"cccccccccccccccccccccccccccccccccc" - - self.l.add({"dn": "OU=01,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG", - "notUnique": [aa_gt_max, ab_gt_max, bb_gt_max], - "objectUUID": b"0123456789abcde0"}) - self.l.add({"dn": "OU=02,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG", - "notUnique": [aa_gt_max, ab_gt_max, cc_gt_max], - "objectUUID": b"0123456789abcde1"}) - self.checkGuids( - "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - b"0123456789abcde0" + b"0123456789abcde0" + - b"0123456789abcde1" + b"0123456789abcde1") - self.checkGuids( - "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - b"0123456789abcde0") - self.checkGuids( - "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc", - b"0123456789abcde1") - - res = self.l.search( - base="DC=SAMBA,DC=ORG", - expression="(notUnique=" + aa_gt_max.decode("ascii") + ")") - self.assertEqual(2, len(res)) - self.assertTrue( - contains(res, "OU=01,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG")) - self.assertTrue( - contains(res, "OU=02,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG")) - - # - # Modify that does not change the indexed attribute - # - msg = ldb.Message() - msg.dn = ldb.Dn(self.l, "OU=01,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG") - msg["notUnique"] = ldb.MessageElement( - [aa_gt_max, ab_gt_max, bb_gt_max], - ldb.FLAG_MOD_REPLACE, - "notUnique") - self.l.modify(msg) - # - # As the modify is replacing the attribute with the same contents - # there should be no changes to the indexes. - # - self.checkGuids( - "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - b"0123456789abcde0" + b"0123456789abcde0" + - b"0123456789abcde1" + b"0123456789abcde1") - self.checkGuids( - "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - b"0123456789abcde0") - self.checkGuids( - "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc", - b"0123456789abcde1") - - # - # Modify that removes a value from the indexed attribute - # - msg = ldb.Message() - msg.dn = ldb.Dn(self.l, "OU=01,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG") - msg["notUnique"] = ldb.MessageElement( - [aa_gt_max, bb_gt_max], - ldb.FLAG_MOD_REPLACE, - "notUnique") - self.l.modify(msg) - - self.checkGuids( - "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - b"0123456789abcde0" + - b"0123456789abcde1" + b"0123456789abcde1") - self.checkGuids( - "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - b"0123456789abcde0") - self.checkGuids( - "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc", - b"0123456789abcde1") - - # - # Modify that does a constrained delete the indexed attribute - # - msg = ldb.Message() - msg.dn = ldb.Dn(self.l, "OU=02,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG") - msg["notUnique"] = ldb.MessageElement( - [ab_gt_max], - ldb.FLAG_MOD_DELETE, - "notUnique") - self.l.modify(msg) - - self.checkGuids( - "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - b"0123456789abcde0" + b"0123456789abcde1") - self.checkGuids( - "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - b"0123456789abcde0") - self.checkGuids( - "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc", - b"0123456789abcde1") - - # - # Modify that does an unconstrained delete the indexed attribute - # - msg = ldb.Message() - msg.dn = ldb.Dn(self.l, "OU=02,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG") - msg["notUnique"] = ldb.MessageElement( - [], - ldb.FLAG_MOD_DELETE, - "notUnique") - self.l.modify(msg) - - self.checkGuids( - "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - b"0123456789abcde0") - self.checkGuids( - "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - b"0123456789abcde0") - self.checkGuids( - "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc", - None) - - # - # Modify that adds a value to the indexed attribute - # - msg = ldb.Message() - msg.dn = ldb.Dn(self.l, "OU=02,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG") - msg["notUnique"] = ldb.MessageElement( - [cc_gt_max], - ldb.FLAG_MOD_ADD, - "notUnique") - self.l.modify(msg) - - self.checkGuids( - "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - b"0123456789abcde0") - self.checkGuids( - "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - b"0123456789abcde0") - self.checkGuids( - "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc", - b"0123456789abcde1") - - # - # Modify that adds a values to the indexed attribute - # - msg = ldb.Message() - msg.dn = ldb.Dn(self.l, "OU=02,OU=MODIFY_NON_UNIQUE,DC=SAMBA,DC=ORG") - msg["notUnique"] = ldb.MessageElement( - [aa_gt_max, ab_gt_max], - ldb.FLAG_MOD_ADD, - "notUnique") - self.l.modify(msg) - - self.checkGuids( - "@INDEX#NOTUNIQUE#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - b"0123456789abcde0" + - b"0123456789abcde1" + b"0123456789abcde1") - self.checkGuids( - "@INDEX#NOTUNIQUE#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", - b"0123456789abcde0") - self.checkGuids( - "@INDEX#NOTUNIQUE#ccccccccccccccccccccccccccccccccc", - b"0123456789abcde1") - - # - # Test Sub tree searches when checkBaseOnSearch is enabled and the - # DN indexes are truncated and collide. - # - def test_check_base_on_search_truncated_dn_keys(self): - # - # Except for the base DN's - # all entries the DN index key gets truncated to - # 0 1 2 3 4 5 - # 12345678901234567890123456789012345678901234567890 - # @INDEX:@IDXDN:OU=??,OU=CHECK_BASE_DN_XXXX,DC=SAMBA - # The base DN-s truncate to - # @INDEX:@IDXDN:OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR - # - checkbaseonsearch = {"dn": "@OPTIONS", - "checkBaseOnSearch": b"TRUE"} - self.l.add(checkbaseonsearch) - - self.l.add({"dn": "OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR1", - "objectUUID": b"0123456789abcdef"}) - self.l.add({"dn": "OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR2", - "objectUUID": b"0123456789abcdee"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR", - b"0123456789abcdee" + b"0123456789abcdef") - - self.l.add({"dn": "OU=01,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR1", - "objectUUID": b"0123456789abcdec"}) - self.l.add({"dn": "OU=01,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR2", - "objectUUID": b"0123456789abcdeb"}) - self.l.add({"dn": "OU=01,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR3", - "objectUUID": b"0123456789abcded"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=01,OU=CHECK_BASE_DN_XXXX,DC=SAMBA", - b"0123456789abcdeb" + b"0123456789abcdec" + b"0123456789abcded") - - self.l.add({"dn": "OU=02,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR1", - "objectUUID": b"0123456789abcde0"}) - self.l.add({"dn": "OU=02,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR2", - "objectUUID": b"0123456789abcde1"}) - self.l.add({"dn": "OU=02,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR3", - "objectUUID": b"0123456789abcde2"}) - self.checkGuids( - "@INDEX#@IDXDN#OU=02,OU=CHECK_BASE_DN_XXXX,DC=SAMBA", - b"0123456789abcde0" + b"0123456789abcde1" + b"0123456789abcde2") - - res = self.l.search(base="OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR1", - scope=ldb.SCOPE_SUBTREE) - self.assertEqual(len(res), 3) - self.assertTrue( - contains(res, "OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR1")) - self.assertTrue( - contains(res, "OU=01,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR1")) - self.assertTrue( - contains(res, "OU=02,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR1")) - - res = self.l.search(base="OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR2", - scope=ldb.SCOPE_SUBTREE) - self.assertEqual(len(res), 3) - self.assertTrue( - contains(res, "OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR2")) - self.assertTrue( - contains(res, "OU=01,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR2")) - self.assertTrue( - contains(res, "OU=02,OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR2")) - - try: - res = self.l.search(base="OU=CHECK_BASE_DN_XXXX,DC=SAMBA,DC=OR3", - scope=ldb.SCOPE_SUBTREE) - self.fail("Expected exception no thrown") - except ldb.LdbError as e: - code = e.args[0] - self.assertEqual(ldb.ERR_NO_SUCH_OBJECT, code) - - -# Run the index truncation tests against an lmdb backend -class MaxIndexKeyLengthTestsLmdb(MaxIndexKeyLengthTests): - - def setUp(self): - if os.environ.get('HAVE_LMDB', '1') == '0': - self.skipTest("No lmdb backend") - self.prefix = MDB_PREFIX - super(MaxIndexKeyLengthTestsLmdb, self).setUp() - - def tearDown(self): - super(MaxIndexKeyLengthTestsLmdb, self).tearDown() - - -class OrderedIntegerRangeTests(LdbBaseTest): - - def tearDown(self): - shutil.rmtree(self.testdir) - super(OrderedIntegerRangeTests, self).tearDown() - - # Ensure the LDB is closed now, so we close the FD - del(self.l) - - def setUp(self): - super(OrderedIntegerRangeTests, self).setUp() - self.testdir = tempdir() - self.filename = os.path.join(self.testdir, "ordered_integer_test.ldb") - - self.l = ldb.Ldb(self.url(), - options=self.options()) - self.l.add({"dn": "@ATTRIBUTES", - "int64attr": "ORDERED_INTEGER"}) - self.l.add({"dn": "@INDEXLIST", - "@IDXATTR": [b"int64attr"], - "@IDXONE": [b"1"], - "@IDXGUID": [b"objectUUID"], - "@IDX_DN_GUID": [b"GUID"]}) - - def options(self): - if self.prefix == MDB_PREFIX: - return ['modules:rdn_name', - 'disable_full_db_scan_for_self_test:1'] - else: - return ['modules:rdn_name'] - - def test_comparison_expression(self): - int64_max = 2**63-1 - int64_min = -2**63 - test_nums = list(range(-5, 5)) - test_nums += list(range(int64_max-5, int64_max+1)) - test_nums += list(range(int64_min, int64_min+5)) - test_nums = sorted(test_nums) - - for (i, num) in enumerate(test_nums): - ouuid = 0x0123456789abcdef + i - ouuid_s = bytes(('0' + hex(ouuid)[2:]).encode()) - self.l.add({"dn": "OU=COMPTESTOU{},DC=SAMBA,DC=ORG".format(i), - "objectUUID": ouuid_s, - "int64attr": str(num)}) - - def assert_int64_expr(expr, py_expr=None): - res = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(int64attr%s)" % (expr)) - - if not py_expr: - py_expr = expr - expect = [n for n in test_nums if eval(str(n) + py_expr)] - vals = sorted([int(r.get("int64attr")[0]) for r in res]) - self.assertEqual(len(res), len(expect)) - self.assertEqual(set(vals), set(expect)) - self.assertEqual(expect, vals) - - assert_int64_expr(">=-2") - assert_int64_expr("<=2") - assert_int64_expr(">=" + str(int64_min)) - assert_int64_expr("<=" + str(int64_min)) - assert_int64_expr("<=" + str(int64_min+1)) - assert_int64_expr("<=" + str(int64_max)) - assert_int64_expr(">=" + str(int64_max)) - assert_int64_expr(">=" + str(int64_max-1)) - assert_int64_expr("=10", "==10") - - def test_comparison_expression_duplicates(self): - int64_max = 2**63-1 - int64_min = -2**63 - test_nums = list(range(-5, 5)) * 3 - test_nums += list(range(-20, 20, 5)) * 2 - test_nums += list(range(-50, 50, 15)) - test_nums = sorted(test_nums) - - for (i, num) in enumerate(test_nums): - ouuid = 0x0123456789abcdef + i - ouuid_s = bytes(('0' + hex(ouuid)[2:]).encode()) - self.l.add({"dn": "OU=COMPTESTOU{},DC=SAMBA,DC=ORG".format(i), - "objectUUID": ouuid_s, - "int64attr": str(num)}) - - def assert_int64_expr(expr, py_expr=None): - res = self.l.search(base="DC=SAMBA,DC=ORG", - scope=ldb.SCOPE_SUBTREE, - expression="(int64attr%s)" % (expr)) - - if not py_expr: - py_expr = expr - expect = [n for n in test_nums if eval(str(n) + py_expr)] - vals = sorted([int(r.get("int64attr")[0]) for r in res]) - self.assertEqual(len(res), len(expect)) - self.assertEqual(set(vals), set(expect)) - self.assertEqual(expect, vals) - - assert_int64_expr(">=-2") - assert_int64_expr("<=2") - assert_int64_expr(">=" + str(int64_min)) - assert_int64_expr("<=" + str(int64_min)) - assert_int64_expr("<=" + str(int64_min+1)) - assert_int64_expr("<=" + str(int64_max)) - assert_int64_expr(">=" + str(int64_max)) - assert_int64_expr(">=" + str(int64_max-1)) - assert_int64_expr("=-5", "==-5") - assert_int64_expr("=5", "==5") - - -# Run the ordered integer range tests against an lmdb backend -class OrderedIntegerRangeTestsLmdb(OrderedIntegerRangeTests): - - def setUp(self): - if os.environ.get('HAVE_LMDB', '1') == '0': - self.skipTest("No lmdb backend") - self.prefix = MDB_PREFIX - super(OrderedIntegerRangeTestsLmdb, self).setUp() - - def tearDown(self): - super(OrderedIntegerRangeTestsLmdb, self).tearDown() - - -# Run the index truncation tests against an lmdb backend -class RejectSubDBIndex(LdbBaseTest): - - def setUp(self): - if os.environ.get('HAVE_LMDB', '1') == '0': - self.skipTest("No lmdb backend") - self.prefix = MDB_PREFIX - super(RejectSubDBIndex, self).setUp() - self.testdir = tempdir() - self.filename = os.path.join(self.testdir, - "reject_subidx_test.ldb") - self.l = ldb.Ldb(self.url(), - options=[ - "modules:rdn_name"]) - - def tearDown(self): - super(RejectSubDBIndex, self).tearDown() - - def test_try_subdb_index(self): - try: - self.l.add({"dn": "@INDEXLIST", - "@IDX_LMDB_SUBDB": [b"1"], - "@IDXONE": [b"1"], - "@IDXGUID": [b"objectUUID"], - "@IDX_DN_GUID": [b"GUID"], - }) - except ldb.LdbError as e: - code = e.args[0] - string = e.args[1] - self.assertEqual(ldb.ERR_OPERATIONS_ERROR, code) - self.assertIn("sub-database index", string) - - -if __name__ == '__main__': - import unittest - unittest.TestProgram() diff --git a/ldb-2.0.8/tests/python/repack.py b/ldb-2.0.8/tests/python/repack.py deleted file mode 100644 index 0844cd2..0000000 --- a/ldb-2.0.8/tests/python/repack.py +++ /dev/null @@ -1,204 +0,0 @@ -import os -from unittest import TestCase -import shutil -from subprocess import check_output -import ldb - -TDB_PREFIX = "tdb://" -MDB_PREFIX = "mdb://" - -def tempdir(): - import tempfile - try: - dir_prefix = os.path.join(os.environ["SELFTEST_PREFIX"], "tmp") - except KeyError: - dir_prefix = None - return tempfile.mkdtemp(dir=dir_prefix) - - -# Check enabling and disabling GUID indexing works and that the database is -# repacked at version 2 if GUID indexing is enabled, or version 1 if disabled. -class GUIDIndexAndPackFormatTests(TestCase): - prefix = TDB_PREFIX - - def setup_newdb(self): - self.testdir = tempdir() - self.filename = os.path.join(self.testdir, - "guidpackformattest.ldb") - url = self.prefix + self.filename - self.l = ldb.Ldb(url, options=["modules:"]) - - self.num_recs_added = 0 - - #guidindexpackv1.ldb is a pre-made database packed with version 1 format - #but with GUID indexing enabled, which is not allowed, so Samba should - #repack the database on the first transaction. - def setup_premade_v1_db(self): - db_name = "guidindexpackv1.ldb" - this_file_dir = os.path.dirname(os.path.abspath(__file__)) - db_path = os.path.join(this_file_dir, "../", db_name) - self.testdir = tempdir() - self.filename = os.path.join(self.testdir, db_name) - - shutil.copy(db_path, self.filename) - - url = self.prefix + self.filename - self.l = ldb.Ldb(url, options=["modules:"]) - self.num_recs_added = 10 - - def tearDown(self): - if hasattr(self, 'testdir'): - shutil.rmtree(self.testdir) - - def add_one_rec(self): - ouuid = 0x0123456789abcdef + self.num_recs_added - ouuid_s = '0' + hex(ouuid)[2:] - dn = "OU=GUIDPFTEST{},DC=SAMBA,DC=ORG".format(self.num_recs_added) - rec = {"dn": dn, "objectUUID": ouuid_s, "distinguishedName": dn} - self.l.add(rec) - self.num_recs_added += 1 - - # Turn GUID back into a str for easier comparisons - return rec - - def set_guid_indexing(self, enable=True): - modmsg = ldb.Message() - modmsg.dn = ldb.Dn(self.l, '@INDEXLIST') - - attrs = {"@IDXGUID": [b"objectUUID"], - "@IDX_DN_GUID": [b"GUID"]} - for attr, val in attrs.items(): - replace = ldb.FLAG_MOD_REPLACE - el = val if enable else [] - el = ldb.MessageElement(elements=el, flags=replace, name=attr) - modmsg.add(el) - - self.l.modify(modmsg) - - # Parse out the comments above each record that ldbdump produces - # containing pack format version and KV level key for each record. - # Return all GUID index keys and the set of all unique pack formats. - def ldbdump_guid_keys_pack_formats(self): - dump = check_output(["bin/ldbdump", "-i", self.filename]) - dump = dump.decode("utf-8") - dump = dump.split("\n") - - comments = [s for s in dump if s.startswith("#")] - - guid_key_tag = "# key: GUID=" - guid_keys = {c[len(guid_key_tag):] for c in comments - if c.startswith(guid_key_tag)} - - pack_format_tag = "# pack format: " - pack_formats = {c[len(pack_format_tag):] for c in comments - if c.startswith(pack_format_tag)} - pack_formats = [int(s, 16) for s in pack_formats] - - return guid_keys, pack_formats - - # Put the whole database in a dict so we can easily check the database - # hasn't changed - def get_database(self): - recs = self.l.search(base="", scope=ldb.SCOPE_SUBTREE, expression="") - db = dict() - for r in recs: - dn = str(r.dn) - self.assertNotIn(dn, db) - db[dn] = dict() - for k in r.keys(): - k = str(k) - db[dn][k] = str(r.get(k)) - return db - - # Toggle GUID indexing on and off a few times, and check that when GUID - # indexing is enabled, the database is repacked to pack format V2, and - # when GUID indexing is disabled again, the database is repacked with - # pack format V1. - def toggle_guidindex_check_pack(self): - expect_db = self.get_database() - - for enable in [False, False, True, False, True, True, False]: - pf = ldb.PACKING_FORMAT_V2 if enable else ldb.PACKING_FORMAT - - self.set_guid_indexing(enable=enable) - - guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() - num_guid_keys = self.num_recs_added if enable else 0 - self.assertEqual(len(guid_keys), num_guid_keys) - self.assertEqual(pack_formats, [pf]) - self.assertEqual(self.get_database(), expect_db) - - rec = self.add_one_rec() - expect_db[rec['dn']] = rec - - guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() - num_guid_keys = self.num_recs_added if enable else 0 - self.assertEqual(len(guid_keys), num_guid_keys) - self.assertEqual(pack_formats, [pf]) - self.assertEqual(self.get_database(), expect_db) - - # Check a newly created database is initially packed at V1, then is - # repacked at V2 when GUID indexing is enabled. - def test_repack(self): - self.setup_newdb() - - guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() - self.assertEqual(len(guid_keys), 0) - self.assertEqual(pack_formats, [ldb.PACKING_FORMAT]) - self.assertEqual(self.get_database(), {}) - - self.l.add({"dn": "@ATTRIBUTES"}) - - guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() - self.assertEqual(len(guid_keys), 0) - self.assertEqual(pack_formats, [ldb.PACKING_FORMAT]) - self.assertEqual(self.get_database(), {}) - - self.l.add({"dn": "@INDEXLIST", - "@IDXONE": [b"1"], - "@IDXGUID": [b"objectUUID"], - "@IDX_DN_GUID": [b"GUID"]}) - - guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() - self.assertEqual(len(guid_keys), 0) - self.assertEqual(pack_formats, [ldb.PACKING_FORMAT_V2]) - self.assertEqual(self.get_database(), {}) - - rec = self.add_one_rec() - expect_db = {rec["dn"]: rec} - - guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() - self.assertEqual(len(guid_keys), 1) - self.assertEqual(pack_formats, [ldb.PACKING_FORMAT_V2]) - self.assertEqual(self.get_database(), expect_db) - - self.toggle_guidindex_check_pack() - - # Check a database with V1 format with GUID indexing enabled is repacked - # with version 2 format. - def test_guid_indexed_v1_db(self): - self.setup_premade_v1_db() - - expect_db = self.get_database() - - guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() - self.assertEqual(len(guid_keys), self.num_recs_added) - self.assertEqual(pack_formats, [ldb.PACKING_FORMAT]) - self.assertEqual(self.get_database(), expect_db) - - rec = self.add_one_rec() - expect_db[rec['dn']] = rec - - guid_keys, pack_formats = self.ldbdump_guid_keys_pack_formats() - self.assertEqual(len(guid_keys), self.num_recs_added) - self.assertEqual(pack_formats, [ldb.PACKING_FORMAT_V2]) - self.assertEqual(self.get_database(), expect_db) - - self.toggle_guidindex_check_pack() - - -if __name__ == '__main__': - import unittest - - - unittest.TestProgram() diff --git a/ldb-2.0.8/tests/samba4.png b/ldb-2.0.8/tests/samba4.png deleted file mode 100644 index c8096889a673007dfe4911ad3988e53e54fee7a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6239 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 diff --git a/ldb-2.0.8/tests/sample_module.c b/ldb-2.0.8/tests/sample_module.c deleted file mode 100644 index 6ba9ed2..0000000 --- a/ldb-2.0.8/tests/sample_module.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba utility functions - Copyright (C) Jelmer Vernooij 2007 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#include "ldb_module.h" - -static int sample_add_callback(struct ldb_request *down_req, - struct ldb_reply *ares) -{ - struct ldb_request *req = - talloc_get_type_abort(down_req->context, - struct ldb_request); - - if (ares == NULL) { - return ldb_module_done(req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - if (ares->type == LDB_REPLY_REFERRAL) { - return ldb_module_send_referral(req, ares->referral); - } - - if (ares->error != LDB_SUCCESS) { - return ldb_module_done(req, ares->controls, - ares->response, ares->error); - } - - if (ares->type != LDB_REPLY_DONE) { - return ldb_module_done(req, NULL, NULL, - LDB_ERR_OPERATIONS_ERROR); - } - - return ldb_module_done(req, ares->controls, - ares->response, LDB_SUCCESS); -} - -static int sample_add(struct ldb_module *mod, struct ldb_request *req) -{ - struct ldb_context *ldb = ldb_module_get_ctx(mod); - struct ldb_control *control = NULL; - struct ldb_message *msg = NULL; - struct ldb_request *down_req = NULL; - int ret; - - /* check if there's a relax control */ - control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID); - if (control != NULL) { - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - msg = ldb_msg_copy_shallow(req, req->op.add.message); - if (msg == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_msg_add_fmt(msg, "touchedBy", "sample"); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_build_add_req(&down_req, ldb, req, - msg, - req->controls, - req, sample_add_callback, - req); - if (ret != LDB_SUCCESS) { - return ret; - } - - talloc_steal(down_req, msg); - - /* go on with the call chain */ - return ldb_next_request(mod, down_req); -} - -static int sample_modify(struct ldb_module *mod, struct ldb_request *req) -{ - struct ldb_control *control; - - /* check if there's a relax control */ - control = ldb_request_get_control(req, LDB_CONTROL_RELAX_OID); - if (control != NULL) { - return LDB_ERR_UNWILLING_TO_PERFORM; - } - - /* not found go on */ - return ldb_next_request(mod, req); -} - - -static struct ldb_module_ops ldb_sample_module_ops = { - .name = "sample", - .add = sample_add, - .del = sample_modify, - .modify = sample_modify, -}; - -int ldb_sample_init(const char *version) -{ - LDB_MODULE_CHECK_VERSION(version); - return ldb_register_module(&ldb_sample_module_ops); -} diff --git a/ldb-2.0.8/tests/schema-tests/schema-add-test.ldif b/ldb-2.0.8/tests/schema-tests/schema-add-test.ldif deleted file mode 100644 index 472ab48..0000000 --- a/ldb-2.0.8/tests/schema-tests/schema-add-test.ldif +++ /dev/null @@ -1,66 +0,0 @@ -dn: CN=Users,DC=schema,DC=test -objectClass: top -objectClass: container -cn: Users -description: Default container for upgraded user accounts -instanceType: 4 -whenCreated: 20050116175504.0Z -whenChanged: 20050116175504.0Z -uSNCreated: 1 -uSNChanged: 1 -showInAdvancedViewOnly: FALSE -name: Users -objectGUID: b847056a-9934-d87b-8a1a-99fabe0863c8 -systemFlags: 0x8c000000 -objectCategory: CN=Container,CN=Schema,CN=Configuration,DC=schema,DC=test -isCriticalSystemObject: TRUE -nTSecurityDescriptor: foo - -dn: CN=Administrator,CN=Users,DC=schema,DC=test -objectClass: top -objectClass: person -objectClass: organizationalPerson -objectClass: user -cn: Administrator -description: Built-in account for administering the computer/domain -instanceType: 4 -whenCreated: 20050116175504.0Z -whenChanged: 20050116175504.0Z -uSNCreated: 1 -memberOf: CN=Group Policy Creator Owners,CN=Users,DC=schema,DC=test -memberOf: CN=Domain Admins,CN=Users,DC=schema,DC=test -memberOf: CN=Enterprise Admins,CN=Users,DC=schema,DC=test -memberOf: CN=Schema Admins,CN=Users,DC=schema,DC=test -memberOf: CN=Administrators,CN=Builtin,DC=schema,DC=test -uSNChanged: 1 -name: Administrator -objectGUID: 6c02f98c-46c6-aa38-5f13-a510cac04e6c -userAccountControl: 0x10200 -badPwdCount: 0 -codePage: 0 -countryCode: 0 -badPasswordTime: 0 -lastLogoff: 0 -lastLogon: 0 -pwdLastSet: 0 -primaryGroupID: 513 -objectSid: S-1-5-21-43662522-77495566-38969261-500 -adminCount: 1 -accountExpires: 9223372036854775807 -logonCount: 0 -sAMAccountName: Administrator -sAMAccountType: 0x30000000 -objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=schema,DC=test -isCriticalSystemObject: TRUE -unicodePwd: samba -nTSecurityDescriptor: foo - -dn: CN=Test,CN=Users,DC=schema,DC=test -objectClass: top -objectClass: test -cn: Test -description: This is a test -objectCategory: CN=Test,CN=Schema,CN=Configuration,DC=schema,DC=test -nTSecurityDescriptor: foo -instanceType: 4 - diff --git a/ldb-2.0.8/tests/schema-tests/schema-mod-test-1.ldif b/ldb-2.0.8/tests/schema-tests/schema-mod-test-1.ldif deleted file mode 100644 index b976724..0000000 --- a/ldb-2.0.8/tests/schema-tests/schema-mod-test-1.ldif +++ /dev/null @@ -1,5 +0,0 @@ -dn: CN=Test,CN=Users,DC=schema,DC=test -changetype: modify -replace: description -description: this test must not fail - diff --git a/ldb-2.0.8/tests/schema-tests/schema-mod-test-2.ldif b/ldb-2.0.8/tests/schema-tests/schema-mod-test-2.ldif deleted file mode 100644 index fa193af..0000000 --- a/ldb-2.0.8/tests/schema-tests/schema-mod-test-2.ldif +++ /dev/null @@ -1,5 +0,0 @@ -dn: CN=Test,CN=Users,DC=schema,DC=test -changetype: modify -delete: description -# this test must not fail - diff --git a/ldb-2.0.8/tests/schema-tests/schema-mod-test-3.ldif b/ldb-2.0.8/tests/schema-tests/schema-mod-test-3.ldif deleted file mode 100644 index 8ab7798..0000000 --- a/ldb-2.0.8/tests/schema-tests/schema-mod-test-3.ldif +++ /dev/null @@ -1,5 +0,0 @@ -dn: CN=Test,CN=Users,DC=schema,DC=test -changetype: modify -add: description -description: this test must not fail - diff --git a/ldb-2.0.8/tests/schema-tests/schema-mod-test-4.ldif b/ldb-2.0.8/tests/schema-tests/schema-mod-test-4.ldif deleted file mode 100644 index cbf0e60..0000000 --- a/ldb-2.0.8/tests/schema-tests/schema-mod-test-4.ldif +++ /dev/null @@ -1,5 +0,0 @@ -dn: CN=Test,CN=Users,DC=schema,DC=test -changetype: modify -add: foo -foo: this test must fail - diff --git a/ldb-2.0.8/tests/schema-tests/schema-mod-test-5.ldif b/ldb-2.0.8/tests/schema-tests/schema-mod-test-5.ldif deleted file mode 100644 index bc64e9e..0000000 --- a/ldb-2.0.8/tests/schema-tests/schema-mod-test-5.ldif +++ /dev/null @@ -1,5 +0,0 @@ -dn: CN=Test,CN=Users,DC=schema,DC=test -changetype: modify -delete: nTSecurityDescriptor -# this test must fail - diff --git a/ldb-2.0.8/tests/schema-tests/schema.ldif b/ldb-2.0.8/tests/schema-tests/schema.ldif deleted file mode 100644 index 4ab1932..0000000 --- a/ldb-2.0.8/tests/schema-tests/schema.ldif +++ /dev/null @@ -1,100 +0,0 @@ -dn: @INDEXLIST -@IDXATTR: name -@IDXATTR: sAMAccountName -@IDXATTR: objectSid -@IDXATTR: objectClass -@IDXATTR: member -@IDXATTR: uidNumber -@IDXATTR: gidNumber -@IDXATTR: unixName -@IDXATTR: privilege -@IDXATTR: lDAPDisplayName - -dn: @ATTRIBUTES -realm: CASE_INSENSITIVE -userPrincipalName: CASE_INSENSITIVE -servicePrincipalName: CASE_INSENSITIVE -name: CASE_INSENSITIVE -dn: CASE_INSENSITIVE -sAMAccountName: CASE_INSENSITIVE -objectClass: CASE_INSENSITIVE -unicodePwd: HIDDEN -ntPwdHash: HIDDEN -ntPwdHistory: HIDDEN -lmPwdHash: HIDDEN -lmPwdHistory: HIDDEN -createTimestamp: HIDDEN -modifyTimestamp: HIDDEN - -dn: @MODULES -@LIST: timestamps,schema - -dn: CN=Top,CN=Schema,CN=Configuration,DC=schema,DC=test -objectClass: top -objectClass: classSchema -lDAPDisplayName: top -cn: Top -uSNCreated: 1 -uSNChanged: 1 -subClassOf: top -systemMustContain: objectClass -systemMayContain: structuralObjectClass -systemMayContain: createTimeStamp -systemMayContain: modifyTimeStamp -systemMayContain: creatorsName -systemMayContain: modifiersName -systemMayContain: hasSubordinates -systemMayContain: subschemaSubentry -systemMayContain: collectiveSubentry -systemMayContain: entryUUID -systemMayContain: entryCSN -systemMayContain: namingCSN -systemMayContain: superiorUUID -systemMayContain: contextCSN -systemMayContain: whenCreated -systemMayContain: whenChanged -systemMayContain: uSNCreated -systemMayContain: uSNChanged -systemMayContain: distinguishedName -systemMayContain: name -systemMayContain: cn -systemMayContain: userPassword -systemMayContain: labeledURI - -dn: CN=Class-Schema,CN=Schema,CN=Configuration,DC=schema,DC=test -objectClass: top -objectClass: classSchema -lDAPDisplayName: classSchema -cn: Class-Schema -uSNCreated: 2 -uSNChanged: 2 -lDAPDisplayName: classSchema -subClassOf: top -systemMustContain: cn -systemMustContain: subClassOf -systemMayContain: systemPossSuperiors -systemMayContain: systemOnly -systemMayContain: systemMustContain -systemMayContain: systemMayContain -systemMayContain: systemAuxiliaryClass -systemMayContain: possSuperiors -systemMayContain: mustContain -systemMayContain: mayContain -systemMayContain: lDAPDisplayName -systemMayContain: auxiliaryClass - -dn: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=schema,DC=test -objectClass: top -objectClass: classSchema -cn: Attribute-Schema -uSNCreated: 3 -uSNChanged: 3 -lDAPDisplayName: attributeSchema -subClassOf: top -systemMustContain: oMSyntax -systemMustContain: lDAPDisplayName -systemMustContain: isSingleValued -systemMustContain: cn -systemMustContain: attributeSyntax -systemMustContain: attributeID - diff --git a/ldb-2.0.8/tests/slapd.conf b/ldb-2.0.8/tests/slapd.conf deleted file mode 100644 index fa2789d..0000000 --- a/ldb-2.0.8/tests/slapd.conf +++ /dev/null @@ -1,26 +0,0 @@ -loglevel 0 - -include tests/schema/core.schema -include tests/schema/cosine.schema -include tests/schema/inetorgperson.schema -include tests/schema/openldap.schema -include tests/schema/nis.schema - - -pidfile tests/tmp/slapd.pid -argsfile tests/tmp/slapd.args - -access to * by * write - -allow update_anon bind_anon_dn - -include tests/tmp/modules.conf - -defaultsearchbase "o=University of Michigan,c=TEST" - -backend bdb -database bdb -suffix "o=University of Michigan,c=TEST" -directory tests/tmp/db -index objectClass eq -index uid eq diff --git a/ldb-2.0.8/tests/start_slapd.sh b/ldb-2.0.8/tests/start_slapd.sh deleted file mode 100755 index 11679d4..0000000 --- a/ldb-2.0.8/tests/start_slapd.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -if [ -z "$LDBDIR" ]; then - LDBDIR=`dirname $0`/.. - export LDBDIR -fi - -mkdir -p $LDBDIR/tests/tmp/db - -# running slapd in the background (with &) means it stays in the same process group, so it can be -# killed by timelimit -slapd -d0 -f $LDBDIR/tests/slapd.conf -h "`$LDBDIR/tests/ldapi_url.sh`" $* & - -sleep 2 diff --git a/ldb-2.0.8/tests/test-attribs.ldif b/ldb-2.0.8/tests/test-attribs.ldif deleted file mode 100644 index 79508c4..0000000 --- a/ldb-2.0.8/tests/test-attribs.ldif +++ /dev/null @@ -1,6 +0,0 @@ -dn: @ATTRIBUTES -uid: CASE_INSENSITIVE -cn: CASE_INSENSITIVE -ou: CASE_INSENSITIVE -dn: CASE_INSENSITIVE - diff --git a/ldb-2.0.8/tests/test-config.ldif b/ldb-2.0.8/tests/test-config.ldif deleted file mode 100644 index 7926a9e..0000000 --- a/ldb-2.0.8/tests/test-config.ldif +++ /dev/null @@ -1,67 +0,0 @@ -############################## -# global configuration options -dn: cn=Global,cn=Config,cn=Samba -objectclass: globalconfig -LocalConfigCn: cn=%U,cn=Config,cn=Samba -LocalConfigCn;1: cn=%U,cn=Config,cn=Samba -LocalConfigCn;2: cn=%I,cn=Config,cn=Samba -LocalConfigCn;3: cn=%M,cn=Config,cn=Samba - -############# -dn: cn=Protocol,cn=Global,cn=Config,cn=Samba -maxXmit: 7000 - -################################ -dn: cn=Volker,cn=Config,cn=Samba -Workgroup: VNET3 -UnixCharset: UTF8 -Security: user -Interfaces: vmnet* eth* -NetbiosName: blu -GuestAccount: tridge - -################################# -dn: cn=Volker,cn=Config,cn=Samba -Workgroup: VNET3 -UnixCharset: UTF8 -Security: user -Interfaces: vmnet* eth* -NetbiosName: blu -GuestAccount: tridge -Include: cn=%U,cn=MyConfig,cn=Config,cn=Samba - -#### ((objectClass=fileshare)(cn=test)) -############################## -# [test] share -dn: cn=test,cn=Shares,cn=Config,cn=Samba -objectclass: fileshare -cn: test -Comment: a test share -Path: /home/tridge/samba4/prefix/test -ReadOnly: no - -##################################### -# [msdn] a remote proxy share, stored -# on \\msdn\test -dn: cn=msdn,cn=Shares,cn=Config,cn=Samba -objectclass: fileshare -cn: msdn -NtvfsHandler: cifs -ReadOnly: no -_CifsServer: msdn -_CifsUser: administrator -_CifsPassword: penguin -_CifsDomain: winxp -_CifsShare: test - - -############################## -# [VisualC] share -dn: cn=visualc,cn=Shares,cn=Config,cn=Samba -objectclass: fileshare -cn: VisualC -Comment: VisualC development -Path: /home/tridge/VisualC -ReadOnly: no -NtvfsHandler: simple - diff --git a/ldb-2.0.8/tests/test-controls.sh b/ldb-2.0.8/tests/test-controls.sh deleted file mode 100755 index 328ed29..0000000 --- a/ldb-2.0.8/tests/test-controls.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh - -if [ -n "$TEST_DATA_PREFIX" ]; then - LDB_URL="$TEST_DATA_PREFIX/tdbtest.ldb" -else - LDB_URL="tdbtest.ldb" -fi -export LDB_URL - -PATH=bin:$PATH -export PATH - -rm -f $LDB_URL* - -echo "LDB_URL: $LDB_URL" -cat </dev/null 2>&1 && exit 1 -dn: dc=foobar -dc: foobar -someThing: someThingElse -EOF - -cat </dev/null 2>&1 && exit 1 -dn: dc=bar -changetype: modify -replace someThing -someThing: someThingElseBetter -EOF - -$VALGRIND ldbsearch --controls "bypassoperational:0" >/dev/null 2>&1 || exit 1 diff --git a/ldb-2.0.8/tests/test-default-config.ldif b/ldb-2.0.8/tests/test-default-config.ldif deleted file mode 100644 index 87b7bcd..0000000 --- a/ldb-2.0.8/tests/test-default-config.ldif +++ /dev/null @@ -1,17 +0,0 @@ -############################## -# global configuration options -dn: cn=Global,cn=DefaultConfig,cn=Samba -objectclass: globalconfig -Workgroup: WORKGROUP -UnixCharset: UTF8 -Security: user -NetbiosName: blu -GuestAccount: nobody - -############################## -# [_default_] share -dn: cn=_default_,cn=Shares,cn=DefaultConfig,cn=Samba -objectclass: fileshare -cn: _default_ -Path: /tmp -ReadOnly: yes diff --git a/ldb-2.0.8/tests/test-dup-2.ldif b/ldb-2.0.8/tests/test-dup-2.ldif deleted file mode 100644 index a426101..0000000 --- a/ldb-2.0.8/tests/test-dup-2.ldif +++ /dev/null @@ -1,6 +0,0 @@ -dn: cn=Sentinel,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST -objectclass: OpenLDAPperson -cn: Sentinel -sn: USER -uid: USER, Sentinel - diff --git a/ldb-2.0.8/tests/test-dup.ldif b/ldb-2.0.8/tests/test-dup.ldif deleted file mode 100644 index b35420b..0000000 --- a/ldb-2.0.8/tests/test-dup.ldif +++ /dev/null @@ -1,13 +0,0 @@ -dn: cn=Fred Bassett,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST -objectclass: OpenLDAPperson -cn: Fred Bassett -sn: Bassett -uid: Bassett, Fred - -dn: cn=Sentinel,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST -objectclass: OpenLDAPperson -cn: Sentinel -sn: USER -uid: USER, Sentinel - - diff --git a/ldb-2.0.8/tests/test-extended.sh b/ldb-2.0.8/tests/test-extended.sh deleted file mode 100755 index 0599757..0000000 --- a/ldb-2.0.8/tests/test-extended.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/sh - -echo "Running extended search tests" - -mv $LDB_URL $LDB_URL.1 - -cat < /dev/null && { - echo "Should have failed to add again - gave $?" - exit 1 -} - -echo "Adding LDIF with one already-existing user again - should fail" -$VALGRIND ldbadd $LDBDIR/tests/test-dup.ldif 2> /dev/null && { - echo "Should have failed to add again - gave $?" - exit 1 -} - -echo "Adding again - should succeed (as previous failed)" -$VALGRIND ldbadd $LDBDIR/tests/test-dup-2.ldif || exit 1 - -echo "Modifying elements" -$VALGRIND ldbmodify $LDBDIR/tests/test-modify.ldif || exit 1 - -echo "Modify LDIF with one un-met constraint - should fail" -$VALGRIND ldbadd $LDBDIR/tests/test-modify-unmet.ldif 2> /dev/null && { - echo "Should have failed to modify - gave $?" - exit 1 -} - -echo "Modify LDIF with after failure of un-met constraint - should also fail" -$VALGRIND ldbadd $LDBDIR/tests/test-modify-unmet-2.ldif 2> /dev/null && { - echo "Should have failed to modify - gave $?" - exit 1 -} - -echo "Showing modified record" -$VALGRIND ldbsearch '(uid=uham)' || exit 1 - -echo "Rename entry with ldbmodify - modrdn" -$VALGRIND ldbmodify $LDBDIR/tests/test-modify-modrdn.ldif || exit 1 - -echo "Rename entry with ldbrename" -OLDDN="cn=Ursula Hampster,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST" -NEWDN="cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST" -$VALGRIND ldbrename "$OLDDN" "$NEWDN" || exit 1 - -echo "Showing renamed record" -$VALGRIND ldbsearch '(uid=uham)' || exit 1 - -echo "Starting ldbtest" -$VALGRIND ldbtest --num-records 100 --num-searches 10 || exit 1 - -if [ $LDB_SPECIALS = 1 ]; then - echo "Adding index" - $VALGRIND ldbadd $LDBDIR/tests/test-index.ldif || exit 1 -fi - -echo "Adding bad attributes - should fail" -$VALGRIND ldbadd $LDBDIR/tests/test-wrong_attributes.ldif && { - echo "Should fhave failed - gave $?" - exit 1 -} - -echo "Testing indexed search" -$VALGRIND ldbsearch '(uid=uham)' || exit 1 -$VALGRIND ldbsearch '(&(objectclass=person)(objectclass=person)(objectclass=top))' || exit 1 -$VALGRIND ldbsearch '(&(uid=uham)(uid=uham))' || exit 1 -$VALGRIND ldbsearch '(|(uid=uham)(uid=uham))' || exit 1 -$VALGRIND ldbsearch '(|(uid=uham)(uid=uham)(objectclass=OpenLDAPperson))' || exit 1 -$VALGRIND ldbsearch '(&(uid=uham)(uid=uham)(!(objectclass=xxx)))' || exit 1 -$VALGRIND ldbsearch '(&(objectclass=person)(uid=uham)(!(uid=uhamxx)))' uid \* \+ dn || exit 1 -$VALGRIND ldbsearch '(&(uid=uham)(uid=uha*)(title=*))' uid || exit 1 - -echo "Testing invalid search expression" -$VALGRIND ldbsearch '(&(uid=uham)(title=foo\blah))' uid && exit 1 - -# note that the "((" is treated as an attribute not an expression -# this matches the openldap ldapsearch behaviour of looking for a '=' -# to see if the first argument is an expression or not -$VALGRIND ldbsearch '((' uid || exit 1 -$VALGRIND ldbsearch '(objectclass=)' uid || exit 1 -$VALGRIND ldbsearch -b 'cn=Hampster Ursula,ou=Alumni Association,ou=People,o=University of Michigan,c=TEST' -s base "" sn || exit 1 - -echo "Test wildcard match" -$VALGRIND ldbadd $LDBDIR/tests/test-wildcard.ldif || exit 1 -$VALGRIND ldbsearch '(cn=test*multi)' || exit 1 -$VALGRIND ldbsearch '(cn=*test*multi*)' || exit 1 -$VALGRIND ldbsearch '(cn=*test_multi)' || exit 1 -$VALGRIND ldbsearch '(cn=test_multi*)' || exit 1 -$VALGRIND ldbsearch '(cn=test*multi*test*multi)' || exit 1 -$VALGRIND ldbsearch '(cn=test*multi*test*multi*multi_*)' || exit 1 - -echo "Starting ldbtest indexed" -$VALGRIND ldbtest --num-records 100 --num-searches 500 || exit 1 - -echo "Testing one level search" -count=`$VALGRIND ldbsearch -b 'ou=Groups,o=University of Michigan,c=TEST' -s one 'objectclass=*' none |grep '^dn' | wc -l` -if [ $count != 3 ]; then - echo returned $count records - expected 3 - exit 1 -fi - -echo "Testing binary file attribute value" -$VALGRIND ldbmodify $LDBDIR/tests/photo.ldif || exit 1 -count=`$VALGRIND ldbsearch '(cn=Hampster Ursula)' jpegPhoto | grep '^dn' | wc -l` -if [ $count != 1 ]; then - echo returned $count records - expected 1 - exit 1 -fi - -echo "*TODO* Testing UTF8 upper lower case searches !!" - -echo "Testing compare" -count=`$VALGRIND ldbsearch '(cn>=t)' cn | grep '^dn' | wc -l` -if [ $count != 1 ]; then - # only "cn: test_multi_test_multi_test_multi" (comes after "t") - # upper-cased words come before "t" - hence excluded - echo returned $count records - expected 1 - exit 1 -fi -$VALGRIND ldbsearch '(cn>t)' cn && exit 1 # strictly greater should not work - -count=`$VALGRIND ldbsearch '(cn<=t)' cn | grep '^dn' | wc -l` -if [ $count != 18 ]; then - # everything except "cn: test_multi_test_multi_test_multi" (comes after "t") - # upper-cased letters come before "t" - hence included - echo returned $count records - expected 18 - exit 1 -fi -$VALGRIND ldbsearch '(cn - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include - -#include -#include "ldb_private.h" - -static void test_ldb_dn_add_child_fmt(void **state) -{ - struct ldb_context *ldb = ldb_init(NULL, NULL); - - struct ldb_dn *dn = ldb_dn_new(ldb, ldb, "dc=samba,dc=org"); - - assert_true(ldb_dn_add_child_fmt(dn, - "DC=X")); - - assert_string_equal("DC=X,dc=samba,dc=org", - ldb_dn_get_linearized(dn)); - - assert_string_equal("DC=X,DC=SAMBA,DC=ORG", - ldb_dn_get_casefold(dn)); - -} - -static void test_ldb_dn_add_child_fmt2(void **state) -{ - struct ldb_context *ldb = ldb_init(NULL, NULL); - - struct ldb_dn *dn = ldb_dn_new(ldb, ldb, "dc=samba,dc=org"); - - assert_true(ldb_dn_add_child_fmt(dn, - "DC=X,DC=Y")); - - assert_string_equal("DC=X,DC=Y,dc=samba,dc=org", - ldb_dn_get_linearized(dn)); - - assert_string_equal("DC=X,DC=Y,DC=SAMBA,DC=ORG", - ldb_dn_get_casefold(dn)); - - assert_int_equal(4, - ldb_dn_get_comp_num(dn)); - -} - -static void test_ldb_dn_add_child_val(void **state) -{ - struct ldb_context *ldb = ldb_init(NULL, NULL); - - struct ldb_dn *dn = ldb_dn_new(ldb, ldb, "dc=samba,dc=org"); - struct ldb_val name = {.data = discard_const("X"), - .length = 1 - }; - - assert_true(ldb_dn_add_child_val(dn, - "DC", name)); - - assert_string_equal("DC=X,dc=samba,dc=org", - ldb_dn_get_linearized(dn)); - - assert_string_equal("DC=X,DC=SAMBA,DC=ORG", - ldb_dn_get_casefold(dn)); - -} - -static void test_ldb_dn_add_child_val2(void **state) -{ - struct ldb_context *ldb = ldb_init(NULL, NULL); - - struct ldb_dn *dn = ldb_dn_new(ldb, ldb, "dc=samba,dc=org"); - - struct ldb_val name = {.data = discard_const("X,DC=Y"), - .length = 6 - }; - - assert_true(ldb_dn_add_child_val(dn, - "DC", name)); - - assert_string_equal("DC=X\\,DC\\3DY,dc=samba,dc=org", - ldb_dn_get_linearized(dn)); - - assert_string_equal("DC=X\\,DC\\3DY,DC=SAMBA,DC=ORG", - ldb_dn_get_casefold(dn)); - - assert_int_equal(3, - ldb_dn_get_comp_num(dn)); - -} - -struct explode_test { - const char *strdn; - int comp_num; - int ext_comp_num; - bool special; - bool invalid; - const char *linearized; - const char *ext_linearized_1; - bool explode_result; -}; - -static int extended_dn_read_ID(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - - /* Allow to check we can cope with validity checks */ - if (in->length != 4) { - return -1; - } - - *out = *in; - out->data = talloc_memdup(mem_ctx, in->data, in->length); - if (out->data == NULL) { - return -1; - } - - return 0; -} - -/* write out (resued for both HEX and clear for now) */ -static int extended_dn_write_ID(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *in, struct ldb_val *out) -{ - *out = *in; - - out->data = talloc_memdup(mem_ctx, in->data, in->length); - if (out->data == NULL) { - return -1; - } - return 0; -} - - -static void test_ldb_dn_explode(void **state) -{ - size_t i; - struct ldb_context *ldb = ldb_init(NULL, NULL); - struct explode_test tests[] = { - {"A=B", 1, 0, false, false, "A=B", "A=B", true}, - {"", 0, 0, false, false, "", "", true}, - {" ", -1, -1, false, false, " ", " ", false}, - {"<>", 0, 0, false, false, "", NULL, true}, - {"<", 0, 0, false, false, "", NULL, true}, - {"<><", 0, 0, false, false, "", NULL, true}, - {"<><>", 0, 0, false, false, "", NULL, true}, - {"A=B,C=D", 2, 0, false, false, "A=B,C=D", "A=B,C=D", true}, - {"A=B,C=D", -1, -1, false, false, "", NULL, false}, - {";A=B,C=D", -1, -1, false, false, "A=B,C=D", NULL, false}, - {";A=B,C=D", -1, -1, false, true, "A=B,C=D", NULL, false}, - {";A=B,C=D", 2, 1, false, false, "A=B,C=D", ";A=B,C=D", true}, - {"x=🔥", 1, 0, false, false, "x=🔥", "x=🔥", true}, - {"@FOO", 0, 0, true, false, "@FOO", "@FOO", true}, - }; - - struct ldb_dn_extended_syntax syntax = { - .name = "ID", - .read_fn = extended_dn_read_ID, - .write_clear_fn = extended_dn_write_ID, - .write_hex_fn = extended_dn_write_ID - }; - - ldb_dn_extended_add_syntax(ldb, 0, &syntax); - - for (i = 0; i < ARRAY_SIZE(tests); i++) { - bool result; - const char *linear; - const char *ext_linear; - struct ldb_dn *dn = ldb_dn_new(ldb, ldb, tests[i].strdn); - - /* - * special, invalid, linear, and ext_linear are set before - * explode - */ - fprintf(stderr, "%zu «%s»: ", i, tests[i].strdn); - linear = ldb_dn_get_linearized(dn); - assert_true((linear == NULL) == (tests[i].linearized == NULL)); - assert_string_equal(linear, - tests[i].linearized); - - ext_linear = ldb_dn_get_extended_linearized(ldb, dn, 1); - assert_true((ext_linear == NULL) == - (tests[i].ext_linearized_1 == NULL)); - - if (tests[i].ext_linearized_1 != NULL) { - assert_string_equal(ext_linear, - tests[i].ext_linearized_1); - } - assert_true(ldb_dn_is_special(dn) == tests[i].special); - assert_true(ldb_dn_is_valid(dn) != tests[i].invalid); - - /* comp nums are set by explode */ - result = ldb_dn_validate(dn); - fprintf(stderr, "res %i lin «%s» ext «%s»\n", - result, linear, ext_linear); - - assert_true(result == tests[i].explode_result); - assert_int_equal(ldb_dn_get_comp_num(dn), - tests[i].comp_num); - assert_int_equal(ldb_dn_get_extended_comp_num(dn), - tests[i].ext_comp_num); - } -} - -int main(void) { - const struct CMUnitTest tests[] = { - cmocka_unit_test(test_ldb_dn_add_child_fmt), - cmocka_unit_test(test_ldb_dn_add_child_fmt2), - cmocka_unit_test(test_ldb_dn_add_child_val), - cmocka_unit_test(test_ldb_dn_add_child_val2), - cmocka_unit_test(test_ldb_dn_explode), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/ldb-2.0.8/tests/test_ldb_qsort.c b/ldb-2.0.8/tests/test_ldb_qsort.c deleted file mode 100644 index 663cf0e..0000000 --- a/ldb-2.0.8/tests/test_ldb_qsort.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * Copyright (C) 2018 Andreas Schneider - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include - -#include - -static int cmp_integer(int *a, int *b, void *opaque) -{ - if (a == NULL || b == NULL) { - return 0; - } - - if (*a > *b) { - return 1; - } - - if (*a < *b) { - return -1; - } - - return 0; -} - -static void test_ldb_qsort(void **state) -{ - int a[6] = { 6, 3, 2, 7, 9, 4 }; - - ldb_qsort(a, 6, sizeof(int), NULL, (ldb_qsort_cmp_fn_t)cmp_integer); - - assert_int_equal(a[0], 2); - assert_int_equal(a[1], 3); - assert_int_equal(a[2], 4); - assert_int_equal(a[3], 6); - assert_int_equal(a[4], 7); - assert_int_equal(a[5], 9); -} - -int main(void) { - const struct CMUnitTest tests[] = { - cmocka_unit_test(test_ldb_qsort), - }; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/ldb-2.0.8/tests/testdata.txt b/ldb-2.0.8/tests/testdata.txt deleted file mode 100644 index dadb9f0..0000000 --- a/ldb-2.0.8/tests/testdata.txt +++ /dev/null @@ -1,8 +0,0 @@ -foo=bar5 -(&(|(a=b)(c=d))(e=f)) -(&(|(a=b)(c=d)(g=h))(e=f)) -name=firstname lastname -(&(sid=S-1-2-3)(name = fred bloggs)) -(&(|(a=b)(c=d))(g=f)) -(&(sid=S-1-2-3)(!(name = fred bloggs))) -(&(!(|(a=b)(c=d))(g=f))) diff --git a/ldb-2.0.8/tests/testsearch.txt b/ldb-2.0.8/tests/testsearch.txt deleted file mode 100644 index c573863..0000000 --- a/ldb-2.0.8/tests/testsearch.txt +++ /dev/null @@ -1,5 +0,0 @@ -(blah=foo) -(objectclass=person) -(dn=*) -(&(objectclass=person)(objectclass=person)) -(&(objectclass=person)(objectclass=personx)) diff --git a/ldb-2.0.8/third_party/cmocka/cmocka.c b/ldb-2.0.8/third_party/cmocka/cmocka.c deleted file mode 100644 index b21fe15..0000000 --- a/ldb-2.0.8/third_party/cmocka/cmocka.c +++ /dev/null @@ -1,3431 +0,0 @@ -/* - * Copyright 2008 Google Inc. - * Copyright 2014-2018 Andreas Schneider - * Copyright 2015 Jakub Hrozek - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_MALLOC_H -#include -#endif - -#ifdef HAVE_INTTYPES_H -#include -#endif - -#ifdef HAVE_SIGNAL_H -#include -#endif - -#ifdef HAVE_STRINGS_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * This allows to add a platform specific header file. Some embedded platforms - * sometimes miss certain types and definitions. - * - * Example: - * - * typedef unsigned long int uintptr_t - * #define _UINTPTR_T 1 - * #define _UINTPTR_T_DEFINED 1 - */ -#ifdef CMOCKA_PLATFORM_INCLUDE -# include "cmocka_platform.h" -#endif /* CMOCKA_PLATFORM_INCLUDE */ - -#include -#include - -/* Size of guard bytes around dynamically allocated blocks. */ -#define MALLOC_GUARD_SIZE 16 -/* Pattern used to initialize guard blocks. */ -#define MALLOC_GUARD_PATTERN 0xEF -/* Pattern used to initialize memory allocated with test_malloc(). */ -#define MALLOC_ALLOC_PATTERN 0xBA -#define MALLOC_FREE_PATTERN 0xCD -/* Alignment of allocated blocks. NOTE: This must be base2. */ -#define MALLOC_ALIGNMENT sizeof(size_t) - -/* Printf formatting for source code locations. */ -#define SOURCE_LOCATION_FORMAT "%s:%u" - -#if defined(HAVE_GCC_THREAD_LOCAL_STORAGE) -# define CMOCKA_THREAD __thread -#elif defined(HAVE_MSVC_THREAD_LOCAL_STORAGE) -# define CMOCKA_THREAD __declspec(thread) -#else -# define CMOCKA_THREAD -#endif - -#ifdef HAVE_CLOCK_REALTIME -#define CMOCKA_CLOCK_GETTIME(clock_id, ts) clock_gettime((clock_id), (ts)) -#else -#define CMOCKA_CLOCK_GETTIME(clock_id, ts) -#endif - -#ifndef MAX -#define MAX(a,b) ((a) < (b) ? (b) : (a)) -#endif - -/** - * POSIX has sigsetjmp/siglongjmp, while Windows only has setjmp/longjmp. - */ -#ifdef HAVE_SIGLONGJMP -# define cm_jmp_buf sigjmp_buf -# define cm_setjmp(env) sigsetjmp(env, 1) -# define cm_longjmp(env, val) siglongjmp(env, val) -#else -# define cm_jmp_buf jmp_buf -# define cm_setjmp(env) setjmp(env) -# define cm_longjmp(env, val) longjmp(env, val) -#endif - - -/* - * Declare and initialize the pointer member of ValuePointer variable name - * with ptr. - */ -#define declare_initialize_value_pointer_pointer(name, ptr) \ - ValuePointer name ; \ - name.value = 0; \ - name.x.pointer = (void*)(ptr) - -/* - * Declare and initialize the value member of ValuePointer variable name - * with val. - */ -#define declare_initialize_value_pointer_value(name, val) \ - ValuePointer name ; \ - name.value = val - -/* Cast a LargestIntegralType to pointer_type via a ValuePointer. */ -#define cast_largest_integral_type_to_pointer( \ - pointer_type, largest_integral_type) \ - ((pointer_type)((ValuePointer*)&(largest_integral_type))->x.pointer) - -/* Used to cast LargetIntegralType to void* and vice versa. */ -typedef union ValuePointer { - LargestIntegralType value; - struct { -#if defined(WORDS_BIGENDIAN) && (WORDS_SIZEOF_VOID_P == 4) - unsigned int padding; -#endif - void *pointer; - } x; -} ValuePointer; - -/* Doubly linked list node. */ -typedef struct ListNode { - const void *value; - int refcount; - struct ListNode *next; - struct ListNode *prev; -} ListNode; - -/* Debug information for malloc(). */ -struct MallocBlockInfoData { - void* block; /* Address of the block returned by malloc(). */ - size_t allocated_size; /* Total size of the allocated block. */ - size_t size; /* Request block size. */ - SourceLocation location; /* Where the block was allocated. */ - ListNode node; /* Node within list of all allocated blocks. */ -}; - -typedef union { - struct MallocBlockInfoData *data; - char *ptr; -} MallocBlockInfo; - -/* State of each test. */ -typedef struct TestState { - const ListNode *check_point; /* Check point of the test if there's a */ - /* setup function. */ - void *state; /* State associated with the test. */ -} TestState; - -/* Determines whether two values are the same. */ -typedef int (*EqualityFunction)(const void *left, const void *right); - -/* Value of a symbol and the place it was declared. */ -typedef struct SymbolValue { - SourceLocation location; - LargestIntegralType value; -} SymbolValue; - -/* - * Contains a list of values for a symbol. - * NOTE: Each structure referenced by symbol_values_list_head must have a - * SourceLocation as its' first member. - */ -typedef struct SymbolMapValue { - const char *symbol_name; - ListNode symbol_values_list_head; -} SymbolMapValue; - -/* Where a particular ordering was located and its symbol name */ -typedef struct FuncOrderingValue { - SourceLocation location; - const char * function; -} FuncOrderingValue; - -/* Used by list_free() to deallocate values referenced by list nodes. */ -typedef void (*CleanupListValue)(const void *value, void *cleanup_value_data); - -/* Structure used to check the range of integer types.a */ -typedef struct CheckIntegerRange { - CheckParameterEvent event; - LargestIntegralType minimum; - LargestIntegralType maximum; -} CheckIntegerRange; - -/* Structure used to check whether an integer value is in a set. */ -typedef struct CheckIntegerSet { - CheckParameterEvent event; - const LargestIntegralType *set; - size_t size_of_set; -} CheckIntegerSet; - -/* Used to check whether a parameter matches the area of memory referenced by - * this structure. */ -typedef struct CheckMemoryData { - CheckParameterEvent event; - const void *memory; - size_t size; -} CheckMemoryData; - -static ListNode* list_initialize(ListNode * const node); -static ListNode* list_add(ListNode * const head, ListNode *new_node); -static ListNode* list_add_value(ListNode * const head, const void *value, - const int count); -static ListNode* list_remove( - ListNode * const node, const CleanupListValue cleanup_value, - void * const cleanup_value_data); -static void list_remove_free( - ListNode * const node, const CleanupListValue cleanup_value, - void * const cleanup_value_data); -static int list_empty(const ListNode * const head); -static int list_find( - ListNode * const head, const void *value, - const EqualityFunction equal_func, ListNode **output); -static int list_first(ListNode * const head, ListNode **output); -static ListNode* list_free( - ListNode * const head, const CleanupListValue cleanup_value, - void * const cleanup_value_data); - -static void add_symbol_value( - ListNode * const symbol_map_head, const char * const symbol_names[], - const size_t number_of_symbol_names, const void* value, const int count); -static int get_symbol_value( - ListNode * const symbol_map_head, const char * const symbol_names[], - const size_t number_of_symbol_names, void **output); -static void free_value(const void *value, void *cleanup_value_data); -static void free_symbol_map_value( - const void *value, void *cleanup_value_data); -static void remove_always_return_values(ListNode * const map_head, - const size_t number_of_symbol_names); - -static size_t check_for_leftover_values_list(const ListNode * head, - const char * const error_message); - -static size_t check_for_leftover_values( - const ListNode * const map_head, const char * const error_message, - const size_t number_of_symbol_names); - -static void remove_always_return_values_from_list(ListNode * const map_head); - -/* - * This must be called at the beginning of a test to initialize some data - * structures. - */ -static void initialize_testing(const char *test_name); - -/* This must be called at the end of a test to free() allocated structures. */ -static void teardown_testing(const char *test_name); - -static enum cm_message_output cm_get_output(void); - -static int cm_error_message_enabled = 1; -static CMOCKA_THREAD char *cm_error_message; - -void cm_print_error(const char * const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); - -/* - * Keeps track of the calling context returned by setenv() so that the fail() - * method can jump out of a test. - */ -static CMOCKA_THREAD cm_jmp_buf global_run_test_env; -static CMOCKA_THREAD int global_running_test = 0; - -/* Keeps track of the calling context returned by setenv() so that */ -/* mock_assert() can optionally jump back to expect_assert_failure(). */ -jmp_buf global_expect_assert_env; -int global_expecting_assert = 0; -const char *global_last_failed_assert = NULL; -static int global_skip_test; - -/* Keeps a map of the values that functions will have to return to provide */ -/* mocked interfaces. */ -static CMOCKA_THREAD ListNode global_function_result_map_head; -/* Location of the last mock value returned was declared. */ -static CMOCKA_THREAD SourceLocation global_last_mock_value_location; - -/* Keeps a map of the values that functions expect as parameters to their - * mocked interfaces. */ -static CMOCKA_THREAD ListNode global_function_parameter_map_head; -/* Location of last parameter value checked was declared. */ -static CMOCKA_THREAD SourceLocation global_last_parameter_location; - -/* List (acting as FIFO) of call ordering. */ -static CMOCKA_THREAD ListNode global_call_ordering_head; -/* Location of last call ordering that was declared. */ -static CMOCKA_THREAD SourceLocation global_last_call_ordering_location; - -/* List of all currently allocated blocks. */ -static CMOCKA_THREAD ListNode global_allocated_blocks; - -static enum cm_message_output global_msg_output = CM_OUTPUT_STDOUT; - -static const char *global_test_filter_pattern; - -#ifndef _WIN32 -/* Signals caught by exception_handler(). */ -static const int exception_signals[] = { - SIGFPE, - SIGILL, - SIGSEGV, -#ifdef SIGBUS - SIGBUS, -#endif -#ifdef SIGSYS - SIGSYS, -#endif -}; - -/* Default signal functions that should be restored after a test is complete. */ -typedef void (*SignalFunction)(int signal); -static SignalFunction default_signal_functions[ - ARRAY_SIZE(exception_signals)]; - -#else /* _WIN32 */ - -/* The default exception filter. */ -static LPTOP_LEVEL_EXCEPTION_FILTER previous_exception_filter; - -/* Fatal exceptions. */ -typedef struct ExceptionCodeInfo { - DWORD code; - const char* description; -} ExceptionCodeInfo; - -#define EXCEPTION_CODE_INFO(exception_code) {exception_code, #exception_code} - -static const ExceptionCodeInfo exception_codes[] = { - EXCEPTION_CODE_INFO(EXCEPTION_ACCESS_VIOLATION), - EXCEPTION_CODE_INFO(EXCEPTION_ARRAY_BOUNDS_EXCEEDED), - EXCEPTION_CODE_INFO(EXCEPTION_DATATYPE_MISALIGNMENT), - EXCEPTION_CODE_INFO(EXCEPTION_FLT_DENORMAL_OPERAND), - EXCEPTION_CODE_INFO(EXCEPTION_FLT_DIVIDE_BY_ZERO), - EXCEPTION_CODE_INFO(EXCEPTION_FLT_INEXACT_RESULT), - EXCEPTION_CODE_INFO(EXCEPTION_FLT_INVALID_OPERATION), - EXCEPTION_CODE_INFO(EXCEPTION_FLT_OVERFLOW), - EXCEPTION_CODE_INFO(EXCEPTION_FLT_STACK_CHECK), - EXCEPTION_CODE_INFO(EXCEPTION_FLT_UNDERFLOW), - EXCEPTION_CODE_INFO(EXCEPTION_GUARD_PAGE), - EXCEPTION_CODE_INFO(EXCEPTION_ILLEGAL_INSTRUCTION), - EXCEPTION_CODE_INFO(EXCEPTION_INT_DIVIDE_BY_ZERO), - EXCEPTION_CODE_INFO(EXCEPTION_INT_OVERFLOW), - EXCEPTION_CODE_INFO(EXCEPTION_INVALID_DISPOSITION), - EXCEPTION_CODE_INFO(EXCEPTION_INVALID_HANDLE), - EXCEPTION_CODE_INFO(EXCEPTION_IN_PAGE_ERROR), - EXCEPTION_CODE_INFO(EXCEPTION_NONCONTINUABLE_EXCEPTION), - EXCEPTION_CODE_INFO(EXCEPTION_PRIV_INSTRUCTION), - EXCEPTION_CODE_INFO(EXCEPTION_STACK_OVERFLOW), -}; -#endif /* !_WIN32 */ - -enum CMUnitTestStatus { - CM_TEST_NOT_STARTED, - CM_TEST_PASSED, - CM_TEST_FAILED, - CM_TEST_ERROR, - CM_TEST_SKIPPED, -}; - -struct CMUnitTestState { - const ListNode *check_point; /* Check point of the test if there's a setup function. */ - const struct CMUnitTest *test; /* Point to array element in the tests we get passed */ - void *state; /* State associated with the test */ - const char *error_message; /* The error messages by the test */ - enum CMUnitTestStatus status; /* PASSED, FAILED, ABORT ... */ - double runtime; /* Time calculations */ -}; - -/* Exit the currently executing test. */ -static void exit_test(const int quit_application) -{ - const char *env = getenv("CMOCKA_TEST_ABORT"); - int abort_test = 0; - - if (env != NULL && strlen(env) == 1) { - abort_test = (env[0] == '1'); - } - - if (global_skip_test == 0 && - abort_test == 1) { - print_error("%s", cm_error_message); - abort(); - } else if (global_running_test) { - cm_longjmp(global_run_test_env, 1); - } else if (quit_application) { - exit(-1); - } -} - -void _skip(const char * const file, const int line) -{ - cm_print_error(SOURCE_LOCATION_FORMAT ": Skipped!\n", file, line); - global_skip_test = 1; - exit_test(1); -} - -/* Initialize a SourceLocation structure. */ -static void initialize_source_location(SourceLocation * const location) { - assert_non_null(location); - location->file = NULL; - location->line = 0; -} - - -/* Determine whether a source location is currently set. */ -static int source_location_is_set(const SourceLocation * const location) { - assert_non_null(location); - return location->file && location->line; -} - - -/* Set a source location. */ -static void set_source_location( - SourceLocation * const location, const char * const file, - const int line) { - assert_non_null(location); - location->file = file; - location->line = line; -} - - -static int c_strreplace(char *src, - size_t src_len, - const char *pattern, - const char *repl, - int *str_replaced) -{ - char *p = NULL; - - p = strstr(src, pattern); - if (p == NULL) { - return -1; - } - - do { - size_t of = p - src; - size_t l = strlen(src); - size_t pl = strlen(pattern); - size_t rl = strlen(repl); - - /* overflow check */ - if (src_len <= l + MAX(pl, rl) + 1) { - return -1; - } - - if (rl != pl) { - memmove(src + of + rl, src + of + pl, l - of - pl + 1); - } - - memcpy(src + of, repl, rl); - - if (str_replaced != NULL) { - *str_replaced = 1; - } - p = strstr(src, pattern); - } while (p != NULL); - - return 0; -} - -static int c_strmatch(const char *str, const char *pattern) -{ - int ok; - - if (str == NULL || pattern == NULL) { - return 0; - } - - for (;;) { - /* Check if pattern is done */ - if (*pattern == '\0') { - /* If string is at the end, we're good */ - if (*str == '\0') { - return 1; - } - - return 0; - } - - if (*pattern == '*') { - /* Move on */ - pattern++; - - /* If we are at the end, everything is fine */ - if (*pattern == '\0') { - return 1; - } - - /* Try to match each position */ - for (; *str != '\0'; str++) { - ok = c_strmatch(str, pattern); - if (ok) { - return 1; - } - } - - /* No match */ - return 0; - } - - /* If we are at the end, leave */ - if (*str == '\0') { - return 0; - } - - /* Check if we have a single wildcard or matching char */ - if (*pattern != '?' && *str != *pattern) { - return 0; - } - - /* Move string and pattern */ - str++; - pattern++; - } - - return 0; -} - -/* Create function results and expected parameter lists. */ -void initialize_testing(const char *test_name) { - (void)test_name; - list_initialize(&global_function_result_map_head); - initialize_source_location(&global_last_mock_value_location); - list_initialize(&global_function_parameter_map_head); - initialize_source_location(&global_last_parameter_location); - list_initialize(&global_call_ordering_head); - initialize_source_location(&global_last_parameter_location); -} - - -static void fail_if_leftover_values(const char *test_name) { - int error_occurred = 0; - (void)test_name; - remove_always_return_values(&global_function_result_map_head, 1); - if (check_for_leftover_values( - &global_function_result_map_head, - "%s() has remaining non-returned values.\n", 1)) { - error_occurred = 1; - } - - remove_always_return_values(&global_function_parameter_map_head, 2); - if (check_for_leftover_values( - &global_function_parameter_map_head, - "'%s' parameter still has values that haven't been checked.\n", - 2)) { - error_occurred = 1; - } - - remove_always_return_values_from_list(&global_call_ordering_head); - if (check_for_leftover_values_list(&global_call_ordering_head, - "%s function was expected to be called but was not not.\n")) { - error_occurred = 1; - } - if (error_occurred) { - exit_test(1); - } -} - - -static void teardown_testing(const char *test_name) { - (void)test_name; - list_free(&global_function_result_map_head, free_symbol_map_value, - (void*)0); - initialize_source_location(&global_last_mock_value_location); - list_free(&global_function_parameter_map_head, free_symbol_map_value, - (void*)1); - initialize_source_location(&global_last_parameter_location); - list_free(&global_call_ordering_head, free_value, - (void*)0); - initialize_source_location(&global_last_call_ordering_location); -} - -/* Initialize a list node. */ -static ListNode* list_initialize(ListNode * const node) { - node->value = NULL; - node->next = node; - node->prev = node; - node->refcount = 1; - return node; -} - - -/* - * Adds a value at the tail of a given list. - * The node referencing the value is allocated from the heap. - */ -static ListNode* list_add_value(ListNode * const head, const void *value, - const int refcount) { - ListNode * const new_node = (ListNode*)malloc(sizeof(ListNode)); - assert_non_null(head); - assert_non_null(value); - new_node->value = value; - new_node->refcount = refcount; - return list_add(head, new_node); -} - - -/* Add new_node to the end of the list. */ -static ListNode* list_add(ListNode * const head, ListNode *new_node) { - assert_non_null(head); - assert_non_null(new_node); - new_node->next = head; - new_node->prev = head->prev; - head->prev->next = new_node; - head->prev = new_node; - return new_node; -} - - -/* Remove a node from a list. */ -static ListNode* list_remove( - ListNode * const node, const CleanupListValue cleanup_value, - void * const cleanup_value_data) { - assert_non_null(node); - node->prev->next = node->next; - node->next->prev = node->prev; - if (cleanup_value) { - cleanup_value(node->value, cleanup_value_data); - } - return node; -} - - -/* Remove a list node from a list and free the node. */ -static void list_remove_free( - ListNode * const node, const CleanupListValue cleanup_value, - void * const cleanup_value_data) { - assert_non_null(node); - free(list_remove(node, cleanup_value, cleanup_value_data)); -} - - -/* - * Frees memory kept by a linked list The cleanup_value function is called for - * every "value" field of nodes in the list, except for the head. In addition - * to each list value, cleanup_value_data is passed to each call to - * cleanup_value. The head of the list is not deallocated. - */ -static ListNode* list_free( - ListNode * const head, const CleanupListValue cleanup_value, - void * const cleanup_value_data) { - assert_non_null(head); - while (!list_empty(head)) { - list_remove_free(head->next, cleanup_value, cleanup_value_data); - } - return head; -} - - -/* Determine whether a list is empty. */ -static int list_empty(const ListNode * const head) { - assert_non_null(head); - return head->next == head; -} - - -/* - * Find a value in the list using the equal_func to compare each node with the - * value. - */ -static int list_find(ListNode * const head, const void *value, - const EqualityFunction equal_func, ListNode **output) { - ListNode *current; - assert_non_null(head); - for (current = head->next; current != head; current = current->next) { - if (equal_func(current->value, value)) { - *output = current; - return 1; - } - } - return 0; -} - -/* Returns the first node of a list */ -static int list_first(ListNode * const head, ListNode **output) { - ListNode *target_node = NULL; - assert_non_null(head); - if (list_empty(head)) { - return 0; - } - target_node = head->next; - *output = target_node; - return 1; -} - - -/* Deallocate a value referenced by a list. */ -static void free_value(const void *value, void *cleanup_value_data) { - (void)cleanup_value_data; - assert_non_null(value); - free((void*)value); -} - - -/* Releases memory associated to a symbol_map_value. */ -static void free_symbol_map_value(const void *value, - void *cleanup_value_data) { - SymbolMapValue * const map_value = (SymbolMapValue*)value; - const LargestIntegralType children = cast_ptr_to_largest_integral_type(cleanup_value_data); - assert_non_null(value); - list_free(&map_value->symbol_values_list_head, - children ? free_symbol_map_value : free_value, - (void *) ((uintptr_t)children - 1)); - free(map_value); -} - - -/* - * Determine whether a symbol name referenced by a symbol_map_value matches the - * specified function name. - */ -static int symbol_names_match(const void *map_value, const void *symbol) { - return !strcmp(((SymbolMapValue*)map_value)->symbol_name, - (const char*)symbol); -} - -/* - * Adds a value to the queue of values associated with the given hierarchy of - * symbols. It's assumed value is allocated from the heap. - */ -static void add_symbol_value(ListNode * const symbol_map_head, - const char * const symbol_names[], - const size_t number_of_symbol_names, - const void* value, const int refcount) { - const char* symbol_name; - ListNode *target_node; - SymbolMapValue *target_map_value; - assert_non_null(symbol_map_head); - assert_non_null(symbol_names); - assert_true(number_of_symbol_names); - symbol_name = symbol_names[0]; - - if (!list_find(symbol_map_head, symbol_name, symbol_names_match, - &target_node)) { - SymbolMapValue * const new_symbol_map_value = - (SymbolMapValue*)malloc(sizeof(*new_symbol_map_value)); - new_symbol_map_value->symbol_name = symbol_name; - list_initialize(&new_symbol_map_value->symbol_values_list_head); - target_node = list_add_value(symbol_map_head, new_symbol_map_value, - 1); - } - - target_map_value = (SymbolMapValue*)target_node->value; - if (number_of_symbol_names == 1) { - list_add_value(&target_map_value->symbol_values_list_head, - value, refcount); - } else { - add_symbol_value(&target_map_value->symbol_values_list_head, - &symbol_names[1], number_of_symbol_names - 1, value, - refcount); - } -} - - -/* - * Gets the next value associated with the given hierarchy of symbols. - * The value is returned as an output parameter with the function returning the - * node's old refcount value if a value is found, 0 otherwise. This means that - * a return value of 1 indicates the node was just removed from the list. - */ -static int get_symbol_value( - ListNode * const head, const char * const symbol_names[], - const size_t number_of_symbol_names, void **output) { - const char* symbol_name = NULL; - ListNode *target_node = NULL; - assert_non_null(head); - assert_non_null(symbol_names); - assert_true(number_of_symbol_names); - assert_non_null(output); - symbol_name = symbol_names[0]; - - if (list_find(head, symbol_name, symbol_names_match, &target_node)) { - SymbolMapValue *map_value = NULL; - ListNode *child_list = NULL; - int return_value = 0; - assert_non_null(target_node); - assert_non_null(target_node->value); - - map_value = (SymbolMapValue*)target_node->value; - child_list = &map_value->symbol_values_list_head; - - if (number_of_symbol_names == 1) { - ListNode *value_node = NULL; - return_value = list_first(child_list, &value_node); - assert_true(return_value); - /* Add a check to silence clang analyzer */ - if (return_value == 0) { - goto out; - } - *output = (void*) value_node->value; - return_value = value_node->refcount; - if (value_node->refcount - 1 == 0) { - list_remove_free(value_node, NULL, NULL); - } else if (value_node->refcount > WILL_RETURN_ONCE) { - --value_node->refcount; - } - } else { - return_value = get_symbol_value( - child_list, &symbol_names[1], number_of_symbol_names - 1, - output); - } - if (list_empty(child_list)) { - list_remove_free(target_node, free_symbol_map_value, (void*)0); - } - return return_value; - } -out: - cm_print_error("No entries for symbol %s.\n", symbol_name); - return 0; -} - -/** - * Taverse a list of nodes and remove first symbol value in list that has a - * refcount < -1 (i.e. should always be returned and has been returned at - * least once). - */ - -static void remove_always_return_values_from_list(ListNode * const map_head) -{ - ListNode * current = NULL; - ListNode * next = NULL; - assert_non_null(map_head); - - for (current = map_head->next, next = current->next; - current != map_head; - current = next, next = current->next) { - if (current->refcount < -1) { - list_remove_free(current, free_value, NULL); - } - } -} - -/* - * Traverse down a tree of symbol values and remove the first symbol value - * in each branch that has a refcount < -1 (i.e should always be returned - * and has been returned at least once). - */ -static void remove_always_return_values(ListNode * const map_head, - const size_t number_of_symbol_names) { - ListNode *current; - assert_non_null(map_head); - assert_true(number_of_symbol_names); - current = map_head->next; - while (current != map_head) { - SymbolMapValue * const value = (SymbolMapValue*)current->value; - ListNode * const next = current->next; - ListNode *child_list; - assert_non_null(value); - child_list = &value->symbol_values_list_head; - - if (!list_empty(child_list)) { - if (number_of_symbol_names == 1) { - ListNode * const child_node = child_list->next; - /* If this item has been returned more than once, free it. */ - if (child_node->refcount < -1) { - list_remove_free(child_node, free_value, NULL); - } - } else { - remove_always_return_values(child_list, - number_of_symbol_names - 1); - } - } - - if (list_empty(child_list)) { - list_remove_free(current, free_value, NULL); - } - current = next; - } -} - -static size_t check_for_leftover_values_list(const ListNode * head, - const char * const error_message) -{ - ListNode *child_node; - size_t leftover_count = 0; - if (!list_empty(head)) - { - for (child_node = head->next; child_node != head; - child_node = child_node->next, ++leftover_count) { - const FuncOrderingValue *const o = - (const FuncOrderingValue*) child_node->value; - cm_print_error(error_message, o->function); - cm_print_error(SOURCE_LOCATION_FORMAT - ": note: remaining item was declared here\n", - o->location.file, o->location.line); - } - } - return leftover_count; -} - -/* - * Checks if there are any leftover values set up by the test that were never - * retrieved through execution, and fail the test if that is the case. - */ -static size_t check_for_leftover_values( - const ListNode * const map_head, const char * const error_message, - const size_t number_of_symbol_names) { - const ListNode *current; - size_t symbols_with_leftover_values = 0; - assert_non_null(map_head); - assert_true(number_of_symbol_names); - - for (current = map_head->next; current != map_head; - current = current->next) { - const SymbolMapValue * const value = - (SymbolMapValue*)current->value; - const ListNode *child_list; - assert_non_null(value); - child_list = &value->symbol_values_list_head; - - if (!list_empty(child_list)) { - if (number_of_symbol_names == 1) { - const ListNode *child_node; - cm_print_error(error_message, value->symbol_name); - - for (child_node = child_list->next; child_node != child_list; - child_node = child_node->next) { - const SourceLocation * const location = - (const SourceLocation*)child_node->value; - cm_print_error(SOURCE_LOCATION_FORMAT - ": note: remaining item was declared here\n", - location->file, location->line); - } - } else { - cm_print_error("%s: ", value->symbol_name); - check_for_leftover_values(child_list, error_message, - number_of_symbol_names - 1); - } - symbols_with_leftover_values ++; - } - } - return symbols_with_leftover_values; -} - - -/* Get the next return value for the specified mock function. */ -LargestIntegralType _mock(const char * const function, const char* const file, - const int line) { - void *result; - const int rc = get_symbol_value(&global_function_result_map_head, - &function, 1, &result); - if (rc) { - SymbolValue * const symbol = (SymbolValue*)result; - const LargestIntegralType value = symbol->value; - global_last_mock_value_location = symbol->location; - if (rc == 1) { - free(symbol); - } - return value; - } else { - cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value " - "to mock function %s\n", file, line, function); - if (source_location_is_set(&global_last_mock_value_location)) { - cm_print_error(SOURCE_LOCATION_FORMAT - ": note: Previously returned mock value was declared here\n", - global_last_mock_value_location.file, - global_last_mock_value_location.line); - } else { - cm_print_error("There were no previously returned mock values for " - "this test.\n"); - } - exit_test(1); - } - return 0; -} - -/* Ensure that function is being called in proper order */ -void _function_called(const char *const function, - const char *const file, - const int line) -{ - ListNode *first_value_node = NULL; - ListNode *value_node = NULL; - int rc; - - rc = list_first(&global_call_ordering_head, &value_node); - first_value_node = value_node; - if (rc) { - FuncOrderingValue *expected_call; - int cmp; - - expected_call = (FuncOrderingValue *)value_node->value; - - cmp = strcmp(expected_call->function, function); - if (value_node->refcount < -1) { - /* - * Search through value nodes until either function is found or - * encounter a non-zero refcount greater than -2 - */ - if (cmp != 0) { - value_node = value_node->next; - expected_call = (FuncOrderingValue *)value_node->value; - - cmp = strcmp(expected_call->function, function); - while (value_node->refcount < -1 && - cmp != 0 && - value_node != first_value_node->prev) { - value_node = value_node->next; - if (value_node == NULL) { - break; - } - expected_call = (FuncOrderingValue *)value_node->value; - if (expected_call == NULL) { - continue; - } - cmp = strcmp(expected_call->function, function); - } - - if (expected_call == NULL || value_node == first_value_node->prev) { - cm_print_error(SOURCE_LOCATION_FORMAT - ": error: No expected mock calls matching " - "called() invocation in %s", - file, line, - function); - exit_test(1); - } - } - } - - if (cmp == 0) { - if (value_node->refcount > -2 && --value_node->refcount == 0) { - list_remove_free(value_node, free_value, NULL); - } - } else { - cm_print_error(SOURCE_LOCATION_FORMAT - ": error: Expected call to %s but received called() " - "in %s\n", - file, line, - expected_call->function, - function); - exit_test(1); - } - } else { - cm_print_error(SOURCE_LOCATION_FORMAT - ": error: No mock calls expected but called() was " - "invoked in %s\n", - file, line, - function); - exit_test(1); - } -} - -/* Add a return value for the specified mock function name. */ -void _will_return(const char * const function_name, const char * const file, - const int line, const LargestIntegralType value, - const int count) { - SymbolValue * const return_value = - (SymbolValue*)malloc(sizeof(*return_value)); - assert_true(count != 0); - return_value->value = value; - set_source_location(&return_value->location, file, line); - add_symbol_value(&global_function_result_map_head, &function_name, 1, - return_value, count); -} - - -/* - * Add a custom parameter checking function. If the event parameter is NULL - * the event structure is allocated internally by this function. If event - * parameter is provided it must be allocated on the heap and doesn't need to - * be deallocated by the caller. - */ -void _expect_check( - const char* const function, const char* const parameter, - const char* const file, const int line, - const CheckParameterValue check_function, - const LargestIntegralType check_data, - CheckParameterEvent * const event, const int count) { - CheckParameterEvent * const check = - event ? event : (CheckParameterEvent*)malloc(sizeof(*check)); - const char* symbols[] = {function, parameter}; - check->parameter_name = parameter; - check->check_value = check_function; - check->check_value_data = check_data; - set_source_location(&check->location, file, line); - add_symbol_value(&global_function_parameter_map_head, symbols, 2, check, - count); -} - -/* - * Add an call expectations that a particular function is called correctly. - * This is used for code under test that makes calls to several functions - * in depended upon components (mocks). - */ - -void _expect_function_call( - const char * const function_name, - const char * const file, - const int line, - const int count) -{ - FuncOrderingValue *ordering; - - assert_non_null(function_name); - assert_non_null(file); - assert_true(count != 0); - - ordering = (FuncOrderingValue *)malloc(sizeof(*ordering)); - - set_source_location(&ordering->location, file, line); - ordering->function = function_name; - - list_add_value(&global_call_ordering_head, ordering, count); -} - -/* Returns 1 if the specified values are equal. If the values are not equal - * an error is displayed and 0 is returned. */ -static int values_equal_display_error(const LargestIntegralType left, - const LargestIntegralType right) { - const int equal = left == right; - if (!equal) { - cm_print_error(LargestIntegralTypePrintfFormat " != " - LargestIntegralTypePrintfFormat "\n", left, right); - } - return equal; -} - -/* - * Returns 1 if the specified values are not equal. If the values are equal - * an error is displayed and 0 is returned. */ -static int values_not_equal_display_error(const LargestIntegralType left, - const LargestIntegralType right) { - const int not_equal = left != right; - if (!not_equal) { - cm_print_error(LargestIntegralTypePrintfFormat " == " - LargestIntegralTypePrintfFormat "\n", left, right); - } - return not_equal; -} - - -/* - * Determine whether value is contained within check_integer_set. - * If invert is 0 and the value is in the set 1 is returned, otherwise 0 is - * returned and an error is displayed. If invert is 1 and the value is not - * in the set 1 is returned, otherwise 0 is returned and an error is - * displayed. - */ -static int value_in_set_display_error( - const LargestIntegralType value, - const CheckIntegerSet * const check_integer_set, const int invert) { - int succeeded = invert; - assert_non_null(check_integer_set); - { - const LargestIntegralType * const set = check_integer_set->set; - const size_t size_of_set = check_integer_set->size_of_set; - size_t i; - for (i = 0; i < size_of_set; i++) { - if (set[i] == value) { - /* If invert = 0 and item is found, succeeded = 1. */ - /* If invert = 1 and item is found, succeeded = 0. */ - succeeded = !succeeded; - break; - } - } - if (succeeded) { - return 1; - } - cm_print_error(LargestIntegralTypePrintfFormatDecimal - " is %sin the set (", - value, invert ? "" : "not "); - for (i = 0; i < size_of_set; i++) { - cm_print_error(LargestIntegralTypePrintfFormat ", ", set[i]); - } - cm_print_error(")\n"); - } - return 0; -} - - -/* - * Determine whether a value is within the specified range. If the value is - * within the specified range 1 is returned. If the value isn't within the - * specified range an error is displayed and 0 is returned. - */ -static int integer_in_range_display_error( - const LargestIntegralType value, const LargestIntegralType range_min, - const LargestIntegralType range_max) { - if (value >= range_min && value <= range_max) { - return 1; - } - cm_print_error(LargestIntegralTypePrintfFormatDecimal - " is not within the range " - LargestIntegralTypePrintfFormatDecimal "-" - LargestIntegralTypePrintfFormatDecimal "\n", - value, range_min, range_max); - return 0; -} - - -/* - * Determine whether a value is within the specified range. If the value - * is not within the range 1 is returned. If the value is within the - * specified range an error is displayed and zero is returned. - */ -static int integer_not_in_range_display_error( - const LargestIntegralType value, const LargestIntegralType range_min, - const LargestIntegralType range_max) { - if (value < range_min || value > range_max) { - return 1; - } - cm_print_error(LargestIntegralTypePrintfFormatDecimal - " is within the range " - LargestIntegralTypePrintfFormatDecimal "-" - LargestIntegralTypePrintfFormatDecimal "\n", - value, range_min, range_max); - return 0; -} - - -/* - * Determine whether the specified strings are equal. If the strings are equal - * 1 is returned. If they're not equal an error is displayed and 0 is - * returned. - */ -static int string_equal_display_error( - const char * const left, const char * const right) { - if (strcmp(left, right) == 0) { - return 1; - } - cm_print_error("\"%s\" != \"%s\"\n", left, right); - return 0; -} - - -/* - * Determine whether the specified strings are equal. If the strings are not - * equal 1 is returned. If they're not equal an error is displayed and 0 is - * returned - */ -static int string_not_equal_display_error( - const char * const left, const char * const right) { - if (strcmp(left, right) != 0) { - return 1; - } - cm_print_error("\"%s\" == \"%s\"\n", left, right); - return 0; -} - - -/* - * Determine whether the specified areas of memory are equal. If they're equal - * 1 is returned otherwise an error is displayed and 0 is returned. - */ -static int memory_equal_display_error(const char* const a, const char* const b, - const size_t size) { - size_t differences = 0; - size_t i; - for (i = 0; i < size; i++) { - const char l = a[i]; - const char r = b[i]; - if (l != r) { - if (differences < 16) { - cm_print_error("difference at offset %" PRIdS " 0x%02x 0x%02x\n", - i, l, r); - } - differences ++; - } - } - if (differences > 0) { - if (differences >= 16) { - cm_print_error("...\n"); - } - cm_print_error("%"PRIdS " bytes of %p and %p differ\n", - differences, (void *)a, (void *)b); - return 0; - } - return 1; -} - - -/* - * Determine whether the specified areas of memory are not equal. If they're - * not equal 1 is returned otherwise an error is displayed and 0 is - * returned. - */ -static int memory_not_equal_display_error( - const char* const a, const char* const b, const size_t size) { - size_t same = 0; - size_t i; - for (i = 0; i < size; i++) { - const char l = a[i]; - const char r = b[i]; - if (l == r) { - same ++; - } - } - if (same == size) { - cm_print_error("%"PRIdS "bytes of %p and %p the same\n", - same, (void *)a, (void *)b); - return 0; - } - return 1; -} - - -/* CheckParameterValue callback to check whether a value is within a set. */ -static int check_in_set(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - return value_in_set_display_error(value, - cast_largest_integral_type_to_pointer(CheckIntegerSet*, - check_value_data), 0); -} - - -/* CheckParameterValue callback to check whether a value isn't within a set. */ -static int check_not_in_set(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - return value_in_set_display_error(value, - cast_largest_integral_type_to_pointer(CheckIntegerSet*, - check_value_data), 1); -} - - -/* Create the callback data for check_in_set() or check_not_in_set() and - * register a check event. */ -static void expect_set( - const char* const function, const char* const parameter, - const char* const file, const int line, - const LargestIntegralType values[], const size_t number_of_values, - const CheckParameterValue check_function, const int count) { - CheckIntegerSet * const check_integer_set = - (CheckIntegerSet*)malloc(sizeof(*check_integer_set) + - (sizeof(values[0]) * number_of_values)); - LargestIntegralType * const set = (LargestIntegralType*)( - check_integer_set + 1); - declare_initialize_value_pointer_pointer(check_data, check_integer_set); - assert_non_null(values); - assert_true(number_of_values); - memcpy(set, values, number_of_values * sizeof(values[0])); - check_integer_set->set = set; - check_integer_set->size_of_set = number_of_values; - _expect_check( - function, parameter, file, line, check_function, - check_data.value, &check_integer_set->event, count); -} - - -/* Add an event to check whether a value is in a set. */ -void _expect_in_set( - const char* const function, const char* const parameter, - const char* const file, const int line, - const LargestIntegralType values[], const size_t number_of_values, - const int count) { - expect_set(function, parameter, file, line, values, number_of_values, - check_in_set, count); -} - - -/* Add an event to check whether a value isn't in a set. */ -void _expect_not_in_set( - const char* const function, const char* const parameter, - const char* const file, const int line, - const LargestIntegralType values[], const size_t number_of_values, - const int count) { - expect_set(function, parameter, file, line, values, number_of_values, - check_not_in_set, count); -} - - -/* CheckParameterValue callback to check whether a value is within a range. */ -static int check_in_range(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - CheckIntegerRange * const check_integer_range = - cast_largest_integral_type_to_pointer(CheckIntegerRange*, - check_value_data); - assert_non_null(check_integer_range); - return integer_in_range_display_error(value, check_integer_range->minimum, - check_integer_range->maximum); -} - - -/* CheckParameterValue callback to check whether a value is not within a range. */ -static int check_not_in_range(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - CheckIntegerRange * const check_integer_range = - cast_largest_integral_type_to_pointer(CheckIntegerRange*, - check_value_data); - assert_non_null(check_integer_range); - return integer_not_in_range_display_error( - value, check_integer_range->minimum, check_integer_range->maximum); -} - - -/* Create the callback data for check_in_range() or check_not_in_range() and - * register a check event. */ -static void expect_range( - const char* const function, const char* const parameter, - const char* const file, const int line, - const LargestIntegralType minimum, const LargestIntegralType maximum, - const CheckParameterValue check_function, const int count) { - CheckIntegerRange * const check_integer_range = - (CheckIntegerRange*)malloc(sizeof(*check_integer_range)); - declare_initialize_value_pointer_pointer(check_data, check_integer_range); - check_integer_range->minimum = minimum; - check_integer_range->maximum = maximum; - _expect_check(function, parameter, file, line, check_function, - check_data.value, &check_integer_range->event, count); -} - - -/* Add an event to determine whether a parameter is within a range. */ -void _expect_in_range( - const char* const function, const char* const parameter, - const char* const file, const int line, - const LargestIntegralType minimum, const LargestIntegralType maximum, - const int count) { - expect_range(function, parameter, file, line, minimum, maximum, - check_in_range, count); -} - - -/* Add an event to determine whether a parameter is not within a range. */ -void _expect_not_in_range( - const char* const function, const char* const parameter, - const char* const file, const int line, - const LargestIntegralType minimum, const LargestIntegralType maximum, - const int count) { - expect_range(function, parameter, file, line, minimum, maximum, - check_not_in_range, count); -} - - -/* CheckParameterValue callback to check whether a value is equal to an - * expected value. */ -static int check_value(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - return values_equal_display_error(value, check_value_data); -} - - -/* Add an event to check a parameter equals an expected value. */ -void _expect_value( - const char* const function, const char* const parameter, - const char* const file, const int line, - const LargestIntegralType value, const int count) { - _expect_check(function, parameter, file, line, check_value, value, NULL, - count); -} - - -/* CheckParameterValue callback to check whether a value is not equal to an - * expected value. */ -static int check_not_value(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - return values_not_equal_display_error(value, check_value_data); -} - - -/* Add an event to check a parameter is not equal to an expected value. */ -void _expect_not_value( - const char* const function, const char* const parameter, - const char* const file, const int line, - const LargestIntegralType value, const int count) { - _expect_check(function, parameter, file, line, check_not_value, value, - NULL, count); -} - - -/* CheckParameterValue callback to check whether a parameter equals a string. */ -static int check_string(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - return string_equal_display_error( - cast_largest_integral_type_to_pointer(char*, value), - cast_largest_integral_type_to_pointer(char*, check_value_data)); -} - - -/* Add an event to check whether a parameter is equal to a string. */ -void _expect_string( - const char* const function, const char* const parameter, - const char* const file, const int line, const char* string, - const int count) { - declare_initialize_value_pointer_pointer(string_pointer, - discard_const(string)); - _expect_check(function, parameter, file, line, check_string, - string_pointer.value, NULL, count); -} - - -/* CheckParameterValue callback to check whether a parameter is not equals to - * a string. */ -static int check_not_string(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - return string_not_equal_display_error( - cast_largest_integral_type_to_pointer(char*, value), - cast_largest_integral_type_to_pointer(char*, check_value_data)); -} - - -/* Add an event to check whether a parameter is not equal to a string. */ -void _expect_not_string( - const char* const function, const char* const parameter, - const char* const file, const int line, const char* string, - const int count) { - declare_initialize_value_pointer_pointer(string_pointer, - discard_const(string)); - _expect_check(function, parameter, file, line, check_not_string, - string_pointer.value, NULL, count); -} - -/* CheckParameterValue callback to check whether a parameter equals an area of - * memory. */ -static int check_memory(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - CheckMemoryData * const check = cast_largest_integral_type_to_pointer( - CheckMemoryData*, check_value_data); - assert_non_null(check); - return memory_equal_display_error( - cast_largest_integral_type_to_pointer(const char*, value), - (const char*)check->memory, check->size); -} - - -/* Create the callback data for check_memory() or check_not_memory() and - * register a check event. */ -static void expect_memory_setup( - const char* const function, const char* const parameter, - const char* const file, const int line, - const void * const memory, const size_t size, - const CheckParameterValue check_function, const int count) { - CheckMemoryData * const check_data = - (CheckMemoryData*)malloc(sizeof(*check_data) + size); - void * const mem = (void*)(check_data + 1); - declare_initialize_value_pointer_pointer(check_data_pointer, check_data); - assert_non_null(memory); - assert_true(size); - memcpy(mem, memory, size); - check_data->memory = mem; - check_data->size = size; - _expect_check(function, parameter, file, line, check_function, - check_data_pointer.value, &check_data->event, count); -} - - -/* Add an event to check whether a parameter matches an area of memory. */ -void _expect_memory( - const char* const function, const char* const parameter, - const char* const file, const int line, const void* const memory, - const size_t size, const int count) { - expect_memory_setup(function, parameter, file, line, memory, size, - check_memory, count); -} - - -/* CheckParameterValue callback to check whether a parameter is not equal to - * an area of memory. */ -static int check_not_memory(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - CheckMemoryData * const check = cast_largest_integral_type_to_pointer( - CheckMemoryData*, check_value_data); - assert_non_null(check); - return memory_not_equal_display_error( - cast_largest_integral_type_to_pointer(const char*, value), - (const char*)check->memory, - check->size); -} - - -/* Add an event to check whether a parameter doesn't match an area of memory. */ -void _expect_not_memory( - const char* const function, const char* const parameter, - const char* const file, const int line, const void* const memory, - const size_t size, const int count) { - expect_memory_setup(function, parameter, file, line, memory, size, - check_not_memory, count); -} - - -/* CheckParameterValue callback that always returns 1. */ -static int check_any(const LargestIntegralType value, - const LargestIntegralType check_value_data) { - (void)value; - (void)check_value_data; - return 1; -} - - -/* Add an event to allow any value for a parameter. */ -void _expect_any( - const char* const function, const char* const parameter, - const char* const file, const int line, const int count) { - _expect_check(function, parameter, file, line, check_any, 0, NULL, - count); -} - - -void _check_expected( - const char * const function_name, const char * const parameter_name, - const char* file, const int line, const LargestIntegralType value) { - void *result = NULL; - const char* symbols[] = {function_name, parameter_name}; - const int rc = get_symbol_value(&global_function_parameter_map_head, - symbols, 2, &result); - if (rc) { - CheckParameterEvent * const check = (CheckParameterEvent*)result; - int check_succeeded; - global_last_parameter_location = check->location; - check_succeeded = check->check_value(value, check->check_value_data); - if (rc == 1) { - free(check); - } - if (!check_succeeded) { - cm_print_error(SOURCE_LOCATION_FORMAT - ": error: Check of parameter %s, function %s failed\n" - SOURCE_LOCATION_FORMAT - ": note: Expected parameter declared here\n", - file, line, - parameter_name, function_name, - global_last_parameter_location.file, - global_last_parameter_location.line); - _fail(file, line); - } - } else { - cm_print_error(SOURCE_LOCATION_FORMAT ": error: Could not get value " - "to check parameter %s of function %s\n", file, line, - parameter_name, function_name); - if (source_location_is_set(&global_last_parameter_location)) { - cm_print_error(SOURCE_LOCATION_FORMAT - ": note: Previously declared parameter value was declared here\n", - global_last_parameter_location.file, - global_last_parameter_location.line); - } else { - cm_print_error("There were no previously declared parameter values " - "for this test.\n"); - } - exit_test(1); - } -} - - -/* Replacement for assert. */ -void mock_assert(const int result, const char* const expression, - const char* const file, const int line) { - if (!result) { - if (global_expecting_assert) { - global_last_failed_assert = expression; - longjmp(global_expect_assert_env, result); - } else { - cm_print_error("ASSERT: %s\n", expression); - _fail(file, line); - } - } -} - - -void _assert_true(const LargestIntegralType result, - const char * const expression, - const char * const file, const int line) { - if (!result) { - cm_print_error("%s\n", expression); - _fail(file, line); - } -} - -void _assert_return_code(const LargestIntegralType result, - size_t rlen, - const LargestIntegralType error, - const char * const expression, - const char * const file, - const int line) -{ - LargestIntegralType valmax; - - - switch (rlen) { - case 1: - valmax = 255; - break; - case 2: - valmax = 32767; - break; - case 4: - valmax = 2147483647; - break; - case 8: - default: - if (rlen > sizeof(valmax)) { - valmax = 2147483647; - } else { - valmax = 9223372036854775807L; - } - break; - } - - if (result > valmax - 1) { - if (error > 0) { - cm_print_error("%s < 0, errno(" - LargestIntegralTypePrintfFormatDecimal "): %s\n", - expression, error, strerror((int)error)); - } else { - cm_print_error("%s < 0\n", expression); - } - _fail(file, line); - } -} - -void _assert_int_equal( - const LargestIntegralType a, const LargestIntegralType b, - const char * const file, const int line) { - if (!values_equal_display_error(a, b)) { - _fail(file, line); - } -} - - -void _assert_int_not_equal( - const LargestIntegralType a, const LargestIntegralType b, - const char * const file, const int line) { - if (!values_not_equal_display_error(a, b)) { - _fail(file, line); - } -} - - -void _assert_string_equal(const char * const a, const char * const b, - const char * const file, const int line) { - if (!string_equal_display_error(a, b)) { - _fail(file, line); - } -} - - -void _assert_string_not_equal(const char * const a, const char * const b, - const char *file, const int line) { - if (!string_not_equal_display_error(a, b)) { - _fail(file, line); - } -} - - -void _assert_memory_equal(const void * const a, const void * const b, - const size_t size, const char* const file, - const int line) { - if (!memory_equal_display_error((const char*)a, (const char*)b, size)) { - _fail(file, line); - } -} - - -void _assert_memory_not_equal(const void * const a, const void * const b, - const size_t size, const char* const file, - const int line) { - if (!memory_not_equal_display_error((const char*)a, (const char*)b, - size)) { - _fail(file, line); - } -} - - -void _assert_in_range( - const LargestIntegralType value, const LargestIntegralType minimum, - const LargestIntegralType maximum, const char* const file, - const int line) { - if (!integer_in_range_display_error(value, minimum, maximum)) { - _fail(file, line); - } -} - -void _assert_not_in_range( - const LargestIntegralType value, const LargestIntegralType minimum, - const LargestIntegralType maximum, const char* const file, - const int line) { - if (!integer_not_in_range_display_error(value, minimum, maximum)) { - _fail(file, line); - } -} - -void _assert_in_set(const LargestIntegralType value, - const LargestIntegralType values[], - const size_t number_of_values, const char* const file, - const int line) { - CheckIntegerSet check_integer_set; - check_integer_set.set = values; - check_integer_set.size_of_set = number_of_values; - if (!value_in_set_display_error(value, &check_integer_set, 0)) { - _fail(file, line); - } -} - -void _assert_not_in_set(const LargestIntegralType value, - const LargestIntegralType values[], - const size_t number_of_values, const char* const file, - const int line) { - CheckIntegerSet check_integer_set; - check_integer_set.set = values; - check_integer_set.size_of_set = number_of_values; - if (!value_in_set_display_error(value, &check_integer_set, 1)) { - _fail(file, line); - } -} - - -/* Get the list of allocated blocks. */ -static ListNode* get_allocated_blocks_list(void) { - /* If it initialized, initialize the list of allocated blocks. */ - if (!global_allocated_blocks.value) { - list_initialize(&global_allocated_blocks); - global_allocated_blocks.value = (void*)1; - } - return &global_allocated_blocks; -} - -static void *libc_malloc(size_t size) -{ -#undef malloc - return malloc(size); -#define malloc test_malloc -} - -static void libc_free(void *ptr) -{ -#undef free - free(ptr); -#define free test_free -} - -static void *libc_realloc(void *ptr, size_t size) -{ -#undef realloc - return realloc(ptr, size); -#define realloc test_realloc -} - -static void vcm_print_error(const char* const format, - va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0); - -/* It's important to use the libc malloc and free here otherwise - * the automatic free of leaked blocks can reap the error messages - */ -static void vcm_print_error(const char* const format, va_list args) -{ - char buffer[1024]; - size_t msg_len = 0; - va_list ap; - int len; - va_copy(ap, args); - - len = vsnprintf(buffer, sizeof(buffer), format, args); - if (len < 0) { - /* TODO */ - goto end; - } - - if (cm_error_message == NULL) { - /* CREATE MESSAGE */ - - cm_error_message = libc_malloc(len + 1); - if (cm_error_message == NULL) { - /* TODO */ - goto end; - } - } else { - /* APPEND MESSAGE */ - char *tmp; - - msg_len = strlen(cm_error_message); - tmp = libc_realloc(cm_error_message, msg_len + len + 1); - if (tmp == NULL) { - goto end; - } - cm_error_message = tmp; - } - - if (((size_t)len) < sizeof(buffer)) { - /* Use len + 1 to also copy '\0' */ - memcpy(cm_error_message + msg_len, buffer, len + 1); - } else { - vsnprintf(cm_error_message + msg_len, len, format, ap); - } -end: - va_end(ap); - -} - -static void vcm_free_error(char *err_msg) -{ - libc_free(err_msg); -} - -/* Use the real malloc in this function. */ -#undef malloc -void* _test_malloc(const size_t size, const char* file, const int line) { - char *ptr = NULL; - MallocBlockInfo block_info; - ListNode * const block_list = get_allocated_blocks_list(); - size_t allocate_size; - char *block = NULL; - - allocate_size = size + (MALLOC_GUARD_SIZE * 2) + - sizeof(struct MallocBlockInfoData) + MALLOC_ALIGNMENT; - assert_true(allocate_size > size); - - block = (char *)malloc(allocate_size); - assert_non_null(block); - - /* Calculate the returned address. */ - ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE + - sizeof(struct MallocBlockInfoData) + - MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1)); - - /* Initialize the guard blocks. */ - memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE); - memset(ptr + size, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE); - memset(ptr, MALLOC_ALLOC_PATTERN, size); - - block_info.ptr = ptr - (MALLOC_GUARD_SIZE + - sizeof(struct MallocBlockInfoData)); - set_source_location(&block_info.data->location, file, line); - block_info.data->allocated_size = allocate_size; - block_info.data->size = size; - block_info.data->block = block; - block_info.data->node.value = block_info.ptr; - list_add(block_list, &block_info.data->node); - return ptr; -} -#define malloc test_malloc - - -void* _test_calloc(const size_t number_of_elements, const size_t size, - const char* file, const int line) { - void* const ptr = _test_malloc(number_of_elements * size, file, line); - if (ptr) { - memset(ptr, 0, number_of_elements * size); - } - return ptr; -} - - -/* Use the real free in this function. */ -#undef free -void _test_free(void* const ptr, const char* file, const int line) { - unsigned int i; - char *block = discard_const_p(char, ptr); - MallocBlockInfo block_info; - - if (ptr == NULL) { - return; - } - - _assert_true(cast_ptr_to_largest_integral_type(ptr), "ptr", file, line); - block_info.ptr = block - (MALLOC_GUARD_SIZE + - sizeof(struct MallocBlockInfoData)); - /* Check the guard blocks. */ - { - char *guards[2] = {block - MALLOC_GUARD_SIZE, - block + block_info.data->size}; - for (i = 0; i < ARRAY_SIZE(guards); i++) { - unsigned int j; - char * const guard = guards[i]; - for (j = 0; j < MALLOC_GUARD_SIZE; j++) { - const char diff = guard[j] - MALLOC_GUARD_PATTERN; - if (diff) { - cm_print_error(SOURCE_LOCATION_FORMAT - ": error: Guard block of %p size=%lu is corrupt\n" - SOURCE_LOCATION_FORMAT ": note: allocated here at %p\n", - file, - line, - ptr, - (unsigned long)block_info.data->size, - block_info.data->location.file, - block_info.data->location.line, - (void *)&guard[j]); - _fail(file, line); - } - } - } - } - list_remove(&block_info.data->node, NULL, NULL); - - block = discard_const_p(char, block_info.data->block); - memset(block, MALLOC_FREE_PATTERN, block_info.data->allocated_size); - free(block); -} -#define free test_free - -#undef realloc -void *_test_realloc(void *ptr, - const size_t size, - const char *file, - const int line) -{ - MallocBlockInfo block_info; - char *block = ptr; - size_t block_size = size; - void *new_block; - - if (ptr == NULL) { - return _test_malloc(size, file, line); - } - - if (size == 0) { - _test_free(ptr, file, line); - return NULL; - } - - block_info.ptr = block - (MALLOC_GUARD_SIZE + - sizeof(struct MallocBlockInfoData)); - - new_block = _test_malloc(size, file, line); - if (new_block == NULL) { - return NULL; - } - - if (block_info.data->size < size) { - block_size = block_info.data->size; - } - - memcpy(new_block, ptr, block_size); - - /* Free previous memory */ - _test_free(ptr, file, line); - - return new_block; -} -#define realloc test_realloc - -/* Crudely checkpoint the current heap state. */ -static const ListNode* check_point_allocated_blocks(void) { - return get_allocated_blocks_list()->prev; -} - - -/* Display the blocks allocated after the specified check point. This - * function returns the number of blocks displayed. */ -static size_t display_allocated_blocks(const ListNode * const check_point) { - const ListNode * const head = get_allocated_blocks_list(); - const ListNode *node; - size_t allocated_blocks = 0; - assert_non_null(check_point); - assert_non_null(check_point->next); - - for (node = check_point->next; node != head; node = node->next) { - const MallocBlockInfo block_info = { - .ptr = discard_const(node->value), - }; - assert_non_null(block_info.ptr); - - if (allocated_blocks == 0) { - cm_print_error("Blocks allocated...\n"); - } - cm_print_error(SOURCE_LOCATION_FORMAT ": note: block %p allocated here\n", - block_info.data->location.file, - block_info.data->location.line, - block_info.data->block); - allocated_blocks++; - } - return allocated_blocks; -} - - -/* Free all blocks allocated after the specified check point. */ -static void free_allocated_blocks(const ListNode * const check_point) { - const ListNode * const head = get_allocated_blocks_list(); - const ListNode *node; - assert_non_null(check_point); - - node = check_point->next; - assert_non_null(node); - - while (node != head) { - const MallocBlockInfo block_info = { - .ptr = discard_const(node->value), - }; - node = node->next; - free(discard_const_p(char, block_info.data) + - sizeof(struct MallocBlockInfoData) + - MALLOC_GUARD_SIZE); - } -} - - -/* Fail if any any blocks are allocated after the specified check point. */ -static void fail_if_blocks_allocated(const ListNode * const check_point, - const char * const test_name) { - const size_t allocated_blocks = display_allocated_blocks(check_point); - if (allocated_blocks > 0) { - free_allocated_blocks(check_point); - cm_print_error("ERROR: %s leaked %zu block(s)\n", test_name, - allocated_blocks); - exit_test(1); - } -} - - -void _fail(const char * const file, const int line) { - enum cm_message_output output = cm_get_output(); - - switch(output) { - case CM_OUTPUT_STDOUT: - cm_print_error("[ LINE ] --- " SOURCE_LOCATION_FORMAT ": error: Failure!", file, line); - break; - default: - cm_print_error(SOURCE_LOCATION_FORMAT ": error: Failure!", file, line); - break; - } - exit_test(1); -} - - -#ifndef _WIN32 -static void exception_handler(int sig) { - const char *sig_strerror = ""; - -#ifdef HAVE_STRSIGNAL - sig_strerror = strsignal(sig); -#endif - - cm_print_error("Test failed with exception: %s(%d)", - sig_strerror, sig); - exit_test(1); -} - -#else /* _WIN32 */ - -static LONG WINAPI exception_filter(EXCEPTION_POINTERS *exception_pointers) { - EXCEPTION_RECORD * const exception_record = - exception_pointers->ExceptionRecord; - const DWORD code = exception_record->ExceptionCode; - unsigned int i; - for (i = 0; i < ARRAY_SIZE(exception_codes); i++) { - const ExceptionCodeInfo * const code_info = &exception_codes[i]; - if (code == code_info->code) { - static int shown_debug_message = 0; - fflush(stdout); - cm_print_error("%s occurred at %p.\n", code_info->description, - exception_record->ExceptionAddress); - if (!shown_debug_message) { - cm_print_error( - "\n" - "To debug in Visual Studio...\n" - "1. Select menu item File->Open Project\n" - "2. Change 'Files of type' to 'Executable Files'\n" - "3. Open this executable.\n" - "4. Select menu item Debug->Start\n" - "\n" - "Alternatively, set the environment variable \n" - "UNIT_TESTING_DEBUG to 1 and rebuild this executable, \n" - "then click 'Debug' in the popup dialog box.\n" - "\n"); - shown_debug_message = 1; - } - exit_test(0); - return EXCEPTION_EXECUTE_HANDLER; - } - } - return EXCEPTION_CONTINUE_SEARCH; -} -#endif /* !_WIN32 */ - -void cm_print_error(const char * const format, ...) -{ - va_list args; - va_start(args, format); - if (cm_error_message_enabled) { - vcm_print_error(format, args); - } else { - vprint_error(format, args); - } - va_end(args); -} - -/* Standard output and error print methods. */ -void vprint_message(const char* const format, va_list args) { - char buffer[1024]; - vsnprintf(buffer, sizeof(buffer), format, args); - printf("%s", buffer); - fflush(stdout); -#ifdef _WIN32 - OutputDebugString(buffer); -#endif /* _WIN32 */ -} - - -void vprint_error(const char* const format, va_list args) { - char buffer[1024]; - vsnprintf(buffer, sizeof(buffer), format, args); - fprintf(stderr, "%s", buffer); - fflush(stderr); -#ifdef _WIN32 - OutputDebugString(buffer); -#endif /* _WIN32 */ -} - - -void print_message(const char* const format, ...) { - va_list args; - va_start(args, format); - vprint_message(format, args); - va_end(args); -} - - -void print_error(const char* const format, ...) { - va_list args; - va_start(args, format); - vprint_error(format, args); - va_end(args); -} - -/* New formatter */ -static enum cm_message_output cm_get_output(void) -{ - enum cm_message_output output = global_msg_output; - char *env; - - env = getenv("CMOCKA_MESSAGE_OUTPUT"); - if (env != NULL) { - if (strcasecmp(env, "STDOUT") == 0) { - output = CM_OUTPUT_STDOUT; - } else if (strcasecmp(env, "SUBUNIT") == 0) { - output = CM_OUTPUT_SUBUNIT; - } else if (strcasecmp(env, "TAP") == 0) { - output = CM_OUTPUT_TAP; - } else if (strcasecmp(env, "XML") == 0) { - output = CM_OUTPUT_XML; - } - } - - return output; -} - -enum cm_printf_type { - PRINTF_TEST_START, - PRINTF_TEST_SUCCESS, - PRINTF_TEST_FAILURE, - PRINTF_TEST_ERROR, - PRINTF_TEST_SKIPPED, -}; - -static int xml_printed; -static int file_append; - -static void cmprintf_group_finish_xml(const char *group_name, - size_t total_executed, - size_t total_failed, - size_t total_errors, - size_t total_skipped, - double total_runtime, - struct CMUnitTestState *cm_tests) -{ - FILE *fp = stdout; - int file_opened = 0; - int multiple_files = 0; - char *env; - size_t i; - - env = getenv("CMOCKA_XML_FILE"); - if (env != NULL) { - char buf[1024]; - int rc; - - snprintf(buf, sizeof(buf), "%s", env); - - rc = c_strreplace(buf, sizeof(buf), "%g", group_name, &multiple_files); - if (rc < 0) { - snprintf(buf, sizeof(buf), "%s", env); - } - - fp = fopen(buf, "r"); - if (fp == NULL) { - fp = fopen(buf, "w"); - if (fp != NULL) { - file_append = 1; - file_opened = 1; - } else { - fp = stderr; - } - } else { - fclose(fp); - if (file_append) { - fp = fopen(buf, "a"); - if (fp != NULL) { - file_opened = 1; - xml_printed = 1; - } else { - fp = stderr; - } - } else { - fp = stderr; - } - } - } - - if (!xml_printed || (file_opened && !file_append)) { - fprintf(fp, "\n"); - if (!file_opened) { - xml_printed = 1; - } - } - - fprintf(fp, "\n"); - fprintf(fp, " \n", - group_name, - total_runtime, /* seconds */ - (unsigned)total_executed, - (unsigned)total_failed, - (unsigned)total_errors, - (unsigned)total_skipped); - - for (i = 0; i < total_executed; i++) { - struct CMUnitTestState *cmtest = &cm_tests[i]; - - fprintf(fp, " \n", - cmtest->test->name, cmtest->runtime); - - switch (cmtest->status) { - case CM_TEST_ERROR: - case CM_TEST_FAILED: - if (cmtest->error_message != NULL) { - fprintf(fp, " \n", - cmtest->error_message); - } else { - fprintf(fp, " \n"); - } - break; - case CM_TEST_SKIPPED: - fprintf(fp, " \n"); - break; - - case CM_TEST_PASSED: - case CM_TEST_NOT_STARTED: - break; - } - - fprintf(fp, " \n"); - } - - fprintf(fp, " \n"); - fprintf(fp, "\n"); - - if (file_opened) { - fclose(fp); - } -} - -static void cmprintf_group_start_standard(const size_t num_tests) -{ - print_message("[==========] Running %u test(s).\n", - (unsigned)num_tests); -} - -static void cmprintf_group_finish_standard(size_t total_executed, - size_t total_passed, - size_t total_failed, - size_t total_errors, - size_t total_skipped, - struct CMUnitTestState *cm_tests) -{ - size_t i; - - print_message("[==========] %u test(s) run.\n", (unsigned)total_executed); - print_error("[ PASSED ] %u test(s).\n", - (unsigned)(total_passed)); - - if (total_skipped) { - print_error("[ SKIPPED ] %"PRIdS " test(s), listed below:\n", total_skipped); - for (i = 0; i < total_executed; i++) { - struct CMUnitTestState *cmtest = &cm_tests[i]; - - if (cmtest->status == CM_TEST_SKIPPED) { - print_error("[ SKIPPED ] %s\n", cmtest->test->name); - } - } - print_error("\n %u SKIPPED TEST(S)\n", (unsigned)(total_skipped)); - } - - if (total_failed) { - print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed); - for (i = 0; i < total_executed; i++) { - struct CMUnitTestState *cmtest = &cm_tests[i]; - - if (cmtest->status == CM_TEST_FAILED) { - print_error("[ FAILED ] %s\n", cmtest->test->name); - } - } - print_error("\n %u FAILED TEST(S)\n", - (unsigned)(total_failed + total_errors)); - } -} - -static void cmprintf_standard(enum cm_printf_type type, - const char *test_name, - const char *error_message) -{ - switch (type) { - case PRINTF_TEST_START: - print_message("[ RUN ] %s\n", test_name); - break; - case PRINTF_TEST_SUCCESS: - print_message("[ OK ] %s\n", test_name); - break; - case PRINTF_TEST_FAILURE: - if (error_message != NULL) { - print_error("[ ERROR ] --- %s\n", error_message); - } - print_message("[ FAILED ] %s\n", test_name); - break; - case PRINTF_TEST_SKIPPED: - print_message("[ SKIPPED ] %s\n", test_name); - break; - case PRINTF_TEST_ERROR: - if (error_message != NULL) { - print_error("%s\n", error_message); - } - print_error("[ ERROR ] %s\n", test_name); - break; - } -} - -static void cmprintf_group_start_tap(const size_t num_tests) -{ - print_message("1..%u\n", (unsigned)num_tests); -} - -static void cmprintf_group_finish_tap(const char *group_name, - size_t total_executed, - size_t total_passed, - size_t total_skipped) -{ - const char *status = "not ok"; - if (total_passed + total_skipped == total_executed) { - status = "ok"; - } - print_message("# %s - %s\n", status, group_name); -} - -static void cmprintf_tap(enum cm_printf_type type, - uint32_t test_number, - const char *test_name, - const char *error_message) -{ - switch (type) { - case PRINTF_TEST_START: - break; - case PRINTF_TEST_SUCCESS: - print_message("ok %u - %s\n", (unsigned)test_number, test_name); - break; - case PRINTF_TEST_FAILURE: - print_message("not ok %u - %s\n", (unsigned)test_number, test_name); - if (error_message != NULL) { - char *msg; - char *p; - - msg = strdup(error_message); - if (msg == NULL) { - return; - } - p = msg; - - while (p[0] != '\0') { - char *q = p; - - p = strchr(q, '\n'); - if (p != NULL) { - p[0] = '\0'; - } - - print_message("# %s\n", q); - - if (p == NULL) { - break; - } - p++; - } - libc_free(msg); - } - break; - case PRINTF_TEST_SKIPPED: - print_message("not ok %u # SKIP %s\n", (unsigned)test_number, test_name); - break; - case PRINTF_TEST_ERROR: - print_message("not ok %u - %s %s\n", - (unsigned)test_number, test_name, error_message); - break; - } -} - -static void cmprintf_subunit(enum cm_printf_type type, - const char *test_name, - const char *error_message) -{ - switch (type) { - case PRINTF_TEST_START: - print_message("test: %s\n", test_name); - break; - case PRINTF_TEST_SUCCESS: - print_message("success: %s\n", test_name); - break; - case PRINTF_TEST_FAILURE: - print_message("failure: %s", test_name); - if (error_message != NULL) { - print_message(" [\n%s\n]\n", error_message); - } - break; - case PRINTF_TEST_SKIPPED: - print_message("skip: %s\n", test_name); - break; - case PRINTF_TEST_ERROR: - print_message("error: %s [ %s ]\n", test_name, error_message); - break; - } -} - -static void cmprintf_group_start(const size_t num_tests) -{ - enum cm_message_output output; - - output = cm_get_output(); - - switch (output) { - case CM_OUTPUT_STDOUT: - cmprintf_group_start_standard(num_tests); - break; - case CM_OUTPUT_SUBUNIT: - break; - case CM_OUTPUT_TAP: - cmprintf_group_start_tap(num_tests); - break; - case CM_OUTPUT_XML: - break; - } -} - -static void cmprintf_group_finish(const char *group_name, - size_t total_executed, - size_t total_passed, - size_t total_failed, - size_t total_errors, - size_t total_skipped, - double total_runtime, - struct CMUnitTestState *cm_tests) -{ - enum cm_message_output output; - - output = cm_get_output(); - - switch (output) { - case CM_OUTPUT_STDOUT: - cmprintf_group_finish_standard(total_executed, - total_passed, - total_failed, - total_errors, - total_skipped, - cm_tests); - break; - case CM_OUTPUT_SUBUNIT: - break; - case CM_OUTPUT_TAP: - cmprintf_group_finish_tap(group_name, total_executed, total_passed, total_skipped); - break; - case CM_OUTPUT_XML: - cmprintf_group_finish_xml(group_name, - total_executed, - total_failed, - total_errors, - total_skipped, - total_runtime, - cm_tests); - break; - } -} - -static void cmprintf(enum cm_printf_type type, - size_t test_number, - const char *test_name, - const char *error_message) -{ - enum cm_message_output output; - - output = cm_get_output(); - - switch (output) { - case CM_OUTPUT_STDOUT: - cmprintf_standard(type, test_name, error_message); - break; - case CM_OUTPUT_SUBUNIT: - cmprintf_subunit(type, test_name, error_message); - break; - case CM_OUTPUT_TAP: - cmprintf_tap(type, test_number, test_name, error_message); - break; - case CM_OUTPUT_XML: - break; - } -} - -void cmocka_set_message_output(enum cm_message_output output) -{ - global_msg_output = output; -} - -void cmocka_set_test_filter(const char *pattern) -{ - global_test_filter_pattern = pattern; -} - -/**************************************************************************** - * TIME CALCULATIONS - ****************************************************************************/ - -#ifdef HAVE_STRUCT_TIMESPEC -static struct timespec cm_tspecdiff(struct timespec time1, - struct timespec time0) -{ - struct timespec ret; - int xsec = 0; - int sign = 1; - - if (time0.tv_nsec > time1.tv_nsec) { - xsec = (int) ((time0.tv_nsec - time1.tv_nsec) / (1E9 + 1)); - time0.tv_nsec -= (long int) (1E9 * xsec); - time0.tv_sec += xsec; - } - - if ((time1.tv_nsec - time0.tv_nsec) > 1E9) { - xsec = (int) ((time1.tv_nsec - time0.tv_nsec) / 1E9); - time0.tv_nsec += (long int) (1E9 * xsec); - time0.tv_sec -= xsec; - } - - ret.tv_sec = time1.tv_sec - time0.tv_sec; - ret.tv_nsec = time1.tv_nsec - time0.tv_nsec; - - if (time1.tv_sec < time0.tv_sec) { - sign = -1; - } - - ret.tv_sec = ret.tv_sec * sign; - - return ret; -} - -static double cm_secdiff(struct timespec clock1, struct timespec clock0) -{ - double ret; - struct timespec diff; - - diff = cm_tspecdiff(clock1, clock0); - - ret = diff.tv_sec; - ret += (double) diff.tv_nsec / (double) 1E9; - - return ret; -} -#endif /* HAVE_STRUCT_TIMESPEC */ - -/**************************************************************************** - * CMOCKA TEST RUNNER - ****************************************************************************/ -static int cmocka_run_one_test_or_fixture(const char *function_name, - CMUnitTestFunction test_func, - CMFixtureFunction setup_func, - CMFixtureFunction teardown_func, - void ** const volatile state, - const void *const heap_check_point) -{ - const ListNode * const volatile check_point = (const ListNode*) - (heap_check_point != NULL ? - heap_check_point : check_point_allocated_blocks()); - int handle_exceptions = 1; - void *current_state = NULL; - int rc = 0; - - /* FIXME check only one test or fixture is set */ - - /* Detect if we should handle exceptions */ -#ifdef _WIN32 - handle_exceptions = !IsDebuggerPresent(); -#endif /* _WIN32 */ -#ifdef UNIT_TESTING_DEBUG - handle_exceptions = 0; -#endif /* UNIT_TESTING_DEBUG */ - - - if (handle_exceptions) { -#ifndef _WIN32 - unsigned int i; - for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { - default_signal_functions[i] = signal( - exception_signals[i], exception_handler); - } -#else /* _WIN32 */ - previous_exception_filter = SetUnhandledExceptionFilter( - exception_filter); -#endif /* !_WIN32 */ - } - - /* Init the test structure */ - initialize_testing(function_name); - - global_running_test = 1; - - if (cm_setjmp(global_run_test_env) == 0) { - if (test_func != NULL) { - test_func(state != NULL ? state : ¤t_state); - - fail_if_blocks_allocated(check_point, function_name); - rc = 0; - } else if (setup_func != NULL) { - rc = setup_func(state != NULL ? state : ¤t_state); - - /* - * For setup we can ignore any allocated blocks. We just need to - * ensure they're deallocated on tear down. - */ - } else if (teardown_func != NULL) { - rc = teardown_func(state != NULL ? state : ¤t_state); - - fail_if_blocks_allocated(check_point, function_name); - } else { - /* ERROR */ - } - fail_if_leftover_values(function_name); - global_running_test = 0; - } else { - /* TEST FAILED */ - global_running_test = 0; - rc = -1; - } - teardown_testing(function_name); - - if (handle_exceptions) { -#ifndef _WIN32 - unsigned int i; - for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { - signal(exception_signals[i], default_signal_functions[i]); - } -#else /* _WIN32 */ - if (previous_exception_filter) { - SetUnhandledExceptionFilter(previous_exception_filter); - previous_exception_filter = NULL; - } -#endif /* !_WIN32 */ - } - - return rc; -} - -static int cmocka_run_group_fixture(const char *function_name, - CMFixtureFunction setup_func, - CMFixtureFunction teardown_func, - void **state, - const void *const heap_check_point) -{ - int rc; - - if (setup_func != NULL) { - rc = cmocka_run_one_test_or_fixture(function_name, - NULL, - setup_func, - NULL, - state, - heap_check_point); - } else { - rc = cmocka_run_one_test_or_fixture(function_name, - NULL, - NULL, - teardown_func, - state, - heap_check_point); - } - - return rc; -} - -static int cmocka_run_one_tests(struct CMUnitTestState *test_state) -{ -#ifdef HAVE_STRUCT_TIMESPEC - struct timespec start = { - .tv_sec = 0, - .tv_nsec = 0, - }; - struct timespec finish = { - .tv_sec = 0, - .tv_nsec = 0, - }; -#endif - int rc = 0; - - /* Run setup */ - if (test_state->test->setup_func != NULL) { - /* Setup the memory check point, it will be evaluated on teardown */ - test_state->check_point = check_point_allocated_blocks(); - - rc = cmocka_run_one_test_or_fixture(test_state->test->name, - NULL, - test_state->test->setup_func, - NULL, - &test_state->state, - test_state->check_point); - if (rc != 0) { - test_state->status = CM_TEST_ERROR; - cm_print_error("Test setup failed"); - } - } - - /* Run test */ -#ifdef HAVE_STRUCT_TIMESPEC - CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &start); -#endif - - if (rc == 0) { - rc = cmocka_run_one_test_or_fixture(test_state->test->name, - test_state->test->test_func, - NULL, - NULL, - &test_state->state, - NULL); - if (rc == 0) { - test_state->status = CM_TEST_PASSED; - } else { - if (global_skip_test) { - test_state->status = CM_TEST_SKIPPED; - global_skip_test = 0; /* Do not skip the next test */ - } else { - test_state->status = CM_TEST_FAILED; - } - } - rc = 0; - } - - test_state->runtime = 0.0; - -#ifdef HAVE_STRUCT_TIMESPEC - CMOCKA_CLOCK_GETTIME(CLOCK_REALTIME, &finish); - test_state->runtime = cm_secdiff(finish, start); -#endif - - /* Run teardown */ - if (rc == 0 && test_state->test->teardown_func != NULL) { - rc = cmocka_run_one_test_or_fixture(test_state->test->name, - NULL, - NULL, - test_state->test->teardown_func, - &test_state->state, - test_state->check_point); - if (rc != 0) { - test_state->status = CM_TEST_ERROR; - cm_print_error("Test teardown failed"); - } - } - - test_state->error_message = cm_error_message; - cm_error_message = NULL; - - return rc; -} - -int _cmocka_run_group_tests(const char *group_name, - const struct CMUnitTest * const tests, - const size_t num_tests, - CMFixtureFunction group_setup, - CMFixtureFunction group_teardown) -{ - struct CMUnitTestState *cm_tests; - const ListNode *group_check_point = check_point_allocated_blocks(); - void *group_state = NULL; - size_t total_tests = 0; - size_t total_failed = 0; - size_t total_passed = 0; - size_t total_executed = 0; - size_t total_errors = 0; - size_t total_skipped = 0; - double total_runtime = 0; - size_t i; - int rc; - - /* Make sure LargestIntegralType is at least the size of a pointer. */ - assert_true(sizeof(LargestIntegralType) >= sizeof(void*)); - - cm_tests = (struct CMUnitTestState *)libc_malloc(sizeof(struct CMUnitTestState) * num_tests); - if (cm_tests == NULL) { - return -1; - } - - /* Setup cmocka test array */ - for (i = 0; i < num_tests; i++) { - if (tests[i].name != NULL && - (tests[i].test_func != NULL - || tests[i].setup_func != NULL - || tests[i].teardown_func != NULL)) { - if (global_test_filter_pattern != NULL) { - int ok; - - ok = c_strmatch(tests[i].name, global_test_filter_pattern); - if (!ok) { - continue; - } - } - cm_tests[total_tests] = (struct CMUnitTestState) { - .test = &tests[i], - .status = CM_TEST_NOT_STARTED, - .state = NULL, - }; - total_tests++; - } - } - - cmprintf_group_start(total_tests); - - rc = 0; - - /* Run group setup */ - if (group_setup != NULL) { - rc = cmocka_run_group_fixture("cmocka_group_setup", - group_setup, - NULL, - &group_state, - group_check_point); - } - - if (rc == 0) { - /* Execute tests */ - for (i = 0; i < total_tests; i++) { - struct CMUnitTestState *cmtest = &cm_tests[i]; - size_t test_number = i + 1; - - cmprintf(PRINTF_TEST_START, test_number, cmtest->test->name, NULL); - - if (group_state != NULL) { - cmtest->state = group_state; - } else if (cmtest->test->initial_state != NULL) { - cmtest->state = cmtest->test->initial_state; - } - - rc = cmocka_run_one_tests(cmtest); - total_executed++; - total_runtime += cmtest->runtime; - if (rc == 0) { - switch (cmtest->status) { - case CM_TEST_PASSED: - cmprintf(PRINTF_TEST_SUCCESS, - test_number, - cmtest->test->name, - cmtest->error_message); - total_passed++; - break; - case CM_TEST_SKIPPED: - cmprintf(PRINTF_TEST_SKIPPED, - test_number, - cmtest->test->name, - cmtest->error_message); - total_skipped++; - break; - case CM_TEST_FAILED: - cmprintf(PRINTF_TEST_FAILURE, - test_number, - cmtest->test->name, - cmtest->error_message); - total_failed++; - break; - default: - cmprintf(PRINTF_TEST_ERROR, - test_number, - cmtest->test->name, - "Internal cmocka error"); - total_errors++; - break; - } - } else { - char err_msg[2048] = {0}; - - snprintf(err_msg, sizeof(err_msg), - "Could not run test: %s", - cmtest->error_message); - - cmprintf(PRINTF_TEST_ERROR, - test_number, - cmtest->test->name, - err_msg); - total_errors++; - } - } - } else { - if (cm_error_message != NULL) { - print_error("[ ERROR ] --- %s\n", cm_error_message); - vcm_free_error(cm_error_message); - cm_error_message = NULL; - } - cmprintf(PRINTF_TEST_ERROR, 0, - group_name, "[ FAILED ] GROUP SETUP"); - total_errors++; - } - - /* Run group teardown */ - if (group_teardown != NULL) { - rc = cmocka_run_group_fixture("cmocka_group_teardown", - NULL, - group_teardown, - &group_state, - group_check_point); - if (rc != 0) { - if (cm_error_message != NULL) { - print_error("[ ERROR ] --- %s\n", cm_error_message); - vcm_free_error(cm_error_message); - cm_error_message = NULL; - } - cmprintf(PRINTF_TEST_ERROR, 0, - group_name, "[ FAILED ] GROUP TEARDOWN"); - } - } - - cmprintf_group_finish(group_name, - total_executed, - total_passed, - total_failed, - total_errors, - total_skipped, - total_runtime, - cm_tests); - - for (i = 0; i < total_tests; i++) { - vcm_free_error(discard_const_p(char, cm_tests[i].error_message)); - } - libc_free(cm_tests); - fail_if_blocks_allocated(group_check_point, "cmocka_group_tests"); - - return total_failed + total_errors; -} - -/**************************************************************************** - * DEPRECATED TEST RUNNER - ****************************************************************************/ - -int _run_test( - const char * const function_name, const UnitTestFunction Function, - void ** const volatile state, const UnitTestFunctionType function_type, - const void* const heap_check_point) { - const ListNode * const volatile check_point = (const ListNode*) - (heap_check_point ? - heap_check_point : check_point_allocated_blocks()); - void *current_state = NULL; - volatile int rc = 1; - int handle_exceptions = 1; -#ifdef _WIN32 - handle_exceptions = !IsDebuggerPresent(); -#endif /* _WIN32 */ -#ifdef UNIT_TESTING_DEBUG - handle_exceptions = 0; -#endif /* UNIT_TESTING_DEBUG */ - - cm_error_message_enabled = 0; - - if (handle_exceptions) { -#ifndef _WIN32 - unsigned int i; - for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { - default_signal_functions[i] = signal( - exception_signals[i], exception_handler); - } -#else /* _WIN32 */ - previous_exception_filter = SetUnhandledExceptionFilter( - exception_filter); -#endif /* !_WIN32 */ - } - - if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) { - print_message("[ RUN ] %s\n", function_name); - } - initialize_testing(function_name); - global_running_test = 1; - if (cm_setjmp(global_run_test_env) == 0) { - Function(state ? state : ¤t_state); - fail_if_leftover_values(function_name); - - /* If this is a setup function then ignore any allocated blocks - * only ensure they're deallocated on tear down. */ - if (function_type != UNIT_TEST_FUNCTION_TYPE_SETUP) { - fail_if_blocks_allocated(check_point, function_name); - } - - global_running_test = 0; - - if (function_type == UNIT_TEST_FUNCTION_TYPE_TEST) { - print_message("[ OK ] %s\n", function_name); - } - rc = 0; - } else { - global_running_test = 0; - print_message("[ FAILED ] %s\n", function_name); - } - teardown_testing(function_name); - - if (handle_exceptions) { -#ifndef _WIN32 - unsigned int i; - for (i = 0; i < ARRAY_SIZE(exception_signals); i++) { - signal(exception_signals[i], default_signal_functions[i]); - } -#else /* _WIN32 */ - if (previous_exception_filter) { - SetUnhandledExceptionFilter(previous_exception_filter); - previous_exception_filter = NULL; - } -#endif /* !_WIN32 */ - } - - return rc; -} - - -int _run_tests(const UnitTest * const tests, const size_t number_of_tests) { - /* Whether to execute the next test. */ - int run_next_test = 1; - /* Whether the previous test failed. */ - int previous_test_failed = 0; - /* Whether the previous setup failed. */ - int previous_setup_failed = 0; - /* Check point of the heap state. */ - const ListNode * const check_point = check_point_allocated_blocks(); - /* Current test being executed. */ - size_t current_test = 0; - /* Number of tests executed. */ - size_t tests_executed = 0; - /* Number of failed tests. */ - size_t total_failed = 0; - /* Number of setup functions. */ - size_t setups = 0; - /* Number of teardown functions. */ - size_t teardowns = 0; - size_t i; - /* - * A stack of test states. A state is pushed on the stack - * when a test setup occurs and popped on tear down. - */ - TestState* test_states = - (TestState*)malloc(number_of_tests * sizeof(*test_states)); - /* The number of test states which should be 0 at the end */ - long number_of_test_states = 0; - /* Names of the tests that failed. */ - const char** failed_names = (const char**)malloc(number_of_tests * - sizeof(*failed_names)); - void **current_state = NULL; - - /* Count setup and teardown functions */ - for (i = 0; i < number_of_tests; i++) { - const UnitTest * const test = &tests[i]; - - if (test->function_type == UNIT_TEST_FUNCTION_TYPE_SETUP) { - setups++; - } - - if (test->function_type == UNIT_TEST_FUNCTION_TYPE_TEARDOWN) { - teardowns++; - } - } - - print_message("[==========] Running %"PRIdS " test(s).\n", - number_of_tests - setups - teardowns); - - /* Make sure LargestIntegralType is at least the size of a pointer. */ - assert_true(sizeof(LargestIntegralType) >= sizeof(void*)); - - while (current_test < number_of_tests) { - const ListNode *test_check_point = NULL; - TestState *current_TestState; - const UnitTest * const test = &tests[current_test++]; - if (!test->function) { - continue; - } - - switch (test->function_type) { - case UNIT_TEST_FUNCTION_TYPE_TEST: - if (! previous_setup_failed) { - run_next_test = 1; - } - break; - case UNIT_TEST_FUNCTION_TYPE_SETUP: { - /* Checkpoint the heap before the setup. */ - current_TestState = &test_states[number_of_test_states++]; - current_TestState->check_point = check_point_allocated_blocks(); - test_check_point = current_TestState->check_point; - current_state = ¤t_TestState->state; - *current_state = NULL; - run_next_test = 1; - break; - } - case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: - /* Check the heap based on the last setup checkpoint. */ - assert_true(number_of_test_states); - current_TestState = &test_states[--number_of_test_states]; - test_check_point = current_TestState->check_point; - current_state = ¤t_TestState->state; - break; - default: - print_error("Invalid unit test function type %d\n", - test->function_type); - exit_test(1); - break; - } - - if (run_next_test) { - int failed = _run_test(test->name, test->function, current_state, - test->function_type, test_check_point); - if (failed) { - failed_names[total_failed] = test->name; - } - - switch (test->function_type) { - case UNIT_TEST_FUNCTION_TYPE_TEST: - previous_test_failed = failed; - total_failed += failed; - tests_executed ++; - break; - - case UNIT_TEST_FUNCTION_TYPE_SETUP: - if (failed) { - total_failed ++; - tests_executed ++; - /* Skip forward until the next test or setup function. */ - run_next_test = 0; - previous_setup_failed = 1; - } - previous_test_failed = 0; - break; - - case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: - /* If this test failed. */ - if (failed && !previous_test_failed) { - total_failed ++; - } - break; - default: -#ifndef _HPUX - assert_null("BUG: shouldn't be here!"); -#endif - break; - } - } - } - - print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed); - print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed); - - if (total_failed > 0) { - print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed); - for (i = 0; i < total_failed; i++) { - print_error("[ FAILED ] %s\n", failed_names[i]); - } - } else { - print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed); - } - - if (number_of_test_states != 0) { - print_error("[ ERROR ] Mismatched number of setup %"PRIdS " and " - "teardown %"PRIdS " functions\n", setups, teardowns); - total_failed = (size_t)-1; - } - - free(test_states); - free((void*)failed_names); - - fail_if_blocks_allocated(check_point, "run_tests"); - return (int)total_failed; -} - -int _run_group_tests(const UnitTest * const tests, const size_t number_of_tests) -{ - UnitTestFunction setup = NULL; - const char *setup_name; - size_t num_setups = 0; - UnitTestFunction teardown = NULL; - const char *teardown_name = NULL; - size_t num_teardowns = 0; - size_t current_test = 0; - size_t i; - - /* Number of tests executed. */ - size_t tests_executed = 0; - /* Number of failed tests. */ - size_t total_failed = 0; - /* Check point of the heap state. */ - const ListNode * const check_point = check_point_allocated_blocks(); - const char **failed_names = NULL; - void **current_state = NULL; - TestState group_state = { - .check_point = NULL, - }; - - if (number_of_tests == 0) { - return -1; - } - - failed_names = (const char **)malloc(number_of_tests * - sizeof(*failed_names)); - if (failed_names == NULL) { - return -2; - } - - /* Find setup and teardown function */ - for (i = 0; i < number_of_tests; i++) { - const UnitTest * const test = &tests[i]; - - if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP) { - if (setup == NULL) { - setup = test->function; - setup_name = test->name; - num_setups = 1; - } else { - print_error("[ ERROR ] More than one group setup function detected\n"); - exit_test(1); - } - } - - if (test->function_type == UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN) { - if (teardown == NULL) { - teardown = test->function; - teardown_name = test->name; - num_teardowns = 1; - } else { - print_error("[ ERROR ] More than one group teardown function detected\n"); - exit_test(1); - } - } - } - - print_message("[==========] Running %"PRIdS " test(s).\n", - number_of_tests - num_setups - num_teardowns); - - if (setup != NULL) { - int failed; - - group_state.check_point = check_point_allocated_blocks(); - current_state = &group_state.state; - *current_state = NULL; - failed = _run_test(setup_name, - setup, - current_state, - UNIT_TEST_FUNCTION_TYPE_SETUP, - group_state.check_point); - if (failed) { - failed_names[total_failed] = setup_name; - } - - total_failed += failed; - tests_executed++; - } - - while (current_test < number_of_tests) { - int run_test = 0; - const UnitTest * const test = &tests[current_test++]; - if (test->function == NULL) { - continue; - } - - switch (test->function_type) { - case UNIT_TEST_FUNCTION_TYPE_TEST: - run_test = 1; - break; - case UNIT_TEST_FUNCTION_TYPE_SETUP: - case UNIT_TEST_FUNCTION_TYPE_TEARDOWN: - case UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP: - case UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN: - break; - default: - print_error("Invalid unit test function type %d\n", - test->function_type); - break; - } - - if (run_test) { - int failed; - - failed = _run_test(test->name, - test->function, - current_state, - test->function_type, - NULL); - if (failed) { - failed_names[total_failed] = test->name; - } - - total_failed += failed; - tests_executed++; - } - } - - if (teardown != NULL) { - int failed; - - failed = _run_test(teardown_name, - teardown, - current_state, - UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN, - group_state.check_point); - if (failed) { - failed_names[total_failed] = teardown_name; - } - - total_failed += failed; - tests_executed++; - } - - print_message("[==========] %"PRIdS " test(s) run.\n", tests_executed); - print_error("[ PASSED ] %"PRIdS " test(s).\n", tests_executed - total_failed); - - if (total_failed) { - print_error("[ FAILED ] %"PRIdS " test(s), listed below:\n", total_failed); - for (i = 0; i < total_failed; i++) { - print_error("[ FAILED ] %s\n", failed_names[i]); - } - } else { - print_error("\n %"PRIdS " FAILED TEST(S)\n", total_failed); - } - - free((void*)failed_names); - fail_if_blocks_allocated(check_point, "run_group_tests"); - - return (int)total_failed; -} diff --git a/ldb-2.0.8/third_party/cmocka/cmocka.h b/ldb-2.0.8/third_party/cmocka/cmocka.h deleted file mode 100644 index e6861c8..0000000 --- a/ldb-2.0.8/third_party/cmocka/cmocka.h +++ /dev/null @@ -1,2298 +0,0 @@ -/* - * Copyright 2008 Google Inc. - * Copyright 2014-2018 Andreas Schneider - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef CMOCKA_H_ -#define CMOCKA_H_ - -#ifdef _WIN32 -# ifdef _MSC_VER - -#define __func__ __FUNCTION__ - -# ifndef inline -#define inline __inline -# endif /* inline */ - -# if _MSC_VER < 1500 -# ifdef __cplusplus -extern "C" { -# endif /* __cplusplus */ -int __stdcall IsDebuggerPresent(); -# ifdef __cplusplus -} /* extern "C" */ -# endif /* __cplusplus */ -# endif /* _MSC_VER < 1500 */ -# endif /* _MSC_VER */ -#endif /* _WIN32 */ - -/** - * @defgroup cmocka The CMocka API - * - * These headers or their equivalents should be included prior to including - * this header file. - * @code - * #include - * #include - * #include - * @endcode - * - * This allows test applications to use custom definitions of C standard - * library functions and types. - * - * @{ - */ - -/* If __WORDSIZE is not set, try to figure it out and default to 32 bit. */ -#ifndef __WORDSIZE -# if (defined(__x86_64__) && !defined(__ILP32__)) || defined(__sparc_v9__) || defined(__sparcv9) -# define __WORDSIZE 64 -# else -# define __WORDSIZE 32 -# endif -#endif - -#ifdef DOXYGEN -/** - * Largest integral type. This type should be large enough to hold any - * pointer or integer supported by the compiler. - */ -typedef uintmax_t LargestIntegralType; -#else /* DOXGEN */ -#ifndef LargestIntegralType -# if __WORDSIZE == 64 && !defined(_WIN64) -# define LargestIntegralType unsigned long int -# else -# define LargestIntegralType unsigned long long int -# endif -#endif /* LargestIntegralType */ -#endif /* DOXYGEN */ - -/* Printf format used to display LargestIntegralType as a hexidecimal. */ -#ifndef LargestIntegralTypePrintfFormat -# ifdef _WIN32 -# define LargestIntegralTypePrintfFormat "0x%I64x" -# else -# if __WORDSIZE == 64 -# define LargestIntegralTypePrintfFormat "%#lx" -# else -# define LargestIntegralTypePrintfFormat "%#llx" -# endif -# endif /* _WIN32 */ -#endif /* LargestIntegralTypePrintfFormat */ - -/* Printf format used to display LargestIntegralType as a decimal. */ -#ifndef LargestIntegralTypePrintfFormatDecimal -# ifdef _WIN32 -# define LargestIntegralTypePrintfFormatDecimal "%I64u" -# else -# if __WORDSIZE == 64 -# define LargestIntegralTypePrintfFormatDecimal "%lu" -# else -# define LargestIntegralTypePrintfFormatDecimal "%llu" -# endif -# endif /* _WIN32 */ -#endif /* LargestIntegralTypePrintfFormat */ - -/* Perform an unsigned cast to LargestIntegralType. */ -#define cast_to_largest_integral_type(value) \ - ((LargestIntegralType)(value)) - -/* Smallest integral type capable of holding a pointer. */ -#if !defined(_UINTPTR_T) && !defined(_UINTPTR_T_DEFINED) -# if defined(_WIN32) - /* WIN32 is an ILP32 platform */ - typedef unsigned int uintptr_t; -# elif defined(_WIN64) - typedef unsigned long int uintptr_t -# else /* _WIN32 */ - -/* ILP32 and LP64 platforms */ -# ifdef __WORDSIZE /* glibc */ -# if __WORDSIZE == 64 - typedef unsigned long int uintptr_t; -# else - typedef unsigned int uintptr_t; -# endif /* __WORDSIZE == 64 */ -# else /* __WORDSIZE */ -# if defined(_LP64) || defined(_I32LPx) - typedef unsigned long int uintptr_t; -# else - typedef unsigned int uintptr_t; -# endif -# endif /* __WORDSIZE */ -# endif /* _WIN32 */ - -# define _UINTPTR_T -# define _UINTPTR_T_DEFINED -#endif /* !defined(_UINTPTR_T) || !defined(_UINTPTR_T_DEFINED) */ - -/* Perform an unsigned cast to uintptr_t. */ -#define cast_to_pointer_integral_type(value) \ - ((uintptr_t)((size_t)(value))) - -/* Perform a cast of a pointer to LargestIntegralType */ -#define cast_ptr_to_largest_integral_type(value) \ -cast_to_largest_integral_type(cast_to_pointer_integral_type(value)) - -/* GCC have printf type attribute check. */ -#ifdef __GNUC__ -#define CMOCKA_PRINTF_ATTRIBUTE(a,b) \ - __attribute__ ((__format__ (__printf__, a, b))) -#else -#define CMOCKA_PRINTF_ATTRIBUTE(a,b) -#endif /* __GNUC__ */ - -#if defined(__GNUC__) -#define CMOCKA_DEPRECATED __attribute__ ((deprecated)) -#elif defined(_MSC_VER) -#define CMOCKA_DEPRECATED __declspec(deprecated) -#else -#define CMOCKA_DEPRECATED -#endif - -#define WILL_RETURN_ALWAYS -1 -#define WILL_RETURN_ONCE -2 - -/** - * @defgroup cmocka_mock Mock Objects - * @ingroup cmocka - * - * Mock objects mock objects are simulated objects that mimic the behavior of - * real objects. Instead of calling the real objects, the tested object calls a - * mock object that merely asserts that the correct methods were called, with - * the expected parameters, in the correct order. - * - *

        - *
      • will_return(function, value) - The will_return() macro - * pushes a value onto a stack of mock values. This macro is intended to be - * used by the unit test itself, while programming the behaviour of the mocked - * object.
      • - * - *
      • mock() - the mock macro pops a value from a stack of - * test values. The user of the mock() macro is the mocked object that uses it - * to learn how it should behave.
      • - *
      - * - * Because the will_return() and mock() are intended to be used in pairs, the - * cmocka library would fail the test if there are more values pushed onto the - * stack using will_return() than consumed with mock() and vice-versa. - * - * The following unit test stub illustrates how would a unit test instruct the - * mock object to return a particular value: - * - * @code - * will_return(chef_cook, "hotdog"); - * will_return(chef_cook, 0); - * @endcode - * - * Now the mock object can check if the parameter it received is the parameter - * which is expected by the test driver. This can be done the following way: - * - * @code - * int chef_cook(const char *order, char **dish_out) - * { - * check_expected(order); - * } - * @endcode - * - * For a complete example please at a look - * here. - * - * @{ - */ - -#ifdef DOXYGEN -/** - * @brief Retrieve a return value of the current function. - * - * @return The value which was stored to return by this function. - * - * @see will_return() - */ -LargestIntegralType mock(void); -#else -#define mock() _mock(__func__, __FILE__, __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Retrieve a typed return value of the current function. - * - * The value would be casted to type internally to avoid having the - * caller to do the cast manually. - * - * @param[in] #type The expected type of the return value - * - * @return The value which was stored to return by this function. - * - * @code - * int param; - * - * param = mock_type(int); - * @endcode - * - * @see will_return() - * @see mock() - * @see mock_ptr_type() - */ -#type mock_type(#type); -#else -#define mock_type(type) ((type) mock()) -#endif - -#ifdef DOXYGEN -/** - * @brief Retrieve a typed return value of the current function. - * - * The value would be casted to type internally to avoid having the - * caller to do the cast manually but also casted to uintptr_t to make - * sure the result has a valid size to be used as a pointer. - * - * @param[in] #type The expected type of the return value - * - * @return The value which was stored to return by this function. - * - * @code - * char *param; - * - * param = mock_ptr_type(char *); - * @endcode - * - * @see will_return() - * @see mock() - * @see mock_type() - */ -type mock_ptr_type(#type); -#else -#define mock_ptr_type(type) ((type) (uintptr_t) mock()) -#endif - - -#ifdef DOXYGEN -/** - * @brief Store a value to be returned by mock() later. - * - * @param[in] #function The function which should return the given value. - * - * @param[in] value The value to be returned by mock(). - * - * @code - * int return_integer(void) - * { - * return (int)mock(); - * } - * - * static void test_integer_return(void **state) - * { - * will_return(return_integer, 42); - * - * assert_int_equal(my_function_calling_return_integer(), 42); - * } - * @endcode - * - * @see mock() - * @see will_return_count() - */ -void will_return(#function, LargestIntegralType value); -#else -#define will_return(function, value) \ - _will_return(#function, __FILE__, __LINE__, \ - cast_to_largest_integral_type(value), 1) -#endif - -#ifdef DOXYGEN -/** - * @brief Store a value to be returned by mock() later. - * - * @param[in] #function The function which should return the given value. - * - * @param[in] value The value to be returned by mock(). - * - * @param[in] count The parameter indicates the number of times the value should - * be returned by mock(). If count is set to -1, the value - * will always be returned but must be returned at least once. - * If count is set to -2, the value will always be returned - * by mock(), but is not required to be returned. - * - * @see mock() - */ -void will_return_count(#function, LargestIntegralType value, int count); -#else -#define will_return_count(function, value, count) \ - _will_return(#function, __FILE__, __LINE__, \ - cast_to_largest_integral_type(value), count) -#endif - -#ifdef DOXYGEN -/** - * @brief Store a value that will be always returned by mock(). - * - * @param[in] #function The function which should return the given value. - * - * @param[in] #value The value to be returned by mock(). - * - * This is equivalent to: - * @code - * will_return_count(function, value, -1); - * @endcode - * - * @see will_return_count() - * @see mock() - */ -void will_return_always(#function, LargestIntegralType value); -#else -#define will_return_always(function, value) \ - will_return_count(function, (value), WILL_RETURN_ALWAYS) -#endif - -#ifdef DOXYGEN -/** - * @brief Store a value that may be always returned by mock(). - * - * This stores a value which will always be returned by mock() but is not - * required to be returned by at least one call to mock(). Therefore, - * in contrast to will_return_always() which causes a test failure if it - * is not returned at least once, will_return_maybe() will never cause a test - * to fail if its value is not returned. - * - * @param[in] #function The function which should return the given value. - * - * @param[in] #value The value to be returned by mock(). - * - * This is equivalent to: - * @code - * will_return_count(function, value, -2); - * @endcode - * - * @see will_return_count() - * @see mock() - */ -void will_return_maybe(#function, LargestIntegralType value); -#else -#define will_return_maybe(function, value) \ - will_return_count(function, (value), WILL_RETURN_ONCE) -#endif -/** @} */ - -/** - * @defgroup cmocka_param Checking Parameters - * @ingroup cmocka - * - * Functionality to store expected values for mock function parameters. - * - * In addition to storing the return values of mock functions, cmocka provides - * functionality to store expected values for mock function parameters using - * the expect_*() functions provided. A mock function parameter can then be - * validated using the check_expected() macro. - * - * Successive calls to expect_*() macros for a parameter queues values to check - * the specified parameter. check_expected() checks a function parameter - * against the next value queued using expect_*(), if the parameter check fails - * a test failure is signalled. In addition if check_expected() is called and - * no more parameter values are queued a test failure occurs. - * - * The following test stub illustrates how to do this. First is the the function - * we call in the test driver: - * - * @code - * static void test_driver(void **state) - * { - * expect_string(chef_cook, order, "hotdog"); - * } - * @endcode - * - * Now the chef_cook function can check if the parameter we got passed is the - * parameter which is expected by the test driver. This can be done the - * following way: - * - * @code - * int chef_cook(const char *order, char **dish_out) - * { - * check_expected(order); - * } - * @endcode - * - * For a complete example please at a look at - * here - * - * @{ - */ - -/* - * Add a custom parameter checking function. If the event parameter is NULL - * the event structure is allocated internally by this function. If event - * parameter is provided it must be allocated on the heap and doesn't need to - * be deallocated by the caller. - */ -#ifdef DOXYGEN -/** - * @brief Add a custom parameter checking function. - * - * If the event parameter is NULL the event structure is allocated internally - * by this function. If the parameter is provided it must be allocated on the - * heap and doesn't need to be deallocated by the caller. - * - * @param[in] #function The function to add a custom parameter checking - * function for. - * - * @param[in] #parameter The parameters passed to the function. - * - * @param[in] #check_function The check function to call. - * - * @param[in] check_data The data to pass to the check function. - */ -void expect_check(#function, #parameter, #check_function, const void *check_data); -#else -#define expect_check(function, parameter, check_function, check_data) \ - _expect_check(#function, #parameter, __FILE__, __LINE__, check_function, \ - cast_to_largest_integral_type(check_data), NULL, 1) -#endif - -#ifdef DOXYGEN -/** - * @brief Add an event to check if the parameter value is part of the provided - * array. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @param[in] value_array[] The array to check for the value. - * - * @see check_expected(). - */ -void expect_in_set(#function, #parameter, LargestIntegralType value_array[]); -#else -#define expect_in_set(function, parameter, value_array) \ - expect_in_set_count(function, parameter, value_array, 1) -#endif - -#ifdef DOXYGEN -/** - * @brief Add an event to check if the parameter value is part of the provided - * array. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @param[in] value_array[] The array to check for the value. - * - * @param[in] count The count parameter returns the number of times the value - * should be returned by check_expected(). If count is set - * to -1 the value will always be returned. - * - * @see check_expected(). - */ -void expect_in_set_count(#function, #parameter, LargestIntegralType value_array[], size_t count); -#else -#define expect_in_set_count(function, parameter, value_array, count) \ - _expect_in_set(#function, #parameter, __FILE__, __LINE__, value_array, \ - sizeof(value_array) / sizeof((value_array)[0]), count) -#endif - -#ifdef DOXYGEN -/** - * @brief Add an event to check if the parameter value is not part of the - * provided array. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @param[in] value_array[] The array to check for the value. - * - * @see check_expected(). - */ -void expect_not_in_set(#function, #parameter, LargestIntegralType value_array[]); -#else -#define expect_not_in_set(function, parameter, value_array) \ - expect_not_in_set_count(function, parameter, value_array, 1) -#endif - -#ifdef DOXYGEN -/** - * @brief Add an event to check if the parameter value is not part of the - * provided array. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @param[in] value_array[] The array to check for the value. - * - * @param[in] count The count parameter returns the number of times the value - * should be returned by check_expected(). If count is set - * to -1 the value will always be returned. - * - * @see check_expected(). - */ -void expect_not_in_set_count(#function, #parameter, LargestIntegralType value_array[], size_t count); -#else -#define expect_not_in_set_count(function, parameter, value_array, count) \ - _expect_not_in_set( \ - #function, #parameter, __FILE__, __LINE__, value_array, \ - sizeof(value_array) / sizeof((value_array)[0]), count) -#endif - - -#ifdef DOXYGEN -/** - * @brief Add an event to check a parameter is inside a numerical range. - * The check would succeed if minimum <= value <= maximum. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @param[in] minimum The lower boundary of the interval to check against. - * - * @param[in] maximum The upper boundary of the interval to check against. - * - * @see check_expected(). - */ -void expect_in_range(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum); -#else -#define expect_in_range(function, parameter, minimum, maximum) \ - expect_in_range_count(function, parameter, minimum, maximum, 1) -#endif - -#ifdef DOXYGEN -/** - * @brief Add an event to repeatedly check a parameter is inside a - * numerical range. The check would succeed if minimum <= value <= maximum. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @param[in] minimum The lower boundary of the interval to check against. - * - * @param[in] maximum The upper boundary of the interval to check against. - * - * @param[in] count The count parameter returns the number of times the value - * should be returned by check_expected(). If count is set - * to -1 the value will always be returned. - * - * @see check_expected(). - */ -void expect_in_range_count(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum, size_t count); -#else -#define expect_in_range_count(function, parameter, minimum, maximum, count) \ - _expect_in_range(#function, #parameter, __FILE__, __LINE__, minimum, \ - maximum, count) -#endif - -#ifdef DOXYGEN -/** - * @brief Add an event to check a parameter is outside a numerical range. - * The check would succeed if minimum > value > maximum. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @param[in] minimum The lower boundary of the interval to check against. - * - * @param[in] maximum The upper boundary of the interval to check against. - * - * @see check_expected(). - */ -void expect_not_in_range(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum); -#else -#define expect_not_in_range(function, parameter, minimum, maximum) \ - expect_not_in_range_count(function, parameter, minimum, maximum, 1) -#endif - -#ifdef DOXYGEN -/** - * @brief Add an event to repeatedly check a parameter is outside a - * numerical range. The check would succeed if minimum > value > maximum. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @param[in] minimum The lower boundary of the interval to check against. - * - * @param[in] maximum The upper boundary of the interval to check against. - * - * @param[in] count The count parameter returns the number of times the value - * should be returned by check_expected(). If count is set - * to -1 the value will always be returned. - * - * @see check_expected(). - */ -void expect_not_in_range_count(#function, #parameter, LargestIntegralType minimum, LargestIntegralType maximum, size_t count); -#else -#define expect_not_in_range_count(function, parameter, minimum, maximum, \ - count) \ - _expect_not_in_range(#function, #parameter, __FILE__, __LINE__, \ - minimum, maximum, count) -#endif - -#ifdef DOXYGEN -/** - * @brief Add an event to check if a parameter is the given value. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @param[in] value The value to check. - * - * @see check_expected(). - */ -void expect_value(#function, #parameter, LargestIntegralType value); -#else -#define expect_value(function, parameter, value) \ - expect_value_count(function, parameter, value, 1) -#endif - -#ifdef DOXYGEN -/** - * @brief Add an event to repeatedly check if a parameter is the given value. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @param[in] value The value to check. - * - * @param[in] count The count parameter returns the number of times the value - * should be returned by check_expected(). If count is set - * to -1 the value will always be returned. - * - * @see check_expected(). - */ -void expect_value_count(#function, #parameter, LargestIntegralType value, size_t count); -#else -#define expect_value_count(function, parameter, value, count) \ - _expect_value(#function, #parameter, __FILE__, __LINE__, \ - cast_to_largest_integral_type(value), count) -#endif - -#ifdef DOXYGEN -/** - * @brief Add an event to check if a parameter isn't the given value. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @param[in] value The value to check. - * - * @see check_expected(). - */ -void expect_not_value(#function, #parameter, LargestIntegralType value); -#else -#define expect_not_value(function, parameter, value) \ - expect_not_value_count(function, parameter, value, 1) -#endif - -#ifdef DOXYGEN -/** - * @brief Add an event to repeatedly check if a parameter isn't the given value. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @param[in] value The value to check. - * - * @param[in] count The count parameter returns the number of times the value - * should be returned by check_expected(). If count is set - * to -1 the value will always be returned. - * - * @see check_expected(). - */ -void expect_not_value_count(#function, #parameter, LargestIntegralType value, size_t count); -#else -#define expect_not_value_count(function, parameter, value, count) \ - _expect_not_value(#function, #parameter, __FILE__, __LINE__, \ - cast_to_largest_integral_type(value), count) -#endif - -#ifdef DOXYGEN -/** - * @brief Add an event to check if the parameter value is equal to the - * provided string. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @param[in] string The string value to compare. - * - * @see check_expected(). - */ -void expect_string(#function, #parameter, const char *string); -#else -#define expect_string(function, parameter, string) \ - expect_string_count(function, parameter, string, 1) -#endif - -#ifdef DOXYGEN -/** - * @brief Add an event to check if the parameter value is equal to the - * provided string. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @param[in] string The string value to compare. - * - * @param[in] count The count parameter returns the number of times the value - * should be returned by check_expected(). If count is set - * to -1 the value will always be returned. - * - * @see check_expected(). - */ -void expect_string_count(#function, #parameter, const char *string, size_t count); -#else -#define expect_string_count(function, parameter, string, count) \ - _expect_string(#function, #parameter, __FILE__, __LINE__, \ - (const char*)(string), count) -#endif - -#ifdef DOXYGEN -/** - * @brief Add an event to check if the parameter value isn't equal to the - * provided string. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @param[in] string The string value to compare. - * - * @see check_expected(). - */ -void expect_not_string(#function, #parameter, const char *string); -#else -#define expect_not_string(function, parameter, string) \ - expect_not_string_count(function, parameter, string, 1) -#endif - -#ifdef DOXYGEN -/** - * @brief Add an event to check if the parameter value isn't equal to the - * provided string. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @param[in] string The string value to compare. - * - * @param[in] count The count parameter returns the number of times the value - * should be returned by check_expected(). If count is set - * to -1 the value will always be returned. - * - * @see check_expected(). - */ -void expect_not_string_count(#function, #parameter, const char *string, size_t count); -#else -#define expect_not_string_count(function, parameter, string, count) \ - _expect_not_string(#function, #parameter, __FILE__, __LINE__, \ - (const char*)(string), count) -#endif - -#ifdef DOXYGEN -/** - * @brief Add an event to check if the parameter does match an area of memory. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @param[in] memory The memory to compare. - * - * @param[in] size The size of the memory to compare. - * - * @see check_expected(). - */ -void expect_memory(#function, #parameter, void *memory, size_t size); -#else -#define expect_memory(function, parameter, memory, size) \ - expect_memory_count(function, parameter, memory, size, 1) -#endif - -#ifdef DOXYGEN -/** - * @brief Add an event to repeatedly check if the parameter does match an area - * of memory. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @param[in] memory The memory to compare. - * - * @param[in] size The size of the memory to compare. - * - * @param[in] count The count parameter returns the number of times the value - * should be returned by check_expected(). If count is set - * to -1 the value will always be returned. - * - * @see check_expected(). - */ -void expect_memory_count(#function, #parameter, void *memory, size_t size, size_t count); -#else -#define expect_memory_count(function, parameter, memory, size, count) \ - _expect_memory(#function, #parameter, __FILE__, __LINE__, \ - (const void*)(memory), size, count) -#endif - -#ifdef DOXYGEN -/** - * @brief Add an event to check if the parameter doesn't match an area of - * memory. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @param[in] memory The memory to compare. - * - * @param[in] size The size of the memory to compare. - * - * @see check_expected(). - */ -void expect_not_memory(#function, #parameter, void *memory, size_t size); -#else -#define expect_not_memory(function, parameter, memory, size) \ - expect_not_memory_count(function, parameter, memory, size, 1) -#endif - -#ifdef DOXYGEN -/** - * @brief Add an event to repeatedly check if the parameter doesn't match an - * area of memory. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @param[in] memory The memory to compare. - * - * @param[in] size The size of the memory to compare. - * - * @param[in] count The count parameter returns the number of times the value - * should be returned by check_expected(). If count is set - * to -1 the value will always be returned. - * - * @see check_expected(). - */ -void expect_not_memory_count(#function, #parameter, void *memory, size_t size, size_t count); -#else -#define expect_not_memory_count(function, parameter, memory, size, count) \ - _expect_not_memory(#function, #parameter, __FILE__, __LINE__, \ - (const void*)(memory), size, count) -#endif - - -#ifdef DOXYGEN -/** - * @brief Add an event to check if a parameter (of any value) has been passed. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @see check_expected(). - */ -void expect_any(#function, #parameter); -#else -#define expect_any(function, parameter) \ - expect_any_count(function, parameter, 1) -#endif - -#ifdef DOXYGEN -/** - * @brief Add an event to repeatedly check if a parameter (of any value) has - * been passed. - * - * The event is triggered by calling check_expected() in the mocked function. - * - * @param[in] #function The function to add the check for. - * - * @param[in] #parameter The name of the parameter passed to the function. - * - * @param[in] count The count parameter returns the number of times the value - * should be returned by check_expected(). If count is set - * to -1 the value will always be returned. - * - * @see check_expected(). - */ -void expect_any_count(#function, #parameter, size_t count); -#else -#define expect_any_count(function, parameter, count) \ - _expect_any(#function, #parameter, __FILE__, __LINE__, count) -#endif - -#ifdef DOXYGEN -/** - * @brief Determine whether a function parameter is correct. - * - * This ensures the next value queued by one of the expect_*() macros matches - * the specified variable. - * - * This function needs to be called in the mock object. - * - * @param[in] #parameter The parameter to check. - */ -void check_expected(#parameter); -#else -#define check_expected(parameter) \ - _check_expected(__func__, #parameter, __FILE__, __LINE__, \ - cast_to_largest_integral_type(parameter)) -#endif - -#ifdef DOXYGEN -/** - * @brief Determine whether a function parameter is correct. - * - * This ensures the next value queued by one of the expect_*() macros matches - * the specified variable. - * - * This function needs to be called in the mock object. - * - * @param[in] #parameter The pointer to check. - */ -void check_expected_ptr(#parameter); -#else -#define check_expected_ptr(parameter) \ - _check_expected(__func__, #parameter, __FILE__, __LINE__, \ - cast_ptr_to_largest_integral_type(parameter)) -#endif - -/** @} */ - -/** - * @defgroup cmocka_asserts Assert Macros - * @ingroup cmocka - * - * This is a set of useful assert macros like the standard C libary's - * assert(3) macro. - * - * On an assertion failure a cmocka assert macro will write the failure to the - * standard error stream and signal a test failure. Due to limitations of the C - * language the general C standard library assert() and cmocka's assert_true() - * and assert_false() macros can only display the expression that caused the - * assert failure. cmocka's type specific assert macros, assert_{type}_equal() - * and assert_{type}_not_equal(), display the data that caused the assertion - * failure which increases data visibility aiding debugging of failing test - * cases. - * - * @{ - */ - -#ifdef DOXYGEN -/** - * @brief Assert that the given expression is true. - * - * The function prints an error message to standard error and terminates the - * test by calling fail() if expression is false (i.e., compares equal to - * zero). - * - * @param[in] expression The expression to evaluate. - * - * @see assert_int_equal() - * @see assert_string_equal() - */ -void assert_true(scalar expression); -#else -#define assert_true(c) _assert_true(cast_to_largest_integral_type(c), #c, \ - __FILE__, __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Assert that the given expression is false. - * - * The function prints an error message to standard error and terminates the - * test by calling fail() if expression is true. - * - * @param[in] expression The expression to evaluate. - * - * @see assert_int_equal() - * @see assert_string_equal() - */ -void assert_false(scalar expression); -#else -#define assert_false(c) _assert_true(!(cast_to_largest_integral_type(c)), #c, \ - __FILE__, __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Assert that the return_code is greater than or equal to 0. - * - * The function prints an error message to standard error and terminates the - * test by calling fail() if the return code is smaller than 0. If the function - * you check sets an errno if it fails you can pass it to the function and - * it will be printed as part of the error message. - * - * @param[in] rc The return code to evaluate. - * - * @param[in] error Pass errno here or 0. - */ -void assert_return_code(int rc, int error); -#else -#define assert_return_code(rc, error) \ - _assert_return_code(cast_to_largest_integral_type(rc), \ - sizeof(rc), \ - cast_to_largest_integral_type(error), \ - #rc, __FILE__, __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Assert that the given pointer is non-NULL. - * - * The function prints an error message to standard error and terminates the - * test by calling fail() if the pointer is NULL. - * - * @param[in] pointer The pointer to evaluate. - * - * @see assert_null() - */ -void assert_non_null(void *pointer); -#else -#define assert_non_null(c) _assert_true(cast_ptr_to_largest_integral_type(c), #c, \ - __FILE__, __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Assert that the given pointer is NULL. - * - * The function prints an error message to standard error and terminates the - * test by calling fail() if the pointer is non-NULL. - * - * @param[in] pointer The pointer to evaluate. - * - * @see assert_non_null() - */ -void assert_null(void *pointer); -#else -#define assert_null(c) _assert_true(!(cast_ptr_to_largest_integral_type(c)), #c, \ -__FILE__, __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Assert that the two given pointers are equal. - * - * The function prints an error message and terminates the test by calling - * fail() if the pointers are not equal. - * - * @param[in] a The first pointer to compare. - * - * @param[in] b The pointer to compare against the first one. - */ -void assert_ptr_equal(void *a, void *b); -#else -#define assert_ptr_equal(a, b) \ - _assert_int_equal(cast_ptr_to_largest_integral_type(a), \ - cast_ptr_to_largest_integral_type(b), \ - __FILE__, __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Assert that the two given pointers are not equal. - * - * The function prints an error message and terminates the test by calling - * fail() if the pointers are equal. - * - * @param[in] a The first pointer to compare. - * - * @param[in] b The pointer to compare against the first one. - */ -void assert_ptr_not_equal(void *a, void *b); -#else -#define assert_ptr_not_equal(a, b) \ - _assert_int_not_equal(cast_ptr_to_largest_integral_type(a), \ - cast_ptr_to_largest_integral_type(b), \ - __FILE__, __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Assert that the two given integers are equal. - * - * The function prints an error message to standard error and terminates the - * test by calling fail() if the integers are not equal. - * - * @param[in] a The first integer to compare. - * - * @param[in] b The integer to compare against the first one. - */ -void assert_int_equal(int a, int b); -#else -#define assert_int_equal(a, b) \ - _assert_int_equal(cast_to_largest_integral_type(a), \ - cast_to_largest_integral_type(b), \ - __FILE__, __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Assert that the two given integers are not equal. - * - * The function prints an error message to standard error and terminates the - * test by calling fail() if the integers are equal. - * - * @param[in] a The first integer to compare. - * - * @param[in] b The integer to compare against the first one. - * - * @see assert_int_equal() - */ -void assert_int_not_equal(int a, int b); -#else -#define assert_int_not_equal(a, b) \ - _assert_int_not_equal(cast_to_largest_integral_type(a), \ - cast_to_largest_integral_type(b), \ - __FILE__, __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Assert that the two given strings are equal. - * - * The function prints an error message to standard error and terminates the - * test by calling fail() if the strings are not equal. - * - * @param[in] a The string to check. - * - * @param[in] b The other string to compare. - */ -void assert_string_equal(const char *a, const char *b); -#else -#define assert_string_equal(a, b) \ - _assert_string_equal((const char*)(a), (const char*)(b), __FILE__, \ - __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Assert that the two given strings are not equal. - * - * The function prints an error message to standard error and terminates the - * test by calling fail() if the strings are equal. - * - * @param[in] a The string to check. - * - * @param[in] b The other string to compare. - */ -void assert_string_not_equal(const char *a, const char *b); -#else -#define assert_string_not_equal(a, b) \ - _assert_string_not_equal((const char*)(a), (const char*)(b), __FILE__, \ - __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Assert that the two given areas of memory are equal, otherwise fail. - * - * The function prints an error message to standard error and terminates the - * test by calling fail() if the memory is not equal. - * - * @param[in] a The first memory area to compare - * (interpreted as unsigned char). - * - * @param[in] b The second memory area to compare - * (interpreted as unsigned char). - * - * @param[in] size The first n bytes of the memory areas to compare. - */ -void assert_memory_equal(const void *a, const void *b, size_t size); -#else -#define assert_memory_equal(a, b, size) \ - _assert_memory_equal((const void*)(a), (const void*)(b), size, __FILE__, \ - __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Assert that the two given areas of memory are not equal. - * - * The function prints an error message to standard error and terminates the - * test by calling fail() if the memory is equal. - * - * @param[in] a The first memory area to compare - * (interpreted as unsigned char). - * - * @param[in] b The second memory area to compare - * (interpreted as unsigned char). - * - * @param[in] size The first n bytes of the memory areas to compare. - */ -void assert_memory_not_equal(const void *a, const void *b, size_t size); -#else -#define assert_memory_not_equal(a, b, size) \ - _assert_memory_not_equal((const void*)(a), (const void*)(b), size, \ - __FILE__, __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Assert that the specified value is not smaller than the minimum - * and and not greater than the maximum. - * - * The function prints an error message to standard error and terminates the - * test by calling fail() if value is not in range. - * - * @param[in] value The value to check. - * - * @param[in] minimum The minimum value allowed. - * - * @param[in] maximum The maximum value allowed. - */ -void assert_in_range(LargestIntegralType value, LargestIntegralType minimum, LargestIntegralType maximum); -#else -#define assert_in_range(value, minimum, maximum) \ - _assert_in_range( \ - cast_to_largest_integral_type(value), \ - cast_to_largest_integral_type(minimum), \ - cast_to_largest_integral_type(maximum), __FILE__, __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Assert that the specified value is smaller than the minimum or - * greater than the maximum. - * - * The function prints an error message to standard error and terminates the - * test by calling fail() if value is in range. - * - * @param[in] value The value to check. - * - * @param[in] minimum The minimum value to compare. - * - * @param[in] maximum The maximum value to compare. - */ -void assert_not_in_range(LargestIntegralType value, LargestIntegralType minimum, LargestIntegralType maximum); -#else -#define assert_not_in_range(value, minimum, maximum) \ - _assert_not_in_range( \ - cast_to_largest_integral_type(value), \ - cast_to_largest_integral_type(minimum), \ - cast_to_largest_integral_type(maximum), __FILE__, __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Assert that the specified value is within a set. - * - * The function prints an error message to standard error and terminates the - * test by calling fail() if value is not within a set. - * - * @param[in] value The value to look up - * - * @param[in] values[] The array to check for the value. - * - * @param[in] count The size of the values array. - */ -void assert_in_set(LargestIntegralType value, LargestIntegralType values[], size_t count); -#else -#define assert_in_set(value, values, number_of_values) \ - _assert_in_set(value, values, number_of_values, __FILE__, __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Assert that the specified value is not within a set. - * - * The function prints an error message to standard error and terminates the - * test by calling fail() if value is within a set. - * - * @param[in] value The value to look up - * - * @param[in] values[] The array to check for the value. - * - * @param[in] count The size of the values array. - */ -void assert_not_in_set(LargestIntegralType value, LargestIntegralType values[], size_t count); -#else -#define assert_not_in_set(value, values, number_of_values) \ - _assert_not_in_set(value, values, number_of_values, __FILE__, __LINE__) -#endif - -/** @} */ - -/** - * @defgroup cmocka_call_order Call Ordering - * @ingroup cmocka - * - * It is often beneficial to make sure that functions are called in an - * order. This is independent of mock returns and parameter checking as both - * of the aforementioned do not check the order in which they are called from - * different functions. - * - *
        - *
      • expect_function_call(function) - The - * expect_function_call() macro pushes an expectation onto the stack of - * expected calls.
      • - * - *
      • function_called() - pops a value from the stack of - * expected calls. function_called() is invoked within the mock object - * that uses it. - *
      - * - * expect_function_call() and function_called() are intended to be used in - * pairs. Cmocka will fail a test if there are more or less expected calls - * created (e.g. expect_function_call()) than consumed with function_called(). - * There are provisions such as ignore_function_calls() which allow this - * restriction to be circumvented in tests where mock calls for the code under - * test are not the focus of the test. - * - * The following example illustrates how a unit test instructs cmocka - * to expect a function_called() from a particular mock, - * chef_sing(): - * - * @code - * void chef_sing(void); - * - * void code_under_test() - * { - * chef_sing(); - * } - * - * void some_test(void **state) - * { - * expect_function_call(chef_sing); - * code_under_test(); - * } - * @endcode - * - * The implementation of the mock then must check whether it was meant to - * be called by invoking function_called(): - * - * @code - * void chef_sing() - * { - * function_called(); - * } - * @endcode - * - * @{ - */ - -#ifdef DOXYGEN -/** - * @brief Check that current mocked function is being called in the expected - * order - * - * @see expect_function_call() - */ -void function_called(void); -#else -#define function_called() _function_called(__func__, __FILE__, __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Store expected call(s) to a mock to be checked by function_called() - * later. - * - * @param[in] #function The function which should should be called - * - * @param[in] times number of times this mock must be called - * - * @see function_called() - */ -void expect_function_calls(#function, const int times); -#else -#define expect_function_calls(function, times) \ - _expect_function_call(#function, __FILE__, __LINE__, times) -#endif - -#ifdef DOXYGEN -/** - * @brief Store expected single call to a mock to be checked by - * function_called() later. - * - * @param[in] #function The function which should should be called - * - * @see function_called() - */ -void expect_function_call(#function); -#else -#define expect_function_call(function) \ - _expect_function_call(#function, __FILE__, __LINE__, 1) -#endif - -#ifdef DOXYGEN -/** - * @brief Expects function_called() from given mock at least once - * - * @param[in] #function The function which should should be called - * - * @see function_called() - */ -void expect_function_call_any(#function); -#else -#define expect_function_call_any(function) \ - _expect_function_call(#function, __FILE__, __LINE__, -1) -#endif - -#ifdef DOXYGEN -/** - * @brief Ignores function_called() invocations from given mock function. - * - * @param[in] #function The function which should should be called - * - * @see function_called() - */ -void ignore_function_calls(#function); -#else -#define ignore_function_calls(function) \ - _expect_function_call(#function, __FILE__, __LINE__, -2) -#endif - -/** @} */ - -/** - * @defgroup cmocka_exec Running Tests - * @ingroup cmocka - * - * This is the way tests are executed with CMocka. - * - * The following example illustrates this macro's use with the unit_test macro. - * - * @code - * void Test0(void **state); - * void Test1(void **state); - * - * int main(void) - * { - * const struct CMUnitTest tests[] = { - * cmocka_unit_test(Test0), - * cmocka_unit_test(Test1), - * }; - * - * return cmocka_run_group_tests(tests, NULL, NULL); - * } - * @endcode - * - * @{ - */ - -#ifdef DOXYGEN -/** - * @brief Forces the test to fail immediately and quit. - */ -void fail(void); -#else -#define fail() _fail(__FILE__, __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Forces the test to not be executed, but marked as skipped - */ -void skip(void); -#else -#define skip() _skip(__FILE__, __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Forces the test to fail immediately and quit, printing the reason. - * - * @code - * fail_msg("This is some error message for test"); - * @endcode - * - * or - * - * @code - * char *error_msg = "This is some error message for test"; - * fail_msg("%s", error_msg); - * @endcode - */ -void fail_msg(const char *msg, ...); -#else -#define fail_msg(msg, ...) do { \ - print_error("ERROR: " msg "\n", ##__VA_ARGS__); \ - fail(); \ -} while (0) -#endif - -#ifdef DOXYGEN -/** - * @brief Generic method to run a single test. - * - * @deprecated This function was deprecated in favor of cmocka_run_group_tests - * - * @param[in] #function The function to test. - * - * @return 0 on success, 1 if an error occured. - * - * @code - * // A test case that does nothing and succeeds. - * void null_test_success(void **state) { - * } - * - * int main(void) { - * return run_test(null_test_success); - * } - * @endcode - */ -int run_test(#function); -#else -#define run_test(f) _run_test(#f, f, NULL, UNIT_TEST_FUNCTION_TYPE_TEST, NULL) -#endif - -static inline void _unit_test_dummy(void **state) { - (void)state; -} - -/** Initializes a UnitTest structure. - * - * @deprecated This function was deprecated in favor of cmocka_unit_test - */ -#define unit_test(f) { #f, f, UNIT_TEST_FUNCTION_TYPE_TEST } - -#define _unit_test_setup(test, setup) \ - { #test "_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_SETUP } - -/** Initializes a UnitTest structure with a setup function. - * - * @deprecated This function was deprecated in favor of cmocka_unit_test_setup - */ -#define unit_test_setup(test, setup) \ - _unit_test_setup(test, setup), \ - unit_test(test), \ - _unit_test_teardown(test, _unit_test_dummy) - -#define _unit_test_teardown(test, teardown) \ - { #test "_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_TEARDOWN } - -/** Initializes a UnitTest structure with a teardown function. - * - * @deprecated This function was deprecated in favor of cmocka_unit_test_teardown - */ -#define unit_test_teardown(test, teardown) \ - _unit_test_setup(test, _unit_test_dummy), \ - unit_test(test), \ - _unit_test_teardown(test, teardown) - -/** Initializes a UnitTest structure for a group setup function. - * - * @deprecated This function was deprecated in favor of cmocka_run_group_tests - */ -#define group_test_setup(setup) \ - { "group_" #setup, setup, UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP } - -/** Initializes a UnitTest structure for a group teardown function. - * - * @deprecated This function was deprecated in favor of cmocka_run_group_tests - */ -#define group_test_teardown(teardown) \ - { "group_" #teardown, teardown, UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN } - -/** - * Initialize an array of UnitTest structures with a setup function for a test - * and a teardown function. Either setup or teardown can be NULL. - * - * @deprecated This function was deprecated in favor of - * cmocka_unit_test_setup_teardown - */ -#define unit_test_setup_teardown(test, setup, teardown) \ - _unit_test_setup(test, setup), \ - unit_test(test), \ - _unit_test_teardown(test, teardown) - - -/** Initializes a CMUnitTest structure. */ -#define cmocka_unit_test(f) { #f, f, NULL, NULL, NULL } - -/** Initializes a CMUnitTest structure with a setup function. */ -#define cmocka_unit_test_setup(f, setup) { #f, f, setup, NULL, NULL } - -/** Initializes a CMUnitTest structure with a teardown function. */ -#define cmocka_unit_test_teardown(f, teardown) { #f, f, NULL, teardown, NULL } - -/** - * Initialize an array of CMUnitTest structures with a setup function for a test - * and a teardown function. Either setup or teardown can be NULL. - */ -#define cmocka_unit_test_setup_teardown(f, setup, teardown) { #f, f, setup, teardown, NULL } - -/** - * Initialize a CMUnitTest structure with given initial state. It will be passed - * to test function as an argument later. It can be used when test state does - * not need special initialization or was initialized already. - * @note If the group setup function initialized the state already, it won't be - * overridden by the initial state defined here. - */ -#define cmocka_unit_test_prestate(f, state) { #f, f, NULL, NULL, state } - -/** - * Initialize a CMUnitTest structure with given initial state, setup and - * teardown function. Any of these values can be NULL. Initial state is passed - * later to setup function, or directly to test if none was given. - * @note If the group setup function initialized the state already, it won't be - * overridden by the initial state defined here. - */ -#define cmocka_unit_test_prestate_setup_teardown(f, setup, teardown, state) { #f, f, setup, teardown, state } - -#define run_tests(tests) _run_tests(tests, sizeof(tests) / sizeof((tests)[0])) -#define run_group_tests(tests) _run_group_tests(tests, sizeof(tests) / sizeof((tests)[0])) - -#ifdef DOXYGEN -/** - * @brief Run tests specified by an array of CMUnitTest structures. - * - * @param[in] group_tests[] The array of unit tests to execute. - * - * @param[in] group_setup The setup function which should be called before - * all unit tests are executed. - * - * @param[in] group_teardown The teardown function to be called after all - * tests have finished. - * - * @return 0 on success, or the number of failed tests. - * - * @code - * static int setup(void **state) { - * int *answer = malloc(sizeof(int)); - * if (*answer == NULL) { - * return -1; - * } - * *answer = 42; - * - * *state = answer; - * - * return 0; - * } - * - * static int teardown(void **state) { - * free(*state); - * - * return 0; - * } - * - * static void null_test_success(void **state) { - * (void) state; - * } - * - * static void int_test_success(void **state) { - * int *answer = *state; - * assert_int_equal(*answer, 42); - * } - * - * int main(void) { - * const struct CMUnitTest tests[] = { - * cmocka_unit_test(null_test_success), - * cmocka_unit_test_setup_teardown(int_test_success, setup, teardown), - * }; - * - * return cmocka_run_group_tests(tests, NULL, NULL); - * } - * @endcode - * - * @see cmocka_unit_test - * @see cmocka_unit_test_setup - * @see cmocka_unit_test_teardown - * @see cmocka_unit_test_setup_teardown - */ -int cmocka_run_group_tests(const struct CMUnitTest group_tests[], - CMFixtureFunction group_setup, - CMFixtureFunction group_teardown); -#else -# define cmocka_run_group_tests(group_tests, group_setup, group_teardown) \ - _cmocka_run_group_tests(#group_tests, group_tests, sizeof(group_tests) / sizeof((group_tests)[0]), group_setup, group_teardown) -#endif - -#ifdef DOXYGEN -/** - * @brief Run tests specified by an array of CMUnitTest structures and specify - * a name. - * - * @param[in] group_name The name of the group test. - * - * @param[in] group_tests[] The array of unit tests to execute. - * - * @param[in] group_setup The setup function which should be called before - * all unit tests are executed. - * - * @param[in] group_teardown The teardown function to be called after all - * tests have finished. - * - * @return 0 on success, or the number of failed tests. - * - * @code - * static int setup(void **state) { - * int *answer = malloc(sizeof(int)); - * if (*answer == NULL) { - * return -1; - * } - * *answer = 42; - * - * *state = answer; - * - * return 0; - * } - * - * static int teardown(void **state) { - * free(*state); - * - * return 0; - * } - * - * static void null_test_success(void **state) { - * (void) state; - * } - * - * static void int_test_success(void **state) { - * int *answer = *state; - * assert_int_equal(*answer, 42); - * } - * - * int main(void) { - * const struct CMUnitTest tests[] = { - * cmocka_unit_test(null_test_success), - * cmocka_unit_test_setup_teardown(int_test_success, setup, teardown), - * }; - * - * return cmocka_run_group_tests_name("success_test", tests, NULL, NULL); - * } - * @endcode - * - * @see cmocka_unit_test - * @see cmocka_unit_test_setup - * @see cmocka_unit_test_teardown - * @see cmocka_unit_test_setup_teardown - */ -int cmocka_run_group_tests_name(const char *group_name, - const struct CMUnitTest group_tests[], - CMFixtureFunction group_setup, - CMFixtureFunction group_teardown); -#else -# define cmocka_run_group_tests_name(group_name, group_tests, group_setup, group_teardown) \ - _cmocka_run_group_tests(group_name, group_tests, sizeof(group_tests) / sizeof((group_tests)[0]), group_setup, group_teardown) -#endif - -/** @} */ - -/** - * @defgroup cmocka_alloc Dynamic Memory Allocation - * @ingroup cmocka - * - * Memory leaks, buffer overflows and underflows can be checked using cmocka. - * - * To test for memory leaks, buffer overflows and underflows a module being - * tested by cmocka should replace calls to malloc(), calloc() and free() to - * test_malloc(), test_calloc() and test_free() respectively. Each time a block - * is deallocated using test_free() it is checked for corruption, if a corrupt - * block is found a test failure is signalled. All blocks allocated using the - * test_*() allocation functions are tracked by the cmocka library. When a test - * completes if any allocated blocks (memory leaks) remain they are reported - * and a test failure is signalled. - * - * For simplicity cmocka currently executes all tests in one process. Therefore - * all test cases in a test application share a single address space which - * means memory corruption from a single test case could potentially cause the - * test application to exit prematurely. - * - * @{ - */ - -#ifdef DOXYGEN -/** - * @brief Test function overriding malloc. - * - * @param[in] size The bytes which should be allocated. - * - * @return A pointer to the allocated memory or NULL on error. - * - * @code - * #ifdef UNIT_TESTING - * extern void* _test_malloc(const size_t size, const char* file, const int line); - * - * #define malloc(size) _test_malloc(size, __FILE__, __LINE__) - * #endif - * - * void leak_memory() { - * int * const temporary = (int*)malloc(sizeof(int)); - * *temporary = 0; - * } - * @endcode - * - * @see malloc(3) - */ -void *test_malloc(size_t size); -#else -#define test_malloc(size) _test_malloc(size, __FILE__, __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Test function overriding calloc. - * - * The memory is set to zero. - * - * @param[in] nmemb The number of elements for an array to be allocated. - * - * @param[in] size The size in bytes of each array element to allocate. - * - * @return A pointer to the allocated memory, NULL on error. - * - * @see calloc(3) - */ -void *test_calloc(size_t nmemb, size_t size); -#else -#define test_calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Test function overriding realloc which detects buffer overruns - * and memoery leaks. - * - * @param[in] ptr The memory block which should be changed. - * - * @param[in] size The bytes which should be allocated. - * - * @return The newly allocated memory block, NULL on error. - */ -void *test_realloc(void *ptr, size_t size); -#else -#define test_realloc(ptr, size) _test_realloc(ptr, size, __FILE__, __LINE__) -#endif - -#ifdef DOXYGEN -/** - * @brief Test function overriding free(3). - * - * @param[in] ptr The pointer to the memory space to free. - * - * @see free(3). - */ -void test_free(void *ptr); -#else -#define test_free(ptr) _test_free(ptr, __FILE__, __LINE__) -#endif - -/* Redirect malloc, calloc and free to the unit test allocators. */ -#ifdef UNIT_TESTING -#define malloc test_malloc -#define realloc test_realloc -#define calloc test_calloc -#define free test_free -#endif /* UNIT_TESTING */ - -/** @} */ - - -/** - * @defgroup cmocka_mock_assert Standard Assertions - * @ingroup cmocka - * - * How to handle assert(3) of the standard C library. - * - * Runtime assert macros like the standard C library's assert() should be - * redefined in modules being tested to use cmocka's mock_assert() function. - * Normally mock_assert() signals a test failure. If a function is called using - * the expect_assert_failure() macro, any calls to mock_assert() within the - * function will result in the execution of the test. If no calls to - * mock_assert() occur during the function called via expect_assert_failure() a - * test failure is signalled. - * - * @{ - */ - -/** - * @brief Function to replace assert(3) in tested code. - * - * In conjuction with check_assert() it's possible to determine whether an - * assert condition has failed without stopping a test. - * - * @param[in] result The expression to assert. - * - * @param[in] expression The expression as string. - * - * @param[in] file The file mock_assert() is called. - * - * @param[in] line The line mock_assert() is called. - * - * @code - * #ifdef UNIT_TESTING - * extern void mock_assert(const int result, const char* const expression, - * const char * const file, const int line); - * - * #undef assert - * #define assert(expression) \ - * mock_assert((int)(expression), #expression, __FILE__, __LINE__); - * #endif - * - * void increment_value(int * const value) { - * assert(value); - * (*value) ++; - * } - * @endcode - * - * @see assert(3) - * @see expect_assert_failure - */ -void mock_assert(const int result, const char* const expression, - const char * const file, const int line); - -#ifdef DOXYGEN -/** - * @brief Ensure that mock_assert() is called. - * - * If mock_assert() is called the assert expression string is returned. - * - * @param[in] fn_call The function will will call mock_assert(). - * - * @code - * #define assert mock_assert - * - * void showmessage(const char *message) { - * assert(message); - * } - * - * int main(int argc, const char* argv[]) { - * expect_assert_failure(show_message(NULL)); - * printf("succeeded\n"); - * return 0; - * } - * @endcode - * - */ -void expect_assert_failure(function fn_call); -#else -#define expect_assert_failure(function_call) \ - { \ - const int result = setjmp(global_expect_assert_env); \ - global_expecting_assert = 1; \ - if (result) { \ - print_message("Expected assertion %s occurred\n", \ - global_last_failed_assert); \ - global_expecting_assert = 0; \ - } else { \ - function_call ; \ - global_expecting_assert = 0; \ - print_error("Expected assert in %s\n", #function_call); \ - _fail(__FILE__, __LINE__); \ - } \ - } -#endif - -/** @} */ - -/* Function prototype for setup, test and teardown functions. */ -typedef void (*UnitTestFunction)(void **state); - -/* Function that determines whether a function parameter value is correct. */ -typedef int (*CheckParameterValue)(const LargestIntegralType value, - const LargestIntegralType check_value_data); - -/* Type of the unit test function. */ -typedef enum UnitTestFunctionType { - UNIT_TEST_FUNCTION_TYPE_TEST = 0, - UNIT_TEST_FUNCTION_TYPE_SETUP, - UNIT_TEST_FUNCTION_TYPE_TEARDOWN, - UNIT_TEST_FUNCTION_TYPE_GROUP_SETUP, - UNIT_TEST_FUNCTION_TYPE_GROUP_TEARDOWN, -} UnitTestFunctionType; - -/* - * Stores a unit test function with its name and type. - * NOTE: Every setup function must be paired with a teardown function. It's - * possible to specify NULL function pointers. - */ -typedef struct UnitTest { - const char* name; - UnitTestFunction function; - UnitTestFunctionType function_type; -} UnitTest; - -typedef struct GroupTest { - UnitTestFunction setup; - UnitTestFunction teardown; - const UnitTest *tests; - const size_t number_of_tests; -} GroupTest; - -/* Function prototype for test functions. */ -typedef void (*CMUnitTestFunction)(void **state); - -/* Function prototype for setup and teardown functions. */ -typedef int (*CMFixtureFunction)(void **state); - -struct CMUnitTest { - const char *name; - CMUnitTestFunction test_func; - CMFixtureFunction setup_func; - CMFixtureFunction teardown_func; - void *initial_state; -}; - -/* Location within some source code. */ -typedef struct SourceLocation { - const char* file; - int line; -} SourceLocation; - -/* Event that's called to check a parameter value. */ -typedef struct CheckParameterEvent { - SourceLocation location; - const char *parameter_name; - CheckParameterValue check_value; - LargestIntegralType check_value_data; -} CheckParameterEvent; - -/* Used by expect_assert_failure() and mock_assert(). */ -extern int global_expecting_assert; -extern jmp_buf global_expect_assert_env; -extern const char * global_last_failed_assert; - -/* Retrieves a value for the given function, as set by "will_return". */ -LargestIntegralType _mock(const char * const function, const char* const file, - const int line); - -void _expect_function_call( - const char * const function_name, - const char * const file, - const int line, - const int count); - -void _function_called(const char * const function, const char* const file, - const int line); - -void _expect_check( - const char* const function, const char* const parameter, - const char* const file, const int line, - const CheckParameterValue check_function, - const LargestIntegralType check_data, CheckParameterEvent * const event, - const int count); - -void _expect_in_set( - const char* const function, const char* const parameter, - const char* const file, const int line, const LargestIntegralType values[], - const size_t number_of_values, const int count); -void _expect_not_in_set( - const char* const function, const char* const parameter, - const char* const file, const int line, const LargestIntegralType values[], - const size_t number_of_values, const int count); - -void _expect_in_range( - const char* const function, const char* const parameter, - const char* const file, const int line, - const LargestIntegralType minimum, - const LargestIntegralType maximum, const int count); -void _expect_not_in_range( - const char* const function, const char* const parameter, - const char* const file, const int line, - const LargestIntegralType minimum, - const LargestIntegralType maximum, const int count); - -void _expect_value( - const char* const function, const char* const parameter, - const char* const file, const int line, const LargestIntegralType value, - const int count); -void _expect_not_value( - const char* const function, const char* const parameter, - const char* const file, const int line, const LargestIntegralType value, - const int count); - -void _expect_string( - const char* const function, const char* const parameter, - const char* const file, const int line, const char* string, - const int count); -void _expect_not_string( - const char* const function, const char* const parameter, - const char* const file, const int line, const char* string, - const int count); - -void _expect_memory( - const char* const function, const char* const parameter, - const char* const file, const int line, const void* const memory, - const size_t size, const int count); -void _expect_not_memory( - const char* const function, const char* const parameter, - const char* const file, const int line, const void* const memory, - const size_t size, const int count); - -void _expect_any( - const char* const function, const char* const parameter, - const char* const file, const int line, const int count); - -void _check_expected( - const char * const function_name, const char * const parameter_name, - const char* file, const int line, const LargestIntegralType value); - -void _will_return(const char * const function_name, const char * const file, - const int line, const LargestIntegralType value, - const int count); -void _assert_true(const LargestIntegralType result, - const char* const expression, - const char * const file, const int line); -void _assert_return_code(const LargestIntegralType result, - size_t rlen, - const LargestIntegralType error, - const char * const expression, - const char * const file, - const int line); -void _assert_int_equal( - const LargestIntegralType a, const LargestIntegralType b, - const char * const file, const int line); -void _assert_int_not_equal( - const LargestIntegralType a, const LargestIntegralType b, - const char * const file, const int line); -void _assert_string_equal(const char * const a, const char * const b, - const char * const file, const int line); -void _assert_string_not_equal(const char * const a, const char * const b, - const char *file, const int line); -void _assert_memory_equal(const void * const a, const void * const b, - const size_t size, const char* const file, - const int line); -void _assert_memory_not_equal(const void * const a, const void * const b, - const size_t size, const char* const file, - const int line); -void _assert_in_range( - const LargestIntegralType value, const LargestIntegralType minimum, - const LargestIntegralType maximum, const char* const file, const int line); -void _assert_not_in_range( - const LargestIntegralType value, const LargestIntegralType minimum, - const LargestIntegralType maximum, const char* const file, const int line); -void _assert_in_set( - const LargestIntegralType value, const LargestIntegralType values[], - const size_t number_of_values, const char* const file, const int line); -void _assert_not_in_set( - const LargestIntegralType value, const LargestIntegralType values[], - const size_t number_of_values, const char* const file, const int line); - -void* _test_malloc(const size_t size, const char* file, const int line); -void* _test_realloc(void *ptr, const size_t size, const char* file, const int line); -void* _test_calloc(const size_t number_of_elements, const size_t size, - const char* file, const int line); -void _test_free(void* const ptr, const char* file, const int line); - -void _fail(const char * const file, const int line); - -void _skip(const char * const file, const int line); - -int _run_test( - const char * const function_name, const UnitTestFunction Function, - void ** const volatile state, const UnitTestFunctionType function_type, - const void* const heap_check_point); -CMOCKA_DEPRECATED int _run_tests(const UnitTest * const tests, - const size_t number_of_tests); -CMOCKA_DEPRECATED int _run_group_tests(const UnitTest * const tests, - const size_t number_of_tests); - -/* Test runner */ -int _cmocka_run_group_tests(const char *group_name, - const struct CMUnitTest * const tests, - const size_t num_tests, - CMFixtureFunction group_setup, - CMFixtureFunction group_teardown); - -/* Standard output and error print methods. */ -void print_message(const char* const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); -void print_error(const char* const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2); -void vprint_message(const char* const format, va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0); -void vprint_error(const char* const format, va_list args) CMOCKA_PRINTF_ATTRIBUTE(1, 0); - -enum cm_message_output { - CM_OUTPUT_STDOUT, - CM_OUTPUT_SUBUNIT, - CM_OUTPUT_TAP, - CM_OUTPUT_XML, -}; - -/** - * @brief Function to set the output format for a test. - * - * The ouput format for the test can either be set globally using this - * function or overriden with environment variable CMOCKA_MESSAGE_OUTPUT. - * - * The environment variable can be set to either STDOUT, SUBUNIT, TAP or XML. - * - * @param[in] output The output format to use for the test. - * - */ -void cmocka_set_message_output(enum cm_message_output output); - - -/** - * @brief Set a pattern to only run the test matching the pattern. - * - * This allows to filter tests and only run the ones matching the pattern. Thep - * pattern can include two wildards. The first is '*', a wildcard that matches - * zero or more characters, or ‘?’, a wildcard that matches exactly one - * character. - * - * @param[in] pattern The pattern to match, e.g. "test_wurst*" - */ -void cmocka_set_test_filter(const char *pattern); - -/** @} */ - -#endif /* CMOCKA_H_ */ diff --git a/ldb-2.0.8/third_party/cmocka/cmocka_private.h b/ldb-2.0.8/third_party/cmocka/cmocka_private.h deleted file mode 100644 index d20d841..0000000 --- a/ldb-2.0.8/third_party/cmocka/cmocka_private.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2008 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef CMOCKA_PRIVATE_H_ -#define CMOCKA_PRIVATE_H_ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#ifdef _WIN32 -#include - -# ifdef _MSC_VER -# include /* _snprintf */ - -# undef inline -# define inline __inline - -# ifndef va_copy -# define va_copy(dest, src) (dest = src) -# endif - -# define strcasecmp _stricmp -# define strncasecmp _strnicmp - -# if defined(HAVE__SNPRINTF_S) -# undef snprintf -# define snprintf(d, n, ...) _snprintf_s((d), (n), _TRUNCATE, __VA_ARGS__) -# else /* HAVE__SNPRINTF_S */ -# if defined(HAVE__SNPRINTF) -# undef snprintf -# define snprintf _snprintf -# else /* HAVE__SNPRINTF */ -# if !defined(HAVE_SNPRINTF) -# error "no snprintf compatible function found" -# endif /* HAVE_SNPRINTF */ -# endif /* HAVE__SNPRINTF */ -# endif /* HAVE__SNPRINTF_S */ - -# if defined(HAVE__VSNPRINTF_S) -# undef vsnprintf -# define vsnprintf(s, n, f, v) _vsnprintf_s((s), (n), _TRUNCATE, (f), (v)) -# else /* HAVE__VSNPRINTF_S */ -# if defined(HAVE__VSNPRINTF) -# undef vsnprintf -# define vsnprintf _vsnprintf -# else -# if !defined(HAVE_VSNPRINTF) -# error "No vsnprintf compatible function found" -# endif /* HAVE_VSNPRINTF */ -# endif /* HAVE__VSNPRINTF */ -# endif /* HAVE__VSNPRINTF_S */ -# endif /* _MSC_VER */ - -/* - * Backwards compatibility with headers shipped with Visual Studio 2005 and - * earlier. - */ -WINBASEAPI BOOL WINAPI IsDebuggerPresent(VOID); - -#ifndef PRIdS -# define PRIdS "Id" -#endif - -#ifndef PRIu64 -# define PRIu64 "I64u" -#endif - -#ifndef PRIuMAX -# define PRIuMAX PRIu64 -#endif - -#ifndef PRIxMAX -#define PRIxMAX "I64x" -#endif - -#ifndef PRIXMAX -#define PRIXMAX "I64X" -#endif - -#else /* _WIN32 */ - -#ifndef __PRI64_PREFIX -# if __WORDSIZE == 64 -# define __PRI64_PREFIX "l" -# else -# define __PRI64_PREFIX "ll" -# endif -#endif - -#ifndef PRIdS -# define PRIdS "zd" -#endif - -#ifndef PRIu64 -# define PRIu64 __PRI64_PREFIX "u" -#endif - -#ifndef PRIuMAX -# define PRIuMAX __PRI64_PREFIX "u" -#endif - -#ifndef PRIxMAX -#define PRIxMAX __PRI64_PREFIX "x" -#endif - -#ifndef PRIXMAX -#define PRIXMAX __PRI64_PREFIX "X" -#endif - -#endif /* _WIN32 */ - -/** Free memory space */ -#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0) - -/** Zero a structure */ -#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x)) - -/** Zero a structure given a pointer to the structure */ -#define ZERO_STRUCTP(x) do { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); } while(0) - -/** Get the size of an array */ -#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) - -/** Overwrite the complete string with 'X' */ -#define BURN_STRING(x) do { if ((x) != NULL) memset((x), 'X', strlen((x))); } while(0) - -/** - * This is a hack to fix warnings. The idea is to use this everywhere that we - * get the "discarding const" warning by the compiler. That doesn't actually - * fix the real issue, but marks the place and you can search the code for - * discard_const. - * - * Please use this macro only when there is no other way to fix the warning. - * We should use this function in only in a very few places. - * - * Also, please call this via the discard_const_p() macro interface, as that - * makes the return type safe. - */ -#define discard_const(ptr) ((void *)((uintptr_t)(ptr))) - -/** - * Type-safe version of discard_const - */ -#define discard_const_p(type, ptr) ((type *)discard_const(ptr)) - -#endif /* CMOCKA_PRIVATE_H_ */ diff --git a/ldb-2.0.8/third_party/cmocka/wscript b/ldb-2.0.8/third_party/cmocka/wscript deleted file mode 100644 index 3c2ad50..0000000 --- a/ldb-2.0.8/third_party/cmocka/wscript +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env python - -from waflib import Options - -def configure(conf): - conf.CHECK_FUNCS('longjmp siglongjmp') - - if conf.CHECK_CMOCKA(): - conf.define('USING_SYSTEM_CMOCKA', 1) - -def build(bld): - if bld.CONFIG_SET('USING_SYSTEM_CMOCKA'): - return - - extra_libs='' - - # Link to librt if needed for clock_gettime() - if bld.CONFIG_SET('HAVE_LIBRT'): extra_libs += ' rt' - - bld.SAMBA_LIBRARY('cmocka', - source='cmocka.c', - deps=extra_libs, - allow_warnings=True, - private_library=True) diff --git a/ldb-2.0.8/third_party/popt/CHANGES b/ldb-2.0.8/third_party/popt/CHANGES deleted file mode 100644 index db16a5f..0000000 --- a/ldb-2.0.8/third_party/popt/CHANGES +++ /dev/null @@ -1,46 +0,0 @@ -1.5 -> 1.6 - - add ability to perform callbacks for every, not just first, match. - -1.3 -> 1.5 - - heavy dose of const's - - poptParseArgvString() now NULL terminates the list - -1.2.3 -> 1.3 - - added support for single - - - misc bug fixes - - portability improvements - -1.2.2 -> 1.2.3 - - fixed memset() in help message generation (Dale Hawkins) - - added extern "C" stuff to popt.h for C++ compilers (Dale Hawkins) - - const'ified poptParseArgvString (Jeff Garzik) - -1.2.1 -> 1.2.2 - - fixed bug in chaind alias happens which seems to have only - affected --triggers in rpm - - added POPT_ARG_VAL - - popt.3 installed by default - -1.2 -> 1.2.1 - - added POPT_ARG_INTL_DOMAIN (Elliot Lee) - - updated Makefile's to be more GNUish (Elliot Lee) - -1.1 -> 1.2 - - added popt.3 man page (Robert Lynch) - - don't use mmap anymore (its lack of portability isn't worth the - trouble) - - added test script - - added support for exec - - removed support for *_POPT_ALIASES env variable -- it was a bad - idea - - reorganized into multiple source files - - added automatic help generation, POPT_AUTOHELP - - added table callbacks - - added table inclusion - - updated man page for new features - - added test scripts - -1.0 -> 1.1 - - moved to autoconf (Fred Fish) - - added STRERROR replacement (Norbert Warmuth) - - added const keywords (Bruce Perens) diff --git a/ldb-2.0.8/third_party/popt/COPYING b/ldb-2.0.8/third_party/popt/COPYING deleted file mode 100644 index b4c7ca8..0000000 --- a/ldb-2.0.8/third_party/popt/COPYING +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 1998 Red Hat Software - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of the X Consortium shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from the X Consortium. diff --git a/ldb-2.0.8/third_party/popt/README b/ldb-2.0.8/third_party/popt/README deleted file mode 100644 index c66432d..0000000 --- a/ldb-2.0.8/third_party/popt/README +++ /dev/null @@ -1,16 +0,0 @@ -This is the popt(3) command line option parsing library. While it is similiar -to getopt(3), it contains a number of enhancements, including: - - 1) popt is fully reentrant - 2) popt can parse arbitrary argv[] style arrays while - getopt(3) makes this quite difficult - 3) popt allows users to alias command line arguments - 4) popt provides convience functions for parsing strings - into argv[] style arrays - -Complete documentation on popt(3) is available in popt.ps (included in this -tarball), which is excerpted with permission from the book "Linux -Application Development" by Michael K. Johnson and Erik Troan (available -from Addison Wesley in May, 1998). - -Comments on popt should be addressed to popt-devel@rpm5.org. diff --git a/ldb-2.0.8/third_party/popt/findme.h b/ldb-2.0.8/third_party/popt/findme.h deleted file mode 100644 index a016b86..0000000 --- a/ldb-2.0.8/third_party/popt/findme.h +++ /dev/null @@ -1,20 +0,0 @@ -/** \ingroup popt - * \file popt/findme.h - */ - -/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist. */ - -#ifndef H_FINDME -#define H_FINDME - -/** - * Return absolute path to executable by searching PATH. - * @param argv0 name of executable - * @return (malloc'd) absolute path to executable (or NULL) - */ -/*@null@*/ const char * findProgramPath(/*@null@*/ const char * argv0) - /*@*/; - -#endif diff --git a/ldb-2.0.8/third_party/popt/lookup3.c b/ldb-2.0.8/third_party/popt/lookup3.c deleted file mode 100644 index eb4e5ce..0000000 --- a/ldb-2.0.8/third_party/popt/lookup3.c +++ /dev/null @@ -1,969 +0,0 @@ -/* -------------------------------------------------------------------- */ -/* - * lookup3.c, by Bob Jenkins, May 2006, Public Domain. - * - * These are functions for producing 32-bit hashes for hash table lookup. - * jlu32w(), jlu32l(), jlu32lpair(), jlu32b(), _JLU3_MIX(), and _JLU3_FINAL() - * are externally useful functions. Routines to test the hash are included - * if SELF_TEST is defined. You can use this free for any purpose. It's in - * the public domain. It has no warranty. - * - * You probably want to use jlu32l(). jlu32l() and jlu32b() - * hash byte arrays. jlu32l() is is faster than jlu32b() on - * little-endian machines. Intel and AMD are little-endian machines. - * On second thought, you probably want jlu32lpair(), which is identical to - * jlu32l() except it returns two 32-bit hashes for the price of one. - * You could implement jlu32bpair() if you wanted but I haven't bothered here. - * - * If you want to find a hash of, say, exactly 7 integers, do - * a = i1; b = i2; c = i3; - * _JLU3_MIX(a,b,c); - * a += i4; b += i5; c += i6; - * _JLU3_MIX(a,b,c); - * a += i7; - * _JLU3_FINAL(a,b,c); - * then use c as the hash value. If you have a variable size array of - * 4-byte integers to hash, use jlu32w(). If you have a byte array (like - * a character string), use jlu32l(). If you have several byte arrays, or - * a mix of things, see the comments above jlu32l(). - * - * Why is this so big? I read 12 bytes at a time into 3 4-byte integers, - * then mix those integers. This is fast (you can do a lot more thorough - * mixing with 12*3 instructions on 3 integers than you can with 3 instructions - * on 1 byte), but shoehorning those bytes into integers efficiently is messy. -*/ -/* -------------------------------------------------------------------- */ - -#include - -#if defined(_JLU3_SELFTEST) -# define _JLU3_jlu32w 1 -# define _JLU3_jlu32l 1 -# define _JLU3_jlu32lpair 1 -# define _JLU3_jlu32b 1 -#endif - -/*@-redef@*/ -/*@unchecked@*/ -static const union _dbswap { - const uint32_t ui; - const unsigned char uc[4]; -} endian = { .ui = 0x11223344 }; -# define HASH_LITTLE_ENDIAN (endian.uc[0] == (unsigned char) 0x44) -# define HASH_BIG_ENDIAN (endian.uc[0] == (unsigned char) 0x11) -/*@=redef@*/ - -#ifndef ROTL32 -# define ROTL32(x, s) (((x) << (s)) | ((x) >> (32 - (s)))) -#endif - -/* NOTE: The _size parameter should be in bytes. */ -#define _JLU3_INIT(_h, _size) (0xdeadbeef + ((uint32_t)(_size)) + (_h)) - -/* -------------------------------------------------------------------- */ -/* - * _JLU3_MIX -- mix 3 32-bit values reversibly. - * - * This is reversible, so any information in (a,b,c) before _JLU3_MIX() is - * still in (a,b,c) after _JLU3_MIX(). - * - * If four pairs of (a,b,c) inputs are run through _JLU3_MIX(), or through - * _JLU3_MIX() in reverse, there are at least 32 bits of the output that - * are sometimes the same for one pair and different for another pair. - * This was tested for: - * * pairs that differed by one bit, by two bits, in any combination - * of top bits of (a,b,c), or in any combination of bottom bits of - * (a,b,c). - * * "differ" is defined as +, -, ^, or ~^. For + and -, I transformed - * the output delta to a Gray code (a^(a>>1)) so a string of 1's (as - * is commonly produced by subtraction) look like a single 1-bit - * difference. - * * the base values were pseudorandom, all zero but one bit set, or - * all zero plus a counter that starts at zero. - * - * Some k values for my "a-=c; a^=ROTL32(c,k); c+=b;" arrangement that - * satisfy this are - * 4 6 8 16 19 4 - * 9 15 3 18 27 15 - * 14 9 3 7 17 3 - * Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing - * for "differ" defined as + with a one-bit base and a two-bit delta. I - * used http://burtleburtle.net/bob/hash/avalanche.html to choose - * the operations, constants, and arrangements of the variables. - * - * This does not achieve avalanche. There are input bits of (a,b,c) - * that fail to affect some output bits of (a,b,c), especially of a. The - * most thoroughly mixed value is c, but it doesn't really even achieve - * avalanche in c. - * - * This allows some parallelism. Read-after-writes are good at doubling - * the number of bits affected, so the goal of mixing pulls in the opposite - * direction as the goal of parallelism. I did what I could. Rotates - * seem to cost as much as shifts on every machine I could lay my hands - * on, and rotates are much kinder to the top and bottom bits, so I used - * rotates. - */ -/* -------------------------------------------------------------------- */ -#define _JLU3_MIX(a,b,c) \ -{ \ - a -= c; a ^= ROTL32(c, 4); c += b; \ - b -= a; b ^= ROTL32(a, 6); a += c; \ - c -= b; c ^= ROTL32(b, 8); b += a; \ - a -= c; a ^= ROTL32(c,16); c += b; \ - b -= a; b ^= ROTL32(a,19); a += c; \ - c -= b; c ^= ROTL32(b, 4); b += a; \ -} - -/* -------------------------------------------------------------------- */ -/** - * _JLU3_FINAL -- final mixing of 3 32-bit values (a,b,c) into c - * - * Pairs of (a,b,c) values differing in only a few bits will usually - * produce values of c that look totally different. This was tested for - * * pairs that differed by one bit, by two bits, in any combination - * of top bits of (a,b,c), or in any combination of bottom bits of - * (a,b,c). - * * "differ" is defined as +, -, ^, or ~^. For + and -, I transformed - * the output delta to a Gray code (a^(a>>1)) so a string of 1's (as - * is commonly produced by subtraction) look like a single 1-bit - * difference. - * * the base values were pseudorandom, all zero but one bit set, or - * all zero plus a counter that starts at zero. - * - * These constants passed: - * 14 11 25 16 4 14 24 - * 12 14 25 16 4 14 24 - * and these came close: - * 4 8 15 26 3 22 24 - * 10 8 15 26 3 22 24 - * 11 8 15 26 3 22 24 - */ -/* -------------------------------------------------------------------- */ -#define _JLU3_FINAL(a,b,c) \ -{ \ - c ^= b; c -= ROTL32(b,14); \ - a ^= c; a -= ROTL32(c,11); \ - b ^= a; b -= ROTL32(a,25); \ - c ^= b; c -= ROTL32(b,16); \ - a ^= c; a -= ROTL32(c,4); \ - b ^= a; b -= ROTL32(a,14); \ - c ^= b; c -= ROTL32(b,24); \ -} - -#if defined(_JLU3_jlu32w) -uint32_t jlu32w(uint32_t h, /*@null@*/ const uint32_t *k, size_t size) - /*@*/; -/* -------------------------------------------------------------------- */ -/** - * This works on all machines. To be useful, it requires - * -- that the key be an array of uint32_t's, and - * -- that the size be the number of uint32_t's in the key - * - * The function jlu32w() is identical to jlu32l() on little-endian - * machines, and identical to jlu32b() on big-endian machines, - * except that the size has to be measured in uint32_ts rather than in - * bytes. jlu32l() is more complicated than jlu32w() only because - * jlu32l() has to dance around fitting the key bytes into registers. - * - * @param h the previous hash, or an arbitrary value - * @param *k the key, an array of uint32_t values - * @param size the size of the key, in uint32_ts - * @return the lookup3 hash - */ -/* -------------------------------------------------------------------- */ -uint32_t jlu32w(uint32_t h, const uint32_t *k, size_t size) -{ - uint32_t a = _JLU3_INIT(h, (size * sizeof(*k))); - uint32_t b = a; - uint32_t c = a; - - if (k == NULL) - goto exit; - - /*----------------------------------------------- handle most of the key */ - while (size > 3) { - a += k[0]; - b += k[1]; - c += k[2]; - _JLU3_MIX(a,b,c); - size -= 3; - k += 3; - } - - /*----------------------------------------- handle the last 3 uint32_t's */ - switch (size) { - case 3 : c+=k[2]; - case 2 : b+=k[1]; - case 1 : a+=k[0]; - _JLU3_FINAL(a,b,c); - /*@fallthrough@*/ - case 0: - break; - } - /*---------------------------------------------------- report the result */ -exit: - return c; -} -#endif /* defined(_JLU3_jlu32w) */ - -#if defined(_JLU3_jlu32l) -uint32_t jlu32l(uint32_t h, const void *key, size_t size) - /*@*/; -/* -------------------------------------------------------------------- */ -/* - * jlu32l() -- hash a variable-length key into a 32-bit value - * h : can be any 4-byte value - * k : the key (the unaligned variable-length array of bytes) - * size : the size of the key, counting by bytes - * Returns a 32-bit value. Every bit of the key affects every bit of - * the return value. Two keys differing by one or two bits will have - * totally different hash values. - * - * The best hash table sizes are powers of 2. There is no need to do - * mod a prime (mod is sooo slow!). If you need less than 32 bits, - * use a bitmask. For example, if you need only 10 bits, do - * h = (h & hashmask(10)); - * In which case, the hash table should have hashsize(10) elements. - * - * If you are hashing n strings (uint8_t **)k, do it like this: - * for (i=0, h=0; i 12) { - a += k[0]; - b += k[1]; - c += k[2]; - _JLU3_MIX(a,b,c); - size -= 12; - k += 3; - } - - /*------------------------- handle the last (probably partial) block */ - /* - * "k[2]&0xffffff" actually reads beyond the end of the string, but - * then masks off the part it's not allowed to read. Because the - * string is aligned, the masked-off tail is in the same word as the - * rest of the string. Every machine with memory protection I've seen - * does it on word boundaries, so is OK with this. But VALGRIND will - * still catch it and complain. The masking trick does make the hash - * noticably faster for short strings (like English words). - */ -#ifndef VALGRIND - - switch (size) { - case 12: c += k[2]; b+=k[1]; a+=k[0]; break; - case 11: c += k[2]&0xffffff; b+=k[1]; a+=k[0]; break; - case 10: c += k[2]&0xffff; b+=k[1]; a+=k[0]; break; - case 9: c += k[2]&0xff; b+=k[1]; a+=k[0]; break; - case 8: b += k[1]; a+=k[0]; break; - case 7: b += k[1]&0xffffff; a+=k[0]; break; - case 6: b += k[1]&0xffff; a+=k[0]; break; - case 5: b += k[1]&0xff; a+=k[0]; break; - case 4: a += k[0]; break; - case 3: a += k[0]&0xffffff; break; - case 2: a += k[0]&0xffff; break; - case 1: a += k[0]&0xff; break; - case 0: goto exit; - } - -#else /* make valgrind happy */ - - k8 = (const uint8_t *)k; - switch (size) { - case 12: c += k[2]; b+=k[1]; a+=k[0] break; - case 11: c += ((uint32_t)k8[10])<<16; /*@fallthrough@*/ - case 10: c += ((uint32_t)k8[9])<<8; /*@fallthrough@*/ - case 9: c += k8[8]; /*@fallthrough@*/ - case 8: b += k[1]; a+=k[0]; break; - case 7: b += ((uint32_t)k8[6])<<16; /*@fallthrough@*/ - case 6: b += ((uint32_t)k8[5])<<8; /*@fallthrough@*/ - case 5: b += k8[4]; /*@fallthrough@*/ - case 4: a += k[0]; break; - case 3: a += ((uint32_t)k8[2])<<16; /*@fallthrough@*/ - case 2: a += ((uint32_t)k8[1])<<8; /*@fallthrough@*/ - case 1: a += k8[0]; break; - case 0: goto exit; - } - -#endif /* !valgrind */ - - } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { - const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ - const uint8_t *k8; - - /*----------- all but last block: aligned reads and different mixing */ - while (size > 12) { - a += k[0] + (((uint32_t)k[1])<<16); - b += k[2] + (((uint32_t)k[3])<<16); - c += k[4] + (((uint32_t)k[5])<<16); - _JLU3_MIX(a,b,c); - size -= 12; - k += 6; - } - - /*------------------------- handle the last (probably partial) block */ - k8 = (const uint8_t *)k; - switch (size) { - case 12: - c += k[4]+(((uint32_t)k[5])<<16); - b += k[2]+(((uint32_t)k[3])<<16); - a += k[0]+(((uint32_t)k[1])<<16); - break; - case 11: - c += ((uint32_t)k8[10])<<16; - /*@fallthrough@*/ - case 10: - c += (uint32_t)k[4]; - b += k[2]+(((uint32_t)k[3])<<16); - a += k[0]+(((uint32_t)k[1])<<16); - break; - case 9: - c += (uint32_t)k8[8]; - /*@fallthrough@*/ - case 8: - b += k[2]+(((uint32_t)k[3])<<16); - a += k[0]+(((uint32_t)k[1])<<16); - break; - case 7: - b += ((uint32_t)k8[6])<<16; - /*@fallthrough@*/ - case 6: - b += (uint32_t)k[2]; - a += k[0]+(((uint32_t)k[1])<<16); - break; - case 5: - b += (uint32_t)k8[4]; - /*@fallthrough@*/ - case 4: - a += k[0]+(((uint32_t)k[1])<<16); - break; - case 3: - a += ((uint32_t)k8[2])<<16; - /*@fallthrough@*/ - case 2: - a += (uint32_t)k[0]; - break; - case 1: - a += (uint32_t)k8[0]; - break; - case 0: - goto exit; - } - - } else { /* need to read the key one byte at a time */ - const uint8_t *k = (const uint8_t *)key; - - /*----------- all but the last block: affect some 32 bits of (a,b,c) */ - while (size > 12) { - a += (uint32_t)k[0]; - a += ((uint32_t)k[1])<<8; - a += ((uint32_t)k[2])<<16; - a += ((uint32_t)k[3])<<24; - b += (uint32_t)k[4]; - b += ((uint32_t)k[5])<<8; - b += ((uint32_t)k[6])<<16; - b += ((uint32_t)k[7])<<24; - c += (uint32_t)k[8]; - c += ((uint32_t)k[9])<<8; - c += ((uint32_t)k[10])<<16; - c += ((uint32_t)k[11])<<24; - _JLU3_MIX(a,b,c); - size -= 12; - k += 12; - } - - /*---------------------------- last block: affect all 32 bits of (c) */ - switch (size) { - case 12: c += ((uint32_t)k[11])<<24; /*@fallthrough@*/ - case 11: c += ((uint32_t)k[10])<<16; /*@fallthrough@*/ - case 10: c += ((uint32_t)k[9])<<8; /*@fallthrough@*/ - case 9: c += (uint32_t)k[8]; /*@fallthrough@*/ - case 8: b += ((uint32_t)k[7])<<24; /*@fallthrough@*/ - case 7: b += ((uint32_t)k[6])<<16; /*@fallthrough@*/ - case 6: b += ((uint32_t)k[5])<<8; /*@fallthrough@*/ - case 5: b += (uint32_t)k[4]; /*@fallthrough@*/ - case 4: a += ((uint32_t)k[3])<<24; /*@fallthrough@*/ - case 3: a += ((uint32_t)k[2])<<16; /*@fallthrough@*/ - case 2: a += ((uint32_t)k[1])<<8; /*@fallthrough@*/ - case 1: a += (uint32_t)k[0]; - break; - case 0: - goto exit; - } - } - - _JLU3_FINAL(a,b,c); - -exit: - return c; -} -#endif /* defined(_JLU3_jlu32l) */ - -#if defined(_JLU3_jlu32lpair) -/** - * jlu32lpair: return 2 32-bit hash values. - * - * This is identical to jlu32l(), except it returns two 32-bit hash - * values instead of just one. This is good enough for hash table - * lookup with 2^^64 buckets, or if you want a second hash if you're not - * happy with the first, or if you want a probably-unique 64-bit ID for - * the key. *pc is better mixed than *pb, so use *pc first. If you want - * a 64-bit value do something like "*pc + (((uint64_t)*pb)<<32)". - * - * @param h the previous hash, or an arbitrary value - * @param *key the key, an array of uint8_t values - * @param size the size of the key in bytes - * @retval *pc, IN: primary initval, OUT: primary hash - * *retval *pb IN: secondary initval, OUT: secondary hash - */ -void jlu32lpair(const void *key, size_t size, uint32_t *pc, uint32_t *pb) -{ - union { const void *ptr; size_t i; } u; - uint32_t a = _JLU3_INIT(*pc, size); - uint32_t b = a; - uint32_t c = a; - - if (key == NULL) - goto exit; - - c += *pb; /* Add the secondary hash. */ - - u.ptr = key; - if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { - const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ -#ifdef VALGRIND - const uint8_t *k8; -#endif - - /*-- all but last block: aligned reads and affect 32 bits of (a,b,c) */ - while (size > (size_t)12) { - a += k[0]; - b += k[1]; - c += k[2]; - _JLU3_MIX(a,b,c); - size -= 12; - k += 3; - } - /*------------------------- handle the last (probably partial) block */ - /* - * "k[2]&0xffffff" actually reads beyond the end of the string, but - * then masks off the part it's not allowed to read. Because the - * string is aligned, the masked-off tail is in the same word as the - * rest of the string. Every machine with memory protection I've seen - * does it on word boundaries, so is OK with this. But VALGRIND will - * still catch it and complain. The masking trick does make the hash - * noticably faster for short strings (like English words). - */ -#ifndef VALGRIND - - switch (size) { - case 12: c += k[2]; b+=k[1]; a+=k[0]; break; - case 11: c += k[2]&0xffffff; b+=k[1]; a+=k[0]; break; - case 10: c += k[2]&0xffff; b+=k[1]; a+=k[0]; break; - case 9: c += k[2]&0xff; b+=k[1]; a+=k[0]; break; - case 8: b += k[1]; a+=k[0]; break; - case 7: b += k[1]&0xffffff; a+=k[0]; break; - case 6: b += k[1]&0xffff; a+=k[0]; break; - case 5: b += k[1]&0xff; a+=k[0]; break; - case 4: a += k[0]; break; - case 3: a += k[0]&0xffffff; break; - case 2: a += k[0]&0xffff; break; - case 1: a += k[0]&0xff; break; - case 0: goto exit; - } - -#else /* make valgrind happy */ - - k8 = (const uint8_t *)k; - switch (size) { - case 12: c += k[2]; b+=k[1]; a+=k[0]; break; - case 11: c += ((uint32_t)k8[10])<<16; /*@fallthrough@*/ - case 10: c += ((uint32_t)k8[9])<<8; /*@fallthrough@*/ - case 9: c += k8[8]; /*@fallthrough@*/ - case 8: b += k[1]; a+=k[0]; break; - case 7: b += ((uint32_t)k8[6])<<16; /*@fallthrough@*/ - case 6: b += ((uint32_t)k8[5])<<8; /*@fallthrough@*/ - case 5: b += k8[4]; /*@fallthrough@*/ - case 4: a += k[0]; break; - case 3: a += ((uint32_t)k8[2])<<16; /*@fallthrough@*/ - case 2: a += ((uint32_t)k8[1])<<8; /*@fallthrough@*/ - case 1: a += k8[0]; break; - case 0: goto exit; - } - -#endif /* !valgrind */ - - } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { - const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ - const uint8_t *k8; - - /*----------- all but last block: aligned reads and different mixing */ - while (size > (size_t)12) { - a += k[0] + (((uint32_t)k[1])<<16); - b += k[2] + (((uint32_t)k[3])<<16); - c += k[4] + (((uint32_t)k[5])<<16); - _JLU3_MIX(a,b,c); - size -= 12; - k += 6; - } - - /*------------------------- handle the last (probably partial) block */ - k8 = (const uint8_t *)k; - switch (size) { - case 12: - c += k[4]+(((uint32_t)k[5])<<16); - b += k[2]+(((uint32_t)k[3])<<16); - a += k[0]+(((uint32_t)k[1])<<16); - break; - case 11: - c += ((uint32_t)k8[10])<<16; - /*@fallthrough@*/ - case 10: - c += k[4]; - b += k[2]+(((uint32_t)k[3])<<16); - a += k[0]+(((uint32_t)k[1])<<16); - break; - case 9: - c += k8[8]; - /*@fallthrough@*/ - case 8: - b += k[2]+(((uint32_t)k[3])<<16); - a += k[0]+(((uint32_t)k[1])<<16); - break; - case 7: - b += ((uint32_t)k8[6])<<16; - /*@fallthrough@*/ - case 6: - b += k[2]; - a += k[0]+(((uint32_t)k[1])<<16); - break; - case 5: - b += k8[4]; - /*@fallthrough@*/ - case 4: - a += k[0]+(((uint32_t)k[1])<<16); - break; - case 3: - a += ((uint32_t)k8[2])<<16; - /*@fallthrough@*/ - case 2: - a += k[0]; - break; - case 1: - a += k8[0]; - break; - case 0: - goto exit; - } - - } else { /* need to read the key one byte at a time */ - const uint8_t *k = (const uint8_t *)key; - - /*----------- all but the last block: affect some 32 bits of (a,b,c) */ - while (size > (size_t)12) { - a += k[0]; - a += ((uint32_t)k[1])<<8; - a += ((uint32_t)k[2])<<16; - a += ((uint32_t)k[3])<<24; - b += k[4]; - b += ((uint32_t)k[5])<<8; - b += ((uint32_t)k[6])<<16; - b += ((uint32_t)k[7])<<24; - c += k[8]; - c += ((uint32_t)k[9])<<8; - c += ((uint32_t)k[10])<<16; - c += ((uint32_t)k[11])<<24; - _JLU3_MIX(a,b,c); - size -= 12; - k += 12; - } - - /*---------------------------- last block: affect all 32 bits of (c) */ - switch (size) { - case 12: c += ((uint32_t)k[11])<<24; /*@fallthrough@*/ - case 11: c += ((uint32_t)k[10])<<16; /*@fallthrough@*/ - case 10: c += ((uint32_t)k[9])<<8; /*@fallthrough@*/ - case 9: c += k[8]; /*@fallthrough@*/ - case 8: b += ((uint32_t)k[7])<<24; /*@fallthrough@*/ - case 7: b += ((uint32_t)k[6])<<16; /*@fallthrough@*/ - case 6: b += ((uint32_t)k[5])<<8; /*@fallthrough@*/ - case 5: b += k[4]; /*@fallthrough@*/ - case 4: a += ((uint32_t)k[3])<<24; /*@fallthrough@*/ - case 3: a += ((uint32_t)k[2])<<16; /*@fallthrough@*/ - case 2: a += ((uint32_t)k[1])<<8; /*@fallthrough@*/ - case 1: a += k[0]; - break; - case 0: - goto exit; - } - } - - _JLU3_FINAL(a,b,c); - -exit: - *pc = c; - *pb = b; - return; -} -#endif /* defined(_JLU3_jlu32lpair) */ - -#if defined(_JLU3_jlu32b) -uint32_t jlu32b(uint32_t h, /*@null@*/ const void *key, size_t size) - /*@*/; -/* - * jlu32b(): - * This is the same as jlu32w() on big-endian machines. It is different - * from jlu32l() on all machines. jlu32b() takes advantage of - * big-endian byte ordering. - * - * @param h the previous hash, or an arbitrary value - * @param *k the key, an array of uint8_t values - * @param size the size of the key - * @return the lookup3 hash - */ -uint32_t jlu32b(uint32_t h, const void *key, size_t size) -{ - union { const void *ptr; size_t i; } u; - uint32_t a = _JLU3_INIT(h, size); - uint32_t b = a; - uint32_t c = a; - - if (key == NULL) - return h; - - u.ptr = key; - if (HASH_BIG_ENDIAN && ((u.i & 0x3) == 0)) { - const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ -#ifdef VALGRIND - const uint8_t *k8; -#endif - - /*-- all but last block: aligned reads and affect 32 bits of (a,b,c) */ - while (size > 12) { - a += k[0]; - b += k[1]; - c += k[2]; - _JLU3_MIX(a,b,c); - size -= 12; - k += 3; - } - - /*------------------------- handle the last (probably partial) block */ - /* - * "k[2]<<8" actually reads beyond the end of the string, but - * then shifts out the part it's not allowed to read. Because the - * string is aligned, the illegal read is in the same word as the - * rest of the string. Every machine with memory protection I've seen - * does it on word boundaries, so is OK with this. But VALGRIND will - * still catch it and complain. The masking trick does make the hash - * noticably faster for short strings (like English words). - */ -#ifndef VALGRIND - - switch (size) { - case 12: c += k[2]; b+=k[1]; a+=k[0]; break; - case 11: c += k[2]&0xffffff00; b+=k[1]; a+=k[0]; break; - case 10: c += k[2]&0xffff0000; b+=k[1]; a+=k[0]; break; - case 9: c += k[2]&0xff000000; b+=k[1]; a+=k[0]; break; - case 8: b += k[1]; a+=k[0]; break; - case 7: b += k[1]&0xffffff00; a+=k[0]; break; - case 6: b += k[1]&0xffff0000; a+=k[0]; break; - case 5: b += k[1]&0xff000000; a+=k[0]; break; - case 4: a += k[0]; break; - case 3: a += k[0]&0xffffff00; break; - case 2: a += k[0]&0xffff0000; break; - case 1: a += k[0]&0xff000000; break; - case 0: goto exit; - } - -#else /* make valgrind happy */ - - k8 = (const uint8_t *)k; - switch (size) { /* all the case statements fall through */ - case 12: c += k[2]; b+=k[1]; a+=k[0]; break; - case 11: c += ((uint32_t)k8[10])<<8; /*@fallthrough@*/ - case 10: c += ((uint32_t)k8[9])<<16; /*@fallthrough@*/ - case 9: c += ((uint32_t)k8[8])<<24; /*@fallthrough@*/ - case 8: b += k[1]; a+=k[0]; break; - case 7: b += ((uint32_t)k8[6])<<8; /*@fallthrough@*/ - case 6: b += ((uint32_t)k8[5])<<16; /*@fallthrough@*/ - case 5: b += ((uint32_t)k8[4])<<24; /*@fallthrough@*/ - case 4: a += k[0]; break; - case 3: a += ((uint32_t)k8[2])<<8; /*@fallthrough@*/ - case 2: a += ((uint32_t)k8[1])<<16; /*@fallthrough@*/ - case 1: a += ((uint32_t)k8[0])<<24; break; - case 0: goto exit; - } - -#endif /* !VALGRIND */ - - } else { /* need to read the key one byte at a time */ - const uint8_t *k = (const uint8_t *)key; - - /*----------- all but the last block: affect some 32 bits of (a,b,c) */ - while (size > 12) { - a += ((uint32_t)k[0])<<24; - a += ((uint32_t)k[1])<<16; - a += ((uint32_t)k[2])<<8; - a += ((uint32_t)k[3]); - b += ((uint32_t)k[4])<<24; - b += ((uint32_t)k[5])<<16; - b += ((uint32_t)k[6])<<8; - b += ((uint32_t)k[7]); - c += ((uint32_t)k[8])<<24; - c += ((uint32_t)k[9])<<16; - c += ((uint32_t)k[10])<<8; - c += ((uint32_t)k[11]); - _JLU3_MIX(a,b,c); - size -= 12; - k += 12; - } - - /*---------------------------- last block: affect all 32 bits of (c) */ - switch (size) { /* all the case statements fall through */ - case 12: c += k[11]; /*@fallthrough@*/ - case 11: c += ((uint32_t)k[10])<<8; /*@fallthrough@*/ - case 10: c += ((uint32_t)k[9])<<16; /*@fallthrough@*/ - case 9: c += ((uint32_t)k[8])<<24; /*@fallthrough@*/ - case 8: b += k[7]; /*@fallthrough@*/ - case 7: b += ((uint32_t)k[6])<<8; /*@fallthrough@*/ - case 6: b += ((uint32_t)k[5])<<16; /*@fallthrough@*/ - case 5: b += ((uint32_t)k[4])<<24; /*@fallthrough@*/ - case 4: a += k[3]; /*@fallthrough@*/ - case 3: a += ((uint32_t)k[2])<<8; /*@fallthrough@*/ - case 2: a += ((uint32_t)k[1])<<16; /*@fallthrough@*/ - case 1: a += ((uint32_t)k[0])<<24; /*@fallthrough@*/ - break; - case 0: - goto exit; - } - } - - _JLU3_FINAL(a,b,c); - -exit: - return c; -} -#endif /* defined(_JLU3_jlu32b) */ - -#if defined(_JLU3_SELFTEST) - -/* used for timings */ -static void driver1(void) - /*@*/ -{ - uint8_t buf[256]; - uint32_t i; - uint32_t h=0; - time_t a,z; - - time(&a); - for (i=0; i<256; ++i) buf[i] = 'x'; - for (i=0; i<1; ++i) { - h = jlu32l(h, &buf[0], sizeof(buf[0])); - } - time(&z); - if (z-a > 0) printf("time %d %.8x\n", (int)(z-a), h); -} - -/* check that every input bit changes every output bit half the time */ -#define HASHSTATE 1 -#define HASHLEN 1 -#define MAXPAIR 60 -#define MAXLEN 70 -static void driver2(void) - /*@*/ -{ - uint8_t qa[MAXLEN+1], qb[MAXLEN+2], *a = &qa[0], *b = &qb[1]; - uint32_t c[HASHSTATE], d[HASHSTATE], i=0, j=0, k, l, m=0, z; - uint32_t e[HASHSTATE],f[HASHSTATE],g[HASHSTATE],h[HASHSTATE]; - uint32_t x[HASHSTATE],y[HASHSTATE]; - uint32_t hlen; - - printf("No more than %d trials should ever be needed \n",MAXPAIR/2); - for (hlen=0; hlen < MAXLEN; ++hlen) { - z=0; - for (i=0; i>(8-j)); - c[0] = jlu32l(m, a, hlen); - b[i] ^= ((k+1)<>(8-j)); - d[0] = jlu32l(m, b, hlen); - /* check every bit is 1, 0, set, and not set at least once */ - for (l=0; lz) z=k; - if (k == MAXPAIR) { - printf("Some bit didn't change: "); - printf("%.8x %.8x %.8x %.8x %.8x %.8x ", - e[0],f[0],g[0],h[0],x[0],y[0]); - printf("i %d j %d m %d len %d\n", i, j, m, hlen); - } - if (z == MAXPAIR) goto done; - } - } - } - done: - if (z < MAXPAIR) { - printf("Mix success %2d bytes %2d initvals ",i,m); - printf("required %d trials\n", z/2); - } - } - printf("\n"); -} - -/* Check for reading beyond the end of the buffer and alignment problems */ -static void driver3(void) - /*@*/ -{ - uint8_t buf[MAXLEN+20], *b; - uint32_t len; - uint8_t q[] = "This is the time for all good men to come to the aid of their country..."; - uint32_t h; - uint8_t qq[] = "xThis is the time for all good men to come to the aid of their country..."; - uint32_t i; - uint8_t qqq[] = "xxThis is the time for all good men to come to the aid of their country..."; - uint32_t j; - uint8_t qqqq[] = "xxxThis is the time for all good men to come to the aid of their country..."; - uint32_t ref,x,y; - uint8_t *p; - uint32_t m = 13; - - printf("Endianness. These lines should all be the same (for values filled in):\n"); - printf("%.8x %.8x %.8x\n", - jlu32w(m, (const uint32_t *)q, (sizeof(q)-1)/4), - jlu32w(m, (const uint32_t *)q, (sizeof(q)-5)/4), - jlu32w(m, (const uint32_t *)q, (sizeof(q)-9)/4)); - p = q; - printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", - jlu32l(m, p, sizeof(q)-1), jlu32l(m, p, sizeof(q)-2), - jlu32l(m, p, sizeof(q)-3), jlu32l(m, p, sizeof(q)-4), - jlu32l(m, p, sizeof(q)-5), jlu32l(m, p, sizeof(q)-6), - jlu32l(m, p, sizeof(q)-7), jlu32l(m, p, sizeof(q)-8), - jlu32l(m, p, sizeof(q)-9), jlu32l(m, p, sizeof(q)-10), - jlu32l(m, p, sizeof(q)-11), jlu32l(m, p, sizeof(q)-12)); - p = &qq[1]; - printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", - jlu32l(m, p, sizeof(q)-1), jlu32l(m, p, sizeof(q)-2), - jlu32l(m, p, sizeof(q)-3), jlu32l(m, p, sizeof(q)-4), - jlu32l(m, p, sizeof(q)-5), jlu32l(m, p, sizeof(q)-6), - jlu32l(m, p, sizeof(q)-7), jlu32l(m, p, sizeof(q)-8), - jlu32l(m, p, sizeof(q)-9), jlu32l(m, p, sizeof(q)-10), - jlu32l(m, p, sizeof(q)-11), jlu32l(m, p, sizeof(q)-12)); - p = &qqq[2]; - printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", - jlu32l(m, p, sizeof(q)-1), jlu32l(m, p, sizeof(q)-2), - jlu32l(m, p, sizeof(q)-3), jlu32l(m, p, sizeof(q)-4), - jlu32l(m, p, sizeof(q)-5), jlu32l(m, p, sizeof(q)-6), - jlu32l(m, p, sizeof(q)-7), jlu32l(m, p, sizeof(q)-8), - jlu32l(m, p, sizeof(q)-9), jlu32l(m, p, sizeof(q)-10), - jlu32l(m, p, sizeof(q)-11), jlu32l(m, p, sizeof(q)-12)); - p = &qqqq[3]; - printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n", - jlu32l(m, p, sizeof(q)-1), jlu32l(m, p, sizeof(q)-2), - jlu32l(m, p, sizeof(q)-3), jlu32l(m, p, sizeof(q)-4), - jlu32l(m, p, sizeof(q)-5), jlu32l(m, p, sizeof(q)-6), - jlu32l(m, p, sizeof(q)-7), jlu32l(m, p, sizeof(q)-8), - jlu32l(m, p, sizeof(q)-9), jlu32l(m, p, sizeof(q)-10), - jlu32l(m, p, sizeof(q)-11), jlu32l(m, p, sizeof(q)-12)); - printf("\n"); - for (h=0, b=buf+1; h<8; ++h, ++b) { - for (i=0; i -#endif -#include - -#include "poptint.h" - -#ifdef MYDEBUG -/*@unchecked@*/ -int _popt_debug = 0; -#endif - -/*@unchecked@*/ -unsigned int _poptArgMask = POPT_ARG_MASK; -/*@unchecked@*/ -unsigned int _poptGroupMask = POPT_GROUP_MASK; - -#if !defined(HAVE_STRERROR) && !defined(__LCLINT__) -static char * strerror(int errno) -{ - extern int sys_nerr; - extern char * sys_errlist[]; - - if ((0 <= errno) && (errno < sys_nerr)) - return sys_errlist[errno]; - else - return POPT_("unknown errno"); -} -#endif - -#ifdef MYDEBUG -/*@unused@*/ -static void prtcon(const char *msg, poptContext con) -{ - if (msg) fprintf(stderr, "%s", msg); - fprintf(stderr, "\tcon %p os %p nextCharArg \"%s\" nextArg \"%s\" argv[%d] \"%s\"\n", - con, con->os, - (con->os->nextCharArg ? con->os->nextCharArg : ""), - (con->os->nextArg ? con->os->nextArg : ""), - con->os->next, - (con->os->argv && con->os->argv[con->os->next] - ? con->os->argv[con->os->next] : "")); -} -#endif - -void poptSetExecPath(poptContext con, const char * path, int allowAbsolute) -{ - con->execPath = _free(con->execPath); - con->execPath = xstrdup(path); - con->execAbsolute = allowAbsolute; - return; -} - -static void invokeCallbacksPRE(poptContext con, const struct poptOption * opt) - /*@globals internalState@*/ - /*@modifies internalState@*/ -{ - if (opt != NULL) - for (; opt->longName || opt->shortName || opt->arg; opt++) { - poptArg arg = { .ptr = opt->arg }; - if (arg.ptr) - switch (poptArgType(opt)) { - case POPT_ARG_INCLUDE_TABLE: /* Recurse on included sub-tables. */ - poptSubstituteHelpI18N(arg.opt); /* XXX side effects */ - invokeCallbacksPRE(con, arg.opt); - /*@switchbreak@*/ break; - case POPT_ARG_CALLBACK: /* Perform callback. */ - if (!CBF_ISSET(opt, PRE)) - /*@switchbreak@*/ break; -/*@-noeffectuncon @*/ /* XXX no known way to annotate (*vector) calls. */ - arg.cb(con, POPT_CALLBACK_REASON_PRE, NULL, NULL, opt->descrip); -/*@=noeffectuncon @*/ - /*@switchbreak@*/ break; - } - } -} - -static void invokeCallbacksPOST(poptContext con, const struct poptOption * opt) - /*@globals internalState@*/ - /*@modifies internalState@*/ -{ - if (opt != NULL) - for (; opt->longName || opt->shortName || opt->arg; opt++) { - poptArg arg = { .ptr = opt->arg }; - if (arg.ptr) - switch (poptArgType(opt)) { - case POPT_ARG_INCLUDE_TABLE: /* Recurse on included sub-tables. */ - poptSubstituteHelpI18N(arg.opt); /* XXX side effects */ - invokeCallbacksPOST(con, arg.opt); - /*@switchbreak@*/ break; - case POPT_ARG_CALLBACK: /* Perform callback. */ - if (!CBF_ISSET(opt, POST)) - /*@switchbreak@*/ break; -/*@-noeffectuncon @*/ /* XXX no known way to annotate (*vector) calls. */ - arg.cb(con, POPT_CALLBACK_REASON_POST, NULL, NULL, opt->descrip); -/*@=noeffectuncon @*/ - /*@switchbreak@*/ break; - } - } -} - -static void invokeCallbacksOPTION(poptContext con, - const struct poptOption * opt, - const struct poptOption * myOpt, - /*@null@*/ const void * myData, int shorty) - /*@globals internalState@*/ - /*@modifies internalState@*/ -{ - const struct poptOption * cbopt = NULL; - poptArg cbarg = { .ptr = NULL }; - - if (opt != NULL) - for (; opt->longName || opt->shortName || opt->arg; opt++) { - poptArg arg = { .ptr = opt->arg }; - switch (poptArgType(opt)) { - case POPT_ARG_INCLUDE_TABLE: /* Recurse on included sub-tables. */ - poptSubstituteHelpI18N(arg.opt); /* XXX side effects */ - if (opt->arg != NULL) - invokeCallbacksOPTION(con, opt->arg, myOpt, myData, shorty); - /*@switchbreak@*/ break; - case POPT_ARG_CALLBACK: /* Save callback info. */ - if (CBF_ISSET(opt, SKIPOPTION)) - /*@switchbreak@*/ break; - cbopt = opt; - cbarg.ptr = opt->arg; - /*@switchbreak@*/ break; - default: /* Perform callback on matching option. */ - if (cbopt == NULL || cbarg.cb == NULL) - /*@switchbreak@*/ break; - if ((myOpt->shortName && opt->shortName && shorty && - myOpt->shortName == opt->shortName) - || (myOpt->longName != NULL && opt->longName != NULL && - !strcmp(myOpt->longName, opt->longName))) - { const void *cbData = (cbopt->descrip ? cbopt->descrip : myData); -/*@-noeffectuncon @*/ /* XXX no known way to annotate (*vector) calls. */ - cbarg.cb(con, POPT_CALLBACK_REASON_OPTION, - myOpt, con->os->nextArg, cbData); -/*@=noeffectuncon @*/ - /* Terminate (unless explcitly continuing). */ - if (!CBF_ISSET(cbopt, CONTINUE)) - return; - } - /*@switchbreak@*/ break; - } - } -} - -poptContext poptGetContext(const char * name, int argc, const char ** argv, - const struct poptOption * options, unsigned int flags) -{ - poptContext con = malloc(sizeof(*con)); - - if (con == NULL) return NULL; /* XXX can't happen */ - memset(con, 0, sizeof(*con)); - - con->os = con->optionStack; - con->os->argc = argc; -/*@-dependenttrans -assignexpose@*/ /* FIX: W2DO? */ - con->os->argv = argv; -/*@=dependenttrans =assignexpose@*/ - con->os->argb = NULL; - - if (!(flags & POPT_CONTEXT_KEEP_FIRST)) - con->os->next = 1; /* skip argv[0] */ - - con->leftovers = calloc( (size_t)(argc + 1), sizeof(*con->leftovers) ); -/*@-dependenttrans -assignexpose@*/ /* FIX: W2DO? */ - con->options = options; -/*@=dependenttrans =assignexpose@*/ - con->aliases = NULL; - con->numAliases = 0; - con->flags = flags; - con->execs = NULL; - con->numExecs = 0; - con->finalArgvAlloced = argc * 2; - con->finalArgv = calloc( (size_t)con->finalArgvAlloced, sizeof(*con->finalArgv) ); - con->execAbsolute = 1; - con->arg_strip = NULL; - - if (getenv("POSIXLY_CORRECT") || getenv("POSIX_ME_HARDER")) - con->flags |= POPT_CONTEXT_POSIXMEHARDER; - - if (name) - con->appName = xstrdup(name); - - invokeCallbacksPRE(con, con->options); - - return con; -} - -static void cleanOSE(/*@special@*/ struct optionStackEntry *os) - /*@uses os @*/ - /*@releases os->nextArg, os->argv, os->argb @*/ - /*@modifies os @*/ -{ - os->nextArg = _free(os->nextArg); - os->argv = _free(os->argv); - os->argb = PBM_FREE(os->argb); -} - -void poptResetContext(poptContext con) -{ - int i; - - if (con == NULL) return; - while (con->os > con->optionStack) { - cleanOSE(con->os--); - } - con->os->argb = PBM_FREE(con->os->argb); - con->os->currAlias = NULL; - con->os->nextCharArg = NULL; - con->os->nextArg = NULL; - con->os->next = 1; /* skip argv[0] */ - - con->numLeftovers = 0; - con->nextLeftover = 0; - con->restLeftover = 0; - con->doExec = NULL; - - if (con->finalArgv != NULL) - for (i = 0; i < con->finalArgvCount; i++) { -/*@-unqualifiedtrans@*/ /* FIX: typedef double indirection. */ - con->finalArgv[i] = _free(con->finalArgv[i]); -/*@=unqualifiedtrans@*/ - } - - con->finalArgvCount = 0; - con->arg_strip = PBM_FREE(con->arg_strip); -/*@-nullstate@*/ /* FIX: con->finalArgv != NULL */ - return; -/*@=nullstate@*/ -} - -/* Only one of longName, shortName should be set, not both. */ -static int handleExec(/*@special@*/ poptContext con, - /*@null@*/ const char * longName, char shortName) - /*@uses con->execs, con->numExecs, con->flags, con->doExec, - con->finalArgv, con->finalArgvAlloced, con->finalArgvCount @*/ - /*@modifies con @*/ -{ - poptItem item; - int i; - - if (con->execs == NULL || con->numExecs <= 0) /* XXX can't happen */ - return 0; - - for (i = con->numExecs - 1; i >= 0; i--) { - item = con->execs + i; - if (longName && !(item->option.longName && - !strcmp(longName, item->option.longName))) - continue; - else if (shortName != item->option.shortName) - continue; - break; - } - if (i < 0) return 0; - - - if (con->flags & POPT_CONTEXT_NO_EXEC) - return 1; - - if (con->doExec == NULL) { - con->doExec = con->execs + i; - return 1; - } - - /* We already have an exec to do; remember this option for next - time 'round */ - if ((con->finalArgvCount + 1) >= (con->finalArgvAlloced)) { - con->finalArgvAlloced += 10; - con->finalArgv = realloc(con->finalArgv, - sizeof(*con->finalArgv) * con->finalArgvAlloced); - } - - i = con->finalArgvCount++; - if (con->finalArgv != NULL) /* XXX can't happen */ - { char *s = malloc((longName ? strlen(longName) : 0) + sizeof("--")); - if (s != NULL) { /* XXX can't happen */ - con->finalArgv[i] = s; - *s++ = '-'; - if (longName) - s = stpcpy( stpcpy(s, "-"), longName); - else - *s++ = shortName; - *s = '\0'; - } else - con->finalArgv[i] = NULL; - } - - return 1; -} - -/** - * Compare long option for equality, adjusting for POPT_ARGFLAG_TOGGLE. - * @param opt option - * @param longName arg option - * @param longNameLen arg option length - * @return does long option match? - */ -static int -longOptionStrcmp(const struct poptOption * opt, - /*@null@*/ const char * longName, size_t longNameLen) - /*@*/ -{ - const char * optLongName = opt->longName; - int rc; - - if (optLongName == NULL || longName == NULL) /* XXX can't heppen */ - return 0; - - if (F_ISSET(opt, TOGGLE)) { - if (optLongName[0] == 'n' && optLongName[1] == 'o') { - optLongName += sizeof("no") - 1; - if (optLongName[0] == '-') - optLongName++; - } - if (longName[0] == 'n' && longName[1] == 'o') { - longName += sizeof("no") - 1; - longNameLen -= sizeof("no") - 1; - if (longName[0] == '-') { - longName++; - longNameLen--; - } - } - } - rc = (int)(strlen(optLongName) == longNameLen); - if (rc) - rc = (int)(strncmp(optLongName, longName, longNameLen) == 0); - return rc; -} - -/* Only one of longName, shortName may be set at a time */ -static int handleAlias(/*@special@*/ poptContext con, - /*@null@*/ const char * longName, size_t longNameLen, - char shortName, - /*@exposed@*/ /*@null@*/ const char * nextArg) - /*@uses con->aliases, con->numAliases, con->optionStack, con->os, - con->os->currAlias, con->os->currAlias->option.longName @*/ - /*@modifies con @*/ -{ - poptItem item = con->os->currAlias; - int rc; - int i; - - if (item) { - if (longName && item->option.longName != NULL - && longOptionStrcmp(&item->option, longName, longNameLen)) - return 0; - else - if (shortName && shortName == item->option.shortName) - return 0; - } - - if (con->aliases == NULL || con->numAliases <= 0) /* XXX can't happen */ - return 0; - - for (i = con->numAliases - 1; i >= 0; i--) { - item = con->aliases + i; - if (longName) { - if (item->option.longName == NULL) - continue; - if (!longOptionStrcmp(&item->option, longName, longNameLen)) - continue; - } else if (shortName != item->option.shortName) - continue; - break; - } - if (i < 0) return 0; - - if ((con->os - con->optionStack + 1) == POPT_OPTION_DEPTH) - return POPT_ERROR_OPTSTOODEEP; - - if (longName == NULL && nextArg != NULL && *nextArg != '\0') - con->os->nextCharArg = nextArg; - - con->os++; - con->os->next = 0; - con->os->stuffed = 0; - con->os->nextArg = NULL; - con->os->nextCharArg = NULL; - con->os->currAlias = con->aliases + i; - { const char ** av; - int ac = con->os->currAlias->argc; - /* Append --foo=bar arg to alias argv array (if present). */ - if (longName && nextArg != NULL && *nextArg != '\0') { - av = malloc((ac + 1 + 1) * sizeof(*av)); - if (av != NULL) { /* XXX won't happen. */ - for (i = 0; i < ac; i++) { - av[i] = con->os->currAlias->argv[i]; - } - av[ac++] = nextArg; - av[ac] = NULL; - } else /* XXX revert to old popt behavior if malloc fails. */ - av = con->os->currAlias->argv; - } else - av = con->os->currAlias->argv; - rc = poptDupArgv(ac, av, &con->os->argc, &con->os->argv); - if (av != NULL && av != con->os->currAlias->argv) - free(av); - } - con->os->argb = NULL; - - return (rc ? rc : 1); -} - -/** - * Return absolute path to executable by searching PATH. - * @param argv0 name of executable - * @return (malloc'd) absolute path to executable (or NULL) - */ -static /*@null@*/ -const char * findProgramPath(/*@null@*/ const char * argv0) - /*@*/ -{ - char *path = NULL, *s = NULL, *se; - char *t = NULL; - - if (argv0 == NULL) return NULL; /* XXX can't happen */ - - /* If there is a / in argv[0], it has to be an absolute path. */ - /* XXX Hmmm, why not if (argv0[0] == '/') ... instead? */ - if (strchr(argv0, '/')) - return xstrdup(argv0); - - if ((path = getenv("PATH")) == NULL || (path = xstrdup(path)) == NULL) - return NULL; - - /* The return buffer in t is big enough for any path. */ - if ((t = malloc(strlen(path) + strlen(argv0) + sizeof("/"))) != NULL) - for (s = path; s && *s; s = se) { - - /* Snip PATH element into [s,se). */ - if ((se = strchr(s, ':'))) - *se++ = '\0'; - - /* Append argv0 to PATH element. */ - (void) stpcpy(stpcpy(stpcpy(t, s), "/"), argv0); - - /* If file is executable, bingo! */ - if (!access(t, X_OK)) - break; - } - - /* If no executable was found in PATH, return NULL. */ -/*@-compdef@*/ - if (!(s && *s) && t != NULL) - t = _free(t); -/*@=compdef@*/ -/*@-modobserver -observertrans -usedef @*/ - path = _free(path); -/*@=modobserver =observertrans =usedef @*/ - - return t; -} - -static int execCommand(poptContext con) - /*@globals internalState @*/ - /*@modifies internalState @*/ -{ - poptItem item = con->doExec; - poptArgv argv = NULL; - int argc = 0; - int rc; - int ec = POPT_ERROR_ERRNO; - - if (item == NULL) /*XXX can't happen*/ - return POPT_ERROR_NOARG; - - if (item->argv == NULL || item->argc < 1 || - (!con->execAbsolute && strchr(item->argv[0], '/'))) - return POPT_ERROR_NOARG; - - argv = malloc(sizeof(*argv) * - (6 + item->argc + con->numLeftovers + con->finalArgvCount)); - if (argv == NULL) return POPT_ERROR_MALLOC; - - if (!strchr(item->argv[0], '/') && con->execPath != NULL) { - char *s = malloc(strlen(con->execPath) + strlen(item->argv[0]) + sizeof("/")); - if (s) - (void)stpcpy(stpcpy(stpcpy(s, con->execPath), "/"), item->argv[0]); - - argv[argc] = s; - } else - argv[argc] = findProgramPath(item->argv[0]); - if (argv[argc++] == NULL) { - ec = POPT_ERROR_NOARG; - goto exit; - } - - if (item->argc > 1) { - memcpy(argv + argc, item->argv + 1, sizeof(*argv) * (item->argc - 1)); - argc += (item->argc - 1); - } - - if (con->finalArgv != NULL && con->finalArgvCount > 0) { - memcpy(argv + argc, con->finalArgv, - sizeof(*argv) * con->finalArgvCount); - argc += con->finalArgvCount; - } - - if (con->leftovers != NULL && con->numLeftovers > 0) { - memcpy(argv + argc, con->leftovers, sizeof(*argv) * con->numLeftovers); - argc += con->numLeftovers; - } - - argv[argc] = NULL; - -#if defined(hpux) || defined(__hpux) - rc = setresgid(getgid(), getgid(),-1); - if (rc) goto exit; - rc = setresuid(getuid(), getuid(),-1); - if (rc) goto exit; -#else -/* - * XXX " ... on BSD systems setuid() should be preferred over setreuid()" - * XXX sez' Timur Bakeyev - * XXX from Norbert Warmuth - */ -#if defined(HAVE_SETUID) - rc = setgid(getgid()); - if (rc) goto exit; - rc = setuid(getuid()); - if (rc) goto exit; -#elif defined (HAVE_SETREUID) - rc = setregid(getgid(), getgid()); - if (rc) goto exit; - rc = setreuid(getuid(), getuid()); - if (rc) goto exit; -#else - ; /* Can't drop privileges */ -#endif -#endif - -#ifdef MYDEBUG -if (_popt_debug) - { poptArgv avp; - fprintf(stderr, "==> execvp(%s) argv[%d]:", argv[0], argc); - for (avp = argv; *avp; avp++) - fprintf(stderr, " '%s'", *avp); - fprintf(stderr, "\n"); - } -#endif - -/*@-nullstate@*/ - rc = execvp(argv[0], (char *const *)argv); -/*@=nullstate@*/ - -exit: - if (argv) { - if (argv[0]) - free((void *)argv[0]); - free(argv); - } - return ec; -} - -/*@observer@*/ /*@null@*/ -static const struct poptOption * -findOption(const struct poptOption * opt, - /*@null@*/ const char * longName, size_t longNameLen, - char shortName, - /*@null@*/ /*@out@*/ poptCallbackType * callback, - /*@null@*/ /*@out@*/ const void ** callbackData, - unsigned int argInfo) - /*@modifies *callback, *callbackData */ -{ - const struct poptOption * cb = NULL; - poptArg cbarg = { .ptr = NULL }; - - /* This happens when a single - is given */ - if (LF_ISSET(ONEDASH) && !shortName && (longName && *longName == '\0')) - shortName = '-'; - - for (; opt->longName || opt->shortName || opt->arg; opt++) { - poptArg arg = { .ptr = opt->arg }; - - switch (poptArgType(opt)) { - case POPT_ARG_INCLUDE_TABLE: /* Recurse on included sub-tables. */ - { const struct poptOption * opt2; - - poptSubstituteHelpI18N(arg.opt); /* XXX side effects */ - if (arg.ptr == NULL) continue; /* XXX program error */ - opt2 = findOption(arg.opt, longName, longNameLen, shortName, callback, - callbackData, argInfo); - if (opt2 == NULL) continue; - /* Sub-table data will be inheirited if no data yet. */ -/*@-observertrans -dependenttrans @*/ - if (callback && *callback - && callbackData && *callbackData == NULL) - *callbackData = opt->descrip; -/*@=observertrans =dependenttrans @*/ - return opt2; - } /*@notreached@*/ /*@switchbreak@*/ break; - case POPT_ARG_CALLBACK: - cb = opt; - cbarg.ptr = opt->arg; - continue; - /*@notreached@*/ /*@switchbreak@*/ break; - default: - /*@switchbreak@*/ break; - } - - if (longName != NULL && opt->longName != NULL && - (!LF_ISSET(ONEDASH) || F_ISSET(opt, ONEDASH)) && - longOptionStrcmp(opt, longName, longNameLen)) - { - break; - } else if (shortName && shortName == opt->shortName) { - break; - } - } - - if (opt->longName == NULL && !opt->shortName) - return NULL; - -/*@-modobserver -mods @*/ - if (callback) - *callback = (cb ? cbarg.cb : NULL); - if (callbackData) -/*@-observertrans -dependenttrans @*/ - *callbackData = (cb && !CBF_ISSET(cb, INC_DATA) ? cb->descrip : NULL); -/*@=observertrans =dependenttrans @*/ -/*@=modobserver =mods @*/ - - return opt; -} - -static const char * findNextArg(/*@special@*/ poptContext con, - unsigned argx, int delete_arg) - /*@uses con->optionStack, con->os, - con->os->next, con->os->argb, con->os->argc, con->os->argv @*/ - /*@modifies con @*/ -{ - struct optionStackEntry * os = con->os; - const char * arg; - - do { - int i; - arg = NULL; - while (os->next == os->argc && os > con->optionStack) os--; - if (os->next == os->argc && os == con->optionStack) break; - if (os->argv != NULL) - for (i = os->next; i < os->argc; i++) { -/*@-sizeoftype@*/ - if (os->argb && PBM_ISSET(i, os->argb)) - /*@innercontinue@*/ continue; - if (*os->argv[i] == '-') - /*@innercontinue@*/ continue; - if (--argx > 0) - /*@innercontinue@*/ continue; - arg = os->argv[i]; - if (delete_arg) { - if (os->argb == NULL) os->argb = PBM_ALLOC(os->argc); - if (os->argb != NULL) /* XXX can't happen */ - PBM_SET(i, os->argb); - } - /*@innerbreak@*/ break; -/*@=sizeoftype@*/ - } - if (os > con->optionStack) os--; - } while (arg == NULL); - return arg; -} - -static /*@only@*/ /*@null@*/ const char * -expandNextArg(/*@special@*/ poptContext con, const char * s) - /*@uses con->optionStack, con->os, - con->os->next, con->os->argb, con->os->argc, con->os->argv @*/ - /*@modifies con @*/ -{ - const char * a = NULL; - char *t, *te; - size_t tn = strlen(s) + 1; - char c; - - te = t = malloc(tn); - if (t == NULL) return NULL; /* XXX can't happen */ - *t = '\0'; - while ((c = *s++) != '\0') { - switch (c) { -#if 0 /* XXX can't do this */ - case '\\': /* escape */ - c = *s++; - /*@switchbreak@*/ break; -#endif - case '!': - if (!(s[0] == '#' && s[1] == ':' && s[2] == '+')) - /*@switchbreak@*/ break; - /* XXX Make sure that findNextArg deletes only next arg. */ - if (a == NULL) { - if ((a = findNextArg(con, 1U, 1)) == NULL) - /*@switchbreak@*/ break; - } - s += sizeof("#:+") - 1; - - tn += strlen(a); - { size_t pos = (size_t) (te - t); - if ((t = realloc(t, tn)) == NULL) /* XXX can't happen */ - return NULL; - te = stpcpy(t + pos, a); - } - continue; - /*@notreached@*/ /*@switchbreak@*/ break; - default: - /*@switchbreak@*/ break; - } - *te++ = c; - } - *te++ = '\0'; - /* If the new string is longer than needed, shorten. */ - if ((t + tn) > te) { -/*@-usereleased@*/ /* XXX splint can't follow the pointers. */ - if ((te = realloc(t, (size_t)(te - t))) == NULL) - free(t); - t = te; -/*@=usereleased@*/ - } - return t; -} - -static void poptStripArg(/*@special@*/ poptContext con, int which) - /*@uses con->optionStack @*/ - /*@defines con->arg_strip @*/ - /*@modifies con @*/ -{ -/*@-compdef -sizeoftype -usedef @*/ - if (con->arg_strip == NULL) - con->arg_strip = PBM_ALLOC(con->optionStack[0].argc); - if (con->arg_strip != NULL) /* XXX can't happen */ - PBM_SET(which, con->arg_strip); - return; -/*@=compdef =sizeoftype =usedef @*/ -} - -/*@unchecked@*/ -unsigned int _poptBitsN = _POPT_BITS_N; -/*@unchecked@*/ -unsigned int _poptBitsM = _POPT_BITS_M; -/*@unchecked@*/ -unsigned int _poptBitsK = _POPT_BITS_K; - -/*@-sizeoftype@*/ -static int _poptBitsNew(/*@null@*/ poptBits *bitsp) - /*@globals _poptBitsN, _poptBitsM, _poptBitsK @*/ - /*@modifies *bitsp, _poptBitsN, _poptBitsM, _poptBitsK @*/ -{ - if (bitsp == NULL) - return POPT_ERROR_NULLARG; - - /* XXX handle negated initialization. */ - if (*bitsp == NULL) { - if (_poptBitsN == 0) { - _poptBitsN = _POPT_BITS_N; - _poptBitsM = _POPT_BITS_M; - } - if (_poptBitsM == 0U) _poptBitsM = (3 * _poptBitsN) / 2; - if (_poptBitsK == 0U || _poptBitsK > 32U) _poptBitsK = _POPT_BITS_K; - *bitsp = PBM_ALLOC(_poptBitsM-1); - } -/*@-nullstate@*/ - return 0; -/*@=nullstate@*/ -} - -int poptBitsAdd(poptBits bits, const char * s) -{ - size_t ns = (s ? strlen(s) : 0); - uint32_t h0 = 0; - uint32_t h1 = 0; - - if (bits == NULL || ns == 0) - return POPT_ERROR_NULLARG; - - poptJlu32lpair(s, ns, &h0, &h1); - - for (ns = 0; ns < (size_t)_poptBitsK; ns++) { - uint32_t h = h0 + ns * h1; - uint32_t ix = (h % _poptBitsM); - PBM_SET(ix, bits); - } - return 0; -} - -int poptBitsChk(poptBits bits, const char * s) -{ - size_t ns = (s ? strlen(s) : 0); - uint32_t h0 = 0; - uint32_t h1 = 0; - int rc = 1; - - if (bits == NULL || ns == 0) - return POPT_ERROR_NULLARG; - - poptJlu32lpair(s, ns, &h0, &h1); - - for (ns = 0; ns < (size_t)_poptBitsK; ns++) { - uint32_t h = h0 + ns * h1; - uint32_t ix = (h % _poptBitsM); - if (PBM_ISSET(ix, bits)) - continue; - rc = 0; - break; - } - return rc; -} - -int poptBitsClr(poptBits bits) -{ - static size_t nbw = (__PBM_NBITS/8); - size_t nw = (__PBM_IX(_poptBitsM-1) + 1); - - if (bits == NULL) - return POPT_ERROR_NULLARG; - memset(bits, 0, nw * nbw); - return 0; -} - -int poptBitsDel(poptBits bits, const char * s) -{ - size_t ns = (s ? strlen(s) : 0); - uint32_t h0 = 0; - uint32_t h1 = 0; - - if (bits == NULL || ns == 0) - return POPT_ERROR_NULLARG; - - poptJlu32lpair(s, ns, &h0, &h1); - - for (ns = 0; ns < (size_t)_poptBitsK; ns++) { - uint32_t h = h0 + ns * h1; - uint32_t ix = (h % _poptBitsM); - PBM_CLR(ix, bits); - } - return 0; -} - -int poptBitsIntersect(poptBits *ap, const poptBits b) -{ - __pbm_bits *abits; - __pbm_bits *bbits; - __pbm_bits rc = 0; - size_t nw = (__PBM_IX(_poptBitsM-1) + 1); - size_t i; - - if (ap == NULL || b == NULL || _poptBitsNew(ap)) - return POPT_ERROR_NULLARG; - abits = __PBM_BITS(*ap); - bbits = __PBM_BITS(b); - - for (i = 0; i < nw; i++) { - abits[i] &= bbits[i]; - rc |= abits[i]; - } - return (rc ? 1 : 0); -} - -int poptBitsUnion(poptBits *ap, const poptBits b) -{ - __pbm_bits *abits; - __pbm_bits *bbits; - __pbm_bits rc = 0; - size_t nw = (__PBM_IX(_poptBitsM-1) + 1); - size_t i; - - if (ap == NULL || b == NULL || _poptBitsNew(ap)) - return POPT_ERROR_NULLARG; - abits = __PBM_BITS(*ap); - bbits = __PBM_BITS(b); - - for (i = 0; i < nw; i++) { - abits[i] |= bbits[i]; - rc |= abits[i]; - } - return (rc ? 1 : 0); -} - -int poptBitsArgs(poptContext con, poptBits *ap) -{ - const char ** av; - int rc = 0; - - if (con == NULL || ap == NULL || _poptBitsNew(ap) || - con->leftovers == NULL || con->numLeftovers == con->nextLeftover) - return POPT_ERROR_NULLARG; - - /* some apps like [like RPM ;-) ] need this NULL terminated */ - con->leftovers[con->numLeftovers] = NULL; - - for (av = con->leftovers + con->nextLeftover; *av != NULL; av++) { - if ((rc = poptBitsAdd(*ap, *av)) != 0) - break; - } -/*@-nullstate@*/ - return rc; -/*@=nullstate@*/ -} - -int poptSaveBits(poptBits * bitsp, - /*@unused@*/ UNUSED(unsigned int argInfo), const char * s) -{ - char *tbuf = NULL; - char *t, *te; - int rc = 0; - - if (bitsp == NULL || s == NULL || *s == '\0' || _poptBitsNew(bitsp)) - return POPT_ERROR_NULLARG; - - /* Parse comma separated attributes. */ - te = tbuf = xstrdup(s); - while ((t = te) != NULL && *t) { - while (*te != '\0' && *te != ',') - te++; - if (*te != '\0') - *te++ = '\0'; - /* XXX Ignore empty strings. */ - if (*t == '\0') - continue; - /* XXX Permit negated attributes. caveat emptor: false negatives. */ - if (*t == '!') { - t++; - if ((rc = poptBitsChk(*bitsp, t)) > 0) - rc = poptBitsDel(*bitsp, t); - } else - rc = poptBitsAdd(*bitsp, t); - if (rc) - break; - } - tbuf = _free(tbuf); - return rc; -} -/*@=sizeoftype@*/ - -int poptSaveString(const char *** argvp, - /*@unused@*/ UNUSED(unsigned int argInfo), const char * val) -{ - int argc = 0; - - if (argvp == NULL || val == NULL) - return POPT_ERROR_NULLARG; - - /* XXX likely needs an upper bound on argc. */ - if (*argvp != NULL) - while ((*argvp)[argc] != NULL) - argc++; - -/*@-unqualifiedtrans -nullstate@*/ /* XXX no annotation for (*argvp) */ - if ((*argvp = xrealloc(*argvp, (argc + 1 + 1) * sizeof(**argvp))) != NULL) { - (*argvp)[argc++] = xstrdup(val); - (*argvp)[argc ] = NULL; - } - return 0; -/*@=unqualifiedtrans =nullstate@*/ -} - -/*@unchecked@*/ -static unsigned int seed = 0; - -int poptSaveLongLong(long long * arg, unsigned int argInfo, long long aLongLong) -{ - if (arg == NULL -#ifdef NOTYET - /* XXX Check alignment, may fail on funky platforms. */ - || (((unsigned long long)arg) & (sizeof(*arg)-1)) -#endif - ) - return POPT_ERROR_NULLARG; - - if (aLongLong != 0 && LF_ISSET(RANDOM)) { -#if defined(HAVE_SRANDOM) - if (!seed) { - srandom((unsigned)getpid()); - srandom((unsigned)random()); - } - aLongLong = (long long)(random() % (aLongLong > 0 ? aLongLong : -aLongLong)); - aLongLong++; -#else - /* XXX avoid adding POPT_ERROR_UNIMPLEMENTED to minimize i18n churn. */ - return POPT_ERROR_BADOPERATION; -#endif - } - if (LF_ISSET(NOT)) - aLongLong = ~aLongLong; - switch (LF_ISSET(LOGICALOPS)) { - case 0: - *arg = aLongLong; - break; - case POPT_ARGFLAG_OR: - *(unsigned long long *)arg |= (unsigned long long)aLongLong; - break; - case POPT_ARGFLAG_AND: - *(unsigned long long *)arg &= (unsigned long long)aLongLong; - break; - case POPT_ARGFLAG_XOR: - *(unsigned long long *)arg ^= (unsigned long long)aLongLong; - break; - default: - return POPT_ERROR_BADOPERATION; - /*@notreached@*/ break; - } - return 0; -} - -int poptSaveLong(long * arg, unsigned int argInfo, long aLong) -{ - /* XXX Check alignment, may fail on funky platforms. */ - if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1))) - return POPT_ERROR_NULLARG; - - if (aLong != 0 && LF_ISSET(RANDOM)) { -#if defined(HAVE_SRANDOM) - if (!seed) { - srandom((unsigned)getpid()); - srandom((unsigned)random()); - } - aLong = random() % (aLong > 0 ? aLong : -aLong); - aLong++; -#else - /* XXX avoid adding POPT_ERROR_UNIMPLEMENTED to minimize i18n churn. */ - return POPT_ERROR_BADOPERATION; -#endif - } - if (LF_ISSET(NOT)) - aLong = ~aLong; - switch (LF_ISSET(LOGICALOPS)) { - case 0: *arg = aLong; break; - case POPT_ARGFLAG_OR: *(unsigned long *)arg |= (unsigned long)aLong; break; - case POPT_ARGFLAG_AND: *(unsigned long *)arg &= (unsigned long)aLong; break; - case POPT_ARGFLAG_XOR: *(unsigned long *)arg ^= (unsigned long)aLong; break; - default: - return POPT_ERROR_BADOPERATION; - /*@notreached@*/ break; - } - return 0; -} - -int poptSaveInt(/*@null@*/ int * arg, unsigned int argInfo, long aLong) -{ - /* XXX Check alignment, may fail on funky platforms. */ - if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1))) - return POPT_ERROR_NULLARG; - - if (aLong != 0 && LF_ISSET(RANDOM)) { -#if defined(HAVE_SRANDOM) - if (!seed) { - srandom((unsigned)getpid()); - srandom((unsigned)random()); - } - aLong = random() % (aLong > 0 ? aLong : -aLong); - aLong++; -#else - /* XXX avoid adding POPT_ERROR_UNIMPLEMENTED to minimize i18n churn. */ - return POPT_ERROR_BADOPERATION; -#endif - } - if (LF_ISSET(NOT)) - aLong = ~aLong; - switch (LF_ISSET(LOGICALOPS)) { - case 0: *arg = (int) aLong; break; - case POPT_ARGFLAG_OR: *(unsigned int *)arg |= (unsigned int) aLong; break; - case POPT_ARGFLAG_AND: *(unsigned int *)arg &= (unsigned int) aLong; break; - case POPT_ARGFLAG_XOR: *(unsigned int *)arg ^= (unsigned int) aLong; break; - default: - return POPT_ERROR_BADOPERATION; - /*@notreached@*/ break; - } - return 0; -} - -int poptSaveShort(/*@null@*/ short * arg, unsigned int argInfo, long aLong) -{ - /* XXX Check alignment, may fail on funky platforms. */ - if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1))) - return POPT_ERROR_NULLARG; - - if (aLong != 0 && LF_ISSET(RANDOM)) { -#if defined(HAVE_SRANDOM) - if (!seed) { - srandom((unsigned)getpid()); - srandom((unsigned)random()); - } - aLong = random() % (aLong > 0 ? aLong : -aLong); - aLong++; -#else - /* XXX avoid adding POPT_ERROR_UNIMPLEMENTED to minimize i18n churn. */ - return POPT_ERROR_BADOPERATION; -#endif - } - if (LF_ISSET(NOT)) - aLong = ~aLong; - switch (LF_ISSET(LOGICALOPS)) { - case 0: *arg = (short) aLong; - break; - case POPT_ARGFLAG_OR: *(unsigned short *)arg |= (unsigned short) aLong; - break; - case POPT_ARGFLAG_AND: *(unsigned short *)arg &= (unsigned short) aLong; - break; - case POPT_ARGFLAG_XOR: *(unsigned short *)arg ^= (unsigned short) aLong; - break; - default: return POPT_ERROR_BADOPERATION; - /*@notreached@*/ break; - } - return 0; -} - -/** - * Return argInfo field, handling POPT_ARGFLAG_TOGGLE overrides. - * @param con context - * @param opt option - * @return argInfo - */ -static unsigned int poptArgInfo(poptContext con, const struct poptOption * opt) - /*@*/ -{ - unsigned int argInfo = opt->argInfo; - - if (con->os->argv != NULL && con->os->next > 0 && opt->longName != NULL) - if (LF_ISSET(TOGGLE)) { - const char * longName = con->os->argv[con->os->next-1]; - while (*longName == '-') longName++; - /* XXX almost good enough but consider --[no]nofoo corner cases. */ - if (longName[0] != opt->longName[0] || longName[1] != opt->longName[1]) - { - if (!LF_ISSET(XOR)) { /* XXX dont toggle with XOR */ - /* Toggle POPT_BIT_SET <=> POPT_BIT_CLR. */ - if (LF_ISSET(LOGICALOPS)) - argInfo ^= (POPT_ARGFLAG_OR|POPT_ARGFLAG_AND); - argInfo ^= POPT_ARGFLAG_NOT; - } - } - } - return argInfo; -} - -/** - * Parse an integer expression. - * @retval *llp integer expression value - * @param argInfo integer expression type - * @param val integer expression string - * @return 0 on success, otherwise POPT_* error. - */ -static int poptParseInteger(long long * llp, - /*@unused@*/ UNUSED(unsigned int argInfo), - /*@null@*/ const char * val) - /*@modifies *llp @*/ -{ - if (val) { - char *end = NULL; - *llp = strtoll(val, &end, 0); - - /* XXX parse scaling suffixes here. */ - - if (!(end && *end == '\0')) - return POPT_ERROR_BADNUMBER; - } else - *llp = 0; - return 0; -} - -/** - * Save the option argument through the (*opt->arg) pointer. - * @param con context - * @param opt option - * @return 0 on success, otherwise POPT_* error. - */ -static int poptSaveArg(poptContext con, const struct poptOption * opt) - /*@globals fileSystem, internalState @*/ - /*@modifies con, fileSystem, internalState @*/ -{ - poptArg arg = { .ptr = opt->arg }; - int rc = 0; /* assume success */ - - switch (poptArgType(opt)) { - case POPT_ARG_BITSET: - /* XXX memory leak, application is responsible for free. */ - rc = poptSaveBits(arg.ptr, opt->argInfo, con->os->nextArg); - /*@switchbreak@*/ break; - case POPT_ARG_ARGV: - /* XXX memory leak, application is responsible for free. */ - rc = poptSaveString(arg.ptr, opt->argInfo, con->os->nextArg); - /*@switchbreak@*/ break; - case POPT_ARG_STRING: - /* XXX memory leak, application is responsible for free. */ - arg.argv[0] = (con->os->nextArg) ? xstrdup(con->os->nextArg) : NULL; - /*@switchbreak@*/ break; - - case POPT_ARG_INT: - case POPT_ARG_SHORT: - case POPT_ARG_LONG: - case POPT_ARG_LONGLONG: - { unsigned int argInfo = poptArgInfo(con, opt); - long long aNUM = 0; - - if ((rc = poptParseInteger(&aNUM, argInfo, con->os->nextArg)) != 0) - break; - - switch (poptArgType(opt)) { - case POPT_ARG_LONGLONG: -/* XXX let's not demand C99 compiler flags for quite yet. */ -#if !defined(LLONG_MAX) -# define LLONG_MAX 9223372036854775807LL -# define LLONG_MIN (-LLONG_MAX - 1LL) -#endif - rc = !(aNUM == LLONG_MIN || aNUM == LLONG_MAX) - ? poptSaveLongLong(arg.longlongp, argInfo, aNUM) - : POPT_ERROR_OVERFLOW; - /*@innerbreak@*/ break; - case POPT_ARG_LONG: - rc = !(aNUM < (long long)LONG_MIN || aNUM > (long long)LONG_MAX) - ? poptSaveLong(arg.longp, argInfo, (long)aNUM) - : POPT_ERROR_OVERFLOW; - /*@innerbreak@*/ break; - case POPT_ARG_INT: - rc = !(aNUM < (long long)INT_MIN || aNUM > (long long)INT_MAX) - ? poptSaveInt(arg.intp, argInfo, (long)aNUM) - : POPT_ERROR_OVERFLOW; - /*@innerbreak@*/ break; - case POPT_ARG_SHORT: - rc = !(aNUM < (long long)SHRT_MIN || aNUM > (long long)SHRT_MAX) - ? poptSaveShort(arg.shortp, argInfo, (long)aNUM) - : POPT_ERROR_OVERFLOW; - /*@innerbreak@*/ break; - } - } /*@switchbreak@*/ break; - - case POPT_ARG_FLOAT: - case POPT_ARG_DOUBLE: - { char *end = NULL; - double aDouble = 0.0; - - if (con->os->nextArg) { -/*@-mods@*/ - int saveerrno = errno; - errno = 0; - aDouble = strtod(con->os->nextArg, &end); - if (errno == ERANGE) { - rc = POPT_ERROR_OVERFLOW; - break; - } - errno = saveerrno; -/*@=mods@*/ - if (*end != '\0') { - rc = POPT_ERROR_BADNUMBER; - break; - } - } - - switch (poptArgType(opt)) { - case POPT_ARG_DOUBLE: - arg.doublep[0] = aDouble; - /*@innerbreak@*/ break; - case POPT_ARG_FLOAT: -#if !defined(DBL_EPSILON) && !defined(__LCLINT__) -#define DBL_EPSILON 2.2204460492503131e-16 -#endif -#define POPT_ABS(a) ((((a) - 0.0) < DBL_EPSILON) ? -(a) : (a)) - if ((FLT_MIN - POPT_ABS(aDouble)) > DBL_EPSILON - || (POPT_ABS(aDouble) - FLT_MAX) > DBL_EPSILON) - rc = POPT_ERROR_OVERFLOW; - else - arg.floatp[0] = (float) aDouble; - /*@innerbreak@*/ break; - } - } /*@switchbreak@*/ break; - case POPT_ARG_MAINCALL: -/*@-assignexpose -type@*/ - con->maincall = opt->arg; -/*@=assignexpose =type@*/ - /*@switchbreak@*/ break; - default: - fprintf(stdout, POPT_("option type (%u) not implemented in popt\n"), - poptArgType(opt)); - exit(EXIT_FAILURE); - /*@notreached@*/ /*@switchbreak@*/ break; - } - return rc; -} - -/* returns 'val' element, -1 on last item, POPT_ERROR_* on error */ -int poptGetNextOpt(poptContext con) -{ - const struct poptOption * opt = NULL; - int done = 0; - - if (con == NULL) - return -1; - while (!done) { - const char * origOptString = NULL; - poptCallbackType cb = NULL; - const void * cbData = NULL; - const char * longArg = NULL; - int canstrip = 0; - int shorty = 0; - - while (!con->os->nextCharArg && con->os->next == con->os->argc - && con->os > con->optionStack) { - cleanOSE(con->os--); - } - if (!con->os->nextCharArg && con->os->next == con->os->argc) { - invokeCallbacksPOST(con, con->options); - - if (con->maincall) { - /*@-noeffectuncon @*/ - (void) (*con->maincall) (con->finalArgvCount, con->finalArgv); - /*@=noeffectuncon @*/ - return -1; - } - - if (con->doExec) return execCommand(con); - return -1; - } - - /* Process next long option */ - if (!con->os->nextCharArg) { - const char * optString; - size_t optStringLen; - int thisopt; - -/*@-sizeoftype@*/ - if (con->os->argb && PBM_ISSET(con->os->next, con->os->argb)) { - con->os->next++; - continue; - } -/*@=sizeoftype@*/ - thisopt = con->os->next; - if (con->os->argv != NULL) /* XXX can't happen */ - origOptString = con->os->argv[con->os->next++]; - - if (origOptString == NULL) /* XXX can't happen */ - return POPT_ERROR_BADOPT; - - if (con->restLeftover || *origOptString != '-' || - (*origOptString == '-' && origOptString[1] == '\0')) - { - if (con->flags & POPT_CONTEXT_POSIXMEHARDER) - con->restLeftover = 1; - if (con->flags & POPT_CONTEXT_ARG_OPTS) { - con->os->nextArg = xstrdup(origOptString); - return 0; - } - if (con->leftovers != NULL) /* XXX can't happen */ - con->leftovers[con->numLeftovers++] = origOptString; - continue; - } - - /* Make a copy we can hack at */ - optString = origOptString; - - if (optString[0] == '\0') - return POPT_ERROR_BADOPT; - - if (optString[1] == '-' && !optString[2]) { - con->restLeftover = 1; - continue; - } else { - const char *oe; - unsigned int argInfo = 0; - - optString++; - if (*optString == '-') - optString++; - else - argInfo |= POPT_ARGFLAG_ONEDASH; - - /* Check for "--long=arg" option. */ - for (oe = optString; *oe && *oe != '='; oe++) - {}; - optStringLen = (size_t)(oe - optString); - if (*oe == '=') - longArg = oe + 1; - - /* XXX aliases with arg substitution need "--alias=arg" */ - if (handleAlias(con, optString, optStringLen, '\0', longArg)) { - longArg = NULL; - continue; - } - - if (handleExec(con, optString, '\0')) - continue; - - opt = findOption(con->options, optString, optStringLen, '\0', &cb, &cbData, - argInfo); - if (!opt && !LF_ISSET(ONEDASH)) - return POPT_ERROR_BADOPT; - } - - if (!opt) { - con->os->nextCharArg = origOptString + 1; - longArg = NULL; - } else { - if (con->os == con->optionStack && F_ISSET(opt, STRIP)) - { - canstrip = 1; - poptStripArg(con, thisopt); - } - shorty = 0; - } - } - - /* Process next short option */ - if (con->os->nextCharArg) { - const char * nextCharArg = con->os->nextCharArg; - - con->os->nextCharArg = NULL; - - if (handleAlias(con, NULL, 0, *nextCharArg, nextCharArg + 1)) - continue; - - if (handleExec(con, NULL, *nextCharArg)) { - /* Restore rest of short options for further processing */ - nextCharArg++; - if (*nextCharArg != '\0') - con->os->nextCharArg = nextCharArg; - continue; - } - - opt = findOption(con->options, NULL, 0, *nextCharArg, &cb, - &cbData, 0); - if (!opt) - return POPT_ERROR_BADOPT; - shorty = 1; - - nextCharArg++; - if (*nextCharArg != '\0') - con->os->nextCharArg = nextCharArg + (int)(*nextCharArg == '='); - } - - if (opt == NULL) return POPT_ERROR_BADOPT; /* XXX can't happen */ - if (opt->arg && poptArgType(opt) == POPT_ARG_NONE) { - unsigned int argInfo = poptArgInfo(con, opt); - if (poptSaveInt((int *)opt->arg, argInfo, 1L)) - return POPT_ERROR_BADOPERATION; - } else if (poptArgType(opt) == POPT_ARG_VAL) { - if (opt->arg) { - unsigned int argInfo = poptArgInfo(con, opt); - if (poptSaveInt((int *)opt->arg, argInfo, (long)opt->val)) - return POPT_ERROR_BADOPERATION; - } - } else if (poptArgType(opt) != POPT_ARG_NONE) { - int rc; - - con->os->nextArg = _free(con->os->nextArg); - if (longArg) { - longArg = expandNextArg(con, longArg); - con->os->nextArg = (char *) longArg; - } else if (con->os->nextCharArg) { - longArg = expandNextArg(con, con->os->nextCharArg); - con->os->nextArg = (char *) longArg; - con->os->nextCharArg = NULL; - } else { - while (con->os->next == con->os->argc && - con->os > con->optionStack) - { - cleanOSE(con->os--); - } - if (con->os->next == con->os->argc) { - if (!F_ISSET(opt, OPTIONAL)) - return POPT_ERROR_NOARG; - con->os->nextArg = NULL; - } else { - - /* - * Make sure this isn't part of a short arg or the - * result of an alias expansion. - */ - if (con->os == con->optionStack - && F_ISSET(opt, STRIP) && canstrip) - { - poptStripArg(con, con->os->next); - } - - if (con->os->argv != NULL) { /* XXX can't happen */ - if (F_ISSET(opt, OPTIONAL) && - con->os->argv[con->os->next][0] == '-') { - con->os->nextArg = NULL; - } else { - /* XXX watchout: subtle side-effects live here. */ - longArg = con->os->argv[con->os->next++]; - longArg = expandNextArg(con, longArg); - con->os->nextArg = (char *) longArg; - } - } - } - } - longArg = NULL; - - /* Save the option argument through a (*opt->arg) pointer. */ - if (opt->arg != NULL && (rc = poptSaveArg(con, opt)) != 0) - return rc; - } - - if (cb) - invokeCallbacksOPTION(con, con->options, opt, cbData, shorty); - else if (opt->val && (poptArgType(opt) != POPT_ARG_VAL)) - done = 1; - - if ((con->finalArgvCount + 2) >= (con->finalArgvAlloced)) { - con->finalArgvAlloced += 10; - con->finalArgv = realloc(con->finalArgv, - sizeof(*con->finalArgv) * con->finalArgvAlloced); - } - - if (con->finalArgv != NULL) - { char *s = malloc((opt->longName ? strlen(opt->longName) : 0) + sizeof("--")); - if (s != NULL) { /* XXX can't happen */ - con->finalArgv[con->finalArgvCount++] = s; - *s++ = '-'; - if (opt->longName) { - if (!F_ISSET(opt, ONEDASH)) - *s++ = '-'; - s = stpcpy(s, opt->longName); - } else { - *s++ = opt->shortName; - *s = '\0'; - } - } else - con->finalArgv[con->finalArgvCount++] = NULL; - } - - if (opt->arg && poptArgType(opt) == POPT_ARG_NONE) - /*@-ifempty@*/ ; /*@=ifempty@*/ - else if (poptArgType(opt) == POPT_ARG_VAL) - /*@-ifempty@*/ ; /*@=ifempty@*/ - else if (poptArgType(opt) != POPT_ARG_NONE) { - if (con->finalArgv != NULL && con->os->nextArg != NULL) - con->finalArgv[con->finalArgvCount++] = - xstrdup(con->os->nextArg); - } - } - - return (opt ? opt->val : -1); /* XXX can't happen */ -} - -char * poptGetOptArg(poptContext con) -{ - char * ret = NULL; - if (con) { - ret = con->os->nextArg; - con->os->nextArg = NULL; - } - return ret; -} - -const char * poptGetArg(poptContext con) -{ - const char * ret = NULL; - if (con && con->leftovers != NULL && con->nextLeftover < con->numLeftovers) - ret = con->leftovers[con->nextLeftover++]; - return ret; -} - -const char * poptPeekArg(poptContext con) -{ - const char * ret = NULL; - if (con && con->leftovers != NULL && con->nextLeftover < con->numLeftovers) - ret = con->leftovers[con->nextLeftover]; - return ret; -} - -const char ** poptGetArgs(poptContext con) -{ - if (con == NULL || - con->leftovers == NULL || con->numLeftovers == con->nextLeftover) - return NULL; - - /* some apps like [like RPM ;-) ] need this NULL terminated */ - con->leftovers[con->numLeftovers] = NULL; - -/*@-nullret -nullstate @*/ /* FIX: typedef double indirection. */ - return (con->leftovers + con->nextLeftover); -/*@=nullret =nullstate @*/ -} - -static /*@null@*/ -poptItem poptFreeItems(/*@only@*/ /*@null@*/ poptItem items, int nitems) - /*@modifies items @*/ -{ - if (items != NULL) { - poptItem item = items; - while (--nitems >= 0) { -/*@-modobserver -observertrans -dependenttrans@*/ - item->option.longName = _free(item->option.longName); - item->option.descrip = _free(item->option.descrip); - item->option.argDescrip = _free(item->option.argDescrip); -/*@=modobserver =observertrans =dependenttrans@*/ - item->argv = _free(item->argv); - item++; - } - items = _free(items); - } - return NULL; -} - -poptContext poptFreeContext(poptContext con) -{ - if (con == NULL) return con; - poptResetContext(con); - con->os->argb = _free(con->os->argb); - - con->aliases = poptFreeItems(con->aliases, con->numAliases); - con->numAliases = 0; - - con->execs = poptFreeItems(con->execs, con->numExecs); - con->numExecs = 0; - - con->leftovers = _free(con->leftovers); - con->finalArgv = _free(con->finalArgv); - con->appName = _free(con->appName); - con->otherHelp = _free(con->otherHelp); - con->execPath = _free(con->execPath); - con->arg_strip = PBM_FREE(con->arg_strip); - - con = _free(con); - return con; -} - -int poptAddAlias(poptContext con, struct poptAlias alias, - /*@unused@*/ UNUSED(int flags)) -{ - struct poptItem_s item_buf; - poptItem item = &item_buf; - memset(item, 0, sizeof(*item)); - item->option.longName = alias.longName; - item->option.shortName = alias.shortName; - item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN; - item->option.arg = 0; - item->option.val = 0; - item->option.descrip = NULL; - item->option.argDescrip = NULL; - item->argc = alias.argc; - item->argv = alias.argv; - return poptAddItem(con, item, 0); -} - -int poptAddItem(poptContext con, poptItem newItem, int flags) -{ - poptItem * items, item; - int * nitems; - - switch (flags) { - case 1: - items = &con->execs; - nitems = &con->numExecs; - break; - case 0: - items = &con->aliases; - nitems = &con->numAliases; - break; - default: - return 1; - /*@notreached@*/ break; - } - - *items = realloc((*items), ((*nitems) + 1) * sizeof(**items)); - if ((*items) == NULL) - return 1; - - item = (*items) + (*nitems); - - item->option.longName = - (newItem->option.longName ? xstrdup(newItem->option.longName) : NULL); - item->option.shortName = newItem->option.shortName; - item->option.argInfo = newItem->option.argInfo; - item->option.arg = newItem->option.arg; - item->option.val = newItem->option.val; - item->option.descrip = - (newItem->option.descrip ? xstrdup(newItem->option.descrip) : NULL); - item->option.argDescrip = - (newItem->option.argDescrip ? xstrdup(newItem->option.argDescrip) : NULL); - item->argc = newItem->argc; - item->argv = newItem->argv; - - (*nitems)++; - - return 0; -} - -const char * poptBadOption(poptContext con, unsigned int flags) -{ - struct optionStackEntry * os = NULL; - - if (con != NULL) - os = (flags & POPT_BADOPTION_NOALIAS) ? con->optionStack : con->os; - - return (os != NULL && os->argv != NULL ? os->argv[os->next - 1] : NULL); -} - -const char * poptStrerror(const int error) -{ - switch (error) { - case POPT_ERROR_NOARG: - return POPT_("missing argument"); - case POPT_ERROR_BADOPT: - return POPT_("unknown option"); - case POPT_ERROR_BADOPERATION: - return POPT_("mutually exclusive logical operations requested"); - case POPT_ERROR_NULLARG: - return POPT_("opt->arg should not be NULL"); - case POPT_ERROR_OPTSTOODEEP: - return POPT_("aliases nested too deeply"); - case POPT_ERROR_BADQUOTE: - return POPT_("error in parameter quoting"); - case POPT_ERROR_BADNUMBER: - return POPT_("invalid numeric value"); - case POPT_ERROR_OVERFLOW: - return POPT_("number too large or too small"); - case POPT_ERROR_MALLOC: - return POPT_("memory allocation failed"); - case POPT_ERROR_BADCONFIG: - return POPT_("config file failed sanity test"); - case POPT_ERROR_ERRNO: - return strerror(errno); - default: - return POPT_("unknown error"); - } -} - -int poptStuffArgs(poptContext con, const char ** argv) -{ - int argc; - int rc; - - if ((con->os - con->optionStack) == POPT_OPTION_DEPTH) - return POPT_ERROR_OPTSTOODEEP; - - for (argc = 0; argv[argc]; argc++) - {}; - - con->os++; - con->os->next = 0; - con->os->nextArg = NULL; - con->os->nextCharArg = NULL; - con->os->currAlias = NULL; - rc = poptDupArgv(argc, argv, &con->os->argc, &con->os->argv); - con->os->argb = NULL; - con->os->stuffed = 1; - - return rc; -} - -const char * poptGetInvocationName(poptContext con) -{ - return (con->os->argv ? con->os->argv[0] : ""); -} - -int poptStrippedArgv(poptContext con, int argc, char ** argv) -{ - int numargs = argc; - int j = 1; - int i; - -/*@-sizeoftype@*/ - if (con->arg_strip) - for (i = 1; i < argc; i++) { - if (PBM_ISSET(i, con->arg_strip)) - numargs--; - } - - for (i = 1; i < argc; i++) { - if (con->arg_strip && PBM_ISSET(i, con->arg_strip)) - continue; - argv[j] = (j < numargs) ? argv[i] : NULL; - j++; - } -/*@=sizeoftype@*/ - - return numargs; -} diff --git a/ldb-2.0.8/third_party/popt/popt.h b/ldb-2.0.8/third_party/popt/popt.h deleted file mode 100644 index a12d143..0000000 --- a/ldb-2.0.8/third_party/popt/popt.h +++ /dev/null @@ -1,744 +0,0 @@ -/** \file popt/popt.h - * \ingroup popt - */ - -/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist. */ - -#ifndef H_POPT -#define H_POPT - -#include /* for FILE * */ - -#define POPT_OPTION_DEPTH 10 - -/** \ingroup popt - * \name Arg type identifiers - */ -/*@{*/ -#define POPT_ARG_NONE 0U /*!< no arg */ -#define POPT_ARG_STRING 1U /*!< arg will be saved as string */ -#define POPT_ARG_INT 2U /*!< arg ==> int */ -#define POPT_ARG_LONG 3U /*!< arg ==> long */ -#define POPT_ARG_INCLUDE_TABLE 4U /*!< arg points to table */ -#define POPT_ARG_CALLBACK 5U /*!< table-wide callback... must be - set first in table; arg points - to callback, descrip points to - callback data to pass */ -#define POPT_ARG_INTL_DOMAIN 6U /*!< set the translation domain - for this table and any - included tables; arg points - to the domain string */ -#define POPT_ARG_VAL 7U /*!< arg should take value val */ -#define POPT_ARG_FLOAT 8U /*!< arg ==> float */ -#define POPT_ARG_DOUBLE 9U /*!< arg ==> double */ -#define POPT_ARG_LONGLONG 10U /*!< arg ==> long long */ - -#define POPT_ARG_MAINCALL 16U+11U /*!< EXPERIMENTAL: return (*arg) (argc, argv) */ -#define POPT_ARG_ARGV 12U /*!< dupe'd arg appended to realloc'd argv array. */ -#define POPT_ARG_SHORT 13U /*!< arg ==> short */ -#define POPT_ARG_BITSET 16U+14U /*!< arg ==> bit set */ - -#define POPT_ARG_MASK 0x000000FFU -#define POPT_GROUP_MASK 0x0000FF00U - -/*@}*/ - -/** \ingroup popt - * \name Arg modifiers - */ -/*@{*/ -#define POPT_ARGFLAG_ONEDASH 0x80000000U /*!< allow -longoption */ -#define POPT_ARGFLAG_DOC_HIDDEN 0x40000000U /*!< don't show in help/usage */ -#define POPT_ARGFLAG_STRIP 0x20000000U /*!< strip this arg from argv(only applies to long args) */ -#define POPT_ARGFLAG_OPTIONAL 0x10000000U /*!< arg may be missing */ - -#define POPT_ARGFLAG_OR 0x08000000U /*!< arg will be or'ed */ -#define POPT_ARGFLAG_NOR 0x09000000U /*!< arg will be nor'ed */ -#define POPT_ARGFLAG_AND 0x04000000U /*!< arg will be and'ed */ -#define POPT_ARGFLAG_NAND 0x05000000U /*!< arg will be nand'ed */ -#define POPT_ARGFLAG_XOR 0x02000000U /*!< arg will be xor'ed */ -#define POPT_ARGFLAG_NOT 0x01000000U /*!< arg will be negated */ -#define POPT_ARGFLAG_LOGICALOPS \ - (POPT_ARGFLAG_OR|POPT_ARGFLAG_AND|POPT_ARGFLAG_XOR) - -#define POPT_BIT_SET (POPT_ARG_VAL|POPT_ARGFLAG_OR) - /*!< set arg bit(s) */ -#define POPT_BIT_CLR (POPT_ARG_VAL|POPT_ARGFLAG_NAND) - /*!< clear arg bit(s) */ - -#define POPT_ARGFLAG_SHOW_DEFAULT 0x00800000U /*!< show default value in --help */ -#define POPT_ARGFLAG_RANDOM 0x00400000U /*!< random value in [1,arg] */ -#define POPT_ARGFLAG_TOGGLE 0x00200000U /*!< permit --[no]opt prefix toggle */ - -/*@}*/ - -/** \ingroup popt - * \name Callback modifiers - */ -/*@{*/ -#define POPT_CBFLAG_PRE 0x80000000U /*!< call the callback before parse */ -#define POPT_CBFLAG_POST 0x40000000U /*!< call the callback after parse */ -#define POPT_CBFLAG_INC_DATA 0x20000000U /*!< use data from the include line, - not the subtable */ -#define POPT_CBFLAG_SKIPOPTION 0x10000000U /*!< don't callback with option */ -#define POPT_CBFLAG_CONTINUE 0x08000000U /*!< continue callbacks with option */ -/*@}*/ - -/** \ingroup popt - * \name Error return values - */ -/*@{*/ -#define POPT_ERROR_NOARG -10 /*!< missing argument */ -#define POPT_ERROR_BADOPT -11 /*!< unknown option */ -#define POPT_ERROR_OPTSTOODEEP -13 /*!< aliases nested too deeply */ -#define POPT_ERROR_BADQUOTE -15 /*!< error in paramter quoting */ -#define POPT_ERROR_ERRNO -16 /*!< errno set, use strerror(errno) */ -#define POPT_ERROR_BADNUMBER -17 /*!< invalid numeric value */ -#define POPT_ERROR_OVERFLOW -18 /*!< number too large or too small */ -#define POPT_ERROR_BADOPERATION -19 /*!< mutually exclusive logical operations requested */ -#define POPT_ERROR_NULLARG -20 /*!< opt->arg should not be NULL */ -#define POPT_ERROR_MALLOC -21 /*!< memory allocation failed */ -#define POPT_ERROR_BADCONFIG -22 /*!< config file failed sanity test */ -/*@}*/ - -/** \ingroup popt - * \name poptBadOption() flags - */ -/*@{*/ -#define POPT_BADOPTION_NOALIAS (1U << 0) /*!< don't go into an alias */ -/*@}*/ - -/** \ingroup popt - * \name poptGetContext() flags - */ -/*@{*/ -#define POPT_CONTEXT_NO_EXEC (1U << 0) /*!< ignore exec expansions */ -#define POPT_CONTEXT_KEEP_FIRST (1U << 1) /*!< pay attention to argv[0] */ -#define POPT_CONTEXT_POSIXMEHARDER (1U << 2) /*!< options can't follow args */ -#define POPT_CONTEXT_ARG_OPTS (1U << 4) /*!< return args as options with value 0 */ -/*@}*/ - -/** \ingroup popt - */ -struct poptOption { -/*@observer@*/ /*@null@*/ - const char * longName; /*!< may be NULL */ - char shortName; /*!< may be NUL */ - unsigned int argInfo; -/*@shared@*/ /*@null@*/ - void * arg; /*!< depends on argInfo */ - int val; /*!< 0 means don't return, just update flag */ -/*@observer@*/ /*@null@*/ - const char * descrip; /*!< description for autohelp -- may be NULL */ -/*@observer@*/ /*@null@*/ - const char * argDescrip; /*!< argument description for autohelp */ -}; - -/** \ingroup popt - * A popt alias argument for poptAddAlias(). - */ -struct poptAlias { -/*@owned@*/ /*@null@*/ - const char * longName; /*!< may be NULL */ - char shortName; /*!< may be NUL */ - int argc; -/*@owned@*/ - const char ** argv; /*!< must be free()able */ -}; - -/** \ingroup popt - * A popt alias or exec argument for poptAddItem(). - */ -/*@-exporttype@*/ -typedef struct poptItem_s { - struct poptOption option; /*!< alias/exec name(s) and description. */ - int argc; /*!< (alias) no. of args. */ -/*@owned@*/ - const char ** argv; /*!< (alias) args, must be free()able. */ -} * poptItem; -/*@=exporttype@*/ - -/** \ingroup popt - * \name Auto-generated help/usage - */ -/*@{*/ - -/** - * Empty table marker to enable displaying popt alias/exec options. - */ -/*@-exportvar@*/ -/*@unchecked@*/ /*@observer@*/ -extern struct poptOption poptAliasOptions[]; -/*@=exportvar@*/ -#define POPT_AUTOALIAS { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptAliasOptions, \ - 0, "Options implemented via popt alias/exec:", NULL }, - -/** - * Auto help table options. - */ -/*@-exportvar@*/ -/*@unchecked@*/ /*@observer@*/ -extern struct poptOption poptHelpOptions[]; -/*@=exportvar@*/ - -/*@-exportvar@*/ -/*@unchecked@*/ /*@observer@*/ -extern struct poptOption * poptHelpOptionsI18N; -/*@=exportvar@*/ - -#define POPT_AUTOHELP { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptHelpOptions, \ - 0, "Help options:", NULL }, - -#define POPT_TABLEEND { NULL, '\0', 0, NULL, 0, NULL, NULL } -/*@}*/ - -/** \ingroup popt - */ -/*@-exporttype@*/ -typedef /*@abstract@*/ struct poptContext_s * poptContext; -/*@=exporttype@*/ - -/** \ingroup popt - */ -#ifndef __cplusplus -/*@-exporttype -typeuse@*/ -typedef struct poptOption * poptOption; -/*@=exporttype =typeuse@*/ -#endif - -/** \ingroup popt - */ -/*@-exportconst@*/ -enum poptCallbackReason { - POPT_CALLBACK_REASON_PRE = 0, - POPT_CALLBACK_REASON_POST = 1, - POPT_CALLBACK_REASON_OPTION = 2 -}; -/*@=exportconst@*/ - -#ifdef __cplusplus -extern "C" { -#endif -/*@-type@*/ - -/** \ingroup popt - * Table callback prototype. - * @param con context - * @param reason reason for callback - * @param opt option that triggered callback - * @param arg @todo Document. - * @param data @todo Document. - */ -typedef void (*poptCallbackType) (poptContext con, - enum poptCallbackReason reason, - /*@null@*/ const struct poptOption * opt, - /*@null@*/ const char * arg, - /*@null@*/ const void * data) - /*@globals internalState @*/ - /*@modifies internalState @*/; - -/** \ingroup popt - * Destroy context. - * @param con context - * @return NULL always - */ -/*@null@*/ -poptContext poptFreeContext( /*@only@*/ /*@null@*/ poptContext con) - /*@modifies con @*/; - -/** \ingroup popt - * Initialize popt context. - * @param name context name (usually argv[0] program name) - * @param argc no. of arguments - * @param argv argument array - * @param options address of popt option table - * @param flags or'd POPT_CONTEXT_* bits - * @return initialized popt context - */ -/*@only@*/ /*@null@*/ -poptContext poptGetContext( - /*@dependent@*/ /*@keep@*/ const char * name, - int argc, /*@dependent@*/ /*@keep@*/ const char ** argv, - /*@dependent@*/ /*@keep@*/ const struct poptOption * options, - unsigned int flags) - /*@globals internalState @*/ - /*@modifies internalState @*/; - -/** \ingroup popt - * Destroy context (alternative implementation). - * @param con context - * @return NULL always - */ -/*@null@*/ -poptContext poptFini( /*@only@*/ /*@null@*/ poptContext con) - /*@modifies con @*/; - -/** \ingroup popt - * Initialize popt context (alternative implementation). - * This routine does poptGetContext() and then poptReadConfigFiles(). - * @param argc no. of arguments - * @param argv argument array - * @param options address of popt option table - * @param configPaths colon separated file path(s) to read. - * @return initialized popt context (NULL on error). - */ -/*@only@*/ /*@null@*/ /*@unused@*/ -poptContext poptInit(int argc, /*@dependent@*/ /*@keep@*/ const char ** argv, - /*@dependent@*/ /*@keep@*/ const struct poptOption * options, - /*@null@*/ const char * configPaths) - /*@globals fileSystem, internalState @*/ - /*@modifies fileSystem, internalState @*/; - -/** \ingroup popt - * Reinitialize popt context. - * @param con context - */ -/*@unused@*/ -void poptResetContext(/*@null@*/poptContext con) - /*@modifies con @*/; - -/** \ingroup popt - * Return value of next option found. - * @param con context - * @return next option val, -1 on last item, POPT_ERROR_* on error - */ -int poptGetNextOpt(/*@null@*/poptContext con) - /*@globals fileSystem, internalState @*/ - /*@modifies con, fileSystem, internalState @*/; - -/** \ingroup popt - * Return next option argument (if any). - * @param con context - * @return option argument, NULL if no argument is available - */ -/*@observer@*/ /*@null@*/ /*@unused@*/ -char * poptGetOptArg(/*@null@*/poptContext con) - /*@modifies con @*/; - -/** \ingroup popt - * Return next argument. - * @param con context - * @return next argument, NULL if no argument is available - */ -/*@observer@*/ /*@null@*/ /*@unused@*/ -const char * poptGetArg(/*@null@*/poptContext con) - /*@modifies con @*/; - -/** \ingroup popt - * Peek at current argument. - * @param con context - * @return current argument, NULL if no argument is available - */ -/*@observer@*/ /*@null@*/ /*@unused@*/ -const char * poptPeekArg(/*@null@*/poptContext con) - /*@*/; - -/** \ingroup popt - * Return remaining arguments. - * @param con context - * @return argument array, NULL terminated - */ -/*@observer@*/ /*@null@*/ -const char ** poptGetArgs(/*@null@*/poptContext con) - /*@modifies con @*/; - -/** \ingroup popt - * Return the option which caused the most recent error. - * @param con context - * @param flags - * @return offending option - */ -/*@observer@*/ -const char * poptBadOption(/*@null@*/poptContext con, unsigned int flags) - /*@*/; - -/** \ingroup popt - * Add arguments to context. - * @param con context - * @param argv argument array, NULL terminated - * @return 0 on success, POPT_ERROR_OPTSTOODEEP on failure - */ -/*@unused@*/ -int poptStuffArgs(poptContext con, /*@keep@*/ const char ** argv) - /*@modifies con @*/; - -/** \ingroup popt - * Add alias to context. - * @todo Pass alias by reference, not value. - * @deprecated Use poptAddItem instead. - * @param con context - * @param alias alias to add - * @param flags (unused) - * @return 0 on success - */ -/*@unused@*/ -int poptAddAlias(poptContext con, struct poptAlias alias, int flags) - /*@modifies con @*/; - -/** \ingroup popt - * Add alias/exec item to context. - * @param con context - * @param newItem alias/exec item to add - * @param flags 0 for alias, 1 for exec - * @return 0 on success - */ -int poptAddItem(poptContext con, poptItem newItem, int flags) - /*@modifies con @*/; - -/** \ingroup popt - * Perform sanity checks on a file path. - * @param fn file name - * @return 0 on OK, 1 on NOTOK. - */ -int poptSaneFile(const char * fn) - /*@globals errno, internalState @*/ - /*@modifies errno, internalState @*/; - -/** - * Read a file into a buffer. - * @param fn file name - * @retval *bp buffer (malloc'd) (or NULL) - * @retval *nbp no. of bytes in buffer (including final NUL) (or NULL) - * @param flags 1 to trim escaped newlines - * return 0 on success - */ -int poptReadFile(const char * fn, /*@null@*/ /*@out@*/ char ** bp, - /*@null@*/ /*@out@*/ size_t * nbp, int flags) - /*@globals errno, fileSystem, internalState @*/ - /*@modifies *bp, *nbp, errno, fileSystem, internalState @*/; -#define POPT_READFILE_TRIMNEWLINES 1 - -/** \ingroup popt - * Read configuration file. - * @param con context - * @param fn file name to read - * @return 0 on success, POPT_ERROR_ERRNO on failure - */ -int poptReadConfigFile(poptContext con, const char * fn) - /*@globals errno, fileSystem, internalState @*/ - /*@modifies con->execs, con->numExecs, - errno, fileSystem, internalState @*/; - -/** \ingroup popt - * Read configuration file(s). - * Colon separated files to read, looping over poptReadConfigFile(). - * Note that an '@' character preceeding a path in the list will - * also perform additional sanity checks on the file before reading. - * @param con context - * @param paths colon separated file name(s) to read - * @return 0 on success, POPT_ERROR_BADCONFIG on failure - */ -int poptReadConfigFiles(poptContext con, /*@null@*/ const char * paths) - /*@globals errno, fileSystem, internalState @*/ - /*@modifies con->execs, con->numExecs, - errno, fileSystem, internalState @*/; - -/** \ingroup popt - * Read default configuration from /etc/popt and $HOME/.popt. - * @param con context - * @param useEnv (unused) - * @return 0 on success, POPT_ERROR_ERRNO on failure - */ -/*@unused@*/ -int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv) - /*@globals fileSystem, internalState @*/ - /*@modifies con->execs, con->numExecs, - fileSystem, internalState @*/; - -/** \ingroup popt - * Duplicate an argument array. - * @note: The argument array is malloc'd as a single area, so only argv must - * be free'd. - * - * @param argc no. of arguments - * @param argv argument array - * @retval argcPtr address of returned no. of arguments - * @retval argvPtr address of returned argument array - * @return 0 on success, POPT_ERROR_NOARG on failure - */ -int poptDupArgv(int argc, /*@null@*/ const char **argv, - /*@null@*/ /*@out@*/ int * argcPtr, - /*@null@*/ /*@out@*/ const char *** argvPtr) - /*@modifies *argcPtr, *argvPtr @*/; - -/** \ingroup popt - * Parse a string into an argument array. - * The parse allows ', ", and \ quoting, but ' is treated the same as " and - * both may include \ quotes. - * @note: The argument array is malloc'd as a single area, so only argv must - * be free'd. - * - * @param s string to parse - * @retval argcPtr address of returned no. of arguments - * @retval argvPtr address of returned argument array - */ -int poptParseArgvString(const char * s, - /*@out@*/ int * argcPtr, /*@out@*/ const char *** argvPtr) - /*@modifies *argcPtr, *argvPtr @*/; - -/** \ingroup popt - * Parses an input configuration file and returns an string that is a - * command line. For use with popt. You must free the return value when done. - * - * Given the file: -\verbatim -# this line is ignored - # this one too -aaa - bbb - ccc -bla=bla - -this_is = fdsafdas - bad_line= - reall bad line - reall bad line = again -5555= 55555 - test = with lots of spaces -\endverbatim -* -* The result is: -\verbatim ---aaa --bbb --ccc --bla="bla" --this_is="fdsafdas" --5555="55555" --test="with lots of spaces" -\endverbatim -* -* Passing this to poptParseArgvString() yields an argv of: -\verbatim -'--aaa' -'--bbb' -'--ccc' -'--bla=bla' -'--this_is=fdsafdas' -'--5555=55555' -'--test=with lots of spaces' -\endverbatim - * - * @bug NULL is returned if file line is too long. - * @bug Silently ignores invalid lines. - * - * @param fp file handle to read - * @param *argstrp return string of options (malloc'd) - * @param flags unused - * @return 0 on success - * @see poptParseArgvString - */ -/*@-fcnuse@*/ -int poptConfigFileToString(FILE *fp, /*@out@*/ char ** argstrp, int flags) - /*@globals fileSystem @*/ - /*@modifies *fp, *argstrp, fileSystem @*/; -/*@=fcnuse@*/ - -/** \ingroup popt - * Return formatted error string for popt failure. - * @param error popt error - * @return error string - */ -/*@observer@*/ -const char * poptStrerror(const int error) - /*@*/; - -/** \ingroup popt - * Limit search for executables. - * @param con context - * @param path single path to search for executables - * @param allowAbsolute absolute paths only? - */ -/*@unused@*/ -void poptSetExecPath(poptContext con, const char * path, int allowAbsolute) - /*@modifies con @*/; - -/** \ingroup popt - * Print detailed description of options. - * @param con context - * @param fp ouput file handle - * @param flags (unused) - */ -void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ int flags) - /*@globals fileSystem @*/ - /*@modifies fp, fileSystem @*/; - -/** \ingroup popt - * Print terse description of options. - * @param con context - * @param fp ouput file handle - * @param flags (unused) - */ -void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ int flags) - /*@globals fileSystem @*/ - /*@modifies fp, fileSystem @*/; - -/** \ingroup popt - * Provide text to replace default "[OPTION...]" in help/usage output. - * @param con context - * @param text replacement text - */ -/*@-fcnuse@*/ -void poptSetOtherOptionHelp(poptContext con, const char * text) - /*@modifies con @*/; -/*@=fcnuse@*/ - -/** \ingroup popt - * Return argv[0] from context. - * @param con context - * @return argv[0] - */ -/*@-fcnuse@*/ -/*@observer@*/ -const char * poptGetInvocationName(poptContext con) - /*@*/; -/*@=fcnuse@*/ - -/** \ingroup popt - * Shuffle argv pointers to remove stripped args, returns new argc. - * @param con context - * @param argc no. of args - * @param argv arg vector - * @return new argc - */ -/*@-fcnuse@*/ -int poptStrippedArgv(poptContext con, int argc, char ** argv) - /*@modifies *argv @*/; -/*@=fcnuse@*/ - -/** - * Add a string to an argv array. - * @retval *argvp argv array - * @param argInfo (unused) - * @param val string arg to add (using strdup) - * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION - */ -/*@unused@*/ -int poptSaveString(/*@null@*/ const char *** argvp, unsigned int argInfo, - /*@null@*/const char * val) - /*@modifies *argvp @*/; - -/** - * Save a long long, performing logical operation with value. - * @warning Alignment check may be too strict on certain platorms. - * @param arg integer pointer, aligned on int boundary. - * @param argInfo logical operation (see POPT_ARGFLAG_*) - * @param aLongLong value to use - * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION - */ -/*@-incondefs@*/ -/*@unused@*/ -int poptSaveLongLong(/*@null@*/ long long * arg, unsigned int argInfo, - long long aLongLong) - /*@globals internalState @*/ - /*@modifies *arg, internalState @*/ - /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/; -/*@=incondefs@*/ - -/** - * Save a long, performing logical operation with value. - * @warning Alignment check may be too strict on certain platorms. - * @param arg integer pointer, aligned on int boundary. - * @param argInfo logical operation (see POPT_ARGFLAG_*) - * @param aLong value to use - * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION - */ -/*@-incondefs@*/ -/*@unused@*/ -int poptSaveLong(/*@null@*/ long * arg, unsigned int argInfo, long aLong) - /*@globals internalState @*/ - /*@modifies *arg, internalState @*/ - /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/; -/*@=incondefs@*/ - -/** - * Save a short integer, performing logical operation with value. - * @warning Alignment check may be too strict on certain platorms. - * @param arg short pointer, aligned on short boundary. - * @param argInfo logical operation (see POPT_ARGFLAG_*) - * @param aLong value to use - * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION - */ -/*@-incondefs@*/ -/*@unused@*/ -int poptSaveShort(/*@null@*/ short * arg, unsigned int argInfo, long aLong) - /*@globals internalState @*/ - /*@modifies *arg, internalState @*/ - /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/; -/*@=incondefs@*/ - -/** - * Save an integer, performing logical operation with value. - * @warning Alignment check may be too strict on certain platorms. - * @param arg integer pointer, aligned on int boundary. - * @param argInfo logical operation (see POPT_ARGFLAG_*) - * @param aLong value to use - * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION - */ -/*@-incondefs@*/ -/*@unused@*/ -int poptSaveInt(/*@null@*/ int * arg, unsigned int argInfo, long aLong) - /*@globals internalState @*/ - /*@modifies *arg, internalState @*/ - /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/; -/*@=incondefs@*/ - -/* The bit set typedef. */ -/*@-exporttype@*/ -typedef struct poptBits_s { - unsigned int bits[1]; -} * poptBits; -/*@=exporttype@*/ - -#define _POPT_BITS_N 1024U /* estimated population */ -#define _POPT_BITS_M ((3U * _POPT_BITS_N) / 2U) -#define _POPT_BITS_K 16U /* no. of linear hash combinations */ - -/*@-exportlocal -exportvar -globuse @*/ -/*@unchecked@*/ -extern unsigned int _poptBitsN; -/*@unchecked@*/ -extern unsigned int _poptBitsM; -/*@unchecked@*/ -extern unsigned int _poptBitsK; -/*@=exportlocal =exportvar =globuse @*/ - -/*@-exportlocal@*/ -int poptBitsAdd(/*@null@*/poptBits bits, /*@null@*/const char * s) - /*@modifies bits @*/; -/*@=exportlocal@*/ -int poptBitsChk(/*@null@*/poptBits bits, /*@null@*/const char * s) - /*@*/; -int poptBitsClr(/*@null@*/poptBits bits) - /*@modifies bits @*/; -/*@-exportlocal@*/ -int poptBitsDel(/*@null@*/poptBits bits, /*@null@*/const char * s) - /*@modifies bits @*/; -/*@-fcnuse@*/ -int poptBitsIntersect(/*@null@*/ poptBits * ap, /*@null@*/ const poptBits b) - /*@modifies *ap @*/; -int poptBitsUnion(/*@null@*/ poptBits * ap, /*@null@*/ const poptBits b) - /*@modifies *ap @*/; -int poptBitsArgs(/*@null@*/ poptContext con, /*@null@*/ poptBits * ap) - /*@modifies con, *ap @*/; -/*@=fcnuse@*/ -/*@=exportlocal@*/ - -/** - * Save a string into a bit set (experimental). - * @retval *bits bit set (lazily malloc'd if NULL) - * @param argInfo logical operation (see POPT_ARGFLAG_*) - * @param s string to add to bit set - * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION - */ -/*@-incondefs@*/ -/*@unused@*/ -int poptSaveBits(/*@null@*/ poptBits * bitsp, unsigned int argInfo, - /*@null@*/ const char * s) - /*@globals _poptBitsN, _poptBitsM, _poptBitsK, internalState @*/ - /*@modifies *bitsp, _poptBitsN, _poptBitsM, _poptBitsK, internalState @*/; -/*@=incondefs@*/ - -/*@=type@*/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/ldb-2.0.8/third_party/popt/poptconfig.c b/ldb-2.0.8/third_party/popt/poptconfig.c deleted file mode 100644 index f0a92e0..0000000 --- a/ldb-2.0.8/third_party/popt/poptconfig.c +++ /dev/null @@ -1,582 +0,0 @@ -/** \ingroup popt - * \file popt/poptconfig.c - */ - -/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist. */ - -#include "system.h" -#include "poptint.h" -#include - -#if defined(HAVE_FNMATCH_H) -#include - -#if defined(__LCLINT__) -/*@-declundef -exportheader -incondefs -protoparammatch -redecl -type @*/ -extern int fnmatch (const char *__pattern, const char *__name, int __flags) - /*@*/; -/*@=declundef =exportheader =incondefs =protoparammatch =redecl =type @*/ -#endif /* __LCLINT__ */ -#endif - -#if defined(HAVE_GLOB_H) -#include - -#if defined(__LCLINT__) -/*@-declundef -exportheader -incondefs -protoparammatch -redecl -type @*/ -extern int glob (const char *__pattern, int __flags, - /*@null@*/ int (*__errfunc) (const char *, int), - /*@out@*/ glob_t *__pglob) - /*@globals errno, fileSystem @*/ - /*@modifies *__pglob, errno, fileSystem @*/; - -/* XXX only annotation is a white lie */ -extern void globfree (/*@only@*/ glob_t *__pglob) - /*@modifies *__pglob @*/; - -/* XXX _GNU_SOURCE ifdef and/or retrofit is needed for portability. */ -extern int glob_pattern_p (const char *__pattern, int __quote) - /*@*/; -/*@=declundef =exportheader =incondefs =protoparammatch =redecl =type @*/ -#endif /* __LCLINT__ */ - -#if !defined(__GLIBC__) -/* Return nonzero if PATTERN contains any metacharacters. - Metacharacters can be quoted with backslashes if QUOTE is nonzero. */ -static int -glob_pattern_p (const char * pattern, int quote) - /*@*/ -{ - const char * p; - int open = 0; - - for (p = pattern; *p != '\0'; ++p) - switch (*p) { - case '?': - case '*': - return 1; - /*@notreached@*/ /*@switchbreak@*/ break; - case '\\': - if (quote && p[1] != '\0') - ++p; - /*@switchbreak@*/ break; - case '[': - open = 1; - /*@switchbreak@*/ break; - case ']': - if (open) - return 1; - /*@switchbreak@*/ break; - } - return 0; -} -#endif /* !defined(__GLIBC__) */ - -/*@unchecked@*/ -static int poptGlobFlags = 0; - -static int poptGlob_error(/*@unused@*/ UNUSED(const char * epath), - /*@unused@*/ UNUSED(int eerrno)) - /*@*/ -{ - return 1; -} -#endif /* HAVE_GLOB_H */ - -/** - * Return path(s) from a glob pattern. - * @param con context - * @param pattern glob pattern - * @retval *acp no. of paths - * @retval *avp array of paths - * @return 0 on success - */ -static int poptGlob(/*@unused@*/ UNUSED(poptContext con), const char * pattern, - /*@out@*/ int * acp, /*@out@*/ const char *** avp) - /*@modifies *acp, *avp @*/ -{ - const char * pat = pattern; - int rc = 0; /* assume success */ - - /* XXX skip the attention marker. */ - if (pat[0] == '@' && pat[1] != '(') - pat++; - -#if defined(HAVE_GLOB_H) - if (glob_pattern_p(pat, 0)) { - glob_t _g, *pglob = &_g; - - if (!glob(pat, poptGlobFlags, poptGlob_error, pglob)) { - if (acp) { - *acp = (int) pglob->gl_pathc; - pglob->gl_pathc = 0; - } - if (avp) { -/*@-onlytrans@*/ - *avp = (const char **) pglob->gl_pathv; -/*@=onlytrans@*/ - pglob->gl_pathv = NULL; - } -/*@-nullstate@*/ - globfree(pglob); -/*@=nullstate@*/ - } else - rc = POPT_ERROR_ERRNO; - } else -#endif /* HAVE_GLOB_H */ - { - if (acp) - *acp = 1; - if (avp && (*avp = calloc((size_t)(1 + 1), sizeof (**avp))) != NULL) - (*avp)[0] = xstrdup(pat); - } - - return rc; -} - -/*@access poptContext @*/ - -int poptSaneFile(const char * fn) -{ - struct stat sb; - uid_t uid = getuid(); - - if (stat(fn, &sb) == -1) - return 1; - if ((uid_t)sb.st_uid != uid) - return 0; - if (!S_ISREG(sb.st_mode)) - return 0; -/*@-bitwisesigned@*/ - if (sb.st_mode & (S_IWGRP|S_IWOTH)) - return 0; -/*@=bitwisesigned@*/ - return 1; -} - -int poptReadFile(const char * fn, char ** bp, size_t * nbp, int flags) -{ - int fdno; - char * b = NULL; - off_t nb = 0; - char * s, * t, * se; - int rc = POPT_ERROR_ERRNO; /* assume failure */ - - fdno = open(fn, O_RDONLY); - if (fdno < 0) - goto exit; - - if ((nb = lseek(fdno, 0, SEEK_END)) == (off_t)-1 - || lseek(fdno, 0, SEEK_SET) == (off_t)-1 - || (b = calloc(sizeof(*b), (size_t)nb + 1)) == NULL - || read(fdno, (char *)b, (size_t)nb) != (ssize_t)nb) - { - int oerrno = errno; - (void) close(fdno); - errno = oerrno; - goto exit; - } - if (close(fdno) == -1) - goto exit; - if (b == NULL) { - rc = POPT_ERROR_MALLOC; - goto exit; - } - rc = 0; - - /* Trim out escaped newlines. */ -/*@-bitwisesigned@*/ - if (flags & POPT_READFILE_TRIMNEWLINES) -/*@=bitwisesigned@*/ - { - for (t = b, s = b, se = b + nb; *s && s < se; s++) { - switch (*s) { - case '\\': - if (s[1] == '\n') { - s++; - continue; - } - /*@fallthrough@*/ - default: - *t++ = *s; - /*@switchbreak@*/ break; - } - } - *t++ = '\0'; - nb = (off_t)(t - b); - } - -exit: - if (rc != 0) { -/*@-usedef@*/ - if (b) - free(b); -/*@=usedef@*/ - b = NULL; - nb = 0; - } - if (bp) - *bp = b; -/*@-usereleased@*/ - else if (b) - free(b); -/*@=usereleased@*/ - if (nbp) - *nbp = (size_t)nb; -/*@-compdef -nullstate @*/ /* XXX cannot annotate char ** correctly */ - return rc; -/*@=compdef =nullstate @*/ -} - -/** - * Check for application match. - * @param con context - * @param s config application name - * return 0 if config application matches - */ -static int configAppMatch(poptContext con, const char * s) - /*@*/ -{ - int rc = 1; - - if (con->appName == NULL) /* XXX can't happen. */ - return rc; - -#if defined(HAVE_GLOB_H) && defined(HAVE_FNMATCH_H) - if (glob_pattern_p(s, 1)) { -/*@-bitwisesigned@*/ - static int flags = FNM_PATHNAME | FNM_PERIOD; -#ifdef FNM_EXTMATCH - flags |= FNM_EXTMATCH; -#endif -/*@=bitwisesigned@*/ - rc = fnmatch(s, con->appName, flags); - } else -#endif - rc = strcmp(s, con->appName); - return rc; -} - -/*@-compmempass@*/ /* FIX: item->option.longName kept, not dependent. */ -static int poptConfigLine(poptContext con, char * line) - /*@globals fileSystem, internalState @*/ - /*@modifies con, fileSystem, internalState @*/ -{ - char *b = NULL; - size_t nb = 0; - char * se = line; - const char * appName; - const char * entryType; - const char * opt; - struct poptItem_s item_buf; - poptItem item = &item_buf; - int i, j; - int rc = POPT_ERROR_BADCONFIG; - - if (con->appName == NULL) - goto exit; - - memset(item, 0, sizeof(*item)); - - appName = se; - while (*se != '\0' && !_isspaceptr(se)) se++; - if (*se == '\0') - goto exit; - else - *se++ = '\0'; - - if (configAppMatch(con, appName)) goto exit; - - while (*se != '\0' && _isspaceptr(se)) se++; - entryType = se; - while (*se != '\0' && !_isspaceptr(se)) se++; - if (*se != '\0') *se++ = '\0'; - - while (*se != '\0' && _isspaceptr(se)) se++; - if (*se == '\0') goto exit; - opt = se; - while (*se != '\0' && !_isspaceptr(se)) se++; - if (opt[0] == '-' && *se == '\0') goto exit; - if (*se != '\0') *se++ = '\0'; - - while (*se != '\0' && _isspaceptr(se)) se++; - if (opt[0] == '-' && *se == '\0') goto exit; - -/*@-temptrans@*/ /* FIX: line alias is saved */ - if (opt[0] == '-' && opt[1] == '-') - item->option.longName = opt + 2; - else if (opt[0] == '-' && opt[2] == '\0') - item->option.shortName = opt[1]; - else { - const char * fn = opt; - - /* XXX handle globs and directories in fn? */ - if ((rc = poptReadFile(fn, &b, &nb, POPT_READFILE_TRIMNEWLINES)) != 0) - goto exit; - if (b == NULL || nb == 0) - goto exit; - - /* Append remaining text to the interpolated file option text. */ - if (*se != '\0') { - size_t nse = strlen(se) + 1; - if ((b = realloc(b, (nb + nse))) == NULL) /* XXX can't happen */ - goto exit; - (void) stpcpy( stpcpy(&b[nb-1], " "), se); - nb += nse; - } - se = b; - - /* Use the basename of the path as the long option name. */ - { const char * longName = strrchr(fn, '/'); - if (longName != NULL) - longName++; - else - longName = fn; - if (longName == NULL) /* XXX can't happen. */ - goto exit; - /* Single character basenames are treated as short options. */ - if (longName[1] != '\0') - item->option.longName = longName; - else - item->option.shortName = longName[0]; - } - } -/*@=temptrans@*/ - - if (poptParseArgvString(se, &item->argc, &item->argv)) goto exit; - -/*@-modobserver@*/ - item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN; - for (i = 0, j = 0; i < item->argc; i++, j++) { - const char * f; - if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) { - f = item->argv[i] + sizeof("--POPTdesc="); - if (f[0] == '$' && f[1] == '"') f++; - item->option.descrip = f; - item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; - j--; - } else - if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) { - f = item->argv[i] + sizeof("--POPTargs="); - if (f[0] == '$' && f[1] == '"') f++; - item->option.argDescrip = f; - item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; - item->option.argInfo |= POPT_ARG_STRING; - j--; - } else - if (j != i) - item->argv[j] = item->argv[i]; - } - if (j != i) { - item->argv[j] = NULL; - item->argc = j; - } -/*@=modobserver@*/ - -/*@-nullstate@*/ /* FIX: item->argv[] may be NULL */ - if (!strcmp(entryType, "alias")) - rc = poptAddItem(con, item, 0); - else if (!strcmp(entryType, "exec")) - rc = poptAddItem(con, item, 1); -/*@=nullstate@*/ -exit: - rc = 0; /* XXX for now, always return success */ - if (b) - free(b); - return rc; -} -/*@=compmempass@*/ - -int poptReadConfigFile(poptContext con, const char * fn) -{ - char * b = NULL, *be; - size_t nb = 0; - const char *se; - char *t, *te; - int rc; - int xx; - - if ((rc = poptReadFile(fn, &b, &nb, POPT_READFILE_TRIMNEWLINES)) != 0) - return (errno == ENOENT ? 0 : rc); - if (b == NULL || nb == 0) - return POPT_ERROR_BADCONFIG; - - if ((t = malloc(nb + 1)) == NULL) - goto exit; - te = t; - - be = (b + nb); - for (se = b; se < be; se++) { - switch (*se) { - case '\n': - *te = '\0'; - te = t; - while (*te && _isspaceptr(te)) te++; - if (*te && *te != '#') - xx = poptConfigLine(con, te); - /*@switchbreak@*/ break; -/*@-usedef@*/ /* XXX *se may be uninitialized */ - case '\\': - *te = *se++; - /* \ at the end of a line does not insert a \n */ - if (se < be && *se != '\n') { - te++; - *te++ = *se; - } - /*@switchbreak@*/ break; - default: - *te++ = *se; - /*@switchbreak@*/ break; -/*@=usedef@*/ - } - } - - free(t); - rc = 0; - -exit: - if (b) - free(b); - return rc; -} - -int poptReadConfigFiles(poptContext con, const char * paths) -{ - char * buf = (paths ? xstrdup(paths) : NULL); - const char * p; - char * pe; - int rc = 0; /* assume success */ - - for (p = buf; p != NULL && *p != '\0'; p = pe) { - const char ** av = NULL; - int ac = 0; - int i; - int xx; - - /* locate start of next path element */ - pe = strchr(p, ':'); - if (pe != NULL && *pe == ':') - *pe++ = '\0'; - else - pe = (char *) (p + strlen(p)); - - xx = poptGlob(con, p, &ac, &av); - - /* work-off each resulting file from the path element */ - for (i = 0; i < ac; i++) { - const char * fn = av[i]; - if (av[i] == NULL) /* XXX can't happen */ - /*@innercontinue@*/ continue; - /* XXX should '@' attention be pushed into poptReadConfigFile? */ - if (p[0] == '@' && p[1] != '(') { - if (fn[0] == '@' && fn[1] != '(') - fn++; - xx = poptSaneFile(fn); - if (!xx && rc == 0) - rc = POPT_ERROR_BADCONFIG; - /*@innercontinue@*/ continue; - } - xx = poptReadConfigFile(con, fn); - if (xx && rc == 0) - rc = xx; - free((void *)av[i]); - av[i] = NULL; - } - free(av); - av = NULL; - } - -/*@-usedef@*/ - if (buf) - free(buf); -/*@=usedef@*/ - - return rc; -} - -int poptReadDefaultConfig(poptContext con, /*@unused@*/ UNUSED(int useEnv)) -{ - static const char _popt_sysconfdir[] = POPT_SYSCONFDIR "/popt"; - static const char _popt_etc[] = "/etc/popt"; - char * home; - struct stat sb; - int rc = 0; /* assume success */ - - if (con->appName == NULL) goto exit; - - if (strcmp(_popt_sysconfdir, _popt_etc)) { - rc = poptReadConfigFile(con, _popt_sysconfdir); - if (rc) goto exit; - } - - rc = poptReadConfigFile(con, _popt_etc); - if (rc) goto exit; - -#if defined(HAVE_GLOB_H) - if (!stat("/etc/popt.d", &sb) && S_ISDIR(sb.st_mode)) { - const char ** av = NULL; - int ac = 0; - int i; - - if ((rc = poptGlob(con, "/etc/popt.d/*", &ac, &av)) == 0) { - for (i = 0; rc == 0 && i < ac; i++) { - const char * fn = av[i]; - if (fn == NULL || strstr(fn, ".rpmnew") || strstr(fn, ".rpmsave")) - continue; - if (!stat(fn, &sb)) { - if (!S_ISREG(sb.st_mode) && !S_ISLNK(sb.st_mode)) - continue; - } - rc = poptReadConfigFile(con, fn); - free((void *)av[i]); - av[i] = NULL; - } - free(av); - av = NULL; - } - } - if (rc) goto exit; -#endif - - if ((home = getenv("HOME"))) { - char * fn = malloc(strlen(home) + 20); - if (fn != NULL) { - (void) stpcpy(stpcpy(fn, home), "/.popt"); - rc = poptReadConfigFile(con, fn); - free(fn); - } else - rc = POPT_ERROR_ERRNO; - if (rc) goto exit; - } - -exit: - return rc; -} - -poptContext -poptFini(poptContext con) -{ - return poptFreeContext(con); -} - -poptContext -poptInit(int argc, const char ** argv, - const struct poptOption * options, const char * configPaths) -{ - poptContext con = NULL; - const char * argv0; - - if (argv == NULL || argv[0] == NULL || options == NULL) - return con; - - if ((argv0 = strrchr(argv[0], '/')) != NULL) argv0++; - else argv0 = argv[0]; - - con = poptGetContext(argv0, argc, (const char **)argv, options, 0); - if (con != NULL&& poptReadConfigFiles(con, configPaths)) - con = poptFini(con); - - return con; -} diff --git a/ldb-2.0.8/third_party/popt/popthelp.c b/ldb-2.0.8/third_party/popt/popthelp.c deleted file mode 100644 index 0d8548b..0000000 --- a/ldb-2.0.8/third_party/popt/popthelp.c +++ /dev/null @@ -1,925 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ - -/** \ingroup popt - * \file popt/popthelp.c - */ - -/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist. */ - -#include "system.h" - -#define POPT_USE_TIOCGWINSZ -#ifdef POPT_USE_TIOCGWINSZ -#include -#endif - -#define POPT_WCHAR_HACK -#ifdef POPT_WCHAR_HACK -#include /* for mbsrtowcs */ -/*@access mbstate_t @*/ -#endif -#include "poptint.h" - -/*@access poptContext@*/ - -/** - * Display arguments. - * @param con context - * @param foo (unused) - * @param key option(s) - * @param arg (unused) - * @param data (unused) - */ -/*@exits@*/ -static void displayArgs(poptContext con, - /*@unused@*/ UNUSED(enum poptCallbackReason foo), - struct poptOption * key, - /*@unused@*/ UNUSED(const char * arg), - /*@unused@*/ UNUSED(void * data)) - /*@globals fileSystem@*/ - /*@modifies fileSystem@*/ -{ - if (key->shortName == '?') - poptPrintHelp(con, stdout, 0); - else - poptPrintUsage(con, stdout, 0); - -#if !defined(__LCLINT__) /* XXX keep both splint & valgrind happy */ - con = poptFreeContext(con); -#endif - exit(0); -} - -#ifdef NOTYET -/*@unchecked@*/ -static int show_option_defaults = 0; -#endif - -/** - * Empty table marker to enable displaying popt alias/exec options. - */ -/*@observer@*/ /*@unchecked@*/ -struct poptOption poptAliasOptions[] = { - POPT_TABLEEND -}; - -/** - * Auto help table options. - */ -/*@-castfcnptr@*/ -/*@observer@*/ /*@unchecked@*/ -struct poptOption poptHelpOptions[] = { - { NULL, '\0', POPT_ARG_CALLBACK, (void *)displayArgs, 0, NULL, NULL }, - { "help", '?', 0, NULL, (int)'?', N_("Show this help message"), NULL }, - { "usage", '\0', 0, NULL, (int)'u', N_("Display brief usage message"), NULL }, - POPT_TABLEEND -} ; - -/*@observer@*/ /*@unchecked@*/ -static struct poptOption poptHelpOptions2[] = { -/*@-readonlytrans@*/ - { NULL, '\0', POPT_ARG_INTL_DOMAIN, PACKAGE, 0, NULL, NULL}, -/*@=readonlytrans@*/ - { NULL, '\0', POPT_ARG_CALLBACK, (void *)displayArgs, 0, NULL, NULL }, - { "help", '?', 0, NULL, (int)'?', N_("Show this help message"), NULL }, - { "usage", '\0', 0, NULL, (int)'u', N_("Display brief usage message"), NULL }, -#ifdef NOTYET - { "defaults", '\0', POPT_ARG_NONE, &show_option_defaults, 0, - N_("Display option defaults in message"), NULL }, -#endif - { "", '\0', 0, NULL, 0, N_("Terminate options"), NULL }, - POPT_TABLEEND -} ; - -/*@observer@*/ /*@unchecked@*/ -struct poptOption * poptHelpOptionsI18N = poptHelpOptions2; -/*@=castfcnptr@*/ - -#define _POPTHELP_MAXLINE ((size_t)79) - -typedef struct columns_s { - size_t cur; - size_t max; -} * columns_t; - -/** - * Return no. of columns in output window. - * @param fp FILE - * @return no. of columns - */ -static size_t maxColumnWidth(FILE *fp) - /*@*/ -{ - size_t maxcols = _POPTHELP_MAXLINE; -#if defined(TIOCGWINSZ) - struct winsize ws; - int fdno = fileno(fp ? fp : stdout); - - memset(&ws, 0, sizeof(ws)); - if (fdno >= 0 && !ioctl(fdno, (unsigned long)TIOCGWINSZ, &ws)) { - size_t ws_col = (size_t)ws.ws_col; - if (ws_col > maxcols && ws_col < (size_t)256) - maxcols = ws_col - 1; - } -#endif - return maxcols; -} - -/** - * Determine number of display characters in a string. - * @param s string - * @return no. of display characters. - */ -static inline size_t stringDisplayWidth(const char *s) - /*@*/ -{ - size_t n = strlen(s); -#ifdef POPT_WCHAR_HACK - mbstate_t t; - - memset ((void *)&t, 0, sizeof (t)); /* In initial state. */ - /* Determine number of display characters. */ - n = mbsrtowcs (NULL, &s, n, &t); -#else - n = 0; - for (; *s; s = POPT_next_char(s)) - n++; -#endif - - return n; -} - -/** - * @param opt option(s) - */ -/*@observer@*/ /*@null@*/ static const char * -getTableTranslationDomain(/*@null@*/ const struct poptOption *opt) - /*@*/ -{ - if (opt != NULL) - for (; opt->longName || opt->shortName || opt->arg; opt++) { - if (opt->argInfo == POPT_ARG_INTL_DOMAIN) - return opt->arg; - } - return NULL; -} - -/** - * @param opt option(s) - * @param translation_domain translation domain - */ -/*@observer@*/ /*@null@*/ static const char * -getArgDescrip(const struct poptOption * opt, - /*@-paramuse@*/ /* FIX: i18n macros disabled with lclint */ - /*@null@*/ const char * translation_domain) - /*@=paramuse@*/ - /*@*/ -{ - if (!poptArgType(opt)) return NULL; - - if (poptArgType(opt) == POPT_ARG_MAINCALL) - return opt->argDescrip; - if (poptArgType(opt) == POPT_ARG_ARGV) - return opt->argDescrip; - - if (opt->argDescrip) { - /* Some strings need popt library, not application, i18n domain. */ - if (opt == (poptHelpOptions + 1) - || opt == (poptHelpOptions + 2) - || !strcmp(opt->argDescrip, N_("Help options:")) - || !strcmp(opt->argDescrip, N_("Options implemented via popt alias/exec:"))) - return POPT_(opt->argDescrip); - - /* Use the application i18n domain. */ - return D_(translation_domain, opt->argDescrip); - } - - switch (poptArgType(opt)) { - case POPT_ARG_NONE: return POPT_("NONE"); -#ifdef DYING - case POPT_ARG_VAL: return POPT_("VAL"); -#else - case POPT_ARG_VAL: return NULL; -#endif - case POPT_ARG_INT: return POPT_("INT"); - case POPT_ARG_SHORT: return POPT_("SHORT"); - case POPT_ARG_LONG: return POPT_("LONG"); - case POPT_ARG_LONGLONG: return POPT_("LONGLONG"); - case POPT_ARG_STRING: return POPT_("STRING"); - case POPT_ARG_FLOAT: return POPT_("FLOAT"); - case POPT_ARG_DOUBLE: return POPT_("DOUBLE"); - case POPT_ARG_MAINCALL: return NULL; - case POPT_ARG_ARGV: return NULL; - default: return POPT_("ARG"); - } -} - -/** - * Display default value for an option. - * @param lineLength display positions remaining - * @param opt option(s) - * @param translation_domain translation domain - * @return - */ -static /*@only@*/ /*@null@*/ char * -singleOptionDefaultValue(size_t lineLength, - const struct poptOption * opt, - /*@-paramuse@*/ /* FIX: i18n macros disabled with lclint */ - /*@null@*/ const char * translation_domain) - /*@=paramuse@*/ - /*@*/ -{ - const char * defstr = D_(translation_domain, "default"); - char * le = malloc(4*lineLength + 1); - char * l = le; - - if (le == NULL) return NULL; /* XXX can't happen */ - *le = '\0'; - *le++ = '('; - le = stpcpy(le, defstr); - *le++ = ':'; - *le++ = ' '; - if (opt->arg) { /* XXX programmer error */ - poptArg arg = { .ptr = opt->arg }; - switch (poptArgType(opt)) { - case POPT_ARG_VAL: - case POPT_ARG_INT: - le += sprintf(le, "%d", arg.intp[0]); - break; - case POPT_ARG_SHORT: - le += sprintf(le, "%hd", arg.shortp[0]); - break; - case POPT_ARG_LONG: - le += sprintf(le, "%ld", arg.longp[0]); - break; - case POPT_ARG_LONGLONG: - le += sprintf(le, "%lld", arg.longlongp[0]); - break; - case POPT_ARG_FLOAT: - { double aDouble = (double) arg.floatp[0]; - le += sprintf(le, "%g", aDouble); - } break; - case POPT_ARG_DOUBLE: - le += sprintf(le, "%g", arg.doublep[0]); - break; - case POPT_ARG_MAINCALL: - le += sprintf(le, "%p", opt->arg); - break; - case POPT_ARG_ARGV: - le += sprintf(le, "%p", opt->arg); - break; - case POPT_ARG_STRING: - { const char * s = arg.argv[0]; - if (s == NULL) - le = stpcpy(le, "null"); - else { - size_t limit = 4*lineLength - (le - l) - sizeof("\"\")"); - size_t slen; - *le++ = '"'; - strncpy(le, s, limit); le[limit] = '\0'; le += (slen = strlen(le)); - if (slen == limit && s[limit]) - le[-1] = le[-2] = le[-3] = '.'; - *le++ = '"'; - } - } break; - case POPT_ARG_NONE: - default: - l = _free(l); - return NULL; - /*@notreached@*/ break; - } - } - *le++ = ')'; - *le = '\0'; - - return l; -} - -/** - * Display help text for an option. - * @param fp output file handle - * @param columns output display width control - * @param opt option(s) - * @param translation_domain translation domain - */ -static void singleOptionHelp(FILE * fp, columns_t columns, - const struct poptOption * opt, - /*@null@*/ const char * translation_domain) - /*@globals fileSystem @*/ - /*@modifies fp, fileSystem @*/ -{ - size_t maxLeftCol = columns->cur; - size_t indentLength = maxLeftCol + 5; - size_t lineLength = columns->max - indentLength; - const char * help = D_(translation_domain, opt->descrip); - const char * argDescrip = getArgDescrip(opt, translation_domain); - /* Display shortName iff printable non-space. */ - int prtshort = (int)(isprint((int)opt->shortName) && opt->shortName != ' '); - size_t helpLength; - char * defs = NULL; - char * left; - size_t nb = maxLeftCol + 1; - int displaypad = 0; - int xx; - - /* Make sure there's more than enough room in target buffer. */ - if (opt->longName) nb += strlen(opt->longName); - if (F_ISSET(opt, TOGGLE)) nb += sizeof("[no]") - 1; - if (argDescrip) nb += strlen(argDescrip); - - left = malloc(nb); - if (left == NULL) return; /* XXX can't happen */ - left[0] = '\0'; - left[maxLeftCol] = '\0'; - -#define prtlong (opt->longName != NULL) /* XXX splint needs a clue */ - if (!(prtshort || prtlong)) - goto out; - if (prtshort && prtlong) { - char *dash = F_ISSET(opt, ONEDASH) ? "-" : "--"; - left[0] = '-'; - left[1] = opt->shortName; - (void) stpcpy(stpcpy(stpcpy(left+2, ", "), dash), opt->longName); - } else if (prtshort) { - left[0] = '-'; - left[1] = opt->shortName; - left[2] = '\0'; - } else if (prtlong) { - /* XXX --long always padded for alignment with/without "-X, ". */ - char *dash = poptArgType(opt) == POPT_ARG_MAINCALL ? "" - : (F_ISSET(opt, ONEDASH) ? "-" : "--"); - const char *longName = opt->longName; - const char *toggle; - if (F_ISSET(opt, TOGGLE)) { - toggle = "[no]"; - if (longName[0] == 'n' && longName[1] == 'o') { - longName += sizeof("no") - 1; - if (longName[0] == '-') - longName++; - } - } else - toggle = ""; - (void) stpcpy(stpcpy(stpcpy(stpcpy(left, " "), dash), toggle), longName); - } -#undef prtlong - - if (argDescrip) { - char * le = left + strlen(left); - - if (F_ISSET(opt, OPTIONAL)) - *le++ = '['; - - /* Choose type of output */ - if (F_ISSET(opt, SHOW_DEFAULT)) { - defs = singleOptionDefaultValue(lineLength, opt, translation_domain); - if (defs) { - char * t = malloc((help ? strlen(help) : 0) + - strlen(defs) + sizeof(" ")); - if (t) { - char * te = t; - if (help) - te = stpcpy(te, help); - *te++ = ' '; - strcpy(te, defs); - defs = _free(defs); - defs = t; - } - } - } - - if (opt->argDescrip == NULL) { - switch (poptArgType(opt)) { - case POPT_ARG_NONE: - break; - case POPT_ARG_VAL: -#ifdef NOTNOW /* XXX pug ugly nerdy output */ - { long aLong = opt->val; - int ops = F_ISSET(opt, LOGICALOPS); - int negate = F_ISSET(opt, NOT); - - /* Don't bother displaying typical values */ - if (!ops && (aLong == 0L || aLong == 1L || aLong == -1L)) - break; - *le++ = '['; - switch (ops) { - case POPT_ARGFLAG_OR: - *le++ = '|'; - /*@innerbreak@*/ break; - case POPT_ARGFLAG_AND: - *le++ = '&'; - /*@innerbreak@*/ break; - case POPT_ARGFLAG_XOR: - *le++ = '^'; - /*@innerbreak@*/ break; - default: - /*@innerbreak@*/ break; - } - *le++ = (opt->longName != NULL ? '=' : ' '); - if (negate) *le++ = '~'; - /*@-formatconst@*/ - le += sprintf(le, (ops ? "0x%lx" : "%ld"), aLong); - /*@=formatconst@*/ - *le++ = ']'; - } -#endif - break; - case POPT_ARG_INT: - case POPT_ARG_SHORT: - case POPT_ARG_LONG: - case POPT_ARG_LONGLONG: - case POPT_ARG_FLOAT: - case POPT_ARG_DOUBLE: - case POPT_ARG_STRING: - *le++ = (opt->longName != NULL ? '=' : ' '); - le = stpcpy(le, argDescrip); - break; - default: - break; - } - } else { - char *leo; - - /* XXX argDescrip[0] determines "--foo=bar" or "--foo bar". */ - if (!strchr(" =(", argDescrip[0])) - *le++ = ((poptArgType(opt) == POPT_ARG_MAINCALL) ? ' ' : - (poptArgType(opt) == POPT_ARG_ARGV) ? ' ' : '='); - le = stpcpy(leo = le, argDescrip); - - /* Adjust for (possible) wide characters. */ - displaypad = (int)((le - leo) - stringDisplayWidth(argDescrip)); - } - if (F_ISSET(opt, OPTIONAL)) - *le++ = ']'; - *le = '\0'; - } - - if (help) - xx = POPT_fprintf(fp," %-*s ", (int)(maxLeftCol+displaypad), left); - else { - xx = POPT_fprintf(fp," %s\n", left); - goto out; - } - - left = _free(left); - if (defs) - help = defs; - - helpLength = strlen(help); - while (helpLength > lineLength) { - const char * ch; - char format[16]; - - ch = help + lineLength - 1; - while (ch > help && !_isspaceptr(ch)) - ch = POPT_prev_char(ch); - if (ch == help) break; /* give up */ - while (ch > (help + 1) && _isspaceptr(ch)) - ch = POPT_prev_char (ch); - ch = POPT_next_char(ch); - - /* - * XXX strdup is necessary to add NUL terminator so that an unknown - * no. of (possible) multi-byte characters can be displayed. - */ - { char * fmthelp = xstrdup(help); - if (fmthelp) { - fmthelp[ch - help] = '\0'; - sprintf(format, "%%s\n%%%ds", (int) indentLength); - /*@-formatconst@*/ - xx = POPT_fprintf(fp, format, fmthelp, " "); - /*@=formatconst@*/ - free(fmthelp); - } - } - - help = ch; - while (_isspaceptr(help) && *help) - help = POPT_next_char(help); - helpLength = strlen(help); - } - - if (helpLength) fprintf(fp, "%s\n", help); - help = NULL; - -out: - /*@-dependenttrans@*/ - defs = _free(defs); - /*@=dependenttrans@*/ - left = _free(left); -} - -/** - * Find display width for longest argument string. - * @param opt option(s) - * @param translation_domain translation domain - * @return display width - */ -static size_t maxArgWidth(const struct poptOption * opt, - /*@null@*/ const char * translation_domain) - /*@*/ -{ - size_t max = 0; - size_t len = 0; - const char * argDescrip; - - if (opt != NULL) - while (opt->longName || opt->shortName || opt->arg) { - if (poptArgType(opt) == POPT_ARG_INCLUDE_TABLE) { - if (opt->arg) /* XXX program error */ - len = maxArgWidth(opt->arg, translation_domain); - if (len > max) max = len; - } else if (!F_ISSET(opt, DOC_HIDDEN)) { - len = sizeof(" ")-1; - /* XXX --long always padded for alignment with/without "-X, ". */ - len += sizeof("-X, ")-1; - if (opt->longName) { - len += (F_ISSET(opt, ONEDASH) ? sizeof("-") : sizeof("--")) - 1; - len += strlen(opt->longName); - } - - argDescrip = getArgDescrip(opt, translation_domain); - - if (argDescrip) { - - /* XXX argDescrip[0] determines "--foo=bar" or "--foo bar". */ - if (!strchr(" =(", argDescrip[0])) len += sizeof("=")-1; - - /* Adjust for (possible) wide characters. */ - len += stringDisplayWidth(argDescrip); - } - - if (F_ISSET(opt, OPTIONAL)) len += sizeof("[]")-1; - if (len > max) max = len; - } - opt++; - } - - return max; -} - -/** - * Display popt alias and exec help. - * @param fp output file handle - * @param items alias/exec array - * @param nitems no. of alias/exec entries - * @param columns output display width control - * @param translation_domain translation domain - */ -static void itemHelp(FILE * fp, - /*@null@*/ poptItem items, int nitems, - columns_t columns, - /*@null@*/ const char * translation_domain) - /*@globals fileSystem @*/ - /*@modifies fp, fileSystem @*/ -{ - poptItem item; - int i; - - if (items != NULL) - for (i = 0, item = items; i < nitems; i++, item++) { - const struct poptOption * opt; - opt = &item->option; - if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN)) - singleOptionHelp(fp, columns, opt, translation_domain); - } -} - -/** - * Display help text for a table of options. - * @param con context - * @param fp output file handle - * @param table option(s) - * @param columns output display width control - * @param translation_domain translation domain - */ -static void singleTableHelp(poptContext con, FILE * fp, - /*@null@*/ const struct poptOption * table, - columns_t columns, - /*@null@*/ const char * translation_domain) - /*@globals fileSystem @*/ - /*@modifies fp, columns->cur, fileSystem @*/ -{ - const struct poptOption * opt; - const char *sub_transdom; - int xx; - - if (table == poptAliasOptions) { - itemHelp(fp, con->aliases, con->numAliases, columns, NULL); - itemHelp(fp, con->execs, con->numExecs, columns, NULL); - return; - } - - if (table != NULL) - for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) { - if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN)) - singleOptionHelp(fp, columns, opt, translation_domain); - } - - if (table != NULL) - for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) { - if (poptArgType(opt) != POPT_ARG_INCLUDE_TABLE) - continue; - sub_transdom = getTableTranslationDomain(opt->arg); - if (sub_transdom == NULL) - sub_transdom = translation_domain; - - /* If no popt aliases/execs, skip poptAliasOption processing. */ - if (opt->arg == poptAliasOptions && !(con->numAliases || con->numExecs)) - continue; - if (opt->descrip) - xx = POPT_fprintf(fp, "\n%s\n", D_(sub_transdom, opt->descrip)); - - singleTableHelp(con, fp, opt->arg, columns, sub_transdom); - } -} - -/** - * @param con context - * @param fp output file handle - */ -static size_t showHelpIntro(poptContext con, FILE * fp) - /*@globals fileSystem @*/ - /*@modifies fp, fileSystem @*/ -{ - size_t len = (size_t)6; - int xx; - - xx = POPT_fprintf(fp, POPT_("Usage:")); - if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) { - struct optionStackEntry * os = con->optionStack; - const char * fn = (os->argv ? os->argv[0] : NULL); - if (fn == NULL) return len; - if (strchr(fn, '/')) fn = strrchr(fn, '/') + 1; - /* XXX POPT_fprintf not needed for argv[0] display. */ - fprintf(fp, " %s", fn); - len += strlen(fn) + 1; - } - - return len; -} - -void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ UNUSED(int flags)) -{ - columns_t columns = calloc((size_t)1, sizeof(*columns)); - int xx; - - (void) showHelpIntro(con, fp); - if (con->otherHelp) - xx = POPT_fprintf(fp, " %s\n", con->otherHelp); - else - xx = POPT_fprintf(fp, " %s\n", POPT_("[OPTION...]")); - - if (columns) { - columns->cur = maxArgWidth(con->options, NULL); - columns->max = maxColumnWidth(fp); - singleTableHelp(con, fp, con->options, columns, NULL); - free(columns); - } -} - -/** - * Display usage text for an option. - * @param fp output file handle - * @param columns output display width control - * @param opt option(s) - * @param translation_domain translation domain - */ -static size_t singleOptionUsage(FILE * fp, columns_t columns, - const struct poptOption * opt, - /*@null@*/ const char *translation_domain) - /*@globals fileSystem @*/ - /*@modifies fp, columns->cur, fileSystem @*/ -{ - size_t len = sizeof(" []")-1; - const char * argDescrip = getArgDescrip(opt, translation_domain); - /* Display shortName iff printable non-space. */ - int prtshort = (int)(isprint((int)opt->shortName) && opt->shortName != ' '); - -#define prtlong (opt->longName != NULL) /* XXX splint needs a clue */ - if (!(prtshort || prtlong)) - return columns->cur; - - len = sizeof(" []")-1; - if (prtshort) - len += sizeof("-c")-1; - if (prtlong) { - if (prtshort) len += sizeof("|")-1; - len += (F_ISSET(opt, ONEDASH) ? sizeof("-") : sizeof("--")) - 1; - len += strlen(opt->longName); - } - - if (argDescrip) { - - /* XXX argDescrip[0] determines "--foo=bar" or "--foo bar". */ - if (!strchr(" =(", argDescrip[0])) len += sizeof("=")-1; - - /* Adjust for (possible) wide characters. */ - len += stringDisplayWidth(argDescrip); - } - - if ((columns->cur + len) > columns->max) { - fprintf(fp, "\n "); - columns->cur = (size_t)7; - } - - fprintf(fp, " ["); - if (prtshort) - fprintf(fp, "-%c", opt->shortName); - if (prtlong) - fprintf(fp, "%s%s%s", - (prtshort ? "|" : ""), - (F_ISSET(opt, ONEDASH) ? "-" : "--"), - opt->longName); -#undef prtlong - - if (argDescrip) { - /* XXX argDescrip[0] determines "--foo=bar" or "--foo bar". */ - if (!strchr(" =(", argDescrip[0])) fprintf(fp, "="); - fprintf(fp, "%s", argDescrip); - } - fprintf(fp, "]"); - - return columns->cur + len + 1; -} - -/** - * Display popt alias and exec usage. - * @param fp output file handle - * @param columns output display width control - * @param item alias/exec array - * @param nitems no. of ara/exec entries - * @param translation_domain translation domain - */ -static size_t itemUsage(FILE * fp, columns_t columns, - /*@null@*/ poptItem item, int nitems, - /*@null@*/ const char * translation_domain) - /*@globals fileSystem @*/ - /*@modifies fp, columns->cur, fileSystem @*/ -{ - int i; - - if (item != NULL) - for (i = 0; i < nitems; i++, item++) { - const struct poptOption * opt; - opt = &item->option; - if (poptArgType(opt) == POPT_ARG_INTL_DOMAIN) { - translation_domain = (const char *)opt->arg; - } else - if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN)) { - columns->cur = singleOptionUsage(fp, columns, opt, translation_domain); - } - } - - return columns->cur; -} - -/** - * Keep track of option tables already processed. - */ -typedef struct poptDone_s { - int nopts; - int maxopts; -/*@null@*/ - const void ** opts; -} * poptDone; - -/** - * Display usage text for a table of options. - * @param con context - * @param fp output file handle - * @param columns output display width control - * @param opt option(s) - * @param translation_domain translation domain - * @param done tables already processed - * @return - */ -static size_t singleTableUsage(poptContext con, FILE * fp, columns_t columns, - /*@null@*/ const struct poptOption * opt, - /*@null@*/ const char * translation_domain, - /*@null@*/ poptDone done) - /*@globals fileSystem @*/ - /*@modifies fp, columns->cur, done, fileSystem @*/ -{ - if (opt != NULL) - for (; (opt->longName || opt->shortName || opt->arg) ; opt++) { - if (poptArgType(opt) == POPT_ARG_INTL_DOMAIN) { - translation_domain = (const char *)opt->arg; - } else - if (poptArgType(opt) == POPT_ARG_INCLUDE_TABLE) { - if (done) { - int i = 0; - if (done->opts != NULL) - for (i = 0; i < done->nopts; i++) { - const void * that = done->opts[i]; - if (that == NULL || that != opt->arg) - /*@innercontinue@*/ continue; - /*@innerbreak@*/ break; - } - /* Skip if this table has already been processed. */ - if (opt->arg == NULL || i < done->nopts) - continue; - if (done->opts != NULL && done->nopts < done->maxopts) - done->opts[done->nopts++] = (const void *) opt->arg; - } - columns->cur = singleTableUsage(con, fp, columns, opt->arg, - translation_domain, done); - } else - if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN)) { - columns->cur = singleOptionUsage(fp, columns, opt, translation_domain); - } - } - - return columns->cur; -} - -/** - * Return concatenated short options for display. - * @todo Sub-tables should be recursed. - * @param opt option(s) - * @param fp output file handle - * @retval str concatenation of short options - * @return length of display string - */ -static size_t showShortOptions(const struct poptOption * opt, FILE * fp, - /*@null@*/ char * str) - /*@globals fileSystem @*/ - /*@modifies str, *fp, fileSystem @*/ - /*@requires maxRead(str) >= 0 @*/ -{ - /* bufsize larger then the ascii set, lazy allocation on top level call. */ - size_t nb = (size_t)300; - char * s = (str != NULL ? str : calloc((size_t)1, nb)); - size_t len = (size_t)0; - - if (s == NULL) - return 0; - - if (opt != NULL) - for (; (opt->longName || opt->shortName || opt->arg); opt++) { - if (!F_ISSET(opt, DOC_HIDDEN) && opt->shortName && !poptArgType(opt)) - { - /* Display shortName iff unique printable non-space. */ - if (!strchr(s, opt->shortName) && isprint((int)opt->shortName) - && opt->shortName != ' ') - s[strlen(s)] = opt->shortName; - } else if (poptArgType(opt) == POPT_ARG_INCLUDE_TABLE) - if (opt->arg) /* XXX program error */ - len = showShortOptions(opt->arg, fp, s); - } - - /* On return to top level, print the short options, return print length. */ - if (s != str && *s != '\0') { - fprintf(fp, " [-%s]", s); - len = strlen(s) + sizeof(" [-]")-1; - } -/*@-temptrans@*/ /* LCL: local s, not str arg, is being freed. */ - if (s != str) - free(s); -/*@=temptrans@*/ - return len; -} - -void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ UNUSED(int flags)) -{ - columns_t columns = calloc((size_t)1, sizeof(*columns)); - struct poptDone_s done_buf; - poptDone done = &done_buf; - - memset(done, 0, sizeof(*done)); - done->nopts = 0; - done->maxopts = 64; - if (columns) { - columns->cur = done->maxopts * sizeof(*done->opts); - columns->max = maxColumnWidth(fp); - done->opts = calloc((size_t)1, columns->cur); - /*@-keeptrans@*/ - if (done->opts != NULL) - done->opts[done->nopts++] = (const void *) con->options; - /*@=keeptrans@*/ - - columns->cur = showHelpIntro(con, fp); - columns->cur += showShortOptions(con->options, fp, NULL); - columns->cur = singleTableUsage(con, fp, columns, con->options, NULL, done); - columns->cur = itemUsage(fp, columns, con->aliases, con->numAliases, NULL); - columns->cur = itemUsage(fp, columns, con->execs, con->numExecs, NULL); - - if (con->otherHelp) { - columns->cur += strlen(con->otherHelp) + 1; - if (columns->cur > columns->max) fprintf(fp, "\n "); - fprintf(fp, " %s", con->otherHelp); - } - - fprintf(fp, "\n"); - if (done->opts != NULL) - free(done->opts); - free(columns); - } -} - -void poptSetOtherOptionHelp(poptContext con, const char * text) -{ - con->otherHelp = _free(con->otherHelp); - con->otherHelp = xstrdup(text); -} diff --git a/ldb-2.0.8/third_party/popt/poptint.c b/ldb-2.0.8/third_party/popt/poptint.c deleted file mode 100644 index 1af46ff..0000000 --- a/ldb-2.0.8/third_party/popt/poptint.c +++ /dev/null @@ -1,199 +0,0 @@ -#include "system.h" -#include -#include "poptint.h" - -/* Any pair of 32 bit hashes can be used. lookup3.c generates pairs, will do. */ -#define _JLU3_jlu32lpair 1 -#define jlu32lpair poptJlu32lpair -#include "lookup3.c" - -/*@-varuse +charint +ignoresigns @*/ -/*@unchecked@*/ /*@observer@*/ -static const unsigned char utf8_skip_data[256] = { - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1 -}; -/*@=varuse =charint =ignoresigns @*/ - -const char * -POPT_prev_char (const char *str) -{ - const char *p = str; - - while (1) { - p--; - if (((unsigned)*p & 0xc0) != (unsigned)0x80) - return p; - } -} - -const char * -POPT_next_char (const char *str) -{ - const char *p = str; - - while (*p != '\0') { - p++; - if (((unsigned)*p & 0xc0) != (unsigned)0x80) - break; - } - return p; -} - -#if !defined(POPT_fprintf) /* XXX lose all the goop ... */ - -#if defined(HAVE_DCGETTEXT) && !defined(__LCLINT__) -/* - * Rebind a "UTF-8" codeset for popt's internal use. - */ -char * -POPT_dgettext(const char * dom, const char * str) -{ - char * codeset = NULL; - char * retval = NULL; - - if (!dom) - dom = textdomain(NULL); - codeset = bind_textdomain_codeset(dom, NULL); - bind_textdomain_codeset(dom, "UTF-8"); - retval = dgettext(dom, str); - bind_textdomain_codeset(dom, codeset); - - return retval; -} -#endif - -#ifdef HAVE_ICONV -/** - * Return malloc'd string converted from UTF-8 to current locale. - * @param istr input string (UTF-8 encoding assumed) - * @return localized string - */ -static /*@only@*/ /*@null@*/ char * -strdup_locale_from_utf8 (/*@null@*/ char * istr) - /*@*/ -{ - char * codeset = NULL; - char * ostr = NULL; - iconv_t cd; - - if (istr == NULL) - return NULL; - -#ifdef HAVE_LANGINFO_H - codeset = nl_langinfo ((nl_item)CODESET); -#endif - - if (codeset != NULL && strcmp(codeset, "UTF-8") != 0 - && (cd = iconv_open(codeset, "UTF-8")) != (iconv_t)-1) - { - char * shift_pin = NULL; - size_t db = strlen(istr); -/*@owned@*/ - char * dstr = malloc((db + 1) * sizeof(*dstr)); - char * pin = istr; - char * pout = dstr; - size_t ib = db; - size_t ob = db; - size_t err; - - if (dstr == NULL) - return NULL; - err = iconv(cd, NULL, NULL, NULL, NULL); - while (1) { - *pout = '\0'; - err = iconv(cd, &pin, &ib, &pout, &ob); - if (err != (size_t)-1) { - if (shift_pin == NULL) { - shift_pin = pin; - pin = NULL; - ib = 0; - continue; - } - } else - switch (errno) { - case E2BIG: - { size_t used = (size_t)(pout - dstr); - db *= 2; - dstr = realloc(dstr, (db + 1) * sizeof(*dstr)); - if (dstr != NULL) { - pout = dstr + used; - ob = db - used; - continue; - } - } /*@switchbreak@*/ break; - case EINVAL: - case EILSEQ: - default: - /*@switchbreak@*/ break; - } - break; - } - (void) iconv_close(cd); - *pout = '\0'; - ostr = xstrdup(dstr); - free(dstr); - } else - ostr = xstrdup(istr); - - return ostr; -} -#endif - -int -POPT_fprintf (FILE * stream, const char * format, ...) -{ - char * b = NULL, * ob = NULL; - int rc; - va_list ap; - -#if defined(HAVE_VASPRINTF) && !defined(__LCLINT__) - va_start(ap, format); - if ((rc = vasprintf(&b, format, ap)) < 0) - b = NULL; - va_end(ap); -#else - size_t nb = (size_t)1; - - /* HACK: add +1 to the realloc no. of bytes "just in case". */ - /* XXX Likely unneeded, the issues wrto vsnprintf(3) return b0rkage have - * to do with whether the final '\0' is counted (or not). The code - * below already adds +1 for the (possibly already counted) trailing NUL. - */ - while ((b = realloc(b, nb+1)) != NULL) { - va_start(ap, format); - rc = vsnprintf(b, nb, format, ap); - va_end(ap); - if (rc > -1) { /* glibc 2.1 */ - if ((size_t)rc < nb) - break; - nb = (size_t)(rc + 1); /* precise buffer length known */ - } else /* glibc 2.0 */ - nb += (nb < (size_t)100 ? (size_t)100 : nb); - ob = b; - } -#endif - - rc = 0; - if (b != NULL) { -#ifdef HAVE_ICONV - ob = strdup_locale_from_utf8(b); - if (ob != NULL) { - rc = fprintf(stream, "%s", ob); - free(ob); - } else -#endif - rc = fprintf(stream, "%s", b); - free (b); - } - - return rc; -} - -#endif /* !defined(POPT_fprintf) */ diff --git a/ldb-2.0.8/third_party/popt/poptint.h b/ldb-2.0.8/third_party/popt/poptint.h deleted file mode 100644 index 80cbaca..0000000 --- a/ldb-2.0.8/third_party/popt/poptint.h +++ /dev/null @@ -1,222 +0,0 @@ -/** \ingroup popt - * \file popt/poptint.h - */ - -/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist. */ - -#ifndef H_POPTINT -#define H_POPTINT - -#include - -/** - * Wrapper to free(3), hides const compilation noise, permit NULL, return NULL. - * @param p memory to free - * @retval NULL always - */ -/*@unused@*/ static inline /*@null@*/ void * -_free(/*@only@*/ /*@null@*/ const void * p) - /*@modifies p @*/ -{ - if (p != NULL) free((void *)p); - return NULL; -} - -/* Bit mask macros. */ -/*@-exporttype -redef @*/ -typedef unsigned int __pbm_bits; -/*@=exporttype =redef @*/ -#define __PBM_NBITS (8 * sizeof (__pbm_bits)) -#define __PBM_IX(d) ((d) / __PBM_NBITS) -#define __PBM_MASK(d) ((__pbm_bits) 1 << (((unsigned)(d)) % __PBM_NBITS)) -/*@-exporttype -redef @*/ -typedef struct { - __pbm_bits bits[1]; -} pbm_set; -/*@=exporttype =redef @*/ -#define __PBM_BITS(set) ((set)->bits) - -#define PBM_ALLOC(d) calloc(__PBM_IX (d) + 1, sizeof(__pbm_bits)) -#define PBM_FREE(s) _free(s); -#define PBM_SET(d, s) (__PBM_BITS (s)[__PBM_IX (d)] |= __PBM_MASK (d)) -#define PBM_CLR(d, s) (__PBM_BITS (s)[__PBM_IX (d)] &= ~__PBM_MASK (d)) -#define PBM_ISSET(d, s) ((__PBM_BITS (s)[__PBM_IX (d)] & __PBM_MASK (d)) != 0) - -extern void poptJlu32lpair(/*@null@*/ const void *key, size_t size, - uint32_t *pc, uint32_t *pb) - /*@modifies *pc, *pb@*/; - -/** \ingroup popt - * Typedef's for string and array of strings. - */ -/*@-exporttype@*/ -typedef const char * poptString; -typedef poptString * poptArgv; -/*@=exporttype@*/ - -/** \ingroup popt - * A union to simplify opt->arg access without casting. - */ -/*@-exporttype -fielduse@*/ -typedef union poptArg_u { -/*@shared@*/ - void * ptr; - int * intp; - short * shortp; - long * longp; - long long * longlongp; - float * floatp; - double * doublep; - const char ** argv; - poptCallbackType cb; -/*@shared@*/ - poptOption opt; -} poptArg; -/*@=exporttype =fielduse@*/ - -/*@-exportvar@*/ -/*@unchecked@*/ -extern unsigned int _poptArgMask; -/*@unchecked@*/ -extern unsigned int _poptGroupMask; -/*@=exportvar@*/ - -#define poptArgType(_opt) ((_opt)->argInfo & _poptArgMask) -#define poptGroup(_opt) ((_opt)->argInfo & _poptGroupMask) - -#define F_ISSET(_opt, _FLAG) ((_opt)->argInfo & POPT_ARGFLAG_##_FLAG) -#define LF_ISSET(_FLAG) (argInfo & POPT_ARGFLAG_##_FLAG) -#define CBF_ISSET(_opt, _FLAG) ((_opt)->argInfo & POPT_CBFLAG_##_FLAG) - -/* XXX sick hack to preserve pretense of a popt-1.x ABI. */ -#define poptSubstituteHelpI18N(opt) \ - { /*@-observertrans@*/ \ - if ((opt) == poptHelpOptions) (opt) = poptHelpOptionsI18N; \ - /*@=observertrans@*/ } - -struct optionStackEntry { - int argc; -/*@only@*/ /*@null@*/ - poptArgv argv; -/*@only@*/ /*@null@*/ - pbm_set * argb; - int next; -/*@only@*/ /*@null@*/ - char * nextArg; -/*@observer@*/ /*@null@*/ - const char * nextCharArg; -/*@dependent@*/ /*@null@*/ - poptItem currAlias; - int stuffed; -}; - -struct poptContext_s { - struct optionStackEntry optionStack[POPT_OPTION_DEPTH]; -/*@dependent@*/ - struct optionStackEntry * os; -/*@owned@*/ /*@null@*/ - poptArgv leftovers; - int numLeftovers; - int nextLeftover; -/*@keep@*/ - const struct poptOption * options; - int restLeftover; -/*@only@*/ /*@null@*/ - const char * appName; -/*@only@*/ /*@null@*/ - poptItem aliases; - int numAliases; - unsigned int flags; -/*@owned@*/ /*@null@*/ - poptItem execs; - int numExecs; -/*@only@*/ /*@null@*/ - poptArgv finalArgv; - int finalArgvCount; - int finalArgvAlloced; -/*@null@*/ - int (*maincall) (int argc, const char **argv); -/*@dependent@*/ /*@null@*/ - poptItem doExec; -/*@only@*/ /*@null@*/ - const char * execPath; - int execAbsolute; -/*@only@*/ /*@relnull@*/ - const char * otherHelp; -/*@null@*/ - pbm_set * arg_strip; -}; - -#if defined(POPT_fprintf) -#define POPT_dgettext dgettext -#else -#ifdef HAVE_ICONV -#include -#if defined(__LCLINT__) -/*@-declundef -incondefs @*/ -extern /*@only@*/ iconv_t iconv_open(const char *__tocode, const char *__fromcode) - /*@*/; - -extern size_t iconv(iconv_t __cd, /*@null@*/ char ** __inbuf, - /*@null@*/ /*@out@*/ size_t * __inbytesleft, - /*@null@*/ /*@out@*/ char ** __outbuf, - /*@null@*/ /*@out@*/ size_t * __outbytesleft) - /*@modifies __cd, - *__inbuf, *__inbytesleft, *__outbuf, *__outbytesleft @*/; - -extern int iconv_close(/*@only@*/ iconv_t __cd) - /*@modifies __cd @*/; -/*@=declundef =incondefs @*/ -#endif -#endif - -#ifdef HAVE_LANGINFO_H -#include -#if defined(__LCLINT__) -/*@-declundef -incondefs @*/ -extern char *nl_langinfo (nl_item __item) - /*@*/; -/*@=declundef =incondefs @*/ -#endif -#endif - -#if defined(HAVE_DCGETTEXT) && !defined(__LCLINT__) -char *POPT_dgettext(const char * dom, const char * str) - /*@*/; -#endif - -int POPT_fprintf (FILE* stream, const char *format, ...) - /*@globals fileSystem @*/ - /*@modifies stream, fileSystem @*/; -#endif /* !defined(POPT_fprintf) */ - -const char *POPT_prev_char (/*@returned@*/ const char *str) - /*@*/; - -const char *POPT_next_char (/*@returned@*/ const char *str) - /*@*/; - -#endif - -#if defined(ENABLE_NLS) && defined(HAVE_LIBINTL_H) -#include -#endif - -#if defined(ENABLE_NLS) && defined(HAVE_GETTEXT) && !defined(__LCLINT__) -#define _(foo) gettext(foo) -#else -#define _(foo) foo -#endif - -#if defined(ENABLE_NLS) && defined(HAVE_DCGETTEXT) && !defined(__LCLINT__) -#define D_(dom, str) POPT_dgettext(dom, str) -#define POPT_(foo) D_("popt", foo) -#else -#define D_(dom, str) str -#define POPT_(foo) foo -#endif - -#define N_(foo) foo - diff --git a/ldb-2.0.8/third_party/popt/poptparse.c b/ldb-2.0.8/third_party/popt/poptparse.c deleted file mode 100644 index 39bf1aa..0000000 --- a/ldb-2.0.8/third_party/popt/poptparse.c +++ /dev/null @@ -1,230 +0,0 @@ -/** \ingroup popt - * \file popt/poptparse.c - */ - -/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from - ftp://ftp.rpm.org/pub/rpm/dist. */ - -#include "system.h" - -#define POPT_ARGV_ARRAY_GROW_DELTA 5 - -int poptDupArgv(int argc, const char **argv, - int * argcPtr, const char *** argvPtr) -{ - size_t nb = (argc + 1) * sizeof(*argv); - const char ** argv2; - char * dst; - int i; - - if (argc <= 0 || argv == NULL) /* XXX can't happen */ - return POPT_ERROR_NOARG; - for (i = 0; i < argc; i++) { - if (argv[i] == NULL) - return POPT_ERROR_NOARG; - nb += strlen(argv[i]) + 1; - } - - dst = malloc(nb); - if (dst == NULL) /* XXX can't happen */ - return POPT_ERROR_MALLOC; - argv2 = (void *) dst; - dst += (argc + 1) * sizeof(*argv); - *dst = '\0'; - - for (i = 0; i < argc; i++) { - argv2[i] = dst; - dst = stpcpy(dst, argv[i]); - dst++; /* trailing NUL */ - } - argv2[argc] = NULL; - - if (argvPtr) { - *argvPtr = argv2; - } else { - free(argv2); - argv2 = NULL; - } - if (argcPtr) - *argcPtr = argc; - return 0; -} - -int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr) -{ - const char * src; - char quote = '\0'; - int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA; - const char ** argv = malloc(sizeof(*argv) * argvAlloced); - int argc = 0; - size_t buflen = strlen(s) + 1; - char * buf, * bufOrig = NULL; - int rc = POPT_ERROR_MALLOC; - - if (argv == NULL) return rc; - buf = bufOrig = calloc((size_t)1, buflen); - if (buf == NULL) { - free(argv); - return rc; - } - argv[argc] = buf; - - for (src = s; *src != '\0'; src++) { - if (quote == *src) { - quote = '\0'; - } else if (quote != '\0') { - if (*src == '\\') { - src++; - if (!*src) { - rc = POPT_ERROR_BADQUOTE; - goto exit; - } - if (*src != quote) *buf++ = '\\'; - } - *buf++ = *src; - } else if (_isspaceptr(src)) { - if (*argv[argc] != '\0') { - buf++, argc++; - if (argc == argvAlloced) { - argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA; - argv = realloc(argv, sizeof(*argv) * argvAlloced); - if (argv == NULL) goto exit; - } - argv[argc] = buf; - } - } else switch (*src) { - case '"': - case '\'': - quote = *src; - /*@switchbreak@*/ break; - case '\\': - src++; - if (!*src) { - rc = POPT_ERROR_BADQUOTE; - goto exit; - } - /*@fallthrough@*/ - default: - *buf++ = *src; - /*@switchbreak@*/ break; - } - } - - if (strlen(argv[argc])) { - argc++, buf++; - } - - rc = poptDupArgv(argc, argv, argcPtr, argvPtr); - -exit: - if (bufOrig) free(bufOrig); - if (argv) free(argv); - return rc; -} - -/* still in the dev stage. - * return values, perhaps 1== file erro - * 2== line to long - * 3== umm.... more? - */ -int poptConfigFileToString(FILE *fp, char ** argstrp, - /*@unused@*/ UNUSED(int flags)) -{ - char line[999]; - char * argstr; - char * p; - char * q; - char * x; - size_t t; - size_t argvlen = 0; - size_t maxlinelen = sizeof(line); - size_t linelen; - size_t maxargvlen = (size_t)480; - - *argstrp = NULL; - - /* | this_is = our_line - * p q x - */ - - if (fp == NULL) - return POPT_ERROR_NULLARG; - - argstr = calloc(maxargvlen, sizeof(*argstr)); - if (argstr == NULL) return POPT_ERROR_MALLOC; - - while (fgets(line, (int)maxlinelen, fp) != NULL) { - p = line; - - /* loop until first non-space char or EOL */ - while( *p != '\0' && _isspaceptr(p) ) - p++; - - linelen = strlen(p); - if (linelen >= maxlinelen-1) { - free(argstr); - return POPT_ERROR_OVERFLOW; /* XXX line too long */ - } - - if (*p == '\0' || *p == '\n') continue; /* line is empty */ - if (*p == '#') continue; /* comment line */ - - q = p; - - while (*q != '\0' && (!_isspaceptr(q)) && *q != '=') - q++; - - if (_isspaceptr(q)) { - /* a space after the name, find next non space */ - *q++='\0'; - while( *q != '\0' && _isspaceptr(q) ) q++; - } - if (*q == '\0') { - /* single command line option (ie, no name=val, just name) */ - q[-1] = '\0'; /* kill off newline from fgets() call */ - argvlen += (t = (size_t)(q - p)) + (sizeof(" --")-1); - if (argvlen >= maxargvlen) { - maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; - argstr = realloc(argstr, maxargvlen); - if (argstr == NULL) return POPT_ERROR_MALLOC; - } - strcat(argstr, " --"); - strcat(argstr, p); - continue; - } - if (*q != '=') - continue; /* XXX for now, silently ignore bogus line */ - - /* *q is an equal sign. */ - *q++ = '\0'; - - /* find next non-space letter of value */ - while (*q != '\0' && _isspaceptr(q)) - q++; - if (*q == '\0') - continue; /* XXX silently ignore missing value */ - - /* now, loop and strip all ending whitespace */ - x = p + linelen; - while (_isspaceptr(--x)) - *x = '\0'; /* null out last char if space (including fgets() NL) */ - - /* rest of line accept */ - t = (size_t)(x - p); - argvlen += t + (sizeof("' --='")-1); - if (argvlen >= maxargvlen) { - maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; - argstr = realloc(argstr, maxargvlen); - if (argstr == NULL) return POPT_ERROR_MALLOC; - } - strcat(argstr, " --"); - strcat(argstr, p); - strcat(argstr, "=\""); - strcat(argstr, q); - strcat(argstr, "\""); - } - - *argstrp = argstr; - return 0; -} diff --git a/ldb-2.0.8/third_party/popt/system.h b/ldb-2.0.8/third_party/popt/system.h deleted file mode 100644 index 452bf40..0000000 --- a/ldb-2.0.8/third_party/popt/system.h +++ /dev/null @@ -1,103 +0,0 @@ -/** - * \file popt/system.h - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#if defined (__GLIBC__) && defined(__LCLINT__) -/*@-declundef@*/ -/*@unchecked@*/ -extern __const __int32_t *__ctype_tolower; -/*@unchecked@*/ -extern __const __int32_t *__ctype_toupper; -/*@=declundef@*/ -#endif - -#include - -/* XXX isspace(3) has i18n encoding signednesss issues on Solaris. */ -#define _isspaceptr(_chp) isspace((int)(*(unsigned char *)(_chp))) - -#include -#include -#include - -#ifdef HAVE_MCHECK_H -#include -#endif - -#include -#include -#include - -#if defined(HAVE_UNISTD_H) && !defined(__LCLINT__) -#include -#endif - -#ifdef __NeXT -/* access macros are not declared in non posix mode in unistd.h - - don't try to use posix on NeXTstep 3.3 ! */ -#include -#endif - -/*@-incondefs@*/ -/*@mayexit@*/ /*@only@*/ /*@out@*/ /*@unused@*/ -void * xmalloc (size_t size) - /*@globals errno @*/ - /*@ensures maxSet(result) == (size - 1) @*/ - /*@modifies errno @*/; - -/*@mayexit@*/ /*@only@*/ /*@unused@*/ -void * xcalloc (size_t nmemb, size_t size) - /*@ensures maxSet(result) == (nmemb - 1) @*/ - /*@*/; - -/*@mayexit@*/ /*@only@*/ /*@unused@*/ -void * xrealloc (/*@null@*/ /*@only@*/ void * ptr, size_t size) - /*@ensures maxSet(result) == (size - 1) @*/ - /*@modifies *ptr @*/; - -/*@mayexit@*/ /*@only@*/ /*@unused@*/ -char * xstrdup (const char *str) - /*@*/; -/*@=incondefs@*/ - -#if !defined(HAVE_STPCPY) -/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */ -static inline char * stpcpy (char *dest, const char * src) { - register char *d = dest; - register const char *s = src; - - do - *d++ = *s; - while (*s++ != '\0'); - return d - 1; -} -#endif - -/* Memory allocation via macro defs to get meaningful locations from mtrace() */ -#if defined(HAVE_MCHECK_H) && defined(__GNUC__) -#define vmefail() (fprintf(stderr, "virtual memory exhausted.\n"), exit(EXIT_FAILURE), NULL) -#define xmalloc(_size) (malloc(_size) ? : vmefail()) -#define xcalloc(_nmemb, _size) (calloc((_nmemb), (_size)) ? : vmefail()) -#define xrealloc(_ptr, _size) (realloc((_ptr), (_size)) ? : vmefail()) -#define xstrdup(_str) (strcpy((malloc(strlen(_str)+1) ? : vmefail()), (_str))) -#else -#define xmalloc(_size) malloc(_size) -#define xcalloc(_nmemb, _size) calloc((_nmemb), (_size)) -#define xrealloc(_ptr, _size) realloc((_ptr), (_size)) -#define xstrdup(_str) strdup(_str) -#endif /* defined(HAVE_MCHECK_H) && defined(__GNUC__) */ - -#if defined(HAVE___SECURE_GETENV) && !defined(__LCLINT__) -#define getenv(_s) __secure_getenv(_s) -#endif - -#if !defined(__GNUC__) && !defined(__attribute__) -#define __attribute__(x) -#endif -#define UNUSED(x) x __attribute__((__unused__)) - -#include "popt.h" diff --git a/ldb-2.0.8/third_party/popt/wscript b/ldb-2.0.8/third_party/popt/wscript deleted file mode 100644 index ea655bb..0000000 --- a/ldb-2.0.8/third_party/popt/wscript +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env python - -from waflib import Options - -def configure(conf): - if conf.CHECK_POPT(): - conf.define('USING_SYSTEM_POPT', 1) - return - - conf.CHECK_HEADERS('float.h') - conf.CHECK_FUNCS('stpcpy') - conf.CHECK_LIB('iconv', shlib=True) - -def build(bld): - if bld.CONFIG_SET('USING_SYSTEM_POPT'): - return - - cflags = '-DPACKAGE="popt" -DPOPT_SYSCONFDIR="%s"' % bld.env.SYSCONFDIR - bld.SAMBA_LIBRARY('popt', - source='popt.c poptconfig.c popthelp.c poptint.c poptparse.c', - cflags=cflags, - deps='iconv', - allow_warnings=True, - private_library=True) diff --git a/ldb-2.0.8/third_party/waf/waflib/Build.py b/ldb-2.0.8/third_party/waf/waflib/Build.py deleted file mode 100644 index 39f0991..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Build.py +++ /dev/null @@ -1,1512 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2005-2018 (ita) - -""" -Classes related to the build phase (build, clean, install, step, etc) - -The inheritance tree is the following: - -""" - -import os, sys, errno, re, shutil, stat -try: - import cPickle -except ImportError: - import pickle as cPickle -from waflib import Node, Runner, TaskGen, Utils, ConfigSet, Task, Logs, Options, Context, Errors - -CACHE_DIR = 'c4che' -"""Name of the cache directory""" - -CACHE_SUFFIX = '_cache.py' -"""ConfigSet cache files for variants are written under :py:attr:´waflib.Build.CACHE_DIR´ in the form ´variant_name´_cache.py""" - -INSTALL = 1337 -"""Positive value '->' install, see :py:attr:`waflib.Build.BuildContext.is_install`""" - -UNINSTALL = -1337 -"""Negative value '<-' uninstall, see :py:attr:`waflib.Build.BuildContext.is_install`""" - -SAVED_ATTRS = 'root node_sigs task_sigs imp_sigs raw_deps node_deps'.split() -"""Build class members to save between the runs; these should be all dicts -except for `root` which represents a :py:class:`waflib.Node.Node` instance -""" - -CFG_FILES = 'cfg_files' -"""Files from the build directory to hash before starting the build (``config.h`` written during the configuration)""" - -POST_AT_ONCE = 0 -"""Post mode: all task generators are posted before any task executed""" - -POST_LAZY = 1 -"""Post mode: post the task generators group after group, the tasks in the next group are created when the tasks in the previous groups are done""" - -PROTOCOL = -1 -if sys.platform == 'cli': - PROTOCOL = 0 - -class BuildContext(Context.Context): - '''executes the build''' - - cmd = 'build' - variant = '' - - def __init__(self, **kw): - super(BuildContext, self).__init__(**kw) - - self.is_install = 0 - """Non-zero value when installing or uninstalling file""" - - self.top_dir = kw.get('top_dir', Context.top_dir) - """See :py:attr:`waflib.Context.top_dir`; prefer :py:attr:`waflib.Build.BuildContext.srcnode`""" - - self.out_dir = kw.get('out_dir', Context.out_dir) - """See :py:attr:`waflib.Context.out_dir`; prefer :py:attr:`waflib.Build.BuildContext.bldnode`""" - - self.run_dir = kw.get('run_dir', Context.run_dir) - """See :py:attr:`waflib.Context.run_dir`""" - - self.launch_dir = Context.launch_dir - """See :py:attr:`waflib.Context.out_dir`; prefer :py:meth:`waflib.Build.BuildContext.launch_node`""" - - self.post_mode = POST_LAZY - """Whether to post the task generators at once or group-by-group (default is group-by-group)""" - - self.cache_dir = kw.get('cache_dir') - if not self.cache_dir: - self.cache_dir = os.path.join(self.out_dir, CACHE_DIR) - - self.all_envs = {} - """Map names to :py:class:`waflib.ConfigSet.ConfigSet`, the empty string must map to the default environment""" - - # ======================================= # - # cache variables - - self.node_sigs = {} - """Dict mapping build nodes to task identifier (uid), it indicates whether a task created a particular file (persists across builds)""" - - self.task_sigs = {} - """Dict mapping task identifiers (uid) to task signatures (persists across builds)""" - - self.imp_sigs = {} - """Dict mapping task identifiers (uid) to implicit task dependencies used for scanning targets (persists across builds)""" - - self.node_deps = {} - """Dict mapping task identifiers (uid) to node dependencies found by :py:meth:`waflib.Task.Task.scan` (persists across builds)""" - - self.raw_deps = {} - """Dict mapping task identifiers (uid) to custom data returned by :py:meth:`waflib.Task.Task.scan` (persists across builds)""" - - self.task_gen_cache_names = {} - - self.jobs = Options.options.jobs - """Amount of jobs to run in parallel""" - - self.targets = Options.options.targets - """List of targets to build (default: \\*)""" - - self.keep = Options.options.keep - """Whether the build should continue past errors""" - - self.progress_bar = Options.options.progress_bar - """ - Level of progress status: - - 0. normal output - 1. progress bar - 2. IDE output - 3. No output at all - """ - - # Manual dependencies. - self.deps_man = Utils.defaultdict(list) - """Manual dependencies set by :py:meth:`waflib.Build.BuildContext.add_manual_dependency`""" - - # just the structure here - self.current_group = 0 - """ - Current build group - """ - - self.groups = [] - """ - List containing lists of task generators - """ - - self.group_names = {} - """ - Map group names to the group lists. See :py:meth:`waflib.Build.BuildContext.add_group` - """ - - for v in SAVED_ATTRS: - if not hasattr(self, v): - setattr(self, v, {}) - - def get_variant_dir(self): - """Getter for the variant_dir attribute""" - if not self.variant: - return self.out_dir - return os.path.join(self.out_dir, os.path.normpath(self.variant)) - variant_dir = property(get_variant_dir, None) - - def __call__(self, *k, **kw): - """ - Create a task generator and add it to the current build group. The following forms are equivalent:: - - def build(bld): - tg = bld(a=1, b=2) - - def build(bld): - tg = bld() - tg.a = 1 - tg.b = 2 - - def build(bld): - tg = TaskGen.task_gen(a=1, b=2) - bld.add_to_group(tg, None) - - :param group: group name to add the task generator to - :type group: string - """ - kw['bld'] = self - ret = TaskGen.task_gen(*k, **kw) - self.task_gen_cache_names = {} # reset the cache, each time - self.add_to_group(ret, group=kw.get('group')) - return ret - - def __copy__(self): - """ - Build contexts cannot be copied - - :raises: :py:class:`waflib.Errors.WafError` - """ - raise Errors.WafError('build contexts cannot be copied') - - def load_envs(self): - """ - The configuration command creates files of the form ``build/c4che/NAMEcache.py``. This method - creates a :py:class:`waflib.ConfigSet.ConfigSet` instance for each ``NAME`` by reading those - files and stores them in :py:attr:`waflib.Build.BuildContext.allenvs`. - """ - node = self.root.find_node(self.cache_dir) - if not node: - raise Errors.WafError('The project was not configured: run "waf configure" first!') - lst = node.ant_glob('**/*%s' % CACHE_SUFFIX, quiet=True) - - if not lst: - raise Errors.WafError('The cache directory is empty: reconfigure the project') - - for x in lst: - name = x.path_from(node).replace(CACHE_SUFFIX, '').replace('\\', '/') - env = ConfigSet.ConfigSet(x.abspath()) - self.all_envs[name] = env - for f in env[CFG_FILES]: - newnode = self.root.find_resource(f) - if not newnode or not newnode.exists(): - raise Errors.WafError('Missing configuration file %r, reconfigure the project!' % f) - - def init_dirs(self): - """ - Initialize the project directory and the build directory by creating the nodes - :py:attr:`waflib.Build.BuildContext.srcnode` and :py:attr:`waflib.Build.BuildContext.bldnode` - corresponding to ``top_dir`` and ``variant_dir`` respectively. The ``bldnode`` directory is - created if necessary. - """ - if not (os.path.isabs(self.top_dir) and os.path.isabs(self.out_dir)): - raise Errors.WafError('The project was not configured: run "waf configure" first!') - - self.path = self.srcnode = self.root.find_dir(self.top_dir) - self.bldnode = self.root.make_node(self.variant_dir) - self.bldnode.mkdir() - - def execute(self): - """ - Restore data from previous builds and call :py:meth:`waflib.Build.BuildContext.execute_build`. - Overrides from :py:func:`waflib.Context.Context.execute` - """ - self.restore() - if not self.all_envs: - self.load_envs() - self.execute_build() - - def execute_build(self): - """ - Execute the build by: - - * reading the scripts (see :py:meth:`waflib.Context.Context.recurse`) - * calling :py:meth:`waflib.Build.BuildContext.pre_build` to call user build functions - * calling :py:meth:`waflib.Build.BuildContext.compile` to process the tasks - * calling :py:meth:`waflib.Build.BuildContext.post_build` to call user build functions - """ - - Logs.info("Waf: Entering directory `%s'", self.variant_dir) - self.recurse([self.run_dir]) - self.pre_build() - - # display the time elapsed in the progress bar - self.timer = Utils.Timer() - - try: - self.compile() - finally: - if self.progress_bar == 1 and sys.stderr.isatty(): - c = self.producer.processed or 1 - m = self.progress_line(c, c, Logs.colors.BLUE, Logs.colors.NORMAL) - Logs.info(m, extra={'stream': sys.stderr, 'c1': Logs.colors.cursor_off, 'c2' : Logs.colors.cursor_on}) - Logs.info("Waf: Leaving directory `%s'", self.variant_dir) - try: - self.producer.bld = None - del self.producer - except AttributeError: - pass - self.post_build() - - def restore(self): - """ - Load data from a previous run, sets the attributes listed in :py:const:`waflib.Build.SAVED_ATTRS` - """ - try: - env = ConfigSet.ConfigSet(os.path.join(self.cache_dir, 'build.config.py')) - except EnvironmentError: - pass - else: - if env.version < Context.HEXVERSION: - raise Errors.WafError('Project was configured with a different version of Waf, please reconfigure it') - - for t in env.tools: - self.setup(**t) - - dbfn = os.path.join(self.variant_dir, Context.DBFILE) - try: - data = Utils.readf(dbfn, 'rb') - except (EnvironmentError, EOFError): - # handle missing file/empty file - Logs.debug('build: Could not load the build cache %s (missing)', dbfn) - else: - try: - Node.pickle_lock.acquire() - Node.Nod3 = self.node_class - try: - data = cPickle.loads(data) - except Exception as e: - Logs.debug('build: Could not pickle the build cache %s: %r', dbfn, e) - else: - for x in SAVED_ATTRS: - setattr(self, x, data.get(x, {})) - finally: - Node.pickle_lock.release() - - self.init_dirs() - - def store(self): - """ - Store data for next runs, set the attributes listed in :py:const:`waflib.Build.SAVED_ATTRS`. Uses a temporary - file to avoid problems on ctrl+c. - """ - data = {} - for x in SAVED_ATTRS: - data[x] = getattr(self, x) - db = os.path.join(self.variant_dir, Context.DBFILE) - - try: - Node.pickle_lock.acquire() - Node.Nod3 = self.node_class - x = cPickle.dumps(data, PROTOCOL) - finally: - Node.pickle_lock.release() - - Utils.writef(db + '.tmp', x, m='wb') - - try: - st = os.stat(db) - os.remove(db) - if not Utils.is_win32: # win32 has no chown but we're paranoid - os.chown(db + '.tmp', st.st_uid, st.st_gid) - except (AttributeError, OSError): - pass - - # do not use shutil.move (copy is not thread-safe) - os.rename(db + '.tmp', db) - - def compile(self): - """ - Run the build by creating an instance of :py:class:`waflib.Runner.Parallel` - The cache file is written when at least a task was executed. - - :raises: :py:class:`waflib.Errors.BuildError` in case the build fails - """ - Logs.debug('build: compile()') - - # delegate the producer-consumer logic to another object to reduce the complexity - self.producer = Runner.Parallel(self, self.jobs) - self.producer.biter = self.get_build_iterator() - try: - self.producer.start() - except KeyboardInterrupt: - if self.is_dirty(): - self.store() - raise - else: - if self.is_dirty(): - self.store() - - if self.producer.error: - raise Errors.BuildError(self.producer.error) - - def is_dirty(self): - return self.producer.dirty - - def setup(self, tool, tooldir=None, funs=None): - """ - Import waf tools defined during the configuration:: - - def configure(conf): - conf.load('glib2') - - def build(bld): - pass # glib2 is imported implicitly - - :param tool: tool list - :type tool: list - :param tooldir: optional tool directory (sys.path) - :type tooldir: list of string - :param funs: unused variable - """ - if isinstance(tool, list): - for i in tool: - self.setup(i, tooldir) - return - - module = Context.load_tool(tool, tooldir) - if hasattr(module, "setup"): - module.setup(self) - - def get_env(self): - """Getter for the env property""" - try: - return self.all_envs[self.variant] - except KeyError: - return self.all_envs[''] - def set_env(self, val): - """Setter for the env property""" - self.all_envs[self.variant] = val - - env = property(get_env, set_env) - - def add_manual_dependency(self, path, value): - """ - Adds a dependency from a node object to a value:: - - def build(bld): - bld.add_manual_dependency( - bld.path.find_resource('wscript'), - bld.root.find_resource('/etc/fstab')) - - :param path: file path - :type path: string or :py:class:`waflib.Node.Node` - :param value: value to depend - :type value: :py:class:`waflib.Node.Node`, byte object, or function returning a byte object - """ - if not path: - raise ValueError('Invalid input path %r' % path) - - if isinstance(path, Node.Node): - node = path - elif os.path.isabs(path): - node = self.root.find_resource(path) - else: - node = self.path.find_resource(path) - if not node: - raise ValueError('Could not find the path %r' % path) - - if isinstance(value, list): - self.deps_man[node].extend(value) - else: - self.deps_man[node].append(value) - - def launch_node(self): - """Returns the launch directory as a :py:class:`waflib.Node.Node` object (cached)""" - try: - # private cache - return self.p_ln - except AttributeError: - self.p_ln = self.root.find_dir(self.launch_dir) - return self.p_ln - - def hash_env_vars(self, env, vars_lst): - """ - Hashes configuration set variables:: - - def build(bld): - bld.hash_env_vars(bld.env, ['CXX', 'CC']) - - This method uses an internal cache. - - :param env: Configuration Set - :type env: :py:class:`waflib.ConfigSet.ConfigSet` - :param vars_lst: list of variables - :type vars_list: list of string - """ - - if not env.table: - env = env.parent - if not env: - return Utils.SIG_NIL - - idx = str(id(env)) + str(vars_lst) - try: - cache = self.cache_env - except AttributeError: - cache = self.cache_env = {} - else: - try: - return self.cache_env[idx] - except KeyError: - pass - - lst = [env[a] for a in vars_lst] - cache[idx] = ret = Utils.h_list(lst) - Logs.debug('envhash: %s %r', Utils.to_hex(ret), lst) - return ret - - def get_tgen_by_name(self, name): - """ - Fetches a task generator by its name or its target attribute; - the name must be unique in a build:: - - def build(bld): - tg = bld(name='foo') - tg == bld.get_tgen_by_name('foo') - - This method use a private internal cache. - - :param name: Task generator name - :raises: :py:class:`waflib.Errors.WafError` in case there is no task genenerator by that name - """ - cache = self.task_gen_cache_names - if not cache: - # create the index lazily - for g in self.groups: - for tg in g: - try: - cache[tg.name] = tg - except AttributeError: - # raised if not a task generator, which should be uncommon - pass - try: - return cache[name] - except KeyError: - raise Errors.WafError('Could not find a task generator for the name %r' % name) - - def progress_line(self, idx, total, col1, col2): - """ - Computes a progress bar line displayed when running ``waf -p`` - - :returns: progress bar line - :rtype: string - """ - if not sys.stderr.isatty(): - return '' - - n = len(str(total)) - - Utils.rot_idx += 1 - ind = Utils.rot_chr[Utils.rot_idx % 4] - - pc = (100. * idx)/total - fs = "[%%%dd/%%d][%%s%%2d%%%%%%s][%s][" % (n, ind) - left = fs % (idx, total, col1, pc, col2) - right = '][%s%s%s]' % (col1, self.timer, col2) - - cols = Logs.get_term_cols() - len(left) - len(right) + 2*len(col1) + 2*len(col2) - if cols < 7: - cols = 7 - - ratio = ((cols * idx)//total) - 1 - - bar = ('='*ratio+'>').ljust(cols) - msg = Logs.indicator % (left, bar, right) - - return msg - - def declare_chain(self, *k, **kw): - """ - Wraps :py:func:`waflib.TaskGen.declare_chain` for convenience - """ - return TaskGen.declare_chain(*k, **kw) - - def pre_build(self): - """Executes user-defined methods before the build starts, see :py:meth:`waflib.Build.BuildContext.add_pre_fun`""" - for m in getattr(self, 'pre_funs', []): - m(self) - - def post_build(self): - """Executes user-defined methods after the build is successful, see :py:meth:`waflib.Build.BuildContext.add_post_fun`""" - for m in getattr(self, 'post_funs', []): - m(self) - - def add_pre_fun(self, meth): - """ - Binds a callback method to execute after the scripts are read and before the build starts:: - - def mycallback(bld): - print("Hello, world!") - - def build(bld): - bld.add_pre_fun(mycallback) - """ - try: - self.pre_funs.append(meth) - except AttributeError: - self.pre_funs = [meth] - - def add_post_fun(self, meth): - """ - Binds a callback method to execute immediately after the build is successful:: - - def call_ldconfig(bld): - bld.exec_command('/sbin/ldconfig') - - def build(bld): - if bld.cmd == 'install': - bld.add_pre_fun(call_ldconfig) - """ - try: - self.post_funs.append(meth) - except AttributeError: - self.post_funs = [meth] - - def get_group(self, x): - """ - Returns the build group named `x`, or the current group if `x` is None - - :param x: name or number or None - :type x: string, int or None - """ - if not self.groups: - self.add_group() - if x is None: - return self.groups[self.current_group] - if x in self.group_names: - return self.group_names[x] - return self.groups[x] - - def add_to_group(self, tgen, group=None): - """Adds a task or a task generator to the build; there is no attempt to remove it if it was already added.""" - assert(isinstance(tgen, TaskGen.task_gen) or isinstance(tgen, Task.Task)) - tgen.bld = self - self.get_group(group).append(tgen) - - def get_group_name(self, g): - """ - Returns the name of the input build group - - :param g: build group object or build group index - :type g: integer or list - :return: name - :rtype: string - """ - if not isinstance(g, list): - g = self.groups[g] - for x in self.group_names: - if id(self.group_names[x]) == id(g): - return x - return '' - - def get_group_idx(self, tg): - """ - Returns the index of the group containing the task generator given as argument:: - - def build(bld): - tg = bld(name='nada') - 0 == bld.get_group_idx(tg) - - :param tg: Task generator object - :type tg: :py:class:`waflib.TaskGen.task_gen` - :rtype: int - """ - se = id(tg) - for i, tmp in enumerate(self.groups): - for t in tmp: - if id(t) == se: - return i - return None - - def add_group(self, name=None, move=True): - """ - Adds a new group of tasks/task generators. By default the new group becomes - the default group for new task generators (make sure to create build groups in order). - - :param name: name for this group - :type name: string - :param move: set this new group as default group (True by default) - :type move: bool - :raises: :py:class:`waflib.Errors.WafError` if a group by the name given already exists - """ - if name and name in self.group_names: - raise Errors.WafError('add_group: name %s already present', name) - g = [] - self.group_names[name] = g - self.groups.append(g) - if move: - self.current_group = len(self.groups) - 1 - - def set_group(self, idx): - """ - Sets the build group at position idx as current so that newly added - task generators are added to this one by default:: - - def build(bld): - bld(rule='touch ${TGT}', target='foo.txt') - bld.add_group() # now the current group is 1 - bld(rule='touch ${TGT}', target='bar.txt') - bld.set_group(0) # now the current group is 0 - bld(rule='touch ${TGT}', target='truc.txt') # build truc.txt before bar.txt - - :param idx: group name or group index - :type idx: string or int - """ - if isinstance(idx, str): - g = self.group_names[idx] - for i, tmp in enumerate(self.groups): - if id(g) == id(tmp): - self.current_group = i - break - else: - self.current_group = idx - - def total(self): - """ - Approximate task count: this value may be inaccurate if task generators - are posted lazily (see :py:attr:`waflib.Build.BuildContext.post_mode`). - The value :py:attr:`waflib.Runner.Parallel.total` is updated during the task execution. - - :rtype: int - """ - total = 0 - for group in self.groups: - for tg in group: - try: - total += len(tg.tasks) - except AttributeError: - total += 1 - return total - - def get_targets(self): - """ - This method returns a pair containing the index of the last build group to post, - and the list of task generator objects corresponding to the target names. - - This is used internally by :py:meth:`waflib.Build.BuildContext.get_build_iterator` - to perform partial builds:: - - $ waf --targets=myprogram,myshlib - - :return: the minimum build group index, and list of task generators - :rtype: tuple - """ - to_post = [] - min_grp = 0 - for name in self.targets.split(','): - tg = self.get_tgen_by_name(name) - m = self.get_group_idx(tg) - if m > min_grp: - min_grp = m - to_post = [tg] - elif m == min_grp: - to_post.append(tg) - return (min_grp, to_post) - - def get_all_task_gen(self): - """ - Returns a list of all task generators for troubleshooting purposes. - """ - lst = [] - for g in self.groups: - lst.extend(g) - return lst - - def post_group(self): - """ - Post task generators from the group indexed by self.current_group; used internally - by :py:meth:`waflib.Build.BuildContext.get_build_iterator` - """ - def tgpost(tg): - try: - f = tg.post - except AttributeError: - pass - else: - f() - - if self.targets == '*': - for tg in self.groups[self.current_group]: - tgpost(tg) - elif self.targets: - if self.current_group < self._min_grp: - for tg in self.groups[self.current_group]: - tgpost(tg) - else: - for tg in self._exact_tg: - tg.post() - else: - ln = self.launch_node() - if ln.is_child_of(self.bldnode): - Logs.warn('Building from the build directory, forcing --targets=*') - ln = self.srcnode - elif not ln.is_child_of(self.srcnode): - Logs.warn('CWD %s is not under %s, forcing --targets=* (run distclean?)', ln.abspath(), self.srcnode.abspath()) - ln = self.srcnode - - def is_post(tg, ln): - try: - p = tg.path - except AttributeError: - pass - else: - if p.is_child_of(ln): - return True - - def is_post_group(): - for i, g in enumerate(self.groups): - if i > self.current_group: - for tg in g: - if is_post(tg, ln): - return True - - if self.post_mode == POST_LAZY and ln != self.srcnode: - # partial folder builds require all targets from a previous build group - if is_post_group(): - ln = self.srcnode - - for tg in self.groups[self.current_group]: - if is_post(tg, ln): - tgpost(tg) - - def get_tasks_group(self, idx): - """ - Returns all task instances for the build group at position idx, - used internally by :py:meth:`waflib.Build.BuildContext.get_build_iterator` - - :rtype: list of :py:class:`waflib.Task.Task` - """ - tasks = [] - for tg in self.groups[idx]: - try: - tasks.extend(tg.tasks) - except AttributeError: # not a task generator - tasks.append(tg) - return tasks - - def get_build_iterator(self): - """ - Creates a Python generator object that returns lists of tasks that may be processed in parallel. - - :return: tasks which can be executed immediately - :rtype: generator returning lists of :py:class:`waflib.Task.Task` - """ - if self.targets and self.targets != '*': - (self._min_grp, self._exact_tg) = self.get_targets() - - if self.post_mode != POST_LAZY: - for self.current_group, _ in enumerate(self.groups): - self.post_group() - - for self.current_group, _ in enumerate(self.groups): - # first post the task generators for the group - if self.post_mode != POST_AT_ONCE: - self.post_group() - - # then extract the tasks - tasks = self.get_tasks_group(self.current_group) - - # if the constraints are set properly (ext_in/ext_out, before/after) - # the call to set_file_constraints may be removed (can be a 15% penalty on no-op rebuilds) - # (but leave set_file_constraints for the installation step) - # - # if the tasks have only files, set_file_constraints is required but set_precedence_constraints is not necessary - # - Task.set_file_constraints(tasks) - Task.set_precedence_constraints(tasks) - - self.cur_tasks = tasks - if tasks: - yield tasks - - while 1: - # the build stops once there are no tasks to process - yield [] - - def install_files(self, dest, files, **kw): - """ - Creates a task generator to install files on the system:: - - def build(bld): - bld.install_files('${DATADIR}', self.path.find_resource('wscript')) - - :param dest: path representing the destination directory - :type dest: :py:class:`waflib.Node.Node` or string (absolute path) - :param files: input files - :type files: list of strings or list of :py:class:`waflib.Node.Node` - :param env: configuration set to expand *dest* - :type env: :py:class:`waflib.ConfigSet.ConfigSet` - :param relative_trick: preserve the folder hierarchy when installing whole folders - :type relative_trick: bool - :param cwd: parent node for searching srcfile, when srcfile is not an instance of :py:class:`waflib.Node.Node` - :type cwd: :py:class:`waflib.Node.Node` - :param postpone: execute the task immediately to perform the installation (False by default) - :type postpone: bool - """ - assert(dest) - tg = self(features='install_task', install_to=dest, install_from=files, **kw) - tg.dest = tg.install_to - tg.type = 'install_files' - if not kw.get('postpone', True): - tg.post() - return tg - - def install_as(self, dest, srcfile, **kw): - """ - Creates a task generator to install a file on the system with a different name:: - - def build(bld): - bld.install_as('${PREFIX}/bin', 'myapp', chmod=Utils.O755) - - :param dest: destination file - :type dest: :py:class:`waflib.Node.Node` or string (absolute path) - :param srcfile: input file - :type srcfile: string or :py:class:`waflib.Node.Node` - :param cwd: parent node for searching srcfile, when srcfile is not an instance of :py:class:`waflib.Node.Node` - :type cwd: :py:class:`waflib.Node.Node` - :param env: configuration set for performing substitutions in dest - :type env: :py:class:`waflib.ConfigSet.ConfigSet` - :param postpone: execute the task immediately to perform the installation (False by default) - :type postpone: bool - """ - assert(dest) - tg = self(features='install_task', install_to=dest, install_from=srcfile, **kw) - tg.dest = tg.install_to - tg.type = 'install_as' - if not kw.get('postpone', True): - tg.post() - return tg - - def symlink_as(self, dest, src, **kw): - """ - Creates a task generator to install a symlink:: - - def build(bld): - bld.symlink_as('${PREFIX}/lib/libfoo.so', 'libfoo.so.1.2.3') - - :param dest: absolute path of the symlink - :type dest: :py:class:`waflib.Node.Node` or string (absolute path) - :param src: link contents, which is a relative or absolute path which may exist or not - :type src: string - :param env: configuration set for performing substitutions in dest - :type env: :py:class:`waflib.ConfigSet.ConfigSet` - :param add: add the task created to a build group - set ``False`` only if the installation task is created after the build has started - :type add: bool - :param postpone: execute the task immediately to perform the installation - :type postpone: bool - :param relative_trick: make the symlink relative (default: ``False``) - :type relative_trick: bool - """ - assert(dest) - tg = self(features='install_task', install_to=dest, install_from=src, **kw) - tg.dest = tg.install_to - tg.type = 'symlink_as' - tg.link = src - # TODO if add: self.add_to_group(tsk) - if not kw.get('postpone', True): - tg.post() - return tg - -@TaskGen.feature('install_task') -@TaskGen.before_method('process_rule', 'process_source') -def process_install_task(self): - """Creates the installation task for the current task generator; uses :py:func:`waflib.Build.add_install_task` internally.""" - self.add_install_task(**self.__dict__) - -@TaskGen.taskgen_method -def add_install_task(self, **kw): - """ - Creates the installation task for the current task generator, and executes it immediately if necessary - - :returns: An installation task - :rtype: :py:class:`waflib.Build.inst` - """ - if not self.bld.is_install: - return - if not kw['install_to']: - return - - if kw['type'] == 'symlink_as' and Utils.is_win32: - if kw.get('win32_install'): - kw['type'] = 'install_as' - else: - # just exit - return - - tsk = self.install_task = self.create_task('inst') - tsk.chmod = kw.get('chmod', Utils.O644) - tsk.link = kw.get('link', '') or kw.get('install_from', '') - tsk.relative_trick = kw.get('relative_trick', False) - tsk.type = kw['type'] - tsk.install_to = tsk.dest = kw['install_to'] - tsk.install_from = kw['install_from'] - tsk.relative_base = kw.get('cwd') or kw.get('relative_base', self.path) - tsk.install_user = kw.get('install_user') - tsk.install_group = kw.get('install_group') - tsk.init_files() - if not kw.get('postpone', True): - tsk.run_now() - return tsk - -@TaskGen.taskgen_method -def add_install_files(self, **kw): - """ - Creates an installation task for files - - :returns: An installation task - :rtype: :py:class:`waflib.Build.inst` - """ - kw['type'] = 'install_files' - return self.add_install_task(**kw) - -@TaskGen.taskgen_method -def add_install_as(self, **kw): - """ - Creates an installation task for a single file - - :returns: An installation task - :rtype: :py:class:`waflib.Build.inst` - """ - kw['type'] = 'install_as' - return self.add_install_task(**kw) - -@TaskGen.taskgen_method -def add_symlink_as(self, **kw): - """ - Creates an installation task for a symbolic link - - :returns: An installation task - :rtype: :py:class:`waflib.Build.inst` - """ - kw['type'] = 'symlink_as' - return self.add_install_task(**kw) - -class inst(Task.Task): - """Task that installs files or symlinks; it is typically executed by :py:class:`waflib.Build.InstallContext` and :py:class:`waflib.Build.UnInstallContext`""" - def __str__(self): - """Returns an empty string to disable the standard task display""" - return '' - - def uid(self): - """Returns a unique identifier for the task""" - lst = self.inputs + self.outputs + [self.link, self.generator.path.abspath()] - return Utils.h_list(lst) - - def init_files(self): - """ - Initializes the task input and output nodes - """ - if self.type == 'symlink_as': - inputs = [] - else: - inputs = self.generator.to_nodes(self.install_from) - if self.type == 'install_as': - assert len(inputs) == 1 - self.set_inputs(inputs) - - dest = self.get_install_path() - outputs = [] - if self.type == 'symlink_as': - if self.relative_trick: - self.link = os.path.relpath(self.link, os.path.dirname(dest)) - outputs.append(self.generator.bld.root.make_node(dest)) - elif self.type == 'install_as': - outputs.append(self.generator.bld.root.make_node(dest)) - else: - for y in inputs: - if self.relative_trick: - destfile = os.path.join(dest, y.path_from(self.relative_base)) - else: - destfile = os.path.join(dest, y.name) - outputs.append(self.generator.bld.root.make_node(destfile)) - self.set_outputs(outputs) - - def runnable_status(self): - """ - Installation tasks are always executed, so this method returns either :py:const:`waflib.Task.ASK_LATER` or :py:const:`waflib.Task.RUN_ME`. - """ - ret = super(inst, self).runnable_status() - if ret == Task.SKIP_ME and self.generator.bld.is_install: - return Task.RUN_ME - return ret - - def post_run(self): - """ - Disables any post-run operations - """ - pass - - def get_install_path(self, destdir=True): - """ - Returns the destination path where files will be installed, pre-pending `destdir`. - - Relative paths will be interpreted relative to `PREFIX` if no `destdir` is given. - - :rtype: string - """ - if isinstance(self.install_to, Node.Node): - dest = self.install_to.abspath() - else: - dest = os.path.normpath(Utils.subst_vars(self.install_to, self.env)) - if not os.path.isabs(dest): - dest = os.path.join(self.env.PREFIX, dest) - if destdir and Options.options.destdir: - dest = os.path.join(Options.options.destdir, os.path.splitdrive(dest)[1].lstrip(os.sep)) - return dest - - def copy_fun(self, src, tgt): - """ - Copies a file from src to tgt, preserving permissions and trying to work - around path limitations on Windows platforms. On Unix-like platforms, - the owner/group of the target file may be set through install_user/install_group - - :param src: absolute path - :type src: string - :param tgt: absolute path - :type tgt: string - """ - # override this if you want to strip executables - # kw['tsk'].source is the task that created the files in the build - if Utils.is_win32 and len(tgt) > 259 and not tgt.startswith('\\\\?\\'): - tgt = '\\\\?\\' + tgt - shutil.copy2(src, tgt) - self.fix_perms(tgt) - - def rm_empty_dirs(self, tgt): - """ - Removes empty folders recursively when uninstalling. - - :param tgt: absolute path - :type tgt: string - """ - while tgt: - tgt = os.path.dirname(tgt) - try: - os.rmdir(tgt) - except OSError: - break - - def run(self): - """ - Performs file or symlink installation - """ - is_install = self.generator.bld.is_install - if not is_install: # unnecessary? - return - - for x in self.outputs: - if is_install == INSTALL: - x.parent.mkdir() - if self.type == 'symlink_as': - fun = is_install == INSTALL and self.do_link or self.do_unlink - fun(self.link, self.outputs[0].abspath()) - else: - fun = is_install == INSTALL and self.do_install or self.do_uninstall - launch_node = self.generator.bld.launch_node() - for x, y in zip(self.inputs, self.outputs): - fun(x.abspath(), y.abspath(), x.path_from(launch_node)) - - def run_now(self): - """ - Try executing the installation task right now - - :raises: :py:class:`waflib.Errors.TaskNotReady` - """ - status = self.runnable_status() - if status not in (Task.RUN_ME, Task.SKIP_ME): - raise Errors.TaskNotReady('Could not process %r: status %r' % (self, status)) - self.run() - self.hasrun = Task.SUCCESS - - def do_install(self, src, tgt, lbl, **kw): - """ - Copies a file from src to tgt with given file permissions. The actual copy is only performed - if the source and target file sizes or timestamps differ. When the copy occurs, - the file is always first removed and then copied so as to prevent stale inodes. - - :param src: file name as absolute path - :type src: string - :param tgt: file destination, as absolute path - :type tgt: string - :param lbl: file source description - :type lbl: string - :param chmod: installation mode - :type chmod: int - :raises: :py:class:`waflib.Errors.WafError` if the file cannot be written - """ - if not Options.options.force: - # check if the file is already there to avoid a copy - try: - st1 = os.stat(tgt) - st2 = os.stat(src) - except OSError: - pass - else: - # same size and identical timestamps -> make no copy - if st1.st_mtime + 2 >= st2.st_mtime and st1.st_size == st2.st_size: - if not self.generator.bld.progress_bar: - - c1 = Logs.colors.NORMAL - c2 = Logs.colors.BLUE - - Logs.info('%s- install %s%s%s (from %s)', c1, c2, tgt, c1, lbl) - return False - - if not self.generator.bld.progress_bar: - - c1 = Logs.colors.NORMAL - c2 = Logs.colors.BLUE - - Logs.info('%s+ install %s%s%s (from %s)', c1, c2, tgt, c1, lbl) - - # Give best attempt at making destination overwritable, - # like the 'install' utility used by 'make install' does. - try: - os.chmod(tgt, Utils.O644 | stat.S_IMODE(os.stat(tgt).st_mode)) - except EnvironmentError: - pass - - # following is for shared libs and stale inodes (-_-) - try: - os.remove(tgt) - except OSError: - pass - - try: - self.copy_fun(src, tgt) - except EnvironmentError as e: - if not os.path.exists(src): - Logs.error('File %r does not exist', src) - elif not os.path.isfile(src): - Logs.error('Input %r is not a file', src) - raise Errors.WafError('Could not install the file %r' % tgt, e) - - def fix_perms(self, tgt): - """ - Change the ownership of the file/folder/link pointed by the given path - This looks up for `install_user` or `install_group` attributes - on the task or on the task generator:: - - def build(bld): - bld.install_as('${PREFIX}/wscript', - 'wscript', - install_user='nobody', install_group='nogroup') - bld.symlink_as('${PREFIX}/wscript_link', - Utils.subst_vars('${PREFIX}/wscript', bld.env), - install_user='nobody', install_group='nogroup') - """ - if not Utils.is_win32: - user = getattr(self, 'install_user', None) or getattr(self.generator, 'install_user', None) - group = getattr(self, 'install_group', None) or getattr(self.generator, 'install_group', None) - if user or group: - Utils.lchown(tgt, user or -1, group or -1) - if not os.path.islink(tgt): - os.chmod(tgt, self.chmod) - - def do_link(self, src, tgt, **kw): - """ - Creates a symlink from tgt to src. - - :param src: file name as absolute path - :type src: string - :param tgt: file destination, as absolute path - :type tgt: string - """ - if os.path.islink(tgt) and os.readlink(tgt) == src: - if not self.generator.bld.progress_bar: - c1 = Logs.colors.NORMAL - c2 = Logs.colors.BLUE - Logs.info('%s- symlink %s%s%s (to %s)', c1, c2, tgt, c1, src) - else: - try: - os.remove(tgt) - except OSError: - pass - if not self.generator.bld.progress_bar: - c1 = Logs.colors.NORMAL - c2 = Logs.colors.BLUE - Logs.info('%s+ symlink %s%s%s (to %s)', c1, c2, tgt, c1, src) - os.symlink(src, tgt) - self.fix_perms(tgt) - - def do_uninstall(self, src, tgt, lbl, **kw): - """ - See :py:meth:`waflib.Build.inst.do_install` - """ - if not self.generator.bld.progress_bar: - c1 = Logs.colors.NORMAL - c2 = Logs.colors.BLUE - Logs.info('%s- remove %s%s%s', c1, c2, tgt, c1) - - #self.uninstall.append(tgt) - try: - os.remove(tgt) - except OSError as e: - if e.errno != errno.ENOENT: - if not getattr(self, 'uninstall_error', None): - self.uninstall_error = True - Logs.warn('build: some files could not be uninstalled (retry with -vv to list them)') - if Logs.verbose > 1: - Logs.warn('Could not remove %s (error code %r)', e.filename, e.errno) - self.rm_empty_dirs(tgt) - - def do_unlink(self, src, tgt, **kw): - """ - See :py:meth:`waflib.Build.inst.do_link` - """ - try: - if not self.generator.bld.progress_bar: - c1 = Logs.colors.NORMAL - c2 = Logs.colors.BLUE - Logs.info('%s- remove %s%s%s', c1, c2, tgt, c1) - os.remove(tgt) - except OSError: - pass - self.rm_empty_dirs(tgt) - -class InstallContext(BuildContext): - '''installs the targets on the system''' - cmd = 'install' - - def __init__(self, **kw): - super(InstallContext, self).__init__(**kw) - self.is_install = INSTALL - -class UninstallContext(InstallContext): - '''removes the targets installed''' - cmd = 'uninstall' - - def __init__(self, **kw): - super(UninstallContext, self).__init__(**kw) - self.is_install = UNINSTALL - -class CleanContext(BuildContext): - '''cleans the project''' - cmd = 'clean' - def execute(self): - """ - See :py:func:`waflib.Build.BuildContext.execute`. - """ - self.restore() - if not self.all_envs: - self.load_envs() - - self.recurse([self.run_dir]) - try: - self.clean() - finally: - self.store() - - def clean(self): - """ - Remove most files from the build directory, and reset all caches. - - Custom lists of files to clean can be declared as `bld.clean_files`. - For example, exclude `build/program/myprogram` from getting removed:: - - def build(bld): - bld.clean_files = bld.bldnode.ant_glob('**', - excl='.lock* config.log c4che/* config.h program/myprogram', - quiet=True, generator=True) - """ - Logs.debug('build: clean called') - - if hasattr(self, 'clean_files'): - for n in self.clean_files: - n.delete() - elif self.bldnode != self.srcnode: - # would lead to a disaster if top == out - lst = [] - for env in self.all_envs.values(): - lst.extend(self.root.find_or_declare(f) for f in env[CFG_FILES]) - excluded_dirs = '.lock* *conf_check_*/** config.log %s/*' % CACHE_DIR - for n in self.bldnode.ant_glob('**/*', excl=excluded_dirs, quiet=True): - if n in lst: - continue - n.delete() - self.root.children = {} - - for v in SAVED_ATTRS: - if v == 'root': - continue - setattr(self, v, {}) - -class ListContext(BuildContext): - '''lists the targets to execute''' - cmd = 'list' - - def execute(self): - """ - In addition to printing the name of each build target, - a description column will include text for each task - generator which has a "description" field set. - - See :py:func:`waflib.Build.BuildContext.execute`. - """ - self.restore() - if not self.all_envs: - self.load_envs() - - self.recurse([self.run_dir]) - self.pre_build() - - # display the time elapsed in the progress bar - self.timer = Utils.Timer() - - for g in self.groups: - for tg in g: - try: - f = tg.post - except AttributeError: - pass - else: - f() - - try: - # force the cache initialization - self.get_tgen_by_name('') - except Errors.WafError: - pass - - targets = sorted(self.task_gen_cache_names) - - # figure out how much to left-justify, for largest target name - line_just = max(len(t) for t in targets) if targets else 0 - - for target in targets: - tgen = self.task_gen_cache_names[target] - - # Support displaying the description for the target - # if it was set on the tgen - descript = getattr(tgen, 'description', '') - if descript: - target = target.ljust(line_just) - descript = ': %s' % descript - - Logs.pprint('GREEN', target, label=descript) - -class StepContext(BuildContext): - '''executes tasks in a step-by-step fashion, for debugging''' - cmd = 'step' - - def __init__(self, **kw): - super(StepContext, self).__init__(**kw) - self.files = Options.options.files - - def compile(self): - """ - Overrides :py:meth:`waflib.Build.BuildContext.compile` to perform a partial build - on tasks matching the input/output pattern given (regular expression matching):: - - $ waf step --files=foo.c,bar.c,in:truc.c,out:bar.o - $ waf step --files=in:foo.cpp.1.o # link task only - - """ - if not self.files: - Logs.warn('Add a pattern for the debug build, for example "waf step --files=main.c,app"') - BuildContext.compile(self) - return - - targets = [] - if self.targets and self.targets != '*': - targets = self.targets.split(',') - - for g in self.groups: - for tg in g: - if targets and tg.name not in targets: - continue - - try: - f = tg.post - except AttributeError: - pass - else: - f() - - for pat in self.files.split(','): - matcher = self.get_matcher(pat) - for tg in g: - if isinstance(tg, Task.Task): - lst = [tg] - else: - lst = tg.tasks - for tsk in lst: - do_exec = False - for node in tsk.inputs: - if matcher(node, output=False): - do_exec = True - break - for node in tsk.outputs: - if matcher(node, output=True): - do_exec = True - break - if do_exec: - ret = tsk.run() - Logs.info('%s -> exit %r', tsk, ret) - - def get_matcher(self, pat): - """ - Converts a step pattern into a function - - :param: pat: pattern of the form in:truc.c,out:bar.o - :returns: Python function that uses Node objects as inputs and returns matches - :rtype: function - """ - # this returns a function - inn = True - out = True - if pat.startswith('in:'): - out = False - pat = pat.replace('in:', '') - elif pat.startswith('out:'): - inn = False - pat = pat.replace('out:', '') - - anode = self.root.find_node(pat) - pattern = None - if not anode: - if not pat.startswith('^'): - pat = '^.+?%s' % pat - if not pat.endswith('$'): - pat = '%s$' % pat - pattern = re.compile(pat) - - def match(node, output): - if output and not out: - return False - if not output and not inn: - return False - - if anode: - return anode == node - else: - return pattern.match(node.abspath()) - return match - -class EnvContext(BuildContext): - """Subclass EnvContext to create commands that require configuration data in 'env'""" - fun = cmd = None - def execute(self): - """ - See :py:func:`waflib.Build.BuildContext.execute`. - """ - self.restore() - if not self.all_envs: - self.load_envs() - self.recurse([self.run_dir]) - diff --git a/ldb-2.0.8/third_party/waf/waflib/ConfigSet.py b/ldb-2.0.8/third_party/waf/waflib/ConfigSet.py deleted file mode 100644 index 901fba6..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/ConfigSet.py +++ /dev/null @@ -1,361 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2005-2018 (ita) - -""" - -ConfigSet: a special dict - -The values put in :py:class:`ConfigSet` must be serializable (dicts, lists, strings) -""" - -import copy, re, os -from waflib import Logs, Utils -re_imp = re.compile(r'^(#)*?([^#=]*?)\ =\ (.*?)$', re.M) - -class ConfigSet(object): - """ - A copy-on-write dict with human-readable serialized format. The serialization format - is human-readable (python-like) and performed by using eval() and repr(). - For high performance prefer pickle. Do not store functions as they are not serializable. - - The values can be accessed by attributes or by keys:: - - from waflib.ConfigSet import ConfigSet - env = ConfigSet() - env.FOO = 'test' - env['FOO'] = 'test' - """ - __slots__ = ('table', 'parent') - def __init__(self, filename=None): - self.table = {} - """ - Internal dict holding the object values - """ - #self.parent = None - - if filename: - self.load(filename) - - def __contains__(self, key): - """ - Enables the *in* syntax:: - - if 'foo' in env: - print(env['foo']) - """ - if key in self.table: - return True - try: - return self.parent.__contains__(key) - except AttributeError: - return False # parent may not exist - - def keys(self): - """Dict interface""" - keys = set() - cur = self - while cur: - keys.update(cur.table.keys()) - cur = getattr(cur, 'parent', None) - keys = list(keys) - keys.sort() - return keys - - def __iter__(self): - return iter(self.keys()) - - def __str__(self): - """Text representation of the ConfigSet (for debugging purposes)""" - return "\n".join(["%r %r" % (x, self.__getitem__(x)) for x in self.keys()]) - - def __getitem__(self, key): - """ - Dictionary interface: get value from key:: - - def configure(conf): - conf.env['foo'] = {} - print(env['foo']) - """ - try: - while 1: - x = self.table.get(key) - if not x is None: - return x - self = self.parent - except AttributeError: - return [] - - def __setitem__(self, key, value): - """ - Dictionary interface: set value from key - """ - self.table[key] = value - - def __delitem__(self, key): - """ - Dictionary interface: mark the value as missing - """ - self[key] = [] - - def __getattr__(self, name): - """ - Attribute access provided for convenience. The following forms are equivalent:: - - def configure(conf): - conf.env.value - conf.env['value'] - """ - if name in self.__slots__: - return object.__getattribute__(self, name) - else: - return self[name] - - def __setattr__(self, name, value): - """ - Attribute access provided for convenience. The following forms are equivalent:: - - def configure(conf): - conf.env.value = x - env['value'] = x - """ - if name in self.__slots__: - object.__setattr__(self, name, value) - else: - self[name] = value - - def __delattr__(self, name): - """ - Attribute access provided for convenience. The following forms are equivalent:: - - def configure(conf): - del env.value - del env['value'] - """ - if name in self.__slots__: - object.__delattr__(self, name) - else: - del self[name] - - def derive(self): - """ - Returns a new ConfigSet deriving from self. The copy returned - will be a shallow copy:: - - from waflib.ConfigSet import ConfigSet - env = ConfigSet() - env.append_value('CFLAGS', ['-O2']) - child = env.derive() - child.CFLAGS.append('test') # warning! this will modify 'env' - child.CFLAGS = ['-O3'] # new list, ok - child.append_value('CFLAGS', ['-O3']) # ok - - Use :py:func:`ConfigSet.detach` to detach the child from the parent. - """ - newenv = ConfigSet() - newenv.parent = self - return newenv - - def detach(self): - """ - Detaches this instance from its parent (if present) - - Modifying the parent :py:class:`ConfigSet` will not change the current object - Modifying this :py:class:`ConfigSet` will not modify the parent one. - """ - tbl = self.get_merged_dict() - try: - delattr(self, 'parent') - except AttributeError: - pass - else: - keys = tbl.keys() - for x in keys: - tbl[x] = copy.deepcopy(tbl[x]) - self.table = tbl - return self - - def get_flat(self, key): - """ - Returns a value as a string. If the input is a list, the value returned is space-separated. - - :param key: key to use - :type key: string - """ - s = self[key] - if isinstance(s, str): - return s - return ' '.join(s) - - def _get_list_value_for_modification(self, key): - """ - Returns a list value for further modification. - - The list may be modified inplace and there is no need to do this afterwards:: - - self.table[var] = value - """ - try: - value = self.table[key] - except KeyError: - try: - value = self.parent[key] - except AttributeError: - value = [] - else: - if isinstance(value, list): - # force a copy - value = value[:] - else: - value = [value] - self.table[key] = value - else: - if not isinstance(value, list): - self.table[key] = value = [value] - return value - - def append_value(self, var, val): - """ - Appends a value to the specified config key:: - - def build(bld): - bld.env.append_value('CFLAGS', ['-O2']) - - The value must be a list or a tuple - """ - if isinstance(val, str): # if there were string everywhere we could optimize this - val = [val] - current_value = self._get_list_value_for_modification(var) - current_value.extend(val) - - def prepend_value(self, var, val): - """ - Prepends a value to the specified item:: - - def configure(conf): - conf.env.prepend_value('CFLAGS', ['-O2']) - - The value must be a list or a tuple - """ - if isinstance(val, str): - val = [val] - self.table[var] = val + self._get_list_value_for_modification(var) - - def append_unique(self, var, val): - """ - Appends a value to the specified item only if it's not already present:: - - def build(bld): - bld.env.append_unique('CFLAGS', ['-O2', '-g']) - - The value must be a list or a tuple - """ - if isinstance(val, str): - val = [val] - current_value = self._get_list_value_for_modification(var) - - for x in val: - if x not in current_value: - current_value.append(x) - - def get_merged_dict(self): - """ - Computes the merged dictionary from the fusion of self and all its parent - - :rtype: a ConfigSet object - """ - table_list = [] - env = self - while 1: - table_list.insert(0, env.table) - try: - env = env.parent - except AttributeError: - break - merged_table = {} - for table in table_list: - merged_table.update(table) - return merged_table - - def store(self, filename): - """ - Serializes the :py:class:`ConfigSet` data to a file. See :py:meth:`ConfigSet.load` for reading such files. - - :param filename: file to use - :type filename: string - """ - try: - os.makedirs(os.path.split(filename)[0]) - except OSError: - pass - - buf = [] - merged_table = self.get_merged_dict() - keys = list(merged_table.keys()) - keys.sort() - - try: - fun = ascii - except NameError: - fun = repr - - for k in keys: - if k != 'undo_stack': - buf.append('%s = %s\n' % (k, fun(merged_table[k]))) - Utils.writef(filename, ''.join(buf)) - - def load(self, filename): - """ - Restores contents from a file (current values are not cleared). Files are written using :py:meth:`ConfigSet.store`. - - :param filename: file to use - :type filename: string - """ - tbl = self.table - code = Utils.readf(filename, m='r') - for m in re_imp.finditer(code): - g = m.group - tbl[g(2)] = eval(g(3)) - Logs.debug('env: %s', self.table) - - def update(self, d): - """ - Dictionary interface: replace values with the ones from another dict - - :param d: object to use the value from - :type d: dict-like object - """ - self.table.update(d) - - def stash(self): - """ - Stores the object state to provide transactionality semantics:: - - env = ConfigSet() - env.stash() - try: - env.append_value('CFLAGS', '-O3') - call_some_method(env) - finally: - env.revert() - - The history is kept in a stack, and is lost during the serialization by :py:meth:`ConfigSet.store` - """ - orig = self.table - tbl = self.table = self.table.copy() - for x in tbl.keys(): - tbl[x] = copy.deepcopy(tbl[x]) - self.undo_stack = self.undo_stack + [orig] - - def commit(self): - """ - Commits transactional changes. See :py:meth:`ConfigSet.stash` - """ - self.undo_stack.pop(-1) - - def revert(self): - """ - Reverts the object to a previous state. See :py:meth:`ConfigSet.stash` - """ - self.table = self.undo_stack.pop(-1) - diff --git a/ldb-2.0.8/third_party/waf/waflib/Configure.py b/ldb-2.0.8/third_party/waf/waflib/Configure.py deleted file mode 100644 index 5762eb6..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Configure.py +++ /dev/null @@ -1,649 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2005-2018 (ita) - -""" -Configuration system - -A :py:class:`waflib.Configure.ConfigurationContext` instance is created when ``waf configure`` is called, it is used to: - -* create data dictionaries (ConfigSet instances) -* store the list of modules to import -* hold configuration routines such as ``find_program``, etc -""" - -import os, re, shlex, shutil, sys, time, traceback -from waflib import ConfigSet, Utils, Options, Logs, Context, Build, Errors - -WAF_CONFIG_LOG = 'config.log' -"""Name of the configuration log file""" - -autoconfig = False -"""Execute the configuration automatically""" - -conf_template = '''# project %(app)s configured on %(now)s by -# waf %(wafver)s (abi %(abi)s, python %(pyver)x on %(systype)s) -# using %(args)s -#''' - -class ConfigurationContext(Context.Context): - '''configures the project''' - - cmd = 'configure' - - error_handlers = [] - """ - Additional functions to handle configuration errors - """ - - def __init__(self, **kw): - super(ConfigurationContext, self).__init__(**kw) - self.environ = dict(os.environ) - self.all_envs = {} - - self.top_dir = None - self.out_dir = None - - self.tools = [] # tools loaded in the configuration, and that will be loaded when building - - self.hash = 0 - self.files = [] - - self.tool_cache = [] - - self.setenv('') - - def setenv(self, name, env=None): - """ - Set a new config set for conf.env. If a config set of that name already exists, - recall it without modification. - - The name is the filename prefix to save to ``c4che/NAME_cache.py``, and it - is also used as *variants* by the build commands. - Though related to variants, whatever kind of data may be stored in the config set:: - - def configure(cfg): - cfg.env.ONE = 1 - cfg.setenv('foo') - cfg.env.ONE = 2 - - def build(bld): - 2 == bld.env_of_name('foo').ONE - - :param name: name of the configuration set - :type name: string - :param env: ConfigSet to copy, or an empty ConfigSet is created - :type env: :py:class:`waflib.ConfigSet.ConfigSet` - """ - if name not in self.all_envs or env: - if not env: - env = ConfigSet.ConfigSet() - self.prepare_env(env) - else: - env = env.derive() - self.all_envs[name] = env - self.variant = name - - def get_env(self): - """Getter for the env property""" - return self.all_envs[self.variant] - def set_env(self, val): - """Setter for the env property""" - self.all_envs[self.variant] = val - - env = property(get_env, set_env) - - def init_dirs(self): - """ - Initialize the project directory and the build directory - """ - - top = self.top_dir - if not top: - top = Options.options.top - if not top: - top = getattr(Context.g_module, Context.TOP, None) - if not top: - top = self.path.abspath() - top = os.path.abspath(top) - - self.srcnode = (os.path.isabs(top) and self.root or self.path).find_dir(top) - assert(self.srcnode) - - out = self.out_dir - if not out: - out = Options.options.out - if not out: - out = getattr(Context.g_module, Context.OUT, None) - if not out: - out = Options.lockfile.replace('.lock-waf_%s_' % sys.platform, '').replace('.lock-waf', '') - - # someone can be messing with symlinks - out = os.path.realpath(out) - - self.bldnode = (os.path.isabs(out) and self.root or self.path).make_node(out) - self.bldnode.mkdir() - - if not os.path.isdir(self.bldnode.abspath()): - self.fatal('Could not create the build directory %s' % self.bldnode.abspath()) - - def execute(self): - """ - See :py:func:`waflib.Context.Context.execute` - """ - self.init_dirs() - - self.cachedir = self.bldnode.make_node(Build.CACHE_DIR) - self.cachedir.mkdir() - - path = os.path.join(self.bldnode.abspath(), WAF_CONFIG_LOG) - self.logger = Logs.make_logger(path, 'cfg') - - app = getattr(Context.g_module, 'APPNAME', '') - if app: - ver = getattr(Context.g_module, 'VERSION', '') - if ver: - app = "%s (%s)" % (app, ver) - - params = {'now': time.ctime(), 'pyver': sys.hexversion, 'systype': sys.platform, 'args': " ".join(sys.argv), 'wafver': Context.WAFVERSION, 'abi': Context.ABI, 'app': app} - self.to_log(conf_template % params) - self.msg('Setting top to', self.srcnode.abspath()) - self.msg('Setting out to', self.bldnode.abspath()) - - if id(self.srcnode) == id(self.bldnode): - Logs.warn('Setting top == out') - elif id(self.path) != id(self.srcnode): - if self.srcnode.is_child_of(self.path): - Logs.warn('Are you certain that you do not want to set top="." ?') - - super(ConfigurationContext, self).execute() - - self.store() - - Context.top_dir = self.srcnode.abspath() - Context.out_dir = self.bldnode.abspath() - - # this will write a configure lock so that subsequent builds will - # consider the current path as the root directory (see prepare_impl). - # to remove: use 'waf distclean' - env = ConfigSet.ConfigSet() - env.argv = sys.argv - env.options = Options.options.__dict__ - env.config_cmd = self.cmd - - env.run_dir = Context.run_dir - env.top_dir = Context.top_dir - env.out_dir = Context.out_dir - - # conf.hash & conf.files hold wscript files paths and hash - # (used only by Configure.autoconfig) - env.hash = self.hash - env.files = self.files - env.environ = dict(self.environ) - env.launch_dir = Context.launch_dir - - if not (self.env.NO_LOCK_IN_RUN or env.environ.get('NO_LOCK_IN_RUN') or getattr(Options.options, 'no_lock_in_run')): - env.store(os.path.join(Context.run_dir, Options.lockfile)) - if not (self.env.NO_LOCK_IN_TOP or env.environ.get('NO_LOCK_IN_TOP') or getattr(Options.options, 'no_lock_in_top')): - env.store(os.path.join(Context.top_dir, Options.lockfile)) - if not (self.env.NO_LOCK_IN_OUT or env.environ.get('NO_LOCK_IN_OUT') or getattr(Options.options, 'no_lock_in_out')): - env.store(os.path.join(Context.out_dir, Options.lockfile)) - - def prepare_env(self, env): - """ - Insert *PREFIX*, *BINDIR* and *LIBDIR* values into ``env`` - - :type env: :py:class:`waflib.ConfigSet.ConfigSet` - :param env: a ConfigSet, usually ``conf.env`` - """ - if not env.PREFIX: - if Options.options.prefix or Utils.is_win32: - env.PREFIX = Options.options.prefix - else: - env.PREFIX = '/' - if not env.BINDIR: - if Options.options.bindir: - env.BINDIR = Options.options.bindir - else: - env.BINDIR = Utils.subst_vars('${PREFIX}/bin', env) - if not env.LIBDIR: - if Options.options.libdir: - env.LIBDIR = Options.options.libdir - else: - env.LIBDIR = Utils.subst_vars('${PREFIX}/lib%s' % Utils.lib64(), env) - - def store(self): - """Save the config results into the cache file""" - n = self.cachedir.make_node('build.config.py') - n.write('version = 0x%x\ntools = %r\n' % (Context.HEXVERSION, self.tools)) - - if not self.all_envs: - self.fatal('nothing to store in the configuration context!') - - for key in self.all_envs: - tmpenv = self.all_envs[key] - tmpenv.store(os.path.join(self.cachedir.abspath(), key + Build.CACHE_SUFFIX)) - - def load(self, tool_list, tooldir=None, funs=None, with_sys_path=True, cache=False): - """ - Load Waf tools, which will be imported whenever a build is started. - - :param tool_list: waf tools to import - :type tool_list: list of string - :param tooldir: paths for the imports - :type tooldir: list of string - :param funs: functions to execute from the waf tools - :type funs: list of string - :param cache: whether to prevent the tool from running twice - :type cache: bool - """ - - tools = Utils.to_list(tool_list) - if tooldir: - tooldir = Utils.to_list(tooldir) - for tool in tools: - # avoid loading the same tool more than once with the same functions - # used by composite projects - - if cache: - mag = (tool, id(self.env), tooldir, funs) - if mag in self.tool_cache: - self.to_log('(tool %s is already loaded, skipping)' % tool) - continue - self.tool_cache.append(mag) - - module = None - try: - module = Context.load_tool(tool, tooldir, ctx=self, with_sys_path=with_sys_path) - except ImportError as e: - self.fatal('Could not load the Waf tool %r from %r\n%s' % (tool, getattr(e, 'waf_sys_path', sys.path), e)) - except Exception as e: - self.to_log('imp %r (%r & %r)' % (tool, tooldir, funs)) - self.to_log(traceback.format_exc()) - raise - - if funs is not None: - self.eval_rules(funs) - else: - func = getattr(module, 'configure', None) - if func: - if type(func) is type(Utils.readf): - func(self) - else: - self.eval_rules(func) - - self.tools.append({'tool':tool, 'tooldir':tooldir, 'funs':funs}) - - def post_recurse(self, node): - """ - Records the path and a hash of the scripts visited, see :py:meth:`waflib.Context.Context.post_recurse` - - :param node: script - :type node: :py:class:`waflib.Node.Node` - """ - super(ConfigurationContext, self).post_recurse(node) - self.hash = Utils.h_list((self.hash, node.read('rb'))) - self.files.append(node.abspath()) - - def eval_rules(self, rules): - """ - Execute configuration tests provided as list of functions to run - - :param rules: list of configuration method names - :type rules: list of string - """ - self.rules = Utils.to_list(rules) - for x in self.rules: - f = getattr(self, x) - if not f: - self.fatal('No such configuration function %r' % x) - f() - -def conf(f): - """ - Decorator: attach new configuration functions to :py:class:`waflib.Build.BuildContext` and - :py:class:`waflib.Configure.ConfigurationContext`. The methods bound will accept a parameter - named 'mandatory' to disable the configuration errors:: - - def configure(conf): - conf.find_program('abc', mandatory=False) - - :param f: method to bind - :type f: function - """ - def fun(*k, **kw): - mandatory = kw.pop('mandatory', True) - try: - return f(*k, **kw) - except Errors.ConfigurationError: - if mandatory: - raise - - fun.__name__ = f.__name__ - setattr(ConfigurationContext, f.__name__, fun) - setattr(Build.BuildContext, f.__name__, fun) - return f - -@conf -def add_os_flags(self, var, dest=None, dup=False): - """ - Import operating system environment values into ``conf.env`` dict:: - - def configure(conf): - conf.add_os_flags('CFLAGS') - - :param var: variable to use - :type var: string - :param dest: destination variable, by default the same as var - :type dest: string - :param dup: add the same set of flags again - :type dup: bool - """ - try: - flags = shlex.split(self.environ[var]) - except KeyError: - return - if dup or ''.join(flags) not in ''.join(Utils.to_list(self.env[dest or var])): - self.env.append_value(dest or var, flags) - -@conf -def cmd_to_list(self, cmd): - """ - Detect if a command is written in pseudo shell like ``ccache g++`` and return a list. - - :param cmd: command - :type cmd: a string or a list of string - """ - if isinstance(cmd, str): - if os.path.isfile(cmd): - # do not take any risk - return [cmd] - if os.sep == '/': - return shlex.split(cmd) - else: - try: - return shlex.split(cmd, posix=False) - except TypeError: - # Python 2.5 on windows? - return shlex.split(cmd) - return cmd - -@conf -def check_waf_version(self, mini='1.9.99', maxi='2.1.0', **kw): - """ - Raise a Configuration error if the Waf version does not strictly match the given bounds:: - - conf.check_waf_version(mini='1.9.99', maxi='2.1.0') - - :type mini: number, tuple or string - :param mini: Minimum required version - :type maxi: number, tuple or string - :param maxi: Maximum allowed version - """ - self.start_msg('Checking for waf version in %s-%s' % (str(mini), str(maxi)), **kw) - ver = Context.HEXVERSION - if Utils.num2ver(mini) > ver: - self.fatal('waf version should be at least %r (%r found)' % (Utils.num2ver(mini), ver)) - if Utils.num2ver(maxi) < ver: - self.fatal('waf version should be at most %r (%r found)' % (Utils.num2ver(maxi), ver)) - self.end_msg('ok', **kw) - -@conf -def find_file(self, filename, path_list=[]): - """ - Find a file in a list of paths - - :param filename: name of the file to search for - :param path_list: list of directories to search - :return: the first matching filename; else a configuration exception is raised - """ - for n in Utils.to_list(filename): - for d in Utils.to_list(path_list): - p = os.path.expanduser(os.path.join(d, n)) - if os.path.exists(p): - return p - self.fatal('Could not find %r' % filename) - -@conf -def find_program(self, filename, **kw): - """ - Search for a program on the operating system - - When var is used, you may set os.environ[var] to help find a specific program version, for example:: - - $ CC='ccache gcc' waf configure - - :param path_list: paths to use for searching - :type param_list: list of string - :param var: store the result to conf.env[var] where var defaults to filename.upper() if not provided; the result is stored as a list of strings - :type var: string - :param value: obtain the program from the value passed exclusively - :type value: list or string (list is preferred) - :param exts: list of extensions for the binary (do not add an extension for portability) - :type exts: list of string - :param msg: name to display in the log, by default filename is used - :type msg: string - :param interpreter: interpreter for the program - :type interpreter: ConfigSet variable key - :raises: :py:class:`waflib.Errors.ConfigurationError` - """ - - exts = kw.get('exts', Utils.is_win32 and '.exe,.com,.bat,.cmd' or ',.sh,.pl,.py') - - environ = kw.get('environ', getattr(self, 'environ', os.environ)) - - ret = '' - - filename = Utils.to_list(filename) - msg = kw.get('msg', ', '.join(filename)) - - var = kw.get('var', '') - if not var: - var = re.sub(r'[-.]', '_', filename[0].upper()) - - path_list = kw.get('path_list', '') - if path_list: - path_list = Utils.to_list(path_list) - else: - path_list = environ.get('PATH', '').split(os.pathsep) - - if kw.get('value'): - # user-provided in command-line options and passed to find_program - ret = self.cmd_to_list(kw['value']) - elif environ.get(var): - # user-provided in the os environment - ret = self.cmd_to_list(environ[var]) - elif self.env[var]: - # a default option in the wscript file - ret = self.cmd_to_list(self.env[var]) - else: - if not ret: - ret = self.find_binary(filename, exts.split(','), path_list) - if not ret and Utils.winreg: - ret = Utils.get_registry_app_path(Utils.winreg.HKEY_CURRENT_USER, filename) - if not ret and Utils.winreg: - ret = Utils.get_registry_app_path(Utils.winreg.HKEY_LOCAL_MACHINE, filename) - ret = self.cmd_to_list(ret) - - if ret: - if len(ret) == 1: - retmsg = ret[0] - else: - retmsg = ret - else: - retmsg = False - - self.msg('Checking for program %r' % msg, retmsg, **kw) - if not kw.get('quiet'): - self.to_log('find program=%r paths=%r var=%r -> %r' % (filename, path_list, var, ret)) - - if not ret: - self.fatal(kw.get('errmsg', '') or 'Could not find the program %r' % filename) - - interpreter = kw.get('interpreter') - if interpreter is None: - if not Utils.check_exe(ret[0], env=environ): - self.fatal('Program %r is not executable' % ret) - self.env[var] = ret - else: - self.env[var] = self.env[interpreter] + ret - - return ret - -@conf -def find_binary(self, filenames, exts, paths): - for f in filenames: - for ext in exts: - exe_name = f + ext - if os.path.isabs(exe_name): - if os.path.isfile(exe_name): - return exe_name - else: - for path in paths: - x = os.path.expanduser(os.path.join(path, exe_name)) - if os.path.isfile(x): - return x - return None - -@conf -def run_build(self, *k, **kw): - """ - Create a temporary build context to execute a build. A reference to that build - context is kept on self.test_bld for debugging purposes, and you should not rely - on it too much (read the note on the cache below). - The parameters given in the arguments to this function are passed as arguments for - a single task generator created in the build. Only three parameters are obligatory: - - :param features: features to pass to a task generator created in the build - :type features: list of string - :param compile_filename: file to create for the compilation (default: *test.c*) - :type compile_filename: string - :param code: code to write in the filename to compile - :type code: string - - Though this function returns *0* by default, the build may set an attribute named *retval* on the - build context object to return a particular value. See :py:func:`waflib.Tools.c_config.test_exec_fun` for example. - - This function also features a cache which can be enabled by the following option:: - - def options(opt): - opt.add_option('--confcache', dest='confcache', default=0, - action='count', help='Use a configuration cache') - - And execute the configuration with the following command-line:: - - $ waf configure --confcache - - """ - buf = [] - for key in sorted(kw.keys()): - v = kw[key] - if hasattr(v, '__call__'): - buf.append(Utils.h_fun(v)) - else: - buf.append(str(v)) - h = Utils.h_list(buf) - dir = self.bldnode.abspath() + os.sep + (not Utils.is_win32 and '.' or '') + 'conf_check_' + Utils.to_hex(h) - - cachemode = kw.get('confcache', getattr(Options.options, 'confcache', None)) - - if not cachemode and os.path.exists(dir): - shutil.rmtree(dir) - - try: - os.makedirs(dir) - except OSError: - pass - - try: - os.stat(dir) - except OSError: - self.fatal('cannot use the configuration test folder %r' % dir) - - if cachemode == 1: - try: - proj = ConfigSet.ConfigSet(os.path.join(dir, 'cache_run_build')) - except EnvironmentError: - pass - else: - ret = proj['cache_run_build'] - if isinstance(ret, str) and ret.startswith('Test does not build'): - self.fatal(ret) - return ret - - bdir = os.path.join(dir, 'testbuild') - - if not os.path.exists(bdir): - os.makedirs(bdir) - - cls_name = kw.get('run_build_cls') or getattr(self, 'run_build_cls', 'build') - self.test_bld = bld = Context.create_context(cls_name, top_dir=dir, out_dir=bdir) - bld.init_dirs() - bld.progress_bar = 0 - bld.targets = '*' - - bld.logger = self.logger - bld.all_envs.update(self.all_envs) # not really necessary - bld.env = kw['env'] - - bld.kw = kw - bld.conf = self - kw['build_fun'](bld) - ret = -1 - try: - try: - bld.compile() - except Errors.WafError: - ret = 'Test does not build: %s' % traceback.format_exc() - self.fatal(ret) - else: - ret = getattr(bld, 'retval', 0) - finally: - if cachemode: - # cache the results each time - proj = ConfigSet.ConfigSet() - proj['cache_run_build'] = ret - proj.store(os.path.join(dir, 'cache_run_build')) - else: - shutil.rmtree(dir) - return ret - -@conf -def ret_msg(self, msg, args): - if isinstance(msg, str): - return msg - return msg(args) - -@conf -def test(self, *k, **kw): - - if not 'env' in kw: - kw['env'] = self.env.derive() - - # validate_c for example - if kw.get('validate'): - kw['validate'](kw) - - self.start_msg(kw['msg'], **kw) - ret = None - try: - ret = self.run_build(*k, **kw) - except self.errors.ConfigurationError: - self.end_msg(kw['errmsg'], 'YELLOW', **kw) - if Logs.verbose > 1: - raise - else: - self.fatal('The configuration failed') - else: - kw['success'] = ret - - if kw.get('post_check'): - ret = kw['post_check'](kw) - - if ret: - self.end_msg(kw['errmsg'], 'YELLOW', **kw) - self.fatal('The configuration failed %r' % ret) - else: - self.end_msg(self.ret_msg(kw['okmsg'], kw), **kw) - return ret - diff --git a/ldb-2.0.8/third_party/waf/waflib/Context.py b/ldb-2.0.8/third_party/waf/waflib/Context.py deleted file mode 100644 index e3305fa..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Context.py +++ /dev/null @@ -1,737 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2010-2018 (ita) - -""" -Classes and functions enabling the command system -""" - -import os, re, imp, sys -from waflib import Utils, Errors, Logs -import waflib.Node - -# the following 3 constants are updated on each new release (do not touch) -HEXVERSION=0x2001200 -"""Constant updated on new releases""" - -WAFVERSION="2.0.18" -"""Constant updated on new releases""" - -WAFREVISION="314689b8994259a84f0de0aaef74d7ce91f541ad" -"""Git revision when the waf version is updated""" - -ABI = 20 -"""Version of the build data cache file format (used in :py:const:`waflib.Context.DBFILE`)""" - -DBFILE = '.wafpickle-%s-%d-%d' % (sys.platform, sys.hexversion, ABI) -"""Name of the pickle file for storing the build data""" - -APPNAME = 'APPNAME' -"""Default application name (used by ``waf dist``)""" - -VERSION = 'VERSION' -"""Default application version (used by ``waf dist``)""" - -TOP = 'top' -"""The variable name for the top-level directory in wscript files""" - -OUT = 'out' -"""The variable name for the output directory in wscript files""" - -WSCRIPT_FILE = 'wscript' -"""Name of the waf script files""" - -launch_dir = '' -"""Directory from which waf has been called""" -run_dir = '' -"""Location of the wscript file to use as the entry point""" -top_dir = '' -"""Location of the project directory (top), if the project was configured""" -out_dir = '' -"""Location of the build directory (out), if the project was configured""" -waf_dir = '' -"""Directory containing the waf modules""" - -default_encoding = Utils.console_encoding() -"""Encoding to use when reading outputs from other processes""" - -g_module = None -""" -Module representing the top-level wscript file (see :py:const:`waflib.Context.run_dir`) -""" - -STDOUT = 1 -STDERR = -1 -BOTH = 0 - -classes = [] -""" -List of :py:class:`waflib.Context.Context` subclasses that can be used as waf commands. The classes -are added automatically by a metaclass. -""" - -def create_context(cmd_name, *k, **kw): - """ - Returns a new :py:class:`waflib.Context.Context` instance corresponding to the given command. - Used in particular by :py:func:`waflib.Scripting.run_command` - - :param cmd_name: command name - :type cmd_name: string - :param k: arguments to give to the context class initializer - :type k: list - :param k: keyword arguments to give to the context class initializer - :type k: dict - :return: Context object - :rtype: :py:class:`waflib.Context.Context` - """ - for x in classes: - if x.cmd == cmd_name: - return x(*k, **kw) - ctx = Context(*k, **kw) - ctx.fun = cmd_name - return ctx - -class store_context(type): - """ - Metaclass that registers command classes into the list :py:const:`waflib.Context.classes` - Context classes must provide an attribute 'cmd' representing the command name, and a function - attribute 'fun' representing the function name that the command uses. - """ - def __init__(cls, name, bases, dct): - super(store_context, cls).__init__(name, bases, dct) - name = cls.__name__ - - if name in ('ctx', 'Context'): - return - - try: - cls.cmd - except AttributeError: - raise Errors.WafError('Missing command for the context class %r (cmd)' % name) - - if not getattr(cls, 'fun', None): - cls.fun = cls.cmd - - classes.insert(0, cls) - -ctx = store_context('ctx', (object,), {}) -"""Base class for all :py:class:`waflib.Context.Context` classes""" - -class Context(ctx): - """ - Default context for waf commands, and base class for new command contexts. - - Context objects are passed to top-level functions:: - - def foo(ctx): - print(ctx.__class__.__name__) # waflib.Context.Context - - Subclasses must define the class attributes 'cmd' and 'fun': - - :param cmd: command to execute as in ``waf cmd`` - :type cmd: string - :param fun: function name to execute when the command is called - :type fun: string - - .. inheritance-diagram:: waflib.Context.Context waflib.Build.BuildContext waflib.Build.InstallContext waflib.Build.UninstallContext waflib.Build.StepContext waflib.Build.ListContext waflib.Configure.ConfigurationContext waflib.Scripting.Dist waflib.Scripting.DistCheck waflib.Build.CleanContext - - """ - - errors = Errors - """ - Shortcut to :py:mod:`waflib.Errors` provided for convenience - """ - - tools = {} - """ - A module cache for wscript files; see :py:meth:`Context.Context.load` - """ - - def __init__(self, **kw): - try: - rd = kw['run_dir'] - except KeyError: - rd = run_dir - - # binds the context to the nodes in use to avoid a context singleton - self.node_class = type('Nod3', (waflib.Node.Node,), {}) - self.node_class.__module__ = 'waflib.Node' - self.node_class.ctx = self - - self.root = self.node_class('', None) - self.cur_script = None - self.path = self.root.find_dir(rd) - - self.stack_path = [] - self.exec_dict = {'ctx':self, 'conf':self, 'bld':self, 'opt':self} - self.logger = None - - def finalize(self): - """ - Called to free resources such as logger files - """ - try: - logger = self.logger - except AttributeError: - pass - else: - Logs.free_logger(logger) - delattr(self, 'logger') - - def load(self, tool_list, *k, **kw): - """ - Loads a Waf tool as a module, and try calling the function named :py:const:`waflib.Context.Context.fun` - from it. A ``tooldir`` argument may be provided as a list of module paths. - - :param tool_list: list of Waf tool names to load - :type tool_list: list of string or space-separated string - """ - tools = Utils.to_list(tool_list) - path = Utils.to_list(kw.get('tooldir', '')) - with_sys_path = kw.get('with_sys_path', True) - - for t in tools: - module = load_tool(t, path, with_sys_path=with_sys_path) - fun = getattr(module, kw.get('name', self.fun), None) - if fun: - fun(self) - - def execute(self): - """ - Here, it calls the function name in the top-level wscript file. Most subclasses - redefine this method to provide additional functionality. - """ - self.recurse([os.path.dirname(g_module.root_path)]) - - def pre_recurse(self, node): - """ - Method executed immediately before a folder is read by :py:meth:`waflib.Context.Context.recurse`. - The current script is bound as a Node object on ``self.cur_script``, and the current path - is bound to ``self.path`` - - :param node: script - :type node: :py:class:`waflib.Node.Node` - """ - self.stack_path.append(self.cur_script) - - self.cur_script = node - self.path = node.parent - - def post_recurse(self, node): - """ - Restores ``self.cur_script`` and ``self.path`` right after :py:meth:`waflib.Context.Context.recurse` terminates. - - :param node: script - :type node: :py:class:`waflib.Node.Node` - """ - self.cur_script = self.stack_path.pop() - if self.cur_script: - self.path = self.cur_script.parent - - def recurse(self, dirs, name=None, mandatory=True, once=True, encoding=None): - """ - Runs user-provided functions from the supplied list of directories. - The directories can be either absolute, or relative to the directory - of the wscript file - - The methods :py:meth:`waflib.Context.Context.pre_recurse` and - :py:meth:`waflib.Context.Context.post_recurse` are called immediately before - and after a script has been executed. - - :param dirs: List of directories to visit - :type dirs: list of string or space-separated string - :param name: Name of function to invoke from the wscript - :type name: string - :param mandatory: whether sub wscript files are required to exist - :type mandatory: bool - :param once: read the script file once for a particular context - :type once: bool - """ - try: - cache = self.recurse_cache - except AttributeError: - cache = self.recurse_cache = {} - - for d in Utils.to_list(dirs): - - if not os.path.isabs(d): - # absolute paths only - d = os.path.join(self.path.abspath(), d) - - WSCRIPT = os.path.join(d, WSCRIPT_FILE) - WSCRIPT_FUN = WSCRIPT + '_' + (name or self.fun) - - node = self.root.find_node(WSCRIPT_FUN) - if node and (not once or node not in cache): - cache[node] = True - self.pre_recurse(node) - try: - function_code = node.read('r', encoding) - exec(compile(function_code, node.abspath(), 'exec'), self.exec_dict) - finally: - self.post_recurse(node) - elif not node: - node = self.root.find_node(WSCRIPT) - tup = (node, name or self.fun) - if node and (not once or tup not in cache): - cache[tup] = True - self.pre_recurse(node) - try: - wscript_module = load_module(node.abspath(), encoding=encoding) - user_function = getattr(wscript_module, (name or self.fun), None) - if not user_function: - if not mandatory: - continue - raise Errors.WafError('No function %r defined in %s' % (name or self.fun, node.abspath())) - user_function(self) - finally: - self.post_recurse(node) - elif not node: - if not mandatory: - continue - try: - os.listdir(d) - except OSError: - raise Errors.WafError('Cannot read the folder %r' % d) - raise Errors.WafError('No wscript file in directory %s' % d) - - def log_command(self, cmd, kw): - if Logs.verbose: - fmt = os.environ.get('WAF_CMD_FORMAT') - if fmt == 'string': - if not isinstance(cmd, str): - cmd = Utils.shell_escape(cmd) - Logs.debug('runner: %r', cmd) - Logs.debug('runner_env: kw=%s', kw) - - def exec_command(self, cmd, **kw): - """ - Runs an external process and returns the exit status:: - - def run(tsk): - ret = tsk.generator.bld.exec_command('touch foo.txt') - return ret - - If the context has the attribute 'log', then captures and logs the process stderr/stdout. - Unlike :py:meth:`waflib.Context.Context.cmd_and_log`, this method does not return the - stdout/stderr values captured. - - :param cmd: command argument for subprocess.Popen - :type cmd: string or list - :param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate. - :type kw: dict - :returns: process exit status - :rtype: integer - :raises: :py:class:`waflib.Errors.WafError` if an invalid executable is specified for a non-shell process - :raises: :py:class:`waflib.Errors.WafError` in case of execution failure - """ - subprocess = Utils.subprocess - kw['shell'] = isinstance(cmd, str) - self.log_command(cmd, kw) - - if self.logger: - self.logger.info(cmd) - - if 'stdout' not in kw: - kw['stdout'] = subprocess.PIPE - if 'stderr' not in kw: - kw['stderr'] = subprocess.PIPE - - if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]): - raise Errors.WafError('Program %s not found!' % cmd[0]) - - cargs = {} - if 'timeout' in kw: - if sys.hexversion >= 0x3030000: - cargs['timeout'] = kw['timeout'] - if not 'start_new_session' in kw: - kw['start_new_session'] = True - del kw['timeout'] - if 'input' in kw: - if kw['input']: - cargs['input'] = kw['input'] - kw['stdin'] = subprocess.PIPE - del kw['input'] - - if 'cwd' in kw: - if not isinstance(kw['cwd'], str): - kw['cwd'] = kw['cwd'].abspath() - - encoding = kw.pop('decode_as', default_encoding) - - try: - ret, out, err = Utils.run_process(cmd, kw, cargs) - except Exception as e: - raise Errors.WafError('Execution failure: %s' % str(e), ex=e) - - if out: - if not isinstance(out, str): - out = out.decode(encoding, errors='replace') - if self.logger: - self.logger.debug('out: %s', out) - else: - Logs.info(out, extra={'stream':sys.stdout, 'c1': ''}) - if err: - if not isinstance(err, str): - err = err.decode(encoding, errors='replace') - if self.logger: - self.logger.error('err: %s' % err) - else: - Logs.info(err, extra={'stream':sys.stderr, 'c1': ''}) - - return ret - - def cmd_and_log(self, cmd, **kw): - """ - Executes a process and returns stdout/stderr if the execution is successful. - An exception is thrown when the exit status is non-0. In that case, both stderr and stdout - will be bound to the WafError object (configuration tests):: - - def configure(conf): - out = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.STDOUT, quiet=waflib.Context.BOTH) - (out, err) = conf.cmd_and_log(['echo', 'hello'], output=waflib.Context.BOTH) - (out, err) = conf.cmd_and_log(cmd, input='\\n'.encode(), output=waflib.Context.STDOUT) - try: - conf.cmd_and_log(['which', 'someapp'], output=waflib.Context.BOTH) - except Errors.WafError as e: - print(e.stdout, e.stderr) - - :param cmd: args for subprocess.Popen - :type cmd: list or string - :param kw: keyword arguments for subprocess.Popen. The parameters input/timeout will be passed to wait/communicate. - :type kw: dict - :returns: a tuple containing the contents of stdout and stderr - :rtype: string - :raises: :py:class:`waflib.Errors.WafError` if an invalid executable is specified for a non-shell process - :raises: :py:class:`waflib.Errors.WafError` in case of execution failure; stdout/stderr/returncode are bound to the exception object - """ - subprocess = Utils.subprocess - kw['shell'] = isinstance(cmd, str) - self.log_command(cmd, kw) - - quiet = kw.pop('quiet', None) - to_ret = kw.pop('output', STDOUT) - - if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]): - raise Errors.WafError('Program %r not found!' % cmd[0]) - - kw['stdout'] = kw['stderr'] = subprocess.PIPE - if quiet is None: - self.to_log(cmd) - - cargs = {} - if 'timeout' in kw: - if sys.hexversion >= 0x3030000: - cargs['timeout'] = kw['timeout'] - if not 'start_new_session' in kw: - kw['start_new_session'] = True - del kw['timeout'] - if 'input' in kw: - if kw['input']: - cargs['input'] = kw['input'] - kw['stdin'] = subprocess.PIPE - del kw['input'] - - if 'cwd' in kw: - if not isinstance(kw['cwd'], str): - kw['cwd'] = kw['cwd'].abspath() - - encoding = kw.pop('decode_as', default_encoding) - - try: - ret, out, err = Utils.run_process(cmd, kw, cargs) - except Exception as e: - raise Errors.WafError('Execution failure: %s' % str(e), ex=e) - - if not isinstance(out, str): - out = out.decode(encoding, errors='replace') - if not isinstance(err, str): - err = err.decode(encoding, errors='replace') - - if out and quiet != STDOUT and quiet != BOTH: - self.to_log('out: %s' % out) - if err and quiet != STDERR and quiet != BOTH: - self.to_log('err: %s' % err) - - if ret: - e = Errors.WafError('Command %r returned %r' % (cmd, ret)) - e.returncode = ret - e.stderr = err - e.stdout = out - raise e - - if to_ret == BOTH: - return (out, err) - elif to_ret == STDERR: - return err - return out - - def fatal(self, msg, ex=None): - """ - Prints an error message in red and stops command execution; this is - usually used in the configuration section:: - - def configure(conf): - conf.fatal('a requirement is missing') - - :param msg: message to display - :type msg: string - :param ex: optional exception object - :type ex: exception - :raises: :py:class:`waflib.Errors.ConfigurationError` - """ - if self.logger: - self.logger.info('from %s: %s' % (self.path.abspath(), msg)) - try: - logfile = self.logger.handlers[0].baseFilename - except AttributeError: - pass - else: - if os.environ.get('WAF_PRINT_FAILURE_LOG'): - # see #1930 - msg = 'Log from (%s):\n%s\n' % (logfile, Utils.readf(logfile)) - else: - msg = '%s\n(complete log in %s)' % (msg, logfile) - raise self.errors.ConfigurationError(msg, ex=ex) - - def to_log(self, msg): - """ - Logs information to the logger (if present), or to stderr. - Empty messages are not printed:: - - def build(bld): - bld.to_log('starting the build') - - Provide a logger on the context class or override this method if necessary. - - :param msg: message - :type msg: string - """ - if not msg: - return - if self.logger: - self.logger.info(msg) - else: - sys.stderr.write(str(msg)) - sys.stderr.flush() - - - def msg(self, *k, **kw): - """ - Prints a configuration message of the form ``msg: result``. - The second part of the message will be in colors. The output - can be disabled easly by setting ``in_msg`` to a positive value:: - - def configure(conf): - self.in_msg = 1 - conf.msg('Checking for library foo', 'ok') - # no output - - :param msg: message to display to the user - :type msg: string - :param result: result to display - :type result: string or boolean - :param color: color to use, see :py:const:`waflib.Logs.colors_lst` - :type color: string - """ - try: - msg = kw['msg'] - except KeyError: - msg = k[0] - - self.start_msg(msg, **kw) - - try: - result = kw['result'] - except KeyError: - result = k[1] - - color = kw.get('color') - if not isinstance(color, str): - color = result and 'GREEN' or 'YELLOW' - - self.end_msg(result, color, **kw) - - def start_msg(self, *k, **kw): - """ - Prints the beginning of a 'Checking for xxx' message. See :py:meth:`waflib.Context.Context.msg` - """ - if kw.get('quiet'): - return - - msg = kw.get('msg') or k[0] - try: - if self.in_msg: - self.in_msg += 1 - return - except AttributeError: - self.in_msg = 0 - self.in_msg += 1 - - try: - self.line_just = max(self.line_just, len(msg)) - except AttributeError: - self.line_just = max(40, len(msg)) - for x in (self.line_just * '-', msg): - self.to_log(x) - Logs.pprint('NORMAL', "%s :" % msg.ljust(self.line_just), sep='') - - def end_msg(self, *k, **kw): - """Prints the end of a 'Checking for' message. See :py:meth:`waflib.Context.Context.msg`""" - if kw.get('quiet'): - return - self.in_msg -= 1 - if self.in_msg: - return - - result = kw.get('result') or k[0] - - defcolor = 'GREEN' - if result is True: - msg = 'ok' - elif not result: - msg = 'not found' - defcolor = 'YELLOW' - else: - msg = str(result) - - self.to_log(msg) - try: - color = kw['color'] - except KeyError: - if len(k) > 1 and k[1] in Logs.colors_lst: - # compatibility waf 1.7 - color = k[1] - else: - color = defcolor - Logs.pprint(color, msg) - - def load_special_tools(self, var, ban=[]): - """ - Loads third-party extensions modules for certain programming languages - by trying to list certain files in the extras/ directory. This method - is typically called once for a programming language group, see for - example :py:mod:`waflib.Tools.compiler_c` - - :param var: glob expression, for example 'cxx\\_\\*.py' - :type var: string - :param ban: list of exact file names to exclude - :type ban: list of string - """ - if os.path.isdir(waf_dir): - lst = self.root.find_node(waf_dir).find_node('waflib/extras').ant_glob(var) - for x in lst: - if not x.name in ban: - load_tool(x.name.replace('.py', '')) - else: - from zipfile import PyZipFile - waflibs = PyZipFile(waf_dir) - lst = waflibs.namelist() - for x in lst: - if not re.match('waflib/extras/%s' % var.replace('*', '.*'), var): - continue - f = os.path.basename(x) - doban = False - for b in ban: - r = b.replace('*', '.*') - if re.match(r, f): - doban = True - if not doban: - f = f.replace('.py', '') - load_tool(f) - -cache_modules = {} -""" -Dictionary holding already loaded modules (wscript), indexed by their absolute path. -The modules are added automatically by :py:func:`waflib.Context.load_module` -""" - -def load_module(path, encoding=None): - """ - Loads a wscript file as a python module. This method caches results in :py:attr:`waflib.Context.cache_modules` - - :param path: file path - :type path: string - :return: Loaded Python module - :rtype: module - """ - try: - return cache_modules[path] - except KeyError: - pass - - module = imp.new_module(WSCRIPT_FILE) - try: - code = Utils.readf(path, m='r', encoding=encoding) - except EnvironmentError: - raise Errors.WafError('Could not read the file %r' % path) - - module_dir = os.path.dirname(path) - sys.path.insert(0, module_dir) - try: - exec(compile(code, path, 'exec'), module.__dict__) - finally: - sys.path.remove(module_dir) - - cache_modules[path] = module - return module - -def load_tool(tool, tooldir=None, ctx=None, with_sys_path=True): - """ - Imports a Waf tool as a python module, and stores it in the dict :py:const:`waflib.Context.Context.tools` - - :type tool: string - :param tool: Name of the tool - :type tooldir: list - :param tooldir: List of directories to search for the tool module - :type with_sys_path: boolean - :param with_sys_path: whether or not to search the regular sys.path, besides waf_dir and potentially given tooldirs - """ - if tool == 'java': - tool = 'javaw' # jython - else: - tool = tool.replace('++', 'xx') - - if not with_sys_path: - back_path = sys.path - sys.path = [] - try: - if tooldir: - assert isinstance(tooldir, list) - sys.path = tooldir + sys.path - try: - __import__(tool) - except ImportError as e: - e.waf_sys_path = list(sys.path) - raise - finally: - for d in tooldir: - sys.path.remove(d) - ret = sys.modules[tool] - Context.tools[tool] = ret - return ret - else: - if not with_sys_path: - sys.path.insert(0, waf_dir) - try: - for x in ('waflib.Tools.%s', 'waflib.extras.%s', 'waflib.%s', '%s'): - try: - __import__(x % tool) - break - except ImportError: - x = None - else: # raise an exception - __import__(tool) - except ImportError as e: - e.waf_sys_path = list(sys.path) - raise - finally: - if not with_sys_path: - sys.path.remove(waf_dir) - ret = sys.modules[x % tool] - Context.tools[tool] = ret - return ret - finally: - if not with_sys_path: - sys.path += back_path - diff --git a/ldb-2.0.8/third_party/waf/waflib/Errors.py b/ldb-2.0.8/third_party/waf/waflib/Errors.py deleted file mode 100644 index bf75c1b..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Errors.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2010-2018 (ita) - -""" -Exceptions used in the Waf code -""" - -import traceback, sys - -class WafError(Exception): - """Base class for all Waf errors""" - def __init__(self, msg='', ex=None): - """ - :param msg: error message - :type msg: string - :param ex: exception causing this error (optional) - :type ex: exception - """ - Exception.__init__(self) - self.msg = msg - assert not isinstance(msg, Exception) - - self.stack = [] - if ex: - if not msg: - self.msg = str(ex) - if isinstance(ex, WafError): - self.stack = ex.stack - else: - self.stack = traceback.extract_tb(sys.exc_info()[2]) - self.stack += traceback.extract_stack()[:-1] - self.verbose_msg = ''.join(traceback.format_list(self.stack)) - - def __str__(self): - return str(self.msg) - -class BuildError(WafError): - """Error raised during the build and install phases""" - def __init__(self, error_tasks=[]): - """ - :param error_tasks: tasks that could not complete normally - :type error_tasks: list of task objects - """ - self.tasks = error_tasks - WafError.__init__(self, self.format_error()) - - def format_error(self): - """Formats the error messages from the tasks that failed""" - lst = ['Build failed'] - for tsk in self.tasks: - txt = tsk.format_error() - if txt: - lst.append(txt) - return '\n'.join(lst) - -class ConfigurationError(WafError): - """Configuration exception raised in particular by :py:meth:`waflib.Context.Context.fatal`""" - pass - -class TaskRescan(WafError): - """Task-specific exception type signalling required signature recalculations""" - pass - -class TaskNotReady(WafError): - """Task-specific exception type signalling that task signatures cannot be computed""" - pass - diff --git a/ldb-2.0.8/third_party/waf/waflib/Logs.py b/ldb-2.0.8/third_party/waf/waflib/Logs.py deleted file mode 100644 index 298411d..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Logs.py +++ /dev/null @@ -1,382 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2005-2018 (ita) - -""" -logging, colors, terminal width and pretty-print -""" - -import os, re, traceback, sys -from waflib import Utils, ansiterm - -if not os.environ.get('NOSYNC', False): - # synchronized output is nearly mandatory to prevent garbled output - if sys.stdout.isatty() and id(sys.stdout) == id(sys.__stdout__): - sys.stdout = ansiterm.AnsiTerm(sys.stdout) - if sys.stderr.isatty() and id(sys.stderr) == id(sys.__stderr__): - sys.stderr = ansiterm.AnsiTerm(sys.stderr) - -# import the logging module after since it holds a reference on sys.stderr -# in case someone uses the root logger -import logging - -LOG_FORMAT = os.environ.get('WAF_LOG_FORMAT', '%(asctime)s %(c1)s%(zone)s%(c2)s %(message)s') -HOUR_FORMAT = os.environ.get('WAF_HOUR_FORMAT', '%H:%M:%S') - -zones = [] -""" -See :py:class:`waflib.Logs.log_filter` -""" - -verbose = 0 -""" -Global verbosity level, see :py:func:`waflib.Logs.debug` and :py:func:`waflib.Logs.error` -""" - -colors_lst = { -'USE' : True, -'BOLD' :'\x1b[01;1m', -'RED' :'\x1b[01;31m', -'GREEN' :'\x1b[32m', -'YELLOW':'\x1b[33m', -'PINK' :'\x1b[35m', -'BLUE' :'\x1b[01;34m', -'CYAN' :'\x1b[36m', -'GREY' :'\x1b[37m', -'NORMAL':'\x1b[0m', -'cursor_on' :'\x1b[?25h', -'cursor_off' :'\x1b[?25l', -} - -indicator = '\r\x1b[K%s%s%s' - -try: - unicode -except NameError: - unicode = None - -def enable_colors(use): - """ - If *1* is given, then the system will perform a few verifications - before enabling colors, such as checking whether the interpreter - is running in a terminal. A value of zero will disable colors, - and a value above *1* will force colors. - - :param use: whether to enable colors or not - :type use: integer - """ - if use == 1: - if not (sys.stderr.isatty() or sys.stdout.isatty()): - use = 0 - if Utils.is_win32 and os.name != 'java': - term = os.environ.get('TERM', '') # has ansiterm - else: - term = os.environ.get('TERM', 'dumb') - - if term in ('dumb', 'emacs'): - use = 0 - - if use >= 1: - os.environ['TERM'] = 'vt100' - - colors_lst['USE'] = use - -# If console packages are available, replace the dummy function with a real -# implementation -try: - get_term_cols = ansiterm.get_term_cols -except AttributeError: - def get_term_cols(): - return 80 - -get_term_cols.__doc__ = """ - Returns the console width in characters. - - :return: the number of characters per line - :rtype: int - """ - -def get_color(cl): - """ - Returns the ansi sequence corresponding to the given color name. - An empty string is returned when coloring is globally disabled. - - :param cl: color name in capital letters - :type cl: string - """ - if colors_lst['USE']: - return colors_lst.get(cl, '') - return '' - -class color_dict(object): - """attribute-based color access, eg: colors.PINK""" - def __getattr__(self, a): - return get_color(a) - def __call__(self, a): - return get_color(a) - -colors = color_dict() - -re_log = re.compile(r'(\w+): (.*)', re.M) -class log_filter(logging.Filter): - """ - Waf logs are of the form 'name: message', and can be filtered by 'waf --zones=name'. - For example, the following:: - - from waflib import Logs - Logs.debug('test: here is a message') - - Will be displayed only when executing:: - - $ waf --zones=test - """ - def __init__(self, name=''): - logging.Filter.__init__(self, name) - - def filter(self, rec): - """ - Filters log records by zone and by logging level - - :param rec: log entry - """ - rec.zone = rec.module - if rec.levelno >= logging.INFO: - return True - - m = re_log.match(rec.msg) - if m: - rec.zone = m.group(1) - rec.msg = m.group(2) - - if zones: - return getattr(rec, 'zone', '') in zones or '*' in zones - elif not verbose > 2: - return False - return True - -class log_handler(logging.StreamHandler): - """Dispatches messages to stderr/stdout depending on the severity level""" - def emit(self, record): - """ - Delegates the functionality to :py:meth:`waflib.Log.log_handler.emit_override` - """ - # default implementation - try: - try: - self.stream = record.stream - except AttributeError: - if record.levelno >= logging.WARNING: - record.stream = self.stream = sys.stderr - else: - record.stream = self.stream = sys.stdout - self.emit_override(record) - self.flush() - except (KeyboardInterrupt, SystemExit): - raise - except: # from the python library -_- - self.handleError(record) - - def emit_override(self, record, **kw): - """ - Writes the log record to the desired stream (stderr/stdout) - """ - self.terminator = getattr(record, 'terminator', '\n') - stream = self.stream - if unicode: - # python2 - msg = self.formatter.format(record) - fs = '%s' + self.terminator - try: - if (isinstance(msg, unicode) and getattr(stream, 'encoding', None)): - fs = fs.decode(stream.encoding) - try: - stream.write(fs % msg) - except UnicodeEncodeError: - stream.write((fs % msg).encode(stream.encoding)) - else: - stream.write(fs % msg) - except UnicodeError: - stream.write((fs % msg).encode('utf-8')) - else: - logging.StreamHandler.emit(self, record) - -class formatter(logging.Formatter): - """Simple log formatter which handles colors""" - def __init__(self): - logging.Formatter.__init__(self, LOG_FORMAT, HOUR_FORMAT) - - def format(self, rec): - """ - Formats records and adds colors as needed. The records do not get - a leading hour format if the logging level is above *INFO*. - """ - try: - msg = rec.msg.decode('utf-8') - except Exception: - msg = rec.msg - - use = colors_lst['USE'] - if (use == 1 and rec.stream.isatty()) or use == 2: - - c1 = getattr(rec, 'c1', None) - if c1 is None: - c1 = '' - if rec.levelno >= logging.ERROR: - c1 = colors.RED - elif rec.levelno >= logging.WARNING: - c1 = colors.YELLOW - elif rec.levelno >= logging.INFO: - c1 = colors.GREEN - c2 = getattr(rec, 'c2', colors.NORMAL) - msg = '%s%s%s' % (c1, msg, c2) - else: - # remove single \r that make long lines in text files - # and other terminal commands - msg = re.sub(r'\r(?!\n)|\x1B\[(K|.*?(m|h|l))', '', msg) - - if rec.levelno >= logging.INFO: - # the goal of this is to format without the leading "Logs, hour" prefix - if rec.args: - try: - return msg % rec.args - except UnicodeDecodeError: - return msg.encode('utf-8') % rec.args - return msg - - rec.msg = msg - rec.c1 = colors.PINK - rec.c2 = colors.NORMAL - return logging.Formatter.format(self, rec) - -log = None -"""global logger for Logs.debug, Logs.error, etc""" - -def debug(*k, **kw): - """ - Wraps logging.debug and discards messages if the verbosity level :py:attr:`waflib.Logs.verbose` ≤ 0 - """ - if verbose: - k = list(k) - k[0] = k[0].replace('\n', ' ') - log.debug(*k, **kw) - -def error(*k, **kw): - """ - Wrap logging.errors, adds the stack trace when the verbosity level :py:attr:`waflib.Logs.verbose` ≥ 2 - """ - log.error(*k, **kw) - if verbose > 2: - st = traceback.extract_stack() - if st: - st = st[:-1] - buf = [] - for filename, lineno, name, line in st: - buf.append(' File %r, line %d, in %s' % (filename, lineno, name)) - if line: - buf.append(' %s' % line.strip()) - if buf: - log.error('\n'.join(buf)) - -def warn(*k, **kw): - """ - Wraps logging.warning - """ - log.warning(*k, **kw) - -def info(*k, **kw): - """ - Wraps logging.info - """ - log.info(*k, **kw) - -def init_log(): - """ - Initializes the logger :py:attr:`waflib.Logs.log` - """ - global log - log = logging.getLogger('waflib') - log.handlers = [] - log.filters = [] - hdlr = log_handler() - hdlr.setFormatter(formatter()) - log.addHandler(hdlr) - log.addFilter(log_filter()) - log.setLevel(logging.DEBUG) - -def make_logger(path, name): - """ - Creates a simple logger, which is often used to redirect the context command output:: - - from waflib import Logs - bld.logger = Logs.make_logger('test.log', 'build') - bld.check(header_name='sadlib.h', features='cxx cprogram', mandatory=False) - - # have the file closed immediately - Logs.free_logger(bld.logger) - - # stop logging - bld.logger = None - - The method finalize() of the command will try to free the logger, if any - - :param path: file name to write the log output to - :type path: string - :param name: logger name (loggers are reused) - :type name: string - """ - logger = logging.getLogger(name) - if sys.hexversion > 0x3000000: - encoding = sys.stdout.encoding - else: - encoding = None - hdlr = logging.FileHandler(path, 'w', encoding=encoding) - formatter = logging.Formatter('%(message)s') - hdlr.setFormatter(formatter) - logger.addHandler(hdlr) - logger.setLevel(logging.DEBUG) - return logger - -def make_mem_logger(name, to_log, size=8192): - """ - Creates a memory logger to avoid writing concurrently to the main logger - """ - from logging.handlers import MemoryHandler - logger = logging.getLogger(name) - hdlr = MemoryHandler(size, target=to_log) - formatter = logging.Formatter('%(message)s') - hdlr.setFormatter(formatter) - logger.addHandler(hdlr) - logger.memhandler = hdlr - logger.setLevel(logging.DEBUG) - return logger - -def free_logger(logger): - """ - Frees the resources held by the loggers created through make_logger or make_mem_logger. - This is used for file cleanup and for handler removal (logger objects are re-used). - """ - try: - for x in logger.handlers: - x.close() - logger.removeHandler(x) - except Exception: - pass - -def pprint(col, msg, label='', sep='\n'): - """ - Prints messages in color immediately on stderr:: - - from waflib import Logs - Logs.pprint('RED', 'Something bad just happened') - - :param col: color name to use in :py:const:`Logs.colors_lst` - :type col: string - :param msg: message to display - :type msg: string or a value that can be printed by %s - :param label: a message to add after the colored output - :type label: string - :param sep: a string to append at the end (line separator) - :type sep: string - """ - info('%s%s%s %s', colors(col), msg, colors.NORMAL, label, extra={'terminator':sep}) - diff --git a/ldb-2.0.8/third_party/waf/waflib/Node.py b/ldb-2.0.8/third_party/waf/waflib/Node.py deleted file mode 100644 index 2ad1846..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Node.py +++ /dev/null @@ -1,969 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2005-2018 (ita) - -""" -Node: filesystem structure - -#. Each file/folder is represented by exactly one node. - -#. Some potential class properties are stored on :py:class:`waflib.Build.BuildContext` : nodes to depend on, etc. - Unused class members can increase the `.wafpickle` file size sensibly. - -#. Node objects should never be created directly, use - the methods :py:func:`Node.make_node` or :py:func:`Node.find_node` for the low-level operations - -#. The methods :py:func:`Node.find_resource`, :py:func:`Node.find_dir` :py:func:`Node.find_or_declare` must be - used when a build context is present - -#. Each instance of :py:class:`waflib.Context.Context` has a unique :py:class:`Node` subclass required for serialization. - (:py:class:`waflib.Node.Nod3`, see the :py:class:`waflib.Context.Context` initializer). A reference to the context - owning a node is held as *self.ctx* -""" - -import os, re, sys, shutil -from waflib import Utils, Errors - -exclude_regs = ''' -**/*~ -**/#*# -**/.#* -**/%*% -**/._* -**/*.swp -**/CVS -**/CVS/** -**/.cvsignore -**/SCCS -**/SCCS/** -**/vssver.scc -**/.svn -**/.svn/** -**/BitKeeper -**/.git -**/.git/** -**/.gitignore -**/.bzr -**/.bzrignore -**/.bzr/** -**/.hg -**/.hg/** -**/_MTN -**/_MTN/** -**/.arch-ids -**/{arch} -**/_darcs -**/_darcs/** -**/.intlcache -**/.DS_Store''' -""" -Ant patterns for files and folders to exclude while doing the -recursive traversal in :py:meth:`waflib.Node.Node.ant_glob` -""" - -def ant_matcher(s, ignorecase): - reflags = re.I if ignorecase else 0 - ret = [] - for x in Utils.to_list(s): - x = x.replace('\\', '/').replace('//', '/') - if x.endswith('/'): - x += '**' - accu = [] - for k in x.split('/'): - if k == '**': - accu.append(k) - else: - k = k.replace('.', '[.]').replace('*', '.*').replace('?', '.').replace('+', '\\+') - k = '^%s$' % k - try: - exp = re.compile(k, flags=reflags) - except Exception as e: - raise Errors.WafError('Invalid pattern: %s' % k, e) - else: - accu.append(exp) - ret.append(accu) - return ret - -def ant_sub_filter(name, nn): - ret = [] - for lst in nn: - if not lst: - pass - elif lst[0] == '**': - ret.append(lst) - if len(lst) > 1: - if lst[1].match(name): - ret.append(lst[2:]) - else: - ret.append([]) - elif lst[0].match(name): - ret.append(lst[1:]) - return ret - -def ant_sub_matcher(name, pats): - nacc = ant_sub_filter(name, pats[0]) - nrej = ant_sub_filter(name, pats[1]) - if [] in nrej: - nacc = [] - return [nacc, nrej] - -class Node(object): - """ - This class is organized in two parts: - - * The basic methods meant for filesystem access (compute paths, create folders, etc) - * The methods bound to a :py:class:`waflib.Build.BuildContext` (require ``bld.srcnode`` and ``bld.bldnode``) - """ - - dict_class = dict - """ - Subclasses can provide a dict class to enable case insensitivity for example. - """ - - __slots__ = ('name', 'parent', 'children', 'cache_abspath', 'cache_isdir') - def __init__(self, name, parent): - """ - .. note:: Use :py:func:`Node.make_node` or :py:func:`Node.find_node` instead of calling this constructor - """ - self.name = name - self.parent = parent - if parent: - if name in parent.children: - raise Errors.WafError('node %s exists in the parent files %r already' % (name, parent)) - parent.children[name] = self - - def __setstate__(self, data): - "Deserializes node information, used for persistence" - self.name = data[0] - self.parent = data[1] - if data[2] is not None: - # Issue 1480 - self.children = self.dict_class(data[2]) - - def __getstate__(self): - "Serializes node information, used for persistence" - return (self.name, self.parent, getattr(self, 'children', None)) - - def __str__(self): - """ - String representation (abspath), for debugging purposes - - :rtype: string - """ - return self.abspath() - - def __repr__(self): - """ - String representation (abspath), for debugging purposes - - :rtype: string - """ - return self.abspath() - - def __copy__(self): - """ - Provided to prevent nodes from being copied - - :raises: :py:class:`waflib.Errors.WafError` - """ - raise Errors.WafError('nodes are not supposed to be copied') - - def read(self, flags='r', encoding='latin-1'): - """ - Reads and returns the contents of the file represented by this node, see :py:func:`waflib.Utils.readf`:: - - def build(bld): - bld.path.find_node('wscript').read() - - :param flags: Open mode - :type flags: string - :param encoding: encoding value for Python3 - :type encoding: string - :rtype: string or bytes - :return: File contents - """ - return Utils.readf(self.abspath(), flags, encoding) - - def write(self, data, flags='w', encoding='latin-1'): - """ - Writes data to the file represented by this node, see :py:func:`waflib.Utils.writef`:: - - def build(bld): - bld.path.make_node('foo.txt').write('Hello, world!') - - :param data: data to write - :type data: string - :param flags: Write mode - :type flags: string - :param encoding: encoding value for Python3 - :type encoding: string - """ - Utils.writef(self.abspath(), data, flags, encoding) - - def read_json(self, convert=True, encoding='utf-8'): - """ - Reads and parses the contents of this node as JSON (Python ≥ 2.6):: - - def build(bld): - bld.path.find_node('abc.json').read_json() - - Note that this by default automatically decodes unicode strings on Python2, unlike what the Python JSON module does. - - :type convert: boolean - :param convert: Prevents decoding of unicode strings on Python2 - :type encoding: string - :param encoding: The encoding of the file to read. This default to UTF8 as per the JSON standard - :rtype: object - :return: Parsed file contents - """ - import json # Python 2.6 and up - object_pairs_hook = None - if convert and sys.hexversion < 0x3000000: - try: - _type = unicode - except NameError: - _type = str - - def convert(value): - if isinstance(value, list): - return [convert(element) for element in value] - elif isinstance(value, _type): - return str(value) - else: - return value - - def object_pairs(pairs): - return dict((str(pair[0]), convert(pair[1])) for pair in pairs) - - object_pairs_hook = object_pairs - - return json.loads(self.read(encoding=encoding), object_pairs_hook=object_pairs_hook) - - def write_json(self, data, pretty=True): - """ - Writes a python object as JSON to disk (Python ≥ 2.6) as UTF-8 data (JSON standard):: - - def build(bld): - bld.path.find_node('xyz.json').write_json(199) - - :type data: object - :param data: The data to write to disk - :type pretty: boolean - :param pretty: Determines if the JSON will be nicely space separated - """ - import json # Python 2.6 and up - indent = 2 - separators = (',', ': ') - sort_keys = pretty - newline = os.linesep - if not pretty: - indent = None - separators = (',', ':') - newline = '' - output = json.dumps(data, indent=indent, separators=separators, sort_keys=sort_keys) + newline - self.write(output, encoding='utf-8') - - def exists(self): - """ - Returns whether the Node is present on the filesystem - - :rtype: bool - """ - return os.path.exists(self.abspath()) - - def isdir(self): - """ - Returns whether the Node represents a folder - - :rtype: bool - """ - return os.path.isdir(self.abspath()) - - def chmod(self, val): - """ - Changes the file/dir permissions:: - - def build(bld): - bld.path.chmod(493) # 0755 - """ - os.chmod(self.abspath(), val) - - def delete(self, evict=True): - """ - Removes the file/folder from the filesystem (equivalent to `rm -rf`), and remove this object from the Node tree. - Do not use this object after calling this method. - """ - try: - try: - if os.path.isdir(self.abspath()): - shutil.rmtree(self.abspath()) - else: - os.remove(self.abspath()) - except OSError: - if os.path.exists(self.abspath()): - raise - finally: - if evict: - self.evict() - - def evict(self): - """ - Removes this node from the Node tree - """ - del self.parent.children[self.name] - - def suffix(self): - """ - Returns the file rightmost extension, for example `a.b.c.d → .d` - - :rtype: string - """ - k = max(0, self.name.rfind('.')) - return self.name[k:] - - def height(self): - """ - Returns the depth in the folder hierarchy from the filesystem root or from all the file drives - - :returns: filesystem depth - :rtype: integer - """ - d = self - val = -1 - while d: - d = d.parent - val += 1 - return val - - def listdir(self): - """ - Lists the folder contents - - :returns: list of file/folder names ordered alphabetically - :rtype: list of string - """ - lst = Utils.listdir(self.abspath()) - lst.sort() - return lst - - def mkdir(self): - """ - Creates a folder represented by this node. Intermediate folders are created as needed. - - :raises: :py:class:`waflib.Errors.WafError` when the folder is missing - """ - if self.isdir(): - return - - try: - self.parent.mkdir() - except OSError: - pass - - if self.name: - try: - os.makedirs(self.abspath()) - except OSError: - pass - - if not self.isdir(): - raise Errors.WafError('Could not create the directory %r' % self) - - try: - self.children - except AttributeError: - self.children = self.dict_class() - - def find_node(self, lst): - """ - Finds a node on the file system (files or folders), and creates the corresponding Node objects if it exists - - :param lst: relative path - :type lst: string or list of string - :returns: The corresponding Node object or None if no entry was found on the filesystem - :rtype: :py:class:´waflib.Node.Node´ - """ - - if isinstance(lst, str): - lst = [x for x in Utils.split_path(lst) if x and x != '.'] - - if lst and lst[0].startswith('\\\\') and not self.parent: - node = self.ctx.root.make_node(lst[0]) - node.cache_isdir = True - return node.find_node(lst[1:]) - - cur = self - for x in lst: - if x == '..': - cur = cur.parent or cur - continue - - try: - ch = cur.children - except AttributeError: - cur.children = self.dict_class() - else: - try: - cur = ch[x] - continue - except KeyError: - pass - - # optimistic: create the node first then look if it was correct to do so - cur = self.__class__(x, cur) - if not cur.exists(): - cur.evict() - return None - - if not cur.exists(): - cur.evict() - return None - - return cur - - def make_node(self, lst): - """ - Returns or creates a Node object corresponding to the input path without considering the filesystem. - - :param lst: relative path - :type lst: string or list of string - :rtype: :py:class:´waflib.Node.Node´ - """ - if isinstance(lst, str): - lst = [x for x in Utils.split_path(lst) if x and x != '.'] - - cur = self - for x in lst: - if x == '..': - cur = cur.parent or cur - continue - - try: - cur = cur.children[x] - except AttributeError: - cur.children = self.dict_class() - except KeyError: - pass - else: - continue - cur = self.__class__(x, cur) - return cur - - def search_node(self, lst): - """ - Returns a Node previously defined in the data structure. The filesystem is not considered. - - :param lst: relative path - :type lst: string or list of string - :rtype: :py:class:´waflib.Node.Node´ or None if there is no entry in the Node datastructure - """ - if isinstance(lst, str): - lst = [x for x in Utils.split_path(lst) if x and x != '.'] - - cur = self - for x in lst: - if x == '..': - cur = cur.parent or cur - else: - try: - cur = cur.children[x] - except (AttributeError, KeyError): - return None - return cur - - def path_from(self, node): - """ - Path of this node seen from the other:: - - def build(bld): - n1 = bld.path.find_node('foo/bar/xyz.txt') - n2 = bld.path.find_node('foo/stuff/') - n1.path_from(n2) # '../bar/xyz.txt' - - :param node: path to use as a reference - :type node: :py:class:`waflib.Node.Node` - :returns: a relative path or an absolute one if that is better - :rtype: string - """ - c1 = self - c2 = node - - c1h = c1.height() - c2h = c2.height() - - lst = [] - up = 0 - - while c1h > c2h: - lst.append(c1.name) - c1 = c1.parent - c1h -= 1 - - while c2h > c1h: - up += 1 - c2 = c2.parent - c2h -= 1 - - while not c1 is c2: - lst.append(c1.name) - up += 1 - - c1 = c1.parent - c2 = c2.parent - - if c1.parent: - lst.extend(['..'] * up) - lst.reverse() - return os.sep.join(lst) or '.' - else: - return self.abspath() - - def abspath(self): - """ - Returns the absolute path. A cache is kept in the context as ``cache_node_abspath`` - - :rtype: string - """ - try: - return self.cache_abspath - except AttributeError: - pass - # think twice before touching this (performance + complexity + correctness) - - if not self.parent: - val = os.sep - elif not self.parent.name: - val = os.sep + self.name - else: - val = self.parent.abspath() + os.sep + self.name - self.cache_abspath = val - return val - - if Utils.is_win32: - def abspath(self): - try: - return self.cache_abspath - except AttributeError: - pass - if not self.parent: - val = '' - elif not self.parent.name: - val = self.name + os.sep - else: - val = self.parent.abspath().rstrip(os.sep) + os.sep + self.name - self.cache_abspath = val - return val - - def is_child_of(self, node): - """ - Returns whether the object belongs to a subtree of the input node:: - - def build(bld): - node = bld.path.find_node('wscript') - node.is_child_of(bld.path) # True - - :param node: path to use as a reference - :type node: :py:class:`waflib.Node.Node` - :rtype: bool - """ - p = self - diff = self.height() - node.height() - while diff > 0: - diff -= 1 - p = p.parent - return p is node - - def ant_iter(self, accept=None, maxdepth=25, pats=[], dir=False, src=True, remove=True, quiet=False): - """ - Recursive method used by :py:meth:`waflib.Node.ant_glob`. - - :param accept: function used for accepting/rejecting a node, returns the patterns that can be still accepted in recursion - :type accept: function - :param maxdepth: maximum depth in the filesystem (25) - :type maxdepth: int - :param pats: list of patterns to accept and list of patterns to exclude - :type pats: tuple - :param dir: return folders too (False by default) - :type dir: bool - :param src: return files (True by default) - :type src: bool - :param remove: remove files/folders that do not exist (True by default) - :type remove: bool - :param quiet: disable build directory traversal warnings (verbose mode) - :type quiet: bool - :returns: A generator object to iterate from - :rtype: iterator - """ - dircont = self.listdir() - - try: - lst = set(self.children.keys()) - except AttributeError: - self.children = self.dict_class() - else: - if remove: - for x in lst - set(dircont): - self.children[x].evict() - - for name in dircont: - npats = accept(name, pats) - if npats and npats[0]: - accepted = [] in npats[0] - - node = self.make_node([name]) - - isdir = node.isdir() - if accepted: - if isdir: - if dir: - yield node - elif src: - yield node - - if isdir: - node.cache_isdir = True - if maxdepth: - for k in node.ant_iter(accept=accept, maxdepth=maxdepth - 1, pats=npats, dir=dir, src=src, remove=remove, quiet=quiet): - yield k - - def ant_glob(self, *k, **kw): - """ - Finds files across folders and returns Node objects: - - * ``**/*`` find all files recursively - * ``**/*.class`` find all files ending by .class - * ``..`` find files having two dot characters - - For example:: - - def configure(cfg): - # find all .cpp files - cfg.path.ant_glob('**/*.cpp') - # find particular files from the root filesystem (can be slow) - cfg.root.ant_glob('etc/*.txt') - # simple exclusion rule example - cfg.path.ant_glob('*.c*', excl=['*.c'], src=True, dir=False) - - For more information about the patterns, consult http://ant.apache.org/manual/dirtasks.html - Please remember that the '..' sequence does not represent the parent directory:: - - def configure(cfg): - cfg.path.ant_glob('../*.h') # incorrect - cfg.path.parent.ant_glob('*.h') # correct - - The Node structure is itself a filesystem cache, so certain precautions must - be taken while matching files in the build or installation phases. - Nodes objects that do have a corresponding file or folder are garbage-collected by default. - This garbage collection is usually required to prevent returning files that do not - exist anymore. Yet, this may also remove Node objects of files that are yet-to-be built. - - This typically happens when trying to match files in the build directory, - but there are also cases when files are created in the source directory. - Run ``waf -v`` to display any warnings, and try consider passing ``remove=False`` - when matching files in the build directory. - - Since ant_glob can traverse both source and build folders, it is a best practice - to call this method only from the most specific build node:: - - def build(bld): - # traverses the build directory, may need ``remove=False``: - bld.path.ant_glob('project/dir/**/*.h') - # better, no accidental build directory traversal: - bld.path.find_node('project/dir').ant_glob('**/*.h') # best - - In addition, files and folders are listed immediately. When matching files in the - build folders, consider passing ``generator=True`` so that the generator object - returned can defer computation to a later stage. For example:: - - def build(bld): - bld(rule='tar xvf ${SRC}', source='arch.tar') - bld.add_group() - gen = bld.bldnode.ant_glob("*.h", generator=True, remove=True) - # files will be listed only after the arch.tar is unpacked - bld(rule='ls ${SRC}', source=gen, name='XYZ') - - - :param incl: ant patterns or list of patterns to include - :type incl: string or list of strings - :param excl: ant patterns or list of patterns to exclude - :type excl: string or list of strings - :param dir: return folders too (False by default) - :type dir: bool - :param src: return files (True by default) - :type src: bool - :param maxdepth: maximum depth of recursion - :type maxdepth: int - :param ignorecase: ignore case while matching (False by default) - :type ignorecase: bool - :param generator: Whether to evaluate the Nodes lazily - :type generator: bool - :param remove: remove files/folders that do not exist (True by default) - :type remove: bool - :param quiet: disable build directory traversal warnings (verbose mode) - :type quiet: bool - :returns: The corresponding Node objects as a list or as a generator object (generator=True) - :rtype: by default, list of :py:class:`waflib.Node.Node` instances - """ - src = kw.get('src', True) - dir = kw.get('dir') - excl = kw.get('excl', exclude_regs) - incl = k and k[0] or kw.get('incl', '**') - remove = kw.get('remove', True) - maxdepth = kw.get('maxdepth', 25) - ignorecase = kw.get('ignorecase', False) - quiet = kw.get('quiet', False) - pats = (ant_matcher(incl, ignorecase), ant_matcher(excl, ignorecase)) - - if kw.get('generator'): - return Utils.lazy_generator(self.ant_iter, (ant_sub_matcher, maxdepth, pats, dir, src, remove, quiet)) - - it = self.ant_iter(ant_sub_matcher, maxdepth, pats, dir, src, remove, quiet) - if kw.get('flat'): - # returns relative paths as a space-delimited string - # prefer Node objects whenever possible - return ' '.join(x.path_from(self) for x in it) - return list(it) - - # ---------------------------------------------------------------------------- - # the methods below require the source/build folders (bld.srcnode/bld.bldnode) - - def is_src(self): - """ - Returns True if the node is below the source directory. Note that ``!is_src() ≠ is_bld()`` - - :rtype: bool - """ - cur = self - x = self.ctx.srcnode - y = self.ctx.bldnode - while cur.parent: - if cur is y: - return False - if cur is x: - return True - cur = cur.parent - return False - - def is_bld(self): - """ - Returns True if the node is below the build directory. Note that ``!is_bld() ≠ is_src()`` - - :rtype: bool - """ - cur = self - y = self.ctx.bldnode - while cur.parent: - if cur is y: - return True - cur = cur.parent - return False - - def get_src(self): - """ - Returns the corresponding Node object in the source directory (or self if already - under the source directory). Use this method only if the purpose is to create - a Node object (this is common with folders but not with files, see ticket 1937) - - :rtype: :py:class:`waflib.Node.Node` - """ - cur = self - x = self.ctx.srcnode - y = self.ctx.bldnode - lst = [] - while cur.parent: - if cur is y: - lst.reverse() - return x.make_node(lst) - if cur is x: - return self - lst.append(cur.name) - cur = cur.parent - return self - - def get_bld(self): - """ - Return the corresponding Node object in the build directory (or self if already - under the build directory). Use this method only if the purpose is to create - a Node object (this is common with folders but not with files, see ticket 1937) - - :rtype: :py:class:`waflib.Node.Node` - """ - cur = self - x = self.ctx.srcnode - y = self.ctx.bldnode - lst = [] - while cur.parent: - if cur is y: - return self - if cur is x: - lst.reverse() - return self.ctx.bldnode.make_node(lst) - lst.append(cur.name) - cur = cur.parent - # the file is external to the current project, make a fake root in the current build directory - lst.reverse() - if lst and Utils.is_win32 and len(lst[0]) == 2 and lst[0].endswith(':'): - lst[0] = lst[0][0] - return self.ctx.bldnode.make_node(['__root__'] + lst) - - def find_resource(self, lst): - """ - Use this method in the build phase to find source files corresponding to the relative path given. - - First it looks up the Node data structure to find any declared Node object in the build directory. - If None is found, it then considers the filesystem in the source directory. - - :param lst: relative path - :type lst: string or list of string - :returns: the corresponding Node object or None - :rtype: :py:class:`waflib.Node.Node` - """ - if isinstance(lst, str): - lst = [x for x in Utils.split_path(lst) if x and x != '.'] - - node = self.get_bld().search_node(lst) - if not node: - node = self.get_src().find_node(lst) - if node and node.isdir(): - return None - return node - - def find_or_declare(self, lst): - """ - Use this method in the build phase to declare output files which - are meant to be written in the build directory. - - This method creates the Node object and its parent folder - as needed. - - :param lst: relative path - :type lst: string or list of string - """ - if isinstance(lst, str) and os.path.isabs(lst): - node = self.ctx.root.make_node(lst) - else: - node = self.get_bld().make_node(lst) - node.parent.mkdir() - return node - - def find_dir(self, lst): - """ - Searches for a folder on the filesystem (see :py:meth:`waflib.Node.Node.find_node`) - - :param lst: relative path - :type lst: string or list of string - :returns: The corresponding Node object or None if there is no such folder - :rtype: :py:class:`waflib.Node.Node` - """ - if isinstance(lst, str): - lst = [x for x in Utils.split_path(lst) if x and x != '.'] - - node = self.find_node(lst) - if node and not node.isdir(): - return None - return node - - # helpers for building things - def change_ext(self, ext, ext_in=None): - """ - Declares a build node with a distinct extension; this is uses :py:meth:`waflib.Node.Node.find_or_declare` - - :return: A build node of the same path, but with a different extension - :rtype: :py:class:`waflib.Node.Node` - """ - name = self.name - if ext_in is None: - k = name.rfind('.') - if k >= 0: - name = name[:k] + ext - else: - name = name + ext - else: - name = name[:- len(ext_in)] + ext - - return self.parent.find_or_declare([name]) - - def bldpath(self): - """ - Returns the relative path seen from the build directory ``src/foo.cpp`` - - :rtype: string - """ - return self.path_from(self.ctx.bldnode) - - def srcpath(self): - """ - Returns the relative path seen from the source directory ``../src/foo.cpp`` - - :rtype: string - """ - return self.path_from(self.ctx.srcnode) - - def relpath(self): - """ - If a file in the build directory, returns :py:meth:`waflib.Node.Node.bldpath`, - else returns :py:meth:`waflib.Node.Node.srcpath` - - :rtype: string - """ - cur = self - x = self.ctx.bldnode - while cur.parent: - if cur is x: - return self.bldpath() - cur = cur.parent - return self.srcpath() - - def bld_dir(self): - """ - Equivalent to self.parent.bldpath() - - :rtype: string - """ - return self.parent.bldpath() - - def h_file(self): - """ - See :py:func:`waflib.Utils.h_file` - - :return: a hash representing the file contents - :rtype: string or bytes - """ - return Utils.h_file(self.abspath()) - - def get_bld_sig(self): - """ - Returns a signature (see :py:meth:`waflib.Node.Node.h_file`) for the purpose - of build dependency calculation. This method uses a per-context cache. - - :return: a hash representing the object contents - :rtype: string or bytes - """ - # previous behaviour can be set by returning self.ctx.node_sigs[self] when a build node - try: - cache = self.ctx.cache_sig - except AttributeError: - cache = self.ctx.cache_sig = {} - try: - ret = cache[self] - except KeyError: - p = self.abspath() - try: - ret = cache[self] = self.h_file() - except EnvironmentError: - if self.isdir(): - # allow folders as build nodes, do not use the creation time - st = os.stat(p) - ret = cache[self] = Utils.h_list([p, st.st_ino, st.st_mode]) - return ret - raise - return ret - -pickle_lock = Utils.threading.Lock() -"""Lock mandatory for thread-safe node serialization""" - -class Nod3(Node): - """Mandatory subclass for thread-safe node serialization""" - pass # do not remove - - diff --git a/ldb-2.0.8/third_party/waf/waflib/Options.py b/ldb-2.0.8/third_party/waf/waflib/Options.py deleted file mode 100644 index ad802d4..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Options.py +++ /dev/null @@ -1,342 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Scott Newton, 2005 (scottn) -# Thomas Nagy, 2006-2018 (ita) - -""" -Support for waf command-line options - -Provides default and command-line options, as well the command -that reads the ``options`` wscript function. -""" - -import os, tempfile, optparse, sys, re -from waflib import Logs, Utils, Context, Errors - -options = optparse.Values() -""" -A global dictionary representing user-provided command-line options:: - - $ waf --foo=bar -""" - -commands = [] -""" -List of commands to execute extracted from the command-line. This list -is consumed during the execution by :py:func:`waflib.Scripting.run_commands`. -""" - -envvars = [] -""" -List of environment variable declarations placed after the Waf executable name. -These are detected by searching for "=" in the remaining arguments. -You probably do not want to use this. -""" - -lockfile = os.environ.get('WAFLOCK', '.lock-waf_%s_build' % sys.platform) -""" -Name of the lock file that marks a project as configured -""" - -class opt_parser(optparse.OptionParser): - """ - Command-line options parser. - """ - def __init__(self, ctx, allow_unknown=False): - optparse.OptionParser.__init__(self, conflict_handler='resolve', add_help_option=False, - version='waf %s (%s)' % (Context.WAFVERSION, Context.WAFREVISION)) - self.formatter.width = Logs.get_term_cols() - self.ctx = ctx - self.allow_unknown = allow_unknown - - def _process_args(self, largs, rargs, values): - """ - Custom _process_args to allow unknown options according to the allow_unknown status - """ - while rargs: - try: - optparse.OptionParser._process_args(self,largs,rargs,values) - except (optparse.BadOptionError, optparse.AmbiguousOptionError) as e: - if self.allow_unknown: - largs.append(e.opt_str) - else: - self.error(str(e)) - - def print_usage(self, file=None): - return self.print_help(file) - - def get_usage(self): - """ - Builds the message to print on ``waf --help`` - - :rtype: string - """ - cmds_str = {} - for cls in Context.classes: - if not cls.cmd or cls.cmd == 'options' or cls.cmd.startswith( '_' ): - continue - - s = cls.__doc__ or '' - cmds_str[cls.cmd] = s - - if Context.g_module: - for (k, v) in Context.g_module.__dict__.items(): - if k in ('options', 'init', 'shutdown'): - continue - - if type(v) is type(Context.create_context): - if v.__doc__ and not k.startswith('_'): - cmds_str[k] = v.__doc__ - - just = 0 - for k in cmds_str: - just = max(just, len(k)) - - lst = [' %s: %s' % (k.ljust(just), v) for (k, v) in cmds_str.items()] - lst.sort() - ret = '\n'.join(lst) - - return '''waf [commands] [options] - -Main commands (example: ./waf build -j4) -%s -''' % ret - - -class OptionsContext(Context.Context): - """ - Collects custom options from wscript files and parses the command line. - Sets the global :py:const:`waflib.Options.commands` and :py:const:`waflib.Options.options` values. - """ - cmd = 'options' - fun = 'options' - - def __init__(self, **kw): - super(OptionsContext, self).__init__(**kw) - - self.parser = opt_parser(self) - """Instance of :py:class:`waflib.Options.opt_parser`""" - - self.option_groups = {} - - jobs = self.jobs() - p = self.add_option - color = os.environ.get('NOCOLOR', '') and 'no' or 'auto' - if os.environ.get('CLICOLOR', '') == '0': - color = 'no' - elif os.environ.get('CLICOLOR_FORCE', '') == '1': - color = 'yes' - p('-c', '--color', dest='colors', default=color, action='store', help='whether to use colors (yes/no/auto) [default: auto]', choices=('yes', 'no', 'auto')) - p('-j', '--jobs', dest='jobs', default=jobs, type='int', help='amount of parallel jobs (%r)' % jobs) - p('-k', '--keep', dest='keep', default=0, action='count', help='continue despite errors (-kk to try harder)') - p('-v', '--verbose', dest='verbose', default=0, action='count', help='verbosity level -v -vv or -vvv [default: 0]') - p('--zones', dest='zones', default='', action='store', help='debugging zones (task_gen, deps, tasks, etc)') - p('--profile', dest='profile', default=0, action='store_true', help=optparse.SUPPRESS_HELP) - p('--pdb', dest='pdb', default=0, action='store_true', help=optparse.SUPPRESS_HELP) - p('-h', '--help', dest='whelp', default=0, action='store_true', help="show this help message and exit") - - gr = self.add_option_group('Configuration options') - self.option_groups['configure options'] = gr - - gr.add_option('-o', '--out', action='store', default='', help='build dir for the project', dest='out') - gr.add_option('-t', '--top', action='store', default='', help='src dir for the project', dest='top') - - gr.add_option('--no-lock-in-run', action='store_true', default='', help=optparse.SUPPRESS_HELP, dest='no_lock_in_run') - gr.add_option('--no-lock-in-out', action='store_true', default='', help=optparse.SUPPRESS_HELP, dest='no_lock_in_out') - gr.add_option('--no-lock-in-top', action='store_true', default='', help=optparse.SUPPRESS_HELP, dest='no_lock_in_top') - - default_prefix = getattr(Context.g_module, 'default_prefix', os.environ.get('PREFIX')) - if not default_prefix: - if Utils.unversioned_sys_platform() == 'win32': - d = tempfile.gettempdir() - default_prefix = d[0].upper() + d[1:] - # win32 preserves the case, but gettempdir does not - else: - default_prefix = '/usr/local/' - gr.add_option('--prefix', dest='prefix', default=default_prefix, help='installation prefix [default: %r]' % default_prefix) - gr.add_option('--bindir', dest='bindir', help='bindir') - gr.add_option('--libdir', dest='libdir', help='libdir') - - gr = self.add_option_group('Build and installation options') - self.option_groups['build and install options'] = gr - gr.add_option('-p', '--progress', dest='progress_bar', default=0, action='count', help= '-p: progress bar; -pp: ide output') - gr.add_option('--targets', dest='targets', default='', action='store', help='task generators, e.g. "target1,target2"') - - gr = self.add_option_group('Step options') - self.option_groups['step options'] = gr - gr.add_option('--files', dest='files', default='', action='store', help='files to process, by regexp, e.g. "*/main.c,*/test/main.o"') - - default_destdir = os.environ.get('DESTDIR', '') - - gr = self.add_option_group('Installation and uninstallation options') - self.option_groups['install/uninstall options'] = gr - gr.add_option('--destdir', help='installation root [default: %r]' % default_destdir, default=default_destdir, dest='destdir') - gr.add_option('-f', '--force', dest='force', default=False, action='store_true', help='force file installation') - gr.add_option('--distcheck-args', metavar='ARGS', help='arguments to pass to distcheck', default=None, action='store') - - def jobs(self): - """ - Finds the optimal amount of cpu cores to use for parallel jobs. - At runtime the options can be obtained from :py:const:`waflib.Options.options` :: - - from waflib.Options import options - njobs = options.jobs - - :return: the amount of cpu cores - :rtype: int - """ - count = int(os.environ.get('JOBS', 0)) - if count < 1: - if 'NUMBER_OF_PROCESSORS' in os.environ: - # on Windows, use the NUMBER_OF_PROCESSORS environment variable - count = int(os.environ.get('NUMBER_OF_PROCESSORS', 1)) - else: - # on everything else, first try the POSIX sysconf values - if hasattr(os, 'sysconf_names'): - if 'SC_NPROCESSORS_ONLN' in os.sysconf_names: - count = int(os.sysconf('SC_NPROCESSORS_ONLN')) - elif 'SC_NPROCESSORS_CONF' in os.sysconf_names: - count = int(os.sysconf('SC_NPROCESSORS_CONF')) - if not count and os.name not in ('nt', 'java'): - try: - tmp = self.cmd_and_log(['sysctl', '-n', 'hw.ncpu'], quiet=0) - except Errors.WafError: - pass - else: - if re.match('^[0-9]+$', tmp): - count = int(tmp) - if count < 1: - count = 1 - elif count > 1024: - count = 1024 - return count - - def add_option(self, *k, **kw): - """ - Wraps ``optparse.add_option``:: - - def options(ctx): - ctx.add_option('-u', '--use', dest='use', default=False, - action='store_true', help='a boolean option') - - :rtype: optparse option object - """ - return self.parser.add_option(*k, **kw) - - def add_option_group(self, *k, **kw): - """ - Wraps ``optparse.add_option_group``:: - - def options(ctx): - gr = ctx.add_option_group('some options') - gr.add_option('-u', '--use', dest='use', default=False, action='store_true') - - :rtype: optparse option group object - """ - try: - gr = self.option_groups[k[0]] - except KeyError: - gr = self.parser.add_option_group(*k, **kw) - self.option_groups[k[0]] = gr - return gr - - def get_option_group(self, opt_str): - """ - Wraps ``optparse.get_option_group``:: - - def options(ctx): - gr = ctx.get_option_group('configure options') - gr.add_option('-o', '--out', action='store', default='', - help='build dir for the project', dest='out') - - :rtype: optparse option group object - """ - try: - return self.option_groups[opt_str] - except KeyError: - for group in self.parser.option_groups: - if group.title == opt_str: - return group - return None - - def sanitize_path(self, path, cwd=None): - if not cwd: - cwd = Context.launch_dir - p = os.path.expanduser(path) - p = os.path.join(cwd, p) - p = os.path.normpath(p) - p = os.path.abspath(p) - return p - - def parse_cmd_args(self, _args=None, cwd=None, allow_unknown=False): - """ - Just parse the arguments - """ - self.parser.allow_unknown = allow_unknown - (options, leftover_args) = self.parser.parse_args(args=_args) - envvars = [] - commands = [] - for arg in leftover_args: - if '=' in arg: - envvars.append(arg) - elif arg != 'options': - commands.append(arg) - - for name in 'top out destdir prefix bindir libdir'.split(): - # those paths are usually expanded from Context.launch_dir - if getattr(options, name, None): - path = self.sanitize_path(getattr(options, name), cwd) - setattr(options, name, path) - return options, commands, envvars - - def init_module_vars(self, arg_options, arg_commands, arg_envvars): - options.__dict__.clear() - del commands[:] - del envvars[:] - - options.__dict__.update(arg_options.__dict__) - commands.extend(arg_commands) - envvars.extend(arg_envvars) - - for var in envvars: - (name, value) = var.split('=', 1) - os.environ[name.strip()] = value - - def init_logs(self, options, commands, envvars): - Logs.verbose = options.verbose - if options.verbose >= 1: - self.load('errcheck') - - colors = {'yes' : 2, 'auto' : 1, 'no' : 0}[options.colors] - Logs.enable_colors(colors) - - if options.zones: - Logs.zones = options.zones.split(',') - if not Logs.verbose: - Logs.verbose = 1 - elif Logs.verbose > 0: - Logs.zones = ['runner'] - if Logs.verbose > 2: - Logs.zones = ['*'] - - def parse_args(self, _args=None): - """ - Parses arguments from a list which is not necessarily the command-line. - Initializes the module variables options, commands and envvars - If help is requested, prints it and exit the application - - :param _args: arguments - :type _args: list of strings - """ - options, commands, envvars = self.parse_cmd_args() - self.init_logs(options, commands, envvars) - self.init_module_vars(options, commands, envvars) - - def execute(self): - """ - See :py:func:`waflib.Context.Context.execute` - """ - super(OptionsContext, self).execute() - self.parse_args() - Utils.alloc_process_pool(options.jobs) - diff --git a/ldb-2.0.8/third_party/waf/waflib/Runner.py b/ldb-2.0.8/third_party/waf/waflib/Runner.py deleted file mode 100644 index 91d5547..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Runner.py +++ /dev/null @@ -1,622 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2005-2018 (ita) - -""" -Runner.py: Task scheduling and execution -""" - -import heapq, traceback -try: - from queue import Queue, PriorityQueue -except ImportError: - from Queue import Queue - try: - from Queue import PriorityQueue - except ImportError: - class PriorityQueue(Queue): - def _init(self, maxsize): - self.maxsize = maxsize - self.queue = [] - def _put(self, item): - heapq.heappush(self.queue, item) - def _get(self): - return heapq.heappop(self.queue) - -from waflib import Utils, Task, Errors, Logs - -GAP = 5 -""" -Wait for at least ``GAP * njobs`` before trying to enqueue more tasks to run -""" - -class PriorityTasks(object): - def __init__(self): - self.lst = [] - def __len__(self): - return len(self.lst) - def __iter__(self): - return iter(self.lst) - def __str__(self): - return 'PriorityTasks: [%s]' % '\n '.join(str(x) for x in self.lst) - def clear(self): - self.lst = [] - def append(self, task): - heapq.heappush(self.lst, task) - def appendleft(self, task): - "Deprecated, do not use" - heapq.heappush(self.lst, task) - def pop(self): - return heapq.heappop(self.lst) - def extend(self, lst): - if self.lst: - for x in lst: - self.append(x) - else: - if isinstance(lst, list): - self.lst = lst - heapq.heapify(lst) - else: - self.lst = lst.lst - -class Consumer(Utils.threading.Thread): - """ - Daemon thread object that executes a task. It shares a semaphore with - the coordinator :py:class:`waflib.Runner.Spawner`. There is one - instance per task to consume. - """ - def __init__(self, spawner, task): - Utils.threading.Thread.__init__(self) - self.task = task - """Task to execute""" - self.spawner = spawner - """Coordinator object""" - self.setDaemon(1) - self.start() - def run(self): - """ - Processes a single task - """ - try: - if not self.spawner.master.stop: - self.spawner.master.process_task(self.task) - finally: - self.spawner.sem.release() - self.spawner.master.out.put(self.task) - self.task = None - self.spawner = None - -class Spawner(Utils.threading.Thread): - """ - Daemon thread that consumes tasks from :py:class:`waflib.Runner.Parallel` producer and - spawns a consuming thread :py:class:`waflib.Runner.Consumer` for each - :py:class:`waflib.Task.Task` instance. - """ - def __init__(self, master): - Utils.threading.Thread.__init__(self) - self.master = master - """:py:class:`waflib.Runner.Parallel` producer instance""" - self.sem = Utils.threading.Semaphore(master.numjobs) - """Bounded semaphore that prevents spawning more than *n* concurrent consumers""" - self.setDaemon(1) - self.start() - def run(self): - """ - Spawns new consumers to execute tasks by delegating to :py:meth:`waflib.Runner.Spawner.loop` - """ - try: - self.loop() - except Exception: - # Python 2 prints unnecessary messages when shutting down - # we also want to stop the thread properly - pass - def loop(self): - """ - Consumes task objects from the producer; ends when the producer has no more - task to provide. - """ - master = self.master - while 1: - task = master.ready.get() - self.sem.acquire() - if not master.stop: - task.log_display(task.generator.bld) - Consumer(self, task) - -class Parallel(object): - """ - Schedule the tasks obtained from the build context for execution. - """ - def __init__(self, bld, j=2): - """ - The initialization requires a build context reference - for computing the total number of jobs. - """ - - self.numjobs = j - """ - Amount of parallel consumers to use - """ - - self.bld = bld - """ - Instance of :py:class:`waflib.Build.BuildContext` - """ - - self.outstanding = PriorityTasks() - """Heap of :py:class:`waflib.Task.Task` that may be ready to be executed""" - - self.postponed = PriorityTasks() - """Heap of :py:class:`waflib.Task.Task` which are not ready to run for non-DAG reasons""" - - self.incomplete = set() - """List of :py:class:`waflib.Task.Task` waiting for dependent tasks to complete (DAG)""" - - self.ready = PriorityQueue(0) - """List of :py:class:`waflib.Task.Task` ready to be executed by consumers""" - - self.out = Queue(0) - """List of :py:class:`waflib.Task.Task` returned by the task consumers""" - - self.count = 0 - """Amount of tasks that may be processed by :py:class:`waflib.Runner.TaskConsumer`""" - - self.processed = 0 - """Amount of tasks processed""" - - self.stop = False - """Error flag to stop the build""" - - self.error = [] - """Tasks that could not be executed""" - - self.biter = None - """Task iterator which must give groups of parallelizable tasks when calling ``next()``""" - - self.dirty = False - """ - Flag that indicates that the build cache must be saved when a task was executed - (calls :py:meth:`waflib.Build.BuildContext.store`)""" - - self.revdeps = Utils.defaultdict(set) - """ - The reverse dependency graph of dependencies obtained from Task.run_after - """ - - self.spawner = None - """ - Coordinating daemon thread that spawns thread consumers - """ - if self.numjobs > 1: - self.spawner = Spawner(self) - - def get_next_task(self): - """ - Obtains the next Task instance to run - - :rtype: :py:class:`waflib.Task.Task` - """ - if not self.outstanding: - return None - return self.outstanding.pop() - - def postpone(self, tsk): - """ - Adds the task to the list :py:attr:`waflib.Runner.Parallel.postponed`. - The order is scrambled so as to consume as many tasks in parallel as possible. - - :param tsk: task instance - :type tsk: :py:class:`waflib.Task.Task` - """ - self.postponed.append(tsk) - - def refill_task_list(self): - """ - Pulls a next group of tasks to execute in :py:attr:`waflib.Runner.Parallel.outstanding`. - Ensures that all tasks in the current build group are complete before processing the next one. - """ - while self.count > self.numjobs * GAP: - self.get_out() - - while not self.outstanding: - if self.count: - self.get_out() - if self.outstanding: - break - elif self.postponed: - try: - cond = self.deadlock == self.processed - except AttributeError: - pass - else: - if cond: - # The most common reason is conflicting build order declaration - # for example: "X run_after Y" and "Y run_after X" - # Another can be changing "run_after" dependencies while the build is running - # for example: updating "tsk.run_after" in the "runnable_status" method - lst = [] - for tsk in self.postponed: - deps = [id(x) for x in tsk.run_after if not x.hasrun] - lst.append('%s\t-> %r' % (repr(tsk), deps)) - if not deps: - lst.append('\n task %r dependencies are done, check its *runnable_status*?' % id(tsk)) - raise Errors.WafError('Deadlock detected: check the task build order%s' % ''.join(lst)) - self.deadlock = self.processed - - if self.postponed: - self.outstanding.extend(self.postponed) - self.postponed.clear() - elif not self.count: - if self.incomplete: - for x in self.incomplete: - for k in x.run_after: - if not k.hasrun: - break - else: - # dependency added after the build started without updating revdeps - self.incomplete.remove(x) - self.outstanding.append(x) - break - else: - if self.stop or self.error: - break - raise Errors.WafError('Broken revdeps detected on %r' % self.incomplete) - else: - tasks = next(self.biter) - ready, waiting = self.prio_and_split(tasks) - self.outstanding.extend(ready) - self.incomplete.update(waiting) - self.total = self.bld.total() - break - - def add_more_tasks(self, tsk): - """ - If a task provides :py:attr:`waflib.Task.Task.more_tasks`, then the tasks contained - in that list are added to the current build and will be processed before the next build group. - - The priorities for dependent tasks are not re-calculated globally - - :param tsk: task instance - :type tsk: :py:attr:`waflib.Task.Task` - """ - if getattr(tsk, 'more_tasks', None): - more = set(tsk.more_tasks) - groups_done = set() - def iteri(a, b): - for x in a: - yield x - for x in b: - yield x - - # Update the dependency tree - # this assumes that task.run_after values were updated - for x in iteri(self.outstanding, self.incomplete): - for k in x.run_after: - if isinstance(k, Task.TaskGroup): - if k not in groups_done: - groups_done.add(k) - for j in k.prev & more: - self.revdeps[j].add(k) - elif k in more: - self.revdeps[k].add(x) - - ready, waiting = self.prio_and_split(tsk.more_tasks) - self.outstanding.extend(ready) - self.incomplete.update(waiting) - self.total += len(tsk.more_tasks) - - def mark_finished(self, tsk): - def try_unfreeze(x): - # DAG ancestors are likely to be in the incomplete set - # This assumes that the run_after contents have not changed - # after the build starts, else a deadlock may occur - if x in self.incomplete: - # TODO remove dependencies to free some memory? - # x.run_after.remove(tsk) - for k in x.run_after: - if not k.hasrun: - break - else: - self.incomplete.remove(x) - self.outstanding.append(x) - - if tsk in self.revdeps: - for x in self.revdeps[tsk]: - if isinstance(x, Task.TaskGroup): - x.prev.remove(tsk) - if not x.prev: - for k in x.next: - # TODO necessary optimization? - k.run_after.remove(x) - try_unfreeze(k) - # TODO necessary optimization? - x.next = [] - else: - try_unfreeze(x) - del self.revdeps[tsk] - - if hasattr(tsk, 'semaphore'): - sem = tsk.semaphore - try: - sem.release(tsk) - except KeyError: - # TODO - pass - else: - while sem.waiting and not sem.is_locked(): - # take a frozen task, make it ready to run - x = sem.waiting.pop() - self._add_task(x) - - def get_out(self): - """ - Waits for a Task that task consumers add to :py:attr:`waflib.Runner.Parallel.out` after execution. - Adds more Tasks if necessary through :py:attr:`waflib.Runner.Parallel.add_more_tasks`. - - :rtype: :py:attr:`waflib.Task.Task` - """ - tsk = self.out.get() - if not self.stop: - self.add_more_tasks(tsk) - self.mark_finished(tsk) - - self.count -= 1 - self.dirty = True - return tsk - - def add_task(self, tsk): - """ - Enqueue a Task to :py:attr:`waflib.Runner.Parallel.ready` so that consumers can run them. - - :param tsk: task instance - :type tsk: :py:attr:`waflib.Task.Task` - """ - # TODO change in waf 2.1 - self.ready.put(tsk) - - def _add_task(self, tsk): - if hasattr(tsk, 'semaphore'): - sem = tsk.semaphore - try: - sem.acquire(tsk) - except IndexError: - sem.waiting.add(tsk) - return - - self.count += 1 - self.processed += 1 - if self.numjobs == 1: - tsk.log_display(tsk.generator.bld) - try: - self.process_task(tsk) - finally: - self.out.put(tsk) - else: - self.add_task(tsk) - - def process_task(self, tsk): - """ - Processes a task and attempts to stop the build in case of errors - """ - tsk.process() - if tsk.hasrun != Task.SUCCESS: - self.error_handler(tsk) - - def skip(self, tsk): - """ - Mark a task as skipped/up-to-date - """ - tsk.hasrun = Task.SKIPPED - self.mark_finished(tsk) - - def cancel(self, tsk): - """ - Mark a task as failed because of unsatisfiable dependencies - """ - tsk.hasrun = Task.CANCELED - self.mark_finished(tsk) - - def error_handler(self, tsk): - """ - Called when a task cannot be executed. The flag :py:attr:`waflib.Runner.Parallel.stop` is set, - unless the build is executed with:: - - $ waf build -k - - :param tsk: task instance - :type tsk: :py:attr:`waflib.Task.Task` - """ - if not self.bld.keep: - self.stop = True - self.error.append(tsk) - - def task_status(self, tsk): - """ - Obtains the task status to decide whether to run it immediately or not. - - :return: the exit status, for example :py:attr:`waflib.Task.ASK_LATER` - :rtype: integer - """ - try: - return tsk.runnable_status() - except Exception: - self.processed += 1 - tsk.err_msg = traceback.format_exc() - if not self.stop and self.bld.keep: - self.skip(tsk) - if self.bld.keep == 1: - # if -k stop on the first exception, if -kk try to go as far as possible - if Logs.verbose > 1 or not self.error: - self.error.append(tsk) - self.stop = True - else: - if Logs.verbose > 1: - self.error.append(tsk) - return Task.EXCEPTION - - tsk.hasrun = Task.EXCEPTION - self.error_handler(tsk) - - return Task.EXCEPTION - - def start(self): - """ - Obtains Task instances from the BuildContext instance and adds the ones that need to be executed to - :py:class:`waflib.Runner.Parallel.ready` so that the :py:class:`waflib.Runner.Spawner` consumer thread - has them executed. Obtains the executed Tasks back from :py:class:`waflib.Runner.Parallel.out` - and marks the build as failed by setting the ``stop`` flag. - If only one job is used, then executes the tasks one by one, without consumers. - """ - self.total = self.bld.total() - - while not self.stop: - - self.refill_task_list() - - # consider the next task - tsk = self.get_next_task() - if not tsk: - if self.count: - # tasks may add new ones after they are run - continue - else: - # no tasks to run, no tasks running, time to exit - break - - if tsk.hasrun: - # if the task is marked as "run", just skip it - self.processed += 1 - continue - - if self.stop: # stop immediately after a failure is detected - break - - st = self.task_status(tsk) - if st == Task.RUN_ME: - self._add_task(tsk) - elif st == Task.ASK_LATER: - self.postpone(tsk) - elif st == Task.SKIP_ME: - self.processed += 1 - self.skip(tsk) - self.add_more_tasks(tsk) - elif st == Task.CANCEL_ME: - # A dependency problem has occurred, and the - # build is most likely run with `waf -k` - if Logs.verbose > 1: - self.error.append(tsk) - self.processed += 1 - self.cancel(tsk) - - # self.count represents the tasks that have been made available to the consumer threads - # collect all the tasks after an error else the message may be incomplete - while self.error and self.count: - self.get_out() - - self.ready.put(None) - if not self.stop: - assert not self.count - assert not self.postponed - assert not self.incomplete - - def prio_and_split(self, tasks): - """ - Label input tasks with priority values, and return a pair containing - the tasks that are ready to run and the tasks that are necessarily - waiting for other tasks to complete. - - The priority system is really meant as an optional layer for optimization: - dependency cycles are found quickly, and builds should be more efficient. - A high priority number means that a task is processed first. - - This method can be overridden to disable the priority system:: - - def prio_and_split(self, tasks): - return tasks, [] - - :return: A pair of task lists - :rtype: tuple - """ - # to disable: - #return tasks, [] - for x in tasks: - x.visited = 0 - - reverse = self.revdeps - - groups_done = set() - for x in tasks: - for k in x.run_after: - if isinstance(k, Task.TaskGroup): - if k not in groups_done: - groups_done.add(k) - for j in k.prev: - reverse[j].add(k) - else: - reverse[k].add(x) - - # the priority number is not the tree depth - def visit(n): - if isinstance(n, Task.TaskGroup): - return sum(visit(k) for k in n.next) - - if n.visited == 0: - n.visited = 1 - - if n in reverse: - rev = reverse[n] - n.prio_order = n.tree_weight + len(rev) + sum(visit(k) for k in rev) - else: - n.prio_order = n.tree_weight - - n.visited = 2 - elif n.visited == 1: - raise Errors.WafError('Dependency cycle found!') - return n.prio_order - - for x in tasks: - if x.visited != 0: - # must visit all to detect cycles - continue - try: - visit(x) - except Errors.WafError: - self.debug_cycles(tasks, reverse) - - ready = [] - waiting = [] - for x in tasks: - for k in x.run_after: - if not k.hasrun: - waiting.append(x) - break - else: - ready.append(x) - return (ready, waiting) - - def debug_cycles(self, tasks, reverse): - tmp = {} - for x in tasks: - tmp[x] = 0 - - def visit(n, acc): - if isinstance(n, Task.TaskGroup): - for k in n.next: - visit(k, acc) - return - if tmp[n] == 0: - tmp[n] = 1 - for k in reverse.get(n, []): - visit(k, [n] + acc) - tmp[n] = 2 - elif tmp[n] == 1: - lst = [] - for tsk in acc: - lst.append(repr(tsk)) - if tsk is n: - # exclude prior nodes, we want the minimum cycle - break - raise Errors.WafError('Task dependency cycle in "run_after" constraints: %s' % ''.join(lst)) - for x in tasks: - visit(x, []) - diff --git a/ldb-2.0.8/third_party/waf/waflib/Scripting.py b/ldb-2.0.8/third_party/waf/waflib/Scripting.py deleted file mode 100644 index 68dccf2..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Scripting.py +++ /dev/null @@ -1,625 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2005-2018 (ita) - -"Module called for configuring, compiling and installing targets" - -from __future__ import with_statement - -import os, shlex, shutil, traceback, errno, sys, stat -from waflib import Utils, Configure, Logs, Options, ConfigSet, Context, Errors, Build, Node - -build_dir_override = None - -no_climb_commands = ['configure'] - -default_cmd = "build" - -def waf_entry_point(current_directory, version, wafdir): - """ - This is the main entry point, all Waf execution starts here. - - :param current_directory: absolute path representing the current directory - :type current_directory: string - :param version: version number - :type version: string - :param wafdir: absolute path representing the directory of the waf library - :type wafdir: string - """ - Logs.init_log() - - if Context.WAFVERSION != version: - Logs.error('Waf script %r and library %r do not match (directory %r)', version, Context.WAFVERSION, wafdir) - sys.exit(1) - - # Store current directory before any chdir - Context.waf_dir = wafdir - Context.run_dir = Context.launch_dir = current_directory - start_dir = current_directory - no_climb = os.environ.get('NOCLIMB') - - if len(sys.argv) > 1: - # os.path.join handles absolute paths - # if sys.argv[1] is not an absolute path, then it is relative to the current working directory - potential_wscript = os.path.join(current_directory, sys.argv[1]) - if os.path.basename(potential_wscript) == Context.WSCRIPT_FILE and os.path.isfile(potential_wscript): - # need to explicitly normalize the path, as it may contain extra '/.' - path = os.path.normpath(os.path.dirname(potential_wscript)) - start_dir = os.path.abspath(path) - no_climb = True - sys.argv.pop(1) - - ctx = Context.create_context('options') - (options, commands, env) = ctx.parse_cmd_args(allow_unknown=True) - if options.top: - start_dir = Context.run_dir = Context.top_dir = options.top - no_climb = True - if options.out: - Context.out_dir = options.out - - # if 'configure' is in the commands, do not search any further - if not no_climb: - for k in no_climb_commands: - for y in commands: - if y.startswith(k): - no_climb = True - break - - # try to find a lock file (if the project was configured) - # at the same time, store the first wscript file seen - cur = start_dir - while cur: - try: - lst = os.listdir(cur) - except OSError: - lst = [] - Logs.error('Directory %r is unreadable!', cur) - if Options.lockfile in lst: - env = ConfigSet.ConfigSet() - try: - env.load(os.path.join(cur, Options.lockfile)) - ino = os.stat(cur)[stat.ST_INO] - except EnvironmentError: - pass - else: - # check if the folder was not moved - for x in (env.run_dir, env.top_dir, env.out_dir): - if not x: - continue - if Utils.is_win32: - if cur == x: - load = True - break - else: - # if the filesystem features symlinks, compare the inode numbers - try: - ino2 = os.stat(x)[stat.ST_INO] - except OSError: - pass - else: - if ino == ino2: - load = True - break - else: - Logs.warn('invalid lock file in %s', cur) - load = False - - if load: - Context.run_dir = env.run_dir - Context.top_dir = env.top_dir - Context.out_dir = env.out_dir - break - - if not Context.run_dir: - if Context.WSCRIPT_FILE in lst: - Context.run_dir = cur - - next = os.path.dirname(cur) - if next == cur: - break - cur = next - - if no_climb: - break - - wscript = os.path.normpath(os.path.join(Context.run_dir, Context.WSCRIPT_FILE)) - if not os.path.exists(wscript): - if options.whelp: - Logs.warn('These are the generic options (no wscript/project found)') - ctx.parser.print_help() - sys.exit(0) - Logs.error('Waf: Run from a folder containing a %r file (or try -h for the generic options)', Context.WSCRIPT_FILE) - sys.exit(1) - - try: - os.chdir(Context.run_dir) - except OSError: - Logs.error('Waf: The folder %r is unreadable', Context.run_dir) - sys.exit(1) - - try: - set_main_module(wscript) - except Errors.WafError as e: - Logs.pprint('RED', e.verbose_msg) - Logs.error(str(e)) - sys.exit(1) - except Exception as e: - Logs.error('Waf: The wscript in %r is unreadable', Context.run_dir) - traceback.print_exc(file=sys.stdout) - sys.exit(2) - - if options.profile: - import cProfile, pstats - cProfile.runctx('from waflib import Scripting; Scripting.run_commands()', {}, {}, 'profi.txt') - p = pstats.Stats('profi.txt') - p.sort_stats('time').print_stats(75) # or 'cumulative' - else: - try: - try: - run_commands() - except: - if options.pdb: - import pdb - type, value, tb = sys.exc_info() - traceback.print_exc() - pdb.post_mortem(tb) - else: - raise - except Errors.WafError as e: - if Logs.verbose > 1: - Logs.pprint('RED', e.verbose_msg) - Logs.error(e.msg) - sys.exit(1) - except SystemExit: - raise - except Exception as e: - traceback.print_exc(file=sys.stdout) - sys.exit(2) - except KeyboardInterrupt: - Logs.pprint('RED', 'Interrupted') - sys.exit(68) - -def set_main_module(file_path): - """ - Read the main wscript file into :py:const:`waflib.Context.Context.g_module` and - bind default functions such as ``init``, ``dist``, ``distclean`` if not defined. - Called by :py:func:`waflib.Scripting.waf_entry_point` during the initialization. - - :param file_path: absolute path representing the top-level wscript file - :type file_path: string - """ - Context.g_module = Context.load_module(file_path) - Context.g_module.root_path = file_path - - # note: to register the module globally, use the following: - # sys.modules['wscript_main'] = g_module - - def set_def(obj): - name = obj.__name__ - if not name in Context.g_module.__dict__: - setattr(Context.g_module, name, obj) - for k in (dist, distclean, distcheck): - set_def(k) - # add dummy init and shutdown functions if they're not defined - if not 'init' in Context.g_module.__dict__: - Context.g_module.init = Utils.nada - if not 'shutdown' in Context.g_module.__dict__: - Context.g_module.shutdown = Utils.nada - if not 'options' in Context.g_module.__dict__: - Context.g_module.options = Utils.nada - -def parse_options(): - """ - Parses the command-line options and initialize the logging system. - Called by :py:func:`waflib.Scripting.waf_entry_point` during the initialization. - """ - ctx = Context.create_context('options') - ctx.execute() - if not Options.commands: - if isinstance(default_cmd, list): - Options.commands.extend(default_cmd) - else: - Options.commands.append(default_cmd) - if Options.options.whelp: - ctx.parser.print_help() - sys.exit(0) - -def run_command(cmd_name): - """ - Executes a single Waf command. Called by :py:func:`waflib.Scripting.run_commands`. - - :param cmd_name: command to execute, like ``build`` - :type cmd_name: string - """ - ctx = Context.create_context(cmd_name) - ctx.log_timer = Utils.Timer() - ctx.options = Options.options # provided for convenience - ctx.cmd = cmd_name - try: - ctx.execute() - finally: - # Issue 1374 - ctx.finalize() - return ctx - -def run_commands(): - """ - Execute the Waf commands that were given on the command-line, and the other options - Called by :py:func:`waflib.Scripting.waf_entry_point` during the initialization, and executed - after :py:func:`waflib.Scripting.parse_options`. - """ - parse_options() - run_command('init') - while Options.commands: - cmd_name = Options.commands.pop(0) - ctx = run_command(cmd_name) - Logs.info('%r finished successfully (%s)', cmd_name, ctx.log_timer) - run_command('shutdown') - -########################################################################################### - -def distclean_dir(dirname): - """ - Distclean function called in the particular case when:: - - top == out - - :param dirname: absolute path of the folder to clean - :type dirname: string - """ - for (root, dirs, files) in os.walk(dirname): - for f in files: - if f.endswith(('.o', '.moc', '.exe')): - fname = os.path.join(root, f) - try: - os.remove(fname) - except OSError: - Logs.warn('Could not remove %r', fname) - - for x in (Context.DBFILE, 'config.log'): - try: - os.remove(x) - except OSError: - pass - - try: - shutil.rmtree(Build.CACHE_DIR) - except OSError: - pass - -def distclean(ctx): - '''removes build folders and data''' - - def remove_and_log(k, fun): - try: - fun(k) - except EnvironmentError as e: - if e.errno != errno.ENOENT: - Logs.warn('Could not remove %r', k) - - # remove waf cache folders on the top-level - if not Options.commands: - for k in os.listdir('.'): - for x in '.waf-2 waf-2 .waf3-2 waf3-2'.split(): - if k.startswith(x): - remove_and_log(k, shutil.rmtree) - - # remove a build folder, if any - cur = '.' - if ctx.options.no_lock_in_top: - cur = ctx.options.out - - try: - lst = os.listdir(cur) - except OSError: - Logs.warn('Could not read %r', cur) - return - - if Options.lockfile in lst: - f = os.path.join(cur, Options.lockfile) - try: - env = ConfigSet.ConfigSet(f) - except EnvironmentError: - Logs.warn('Could not read %r', f) - return - - if not env.out_dir or not env.top_dir: - Logs.warn('Invalid lock file %r', f) - return - - if env.out_dir == env.top_dir: - distclean_dir(env.out_dir) - else: - remove_and_log(env.out_dir, shutil.rmtree) - - env_dirs = [env.out_dir] - if not ctx.options.no_lock_in_top: - env_dirs.append(env.top_dir) - if not ctx.options.no_lock_in_run: - env_dirs.append(env.run_dir) - for k in env_dirs: - p = os.path.join(k, Options.lockfile) - remove_and_log(p, os.remove) - -class Dist(Context.Context): - '''creates an archive containing the project source code''' - cmd = 'dist' - fun = 'dist' - algo = 'tar.bz2' - ext_algo = {} - - def execute(self): - """ - See :py:func:`waflib.Context.Context.execute` - """ - self.recurse([os.path.dirname(Context.g_module.root_path)]) - self.archive() - - def archive(self): - """ - Creates the source archive. - """ - import tarfile - - arch_name = self.get_arch_name() - - try: - self.base_path - except AttributeError: - self.base_path = self.path - - node = self.base_path.make_node(arch_name) - try: - node.delete() - except OSError: - pass - - files = self.get_files() - - if self.algo.startswith('tar.'): - tar = tarfile.open(node.abspath(), 'w:' + self.algo.replace('tar.', '')) - - for x in files: - self.add_tar_file(x, tar) - tar.close() - elif self.algo == 'zip': - import zipfile - zip = zipfile.ZipFile(node.abspath(), 'w', compression=zipfile.ZIP_DEFLATED) - - for x in files: - archive_name = self.get_base_name() + '/' + x.path_from(self.base_path) - zip.write(x.abspath(), archive_name, zipfile.ZIP_DEFLATED) - zip.close() - else: - self.fatal('Valid algo types are tar.bz2, tar.gz, tar.xz or zip') - - try: - from hashlib import sha256 - except ImportError: - digest = '' - else: - digest = ' (sha256=%r)' % sha256(node.read(flags='rb')).hexdigest() - - Logs.info('New archive created: %s%s', self.arch_name, digest) - - def get_tar_path(self, node): - """ - Return the path to use for a node in the tar archive, the purpose of this - is to let subclases resolve symbolic links or to change file names - - :return: absolute path - :rtype: string - """ - return node.abspath() - - def add_tar_file(self, x, tar): - """ - Adds a file to the tar archive. Symlinks are not verified. - - :param x: file path - :param tar: tar file object - """ - p = self.get_tar_path(x) - tinfo = tar.gettarinfo(name=p, arcname=self.get_tar_prefix() + '/' + x.path_from(self.base_path)) - tinfo.uid = 0 - tinfo.gid = 0 - tinfo.uname = 'root' - tinfo.gname = 'root' - - if os.path.isfile(p): - with open(p, 'rb') as f: - tar.addfile(tinfo, fileobj=f) - else: - tar.addfile(tinfo) - - def get_tar_prefix(self): - """ - Returns the base path for files added into the archive tar file - - :rtype: string - """ - try: - return self.tar_prefix - except AttributeError: - return self.get_base_name() - - def get_arch_name(self): - """ - Returns the archive file name. - Set the attribute *arch_name* to change the default value:: - - def dist(ctx): - ctx.arch_name = 'ctx.tar.bz2' - - :rtype: string - """ - try: - self.arch_name - except AttributeError: - self.arch_name = self.get_base_name() + '.' + self.ext_algo.get(self.algo, self.algo) - return self.arch_name - - def get_base_name(self): - """ - Returns the default name of the main directory in the archive, which is set to *appname-version*. - Set the attribute *base_name* to change the default value:: - - def dist(ctx): - ctx.base_name = 'files' - - :rtype: string - """ - try: - self.base_name - except AttributeError: - appname = getattr(Context.g_module, Context.APPNAME, 'noname') - version = getattr(Context.g_module, Context.VERSION, '1.0') - self.base_name = appname + '-' + version - return self.base_name - - def get_excl(self): - """ - Returns the patterns to exclude for finding the files in the top-level directory. - Set the attribute *excl* to change the default value:: - - def dist(ctx): - ctx.excl = 'build **/*.o **/*.class' - - :rtype: string - """ - try: - return self.excl - except AttributeError: - self.excl = Node.exclude_regs + ' **/waf-2.* **/.waf-2.* **/waf3-2.* **/.waf3-2.* **/*~ **/*.rej **/*.orig **/*.pyc **/*.pyo **/*.bak **/*.swp **/.lock-w*' - if Context.out_dir: - nd = self.root.find_node(Context.out_dir) - if nd: - self.excl += ' ' + nd.path_from(self.base_path) - return self.excl - - def get_files(self): - """ - Files to package are searched automatically by :py:func:`waflib.Node.Node.ant_glob`. - Set *files* to prevent this behaviour:: - - def dist(ctx): - ctx.files = ctx.path.find_node('wscript') - - Files are also searched from the directory 'base_path', to change it, set:: - - def dist(ctx): - ctx.base_path = path - - :rtype: list of :py:class:`waflib.Node.Node` - """ - try: - files = self.files - except AttributeError: - files = self.base_path.ant_glob('**/*', excl=self.get_excl()) - return files - -def dist(ctx): - '''makes a tarball for redistributing the sources''' - pass - -class DistCheck(Dist): - """creates an archive with dist, then tries to build it""" - fun = 'distcheck' - cmd = 'distcheck' - - def execute(self): - """ - See :py:func:`waflib.Context.Context.execute` - """ - self.recurse([os.path.dirname(Context.g_module.root_path)]) - self.archive() - self.check() - - def make_distcheck_cmd(self, tmpdir): - cfg = [] - if Options.options.distcheck_args: - cfg = shlex.split(Options.options.distcheck_args) - else: - cfg = [x for x in sys.argv if x.startswith('-')] - cmd = [sys.executable, sys.argv[0], 'configure', 'build', 'install', 'uninstall', '--destdir=' + tmpdir] + cfg - return cmd - - def check(self): - """ - Creates the archive, uncompresses it and tries to build the project - """ - import tempfile, tarfile - - with tarfile.open(self.get_arch_name()) as t: - for x in t: - t.extract(x) - - instdir = tempfile.mkdtemp('.inst', self.get_base_name()) - cmd = self.make_distcheck_cmd(instdir) - ret = Utils.subprocess.Popen(cmd, cwd=self.get_base_name()).wait() - if ret: - raise Errors.WafError('distcheck failed with code %r' % ret) - - if os.path.exists(instdir): - raise Errors.WafError('distcheck succeeded, but files were left in %s' % instdir) - - shutil.rmtree(self.get_base_name()) - - -def distcheck(ctx): - '''checks if the project compiles (tarball from 'dist')''' - pass - -def autoconfigure(execute_method): - """ - Decorator that enables context commands to run *configure* as needed. - """ - def execute(self): - """ - Wraps :py:func:`waflib.Context.Context.execute` on the context class - """ - if not Configure.autoconfig: - return execute_method(self) - - env = ConfigSet.ConfigSet() - do_config = False - try: - env.load(os.path.join(Context.top_dir, Options.lockfile)) - except EnvironmentError: - Logs.warn('Configuring the project') - do_config = True - else: - if env.run_dir != Context.run_dir: - do_config = True - else: - h = 0 - for f in env.files: - try: - h = Utils.h_list((h, Utils.readf(f, 'rb'))) - except EnvironmentError: - do_config = True - break - else: - do_config = h != env.hash - - if do_config: - cmd = env.config_cmd or 'configure' - if Configure.autoconfig == 'clobber': - tmp = Options.options.__dict__ - launch_dir_tmp = Context.launch_dir - if env.options: - Options.options.__dict__ = env.options - Context.launch_dir = env.launch_dir - try: - run_command(cmd) - finally: - Options.options.__dict__ = tmp - Context.launch_dir = launch_dir_tmp - else: - run_command(cmd) - run_command(self.cmd) - else: - return execute_method(self) - return execute -Build.BuildContext.execute = autoconfigure(Build.BuildContext.execute) - diff --git a/ldb-2.0.8/third_party/waf/waflib/Task.py b/ldb-2.0.8/third_party/waf/waflib/Task.py deleted file mode 100644 index cb49a73..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Task.py +++ /dev/null @@ -1,1406 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2005-2018 (ita) - -""" -Tasks represent atomic operations such as processes. -""" - -import os, re, sys, tempfile, traceback -from waflib import Utils, Logs, Errors - -# task states -NOT_RUN = 0 -"""The task was not executed yet""" - -MISSING = 1 -"""The task has been executed but the files have not been created""" - -CRASHED = 2 -"""The task execution returned a non-zero exit status""" - -EXCEPTION = 3 -"""An exception occurred in the task execution""" - -CANCELED = 4 -"""A dependency for the task is missing so it was cancelled""" - -SKIPPED = 8 -"""The task did not have to be executed""" - -SUCCESS = 9 -"""The task was successfully executed""" - -ASK_LATER = -1 -"""The task is not ready to be executed""" - -SKIP_ME = -2 -"""The task does not need to be executed""" - -RUN_ME = -3 -"""The task must be executed""" - -CANCEL_ME = -4 -"""The task cannot be executed because of a dependency problem""" - -COMPILE_TEMPLATE_SHELL = ''' -def f(tsk): - env = tsk.env - gen = tsk.generator - bld = gen.bld - cwdx = tsk.get_cwd() - p = env.get_flat - def to_list(xx): - if isinstance(xx, str): return [xx] - return xx - tsk.last_cmd = cmd = \'\'\' %s \'\'\' % s - return tsk.exec_command(cmd, cwd=cwdx, env=env.env or None) -''' - -COMPILE_TEMPLATE_NOSHELL = ''' -def f(tsk): - env = tsk.env - gen = tsk.generator - bld = gen.bld - cwdx = tsk.get_cwd() - def to_list(xx): - if isinstance(xx, str): return [xx] - return xx - def merge(lst1, lst2): - if lst1 and lst2: - return lst1[:-1] + [lst1[-1] + lst2[0]] + lst2[1:] - return lst1 + lst2 - lst = [] - %s - if '' in lst: - lst = [x for x in lst if x] - tsk.last_cmd = lst - return tsk.exec_command(lst, cwd=cwdx, env=env.env or None) -''' - -COMPILE_TEMPLATE_SIG_VARS = ''' -def f(tsk): - sig = tsk.generator.bld.hash_env_vars(tsk.env, tsk.vars) - tsk.m.update(sig) - env = tsk.env - gen = tsk.generator - bld = gen.bld - cwdx = tsk.get_cwd() - p = env.get_flat - buf = [] - %s - tsk.m.update(repr(buf).encode()) -''' - -classes = {} -""" -The metaclass :py:class:`waflib.Task.store_task_type` stores all class tasks -created by user scripts or Waf tools to this dict. It maps class names to class objects. -""" - -class store_task_type(type): - """ - Metaclass: store the task classes into the dict pointed by the - class attribute 'register' which defaults to :py:const:`waflib.Task.classes`, - - The attribute 'run_str' is compiled into a method 'run' bound to the task class. - """ - def __init__(cls, name, bases, dict): - super(store_task_type, cls).__init__(name, bases, dict) - name = cls.__name__ - - if name != 'evil' and name != 'Task': - if getattr(cls, 'run_str', None): - # if a string is provided, convert it to a method - (f, dvars) = compile_fun(cls.run_str, cls.shell) - cls.hcode = Utils.h_cmd(cls.run_str) - cls.orig_run_str = cls.run_str - # change the name of run_str or it is impossible to subclass with a function - cls.run_str = None - cls.run = f - # process variables - cls.vars = list(set(cls.vars + dvars)) - cls.vars.sort() - if cls.vars: - fun = compile_sig_vars(cls.vars) - if fun: - cls.sig_vars = fun - elif getattr(cls, 'run', None) and not 'hcode' in cls.__dict__: - # getattr(cls, 'hcode') would look in the upper classes - cls.hcode = Utils.h_cmd(cls.run) - - # be creative - getattr(cls, 'register', classes)[name] = cls - -evil = store_task_type('evil', (object,), {}) -"Base class provided to avoid writing a metaclass, so the code can run in python 2.6 and 3.x unmodified" - -class Task(evil): - """ - Task objects represents actions to perform such as commands to execute by calling the `run` method. - - Detecting when to execute a task occurs in the method :py:meth:`waflib.Task.Task.runnable_status`. - - Detecting which tasks to execute is performed through a hash value returned by - :py:meth:`waflib.Task.Task.signature`. The task signature is persistent from build to build. - """ - vars = [] - """ConfigSet variables that should trigger a rebuild (class attribute used for :py:meth:`waflib.Task.Task.sig_vars`)""" - - always_run = False - """Specify whether task instances must always be executed or not (class attribute)""" - - shell = False - """Execute the command with the shell (class attribute)""" - - color = 'GREEN' - """Color for the console display, see :py:const:`waflib.Logs.colors_lst`""" - - ext_in = [] - """File extensions that objects of this task class may use""" - - ext_out = [] - """File extensions that objects of this task class may create""" - - before = [] - """The instances of this class are executed before the instances of classes whose names are in this list""" - - after = [] - """The instances of this class are executed after the instances of classes whose names are in this list""" - - hcode = Utils.SIG_NIL - """String representing an additional hash for the class representation""" - - keep_last_cmd = False - """Whether to keep the last command executed on the instance after execution. - This may be useful for certain extensions but it can a lot of memory. - """ - - weight = 0 - """Optional weight to tune the priority for task instances. - The higher, the earlier. The weight only applies to single task objects.""" - - tree_weight = 0 - """Optional weight to tune the priority of task instances and whole subtrees. - The higher, the earlier.""" - - prio_order = 0 - """Priority order set by the scheduler on instances during the build phase. - You most likely do not need to set it. - """ - - __slots__ = ('hasrun', 'generator', 'env', 'inputs', 'outputs', 'dep_nodes', 'run_after') - - def __init__(self, *k, **kw): - self.hasrun = NOT_RUN - try: - self.generator = kw['generator'] - except KeyError: - self.generator = self - - self.env = kw['env'] - """:py:class:`waflib.ConfigSet.ConfigSet` object (make sure to provide one)""" - - self.inputs = [] - """List of input nodes, which represent the files used by the task instance""" - - self.outputs = [] - """List of output nodes, which represent the files created by the task instance""" - - self.dep_nodes = [] - """List of additional nodes to depend on""" - - self.run_after = set() - """Set of tasks that must be executed before this one""" - - def __lt__(self, other): - return self.priority() > other.priority() - def __le__(self, other): - return self.priority() >= other.priority() - def __gt__(self, other): - return self.priority() < other.priority() - def __ge__(self, other): - return self.priority() <= other.priority() - - def get_cwd(self): - """ - :return: current working directory - :rtype: :py:class:`waflib.Node.Node` - """ - bld = self.generator.bld - ret = getattr(self, 'cwd', None) or getattr(bld, 'cwd', bld.bldnode) - if isinstance(ret, str): - if os.path.isabs(ret): - ret = bld.root.make_node(ret) - else: - ret = self.generator.path.make_node(ret) - return ret - - def quote_flag(self, x): - """ - Surround a process argument by quotes so that a list of arguments can be written to a file - - :param x: flag - :type x: string - :return: quoted flag - :rtype: string - """ - old = x - if '\\' in x: - x = x.replace('\\', '\\\\') - if '"' in x: - x = x.replace('"', '\\"') - if old != x or ' ' in x or '\t' in x or "'" in x: - x = '"%s"' % x - return x - - def priority(self): - """ - Priority of execution; the higher, the earlier - - :return: the priority value - :rtype: a tuple of numeric values - """ - return (self.weight + self.prio_order, - getattr(self.generator, 'tg_idx_count', 0)) - - def split_argfile(self, cmd): - """ - Splits a list of process commands into the executable part and its list of arguments - - :return: a tuple containing the executable first and then the rest of arguments - :rtype: tuple - """ - return ([cmd[0]], [self.quote_flag(x) for x in cmd[1:]]) - - def exec_command(self, cmd, **kw): - """ - Wrapper for :py:meth:`waflib.Context.Context.exec_command`. - This version set the current working directory (``build.variant_dir``), - applies PATH settings (if self.env.PATH is provided), and can run long - commands through a temporary ``@argfile``. - - :param cmd: process command to execute - :type cmd: list of string (best) or string (process will use a shell) - :return: the return code - :rtype: int - - Optional parameters: - - #. cwd: current working directory (Node or string) - #. stdout: set to None to prevent waf from capturing the process standard output - #. stderr: set to None to prevent waf from capturing the process standard error - #. timeout: timeout value (Python 3) - """ - if not 'cwd' in kw: - kw['cwd'] = self.get_cwd() - - if hasattr(self, 'timeout'): - kw['timeout'] = self.timeout - - if self.env.PATH: - env = kw['env'] = dict(kw.get('env') or self.env.env or os.environ) - env['PATH'] = self.env.PATH if isinstance(self.env.PATH, str) else os.pathsep.join(self.env.PATH) - - if hasattr(self, 'stdout'): - kw['stdout'] = self.stdout - if hasattr(self, 'stderr'): - kw['stderr'] = self.stderr - - if not isinstance(cmd, str): - if Utils.is_win32: - # win32 compares the resulting length http://support.microsoft.com/kb/830473 - too_long = sum([len(arg) for arg in cmd]) + len(cmd) > 8192 - else: - # non-win32 counts the amount of arguments (200k) - too_long = len(cmd) > 200000 - - if too_long and getattr(self, 'allow_argsfile', True): - # Shunt arguments to a temporary file if the command is too long. - cmd, args = self.split_argfile(cmd) - try: - (fd, tmp) = tempfile.mkstemp() - os.write(fd, '\r\n'.join(args).encode()) - os.close(fd) - if Logs.verbose: - Logs.debug('argfile: @%r -> %r', tmp, args) - return self.generator.bld.exec_command(cmd + ['@' + tmp], **kw) - finally: - try: - os.remove(tmp) - except OSError: - # anti-virus and indexers can keep files open -_- - pass - return self.generator.bld.exec_command(cmd, **kw) - - def process(self): - """ - Runs the task and handles errors - - :return: 0 or None if everything is fine - :rtype: integer - """ - # remove the task signature immediately before it is executed - # so that the task will be executed again in case of failure - try: - del self.generator.bld.task_sigs[self.uid()] - except KeyError: - pass - - try: - ret = self.run() - except Exception: - self.err_msg = traceback.format_exc() - self.hasrun = EXCEPTION - else: - if ret: - self.err_code = ret - self.hasrun = CRASHED - else: - try: - self.post_run() - except Errors.WafError: - pass - except Exception: - self.err_msg = traceback.format_exc() - self.hasrun = EXCEPTION - else: - self.hasrun = SUCCESS - - if self.hasrun != SUCCESS and self.scan: - # rescan dependencies on next run - try: - del self.generator.bld.imp_sigs[self.uid()] - except KeyError: - pass - - def log_display(self, bld): - "Writes the execution status on the context logger" - if self.generator.bld.progress_bar == 3: - return - - s = self.display() - if s: - if bld.logger: - logger = bld.logger - else: - logger = Logs - - if self.generator.bld.progress_bar == 1: - c1 = Logs.colors.cursor_off - c2 = Logs.colors.cursor_on - logger.info(s, extra={'stream': sys.stderr, 'terminator':'', 'c1': c1, 'c2' : c2}) - else: - logger.info(s, extra={'terminator':'', 'c1': '', 'c2' : ''}) - - def display(self): - """ - Returns an execution status for the console, the progress bar, or the IDE output. - - :rtype: string - """ - col1 = Logs.colors(self.color) - col2 = Logs.colors.NORMAL - master = self.generator.bld.producer - - def cur(): - # the current task position, computed as late as possible - return master.processed - master.ready.qsize() - - if self.generator.bld.progress_bar == 1: - return self.generator.bld.progress_line(cur(), master.total, col1, col2) - - if self.generator.bld.progress_bar == 2: - ela = str(self.generator.bld.timer) - try: - ins = ','.join([n.name for n in self.inputs]) - except AttributeError: - ins = '' - try: - outs = ','.join([n.name for n in self.outputs]) - except AttributeError: - outs = '' - return '|Total %s|Current %s|Inputs %s|Outputs %s|Time %s|\n' % (master.total, cur(), ins, outs, ela) - - s = str(self) - if not s: - return None - - total = master.total - n = len(str(total)) - fs = '[%%%dd/%%%dd] %%s%%s%%s%%s\n' % (n, n) - kw = self.keyword() - if kw: - kw += ' ' - return fs % (cur(), total, kw, col1, s, col2) - - def hash_constraints(self): - """ - Identifies a task type for all the constraints relevant for the scheduler: precedence, file production - - :return: a hash value - :rtype: string - """ - return (tuple(self.before), tuple(self.after), tuple(self.ext_in), tuple(self.ext_out), self.__class__.__name__, self.hcode) - - def format_error(self): - """ - Returns an error message to display the build failure reasons - - :rtype: string - """ - if Logs.verbose: - msg = ': %r\n%r' % (self, getattr(self, 'last_cmd', '')) - else: - msg = ' (run with -v to display more information)' - name = getattr(self.generator, 'name', '') - if getattr(self, "err_msg", None): - return self.err_msg - elif not self.hasrun: - return 'task in %r was not executed for some reason: %r' % (name, self) - elif self.hasrun == CRASHED: - try: - return ' -> task in %r failed with exit status %r%s' % (name, self.err_code, msg) - except AttributeError: - return ' -> task in %r failed%s' % (name, msg) - elif self.hasrun == MISSING: - return ' -> missing files in %r%s' % (name, msg) - elif self.hasrun == CANCELED: - return ' -> %r canceled because of missing dependencies' % name - else: - return 'invalid status for task in %r: %r' % (name, self.hasrun) - - def colon(self, var1, var2): - """ - Enable scriptlet expressions of the form ${FOO_ST:FOO} - If the first variable (FOO_ST) is empty, then an empty list is returned - - The results will be slightly different if FOO_ST is a list, for example:: - - env.FOO = ['p1', 'p2'] - env.FOO_ST = '-I%s' - # ${FOO_ST:FOO} returns - ['-Ip1', '-Ip2'] - - env.FOO_ST = ['-a', '-b'] - # ${FOO_ST:FOO} returns - ['-a', '-b', 'p1', '-a', '-b', 'p2'] - """ - tmp = self.env[var1] - if not tmp: - return [] - - if isinstance(var2, str): - it = self.env[var2] - else: - it = var2 - if isinstance(tmp, str): - return [tmp % x for x in it] - else: - lst = [] - for y in it: - lst.extend(tmp) - lst.append(y) - return lst - - def __str__(self): - "string to display to the user" - name = self.__class__.__name__ - if self.outputs: - if name.endswith(('lib', 'program')) or not self.inputs: - node = self.outputs[0] - return node.path_from(node.ctx.launch_node()) - if not (self.inputs or self.outputs): - return self.__class__.__name__ - if len(self.inputs) == 1: - node = self.inputs[0] - return node.path_from(node.ctx.launch_node()) - - src_str = ' '.join([a.path_from(a.ctx.launch_node()) for a in self.inputs]) - tgt_str = ' '.join([a.path_from(a.ctx.launch_node()) for a in self.outputs]) - if self.outputs: - sep = ' -> ' - else: - sep = '' - return '%s: %s%s%s' % (self.__class__.__name__, src_str, sep, tgt_str) - - def keyword(self): - "Display keyword used to prettify the console outputs" - name = self.__class__.__name__ - if name.endswith(('lib', 'program')): - return 'Linking' - if len(self.inputs) == 1 and len(self.outputs) == 1: - return 'Compiling' - if not self.inputs: - if self.outputs: - return 'Creating' - else: - return 'Running' - return 'Processing' - - def __repr__(self): - "for debugging purposes" - try: - ins = ",".join([x.name for x in self.inputs]) - outs = ",".join([x.name for x in self.outputs]) - except AttributeError: - ins = ",".join([str(x) for x in self.inputs]) - outs = ",".join([str(x) for x in self.outputs]) - return "".join(['\n\t{task %r: ' % id(self), self.__class__.__name__, " ", ins, " -> ", outs, '}']) - - def uid(self): - """ - Returns an identifier used to determine if tasks are up-to-date. Since the - identifier will be stored between executions, it must be: - - - unique for a task: no two tasks return the same value (for a given build context) - - the same for a given task instance - - By default, the node paths, the class name, and the function are used - as inputs to compute a hash. - - The pointer to the object (python built-in 'id') will change between build executions, - and must be avoided in such hashes. - - :return: hash value - :rtype: string - """ - try: - return self.uid_ - except AttributeError: - m = Utils.md5(self.__class__.__name__) - up = m.update - for x in self.inputs + self.outputs: - up(x.abspath()) - self.uid_ = m.digest() - return self.uid_ - - def set_inputs(self, inp): - """ - Appends the nodes to the *inputs* list - - :param inp: input nodes - :type inp: node or list of nodes - """ - if isinstance(inp, list): - self.inputs += inp - else: - self.inputs.append(inp) - - def set_outputs(self, out): - """ - Appends the nodes to the *outputs* list - - :param out: output nodes - :type out: node or list of nodes - """ - if isinstance(out, list): - self.outputs += out - else: - self.outputs.append(out) - - def set_run_after(self, task): - """ - Run this task only after the given *task*. - - Calling this method from :py:meth:`waflib.Task.Task.runnable_status` may cause - build deadlocks; see :py:meth:`waflib.Tools.fc.fc.runnable_status` for details. - - :param task: task - :type task: :py:class:`waflib.Task.Task` - """ - assert isinstance(task, Task) - self.run_after.add(task) - - def signature(self): - """ - Task signatures are stored between build executions, they are use to track the changes - made to the input nodes (not to the outputs!). The signature hashes data from various sources: - - * explicit dependencies: files listed in the inputs (list of node objects) :py:meth:`waflib.Task.Task.sig_explicit_deps` - * implicit dependencies: list of nodes returned by scanner methods (when present) :py:meth:`waflib.Task.Task.sig_implicit_deps` - * hashed data: variables/values read from task.vars/task.env :py:meth:`waflib.Task.Task.sig_vars` - - If the signature is expected to give a different result, clear the cache kept in ``self.cache_sig``:: - - from waflib import Task - class cls(Task.Task): - def signature(self): - sig = super(Task.Task, self).signature() - delattr(self, 'cache_sig') - return super(Task.Task, self).signature() - - :return: the signature value - :rtype: string or bytes - """ - try: - return self.cache_sig - except AttributeError: - pass - - self.m = Utils.md5(self.hcode) - - # explicit deps - self.sig_explicit_deps() - - # env vars - self.sig_vars() - - # implicit deps / scanner results - if self.scan: - try: - self.sig_implicit_deps() - except Errors.TaskRescan: - return self.signature() - - ret = self.cache_sig = self.m.digest() - return ret - - def runnable_status(self): - """ - Returns the Task status - - :return: a task state in :py:const:`waflib.Task.RUN_ME`, - :py:const:`waflib.Task.SKIP_ME`, :py:const:`waflib.Task.CANCEL_ME` or :py:const:`waflib.Task.ASK_LATER`. - :rtype: int - """ - bld = self.generator.bld - if bld.is_install < 0: - return SKIP_ME - - for t in self.run_after: - if not t.hasrun: - return ASK_LATER - elif t.hasrun < SKIPPED: - # a dependency has an error - return CANCEL_ME - - # first compute the signature - try: - new_sig = self.signature() - except Errors.TaskNotReady: - return ASK_LATER - - # compare the signature to a signature computed previously - key = self.uid() - try: - prev_sig = bld.task_sigs[key] - except KeyError: - Logs.debug('task: task %r must run: it was never run before or the task code changed', self) - return RUN_ME - - if new_sig != prev_sig: - Logs.debug('task: task %r must run: the task signature changed', self) - return RUN_ME - - # compare the signatures of the outputs - for node in self.outputs: - sig = bld.node_sigs.get(node) - if not sig: - Logs.debug('task: task %r must run: an output node has no signature', self) - return RUN_ME - if sig != key: - Logs.debug('task: task %r must run: an output node was produced by another task', self) - return RUN_ME - if not node.exists(): - Logs.debug('task: task %r must run: an output node does not exist', self) - return RUN_ME - - return (self.always_run and RUN_ME) or SKIP_ME - - def post_run(self): - """ - Called after successful execution to record that the task has run by - updating the entry in :py:attr:`waflib.Build.BuildContext.task_sigs`. - """ - bld = self.generator.bld - for node in self.outputs: - if not node.exists(): - self.hasrun = MISSING - self.err_msg = '-> missing file: %r' % node.abspath() - raise Errors.WafError(self.err_msg) - bld.node_sigs[node] = self.uid() # make sure this task produced the files in question - bld.task_sigs[self.uid()] = self.signature() - if not self.keep_last_cmd: - try: - del self.last_cmd - except AttributeError: - pass - - def sig_explicit_deps(self): - """ - Used by :py:meth:`waflib.Task.Task.signature`; it hashes :py:attr:`waflib.Task.Task.inputs` - and :py:attr:`waflib.Task.Task.dep_nodes` signatures. - """ - bld = self.generator.bld - upd = self.m.update - - # the inputs - for x in self.inputs + self.dep_nodes: - upd(x.get_bld_sig()) - - # manual dependencies, they can slow down the builds - if bld.deps_man: - additional_deps = bld.deps_man - for x in self.inputs + self.outputs: - try: - d = additional_deps[x] - except KeyError: - continue - - for v in d: - try: - v = v.get_bld_sig() - except AttributeError: - if hasattr(v, '__call__'): - v = v() # dependency is a function, call it - upd(v) - - def sig_deep_inputs(self): - """ - Enable rebuilds on input files task signatures. Not used by default. - - Example: hashes of output programs can be unchanged after being re-linked, - despite the libraries being different. This method can thus prevent stale unit test - results (waf_unit_test.py). - - Hashing input file timestamps is another possibility for the implementation. - This may cause unnecessary rebuilds when input tasks are frequently executed. - Here is an implementation example:: - - lst = [] - for node in self.inputs + self.dep_nodes: - st = os.stat(node.abspath()) - lst.append(st.st_mtime) - lst.append(st.st_size) - self.m.update(Utils.h_list(lst)) - - The downside of the implementation is that it absolutely requires all build directory - files to be declared within the current build. - """ - bld = self.generator.bld - lst = [bld.task_sigs[bld.node_sigs[node]] for node in (self.inputs + self.dep_nodes) if node.is_bld()] - self.m.update(Utils.h_list(lst)) - - def sig_vars(self): - """ - Used by :py:meth:`waflib.Task.Task.signature`; it hashes :py:attr:`waflib.Task.Task.env` variables/values - When overriding this method, and if scriptlet expressions are used, make sure to follow - the code in :py:meth:`waflib.Task.Task.compile_sig_vars` to enable dependencies on scriptlet results. - - This method may be replaced on subclasses by the metaclass to force dependencies on scriptlet code. - """ - sig = self.generator.bld.hash_env_vars(self.env, self.vars) - self.m.update(sig) - - scan = None - """ - This method, when provided, returns a tuple containing: - - * a list of nodes corresponding to real files - * a list of names for files not found in path_lst - - For example:: - - from waflib.Task import Task - class mytask(Task): - def scan(self, node): - return ([], []) - - The first and second lists in the tuple are stored in :py:attr:`waflib.Build.BuildContext.node_deps` and - :py:attr:`waflib.Build.BuildContext.raw_deps` respectively. - """ - - def sig_implicit_deps(self): - """ - Used by :py:meth:`waflib.Task.Task.signature`; it hashes node signatures - obtained by scanning for dependencies (:py:meth:`waflib.Task.Task.scan`). - - The exception :py:class:`waflib.Errors.TaskRescan` is thrown - when a file has changed. In this case, the method :py:meth:`waflib.Task.Task.signature` is called - once again, and return here to call :py:meth:`waflib.Task.Task.scan` and searching for dependencies. - """ - bld = self.generator.bld - - # get the task signatures from previous runs - key = self.uid() - prev = bld.imp_sigs.get(key, []) - - # for issue #379 - if prev: - try: - if prev == self.compute_sig_implicit_deps(): - return prev - except Errors.TaskNotReady: - raise - except EnvironmentError: - # when a file was renamed, remove the stale nodes (headers in folders without source files) - # this will break the order calculation for headers created during the build in the source directory (should be uncommon) - # the behaviour will differ when top != out - for x in bld.node_deps.get(self.uid(), []): - if not x.is_bld() and not x.exists(): - try: - del x.parent.children[x.name] - except KeyError: - pass - del bld.imp_sigs[key] - raise Errors.TaskRescan('rescan') - - # no previous run or the signature of the dependencies has changed, rescan the dependencies - (bld.node_deps[key], bld.raw_deps[key]) = self.scan() - if Logs.verbose: - Logs.debug('deps: scanner for %s: %r; unresolved: %r', self, bld.node_deps[key], bld.raw_deps[key]) - - # recompute the signature and return it - try: - bld.imp_sigs[key] = self.compute_sig_implicit_deps() - except EnvironmentError: - for k in bld.node_deps.get(self.uid(), []): - if not k.exists(): - Logs.warn('Dependency %r for %r is missing: check the task declaration and the build order!', k, self) - raise - - def compute_sig_implicit_deps(self): - """ - Used by :py:meth:`waflib.Task.Task.sig_implicit_deps` for computing the actual hash of the - :py:class:`waflib.Node.Node` returned by the scanner. - - :return: a hash value for the implicit dependencies - :rtype: string or bytes - """ - upd = self.m.update - self.are_implicit_nodes_ready() - - # scanner returns a node that does not have a signature - # just *ignore* the error and let them figure out from the compiler output - # waf -k behaviour - for k in self.generator.bld.node_deps.get(self.uid(), []): - upd(k.get_bld_sig()) - return self.m.digest() - - def are_implicit_nodes_ready(self): - """ - For each node returned by the scanner, see if there is a task that creates it, - and infer the build order - - This has a low performance impact on null builds (1.86s->1.66s) thanks to caching (28s->1.86s) - """ - bld = self.generator.bld - try: - cache = bld.dct_implicit_nodes - except AttributeError: - bld.dct_implicit_nodes = cache = {} - - # one cache per build group - try: - dct = cache[bld.current_group] - except KeyError: - dct = cache[bld.current_group] = {} - for tsk in bld.cur_tasks: - for x in tsk.outputs: - dct[x] = tsk - - modified = False - for x in bld.node_deps.get(self.uid(), []): - if x in dct: - self.run_after.add(dct[x]) - modified = True - - if modified: - for tsk in self.run_after: - if not tsk.hasrun: - #print "task is not ready..." - raise Errors.TaskNotReady('not ready') -if sys.hexversion > 0x3000000: - def uid(self): - try: - return self.uid_ - except AttributeError: - m = Utils.md5(self.__class__.__name__.encode('latin-1', 'xmlcharrefreplace')) - up = m.update - for x in self.inputs + self.outputs: - up(x.abspath().encode('latin-1', 'xmlcharrefreplace')) - self.uid_ = m.digest() - return self.uid_ - uid.__doc__ = Task.uid.__doc__ - Task.uid = uid - -def is_before(t1, t2): - """ - Returns a non-zero value if task t1 is to be executed before task t2:: - - t1.ext_out = '.h' - t2.ext_in = '.h' - t2.after = ['t1'] - t1.before = ['t2'] - waflib.Task.is_before(t1, t2) # True - - :param t1: Task object - :type t1: :py:class:`waflib.Task.Task` - :param t2: Task object - :type t2: :py:class:`waflib.Task.Task` - """ - to_list = Utils.to_list - for k in to_list(t2.ext_in): - if k in to_list(t1.ext_out): - return 1 - - if t1.__class__.__name__ in to_list(t2.after): - return 1 - - if t2.__class__.__name__ in to_list(t1.before): - return 1 - - return 0 - -def set_file_constraints(tasks): - """ - Updates the ``run_after`` attribute of all tasks based on the task inputs and outputs - - :param tasks: tasks - :type tasks: list of :py:class:`waflib.Task.Task` - """ - ins = Utils.defaultdict(set) - outs = Utils.defaultdict(set) - for x in tasks: - for a in x.inputs: - ins[a].add(x) - for a in x.dep_nodes: - ins[a].add(x) - for a in x.outputs: - outs[a].add(x) - - links = set(ins.keys()).intersection(outs.keys()) - for k in links: - for a in ins[k]: - a.run_after.update(outs[k]) - - -class TaskGroup(object): - """ - Wrap nxm task order constraints into a single object - to prevent the creation of large list/set objects - - This is an optimization - """ - def __init__(self, prev, next): - self.prev = prev - self.next = next - self.done = False - - def get_hasrun(self): - for k in self.prev: - if not k.hasrun: - return NOT_RUN - return SUCCESS - - hasrun = property(get_hasrun, None) - -def set_precedence_constraints(tasks): - """ - Updates the ``run_after`` attribute of all tasks based on the after/before/ext_out/ext_in attributes - - :param tasks: tasks - :type tasks: list of :py:class:`waflib.Task.Task` - """ - cstr_groups = Utils.defaultdict(list) - for x in tasks: - h = x.hash_constraints() - cstr_groups[h].append(x) - - keys = list(cstr_groups.keys()) - maxi = len(keys) - - # this list should be short - for i in range(maxi): - t1 = cstr_groups[keys[i]][0] - for j in range(i + 1, maxi): - t2 = cstr_groups[keys[j]][0] - - # add the constraints based on the comparisons - if is_before(t1, t2): - a = i - b = j - elif is_before(t2, t1): - a = j - b = i - else: - continue - - a = cstr_groups[keys[a]] - b = cstr_groups[keys[b]] - - if len(a) < 2 or len(b) < 2: - for x in b: - x.run_after.update(a) - else: - group = TaskGroup(set(a), set(b)) - for x in b: - x.run_after.add(group) - -def funex(c): - """ - Compiles a scriptlet expression into a Python function - - :param c: function to compile - :type c: string - :return: the function 'f' declared in the input string - :rtype: function - """ - dc = {} - exec(c, dc) - return dc['f'] - -re_cond = re.compile(r'(?P\w+)|(?P\|)|(?P&)') -re_novar = re.compile(r'^(SRC|TGT)\W+.*?$') -reg_act = re.compile(r'(?P\\)|(?P\$\$)|(?P\$\{(?P\w+)(?P.*?)\})', re.M) -def compile_fun_shell(line): - """ - Creates a compiled function to execute a process through a sub-shell - """ - extr = [] - def repl(match): - g = match.group - if g('dollar'): - return "$" - elif g('backslash'): - return '\\\\' - elif g('subst'): - extr.append((g('var'), g('code'))) - return "%s" - return None - line = reg_act.sub(repl, line) or line - dvars = [] - def add_dvar(x): - if x not in dvars: - dvars.append(x) - - def replc(m): - # performs substitutions and populates dvars - if m.group('and'): - return ' and ' - elif m.group('or'): - return ' or ' - else: - x = m.group('var') - add_dvar(x) - return 'env[%r]' % x - - parm = [] - app = parm.append - for (var, meth) in extr: - if var == 'SRC': - if meth: - app('tsk.inputs%s' % meth) - else: - app('" ".join([a.path_from(cwdx) for a in tsk.inputs])') - elif var == 'TGT': - if meth: - app('tsk.outputs%s' % meth) - else: - app('" ".join([a.path_from(cwdx) for a in tsk.outputs])') - elif meth: - if meth.startswith(':'): - add_dvar(var) - m = meth[1:] - if m == 'SRC': - m = '[a.path_from(cwdx) for a in tsk.inputs]' - elif m == 'TGT': - m = '[a.path_from(cwdx) for a in tsk.outputs]' - elif re_novar.match(m): - m = '[tsk.inputs%s]' % m[3:] - elif re_novar.match(m): - m = '[tsk.outputs%s]' % m[3:] - else: - add_dvar(m) - if m[:3] not in ('tsk', 'gen', 'bld'): - m = '%r' % m - app('" ".join(tsk.colon(%r, %s))' % (var, m)) - elif meth.startswith('?'): - # In A?B|C output env.A if one of env.B or env.C is non-empty - expr = re_cond.sub(replc, meth[1:]) - app('p(%r) if (%s) else ""' % (var, expr)) - else: - call = '%s%s' % (var, meth) - add_dvar(call) - app(call) - else: - add_dvar(var) - app("p('%s')" % var) - if parm: - parm = "%% (%s) " % (',\n\t\t'.join(parm)) - else: - parm = '' - - c = COMPILE_TEMPLATE_SHELL % (line, parm) - Logs.debug('action: %s', c.strip().splitlines()) - return (funex(c), dvars) - -reg_act_noshell = re.compile(r"(?P\s+)|(?P\$\{(?P\w+)(?P.*?)\})|(?P([^$ \t\n\r\f\v]|\$\$)+)", re.M) -def compile_fun_noshell(line): - """ - Creates a compiled function to execute a process without a sub-shell - """ - buf = [] - dvars = [] - merge = False - app = buf.append - - def add_dvar(x): - if x not in dvars: - dvars.append(x) - - def replc(m): - # performs substitutions and populates dvars - if m.group('and'): - return ' and ' - elif m.group('or'): - return ' or ' - else: - x = m.group('var') - add_dvar(x) - return 'env[%r]' % x - - for m in reg_act_noshell.finditer(line): - if m.group('space'): - merge = False - continue - elif m.group('text'): - app('[%r]' % m.group('text').replace('$$', '$')) - elif m.group('subst'): - var = m.group('var') - code = m.group('code') - if var == 'SRC': - if code: - app('[tsk.inputs%s]' % code) - else: - app('[a.path_from(cwdx) for a in tsk.inputs]') - elif var == 'TGT': - if code: - app('[tsk.outputs%s]' % code) - else: - app('[a.path_from(cwdx) for a in tsk.outputs]') - elif code: - if code.startswith(':'): - # a composed variable ${FOO:OUT} - add_dvar(var) - m = code[1:] - if m == 'SRC': - m = '[a.path_from(cwdx) for a in tsk.inputs]' - elif m == 'TGT': - m = '[a.path_from(cwdx) for a in tsk.outputs]' - elif re_novar.match(m): - m = '[tsk.inputs%s]' % m[3:] - elif re_novar.match(m): - m = '[tsk.outputs%s]' % m[3:] - else: - add_dvar(m) - if m[:3] not in ('tsk', 'gen', 'bld'): - m = '%r' % m - app('tsk.colon(%r, %s)' % (var, m)) - elif code.startswith('?'): - # In A?B|C output env.A if one of env.B or env.C is non-empty - expr = re_cond.sub(replc, code[1:]) - app('to_list(env[%r] if (%s) else [])' % (var, expr)) - else: - # plain code such as ${tsk.inputs[0].abspath()} - call = '%s%s' % (var, code) - add_dvar(call) - app('to_list(%s)' % call) - else: - # a plain variable such as # a plain variable like ${AR} - app('to_list(env[%r])' % var) - add_dvar(var) - if merge: - tmp = 'merge(%s, %s)' % (buf[-2], buf[-1]) - del buf[-1] - buf[-1] = tmp - merge = True # next turn - - buf = ['lst.extend(%s)' % x for x in buf] - fun = COMPILE_TEMPLATE_NOSHELL % "\n\t".join(buf) - Logs.debug('action: %s', fun.strip().splitlines()) - return (funex(fun), dvars) - -def compile_fun(line, shell=False): - """ - Parses a string expression such as '${CC} ${SRC} -o ${TGT}' and returns a pair containing: - - * The function created (compiled) for use as :py:meth:`waflib.Task.Task.run` - * The list of variables that must cause rebuilds when *env* data is modified - - for example:: - - from waflib.Task import compile_fun - compile_fun('cxx', '${CXX} -o ${TGT[0]} ${SRC} -I ${SRC[0].parent.bldpath()}') - - def build(bld): - bld(source='wscript', rule='echo "foo\\${SRC[0].name}\\bar"') - - The env variables (CXX, ..) on the task must not hold dicts so as to preserve a consistent order. - The reserved keywords ``TGT`` and ``SRC`` represent the task input and output nodes - - """ - if isinstance(line, str): - if line.find('<') > 0 or line.find('>') > 0 or line.find('&&') > 0: - shell = True - else: - dvars_lst = [] - funs_lst = [] - for x in line: - if isinstance(x, str): - fun, dvars = compile_fun(x, shell) - dvars_lst += dvars - funs_lst.append(fun) - else: - # assume a function to let through - funs_lst.append(x) - def composed_fun(task): - for x in funs_lst: - ret = x(task) - if ret: - return ret - return None - return composed_fun, dvars_lst - if shell: - return compile_fun_shell(line) - else: - return compile_fun_noshell(line) - -def compile_sig_vars(vars): - """ - This method produces a sig_vars method suitable for subclasses that provide - scriptlet code in their run_str code. - If no such method can be created, this method returns None. - - The purpose of the sig_vars method returned is to ensures - that rebuilds occur whenever the contents of the expression changes. - This is the case B below:: - - import time - # case A: regular variables - tg = bld(rule='echo ${FOO}') - tg.env.FOO = '%s' % time.time() - # case B - bld(rule='echo ${gen.foo}', foo='%s' % time.time()) - - :param vars: env variables such as CXXFLAGS or gen.foo - :type vars: list of string - :return: A sig_vars method relevant for dependencies if adequate, else None - :rtype: A function, or None in most cases - """ - buf = [] - for x in sorted(vars): - if x[:3] in ('tsk', 'gen', 'bld'): - buf.append('buf.append(%s)' % x) - if buf: - return funex(COMPILE_TEMPLATE_SIG_VARS % '\n\t'.join(buf)) - return None - -def task_factory(name, func=None, vars=None, color='GREEN', ext_in=[], ext_out=[], before=[], after=[], shell=False, scan=None): - """ - Returns a new task subclass with the function ``run`` compiled from the line given. - - :param func: method run - :type func: string or function - :param vars: list of variables to hash - :type vars: list of string - :param color: color to use - :type color: string - :param shell: when *func* is a string, enable/disable the use of the shell - :type shell: bool - :param scan: method scan - :type scan: function - :rtype: :py:class:`waflib.Task.Task` - """ - - params = { - 'vars': vars or [], # function arguments are static, and this one may be modified by the class - 'color': color, - 'name': name, - 'shell': shell, - 'scan': scan, - } - - if isinstance(func, str) or isinstance(func, tuple): - params['run_str'] = func - else: - params['run'] = func - - cls = type(Task)(name, (Task,), params) - classes[name] = cls - - if ext_in: - cls.ext_in = Utils.to_list(ext_in) - if ext_out: - cls.ext_out = Utils.to_list(ext_out) - if before: - cls.before = Utils.to_list(before) - if after: - cls.after = Utils.to_list(after) - - return cls - -def deep_inputs(cls): - """ - Task class decorator to enable rebuilds on input files task signatures - """ - def sig_explicit_deps(self): - Task.sig_explicit_deps(self) - Task.sig_deep_inputs(self) - cls.sig_explicit_deps = sig_explicit_deps - return cls - -TaskBase = Task -"Provided for compatibility reasons, TaskBase should not be used" - -class TaskSemaphore(object): - """ - Task semaphores provide a simple and efficient way of throttling the amount of - a particular task to run concurrently. The throttling value is capped - by the amount of maximum jobs, so for example, a `TaskSemaphore(10)` - has no effect in a `-j2` build. - - Task semaphores are typically specified on the task class level:: - - class compile(waflib.Task.Task): - semaphore = waflib.Task.TaskSemaphore(2) - run_str = 'touch ${TGT}' - - Task semaphores are meant to be used by the build scheduler in the main - thread, so there are no guarantees of thread safety. - """ - def __init__(self, num): - """ - :param num: maximum value of concurrent tasks - :type num: int - """ - self.num = num - self.locking = set() - self.waiting = set() - - def is_locked(self): - """Returns True if this semaphore cannot be acquired by more tasks""" - return len(self.locking) >= self.num - - def acquire(self, tsk): - """ - Mark the semaphore as used by the given task (not re-entrant). - - :param tsk: task object - :type tsk: :py:class:`waflib.Task.Task` - :raises: :py:class:`IndexError` in case the resource is already acquired - """ - if self.is_locked(): - raise IndexError('Cannot lock more %r' % self.locking) - self.locking.add(tsk) - - def release(self, tsk): - """ - Mark the semaphore as unused by the given task. - - :param tsk: task object - :type tsk: :py:class:`waflib.Task.Task` - :raises: :py:class:`KeyError` in case the resource is not acquired by the task - """ - self.locking.remove(tsk) - diff --git a/ldb-2.0.8/third_party/waf/waflib/TaskGen.py b/ldb-2.0.8/third_party/waf/waflib/TaskGen.py deleted file mode 100644 index f8f92bd..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/TaskGen.py +++ /dev/null @@ -1,917 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2005-2018 (ita) - -""" -Task generators - -The class :py:class:`waflib.TaskGen.task_gen` encapsulates the creation of task objects (low-level code) -The instances can have various parameters, but the creation of task nodes (Task.py) -is deferred. To achieve this, various methods are called from the method "apply" -""" - -import copy, re, os, functools -from waflib import Task, Utils, Logs, Errors, ConfigSet, Node - -feats = Utils.defaultdict(set) -"""remember the methods declaring features""" - -HEADER_EXTS = ['.h', '.hpp', '.hxx', '.hh'] - -class task_gen(object): - """ - Instances of this class create :py:class:`waflib.Task.Task` when - calling the method :py:meth:`waflib.TaskGen.task_gen.post` from the main thread. - A few notes: - - * The methods to call (*self.meths*) can be specified dynamically (removing, adding, ..) - * The 'features' are used to add methods to self.meths and then execute them - * The attribute 'path' is a node representing the location of the task generator - * The tasks created are added to the attribute *tasks* - * The attribute 'idx' is a counter of task generators in the same path - """ - - mappings = Utils.ordered_iter_dict() - """Mappings are global file extension mappings that are retrieved in the order of definition""" - - prec = Utils.defaultdict(set) - """Dict that holds the precedence execution rules for task generator methods""" - - def __init__(self, *k, **kw): - """ - Task generator objects predefine various attributes (source, target) for possible - processing by process_rule (make-like rules) or process_source (extensions, misc methods) - - Tasks are stored on the attribute 'tasks'. They are created by calling methods - listed in ``self.meths`` or referenced in the attribute ``features`` - A topological sort is performed to execute the methods in correct order. - - The extra key/value elements passed in ``kw`` are set as attributes - """ - self.source = [] - self.target = '' - - self.meths = [] - """ - List of method names to execute (internal) - """ - - self.features = [] - """ - List of feature names for bringing new methods in - """ - - self.tasks = [] - """ - Tasks created are added to this list - """ - - if not 'bld' in kw: - # task generators without a build context :-/ - self.env = ConfigSet.ConfigSet() - self.idx = 0 - self.path = None - else: - self.bld = kw['bld'] - self.env = self.bld.env.derive() - self.path = kw.get('path', self.bld.path) # by default, emulate chdir when reading scripts - - # Provide a unique index per folder - # This is part of a measure to prevent output file name collisions - path = self.path.abspath() - try: - self.idx = self.bld.idx[path] = self.bld.idx.get(path, 0) + 1 - except AttributeError: - self.bld.idx = {} - self.idx = self.bld.idx[path] = 1 - - # Record the global task generator count - try: - self.tg_idx_count = self.bld.tg_idx_count = self.bld.tg_idx_count + 1 - except AttributeError: - self.tg_idx_count = self.bld.tg_idx_count = 1 - - for key, val in kw.items(): - setattr(self, key, val) - - def __str__(self): - """Debugging helper""" - return "" % (self.name, self.path.abspath()) - - def __repr__(self): - """Debugging helper""" - lst = [] - for x in self.__dict__: - if x not in ('env', 'bld', 'compiled_tasks', 'tasks'): - lst.append("%s=%s" % (x, repr(getattr(self, x)))) - return "bld(%s) in %s" % (", ".join(lst), self.path.abspath()) - - def get_cwd(self): - """ - Current working directory for the task generator, defaults to the build directory. - This is still used in a few places but it should disappear at some point as the classes - define their own working directory. - - :rtype: :py:class:`waflib.Node.Node` - """ - return self.bld.bldnode - - def get_name(self): - """ - If the attribute ``name`` is not set on the instance, - the name is computed from the target name:: - - def build(bld): - x = bld(name='foo') - x.get_name() # foo - y = bld(target='bar') - y.get_name() # bar - - :rtype: string - :return: name of this task generator - """ - try: - return self._name - except AttributeError: - if isinstance(self.target, list): - lst = [str(x) for x in self.target] - name = self._name = ','.join(lst) - else: - name = self._name = str(self.target) - return name - def set_name(self, name): - self._name = name - - name = property(get_name, set_name) - - def to_list(self, val): - """ - Ensures that a parameter is a list, see :py:func:`waflib.Utils.to_list` - - :type val: string or list of string - :param val: input to return as a list - :rtype: list - """ - if isinstance(val, str): - return val.split() - else: - return val - - def post(self): - """ - Creates tasks for this task generators. The following operations are performed: - - #. The body of this method is called only once and sets the attribute ``posted`` - #. The attribute ``features`` is used to add more methods in ``self.meths`` - #. The methods are sorted by the precedence table ``self.prec`` or `:waflib:attr:waflib.TaskGen.task_gen.prec` - #. The methods are then executed in order - #. The tasks created are added to :py:attr:`waflib.TaskGen.task_gen.tasks` - """ - if getattr(self, 'posted', None): - return False - self.posted = True - - keys = set(self.meths) - keys.update(feats['*']) - - # add the methods listed in the features - self.features = Utils.to_list(self.features) - for x in self.features: - st = feats[x] - if st: - keys.update(st) - elif not x in Task.classes: - Logs.warn('feature %r does not exist - bind at least one method to it?', x) - - # copy the precedence table - prec = {} - prec_tbl = self.prec - for x in prec_tbl: - if x in keys: - prec[x] = prec_tbl[x] - - # elements disconnected - tmp = [] - for a in keys: - for x in prec.values(): - if a in x: - break - else: - tmp.append(a) - - tmp.sort(reverse=True) - - # topological sort - out = [] - while tmp: - e = tmp.pop() - if e in keys: - out.append(e) - try: - nlst = prec[e] - except KeyError: - pass - else: - del prec[e] - for x in nlst: - for y in prec: - if x in prec[y]: - break - else: - tmp.append(x) - tmp.sort(reverse=True) - - if prec: - buf = ['Cycle detected in the method execution:'] - for k, v in prec.items(): - buf.append('- %s after %s' % (k, [x for x in v if x in prec])) - raise Errors.WafError('\n'.join(buf)) - self.meths = out - - # then we run the methods in order - Logs.debug('task_gen: posting %s %d', self, id(self)) - for x in out: - try: - v = getattr(self, x) - except AttributeError: - raise Errors.WafError('%r is not a valid task generator method' % x) - Logs.debug('task_gen: -> %s (%d)', x, id(self)) - v() - - Logs.debug('task_gen: posted %s', self.name) - return True - - def get_hook(self, node): - """ - Returns the ``@extension`` method to call for a Node of a particular extension. - - :param node: Input file to process - :type node: :py:class:`waflib.Tools.Node.Node` - :return: A method able to process the input node by looking at the extension - :rtype: function - """ - name = node.name - for k in self.mappings: - try: - if name.endswith(k): - return self.mappings[k] - except TypeError: - # regexps objects - if k.match(name): - return self.mappings[k] - keys = list(self.mappings.keys()) - raise Errors.WafError("File %r has no mapping in %r (load a waf tool?)" % (node, keys)) - - def create_task(self, name, src=None, tgt=None, **kw): - """ - Creates task instances. - - :param name: task class name - :type name: string - :param src: input nodes - :type src: list of :py:class:`waflib.Tools.Node.Node` - :param tgt: output nodes - :type tgt: list of :py:class:`waflib.Tools.Node.Node` - :return: A task object - :rtype: :py:class:`waflib.Task.Task` - """ - task = Task.classes[name](env=self.env.derive(), generator=self) - if src: - task.set_inputs(src) - if tgt: - task.set_outputs(tgt) - task.__dict__.update(kw) - self.tasks.append(task) - return task - - def clone(self, env): - """ - Makes a copy of a task generator. Once the copy is made, it is necessary to ensure that the - it does not create the same output files as the original, or the same files may - be compiled several times. - - :param env: A configuration set - :type env: :py:class:`waflib.ConfigSet.ConfigSet` - :return: A copy - :rtype: :py:class:`waflib.TaskGen.task_gen` - """ - newobj = self.bld() - for x in self.__dict__: - if x in ('env', 'bld'): - continue - elif x in ('path', 'features'): - setattr(newobj, x, getattr(self, x)) - else: - setattr(newobj, x, copy.copy(getattr(self, x))) - - newobj.posted = False - if isinstance(env, str): - newobj.env = self.bld.all_envs[env].derive() - else: - newobj.env = env.derive() - - return newobj - -def declare_chain(name='', rule=None, reentrant=None, color='BLUE', - ext_in=[], ext_out=[], before=[], after=[], decider=None, scan=None, install_path=None, shell=False): - """ - Creates a new mapping and a task class for processing files by extension. - See Tools/flex.py for an example. - - :param name: name for the task class - :type name: string - :param rule: function to execute or string to be compiled in a function - :type rule: string or function - :param reentrant: re-inject the output file in the process (done automatically, set to 0 to disable) - :type reentrant: int - :param color: color for the task output - :type color: string - :param ext_in: execute the task only after the files of such extensions are created - :type ext_in: list of string - :param ext_out: execute the task only before files of such extensions are processed - :type ext_out: list of string - :param before: execute instances of this task before classes of the given names - :type before: list of string - :param after: execute instances of this task after classes of the given names - :type after: list of string - :param decider: if present, function that returns a list of output file extensions (overrides ext_out for output files, but not for the build order) - :type decider: function - :param scan: scanner function for the task - :type scan: function - :param install_path: installation path for the output nodes - :type install_path: string - """ - ext_in = Utils.to_list(ext_in) - ext_out = Utils.to_list(ext_out) - if not name: - name = rule - cls = Task.task_factory(name, rule, color=color, ext_in=ext_in, ext_out=ext_out, before=before, after=after, scan=scan, shell=shell) - - def x_file(self, node): - if ext_in: - _ext_in = ext_in[0] - - tsk = self.create_task(name, node) - cnt = 0 - - ext = decider(self, node) if decider else cls.ext_out - for x in ext: - k = node.change_ext(x, ext_in=_ext_in) - tsk.outputs.append(k) - - if reentrant != None: - if cnt < int(reentrant): - self.source.append(k) - else: - # reinject downstream files into the build - for y in self.mappings: # ~ nfile * nextensions :-/ - if k.name.endswith(y): - self.source.append(k) - break - cnt += 1 - - if install_path: - self.install_task = self.add_install_files(install_to=install_path, install_from=tsk.outputs) - return tsk - - for x in cls.ext_in: - task_gen.mappings[x] = x_file - return x_file - -def taskgen_method(func): - """ - Decorator that registers method as a task generator method. - The function must accept a task generator as first parameter:: - - from waflib.TaskGen import taskgen_method - @taskgen_method - def mymethod(self): - pass - - :param func: task generator method to add - :type func: function - :rtype: function - """ - setattr(task_gen, func.__name__, func) - return func - -def feature(*k): - """ - Decorator that registers a task generator method that will be executed when the - object attribute ``feature`` contains the corresponding key(s):: - - from waflib.Task import feature - @feature('myfeature') - def myfunction(self): - print('that is my feature!') - def build(bld): - bld(features='myfeature') - - :param k: feature names - :type k: list of string - """ - def deco(func): - setattr(task_gen, func.__name__, func) - for name in k: - feats[name].update([func.__name__]) - return func - return deco - -def before_method(*k): - """ - Decorator that registera task generator method which will be executed - before the functions of given name(s):: - - from waflib.TaskGen import feature, before - @feature('myfeature') - @before_method('fun2') - def fun1(self): - print('feature 1!') - @feature('myfeature') - def fun2(self): - print('feature 2!') - def build(bld): - bld(features='myfeature') - - :param k: method names - :type k: list of string - """ - def deco(func): - setattr(task_gen, func.__name__, func) - for fun_name in k: - task_gen.prec[func.__name__].add(fun_name) - return func - return deco -before = before_method - -def after_method(*k): - """ - Decorator that registers a task generator method which will be executed - after the functions of given name(s):: - - from waflib.TaskGen import feature, after - @feature('myfeature') - @after_method('fun2') - def fun1(self): - print('feature 1!') - @feature('myfeature') - def fun2(self): - print('feature 2!') - def build(bld): - bld(features='myfeature') - - :param k: method names - :type k: list of string - """ - def deco(func): - setattr(task_gen, func.__name__, func) - for fun_name in k: - task_gen.prec[fun_name].add(func.__name__) - return func - return deco -after = after_method - -def extension(*k): - """ - Decorator that registers a task generator method which will be invoked during - the processing of source files for the extension given:: - - from waflib import Task - class mytask(Task): - run_str = 'cp ${SRC} ${TGT}' - @extension('.moo') - def create_maa_file(self, node): - self.create_task('mytask', node, node.change_ext('.maa')) - def build(bld): - bld(source='foo.moo') - """ - def deco(func): - setattr(task_gen, func.__name__, func) - for x in k: - task_gen.mappings[x] = func - return func - return deco - -@taskgen_method -def to_nodes(self, lst, path=None): - """ - Flatten the input list of string/nodes/lists into a list of nodes. - - It is used by :py:func:`waflib.TaskGen.process_source` and :py:func:`waflib.TaskGen.process_rule`. - It is designed for source files, for folders, see :py:func:`waflib.Tools.ccroot.to_incnodes`: - - :param lst: input list - :type lst: list of string and nodes - :param path: path from which to search the nodes (by default, :py:attr:`waflib.TaskGen.task_gen.path`) - :type path: :py:class:`waflib.Tools.Node.Node` - :rtype: list of :py:class:`waflib.Tools.Node.Node` - """ - tmp = [] - path = path or self.path - find = path.find_resource - - if isinstance(lst, Node.Node): - lst = [lst] - - for x in Utils.to_list(lst): - if isinstance(x, str): - node = find(x) - elif hasattr(x, 'name'): - node = x - else: - tmp.extend(self.to_nodes(x)) - continue - if not node: - raise Errors.WafError('source not found: %r in %r' % (x, self)) - tmp.append(node) - return tmp - -@feature('*') -def process_source(self): - """ - Processes each element in the attribute ``source`` by extension. - - #. The *source* list is converted through :py:meth:`waflib.TaskGen.to_nodes` to a list of :py:class:`waflib.Node.Node` first. - #. File extensions are mapped to methods having the signature: ``def meth(self, node)`` by :py:meth:`waflib.TaskGen.extension` - #. The method is retrieved through :py:meth:`waflib.TaskGen.task_gen.get_hook` - #. When called, the methods may modify self.source to append more source to process - #. The mappings can map an extension or a filename (see the code below) - """ - self.source = self.to_nodes(getattr(self, 'source', [])) - for node in self.source: - self.get_hook(node)(self, node) - -@feature('*') -@before_method('process_source') -def process_rule(self): - """ - Processes the attribute ``rule``. When present, :py:meth:`waflib.TaskGen.process_source` is disabled:: - - def build(bld): - bld(rule='cp ${SRC} ${TGT}', source='wscript', target='bar.txt') - - Main attributes processed: - - * rule: command to execute, it can be a tuple of strings for multiple commands - * chmod: permissions for the resulting files (integer value such as Utils.O755) - * shell: set to False to execute the command directly (default is True to use a shell) - * scan: scanner function - * vars: list of variables to trigger rebuilds, such as CFLAGS - * cls_str: string to display when executing the task - * cls_keyword: label to display when executing the task - * cache_rule: by default, try to re-use similar classes, set to False to disable - * source: list of Node or string objects representing the source files required by this task - * target: list of Node or string objects representing the files that this task creates - * cwd: current working directory (Node or string) - * stdout: standard output, set to None to prevent waf from capturing the text - * stderr: standard error, set to None to prevent waf from capturing the text - * timeout: timeout for command execution (Python 3) - * always: whether to always run the command (False by default) - * deep_inputs: whether the task must depend on the input file tasks too (False by default) - """ - if not getattr(self, 'rule', None): - return - - # create the task class - name = str(getattr(self, 'name', None) or self.target or getattr(self.rule, '__name__', self.rule)) - - # or we can put the class in a cache for performance reasons - try: - cache = self.bld.cache_rule_attr - except AttributeError: - cache = self.bld.cache_rule_attr = {} - - chmod = getattr(self, 'chmod', None) - shell = getattr(self, 'shell', True) - color = getattr(self, 'color', 'BLUE') - scan = getattr(self, 'scan', None) - _vars = getattr(self, 'vars', []) - cls_str = getattr(self, 'cls_str', None) - cls_keyword = getattr(self, 'cls_keyword', None) - use_cache = getattr(self, 'cache_rule', 'True') - deep_inputs = getattr(self, 'deep_inputs', False) - - scan_val = has_deps = hasattr(self, 'deps') - if scan: - scan_val = id(scan) - - key = Utils.h_list((name, self.rule, chmod, shell, color, cls_str, cls_keyword, scan_val, _vars, deep_inputs)) - - cls = None - if use_cache: - try: - cls = cache[key] - except KeyError: - pass - if not cls: - rule = self.rule - if chmod is not None: - def chmod_fun(tsk): - for x in tsk.outputs: - os.chmod(x.abspath(), tsk.generator.chmod) - if isinstance(rule, tuple): - rule = list(rule) - rule.append(chmod_fun) - rule = tuple(rule) - else: - rule = (rule, chmod_fun) - - cls = Task.task_factory(name, rule, _vars, shell=shell, color=color) - - if cls_str: - setattr(cls, '__str__', self.cls_str) - - if cls_keyword: - setattr(cls, 'keyword', self.cls_keyword) - - if deep_inputs: - Task.deep_inputs(cls) - - if scan: - cls.scan = self.scan - elif has_deps: - def scan(self): - nodes = [] - for x in self.generator.to_list(getattr(self.generator, 'deps', None)): - node = self.generator.path.find_resource(x) - if not node: - self.generator.bld.fatal('Could not find %r (was it declared?)' % x) - nodes.append(node) - return [nodes, []] - cls.scan = scan - - if use_cache: - cache[key] = cls - - # now create one instance - tsk = self.create_task(name) - - for x in ('after', 'before', 'ext_in', 'ext_out'): - setattr(tsk, x, getattr(self, x, [])) - - if hasattr(self, 'stdout'): - tsk.stdout = self.stdout - - if hasattr(self, 'stderr'): - tsk.stderr = self.stderr - - if getattr(self, 'timeout', None): - tsk.timeout = self.timeout - - if getattr(self, 'always', None): - tsk.always_run = True - - if getattr(self, 'target', None): - if isinstance(self.target, str): - self.target = self.target.split() - if not isinstance(self.target, list): - self.target = [self.target] - for x in self.target: - if isinstance(x, str): - tsk.outputs.append(self.path.find_or_declare(x)) - else: - x.parent.mkdir() # if a node was given, create the required folders - tsk.outputs.append(x) - if getattr(self, 'install_path', None): - self.install_task = self.add_install_files(install_to=self.install_path, - install_from=tsk.outputs, chmod=getattr(self, 'chmod', Utils.O644)) - - if getattr(self, 'source', None): - tsk.inputs = self.to_nodes(self.source) - # bypass the execution of process_source by setting the source to an empty list - self.source = [] - - if getattr(self, 'cwd', None): - tsk.cwd = self.cwd - - if isinstance(tsk.run, functools.partial): - # Python documentation says: "partial objects defined in classes - # behave like static methods and do not transform into bound - # methods during instance attribute look-up." - tsk.run = functools.partial(tsk.run, tsk) - -@feature('seq') -def sequence_order(self): - """ - Adds a strict sequential constraint between the tasks generated by task generators. - It works because task generators are posted in order. - It will not post objects which belong to other folders. - - Example:: - - bld(features='javac seq') - bld(features='jar seq') - - To start a new sequence, set the attribute seq_start, for example:: - - obj = bld(features='seq') - obj.seq_start = True - - Note that the method is executed in last position. This is more an - example than a widely-used solution. - """ - if self.meths and self.meths[-1] != 'sequence_order': - self.meths.append('sequence_order') - return - - if getattr(self, 'seq_start', None): - return - - # all the tasks previously declared must be run before these - if getattr(self.bld, 'prev', None): - self.bld.prev.post() - for x in self.bld.prev.tasks: - for y in self.tasks: - y.set_run_after(x) - - self.bld.prev = self - - -re_m4 = re.compile(r'@(\w+)@', re.M) - -class subst_pc(Task.Task): - """ - Creates *.pc* files from *.pc.in*. The task is executed whenever an input variable used - in the substitution changes. - """ - - def force_permissions(self): - "Private for the time being, we will probably refactor this into run_str=[run1,chmod]" - if getattr(self.generator, 'chmod', None): - for x in self.outputs: - os.chmod(x.abspath(), self.generator.chmod) - - def run(self): - "Substitutes variables in a .in file" - - if getattr(self.generator, 'is_copy', None): - for i, x in enumerate(self.outputs): - x.write(self.inputs[i].read('rb'), 'wb') - stat = os.stat(self.inputs[i].abspath()) # Preserve mtime of the copy - os.utime(self.outputs[i].abspath(), (stat.st_atime, stat.st_mtime)) - self.force_permissions() - return None - - if getattr(self.generator, 'fun', None): - ret = self.generator.fun(self) - if not ret: - self.force_permissions() - return ret - - code = self.inputs[0].read(encoding=getattr(self.generator, 'encoding', 'latin-1')) - if getattr(self.generator, 'subst_fun', None): - code = self.generator.subst_fun(self, code) - if code is not None: - self.outputs[0].write(code, encoding=getattr(self.generator, 'encoding', 'latin-1')) - self.force_permissions() - return None - - # replace all % by %% to prevent errors by % signs - code = code.replace('%', '%%') - - # extract the vars foo into lst and replace @foo@ by %(foo)s - lst = [] - def repl(match): - g = match.group - if g(1): - lst.append(g(1)) - return "%%(%s)s" % g(1) - return '' - code = getattr(self.generator, 're_m4', re_m4).sub(repl, code) - - try: - d = self.generator.dct - except AttributeError: - d = {} - for x in lst: - tmp = getattr(self.generator, x, '') or self.env[x] or self.env[x.upper()] - try: - tmp = ''.join(tmp) - except TypeError: - tmp = str(tmp) - d[x] = tmp - - code = code % d - self.outputs[0].write(code, encoding=getattr(self.generator, 'encoding', 'latin-1')) - self.generator.bld.raw_deps[self.uid()] = lst - - # make sure the signature is updated - try: - delattr(self, 'cache_sig') - except AttributeError: - pass - - self.force_permissions() - - def sig_vars(self): - """ - Compute a hash (signature) of the variables used in the substitution - """ - bld = self.generator.bld - env = self.env - upd = self.m.update - - if getattr(self.generator, 'fun', None): - upd(Utils.h_fun(self.generator.fun).encode()) - if getattr(self.generator, 'subst_fun', None): - upd(Utils.h_fun(self.generator.subst_fun).encode()) - - # raw_deps: persistent custom values returned by the scanner - vars = self.generator.bld.raw_deps.get(self.uid(), []) - - # hash both env vars and task generator attributes - act_sig = bld.hash_env_vars(env, vars) - upd(act_sig) - - lst = [getattr(self.generator, x, '') for x in vars] - upd(Utils.h_list(lst)) - - return self.m.digest() - -@extension('.pc.in') -def add_pcfile(self, node): - """ - Processes *.pc.in* files to *.pc*. Installs the results to ``${PREFIX}/lib/pkgconfig/`` by default - - def build(bld): - bld(source='foo.pc.in', install_path='${LIBDIR}/pkgconfig/') - """ - tsk = self.create_task('subst_pc', node, node.change_ext('.pc', '.pc.in')) - self.install_task = self.add_install_files( - install_to=getattr(self, 'install_path', '${LIBDIR}/pkgconfig/'), install_from=tsk.outputs) - -class subst(subst_pc): - pass - -@feature('subst') -@before_method('process_source', 'process_rule') -def process_subst(self): - """ - Defines a transformation that substitutes the contents of *source* files to *target* files:: - - def build(bld): - bld( - features='subst', - source='foo.c.in', - target='foo.c', - install_path='${LIBDIR}/pkgconfig', - VAR = 'val' - ) - - The input files are supposed to contain macros of the form *@VAR@*, where *VAR* is an argument - of the task generator object. - - This method overrides the processing by :py:meth:`waflib.TaskGen.process_source`. - """ - - src = Utils.to_list(getattr(self, 'source', [])) - if isinstance(src, Node.Node): - src = [src] - tgt = Utils.to_list(getattr(self, 'target', [])) - if isinstance(tgt, Node.Node): - tgt = [tgt] - if len(src) != len(tgt): - raise Errors.WafError('invalid number of source/target for %r' % self) - - for x, y in zip(src, tgt): - if not x or not y: - raise Errors.WafError('null source or target for %r' % self) - a, b = None, None - - if isinstance(x, str) and isinstance(y, str) and x == y: - a = self.path.find_node(x) - b = self.path.get_bld().make_node(y) - if not os.path.isfile(b.abspath()): - b.parent.mkdir() - else: - if isinstance(x, str): - a = self.path.find_resource(x) - elif isinstance(x, Node.Node): - a = x - if isinstance(y, str): - b = self.path.find_or_declare(y) - elif isinstance(y, Node.Node): - b = y - - if not a: - raise Errors.WafError('could not find %r for %r' % (x, self)) - - tsk = self.create_task('subst', a, b) - for k in ('after', 'before', 'ext_in', 'ext_out'): - val = getattr(self, k, None) - if val: - setattr(tsk, k, val) - - # paranoid safety measure for the general case foo.in->foo.h with ambiguous dependencies - for xt in HEADER_EXTS: - if b.name.endswith(xt): - tsk.ext_out = tsk.ext_out + ['.h'] - break - - inst_to = getattr(self, 'install_path', None) - if inst_to: - self.install_task = self.add_install_files(install_to=inst_to, - install_from=b, chmod=getattr(self, 'chmod', Utils.O644)) - - self.source = [] - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/__init__.py b/ldb-2.0.8/third_party/waf/waflib/Tools/__init__.py deleted file mode 100644 index 079df35..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2005-2018 (ita) diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/ar.py b/ldb-2.0.8/third_party/waf/waflib/Tools/ar.py deleted file mode 100644 index b39b645..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/ar.py +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2006-2018 (ita) -# Ralf Habacker, 2006 (rh) - -""" -The **ar** program creates static libraries. This tool is almost always loaded -from others (C, C++, D, etc) for static library support. -""" - -from waflib.Configure import conf - -@conf -def find_ar(conf): - """Configuration helper used by C/C++ tools to enable the support for static libraries""" - conf.load('ar') - -def configure(conf): - """Finds the ar program and sets the default flags in ``conf.env.ARFLAGS``""" - conf.find_program('ar', var='AR') - conf.add_os_flags('ARFLAGS') - if not conf.env.ARFLAGS: - conf.env.ARFLAGS = ['rcs'] - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/asm.py b/ldb-2.0.8/third_party/waf/waflib/Tools/asm.py deleted file mode 100644 index a57e83b..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/asm.py +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2008-2018 (ita) - -""" -Assembly support, used by tools such as gas and nasm - -To declare targets using assembly:: - - def configure(conf): - conf.load('gcc gas') - - def build(bld): - bld( - features='c cstlib asm', - source = 'test.S', - target = 'asmtest') - - bld( - features='asm asmprogram', - source = 'test.S', - target = 'asmtest') - -Support for pure asm programs and libraries should also work:: - - def configure(conf): - conf.load('nasm') - conf.find_program('ld', 'ASLINK') - - def build(bld): - bld( - features='asm asmprogram', - source = 'test.S', - target = 'asmtest') -""" - -import re -from waflib import Errors, Logs, Task -from waflib.Tools.ccroot import link_task, stlink_task -from waflib.TaskGen import extension -from waflib.Tools import c_preproc - -re_lines = re.compile( - '^[ \t]*(?:%)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef)[ \t]*(.*)\r*$', - re.IGNORECASE | re.MULTILINE) - -class asm_parser(c_preproc.c_parser): - def filter_comments(self, node): - code = node.read() - code = c_preproc.re_nl.sub('', code) - code = c_preproc.re_cpp.sub(c_preproc.repl, code) - return re_lines.findall(code) - -class asm(Task.Task): - """ - Compiles asm files by gas/nasm/yasm/... - """ - color = 'BLUE' - run_str = '${AS} ${ASFLAGS} ${ASMPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${AS_SRC_F}${SRC} ${AS_TGT_F}${TGT}' - - def scan(self): - if self.env.ASM_NAME == 'gas': - return c_preproc.scan(self) - Logs.warn('There is no dependency scanner for Nasm!') - return [[], []] - elif self.env.ASM_NAME == 'nasm': - Logs.warn('The Nasm dependency scanner is incomplete!') - - try: - incn = self.generator.includes_nodes - except AttributeError: - raise Errors.WafError('%r is missing the "asm" feature' % self.generator) - - if c_preproc.go_absolute: - nodepaths = incn - else: - nodepaths = [x for x in incn if x.is_child_of(x.ctx.srcnode) or x.is_child_of(x.ctx.bldnode)] - - tmp = asm_parser(nodepaths) - tmp.start(self.inputs[0], self.env) - return (tmp.nodes, tmp.names) - -@extension('.s', '.S', '.asm', '.ASM', '.spp', '.SPP') -def asm_hook(self, node): - """ - Binds the asm extension to the asm task - - :param node: input file - :type node: :py:class:`waflib.Node.Node` - """ - return self.create_compiled_task('asm', node) - -class asmprogram(link_task): - "Links object files into a c program" - run_str = '${ASLINK} ${ASLINKFLAGS} ${ASLNK_TGT_F}${TGT} ${ASLNK_SRC_F}${SRC}' - ext_out = ['.bin'] - inst_to = '${BINDIR}' - -class asmshlib(asmprogram): - "Links object files into a c shared library" - inst_to = '${LIBDIR}' - -class asmstlib(stlink_task): - "Links object files into a c static library" - pass # do not remove - -def configure(conf): - conf.env.ASMPATH_ST = '-I%s' diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/bison.py b/ldb-2.0.8/third_party/waf/waflib/Tools/bison.py deleted file mode 100644 index eef56dc..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/bison.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# John O'Meara, 2006 -# Thomas Nagy 2009-2018 (ita) - -""" -The **bison** program is a code generator which creates C or C++ files. -The generated files are compiled into object files. -""" - -from waflib import Task -from waflib.TaskGen import extension - -class bison(Task.Task): - """Compiles bison files""" - color = 'BLUE' - run_str = '${BISON} ${BISONFLAGS} ${SRC[0].abspath()} -o ${TGT[0].name}' - ext_out = ['.h'] # just to make sure - -@extension('.y', '.yc', '.yy') -def big_bison(self, node): - """ - Creates a bison task, which must be executed from the directory of the output file. - """ - has_h = '-d' in self.env.BISONFLAGS - - outs = [] - if node.name.endswith('.yc'): - outs.append(node.change_ext('.tab.cc')) - if has_h: - outs.append(node.change_ext('.tab.hh')) - else: - outs.append(node.change_ext('.tab.c')) - if has_h: - outs.append(node.change_ext('.tab.h')) - - tsk = self.create_task('bison', node, outs) - tsk.cwd = node.parent.get_bld() - - # and the c/cxx file must be compiled too - self.source.append(outs[0]) - -def configure(conf): - """ - Detects the *bison* program - """ - conf.find_program('bison', var='BISON') - conf.env.BISONFLAGS = ['-d'] - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/c.py b/ldb-2.0.8/third_party/waf/waflib/Tools/c.py deleted file mode 100644 index effd6b6..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/c.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2006-2018 (ita) - -"Base for c programs/libraries" - -from waflib import TaskGen, Task -from waflib.Tools import c_preproc -from waflib.Tools.ccroot import link_task, stlink_task - -@TaskGen.extension('.c') -def c_hook(self, node): - "Binds the c file extensions create :py:class:`waflib.Tools.c.c` instances" - if not self.env.CC and self.env.CXX: - return self.create_compiled_task('cxx', node) - return self.create_compiled_task('c', node) - -class c(Task.Task): - "Compiles C files into object files" - run_str = '${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CC_SRC_F}${SRC} ${CC_TGT_F}${TGT[0].abspath()} ${CPPFLAGS}' - vars = ['CCDEPS'] # unused variable to depend on, just in case - ext_in = ['.h'] # set the build order easily by using ext_out=['.h'] - scan = c_preproc.scan - -class cprogram(link_task): - "Links object files into c programs" - run_str = '${LINK_CC} ${LINKFLAGS} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LDFLAGS}' - ext_out = ['.bin'] - vars = ['LINKDEPS'] - inst_to = '${BINDIR}' - -class cshlib(cprogram): - "Links object files into c shared libraries" - inst_to = '${LIBDIR}' - -class cstlib(stlink_task): - "Links object files into a c static libraries" - pass # do not remove - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/c_aliases.py b/ldb-2.0.8/third_party/waf/waflib/Tools/c_aliases.py deleted file mode 100644 index 985e048..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/c_aliases.py +++ /dev/null @@ -1,146 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2005-2015 (ita) - -"base for all c/c++ programs and libraries" - -from waflib import Utils, Errors -from waflib.Configure import conf - -def get_extensions(lst): - """ - Returns the file extensions for the list of files given as input - - :param lst: files to process - :list lst: list of string or :py:class:`waflib.Node.Node` - :return: list of file extensions - :rtype: list of string - """ - ret = [] - for x in Utils.to_list(lst): - if not isinstance(x, str): - x = x.name - ret.append(x[x.rfind('.') + 1:]) - return ret - -def sniff_features(**kw): - """ - Computes and returns the features required for a task generator by - looking at the file extensions. This aimed for C/C++ mainly:: - - snif_features(source=['foo.c', 'foo.cxx'], type='shlib') - # returns ['cxx', 'c', 'cxxshlib', 'cshlib'] - - :param source: source files to process - :type source: list of string or :py:class:`waflib.Node.Node` - :param type: object type in *program*, *shlib* or *stlib* - :type type: string - :return: the list of features for a task generator processing the source files - :rtype: list of string - """ - exts = get_extensions(kw['source']) - typ = kw['typ'] - feats = [] - - # watch the order, cxx will have the precedence - for x in 'cxx cpp c++ cc C'.split(): - if x in exts: - feats.append('cxx') - break - if 'c' in exts or 'vala' in exts or 'gs' in exts: - feats.append('c') - - if 's' in exts or 'S' in exts: - feats.append('asm') - - for x in 'f f90 F F90 for FOR'.split(): - if x in exts: - feats.append('fc') - break - - if 'd' in exts: - feats.append('d') - - if 'java' in exts: - feats.append('java') - return 'java' - - if typ in ('program', 'shlib', 'stlib'): - will_link = False - for x in feats: - if x in ('cxx', 'd', 'fc', 'c', 'asm'): - feats.append(x + typ) - will_link = True - if not will_link and not kw.get('features', []): - raise Errors.WafError('Cannot link from %r, try passing eg: features="c cprogram"?' % kw) - return feats - -def set_features(kw, typ): - """ - Inserts data in the input dict *kw* based on existing data and on the type of target - required (typ). - - :param kw: task generator parameters - :type kw: dict - :param typ: type of target - :type typ: string - """ - kw['typ'] = typ - kw['features'] = Utils.to_list(kw.get('features', [])) + Utils.to_list(sniff_features(**kw)) - -@conf -def program(bld, *k, **kw): - """ - Alias for creating programs by looking at the file extensions:: - - def build(bld): - bld.program(source='foo.c', target='app') - # equivalent to: - # bld(features='c cprogram', source='foo.c', target='app') - - """ - set_features(kw, 'program') - return bld(*k, **kw) - -@conf -def shlib(bld, *k, **kw): - """ - Alias for creating shared libraries by looking at the file extensions:: - - def build(bld): - bld.shlib(source='foo.c', target='app') - # equivalent to: - # bld(features='c cshlib', source='foo.c', target='app') - - """ - set_features(kw, 'shlib') - return bld(*k, **kw) - -@conf -def stlib(bld, *k, **kw): - """ - Alias for creating static libraries by looking at the file extensions:: - - def build(bld): - bld.stlib(source='foo.cpp', target='app') - # equivalent to: - # bld(features='cxx cxxstlib', source='foo.cpp', target='app') - - """ - set_features(kw, 'stlib') - return bld(*k, **kw) - -@conf -def objects(bld, *k, **kw): - """ - Alias for creating object files by looking at the file extensions:: - - def build(bld): - bld.objects(source='foo.c', target='app') - # equivalent to: - # bld(features='c', source='foo.c', target='app') - - """ - set_features(kw, 'objects') - return bld(*k, **kw) - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/c_config.py b/ldb-2.0.8/third_party/waf/waflib/Tools/c_config.py deleted file mode 100644 index 80580cc..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/c_config.py +++ /dev/null @@ -1,1352 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2005-2018 (ita) - -""" -C/C++/D configuration helpers -""" - -from __future__ import with_statement - -import os, re, shlex -from waflib import Build, Utils, Task, Options, Logs, Errors, Runner -from waflib.TaskGen import after_method, feature -from waflib.Configure import conf - -WAF_CONFIG_H = 'config.h' -"""default name for the config.h file""" - -DEFKEYS = 'define_key' -INCKEYS = 'include_key' - -SNIP_EMPTY_PROGRAM = ''' -int main(int argc, char **argv) { - (void)argc; (void)argv; - return 0; -} -''' - -MACRO_TO_DESTOS = { -'__linux__' : 'linux', -'__GNU__' : 'gnu', # hurd -'__FreeBSD__' : 'freebsd', -'__NetBSD__' : 'netbsd', -'__OpenBSD__' : 'openbsd', -'__sun' : 'sunos', -'__hpux' : 'hpux', -'__sgi' : 'irix', -'_AIX' : 'aix', -'__CYGWIN__' : 'cygwin', -'__MSYS__' : 'cygwin', -'_UWIN' : 'uwin', -'_WIN64' : 'win32', -'_WIN32' : 'win32', -# Note about darwin: this is also tested with 'defined __APPLE__ && defined __MACH__' somewhere below in this file. -'__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' : 'darwin', -'__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__' : 'darwin', # iphone -'__QNX__' : 'qnx', -'__native_client__' : 'nacl' # google native client platform -} - -MACRO_TO_DEST_CPU = { -'__x86_64__' : 'x86_64', -'__amd64__' : 'x86_64', -'__i386__' : 'x86', -'__ia64__' : 'ia', -'__mips__' : 'mips', -'__sparc__' : 'sparc', -'__alpha__' : 'alpha', -'__aarch64__' : 'aarch64', -'__thumb__' : 'thumb', -'__arm__' : 'arm', -'__hppa__' : 'hppa', -'__powerpc__' : 'powerpc', -'__ppc__' : 'powerpc', -'__convex__' : 'convex', -'__m68k__' : 'm68k', -'__s390x__' : 's390x', -'__s390__' : 's390', -'__sh__' : 'sh', -'__xtensa__' : 'xtensa', -} - -@conf -def parse_flags(self, line, uselib_store, env=None, force_static=False, posix=None): - """ - Parses flags from the input lines, and adds them to the relevant use variables:: - - def configure(conf): - conf.parse_flags('-O3', 'FOO') - # conf.env.CXXFLAGS_FOO = ['-O3'] - # conf.env.CFLAGS_FOO = ['-O3'] - - :param line: flags - :type line: string - :param uselib_store: where to add the flags - :type uselib_store: string - :param env: config set or conf.env by default - :type env: :py:class:`waflib.ConfigSet.ConfigSet` - """ - - assert(isinstance(line, str)) - - env = env or self.env - - # Issue 811 and 1371 - if posix is None: - posix = True - if '\\' in line: - posix = ('\\ ' in line) or ('\\\\' in line) - - lex = shlex.shlex(line, posix=posix) - lex.whitespace_split = True - lex.commenters = '' - lst = list(lex) - - # append_unique is not always possible - # for example, apple flags may require both -arch i386 and -arch ppc - uselib = uselib_store - def app(var, val): - env.append_value('%s_%s' % (var, uselib), val) - def appu(var, val): - env.append_unique('%s_%s' % (var, uselib), val) - static = False - while lst: - x = lst.pop(0) - st = x[:2] - ot = x[2:] - - if st == '-I' or st == '/I': - if not ot: - ot = lst.pop(0) - appu('INCLUDES', ot) - elif st == '-i': - tmp = [x, lst.pop(0)] - app('CFLAGS', tmp) - app('CXXFLAGS', tmp) - elif st == '-D' or (env.CXX_NAME == 'msvc' and st == '/D'): # not perfect but.. - if not ot: - ot = lst.pop(0) - app('DEFINES', ot) - elif st == '-l': - if not ot: - ot = lst.pop(0) - prefix = 'STLIB' if (force_static or static) else 'LIB' - app(prefix, ot) - elif st == '-L': - if not ot: - ot = lst.pop(0) - prefix = 'STLIBPATH' if (force_static or static) else 'LIBPATH' - appu(prefix, ot) - elif x.startswith('/LIBPATH:'): - prefix = 'STLIBPATH' if (force_static or static) else 'LIBPATH' - appu(prefix, x.replace('/LIBPATH:', '')) - elif x.startswith('-std='): - prefix = 'CXXFLAGS' if '++' in x else 'CFLAGS' - app(prefix, x) - elif x.startswith('+') or x in ('-pthread', '-fPIC', '-fpic', '-fPIE', '-fpie'): - app('CFLAGS', x) - app('CXXFLAGS', x) - app('LINKFLAGS', x) - elif x == '-framework': - appu('FRAMEWORK', lst.pop(0)) - elif x.startswith('-F'): - appu('FRAMEWORKPATH', x[2:]) - elif x == '-Wl,-rpath' or x == '-Wl,-R': - app('RPATH', lst.pop(0).lstrip('-Wl,')) - elif x.startswith('-Wl,-R,'): - app('RPATH', x[7:]) - elif x.startswith('-Wl,-R'): - app('RPATH', x[6:]) - elif x.startswith('-Wl,-rpath,'): - app('RPATH', x[11:]) - elif x == '-Wl,-Bstatic' or x == '-Bstatic': - static = True - elif x == '-Wl,-Bdynamic' or x == '-Bdynamic': - static = False - elif x.startswith('-Wl') or x in ('-rdynamic', '-pie'): - app('LINKFLAGS', x) - elif x.startswith(('-m', '-f', '-dynamic', '-O', '-g')): - # Adding the -W option breaks python builds on Openindiana - app('CFLAGS', x) - app('CXXFLAGS', x) - elif x.startswith('-bundle'): - app('LINKFLAGS', x) - elif x.startswith(('-undefined', '-Xlinker')): - arg = lst.pop(0) - app('LINKFLAGS', [x, arg]) - elif x.startswith(('-arch', '-isysroot')): - tmp = [x, lst.pop(0)] - app('CFLAGS', tmp) - app('CXXFLAGS', tmp) - app('LINKFLAGS', tmp) - elif x.endswith(('.a', '.so', '.dylib', '.lib')): - appu('LINKFLAGS', x) # not cool, #762 - else: - self.to_log('Unhandled flag %r' % x) - -@conf -def validate_cfg(self, kw): - """ - Searches for the program *pkg-config* if missing, and validates the - parameters to pass to :py:func:`waflib.Tools.c_config.exec_cfg`. - - :param path: the **-config program to use** (default is *pkg-config*) - :type path: list of string - :param msg: message to display to describe the test executed - :type msg: string - :param okmsg: message to display when the test is successful - :type okmsg: string - :param errmsg: message to display in case of error - :type errmsg: string - """ - if not 'path' in kw: - if not self.env.PKGCONFIG: - self.find_program('pkg-config', var='PKGCONFIG') - kw['path'] = self.env.PKGCONFIG - - # verify that exactly one action is requested - s = ('atleast_pkgconfig_version' in kw) + ('modversion' in kw) + ('package' in kw) - if s != 1: - raise ValueError('exactly one of atleast_pkgconfig_version, modversion and package must be set') - if not 'msg' in kw: - if 'atleast_pkgconfig_version' in kw: - kw['msg'] = 'Checking for pkg-config version >= %r' % kw['atleast_pkgconfig_version'] - elif 'modversion' in kw: - kw['msg'] = 'Checking for %r version' % kw['modversion'] - else: - kw['msg'] = 'Checking for %r' %(kw['package']) - - # let the modversion check set the okmsg to the detected version - if not 'okmsg' in kw and not 'modversion' in kw: - kw['okmsg'] = 'yes' - if not 'errmsg' in kw: - kw['errmsg'] = 'not found' - - # pkg-config version - if 'atleast_pkgconfig_version' in kw: - pass - elif 'modversion' in kw: - if not 'uselib_store' in kw: - kw['uselib_store'] = kw['modversion'] - if not 'define_name' in kw: - kw['define_name'] = '%s_VERSION' % Utils.quote_define_name(kw['uselib_store']) - else: - if not 'uselib_store' in kw: - kw['uselib_store'] = Utils.to_list(kw['package'])[0].upper() - if not 'define_name' in kw: - kw['define_name'] = self.have_define(kw['uselib_store']) - -@conf -def exec_cfg(self, kw): - """ - Executes ``pkg-config`` or other ``-config`` applications to collect configuration flags: - - * if atleast_pkgconfig_version is given, check that pkg-config has the version n and return - * if modversion is given, then return the module version - * else, execute the *-config* program with the *args* and *variables* given, and set the flags on the *conf.env.FLAGS_name* variable - - :param atleast_pkgconfig_version: minimum pkg-config version to use (disable other tests) - :type atleast_pkgconfig_version: string - :param package: package name, for example *gtk+-2.0* - :type package: string - :param uselib_store: if the test is successful, define HAVE\\_*name*. It is also used to define *conf.env.FLAGS_name* variables. - :type uselib_store: string - :param modversion: if provided, return the version of the given module and define *name*\\_VERSION - :type modversion: string - :param args: arguments to give to *package* when retrieving flags - :type args: list of string - :param variables: return the values of particular variables - :type variables: list of string - :param define_variable: additional variables to define (also in conf.env.PKG_CONFIG_DEFINES) - :type define_variable: dict(string: string) - """ - - path = Utils.to_list(kw['path']) - env = self.env.env or None - if kw.get('pkg_config_path'): - if not env: - env = dict(self.environ) - env['PKG_CONFIG_PATH'] = kw['pkg_config_path'] - - def define_it(): - define_name = kw['define_name'] - # by default, add HAVE_X to the config.h, else provide DEFINES_X for use=X - if kw.get('global_define', 1): - self.define(define_name, 1, False) - else: - self.env.append_unique('DEFINES_%s' % kw['uselib_store'], "%s=1" % define_name) - - if kw.get('add_have_to_env', 1): - self.env[define_name] = 1 - - # pkg-config version - if 'atleast_pkgconfig_version' in kw: - cmd = path + ['--atleast-pkgconfig-version=%s' % kw['atleast_pkgconfig_version']] - self.cmd_and_log(cmd, env=env) - return - - # single version for a module - if 'modversion' in kw: - version = self.cmd_and_log(path + ['--modversion', kw['modversion']], env=env).strip() - if not 'okmsg' in kw: - kw['okmsg'] = version - self.define(kw['define_name'], version) - return version - - lst = [] + path - - defi = kw.get('define_variable') - if not defi: - defi = self.env.PKG_CONFIG_DEFINES or {} - for key, val in defi.items(): - lst.append('--define-variable=%s=%s' % (key, val)) - - static = kw.get('force_static', False) - if 'args' in kw: - args = Utils.to_list(kw['args']) - if '--static' in args or '--static-libs' in args: - static = True - lst += args - - # tools like pkgconf expect the package argument after the -- ones -_- - lst.extend(Utils.to_list(kw['package'])) - - # retrieving variables of a module - if 'variables' in kw: - v_env = kw.get('env', self.env) - vars = Utils.to_list(kw['variables']) - for v in vars: - val = self.cmd_and_log(lst + ['--variable=' + v], env=env).strip() - var = '%s_%s' % (kw['uselib_store'], v) - v_env[var] = val - return - - # so we assume the command-line will output flags to be parsed afterwards - ret = self.cmd_and_log(lst, env=env) - - define_it() - self.parse_flags(ret, kw['uselib_store'], kw.get('env', self.env), force_static=static, posix=kw.get('posix')) - return ret - -@conf -def check_cfg(self, *k, **kw): - """ - Checks for configuration flags using a **-config**-like program (pkg-config, sdl-config, etc). - This wraps internal calls to :py:func:`waflib.Tools.c_config.validate_cfg` and :py:func:`waflib.Tools.c_config.exec_cfg` - - A few examples:: - - def configure(conf): - conf.load('compiler_c') - conf.check_cfg(package='glib-2.0', args='--libs --cflags') - conf.check_cfg(package='pango') - conf.check_cfg(package='pango', uselib_store='MYPANGO', args=['--cflags', '--libs']) - conf.check_cfg(package='pango', - args=['pango >= 0.1.0', 'pango < 9.9.9', '--cflags', '--libs'], - msg="Checking for 'pango 0.1.0'") - conf.check_cfg(path='sdl-config', args='--cflags --libs', package='', uselib_store='SDL') - conf.check_cfg(path='mpicc', args='--showme:compile --showme:link', - package='', uselib_store='OPEN_MPI', mandatory=False) - # variables - conf.check_cfg(package='gtk+-2.0', variables=['includedir', 'prefix'], uselib_store='FOO') - print(conf.env.FOO_includedir) - """ - self.validate_cfg(kw) - if 'msg' in kw: - self.start_msg(kw['msg'], **kw) - ret = None - try: - ret = self.exec_cfg(kw) - except self.errors.WafError as e: - if 'errmsg' in kw: - self.end_msg(kw['errmsg'], 'YELLOW', **kw) - if Logs.verbose > 1: - self.to_log('Command failure: %s' % e) - self.fatal('The configuration failed') - else: - if not ret: - ret = True - kw['success'] = ret - if 'okmsg' in kw: - self.end_msg(self.ret_msg(kw['okmsg'], kw), **kw) - - return ret - -def build_fun(bld): - """ - Build function that is used for running configuration tests with ``conf.check()`` - """ - if bld.kw['compile_filename']: - node = bld.srcnode.make_node(bld.kw['compile_filename']) - node.write(bld.kw['code']) - - o = bld(features=bld.kw['features'], source=bld.kw['compile_filename'], target='testprog') - - for k, v in bld.kw.items(): - setattr(o, k, v) - - if not bld.kw.get('quiet'): - bld.conf.to_log("==>\n%s\n<==" % bld.kw['code']) - -@conf -def validate_c(self, kw): - """ - Pre-checks the parameters that will be given to :py:func:`waflib.Configure.run_build` - - :param compiler: c or cxx (tries to guess what is best) - :type compiler: string - :param type: cprogram, cshlib, cstlib - not required if *features are given directly* - :type type: binary to create - :param feature: desired features for the task generator that will execute the test, for example ``cxx cxxstlib`` - :type feature: list of string - :param fragment: provide a piece of code for the test (default is to let the system create one) - :type fragment: string - :param uselib_store: define variables after the test is executed (IMPORTANT!) - :type uselib_store: string - :param use: parameters to use for building (just like the normal *use* keyword) - :type use: list of string - :param define_name: define to set when the check is over - :type define_name: string - :param execute: execute the resulting binary - :type execute: bool - :param define_ret: if execute is set to True, use the execution output in both the define and the return value - :type define_ret: bool - :param header_name: check for a particular header - :type header_name: string - :param auto_add_header_name: if header_name was set, add the headers in env.INCKEYS so the next tests will include these headers - :type auto_add_header_name: bool - """ - for x in ('type_name', 'field_name', 'function_name'): - if x in kw: - Logs.warn('Invalid argument %r in test' % x) - - if not 'build_fun' in kw: - kw['build_fun'] = build_fun - - if not 'env' in kw: - kw['env'] = self.env.derive() - env = kw['env'] - - if not 'compiler' in kw and not 'features' in kw: - kw['compiler'] = 'c' - if env.CXX_NAME and Task.classes.get('cxx'): - kw['compiler'] = 'cxx' - if not self.env.CXX: - self.fatal('a c++ compiler is required') - else: - if not self.env.CC: - self.fatal('a c compiler is required') - - if not 'compile_mode' in kw: - kw['compile_mode'] = 'c' - if 'cxx' in Utils.to_list(kw.get('features', [])) or kw.get('compiler') == 'cxx': - kw['compile_mode'] = 'cxx' - - if not 'type' in kw: - kw['type'] = 'cprogram' - - if not 'features' in kw: - if not 'header_name' in kw or kw.get('link_header_test', True): - kw['features'] = [kw['compile_mode'], kw['type']] # "c ccprogram" - else: - kw['features'] = [kw['compile_mode']] - else: - kw['features'] = Utils.to_list(kw['features']) - - if not 'compile_filename' in kw: - kw['compile_filename'] = 'test.c' + ((kw['compile_mode'] == 'cxx') and 'pp' or '') - - def to_header(dct): - if 'header_name' in dct: - dct = Utils.to_list(dct['header_name']) - return ''.join(['#include <%s>\n' % x for x in dct]) - return '' - - if 'framework_name' in kw: - # OSX, not sure this is used anywhere - fwkname = kw['framework_name'] - if not 'uselib_store' in kw: - kw['uselib_store'] = fwkname.upper() - if not kw.get('no_header'): - fwk = '%s/%s.h' % (fwkname, fwkname) - if kw.get('remove_dot_h'): - fwk = fwk[:-2] - val = kw.get('header_name', []) - kw['header_name'] = Utils.to_list(val) + [fwk] - kw['msg'] = 'Checking for framework %s' % fwkname - kw['framework'] = fwkname - - elif 'header_name' in kw: - if not 'msg' in kw: - kw['msg'] = 'Checking for header %s' % kw['header_name'] - - l = Utils.to_list(kw['header_name']) - assert len(l), 'list of headers in header_name is empty' - - kw['code'] = to_header(kw) + SNIP_EMPTY_PROGRAM - if not 'uselib_store' in kw: - kw['uselib_store'] = l[0].upper() - if not 'define_name' in kw: - kw['define_name'] = self.have_define(l[0]) - - if 'lib' in kw: - if not 'msg' in kw: - kw['msg'] = 'Checking for library %s' % kw['lib'] - if not 'uselib_store' in kw: - kw['uselib_store'] = kw['lib'].upper() - - if 'stlib' in kw: - if not 'msg' in kw: - kw['msg'] = 'Checking for static library %s' % kw['stlib'] - if not 'uselib_store' in kw: - kw['uselib_store'] = kw['stlib'].upper() - - if 'fragment' in kw: - # an additional code fragment may be provided to replace the predefined code - # in custom headers - kw['code'] = kw['fragment'] - if not 'msg' in kw: - kw['msg'] = 'Checking for code snippet' - if not 'errmsg' in kw: - kw['errmsg'] = 'no' - - for (flagsname,flagstype) in (('cxxflags','compiler'), ('cflags','compiler'), ('linkflags','linker')): - if flagsname in kw: - if not 'msg' in kw: - kw['msg'] = 'Checking for %s flags %s' % (flagstype, kw[flagsname]) - if not 'errmsg' in kw: - kw['errmsg'] = 'no' - - if not 'execute' in kw: - kw['execute'] = False - if kw['execute']: - kw['features'].append('test_exec') - kw['chmod'] = Utils.O755 - - if not 'errmsg' in kw: - kw['errmsg'] = 'not found' - - if not 'okmsg' in kw: - kw['okmsg'] = 'yes' - - if not 'code' in kw: - kw['code'] = SNIP_EMPTY_PROGRAM - - # if there are headers to append automatically to the next tests - if self.env[INCKEYS]: - kw['code'] = '\n'.join(['#include <%s>' % x for x in self.env[INCKEYS]]) + '\n' + kw['code'] - - # in case defines lead to very long command-lines - if kw.get('merge_config_header') or env.merge_config_header: - kw['code'] = '%s\n\n%s' % (self.get_config_header(), kw['code']) - env.DEFINES = [] # modify the copy - - if not kw.get('success'): - kw['success'] = None - - if 'define_name' in kw: - self.undefine(kw['define_name']) - if not 'msg' in kw: - self.fatal('missing "msg" in conf.check(...)') - -@conf -def post_check(self, *k, **kw): - """ - Sets the variables after a test executed in - :py:func:`waflib.Tools.c_config.check` was run successfully - """ - is_success = 0 - if kw['execute']: - if kw['success'] is not None: - if kw.get('define_ret'): - is_success = kw['success'] - else: - is_success = (kw['success'] == 0) - else: - is_success = (kw['success'] == 0) - - if kw.get('define_name'): - comment = kw.get('comment', '') - define_name = kw['define_name'] - if kw['execute'] and kw.get('define_ret') and isinstance(is_success, str): - if kw.get('global_define', 1): - self.define(define_name, is_success, quote=kw.get('quote', 1), comment=comment) - else: - if kw.get('quote', 1): - succ = '"%s"' % is_success - else: - succ = int(is_success) - val = '%s=%s' % (define_name, succ) - var = 'DEFINES_%s' % kw['uselib_store'] - self.env.append_value(var, val) - else: - if kw.get('global_define', 1): - self.define_cond(define_name, is_success, comment=comment) - else: - var = 'DEFINES_%s' % kw['uselib_store'] - self.env.append_value(var, '%s=%s' % (define_name, int(is_success))) - - # define conf.env.HAVE_X to 1 - if kw.get('add_have_to_env', 1): - if kw.get('uselib_store'): - self.env[self.have_define(kw['uselib_store'])] = 1 - elif kw['execute'] and kw.get('define_ret'): - self.env[define_name] = is_success - else: - self.env[define_name] = int(is_success) - - if 'header_name' in kw: - if kw.get('auto_add_header_name'): - self.env.append_value(INCKEYS, Utils.to_list(kw['header_name'])) - - if is_success and 'uselib_store' in kw: - from waflib.Tools import ccroot - # See get_uselib_vars in ccroot.py - _vars = set() - for x in kw['features']: - if x in ccroot.USELIB_VARS: - _vars |= ccroot.USELIB_VARS[x] - - for k in _vars: - x = k.lower() - if x in kw: - self.env.append_value(k + '_' + kw['uselib_store'], kw[x]) - return is_success - -@conf -def check(self, *k, **kw): - """ - Performs a configuration test by calling :py:func:`waflib.Configure.run_build`. - For the complete list of parameters, see :py:func:`waflib.Tools.c_config.validate_c`. - To force a specific compiler, pass ``compiler='c'`` or ``compiler='cxx'`` to the list of arguments - - Besides build targets, complete builds can be given through a build function. All files will - be written to a temporary directory:: - - def build(bld): - lib_node = bld.srcnode.make_node('libdir/liblc1.c') - lib_node.parent.mkdir() - lib_node.write('#include \\nint lib_func(void) { FILE *f = fopen("foo", "r");}\\n', 'w') - bld(features='c cshlib', source=[lib_node], linkflags=conf.env.EXTRA_LDFLAGS, target='liblc') - conf.check(build_fun=build, msg=msg) - """ - self.validate_c(kw) - self.start_msg(kw['msg'], **kw) - ret = None - try: - ret = self.run_build(*k, **kw) - except self.errors.ConfigurationError: - self.end_msg(kw['errmsg'], 'YELLOW', **kw) - if Logs.verbose > 1: - raise - else: - self.fatal('The configuration failed') - else: - kw['success'] = ret - - ret = self.post_check(*k, **kw) - if not ret: - self.end_msg(kw['errmsg'], 'YELLOW', **kw) - self.fatal('The configuration failed %r' % ret) - else: - self.end_msg(self.ret_msg(kw['okmsg'], kw), **kw) - return ret - -class test_exec(Task.Task): - """ - A task that runs programs after they are built. See :py:func:`waflib.Tools.c_config.test_exec_fun`. - """ - color = 'PINK' - def run(self): - cmd = [self.inputs[0].abspath()] + getattr(self.generator, 'test_args', []) - if getattr(self.generator, 'rpath', None): - if getattr(self.generator, 'define_ret', False): - self.generator.bld.retval = self.generator.bld.cmd_and_log(cmd) - else: - self.generator.bld.retval = self.generator.bld.exec_command(cmd) - else: - env = self.env.env or {} - env.update(dict(os.environ)) - for var in ('LD_LIBRARY_PATH', 'DYLD_LIBRARY_PATH', 'PATH'): - env[var] = self.inputs[0].parent.abspath() + os.path.pathsep + env.get(var, '') - if getattr(self.generator, 'define_ret', False): - self.generator.bld.retval = self.generator.bld.cmd_and_log(cmd, env=env) - else: - self.generator.bld.retval = self.generator.bld.exec_command(cmd, env=env) - -@feature('test_exec') -@after_method('apply_link') -def test_exec_fun(self): - """ - The feature **test_exec** is used to create a task that will to execute the binary - created (link task output) during the build. The exit status will be set - on the build context, so only one program may have the feature *test_exec*. - This is used by configuration tests:: - - def configure(conf): - conf.check(execute=True) - """ - self.create_task('test_exec', self.link_task.outputs[0]) - -@conf -def check_cxx(self, *k, **kw): - """ - Runs a test with a task generator of the form:: - - conf.check(features='cxx cxxprogram', ...) - """ - kw['compiler'] = 'cxx' - return self.check(*k, **kw) - -@conf -def check_cc(self, *k, **kw): - """ - Runs a test with a task generator of the form:: - - conf.check(features='c cprogram', ...) - """ - kw['compiler'] = 'c' - return self.check(*k, **kw) - -@conf -def set_define_comment(self, key, comment): - """ - Sets a comment that will appear in the configuration header - - :type key: string - :type comment: string - """ - coms = self.env.DEFINE_COMMENTS - if not coms: - coms = self.env.DEFINE_COMMENTS = {} - coms[key] = comment or '' - -@conf -def get_define_comment(self, key): - """ - Returns the comment associated to a define - - :type key: string - """ - coms = self.env.DEFINE_COMMENTS or {} - return coms.get(key, '') - -@conf -def define(self, key, val, quote=True, comment=''): - """ - Stores a single define and its state into ``conf.env.DEFINES``. The value is cast to an integer (0/1). - - :param key: define name - :type key: string - :param val: value - :type val: int or string - :param quote: enclose strings in quotes (yes by default) - :type quote: bool - """ - assert isinstance(key, str) - if not key: - return - if val is True: - val = 1 - elif val in (False, None): - val = 0 - - if isinstance(val, int) or isinstance(val, float): - s = '%s=%s' - else: - s = quote and '%s="%s"' or '%s=%s' - app = s % (key, str(val)) - - ban = key + '=' - lst = self.env.DEFINES - for x in lst: - if x.startswith(ban): - lst[lst.index(x)] = app - break - else: - self.env.append_value('DEFINES', app) - - self.env.append_unique(DEFKEYS, key) - self.set_define_comment(key, comment) - -@conf -def undefine(self, key, comment=''): - """ - Removes a global define from ``conf.env.DEFINES`` - - :param key: define name - :type key: string - """ - assert isinstance(key, str) - if not key: - return - ban = key + '=' - lst = [x for x in self.env.DEFINES if not x.startswith(ban)] - self.env.DEFINES = lst - self.env.append_unique(DEFKEYS, key) - self.set_define_comment(key, comment) - -@conf -def define_cond(self, key, val, comment=''): - """ - Conditionally defines a name:: - - def configure(conf): - conf.define_cond('A', True) - # equivalent to: - # if val: conf.define('A', 1) - # else: conf.undefine('A') - - :param key: define name - :type key: string - :param val: value - :type val: int or string - """ - assert isinstance(key, str) - if not key: - return - if val: - self.define(key, 1, comment=comment) - else: - self.undefine(key, comment=comment) - -@conf -def is_defined(self, key): - """ - Indicates whether a particular define is globally set in ``conf.env.DEFINES``. - - :param key: define name - :type key: string - :return: True if the define is set - :rtype: bool - """ - assert key and isinstance(key, str) - - ban = key + '=' - for x in self.env.DEFINES: - if x.startswith(ban): - return True - return False - -@conf -def get_define(self, key): - """ - Returns the value of an existing define, or None if not found - - :param key: define name - :type key: string - :rtype: string - """ - assert key and isinstance(key, str) - - ban = key + '=' - for x in self.env.DEFINES: - if x.startswith(ban): - return x[len(ban):] - return None - -@conf -def have_define(self, key): - """ - Returns a variable suitable for command-line or header use by removing invalid characters - and prefixing it with ``HAVE_`` - - :param key: define name - :type key: string - :return: the input key prefixed by *HAVE_* and substitute any invalid characters. - :rtype: string - """ - return (self.env.HAVE_PAT or 'HAVE_%s') % Utils.quote_define_name(key) - -@conf -def write_config_header(self, configfile='', guard='', top=False, defines=True, headers=False, remove=True, define_prefix=''): - """ - Writes a configuration header containing defines and includes:: - - def configure(cnf): - cnf.define('A', 1) - cnf.write_config_header('config.h') - - This function only adds include guards (if necessary), consult - :py:func:`waflib.Tools.c_config.get_config_header` for details on the body. - - :param configfile: path to the file to create (relative or absolute) - :type configfile: string - :param guard: include guard name to add, by default it is computed from the file name - :type guard: string - :param top: write the configuration header from the build directory (default is from the current path) - :type top: bool - :param defines: add the defines (yes by default) - :type defines: bool - :param headers: add #include in the file - :type headers: bool - :param remove: remove the defines after they are added (yes by default, works like in autoconf) - :type remove: bool - :type define_prefix: string - :param define_prefix: prefix all the defines in the file with a particular prefix - """ - if not configfile: - configfile = WAF_CONFIG_H - waf_guard = guard or 'W_%s_WAF' % Utils.quote_define_name(configfile) - - node = top and self.bldnode or self.path.get_bld() - node = node.make_node(configfile) - node.parent.mkdir() - - lst = ['/* WARNING! All changes made to this file will be lost! */\n'] - lst.append('#ifndef %s\n#define %s\n' % (waf_guard, waf_guard)) - lst.append(self.get_config_header(defines, headers, define_prefix=define_prefix)) - lst.append('\n#endif /* %s */\n' % waf_guard) - - node.write('\n'.join(lst)) - - # config files must not be removed on "waf clean" - self.env.append_unique(Build.CFG_FILES, [node.abspath()]) - - if remove: - for key in self.env[DEFKEYS]: - self.undefine(key) - self.env[DEFKEYS] = [] - -@conf -def get_config_header(self, defines=True, headers=False, define_prefix=''): - """ - Creates the contents of a ``config.h`` file from the defines and includes - set in conf.env.define_key / conf.env.include_key. No include guards are added. - - A prelude will be added from the variable env.WAF_CONFIG_H_PRELUDE if provided. This - can be used to insert complex macros or include guards:: - - def configure(conf): - conf.env.WAF_CONFIG_H_PRELUDE = '#include \\n' - conf.write_config_header('config.h') - - :param defines: write the defines values - :type defines: bool - :param headers: write include entries for each element in self.env.INCKEYS - :type headers: bool - :type define_prefix: string - :param define_prefix: prefix all the defines with a particular prefix - :return: the contents of a ``config.h`` file - :rtype: string - """ - lst = [] - - if self.env.WAF_CONFIG_H_PRELUDE: - lst.append(self.env.WAF_CONFIG_H_PRELUDE) - - if headers: - for x in self.env[INCKEYS]: - lst.append('#include <%s>' % x) - - if defines: - tbl = {} - for k in self.env.DEFINES: - a, _, b = k.partition('=') - tbl[a] = b - - for k in self.env[DEFKEYS]: - caption = self.get_define_comment(k) - if caption: - caption = ' /* %s */' % caption - try: - txt = '#define %s%s %s%s' % (define_prefix, k, tbl[k], caption) - except KeyError: - txt = '/* #undef %s%s */%s' % (define_prefix, k, caption) - lst.append(txt) - return "\n".join(lst) - -@conf -def cc_add_flags(conf): - """ - Adds CFLAGS / CPPFLAGS from os.environ to conf.env - """ - conf.add_os_flags('CPPFLAGS', dup=False) - conf.add_os_flags('CFLAGS', dup=False) - -@conf -def cxx_add_flags(conf): - """ - Adds CXXFLAGS / CPPFLAGS from os.environ to conf.env - """ - conf.add_os_flags('CPPFLAGS', dup=False) - conf.add_os_flags('CXXFLAGS', dup=False) - -@conf -def link_add_flags(conf): - """ - Adds LINKFLAGS / LDFLAGS from os.environ to conf.env - """ - conf.add_os_flags('LINKFLAGS', dup=False) - conf.add_os_flags('LDFLAGS', dup=False) - -@conf -def cc_load_tools(conf): - """ - Loads the Waf c extensions - """ - if not conf.env.DEST_OS: - conf.env.DEST_OS = Utils.unversioned_sys_platform() - conf.load('c') - -@conf -def cxx_load_tools(conf): - """ - Loads the Waf c++ extensions - """ - if not conf.env.DEST_OS: - conf.env.DEST_OS = Utils.unversioned_sys_platform() - conf.load('cxx') - -@conf -def get_cc_version(conf, cc, gcc=False, icc=False, clang=False): - """ - Runs the preprocessor to determine the gcc/icc/clang version - - The variables CC_VERSION, DEST_OS, DEST_BINFMT and DEST_CPU will be set in *conf.env* - - :raise: :py:class:`waflib.Errors.ConfigurationError` - """ - cmd = cc + ['-dM', '-E', '-'] - env = conf.env.env or None - try: - out, err = conf.cmd_and_log(cmd, output=0, input='\n'.encode(), env=env) - except Errors.WafError: - conf.fatal('Could not determine the compiler version %r' % cmd) - - if gcc: - if out.find('__INTEL_COMPILER') >= 0: - conf.fatal('The intel compiler pretends to be gcc') - if out.find('__GNUC__') < 0 and out.find('__clang__') < 0: - conf.fatal('Could not determine the compiler type') - - if icc and out.find('__INTEL_COMPILER') < 0: - conf.fatal('Not icc/icpc') - - if clang and out.find('__clang__') < 0: - conf.fatal('Not clang/clang++') - if not clang and out.find('__clang__') >= 0: - conf.fatal('Could not find gcc/g++ (only Clang), if renamed try eg: CC=gcc48 CXX=g++48 waf configure') - - k = {} - if icc or gcc or clang: - out = out.splitlines() - for line in out: - lst = shlex.split(line) - if len(lst)>2: - key = lst[1] - val = lst[2] - k[key] = val - - def isD(var): - return var in k - - # Some documentation is available at http://predef.sourceforge.net - # The names given to DEST_OS must match what Utils.unversioned_sys_platform() returns. - if not conf.env.DEST_OS: - conf.env.DEST_OS = '' - for i in MACRO_TO_DESTOS: - if isD(i): - conf.env.DEST_OS = MACRO_TO_DESTOS[i] - break - else: - if isD('__APPLE__') and isD('__MACH__'): - conf.env.DEST_OS = 'darwin' - elif isD('__unix__'): # unix must be tested last as it's a generic fallback - conf.env.DEST_OS = 'generic' - - if isD('__ELF__'): - conf.env.DEST_BINFMT = 'elf' - elif isD('__WINNT__') or isD('__CYGWIN__') or isD('_WIN32'): - conf.env.DEST_BINFMT = 'pe' - if not conf.env.IMPLIBDIR: - conf.env.IMPLIBDIR = conf.env.LIBDIR # for .lib or .dll.a files - conf.env.LIBDIR = conf.env.BINDIR - elif isD('__APPLE__'): - conf.env.DEST_BINFMT = 'mac-o' - - if not conf.env.DEST_BINFMT: - # Infer the binary format from the os name. - conf.env.DEST_BINFMT = Utils.destos_to_binfmt(conf.env.DEST_OS) - - for i in MACRO_TO_DEST_CPU: - if isD(i): - conf.env.DEST_CPU = MACRO_TO_DEST_CPU[i] - break - - Logs.debug('ccroot: dest platform: ' + ' '.join([conf.env[x] or '?' for x in ('DEST_OS', 'DEST_BINFMT', 'DEST_CPU')])) - if icc: - ver = k['__INTEL_COMPILER'] - conf.env.CC_VERSION = (ver[:-2], ver[-2], ver[-1]) - else: - if isD('__clang__') and isD('__clang_major__'): - conf.env.CC_VERSION = (k['__clang_major__'], k['__clang_minor__'], k['__clang_patchlevel__']) - else: - # older clang versions and gcc - conf.env.CC_VERSION = (k['__GNUC__'], k['__GNUC_MINOR__'], k.get('__GNUC_PATCHLEVEL__', '0')) - return k - -@conf -def get_xlc_version(conf, cc): - """ - Returns the Aix compiler version - - :raise: :py:class:`waflib.Errors.ConfigurationError` - """ - cmd = cc + ['-qversion'] - try: - out, err = conf.cmd_and_log(cmd, output=0) - except Errors.WafError: - conf.fatal('Could not find xlc %r' % cmd) - - # the intention is to catch the 8.0 in "IBM XL C/C++ Enterprise Edition V8.0 for AIX..." - for v in (r"IBM XL C/C\+\+.* V(?P\d*)\.(?P\d*)",): - version_re = re.compile(v, re.I).search - match = version_re(out or err) - if match: - k = match.groupdict() - conf.env.CC_VERSION = (k['major'], k['minor']) - break - else: - conf.fatal('Could not determine the XLC version.') - -@conf -def get_suncc_version(conf, cc): - """ - Returns the Sun compiler version - - :raise: :py:class:`waflib.Errors.ConfigurationError` - """ - cmd = cc + ['-V'] - try: - out, err = conf.cmd_and_log(cmd, output=0) - except Errors.WafError as e: - # Older versions of the compiler exit with non-zero status when reporting their version - if not (hasattr(e, 'returncode') and hasattr(e, 'stdout') and hasattr(e, 'stderr')): - conf.fatal('Could not find suncc %r' % cmd) - out = e.stdout - err = e.stderr - - version = (out or err) - version = version.splitlines()[0] - - # cc: Sun C 5.10 SunOS_i386 2009/06/03 - # cc: Studio 12.5 Sun C++ 5.14 SunOS_sparc Beta 2015/11/17 - # cc: WorkShop Compilers 5.0 98/12/15 C 5.0 - version_re = re.compile(r'cc: (studio.*?|\s+)?(sun\s+(c\+\+|c)|(WorkShop\s+Compilers))?\s+(?P\d*)\.(?P\d*)', re.I).search - match = version_re(version) - if match: - k = match.groupdict() - conf.env.CC_VERSION = (k['major'], k['minor']) - else: - conf.fatal('Could not determine the suncc version.') - -# ============ the --as-needed flag should added during the configuration, not at runtime ========= - -@conf -def add_as_needed(self): - """ - Adds ``--as-needed`` to the *LINKFLAGS* - On some platforms, it is a default flag. In some cases (e.g., in NS-3) it is necessary to explicitly disable this feature with `-Wl,--no-as-needed` flag. - """ - if self.env.DEST_BINFMT == 'elf' and 'gcc' in (self.env.CXX_NAME, self.env.CC_NAME): - self.env.append_unique('LINKFLAGS', '-Wl,--as-needed') - -# ============ parallel configuration - -class cfgtask(Task.Task): - """ - A task that executes build configuration tests (calls conf.check) - - Make sure to use locks if concurrent access to the same conf.env data is necessary. - """ - def __init__(self, *k, **kw): - Task.Task.__init__(self, *k, **kw) - self.run_after = set() - - def display(self): - return '' - - def runnable_status(self): - for x in self.run_after: - if not x.hasrun: - return Task.ASK_LATER - return Task.RUN_ME - - def uid(self): - return Utils.SIG_NIL - - def signature(self): - return Utils.SIG_NIL - - def run(self): - conf = self.conf - bld = Build.BuildContext(top_dir=conf.srcnode.abspath(), out_dir=conf.bldnode.abspath()) - bld.env = conf.env - bld.init_dirs() - bld.in_msg = 1 # suppress top-level start_msg - bld.logger = self.logger - bld.multicheck_task = self - args = self.args - try: - if 'func' in args: - bld.test(build_fun=args['func'], - msg=args.get('msg', ''), - okmsg=args.get('okmsg', ''), - errmsg=args.get('errmsg', ''), - ) - else: - args['multicheck_mandatory'] = args.get('mandatory', True) - args['mandatory'] = True - try: - bld.check(**args) - finally: - args['mandatory'] = args['multicheck_mandatory'] - except Exception: - return 1 - - def process(self): - Task.Task.process(self) - if 'msg' in self.args: - with self.generator.bld.multicheck_lock: - self.conf.start_msg(self.args['msg']) - if self.hasrun == Task.NOT_RUN: - self.conf.end_msg('test cancelled', 'YELLOW') - elif self.hasrun != Task.SUCCESS: - self.conf.end_msg(self.args.get('errmsg', 'no'), 'YELLOW') - else: - self.conf.end_msg(self.args.get('okmsg', 'yes'), 'GREEN') - -@conf -def multicheck(self, *k, **kw): - """ - Runs configuration tests in parallel; results are printed sequentially at the end of the build - but each test must provide its own msg value to display a line:: - - def test_build(ctx): - ctx.in_msg = True # suppress console outputs - ctx.check_large_file(mandatory=False) - - conf.multicheck( - {'header_name':'stdio.h', 'msg':'... stdio', 'uselib_store':'STDIO', 'global_define':False}, - {'header_name':'xyztabcd.h', 'msg':'... optional xyztabcd.h', 'mandatory': False}, - {'header_name':'stdlib.h', 'msg':'... stdlib', 'okmsg': 'aye', 'errmsg': 'nope'}, - {'func': test_build, 'msg':'... testing an arbitrary build function', 'okmsg':'ok'}, - msg = 'Checking for headers in parallel', - mandatory = True, # mandatory tests raise an error at the end - run_all_tests = True, # try running all tests - ) - - The configuration tests may modify the values in conf.env in any order, and the define - values can affect configuration tests being executed. It is hence recommended - to provide `uselib_store` values with `global_define=False` to prevent such issues. - """ - self.start_msg(kw.get('msg', 'Executing %d configuration tests' % len(k)), **kw) - - # Force a copy so that threads append to the same list at least - # no order is guaranteed, but the values should not disappear at least - for var in ('DEFINES', DEFKEYS): - self.env.append_value(var, []) - self.env.DEFINE_COMMENTS = self.env.DEFINE_COMMENTS or {} - - # define a task object that will execute our tests - class par(object): - def __init__(self): - self.keep = False - self.task_sigs = {} - self.progress_bar = 0 - def total(self): - return len(tasks) - def to_log(self, *k, **kw): - return - - bld = par() - bld.keep = kw.get('run_all_tests', True) - bld.imp_sigs = {} - tasks = [] - - id_to_task = {} - for dct in k: - x = Task.classes['cfgtask'](bld=bld, env=None) - tasks.append(x) - x.args = dct - x.bld = bld - x.conf = self - x.args = dct - - # bind a logger that will keep the info in memory - x.logger = Logs.make_mem_logger(str(id(x)), self.logger) - - if 'id' in dct: - id_to_task[dct['id']] = x - - # second pass to set dependencies with after_test/before_test - for x in tasks: - for key in Utils.to_list(x.args.get('before_tests', [])): - tsk = id_to_task[key] - if not tsk: - raise ValueError('No test named %r' % key) - tsk.run_after.add(x) - for key in Utils.to_list(x.args.get('after_tests', [])): - tsk = id_to_task[key] - if not tsk: - raise ValueError('No test named %r' % key) - x.run_after.add(tsk) - - def it(): - yield tasks - while 1: - yield [] - bld.producer = p = Runner.Parallel(bld, Options.options.jobs) - bld.multicheck_lock = Utils.threading.Lock() - p.biter = it() - - self.end_msg('started') - p.start() - - # flush the logs in order into the config.log - for x in tasks: - x.logger.memhandler.flush() - - self.start_msg('-> processing test results') - if p.error: - for x in p.error: - if getattr(x, 'err_msg', None): - self.to_log(x.err_msg) - self.end_msg('fail', color='RED') - raise Errors.WafError('There is an error in the library, read config.log for more information') - - failure_count = 0 - for x in tasks: - if x.hasrun not in (Task.SUCCESS, Task.NOT_RUN): - failure_count += 1 - - if failure_count: - self.end_msg(kw.get('errmsg', '%s test failed' % failure_count), color='YELLOW', **kw) - else: - self.end_msg('all ok', **kw) - - for x in tasks: - if x.hasrun != Task.SUCCESS: - if x.args.get('mandatory', True): - self.fatal(kw.get('fatalmsg') or 'One of the tests has failed, read config.log for more information') - -@conf -def check_gcc_o_space(self, mode='c'): - if int(self.env.CC_VERSION[0]) > 4: - # this is for old compilers - return - self.env.stash() - if mode == 'c': - self.env.CCLNK_TGT_F = ['-o', ''] - elif mode == 'cxx': - self.env.CXXLNK_TGT_F = ['-o', ''] - features = '%s %sshlib' % (mode, mode) - try: - self.check(msg='Checking if the -o link must be split from arguments', fragment=SNIP_EMPTY_PROGRAM, features=features) - except self.errors.ConfigurationError: - self.env.revert() - else: - self.env.commit() - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/c_osx.py b/ldb-2.0.8/third_party/waf/waflib/Tools/c_osx.py deleted file mode 100644 index f70b128..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/c_osx.py +++ /dev/null @@ -1,193 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy 2008-2018 (ita) - -""" -MacOSX related tools -""" - -import os, shutil, platform -from waflib import Task, Utils -from waflib.TaskGen import taskgen_method, feature, after_method, before_method - -app_info = ''' - - - - - CFBundlePackageType - APPL - CFBundleGetInfoString - Created by Waf - CFBundleSignature - ???? - NOTE - THIS IS A GENERATED FILE, DO NOT MODIFY - CFBundleExecutable - {app_name} - - -''' -""" -plist template -""" - -@feature('c', 'cxx') -def set_macosx_deployment_target(self): - """ - see WAF issue 285 and also and also http://trac.macports.org/ticket/17059 - """ - if self.env.MACOSX_DEPLOYMENT_TARGET: - os.environ['MACOSX_DEPLOYMENT_TARGET'] = self.env.MACOSX_DEPLOYMENT_TARGET - elif 'MACOSX_DEPLOYMENT_TARGET' not in os.environ: - if Utils.unversioned_sys_platform() == 'darwin': - os.environ['MACOSX_DEPLOYMENT_TARGET'] = '.'.join(platform.mac_ver()[0].split('.')[:2]) - -@taskgen_method -def create_bundle_dirs(self, name, out): - """ - Creates bundle folders, used by :py:func:`create_task_macplist` and :py:func:`create_task_macapp` - """ - dir = out.parent.find_or_declare(name) - dir.mkdir() - macos = dir.find_or_declare(['Contents', 'MacOS']) - macos.mkdir() - return dir - -def bundle_name_for_output(out): - name = out.name - k = name.rfind('.') - if k >= 0: - name = name[:k] + '.app' - else: - name = name + '.app' - return name - -@feature('cprogram', 'cxxprogram') -@after_method('apply_link') -def create_task_macapp(self): - """ - To compile an executable into a Mac application (a .app), set its *mac_app* attribute:: - - def build(bld): - bld.shlib(source='a.c', target='foo', mac_app=True) - - To force *all* executables to be transformed into Mac applications:: - - def build(bld): - bld.env.MACAPP = True - bld.shlib(source='a.c', target='foo') - """ - if self.env.MACAPP or getattr(self, 'mac_app', False): - out = self.link_task.outputs[0] - - name = bundle_name_for_output(out) - dir = self.create_bundle_dirs(name, out) - - n1 = dir.find_or_declare(['Contents', 'MacOS', out.name]) - - self.apptask = self.create_task('macapp', self.link_task.outputs, n1) - inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Contents/MacOS/' % name - self.add_install_files(install_to=inst_to, install_from=n1, chmod=Utils.O755) - - if getattr(self, 'mac_files', None): - # this only accepts files; they will be installed as seen from mac_files_root - mac_files_root = getattr(self, 'mac_files_root', None) - if isinstance(mac_files_root, str): - mac_files_root = self.path.find_node(mac_files_root) - if not mac_files_root: - self.bld.fatal('Invalid mac_files_root %r' % self.mac_files_root) - res_dir = n1.parent.parent.make_node('Resources') - inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Resources' % name - for node in self.to_nodes(self.mac_files): - relpath = node.path_from(mac_files_root or node.parent) - self.create_task('macapp', node, res_dir.make_node(relpath)) - self.add_install_as(install_to=os.path.join(inst_to, relpath), install_from=node) - - if getattr(self.bld, 'is_install', None): - # disable regular binary installation - self.install_task.hasrun = Task.SKIP_ME - -@feature('cprogram', 'cxxprogram') -@after_method('apply_link') -def create_task_macplist(self): - """ - Creates a :py:class:`waflib.Tools.c_osx.macplist` instance. - """ - if self.env.MACAPP or getattr(self, 'mac_app', False): - out = self.link_task.outputs[0] - - name = bundle_name_for_output(out) - - dir = self.create_bundle_dirs(name, out) - n1 = dir.find_or_declare(['Contents', 'Info.plist']) - self.plisttask = plisttask = self.create_task('macplist', [], n1) - plisttask.context = { - 'app_name': self.link_task.outputs[0].name, - 'env': self.env - } - - plist_ctx = getattr(self, 'plist_context', None) - if (plist_ctx): - plisttask.context.update(plist_ctx) - - if getattr(self, 'mac_plist', False): - node = self.path.find_resource(self.mac_plist) - if node: - plisttask.inputs.append(node) - else: - plisttask.code = self.mac_plist - else: - plisttask.code = app_info - - inst_to = getattr(self, 'install_path', '/Applications') + '/%s/Contents/' % name - self.add_install_files(install_to=inst_to, install_from=n1) - -@feature('cshlib', 'cxxshlib') -@before_method('apply_link', 'propagate_uselib_vars') -def apply_bundle(self): - """ - To make a bundled shared library (a ``.bundle``), set the *mac_bundle* attribute:: - - def build(bld): - bld.shlib(source='a.c', target='foo', mac_bundle = True) - - To force *all* executables to be transformed into bundles:: - - def build(bld): - bld.env.MACBUNDLE = True - bld.shlib(source='a.c', target='foo') - """ - if self.env.MACBUNDLE or getattr(self, 'mac_bundle', False): - self.env.LINKFLAGS_cshlib = self.env.LINKFLAGS_cxxshlib = [] # disable the '-dynamiclib' flag - self.env.cshlib_PATTERN = self.env.cxxshlib_PATTERN = self.env.macbundle_PATTERN - use = self.use = self.to_list(getattr(self, 'use', [])) - if not 'MACBUNDLE' in use: - use.append('MACBUNDLE') - -app_dirs = ['Contents', 'Contents/MacOS', 'Contents/Resources'] - -class macapp(Task.Task): - """ - Creates mac applications - """ - color = 'PINK' - def run(self): - self.outputs[0].parent.mkdir() - shutil.copy2(self.inputs[0].srcpath(), self.outputs[0].abspath()) - -class macplist(Task.Task): - """ - Creates plist files - """ - color = 'PINK' - ext_in = ['.bin'] - def run(self): - if getattr(self, 'code', None): - txt = self.code - else: - txt = self.inputs[0].read() - context = getattr(self, 'context', {}) - txt = txt.format(**context) - self.outputs[0].write(txt) - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/c_preproc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/c_preproc.py deleted file mode 100644 index 68e5f5a..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/c_preproc.py +++ /dev/null @@ -1,1091 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2006-2018 (ita) - -""" -C/C++ preprocessor for finding dependencies - -Reasons for using the Waf preprocessor by default - -#. Some c/c++ extensions (Qt) require a custom preprocessor for obtaining the dependencies (.moc files) -#. Not all compilers provide .d files for obtaining the dependencies (portability) -#. A naive file scanner will not catch the constructs such as "#include foo()" -#. A naive file scanner will catch unnecessary dependencies (change an unused header -> recompile everything) - -Regarding the speed concerns: - -* the preprocessing is performed only when files must be compiled -* the macros are evaluated only for #if/#elif/#include -* system headers are not scanned by default - -Now if you do not want the Waf preprocessor, the tool +gccdeps* uses the .d files produced -during the compilation to track the dependencies (useful when used with the boost libraries). -It only works with gcc >= 4.4 though. - -A dumb preprocessor is also available in the tool *c_dumbpreproc* -""" -# TODO: more varargs, pragma once - -import re, string, traceback -from waflib import Logs, Utils, Errors - -class PreprocError(Errors.WafError): - pass - -FILE_CACHE_SIZE = 100000 -LINE_CACHE_SIZE = 100000 - -POPFILE = '-' -"Constant representing a special token used in :py:meth:`waflib.Tools.c_preproc.c_parser.start` iteration to switch to a header read previously" - -recursion_limit = 150 -"Limit on the amount of files to read in the dependency scanner" - -go_absolute = False -"Set to True to track headers on files in /usr/include, else absolute paths are ignored (but it becomes very slow)" - -standard_includes = ['/usr/local/include', '/usr/include'] -if Utils.is_win32: - standard_includes = [] - -use_trigraphs = 0 -"""Apply trigraph rules (False by default)""" - -# obsolete, do not use -strict_quotes = 0 - -g_optrans = { -'not':'!', -'not_eq':'!', -'and':'&&', -'and_eq':'&=', -'or':'||', -'or_eq':'|=', -'xor':'^', -'xor_eq':'^=', -'bitand':'&', -'bitor':'|', -'compl':'~', -} -"""Operators such as and/or/xor for c++. Set an empty dict to disable.""" - -# ignore #warning and #error -re_lines = re.compile( - '^[ \t]*(?:#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*)\r*$', - re.IGNORECASE | re.MULTILINE) -"""Match #include lines""" - -re_mac = re.compile(r"^[a-zA-Z_]\w*") -"""Match macro definitions""" - -re_fun = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*[(]') -"""Match macro functions""" - -re_pragma_once = re.compile(r'^\s*once\s*', re.IGNORECASE) -"""Match #pragma once statements""" - -re_nl = re.compile('\\\\\r*\n', re.MULTILINE) -"""Match newlines""" - -re_cpp = re.compile(r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', re.DOTALL | re.MULTILINE ) -"""Filter C/C++ comments""" - -trig_def = [('??'+a, b) for a, b in zip("=-/!'()<>", r'#~\|^[]{}')] -"""Trigraph definitions""" - -chr_esc = {'0':0, 'a':7, 'b':8, 't':9, 'n':10, 'f':11, 'v':12, 'r':13, '\\':92, "'":39} -"""Escape characters""" - -NUM = 'i' -"""Number token""" - -OP = 'O' -"""Operator token""" - -IDENT = 'T' -"""Identifier token""" - -STR = 's' -"""String token""" - -CHAR = 'c' -"""Character token""" - -tok_types = [NUM, STR, IDENT, OP] -"""Token types""" - -exp_types = [ - r"""0[xX](?P[a-fA-F0-9]+)(?P[uUlL]*)|L*?'(?P(\\.|[^\\'])+)'|(?P\d+)[Ee](?P[+-]*?\d+)(?P[fFlL]*)|(?P\d*\.\d+)([Ee](?P[+-]*?\d+))?(?P[fFlL]*)|(?P\d+\.\d*)([Ee](?P[+-]*?\d+))?(?P[fFlL]*)|(?P0*)(?P\d+)(?P[uUlL]*)""", - r'L?"([^"\\]|\\.)*"', - r'[a-zA-Z_]\w*', - r'%:%:|<<=|>>=|\.\.\.|<<|<%|<:|<=|>>|>=|\+\+|\+=|--|->|-=|\*=|/=|%:|%=|%>|==|&&|&=|\|\||\|=|\^=|:>|!=|##|[\(\)\{\}\[\]<>\?\|\^\*\+&=:!#;,%/\-\?\~\.]', -] -"""Expression types""" - -re_clexer = re.compile('|'.join(["(?P<%s>%s)" % (name, part) for name, part in zip(tok_types, exp_types)]), re.M) -"""Match expressions into tokens""" - -accepted = 'a' -"""Parser state is *accepted*""" - -ignored = 'i' -"""Parser state is *ignored*, for example preprocessor lines in an #if 0 block""" - -undefined = 'u' -"""Parser state is *undefined* at the moment""" - -skipped = 's' -"""Parser state is *skipped*, for example preprocessor lines in a #elif 0 block""" - -def repl(m): - """Replace function used with :py:attr:`waflib.Tools.c_preproc.re_cpp`""" - s = m.group() - if s[0] == '/': - return ' ' - return s - -prec = {} -""" -Operator precedence rules required for parsing expressions of the form:: - - #if 1 && 2 != 0 -""" -ops = ['* / %', '+ -', '<< >>', '< <= >= >', '== !=', '& | ^', '&& ||', ','] -for x, syms in enumerate(ops): - for u in syms.split(): - prec[u] = x - -def reduce_nums(val_1, val_2, val_op): - """ - Apply arithmetic rules to compute a result - - :param val1: input parameter - :type val1: int or string - :param val2: input parameter - :type val2: int or string - :param val_op: C operator in *+*, */*, *-*, etc - :type val_op: string - :rtype: int - """ - #print val_1, val_2, val_op - - # now perform the operation, make certain a and b are numeric - try: - a = 0 + val_1 - except TypeError: - a = int(val_1) - try: - b = 0 + val_2 - except TypeError: - b = int(val_2) - - d = val_op - if d == '%': - c = a % b - elif d=='+': - c = a + b - elif d=='-': - c = a - b - elif d=='*': - c = a * b - elif d=='/': - c = a / b - elif d=='^': - c = a ^ b - elif d=='==': - c = int(a == b) - elif d=='|' or d == 'bitor': - c = a | b - elif d=='||' or d == 'or' : - c = int(a or b) - elif d=='&' or d == 'bitand': - c = a & b - elif d=='&&' or d == 'and': - c = int(a and b) - elif d=='!=' or d == 'not_eq': - c = int(a != b) - elif d=='^' or d == 'xor': - c = int(a^b) - elif d=='<=': - c = int(a <= b) - elif d=='<': - c = int(a < b) - elif d=='>': - c = int(a > b) - elif d=='>=': - c = int(a >= b) - elif d=='<<': - c = a << b - elif d=='>>': - c = a >> b - else: - c = 0 - return c - -def get_num(lst): - """ - Try to obtain a number from a list of tokens. The token types are defined in :py:attr:`waflib.Tools.ccroot.tok_types`. - - :param lst: list of preprocessor tokens - :type lst: list of tuple (tokentype, value) - :return: a pair containing the number and the rest of the list - :rtype: tuple(value, list) - """ - if not lst: - raise PreprocError('empty list for get_num') - (p, v) = lst[0] - if p == OP: - if v == '(': - count_par = 1 - i = 1 - while i < len(lst): - (p, v) = lst[i] - - if p == OP: - if v == ')': - count_par -= 1 - if count_par == 0: - break - elif v == '(': - count_par += 1 - i += 1 - else: - raise PreprocError('rparen expected %r' % lst) - - (num, _) = get_term(lst[1:i]) - return (num, lst[i+1:]) - - elif v == '+': - return get_num(lst[1:]) - elif v == '-': - num, lst = get_num(lst[1:]) - return (reduce_nums('-1', num, '*'), lst) - elif v == '!': - num, lst = get_num(lst[1:]) - return (int(not int(num)), lst) - elif v == '~': - num, lst = get_num(lst[1:]) - return (~ int(num), lst) - else: - raise PreprocError('Invalid op token %r for get_num' % lst) - elif p == NUM: - return v, lst[1:] - elif p == IDENT: - # all macros should have been replaced, remaining identifiers eval to 0 - return 0, lst[1:] - else: - raise PreprocError('Invalid token %r for get_num' % lst) - -def get_term(lst): - """ - Evaluate an expression recursively, for example:: - - 1+1+1 -> 2+1 -> 3 - - :param lst: list of tokens - :type lst: list of tuple(token, value) - :return: the value and the remaining tokens - :rtype: value, list - """ - - if not lst: - raise PreprocError('empty list for get_term') - num, lst = get_num(lst) - if not lst: - return (num, []) - (p, v) = lst[0] - if p == OP: - if v == ',': - # skip - return get_term(lst[1:]) - elif v == '?': - count_par = 0 - i = 1 - while i < len(lst): - (p, v) = lst[i] - - if p == OP: - if v == ')': - count_par -= 1 - elif v == '(': - count_par += 1 - elif v == ':': - if count_par == 0: - break - i += 1 - else: - raise PreprocError('rparen expected %r' % lst) - - if int(num): - return get_term(lst[1:i]) - else: - return get_term(lst[i+1:]) - - else: - num2, lst = get_num(lst[1:]) - - if not lst: - # no more tokens to process - num2 = reduce_nums(num, num2, v) - return get_term([(NUM, num2)] + lst) - - # operator precedence - p2, v2 = lst[0] - if p2 != OP: - raise PreprocError('op expected %r' % lst) - - if prec[v2] >= prec[v]: - num2 = reduce_nums(num, num2, v) - return get_term([(NUM, num2)] + lst) - else: - num3, lst = get_num(lst[1:]) - num3 = reduce_nums(num2, num3, v2) - return get_term([(NUM, num), (p, v), (NUM, num3)] + lst) - - - raise PreprocError('cannot reduce %r' % lst) - -def reduce_eval(lst): - """ - Take a list of tokens and output true or false for #if/#elif conditions. - - :param lst: a list of tokens - :type lst: list of tuple(token, value) - :return: a token - :rtype: tuple(NUM, int) - """ - num, lst = get_term(lst) - return (NUM, num) - -def stringize(lst): - """ - Merge a list of tokens into a string - - :param lst: a list of tokens - :type lst: list of tuple(token, value) - :rtype: string - """ - lst = [str(v2) for (p2, v2) in lst] - return "".join(lst) - -def paste_tokens(t1, t2): - """ - Token pasting works between identifiers, particular operators, and identifiers and numbers:: - - a ## b -> ab - > ## = -> >= - a ## 2 -> a2 - - :param t1: token - :type t1: tuple(type, value) - :param t2: token - :type t2: tuple(type, value) - """ - p1 = None - if t1[0] == OP and t2[0] == OP: - p1 = OP - elif t1[0] == IDENT and (t2[0] == IDENT or t2[0] == NUM): - p1 = IDENT - elif t1[0] == NUM and t2[0] == NUM: - p1 = NUM - if not p1: - raise PreprocError('tokens do not make a valid paste %r and %r' % (t1, t2)) - return (p1, t1[1] + t2[1]) - -def reduce_tokens(lst, defs, ban=[]): - """ - Replace the tokens in lst, using the macros provided in defs, and a list of macros that cannot be re-applied - - :param lst: list of tokens - :type lst: list of tuple(token, value) - :param defs: macro definitions - :type defs: dict - :param ban: macros that cannot be substituted (recursion is not allowed) - :type ban: list of string - :return: the new list of tokens - :rtype: value, list - """ - - i = 0 - while i < len(lst): - (p, v) = lst[i] - - if p == IDENT and v == "defined": - del lst[i] - if i < len(lst): - (p2, v2) = lst[i] - if p2 == IDENT: - if v2 in defs: - lst[i] = (NUM, 1) - else: - lst[i] = (NUM, 0) - elif p2 == OP and v2 == '(': - del lst[i] - (p2, v2) = lst[i] - del lst[i] # remove the ident, and change the ) for the value - if v2 in defs: - lst[i] = (NUM, 1) - else: - lst[i] = (NUM, 0) - else: - raise PreprocError('Invalid define expression %r' % lst) - - elif p == IDENT and v in defs: - - if isinstance(defs[v], str): - a, b = extract_macro(defs[v]) - defs[v] = b - macro_def = defs[v] - to_add = macro_def[1] - - if isinstance(macro_def[0], list): - # macro without arguments - del lst[i] - accu = to_add[:] - reduce_tokens(accu, defs, ban+[v]) - for tmp in accu: - lst.insert(i, tmp) - i += 1 - else: - # collect the arguments for the funcall - - args = [] - del lst[i] - - if i >= len(lst): - raise PreprocError('expected ( after %r (got nothing)' % v) - - (p2, v2) = lst[i] - if p2 != OP or v2 != '(': - raise PreprocError('expected ( after %r' % v) - - del lst[i] - - one_param = [] - count_paren = 0 - while i < len(lst): - p2, v2 = lst[i] - - del lst[i] - if p2 == OP and count_paren == 0: - if v2 == '(': - one_param.append((p2, v2)) - count_paren += 1 - elif v2 == ')': - if one_param: - args.append(one_param) - break - elif v2 == ',': - if not one_param: - raise PreprocError('empty param in funcall %r' % v) - args.append(one_param) - one_param = [] - else: - one_param.append((p2, v2)) - else: - one_param.append((p2, v2)) - if v2 == '(': - count_paren += 1 - elif v2 == ')': - count_paren -= 1 - else: - raise PreprocError('malformed macro') - - # substitute the arguments within the define expression - accu = [] - arg_table = macro_def[0] - j = 0 - while j < len(to_add): - (p2, v2) = to_add[j] - - if p2 == OP and v2 == '#': - # stringize is for arguments only - if j+1 < len(to_add) and to_add[j+1][0] == IDENT and to_add[j+1][1] in arg_table: - toks = args[arg_table[to_add[j+1][1]]] - accu.append((STR, stringize(toks))) - j += 1 - else: - accu.append((p2, v2)) - elif p2 == OP and v2 == '##': - # token pasting, how can man invent such a complicated system? - if accu and j+1 < len(to_add): - # we have at least two tokens - - t1 = accu[-1] - - if to_add[j+1][0] == IDENT and to_add[j+1][1] in arg_table: - toks = args[arg_table[to_add[j+1][1]]] - - if toks: - accu[-1] = paste_tokens(t1, toks[0]) #(IDENT, accu[-1][1] + toks[0][1]) - accu.extend(toks[1:]) - else: - # error, case "a##" - accu.append((p2, v2)) - accu.extend(toks) - elif to_add[j+1][0] == IDENT and to_add[j+1][1] == '__VA_ARGS__': - # first collect the tokens - va_toks = [] - st = len(macro_def[0]) - pt = len(args) - for x in args[pt-st+1:]: - va_toks.extend(x) - va_toks.append((OP, ',')) - if va_toks: - va_toks.pop() # extra comma - if len(accu)>1: - (p3, v3) = accu[-1] - (p4, v4) = accu[-2] - if v3 == '##': - # remove the token paste - accu.pop() - if v4 == ',' and pt < st: - # remove the comma - accu.pop() - accu += va_toks - else: - accu[-1] = paste_tokens(t1, to_add[j+1]) - - j += 1 - else: - # Invalid paste, case "##a" or "b##" - accu.append((p2, v2)) - - elif p2 == IDENT and v2 in arg_table: - toks = args[arg_table[v2]] - reduce_tokens(toks, defs, ban+[v]) - accu.extend(toks) - else: - accu.append((p2, v2)) - - j += 1 - - - reduce_tokens(accu, defs, ban+[v]) - - for x in range(len(accu)-1, -1, -1): - lst.insert(i, accu[x]) - - i += 1 - - -def eval_macro(lst, defs): - """ - Reduce the tokens by :py:func:`waflib.Tools.c_preproc.reduce_tokens` and try to return a 0/1 result by :py:func:`waflib.Tools.c_preproc.reduce_eval`. - - :param lst: list of tokens - :type lst: list of tuple(token, value) - :param defs: macro definitions - :type defs: dict - :rtype: int - """ - reduce_tokens(lst, defs, []) - if not lst: - raise PreprocError('missing tokens to evaluate') - - if lst: - p, v = lst[0] - if p == IDENT and v not in defs: - raise PreprocError('missing macro %r' % lst) - - p, v = reduce_eval(lst) - return int(v) != 0 - -def extract_macro(txt): - """ - Process a macro definition of the form:: - #define f(x, y) x * y - - into a function or a simple macro without arguments - - :param txt: expression to exact a macro definition from - :type txt: string - :return: a tuple containing the name, the list of arguments and the replacement - :rtype: tuple(string, [list, list]) - """ - t = tokenize(txt) - if re_fun.search(txt): - p, name = t[0] - - p, v = t[1] - if p != OP: - raise PreprocError('expected (') - - i = 1 - pindex = 0 - params = {} - prev = '(' - - while 1: - i += 1 - p, v = t[i] - - if prev == '(': - if p == IDENT: - params[v] = pindex - pindex += 1 - prev = p - elif p == OP and v == ')': - break - else: - raise PreprocError('unexpected token (3)') - elif prev == IDENT: - if p == OP and v == ',': - prev = v - elif p == OP and v == ')': - break - else: - raise PreprocError('comma or ... expected') - elif prev == ',': - if p == IDENT: - params[v] = pindex - pindex += 1 - prev = p - elif p == OP and v == '...': - raise PreprocError('not implemented (1)') - else: - raise PreprocError('comma or ... expected (2)') - elif prev == '...': - raise PreprocError('not implemented (2)') - else: - raise PreprocError('unexpected else') - - #~ print (name, [params, t[i+1:]]) - return (name, [params, t[i+1:]]) - else: - (p, v) = t[0] - if len(t) > 1: - return (v, [[], t[1:]]) - else: - # empty define, assign an empty token - return (v, [[], [('T','')]]) - -re_include = re.compile(r'^\s*(<(?:.*)>|"(?:.*)")') -def extract_include(txt, defs): - """ - Process a line in the form:: - - #include foo - - :param txt: include line to process - :type txt: string - :param defs: macro definitions - :type defs: dict - :return: the file name - :rtype: string - """ - m = re_include.search(txt) - if m: - txt = m.group(1) - return txt[0], txt[1:-1] - - # perform preprocessing and look at the result, it must match an include - toks = tokenize(txt) - reduce_tokens(toks, defs, ['waf_include']) - - if not toks: - raise PreprocError('could not parse include %r' % txt) - - if len(toks) == 1: - if toks[0][0] == STR: - return '"', toks[0][1] - else: - if toks[0][1] == '<' and toks[-1][1] == '>': - ret = '<', stringize(toks).lstrip('<').rstrip('>') - return ret - - raise PreprocError('could not parse include %r' % txt) - -def parse_char(txt): - """ - Parse a c character - - :param txt: character to parse - :type txt: string - :return: a character literal - :rtype: string - """ - - if not txt: - raise PreprocError('attempted to parse a null char') - if txt[0] != '\\': - return ord(txt) - c = txt[1] - if c == 'x': - if len(txt) == 4 and txt[3] in string.hexdigits: - return int(txt[2:], 16) - return int(txt[2:], 16) - elif c.isdigit(): - if c == '0' and len(txt)==2: - return 0 - for i in 3, 2, 1: - if len(txt) > i and txt[1:1+i].isdigit(): - return (1+i, int(txt[1:1+i], 8)) - else: - try: - return chr_esc[c] - except KeyError: - raise PreprocError('could not parse char literal %r' % txt) - -def tokenize(s): - """ - Convert a string into a list of tokens (shlex.split does not apply to c/c++/d) - - :param s: input to tokenize - :type s: string - :return: a list of tokens - :rtype: list of tuple(token, value) - """ - return tokenize_private(s)[:] # force a copy of the results - -def tokenize_private(s): - ret = [] - for match in re_clexer.finditer(s): - m = match.group - for name in tok_types: - v = m(name) - if v: - if name == IDENT: - if v in g_optrans: - name = OP - elif v.lower() == "true": - v = 1 - name = NUM - elif v.lower() == "false": - v = 0 - name = NUM - elif name == NUM: - if m('oct'): - v = int(v, 8) - elif m('hex'): - v = int(m('hex'), 16) - elif m('n0'): - v = m('n0') - else: - v = m('char') - if v: - v = parse_char(v) - else: - v = m('n2') or m('n4') - elif name == OP: - if v == '%:': - v = '#' - elif v == '%:%:': - v = '##' - elif name == STR: - # remove the quotes around the string - v = v[1:-1] - ret.append((name, v)) - break - return ret - -def format_defines(lst): - ret = [] - for y in lst: - if y: - pos = y.find('=') - if pos == -1: - # "-DFOO" should give "#define FOO 1" - ret.append(y) - elif pos > 0: - # all others are assumed to be -DX=Y - ret.append('%s %s' % (y[:pos], y[pos+1:])) - else: - raise ValueError('Invalid define expression %r' % y) - return ret - -class c_parser(object): - """ - Used by :py:func:`waflib.Tools.c_preproc.scan` to parse c/h files. Note that by default, - only project headers are parsed. - """ - def __init__(self, nodepaths=None, defines=None): - self.lines = [] - """list of lines read""" - - if defines is None: - self.defs = {} - else: - self.defs = dict(defines) # make a copy - self.state = [] - - self.count_files = 0 - self.currentnode_stack = [] - - self.nodepaths = nodepaths or [] - """Include paths""" - - self.nodes = [] - """List of :py:class:`waflib.Node.Node` found so far""" - - self.names = [] - """List of file names that could not be matched by any file""" - - self.curfile = '' - """Current file""" - - self.ban_includes = set() - """Includes that must not be read (#pragma once)""" - - self.listed = set() - """Include nodes/names already listed to avoid duplicates in self.nodes/self.names""" - - def cached_find_resource(self, node, filename): - """ - Find a file from the input directory - - :param node: directory - :type node: :py:class:`waflib.Node.Node` - :param filename: header to find - :type filename: string - :return: the node if found, or None - :rtype: :py:class:`waflib.Node.Node` - """ - try: - cache = node.ctx.preproc_cache_node - except AttributeError: - cache = node.ctx.preproc_cache_node = Utils.lru_cache(FILE_CACHE_SIZE) - - key = (node, filename) - try: - return cache[key] - except KeyError: - ret = node.find_resource(filename) - if ret: - if getattr(ret, 'children', None): - ret = None - elif ret.is_child_of(node.ctx.bldnode): - tmp = node.ctx.srcnode.search_node(ret.path_from(node.ctx.bldnode)) - if tmp and getattr(tmp, 'children', None): - ret = None - cache[key] = ret - return ret - - def tryfind(self, filename, kind='"', env=None): - """ - Try to obtain a node from the filename based from the include paths. Will add - the node found to :py:attr:`waflib.Tools.c_preproc.c_parser.nodes` or the file name to - :py:attr:`waflib.Tools.c_preproc.c_parser.names` if no corresponding file is found. Called by - :py:attr:`waflib.Tools.c_preproc.c_parser.start`. - - :param filename: header to find - :type filename: string - :return: the node if found - :rtype: :py:class:`waflib.Node.Node` - """ - if filename.endswith('.moc'): - # we could let the qt4 module use a subclass, but then the function "scan" below must be duplicated - # in the qt4 and in the qt5 classes. So we have two lines here and it is sufficient. - self.names.append(filename) - return None - - self.curfile = filename - - found = None - if kind == '"': - if env.MSVC_VERSION: - for n in reversed(self.currentnode_stack): - found = self.cached_find_resource(n, filename) - if found: - break - else: - found = self.cached_find_resource(self.currentnode_stack[-1], filename) - - if not found: - for n in self.nodepaths: - found = self.cached_find_resource(n, filename) - if found: - break - - listed = self.listed - if found and not found in self.ban_includes: - if found not in listed: - listed.add(found) - self.nodes.append(found) - self.addlines(found) - else: - if filename not in listed: - listed.add(filename) - self.names.append(filename) - return found - - def filter_comments(self, node): - """ - Filter the comments from a c/h file, and return the preprocessor lines. - The regexps :py:attr:`waflib.Tools.c_preproc.re_cpp`, :py:attr:`waflib.Tools.c_preproc.re_nl` and :py:attr:`waflib.Tools.c_preproc.re_lines` are used internally. - - :return: the preprocessor directives as a list of (keyword, line) - :rtype: a list of string pairs - """ - # return a list of tuples : keyword, line - code = node.read() - if use_trigraphs: - for (a, b) in trig_def: - code = code.split(a).join(b) - code = re_nl.sub('', code) - code = re_cpp.sub(repl, code) - return re_lines.findall(code) - - def parse_lines(self, node): - try: - cache = node.ctx.preproc_cache_lines - except AttributeError: - cache = node.ctx.preproc_cache_lines = Utils.lru_cache(LINE_CACHE_SIZE) - try: - return cache[node] - except KeyError: - cache[node] = lines = self.filter_comments(node) - lines.append((POPFILE, '')) - lines.reverse() - return lines - - def addlines(self, node): - """ - Add the lines from a header in the list of preprocessor lines to parse - - :param node: header - :type node: :py:class:`waflib.Node.Node` - """ - - self.currentnode_stack.append(node.parent) - - self.count_files += 1 - if self.count_files > recursion_limit: - # issue #812 - raise PreprocError('recursion limit exceeded') - - if Logs.verbose: - Logs.debug('preproc: reading file %r', node) - try: - lines = self.parse_lines(node) - except EnvironmentError: - raise PreprocError('could not read the file %r' % node) - except Exception: - if Logs.verbose > 0: - Logs.error('parsing %r failed %s', node, traceback.format_exc()) - else: - self.lines.extend(lines) - - def start(self, node, env): - """ - Preprocess a source file to obtain the dependencies, which are accumulated to :py:attr:`waflib.Tools.c_preproc.c_parser.nodes` - and :py:attr:`waflib.Tools.c_preproc.c_parser.names`. - - :param node: source file - :type node: :py:class:`waflib.Node.Node` - :param env: config set containing additional defines to take into account - :type env: :py:class:`waflib.ConfigSet.ConfigSet` - """ - Logs.debug('preproc: scanning %s (in %s)', node.name, node.parent.name) - - self.current_file = node - self.addlines(node) - - # macros may be defined on the command-line, so they must be parsed as if they were part of the file - if env.DEFINES: - lst = format_defines(env.DEFINES) - lst.reverse() - self.lines.extend([('define', x) for x in lst]) - - while self.lines: - (token, line) = self.lines.pop() - if token == POPFILE: - self.count_files -= 1 - self.currentnode_stack.pop() - continue - - try: - state = self.state - - # make certain we define the state if we are about to enter in an if block - if token[:2] == 'if': - state.append(undefined) - elif token == 'endif': - state.pop() - - # skip lines when in a dead 'if' branch, wait for the endif - if token[0] != 'e': - if skipped in self.state or ignored in self.state: - continue - - if token == 'if': - ret = eval_macro(tokenize(line), self.defs) - if ret: - state[-1] = accepted - else: - state[-1] = ignored - elif token == 'ifdef': - m = re_mac.match(line) - if m and m.group() in self.defs: - state[-1] = accepted - else: - state[-1] = ignored - elif token == 'ifndef': - m = re_mac.match(line) - if m and m.group() in self.defs: - state[-1] = ignored - else: - state[-1] = accepted - elif token == 'include' or token == 'import': - (kind, inc) = extract_include(line, self.defs) - self.current_file = self.tryfind(inc, kind, env) - if token == 'import': - self.ban_includes.add(self.current_file) - elif token == 'elif': - if state[-1] == accepted: - state[-1] = skipped - elif state[-1] == ignored: - if eval_macro(tokenize(line), self.defs): - state[-1] = accepted - elif token == 'else': - if state[-1] == accepted: - state[-1] = skipped - elif state[-1] == ignored: - state[-1] = accepted - elif token == 'define': - try: - self.defs[self.define_name(line)] = line - except AttributeError: - raise PreprocError('Invalid define line %r' % line) - elif token == 'undef': - m = re_mac.match(line) - if m and m.group() in self.defs: - self.defs.__delitem__(m.group()) - #print "undef %s" % name - elif token == 'pragma': - if re_pragma_once.match(line.lower()): - self.ban_includes.add(self.current_file) - except Exception as e: - if Logs.verbose: - Logs.debug('preproc: line parsing failed (%s): %s %s', e, line, traceback.format_exc()) - - def define_name(self, line): - """ - :param line: define line - :type line: string - :rtype: string - :return: the define name - """ - return re_mac.match(line).group() - -def scan(task): - """ - Get the dependencies using a c/c++ preprocessor, this is required for finding dependencies of the kind:: - - #include some_macro() - - This function is bound as a task method on :py:class:`waflib.Tools.c.c` and :py:class:`waflib.Tools.cxx.cxx` for example - """ - try: - incn = task.generator.includes_nodes - except AttributeError: - raise Errors.WafError('%r is missing a feature such as "c", "cxx" or "includes": ' % task.generator) - - if go_absolute: - nodepaths = incn + [task.generator.bld.root.find_dir(x) for x in standard_includes] - else: - nodepaths = [x for x in incn if x.is_child_of(x.ctx.srcnode) or x.is_child_of(x.ctx.bldnode)] - - tmp = c_parser(nodepaths) - tmp.start(task.inputs[0], task.env) - return (tmp.nodes, tmp.names) diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/c_tests.py b/ldb-2.0.8/third_party/waf/waflib/Tools/c_tests.py deleted file mode 100644 index 7a4094f..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/c_tests.py +++ /dev/null @@ -1,230 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2016-2018 (ita) - -""" -Various configuration tests. -""" - -from waflib import Task -from waflib.Configure import conf -from waflib.TaskGen import feature, before_method, after_method - -LIB_CODE = ''' -#ifdef _MSC_VER -#define testEXPORT __declspec(dllexport) -#else -#define testEXPORT -#endif -testEXPORT int lib_func(void) { return 9; } -''' - -MAIN_CODE = ''' -#ifdef _MSC_VER -#define testEXPORT __declspec(dllimport) -#else -#define testEXPORT -#endif -testEXPORT int lib_func(void); -int main(int argc, char **argv) { - (void)argc; (void)argv; - return !(lib_func() == 9); -} -''' - -@feature('link_lib_test') -@before_method('process_source') -def link_lib_test_fun(self): - """ - The configuration test :py:func:`waflib.Configure.run_build` declares a unique task generator, - so we need to create other task generators from here to check if the linker is able to link libraries. - """ - def write_test_file(task): - task.outputs[0].write(task.generator.code) - - rpath = [] - if getattr(self, 'add_rpath', False): - rpath = [self.bld.path.get_bld().abspath()] - - mode = self.mode - m = '%s %s' % (mode, mode) - ex = self.test_exec and 'test_exec' or '' - bld = self.bld - bld(rule=write_test_file, target='test.' + mode, code=LIB_CODE) - bld(rule=write_test_file, target='main.' + mode, code=MAIN_CODE) - bld(features='%sshlib' % m, source='test.' + mode, target='test') - bld(features='%sprogram %s' % (m, ex), source='main.' + mode, target='app', use='test', rpath=rpath) - -@conf -def check_library(self, mode=None, test_exec=True): - """ - Checks if libraries can be linked with the current linker. Uses :py:func:`waflib.Tools.c_tests.link_lib_test_fun`. - - :param mode: c or cxx or d - :type mode: string - """ - if not mode: - mode = 'c' - if self.env.CXX: - mode = 'cxx' - self.check( - compile_filename = [], - features = 'link_lib_test', - msg = 'Checking for libraries', - mode = mode, - test_exec = test_exec) - -######################################################################################## - -INLINE_CODE = ''' -typedef int foo_t; -static %s foo_t static_foo () {return 0; } -%s foo_t foo () { - return 0; -} -''' -INLINE_VALUES = ['inline', '__inline__', '__inline'] - -@conf -def check_inline(self, **kw): - """ - Checks for the right value for inline macro. - Define INLINE_MACRO to 1 if the define is found. - If the inline macro is not 'inline', add a define to the ``config.h`` (#define inline __inline__) - - :param define_name: define INLINE_MACRO by default to 1 if the macro is defined - :type define_name: string - :param features: by default *c* or *cxx* depending on the compiler present - :type features: list of string - """ - self.start_msg('Checking for inline') - - if not 'define_name' in kw: - kw['define_name'] = 'INLINE_MACRO' - if not 'features' in kw: - if self.env.CXX: - kw['features'] = ['cxx'] - else: - kw['features'] = ['c'] - - for x in INLINE_VALUES: - kw['fragment'] = INLINE_CODE % (x, x) - - try: - self.check(**kw) - except self.errors.ConfigurationError: - continue - else: - self.end_msg(x) - if x != 'inline': - self.define('inline', x, quote=False) - return x - self.fatal('could not use inline functions') - -######################################################################################## - -LARGE_FRAGMENT = '''#include -int main(int argc, char **argv) { - (void)argc; (void)argv; - return !(sizeof(off_t) >= 8); -} -''' - -@conf -def check_large_file(self, **kw): - """ - Checks for large file support and define the macro HAVE_LARGEFILE - The test is skipped on win32 systems (DEST_BINFMT == pe). - - :param define_name: define to set, by default *HAVE_LARGEFILE* - :type define_name: string - :param execute: execute the test (yes by default) - :type execute: bool - """ - if not 'define_name' in kw: - kw['define_name'] = 'HAVE_LARGEFILE' - if not 'execute' in kw: - kw['execute'] = True - - if not 'features' in kw: - if self.env.CXX: - kw['features'] = ['cxx', 'cxxprogram'] - else: - kw['features'] = ['c', 'cprogram'] - - kw['fragment'] = LARGE_FRAGMENT - - kw['msg'] = 'Checking for large file support' - ret = True - try: - if self.env.DEST_BINFMT != 'pe': - ret = self.check(**kw) - except self.errors.ConfigurationError: - pass - else: - if ret: - return True - - kw['msg'] = 'Checking for -D_FILE_OFFSET_BITS=64' - kw['defines'] = ['_FILE_OFFSET_BITS=64'] - try: - ret = self.check(**kw) - except self.errors.ConfigurationError: - pass - else: - self.define('_FILE_OFFSET_BITS', 64) - return ret - - self.fatal('There is no support for large files') - -######################################################################################## - -ENDIAN_FRAGMENT = ''' -short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; -short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; -int use_ascii (int i) { - return ascii_mm[i] + ascii_ii[i]; -} -short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; -short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; -int use_ebcdic (int i) { - return ebcdic_mm[i] + ebcdic_ii[i]; -} -extern int foo; -''' - -class grep_for_endianness(Task.Task): - """ - Task that reads a binary and tries to determine the endianness - """ - color = 'PINK' - def run(self): - txt = self.inputs[0].read(flags='rb').decode('latin-1') - if txt.find('LiTTleEnDian') > -1: - self.generator.tmp.append('little') - elif txt.find('BIGenDianSyS') > -1: - self.generator.tmp.append('big') - else: - return -1 - -@feature('grep_for_endianness') -@after_method('process_source') -def grep_for_endianness_fun(self): - """ - Used by the endianness configuration test - """ - self.create_task('grep_for_endianness', self.compiled_tasks[0].outputs[0]) - -@conf -def check_endianness(self): - """ - Executes a configuration test to determine the endianness - """ - tmp = [] - def check_msg(self): - return tmp[0] - self.check(fragment=ENDIAN_FRAGMENT, features='c grep_for_endianness', - msg='Checking for endianness', define='ENDIANNESS', tmp=tmp, - okmsg=check_msg, confcache=None) - return tmp[0] - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/ccroot.py b/ldb-2.0.8/third_party/waf/waflib/Tools/ccroot.py deleted file mode 100644 index 579d5b2..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/ccroot.py +++ /dev/null @@ -1,791 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2005-2018 (ita) - -""" -Classes and methods shared by tools providing support for C-like language such -as C/C++/D/Assembly/Go (this support module is almost never used alone). -""" - -import os, re -from waflib import Task, Utils, Node, Errors, Logs -from waflib.TaskGen import after_method, before_method, feature, taskgen_method, extension -from waflib.Tools import c_aliases, c_preproc, c_config, c_osx, c_tests -from waflib.Configure import conf - -SYSTEM_LIB_PATHS = ['/usr/lib64', '/usr/lib', '/usr/local/lib64', '/usr/local/lib'] - -USELIB_VARS = Utils.defaultdict(set) -""" -Mapping for features to :py:class:`waflib.ConfigSet.ConfigSet` variables. See :py:func:`waflib.Tools.ccroot.propagate_uselib_vars`. -""" - -USELIB_VARS['c'] = set(['INCLUDES', 'FRAMEWORKPATH', 'DEFINES', 'CPPFLAGS', 'CCDEPS', 'CFLAGS', 'ARCH']) -USELIB_VARS['cxx'] = set(['INCLUDES', 'FRAMEWORKPATH', 'DEFINES', 'CPPFLAGS', 'CXXDEPS', 'CXXFLAGS', 'ARCH']) -USELIB_VARS['d'] = set(['INCLUDES', 'DFLAGS']) -USELIB_VARS['includes'] = set(['INCLUDES', 'FRAMEWORKPATH', 'ARCH']) - -USELIB_VARS['cprogram'] = USELIB_VARS['cxxprogram'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS', 'FRAMEWORK', 'FRAMEWORKPATH', 'ARCH', 'LDFLAGS']) -USELIB_VARS['cshlib'] = USELIB_VARS['cxxshlib'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS', 'FRAMEWORK', 'FRAMEWORKPATH', 'ARCH', 'LDFLAGS']) -USELIB_VARS['cstlib'] = USELIB_VARS['cxxstlib'] = set(['ARFLAGS', 'LINKDEPS']) - -USELIB_VARS['dprogram'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS']) -USELIB_VARS['dshlib'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS']) -USELIB_VARS['dstlib'] = set(['ARFLAGS', 'LINKDEPS']) - -USELIB_VARS['asm'] = set(['ASFLAGS']) - -# ================================================================================================= - -@taskgen_method -def create_compiled_task(self, name, node): - """ - Create the compilation task: c, cxx, asm, etc. The output node is created automatically (object file with a typical **.o** extension). - The task is appended to the list *compiled_tasks* which is then used by :py:func:`waflib.Tools.ccroot.apply_link` - - :param name: name of the task class - :type name: string - :param node: the file to compile - :type node: :py:class:`waflib.Node.Node` - :return: The task created - :rtype: :py:class:`waflib.Task.Task` - """ - out = '%s.%d.o' % (node.name, self.idx) - task = self.create_task(name, node, node.parent.find_or_declare(out)) - try: - self.compiled_tasks.append(task) - except AttributeError: - self.compiled_tasks = [task] - return task - -@taskgen_method -def to_incnodes(self, inlst): - """ - Task generator method provided to convert a list of string/nodes into a list of includes folders. - - The paths are assumed to be relative to the task generator path, except if they begin by **#** - in which case they are searched from the top-level directory (``bld.srcnode``). - The folders are simply assumed to be existing. - - The node objects in the list are returned in the output list. The strings are converted - into node objects if possible. The node is searched from the source directory, and if a match is found, - the equivalent build directory is created and added to the returned list too. When a folder cannot be found, it is ignored. - - :param inlst: list of folders - :type inlst: space-delimited string or a list of string/nodes - :rtype: list of :py:class:`waflib.Node.Node` - :return: list of include folders as nodes - """ - lst = [] - seen = set() - for x in self.to_list(inlst): - if x in seen or not x: - continue - seen.add(x) - - # with a real lot of targets, it is sometimes interesting to cache the results below - if isinstance(x, Node.Node): - lst.append(x) - else: - if os.path.isabs(x): - lst.append(self.bld.root.make_node(x) or x) - else: - if x[0] == '#': - p = self.bld.bldnode.make_node(x[1:]) - v = self.bld.srcnode.make_node(x[1:]) - else: - p = self.path.get_bld().make_node(x) - v = self.path.make_node(x) - if p.is_child_of(self.bld.bldnode): - p.mkdir() - lst.append(p) - lst.append(v) - return lst - -@feature('c', 'cxx', 'd', 'asm', 'fc', 'includes') -@after_method('propagate_uselib_vars', 'process_source') -def apply_incpaths(self): - """ - Task generator method that processes the attribute *includes*:: - - tg = bld(features='includes', includes='.') - - The folders only need to be relative to the current directory, the equivalent build directory is - added automatically (for headers created in the build directory). This enables using a build directory - or not (``top == out``). - - This method will add a list of nodes read by :py:func:`waflib.Tools.ccroot.to_incnodes` in ``tg.env.INCPATHS``, - and the list of include paths in ``tg.env.INCLUDES``. - """ - - lst = self.to_incnodes(self.to_list(getattr(self, 'includes', [])) + self.env.INCLUDES) - self.includes_nodes = lst - cwd = self.get_cwd() - self.env.INCPATHS = [x.path_from(cwd) for x in lst] - -class link_task(Task.Task): - """ - Base class for all link tasks. A task generator is supposed to have at most one link task bound in the attribute *link_task*. See :py:func:`waflib.Tools.ccroot.apply_link`. - - .. inheritance-diagram:: waflib.Tools.ccroot.stlink_task waflib.Tools.c.cprogram waflib.Tools.c.cshlib waflib.Tools.cxx.cxxstlib waflib.Tools.cxx.cxxprogram waflib.Tools.cxx.cxxshlib waflib.Tools.d.dprogram waflib.Tools.d.dshlib waflib.Tools.d.dstlib waflib.Tools.ccroot.fake_shlib waflib.Tools.ccroot.fake_stlib waflib.Tools.asm.asmprogram waflib.Tools.asm.asmshlib waflib.Tools.asm.asmstlib - """ - color = 'YELLOW' - - weight = 3 - """Try to process link tasks as early as possible""" - - inst_to = None - """Default installation path for the link task outputs, or None to disable""" - - chmod = Utils.O755 - """Default installation mode for the link task outputs""" - - def add_target(self, target): - """ - Process the *target* attribute to add the platform-specific prefix/suffix such as *.so* or *.exe*. - The settings are retrieved from ``env.clsname_PATTERN`` - """ - if isinstance(target, str): - base = self.generator.path - if target.startswith('#'): - # for those who like flat structures - target = target[1:] - base = self.generator.bld.bldnode - - pattern = self.env[self.__class__.__name__ + '_PATTERN'] - if not pattern: - pattern = '%s' - folder, name = os.path.split(target) - - if self.__class__.__name__.find('shlib') > 0 and getattr(self.generator, 'vnum', None): - nums = self.generator.vnum.split('.') - if self.env.DEST_BINFMT == 'pe': - # include the version in the dll file name, - # the import lib file name stays unversioned. - name = name + '-' + nums[0] - elif self.env.DEST_OS == 'openbsd': - pattern = '%s.%s' % (pattern, nums[0]) - if len(nums) >= 2: - pattern += '.%s' % nums[1] - - if folder: - tmp = folder + os.sep + pattern % name - else: - tmp = pattern % name - target = base.find_or_declare(tmp) - self.set_outputs(target) - - def exec_command(self, *k, **kw): - ret = super(link_task, self).exec_command(*k, **kw) - if not ret and self.env.DO_MANIFEST: - ret = self.exec_mf() - return ret - - def exec_mf(self): - """ - Create manifest files for VS-like compilers (msvc, ifort, ...) - """ - if not self.env.MT: - return 0 - - manifest = None - for out_node in self.outputs: - if out_node.name.endswith('.manifest'): - manifest = out_node.abspath() - break - else: - # Should never get here. If we do, it means the manifest file was - # never added to the outputs list, thus we don't have a manifest file - # to embed, so we just return. - return 0 - - # embedding mode. Different for EXE's and DLL's. - # see: http://msdn2.microsoft.com/en-us/library/ms235591(VS.80).aspx - mode = '' - for x in Utils.to_list(self.generator.features): - if x in ('cprogram', 'cxxprogram', 'fcprogram', 'fcprogram_test'): - mode = 1 - elif x in ('cshlib', 'cxxshlib', 'fcshlib'): - mode = 2 - - Logs.debug('msvc: embedding manifest in mode %r', mode) - - lst = [] + self.env.MT - lst.extend(Utils.to_list(self.env.MTFLAGS)) - lst.extend(['-manifest', manifest]) - lst.append('-outputresource:%s;%s' % (self.outputs[0].abspath(), mode)) - - return super(link_task, self).exec_command(lst) - -class stlink_task(link_task): - """ - Base for static link tasks, which use *ar* most of the time. - The target is always removed before being written. - """ - run_str = '${AR} ${ARFLAGS} ${AR_TGT_F}${TGT} ${AR_SRC_F}${SRC}' - - chmod = Utils.O644 - """Default installation mode for the static libraries""" - -def rm_tgt(cls): - old = cls.run - def wrap(self): - try: - os.remove(self.outputs[0].abspath()) - except OSError: - pass - return old(self) - setattr(cls, 'run', wrap) -rm_tgt(stlink_task) - -@feature('skip_stlib_link_deps') -@before_method('process_use') -def apply_skip_stlib_link_deps(self): - """ - This enables an optimization in the :py:func:wafilb.Tools.ccroot.processes_use: method that skips dependency and - link flag optimizations for targets that generate static libraries (via the :py:class:Tools.ccroot.stlink_task task). - The actual behavior is implemented in :py:func:wafilb.Tools.ccroot.processes_use: method so this feature only tells waf - to enable the new behavior. - """ - self.env.SKIP_STLIB_LINK_DEPS = True - -@feature('c', 'cxx', 'd', 'fc', 'asm') -@after_method('process_source') -def apply_link(self): - """ - Collect the tasks stored in ``compiled_tasks`` (created by :py:func:`waflib.Tools.ccroot.create_compiled_task`), and - use the outputs for a new instance of :py:class:`waflib.Tools.ccroot.link_task`. The class to use is the first link task - matching a name from the attribute *features*, for example:: - - def build(bld): - tg = bld(features='cxx cxxprogram cprogram', source='main.c', target='app') - - will create the task ``tg.link_task`` as a new instance of :py:class:`waflib.Tools.cxx.cxxprogram` - """ - - for x in self.features: - if x == 'cprogram' and 'cxx' in self.features: # limited compat - x = 'cxxprogram' - elif x == 'cshlib' and 'cxx' in self.features: - x = 'cxxshlib' - - if x in Task.classes: - if issubclass(Task.classes[x], link_task): - link = x - break - else: - return - - objs = [t.outputs[0] for t in getattr(self, 'compiled_tasks', [])] - self.link_task = self.create_task(link, objs) - self.link_task.add_target(self.target) - - # remember that the install paths are given by the task generators - try: - inst_to = self.install_path - except AttributeError: - inst_to = self.link_task.inst_to - if inst_to: - # install a copy of the node list we have at this moment (implib not added) - self.install_task = self.add_install_files( - install_to=inst_to, install_from=self.link_task.outputs[:], - chmod=self.link_task.chmod, task=self.link_task) - -@taskgen_method -def use_rec(self, name, **kw): - """ - Processes the ``use`` keyword recursively. This method is kind of private and only meant to be used from ``process_use`` - """ - - if name in self.tmp_use_not or name in self.tmp_use_seen: - return - - try: - y = self.bld.get_tgen_by_name(name) - except Errors.WafError: - self.uselib.append(name) - self.tmp_use_not.add(name) - return - - self.tmp_use_seen.append(name) - y.post() - - # bind temporary attributes on the task generator - y.tmp_use_objects = objects = kw.get('objects', True) - y.tmp_use_stlib = stlib = kw.get('stlib', True) - try: - link_task = y.link_task - except AttributeError: - y.tmp_use_var = '' - else: - objects = False - if not isinstance(link_task, stlink_task): - stlib = False - y.tmp_use_var = 'LIB' - else: - y.tmp_use_var = 'STLIB' - - p = self.tmp_use_prec - for x in self.to_list(getattr(y, 'use', [])): - if self.env["STLIB_" + x]: - continue - try: - p[x].append(name) - except KeyError: - p[x] = [name] - self.use_rec(x, objects=objects, stlib=stlib) - -@feature('c', 'cxx', 'd', 'use', 'fc') -@before_method('apply_incpaths', 'propagate_uselib_vars') -@after_method('apply_link', 'process_source') -def process_use(self): - """ - Process the ``use`` attribute which contains a list of task generator names:: - - def build(bld): - bld.shlib(source='a.c', target='lib1') - bld.program(source='main.c', target='app', use='lib1') - - See :py:func:`waflib.Tools.ccroot.use_rec`. - """ - - use_not = self.tmp_use_not = set() - self.tmp_use_seen = [] # we would like an ordered set - use_prec = self.tmp_use_prec = {} - self.uselib = self.to_list(getattr(self, 'uselib', [])) - self.includes = self.to_list(getattr(self, 'includes', [])) - names = self.to_list(getattr(self, 'use', [])) - - for x in names: - self.use_rec(x) - - for x in use_not: - if x in use_prec: - del use_prec[x] - - # topological sort - out = self.tmp_use_sorted = [] - tmp = [] - for x in self.tmp_use_seen: - for k in use_prec.values(): - if x in k: - break - else: - tmp.append(x) - - while tmp: - e = tmp.pop() - out.append(e) - try: - nlst = use_prec[e] - except KeyError: - pass - else: - del use_prec[e] - for x in nlst: - for y in use_prec: - if x in use_prec[y]: - break - else: - tmp.append(x) - if use_prec: - raise Errors.WafError('Cycle detected in the use processing %r' % use_prec) - out.reverse() - - link_task = getattr(self, 'link_task', None) - for x in out: - y = self.bld.get_tgen_by_name(x) - var = y.tmp_use_var - if var and link_task: - if self.env.SKIP_STLIB_LINK_DEPS and isinstance(link_task, stlink_task): - # If the skip_stlib_link_deps feature is enabled then we should - # avoid adding lib deps to the stlink_task instance. - pass - elif var == 'LIB' or y.tmp_use_stlib or x in names: - self.env.append_value(var, [y.target[y.target.rfind(os.sep) + 1:]]) - self.link_task.dep_nodes.extend(y.link_task.outputs) - tmp_path = y.link_task.outputs[0].parent.path_from(self.get_cwd()) - self.env.append_unique(var + 'PATH', [tmp_path]) - else: - if y.tmp_use_objects: - self.add_objects_from_tgen(y) - - if getattr(y, 'export_includes', None): - # self.includes may come from a global variable #2035 - self.includes = self.includes + y.to_incnodes(y.export_includes) - - if getattr(y, 'export_defines', None): - self.env.append_value('DEFINES', self.to_list(y.export_defines)) - - - # and finally, add the use variables (no recursion needed) - for x in names: - try: - y = self.bld.get_tgen_by_name(x) - except Errors.WafError: - if not self.env['STLIB_' + x] and not x in self.uselib: - self.uselib.append(x) - else: - for k in self.to_list(getattr(y, 'use', [])): - if not self.env['STLIB_' + k] and not k in self.uselib: - self.uselib.append(k) - -@taskgen_method -def accept_node_to_link(self, node): - """ - PRIVATE INTERNAL USE ONLY - """ - return not node.name.endswith('.pdb') - -@taskgen_method -def add_objects_from_tgen(self, tg): - """ - Add the objects from the depending compiled tasks as link task inputs. - - Some objects are filtered: for instance, .pdb files are added - to the compiled tasks but not to the link tasks (to avoid errors) - PRIVATE INTERNAL USE ONLY - """ - try: - link_task = self.link_task - except AttributeError: - pass - else: - for tsk in getattr(tg, 'compiled_tasks', []): - for x in tsk.outputs: - if self.accept_node_to_link(x): - link_task.inputs.append(x) - -@taskgen_method -def get_uselib_vars(self): - """ - :return: the *uselib* variables associated to the *features* attribute (see :py:attr:`waflib.Tools.ccroot.USELIB_VARS`) - :rtype: list of string - """ - _vars = set() - for x in self.features: - if x in USELIB_VARS: - _vars |= USELIB_VARS[x] - return _vars - -@feature('c', 'cxx', 'd', 'fc', 'javac', 'cs', 'uselib', 'asm') -@after_method('process_use') -def propagate_uselib_vars(self): - """ - Process uselib variables for adding flags. For example, the following target:: - - def build(bld): - bld.env.AFLAGS_aaa = ['bar'] - from waflib.Tools.ccroot import USELIB_VARS - USELIB_VARS['aaa'] = ['AFLAGS'] - - tg = bld(features='aaa', aflags='test') - - The *aflags* attribute will be processed and this method will set:: - - tg.env.AFLAGS = ['bar', 'test'] - """ - _vars = self.get_uselib_vars() - env = self.env - app = env.append_value - feature_uselib = self.features + self.to_list(getattr(self, 'uselib', [])) - for var in _vars: - y = var.lower() - val = getattr(self, y, []) - if val: - app(var, self.to_list(val)) - - for x in feature_uselib: - val = env['%s_%s' % (var, x)] - if val: - app(var, val) - -# ============ the code above must not know anything about import libs ========== - -@feature('cshlib', 'cxxshlib', 'fcshlib') -@after_method('apply_link') -def apply_implib(self): - """ - Handle dlls and their import libs on Windows-like systems. - - A ``.dll.a`` file called *import library* is generated. - It must be installed as it is required for linking the library. - """ - if not self.env.DEST_BINFMT == 'pe': - return - - dll = self.link_task.outputs[0] - if isinstance(self.target, Node.Node): - name = self.target.name - else: - name = os.path.split(self.target)[1] - implib = self.env.implib_PATTERN % name - implib = dll.parent.find_or_declare(implib) - self.env.append_value('LINKFLAGS', self.env.IMPLIB_ST % implib.bldpath()) - self.link_task.outputs.append(implib) - - if getattr(self, 'defs', None) and self.env.DEST_BINFMT == 'pe': - node = self.path.find_resource(self.defs) - if not node: - raise Errors.WafError('invalid def file %r' % self.defs) - if self.env.def_PATTERN: - self.env.append_value('LINKFLAGS', self.env.def_PATTERN % node.path_from(self.get_cwd())) - self.link_task.dep_nodes.append(node) - else: - # gcc for windows takes *.def file as input without any special flag - self.link_task.inputs.append(node) - - # where to put the import library - if getattr(self, 'install_task', None): - try: - # user has given a specific installation path for the import library - inst_to = self.install_path_implib - except AttributeError: - try: - # user has given an installation path for the main library, put the import library in it - inst_to = self.install_path - except AttributeError: - # else, put the library in BINDIR and the import library in LIBDIR - inst_to = '${IMPLIBDIR}' - self.install_task.install_to = '${BINDIR}' - if not self.env.IMPLIBDIR: - self.env.IMPLIBDIR = self.env.LIBDIR - self.implib_install_task = self.add_install_files(install_to=inst_to, install_from=implib, - chmod=self.link_task.chmod, task=self.link_task) - -# ============ the code above must not know anything about vnum processing on unix platforms ========= - -re_vnum = re.compile('^([1-9]\\d*|0)([.]([1-9]\\d*|0)){0,2}?$') -@feature('cshlib', 'cxxshlib', 'dshlib', 'fcshlib', 'vnum') -@after_method('apply_link', 'propagate_uselib_vars') -def apply_vnum(self): - """ - Enforce version numbering on shared libraries. The valid version numbers must have either zero or two dots:: - - def build(bld): - bld.shlib(source='a.c', target='foo', vnum='14.15.16') - - In this example on Linux platform, ``libfoo.so`` is installed as ``libfoo.so.14.15.16``, and the following symbolic links are created: - - * ``libfoo.so → libfoo.so.14.15.16`` - * ``libfoo.so.14 → libfoo.so.14.15.16`` - - By default, the library will be assigned SONAME ``libfoo.so.14``, effectively declaring ABI compatibility between all minor and patch releases for the major version of the library. When necessary, the compatibility can be explicitly defined using `cnum` parameter: - - def build(bld): - bld.shlib(source='a.c', target='foo', vnum='14.15.16', cnum='14.15') - - In this case, the assigned SONAME will be ``libfoo.so.14.15`` with ABI compatibility only between path releases for a specific major and minor version of the library. - - On OS X platform, install-name parameter will follow the above logic for SONAME with exception that it also specifies an absolute path (based on install_path) of the library. - """ - if not getattr(self, 'vnum', '') or os.name != 'posix' or self.env.DEST_BINFMT not in ('elf', 'mac-o'): - return - - link = self.link_task - if not re_vnum.match(self.vnum): - raise Errors.WafError('Invalid vnum %r for target %r' % (self.vnum, getattr(self, 'name', self))) - nums = self.vnum.split('.') - node = link.outputs[0] - - cnum = getattr(self, 'cnum', str(nums[0])) - cnums = cnum.split('.') - if len(cnums)>len(nums) or nums[0:len(cnums)] != cnums: - raise Errors.WafError('invalid compatibility version %s' % cnum) - - libname = node.name - if libname.endswith('.dylib'): - name3 = libname.replace('.dylib', '.%s.dylib' % self.vnum) - name2 = libname.replace('.dylib', '.%s.dylib' % cnum) - else: - name3 = libname + '.' + self.vnum - name2 = libname + '.' + cnum - - # add the so name for the ld linker - to disable, just unset env.SONAME_ST - if self.env.SONAME_ST: - v = self.env.SONAME_ST % name2 - self.env.append_value('LINKFLAGS', v.split()) - - # the following task is just to enable execution from the build dir :-/ - if self.env.DEST_OS != 'openbsd': - outs = [node.parent.make_node(name3)] - if name2 != name3: - outs.append(node.parent.make_node(name2)) - self.create_task('vnum', node, outs) - - if getattr(self, 'install_task', None): - self.install_task.hasrun = Task.SKIPPED - self.install_task.no_errcheck_out = True - path = self.install_task.install_to - if self.env.DEST_OS == 'openbsd': - libname = self.link_task.outputs[0].name - t1 = self.add_install_as(install_to='%s/%s' % (path, libname), install_from=node, chmod=self.link_task.chmod) - self.vnum_install_task = (t1,) - else: - t1 = self.add_install_as(install_to=path + os.sep + name3, install_from=node, chmod=self.link_task.chmod) - t3 = self.add_symlink_as(install_to=path + os.sep + libname, install_from=name3) - if name2 != name3: - t2 = self.add_symlink_as(install_to=path + os.sep + name2, install_from=name3) - self.vnum_install_task = (t1, t2, t3) - else: - self.vnum_install_task = (t1, t3) - - if '-dynamiclib' in self.env.LINKFLAGS: - # this requires after(propagate_uselib_vars) - try: - inst_to = self.install_path - except AttributeError: - inst_to = self.link_task.inst_to - if inst_to: - p = Utils.subst_vars(inst_to, self.env) - path = os.path.join(p, name2) - self.env.append_value('LINKFLAGS', ['-install_name', path]) - self.env.append_value('LINKFLAGS', '-Wl,-compatibility_version,%s' % cnum) - self.env.append_value('LINKFLAGS', '-Wl,-current_version,%s' % self.vnum) - -class vnum(Task.Task): - """ - Create the symbolic links for a versioned shared library. Instances are created by :py:func:`waflib.Tools.ccroot.apply_vnum` - """ - color = 'CYAN' - ext_in = ['.bin'] - def keyword(self): - return 'Symlinking' - def run(self): - for x in self.outputs: - path = x.abspath() - try: - os.remove(path) - except OSError: - pass - - try: - os.symlink(self.inputs[0].name, path) - except OSError: - return 1 - -class fake_shlib(link_task): - """ - Task used for reading a system library and adding the dependency on it - """ - def runnable_status(self): - for t in self.run_after: - if not t.hasrun: - return Task.ASK_LATER - return Task.SKIP_ME - -class fake_stlib(stlink_task): - """ - Task used for reading a system library and adding the dependency on it - """ - def runnable_status(self): - for t in self.run_after: - if not t.hasrun: - return Task.ASK_LATER - return Task.SKIP_ME - -@conf -def read_shlib(self, name, paths=[], export_includes=[], export_defines=[]): - """ - Read a system shared library, enabling its use as a local library. Will trigger a rebuild if the file changes:: - - def build(bld): - bld.read_shlib('m') - bld.program(source='main.c', use='m') - """ - return self(name=name, features='fake_lib', lib_paths=paths, lib_type='shlib', export_includes=export_includes, export_defines=export_defines) - -@conf -def read_stlib(self, name, paths=[], export_includes=[], export_defines=[]): - """ - Read a system static library, enabling a use as a local library. Will trigger a rebuild if the file changes. - """ - return self(name=name, features='fake_lib', lib_paths=paths, lib_type='stlib', export_includes=export_includes, export_defines=export_defines) - -lib_patterns = { - 'shlib' : ['lib%s.so', '%s.so', 'lib%s.dylib', 'lib%s.dll', '%s.dll'], - 'stlib' : ['lib%s.a', '%s.a', 'lib%s.dll', '%s.dll', 'lib%s.lib', '%s.lib'], -} - -@feature('fake_lib') -def process_lib(self): - """ - Find the location of a foreign library. Used by :py:class:`waflib.Tools.ccroot.read_shlib` and :py:class:`waflib.Tools.ccroot.read_stlib`. - """ - node = None - - names = [x % self.name for x in lib_patterns[self.lib_type]] - for x in self.lib_paths + [self.path] + SYSTEM_LIB_PATHS: - if not isinstance(x, Node.Node): - x = self.bld.root.find_node(x) or self.path.find_node(x) - if not x: - continue - - for y in names: - node = x.find_node(y) - if node: - try: - Utils.h_file(node.abspath()) - except EnvironmentError: - raise ValueError('Could not read %r' % y) - break - else: - continue - break - else: - raise Errors.WafError('could not find library %r' % self.name) - self.link_task = self.create_task('fake_%s' % self.lib_type, [], [node]) - self.target = self.name - - -class fake_o(Task.Task): - def runnable_status(self): - return Task.SKIP_ME - -@extension('.o', '.obj') -def add_those_o_files(self, node): - tsk = self.create_task('fake_o', [], node) - try: - self.compiled_tasks.append(tsk) - except AttributeError: - self.compiled_tasks = [tsk] - -@feature('fake_obj') -@before_method('process_source') -def process_objs(self): - """ - Puts object files in the task generator outputs - """ - for node in self.to_nodes(self.source): - self.add_those_o_files(node) - self.source = [] - -@conf -def read_object(self, obj): - """ - Read an object file, enabling injection in libs/programs. Will trigger a rebuild if the file changes. - - :param obj: object file path, as string or Node - """ - if not isinstance(obj, self.path.__class__): - obj = self.path.find_resource(obj) - return self(features='fake_obj', source=obj, name=obj.name) - -@feature('cxxprogram', 'cprogram') -@after_method('apply_link', 'process_use') -def set_full_paths_hpux(self): - """ - On hp-ux, extend the libpaths and static library paths to absolute paths - """ - if self.env.DEST_OS != 'hp-ux': - return - base = self.bld.bldnode.abspath() - for var in ['LIBPATH', 'STLIBPATH']: - lst = [] - for x in self.env[var]: - if x.startswith('/'): - lst.append(x) - else: - lst.append(os.path.normpath(os.path.join(base, x))) - self.env[var] = lst - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/clang.py b/ldb-2.0.8/third_party/waf/waflib/Tools/clang.py deleted file mode 100644 index 3828e39..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/clang.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Krzysztof Kosiński 2014 - -""" -Detect the Clang C compiler -""" - -from waflib.Tools import ccroot, ar, gcc -from waflib.Configure import conf - -@conf -def find_clang(conf): - """ - Finds the program clang and executes it to ensure it really is clang - """ - cc = conf.find_program('clang', var='CC') - conf.get_cc_version(cc, clang=True) - conf.env.CC_NAME = 'clang' - -def configure(conf): - conf.find_clang() - conf.find_program(['llvm-ar', 'ar'], var='AR') - conf.find_ar() - conf.gcc_common_flags() - conf.gcc_modifier_platform() - conf.cc_load_tools() - conf.cc_add_flags() - conf.link_add_flags() diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/clangxx.py b/ldb-2.0.8/third_party/waf/waflib/Tools/clangxx.py deleted file mode 100644 index 152013c..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/clangxx.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy 2009-2018 (ita) - -""" -Detect the Clang++ C++ compiler -""" - -from waflib.Tools import ccroot, ar, gxx -from waflib.Configure import conf - -@conf -def find_clangxx(conf): - """ - Finds the program clang++, and executes it to ensure it really is clang++ - """ - cxx = conf.find_program('clang++', var='CXX') - conf.get_cc_version(cxx, clang=True) - conf.env.CXX_NAME = 'clang' - -def configure(conf): - conf.find_clangxx() - conf.find_program(['llvm-ar', 'ar'], var='AR') - conf.find_ar() - conf.gxx_common_flags() - conf.gxx_modifier_platform() - conf.cxx_load_tools() - conf.cxx_add_flags() - conf.link_add_flags() - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_c.py b/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_c.py deleted file mode 100644 index 2dba3f8..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_c.py +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Matthias Jahn jahn dôt matthias ât freenet dôt de, 2007 (pmarat) - -""" -Try to detect a C compiler from the list of supported compilers (gcc, msvc, etc):: - - def options(opt): - opt.load('compiler_c') - def configure(cnf): - cnf.load('compiler_c') - def build(bld): - bld.program(source='main.c', target='app') - -The compilers are associated to platforms in :py:attr:`waflib.Tools.compiler_c.c_compiler`. To register -a new C compiler named *cfoo* (assuming the tool ``waflib/extras/cfoo.py`` exists), use:: - - from waflib.Tools.compiler_c import c_compiler - c_compiler['win32'] = ['cfoo', 'msvc', 'gcc'] - - def options(opt): - opt.load('compiler_c') - def configure(cnf): - cnf.load('compiler_c') - def build(bld): - bld.program(source='main.c', target='app') - -Not all compilers need to have a specific tool. For example, the clang compilers can be detected by the gcc tools when using:: - - $ CC=clang waf configure -""" - -import re -from waflib.Tools import ccroot -from waflib import Utils -from waflib.Logs import debug - -c_compiler = { -'win32': ['msvc', 'gcc', 'clang'], -'cygwin': ['gcc'], -'darwin': ['clang', 'gcc'], -'aix': ['xlc', 'gcc', 'clang'], -'linux': ['gcc', 'clang', 'icc'], -'sunos': ['suncc', 'gcc'], -'irix': ['gcc', 'irixcc'], -'hpux': ['gcc'], -'osf1V': ['gcc'], -'gnu': ['gcc', 'clang'], -'java': ['gcc', 'msvc', 'clang', 'icc'], -'default':['clang', 'gcc'], -} -""" -Dict mapping platform names to Waf tools finding specific C compilers:: - - from waflib.Tools.compiler_c import c_compiler - c_compiler['linux'] = ['gcc', 'icc', 'suncc'] -""" - -def default_compilers(): - build_platform = Utils.unversioned_sys_platform() - possible_compiler_list = c_compiler.get(build_platform, c_compiler['default']) - return ' '.join(possible_compiler_list) - -def configure(conf): - """ - Detects a suitable C compiler - - :raises: :py:class:`waflib.Errors.ConfigurationError` when no suitable compiler is found - """ - try: - test_for_compiler = conf.options.check_c_compiler or default_compilers() - except AttributeError: - conf.fatal("Add options(opt): opt.load('compiler_c')") - - for compiler in re.split('[ ,]+', test_for_compiler): - conf.env.stash() - conf.start_msg('Checking for %r (C compiler)' % compiler) - try: - conf.load(compiler) - except conf.errors.ConfigurationError as e: - conf.env.revert() - conf.end_msg(False) - debug('compiler_c: %r', e) - else: - if conf.env.CC: - conf.end_msg(conf.env.get_flat('CC')) - conf.env.COMPILER_CC = compiler - conf.env.commit() - break - conf.env.revert() - conf.end_msg(False) - else: - conf.fatal('could not configure a C compiler!') - -def options(opt): - """ - This is how to provide compiler preferences on the command-line:: - - $ waf configure --check-c-compiler=gcc - """ - test_for_compiler = default_compilers() - opt.load_special_tools('c_*.py', ban=['c_dumbpreproc.py']) - cc_compiler_opts = opt.add_option_group('Configuration options') - cc_compiler_opts.add_option('--check-c-compiler', default=None, - help='list of C compilers to try [%s]' % test_for_compiler, - dest="check_c_compiler") - - for x in test_for_compiler.split(): - opt.load('%s' % x) - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_cxx.py b/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_cxx.py deleted file mode 100644 index 1af65a2..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_cxx.py +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Matthias Jahn jahn dôt matthias ât freenet dôt de 2007 (pmarat) - -""" -Try to detect a C++ compiler from the list of supported compilers (g++, msvc, etc):: - - def options(opt): - opt.load('compiler_cxx') - def configure(cnf): - cnf.load('compiler_cxx') - def build(bld): - bld.program(source='main.cpp', target='app') - -The compilers are associated to platforms in :py:attr:`waflib.Tools.compiler_cxx.cxx_compiler`. To register -a new C++ compiler named *cfoo* (assuming the tool ``waflib/extras/cfoo.py`` exists), use:: - - from waflib.Tools.compiler_cxx import cxx_compiler - cxx_compiler['win32'] = ['cfoo', 'msvc', 'gcc'] - - def options(opt): - opt.load('compiler_cxx') - def configure(cnf): - cnf.load('compiler_cxx') - def build(bld): - bld.program(source='main.c', target='app') - -Not all compilers need to have a specific tool. For example, the clang compilers can be detected by the gcc tools when using:: - - $ CXX=clang waf configure -""" - - -import re -from waflib.Tools import ccroot -from waflib import Utils -from waflib.Logs import debug - -cxx_compiler = { -'win32': ['msvc', 'g++', 'clang++'], -'cygwin': ['g++'], -'darwin': ['clang++', 'g++'], -'aix': ['xlc++', 'g++', 'clang++'], -'linux': ['g++', 'clang++', 'icpc'], -'sunos': ['sunc++', 'g++'], -'irix': ['g++'], -'hpux': ['g++'], -'osf1V': ['g++'], -'gnu': ['g++', 'clang++'], -'java': ['g++', 'msvc', 'clang++', 'icpc'], -'default': ['clang++', 'g++'] -} -""" -Dict mapping the platform names to Waf tools finding specific C++ compilers:: - - from waflib.Tools.compiler_cxx import cxx_compiler - cxx_compiler['linux'] = ['gxx', 'icpc', 'suncxx'] -""" - -def default_compilers(): - build_platform = Utils.unversioned_sys_platform() - possible_compiler_list = cxx_compiler.get(build_platform, cxx_compiler['default']) - return ' '.join(possible_compiler_list) - -def configure(conf): - """ - Detects a suitable C++ compiler - - :raises: :py:class:`waflib.Errors.ConfigurationError` when no suitable compiler is found - """ - try: - test_for_compiler = conf.options.check_cxx_compiler or default_compilers() - except AttributeError: - conf.fatal("Add options(opt): opt.load('compiler_cxx')") - - for compiler in re.split('[ ,]+', test_for_compiler): - conf.env.stash() - conf.start_msg('Checking for %r (C++ compiler)' % compiler) - try: - conf.load(compiler) - except conf.errors.ConfigurationError as e: - conf.env.revert() - conf.end_msg(False) - debug('compiler_cxx: %r', e) - else: - if conf.env.CXX: - conf.end_msg(conf.env.get_flat('CXX')) - conf.env.COMPILER_CXX = compiler - conf.env.commit() - break - conf.env.revert() - conf.end_msg(False) - else: - conf.fatal('could not configure a C++ compiler!') - -def options(opt): - """ - This is how to provide compiler preferences on the command-line:: - - $ waf configure --check-cxx-compiler=gxx - """ - test_for_compiler = default_compilers() - opt.load_special_tools('cxx_*.py') - cxx_compiler_opts = opt.add_option_group('Configuration options') - cxx_compiler_opts.add_option('--check-cxx-compiler', default=None, - help='list of C++ compilers to try [%s]' % test_for_compiler, - dest="check_cxx_compiler") - - for x in test_for_compiler.split(): - opt.load('%s' % x) - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_d.py b/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_d.py deleted file mode 100644 index 43bb1f6..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_d.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Carlos Rafael Giani, 2007 (dv) -# Thomas Nagy, 2016-2018 (ita) - -""" -Try to detect a D compiler from the list of supported compilers:: - - def options(opt): - opt.load('compiler_d') - def configure(cnf): - cnf.load('compiler_d') - def build(bld): - bld.program(source='main.d', target='app') - -Only three D compilers are really present at the moment: - -* gdc -* dmd, the ldc compiler having a very similar command-line interface -* ldc2 -""" - -import re -from waflib import Utils, Logs - -d_compiler = { -'default' : ['gdc', 'dmd', 'ldc2'] -} -""" -Dict mapping the platform names to lists of names of D compilers to try, in order of preference:: - - from waflib.Tools.compiler_d import d_compiler - d_compiler['default'] = ['gdc', 'dmd', 'ldc2'] -""" - -def default_compilers(): - build_platform = Utils.unversioned_sys_platform() - possible_compiler_list = d_compiler.get(build_platform, d_compiler['default']) - return ' '.join(possible_compiler_list) - -def configure(conf): - """ - Detects a suitable D compiler - - :raises: :py:class:`waflib.Errors.ConfigurationError` when no suitable compiler is found - """ - try: - test_for_compiler = conf.options.check_d_compiler or default_compilers() - except AttributeError: - conf.fatal("Add options(opt): opt.load('compiler_d')") - - for compiler in re.split('[ ,]+', test_for_compiler): - conf.env.stash() - conf.start_msg('Checking for %r (D compiler)' % compiler) - try: - conf.load(compiler) - except conf.errors.ConfigurationError as e: - conf.env.revert() - conf.end_msg(False) - Logs.debug('compiler_d: %r', e) - else: - if conf.env.D: - conf.end_msg(conf.env.get_flat('D')) - conf.env.COMPILER_D = compiler - conf.env.commit() - break - conf.env.revert() - conf.end_msg(False) - else: - conf.fatal('could not configure a D compiler!') - -def options(opt): - """ - This is how to provide compiler preferences on the command-line:: - - $ waf configure --check-d-compiler=dmd - """ - test_for_compiler = default_compilers() - d_compiler_opts = opt.add_option_group('Configuration options') - d_compiler_opts.add_option('--check-d-compiler', default=None, - help='list of D compilers to try [%s]' % test_for_compiler, dest='check_d_compiler') - - for x in test_for_compiler.split(): - opt.load('%s' % x) - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_fc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_fc.py deleted file mode 100644 index 96b58e7..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/compiler_fc.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 - -import re -from waflib import Utils, Logs -from waflib.Tools import fc - -fc_compiler = { - 'win32' : ['gfortran','ifort'], - 'darwin' : ['gfortran', 'g95', 'ifort'], - 'linux' : ['gfortran', 'g95', 'ifort'], - 'java' : ['gfortran', 'g95', 'ifort'], - 'default': ['gfortran'], - 'aix' : ['gfortran'] -} -""" -Dict mapping the platform names to lists of names of Fortran compilers to try, in order of preference:: - - from waflib.Tools.compiler_c import c_compiler - c_compiler['linux'] = ['gfortran', 'g95', 'ifort'] -""" - -def default_compilers(): - build_platform = Utils.unversioned_sys_platform() - possible_compiler_list = fc_compiler.get(build_platform, fc_compiler['default']) - return ' '.join(possible_compiler_list) - -def configure(conf): - """ - Detects a suitable Fortran compiler - - :raises: :py:class:`waflib.Errors.ConfigurationError` when no suitable compiler is found - """ - try: - test_for_compiler = conf.options.check_fortran_compiler or default_compilers() - except AttributeError: - conf.fatal("Add options(opt): opt.load('compiler_fc')") - for compiler in re.split('[ ,]+', test_for_compiler): - conf.env.stash() - conf.start_msg('Checking for %r (Fortran compiler)' % compiler) - try: - conf.load(compiler) - except conf.errors.ConfigurationError as e: - conf.env.revert() - conf.end_msg(False) - Logs.debug('compiler_fortran: %r', e) - else: - if conf.env.FC: - conf.end_msg(conf.env.get_flat('FC')) - conf.env.COMPILER_FORTRAN = compiler - conf.env.commit() - break - conf.env.revert() - conf.end_msg(False) - else: - conf.fatal('could not configure a Fortran compiler!') - -def options(opt): - """ - This is how to provide compiler preferences on the command-line:: - - $ waf configure --check-fortran-compiler=ifort - """ - test_for_compiler = default_compilers() - opt.load_special_tools('fc_*.py') - fortran_compiler_opts = opt.add_option_group('Configuration options') - fortran_compiler_opts.add_option('--check-fortran-compiler', default=None, - help='list of Fortran compiler to try [%s]' % test_for_compiler, - dest="check_fortran_compiler") - - for x in test_for_compiler.split(): - opt.load('%s' % x) - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/cs.py b/ldb-2.0.8/third_party/waf/waflib/Tools/cs.py deleted file mode 100644 index aecca6d..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/cs.py +++ /dev/null @@ -1,211 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2006-2018 (ita) - -""" -C# support. A simple example:: - - def configure(conf): - conf.load('cs') - def build(bld): - bld(features='cs', source='main.cs', gen='foo') - -Note that the configuration may compile C# snippets:: - - FRAG = ''' - namespace Moo { - public class Test { public static int Main(string[] args) { return 0; } } - }''' - def configure(conf): - conf.check(features='cs', fragment=FRAG, compile_filename='test.cs', gen='test.exe', - bintype='exe', csflags=['-pkg:gtk-sharp-2.0'], msg='Checking for Gtksharp support') -""" - -from waflib import Utils, Task, Options, Errors -from waflib.TaskGen import before_method, after_method, feature -from waflib.Tools import ccroot -from waflib.Configure import conf - -ccroot.USELIB_VARS['cs'] = set(['CSFLAGS', 'ASSEMBLIES', 'RESOURCES']) -ccroot.lib_patterns['csshlib'] = ['%s'] - -@feature('cs') -@before_method('process_source') -def apply_cs(self): - """ - Create a C# task bound to the attribute *cs_task*. There can be only one C# task by task generator. - """ - cs_nodes = [] - no_nodes = [] - for x in self.to_nodes(self.source): - if x.name.endswith('.cs'): - cs_nodes.append(x) - else: - no_nodes.append(x) - self.source = no_nodes - - bintype = getattr(self, 'bintype', self.gen.endswith('.dll') and 'library' or 'exe') - self.cs_task = tsk = self.create_task('mcs', cs_nodes, self.path.find_or_declare(self.gen)) - tsk.env.CSTYPE = '/target:%s' % bintype - tsk.env.OUT = '/out:%s' % tsk.outputs[0].abspath() - self.env.append_value('CSFLAGS', '/platform:%s' % getattr(self, 'platform', 'anycpu')) - - inst_to = getattr(self, 'install_path', bintype=='exe' and '${BINDIR}' or '${LIBDIR}') - if inst_to: - # note: we are making a copy, so the files added to cs_task.outputs won't be installed automatically - mod = getattr(self, 'chmod', bintype=='exe' and Utils.O755 or Utils.O644) - self.install_task = self.add_install_files(install_to=inst_to, install_from=self.cs_task.outputs[:], chmod=mod) - -@feature('cs') -@after_method('apply_cs') -def use_cs(self): - """ - C# applications honor the **use** keyword:: - - def build(bld): - bld(features='cs', source='My.cs', bintype='library', gen='my.dll', name='mylib') - bld(features='cs', source='Hi.cs', includes='.', bintype='exe', gen='hi.exe', use='mylib', name='hi') - """ - names = self.to_list(getattr(self, 'use', [])) - get = self.bld.get_tgen_by_name - for x in names: - try: - y = get(x) - except Errors.WafError: - self.env.append_value('CSFLAGS', '/reference:%s' % x) - continue - y.post() - - tsk = getattr(y, 'cs_task', None) or getattr(y, 'link_task', None) - if not tsk: - self.bld.fatal('cs task has no link task for use %r' % self) - self.cs_task.dep_nodes.extend(tsk.outputs) # dependency - self.cs_task.set_run_after(tsk) # order (redundant, the order is inferred from the nodes inputs/outputs) - self.env.append_value('CSFLAGS', '/reference:%s' % tsk.outputs[0].abspath()) - -@feature('cs') -@after_method('apply_cs', 'use_cs') -def debug_cs(self): - """ - The C# targets may create .mdb or .pdb files:: - - def build(bld): - bld(features='cs', source='My.cs', bintype='library', gen='my.dll', csdebug='full') - # csdebug is a value in (True, 'full', 'pdbonly') - """ - csdebug = getattr(self, 'csdebug', self.env.CSDEBUG) - if not csdebug: - return - - node = self.cs_task.outputs[0] - if self.env.CS_NAME == 'mono': - out = node.parent.find_or_declare(node.name + '.mdb') - else: - out = node.change_ext('.pdb') - self.cs_task.outputs.append(out) - - if getattr(self, 'install_task', None): - self.pdb_install_task = self.add_install_files( - install_to=self.install_task.install_to, install_from=out) - - if csdebug == 'pdbonly': - val = ['/debug+', '/debug:pdbonly'] - elif csdebug == 'full': - val = ['/debug+', '/debug:full'] - else: - val = ['/debug-'] - self.env.append_value('CSFLAGS', val) - -@feature('cs') -@after_method('debug_cs') -def doc_cs(self): - """ - The C# targets may create .xml documentation files:: - - def build(bld): - bld(features='cs', source='My.cs', bintype='library', gen='my.dll', csdoc=True) - # csdoc is a boolean value - """ - csdoc = getattr(self, 'csdoc', self.env.CSDOC) - if not csdoc: - return - - node = self.cs_task.outputs[0] - out = node.change_ext('.xml') - self.cs_task.outputs.append(out) - - if getattr(self, 'install_task', None): - self.doc_install_task = self.add_install_files( - install_to=self.install_task.install_to, install_from=out) - - self.env.append_value('CSFLAGS', '/doc:%s' % out.abspath()) - -class mcs(Task.Task): - """ - Compile C# files - """ - color = 'YELLOW' - run_str = '${MCS} ${CSTYPE} ${CSFLAGS} ${ASS_ST:ASSEMBLIES} ${RES_ST:RESOURCES} ${OUT} ${SRC}' - - def split_argfile(self, cmd): - inline = [cmd[0]] - infile = [] - for x in cmd[1:]: - # csc doesn't want /noconfig in @file - if x.lower() == '/noconfig': - inline.append(x) - else: - infile.append(self.quote_flag(x)) - return (inline, infile) - -def configure(conf): - """ - Find a C# compiler, set the variable MCS for the compiler and CS_NAME (mono or csc) - """ - csc = getattr(Options.options, 'cscbinary', None) - if csc: - conf.env.MCS = csc - conf.find_program(['csc', 'mcs', 'gmcs'], var='MCS') - conf.env.ASS_ST = '/r:%s' - conf.env.RES_ST = '/resource:%s' - - conf.env.CS_NAME = 'csc' - if str(conf.env.MCS).lower().find('mcs') > -1: - conf.env.CS_NAME = 'mono' - -def options(opt): - """ - Add a command-line option for the configuration:: - - $ waf configure --with-csc-binary=/foo/bar/mcs - """ - opt.add_option('--with-csc-binary', type='string', dest='cscbinary') - -class fake_csshlib(Task.Task): - """ - Task used for reading a foreign .net assembly and adding the dependency on it - """ - color = 'YELLOW' - inst_to = None - - def runnable_status(self): - return Task.SKIP_ME - -@conf -def read_csshlib(self, name, paths=[]): - """ - Read a foreign .net assembly for the *use* system:: - - def build(bld): - bld.read_csshlib('ManagedLibrary.dll', paths=[bld.env.mylibrarypath]) - bld(features='cs', source='Hi.cs', bintype='exe', gen='hi.exe', use='ManagedLibrary.dll') - - :param name: Name of the library - :type name: string - :param paths: Folders in which the library may be found - :type paths: list of string - :return: A task generator having the feature *fake_lib* which will call :py:func:`waflib.Tools.ccroot.process_lib` - :rtype: :py:class:`waflib.TaskGen.task_gen` - """ - return self(name=name, features='fake_lib', lib_paths=paths, lib_type='csshlib') - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/cxx.py b/ldb-2.0.8/third_party/waf/waflib/Tools/cxx.py deleted file mode 100644 index 194fad7..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/cxx.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2005-2018 (ita) - -"Base for c++ programs and libraries" - -from waflib import TaskGen, Task -from waflib.Tools import c_preproc -from waflib.Tools.ccroot import link_task, stlink_task - -@TaskGen.extension('.cpp','.cc','.cxx','.C','.c++') -def cxx_hook(self, node): - "Binds c++ file extensions to create :py:class:`waflib.Tools.cxx.cxx` instances" - return self.create_compiled_task('cxx', node) - -if not '.c' in TaskGen.task_gen.mappings: - TaskGen.task_gen.mappings['.c'] = TaskGen.task_gen.mappings['.cpp'] - -class cxx(Task.Task): - "Compiles C++ files into object files" - run_str = '${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT[0].abspath()} ${CPPFLAGS}' - vars = ['CXXDEPS'] # unused variable to depend on, just in case - ext_in = ['.h'] # set the build order easily by using ext_out=['.h'] - scan = c_preproc.scan - -class cxxprogram(link_task): - "Links object files into c++ programs" - run_str = '${LINK_CXX} ${LINKFLAGS} ${CXXLNK_SRC_F}${SRC} ${CXXLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LDFLAGS}' - vars = ['LINKDEPS'] - ext_out = ['.bin'] - inst_to = '${BINDIR}' - -class cxxshlib(cxxprogram): - "Links object files into c++ shared libraries" - inst_to = '${LIBDIR}' - -class cxxstlib(stlink_task): - "Links object files into c++ static libraries" - pass # do not remove - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/d.py b/ldb-2.0.8/third_party/waf/waflib/Tools/d.py deleted file mode 100644 index e4cf73b..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/d.py +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Carlos Rafael Giani, 2007 (dv) -# Thomas Nagy, 2007-2018 (ita) - -from waflib import Utils, Task, Errors -from waflib.TaskGen import taskgen_method, feature, extension -from waflib.Tools import d_scan, d_config -from waflib.Tools.ccroot import link_task, stlink_task - -class d(Task.Task): - "Compile a d file into an object file" - color = 'GREEN' - run_str = '${D} ${DFLAGS} ${DINC_ST:INCPATHS} ${D_SRC_F:SRC} ${D_TGT_F:TGT}' - scan = d_scan.scan - -class d_with_header(d): - "Compile a d file and generate a header" - run_str = '${D} ${DFLAGS} ${DINC_ST:INCPATHS} ${D_HDR_F:tgt.outputs[1].bldpath()} ${D_SRC_F:SRC} ${D_TGT_F:tgt.outputs[0].bldpath()}' - -class d_header(Task.Task): - "Compile d headers" - color = 'BLUE' - run_str = '${D} ${D_HEADER} ${SRC}' - -class dprogram(link_task): - "Link object files into a d program" - run_str = '${D_LINKER} ${LINKFLAGS} ${DLNK_SRC_F}${SRC} ${DLNK_TGT_F:TGT} ${RPATH_ST:RPATH} ${DSTLIB_MARKER} ${DSTLIBPATH_ST:STLIBPATH} ${DSTLIB_ST:STLIB} ${DSHLIB_MARKER} ${DLIBPATH_ST:LIBPATH} ${DSHLIB_ST:LIB}' - inst_to = '${BINDIR}' - -class dshlib(dprogram): - "Link object files into a d shared library" - inst_to = '${LIBDIR}' - -class dstlib(stlink_task): - "Link object files into a d static library" - pass # do not remove - -@extension('.d', '.di', '.D') -def d_hook(self, node): - """ - Compile *D* files. To get .di files as well as .o files, set the following:: - - def build(bld): - bld.program(source='foo.d', target='app', generate_headers=True) - - """ - ext = Utils.destos_to_binfmt(self.env.DEST_OS) == 'pe' and 'obj' or 'o' - out = '%s.%d.%s' % (node.name, self.idx, ext) - def create_compiled_task(self, name, node): - task = self.create_task(name, node, node.parent.find_or_declare(out)) - try: - self.compiled_tasks.append(task) - except AttributeError: - self.compiled_tasks = [task] - return task - - if getattr(self, 'generate_headers', None): - tsk = create_compiled_task(self, 'd_with_header', node) - tsk.outputs.append(node.change_ext(self.env.DHEADER_ext)) - else: - tsk = create_compiled_task(self, 'd', node) - return tsk - -@taskgen_method -def generate_header(self, filename): - """ - See feature request #104:: - - def build(bld): - tg = bld.program(source='foo.d', target='app') - tg.generate_header('blah.d') - # is equivalent to: - #tg = bld.program(source='foo.d', target='app', header_lst='blah.d') - - :param filename: header to create - :type filename: string - """ - try: - self.header_lst.append([filename, self.install_path]) - except AttributeError: - self.header_lst = [[filename, self.install_path]] - -@feature('d') -def process_header(self): - """ - Process the attribute 'header_lst' to create the d header compilation tasks:: - - def build(bld): - bld.program(source='foo.d', target='app', header_lst='blah.d') - """ - for i in getattr(self, 'header_lst', []): - node = self.path.find_resource(i[0]) - if not node: - raise Errors.WafError('file %r not found on d obj' % i[0]) - self.create_task('d_header', node, node.change_ext('.di')) - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/d_config.py b/ldb-2.0.8/third_party/waf/waflib/Tools/d_config.py deleted file mode 100644 index 6637556..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/d_config.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2016-2018 (ita) - -from waflib import Utils -from waflib.Configure import conf - -@conf -def d_platform_flags(self): - """ - Sets the extensions dll/so for d programs and libraries - """ - v = self.env - if not v.DEST_OS: - v.DEST_OS = Utils.unversioned_sys_platform() - binfmt = Utils.destos_to_binfmt(self.env.DEST_OS) - if binfmt == 'pe': - v.dprogram_PATTERN = '%s.exe' - v.dshlib_PATTERN = 'lib%s.dll' - v.dstlib_PATTERN = 'lib%s.a' - elif binfmt == 'mac-o': - v.dprogram_PATTERN = '%s' - v.dshlib_PATTERN = 'lib%s.dylib' - v.dstlib_PATTERN = 'lib%s.a' - else: - v.dprogram_PATTERN = '%s' - v.dshlib_PATTERN = 'lib%s.so' - v.dstlib_PATTERN = 'lib%s.a' - -DLIB = ''' -version(D_Version2) { - import std.stdio; - int main() { - writefln("phobos2"); - return 0; - } -} else { - version(Tango) { - import tango.stdc.stdio; - int main() { - printf("tango"); - return 0; - } - } else { - import std.stdio; - int main() { - writefln("phobos1"); - return 0; - } - } -} -''' -"""Detection string for the D standard library""" - -@conf -def check_dlibrary(self, execute=True): - """ - Detects the kind of standard library that comes with the compiler, - and sets conf.env.DLIBRARY to tango, phobos1 or phobos2 - """ - ret = self.check_cc(features='d dprogram', fragment=DLIB, compile_filename='test.d', execute=execute, define_ret=True) - if execute: - self.env.DLIBRARY = ret.strip() - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/d_scan.py b/ldb-2.0.8/third_party/waf/waflib/Tools/d_scan.py deleted file mode 100644 index 4e807a6..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/d_scan.py +++ /dev/null @@ -1,211 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2016-2018 (ita) - -""" -Provide a scanner for finding dependencies on d files -""" - -import re -from waflib import Utils - -def filter_comments(filename): - """ - :param filename: d file name - :type filename: string - :rtype: list - :return: a list of characters - """ - txt = Utils.readf(filename) - i = 0 - buf = [] - max = len(txt) - begin = 0 - while i < max: - c = txt[i] - if c == '"' or c == "'": # skip a string or character literal - buf.append(txt[begin:i]) - delim = c - i += 1 - while i < max: - c = txt[i] - if c == delim: - break - elif c == '\\': # skip the character following backslash - i += 1 - i += 1 - i += 1 - begin = i - elif c == '/': # try to replace a comment with whitespace - buf.append(txt[begin:i]) - i += 1 - if i == max: - break - c = txt[i] - if c == '+': # eat nesting /+ +/ comment - i += 1 - nesting = 1 - c = None - while i < max: - prev = c - c = txt[i] - if prev == '/' and c == '+': - nesting += 1 - c = None - elif prev == '+' and c == '/': - nesting -= 1 - if nesting == 0: - break - c = None - i += 1 - elif c == '*': # eat /* */ comment - i += 1 - c = None - while i < max: - prev = c - c = txt[i] - if prev == '*' and c == '/': - break - i += 1 - elif c == '/': # eat // comment - i += 1 - while i < max and txt[i] != '\n': - i += 1 - else: # no comment - begin = i - 1 - continue - i += 1 - begin = i - buf.append(' ') - else: - i += 1 - buf.append(txt[begin:]) - return buf - -class d_parser(object): - """ - Parser for d files - """ - def __init__(self, env, incpaths): - #self.code = '' - #self.module = '' - #self.imports = [] - - self.allnames = [] - - self.re_module = re.compile(r"module\s+([^;]+)") - self.re_import = re.compile(r"import\s+([^;]+)") - self.re_import_bindings = re.compile("([^:]+):(.*)") - self.re_import_alias = re.compile("[^=]+=(.+)") - - self.env = env - - self.nodes = [] - self.names = [] - - self.incpaths = incpaths - - def tryfind(self, filename): - """ - Search file a file matching an module/import directive - - :param filename: file to read - :type filename: string - """ - found = 0 - for n in self.incpaths: - found = n.find_resource(filename.replace('.', '/') + '.d') - if found: - self.nodes.append(found) - self.waiting.append(found) - break - if not found: - if not filename in self.names: - self.names.append(filename) - - def get_strings(self, code): - """ - :param code: d code to parse - :type code: string - :return: the modules that the code uses - :rtype: a list of match objects - """ - #self.imports = [] - self.module = '' - lst = [] - - # get the module name (if present) - - mod_name = self.re_module.search(code) - if mod_name: - self.module = re.sub(r'\s+', '', mod_name.group(1)) # strip all whitespaces - - # go through the code, have a look at all import occurrences - - # first, lets look at anything beginning with "import" and ending with ";" - import_iterator = self.re_import.finditer(code) - if import_iterator: - for import_match in import_iterator: - import_match_str = re.sub(r'\s+', '', import_match.group(1)) # strip all whitespaces - - # does this end with an import bindings declaration? - # (import bindings always terminate the list of imports) - bindings_match = self.re_import_bindings.match(import_match_str) - if bindings_match: - import_match_str = bindings_match.group(1) - # if so, extract the part before the ":" (since the module declaration(s) is/are located there) - - # split the matching string into a bunch of strings, separated by a comma - matches = import_match_str.split(',') - - for match in matches: - alias_match = self.re_import_alias.match(match) - if alias_match: - # is this an alias declaration? (alias = module name) if so, extract the module name - match = alias_match.group(1) - - lst.append(match) - return lst - - def start(self, node): - """ - The parsing starts here - - :param node: input file - :type node: :py:class:`waflib.Node.Node` - """ - self.waiting = [node] - # while the stack is not empty, add the dependencies - while self.waiting: - nd = self.waiting.pop(0) - self.iter(nd) - - def iter(self, node): - """ - Find all the modules that a file depends on, uses :py:meth:`waflib.Tools.d_scan.d_parser.tryfind` to process dependent files - - :param node: input file - :type node: :py:class:`waflib.Node.Node` - """ - path = node.abspath() # obtain the absolute path - code = "".join(filter_comments(path)) # read the file and filter the comments - names = self.get_strings(code) # obtain the import strings - for x in names: - # optimization - if x in self.allnames: - continue - self.allnames.append(x) - - # for each name, see if it is like a node or not - self.tryfind(x) - -def scan(self): - "look for .d/.di used by a d file" - env = self.env - gruik = d_parser(env, self.generator.includes_nodes) - node = self.inputs[0] - gruik.start(node) - nodes = gruik.nodes - names = gruik.names - return (nodes, names) - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/dbus.py b/ldb-2.0.8/third_party/waf/waflib/Tools/dbus.py deleted file mode 100644 index d520f1c..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/dbus.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Ali Sabil, 2007 - -""" -Compiles dbus files with **dbus-binding-tool** - -Typical usage:: - - def options(opt): - opt.load('compiler_c dbus') - def configure(conf): - conf.load('compiler_c dbus') - def build(bld): - tg = bld.program( - includes = '.', - source = bld.path.ant_glob('*.c'), - target = 'gnome-hello') - tg.add_dbus_file('test.xml', 'test_prefix', 'glib-server') -""" - -from waflib import Task, Errors -from waflib.TaskGen import taskgen_method, before_method - -@taskgen_method -def add_dbus_file(self, filename, prefix, mode): - """ - Adds a dbus file to the list of dbus files to process. Store them in the attribute *dbus_lst*. - - :param filename: xml file to compile - :type filename: string - :param prefix: dbus binding tool prefix (--prefix=prefix) - :type prefix: string - :param mode: dbus binding tool mode (--mode=mode) - :type mode: string - """ - if not hasattr(self, 'dbus_lst'): - self.dbus_lst = [] - if not 'process_dbus' in self.meths: - self.meths.append('process_dbus') - self.dbus_lst.append([filename, prefix, mode]) - -@before_method('process_source') -def process_dbus(self): - """ - Processes the dbus files stored in the attribute *dbus_lst* to create :py:class:`waflib.Tools.dbus.dbus_binding_tool` instances. - """ - for filename, prefix, mode in getattr(self, 'dbus_lst', []): - node = self.path.find_resource(filename) - if not node: - raise Errors.WafError('file not found ' + filename) - tsk = self.create_task('dbus_binding_tool', node, node.change_ext('.h')) - tsk.env.DBUS_BINDING_TOOL_PREFIX = prefix - tsk.env.DBUS_BINDING_TOOL_MODE = mode - -class dbus_binding_tool(Task.Task): - """ - Compiles a dbus file - """ - color = 'BLUE' - ext_out = ['.h'] - run_str = '${DBUS_BINDING_TOOL} --prefix=${DBUS_BINDING_TOOL_PREFIX} --mode=${DBUS_BINDING_TOOL_MODE} --output=${TGT} ${SRC}' - shell = True # temporary workaround for #795 - -def configure(conf): - """ - Detects the program dbus-binding-tool and sets ``conf.env.DBUS_BINDING_TOOL`` - """ - conf.find_program('dbus-binding-tool', var='DBUS_BINDING_TOOL') - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/dmd.py b/ldb-2.0.8/third_party/waf/waflib/Tools/dmd.py deleted file mode 100644 index 8917ca1..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/dmd.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Carlos Rafael Giani, 2007 (dv) -# Thomas Nagy, 2008-2018 (ita) - -import sys -from waflib.Tools import ar, d -from waflib.Configure import conf - -@conf -def find_dmd(conf): - """ - Finds the program *dmd*, *dmd2*, or *ldc* and set the variable *D* - """ - conf.find_program(['dmd', 'dmd2', 'ldc'], var='D') - - # make sure that we're dealing with dmd1, dmd2, or ldc(1) - out = conf.cmd_and_log(conf.env.D + ['--help']) - if out.find("D Compiler v") == -1: - out = conf.cmd_and_log(conf.env.D + ['-version']) - if out.find("based on DMD v1.") == -1: - conf.fatal("detected compiler is not dmd/ldc") - -@conf -def common_flags_ldc(conf): - """ - Sets the D flags required by *ldc* - """ - v = conf.env - v.DFLAGS = ['-d-version=Posix'] - v.LINKFLAGS = [] - v.DFLAGS_dshlib = ['-relocation-model=pic'] - -@conf -def common_flags_dmd(conf): - """ - Set the flags required by *dmd* or *dmd2* - """ - v = conf.env - - v.D_SRC_F = ['-c'] - v.D_TGT_F = '-of%s' - - v.D_LINKER = v.D - v.DLNK_SRC_F = '' - v.DLNK_TGT_F = '-of%s' - v.DINC_ST = '-I%s' - - v.DSHLIB_MARKER = v.DSTLIB_MARKER = '' - v.DSTLIB_ST = v.DSHLIB_ST = '-L-l%s' - v.DSTLIBPATH_ST = v.DLIBPATH_ST = '-L-L%s' - - v.LINKFLAGS_dprogram= ['-quiet'] - - v.DFLAGS_dshlib = ['-fPIC'] - v.LINKFLAGS_dshlib = ['-L-shared'] - - v.DHEADER_ext = '.di' - v.DFLAGS_d_with_header = ['-H', '-Hf'] - v.D_HDR_F = '%s' - -def configure(conf): - """ - Configuration for *dmd*, *dmd2*, and *ldc* - """ - conf.find_dmd() - - if sys.platform == 'win32': - out = conf.cmd_and_log(conf.env.D + ['--help']) - if out.find('D Compiler v2.') > -1: - conf.fatal('dmd2 on Windows is not supported, use gdc or ldc2 instead') - - conf.load('ar') - conf.load('d') - conf.common_flags_dmd() - conf.d_platform_flags() - - if str(conf.env.D).find('ldc') > -1: - conf.common_flags_ldc() - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/errcheck.py b/ldb-2.0.8/third_party/waf/waflib/Tools/errcheck.py deleted file mode 100644 index de8d75a..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/errcheck.py +++ /dev/null @@ -1,237 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2011 (ita) - -""" -Common mistakes highlighting. - -There is a performance impact, so this tool is only loaded when running ``waf -v`` -""" - -typos = { -'feature':'features', -'sources':'source', -'targets':'target', -'include':'includes', -'export_include':'export_includes', -'define':'defines', -'importpath':'includes', -'installpath':'install_path', -'iscopy':'is_copy', -'uses':'use', -} - -meths_typos = ['__call__', 'program', 'shlib', 'stlib', 'objects'] - -import sys -from waflib import Logs, Build, Node, Task, TaskGen, ConfigSet, Errors, Utils -from waflib.Tools import ccroot - -def check_same_targets(self): - mp = Utils.defaultdict(list) - uids = {} - - def check_task(tsk): - if not isinstance(tsk, Task.Task): - return - if hasattr(tsk, 'no_errcheck_out'): - return - - for node in tsk.outputs: - mp[node].append(tsk) - try: - uids[tsk.uid()].append(tsk) - except KeyError: - uids[tsk.uid()] = [tsk] - - for g in self.groups: - for tg in g: - try: - for tsk in tg.tasks: - check_task(tsk) - except AttributeError: - # raised if not a task generator, which should be uncommon - check_task(tg) - - dupe = False - for (k, v) in mp.items(): - if len(v) > 1: - dupe = True - msg = '* Node %r is created more than once%s. The task generators are:' % (k, Logs.verbose == 1 and " (full message on 'waf -v -v')" or "") - Logs.error(msg) - for x in v: - if Logs.verbose > 1: - Logs.error(' %d. %r', 1 + v.index(x), x.generator) - else: - Logs.error(' %d. %r in %r', 1 + v.index(x), x.generator.name, getattr(x.generator, 'path', None)) - Logs.error('If you think that this is an error, set no_errcheck_out on the task instance') - - if not dupe: - for (k, v) in uids.items(): - if len(v) > 1: - Logs.error('* Several tasks use the same identifier. Please check the information on\n https://waf.io/apidocs/Task.html?highlight=uid#waflib.Task.Task.uid') - tg_details = tsk.generator.name - if Logs.verbose > 2: - tg_details = tsk.generator - for tsk in v: - Logs.error(' - object %r (%r) defined in %r', tsk.__class__.__name__, tsk, tg_details) - -def check_invalid_constraints(self): - feat = set() - for x in list(TaskGen.feats.values()): - feat.union(set(x)) - for (x, y) in TaskGen.task_gen.prec.items(): - feat.add(x) - feat.union(set(y)) - ext = set() - for x in TaskGen.task_gen.mappings.values(): - ext.add(x.__name__) - invalid = ext & feat - if invalid: - Logs.error('The methods %r have invalid annotations: @extension <-> @feature/@before_method/@after_method', list(invalid)) - - # the build scripts have been read, so we can check for invalid after/before attributes on task classes - for cls in list(Task.classes.values()): - if sys.hexversion > 0x3000000 and issubclass(cls, Task.Task) and isinstance(cls.hcode, str): - raise Errors.WafError('Class %r has hcode value %r of type , expecting (use Utils.h_cmd() ?)' % (cls, cls.hcode)) - - for x in ('before', 'after'): - for y in Utils.to_list(getattr(cls, x, [])): - if not Task.classes.get(y): - Logs.error('Erroneous order constraint %r=%r on task class %r', x, y, cls.__name__) - if getattr(cls, 'rule', None): - Logs.error('Erroneous attribute "rule" on task class %r (rename to "run_str")', cls.__name__) - -def replace(m): - """ - Replaces existing BuildContext methods to verify parameter names, - for example ``bld(source=)`` has no ending *s* - """ - oldcall = getattr(Build.BuildContext, m) - def call(self, *k, **kw): - ret = oldcall(self, *k, **kw) - for x in typos: - if x in kw: - if x == 'iscopy' and 'subst' in getattr(self, 'features', ''): - continue - Logs.error('Fix the typo %r -> %r on %r', x, typos[x], ret) - return ret - setattr(Build.BuildContext, m, call) - -def enhance_lib(): - """ - Modifies existing classes and methods to enable error verification - """ - for m in meths_typos: - replace(m) - - # catch '..' in ant_glob patterns - def ant_glob(self, *k, **kw): - if k: - lst = Utils.to_list(k[0]) - for pat in lst: - sp = pat.split('/') - if '..' in sp: - Logs.error("In ant_glob pattern %r: '..' means 'two dots', not 'parent directory'", k[0]) - if '.' in sp: - Logs.error("In ant_glob pattern %r: '.' means 'one dot', not 'current directory'", k[0]) - return self.old_ant_glob(*k, **kw) - Node.Node.old_ant_glob = Node.Node.ant_glob - Node.Node.ant_glob = ant_glob - - # catch ant_glob on build folders - def ant_iter(self, accept=None, maxdepth=25, pats=[], dir=False, src=True, remove=True, quiet=False): - if remove: - try: - if self.is_child_of(self.ctx.bldnode) and not quiet: - quiet = True - Logs.error('Calling ant_glob on build folders (%r) is dangerous: add quiet=True / remove=False', self) - except AttributeError: - pass - return self.old_ant_iter(accept, maxdepth, pats, dir, src, remove, quiet) - Node.Node.old_ant_iter = Node.Node.ant_iter - Node.Node.ant_iter = ant_iter - - # catch conflicting ext_in/ext_out/before/after declarations - old = Task.is_before - def is_before(t1, t2): - ret = old(t1, t2) - if ret and old(t2, t1): - Logs.error('Contradictory order constraints in classes %r %r', t1, t2) - return ret - Task.is_before = is_before - - # check for bld(feature='cshlib') where no 'c' is given - this can be either a mistake or on purpose - # so we only issue a warning - def check_err_features(self): - lst = self.to_list(self.features) - if 'shlib' in lst: - Logs.error('feature shlib -> cshlib, dshlib or cxxshlib') - for x in ('c', 'cxx', 'd', 'fc'): - if not x in lst and lst and lst[0] in [x+y for y in ('program', 'shlib', 'stlib')]: - Logs.error('%r features is probably missing %r', self, x) - TaskGen.feature('*')(check_err_features) - - # check for erroneous order constraints - def check_err_order(self): - if not hasattr(self, 'rule') and not 'subst' in Utils.to_list(self.features): - for x in ('before', 'after', 'ext_in', 'ext_out'): - if hasattr(self, x): - Logs.warn('Erroneous order constraint %r on non-rule based task generator %r', x, self) - else: - for x in ('before', 'after'): - for y in self.to_list(getattr(self, x, [])): - if not Task.classes.get(y): - Logs.error('Erroneous order constraint %s=%r on %r (no such class)', x, y, self) - TaskGen.feature('*')(check_err_order) - - # check for @extension used with @feature/@before_method/@after_method - def check_compile(self): - check_invalid_constraints(self) - try: - ret = self.orig_compile() - finally: - check_same_targets(self) - return ret - Build.BuildContext.orig_compile = Build.BuildContext.compile - Build.BuildContext.compile = check_compile - - # check for invalid build groups #914 - def use_rec(self, name, **kw): - try: - y = self.bld.get_tgen_by_name(name) - except Errors.WafError: - pass - else: - idx = self.bld.get_group_idx(self) - odx = self.bld.get_group_idx(y) - if odx > idx: - msg = "Invalid 'use' across build groups:" - if Logs.verbose > 1: - msg += '\n target %r\n uses:\n %r' % (self, y) - else: - msg += " %r uses %r (try 'waf -v -v' for the full error)" % (self.name, name) - raise Errors.WafError(msg) - self.orig_use_rec(name, **kw) - TaskGen.task_gen.orig_use_rec = TaskGen.task_gen.use_rec - TaskGen.task_gen.use_rec = use_rec - - # check for env.append - def _getattr(self, name, default=None): - if name == 'append' or name == 'add': - raise Errors.WafError('env.append and env.add do not exist: use env.append_value/env.append_unique') - elif name == 'prepend': - raise Errors.WafError('env.prepend does not exist: use env.prepend_value') - if name in self.__slots__: - return super(ConfigSet.ConfigSet, self).__getattr__(name, default) - else: - return self[name] - ConfigSet.ConfigSet.__getattr__ = _getattr - - -def options(opt): - """ - Error verification can be enabled by default (not just on ``waf -v``) by adding to the user script options - """ - enhance_lib() - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/fc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/fc.py deleted file mode 100644 index fd4d39c..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/fc.py +++ /dev/null @@ -1,203 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# DC 2008 -# Thomas Nagy 2016-2018 (ita) - -""" -Fortran support -""" - -from waflib import Utils, Task, Errors -from waflib.Tools import ccroot, fc_config, fc_scan -from waflib.TaskGen import extension -from waflib.Configure import conf - -ccroot.USELIB_VARS['fc'] = set(['FCFLAGS', 'DEFINES', 'INCLUDES', 'FCPPFLAGS']) -ccroot.USELIB_VARS['fcprogram_test'] = ccroot.USELIB_VARS['fcprogram'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS']) -ccroot.USELIB_VARS['fcshlib'] = set(['LIB', 'STLIB', 'LIBPATH', 'STLIBPATH', 'LINKFLAGS', 'RPATH', 'LINKDEPS']) -ccroot.USELIB_VARS['fcstlib'] = set(['ARFLAGS', 'LINKDEPS']) - -@extension('.f','.F','.f90','.F90','.for','.FOR','.f95','.F95','.f03','.F03','.f08','.F08') -def fc_hook(self, node): - "Binds the Fortran file extensions create :py:class:`waflib.Tools.fc.fc` instances" - return self.create_compiled_task('fc', node) - -@conf -def modfile(conf, name): - """ - Turns a module name into the right module file name. - Defaults to all lower case. - """ - if name.find(':') >= 0: - # Depending on a submodule! - separator = conf.env.FC_SUBMOD_SEPARATOR or '@' - # Ancestors of the submodule will be prefixed to the - # submodule name, separated by a colon. - modpath = name.split(':') - # Only the ancestor (actual) module and the submodule name - # will be used for the filename. - modname = modpath[0] + separator + modpath[-1] - suffix = conf.env.FC_SUBMOD_SUFFIX or '.smod' - else: - modname = name - suffix = '.mod' - - return {'lower' :modname.lower() + suffix.lower(), - 'lower.MOD' :modname.lower() + suffix.upper(), - 'UPPER.mod' :modname.upper() + suffix.lower(), - 'UPPER' :modname.upper() + suffix.upper()}[conf.env.FC_MOD_CAPITALIZATION or 'lower'] - -def get_fortran_tasks(tsk): - """ - Obtains all fortran tasks from the same build group. Those tasks must not have - the attribute 'nomod' or 'mod_fortran_done' - - :return: a list of :py:class:`waflib.Tools.fc.fc` instances - """ - bld = tsk.generator.bld - tasks = bld.get_tasks_group(bld.get_group_idx(tsk.generator)) - return [x for x in tasks if isinstance(x, fc) and not getattr(x, 'nomod', None) and not getattr(x, 'mod_fortran_done', None)] - -class fc(Task.Task): - """ - Fortran tasks can only run when all fortran tasks in a current task group are ready to be executed - This may cause a deadlock if some fortran task is waiting for something that cannot happen (circular dependency) - Should this ever happen, set the 'nomod=True' on those tasks instances to break the loop - """ - color = 'GREEN' - run_str = '${FC} ${FCFLAGS} ${FCINCPATH_ST:INCPATHS} ${FCDEFINES_ST:DEFINES} ${_FCMODOUTFLAGS} ${FC_TGT_F}${TGT[0].abspath()} ${FC_SRC_F}${SRC[0].abspath()} ${FCPPFLAGS}' - vars = ["FORTRANMODPATHFLAG"] - - def scan(self): - """Fortran dependency scanner""" - tmp = fc_scan.fortran_parser(self.generator.includes_nodes) - tmp.task = self - tmp.start(self.inputs[0]) - return (tmp.nodes, tmp.names) - - def runnable_status(self): - """ - Sets the mod file outputs and the dependencies on the mod files over all Fortran tasks - executed by the main thread so there are no concurrency issues - """ - if getattr(self, 'mod_fortran_done', None): - return super(fc, self).runnable_status() - - # now, if we reach this part it is because this fortran task is the first in the list - bld = self.generator.bld - - # obtain the fortran tasks - lst = get_fortran_tasks(self) - - # disable this method for other tasks - for tsk in lst: - tsk.mod_fortran_done = True - - # wait for all the .f tasks to be ready for execution - # and ensure that the scanners are called at least once - for tsk in lst: - ret = tsk.runnable_status() - if ret == Task.ASK_LATER: - # we have to wait for one of the other fortran tasks to be ready - # this may deadlock if there are dependencies between fortran tasks - # but this should not happen (we are setting them here!) - for x in lst: - x.mod_fortran_done = None - - return Task.ASK_LATER - - ins = Utils.defaultdict(set) - outs = Utils.defaultdict(set) - - # the .mod files to create - for tsk in lst: - key = tsk.uid() - for x in bld.raw_deps[key]: - if x.startswith('MOD@'): - name = bld.modfile(x.replace('MOD@', '')) - node = bld.srcnode.find_or_declare(name) - tsk.set_outputs(node) - outs[node].add(tsk) - - # the .mod files to use - for tsk in lst: - key = tsk.uid() - for x in bld.raw_deps[key]: - if x.startswith('USE@'): - name = bld.modfile(x.replace('USE@', '')) - node = bld.srcnode.find_resource(name) - if node and node not in tsk.outputs: - if not node in bld.node_deps[key]: - bld.node_deps[key].append(node) - ins[node].add(tsk) - - # if the intersection matches, set the order - for k in ins.keys(): - for a in ins[k]: - a.run_after.update(outs[k]) - for x in outs[k]: - self.generator.bld.producer.revdeps[x].add(a) - - # the scanner cannot output nodes, so we have to set them - # ourselves as task.dep_nodes (additional input nodes) - tmp = [] - for t in outs[k]: - tmp.extend(t.outputs) - a.dep_nodes.extend(tmp) - a.dep_nodes.sort(key=lambda x: x.abspath()) - - # the task objects have changed: clear the signature cache - for tsk in lst: - try: - delattr(tsk, 'cache_sig') - except AttributeError: - pass - - return super(fc, self).runnable_status() - -class fcprogram(ccroot.link_task): - """Links Fortran programs""" - color = 'YELLOW' - run_str = '${FC} ${LINKFLAGS} ${FCLNK_SRC_F}${SRC} ${FCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FCSTLIB_MARKER} ${FCSTLIBPATH_ST:STLIBPATH} ${FCSTLIB_ST:STLIB} ${FCSHLIB_MARKER} ${FCLIBPATH_ST:LIBPATH} ${FCLIB_ST:LIB} ${LDFLAGS}' - inst_to = '${BINDIR}' - -class fcshlib(fcprogram): - """Links Fortran libraries""" - inst_to = '${LIBDIR}' - -class fcstlib(ccroot.stlink_task): - """Links Fortran static libraries (uses ar by default)""" - pass # do not remove the pass statement - -class fcprogram_test(fcprogram): - """Custom link task to obtain compiler outputs for Fortran configuration tests""" - - def runnable_status(self): - """This task is always executed""" - ret = super(fcprogram_test, self).runnable_status() - if ret == Task.SKIP_ME: - ret = Task.RUN_ME - return ret - - def exec_command(self, cmd, **kw): - """Stores the compiler std our/err onto the build context, to bld.out + bld.err""" - bld = self.generator.bld - - kw['shell'] = isinstance(cmd, str) - kw['stdout'] = kw['stderr'] = Utils.subprocess.PIPE - kw['cwd'] = self.get_cwd() - bld.out = bld.err = '' - - bld.to_log('command: %s\n' % cmd) - - kw['output'] = 0 - try: - (bld.out, bld.err) = bld.cmd_and_log(cmd, **kw) - except Errors.WafError: - return -1 - - if bld.out: - bld.to_log('out: %s\n' % bld.out) - if bld.err: - bld.to_log('err: %s\n' % bld.err) - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/fc_config.py b/ldb-2.0.8/third_party/waf/waflib/Tools/fc_config.py deleted file mode 100644 index dc5e5c9..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/fc_config.py +++ /dev/null @@ -1,488 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# DC 2008 -# Thomas Nagy 2016-2018 (ita) - -""" -Fortran configuration helpers -""" - -import re, os, sys, shlex -from waflib.Configure import conf -from waflib.TaskGen import feature, before_method - -FC_FRAGMENT = ' program main\n end program main\n' -FC_FRAGMENT2 = ' PROGRAM MAIN\n END\n' # what's the actual difference between these? - -@conf -def fc_flags(conf): - """ - Defines common fortran configuration flags and file extensions - """ - v = conf.env - - v.FC_SRC_F = [] - v.FC_TGT_F = ['-c', '-o'] - v.FCINCPATH_ST = '-I%s' - v.FCDEFINES_ST = '-D%s' - - if not v.LINK_FC: - v.LINK_FC = v.FC - - v.FCLNK_SRC_F = [] - v.FCLNK_TGT_F = ['-o'] - - v.FCFLAGS_fcshlib = ['-fpic'] - v.LINKFLAGS_fcshlib = ['-shared'] - v.fcshlib_PATTERN = 'lib%s.so' - - v.fcstlib_PATTERN = 'lib%s.a' - - v.FCLIB_ST = '-l%s' - v.FCLIBPATH_ST = '-L%s' - v.FCSTLIB_ST = '-l%s' - v.FCSTLIBPATH_ST = '-L%s' - v.FCSTLIB_MARKER = '-Wl,-Bstatic' - v.FCSHLIB_MARKER = '-Wl,-Bdynamic' - - v.SONAME_ST = '-Wl,-h,%s' - -@conf -def fc_add_flags(conf): - """ - Adds FCFLAGS / LDFLAGS / LINKFLAGS from os.environ to conf.env - """ - conf.add_os_flags('FCPPFLAGS', dup=False) - conf.add_os_flags('FCFLAGS', dup=False) - conf.add_os_flags('LINKFLAGS', dup=False) - conf.add_os_flags('LDFLAGS', dup=False) - -@conf -def check_fortran(self, *k, **kw): - """ - Compiles a Fortran program to ensure that the settings are correct - """ - self.check_cc( - fragment = FC_FRAGMENT, - compile_filename = 'test.f', - features = 'fc fcprogram', - msg = 'Compiling a simple fortran app') - -@conf -def check_fc(self, *k, **kw): - """ - Same as :py:func:`waflib.Tools.c_config.check` but defaults to the *Fortran* programming language - (this overrides the C defaults in :py:func:`waflib.Tools.c_config.validate_c`) - """ - kw['compiler'] = 'fc' - if not 'compile_mode' in kw: - kw['compile_mode'] = 'fc' - if not 'type' in kw: - kw['type'] = 'fcprogram' - if not 'compile_filename' in kw: - kw['compile_filename'] = 'test.f90' - if not 'code' in kw: - kw['code'] = FC_FRAGMENT - return self.check(*k, **kw) - -# ------------------------------------------------------------------------ -# --- These are the default platform modifiers, refactored here for -# convenience. gfortran and g95 have much overlap. -# ------------------------------------------------------------------------ - -@conf -def fortran_modifier_darwin(conf): - """ - Defines Fortran flags and extensions for OSX systems - """ - v = conf.env - v.FCFLAGS_fcshlib = ['-fPIC'] - v.LINKFLAGS_fcshlib = ['-dynamiclib'] - v.fcshlib_PATTERN = 'lib%s.dylib' - v.FRAMEWORKPATH_ST = '-F%s' - v.FRAMEWORK_ST = ['-framework'] - - v.LINKFLAGS_fcstlib = [] - - v.FCSHLIB_MARKER = '' - v.FCSTLIB_MARKER = '' - v.SONAME_ST = '' - -@conf -def fortran_modifier_win32(conf): - """ - Defines Fortran flags for Windows platforms - """ - v = conf.env - v.fcprogram_PATTERN = v.fcprogram_test_PATTERN = '%s.exe' - - v.fcshlib_PATTERN = '%s.dll' - v.implib_PATTERN = '%s.dll.a' - v.IMPLIB_ST = '-Wl,--out-implib,%s' - - v.FCFLAGS_fcshlib = [] - - # Auto-import is enabled by default even without this option, - # but enabling it explicitly has the nice effect of suppressing the rather boring, debug-level messages - # that the linker emits otherwise. - v.append_value('LINKFLAGS', ['-Wl,--enable-auto-import']) - -@conf -def fortran_modifier_cygwin(conf): - """ - Defines Fortran flags for use on cygwin - """ - fortran_modifier_win32(conf) - v = conf.env - v.fcshlib_PATTERN = 'cyg%s.dll' - v.append_value('LINKFLAGS_fcshlib', ['-Wl,--enable-auto-image-base']) - v.FCFLAGS_fcshlib = [] - -# ------------------------------------------------------------------------ - -@conf -def check_fortran_dummy_main(self, *k, **kw): - """ - Determines if a main function is needed by compiling a code snippet with - the C compiler and linking it with the Fortran compiler (useful on unix-like systems) - """ - if not self.env.CC: - self.fatal('A c compiler is required for check_fortran_dummy_main') - - lst = ['MAIN__', '__MAIN', '_MAIN', 'MAIN_', 'MAIN'] - lst.extend([m.lower() for m in lst]) - lst.append('') - - self.start_msg('Detecting whether we need a dummy main') - for main in lst: - kw['fortran_main'] = main - try: - self.check_cc( - fragment = 'int %s() { return 0; }\n' % (main or 'test'), - features = 'c fcprogram', - mandatory = True - ) - if not main: - self.env.FC_MAIN = -1 - self.end_msg('no') - else: - self.env.FC_MAIN = main - self.end_msg('yes %s' % main) - break - except self.errors.ConfigurationError: - pass - else: - self.end_msg('not found') - self.fatal('could not detect whether fortran requires a dummy main, see the config.log') - -# ------------------------------------------------------------------------ - -GCC_DRIVER_LINE = re.compile('^Driving:') -POSIX_STATIC_EXT = re.compile(r'\S+\.a') -POSIX_LIB_FLAGS = re.compile(r'-l\S+') - -@conf -def is_link_verbose(self, txt): - """Returns True if 'useful' link options can be found in txt""" - assert isinstance(txt, str) - for line in txt.splitlines(): - if not GCC_DRIVER_LINE.search(line): - if POSIX_STATIC_EXT.search(line) or POSIX_LIB_FLAGS.search(line): - return True - return False - -@conf -def check_fortran_verbose_flag(self, *k, **kw): - """ - Checks what kind of verbose (-v) flag works, then sets it to env.FC_VERBOSE_FLAG - """ - self.start_msg('fortran link verbose flag') - for x in ('-v', '--verbose', '-verbose', '-V'): - try: - self.check_cc( - features = 'fc fcprogram_test', - fragment = FC_FRAGMENT2, - compile_filename = 'test.f', - linkflags = [x], - mandatory=True) - except self.errors.ConfigurationError: - pass - else: - # output is on stderr or stdout (for xlf) - if self.is_link_verbose(self.test_bld.err) or self.is_link_verbose(self.test_bld.out): - self.end_msg(x) - break - else: - self.end_msg('failure') - self.fatal('Could not obtain the fortran link verbose flag (see config.log)') - - self.env.FC_VERBOSE_FLAG = x - return x - -# ------------------------------------------------------------------------ - -# linkflags which match those are ignored -LINKFLAGS_IGNORED = [r'-lang*', r'-lcrt[a-zA-Z0-9\.]*\.o', r'-lc$', r'-lSystem', r'-libmil', r'-LIST:*', r'-LNO:*'] -if os.name == 'nt': - LINKFLAGS_IGNORED.extend([r'-lfrt*', r'-luser32', r'-lkernel32', r'-ladvapi32', r'-lmsvcrt', r'-lshell32', r'-lmingw', r'-lmoldname']) -else: - LINKFLAGS_IGNORED.append(r'-lgcc*') -RLINKFLAGS_IGNORED = [re.compile(f) for f in LINKFLAGS_IGNORED] - -def _match_ignore(line): - """Returns True if the line should be ignored (Fortran verbose flag test)""" - for i in RLINKFLAGS_IGNORED: - if i.match(line): - return True - return False - -def parse_fortran_link(lines): - """Given the output of verbose link of Fortran compiler, this returns a - list of flags necessary for linking using the standard linker.""" - final_flags = [] - for line in lines: - if not GCC_DRIVER_LINE.match(line): - _parse_flink_line(line, final_flags) - return final_flags - -SPACE_OPTS = re.compile('^-[LRuYz]$') -NOSPACE_OPTS = re.compile('^-[RL]') - -def _parse_flink_token(lexer, token, tmp_flags): - # Here we go (convention for wildcard is shell, not regex !) - # 1 TODO: we first get some root .a libraries - # 2 TODO: take everything starting by -bI:* - # 3 Ignore the following flags: -lang* | -lcrt*.o | -lc | - # -lgcc* | -lSystem | -libmil | -LANG:=* | -LIST:* | -LNO:*) - # 4 take into account -lkernel32 - # 5 For options of the kind -[[LRuYz]], as they take one argument - # after, the actual option is the next token - # 6 For -YP,*: take and replace by -Larg where arg is the old - # argument - # 7 For -[lLR]*: take - - # step 3 - if _match_ignore(token): - pass - # step 4 - elif token.startswith('-lkernel32') and sys.platform == 'cygwin': - tmp_flags.append(token) - # step 5 - elif SPACE_OPTS.match(token): - t = lexer.get_token() - if t.startswith('P,'): - t = t[2:] - for opt in t.split(os.pathsep): - tmp_flags.append('-L%s' % opt) - # step 6 - elif NOSPACE_OPTS.match(token): - tmp_flags.append(token) - # step 7 - elif POSIX_LIB_FLAGS.match(token): - tmp_flags.append(token) - else: - # ignore anything not explicitly taken into account - pass - - t = lexer.get_token() - return t - -def _parse_flink_line(line, final_flags): - """private""" - lexer = shlex.shlex(line, posix = True) - lexer.whitespace_split = True - - t = lexer.get_token() - tmp_flags = [] - while t: - t = _parse_flink_token(lexer, t, tmp_flags) - - final_flags.extend(tmp_flags) - return final_flags - -@conf -def check_fortran_clib(self, autoadd=True, *k, **kw): - """ - Obtains the flags for linking with the C library - if this check works, add uselib='CLIB' to your task generators - """ - if not self.env.FC_VERBOSE_FLAG: - self.fatal('env.FC_VERBOSE_FLAG is not set: execute check_fortran_verbose_flag?') - - self.start_msg('Getting fortran runtime link flags') - try: - self.check_cc( - fragment = FC_FRAGMENT2, - compile_filename = 'test.f', - features = 'fc fcprogram_test', - linkflags = [self.env.FC_VERBOSE_FLAG] - ) - except Exception: - self.end_msg(False) - if kw.get('mandatory', True): - conf.fatal('Could not find the c library flags') - else: - out = self.test_bld.err - flags = parse_fortran_link(out.splitlines()) - self.end_msg('ok (%s)' % ' '.join(flags)) - self.env.LINKFLAGS_CLIB = flags - return flags - return [] - -def getoutput(conf, cmd, stdin=False): - """ - Obtains Fortran command outputs - """ - from waflib import Errors - if conf.env.env: - env = conf.env.env - else: - env = dict(os.environ) - env['LANG'] = 'C' - input = stdin and '\n'.encode() or None - try: - out, err = conf.cmd_and_log(cmd, env=env, output=0, input=input) - except Errors.WafError as e: - # An WafError might indicate an error code during the command - # execution, in this case we still obtain the stderr and stdout, - # which we can use to find the version string. - if not (hasattr(e, 'stderr') and hasattr(e, 'stdout')): - raise e - else: - # Ignore the return code and return the original - # stdout and stderr. - out = e.stdout - err = e.stderr - except Exception: - conf.fatal('could not determine the compiler version %r' % cmd) - return (out, err) - -# ------------------------------------------------------------------------ - -ROUTINES_CODE = """\ - subroutine foobar() - return - end - subroutine foo_bar() - return - end -""" - -MAIN_CODE = """ -void %(dummy_func_nounder)s(void); -void %(dummy_func_under)s(void); -int %(main_func_name)s() { - %(dummy_func_nounder)s(); - %(dummy_func_under)s(); - return 0; -} -""" - -@feature('link_main_routines_func') -@before_method('process_source') -def link_main_routines_tg_method(self): - """ - The configuration test declares a unique task generator, - so we create other task generators from there for fortran link tests - """ - def write_test_file(task): - task.outputs[0].write(task.generator.code) - bld = self.bld - bld(rule=write_test_file, target='main.c', code=MAIN_CODE % self.__dict__) - bld(rule=write_test_file, target='test.f', code=ROUTINES_CODE) - bld(features='fc fcstlib', source='test.f', target='test') - bld(features='c fcprogram', source='main.c', target='app', use='test') - -def mangling_schemes(): - """ - Generate triplets for use with mangle_name - (used in check_fortran_mangling) - the order is tuned for gfortan - """ - for u in ('_', ''): - for du in ('', '_'): - for c in ("lower", "upper"): - yield (u, du, c) - -def mangle_name(u, du, c, name): - """Mangle a name from a triplet (used in check_fortran_mangling)""" - return getattr(name, c)() + u + (name.find('_') != -1 and du or '') - -@conf -def check_fortran_mangling(self, *k, **kw): - """ - Detect the mangling scheme, sets FORTRAN_MANGLING to the triplet found - - This test will compile a fortran static library, then link a c app against it - """ - if not self.env.CC: - self.fatal('A c compiler is required for link_main_routines') - if not self.env.FC: - self.fatal('A fortran compiler is required for link_main_routines') - if not self.env.FC_MAIN: - self.fatal('Checking for mangling requires self.env.FC_MAIN (execute "check_fortran_dummy_main" first?)') - - self.start_msg('Getting fortran mangling scheme') - for (u, du, c) in mangling_schemes(): - try: - self.check_cc( - compile_filename = [], - features = 'link_main_routines_func', - msg = 'nomsg', - errmsg = 'nomsg', - dummy_func_nounder = mangle_name(u, du, c, 'foobar'), - dummy_func_under = mangle_name(u, du, c, 'foo_bar'), - main_func_name = self.env.FC_MAIN - ) - except self.errors.ConfigurationError: - pass - else: - self.end_msg("ok ('%s', '%s', '%s-case')" % (u, du, c)) - self.env.FORTRAN_MANGLING = (u, du, c) - break - else: - self.end_msg(False) - self.fatal('mangler not found') - return (u, du, c) - -@feature('pyext') -@before_method('propagate_uselib_vars', 'apply_link') -def set_lib_pat(self): - """Sets the Fortran flags for linking with Python""" - self.env.fcshlib_PATTERN = self.env.pyext_PATTERN - -@conf -def detect_openmp(self): - """ - Detects openmp flags and sets the OPENMP ``FCFLAGS``/``LINKFLAGS`` - """ - for x in ('-fopenmp','-openmp','-mp','-xopenmp','-omp','-qsmp=omp'): - try: - self.check_fc( - msg = 'Checking for OpenMP flag %s' % x, - fragment = 'program main\n call omp_get_num_threads()\nend program main', - fcflags = x, - linkflags = x, - uselib_store = 'OPENMP' - ) - except self.errors.ConfigurationError: - pass - else: - break - else: - self.fatal('Could not find OpenMP') - -@conf -def check_gfortran_o_space(self): - if self.env.FC_NAME != 'GFORTRAN' or int(self.env.FC_VERSION[0]) > 4: - # This is for old compilers and only for gfortran. - # No idea how other implementations handle this. Be safe and bail out. - return - self.env.stash() - self.env.FCLNK_TGT_F = ['-o', ''] - try: - self.check_fc(msg='Checking if the -o link must be split from arguments', fragment=FC_FRAGMENT, features='fc fcshlib') - except self.errors.ConfigurationError: - self.env.revert() - else: - self.env.commit() diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/fc_scan.py b/ldb-2.0.8/third_party/waf/waflib/Tools/fc_scan.py deleted file mode 100644 index 0824c92..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/fc_scan.py +++ /dev/null @@ -1,120 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# DC 2008 -# Thomas Nagy 2016-2018 (ita) - -import re - -INC_REGEX = r"""(?:^|['">]\s*;)\s*(?:|#\s*)INCLUDE\s+(?:\w+_)?[<"'](.+?)(?=["'>])""" -USE_REGEX = r"""(?:^|;)\s*USE(?:\s+|(?:(?:\s*,\s*(?:NON_)?INTRINSIC)?\s*::))\s*(\w+)""" -MOD_REGEX = r"""(?:^|;)\s*MODULE(?!\s+(?:PROCEDURE|SUBROUTINE|FUNCTION))\s+(\w+)""" -SMD_REGEX = r"""(?:^|;)\s*SUBMODULE\s*\(([\w:]+)\)\s*(\w+)""" - -re_inc = re.compile(INC_REGEX, re.I) -re_use = re.compile(USE_REGEX, re.I) -re_mod = re.compile(MOD_REGEX, re.I) -re_smd = re.compile(SMD_REGEX, re.I) - -class fortran_parser(object): - """ - This parser returns: - - * the nodes corresponding to the module names to produce - * the nodes corresponding to the include files used - * the module names used by the fortran files - """ - def __init__(self, incpaths): - self.seen = [] - """Files already parsed""" - - self.nodes = [] - """List of :py:class:`waflib.Node.Node` representing the dependencies to return""" - - self.names = [] - """List of module names to return""" - - self.incpaths = incpaths - """List of :py:class:`waflib.Node.Node` representing the include paths""" - - def find_deps(self, node): - """ - Parses a Fortran file to obtain the dependencies used/provided - - :param node: fortran file to read - :type node: :py:class:`waflib.Node.Node` - :return: lists representing the includes, the modules used, and the modules created by a fortran file - :rtype: tuple of list of strings - """ - txt = node.read() - incs = [] - uses = [] - mods = [] - for line in txt.splitlines(): - # line by line regexp search? optimize? - m = re_inc.search(line) - if m: - incs.append(m.group(1)) - m = re_use.search(line) - if m: - uses.append(m.group(1)) - m = re_mod.search(line) - if m: - mods.append(m.group(1)) - m = re_smd.search(line) - if m: - uses.append(m.group(1)) - mods.append('{0}:{1}'.format(m.group(1),m.group(2))) - return (incs, uses, mods) - - def start(self, node): - """ - Start parsing. Use the stack ``self.waiting`` to hold nodes to iterate on - - :param node: fortran file - :type node: :py:class:`waflib.Node.Node` - """ - self.waiting = [node] - while self.waiting: - nd = self.waiting.pop(0) - self.iter(nd) - - def iter(self, node): - """ - Processes a single file during dependency parsing. Extracts files used - modules used and modules provided. - """ - incs, uses, mods = self.find_deps(node) - for x in incs: - if x in self.seen: - continue - self.seen.append(x) - self.tryfind_header(x) - - for x in uses: - name = "USE@%s" % x - if not name in self.names: - self.names.append(name) - - for x in mods: - name = "MOD@%s" % x - if not name in self.names: - self.names.append(name) - - def tryfind_header(self, filename): - """ - Adds an include file to the list of nodes to process - - :param filename: file name - :type filename: string - """ - found = None - for n in self.incpaths: - found = n.find_resource(filename) - if found: - self.nodes.append(found) - self.waiting.append(found) - break - if not found: - if not filename in self.names: - self.names.append(filename) - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/flex.py b/ldb-2.0.8/third_party/waf/waflib/Tools/flex.py deleted file mode 100644 index 2256657..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/flex.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# John O'Meara, 2006 -# Thomas Nagy, 2006-2018 (ita) - -""" -The **flex** program is a code generator which creates C or C++ files. -The generated files are compiled into object files. -""" - -import os, re -from waflib import Task, TaskGen -from waflib.Tools import ccroot - -def decide_ext(self, node): - if 'cxx' in self.features: - return ['.lex.cc'] - return ['.lex.c'] - -def flexfun(tsk): - env = tsk.env - bld = tsk.generator.bld - wd = bld.variant_dir - def to_list(xx): - if isinstance(xx, str): - return [xx] - return xx - tsk.last_cmd = lst = [] - lst.extend(to_list(env.FLEX)) - lst.extend(to_list(env.FLEXFLAGS)) - inputs = [a.path_from(tsk.get_cwd()) for a in tsk.inputs] - if env.FLEX_MSYS: - inputs = [x.replace(os.sep, '/') for x in inputs] - lst.extend(inputs) - lst = [x for x in lst if x] - txt = bld.cmd_and_log(lst, cwd=wd, env=env.env or None, quiet=0) - tsk.outputs[0].write(txt.replace('\r\n', '\n').replace('\r', '\n')) # issue #1207 - -TaskGen.declare_chain( - name = 'flex', - rule = flexfun, # issue #854 - ext_in = '.l', - decider = decide_ext, -) - -# To support the following: -# bld(features='c', flexflags='-P/foo') -Task.classes['flex'].vars = ['FLEXFLAGS', 'FLEX'] -ccroot.USELIB_VARS['c'].add('FLEXFLAGS') -ccroot.USELIB_VARS['cxx'].add('FLEXFLAGS') - -def configure(conf): - """ - Detect the *flex* program - """ - conf.find_program('flex', var='FLEX') - conf.env.FLEXFLAGS = ['-t'] - - if re.search (r"\\msys\\[0-9.]+\\bin\\flex.exe$", conf.env.FLEX[0]): - # this is the flex shipped with MSYS - conf.env.FLEX_MSYS = True - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/g95.py b/ldb-2.0.8/third_party/waf/waflib/Tools/g95.py deleted file mode 100644 index f69ba4f..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/g95.py +++ /dev/null @@ -1,66 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# KWS 2010 -# Thomas Nagy 2016-2018 (ita) - -import re -from waflib import Utils -from waflib.Tools import fc, fc_config, fc_scan, ar -from waflib.Configure import conf - -@conf -def find_g95(conf): - fc = conf.find_program('g95', var='FC') - conf.get_g95_version(fc) - conf.env.FC_NAME = 'G95' - -@conf -def g95_flags(conf): - v = conf.env - v.FCFLAGS_fcshlib = ['-fPIC'] - v.FORTRANMODFLAG = ['-fmod=', ''] # template for module path - v.FCFLAGS_DEBUG = ['-Werror'] # why not - -@conf -def g95_modifier_win32(conf): - fc_config.fortran_modifier_win32(conf) - -@conf -def g95_modifier_cygwin(conf): - fc_config.fortran_modifier_cygwin(conf) - -@conf -def g95_modifier_darwin(conf): - fc_config.fortran_modifier_darwin(conf) - -@conf -def g95_modifier_platform(conf): - dest_os = conf.env.DEST_OS or Utils.unversioned_sys_platform() - g95_modifier_func = getattr(conf, 'g95_modifier_' + dest_os, None) - if g95_modifier_func: - g95_modifier_func() - -@conf -def get_g95_version(conf, fc): - """get the compiler version""" - - version_re = re.compile(r"g95\s*(?P\d*)\.(?P\d*)").search - cmd = fc + ['--version'] - out, err = fc_config.getoutput(conf, cmd, stdin=False) - if out: - match = version_re(out) - else: - match = version_re(err) - if not match: - conf.fatal('cannot determine g95 version') - k = match.groupdict() - conf.env.FC_VERSION = (k['major'], k['minor']) - -def configure(conf): - conf.find_g95() - conf.find_ar() - conf.fc_flags() - conf.fc_add_flags() - conf.g95_flags() - conf.g95_modifier_platform() - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/gas.py b/ldb-2.0.8/third_party/waf/waflib/Tools/gas.py deleted file mode 100644 index 4a8745a..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/gas.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2008-2018 (ita) - -"Detect as/gas/gcc for compiling assembly files" - -import waflib.Tools.asm # - leave this -from waflib.Tools import ar - -def configure(conf): - """ - Find the programs gas/as/gcc and set the variable *AS* - """ - conf.find_program(['gas', 'gcc'], var='AS') - conf.env.AS_TGT_F = ['-c', '-o'] - conf.env.ASLNK_TGT_F = ['-o'] - conf.find_ar() - conf.load('asm') - conf.env.ASM_NAME = 'gas' diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/gcc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/gcc.py deleted file mode 100644 index acdd473..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/gcc.py +++ /dev/null @@ -1,156 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2006-2018 (ita) -# Ralf Habacker, 2006 (rh) -# Yinon Ehrlich, 2009 - -""" -gcc/llvm detection. -""" - -from waflib.Tools import ccroot, ar -from waflib.Configure import conf - -@conf -def find_gcc(conf): - """ - Find the program gcc, and if present, try to detect its version number - """ - cc = conf.find_program(['gcc', 'cc'], var='CC') - conf.get_cc_version(cc, gcc=True) - conf.env.CC_NAME = 'gcc' - -@conf -def gcc_common_flags(conf): - """ - Common flags for gcc on nearly all platforms - """ - v = conf.env - - v.CC_SRC_F = [] - v.CC_TGT_F = ['-c', '-o'] - - if not v.LINK_CC: - v.LINK_CC = v.CC - - v.CCLNK_SRC_F = [] - v.CCLNK_TGT_F = ['-o'] - v.CPPPATH_ST = '-I%s' - v.DEFINES_ST = '-D%s' - - v.LIB_ST = '-l%s' # template for adding libs - v.LIBPATH_ST = '-L%s' # template for adding libpaths - v.STLIB_ST = '-l%s' - v.STLIBPATH_ST = '-L%s' - v.RPATH_ST = '-Wl,-rpath,%s' - - v.SONAME_ST = '-Wl,-h,%s' - v.SHLIB_MARKER = '-Wl,-Bdynamic' - v.STLIB_MARKER = '-Wl,-Bstatic' - - v.cprogram_PATTERN = '%s' - - v.CFLAGS_cshlib = ['-fPIC'] - v.LINKFLAGS_cshlib = ['-shared'] - v.cshlib_PATTERN = 'lib%s.so' - - v.LINKFLAGS_cstlib = ['-Wl,-Bstatic'] - v.cstlib_PATTERN = 'lib%s.a' - - v.LINKFLAGS_MACBUNDLE = ['-bundle', '-undefined', 'dynamic_lookup'] - v.CFLAGS_MACBUNDLE = ['-fPIC'] - v.macbundle_PATTERN = '%s.bundle' - -@conf -def gcc_modifier_win32(conf): - """Configuration flags for executing gcc on Windows""" - v = conf.env - v.cprogram_PATTERN = '%s.exe' - - v.cshlib_PATTERN = '%s.dll' - v.implib_PATTERN = '%s.dll.a' - v.IMPLIB_ST = '-Wl,--out-implib,%s' - - v.CFLAGS_cshlib = [] - - # Auto-import is enabled by default even without this option, - # but enabling it explicitly has the nice effect of suppressing the rather boring, debug-level messages - # that the linker emits otherwise. - v.append_value('LINKFLAGS', ['-Wl,--enable-auto-import']) - -@conf -def gcc_modifier_cygwin(conf): - """Configuration flags for executing gcc on Cygwin""" - gcc_modifier_win32(conf) - v = conf.env - v.cshlib_PATTERN = 'cyg%s.dll' - v.append_value('LINKFLAGS_cshlib', ['-Wl,--enable-auto-image-base']) - v.CFLAGS_cshlib = [] - -@conf -def gcc_modifier_darwin(conf): - """Configuration flags for executing gcc on MacOS""" - v = conf.env - v.CFLAGS_cshlib = ['-fPIC'] - v.LINKFLAGS_cshlib = ['-dynamiclib'] - v.cshlib_PATTERN = 'lib%s.dylib' - v.FRAMEWORKPATH_ST = '-F%s' - v.FRAMEWORK_ST = ['-framework'] - v.ARCH_ST = ['-arch'] - - v.LINKFLAGS_cstlib = [] - - v.SHLIB_MARKER = [] - v.STLIB_MARKER = [] - v.SONAME_ST = [] - -@conf -def gcc_modifier_aix(conf): - """Configuration flags for executing gcc on AIX""" - v = conf.env - v.LINKFLAGS_cprogram = ['-Wl,-brtl'] - v.LINKFLAGS_cshlib = ['-shared','-Wl,-brtl,-bexpfull'] - v.SHLIB_MARKER = [] - -@conf -def gcc_modifier_hpux(conf): - v = conf.env - v.SHLIB_MARKER = [] - v.STLIB_MARKER = [] - v.CFLAGS_cshlib = ['-fPIC','-DPIC'] - v.cshlib_PATTERN = 'lib%s.sl' - -@conf -def gcc_modifier_openbsd(conf): - conf.env.SONAME_ST = [] - -@conf -def gcc_modifier_osf1V(conf): - v = conf.env - v.SHLIB_MARKER = [] - v.STLIB_MARKER = [] - v.SONAME_ST = [] - -@conf -def gcc_modifier_platform(conf): - """Execute platform-specific functions based on *gcc_modifier_+NAME*""" - # * set configurations specific for a platform. - # * the destination platform is detected automatically by looking at the macros the compiler predefines, - # and if it's not recognised, it fallbacks to sys.platform. - gcc_modifier_func = getattr(conf, 'gcc_modifier_' + conf.env.DEST_OS, None) - if gcc_modifier_func: - gcc_modifier_func() - -def configure(conf): - """ - Configuration for gcc - """ - conf.find_gcc() - conf.find_ar() - conf.gcc_common_flags() - conf.gcc_modifier_platform() - conf.cc_load_tools() - conf.cc_add_flags() - conf.link_add_flags() - conf.check_gcc_o_space() - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/gdc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/gdc.py deleted file mode 100644 index d89a66d..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/gdc.py +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Carlos Rafael Giani, 2007 (dv) - -from waflib.Tools import ar, d -from waflib.Configure import conf - -@conf -def find_gdc(conf): - """ - Finds the program gdc and set the variable *D* - """ - conf.find_program('gdc', var='D') - - out = conf.cmd_and_log(conf.env.D + ['--version']) - if out.find("gdc") == -1: - conf.fatal("detected compiler is not gdc") - -@conf -def common_flags_gdc(conf): - """ - Sets the flags required by *gdc* - """ - v = conf.env - - v.DFLAGS = [] - - v.D_SRC_F = ['-c'] - v.D_TGT_F = '-o%s' - - v.D_LINKER = v.D - v.DLNK_SRC_F = '' - v.DLNK_TGT_F = '-o%s' - v.DINC_ST = '-I%s' - - v.DSHLIB_MARKER = v.DSTLIB_MARKER = '' - v.DSTLIB_ST = v.DSHLIB_ST = '-l%s' - v.DSTLIBPATH_ST = v.DLIBPATH_ST = '-L%s' - - v.LINKFLAGS_dshlib = ['-shared'] - - v.DHEADER_ext = '.di' - v.DFLAGS_d_with_header = '-fintfc' - v.D_HDR_F = '-fintfc-file=%s' - -def configure(conf): - """ - Configuration for gdc - """ - conf.find_gdc() - conf.load('ar') - conf.load('d') - conf.common_flags_gdc() - conf.d_platform_flags() - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/gfortran.py b/ldb-2.0.8/third_party/waf/waflib/Tools/gfortran.py deleted file mode 100644 index 1050667..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/gfortran.py +++ /dev/null @@ -1,93 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# DC 2008 -# Thomas Nagy 2016-2018 (ita) - -import re -from waflib import Utils -from waflib.Tools import fc, fc_config, fc_scan, ar -from waflib.Configure import conf - -@conf -def find_gfortran(conf): - """Find the gfortran program (will look in the environment variable 'FC')""" - fc = conf.find_program(['gfortran','g77'], var='FC') - # (fallback to g77 for systems, where no gfortran is available) - conf.get_gfortran_version(fc) - conf.env.FC_NAME = 'GFORTRAN' - -@conf -def gfortran_flags(conf): - v = conf.env - v.FCFLAGS_fcshlib = ['-fPIC'] - v.FORTRANMODFLAG = ['-J', ''] # template for module path - v.FCFLAGS_DEBUG = ['-Werror'] # why not - -@conf -def gfortran_modifier_win32(conf): - fc_config.fortran_modifier_win32(conf) - -@conf -def gfortran_modifier_cygwin(conf): - fc_config.fortran_modifier_cygwin(conf) - -@conf -def gfortran_modifier_darwin(conf): - fc_config.fortran_modifier_darwin(conf) - -@conf -def gfortran_modifier_platform(conf): - dest_os = conf.env.DEST_OS or Utils.unversioned_sys_platform() - gfortran_modifier_func = getattr(conf, 'gfortran_modifier_' + dest_os, None) - if gfortran_modifier_func: - gfortran_modifier_func() - -@conf -def get_gfortran_version(conf, fc): - """Get the compiler version""" - - # ensure this is actually gfortran, not an imposter. - version_re = re.compile(r"GNU\s*Fortran", re.I).search - cmd = fc + ['--version'] - out, err = fc_config.getoutput(conf, cmd, stdin=False) - if out: - match = version_re(out) - else: - match = version_re(err) - if not match: - conf.fatal('Could not determine the compiler type') - - # --- now get more detailed info -- see c_config.get_cc_version - cmd = fc + ['-dM', '-E', '-'] - out, err = fc_config.getoutput(conf, cmd, stdin=True) - - if out.find('__GNUC__') < 0: - conf.fatal('Could not determine the compiler type') - - k = {} - out = out.splitlines() - import shlex - - for line in out: - lst = shlex.split(line) - if len(lst)>2: - key = lst[1] - val = lst[2] - k[key] = val - - def isD(var): - return var in k - - def isT(var): - return var in k and k[var] != '0' - - conf.env.FC_VERSION = (k['__GNUC__'], k['__GNUC_MINOR__'], k['__GNUC_PATCHLEVEL__']) - -def configure(conf): - conf.find_gfortran() - conf.find_ar() - conf.fc_flags() - conf.fc_add_flags() - conf.gfortran_flags() - conf.gfortran_modifier_platform() - conf.check_gfortran_o_space() diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/glib2.py b/ldb-2.0.8/third_party/waf/waflib/Tools/glib2.py deleted file mode 100644 index 949fe37..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/glib2.py +++ /dev/null @@ -1,489 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2006-2018 (ita) - -""" -Support for GLib2 tools: - -* marshal -* enums -* gsettings -* gresource -""" - -import os -import functools -from waflib import Context, Task, Utils, Options, Errors, Logs -from waflib.TaskGen import taskgen_method, before_method, feature, extension -from waflib.Configure import conf - -################## marshal files - -@taskgen_method -def add_marshal_file(self, filename, prefix): - """ - Adds a file to the list of marshal files to process. Store them in the attribute *marshal_list*. - - :param filename: xml file to compile - :type filename: string - :param prefix: marshal prefix (--prefix=prefix) - :type prefix: string - """ - if not hasattr(self, 'marshal_list'): - self.marshal_list = [] - self.meths.append('process_marshal') - self.marshal_list.append((filename, prefix)) - -@before_method('process_source') -def process_marshal(self): - """ - Processes the marshal files stored in the attribute *marshal_list* to create :py:class:`waflib.Tools.glib2.glib_genmarshal` instances. - Adds the c file created to the list of source to process. - """ - for f, prefix in getattr(self, 'marshal_list', []): - node = self.path.find_resource(f) - - if not node: - raise Errors.WafError('file not found %r' % f) - - h_node = node.change_ext('.h') - c_node = node.change_ext('.c') - - task = self.create_task('glib_genmarshal', node, [h_node, c_node]) - task.env.GLIB_GENMARSHAL_PREFIX = prefix - self.source = self.to_nodes(getattr(self, 'source', [])) - self.source.append(c_node) - -class glib_genmarshal(Task.Task): - vars = ['GLIB_GENMARSHAL_PREFIX', 'GLIB_GENMARSHAL'] - color = 'BLUE' - ext_out = ['.h'] - def run(self): - bld = self.generator.bld - - get = self.env.get_flat - cmd1 = "%s %s --prefix=%s --header > %s" % ( - get('GLIB_GENMARSHAL'), - self.inputs[0].srcpath(), - get('GLIB_GENMARSHAL_PREFIX'), - self.outputs[0].abspath() - ) - - ret = bld.exec_command(cmd1) - if ret: - return ret - - #print self.outputs[1].abspath() - c = '''#include "%s"\n''' % self.outputs[0].name - self.outputs[1].write(c) - - cmd2 = "%s %s --prefix=%s --body >> %s" % ( - get('GLIB_GENMARSHAL'), - self.inputs[0].srcpath(), - get('GLIB_GENMARSHAL_PREFIX'), - self.outputs[1].abspath() - ) - return bld.exec_command(cmd2) - -########################## glib-mkenums - -@taskgen_method -def add_enums_from_template(self, source='', target='', template='', comments=''): - """ - Adds a file to the list of enum files to process. Stores them in the attribute *enums_list*. - - :param source: enum file to process - :type source: string - :param target: target file - :type target: string - :param template: template file - :type template: string - :param comments: comments - :type comments: string - """ - if not hasattr(self, 'enums_list'): - self.enums_list = [] - self.meths.append('process_enums') - self.enums_list.append({'source': source, - 'target': target, - 'template': template, - 'file-head': '', - 'file-prod': '', - 'file-tail': '', - 'enum-prod': '', - 'value-head': '', - 'value-prod': '', - 'value-tail': '', - 'comments': comments}) - -@taskgen_method -def add_enums(self, source='', target='', - file_head='', file_prod='', file_tail='', enum_prod='', - value_head='', value_prod='', value_tail='', comments=''): - """ - Adds a file to the list of enum files to process. Stores them in the attribute *enums_list*. - - :param source: enum file to process - :type source: string - :param target: target file - :type target: string - :param file_head: unused - :param file_prod: unused - :param file_tail: unused - :param enum_prod: unused - :param value_head: unused - :param value_prod: unused - :param value_tail: unused - :param comments: comments - :type comments: string - """ - if not hasattr(self, 'enums_list'): - self.enums_list = [] - self.meths.append('process_enums') - self.enums_list.append({'source': source, - 'template': '', - 'target': target, - 'file-head': file_head, - 'file-prod': file_prod, - 'file-tail': file_tail, - 'enum-prod': enum_prod, - 'value-head': value_head, - 'value-prod': value_prod, - 'value-tail': value_tail, - 'comments': comments}) - -@before_method('process_source') -def process_enums(self): - """ - Processes the enum files stored in the attribute *enum_list* to create :py:class:`waflib.Tools.glib2.glib_mkenums` instances. - """ - for enum in getattr(self, 'enums_list', []): - task = self.create_task('glib_mkenums') - env = task.env - - inputs = [] - - # process the source - source_list = self.to_list(enum['source']) - if not source_list: - raise Errors.WafError('missing source ' + str(enum)) - source_list = [self.path.find_resource(k) for k in source_list] - inputs += source_list - env.GLIB_MKENUMS_SOURCE = [k.abspath() for k in source_list] - - # find the target - if not enum['target']: - raise Errors.WafError('missing target ' + str(enum)) - tgt_node = self.path.find_or_declare(enum['target']) - if tgt_node.name.endswith('.c'): - self.source.append(tgt_node) - env.GLIB_MKENUMS_TARGET = tgt_node.abspath() - - - options = [] - - if enum['template']: # template, if provided - template_node = self.path.find_resource(enum['template']) - options.append('--template %s' % (template_node.abspath())) - inputs.append(template_node) - params = {'file-head' : '--fhead', - 'file-prod' : '--fprod', - 'file-tail' : '--ftail', - 'enum-prod' : '--eprod', - 'value-head' : '--vhead', - 'value-prod' : '--vprod', - 'value-tail' : '--vtail', - 'comments': '--comments'} - for param, option in params.items(): - if enum[param]: - options.append('%s %r' % (option, enum[param])) - - env.GLIB_MKENUMS_OPTIONS = ' '.join(options) - - # update the task instance - task.set_inputs(inputs) - task.set_outputs(tgt_node) - -class glib_mkenums(Task.Task): - """ - Processes enum files - """ - run_str = '${GLIB_MKENUMS} ${GLIB_MKENUMS_OPTIONS} ${GLIB_MKENUMS_SOURCE} > ${GLIB_MKENUMS_TARGET}' - color = 'PINK' - ext_out = ['.h'] - -######################################### gsettings - -@taskgen_method -def add_settings_schemas(self, filename_list): - """ - Adds settings files to process to *settings_schema_files* - - :param filename_list: files - :type filename_list: list of string - """ - if not hasattr(self, 'settings_schema_files'): - self.settings_schema_files = [] - - if not isinstance(filename_list, list): - filename_list = [filename_list] - - self.settings_schema_files.extend(filename_list) - -@taskgen_method -def add_settings_enums(self, namespace, filename_list): - """ - Called only once by task generator to set the enums namespace. - - :param namespace: namespace - :type namespace: string - :param filename_list: enum files to process - :type filename_list: file list - """ - if hasattr(self, 'settings_enum_namespace'): - raise Errors.WafError("Tried to add gsettings enums to %r more than once" % self.name) - self.settings_enum_namespace = namespace - - if not isinstance(filename_list, list): - filename_list = [filename_list] - self.settings_enum_files = filename_list - -@feature('glib2') -def process_settings(self): - """ - Processes the schema files in *settings_schema_files* to create :py:class:`waflib.Tools.glib2.glib_mkenums` instances. The - same files are validated through :py:class:`waflib.Tools.glib2.glib_validate_schema` tasks. - - """ - enums_tgt_node = [] - install_files = [] - - settings_schema_files = getattr(self, 'settings_schema_files', []) - if settings_schema_files and not self.env.GLIB_COMPILE_SCHEMAS: - raise Errors.WafError ("Unable to process GSettings schemas - glib-compile-schemas was not found during configure") - - # 1. process gsettings_enum_files (generate .enums.xml) - # - if hasattr(self, 'settings_enum_files'): - enums_task = self.create_task('glib_mkenums') - - source_list = self.settings_enum_files - source_list = [self.path.find_resource(k) for k in source_list] - enums_task.set_inputs(source_list) - enums_task.env.GLIB_MKENUMS_SOURCE = [k.abspath() for k in source_list] - - target = self.settings_enum_namespace + '.enums.xml' - tgt_node = self.path.find_or_declare(target) - enums_task.set_outputs(tgt_node) - enums_task.env.GLIB_MKENUMS_TARGET = tgt_node.abspath() - enums_tgt_node = [tgt_node] - - install_files.append(tgt_node) - - options = '--comments "" --fhead "" --vhead " <@type@ id=\\"%s.@EnumName@\\">" --vprod " " --vtail " " --ftail "" ' % (self.settings_enum_namespace) - enums_task.env.GLIB_MKENUMS_OPTIONS = options - - # 2. process gsettings_schema_files (validate .gschema.xml files) - # - for schema in settings_schema_files: - schema_task = self.create_task ('glib_validate_schema') - - schema_node = self.path.find_resource(schema) - if not schema_node: - raise Errors.WafError("Cannot find the schema file %r" % schema) - install_files.append(schema_node) - source_list = enums_tgt_node + [schema_node] - - schema_task.set_inputs (source_list) - schema_task.env.GLIB_COMPILE_SCHEMAS_OPTIONS = [("--schema-file=" + k.abspath()) for k in source_list] - - target_node = schema_node.change_ext('.xml.valid') - schema_task.set_outputs (target_node) - schema_task.env.GLIB_VALIDATE_SCHEMA_OUTPUT = target_node.abspath() - - # 3. schemas install task - def compile_schemas_callback(bld): - if not bld.is_install: - return - compile_schemas = Utils.to_list(bld.env.GLIB_COMPILE_SCHEMAS) - destdir = Options.options.destdir - paths = bld._compile_schemas_registered - if destdir: - paths = (os.path.join(destdir, path.lstrip(os.sep)) for path in paths) - for path in paths: - Logs.pprint('YELLOW', 'Updating GSettings schema cache %r' % path) - if self.bld.exec_command(compile_schemas + [path]): - Logs.warn('Could not update GSettings schema cache %r' % path) - - if self.bld.is_install: - schemadir = self.env.GSETTINGSSCHEMADIR - if not schemadir: - raise Errors.WafError ('GSETTINGSSCHEMADIR not defined (should have been set up automatically during configure)') - - if install_files: - self.add_install_files(install_to=schemadir, install_from=install_files) - registered_schemas = getattr(self.bld, '_compile_schemas_registered', None) - if not registered_schemas: - registered_schemas = self.bld._compile_schemas_registered = set() - self.bld.add_post_fun(compile_schemas_callback) - registered_schemas.add(schemadir) - -class glib_validate_schema(Task.Task): - """ - Validates schema files - """ - run_str = 'rm -f ${GLIB_VALIDATE_SCHEMA_OUTPUT} && ${GLIB_COMPILE_SCHEMAS} --dry-run ${GLIB_COMPILE_SCHEMAS_OPTIONS} && touch ${GLIB_VALIDATE_SCHEMA_OUTPUT}' - color = 'PINK' - -################## gresource - -@extension('.gresource.xml') -def process_gresource_source(self, node): - """ - Creates tasks that turn ``.gresource.xml`` files to C code - """ - if not self.env.GLIB_COMPILE_RESOURCES: - raise Errors.WafError ("Unable to process GResource file - glib-compile-resources was not found during configure") - - if 'gresource' in self.features: - return - - h_node = node.change_ext('_xml.h') - c_node = node.change_ext('_xml.c') - self.create_task('glib_gresource_source', node, [h_node, c_node]) - self.source.append(c_node) - -@feature('gresource') -def process_gresource_bundle(self): - """ - Creates tasks to turn ``.gresource`` files from ``.gresource.xml`` files:: - - def build(bld): - bld( - features='gresource', - source=['resources1.gresource.xml', 'resources2.gresource.xml'], - install_path='${LIBDIR}/${PACKAGE}' - ) - - :param source: XML files to process - :type source: list of string - :param install_path: installation path - :type install_path: string - """ - for i in self.to_list(self.source): - node = self.path.find_resource(i) - - task = self.create_task('glib_gresource_bundle', node, node.change_ext('')) - inst_to = getattr(self, 'install_path', None) - if inst_to: - self.add_install_files(install_to=inst_to, install_from=task.outputs) - -class glib_gresource_base(Task.Task): - """ - Base class for gresource based tasks - """ - color = 'BLUE' - base_cmd = '${GLIB_COMPILE_RESOURCES} --sourcedir=${SRC[0].parent.srcpath()} --sourcedir=${SRC[0].bld_dir()}' - - def scan(self): - """ - Scans gresource dependencies through ``glib-compile-resources --generate-dependencies command`` - """ - bld = self.generator.bld - kw = {} - kw['cwd'] = self.get_cwd() - kw['quiet'] = Context.BOTH - - cmd = Utils.subst_vars('${GLIB_COMPILE_RESOURCES} --sourcedir=%s --sourcedir=%s --generate-dependencies %s' % ( - self.inputs[0].parent.srcpath(), - self.inputs[0].bld_dir(), - self.inputs[0].bldpath() - ), self.env) - - output = bld.cmd_and_log(cmd, **kw) - - nodes = [] - names = [] - for dep in output.splitlines(): - if dep: - node = bld.bldnode.find_node(dep) - if node: - nodes.append(node) - else: - names.append(dep) - - return (nodes, names) - -class glib_gresource_source(glib_gresource_base): - """ - Task to generate C source code (.h and .c files) from a gresource.xml file - """ - vars = ['GLIB_COMPILE_RESOURCES'] - fun_h = Task.compile_fun_shell(glib_gresource_base.base_cmd + ' --target=${TGT[0].abspath()} --generate-header ${SRC}') - fun_c = Task.compile_fun_shell(glib_gresource_base.base_cmd + ' --target=${TGT[1].abspath()} --generate-source ${SRC}') - ext_out = ['.h'] - - def run(self): - return self.fun_h[0](self) or self.fun_c[0](self) - -class glib_gresource_bundle(glib_gresource_base): - """ - Task to generate a .gresource binary file from a gresource.xml file - """ - run_str = glib_gresource_base.base_cmd + ' --target=${TGT} ${SRC}' - shell = True # temporary workaround for #795 - -@conf -def find_glib_genmarshal(conf): - conf.find_program('glib-genmarshal', var='GLIB_GENMARSHAL') - -@conf -def find_glib_mkenums(conf): - if not conf.env.PERL: - conf.find_program('perl', var='PERL') - conf.find_program('glib-mkenums', interpreter='PERL', var='GLIB_MKENUMS') - -@conf -def find_glib_compile_schemas(conf): - # when cross-compiling, gsettings.m4 locates the program with the following: - # pkg-config --variable glib_compile_schemas gio-2.0 - conf.find_program('glib-compile-schemas', var='GLIB_COMPILE_SCHEMAS') - - def getstr(varname): - return getattr(Options.options, varname, getattr(conf.env,varname, '')) - - gsettingsschemadir = getstr('GSETTINGSSCHEMADIR') - if not gsettingsschemadir: - datadir = getstr('DATADIR') - if not datadir: - prefix = conf.env.PREFIX - datadir = os.path.join(prefix, 'share') - gsettingsschemadir = os.path.join(datadir, 'glib-2.0', 'schemas') - - conf.env.GSETTINGSSCHEMADIR = gsettingsschemadir - -@conf -def find_glib_compile_resources(conf): - conf.find_program('glib-compile-resources', var='GLIB_COMPILE_RESOURCES') - -def configure(conf): - """ - Finds the following programs: - - * *glib-genmarshal* and set *GLIB_GENMARSHAL* - * *glib-mkenums* and set *GLIB_MKENUMS* - * *glib-compile-schemas* and set *GLIB_COMPILE_SCHEMAS* (not mandatory) - * *glib-compile-resources* and set *GLIB_COMPILE_RESOURCES* (not mandatory) - """ - conf.find_glib_genmarshal() - conf.find_glib_mkenums() - conf.find_glib_compile_schemas(mandatory=False) - conf.find_glib_compile_resources(mandatory=False) - -def options(opt): - """ - Adds the ``--gsettingsschemadir`` command-line option - """ - gr = opt.add_option_group('Installation directories') - gr.add_option('--gsettingsschemadir', help='GSettings schema location [DATADIR/glib-2.0/schemas]', default='', dest='GSETTINGSSCHEMADIR') - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/gnu_dirs.py b/ldb-2.0.8/third_party/waf/waflib/Tools/gnu_dirs.py deleted file mode 100644 index 2847071..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/gnu_dirs.py +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Ali Sabil, 2007 - -""" -Sets various standard variables such as INCLUDEDIR. SBINDIR and others. To use this module just call:: - - opt.load('gnu_dirs') - -and:: - - conf.load('gnu_dirs') - -Add options for the standard GNU directories, this tool will add the options -found in autotools, and will update the environment with the following -installation variables: - -============== ========================================= ======================= -Variable Description Default Value -============== ========================================= ======================= -PREFIX installation prefix /usr/local -EXEC_PREFIX installation prefix for binaries PREFIX -BINDIR user commands EXEC_PREFIX/bin -SBINDIR system binaries EXEC_PREFIX/sbin -LIBEXECDIR program-specific binaries EXEC_PREFIX/libexec -SYSCONFDIR host-specific configuration PREFIX/etc -SHAREDSTATEDIR architecture-independent variable data PREFIX/com -LOCALSTATEDIR variable data PREFIX/var -LIBDIR object code libraries EXEC_PREFIX/lib -INCLUDEDIR header files PREFIX/include -OLDINCLUDEDIR header files for non-GCC compilers /usr/include -DATAROOTDIR architecture-independent data root PREFIX/share -DATADIR architecture-independent data DATAROOTDIR -INFODIR GNU "info" documentation DATAROOTDIR/info -LOCALEDIR locale-dependent data DATAROOTDIR/locale -MANDIR manual pages DATAROOTDIR/man -DOCDIR documentation root DATAROOTDIR/doc/APPNAME -HTMLDIR HTML documentation DOCDIR -DVIDIR DVI documentation DOCDIR -PDFDIR PDF documentation DOCDIR -PSDIR PostScript documentation DOCDIR -============== ========================================= ======================= -""" - -import os, re -from waflib import Utils, Options, Context - -gnuopts = ''' -bindir, user commands, ${EXEC_PREFIX}/bin -sbindir, system binaries, ${EXEC_PREFIX}/sbin -libexecdir, program-specific binaries, ${EXEC_PREFIX}/libexec -sysconfdir, host-specific configuration, ${PREFIX}/etc -sharedstatedir, architecture-independent variable data, ${PREFIX}/com -localstatedir, variable data, ${PREFIX}/var -libdir, object code libraries, ${EXEC_PREFIX}/lib%s -includedir, header files, ${PREFIX}/include -oldincludedir, header files for non-GCC compilers, /usr/include -datarootdir, architecture-independent data root, ${PREFIX}/share -datadir, architecture-independent data, ${DATAROOTDIR} -infodir, GNU "info" documentation, ${DATAROOTDIR}/info -localedir, locale-dependent data, ${DATAROOTDIR}/locale -mandir, manual pages, ${DATAROOTDIR}/man -docdir, documentation root, ${DATAROOTDIR}/doc/${PACKAGE} -htmldir, HTML documentation, ${DOCDIR} -dvidir, DVI documentation, ${DOCDIR} -pdfdir, PDF documentation, ${DOCDIR} -psdir, PostScript documentation, ${DOCDIR} -''' % Utils.lib64() - -_options = [x.split(', ') for x in gnuopts.splitlines() if x] - -def configure(conf): - """ - Reads the command-line options to set lots of variables in *conf.env*. The variables - BINDIR and LIBDIR will be overwritten. - """ - def get_param(varname, default): - return getattr(Options.options, varname, '') or default - - env = conf.env - env.LIBDIR = env.BINDIR = [] - env.EXEC_PREFIX = get_param('EXEC_PREFIX', env.PREFIX) - env.PACKAGE = getattr(Context.g_module, 'APPNAME', None) or env.PACKAGE - - complete = False - iter = 0 - while not complete and iter < len(_options) + 1: - iter += 1 - complete = True - for name, help, default in _options: - name = name.upper() - if not env[name]: - try: - env[name] = Utils.subst_vars(get_param(name, default).replace('/', os.sep), env) - except TypeError: - complete = False - - if not complete: - lst = [x for x, _, _ in _options if not env[x.upper()]] - raise conf.errors.WafError('Variable substitution failure %r' % lst) - -def options(opt): - """ - Adds lots of command-line options, for example:: - - --exec-prefix: EXEC_PREFIX - """ - inst_dir = opt.add_option_group('Installation prefix', -'By default, "waf install" will put the files in\ - "/usr/local/bin", "/usr/local/lib" etc. An installation prefix other\ - than "/usr/local" can be given using "--prefix", for example "--prefix=$HOME"') - - for k in ('--prefix', '--destdir'): - option = opt.parser.get_option(k) - if option: - opt.parser.remove_option(k) - inst_dir.add_option(option) - - inst_dir.add_option('--exec-prefix', - help = 'installation prefix for binaries [PREFIX]', - default = '', - dest = 'EXEC_PREFIX') - - dirs_options = opt.add_option_group('Installation directories') - - for name, help, default in _options: - option_name = '--' + name - str_default = default - str_help = '%s [%s]' % (help, re.sub(r'\$\{([^}]+)\}', r'\1', str_default)) - dirs_options.add_option(option_name, help=str_help, default='', dest=name.upper()) - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/gxx.py b/ldb-2.0.8/third_party/waf/waflib/Tools/gxx.py deleted file mode 100644 index 22c5d26..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/gxx.py +++ /dev/null @@ -1,157 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2006-2018 (ita) -# Ralf Habacker, 2006 (rh) -# Yinon Ehrlich, 2009 - -""" -g++/llvm detection. -""" - -from waflib.Tools import ccroot, ar -from waflib.Configure import conf - -@conf -def find_gxx(conf): - """ - Finds the program g++, and if present, try to detect its version number - """ - cxx = conf.find_program(['g++', 'c++'], var='CXX') - conf.get_cc_version(cxx, gcc=True) - conf.env.CXX_NAME = 'gcc' - -@conf -def gxx_common_flags(conf): - """ - Common flags for g++ on nearly all platforms - """ - v = conf.env - - v.CXX_SRC_F = [] - v.CXX_TGT_F = ['-c', '-o'] - - if not v.LINK_CXX: - v.LINK_CXX = v.CXX - - v.CXXLNK_SRC_F = [] - v.CXXLNK_TGT_F = ['-o'] - v.CPPPATH_ST = '-I%s' - v.DEFINES_ST = '-D%s' - - v.LIB_ST = '-l%s' # template for adding libs - v.LIBPATH_ST = '-L%s' # template for adding libpaths - v.STLIB_ST = '-l%s' - v.STLIBPATH_ST = '-L%s' - v.RPATH_ST = '-Wl,-rpath,%s' - - v.SONAME_ST = '-Wl,-h,%s' - v.SHLIB_MARKER = '-Wl,-Bdynamic' - v.STLIB_MARKER = '-Wl,-Bstatic' - - v.cxxprogram_PATTERN = '%s' - - v.CXXFLAGS_cxxshlib = ['-fPIC'] - v.LINKFLAGS_cxxshlib = ['-shared'] - v.cxxshlib_PATTERN = 'lib%s.so' - - v.LINKFLAGS_cxxstlib = ['-Wl,-Bstatic'] - v.cxxstlib_PATTERN = 'lib%s.a' - - v.LINKFLAGS_MACBUNDLE = ['-bundle', '-undefined', 'dynamic_lookup'] - v.CXXFLAGS_MACBUNDLE = ['-fPIC'] - v.macbundle_PATTERN = '%s.bundle' - -@conf -def gxx_modifier_win32(conf): - """Configuration flags for executing gcc on Windows""" - v = conf.env - v.cxxprogram_PATTERN = '%s.exe' - - v.cxxshlib_PATTERN = '%s.dll' - v.implib_PATTERN = '%s.dll.a' - v.IMPLIB_ST = '-Wl,--out-implib,%s' - - v.CXXFLAGS_cxxshlib = [] - - # Auto-import is enabled by default even without this option, - # but enabling it explicitly has the nice effect of suppressing the rather boring, debug-level messages - # that the linker emits otherwise. - v.append_value('LINKFLAGS', ['-Wl,--enable-auto-import']) - -@conf -def gxx_modifier_cygwin(conf): - """Configuration flags for executing g++ on Cygwin""" - gxx_modifier_win32(conf) - v = conf.env - v.cxxshlib_PATTERN = 'cyg%s.dll' - v.append_value('LINKFLAGS_cxxshlib', ['-Wl,--enable-auto-image-base']) - v.CXXFLAGS_cxxshlib = [] - -@conf -def gxx_modifier_darwin(conf): - """Configuration flags for executing g++ on MacOS""" - v = conf.env - v.CXXFLAGS_cxxshlib = ['-fPIC'] - v.LINKFLAGS_cxxshlib = ['-dynamiclib'] - v.cxxshlib_PATTERN = 'lib%s.dylib' - v.FRAMEWORKPATH_ST = '-F%s' - v.FRAMEWORK_ST = ['-framework'] - v.ARCH_ST = ['-arch'] - - v.LINKFLAGS_cxxstlib = [] - - v.SHLIB_MARKER = [] - v.STLIB_MARKER = [] - v.SONAME_ST = [] - -@conf -def gxx_modifier_aix(conf): - """Configuration flags for executing g++ on AIX""" - v = conf.env - v.LINKFLAGS_cxxprogram= ['-Wl,-brtl'] - - v.LINKFLAGS_cxxshlib = ['-shared', '-Wl,-brtl,-bexpfull'] - v.SHLIB_MARKER = [] - -@conf -def gxx_modifier_hpux(conf): - v = conf.env - v.SHLIB_MARKER = [] - v.STLIB_MARKER = [] - v.CFLAGS_cxxshlib = ['-fPIC','-DPIC'] - v.cxxshlib_PATTERN = 'lib%s.sl' - -@conf -def gxx_modifier_openbsd(conf): - conf.env.SONAME_ST = [] - -@conf -def gcc_modifier_osf1V(conf): - v = conf.env - v.SHLIB_MARKER = [] - v.STLIB_MARKER = [] - v.SONAME_ST = [] - -@conf -def gxx_modifier_platform(conf): - """Execute platform-specific functions based on *gxx_modifier_+NAME*""" - # * set configurations specific for a platform. - # * the destination platform is detected automatically by looking at the macros the compiler predefines, - # and if it's not recognised, it fallbacks to sys.platform. - gxx_modifier_func = getattr(conf, 'gxx_modifier_' + conf.env.DEST_OS, None) - if gxx_modifier_func: - gxx_modifier_func() - -def configure(conf): - """ - Configuration for g++ - """ - conf.find_gxx() - conf.find_ar() - conf.gxx_common_flags() - conf.gxx_modifier_platform() - conf.cxx_load_tools() - conf.cxx_add_flags() - conf.link_add_flags() - conf.check_gcc_o_space('cxx') - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/icc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/icc.py deleted file mode 100644 index b6492c8..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/icc.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Stian Selnes 2008 -# Thomas Nagy 2009-2018 (ita) - -""" -Detects the Intel C compiler -""" - -import sys -from waflib.Tools import ccroot, ar, gcc -from waflib.Configure import conf - -@conf -def find_icc(conf): - """ - Finds the program icc and execute it to ensure it really is icc - """ - cc = conf.find_program(['icc', 'ICL'], var='CC') - conf.get_cc_version(cc, icc=True) - conf.env.CC_NAME = 'icc' - -def configure(conf): - conf.find_icc() - conf.find_ar() - conf.gcc_common_flags() - conf.gcc_modifier_platform() - conf.cc_load_tools() - conf.cc_add_flags() - conf.link_add_flags() diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/icpc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/icpc.py deleted file mode 100644 index 8a6cc6c..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/icpc.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy 2009-2018 (ita) - -""" -Detects the Intel C++ compiler -""" - -import sys -from waflib.Tools import ccroot, ar, gxx -from waflib.Configure import conf - -@conf -def find_icpc(conf): - """ - Finds the program icpc, and execute it to ensure it really is icpc - """ - cxx = conf.find_program('icpc', var='CXX') - conf.get_cc_version(cxx, icc=True) - conf.env.CXX_NAME = 'icc' - -def configure(conf): - conf.find_icpc() - conf.find_ar() - conf.gxx_common_flags() - conf.gxx_modifier_platform() - conf.cxx_load_tools() - conf.cxx_add_flags() - conf.link_add_flags() - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/ifort.py b/ldb-2.0.8/third_party/waf/waflib/Tools/ifort.py deleted file mode 100644 index 17d3052..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/ifort.py +++ /dev/null @@ -1,413 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# DC 2008 -# Thomas Nagy 2016-2018 (ita) - -import os, re, traceback -from waflib import Utils, Logs, Errors -from waflib.Tools import fc, fc_config, fc_scan, ar, ccroot -from waflib.Configure import conf -from waflib.TaskGen import after_method, feature - -@conf -def find_ifort(conf): - fc = conf.find_program('ifort', var='FC') - conf.get_ifort_version(fc) - conf.env.FC_NAME = 'IFORT' - -@conf -def ifort_modifier_win32(self): - v = self.env - v.IFORT_WIN32 = True - v.FCSTLIB_MARKER = '' - v.FCSHLIB_MARKER = '' - - v.FCLIB_ST = v.FCSTLIB_ST = '%s.lib' - v.FCLIBPATH_ST = v.STLIBPATH_ST = '/LIBPATH:%s' - v.FCINCPATH_ST = '/I%s' - v.FCDEFINES_ST = '/D%s' - - v.fcprogram_PATTERN = v.fcprogram_test_PATTERN = '%s.exe' - v.fcshlib_PATTERN = '%s.dll' - v.fcstlib_PATTERN = v.implib_PATTERN = '%s.lib' - - v.FCLNK_TGT_F = '/out:' - v.FC_TGT_F = ['/c', '/o', ''] - v.FCFLAGS_fcshlib = '' - v.LINKFLAGS_fcshlib = '/DLL' - v.AR_TGT_F = '/out:' - v.IMPLIB_ST = '/IMPLIB:%s' - - v.append_value('LINKFLAGS', '/subsystem:console') - if v.IFORT_MANIFEST: - v.append_value('LINKFLAGS', ['/MANIFEST']) - -@conf -def ifort_modifier_darwin(conf): - fc_config.fortran_modifier_darwin(conf) - -@conf -def ifort_modifier_platform(conf): - dest_os = conf.env.DEST_OS or Utils.unversioned_sys_platform() - ifort_modifier_func = getattr(conf, 'ifort_modifier_' + dest_os, None) - if ifort_modifier_func: - ifort_modifier_func() - -@conf -def get_ifort_version(conf, fc): - """ - Detects the compiler version and sets ``conf.env.FC_VERSION`` - """ - version_re = re.compile(r"\bIntel\b.*\bVersion\s*(?P\d*)\.(?P\d*)",re.I).search - if Utils.is_win32: - cmd = fc - else: - cmd = fc + ['-logo'] - - out, err = fc_config.getoutput(conf, cmd, stdin=False) - match = version_re(out) or version_re(err) - if not match: - conf.fatal('cannot determine ifort version.') - k = match.groupdict() - conf.env.FC_VERSION = (k['major'], k['minor']) - -def configure(conf): - """ - Detects the Intel Fortran compilers - """ - if Utils.is_win32: - compiler, version, path, includes, libdirs, arch = conf.detect_ifort() - v = conf.env - v.DEST_CPU = arch - v.PATH = path - v.INCLUDES = includes - v.LIBPATH = libdirs - v.MSVC_COMPILER = compiler - try: - v.MSVC_VERSION = float(version) - except ValueError: - v.MSVC_VERSION = float(version[:-3]) - - conf.find_ifort_win32() - conf.ifort_modifier_win32() - else: - conf.find_ifort() - conf.find_program('xiar', var='AR') - conf.find_ar() - conf.fc_flags() - conf.fc_add_flags() - conf.ifort_modifier_platform() - - -all_ifort_platforms = [ ('intel64', 'amd64'), ('em64t', 'amd64'), ('ia32', 'x86'), ('Itanium', 'ia64')] -"""List of icl platforms""" - -@conf -def gather_ifort_versions(conf, versions): - """ - List compiler versions by looking up registry keys - """ - version_pattern = re.compile(r'^...?.?\....?.?') - try: - all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Intel\\Compilers\\Fortran') - except OSError: - try: - all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Intel\\Compilers\\Fortran') - except OSError: - return - index = 0 - while 1: - try: - version = Utils.winreg.EnumKey(all_versions, index) - except OSError: - break - index += 1 - if not version_pattern.match(version): - continue - targets = {} - for target,arch in all_ifort_platforms: - if target=='intel64': - targetDir='EM64T_NATIVE' - else: - targetDir=target - try: - Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir) - icl_version=Utils.winreg.OpenKey(all_versions,version) - path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') - except OSError: - pass - else: - batch_file=os.path.join(path,'bin','ifortvars.bat') - if os.path.isfile(batch_file): - targets[target] = target_compiler(conf, 'intel', arch, version, target, batch_file) - - for target,arch in all_ifort_platforms: - try: - icl_version = Utils.winreg.OpenKey(all_versions, version+'\\'+target) - path,type = Utils.winreg.QueryValueEx(icl_version,'ProductDir') - except OSError: - continue - else: - batch_file=os.path.join(path,'bin','ifortvars.bat') - if os.path.isfile(batch_file): - targets[target] = target_compiler(conf, 'intel', arch, version, target, batch_file) - major = version[0:2] - versions['intel ' + major] = targets - -@conf -def setup_ifort(conf, versiondict): - """ - Checks installed compilers and targets and returns the first combination from the user's - options, env, or the global supported lists that checks. - - :param versiondict: dict(platform -> dict(architecture -> configuration)) - :type versiondict: dict(string -> dict(string -> target_compiler) - :return: the compiler, revision, path, include dirs, library paths and target architecture - :rtype: tuple of strings - """ - platforms = Utils.to_list(conf.env.MSVC_TARGETS) or [i for i,j in all_ifort_platforms] - desired_versions = conf.env.MSVC_VERSIONS or list(reversed(list(versiondict.keys()))) - for version in desired_versions: - try: - targets = versiondict[version] - except KeyError: - continue - for arch in platforms: - try: - cfg = targets[arch] - except KeyError: - continue - cfg.evaluate() - if cfg.is_valid: - compiler,revision = version.rsplit(' ', 1) - return compiler,revision,cfg.bindirs,cfg.incdirs,cfg.libdirs,cfg.cpu - conf.fatal('ifort: Impossible to find a valid architecture for building %r - %r' % (desired_versions, list(versiondict.keys()))) - -@conf -def get_ifort_version_win32(conf, compiler, version, target, vcvars): - # FIXME hack - try: - conf.msvc_cnt += 1 - except AttributeError: - conf.msvc_cnt = 1 - batfile = conf.bldnode.make_node('waf-print-msvc-%d.bat' % conf.msvc_cnt) - batfile.write("""@echo off -set INCLUDE= -set LIB= -call "%s" %s -echo PATH=%%PATH%% -echo INCLUDE=%%INCLUDE%% -echo LIB=%%LIB%%;%%LIBPATH%% -""" % (vcvars,target)) - sout = conf.cmd_and_log(['cmd.exe', '/E:on', '/V:on', '/C', batfile.abspath()]) - batfile.delete() - lines = sout.splitlines() - - if not lines[0]: - lines.pop(0) - - MSVC_PATH = MSVC_INCDIR = MSVC_LIBDIR = None - for line in lines: - if line.startswith('PATH='): - path = line[5:] - MSVC_PATH = path.split(';') - elif line.startswith('INCLUDE='): - MSVC_INCDIR = [i for i in line[8:].split(';') if i] - elif line.startswith('LIB='): - MSVC_LIBDIR = [i for i in line[4:].split(';') if i] - if None in (MSVC_PATH, MSVC_INCDIR, MSVC_LIBDIR): - conf.fatal('ifort: Could not find a valid architecture for building (get_ifort_version_win32)') - - # Check if the compiler is usable at all. - # The detection may return 64-bit versions even on 32-bit systems, and these would fail to run. - env = dict(os.environ) - env.update(PATH = path) - compiler_name, linker_name, lib_name = _get_prog_names(conf, compiler) - fc = conf.find_program(compiler_name, path_list=MSVC_PATH) - - # delete CL if exists. because it could contain parameters which can change cl's behaviour rather catastrophically. - if 'CL' in env: - del(env['CL']) - - try: - conf.cmd_and_log(fc + ['/help'], env=env) - except UnicodeError: - st = traceback.format_exc() - if conf.logger: - conf.logger.error(st) - conf.fatal('ifort: Unicode error - check the code page?') - except Exception as e: - Logs.debug('ifort: get_ifort_version: %r %r %r -> failure %s', compiler, version, target, str(e)) - conf.fatal('ifort: cannot run the compiler in get_ifort_version (run with -v to display errors)') - else: - Logs.debug('ifort: get_ifort_version: %r %r %r -> OK', compiler, version, target) - finally: - conf.env[compiler_name] = '' - - return (MSVC_PATH, MSVC_INCDIR, MSVC_LIBDIR) - -class target_compiler(object): - """ - Wraps a compiler configuration; call evaluate() to determine - whether the configuration is usable. - """ - def __init__(self, ctx, compiler, cpu, version, bat_target, bat, callback=None): - """ - :param ctx: configuration context to use to eventually get the version environment - :param compiler: compiler name - :param cpu: target cpu - :param version: compiler version number - :param bat_target: ? - :param bat: path to the batch file to run - :param callback: optional function to take the realized environment variables tup and map it (e.g. to combine other constant paths) - """ - self.conf = ctx - self.name = None - self.is_valid = False - self.is_done = False - - self.compiler = compiler - self.cpu = cpu - self.version = version - self.bat_target = bat_target - self.bat = bat - self.callback = callback - - def evaluate(self): - if self.is_done: - return - self.is_done = True - try: - vs = self.conf.get_ifort_version_win32(self.compiler, self.version, self.bat_target, self.bat) - except Errors.ConfigurationError: - self.is_valid = False - return - if self.callback: - vs = self.callback(self, vs) - self.is_valid = True - (self.bindirs, self.incdirs, self.libdirs) = vs - - def __str__(self): - return str((self.bindirs, self.incdirs, self.libdirs)) - - def __repr__(self): - return repr((self.bindirs, self.incdirs, self.libdirs)) - -@conf -def detect_ifort(self): - return self.setup_ifort(self.get_ifort_versions(False)) - -@conf -def get_ifort_versions(self, eval_and_save=True): - """ - :return: platforms to compiler configurations - :rtype: dict - """ - dct = {} - self.gather_ifort_versions(dct) - return dct - -def _get_prog_names(self, compiler): - if compiler=='intel': - compiler_name = 'ifort' - linker_name = 'XILINK' - lib_name = 'XILIB' - else: - # assumes CL.exe - compiler_name = 'CL' - linker_name = 'LINK' - lib_name = 'LIB' - return compiler_name, linker_name, lib_name - -@conf -def find_ifort_win32(conf): - # the autodetection is supposed to be performed before entering in this method - v = conf.env - path = v.PATH - compiler = v.MSVC_COMPILER - version = v.MSVC_VERSION - - compiler_name, linker_name, lib_name = _get_prog_names(conf, compiler) - v.IFORT_MANIFEST = (compiler == 'intel' and version >= 11) - - # compiler - fc = conf.find_program(compiler_name, var='FC', path_list=path) - - # before setting anything, check if the compiler is really intel fortran - env = dict(conf.environ) - if path: - env.update(PATH = ';'.join(path)) - if not conf.cmd_and_log(fc + ['/nologo', '/help'], env=env): - conf.fatal('not intel fortran compiler could not be identified') - - v.FC_NAME = 'IFORT' - - if not v.LINK_FC: - conf.find_program(linker_name, var='LINK_FC', path_list=path, mandatory=True) - - if not v.AR: - conf.find_program(lib_name, path_list=path, var='AR', mandatory=True) - v.ARFLAGS = ['/nologo'] - - # manifest tool. Not required for VS 2003 and below. Must have for VS 2005 and later - if v.IFORT_MANIFEST: - conf.find_program('MT', path_list=path, var='MT') - v.MTFLAGS = ['/nologo'] - - try: - conf.load('winres') - except Errors.WafError: - Logs.warn('Resource compiler not found. Compiling resource file is disabled') - -####################################################################################################### -##### conf above, build below - -@after_method('apply_link') -@feature('fc') -def apply_flags_ifort(self): - """ - Adds additional flags implied by msvc, such as subsystems and pdb files:: - - def build(bld): - bld.stlib(source='main.c', target='bar', subsystem='gruik') - """ - if not self.env.IFORT_WIN32 or not getattr(self, 'link_task', None): - return - - is_static = isinstance(self.link_task, ccroot.stlink_task) - - subsystem = getattr(self, 'subsystem', '') - if subsystem: - subsystem = '/subsystem:%s' % subsystem - flags = is_static and 'ARFLAGS' or 'LINKFLAGS' - self.env.append_value(flags, subsystem) - - if not is_static: - for f in self.env.LINKFLAGS: - d = f.lower() - if d[1:] == 'debug': - pdbnode = self.link_task.outputs[0].change_ext('.pdb') - self.link_task.outputs.append(pdbnode) - - if getattr(self, 'install_task', None): - self.pdb_install_task = self.add_install_files(install_to=self.install_task.install_to, install_from=pdbnode) - - break - -@feature('fcprogram', 'fcshlib', 'fcprogram_test') -@after_method('apply_link') -def apply_manifest_ifort(self): - """ - Enables manifest embedding in Fortran DLLs when using ifort on Windows - See: http://msdn2.microsoft.com/en-us/library/ms235542(VS.80).aspx - """ - if self.env.IFORT_WIN32 and getattr(self, 'link_task', None): - # it seems ifort.exe cannot be called for linking - self.link_task.env.FC = self.env.LINK_FC - - if self.env.IFORT_WIN32 and self.env.IFORT_MANIFEST and getattr(self, 'link_task', None): - out_node = self.link_task.outputs[0] - man_node = out_node.parent.find_or_declare(out_node.name + '.manifest') - self.link_task.outputs.append(man_node) - self.env.DO_MANIFEST = True - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/intltool.py b/ldb-2.0.8/third_party/waf/waflib/Tools/intltool.py deleted file mode 100644 index af95ba8..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/intltool.py +++ /dev/null @@ -1,231 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2006-2018 (ita) - -""" -Support for translation tools such as msgfmt and intltool - -Usage:: - - def configure(conf): - conf.load('gnu_dirs intltool') - - def build(bld): - # process the .po files into .gmo files, and install them in LOCALEDIR - bld(features='intltool_po', appname='myapp', podir='po', install_path="${LOCALEDIR}") - - # process an input file, substituting the translations from the po dir - bld( - features = "intltool_in", - podir = "../po", - style = "desktop", - flags = ["-u"], - source = 'kupfer.desktop.in', - install_path = "${DATADIR}/applications", - ) - -Usage of the :py:mod:`waflib.Tools.gnu_dirs` is recommended, but not obligatory. -""" - -from __future__ import with_statement - -import os, re -from waflib import Context, Task, Utils, Logs -import waflib.Tools.ccroot -from waflib.TaskGen import feature, before_method, taskgen_method -from waflib.Logs import error -from waflib.Configure import conf - -_style_flags = { - 'ba': '-b', - 'desktop': '-d', - 'keys': '-k', - 'quoted': '--quoted-style', - 'quotedxml': '--quotedxml-style', - 'rfc822deb': '-r', - 'schemas': '-s', - 'xml': '-x', -} - -@taskgen_method -def ensure_localedir(self): - """ - Expands LOCALEDIR from DATAROOTDIR/locale if possible, or falls back to PREFIX/share/locale - """ - # use the tool gnu_dirs to provide options to define this - if not self.env.LOCALEDIR: - if self.env.DATAROOTDIR: - self.env.LOCALEDIR = os.path.join(self.env.DATAROOTDIR, 'locale') - else: - self.env.LOCALEDIR = os.path.join(self.env.PREFIX, 'share', 'locale') - -@before_method('process_source') -@feature('intltool_in') -def apply_intltool_in_f(self): - """ - Creates tasks to translate files by intltool-merge:: - - def build(bld): - bld( - features = "intltool_in", - podir = "../po", - style = "desktop", - flags = ["-u"], - source = 'kupfer.desktop.in', - install_path = "${DATADIR}/applications", - ) - - :param podir: location of the .po files - :type podir: string - :param source: source files to process - :type source: list of string - :param style: the intltool-merge mode of operation, can be one of the following values: - ``ba``, ``desktop``, ``keys``, ``quoted``, ``quotedxml``, ``rfc822deb``, ``schemas`` and ``xml``. - See the ``intltool-merge`` man page for more information about supported modes of operation. - :type style: string - :param flags: compilation flags ("-quc" by default) - :type flags: list of string - :param install_path: installation path - :type install_path: string - """ - try: - self.meths.remove('process_source') - except ValueError: - pass - - self.ensure_localedir() - - podir = getattr(self, 'podir', '.') - podirnode = self.path.find_dir(podir) - if not podirnode: - error("could not find the podir %r" % podir) - return - - cache = getattr(self, 'intlcache', '.intlcache') - self.env.INTLCACHE = [os.path.join(str(self.path.get_bld()), podir, cache)] - self.env.INTLPODIR = podirnode.bldpath() - self.env.append_value('INTLFLAGS', getattr(self, 'flags', self.env.INTLFLAGS_DEFAULT)) - - if '-c' in self.env.INTLFLAGS: - self.bld.fatal('Redundant -c flag in intltool task %r' % self) - - style = getattr(self, 'style', None) - if style: - try: - style_flag = _style_flags[style] - except KeyError: - self.bld.fatal('intltool_in style "%s" is not valid' % style) - - self.env.append_unique('INTLFLAGS', [style_flag]) - - for i in self.to_list(self.source): - node = self.path.find_resource(i) - - task = self.create_task('intltool', node, node.change_ext('')) - inst = getattr(self, 'install_path', None) - if inst: - self.add_install_files(install_to=inst, install_from=task.outputs) - -@feature('intltool_po') -def apply_intltool_po(self): - """ - Creates tasks to process po files:: - - def build(bld): - bld(features='intltool_po', appname='myapp', podir='po', install_path="${LOCALEDIR}") - - The relevant task generator arguments are: - - :param podir: directory of the .po files - :type podir: string - :param appname: name of the application - :type appname: string - :param install_path: installation directory - :type install_path: string - - The file LINGUAS must be present in the directory pointed by *podir* and list the translation files to process. - """ - try: - self.meths.remove('process_source') - except ValueError: - pass - - self.ensure_localedir() - - appname = getattr(self, 'appname', getattr(Context.g_module, Context.APPNAME, 'set_your_app_name')) - podir = getattr(self, 'podir', '.') - inst = getattr(self, 'install_path', '${LOCALEDIR}') - - linguas = self.path.find_node(os.path.join(podir, 'LINGUAS')) - if linguas: - # scan LINGUAS file for locales to process - with open(linguas.abspath()) as f: - langs = [] - for line in f.readlines(): - # ignore lines containing comments - if not line.startswith('#'): - langs += line.split() - re_linguas = re.compile('[-a-zA-Z_@.]+') - for lang in langs: - # Make sure that we only process lines which contain locales - if re_linguas.match(lang): - node = self.path.find_resource(os.path.join(podir, re_linguas.match(lang).group() + '.po')) - task = self.create_task('po', node, node.change_ext('.mo')) - - if inst: - filename = task.outputs[0].name - (langname, ext) = os.path.splitext(filename) - inst_file = inst + os.sep + langname + os.sep + 'LC_MESSAGES' + os.sep + appname + '.mo' - self.add_install_as(install_to=inst_file, install_from=task.outputs[0], - chmod=getattr(self, 'chmod', Utils.O644)) - - else: - Logs.pprint('RED', "Error no LINGUAS file found in po directory") - -class po(Task.Task): - """ - Compiles .po files into .gmo files - """ - run_str = '${MSGFMT} -o ${TGT} ${SRC}' - color = 'BLUE' - -class intltool(Task.Task): - """ - Calls intltool-merge to update translation files - """ - run_str = '${INTLTOOL} ${INTLFLAGS} ${INTLCACHE_ST:INTLCACHE} ${INTLPODIR} ${SRC} ${TGT}' - color = 'BLUE' - -@conf -def find_msgfmt(conf): - """ - Detects msgfmt and sets the ``MSGFMT`` variable - """ - conf.find_program('msgfmt', var='MSGFMT') - -@conf -def find_intltool_merge(conf): - """ - Detects intltool-merge - """ - if not conf.env.PERL: - conf.find_program('perl', var='PERL') - conf.env.INTLCACHE_ST = '--cache=%s' - conf.env.INTLFLAGS_DEFAULT = ['-q', '-u'] - conf.find_program('intltool-merge', interpreter='PERL', var='INTLTOOL') - -def configure(conf): - """ - Detects the program *msgfmt* and set *conf.env.MSGFMT*. - Detects the program *intltool-merge* and set *conf.env.INTLTOOL*. - It is possible to set INTLTOOL in the environment, but it must not have spaces in it:: - - $ INTLTOOL="/path/to/the program/intltool" waf configure - - If a C/C++ compiler is present, execute a compilation test to find the header *locale.h*. - """ - conf.find_msgfmt() - conf.find_intltool_merge() - if conf.env.CC or conf.env.CXX: - conf.check(header_name='locale.h') - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/irixcc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/irixcc.py deleted file mode 100644 index c3ae1ac..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/irixcc.py +++ /dev/null @@ -1,66 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# imported from samba - -""" -Compiler definition for irix/MIPSpro cc compiler -""" - -from waflib import Errors -from waflib.Tools import ccroot, ar -from waflib.Configure import conf - -@conf -def find_irixcc(conf): - v = conf.env - cc = None - if v.CC: - cc = v.CC - elif 'CC' in conf.environ: - cc = conf.environ['CC'] - if not cc: - cc = conf.find_program('cc', var='CC') - if not cc: - conf.fatal('irixcc was not found') - - try: - conf.cmd_and_log(cc + ['-version']) - except Errors.WafError: - conf.fatal('%r -version could not be executed' % cc) - - v.CC = cc - v.CC_NAME = 'irix' - -@conf -def irixcc_common_flags(conf): - v = conf.env - - v.CC_SRC_F = '' - v.CC_TGT_F = ['-c', '-o'] - v.CPPPATH_ST = '-I%s' - v.DEFINES_ST = '-D%s' - - if not v.LINK_CC: - v.LINK_CC = v.CC - - v.CCLNK_SRC_F = '' - v.CCLNK_TGT_F = ['-o'] - - v.LIB_ST = '-l%s' # template for adding libs - v.LIBPATH_ST = '-L%s' # template for adding libpaths - v.STLIB_ST = '-l%s' - v.STLIBPATH_ST = '-L%s' - - v.cprogram_PATTERN = '%s' - v.cshlib_PATTERN = 'lib%s.so' - v.cstlib_PATTERN = 'lib%s.a' - -def configure(conf): - conf.find_irixcc() - conf.find_cpp() - conf.find_ar() - conf.irixcc_common_flags() - conf.cc_load_tools() - conf.cc_add_flags() - conf.link_add_flags() - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/javaw.py b/ldb-2.0.8/third_party/waf/waflib/Tools/javaw.py deleted file mode 100644 index ceb08c2..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/javaw.py +++ /dev/null @@ -1,593 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2006-2018 (ita) - -""" -Java support - -Javac is one of the few compilers that behaves very badly: - -#. it outputs files where it wants to (-d is only for the package root) - -#. it recompiles files silently behind your back - -#. it outputs an undefined amount of files (inner classes) - -Remember that the compilation can be performed using Jython[1] rather than regular Python. Instead of -running one of the following commands:: - - ./waf configure - python waf configure - -You would have to run:: - - java -jar /path/to/jython.jar waf configure - -[1] http://www.jython.org/ - -Usage -===== - -Load the "java" tool. - -def configure(conf): - conf.load('java') - -Java tools will be autodetected and eventually, if present, the quite -standard JAVA_HOME environment variable will be used. The also standard -CLASSPATH variable is used for library searching. - -In configuration phase checks can be done on the system environment, for -example to check if a class is known in the classpath:: - - conf.check_java_class('java.io.FileOutputStream') - -or if the system supports JNI applications building:: - - conf.check_jni_headers() - - -The java tool supports compiling java code, creating jar files and -creating javadoc documentation. This can be either done separately or -together in a single definition. For example to manage them separately:: - - bld(features = 'javac', - srcdir = 'src', - compat = '1.7', - use = 'animals', - name = 'cats-src', - ) - - bld(features = 'jar', - basedir = '.', - destfile = '../cats.jar', - name = 'cats', - use = 'cats-src' - ) - - -Or together by defining all the needed attributes:: - - bld(features = 'javac jar javadoc', - srcdir = 'src/', # folder containing the sources to compile - outdir = 'src', # folder where to output the classes (in the build directory) - compat = '1.6', # java compatibility version number - classpath = ['.', '..'], - - # jar - basedir = 'src', # folder containing the classes and other files to package (must match outdir) - destfile = 'foo.jar', # do not put the destfile in the folder of the java classes! - use = 'NNN', - jaropts = ['-C', 'default/src/', '.'], # can be used to give files - manifest = 'src/Manifest.mf', # Manifest file to include - - # javadoc - javadoc_package = ['com.meow' , 'com.meow.truc.bar', 'com.meow.truc.foo'], - javadoc_output = 'javadoc', - ) - -External jar dependencies can be mapped to a standard waf "use" dependency by -setting an environment variable with a CLASSPATH prefix in the configuration, -for example:: - - conf.env.CLASSPATH_NNN = ['aaaa.jar', 'bbbb.jar'] - -and then NNN can be freely used in rules as:: - - use = 'NNN', - -In the java tool the dependencies via use are not transitive by default, as -this necessity depends on the code. To enable recursive dependency scanning -use on a specific rule: - - recurse_use = True - -Or build-wise by setting RECURSE_JAVA: - - bld.env.RECURSE_JAVA = True - -Unit tests can be integrated in the waf unit test environment using the javatest extra. -""" - -import os, shutil -from waflib import Task, Utils, Errors, Node -from waflib.Configure import conf -from waflib.TaskGen import feature, before_method, after_method, taskgen_method - -from waflib.Tools import ccroot -ccroot.USELIB_VARS['javac'] = set(['CLASSPATH', 'JAVACFLAGS']) - -SOURCE_RE = '**/*.java' -JAR_RE = '**/*' - -class_check_source = ''' -public class Test { - public static void main(String[] argv) { - Class lib; - if (argv.length < 1) { - System.err.println("Missing argument"); - System.exit(77); - } - try { - lib = Class.forName(argv[0]); - } catch (ClassNotFoundException e) { - System.err.println("ClassNotFoundException"); - System.exit(1); - } - lib = null; - System.exit(0); - } -} -''' - -@feature('javac') -@before_method('process_source') -def apply_java(self): - """ - Create a javac task for compiling *.java files*. There can be - only one javac task by task generator. - """ - Utils.def_attrs(self, jarname='', classpath='', - sourcepath='.', srcdir='.', - jar_mf_attributes={}, jar_mf_classpath=[]) - - outdir = getattr(self, 'outdir', None) - if outdir: - if not isinstance(outdir, Node.Node): - outdir = self.path.get_bld().make_node(self.outdir) - else: - outdir = self.path.get_bld() - outdir.mkdir() - self.outdir = outdir - self.env.OUTDIR = outdir.abspath() - - self.javac_task = tsk = self.create_task('javac') - tmp = [] - - srcdir = getattr(self, 'srcdir', '') - if isinstance(srcdir, Node.Node): - srcdir = [srcdir] - for x in Utils.to_list(srcdir): - if isinstance(x, Node.Node): - y = x - else: - y = self.path.find_dir(x) - if not y: - self.bld.fatal('Could not find the folder %s from %s' % (x, self.path)) - tmp.append(y) - - tsk.srcdir = tmp - - if getattr(self, 'compat', None): - tsk.env.append_value('JAVACFLAGS', ['-source', str(self.compat)]) - - if hasattr(self, 'sourcepath'): - fold = [isinstance(x, Node.Node) and x or self.path.find_dir(x) for x in self.to_list(self.sourcepath)] - names = os.pathsep.join([x.srcpath() for x in fold]) - else: - names = [x.srcpath() for x in tsk.srcdir] - - if names: - tsk.env.append_value('JAVACFLAGS', ['-sourcepath', names]) - - -@taskgen_method -def java_use_rec(self, name, **kw): - """ - Processes recursively the *use* attribute for each referred java compilation - """ - if name in self.tmp_use_seen: - return - - self.tmp_use_seen.append(name) - - try: - y = self.bld.get_tgen_by_name(name) - except Errors.WafError: - self.uselib.append(name) - return - else: - y.post() - # Add generated JAR name for CLASSPATH. Task ordering (set_run_after) - # is already guaranteed by ordering done between the single tasks - if hasattr(y, 'jar_task'): - self.use_lst.append(y.jar_task.outputs[0].abspath()) - else: - if hasattr(y,'outdir'): - self.use_lst.append(y.outdir.abspath()) - else: - self.use_lst.append(y.path.get_bld().abspath()) - - for x in self.to_list(getattr(y, 'use', [])): - self.java_use_rec(x) - -@feature('javac') -@before_method('propagate_uselib_vars') -@after_method('apply_java') -def use_javac_files(self): - """ - Processes the *use* attribute referring to other java compilations - """ - self.use_lst = [] - self.tmp_use_seen = [] - self.uselib = self.to_list(getattr(self, 'uselib', [])) - names = self.to_list(getattr(self, 'use', [])) - get = self.bld.get_tgen_by_name - for x in names: - try: - tg = get(x) - except Errors.WafError: - self.uselib.append(x) - else: - tg.post() - if hasattr(tg, 'jar_task'): - self.use_lst.append(tg.jar_task.outputs[0].abspath()) - self.javac_task.set_run_after(tg.jar_task) - self.javac_task.dep_nodes.extend(tg.jar_task.outputs) - else: - if hasattr(tg, 'outdir'): - base_node = tg.outdir - else: - base_node = tg.path.get_bld() - - self.use_lst.append(base_node.abspath()) - self.javac_task.dep_nodes.extend([x for x in base_node.ant_glob(JAR_RE, remove=False, quiet=True)]) - - for tsk in tg.tasks: - self.javac_task.set_run_after(tsk) - - # If recurse use scan is enabled recursively add use attribute for each used one - if getattr(self, 'recurse_use', False) or self.bld.env.RECURSE_JAVA: - self.java_use_rec(x) - - self.env.append_value('CLASSPATH', self.use_lst) - -@feature('javac') -@after_method('apply_java', 'propagate_uselib_vars', 'use_javac_files') -def set_classpath(self): - """ - Sets the CLASSPATH value on the *javac* task previously created. - """ - if getattr(self, 'classpath', None): - self.env.append_unique('CLASSPATH', getattr(self, 'classpath', [])) - for x in self.tasks: - x.env.CLASSPATH = os.pathsep.join(self.env.CLASSPATH) + os.pathsep - -@feature('jar') -@after_method('apply_java', 'use_javac_files') -@before_method('process_source') -def jar_files(self): - """ - Creates a jar task (one maximum per task generator) - """ - destfile = getattr(self, 'destfile', 'test.jar') - jaropts = getattr(self, 'jaropts', []) - manifest = getattr(self, 'manifest', None) - - basedir = getattr(self, 'basedir', None) - if basedir: - if not isinstance(self.basedir, Node.Node): - basedir = self.path.get_bld().make_node(basedir) - else: - basedir = self.path.get_bld() - if not basedir: - self.bld.fatal('Could not find the basedir %r for %r' % (self.basedir, self)) - - self.jar_task = tsk = self.create_task('jar_create') - if manifest: - jarcreate = getattr(self, 'jarcreate', 'cfm') - if not isinstance(manifest,Node.Node): - node = self.path.find_resource(manifest) - else: - node = manifest - if not node: - self.bld.fatal('invalid manifest file %r for %r' % (manifest, self)) - tsk.dep_nodes.append(node) - jaropts.insert(0, node.abspath()) - else: - jarcreate = getattr(self, 'jarcreate', 'cf') - if not isinstance(destfile, Node.Node): - destfile = self.path.find_or_declare(destfile) - if not destfile: - self.bld.fatal('invalid destfile %r for %r' % (destfile, self)) - tsk.set_outputs(destfile) - tsk.basedir = basedir - - jaropts.append('-C') - jaropts.append(basedir.bldpath()) - jaropts.append('.') - - tsk.env.JAROPTS = jaropts - tsk.env.JARCREATE = jarcreate - - if getattr(self, 'javac_task', None): - tsk.set_run_after(self.javac_task) - -@feature('jar') -@after_method('jar_files') -def use_jar_files(self): - """ - Processes the *use* attribute to set the build order on the - tasks created by another task generator. - """ - self.uselib = self.to_list(getattr(self, 'uselib', [])) - names = self.to_list(getattr(self, 'use', [])) - get = self.bld.get_tgen_by_name - for x in names: - try: - y = get(x) - except Errors.WafError: - self.uselib.append(x) - else: - y.post() - self.jar_task.run_after.update(y.tasks) - -class JTask(Task.Task): - """ - Base class for java and jar tasks; provides functionality to run long commands - """ - def split_argfile(self, cmd): - inline = [cmd[0]] - infile = [] - for x in cmd[1:]: - # jar and javac do not want -J flags in @file - if x.startswith('-J'): - inline.append(x) - else: - infile.append(self.quote_flag(x)) - return (inline, infile) - -class jar_create(JTask): - """ - Creates a jar file - """ - color = 'GREEN' - run_str = '${JAR} ${JARCREATE} ${TGT} ${JAROPTS}' - - def runnable_status(self): - """ - Wait for dependent tasks to be executed, then read the - files to update the list of inputs. - """ - for t in self.run_after: - if not t.hasrun: - return Task.ASK_LATER - if not self.inputs: - try: - self.inputs = [x for x in self.basedir.ant_glob(JAR_RE, remove=False, quiet=True) if id(x) != id(self.outputs[0])] - except Exception: - raise Errors.WafError('Could not find the basedir %r for %r' % (self.basedir, self)) - return super(jar_create, self).runnable_status() - -class javac(JTask): - """ - Compiles java files - """ - color = 'BLUE' - run_str = '${JAVAC} -classpath ${CLASSPATH} -d ${OUTDIR} ${JAVACFLAGS} ${SRC}' - vars = ['CLASSPATH', 'JAVACFLAGS', 'JAVAC', 'OUTDIR'] - """ - The javac task will be executed again if the variables CLASSPATH, JAVACFLAGS, JAVAC or OUTDIR change. - """ - def uid(self): - """Identify java tasks by input&output folder""" - lst = [self.__class__.__name__, self.generator.outdir.abspath()] - for x in self.srcdir: - lst.append(x.abspath()) - return Utils.h_list(lst) - - def runnable_status(self): - """ - Waits for dependent tasks to be complete, then read the file system to find the input nodes. - """ - for t in self.run_after: - if not t.hasrun: - return Task.ASK_LATER - - if not self.inputs: - self.inputs = [] - for x in self.srcdir: - if x.exists(): - self.inputs.extend(x.ant_glob(SOURCE_RE, remove=False, quiet=True)) - return super(javac, self).runnable_status() - - def post_run(self): - """ - List class files created - """ - for node in self.generator.outdir.ant_glob('**/*.class', quiet=True): - self.generator.bld.node_sigs[node] = self.uid() - self.generator.bld.task_sigs[self.uid()] = self.cache_sig - -@feature('javadoc') -@after_method('process_rule') -def create_javadoc(self): - """ - Creates a javadoc task (feature 'javadoc') - """ - tsk = self.create_task('javadoc') - tsk.classpath = getattr(self, 'classpath', []) - self.javadoc_package = Utils.to_list(self.javadoc_package) - if not isinstance(self.javadoc_output, Node.Node): - self.javadoc_output = self.bld.path.find_or_declare(self.javadoc_output) - -class javadoc(Task.Task): - """ - Builds java documentation - """ - color = 'BLUE' - - def __str__(self): - return '%s: %s -> %s\n' % (self.__class__.__name__, self.generator.srcdir, self.generator.javadoc_output) - - def run(self): - env = self.env - bld = self.generator.bld - wd = bld.bldnode - - #add src node + bld node (for generated java code) - srcpath = self.generator.path.abspath() + os.sep + self.generator.srcdir - srcpath += os.pathsep - srcpath += self.generator.path.get_bld().abspath() + os.sep + self.generator.srcdir - - classpath = env.CLASSPATH - classpath += os.pathsep - classpath += os.pathsep.join(self.classpath) - classpath = "".join(classpath) - - self.last_cmd = lst = [] - lst.extend(Utils.to_list(env.JAVADOC)) - lst.extend(['-d', self.generator.javadoc_output.abspath()]) - lst.extend(['-sourcepath', srcpath]) - lst.extend(['-classpath', classpath]) - lst.extend(['-subpackages']) - lst.extend(self.generator.javadoc_package) - lst = [x for x in lst if x] - - self.generator.bld.cmd_and_log(lst, cwd=wd, env=env.env or None, quiet=0) - - def post_run(self): - nodes = self.generator.javadoc_output.ant_glob('**', quiet=True) - for node in nodes: - self.generator.bld.node_sigs[node] = self.uid() - self.generator.bld.task_sigs[self.uid()] = self.cache_sig - -def configure(self): - """ - Detects the javac, java and jar programs - """ - # If JAVA_PATH is set, we prepend it to the path list - java_path = self.environ['PATH'].split(os.pathsep) - v = self.env - - if 'JAVA_HOME' in self.environ: - java_path = [os.path.join(self.environ['JAVA_HOME'], 'bin')] + java_path - self.env.JAVA_HOME = [self.environ['JAVA_HOME']] - - for x in 'javac java jar javadoc'.split(): - self.find_program(x, var=x.upper(), path_list=java_path, mandatory=(x not in ('javadoc'))) - - if 'CLASSPATH' in self.environ: - v.CLASSPATH = self.environ['CLASSPATH'] - - if not v.JAR: - self.fatal('jar is required for making java packages') - if not v.JAVAC: - self.fatal('javac is required for compiling java classes') - - v.JARCREATE = 'cf' # can use cvf - v.JAVACFLAGS = [] - -@conf -def check_java_class(self, classname, with_classpath=None): - """ - Checks if the specified java class exists - - :param classname: class to check, like java.util.HashMap - :type classname: string - :param with_classpath: additional classpath to give - :type with_classpath: string - """ - javatestdir = '.waf-javatest' - - classpath = javatestdir - if self.env.CLASSPATH: - classpath += os.pathsep + self.env.CLASSPATH - if isinstance(with_classpath, str): - classpath += os.pathsep + with_classpath - - shutil.rmtree(javatestdir, True) - os.mkdir(javatestdir) - - Utils.writef(os.path.join(javatestdir, 'Test.java'), class_check_source) - - # Compile the source - self.exec_command(self.env.JAVAC + [os.path.join(javatestdir, 'Test.java')], shell=False) - - # Try to run the app - cmd = self.env.JAVA + ['-cp', classpath, 'Test', classname] - self.to_log("%s\n" % str(cmd)) - found = self.exec_command(cmd, shell=False) - - self.msg('Checking for java class %s' % classname, not found) - - shutil.rmtree(javatestdir, True) - - return found - -@conf -def check_jni_headers(conf): - """ - Checks for jni headers and libraries. On success the conf.env variables xxx_JAVA are added for use in C/C++ targets:: - - def options(opt): - opt.load('compiler_c') - - def configure(conf): - conf.load('compiler_c java') - conf.check_jni_headers() - - def build(bld): - bld.shlib(source='a.c', target='app', use='JAVA') - """ - if not conf.env.CC_NAME and not conf.env.CXX_NAME: - conf.fatal('load a compiler first (gcc, g++, ..)') - - if not conf.env.JAVA_HOME: - conf.fatal('set JAVA_HOME in the system environment') - - # jni requires the jvm - javaHome = conf.env.JAVA_HOME[0] - - dir = conf.root.find_dir(conf.env.JAVA_HOME[0] + '/include') - if dir is None: - dir = conf.root.find_dir(conf.env.JAVA_HOME[0] + '/../Headers') # think different?! - if dir is None: - conf.fatal('JAVA_HOME does not seem to be set properly') - - f = dir.ant_glob('**/(jni|jni_md).h') - incDirs = [x.parent.abspath() for x in f] - - dir = conf.root.find_dir(conf.env.JAVA_HOME[0]) - f = dir.ant_glob('**/*jvm.(so|dll|dylib)') - libDirs = [x.parent.abspath() for x in f] or [javaHome] - - # On windows, we need both the .dll and .lib to link. On my JDK, they are - # in different directories... - f = dir.ant_glob('**/*jvm.(lib)') - if f: - libDirs = [[x, y.parent.abspath()] for x in libDirs for y in f] - - if conf.env.DEST_OS == 'freebsd': - conf.env.append_unique('LINKFLAGS_JAVA', '-pthread') - for d in libDirs: - try: - conf.check(header_name='jni.h', define_name='HAVE_JNI_H', lib='jvm', - libpath=d, includes=incDirs, uselib_store='JAVA', uselib='JAVA') - except Exception: - pass - else: - break - else: - conf.fatal('could not find lib jvm in %r (see config.log)' % libDirs) - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/ldc2.py b/ldb-2.0.8/third_party/waf/waflib/Tools/ldc2.py deleted file mode 100644 index a51c344..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/ldc2.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Alex Rønne Petersen, 2012 (alexrp/Zor) - -from waflib.Tools import ar, d -from waflib.Configure import conf - -@conf -def find_ldc2(conf): - """ - Finds the program *ldc2* and set the variable *D* - """ - conf.find_program(['ldc2'], var='D') - - out = conf.cmd_and_log(conf.env.D + ['-version']) - if out.find("based on DMD v2.") == -1: - conf.fatal("detected compiler is not ldc2") - -@conf -def common_flags_ldc2(conf): - """ - Sets the D flags required by *ldc2* - """ - v = conf.env - - v.D_SRC_F = ['-c'] - v.D_TGT_F = '-of%s' - - v.D_LINKER = v.D - v.DLNK_SRC_F = '' - v.DLNK_TGT_F = '-of%s' - v.DINC_ST = '-I%s' - - v.DSHLIB_MARKER = v.DSTLIB_MARKER = '' - v.DSTLIB_ST = v.DSHLIB_ST = '-L-l%s' - v.DSTLIBPATH_ST = v.DLIBPATH_ST = '-L-L%s' - - v.LINKFLAGS_dshlib = ['-L-shared'] - - v.DHEADER_ext = '.di' - v.DFLAGS_d_with_header = ['-H', '-Hf'] - v.D_HDR_F = '%s' - - v.LINKFLAGS = [] - v.DFLAGS_dshlib = ['-relocation-model=pic'] - -def configure(conf): - """ - Configuration for *ldc2* - """ - conf.find_ldc2() - conf.load('ar') - conf.load('d') - conf.common_flags_ldc2() - conf.d_platform_flags() - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/lua.py b/ldb-2.0.8/third_party/waf/waflib/Tools/lua.py deleted file mode 100644 index 15a333a..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/lua.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Sebastian Schlingmann, 2008 -# Thomas Nagy, 2008-2018 (ita) - -""" -Lua support. - -Compile *.lua* files into *.luac*:: - - def configure(conf): - conf.load('lua') - conf.env.LUADIR = '/usr/local/share/myapp/scripts/' - def build(bld): - bld(source='foo.lua') -""" - -from waflib.TaskGen import extension -from waflib import Task - -@extension('.lua') -def add_lua(self, node): - tsk = self.create_task('luac', node, node.change_ext('.luac')) - inst_to = getattr(self, 'install_path', self.env.LUADIR and '${LUADIR}' or None) - if inst_to: - self.add_install_files(install_to=inst_to, install_from=tsk.outputs) - return tsk - -class luac(Task.Task): - run_str = '${LUAC} -s -o ${TGT} ${SRC}' - color = 'PINK' - -def configure(conf): - """ - Detect the luac compiler and set *conf.env.LUAC* - """ - conf.find_program('luac', var='LUAC') - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/md5_tstamp.py b/ldb-2.0.8/third_party/waf/waflib/Tools/md5_tstamp.py deleted file mode 100644 index d1569fa..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/md5_tstamp.py +++ /dev/null @@ -1,41 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 - -""" -Re-calculate md5 hashes of files only when the file time have changed:: - - def options(opt): - opt.load('md5_tstamp') - -The hashes can also reflect either the file contents (STRONGEST=True) or the -file time and file size. - -The performance benefits of this module are usually insignificant. -""" - -import os, stat -from waflib import Utils, Build, Node - -STRONGEST = True - -Build.SAVED_ATTRS.append('hashes_md5_tstamp') -def h_file(self): - filename = self.abspath() - st = os.stat(filename) - - cache = self.ctx.hashes_md5_tstamp - if filename in cache and cache[filename][0] == st.st_mtime: - return cache[filename][1] - - if STRONGEST: - ret = Utils.h_file(filename) - else: - if stat.S_ISDIR(st[stat.ST_MODE]): - raise IOError('Not a file') - ret = Utils.md5(str((st.st_mtime, st.st_size)).encode()).digest() - - cache[filename] = (st.st_mtime, ret) - return ret -h_file.__doc__ = Node.Node.h_file.__doc__ -Node.Node.h_file = h_file - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/msvc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/msvc.py deleted file mode 100644 index f169c7f..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/msvc.py +++ /dev/null @@ -1,1020 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Carlos Rafael Giani, 2006 (dv) -# Tamas Pal, 2007 (folti) -# Nicolas Mercier, 2009 -# Matt Clarkson, 2012 - -""" -Microsoft Visual C++/Intel C++ compiler support - -If you get detection problems, first try any of the following:: - - chcp 65001 - set PYTHONIOENCODING=... - set PYTHONLEGACYWINDOWSSTDIO=1 - -Usage:: - - $ waf configure --msvc_version="msvc 10.0,msvc 9.0" --msvc_target="x64" - -or:: - - def configure(conf): - conf.env.MSVC_VERSIONS = ['msvc 10.0', 'msvc 9.0', 'msvc 8.0', 'msvc 7.1', 'msvc 7.0', 'msvc 6.0', 'wsdk 7.0', 'intel 11', 'PocketPC 9.0', 'Smartphone 8.0'] - conf.env.MSVC_TARGETS = ['x64'] - conf.load('msvc') - -or:: - - def configure(conf): - conf.load('msvc', funs='no_autodetect') - conf.check_lib_msvc('gdi32') - conf.check_libs_msvc('kernel32 user32') - def build(bld): - tg = bld.program(source='main.c', target='app', use='KERNEL32 USER32 GDI32') - -Platforms and targets will be tested in the order they appear; -the first good configuration will be used. - -To force testing all the configurations that are not used, use the ``--no-msvc-lazy`` option -or set ``conf.env.MSVC_LAZY_AUTODETECT=False``. - -Supported platforms: ia64, x64, x86, x86_amd64, x86_ia64, x86_arm, amd64_x86, amd64_arm - -Compilers supported: - -* msvc => Visual Studio, versions 6.0 (VC 98, VC .NET 2002) to 15 (Visual Studio 2017) -* wsdk => Windows SDK, versions 6.0, 6.1, 7.0, 7.1, 8.0 -* icl => Intel compiler, versions 9, 10, 11, 13 -* winphone => Visual Studio to target Windows Phone 8 native (version 8.0 for now) -* Smartphone => Compiler/SDK for Smartphone devices (armv4/v4i) -* PocketPC => Compiler/SDK for PocketPC devices (armv4/v4i) - -To use WAF in a VS2008 Make file project (see http://code.google.com/p/waf/issues/detail?id=894) -You may consider to set the environment variable "VS_UNICODE_OUTPUT" to nothing before calling waf. -So in your project settings use something like 'cmd.exe /C "set VS_UNICODE_OUTPUT=& set PYTHONUNBUFFERED=true & waf build"'. -cmd.exe /C "chcp 1252 & set PYTHONUNBUFFERED=true && set && waf configure" -Setting PYTHONUNBUFFERED gives the unbuffered output. -""" - -import os, sys, re, traceback -from waflib import Utils, Logs, Options, Errors -from waflib.TaskGen import after_method, feature - -from waflib.Configure import conf -from waflib.Tools import ccroot, c, cxx, ar - -g_msvc_systemlibs = ''' -aclui activeds ad1 adptif adsiid advapi32 asycfilt authz bhsupp bits bufferoverflowu cabinet -cap certadm certidl ciuuid clusapi comctl32 comdlg32 comsupp comsuppd comsuppw comsuppwd comsvcs -credui crypt32 cryptnet cryptui d3d8thk daouuid dbgeng dbghelp dciman32 ddao35 ddao35d -ddao35u ddao35ud delayimp dhcpcsvc dhcpsapi dlcapi dnsapi dsprop dsuiext dtchelp -faultrep fcachdll fci fdi framedyd framedyn gdi32 gdiplus glauxglu32 gpedit gpmuuid -gtrts32w gtrtst32hlink htmlhelp httpapi icm32 icmui imagehlp imm32 iphlpapi iprop -kernel32 ksguid ksproxy ksuser libcmt libcmtd libcpmt libcpmtd loadperf lz32 mapi -mapi32 mgmtapi minidump mmc mobsync mpr mprapi mqoa mqrt msacm32 mscms mscoree -msdasc msimg32 msrating mstask msvcmrt msvcurt msvcurtd mswsock msxml2 mtx mtxdm -netapi32 nmapinmsupp npptools ntdsapi ntdsbcli ntmsapi ntquery odbc32 odbcbcp -odbccp32 oldnames ole32 oleacc oleaut32 oledb oledlgolepro32 opends60 opengl32 -osptk parser pdh penter pgobootrun pgort powrprof psapi ptrustm ptrustmd ptrustu -ptrustud qosname rasapi32 rasdlg rassapi resutils riched20 rpcndr rpcns4 rpcrt4 rtm -rtutils runtmchk scarddlg scrnsave scrnsavw secur32 sensapi setupapi sfc shell32 -shfolder shlwapi sisbkup snmpapi sporder srclient sti strsafe svcguid tapi32 thunk32 -traffic unicows url urlmon user32 userenv usp10 uuid uxtheme vcomp vcompd vdmdbg -version vfw32 wbemuuid webpost wiaguid wininet winmm winscard winspool winstrm -wintrust wldap32 wmiutils wow32 ws2_32 wsnmp32 wsock32 wst wtsapi32 xaswitch xolehlp -'''.split() -"""importlibs provided by MSVC/Platform SDK. Do NOT search them""" - -all_msvc_platforms = [ ('x64', 'amd64'), ('x86', 'x86'), ('ia64', 'ia64'), - ('x86_amd64', 'amd64'), ('x86_ia64', 'ia64'), ('x86_arm', 'arm'), ('x86_arm64', 'arm64'), - ('amd64_x86', 'x86'), ('amd64_arm', 'arm'), ('amd64_arm64', 'arm64') ] -"""List of msvc platforms""" - -all_wince_platforms = [ ('armv4', 'arm'), ('armv4i', 'arm'), ('mipsii', 'mips'), ('mipsii_fp', 'mips'), ('mipsiv', 'mips'), ('mipsiv_fp', 'mips'), ('sh4', 'sh'), ('x86', 'cex86') ] -"""List of wince platforms""" - -all_icl_platforms = [ ('intel64', 'amd64'), ('em64t', 'amd64'), ('ia32', 'x86'), ('Itanium', 'ia64')] -"""List of icl platforms""" - -def options(opt): - opt.add_option('--msvc_version', type='string', help = 'msvc version, eg: "msvc 10.0,msvc 9.0"', default='') - opt.add_option('--msvc_targets', type='string', help = 'msvc targets, eg: "x64,arm"', default='') - opt.add_option('--no-msvc-lazy', action='store_false', help = 'lazily check msvc target environments', default=True, dest='msvc_lazy') - -@conf -def setup_msvc(conf, versiondict): - """ - Checks installed compilers and targets and returns the first combination from the user's - options, env, or the global supported lists that checks. - - :param versiondict: dict(platform -> dict(architecture -> configuration)) - :type versiondict: dict(string -> dict(string -> target_compiler) - :return: the compiler, revision, path, include dirs, library paths and target architecture - :rtype: tuple of strings - """ - platforms = getattr(Options.options, 'msvc_targets', '').split(',') - if platforms == ['']: - platforms=Utils.to_list(conf.env.MSVC_TARGETS) or [i for i,j in all_msvc_platforms+all_icl_platforms+all_wince_platforms] - desired_versions = getattr(Options.options, 'msvc_version', '').split(',') - if desired_versions == ['']: - desired_versions = conf.env.MSVC_VERSIONS or list(reversed(sorted(versiondict.keys()))) - - # Override lazy detection by evaluating after the fact. - lazy_detect = getattr(Options.options, 'msvc_lazy', True) - if conf.env.MSVC_LAZY_AUTODETECT is False: - lazy_detect = False - - if not lazy_detect: - for val in versiondict.values(): - for arch in list(val.keys()): - cfg = val[arch] - cfg.evaluate() - if not cfg.is_valid: - del val[arch] - conf.env.MSVC_INSTALLED_VERSIONS = versiondict - - for version in desired_versions: - Logs.debug('msvc: detecting %r - %r', version, desired_versions) - try: - targets = versiondict[version] - except KeyError: - continue - - seen = set() - for arch in platforms: - if arch in seen: - continue - else: - seen.add(arch) - try: - cfg = targets[arch] - except KeyError: - continue - - cfg.evaluate() - if cfg.is_valid: - compiler,revision = version.rsplit(' ', 1) - return compiler,revision,cfg.bindirs,cfg.incdirs,cfg.libdirs,cfg.cpu - conf.fatal('msvc: Impossible to find a valid architecture for building %r - %r' % (desired_versions, list(versiondict.keys()))) - -@conf -def get_msvc_version(conf, compiler, version, target, vcvars): - """ - Checks that an installed compiler actually runs and uses vcvars to obtain the - environment needed by the compiler. - - :param compiler: compiler type, for looking up the executable name - :param version: compiler version, for debugging only - :param target: target architecture - :param vcvars: batch file to run to check the environment - :return: the location of the compiler executable, the location of include dirs, and the library paths - :rtype: tuple of strings - """ - Logs.debug('msvc: get_msvc_version: %r %r %r', compiler, version, target) - - try: - conf.msvc_cnt += 1 - except AttributeError: - conf.msvc_cnt = 1 - batfile = conf.bldnode.make_node('waf-print-msvc-%d.bat' % conf.msvc_cnt) - batfile.write("""@echo off -set INCLUDE= -set LIB= -call "%s" %s -echo PATH=%%PATH%% -echo INCLUDE=%%INCLUDE%% -echo LIB=%%LIB%%;%%LIBPATH%% -""" % (vcvars,target)) - sout = conf.cmd_and_log(['cmd.exe', '/E:on', '/V:on', '/C', batfile.abspath()]) - lines = sout.splitlines() - - if not lines[0]: - lines.pop(0) - - MSVC_PATH = MSVC_INCDIR = MSVC_LIBDIR = None - for line in lines: - if line.startswith('PATH='): - path = line[5:] - MSVC_PATH = path.split(';') - elif line.startswith('INCLUDE='): - MSVC_INCDIR = [i for i in line[8:].split(';') if i] - elif line.startswith('LIB='): - MSVC_LIBDIR = [i for i in line[4:].split(';') if i] - if None in (MSVC_PATH, MSVC_INCDIR, MSVC_LIBDIR): - conf.fatal('msvc: Could not find a valid architecture for building (get_msvc_version_3)') - - # Check if the compiler is usable at all. - # The detection may return 64-bit versions even on 32-bit systems, and these would fail to run. - env = dict(os.environ) - env.update(PATH = path) - compiler_name, linker_name, lib_name = _get_prog_names(conf, compiler) - cxx = conf.find_program(compiler_name, path_list=MSVC_PATH) - - # delete CL if exists. because it could contain parameters which can change cl's behaviour rather catastrophically. - if 'CL' in env: - del(env['CL']) - - try: - conf.cmd_and_log(cxx + ['/help'], env=env) - except UnicodeError: - st = traceback.format_exc() - if conf.logger: - conf.logger.error(st) - conf.fatal('msvc: Unicode error - check the code page?') - except Exception as e: - Logs.debug('msvc: get_msvc_version: %r %r %r -> failure %s', compiler, version, target, str(e)) - conf.fatal('msvc: cannot run the compiler in get_msvc_version (run with -v to display errors)') - else: - Logs.debug('msvc: get_msvc_version: %r %r %r -> OK', compiler, version, target) - finally: - conf.env[compiler_name] = '' - - return (MSVC_PATH, MSVC_INCDIR, MSVC_LIBDIR) - -def gather_wince_supported_platforms(): - """ - Checks SmartPhones SDKs - - :param versions: list to modify - :type versions: list - """ - supported_wince_platforms = [] - try: - ce_sdk = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Microsoft\\Windows CE Tools\\SDKs') - except OSError: - try: - ce_sdk = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Microsoft\\Windows CE Tools\\SDKs') - except OSError: - ce_sdk = '' - if not ce_sdk: - return supported_wince_platforms - - index = 0 - while 1: - try: - sdk_device = Utils.winreg.EnumKey(ce_sdk, index) - sdk = Utils.winreg.OpenKey(ce_sdk, sdk_device) - except OSError: - break - index += 1 - try: - path,type = Utils.winreg.QueryValueEx(sdk, 'SDKRootDir') - except OSError: - try: - path,type = Utils.winreg.QueryValueEx(sdk,'SDKInformation') - except OSError: - continue - path,xml = os.path.split(path) - path = str(path) - path,device = os.path.split(path) - if not device: - path,device = os.path.split(path) - platforms = [] - for arch,compiler in all_wince_platforms: - if os.path.isdir(os.path.join(path, device, 'Lib', arch)): - platforms.append((arch, compiler, os.path.join(path, device, 'Include', arch), os.path.join(path, device, 'Lib', arch))) - if platforms: - supported_wince_platforms.append((device, platforms)) - return supported_wince_platforms - -def gather_msvc_detected_versions(): - #Detected MSVC versions! - version_pattern = re.compile(r'^(\d\d?\.\d\d?)(Exp)?$') - detected_versions = [] - for vcver,vcvar in (('VCExpress','Exp'), ('VisualStudio','')): - prefix = 'SOFTWARE\\Wow6432node\\Microsoft\\' + vcver - try: - all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, prefix) - except OSError: - prefix = 'SOFTWARE\\Microsoft\\' + vcver - try: - all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, prefix) - except OSError: - continue - - index = 0 - while 1: - try: - version = Utils.winreg.EnumKey(all_versions, index) - except OSError: - break - index += 1 - match = version_pattern.match(version) - if match: - versionnumber = float(match.group(1)) - else: - continue - detected_versions.append((versionnumber, version+vcvar, prefix+'\\'+version)) - def fun(tup): - return tup[0] - - detected_versions.sort(key = fun) - return detected_versions - -class target_compiler(object): - """ - Wrap a compiler configuration; call evaluate() to determine - whether the configuration is usable. - """ - def __init__(self, ctx, compiler, cpu, version, bat_target, bat, callback=None): - """ - :param ctx: configuration context to use to eventually get the version environment - :param compiler: compiler name - :param cpu: target cpu - :param version: compiler version number - :param bat_target: ? - :param bat: path to the batch file to run - """ - self.conf = ctx - self.name = None - self.is_valid = False - self.is_done = False - - self.compiler = compiler - self.cpu = cpu - self.version = version - self.bat_target = bat_target - self.bat = bat - self.callback = callback - - def evaluate(self): - if self.is_done: - return - self.is_done = True - try: - vs = self.conf.get_msvc_version(self.compiler, self.version, self.bat_target, self.bat) - except Errors.ConfigurationError: - self.is_valid = False - return - if self.callback: - vs = self.callback(self, vs) - self.is_valid = True - (self.bindirs, self.incdirs, self.libdirs) = vs - - def __str__(self): - return str((self.compiler, self.cpu, self.version, self.bat_target, self.bat)) - - def __repr__(self): - return repr((self.compiler, self.cpu, self.version, self.bat_target, self.bat)) - -@conf -def gather_wsdk_versions(conf, versions): - """ - Use winreg to add the msvc versions to the input list - - :param versions: list to modify - :type versions: list - """ - version_pattern = re.compile(r'^v..?.?\...?.?') - try: - all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Microsoft\\Microsoft SDKs\\Windows') - except OSError: - try: - all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows') - except OSError: - return - index = 0 - while 1: - try: - version = Utils.winreg.EnumKey(all_versions, index) - except OSError: - break - index += 1 - if not version_pattern.match(version): - continue - try: - msvc_version = Utils.winreg.OpenKey(all_versions, version) - path,type = Utils.winreg.QueryValueEx(msvc_version,'InstallationFolder') - except OSError: - continue - if path and os.path.isfile(os.path.join(path, 'bin', 'SetEnv.cmd')): - targets = {} - for target,arch in all_msvc_platforms: - targets[target] = target_compiler(conf, 'wsdk', arch, version, '/'+target, os.path.join(path, 'bin', 'SetEnv.cmd')) - versions['wsdk ' + version[1:]] = targets - -@conf -def gather_msvc_targets(conf, versions, version, vc_path): - #Looking for normal MSVC compilers! - targets = {} - - if os.path.isfile(os.path.join(vc_path, 'VC', 'Auxiliary', 'Build', 'vcvarsall.bat')): - for target,realtarget in all_msvc_platforms[::-1]: - targets[target] = target_compiler(conf, 'msvc', realtarget, version, target, os.path.join(vc_path, 'VC', 'Auxiliary', 'Build', 'vcvarsall.bat')) - elif os.path.isfile(os.path.join(vc_path, 'vcvarsall.bat')): - for target,realtarget in all_msvc_platforms[::-1]: - targets[target] = target_compiler(conf, 'msvc', realtarget, version, target, os.path.join(vc_path, 'vcvarsall.bat')) - elif os.path.isfile(os.path.join(vc_path, 'Common7', 'Tools', 'vsvars32.bat')): - targets['x86'] = target_compiler(conf, 'msvc', 'x86', version, 'x86', os.path.join(vc_path, 'Common7', 'Tools', 'vsvars32.bat')) - elif os.path.isfile(os.path.join(vc_path, 'Bin', 'vcvars32.bat')): - targets['x86'] = target_compiler(conf, 'msvc', 'x86', version, '', os.path.join(vc_path, 'Bin', 'vcvars32.bat')) - if targets: - versions['msvc %s' % version] = targets - -@conf -def gather_wince_targets(conf, versions, version, vc_path, vsvars, supported_platforms): - #Looking for Win CE compilers! - for device,platforms in supported_platforms: - targets = {} - for platform,compiler,include,lib in platforms: - winCEpath = os.path.join(vc_path, 'ce') - if not os.path.isdir(winCEpath): - continue - - if os.path.isdir(os.path.join(winCEpath, 'lib', platform)): - bindirs = [os.path.join(winCEpath, 'bin', compiler), os.path.join(winCEpath, 'bin', 'x86_'+compiler)] - incdirs = [os.path.join(winCEpath, 'include'), os.path.join(winCEpath, 'atlmfc', 'include'), include] - libdirs = [os.path.join(winCEpath, 'lib', platform), os.path.join(winCEpath, 'atlmfc', 'lib', platform), lib] - def combine_common(obj, compiler_env): - # TODO this is likely broken, remove in waf 2.1 - (common_bindirs,_1,_2) = compiler_env - return (bindirs + common_bindirs, incdirs, libdirs) - targets[platform] = target_compiler(conf, 'msvc', platform, version, 'x86', vsvars, combine_common) - if targets: - versions[device + ' ' + version] = targets - -@conf -def gather_winphone_targets(conf, versions, version, vc_path, vsvars): - #Looking for WinPhone compilers - targets = {} - for target,realtarget in all_msvc_platforms[::-1]: - targets[target] = target_compiler(conf, 'winphone', realtarget, version, target, vsvars) - if targets: - versions['winphone ' + version] = targets - -@conf -def gather_vswhere_versions(conf, versions): - try: - import json - except ImportError: - Logs.error('Visual Studio 2017 detection requires Python 2.6') - return - - prg_path = os.environ.get('ProgramFiles(x86)', os.environ.get('ProgramFiles', 'C:\\Program Files (x86)')) - - vswhere = os.path.join(prg_path, 'Microsoft Visual Studio', 'Installer', 'vswhere.exe') - args = [vswhere, '-products', '*', '-legacy', '-format', 'json'] - try: - txt = conf.cmd_and_log(args) - except Errors.WafError as e: - Logs.debug('msvc: vswhere.exe failed %s', e) - return - - if sys.version_info[0] < 3: - txt = txt.decode(Utils.console_encoding()) - - arr = json.loads(txt) - arr.sort(key=lambda x: x['installationVersion']) - for entry in arr: - ver = entry['installationVersion'] - ver = str('.'.join(ver.split('.')[:2])) - path = str(os.path.abspath(entry['installationPath'])) - if os.path.exists(path) and ('msvc %s' % ver) not in versions: - conf.gather_msvc_targets(versions, ver, path) - -@conf -def gather_msvc_versions(conf, versions): - vc_paths = [] - for (v,version,reg) in gather_msvc_detected_versions(): - try: - try: - msvc_version = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, reg + "\\Setup\\VC") - except OSError: - msvc_version = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, reg + "\\Setup\\Microsoft Visual C++") - path,type = Utils.winreg.QueryValueEx(msvc_version, 'ProductDir') - except OSError: - try: - msvc_version = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Wow6432node\\Microsoft\\VisualStudio\\SxS\\VS7") - path,type = Utils.winreg.QueryValueEx(msvc_version, version) - except OSError: - continue - else: - vc_paths.append((version, os.path.abspath(str(path)))) - continue - else: - vc_paths.append((version, os.path.abspath(str(path)))) - - wince_supported_platforms = gather_wince_supported_platforms() - - for version,vc_path in vc_paths: - vs_path = os.path.dirname(vc_path) - vsvars = os.path.join(vs_path, 'Common7', 'Tools', 'vsvars32.bat') - if wince_supported_platforms and os.path.isfile(vsvars): - conf.gather_wince_targets(versions, version, vc_path, vsvars, wince_supported_platforms) - - # WP80 works with 11.0Exp and 11.0, both of which resolve to the same vc_path. - # Stop after one is found. - for version,vc_path in vc_paths: - vs_path = os.path.dirname(vc_path) - vsvars = os.path.join(vs_path, 'VC', 'WPSDK', 'WP80', 'vcvarsphoneall.bat') - if os.path.isfile(vsvars): - conf.gather_winphone_targets(versions, '8.0', vc_path, vsvars) - break - - for version,vc_path in vc_paths: - vs_path = os.path.dirname(vc_path) - conf.gather_msvc_targets(versions, version, vc_path) - -@conf -def gather_icl_versions(conf, versions): - """ - Checks ICL compilers - - :param versions: list to modify - :type versions: list - """ - version_pattern = re.compile(r'^...?.?\....?.?') - try: - all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Intel\\Compilers\\C++') - except OSError: - try: - all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Intel\\Compilers\\C++') - except OSError: - return - index = 0 - while 1: - try: - version = Utils.winreg.EnumKey(all_versions, index) - except OSError: - break - index += 1 - if not version_pattern.match(version): - continue - targets = {} - for target,arch in all_icl_platforms: - if target=='intel64': - targetDir='EM64T_NATIVE' - else: - targetDir=target - try: - Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir) - icl_version=Utils.winreg.OpenKey(all_versions,version) - path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') - except OSError: - pass - else: - batch_file=os.path.join(path,'bin','iclvars.bat') - if os.path.isfile(batch_file): - targets[target] = target_compiler(conf, 'intel', arch, version, target, batch_file) - for target,arch in all_icl_platforms: - try: - icl_version = Utils.winreg.OpenKey(all_versions, version+'\\'+target) - path,type = Utils.winreg.QueryValueEx(icl_version,'ProductDir') - except OSError: - continue - else: - batch_file=os.path.join(path,'bin','iclvars.bat') - if os.path.isfile(batch_file): - targets[target] = target_compiler(conf, 'intel', arch, version, target, batch_file) - major = version[0:2] - versions['intel ' + major] = targets - -@conf -def gather_intel_composer_versions(conf, versions): - """ - Checks ICL compilers that are part of Intel Composer Suites - - :param versions: list to modify - :type versions: list - """ - version_pattern = re.compile(r'^...?.?\...?.?.?') - try: - all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Wow6432node\\Intel\\Suites') - except OSError: - try: - all_versions = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Intel\\Suites') - except OSError: - return - index = 0 - while 1: - try: - version = Utils.winreg.EnumKey(all_versions, index) - except OSError: - break - index += 1 - if not version_pattern.match(version): - continue - targets = {} - for target,arch in all_icl_platforms: - if target=='intel64': - targetDir='EM64T_NATIVE' - else: - targetDir=target - try: - try: - defaults = Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\'+targetDir) - except OSError: - if targetDir == 'EM64T_NATIVE': - defaults = Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\EM64T') - else: - raise - uid,type = Utils.winreg.QueryValueEx(defaults, 'SubKey') - Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++\\'+targetDir) - icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++') - path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir') - except OSError: - pass - else: - batch_file=os.path.join(path,'bin','iclvars.bat') - if os.path.isfile(batch_file): - targets[target] = target_compiler(conf, 'intel', arch, version, target, batch_file) - # The intel compilervar_arch.bat is broken when used with Visual Studio Express 2012 - # http://software.intel.com/en-us/forums/topic/328487 - compilervars_warning_attr = '_compilervars_warning_key' - if version[0:2] == '13' and getattr(conf, compilervars_warning_attr, True): - setattr(conf, compilervars_warning_attr, False) - patch_url = 'http://software.intel.com/en-us/forums/topic/328487' - compilervars_arch = os.path.join(path, 'bin', 'compilervars_arch.bat') - for vscomntool in ('VS110COMNTOOLS', 'VS100COMNTOOLS'): - if vscomntool in os.environ: - vs_express_path = os.environ[vscomntool] + r'..\IDE\VSWinExpress.exe' - dev_env_path = os.environ[vscomntool] + r'..\IDE\devenv.exe' - if (r'if exist "%VS110COMNTOOLS%..\IDE\VSWinExpress.exe"' in Utils.readf(compilervars_arch) and - not os.path.exists(vs_express_path) and not os.path.exists(dev_env_path)): - Logs.warn(('The Intel compilervar_arch.bat only checks for one Visual Studio SKU ' - '(VSWinExpress.exe) but it does not seem to be installed at %r. ' - 'The intel command line set up will fail to configure unless the file %r' - 'is patched. See: %s') % (vs_express_path, compilervars_arch, patch_url)) - major = version[0:2] - versions['intel ' + major] = targets - -@conf -def detect_msvc(self): - return self.setup_msvc(self.get_msvc_versions()) - -@conf -def get_msvc_versions(self): - """ - :return: platform to compiler configurations - :rtype: dict - """ - dct = Utils.ordered_iter_dict() - self.gather_icl_versions(dct) - self.gather_intel_composer_versions(dct) - self.gather_wsdk_versions(dct) - self.gather_msvc_versions(dct) - self.gather_vswhere_versions(dct) - Logs.debug('msvc: detected versions %r', list(dct.keys())) - return dct - -@conf -def find_lt_names_msvc(self, libname, is_static=False): - """ - Win32/MSVC specific code to glean out information from libtool la files. - this function is not attached to the task_gen class. Returns a triplet: - (library absolute path, library name without extension, whether the library is static) - """ - lt_names=[ - 'lib%s.la' % libname, - '%s.la' % libname, - ] - - for path in self.env.LIBPATH: - for la in lt_names: - laf=os.path.join(path,la) - dll=None - if os.path.exists(laf): - ltdict = Utils.read_la_file(laf) - lt_libdir=None - if ltdict.get('libdir', ''): - lt_libdir = ltdict['libdir'] - if not is_static and ltdict.get('library_names', ''): - dllnames=ltdict['library_names'].split() - dll=dllnames[0].lower() - dll=re.sub(r'\.dll$', '', dll) - return (lt_libdir, dll, False) - elif ltdict.get('old_library', ''): - olib=ltdict['old_library'] - if os.path.exists(os.path.join(path,olib)): - return (path, olib, True) - elif lt_libdir != '' and os.path.exists(os.path.join(lt_libdir,olib)): - return (lt_libdir, olib, True) - else: - return (None, olib, True) - else: - raise self.errors.WafError('invalid libtool object file: %s' % laf) - return (None, None, None) - -@conf -def libname_msvc(self, libname, is_static=False): - lib = libname.lower() - lib = re.sub(r'\.lib$','',lib) - - if lib in g_msvc_systemlibs: - return lib - - lib=re.sub('^lib','',lib) - - if lib == 'm': - return None - - (lt_path, lt_libname, lt_static) = self.find_lt_names_msvc(lib, is_static) - - if lt_path != None and lt_libname != None: - if lt_static: - # file existence check has been made by find_lt_names - return os.path.join(lt_path,lt_libname) - - if lt_path != None: - _libpaths = [lt_path] + self.env.LIBPATH - else: - _libpaths = self.env.LIBPATH - - static_libs=[ - 'lib%ss.lib' % lib, - 'lib%s.lib' % lib, - '%ss.lib' % lib, - '%s.lib' %lib, - ] - - dynamic_libs=[ - 'lib%s.dll.lib' % lib, - 'lib%s.dll.a' % lib, - '%s.dll.lib' % lib, - '%s.dll.a' % lib, - 'lib%s_d.lib' % lib, - '%s_d.lib' % lib, - '%s.lib' %lib, - ] - - libnames=static_libs - if not is_static: - libnames=dynamic_libs + static_libs - - for path in _libpaths: - for libn in libnames: - if os.path.exists(os.path.join(path, libn)): - Logs.debug('msvc: lib found: %s', os.path.join(path,libn)) - return re.sub(r'\.lib$', '',libn) - - #if no lib can be found, just return the libname as msvc expects it - self.fatal('The library %r could not be found' % libname) - return re.sub(r'\.lib$', '', libname) - -@conf -def check_lib_msvc(self, libname, is_static=False, uselib_store=None): - """ - Ideally we should be able to place the lib in the right env var, either STLIB or LIB, - but we don't distinguish static libs from shared libs. - This is ok since msvc doesn't have any special linker flag to select static libs (no env.STLIB_MARKER) - """ - libn = self.libname_msvc(libname, is_static) - - if not uselib_store: - uselib_store = libname.upper() - - if False and is_static: # disabled - self.env['STLIB_' + uselib_store] = [libn] - else: - self.env['LIB_' + uselib_store] = [libn] - -@conf -def check_libs_msvc(self, libnames, is_static=False): - for libname in Utils.to_list(libnames): - self.check_lib_msvc(libname, is_static) - -def configure(conf): - """ - Configuration methods to call for detecting msvc - """ - conf.autodetect(True) - conf.find_msvc() - conf.msvc_common_flags() - conf.cc_load_tools() - conf.cxx_load_tools() - conf.cc_add_flags() - conf.cxx_add_flags() - conf.link_add_flags() - conf.visual_studio_add_flags() - -@conf -def no_autodetect(conf): - conf.env.NO_MSVC_DETECT = 1 - configure(conf) - -@conf -def autodetect(conf, arch=False): - v = conf.env - if v.NO_MSVC_DETECT: - return - - compiler, version, path, includes, libdirs, cpu = conf.detect_msvc() - if arch: - v.DEST_CPU = cpu - - v.PATH = path - v.INCLUDES = includes - v.LIBPATH = libdirs - v.MSVC_COMPILER = compiler - try: - v.MSVC_VERSION = float(version) - except ValueError: - v.MSVC_VERSION = float(version[:-3]) - -def _get_prog_names(conf, compiler): - if compiler == 'intel': - compiler_name = 'ICL' - linker_name = 'XILINK' - lib_name = 'XILIB' - else: - # assumes CL.exe - compiler_name = 'CL' - linker_name = 'LINK' - lib_name = 'LIB' - return compiler_name, linker_name, lib_name - -@conf -def find_msvc(conf): - """Due to path format limitations, limit operation only to native Win32. Yeah it sucks.""" - if sys.platform == 'cygwin': - conf.fatal('MSVC module does not work under cygwin Python!') - - # the autodetection is supposed to be performed before entering in this method - v = conf.env - path = v.PATH - compiler = v.MSVC_COMPILER - version = v.MSVC_VERSION - - compiler_name, linker_name, lib_name = _get_prog_names(conf, compiler) - v.MSVC_MANIFEST = (compiler == 'msvc' and version >= 8) or (compiler == 'wsdk' and version >= 6) or (compiler == 'intel' and version >= 11) - - # compiler - cxx = conf.find_program(compiler_name, var='CXX', path_list=path) - - # before setting anything, check if the compiler is really msvc - env = dict(conf.environ) - if path: - env.update(PATH = ';'.join(path)) - if not conf.cmd_and_log(cxx + ['/nologo', '/help'], env=env): - conf.fatal('the msvc compiler could not be identified') - - # c/c++ compiler - v.CC = v.CXX = cxx - v.CC_NAME = v.CXX_NAME = 'msvc' - - # linker - if not v.LINK_CXX: - conf.find_program(linker_name, path_list=path, errmsg='%s was not found (linker)' % linker_name, var='LINK_CXX') - - if not v.LINK_CC: - v.LINK_CC = v.LINK_CXX - - # staticlib linker - if not v.AR: - stliblink = conf.find_program(lib_name, path_list=path, var='AR') - if not stliblink: - return - v.ARFLAGS = ['/nologo'] - - # manifest tool. Not required for VS 2003 and below. Must have for VS 2005 and later - if v.MSVC_MANIFEST: - conf.find_program('MT', path_list=path, var='MT') - v.MTFLAGS = ['/nologo'] - - try: - conf.load('winres') - except Errors.ConfigurationError: - Logs.warn('Resource compiler not found. Compiling resource file is disabled') - -@conf -def visual_studio_add_flags(self): - """visual studio flags found in the system environment""" - v = self.env - if self.environ.get('INCLUDE'): - v.prepend_value('INCLUDES', [x for x in self.environ['INCLUDE'].split(';') if x]) # notice the 'S' - if self.environ.get('LIB'): - v.prepend_value('LIBPATH', [x for x in self.environ['LIB'].split(';') if x]) - -@conf -def msvc_common_flags(conf): - """ - Setup the flags required for executing the msvc compiler - """ - v = conf.env - - v.DEST_BINFMT = 'pe' - v.append_value('CFLAGS', ['/nologo']) - v.append_value('CXXFLAGS', ['/nologo']) - v.append_value('LINKFLAGS', ['/nologo']) - v.DEFINES_ST = '/D%s' - - v.CC_SRC_F = '' - v.CC_TGT_F = ['/c', '/Fo'] - v.CXX_SRC_F = '' - v.CXX_TGT_F = ['/c', '/Fo'] - - if (v.MSVC_COMPILER == 'msvc' and v.MSVC_VERSION >= 8) or (v.MSVC_COMPILER == 'wsdk' and v.MSVC_VERSION >= 6): - v.CC_TGT_F = ['/FC'] + v.CC_TGT_F - v.CXX_TGT_F = ['/FC'] + v.CXX_TGT_F - - v.CPPPATH_ST = '/I%s' # template for adding include paths - - v.AR_TGT_F = v.CCLNK_TGT_F = v.CXXLNK_TGT_F = '/OUT:' - - # CRT specific flags - v.CFLAGS_CRT_MULTITHREADED = v.CXXFLAGS_CRT_MULTITHREADED = ['/MT'] - v.CFLAGS_CRT_MULTITHREADED_DLL = v.CXXFLAGS_CRT_MULTITHREADED_DLL = ['/MD'] - - v.CFLAGS_CRT_MULTITHREADED_DBG = v.CXXFLAGS_CRT_MULTITHREADED_DBG = ['/MTd'] - v.CFLAGS_CRT_MULTITHREADED_DLL_DBG = v.CXXFLAGS_CRT_MULTITHREADED_DLL_DBG = ['/MDd'] - - v.LIB_ST = '%s.lib' - v.LIBPATH_ST = '/LIBPATH:%s' - v.STLIB_ST = '%s.lib' - v.STLIBPATH_ST = '/LIBPATH:%s' - - if v.MSVC_MANIFEST: - v.append_value('LINKFLAGS', ['/MANIFEST']) - - v.CFLAGS_cshlib = [] - v.CXXFLAGS_cxxshlib = [] - v.LINKFLAGS_cshlib = v.LINKFLAGS_cxxshlib = ['/DLL'] - v.cshlib_PATTERN = v.cxxshlib_PATTERN = '%s.dll' - v.implib_PATTERN = '%s.lib' - v.IMPLIB_ST = '/IMPLIB:%s' - - v.LINKFLAGS_cstlib = [] - v.cstlib_PATTERN = v.cxxstlib_PATTERN = '%s.lib' - - v.cprogram_PATTERN = v.cxxprogram_PATTERN = '%s.exe' - - v.def_PATTERN = '/def:%s' - - -####################################################################################################### -##### conf above, build below - -@after_method('apply_link') -@feature('c', 'cxx') -def apply_flags_msvc(self): - """ - Add additional flags implied by msvc, such as subsystems and pdb files:: - - def build(bld): - bld.stlib(source='main.c', target='bar', subsystem='gruik') - """ - if self.env.CC_NAME != 'msvc' or not getattr(self, 'link_task', None): - return - - is_static = isinstance(self.link_task, ccroot.stlink_task) - - subsystem = getattr(self, 'subsystem', '') - if subsystem: - subsystem = '/subsystem:%s' % subsystem - flags = is_static and 'ARFLAGS' or 'LINKFLAGS' - self.env.append_value(flags, subsystem) - - if not is_static: - for f in self.env.LINKFLAGS: - d = f.lower() - if d[1:] in ('debug', 'debug:full', 'debug:fastlink'): - pdbnode = self.link_task.outputs[0].change_ext('.pdb') - self.link_task.outputs.append(pdbnode) - - if getattr(self, 'install_task', None): - self.pdb_install_task = self.add_install_files( - install_to=self.install_task.install_to, install_from=pdbnode) - break - -@feature('cprogram', 'cshlib', 'cxxprogram', 'cxxshlib') -@after_method('apply_link') -def apply_manifest(self): - """ - Special linker for MSVC with support for embedding manifests into DLL's - and executables compiled by Visual Studio 2005 or probably later. Without - the manifest file, the binaries are unusable. - See: http://msdn2.microsoft.com/en-us/library/ms235542(VS.80).aspx - """ - if self.env.CC_NAME == 'msvc' and self.env.MSVC_MANIFEST and getattr(self, 'link_task', None): - out_node = self.link_task.outputs[0] - man_node = out_node.parent.find_or_declare(out_node.name + '.manifest') - self.link_task.outputs.append(man_node) - self.env.DO_MANIFEST = True - -def make_winapp(self, family): - append = self.env.append_unique - append('DEFINES', 'WINAPI_FAMILY=%s' % family) - append('CXXFLAGS', ['/ZW', '/TP']) - for lib_path in self.env.LIBPATH: - append('CXXFLAGS','/AI%s'%lib_path) - -@feature('winphoneapp') -@after_method('process_use') -@after_method('propagate_uselib_vars') -def make_winphone_app(self): - """ - Insert configuration flags for windows phone applications (adds /ZW, /TP...) - """ - make_winapp(self, 'WINAPI_FAMILY_PHONE_APP') - self.env.append_unique('LINKFLAGS', ['/NODEFAULTLIB:ole32.lib', 'PhoneAppModelHost.lib']) - -@feature('winapp') -@after_method('process_use') -@after_method('propagate_uselib_vars') -def make_windows_app(self): - """ - Insert configuration flags for windows applications (adds /ZW, /TP...) - """ - make_winapp(self, 'WINAPI_FAMILY_DESKTOP_APP') diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/nasm.py b/ldb-2.0.8/third_party/waf/waflib/Tools/nasm.py deleted file mode 100644 index 9c51c18..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/nasm.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2008-2018 (ita) - -""" -Nasm tool (asm processing) -""" - -import os -import waflib.Tools.asm # leave this -from waflib.TaskGen import feature - -@feature('asm') -def apply_nasm_vars(self): - """provided for compatibility""" - self.env.append_value('ASFLAGS', self.to_list(getattr(self, 'nasm_flags', []))) - -def configure(conf): - """ - Detect nasm/yasm and set the variable *AS* - """ - conf.find_program(['nasm', 'yasm'], var='AS') - conf.env.AS_TGT_F = ['-o'] - conf.env.ASLNK_TGT_F = ['-o'] - conf.load('asm') - conf.env.ASMPATH_ST = '-I%s' + os.sep - txt = conf.cmd_and_log(conf.env.AS + ['--version']) - if 'yasm' in txt.lower(): - conf.env.ASM_NAME = 'yasm' - else: - conf.env.ASM_NAME = 'nasm' diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/nobuild.py b/ldb-2.0.8/third_party/waf/waflib/Tools/nobuild.py deleted file mode 100644 index 2e4b055..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/nobuild.py +++ /dev/null @@ -1,24 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2015 (ita) - -""" -Override the build commands to write empty files. -This is useful for profiling and evaluating the Python overhead. - -To use:: - - def build(bld): - ... - bld.load('nobuild') - -""" - -from waflib import Task -def build(bld): - def run(self): - for x in self.outputs: - x.write('') - for (name, cls) in Task.classes.items(): - cls.run = run - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/perl.py b/ldb-2.0.8/third_party/waf/waflib/Tools/perl.py deleted file mode 100644 index 32b03fb..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/perl.py +++ /dev/null @@ -1,156 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# andersg at 0x63.nu 2007 -# Thomas Nagy 2016-2018 (ita) - -""" -Support for Perl extensions. A C/C++ compiler is required:: - - def options(opt): - opt.load('compiler_c perl') - def configure(conf): - conf.load('compiler_c perl') - conf.check_perl_version((5,6,0)) - conf.check_perl_ext_devel() - conf.check_perl_module('Cairo') - conf.check_perl_module('Devel::PPPort 4.89') - def build(bld): - bld( - features = 'c cshlib perlext', - source = 'Mytest.xs', - target = 'Mytest', - install_path = '${ARCHDIR_PERL}/auto') - bld.install_files('${ARCHDIR_PERL}', 'Mytest.pm') -""" - -import os -from waflib import Task, Options, Utils, Errors -from waflib.Configure import conf -from waflib.TaskGen import extension, feature, before_method - -@before_method('apply_incpaths', 'apply_link', 'propagate_uselib_vars') -@feature('perlext') -def init_perlext(self): - """ - Change the values of *cshlib_PATTERN* and *cxxshlib_PATTERN* to remove the - *lib* prefix from library names. - """ - self.uselib = self.to_list(getattr(self, 'uselib', [])) - if not 'PERLEXT' in self.uselib: - self.uselib.append('PERLEXT') - self.env.cshlib_PATTERN = self.env.cxxshlib_PATTERN = self.env.perlext_PATTERN - -@extension('.xs') -def xsubpp_file(self, node): - """ - Create :py:class:`waflib.Tools.perl.xsubpp` tasks to process *.xs* files - """ - outnode = node.change_ext('.c') - self.create_task('xsubpp', node, outnode) - self.source.append(outnode) - -class xsubpp(Task.Task): - """ - Process *.xs* files - """ - run_str = '${PERL} ${XSUBPP} -noprototypes -typemap ${EXTUTILS_TYPEMAP} ${SRC} > ${TGT}' - color = 'BLUE' - ext_out = ['.h'] - -@conf -def check_perl_version(self, minver=None): - """ - Check if Perl is installed, and set the variable PERL. - minver is supposed to be a tuple - """ - res = True - if minver: - cver = '.'.join(map(str,minver)) - else: - cver = '' - - self.start_msg('Checking for minimum perl version %s' % cver) - - perl = self.find_program('perl', var='PERL', value=getattr(Options.options, 'perlbinary', None)) - version = self.cmd_and_log(perl + ["-e", 'printf \"%vd\", $^V']) - if not version: - res = False - version = "Unknown" - elif not minver is None: - ver = tuple(map(int, version.split("."))) - if ver < minver: - res = False - - self.end_msg(version, color=res and 'GREEN' or 'YELLOW') - return res - -@conf -def check_perl_module(self, module): - """ - Check if specified perlmodule is installed. - - The minimum version can be specified by specifying it after modulename - like this:: - - def configure(conf): - conf.check_perl_module("Some::Module 2.92") - """ - cmd = self.env.PERL + ['-e', 'use %s' % module] - self.start_msg('perl module %s' % module) - try: - r = self.cmd_and_log(cmd) - except Errors.WafError: - self.end_msg(False) - return None - self.end_msg(r or True) - return r - -@conf -def check_perl_ext_devel(self): - """ - Check for configuration needed to build perl extensions. - - Sets different xxx_PERLEXT variables in the environment. - - Also sets the ARCHDIR_PERL variable useful as installation path, - which can be overridden by ``--with-perl-archdir`` option. - """ - - env = self.env - perl = env.PERL - if not perl: - self.fatal('find perl first') - - def cmd_perl_config(s): - return perl + ['-MConfig', '-e', 'print \"%s\"' % s] - def cfg_str(cfg): - return self.cmd_and_log(cmd_perl_config(cfg)) - def cfg_lst(cfg): - return Utils.to_list(cfg_str(cfg)) - def find_xsubpp(): - for var in ('privlib', 'vendorlib'): - xsubpp = cfg_lst('$Config{%s}/ExtUtils/xsubpp$Config{exe_ext}' % var) - if xsubpp and os.path.isfile(xsubpp[0]): - return xsubpp - return self.find_program('xsubpp') - - env.LINKFLAGS_PERLEXT = cfg_lst('$Config{lddlflags}') - env.INCLUDES_PERLEXT = cfg_lst('$Config{archlib}/CORE') - env.CFLAGS_PERLEXT = cfg_lst('$Config{ccflags} $Config{cccdlflags}') - env.EXTUTILS_TYPEMAP = cfg_lst('$Config{privlib}/ExtUtils/typemap') - env.XSUBPP = find_xsubpp() - - if not getattr(Options.options, 'perlarchdir', None): - env.ARCHDIR_PERL = cfg_str('$Config{sitearch}') - else: - env.ARCHDIR_PERL = getattr(Options.options, 'perlarchdir') - - env.perlext_PATTERN = '%s.' + cfg_str('$Config{dlext}') - -def options(opt): - """ - Add the ``--with-perl-archdir`` and ``--with-perl-binary`` command-line options. - """ - opt.add_option('--with-perl-binary', type='string', dest='perlbinary', help = 'Specify alternate perl binary', default=None) - opt.add_option('--with-perl-archdir', type='string', dest='perlarchdir', help = 'Specify directory where to install arch specific files', default=None) - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/python.py b/ldb-2.0.8/third_party/waf/waflib/Tools/python.py deleted file mode 100644 index 7c45a76..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/python.py +++ /dev/null @@ -1,644 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2007-2015 (ita) -# Gustavo Carneiro (gjc), 2007 - -""" -Support for Python, detect the headers and libraries and provide -*use* variables to link C/C++ programs against them:: - - def options(opt): - opt.load('compiler_c python') - def configure(conf): - conf.load('compiler_c python') - conf.check_python_version((2,4,2)) - conf.check_python_headers() - def build(bld): - bld.program(features='pyembed', source='a.c', target='myprog') - bld.shlib(features='pyext', source='b.c', target='mylib') -""" - -import os, sys -from waflib import Errors, Logs, Node, Options, Task, Utils -from waflib.TaskGen import extension, before_method, after_method, feature -from waflib.Configure import conf - -FRAG = ''' -#include -#ifdef __cplusplus -extern "C" { -#endif - void Py_Initialize(void); - void Py_Finalize(void); -#ifdef __cplusplus -} -#endif -int main(int argc, char **argv) -{ - (void)argc; (void)argv; - Py_Initialize(); - Py_Finalize(); - return 0; -} -''' -""" -Piece of C/C++ code used in :py:func:`waflib.Tools.python.check_python_headers` -""" - -INST = ''' -import sys, py_compile -py_compile.compile(sys.argv[1], sys.argv[2], sys.argv[3], True) -''' -""" -Piece of Python code used in :py:class:`waflib.Tools.python.pyo` and :py:class:`waflib.Tools.python.pyc` for byte-compiling python files -""" - -DISTUTILS_IMP = ['from distutils.sysconfig import get_config_var, get_python_lib'] - -@before_method('process_source') -@feature('py') -def feature_py(self): - """ - Create tasks to byte-compile .py files and install them, if requested - """ - self.install_path = getattr(self, 'install_path', '${PYTHONDIR}') - install_from = getattr(self, 'install_from', None) - if install_from and not isinstance(install_from, Node.Node): - install_from = self.path.find_dir(install_from) - self.install_from = install_from - - ver = self.env.PYTHON_VERSION - if not ver: - self.bld.fatal('Installing python files requires PYTHON_VERSION, try conf.check_python_version') - - if int(ver.replace('.', '')) > 31: - self.install_32 = True - -@extension('.py') -def process_py(self, node): - """ - Add signature of .py file, so it will be byte-compiled when necessary - """ - assert(hasattr(self, 'install_path')), 'add features="py" for target "%s" in "%s/wscript".' % (self.target, self.path.nice_path()) - self.install_from = getattr(self, 'install_from', None) - relative_trick = getattr(self, 'relative_trick', True) - if self.install_from: - assert isinstance(self.install_from, Node.Node), \ - 'add features="py" for target "%s" in "%s/wscript" (%s).' % (self.target, self.path.nice_path(), type(self.install_from)) - - # where to install the python file - if self.install_path: - if self.install_from: - self.add_install_files(install_to=self.install_path, install_from=node, cwd=self.install_from, relative_trick=relative_trick) - else: - self.add_install_files(install_to=self.install_path, install_from=node, relative_trick=relative_trick) - - lst = [] - if self.env.PYC: - lst.append('pyc') - if self.env.PYO: - lst.append('pyo') - - if self.install_path: - if self.install_from: - target_dir = node.path_from(self.install_from) if relative_trick else node.name - pyd = Utils.subst_vars("%s/%s" % (self.install_path, target_dir), self.env) - else: - target_dir = node.path_from(self.path) if relative_trick else node.name - pyd = Utils.subst_vars("%s/%s" % (self.install_path, target_dir), self.env) - else: - pyd = node.abspath() - - for ext in lst: - if self.env.PYTAG and not self.env.NOPYCACHE: - # __pycache__ installation for python 3.2 - PEP 3147 - name = node.name[:-3] - pyobj = node.parent.get_bld().make_node('__pycache__').make_node("%s.%s.%s" % (name, self.env.PYTAG, ext)) - pyobj.parent.mkdir() - else: - pyobj = node.change_ext(".%s" % ext) - - tsk = self.create_task(ext, node, pyobj) - tsk.pyd = pyd - - if self.install_path: - self.add_install_files(install_to=os.path.dirname(pyd), install_from=pyobj, cwd=node.parent.get_bld(), relative_trick=relative_trick) - -class pyc(Task.Task): - """ - Byte-compiling python files - """ - color = 'PINK' - def __str__(self): - node = self.outputs[0] - return node.path_from(node.ctx.launch_node()) - def run(self): - cmd = [Utils.subst_vars('${PYTHON}', self.env), '-c', INST, self.inputs[0].abspath(), self.outputs[0].abspath(), self.pyd] - ret = self.generator.bld.exec_command(cmd) - return ret - -class pyo(Task.Task): - """ - Byte-compiling python files - """ - color = 'PINK' - def __str__(self): - node = self.outputs[0] - return node.path_from(node.ctx.launch_node()) - def run(self): - cmd = [Utils.subst_vars('${PYTHON}', self.env), Utils.subst_vars('${PYFLAGS_OPT}', self.env), '-c', INST, self.inputs[0].abspath(), self.outputs[0].abspath(), self.pyd] - ret = self.generator.bld.exec_command(cmd) - return ret - -@feature('pyext') -@before_method('propagate_uselib_vars', 'apply_link') -@after_method('apply_bundle') -def init_pyext(self): - """ - Change the values of *cshlib_PATTERN* and *cxxshlib_PATTERN* to remove the - *lib* prefix from library names. - """ - self.uselib = self.to_list(getattr(self, 'uselib', [])) - if not 'PYEXT' in self.uselib: - self.uselib.append('PYEXT') - # override shlib_PATTERN set by the osx module - self.env.cshlib_PATTERN = self.env.cxxshlib_PATTERN = self.env.macbundle_PATTERN = self.env.pyext_PATTERN - self.env.fcshlib_PATTERN = self.env.dshlib_PATTERN = self.env.pyext_PATTERN - - try: - if not self.install_path: - return - except AttributeError: - self.install_path = '${PYTHONARCHDIR}' - -@feature('pyext') -@before_method('apply_link', 'apply_bundle') -def set_bundle(self): - """Mac-specific pyext extension that enables bundles from c_osx.py""" - if Utils.unversioned_sys_platform() == 'darwin': - self.mac_bundle = True - -@before_method('propagate_uselib_vars') -@feature('pyembed') -def init_pyembed(self): - """ - Add the PYEMBED variable. - """ - self.uselib = self.to_list(getattr(self, 'uselib', [])) - if not 'PYEMBED' in self.uselib: - self.uselib.append('PYEMBED') - -@conf -def get_python_variables(self, variables, imports=None): - """ - Spawn a new python process to dump configuration variables - - :param variables: variables to print - :type variables: list of string - :param imports: one import by element - :type imports: list of string - :return: the variable values - :rtype: list of string - """ - if not imports: - try: - imports = self.python_imports - except AttributeError: - imports = DISTUTILS_IMP - - program = list(imports) # copy - program.append('') - for v in variables: - program.append("print(repr(%s))" % v) - os_env = dict(os.environ) - try: - del os_env['MACOSX_DEPLOYMENT_TARGET'] # see comments in the OSX tool - except KeyError: - pass - - try: - out = self.cmd_and_log(self.env.PYTHON + ['-c', '\n'.join(program)], env=os_env) - except Errors.WafError: - self.fatal('The distutils module is unusable: install "python-devel"?') - self.to_log(out) - return_values = [] - for s in out.splitlines(): - s = s.strip() - if not s: - continue - if s == 'None': - return_values.append(None) - elif (s[0] == "'" and s[-1] == "'") or (s[0] == '"' and s[-1] == '"'): - return_values.append(eval(s)) - elif s[0].isdigit(): - return_values.append(int(s)) - else: break - return return_values - -@conf -def test_pyembed(self, mode, msg='Testing pyembed configuration'): - self.check(header_name='Python.h', define_name='HAVE_PYEMBED', msg=msg, - fragment=FRAG, errmsg='Could not build a python embedded interpreter', - features='%s %sprogram pyembed' % (mode, mode)) - -@conf -def test_pyext(self, mode, msg='Testing pyext configuration'): - self.check(header_name='Python.h', define_name='HAVE_PYEXT', msg=msg, - fragment=FRAG, errmsg='Could not build python extensions', - features='%s %sshlib pyext' % (mode, mode)) - -@conf -def python_cross_compile(self, features='pyembed pyext'): - """ - For cross-compilation purposes, it is possible to bypass the normal detection and set the flags that you want: - PYTHON_VERSION='3.4' PYTAG='cpython34' pyext_PATTERN="%s.so" PYTHON_LDFLAGS='-lpthread -ldl' waf configure - - The following variables are used: - PYTHON_VERSION required - PYTAG required - PYTHON_LDFLAGS required - pyext_PATTERN required - PYTHON_PYEXT_LDFLAGS - PYTHON_PYEMBED_LDFLAGS - """ - features = Utils.to_list(features) - if not ('PYTHON_LDFLAGS' in self.environ or 'PYTHON_PYEXT_LDFLAGS' in self.environ or 'PYTHON_PYEMBED_LDFLAGS' in self.environ): - return False - - for x in 'PYTHON_VERSION PYTAG pyext_PATTERN'.split(): - if not x in self.environ: - self.fatal('Please set %s in the os environment' % x) - else: - self.env[x] = self.environ[x] - - xx = self.env.CXX_NAME and 'cxx' or 'c' - if 'pyext' in features: - flags = self.environ.get('PYTHON_PYEXT_LDFLAGS', self.environ.get('PYTHON_LDFLAGS')) - if flags is None: - self.fatal('No flags provided through PYTHON_PYEXT_LDFLAGS as required') - else: - self.parse_flags(flags, 'PYEXT') - self.test_pyext(xx) - if 'pyembed' in features: - flags = self.environ.get('PYTHON_PYEMBED_LDFLAGS', self.environ.get('PYTHON_LDFLAGS')) - if flags is None: - self.fatal('No flags provided through PYTHON_PYEMBED_LDFLAGS as required') - else: - self.parse_flags(flags, 'PYEMBED') - self.test_pyembed(xx) - return True - -@conf -def check_python_headers(conf, features='pyembed pyext'): - """ - Check for headers and libraries necessary to extend or embed python by using the module *distutils*. - On success the environment variables xxx_PYEXT and xxx_PYEMBED are added: - - * PYEXT: for compiling python extensions - * PYEMBED: for embedding a python interpreter - """ - features = Utils.to_list(features) - assert ('pyembed' in features) or ('pyext' in features), "check_python_headers features must include 'pyembed' and/or 'pyext'" - env = conf.env - if not env.CC_NAME and not env.CXX_NAME: - conf.fatal('load a compiler first (gcc, g++, ..)') - - # bypass all the code below for cross-compilation - if conf.python_cross_compile(features): - return - - if not env.PYTHON_VERSION: - conf.check_python_version() - - pybin = env.PYTHON - if not pybin: - conf.fatal('Could not find the python executable') - - # so we actually do all this for compatibility reasons and for obtaining pyext_PATTERN below - v = 'prefix SO LDFLAGS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET LDSHARED CFLAGS LDVERSION'.split() - try: - lst = conf.get_python_variables(["get_config_var('%s') or ''" % x for x in v]) - except RuntimeError: - conf.fatal("Python development headers not found (-v for details).") - - vals = ['%s = %r' % (x, y) for (x, y) in zip(v, lst)] - conf.to_log("Configuration returned from %r:\n%s\n" % (pybin, '\n'.join(vals))) - - dct = dict(zip(v, lst)) - x = 'MACOSX_DEPLOYMENT_TARGET' - if dct[x]: - env[x] = conf.environ[x] = dct[x] - env.pyext_PATTERN = '%s' + dct['SO'] # not a mistake - - - # Try to get pythonX.Y-config - num = '.'.join(env.PYTHON_VERSION.split('.')[:2]) - conf.find_program([''.join(pybin) + '-config', 'python%s-config' % num, 'python-config-%s' % num, 'python%sm-config' % num], var='PYTHON_CONFIG', msg="python-config", mandatory=False) - - if env.PYTHON_CONFIG: - # check python-config output only once - if conf.env.HAVE_PYTHON_H: - return - - # python2.6-config requires 3 runs - all_flags = [['--cflags', '--libs', '--ldflags']] - if sys.hexversion < 0x2070000: - all_flags = [[k] for k in all_flags[0]] - - xx = env.CXX_NAME and 'cxx' or 'c' - - if 'pyembed' in features: - for flags in all_flags: - # Python 3.8 has different flags for pyembed, needs --embed - embedflags = flags + ['--embed'] - try: - conf.check_cfg(msg='Asking python-config for pyembed %r flags' % ' '.join(embedflags), path=env.PYTHON_CONFIG, package='', uselib_store='PYEMBED', args=embedflags) - except conf.errors.ConfigurationError: - # However Python < 3.8 doesn't accept --embed, so we need a fallback - conf.check_cfg(msg='Asking python-config for pyembed %r flags' % ' '.join(flags), path=env.PYTHON_CONFIG, package='', uselib_store='PYEMBED', args=flags) - - try: - conf.test_pyembed(xx) - except conf.errors.ConfigurationError: - # python bug 7352 - if dct['Py_ENABLE_SHARED'] and dct['LIBDIR']: - env.append_unique('LIBPATH_PYEMBED', [dct['LIBDIR']]) - conf.test_pyembed(xx) - else: - raise - - if 'pyext' in features: - for flags in all_flags: - conf.check_cfg(msg='Asking python-config for pyext %r flags' % ' '.join(flags), path=env.PYTHON_CONFIG, package='', uselib_store='PYEXT', args=flags) - - try: - conf.test_pyext(xx) - except conf.errors.ConfigurationError: - # python bug 7352 - if dct['Py_ENABLE_SHARED'] and dct['LIBDIR']: - env.append_unique('LIBPATH_PYEXT', [dct['LIBDIR']]) - conf.test_pyext(xx) - else: - raise - - conf.define('HAVE_PYTHON_H', 1) - return - - # No python-config, do something else on windows systems - all_flags = dct['LDFLAGS'] + ' ' + dct['CFLAGS'] - conf.parse_flags(all_flags, 'PYEMBED') - - all_flags = dct['LDFLAGS'] + ' ' + dct['LDSHARED'] + ' ' + dct['CFLAGS'] - conf.parse_flags(all_flags, 'PYEXT') - - result = None - if not dct["LDVERSION"]: - dct["LDVERSION"] = env.PYTHON_VERSION - - # further simplification will be complicated - for name in ('python' + dct['LDVERSION'], 'python' + env.PYTHON_VERSION + 'm', 'python' + env.PYTHON_VERSION.replace('.', '')): - - # LIBPATH_PYEMBED is already set; see if it works. - if not result and env.LIBPATH_PYEMBED: - path = env.LIBPATH_PYEMBED - conf.to_log("\n\n# Trying default LIBPATH_PYEMBED: %r\n" % path) - result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in LIBPATH_PYEMBED' % name) - - if not result and dct['LIBDIR']: - path = [dct['LIBDIR']] - conf.to_log("\n\n# try again with -L$python_LIBDIR: %r\n" % path) - result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in LIBDIR' % name) - - if not result and dct['LIBPL']: - path = [dct['LIBPL']] - conf.to_log("\n\n# try again with -L$python_LIBPL (some systems don't install the python library in $prefix/lib)\n") - result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in python_LIBPL' % name) - - if not result: - path = [os.path.join(dct['prefix'], "libs")] - conf.to_log("\n\n# try again with -L$prefix/libs, and pythonXY name rather than pythonX.Y (win32)\n") - result = conf.check(lib=name, uselib='PYEMBED', libpath=path, mandatory=False, msg='Checking for library %s in $prefix/libs' % name) - - if result: - break # do not forget to set LIBPATH_PYEMBED - - if result: - env.LIBPATH_PYEMBED = path - env.append_value('LIB_PYEMBED', [name]) - else: - conf.to_log("\n\n### LIB NOT FOUND\n") - - # under certain conditions, python extensions must link to - # python libraries, not just python embedding programs. - if Utils.is_win32 or dct['Py_ENABLE_SHARED']: - env.LIBPATH_PYEXT = env.LIBPATH_PYEMBED - env.LIB_PYEXT = env.LIB_PYEMBED - - conf.to_log("Include path for Python extensions (found via distutils module): %r\n" % (dct['INCLUDEPY'],)) - env.INCLUDES_PYEXT = [dct['INCLUDEPY']] - env.INCLUDES_PYEMBED = [dct['INCLUDEPY']] - - # Code using the Python API needs to be compiled with -fno-strict-aliasing - if env.CC_NAME == 'gcc': - env.append_unique('CFLAGS_PYEMBED', ['-fno-strict-aliasing']) - env.append_unique('CFLAGS_PYEXT', ['-fno-strict-aliasing']) - if env.CXX_NAME == 'gcc': - env.append_unique('CXXFLAGS_PYEMBED', ['-fno-strict-aliasing']) - env.append_unique('CXXFLAGS_PYEXT', ['-fno-strict-aliasing']) - - if env.CC_NAME == "msvc": - from distutils.msvccompiler import MSVCCompiler - dist_compiler = MSVCCompiler() - dist_compiler.initialize() - env.append_value('CFLAGS_PYEXT', dist_compiler.compile_options) - env.append_value('CXXFLAGS_PYEXT', dist_compiler.compile_options) - env.append_value('LINKFLAGS_PYEXT', dist_compiler.ldflags_shared) - - # See if it compiles - conf.check(header_name='Python.h', define_name='HAVE_PYTHON_H', uselib='PYEMBED', fragment=FRAG, errmsg='Distutils not installed? Broken python installation? Get python-config now!') - -@conf -def check_python_version(conf, minver=None): - """ - Check if the python interpreter is found matching a given minimum version. - minver should be a tuple, eg. to check for python >= 2.4.2 pass (2,4,2) as minver. - - If successful, PYTHON_VERSION is defined as 'MAJOR.MINOR' (eg. '2.4') - of the actual python version found, and PYTHONDIR and PYTHONARCHDIR - are defined, pointing to the site-packages directories appropriate for - this python version, where modules/packages/extensions should be - installed. - - :param minver: minimum version - :type minver: tuple of int - """ - assert minver is None or isinstance(minver, tuple) - pybin = conf.env.PYTHON - if not pybin: - conf.fatal('could not find the python executable') - - # Get python version string - cmd = pybin + ['-c', 'import sys\nfor x in sys.version_info: print(str(x))'] - Logs.debug('python: Running python command %r', cmd) - lines = conf.cmd_and_log(cmd).split() - assert len(lines) == 5, "found %r lines, expected 5: %r" % (len(lines), lines) - pyver_tuple = (int(lines[0]), int(lines[1]), int(lines[2]), lines[3], int(lines[4])) - - # Compare python version with the minimum required - result = (minver is None) or (pyver_tuple >= minver) - - if result: - # define useful environment variables - pyver = '.'.join([str(x) for x in pyver_tuple[:2]]) - conf.env.PYTHON_VERSION = pyver - - if 'PYTHONDIR' in conf.env: - # Check if --pythondir was specified - pydir = conf.env.PYTHONDIR - elif 'PYTHONDIR' in conf.environ: - # Check environment for PYTHONDIR - pydir = conf.environ['PYTHONDIR'] - else: - # Finally, try to guess - if Utils.is_win32: - (python_LIBDEST, pydir) = conf.get_python_variables( - ["get_config_var('LIBDEST') or ''", - "get_python_lib(standard_lib=0) or ''"]) - else: - python_LIBDEST = None - (pydir,) = conf.get_python_variables( ["get_python_lib(standard_lib=0, prefix=%r) or ''" % conf.env.PREFIX]) - if python_LIBDEST is None: - if conf.env.LIBDIR: - python_LIBDEST = os.path.join(conf.env.LIBDIR, 'python' + pyver) - else: - python_LIBDEST = os.path.join(conf.env.PREFIX, 'lib', 'python' + pyver) - - if 'PYTHONARCHDIR' in conf.env: - # Check if --pythonarchdir was specified - pyarchdir = conf.env.PYTHONARCHDIR - elif 'PYTHONARCHDIR' in conf.environ: - # Check environment for PYTHONDIR - pyarchdir = conf.environ['PYTHONARCHDIR'] - else: - # Finally, try to guess - (pyarchdir, ) = conf.get_python_variables( ["get_python_lib(plat_specific=1, standard_lib=0, prefix=%r) or ''" % conf.env.PREFIX]) - if not pyarchdir: - pyarchdir = pydir - - if hasattr(conf, 'define'): # conf.define is added by the C tool, so may not exist - conf.define('PYTHONDIR', pydir) - conf.define('PYTHONARCHDIR', pyarchdir) - - conf.env.PYTHONDIR = pydir - conf.env.PYTHONARCHDIR = pyarchdir - - # Feedback - pyver_full = '.'.join(map(str, pyver_tuple[:3])) - if minver is None: - conf.msg('Checking for python version', pyver_full) - else: - minver_str = '.'.join(map(str, minver)) - conf.msg('Checking for python version >= %s' % (minver_str,), pyver_full, color=result and 'GREEN' or 'YELLOW') - - if not result: - conf.fatal('The python version is too old, expecting %r' % (minver,)) - -PYTHON_MODULE_TEMPLATE = ''' -import %s as current_module -version = getattr(current_module, '__version__', None) -if version is not None: - print(str(version)) -else: - print('unknown version') -''' - -@conf -def check_python_module(conf, module_name, condition=''): - """ - Check if the selected python interpreter can import the given python module:: - - def configure(conf): - conf.check_python_module('pygccxml') - conf.check_python_module('re', condition="ver > num(2, 0, 4) and ver <= num(3, 0, 0)") - - :param module_name: module - :type module_name: string - """ - msg = "Checking for python module %r" % module_name - if condition: - msg = '%s (%s)' % (msg, condition) - conf.start_msg(msg) - try: - ret = conf.cmd_and_log(conf.env.PYTHON + ['-c', PYTHON_MODULE_TEMPLATE % module_name]) - except Errors.WafError: - conf.end_msg(False) - conf.fatal('Could not find the python module %r' % module_name) - - ret = ret.strip() - if condition: - conf.end_msg(ret) - if ret == 'unknown version': - conf.fatal('Could not check the %s version' % module_name) - - from distutils.version import LooseVersion - def num(*k): - if isinstance(k[0], int): - return LooseVersion('.'.join([str(x) for x in k])) - else: - return LooseVersion(k[0]) - d = {'num': num, 'ver': LooseVersion(ret)} - ev = eval(condition, {}, d) - if not ev: - conf.fatal('The %s version does not satisfy the requirements' % module_name) - else: - if ret == 'unknown version': - conf.end_msg(True) - else: - conf.end_msg(ret) - -def configure(conf): - """ - Detect the python interpreter - """ - v = conf.env - if getattr(Options.options, 'pythondir', None): - v.PYTHONDIR = Options.options.pythondir - if getattr(Options.options, 'pythonarchdir', None): - v.PYTHONARCHDIR = Options.options.pythonarchdir - if getattr(Options.options, 'nopycache', None): - v.NOPYCACHE=Options.options.nopycache - - if not v.PYTHON: - v.PYTHON = [getattr(Options.options, 'python', None) or sys.executable] - v.PYTHON = Utils.to_list(v.PYTHON) - conf.find_program('python', var='PYTHON') - - v.PYFLAGS = '' - v.PYFLAGS_OPT = '-O' - - v.PYC = getattr(Options.options, 'pyc', 1) - v.PYO = getattr(Options.options, 'pyo', 1) - - try: - v.PYTAG = conf.cmd_and_log(conf.env.PYTHON + ['-c', "import imp;print(imp.get_tag())"]).strip() - except Errors.WafError: - pass - -def options(opt): - """ - Add python-specific options - """ - pyopt=opt.add_option_group("Python Options") - pyopt.add_option('--nopyc', dest = 'pyc', action='store_false', default=1, - help = 'Do not install bytecode compiled .pyc files (configuration) [Default:install]') - pyopt.add_option('--nopyo', dest='pyo', action='store_false', default=1, - help='Do not install optimised compiled .pyo files (configuration) [Default:install]') - pyopt.add_option('--nopycache',dest='nopycache', action='store_true', - help='Do not use __pycache__ directory to install objects [Default:auto]') - pyopt.add_option('--python', dest="python", - help='python binary to be used [Default: %s]' % sys.executable) - pyopt.add_option('--pythondir', dest='pythondir', - help='Installation path for python modules (py, platform-independent .py and .pyc files)') - pyopt.add_option('--pythonarchdir', dest='pythonarchdir', - help='Installation path for python extension (pyext, platform-dependent .so or .dylib files)') - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/qt5.py b/ldb-2.0.8/third_party/waf/waflib/Tools/qt5.py deleted file mode 100644 index 287c253..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/qt5.py +++ /dev/null @@ -1,800 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2006-2018 (ita) - -""" -This tool helps with finding Qt5 tools and libraries, -and also provides syntactic sugar for using Qt5 tools. - -The following snippet illustrates the tool usage:: - - def options(opt): - opt.load('compiler_cxx qt5') - - def configure(conf): - conf.load('compiler_cxx qt5') - - def build(bld): - bld( - features = 'qt5 cxx cxxprogram', - uselib = 'QT5CORE QT5GUI QT5OPENGL QT5SVG', - source = 'main.cpp textures.qrc aboutDialog.ui', - target = 'window', - ) - -Here, the UI description and resource files will be processed -to generate code. - -Usage -===== - -Load the "qt5" tool. - -You also need to edit your sources accordingly: - -- the normal way of doing things is to have your C++ files - include the .moc file. - This is regarded as the best practice (and provides much faster - compilations). - It also implies that the include paths have beenset properly. - -- to have the include paths added automatically, use the following:: - - from waflib.TaskGen import feature, before_method, after_method - @feature('cxx') - @after_method('process_source') - @before_method('apply_incpaths') - def add_includes_paths(self): - incs = set(self.to_list(getattr(self, 'includes', ''))) - for x in self.compiled_tasks: - incs.add(x.inputs[0].parent.path_from(self.path)) - self.includes = sorted(incs) - -Note: another tool provides Qt processing that does not require -.moc includes, see 'playground/slow_qt/'. - -A few options (--qt{dir,bin,...}) and environment variables -(QT5_{ROOT,DIR,MOC,UIC,XCOMPILE}) allow finer tuning of the tool, -tool path selection, etc; please read the source for more info. - -The detection uses pkg-config on Linux by default. To force static library detection use: -QT5_XCOMPILE=1 QT5_FORCE_STATIC=1 waf configure -""" - -from __future__ import with_statement - -try: - from xml.sax import make_parser - from xml.sax.handler import ContentHandler -except ImportError: - has_xml = False - ContentHandler = object -else: - has_xml = True - -import os, sys, re -from waflib.Tools import cxx -from waflib import Build, Task, Utils, Options, Errors, Context -from waflib.TaskGen import feature, after_method, extension, before_method -from waflib.Configure import conf -from waflib import Logs - -MOC_H = ['.h', '.hpp', '.hxx', '.hh'] -""" -File extensions associated to .moc files -""" - -EXT_RCC = ['.qrc'] -""" -File extension for the resource (.qrc) files -""" - -EXT_UI = ['.ui'] -""" -File extension for the user interface (.ui) files -""" - -EXT_QT5 = ['.cpp', '.cc', '.cxx', '.C'] -""" -File extensions of C++ files that may require a .moc processing -""" - -class qxx(Task.classes['cxx']): - """ - Each C++ file can have zero or several .moc files to create. - They are known only when the files are scanned (preprocessor) - To avoid scanning the c++ files each time (parsing C/C++), the results - are retrieved from the task cache (bld.node_deps/bld.raw_deps). - The moc tasks are also created *dynamically* during the build. - """ - - def __init__(self, *k, **kw): - Task.Task.__init__(self, *k, **kw) - self.moc_done = 0 - - def runnable_status(self): - """ - Compute the task signature to make sure the scanner was executed. Create the - moc tasks by using :py:meth:`waflib.Tools.qt5.qxx.add_moc_tasks` (if necessary), - then postpone the task execution (there is no need to recompute the task signature). - """ - if self.moc_done: - return Task.Task.runnable_status(self) - else: - for t in self.run_after: - if not t.hasrun: - return Task.ASK_LATER - self.add_moc_tasks() - return Task.Task.runnable_status(self) - - def create_moc_task(self, h_node, m_node): - """ - If several libraries use the same classes, it is possible that moc will run several times (Issue 1318) - It is not possible to change the file names, but we can assume that the moc transformation will be identical, - and the moc tasks can be shared in a global cache. - """ - try: - moc_cache = self.generator.bld.moc_cache - except AttributeError: - moc_cache = self.generator.bld.moc_cache = {} - - try: - return moc_cache[h_node] - except KeyError: - tsk = moc_cache[h_node] = Task.classes['moc'](env=self.env, generator=self.generator) - tsk.set_inputs(h_node) - tsk.set_outputs(m_node) - tsk.env.append_unique('MOC_FLAGS', '-i') - - if self.generator: - self.generator.tasks.append(tsk) - - # direct injection in the build phase (safe because called from the main thread) - gen = self.generator.bld.producer - gen.outstanding.append(tsk) - gen.total += 1 - - return tsk - - else: - # remove the signature, it must be recomputed with the moc task - delattr(self, 'cache_sig') - - def add_moc_tasks(self): - """ - Creates moc tasks by looking in the list of file dependencies ``bld.raw_deps[self.uid()]`` - """ - node = self.inputs[0] - bld = self.generator.bld - - # skip on uninstall due to generated files - if bld.is_install == Build.UNINSTALL: - return - - try: - # compute the signature once to know if there is a moc file to create - self.signature() - except KeyError: - # the moc file may be referenced somewhere else - pass - else: - # remove the signature, it must be recomputed with the moc task - delattr(self, 'cache_sig') - - include_nodes = [node.parent] + self.generator.includes_nodes - - moctasks = [] - mocfiles = set() - for d in bld.raw_deps.get(self.uid(), []): - if not d.endswith('.moc'): - continue - - # process that base.moc only once - if d in mocfiles: - continue - mocfiles.add(d) - - # find the source associated with the moc file - h_node = None - base2 = d[:-4] - - # foo.moc from foo.cpp - prefix = node.name[:node.name.rfind('.')] - if base2 == prefix: - h_node = node - else: - # this deviates from the standard - # if bar.cpp includes foo.moc, then assume it is from foo.h - for x in include_nodes: - for e in MOC_H: - h_node = x.find_node(base2 + e) - if h_node: - break - else: - continue - break - if h_node: - m_node = h_node.change_ext('.moc') - else: - raise Errors.WafError('No source found for %r which is a moc file' % d) - - # create the moc task - task = self.create_moc_task(h_node, m_node) - moctasks.append(task) - - # simple scheduler dependency: run the moc task before others - self.run_after.update(set(moctasks)) - self.moc_done = 1 - -class trans_update(Task.Task): - """Updates a .ts files from a list of C++ files""" - run_str = '${QT_LUPDATE} ${SRC} -ts ${TGT}' - color = 'BLUE' - -class XMLHandler(ContentHandler): - """ - Parses ``.qrc`` files - """ - def __init__(self): - ContentHandler.__init__(self) - self.buf = [] - self.files = [] - def startElement(self, name, attrs): - if name == 'file': - self.buf = [] - def endElement(self, name): - if name == 'file': - self.files.append(str(''.join(self.buf))) - def characters(self, cars): - self.buf.append(cars) - -@extension(*EXT_RCC) -def create_rcc_task(self, node): - "Creates rcc and cxx tasks for ``.qrc`` files" - rcnode = node.change_ext('_rc.%d.cpp' % self.idx) - self.create_task('rcc', node, rcnode) - cpptask = self.create_task('cxx', rcnode, rcnode.change_ext('.o')) - try: - self.compiled_tasks.append(cpptask) - except AttributeError: - self.compiled_tasks = [cpptask] - return cpptask - -@extension(*EXT_UI) -def create_uic_task(self, node): - "Create uic tasks for user interface ``.ui`` definition files" - - """ - If UIC file is used in more than one bld, we would have a conflict in parallel execution - It is not possible to change the file names (like .self.idx. as for objects) as they have - to be referenced by the source file, but we can assume that the transformation will be identical - and the tasks can be shared in a global cache. - """ - try: - uic_cache = self.bld.uic_cache - except AttributeError: - uic_cache = self.bld.uic_cache = {} - - if node not in uic_cache: - uictask = uic_cache[node] = self.create_task('ui5', node) - uictask.outputs = [node.parent.find_or_declare(self.env.ui_PATTERN % node.name[:-3])] - -@extension('.ts') -def add_lang(self, node): - """Adds all the .ts file into ``self.lang``""" - self.lang = self.to_list(getattr(self, 'lang', [])) + [node] - -@feature('qt5') -@before_method('process_source') -def process_mocs(self): - """ - Processes MOC files included in headers:: - - def build(bld): - bld.program(features='qt5', source='main.cpp', target='app', use='QT5CORE', moc='foo.h') - - The build will run moc on foo.h to create moc_foo.n.cpp. The number in the file name - is provided to avoid name clashes when the same headers are used by several targets. - """ - lst = self.to_nodes(getattr(self, 'moc', [])) - self.source = self.to_list(getattr(self, 'source', [])) - for x in lst: - prefix = x.name[:x.name.rfind('.')] # foo.h -> foo - moc_target = 'moc_%s.%d.cpp' % (prefix, self.idx) - moc_node = x.parent.find_or_declare(moc_target) - self.source.append(moc_node) - - self.create_task('moc', x, moc_node) - -@feature('qt5') -@after_method('apply_link') -def apply_qt5(self): - """ - Adds MOC_FLAGS which may be necessary for moc:: - - def build(bld): - bld.program(features='qt5', source='main.cpp', target='app', use='QT5CORE') - - The additional parameters are: - - :param lang: list of translation files (\\*.ts) to process - :type lang: list of :py:class:`waflib.Node.Node` or string without the .ts extension - :param update: whether to process the C++ files to update the \\*.ts files (use **waf --translate**) - :type update: bool - :param langname: if given, transform the \\*.ts files into a .qrc files to include in the binary file - :type langname: :py:class:`waflib.Node.Node` or string without the .qrc extension - """ - if getattr(self, 'lang', None): - qmtasks = [] - for x in self.to_list(self.lang): - if isinstance(x, str): - x = self.path.find_resource(x + '.ts') - qmtasks.append(self.create_task('ts2qm', x, x.change_ext('.%d.qm' % self.idx))) - - if getattr(self, 'update', None) and Options.options.trans_qt5: - cxxnodes = [a.inputs[0] for a in self.compiled_tasks] + [ - a.inputs[0] for a in self.tasks if a.inputs and a.inputs[0].name.endswith('.ui')] - for x in qmtasks: - self.create_task('trans_update', cxxnodes, x.inputs) - - if getattr(self, 'langname', None): - qmnodes = [x.outputs[0] for x in qmtasks] - rcnode = self.langname - if isinstance(rcnode, str): - rcnode = self.path.find_or_declare(rcnode + ('.%d.qrc' % self.idx)) - t = self.create_task('qm2rcc', qmnodes, rcnode) - k = create_rcc_task(self, t.outputs[0]) - self.link_task.inputs.append(k.outputs[0]) - - lst = [] - for flag in self.to_list(self.env.CXXFLAGS): - if len(flag) < 2: - continue - f = flag[0:2] - if f in ('-D', '-I', '/D', '/I'): - if (f[0] == '/'): - lst.append('-' + flag[1:]) - else: - lst.append(flag) - self.env.append_value('MOC_FLAGS', lst) - -@extension(*EXT_QT5) -def cxx_hook(self, node): - """ - Re-maps C++ file extensions to the :py:class:`waflib.Tools.qt5.qxx` task. - """ - return self.create_compiled_task('qxx', node) - -class rcc(Task.Task): - """ - Processes ``.qrc`` files - """ - color = 'BLUE' - run_str = '${QT_RCC} -name ${tsk.rcname()} ${SRC[0].abspath()} ${RCC_ST} -o ${TGT}' - ext_out = ['.h'] - - def rcname(self): - return os.path.splitext(self.inputs[0].name)[0] - - def scan(self): - """Parse the *.qrc* files""" - if not has_xml: - Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!') - return ([], []) - - parser = make_parser() - curHandler = XMLHandler() - parser.setContentHandler(curHandler) - with open(self.inputs[0].abspath(), 'r') as f: - parser.parse(f) - - nodes = [] - names = [] - root = self.inputs[0].parent - for x in curHandler.files: - nd = root.find_resource(x) - if nd: - nodes.append(nd) - else: - names.append(x) - return (nodes, names) - - def quote_flag(self, x): - """ - Override Task.quote_flag. QT parses the argument files - differently than cl.exe and link.exe - - :param x: flag - :type x: string - :return: quoted flag - :rtype: string - """ - return x - - -class moc(Task.Task): - """ - Creates ``.moc`` files - """ - color = 'BLUE' - run_str = '${QT_MOC} ${MOC_FLAGS} ${MOCCPPPATH_ST:INCPATHS} ${MOCDEFINES_ST:DEFINES} ${SRC} ${MOC_ST} ${TGT}' - - def quote_flag(self, x): - """ - Override Task.quote_flag. QT parses the argument files - differently than cl.exe and link.exe - - :param x: flag - :type x: string - :return: quoted flag - :rtype: string - """ - return x - - -class ui5(Task.Task): - """ - Processes ``.ui`` files - """ - color = 'BLUE' - run_str = '${QT_UIC} ${SRC} -o ${TGT}' - ext_out = ['.h'] - -class ts2qm(Task.Task): - """ - Generates ``.qm`` files from ``.ts`` files - """ - color = 'BLUE' - run_str = '${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}' - -class qm2rcc(Task.Task): - """ - Generates ``.qrc`` files from ``.qm`` files - """ - color = 'BLUE' - after = 'ts2qm' - def run(self): - """Create a qrc file including the inputs""" - txt = '\n'.join(['%s' % k.path_from(self.outputs[0].parent) for k in self.inputs]) - code = '\n\n%s\n\n' % txt - self.outputs[0].write(code) - -def configure(self): - """ - Besides the configuration options, the environment variable QT5_ROOT may be used - to give the location of the qt5 libraries (absolute path). - - The detection uses the program ``pkg-config`` through :py:func:`waflib.Tools.config_c.check_cfg` - """ - self.find_qt5_binaries() - self.set_qt5_libs_dir() - self.set_qt5_libs_to_check() - self.set_qt5_defines() - self.find_qt5_libraries() - self.add_qt5_rpath() - self.simplify_qt5_libs() - - # warn about this during the configuration too - if not has_xml: - Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!') - - if 'COMPILER_CXX' not in self.env: - self.fatal('No CXX compiler defined: did you forget to configure compiler_cxx first?') - - # Qt5 may be compiled with '-reduce-relocations' which requires dependent programs to have -fPIE or -fPIC? - frag = '#include \nint main(int argc, char **argv) {return 0;}\n' - uses = 'QT5CORE QT5WIDGETS QT5GUI' - for flag in [[], '-fPIE', '-fPIC', '-std=c++11' , ['-std=c++11', '-fPIE'], ['-std=c++11', '-fPIC']]: - msg = 'See if Qt files compile ' - if flag: - msg += 'with %s' % flag - try: - self.check(features='qt5 cxx', use=uses, uselib_store='qt5', cxxflags=flag, fragment=frag, msg=msg) - except self.errors.ConfigurationError: - pass - else: - break - else: - self.fatal('Could not build a simple Qt application') - - # FreeBSD does not add /usr/local/lib and the pkg-config files do not provide it either :-/ - if Utils.unversioned_sys_platform() == 'freebsd': - frag = '#include \nint main(int argc, char **argv) { QApplication app(argc, argv); return NULL != (void*) (&app);}\n' - try: - self.check(features='qt5 cxx cxxprogram', use=uses, fragment=frag, msg='Can we link Qt programs on FreeBSD directly?') - except self.errors.ConfigurationError: - self.check(features='qt5 cxx cxxprogram', use=uses, uselib_store='qt5', libpath='/usr/local/lib', fragment=frag, msg='Is /usr/local/lib required?') - -@conf -def find_qt5_binaries(self): - """ - Detects Qt programs such as qmake, moc, uic, lrelease - """ - env = self.env - opt = Options.options - - qtdir = getattr(opt, 'qtdir', '') - qtbin = getattr(opt, 'qtbin', '') - - paths = [] - - if qtdir: - qtbin = os.path.join(qtdir, 'bin') - - # the qt directory has been given from QT5_ROOT - deduce the qt binary path - if not qtdir: - qtdir = self.environ.get('QT5_ROOT', '') - qtbin = self.environ.get('QT5_BIN') or os.path.join(qtdir, 'bin') - - if qtbin: - paths = [qtbin] - - # no qtdir, look in the path and in /usr/local/Trolltech - if not qtdir: - paths = self.environ.get('PATH', '').split(os.pathsep) - paths.extend(['/usr/share/qt5/bin', '/usr/local/lib/qt5/bin']) - try: - lst = Utils.listdir('/usr/local/Trolltech/') - except OSError: - pass - else: - if lst: - lst.sort() - lst.reverse() - - # keep the highest version - qtdir = '/usr/local/Trolltech/%s/' % lst[0] - qtbin = os.path.join(qtdir, 'bin') - paths.append(qtbin) - - # at the end, try to find qmake in the paths given - # keep the one with the highest version - cand = None - prev_ver = ['5', '0', '0'] - for qmk in ('qmake-qt5', 'qmake5', 'qmake'): - try: - qmake = self.find_program(qmk, path_list=paths) - except self.errors.ConfigurationError: - pass - else: - try: - version = self.cmd_and_log(qmake + ['-query', 'QT_VERSION']).strip() - except self.errors.WafError: - pass - else: - if version: - new_ver = version.split('.') - if new_ver > prev_ver: - cand = qmake - prev_ver = new_ver - - # qmake could not be found easily, rely on qtchooser - if not cand: - try: - self.find_program('qtchooser') - except self.errors.ConfigurationError: - pass - else: - cmd = self.env.QTCHOOSER + ['-qt=5', '-run-tool=qmake'] - try: - version = self.cmd_and_log(cmd + ['-query', 'QT_VERSION']) - except self.errors.WafError: - pass - else: - cand = cmd - - if cand: - self.env.QMAKE = cand - else: - self.fatal('Could not find qmake for qt5') - - self.env.QT_HOST_BINS = qtbin = self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_HOST_BINS']).strip() - paths.insert(0, qtbin) - - def find_bin(lst, var): - if var in env: - return - for f in lst: - try: - ret = self.find_program(f, path_list=paths) - except self.errors.ConfigurationError: - pass - else: - env[var]=ret - break - - find_bin(['uic-qt5', 'uic'], 'QT_UIC') - if not env.QT_UIC: - self.fatal('cannot find the uic compiler for qt5') - - self.start_msg('Checking for uic version') - uicver = self.cmd_and_log(env.QT_UIC + ['-version'], output=Context.BOTH) - uicver = ''.join(uicver).strip() - uicver = uicver.replace('Qt User Interface Compiler ','').replace('User Interface Compiler for Qt', '') - self.end_msg(uicver) - if uicver.find(' 3.') != -1 or uicver.find(' 4.') != -1: - self.fatal('this uic compiler is for qt3 or qt4, add uic for qt5 to your path') - - find_bin(['moc-qt5', 'moc'], 'QT_MOC') - find_bin(['rcc-qt5', 'rcc'], 'QT_RCC') - find_bin(['lrelease-qt5', 'lrelease'], 'QT_LRELEASE') - find_bin(['lupdate-qt5', 'lupdate'], 'QT_LUPDATE') - - env.UIC_ST = '%s -o %s' - env.MOC_ST = '-o' - env.ui_PATTERN = 'ui_%s.h' - env.QT_LRELEASE_FLAGS = ['-silent'] - env.MOCCPPPATH_ST = '-I%s' - env.MOCDEFINES_ST = '-D%s' - -@conf -def set_qt5_libs_dir(self): - env = self.env - qtlibs = getattr(Options.options, 'qtlibs', None) or self.environ.get('QT5_LIBDIR') - if not qtlibs: - try: - qtlibs = self.cmd_and_log(env.QMAKE + ['-query', 'QT_INSTALL_LIBS']).strip() - except Errors.WafError: - qtdir = self.cmd_and_log(env.QMAKE + ['-query', 'QT_INSTALL_PREFIX']).strip() - qtlibs = os.path.join(qtdir, 'lib') - self.msg('Found the Qt5 libraries in', qtlibs) - env.QTLIBS = qtlibs - -@conf -def find_single_qt5_lib(self, name, uselib, qtlibs, qtincludes, force_static): - env = self.env - if force_static: - exts = ('.a', '.lib') - prefix = 'STLIB' - else: - exts = ('.so', '.lib') - prefix = 'LIB' - - def lib_names(): - for x in exts: - for k in ('', '5') if Utils.is_win32 else ['']: - for p in ('lib', ''): - yield (p, name, k, x) - - for tup in lib_names(): - k = ''.join(tup) - path = os.path.join(qtlibs, k) - if os.path.exists(path): - if env.DEST_OS == 'win32': - libval = ''.join(tup[:-1]) - else: - libval = name - env.append_unique(prefix + '_' + uselib, libval) - env.append_unique('%sPATH_%s' % (prefix, uselib), qtlibs) - env.append_unique('INCLUDES_' + uselib, qtincludes) - env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, name.replace('Qt5', 'Qt'))) - return k - return False - -@conf -def find_qt5_libraries(self): - env = self.env - - qtincludes = self.environ.get('QT5_INCLUDES') or self.cmd_and_log(env.QMAKE + ['-query', 'QT_INSTALL_HEADERS']).strip() - force_static = self.environ.get('QT5_FORCE_STATIC') - try: - if self.environ.get('QT5_XCOMPILE'): - self.fatal('QT5_XCOMPILE Disables pkg-config detection') - self.check_cfg(atleast_pkgconfig_version='0.1') - except self.errors.ConfigurationError: - for i in self.qt5_vars: - uselib = i.upper() - if Utils.unversioned_sys_platform() == 'darwin': - # Since at least qt 4.7.3 each library locates in separate directory - fwk = i.replace('Qt5', 'Qt') - frameworkName = fwk + '.framework' - - qtDynamicLib = os.path.join(env.QTLIBS, frameworkName, fwk) - if os.path.exists(qtDynamicLib): - env.append_unique('FRAMEWORK_' + uselib, fwk) - env.append_unique('FRAMEWORKPATH_' + uselib, env.QTLIBS) - self.msg('Checking for %s' % i, qtDynamicLib, 'GREEN') - else: - self.msg('Checking for %s' % i, False, 'YELLOW') - env.append_unique('INCLUDES_' + uselib, os.path.join(env.QTLIBS, frameworkName, 'Headers')) - else: - ret = self.find_single_qt5_lib(i, uselib, env.QTLIBS, qtincludes, force_static) - if not force_static and not ret: - ret = self.find_single_qt5_lib(i, uselib, env.QTLIBS, qtincludes, True) - self.msg('Checking for %s' % i, ret, 'GREEN' if ret else 'YELLOW') - else: - path = '%s:%s:%s/pkgconfig:/usr/lib/qt5/lib/pkgconfig:/opt/qt5/lib/pkgconfig:/usr/lib/qt5/lib:/opt/qt5/lib' % ( - self.environ.get('PKG_CONFIG_PATH', ''), env.QTLIBS, env.QTLIBS) - for i in self.qt5_vars: - self.check_cfg(package=i, args='--cflags --libs', mandatory=False, force_static=force_static, pkg_config_path=path) - -@conf -def simplify_qt5_libs(self): - """ - Since library paths make really long command-lines, - and since everything depends on qtcore, remove the qtcore ones from qtgui, etc - """ - env = self.env - def process_lib(vars_, coreval): - for d in vars_: - var = d.upper() - if var == 'QTCORE': - continue - - value = env['LIBPATH_'+var] - if value: - core = env[coreval] - accu = [] - for lib in value: - if lib in core: - continue - accu.append(lib) - env['LIBPATH_'+var] = accu - process_lib(self.qt5_vars, 'LIBPATH_QTCORE') - -@conf -def add_qt5_rpath(self): - """ - Defines rpath entries for Qt libraries - """ - env = self.env - if getattr(Options.options, 'want_rpath', False): - def process_rpath(vars_, coreval): - for d in vars_: - var = d.upper() - value = env['LIBPATH_' + var] - if value: - core = env[coreval] - accu = [] - for lib in value: - if var != 'QTCORE': - if lib in core: - continue - accu.append('-Wl,--rpath='+lib) - env['RPATH_' + var] = accu - process_rpath(self.qt5_vars, 'LIBPATH_QTCORE') - -@conf -def set_qt5_libs_to_check(self): - self.qt5_vars = Utils.to_list(getattr(self, 'qt5_vars', [])) - if not self.qt5_vars: - dirlst = Utils.listdir(self.env.QTLIBS) - - pat = self.env.cxxshlib_PATTERN - if Utils.is_win32: - pat = pat.replace('.dll', '.lib') - if self.environ.get('QT5_FORCE_STATIC'): - pat = self.env.cxxstlib_PATTERN - if Utils.unversioned_sys_platform() == 'darwin': - pat = r"%s\.framework" - re_qt = re.compile(pat%'Qt5?(?P.*)'+'$') - for x in dirlst: - m = re_qt.match(x) - if m: - self.qt5_vars.append("Qt5%s" % m.group('name')) - if not self.qt5_vars: - self.fatal('cannot find any Qt5 library (%r)' % self.env.QTLIBS) - - qtextralibs = getattr(Options.options, 'qtextralibs', None) - if qtextralibs: - self.qt5_vars.extend(qtextralibs.split(',')) - -@conf -def set_qt5_defines(self): - if sys.platform != 'win32': - return - for x in self.qt5_vars: - y=x.replace('Qt5', 'Qt')[2:].upper() - self.env.append_unique('DEFINES_%s' % x.upper(), 'QT_%s_LIB' % y) - -def options(opt): - """ - Command-line options - """ - opt.add_option('--want-rpath', action='store_true', default=False, dest='want_rpath', help='enable the rpath for qt libraries') - for i in 'qtdir qtbin qtlibs'.split(): - opt.add_option('--'+i, type='string', default='', dest=i) - - opt.add_option('--translate', action='store_true', help='collect translation strings', dest='trans_qt5', default=False) - opt.add_option('--qtextralibs', type='string', default='', dest='qtextralibs', help='additional qt libraries on the system to add to default ones, comma separated') - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/ruby.py b/ldb-2.0.8/third_party/waf/waflib/Tools/ruby.py deleted file mode 100644 index 8d92a79..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/ruby.py +++ /dev/null @@ -1,186 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# daniel.svensson at purplescout.se 2008 -# Thomas Nagy 2016-2018 (ita) - -""" -Support for Ruby extensions. A C/C++ compiler is required:: - - def options(opt): - opt.load('compiler_c ruby') - def configure(conf): - conf.load('compiler_c ruby') - conf.check_ruby_version((1,8,0)) - conf.check_ruby_ext_devel() - conf.check_ruby_module('libxml') - def build(bld): - bld( - features = 'c cshlib rubyext', - source = 'rb_mytest.c', - target = 'mytest_ext', - install_path = '${ARCHDIR_RUBY}') - bld.install_files('${LIBDIR_RUBY}', 'Mytest.rb') -""" - -import os -from waflib import Errors, Options, Task, Utils -from waflib.TaskGen import before_method, feature, extension -from waflib.Configure import conf - -@feature('rubyext') -@before_method('apply_incpaths', 'process_source', 'apply_bundle', 'apply_link') -def init_rubyext(self): - """ - Add required variables for ruby extensions - """ - self.install_path = '${ARCHDIR_RUBY}' - self.uselib = self.to_list(getattr(self, 'uselib', '')) - if not 'RUBY' in self.uselib: - self.uselib.append('RUBY') - if not 'RUBYEXT' in self.uselib: - self.uselib.append('RUBYEXT') - -@feature('rubyext') -@before_method('apply_link', 'propagate_uselib_vars') -def apply_ruby_so_name(self): - """ - Strip the *lib* prefix from ruby extensions - """ - self.env.cshlib_PATTERN = self.env.cxxshlib_PATTERN = self.env.rubyext_PATTERN - -@conf -def check_ruby_version(self, minver=()): - """ - Checks if ruby is installed. - If installed the variable RUBY will be set in environment. - The ruby binary can be overridden by ``--with-ruby-binary`` command-line option. - """ - - ruby = self.find_program('ruby', var='RUBY', value=Options.options.rubybinary) - - try: - version = self.cmd_and_log(ruby + ['-e', 'puts defined?(VERSION) ? VERSION : RUBY_VERSION']).strip() - except Errors.WafError: - self.fatal('could not determine ruby version') - self.env.RUBY_VERSION = version - - try: - ver = tuple(map(int, version.split('.'))) - except Errors.WafError: - self.fatal('unsupported ruby version %r' % version) - - cver = '' - if minver: - cver = '> ' + '.'.join(str(x) for x in minver) - if ver < minver: - self.fatal('ruby is too old %r' % ver) - - self.msg('Checking for ruby version %s' % cver, version) - -@conf -def check_ruby_ext_devel(self): - """ - Check if a ruby extension can be created - """ - if not self.env.RUBY: - self.fatal('ruby detection is required first') - - if not self.env.CC_NAME and not self.env.CXX_NAME: - self.fatal('load a c/c++ compiler first') - - version = tuple(map(int, self.env.RUBY_VERSION.split("."))) - - def read_out(cmd): - return Utils.to_list(self.cmd_and_log(self.env.RUBY + ['-rrbconfig', '-e', cmd])) - - def read_config(key): - return read_out('puts RbConfig::CONFIG[%r]' % key) - - cpppath = archdir = read_config('archdir') - - if version >= (1, 9, 0): - ruby_hdrdir = read_config('rubyhdrdir') - cpppath += ruby_hdrdir - if version >= (2, 0, 0): - cpppath += read_config('rubyarchhdrdir') - cpppath += [os.path.join(ruby_hdrdir[0], read_config('arch')[0])] - - self.check(header_name='ruby.h', includes=cpppath, errmsg='could not find ruby header file', link_header_test=False) - - self.env.LIBPATH_RUBYEXT = read_config('libdir') - self.env.LIBPATH_RUBYEXT += archdir - self.env.INCLUDES_RUBYEXT = cpppath - self.env.CFLAGS_RUBYEXT = read_config('CCDLFLAGS') - self.env.rubyext_PATTERN = '%s.' + read_config('DLEXT')[0] - - # ok this is really stupid, but the command and flags are combined. - # so we try to find the first argument... - flags = read_config('LDSHARED') - while flags and flags[0][0] != '-': - flags = flags[1:] - - # we also want to strip out the deprecated ppc flags - if len(flags) > 1 and flags[1] == "ppc": - flags = flags[2:] - - self.env.LINKFLAGS_RUBYEXT = flags - self.env.LINKFLAGS_RUBYEXT += read_config('LIBS') - self.env.LINKFLAGS_RUBYEXT += read_config('LIBRUBYARG_SHARED') - - if Options.options.rubyarchdir: - self.env.ARCHDIR_RUBY = Options.options.rubyarchdir - else: - self.env.ARCHDIR_RUBY = read_config('sitearchdir')[0] - - if Options.options.rubylibdir: - self.env.LIBDIR_RUBY = Options.options.rubylibdir - else: - self.env.LIBDIR_RUBY = read_config('sitelibdir')[0] - -@conf -def check_ruby_module(self, module_name): - """ - Check if the selected ruby interpreter can require the given ruby module:: - - def configure(conf): - conf.check_ruby_module('libxml') - - :param module_name: module - :type module_name: string - """ - self.start_msg('Ruby module %s' % module_name) - try: - self.cmd_and_log(self.env.RUBY + ['-e', 'require \'%s\';puts 1' % module_name]) - except Errors.WafError: - self.end_msg(False) - self.fatal('Could not find the ruby module %r' % module_name) - self.end_msg(True) - -@extension('.rb') -def process(self, node): - return self.create_task('run_ruby', node) - -class run_ruby(Task.Task): - """ - Task to run ruby files detected by file extension .rb:: - - def options(opt): - opt.load('ruby') - - def configure(ctx): - ctx.check_ruby_version() - - def build(bld): - bld.env.RBFLAGS = '-e puts "hello world"' - bld(source='a_ruby_file.rb') - """ - run_str = '${RUBY} ${RBFLAGS} -I ${SRC[0].parent.abspath()} ${SRC}' - -def options(opt): - """ - Add the ``--with-ruby-archdir``, ``--with-ruby-libdir`` and ``--with-ruby-binary`` options - """ - opt.add_option('--with-ruby-archdir', type='string', dest='rubyarchdir', help='Specify directory where to install arch specific files') - opt.add_option('--with-ruby-libdir', type='string', dest='rubylibdir', help='Specify alternate ruby library path') - opt.add_option('--with-ruby-binary', type='string', dest='rubybinary', help='Specify alternate ruby binary') - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/suncc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/suncc.py deleted file mode 100644 index 33d34fc..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/suncc.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2006-2018 (ita) -# Ralf Habacker, 2006 (rh) - -from waflib import Errors -from waflib.Tools import ccroot, ar -from waflib.Configure import conf - -@conf -def find_scc(conf): - """ - Detects the Sun C compiler - """ - v = conf.env - cc = conf.find_program('cc', var='CC') - try: - conf.cmd_and_log(cc + ['-flags']) - except Errors.WafError: - conf.fatal('%r is not a Sun compiler' % cc) - v.CC_NAME = 'sun' - conf.get_suncc_version(cc) - -@conf -def scc_common_flags(conf): - """ - Flags required for executing the sun C compiler - """ - v = conf.env - - v.CC_SRC_F = [] - v.CC_TGT_F = ['-c', '-o', ''] - - if not v.LINK_CC: - v.LINK_CC = v.CC - - v.CCLNK_SRC_F = '' - v.CCLNK_TGT_F = ['-o', ''] - v.CPPPATH_ST = '-I%s' - v.DEFINES_ST = '-D%s' - - v.LIB_ST = '-l%s' # template for adding libs - v.LIBPATH_ST = '-L%s' # template for adding libpaths - v.STLIB_ST = '-l%s' - v.STLIBPATH_ST = '-L%s' - - v.SONAME_ST = '-Wl,-h,%s' - v.SHLIB_MARKER = '-Bdynamic' - v.STLIB_MARKER = '-Bstatic' - - v.cprogram_PATTERN = '%s' - - v.CFLAGS_cshlib = ['-xcode=pic32', '-DPIC'] - v.LINKFLAGS_cshlib = ['-G'] - v.cshlib_PATTERN = 'lib%s.so' - - v.LINKFLAGS_cstlib = ['-Bstatic'] - v.cstlib_PATTERN = 'lib%s.a' - -def configure(conf): - conf.find_scc() - conf.find_ar() - conf.scc_common_flags() - conf.cc_load_tools() - conf.cc_add_flags() - conf.link_add_flags() - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/suncxx.py b/ldb-2.0.8/third_party/waf/waflib/Tools/suncxx.py deleted file mode 100644 index 3b384f6..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/suncxx.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2006-2018 (ita) -# Ralf Habacker, 2006 (rh) - -from waflib import Errors -from waflib.Tools import ccroot, ar -from waflib.Configure import conf - -@conf -def find_sxx(conf): - """ - Detects the sun C++ compiler - """ - v = conf.env - cc = conf.find_program(['CC', 'c++'], var='CXX') - try: - conf.cmd_and_log(cc + ['-flags']) - except Errors.WafError: - conf.fatal('%r is not a Sun compiler' % cc) - v.CXX_NAME = 'sun' - conf.get_suncc_version(cc) - -@conf -def sxx_common_flags(conf): - """ - Flags required for executing the sun C++ compiler - """ - v = conf.env - - v.CXX_SRC_F = [] - v.CXX_TGT_F = ['-c', '-o', ''] - - if not v.LINK_CXX: - v.LINK_CXX = v.CXX - - v.CXXLNK_SRC_F = [] - v.CXXLNK_TGT_F = ['-o', ''] - v.CPPPATH_ST = '-I%s' - v.DEFINES_ST = '-D%s' - - v.LIB_ST = '-l%s' # template for adding libs - v.LIBPATH_ST = '-L%s' # template for adding libpaths - v.STLIB_ST = '-l%s' - v.STLIBPATH_ST = '-L%s' - - v.SONAME_ST = '-Wl,-h,%s' - v.SHLIB_MARKER = '-Bdynamic' - v.STLIB_MARKER = '-Bstatic' - - v.cxxprogram_PATTERN = '%s' - - v.CXXFLAGS_cxxshlib = ['-xcode=pic32', '-DPIC'] - v.LINKFLAGS_cxxshlib = ['-G'] - v.cxxshlib_PATTERN = 'lib%s.so' - - v.LINKFLAGS_cxxstlib = ['-Bstatic'] - v.cxxstlib_PATTERN = 'lib%s.a' - -def configure(conf): - conf.find_sxx() - conf.find_ar() - conf.sxx_common_flags() - conf.cxx_load_tools() - conf.cxx_add_flags() - conf.link_add_flags() - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/tex.py b/ldb-2.0.8/third_party/waf/waflib/Tools/tex.py deleted file mode 100644 index eaf9fdb..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/tex.py +++ /dev/null @@ -1,543 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2006-2018 (ita) - -""" -TeX/LaTeX/PDFLaTeX/XeLaTeX support - -Example:: - - def configure(conf): - conf.load('tex') - if not conf.env.LATEX: - conf.fatal('The program LaTex is required') - - def build(bld): - bld( - features = 'tex', - type = 'latex', # pdflatex or xelatex - source = 'document.ltx', # mandatory, the source - outs = 'ps', # 'pdf' or 'ps pdf' - deps = 'crossreferencing.lst', # to give dependencies directly - prompt = 1, # 0 for the batch mode - ) - -Notes: - -- To configure with a special program, use:: - - $ PDFLATEX=luatex waf configure - -- This tool does not use the target attribute of the task generator - (``bld(target=...)``); the target file name is built from the source - base name and the output type(s) -""" - -import os, re -from waflib import Utils, Task, Errors, Logs, Node -from waflib.TaskGen import feature, before_method - -re_bibunit = re.compile(r'\\(?Pputbib)\[(?P[^\[\]]*)\]',re.M) -def bibunitscan(self): - """ - Parses TeX inputs and try to find the *bibunit* file dependencies - - :return: list of bibunit files - :rtype: list of :py:class:`waflib.Node.Node` - """ - node = self.inputs[0] - - nodes = [] - if not node: - return nodes - - code = node.read() - for match in re_bibunit.finditer(code): - path = match.group('file') - if path: - found = None - for k in ('', '.bib'): - # add another loop for the tex include paths? - Logs.debug('tex: trying %s%s', path, k) - fi = node.parent.find_resource(path + k) - if fi: - found = True - nodes.append(fi) - # no break - if not found: - Logs.debug('tex: could not find %s', path) - - Logs.debug('tex: found the following bibunit files: %s', nodes) - return nodes - -exts_deps_tex = ['', '.ltx', '.tex', '.bib', '.pdf', '.png', '.eps', '.ps', '.sty'] -"""List of typical file extensions included in latex files""" - -exts_tex = ['.ltx', '.tex'] -"""List of typical file extensions that contain latex""" - -re_tex = re.compile(r'\\(?Pusepackage|RequirePackage|include|bibliography([^\[\]{}]*)|putbib|includegraphics|input|import|bringin|lstinputlisting)(\[[^\[\]]*\])?{(?P[^{}]*)}',re.M) -"""Regexp for expressions that may include latex files""" - -g_bibtex_re = re.compile('bibdata', re.M) -"""Regexp for bibtex files""" - -g_glossaries_re = re.compile('\\@newglossary', re.M) -"""Regexp for expressions that create glossaries""" - -class tex(Task.Task): - """ - Compiles a tex/latex file. - - .. inheritance-diagram:: waflib.Tools.tex.latex waflib.Tools.tex.xelatex waflib.Tools.tex.pdflatex - """ - - bibtex_fun, _ = Task.compile_fun('${BIBTEX} ${BIBTEXFLAGS} ${SRCFILE}', shell=False) - bibtex_fun.__doc__ = """ - Execute the program **bibtex** - """ - - makeindex_fun, _ = Task.compile_fun('${MAKEINDEX} ${MAKEINDEXFLAGS} ${SRCFILE}', shell=False) - makeindex_fun.__doc__ = """ - Execute the program **makeindex** - """ - - makeglossaries_fun, _ = Task.compile_fun('${MAKEGLOSSARIES} ${SRCFILE}', shell=False) - makeglossaries_fun.__doc__ = """ - Execute the program **makeglossaries** - """ - - def exec_command(self, cmd, **kw): - """ - Executes TeX commands without buffering (latex may prompt for inputs) - - :return: the return code - :rtype: int - """ - if self.env.PROMPT_LATEX: - # capture the outputs in configuration tests - kw['stdout'] = kw['stderr'] = None - return super(tex, self).exec_command(cmd, **kw) - - def scan_aux(self, node): - """ - Recursive regex-based scanner that finds included auxiliary files. - """ - nodes = [node] - re_aux = re.compile(r'\\@input{(?P[^{}]*)}', re.M) - - def parse_node(node): - code = node.read() - for match in re_aux.finditer(code): - path = match.group('file') - found = node.parent.find_or_declare(path) - if found and found not in nodes: - Logs.debug('tex: found aux node %r', found) - nodes.append(found) - parse_node(found) - parse_node(node) - return nodes - - def scan(self): - """ - Recursive regex-based scanner that finds latex dependencies. It uses :py:attr:`waflib.Tools.tex.re_tex` - - Depending on your needs you might want: - - * to change re_tex:: - - from waflib.Tools import tex - tex.re_tex = myregex - - * or to change the method scan from the latex tasks:: - - from waflib.Task import classes - classes['latex'].scan = myscanfunction - """ - node = self.inputs[0] - - nodes = [] - names = [] - seen = [] - if not node: - return (nodes, names) - - def parse_node(node): - if node in seen: - return - seen.append(node) - code = node.read() - for match in re_tex.finditer(code): - - multibib = match.group('type') - if multibib and multibib.startswith('bibliography'): - multibib = multibib[len('bibliography'):] - if multibib.startswith('style'): - continue - else: - multibib = None - - for path in match.group('file').split(','): - if path: - add_name = True - found = None - for k in exts_deps_tex: - - # issue 1067, scan in all texinputs folders - for up in self.texinputs_nodes: - Logs.debug('tex: trying %s%s', path, k) - found = up.find_resource(path + k) - if found: - break - - - for tsk in self.generator.tasks: - if not found or found in tsk.outputs: - break - else: - nodes.append(found) - add_name = False - for ext in exts_tex: - if found.name.endswith(ext): - parse_node(found) - break - - # multibib stuff - if found and multibib and found.name.endswith('.bib'): - try: - self.multibibs.append(found) - except AttributeError: - self.multibibs = [found] - - # no break, people are crazy - if add_name: - names.append(path) - parse_node(node) - - for x in nodes: - x.parent.get_bld().mkdir() - - Logs.debug("tex: found the following : %s and names %s", nodes, names) - return (nodes, names) - - def check_status(self, msg, retcode): - """ - Checks an exit status and raise an error with a particular message - - :param msg: message to display if the code is non-zero - :type msg: string - :param retcode: condition - :type retcode: boolean - """ - if retcode != 0: - raise Errors.WafError('%r command exit status %r' % (msg, retcode)) - - def info(self, *k, **kw): - try: - info = self.generator.bld.conf.logger.info - except AttributeError: - info = Logs.info - info(*k, **kw) - - def bibfile(self): - """ - Parses *.aux* files to find bibfiles to process. - If present, execute :py:meth:`waflib.Tools.tex.tex.bibtex_fun` - """ - for aux_node in self.aux_nodes: - try: - ct = aux_node.read() - except EnvironmentError: - Logs.error('Error reading %s: %r', aux_node.abspath()) - continue - - if g_bibtex_re.findall(ct): - self.info('calling bibtex') - - self.env.env = {} - self.env.env.update(os.environ) - self.env.env.update({'BIBINPUTS': self.texinputs(), 'BSTINPUTS': self.texinputs()}) - self.env.SRCFILE = aux_node.name[:-4] - self.check_status('error when calling bibtex', self.bibtex_fun()) - - for node in getattr(self, 'multibibs', []): - self.env.env = {} - self.env.env.update(os.environ) - self.env.env.update({'BIBINPUTS': self.texinputs(), 'BSTINPUTS': self.texinputs()}) - self.env.SRCFILE = node.name[:-4] - self.check_status('error when calling bibtex', self.bibtex_fun()) - - def bibunits(self): - """ - Parses *.aux* file to find bibunit files. If there are bibunit files, - runs :py:meth:`waflib.Tools.tex.tex.bibtex_fun`. - """ - try: - bibunits = bibunitscan(self) - except OSError: - Logs.error('error bibunitscan') - else: - if bibunits: - fn = ['bu' + str(i) for i in range(1, len(bibunits) + 1)] - if fn: - self.info('calling bibtex on bibunits') - - for f in fn: - self.env.env = {'BIBINPUTS': self.texinputs(), 'BSTINPUTS': self.texinputs()} - self.env.SRCFILE = f - self.check_status('error when calling bibtex', self.bibtex_fun()) - - def makeindex(self): - """ - Searches the filesystem for *.idx* files to process. If present, - runs :py:meth:`waflib.Tools.tex.tex.makeindex_fun` - """ - self.idx_node = self.inputs[0].change_ext('.idx') - try: - idx_path = self.idx_node.abspath() - os.stat(idx_path) - except OSError: - self.info('index file %s absent, not calling makeindex', idx_path) - else: - self.info('calling makeindex') - - self.env.SRCFILE = self.idx_node.name - self.env.env = {} - self.check_status('error when calling makeindex %s' % idx_path, self.makeindex_fun()) - - def bibtopic(self): - """ - Lists additional .aux files from the bibtopic package - """ - p = self.inputs[0].parent.get_bld() - if os.path.exists(os.path.join(p.abspath(), 'btaux.aux')): - self.aux_nodes += p.ant_glob('*[0-9].aux') - - def makeglossaries(self): - """ - Lists additional glossaries from .aux files. If present, runs the makeglossaries program. - """ - src_file = self.inputs[0].abspath() - base_file = os.path.basename(src_file) - base, _ = os.path.splitext(base_file) - for aux_node in self.aux_nodes: - try: - ct = aux_node.read() - except EnvironmentError: - Logs.error('Error reading %s: %r', aux_node.abspath()) - continue - - if g_glossaries_re.findall(ct): - if not self.env.MAKEGLOSSARIES: - raise Errors.WafError("The program 'makeglossaries' is missing!") - Logs.warn('calling makeglossaries') - self.env.SRCFILE = base - self.check_status('error when calling makeglossaries %s' % base, self.makeglossaries_fun()) - return - - def texinputs(self): - """ - Returns the list of texinput nodes as a string suitable for the TEXINPUTS environment variables - - :rtype: string - """ - return os.pathsep.join([k.abspath() for k in self.texinputs_nodes]) + os.pathsep - - def run(self): - """ - Runs the whole TeX build process - - Multiple passes are required depending on the usage of cross-references, - bibliographies, glossaries, indexes and additional contents - The appropriate TeX compiler is called until the *.aux* files stop changing. - """ - env = self.env - - if not env.PROMPT_LATEX: - env.append_value('LATEXFLAGS', '-interaction=batchmode') - env.append_value('PDFLATEXFLAGS', '-interaction=batchmode') - env.append_value('XELATEXFLAGS', '-interaction=batchmode') - - # important, set the cwd for everybody - self.cwd = self.inputs[0].parent.get_bld() - - self.info('first pass on %s', self.__class__.__name__) - - # Hash .aux files before even calling the LaTeX compiler - cur_hash = self.hash_aux_nodes() - - self.call_latex() - - # Find the .aux files again since bibtex processing can require it - self.hash_aux_nodes() - - self.bibtopic() - self.bibfile() - self.bibunits() - self.makeindex() - self.makeglossaries() - - for i in range(10): - # There is no need to call latex again if the .aux hash value has not changed - prev_hash = cur_hash - cur_hash = self.hash_aux_nodes() - if not cur_hash: - Logs.error('No aux.h to process') - if cur_hash and cur_hash == prev_hash: - break - - # run the command - self.info('calling %s', self.__class__.__name__) - self.call_latex() - - def hash_aux_nodes(self): - """ - Returns a hash of the .aux file contents - - :rtype: string or bytes - """ - try: - self.aux_nodes - except AttributeError: - try: - self.aux_nodes = self.scan_aux(self.inputs[0].change_ext('.aux')) - except IOError: - return None - return Utils.h_list([Utils.h_file(x.abspath()) for x in self.aux_nodes]) - - def call_latex(self): - """ - Runs the TeX compiler once - """ - self.env.env = {} - self.env.env.update(os.environ) - self.env.env.update({'TEXINPUTS': self.texinputs()}) - self.env.SRCFILE = self.inputs[0].abspath() - self.check_status('error when calling latex', self.texfun()) - -class latex(tex): - "Compiles LaTeX files" - texfun, vars = Task.compile_fun('${LATEX} ${LATEXFLAGS} ${SRCFILE}', shell=False) - -class pdflatex(tex): - "Compiles PdfLaTeX files" - texfun, vars = Task.compile_fun('${PDFLATEX} ${PDFLATEXFLAGS} ${SRCFILE}', shell=False) - -class xelatex(tex): - "XeLaTeX files" - texfun, vars = Task.compile_fun('${XELATEX} ${XELATEXFLAGS} ${SRCFILE}', shell=False) - -class dvips(Task.Task): - "Converts dvi files to postscript" - run_str = '${DVIPS} ${DVIPSFLAGS} ${SRC} -o ${TGT}' - color = 'BLUE' - after = ['latex', 'pdflatex', 'xelatex'] - -class dvipdf(Task.Task): - "Converts dvi files to pdf" - run_str = '${DVIPDF} ${DVIPDFFLAGS} ${SRC} ${TGT}' - color = 'BLUE' - after = ['latex', 'pdflatex', 'xelatex'] - -class pdf2ps(Task.Task): - "Converts pdf files to postscript" - run_str = '${PDF2PS} ${PDF2PSFLAGS} ${SRC} ${TGT}' - color = 'BLUE' - after = ['latex', 'pdflatex', 'xelatex'] - -@feature('tex') -@before_method('process_source') -def apply_tex(self): - """ - Creates :py:class:`waflib.Tools.tex.tex` objects, and - dvips/dvipdf/pdf2ps tasks if necessary (outs='ps', etc). - """ - if not getattr(self, 'type', None) in ('latex', 'pdflatex', 'xelatex'): - self.type = 'pdflatex' - - outs = Utils.to_list(getattr(self, 'outs', [])) - - # prompt for incomplete files (else the batchmode is used) - try: - self.generator.bld.conf - except AttributeError: - default_prompt = False - else: - default_prompt = True - self.env.PROMPT_LATEX = getattr(self, 'prompt', default_prompt) - - deps_lst = [] - - if getattr(self, 'deps', None): - deps = self.to_list(self.deps) - for dep in deps: - if isinstance(dep, str): - n = self.path.find_resource(dep) - if not n: - self.bld.fatal('Could not find %r for %r' % (dep, self)) - if not n in deps_lst: - deps_lst.append(n) - elif isinstance(dep, Node.Node): - deps_lst.append(dep) - - for node in self.to_nodes(self.source): - if self.type == 'latex': - task = self.create_task('latex', node, node.change_ext('.dvi')) - elif self.type == 'pdflatex': - task = self.create_task('pdflatex', node, node.change_ext('.pdf')) - elif self.type == 'xelatex': - task = self.create_task('xelatex', node, node.change_ext('.pdf')) - - task.env = self.env - - # add the manual dependencies - if deps_lst: - for n in deps_lst: - if not n in task.dep_nodes: - task.dep_nodes.append(n) - - # texinputs is a nasty beast - if hasattr(self, 'texinputs_nodes'): - task.texinputs_nodes = self.texinputs_nodes - else: - task.texinputs_nodes = [node.parent, node.parent.get_bld(), self.path, self.path.get_bld()] - lst = os.environ.get('TEXINPUTS', '') - if self.env.TEXINPUTS: - lst += os.pathsep + self.env.TEXINPUTS - if lst: - lst = lst.split(os.pathsep) - for x in lst: - if x: - if os.path.isabs(x): - p = self.bld.root.find_node(x) - if p: - task.texinputs_nodes.append(p) - else: - Logs.error('Invalid TEXINPUTS folder %s', x) - else: - Logs.error('Cannot resolve relative paths in TEXINPUTS %s', x) - - if self.type == 'latex': - if 'ps' in outs: - tsk = self.create_task('dvips', task.outputs, node.change_ext('.ps')) - tsk.env.env = dict(os.environ) - if 'pdf' in outs: - tsk = self.create_task('dvipdf', task.outputs, node.change_ext('.pdf')) - tsk.env.env = dict(os.environ) - elif self.type == 'pdflatex': - if 'ps' in outs: - self.create_task('pdf2ps', task.outputs, node.change_ext('.ps')) - self.source = [] - -def configure(self): - """ - Find the programs tex, latex and others without raising errors. - """ - v = self.env - for p in 'tex latex pdflatex xelatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps makeglossaries'.split(): - try: - self.find_program(p, var=p.upper()) - except self.errors.ConfigurationError: - pass - v.DVIPSFLAGS = '-Ppdf' - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/vala.py b/ldb-2.0.8/third_party/waf/waflib/Tools/vala.py deleted file mode 100644 index 822ec50..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/vala.py +++ /dev/null @@ -1,355 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Ali Sabil, 2007 -# Radosław Szkodziński, 2010 - -""" -At this point, vala is still unstable, so do not expect -this tool to be too stable either (apis, etc) -""" - -import re -from waflib import Build, Context, Errors, Logs, Node, Options, Task, Utils -from waflib.TaskGen import extension, taskgen_method -from waflib.Configure import conf - -class valac(Task.Task): - """ - Compiles vala files - """ - #run_str = "${VALAC} ${VALAFLAGS}" # ideally - #vars = ['VALAC_VERSION'] - vars = ["VALAC", "VALAC_VERSION", "VALAFLAGS"] - ext_out = ['.h'] - - def run(self): - cmd = self.env.VALAC + self.env.VALAFLAGS - resources = getattr(self, 'vala_exclude', []) - cmd.extend([a.abspath() for a in self.inputs if a not in resources]) - ret = self.exec_command(cmd, cwd=self.vala_dir_node.abspath()) - - if ret: - return ret - - if self.generator.dump_deps_node: - self.generator.dump_deps_node.write('\n'.join(self.generator.packages)) - - return ret - -@taskgen_method -def init_vala_task(self): - """ - Initializes the vala task with the relevant data (acts as a constructor) - """ - self.profile = getattr(self, 'profile', 'gobject') - - self.packages = packages = Utils.to_list(getattr(self, 'packages', [])) - self.use = Utils.to_list(getattr(self, 'use', [])) - if packages and not self.use: - self.use = packages[:] # copy - - if self.profile == 'gobject': - if not 'GOBJECT' in self.use: - self.use.append('GOBJECT') - - def addflags(flags): - self.env.append_value('VALAFLAGS', flags) - - if self.profile: - addflags('--profile=%s' % self.profile) - - valatask = self.valatask - - # output directory - if hasattr(self, 'vala_dir'): - if isinstance(self.vala_dir, str): - valatask.vala_dir_node = self.path.get_bld().make_node(self.vala_dir) - try: - valatask.vala_dir_node.mkdir() - except OSError: - raise self.bld.fatal('Cannot create the vala dir %r' % valatask.vala_dir_node) - else: - valatask.vala_dir_node = self.vala_dir - else: - valatask.vala_dir_node = self.path.get_bld() - addflags('--directory=%s' % valatask.vala_dir_node.abspath()) - - if hasattr(self, 'thread'): - if self.profile == 'gobject': - if not 'GTHREAD' in self.use: - self.use.append('GTHREAD') - else: - #Vala doesn't have threading support for dova nor posix - Logs.warn('Profile %s means no threading support', self.profile) - self.thread = False - - if self.thread: - addflags('--thread') - - self.is_lib = 'cprogram' not in self.features - if self.is_lib: - addflags('--library=%s' % self.target) - - h_node = valatask.vala_dir_node.find_or_declare('%s.h' % self.target) - valatask.outputs.append(h_node) - addflags('--header=%s' % h_node.name) - - valatask.outputs.append(valatask.vala_dir_node.find_or_declare('%s.vapi' % self.target)) - - if getattr(self, 'gir', None): - gir_node = valatask.vala_dir_node.find_or_declare('%s.gir' % self.gir) - addflags('--gir=%s' % gir_node.name) - valatask.outputs.append(gir_node) - - self.vala_target_glib = getattr(self, 'vala_target_glib', getattr(Options.options, 'vala_target_glib', None)) - if self.vala_target_glib: - addflags('--target-glib=%s' % self.vala_target_glib) - - addflags(['--define=%s' % x for x in Utils.to_list(getattr(self, 'vala_defines', []))]) - - packages_private = Utils.to_list(getattr(self, 'packages_private', [])) - addflags(['--pkg=%s' % x for x in packages_private]) - - def _get_api_version(): - api_version = '1.0' - if hasattr(Context.g_module, 'API_VERSION'): - version = Context.g_module.API_VERSION.split(".") - if version[0] == "0": - api_version = "0." + version[1] - else: - api_version = version[0] + ".0" - return api_version - - self.includes = Utils.to_list(getattr(self, 'includes', [])) - valatask.install_path = getattr(self, 'install_path', '') - - valatask.vapi_path = getattr(self, 'vapi_path', '${DATAROOTDIR}/vala/vapi') - valatask.pkg_name = getattr(self, 'pkg_name', self.env.PACKAGE) - valatask.header_path = getattr(self, 'header_path', '${INCLUDEDIR}/%s-%s' % (valatask.pkg_name, _get_api_version())) - valatask.install_binding = getattr(self, 'install_binding', True) - - self.vapi_dirs = vapi_dirs = Utils.to_list(getattr(self, 'vapi_dirs', [])) - #includes = [] - - if hasattr(self, 'use'): - local_packages = Utils.to_list(self.use)[:] # make sure to have a copy - seen = [] - while len(local_packages) > 0: - package = local_packages.pop() - if package in seen: - continue - seen.append(package) - - # check if the package exists - try: - package_obj = self.bld.get_tgen_by_name(package) - except Errors.WafError: - continue - - # in practice the other task is already processed - # but this makes it explicit - package_obj.post() - package_name = package_obj.target - task = getattr(package_obj, 'valatask', None) - if task: - for output in task.outputs: - if output.name == package_name + ".vapi": - valatask.set_run_after(task) - if package_name not in packages: - packages.append(package_name) - if output.parent not in vapi_dirs: - vapi_dirs.append(output.parent) - if output.parent not in self.includes: - self.includes.append(output.parent) - - if hasattr(package_obj, 'use'): - lst = self.to_list(package_obj.use) - lst.reverse() - local_packages = [pkg for pkg in lst if pkg not in seen] + local_packages - - addflags(['--pkg=%s' % p for p in packages]) - - for vapi_dir in vapi_dirs: - if isinstance(vapi_dir, Node.Node): - v_node = vapi_dir - else: - v_node = self.path.find_dir(vapi_dir) - if not v_node: - Logs.warn('Unable to locate Vala API directory: %r', vapi_dir) - else: - addflags('--vapidir=%s' % v_node.abspath()) - - self.dump_deps_node = None - if self.is_lib and self.packages: - self.dump_deps_node = valatask.vala_dir_node.find_or_declare('%s.deps' % self.target) - valatask.outputs.append(self.dump_deps_node) - - if self.is_lib and valatask.install_binding: - headers_list = [o for o in valatask.outputs if o.suffix() == ".h"] - if headers_list: - self.install_vheader = self.add_install_files(install_to=valatask.header_path, install_from=headers_list) - - vapi_list = [o for o in valatask.outputs if (o.suffix() in (".vapi", ".deps"))] - if vapi_list: - self.install_vapi = self.add_install_files(install_to=valatask.vapi_path, install_from=vapi_list) - - gir_list = [o for o in valatask.outputs if o.suffix() == '.gir'] - if gir_list: - self.install_gir = self.add_install_files( - install_to=getattr(self, 'gir_path', '${DATAROOTDIR}/gir-1.0'), install_from=gir_list) - - if hasattr(self, 'vala_resources'): - nodes = self.to_nodes(self.vala_resources) - valatask.vala_exclude = getattr(valatask, 'vala_exclude', []) + nodes - valatask.inputs.extend(nodes) - for x in nodes: - addflags(['--gresources', x.abspath()]) - -@extension('.vala', '.gs') -def vala_file(self, node): - """ - Compile a vala file and bind the task to *self.valatask*. If an existing vala task is already set, add the node - to its inputs. The typical example is:: - - def build(bld): - bld.program( - packages = 'gtk+-2.0', - target = 'vala-gtk-example', - use = 'GTK GLIB', - source = 'vala-gtk-example.vala foo.vala', - vala_defines = ['DEBUG'] # adds --define= values to the command-line - - # the following arguments are for libraries - #gir = 'hello-1.0', - #gir_path = '/tmp', - #vapi_path = '/tmp', - #pkg_name = 'hello' - # disable installing of gir, vapi and header - #install_binding = False - - # profile = 'xyz' # adds --profile= to enable profiling - # thread = True, # adds --thread, except if profile is on or not on 'gobject' - # vala_target_glib = 'xyz' # adds --target-glib=, can be given through the command-line option --vala-target-glib= - ) - - - :param node: vala file - :type node: :py:class:`waflib.Node.Node` - """ - - try: - valatask = self.valatask - except AttributeError: - valatask = self.valatask = self.create_task('valac') - self.init_vala_task() - - valatask.inputs.append(node) - name = node.name[:node.name.rfind('.')] + '.c' - c_node = valatask.vala_dir_node.find_or_declare(name) - valatask.outputs.append(c_node) - self.source.append(c_node) - -@extension('.vapi') -def vapi_file(self, node): - try: - valatask = self.valatask - except AttributeError: - valatask = self.valatask = self.create_task('valac') - self.init_vala_task() - valatask.inputs.append(node) - -@conf -def find_valac(self, valac_name, min_version): - """ - Find the valac program, and execute it to store the version - number in *conf.env.VALAC_VERSION* - - :param valac_name: program name - :type valac_name: string or list of string - :param min_version: minimum version acceptable - :type min_version: tuple of int - """ - valac = self.find_program(valac_name, var='VALAC') - try: - output = self.cmd_and_log(valac + ['--version']) - except Errors.WafError: - valac_version = None - else: - ver = re.search(r'\d+.\d+.\d+', output).group().split('.') - valac_version = tuple([int(x) for x in ver]) - - self.msg('Checking for %s version >= %r' % (valac_name, min_version), - valac_version, valac_version and valac_version >= min_version) - if valac and valac_version < min_version: - self.fatal("%s version %r is too old, need >= %r" % (valac_name, valac_version, min_version)) - - self.env.VALAC_VERSION = valac_version - return valac - -@conf -def check_vala(self, min_version=(0,8,0), branch=None): - """ - Check if vala compiler from a given branch exists of at least a given - version. - - :param min_version: minimum version acceptable (0.8.0) - :type min_version: tuple - :param branch: first part of the version number, in case a snapshot is used (0, 8) - :type branch: tuple of int - """ - if self.env.VALA_MINVER: - min_version = self.env.VALA_MINVER - if self.env.VALA_MINVER_BRANCH: - branch = self.env.VALA_MINVER_BRANCH - if not branch: - branch = min_version[:2] - try: - find_valac(self, 'valac-%d.%d' % (branch[0], branch[1]), min_version) - except self.errors.ConfigurationError: - find_valac(self, 'valac', min_version) - -@conf -def check_vala_deps(self): - """ - Load the gobject and gthread packages if they are missing. - """ - if not self.env.HAVE_GOBJECT: - pkg_args = {'package': 'gobject-2.0', - 'uselib_store': 'GOBJECT', - 'args': '--cflags --libs'} - if getattr(Options.options, 'vala_target_glib', None): - pkg_args['atleast_version'] = Options.options.vala_target_glib - self.check_cfg(**pkg_args) - - if not self.env.HAVE_GTHREAD: - pkg_args = {'package': 'gthread-2.0', - 'uselib_store': 'GTHREAD', - 'args': '--cflags --libs'} - if getattr(Options.options, 'vala_target_glib', None): - pkg_args['atleast_version'] = Options.options.vala_target_glib - self.check_cfg(**pkg_args) - -def configure(self): - """ - Use the following to enforce minimum vala version:: - - def configure(conf): - conf.env.VALA_MINVER = (0, 10, 0) - conf.load('vala') - """ - self.load('gnu_dirs') - self.check_vala_deps() - self.check_vala() - self.add_os_flags('VALAFLAGS') - self.env.append_unique('VALAFLAGS', ['-C']) - -def options(opt): - """ - Load the :py:mod:`waflib.Tools.gnu_dirs` tool and add the ``--vala-target-glib`` command-line option - """ - opt.load('gnu_dirs') - valaopts = opt.add_option_group('Vala Compiler Options') - valaopts.add_option('--vala-target-glib', default=None, - dest='vala_target_glib', metavar='MAJOR.MINOR', - help='Target version of glib for Vala GObject code generation') - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/waf_unit_test.py b/ldb-2.0.8/third_party/waf/waflib/Tools/waf_unit_test.py deleted file mode 100644 index 6ff6f72..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/waf_unit_test.py +++ /dev/null @@ -1,296 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Carlos Rafael Giani, 2006 -# Thomas Nagy, 2010-2018 (ita) - -""" -Unit testing system for C/C++/D and interpreted languages providing test execution: - -* in parallel, by using ``waf -j`` -* partial (only the tests that have changed) or full (by using ``waf --alltests``) - -The tests are declared by adding the **test** feature to programs:: - - def options(opt): - opt.load('compiler_cxx waf_unit_test') - def configure(conf): - conf.load('compiler_cxx waf_unit_test') - def build(bld): - bld(features='cxx cxxprogram test', source='main.cpp', target='app') - # or - bld.program(features='test', source='main2.cpp', target='app2') - -When the build is executed, the program 'test' will be built and executed without arguments. -The success/failure is detected by looking at the return code. The status and the standard output/error -are stored on the build context. - -The results can be displayed by registering a callback function. Here is how to call -the predefined callback:: - - def build(bld): - bld(features='cxx cxxprogram test', source='main.c', target='app') - from waflib.Tools import waf_unit_test - bld.add_post_fun(waf_unit_test.summary) - -By passing --dump-test-scripts the build outputs corresponding python files -(with extension _run.py) that are useful for debugging purposes. -""" - -import os, shlex, sys -from waflib.TaskGen import feature, after_method, taskgen_method -from waflib import Utils, Task, Logs, Options -from waflib.Tools import ccroot -testlock = Utils.threading.Lock() - -SCRIPT_TEMPLATE = """#! %(python)s -import subprocess, sys -cmd = %(cmd)r -# if you want to debug with gdb: -#cmd = ['gdb', '-args'] + cmd -env = %(env)r -status = subprocess.call(cmd, env=env, cwd=%(cwd)r, shell=isinstance(cmd, str)) -sys.exit(status) -""" - -@taskgen_method -def handle_ut_cwd(self, key): - """ - Task generator method, used internally to limit code duplication. - This method may disappear anytime. - """ - cwd = getattr(self, key, None) - if cwd: - if isinstance(cwd, str): - # we want a Node instance - if os.path.isabs(cwd): - self.ut_cwd = self.bld.root.make_node(cwd) - else: - self.ut_cwd = self.path.make_node(cwd) - -@feature('test_scripts') -def make_interpreted_test(self): - """Create interpreted unit tests.""" - for x in ['test_scripts_source', 'test_scripts_template']: - if not hasattr(self, x): - Logs.warn('a test_scripts taskgen i missing %s' % x) - return - - self.ut_run, lst = Task.compile_fun(self.test_scripts_template, shell=getattr(self, 'test_scripts_shell', False)) - - script_nodes = self.to_nodes(self.test_scripts_source) - for script_node in script_nodes: - tsk = self.create_task('utest', [script_node]) - tsk.vars = lst + tsk.vars - tsk.env['SCRIPT'] = script_node.path_from(tsk.get_cwd()) - - self.handle_ut_cwd('test_scripts_cwd') - - env = getattr(self, 'test_scripts_env', None) - if env: - self.ut_env = env - else: - self.ut_env = dict(os.environ) - - paths = getattr(self, 'test_scripts_paths', {}) - for (k,v) in paths.items(): - p = self.ut_env.get(k, '').split(os.pathsep) - if isinstance(v, str): - v = v.split(os.pathsep) - self.ut_env[k] = os.pathsep.join(p + v) - -@feature('test') -@after_method('apply_link', 'process_use') -def make_test(self): - """Create the unit test task. There can be only one unit test task by task generator.""" - if not getattr(self, 'link_task', None): - return - - tsk = self.create_task('utest', self.link_task.outputs) - if getattr(self, 'ut_str', None): - self.ut_run, lst = Task.compile_fun(self.ut_str, shell=getattr(self, 'ut_shell', False)) - tsk.vars = lst + tsk.vars - - self.handle_ut_cwd('ut_cwd') - - if not hasattr(self, 'ut_paths'): - paths = [] - for x in self.tmp_use_sorted: - try: - y = self.bld.get_tgen_by_name(x).link_task - except AttributeError: - pass - else: - if not isinstance(y, ccroot.stlink_task): - paths.append(y.outputs[0].parent.abspath()) - self.ut_paths = os.pathsep.join(paths) + os.pathsep - - if not hasattr(self, 'ut_env'): - self.ut_env = dct = dict(os.environ) - def add_path(var): - dct[var] = self.ut_paths + dct.get(var,'') - if Utils.is_win32: - add_path('PATH') - elif Utils.unversioned_sys_platform() == 'darwin': - add_path('DYLD_LIBRARY_PATH') - add_path('LD_LIBRARY_PATH') - else: - add_path('LD_LIBRARY_PATH') - - if not hasattr(self, 'ut_cmd'): - self.ut_cmd = getattr(Options.options, 'testcmd', False) - -@taskgen_method -def add_test_results(self, tup): - """Override and return tup[1] to interrupt the build immediately if a test does not run""" - Logs.debug("ut: %r", tup) - try: - self.utest_results.append(tup) - except AttributeError: - self.utest_results = [tup] - try: - self.bld.utest_results.append(tup) - except AttributeError: - self.bld.utest_results = [tup] - -@Task.deep_inputs -class utest(Task.Task): - """ - Execute a unit test - """ - color = 'PINK' - after = ['vnum', 'inst'] - vars = [] - - def runnable_status(self): - """ - Always execute the task if `waf --alltests` was used or no - tests if ``waf --notests`` was used - """ - if getattr(Options.options, 'no_tests', False): - return Task.SKIP_ME - - ret = super(utest, self).runnable_status() - if ret == Task.SKIP_ME: - if getattr(Options.options, 'all_tests', False): - return Task.RUN_ME - return ret - - def get_test_env(self): - """ - In general, tests may require any library built anywhere in the project. - Override this method if fewer paths are needed - """ - return self.generator.ut_env - - def post_run(self): - super(utest, self).post_run() - if getattr(Options.options, 'clear_failed_tests', False) and self.waf_unit_test_results[1]: - self.generator.bld.task_sigs[self.uid()] = None - - def run(self): - """ - Execute the test. The execution is always successful, and the results - are stored on ``self.generator.bld.utest_results`` for postprocessing. - - Override ``add_test_results`` to interrupt the build - """ - if hasattr(self.generator, 'ut_run'): - return self.generator.ut_run(self) - - self.ut_exec = getattr(self.generator, 'ut_exec', [self.inputs[0].abspath()]) - ut_cmd = getattr(self.generator, 'ut_cmd', False) - if ut_cmd: - self.ut_exec = shlex.split(ut_cmd % ' '.join(self.ut_exec)) - - return self.exec_command(self.ut_exec) - - def exec_command(self, cmd, **kw): - self.generator.bld.log_command(cmd, kw) - if getattr(Options.options, 'dump_test_scripts', False): - script_code = SCRIPT_TEMPLATE % { - 'python': sys.executable, - 'env': self.get_test_env(), - 'cwd': self.get_cwd().abspath(), - 'cmd': cmd - } - script_file = self.inputs[0].abspath() + '_run.py' - Utils.writef(script_file, script_code, encoding='utf-8') - os.chmod(script_file, Utils.O755) - if Logs.verbose > 1: - Logs.info('Test debug file written as %r' % script_file) - - proc = Utils.subprocess.Popen(cmd, cwd=self.get_cwd().abspath(), env=self.get_test_env(), - stderr=Utils.subprocess.PIPE, stdout=Utils.subprocess.PIPE, shell=isinstance(cmd,str)) - (stdout, stderr) = proc.communicate() - self.waf_unit_test_results = tup = (self.inputs[0].abspath(), proc.returncode, stdout, stderr) - testlock.acquire() - try: - return self.generator.add_test_results(tup) - finally: - testlock.release() - - def get_cwd(self): - return getattr(self.generator, 'ut_cwd', self.inputs[0].parent) - -def summary(bld): - """ - Display an execution summary:: - - def build(bld): - bld(features='cxx cxxprogram test', source='main.c', target='app') - from waflib.Tools import waf_unit_test - bld.add_post_fun(waf_unit_test.summary) - """ - lst = getattr(bld, 'utest_results', []) - if lst: - Logs.pprint('CYAN', 'execution summary') - - total = len(lst) - tfail = len([x for x in lst if x[1]]) - - Logs.pprint('GREEN', ' tests that pass %d/%d' % (total-tfail, total)) - for (f, code, out, err) in lst: - if not code: - Logs.pprint('GREEN', ' %s' % f) - - Logs.pprint('GREEN' if tfail == 0 else 'RED', ' tests that fail %d/%d' % (tfail, total)) - for (f, code, out, err) in lst: - if code: - Logs.pprint('RED', ' %s' % f) - -def set_exit_code(bld): - """ - If any of the tests fail waf will exit with that exit code. - This is useful if you have an automated build system which need - to report on errors from the tests. - You may use it like this: - - def build(bld): - bld(features='cxx cxxprogram test', source='main.c', target='app') - from waflib.Tools import waf_unit_test - bld.add_post_fun(waf_unit_test.set_exit_code) - """ - lst = getattr(bld, 'utest_results', []) - for (f, code, out, err) in lst: - if code: - msg = [] - if out: - msg.append('stdout:%s%s' % (os.linesep, out.decode('utf-8'))) - if err: - msg.append('stderr:%s%s' % (os.linesep, err.decode('utf-8'))) - bld.fatal(os.linesep.join(msg)) - - -def options(opt): - """ - Provide the ``--alltests``, ``--notests`` and ``--testcmd`` command-line options. - """ - opt.add_option('--notests', action='store_true', default=False, help='Exec no unit tests', dest='no_tests') - opt.add_option('--alltests', action='store_true', default=False, help='Exec all unit tests', dest='all_tests') - opt.add_option('--clear-failed', action='store_true', default=False, - help='Force failed unit tests to run again next time', dest='clear_failed_tests') - opt.add_option('--testcmd', action='store', default=False, dest='testcmd', - help='Run the unit tests using the test-cmd string example "--testcmd="valgrind --error-exitcode=1 %s" to run under valgrind') - opt.add_option('--dump-test-scripts', action='store_true', default=False, - help='Create python scripts to help debug tests', dest='dump_test_scripts') - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/winres.py b/ldb-2.0.8/third_party/waf/waflib/Tools/winres.py deleted file mode 100644 index 9be1ed6..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/winres.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Brant Young, 2007 - -"Process *.rc* files for C/C++: X{.rc -> [.res|.rc.o]}" - -import re -from waflib import Task -from waflib.TaskGen import extension -from waflib.Tools import c_preproc - -@extension('.rc') -def rc_file(self, node): - """ - Binds the .rc extension to a winrc task - """ - obj_ext = '.rc.o' - if self.env.WINRC_TGT_F == '/fo': - obj_ext = '.res' - rctask = self.create_task('winrc', node, node.change_ext(obj_ext)) - try: - self.compiled_tasks.append(rctask) - except AttributeError: - self.compiled_tasks = [rctask] - -re_lines = re.compile( - r'(?:^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*?)\s*$)|'\ - r'(?:^\w+[ \t]*(ICON|BITMAP|CURSOR|HTML|FONT|MESSAGETABLE|TYPELIB|REGISTRY|D3DFX)[ \t]*(.*?)\s*$)', - re.IGNORECASE | re.MULTILINE) - -class rc_parser(c_preproc.c_parser): - """ - Calculates dependencies in .rc files - """ - def filter_comments(self, node): - """ - Overrides :py:meth:`waflib.Tools.c_preproc.c_parser.filter_comments` - """ - code = node.read() - if c_preproc.use_trigraphs: - for (a, b) in c_preproc.trig_def: - code = code.split(a).join(b) - code = c_preproc.re_nl.sub('', code) - code = c_preproc.re_cpp.sub(c_preproc.repl, code) - ret = [] - for m in re.finditer(re_lines, code): - if m.group(2): - ret.append((m.group(2), m.group(3))) - else: - ret.append(('include', m.group(5))) - return ret - -class winrc(Task.Task): - """ - Compiles resource files - """ - run_str = '${WINRC} ${WINRCFLAGS} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${WINRC_TGT_F} ${TGT} ${WINRC_SRC_F} ${SRC}' - color = 'BLUE' - def scan(self): - tmp = rc_parser(self.generator.includes_nodes) - tmp.start(self.inputs[0], self.env) - return (tmp.nodes, tmp.names) - -def configure(conf): - """ - Detects the programs RC or windres, depending on the C/C++ compiler in use - """ - v = conf.env - if not v.WINRC: - if v.CC_NAME == 'msvc': - conf.find_program('RC', var='WINRC', path_list=v.PATH) - v.WINRC_TGT_F = '/fo' - v.WINRC_SRC_F = '' - else: - conf.find_program('windres', var='WINRC', path_list=v.PATH) - v.WINRC_TGT_F = '-o' - v.WINRC_SRC_F = '-i' - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/xlc.py b/ldb-2.0.8/third_party/waf/waflib/Tools/xlc.py deleted file mode 100644 index 134dd41..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/xlc.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2006-2018 (ita) -# Ralf Habacker, 2006 (rh) -# Yinon Ehrlich, 2009 -# Michael Kuhn, 2009 - -from waflib.Tools import ccroot, ar -from waflib.Configure import conf - -@conf -def find_xlc(conf): - """ - Detects the Aix C compiler - """ - cc = conf.find_program(['xlc_r', 'xlc'], var='CC') - conf.get_xlc_version(cc) - conf.env.CC_NAME = 'xlc' - -@conf -def xlc_common_flags(conf): - """ - Flags required for executing the Aix C compiler - """ - v = conf.env - - v.CC_SRC_F = [] - v.CC_TGT_F = ['-c', '-o'] - - if not v.LINK_CC: - v.LINK_CC = v.CC - - v.CCLNK_SRC_F = [] - v.CCLNK_TGT_F = ['-o'] - v.CPPPATH_ST = '-I%s' - v.DEFINES_ST = '-D%s' - - v.LIB_ST = '-l%s' # template for adding libs - v.LIBPATH_ST = '-L%s' # template for adding libpaths - v.STLIB_ST = '-l%s' - v.STLIBPATH_ST = '-L%s' - v.RPATH_ST = '-Wl,-rpath,%s' - - v.SONAME_ST = [] - v.SHLIB_MARKER = [] - v.STLIB_MARKER = [] - - v.LINKFLAGS_cprogram = ['-Wl,-brtl'] - v.cprogram_PATTERN = '%s' - - v.CFLAGS_cshlib = ['-fPIC'] - v.LINKFLAGS_cshlib = ['-G', '-Wl,-brtl,-bexpfull'] - v.cshlib_PATTERN = 'lib%s.so' - - v.LINKFLAGS_cstlib = [] - v.cstlib_PATTERN = 'lib%s.a' - -def configure(conf): - conf.find_xlc() - conf.find_ar() - conf.xlc_common_flags() - conf.cc_load_tools() - conf.cc_add_flags() - conf.link_add_flags() - diff --git a/ldb-2.0.8/third_party/waf/waflib/Tools/xlcxx.py b/ldb-2.0.8/third_party/waf/waflib/Tools/xlcxx.py deleted file mode 100644 index 76aa59b..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Tools/xlcxx.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2006-2018 (ita) -# Ralf Habacker, 2006 (rh) -# Yinon Ehrlich, 2009 -# Michael Kuhn, 2009 - -from waflib.Tools import ccroot, ar -from waflib.Configure import conf - -@conf -def find_xlcxx(conf): - """ - Detects the Aix C++ compiler - """ - cxx = conf.find_program(['xlc++_r', 'xlc++'], var='CXX') - conf.get_xlc_version(cxx) - conf.env.CXX_NAME = 'xlc++' - -@conf -def xlcxx_common_flags(conf): - """ - Flags required for executing the Aix C++ compiler - """ - v = conf.env - - v.CXX_SRC_F = [] - v.CXX_TGT_F = ['-c', '-o'] - - if not v.LINK_CXX: - v.LINK_CXX = v.CXX - - v.CXXLNK_SRC_F = [] - v.CXXLNK_TGT_F = ['-o'] - v.CPPPATH_ST = '-I%s' - v.DEFINES_ST = '-D%s' - - v.LIB_ST = '-l%s' # template for adding libs - v.LIBPATH_ST = '-L%s' # template for adding libpaths - v.STLIB_ST = '-l%s' - v.STLIBPATH_ST = '-L%s' - v.RPATH_ST = '-Wl,-rpath,%s' - - v.SONAME_ST = [] - v.SHLIB_MARKER = [] - v.STLIB_MARKER = [] - - v.LINKFLAGS_cxxprogram= ['-Wl,-brtl'] - v.cxxprogram_PATTERN = '%s' - - v.CXXFLAGS_cxxshlib = ['-fPIC'] - v.LINKFLAGS_cxxshlib = ['-G', '-Wl,-brtl,-bexpfull'] - v.cxxshlib_PATTERN = 'lib%s.so' - - v.LINKFLAGS_cxxstlib = [] - v.cxxstlib_PATTERN = 'lib%s.a' - -def configure(conf): - conf.find_xlcxx() - conf.find_ar() - conf.xlcxx_common_flags() - conf.cxx_load_tools() - conf.cxx_add_flags() - conf.link_add_flags() - diff --git a/ldb-2.0.8/third_party/waf/waflib/Utils.py b/ldb-2.0.8/third_party/waf/waflib/Utils.py deleted file mode 100644 index 7472226..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/Utils.py +++ /dev/null @@ -1,1035 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2005-2018 (ita) - -""" -Utilities and platform-specific fixes - -The portability fixes try to provide a consistent behavior of the Waf API -through Python versions 2.5 to 3.X and across different platforms (win32, linux, etc) -""" - -from __future__ import with_statement - -import atexit, os, sys, errno, inspect, re, datetime, platform, base64, signal, functools, time - -try: - import cPickle -except ImportError: - import pickle as cPickle - -# leave this -if os.name == 'posix' and sys.version_info[0] < 3: - try: - import subprocess32 as subprocess - except ImportError: - import subprocess -else: - import subprocess - -try: - TimeoutExpired = subprocess.TimeoutExpired -except AttributeError: - class TimeoutExpired(Exception): - pass - -from collections import deque, defaultdict - -try: - import _winreg as winreg -except ImportError: - try: - import winreg - except ImportError: - winreg = None - -from waflib import Errors - -try: - from hashlib import md5 -except ImportError: - try: - from hashlib import sha1 as md5 - except ImportError: - # never fail to enable potential fixes from another module - pass -else: - try: - md5().digest() - except ValueError: - # Fips? #2213 - from hashlib import sha1 as md5 - -try: - import threading -except ImportError: - if not 'JOBS' in os.environ: - # no threading :-( - os.environ['JOBS'] = '1' - - class threading(object): - """ - A fake threading class for platforms lacking the threading module. - Use ``waf -j1`` on those platforms - """ - pass - class Lock(object): - """Fake Lock class""" - def acquire(self): - pass - def release(self): - pass - threading.Lock = threading.Thread = Lock - -SIG_NIL = 'SIG_NIL_SIG_NIL_'.encode() -"""Arbitrary null value for hashes. Modify this value according to the hash function in use""" - -O644 = 420 -"""Constant representing the permissions for regular files (0644 raises a syntax error on python 3)""" - -O755 = 493 -"""Constant representing the permissions for executable files (0755 raises a syntax error on python 3)""" - -rot_chr = ['\\', '|', '/', '-'] -"List of characters to use when displaying the throbber (progress bar)" - -rot_idx = 0 -"Index of the current throbber character (progress bar)" - -class ordered_iter_dict(dict): - """Ordered dictionary that provides iteration from the most recently inserted keys first""" - def __init__(self, *k, **kw): - self.lst = deque() - dict.__init__(self, *k, **kw) - def clear(self): - dict.clear(self) - self.lst = deque() - def __setitem__(self, key, value): - if key in dict.keys(self): - self.lst.remove(key) - dict.__setitem__(self, key, value) - self.lst.append(key) - def __delitem__(self, key): - dict.__delitem__(self, key) - try: - self.lst.remove(key) - except ValueError: - pass - def __iter__(self): - return reversed(self.lst) - def keys(self): - return reversed(self.lst) - -class lru_node(object): - """ - Used by :py:class:`waflib.Utils.lru_cache` - """ - __slots__ = ('next', 'prev', 'key', 'val') - def __init__(self): - self.next = self - self.prev = self - self.key = None - self.val = None - -class lru_cache(object): - """ - A simple least-recently used cache with lazy allocation - """ - __slots__ = ('maxlen', 'table', 'head') - def __init__(self, maxlen=100): - self.maxlen = maxlen - """ - Maximum amount of elements in the cache - """ - self.table = {} - """ - Mapping key-value - """ - self.head = lru_node() - self.head.next = self.head - self.head.prev = self.head - - def __getitem__(self, key): - node = self.table[key] - # assert(key==node.key) - if node is self.head: - return node.val - - # detach the node found - node.prev.next = node.next - node.next.prev = node.prev - - # replace the head - node.next = self.head.next - node.prev = self.head - self.head = node.next.prev = node.prev.next = node - - return node.val - - def __setitem__(self, key, val): - if key in self.table: - # update the value for an existing key - node = self.table[key] - node.val = val - self.__getitem__(key) - else: - if len(self.table) < self.maxlen: - # the very first item is unused until the maximum is reached - node = lru_node() - node.prev = self.head - node.next = self.head.next - node.prev.next = node.next.prev = node - else: - node = self.head = self.head.next - try: - # that's another key - del self.table[node.key] - except KeyError: - pass - - node.key = key - node.val = val - self.table[key] = node - -class lazy_generator(object): - def __init__(self, fun, params): - self.fun = fun - self.params = params - - def __iter__(self): - return self - - def __next__(self): - try: - it = self.it - except AttributeError: - it = self.it = self.fun(*self.params) - return next(it) - - next = __next__ - -is_win32 = os.sep == '\\' or sys.platform == 'win32' or os.name == 'nt' # msys2 -""" -Whether this system is a Windows series -""" - -def readf(fname, m='r', encoding='latin-1'): - """ - Reads an entire file into a string. See also :py:meth:`waflib.Node.Node.readf`:: - - def build(ctx): - from waflib import Utils - txt = Utils.readf(self.path.find_node('wscript').abspath()) - txt = ctx.path.find_node('wscript').read() - - :type fname: string - :param fname: Path to file - :type m: string - :param m: Open mode - :type encoding: string - :param encoding: encoding value, only used for python 3 - :rtype: string - :return: Content of the file - """ - - if sys.hexversion > 0x3000000 and not 'b' in m: - m += 'b' - with open(fname, m) as f: - txt = f.read() - if encoding: - txt = txt.decode(encoding) - else: - txt = txt.decode() - else: - with open(fname, m) as f: - txt = f.read() - return txt - -def writef(fname, data, m='w', encoding='latin-1'): - """ - Writes an entire file from a string. - See also :py:meth:`waflib.Node.Node.writef`:: - - def build(ctx): - from waflib import Utils - txt = Utils.writef(self.path.make_node('i_like_kittens').abspath(), 'some data') - self.path.make_node('i_like_kittens').write('some data') - - :type fname: string - :param fname: Path to file - :type data: string - :param data: The contents to write to the file - :type m: string - :param m: Open mode - :type encoding: string - :param encoding: encoding value, only used for python 3 - """ - if sys.hexversion > 0x3000000 and not 'b' in m: - data = data.encode(encoding) - m += 'b' - with open(fname, m) as f: - f.write(data) - -def h_file(fname): - """ - Computes a hash value for a file by using md5. Use the md5_tstamp - extension to get faster build hashes if necessary. - - :type fname: string - :param fname: path to the file to hash - :return: hash of the file contents - :rtype: string or bytes - """ - m = md5() - with open(fname, 'rb') as f: - while fname: - fname = f.read(200000) - m.update(fname) - return m.digest() - -def readf_win32(f, m='r', encoding='latin-1'): - flags = os.O_NOINHERIT | os.O_RDONLY - if 'b' in m: - flags |= os.O_BINARY - if '+' in m: - flags |= os.O_RDWR - try: - fd = os.open(f, flags) - except OSError: - raise IOError('Cannot read from %r' % f) - - if sys.hexversion > 0x3000000 and not 'b' in m: - m += 'b' - with os.fdopen(fd, m) as f: - txt = f.read() - if encoding: - txt = txt.decode(encoding) - else: - txt = txt.decode() - else: - with os.fdopen(fd, m) as f: - txt = f.read() - return txt - -def writef_win32(f, data, m='w', encoding='latin-1'): - if sys.hexversion > 0x3000000 and not 'b' in m: - data = data.encode(encoding) - m += 'b' - flags = os.O_CREAT | os.O_TRUNC | os.O_WRONLY | os.O_NOINHERIT - if 'b' in m: - flags |= os.O_BINARY - if '+' in m: - flags |= os.O_RDWR - try: - fd = os.open(f, flags) - except OSError: - raise OSError('Cannot write to %r' % f) - with os.fdopen(fd, m) as f: - f.write(data) - -def h_file_win32(fname): - try: - fd = os.open(fname, os.O_BINARY | os.O_RDONLY | os.O_NOINHERIT) - except OSError: - raise OSError('Cannot read from %r' % fname) - m = md5() - with os.fdopen(fd, 'rb') as f: - while fname: - fname = f.read(200000) - m.update(fname) - return m.digest() - -# always save these -readf_unix = readf -writef_unix = writef -h_file_unix = h_file -if hasattr(os, 'O_NOINHERIT') and sys.hexversion < 0x3040000: - # replace the default functions - readf = readf_win32 - writef = writef_win32 - h_file = h_file_win32 - -try: - x = ''.encode('hex') -except LookupError: - import binascii - def to_hex(s): - ret = binascii.hexlify(s) - if not isinstance(ret, str): - ret = ret.decode('utf-8') - return ret -else: - def to_hex(s): - return s.encode('hex') - -to_hex.__doc__ = """ -Return the hexadecimal representation of a string - -:param s: string to convert -:type s: string -""" - -def listdir_win32(s): - """ - Lists the contents of a folder in a portable manner. - On Win32, returns the list of drive letters: ['C:', 'X:', 'Z:'] when an empty string is given. - - :type s: string - :param s: a string, which can be empty on Windows - """ - if not s: - try: - import ctypes - except ImportError: - # there is nothing much we can do - return [x + ':\\' for x in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'] - else: - dlen = 4 # length of "?:\\x00" - maxdrives = 26 - buf = ctypes.create_string_buffer(maxdrives * dlen) - ndrives = ctypes.windll.kernel32.GetLogicalDriveStringsA(maxdrives*dlen, ctypes.byref(buf)) - return [ str(buf.raw[4*i:4*i+2].decode('ascii')) for i in range(int(ndrives/dlen)) ] - - if len(s) == 2 and s[1] == ":": - s += os.sep - - if not os.path.isdir(s): - e = OSError('%s is not a directory' % s) - e.errno = errno.ENOENT - raise e - return os.listdir(s) - -listdir = os.listdir -if is_win32: - listdir = listdir_win32 - -def num2ver(ver): - """ - Converts a string, tuple or version number into an integer. The number is supposed to have at most 4 digits:: - - from waflib.Utils import num2ver - num2ver('1.3.2') == num2ver((1,3,2)) == num2ver((1,3,2,0)) - - :type ver: string or tuple of numbers - :param ver: a version number - """ - if isinstance(ver, str): - ver = tuple(ver.split('.')) - if isinstance(ver, tuple): - ret = 0 - for i in range(4): - if i < len(ver): - ret += 256**(3 - i) * int(ver[i]) - return ret - return ver - -def to_list(val): - """ - Converts a string argument to a list by splitting it by spaces. - Returns the object if not a string:: - - from waflib.Utils import to_list - lst = to_list('a b c d') - - :param val: list of string or space-separated string - :rtype: list - :return: Argument converted to list - """ - if isinstance(val, str): - return val.split() - else: - return val - -def console_encoding(): - try: - import ctypes - except ImportError: - pass - else: - try: - codepage = ctypes.windll.kernel32.GetConsoleCP() - except AttributeError: - pass - else: - if codepage: - return 'cp%d' % codepage - return sys.stdout.encoding or ('cp1252' if is_win32 else 'latin-1') - -def split_path_unix(path): - return path.split('/') - -def split_path_cygwin(path): - if path.startswith('//'): - ret = path.split('/')[2:] - ret[0] = '/' + ret[0] - return ret - return path.split('/') - -re_sp = re.compile('[/\\\\]+') -def split_path_win32(path): - if path.startswith('\\\\'): - ret = re_sp.split(path)[1:] - ret[0] = '\\\\' + ret[0] - if ret[0] == '\\\\?': - return ret[1:] - return ret - return re_sp.split(path) - -msysroot = None -def split_path_msys(path): - if path.startswith(('/', '\\')) and not path.startswith(('//', '\\\\')): - # msys paths can be in the form /usr/bin - global msysroot - if not msysroot: - # msys has python 2.7 or 3, so we can use this - msysroot = subprocess.check_output(['cygpath', '-w', '/']).decode(sys.stdout.encoding or 'latin-1') - msysroot = msysroot.strip() - path = os.path.normpath(msysroot + os.sep + path) - return split_path_win32(path) - -if sys.platform == 'cygwin': - split_path = split_path_cygwin -elif is_win32: - # Consider this an MSYSTEM environment if $MSYSTEM is set and python - # reports is executable from a unix like path on a windows host. - if os.environ.get('MSYSTEM') and sys.executable.startswith('/'): - split_path = split_path_msys - else: - split_path = split_path_win32 -else: - split_path = split_path_unix - -split_path.__doc__ = """ -Splits a path by / or \\; do not confuse this function with with ``os.path.split`` - -:type path: string -:param path: path to split -:return: list of string -""" - -def check_dir(path): - """ - Ensures that a directory exists (similar to ``mkdir -p``). - - :type path: string - :param path: Path to directory - :raises: :py:class:`waflib.Errors.WafError` if the folder cannot be added. - """ - if not os.path.isdir(path): - try: - os.makedirs(path) - except OSError as e: - if not os.path.isdir(path): - raise Errors.WafError('Cannot create the folder %r' % path, ex=e) - -def check_exe(name, env=None): - """ - Ensures that a program exists - - :type name: string - :param name: path to the program - :param env: configuration object - :type env: :py:class:`waflib.ConfigSet.ConfigSet` - :return: path of the program or None - :raises: :py:class:`waflib.Errors.WafError` if the folder cannot be added. - """ - if not name: - raise ValueError('Cannot execute an empty string!') - def is_exe(fpath): - return os.path.isfile(fpath) and os.access(fpath, os.X_OK) - - fpath, fname = os.path.split(name) - if fpath and is_exe(name): - return os.path.abspath(name) - else: - env = env or os.environ - for path in env['PATH'].split(os.pathsep): - path = path.strip('"') - exe_file = os.path.join(path, name) - if is_exe(exe_file): - return os.path.abspath(exe_file) - return None - -def def_attrs(cls, **kw): - """ - Sets default attributes on a class instance - - :type cls: class - :param cls: the class to update the given attributes in. - :type kw: dict - :param kw: dictionary of attributes names and values. - """ - for k, v in kw.items(): - if not hasattr(cls, k): - setattr(cls, k, v) - -def quote_define_name(s): - """ - Converts a string into an identifier suitable for C defines. - - :type s: string - :param s: String to convert - :rtype: string - :return: Identifier suitable for C defines - """ - fu = re.sub('[^a-zA-Z0-9]', '_', s) - fu = re.sub('_+', '_', fu) - fu = fu.upper() - return fu - -re_sh = re.compile('\\s|\'|"') -""" -Regexp used for shell_escape below -""" - -def shell_escape(cmd): - """ - Escapes a command: - ['ls', '-l', 'arg space'] -> ls -l 'arg space' - """ - if isinstance(cmd, str): - return cmd - return ' '.join(repr(x) if re_sh.search(x) else x for x in cmd) - -def h_list(lst): - """ - Hashes lists of ordered data. - - Using hash(tup) for tuples would be much more efficient, - but Python now enforces hash randomization - - :param lst: list to hash - :type lst: list of strings - :return: hash of the list - """ - return md5(repr(lst).encode()).digest() - -if sys.hexversion < 0x3000000: - def h_list_python2(lst): - return md5(repr(lst)).digest() - h_list_python2.__doc__ = h_list.__doc__ - h_list = h_list_python2 - -def h_fun(fun): - """ - Hash functions - - :param fun: function to hash - :type fun: function - :return: hash of the function - :rtype: string or bytes - """ - try: - return fun.code - except AttributeError: - if isinstance(fun, functools.partial): - code = list(fun.args) - # The method items() provides a sequence of tuples where the first element - # represents an optional argument of the partial function application - # - # The sorting result outcome will be consistent because: - # 1. tuples are compared in order of their elements - # 2. optional argument namess are unique - code.extend(sorted(fun.keywords.items())) - code.append(h_fun(fun.func)) - fun.code = h_list(code) - return fun.code - try: - h = inspect.getsource(fun) - except EnvironmentError: - h = 'nocode' - try: - fun.code = h - except AttributeError: - pass - return h - -def h_cmd(ins): - """ - Hashes objects recursively - - :param ins: input object - :type ins: string or list or tuple or function - :rtype: string or bytes - """ - # this function is not meant to be particularly fast - if isinstance(ins, str): - # a command is either a string - ret = ins - elif isinstance(ins, list) or isinstance(ins, tuple): - # or a list of functions/strings - ret = str([h_cmd(x) for x in ins]) - else: - # or just a python function - ret = str(h_fun(ins)) - if sys.hexversion > 0x3000000: - ret = ret.encode('latin-1', 'xmlcharrefreplace') - return ret - -reg_subst = re.compile(r"(\\\\)|(\$\$)|\$\{([^}]+)\}") -def subst_vars(expr, params): - """ - Replaces ${VAR} with the value of VAR taken from a dict or a config set:: - - from waflib import Utils - s = Utils.subst_vars('${PREFIX}/bin', env) - - :type expr: string - :param expr: String to perform substitution on - :param params: Dictionary or config set to look up variable values. - """ - def repl_var(m): - if m.group(1): - return '\\' - if m.group(2): - return '$' - try: - # ConfigSet instances may contain lists - return params.get_flat(m.group(3)) - except AttributeError: - return params[m.group(3)] - # if you get a TypeError, it means that 'expr' is not a string... - # Utils.subst_vars(None, env) will not work - return reg_subst.sub(repl_var, expr) - -def destos_to_binfmt(key): - """ - Returns the binary format based on the unversioned platform name, - and defaults to ``elf`` if nothing is found. - - :param key: platform name - :type key: string - :return: string representing the binary format - """ - if key == 'darwin': - return 'mac-o' - elif key in ('win32', 'cygwin', 'uwin', 'msys'): - return 'pe' - return 'elf' - -def unversioned_sys_platform(): - """ - Returns the unversioned platform name. - Some Python platform names contain versions, that depend on - the build environment, e.g. linux2, freebsd6, etc. - This returns the name without the version number. Exceptions are - os2 and win32, which are returned verbatim. - - :rtype: string - :return: Unversioned platform name - """ - s = sys.platform - if s.startswith('java'): - # The real OS is hidden under the JVM. - from java.lang import System - s = System.getProperty('os.name') - # see http://lopica.sourceforge.net/os.html for a list of possible values - if s == 'Mac OS X': - return 'darwin' - elif s.startswith('Windows '): - return 'win32' - elif s == 'OS/2': - return 'os2' - elif s == 'HP-UX': - return 'hp-ux' - elif s in ('SunOS', 'Solaris'): - return 'sunos' - else: s = s.lower() - - # powerpc == darwin for our purposes - if s == 'powerpc': - return 'darwin' - if s == 'win32' or s == 'os2': - return s - if s == 'cli' and os.name == 'nt': - # ironpython is only on windows as far as we know - return 'win32' - return re.split(r'\d+$', s)[0] - -def nada(*k, **kw): - """ - Does nothing - - :return: None - """ - pass - -class Timer(object): - """ - Simple object for timing the execution of commands. - Its string representation is the duration:: - - from waflib.Utils import Timer - timer = Timer() - a_few_operations() - s = str(timer) - """ - def __init__(self): - self.start_time = self.now() - - def __str__(self): - delta = self.now() - self.start_time - if not isinstance(delta, datetime.timedelta): - delta = datetime.timedelta(seconds=delta) - days = delta.days - hours, rem = divmod(delta.seconds, 3600) - minutes, seconds = divmod(rem, 60) - seconds += delta.microseconds * 1e-6 - result = '' - if days: - result += '%dd' % days - if days or hours: - result += '%dh' % hours - if days or hours or minutes: - result += '%dm' % minutes - return '%s%.3fs' % (result, seconds) - - def now(self): - return datetime.datetime.utcnow() - - if hasattr(time, 'perf_counter'): - def now(self): - return time.perf_counter() - -def read_la_file(path): - """ - Reads property files, used by msvc.py - - :param path: file to read - :type path: string - """ - sp = re.compile(r'^([^=]+)=\'(.*)\'$') - dc = {} - for line in readf(path).splitlines(): - try: - _, left, right, _ = sp.split(line.strip()) - dc[left] = right - except ValueError: - pass - return dc - -def run_once(fun): - """ - Decorator: let a function cache its results, use like this:: - - @run_once - def foo(k): - return 345*2343 - - .. note:: in practice this can cause memory leaks, prefer a :py:class:`waflib.Utils.lru_cache` - - :param fun: function to execute - :type fun: function - :return: the return value of the function executed - """ - cache = {} - def wrap(*k): - try: - return cache[k] - except KeyError: - ret = fun(*k) - cache[k] = ret - return ret - wrap.__cache__ = cache - wrap.__name__ = fun.__name__ - return wrap - -def get_registry_app_path(key, filename): - """ - Returns the value of a registry key for an executable - - :type key: string - :type filename: list of string - """ - if not winreg: - return None - try: - result = winreg.QueryValue(key, "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\%s.exe" % filename[0]) - except OSError: - pass - else: - if os.path.isfile(result): - return result - -def lib64(): - """ - Guess the default ``/usr/lib`` extension for 64-bit applications - - :return: '64' or '' - :rtype: string - """ - # default settings for /usr/lib - if os.sep == '/': - if platform.architecture()[0] == '64bit': - if os.path.exists('/usr/lib64') and not os.path.exists('/usr/lib32'): - return '64' - return '' - -def sane_path(p): - # private function for the time being! - return os.path.abspath(os.path.expanduser(p)) - -process_pool = [] -""" -List of processes started to execute sub-process commands -""" - -def get_process(): - """ - Returns a process object that can execute commands as sub-processes - - :rtype: subprocess.Popen - """ - try: - return process_pool.pop() - except IndexError: - filepath = os.path.dirname(os.path.abspath(__file__)) + os.sep + 'processor.py' - cmd = [sys.executable, '-c', readf(filepath)] - return subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, bufsize=0, close_fds=not is_win32) - -def run_prefork_process(cmd, kwargs, cargs): - """ - Delegates process execution to a pre-forked process instance. - """ - if not 'env' in kwargs: - kwargs['env'] = dict(os.environ) - try: - obj = base64.b64encode(cPickle.dumps([cmd, kwargs, cargs])) - except (TypeError, AttributeError): - return run_regular_process(cmd, kwargs, cargs) - - proc = get_process() - if not proc: - return run_regular_process(cmd, kwargs, cargs) - - proc.stdin.write(obj) - proc.stdin.write('\n'.encode()) - proc.stdin.flush() - obj = proc.stdout.readline() - if not obj: - raise OSError('Preforked sub-process %r died' % proc.pid) - - process_pool.append(proc) - lst = cPickle.loads(base64.b64decode(obj)) - # Jython wrapper failures (bash/execvp) - assert len(lst) == 5 - ret, out, err, ex, trace = lst - if ex: - if ex == 'OSError': - raise OSError(trace) - elif ex == 'ValueError': - raise ValueError(trace) - elif ex == 'TimeoutExpired': - exc = TimeoutExpired(cmd, timeout=cargs['timeout'], output=out) - exc.stderr = err - raise exc - else: - raise Exception(trace) - return ret, out, err - -def lchown(path, user=-1, group=-1): - """ - Change the owner/group of a path, raises an OSError if the - ownership change fails. - - :param user: user to change - :type user: int or str - :param group: group to change - :type group: int or str - """ - if isinstance(user, str): - import pwd - entry = pwd.getpwnam(user) - if not entry: - raise OSError('Unknown user %r' % user) - user = entry[2] - if isinstance(group, str): - import grp - entry = grp.getgrnam(group) - if not entry: - raise OSError('Unknown group %r' % group) - group = entry[2] - return os.lchown(path, user, group) - -def run_regular_process(cmd, kwargs, cargs={}): - """ - Executes a subprocess command by using subprocess.Popen - """ - proc = subprocess.Popen(cmd, **kwargs) - if kwargs.get('stdout') or kwargs.get('stderr'): - try: - out, err = proc.communicate(**cargs) - except TimeoutExpired: - if kwargs.get('start_new_session') and hasattr(os, 'killpg'): - os.killpg(proc.pid, signal.SIGKILL) - else: - proc.kill() - out, err = proc.communicate() - exc = TimeoutExpired(proc.args, timeout=cargs['timeout'], output=out) - exc.stderr = err - raise exc - status = proc.returncode - else: - out, err = (None, None) - try: - status = proc.wait(**cargs) - except TimeoutExpired as e: - if kwargs.get('start_new_session') and hasattr(os, 'killpg'): - os.killpg(proc.pid, signal.SIGKILL) - else: - proc.kill() - proc.wait() - raise e - return status, out, err - -def run_process(cmd, kwargs, cargs={}): - """ - Executes a subprocess by using a pre-forked process when possible - or falling back to subprocess.Popen. See :py:func:`waflib.Utils.run_prefork_process` - and :py:func:`waflib.Utils.run_regular_process` - """ - if kwargs.get('stdout') and kwargs.get('stderr'): - return run_prefork_process(cmd, kwargs, cargs) - else: - return run_regular_process(cmd, kwargs, cargs) - -def alloc_process_pool(n, force=False): - """ - Allocates an amount of processes to the default pool so its size is at least *n*. - It is useful to call this function early so that the pre-forked - processes use as little memory as possible. - - :param n: pool size - :type n: integer - :param force: if True then *n* more processes are added to the existing pool - :type force: bool - """ - # mandatory on python2, unnecessary on python >= 3.2 - global run_process, get_process, alloc_process_pool - if not force: - n = max(n - len(process_pool), 0) - try: - lst = [get_process() for x in range(n)] - except OSError: - run_process = run_regular_process - get_process = alloc_process_pool = nada - else: - for x in lst: - process_pool.append(x) - -def atexit_pool(): - for k in process_pool: - try: - os.kill(k.pid, 9) - except OSError: - pass - else: - k.wait() -# see #1889 -if (sys.hexversion<0x207000f and not is_win32) or sys.hexversion>=0x306000f: - atexit.register(atexit_pool) - -if os.environ.get('WAF_NO_PREFORK') or sys.platform == 'cli' or not sys.executable: - run_process = run_regular_process - get_process = alloc_process_pool = nada - diff --git a/ldb-2.0.8/third_party/waf/waflib/__init__.py b/ldb-2.0.8/third_party/waf/waflib/__init__.py deleted file mode 100644 index 079df35..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2005-2018 (ita) diff --git a/ldb-2.0.8/third_party/waf/waflib/ansiterm.py b/ldb-2.0.8/third_party/waf/waflib/ansiterm.py deleted file mode 100644 index 027f0ad..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/ansiterm.py +++ /dev/null @@ -1,342 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 - -""" -Emulate a vt100 terminal in cmd.exe - -By wrapping sys.stdout / sys.stderr with Ansiterm, -the vt100 escape characters will be interpreted and -the equivalent actions will be performed with Win32 -console commands. - -""" - -import os, re, sys -from waflib import Utils - -wlock = Utils.threading.Lock() - -try: - from ctypes import Structure, windll, c_short, c_ushort, c_ulong, c_int, byref, c_wchar, POINTER, c_long -except ImportError: - - class AnsiTerm(object): - def __init__(self, stream): - self.stream = stream - try: - self.errors = self.stream.errors - except AttributeError: - pass # python 2.5 - self.encoding = self.stream.encoding - - def write(self, txt): - try: - wlock.acquire() - self.stream.write(txt) - self.stream.flush() - finally: - wlock.release() - - def fileno(self): - return self.stream.fileno() - - def flush(self): - self.stream.flush() - - def isatty(self): - return self.stream.isatty() -else: - - class COORD(Structure): - _fields_ = [("X", c_short), ("Y", c_short)] - - class SMALL_RECT(Structure): - _fields_ = [("Left", c_short), ("Top", c_short), ("Right", c_short), ("Bottom", c_short)] - - class CONSOLE_SCREEN_BUFFER_INFO(Structure): - _fields_ = [("Size", COORD), ("CursorPosition", COORD), ("Attributes", c_ushort), ("Window", SMALL_RECT), ("MaximumWindowSize", COORD)] - - class CONSOLE_CURSOR_INFO(Structure): - _fields_ = [('dwSize', c_ulong), ('bVisible', c_int)] - - try: - _type = unicode - except NameError: - _type = str - - to_int = lambda number, default: number and int(number) or default - - STD_OUTPUT_HANDLE = -11 - STD_ERROR_HANDLE = -12 - - windll.kernel32.GetStdHandle.argtypes = [c_ulong] - windll.kernel32.GetStdHandle.restype = c_ulong - windll.kernel32.GetConsoleScreenBufferInfo.argtypes = [c_ulong, POINTER(CONSOLE_SCREEN_BUFFER_INFO)] - windll.kernel32.GetConsoleScreenBufferInfo.restype = c_long - windll.kernel32.SetConsoleTextAttribute.argtypes = [c_ulong, c_ushort] - windll.kernel32.SetConsoleTextAttribute.restype = c_long - windll.kernel32.FillConsoleOutputCharacterW.argtypes = [c_ulong, c_wchar, c_ulong, POINTER(COORD), POINTER(c_ulong)] - windll.kernel32.FillConsoleOutputCharacterW.restype = c_long - windll.kernel32.FillConsoleOutputAttribute.argtypes = [c_ulong, c_ushort, c_ulong, POINTER(COORD), POINTER(c_ulong) ] - windll.kernel32.FillConsoleOutputAttribute.restype = c_long - windll.kernel32.SetConsoleCursorPosition.argtypes = [c_ulong, POINTER(COORD) ] - windll.kernel32.SetConsoleCursorPosition.restype = c_long - windll.kernel32.SetConsoleCursorInfo.argtypes = [c_ulong, POINTER(CONSOLE_CURSOR_INFO)] - windll.kernel32.SetConsoleCursorInfo.restype = c_long - - class AnsiTerm(object): - """ - emulate a vt100 terminal in cmd.exe - """ - def __init__(self, s): - self.stream = s - try: - self.errors = s.errors - except AttributeError: - pass # python2.5 - self.encoding = s.encoding - self.cursor_history = [] - - handle = (s.fileno() == 2) and STD_ERROR_HANDLE or STD_OUTPUT_HANDLE - self.hconsole = windll.kernel32.GetStdHandle(handle) - - self._sbinfo = CONSOLE_SCREEN_BUFFER_INFO() - - self._csinfo = CONSOLE_CURSOR_INFO() - windll.kernel32.GetConsoleCursorInfo(self.hconsole, byref(self._csinfo)) - - # just to double check that the console is usable - self._orig_sbinfo = CONSOLE_SCREEN_BUFFER_INFO() - r = windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole, byref(self._orig_sbinfo)) - self._isatty = r == 1 - - def screen_buffer_info(self): - """ - Updates self._sbinfo and returns it - """ - windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole, byref(self._sbinfo)) - return self._sbinfo - - def clear_line(self, param): - mode = param and int(param) or 0 - sbinfo = self.screen_buffer_info() - if mode == 1: # Clear from beginning of line to cursor position - line_start = COORD(0, sbinfo.CursorPosition.Y) - line_length = sbinfo.Size.X - elif mode == 2: # Clear entire line - line_start = COORD(sbinfo.CursorPosition.X, sbinfo.CursorPosition.Y) - line_length = sbinfo.Size.X - sbinfo.CursorPosition.X - else: # Clear from cursor position to end of line - line_start = sbinfo.CursorPosition - line_length = sbinfo.Size.X - sbinfo.CursorPosition.X - chars_written = c_ulong() - windll.kernel32.FillConsoleOutputCharacterW(self.hconsole, c_wchar(' '), line_length, line_start, byref(chars_written)) - windll.kernel32.FillConsoleOutputAttribute(self.hconsole, sbinfo.Attributes, line_length, line_start, byref(chars_written)) - - def clear_screen(self, param): - mode = to_int(param, 0) - sbinfo = self.screen_buffer_info() - if mode == 1: # Clear from beginning of screen to cursor position - clear_start = COORD(0, 0) - clear_length = sbinfo.CursorPosition.X * sbinfo.CursorPosition.Y - elif mode == 2: # Clear entire screen and return cursor to home - clear_start = COORD(0, 0) - clear_length = sbinfo.Size.X * sbinfo.Size.Y - windll.kernel32.SetConsoleCursorPosition(self.hconsole, clear_start) - else: # Clear from cursor position to end of screen - clear_start = sbinfo.CursorPosition - clear_length = ((sbinfo.Size.X - sbinfo.CursorPosition.X) + sbinfo.Size.X * (sbinfo.Size.Y - sbinfo.CursorPosition.Y)) - chars_written = c_ulong() - windll.kernel32.FillConsoleOutputCharacterW(self.hconsole, c_wchar(' '), clear_length, clear_start, byref(chars_written)) - windll.kernel32.FillConsoleOutputAttribute(self.hconsole, sbinfo.Attributes, clear_length, clear_start, byref(chars_written)) - - def push_cursor(self, param): - sbinfo = self.screen_buffer_info() - self.cursor_history.append(sbinfo.CursorPosition) - - def pop_cursor(self, param): - if self.cursor_history: - old_pos = self.cursor_history.pop() - windll.kernel32.SetConsoleCursorPosition(self.hconsole, old_pos) - - def set_cursor(self, param): - y, sep, x = param.partition(';') - x = to_int(x, 1) - 1 - y = to_int(y, 1) - 1 - sbinfo = self.screen_buffer_info() - new_pos = COORD( - min(max(0, x), sbinfo.Size.X), - min(max(0, y), sbinfo.Size.Y) - ) - windll.kernel32.SetConsoleCursorPosition(self.hconsole, new_pos) - - def set_column(self, param): - x = to_int(param, 1) - 1 - sbinfo = self.screen_buffer_info() - new_pos = COORD( - min(max(0, x), sbinfo.Size.X), - sbinfo.CursorPosition.Y - ) - windll.kernel32.SetConsoleCursorPosition(self.hconsole, new_pos) - - def move_cursor(self, x_offset=0, y_offset=0): - sbinfo = self.screen_buffer_info() - new_pos = COORD( - min(max(0, sbinfo.CursorPosition.X + x_offset), sbinfo.Size.X), - min(max(0, sbinfo.CursorPosition.Y + y_offset), sbinfo.Size.Y) - ) - windll.kernel32.SetConsoleCursorPosition(self.hconsole, new_pos) - - def move_up(self, param): - self.move_cursor(y_offset = -to_int(param, 1)) - - def move_down(self, param): - self.move_cursor(y_offset = to_int(param, 1)) - - def move_left(self, param): - self.move_cursor(x_offset = -to_int(param, 1)) - - def move_right(self, param): - self.move_cursor(x_offset = to_int(param, 1)) - - def next_line(self, param): - sbinfo = self.screen_buffer_info() - self.move_cursor( - x_offset = -sbinfo.CursorPosition.X, - y_offset = to_int(param, 1) - ) - - def prev_line(self, param): - sbinfo = self.screen_buffer_info() - self.move_cursor( - x_offset = -sbinfo.CursorPosition.X, - y_offset = -to_int(param, 1) - ) - - def rgb2bgr(self, c): - return ((c&1) << 2) | (c&2) | ((c&4)>>2) - - def set_color(self, param): - cols = param.split(';') - sbinfo = self.screen_buffer_info() - attr = sbinfo.Attributes - for c in cols: - c = to_int(c, 0) - if 29 < c < 38: # fgcolor - attr = (attr & 0xfff0) | self.rgb2bgr(c - 30) - elif 39 < c < 48: # bgcolor - attr = (attr & 0xff0f) | (self.rgb2bgr(c - 40) << 4) - elif c == 0: # reset - attr = self._orig_sbinfo.Attributes - elif c == 1: # strong - attr |= 0x08 - elif c == 4: # blink not available -> bg intensity - attr |= 0x80 - elif c == 7: # negative - attr = (attr & 0xff88) | ((attr & 0x70) >> 4) | ((attr & 0x07) << 4) - - windll.kernel32.SetConsoleTextAttribute(self.hconsole, attr) - - def show_cursor(self,param): - self._csinfo.bVisible = 1 - windll.kernel32.SetConsoleCursorInfo(self.hconsole, byref(self._csinfo)) - - def hide_cursor(self,param): - self._csinfo.bVisible = 0 - windll.kernel32.SetConsoleCursorInfo(self.hconsole, byref(self._csinfo)) - - ansi_command_table = { - 'A': move_up, - 'B': move_down, - 'C': move_right, - 'D': move_left, - 'E': next_line, - 'F': prev_line, - 'G': set_column, - 'H': set_cursor, - 'f': set_cursor, - 'J': clear_screen, - 'K': clear_line, - 'h': show_cursor, - 'l': hide_cursor, - 'm': set_color, - 's': push_cursor, - 'u': pop_cursor, - } - # Match either the escape sequence or text not containing escape sequence - ansi_tokens = re.compile(r'(?:\x1b\[([0-9?;]*)([a-zA-Z])|([^\x1b]+))') - def write(self, text): - try: - wlock.acquire() - if self._isatty: - for param, cmd, txt in self.ansi_tokens.findall(text): - if cmd: - cmd_func = self.ansi_command_table.get(cmd) - if cmd_func: - cmd_func(self, param) - else: - self.writeconsole(txt) - else: - # no support for colors in the console, just output the text: - # eclipse or msys may be able to interpret the escape sequences - self.stream.write(text) - finally: - wlock.release() - - def writeconsole(self, txt): - chars_written = c_ulong() - writeconsole = windll.kernel32.WriteConsoleA - if isinstance(txt, _type): - writeconsole = windll.kernel32.WriteConsoleW - - # MSDN says that there is a shared buffer of 64 KB for the console - # writes. Attempt to not get ERROR_NOT_ENOUGH_MEMORY, see waf issue #746 - done = 0 - todo = len(txt) - chunk = 32<<10 - while todo != 0: - doing = min(chunk, todo) - buf = txt[done:done+doing] - r = writeconsole(self.hconsole, buf, doing, byref(chars_written), None) - if r == 0: - chunk >>= 1 - continue - done += doing - todo -= doing - - - def fileno(self): - return self.stream.fileno() - - def flush(self): - pass - - def isatty(self): - return self._isatty - - if sys.stdout.isatty() or sys.stderr.isatty(): - handle = sys.stdout.isatty() and STD_OUTPUT_HANDLE or STD_ERROR_HANDLE - console = windll.kernel32.GetStdHandle(handle) - sbinfo = CONSOLE_SCREEN_BUFFER_INFO() - def get_term_cols(): - windll.kernel32.GetConsoleScreenBufferInfo(console, byref(sbinfo)) - # Issue 1401 - the progress bar cannot reach the last character - return sbinfo.Size.X - 1 - -# just try and see -try: - import struct, fcntl, termios -except ImportError: - pass -else: - if (sys.stdout.isatty() or sys.stderr.isatty()) and os.environ.get('TERM', '') not in ('dumb', 'emacs'): - FD = sys.stdout.isatty() and sys.stdout.fileno() or sys.stderr.fileno() - def fun(): - return struct.unpack("HHHH", fcntl.ioctl(FD, termios.TIOCGWINSZ, struct.pack("HHHH", 0, 0, 0, 0)))[1] - try: - fun() - except Exception as e: - pass - else: - get_term_cols = fun - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/__init__.py b/ldb-2.0.8/third_party/waf/waflib/extras/__init__.py deleted file mode 100644 index c8a3c34..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2005-2010 (ita) diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/batched_cc.py b/ldb-2.0.8/third_party/waf/waflib/extras/batched_cc.py deleted file mode 100644 index aad2872..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/batched_cc.py +++ /dev/null @@ -1,173 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2006-2015 (ita) - -""" -Instead of compiling object files one by one, c/c++ compilers are often able to compile at once: -cc -c ../file1.c ../file2.c ../file3.c - -Files are output on the directory where the compiler is called, and dependencies are more difficult -to track (do not run the command on all source files if only one file changes) -As such, we do as if the files were compiled one by one, but no command is actually run: -replace each cc/cpp Task by a TaskSlave. A new task called TaskMaster collects the -signatures from each slave and finds out the command-line to run. - -Just import this module to start using it: -def build(bld): - bld.load('batched_cc') - -Note that this is provided as an example, unity builds are recommended -for best performance results (fewer tasks and fewer jobs to execute). -See waflib/extras/unity.py. -""" - -from waflib import Task, Utils -from waflib.TaskGen import extension, feature, after_method -from waflib.Tools import c, cxx - -MAX_BATCH = 50 - -c_str = '${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${tsk.batch_incpaths()} ${DEFINES_ST:DEFINES} -c ${SRCLST} ${CXX_TGT_F_BATCHED} ${CPPFLAGS}' -c_fun, _ = Task.compile_fun_noshell(c_str) - -cxx_str = '${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${tsk.batch_incpaths()} ${DEFINES_ST:DEFINES} -c ${SRCLST} ${CXX_TGT_F_BATCHED} ${CPPFLAGS}' -cxx_fun, _ = Task.compile_fun_noshell(cxx_str) - -count = 70000 -class batch(Task.Task): - color = 'PINK' - - after = ['c', 'cxx'] - before = ['cprogram', 'cshlib', 'cstlib', 'cxxprogram', 'cxxshlib', 'cxxstlib'] - - def uid(self): - return Utils.h_list([Task.Task.uid(self), self.generator.idx, self.generator.path.abspath(), self.generator.target]) - - def __str__(self): - return 'Batch compilation for %d slaves' % len(self.slaves) - - def __init__(self, *k, **kw): - Task.Task.__init__(self, *k, **kw) - self.slaves = [] - self.inputs = [] - self.hasrun = 0 - - global count - count += 1 - self.idx = count - - def add_slave(self, slave): - self.slaves.append(slave) - self.set_run_after(slave) - - def runnable_status(self): - for t in self.run_after: - if not t.hasrun: - return Task.ASK_LATER - - for t in self.slaves: - #if t.executed: - if t.hasrun != Task.SKIPPED: - return Task.RUN_ME - - return Task.SKIP_ME - - def get_cwd(self): - return self.slaves[0].outputs[0].parent - - def batch_incpaths(self): - st = self.env.CPPPATH_ST - return [st % node.abspath() for node in self.generator.includes_nodes] - - def run(self): - self.outputs = [] - - srclst = [] - slaves = [] - for t in self.slaves: - if t.hasrun != Task.SKIPPED: - slaves.append(t) - srclst.append(t.inputs[0].abspath()) - - self.env.SRCLST = srclst - - if self.slaves[0].__class__.__name__ == 'c': - ret = c_fun(self) - else: - ret = cxx_fun(self) - - if ret: - return ret - - for t in slaves: - t.old_post_run() - -def hook(cls_type): - def n_hook(self, node): - - ext = '.obj' if self.env.CC_NAME == 'msvc' else '.o' - name = node.name - k = name.rfind('.') - if k >= 0: - basename = name[:k] + ext - else: - basename = name + ext - - outdir = node.parent.get_bld().make_node('%d' % self.idx) - outdir.mkdir() - out = outdir.find_or_declare(basename) - - task = self.create_task(cls_type, node, out) - - try: - self.compiled_tasks.append(task) - except AttributeError: - self.compiled_tasks = [task] - - if not getattr(self, 'masters', None): - self.masters = {} - self.allmasters = [] - - def fix_path(tsk): - if self.env.CC_NAME == 'msvc': - tsk.env.append_unique('CXX_TGT_F_BATCHED', '/Fo%s\\' % outdir.abspath()) - - if not node.parent in self.masters: - m = self.masters[node.parent] = self.master = self.create_task('batch') - fix_path(m) - self.allmasters.append(m) - else: - m = self.masters[node.parent] - if len(m.slaves) > MAX_BATCH: - m = self.masters[node.parent] = self.master = self.create_task('batch') - fix_path(m) - self.allmasters.append(m) - m.add_slave(task) - return task - return n_hook - -extension('.c')(hook('c')) -extension('.cpp','.cc','.cxx','.C','.c++')(hook('cxx')) - -@feature('cprogram', 'cshlib', 'cstaticlib', 'cxxprogram', 'cxxshlib', 'cxxstlib') -@after_method('apply_link') -def link_after_masters(self): - if getattr(self, 'allmasters', None): - for m in self.allmasters: - self.link_task.set_run_after(m) - -# Modify the c and cxx task classes - in theory it would be best to -# create subclasses and to re-map the c/c++ extensions -for x in ('c', 'cxx'): - t = Task.classes[x] - def run(self): - pass - - def post_run(self): - pass - - setattr(t, 'oldrun', getattr(t, 'run', None)) - setattr(t, 'run', run) - setattr(t, 'old_post_run', t.post_run) - setattr(t, 'post_run', post_run) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/biber.py b/ldb-2.0.8/third_party/waf/waflib/extras/biber.py deleted file mode 100644 index fd9db4e..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/biber.py +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2011 (ita) - -""" -Latex processing using "biber" -""" - -import os -from waflib import Task, Logs - -from waflib.Tools import tex as texmodule - -class tex(texmodule.tex): - biber_fun, _ = Task.compile_fun('${BIBER} ${BIBERFLAGS} ${SRCFILE}',shell=False) - biber_fun.__doc__ = """ - Execute the program **biber** - """ - - def bibfile(self): - return None - - def bibunits(self): - self.env.env = {} - self.env.env.update(os.environ) - self.env.env.update({'BIBINPUTS': self.texinputs(), 'BSTINPUTS': self.texinputs()}) - self.env.SRCFILE = self.aux_nodes[0].name[:-4] - - if not self.env['PROMPT_LATEX']: - self.env.append_unique('BIBERFLAGS', '--quiet') - - path = self.aux_nodes[0].abspath()[:-4] + '.bcf' - if os.path.isfile(path): - Logs.warn('calling biber') - self.check_status('error when calling biber, check %s.blg for errors' % (self.env.SRCFILE), self.biber_fun()) - else: - super(tex, self).bibfile() - super(tex, self).bibunits() - -class latex(tex): - texfun, vars = Task.compile_fun('${LATEX} ${LATEXFLAGS} ${SRCFILE}', shell=False) -class pdflatex(tex): - texfun, vars = Task.compile_fun('${PDFLATEX} ${PDFLATEXFLAGS} ${SRCFILE}', shell=False) -class xelatex(tex): - texfun, vars = Task.compile_fun('${XELATEX} ${XELATEXFLAGS} ${SRCFILE}', shell=False) - -def configure(self): - """ - Almost the same as in tex.py, but try to detect 'biber' - """ - v = self.env - for p in ' biber tex latex pdflatex xelatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps'.split(): - try: - self.find_program(p, var=p.upper()) - except self.errors.ConfigurationError: - pass - v['DVIPSFLAGS'] = '-Ppdf' - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/bjam.py b/ldb-2.0.8/third_party/waf/waflib/extras/bjam.py deleted file mode 100644 index 8e04d3a..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/bjam.py +++ /dev/null @@ -1,128 +0,0 @@ -#! /usr/bin/env python -# per rosengren 2011 - -from os import sep, readlink -from waflib import Logs -from waflib.TaskGen import feature, after_method -from waflib.Task import Task, always_run - -def options(opt): - grp = opt.add_option_group('Bjam Options') - grp.add_option('--bjam_src', default=None, help='You can find it in /tools/jam/src') - grp.add_option('--bjam_uname', default='linuxx86_64', help='bjam is built in /bin./bjam') - grp.add_option('--bjam_config', default=None) - grp.add_option('--bjam_toolset', default=None) - -def configure(cnf): - if not cnf.env.BJAM_SRC: - cnf.env.BJAM_SRC = cnf.options.bjam_src - if not cnf.env.BJAM_UNAME: - cnf.env.BJAM_UNAME = cnf.options.bjam_uname - try: - cnf.find_program('bjam', path_list=[ - cnf.env.BJAM_SRC + sep + 'bin.' + cnf.env.BJAM_UNAME - ]) - except Exception: - cnf.env.BJAM = None - if not cnf.env.BJAM_CONFIG: - cnf.env.BJAM_CONFIG = cnf.options.bjam_config - if not cnf.env.BJAM_TOOLSET: - cnf.env.BJAM_TOOLSET = cnf.options.bjam_toolset - -@feature('bjam') -@after_method('process_rule') -def process_bjam(self): - if not self.bld.env.BJAM: - self.create_task('bjam_creator') - self.create_task('bjam_build') - self.create_task('bjam_installer') - if getattr(self, 'always', False): - always_run(bjam_creator) - always_run(bjam_build) - always_run(bjam_installer) - -class bjam_creator(Task): - ext_out = 'bjam_exe' - vars=['BJAM_SRC', 'BJAM_UNAME'] - def run(self): - env = self.env - gen = self.generator - bjam = gen.bld.root.find_dir(env.BJAM_SRC) - if not bjam: - Logs.error('Can not find bjam source') - return -1 - bjam_exe_relpath = 'bin.' + env.BJAM_UNAME + '/bjam' - bjam_exe = bjam.find_resource(bjam_exe_relpath) - if bjam_exe: - env.BJAM = bjam_exe.srcpath() - return 0 - bjam_cmd = ['./build.sh'] - Logs.debug('runner: ' + bjam.srcpath() + '> ' + str(bjam_cmd)) - result = self.exec_command(bjam_cmd, cwd=bjam.srcpath()) - if not result == 0: - Logs.error('bjam failed') - return -1 - bjam_exe = bjam.find_resource(bjam_exe_relpath) - if bjam_exe: - env.BJAM = bjam_exe.srcpath() - return 0 - Logs.error('bjam failed') - return -1 - -class bjam_build(Task): - ext_in = 'bjam_exe' - ext_out = 'install' - vars = ['BJAM_TOOLSET'] - def run(self): - env = self.env - gen = self.generator - path = gen.path - bld = gen.bld - if hasattr(gen, 'root'): - build_root = path.find_node(gen.root) - else: - build_root = path - jam = bld.srcnode.find_resource(env.BJAM_CONFIG) - if jam: - Logs.debug('bjam: Using jam configuration from ' + jam.srcpath()) - jam_rel = jam.relpath_gen(build_root) - else: - Logs.warn('No build configuration in build_config/user-config.jam. Using default') - jam_rel = None - bjam_exe = bld.srcnode.find_node(env.BJAM) - if not bjam_exe: - Logs.error('env.BJAM is not set') - return -1 - bjam_exe_rel = bjam_exe.relpath_gen(build_root) - cmd = ([bjam_exe_rel] + - (['--user-config=' + jam_rel] if jam_rel else []) + - ['--stagedir=' + path.get_bld().path_from(build_root)] + - ['--debug-configuration'] + - ['--with-' + lib for lib in self.generator.target] + - (['toolset=' + env.BJAM_TOOLSET] if env.BJAM_TOOLSET else []) + - ['link=' + 'shared'] + - ['variant=' + 'release'] - ) - Logs.debug('runner: ' + build_root.srcpath() + '> ' + str(cmd)) - ret = self.exec_command(cmd, cwd=build_root.srcpath()) - if ret != 0: - return ret - self.set_outputs(path.get_bld().ant_glob('lib/*') + path.get_bld().ant_glob('bin/*')) - return 0 - -class bjam_installer(Task): - ext_in = 'install' - def run(self): - gen = self.generator - path = gen.path - for idir, pat in (('${LIBDIR}', 'lib/*'), ('${BINDIR}', 'bin/*')): - files = [] - for n in path.get_bld().ant_glob(pat): - try: - t = readlink(n.srcpath()) - gen.bld.symlink_as(sep.join([idir, n.name]), t, postpone=False) - except OSError: - files.append(n) - gen.bld.install_files(idir, files, postpone=False) - return 0 - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/blender.py b/ldb-2.0.8/third_party/waf/waflib/extras/blender.py deleted file mode 100644 index e5efc28..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/blender.py +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Michal Proszek, 2014 (poxip) - -""" -Detect the version of Blender, path -and install the extension: - - def options(opt): - opt.load('blender') - def configure(cnf): - cnf.load('blender') - def build(bld): - bld(name='io_mesh_raw', - feature='blender', - files=['file1.py', 'file2.py'] - ) -If name variable is empty, files are installed in scripts/addons, otherwise scripts/addons/name -Use ./waf configure --system to set the installation directory to system path -""" -import os -import re -from getpass import getuser - -from waflib import Utils -from waflib.TaskGen import feature -from waflib.Configure import conf - -def options(opt): - opt.add_option( - '-s', '--system', - dest='directory_system', - default=False, - action='store_true', - help='determines installation directory (default: user)' - ) - -@conf -def find_blender(ctx): - '''Return version number of blender, if not exist return None''' - blender = ctx.find_program('blender') - output = ctx.cmd_and_log(blender + ['--version']) - m = re.search(r'Blender\s*((\d+(\.|))*)', output) - if not m: - ctx.fatal('Could not retrieve blender version') - - try: - blender_version = m.group(1) - except IndexError: - ctx.fatal('Could not retrieve blender version') - - ctx.env['BLENDER_VERSION'] = blender_version - return blender - -@conf -def configure_paths(ctx): - """Setup blender paths""" - # Get the username - user = getuser() - _platform = Utils.unversioned_sys_platform() - config_path = {'user': '', 'system': ''} - if _platform.startswith('linux'): - config_path['user'] = '/home/%s/.config/blender/' % user - config_path['system'] = '/usr/share/blender/' - elif _platform == 'darwin': - # MAC OS X - config_path['user'] = \ - '/Users/%s/Library/Application Support/Blender/' % user - config_path['system'] = '/Library/Application Support/Blender/' - elif Utils.is_win32: - # Windows - appdata_path = ctx.getenv('APPDATA').replace('\\', '/') - homedrive = ctx.getenv('HOMEDRIVE').replace('\\', '/') - - config_path['user'] = '%s/Blender Foundation/Blender/' % appdata_path - config_path['system'] = \ - '%sAll Users/AppData/Roaming/Blender Foundation/Blender/' % homedrive - else: - ctx.fatal( - 'Unsupported platform. ' - 'Available platforms: Linux, OSX, MS-Windows.' - ) - - blender_version = ctx.env['BLENDER_VERSION'] - - config_path['user'] += blender_version + '/' - config_path['system'] += blender_version + '/' - - ctx.env['BLENDER_CONFIG_DIR'] = os.path.abspath(config_path['user']) - if ctx.options.directory_system: - ctx.env['BLENDER_CONFIG_DIR'] = config_path['system'] - - ctx.env['BLENDER_ADDONS_DIR'] = os.path.join( - ctx.env['BLENDER_CONFIG_DIR'], 'scripts/addons' - ) - Utils.check_dir(ctx.env['BLENDER_ADDONS_DIR']) - -def configure(ctx): - ctx.find_blender() - ctx.configure_paths() - -@feature('blender_list') -def blender(self): - # Two ways to install a blender extension: as a module or just .py files - dest_dir = os.path.join(self.env.BLENDER_ADDONS_DIR, self.get_name()) - Utils.check_dir(dest_dir) - self.add_install_files(install_to=dest_dir, install_from=getattr(self, 'files', '.')) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/boo.py b/ldb-2.0.8/third_party/waf/waflib/extras/boo.py deleted file mode 100644 index 06623d4..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/boo.py +++ /dev/null @@ -1,81 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Yannick LM 2011 - -""" -Support for the boo programming language, for example:: - - bld(features = "boo", # necessary feature - source = "src.boo", # list of boo files - gen = "world.dll", # target - type = "library", # library/exe ("-target:xyz" flag) - name = "world" # necessary if the target is referenced by 'use' - ) -""" - -from waflib import Task -from waflib.Configure import conf -from waflib.TaskGen import feature, after_method, before_method, extension - -@extension('.boo') -def boo_hook(self, node): - # Nothing here yet ... - # TODO filter the non-boo source files in 'apply_booc' and remove this method - pass - -@feature('boo') -@before_method('process_source') -def apply_booc(self): - """Create a booc task """ - src_nodes = self.to_nodes(self.source) - out_node = self.path.find_or_declare(self.gen) - - self.boo_task = self.create_task('booc', src_nodes, [out_node]) - - # Set variables used by the 'booc' task - self.boo_task.env.OUT = '-o:%s' % out_node.abspath() - - # type is "exe" by default - type = getattr(self, "type", "exe") - self.boo_task.env.BOO_TARGET_TYPE = "-target:%s" % type - -@feature('boo') -@after_method('apply_boo') -def use_boo(self): - """" - boo applications honor the **use** keyword:: - """ - dep_names = self.to_list(getattr(self, 'use', [])) - for dep_name in dep_names: - dep_task_gen = self.bld.get_tgen_by_name(dep_name) - if not dep_task_gen: - continue - dep_task_gen.post() - dep_task = getattr(dep_task_gen, 'boo_task', None) - if not dep_task: - # Try a cs task: - dep_task = getattr(dep_task_gen, 'cs_task', None) - if not dep_task: - # Try a link task: - dep_task = getattr(dep_task, 'link_task', None) - if not dep_task: - # Abort ... - continue - self.boo_task.set_run_after(dep_task) # order - self.boo_task.dep_nodes.extend(dep_task.outputs) # dependency - self.boo_task.env.append_value('BOO_FLAGS', '-reference:%s' % dep_task.outputs[0].abspath()) - -class booc(Task.Task): - """Compiles .boo files """ - color = 'YELLOW' - run_str = '${BOOC} ${BOO_FLAGS} ${BOO_TARGET_TYPE} ${OUT} ${SRC}' - -@conf -def check_booc(self): - self.find_program('booc', 'BOOC') - self.env.BOO_FLAGS = ['-nologo'] - -def configure(self): - """Check that booc is available """ - self.check_booc() - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/boost.py b/ldb-2.0.8/third_party/waf/waflib/extras/boost.py deleted file mode 100644 index c2aaaa9..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/boost.py +++ /dev/null @@ -1,525 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# -# partially based on boost.py written by Gernot Vormayr -# written by Ruediger Sonderfeld , 2008 -# modified by Bjoern Michaelsen, 2008 -# modified by Luca Fossati, 2008 -# rewritten for waf 1.5.1, Thomas Nagy, 2008 -# rewritten for waf 1.6.2, Sylvain Rouquette, 2011 - -''' - -This is an extra tool, not bundled with the default waf binary. -To add the boost tool to the waf file: -$ ./waf-light --tools=compat15,boost - or, if you have waf >= 1.6.2 -$ ./waf update --files=boost - -When using this tool, the wscript will look like: - - def options(opt): - opt.load('compiler_cxx boost') - - def configure(conf): - conf.load('compiler_cxx boost') - conf.check_boost(lib='system filesystem') - - def build(bld): - bld(source='main.cpp', target='app', use='BOOST') - -Options are generated, in order to specify the location of boost includes/libraries. -The `check_boost` configuration function allows to specify the used boost libraries. -It can also provide default arguments to the --boost-mt command-line arguments. -Everything will be packaged together in a BOOST component that you can use. - -When using MSVC, a lot of compilation flags need to match your BOOST build configuration: - - you may have to add /EHsc to your CXXFLAGS or define boost::throw_exception if BOOST_NO_EXCEPTIONS is defined. - Errors: C4530 - - boost libraries will try to be smart and use the (pretty but often not useful) auto-linking feature of MSVC - So before calling `conf.check_boost` you might want to disabling by adding - conf.env.DEFINES_BOOST += ['BOOST_ALL_NO_LIB'] - Errors: - - boost might also be compiled with /MT, which links the runtime statically. - If you have problems with redefined symbols, - self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB'] - self.env['CXXFLAGS_%s' % var] += ['/MD', '/EHsc'] -Passing `--boost-linkage_autodetect` might help ensuring having a correct linkage in some basic cases. - -''' - -import sys -import re -from waflib import Utils, Logs, Errors -from waflib.Configure import conf -from waflib.TaskGen import feature, after_method - -BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib'] -BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include'] -BOOST_VERSION_FILE = 'boost/version.hpp' -BOOST_VERSION_CODE = ''' -#include -#include -int main() { std::cout << BOOST_LIB_VERSION << ":" << BOOST_VERSION << std::endl; } -''' - -BOOST_ERROR_CODE = ''' -#include -int main() { boost::system::error_code c; } -''' - -PTHREAD_CODE = ''' -#include -static void* f(void*) { return 0; } -int main() { - pthread_t th; - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_create(&th, &attr, &f, 0); - pthread_join(th, 0); - pthread_cleanup_push(0, 0); - pthread_cleanup_pop(0); - pthread_attr_destroy(&attr); -} -''' - -BOOST_THREAD_CODE = ''' -#include -int main() { boost::thread t; } -''' - -BOOST_LOG_CODE = ''' -#include -#include -#include -int main() { - using namespace boost::log; - add_common_attributes(); - add_console_log(std::clog, keywords::format = "%Message%"); - BOOST_LOG_TRIVIAL(debug) << "log is working" << std::endl; -} -''' - -# toolsets from {boost_dir}/tools/build/v2/tools/common.jam -PLATFORM = Utils.unversioned_sys_platform() -detect_intel = lambda env: (PLATFORM == 'win32') and 'iw' or 'il' -detect_clang = lambda env: (PLATFORM == 'darwin') and 'clang-darwin' or 'clang' -detect_mingw = lambda env: (re.search('MinGW', env.CXX[0])) and 'mgw' or 'gcc' -BOOST_TOOLSETS = { - 'borland': 'bcb', - 'clang': detect_clang, - 'como': 'como', - 'cw': 'cw', - 'darwin': 'xgcc', - 'edg': 'edg', - 'g++': detect_mingw, - 'gcc': detect_mingw, - 'icpc': detect_intel, - 'intel': detect_intel, - 'kcc': 'kcc', - 'kylix': 'bck', - 'mipspro': 'mp', - 'mingw': 'mgw', - 'msvc': 'vc', - 'qcc': 'qcc', - 'sun': 'sw', - 'sunc++': 'sw', - 'tru64cxx': 'tru', - 'vacpp': 'xlc' -} - - -def options(opt): - opt = opt.add_option_group('Boost Options') - opt.add_option('--boost-includes', type='string', - default='', dest='boost_includes', - help='''path to the directory where the boost includes are, - e.g., /path/to/boost_1_55_0/stage/include''') - opt.add_option('--boost-libs', type='string', - default='', dest='boost_libs', - help='''path to the directory where the boost libs are, - e.g., path/to/boost_1_55_0/stage/lib''') - opt.add_option('--boost-mt', action='store_true', - default=False, dest='boost_mt', - help='select multi-threaded libraries') - opt.add_option('--boost-abi', type='string', default='', dest='boost_abi', - help='''select libraries with tags (gd for debug, static is automatically added), - see doc Boost, Getting Started, chapter 6.1''') - opt.add_option('--boost-linkage_autodetect', action="store_true", dest='boost_linkage_autodetect', - help="auto-detect boost linkage options (don't get used to it / might break other stuff)") - opt.add_option('--boost-toolset', type='string', - default='', dest='boost_toolset', - help='force a toolset e.g. msvc, vc90, \ - gcc, mingw, mgw45 (default: auto)') - py_version = '%d%d' % (sys.version_info[0], sys.version_info[1]) - opt.add_option('--boost-python', type='string', - default=py_version, dest='boost_python', - help='select the lib python with this version \ - (default: %s)' % py_version) - - -@conf -def __boost_get_version_file(self, d): - if not d: - return None - dnode = self.root.find_dir(d) - if dnode: - return dnode.find_node(BOOST_VERSION_FILE) - return None - -@conf -def boost_get_version(self, d): - """silently retrieve the boost version number""" - node = self.__boost_get_version_file(d) - if node: - try: - txt = node.read() - except EnvironmentError: - Logs.error("Could not read the file %r", node.abspath()) - else: - re_but1 = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.+)"', re.M) - m1 = re_but1.search(txt) - re_but2 = re.compile('^#define\\s+BOOST_VERSION\\s+(\\d+)', re.M) - m2 = re_but2.search(txt) - if m1 and m2: - return (m1.group(1), m2.group(1)) - return self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[d], execute=True, define_ret=True).split(":") - -@conf -def boost_get_includes(self, *k, **kw): - includes = k and k[0] or kw.get('includes') - if includes and self.__boost_get_version_file(includes): - return includes - for d in self.environ.get('INCLUDE', '').split(';') + BOOST_INCLUDES: - if self.__boost_get_version_file(d): - return d - if includes: - self.end_msg('headers not found in %s' % includes) - self.fatal('The configuration failed') - else: - self.end_msg('headers not found, please provide a --boost-includes argument (see help)') - self.fatal('The configuration failed') - - -@conf -def boost_get_toolset(self, cc): - toolset = cc - if not cc: - build_platform = Utils.unversioned_sys_platform() - if build_platform in BOOST_TOOLSETS: - cc = build_platform - else: - cc = self.env.CXX_NAME - if cc in BOOST_TOOLSETS: - toolset = BOOST_TOOLSETS[cc] - return isinstance(toolset, str) and toolset or toolset(self.env) - - -@conf -def __boost_get_libs_path(self, *k, **kw): - ''' return the lib path and all the files in it ''' - if 'files' in kw: - return self.root.find_dir('.'), Utils.to_list(kw['files']) - libs = k and k[0] or kw.get('libs') - if libs: - path = self.root.find_dir(libs) - files = path.ant_glob('*boost_*') - if not libs or not files: - for d in self.environ.get('LIB', '').split(';') + BOOST_LIBS: - if not d: - continue - path = self.root.find_dir(d) - if path: - files = path.ant_glob('*boost_*') - if files: - break - path = self.root.find_dir(d + '64') - if path: - files = path.ant_glob('*boost_*') - if files: - break - if not path: - if libs: - self.end_msg('libs not found in %s' % libs) - self.fatal('The configuration failed') - else: - self.end_msg('libs not found, please provide a --boost-libs argument (see help)') - self.fatal('The configuration failed') - - self.to_log('Found the boost path in %r with the libraries:' % path) - for x in files: - self.to_log(' %r' % x) - return path, files - -@conf -def boost_get_libs(self, *k, **kw): - ''' - return the lib path and the required libs - according to the parameters - ''' - path, files = self.__boost_get_libs_path(**kw) - files = sorted(files, key=lambda f: (len(f.name), f.name), reverse=True) - toolset = self.boost_get_toolset(kw.get('toolset', '')) - toolset_pat = '(-%s[0-9]{0,3})' % toolset - version = '-%s' % self.env.BOOST_VERSION - - def find_lib(re_lib, files): - for file in files: - if re_lib.search(file.name): - self.to_log('Found boost lib %s' % file) - return file - return None - - def format_lib_name(name): - if name.startswith('lib') and self.env.CC_NAME != 'msvc': - name = name[3:] - return name[:name.rfind('.')] - - def match_libs(lib_names, is_static): - libs = [] - lib_names = Utils.to_list(lib_names) - if not lib_names: - return libs - t = [] - if kw.get('mt', False): - t.append('-mt') - if kw.get('abi'): - t.append('%s%s' % (is_static and '-s' or '-', kw['abi'])) - elif is_static: - t.append('-s') - tags_pat = t and ''.join(t) or '' - ext = is_static and self.env.cxxstlib_PATTERN or self.env.cxxshlib_PATTERN - ext = ext.partition('%s')[2] # remove '%s' or 'lib%s' from PATTERN - - for lib in lib_names: - if lib == 'python': - # for instance, with python='27', - # accepts '-py27', '-py2', '27', '-2.7' and '2' - # but will reject '-py3', '-py26', '26' and '3' - tags = '({0})?((-py{2})|(-py{1}(?=[^0-9]))|({2})|(-{1}.{3})|({1}(?=[^0-9]))|(?=[^0-9])(?!-py))'.format(tags_pat, kw['python'][0], kw['python'], kw['python'][1]) - else: - tags = tags_pat - # Trying libraries, from most strict match to least one - for pattern in ['boost_%s%s%s%s%s$' % (lib, toolset_pat, tags, version, ext), - 'boost_%s%s%s%s$' % (lib, tags, version, ext), - # Give up trying to find the right version - 'boost_%s%s%s%s$' % (lib, toolset_pat, tags, ext), - 'boost_%s%s%s$' % (lib, tags, ext), - 'boost_%s%s$' % (lib, ext), - 'boost_%s' % lib]: - self.to_log('Trying pattern %s' % pattern) - file = find_lib(re.compile(pattern), files) - if file: - libs.append(format_lib_name(file.name)) - break - else: - self.end_msg('lib %s not found in %s' % (lib, path.abspath())) - self.fatal('The configuration failed') - return libs - - return path.abspath(), match_libs(kw.get('lib'), False), match_libs(kw.get('stlib'), True) - -@conf -def _check_pthread_flag(self, *k, **kw): - ''' - Computes which flags should be added to CXXFLAGS and LINKFLAGS to compile in multi-threading mode - - Yes, we *need* to put the -pthread thing in CPPFLAGS because with GCC3, - boost/thread.hpp will trigger a #error if -pthread isn't used: - boost/config/requires_threads.hpp:47:5: #error "Compiler threading support - is not turned on. Please set the correct command line options for - threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)" - - Based on _BOOST_PTHREAD_FLAG(): https://github.com/tsuna/boost.m4/blob/master/build-aux/boost.m4 - ''' - - var = kw.get('uselib_store', 'BOOST') - - self.start_msg('Checking the flags needed to use pthreads') - - # The ordering *is* (sometimes) important. Some notes on the - # individual items follow: - # (none): in case threads are in libc; should be tried before -Kthread and - # other compiler flags to prevent continual compiler warnings - # -lpthreads: AIX (must check this before -lpthread) - # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) - # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) - # -llthread: LinuxThreads port on FreeBSD (also preferred to -pthread) - # -pthread: GNU Linux/GCC (kernel threads), BSD/GCC (userland threads) - # -pthreads: Solaris/GCC - # -mthreads: MinGW32/GCC, Lynx/GCC - # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it - # doesn't hurt to check since this sometimes defines pthreads too; - # also defines -D_REENTRANT) - # ... -mt is also the pthreads flag for HP/aCC - # -lpthread: GNU Linux, etc. - # --thread-safe: KAI C++ - if Utils.unversioned_sys_platform() == "sunos": - # On Solaris (at least, for some versions), libc contains stubbed - # (non-functional) versions of the pthreads routines, so link-based - # tests will erroneously succeed. (We need to link with -pthreads/-mt/ - # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather - # a function called by this macro, so we could check for that, but - # who knows whether they'll stub that too in a future libc.) So, - # we'll just look for -pthreads and -lpthread first: - boost_pthread_flags = ["-pthreads", "-lpthread", "-mt", "-pthread"] - else: - boost_pthread_flags = ["", "-lpthreads", "-Kthread", "-kthread", "-llthread", "-pthread", - "-pthreads", "-mthreads", "-lpthread", "--thread-safe", "-mt"] - - for boost_pthread_flag in boost_pthread_flags: - try: - self.env.stash() - self.env.append_value('CXXFLAGS_%s' % var, boost_pthread_flag) - self.env.append_value('LINKFLAGS_%s' % var, boost_pthread_flag) - self.check_cxx(code=PTHREAD_CODE, msg=None, use=var, execute=False) - - self.end_msg(boost_pthread_flag) - return - except self.errors.ConfigurationError: - self.env.revert() - self.end_msg('None') - -@conf -def check_boost(self, *k, **kw): - """ - Initialize boost libraries to be used. - - Keywords: you can pass the same parameters as with the command line (without "--boost-"). - Note that the command line has the priority, and should preferably be used. - """ - if not self.env['CXX']: - self.fatal('load a c++ compiler first, conf.load("compiler_cxx")') - - params = { - 'lib': k and k[0] or kw.get('lib'), - 'stlib': kw.get('stlib') - } - for key, value in self.options.__dict__.items(): - if not key.startswith('boost_'): - continue - key = key[len('boost_'):] - params[key] = value and value or kw.get(key, '') - - var = kw.get('uselib_store', 'BOOST') - - self.find_program('dpkg-architecture', var='DPKG_ARCHITECTURE', mandatory=False) - if self.env.DPKG_ARCHITECTURE: - deb_host_multiarch = self.cmd_and_log([self.env.DPKG_ARCHITECTURE[0], '-qDEB_HOST_MULTIARCH']) - BOOST_LIBS.insert(0, '/usr/lib/%s' % deb_host_multiarch.strip()) - - self.start_msg('Checking boost includes') - self.env['INCLUDES_%s' % var] = inc = self.boost_get_includes(**params) - versions = self.boost_get_version(inc) - self.env.BOOST_VERSION = versions[0] - self.env.BOOST_VERSION_NUMBER = int(versions[1]) - self.end_msg("%d.%d.%d" % (int(versions[1]) / 100000, - int(versions[1]) / 100 % 1000, - int(versions[1]) % 100)) - if Logs.verbose: - Logs.pprint('CYAN', ' path : %s' % self.env['INCLUDES_%s' % var]) - - if not params['lib'] and not params['stlib']: - return - if 'static' in kw or 'static' in params: - Logs.warn('boost: static parameter is deprecated, use stlib instead.') - self.start_msg('Checking boost libs') - path, libs, stlibs = self.boost_get_libs(**params) - self.env['LIBPATH_%s' % var] = [path] - self.env['STLIBPATH_%s' % var] = [path] - self.env['LIB_%s' % var] = libs - self.env['STLIB_%s' % var] = stlibs - self.end_msg('ok') - if Logs.verbose: - Logs.pprint('CYAN', ' path : %s' % path) - Logs.pprint('CYAN', ' shared libs : %s' % libs) - Logs.pprint('CYAN', ' static libs : %s' % stlibs) - - def has_shlib(lib): - return params['lib'] and lib in params['lib'] - def has_stlib(lib): - return params['stlib'] and lib in params['stlib'] - def has_lib(lib): - return has_shlib(lib) or has_stlib(lib) - if has_lib('thread'): - # not inside try_link to make check visible in the output - self._check_pthread_flag(k, kw) - - def try_link(): - if has_lib('system'): - self.check_cxx(fragment=BOOST_ERROR_CODE, use=var, execute=False) - if has_lib('thread'): - self.check_cxx(fragment=BOOST_THREAD_CODE, use=var, execute=False) - if has_lib('log'): - if not has_lib('thread'): - self.env['DEFINES_%s' % var] += ['BOOST_LOG_NO_THREADS'] - if has_shlib('log'): - self.env['DEFINES_%s' % var] += ['BOOST_LOG_DYN_LINK'] - self.check_cxx(fragment=BOOST_LOG_CODE, use=var, execute=False) - - if params.get('linkage_autodetect', False): - self.start_msg("Attempting to detect boost linkage flags") - toolset = self.boost_get_toolset(kw.get('toolset', '')) - if toolset in ('vc',): - # disable auto-linking feature, causing error LNK1181 - # because the code wants to be linked against - self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB'] - - # if no dlls are present, we guess the .lib files are not stubs - has_dlls = False - for x in Utils.listdir(path): - if x.endswith(self.env.cxxshlib_PATTERN % ''): - has_dlls = True - break - if not has_dlls: - self.env['STLIBPATH_%s' % var] = [path] - self.env['STLIB_%s' % var] = libs - del self.env['LIB_%s' % var] - del self.env['LIBPATH_%s' % var] - - # we attempt to play with some known-to-work CXXFLAGS combinations - for cxxflags in (['/MD', '/EHsc'], []): - self.env.stash() - self.env["CXXFLAGS_%s" % var] += cxxflags - try: - try_link() - except Errors.ConfigurationError as e: - self.env.revert() - exc = e - else: - self.end_msg("ok: winning cxxflags combination: %s" % (self.env["CXXFLAGS_%s" % var])) - exc = None - self.env.commit() - break - - if exc is not None: - self.end_msg("Could not auto-detect boost linking flags combination, you may report it to boost.py author", ex=exc) - self.fatal('The configuration failed') - else: - self.end_msg("Boost linkage flags auto-detection not implemented (needed ?) for this toolchain") - self.fatal('The configuration failed') - else: - self.start_msg('Checking for boost linkage') - try: - try_link() - except Errors.ConfigurationError as e: - self.end_msg("Could not link against boost libraries using supplied options") - self.fatal('The configuration failed') - self.end_msg('ok') - - -@feature('cxx') -@after_method('apply_link') -def install_boost(self): - if install_boost.done or not Utils.is_win32 or not self.bld.cmd.startswith('install'): - return - install_boost.done = True - inst_to = getattr(self, 'install_path', '${BINDIR}') - for lib in self.env.LIB_BOOST: - try: - file = self.bld.find_file(self.env.cxxshlib_PATTERN % lib, self.env.LIBPATH_BOOST) - self.add_install_files(install_to=inst_to, install_from=self.bld.root.find_node(file)) - except: - continue -install_boost.done = False - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/build_file_tracker.py b/ldb-2.0.8/third_party/waf/waflib/extras/build_file_tracker.py deleted file mode 100644 index c4f26fd..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/build_file_tracker.py +++ /dev/null @@ -1,28 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2015 - -""" -Force files to depend on the timestamps of those located in the build directory. You may -want to use this to force partial rebuilds, see playground/track_output_files/ for a working example. - -Note that there is a variety of ways to implement this, one may want use timestamps on source files too for example, -or one may want to hash the files in the source directory only under certain conditions (md5_tstamp tool) -or to hash the file in the build directory with its timestamp -""" - -import os -from waflib import Node, Utils - -def get_bld_sig(self): - if not self.is_bld() or self.ctx.bldnode is self.ctx.srcnode: - return Utils.h_file(self.abspath()) - - try: - # add the creation time to the signature - return self.sig + str(os.stat(self.abspath()).st_mtime) - except AttributeError: - return None - -Node.Node.get_bld_sig = get_bld_sig - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/build_logs.py b/ldb-2.0.8/third_party/waf/waflib/extras/build_logs.py deleted file mode 100644 index cdf8ed0..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/build_logs.py +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2013 (ita) - -""" -A system for recording all outputs to a log file. Just add the following to your wscript file:: - - def init(ctx): - ctx.load('build_logs') -""" - -import atexit, sys, time, os, shutil, threading -from waflib import ansiterm, Logs, Context - -# adding the logs under the build/ directory will clash with the clean/ command -try: - up = os.path.dirname(Context.g_module.__file__) -except AttributeError: - up = '.' -LOGFILE = os.path.join(up, 'logs', time.strftime('%Y_%m_%d_%H_%M.log')) - -wlock = threading.Lock() -class log_to_file(object): - def __init__(self, stream, fileobj, filename): - self.stream = stream - self.encoding = self.stream.encoding - self.fileobj = fileobj - self.filename = filename - self.is_valid = True - def replace_colors(self, data): - for x in Logs.colors_lst.values(): - if isinstance(x, str): - data = data.replace(x, '') - return data - def write(self, data): - try: - wlock.acquire() - self.stream.write(data) - self.stream.flush() - if self.is_valid: - self.fileobj.write(self.replace_colors(data)) - finally: - wlock.release() - def fileno(self): - return self.stream.fileno() - def flush(self): - self.stream.flush() - if self.is_valid: - self.fileobj.flush() - def isatty(self): - return self.stream.isatty() - -def init(ctx): - global LOGFILE - filename = os.path.abspath(LOGFILE) - try: - os.makedirs(os.path.dirname(os.path.abspath(filename))) - except OSError: - pass - - if hasattr(os, 'O_NOINHERIT'): - fd = os.open(LOGFILE, os.O_CREAT | os.O_TRUNC | os.O_WRONLY | os.O_NOINHERIT) - fileobj = os.fdopen(fd, 'w') - else: - fileobj = open(LOGFILE, 'w') - old_stderr = sys.stderr - - # sys.stdout has already been replaced, so __stdout__ will be faster - #sys.stdout = log_to_file(sys.stdout, fileobj, filename) - #sys.stderr = log_to_file(sys.stderr, fileobj, filename) - def wrap(stream): - if stream.isatty(): - return ansiterm.AnsiTerm(stream) - return stream - sys.stdout = log_to_file(wrap(sys.__stdout__), fileobj, filename) - sys.stderr = log_to_file(wrap(sys.__stderr__), fileobj, filename) - - # now mess with the logging module... - for x in Logs.log.handlers: - try: - stream = x.stream - except AttributeError: - pass - else: - if id(stream) == id(old_stderr): - x.stream = sys.stderr - -def exit_cleanup(): - try: - fileobj = sys.stdout.fileobj - except AttributeError: - pass - else: - sys.stdout.is_valid = False - sys.stderr.is_valid = False - fileobj.close() - filename = sys.stdout.filename - - Logs.info('Output logged to %r', filename) - - # then copy the log file to "latest.log" if possible - up = os.path.dirname(os.path.abspath(filename)) - try: - shutil.copy(filename, os.path.join(up, 'latest.log')) - except OSError: - # this may fail on windows due to processes spawned - pass - -atexit.register(exit_cleanup) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/buildcopy.py b/ldb-2.0.8/third_party/waf/waflib/extras/buildcopy.py deleted file mode 100644 index eaff7e6..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/buildcopy.py +++ /dev/null @@ -1,85 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Calle Rosenquist, 2017 (xbreak) -""" -Create task that copies source files to the associated build node. -This is useful to e.g. construct a complete Python package so it can be unit tested -without installation. - -Source files to be copied can be specified either in `buildcopy_source` attribute, or -`source` attribute. If both are specified `buildcopy_source` has priority. - -Examples:: - - def build(bld): - bld(name = 'bar', - features = 'py buildcopy', - source = bld.path.ant_glob('src/bar/*.py')) - - bld(name = 'py baz', - features = 'buildcopy', - buildcopy_source = bld.path.ant_glob('src/bar/*.py') + ['src/bar/resource.txt']) - -""" -import os, shutil -from waflib import Errors, Task, TaskGen, Utils, Node, Logs - -@TaskGen.before_method('process_source') -@TaskGen.feature('buildcopy') -def make_buildcopy(self): - """ - Creates the buildcopy task. - """ - def to_src_nodes(lst): - """Find file nodes only in src, TaskGen.to_nodes will not work for this since it gives - preference to nodes in build. - """ - if isinstance(lst, Node.Node): - if not lst.is_src(): - raise Errors.WafError('buildcopy: node %s is not in src'%lst) - if not os.path.isfile(lst.abspath()): - raise Errors.WafError('buildcopy: Cannot copy directory %s (unsupported action)'%lst) - return lst - - if isinstance(lst, str): - lst = [x for x in Utils.split_path(lst) if x and x != '.'] - - node = self.bld.path.get_src().search_node(lst) - if node: - if not os.path.isfile(node.abspath()): - raise Errors.WafError('buildcopy: Cannot copy directory %s (unsupported action)'%node) - return node - - node = self.bld.path.get_src().find_node(lst) - if node: - if not os.path.isfile(node.abspath()): - raise Errors.WafError('buildcopy: Cannot copy directory %s (unsupported action)'%node) - return node - raise Errors.WafError('buildcopy: File not found in src: %s'%os.path.join(*lst)) - - nodes = [ to_src_nodes(n) for n in getattr(self, 'buildcopy_source', getattr(self, 'source', [])) ] - if not nodes: - Logs.warn('buildcopy: No source files provided to buildcopy in %s (set `buildcopy_source` or `source`)', - self) - return - node_pairs = [(n, n.get_bld()) for n in nodes] - self.create_task('buildcopy', [n[0] for n in node_pairs], [n[1] for n in node_pairs], node_pairs=node_pairs) - -class buildcopy(Task.Task): - """ - Copy for each pair `n` in `node_pairs`: n[0] -> n[1]. - - Attribute `node_pairs` should contain a list of tuples describing source and target: - - node_pairs = [(in, out), ...] - - """ - color = 'PINK' - - def keyword(self): - return 'Copying' - - def run(self): - for f,t in self.node_pairs: - t.parent.mkdir() - shutil.copy2(f.abspath(), t.abspath()) diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/c_bgxlc.py b/ldb-2.0.8/third_party/waf/waflib/extras/c_bgxlc.py deleted file mode 100644 index 6e3eaf7..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/c_bgxlc.py +++ /dev/null @@ -1,32 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# harald at klimachs.de - -""" -IBM XL Compiler for Blue Gene -""" - -from waflib.Tools import ccroot,ar -from waflib.Configure import conf - -from waflib.Tools import xlc # method xlc_common_flags -from waflib.Tools.compiler_c import c_compiler -c_compiler['linux'].append('c_bgxlc') - -@conf -def find_bgxlc(conf): - cc = conf.find_program(['bgxlc_r','bgxlc'], var='CC') - conf.get_xlc_version(cc) - conf.env.CC = cc - conf.env.CC_NAME = 'bgxlc' - -def configure(conf): - conf.find_bgxlc() - conf.find_ar() - conf.xlc_common_flags() - conf.env.LINKFLAGS_cshlib = ['-G','-Wl,-bexpfull'] - conf.env.LINKFLAGS_cprogram = [] - conf.cc_load_tools() - conf.cc_add_flags() - conf.link_add_flags() - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/c_dumbpreproc.py b/ldb-2.0.8/third_party/waf/waflib/extras/c_dumbpreproc.py deleted file mode 100644 index ce9e1a4..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/c_dumbpreproc.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2006-2010 (ita) - -""" -Dumb C/C++ preprocessor for finding dependencies - -It will look at all include files it can find after removing the comments, so the following -will always add the dependency on both "a.h" and "b.h":: - - #include "a.h" - #ifdef B - #include "b.h" - #endif - int main() { - return 0; - } - -To use:: - - def configure(conf): - conf.load('compiler_c') - conf.load('c_dumbpreproc') -""" - -import re -from waflib.Tools import c_preproc - -re_inc = re.compile( - '^[ \t]*(#|%:)[ \t]*(include)[ \t]*[<"](.*)[>"]\r*$', - re.IGNORECASE | re.MULTILINE) - -def lines_includes(node): - code = node.read() - if c_preproc.use_trigraphs: - for (a, b) in c_preproc.trig_def: - code = code.split(a).join(b) - code = c_preproc.re_nl.sub('', code) - code = c_preproc.re_cpp.sub(c_preproc.repl, code) - return [(m.group(2), m.group(3)) for m in re.finditer(re_inc, code)] - -parser = c_preproc.c_parser -class dumb_parser(parser): - def addlines(self, node): - if node in self.nodes[:-1]: - return - self.currentnode_stack.append(node.parent) - - # Avoid reading the same files again - try: - lines = self.parse_cache[node] - except KeyError: - lines = self.parse_cache[node] = lines_includes(node) - - self.lines = lines + [(c_preproc.POPFILE, '')] + self.lines - - def start(self, node, env): - try: - self.parse_cache = node.ctx.parse_cache - except AttributeError: - self.parse_cache = node.ctx.parse_cache = {} - - self.addlines(node) - while self.lines: - (x, y) = self.lines.pop(0) - if x == c_preproc.POPFILE: - self.currentnode_stack.pop() - continue - self.tryfind(y) - -c_preproc.c_parser = dumb_parser - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/c_emscripten.py b/ldb-2.0.8/third_party/waf/waflib/extras/c_emscripten.py deleted file mode 100644 index e1ac494..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/c_emscripten.py +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 vi:ts=4:noexpandtab - -import subprocess, shlex, sys - -from waflib.Tools import ccroot, gcc, gxx -from waflib.Configure import conf -from waflib.TaskGen import after_method, feature - -from waflib.Tools.compiler_c import c_compiler -from waflib.Tools.compiler_cxx import cxx_compiler - -for supported_os in ('linux', 'darwin', 'gnu', 'aix'): - c_compiler[supported_os].append('c_emscripten') - cxx_compiler[supported_os].append('c_emscripten') - - -@conf -def get_emscripten_version(conf, cc): - """ - Emscripten doesn't support processing '-' like clang/gcc - """ - - dummy = conf.cachedir.parent.make_node("waf-emscripten.c") - dummy.write("") - cmd = cc + ['-dM', '-E', '-x', 'c', dummy.abspath()] - env = conf.env.env or None - try: - p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) - out = p.communicate()[0] - except Exception as e: - conf.fatal('Could not determine emscripten version %r: %s' % (cmd, e)) - - if not isinstance(out, str): - out = out.decode(sys.stdout.encoding or 'latin-1') - - k = {} - out = out.splitlines() - for line in out: - lst = shlex.split(line) - if len(lst)>2: - key = lst[1] - val = lst[2] - k[key] = val - - if not ('__clang__' in k and 'EMSCRIPTEN' in k): - conf.fatal('Could not determine the emscripten compiler version.') - - conf.env.DEST_OS = 'generic' - conf.env.DEST_BINFMT = 'elf' - conf.env.DEST_CPU = 'asm-js' - conf.env.CC_VERSION = (k['__clang_major__'], k['__clang_minor__'], k['__clang_patchlevel__']) - return k - -@conf -def find_emscripten(conf): - cc = conf.find_program(['emcc'], var='CC') - conf.get_emscripten_version(cc) - conf.env.CC = cc - conf.env.CC_NAME = 'emscripten' - cxx = conf.find_program(['em++'], var='CXX') - conf.env.CXX = cxx - conf.env.CXX_NAME = 'emscripten' - conf.find_program(['emar'], var='AR') - -def configure(conf): - conf.find_emscripten() - conf.find_ar() - conf.gcc_common_flags() - conf.gxx_common_flags() - conf.cc_load_tools() - conf.cc_add_flags() - conf.cxx_load_tools() - conf.cxx_add_flags() - conf.link_add_flags() - conf.env.ARFLAGS = ['rcs'] - conf.env.cshlib_PATTERN = '%s.js' - conf.env.cxxshlib_PATTERN = '%s.js' - conf.env.cstlib_PATTERN = '%s.a' - conf.env.cxxstlib_PATTERN = '%s.a' - conf.env.cprogram_PATTERN = '%s.html' - conf.env.cxxprogram_PATTERN = '%s.html' - conf.env.CXX_TGT_F = ['-c', '-o', ''] - conf.env.CC_TGT_F = ['-c', '-o', ''] - conf.env.CXXLNK_TGT_F = ['-o', ''] - conf.env.CCLNK_TGT_F = ['-o', ''] - conf.env.append_value('LINKFLAGS',['-Wl,--enable-auto-import']) diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/c_nec.py b/ldb-2.0.8/third_party/waf/waflib/extras/c_nec.py deleted file mode 100644 index 96bfae4..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/c_nec.py +++ /dev/null @@ -1,74 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# harald at klimachs.de - -""" -NEC SX Compiler for SX vector systems -""" - -import re -from waflib import Utils -from waflib.Tools import ccroot,ar -from waflib.Configure import conf - -from waflib.Tools import xlc # method xlc_common_flags -from waflib.Tools.compiler_c import c_compiler -c_compiler['linux'].append('c_nec') - -@conf -def find_sxc(conf): - cc = conf.find_program(['sxcc'], var='CC') - conf.get_sxc_version(cc) - conf.env.CC = cc - conf.env.CC_NAME = 'sxcc' - -@conf -def get_sxc_version(conf, fc): - version_re = re.compile(r"C\+\+/SX\s*Version\s*(?P\d*)\.(?P\d*)", re.I).search - cmd = fc + ['-V'] - p = Utils.subprocess.Popen(cmd, stdin=False, stdout=Utils.subprocess.PIPE, stderr=Utils.subprocess.PIPE, env=None) - out, err = p.communicate() - - if out: - match = version_re(out) - else: - match = version_re(err) - if not match: - conf.fatal('Could not determine the NEC C compiler version.') - k = match.groupdict() - conf.env['C_VERSION'] = (k['major'], k['minor']) - -@conf -def sxc_common_flags(conf): - v=conf.env - v['CC_SRC_F']=[] - v['CC_TGT_F']=['-c','-o'] - if not v['LINK_CC']: - v['LINK_CC']=v['CC'] - v['CCLNK_SRC_F']=[] - v['CCLNK_TGT_F']=['-o'] - v['CPPPATH_ST']='-I%s' - v['DEFINES_ST']='-D%s' - v['LIB_ST']='-l%s' - v['LIBPATH_ST']='-L%s' - v['STLIB_ST']='-l%s' - v['STLIBPATH_ST']='-L%s' - v['RPATH_ST']='' - v['SONAME_ST']=[] - v['SHLIB_MARKER']=[] - v['STLIB_MARKER']=[] - v['LINKFLAGS_cprogram']=[''] - v['cprogram_PATTERN']='%s' - v['CFLAGS_cshlib']=['-fPIC'] - v['LINKFLAGS_cshlib']=[''] - v['cshlib_PATTERN']='lib%s.so' - v['LINKFLAGS_cstlib']=[] - v['cstlib_PATTERN']='lib%s.a' - -def configure(conf): - conf.find_sxc() - conf.find_program('sxar',VAR='AR') - conf.sxc_common_flags() - conf.cc_load_tools() - conf.cc_add_flags() - conf.link_add_flags() diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/cabal.py b/ldb-2.0.8/third_party/waf/waflib/extras/cabal.py deleted file mode 100644 index e10a0d1..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/cabal.py +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Anton Feldmann, 2012 -# "Base for cabal" - -from waflib import Task, Utils -from waflib.TaskGen import extension -from waflib.Utils import threading -from shutil import rmtree - -lock = threading.Lock() -registering = False - -def configure(self): - self.find_program('cabal', var='CABAL') - self.find_program('ghc-pkg', var='GHCPKG') - pkgconfd = self.bldnode.abspath() + '/package.conf.d' - self.env.PREFIX = self.bldnode.abspath() + '/dist' - self.env.PKGCONFD = pkgconfd - if self.root.find_node(pkgconfd + '/package.cache'): - self.msg('Using existing package database', pkgconfd, color='CYAN') - else: - pkgdir = self.root.find_dir(pkgconfd) - if pkgdir: - self.msg('Deleting corrupt package database', pkgdir.abspath(), color ='RED') - rmtree(pkgdir.abspath()) - pkgdir = None - - self.cmd_and_log(self.env.GHCPKG + ['init', pkgconfd]) - self.msg('Created package database', pkgconfd, color = 'YELLOW' if pkgdir else 'GREEN') - -@extension('.cabal') -def process_cabal(self, node): - out_dir_node = self.bld.root.find_dir(self.bld.out_dir) - package_node = node.change_ext('.package') - package_node = out_dir_node.find_or_declare(package_node.name) - build_node = node.parent.get_bld() - build_path = build_node.abspath() - config_node = build_node.find_or_declare('setup-config') - inplace_node = build_node.find_or_declare('package.conf.inplace') - - config_task = self.create_task('cabal_configure', node) - config_task.cwd = node.parent.abspath() - config_task.depends_on = getattr(self, 'depends_on', '') - config_task.build_path = build_path - config_task.set_outputs(config_node) - - build_task = self.create_task('cabal_build', config_node) - build_task.cwd = node.parent.abspath() - build_task.build_path = build_path - build_task.set_outputs(inplace_node) - - copy_task = self.create_task('cabal_copy', inplace_node) - copy_task.cwd = node.parent.abspath() - copy_task.depends_on = getattr(self, 'depends_on', '') - copy_task.build_path = build_path - - last_task = copy_task - task_list = [config_task, build_task, copy_task] - - if (getattr(self, 'register', False)): - register_task = self.create_task('cabal_register', inplace_node) - register_task.cwd = node.parent.abspath() - register_task.set_run_after(copy_task) - register_task.build_path = build_path - - pkgreg_task = self.create_task('ghcpkg_register', inplace_node) - pkgreg_task.cwd = node.parent.abspath() - pkgreg_task.set_run_after(register_task) - pkgreg_task.build_path = build_path - - last_task = pkgreg_task - task_list += [register_task, pkgreg_task] - - touch_task = self.create_task('cabal_touch', inplace_node) - touch_task.set_run_after(last_task) - touch_task.set_outputs(package_node) - touch_task.build_path = build_path - - task_list += [touch_task] - - return task_list - -def get_all_src_deps(node): - hs_deps = node.ant_glob('**/*.hs') - hsc_deps = node.ant_glob('**/*.hsc') - lhs_deps = node.ant_glob('**/*.lhs') - c_deps = node.ant_glob('**/*.c') - cpp_deps = node.ant_glob('**/*.cpp') - proto_deps = node.ant_glob('**/*.proto') - return sum([hs_deps, hsc_deps, lhs_deps, c_deps, cpp_deps, proto_deps], []) - -class Cabal(Task.Task): - def scan(self): - return (get_all_src_deps(self.generator.path), ()) - -class cabal_configure(Cabal): - run_str = '${CABAL} configure -v0 --prefix=${PREFIX} --global --user --package-db=${PKGCONFD} --builddir=${tsk.build_path}' - shell = True - - def scan(self): - out_node = self.generator.bld.root.find_dir(self.generator.bld.out_dir) - deps = [out_node.find_or_declare(dep).change_ext('.package') for dep in Utils.to_list(self.depends_on)] - return (deps, ()) - -class cabal_build(Cabal): - run_str = '${CABAL} build -v1 --builddir=${tsk.build_path}/' - shell = True - -class cabal_copy(Cabal): - run_str = '${CABAL} copy -v0 --builddir=${tsk.build_path}' - shell = True - -class cabal_register(Cabal): - run_str = '${CABAL} register -v0 --gen-pkg-config=${tsk.build_path}/pkg.config --builddir=${tsk.build_path}' - shell = True - -class ghcpkg_register(Cabal): - run_str = '${GHCPKG} update -v0 --global --user --package-conf=${PKGCONFD} ${tsk.build_path}/pkg.config' - shell = True - - def runnable_status(self): - global lock, registering - - val = False - lock.acquire() - val = registering - lock.release() - - if val: - return Task.ASK_LATER - - ret = Task.Task.runnable_status(self) - if ret == Task.RUN_ME: - lock.acquire() - registering = True - lock.release() - - return ret - - def post_run(self): - global lock, registering - - lock.acquire() - registering = False - lock.release() - - return Task.Task.post_run(self) - -class cabal_touch(Cabal): - run_str = 'touch ${TGT}' - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/cfg_altoptions.py b/ldb-2.0.8/third_party/waf/waflib/extras/cfg_altoptions.py deleted file mode 100644 index 47b1189..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/cfg_altoptions.py +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Tool to extend c_config.check_cfg() - -__author__ = __maintainer__ = "Jérôme Carretero " -__copyright__ = "Jérôme Carretero, 2014" - -""" - -This tool allows to work around the absence of ``*-config`` programs -on systems, by keeping the same clean configuration syntax but inferring -values or permitting their modification via the options interface. - -Note that pkg-config can also support setting ``PKG_CONFIG_PATH``, -so you can put custom files in a folder containing new .pc files. -This tool could also be implemented by taking advantage of this fact. - -Usage:: - - def options(opt): - opt.load('c_config_alt') - opt.add_package_option('package') - - def configure(cfg): - conf.load('c_config_alt') - conf.check_cfg(...) - -Known issues: - -- Behavior with different build contexts... - -""" - -import os -import functools -from waflib import Configure, Options, Errors - -def name_to_dest(x): - return x.lower().replace('-', '_') - - -def options(opt): - def x(opt, param): - dest = name_to_dest(param) - gr = opt.get_option_group("configure options") - gr.add_option('--%s-root' % dest, - help="path containing include and lib subfolders for %s" \ - % param, - ) - - opt.add_package_option = functools.partial(x, opt) - - -check_cfg_old = getattr(Configure.ConfigurationContext, 'check_cfg') - -@Configure.conf -def check_cfg(conf, *k, **kw): - if k: - lst = k[0].split() - kw['package'] = lst[0] - kw['args'] = ' '.join(lst[1:]) - - if not 'package' in kw: - return check_cfg_old(conf, **kw) - - package = kw['package'] - - package_lo = name_to_dest(package) - package_hi = package.upper().replace('-', '_') # TODO FIXME - package_hi = kw.get('uselib_store', package_hi) - - def check_folder(path, name): - try: - assert os.path.isdir(path) - except AssertionError: - raise Errors.ConfigurationError( - "%s_%s (%s) is not a folder!" \ - % (package_lo, name, path)) - return path - - root = getattr(Options.options, '%s_root' % package_lo, None) - - if root is None: - return check_cfg_old(conf, **kw) - else: - def add_manual_var(k, v): - conf.start_msg('Adding for %s a manual var' % (package)) - conf.env["%s_%s" % (k, package_hi)] = v - conf.end_msg("%s = %s" % (k, v)) - - - check_folder(root, 'root') - - pkg_inc = check_folder(os.path.join(root, "include"), 'inc') - add_manual_var('INCLUDES', [pkg_inc]) - pkg_lib = check_folder(os.path.join(root, "lib"), 'libpath') - add_manual_var('LIBPATH', [pkg_lib]) - add_manual_var('LIB', [package]) - - for x in kw.get('manual_deps', []): - for k, v in sorted(conf.env.get_merged_dict().items()): - if k.endswith('_%s' % x): - k = k.replace('_%s' % x, '') - conf.start_msg('Adding for %s a manual dep' \ - %(package)) - conf.env["%s_%s" % (k, package_hi)] += v - conf.end_msg('%s += %s' % (k, v)) - - return True - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/clang_compilation_database.py b/ldb-2.0.8/third_party/waf/waflib/extras/clang_compilation_database.py deleted file mode 100644 index 4d9b5e2..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/clang_compilation_database.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Christoph Koke, 2013 - -""" -Writes the c and cpp compile commands into build/compile_commands.json -see http://clang.llvm.org/docs/JSONCompilationDatabase.html - -Usage: - - def configure(conf): - conf.load('compiler_cxx') - ... - conf.load('clang_compilation_database') -""" - -import sys, os, json, shlex, pipes -from waflib import Logs, TaskGen, Task - -Task.Task.keep_last_cmd = True - -@TaskGen.feature('c', 'cxx') -@TaskGen.after_method('process_use') -def collect_compilation_db_tasks(self): - "Add a compilation database entry for compiled tasks" - try: - clang_db = self.bld.clang_compilation_database_tasks - except AttributeError: - clang_db = self.bld.clang_compilation_database_tasks = [] - self.bld.add_post_fun(write_compilation_database) - - tup = tuple(y for y in [Task.classes.get(x) for x in ('c', 'cxx')] if y) - for task in getattr(self, 'compiled_tasks', []): - if isinstance(task, tup): - clang_db.append(task) - -def write_compilation_database(ctx): - "Write the clang compilation database as JSON" - database_file = ctx.bldnode.make_node('compile_commands.json') - Logs.info('Build commands will be stored in %s', database_file.path_from(ctx.path)) - try: - root = json.load(database_file) - except IOError: - root = [] - clang_db = dict((x['file'], x) for x in root) - for task in getattr(ctx, 'clang_compilation_database_tasks', []): - try: - cmd = task.last_cmd - except AttributeError: - continue - directory = getattr(task, 'cwd', ctx.variant_dir) - f_node = task.inputs[0] - filename = os.path.relpath(f_node.abspath(), directory) - entry = { - "directory": directory, - "arguments": cmd, - "file": filename, - } - clang_db[filename] = entry - root = list(clang_db.values()) - database_file.write(json.dumps(root, indent=2)) - -# Override the runnable_status function to do a dummy/dry run when the file doesn't need to be compiled. -# This will make sure compile_commands.json is always fully up to date. -# Previously you could end up with a partial compile_commands.json if the build failed. -for x in ('c', 'cxx'): - if x not in Task.classes: - continue - - t = Task.classes[x] - - def runnable_status(self): - def exec_command(cmd, **kw): - pass - - run_status = self.old_runnable_status() - if run_status == Task.SKIP_ME: - setattr(self, 'old_exec_command', getattr(self, 'exec_command', None)) - setattr(self, 'exec_command', exec_command) - self.run() - setattr(self, 'exec_command', getattr(self, 'old_exec_command', None)) - return run_status - - setattr(t, 'old_runnable_status', getattr(t, 'runnable_status', None)) - setattr(t, 'runnable_status', runnable_status) diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/clang_cross.py b/ldb-2.0.8/third_party/waf/waflib/extras/clang_cross.py deleted file mode 100644 index 1b51e28..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/clang_cross.py +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Krzysztof Kosiński 2014 -# DragoonX6 2018 - -""" -Detect the Clang C compiler -This version is an attempt at supporting the -target and -sysroot flag of Clang. -""" - -from waflib.Tools import ccroot, ar, gcc -from waflib.Configure import conf -import waflib.Context -import waflib.extras.clang_cross_common - -def options(opt): - """ - Target triplet for clang:: - $ waf configure --clang-target-triple=x86_64-pc-linux-gnu - """ - cc_compiler_opts = opt.add_option_group('Configuration options') - cc_compiler_opts.add_option('--clang-target-triple', default=None, - help='Target triple for clang', - dest='clang_target_triple') - cc_compiler_opts.add_option('--clang-sysroot', default=None, - help='Sysroot for clang', - dest='clang_sysroot') - -@conf -def find_clang(conf): - """ - Finds the program clang and executes it to ensure it really is clang - """ - - import os - - cc = conf.find_program('clang', var='CC') - - if conf.options.clang_target_triple != None: - conf.env.append_value('CC', ['-target', conf.options.clang_target_triple]) - - if conf.options.clang_sysroot != None: - sysroot = str() - - if os.path.isabs(conf.options.clang_sysroot): - sysroot = conf.options.clang_sysroot - else: - sysroot = os.path.normpath(os.path.join(os.getcwd(), conf.options.clang_sysroot)) - - conf.env.append_value('CC', ['--sysroot', sysroot]) - - conf.get_cc_version(cc, clang=True) - conf.env.CC_NAME = 'clang' - -@conf -def clang_modifier_x86_64_w64_mingw32(conf): - conf.gcc_modifier_win32() - -@conf -def clang_modifier_i386_w64_mingw32(conf): - conf.gcc_modifier_win32() - -@conf -def clang_modifier_x86_64_windows_msvc(conf): - conf.clang_modifier_msvc() - - # Allow the user to override any flags if they so desire. - clang_modifier_user_func = getattr(conf, 'clang_modifier_x86_64_windows_msvc_user', None) - if clang_modifier_user_func: - clang_modifier_user_func() - -@conf -def clang_modifier_i386_windows_msvc(conf): - conf.clang_modifier_msvc() - - # Allow the user to override any flags if they so desire. - clang_modifier_user_func = getattr(conf, 'clang_modifier_i386_windows_msvc_user', None) - if clang_modifier_user_func: - clang_modifier_user_func() - -def configure(conf): - conf.find_clang() - conf.find_program(['llvm-ar', 'ar'], var='AR') - conf.find_ar() - conf.gcc_common_flags() - # Allow the user to provide flags for the target platform. - conf.gcc_modifier_platform() - # And allow more fine grained control based on the compiler's triplet. - conf.clang_modifier_target_triple() - conf.cc_load_tools() - conf.cc_add_flags() - conf.link_add_flags() diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/clang_cross_common.py b/ldb-2.0.8/third_party/waf/waflib/extras/clang_cross_common.py deleted file mode 100644 index b76a070..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/clang_cross_common.py +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# DragoonX6 2018 - -""" -Common routines for cross_clang.py and cross_clangxx.py -""" - -from waflib.Configure import conf -import waflib.Context - -def normalize_target_triple(target_triple): - target_triple = target_triple[:-1] - normalized_triple = target_triple.replace('--', '-unknown-') - - if normalized_triple.startswith('-'): - normalized_triple = 'unknown' + normalized_triple - - if normalized_triple.endswith('-'): - normalized_triple += 'unknown' - - # Normalize MinGW builds to *arch*-w64-mingw32 - if normalized_triple.endswith('windows-gnu'): - normalized_triple = normalized_triple[:normalized_triple.index('-')] + '-w64-mingw32' - - # Strip the vendor when doing msvc builds, since it's unused anyway. - if normalized_triple.endswith('windows-msvc'): - normalized_triple = normalized_triple[:normalized_triple.index('-')] + '-windows-msvc' - - return normalized_triple.replace('-', '_') - -@conf -def clang_modifier_msvc(conf): - import os - - """ - Really basic setup to use clang in msvc mode. - We actually don't really want to do a lot, even though clang is msvc compatible - in this mode, that doesn't mean we're actually using msvc. - It's probably the best to leave it to the user, we can assume msvc mode if the user - uses the clang-cl frontend, but this module only concerns itself with the gcc-like frontend. - """ - v = conf.env - v.cprogram_PATTERN = '%s.exe' - - v.cshlib_PATTERN = '%s.dll' - v.implib_PATTERN = '%s.lib' - v.IMPLIB_ST = '-Wl,-IMPLIB:%s' - v.SHLIB_MARKER = [] - - v.CFLAGS_cshlib = [] - v.LINKFLAGS_cshlib = ['-Wl,-DLL'] - v.cstlib_PATTERN = '%s.lib' - v.STLIB_MARKER = [] - - del(v.AR) - conf.find_program(['llvm-lib', 'lib'], var='AR') - v.ARFLAGS = ['-nologo'] - v.AR_TGT_F = ['-out:'] - - # Default to the linker supplied with llvm instead of link.exe or ld - v.LINK_CC = v.CC + ['-fuse-ld=lld', '-nostdlib'] - v.CCLNK_TGT_F = ['-o'] - v.def_PATTERN = '-Wl,-def:%s' - - v.LINKFLAGS = [] - - v.LIB_ST = '-l%s' - v.LIBPATH_ST = '-Wl,-LIBPATH:%s' - v.STLIB_ST = '-l%s' - v.STLIBPATH_ST = '-Wl,-LIBPATH:%s' - - CFLAGS_CRT_COMMON = [ - '-Xclang', '--dependent-lib=oldnames', - '-Xclang', '-fno-rtti-data', - '-D_MT' - ] - - v.CFLAGS_CRT_MULTITHREADED = CFLAGS_CRT_COMMON + [ - '-Xclang', '-flto-visibility-public-std', - '-Xclang', '--dependent-lib=libcmt', - ] - v.CXXFLAGS_CRT_MULTITHREADED = v.CFLAGS_CRT_MULTITHREADED - - v.CFLAGS_CRT_MULTITHREADED_DBG = CFLAGS_CRT_COMMON + [ - '-D_DEBUG', - '-Xclang', '-flto-visibility-public-std', - '-Xclang', '--dependent-lib=libcmtd', - ] - v.CXXFLAGS_CRT_MULTITHREADED_DBG = v.CFLAGS_CRT_MULTITHREADED_DBG - - v.CFLAGS_CRT_MULTITHREADED_DLL = CFLAGS_CRT_COMMON + [ - '-D_DLL', - '-Xclang', '--dependent-lib=msvcrt' - ] - v.CXXFLAGS_CRT_MULTITHREADED_DLL = v.CFLAGS_CRT_MULTITHREADED_DLL - - v.CFLAGS_CRT_MULTITHREADED_DLL_DBG = CFLAGS_CRT_COMMON + [ - '-D_DLL', - '-D_DEBUG', - '-Xclang', '--dependent-lib=msvcrtd', - ] - v.CXXFLAGS_CRT_MULTITHREADED_DLL_DBG = v.CFLAGS_CRT_MULTITHREADED_DLL_DBG - -@conf -def clang_modifier_target_triple(conf, cpp=False): - compiler = conf.env.CXX if cpp else conf.env.CC - output = conf.cmd_and_log(compiler + ['-dumpmachine'], output=waflib.Context.STDOUT) - - modifier = ('clangxx' if cpp else 'clang') + '_modifier_' - clang_modifier_func = getattr(conf, modifier + normalize_target_triple(output), None) - if clang_modifier_func: - clang_modifier_func() diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/clangxx_cross.py b/ldb-2.0.8/third_party/waf/waflib/extras/clangxx_cross.py deleted file mode 100644 index 0ad38ad..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/clangxx_cross.py +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy 2009-2018 (ita) -# DragoonX6 2018 - -""" -Detect the Clang++ C++ compiler -This version is an attempt at supporting the -target and -sysroot flag of Clang++. -""" - -from waflib.Tools import ccroot, ar, gxx -from waflib.Configure import conf -import waflib.extras.clang_cross_common - -def options(opt): - """ - Target triplet for clang++:: - $ waf configure --clangxx-target-triple=x86_64-pc-linux-gnu - """ - cxx_compiler_opts = opt.add_option_group('Configuration options') - cxx_compiler_opts.add_option('--clangxx-target-triple', default=None, - help='Target triple for clang++', - dest='clangxx_target_triple') - cxx_compiler_opts.add_option('--clangxx-sysroot', default=None, - help='Sysroot for clang++', - dest='clangxx_sysroot') - -@conf -def find_clangxx(conf): - """ - Finds the program clang++, and executes it to ensure it really is clang++ - """ - - import os - - cxx = conf.find_program('clang++', var='CXX') - - if conf.options.clangxx_target_triple != None: - conf.env.append_value('CXX', ['-target', conf.options.clangxx_target_triple]) - - if conf.options.clangxx_sysroot != None: - sysroot = str() - - if os.path.isabs(conf.options.clangxx_sysroot): - sysroot = conf.options.clangxx_sysroot - else: - sysroot = os.path.normpath(os.path.join(os.getcwd(), conf.options.clangxx_sysroot)) - - conf.env.append_value('CXX', ['--sysroot', sysroot]) - - conf.get_cc_version(cxx, clang=True) - conf.env.CXX_NAME = 'clang' - -@conf -def clangxx_modifier_x86_64_w64_mingw32(conf): - conf.gcc_modifier_win32() - -@conf -def clangxx_modifier_i386_w64_mingw32(conf): - conf.gcc_modifier_win32() - -@conf -def clangxx_modifier_msvc(conf): - v = conf.env - v.cxxprogram_PATTERN = v.cprogram_PATTERN - v.cxxshlib_PATTERN = v.cshlib_PATTERN - - v.CXXFLAGS_cxxshlib = [] - v.LINKFLAGS_cxxshlib = v.LINKFLAGS_cshlib - v.cxxstlib_PATTERN = v.cstlib_PATTERN - - v.LINK_CXX = v.CXX + ['-fuse-ld=lld', '-nostdlib'] - v.CXXLNK_TGT_F = v.CCLNK_TGT_F - -@conf -def clangxx_modifier_x86_64_windows_msvc(conf): - conf.clang_modifier_msvc() - conf.clangxx_modifier_msvc() - - # Allow the user to override any flags if they so desire. - clang_modifier_user_func = getattr(conf, 'clangxx_modifier_x86_64_windows_msvc_user', None) - if clang_modifier_user_func: - clang_modifier_user_func() - -@conf -def clangxx_modifier_i386_windows_msvc(conf): - conf.clang_modifier_msvc() - conf.clangxx_modifier_msvc() - - # Allow the user to override any flags if they so desire. - clang_modifier_user_func = getattr(conf, 'clangxx_modifier_i386_windows_msvc_user', None) - if clang_modifier_user_func: - clang_modifier_user_func() - -def configure(conf): - conf.find_clangxx() - conf.find_program(['llvm-ar', 'ar'], var='AR') - conf.find_ar() - conf.gxx_common_flags() - # Allow the user to provide flags for the target platform. - conf.gxx_modifier_platform() - # And allow more fine grained control based on the compiler's triplet. - conf.clang_modifier_target_triple(cpp=True) - conf.cxx_load_tools() - conf.cxx_add_flags() - conf.link_add_flags() diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/codelite.py b/ldb-2.0.8/third_party/waf/waflib/extras/codelite.py deleted file mode 100644 index 523302c..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/codelite.py +++ /dev/null @@ -1,875 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# CodeLite Project -# Christian Klein (chrikle@berlios.de) -# Created: Jan 2012 -# As templete for this file I used the msvs.py -# I hope this template will work proper - -""" -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -""" - -""" - - -To add this tool to your project: -def options(conf): - opt.load('codelite') - -It can be a good idea to add the sync_exec tool too. - -To generate solution files: -$ waf configure codelite - -To customize the outputs, provide subclasses in your wscript files: - -from waflib.extras import codelite -class vsnode_target(codelite.vsnode_target): - def get_build_command(self, props): - # likely to be required - return "waf.bat build" - def collect_source(self): - # likely to be required - ... -class codelite_bar(codelite.codelite_generator): - def init(self): - codelite.codelite_generator.init(self) - self.vsnode_target = vsnode_target - -The codelite class re-uses the same build() function for reading the targets (task generators), -you may therefore specify codelite settings on the context object: - -def build(bld): - bld.codelite_solution_name = 'foo.workspace' - bld.waf_command = 'waf.bat' - bld.projects_dir = bld.srcnode.make_node('') - bld.projects_dir.mkdir() - - -ASSUMPTIONS: -* a project can be either a directory or a target, project files are written only for targets that have source files -* each project is a vcxproj file, therefore the project uuid needs only to be a hash of the absolute path -""" - -import os, re, sys -import uuid # requires python 2.5 -from waflib.Build import BuildContext -from waflib import Utils, TaskGen, Logs, Task, Context, Node, Options - -HEADERS_GLOB = '**/(*.h|*.hpp|*.H|*.inl)' - -PROJECT_TEMPLATE = r''' - - - - - - - - - - ${for x in project.source} - ${if (project.get_key(x)=="sourcefile")} - - ${endif} - ${endfor} - - - ${for x in project.source} - ${if (project.get_key(x)=="headerfile")} - - ${endif} - ${endfor} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $b = project.build_properties[0]} - ${xml:project.get_rebuild_command(project.build_properties[0])} - ${xml:project.get_clean_command(project.build_properties[0])} - ${xml:project.get_build_command(project.build_properties[0])} - ${xml:project.get_install_command(project.build_properties[0])} - ${xml:project.get_build_and_install_command(project.build_properties[0])} - ${xml:project.get_build_all_command(project.build_properties[0])} - ${xml:project.get_rebuild_all_command(project.build_properties[0])} - ${xml:project.get_clean_all_command(project.build_properties[0])} - ${xml:project.get_build_and_install_all_command(project.build_properties[0])} - - - - None - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -''' - - - - -SOLUTION_TEMPLATE = ''' - -${for p in project.all_projects} - -${endfor} - - -${for p in project.all_projects} - -${endfor} - - -''' - - - -COMPILE_TEMPLATE = '''def f(project): - lst = [] - def xml_escape(value): - return value.replace("&", "&").replace('"', """).replace("'", "'").replace("<", "<").replace(">", ">") - - %s - - #f = open('cmd.txt', 'w') - #f.write(str(lst)) - #f.close() - return ''.join(lst) -''' -reg_act = re.compile(r"(?P\\)|(?P\$\$)|(?P\$\{(?P[^}]*?)\})", re.M) -def compile_template(line): - """ - Compile a template expression into a python function (like jsps, but way shorter) - """ - extr = [] - def repl(match): - g = match.group - if g('dollar'): - return "$" - elif g('backslash'): - return "\\" - elif g('subst'): - extr.append(g('code')) - return "<<|@|>>" - return None - - line2 = reg_act.sub(repl, line) - params = line2.split('<<|@|>>') - assert(extr) - - - indent = 0 - buf = [] - app = buf.append - - def app(txt): - buf.append(indent * '\t' + txt) - - for x in range(len(extr)): - if params[x]: - app("lst.append(%r)" % params[x]) - - f = extr[x] - if f.startswith(('if', 'for')): - app(f + ':') - indent += 1 - elif f.startswith('py:'): - app(f[3:]) - elif f.startswith(('endif', 'endfor')): - indent -= 1 - elif f.startswith(('else', 'elif')): - indent -= 1 - app(f + ':') - indent += 1 - elif f.startswith('xml:'): - app('lst.append(xml_escape(%s))' % f[4:]) - else: - #app('lst.append((%s) or "cannot find %s")' % (f, f)) - app('lst.append(%s)' % f) - - if extr: - if params[-1]: - app("lst.append(%r)" % params[-1]) - - fun = COMPILE_TEMPLATE % "\n\t".join(buf) - #print(fun) - return Task.funex(fun) - - -re_blank = re.compile('(\n|\r|\\s)*\n', re.M) -def rm_blank_lines(txt): - txt = re_blank.sub('\r\n', txt) - return txt - -BOM = '\xef\xbb\xbf' -try: - BOM = bytes(BOM, 'latin-1') # python 3 -except (TypeError, NameError): - pass - -def stealth_write(self, data, flags='wb'): - try: - unicode - except NameError: - data = data.encode('utf-8') # python 3 - else: - data = data.decode(sys.getfilesystemencoding(), 'replace') - data = data.encode('utf-8') - - if self.name.endswith('.project'): - data = BOM + data - - try: - txt = self.read(flags='rb') - if txt != data: - raise ValueError('must write') - except (IOError, ValueError): - self.write(data, flags=flags) - else: - Logs.debug('codelite: skipping %r', self) -Node.Node.stealth_write = stealth_write - -re_quote = re.compile("[^a-zA-Z0-9-]") -def quote(s): - return re_quote.sub("_", s) - -def xml_escape(value): - return value.replace("&", "&").replace('"', """).replace("'", "'").replace("<", "<").replace(">", ">") - -def make_uuid(v, prefix = None): - """ - simple utility function - """ - if isinstance(v, dict): - keys = list(v.keys()) - keys.sort() - tmp = str([(k, v[k]) for k in keys]) - else: - tmp = str(v) - d = Utils.md5(tmp.encode()).hexdigest().upper() - if prefix: - d = '%s%s' % (prefix, d[8:]) - gid = uuid.UUID(d, version = 4) - return str(gid).upper() - -def diff(node, fromnode): - # difference between two nodes, but with "(..)" instead of ".." - c1 = node - c2 = fromnode - - c1h = c1.height() - c2h = c2.height() - - lst = [] - up = 0 - - while c1h > c2h: - lst.append(c1.name) - c1 = c1.parent - c1h -= 1 - - while c2h > c1h: - up += 1 - c2 = c2.parent - c2h -= 1 - - while id(c1) != id(c2): - lst.append(c1.name) - up += 1 - - c1 = c1.parent - c2 = c2.parent - - for i in range(up): - lst.append('(..)') - lst.reverse() - return tuple(lst) - -class build_property(object): - pass - -class vsnode(object): - """ - Abstract class representing visual studio elements - We assume that all visual studio nodes have a uuid and a parent - """ - def __init__(self, ctx): - self.ctx = ctx # codelite context - self.name = '' # string, mandatory - self.vspath = '' # path in visual studio (name for dirs, absolute path for projects) - self.uuid = '' # string, mandatory - self.parent = None # parent node for visual studio nesting - - def get_waf(self): - """ - Override in subclasses... - """ - return '%s/%s' % (self.ctx.srcnode.abspath(), getattr(self.ctx, 'waf_command', 'waf')) - - def ptype(self): - """ - Return a special uuid for projects written in the solution file - """ - pass - - def write(self): - """ - Write the project file, by default, do nothing - """ - pass - - def make_uuid(self, val): - """ - Alias for creating uuid values easily (the templates cannot access global variables) - """ - return make_uuid(val) - -class vsnode_vsdir(vsnode): - """ - Nodes representing visual studio folders (which do not match the filesystem tree!) - """ - VS_GUID_SOLUTIONFOLDER = "2150E333-8FDC-42A3-9474-1A3956D46DE8" - def __init__(self, ctx, uuid, name, vspath=''): - vsnode.__init__(self, ctx) - self.title = self.name = name - self.uuid = uuid - self.vspath = vspath or name - - def ptype(self): - return self.VS_GUID_SOLUTIONFOLDER - -class vsnode_project(vsnode): - """ - Abstract class representing visual studio project elements - A project is assumed to be writable, and has a node representing the file to write to - """ - VS_GUID_VCPROJ = "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942" - def ptype(self): - return self.VS_GUID_VCPROJ - - def __init__(self, ctx, node): - vsnode.__init__(self, ctx) - self.path = node - self.uuid = make_uuid(node.abspath()) - self.name = node.name - self.title = self.path.abspath() - self.source = [] # list of node objects - self.build_properties = [] # list of properties (nmake commands, output dir, etc) - - def dirs(self): - """ - Get the list of parent folders of the source files (header files included) - for writing the filters - """ - lst = [] - def add(x): - if x.height() > self.tg.path.height() and x not in lst: - lst.append(x) - add(x.parent) - for x in self.source: - add(x.parent) - return lst - - def write(self): - Logs.debug('codelite: creating %r', self.path) - #print "self.name:",self.name - - # first write the project file - template1 = compile_template(PROJECT_TEMPLATE) - proj_str = template1(self) - proj_str = rm_blank_lines(proj_str) - self.path.stealth_write(proj_str) - - # then write the filter - #template2 = compile_template(FILTER_TEMPLATE) - #filter_str = template2(self) - #filter_str = rm_blank_lines(filter_str) - #tmp = self.path.parent.make_node(self.path.name + '.filters') - #tmp.stealth_write(filter_str) - - def get_key(self, node): - """ - required for writing the source files - """ - name = node.name - if name.endswith(('.cpp', '.c')): - return 'sourcefile' - return 'headerfile' - - def collect_properties(self): - """ - Returns a list of triplet (configuration, platform, output_directory) - """ - ret = [] - for c in self.ctx.configurations: - for p in self.ctx.platforms: - x = build_property() - x.outdir = '' - - x.configuration = c - x.platform = p - - x.preprocessor_definitions = '' - x.includes_search_path = '' - - # can specify "deploy_dir" too - ret.append(x) - self.build_properties = ret - - def get_build_params(self, props): - opt = '' - return (self.get_waf(), opt) - - def get_build_command(self, props): - return "%s build %s" % self.get_build_params(props) - - def get_clean_command(self, props): - return "%s clean %s" % self.get_build_params(props) - - def get_rebuild_command(self, props): - return "%s clean build %s" % self.get_build_params(props) - - def get_install_command(self, props): - return "%s install %s" % self.get_build_params(props) - def get_build_and_install_command(self, props): - return "%s build install %s" % self.get_build_params(props) - - def get_build_and_install_all_command(self, props): - return "%s build install" % self.get_build_params(props)[0] - - def get_clean_all_command(self, props): - return "%s clean" % self.get_build_params(props)[0] - - def get_build_all_command(self, props): - return "%s build" % self.get_build_params(props)[0] - - def get_rebuild_all_command(self, props): - return "%s clean build" % self.get_build_params(props)[0] - - def get_filter_name(self, node): - lst = diff(node, self.tg.path) - return '\\'.join(lst) or '.' - -class vsnode_alias(vsnode_project): - def __init__(self, ctx, node, name): - vsnode_project.__init__(self, ctx, node) - self.name = name - self.output_file = '' - -class vsnode_build_all(vsnode_alias): - """ - Fake target used to emulate the behaviour of "make all" (starting one process by target is slow) - This is the only alias enabled by default - """ - def __init__(self, ctx, node, name='build_all_projects'): - vsnode_alias.__init__(self, ctx, node, name) - self.is_active = True - -class vsnode_install_all(vsnode_alias): - """ - Fake target used to emulate the behaviour of "make install" - """ - def __init__(self, ctx, node, name='install_all_projects'): - vsnode_alias.__init__(self, ctx, node, name) - - def get_build_command(self, props): - return "%s build install %s" % self.get_build_params(props) - - def get_clean_command(self, props): - return "%s clean %s" % self.get_build_params(props) - - def get_rebuild_command(self, props): - return "%s clean build install %s" % self.get_build_params(props) - -class vsnode_project_view(vsnode_alias): - """ - Fake target used to emulate a file system view - """ - def __init__(self, ctx, node, name='project_view'): - vsnode_alias.__init__(self, ctx, node, name) - self.tg = self.ctx() # fake one, cannot remove - self.exclude_files = Node.exclude_regs + ''' -waf-2* -waf3-2*/** -.waf-2* -.waf3-2*/** -**/*.sdf -**/*.suo -**/*.ncb -**/%s - ''' % Options.lockfile - - def collect_source(self): - # this is likely to be slow - self.source = self.ctx.srcnode.ant_glob('**', excl=self.exclude_files) - - def get_build_command(self, props): - params = self.get_build_params(props) + (self.ctx.cmd,) - return "%s %s %s" % params - - def get_clean_command(self, props): - return "" - - def get_rebuild_command(self, props): - return self.get_build_command(props) - -class vsnode_target(vsnode_project): - """ - CodeLite project representing a targets (programs, libraries, etc) and bound - to a task generator - """ - def __init__(self, ctx, tg): - """ - A project is more or less equivalent to a file/folder - """ - base = getattr(ctx, 'projects_dir', None) or tg.path - node = base.make_node(quote(tg.name) + ctx.project_extension) # the project file as a Node - vsnode_project.__init__(self, ctx, node) - self.name = quote(tg.name) - self.tg = tg # task generator - - def get_build_params(self, props): - """ - Override the default to add the target name - """ - opt = '' - if getattr(self, 'tg', None): - opt += " --targets=%s" % self.tg.name - return (self.get_waf(), opt) - - def collect_source(self): - tg = self.tg - source_files = tg.to_nodes(getattr(tg, 'source', [])) - include_dirs = Utils.to_list(getattr(tg, 'codelite_includes', [])) - include_files = [] - for x in include_dirs: - if isinstance(x, str): - x = tg.path.find_node(x) - if x: - lst = [y for y in x.ant_glob(HEADERS_GLOB, flat=False)] - include_files.extend(lst) - - # remove duplicates - self.source.extend(list(set(source_files + include_files))) - self.source.sort(key=lambda x: x.abspath()) - - def collect_properties(self): - """ - CodeLite projects are associated with platforms and configurations (for building especially) - """ - super(vsnode_target, self).collect_properties() - for x in self.build_properties: - x.outdir = self.path.parent.abspath() - x.preprocessor_definitions = '' - x.includes_search_path = '' - - try: - tsk = self.tg.link_task - except AttributeError: - pass - else: - x.output_file = tsk.outputs[0].abspath() - x.preprocessor_definitions = ';'.join(tsk.env.DEFINES) - x.includes_search_path = ';'.join(self.tg.env.INCPATHS) - -class codelite_generator(BuildContext): - '''generates a CodeLite workspace''' - cmd = 'codelite' - fun = 'build' - - def init(self): - """ - Some data that needs to be present - """ - if not getattr(self, 'configurations', None): - self.configurations = ['Release'] # LocalRelease, RemoteDebug, etc - if not getattr(self, 'platforms', None): - self.platforms = ['Win32'] - if not getattr(self, 'all_projects', None): - self.all_projects = [] - if not getattr(self, 'project_extension', None): - self.project_extension = '.project' - if not getattr(self, 'projects_dir', None): - self.projects_dir = self.srcnode.make_node('') - self.projects_dir.mkdir() - - # bind the classes to the object, so that subclass can provide custom generators - if not getattr(self, 'vsnode_vsdir', None): - self.vsnode_vsdir = vsnode_vsdir - if not getattr(self, 'vsnode_target', None): - self.vsnode_target = vsnode_target - if not getattr(self, 'vsnode_build_all', None): - self.vsnode_build_all = vsnode_build_all - if not getattr(self, 'vsnode_install_all', None): - self.vsnode_install_all = vsnode_install_all - if not getattr(self, 'vsnode_project_view', None): - self.vsnode_project_view = vsnode_project_view - - self.numver = '11.00' - self.vsver = '2010' - - def execute(self): - """ - Entry point - """ - self.restore() - if not self.all_envs: - self.load_envs() - self.recurse([self.run_dir]) - - # user initialization - self.init() - - # two phases for creating the solution - self.collect_projects() # add project objects into "self.all_projects" - self.write_files() # write the corresponding project and solution files - - def collect_projects(self): - """ - Fill the list self.all_projects with project objects - Fill the list of build targets - """ - self.collect_targets() - #self.add_aliases() - #self.collect_dirs() - default_project = getattr(self, 'default_project', None) - def sortfun(x): - if x.name == default_project: - return '' - return getattr(x, 'path', None) and x.path.abspath() or x.name - self.all_projects.sort(key=sortfun) - - def write_files(self): - """ - Write the project and solution files from the data collected - so far. It is unlikely that you will want to change this - """ - for p in self.all_projects: - p.write() - - # and finally write the solution file - node = self.get_solution_node() - node.parent.mkdir() - Logs.warn('Creating %r', node) - #a = dir(self.root) - #for b in a: - # print b - #print self.group_names - #print "Hallo2: ",self.root.listdir() - #print getattr(self, 'codelite_solution_name', None) - template1 = compile_template(SOLUTION_TEMPLATE) - sln_str = template1(self) - sln_str = rm_blank_lines(sln_str) - node.stealth_write(sln_str) - - def get_solution_node(self): - """ - The solution filename is required when writing the .vcproj files - return self.solution_node and if it does not exist, make one - """ - try: - return self.solution_node - except: - pass - - codelite_solution_name = getattr(self, 'codelite_solution_name', None) - if not codelite_solution_name: - codelite_solution_name = getattr(Context.g_module, Context.APPNAME, 'project') + '.workspace' - setattr(self, 'codelite_solution_name', codelite_solution_name) - if os.path.isabs(codelite_solution_name): - self.solution_node = self.root.make_node(codelite_solution_name) - else: - self.solution_node = self.srcnode.make_node(codelite_solution_name) - return self.solution_node - - def project_configurations(self): - """ - Helper that returns all the pairs (config,platform) - """ - ret = [] - for c in self.configurations: - for p in self.platforms: - ret.append((c, p)) - return ret - - def collect_targets(self): - """ - Process the list of task generators - """ - for g in self.groups: - for tg in g: - if not isinstance(tg, TaskGen.task_gen): - continue - - if not hasattr(tg, 'codelite_includes'): - tg.codelite_includes = tg.to_list(getattr(tg, 'includes', [])) + tg.to_list(getattr(tg, 'export_includes', [])) - tg.post() - if not getattr(tg, 'link_task', None): - continue - - p = self.vsnode_target(self, tg) - p.collect_source() # delegate this processing - p.collect_properties() - self.all_projects.append(p) - - def add_aliases(self): - """ - Add a specific target that emulates the "make all" necessary for Visual studio when pressing F7 - We also add an alias for "make install" (disabled by default) - """ - base = getattr(self, 'projects_dir', None) or self.tg.path - - node_project = base.make_node('build_all_projects' + self.project_extension) # Node - p_build = self.vsnode_build_all(self, node_project) - p_build.collect_properties() - self.all_projects.append(p_build) - - node_project = base.make_node('install_all_projects' + self.project_extension) # Node - p_install = self.vsnode_install_all(self, node_project) - p_install.collect_properties() - self.all_projects.append(p_install) - - node_project = base.make_node('project_view' + self.project_extension) # Node - p_view = self.vsnode_project_view(self, node_project) - p_view.collect_source() - p_view.collect_properties() - self.all_projects.append(p_view) - - n = self.vsnode_vsdir(self, make_uuid(self.srcnode.abspath() + 'build_aliases'), "build_aliases") - p_build.parent = p_install.parent = p_view.parent = n - self.all_projects.append(n) - - def collect_dirs(self): - """ - Create the folder structure in the CodeLite project view - """ - seen = {} - def make_parents(proj): - # look at a project, try to make a parent - if getattr(proj, 'parent', None): - # aliases already have parents - return - x = proj.iter_path - if x in seen: - proj.parent = seen[x] - return - - # There is not vsnode_vsdir for x. - # So create a project representing the folder "x" - n = proj.parent = seen[x] = self.vsnode_vsdir(self, make_uuid(x.abspath()), x.name) - n.iter_path = x.parent - self.all_projects.append(n) - - # recurse up to the project directory - if x.height() > self.srcnode.height() + 1: - make_parents(n) - - for p in self.all_projects[:]: # iterate over a copy of all projects - if not getattr(p, 'tg', None): - # but only projects that have a task generator - continue - - # make a folder for each task generator - p.iter_path = p.tg.path - make_parents(p) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/color_gcc.py b/ldb-2.0.8/third_party/waf/waflib/extras/color_gcc.py deleted file mode 100644 index b68c5eb..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/color_gcc.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 - -# Replaces the default formatter by one which understands GCC output and colorizes it. - -__author__ = __maintainer__ = "Jérôme Carretero " -__copyright__ = "Jérôme Carretero, 2012" - -import sys -from waflib import Logs - -class ColorGCCFormatter(Logs.formatter): - def __init__(self, colors): - self.colors = colors - Logs.formatter.__init__(self) - def format(self, rec): - frame = sys._getframe() - while frame: - func = frame.f_code.co_name - if func == 'exec_command': - cmd = frame.f_locals.get('cmd') - if isinstance(cmd, list) and ('gcc' in cmd[0] or 'g++' in cmd[0]): - lines = [] - for line in rec.msg.splitlines(): - if 'warning: ' in line: - lines.append(self.colors.YELLOW + line) - elif 'error: ' in line: - lines.append(self.colors.RED + line) - elif 'note: ' in line: - lines.append(self.colors.CYAN + line) - else: - lines.append(line) - rec.msg = "\n".join(lines) - frame = frame.f_back - return Logs.formatter.format(self, rec) - -def options(opt): - Logs.log.handlers[0].setFormatter(ColorGCCFormatter(Logs.colors)) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/color_msvc.py b/ldb-2.0.8/third_party/waf/waflib/extras/color_msvc.py deleted file mode 100644 index 60bacb7..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/color_msvc.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 - -# Replaces the default formatter by one which understands MSVC output and colorizes it. -# Modified from color_gcc.py - -__author__ = __maintainer__ = "Alibek Omarov " -__copyright__ = "Alibek Omarov, 2019" - -import sys -from waflib import Logs - -class ColorMSVCFormatter(Logs.formatter): - def __init__(self, colors): - self.colors = colors - Logs.formatter.__init__(self) - - def parseMessage(self, line, color): - # Split messaage from 'disk:filepath: type: message' - arr = line.split(':', 3) - if len(arr) < 4: - return line - - colored = self.colors.BOLD + arr[0] + ':' + arr[1] + ':' + self.colors.NORMAL - colored += color + arr[2] + ':' + self.colors.NORMAL - colored += arr[3] - return colored - - def format(self, rec): - frame = sys._getframe() - while frame: - func = frame.f_code.co_name - if func == 'exec_command': - cmd = frame.f_locals.get('cmd') - if isinstance(cmd, list): - # Fix file case, it may be CL.EXE or cl.exe - argv0 = cmd[0].lower() - if 'cl.exe' in argv0: - lines = [] - # This will not work with "localized" versions - # of MSVC - for line in rec.msg.splitlines(): - if ': warning ' in line: - lines.append(self.parseMessage(line, self.colors.YELLOW)) - elif ': error ' in line: - lines.append(self.parseMessage(line, self.colors.RED)) - elif ': fatal error ' in line: - lines.append(self.parseMessage(line, self.colors.RED + self.colors.BOLD)) - elif ': note: ' in line: - lines.append(self.parseMessage(line, self.colors.CYAN)) - else: - lines.append(line) - rec.msg = "\n".join(lines) - frame = frame.f_back - return Logs.formatter.format(self, rec) - -def options(opt): - Logs.log.handlers[0].setFormatter(ColorMSVCFormatter(Logs.colors)) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/color_rvct.py b/ldb-2.0.8/third_party/waf/waflib/extras/color_rvct.py deleted file mode 100644 index f89ccbd..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/color_rvct.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 - -# Replaces the default formatter by one which understands RVCT output and colorizes it. - -__author__ = __maintainer__ = "Jérôme Carretero " -__copyright__ = "Jérôme Carretero, 2012" - -import sys -import atexit -from waflib import Logs - -errors = [] - -def show_errors(): - for i, e in enumerate(errors): - if i > 5: - break - print("Error: %s" % e) - -atexit.register(show_errors) - -class RcvtFormatter(Logs.formatter): - def __init__(self, colors): - Logs.formatter.__init__(self) - self.colors = colors - def format(self, rec): - frame = sys._getframe() - while frame: - func = frame.f_code.co_name - if func == 'exec_command': - cmd = frame.f_locals['cmd'] - if isinstance(cmd, list) and ('armcc' in cmd[0] or 'armld' in cmd[0]): - lines = [] - for line in rec.msg.splitlines(): - if 'Warning: ' in line: - lines.append(self.colors.YELLOW + line) - elif 'Error: ' in line: - lines.append(self.colors.RED + line) - errors.append(line) - elif 'note: ' in line: - lines.append(self.colors.CYAN + line) - else: - lines.append(line) - rec.msg = "\n".join(lines) - frame = frame.f_back - return Logs.formatter.format(self, rec) - -def options(opt): - Logs.log.handlers[0].setFormatter(RcvtFormatter(Logs.colors)) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/compat15.py b/ldb-2.0.8/third_party/waf/waflib/extras/compat15.py deleted file mode 100644 index 0e74df8..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/compat15.py +++ /dev/null @@ -1,406 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2010 (ita) - -""" -This file is provided to enable compatibility with waf 1.5 -It was enabled by default in waf 1.6, but it is not used in waf 1.7 -""" - -import sys -from waflib import ConfigSet, Logs, Options, Scripting, Task, Build, Configure, Node, Runner, TaskGen, Utils, Errors, Context - -# the following is to bring some compatibility with waf 1.5 "import waflib.Configure → import Configure" -sys.modules['Environment'] = ConfigSet -ConfigSet.Environment = ConfigSet.ConfigSet - -sys.modules['Logs'] = Logs -sys.modules['Options'] = Options -sys.modules['Scripting'] = Scripting -sys.modules['Task'] = Task -sys.modules['Build'] = Build -sys.modules['Configure'] = Configure -sys.modules['Node'] = Node -sys.modules['Runner'] = Runner -sys.modules['TaskGen'] = TaskGen -sys.modules['Utils'] = Utils -sys.modules['Constants'] = Context -Context.SRCDIR = '' -Context.BLDDIR = '' - -from waflib.Tools import c_preproc -sys.modules['preproc'] = c_preproc - -from waflib.Tools import c_config -sys.modules['config_c'] = c_config - -ConfigSet.ConfigSet.copy = ConfigSet.ConfigSet.derive -ConfigSet.ConfigSet.set_variant = Utils.nada - -Utils.pproc = Utils.subprocess - -Build.BuildContext.add_subdirs = Build.BuildContext.recurse -Build.BuildContext.new_task_gen = Build.BuildContext.__call__ -Build.BuildContext.is_install = 0 -Node.Node.relpath_gen = Node.Node.path_from - -Utils.pproc = Utils.subprocess -Utils.get_term_cols = Logs.get_term_cols - -def cmd_output(cmd, **kw): - - silent = False - if 'silent' in kw: - silent = kw['silent'] - del(kw['silent']) - - if 'e' in kw: - tmp = kw['e'] - del(kw['e']) - kw['env'] = tmp - - kw['shell'] = isinstance(cmd, str) - kw['stdout'] = Utils.subprocess.PIPE - if silent: - kw['stderr'] = Utils.subprocess.PIPE - - try: - p = Utils.subprocess.Popen(cmd, **kw) - output = p.communicate()[0] - except OSError as e: - raise ValueError(str(e)) - - if p.returncode: - if not silent: - msg = "command execution failed: %s -> %r" % (cmd, str(output)) - raise ValueError(msg) - output = '' - return output -Utils.cmd_output = cmd_output - -def name_to_obj(self, s, env=None): - if Logs.verbose: - Logs.warn('compat: change "name_to_obj(name, env)" by "get_tgen_by_name(name)"') - return self.get_tgen_by_name(s) -Build.BuildContext.name_to_obj = name_to_obj - -def env_of_name(self, name): - try: - return self.all_envs[name] - except KeyError: - Logs.error('no such environment: '+name) - return None -Build.BuildContext.env_of_name = env_of_name - - -def set_env_name(self, name, env): - self.all_envs[name] = env - return env -Configure.ConfigurationContext.set_env_name = set_env_name - -def retrieve(self, name, fromenv=None): - try: - env = self.all_envs[name] - except KeyError: - env = ConfigSet.ConfigSet() - self.prepare_env(env) - self.all_envs[name] = env - else: - if fromenv: - Logs.warn('The environment %s may have been configured already', name) - return env -Configure.ConfigurationContext.retrieve = retrieve - -Configure.ConfigurationContext.sub_config = Configure.ConfigurationContext.recurse -Configure.ConfigurationContext.check_tool = Configure.ConfigurationContext.load -Configure.conftest = Configure.conf -Configure.ConfigurationError = Errors.ConfigurationError -Utils.WafError = Errors.WafError - -Options.OptionsContext.sub_options = Options.OptionsContext.recurse -Options.OptionsContext.tool_options = Context.Context.load -Options.Handler = Options.OptionsContext - -Task.simple_task_type = Task.task_type_from_func = Task.task_factory -Task.Task.classes = Task.classes - -def setitem(self, key, value): - if key.startswith('CCFLAGS'): - key = key[1:] - self.table[key] = value -ConfigSet.ConfigSet.__setitem__ = setitem - -@TaskGen.feature('d') -@TaskGen.before('apply_incpaths') -def old_importpaths(self): - if getattr(self, 'importpaths', []): - self.includes = self.importpaths - -from waflib import Context -eld = Context.load_tool -def load_tool(*k, **kw): - ret = eld(*k, **kw) - if 'set_options' in ret.__dict__: - if Logs.verbose: - Logs.warn('compat: rename "set_options" to options') - ret.options = ret.set_options - if 'detect' in ret.__dict__: - if Logs.verbose: - Logs.warn('compat: rename "detect" to "configure"') - ret.configure = ret.detect - return ret -Context.load_tool = load_tool - -def get_curdir(self): - return self.path.abspath() -Context.Context.curdir = property(get_curdir, Utils.nada) - -def get_srcdir(self): - return self.srcnode.abspath() -Configure.ConfigurationContext.srcdir = property(get_srcdir, Utils.nada) - -def get_blddir(self): - return self.bldnode.abspath() -Configure.ConfigurationContext.blddir = property(get_blddir, Utils.nada) - -Configure.ConfigurationContext.check_message_1 = Configure.ConfigurationContext.start_msg -Configure.ConfigurationContext.check_message_2 = Configure.ConfigurationContext.end_msg - -rev = Context.load_module -def load_module(path, encoding=None): - ret = rev(path, encoding) - if 'set_options' in ret.__dict__: - if Logs.verbose: - Logs.warn('compat: rename "set_options" to "options" (%r)', path) - ret.options = ret.set_options - if 'srcdir' in ret.__dict__: - if Logs.verbose: - Logs.warn('compat: rename "srcdir" to "top" (%r)', path) - ret.top = ret.srcdir - if 'blddir' in ret.__dict__: - if Logs.verbose: - Logs.warn('compat: rename "blddir" to "out" (%r)', path) - ret.out = ret.blddir - Utils.g_module = Context.g_module - Options.launch_dir = Context.launch_dir - return ret -Context.load_module = load_module - -old_post = TaskGen.task_gen.post -def post(self): - self.features = self.to_list(self.features) - if 'cc' in self.features: - if Logs.verbose: - Logs.warn('compat: the feature cc does not exist anymore (use "c")') - self.features.remove('cc') - self.features.append('c') - if 'cstaticlib' in self.features: - if Logs.verbose: - Logs.warn('compat: the feature cstaticlib does not exist anymore (use "cstlib" or "cxxstlib")') - self.features.remove('cstaticlib') - self.features.append(('cxx' in self.features) and 'cxxstlib' or 'cstlib') - if getattr(self, 'ccflags', None): - if Logs.verbose: - Logs.warn('compat: "ccflags" was renamed to "cflags"') - self.cflags = self.ccflags - return old_post(self) -TaskGen.task_gen.post = post - -def waf_version(*k, **kw): - Logs.warn('wrong version (waf_version was removed in waf 1.6)') -Utils.waf_version = waf_version - - -import os -@TaskGen.feature('c', 'cxx', 'd') -@TaskGen.before('apply_incpaths', 'propagate_uselib_vars') -@TaskGen.after('apply_link', 'process_source') -def apply_uselib_local(self): - """ - process the uselib_local attribute - execute after apply_link because of the execution order set on 'link_task' - """ - env = self.env - from waflib.Tools.ccroot import stlink_task - - # 1. the case of the libs defined in the project (visit ancestors first) - # the ancestors external libraries (uselib) will be prepended - self.uselib = self.to_list(getattr(self, 'uselib', [])) - self.includes = self.to_list(getattr(self, 'includes', [])) - names = self.to_list(getattr(self, 'uselib_local', [])) - get = self.bld.get_tgen_by_name - seen = set() - seen_uselib = set() - tmp = Utils.deque(names) # consume a copy of the list of names - if tmp: - if Logs.verbose: - Logs.warn('compat: "uselib_local" is deprecated, replace by "use"') - while tmp: - lib_name = tmp.popleft() - # visit dependencies only once - if lib_name in seen: - continue - - y = get(lib_name) - y.post() - seen.add(lib_name) - - # object has ancestors to process (shared libraries): add them to the end of the list - if getattr(y, 'uselib_local', None): - for x in self.to_list(getattr(y, 'uselib_local', [])): - obj = get(x) - obj.post() - if getattr(obj, 'link_task', None): - if not isinstance(obj.link_task, stlink_task): - tmp.append(x) - - # link task and flags - if getattr(y, 'link_task', None): - - link_name = y.target[y.target.rfind(os.sep) + 1:] - if isinstance(y.link_task, stlink_task): - env.append_value('STLIB', [link_name]) - else: - # some linkers can link against programs - env.append_value('LIB', [link_name]) - - # the order - self.link_task.set_run_after(y.link_task) - - # for the recompilation - self.link_task.dep_nodes += y.link_task.outputs - - # add the link path too - tmp_path = y.link_task.outputs[0].parent.bldpath() - if not tmp_path in env['LIBPATH']: - env.prepend_value('LIBPATH', [tmp_path]) - - # add ancestors uselib too - but only propagate those that have no staticlib defined - for v in self.to_list(getattr(y, 'uselib', [])): - if v not in seen_uselib: - seen_uselib.add(v) - if not env['STLIB_' + v]: - if not v in self.uselib: - self.uselib.insert(0, v) - - # if the library task generator provides 'export_includes', add to the include path - # the export_includes must be a list of paths relative to the other library - if getattr(y, 'export_includes', None): - self.includes.extend(y.to_incnodes(y.export_includes)) - -@TaskGen.feature('cprogram', 'cxxprogram', 'cstlib', 'cxxstlib', 'cshlib', 'cxxshlib', 'dprogram', 'dstlib', 'dshlib') -@TaskGen.after('apply_link') -def apply_objdeps(self): - "add the .o files produced by some other object files in the same manner as uselib_local" - names = getattr(self, 'add_objects', []) - if not names: - return - names = self.to_list(names) - - get = self.bld.get_tgen_by_name - seen = [] - while names: - x = names[0] - - # visit dependencies only once - if x in seen: - names = names[1:] - continue - - # object does not exist ? - y = get(x) - - # object has ancestors to process first ? update the list of names - if getattr(y, 'add_objects', None): - added = 0 - lst = y.to_list(y.add_objects) - lst.reverse() - for u in lst: - if u in seen: - continue - added = 1 - names = [u]+names - if added: - continue # list of names modified, loop - - # safe to process the current object - y.post() - seen.append(x) - - for t in getattr(y, 'compiled_tasks', []): - self.link_task.inputs.extend(t.outputs) - -@TaskGen.after('apply_link') -def process_obj_files(self): - if not hasattr(self, 'obj_files'): - return - for x in self.obj_files: - node = self.path.find_resource(x) - self.link_task.inputs.append(node) - -@TaskGen.taskgen_method -def add_obj_file(self, file): - """Small example on how to link object files as if they were source - obj = bld.create_obj('cc') - obj.add_obj_file('foo.o')""" - if not hasattr(self, 'obj_files'): - self.obj_files = [] - if not 'process_obj_files' in self.meths: - self.meths.append('process_obj_files') - self.obj_files.append(file) - - -old_define = Configure.ConfigurationContext.__dict__['define'] - -@Configure.conf -def define(self, key, val, quote=True, comment=''): - old_define(self, key, val, quote, comment) - if key.startswith('HAVE_'): - self.env[key] = 1 - -old_undefine = Configure.ConfigurationContext.__dict__['undefine'] - -@Configure.conf -def undefine(self, key, comment=''): - old_undefine(self, key, comment) - if key.startswith('HAVE_'): - self.env[key] = 0 - -# some people might want to use export_incdirs, but it was renamed -def set_incdirs(self, val): - Logs.warn('compat: change "export_incdirs" by "export_includes"') - self.export_includes = val -TaskGen.task_gen.export_incdirs = property(None, set_incdirs) - -def install_dir(self, path): - if not path: - return [] - - destpath = Utils.subst_vars(path, self.env) - - if self.is_install > 0: - Logs.info('* creating %s', destpath) - Utils.check_dir(destpath) - elif self.is_install < 0: - Logs.info('* removing %s', destpath) - try: - os.remove(destpath) - except OSError: - pass -Build.BuildContext.install_dir = install_dir - -# before/after names -repl = {'apply_core': 'process_source', - 'apply_lib_vars': 'process_source', - 'apply_obj_vars': 'propagate_uselib_vars', - 'exec_rule': 'process_rule' -} -def after(*k): - k = [repl.get(key, key) for key in k] - return TaskGen.after_method(*k) - -def before(*k): - k = [repl.get(key, key) for key in k] - return TaskGen.before_method(*k) -TaskGen.before = before - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/cppcheck.py b/ldb-2.0.8/third_party/waf/waflib/extras/cppcheck.py deleted file mode 100644 index 13ff424..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/cppcheck.py +++ /dev/null @@ -1,591 +0,0 @@ -#! /usr/bin/env python -# -*- encoding: utf-8 -*- -# Michel Mooij, michel.mooij7@gmail.com - -""" -Tool Description -================ -This module provides a waf wrapper (i.e. waftool) around the C/C++ source code -checking tool 'cppcheck'. - -See http://cppcheck.sourceforge.net/ for more information on the cppcheck tool -itself. -Note that many linux distributions already provide a ready to install version -of cppcheck. On fedora, for instance, it can be installed using yum: - - 'sudo yum install cppcheck' - - -Usage -===== -In order to use this waftool simply add it to the 'options' and 'configure' -functions of your main waf script as shown in the example below: - - def options(opt): - opt.load('cppcheck', tooldir='./waftools') - - def configure(conf): - conf.load('cppcheck') - -Note that example shown above assumes that the cppcheck waftool is located in -the sub directory named 'waftools'. - -When configured as shown in the example above, cppcheck will automatically -perform a source code analysis on all C/C++ build tasks that have been -defined in your waf build system. - -The example shown below for a C program will be used as input for cppcheck when -building the task. - - def build(bld): - bld.program(name='foo', src='foobar.c') - -The result of the source code analysis will be stored both as xml and html -files in the build location for the task. Should any error be detected by -cppcheck the build will be aborted and a link to the html report will be shown. -By default, one index.html file is created for each task generator. A global -index.html file can be obtained by setting the following variable -in the configuration section: - - conf.env.CPPCHECK_SINGLE_HTML = False - -When needed source code checking by cppcheck can be disabled per task, per -detected error or warning for a particular task. It can be also be disabled for -all tasks. - -In order to exclude a task from source code checking add the skip option to the -task as shown below: - - def build(bld): - bld.program( - name='foo', - src='foobar.c' - cppcheck_skip=True - ) - -When needed problems detected by cppcheck may be suppressed using a file -containing a list of suppression rules. The relative or absolute path to this -file can be added to the build task as shown in the example below: - - bld.program( - name='bar', - src='foobar.c', - cppcheck_suppress='bar.suppress' - ) - -A cppcheck suppress file should contain one suppress rule per line. Each of -these rules will be passed as an '--suppress=' argument to cppcheck. - -Dependencies -================ -This waftool depends on the python pygments module, it is used for source code -syntax highlighting when creating the html reports. see http://pygments.org/ for -more information on this package. - -Remarks -================ -The generation of the html report is originally based on the cppcheck-htmlreport.py -script that comes shipped with the cppcheck tool. -""" - -import sys -import xml.etree.ElementTree as ElementTree -from waflib import Task, TaskGen, Logs, Context, Options - -PYGMENTS_EXC_MSG= ''' -The required module 'pygments' could not be found. Please install it using your -platform package manager (e.g. apt-get or yum), using 'pip' or 'easy_install', -see 'http://pygments.org/download/' for installation instructions. -''' - -try: - import pygments - from pygments import formatters, lexers -except ImportError as e: - Logs.warn(PYGMENTS_EXC_MSG) - raise e - - -def options(opt): - opt.add_option('--cppcheck-skip', dest='cppcheck_skip', - default=False, action='store_true', - help='do not check C/C++ sources (default=False)') - - opt.add_option('--cppcheck-err-resume', dest='cppcheck_err_resume', - default=False, action='store_true', - help='continue in case of errors (default=False)') - - opt.add_option('--cppcheck-bin-enable', dest='cppcheck_bin_enable', - default='warning,performance,portability,style,unusedFunction', action='store', - help="cppcheck option '--enable=' for binaries (default=warning,performance,portability,style,unusedFunction)") - - opt.add_option('--cppcheck-lib-enable', dest='cppcheck_lib_enable', - default='warning,performance,portability,style', action='store', - help="cppcheck option '--enable=' for libraries (default=warning,performance,portability,style)") - - opt.add_option('--cppcheck-std-c', dest='cppcheck_std_c', - default='c99', action='store', - help='cppcheck standard to use when checking C (default=c99)') - - opt.add_option('--cppcheck-std-cxx', dest='cppcheck_std_cxx', - default='c++03', action='store', - help='cppcheck standard to use when checking C++ (default=c++03)') - - opt.add_option('--cppcheck-check-config', dest='cppcheck_check_config', - default=False, action='store_true', - help='forced check for missing buildin include files, e.g. stdio.h (default=False)') - - opt.add_option('--cppcheck-max-configs', dest='cppcheck_max_configs', - default='20', action='store', - help='maximum preprocessor (--max-configs) define iterations (default=20)') - - opt.add_option('--cppcheck-jobs', dest='cppcheck_jobs', - default='1', action='store', - help='number of jobs (-j) to do the checking work (default=1)') - -def configure(conf): - if conf.options.cppcheck_skip: - conf.env.CPPCHECK_SKIP = [True] - conf.env.CPPCHECK_STD_C = conf.options.cppcheck_std_c - conf.env.CPPCHECK_STD_CXX = conf.options.cppcheck_std_cxx - conf.env.CPPCHECK_MAX_CONFIGS = conf.options.cppcheck_max_configs - conf.env.CPPCHECK_BIN_ENABLE = conf.options.cppcheck_bin_enable - conf.env.CPPCHECK_LIB_ENABLE = conf.options.cppcheck_lib_enable - conf.env.CPPCHECK_JOBS = conf.options.cppcheck_jobs - if conf.options.cppcheck_jobs != '1' and ('unusedFunction' in conf.options.cppcheck_bin_enable or 'unusedFunction' in conf.options.cppcheck_lib_enable or 'all' in conf.options.cppcheck_bin_enable or 'all' in conf.options.cppcheck_lib_enable): - Logs.warn('cppcheck: unusedFunction cannot be used with multiple threads, cppcheck will disable it automatically') - conf.find_program('cppcheck', var='CPPCHECK') - - # set to True to get a single index.html file - conf.env.CPPCHECK_SINGLE_HTML = False - -@TaskGen.feature('c') -@TaskGen.feature('cxx') -def cppcheck_execute(self): - if hasattr(self.bld, 'conf'): - return - if len(self.env.CPPCHECK_SKIP) or Options.options.cppcheck_skip: - return - if getattr(self, 'cppcheck_skip', False): - return - task = self.create_task('cppcheck') - task.cmd = _tgen_create_cmd(self) - task.fatal = [] - if not Options.options.cppcheck_err_resume: - task.fatal.append('error') - - -def _tgen_create_cmd(self): - features = getattr(self, 'features', []) - std_c = self.env.CPPCHECK_STD_C - std_cxx = self.env.CPPCHECK_STD_CXX - max_configs = self.env.CPPCHECK_MAX_CONFIGS - bin_enable = self.env.CPPCHECK_BIN_ENABLE - lib_enable = self.env.CPPCHECK_LIB_ENABLE - jobs = self.env.CPPCHECK_JOBS - - cmd = self.env.CPPCHECK - args = ['--inconclusive','--report-progress','--verbose','--xml','--xml-version=2'] - args.append('--max-configs=%s' % max_configs) - args.append('-j %s' % jobs) - - if 'cxx' in features: - args.append('--language=c++') - args.append('--std=%s' % std_cxx) - else: - args.append('--language=c') - args.append('--std=%s' % std_c) - - if Options.options.cppcheck_check_config: - args.append('--check-config') - - if set(['cprogram','cxxprogram']) & set(features): - args.append('--enable=%s' % bin_enable) - else: - args.append('--enable=%s' % lib_enable) - - for src in self.to_list(getattr(self, 'source', [])): - if not isinstance(src, str): - src = repr(src) - args.append(src) - for inc in self.to_incnodes(self.to_list(getattr(self, 'includes', []))): - if not isinstance(inc, str): - inc = repr(inc) - args.append('-I%s' % inc) - for inc in self.to_incnodes(self.to_list(self.env.INCLUDES)): - if not isinstance(inc, str): - inc = repr(inc) - args.append('-I%s' % inc) - return cmd + args - - -class cppcheck(Task.Task): - quiet = True - - def run(self): - stderr = self.generator.bld.cmd_and_log(self.cmd, quiet=Context.STDERR, output=Context.STDERR) - self._save_xml_report(stderr) - defects = self._get_defects(stderr) - index = self._create_html_report(defects) - self._errors_evaluate(defects, index) - return 0 - - def _save_xml_report(self, s): - '''use cppcheck xml result string, add the command string used to invoke cppcheck - and save as xml file. - ''' - header = '%s\n' % s.splitlines()[0] - root = ElementTree.fromstring(s) - cmd = ElementTree.SubElement(root.find('cppcheck'), 'cmd') - cmd.text = str(self.cmd) - body = ElementTree.tostring(root).decode('us-ascii') - body_html_name = 'cppcheck-%s.xml' % self.generator.get_name() - if self.env.CPPCHECK_SINGLE_HTML: - body_html_name = 'cppcheck.xml' - node = self.generator.path.get_bld().find_or_declare(body_html_name) - node.write(header + body) - - def _get_defects(self, xml_string): - '''evaluate the xml string returned by cppcheck (on sdterr) and use it to create - a list of defects. - ''' - defects = [] - for error in ElementTree.fromstring(xml_string).iter('error'): - defect = {} - defect['id'] = error.get('id') - defect['severity'] = error.get('severity') - defect['msg'] = str(error.get('msg')).replace('<','<') - defect['verbose'] = error.get('verbose') - for location in error.findall('location'): - defect['file'] = location.get('file') - defect['line'] = str(int(location.get('line')) - 1) - defects.append(defect) - return defects - - def _create_html_report(self, defects): - files, css_style_defs = self._create_html_files(defects) - index = self._create_html_index(files) - self._create_css_file(css_style_defs) - return index - - def _create_html_files(self, defects): - sources = {} - defects = [defect for defect in defects if 'file' in defect] - for defect in defects: - name = defect['file'] - if not name in sources: - sources[name] = [defect] - else: - sources[name].append(defect) - - files = {} - css_style_defs = None - bpath = self.generator.path.get_bld().abspath() - names = list(sources.keys()) - for i in range(0,len(names)): - name = names[i] - if self.env.CPPCHECK_SINGLE_HTML: - htmlfile = 'cppcheck/%i.html' % (i) - else: - htmlfile = 'cppcheck/%s%i.html' % (self.generator.get_name(),i) - errors = sources[name] - files[name] = { 'htmlfile': '%s/%s' % (bpath, htmlfile), 'errors': errors } - css_style_defs = self._create_html_file(name, htmlfile, errors) - return files, css_style_defs - - def _create_html_file(self, sourcefile, htmlfile, errors): - name = self.generator.get_name() - root = ElementTree.fromstring(CPPCHECK_HTML_FILE) - title = root.find('head/title') - title.text = 'cppcheck - report - %s' % name - - body = root.find('body') - for div in body.findall('div'): - if div.get('id') == 'page': - page = div - break - for div in page.findall('div'): - if div.get('id') == 'header': - h1 = div.find('h1') - h1.text = 'cppcheck report - %s' % name - if div.get('id') == 'menu': - indexlink = div.find('a') - if self.env.CPPCHECK_SINGLE_HTML: - indexlink.attrib['href'] = 'index.html' - else: - indexlink.attrib['href'] = 'index-%s.html' % name - if div.get('id') == 'content': - content = div - srcnode = self.generator.bld.root.find_node(sourcefile) - hl_lines = [e['line'] for e in errors if 'line' in e] - formatter = CppcheckHtmlFormatter(linenos=True, style='colorful', hl_lines=hl_lines, lineanchors='line') - formatter.errors = [e for e in errors if 'line' in e] - css_style_defs = formatter.get_style_defs('.highlight') - lexer = pygments.lexers.guess_lexer_for_filename(sourcefile, "") - s = pygments.highlight(srcnode.read(), lexer, formatter) - table = ElementTree.fromstring(s) - content.append(table) - - s = ElementTree.tostring(root, method='html').decode('us-ascii') - s = CCPCHECK_HTML_TYPE + s - node = self.generator.path.get_bld().find_or_declare(htmlfile) - node.write(s) - return css_style_defs - - def _create_html_index(self, files): - name = self.generator.get_name() - root = ElementTree.fromstring(CPPCHECK_HTML_FILE) - title = root.find('head/title') - title.text = 'cppcheck - report - %s' % name - - body = root.find('body') - for div in body.findall('div'): - if div.get('id') == 'page': - page = div - break - for div in page.findall('div'): - if div.get('id') == 'header': - h1 = div.find('h1') - h1.text = 'cppcheck report - %s' % name - if div.get('id') == 'content': - content = div - self._create_html_table(content, files) - if div.get('id') == 'menu': - indexlink = div.find('a') - if self.env.CPPCHECK_SINGLE_HTML: - indexlink.attrib['href'] = 'index.html' - else: - indexlink.attrib['href'] = 'index-%s.html' % name - - s = ElementTree.tostring(root, method='html').decode('us-ascii') - s = CCPCHECK_HTML_TYPE + s - index_html_name = 'cppcheck/index-%s.html' % name - if self.env.CPPCHECK_SINGLE_HTML: - index_html_name = 'cppcheck/index.html' - node = self.generator.path.get_bld().find_or_declare(index_html_name) - node.write(s) - return node - - def _create_html_table(self, content, files): - table = ElementTree.fromstring(CPPCHECK_HTML_TABLE) - for name, val in files.items(): - f = val['htmlfile'] - s = '%s\n' % (f,name) - row = ElementTree.fromstring(s) - table.append(row) - - errors = sorted(val['errors'], key=lambda e: int(e['line']) if 'line' in e else sys.maxint) - for e in errors: - if not 'line' in e: - s = '%s%s%s\n' % (e['id'], e['severity'], e['msg']) - else: - attr = '' - if e['severity'] == 'error': - attr = 'class="error"' - s = '%s' % (f, e['line'], e['line']) - s+= '%s%s%s\n' % (e['id'], e['severity'], attr, e['msg']) - row = ElementTree.fromstring(s) - table.append(row) - content.append(table) - - def _create_css_file(self, css_style_defs): - css = str(CPPCHECK_CSS_FILE) - if css_style_defs: - css = "%s\n%s\n" % (css, css_style_defs) - node = self.generator.path.get_bld().find_or_declare('cppcheck/style.css') - node.write(css) - - def _errors_evaluate(self, errors, http_index): - name = self.generator.get_name() - fatal = self.fatal - severity = [err['severity'] for err in errors] - problems = [err for err in errors if err['severity'] != 'information'] - - if set(fatal) & set(severity): - exc = "\n" - exc += "\nccpcheck detected fatal error(s) in task '%s', see report for details:" % name - exc += "\n file://%r" % (http_index) - exc += "\n" - self.generator.bld.fatal(exc) - - elif len(problems): - msg = "\nccpcheck detected (possible) problem(s) in task '%s', see report for details:" % name - msg += "\n file://%r" % http_index - msg += "\n" - Logs.error(msg) - - -class CppcheckHtmlFormatter(pygments.formatters.HtmlFormatter): - errors = [] - - def wrap(self, source, outfile): - line_no = 1 - for i, t in super(CppcheckHtmlFormatter, self).wrap(source, outfile): - # If this is a source code line we want to add a span tag at the end. - if i == 1: - for error in self.errors: - if int(error['line']) == line_no: - t = t.replace('\n', CPPCHECK_HTML_ERROR % error['msg']) - line_no += 1 - yield i, t - - -CCPCHECK_HTML_TYPE = \ -'\n' - -CPPCHECK_HTML_FILE = """ -]> - - - cppcheck - report - XXX - - - - - -
      - - -
      -
      - -   -
      - - - -""" - -CPPCHECK_HTML_TABLE = """ - - - - - - - -
      LineIdSeverityMessage
      -""" - -CPPCHECK_HTML_ERROR = \ -'<--- %s\n' - -CPPCHECK_CSS_FILE = """ -body.body { - font-family: Arial; - font-size: 13px; - background-color: black; - padding: 0px; - margin: 0px; -} - -.error { - font-family: Arial; - font-size: 13px; - background-color: #ffb7b7; - padding: 0px; - margin: 0px; -} - -th, td { - min-width: 100px; - text-align: left; -} - -#page-header { - clear: both; - width: 1200px; - margin: 20px auto 0px auto; - height: 10px; - border-bottom-width: 2px; - border-bottom-style: solid; - border-bottom-color: #aaaaaa; -} - -#page { - width: 1160px; - margin: auto; - border-left-width: 2px; - border-left-style: solid; - border-left-color: #aaaaaa; - border-right-width: 2px; - border-right-style: solid; - border-right-color: #aaaaaa; - background-color: White; - padding: 20px; -} - -#page-footer { - clear: both; - width: 1200px; - margin: auto; - height: 10px; - border-top-width: 2px; - border-top-style: solid; - border-top-color: #aaaaaa; -} - -#header { - width: 100%; - height: 70px; - background-image: url(logo.png); - background-repeat: no-repeat; - background-position: left top; - border-bottom-style: solid; - border-bottom-width: thin; - border-bottom-color: #aaaaaa; -} - -#menu { - margin-top: 5px; - text-align: left; - float: left; - width: 100px; - height: 300px; -} - -#menu > a { - margin-left: 10px; - display: block; -} - -#content { - float: left; - width: 1020px; - margin: 5px; - padding: 0px 10px 10px 10px; - border-left-style: solid; - border-left-width: thin; - border-left-color: #aaaaaa; -} - -#footer { - padding-bottom: 5px; - padding-top: 5px; - border-top-style: solid; - border-top-width: thin; - border-top-color: #aaaaaa; - clear: both; - font-size: 10px; -} - -#footer > div { - float: left; - width: 33%; -} - -""" - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/cpplint.py b/ldb-2.0.8/third_party/waf/waflib/extras/cpplint.py deleted file mode 100644 index 8cdd6dd..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/cpplint.py +++ /dev/null @@ -1,209 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# -# written by Sylvain Rouquette, 2014 - -''' - -This is an extra tool, not bundled with the default waf binary. -To add the cpplint tool to the waf file: -$ ./waf-light --tools=compat15,cpplint - -this tool also requires cpplint for python. -If you have PIP, you can install it like this: pip install cpplint - -When using this tool, the wscript will look like: - - def options(opt): - opt.load('compiler_cxx cpplint') - - def configure(conf): - conf.load('compiler_cxx cpplint') - # optional, you can also specify them on the command line - conf.env.CPPLINT_FILTERS = ','.join(( - '-whitespace/newline', # c++11 lambda - '-readability/braces', # c++11 constructor - '-whitespace/braces', # c++11 constructor - '-build/storage_class', # c++11 for-range - '-whitespace/blank_line', # user pref - '-whitespace/labels' # user pref - )) - - def build(bld): - bld(features='cpplint', source='main.cpp', target='app') - # add include files, because they aren't usually built - bld(features='cpplint', source=bld.path.ant_glob('**/*.hpp')) -''' - -from __future__ import absolute_import -import sys, re -import logging -from waflib import Errors, Task, TaskGen, Logs, Options, Node, Utils - - -critical_errors = 0 -CPPLINT_FORMAT = '[CPPLINT] %(filename)s:\nline %(linenum)s, severity %(confidence)s, category: %(category)s\n%(message)s\n' -RE_EMACS = re.compile(r'(?P.*):(?P\d+): (?P.*) \[(?P.*)\] \[(?P\d+)\]') -CPPLINT_RE = { - 'waf': RE_EMACS, - 'emacs': RE_EMACS, - 'vs7': re.compile(r'(?P.*)\((?P\d+)\): (?P.*) \[(?P.*)\] \[(?P\d+)\]'), - 'eclipse': re.compile(r'(?P.*):(?P\d+): warning: (?P.*) \[(?P.*)\] \[(?P\d+)\]'), -} -CPPLINT_STR = ('${CPPLINT} ' - '--verbose=${CPPLINT_LEVEL} ' - '--output=${CPPLINT_OUTPUT} ' - '--filter=${CPPLINT_FILTERS} ' - '--root=${CPPLINT_ROOT} ' - '--linelength=${CPPLINT_LINE_LENGTH} ') - - -def options(opt): - opt.add_option('--cpplint-filters', type='string', - default='', dest='CPPLINT_FILTERS', - help='add filters to cpplint') - opt.add_option('--cpplint-length', type='int', - default=80, dest='CPPLINT_LINE_LENGTH', - help='specify the line length (default: 80)') - opt.add_option('--cpplint-level', default=1, type='int', dest='CPPLINT_LEVEL', - help='specify the log level (default: 1)') - opt.add_option('--cpplint-break', default=5, type='int', dest='CPPLINT_BREAK', - help='break the build if error >= level (default: 5)') - opt.add_option('--cpplint-root', type='string', - default='', dest='CPPLINT_ROOT', - help='root directory used to derive header guard') - opt.add_option('--cpplint-skip', action='store_true', - default=False, dest='CPPLINT_SKIP', - help='skip cpplint during build') - opt.add_option('--cpplint-output', type='string', - default='waf', dest='CPPLINT_OUTPUT', - help='select output format (waf, emacs, vs7, eclipse)') - - -def configure(conf): - try: - conf.find_program('cpplint', var='CPPLINT') - except Errors.ConfigurationError: - conf.env.CPPLINT_SKIP = True - - -class cpplint_formatter(Logs.formatter, object): - def __init__(self, fmt): - logging.Formatter.__init__(self, CPPLINT_FORMAT) - self.fmt = fmt - - def format(self, rec): - if self.fmt == 'waf': - result = CPPLINT_RE[self.fmt].match(rec.msg).groupdict() - rec.msg = CPPLINT_FORMAT % result - if rec.levelno <= logging.INFO: - rec.c1 = Logs.colors.CYAN - return super(cpplint_formatter, self).format(rec) - - -class cpplint_handler(Logs.log_handler, object): - def __init__(self, stream=sys.stderr, **kw): - super(cpplint_handler, self).__init__(stream, **kw) - self.stream = stream - - def emit(self, rec): - rec.stream = self.stream - self.emit_override(rec) - self.flush() - - -class cpplint_wrapper(object): - def __init__(self, logger, threshold, fmt): - self.logger = logger - self.threshold = threshold - self.fmt = fmt - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_value, traceback): - if isinstance(exc_value, Utils.subprocess.CalledProcessError): - messages = [m for m in exc_value.output.splitlines() - if 'Done processing' not in m - and 'Total errors found' not in m] - for message in messages: - self.write(message) - return True - - def write(self, message): - global critical_errors - result = CPPLINT_RE[self.fmt].match(message) - if not result: - return - level = int(result.groupdict()['confidence']) - if level >= self.threshold: - critical_errors += 1 - if level <= 2: - self.logger.info(message) - elif level <= 4: - self.logger.warning(message) - else: - self.logger.error(message) - - -cpplint_logger = None -def get_cpplint_logger(fmt): - global cpplint_logger - if cpplint_logger: - return cpplint_logger - cpplint_logger = logging.getLogger('cpplint') - hdlr = cpplint_handler() - hdlr.setFormatter(cpplint_formatter(fmt)) - cpplint_logger.addHandler(hdlr) - cpplint_logger.setLevel(logging.DEBUG) - return cpplint_logger - - -class cpplint(Task.Task): - color = 'PINK' - - def __init__(self, *k, **kw): - super(cpplint, self).__init__(*k, **kw) - - def run(self): - global critical_errors - with cpplint_wrapper(get_cpplint_logger(self.env.CPPLINT_OUTPUT), self.env.CPPLINT_BREAK, self.env.CPPLINT_OUTPUT): - params = {key: str(self.env[key]) for key in self.env if 'CPPLINT_' in key} - if params['CPPLINT_OUTPUT'] is 'waf': - params['CPPLINT_OUTPUT'] = 'emacs' - params['CPPLINT'] = self.env.get_flat('CPPLINT') - cmd = Utils.subst_vars(CPPLINT_STR, params) - env = self.env.env or None - Utils.subprocess.check_output(cmd + self.inputs[0].abspath(), - stderr=Utils.subprocess.STDOUT, - env=env, shell=True) - return critical_errors - -@TaskGen.extension('.h', '.hh', '.hpp', '.hxx') -def cpplint_includes(self, node): - pass - -@TaskGen.feature('cpplint') -@TaskGen.before_method('process_source') -def post_cpplint(self): - if not self.env.CPPLINT_INITIALIZED: - for key, value in Options.options.__dict__.items(): - if not key.startswith('CPPLINT_') or self.env[key]: - continue - self.env[key] = value - self.env.CPPLINT_INITIALIZED = True - - if self.env.CPPLINT_SKIP: - return - - if not self.env.CPPLINT_OUTPUT in CPPLINT_RE: - return - - for src in self.to_list(getattr(self, 'source', [])): - if isinstance(src, Node.Node): - node = src - else: - node = self.path.find_or_declare(src) - if not node: - self.bld.fatal('Could not find %r' % src) - self.create_task('cpplint', node) diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/cross_gnu.py b/ldb-2.0.8/third_party/waf/waflib/extras/cross_gnu.py deleted file mode 100644 index 309f53b..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/cross_gnu.py +++ /dev/null @@ -1,227 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 vi:ts=4:noexpandtab -# Tool to provide dedicated variables for cross-compilation - -__author__ = __maintainer__ = "Jérôme Carretero " -__copyright__ = "Jérôme Carretero, 2014" - -""" -This tool allows to use environment variables to define cross-compilation -variables intended for build variants. - -The variables are obtained from the environment in 3 ways: - -1. By defining CHOST, they can be derived as ${CHOST}-${TOOL} -2. By defining HOST_x -3. By defining ${CHOST//-/_}_x - -else one can set ``cfg.env.CHOST`` in ``wscript`` before loading ``cross_gnu``. - -Usage: - -- In your build script:: - - def configure(cfg): - ... - for variant in x_variants: - setenv(variant) - conf.load('cross_gnu') - conf.xcheck_host_var('POUET') - ... - - -- Then:: - - CHOST=arm-hardfloat-linux-gnueabi waf configure - env arm-hardfloat-linux-gnueabi-CC="clang -..." waf configure - CFLAGS=... CHOST=arm-hardfloat-linux-gnueabi HOST_CFLAGS=-g waf configure - HOST_CC="clang -..." waf configure - -This example ``wscript`` compiles to Microchip PIC (xc16-gcc-xyz must be in PATH): - -.. code:: python - - from waflib import Configure - - #from https://gist.github.com/rpuntaie/2bddfb5d7b77db26415ee14371289971 - import waf_variants - - variants='pc fw/variant1 fw/variant2'.split() - - top = "." - out = "../build" - - PIC = '33FJ128GP804' #dsPICxxx - - @Configure.conf - def gcc_modifier_xc16(cfg): - v = cfg.env - v.cprogram_PATTERN = '%s.elf' - v.LINKFLAGS_cprogram = ','.join(['-Wl','','','--defsym=__MPLAB_BUILD=0','','--script=p'+PIC+'.gld', - '--stack=16','--check-sections','--data-init','--pack-data','--handles','--isr','--no-gc-sections', - '--fill-upper=0','--stackguard=16','--no-force-link','--smart-io']) #,'--report-mem']) - v.CFLAGS_cprogram=['-mcpu='+PIC,'-omf=elf','-mlarge-code','-msmart-io=1', - '-msfr-warn=off','-mno-override-inline','-finline','-Winline'] - - def configure(cfg): - if 'fw' in cfg.variant: #firmware - cfg.env.DEST_OS = 'xc16' #cfg.env.CHOST = 'xc16' #works too - cfg.load('c cross_gnu') #cfg.env.CHOST becomes ['xc16'] - ... - else: #configure for pc SW - ... - - def build(bld): - if 'fw' in bld.variant: #firmware - bld.program(source='maintst.c', target='maintst'); - bld(source='maintst.elf', target='maintst.hex', rule="xc16-bin2hex ${SRC} -a -omf=elf") - else: #build for pc SW - ... - -""" - -import os -from waflib import Utils, Configure -from waflib.Tools import ccroot, gcc - -try: - from shlex import quote -except ImportError: - from pipes import quote - -def get_chost_stuff(conf): - """ - Get the CHOST environment variable contents - """ - chost = None - chost_envar = None - if conf.env.CHOST: - chost = conf.env.CHOST[0] - chost_envar = chost.replace('-', '_') - return chost, chost_envar - - -@Configure.conf -def xcheck_var(conf, name, wafname=None, cross=False): - wafname = wafname or name - - if wafname in conf.env: - value = conf.env[wafname] - if isinstance(value, str): - value = [value] - else: - envar = os.environ.get(name) - if not envar: - return - value = Utils.to_list(envar) if envar != '' else [envar] - - conf.env[wafname] = value - if cross: - pretty = 'cross-compilation %s' % wafname - else: - pretty = wafname - conf.msg('Will use %s' % pretty, " ".join(quote(x) for x in value)) - -@Configure.conf -def xcheck_host_prog(conf, name, tool, wafname=None): - wafname = wafname or name - - chost, chost_envar = get_chost_stuff(conf) - - specific = None - if chost: - specific = os.environ.get('%s_%s' % (chost_envar, name)) - - if specific: - value = Utils.to_list(specific) - conf.env[wafname] += value - conf.msg('Will use cross-compilation %s from %s_%s' % (name, chost_envar, name), - " ".join(quote(x) for x in value)) - return - else: - envar = os.environ.get('HOST_%s' % name) - if envar is not None: - value = Utils.to_list(envar) - conf.env[wafname] = value - conf.msg('Will use cross-compilation %s from HOST_%s' % (name, name), - " ".join(quote(x) for x in value)) - return - - if conf.env[wafname]: - return - - value = None - if chost: - value = '%s-%s' % (chost, tool) - - if value: - conf.env[wafname] = value - conf.msg('Will use cross-compilation %s from CHOST' % wafname, value) - -@Configure.conf -def xcheck_host_envar(conf, name, wafname=None): - wafname = wafname or name - - chost, chost_envar = get_chost_stuff(conf) - - specific = None - if chost: - specific = os.environ.get('%s_%s' % (chost_envar, name)) - - if specific: - value = Utils.to_list(specific) - conf.env[wafname] += value - conf.msg('Will use cross-compilation %s from %s_%s' \ - % (name, chost_envar, name), - " ".join(quote(x) for x in value)) - return - - - envar = os.environ.get('HOST_%s' % name) - if envar is None: - return - - value = Utils.to_list(envar) if envar != '' else [envar] - - conf.env[wafname] = value - conf.msg('Will use cross-compilation %s from HOST_%s' % (name, name), - " ".join(quote(x) for x in value)) - - -@Configure.conf -def xcheck_host(conf): - conf.xcheck_var('CHOST', cross=True) - conf.env.CHOST = conf.env.CHOST or [conf.env.DEST_OS] - conf.env.DEST_OS = conf.env.CHOST[0].replace('-','_') - conf.xcheck_host_prog('CC', 'gcc') - conf.xcheck_host_prog('CXX', 'g++') - conf.xcheck_host_prog('LINK_CC', 'gcc') - conf.xcheck_host_prog('LINK_CXX', 'g++') - conf.xcheck_host_prog('AR', 'ar') - conf.xcheck_host_prog('AS', 'as') - conf.xcheck_host_prog('LD', 'ld') - conf.xcheck_host_envar('CFLAGS') - conf.xcheck_host_envar('CXXFLAGS') - conf.xcheck_host_envar('LDFLAGS', 'LINKFLAGS') - conf.xcheck_host_envar('LIB') - conf.xcheck_host_envar('PKG_CONFIG_LIBDIR') - conf.xcheck_host_envar('PKG_CONFIG_PATH') - - if not conf.env.env: - conf.env.env = {} - conf.env.env.update(os.environ) - if conf.env.PKG_CONFIG_LIBDIR: - conf.env.env['PKG_CONFIG_LIBDIR'] = conf.env.PKG_CONFIG_LIBDIR[0] - if conf.env.PKG_CONFIG_PATH: - conf.env.env['PKG_CONFIG_PATH'] = conf.env.PKG_CONFIG_PATH[0] - -def configure(conf): - """ - Configuration example for gcc, it will not work for g++/clang/clang++ - """ - conf.xcheck_host() - conf.gcc_common_flags() - conf.gcc_modifier_platform() - conf.cc_load_tools() - conf.cc_add_flags() - conf.link_add_flags() diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/cython.py b/ldb-2.0.8/third_party/waf/waflib/extras/cython.py deleted file mode 100644 index 591c274..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/cython.py +++ /dev/null @@ -1,147 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2010-2015 - -import re -from waflib import Task, Logs -from waflib.TaskGen import extension - -cy_api_pat = re.compile(r'\s*?cdef\s*?(public|api)\w*') -re_cyt = re.compile(r""" - ^\s* # must begin with some whitespace characters - (?:from\s+(\w+)(?:\.\w+)*\s+)? # optionally match "from foo(.baz)" and capture foo - c?import\s(\w+|[*]) # require "import bar" and capture bar - """, re.M | re.VERBOSE) - -@extension('.pyx') -def add_cython_file(self, node): - """ - Process a *.pyx* file given in the list of source files. No additional - feature is required:: - - def build(bld): - bld(features='c cshlib pyext', source='main.c foo.pyx', target='app') - """ - ext = '.c' - if 'cxx' in self.features: - self.env.append_unique('CYTHONFLAGS', '--cplus') - ext = '.cc' - - for x in getattr(self, 'cython_includes', []): - # TODO re-use these nodes in "scan" below - d = self.path.find_dir(x) - if d: - self.env.append_unique('CYTHONFLAGS', '-I%s' % d.abspath()) - - tsk = self.create_task('cython', node, node.change_ext(ext)) - self.source += tsk.outputs - -class cython(Task.Task): - run_str = '${CYTHON} ${CYTHONFLAGS} -o ${TGT[0].abspath()} ${SRC}' - color = 'GREEN' - - vars = ['INCLUDES'] - """ - Rebuild whenever the INCLUDES change. The variables such as CYTHONFLAGS will be appended - by the metaclass. - """ - - ext_out = ['.h'] - """ - The creation of a .h file is known only after the build has begun, so it is not - possible to compute a build order just by looking at the task inputs/outputs. - """ - - def runnable_status(self): - """ - Perform a double-check to add the headers created by cython - to the output nodes. The scanner is executed only when the cython task - must be executed (optimization). - """ - ret = super(cython, self).runnable_status() - if ret == Task.ASK_LATER: - return ret - for x in self.generator.bld.raw_deps[self.uid()]: - if x.startswith('header:'): - self.outputs.append(self.inputs[0].parent.find_or_declare(x.replace('header:', ''))) - return super(cython, self).runnable_status() - - def post_run(self): - for x in self.outputs: - if x.name.endswith('.h'): - if not x.exists(): - if Logs.verbose: - Logs.warn('Expected %r', x.abspath()) - x.write('') - return Task.Task.post_run(self) - - def scan(self): - """ - Return the dependent files (.pxd) by looking in the include folders. - Put the headers to generate in the custom list "bld.raw_deps". - To inspect the scanne results use:: - - $ waf clean build --zones=deps - """ - node = self.inputs[0] - txt = node.read() - - mods = set() - for m in re_cyt.finditer(txt): - if m.group(1): # matches "from foo import bar" - mods.add(m.group(1)) - else: - mods.add(m.group(2)) - - Logs.debug('cython: mods %r', mods) - incs = getattr(self.generator, 'cython_includes', []) - incs = [self.generator.path.find_dir(x) for x in incs] - incs.append(node.parent) - - found = [] - missing = [] - for x in sorted(mods): - for y in incs: - k = y.find_resource(x + '.pxd') - if k: - found.append(k) - break - else: - missing.append(x) - - # the cython file implicitly depends on a pxd file that might be present - implicit = node.parent.find_resource(node.name[:-3] + 'pxd') - if implicit: - found.append(implicit) - - Logs.debug('cython: found %r', found) - - # Now the .h created - store them in bld.raw_deps for later use - has_api = False - has_public = False - for l in txt.splitlines(): - if cy_api_pat.match(l): - if ' api ' in l: - has_api = True - if ' public ' in l: - has_public = True - name = node.name.replace('.pyx', '') - if has_api: - missing.append('header:%s_api.h' % name) - if has_public: - missing.append('header:%s.h' % name) - - return (found, missing) - -def options(ctx): - ctx.add_option('--cython-flags', action='store', default='', help='space separated list of flags to pass to cython') - -def configure(ctx): - if not ctx.env.CC and not ctx.env.CXX: - ctx.fatal('Load a C/C++ compiler first') - if not ctx.env.PYTHON: - ctx.fatal('Load the python tool first!') - ctx.find_program('cython', var='CYTHON') - if hasattr(ctx.options, 'cython_flags'): - ctx.env.CYTHONFLAGS = ctx.options.cython_flags - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/dcc.py b/ldb-2.0.8/third_party/waf/waflib/extras/dcc.py deleted file mode 100644 index c1a57c0..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/dcc.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Jérôme Carretero, 2011 (zougloub) - -from waflib import Options -from waflib.Tools import ccroot -from waflib.Configure import conf - -@conf -def find_dcc(conf): - conf.find_program(['dcc'], var='CC', path_list=getattr(Options.options, 'diabbindir', "")) - conf.env.CC_NAME = 'dcc' - -@conf -def find_dld(conf): - conf.find_program(['dld'], var='LINK_CC', path_list=getattr(Options.options, 'diabbindir', "")) - conf.env.LINK_CC_NAME = 'dld' - -@conf -def find_dar(conf): - conf.find_program(['dar'], var='AR', path_list=getattr(Options.options, 'diabbindir', "")) - conf.env.AR_NAME = 'dar' - conf.env.ARFLAGS = 'rcs' - -@conf -def find_ddump(conf): - conf.find_program(['ddump'], var='DDUMP', path_list=getattr(Options.options, 'diabbindir', "")) - -@conf -def dcc_common_flags(conf): - v = conf.env - v['CC_SRC_F'] = [] - v['CC_TGT_F'] = ['-c', '-o'] - - # linker - if not v['LINK_CC']: - v['LINK_CC'] = v['CC'] - v['CCLNK_SRC_F'] = [] - v['CCLNK_TGT_F'] = ['-o'] - v['CPPPATH_ST'] = '-I%s' - v['DEFINES_ST'] = '-D%s' - - v['LIB_ST'] = '-l:%s' # template for adding libs - v['LIBPATH_ST'] = '-L%s' # template for adding libpaths - v['STLIB_ST'] = '-l:%s' - v['STLIBPATH_ST'] = '-L%s' - v['RPATH_ST'] = '-Wl,-rpath,%s' - #v['STLIB_MARKER'] = '-Wl,-Bstatic' - - # program - v['cprogram_PATTERN'] = '%s.elf' - - # static lib - v['LINKFLAGS_cstlib'] = ['-Wl,-Bstatic'] - v['cstlib_PATTERN'] = 'lib%s.a' - -def configure(conf): - conf.find_dcc() - conf.find_dar() - conf.find_dld() - conf.find_ddump() - conf.dcc_common_flags() - conf.cc_load_tools() - conf.cc_add_flags() - conf.link_add_flags() - -def options(opt): - """ - Add the ``--with-diab-bindir`` command-line options. - """ - opt.add_option('--with-diab-bindir', type='string', dest='diabbindir', help = 'Specify alternate diab bin folder', default="") - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/distnet.py b/ldb-2.0.8/third_party/waf/waflib/extras/distnet.py deleted file mode 100644 index ff3ed8e..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/distnet.py +++ /dev/null @@ -1,430 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 - -""" -waf-powered distributed network builds, with a network cache. - -Caching files from a server has advantages over a NFS/Samba shared folder: - -- builds are much faster because they use local files -- builds just continue to work in case of a network glitch -- permissions are much simpler to manage -""" - -import os, urllib, tarfile, re, shutil, tempfile, sys -from collections import OrderedDict -from waflib import Context, Utils, Logs - -try: - from urllib.parse import urlencode -except ImportError: - urlencode = urllib.urlencode - -def safe_urlencode(data): - x = urlencode(data) - try: - x = x.encode('utf-8') - except Exception: - pass - return x - -try: - from urllib.error import URLError -except ImportError: - from urllib2 import URLError - -try: - from urllib.request import Request, urlopen -except ImportError: - from urllib2 import Request, urlopen - -DISTNETCACHE = os.environ.get('DISTNETCACHE', '/tmp/distnetcache') -DISTNETSERVER = os.environ.get('DISTNETSERVER', 'http://localhost:8000/cgi-bin/') -TARFORMAT = 'w:bz2' -TIMEOUT = 60 -REQUIRES = 'requires.txt' - -re_com = re.compile(r'\s*#.*', re.M) - -def total_version_order(num): - lst = num.split('.') - template = '%10s' * len(lst) - ret = template % tuple(lst) - return ret - -def get_distnet_cache(): - return getattr(Context.g_module, 'DISTNETCACHE', DISTNETCACHE) - -def get_server_url(): - return getattr(Context.g_module, 'DISTNETSERVER', DISTNETSERVER) - -def get_download_url(): - return '%s/download.py' % get_server_url() - -def get_upload_url(): - return '%s/upload.py' % get_server_url() - -def get_resolve_url(): - return '%s/resolve.py' % get_server_url() - -def send_package_name(): - out = getattr(Context.g_module, 'out', 'build') - pkgfile = '%s/package_to_upload.tarfile' % out - return pkgfile - -class package(Context.Context): - fun = 'package' - cmd = 'package' - - def execute(self): - try: - files = self.files - except AttributeError: - files = self.files = [] - - Context.Context.execute(self) - pkgfile = send_package_name() - if not pkgfile in files: - if not REQUIRES in files: - files.append(REQUIRES) - self.make_tarfile(pkgfile, files, add_to_package=False) - - def make_tarfile(self, filename, files, **kw): - if kw.get('add_to_package', True): - self.files.append(filename) - - with tarfile.open(filename, TARFORMAT) as tar: - endname = os.path.split(filename)[-1] - endname = endname.split('.')[0] + '/' - for x in files: - tarinfo = tar.gettarinfo(x, x) - tarinfo.uid = tarinfo.gid = 0 - tarinfo.uname = tarinfo.gname = 'root' - tarinfo.size = os.stat(x).st_size - - # TODO - more archive creation options? - if kw.get('bare', True): - tarinfo.name = os.path.split(x)[1] - else: - tarinfo.name = endname + x # todo, if tuple, then.. - Logs.debug('distnet: adding %r to %s', tarinfo.name, filename) - with open(x, 'rb') as f: - tar.addfile(tarinfo, f) - Logs.info('Created %s', filename) - -class publish(Context.Context): - fun = 'publish' - cmd = 'publish' - def execute(self): - if hasattr(Context.g_module, 'publish'): - Context.Context.execute(self) - mod = Context.g_module - - rfile = getattr(self, 'rfile', send_package_name()) - if not os.path.isfile(rfile): - self.fatal('Create the release file with "waf release" first! %r' % rfile) - - fdata = Utils.readf(rfile, m='rb') - data = safe_urlencode([('pkgdata', fdata), ('pkgname', mod.APPNAME), ('pkgver', mod.VERSION)]) - - req = Request(get_upload_url(), data) - response = urlopen(req, timeout=TIMEOUT) - data = response.read().strip() - - if sys.hexversion>0x300000f: - data = data.decode('utf-8') - - if data != 'ok': - self.fatal('Could not publish the package %r' % data) - -class constraint(object): - def __init__(self, line=''): - self.required_line = line - self.info = [] - - line = line.strip() - if not line: - return - - lst = line.split(',') - if lst: - self.pkgname = lst[0] - self.required_version = lst[1] - for k in lst: - a, b, c = k.partition('=') - if a and c: - self.info.append((a, c)) - def __str__(self): - buf = [] - buf.append(self.pkgname) - buf.append(self.required_version) - for k in self.info: - buf.append('%s=%s' % k) - return ','.join(buf) - - def __repr__(self): - return "requires %s-%s" % (self.pkgname, self.required_version) - - def human_display(self, pkgname, pkgver): - return '%s-%s requires %s-%s' % (pkgname, pkgver, self.pkgname, self.required_version) - - def why(self): - ret = [] - for x in self.info: - if x[0] == 'reason': - ret.append(x[1]) - return ret - - def add_reason(self, reason): - self.info.append(('reason', reason)) - -def parse_constraints(text): - assert(text is not None) - constraints = [] - text = re.sub(re_com, '', text) - lines = text.splitlines() - for line in lines: - line = line.strip() - if not line: - continue - constraints.append(constraint(line)) - return constraints - -def list_package_versions(cachedir, pkgname): - pkgdir = os.path.join(cachedir, pkgname) - try: - versions = os.listdir(pkgdir) - except OSError: - return [] - versions.sort(key=total_version_order) - versions.reverse() - return versions - -class package_reader(Context.Context): - cmd = 'solver' - fun = 'solver' - - def __init__(self, **kw): - Context.Context.__init__(self, **kw) - - self.myproject = getattr(Context.g_module, 'APPNAME', 'project') - self.myversion = getattr(Context.g_module, 'VERSION', '1.0') - self.cache_constraints = {} - self.constraints = [] - - def compute_dependencies(self, filename=REQUIRES): - text = Utils.readf(filename) - data = safe_urlencode([('text', text)]) - - if '--offline' in sys.argv: - self.constraints = self.local_resolve(text) - else: - req = Request(get_resolve_url(), data) - try: - response = urlopen(req, timeout=TIMEOUT) - except URLError as e: - Logs.warn('The package server is down! %r', e) - self.constraints = self.local_resolve(text) - else: - ret = response.read() - try: - ret = ret.decode('utf-8') - except Exception: - pass - self.trace(ret) - self.constraints = parse_constraints(ret) - self.check_errors() - - def check_errors(self): - errors = False - for c in self.constraints: - if not c.required_version: - errors = True - - reasons = c.why() - if len(reasons) == 1: - Logs.error('%s but no matching package could be found in this repository', reasons[0]) - else: - Logs.error('Conflicts on package %r:', c.pkgname) - for r in reasons: - Logs.error(' %s', r) - if errors: - self.fatal('The package requirements cannot be satisfied!') - - def load_constraints(self, pkgname, pkgver, requires=REQUIRES): - try: - return self.cache_constraints[(pkgname, pkgver)] - except KeyError: - text = Utils.readf(os.path.join(get_distnet_cache(), pkgname, pkgver, requires)) - ret = parse_constraints(text) - self.cache_constraints[(pkgname, pkgver)] = ret - return ret - - def apply_constraint(self, domain, constraint): - vname = constraint.required_version.replace('*', '.*') - rev = re.compile(vname, re.M) - ret = [x for x in domain if rev.match(x)] - return ret - - def trace(self, *k): - if getattr(self, 'debug', None): - Logs.error(*k) - - def solve(self, packages_to_versions={}, packages_to_constraints={}, pkgname='', pkgver='', todo=[], done=[]): - # breadth first search - n_packages_to_versions = dict(packages_to_versions) - n_packages_to_constraints = dict(packages_to_constraints) - - self.trace("calling solve with %r %r %r" % (packages_to_versions, todo, done)) - done = done + [pkgname] - - constraints = self.load_constraints(pkgname, pkgver) - self.trace("constraints %r" % constraints) - - for k in constraints: - try: - domain = n_packages_to_versions[k.pkgname] - except KeyError: - domain = list_package_versions(get_distnet_cache(), k.pkgname) - - - self.trace("constraints?") - if not k.pkgname in done: - todo = todo + [k.pkgname] - - self.trace("domain before %s -> %s, %r" % (pkgname, k.pkgname, domain)) - - # apply the constraint - domain = self.apply_constraint(domain, k) - - self.trace("domain after %s -> %s, %r" % (pkgname, k.pkgname, domain)) - - n_packages_to_versions[k.pkgname] = domain - - # then store the constraint applied - constraints = list(packages_to_constraints.get(k.pkgname, [])) - constraints.append((pkgname, pkgver, k)) - n_packages_to_constraints[k.pkgname] = constraints - - if not domain: - self.trace("no domain while processing constraint %r from %r %r" % (domain, pkgname, pkgver)) - return (n_packages_to_versions, n_packages_to_constraints) - - # next package on the todo list - if not todo: - return (n_packages_to_versions, n_packages_to_constraints) - - n_pkgname = todo[0] - n_pkgver = n_packages_to_versions[n_pkgname][0] - tmp = dict(n_packages_to_versions) - tmp[n_pkgname] = [n_pkgver] - - self.trace("fixed point %s" % n_pkgname) - - return self.solve(tmp, n_packages_to_constraints, n_pkgname, n_pkgver, todo[1:], done) - - def get_results(self): - return '\n'.join([str(c) for c in self.constraints]) - - def solution_to_constraints(self, versions, constraints): - solution = [] - for p in versions: - c = constraint() - solution.append(c) - - c.pkgname = p - if versions[p]: - c.required_version = versions[p][0] - else: - c.required_version = '' - for (from_pkgname, from_pkgver, c2) in constraints.get(p, ''): - c.add_reason(c2.human_display(from_pkgname, from_pkgver)) - return solution - - def local_resolve(self, text): - self.cache_constraints[(self.myproject, self.myversion)] = parse_constraints(text) - p2v = OrderedDict({self.myproject: [self.myversion]}) - (versions, constraints) = self.solve(p2v, {}, self.myproject, self.myversion, []) - return self.solution_to_constraints(versions, constraints) - - def download_to_file(self, pkgname, pkgver, subdir, tmp): - data = safe_urlencode([('pkgname', pkgname), ('pkgver', pkgver), ('pkgfile', subdir)]) - req = urlopen(get_download_url(), data, timeout=TIMEOUT) - with open(tmp, 'wb') as f: - while True: - buf = req.read(8192) - if not buf: - break - f.write(buf) - - def extract_tar(self, subdir, pkgdir, tmpfile): - with tarfile.open(tmpfile) as f: - temp = tempfile.mkdtemp(dir=pkgdir) - try: - f.extractall(temp) - os.rename(temp, os.path.join(pkgdir, subdir)) - finally: - try: - shutil.rmtree(temp) - except Exception: - pass - - def get_pkg_dir(self, pkgname, pkgver, subdir): - pkgdir = os.path.join(get_distnet_cache(), pkgname, pkgver) - if not os.path.isdir(pkgdir): - os.makedirs(pkgdir) - - target = os.path.join(pkgdir, subdir) - - if os.path.exists(target): - return target - - (fd, tmp) = tempfile.mkstemp(dir=pkgdir) - try: - os.close(fd) - self.download_to_file(pkgname, pkgver, subdir, tmp) - if subdir == REQUIRES: - os.rename(tmp, target) - else: - self.extract_tar(subdir, pkgdir, tmp) - finally: - try: - os.remove(tmp) - except OSError: - pass - - return target - - def __iter__(self): - if not self.constraints: - self.compute_dependencies() - for x in self.constraints: - if x.pkgname == self.myproject: - continue - yield x - - def execute(self): - self.compute_dependencies() - -packages = package_reader() - -def load_tools(ctx, extra): - global packages - for c in packages: - packages.get_pkg_dir(c.pkgname, c.required_version, extra) - noarchdir = packages.get_pkg_dir(c.pkgname, c.required_version, 'noarch') - for x in os.listdir(noarchdir): - if x.startswith('waf_') and x.endswith('.py'): - ctx.load([x.rstrip('.py')], tooldir=[noarchdir]) - -def options(opt): - opt.add_option('--offline', action='store_true') - packages.execute() - load_tools(opt, REQUIRES) - -def configure(conf): - load_tools(conf, conf.variant) - -def build(bld): - load_tools(bld, bld.variant) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/doxygen.py b/ldb-2.0.8/third_party/waf/waflib/extras/doxygen.py deleted file mode 100644 index 20cd9e1..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/doxygen.py +++ /dev/null @@ -1,235 +0,0 @@ -#! /usr/bin/env python -# encoding: UTF-8 -# Thomas Nagy 2008-2010 (ita) - -""" - -Doxygen support - -Variables passed to bld(): -* doxyfile -- the Doxyfile to use -* doxy_tar -- destination archive for generated documentation (if desired) -* install_path -- where to install the documentation -* pars -- dictionary overriding doxygen configuration settings - -When using this tool, the wscript will look like: - - def options(opt): - opt.load('doxygen') - - def configure(conf): - conf.load('doxygen') - # check conf.env.DOXYGEN, if it is mandatory - - def build(bld): - if bld.env.DOXYGEN: - bld(features="doxygen", doxyfile='Doxyfile', ...) -""" - -import os, os.path, re -from collections import OrderedDict -from waflib import Task, Utils, Node -from waflib.TaskGen import feature - -DOXY_STR = '"${DOXYGEN}" - ' -DOXY_FMTS = 'html latex man rft xml'.split() -DOXY_FILE_PATTERNS = '*.' + ' *.'.join(''' -c cc cxx cpp c++ java ii ixx ipp i++ inl h hh hxx hpp h++ idl odl cs php php3 -inc m mm py f90c cc cxx cpp c++ java ii ixx ipp i++ inl h hh hxx -'''.split()) - -re_rl = re.compile('\\\\\r*\n', re.MULTILINE) -re_nl = re.compile('\r*\n', re.M) -def parse_doxy(txt): - ''' - Parses a doxygen file. - Returns an ordered dictionary. We cannot return a default dictionary, as the - order in which the entries are reported does matter, especially for the - '@INCLUDE' lines. - ''' - tbl = OrderedDict() - txt = re_rl.sub('', txt) - lines = re_nl.split(txt) - for x in lines: - x = x.strip() - if not x or x.startswith('#') or x.find('=') < 0: - continue - if x.find('+=') >= 0: - tmp = x.split('+=') - key = tmp[0].strip() - if key in tbl: - tbl[key] += ' ' + '+='.join(tmp[1:]).strip() - else: - tbl[key] = '+='.join(tmp[1:]).strip() - else: - tmp = x.split('=') - tbl[tmp[0].strip()] = '='.join(tmp[1:]).strip() - return tbl - -class doxygen(Task.Task): - vars = ['DOXYGEN', 'DOXYFLAGS'] - color = 'BLUE' - - def runnable_status(self): - ''' - self.pars are populated in runnable_status - because this function is being - run *before* both self.pars "consumers" - scan() and run() - - set output_dir (node) for the output - ''' - - for x in self.run_after: - if not x.hasrun: - return Task.ASK_LATER - - if not getattr(self, 'pars', None): - txt = self.inputs[0].read() - self.pars = parse_doxy(txt) - - # Override with any parameters passed to the task generator - if getattr(self.generator, 'pars', None): - for k, v in self.generator.pars.items(): - self.pars[k] = v - - if self.pars.get('OUTPUT_DIRECTORY'): - # Use the path parsed from the Doxyfile as an absolute path - output_node = self.inputs[0].parent.get_bld().make_node(self.pars['OUTPUT_DIRECTORY']) - else: - # If no OUTPUT_PATH was specified in the Doxyfile, build path from the Doxyfile name + '.doxy' - output_node = self.inputs[0].parent.get_bld().make_node(self.inputs[0].name + '.doxy') - output_node.mkdir() - self.pars['OUTPUT_DIRECTORY'] = output_node.abspath() - - self.doxy_inputs = getattr(self, 'doxy_inputs', []) - if not self.pars.get('INPUT'): - self.doxy_inputs.append(self.inputs[0].parent) - else: - for i in self.pars.get('INPUT').split(): - if os.path.isabs(i): - node = self.generator.bld.root.find_node(i) - else: - node = self.inputs[0].parent.find_node(i) - if not node: - self.generator.bld.fatal('Could not find the doxygen input %r' % i) - self.doxy_inputs.append(node) - - if not getattr(self, 'output_dir', None): - bld = self.generator.bld - # Output path is always an absolute path as it was transformed above. - self.output_dir = bld.root.find_dir(self.pars['OUTPUT_DIRECTORY']) - - self.signature() - ret = Task.Task.runnable_status(self) - if ret == Task.SKIP_ME: - # in case the files were removed - self.add_install() - return ret - - def scan(self): - exclude_patterns = self.pars.get('EXCLUDE_PATTERNS','').split() - exclude_patterns = [pattern.replace('*/', '**/') for pattern in exclude_patterns] - file_patterns = self.pars.get('FILE_PATTERNS','').split() - if not file_patterns: - file_patterns = DOXY_FILE_PATTERNS.split() - if self.pars.get('RECURSIVE') == 'YES': - file_patterns = ["**/%s" % pattern for pattern in file_patterns] - nodes = [] - names = [] - for node in self.doxy_inputs: - if os.path.isdir(node.abspath()): - for m in node.ant_glob(incl=file_patterns, excl=exclude_patterns): - nodes.append(m) - else: - nodes.append(node) - return (nodes, names) - - def run(self): - dct = self.pars.copy() - code = '\n'.join(['%s = %s' % (x, dct[x]) for x in self.pars]) - code = code.encode() # for python 3 - #fmt = DOXY_STR % (self.inputs[0].parent.abspath()) - cmd = Utils.subst_vars(DOXY_STR, self.env) - env = self.env.env or None - proc = Utils.subprocess.Popen(cmd, shell=True, stdin=Utils.subprocess.PIPE, env=env, cwd=self.inputs[0].parent.abspath()) - proc.communicate(code) - return proc.returncode - - def post_run(self): - nodes = self.output_dir.ant_glob('**/*', quiet=True) - for x in nodes: - self.generator.bld.node_sigs[x] = self.uid() - self.add_install() - return Task.Task.post_run(self) - - def add_install(self): - nodes = self.output_dir.ant_glob('**/*', quiet=True) - self.outputs += nodes - if getattr(self.generator, 'install_path', None): - if not getattr(self.generator, 'doxy_tar', None): - self.generator.add_install_files(install_to=self.generator.install_path, - install_from=self.outputs, - postpone=False, - cwd=self.output_dir, - relative_trick=True) - -class tar(Task.Task): - "quick tar creation" - run_str = '${TAR} ${TAROPTS} ${TGT} ${SRC}' - color = 'RED' - after = ['doxygen'] - def runnable_status(self): - for x in getattr(self, 'input_tasks', []): - if not x.hasrun: - return Task.ASK_LATER - - if not getattr(self, 'tar_done_adding', None): - # execute this only once - self.tar_done_adding = True - for x in getattr(self, 'input_tasks', []): - self.set_inputs(x.outputs) - if not self.inputs: - return Task.SKIP_ME - return Task.Task.runnable_status(self) - - def __str__(self): - tgt_str = ' '.join([a.path_from(a.ctx.launch_node()) for a in self.outputs]) - return '%s: %s\n' % (self.__class__.__name__, tgt_str) - -@feature('doxygen') -def process_doxy(self): - if not getattr(self, 'doxyfile', None): - self.bld.fatal('no doxyfile variable specified??') - - node = self.doxyfile - if not isinstance(node, Node.Node): - node = self.path.find_resource(node) - if not node: - self.bld.fatal('doxygen file %s not found' % self.doxyfile) - - # the task instance - dsk = self.create_task('doxygen', node) - - if getattr(self, 'doxy_tar', None): - tsk = self.create_task('tar') - tsk.input_tasks = [dsk] - tsk.set_outputs(self.path.find_or_declare(self.doxy_tar)) - if self.doxy_tar.endswith('bz2'): - tsk.env['TAROPTS'] = ['cjf'] - elif self.doxy_tar.endswith('gz'): - tsk.env['TAROPTS'] = ['czf'] - else: - tsk.env['TAROPTS'] = ['cf'] - if getattr(self, 'install_path', None): - self.add_install_files(install_to=self.install_path, install_from=tsk.outputs) - -def configure(conf): - ''' - Check if doxygen and tar commands are present in the system - - If the commands are present, then conf.env.DOXYGEN and conf.env.TAR - variables will be set. Detection can be controlled by setting DOXYGEN and - TAR environmental variables. - ''' - - conf.find_program('doxygen', var='DOXYGEN', mandatory=False) - conf.find_program('tar', var='TAR', mandatory=False) diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/dpapi.py b/ldb-2.0.8/third_party/waf/waflib/extras/dpapi.py deleted file mode 100644 index b94d482..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/dpapi.py +++ /dev/null @@ -1,87 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Matt Clarkson, 2012 - -''' -DPAPI access library (http://msdn.microsoft.com/en-us/library/ms995355.aspx) -This file uses code originally created by Crusher Joe: -http://article.gmane.org/gmane.comp.python.ctypes/420 -And modified by Wayne Koorts: -http://stackoverflow.com/questions/463832/using-dpapi-with-python -''' - -from ctypes import windll, byref, cdll, Structure, POINTER, c_char, c_buffer -from ctypes.wintypes import DWORD -from waflib.Configure import conf - -LocalFree = windll.kernel32.LocalFree -memcpy = cdll.msvcrt.memcpy -CryptProtectData = windll.crypt32.CryptProtectData -CryptUnprotectData = windll.crypt32.CryptUnprotectData -CRYPTPROTECT_UI_FORBIDDEN = 0x01 -try: - extra_entropy = 'cl;ad13 \0al;323kjd #(adl;k$#ajsd'.encode('ascii') -except AttributeError: - extra_entropy = 'cl;ad13 \0al;323kjd #(adl;k$#ajsd' - -class DATA_BLOB(Structure): - _fields_ = [ - ('cbData', DWORD), - ('pbData', POINTER(c_char)) - ] - -def get_data(blob_out): - cbData = int(blob_out.cbData) - pbData = blob_out.pbData - buffer = c_buffer(cbData) - memcpy(buffer, pbData, cbData) - LocalFree(pbData) - return buffer.raw - -@conf -def dpapi_encrypt_data(self, input_bytes, entropy = extra_entropy): - ''' - Encrypts data and returns byte string - - :param input_bytes: The data to be encrypted - :type input_bytes: String or Bytes - :param entropy: Extra entropy to add to the encryption process (optional) - :type entropy: String or Bytes - ''' - if not isinstance(input_bytes, bytes) or not isinstance(entropy, bytes): - self.fatal('The inputs to dpapi must be bytes') - buffer_in = c_buffer(input_bytes, len(input_bytes)) - buffer_entropy = c_buffer(entropy, len(entropy)) - blob_in = DATA_BLOB(len(input_bytes), buffer_in) - blob_entropy = DATA_BLOB(len(entropy), buffer_entropy) - blob_out = DATA_BLOB() - - if CryptProtectData(byref(blob_in), 'python_data', byref(blob_entropy), - None, None, CRYPTPROTECT_UI_FORBIDDEN, byref(blob_out)): - return get_data(blob_out) - else: - self.fatal('Failed to decrypt data') - -@conf -def dpapi_decrypt_data(self, encrypted_bytes, entropy = extra_entropy): - ''' - Decrypts data and returns byte string - - :param encrypted_bytes: The encrypted data - :type encrypted_bytes: Bytes - :param entropy: Extra entropy to add to the encryption process (optional) - :type entropy: String or Bytes - ''' - if not isinstance(encrypted_bytes, bytes) or not isinstance(entropy, bytes): - self.fatal('The inputs to dpapi must be bytes') - buffer_in = c_buffer(encrypted_bytes, len(encrypted_bytes)) - buffer_entropy = c_buffer(entropy, len(entropy)) - blob_in = DATA_BLOB(len(encrypted_bytes), buffer_in) - blob_entropy = DATA_BLOB(len(entropy), buffer_entropy) - blob_out = DATA_BLOB() - if CryptUnprotectData(byref(blob_in), None, byref(blob_entropy), None, - None, CRYPTPROTECT_UI_FORBIDDEN, byref(blob_out)): - return get_data(blob_out) - else: - self.fatal('Failed to decrypt data') - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/eclipse.py b/ldb-2.0.8/third_party/waf/waflib/extras/eclipse.py deleted file mode 100644 index bb78741..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/eclipse.py +++ /dev/null @@ -1,431 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Eclipse CDT 5.0 generator for Waf -# Richard Quirk 2009-1011 (New BSD License) -# Thomas Nagy 2011 (ported to Waf 1.6) - -""" -Usage: - -def options(opt): - opt.load('eclipse') - -$ waf configure eclipse -""" - -import sys, os -from waflib import Utils, Logs, Context, Build, TaskGen, Scripting, Errors, Node -from xml.dom.minidom import Document - -STANDARD_INCLUDES = [ '/usr/local/include', '/usr/include' ] - -oe_cdt = 'org.eclipse.cdt' -cdt_mk = oe_cdt + '.make.core' -cdt_core = oe_cdt + '.core' -cdt_bld = oe_cdt + '.build.core' -extbuilder_dir = '.externalToolBuilders' -extbuilder_name = 'Waf_Builder.launch' - -class eclipse(Build.BuildContext): - cmd = 'eclipse' - fun = Scripting.default_cmd - - def execute(self): - """ - Entry point - """ - self.restore() - if not self.all_envs: - self.load_envs() - self.recurse([self.run_dir]) - - appname = getattr(Context.g_module, Context.APPNAME, os.path.basename(self.srcnode.abspath())) - self.create_cproject(appname, pythonpath=self.env['ECLIPSE_PYTHON_PATH']) - - # Helper to dump the XML document content to XML with UTF-8 encoding - def write_conf_to_xml(self, filename, document): - self.srcnode.make_node(filename).write(document.toprettyxml(encoding='UTF-8'), flags='wb') - - def create_cproject(self, appname, workspace_includes=[], pythonpath=[]): - """ - Create the Eclipse CDT .project and .cproject files - @param appname The name that will appear in the Project Explorer - @param build The BuildContext object to extract includes from - @param workspace_includes Optional project includes to prevent - "Unresolved Inclusion" errors in the Eclipse editor - @param pythonpath Optional project specific python paths - """ - hasc = hasjava = haspython = False - source_dirs = [] - cpppath = self.env['CPPPATH'] - javasrcpath = [] - javalibpath = [] - includes = STANDARD_INCLUDES - if sys.platform != 'win32': - cc = self.env.CC or self.env.CXX - if cc: - cmd = cc + ['-xc++', '-E', '-Wp,-v', '-'] - try: - gccout = self.cmd_and_log(cmd, output=Context.STDERR, quiet=Context.BOTH, input='\n'.encode()).splitlines() - except Errors.WafError: - pass - else: - includes = [] - for ipath in gccout: - if ipath.startswith(' /'): - includes.append(ipath[1:]) - cpppath += includes - Logs.warn('Generating Eclipse CDT project files') - - for g in self.groups: - for tg in g: - if not isinstance(tg, TaskGen.task_gen): - continue - - tg.post() - - # Add local Python modules paths to configuration so object resolving will work in IDE - # This may also contain generated files (ie. pyqt5 or protoc) that get picked from build - if 'py' in tg.features: - pypath = tg.path.relpath() - py_installfrom = getattr(tg, 'install_from', None) - if isinstance(py_installfrom, Node.Node): - pypath = py_installfrom.path_from(self.root.make_node(self.top_dir)) - if pypath not in pythonpath: - pythonpath.append(pypath) - haspython = True - - # Add Java source directories so object resolving works in IDE - # This may also contain generated files (ie. protoc) that get picked from build - if 'javac' in tg.features: - java_src = tg.path.relpath() - java_srcdir = getattr(tg.javac_task, 'srcdir', None) - if java_srcdir: - if isinstance(java_srcdir, Node.Node): - java_srcdir = [java_srcdir] - for x in Utils.to_list(java_srcdir): - x = x.path_from(self.root.make_node(self.top_dir)) - if x not in javasrcpath: - javasrcpath.append(x) - else: - if java_src not in javasrcpath: - javasrcpath.append(java_src) - hasjava = True - - # Check if there are external dependencies and add them as external jar so they will be resolved by Eclipse - usedlibs=getattr(tg, 'use', []) - for x in Utils.to_list(usedlibs): - for cl in Utils.to_list(tg.env['CLASSPATH_'+x]): - if cl not in javalibpath: - javalibpath.append(cl) - - if not getattr(tg, 'link_task', None): - continue - - features = Utils.to_list(getattr(tg, 'features', '')) - - is_cc = 'c' in features or 'cxx' in features - - incnodes = tg.to_incnodes(tg.to_list(getattr(tg, 'includes', [])) + tg.env['INCLUDES']) - for p in incnodes: - path = p.path_from(self.srcnode) - - if (path.startswith("/")): - cpppath.append(path) - else: - workspace_includes.append(path) - - if is_cc and path not in source_dirs: - source_dirs.append(path) - - hasc = True - - waf_executable = os.path.abspath(sys.argv[0]) - project = self.impl_create_project(sys.executable, appname, hasc, hasjava, haspython, waf_executable) - self.write_conf_to_xml('.project', project) - - if hasc: - project = self.impl_create_cproject(sys.executable, waf_executable, appname, workspace_includes, cpppath, source_dirs) - self.write_conf_to_xml('.cproject', project) - - if haspython: - project = self.impl_create_pydevproject(sys.path, pythonpath) - self.write_conf_to_xml('.pydevproject', project) - - if hasjava: - project = self.impl_create_javaproject(javasrcpath, javalibpath) - self.write_conf_to_xml('.classpath', project) - - def impl_create_project(self, executable, appname, hasc, hasjava, haspython, waf_executable): - doc = Document() - projectDescription = doc.createElement('projectDescription') - self.add(doc, projectDescription, 'name', appname) - self.add(doc, projectDescription, 'comment') - self.add(doc, projectDescription, 'projects') - buildSpec = self.add(doc, projectDescription, 'buildSpec') - buildCommand = self.add(doc, buildSpec, 'buildCommand') - self.add(doc, buildCommand, 'triggers', 'clean,full,incremental,') - arguments = self.add(doc, buildCommand, 'arguments') - dictionaries = {} - - # If CDT is present, instruct this one to call waf as it is more flexible (separate build/clean ...) - if hasc: - self.add(doc, buildCommand, 'name', oe_cdt + '.managedbuilder.core.genmakebuilder') - # the default make-style targets are overwritten by the .cproject values - dictionaries = { - cdt_mk + '.contents': cdt_mk + '.activeConfigSettings', - cdt_mk + '.enableAutoBuild': 'false', - cdt_mk + '.enableCleanBuild': 'true', - cdt_mk + '.enableFullBuild': 'true', - } - else: - # Otherwise for Java/Python an external builder tool is created that will call waf build - self.add(doc, buildCommand, 'name', 'org.eclipse.ui.externaltools.ExternalToolBuilder') - dictionaries = { - 'LaunchConfigHandle': '/%s/%s'%(extbuilder_dir, extbuilder_name), - } - # The definition is in a separate directory XML file - try: - os.mkdir(extbuilder_dir) - except OSError: - pass # Ignore error if already exists - - # Populate here the external builder XML calling waf - builder = Document() - launchConfiguration = doc.createElement('launchConfiguration') - launchConfiguration.setAttribute('type', 'org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType') - self.add(doc, launchConfiguration, 'booleanAttribute', {'key': 'org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND', 'value': 'false'}) - self.add(doc, launchConfiguration, 'booleanAttribute', {'key': 'org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED', 'value': 'true'}) - self.add(doc, launchConfiguration, 'stringAttribute', {'key': 'org.eclipse.ui.externaltools.ATTR_LOCATION', 'value': waf_executable}) - self.add(doc, launchConfiguration, 'stringAttribute', {'key': 'org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS', 'value': 'full,incremental,'}) - self.add(doc, launchConfiguration, 'stringAttribute', {'key': 'org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS', 'value': 'build'}) - self.add(doc, launchConfiguration, 'stringAttribute', {'key': 'org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY', 'value': '${project_loc}'}) - builder.appendChild(launchConfiguration) - # And write the XML to the file references before - self.write_conf_to_xml('%s%s%s'%(extbuilder_dir, os.path.sep, extbuilder_name), builder) - - - for k, v in dictionaries.items(): - self.addDictionary(doc, arguments, k, v) - - natures = self.add(doc, projectDescription, 'natures') - - if hasc: - nature_list = """ - core.ccnature - managedbuilder.core.ScannerConfigNature - managedbuilder.core.managedBuildNature - core.cnature - """.split() - for n in nature_list: - self.add(doc, natures, 'nature', oe_cdt + '.' + n) - - if haspython: - self.add(doc, natures, 'nature', 'org.python.pydev.pythonNature') - if hasjava: - self.add(doc, natures, 'nature', 'org.eclipse.jdt.core.javanature') - - doc.appendChild(projectDescription) - return doc - - def impl_create_cproject(self, executable, waf_executable, appname, workspace_includes, cpppath, source_dirs=[]): - doc = Document() - doc.appendChild(doc.createProcessingInstruction('fileVersion', '4.0.0')) - cconf_id = cdt_core + '.default.config.1' - cproject = doc.createElement('cproject') - storageModule = self.add(doc, cproject, 'storageModule', - {'moduleId': cdt_core + '.settings'}) - cconf = self.add(doc, storageModule, 'cconfiguration', {'id':cconf_id}) - - storageModule = self.add(doc, cconf, 'storageModule', - {'buildSystemId': oe_cdt + '.managedbuilder.core.configurationDataProvider', - 'id': cconf_id, - 'moduleId': cdt_core + '.settings', - 'name': 'Default'}) - - self.add(doc, storageModule, 'externalSettings') - - extensions = self.add(doc, storageModule, 'extensions') - extension_list = """ - VCErrorParser - MakeErrorParser - GCCErrorParser - GASErrorParser - GLDErrorParser - """.split() - self.add(doc, extensions, 'extension', {'id': cdt_core + '.ELF', 'point':cdt_core + '.BinaryParser'}) - for e in extension_list: - self.add(doc, extensions, 'extension', {'id': cdt_core + '.' + e, 'point':cdt_core + '.ErrorParser'}) - - storageModule = self.add(doc, cconf, 'storageModule', - {'moduleId': 'cdtBuildSystem', 'version': '4.0.0'}) - config = self.add(doc, storageModule, 'configuration', - {'artifactName': appname, - 'id': cconf_id, - 'name': 'Default', - 'parent': cdt_bld + '.prefbase.cfg'}) - folderInfo = self.add(doc, config, 'folderInfo', - {'id': cconf_id+'.', 'name': '/', 'resourcePath': ''}) - - toolChain = self.add(doc, folderInfo, 'toolChain', - {'id': cdt_bld + '.prefbase.toolchain.1', - 'name': 'No ToolChain', - 'resourceTypeBasedDiscovery': 'false', - 'superClass': cdt_bld + '.prefbase.toolchain'}) - - self.add(doc, toolChain, 'targetPlatform', {'binaryParser': 'org.eclipse.cdt.core.ELF', 'id': cdt_bld + '.prefbase.toolchain.1', 'name': ''}) - - waf_build = '"%s" %s'%(waf_executable, eclipse.fun) - waf_clean = '"%s" clean'%(waf_executable) - self.add(doc, toolChain, 'builder', - {'autoBuildTarget': waf_build, - 'command': executable, - 'enableAutoBuild': 'false', - 'cleanBuildTarget': waf_clean, - 'enableIncrementalBuild': 'true', - 'id': cdt_bld + '.settings.default.builder.1', - 'incrementalBuildTarget': waf_build, - 'managedBuildOn': 'false', - 'name': 'Gnu Make Builder', - 'superClass': cdt_bld + '.settings.default.builder'}) - - tool_index = 1; - for tool_name in ("Assembly", "GNU C++", "GNU C"): - tool = self.add(doc, toolChain, 'tool', - {'id': cdt_bld + '.settings.holder.' + str(tool_index), - 'name': tool_name, - 'superClass': cdt_bld + '.settings.holder'}) - if cpppath or workspace_includes: - incpaths = cdt_bld + '.settings.holder.incpaths' - option = self.add(doc, tool, 'option', - {'id': incpaths + '.' + str(tool_index), - 'name': 'Include Paths', - 'superClass': incpaths, - 'valueType': 'includePath'}) - for i in workspace_includes: - self.add(doc, option, 'listOptionValue', - {'builtIn': 'false', - 'value': '"${workspace_loc:/%s/%s}"'%(appname, i)}) - for i in cpppath: - self.add(doc, option, 'listOptionValue', - {'builtIn': 'false', - 'value': '"%s"'%(i)}) - if tool_name == "GNU C++" or tool_name == "GNU C": - self.add(doc,tool,'inputType',{ 'id':'org.eclipse.cdt.build.core.settings.holder.inType.' + str(tool_index), \ - 'languageId':'org.eclipse.cdt.core.gcc' if tool_name == "GNU C" else 'org.eclipse.cdt.core.g++','languageName':tool_name, \ - 'sourceContentType':'org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader', \ - 'superClass':'org.eclipse.cdt.build.core.settings.holder.inType' }) - tool_index += 1 - - if source_dirs: - sourceEntries = self.add(doc, config, 'sourceEntries') - for i in source_dirs: - self.add(doc, sourceEntries, 'entry', - {'excluding': i, - 'flags': 'VALUE_WORKSPACE_PATH|RESOLVED', - 'kind': 'sourcePath', - 'name': ''}) - self.add(doc, sourceEntries, 'entry', - { - 'flags': 'VALUE_WORKSPACE_PATH|RESOLVED', - 'kind': 'sourcePath', - 'name': i}) - - storageModule = self.add(doc, cconf, 'storageModule', - {'moduleId': cdt_mk + '.buildtargets'}) - buildTargets = self.add(doc, storageModule, 'buildTargets') - def addTargetWrap(name, runAll): - return self.addTarget(doc, buildTargets, executable, name, - '"%s" %s'%(waf_executable, name), runAll) - addTargetWrap('configure', True) - addTargetWrap('dist', False) - addTargetWrap('install', False) - addTargetWrap('check', False) - - storageModule = self.add(doc, cproject, 'storageModule', - {'moduleId': 'cdtBuildSystem', - 'version': '4.0.0'}) - - self.add(doc, storageModule, 'project', {'id': '%s.null.1'%appname, 'name': appname}) - - doc.appendChild(cproject) - return doc - - def impl_create_pydevproject(self, system_path, user_path): - # create a pydevproject file - doc = Document() - doc.appendChild(doc.createProcessingInstruction('eclipse-pydev', 'version="1.0"')) - pydevproject = doc.createElement('pydev_project') - prop = self.add(doc, pydevproject, - 'pydev_property', - 'python %d.%d'%(sys.version_info[0], sys.version_info[1])) - prop.setAttribute('name', 'org.python.pydev.PYTHON_PROJECT_VERSION') - prop = self.add(doc, pydevproject, 'pydev_property', 'Default') - prop.setAttribute('name', 'org.python.pydev.PYTHON_PROJECT_INTERPRETER') - # add waf's paths - wafadmin = [p for p in system_path if p.find('wafadmin') != -1] - if wafadmin: - prop = self.add(doc, pydevproject, 'pydev_pathproperty', - {'name':'org.python.pydev.PROJECT_EXTERNAL_SOURCE_PATH'}) - for i in wafadmin: - self.add(doc, prop, 'path', i) - if user_path: - prop = self.add(doc, pydevproject, 'pydev_pathproperty', - {'name':'org.python.pydev.PROJECT_SOURCE_PATH'}) - for i in user_path: - self.add(doc, prop, 'path', '/${PROJECT_DIR_NAME}/'+i) - - doc.appendChild(pydevproject) - return doc - - def impl_create_javaproject(self, javasrcpath, javalibpath): - # create a .classpath file for java usage - doc = Document() - javaproject = doc.createElement('classpath') - if javasrcpath: - for i in javasrcpath: - self.add(doc, javaproject, 'classpathentry', - {'kind': 'src', 'path': i}) - - if javalibpath: - for i in javalibpath: - self.add(doc, javaproject, 'classpathentry', - {'kind': 'lib', 'path': i}) - - self.add(doc, javaproject, 'classpathentry', {'kind': 'con', 'path': 'org.eclipse.jdt.launching.JRE_CONTAINER'}) - self.add(doc, javaproject, 'classpathentry', {'kind': 'output', 'path': self.bldnode.name }) - doc.appendChild(javaproject) - return doc - - def addDictionary(self, doc, parent, k, v): - dictionary = self.add(doc, parent, 'dictionary') - self.add(doc, dictionary, 'key', k) - self.add(doc, dictionary, 'value', v) - return dictionary - - def addTarget(self, doc, buildTargets, executable, name, buildTarget, runAllBuilders=True): - target = self.add(doc, buildTargets, 'target', - {'name': name, - 'path': '', - 'targetID': oe_cdt + '.build.MakeTargetBuilder'}) - self.add(doc, target, 'buildCommand', executable) - self.add(doc, target, 'buildArguments', None) - self.add(doc, target, 'buildTarget', buildTarget) - self.add(doc, target, 'stopOnError', 'true') - self.add(doc, target, 'useDefaultCommand', 'false') - self.add(doc, target, 'runAllBuilders', str(runAllBuilders).lower()) - - def add(self, doc, parent, tag, value = None): - el = doc.createElement(tag) - if (value): - if type(value) == type(str()): - el.appendChild(doc.createTextNode(value)) - elif type(value) == type(dict()): - self.setAttributes(el, value) - parent.appendChild(el) - return el - - def setAttributes(self, node, attrs): - for k, v in attrs.items(): - node.setAttribute(k, v) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/erlang.py b/ldb-2.0.8/third_party/waf/waflib/extras/erlang.py deleted file mode 100644 index 0b93d9a..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/erlang.py +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2010 (ita) -# Przemyslaw Rzepecki, 2016 - -""" -Erlang support -""" - -import re -from waflib import Task, TaskGen -from waflib.TaskGen import feature, after_method, before_method -# to load the method "to_incnodes" below -from waflib.Tools import ccroot - -# Those flags are required by the Erlang VM to execute/evaluate code in -# non-interactive mode. It is used in this tool to create Erlang modules -# documentation and run unit tests. The user can pass additional arguments to the -# 'erl' command with ERL_FLAGS environment variable. -EXEC_NON_INTERACTIVE = ['-noshell', '-noinput', '-eval'] - -def configure(conf): - conf.find_program('erlc', var='ERLC') - conf.find_program('erl', var='ERL') - conf.add_os_flags('ERLC_FLAGS') - conf.add_os_flags('ERL_FLAGS') - conf.env.ERLC_DEF_PATTERN = '-D%s' - conf.env.ERLC_INC_PATTERN = '-I%s' - -@TaskGen.extension('.erl') -def process_erl_node(self, node): - tsk = self.create_task('erl', node, node.change_ext('.beam')) - tsk.erlc_incnodes = [tsk.outputs[0].parent] + self.to_incnodes(self.includes) - tsk.env.append_value('ERLC_INCPATHS', [x.abspath() for x in tsk.erlc_incnodes]) - tsk.env.append_value('ERLC_DEFINES', self.to_list(getattr(self, 'defines', []))) - tsk.env.append_value('ERLC_FLAGS', self.to_list(getattr(self, 'flags', []))) - tsk.cwd = tsk.outputs[0].parent - -class erl(Task.Task): - color = 'GREEN' - run_str = '${ERLC} ${ERL_FLAGS} ${ERLC_INC_PATTERN:ERLC_INCPATHS} ${ERLC_DEF_PATTERN:ERLC_DEFINES} ${SRC}' - - def scan(task): - node = task.inputs[0] - - deps = [] - scanned = set([]) - nodes_to_scan = [node] - - for n in nodes_to_scan: - if n.abspath() in scanned: - continue - - for i in re.findall(r'-include\("(.*)"\)\.', n.read()): - for d in task.erlc_incnodes: - r = d.find_node(i) - if r: - deps.append(r) - nodes_to_scan.append(r) - break - scanned.add(n.abspath()) - - return (deps, []) - -@TaskGen.extension('.beam') -def process(self, node): - pass - - -class erl_test(Task.Task): - color = 'BLUE' - run_str = '${ERL} ${ERL_FLAGS} ${ERL_TEST_FLAGS}' - -@feature('eunit') -@after_method('process_source') -def add_erl_test_run(self): - test_modules = [t.outputs[0] for t in self.tasks] - test_task = self.create_task('erl_test') - test_task.set_inputs(self.source + test_modules) - test_task.cwd = test_modules[0].parent - - test_task.env.append_value('ERL_FLAGS', self.to_list(getattr(self, 'flags', []))) - - test_list = ", ".join([m.change_ext("").path_from(test_task.cwd)+":test()" for m in test_modules]) - test_flag = 'halt(case lists:all(fun(Elem) -> Elem == ok end, [%s]) of true -> 0; false -> 1 end).' % test_list - test_task.env.append_value('ERL_TEST_FLAGS', EXEC_NON_INTERACTIVE) - test_task.env.append_value('ERL_TEST_FLAGS', test_flag) - - -class edoc(Task.Task): - color = 'BLUE' - run_str = "${ERL} ${ERL_FLAGS} ${ERL_DOC_FLAGS}" - def keyword(self): - return 'Generating edoc' - -@feature('edoc') -@before_method('process_source') -def add_edoc_task(self): - # do not process source, it would create double erl->beam task - self.meths.remove('process_source') - e = self.path.find_resource(self.source) - t = e.change_ext('.html') - png = t.parent.make_node('erlang.png') - css = t.parent.make_node('stylesheet.css') - tsk = self.create_task('edoc', e, [t, png, css]) - tsk.cwd = tsk.outputs[0].parent - tsk.env.append_value('ERL_DOC_FLAGS', EXEC_NON_INTERACTIVE) - tsk.env.append_value('ERL_DOC_FLAGS', 'edoc:files(["%s"]), halt(0).' % tsk.inputs[0].abspath()) - # TODO the above can break if a file path contains '"' - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fast_partial.py b/ldb-2.0.8/third_party/waf/waflib/extras/fast_partial.py deleted file mode 100644 index 90a9472..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/fast_partial.py +++ /dev/null @@ -1,531 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2017-2018 (ita) - -""" -A system for fast partial rebuilds - -Creating a large amount of task objects up front can take some time. -By making a few assumptions, it is possible to avoid posting creating -task objects for targets that are already up-to-date. - -On a silly benchmark the gain observed for 1M tasks can be 5m->10s -for a single file change. - -Usage:: - - def options(opt): - opt.load('fast_partial') - -Assumptions: -* Start with a clean build (run "waf distclean" after enabling) -* Mostly for C/C++/Fortran targets with link tasks (object-only targets are not handled) - try it in the folder generated by utils/genbench.py -* For full project builds: no --targets and no pruning from subfolders -* The installation phase is ignored -* `use=` dependencies are specified up front even across build groups -* Task generator source files are not obtained from globs - -Implementation details: -* The first layer obtains file timestamps to recalculate file hashes only - when necessary (similar to md5_tstamp); the timestamps are then stored - in a dedicated pickle file -* A second layer associates each task generator to a file set to help - detecting changes. Task generators are to create their tasks only when - the related files have been modified. A specific db file is created - to store such data (5m -> 1m10) -* A third layer binds build context proxies onto task generators, replacing - the default context. While loading data for the full build uses more memory - (4GB -> 9GB), partial builds are then much faster (1m10 -> 13s) -* A fourth layer enables a 2-level cache on file signatures to - reduce the size of the main pickle file (13s -> 10s) -""" - -import os -from waflib import Build, Context, Errors, Logs, Task, TaskGen, Utils -from waflib.TaskGen import feature, after_method, taskgen_method -import waflib.Node - -DONE = 0 -DIRTY = 1 -NEEDED = 2 - -SKIPPABLE = ['cshlib', 'cxxshlib', 'cstlib', 'cxxstlib', 'cprogram', 'cxxprogram'] - -TSTAMP_DB = '.wafpickle_tstamp_db_file' - -SAVED_ATTRS = 'root node_sigs task_sigs imp_sigs raw_deps node_deps'.split() - -class bld_proxy(object): - def __init__(self, bld): - object.__setattr__(self, 'bld', bld) - - object.__setattr__(self, 'node_class', type('Nod3', (waflib.Node.Node,), {})) - self.node_class.__module__ = 'waflib.Node' - self.node_class.ctx = self - - object.__setattr__(self, 'root', self.node_class('', None)) - for x in SAVED_ATTRS: - if x != 'root': - object.__setattr__(self, x, {}) - - self.fix_nodes() - - def __setattr__(self, name, value): - bld = object.__getattribute__(self, 'bld') - setattr(bld, name, value) - - def __delattr__(self, name): - bld = object.__getattribute__(self, 'bld') - delattr(bld, name) - - def __getattribute__(self, name): - try: - return object.__getattribute__(self, name) - except AttributeError: - bld = object.__getattribute__(self, 'bld') - return getattr(bld, name) - - def __call__(self, *k, **kw): - return self.bld(*k, **kw) - - def fix_nodes(self): - for x in ('srcnode', 'path', 'bldnode'): - node = self.root.find_dir(getattr(self.bld, x).abspath()) - object.__setattr__(self, x, node) - - def set_key(self, store_key): - object.__setattr__(self, 'store_key', store_key) - - def fix_tg_path(self, *tgs): - # changing Node objects on task generators is possible - # yet, all Node objects must belong to the same parent - for tg in tgs: - tg.path = self.root.make_node(tg.path.abspath()) - - def restore(self): - dbfn = os.path.join(self.variant_dir, Context.DBFILE + self.store_key) - Logs.debug('rev_use: reading %s', dbfn) - try: - data = Utils.readf(dbfn, 'rb') - except (EnvironmentError, EOFError): - # handle missing file/empty file - Logs.debug('rev_use: Could not load the build cache %s (missing)', dbfn) - else: - try: - waflib.Node.pickle_lock.acquire() - waflib.Node.Nod3 = self.node_class - try: - data = Build.cPickle.loads(data) - except Exception as e: - Logs.debug('rev_use: Could not pickle the build cache %s: %r', dbfn, e) - else: - for x in SAVED_ATTRS: - object.__setattr__(self, x, data.get(x, {})) - finally: - waflib.Node.pickle_lock.release() - self.fix_nodes() - - def store(self): - data = {} - for x in Build.SAVED_ATTRS: - data[x] = getattr(self, x) - db = os.path.join(self.variant_dir, Context.DBFILE + self.store_key) - - with waflib.Node.pickle_lock: - waflib.Node.Nod3 = self.node_class - try: - x = Build.cPickle.dumps(data, Build.PROTOCOL) - except Build.cPickle.PicklingError: - root = data['root'] - for node_deps in data['node_deps'].values(): - for idx, node in enumerate(node_deps): - # there may be more cross-context Node objects to fix, - # but this should be the main source - node_deps[idx] = root.find_node(node.abspath()) - x = Build.cPickle.dumps(data, Build.PROTOCOL) - - Logs.debug('rev_use: storing %s', db) - Utils.writef(db + '.tmp', x, m='wb') - try: - st = os.stat(db) - os.remove(db) - if not Utils.is_win32: - os.chown(db + '.tmp', st.st_uid, st.st_gid) - except (AttributeError, OSError): - pass - os.rename(db + '.tmp', db) - -class bld(Build.BuildContext): - def __init__(self, **kw): - super(bld, self).__init__(**kw) - self.hashes_md5_tstamp = {} - - def __call__(self, *k, **kw): - # this is one way of doing it, one could use a task generator method too - bld = kw['bld'] = bld_proxy(self) - ret = TaskGen.task_gen(*k, **kw) - self.task_gen_cache_names = {} - self.add_to_group(ret, group=kw.get('group')) - ret.bld = bld - bld.set_key(ret.path.abspath().replace(os.sep, '') + str(ret.idx)) - return ret - - def is_dirty(self): - return True - - def store_tstamps(self): - # Called after a build is finished - # For each task generator, record all files involved in task objects - # optimization: done only if there was something built - do_store = False - try: - f_deps = self.f_deps - except AttributeError: - f_deps = self.f_deps = {} - self.f_tstamps = {} - - allfiles = set() - for g in self.groups: - for tg in g: - try: - staleness = tg.staleness - except AttributeError: - staleness = DIRTY - - if staleness != DIRTY: - # DONE case: there was nothing built - # NEEDED case: the tg was brought in because of 'use' propagation - # but nothing really changed for them, there may be incomplete - # tasks (object files) and in this case it is best to let the next build - # figure out if an input/output file changed - continue - - do_cache = False - for tsk in tg.tasks: - if tsk.hasrun == Task.SUCCESS: - do_cache = True - pass - elif tsk.hasrun == Task.SKIPPED: - pass - else: - # one failed task, clear the cache for this tg - try: - del f_deps[(tg.path.abspath(), tg.idx)] - except KeyError: - pass - else: - # just store the new state because there is a change - do_store = True - - # skip the rest because there is no valid cache possible - break - else: - if not do_cache: - # all skipped, but is there anything in cache? - try: - f_deps[(tg.path.abspath(), tg.idx)] - except KeyError: - # probably cleared because a wscript file changed - # store it - do_cache = True - - if do_cache: - - # there was a rebuild, store the data structure too - tg.bld.store() - - # all tasks skipped but no cache - # or a successful task build - do_store = True - st = set() - for tsk in tg.tasks: - st.update(tsk.inputs) - st.update(self.node_deps.get(tsk.uid(), [])) - - # TODO do last/when loading the tgs? - lst = [] - for k in ('wscript', 'wscript_build'): - n = tg.path.find_node(k) - if n: - n.get_bld_sig() - lst.append(n.abspath()) - - lst.extend(sorted(x.abspath() for x in st)) - allfiles.update(lst) - f_deps[(tg.path.abspath(), tg.idx)] = lst - - for x in allfiles: - # f_tstamps has everything, while md5_tstamp can be relatively empty on partial builds - self.f_tstamps[x] = self.hashes_md5_tstamp[x][0] - - if do_store: - dbfn = os.path.join(self.variant_dir, TSTAMP_DB) - Logs.debug('rev_use: storing %s', dbfn) - dbfn_tmp = dbfn + '.tmp' - x = Build.cPickle.dumps([self.f_tstamps, f_deps], Build.PROTOCOL) - Utils.writef(dbfn_tmp, x, m='wb') - os.rename(dbfn_tmp, dbfn) - Logs.debug('rev_use: stored %s', dbfn) - - def store(self): - self.store_tstamps() - if self.producer.dirty: - Build.BuildContext.store(self) - - def compute_needed_tgs(self): - # assume the 'use' keys are not modified during the build phase - - dbfn = os.path.join(self.variant_dir, TSTAMP_DB) - Logs.debug('rev_use: Loading %s', dbfn) - try: - data = Utils.readf(dbfn, 'rb') - except (EnvironmentError, EOFError): - Logs.debug('rev_use: Could not load the build cache %s (missing)', dbfn) - self.f_deps = {} - self.f_tstamps = {} - else: - try: - self.f_tstamps, self.f_deps = Build.cPickle.loads(data) - except Exception as e: - Logs.debug('rev_use: Could not pickle the build cache %s: %r', dbfn, e) - self.f_deps = {} - self.f_tstamps = {} - else: - Logs.debug('rev_use: Loaded %s', dbfn) - - - # 1. obtain task generators that contain rebuilds - # 2. obtain the 'use' graph and its dual - stales = set() - reverse_use_map = Utils.defaultdict(list) - use_map = Utils.defaultdict(list) - - for g in self.groups: - for tg in g: - if tg.is_stale(): - stales.add(tg) - - try: - lst = tg.use = Utils.to_list(tg.use) - except AttributeError: - pass - else: - for x in lst: - try: - xtg = self.get_tgen_by_name(x) - except Errors.WafError: - pass - else: - use_map[tg].append(xtg) - reverse_use_map[xtg].append(tg) - - Logs.debug('rev_use: found %r stale tgs', len(stales)) - - # 3. dfs to post downstream tg as stale - visited = set() - def mark_down(tg): - if tg in visited: - return - visited.add(tg) - Logs.debug('rev_use: marking down %r as stale', tg.name) - tg.staleness = DIRTY - for x in reverse_use_map[tg]: - mark_down(x) - for tg in stales: - mark_down(tg) - - # 4. dfs to find ancestors tg to mark as needed - self.needed_tgs = needed_tgs = set() - def mark_needed(tg): - if tg in needed_tgs: - return - needed_tgs.add(tg) - if tg.staleness == DONE: - Logs.debug('rev_use: marking up %r as needed', tg.name) - tg.staleness = NEEDED - for x in use_map[tg]: - mark_needed(x) - for xx in visited: - mark_needed(xx) - - # so we have the whole tg trees to post in the set "needed" - # load their build trees - for tg in needed_tgs: - tg.bld.restore() - tg.bld.fix_tg_path(tg) - - # the stale ones should be fully build, while the needed ones - # may skip a few tasks, see create_compiled_task and apply_link_after below - Logs.debug('rev_use: amount of needed task gens: %r', len(needed_tgs)) - - def post_group(self): - # assumption: we can ignore the folder/subfolders cuts - def tgpost(tg): - try: - f = tg.post - except AttributeError: - pass - else: - f() - - if not self.targets or self.targets == '*': - for tg in self.groups[self.current_group]: - # this can cut quite a lot of tg objects - if tg in self.needed_tgs: - tgpost(tg) - else: - # default implementation - return Build.BuildContext.post_group() - - def get_build_iterator(self): - if not self.targets or self.targets == '*': - self.compute_needed_tgs() - return Build.BuildContext.get_build_iterator(self) - -@taskgen_method -def is_stale(self): - # assume no globs - self.staleness = DIRTY - - # 1. the case of always stale targets - if getattr(self, 'always_stale', False): - return True - - # 2. check if the db file exists - db = os.path.join(self.bld.variant_dir, Context.DBFILE) - try: - dbstat = os.stat(db).st_mtime - except OSError: - Logs.debug('rev_use: must post %r because this is a clean build') - return True - - # 3.a check if the configuration exists - cache_node = self.bld.bldnode.find_node('c4che/build.config.py') - if not cache_node: - return True - - # 3.b check if the configuration changed - if os.stat(cache_node.abspath()).st_mtime > dbstat: - Logs.debug('rev_use: must post %r because the configuration has changed', self.name) - return True - - # 3.c any tstamp data? - try: - f_deps = self.bld.f_deps - except AttributeError: - Logs.debug('rev_use: must post %r because there is no f_deps', self.name) - return True - - # 4. check if this is the first build (no cache) - try: - lst = f_deps[(self.path.abspath(), self.idx)] - except KeyError: - Logs.debug('rev_use: must post %r because there it has no cached data', self.name) - return True - - try: - cache = self.bld.cache_tstamp_rev_use - except AttributeError: - cache = self.bld.cache_tstamp_rev_use = {} - - # 5. check the timestamp of each dependency files listed is unchanged - f_tstamps = self.bld.f_tstamps - for x in lst: - try: - old_ts = f_tstamps[x] - except KeyError: - Logs.debug('rev_use: must post %r because %r is not in cache', self.name, x) - return True - - try: - try: - ts = cache[x] - except KeyError: - ts = cache[x] = os.stat(x).st_mtime - except OSError: - del f_deps[(self.path.abspath(), self.idx)] - Logs.debug('rev_use: must post %r because %r does not exist anymore', self.name, x) - return True - else: - if ts != old_ts: - Logs.debug('rev_use: must post %r because the timestamp on %r changed %r %r', self.name, x, old_ts, ts) - return True - - self.staleness = DONE - return False - -@taskgen_method -def create_compiled_task(self, name, node): - # skip the creation of object files - # assumption: object-only targets are not skippable - if self.staleness == NEEDED: - # only libraries/programs can skip object files - for x in SKIPPABLE: - if x in self.features: - return None - - out = '%s.%d.o' % (node.name, self.idx) - task = self.create_task(name, node, node.parent.find_or_declare(out)) - try: - self.compiled_tasks.append(task) - except AttributeError: - self.compiled_tasks = [task] - return task - -@feature(*SKIPPABLE) -@after_method('apply_link') -def apply_link_after(self): - # cprogram/cxxprogram might be unnecessary - if self.staleness != NEEDED: - return - for tsk in self.tasks: - tsk.hasrun = Task.SKIPPED - -def path_from(self, node): - # handle nodes of distinct types - if node.ctx is not self.ctx: - node = self.ctx.root.make_node(node.abspath()) - return self.default_path_from(node) -waflib.Node.Node.default_path_from = waflib.Node.Node.path_from -waflib.Node.Node.path_from = path_from - -def h_file(self): - # similar to md5_tstamp.py, but with 2-layer cache - # global_cache for the build context common for all task generators - # local_cache for the build context proxy (one by task generator) - # - # the global cache is not persistent - # the local cache is persistent and meant for partial builds - # - # assume all calls are made from a single thread - # - filename = self.abspath() - st = os.stat(filename) - - global_cache = self.ctx.bld.hashes_md5_tstamp - local_cache = self.ctx.hashes_md5_tstamp - - if filename in global_cache: - # value already calculated in this build - cval = global_cache[filename] - - # the value in global cache is assumed to be calculated once - # reverifying it could cause task generators - # to get distinct tstamp values, thus missing rebuilds - local_cache[filename] = cval - return cval[1] - - if filename in local_cache: - cval = local_cache[filename] - if cval[0] == st.st_mtime: - # correct value from a previous build - # put it in the global cache - global_cache[filename] = cval - return cval[1] - - ret = Utils.h_file(filename) - local_cache[filename] = global_cache[filename] = (st.st_mtime, ret) - return ret -waflib.Node.Node.h_file = h_file - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fc_bgxlf.py b/ldb-2.0.8/third_party/waf/waflib/extras/fc_bgxlf.py deleted file mode 100644 index cca1810..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/fc_bgxlf.py +++ /dev/null @@ -1,32 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# harald at klimachs.de - -from waflib.Tools import fc, fc_config, fc_scan -from waflib.Configure import conf - -from waflib.Tools.compiler_fc import fc_compiler -fc_compiler['linux'].insert(0, 'fc_bgxlf') - -@conf -def find_bgxlf(conf): - fc = conf.find_program(['bgxlf2003_r','bgxlf2003'], var='FC') - conf.get_xlf_version(fc) - conf.env.FC_NAME = 'BGXLF' - -@conf -def bg_flags(self): - self.env.SONAME_ST = '' - self.env.FCSHLIB_MARKER = '' - self.env.FCSTLIB_MARKER = '' - self.env.FCFLAGS_fcshlib = ['-fPIC'] - self.env.LINKFLAGS_fcshlib = ['-G', '-Wl,-bexpfull'] - -def configure(conf): - conf.find_bgxlf() - conf.find_ar() - conf.fc_flags() - conf.fc_add_flags() - conf.xlf_flags() - conf.bg_flags() - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fc_cray.py b/ldb-2.0.8/third_party/waf/waflib/extras/fc_cray.py deleted file mode 100644 index da733fa..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/fc_cray.py +++ /dev/null @@ -1,51 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# harald at klimachs.de - -import re -from waflib.Tools import fc, fc_config, fc_scan -from waflib.Configure import conf - -from waflib.Tools.compiler_fc import fc_compiler -fc_compiler['linux'].append('fc_cray') - -@conf -def find_crayftn(conf): - """Find the Cray fortran compiler (will look in the environment variable 'FC')""" - fc = conf.find_program(['crayftn'], var='FC') - conf.get_crayftn_version(fc) - conf.env.FC_NAME = 'CRAY' - conf.env.FC_MOD_CAPITALIZATION = 'UPPER.mod' - -@conf -def crayftn_flags(conf): - v = conf.env - v['_FCMODOUTFLAGS'] = ['-em', '-J.'] # enable module files and put them in the current directory - v['FCFLAGS_DEBUG'] = ['-m1'] # more verbose compiler warnings - v['FCFLAGS_fcshlib'] = ['-h pic'] - v['LINKFLAGS_fcshlib'] = ['-h shared'] - - v['FCSTLIB_MARKER'] = '-h static' - v['FCSHLIB_MARKER'] = '-h dynamic' - -@conf -def get_crayftn_version(conf, fc): - version_re = re.compile(r"Cray Fortran\s*:\s*Version\s*(?P\d*)\.(?P\d*)", re.I).search - cmd = fc + ['-V'] - out,err = fc_config.getoutput(conf, cmd, stdin=False) - if out: - match = version_re(out) - else: - match = version_re(err) - if not match: - conf.fatal('Could not determine the Cray Fortran compiler version.') - k = match.groupdict() - conf.env['FC_VERSION'] = (k['major'], k['minor']) - -def configure(conf): - conf.find_crayftn() - conf.find_ar() - conf.fc_flags() - conf.fc_add_flags() - conf.crayftn_flags() - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fc_nag.py b/ldb-2.0.8/third_party/waf/waflib/extras/fc_nag.py deleted file mode 100644 index edcb218..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/fc_nag.py +++ /dev/null @@ -1,61 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# harald at klimachs.de - -import re -from waflib import Utils -from waflib.Tools import fc,fc_config,fc_scan -from waflib.Configure import conf - -from waflib.Tools.compiler_fc import fc_compiler -fc_compiler['linux'].insert(0, 'fc_nag') - -@conf -def find_nag(conf): - """Find the NAG Fortran Compiler (will look in the environment variable 'FC')""" - - fc = conf.find_program(['nagfor'], var='FC') - conf.get_nag_version(fc) - conf.env.FC_NAME = 'NAG' - conf.env.FC_MOD_CAPITALIZATION = 'lower' - -@conf -def nag_flags(conf): - v = conf.env - v.FCFLAGS_DEBUG = ['-C=all'] - v.FCLNK_TGT_F = ['-o', ''] - v.FC_TGT_F = ['-c', '-o', ''] - -@conf -def nag_modifier_platform(conf): - dest_os = conf.env['DEST_OS'] or Utils.unversioned_sys_platform() - nag_modifier_func = getattr(conf, 'nag_modifier_' + dest_os, None) - if nag_modifier_func: - nag_modifier_func() - -@conf -def get_nag_version(conf, fc): - """Get the NAG compiler version""" - - version_re = re.compile(r"^NAG Fortran Compiler *Release *(?P\d*)\.(?P\d*)", re.M).search - cmd = fc + ['-V'] - - out, err = fc_config.getoutput(conf,cmd,stdin=False) - if out: - match = version_re(out) - if not match: - match = version_re(err) - else: match = version_re(err) - if not match: - conf.fatal('Could not determine the NAG version.') - k = match.groupdict() - conf.env['FC_VERSION'] = (k['major'], k['minor']) - -def configure(conf): - conf.find_nag() - conf.find_ar() - conf.fc_flags() - conf.fc_add_flags() - conf.nag_flags() - conf.nag_modifier_platform() - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fc_nec.py b/ldb-2.0.8/third_party/waf/waflib/extras/fc_nec.py deleted file mode 100644 index 67c8680..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/fc_nec.py +++ /dev/null @@ -1,60 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# harald at klimachs.de - -import re -from waflib.Tools import fc, fc_config, fc_scan -from waflib.Configure import conf - -from waflib.Tools.compiler_fc import fc_compiler -fc_compiler['linux'].append('fc_nec') - -@conf -def find_sxfc(conf): - """Find the NEC fortran compiler (will look in the environment variable 'FC')""" - fc = conf.find_program(['sxf90','sxf03'], var='FC') - conf.get_sxfc_version(fc) - conf.env.FC_NAME = 'NEC' - conf.env.FC_MOD_CAPITALIZATION = 'lower' - -@conf -def sxfc_flags(conf): - v = conf.env - v['_FCMODOUTFLAGS'] = [] # enable module files and put them in the current directory - v['FCFLAGS_DEBUG'] = [] # more verbose compiler warnings - v['FCFLAGS_fcshlib'] = [] - v['LINKFLAGS_fcshlib'] = [] - - v['FCSTLIB_MARKER'] = '' - v['FCSHLIB_MARKER'] = '' - -@conf -def get_sxfc_version(conf, fc): - version_re = re.compile(r"FORTRAN90/SX\s*Version\s*(?P\d*)\.(?P\d*)", re.I).search - cmd = fc + ['-V'] - out,err = fc_config.getoutput(conf, cmd, stdin=False) - if out: - match = version_re(out) - else: - match = version_re(err) - if not match: - version_re=re.compile(r"NEC Fortran 2003 Compiler for\s*(?P\S*)\s*\(c\)\s*(?P\d*)",re.I).search - if out: - match = version_re(out) - else: - match = version_re(err) - if not match: - conf.fatal('Could not determine the NEC Fortran compiler version.') - k = match.groupdict() - conf.env['FC_VERSION'] = (k['major'], k['minor']) - -def configure(conf): - conf.find_sxfc() - conf.find_program('sxar',var='AR') - conf.add_os_flags('ARFLAGS') - if not conf.env.ARFLAGS: - conf.env.ARFLAGS=['rcs'] - - conf.fc_flags() - conf.fc_add_flags() - conf.sxfc_flags() diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fc_nfort.py b/ldb-2.0.8/third_party/waf/waflib/extras/fc_nfort.py deleted file mode 100644 index c25886b..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/fc_nfort.py +++ /dev/null @@ -1,52 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Detection of the NEC Fortran compiler for Aurora Tsubasa - -import re -from waflib.Tools import fc,fc_config,fc_scan -from waflib.Configure import conf -from waflib.Tools.compiler_fc import fc_compiler -fc_compiler['linux'].append('fc_nfort') - -@conf -def find_nfort(conf): - fc=conf.find_program(['nfort'],var='FC') - conf.get_nfort_version(fc) - conf.env.FC_NAME='NFORT' - conf.env.FC_MOD_CAPITALIZATION='lower' - -@conf -def nfort_flags(conf): - v=conf.env - v['_FCMODOUTFLAGS']=[] - v['FCFLAGS_DEBUG']=[] - v['FCFLAGS_fcshlib']=[] - v['LINKFLAGS_fcshlib']=[] - v['FCSTLIB_MARKER']='' - v['FCSHLIB_MARKER']='' - -@conf -def get_nfort_version(conf,fc): - version_re=re.compile(r"nfort\s*\(NFORT\)\s*(?P\d+)\.(?P\d+)\.",re.I).search - cmd=fc+['--version'] - out,err=fc_config.getoutput(conf,cmd,stdin=False) - if out: - match=version_re(out) - else: - match=version_re(err) - if not match: - return(False) - conf.fatal('Could not determine the NEC NFORT Fortran compiler version.') - else: - k=match.groupdict() - conf.env['FC_VERSION']=(k['major'],k['minor']) - -def configure(conf): - conf.find_nfort() - conf.find_program('nar',var='AR') - conf.add_os_flags('ARFLAGS') - if not conf.env.ARFLAGS: - conf.env.ARFLAGS=['rcs'] - conf.fc_flags() - conf.fc_add_flags() - conf.nfort_flags() diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fc_open64.py b/ldb-2.0.8/third_party/waf/waflib/extras/fc_open64.py deleted file mode 100644 index 413719f..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/fc_open64.py +++ /dev/null @@ -1,58 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# harald at klimachs.de - -import re -from waflib import Utils -from waflib.Tools import fc,fc_config,fc_scan -from waflib.Configure import conf - -from waflib.Tools.compiler_fc import fc_compiler -fc_compiler['linux'].insert(0, 'fc_open64') - -@conf -def find_openf95(conf): - """Find the Open64 Fortran Compiler (will look in the environment variable 'FC')""" - - fc = conf.find_program(['openf95', 'openf90'], var='FC') - conf.get_open64_version(fc) - conf.env.FC_NAME = 'OPEN64' - conf.env.FC_MOD_CAPITALIZATION = 'UPPER.mod' - -@conf -def openf95_flags(conf): - v = conf.env - v['FCFLAGS_DEBUG'] = ['-fullwarn'] - -@conf -def openf95_modifier_platform(conf): - dest_os = conf.env['DEST_OS'] or Utils.unversioned_sys_platform() - openf95_modifier_func = getattr(conf, 'openf95_modifier_' + dest_os, None) - if openf95_modifier_func: - openf95_modifier_func() - -@conf -def get_open64_version(conf, fc): - """Get the Open64 compiler version""" - - version_re = re.compile(r"Open64 Compiler Suite: *Version *(?P\d*)\.(?P\d*)", re.I).search - cmd = fc + ['-version'] - - out, err = fc_config.getoutput(conf,cmd,stdin=False) - if out: - match = version_re(out) - else: - match = version_re(err) - if not match: - conf.fatal('Could not determine the Open64 version.') - k = match.groupdict() - conf.env['FC_VERSION'] = (k['major'], k['minor']) - -def configure(conf): - conf.find_openf95() - conf.find_ar() - conf.fc_flags() - conf.fc_add_flags() - conf.openf95_flags() - conf.openf95_modifier_platform() - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fc_pgfortran.py b/ldb-2.0.8/third_party/waf/waflib/extras/fc_pgfortran.py deleted file mode 100644 index afb2817..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/fc_pgfortran.py +++ /dev/null @@ -1,68 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# harald at klimachs.de - -import re -from waflib.Tools import fc, fc_config, fc_scan -from waflib.Configure import conf - -from waflib.Tools.compiler_fc import fc_compiler -fc_compiler['linux'].append('fc_pgfortran') - -@conf -def find_pgfortran(conf): - """Find the PGI fortran compiler (will look in the environment variable 'FC')""" - fc = conf.find_program(['pgfortran', 'pgf95', 'pgf90'], var='FC') - conf.get_pgfortran_version(fc) - conf.env.FC_NAME = 'PGFC' - -@conf -def pgfortran_flags(conf): - v = conf.env - v['FCFLAGS_fcshlib'] = ['-shared'] - v['FCFLAGS_DEBUG'] = ['-Minform=inform', '-Mstandard'] # why not - v['FCSTLIB_MARKER'] = '-Bstatic' - v['FCSHLIB_MARKER'] = '-Bdynamic' - v['SONAME_ST'] = '-soname %s' - -@conf -def get_pgfortran_version(conf,fc): - version_re = re.compile(r"The Portland Group", re.I).search - cmd = fc + ['-V'] - out,err = fc_config.getoutput(conf, cmd, stdin=False) - if out: - match = version_re(out) - else: - match = version_re(err) - if not match: - conf.fatal('Could not verify PGI signature') - cmd = fc + ['-help=variable'] - out,err = fc_config.getoutput(conf, cmd, stdin=False) - if out.find('COMPVER')<0: - conf.fatal('Could not determine the compiler type') - k = {} - prevk = '' - out = out.splitlines() - for line in out: - lst = line.partition('=') - if lst[1] == '=': - key = lst[0].rstrip() - if key == '': - key = prevk - val = lst[2].rstrip() - k[key] = val - else: - prevk = line.partition(' ')[0] - def isD(var): - return var in k - def isT(var): - return var in k and k[var]!='0' - conf.env['FC_VERSION'] = (k['COMPVER'].split('.')) - -def configure(conf): - conf.find_pgfortran() - conf.find_ar() - conf.fc_flags() - conf.fc_add_flags() - conf.pgfortran_flags() - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fc_solstudio.py b/ldb-2.0.8/third_party/waf/waflib/extras/fc_solstudio.py deleted file mode 100644 index 53766df..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/fc_solstudio.py +++ /dev/null @@ -1,62 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# harald at klimachs.de - -import re -from waflib import Utils -from waflib.Tools import fc,fc_config,fc_scan -from waflib.Configure import conf - -from waflib.Tools.compiler_fc import fc_compiler -fc_compiler['linux'].append('fc_solstudio') - -@conf -def find_solstudio(conf): - """Find the Solaris Studio compiler (will look in the environment variable 'FC')""" - - fc = conf.find_program(['sunf95', 'f95', 'sunf90', 'f90'], var='FC') - conf.get_solstudio_version(fc) - conf.env.FC_NAME = 'SOL' - -@conf -def solstudio_flags(conf): - v = conf.env - v['FCFLAGS_fcshlib'] = ['-Kpic'] - v['FCFLAGS_DEBUG'] = ['-w3'] - v['LINKFLAGS_fcshlib'] = ['-G'] - v['FCSTLIB_MARKER'] = '-Bstatic' - v['FCSHLIB_MARKER'] = '-Bdynamic' - v['SONAME_ST'] = '-h %s' - -@conf -def solstudio_modifier_platform(conf): - dest_os = conf.env['DEST_OS'] or Utils.unversioned_sys_platform() - solstudio_modifier_func = getattr(conf, 'solstudio_modifier_' + dest_os, None) - if solstudio_modifier_func: - solstudio_modifier_func() - -@conf -def get_solstudio_version(conf, fc): - """Get the compiler version""" - - version_re = re.compile(r"Sun Fortran 95 *(?P\d*)\.(?P\d*)", re.I).search - cmd = fc + ['-V'] - - out, err = fc_config.getoutput(conf,cmd,stdin=False) - if out: - match = version_re(out) - else: - match = version_re(err) - if not match: - conf.fatal('Could not determine the Sun Studio Fortran version.') - k = match.groupdict() - conf.env['FC_VERSION'] = (k['major'], k['minor']) - -def configure(conf): - conf.find_solstudio() - conf.find_ar() - conf.fc_flags() - conf.fc_add_flags() - conf.solstudio_flags() - conf.solstudio_modifier_platform() - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fc_xlf.py b/ldb-2.0.8/third_party/waf/waflib/extras/fc_xlf.py deleted file mode 100644 index 5a3da03..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/fc_xlf.py +++ /dev/null @@ -1,63 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# harald at klimachs.de - -import re -from waflib import Utils,Errors -from waflib.Tools import fc,fc_config,fc_scan -from waflib.Configure import conf - -from waflib.Tools.compiler_fc import fc_compiler -fc_compiler['aix'].insert(0, 'fc_xlf') - -@conf -def find_xlf(conf): - """Find the xlf program (will look in the environment variable 'FC')""" - - fc = conf.find_program(['xlf2003_r', 'xlf2003', 'xlf95_r', 'xlf95', 'xlf90_r', 'xlf90', 'xlf_r', 'xlf'], var='FC') - conf.get_xlf_version(fc) - conf.env.FC_NAME='XLF' - -@conf -def xlf_flags(conf): - v = conf.env - v['FCDEFINES_ST'] = '-WF,-D%s' - v['FCFLAGS_fcshlib'] = ['-qpic=small'] - v['FCFLAGS_DEBUG'] = ['-qhalt=w'] - v['LINKFLAGS_fcshlib'] = ['-Wl,-shared'] - -@conf -def xlf_modifier_platform(conf): - dest_os = conf.env['DEST_OS'] or Utils.unversioned_sys_platform() - xlf_modifier_func = getattr(conf, 'xlf_modifier_' + dest_os, None) - if xlf_modifier_func: - xlf_modifier_func() - -@conf -def get_xlf_version(conf, fc): - """Get the compiler version""" - - cmd = fc + ['-qversion'] - try: - out, err = conf.cmd_and_log(cmd, output=0) - except Errors.WafError: - conf.fatal('Could not find xlf %r' % cmd) - - for v in (r"IBM XL Fortran.* V(?P\d*)\.(?P\d*)",): - version_re = re.compile(v, re.I).search - match = version_re(out or err) - if match: - k = match.groupdict() - conf.env['FC_VERSION'] = (k['major'], k['minor']) - break - else: - conf.fatal('Could not determine the XLF version.') - -def configure(conf): - conf.find_xlf() - conf.find_ar() - conf.fc_flags() - conf.fc_add_flags() - conf.xlf_flags() - conf.xlf_modifier_platform() - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/file_to_object.py b/ldb-2.0.8/third_party/waf/waflib/extras/file_to_object.py deleted file mode 100644 index 1393b51..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/file_to_object.py +++ /dev/null @@ -1,137 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Tool to embed file into objects - -__author__ = __maintainer__ = "Jérôme Carretero " -__copyright__ = "Jérôme Carretero, 2014" - -""" - -This tool allows to embed file contents in object files (.o). -It is not exactly portable, and the file contents are reachable -using various non-portable fashions. -The goal here is to provide a functional interface to the embedding -of file data in objects. -See the ``playground/embedded_resources`` example for an example. - -Usage:: - - bld( - name='pipeline', - # ^ Reference this in use="..." for things using the generated code - features='file_to_object', - source='some.file', - # ^ Name of the file to embed in binary section. - ) - -Known issues: - -- Destination is named like source, with extension renamed to .o - eg. some.file -> some.o - -""" - -import os -from waflib import Task, TaskGen, Errors - -def filename_c_escape(x): - return x.replace("\\", "\\\\") - -class file_to_object_s(Task.Task): - color = 'CYAN' - vars = ['DEST_CPU', 'DEST_BINFMT'] - - def run(self): - name = [] - for i, x in enumerate(self.inputs[0].name): - if x.isalnum(): - name.append(x) - else: - name.append('_') - file = self.inputs[0].abspath() - size = os.path.getsize(file) - if self.env.DEST_CPU in ('x86_64', 'ia', 'aarch64'): - unit = 'quad' - align = 8 - elif self.env.DEST_CPU in ('x86','arm', 'thumb', 'm68k'): - unit = 'long' - align = 4 - else: - raise Errors.WafError("Unsupported DEST_CPU, please report bug!") - - file = filename_c_escape(file) - name = "_binary_" + "".join(name) - rodata = ".section .rodata" - if self.env.DEST_BINFMT == "mac-o": - name = "_" + name - rodata = ".section __TEXT,__const" - - with open(self.outputs[0].abspath(), 'w') as f: - f.write(\ -""" - .global %(name)s_start - .global %(name)s_end - .global %(name)s_size - %(rodata)s -%(name)s_start: - .incbin "%(file)s" -%(name)s_end: - .align %(align)d -%(name)s_size: - .%(unit)s 0x%(size)x -""" % locals()) - -class file_to_object_c(Task.Task): - color = 'CYAN' - def run(self): - name = [] - for i, x in enumerate(self.inputs[0].name): - if x.isalnum(): - name.append(x) - else: - name.append('_') - file = self.inputs[0].abspath() - size = os.path.getsize(file) - - name = "_binary_" + "".join(name) - - data = self.inputs[0].read('rb') - lines, line = [], [] - for idx_byte, byte in enumerate(data): - line.append(byte) - if len(line) > 15 or idx_byte == size-1: - lines.append(", ".join(("0x%02x" % ord(x)) for x in line)) - line = [] - data = ",\n ".join(lines) - - self.outputs[0].write(\ -""" -unsigned long %(name)s_size = %(size)dL; -char const %(name)s_start[] = { - %(data)s -}; -char const %(name)s_end[] = {}; -""" % locals()) - -@TaskGen.feature('file_to_object') -@TaskGen.before_method('process_source') -def tg_file_to_object(self): - bld = self.bld - sources = self.to_nodes(self.source) - targets = [] - for src in sources: - if bld.env.F2O_METHOD == ["asm"]: - tgt = src.parent.find_or_declare(src.name + '.f2o.s') - tsk = self.create_task('file_to_object_s', src, tgt) - tsk.cwd = src.parent.abspath() # verify - else: - tgt = src.parent.find_or_declare(src.name + '.f2o.c') - tsk = self.create_task('file_to_object_c', src, tgt) - tsk.cwd = src.parent.abspath() # verify - targets.append(tgt) - self.source = targets - -def configure(conf): - conf.load('gas') - conf.env.F2O_METHOD = ["c"] - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fluid.py b/ldb-2.0.8/third_party/waf/waflib/extras/fluid.py deleted file mode 100644 index 4814a35..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/fluid.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/python -# encoding: utf-8 -# Grygoriy Fuchedzhy 2009 - -""" -Compile fluid files (fltk graphic library). Use the 'fluid' feature in conjunction with the 'cxx' feature. -""" - -from waflib import Task -from waflib.TaskGen import extension - -class fluid(Task.Task): - color = 'BLUE' - ext_out = ['.h'] - run_str = '${FLUID} -c -o ${TGT[0].abspath()} -h ${TGT[1].abspath()} ${SRC}' - -@extension('.fl') -def process_fluid(self, node): - """add the .fl to the source list; the cxx file generated will be compiled when possible""" - cpp = node.change_ext('.cpp') - hpp = node.change_ext('.hpp') - self.create_task('fluid', node, [cpp, hpp]) - - if 'cxx' in self.features: - self.source.append(cpp) - -def configure(conf): - conf.find_program('fluid', var='FLUID') - conf.check_cfg(path='fltk-config', package='', args='--cxxflags --ldflags', uselib_store='FLTK', mandatory=True) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/freeimage.py b/ldb-2.0.8/third_party/waf/waflib/extras/freeimage.py deleted file mode 100644 index f27e525..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/freeimage.py +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# -# written by Sylvain Rouquette, 2011 - -''' -To add the freeimage tool to the waf file: -$ ./waf-light --tools=compat15,freeimage - or, if you have waf >= 1.6.2 -$ ./waf update --files=freeimage - -The wscript will look like: - -def options(opt): - opt.load('compiler_cxx freeimage') - -def configure(conf): - conf.load('compiler_cxx freeimage') - - # you can call check_freeimage with some parameters. - # It's optional on Linux, it's 'mandatory' on Windows if - # you didn't use --fi-path on the command-line - - # conf.check_freeimage(path='FreeImage/Dist', fip=True) - -def build(bld): - bld(source='main.cpp', target='app', use='FREEIMAGE') -''' - -from waflib import Utils -from waflib.Configure import conf - - -def options(opt): - opt.add_option('--fi-path', type='string', default='', dest='fi_path', - help='''path to the FreeImage directory \ - where the files are e.g. /FreeImage/Dist''') - opt.add_option('--fip', action='store_true', default=False, dest='fip', - help='link with FreeImagePlus') - opt.add_option('--fi-static', action='store_true', - default=False, dest='fi_static', - help="link as shared libraries") - - -@conf -def check_freeimage(self, path=None, fip=False): - self.start_msg('Checking FreeImage') - if not self.env['CXX']: - self.fatal('you must load compiler_cxx before loading freeimage') - prefix = self.options.fi_static and 'ST' or '' - platform = Utils.unversioned_sys_platform() - if platform == 'win32': - if not path: - self.fatal('you must specify the path to FreeImage. \ - use --fi-path=/FreeImage/Dist') - else: - self.env['INCLUDES_FREEIMAGE'] = path - self.env['%sLIBPATH_FREEIMAGE' % prefix] = path - libs = ['FreeImage'] - if self.options.fip: - libs.append('FreeImagePlus') - if platform == 'win32': - self.env['%sLIB_FREEIMAGE' % prefix] = libs - else: - self.env['%sLIB_FREEIMAGE' % prefix] = [i.lower() for i in libs] - self.end_msg('ok') - - -def configure(conf): - platform = Utils.unversioned_sys_platform() - if platform == 'win32' and not conf.options.fi_path: - return - conf.check_freeimage(conf.options.fi_path, conf.options.fip) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fsb.py b/ldb-2.0.8/third_party/waf/waflib/extras/fsb.py deleted file mode 100644 index 1b8f398..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/fsb.py +++ /dev/null @@ -1,31 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2011 (ita) - -""" -Fully sequential builds - -The previous tasks from task generators are re-processed, and this may lead to speed issues -Yet, if you are using this, speed is probably a minor concern -""" - -from waflib import Build - -def options(opt): - pass - -def configure(conf): - pass - -class FSBContext(Build.BuildContext): - def __call__(self, *k, **kw): - ret = Build.BuildContext.__call__(self, *k, **kw) - - # evaluate the results immediately - Build.BuildContext.compile(self) - - return ret - - def compile(self): - pass - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/fsc.py b/ldb-2.0.8/third_party/waf/waflib/extras/fsc.py deleted file mode 100644 index c67e70b..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/fsc.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2011 (ita) - -""" -Experimental F# stuff - -FSC="mono /path/to/fsc.exe" waf configure build -""" - -from waflib import Utils, Task -from waflib.TaskGen import before_method, after_method, feature -from waflib.Tools import ccroot, cs - -ccroot.USELIB_VARS['fsc'] = set(['CSFLAGS', 'ASSEMBLIES', 'RESOURCES']) - -@feature('fs') -@before_method('process_source') -def apply_fsc(self): - cs_nodes = [] - no_nodes = [] - for x in self.to_nodes(self.source): - if x.name.endswith('.fs'): - cs_nodes.append(x) - else: - no_nodes.append(x) - self.source = no_nodes - - bintype = getattr(self, 'type', self.gen.endswith('.dll') and 'library' or 'exe') - self.cs_task = tsk = self.create_task('fsc', cs_nodes, self.path.find_or_declare(self.gen)) - tsk.env.CSTYPE = '/target:%s' % bintype - tsk.env.OUT = '/out:%s' % tsk.outputs[0].abspath() - - inst_to = getattr(self, 'install_path', bintype=='exe' and '${BINDIR}' or '${LIBDIR}') - if inst_to: - # note: we are making a copy, so the files added to cs_task.outputs won't be installed automatically - mod = getattr(self, 'chmod', bintype=='exe' and Utils.O755 or Utils.O644) - self.install_task = self.add_install_files(install_to=inst_to, install_from=self.cs_task.outputs[:], chmod=mod) - -feature('fs')(cs.use_cs) -after_method('apply_fsc')(cs.use_cs) - -feature('fs')(cs.debug_cs) -after_method('apply_fsc', 'use_cs')(cs.debug_cs) - -class fsc(Task.Task): - """ - Compile F# files - """ - color = 'YELLOW' - run_str = '${FSC} ${CSTYPE} ${CSFLAGS} ${ASS_ST:ASSEMBLIES} ${RES_ST:RESOURCES} ${OUT} ${SRC}' - -def configure(conf): - """ - Find a F# compiler, set the variable FSC for the compiler and FS_NAME (mono or fsc) - """ - conf.find_program(['fsc.exe', 'fsharpc'], var='FSC') - conf.env.ASS_ST = '/r:%s' - conf.env.RES_ST = '/resource:%s' - - conf.env.FS_NAME = 'fsc' - if str(conf.env.FSC).lower().find('fsharpc') > -1: - conf.env.FS_NAME = 'mono' - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/gccdeps.py b/ldb-2.0.8/third_party/waf/waflib/extras/gccdeps.py deleted file mode 100644 index bfabe72..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/gccdeps.py +++ /dev/null @@ -1,214 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2008-2010 (ita) - -""" -Execute the tasks with gcc -MD, read the dependencies from the .d file -and prepare the dependency calculation for the next run. -This affects the cxx class, so make sure to load Qt5 after this tool. - -Usage:: - - def options(opt): - opt.load('compiler_cxx') - def configure(conf): - conf.load('compiler_cxx gccdeps') -""" - -import os, re, threading -from waflib import Task, Logs, Utils, Errors -from waflib.Tools import c_preproc -from waflib.TaskGen import before_method, feature - -lock = threading.Lock() - -gccdeps_flags = ['-MD'] -if not c_preproc.go_absolute: - gccdeps_flags = ['-MMD'] - -# Third-party tools are allowed to add extra names in here with append() -supported_compilers = ['gcc', 'icc', 'clang'] - -def scan(self): - if not self.__class__.__name__ in self.env.ENABLE_GCCDEPS: - return super(self.derived_gccdeps, self).scan() - nodes = self.generator.bld.node_deps.get(self.uid(), []) - names = [] - return (nodes, names) - -re_o = re.compile(r"\.o$") -re_splitter = re.compile(r'(?= 0: - return line[sep_idx + 2:] - else: - return line - -def path_to_node(base_node, path, cached_nodes): - # Take the base node and the path and return a node - # Results are cached because searching the node tree is expensive - # The following code is executed by threads, it is not safe, so a lock is needed... - if getattr(path, '__hash__'): - node_lookup_key = (base_node, path) - else: - # Not hashable, assume it is a list and join into a string - node_lookup_key = (base_node, os.path.sep.join(path)) - try: - lock.acquire() - node = cached_nodes[node_lookup_key] - except KeyError: - node = base_node.find_resource(path) - cached_nodes[node_lookup_key] = node - finally: - lock.release() - return node - -def post_run(self): - if not self.__class__.__name__ in self.env.ENABLE_GCCDEPS: - return super(self.derived_gccdeps, self).post_run() - - name = self.outputs[0].abspath() - name = re_o.sub('.d', name) - try: - txt = Utils.readf(name) - except EnvironmentError: - Logs.error('Could not find a .d dependency file, are cflags/cxxflags overwritten?') - raise - #os.remove(name) - - # Compilers have the choice to either output the file's dependencies - # as one large Makefile rule: - # - # /path/to/file.o: /path/to/dep1.h \ - # /path/to/dep2.h \ - # /path/to/dep3.h \ - # ... - # - # or as many individual rules: - # - # /path/to/file.o: /path/to/dep1.h - # /path/to/file.o: /path/to/dep2.h - # /path/to/file.o: /path/to/dep3.h - # ... - # - # So the first step is to sanitize the input by stripping out the left- - # hand side of all these lines. After that, whatever remains are the - # implicit dependencies of task.outputs[0] - txt = '\n'.join([remove_makefile_rule_lhs(line) for line in txt.splitlines()]) - - # Now join all the lines together - txt = txt.replace('\\\n', '') - - val = txt.strip() - val = [x.replace('\\ ', ' ') for x in re_splitter.split(val) if x] - - nodes = [] - bld = self.generator.bld - - # Dynamically bind to the cache - try: - cached_nodes = bld.cached_nodes - except AttributeError: - cached_nodes = bld.cached_nodes = {} - - for x in val: - - node = None - if os.path.isabs(x): - node = path_to_node(bld.root, x, cached_nodes) - else: - # TODO waf 1.9 - single cwd value - path = getattr(bld, 'cwdx', bld.bldnode) - # when calling find_resource, make sure the path does not contain '..' - x = [k for k in Utils.split_path(x) if k and k != '.'] - while '..' in x: - idx = x.index('..') - if idx == 0: - x = x[1:] - path = path.parent - else: - del x[idx] - del x[idx-1] - - node = path_to_node(path, x, cached_nodes) - - if not node: - raise ValueError('could not find %r for %r' % (x, self)) - if id(node) == id(self.inputs[0]): - # ignore the source file, it is already in the dependencies - # this way, successful config tests may be retrieved from the cache - continue - nodes.append(node) - - Logs.debug('deps: gccdeps for %s returned %s', self, nodes) - - bld.node_deps[self.uid()] = nodes - bld.raw_deps[self.uid()] = [] - - try: - del self.cache_sig - except AttributeError: - pass - - Task.Task.post_run(self) - -def sig_implicit_deps(self): - if not self.__class__.__name__ in self.env.ENABLE_GCCDEPS: - return super(self.derived_gccdeps, self).sig_implicit_deps() - try: - return Task.Task.sig_implicit_deps(self) - except Errors.WafError: - return Utils.SIG_NIL - -def wrap_compiled_task(classname): - derived_class = type(classname, (Task.classes[classname],), {}) - derived_class.derived_gccdeps = derived_class - derived_class.post_run = post_run - derived_class.scan = scan - derived_class.sig_implicit_deps = sig_implicit_deps - -for k in ('c', 'cxx'): - if k in Task.classes: - wrap_compiled_task(k) - -@before_method('process_source') -@feature('force_gccdeps') -def force_gccdeps(self): - self.env.ENABLE_GCCDEPS = ['c', 'cxx'] - -def configure(conf): - # in case someone provides a --enable-gccdeps command-line option - if not getattr(conf.options, 'enable_gccdeps', True): - return - - global gccdeps_flags - flags = conf.env.GCCDEPS_FLAGS or gccdeps_flags - if conf.env.CC_NAME in supported_compilers: - try: - conf.check(fragment='int main() { return 0; }', features='c force_gccdeps', cflags=flags, msg='Checking for c flags %r' % ''.join(flags)) - except Errors.ConfigurationError: - pass - else: - conf.env.append_value('CFLAGS', flags) - conf.env.append_unique('ENABLE_GCCDEPS', 'c') - - if conf.env.CXX_NAME in supported_compilers: - try: - conf.check(fragment='int main() { return 0; }', features='cxx force_gccdeps', cxxflags=flags, msg='Checking for cxx flags %r' % ''.join(flags)) - except Errors.ConfigurationError: - pass - else: - conf.env.append_value('CXXFLAGS', flags) - conf.env.append_unique('ENABLE_GCCDEPS', 'cxx') - -def options(opt): - raise ValueError('Do not load gccdeps options') - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/gdbus.py b/ldb-2.0.8/third_party/waf/waflib/extras/gdbus.py deleted file mode 100644 index 0e0476e..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/gdbus.py +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Copyright Garmin International or its subsidiaries, 2018 -# -# Heavily based on dbus.py - -""" -Compiles dbus files with **gdbus-codegen** -Typical usage:: - def options(opt): - opt.load('compiler_c gdbus') - def configure(conf): - conf.load('compiler_c gdbus') - def build(bld): - tg = bld.program( - includes = '.', - source = bld.path.ant_glob('*.c'), - target = 'gnome-hello') - tg.add_gdbus_file('test.xml', 'com.example.example.', 'Example') -""" - -from waflib import Task, Errors, Utils -from waflib.TaskGen import taskgen_method, before_method - -@taskgen_method -def add_gdbus_file(self, filename, prefix, namespace, export=False): - """ - Adds a dbus file to the list of dbus files to process. Store them in the attribute *dbus_lst*. - :param filename: xml file to compile - :type filename: string - :param prefix: interface prefix (--interface-prefix=prefix) - :type prefix: string - :param mode: C namespace (--c-namespace=namespace) - :type mode: string - :param export: Export Headers? - :type export: boolean - """ - if not hasattr(self, 'gdbus_lst'): - self.gdbus_lst = [] - if not 'process_gdbus' in self.meths: - self.meths.append('process_gdbus') - self.gdbus_lst.append([filename, prefix, namespace, export]) - -@before_method('process_source') -def process_gdbus(self): - """ - Processes the dbus files stored in the attribute *gdbus_lst* to create :py:class:`gdbus_binding_tool` instances. - """ - output_node = self.path.get_bld().make_node(['gdbus', self.get_name()]) - sources = [] - - for filename, prefix, namespace, export in getattr(self, 'gdbus_lst', []): - node = self.path.find_resource(filename) - if not node: - raise Errors.WafError('file not found ' + filename) - c_file = output_node.find_or_declare(node.change_ext('.c').name) - h_file = output_node.find_or_declare(node.change_ext('.h').name) - tsk = self.create_task('gdbus_binding_tool', node, [c_file, h_file]) - tsk.cwd = output_node.abspath() - - tsk.env.GDBUS_CODEGEN_INTERFACE_PREFIX = prefix - tsk.env.GDBUS_CODEGEN_NAMESPACE = namespace - tsk.env.GDBUS_CODEGEN_OUTPUT = node.change_ext('').name - sources.append(c_file) - - if sources: - output_node.mkdir() - self.source = Utils.to_list(self.source) + sources - self.includes = [output_node] + self.to_incnodes(getattr(self, 'includes', [])) - if export: - self.export_includes = [output_node] + self.to_incnodes(getattr(self, 'export_includes', [])) - -class gdbus_binding_tool(Task.Task): - """ - Compiles a dbus file - """ - color = 'BLUE' - ext_out = ['.h', '.c'] - run_str = '${GDBUS_CODEGEN} --interface-prefix ${GDBUS_CODEGEN_INTERFACE_PREFIX} --generate-c-code ${GDBUS_CODEGEN_OUTPUT} --c-namespace ${GDBUS_CODEGEN_NAMESPACE} --c-generate-object-manager ${SRC[0].abspath()}' - shell = True - -def configure(conf): - """ - Detects the program gdbus-codegen and sets ``conf.env.GDBUS_CODEGEN`` - """ - conf.find_program('gdbus-codegen', var='GDBUS_CODEGEN') - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/genpybind.py b/ldb-2.0.8/third_party/waf/waflib/extras/genpybind.py deleted file mode 100644 index ac206ee..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/genpybind.py +++ /dev/null @@ -1,194 +0,0 @@ -import os -import pipes -import subprocess -import sys - -from waflib import Logs, Task, Context -from waflib.Tools.c_preproc import scan as scan_impl -# ^-- Note: waflib.extras.gccdeps.scan does not work for us, -# due to its current implementation: -# The -MD flag is injected into the {C,CXX}FLAGS environment variable and -# dependencies are read out in a separate step after compiling by reading -# the .d file saved alongside the object file. -# As the genpybind task refers to a header file that is never compiled itself, -# gccdeps will not be able to extract the list of dependencies. - -from waflib.TaskGen import feature, before_method - - -def join_args(args): - return " ".join(pipes.quote(arg) for arg in args) - - -def configure(cfg): - cfg.load("compiler_cxx") - cfg.load("python") - cfg.check_python_version(minver=(2, 7)) - if not cfg.env.LLVM_CONFIG: - cfg.find_program("llvm-config", var="LLVM_CONFIG") - if not cfg.env.GENPYBIND: - cfg.find_program("genpybind", var="GENPYBIND") - - # find clang reasource dir for builtin headers - cfg.env.GENPYBIND_RESOURCE_DIR = os.path.join( - cfg.cmd_and_log(cfg.env.LLVM_CONFIG + ["--libdir"]).strip(), - "clang", - cfg.cmd_and_log(cfg.env.LLVM_CONFIG + ["--version"]).strip()) - if os.path.exists(cfg.env.GENPYBIND_RESOURCE_DIR): - cfg.msg("Checking clang resource dir", cfg.env.GENPYBIND_RESOURCE_DIR) - else: - cfg.fatal("Clang resource dir not found") - - -@feature("genpybind") -@before_method("process_source") -def generate_genpybind_source(self): - """ - Run genpybind on the headers provided in `source` and compile/link the - generated code instead. This works by generating the code on the fly and - swapping the source node before `process_source` is run. - """ - # name of module defaults to name of target - module = getattr(self, "module", self.target) - - # create temporary source file in build directory to hold generated code - out = "genpybind-%s.%d.cpp" % (module, self.idx) - out = self.path.get_bld().find_or_declare(out) - - task = self.create_task("genpybind", self.to_nodes(self.source), out) - # used to detect whether CFLAGS or CXXFLAGS should be passed to genpybind - task.features = self.features - task.module = module - # can be used to select definitions to include in the current module - # (when header files are shared by more than one module) - task.genpybind_tags = self.to_list(getattr(self, "genpybind_tags", [])) - # additional include directories - task.includes = self.to_list(getattr(self, "includes", [])) - task.genpybind = self.env.GENPYBIND - - # Tell waf to compile/link the generated code instead of the headers - # originally passed-in via the `source` parameter. (see `process_source`) - self.source = [out] - - -class genpybind(Task.Task): # pylint: disable=invalid-name - """ - Runs genpybind on headers provided as input to this task. - Generated code will be written to the first (and only) output node. - """ - quiet = True - color = "PINK" - scan = scan_impl - - @staticmethod - def keyword(): - return "Analyzing" - - def run(self): - if not self.inputs: - return - - args = self.find_genpybind() + self._arguments( - resource_dir=self.env.GENPYBIND_RESOURCE_DIR) - - output = self.run_genpybind(args) - - # For debugging / log output - pasteable_command = join_args(args) - - # write generated code to file in build directory - # (will be compiled during process_source stage) - (output_node,) = self.outputs - output_node.write("// {}\n{}\n".format( - pasteable_command.replace("\n", "\n// "), output)) - - def find_genpybind(self): - return self.genpybind - - def run_genpybind(self, args): - bld = self.generator.bld - - kwargs = dict(cwd=bld.variant_dir) - if hasattr(bld, "log_command"): - bld.log_command(args, kwargs) - else: - Logs.debug("runner: {!r}".format(args)) - proc = subprocess.Popen( - args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs) - stdout, stderr = proc.communicate() - - if not isinstance(stdout, str): - stdout = stdout.decode(sys.stdout.encoding, errors="replace") - if not isinstance(stderr, str): - stderr = stderr.decode(sys.stderr.encoding, errors="replace") - - if proc.returncode != 0: - bld.fatal( - "genpybind returned {code} during the following call:" - "\n{command}\n\n{stdout}\n\n{stderr}".format( - code=proc.returncode, - command=join_args(args), - stdout=stdout, - stderr=stderr, - )) - - if stderr.strip(): - Logs.debug("non-fatal warnings during genpybind run:\n{}".format(stderr)) - - return stdout - - def _include_paths(self): - return self.generator.to_incnodes(self.includes + self.env.INCLUDES) - - def _inputs_as_relative_includes(self): - include_paths = self._include_paths() - relative_includes = [] - for node in self.inputs: - for inc in include_paths: - if node.is_child_of(inc): - relative_includes.append(node.path_from(inc)) - break - else: - self.generator.bld.fatal("could not resolve {}".format(node)) - return relative_includes - - def _arguments(self, genpybind_parse=None, resource_dir=None): - args = [] - relative_includes = self._inputs_as_relative_includes() - is_cxx = "cxx" in self.features - - # options for genpybind - args.extend(["--genpybind-module", self.module]) - if self.genpybind_tags: - args.extend(["--genpybind-tag"] + self.genpybind_tags) - if relative_includes: - args.extend(["--genpybind-include"] + relative_includes) - if genpybind_parse: - args.extend(["--genpybind-parse", genpybind_parse]) - - args.append("--") - - # headers to be processed by genpybind - args.extend(node.abspath() for node in self.inputs) - - args.append("--") - - # options for clang/genpybind-parse - args.append("-D__GENPYBIND__") - args.append("-xc++" if is_cxx else "-xc") - has_std_argument = False - for flag in self.env["CXXFLAGS" if is_cxx else "CFLAGS"]: - flag = flag.replace("-std=gnu", "-std=c") - if flag.startswith("-std=c"): - has_std_argument = True - args.append(flag) - if not has_std_argument: - args.append("-std=c++14") - args.extend("-I{}".format(n.abspath()) for n in self._include_paths()) - args.extend("-D{}".format(p) for p in self.env.DEFINES) - - # point to clang resource dir, if specified - if resource_dir: - args.append("-resource-dir={}".format(resource_dir)) - - return args diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/gob2.py b/ldb-2.0.8/third_party/waf/waflib/extras/gob2.py deleted file mode 100644 index b4fa3b9..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/gob2.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Ali Sabil, 2007 - -from waflib import TaskGen - -TaskGen.declare_chain( - name = 'gob2', - rule = '${GOB2} -o ${TGT[0].bld_dir()} ${GOB2FLAGS} ${SRC}', - ext_in = '.gob', - ext_out = '.c' -) - -def configure(conf): - conf.find_program('gob2', var='GOB2') - conf.env['GOB2FLAGS'] = '' - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/halide.py b/ldb-2.0.8/third_party/waf/waflib/extras/halide.py deleted file mode 100644 index 6078e38..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/halide.py +++ /dev/null @@ -1,151 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Halide code generation tool - -__author__ = __maintainer__ = "Jérôme Carretero " -__copyright__ = "Jérôme Carretero, 2014" - -""" - -Tool to run `Halide `_ code generators. - -Usage:: - - bld( - name='pipeline', - # ^ Reference this in use="..." for things using the generated code - #target=['pipeline.o', 'pipeline.h'] - # ^ by default, name.{o,h} is added, but you can set the outputs here - features='halide', - halide_env="HL_TRACE=1 HL_TARGET=host-opencl-gpu_debug", - # ^ Environment passed to the generator, - # can be a dict, k/v list, or string. - args=[], - # ^ Command-line arguments to the generator (optional), - # eg. to give parameters to the scheduling - source='pipeline_gen', - # ^ Name of the source executable - ) - - -Known issues: - - -- Currently only supports Linux (no ".exe") - -- Doesn't rerun on input modification when input is part of a build - chain, and has been modified externally. - -""" - -import os -from waflib import Task, Utils, Options, TaskGen, Errors - -class run_halide_gen(Task.Task): - color = 'CYAN' - vars = ['HALIDE_ENV', 'HALIDE_ARGS'] - run_str = "${SRC[0].abspath()} ${HALIDE_ARGS}" - def __str__(self): - stuff = "halide" - stuff += ("[%s]" % (",".join( - ('%s=%s' % (k,v)) for k, v in sorted(self.env.env.items())))) - return Task.Task.__str__(self).replace(self.__class__.__name__, - stuff) - -@TaskGen.feature('halide') -@TaskGen.before_method('process_source') -def halide(self): - Utils.def_attrs(self, - args=[], - halide_env={}, - ) - - bld = self.bld - - env = self.halide_env - try: - if isinstance(env, str): - env = dict(x.split('=') for x in env.split()) - elif isinstance(env, list): - env = dict(x.split('=') for x in env) - assert isinstance(env, dict) - except Exception as e: - if not isinstance(e, ValueError) \ - and not isinstance(e, AssertionError): - raise - raise Errors.WafError( - "halide_env must be under the form" \ - " {'HL_x':'a', 'HL_y':'b'}" \ - " or ['HL_x=y', 'HL_y=b']" \ - " or 'HL_x=y HL_y=b'") - - src = self.to_nodes(self.source) - assert len(src) == 1, "Only one source expected" - src = src[0] - - args = Utils.to_list(self.args) - - def change_ext(src, ext): - # Return a node with a new extension, in an appropriate folder - name = src.name - xpos = src.name.rfind('.') - if xpos == -1: - xpos = len(src.name) - newname = name[:xpos] + ext - if src.is_child_of(bld.bldnode): - node = src.get_src().parent.find_or_declare(newname) - else: - node = bld.bldnode.find_or_declare(newname) - return node - - def to_nodes(self, lst, path=None): - tmp = [] - path = path or self.path - find = path.find_or_declare - - if isinstance(lst, self.path.__class__): - lst = [lst] - - for x in Utils.to_list(lst): - if isinstance(x, str): - node = find(x) - else: - node = x - tmp.append(node) - return tmp - - tgt = to_nodes(self, self.target) - if not tgt: - tgt = [change_ext(src, '.o'), change_ext(src, '.h')] - cwd = tgt[0].parent.abspath() - task = self.create_task('run_halide_gen', src, tgt, cwd=cwd) - task.env.append_unique('HALIDE_ARGS', args) - if task.env.env == []: - task.env.env = {} - task.env.env.update(env) - task.env.HALIDE_ENV = " ".join(("%s=%s" % (k,v)) for (k,v) in sorted(env.items())) - task.env.HALIDE_ARGS = args - - try: - self.compiled_tasks.append(task) - except AttributeError: - self.compiled_tasks = [task] - self.source = [] - -def configure(conf): - if Options.options.halide_root is None: - conf.check_cfg(package='Halide', args='--cflags --libs') - else: - halide_root = Options.options.halide_root - conf.env.INCLUDES_HALIDE = [ os.path.join(halide_root, "include") ] - conf.env.LIBPATH_HALIDE = [ os.path.join(halide_root, "lib") ] - conf.env.LIB_HALIDE = ["Halide"] - - # You might want to add this, while upstream doesn't fix it - #conf.env.LIB_HALIDE += ['ncurses', 'dl', 'pthread'] - -def options(opt): - opt.add_option('--halide-root', - help="path to Halide include and lib files", - ) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/javatest.py b/ldb-2.0.8/third_party/waf/waflib/extras/javatest.py deleted file mode 100755 index 979b8d8..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/javatest.py +++ /dev/null @@ -1,118 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Federico Pellegrin, 2017 (fedepell) - -""" -Provides Java Unit test support using :py:class:`waflib.Tools.waf_unit_test.utest` -task via the **javatest** feature. - -This gives the possibility to run unit test and have them integrated into the -standard waf unit test environment. It has been tested with TestNG and JUnit -but should be easily expandable to other frameworks given the flexibility of -ut_str provided by the standard waf unit test environment. - -Example usage: - -def options(opt): - opt.load('java waf_unit_test javatest') - -def configure(conf): - conf.load('java javatest') - -def build(bld): - - [ ... mainprog is built here ... ] - - bld(features = 'javac javatest', - srcdir = 'test/', - outdir = 'test', - sourcepath = ['test'], - classpath = [ 'src' ], - basedir = 'test', - use = ['JAVATEST', 'mainprog'], # mainprog is the program being tested in src/ - ut_str = 'java -cp ${CLASSPATH} ${JTRUNNER} ${SRC}', - jtest_source = bld.path.ant_glob('test/*.xml'), - ) - - -At command line the CLASSPATH where to find the testing environment and the -test runner (default TestNG) that will then be seen in the environment as -CLASSPATH_JAVATEST (then used for use) and JTRUNNER and can be used for -dependencies and ut_str generation. - -Example configure for TestNG: - waf configure --jtpath=/tmp/testng-6.12.jar:/tmp/jcommander-1.71.jar --jtrunner=org.testng.TestNG - or as default runner is TestNG: - waf configure --jtpath=/tmp/testng-6.12.jar:/tmp/jcommander-1.71.jar - -Example configure for JUnit: - waf configure --jtpath=/tmp/junit.jar --jtrunner=org.junit.runner.JUnitCore - -The runner class presence on the system is checked for at configuration stage. - -""" - -import os -from waflib import Task, TaskGen, Options - -@TaskGen.feature('javatest') -@TaskGen.after_method('apply_java', 'use_javac_files', 'set_classpath') -def make_javatest(self): - """ - Creates a ``utest`` task with a populated environment for Java Unit test execution - - """ - tsk = self.create_task('utest') - tsk.set_run_after(self.javac_task) - - # Put test input files as waf_unit_test relies on that for some prints and log generation - # If jtest_source is there, this is specially useful for passing XML for TestNG - # that contain test specification, use that as inputs, otherwise test sources - if getattr(self, 'jtest_source', None): - tsk.inputs = self.to_nodes(self.jtest_source) - else: - if self.javac_task.srcdir[0].exists(): - tsk.inputs = self.javac_task.srcdir[0].ant_glob('**/*.java', remove=False) - - if getattr(self, 'ut_str', None): - self.ut_run, lst = Task.compile_fun(self.ut_str, shell=getattr(self, 'ut_shell', False)) - tsk.vars = lst + tsk.vars - - if getattr(self, 'ut_cwd', None): - if isinstance(self.ut_cwd, str): - # we want a Node instance - if os.path.isabs(self.ut_cwd): - self.ut_cwd = self.bld.root.make_node(self.ut_cwd) - else: - self.ut_cwd = self.path.make_node(self.ut_cwd) - else: - self.ut_cwd = self.bld.bldnode - - # Get parent CLASSPATH and add output dir of test, we run from wscript dir - # We have to change it from list to the standard java -cp format (: separated) - tsk.env.CLASSPATH = ':'.join(self.env.CLASSPATH) + ':' + self.outdir.abspath() - - if not self.ut_cwd.exists(): - self.ut_cwd.mkdir() - - if not hasattr(self, 'ut_env'): - self.ut_env = dict(os.environ) - -def configure(ctx): - cp = ctx.env.CLASSPATH or '.' - if getattr(Options.options, 'jtpath', None): - ctx.env.CLASSPATH_JAVATEST = getattr(Options.options, 'jtpath').split(':') - cp += ':' + getattr(Options.options, 'jtpath') - - if getattr(Options.options, 'jtrunner', None): - ctx.env.JTRUNNER = getattr(Options.options, 'jtrunner') - - if ctx.check_java_class(ctx.env.JTRUNNER, with_classpath=cp): - ctx.fatal('Could not run test class %r' % ctx.env.JTRUNNER) - -def options(opt): - opt.add_option('--jtpath', action='store', default='', dest='jtpath', - help='Path to jar(s) needed for javatest execution, colon separated, if not in the system CLASSPATH') - opt.add_option('--jtrunner', action='store', default='org.testng.TestNG', dest='jtrunner', - help='Class to run javatest test [default: org.testng.TestNG]') - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/kde4.py b/ldb-2.0.8/third_party/waf/waflib/extras/kde4.py deleted file mode 100644 index aed9bfb..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/kde4.py +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2006-2010 (ita) - -""" -Support for the KDE4 libraries and msgfmt -""" - -import os, re -from waflib import Task, Utils -from waflib.TaskGen import feature - -@feature('msgfmt') -def apply_msgfmt(self): - """ - Process all languages to create .mo files and to install them:: - - def build(bld): - bld(features='msgfmt', langs='es de fr', appname='myapp', install_path='${KDE4_LOCALE_INSTALL_DIR}') - """ - for lang in self.to_list(self.langs): - node = self.path.find_resource(lang+'.po') - task = self.create_task('msgfmt', node, node.change_ext('.mo')) - - langname = lang.split('/') - langname = langname[-1] - - inst = getattr(self, 'install_path', '${KDE4_LOCALE_INSTALL_DIR}') - - self.add_install_as( - inst_to = inst + os.sep + langname + os.sep + 'LC_MESSAGES' + os.sep + getattr(self, 'appname', 'set_your_appname') + '.mo', - inst_from = task.outputs[0], - chmod = getattr(self, 'chmod', Utils.O644)) - -class msgfmt(Task.Task): - """ - Transform .po files into .mo files - """ - color = 'BLUE' - run_str = '${MSGFMT} ${SRC} -o ${TGT}' - -def configure(self): - """ - Detect kde4-config and set various variables for the *use* system:: - - def options(opt): - opt.load('compiler_cxx kde4') - def configure(conf): - conf.load('compiler_cxx kde4') - def build(bld): - bld.program(source='main.c', target='app', use='KDECORE KIO KHTML') - """ - kdeconfig = self.find_program('kde4-config') - prefix = self.cmd_and_log(kdeconfig + ['--prefix']).strip() - fname = '%s/share/apps/cmake/modules/KDELibsDependencies.cmake' % prefix - try: - os.stat(fname) - except OSError: - fname = '%s/share/kde4/apps/cmake/modules/KDELibsDependencies.cmake' % prefix - try: - os.stat(fname) - except OSError: - self.fatal('could not open %s' % fname) - - try: - txt = Utils.readf(fname) - except EnvironmentError: - self.fatal('could not read %s' % fname) - - txt = txt.replace('\\\n', '\n') - fu = re.compile('#(.*)\n') - txt = fu.sub('', txt) - - setregexp = re.compile(r'([sS][eE][tT]\s*\()\s*([^\s]+)\s+\"([^"]+)\"\)') - found = setregexp.findall(txt) - - for (_, key, val) in found: - #print key, val - self.env[key] = val - - # well well, i could just write an interpreter for cmake files - self.env['LIB_KDECORE']= ['kdecore'] - self.env['LIB_KDEUI'] = ['kdeui'] - self.env['LIB_KIO'] = ['kio'] - self.env['LIB_KHTML'] = ['khtml'] - self.env['LIB_KPARTS'] = ['kparts'] - - self.env['LIBPATH_KDECORE'] = [os.path.join(self.env.KDE4_LIB_INSTALL_DIR, 'kde4', 'devel'), self.env.KDE4_LIB_INSTALL_DIR] - self.env['INCLUDES_KDECORE'] = [self.env['KDE4_INCLUDE_INSTALL_DIR']] - self.env.append_value('INCLUDES_KDECORE', [self.env['KDE4_INCLUDE_INSTALL_DIR']+ os.sep + 'KDE']) - - self.find_program('msgfmt', var='MSGFMT') - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/local_rpath.py b/ldb-2.0.8/third_party/waf/waflib/extras/local_rpath.py deleted file mode 100644 index e3923d9..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/local_rpath.py +++ /dev/null @@ -1,21 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2011 (ita) - -import copy -from waflib.TaskGen import after_method, feature - -@after_method('propagate_uselib_vars') -@feature('cprogram', 'cshlib', 'cxxprogram', 'cxxshlib', 'fcprogram', 'fcshlib') -def add_rpath_stuff(self): - all = copy.copy(self.to_list(getattr(self, 'use', []))) - while all: - name = all.pop() - try: - tg = self.bld.get_tgen_by_name(name) - except: - continue - if hasattr(tg, 'link_task'): - self.env.append_value('RPATH', tg.link_task.outputs[0].parent.abspath()) - all.extend(self.to_list(getattr(tg, 'use', []))) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/make.py b/ldb-2.0.8/third_party/waf/waflib/extras/make.py deleted file mode 100644 index 933d9ca..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/make.py +++ /dev/null @@ -1,142 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2011 (ita) - -""" -A make-like way of executing the build, following the relationships between inputs/outputs - -This algorithm will lead to slower builds, will not be as flexible as "waf build", but -it might be useful for building data files (?) - -It is likely to break in the following cases: -- files are created dynamically (no inputs or outputs) -- headers -- building two files from different groups -""" - -import re -from waflib import Options, Task -from waflib.Build import BuildContext - -class MakeContext(BuildContext): - '''executes tasks in a step-by-step manner, following dependencies between inputs/outputs''' - cmd = 'make' - fun = 'build' - - def __init__(self, **kw): - super(MakeContext, self).__init__(**kw) - self.files = Options.options.files - - def get_build_iterator(self): - if not self.files: - while 1: - yield super(MakeContext, self).get_build_iterator() - - for g in self.groups: - for tg in g: - try: - f = tg.post - except AttributeError: - pass - else: - f() - - provides = {} - uses = {} - all_tasks = [] - tasks = [] - for pat in self.files.split(','): - matcher = self.get_matcher(pat) - for tg in g: - if isinstance(tg, Task.Task): - lst = [tg] - else: - lst = tg.tasks - for tsk in lst: - all_tasks.append(tsk) - - do_exec = False - for node in tsk.inputs: - try: - uses[node].append(tsk) - except: - uses[node] = [tsk] - - if matcher(node, output=False): - do_exec = True - break - - for node in tsk.outputs: - try: - provides[node].append(tsk) - except: - provides[node] = [tsk] - - if matcher(node, output=True): - do_exec = True - break - if do_exec: - tasks.append(tsk) - - # so we have the tasks that we need to process, the list of all tasks, - # the map of the tasks providing nodes, and the map of tasks using nodes - - if not tasks: - # if there are no tasks matching, return everything in the current group - result = all_tasks - else: - # this is like a big filter... - result = set() - seen = set() - cur = set(tasks) - while cur: - result |= cur - tosee = set() - for tsk in cur: - for node in tsk.inputs: - if node in seen: - continue - seen.add(node) - tosee |= set(provides.get(node, [])) - cur = tosee - result = list(result) - - Task.set_file_constraints(result) - Task.set_precedence_constraints(result) - yield result - - while 1: - yield [] - - def get_matcher(self, pat): - # this returns a function - inn = True - out = True - if pat.startswith('in:'): - out = False - pat = pat.replace('in:', '') - elif pat.startswith('out:'): - inn = False - pat = pat.replace('out:', '') - - anode = self.root.find_node(pat) - pattern = None - if not anode: - if not pat.startswith('^'): - pat = '^.+?%s' % pat - if not pat.endswith('$'): - pat = '%s$' % pat - pattern = re.compile(pat) - - def match(node, output): - if output and not out: - return False - if not output and not inn: - return False - - if anode: - return anode == node - else: - return pattern.match(node.abspath()) - return match - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/midl.py b/ldb-2.0.8/third_party/waf/waflib/extras/midl.py deleted file mode 100644 index 43e6cf9..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/midl.py +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env python -# Issue 1185 ultrix gmail com - -""" -Microsoft Interface Definition Language support. Given ComObject.idl, this tool -will generate ComObject.tlb ComObject_i.h ComObject_i.c ComObject_p.c and dlldata.c - -To declare targets using midl:: - - def configure(conf): - conf.load('msvc') - conf.load('midl') - - def build(bld): - bld( - features='c cshlib', - # Note: ComObject_i.c is generated from ComObject.idl - source = 'main.c ComObject.idl ComObject_i.c', - target = 'ComObject.dll') -""" - -from waflib import Task, Utils -from waflib.TaskGen import feature, before_method -import os - -def configure(conf): - conf.find_program(['midl'], var='MIDL') - - conf.env.MIDLFLAGS = [ - '/nologo', - '/D', - '_DEBUG', - '/W1', - '/char', - 'signed', - '/Oicf', - ] - -@feature('c', 'cxx') -@before_method('process_source') -def idl_file(self): - # Do this before process_source so that the generated header can be resolved - # when scanning source dependencies. - idl_nodes = [] - src_nodes = [] - for node in Utils.to_list(self.source): - if str(node).endswith('.idl'): - idl_nodes.append(node) - else: - src_nodes.append(node) - - for node in self.to_nodes(idl_nodes): - t = node.change_ext('.tlb') - h = node.change_ext('_i.h') - c = node.change_ext('_i.c') - p = node.change_ext('_p.c') - d = node.parent.find_or_declare('dlldata.c') - self.create_task('midl', node, [t, h, c, p, d]) - - self.source = src_nodes - -class midl(Task.Task): - """ - Compile idl files - """ - color = 'YELLOW' - run_str = '${MIDL} ${MIDLFLAGS} ${CPPPATH_ST:INCLUDES} /tlb ${TGT[0].bldpath()} /header ${TGT[1].bldpath()} /iid ${TGT[2].bldpath()} /proxy ${TGT[3].bldpath()} /dlldata ${TGT[4].bldpath()} ${SRC}' - before = ['winrc'] - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/msvcdeps.py b/ldb-2.0.8/third_party/waf/waflib/extras/msvcdeps.py deleted file mode 100644 index 873a419..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/msvcdeps.py +++ /dev/null @@ -1,251 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Copyright Garmin International or its subsidiaries, 2012-2013 - -''' -Off-load dependency scanning from Python code to MSVC compiler - -This tool is safe to load in any environment; it will only activate the -MSVC exploits when it finds that a particular taskgen uses MSVC to -compile. - -Empirical testing shows about a 10% execution time savings from using -this tool as compared to c_preproc. - -The technique of gutting scan() and pushing the dependency calculation -down to post_run() is cribbed from gccdeps.py. - -This affects the cxx class, so make sure to load Qt5 after this tool. - -Usage:: - - def options(opt): - opt.load('compiler_cxx') - def configure(conf): - conf.load('compiler_cxx msvcdeps') -''' - -import os, sys, tempfile, threading - -from waflib import Context, Errors, Logs, Task, Utils -from waflib.Tools import c_preproc, c, cxx, msvc -from waflib.TaskGen import feature, before_method - -lock = threading.Lock() -nodes = {} # Cache the path -> Node lookup - -PREPROCESSOR_FLAG = '/showIncludes' -INCLUDE_PATTERN = 'Note: including file:' - -# Extensible by outside tools -supported_compilers = ['msvc'] - -@feature('c', 'cxx') -@before_method('process_source') -def apply_msvcdeps_flags(taskgen): - if taskgen.env.CC_NAME not in supported_compilers: - return - - for flag in ('CFLAGS', 'CXXFLAGS'): - if taskgen.env.get_flat(flag).find(PREPROCESSOR_FLAG) < 0: - taskgen.env.append_value(flag, PREPROCESSOR_FLAG) - -def path_to_node(base_node, path, cached_nodes): - ''' - Take the base node and the path and return a node - Results are cached because searching the node tree is expensive - The following code is executed by threads, it is not safe, so a lock is needed... - ''' - # normalize the path because ant_glob() does not understand - # parent path components (..) - path = os.path.normpath(path) - - # normalize the path case to increase likelihood of a cache hit - path = os.path.normcase(path) - - # ant_glob interprets [] and () characters, so those must be replaced - path = path.replace('[', '?').replace(']', '?').replace('(', '[(]').replace(')', '[)]') - - node_lookup_key = (base_node, path) - - try: - node = cached_nodes[node_lookup_key] - except KeyError: - # retry with lock on cache miss - with lock: - try: - node = cached_nodes[node_lookup_key] - except KeyError: - node_list = base_node.ant_glob([path], ignorecase=True, remove=False, quiet=True, regex=False) - node = cached_nodes[node_lookup_key] = node_list[0] if node_list else None - - return node - -def post_run(self): - if self.env.CC_NAME not in supported_compilers: - return super(self.derived_msvcdeps, self).post_run() - - # TODO this is unlikely to work with netcache - if getattr(self, 'cached', None): - return Task.Task.post_run(self) - - bld = self.generator.bld - unresolved_names = [] - resolved_nodes = [] - - # Dynamically bind to the cache - try: - cached_nodes = bld.cached_nodes - except AttributeError: - cached_nodes = bld.cached_nodes = {} - - for path in self.msvcdeps_paths: - node = None - if os.path.isabs(path): - node = path_to_node(bld.root, path, cached_nodes) - else: - # when calling find_resource, make sure the path does not begin with '..' - base_node = bld.bldnode - path = [k for k in Utils.split_path(path) if k and k != '.'] - while path[0] == '..': - path.pop(0) - base_node = base_node.parent - path = os.sep.join(path) - - node = path_to_node(base_node, path, cached_nodes) - - if not node: - raise ValueError('could not find %r for %r' % (path, self)) - else: - if not c_preproc.go_absolute: - if not (node.is_child_of(bld.srcnode) or node.is_child_of(bld.bldnode)): - # System library - Logs.debug('msvcdeps: Ignoring system include %r', node) - continue - - if id(node) == id(self.inputs[0]): - # Self-dependency - continue - - resolved_nodes.append(node) - - bld.node_deps[self.uid()] = resolved_nodes - bld.raw_deps[self.uid()] = unresolved_names - - try: - del self.cache_sig - except AttributeError: - pass - - Task.Task.post_run(self) - -def scan(self): - if self.env.CC_NAME not in supported_compilers: - return super(self.derived_msvcdeps, self).scan() - - resolved_nodes = self.generator.bld.node_deps.get(self.uid(), []) - unresolved_names = [] - return (resolved_nodes, unresolved_names) - -def sig_implicit_deps(self): - if self.env.CC_NAME not in supported_compilers: - return super(self.derived_msvcdeps, self).sig_implicit_deps() - - try: - return Task.Task.sig_implicit_deps(self) - except Errors.WafError: - return Utils.SIG_NIL - -def exec_command(self, cmd, **kw): - if self.env.CC_NAME not in supported_compilers: - return super(self.derived_msvcdeps, self).exec_command(cmd, **kw) - - if not 'cwd' in kw: - kw['cwd'] = self.get_cwd() - - if self.env.PATH: - env = kw['env'] = dict(kw.get('env') or self.env.env or os.environ) - env['PATH'] = self.env.PATH if isinstance(self.env.PATH, str) else os.pathsep.join(self.env.PATH) - - # The Visual Studio IDE adds an environment variable that causes - # the MS compiler to send its textual output directly to the - # debugging window rather than normal stdout/stderr. - # - # This is unrecoverably bad for this tool because it will cause - # all the dependency scanning to see an empty stdout stream and - # assume that the file being compiled uses no headers. - # - # See http://blogs.msdn.com/b/freik/archive/2006/04/05/569025.aspx - # - # Attempting to repair the situation by deleting the offending - # envvar at this point in tool execution will not be good enough-- - # its presence poisons the 'waf configure' step earlier. We just - # want to put a sanity check here in order to help developers - # quickly diagnose the issue if an otherwise-good Waf tree - # is then executed inside the MSVS IDE. - assert 'VS_UNICODE_OUTPUT' not in kw['env'] - - cmd, args = self.split_argfile(cmd) - try: - (fd, tmp) = tempfile.mkstemp() - os.write(fd, '\r\n'.join(args).encode()) - os.close(fd) - - self.msvcdeps_paths = [] - kw['env'] = kw.get('env', os.environ.copy()) - kw['cwd'] = kw.get('cwd', os.getcwd()) - kw['quiet'] = Context.STDOUT - kw['output'] = Context.STDOUT - - out = [] - if Logs.verbose: - Logs.debug('argfile: @%r -> %r', tmp, args) - try: - raw_out = self.generator.bld.cmd_and_log(cmd + ['@' + tmp], **kw) - ret = 0 - except Errors.WafError as e: - # Use e.msg if e.stdout is not set - raw_out = getattr(e, 'stdout', e.msg) - - # Return non-zero error code even if we didn't - # get one from the exception object - ret = getattr(e, 'returncode', 1) - - for line in raw_out.splitlines(): - if line.startswith(INCLUDE_PATTERN): - inc_path = line[len(INCLUDE_PATTERN):].strip() - Logs.debug('msvcdeps: Regex matched %s', inc_path) - self.msvcdeps_paths.append(inc_path) - else: - out.append(line) - - # Pipe through the remaining stdout content (not related to /showIncludes) - if self.generator.bld.logger: - self.generator.bld.logger.debug('out: %s' % os.linesep.join(out)) - else: - sys.stdout.write(os.linesep.join(out) + os.linesep) - - return ret - finally: - try: - os.remove(tmp) - except OSError: - # anti-virus and indexers can keep files open -_- - pass - - -def wrap_compiled_task(classname): - derived_class = type(classname, (Task.classes[classname],), {}) - derived_class.derived_msvcdeps = derived_class - derived_class.post_run = post_run - derived_class.scan = scan - derived_class.sig_implicit_deps = sig_implicit_deps - derived_class.exec_command = exec_command - -for k in ('c', 'cxx'): - if k in Task.classes: - wrap_compiled_task(k) - -def options(opt): - raise ValueError('Do not load msvcdeps options') - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/msvs.py b/ldb-2.0.8/third_party/waf/waflib/extras/msvs.py deleted file mode 100644 index 8aa2db0..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/msvs.py +++ /dev/null @@ -1,1048 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Avalanche Studios 2009-2011 -# Thomas Nagy 2011 - -""" -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -""" - -""" -To add this tool to your project: -def options(conf): - opt.load('msvs') - -It can be a good idea to add the sync_exec tool too. - -To generate solution files: -$ waf configure msvs - -To customize the outputs, provide subclasses in your wscript files:: - - from waflib.extras import msvs - class vsnode_target(msvs.vsnode_target): - def get_build_command(self, props): - # likely to be required - return "waf.bat build" - def collect_source(self): - # likely to be required - ... - class msvs_bar(msvs.msvs_generator): - def init(self): - msvs.msvs_generator.init(self) - self.vsnode_target = vsnode_target - -The msvs class re-uses the same build() function for reading the targets (task generators), -you may therefore specify msvs settings on the context object:: - - def build(bld): - bld.solution_name = 'foo.sln' - bld.waf_command = 'waf.bat' - bld.projects_dir = bld.srcnode.make_node('.depproj') - bld.projects_dir.mkdir() - -For visual studio 2008, the command is called 'msvs2008', and the classes -such as vsnode_target are wrapped by a decorator class 'wrap_2008' to -provide special functionality. - -To customize platform toolsets, pass additional parameters, for example:: - - class msvs_2013(msvs.msvs_generator): - cmd = 'msvs2013' - numver = '13.00' - vsver = '2013' - platform_toolset_ver = 'v120' - -ASSUMPTIONS: -* a project can be either a directory or a target, vcxproj files are written only for targets that have source files -* each project is a vcxproj file, therefore the project uuid needs only to be a hash of the absolute path -""" - -import os, re, sys -import uuid # requires python 2.5 -from waflib.Build import BuildContext -from waflib import Utils, TaskGen, Logs, Task, Context, Node, Options - -HEADERS_GLOB = '**/(*.h|*.hpp|*.H|*.inl)' - -PROJECT_TEMPLATE = r''' - - - - ${for b in project.build_properties} - - ${b.configuration} - ${b.platform} - - ${endfor} - - - - {${project.uuid}} - MakeFileProj - ${project.name} - - - - ${for b in project.build_properties} - - Makefile - ${b.outdir} - ${project.platform_toolset_ver} - - ${endfor} - - - - - - ${for b in project.build_properties} - - - - ${endfor} - - ${for b in project.build_properties} - - ${xml:project.get_build_command(b)} - ${xml:project.get_rebuild_command(b)} - ${xml:project.get_clean_command(b)} - ${xml:b.includes_search_path} - ${xml:b.preprocessor_definitions};$(NMakePreprocessorDefinitions) - ${xml:b.includes_search_path} - $(ExecutablePath) - - ${if getattr(b, 'output_file', None)} - ${xml:b.output_file} - ${endif} - ${if getattr(b, 'deploy_dir', None)} - ${xml:b.deploy_dir} - ${endif} - - ${endfor} - - ${for b in project.build_properties} - ${if getattr(b, 'deploy_dir', None)} - - - CopyToHardDrive - - - ${endif} - ${endfor} - - - ${for x in project.source} - <${project.get_key(x)} Include='${x.win32path()}' /> - ${endfor} - - - - - -''' - -FILTER_TEMPLATE = ''' - - - ${for x in project.source} - <${project.get_key(x)} Include="${x.win32path()}"> - ${project.get_filter_name(x.parent)} - - ${endfor} - - - ${for x in project.dirs()} - - {${project.make_uuid(x.win32path())}} - - ${endfor} - - -''' - -PROJECT_2008_TEMPLATE = r''' - - - ${if project.build_properties} - ${for b in project.build_properties} - - ${endfor} - ${else} - - ${endif} - - - - - ${if project.build_properties} - ${for b in project.build_properties} - - - - ${endfor} - ${else} - - - ${endif} - - - - -${project.display_filter()} - - -''' - -SOLUTION_TEMPLATE = '''Microsoft Visual Studio Solution File, Format Version ${project.numver} -# Visual Studio ${project.vsver} -${for p in project.all_projects} -Project("{${p.ptype()}}") = "${p.name}", "${p.title}", "{${p.uuid}}" -EndProject${endfor} -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - ${if project.all_projects} - ${for (configuration, platform) in project.all_projects[0].ctx.project_configurations()} - ${configuration}|${platform} = ${configuration}|${platform} - ${endfor} - ${endif} - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - ${for p in project.all_projects} - ${if hasattr(p, 'source')} - ${for b in p.build_properties} - {${p.uuid}}.${b.configuration}|${b.platform}.ActiveCfg = ${b.configuration}|${b.platform} - ${if getattr(p, 'is_active', None)} - {${p.uuid}}.${b.configuration}|${b.platform}.Build.0 = ${b.configuration}|${b.platform} - ${endif} - ${if getattr(p, 'is_deploy', None)} - {${p.uuid}}.${b.configuration}|${b.platform}.Deploy.0 = ${b.configuration}|${b.platform} - ${endif} - ${endfor} - ${endif} - ${endfor} - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - ${for p in project.all_projects} - ${if p.parent} - {${p.uuid}} = {${p.parent.uuid}} - ${endif} - ${endfor} - EndGlobalSection -EndGlobal -''' - -COMPILE_TEMPLATE = '''def f(project): - lst = [] - def xml_escape(value): - return value.replace("&", "&").replace('"', """).replace("'", "'").replace("<", "<").replace(">", ">") - - %s - - #f = open('cmd.txt', 'w') - #f.write(str(lst)) - #f.close() - return ''.join(lst) -''' -reg_act = re.compile(r"(?P\\)|(?P\$\$)|(?P\$\{(?P[^}]*?)\})", re.M) -def compile_template(line): - """ - Compile a template expression into a python function (like jsps, but way shorter) - """ - extr = [] - def repl(match): - g = match.group - if g('dollar'): - return "$" - elif g('backslash'): - return "\\" - elif g('subst'): - extr.append(g('code')) - return "<<|@|>>" - return None - - line2 = reg_act.sub(repl, line) - params = line2.split('<<|@|>>') - assert(extr) - - - indent = 0 - buf = [] - app = buf.append - - def app(txt): - buf.append(indent * '\t' + txt) - - for x in range(len(extr)): - if params[x]: - app("lst.append(%r)" % params[x]) - - f = extr[x] - if f.startswith(('if', 'for')): - app(f + ':') - indent += 1 - elif f.startswith('py:'): - app(f[3:]) - elif f.startswith(('endif', 'endfor')): - indent -= 1 - elif f.startswith(('else', 'elif')): - indent -= 1 - app(f + ':') - indent += 1 - elif f.startswith('xml:'): - app('lst.append(xml_escape(%s))' % f[4:]) - else: - #app('lst.append((%s) or "cannot find %s")' % (f, f)) - app('lst.append(%s)' % f) - - if extr: - if params[-1]: - app("lst.append(%r)" % params[-1]) - - fun = COMPILE_TEMPLATE % "\n\t".join(buf) - #print(fun) - return Task.funex(fun) - - -re_blank = re.compile('(\n|\r|\\s)*\n', re.M) -def rm_blank_lines(txt): - txt = re_blank.sub('\r\n', txt) - return txt - -BOM = '\xef\xbb\xbf' -try: - BOM = bytes(BOM, 'latin-1') # python 3 -except TypeError: - pass - -def stealth_write(self, data, flags='wb'): - try: - unicode - except NameError: - data = data.encode('utf-8') # python 3 - else: - data = data.decode(sys.getfilesystemencoding(), 'replace') - data = data.encode('utf-8') - - if self.name.endswith(('.vcproj', '.vcxproj')): - data = BOM + data - - try: - txt = self.read(flags='rb') - if txt != data: - raise ValueError('must write') - except (IOError, ValueError): - self.write(data, flags=flags) - else: - Logs.debug('msvs: skipping %s', self.win32path()) -Node.Node.stealth_write = stealth_write - -re_win32 = re.compile(r'^([/\\]cygdrive)?[/\\]([a-z])([^a-z0-9_-].*)', re.I) -def win32path(self): - p = self.abspath() - m = re_win32.match(p) - if m: - return "%s:%s" % (m.group(2).upper(), m.group(3)) - return p -Node.Node.win32path = win32path - -re_quote = re.compile("[^a-zA-Z0-9-]") -def quote(s): - return re_quote.sub("_", s) - -def xml_escape(value): - return value.replace("&", "&").replace('"', """).replace("'", "'").replace("<", "<").replace(">", ">") - -def make_uuid(v, prefix = None): - """ - simple utility function - """ - if isinstance(v, dict): - keys = list(v.keys()) - keys.sort() - tmp = str([(k, v[k]) for k in keys]) - else: - tmp = str(v) - d = Utils.md5(tmp.encode()).hexdigest().upper() - if prefix: - d = '%s%s' % (prefix, d[8:]) - gid = uuid.UUID(d, version = 4) - return str(gid).upper() - -def diff(node, fromnode): - # difference between two nodes, but with "(..)" instead of ".." - c1 = node - c2 = fromnode - - c1h = c1.height() - c2h = c2.height() - - lst = [] - up = 0 - - while c1h > c2h: - lst.append(c1.name) - c1 = c1.parent - c1h -= 1 - - while c2h > c1h: - up += 1 - c2 = c2.parent - c2h -= 1 - - while id(c1) != id(c2): - lst.append(c1.name) - up += 1 - - c1 = c1.parent - c2 = c2.parent - - for i in range(up): - lst.append('(..)') - lst.reverse() - return tuple(lst) - -class build_property(object): - pass - -class vsnode(object): - """ - Abstract class representing visual studio elements - We assume that all visual studio nodes have a uuid and a parent - """ - def __init__(self, ctx): - self.ctx = ctx # msvs context - self.name = '' # string, mandatory - self.vspath = '' # path in visual studio (name for dirs, absolute path for projects) - self.uuid = '' # string, mandatory - self.parent = None # parent node for visual studio nesting - - def get_waf(self): - """ - Override in subclasses... - """ - return 'cd /d "%s" & %s' % (self.ctx.srcnode.win32path(), getattr(self.ctx, 'waf_command', 'waf.bat')) - - def ptype(self): - """ - Return a special uuid for projects written in the solution file - """ - pass - - def write(self): - """ - Write the project file, by default, do nothing - """ - pass - - def make_uuid(self, val): - """ - Alias for creating uuid values easily (the templates cannot access global variables) - """ - return make_uuid(val) - -class vsnode_vsdir(vsnode): - """ - Nodes representing visual studio folders (which do not match the filesystem tree!) - """ - VS_GUID_SOLUTIONFOLDER = "2150E333-8FDC-42A3-9474-1A3956D46DE8" - def __init__(self, ctx, uuid, name, vspath=''): - vsnode.__init__(self, ctx) - self.title = self.name = name - self.uuid = uuid - self.vspath = vspath or name - - def ptype(self): - return self.VS_GUID_SOLUTIONFOLDER - -class vsnode_project(vsnode): - """ - Abstract class representing visual studio project elements - A project is assumed to be writable, and has a node representing the file to write to - """ - VS_GUID_VCPROJ = "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942" - def ptype(self): - return self.VS_GUID_VCPROJ - - def __init__(self, ctx, node): - vsnode.__init__(self, ctx) - self.path = node - self.uuid = make_uuid(node.win32path()) - self.name = node.name - self.platform_toolset_ver = getattr(ctx, 'platform_toolset_ver', None) - self.title = self.path.win32path() - self.source = [] # list of node objects - self.build_properties = [] # list of properties (nmake commands, output dir, etc) - - def dirs(self): - """ - Get the list of parent folders of the source files (header files included) - for writing the filters - """ - lst = [] - def add(x): - if x.height() > self.tg.path.height() and x not in lst: - lst.append(x) - add(x.parent) - for x in self.source: - add(x.parent) - return lst - - def write(self): - Logs.debug('msvs: creating %r', self.path) - - # first write the project file - template1 = compile_template(PROJECT_TEMPLATE) - proj_str = template1(self) - proj_str = rm_blank_lines(proj_str) - self.path.stealth_write(proj_str) - - # then write the filter - template2 = compile_template(FILTER_TEMPLATE) - filter_str = template2(self) - filter_str = rm_blank_lines(filter_str) - tmp = self.path.parent.make_node(self.path.name + '.filters') - tmp.stealth_write(filter_str) - - def get_key(self, node): - """ - required for writing the source files - """ - name = node.name - if name.endswith(('.cpp', '.c')): - return 'ClCompile' - return 'ClInclude' - - def collect_properties(self): - """ - Returns a list of triplet (configuration, platform, output_directory) - """ - ret = [] - for c in self.ctx.configurations: - for p in self.ctx.platforms: - x = build_property() - x.outdir = '' - - x.configuration = c - x.platform = p - - x.preprocessor_definitions = '' - x.includes_search_path = '' - - # can specify "deploy_dir" too - ret.append(x) - self.build_properties = ret - - def get_build_params(self, props): - opt = '--execsolution=%s' % self.ctx.get_solution_node().win32path() - return (self.get_waf(), opt) - - def get_build_command(self, props): - return "%s build %s" % self.get_build_params(props) - - def get_clean_command(self, props): - return "%s clean %s" % self.get_build_params(props) - - def get_rebuild_command(self, props): - return "%s clean build %s" % self.get_build_params(props) - - def get_filter_name(self, node): - lst = diff(node, self.tg.path) - return '\\'.join(lst) or '.' - -class vsnode_alias(vsnode_project): - def __init__(self, ctx, node, name): - vsnode_project.__init__(self, ctx, node) - self.name = name - self.output_file = '' - -class vsnode_build_all(vsnode_alias): - """ - Fake target used to emulate the behaviour of "make all" (starting one process by target is slow) - This is the only alias enabled by default - """ - def __init__(self, ctx, node, name='build_all_projects'): - vsnode_alias.__init__(self, ctx, node, name) - self.is_active = True - -class vsnode_install_all(vsnode_alias): - """ - Fake target used to emulate the behaviour of "make install" - """ - def __init__(self, ctx, node, name='install_all_projects'): - vsnode_alias.__init__(self, ctx, node, name) - - def get_build_command(self, props): - return "%s build install %s" % self.get_build_params(props) - - def get_clean_command(self, props): - return "%s clean %s" % self.get_build_params(props) - - def get_rebuild_command(self, props): - return "%s clean build install %s" % self.get_build_params(props) - -class vsnode_project_view(vsnode_alias): - """ - Fake target used to emulate a file system view - """ - def __init__(self, ctx, node, name='project_view'): - vsnode_alias.__init__(self, ctx, node, name) - self.tg = self.ctx() # fake one, cannot remove - self.exclude_files = Node.exclude_regs + ''' -waf-2* -waf3-2*/** -.waf-2* -.waf3-2*/** -**/*.sdf -**/*.suo -**/*.ncb -**/%s - ''' % Options.lockfile - - def collect_source(self): - # this is likely to be slow - self.source = self.ctx.srcnode.ant_glob('**', excl=self.exclude_files) - - def get_build_command(self, props): - params = self.get_build_params(props) + (self.ctx.cmd,) - return "%s %s %s" % params - - def get_clean_command(self, props): - return "" - - def get_rebuild_command(self, props): - return self.get_build_command(props) - -class vsnode_target(vsnode_project): - """ - Visual studio project representing a targets (programs, libraries, etc) and bound - to a task generator - """ - def __init__(self, ctx, tg): - """ - A project is more or less equivalent to a file/folder - """ - base = getattr(ctx, 'projects_dir', None) or tg.path - node = base.make_node(quote(tg.name) + ctx.project_extension) # the project file as a Node - vsnode_project.__init__(self, ctx, node) - self.name = quote(tg.name) - self.tg = tg # task generator - - def get_build_params(self, props): - """ - Override the default to add the target name - """ - opt = '--execsolution=%s' % self.ctx.get_solution_node().win32path() - if getattr(self, 'tg', None): - opt += " --targets=%s" % self.tg.name - return (self.get_waf(), opt) - - def collect_source(self): - tg = self.tg - source_files = tg.to_nodes(getattr(tg, 'source', [])) - include_dirs = Utils.to_list(getattr(tg, 'msvs_includes', [])) - include_files = [] - for x in include_dirs: - if isinstance(x, str): - x = tg.path.find_node(x) - if x: - lst = [y for y in x.ant_glob(HEADERS_GLOB, flat=False)] - include_files.extend(lst) - - # remove duplicates - self.source.extend(list(set(source_files + include_files))) - self.source.sort(key=lambda x: x.win32path()) - - def collect_properties(self): - """ - Visual studio projects are associated with platforms and configurations (for building especially) - """ - super(vsnode_target, self).collect_properties() - for x in self.build_properties: - x.outdir = self.path.parent.win32path() - x.preprocessor_definitions = '' - x.includes_search_path = '' - - try: - tsk = self.tg.link_task - except AttributeError: - pass - else: - x.output_file = tsk.outputs[0].win32path() - x.preprocessor_definitions = ';'.join(tsk.env.DEFINES) - x.includes_search_path = ';'.join(self.tg.env.INCPATHS) - -class msvs_generator(BuildContext): - '''generates a visual studio 2010 solution''' - cmd = 'msvs' - fun = 'build' - numver = '11.00' # Visual Studio Version Number - vsver = '2010' # Visual Studio Version Year - platform_toolset_ver = 'v110' # Platform Toolset Version Number - - def init(self): - """ - Some data that needs to be present - """ - if not getattr(self, 'configurations', None): - self.configurations = ['Release'] # LocalRelease, RemoteDebug, etc - if not getattr(self, 'platforms', None): - self.platforms = ['Win32'] - if not getattr(self, 'all_projects', None): - self.all_projects = [] - if not getattr(self, 'project_extension', None): - self.project_extension = '.vcxproj' - if not getattr(self, 'projects_dir', None): - self.projects_dir = self.srcnode.make_node('.depproj') - self.projects_dir.mkdir() - - # bind the classes to the object, so that subclass can provide custom generators - if not getattr(self, 'vsnode_vsdir', None): - self.vsnode_vsdir = vsnode_vsdir - if not getattr(self, 'vsnode_target', None): - self.vsnode_target = vsnode_target - if not getattr(self, 'vsnode_build_all', None): - self.vsnode_build_all = vsnode_build_all - if not getattr(self, 'vsnode_install_all', None): - self.vsnode_install_all = vsnode_install_all - if not getattr(self, 'vsnode_project_view', None): - self.vsnode_project_view = vsnode_project_view - - self.numver = self.__class__.numver - self.vsver = self.__class__.vsver - self.platform_toolset_ver = self.__class__.platform_toolset_ver - - def execute(self): - """ - Entry point - """ - self.restore() - if not self.all_envs: - self.load_envs() - self.recurse([self.run_dir]) - - # user initialization - self.init() - - # two phases for creating the solution - self.collect_projects() # add project objects into "self.all_projects" - self.write_files() # write the corresponding project and solution files - - def collect_projects(self): - """ - Fill the list self.all_projects with project objects - Fill the list of build targets - """ - self.collect_targets() - self.add_aliases() - self.collect_dirs() - default_project = getattr(self, 'default_project', None) - def sortfun(x): - if x.name == default_project: - return '' - return getattr(x, 'path', None) and x.path.win32path() or x.name - self.all_projects.sort(key=sortfun) - - def write_files(self): - """ - Write the project and solution files from the data collected - so far. It is unlikely that you will want to change this - """ - for p in self.all_projects: - p.write() - - # and finally write the solution file - node = self.get_solution_node() - node.parent.mkdir() - Logs.warn('Creating %r', node) - template1 = compile_template(SOLUTION_TEMPLATE) - sln_str = template1(self) - sln_str = rm_blank_lines(sln_str) - node.stealth_write(sln_str) - - def get_solution_node(self): - """ - The solution filename is required when writing the .vcproj files - return self.solution_node and if it does not exist, make one - """ - try: - return self.solution_node - except AttributeError: - pass - - solution_name = getattr(self, 'solution_name', None) - if not solution_name: - solution_name = getattr(Context.g_module, Context.APPNAME, 'project') + '.sln' - if os.path.isabs(solution_name): - self.solution_node = self.root.make_node(solution_name) - else: - self.solution_node = self.srcnode.make_node(solution_name) - return self.solution_node - - def project_configurations(self): - """ - Helper that returns all the pairs (config,platform) - """ - ret = [] - for c in self.configurations: - for p in self.platforms: - ret.append((c, p)) - return ret - - def collect_targets(self): - """ - Process the list of task generators - """ - for g in self.groups: - for tg in g: - if not isinstance(tg, TaskGen.task_gen): - continue - - if not hasattr(tg, 'msvs_includes'): - tg.msvs_includes = tg.to_list(getattr(tg, 'includes', [])) + tg.to_list(getattr(tg, 'export_includes', [])) - tg.post() - if not getattr(tg, 'link_task', None): - continue - - p = self.vsnode_target(self, tg) - p.collect_source() # delegate this processing - p.collect_properties() - self.all_projects.append(p) - - def add_aliases(self): - """ - Add a specific target that emulates the "make all" necessary for Visual studio when pressing F7 - We also add an alias for "make install" (disabled by default) - """ - base = getattr(self, 'projects_dir', None) or self.tg.path - - node_project = base.make_node('build_all_projects' + self.project_extension) # Node - p_build = self.vsnode_build_all(self, node_project) - p_build.collect_properties() - self.all_projects.append(p_build) - - node_project = base.make_node('install_all_projects' + self.project_extension) # Node - p_install = self.vsnode_install_all(self, node_project) - p_install.collect_properties() - self.all_projects.append(p_install) - - node_project = base.make_node('project_view' + self.project_extension) # Node - p_view = self.vsnode_project_view(self, node_project) - p_view.collect_source() - p_view.collect_properties() - self.all_projects.append(p_view) - - n = self.vsnode_vsdir(self, make_uuid(self.srcnode.win32path() + 'build_aliases'), "build_aliases") - p_build.parent = p_install.parent = p_view.parent = n - self.all_projects.append(n) - - def collect_dirs(self): - """ - Create the folder structure in the Visual studio project view - """ - seen = {} - def make_parents(proj): - # look at a project, try to make a parent - if getattr(proj, 'parent', None): - # aliases already have parents - return - x = proj.iter_path - if x in seen: - proj.parent = seen[x] - return - - # There is not vsnode_vsdir for x. - # So create a project representing the folder "x" - n = proj.parent = seen[x] = self.vsnode_vsdir(self, make_uuid(x.win32path()), x.name) - n.iter_path = x.parent - self.all_projects.append(n) - - # recurse up to the project directory - if x.height() > self.srcnode.height() + 1: - make_parents(n) - - for p in self.all_projects[:]: # iterate over a copy of all projects - if not getattr(p, 'tg', None): - # but only projects that have a task generator - continue - - # make a folder for each task generator - p.iter_path = p.tg.path - make_parents(p) - -def wrap_2008(cls): - class dec(cls): - def __init__(self, *k, **kw): - cls.__init__(self, *k, **kw) - self.project_template = PROJECT_2008_TEMPLATE - - def display_filter(self): - - root = build_property() - root.subfilters = [] - root.sourcefiles = [] - root.source = [] - root.name = '' - - @Utils.run_once - def add_path(lst): - if not lst: - return root - child = build_property() - child.subfilters = [] - child.sourcefiles = [] - child.source = [] - child.name = lst[-1] - - par = add_path(lst[:-1]) - par.subfilters.append(child) - return child - - for x in self.source: - # this crap is for enabling subclasses to override get_filter_name - tmp = self.get_filter_name(x.parent) - tmp = tmp != '.' and tuple(tmp.split('\\')) or () - par = add_path(tmp) - par.source.append(x) - - def display(n): - buf = [] - for x in n.source: - buf.append('\n' % (xml_escape(x.win32path()), self.get_key(x))) - for x in n.subfilters: - buf.append('' % xml_escape(x.name)) - buf.append(display(x)) - buf.append('') - return '\n'.join(buf) - - return display(root) - - def get_key(self, node): - """ - If you do not want to let visual studio use the default file extensions, - override this method to return a value: - 0: C/C++ Code, 1: C++ Class, 2: C++ Header File, 3: C++ Form, - 4: C++ Control, 5: Text File, 6: DEF File, 7: IDL File, - 8: Makefile, 9: RGS File, 10: RC File, 11: RES File, 12: XSD File, - 13: XML File, 14: HTML File, 15: CSS File, 16: Bitmap, 17: Icon, - 18: Resx File, 19: BSC File, 20: XSX File, 21: C++ Web Service, - 22: ASAX File, 23: Asp Page, 24: Document, 25: Discovery File, - 26: C# File, 27: eFileTypeClassDiagram, 28: MHTML Document, - 29: Property Sheet, 30: Cursor, 31: Manifest, 32: eFileTypeRDLC - """ - return '' - - def write(self): - Logs.debug('msvs: creating %r', self.path) - template1 = compile_template(self.project_template) - proj_str = template1(self) - proj_str = rm_blank_lines(proj_str) - self.path.stealth_write(proj_str) - - return dec - -class msvs_2008_generator(msvs_generator): - '''generates a visual studio 2008 solution''' - cmd = 'msvs2008' - fun = msvs_generator.fun - numver = '10.00' - vsver = '2008' - - def init(self): - if not getattr(self, 'project_extension', None): - self.project_extension = '_2008.vcproj' - if not getattr(self, 'solution_name', None): - self.solution_name = getattr(Context.g_module, Context.APPNAME, 'project') + '_2008.sln' - - if not getattr(self, 'vsnode_target', None): - self.vsnode_target = wrap_2008(vsnode_target) - if not getattr(self, 'vsnode_build_all', None): - self.vsnode_build_all = wrap_2008(vsnode_build_all) - if not getattr(self, 'vsnode_install_all', None): - self.vsnode_install_all = wrap_2008(vsnode_install_all) - if not getattr(self, 'vsnode_project_view', None): - self.vsnode_project_view = wrap_2008(vsnode_project_view) - - msvs_generator.init(self) - -def options(ctx): - """ - If the msvs option is used, try to detect if the build is made from visual studio - """ - ctx.add_option('--execsolution', action='store', help='when building with visual studio, use a build state file') - - old = BuildContext.execute - def override_build_state(ctx): - def lock(rm, add): - uns = ctx.options.execsolution.replace('.sln', rm) - uns = ctx.root.make_node(uns) - try: - uns.delete() - except OSError: - pass - - uns = ctx.options.execsolution.replace('.sln', add) - uns = ctx.root.make_node(uns) - try: - uns.write('') - except EnvironmentError: - pass - - if ctx.options.execsolution: - ctx.launch_dir = Context.top_dir # force a build for the whole project (invalid cwd when called by visual studio) - lock('.lastbuildstate', '.unsuccessfulbuild') - old(ctx) - lock('.unsuccessfulbuild', '.lastbuildstate') - else: - old(ctx) - BuildContext.execute = override_build_state - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/netcache_client.py b/ldb-2.0.8/third_party/waf/waflib/extras/netcache_client.py deleted file mode 100644 index dc49048..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/netcache_client.py +++ /dev/null @@ -1,390 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2011-2015 (ita) - -""" -A client for the network cache (playground/netcache/). Launch the server with: -./netcache_server, then use it for the builds by adding the following: - - def build(bld): - bld.load('netcache_client') - -The parameters should be present in the environment in the form: - NETCACHE=host:port waf configure build - -Or in a more detailed way: - NETCACHE_PUSH=host:port NETCACHE_PULL=host:port waf configure build - -where: - host: host where the server resides, by default localhost - port: by default push on 11001 and pull on 12001 - -Use the server provided in playground/netcache/Netcache.java -""" - -import os, socket, time, atexit, sys -from waflib import Task, Logs, Utils, Build, Runner -from waflib.Configure import conf - -BUF = 8192 * 16 -HEADER_SIZE = 128 -MODES = ['PUSH', 'PULL', 'PUSH_PULL'] -STALE_TIME = 30 # seconds - -GET = 'GET' -PUT = 'PUT' -LST = 'LST' -BYE = 'BYE' - -all_sigs_in_cache = (0.0, []) - -def put_data(conn, data): - if sys.hexversion > 0x3000000: - data = data.encode('latin-1') - cnt = 0 - while cnt < len(data): - sent = conn.send(data[cnt:]) - if sent == 0: - raise RuntimeError('connection ended') - cnt += sent - -push_connections = Runner.Queue(0) -pull_connections = Runner.Queue(0) -def get_connection(push=False): - # return a new connection... do not forget to release it! - try: - if push: - ret = push_connections.get(block=False) - else: - ret = pull_connections.get(block=False) - except Exception: - ret = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - if push: - ret.connect(Task.push_addr) - else: - ret.connect(Task.pull_addr) - return ret - -def release_connection(conn, msg='', push=False): - if conn: - if push: - push_connections.put(conn) - else: - pull_connections.put(conn) - -def close_connection(conn, msg=''): - if conn: - data = '%s,%s' % (BYE, msg) - try: - put_data(conn, data.ljust(HEADER_SIZE)) - except: - pass - try: - conn.close() - except: - pass - -def close_all(): - for q in (push_connections, pull_connections): - while q.qsize(): - conn = q.get() - try: - close_connection(conn) - except: - # ignore errors when cleaning up - pass -atexit.register(close_all) - -def read_header(conn): - cnt = 0 - buf = [] - while cnt < HEADER_SIZE: - data = conn.recv(HEADER_SIZE - cnt) - if not data: - #import traceback - #traceback.print_stack() - raise ValueError('connection ended when reading a header %r' % buf) - buf.append(data) - cnt += len(data) - if sys.hexversion > 0x3000000: - ret = ''.encode('latin-1').join(buf) - ret = ret.decode('latin-1') - else: - ret = ''.join(buf) - return ret - -def check_cache(conn, ssig): - """ - List the files on the server, this is an optimization because it assumes that - concurrent builds are rare - """ - global all_sigs_in_cache - if not STALE_TIME: - return - if time.time() - all_sigs_in_cache[0] > STALE_TIME: - - params = (LST,'') - put_data(conn, ','.join(params).ljust(HEADER_SIZE)) - - # read what is coming back - ret = read_header(conn) - size = int(ret.split(',')[0]) - - buf = [] - cnt = 0 - while cnt < size: - data = conn.recv(min(BUF, size-cnt)) - if not data: - raise ValueError('connection ended %r %r' % (cnt, size)) - buf.append(data) - cnt += len(data) - - if sys.hexversion > 0x3000000: - ret = ''.encode('latin-1').join(buf) - ret = ret.decode('latin-1') - else: - ret = ''.join(buf) - - all_sigs_in_cache = (time.time(), ret.splitlines()) - Logs.debug('netcache: server cache has %r entries', len(all_sigs_in_cache[1])) - - if not ssig in all_sigs_in_cache[1]: - raise ValueError('no file %s in cache' % ssig) - -class MissingFile(Exception): - pass - -def recv_file(conn, ssig, count, p): - check_cache(conn, ssig) - - params = (GET, ssig, str(count)) - put_data(conn, ','.join(params).ljust(HEADER_SIZE)) - data = read_header(conn) - - size = int(data.split(',')[0]) - - if size == -1: - raise MissingFile('no file %s - %s in cache' % (ssig, count)) - - # get the file, writing immediately - # TODO a tmp file would be better - f = open(p, 'wb') - cnt = 0 - while cnt < size: - data = conn.recv(min(BUF, size-cnt)) - if not data: - raise ValueError('connection ended %r %r' % (cnt, size)) - f.write(data) - cnt += len(data) - f.close() - -def sock_send(conn, ssig, cnt, p): - #print "pushing %r %r %r" % (ssig, cnt, p) - size = os.stat(p).st_size - params = (PUT, ssig, str(cnt), str(size)) - put_data(conn, ','.join(params).ljust(HEADER_SIZE)) - f = open(p, 'rb') - cnt = 0 - while cnt < size: - r = f.read(min(BUF, size-cnt)) - while r: - k = conn.send(r) - if not k: - raise ValueError('connection ended') - cnt += k - r = r[k:] - -def can_retrieve_cache(self): - if not Task.pull_addr: - return False - if not self.outputs: - return False - self.cached = False - - cnt = 0 - sig = self.signature() - ssig = Utils.to_hex(self.uid() + sig) - - conn = None - err = False - try: - try: - conn = get_connection() - for node in self.outputs: - p = node.abspath() - recv_file(conn, ssig, cnt, p) - cnt += 1 - except MissingFile as e: - Logs.debug('netcache: file is not in the cache %r', e) - err = True - except Exception as e: - Logs.debug('netcache: could not get the files %r', self.outputs) - if Logs.verbose > 1: - Logs.debug('netcache: exception %r', e) - err = True - - # broken connection? remove this one - close_connection(conn) - conn = None - else: - Logs.debug('netcache: obtained %r from cache', self.outputs) - - finally: - release_connection(conn) - if err: - return False - - self.cached = True - return True - -@Utils.run_once -def put_files_cache(self): - if not Task.push_addr: - return - if not self.outputs: - return - if getattr(self, 'cached', None): - return - - #print "called put_files_cache", id(self) - bld = self.generator.bld - sig = self.signature() - ssig = Utils.to_hex(self.uid() + sig) - - conn = None - cnt = 0 - try: - for node in self.outputs: - # We could re-create the signature of the task with the signature of the outputs - # in practice, this means hashing the output files - # this is unnecessary - try: - if not conn: - conn = get_connection(push=True) - sock_send(conn, ssig, cnt, node.abspath()) - Logs.debug('netcache: sent %r', node) - except Exception as e: - Logs.debug('netcache: could not push the files %r', e) - - # broken connection? remove this one - close_connection(conn) - conn = None - cnt += 1 - finally: - release_connection(conn, push=True) - - bld.task_sigs[self.uid()] = self.cache_sig - -def hash_env_vars(self, env, vars_lst): - # reimplement so that the resulting hash does not depend on local paths - if not env.table: - env = env.parent - if not env: - return Utils.SIG_NIL - - idx = str(id(env)) + str(vars_lst) - try: - cache = self.cache_env - except AttributeError: - cache = self.cache_env = {} - else: - try: - return self.cache_env[idx] - except KeyError: - pass - - v = str([env[a] for a in vars_lst]) - v = v.replace(self.srcnode.abspath().__repr__()[:-1], '') - m = Utils.md5() - m.update(v.encode()) - ret = m.digest() - - Logs.debug('envhash: %r %r', ret, v) - - cache[idx] = ret - - return ret - -def uid(self): - # reimplement so that the signature does not depend on local paths - try: - return self.uid_ - except AttributeError: - m = Utils.md5() - src = self.generator.bld.srcnode - up = m.update - up(self.__class__.__name__.encode()) - for x in self.inputs + self.outputs: - up(x.path_from(src).encode()) - self.uid_ = m.digest() - return self.uid_ - - -def make_cached(cls): - if getattr(cls, 'nocache', None): - return - - m1 = cls.run - def run(self): - if getattr(self, 'nocache', False): - return m1(self) - if self.can_retrieve_cache(): - return 0 - return m1(self) - cls.run = run - - m2 = cls.post_run - def post_run(self): - if getattr(self, 'nocache', False): - return m2(self) - bld = self.generator.bld - ret = m2(self) - if bld.cache_global: - self.put_files_cache() - if hasattr(self, 'chmod'): - for node in self.outputs: - os.chmod(node.abspath(), self.chmod) - return ret - cls.post_run = post_run - -@conf -def setup_netcache(ctx, push_addr, pull_addr): - Task.Task.can_retrieve_cache = can_retrieve_cache - Task.Task.put_files_cache = put_files_cache - Task.Task.uid = uid - Task.push_addr = push_addr - Task.pull_addr = pull_addr - Build.BuildContext.hash_env_vars = hash_env_vars - ctx.cache_global = True - - for x in Task.classes.values(): - make_cached(x) - -def build(bld): - if not 'NETCACHE' in os.environ and not 'NETCACHE_PULL' in os.environ and not 'NETCACHE_PUSH' in os.environ: - Logs.warn('Setting NETCACHE_PULL=127.0.0.1:11001 and NETCACHE_PUSH=127.0.0.1:12001') - os.environ['NETCACHE_PULL'] = '127.0.0.1:12001' - os.environ['NETCACHE_PUSH'] = '127.0.0.1:11001' - - if 'NETCACHE' in os.environ: - if not 'NETCACHE_PUSH' in os.environ: - os.environ['NETCACHE_PUSH'] = os.environ['NETCACHE'] - if not 'NETCACHE_PULL' in os.environ: - os.environ['NETCACHE_PULL'] = os.environ['NETCACHE'] - - v = os.environ['NETCACHE_PULL'] - if v: - h, p = v.split(':') - pull_addr = (h, int(p)) - else: - pull_addr = None - - v = os.environ['NETCACHE_PUSH'] - if v: - h, p = v.split(':') - push_addr = (h, int(p)) - else: - push_addr = None - - setup_netcache(bld, push_addr, pull_addr) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/objcopy.py b/ldb-2.0.8/third_party/waf/waflib/extras/objcopy.py deleted file mode 100644 index bb7ca6e..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/objcopy.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/python -# Grygoriy Fuchedzhy 2010 - -""" -Support for converting linked targets to ihex, srec or binary files using -objcopy. Use the 'objcopy' feature in conjunction with the 'cc' or 'cxx' -feature. The 'objcopy' feature uses the following attributes: - -objcopy_bfdname Target object format name (eg. ihex, srec, binary). - Defaults to ihex. -objcopy_target File name used for objcopy output. This defaults to the - target name with objcopy_bfdname as extension. -objcopy_install_path Install path for objcopy_target file. Defaults to ${PREFIX}/fw. -objcopy_flags Additional flags passed to objcopy. -""" - -from waflib.Utils import def_attrs -from waflib import Task, Options -from waflib.TaskGen import feature, after_method - -class objcopy(Task.Task): - run_str = '${OBJCOPY} -O ${TARGET_BFDNAME} ${OBJCOPYFLAGS} ${SRC} ${TGT}' - color = 'CYAN' - -@feature('objcopy') -@after_method('apply_link') -def map_objcopy(self): - def_attrs(self, - objcopy_bfdname = 'ihex', - objcopy_target = None, - objcopy_install_path = "${PREFIX}/firmware", - objcopy_flags = '') - - link_output = self.link_task.outputs[0] - if not self.objcopy_target: - self.objcopy_target = link_output.change_ext('.' + self.objcopy_bfdname).name - task = self.create_task('objcopy', src=link_output, tgt=self.path.find_or_declare(self.objcopy_target)) - - task.env.append_unique('TARGET_BFDNAME', self.objcopy_bfdname) - try: - task.env.append_unique('OBJCOPYFLAGS', getattr(self, 'objcopy_flags')) - except AttributeError: - pass - - if self.objcopy_install_path: - self.add_install_files(install_to=self.objcopy_install_path, install_from=task.outputs[0]) - -def configure(ctx): - program_name = 'objcopy' - prefix = getattr(Options.options, 'cross_prefix', None) - if prefix: - program_name = '{}-{}'.format(prefix, program_name) - ctx.find_program(program_name, var='OBJCOPY', mandatory=True) diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/ocaml.py b/ldb-2.0.8/third_party/waf/waflib/extras/ocaml.py deleted file mode 100644 index 7d785c6..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/ocaml.py +++ /dev/null @@ -1,348 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2006-2010 (ita) - -"ocaml support" - -import os, re -from waflib import Utils, Task -from waflib.Logs import error -from waflib.TaskGen import feature, before_method, after_method, extension - -EXT_MLL = ['.mll'] -EXT_MLY = ['.mly'] -EXT_MLI = ['.mli'] -EXT_MLC = ['.c'] -EXT_ML = ['.ml'] - -open_re = re.compile(r'^\s*open\s+([a-zA-Z]+)(;;){0,1}$', re.M) -foo = re.compile(r"""(\(\*)|(\*\))|("(\\.|[^"\\])*"|'(\\.|[^'\\])*'|.[^()*"'\\]*)""", re.M) -def filter_comments(txt): - meh = [0] - def repl(m): - if m.group(1): - meh[0] += 1 - elif m.group(2): - meh[0] -= 1 - elif not meh[0]: - return m.group() - return '' - return foo.sub(repl, txt) - -def scan(self): - node = self.inputs[0] - code = filter_comments(node.read()) - - global open_re - names = [] - import_iterator = open_re.finditer(code) - if import_iterator: - for import_match in import_iterator: - names.append(import_match.group(1)) - found_lst = [] - raw_lst = [] - for name in names: - nd = None - for x in self.incpaths: - nd = x.find_resource(name.lower()+'.ml') - if not nd: - nd = x.find_resource(name+'.ml') - if nd: - found_lst.append(nd) - break - else: - raw_lst.append(name) - - return (found_lst, raw_lst) - -native_lst=['native', 'all', 'c_object'] -bytecode_lst=['bytecode', 'all'] - -@feature('ocaml') -def init_ml(self): - Utils.def_attrs(self, - type = 'all', - incpaths_lst = [], - bld_incpaths_lst = [], - mlltasks = [], - mlytasks = [], - mlitasks = [], - native_tasks = [], - bytecode_tasks = [], - linktasks = [], - bytecode_env = None, - native_env = None, - compiled_tasks = [], - includes = '', - uselib = '', - are_deps_set = 0) - -@feature('ocaml') -@after_method('init_ml') -def init_envs_ml(self): - - self.islibrary = getattr(self, 'islibrary', False) - - global native_lst, bytecode_lst - self.native_env = None - if self.type in native_lst: - self.native_env = self.env.derive() - if self.islibrary: - self.native_env['OCALINKFLAGS'] = '-a' - - self.bytecode_env = None - if self.type in bytecode_lst: - self.bytecode_env = self.env.derive() - if self.islibrary: - self.bytecode_env['OCALINKFLAGS'] = '-a' - - if self.type == 'c_object': - self.native_env.append_unique('OCALINKFLAGS_OPT', '-output-obj') - -@feature('ocaml') -@before_method('apply_vars_ml') -@after_method('init_envs_ml') -def apply_incpaths_ml(self): - inc_lst = self.includes.split() - lst = self.incpaths_lst - for dir in inc_lst: - node = self.path.find_dir(dir) - if not node: - error("node not found: " + str(dir)) - continue - if not node in lst: - lst.append(node) - self.bld_incpaths_lst.append(node) - # now the nodes are added to self.incpaths_lst - -@feature('ocaml') -@before_method('process_source') -def apply_vars_ml(self): - for i in self.incpaths_lst: - if self.bytecode_env: - app = self.bytecode_env.append_value - app('OCAMLPATH', ['-I', i.bldpath(), '-I', i.srcpath()]) - - if self.native_env: - app = self.native_env.append_value - app('OCAMLPATH', ['-I', i.bldpath(), '-I', i.srcpath()]) - - varnames = ['INCLUDES', 'OCAMLFLAGS', 'OCALINKFLAGS', 'OCALINKFLAGS_OPT'] - for name in self.uselib.split(): - for vname in varnames: - cnt = self.env[vname+'_'+name] - if cnt: - if self.bytecode_env: - self.bytecode_env.append_value(vname, cnt) - if self.native_env: - self.native_env.append_value(vname, cnt) - -@feature('ocaml') -@after_method('process_source') -def apply_link_ml(self): - - if self.bytecode_env: - ext = self.islibrary and '.cma' or '.run' - - linktask = self.create_task('ocalink') - linktask.bytecode = 1 - linktask.set_outputs(self.path.find_or_declare(self.target + ext)) - linktask.env = self.bytecode_env - self.linktasks.append(linktask) - - if self.native_env: - if self.type == 'c_object': - ext = '.o' - elif self.islibrary: - ext = '.cmxa' - else: - ext = '' - - linktask = self.create_task('ocalinkx') - linktask.set_outputs(self.path.find_or_declare(self.target + ext)) - linktask.env = self.native_env - self.linktasks.append(linktask) - - # we produce a .o file to be used by gcc - self.compiled_tasks.append(linktask) - -@extension(*EXT_MLL) -def mll_hook(self, node): - mll_task = self.create_task('ocamllex', node, node.change_ext('.ml')) - mll_task.env = self.native_env.derive() - self.mlltasks.append(mll_task) - - self.source.append(mll_task.outputs[0]) - -@extension(*EXT_MLY) -def mly_hook(self, node): - mly_task = self.create_task('ocamlyacc', node, [node.change_ext('.ml'), node.change_ext('.mli')]) - mly_task.env = self.native_env.derive() - self.mlytasks.append(mly_task) - self.source.append(mly_task.outputs[0]) - - task = self.create_task('ocamlcmi', mly_task.outputs[1], mly_task.outputs[1].change_ext('.cmi')) - task.env = self.native_env.derive() - -@extension(*EXT_MLI) -def mli_hook(self, node): - task = self.create_task('ocamlcmi', node, node.change_ext('.cmi')) - task.env = self.native_env.derive() - self.mlitasks.append(task) - -@extension(*EXT_MLC) -def mlc_hook(self, node): - task = self.create_task('ocamlcc', node, node.change_ext('.o')) - task.env = self.native_env.derive() - self.compiled_tasks.append(task) - -@extension(*EXT_ML) -def ml_hook(self, node): - if self.native_env: - task = self.create_task('ocamlx', node, node.change_ext('.cmx')) - task.env = self.native_env.derive() - task.incpaths = self.bld_incpaths_lst - self.native_tasks.append(task) - - if self.bytecode_env: - task = self.create_task('ocaml', node, node.change_ext('.cmo')) - task.env = self.bytecode_env.derive() - task.bytecode = 1 - task.incpaths = self.bld_incpaths_lst - self.bytecode_tasks.append(task) - -def compile_may_start(self): - - if not getattr(self, 'flag_deps', ''): - self.flag_deps = 1 - - # the evil part is that we can only compute the dependencies after the - # source files can be read (this means actually producing the source files) - if getattr(self, 'bytecode', ''): - alltasks = self.generator.bytecode_tasks - else: - alltasks = self.generator.native_tasks - - self.signature() # ensure that files are scanned - unfortunately - tree = self.generator.bld - for node in self.inputs: - lst = tree.node_deps[self.uid()] - for depnode in lst: - for t in alltasks: - if t == self: - continue - if depnode in t.inputs: - self.set_run_after(t) - - # TODO necessary to get the signature right - for now - delattr(self, 'cache_sig') - self.signature() - - return Task.Task.runnable_status(self) - -class ocamlx(Task.Task): - """native caml compilation""" - color = 'GREEN' - run_str = '${OCAMLOPT} ${OCAMLPATH} ${OCAMLFLAGS} ${OCAMLINCLUDES} -c -o ${TGT} ${SRC}' - scan = scan - runnable_status = compile_may_start - -class ocaml(Task.Task): - """bytecode caml compilation""" - color = 'GREEN' - run_str = '${OCAMLC} ${OCAMLPATH} ${OCAMLFLAGS} ${OCAMLINCLUDES} -c -o ${TGT} ${SRC}' - scan = scan - runnable_status = compile_may_start - -class ocamlcmi(Task.Task): - """interface generator (the .i files?)""" - color = 'BLUE' - run_str = '${OCAMLC} ${OCAMLPATH} ${OCAMLINCLUDES} -o ${TGT} -c ${SRC}' - before = ['ocamlcc', 'ocaml', 'ocamlcc'] - -class ocamlcc(Task.Task): - """ocaml to c interfaces""" - color = 'GREEN' - run_str = 'cd ${TGT[0].bld_dir()} && ${OCAMLOPT} ${OCAMLFLAGS} ${OCAMLPATH} ${OCAMLINCLUDES} -c ${SRC[0].abspath()}' - -class ocamllex(Task.Task): - """lexical generator""" - color = 'BLUE' - run_str = '${OCAMLLEX} ${SRC} -o ${TGT}' - before = ['ocamlcmi', 'ocaml', 'ocamlcc'] - -class ocamlyacc(Task.Task): - """parser generator""" - color = 'BLUE' - run_str = '${OCAMLYACC} -b ${tsk.base()} ${SRC}' - before = ['ocamlcmi', 'ocaml', 'ocamlcc'] - - def base(self): - node = self.outputs[0] - s = os.path.splitext(node.name)[0] - return node.bld_dir() + os.sep + s - -def link_may_start(self): - - if getattr(self, 'bytecode', 0): - alltasks = self.generator.bytecode_tasks - else: - alltasks = self.generator.native_tasks - - for x in alltasks: - if not x.hasrun: - return Task.ASK_LATER - - if not getattr(self, 'order', ''): - - # now reorder the inputs given the task dependencies - # this part is difficult, we do not have a total order on the tasks - # if the dependencies are wrong, this may not stop - seen = [] - pendant = []+alltasks - while pendant: - task = pendant.pop(0) - if task in seen: - continue - for x in task.run_after: - if not x in seen: - pendant.append(task) - break - else: - seen.append(task) - self.inputs = [x.outputs[0] for x in seen] - self.order = 1 - return Task.Task.runnable_status(self) - -class ocalink(Task.Task): - """bytecode caml link""" - color = 'YELLOW' - run_str = '${OCAMLC} -o ${TGT} ${OCAMLINCLUDES} ${OCALINKFLAGS} ${SRC}' - runnable_status = link_may_start - after = ['ocaml', 'ocamlcc'] - -class ocalinkx(Task.Task): - """native caml link""" - color = 'YELLOW' - run_str = '${OCAMLOPT} -o ${TGT} ${OCAMLINCLUDES} ${OCALINKFLAGS_OPT} ${SRC}' - runnable_status = link_may_start - after = ['ocamlx', 'ocamlcc'] - -def configure(conf): - opt = conf.find_program('ocamlopt', var='OCAMLOPT', mandatory=False) - occ = conf.find_program('ocamlc', var='OCAMLC', mandatory=False) - if (not opt) or (not occ): - conf.fatal('The objective caml compiler was not found:\ninstall it or make it available in your PATH') - - v = conf.env - v['OCAMLC'] = occ - v['OCAMLOPT'] = opt - v['OCAMLLEX'] = conf.find_program('ocamllex', var='OCAMLLEX', mandatory=False) - v['OCAMLYACC'] = conf.find_program('ocamlyacc', var='OCAMLYACC', mandatory=False) - v['OCAMLFLAGS'] = '' - where = conf.cmd_and_log(conf.env.OCAMLC + ['-where']).strip()+os.sep - v['OCAMLLIB'] = where - v['LIBPATH_OCAML'] = where - v['INCLUDES_OCAML'] = where - v['LIB_OCAML'] = 'camlrun' - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/package.py b/ldb-2.0.8/third_party/waf/waflib/extras/package.py deleted file mode 100644 index c06498e..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/package.py +++ /dev/null @@ -1,76 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2011 - -""" -Obtain packages, unpack them in a location, and add associated uselib variables -(CFLAGS_pkgname, LIBPATH_pkgname, etc). - -The default is use a Dependencies.txt file in the source directory. - -This is a work in progress. - -Usage: - -def options(opt): - opt.load('package') - -def configure(conf): - conf.load_packages() -""" - -from waflib import Logs -from waflib.Configure import conf - -try: - from urllib import request -except ImportError: - from urllib import urlopen -else: - urlopen = request.urlopen - - -CACHEVAR = 'WAFCACHE_PACKAGE' - -@conf -def get_package_cache_dir(self): - cache = None - if CACHEVAR in conf.environ: - cache = conf.environ[CACHEVAR] - cache = self.root.make_node(cache) - elif self.env[CACHEVAR]: - cache = self.env[CACHEVAR] - cache = self.root.make_node(cache) - else: - cache = self.srcnode.make_node('.wafcache_package') - cache.mkdir() - return cache - -@conf -def download_archive(self, src, dst): - for x in self.env.PACKAGE_REPO: - url = '/'.join((x, src)) - try: - web = urlopen(url) - try: - if web.getcode() != 200: - continue - except AttributeError: - pass - except Exception: - # on python3 urlopen throws an exception - # python 2.3 does not have getcode and throws an exception to fail - continue - else: - tmp = self.root.make_node(dst) - tmp.write(web.read()) - Logs.warn('Downloaded %s from %s', tmp.abspath(), url) - break - else: - self.fatal('Could not get the package %s' % src) - -@conf -def load_packages(self): - self.get_package_cache_dir() - # read the dependencies, get the archives, .. - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/parallel_debug.py b/ldb-2.0.8/third_party/waf/waflib/extras/parallel_debug.py deleted file mode 100644 index 4ffec5e..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/parallel_debug.py +++ /dev/null @@ -1,462 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2007-2010 (ita) - -""" -Debugging helper for parallel compilation. - -Copy it to your project and load it with:: - - def options(opt): - opt.load('parallel_debug', tooldir='.') - def build(bld): - ... - -The build will then output a file named pdebug.svg in the source directory. -""" - -import re, sys, threading, time, traceback -try: - from Queue import Queue -except: - from queue import Queue -from waflib import Runner, Options, Task, Logs, Errors - -SVG_TEMPLATE = """ - - - - - - - - - - -${if project.title} - ${project.title} -${endif} - - -${for cls in project.groups} - - ${for rect in cls.rects} - - ${endfor} - -${endfor} - -${for info in project.infos} - - - ${info.text} - -${endfor} - -${if project.tooltip} - - - - -${endif} - - -""" - -COMPILE_TEMPLATE = '''def f(project): - lst = [] - def xml_escape(value): - return value.replace("&", "&").replace('"', """).replace("'", "'").replace("<", "<").replace(">", ">") - - %s - return ''.join(lst) -''' -reg_act = re.compile(r"(?P\\)|(?P\$\$)|(?P\$\{(?P[^}]*?)\})", re.M) -def compile_template(line): - - extr = [] - def repl(match): - g = match.group - if g('dollar'): - return "$" - elif g('backslash'): - return "\\" - elif g('subst'): - extr.append(g('code')) - return "<<|@|>>" - return None - - line2 = reg_act.sub(repl, line) - params = line2.split('<<|@|>>') - assert(extr) - - - indent = 0 - buf = [] - app = buf.append - - def app(txt): - buf.append(indent * '\t' + txt) - - for x in range(len(extr)): - if params[x]: - app("lst.append(%r)" % params[x]) - - f = extr[x] - if f.startswith(('if', 'for')): - app(f + ':') - indent += 1 - elif f.startswith('py:'): - app(f[3:]) - elif f.startswith(('endif', 'endfor')): - indent -= 1 - elif f.startswith(('else', 'elif')): - indent -= 1 - app(f + ':') - indent += 1 - elif f.startswith('xml:'): - app('lst.append(xml_escape(%s))' % f[4:]) - else: - #app('lst.append((%s) or "cannot find %s")' % (f, f)) - app('lst.append(str(%s))' % f) - - if extr: - if params[-1]: - app("lst.append(%r)" % params[-1]) - - fun = COMPILE_TEMPLATE % "\n\t".join(buf) - # uncomment the following to debug the template - #for i, x in enumerate(fun.splitlines()): - # print i, x - return Task.funex(fun) - -# red #ff4d4d -# green #4da74d -# lila #a751ff - -color2code = { - 'GREEN' : '#4da74d', - 'YELLOW' : '#fefe44', - 'PINK' : '#a751ff', - 'RED' : '#cc1d1d', - 'BLUE' : '#6687bb', - 'CYAN' : '#34e2e2', -} - -mp = {} -info = [] # list of (text,color) - -def map_to_color(name): - if name in mp: - return mp[name] - try: - cls = Task.classes[name] - except KeyError: - return color2code['RED'] - if cls.color in mp: - return mp[cls.color] - if cls.color in color2code: - return color2code[cls.color] - return color2code['RED'] - -def process(self): - m = self.generator.bld.producer - try: - # TODO another place for this? - del self.generator.bld.task_sigs[self.uid()] - except KeyError: - pass - - self.generator.bld.producer.set_running(1, self) - - try: - ret = self.run() - except Exception: - self.err_msg = traceback.format_exc() - self.hasrun = Task.EXCEPTION - - # TODO cleanup - m.error_handler(self) - return - - if ret: - self.err_code = ret - self.hasrun = Task.CRASHED - else: - try: - self.post_run() - except Errors.WafError: - pass - except Exception: - self.err_msg = traceback.format_exc() - self.hasrun = Task.EXCEPTION - else: - self.hasrun = Task.SUCCESS - if self.hasrun != Task.SUCCESS: - m.error_handler(self) - - self.generator.bld.producer.set_running(-1, self) - -Task.Task.process_back = Task.Task.process -Task.Task.process = process - -old_start = Runner.Parallel.start -def do_start(self): - try: - Options.options.dband - except AttributeError: - self.bld.fatal('use def options(opt): opt.load("parallel_debug")!') - - self.taskinfo = Queue() - old_start(self) - if self.dirty: - make_picture(self) -Runner.Parallel.start = do_start - -lock_running = threading.Lock() -def set_running(self, by, tsk): - with lock_running: - try: - cache = self.lock_cache - except AttributeError: - cache = self.lock_cache = {} - - i = 0 - if by > 0: - vals = cache.values() - for i in range(self.numjobs): - if i not in vals: - cache[tsk] = i - break - else: - i = cache[tsk] - del cache[tsk] - - self.taskinfo.put( (i, id(tsk), time.time(), tsk.__class__.__name__, self.processed, self.count, by, ",".join(map(str, tsk.outputs))) ) -Runner.Parallel.set_running = set_running - -def name2class(name): - return name.replace(' ', '_').replace('.', '_') - -def make_picture(producer): - # first, cast the parameters - if not hasattr(producer.bld, 'path'): - return - - tmp = [] - try: - while True: - tup = producer.taskinfo.get(False) - tmp.append(list(tup)) - except: - pass - - try: - ini = float(tmp[0][2]) - except: - return - - if not info: - seen = [] - for x in tmp: - name = x[3] - if not name in seen: - seen.append(name) - else: - continue - - info.append((name, map_to_color(name))) - info.sort(key=lambda x: x[0]) - - thread_count = 0 - acc = [] - for x in tmp: - thread_count += x[6] - acc.append("%d %d %f %r %d %d %d %s" % (x[0], x[1], x[2] - ini, x[3], x[4], x[5], thread_count, x[7])) - - data_node = producer.bld.path.make_node('pdebug.dat') - data_node.write('\n'.join(acc)) - - tmp = [lst[:2] + [float(lst[2]) - ini] + lst[3:] for lst in tmp] - - st = {} - for l in tmp: - if not l[0] in st: - st[l[0]] = len(st.keys()) - tmp = [ [st[lst[0]]] + lst[1:] for lst in tmp ] - THREAD_AMOUNT = len(st.keys()) - - st = {} - for l in tmp: - if not l[1] in st: - st[l[1]] = len(st.keys()) - tmp = [ [lst[0]] + [st[lst[1]]] + lst[2:] for lst in tmp ] - - - BAND = Options.options.dband - - seen = {} - acc = [] - for x in range(len(tmp)): - line = tmp[x] - id = line[1] - - if id in seen: - continue - seen[id] = True - - begin = line[2] - thread_id = line[0] - for y in range(x + 1, len(tmp)): - line = tmp[y] - if line[1] == id: - end = line[2] - #print id, thread_id, begin, end - #acc.append( ( 10*thread_id, 10*(thread_id+1), 10*begin, 10*end ) ) - acc.append( (BAND * begin, BAND*thread_id, BAND*end - BAND*begin, BAND, line[3], line[7]) ) - break - - if Options.options.dmaxtime < 0.1: - gwidth = 1 - for x in tmp: - m = BAND * x[2] - if m > gwidth: - gwidth = m - else: - gwidth = BAND * Options.options.dmaxtime - - ratio = float(Options.options.dwidth) / gwidth - gwidth = Options.options.dwidth - gheight = BAND * (THREAD_AMOUNT + len(info) + 1.5) - - - # simple data model for our template - class tobject(object): - pass - - model = tobject() - model.x = 0 - model.y = 0 - model.width = gwidth + 4 - model.height = gheight + 4 - - model.tooltip = not Options.options.dnotooltip - - model.title = Options.options.dtitle - model.title_x = gwidth / 2 - model.title_y = gheight + - 5 - - groups = {} - for (x, y, w, h, clsname, name) in acc: - try: - groups[clsname].append((x, y, w, h, name)) - except: - groups[clsname] = [(x, y, w, h, name)] - - # groups of rectangles (else js highlighting is slow) - model.groups = [] - for cls in groups: - g = tobject() - model.groups.append(g) - g.classname = name2class(cls) - g.rects = [] - for (x, y, w, h, name) in groups[cls]: - r = tobject() - g.rects.append(r) - r.x = 2 + x * ratio - r.y = 2 + y - r.width = w * ratio - r.height = h - r.name = name - r.color = map_to_color(cls) - - cnt = THREAD_AMOUNT - - # caption - model.infos = [] - for (text, color) in info: - inf = tobject() - model.infos.append(inf) - inf.classname = name2class(text) - inf.x = 2 + BAND - inf.y = 5 + (cnt + 0.5) * BAND - inf.width = BAND/2 - inf.height = BAND/2 - inf.color = color - - inf.text = text - inf.text_x = 2 + 2 * BAND - inf.text_y = 5 + (cnt + 0.5) * BAND + 10 - - cnt += 1 - - # write the file... - template1 = compile_template(SVG_TEMPLATE) - txt = template1(model) - - node = producer.bld.path.make_node('pdebug.svg') - node.write(txt) - Logs.warn('Created the diagram %r', node) - -def options(opt): - opt.add_option('--dtitle', action='store', default='Parallel build representation for %r' % ' '.join(sys.argv), - help='title for the svg diagram', dest='dtitle') - opt.add_option('--dwidth', action='store', type='int', help='diagram width', default=800, dest='dwidth') - opt.add_option('--dtime', action='store', type='float', help='recording interval in seconds', default=0.009, dest='dtime') - opt.add_option('--dband', action='store', type='int', help='band width', default=22, dest='dband') - opt.add_option('--dmaxtime', action='store', type='float', help='maximum time, for drawing fair comparisons', default=0, dest='dmaxtime') - opt.add_option('--dnotooltip', action='store_true', help='disable tooltips', default=False, dest='dnotooltip') - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/pch.py b/ldb-2.0.8/third_party/waf/waflib/extras/pch.py deleted file mode 100644 index 103e752..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/pch.py +++ /dev/null @@ -1,148 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Alexander Afanasyev (UCLA), 2014 - -""" -Enable precompiled C++ header support (currently only clang++ and g++ are supported) - -To use this tool, wscript should look like: - - def options(opt): - opt.load('pch') - # This will add `--with-pch` configure option. - # Unless --with-pch during configure stage specified, the precompiled header support is disabled - - def configure(conf): - conf.load('pch') - # this will set conf.env.WITH_PCH if --with-pch is specified and the supported compiler is used - # Unless conf.env.WITH_PCH is set, the precompiled header support is disabled - - def build(bld): - bld(features='cxx pch', - target='precompiled-headers', - name='precompiled-headers', - headers='a.h b.h c.h', # headers to pre-compile into `precompiled-headers` - - # Other parameters to compile precompiled headers - # includes=..., - # export_includes=..., - # use=..., - # ... - - # Exported parameters will be propagated even if precompiled headers are disabled - ) - - bld( - target='test', - features='cxx cxxprogram', - source='a.cpp b.cpp d.cpp main.cpp', - use='precompiled-headers', - ) - - # or - - bld( - target='test', - features='pch cxx cxxprogram', - source='a.cpp b.cpp d.cpp main.cpp', - headers='a.h b.h c.h', - ) - -Note that precompiled header must have multiple inclusion guards. If the guards are missing, any benefit of precompiled header will be voided and compilation may fail in some cases. -""" - -import os -from waflib import Task, TaskGen, Utils -from waflib.Tools import c_preproc, cxx - - -PCH_COMPILER_OPTIONS = { - 'clang++': [['-include'], '.pch', ['-x', 'c++-header']], - 'g++': [['-include'], '.gch', ['-x', 'c++-header']], -} - - -def options(opt): - opt.add_option('--without-pch', action='store_false', default=True, dest='with_pch', help='''Try to use precompiled header to speed up compilation (only g++ and clang++)''') - -def configure(conf): - if (conf.options.with_pch and conf.env['COMPILER_CXX'] in PCH_COMPILER_OPTIONS.keys()): - conf.env.WITH_PCH = True - flags = PCH_COMPILER_OPTIONS[conf.env['COMPILER_CXX']] - conf.env.CXXPCH_F = flags[0] - conf.env.CXXPCH_EXT = flags[1] - conf.env.CXXPCH_FLAGS = flags[2] - - -@TaskGen.feature('pch') -@TaskGen.before('process_source') -def apply_pch(self): - if not self.env.WITH_PCH: - return - - if getattr(self.bld, 'pch_tasks', None) is None: - self.bld.pch_tasks = {} - - if getattr(self, 'headers', None) is None: - return - - self.headers = self.to_nodes(self.headers) - - if getattr(self, 'name', None): - try: - task = self.bld.pch_tasks["%s.%s" % (self.name, self.idx)] - self.bld.fatal("Duplicated 'pch' task with name %r" % "%s.%s" % (self.name, self.idx)) - except KeyError: - pass - - out = '%s.%d%s' % (self.target, self.idx, self.env['CXXPCH_EXT']) - out = self.path.find_or_declare(out) - task = self.create_task('gchx', self.headers, out) - - # target should be an absolute path of `out`, but without precompiled header extension - task.target = out.abspath()[:-len(out.suffix())] - - self.pch_task = task - if getattr(self, 'name', None): - self.bld.pch_tasks["%s.%s" % (self.name, self.idx)] = task - -@TaskGen.feature('cxx') -@TaskGen.after_method('process_source', 'propagate_uselib_vars') -def add_pch(self): - if not (self.env['WITH_PCH'] and getattr(self, 'use', None) and getattr(self, 'compiled_tasks', None) and getattr(self.bld, 'pch_tasks', None)): - return - - pch = None - # find pch task, if any - - if getattr(self, 'pch_task', None): - pch = self.pch_task - else: - for use in Utils.to_list(self.use): - try: - pch = self.bld.pch_tasks[use] - except KeyError: - pass - - if pch: - for x in self.compiled_tasks: - x.env.append_value('CXXFLAGS', self.env['CXXPCH_F'] + [pch.target]) - -class gchx(Task.Task): - run_str = '${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${CXXPCH_FLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXXPCH_F:SRC} ${CXX_SRC_F}${SRC[0].abspath()} ${CXX_TGT_F}${TGT[0].abspath()} ${CPPFLAGS}' - scan = c_preproc.scan - color = 'BLUE' - ext_out=['.h'] - - def runnable_status(self): - try: - node_deps = self.generator.bld.node_deps[self.uid()] - except KeyError: - node_deps = [] - ret = Task.Task.runnable_status(self) - if ret == Task.SKIP_ME and self.env.CXX_NAME == 'clang': - t = os.stat(self.outputs[0].abspath()).st_mtime - for n in self.inputs + node_deps: - if os.stat(n.abspath()).st_mtime > t: - return Task.RUN_ME - return ret diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/pep8.py b/ldb-2.0.8/third_party/waf/waflib/extras/pep8.py deleted file mode 100644 index 676beed..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/pep8.py +++ /dev/null @@ -1,106 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# -# written by Sylvain Rouquette, 2011 - -''' -Install pep8 module: -$ easy_install pep8 - or -$ pip install pep8 - -To add the pep8 tool to the waf file: -$ ./waf-light --tools=compat15,pep8 - or, if you have waf >= 1.6.2 -$ ./waf update --files=pep8 - - -Then add this to your wscript: - -[at]extension('.py', 'wscript') -def run_pep8(self, node): - self.create_task('Pep8', node) - -''' - -import threading -from waflib import Task, Options - -pep8 = __import__('pep8') - - -class Pep8(Task.Task): - color = 'PINK' - lock = threading.Lock() - - def check_options(self): - if pep8.options: - return - pep8.options = Options.options - pep8.options.prog = 'pep8' - excl = pep8.options.exclude.split(',') - pep8.options.exclude = [s.rstrip('/') for s in excl] - if pep8.options.filename: - pep8.options.filename = pep8.options.filename.split(',') - if pep8.options.select: - pep8.options.select = pep8.options.select.split(',') - else: - pep8.options.select = [] - if pep8.options.ignore: - pep8.options.ignore = pep8.options.ignore.split(',') - elif pep8.options.select: - # Ignore all checks which are not explicitly selected - pep8.options.ignore = [''] - elif pep8.options.testsuite or pep8.options.doctest: - # For doctest and testsuite, all checks are required - pep8.options.ignore = [] - else: - # The default choice: ignore controversial checks - pep8.options.ignore = pep8.DEFAULT_IGNORE.split(',') - pep8.options.physical_checks = pep8.find_checks('physical_line') - pep8.options.logical_checks = pep8.find_checks('logical_line') - pep8.options.counters = dict.fromkeys(pep8.BENCHMARK_KEYS, 0) - pep8.options.messages = {} - - def run(self): - with Pep8.lock: - self.check_options() - pep8.input_file(self.inputs[0].abspath()) - return 0 if not pep8.get_count() else -1 - - -def options(opt): - opt.add_option('-q', '--quiet', default=0, action='count', - help="report only file names, or nothing with -qq") - opt.add_option('-r', '--repeat', action='store_true', - help="show all occurrences of the same error") - opt.add_option('--exclude', metavar='patterns', - default=pep8.DEFAULT_EXCLUDE, - help="exclude files or directories which match these " - "comma separated patterns (default: %s)" % - pep8.DEFAULT_EXCLUDE, - dest='exclude') - opt.add_option('--filename', metavar='patterns', default='*.py', - help="when parsing directories, only check filenames " - "matching these comma separated patterns (default: " - "*.py)") - opt.add_option('--select', metavar='errors', default='', - help="select errors and warnings (e.g. E,W6)") - opt.add_option('--ignore', metavar='errors', default='', - help="skip errors and warnings (e.g. E4,W)") - opt.add_option('--show-source', action='store_true', - help="show source code for each error") - opt.add_option('--show-pep8', action='store_true', - help="show text of PEP 8 for each error") - opt.add_option('--statistics', action='store_true', - help="count errors and warnings") - opt.add_option('--count', action='store_true', - help="print total number of errors and warnings " - "to standard error and set exit code to 1 if " - "total is not null") - opt.add_option('--benchmark', action='store_true', - help="measure processing speed") - opt.add_option('--testsuite', metavar='dir', - help="run regression tests from dir") - opt.add_option('--doctest', action='store_true', - help="run doctest on myself") diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/pgicc.py b/ldb-2.0.8/third_party/waf/waflib/extras/pgicc.py deleted file mode 100644 index f8068d5..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/pgicc.py +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Antoine Dechaume 2011 - -""" -Detect the PGI C compiler -""" - -import sys, re -from waflib import Errors -from waflib.Configure import conf -from waflib.Tools.compiler_c import c_compiler -c_compiler['linux'].append('pgicc') - -@conf -def find_pgi_compiler(conf, var, name): - """ - Find the program name, and execute it to ensure it really is itself. - """ - if sys.platform == 'cygwin': - conf.fatal('The PGI compiler does not work on Cygwin') - - v = conf.env - cc = None - if v[var]: - cc = v[var] - elif var in conf.environ: - cc = conf.environ[var] - if not cc: - cc = conf.find_program(name, var=var) - if not cc: - conf.fatal('PGI Compiler (%s) was not found' % name) - - v[var + '_VERSION'] = conf.get_pgi_version(cc) - v[var] = cc - v[var + '_NAME'] = 'pgi' - -@conf -def get_pgi_version(conf, cc): - """Find the version of a pgi compiler.""" - version_re = re.compile(r"The Portland Group", re.I).search - cmd = cc + ['-V', '-E'] # Issue 1078, prevent wrappers from linking - - try: - out, err = conf.cmd_and_log(cmd, output=0) - except Errors.WafError: - conf.fatal('Could not find pgi compiler %r' % cmd) - - if out: - match = version_re(out) - else: - match = version_re(err) - - if not match: - conf.fatal('Could not verify PGI signature') - - cmd = cc + ['-help=variable'] - try: - out, err = conf.cmd_and_log(cmd, output=0) - except Errors.WafError: - conf.fatal('Could not find pgi compiler %r' % cmd) - - version = re.findall(r'^COMPVER\s*=(.*)', out, re.M) - if len(version) != 1: - conf.fatal('Could not determine the compiler version') - return version[0] - -def configure(conf): - conf.find_pgi_compiler('CC', 'pgcc') - conf.find_ar() - conf.gcc_common_flags() - conf.cc_load_tools() - conf.cc_add_flags() - conf.link_add_flags() - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/pgicxx.py b/ldb-2.0.8/third_party/waf/waflib/extras/pgicxx.py deleted file mode 100644 index eae121c..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/pgicxx.py +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Antoine Dechaume 2011 - -""" -Detect the PGI C++ compiler -""" - -from waflib.Tools.compiler_cxx import cxx_compiler -cxx_compiler['linux'].append('pgicxx') - -from waflib.extras import pgicc - -def configure(conf): - conf.find_pgi_compiler('CXX', 'pgCC') - conf.find_ar() - conf.gxx_common_flags() - conf.cxx_load_tools() - conf.cxx_add_flags() - conf.link_add_flags() diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/proc.py b/ldb-2.0.8/third_party/waf/waflib/extras/proc.py deleted file mode 100644 index 764abec..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/proc.py +++ /dev/null @@ -1,54 +0,0 @@ -#! /usr/bin/env python -# per rosengren 2011 - -from os import environ, path -from waflib import TaskGen, Utils - -def options(opt): - grp = opt.add_option_group('Oracle ProC Options') - grp.add_option('--oracle_home', action='store', default=environ.get('PROC_ORACLE'), help='Path to Oracle installation home (has bin/lib)') - grp.add_option('--tns_admin', action='store', default=environ.get('TNS_ADMIN'), help='Directory containing server list (TNS_NAMES.ORA)') - grp.add_option('--connection', action='store', default='dummy-user/dummy-password@dummy-server', help='Format: user/password@server') - -def configure(cnf): - env = cnf.env - if not env.PROC_ORACLE: - env.PROC_ORACLE = cnf.options.oracle_home - if not env.PROC_TNS_ADMIN: - env.PROC_TNS_ADMIN = cnf.options.tns_admin - if not env.PROC_CONNECTION: - env.PROC_CONNECTION = cnf.options.connection - cnf.find_program('proc', var='PROC', path_list=env.PROC_ORACLE + path.sep + 'bin') - -def proc(tsk): - env = tsk.env - gen = tsk.generator - inc_nodes = gen.to_incnodes(Utils.to_list(getattr(gen,'includes',[])) + env['INCLUDES']) - - cmd = ( - [env.PROC] + - ['SQLCHECK=SEMANTICS'] + - (['SYS_INCLUDE=(' + ','.join(env.PROC_INCLUDES) + ')'] - if env.PROC_INCLUDES else []) + - ['INCLUDE=(' + ','.join( - [i.bldpath() for i in inc_nodes] - ) + ')'] + - ['userid=' + env.PROC_CONNECTION] + - ['INAME=' + tsk.inputs[0].bldpath()] + - ['ONAME=' + tsk.outputs[0].bldpath()] - ) - exec_env = { - 'ORACLE_HOME': env.PROC_ORACLE, - 'LD_LIBRARY_PATH': env.PROC_ORACLE + path.sep + 'lib', - } - if env.PROC_TNS_ADMIN: - exec_env['TNS_ADMIN'] = env.PROC_TNS_ADMIN - return tsk.exec_command(cmd, env=exec_env) - -TaskGen.declare_chain( - name = 'proc', - rule = proc, - ext_in = '.pc', - ext_out = '.c', -) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/protoc.py b/ldb-2.0.8/third_party/waf/waflib/extras/protoc.py deleted file mode 100644 index 4a519cc..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/protoc.py +++ /dev/null @@ -1,224 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Philipp Bender, 2012 -# Matt Clarkson, 2012 - -import re, os -from waflib.Task import Task -from waflib.TaskGen import extension -from waflib import Errors, Context, Logs - -""" -A simple tool to integrate protocol buffers into your build system. - -Example for C++: - - def configure(conf): - conf.load('compiler_cxx cxx protoc') - - def build(bld): - bld( - features = 'cxx cxxprogram' - source = 'main.cpp file1.proto proto/file2.proto', - includes = '. proto', - target = 'executable') - -Example for Python: - - def configure(conf): - conf.load('python protoc') - - def build(bld): - bld( - features = 'py' - source = 'main.py file1.proto proto/file2.proto', - protoc_includes = 'proto') - -Example for both Python and C++ at same time: - - def configure(conf): - conf.load('cxx python protoc') - - def build(bld): - bld( - features = 'cxx py' - source = 'file1.proto proto/file2.proto', - protoc_includes = 'proto') # or includes - - -Example for Java: - - def options(opt): - opt.load('java') - - def configure(conf): - conf.load('python java protoc') - # Here you have to point to your protobuf-java JAR and have it in classpath - conf.env.CLASSPATH_PROTOBUF = ['protobuf-java-2.5.0.jar'] - - def build(bld): - bld( - features = 'javac protoc', - name = 'pbjava', - srcdir = 'inc/ src', # directories used by javac - source = ['inc/message_inc.proto', 'inc/message.proto'], - # source is used by protoc for .proto files - use = 'PROTOBUF', - protoc_includes = ['inc']) # for protoc to search dependencies - - -Protoc includes passed via protoc_includes are either relative to the taskgen -or to the project and are searched in this order. - -Include directories external to the waf project can also be passed to the -extra by using protoc_extincludes - - protoc_extincludes = ['/usr/include/pblib'] - - -Notes when using this tool: - -- protoc command line parsing is tricky. - - The generated files can be put in subfolders which depend on - the order of the include paths. - - Try to be simple when creating task generators - containing protoc stuff. - -""" - -class protoc(Task): - run_str = '${PROTOC} ${PROTOC_FL:PROTOC_FLAGS} ${PROTOC_ST:INCPATHS} ${PROTOC_ST:PROTOC_INCPATHS} ${PROTOC_ST:PROTOC_EXTINCPATHS} ${SRC[0].bldpath()}' - color = 'BLUE' - ext_out = ['.h', 'pb.cc', '.py', '.java'] - def scan(self): - """ - Scan .proto dependencies - """ - node = self.inputs[0] - - nodes = [] - names = [] - seen = [] - search_nodes = [] - - if not node: - return (nodes, names) - - if 'cxx' in self.generator.features: - search_nodes = self.generator.includes_nodes - - if 'py' in self.generator.features or 'javac' in self.generator.features: - for incpath in getattr(self.generator, 'protoc_includes', []): - incpath_node = self.generator.path.find_node(incpath) - if incpath_node: - search_nodes.append(incpath_node) - else: - # Check if relative to top-level for extra tg dependencies - incpath_node = self.generator.bld.path.find_node(incpath) - if incpath_node: - search_nodes.append(incpath_node) - else: - raise Errors.WafError('protoc: include path %r does not exist' % incpath) - - - def parse_node(node): - if node in seen: - return - seen.append(node) - code = node.read().splitlines() - for line in code: - m = re.search(r'^import\s+"(.*)";.*(//)?.*', line) - if m: - dep = m.groups()[0] - for incnode in search_nodes: - found = incnode.find_resource(dep) - if found: - nodes.append(found) - parse_node(found) - else: - names.append(dep) - - parse_node(node) - # Add also dependencies path to INCPATHS so protoc will find the included file - for deppath in nodes: - self.env.append_unique('INCPATHS', deppath.parent.bldpath()) - return (nodes, names) - -@extension('.proto') -def process_protoc(self, node): - incdirs = [] - out_nodes = [] - protoc_flags = [] - - # ensure PROTOC_FLAGS is a list; a copy is used below anyway - self.env.PROTOC_FLAGS = self.to_list(self.env.PROTOC_FLAGS) - - if 'cxx' in self.features: - cpp_node = node.change_ext('.pb.cc') - hpp_node = node.change_ext('.pb.h') - self.source.append(cpp_node) - out_nodes.append(cpp_node) - out_nodes.append(hpp_node) - protoc_flags.append('--cpp_out=%s' % node.parent.get_bld().bldpath()) - - if 'py' in self.features: - py_node = node.change_ext('_pb2.py') - self.source.append(py_node) - out_nodes.append(py_node) - protoc_flags.append('--python_out=%s' % node.parent.get_bld().bldpath()) - - if 'javac' in self.features: - # Make javac get also pick java code generated in build - if not node.parent.get_bld() in self.javac_task.srcdir: - self.javac_task.srcdir.append(node.parent.get_bld()) - - protoc_flags.append('--java_out=%s' % node.parent.get_bld().bldpath()) - node.parent.get_bld().mkdir() - - tsk = self.create_task('protoc', node, out_nodes) - tsk.env.append_value('PROTOC_FLAGS', protoc_flags) - - if 'javac' in self.features: - self.javac_task.set_run_after(tsk) - - # Instruct protoc where to search for .proto included files. - # For C++ standard include files dirs are used, - # but this doesn't apply to Python for example - for incpath in getattr(self, 'protoc_includes', []): - incpath_node = self.path.find_node(incpath) - if incpath_node: - incdirs.append(incpath_node.bldpath()) - else: - # Check if relative to top-level for extra tg dependencies - incpath_node = self.bld.path.find_node(incpath) - if incpath_node: - incdirs.append(incpath_node.bldpath()) - else: - raise Errors.WafError('protoc: include path %r does not exist' % incpath) - - tsk.env.PROTOC_INCPATHS = incdirs - - # Include paths external to the waf project (ie. shared pb repositories) - tsk.env.PROTOC_EXTINCPATHS = getattr(self, 'protoc_extincludes', []) - - # PR2115: protoc generates output of .proto files in nested - # directories by canonicalizing paths. To avoid this we have to pass - # as first include the full directory file of the .proto file - tsk.env.prepend_value('INCPATHS', node.parent.bldpath()) - - use = getattr(self, 'use', '') - if not 'PROTOBUF' in use: - self.use = self.to_list(use) + ['PROTOBUF'] - -def configure(conf): - conf.check_cfg(package='protobuf', uselib_store='PROTOBUF', args=['--cflags', '--libs']) - conf.find_program('protoc', var='PROTOC') - conf.start_msg('Checking for protoc version') - protocver = conf.cmd_and_log(conf.env.PROTOC + ['--version'], output=Context.BOTH) - protocver = ''.join(protocver).strip()[protocver[0].rfind(' ')+1:] - conf.end_msg(protocver) - conf.env.PROTOC_MAJOR = protocver[:protocver.find('.')] - conf.env.PROTOC_ST = '-I%s' - conf.env.PROTOC_FL = '%s' diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/pyqt5.py b/ldb-2.0.8/third_party/waf/waflib/extras/pyqt5.py deleted file mode 100644 index 9c94176..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/pyqt5.py +++ /dev/null @@ -1,246 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Federico Pellegrin, 2016-2019 (fedepell) adapted for Python - -""" -This tool helps with finding Python Qt5 tools and libraries, -and provides translation from QT5 files to Python code. - -The following snippet illustrates the tool usage:: - - def options(opt): - opt.load('py pyqt5') - - def configure(conf): - conf.load('py pyqt5') - - def build(bld): - bld( - features = 'py pyqt5', - source = 'main.py textures.qrc aboutDialog.ui', - ) - -Here, the UI description and resource files will be processed -to generate code. - -Usage -===== - -Load the "pyqt5" tool. - -Add into the sources list also the qrc resources files or ui5 -definition files and they will be translated into python code -with the system tools (PyQt5, PySide2, PyQt4 are searched in this -order) and then compiled -""" - -try: - from xml.sax import make_parser - from xml.sax.handler import ContentHandler -except ImportError: - has_xml = False - ContentHandler = object -else: - has_xml = True - -import os -from waflib.Tools import python -from waflib import Task, Options -from waflib.TaskGen import feature, extension -from waflib.Configure import conf -from waflib import Logs - -EXT_RCC = ['.qrc'] -""" -File extension for the resource (.qrc) files -""" - -EXT_UI = ['.ui'] -""" -File extension for the user interface (.ui) files -""" - - -class XMLHandler(ContentHandler): - """ - Parses ``.qrc`` files - """ - def __init__(self): - self.buf = [] - self.files = [] - def startElement(self, name, attrs): - if name == 'file': - self.buf = [] - def endElement(self, name): - if name == 'file': - self.files.append(str(''.join(self.buf))) - def characters(self, cars): - self.buf.append(cars) - -@extension(*EXT_RCC) -def create_pyrcc_task(self, node): - "Creates rcc and py task for ``.qrc`` files" - rcnode = node.change_ext('.py') - self.create_task('pyrcc', node, rcnode) - if getattr(self, 'install_from', None): - self.install_from = self.install_from.get_bld() - else: - self.install_from = self.path.get_bld() - self.install_path = getattr(self, 'install_path', '${PYTHONDIR}') - self.process_py(rcnode) - -@extension(*EXT_UI) -def create_pyuic_task(self, node): - "Create uic tasks and py for user interface ``.ui`` definition files" - uinode = node.change_ext('.py') - self.create_task('ui5py', node, uinode) - if getattr(self, 'install_from', None): - self.install_from = self.install_from.get_bld() - else: - self.install_from = self.path.get_bld() - self.install_path = getattr(self, 'install_path', '${PYTHONDIR}') - self.process_py(uinode) - -@extension('.ts') -def add_pylang(self, node): - """Adds all the .ts file into ``self.lang``""" - self.lang = self.to_list(getattr(self, 'lang', [])) + [node] - -@feature('pyqt5') -def apply_pyqt5(self): - """ - The additional parameters are: - - :param lang: list of translation files (\\*.ts) to process - :type lang: list of :py:class:`waflib.Node.Node` or string without the .ts extension - :param langname: if given, transform the \\*.ts files into a .qrc files to include in the binary file - :type langname: :py:class:`waflib.Node.Node` or string without the .qrc extension - """ - if getattr(self, 'lang', None): - qmtasks = [] - for x in self.to_list(self.lang): - if isinstance(x, str): - x = self.path.find_resource(x + '.ts') - qmtasks.append(self.create_task('ts2qm', x, x.change_ext('.qm'))) - - - if getattr(self, 'langname', None): - qmnodes = [k.outputs[0] for k in qmtasks] - rcnode = self.langname - if isinstance(rcnode, str): - rcnode = self.path.find_or_declare(rcnode + '.qrc') - t = self.create_task('qm2rcc', qmnodes, rcnode) - create_pyrcc_task(self, t.outputs[0]) - -class pyrcc(Task.Task): - """ - Processes ``.qrc`` files - """ - color = 'BLUE' - run_str = '${QT_PYRCC} ${SRC} -o ${TGT}' - ext_out = ['.py'] - - def rcname(self): - return os.path.splitext(self.inputs[0].name)[0] - - def scan(self): - """Parse the *.qrc* files""" - if not has_xml: - Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!') - return ([], []) - - parser = make_parser() - curHandler = XMLHandler() - parser.setContentHandler(curHandler) - fi = open(self.inputs[0].abspath(), 'r') - try: - parser.parse(fi) - finally: - fi.close() - - nodes = [] - names = [] - root = self.inputs[0].parent - for x in curHandler.files: - nd = root.find_resource(x) - if nd: - nodes.append(nd) - else: - names.append(x) - return (nodes, names) - - -class ui5py(Task.Task): - """ - Processes ``.ui`` files for python - """ - color = 'BLUE' - run_str = '${QT_PYUIC} ${SRC} -o ${TGT}' - ext_out = ['.py'] - -class ts2qm(Task.Task): - """ - Generates ``.qm`` files from ``.ts`` files - """ - color = 'BLUE' - run_str = '${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}' - -class qm2rcc(Task.Task): - """ - Generates ``.qrc`` files from ``.qm`` files - """ - color = 'BLUE' - after = 'ts2qm' - def run(self): - """Create a qrc file including the inputs""" - txt = '\n'.join(['%s' % k.path_from(self.outputs[0].parent) for k in self.inputs]) - code = '\n\n%s\n\n' % txt - self.outputs[0].write(code) - -def configure(self): - self.find_pyqt5_binaries() - - # warn about this during the configuration too - if not has_xml: - Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!') - -@conf -def find_pyqt5_binaries(self): - """ - Detects PyQt5 or PySide2 programs such as pyuic5/pyside2-uic, pyrcc5/pyside2-rcc - """ - env = self.env - - if getattr(Options.options, 'want_pyqt5', True): - self.find_program(['pyuic5'], var='QT_PYUIC') - self.find_program(['pyrcc5'], var='QT_PYRCC') - self.find_program(['pylupdate5'], var='QT_PYLUPDATE') - elif getattr(Options.options, 'want_pyside2', True): - self.find_program(['pyside2-uic'], var='QT_PYUIC') - self.find_program(['pyside2-rcc'], var='QT_PYRCC') - self.find_program(['pyside2-lupdate'], var='QT_PYLUPDATE') - elif getattr(Options.options, 'want_pyqt4', True): - self.find_program(['pyuic4'], var='QT_PYUIC') - self.find_program(['pyrcc4'], var='QT_PYRCC') - self.find_program(['pylupdate4'], var='QT_PYLUPDATE') - else: - self.find_program(['pyuic5','pyside2-uic','pyuic4'], var='QT_PYUIC') - self.find_program(['pyrcc5','pyside2-rcc','pyrcc4'], var='QT_PYRCC') - self.find_program(['pylupdate5', 'pyside2-lupdate','pylupdate4'], var='QT_PYLUPDATE') - - if not env.QT_PYUIC: - self.fatal('cannot find the uic compiler for python for qt5') - - if not env.QT_PYRCC: - self.fatal('cannot find the rcc compiler for python for qt5') - - self.find_program(['lrelease-qt5', 'lrelease'], var='QT_LRELEASE') - -def options(opt): - """ - Command-line options - """ - pyqt5opt=opt.add_option_group("Python QT5 Options") - pyqt5opt.add_option('--pyqt5-pyqt5', action='store_true', default=False, dest='want_pyqt5', help='use PyQt5 bindings as python QT5 bindings (default PyQt5 is searched first, PySide2 after, PyQt4 last)') - pyqt5opt.add_option('--pyqt5-pyside2', action='store_true', default=False, dest='want_pyside2', help='use PySide2 bindings as python QT5 bindings (default PyQt5 is searched first, PySide2 after, PyQt4 last)') - pyqt5opt.add_option('--pyqt5-pyqt4', action='store_true', default=False, dest='want_pyqt4', help='use PyQt4 bindings as python QT5 bindings (default PyQt5 is searched first, PySide2 after, PyQt4 last)') diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/pytest.py b/ldb-2.0.8/third_party/waf/waflib/extras/pytest.py deleted file mode 100644 index 7dd5a1a..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/pytest.py +++ /dev/null @@ -1,225 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Calle Rosenquist, 2016-2018 (xbreak) - -""" -Provides Python unit test support using :py:class:`waflib.Tools.waf_unit_test.utest` -task via the **pytest** feature. - -To use pytest the following is needed: - -1. Load `pytest` and the dependency `waf_unit_test` tools. -2. Create a task generator with feature `pytest` (not `test`) and customize behaviour with - the following attributes: - - - `pytest_source`: Test input files. - - `ut_str`: Test runner command, e.g. ``${PYTHON} -B -m unittest discover`` or - if nose is used: ``${NOSETESTS} --no-byte-compile ${SRC}``. - - `ut_shell`: Determines if ``ut_str`` is executed in a shell. Default: False. - - `ut_cwd`: Working directory for test runner. Defaults to directory of - first ``pytest_source`` file. - - Additionally the following `pytest` specific attributes are used in dependent taskgens: - - - `pytest_path`: Node or string list of additional Python paths. - - `pytest_libpath`: Node or string list of additional library paths. - -The `use` dependencies are used for both update calculation and to populate -the following environment variables for the `pytest` test runner: - -1. `PYTHONPATH` (`sys.path`) of any dependent taskgen that has the feature `py`: - - - `install_from` attribute is used to determine where the root of the Python sources - are located. If `install_from` is not specified the default is to use the taskgen path - as the root. - - - `pytest_path` attribute is used to manually specify additional Python paths. - -2. Dynamic linker search path variable (e.g. `LD_LIBRARY_PATH`) of any dependent taskgen with - non-static link_task. - - - `pytest_libpath` attribute is used to manually specify additional linker paths. - -Note: `pytest` cannot automatically determine the correct `PYTHONPATH` for `pyext` taskgens - because the extension might be part of a Python package or used standalone: - - - When used as part of another `py` package, the `PYTHONPATH` is provided by - that taskgen so no additional action is required. - - - When used as a standalone module, the user needs to specify the `PYTHONPATH` explicitly - via the `pytest_path` attribute on the `pyext` taskgen. - - For details c.f. the pytest playground examples. - - -For example:: - - # A standalone Python C extension that demonstrates unit test environment population - # of PYTHONPATH and LD_LIBRARY_PATH/PATH/DYLD_LIBRARY_PATH. - # - # Note: `pytest_path` is provided here because pytest cannot automatically determine - # if the extension is part of another Python package or is used standalone. - bld(name = 'foo_ext', - features = 'c cshlib pyext', - source = 'src/foo_ext.c', - target = 'foo_ext', - pytest_path = [ bld.path.get_bld() ]) - - # Python package under test that also depend on the Python module `foo_ext` - # - # Note: `install_from` is added automatically to `PYTHONPATH`. - bld(name = 'foo', - features = 'py', - use = 'foo_ext', - source = bld.path.ant_glob('src/foo/*.py'), - install_from = 'src') - - # Unit test example using the built in module unittest and let that discover - # any test cases. - bld(name = 'foo_test', - features = 'pytest', - use = 'foo', - pytest_source = bld.path.ant_glob('test/*.py'), - ut_str = '${PYTHON} -B -m unittest discover') - -""" - -import os -from waflib import Task, TaskGen, Errors, Utils, Logs -from waflib.Tools import ccroot - -def _process_use_rec(self, name): - """ - Recursively process ``use`` for task generator with name ``name``.. - Used by pytest_process_use. - """ - if name in self.pytest_use_not or name in self.pytest_use_seen: - return - try: - tg = self.bld.get_tgen_by_name(name) - except Errors.WafError: - self.pytest_use_not.add(name) - return - - self.pytest_use_seen.append(name) - tg.post() - - for n in self.to_list(getattr(tg, 'use', [])): - _process_use_rec(self, n) - - -@TaskGen.feature('pytest') -@TaskGen.after_method('process_source', 'apply_link') -def pytest_process_use(self): - """ - Process the ``use`` attribute which contains a list of task generator names and store - paths that later is used to populate the unit test runtime environment. - """ - self.pytest_use_not = set() - self.pytest_use_seen = [] - self.pytest_paths = [] # strings or Nodes - self.pytest_libpaths = [] # strings or Nodes - self.pytest_dep_nodes = [] - - names = self.to_list(getattr(self, 'use', [])) - for name in names: - _process_use_rec(self, name) - - def extend_unique(lst, varlst): - ext = [] - for x in varlst: - if x not in lst: - ext.append(x) - lst.extend(ext) - - # Collect type specific info needed to construct a valid runtime environment - # for the test. - for name in self.pytest_use_seen: - tg = self.bld.get_tgen_by_name(name) - - extend_unique(self.pytest_paths, Utils.to_list(getattr(tg, 'pytest_path', []))) - extend_unique(self.pytest_libpaths, Utils.to_list(getattr(tg, 'pytest_libpath', []))) - - if 'py' in tg.features: - # Python dependencies are added to PYTHONPATH - pypath = getattr(tg, 'install_from', tg.path) - - if 'buildcopy' in tg.features: - # Since buildcopy is used we assume that PYTHONPATH in build should be used, - # not source - extend_unique(self.pytest_paths, [pypath.get_bld().abspath()]) - - # Add buildcopy output nodes to dependencies - extend_unique(self.pytest_dep_nodes, [o for task in getattr(tg, 'tasks', []) \ - for o in getattr(task, 'outputs', [])]) - else: - # If buildcopy is not used, depend on sources instead - extend_unique(self.pytest_dep_nodes, tg.source) - extend_unique(self.pytest_paths, [pypath.abspath()]) - - if getattr(tg, 'link_task', None): - # For tasks with a link_task (C, C++, D et.c.) include their library paths: - if not isinstance(tg.link_task, ccroot.stlink_task): - extend_unique(self.pytest_dep_nodes, tg.link_task.outputs) - extend_unique(self.pytest_libpaths, tg.link_task.env.LIBPATH) - - if 'pyext' in tg.features: - # If the taskgen is extending Python we also want to add the interpreter libpath. - extend_unique(self.pytest_libpaths, tg.link_task.env.LIBPATH_PYEXT) - else: - # Only add to libpath if the link task is not a Python extension - extend_unique(self.pytest_libpaths, [tg.link_task.outputs[0].parent.abspath()]) - - -@TaskGen.feature('pytest') -@TaskGen.after_method('pytest_process_use') -def make_pytest(self): - """ - Creates a ``utest`` task with a populated environment for Python if not specified in ``ut_env``: - - - Paths in `pytest_paths` attribute are used to populate PYTHONPATH - - Paths in `pytest_libpaths` attribute are used to populate the system library path (e.g. LD_LIBRARY_PATH) - """ - nodes = self.to_nodes(self.pytest_source) - tsk = self.create_task('utest', nodes) - - tsk.dep_nodes.extend(self.pytest_dep_nodes) - if getattr(self, 'ut_str', None): - self.ut_run, lst = Task.compile_fun(self.ut_str, shell=getattr(self, 'ut_shell', False)) - tsk.vars = lst + tsk.vars - - if getattr(self, 'ut_cwd', None): - if isinstance(self.ut_cwd, str): - # we want a Node instance - if os.path.isabs(self.ut_cwd): - self.ut_cwd = self.bld.root.make_node(self.ut_cwd) - else: - self.ut_cwd = self.path.make_node(self.ut_cwd) - else: - if tsk.inputs: - self.ut_cwd = tsk.inputs[0].parent - else: - raise Errors.WafError("no valid input files for pytest task, check pytest_source value") - - if not self.ut_cwd.exists(): - self.ut_cwd.mkdir() - - if not hasattr(self, 'ut_env'): - self.ut_env = dict(os.environ) - def add_paths(var, lst): - # Add list of paths to a variable, lst can contain strings or nodes - lst = [ str(n) for n in lst ] - Logs.debug("ut: %s: Adding paths %s=%s", self, var, lst) - self.ut_env[var] = os.pathsep.join(lst) + os.pathsep + self.ut_env.get(var, '') - - # Prepend dependency paths to PYTHONPATH and LD_LIBRARY_PATH - add_paths('PYTHONPATH', self.pytest_paths) - - if Utils.is_win32: - add_paths('PATH', self.pytest_libpaths) - elif Utils.unversioned_sys_platform() == 'darwin': - add_paths('DYLD_LIBRARY_PATH', self.pytest_libpaths) - add_paths('LD_LIBRARY_PATH', self.pytest_libpaths) - else: - add_paths('LD_LIBRARY_PATH', self.pytest_libpaths) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/qnxnto.py b/ldb-2.0.8/third_party/waf/waflib/extras/qnxnto.py deleted file mode 100644 index 1158124..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/qnxnto.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Jérôme Carretero 2011 (zougloub) -# QNX neutrino compatibility functions - -import sys, os -from waflib import Utils - -class Popen(object): - """ - Popen cannot work on QNX from a threaded program: - Forking in threads is not implemented in neutrino. - - Python's os.popen / spawn / fork won't work when running in threads (they will if in the main program thread) - - In waf, this happens mostly in build. - And the use cases can be replaced by os.system() calls. - """ - __slots__ = ["prog", "kw", "popen", "verbose"] - verbose = 0 - def __init__(self, prog, **kw): - try: - self.prog = prog - self.kw = kw - self.popen = None - if Popen.verbose: - sys.stdout.write("Popen created: %r, kw=%r..." % (prog, kw)) - - do_delegate = kw.get('stdout') == -1 and kw.get('stderr') == -1 - if do_delegate: - if Popen.verbose: - print("Delegating to real Popen") - self.popen = self.real_Popen(prog, **kw) - else: - if Popen.verbose: - print("Emulating") - except Exception as e: - if Popen.verbose: - print("Exception: %s" % e) - raise - - def __getattr__(self, name): - if Popen.verbose: - sys.stdout.write("Getattr: %s..." % name) - if name in Popen.__slots__: - return object.__getattribute__(self, name) - else: - if self.popen is not None: - if Popen.verbose: - print("from Popen") - return getattr(self.popen, name) - else: - if name == "wait": - return self.emu_wait - else: - raise Exception("subprocess emulation: not implemented: %s" % name) - - def emu_wait(self): - if Popen.verbose: - print("emulated wait (%r kw=%r)" % (self.prog, self.kw)) - if isinstance(self.prog, str): - cmd = self.prog - else: - cmd = " ".join(self.prog) - if 'cwd' in self.kw: - cmd = 'cd "%s" && %s' % (self.kw['cwd'], cmd) - return os.system(cmd) - -if sys.platform == "qnx6": - Popen.real_Popen = Utils.subprocess.Popen - Utils.subprocess.Popen = Popen - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/qt4.py b/ldb-2.0.8/third_party/waf/waflib/extras/qt4.py deleted file mode 100644 index d19a4dd..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/qt4.py +++ /dev/null @@ -1,695 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2006-2010 (ita) - -""" - -Tool Description -================ - -This tool helps with finding Qt4 tools and libraries, -and also provides syntactic sugar for using Qt4 tools. - -The following snippet illustrates the tool usage:: - - def options(opt): - opt.load('compiler_cxx qt4') - - def configure(conf): - conf.load('compiler_cxx qt4') - - def build(bld): - bld( - features = 'qt4 cxx cxxprogram', - uselib = 'QTCORE QTGUI QTOPENGL QTSVG', - source = 'main.cpp textures.qrc aboutDialog.ui', - target = 'window', - ) - -Here, the UI description and resource files will be processed -to generate code. - -Usage -===== - -Load the "qt4" tool. - -You also need to edit your sources accordingly: - -- the normal way of doing things is to have your C++ files - include the .moc file. - This is regarded as the best practice (and provides much faster - compilations). - It also implies that the include paths have beenset properly. - -- to have the include paths added automatically, use the following:: - - from waflib.TaskGen import feature, before_method, after_method - @feature('cxx') - @after_method('process_source') - @before_method('apply_incpaths') - def add_includes_paths(self): - incs = set(self.to_list(getattr(self, 'includes', ''))) - for x in self.compiled_tasks: - incs.add(x.inputs[0].parent.path_from(self.path)) - self.includes = sorted(incs) - -Note: another tool provides Qt processing that does not require -.moc includes, see 'playground/slow_qt/'. - -A few options (--qt{dir,bin,...}) and environment variables -(QT4_{ROOT,DIR,MOC,UIC,XCOMPILE}) allow finer tuning of the tool, -tool path selection, etc; please read the source for more info. - -""" - -try: - from xml.sax import make_parser - from xml.sax.handler import ContentHandler -except ImportError: - has_xml = False - ContentHandler = object -else: - has_xml = True - -import os, sys -from waflib.Tools import cxx -from waflib import Task, Utils, Options, Errors, Context -from waflib.TaskGen import feature, after_method, extension -from waflib.Configure import conf -from waflib import Logs - -MOC_H = ['.h', '.hpp', '.hxx', '.hh'] -""" -File extensions associated to the .moc files -""" - -EXT_RCC = ['.qrc'] -""" -File extension for the resource (.qrc) files -""" - -EXT_UI = ['.ui'] -""" -File extension for the user interface (.ui) files -""" - -EXT_QT4 = ['.cpp', '.cc', '.cxx', '.C'] -""" -File extensions of C++ files that may require a .moc processing -""" - -QT4_LIBS = "QtCore QtGui QtUiTools QtNetwork QtOpenGL QtSql QtSvg QtTest QtXml QtXmlPatterns QtWebKit Qt3Support QtHelp QtScript QtDeclarative QtDesigner" - -class qxx(Task.classes['cxx']): - """ - Each C++ file can have zero or several .moc files to create. - They are known only when the files are scanned (preprocessor) - To avoid scanning the c++ files each time (parsing C/C++), the results - are retrieved from the task cache (bld.node_deps/bld.raw_deps). - The moc tasks are also created *dynamically* during the build. - """ - - def __init__(self, *k, **kw): - Task.Task.__init__(self, *k, **kw) - self.moc_done = 0 - - def runnable_status(self): - """ - Compute the task signature to make sure the scanner was executed. Create the - moc tasks by using :py:meth:`waflib.Tools.qt4.qxx.add_moc_tasks` (if necessary), - then postpone the task execution (there is no need to recompute the task signature). - """ - if self.moc_done: - return Task.Task.runnable_status(self) - else: - for t in self.run_after: - if not t.hasrun: - return Task.ASK_LATER - self.add_moc_tasks() - return Task.Task.runnable_status(self) - - def create_moc_task(self, h_node, m_node): - """ - If several libraries use the same classes, it is possible that moc will run several times (Issue 1318) - It is not possible to change the file names, but we can assume that the moc transformation will be identical, - and the moc tasks can be shared in a global cache. - - The defines passed to moc will then depend on task generator order. If this is not acceptable, then - use the tool slow_qt4 instead (and enjoy the slow builds... :-( ) - """ - try: - moc_cache = self.generator.bld.moc_cache - except AttributeError: - moc_cache = self.generator.bld.moc_cache = {} - - try: - return moc_cache[h_node] - except KeyError: - tsk = moc_cache[h_node] = Task.classes['moc'](env=self.env, generator=self.generator) - tsk.set_inputs(h_node) - tsk.set_outputs(m_node) - - if self.generator: - self.generator.tasks.append(tsk) - - # direct injection in the build phase (safe because called from the main thread) - gen = self.generator.bld.producer - gen.outstanding.append(tsk) - gen.total += 1 - - return tsk - - def moc_h_ext(self): - ext = [] - try: - ext = Options.options.qt_header_ext.split() - except AttributeError: - pass - if not ext: - ext = MOC_H - return ext - - def add_moc_tasks(self): - """ - Create the moc tasks by looking in ``bld.raw_deps[self.uid()]`` - """ - node = self.inputs[0] - bld = self.generator.bld - - try: - # compute the signature once to know if there is a moc file to create - self.signature() - except KeyError: - # the moc file may be referenced somewhere else - pass - else: - # remove the signature, it must be recomputed with the moc task - delattr(self, 'cache_sig') - - include_nodes = [node.parent] + self.generator.includes_nodes - - moctasks = [] - mocfiles = set() - for d in bld.raw_deps.get(self.uid(), []): - if not d.endswith('.moc'): - continue - - # process that base.moc only once - if d in mocfiles: - continue - mocfiles.add(d) - - # find the source associated with the moc file - h_node = None - - base2 = d[:-4] - for x in include_nodes: - for e in self.moc_h_ext(): - h_node = x.find_node(base2 + e) - if h_node: - break - if h_node: - m_node = h_node.change_ext('.moc') - break - else: - # foo.cpp -> foo.cpp.moc - for k in EXT_QT4: - if base2.endswith(k): - for x in include_nodes: - h_node = x.find_node(base2) - if h_node: - break - if h_node: - m_node = h_node.change_ext(k + '.moc') - break - - if not h_node: - raise Errors.WafError('No source found for %r which is a moc file' % d) - - # create the moc task - task = self.create_moc_task(h_node, m_node) - moctasks.append(task) - - # simple scheduler dependency: run the moc task before others - self.run_after.update(set(moctasks)) - self.moc_done = 1 - -class trans_update(Task.Task): - """Update a .ts files from a list of C++ files""" - run_str = '${QT_LUPDATE} ${SRC} -ts ${TGT}' - color = 'BLUE' - -class XMLHandler(ContentHandler): - """ - Parser for *.qrc* files - """ - def __init__(self): - self.buf = [] - self.files = [] - def startElement(self, name, attrs): - if name == 'file': - self.buf = [] - def endElement(self, name): - if name == 'file': - self.files.append(str(''.join(self.buf))) - def characters(self, cars): - self.buf.append(cars) - -@extension(*EXT_RCC) -def create_rcc_task(self, node): - "Create rcc and cxx tasks for *.qrc* files" - rcnode = node.change_ext('_rc.cpp') - self.create_task('rcc', node, rcnode) - cpptask = self.create_task('cxx', rcnode, rcnode.change_ext('.o')) - try: - self.compiled_tasks.append(cpptask) - except AttributeError: - self.compiled_tasks = [cpptask] - return cpptask - -@extension(*EXT_UI) -def create_uic_task(self, node): - "hook for uic tasks" - uictask = self.create_task('ui4', node) - uictask.outputs = [self.path.find_or_declare(self.env['ui_PATTERN'] % node.name[:-3])] - -@extension('.ts') -def add_lang(self, node): - """add all the .ts file into self.lang""" - self.lang = self.to_list(getattr(self, 'lang', [])) + [node] - -@feature('qt4') -@after_method('apply_link') -def apply_qt4(self): - """ - Add MOC_FLAGS which may be necessary for moc:: - - def build(bld): - bld.program(features='qt4', source='main.cpp', target='app', use='QTCORE') - - The additional parameters are: - - :param lang: list of translation files (\\*.ts) to process - :type lang: list of :py:class:`waflib.Node.Node` or string without the .ts extension - :param update: whether to process the C++ files to update the \\*.ts files (use **waf --translate**) - :type update: bool - :param langname: if given, transform the \\*.ts files into a .qrc files to include in the binary file - :type langname: :py:class:`waflib.Node.Node` or string without the .qrc extension - """ - if getattr(self, 'lang', None): - qmtasks = [] - for x in self.to_list(self.lang): - if isinstance(x, str): - x = self.path.find_resource(x + '.ts') - qmtasks.append(self.create_task('ts2qm', x, x.change_ext('.qm'))) - - if getattr(self, 'update', None) and Options.options.trans_qt4: - cxxnodes = [a.inputs[0] for a in self.compiled_tasks] + [ - a.inputs[0] for a in self.tasks if getattr(a, 'inputs', None) and a.inputs[0].name.endswith('.ui')] - for x in qmtasks: - self.create_task('trans_update', cxxnodes, x.inputs) - - if getattr(self, 'langname', None): - qmnodes = [x.outputs[0] for x in qmtasks] - rcnode = self.langname - if isinstance(rcnode, str): - rcnode = self.path.find_or_declare(rcnode + '.qrc') - t = self.create_task('qm2rcc', qmnodes, rcnode) - k = create_rcc_task(self, t.outputs[0]) - self.link_task.inputs.append(k.outputs[0]) - - lst = [] - for flag in self.to_list(self.env['CXXFLAGS']): - if len(flag) < 2: - continue - f = flag[0:2] - if f in ('-D', '-I', '/D', '/I'): - if (f[0] == '/'): - lst.append('-' + flag[1:]) - else: - lst.append(flag) - self.env.append_value('MOC_FLAGS', lst) - -@extension(*EXT_QT4) -def cxx_hook(self, node): - """ - Re-map C++ file extensions to the :py:class:`waflib.Tools.qt4.qxx` task. - """ - return self.create_compiled_task('qxx', node) - -class rcc(Task.Task): - """ - Process *.qrc* files - """ - color = 'BLUE' - run_str = '${QT_RCC} -name ${tsk.rcname()} ${SRC[0].abspath()} ${RCC_ST} -o ${TGT}' - ext_out = ['.h'] - - def rcname(self): - return os.path.splitext(self.inputs[0].name)[0] - - def scan(self): - """Parse the *.qrc* files""" - if not has_xml: - Logs.error('no xml support was found, the rcc dependencies will be incomplete!') - return ([], []) - - parser = make_parser() - curHandler = XMLHandler() - parser.setContentHandler(curHandler) - fi = open(self.inputs[0].abspath(), 'r') - try: - parser.parse(fi) - finally: - fi.close() - - nodes = [] - names = [] - root = self.inputs[0].parent - for x in curHandler.files: - nd = root.find_resource(x) - if nd: - nodes.append(nd) - else: - names.append(x) - return (nodes, names) - -class moc(Task.Task): - """ - Create *.moc* files - """ - color = 'BLUE' - run_str = '${QT_MOC} ${MOC_FLAGS} ${MOCCPPPATH_ST:INCPATHS} ${MOCDEFINES_ST:DEFINES} ${SRC} ${MOC_ST} ${TGT}' - def keyword(self): - return "Creating" - def __str__(self): - return self.outputs[0].path_from(self.generator.bld.launch_node()) - -class ui4(Task.Task): - """ - Process *.ui* files - """ - color = 'BLUE' - run_str = '${QT_UIC} ${SRC} -o ${TGT}' - ext_out = ['.h'] - -class ts2qm(Task.Task): - """ - Create *.qm* files from *.ts* files - """ - color = 'BLUE' - run_str = '${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}' - -class qm2rcc(Task.Task): - """ - Transform *.qm* files into *.rc* files - """ - color = 'BLUE' - after = 'ts2qm' - - def run(self): - """Create a qrc file including the inputs""" - txt = '\n'.join(['%s' % k.path_from(self.outputs[0].parent) for k in self.inputs]) - code = '\n\n%s\n\n' % txt - self.outputs[0].write(code) - -def configure(self): - """ - Besides the configuration options, the environment variable QT4_ROOT may be used - to give the location of the qt4 libraries (absolute path). - - The detection will use the program *pkg-config* through :py:func:`waflib.Tools.config_c.check_cfg` - """ - self.find_qt4_binaries() - self.set_qt4_libs_to_check() - self.set_qt4_defines() - self.find_qt4_libraries() - self.add_qt4_rpath() - self.simplify_qt4_libs() - -@conf -def find_qt4_binaries(self): - env = self.env - opt = Options.options - - qtdir = getattr(opt, 'qtdir', '') - qtbin = getattr(opt, 'qtbin', '') - - paths = [] - - if qtdir: - qtbin = os.path.join(qtdir, 'bin') - - # the qt directory has been given from QT4_ROOT - deduce the qt binary path - if not qtdir: - qtdir = os.environ.get('QT4_ROOT', '') - qtbin = os.environ.get('QT4_BIN') or os.path.join(qtdir, 'bin') - - if qtbin: - paths = [qtbin] - - # no qtdir, look in the path and in /usr/local/Trolltech - if not qtdir: - paths = os.environ.get('PATH', '').split(os.pathsep) - paths.append('/usr/share/qt4/bin/') - try: - lst = Utils.listdir('/usr/local/Trolltech/') - except OSError: - pass - else: - if lst: - lst.sort() - lst.reverse() - - # keep the highest version - qtdir = '/usr/local/Trolltech/%s/' % lst[0] - qtbin = os.path.join(qtdir, 'bin') - paths.append(qtbin) - - # at the end, try to find qmake in the paths given - # keep the one with the highest version - cand = None - prev_ver = ['4', '0', '0'] - for qmk in ('qmake-qt4', 'qmake4', 'qmake'): - try: - qmake = self.find_program(qmk, path_list=paths) - except self.errors.ConfigurationError: - pass - else: - try: - version = self.cmd_and_log(qmake + ['-query', 'QT_VERSION']).strip() - except self.errors.WafError: - pass - else: - if version: - new_ver = version.split('.') - if new_ver > prev_ver: - cand = qmake - prev_ver = new_ver - if cand: - self.env.QMAKE = cand - else: - self.fatal('Could not find qmake for qt4') - - qtbin = self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_INSTALL_BINS']).strip() + os.sep - - def find_bin(lst, var): - if var in env: - return - for f in lst: - try: - ret = self.find_program(f, path_list=paths) - except self.errors.ConfigurationError: - pass - else: - env[var]=ret - break - - find_bin(['uic-qt3', 'uic3'], 'QT_UIC3') - find_bin(['uic-qt4', 'uic'], 'QT_UIC') - if not env.QT_UIC: - self.fatal('cannot find the uic compiler for qt4') - - self.start_msg('Checking for uic version') - uicver = self.cmd_and_log(env.QT_UIC + ["-version"], output=Context.BOTH) - uicver = ''.join(uicver).strip() - uicver = uicver.replace('Qt User Interface Compiler ','').replace('User Interface Compiler for Qt', '') - self.end_msg(uicver) - if uicver.find(' 3.') != -1: - self.fatal('this uic compiler is for qt3, add uic for qt4 to your path') - - find_bin(['moc-qt4', 'moc'], 'QT_MOC') - find_bin(['rcc-qt4', 'rcc'], 'QT_RCC') - find_bin(['lrelease-qt4', 'lrelease'], 'QT_LRELEASE') - find_bin(['lupdate-qt4', 'lupdate'], 'QT_LUPDATE') - - env['UIC3_ST']= '%s -o %s' - env['UIC_ST'] = '%s -o %s' - env['MOC_ST'] = '-o' - env['ui_PATTERN'] = 'ui_%s.h' - env['QT_LRELEASE_FLAGS'] = ['-silent'] - env.MOCCPPPATH_ST = '-I%s' - env.MOCDEFINES_ST = '-D%s' - -@conf -def find_qt4_libraries(self): - qtlibs = getattr(Options.options, 'qtlibs', None) or os.environ.get("QT4_LIBDIR") - if not qtlibs: - try: - qtlibs = self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_INSTALL_LIBS']).strip() - except Errors.WafError: - qtdir = self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_INSTALL_PREFIX']).strip() + os.sep - qtlibs = os.path.join(qtdir, 'lib') - self.msg('Found the Qt4 libraries in', qtlibs) - - qtincludes = os.environ.get("QT4_INCLUDES") or self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_INSTALL_HEADERS']).strip() - env = self.env - if not 'PKG_CONFIG_PATH' in os.environ: - os.environ['PKG_CONFIG_PATH'] = '%s:%s/pkgconfig:/usr/lib/qt4/lib/pkgconfig:/opt/qt4/lib/pkgconfig:/usr/lib/qt4/lib:/opt/qt4/lib' % (qtlibs, qtlibs) - - try: - if os.environ.get("QT4_XCOMPILE"): - raise self.errors.ConfigurationError() - self.check_cfg(atleast_pkgconfig_version='0.1') - except self.errors.ConfigurationError: - for i in self.qt4_vars: - uselib = i.upper() - if Utils.unversioned_sys_platform() == "darwin": - # Since at least qt 4.7.3 each library locates in separate directory - frameworkName = i + ".framework" - qtDynamicLib = os.path.join(qtlibs, frameworkName, i) - if os.path.exists(qtDynamicLib): - env.append_unique('FRAMEWORK_' + uselib, i) - self.msg('Checking for %s' % i, qtDynamicLib, 'GREEN') - else: - self.msg('Checking for %s' % i, False, 'YELLOW') - env.append_unique('INCLUDES_' + uselib, os.path.join(qtlibs, frameworkName, 'Headers')) - elif env.DEST_OS != "win32": - qtDynamicLib = os.path.join(qtlibs, "lib" + i + ".so") - qtStaticLib = os.path.join(qtlibs, "lib" + i + ".a") - if os.path.exists(qtDynamicLib): - env.append_unique('LIB_' + uselib, i) - self.msg('Checking for %s' % i, qtDynamicLib, 'GREEN') - elif os.path.exists(qtStaticLib): - env.append_unique('LIB_' + uselib, i) - self.msg('Checking for %s' % i, qtStaticLib, 'GREEN') - else: - self.msg('Checking for %s' % i, False, 'YELLOW') - - env.append_unique('LIBPATH_' + uselib, qtlibs) - env.append_unique('INCLUDES_' + uselib, qtincludes) - env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i)) - else: - # Release library names are like QtCore4 - for k in ("lib%s.a", "lib%s4.a", "%s.lib", "%s4.lib"): - lib = os.path.join(qtlibs, k % i) - if os.path.exists(lib): - env.append_unique('LIB_' + uselib, i + k[k.find("%s") + 2 : k.find('.')]) - self.msg('Checking for %s' % i, lib, 'GREEN') - break - else: - self.msg('Checking for %s' % i, False, 'YELLOW') - - env.append_unique('LIBPATH_' + uselib, qtlibs) - env.append_unique('INCLUDES_' + uselib, qtincludes) - env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i)) - - # Debug library names are like QtCore4d - uselib = i.upper() + "_debug" - for k in ("lib%sd.a", "lib%sd4.a", "%sd.lib", "%sd4.lib"): - lib = os.path.join(qtlibs, k % i) - if os.path.exists(lib): - env.append_unique('LIB_' + uselib, i + k[k.find("%s") + 2 : k.find('.')]) - self.msg('Checking for %s' % i, lib, 'GREEN') - break - else: - self.msg('Checking for %s' % i, False, 'YELLOW') - - env.append_unique('LIBPATH_' + uselib, qtlibs) - env.append_unique('INCLUDES_' + uselib, qtincludes) - env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, i)) - else: - for i in self.qt4_vars_debug + self.qt4_vars: - self.check_cfg(package=i, args='--cflags --libs', mandatory=False) - -@conf -def simplify_qt4_libs(self): - # the libpaths make really long command-lines - # remove the qtcore ones from qtgui, etc - env = self.env - def process_lib(vars_, coreval): - for d in vars_: - var = d.upper() - if var == 'QTCORE': - continue - - value = env['LIBPATH_'+var] - if value: - core = env[coreval] - accu = [] - for lib in value: - if lib in core: - continue - accu.append(lib) - env['LIBPATH_'+var] = accu - - process_lib(self.qt4_vars, 'LIBPATH_QTCORE') - process_lib(self.qt4_vars_debug, 'LIBPATH_QTCORE_DEBUG') - -@conf -def add_qt4_rpath(self): - # rpath if wanted - env = self.env - if getattr(Options.options, 'want_rpath', False): - def process_rpath(vars_, coreval): - for d in vars_: - var = d.upper() - value = env['LIBPATH_'+var] - if value: - core = env[coreval] - accu = [] - for lib in value: - if var != 'QTCORE': - if lib in core: - continue - accu.append('-Wl,--rpath='+lib) - env['RPATH_'+var] = accu - process_rpath(self.qt4_vars, 'LIBPATH_QTCORE') - process_rpath(self.qt4_vars_debug, 'LIBPATH_QTCORE_DEBUG') - -@conf -def set_qt4_libs_to_check(self): - if not hasattr(self, 'qt4_vars'): - self.qt4_vars = QT4_LIBS - self.qt4_vars = Utils.to_list(self.qt4_vars) - if not hasattr(self, 'qt4_vars_debug'): - self.qt4_vars_debug = [a + '_debug' for a in self.qt4_vars] - self.qt4_vars_debug = Utils.to_list(self.qt4_vars_debug) - -@conf -def set_qt4_defines(self): - if sys.platform != 'win32': - return - for x in self.qt4_vars: - y = x[2:].upper() - self.env.append_unique('DEFINES_%s' % x.upper(), 'QT_%s_LIB' % y) - self.env.append_unique('DEFINES_%s_DEBUG' % x.upper(), 'QT_%s_LIB' % y) - -def options(opt): - """ - Command-line options - """ - opt.add_option('--want-rpath', action='store_true', default=False, dest='want_rpath', help='enable the rpath for qt libraries') - - opt.add_option('--header-ext', - type='string', - default='', - help='header extension for moc files', - dest='qt_header_ext') - - for i in 'qtdir qtbin qtlibs'.split(): - opt.add_option('--'+i, type='string', default='', dest=i) - - opt.add_option('--translate', action="store_true", help="collect translation strings", dest="trans_qt4", default=False) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/relocation.py b/ldb-2.0.8/third_party/waf/waflib/extras/relocation.py deleted file mode 100644 index 7e821f4..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/relocation.py +++ /dev/null @@ -1,85 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 - -""" -Waf 1.6 - -Try to detect if the project directory was relocated, and if it was, -change the node representing the project directory. Just call: - - waf configure build - -Note that if the project directory name changes, the signatures for the tasks using -files in that directory will change, causing a partial build. -""" - -import os -from waflib import Build, ConfigSet, Task, Utils, Errors -from waflib.TaskGen import feature, after_method - -EXTRA_LOCK = '.old_srcdir' - -old1 = Build.BuildContext.store -def store(self): - old1(self) - db = os.path.join(self.variant_dir, EXTRA_LOCK) - env = ConfigSet.ConfigSet() - env.SRCDIR = self.srcnode.abspath() - env.store(db) -Build.BuildContext.store = store - -old2 = Build.BuildContext.init_dirs -def init_dirs(self): - - if not (os.path.isabs(self.top_dir) and os.path.isabs(self.out_dir)): - raise Errors.WafError('The project was not configured: run "waf configure" first!') - - srcdir = None - db = os.path.join(self.variant_dir, EXTRA_LOCK) - env = ConfigSet.ConfigSet() - try: - env.load(db) - srcdir = env.SRCDIR - except: - pass - - if srcdir: - d = self.root.find_node(srcdir) - if d and srcdir != self.top_dir and getattr(d, 'children', ''): - srcnode = self.root.make_node(self.top_dir) - print("relocating the source directory %r -> %r" % (srcdir, self.top_dir)) - srcnode.children = {} - - for (k, v) in d.children.items(): - srcnode.children[k] = v - v.parent = srcnode - d.children = {} - - old2(self) - -Build.BuildContext.init_dirs = init_dirs - - -def uid(self): - try: - return self.uid_ - except AttributeError: - # this is not a real hot zone, but we want to avoid surprises here - m = Utils.md5() - up = m.update - up(self.__class__.__name__.encode()) - for x in self.inputs + self.outputs: - up(x.path_from(x.ctx.srcnode).encode()) - self.uid_ = m.digest() - return self.uid_ -Task.Task.uid = uid - -@feature('c', 'cxx', 'd', 'go', 'asm', 'fc', 'includes') -@after_method('propagate_uselib_vars', 'process_source') -def apply_incpaths(self): - lst = self.to_incnodes(self.to_list(getattr(self, 'includes', [])) + self.env['INCLUDES']) - self.includes_nodes = lst - bld = self.bld - self.env['INCPATHS'] = [x.is_child_of(bld.srcnode) and x.path_from(bld.bldnode) or x.abspath() for x in lst] - - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/remote.py b/ldb-2.0.8/third_party/waf/waflib/extras/remote.py deleted file mode 100644 index f43b600..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/remote.py +++ /dev/null @@ -1,327 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Remote Builds tool using rsync+ssh - -__author__ = "Jérôme Carretero " -__copyright__ = "Jérôme Carretero, 2013" - -""" -Simple Remote Builds -******************** - -This tool is an *experimental* tool (meaning, do not even try to pollute -the waf bug tracker with bugs in here, contact me directly) providing simple -remote builds. - -It uses rsync and ssh to perform the remote builds. -It is intended for performing cross-compilation on platforms where -a cross-compiler is either unavailable (eg. MacOS, QNX) a specific product -does not exist (eg. Windows builds using Visual Studio) or simply not installed. -This tool sends the sources and the waf script to the remote host, -and commands the usual waf execution. - -There are alternatives to using this tool, such as setting up shared folders, -logging on to remote machines, and building on the shared folders. -Electing one method or another depends on the size of the program. - - -Usage -===== - -1. Set your wscript file so it includes a list of variants, - e.g.:: - - from waflib import Utils - top = '.' - out = 'build' - - variants = [ - 'linux_64_debug', - 'linux_64_release', - 'linux_32_debug', - 'linux_32_release', - ] - - from waflib.extras import remote - - def options(opt): - # normal stuff from here on - opt.load('compiler_c') - - def configure(conf): - if not conf.variant: - return - # normal stuff from here on - conf.load('compiler_c') - - def build(bld): - if not bld.variant: - return - # normal stuff from here on - bld(features='c cprogram', target='app', source='main.c') - - -2. Build the waf file, so it includes this tool, and put it in the current - directory - - .. code:: bash - - ./waf-light --tools=remote - -3. Set the host names to access the hosts: - - .. code:: bash - - export REMOTE_QNX=user@kiunix - -4. Setup the ssh server and ssh keys - - The ssh key should not be protected by a password, or it will prompt for it every time. - Create the key on the client: - - .. code:: bash - - ssh-keygen -t rsa -f foo.rsa - - Then copy foo.rsa.pub to the remote machine (user@kiunix:/home/user/.ssh/authorized_keys), - and make sure the permissions are correct (chmod go-w ~ ~/.ssh ~/.ssh/authorized_keys) - - A separate key for the build processes can be set in the environment variable WAF_SSH_KEY. - The tool will then use 'ssh-keyscan' to avoid prompting for remote hosts, so - be warned to use this feature on internal networks only (MITM). - - .. code:: bash - - export WAF_SSH_KEY=~/foo.rsa - -5. Perform the build: - - .. code:: bash - - waf configure_all build_all --remote - -""" - - -import getpass, os, re, sys -from collections import OrderedDict -from waflib import Context, Options, Utils, ConfigSet - -from waflib.Build import BuildContext, CleanContext, InstallContext, UninstallContext -from waflib.Configure import ConfigurationContext - - -is_remote = False -if '--remote' in sys.argv: - is_remote = True - sys.argv.remove('--remote') - -class init(Context.Context): - """ - Generates the *_all commands - """ - cmd = 'init' - fun = 'init' - def execute(self): - for x in list(Context.g_module.variants): - self.make_variant(x) - lst = ['remote'] - for k in Options.commands: - if k.endswith('_all'): - name = k.replace('_all', '') - for x in Context.g_module.variants: - lst.append('%s_%s' % (name, x)) - else: - lst.append(k) - del Options.commands[:] - Options.commands += lst - - def make_variant(self, x): - for y in (BuildContext, CleanContext, InstallContext, UninstallContext): - name = y.__name__.replace('Context','').lower() - class tmp(y): - cmd = name + '_' + x - fun = 'build' - variant = x - class tmp(ConfigurationContext): - cmd = 'configure_' + x - fun = 'configure' - variant = x - def __init__(self, **kw): - ConfigurationContext.__init__(self, **kw) - self.setenv(x) - -class remote(BuildContext): - cmd = 'remote' - fun = 'build' - - def get_ssh_hosts(self): - lst = [] - for v in Context.g_module.variants: - self.env.HOST = self.login_to_host(self.variant_to_login(v)) - cmd = Utils.subst_vars('${SSH_KEYSCAN} -t rsa,ecdsa ${HOST}', self.env) - out, err = self.cmd_and_log(cmd, output=Context.BOTH, quiet=Context.BOTH) - lst.append(out.strip()) - return lst - - def setup_private_ssh_key(self): - """ - When WAF_SSH_KEY points to a private key, a .ssh directory will be created in the build directory - Make sure that the ssh key does not prompt for a password - """ - key = os.environ.get('WAF_SSH_KEY', '') - if not key: - return - if not os.path.isfile(key): - self.fatal('Key in WAF_SSH_KEY must point to a valid file') - self.ssh_dir = os.path.join(self.path.abspath(), 'build', '.ssh') - self.ssh_hosts = os.path.join(self.ssh_dir, 'known_hosts') - self.ssh_key = os.path.join(self.ssh_dir, os.path.basename(key)) - self.ssh_config = os.path.join(self.ssh_dir, 'config') - for x in self.ssh_hosts, self.ssh_key, self.ssh_config: - if not os.path.isfile(x): - if not os.path.isdir(self.ssh_dir): - os.makedirs(self.ssh_dir) - Utils.writef(self.ssh_key, Utils.readf(key), 'wb') - os.chmod(self.ssh_key, 448) - - Utils.writef(self.ssh_hosts, '\n'.join(self.get_ssh_hosts())) - os.chmod(self.ssh_key, 448) - - Utils.writef(self.ssh_config, 'UserKnownHostsFile %s' % self.ssh_hosts, 'wb') - os.chmod(self.ssh_config, 448) - self.env.SSH_OPTS = ['-F', self.ssh_config, '-i', self.ssh_key] - self.env.append_value('RSYNC_SEND_OPTS', '--exclude=build/.ssh') - - def skip_unbuildable_variant(self): - # skip variants that cannot be built on this OS - for k in Options.commands: - a, _, b = k.partition('_') - if b in Context.g_module.variants: - c, _, _ = b.partition('_') - if c != Utils.unversioned_sys_platform(): - Options.commands.remove(k) - - def login_to_host(self, login): - return re.sub(r'(\w+@)', '', login) - - def variant_to_login(self, variant): - """linux_32_debug -> search env.LINUX_32 and then env.LINUX""" - x = variant[:variant.rfind('_')] - ret = os.environ.get('REMOTE_' + x.upper(), '') - if not ret: - x = x[:x.find('_')] - ret = os.environ.get('REMOTE_' + x.upper(), '') - if not ret: - ret = '%s@localhost' % getpass.getuser() - return ret - - def execute(self): - global is_remote - if not is_remote: - self.skip_unbuildable_variant() - else: - BuildContext.execute(self) - - def restore(self): - self.top_dir = os.path.abspath(Context.g_module.top) - self.srcnode = self.root.find_node(self.top_dir) - self.path = self.srcnode - - self.out_dir = os.path.join(self.top_dir, Context.g_module.out) - self.bldnode = self.root.make_node(self.out_dir) - self.bldnode.mkdir() - - self.env = ConfigSet.ConfigSet() - - def extract_groups_of_builds(self): - """Return a dict mapping each variants to the commands to build""" - self.vgroups = {} - for x in reversed(Options.commands): - _, _, variant = x.partition('_') - if variant in Context.g_module.variants: - try: - dct = self.vgroups[variant] - except KeyError: - dct = self.vgroups[variant] = OrderedDict() - try: - dct[variant].append(x) - except KeyError: - dct[variant] = [x] - Options.commands.remove(x) - - def custom_options(self, login): - try: - return Context.g_module.host_options[login] - except (AttributeError, KeyError): - return {} - - def recurse(self, *k, **kw): - self.env.RSYNC = getattr(Context.g_module, 'rsync', 'rsync -a --chmod=u+rwx') - self.env.SSH = getattr(Context.g_module, 'ssh', 'ssh') - self.env.SSH_KEYSCAN = getattr(Context.g_module, 'ssh_keyscan', 'ssh-keyscan') - try: - self.env.WAF = getattr(Context.g_module, 'waf') - except AttributeError: - try: - os.stat('waf') - except KeyError: - self.fatal('Put a waf file in the directory (./waf-light --tools=remote)') - else: - self.env.WAF = './waf' - - self.extract_groups_of_builds() - self.setup_private_ssh_key() - for k, v in self.vgroups.items(): - task = self(rule=rsync_and_ssh, always=True) - task.env.login = self.variant_to_login(k) - - task.env.commands = [] - for opt, value in v.items(): - task.env.commands += value - task.env.variant = task.env.commands[0].partition('_')[2] - for opt, value in self.custom_options(k): - task.env[opt] = value - self.jobs = len(self.vgroups) - - def make_mkdir_command(self, task): - return Utils.subst_vars('${SSH} ${SSH_OPTS} ${login} "rm -fr ${remote_dir} && mkdir -p ${remote_dir}"', task.env) - - def make_send_command(self, task): - return Utils.subst_vars('${RSYNC} ${RSYNC_SEND_OPTS} -e "${SSH} ${SSH_OPTS}" ${local_dir} ${login}:${remote_dir}', task.env) - - def make_exec_command(self, task): - txt = '''${SSH} ${SSH_OPTS} ${login} "cd ${remote_dir} && ${WAF} ${commands}"''' - return Utils.subst_vars(txt, task.env) - - def make_save_command(self, task): - return Utils.subst_vars('${RSYNC} ${RSYNC_SAVE_OPTS} -e "${SSH} ${SSH_OPTS}" ${login}:${remote_dir_variant} ${build_dir}', task.env) - -def rsync_and_ssh(task): - - # remove a warning - task.uid_ = id(task) - - bld = task.generator.bld - - task.env.user, _, _ = task.env.login.partition('@') - task.env.hdir = Utils.to_hex(Utils.h_list((task.generator.path.abspath(), task.env.variant))) - task.env.remote_dir = '~%s/wafremote/%s' % (task.env.user, task.env.hdir) - task.env.local_dir = bld.srcnode.abspath() + '/' - - task.env.remote_dir_variant = '%s/%s/%s' % (task.env.remote_dir, Context.g_module.out, task.env.variant) - task.env.build_dir = bld.bldnode.abspath() - - ret = task.exec_command(bld.make_mkdir_command(task)) - if ret: - return ret - ret = task.exec_command(bld.make_send_command(task)) - if ret: - return ret - ret = task.exec_command(bld.make_exec_command(task)) - if ret: - return ret - ret = task.exec_command(bld.make_save_command(task)) - if ret: - return ret - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/resx.py b/ldb-2.0.8/third_party/waf/waflib/extras/resx.py deleted file mode 100644 index caf4d31..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/resx.py +++ /dev/null @@ -1,35 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 - -import os -from waflib import Task -from waflib.TaskGen import extension - -def configure(conf): - conf.find_program(['resgen'], var='RESGEN') - conf.env.RESGENFLAGS = '/useSourcePath' - -@extension('.resx') -def resx_file(self, node): - """ - Bind the .resx extension to a resgen task - """ - if not getattr(self, 'cs_task', None): - self.bld.fatal('resx_file has no link task for use %r' % self) - - # Given assembly 'Foo' and file 'Sub/Dir/File.resx', create 'Foo.Sub.Dir.File.resources' - assembly = getattr(self, 'namespace', os.path.splitext(self.gen)[0]) - res = os.path.splitext(node.path_from(self.path))[0].replace('/', '.').replace('\\', '.') - out = self.path.find_or_declare(assembly + '.' + res + '.resources') - - tsk = self.create_task('resgen', node, out) - - self.cs_task.dep_nodes.extend(tsk.outputs) # dependency - self.env.append_value('RESOURCES', tsk.outputs[0].bldpath()) - -class resgen(Task.Task): - """ - Compile C# resource files - """ - color = 'YELLOW' - run_str = '${RESGEN} ${RESGENFLAGS} ${SRC} ${TGT}' diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/review.py b/ldb-2.0.8/third_party/waf/waflib/extras/review.py deleted file mode 100644 index 561e062..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/review.py +++ /dev/null @@ -1,325 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Laurent Birtz, 2011 -# moved the code into a separate tool (ita) - -""" -There are several things here: -- a different command-line option management making options persistent -- the review command to display the options set - -Assumptions: -- configuration options are not always added to the right group (and do not count on the users to do it...) -- the options are persistent between the executions (waf options are NOT persistent by design), even for the configuration -- when the options change, the build is invalidated (forcing a reconfiguration) -""" - -import os, textwrap, shutil -from waflib import Logs, Context, ConfigSet, Options, Build, Configure - -class Odict(dict): - """Ordered dictionary""" - def __init__(self, data=None): - self._keys = [] - dict.__init__(self) - if data: - # we were provided a regular dict - if isinstance(data, dict): - self.append_from_dict(data) - - # we were provided a tuple list - elif type(data) == list: - self.append_from_plist(data) - - # we were provided invalid input - else: - raise Exception("expected a dict or a tuple list") - - def append_from_dict(self, dict): - map(self.__setitem__, dict.keys(), dict.values()) - - def append_from_plist(self, plist): - for pair in plist: - if len(pair) != 2: - raise Exception("invalid pairs list") - for (k, v) in plist: - self.__setitem__(k, v) - - def __delitem__(self, key): - if not key in self._keys: - raise KeyError(key) - dict.__delitem__(self, key) - self._keys.remove(key) - - def __setitem__(self, key, item): - dict.__setitem__(self, key, item) - if key not in self._keys: - self._keys.append(key) - - def clear(self): - dict.clear(self) - self._keys = [] - - def copy(self): - return Odict(self.plist()) - - def items(self): - return zip(self._keys, self.values()) - - def keys(self): - return list(self._keys) # return a copy of the list - - def values(self): - return map(self.get, self._keys) - - def plist(self): - p = [] - for k, v in self.items(): - p.append( (k, v) ) - return p - - def __str__(self): - buf = [] - buf.append("{ ") - for k, v in self.items(): - buf.append('%r : %r, ' % (k, v)) - buf.append("}") - return ''.join(buf) - -review_options = Odict() -""" -Ordered dictionary mapping configuration option names to their optparse option. -""" - -review_defaults = {} -""" -Dictionary mapping configuration option names to their default value. -""" - -old_review_set = None -""" -Review set containing the configuration values before parsing the command line. -""" - -new_review_set = None -""" -Review set containing the configuration values after parsing the command line. -""" - -class OptionsReview(Options.OptionsContext): - def __init__(self, **kw): - super(self.__class__, self).__init__(**kw) - - def prepare_config_review(self): - """ - Find the configuration options that are reviewable, detach - their default value from their optparse object and store them - into the review dictionaries. - """ - gr = self.get_option_group('configure options') - for opt in gr.option_list: - if opt.action != 'store' or opt.dest in ("out", "top"): - continue - review_options[opt.dest] = opt - review_defaults[opt.dest] = opt.default - if gr.defaults.has_key(opt.dest): - del gr.defaults[opt.dest] - opt.default = None - - def parse_args(self): - self.prepare_config_review() - self.parser.get_option('--prefix').help = 'installation prefix' - super(OptionsReview, self).parse_args() - Context.create_context('review').refresh_review_set() - -class ReviewContext(Context.Context): - '''reviews the configuration values''' - - cmd = 'review' - - def __init__(self, **kw): - super(self.__class__, self).__init__(**kw) - - out = Options.options.out - if not out: - out = getattr(Context.g_module, Context.OUT, None) - if not out: - out = Options.lockfile.replace('.lock-waf', '') - self.build_path = (os.path.isabs(out) and self.root or self.path).make_node(out).abspath() - """Path to the build directory""" - - self.cache_path = os.path.join(self.build_path, Build.CACHE_DIR) - """Path to the cache directory""" - - self.review_path = os.path.join(self.cache_path, 'review.cache') - """Path to the review cache file""" - - def execute(self): - """ - Display and store the review set. Invalidate the cache as required. - """ - if not self.compare_review_set(old_review_set, new_review_set): - self.invalidate_cache() - self.store_review_set(new_review_set) - print(self.display_review_set(new_review_set)) - - def invalidate_cache(self): - """Invalidate the cache to prevent bad builds.""" - try: - Logs.warn("Removing the cached configuration since the options have changed") - shutil.rmtree(self.cache_path) - except: - pass - - def refresh_review_set(self): - """ - Obtain the old review set and the new review set, and import the new set. - """ - global old_review_set, new_review_set - old_review_set = self.load_review_set() - new_review_set = self.update_review_set(old_review_set) - self.import_review_set(new_review_set) - - def load_review_set(self): - """ - Load and return the review set from the cache if it exists. - Otherwise, return an empty set. - """ - if os.path.isfile(self.review_path): - return ConfigSet.ConfigSet(self.review_path) - return ConfigSet.ConfigSet() - - def store_review_set(self, review_set): - """ - Store the review set specified in the cache. - """ - if not os.path.isdir(self.cache_path): - os.makedirs(self.cache_path) - review_set.store(self.review_path) - - def update_review_set(self, old_set): - """ - Merge the options passed on the command line with those imported - from the previous review set and return the corresponding - preview set. - """ - - # Convert value to string. It's important that 'None' maps to - # the empty string. - def val_to_str(val): - if val == None or val == '': - return '' - return str(val) - - new_set = ConfigSet.ConfigSet() - opt_dict = Options.options.__dict__ - - for name in review_options.keys(): - # the option is specified explicitly on the command line - if name in opt_dict: - # if the option is the default, pretend it was never specified - if val_to_str(opt_dict[name]) != val_to_str(review_defaults[name]): - new_set[name] = opt_dict[name] - # the option was explicitly specified in a previous command - elif name in old_set: - new_set[name] = old_set[name] - - return new_set - - def import_review_set(self, review_set): - """ - Import the actual value of the reviewable options in the option - dictionary, given the current review set. - """ - for name in review_options.keys(): - if name in review_set: - value = review_set[name] - else: - value = review_defaults[name] - setattr(Options.options, name, value) - - def compare_review_set(self, set1, set2): - """ - Return true if the review sets specified are equal. - """ - if len(set1.keys()) != len(set2.keys()): - return False - for key in set1.keys(): - if not key in set2 or set1[key] != set2[key]: - return False - return True - - def display_review_set(self, review_set): - """ - Return the string representing the review set specified. - """ - term_width = Logs.get_term_cols() - lines = [] - for dest in review_options.keys(): - opt = review_options[dest] - name = ", ".join(opt._short_opts + opt._long_opts) - help = opt.help - actual = None - if dest in review_set: - actual = review_set[dest] - default = review_defaults[dest] - lines.append(self.format_option(name, help, actual, default, term_width)) - return "Configuration:\n\n" + "\n\n".join(lines) + "\n" - - def format_option(self, name, help, actual, default, term_width): - """ - Return the string representing the option specified. - """ - def val_to_str(val): - if val == None or val == '': - return "(void)" - return str(val) - - max_name_len = 20 - sep_len = 2 - - w = textwrap.TextWrapper() - w.width = term_width - 1 - if w.width < 60: - w.width = 60 - - out = "" - - # format the help - out += w.fill(help) + "\n" - - # format the name - name_len = len(name) - out += Logs.colors.CYAN + name + Logs.colors.NORMAL - - # set the indentation used when the value wraps to the next line - w.subsequent_indent = " ".rjust(max_name_len + sep_len) - w.width -= (max_name_len + sep_len) - - # the name string is too long, switch to the next line - if name_len > max_name_len: - out += "\n" + w.subsequent_indent - - # fill the remaining of the line with spaces - else: - out += " ".rjust(max_name_len + sep_len - name_len) - - # format the actual value, if there is one - if actual != None: - out += Logs.colors.BOLD + w.fill(val_to_str(actual)) + Logs.colors.NORMAL + "\n" + w.subsequent_indent - - # format the default value - default_fmt = val_to_str(default) - if actual != None: - default_fmt = "default: " + default_fmt - out += Logs.colors.NORMAL + w.fill(default_fmt) + Logs.colors.NORMAL - - return out - -# Monkey-patch ConfigurationContext.execute() to have it store the review set. -old_configure_execute = Configure.ConfigurationContext.execute -def new_configure_execute(self): - old_configure_execute(self) - Context.create_context('review').store_review_set(new_review_set) -Configure.ConfigurationContext.execute = new_configure_execute - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/rst.py b/ldb-2.0.8/third_party/waf/waflib/extras/rst.py deleted file mode 100644 index f3c3a5e..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/rst.py +++ /dev/null @@ -1,260 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Jérôme Carretero, 2013 (zougloub) - -""" -reStructuredText support (experimental) - -Example:: - - def configure(conf): - conf.load('rst') - if not conf.env.RST2HTML: - conf.fatal('The program rst2html is required') - - def build(bld): - bld( - features = 'rst', - type = 'rst2html', # rst2html, rst2pdf, ... - source = 'index.rst', # mandatory, the source - deps = 'image.png', # to give additional non-trivial dependencies - ) - -By default the tool looks for a set of programs in PATH. -The tools are defined in `rst_progs`. -To configure with a special program use:: - - $ RST2HTML=/path/to/rst2html waf configure - -This tool is experimental; don't hesitate to contribute to it. - -""" - -import re -from waflib import Node, Utils, Task, Errors, Logs -from waflib.TaskGen import feature, before_method - -rst_progs = "rst2html rst2xetex rst2latex rst2xml rst2pdf rst2s5 rst2man rst2odt rst2rtf".split() - -def parse_rst_node(task, node, nodes, names, seen, dirs=None): - # TODO add extensibility, to handle custom rst include tags... - if dirs is None: - dirs = (node.parent,node.get_bld().parent) - - if node in seen: - return - seen.append(node) - code = node.read() - re_rst = re.compile(r'^\s*.. ((?P\|\S+\|) )?(?Pinclude|image|figure):: (?P.*)$', re.M) - for match in re_rst.finditer(code): - ipath = match.group('file') - itype = match.group('type') - Logs.debug('rst: visiting %s: %s', itype, ipath) - found = False - for d in dirs: - Logs.debug('rst: looking for %s in %s', ipath, d.abspath()) - found = d.find_node(ipath) - if found: - Logs.debug('rst: found %s as %s', ipath, found.abspath()) - nodes.append((itype, found)) - if itype == 'include': - parse_rst_node(task, found, nodes, names, seen) - break - if not found: - names.append((itype, ipath)) - -class docutils(Task.Task): - """ - Compile a rst file. - """ - - def scan(self): - """ - A recursive regex-based scanner that finds rst dependencies. - """ - - nodes = [] - names = [] - seen = [] - - node = self.inputs[0] - - if not node: - return (nodes, names) - - parse_rst_node(self, node, nodes, names, seen) - - Logs.debug('rst: %r: found the following file deps: %r', self, nodes) - if names: - Logs.warn('rst: %r: could not find the following file deps: %r', self, names) - - return ([v for (t,v) in nodes], [v for (t,v) in names]) - - def check_status(self, msg, retcode): - """ - Check an exit status and raise an error with a particular message - - :param msg: message to display if the code is non-zero - :type msg: string - :param retcode: condition - :type retcode: boolean - """ - if retcode != 0: - raise Errors.WafError('%r command exit status %r' % (msg, retcode)) - - def run(self): - """ - Runs the rst compilation using docutils - """ - raise NotImplementedError() - -class rst2html(docutils): - color = 'BLUE' - - def __init__(self, *args, **kw): - docutils.__init__(self, *args, **kw) - self.command = self.generator.env.RST2HTML - self.attributes = ['stylesheet'] - - def scan(self): - nodes, names = docutils.scan(self) - - for attribute in self.attributes: - stylesheet = getattr(self.generator, attribute, None) - if stylesheet is not None: - ssnode = self.generator.to_nodes(stylesheet)[0] - nodes.append(ssnode) - Logs.debug('rst: adding dep to %s %s', attribute, stylesheet) - - return nodes, names - - def run(self): - cwdn = self.outputs[0].parent - src = self.inputs[0].path_from(cwdn) - dst = self.outputs[0].path_from(cwdn) - - cmd = self.command + [src, dst] - cmd += Utils.to_list(getattr(self.generator, 'options', [])) - for attribute in self.attributes: - stylesheet = getattr(self.generator, attribute, None) - if stylesheet is not None: - stylesheet = self.generator.to_nodes(stylesheet)[0] - cmd += ['--%s' % attribute, stylesheet.path_from(cwdn)] - - return self.exec_command(cmd, cwd=cwdn.abspath()) - -class rst2s5(rst2html): - def __init__(self, *args, **kw): - rst2html.__init__(self, *args, **kw) - self.command = self.generator.env.RST2S5 - self.attributes = ['stylesheet'] - -class rst2latex(rst2html): - def __init__(self, *args, **kw): - rst2html.__init__(self, *args, **kw) - self.command = self.generator.env.RST2LATEX - self.attributes = ['stylesheet'] - -class rst2xetex(rst2html): - def __init__(self, *args, **kw): - rst2html.__init__(self, *args, **kw) - self.command = self.generator.env.RST2XETEX - self.attributes = ['stylesheet'] - -class rst2pdf(docutils): - color = 'BLUE' - def run(self): - cwdn = self.outputs[0].parent - src = self.inputs[0].path_from(cwdn) - dst = self.outputs[0].path_from(cwdn) - - cmd = self.generator.env.RST2PDF + [src, '-o', dst] - cmd += Utils.to_list(getattr(self.generator, 'options', [])) - - return self.exec_command(cmd, cwd=cwdn.abspath()) - - -@feature('rst') -@before_method('process_source') -def apply_rst(self): - """ - Create :py:class:`rst` or other rst-related task objects - """ - - if self.target: - if isinstance(self.target, Node.Node): - tgt = self.target - elif isinstance(self.target, str): - tgt = self.path.get_bld().make_node(self.target) - else: - self.bld.fatal("rst: Don't know how to build target name %s which is not a string or Node for %s" % (self.target, self)) - else: - tgt = None - - tsk_type = getattr(self, 'type', None) - - src = self.to_nodes(self.source) - assert len(src) == 1 - src = src[0] - - if tsk_type is not None and tgt is None: - if tsk_type.startswith('rst2'): - ext = tsk_type[4:] - else: - self.bld.fatal("rst: Could not detect the output file extension for %s" % self) - tgt = src.change_ext('.%s' % ext) - elif tsk_type is None and tgt is not None: - out = tgt.name - ext = out[out.rfind('.')+1:] - self.type = 'rst2' + ext - elif tsk_type is not None and tgt is not None: - # the user knows what he wants - pass - else: - self.bld.fatal("rst: Need to indicate task type or target name for %s" % self) - - deps_lst = [] - - if getattr(self, 'deps', None): - deps = self.to_list(self.deps) - for filename in deps: - n = self.path.find_resource(filename) - if not n: - self.bld.fatal('Could not find %r for %r' % (filename, self)) - if not n in deps_lst: - deps_lst.append(n) - - try: - task = self.create_task(self.type, src, tgt) - except KeyError: - self.bld.fatal("rst: Task of type %s not implemented (created by %s)" % (self.type, self)) - - task.env = self.env - - # add the manual dependencies - if deps_lst: - try: - lst = self.bld.node_deps[task.uid()] - for n in deps_lst: - if not n in lst: - lst.append(n) - except KeyError: - self.bld.node_deps[task.uid()] = deps_lst - - inst_to = getattr(self, 'install_path', None) - if inst_to: - self.install_task = self.add_install_files(install_to=inst_to, install_from=task.outputs[:]) - - self.source = [] - -def configure(self): - """ - Try to find the rst programs. - - Do not raise any error if they are not found. - You'll have to use additional code in configure() to die - if programs were not found. - """ - for p in rst_progs: - self.find_program(p, mandatory=False) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/run_do_script.py b/ldb-2.0.8/third_party/waf/waflib/extras/run_do_script.py deleted file mode 100644 index 07e3aa2..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/run_do_script.py +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Hans-Martin von Gaudecker, 2012 - -""" -Run a Stata do-script in the directory specified by **ctx.bldnode**. The -first and only argument will be the name of the do-script (no extension), -which can be accessed inside the do-script by the local macro `1'. Useful -for keeping a log file. - -The tool uses the log file that is automatically kept by Stata only -for error-catching purposes, it will be destroyed if the task finished -without error. In case of an error in **some_script.do**, you can inspect -it as **some_script.log** in the **ctx.bldnode** directory. - -Note that Stata will not return an error code if it exits abnormally -- -catching errors relies on parsing the log file mentioned before. Should -the parser behave incorrectly please send an email to hmgaudecker [at] gmail. - -**WARNING** - - The tool will not work if multiple do-scripts of the same name---but in - different directories---are run at the same time! Avoid this situation. - -Usage:: - - ctx(features='run_do_script', - source='some_script.do', - target=['some_table.tex', 'some_figure.eps'], - deps='some_data.csv') -""" - - -import os, re, sys -from waflib import Task, TaskGen, Logs - -if sys.platform == 'darwin': - STATA_COMMANDS = ['Stata64MP', 'StataMP', - 'Stata64SE', 'StataSE', - 'Stata64', 'Stata'] - STATAFLAGS = '-e -q do' - STATAENCODING = 'MacRoman' -elif sys.platform.startswith('linux'): - STATA_COMMANDS = ['stata-mp', 'stata-se', 'stata'] - STATAFLAGS = '-b -q do' - # Not sure whether this is correct... - STATAENCODING = 'Latin-1' -elif sys.platform.lower().startswith('win'): - STATA_COMMANDS = ['StataMP-64', 'StataMP-ia', - 'StataMP', 'StataSE-64', - 'StataSE-ia', 'StataSE', - 'Stata-64', 'Stata-ia', - 'Stata.e', 'WMPSTATA', - 'WSESTATA', 'WSTATA'] - STATAFLAGS = '/e do' - STATAENCODING = 'Latin-1' -else: - raise Exception("Unknown sys.platform: %s " % sys.platform) - -def configure(ctx): - ctx.find_program(STATA_COMMANDS, var='STATACMD', errmsg="""\n -No Stata executable found!\n\n -If Stata is needed:\n - 1) Check the settings of your system path. - 2) Note we are looking for Stata executables called: %s - If yours has a different name, please report to hmgaudecker [at] gmail\n -Else:\n - Do not load the 'run_do_script' tool in the main wscript.\n\n""" % STATA_COMMANDS) - ctx.env.STATAFLAGS = STATAFLAGS - ctx.env.STATAENCODING = STATAENCODING - -class run_do_script_base(Task.Task): - """Run a Stata do-script from the bldnode directory.""" - run_str = '"${STATACMD}" ${STATAFLAGS} "${SRC[0].abspath()}" "${DOFILETRUNK}"' - shell = True - -class run_do_script(run_do_script_base): - """Use the log file automatically kept by Stata for error-catching. - Erase it if the task finished without error. If not, it will show - up as do_script.log in the bldnode directory. - """ - def run(self): - run_do_script_base.run(self) - ret, log_tail = self.check_erase_log_file() - if ret: - Logs.error("""Running Stata on %r failed with code %r.\n\nCheck the log file %s, last 10 lines\n\n%s\n\n\n""", - self.inputs[0], ret, self.env.LOGFILEPATH, log_tail) - return ret - - def check_erase_log_file(self): - """Parse Stata's default log file and erase it if everything okay. - - Parser is based on Brendan Halpin's shell script found here: - http://teaching.sociology.ul.ie/bhalpin/wordpress/?p=122 - """ - - if sys.version_info.major >= 3: - kwargs = {'file': self.env.LOGFILEPATH, 'mode': 'r', 'encoding': self.env.STATAENCODING} - else: - kwargs = {'name': self.env.LOGFILEPATH, 'mode': 'r'} - with open(**kwargs) as log: - log_tail = log.readlines()[-10:] - for line in log_tail: - error_found = re.match(r"r\(([0-9]+)\)", line) - if error_found: - return error_found.group(1), ''.join(log_tail) - else: - pass - # Only end up here if the parser did not identify an error. - os.remove(self.env.LOGFILEPATH) - return None, None - - -@TaskGen.feature('run_do_script') -@TaskGen.before_method('process_source') -def apply_run_do_script(tg): - """Task generator customising the options etc. to call Stata in batch - mode for running a do-script. - """ - - # Convert sources and targets to nodes - src_node = tg.path.find_resource(tg.source) - tgt_nodes = [tg.path.find_or_declare(t) for t in tg.to_list(tg.target)] - - tsk = tg.create_task('run_do_script', src=src_node, tgt=tgt_nodes) - tsk.env.DOFILETRUNK = os.path.splitext(src_node.name)[0] - tsk.env.LOGFILEPATH = os.path.join(tg.bld.bldnode.abspath(), '%s.log' % (tsk.env.DOFILETRUNK)) - - # dependencies (if the attribute 'deps' changes, trigger a recompilation) - for x in tg.to_list(getattr(tg, 'deps', [])): - node = tg.path.find_resource(x) - if not node: - tg.bld.fatal('Could not find dependency %r for running %r' % (x, src_node.abspath())) - tsk.dep_nodes.append(node) - Logs.debug('deps: found dependencies %r for running %r', tsk.dep_nodes, src_node.abspath()) - - # Bypass the execution of process_source by setting the source to an empty list - tg.source = [] - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/run_m_script.py b/ldb-2.0.8/third_party/waf/waflib/extras/run_m_script.py deleted file mode 100644 index b5f27eb..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/run_m_script.py +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Hans-Martin von Gaudecker, 2012 - -""" -Run a Matlab script. - -Note that the script is run in the directory where it lives -- Matlab won't -allow it any other way. - -For error-catching purposes, keep an own log-file that is destroyed if the -task finished without error. If not, it will show up as mscript_[index].log -in the bldnode directory. - -Usage:: - - ctx(features='run_m_script', - source='some_script.m', - target=['some_table.tex', 'some_figure.eps'], - deps='some_data.mat') -""" - -import os, sys -from waflib import Task, TaskGen, Logs - -MATLAB_COMMANDS = ['matlab'] - -def configure(ctx): - ctx.find_program(MATLAB_COMMANDS, var='MATLABCMD', errmsg = """\n -No Matlab executable found!\n\n -If Matlab is needed:\n - 1) Check the settings of your system path. - 2) Note we are looking for Matlab executables called: %s - If yours has a different name, please report to hmgaudecker [at] gmail\n -Else:\n - Do not load the 'run_m_script' tool in the main wscript.\n\n""" % MATLAB_COMMANDS) - ctx.env.MATLABFLAGS = '-wait -nojvm -nosplash -minimize' - -class run_m_script_base(Task.Task): - """Run a Matlab script.""" - run_str = '"${MATLABCMD}" ${MATLABFLAGS} -logfile "${LOGFILEPATH}" -r "try, ${MSCRIPTTRUNK}, exit(0), catch err, disp(err.getReport()), exit(1), end"' - shell = True - -class run_m_script(run_m_script_base): - """Erase the Matlab overall log file if everything went okay, else raise an - error and print its 10 last lines. - """ - def run(self): - ret = run_m_script_base.run(self) - logfile = self.env.LOGFILEPATH - if ret: - mode = 'r' - if sys.version_info.major >= 3: - mode = 'rb' - with open(logfile, mode=mode) as f: - tail = f.readlines()[-10:] - Logs.error("""Running Matlab on %r returned the error %r\n\nCheck the log file %s, last 10 lines\n\n%s\n\n\n""", - self.inputs[0], ret, logfile, '\n'.join(tail)) - else: - os.remove(logfile) - return ret - -@TaskGen.feature('run_m_script') -@TaskGen.before_method('process_source') -def apply_run_m_script(tg): - """Task generator customising the options etc. to call Matlab in batch - mode for running a m-script. - """ - - # Convert sources and targets to nodes - src_node = tg.path.find_resource(tg.source) - tgt_nodes = [tg.path.find_or_declare(t) for t in tg.to_list(tg.target)] - - tsk = tg.create_task('run_m_script', src=src_node, tgt=tgt_nodes) - tsk.cwd = src_node.parent.abspath() - tsk.env.MSCRIPTTRUNK = os.path.splitext(src_node.name)[0] - tsk.env.LOGFILEPATH = os.path.join(tg.bld.bldnode.abspath(), '%s_%d.log' % (tsk.env.MSCRIPTTRUNK, tg.idx)) - - # dependencies (if the attribute 'deps' changes, trigger a recompilation) - for x in tg.to_list(getattr(tg, 'deps', [])): - node = tg.path.find_resource(x) - if not node: - tg.bld.fatal('Could not find dependency %r for running %r' % (x, src_node.abspath())) - tsk.dep_nodes.append(node) - Logs.debug('deps: found dependencies %r for running %r', tsk.dep_nodes, src_node.abspath()) - - # Bypass the execution of process_source by setting the source to an empty list - tg.source = [] diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/run_py_script.py b/ldb-2.0.8/third_party/waf/waflib/extras/run_py_script.py deleted file mode 100644 index 3670381..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/run_py_script.py +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Hans-Martin von Gaudecker, 2012 - -""" -Run a Python script in the directory specified by **ctx.bldnode**. - -Select a Python version by specifying the **version** keyword for -the task generator instance as integer 2 or 3. Default is 3. - -If the build environment has an attribute "PROJECT_PATHS" with -a key "PROJECT_ROOT", its value will be appended to the PYTHONPATH. -Same a string passed to the optional **add_to_pythonpath** -keyword (appended after the PROJECT_ROOT). - -Usage:: - - ctx(features='run_py_script', version=3, - source='some_script.py', - target=['some_table.tex', 'some_figure.eps'], - deps='some_data.csv', - add_to_pythonpath='src/some/library') -""" - -import os, re -from waflib import Task, TaskGen, Logs - - -def configure(conf): - """TODO: Might need to be updated for Windows once - "PEP 397":http://www.python.org/dev/peps/pep-0397/ is settled. - """ - conf.find_program('python', var='PY2CMD', mandatory=False) - conf.find_program('python3', var='PY3CMD', mandatory=False) - if not conf.env.PY2CMD and not conf.env.PY3CMD: - conf.fatal("No Python interpreter found!") - -class run_py_2_script(Task.Task): - """Run a Python 2 script.""" - run_str = '${PY2CMD} ${SRC[0].abspath()}' - shell=True - -class run_py_3_script(Task.Task): - """Run a Python 3 script.""" - run_str = '${PY3CMD} ${SRC[0].abspath()}' - shell=True - -@TaskGen.feature('run_py_script') -@TaskGen.before_method('process_source') -def apply_run_py_script(tg): - """Task generator for running either Python 2 or Python 3 on a single - script. - - Attributes: - - * source -- A **single** source node or string. (required) - * target -- A single target or list of targets (nodes or strings) - * deps -- A single dependency or list of dependencies (nodes or strings) - * add_to_pythonpath -- A string that will be appended to the PYTHONPATH environment variable - - If the build environment has an attribute "PROJECT_PATHS" with - a key "PROJECT_ROOT", its value will be appended to the PYTHONPATH. - """ - - # Set the Python version to use, default to 3. - v = getattr(tg, 'version', 3) - if v not in (2, 3): - raise ValueError("Specify the 'version' attribute for run_py_script task generator as integer 2 or 3.\n Got: %s" %v) - - # Convert sources and targets to nodes - src_node = tg.path.find_resource(tg.source) - tgt_nodes = [tg.path.find_or_declare(t) for t in tg.to_list(tg.target)] - - # Create the task. - tsk = tg.create_task('run_py_%d_script' %v, src=src_node, tgt=tgt_nodes) - - # custom execution environment - # TODO use a list and os.sep.join(lst) at the end instead of concatenating strings - tsk.env.env = dict(os.environ) - tsk.env.env['PYTHONPATH'] = tsk.env.env.get('PYTHONPATH', '') - project_paths = getattr(tsk.env, 'PROJECT_PATHS', None) - if project_paths and 'PROJECT_ROOT' in project_paths: - tsk.env.env['PYTHONPATH'] += os.pathsep + project_paths['PROJECT_ROOT'].abspath() - if getattr(tg, 'add_to_pythonpath', None): - tsk.env.env['PYTHONPATH'] += os.pathsep + tg.add_to_pythonpath - - # Clean up the PYTHONPATH -- replace double occurrences of path separator - tsk.env.env['PYTHONPATH'] = re.sub(os.pathsep + '+', os.pathsep, tsk.env.env['PYTHONPATH']) - - # Clean up the PYTHONPATH -- doesn't like starting with path separator - if tsk.env.env['PYTHONPATH'].startswith(os.pathsep): - tsk.env.env['PYTHONPATH'] = tsk.env.env['PYTHONPATH'][1:] - - # dependencies (if the attribute 'deps' changes, trigger a recompilation) - for x in tg.to_list(getattr(tg, 'deps', [])): - node = tg.path.find_resource(x) - if not node: - tg.bld.fatal('Could not find dependency %r for running %r' % (x, src_node.abspath())) - tsk.dep_nodes.append(node) - Logs.debug('deps: found dependencies %r for running %r', tsk.dep_nodes, src_node.abspath()) - - # Bypass the execution of process_source by setting the source to an empty list - tg.source = [] - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/run_r_script.py b/ldb-2.0.8/third_party/waf/waflib/extras/run_r_script.py deleted file mode 100644 index b0d8f2b..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/run_r_script.py +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Hans-Martin von Gaudecker, 2012 - -""" -Run a R script in the directory specified by **ctx.bldnode**. - -For error-catching purposes, keep an own log-file that is destroyed if the -task finished without error. If not, it will show up as rscript_[index].log -in the bldnode directory. - -Usage:: - - ctx(features='run_r_script', - source='some_script.r', - target=['some_table.tex', 'some_figure.eps'], - deps='some_data.csv') -""" - - -import os, sys -from waflib import Task, TaskGen, Logs - -R_COMMANDS = ['RTerm', 'R', 'r'] - -def configure(ctx): - ctx.find_program(R_COMMANDS, var='RCMD', errmsg = """\n -No R executable found!\n\n -If R is needed:\n - 1) Check the settings of your system path. - 2) Note we are looking for R executables called: %s - If yours has a different name, please report to hmgaudecker [at] gmail\n -Else:\n - Do not load the 'run_r_script' tool in the main wscript.\n\n""" % R_COMMANDS) - ctx.env.RFLAGS = 'CMD BATCH --slave' - -class run_r_script_base(Task.Task): - """Run a R script.""" - run_str = '"${RCMD}" ${RFLAGS} "${SRC[0].abspath()}" "${LOGFILEPATH}"' - shell = True - -class run_r_script(run_r_script_base): - """Erase the R overall log file if everything went okay, else raise an - error and print its 10 last lines. - """ - def run(self): - ret = run_r_script_base.run(self) - logfile = self.env.LOGFILEPATH - if ret: - mode = 'r' - if sys.version_info.major >= 3: - mode = 'rb' - with open(logfile, mode=mode) as f: - tail = f.readlines()[-10:] - Logs.error("""Running R on %r returned the error %r\n\nCheck the log file %s, last 10 lines\n\n%s\n\n\n""", - self.inputs[0], ret, logfile, '\n'.join(tail)) - else: - os.remove(logfile) - return ret - - -@TaskGen.feature('run_r_script') -@TaskGen.before_method('process_source') -def apply_run_r_script(tg): - """Task generator customising the options etc. to call R in batch - mode for running a R script. - """ - - # Convert sources and targets to nodes - src_node = tg.path.find_resource(tg.source) - tgt_nodes = [tg.path.find_or_declare(t) for t in tg.to_list(tg.target)] - - tsk = tg.create_task('run_r_script', src=src_node, tgt=tgt_nodes) - tsk.env.LOGFILEPATH = os.path.join(tg.bld.bldnode.abspath(), '%s_%d.log' % (os.path.splitext(src_node.name)[0], tg.idx)) - - # dependencies (if the attribute 'deps' changes, trigger a recompilation) - for x in tg.to_list(getattr(tg, 'deps', [])): - node = tg.path.find_resource(x) - if not node: - tg.bld.fatal('Could not find dependency %r for running %r' % (x, src_node.abspath())) - tsk.dep_nodes.append(node) - Logs.debug('deps: found dependencies %r for running %r', tsk.dep_nodes, src_node.abspath()) - - # Bypass the execution of process_source by setting the source to an empty list - tg.source = [] - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/sas.py b/ldb-2.0.8/third_party/waf/waflib/extras/sas.py deleted file mode 100644 index 754c614..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/sas.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Mark Coggeshall, 2010 - -"SAS support" - -import os -from waflib import Task, Errors, Logs -from waflib.TaskGen import feature, before_method - -sas_fun, _ = Task.compile_fun('sas -sysin ${SRCFILE} -log ${LOGFILE} -print ${LSTFILE}', shell=False) - -class sas(Task.Task): - vars = ['SAS', 'SASFLAGS'] - def run(task): - command = 'SAS' - fun = sas_fun - - node = task.inputs[0] - logfilenode = node.change_ext('.log') - lstfilenode = node.change_ext('.lst') - - # set the cwd - task.cwd = task.inputs[0].parent.get_src().abspath() - Logs.debug('runner: %r on %r', command, node) - - SASINPUTS = node.parent.get_bld().abspath() + os.pathsep + node.parent.get_src().abspath() + os.pathsep - task.env.env = {'SASINPUTS': SASINPUTS} - - task.env.SRCFILE = node.abspath() - task.env.LOGFILE = logfilenode.abspath() - task.env.LSTFILE = lstfilenode.abspath() - ret = fun(task) - if ret: - Logs.error('Running %s on %r returned a non-zero exit', command, node) - Logs.error('SRCFILE = %r', node) - Logs.error('LOGFILE = %r', logfilenode) - Logs.error('LSTFILE = %r', lstfilenode) - return ret - -@feature('sas') -@before_method('process_source') -def apply_sas(self): - if not getattr(self, 'type', None) in ('sas',): - self.type = 'sas' - - self.env['logdir'] = getattr(self, 'logdir', 'log') - self.env['lstdir'] = getattr(self, 'lstdir', 'lst') - - deps_lst = [] - - if getattr(self, 'deps', None): - deps = self.to_list(self.deps) - for filename in deps: - n = self.path.find_resource(filename) - if not n: - n = self.bld.root.find_resource(filename) - if not n: - raise Errors.WafError('cannot find input file %s for processing' % filename) - if not n in deps_lst: - deps_lst.append(n) - - for node in self.to_nodes(self.source): - if self.type == 'sas': - task = self.create_task('sas', src=node) - task.dep_nodes = deps_lst - self.source = [] - -def configure(self): - self.find_program('sas', var='SAS', mandatory=False) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/satellite_assembly.py b/ldb-2.0.8/third_party/waf/waflib/extras/satellite_assembly.py deleted file mode 100644 index 005eb07..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/satellite_assembly.py +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/python -# encoding: utf-8 -# vim: tabstop=4 noexpandtab - -""" -Create a satellite assembly from "*.??.txt" files. ?? stands for a language code. - -The projects Resources subfolder contains resources.??.txt string files for several languages. -The build folder will hold the satellite assemblies as ./??/ExeName.resources.dll - -#gen becomes template (It is called gen because it also uses resx.py). -bld(source='Resources/resources.de.txt',gen=ExeName) -""" - -import os, re -from waflib import Task -from waflib.TaskGen import feature,before_method - -class al(Task.Task): - run_str = '${AL} ${ALFLAGS}' - -@feature('satellite_assembly') -@before_method('process_source') -def satellite_assembly(self): - if not getattr(self, 'gen', None): - self.bld.fatal('satellite_assembly needs a template assembly provided with the "gen" parameter') - res_lang = re.compile(r'(.*)\.(\w\w)\.(?:resx|txt)',flags=re.I) - - # self.source can contain node objects, so this will break in one way or another - self.source = self.to_list(self.source) - for i, x in enumerate(self.source): - #x = 'resources/resources.de.resx' - #x = 'resources/resources.de.txt' - mo = res_lang.match(x) - if mo: - template = os.path.splitext(self.gen)[0] - templatedir, templatename = os.path.split(template) - res = mo.group(1) - lang = mo.group(2) - #./Resources/resources.de.resources - resources = self.path.find_or_declare(res+ '.' + lang + '.resources') - self.create_task('resgen', self.to_nodes(x), [resources]) - #./de/Exename.resources.dll - satellite = self.path.find_or_declare(os.path.join(templatedir,lang,templatename) + '.resources.dll') - tsk = self.create_task('al',[resources],[satellite]) - tsk.env.append_value('ALFLAGS','/template:'+os.path.join(self.path.relpath(),self.gen)) - tsk.env.append_value('ALFLAGS','/embed:'+resources.relpath()) - tsk.env.append_value('ALFLAGS','/culture:'+lang) - tsk.env.append_value('ALFLAGS','/out:'+satellite.relpath()) - self.source[i] = None - # remove the None elements that we just substituted - self.source = list(filter(lambda x:x, self.source)) - -def configure(ctx): - ctx.find_program('al', var='AL', mandatory=True) - ctx.load('resx') - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/scala.py b/ldb-2.0.8/third_party/waf/waflib/extras/scala.py deleted file mode 100644 index a9880f0..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/scala.py +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2010 (ita) - -""" -Scala support - -scalac outputs files a bit where it wants to -""" - -import os -from waflib import Task, Utils, Node -from waflib.TaskGen import feature, before_method, after_method - -from waflib.Tools import ccroot -ccroot.USELIB_VARS['scalac'] = set(['CLASSPATH', 'SCALACFLAGS']) - -from waflib.Tools import javaw - -@feature('scalac') -@before_method('process_source') -def apply_scalac(self): - - Utils.def_attrs(self, jarname='', classpath='', - sourcepath='.', srcdir='.', - jar_mf_attributes={}, jar_mf_classpath=[]) - - outdir = getattr(self, 'outdir', None) - if outdir: - if not isinstance(outdir, Node.Node): - outdir = self.path.get_bld().make_node(self.outdir) - else: - outdir = self.path.get_bld() - outdir.mkdir() - self.env['OUTDIR'] = outdir.abspath() - - self.scalac_task = tsk = self.create_task('scalac') - tmp = [] - - srcdir = getattr(self, 'srcdir', '') - if isinstance(srcdir, Node.Node): - srcdir = [srcdir] - for x in Utils.to_list(srcdir): - if isinstance(x, Node.Node): - y = x - else: - y = self.path.find_dir(x) - if not y: - self.bld.fatal('Could not find the folder %s from %s' % (x, self.path)) - tmp.append(y) - tsk.srcdir = tmp - -# reuse some code -feature('scalac')(javaw.use_javac_files) -after_method('apply_scalac')(javaw.use_javac_files) - -feature('scalac')(javaw.set_classpath) -after_method('apply_scalac', 'use_scalac_files')(javaw.set_classpath) - - -SOURCE_RE = '**/*.scala' -class scalac(javaw.javac): - color = 'GREEN' - vars = ['CLASSPATH', 'SCALACFLAGS', 'SCALAC', 'OUTDIR'] - - def runnable_status(self): - """ - Wait for dependent tasks to be complete, then read the file system to find the input nodes. - """ - for t in self.run_after: - if not t.hasrun: - return Task.ASK_LATER - - if not self.inputs: - global SOURCE_RE - self.inputs = [] - for x in self.srcdir: - self.inputs.extend(x.ant_glob(SOURCE_RE, remove=False)) - return super(javaw.javac, self).runnable_status() - - def run(self): - """ - Execute the scalac compiler - """ - env = self.env - gen = self.generator - bld = gen.bld - wd = bld.bldnode.abspath() - def to_list(xx): - if isinstance(xx, str): - return [xx] - return xx - self.last_cmd = lst = [] - lst.extend(to_list(env['SCALAC'])) - lst.extend(['-classpath']) - lst.extend(to_list(env['CLASSPATH'])) - lst.extend(['-d']) - lst.extend(to_list(env['OUTDIR'])) - lst.extend(to_list(env['SCALACFLAGS'])) - lst.extend([a.abspath() for a in self.inputs]) - lst = [x for x in lst if x] - try: - self.out = self.generator.bld.cmd_and_log(lst, cwd=wd, env=env.env or None, output=0, quiet=0)[1] - except: - self.generator.bld.cmd_and_log(lst, cwd=wd, env=env.env or None) - -def configure(self): - """ - Detect the scalac program - """ - # If SCALA_HOME is set, we prepend it to the path list - java_path = self.environ['PATH'].split(os.pathsep) - v = self.env - - if 'SCALA_HOME' in self.environ: - java_path = [os.path.join(self.environ['SCALA_HOME'], 'bin')] + java_path - self.env['SCALA_HOME'] = [self.environ['SCALA_HOME']] - - for x in 'scalac scala'.split(): - self.find_program(x, var=x.upper(), path_list=java_path) - - if 'CLASSPATH' in self.environ: - v['CLASSPATH'] = self.environ['CLASSPATH'] - - v.SCALACFLAGS = ['-verbose'] - if not v['SCALAC']: - self.fatal('scalac is required for compiling scala classes') - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/slow_qt4.py b/ldb-2.0.8/third_party/waf/waflib/extras/slow_qt4.py deleted file mode 100644 index ec7880b..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/slow_qt4.py +++ /dev/null @@ -1,96 +0,0 @@ -#! /usr/bin/env python -# Thomas Nagy, 2011 (ita) - -""" -Create _moc.cpp files - -The builds are 30-40% faster when .moc files are included, -you should NOT use this tool. If you really -really want it: - -def configure(conf): - conf.load('compiler_cxx qt4') - conf.load('slow_qt4') - -See playground/slow_qt/wscript for a complete example. -""" - -from waflib.TaskGen import extension -from waflib import Task -import waflib.Tools.qt4 -import waflib.Tools.cxx - -@extension(*waflib.Tools.qt4.EXT_QT4) -def cxx_hook(self, node): - return self.create_compiled_task('cxx_qt', node) - -class cxx_qt(Task.classes['cxx']): - def runnable_status(self): - ret = Task.classes['cxx'].runnable_status(self) - if ret != Task.ASK_LATER and not getattr(self, 'moc_done', None): - - try: - cache = self.generator.moc_cache - except AttributeError: - cache = self.generator.moc_cache = {} - - deps = self.generator.bld.node_deps[self.uid()] - for x in [self.inputs[0]] + deps: - if x.read().find('Q_OBJECT') > 0: - - # process "foo.h -> foo.moc" only if "foo.cpp" is in the sources for the current task generator - # this code will work because it is in the main thread (runnable_status) - if x.name.rfind('.') > -1: # a .h file... - name = x.name[:x.name.rfind('.')] - for tsk in self.generator.compiled_tasks: - if tsk.inputs and tsk.inputs[0].name.startswith(name): - break - else: - # no corresponding file, continue - continue - - # the file foo.cpp could be compiled for a static and a shared library - hence the %number in the name - cxx_node = x.parent.get_bld().make_node(x.name.replace('.', '_') + '_%d_moc.cpp' % self.generator.idx) - if cxx_node in cache: - continue - cache[cxx_node] = self - - tsk = Task.classes['moc'](env=self.env, generator=self.generator) - tsk.set_inputs(x) - tsk.set_outputs(cxx_node) - - if x.name.endswith('.cpp'): - # moc is trying to be too smart but it is too dumb: - # why forcing the #include when Q_OBJECT is in the cpp file? - gen = self.generator.bld.producer - gen.outstanding.append(tsk) - gen.total += 1 - self.set_run_after(tsk) - else: - cxxtsk = Task.classes['cxx'](env=self.env, generator=self.generator) - cxxtsk.set_inputs(tsk.outputs) - cxxtsk.set_outputs(cxx_node.change_ext('.o')) - cxxtsk.set_run_after(tsk) - - try: - self.more_tasks.extend([tsk, cxxtsk]) - except AttributeError: - self.more_tasks = [tsk, cxxtsk] - - try: - link = self.generator.link_task - except AttributeError: - pass - else: - link.set_run_after(cxxtsk) - link.inputs.extend(cxxtsk.outputs) - link.inputs.sort(key=lambda x: x.abspath()) - - self.moc_done = True - - for t in self.run_after: - if not t.hasrun: - return Task.ASK_LATER - - return ret - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/softlink_libs.py b/ldb-2.0.8/third_party/waf/waflib/extras/softlink_libs.py deleted file mode 100644 index 50c777f..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/softlink_libs.py +++ /dev/null @@ -1,76 +0,0 @@ -#! /usr/bin/env python -# per rosengren 2011 - -from waflib.TaskGen import feature, after_method -from waflib.Task import Task, always_run -from os.path import basename, isabs -from os import tmpfile, linesep - -def options(opt): - grp = opt.add_option_group('Softlink Libraries Options') - grp.add_option('--exclude', default='/usr/lib,/lib', help='No symbolic links are created for libs within [%default]') - -def configure(cnf): - cnf.find_program('ldd') - if not cnf.env.SOFTLINK_EXCLUDE: - cnf.env.SOFTLINK_EXCLUDE = cnf.options.exclude.split(',') - -@feature('softlink_libs') -@after_method('process_rule') -def add_finder(self): - tgt = self.path.find_or_declare(self.target) - self.create_task('sll_finder', tgt=tgt) - self.create_task('sll_installer', tgt=tgt) - always_run(sll_installer) - -class sll_finder(Task): - ext_out = 'softlink_libs' - def run(self): - bld = self.generator.bld - linked=[] - target_paths = [] - for g in bld.groups: - for tgen in g: - # FIXME it might be better to check if there is a link_task (getattr?) - target_paths += [tgen.path.get_bld().bldpath()] - linked += [t.outputs[0].bldpath() - for t in getattr(tgen, 'tasks', []) - if t.__class__.__name__ in - ['cprogram', 'cshlib', 'cxxprogram', 'cxxshlib']] - lib_list = [] - if len(linked): - cmd = [self.env.LDD] + linked - # FIXME add DYLD_LIBRARY_PATH+PATH for osx+win32 - ldd_env = {'LD_LIBRARY_PATH': ':'.join(target_paths + self.env.LIBPATH)} - # FIXME the with syntax will not work in python 2 - with tmpfile() as result: - self.exec_command(cmd, env=ldd_env, stdout=result) - result.seek(0) - for line in result.readlines(): - words = line.split() - if len(words) < 3 or words[1] != '=>': - continue - lib = words[2] - if lib == 'not': - continue - if any([lib.startswith(p) for p in - [bld.bldnode.abspath(), '('] + - self.env.SOFTLINK_EXCLUDE]): - continue - if not isabs(lib): - continue - lib_list.append(lib) - lib_list = sorted(set(lib_list)) - self.outputs[0].write(linesep.join(lib_list + self.env.DYNAMIC_LIBS)) - return 0 - -class sll_installer(Task): - ext_in = 'softlink_libs' - def run(self): - tgt = self.outputs[0] - self.generator.bld.install_files('${LIBDIR}', tgt, postpone=False) - lib_list=tgt.read().split() - for lib in lib_list: - self.generator.bld.symlink_as('${LIBDIR}/'+basename(lib), lib, postpone=False) - return 0 - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/sphinx.py b/ldb-2.0.8/third_party/waf/waflib/extras/sphinx.py deleted file mode 100644 index ce11110..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/sphinx.py +++ /dev/null @@ -1,81 +0,0 @@ -"""Support for Sphinx documentation - -This is a wrapper for sphinx-build program. Please note that sphinx-build supports only one output format which can -passed to build via sphinx_output_format attribute. The default output format is html. - -Example wscript: - -def configure(cnf): - conf.load('sphinx') - -def build(bld): - bld( - features='sphinx', - sphinx_source='sources', # path to source directory - sphinx_options='-a -v', # sphinx-build program additional options - sphinx_output_format='man' # output format of sphinx documentation - ) - -""" - -from waflib.Node import Node -from waflib import Utils -from waflib.Task import Task -from waflib.TaskGen import feature, after_method - - -def configure(cnf): - """Check if sphinx-build program is available and loads gnu_dirs tool.""" - cnf.find_program('sphinx-build', var='SPHINX_BUILD', mandatory=False) - cnf.load('gnu_dirs') - - -@feature('sphinx') -def build_sphinx(self): - """Builds sphinx sources. - """ - if not self.env.SPHINX_BUILD: - self.bld.fatal('Program SPHINX_BUILD not defined.') - if not getattr(self, 'sphinx_source', None): - self.bld.fatal('Attribute sphinx_source not defined.') - if not isinstance(self.sphinx_source, Node): - self.sphinx_source = self.path.find_node(self.sphinx_source) - if not self.sphinx_source: - self.bld.fatal('Can\'t find sphinx_source: %r' % self.sphinx_source) - - Utils.def_attrs(self, sphinx_output_format='html') - self.env.SPHINX_OUTPUT_FORMAT = self.sphinx_output_format - self.env.SPHINX_OPTIONS = getattr(self, 'sphinx_options', []) - - for source_file in self.sphinx_source.ant_glob('**/*'): - self.bld.add_manual_dependency(self.sphinx_source, source_file) - - sphinx_build_task = self.create_task('SphinxBuildingTask') - sphinx_build_task.set_inputs(self.sphinx_source) - sphinx_build_task.set_outputs(self.path.get_bld()) - - # the sphinx-build results are in directory - sphinx_output_directory = self.path.get_bld().make_node(self.env.SPHINX_OUTPUT_FORMAT) - sphinx_output_directory.mkdir() - Utils.def_attrs(self, install_path=get_install_path(self)) - self.add_install_files(install_to=self.install_path, - install_from=sphinx_output_directory.ant_glob('**/*'), - cwd=sphinx_output_directory, - relative_trick=True) - - -def get_install_path(tg): - if tg.env.SPHINX_OUTPUT_FORMAT == 'man': - return tg.env.MANDIR - elif tg.env.SPHINX_OUTPUT_FORMAT == 'info': - return tg.env.INFODIR - else: - return tg.env.DOCDIR - - -class SphinxBuildingTask(Task): - color = 'BOLD' - run_str = '${SPHINX_BUILD} -M ${SPHINX_OUTPUT_FORMAT} ${SRC} ${TGT} ${SPHINX_OPTIONS}' - - def keyword(self): - return 'Compiling (%s)' % self.env.SPHINX_OUTPUT_FORMAT diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/stale.py b/ldb-2.0.8/third_party/waf/waflib/extras/stale.py deleted file mode 100644 index cac3f46..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/stale.py +++ /dev/null @@ -1,98 +0,0 @@ -#! /usr/bin/env python -# encoding: UTF-8 -# Thomas Nagy, 2006-2015 (ita) - -""" -Add a pre-build hook to remove build files (declared in the system) -that do not have a corresponding target - -This can be used for example to remove the targets -that have changed name without performing -a full 'waf clean' - -Of course, it will only work if there are no dynamically generated -nodes/tasks, in which case the method will have to be modified -to exclude some folders for example. - -Make sure to set bld.post_mode = waflib.Build.POST_AT_ONCE -""" - -from waflib import Logs, Build -from waflib.Runner import Parallel - -DYNAMIC_EXT = [] # add your non-cleanable files/extensions here -MOC_H_EXTS = '.cpp .cxx .hpp .hxx .h'.split() - -def can_delete(node): - """Imperfect moc cleanup which does not look for a Q_OBJECT macro in the files""" - if not node.name.endswith('.moc'): - return True - base = node.name[:-4] - p1 = node.parent.get_src() - p2 = node.parent.get_bld() - for k in MOC_H_EXTS: - h_name = base + k - n = p1.search_node(h_name) - if n: - return False - n = p2.search_node(h_name) - if n: - return False - - # foo.cpp.moc, foo.h.moc, etc. - if base.endswith(k): - return False - - return True - -# recursion over the nodes to find the stale files -def stale_rec(node, nodes): - if node.abspath() in node.ctx.env[Build.CFG_FILES]: - return - - if getattr(node, 'children', []): - for x in node.children.values(): - if x.name != "c4che": - stale_rec(x, nodes) - else: - for ext in DYNAMIC_EXT: - if node.name.endswith(ext): - break - else: - if not node in nodes: - if can_delete(node): - Logs.warn('Removing stale file -> %r', node) - node.delete() - -old = Parallel.refill_task_list -def refill_task_list(self): - iit = old(self) - bld = self.bld - - # execute this operation only once - if getattr(self, 'stale_done', False): - return iit - self.stale_done = True - - # this does not work in partial builds - if bld.targets != '*': - return iit - - # this does not work in dynamic builds - if getattr(bld, 'post_mode') == Build.POST_AT_ONCE: - return iit - - # obtain the nodes to use during the build - nodes = [] - for tasks in bld.groups: - for x in tasks: - try: - nodes.extend(x.outputs) - except AttributeError: - pass - - stale_rec(bld.bldnode, nodes) - return iit - -Parallel.refill_task_list = refill_task_list - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/stracedeps.py b/ldb-2.0.8/third_party/waf/waflib/extras/stracedeps.py deleted file mode 100644 index 37d82cb..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/stracedeps.py +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2015 (ita) - -""" -Execute tasks through strace to obtain dependencies after the process is run. This -scheme is similar to that of the Fabricate script. - -To use:: - - def configure(conf): - conf.load('strace') - -WARNING: -* This will not work when advanced scanners are needed (qt4/qt5) -* The overhead of running 'strace' is significant (56s -> 1m29s) -* It will not work on Windows :-) -""" - -import os, re, threading -from waflib import Task, Logs, Utils - -#TRACECALLS = 'trace=access,chdir,clone,creat,execve,exit_group,fork,lstat,lstat64,mkdir,open,rename,stat,stat64,symlink,vfork' -TRACECALLS = 'trace=process,file' - -BANNED = ('/tmp', '/proc', '/sys', '/dev') - -s_process = r'(?:clone|fork|vfork)\(.*?(?P\d+)' -s_file = r'(?P\w+)\("(?P([^"\\]|\\.)*)"(.*)' -re_lines = re.compile(r'^(?P\d+)\s+(?:(?:%s)|(?:%s))\r*$' % (s_file, s_process), re.IGNORECASE | re.MULTILINE) -strace_lock = threading.Lock() - -def configure(conf): - conf.find_program('strace') - -def task_method(func): - # Decorator function to bind/replace methods on the base Task class - # - # The methods Task.exec_command and Task.sig_implicit_deps already exists and are rarely overridden - # we thus expect that we are the only ones doing this - try: - setattr(Task.Task, 'nostrace_%s' % func.__name__, getattr(Task.Task, func.__name__)) - except AttributeError: - pass - setattr(Task.Task, func.__name__, func) - return func - -@task_method -def get_strace_file(self): - try: - return self.strace_file - except AttributeError: - pass - - if self.outputs: - ret = self.outputs[0].abspath() + '.strace' - else: - ret = '%s%s%d%s' % (self.generator.bld.bldnode.abspath(), os.sep, id(self), '.strace') - self.strace_file = ret - return ret - -@task_method -def get_strace_args(self): - return (self.env.STRACE or ['strace']) + ['-e', TRACECALLS, '-f', '-o', self.get_strace_file()] - -@task_method -def exec_command(self, cmd, **kw): - bld = self.generator.bld - if not 'cwd' in kw: - kw['cwd'] = self.get_cwd() - - args = self.get_strace_args() - fname = self.get_strace_file() - if isinstance(cmd, list): - cmd = args + cmd - else: - cmd = '%s %s' % (' '.join(args), cmd) - - try: - ret = bld.exec_command(cmd, **kw) - finally: - if not ret: - self.parse_strace_deps(fname, kw['cwd']) - return ret - -@task_method -def sig_implicit_deps(self): - # bypass the scanner functions - return - -@task_method -def parse_strace_deps(self, path, cwd): - # uncomment the following line to disable the dependencies and force a file scan - # return - try: - cnt = Utils.readf(path) - finally: - try: - os.remove(path) - except OSError: - pass - - if not isinstance(cwd, str): - cwd = cwd.abspath() - - nodes = [] - bld = self.generator.bld - try: - cache = bld.strace_cache - except AttributeError: - cache = bld.strace_cache = {} - - # chdir and relative paths - pid_to_cwd = {} - - global BANNED - done = set() - for m in re.finditer(re_lines, cnt): - # scraping the output of strace - pid = m.group('pid') - if m.group('npid'): - npid = m.group('npid') - pid_to_cwd[npid] = pid_to_cwd.get(pid, cwd) - continue - - p = m.group('path').replace('\\"', '"') - - if p == '.' or m.group().find('= -1 ENOENT') > -1: - # just to speed it up a bit - continue - - if not os.path.isabs(p): - p = os.path.join(pid_to_cwd.get(pid, cwd), p) - - call = m.group('call') - if call == 'chdir': - pid_to_cwd[pid] = p - continue - - if p in done: - continue - done.add(p) - - for x in BANNED: - if p.startswith(x): - break - else: - if p.endswith('/') or os.path.isdir(p): - continue - - try: - node = cache[p] - except KeyError: - strace_lock.acquire() - try: - cache[p] = node = bld.root.find_node(p) - if not node: - continue - finally: - strace_lock.release() - nodes.append(node) - - # record the dependencies then force the task signature recalculation for next time - if Logs.verbose: - Logs.debug('deps: real scanner for %r returned %r', self, nodes) - bld = self.generator.bld - bld.node_deps[self.uid()] = nodes - bld.raw_deps[self.uid()] = [] - try: - del self.cache_sig - except AttributeError: - pass - self.signature() - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/swig.py b/ldb-2.0.8/third_party/waf/waflib/extras/swig.py deleted file mode 100644 index 740ab46..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/swig.py +++ /dev/null @@ -1,237 +0,0 @@ -#! /usr/bin/env python -# encoding: UTF-8 -# Petar Forai -# Thomas Nagy 2008-2010 (ita) - -import re -from waflib import Task, Logs -from waflib.TaskGen import extension, feature, after_method -from waflib.Configure import conf -from waflib.Tools import c_preproc - -""" -tasks have to be added dynamically: -- swig interface files may be created at runtime -- the module name may be unknown in advance -""" - -SWIG_EXTS = ['.swig', '.i'] - -re_module = re.compile(r'%module(?:\s*\(.*\))?\s+(.+)', re.M) - -re_1 = re.compile(r'^%module.*?\s+([\w]+)\s*?$', re.M) -re_2 = re.compile(r'[#%](?:include|import(?:\(module=".*"\))+|python(?:begin|code)) [<"](.*)[">]', re.M) - -class swig(Task.Task): - color = 'BLUE' - run_str = '${SWIG} ${SWIGFLAGS} ${SWIGPATH_ST:INCPATHS} ${SWIGDEF_ST:DEFINES} ${SRC}' - ext_out = ['.h'] # might produce .h files although it is not mandatory - vars = ['SWIG_VERSION', 'SWIGDEPS'] - - def runnable_status(self): - for t in self.run_after: - if not t.hasrun: - return Task.ASK_LATER - - if not getattr(self, 'init_outputs', None): - self.init_outputs = True - if not getattr(self, 'module', None): - # search the module name - txt = self.inputs[0].read() - m = re_module.search(txt) - if not m: - raise ValueError("could not find the swig module name") - self.module = m.group(1) - - swig_c(self) - - # add the language-specific output files as nodes - # call funs in the dict swig_langs - for x in self.env['SWIGFLAGS']: - # obtain the language - x = x[1:] - try: - fun = swig_langs[x] - except KeyError: - pass - else: - fun(self) - - return super(swig, self).runnable_status() - - def scan(self): - "scan for swig dependencies, climb the .i files" - lst_src = [] - - seen = [] - missing = [] - to_see = [self.inputs[0]] - - while to_see: - node = to_see.pop(0) - if node in seen: - continue - seen.append(node) - lst_src.append(node) - - # read the file - code = node.read() - code = c_preproc.re_nl.sub('', code) - code = c_preproc.re_cpp.sub(c_preproc.repl, code) - - # find .i files and project headers - names = re_2.findall(code) - for n in names: - for d in self.generator.includes_nodes + [node.parent]: - u = d.find_resource(n) - if u: - to_see.append(u) - break - else: - missing.append(n) - return (lst_src, missing) - -# provide additional language processing -swig_langs = {} -def swigf(fun): - swig_langs[fun.__name__.replace('swig_', '')] = fun - return fun -swig.swigf = swigf - -def swig_c(self): - ext = '.swigwrap_%d.c' % self.generator.idx - flags = self.env['SWIGFLAGS'] - if '-c++' in flags: - ext += 'xx' - out_node = self.inputs[0].parent.find_or_declare(self.module + ext) - - if '-c++' in flags: - c_tsk = self.generator.cxx_hook(out_node) - else: - c_tsk = self.generator.c_hook(out_node) - - c_tsk.set_run_after(self) - - # transfer weights from swig task to c task - if getattr(self, 'weight', None): - c_tsk.weight = self.weight - if getattr(self, 'tree_weight', None): - c_tsk.tree_weight = self.tree_weight - - try: - self.more_tasks.append(c_tsk) - except AttributeError: - self.more_tasks = [c_tsk] - - try: - ltask = self.generator.link_task - except AttributeError: - pass - else: - ltask.set_run_after(c_tsk) - # setting input nodes does not declare the build order - # because the build already started, but it sets - # the dependency to enable rebuilds - ltask.inputs.append(c_tsk.outputs[0]) - - self.outputs.append(out_node) - - if not '-o' in self.env['SWIGFLAGS']: - self.env.append_value('SWIGFLAGS', ['-o', self.outputs[0].abspath()]) - -@swigf -def swig_python(tsk): - node = tsk.inputs[0].parent - if tsk.outdir: - node = tsk.outdir - tsk.set_outputs(node.find_or_declare(tsk.module+'.py')) - -@swigf -def swig_ocaml(tsk): - node = tsk.inputs[0].parent - if tsk.outdir: - node = tsk.outdir - tsk.set_outputs(node.find_or_declare(tsk.module+'.ml')) - tsk.set_outputs(node.find_or_declare(tsk.module+'.mli')) - -@extension(*SWIG_EXTS) -def i_file(self, node): - # the task instance - tsk = self.create_task('swig') - tsk.set_inputs(node) - tsk.module = getattr(self, 'swig_module', None) - - flags = self.to_list(getattr(self, 'swig_flags', [])) - tsk.env.append_value('SWIGFLAGS', flags) - - tsk.outdir = None - if '-outdir' in flags: - outdir = flags[flags.index('-outdir')+1] - outdir = tsk.generator.bld.bldnode.make_node(outdir) - outdir.mkdir() - tsk.outdir = outdir - -@feature('c', 'cxx', 'd', 'fc', 'asm') -@after_method('apply_link', 'process_source') -def enforce_swig_before_link(self): - try: - link_task = self.link_task - except AttributeError: - pass - else: - for x in self.tasks: - if x.__class__.__name__ == 'swig': - link_task.run_after.add(x) - -@conf -def check_swig_version(conf, minver=None): - """ - Check if the swig tool is found matching a given minimum version. - minver should be a tuple, eg. to check for swig >= 1.3.28 pass (1,3,28) as minver. - - If successful, SWIG_VERSION is defined as 'MAJOR.MINOR' - (eg. '1.3') of the actual swig version found. - - :param minver: minimum version - :type minver: tuple of int - :return: swig version - :rtype: tuple of int - """ - assert minver is None or isinstance(minver, tuple) - swigbin = conf.env['SWIG'] - if not swigbin: - conf.fatal('could not find the swig executable') - - # Get swig version string - cmd = swigbin + ['-version'] - Logs.debug('swig: Running swig command %r', cmd) - reg_swig = re.compile(r'SWIG Version\s(.*)', re.M) - swig_out = conf.cmd_and_log(cmd) - swigver_tuple = tuple([int(s) for s in reg_swig.findall(swig_out)[0].split('.')]) - - # Compare swig version with the minimum required - result = (minver is None) or (swigver_tuple >= minver) - - if result: - # Define useful environment variables - swigver = '.'.join([str(x) for x in swigver_tuple[:2]]) - conf.env['SWIG_VERSION'] = swigver - - # Feedback - swigver_full = '.'.join(map(str, swigver_tuple[:3])) - if minver is None: - conf.msg('Checking for swig version', swigver_full) - else: - minver_str = '.'.join(map(str, minver)) - conf.msg('Checking for swig version >= %s' % (minver_str,), swigver_full, color=result and 'GREEN' or 'YELLOW') - - if not result: - conf.fatal('The swig version is too old, expecting %r' % (minver,)) - - return swigver_tuple - -def configure(conf): - conf.find_program('swig', var='SWIG') - conf.env.SWIGPATH_ST = '-I%s' - conf.env.SWIGDEF_ST = '-D%s' - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/syms.py b/ldb-2.0.8/third_party/waf/waflib/extras/syms.py deleted file mode 100644 index 562f708..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/syms.py +++ /dev/null @@ -1,84 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 - -""" -This tool supports the export_symbols_regex to export the symbols in a shared library. -by default, all symbols are exported by gcc, and nothing by msvc. -to use the tool, do something like: - -def build(ctx): - ctx(features='c cshlib syms', source='a.c b.c', export_symbols_regex='mylib_.*', target='testlib') - -only the symbols starting with 'mylib_' will be exported. -""" - -import re -from waflib.Context import STDOUT -from waflib.Task import Task -from waflib.Errors import WafError -from waflib.TaskGen import feature, after_method - -class gen_sym(Task): - def run(self): - obj = self.inputs[0] - kw = {} - - reg = getattr(self.generator, 'export_symbols_regex', '.+?') - if 'msvc' in (self.env.CC_NAME, self.env.CXX_NAME): - re_nm = re.compile(r'External\s+\|\s+_(?P%s)\b' % reg) - cmd = (self.env.DUMPBIN or ['dumpbin']) + ['/symbols', obj.abspath()] - else: - if self.env.DEST_BINFMT == 'pe': #gcc uses nm, and has a preceding _ on windows - re_nm = re.compile(r'(T|D)\s+_(?P%s)\b' % reg) - elif self.env.DEST_BINFMT=='mac-o': - re_nm=re.compile(r'(T|D)\s+(?P_?(%s))\b' % reg) - else: - re_nm = re.compile(r'(T|D)\s+(?P%s)\b' % reg) - cmd = (self.env.NM or ['nm']) + ['-g', obj.abspath()] - syms = [m.group('symbol') for m in re_nm.finditer(self.generator.bld.cmd_and_log(cmd, quiet=STDOUT, **kw))] - self.outputs[0].write('%r' % syms) - -class compile_sym(Task): - def run(self): - syms = {} - for x in self.inputs: - slist = eval(x.read()) - for s in slist: - syms[s] = 1 - lsyms = list(syms.keys()) - lsyms.sort() - if self.env.DEST_BINFMT == 'pe': - self.outputs[0].write('EXPORTS\n' + '\n'.join(lsyms)) - elif self.env.DEST_BINFMT == 'elf': - self.outputs[0].write('{ global:\n' + ';\n'.join(lsyms) + ";\nlocal: *; };\n") - elif self.env.DEST_BINFMT=='mac-o': - self.outputs[0].write('\n'.join(lsyms) + '\n') - else: - raise WafError('NotImplemented') - -@feature('syms') -@after_method('process_source', 'process_use', 'apply_link', 'process_uselib_local', 'propagate_uselib_vars') -def do_the_symbol_stuff(self): - def_node = self.path.find_or_declare(getattr(self, 'sym_file', self.target + '.def')) - compiled_tasks = getattr(self, 'compiled_tasks', None) - if compiled_tasks: - ins = [x.outputs[0] for x in compiled_tasks] - self.gen_sym_tasks = [self.create_task('gen_sym', x, x.change_ext('.%d.sym' % self.idx)) for x in ins] - self.create_task('compile_sym', [x.outputs[0] for x in self.gen_sym_tasks], def_node) - - link_task = getattr(self, 'link_task', None) - if link_task: - self.link_task.dep_nodes.append(def_node) - - if 'msvc' in (self.env.CC_NAME, self.env.CXX_NAME): - self.link_task.env.append_value('LINKFLAGS', ['/def:' + def_node.bldpath()]) - elif self.env.DEST_BINFMT == 'pe': - # gcc on windows takes *.def as an additional input - self.link_task.inputs.append(def_node) - elif self.env.DEST_BINFMT == 'elf': - self.link_task.env.append_value('LINKFLAGS', ['-Wl,-version-script', '-Wl,' + def_node.bldpath()]) - elif self.env.DEST_BINFMT=='mac-o': - self.link_task.env.append_value('LINKFLAGS',['-Wl,-exported_symbols_list,' + def_node.bldpath()]) - else: - raise WafError('NotImplemented') - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/ticgt.py b/ldb-2.0.8/third_party/waf/waflib/extras/ticgt.py deleted file mode 100644 index f43a7ea..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/ticgt.py +++ /dev/null @@ -1,300 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 - -# Texas Instruments code generator support (experimental) -# When reporting issues, please directly assign the bug to the maintainer. - -__author__ = __maintainer__ = "Jérôme Carretero " -__copyright__ = "Jérôme Carretero, 2012" - -""" -TI cgt6x is a compiler suite for TI DSPs. - -The toolchain does pretty weird things, and I'm sure I'm missing some of them. -But still, the tool saves time. - -What this tool does is: - -- create a TI compiler environment -- create TI compiler features, to handle some specifics about this compiler - It has a few idiosyncracies, such as not giving the liberty of the .o file names -- automatically activate them when using the TI compiler -- handle the tconf tool - The tool - -TODO: - -- the set_platform_flags() function is not nice -- more tests -- broaden tool scope, if needed - -""" - -import os, re - -from waflib import Options, Utils, Task, TaskGen -from waflib.Tools import c, ccroot, c_preproc -from waflib.Configure import conf -from waflib.TaskGen import feature, before_method -from waflib.Tools.c import cprogram - -opj = os.path.join - -@conf -def find_ticc(conf): - conf.find_program(['cl6x'], var='CC', path_list=opj(getattr(Options.options, 'ti-cgt-dir', ""), 'bin')) - conf.env.CC_NAME = 'ticc' - -@conf -def find_tild(conf): - conf.find_program(['lnk6x'], var='LINK_CC', path_list=opj(getattr(Options.options, 'ti-cgt-dir', ""), 'bin')) - conf.env.LINK_CC_NAME = 'tild' - -@conf -def find_tiar(conf): - conf.find_program(['ar6x'], var='AR', path_list=opj(getattr(Options.options, 'ti-cgt-dir', ""), 'bin')) - conf.env.AR_NAME = 'tiar' - conf.env.ARFLAGS = 'qru' - -@conf -def ticc_common_flags(conf): - v = conf.env - - if not v['LINK_CC']: - v['LINK_CC'] = v['CC'] - v['CCLNK_SRC_F'] = [] - v['CCLNK_TGT_F'] = ['-o'] - v['CPPPATH_ST'] = '-I%s' - v['DEFINES_ST'] = '-d%s' - - v['LIB_ST'] = '-l%s' # template for adding libs - v['LIBPATH_ST'] = '-i%s' # template for adding libpaths - v['STLIB_ST'] = '-l=%s.lib' - v['STLIBPATH_ST'] = '-i%s' - - # program - v['cprogram_PATTERN'] = '%s.out' - - # static lib - #v['LINKFLAGS_cstlib'] = ['-Wl,-Bstatic'] - v['cstlib_PATTERN'] = '%s.lib' - -def configure(conf): - v = conf.env - v.TI_CGT_DIR = getattr(Options.options, 'ti-cgt-dir', "") - v.TI_DSPLINK_DIR = getattr(Options.options, 'ti-dsplink-dir', "") - v.TI_BIOSUTILS_DIR = getattr(Options.options, 'ti-biosutils-dir', "") - v.TI_DSPBIOS_DIR = getattr(Options.options, 'ti-dspbios-dir', "") - v.TI_XDCTOOLS_DIR = getattr(Options.options, 'ti-xdctools-dir', "") - conf.find_ticc() - conf.find_tiar() - conf.find_tild() - conf.ticc_common_flags() - conf.cc_load_tools() - conf.cc_add_flags() - conf.link_add_flags() - conf.find_program(['tconf'], var='TCONF', path_list=v.TI_XDCTOOLS_DIR) - - conf.env.TCONF_INCLUDES += [ - opj(conf.env.TI_DSPBIOS_DIR, 'packages'), - ] - - conf.env.INCLUDES += [ - opj(conf.env.TI_CGT_DIR, 'include'), - ] - - conf.env.LIBPATH += [ - opj(conf.env.TI_CGT_DIR, "lib"), - ] - - conf.env.INCLUDES_DSPBIOS += [ - opj(conf.env.TI_DSPBIOS_DIR, 'packages', 'ti', 'bios', 'include'), - ] - - conf.env.LIBPATH_DSPBIOS += [ - opj(conf.env.TI_DSPBIOS_DIR, 'packages', 'ti', 'bios', 'lib'), - ] - - conf.env.INCLUDES_DSPLINK += [ - opj(conf.env.TI_DSPLINK_DIR, 'dsplink', 'dsp', 'inc'), - ] - -@conf -def ti_set_debug(cfg, debug=1): - """ - Sets debug flags for the compiler. - - TODO: - - for each TI CFLAG/INCLUDES/LINKFLAGS/LIBPATH replace RELEASE by DEBUG - - -g --no_compress - """ - if debug: - cfg.env.CFLAGS += "-d_DEBUG -dDEBUG -dDDSP_DEBUG".split() - -@conf -def ti_dsplink_set_platform_flags(cfg, splat, dsp, dspbios_ver, board): - """ - Sets the INCLUDES, LINKFLAGS for DSPLINK and TCONF_INCLUDES - For the specific hardware. - - Assumes that DSPLINK was built in its own folder. - - :param splat: short platform name (eg. OMAPL138) - :param dsp: DSP name (eg. 674X) - :param dspbios_ver: string identifying DspBios version (eg. 5.XX) - :param board: board name (eg. OMAPL138GEM) - - """ - d1 = opj(cfg.env.TI_DSPLINK_DIR, 'dsplink', 'dsp', 'inc', 'DspBios', dspbios_ver) - d = opj(cfg.env.TI_DSPLINK_DIR, 'dsplink', 'dsp', 'inc', 'DspBios', dspbios_ver, board) - cfg.env.TCONF_INCLUDES += [d1, d] - cfg.env.INCLUDES_DSPLINK += [ - opj(cfg.env.TI_DSPLINK_DIR, 'dsplink', 'dsp', 'inc', dsp), - d, - ] - - cfg.env.LINKFLAGS_DSPLINK += [ - opj(cfg.env.TI_DSPLINK_DIR, 'dsplink', 'dsp', 'export', 'BIN', 'DspBios', splat, board+'_0', 'RELEASE', 'dsplink%s.lib' % x) - for x in ('', 'pool', 'mpcs', 'mplist', 'msg', 'data', 'notify', 'ringio') - ] - - -def options(opt): - opt.add_option('--with-ti-cgt', type='string', dest='ti-cgt-dir', help = 'Specify alternate cgt root folder', default="") - opt.add_option('--with-ti-biosutils', type='string', dest='ti-biosutils-dir', help = 'Specify alternate biosutils folder', default="") - opt.add_option('--with-ti-dspbios', type='string', dest='ti-dspbios-dir', help = 'Specify alternate dspbios folder', default="") - opt.add_option('--with-ti-dsplink', type='string', dest='ti-dsplink-dir', help = 'Specify alternate dsplink folder', default="") - opt.add_option('--with-ti-xdctools', type='string', dest='ti-xdctools-dir', help = 'Specify alternate xdctools folder', default="") - -class ti_cprogram(cprogram): - """ - Link object files into a c program - - Changes: - - - the linked executable to have a relative path (because we can) - - put the LIBPATH first - """ - run_str = '${LINK_CC} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LINKFLAGS} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].bldpath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ' - -@feature("c") -@before_method('apply_link') -def use_ti_cprogram(self): - """ - Automatically uses ti_cprogram link process - """ - if 'cprogram' in self.features and self.env.CC_NAME == 'ticc': - self.features.insert(0, "ti_cprogram") - -class ti_c(Task.Task): - """ - Compile task for the TI codegen compiler - - This compiler does not allow specifying the output file name, only the output path. - - """ - "Compile C files into object files" - run_str = '${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${SRC} -c ${OUT} ${CPPFLAGS}' - vars = ['CCDEPS'] # unused variable to depend on, just in case - ext_in = ['.h'] # set the build order easily by using ext_out=['.h'] - scan = c_preproc.scan - -def create_compiled_task(self, name, node): - """ - Overrides ccroot.create_compiled_task to support ti_c - """ - out = '%s' % (node.change_ext('.obj').name) - if self.env.CC_NAME == 'ticc': - name = 'ti_c' - task = self.create_task(name, node, node.parent.find_or_declare(out)) - self.env.OUT = '-fr%s' % (node.parent.get_bld().abspath()) - try: - self.compiled_tasks.append(task) - except AttributeError: - self.compiled_tasks = [task] - return task - -@TaskGen.extension('.c') -def c_hook(self, node): - "Bind the c file extension to the creation of a :py:class:`waflib.Tools.c.c` instance" - if self.env.CC_NAME == 'ticc': - return create_compiled_task(self, 'ti_c', node) - else: - return self.create_compiled_task('c', node) - - -@feature("ti-tconf") -@before_method('process_source') -def apply_tconf(self): - sources = [x.get_src() for x in self.to_nodes(self.source, path=self.path.get_src())] - node = sources[0] - assert(sources[0].name.endswith(".tcf")) - if len(sources) > 1: - assert(sources[1].name.endswith(".cmd")) - - target = getattr(self, 'target', self.source) - target_node = node.get_bld().parent.find_or_declare(node.name) - - procid = "%d" % int(getattr(self, 'procid', 0)) - - importpaths = [] - includes = Utils.to_list(getattr(self, 'includes', [])) - for x in includes + self.env.TCONF_INCLUDES: - if x == os.path.abspath(x): - importpaths.append(x) - else: - relpath = self.path.find_node(x).path_from(target_node.parent) - importpaths.append(relpath) - - task = self.create_task('ti_tconf', sources, target_node.change_ext('.cdb')) - task.path = self.path - task.includes = includes - task.cwd = target_node.parent.abspath() - task.env = self.env.derive() - task.env["TCONFSRC"] = node.path_from(target_node.parent) - task.env["TCONFINC"] = '-Dconfig.importPath=%s' % ";".join(importpaths) - task.env['TCONFPROGNAME'] = '-Dconfig.programName=%s' % target - task.env['PROCID'] = procid - task.outputs = [ - target_node.change_ext("cfg_c.c"), - target_node.change_ext("cfg.s62"), - target_node.change_ext("cfg.cmd"), - ] - - create_compiled_task(self, 'ti_c', task.outputs[1]) - ctask = create_compiled_task(self, 'ti_c', task.outputs[0]) - ctask.env = self.env.derive() - - self.add_those_o_files(target_node.change_ext("cfg.cmd")) - if len(sources) > 1: - self.add_those_o_files(sources[1]) - self.source = [] - -re_tconf_include = re.compile(r'(?Putils\.importFile)\("(?P.*)"\)',re.M) -class ti_tconf(Task.Task): - run_str = '${TCONF} ${TCONFINC} ${TCONFPROGNAME} ${TCONFSRC} ${PROCID}' - color = 'PINK' - - def scan(self): - includes = Utils.to_list(getattr(self, 'includes', [])) - - def deps(node): - nodes, names = [], [] - if node: - code = Utils.readf(node.abspath()) - for match in re_tconf_include.finditer(code): - path = match.group('file') - if path: - for x in includes: - filename = opj(x, path) - fi = self.path.find_resource(filename) - if fi: - subnodes, subnames = deps(fi) - nodes += subnodes - names += subnames - nodes.append(fi) - names.append(path) - break - return nodes, names - return deps(self.inputs[0]) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/unity.py b/ldb-2.0.8/third_party/waf/waflib/extras/unity.py deleted file mode 100644 index 78128ed..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/unity.py +++ /dev/null @@ -1,108 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 - -""" -Compile whole groups of C/C++ files at once -(C and C++ files are processed independently though). - -To enable globally:: - - def options(opt): - opt.load('compiler_cxx') - def build(bld): - bld.load('compiler_cxx unity') - -To enable for specific task generators only:: - - def build(bld): - bld(features='c cprogram unity', source='main.c', ...) - -The file order is often significant in such builds, so it can be -necessary to adjust the order of source files and the batch sizes. -To control the amount of files processed in a batch per target -(the default is 50):: - - def build(bld): - bld(features='c cprogram', unity_size=20) - -""" - -from waflib import Task, Options -from waflib.Tools import c_preproc -from waflib import TaskGen - -MAX_BATCH = 50 - -EXTS_C = ('.c',) -EXTS_CXX = ('.cpp','.cc','.cxx','.C','.c++') - -def options(opt): - global MAX_BATCH - opt.add_option('--batchsize', action='store', dest='batchsize', type='int', default=MAX_BATCH, - help='default unity batch size (0 disables unity builds)') - -@TaskGen.taskgen_method -def batch_size(self): - default = getattr(Options.options, 'batchsize', MAX_BATCH) - if default < 1: - return 0 - return getattr(self, 'unity_size', default) - - -class unity(Task.Task): - color = 'BLUE' - scan = c_preproc.scan - def to_include(self, node): - ret = node.path_from(self.outputs[0].parent) - ret = ret.replace('\\', '\\\\').replace('"', '\\"') - return ret - def run(self): - lst = ['#include "%s"\n' % self.to_include(node) for node in self.inputs] - txt = ''.join(lst) - self.outputs[0].write(txt) - def __str__(self): - node = self.outputs[0] - return node.path_from(node.ctx.launch_node()) - -def bind_unity(obj, cls_name, exts): - if not 'mappings' in obj.__dict__: - obj.mappings = dict(obj.mappings) - - for j in exts: - fun = obj.mappings[j] - if fun.__name__ == 'unity_fun': - raise ValueError('Attempt to bind unity mappings multiple times %r' % j) - - def unity_fun(self, node): - cnt = self.batch_size() - if cnt <= 1: - return fun(self, node) - x = getattr(self, 'master_%s' % cls_name, None) - if not x or len(x.inputs) >= cnt: - x = self.create_task('unity') - setattr(self, 'master_%s' % cls_name, x) - - cnt_cur = getattr(self, 'cnt_%s' % cls_name, 0) - c_node = node.parent.find_or_declare('unity_%s_%d_%d.%s' % (self.idx, cnt_cur, cnt, cls_name)) - x.outputs = [c_node] - setattr(self, 'cnt_%s' % cls_name, cnt_cur + 1) - fun(self, c_node) - x.inputs.append(node) - - obj.mappings[j] = unity_fun - -@TaskGen.feature('unity') -@TaskGen.before('process_source') -def single_unity(self): - lst = self.to_list(self.features) - if 'c' in lst: - bind_unity(self, 'c', EXTS_C) - if 'cxx' in lst: - bind_unity(self, 'cxx', EXTS_CXX) - -def build(bld): - if bld.env.CC_NAME: - bind_unity(TaskGen.task_gen, 'c', EXTS_C) - if bld.env.CXX_NAME: - bind_unity(TaskGen.task_gen, 'cxx', EXTS_CXX) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/use_config.py b/ldb-2.0.8/third_party/waf/waflib/extras/use_config.py deleted file mode 100644 index ef5129f..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/use_config.py +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env python -# coding=utf-8 -# Mathieu Courtois - EDF R&D, 2013 - http://www.code-aster.org - -""" -When a project has a lot of options the 'waf configure' command line can be -very long and it becomes a cause of error. -This tool provides a convenient way to load a set of configuration parameters -from a local file or from a remote url. - -The configuration parameters are stored in a Python file that is imported as -an extra waf tool can be. - -Example: -$ waf configure --use-config-dir=http://www.anywhere.org --use-config=myconf1 ... - -The file 'myconf1' will be downloaded from 'http://www.anywhere.org' -(or 'http://www.anywhere.org/wafcfg'). -If the files are available locally, it could be: -$ waf configure --use-config-dir=/somewhere/myconfigurations --use-config=myconf1 ... - -The configuration of 'myconf1.py' is automatically loaded by calling -its 'configure' function. In this example, it defines environment variables and -set options: - -def configure(self): - self.env['CC'] = 'gcc-4.8' - self.env.append_value('LIBPATH', [...]) - self.options.perlbinary = '/usr/local/bin/perl' - self.options.pyc = False - -The corresponding command line should have been: -$ CC=gcc-4.8 LIBPATH=... waf configure --nopyc --with-perl-binary=/usr/local/bin/perl - - -This is an extra tool, not bundled with the default waf binary. -To add the use_config tool to the waf file: -$ ./waf-light --tools=use_config - -When using this tool, the wscript will look like: - - def options(opt): - opt.load('use_config') - - def configure(conf): - conf.load('use_config') -""" - -import sys -import os.path as osp -import os - -local_repo = '' -"""Local repository containing additional Waf tools (plugins)""" -remote_repo = 'https://gitlab.com/ita1024/waf/raw/master/' -""" -Remote directory containing downloadable waf tools. The missing tools can be downloaded by using:: - - $ waf configure --download -""" - -remote_locs = ['waflib/extras', 'waflib/Tools'] -""" -Remote directories for use with :py:const:`waflib.extras.use_config.remote_repo` -""" - - -try: - from urllib import request -except ImportError: - from urllib import urlopen -else: - urlopen = request.urlopen - - -from waflib import Errors, Context, Logs, Utils, Options, Configure - -try: - from urllib.parse import urlparse -except ImportError: - from urlparse import urlparse - - - - -DEFAULT_DIR = 'wafcfg' -# add first the current wafcfg subdirectory -sys.path.append(osp.abspath(DEFAULT_DIR)) - -def options(self): - group = self.add_option_group('configure options') - group.add_option('--download', dest='download', default=False, action='store_true', help='try to download the tools if missing') - - group.add_option('--use-config', action='store', default=None, - metavar='CFG', dest='use_config', - help='force the configuration parameters by importing ' - 'CFG.py. Several modules may be provided (comma ' - 'separated).') - group.add_option('--use-config-dir', action='store', default=DEFAULT_DIR, - metavar='CFG_DIR', dest='use_config_dir', - help='path or url where to find the configuration file') - -def download_check(node): - """ - Hook to check for the tools which are downloaded. Replace with your function if necessary. - """ - pass - - -def download_tool(tool, force=False, ctx=None): - """ - Download a Waf tool from the remote repository defined in :py:const:`waflib.extras.use_config.remote_repo`:: - - $ waf configure --download - """ - for x in Utils.to_list(remote_repo): - for sub in Utils.to_list(remote_locs): - url = '/'.join((x, sub, tool + '.py')) - try: - web = urlopen(url) - try: - if web.getcode() != 200: - continue - except AttributeError: - pass - except Exception: - # on python3 urlopen throws an exception - # python 2.3 does not have getcode and throws an exception to fail - continue - else: - tmp = ctx.root.make_node(os.sep.join((Context.waf_dir, 'waflib', 'extras', tool + '.py'))) - tmp.write(web.read(), 'wb') - Logs.warn('Downloaded %s from %s', tool, url) - download_check(tmp) - try: - module = Context.load_tool(tool) - except Exception: - Logs.warn('The tool %s from %s is unusable', tool, url) - try: - tmp.delete() - except Exception: - pass - continue - return module - - raise Errors.WafError('Could not load the Waf tool') - -def load_tool(tool, tooldir=None, ctx=None, with_sys_path=True): - try: - module = Context.load_tool_default(tool, tooldir, ctx, with_sys_path) - except ImportError as e: - if not ctx or not hasattr(Options.options, 'download'): - Logs.error('Could not load %r during options phase (download unavailable at this point)' % tool) - raise - if Options.options.download: - module = download_tool(tool, ctx=ctx) - if not module: - ctx.fatal('Could not load the Waf tool %r or download a suitable replacement from the repository (sys.path %r)\n%s' % (tool, sys.path, e)) - else: - ctx.fatal('Could not load the Waf tool %r from %r (try the --download option?):\n%s' % (tool, sys.path, e)) - return module - -Context.load_tool_default = Context.load_tool -Context.load_tool = load_tool -Configure.download_tool = download_tool - -def configure(self): - opts = self.options - use_cfg = opts.use_config - if use_cfg is None: - return - url = urlparse(opts.use_config_dir) - kwargs = {} - if url.scheme: - kwargs['download'] = True - kwargs['remote_url'] = url.geturl() - # search first with the exact url, else try with +'/wafcfg' - kwargs['remote_locs'] = ['', DEFAULT_DIR] - tooldir = url.geturl() + ' ' + DEFAULT_DIR - for cfg in use_cfg.split(','): - Logs.pprint('NORMAL', "Searching configuration '%s'..." % cfg) - self.load(cfg, tooldir=tooldir, **kwargs) - self.start_msg('Checking for configuration') - self.end_msg(use_cfg) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/valadoc.py b/ldb-2.0.8/third_party/waf/waflib/extras/valadoc.py deleted file mode 100644 index c50f69e..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/valadoc.py +++ /dev/null @@ -1,140 +0,0 @@ -#! /usr/bin/env python -# encoding: UTF-8 -# Nicolas Joseph 2009 - -""" -ported from waf 1.5: -TODO: tabs vs spaces -""" - -from waflib import Task, Utils, Errors, Logs -from waflib.TaskGen import feature - -VALADOC_STR = '${VALADOC}' - -class valadoc(Task.Task): - vars = ['VALADOC', 'VALADOCFLAGS'] - color = 'BLUE' - after = ['cprogram', 'cstlib', 'cshlib', 'cxxprogram', 'cxxstlib', 'cxxshlib'] - quiet = True # no outputs .. this is weird - - def __init__(self, *k, **kw): - Task.Task.__init__(self, *k, **kw) - self.output_dir = '' - self.doclet = '' - self.package_name = '' - self.package_version = '' - self.files = [] - self.vapi_dirs = [] - self.protected = True - self.private = False - self.inherit = False - self.deps = False - self.vala_defines = [] - self.vala_target_glib = None - self.enable_non_null_experimental = False - self.force = False - - def run(self): - if not self.env['VALADOCFLAGS']: - self.env['VALADOCFLAGS'] = '' - cmd = [Utils.subst_vars(VALADOC_STR, self.env)] - cmd.append ('-o %s' % self.output_dir) - if getattr(self, 'doclet', None): - cmd.append ('--doclet %s' % self.doclet) - cmd.append ('--package-name %s' % self.package_name) - if getattr(self, 'package_version', None): - cmd.append ('--package-version %s' % self.package_version) - if getattr(self, 'packages', None): - for package in self.packages: - cmd.append ('--pkg %s' % package) - if getattr(self, 'vapi_dirs', None): - for vapi_dir in self.vapi_dirs: - cmd.append ('--vapidir %s' % vapi_dir) - if not getattr(self, 'protected', None): - cmd.append ('--no-protected') - if getattr(self, 'private', None): - cmd.append ('--private') - if getattr(self, 'inherit', None): - cmd.append ('--inherit') - if getattr(self, 'deps', None): - cmd.append ('--deps') - if getattr(self, 'vala_defines', None): - for define in self.vala_defines: - cmd.append ('--define %s' % define) - if getattr(self, 'vala_target_glib', None): - cmd.append ('--target-glib=%s' % self.vala_target_glib) - if getattr(self, 'enable_non_null_experimental', None): - cmd.append ('--enable-non-null-experimental') - if getattr(self, 'force', None): - cmd.append ('--force') - cmd.append (' '.join ([x.abspath() for x in self.files])) - return self.generator.bld.exec_command(' '.join(cmd)) - -@feature('valadoc') -def process_valadoc(self): - """ - Generate API documentation from Vala source code with valadoc - - doc = bld( - features = 'valadoc', - output_dir = '../doc/html', - package_name = 'vala-gtk-example', - package_version = '1.0.0', - packages = 'gtk+-2.0', - vapi_dirs = '../vapi', - force = True - ) - - path = bld.path.find_dir ('../src') - doc.files = path.ant_glob (incl='**/*.vala') - """ - - task = self.create_task('valadoc') - if getattr(self, 'output_dir', None): - task.output_dir = self.path.find_or_declare(self.output_dir).abspath() - else: - Errors.WafError('no output directory') - if getattr(self, 'doclet', None): - task.doclet = self.doclet - else: - Errors.WafError('no doclet directory') - if getattr(self, 'package_name', None): - task.package_name = self.package_name - else: - Errors.WafError('no package name') - if getattr(self, 'package_version', None): - task.package_version = self.package_version - if getattr(self, 'packages', None): - task.packages = Utils.to_list(self.packages) - if getattr(self, 'vapi_dirs', None): - vapi_dirs = Utils.to_list(self.vapi_dirs) - for vapi_dir in vapi_dirs: - try: - task.vapi_dirs.append(self.path.find_dir(vapi_dir).abspath()) - except AttributeError: - Logs.warn('Unable to locate Vala API directory: %r', vapi_dir) - if getattr(self, 'files', None): - task.files = self.files - else: - Errors.WafError('no input file') - if getattr(self, 'protected', None): - task.protected = self.protected - if getattr(self, 'private', None): - task.private = self.private - if getattr(self, 'inherit', None): - task.inherit = self.inherit - if getattr(self, 'deps', None): - task.deps = self.deps - if getattr(self, 'vala_defines', None): - task.vala_defines = Utils.to_list(self.vala_defines) - if getattr(self, 'vala_target_glib', None): - task.vala_target_glib = self.vala_target_glib - if getattr(self, 'enable_non_null_experimental', None): - task.enable_non_null_experimental = self.enable_non_null_experimental - if getattr(self, 'force', None): - task.force = self.force - -def configure(conf): - conf.find_program('valadoc', errmsg='You must install valadoc for generate the API documentation') - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/waf_xattr.py b/ldb-2.0.8/third_party/waf/waflib/extras/waf_xattr.py deleted file mode 100644 index 351dd63..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/waf_xattr.py +++ /dev/null @@ -1,150 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 - -""" -Use extended attributes instead of database files - -1. Input files will be made writable -2. This is only for systems providing extended filesystem attributes -3. By default, hashes are calculated only if timestamp/size change (HASH_CACHE below) -4. The module enables "deep_inputs" on all tasks by propagating task signatures -5. This module also skips task signature comparisons for task code changes due to point 4. -6. This module is for Python3/Linux only, but it could be extended to Python2/other systems - using the xattr library -7. For projects in which tasks always declare output files, it should be possible to - store the rest of build context attributes on output files (imp_sigs, raw_deps and node_deps) - but this is not done here - -On a simple C++ project benchmark, the variations before and after adding waf_xattr.py were observed: -total build time: 20s -> 22s -no-op build time: 2.4s -> 1.8s -pickle file size: 2.9MB -> 2.6MB -""" - -import os -from waflib import Logs, Node, Task, Utils, Errors -from waflib.Task import SKIP_ME, RUN_ME, CANCEL_ME, ASK_LATER, SKIPPED, MISSING - -HASH_CACHE = True -SIG_VAR = 'user.waf.sig' -SEP = ','.encode() -TEMPLATE = '%b%d,%d'.encode() - -try: - PermissionError -except NameError: - PermissionError = IOError - -def getxattr(self): - return os.getxattr(self.abspath(), SIG_VAR) - -def setxattr(self, val): - os.setxattr(self.abspath(), SIG_VAR, val) - -def h_file(self): - try: - ret = getxattr(self) - except OSError: - if HASH_CACHE: - st = os.stat(self.abspath()) - mtime = st.st_mtime - size = st.st_size - else: - if len(ret) == 16: - # for build directory files - return ret - - if HASH_CACHE: - # check if timestamp and mtime match to avoid re-hashing - st = os.stat(self.abspath()) - mtime, size = ret[16:].split(SEP) - if int(1000 * st.st_mtime) == int(mtime) and st.st_size == int(size): - return ret[:16] - - ret = Utils.h_file(self.abspath()) - if HASH_CACHE: - val = TEMPLATE % (ret, int(1000 * st.st_mtime), int(st.st_size)) - try: - setxattr(self, val) - except PermissionError: - os.chmod(self.abspath(), st.st_mode | 128) - setxattr(self, val) - return ret - -def runnable_status(self): - bld = self.generator.bld - if bld.is_install < 0: - return SKIP_ME - - for t in self.run_after: - if not t.hasrun: - return ASK_LATER - elif t.hasrun < SKIPPED: - # a dependency has an error - return CANCEL_ME - - # first compute the signature - try: - new_sig = self.signature() - except Errors.TaskNotReady: - return ASK_LATER - - if not self.outputs: - # compare the signature to a signature computed previously - # this part is only for tasks with no output files - key = self.uid() - try: - prev_sig = bld.task_sigs[key] - except KeyError: - Logs.debug('task: task %r must run: it was never run before or the task code changed', self) - return RUN_ME - if new_sig != prev_sig: - Logs.debug('task: task %r must run: the task signature changed', self) - return RUN_ME - - # compare the signatures of the outputs to make a decision - for node in self.outputs: - try: - sig = node.h_file() - except EnvironmentError: - Logs.debug('task: task %r must run: an output node does not exist', self) - return RUN_ME - if sig != new_sig: - Logs.debug('task: task %r must run: an output node is stale', self) - return RUN_ME - - return (self.always_run and RUN_ME) or SKIP_ME - -def post_run(self): - bld = self.generator.bld - sig = self.signature() - for node in self.outputs: - if not node.exists(): - self.hasrun = MISSING - self.err_msg = '-> missing file: %r' % node.abspath() - raise Errors.WafError(self.err_msg) - os.setxattr(node.abspath(), 'user.waf.sig', sig) - if not self.outputs: - # only for task with no outputs - bld.task_sigs[self.uid()] = sig - if not self.keep_last_cmd: - try: - del self.last_cmd - except AttributeError: - pass - -try: - os.getxattr -except AttributeError: - pass -else: - h_file.__doc__ = Node.Node.h_file.__doc__ - - # keep file hashes as file attributes - Node.Node.h_file = h_file - - # enable "deep_inputs" on all tasks - Task.Task.runnable_status = runnable_status - Task.Task.post_run = post_run - Task.Task.sig_deep_inputs = Utils.nada - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/why.py b/ldb-2.0.8/third_party/waf/waflib/extras/why.py deleted file mode 100644 index 1bb941f..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/why.py +++ /dev/null @@ -1,78 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2010 (ita) - -""" -This tool modifies the task signature scheme to store and obtain -information about the task execution (why it must run, etc):: - - def configure(conf): - conf.load('why') - -After adding the tool, a full rebuild is necessary: -waf clean build --zones=task -""" - -from waflib import Task, Utils, Logs, Errors - -def signature(self): - # compute the result one time, and suppose the scan_signature will give the good result - try: - return self.cache_sig - except AttributeError: - pass - - self.m = Utils.md5() - self.m.update(self.hcode) - id_sig = self.m.digest() - - # explicit deps - self.m = Utils.md5() - self.sig_explicit_deps() - exp_sig = self.m.digest() - - # env vars - self.m = Utils.md5() - self.sig_vars() - var_sig = self.m.digest() - - # implicit deps / scanner results - self.m = Utils.md5() - if self.scan: - try: - self.sig_implicit_deps() - except Errors.TaskRescan: - return self.signature() - impl_sig = self.m.digest() - - ret = self.cache_sig = impl_sig + id_sig + exp_sig + var_sig - return ret - - -Task.Task.signature = signature - -old = Task.Task.runnable_status -def runnable_status(self): - ret = old(self) - if ret == Task.RUN_ME: - try: - old_sigs = self.generator.bld.task_sigs[self.uid()] - except (KeyError, AttributeError): - Logs.debug("task: task must run as no previous signature exists") - else: - new_sigs = self.cache_sig - def v(x): - return Utils.to_hex(x) - - Logs.debug('Task %r', self) - msgs = ['* Implicit or scanner dependency', '* Task code', '* Source file, explicit or manual dependency', '* Configuration data variable'] - tmp = 'task: -> %s: %s %s' - for x in range(len(msgs)): - l = len(Utils.SIG_NIL) - a = new_sigs[x*l : (x+1)*l] - b = old_sigs[x*l : (x+1)*l] - if (a != b): - Logs.debug(tmp, msgs[x].ljust(35), v(a), v(b)) - return ret -Task.Task.runnable_status = runnable_status - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/win32_opts.py b/ldb-2.0.8/third_party/waf/waflib/extras/win32_opts.py deleted file mode 100644 index 9f7443c..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/win32_opts.py +++ /dev/null @@ -1,170 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 - -""" -Windows-specific optimizations - -This module can help reducing the overhead of listing files on windows -(more than 10000 files). Python 3.5 already provides the listdir -optimization though. -""" - -import os -from waflib import Utils, Build, Node, Logs - -try: - TP = '%s\\*'.decode('ascii') -except AttributeError: - TP = '%s\\*' - -if Utils.is_win32: - from waflib.Tools import md5_tstamp - import ctypes, ctypes.wintypes - - FindFirstFile = ctypes.windll.kernel32.FindFirstFileW - FindNextFile = ctypes.windll.kernel32.FindNextFileW - FindClose = ctypes.windll.kernel32.FindClose - FILE_ATTRIBUTE_DIRECTORY = 0x10 - INVALID_HANDLE_VALUE = -1 - UPPER_FOLDERS = ('.', '..') - try: - UPPER_FOLDERS = [unicode(x) for x in UPPER_FOLDERS] - except NameError: - pass - - def cached_hash_file(self): - try: - cache = self.ctx.cache_listdir_cache_hash_file - except AttributeError: - cache = self.ctx.cache_listdir_cache_hash_file = {} - - if id(self.parent) in cache: - try: - t = cache[id(self.parent)][self.name] - except KeyError: - raise IOError('Not a file') - else: - # an opportunity to list the files and the timestamps at once - findData = ctypes.wintypes.WIN32_FIND_DATAW() - find = FindFirstFile(TP % self.parent.abspath(), ctypes.byref(findData)) - - if find == INVALID_HANDLE_VALUE: - cache[id(self.parent)] = {} - raise IOError('Not a file') - - cache[id(self.parent)] = lst_files = {} - try: - while True: - if findData.cFileName not in UPPER_FOLDERS: - thatsadir = findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY - if not thatsadir: - ts = findData.ftLastWriteTime - d = (ts.dwLowDateTime << 32) | ts.dwHighDateTime - lst_files[str(findData.cFileName)] = d - if not FindNextFile(find, ctypes.byref(findData)): - break - except Exception: - cache[id(self.parent)] = {} - raise IOError('Not a file') - finally: - FindClose(find) - t = lst_files[self.name] - - fname = self.abspath() - if fname in Build.hashes_md5_tstamp: - if Build.hashes_md5_tstamp[fname][0] == t: - return Build.hashes_md5_tstamp[fname][1] - - try: - fd = os.open(fname, os.O_BINARY | os.O_RDONLY | os.O_NOINHERIT) - except OSError: - raise IOError('Cannot read from %r' % fname) - f = os.fdopen(fd, 'rb') - m = Utils.md5() - rb = 1 - try: - while rb: - rb = f.read(200000) - m.update(rb) - finally: - f.close() - - # ensure that the cache is overwritten - Build.hashes_md5_tstamp[fname] = (t, m.digest()) - return m.digest() - Node.Node.cached_hash_file = cached_hash_file - - def get_bld_sig_win32(self): - try: - return self.ctx.hash_cache[id(self)] - except KeyError: - pass - except AttributeError: - self.ctx.hash_cache = {} - self.ctx.hash_cache[id(self)] = ret = Utils.h_file(self.abspath()) - return ret - Node.Node.get_bld_sig = get_bld_sig_win32 - - def isfile_cached(self): - # optimize for nt.stat calls, assuming there are many files for few folders - try: - cache = self.__class__.cache_isfile_cache - except AttributeError: - cache = self.__class__.cache_isfile_cache = {} - - try: - c1 = cache[id(self.parent)] - except KeyError: - c1 = cache[id(self.parent)] = [] - - curpath = self.parent.abspath() - findData = ctypes.wintypes.WIN32_FIND_DATAW() - find = FindFirstFile(TP % curpath, ctypes.byref(findData)) - - if find == INVALID_HANDLE_VALUE: - Logs.error("invalid win32 handle isfile_cached %r", self.abspath()) - return os.path.isfile(self.abspath()) - - try: - while True: - if findData.cFileName not in UPPER_FOLDERS: - thatsadir = findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY - if not thatsadir: - c1.append(str(findData.cFileName)) - if not FindNextFile(find, ctypes.byref(findData)): - break - except Exception as e: - Logs.error('exception while listing a folder %r %r', self.abspath(), e) - return os.path.isfile(self.abspath()) - finally: - FindClose(find) - return self.name in c1 - Node.Node.isfile_cached = isfile_cached - - def find_or_declare_win32(self, lst): - # assuming that "find_or_declare" is called before the build starts, remove the calls to os.path.isfile - if isinstance(lst, str): - lst = [x for x in Utils.split_path(lst) if x and x != '.'] - - node = self.get_bld().search_node(lst) - if node: - if not node.isfile_cached(): - try: - node.parent.mkdir() - except OSError: - pass - return node - self = self.get_src() - node = self.find_node(lst) - if node: - if not node.isfile_cached(): - try: - node.parent.mkdir() - except OSError: - pass - return node - node = self.get_bld().make_node(lst) - node.parent.mkdir() - return node - Node.Node.find_or_declare = find_or_declare_win32 - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/wix.py b/ldb-2.0.8/third_party/waf/waflib/extras/wix.py deleted file mode 100644 index d87bfbb..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/wix.py +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/python -# encoding: utf-8 -# vim: tabstop=4 noexpandtab - -""" -Windows Installer XML Tool (WiX) - -.wxs --- candle ---> .wxobj --- light ---> .msi - -bld(features='wix', some.wxs, gen='some.msi', candleflags=[..], lightflags=[..]) - -bld(features='wix', source=['bundle.wxs','WixBalExtension'], gen='setup.exe', candleflags=[..]) -""" - -import os, copy -from waflib import TaskGen -from waflib import Task -from waflib.Utils import winreg - -class candle(Task.Task): - run_str = '${CANDLE} -nologo ${CANDLEFLAGS} -out ${TGT} ${SRC[0].abspath()}', - -class light(Task.Task): - run_str = "${LIGHT} -nologo -b ${SRC[0].parent.abspath()} ${LIGHTFLAGS} -out ${TGT} ${SRC[0].abspath()}" - -@TaskGen.feature('wix') -@TaskGen.before_method('process_source') -def wix(self): - #X.wxs -> ${SRC} for CANDLE - #X.wxobj -> ${SRC} for LIGHT - #X.dll -> -ext X in ${LIGHTFLAGS} - #X.wxl -> wixui.wixlib -loc X.wxl in ${LIGHTFLAGS} - wxobj = [] - wxs = [] - exts = [] - wxl = [] - rest = [] - for x in self.source: - if x.endswith('.wxobj'): - wxobj.append(x) - elif x.endswith('.wxs'): - wxobj.append(self.path.find_or_declare(x[:-4]+'.wxobj')) - wxs.append(x) - elif x.endswith('.dll'): - exts.append(x[:-4]) - elif '.' not in x: - exts.append(x) - elif x.endswith('.wxl'): - wxl.append(x) - else: - rest.append(x) - self.source = self.to_nodes(rest) #.wxs - - cndl = self.create_task('candle', self.to_nodes(wxs), self.to_nodes(wxobj)) - lght = self.create_task('light', self.to_nodes(wxobj), self.path.find_or_declare(self.gen)) - - cndl.env.CANDLEFLAGS = copy.copy(getattr(self,'candleflags',[])) - lght.env.LIGHTFLAGS = copy.copy(getattr(self,'lightflags',[])) - - for x in wxl: - lght.env.append_value('LIGHTFLAGS','wixui.wixlib') - lght.env.append_value('LIGHTFLAGS','-loc') - lght.env.append_value('LIGHTFLAGS',x) - for x in exts: - cndl.env.append_value('CANDLEFLAGS','-ext') - cndl.env.append_value('CANDLEFLAGS',x) - lght.env.append_value('LIGHTFLAGS','-ext') - lght.env.append_value('LIGHTFLAGS',x) - -#wix_bin_path() -def wix_bin_path(): - basekey = r"SOFTWARE\Microsoft\.NETFramework\AssemblyFolders" - query = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, basekey) - cnt=winreg.QueryInfoKey(query)[0] - thiskey = r'C:\Program Files (x86)\WiX Toolset v3.10\SDK' - for i in range(cnt-1,-1,-1): - thiskey = winreg.EnumKey(query,i) - if 'WiX' in thiskey: - break - winreg.CloseKey(query) - return os.path.normpath(winreg.QueryValue(winreg.HKEY_LOCAL_MACHINE, basekey+r'\\'+thiskey)+'..\\bin') - -def configure(ctx): - path_list=[wix_bin_path()] - ctx.find_program('candle', var='CANDLE', mandatory=True, path_list = path_list) - ctx.find_program('light', var='LIGHT', mandatory=True, path_list = path_list) - diff --git a/ldb-2.0.8/third_party/waf/waflib/extras/xcode6.py b/ldb-2.0.8/third_party/waf/waflib/extras/xcode6.py deleted file mode 100644 index 91bbff1..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/extras/xcode6.py +++ /dev/null @@ -1,727 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# XCode 3/XCode 4/XCode 6/Xcode 7 generator for Waf -# Based on work by Nicolas Mercier 2011 -# Extended by Simon Warg 2015, https://github.com/mimon -# XCode project file format based on http://www.monobjc.net/xcode-project-file-format.html - -""" -See playground/xcode6/ for usage examples. - -""" - -from waflib import Context, TaskGen, Build, Utils, Errors, Logs -import os, sys - -# FIXME too few extensions -XCODE_EXTS = ['.c', '.cpp', '.m', '.mm'] - -HEADERS_GLOB = '**/(*.h|*.hpp|*.H|*.inl)' - -MAP_EXT = { - '': "folder", - '.h' : "sourcecode.c.h", - - '.hh': "sourcecode.cpp.h", - '.inl': "sourcecode.cpp.h", - '.hpp': "sourcecode.cpp.h", - - '.c': "sourcecode.c.c", - - '.m': "sourcecode.c.objc", - - '.mm': "sourcecode.cpp.objcpp", - - '.cc': "sourcecode.cpp.cpp", - - '.cpp': "sourcecode.cpp.cpp", - '.C': "sourcecode.cpp.cpp", - '.cxx': "sourcecode.cpp.cpp", - '.c++': "sourcecode.cpp.cpp", - - '.l': "sourcecode.lex", # luthor - '.ll': "sourcecode.lex", - - '.y': "sourcecode.yacc", - '.yy': "sourcecode.yacc", - - '.plist': "text.plist.xml", - ".nib": "wrapper.nib", - ".xib": "text.xib", -} - -# Used in PBXNativeTarget elements -PRODUCT_TYPE_APPLICATION = 'com.apple.product-type.application' -PRODUCT_TYPE_FRAMEWORK = 'com.apple.product-type.framework' -PRODUCT_TYPE_EXECUTABLE = 'com.apple.product-type.tool' -PRODUCT_TYPE_LIB_STATIC = 'com.apple.product-type.library.static' -PRODUCT_TYPE_LIB_DYNAMIC = 'com.apple.product-type.library.dynamic' -PRODUCT_TYPE_EXTENSION = 'com.apple.product-type.kernel-extension' -PRODUCT_TYPE_IOKIT = 'com.apple.product-type.kernel-extension.iokit' - -# Used in PBXFileReference elements -FILE_TYPE_APPLICATION = 'wrapper.cfbundle' -FILE_TYPE_FRAMEWORK = 'wrapper.framework' -FILE_TYPE_LIB_DYNAMIC = 'compiled.mach-o.dylib' -FILE_TYPE_LIB_STATIC = 'archive.ar' -FILE_TYPE_EXECUTABLE = 'compiled.mach-o.executable' - -# Tuple packs of the above -TARGET_TYPE_FRAMEWORK = (PRODUCT_TYPE_FRAMEWORK, FILE_TYPE_FRAMEWORK, '.framework') -TARGET_TYPE_APPLICATION = (PRODUCT_TYPE_APPLICATION, FILE_TYPE_APPLICATION, '.app') -TARGET_TYPE_DYNAMIC_LIB = (PRODUCT_TYPE_LIB_DYNAMIC, FILE_TYPE_LIB_DYNAMIC, '.dylib') -TARGET_TYPE_STATIC_LIB = (PRODUCT_TYPE_LIB_STATIC, FILE_TYPE_LIB_STATIC, '.a') -TARGET_TYPE_EXECUTABLE = (PRODUCT_TYPE_EXECUTABLE, FILE_TYPE_EXECUTABLE, '') - -# Maps target type string to its data -TARGET_TYPES = { - 'framework': TARGET_TYPE_FRAMEWORK, - 'app': TARGET_TYPE_APPLICATION, - 'dylib': TARGET_TYPE_DYNAMIC_LIB, - 'stlib': TARGET_TYPE_STATIC_LIB, - 'exe' :TARGET_TYPE_EXECUTABLE, -} - -def delete_invalid_values(dct): - """ Deletes entries that are dictionaries or sets """ - for k, v in list(dct.items()): - if isinstance(v, dict) or isinstance(v, set): - del dct[k] - return dct - -""" -Configuration of the global project settings. Sets an environment variable 'PROJ_CONFIGURATION' -which is a dictionary of configuration name and buildsettings pair. -E.g.: -env.PROJ_CONFIGURATION = { - 'Debug': { - 'ARCHS': 'x86', - ... - } - 'Release': { - 'ARCHS' x86_64' - ... - } -} -The user can define a completely customized dictionary in configure() stage. Otherwise a default Debug/Release will be created -based on env variable -""" -def configure(self): - if not self.env.PROJ_CONFIGURATION: - self.to_log("A default project configuration was created since no custom one was given in the configure(conf) stage. Define your custom project settings by adding PROJ_CONFIGURATION to env. The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.\n") - - # Check for any added config files added by the tool 'c_config'. - if 'cfg_files' in self.env: - self.env.INCLUDES = Utils.to_list(self.env.INCLUDES) + [os.path.abspath(os.path.dirname(f)) for f in self.env.cfg_files] - - # Create default project configuration? - if 'PROJ_CONFIGURATION' not in self.env: - defaults = delete_invalid_values(self.env.get_merged_dict()) - self.env.PROJ_CONFIGURATION = { - "Debug": defaults, - "Release": defaults, - } - - # Some build settings are required to be present by XCode. We will supply default values - # if user hasn't defined any. - defaults_required = [('PRODUCT_NAME', '$(TARGET_NAME)')] - for cfgname,settings in self.env.PROJ_CONFIGURATION.items(): - for default_var, default_val in defaults_required: - if default_var not in settings: - settings[default_var] = default_val - - # Error check customization - if not isinstance(self.env.PROJ_CONFIGURATION, dict): - raise Errors.ConfigurationError("The env.PROJ_CONFIGURATION must be a dictionary with at least one key, where each key is the configuration name, and the value is a dictionary of key/value settings.") - -part1 = 0 -part2 = 10000 -part3 = 0 -id = 562000999 -def newid(): - global id - id += 1 - return "%04X%04X%04X%012d" % (0, 10000, 0, id) - -""" -Represents a tree node in the XCode project plist file format. -When written to a file, all attributes of XCodeNode are stringified together with -its value. However, attributes starting with an underscore _ are ignored -during that process and allows you to store arbitrary values that are not supposed -to be written out. -""" -class XCodeNode(object): - def __init__(self): - self._id = newid() - self._been_written = False - - def tostring(self, value): - if isinstance(value, dict): - result = "{\n" - for k,v in value.items(): - result = result + "\t\t\t%s = %s;\n" % (k, self.tostring(v)) - result = result + "\t\t}" - return result - elif isinstance(value, str): - return "\"%s\"" % value - elif isinstance(value, list): - result = "(\n" - for i in value: - result = result + "\t\t\t%s,\n" % self.tostring(i) - result = result + "\t\t)" - return result - elif isinstance(value, XCodeNode): - return value._id - else: - return str(value) - - def write_recursive(self, value, file): - if isinstance(value, dict): - for k,v in value.items(): - self.write_recursive(v, file) - elif isinstance(value, list): - for i in value: - self.write_recursive(i, file) - elif isinstance(value, XCodeNode): - value.write(file) - - def write(self, file): - if not self._been_written: - self._been_written = True - for attribute,value in self.__dict__.items(): - if attribute[0] != '_': - self.write_recursive(value, file) - w = file.write - w("\t%s = {\n" % self._id) - w("\t\tisa = %s;\n" % self.__class__.__name__) - for attribute,value in self.__dict__.items(): - if attribute[0] != '_': - w("\t\t%s = %s;\n" % (attribute, self.tostring(value))) - w("\t};\n\n") - -# Configurations -class XCBuildConfiguration(XCodeNode): - def __init__(self, name, settings = {}, env=None): - XCodeNode.__init__(self) - self.baseConfigurationReference = "" - self.buildSettings = settings - self.name = name - if env and env.ARCH: - settings['ARCHS'] = " ".join(env.ARCH) - - -class XCConfigurationList(XCodeNode): - def __init__(self, configlst): - """ :param configlst: list of XCConfigurationList """ - XCodeNode.__init__(self) - self.buildConfigurations = configlst - self.defaultConfigurationIsVisible = 0 - self.defaultConfigurationName = configlst and configlst[0].name or "" - -# Group/Files -class PBXFileReference(XCodeNode): - def __init__(self, name, path, filetype = '', sourcetree = "SOURCE_ROOT"): - - XCodeNode.__init__(self) - self.fileEncoding = 4 - if not filetype: - _, ext = os.path.splitext(name) - filetype = MAP_EXT.get(ext, 'text') - self.lastKnownFileType = filetype - self.explicitFileType = filetype - self.name = name - self.path = path - self.sourceTree = sourcetree - - def __hash__(self): - return (self.path+self.name).__hash__() - - def __eq__(self, other): - return (self.path, self.name) == (other.path, other.name) - -class PBXBuildFile(XCodeNode): - """ This element indicate a file reference that is used in a PBXBuildPhase (either as an include or resource). """ - def __init__(self, fileRef, settings={}): - XCodeNode.__init__(self) - - # fileRef is a reference to a PBXFileReference object - self.fileRef = fileRef - - # A map of key/value pairs for additional settings. - self.settings = settings - - def __hash__(self): - return (self.fileRef).__hash__() - - def __eq__(self, other): - return self.fileRef == other.fileRef - -class PBXGroup(XCodeNode): - def __init__(self, name, sourcetree = 'SOURCE_TREE'): - XCodeNode.__init__(self) - self.children = [] - self.name = name - self.sourceTree = sourcetree - - # Maintain a lookup table for all PBXFileReferences - # that are contained in this group. - self._filerefs = {} - - def add(self, sources): - """ - Add a list of PBXFileReferences to this group - - :param sources: list of PBXFileReferences objects - """ - self._filerefs.update(dict(zip(sources, sources))) - self.children.extend(sources) - - def get_sub_groups(self): - """ - Returns all child PBXGroup objects contained in this group - """ - return list(filter(lambda x: isinstance(x, PBXGroup), self.children)) - - def find_fileref(self, fileref): - """ - Recursively search this group for an existing PBXFileReference. Returns None - if none were found. - - The reason you'd want to reuse existing PBXFileReferences from a PBXGroup is that XCode doesn't like PBXFileReferences that aren't part of a PBXGroup hierarchy. - If it isn't, the consequence is that certain UI features like 'Reveal in Finder' - stops working. - """ - if fileref in self._filerefs: - return self._filerefs[fileref] - elif self.children: - for childgroup in self.get_sub_groups(): - f = childgroup.find_fileref(fileref) - if f: - return f - return None - -class PBXContainerItemProxy(XCodeNode): - """ This is the element for to decorate a target item. """ - def __init__(self, containerPortal, remoteGlobalIDString, remoteInfo='', proxyType=1): - XCodeNode.__init__(self) - self.containerPortal = containerPortal # PBXProject - self.remoteGlobalIDString = remoteGlobalIDString # PBXNativeTarget - self.remoteInfo = remoteInfo # Target name - self.proxyType = proxyType - -class PBXTargetDependency(XCodeNode): - """ This is the element for referencing other target through content proxies. """ - def __init__(self, native_target, proxy): - XCodeNode.__init__(self) - self.target = native_target - self.targetProxy = proxy - -class PBXFrameworksBuildPhase(XCodeNode): - """ This is the element for the framework link build phase, i.e. linking to frameworks """ - def __init__(self, pbxbuildfiles): - XCodeNode.__init__(self) - self.buildActionMask = 2147483647 - self.runOnlyForDeploymentPostprocessing = 0 - self.files = pbxbuildfiles #List of PBXBuildFile (.o, .framework, .dylib) - -class PBXHeadersBuildPhase(XCodeNode): - """ This is the element for adding header files to be packaged into the .framework """ - def __init__(self, pbxbuildfiles): - XCodeNode.__init__(self) - self.buildActionMask = 2147483647 - self.runOnlyForDeploymentPostprocessing = 0 - self.files = pbxbuildfiles #List of PBXBuildFile (.o, .framework, .dylib) - -class PBXCopyFilesBuildPhase(XCodeNode): - """ - Represents the PBXCopyFilesBuildPhase section. PBXBuildFile - can be added to this node to copy files after build is done. - """ - def __init__(self, pbxbuildfiles, dstpath, dstSubpathSpec=0, *args, **kwargs): - XCodeNode.__init__(self) - self.files = pbxbuildfiles - self.dstPath = dstpath - self.dstSubfolderSpec = dstSubpathSpec - -class PBXSourcesBuildPhase(XCodeNode): - """ Represents the 'Compile Sources' build phase in a Xcode target """ - def __init__(self, buildfiles): - XCodeNode.__init__(self) - self.files = buildfiles # List of PBXBuildFile objects - -class PBXLegacyTarget(XCodeNode): - def __init__(self, action, target=''): - XCodeNode.__init__(self) - self.buildConfigurationList = XCConfigurationList([XCBuildConfiguration('waf', {})]) - if not target: - self.buildArgumentsString = "%s %s" % (sys.argv[0], action) - else: - self.buildArgumentsString = "%s %s --targets=%s" % (sys.argv[0], action, target) - self.buildPhases = [] - self.buildToolPath = sys.executable - self.buildWorkingDirectory = "" - self.dependencies = [] - self.name = target or action - self.productName = target or action - self.passBuildSettingsInEnvironment = 0 - -class PBXShellScriptBuildPhase(XCodeNode): - def __init__(self, action, target): - XCodeNode.__init__(self) - self.buildActionMask = 2147483647 - self.files = [] - self.inputPaths = [] - self.outputPaths = [] - self.runOnlyForDeploymentPostProcessing = 0 - self.shellPath = "/bin/sh" - self.shellScript = "%s %s %s --targets=%s" % (sys.executable, sys.argv[0], action, target) - -class PBXNativeTarget(XCodeNode): - """ Represents a target in XCode, e.g. App, DyLib, Framework etc. """ - def __init__(self, target, node, target_type=TARGET_TYPE_APPLICATION, configlist=[], buildphases=[]): - XCodeNode.__init__(self) - product_type = target_type[0] - file_type = target_type[1] - - self.buildConfigurationList = XCConfigurationList(configlist) - self.buildPhases = buildphases - self.buildRules = [] - self.dependencies = [] - self.name = target - self.productName = target - self.productType = product_type # See TARGET_TYPE_ tuples constants - self.productReference = PBXFileReference(node.name, node.abspath(), file_type, '') - - def add_configuration(self, cf): - """ :type cf: XCBuildConfiguration """ - self.buildConfigurationList.buildConfigurations.append(cf) - - def add_build_phase(self, phase): - # Some build phase types may appear only once. If a phase type already exists, then merge them. - if ( (phase.__class__ == PBXFrameworksBuildPhase) - or (phase.__class__ == PBXSourcesBuildPhase) ): - for b in self.buildPhases: - if b.__class__ == phase.__class__: - b.files.extend(phase.files) - return - self.buildPhases.append(phase) - - def add_dependency(self, depnd): - self.dependencies.append(depnd) - -# Root project object -class PBXProject(XCodeNode): - def __init__(self, name, version, env): - XCodeNode.__init__(self) - - if not isinstance(env.PROJ_CONFIGURATION, dict): - raise Errors.WafError("Error: env.PROJ_CONFIGURATION must be a dictionary. This is done for you if you do not define one yourself. However, did you load the xcode module at the end of your wscript configure() ?") - - # Retrieve project configuration - configurations = [] - for config_name, settings in env.PROJ_CONFIGURATION.items(): - cf = XCBuildConfiguration(config_name, settings) - configurations.append(cf) - - self.buildConfigurationList = XCConfigurationList(configurations) - self.compatibilityVersion = version[0] - self.hasScannedForEncodings = 1 - self.mainGroup = PBXGroup(name) - self.projectRoot = "" - self.projectDirPath = "" - self.targets = [] - self._objectVersion = version[1] - - def create_target_dependency(self, target, name): - """ : param target : PXBNativeTarget """ - proxy = PBXContainerItemProxy(self, target, name) - dependency = PBXTargetDependency(target, proxy) - return dependency - - def write(self, file): - - # Make sure this is written only once - if self._been_written: - return - - w = file.write - w("// !$*UTF8*$!\n") - w("{\n") - w("\tarchiveVersion = 1;\n") - w("\tclasses = {\n") - w("\t};\n") - w("\tobjectVersion = %d;\n" % self._objectVersion) - w("\tobjects = {\n\n") - - XCodeNode.write(self, file) - - w("\t};\n") - w("\trootObject = %s;\n" % self._id) - w("}\n") - - def add_target(self, target): - self.targets.append(target) - - def get_target(self, name): - """ Get a reference to PBXNativeTarget if it exists """ - for t in self.targets: - if t.name == name: - return t - return None - -@TaskGen.feature('c', 'cxx') -@TaskGen.after('propagate_uselib_vars', 'apply_incpaths') -def process_xcode(self): - bld = self.bld - try: - p = bld.project - except AttributeError: - return - - if not hasattr(self, 'target_type'): - return - - products_group = bld.products_group - - target_group = PBXGroup(self.name) - p.mainGroup.children.append(target_group) - - # Determine what type to build - framework, app bundle etc. - target_type = getattr(self, 'target_type', 'app') - if target_type not in TARGET_TYPES: - raise Errors.WafError("Target type '%s' does not exists. Available options are '%s'. In target '%s'" % (target_type, "', '".join(TARGET_TYPES.keys()), self.name)) - else: - target_type = TARGET_TYPES[target_type] - file_ext = target_type[2] - - # Create the output node - target_node = self.path.find_or_declare(self.name+file_ext) - target = PBXNativeTarget(self.name, target_node, target_type, [], []) - - products_group.children.append(target.productReference) - - # Pull source files from the 'source' attribute and assign them to a UI group. - # Use a default UI group named 'Source' unless the user - # provides a 'group_files' dictionary to customize the UI grouping. - sources = getattr(self, 'source', []) - if hasattr(self, 'group_files'): - group_files = getattr(self, 'group_files', []) - for grpname,files in group_files.items(): - group = bld.create_group(grpname, files) - target_group.children.append(group) - else: - group = bld.create_group('Source', sources) - target_group.children.append(group) - - # Create a PBXFileReference for each source file. - # If the source file already exists as a PBXFileReference in any of the UI groups, then - # reuse that PBXFileReference object (XCode does not like it if we don't reuse) - for idx, path in enumerate(sources): - fileref = PBXFileReference(path.name, path.abspath()) - existing_fileref = target_group.find_fileref(fileref) - if existing_fileref: - sources[idx] = existing_fileref - else: - sources[idx] = fileref - - # If the 'source' attribute contains any file extension that XCode can't work with, - # then remove it. The allowed file extensions are defined in XCODE_EXTS. - is_valid_file_extension = lambda file: os.path.splitext(file.path)[1] in XCODE_EXTS - sources = list(filter(is_valid_file_extension, sources)) - - buildfiles = [bld.unique_buildfile(PBXBuildFile(x)) for x in sources] - target.add_build_phase(PBXSourcesBuildPhase(buildfiles)) - - # Check if any framework to link against is some other target we've made - libs = getattr(self, 'tmp_use_seen', []) - for lib in libs: - use_target = p.get_target(lib) - if use_target: - # Create an XCode dependency so that XCode knows to build the other target before this target - dependency = p.create_target_dependency(use_target, use_target.name) - target.add_dependency(dependency) - - buildphase = PBXFrameworksBuildPhase([PBXBuildFile(use_target.productReference)]) - target.add_build_phase(buildphase) - if lib in self.env.LIB: - self.env.LIB = list(filter(lambda x: x != lib, self.env.LIB)) - - # If 'export_headers' is present, add files to the Headers build phase in xcode. - # These are files that'll get packed into the Framework for instance. - exp_hdrs = getattr(self, 'export_headers', []) - hdrs = bld.as_nodes(Utils.to_list(exp_hdrs)) - files = [p.mainGroup.find_fileref(PBXFileReference(n.name, n.abspath())) for n in hdrs] - files = [PBXBuildFile(f, {'ATTRIBUTES': ('Public',)}) for f in files] - buildphase = PBXHeadersBuildPhase(files) - target.add_build_phase(buildphase) - - # Merge frameworks and libs into one list, and prefix the frameworks - frameworks = Utils.to_list(self.env.FRAMEWORK) - frameworks = ' '.join(['-framework %s' % (f.split('.framework')[0]) for f in frameworks]) - - libs = Utils.to_list(self.env.STLIB) + Utils.to_list(self.env.LIB) - libs = ' '.join(bld.env['STLIB_ST'] % t for t in libs) - - # Override target specific build settings - bldsettings = { - 'HEADER_SEARCH_PATHS': ['$(inherited)'] + self.env['INCPATHS'], - 'LIBRARY_SEARCH_PATHS': ['$(inherited)'] + Utils.to_list(self.env.LIBPATH) + Utils.to_list(self.env.STLIBPATH) + Utils.to_list(self.env.LIBDIR) , - 'FRAMEWORK_SEARCH_PATHS': ['$(inherited)'] + Utils.to_list(self.env.FRAMEWORKPATH), - 'OTHER_LDFLAGS': libs + ' ' + frameworks, - 'OTHER_LIBTOOLFLAGS': bld.env['LINKFLAGS'], - 'OTHER_CPLUSPLUSFLAGS': Utils.to_list(self.env['CXXFLAGS']), - 'OTHER_CFLAGS': Utils.to_list(self.env['CFLAGS']), - 'INSTALL_PATH': [] - } - - # Install path - installpaths = Utils.to_list(getattr(self, 'install', [])) - prodbuildfile = PBXBuildFile(target.productReference) - for instpath in installpaths: - bldsettings['INSTALL_PATH'].append(instpath) - target.add_build_phase(PBXCopyFilesBuildPhase([prodbuildfile], instpath)) - - if not bldsettings['INSTALL_PATH']: - del bldsettings['INSTALL_PATH'] - - # Create build settings which can override the project settings. Defaults to none if user - # did not pass argument. This will be filled up with target specific - # search paths, libs to link etc. - settings = getattr(self, 'settings', {}) - - # The keys represents different build configuration, e.g. Debug, Release and so on.. - # Insert our generated build settings to all configuration names - keys = set(settings.keys() + bld.env.PROJ_CONFIGURATION.keys()) - for k in keys: - if k in settings: - settings[k].update(bldsettings) - else: - settings[k] = bldsettings - - for k,v in settings.items(): - target.add_configuration(XCBuildConfiguration(k, v)) - - p.add_target(target) - - -class xcode(Build.BuildContext): - cmd = 'xcode6' - fun = 'build' - - def as_nodes(self, files): - """ Returns a list of waflib.Nodes from a list of string of file paths """ - nodes = [] - for x in files: - if not isinstance(x, str): - d = x - else: - d = self.srcnode.find_node(x) - if not d: - raise Errors.WafError('File \'%s\' was not found' % x) - nodes.append(d) - return nodes - - def create_group(self, name, files): - """ - Returns a new PBXGroup containing the files (paths) passed in the files arg - :type files: string - """ - group = PBXGroup(name) - """ - Do not use unique file reference here, since XCode seem to allow only one file reference - to be referenced by a group. - """ - files_ = [] - for d in self.as_nodes(Utils.to_list(files)): - fileref = PBXFileReference(d.name, d.abspath()) - files_.append(fileref) - group.add(files_) - return group - - def unique_buildfile(self, buildfile): - """ - Returns a unique buildfile, possibly an existing one. - Use this after you've constructed a PBXBuildFile to make sure there is - only one PBXBuildFile for the same file in the same project. - """ - try: - build_files = self.build_files - except AttributeError: - build_files = self.build_files = {} - - if buildfile not in build_files: - build_files[buildfile] = buildfile - return build_files[buildfile] - - def execute(self): - """ - Entry point - """ - self.restore() - if not self.all_envs: - self.load_envs() - self.recurse([self.run_dir]) - - appname = getattr(Context.g_module, Context.APPNAME, os.path.basename(self.srcnode.abspath())) - - p = PBXProject(appname, ('Xcode 3.2', 46), self.env) - - # If we don't create a Products group, then - # XCode will create one, which entails that - # we'll start to see duplicate files in the UI - # for some reason. - products_group = PBXGroup('Products') - p.mainGroup.children.append(products_group) - - self.project = p - self.products_group = products_group - - # post all task generators - # the process_xcode method above will be called for each target - if self.targets and self.targets != '*': - (self._min_grp, self._exact_tg) = self.get_targets() - - self.current_group = 0 - while self.current_group < len(self.groups): - self.post_group() - self.current_group += 1 - - node = self.bldnode.make_node('%s.xcodeproj' % appname) - node.mkdir() - node = node.make_node('project.pbxproj') - with open(node.abspath(), 'w') as f: - p.write(f) - Logs.pprint('GREEN', 'Wrote %r' % node.abspath()) - -def bind_fun(tgtype): - def fun(self, *k, **kw): - tgtype = fun.__name__ - if tgtype == 'shlib' or tgtype == 'dylib': - features = 'cxx cxxshlib' - tgtype = 'dylib' - elif tgtype == 'framework': - features = 'cxx cxxshlib' - tgtype = 'framework' - elif tgtype == 'program': - features = 'cxx cxxprogram' - tgtype = 'exe' - elif tgtype == 'app': - features = 'cxx cxxprogram' - tgtype = 'app' - elif tgtype == 'stlib': - features = 'cxx cxxstlib' - tgtype = 'stlib' - lst = kw['features'] = Utils.to_list(kw.get('features', [])) - for x in features.split(): - if not x in kw['features']: - lst.append(x) - - kw['target_type'] = tgtype - return self(*k, **kw) - fun.__name__ = tgtype - setattr(Build.BuildContext, tgtype, fun) - return fun - -for xx in 'app framework dylib shlib stlib program'.split(): - bind_fun(xx) - diff --git a/ldb-2.0.8/third_party/waf/waflib/fixpy2.py b/ldb-2.0.8/third_party/waf/waflib/fixpy2.py deleted file mode 100644 index 24176e0..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/fixpy2.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2010-2018 (ita) - -from __future__ import with_statement - -import os - -all_modifs = {} - -def fixdir(dir): - """Call all substitution functions on Waf folders""" - for k in all_modifs: - for v in all_modifs[k]: - modif(os.path.join(dir, 'waflib'), k, v) - -def modif(dir, name, fun): - """Call a substitution function""" - if name == '*': - lst = [] - for y in '. Tools extras'.split(): - for x in os.listdir(os.path.join(dir, y)): - if x.endswith('.py'): - lst.append(y + os.sep + x) - for x in lst: - modif(dir, x, fun) - return - - filename = os.path.join(dir, name) - with open(filename, 'r') as f: - txt = f.read() - - txt = fun(txt) - - with open(filename, 'w') as f: - f.write(txt) - -def subst(*k): - """register a substitution function""" - def do_subst(fun): - for x in k: - try: - all_modifs[x].append(fun) - except KeyError: - all_modifs[x] = [fun] - return fun - return do_subst - -@subst('*') -def r1(code): - "utf-8 fixes for python < 2.6" - code = code.replace('as e:', ',e:') - code = code.replace(".decode(sys.stdout.encoding or'latin-1',errors='replace')", '') - return code.replace('.encode()', '') - -@subst('Runner.py') -def r4(code): - "generator syntax" - return code.replace('next(self.biter)', 'self.biter.next()') - -@subst('Context.py') -def r5(code): - return code.replace("('Execution failure: %s'%str(e),ex=e)", "('Execution failure: %s'%str(e),ex=e),None,sys.exc_info()[2]") - diff --git a/ldb-2.0.8/third_party/waf/waflib/processor.py b/ldb-2.0.8/third_party/waf/waflib/processor.py deleted file mode 100755 index eff2e69..0000000 --- a/ldb-2.0.8/third_party/waf/waflib/processor.py +++ /dev/null @@ -1,68 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 -# Thomas Nagy, 2016-2018 (ita) - -import os, sys, traceback, base64, signal -try: - import cPickle -except ImportError: - import pickle as cPickle - -try: - import subprocess32 as subprocess -except ImportError: - import subprocess - -try: - TimeoutExpired = subprocess.TimeoutExpired -except AttributeError: - class TimeoutExpired(Exception): - pass - -def run(): - txt = sys.stdin.readline().strip() - if not txt: - # parent process probably ended - sys.exit(1) - [cmd, kwargs, cargs] = cPickle.loads(base64.b64decode(txt)) - cargs = cargs or {} - - if not 'close_fds' in kwargs: - # workers have no fds - kwargs['close_fds'] = False - - ret = 1 - out, err, ex, trace = (None, None, None, None) - try: - proc = subprocess.Popen(cmd, **kwargs) - try: - out, err = proc.communicate(**cargs) - except TimeoutExpired: - if kwargs.get('start_new_session') and hasattr(os, 'killpg'): - os.killpg(proc.pid, signal.SIGKILL) - else: - proc.kill() - out, err = proc.communicate() - exc = TimeoutExpired(proc.args, timeout=cargs['timeout'], output=out) - exc.stderr = err - raise exc - ret = proc.returncode - except Exception as e: - exc_type, exc_value, tb = sys.exc_info() - exc_lines = traceback.format_exception(exc_type, exc_value, tb) - trace = str(cmd) + '\n' + ''.join(exc_lines) - ex = e.__class__.__name__ - - # it is just text so maybe we do not need to pickle() - tmp = [ret, out, err, ex, trace] - obj = base64.b64encode(cPickle.dumps(tmp)) - sys.stdout.write(obj.decode()) - sys.stdout.write('\n') - sys.stdout.flush() - -while 1: - try: - run() - except KeyboardInterrupt: - break - diff --git a/ldb-2.0.8/tools/cmdline.c b/ldb-2.0.8/tools/cmdline.c deleted file mode 100644 index a2fe97e..0000000 --- a/ldb-2.0.8/tools/cmdline.c +++ /dev/null @@ -1,521 +0,0 @@ -/* - ldb database library - command line handling for ldb tools - - Copyright (C) Andrew Tridgell 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb.h" -#include "ldb_module.h" -#include "tools/cmdline.h" - -static struct ldb_cmdline options; /* needs to be static for older compilers */ - -enum ldb_cmdline_options { CMDLINE_RELAX=1 }; - -static struct poptOption builtin_popt_options[] = { - POPT_AUTOHELP - { "url", 'H', POPT_ARG_STRING, &options.url, 0, "database URL", "URL" }, - { "basedn", 'b', POPT_ARG_STRING, &options.basedn, 0, "base DN", "DN" }, - { "editor", 'e', POPT_ARG_STRING, &options.editor, 0, "external editor", "PROGRAM" }, - { "scope", 's', POPT_ARG_STRING, NULL, 's', "search scope", "SCOPE" }, - { "verbose", 'v', POPT_ARG_NONE, NULL, 'v', "increase verbosity", NULL }, - { "trace", 0, POPT_ARG_NONE, &options.tracing, 0, "enable tracing", NULL }, - { "interactive", 'i', POPT_ARG_NONE, &options.interactive, 0, "input from stdin", NULL }, - { "recursive", 'r', POPT_ARG_NONE, &options.recursive, 0, "recursive delete", NULL }, - { "modules-path", 0, POPT_ARG_STRING, &options.modules_path, 0, "modules path", "PATH" }, - { "num-searches", 0, POPT_ARG_INT, &options.num_searches, 0, "number of test searches", NULL }, - { "num-records", 0, POPT_ARG_INT, &options.num_records, 0, "number of test records", NULL }, - { "all", 'a', POPT_ARG_NONE, &options.all_records, 0, "(|(objectClass=*)(distinguishedName=*))", NULL }, - { "nosync", 0, POPT_ARG_NONE, &options.nosync, 0, "non-synchronous transactions", NULL }, - { "sorted", 'S', POPT_ARG_NONE, &options.sorted, 0, "sort attributes", NULL }, - { NULL, 'o', POPT_ARG_STRING, NULL, 'o', "ldb_connect option", "OPTION" }, - { "controls", 0, POPT_ARG_STRING, NULL, 'c', "controls", NULL }, - { "show-binary", 0, POPT_ARG_NONE, &options.show_binary, 0, "display binary LDIF", NULL }, - { "paged", 0, POPT_ARG_NONE, NULL, 'P', "use a paged search", NULL }, - { "show-deleted", 0, POPT_ARG_NONE, NULL, 'D', "show deleted objects", NULL }, - { "show-recycled", 0, POPT_ARG_NONE, NULL, 'R', "show recycled objects", NULL }, - { "show-deactivated-link", 0, POPT_ARG_NONE, NULL, 'd', "show deactivated links", NULL }, - { "reveal", 0, POPT_ARG_NONE, NULL, 'r', "reveal ldb internals", NULL }, - { "relax", 0, POPT_ARG_NONE, NULL, CMDLINE_RELAX, "pass relax control", NULL }, - { "cross-ncs", 0, POPT_ARG_NONE, NULL, 'N', "search across NC boundaries", NULL }, - { "extended-dn", 0, POPT_ARG_NONE, NULL, 'E', "show extended DNs", NULL }, - { NULL } -}; - -void ldb_cmdline_help(struct ldb_context *ldb, const char *cmdname, FILE *f) -{ - poptContext pc; - struct poptOption **popt_options = ldb_module_popt_options(ldb); - pc = poptGetContext(cmdname, 0, NULL, *popt_options, - POPT_CONTEXT_KEEP_FIRST); - poptPrintHelp(pc, f, 0); -} - -/* - add a control to the options structure - */ -static bool add_control(TALLOC_CTX *mem_ctx, const char *control) -{ - unsigned int i; - - /* count how many controls we already have */ - for (i=0; options.controls && options.controls[i]; i++) ; - - options.controls = talloc_realloc(mem_ctx, options.controls, const char *, i + 2); - if (options.controls == NULL) { - return false; - } - options.controls[i] = control; - options.controls[i+1] = NULL; - return true; -} - -/** - process command line options -*/ -static struct ldb_cmdline *ldb_cmdline_process_internal(struct ldb_context *ldb, - int argc, const char **argv, - void (*usage)(struct ldb_context *), - bool search) -{ - struct ldb_cmdline *ret=NULL; - poptContext pc; - int num_options = 0; - int opt; - unsigned int flags = 0; - int rc; - struct poptOption **popt_options; - - /* make the ldb utilities line buffered */ - setlinebuf(stdout); - - ret = talloc_zero(ldb, struct ldb_cmdline); - if (ret == NULL) { - fprintf(stderr, "Out of memory!\n"); - goto failed; - } - - options = *ret; - - /* pull in URL */ - options.url = getenv("LDB_URL"); - - /* and editor (used by ldbedit) */ - options.editor = getenv("VISUAL"); - if (!options.editor) { - options.editor = getenv("EDITOR"); - } - if (!options.editor) { - options.editor = "vi"; - } - - options.scope = LDB_SCOPE_DEFAULT; - - popt_options = ldb_module_popt_options(ldb); - (*popt_options) = builtin_popt_options; - - rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_OPTIONS); - if (rc != LDB_SUCCESS) { - fprintf(stderr, "ldb: failed to run command line hooks : %s\n", ldb_strerror(rc)); - goto failed; - } - - pc = poptGetContext(argv[0], argc, argv, *popt_options, - POPT_CONTEXT_KEEP_FIRST); - - while((opt = poptGetNextOpt(pc)) != -1) { - switch (opt) { - case 's': { - const char *arg = poptGetOptArg(pc); - if (strcmp(arg, "base") == 0) { - options.scope = LDB_SCOPE_BASE; - } else if (strcmp(arg, "sub") == 0) { - options.scope = LDB_SCOPE_SUBTREE; - } else if (strcmp(arg, "one") == 0) { - options.scope = LDB_SCOPE_ONELEVEL; - } else { - fprintf(stderr, "Invalid scope '%s'\n", arg); - goto failed; - } - break; - } - - case 'v': - options.verbose++; - break; - - case 'o': - options.options = talloc_realloc(ret, options.options, - const char *, num_options+3); - if (options.options == NULL) { - fprintf(stderr, "Out of memory!\n"); - goto failed; - } - options.options[num_options] = poptGetOptArg(pc); - options.options[num_options+1] = NULL; - num_options++; - break; - - case 'c': { - const char *cs = poptGetOptArg(pc); - const char *p; - - for (p = cs; p != NULL; ) { - const char *t, *c; - - t = strchr(p, ','); - if (t == NULL) { - c = talloc_strdup(options.controls, p); - p = NULL; - } else { - c = talloc_strndup(options.controls, p, t-p); - p = t + 1; - } - if (c == NULL || !add_control(ret, c)) { - fprintf(stderr, __location__ ": out of memory\n"); - goto failed; - } - } - - break; - } - case 'P': - if (!add_control(ret, "paged_results:1:1024")) { - fprintf(stderr, __location__ ": out of memory\n"); - goto failed; - } - break; - case 'D': - if (!add_control(ret, "show_deleted:1")) { - fprintf(stderr, __location__ ": out of memory\n"); - goto failed; - } - break; - case 'R': - if (!add_control(ret, "show_recycled:0")) { - fprintf(stderr, __location__ ": out of memory\n"); - goto failed; - } - break; - case 'd': - if (!add_control(ret, "show_deactivated_link:0")) { - fprintf(stderr, __location__ ": out of memory\n"); - goto failed; - } - break; - case 'r': - if (!add_control(ret, "reveal_internals:0")) { - fprintf(stderr, __location__ ": out of memory\n"); - goto failed; - } - break; - case CMDLINE_RELAX: - if (!add_control(ret, "relax:0")) { - fprintf(stderr, __location__ ": out of memory\n"); - goto failed; - } - break; - case 'N': - if (!add_control(ret, "search_options:1:2")) { - fprintf(stderr, __location__ ": out of memory\n"); - goto failed; - } - break; - case 'E': - if (!add_control(ret, "extended_dn:1:1")) { - fprintf(stderr, __location__ ": out of memory\n"); - goto failed; - } - break; - default: - fprintf(stderr, "Invalid option %s: %s\n", - poptBadOption(pc, 0), poptStrerror(opt)); - if (usage) usage(ldb); - goto failed; - } - } - - /* setup the remaining options for the main program to use */ - options.argv = poptGetArgs(pc); - if (options.argv) { - options.argv++; - while (options.argv[options.argc]) options.argc++; - } - - *ret = options; - - /* all utils need some option */ - if (ret->url == NULL) { - fprintf(stderr, "You must supply a url with -H or with $LDB_URL\n"); - if (usage) usage(ldb); - goto failed; - } - - if (strcmp(ret->url, "NONE") == 0) { - return ret; - } - - if (options.nosync) { - flags |= LDB_FLG_NOSYNC; - } - - if (search) { - flags |= LDB_FLG_DONT_CREATE_DB; - - if (options.show_binary) { - flags |= LDB_FLG_SHOW_BINARY; - } - } - - if (options.tracing) { - flags |= LDB_FLG_ENABLE_TRACING; - } - - if (options.modules_path != NULL) { - ldb_set_modules_dir(ldb, options.modules_path); - } - - rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_PRECONNECT); - if (rc != LDB_SUCCESS) { - fprintf(stderr, "ldb: failed to run preconnect hooks : %s\n", ldb_strerror(rc)); - goto failed; - } - - /* now connect to the ldb */ - if (ldb_connect(ldb, ret->url, flags, ret->options) != LDB_SUCCESS) { - fprintf(stderr, "Failed to connect to %s - %s\n", - ret->url, ldb_errstring(ldb)); - goto failed; - } - - rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_POSTCONNECT); - if (rc != LDB_SUCCESS) { - fprintf(stderr, "ldb: failed to run post connect hooks : %s\n", ldb_strerror(rc)); - goto failed; - } - - return ret; - -failed: - talloc_free(ret); - exit(LDB_ERR_OPERATIONS_ERROR); - return NULL; -} - -struct ldb_cmdline *ldb_cmdline_process_search(struct ldb_context *ldb, - int argc, const char **argv, - void (*usage)(struct ldb_context *)) -{ - return ldb_cmdline_process_internal(ldb, argc, argv, usage, true); -} - -struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, - int argc, const char **argv, - void (*usage)(struct ldb_context *)) -{ - return ldb_cmdline_process_internal(ldb, argc, argv, usage, false); -} - -/* this function check controls reply and determines if more - * processing is needed setting up the request controls correctly - * - * returns: - * -1 error - * 0 all ok - * 1 all ok, more processing required - */ -int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request) -{ - unsigned int i, j; - int ret = 0; - - if (reply == NULL || request == NULL) return -1; - - for (i = 0; reply[i]; i++) { - if (strcmp(LDB_CONTROL_VLV_RESP_OID, reply[i]->oid) == 0) { - struct ldb_vlv_resp_control *rep_control; - - rep_control = talloc_get_type(reply[i]->data, struct ldb_vlv_resp_control); - - /* check we have a matching control in the request */ - for (j = 0; request[j]; j++) { - if (strcmp(LDB_CONTROL_VLV_REQ_OID, request[j]->oid) == 0) - break; - } - if (! request[j]) { - fprintf(stderr, "Warning VLV reply received but no request have been made\n"); - continue; - } - - /* check the result */ - if (rep_control->vlv_result != 0) { - fprintf(stderr, "Warning: VLV not performed with error: %d\n", rep_control->vlv_result); - } else { - fprintf(stderr, "VLV Info: target position = %d, content count = %d\n", rep_control->targetPosition, rep_control->contentCount); - } - - continue; - } - - if (strcmp(LDB_CONTROL_ASQ_OID, reply[i]->oid) == 0) { - struct ldb_asq_control *rep_control; - - rep_control = talloc_get_type(reply[i]->data, struct ldb_asq_control); - - /* check the result */ - if (rep_control->result != 0) { - fprintf(stderr, "Warning: ASQ not performed with error: %d\n", rep_control->result); - } - - continue; - } - - if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, reply[i]->oid) == 0) { - struct ldb_paged_control *rep_control, *req_control; - - rep_control = talloc_get_type(reply[i]->data, struct ldb_paged_control); - if (rep_control->cookie_len == 0) /* we are done */ - break; - - /* more processing required */ - /* let's fill in the request control with the new cookie */ - - for (j = 0; request[j]; j++) { - if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, request[j]->oid) == 0) - break; - } - /* if there's a reply control we must find a request - * control matching it */ - if (! request[j]) return -1; - - req_control = talloc_get_type(request[j]->data, struct ldb_paged_control); - - if (req_control->cookie) - talloc_free(req_control->cookie); - req_control->cookie = (char *)talloc_memdup( - req_control, rep_control->cookie, - rep_control->cookie_len); - req_control->cookie_len = rep_control->cookie_len; - - ret = 1; - - continue; - } - - if (strcmp(LDB_CONTROL_SORT_RESP_OID, reply[i]->oid) == 0) { - struct ldb_sort_resp_control *rep_control; - - rep_control = talloc_get_type(reply[i]->data, struct ldb_sort_resp_control); - - /* check we have a matching control in the request */ - for (j = 0; request[j]; j++) { - if (strcmp(LDB_CONTROL_SERVER_SORT_OID, request[j]->oid) == 0) - break; - } - if (! request[j]) { - fprintf(stderr, "Warning Server Sort reply received but no request found\n"); - continue; - } - - /* check the result */ - if (rep_control->result != 0) { - fprintf(stderr, "Warning: Sorting not performed with error: %d\n", rep_control->result); - } - - continue; - } - - if (strcmp(LDB_CONTROL_DIRSYNC_OID, reply[i]->oid) == 0) { - struct ldb_dirsync_control *rep_control, *req_control; - char *cookie; - - rep_control = talloc_get_type(reply[i]->data, struct ldb_dirsync_control); - if (rep_control->cookie_len == 0) /* we are done */ - break; - - /* more processing required */ - /* let's fill in the request control with the new cookie */ - - for (j = 0; request[j]; j++) { - if (strcmp(LDB_CONTROL_DIRSYNC_OID, request[j]->oid) == 0) - break; - } - /* if there's a reply control we must find a request - * control matching it */ - if (! request[j]) return -1; - - req_control = talloc_get_type(request[j]->data, struct ldb_dirsync_control); - - if (req_control->cookie) - talloc_free(req_control->cookie); - req_control->cookie = (char *)talloc_memdup( - req_control, rep_control->cookie, - rep_control->cookie_len); - req_control->cookie_len = rep_control->cookie_len; - - cookie = ldb_base64_encode(req_control, rep_control->cookie, rep_control->cookie_len); - printf("# DIRSYNC cookie returned was:\n# %s\n", cookie); - - continue; - } - if (strcmp(LDB_CONTROL_DIRSYNC_EX_OID, reply[i]->oid) == 0) { - struct ldb_dirsync_control *rep_control, *req_control; - char *cookie; - - rep_control = talloc_get_type(reply[i]->data, struct ldb_dirsync_control); - if (rep_control->cookie_len == 0) /* we are done */ - break; - - /* more processing required */ - /* let's fill in the request control with the new cookie */ - - for (j = 0; request[j]; j++) { - if (strcmp(LDB_CONTROL_DIRSYNC_EX_OID, request[j]->oid) == 0) - break; - } - /* if there's a reply control we must find a request - * control matching it */ - if (! request[j]) return -1; - - req_control = talloc_get_type(request[j]->data, struct ldb_dirsync_control); - - if (req_control->cookie) - talloc_free(req_control->cookie); - req_control->cookie = (char *)talloc_memdup( - req_control, rep_control->cookie, - rep_control->cookie_len); - req_control->cookie_len = rep_control->cookie_len; - - cookie = ldb_base64_encode(req_control, rep_control->cookie, rep_control->cookie_len); - printf("# DIRSYNC_EX cookie returned was:\n# %s\n", cookie); - - continue; - } - - /* no controls matched, throw a warning */ - fprintf(stderr, "Unknown reply control oid: %s\n", reply[i]->oid); - } - - return ret; -} - diff --git a/ldb-2.0.8/tools/cmdline.h b/ldb-2.0.8/tools/cmdline.h deleted file mode 100644 index 9af0ea1..0000000 --- a/ldb-2.0.8/tools/cmdline.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - ldb database library - command line handling for ldb tools - - Copyright (C) Andrew Tridgell 2005 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include - -struct ldb_cmdline { - const char *url; - enum ldb_scope scope; - const char *basedn; - const char *modules_path; - int interactive; - int sorted; - const char *editor; - int verbose; - int recursive; - int all_records; - int nosync; - const char **options; - int argc; - const char **argv; - int num_records; - int num_searches; - const char *sasl_mechanism; - const char **controls; - int show_binary; - int tracing; -}; - -struct ldb_cmdline *ldb_cmdline_process_search(struct ldb_context *ldb, - int argc, const char **argv, - void (*usage)(struct ldb_context *)); -struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, - const char **argv, - void (*usage)(struct ldb_context *)); - - -int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request); -void ldb_cmdline_help(struct ldb_context *ldb, const char *cmdname, FILE *f); - diff --git a/ldb-2.0.8/tools/ldbadd.c b/ldb-2.0.8/tools/ldbadd.c deleted file mode 100644 index e6cea29..0000000 --- a/ldb-2.0.8/tools/ldbadd.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldbadd - * - * Description: utility to add records - modelled on ldapadd - * - * Author: Andrew Tridgell - */ - -#include "replace.h" -#include "ldb.h" -#include "tools/cmdline.h" -#include "ldbutil.h" -#include "include/ldb_private.h" - -static struct ldb_cmdline *options; - -static void usage(struct ldb_context *ldb) -{ - printf("Usage: ldbadd \n"); - printf("Adds records to a ldb, reading ldif the specified list of files\n\n"); - ldb_cmdline_help(ldb, "ldbadd", stdout); - exit(LDB_ERR_OPERATIONS_ERROR); -} - - -/* - add records from an opened file -*/ -static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) -{ - struct ldb_ldif *ldif; - int fun_ret = LDB_SUCCESS, ret; - struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); - struct ldif_read_file_state state = { - .f = f - }; - - if (options->controls != NULL && req_ctrls== NULL) { - printf("parsing controls failed: %s\n", ldb_errstring(ldb)); - return LDB_ERR_OPERATIONS_ERROR; - } - - fun_ret = ldb_transaction_start(ldb); - if (fun_ret != LDB_SUCCESS) { - fprintf(stderr, "ERR: (%s) on transaction start\n", - ldb_errstring(ldb)); - return fun_ret; - } - - while ((ldif = ldb_ldif_read_file_state(ldb, &state))) { - if (ldif->changetype != LDB_CHANGETYPE_ADD && - ldif->changetype != LDB_CHANGETYPE_NONE) { - fprintf(stderr, "Only CHANGETYPE_ADD records allowed\n"); - break; - } - - ret = ldb_msg_normalize(ldb, ldif, ldif->msg, &ldif->msg); - if (ret != LDB_SUCCESS) { - fprintf(stderr, - "ERR: Message canonicalize failed - %s\n", - ldb_strerror(ret)); - fun_ret = ret; - ldb_ldif_read_free(ldb, ldif); - continue; - } - - ret = ldb_add_ctrl(ldb, ldif->msg,req_ctrls); - if (ret != LDB_SUCCESS) { - fprintf(stderr, "ERR: %s : \"%s\" on DN %s at block before line %llu\n", - ldb_strerror(ret), ldb_errstring(ldb), - ldb_dn_get_linearized(ldif->msg->dn), - (unsigned long long)state.line_no); - fun_ret = ret; - } else { - (*count)++; - if (options->verbose) { - printf("Added %s\n", ldb_dn_get_linearized(ldif->msg->dn)); - } - } - ldb_ldif_read_free(ldb, ldif); - if (ret) { - break; - } - } - - if (fun_ret == LDB_SUCCESS && !feof(f)) { - fprintf(stderr, "Failed to parse ldif\n"); - fun_ret = LDB_ERR_OPERATIONS_ERROR; - } - - if (fun_ret == LDB_SUCCESS) { - fun_ret = ldb_transaction_commit(ldb); - if (fun_ret != LDB_SUCCESS) { - fprintf(stderr, "ERR: (%s) on transaction commit\n", - ldb_errstring(ldb)); - } - } else { - ldb_transaction_cancel(ldb); - } - - return fun_ret; -} - - - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - unsigned int i, count = 0; - int ret = LDB_SUCCESS; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - - ldb = ldb_init(mem_ctx, NULL); - if (ldb == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - ret = ldb_transaction_start(ldb); - if (ret != LDB_SUCCESS) { - printf("Failed to start transaction: %s\n", ldb_errstring(ldb)); - return ret; - } - - if (options->argc == 0) { - ret = process_file(ldb, stdin, &count); - } else { - for (i=0;iargc;i++) { - const char *fname = options->argv[i]; - FILE *f; - f = fopen(fname, "r"); - if (!f) { - perror(fname); - return LDB_ERR_OPERATIONS_ERROR; - } - ret = process_file(ldb, f, &count); - fclose(f); - } - } - - if (count != 0) { - ret = ldb_transaction_commit(ldb); - if (ret != LDB_SUCCESS) { - printf("Failed to commit transaction: %s\n", ldb_errstring(ldb)); - return ret; - } - } else { - ldb_transaction_cancel(ldb); - } - - talloc_free(mem_ctx); - - if (ret) { - printf("Add failed after processing %u records\n", count); - } else { - printf("Added %u records successfully\n", count); - } - - return ret; -} diff --git a/ldb-2.0.8/tools/ldbdel.c b/ldb-2.0.8/tools/ldbdel.c deleted file mode 100644 index 8036d09..0000000 --- a/ldb-2.0.8/tools/ldbdel.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldbdel - * - * Description: utility to delete records - modelled on ldapdelete - * - * Author: Andrew Tridgell - */ - -#include "replace.h" -#include "ldb.h" -#include "tools/cmdline.h" -#include "ldbutil.h" - -static int dn_cmp(struct ldb_message **msg1, struct ldb_message **msg2) -{ - return ldb_dn_compare((*msg1)->dn, (*msg2)->dn); -} - -static int ldb_delete_recursive(struct ldb_context *ldb, struct ldb_dn *dn,struct ldb_control **req_ctrls) -{ - int ret; - unsigned int i, total=0; - const char *attrs[] = { NULL }; - struct ldb_result *res; - - ret = ldb_search(ldb, ldb, &res, dn, LDB_SCOPE_SUBTREE, attrs, "distinguishedName=*"); - if (ret != LDB_SUCCESS) return ret; - - /* sort the DNs, deepest first */ - TYPESAFE_QSORT(res->msgs, res->count, dn_cmp); - - for (i = 0; i < res->count; i++) { - if (ldb_delete_ctrl(ldb, res->msgs[i]->dn,req_ctrls) == LDB_SUCCESS) { - total++; - } else { - printf("Failed to delete '%s' - %s\n", - ldb_dn_get_linearized(res->msgs[i]->dn), - ldb_errstring(ldb)); - } - } - - talloc_free(res); - - if (total == 0) { - return LDB_ERR_OPERATIONS_ERROR; - } - printf("Deleted %u records\n", total); - return LDB_SUCCESS; -} - -static void usage(struct ldb_context *ldb) -{ - printf("Usage: ldbdel \n"); - printf("Deletes records from a ldb\n\n"); - ldb_cmdline_help(ldb, "ldbdel", stdout); - exit(LDB_ERR_OPERATIONS_ERROR); -} - -int main(int argc, const char **argv) -{ - struct ldb_control **req_ctrls; - struct ldb_cmdline *options; - struct ldb_context *ldb; - int ret = 0, i; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - - ldb = ldb_init(mem_ctx, NULL); - if (ldb == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - if (options->argc < 1) { - usage(ldb); - } - - req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); - if (options->controls != NULL && req_ctrls== NULL) { - printf("parsing controls failed: %s\n", ldb_errstring(ldb)); - return LDB_ERR_OPERATIONS_ERROR; - } - - for (i=0;iargc;i++) { - struct ldb_dn *dn; - - dn = ldb_dn_new(ldb, ldb, options->argv[i]); - if (dn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - if (options->recursive) { - ret = ldb_delete_recursive(ldb, dn,req_ctrls); - } else { - ret = ldb_delete_ctrl(ldb, dn,req_ctrls); - if (ret == LDB_SUCCESS) { - printf("Deleted 1 record\n"); - } - } - if (ret != LDB_SUCCESS) { - printf("delete of '%s' failed - (%s) %s\n", - ldb_dn_get_linearized(dn), - ldb_strerror(ret), - ldb_errstring(ldb)); - } - } - - talloc_free(mem_ctx); - - return ret; -} diff --git a/ldb-2.0.8/tools/ldbdump.c b/ldb-2.0.8/tools/ldbdump.c deleted file mode 100644 index 5cdb7d8..0000000 --- a/ldb-2.0.8/tools/ldbdump.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - Unix SMB/CIFS implementation. - simple ldb tdb dump util - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Andrew Bartlett 2012 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "replace.h" -#include "system/locale.h" -#include "system/time.h" -#include "system/filesys.h" -#include "system/wait.h" -#include -#include -#include - -#ifdef HAVE_LMDB -#include -#endif /* ifdef HAVE_LMDB */ - - -static struct ldb_context *ldb; -bool show_index = false; -bool validate_contents = false; - -static void print_data(TDB_DATA d) -{ - unsigned char *p = (unsigned char *)d.dptr; - int len = d.dsize; - while (len--) { - if (isprint(*p) && !strchr("\"\\", *p)) { - fputc(*p, stdout); - } else { - printf("\\%02X", *p); - } - p++; - } -} - -static unsigned int pull_uint32(uint8_t *p) -{ - return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24); -} - - -static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA _dbuf, void *state) -{ - int ret, i, j; - struct ldb_dn *dn = state; - struct ldb_message *msg = ldb_msg_new(NULL); - struct ldb_val dbuf = { - .data = _dbuf.dptr, - .length = _dbuf.dsize, - }; - struct ldb_ldif ldif = { - .msg = msg, - .changetype = LDB_CHANGETYPE_NONE - }; - if (!msg) { - return -1; - } - - ret = ldb_unpack_data(ldb, &dbuf, msg); - if (ret != 0) { - fprintf(stderr, "Failed to parse record %*.*s as an LDB record\n", (int)key.dsize, (int)key.dsize, (char *)key.dptr); - TALLOC_FREE(msg); - return 0; - } - - if (dn && ldb_dn_compare(msg->dn, dn) != 0) { - TALLOC_FREE(msg); - return 0; - } - - if (!show_index && ldb_dn_is_special(msg->dn)) { - const char *dn_lin = ldb_dn_get_linearized(msg->dn); - if ((strcmp(dn_lin, "@BASEINFO") == 0) || (strncmp(dn_lin, "@INDEX:", strlen("@INDEX:")) == 0)) { - /* - the user has asked not to show index - records. Also exclude BASEINFO as it - contains meta-data which will be re-created - if this database is restored - */ - TALLOC_FREE(msg); - return 0; - } - } - - printf("# key: "); - print_data(key); - printf("\n# pack format: %#010x\n", pull_uint32(_dbuf.dptr)); - - if (!validate_contents || ldb_dn_is_special(msg->dn)) { - ldb_ldif_write_file(ldb, stdout, &ldif); - TALLOC_FREE(msg); - return 0; - } - - for (i=0;inum_elements;i++) { - const struct ldb_schema_attribute *a; - - a = ldb_schema_attribute_by_name(ldb, msg->elements[i].name); - for (j=0;jelements[i].num_values;j++) { - struct ldb_val v; - ret = a->syntax->ldif_write_fn(ldb, msg, &msg->elements[i].values[j], &v); - if (ret != 0) { - v = msg->elements[i].values[j]; - if (ldb_should_b64_encode(ldb, &v)) { - v.data = (uint8_t *)ldb_base64_encode(ldb, (char *)v.data, v.length); - v.length = strlen((char *)v.data); - } - fprintf(stderr, "On %s element %s value %d (%*.*s) failed to convert to LDIF correctly, skipping possibly corrupt record\n", - ldb_dn_get_linearized(msg->dn), - msg->elements[i].name, - j, (int)v.length, (int)v.length, - v.data); - TALLOC_FREE(msg); - return 0; - } - } - } - ldb_ldif_write_file(ldb, stdout, &ldif); - TALLOC_FREE(msg); - - return 0; -} - -static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level, - const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); - -static void log_stderr(struct tdb_context *tdb, enum tdb_debug_level level, - const char *fmt, ...) -{ - va_list ap; - const char *name = tdb_name(tdb); - const char *prefix = ""; - - if (!name) - name = "unnamed"; - - switch (level) { - case TDB_DEBUG_ERROR: - prefix = "ERROR: "; - break; - case TDB_DEBUG_WARNING: - prefix = "WARNING: "; - break; - case TDB_DEBUG_TRACE: - return; - - default: - case TDB_DEBUG_FATAL: - prefix = "FATAL: "; - break; - } - - va_start(ap, fmt); - fprintf(stderr, "tdb(%s): %s", name, prefix); - vfprintf(stderr, fmt, ap); - va_end(ap); -} - -static void emergency_walk(TDB_DATA key, TDB_DATA dbuf, void *keyname) -{ - traverse_fn(NULL, key, dbuf, keyname); -} - -static int dump_tdb(const char *fname, struct ldb_dn *dn, bool emergency) -{ - TDB_CONTEXT *tdb; - struct tdb_logging_context logfn = { - .log_fn = log_stderr, - }; - - tdb = tdb_open_ex(fname, 0, 0, O_RDONLY, 0, &logfn, NULL); - if (!tdb) { - fprintf(stderr, "Failed to open %s\n", fname); - return 1; - } - - if (emergency) { - return tdb_rescue(tdb, emergency_walk, dn) == 0; - } - return tdb_traverse(tdb, traverse_fn, dn) == -1 ? 1 : 0; -} - -#ifdef HAVE_LMDB -static int dump_lmdb(const char *fname, struct ldb_dn *dn, bool emergency) -{ - int ret; - struct MDB_env *env = NULL; - struct MDB_txn *txn = NULL; - MDB_dbi dbi; - struct MDB_cursor *cursor = NULL; - struct MDB_val key; - struct MDB_val data; - - ret = mdb_env_create(&env); - if (ret != 0) { - fprintf(stderr, - "Could not create MDB environment: (%d) %s\n", - ret, - mdb_strerror(ret)); - goto close_env; - } - - ret = mdb_env_open(env, - fname, - MDB_NOSUBDIR|MDB_NOTLS|MDB_RDONLY, - 0600); - if (ret != 0) { - fprintf(stderr, - "Could not open environment for %s: (%d) %s\n", - fname, - ret, - mdb_strerror(ret)); - goto close_env; - } - - ret = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn); - if (ret != 0) { - fprintf(stderr, - "Could not start transaction: (%d) %s\n", - ret, - mdb_strerror(ret)); - goto close_env; - } - - ret = mdb_dbi_open(txn, NULL, 0, &dbi); - if (ret != 0) { - fprintf(stderr, - "Could not open database: (%d) %s\n", - ret, - mdb_strerror(ret)); - goto close_txn; - } - - ret = mdb_cursor_open(txn, dbi, &cursor); - if (ret != 0) { - fprintf(stderr, - "Could not open cursor: (%d) %s\n", - ret, - mdb_strerror(ret)); - goto close_txn; - } - - ret = mdb_cursor_get(cursor, &key, &data, MDB_FIRST); - if (ret != 0 && ret != MDB_NOTFOUND) { - fprintf(stderr, - "Could not find first record: (%d) %s\n", - ret, - mdb_strerror(ret)); - goto close_cursor; - } - while (ret != MDB_NOTFOUND) { - struct TDB_DATA tkey = { - .dptr = key.mv_data, - .dsize = key.mv_size - }; - struct TDB_DATA tdata = { - .dptr = data.mv_data, - .dsize = data.mv_size - }; - traverse_fn(NULL, tkey, tdata, dn); - ret = mdb_cursor_get(cursor, &key, &data, MDB_NEXT); - if (ret != 0 && ret != MDB_NOTFOUND) { - fprintf(stderr, - "Could not read next record: (%d) %s\n", - ret, - mdb_strerror(ret)); - goto close_cursor; - } - } - ret = 0; - -close_cursor: - mdb_cursor_close(cursor); -close_txn: - mdb_txn_commit(txn); -close_env: - mdb_env_close(env); - - if (ret != 0) { - return 1; - } - return 0; - -} -#else -static int dump_lmdb(const char *fname, struct ldb_dn *dn, bool emergency) -{ - /* not built with lmdb support */ - return 1; -} -#endif /* #ifdef HAVE_LMDB */ - -static void usage( void) -{ - printf( "Usage: ldbdump [options] \n\n"); - printf( " -h this help message\n"); - printf( " -d DN dumps DN only\n"); - printf( " -e emergency dump, for corrupt databases\n"); - printf( " -i include index and @BASEINFO records in dump\n"); - printf( " -c validate contents of the records\n"); -} - - int main(int argc, char *argv[]) -{ - bool emergency = false; - int c, rc; - char *fname; - struct ldb_dn *dn = NULL; - - ldb = ldb_init(NULL, NULL); - if (ldb == NULL) { - fprintf(stderr, "ldb: ldb_init failed()"); - exit(1); - } - - rc = ldb_modules_hook(ldb, LDB_MODULE_HOOK_CMDLINE_PRECONNECT); - if (rc != LDB_SUCCESS) { - fprintf(stderr, "ldb: failed to run preconnect hooks (needed to get Samba LDIF handlers): %s\n", ldb_strerror(rc)); - exit(1); - } - - if (argc < 2) { - printf("Usage: ldbdump \n"); - exit(1); - } - - while ((c = getopt( argc, argv, "hd:eic")) != -1) { - switch (c) { - case 'h': - usage(); - exit( 0); - case 'd': - dn = ldb_dn_new(ldb, ldb, optarg); - if (!dn) { - fprintf(stderr, "ldb failed to parse %s as a DN\n", optarg); - exit(1); - } - break; - case 'e': - emergency = true; - break; - case 'i': - show_index = true; - break; - case 'c': - validate_contents = true; - break; - default: - usage(); - exit( 1); - } - } - - fname = argv[optind]; - - rc = dump_lmdb(fname, dn, emergency); - if (rc != 0) { - rc = dump_tdb(fname, dn, emergency); - if (rc != 0) { - fprintf(stderr, "Failed to open %s\n", fname); - return 1; - } - } - return 0; - -} diff --git a/ldb-2.0.8/tools/ldbedit.c b/ldb-2.0.8/tools/ldbedit.c deleted file mode 100644 index 5b83783..0000000 --- a/ldb-2.0.8/tools/ldbedit.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldbedit - * - * Description: utility for ldb database editing - * - * Author: Andrew Tridgell - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "system/filesys.h" -#include "ldb.h" -#include "tools/cmdline.h" -#include "tools/ldbutil.h" - -static struct ldb_cmdline *options; - -/* - debug routine -*/ -static void ldif_write_msg(struct ldb_context *ldb, - FILE *f, - enum ldb_changetype changetype, - struct ldb_message *msg) -{ - struct ldb_ldif ldif; - ldif.changetype = changetype; - ldif.msg = msg; - ldb_ldif_write_file(ldb, f, &ldif); -} - -/* - modify a database record so msg1 becomes msg2 - returns the number of modified elements -*/ -static int modify_record(struct ldb_context *ldb, - struct ldb_message *msg1, - struct ldb_message *msg2, - struct ldb_control **req_ctrls) -{ - int ret; - struct ldb_message *mod; - - if (ldb_msg_difference(ldb, ldb, msg1, msg2, &mod) != LDB_SUCCESS) { - fprintf(stderr, "Failed to calculate message differences\n"); - return -1; - } - - ret = mod->num_elements; - if (ret == 0) { - goto done; - } - - if (options->verbose > 0) { - ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_MODIFY, mod); - } - - if (ldb_modify_ctrl(ldb, mod, req_ctrls) != LDB_SUCCESS) { - fprintf(stderr, "failed to modify %s - %s\n", - ldb_dn_get_linearized(msg1->dn), ldb_errstring(ldb)); - ret = -1; - goto done; - } - -done: - talloc_free(mod); - return ret; -} - -/* - find dn in msgs[] -*/ -static struct ldb_message *msg_find(struct ldb_context *ldb, - struct ldb_message **msgs, - unsigned int count, - struct ldb_dn *dn) -{ - unsigned int i; - for (i=0;idn) == 0) { - return msgs[i]; - } - } - return NULL; -} - -/* - merge the changes in msgs2 into the messages from msgs1 -*/ -static int merge_edits(struct ldb_context *ldb, - struct ldb_message **msgs1, unsigned int count1, - struct ldb_message **msgs2, unsigned int count2) -{ - unsigned int i; - struct ldb_message *msg; - int ret; - unsigned int adds=0, modifies=0, deletes=0; - struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); - if (options->controls != NULL && req_ctrls == NULL) { - fprintf(stderr, "parsing controls failed: %s\n", ldb_errstring(ldb)); - return -1; - } - - if (ldb_transaction_start(ldb) != LDB_SUCCESS) { - fprintf(stderr, "Failed to start transaction: %s\n", ldb_errstring(ldb)); - return -1; - } - - /* do the adds and modifies */ - for (i=0;idn); - if (!msg) { - if (options->verbose > 0) { - ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_ADD, msgs2[i]); - } - if (ldb_add_ctrl(ldb, msgs2[i], req_ctrls) != LDB_SUCCESS) { - fprintf(stderr, "failed to add %s - %s\n", - ldb_dn_get_linearized(msgs2[i]->dn), - ldb_errstring(ldb)); - ldb_transaction_cancel(ldb); - return -1; - } - adds++; - } else { - ret = modify_record(ldb, msg, msgs2[i], req_ctrls); - if (ret != -1) { - modifies += (unsigned int) ret; - } else { - ldb_transaction_cancel(ldb); - return -1; - } - } - } - - /* do the deletes */ - for (i=0;idn); - if (!msg) { - if (options->verbose > 0) { - ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_DELETE, msgs1[i]); - } - if (ldb_delete_ctrl(ldb, msgs1[i]->dn, req_ctrls) != LDB_SUCCESS) { - fprintf(stderr, "failed to delete %s - %s\n", - ldb_dn_get_linearized(msgs1[i]->dn), - ldb_errstring(ldb)); - ldb_transaction_cancel(ldb); - return -1; - } - deletes++; - } - } - - if (ldb_transaction_commit(ldb) != LDB_SUCCESS) { - fprintf(stderr, "Failed to commit transaction: %s\n", ldb_errstring(ldb)); - return -1; - } - - printf("# %u adds %u modifies %u deletes\n", adds, modifies, deletes); - - return 0; -} - -/* - save a set of messages as ldif to a file -*/ -static int save_ldif(struct ldb_context *ldb, - FILE *f, struct ldb_message **msgs, unsigned int count) -{ - unsigned int i; - - fprintf(f, "# editing %u records\n", count); - - for (i=0;imsg; - } - - /* the feof() test works here, even for the last line of the - * file, as we parse ldif files character by character, and - * feof() is only true if we have failed to read a character - * from the file. So if the last line is bad, we don't get - * feof() set, so we know the record was bad. Only if we - * attempt to go to the next record will we get feof() and - * thus consider that the ldif has ended without errors - */ - if (!feof(f)) { - fprintf(stderr, "Error parsing ldif - aborting\n"); - fclose(f); - unlink(file_template); - return -1; - } - - fclose(f); - unlink(file_template); - - return merge_edits(ldb, msgs1, count1, msgs2, count2); -} - -static void usage(struct ldb_context *ldb) -{ - printf("Usage: ldbedit \n"); - ldb_cmdline_help(ldb, "ldbedit", stdout); - exit(LDB_ERR_OPERATIONS_ERROR); -} - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - struct ldb_result *result = NULL; - struct ldb_dn *basedn = NULL; - int ret; - const char *expression = "(|(objectClass=*)(distinguishedName=*))"; - const char * const * attrs = NULL; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - struct ldb_control **req_ctrls; - unsigned int i; - - ldb = ldb_init(mem_ctx, NULL); - if (ldb == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - /* the check for '=' is for compatibility with ldapsearch */ - if (options->argc > 0 && - strchr(options->argv[0], '=')) { - expression = options->argv[0]; - options->argv++; - options->argc--; - } - - if (options->argc > 0) { - attrs = (const char * const *)(options->argv); - } - - if (options->basedn != NULL) { - basedn = ldb_dn_new(ldb, ldb, options->basedn); - if (basedn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - } - - for (i = 0; options->controls != NULL && options->controls[i] != NULL; i++) { - if (strncmp(options->controls[i], "reveal_internals:", 17) == 0) { - printf("Using reveal internals has unintended consequences.\n"); - printf("If this is your intent, manually perform the search," - " and use ldbmodify directly.\n"); - return LDB_ERR_OPERATIONS_ERROR; - } - } - - req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); - if (options->controls != NULL && req_ctrls== NULL) { - printf("parsing controls failed: %s\n", ldb_errstring(ldb)); - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_search_ctrl(ldb, ldb, &result, basedn, options->scope, attrs, req_ctrls, "%s", expression); - if (ret != LDB_SUCCESS) { - printf("search failed - %s\n", ldb_errstring(ldb)); - return ret; - } - - if (result->count == 0) { - printf("no matching records - cannot edit\n"); - talloc_free(mem_ctx); - return LDB_SUCCESS; - } - - ret = do_edit(ldb, result->msgs, result->count, options->editor); - - talloc_free(mem_ctx); - - return ret == 0 ? LDB_SUCCESS : LDB_ERR_OPERATIONS_ERROR; -} diff --git a/ldb-2.0.8/tools/ldbmodify.c b/ldb-2.0.8/tools/ldbmodify.c deleted file mode 100644 index 9b4d7b7..0000000 --- a/ldb-2.0.8/tools/ldbmodify.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldbmodify - * - * Description: utility to modify records - modelled on ldapmodify - * - * Author: Andrew Tridgell - */ - -#include "replace.h" -#include "ldb.h" -#include "tools/cmdline.h" -#include "ldbutil.h" -#include "include/ldb_private.h" - -static struct ldb_cmdline *options; - -static void usage(struct ldb_context *ldb) -{ - printf("Usage: ldbmodify \n"); - printf("Modifies a ldb based upon ldif change records\n\n"); - ldb_cmdline_help(ldb, "ldbmodify", stdout); - exit(LDB_ERR_OPERATIONS_ERROR); -} - -/* - process modifies for one file -*/ -static int process_file(struct ldb_context *ldb, FILE *f, unsigned int *count) -{ - struct ldb_ldif *ldif; - int fun_ret = LDB_SUCCESS, ret; - struct ldb_control **req_ctrls = ldb_parse_control_strings(ldb, ldb, (const char **)options->controls); - struct ldif_read_file_state state = { - .f = f - }; - - if (options->controls != NULL && req_ctrls== NULL) { - printf("parsing controls failed: %s\n", ldb_errstring(ldb)); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - fun_ret = ldb_transaction_start(ldb); - if (fun_ret != LDB_SUCCESS) { - fprintf(stderr, "ERR: (%s) on transaction start\n", - ldb_errstring(ldb)); - return fun_ret; - } - - while ((ldif = ldb_ldif_read_file_state(ldb, &state))) { - struct ldb_dn *olddn; - bool deleteoldrdn = false; - struct ldb_dn *newdn; - const char *errstr = NULL; - - switch (ldif->changetype) { - case LDB_CHANGETYPE_NONE: - case LDB_CHANGETYPE_ADD: - ret = ldb_add_ctrl(ldb, ldif->msg,req_ctrls); - break; - case LDB_CHANGETYPE_DELETE: - ret = ldb_delete_ctrl(ldb, ldif->msg->dn,req_ctrls); - break; - case LDB_CHANGETYPE_MODIFY: - ret = ldb_modify_ctrl(ldb, ldif->msg,req_ctrls); - break; - case LDB_CHANGETYPE_MODRDN: - ret = ldb_ldif_parse_modrdn(ldb, ldif, ldif, &olddn, - NULL, &deleteoldrdn, - NULL, &newdn); - if (ret == LDB_SUCCESS) { - if (deleteoldrdn) { - ret = ldb_rename(ldb, olddn, newdn); - } else { - errstr = "modrdn: deleteoldrdn=0 " - "not supported."; - ret = LDB_ERR_CONSTRAINT_VIOLATION; - } - } - break; - } - if (ret != LDB_SUCCESS) { - if (errstr == NULL) { - errstr = ldb_errstring(ldb); - } - fprintf(stderr, "ERR: (%s) \"%s\" on DN %s at block before line %llu\n", - ldb_strerror(ret), - errstr, ldb_dn_get_linearized(ldif->msg->dn), - (unsigned long long)state.line_no); - fun_ret = ret; - } else { - (*count)++; - if (options->verbose) { - printf("Modified %s\n", ldb_dn_get_linearized(ldif->msg->dn)); - } - } - ldb_ldif_read_free(ldb, ldif); - if (ret) { - break; - } - } - - if (fun_ret == LDB_SUCCESS && !feof(f)) { - fprintf(stderr, "Failed to parse ldif\n"); - fun_ret = LDB_ERR_OPERATIONS_ERROR; - } - - if (fun_ret == LDB_SUCCESS) { - fun_ret = ldb_transaction_commit(ldb); - if (fun_ret != LDB_SUCCESS) { - fprintf(stderr, "ERR: (%s) on transaction commit\n", - ldb_errstring(ldb)); - } - } else { - ldb_transaction_cancel(ldb); - } - - return fun_ret; -} - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - unsigned int i, count = 0; - int ret = LDB_SUCCESS; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - - ldb = ldb_init(mem_ctx, NULL); - if (ldb == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - if (options->argc == 0) { - ret = process_file(ldb, stdin, &count); - } else { - for (i=0;iargc;i++) { - const char *fname = options->argv[i]; - FILE *f; - f = fopen(fname, "r"); - if (!f) { - perror(fname); - return LDB_ERR_OPERATIONS_ERROR; - } - ret = process_file(ldb, f, &count); - fclose(f); - } - } - - talloc_free(mem_ctx); - - if (ret) { - printf("Modify failed after processing %u records\n", count); - } else { - printf("Modified %u records successfully\n", count); - } - - return ret; -} diff --git a/ldb-2.0.8/tools/ldbrename.c b/ldb-2.0.8/tools/ldbrename.c deleted file mode 100644 index ab2be4d..0000000 --- a/ldb-2.0.8/tools/ldbrename.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Stefan Metzmacher 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldbrename - * - * Description: utility to rename records - modelled on ldapmodrdn - * - * Author: Andrew Tridgell - * Author: Stefan Metzmacher - */ - -#include "replace.h" -#include "ldb.h" -#include "tools/cmdline.h" - -static void usage(struct ldb_context *ldb) -{ - printf("Usage: ldbrename [] \n"); - printf("Renames records in a ldb\n\n"); - ldb_cmdline_help(ldb, "ldbmodify", stdout); - exit(LDB_ERR_OPERATIONS_ERROR); -} - - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - int ret; - struct ldb_cmdline *options; - struct ldb_dn *dn1, *dn2; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - - ldb = ldb_init(mem_ctx, NULL); - if (ldb == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - if (options->argc < 2) { - usage(ldb); - } - - dn1 = ldb_dn_new(ldb, ldb, options->argv[0]); - dn2 = ldb_dn_new(ldb, ldb, options->argv[1]); - if ((dn1 == NULL) || (dn2 == NULL)) { - return LDB_ERR_OPERATIONS_ERROR; - } - - ret = ldb_rename(ldb, dn1, dn2); - if (ret == LDB_SUCCESS) { - printf("Renamed 1 record\n"); - } else { - printf("rename of '%s' to '%s' failed - %s\n", - options->argv[0], options->argv[1], ldb_errstring(ldb)); - } - - talloc_free(mem_ctx); - - return ret; -} diff --git a/ldb-2.0.8/tools/ldbsearch.c b/ldb-2.0.8/tools/ldbsearch.c deleted file mode 100644 index 374f240..0000000 --- a/ldb-2.0.8/tools/ldbsearch.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldbsearch - * - * Description: utility for ldb search - modelled on ldapsearch - * - * Author: Andrew Tridgell - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb.h" -#include "tools/cmdline.h" - -static void usage(struct ldb_context *ldb) -{ - printf("Usage: ldbsearch \n"); - ldb_cmdline_help(ldb, "ldbsearch", stdout); - exit(LDB_ERR_OPERATIONS_ERROR); -} - -static int do_compare_msg(struct ldb_message **el1, - struct ldb_message **el2, - void *opaque) -{ - return ldb_dn_compare((*el1)->dn, (*el2)->dn); -} - -struct search_context { - struct ldb_context *ldb; - struct ldb_control **req_ctrls; - - int sort; - unsigned int num_stored; - struct ldb_message **store; - unsigned int refs_stored; - char **refs_store; - - unsigned int entries; - unsigned int refs; - - unsigned int pending; - int status; -}; - -static int store_message(struct ldb_message *msg, struct search_context *sctx) { - - sctx->store = talloc_realloc(sctx, sctx->store, struct ldb_message *, sctx->num_stored + 2); - if (!sctx->store) { - fprintf(stderr, "talloc_realloc failed while storing messages\n"); - return -1; - } - - sctx->store[sctx->num_stored] = talloc_move(sctx->store, &msg); - sctx->num_stored++; - sctx->store[sctx->num_stored] = NULL; - - return 0; -} - -static int store_referral(char *referral, struct search_context *sctx) { - - sctx->refs_store = talloc_realloc(sctx, sctx->refs_store, char *, sctx->refs_stored + 2); - if (!sctx->refs_store) { - fprintf(stderr, "talloc_realloc failed while storing referrals\n"); - return -1; - } - - sctx->refs_store[sctx->refs_stored] = talloc_move(sctx->refs_store, &referral); - sctx->refs_stored++; - sctx->refs_store[sctx->refs_stored] = NULL; - - return 0; -} - -static int display_message(struct ldb_message *msg, struct search_context *sctx) { - struct ldb_ldif ldif; - - sctx->entries++; - printf("# record %d\n", sctx->entries); - - ldif.changetype = LDB_CHANGETYPE_NONE; - ldif.msg = msg; - - if (sctx->sort) { - /* - * Ensure attributes are always returned in the same - * order. For testing, this makes comparison of old - * vs. new much easier. - */ - ldb_msg_sort_elements(ldif.msg); - } - - ldb_ldif_write_file(sctx->ldb, stdout, &ldif); - - return 0; -} - -static int display_referral(char *referral, struct search_context *sctx) -{ - - sctx->refs++; - printf("# Referral\nref: %s\n\n", referral); - - return 0; -} - -static int search_callback(struct ldb_request *req, struct ldb_reply *ares) -{ - struct search_context *sctx; - int ret = LDB_SUCCESS; - - sctx = talloc_get_type(req->context, struct search_context); - - if (!ares) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - if (ares->error != LDB_SUCCESS) { - return ldb_request_done(req, ares->error); - } - - switch (ares->type) { - case LDB_REPLY_ENTRY: - if (sctx->sort) { - ret = store_message(ares->message, sctx); - } else { - ret = display_message(ares->message, sctx); - } - break; - - case LDB_REPLY_REFERRAL: - if (sctx->sort) { - ret = store_referral(ares->referral, sctx); - } else { - ret = display_referral(ares->referral, sctx); - } - if (ret) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - break; - - case LDB_REPLY_DONE: - if (ares->controls) { - if (handle_controls_reply(ares->controls, sctx->req_ctrls) == 1) - sctx->pending = 1; - } - talloc_free(ares); - return ldb_request_done(req, LDB_SUCCESS); - } - - talloc_free(ares); - if (ret != LDB_SUCCESS) { - return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR); - } - - return LDB_SUCCESS; -} - -static int do_search(struct ldb_context *ldb, - struct ldb_dn *basedn, - struct ldb_cmdline *options, - const char *expression, - const char * const *attrs) -{ - struct ldb_request *req; - struct search_context *sctx; - int ret; - - req = NULL; - - sctx = talloc_zero(ldb, struct search_context); - if (!sctx) return LDB_ERR_OPERATIONS_ERROR; - - sctx->ldb = ldb; - sctx->sort = options->sorted; - sctx->req_ctrls = ldb_parse_control_strings(ldb, sctx, (const char **)options->controls); - if (options->controls != NULL && sctx->req_ctrls== NULL) { - printf("parsing controls failed: %s\n", ldb_errstring(ldb)); - return LDB_ERR_OPERATIONS_ERROR; - } - -again: - /* free any previous requests */ - if (req) talloc_free(req); - - ret = ldb_build_search_req(&req, ldb, ldb, - basedn, options->scope, - expression, attrs, - sctx->req_ctrls, - sctx, search_callback, - NULL); - if (ret != LDB_SUCCESS) { - talloc_free(sctx); - printf("allocating request failed: %s\n", ldb_errstring(ldb)); - return ret; - } - - if (basedn == NULL) { - /* - we need to use a NULL base DN when doing a cross-ncs - search so we find results on all partitions in a - forest. When doing a domain-local search, default to - the default basedn - */ - struct ldb_control *ctrl; - struct ldb_search_options_control *search_options = NULL; - - ctrl = ldb_request_get_control(req, LDB_CONTROL_SEARCH_OPTIONS_OID); - if (ctrl) { - search_options = talloc_get_type(ctrl->data, struct ldb_search_options_control); - } - - if (ctrl == NULL || search_options == NULL || - !(search_options->search_options & LDB_SEARCH_OPTION_PHANTOM_ROOT)) { - struct ldb_dn *base = ldb_get_default_basedn(ldb); - if (base != NULL) { - req->op.search.base = base; - } - } - } - - sctx->pending = 0; - - ret = ldb_request(ldb, req); - if (ret != LDB_SUCCESS) { - talloc_free(sctx); - talloc_free(req); - printf("search failed - %s\n", ldb_errstring(ldb)); - return ret; - } - - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - if (ret != LDB_SUCCESS) { - talloc_free(sctx); - talloc_free(req); - printf("search error - %s\n", ldb_errstring(ldb)); - return ret; - } - - if (sctx->pending) - goto again; - - if (sctx->sort && (sctx->num_stored != 0 || sctx->refs != 0)) { - unsigned int i; - - if (sctx->num_stored) { - LDB_TYPESAFE_QSORT(sctx->store, sctx->num_stored, ldb, do_compare_msg); - } - for (i = 0; i < sctx->num_stored; i++) { - display_message(sctx->store[i], sctx); - } - - for (i = 0; i < sctx->refs_stored; i++) { - display_referral(sctx->refs_store[i], sctx); - } - } - - printf("# returned %u records\n# %u entries\n# %u referrals\n", - sctx->entries + sctx->refs, sctx->entries, sctx->refs); - - talloc_free(sctx); - talloc_free(req); - - return LDB_SUCCESS; -} - -int main(int argc, const char **argv) -{ - struct ldb_context *ldb; - struct ldb_dn *basedn = NULL; - const char * const * attrs = NULL; - struct ldb_cmdline *options; - int ret = -1; - const char *expression = "(|(objectClass=*)(distinguishedName=*))"; - TALLOC_CTX *mem_ctx = talloc_new(NULL); - - ldb = ldb_init(mem_ctx, NULL); - if (ldb == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - options = ldb_cmdline_process_search(ldb, argc, argv, usage); - - /* the check for '=' is for compatibility with ldapsearch */ - if (!options->interactive && - options->argc > 0 && - strpbrk(options->argv[0], "=<>~:")) { - expression = options->argv[0]; - options->argv++; - options->argc--; - } - - if (options->argc > 0) { - attrs = (const char * const *)(options->argv); - } - - if (options->basedn != NULL) { - basedn = ldb_dn_new(ldb, ldb, options->basedn); - if (basedn == NULL) { - talloc_free(mem_ctx); - return LDB_ERR_OPERATIONS_ERROR; - } - } - - if (options->interactive) { - char line[1024]; - while (fgets(line, sizeof(line), stdin)) { - ret = do_search(ldb, basedn, options, line, attrs); - } - } else { - ret = do_search(ldb, basedn, options, expression, attrs); - } - - talloc_free(mem_ctx); - - return ret; -} diff --git a/ldb-2.0.8/tools/ldbtest.c b/ldb-2.0.8/tools/ldbtest.c deleted file mode 100644 index 64b6baa..0000000 --- a/ldb-2.0.8/tools/ldbtest.c +++ /dev/null @@ -1,438 +0,0 @@ -/* - ldb database library - - Copyright (C) Andrew Tridgell 2004 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Component: ldbtest - * - * Description: utility to test ldb - * - * Author: Andrew Tridgell - */ - -#include "replace.h" -#include "system/filesys.h" -#include "system/time.h" -#include "ldb.h" -#include "tools/cmdline.h" - -static struct timespec tp1,tp2; -static struct ldb_cmdline *options; - -static void _start_timer(void) -{ - if (clock_gettime(CUSTOM_CLOCK_MONOTONIC, &tp1) != 0) { - clock_gettime(CLOCK_REALTIME, &tp1); - } -} - -static double _end_timer(void) -{ - if (clock_gettime(CUSTOM_CLOCK_MONOTONIC, &tp2) != 0) { - clock_gettime(CLOCK_REALTIME, &tp2); - } - return((tp2.tv_sec - tp1.tv_sec) + - (tp2.tv_nsec - tp1.tv_nsec)*1.0e-9); -} - -static void add_records(struct ldb_context *ldb, - struct ldb_dn *basedn, - unsigned int count) -{ - struct ldb_message msg = {0}; - unsigned int i; - -#if 0 - if (ldb_lock(ldb, "transaction") != 0) { - printf("transaction lock failed\n"); - exit(LDB_ERR_OPERATIONS_ERROR); - } -#endif - for (i=0;icount != 1)) { - printf("Failed to find %s - %s\n", expr, ldb_errstring(ldb)); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - if (uid >= nrecords && res->count > 0) { - printf("Found %s !? - %d\n", expr, ret); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - printf("Testing uid %d/%d - %d \r", i, uid, res->count); - fflush(stdout); - - talloc_free(res); - talloc_free(expr); - } - - printf("\n"); -} - -static void start_test(struct ldb_context *ldb, unsigned int nrecords, - unsigned int nsearches) -{ - struct ldb_dn *basedn; - - basedn = ldb_dn_new(ldb, ldb, options->basedn); - if ( ! ldb_dn_validate(basedn)) { - printf("Invalid base DN format\n"); - exit(LDB_ERR_INVALID_DN_SYNTAX); - } - - printf("Adding %d records\n", nrecords); - add_records(ldb, basedn, nrecords); - - printf("Starting search on uid\n"); - _start_timer(); - search_uid(ldb, basedn, nrecords, nsearches); - printf("uid search took %.2f seconds\n", _end_timer()); - - printf("Modifying records\n"); - modify_records(ldb, basedn, nrecords); - - printf("Deleting records\n"); - delete_records(ldb, basedn, nrecords); -} - - -/* - 2) Store an @indexlist record - - 3) Store a record that contains fields that should be index according -to @index - - 4) disconnection from database - - 5) connect to same database - - 6) search for record added in step 3 using a search key that should -be indexed -*/ -static void start_test_index(struct ldb_context **ldb) -{ - struct ldb_message *msg; - struct ldb_result *res = NULL; - struct ldb_dn *indexlist; - struct ldb_dn *basedn; - int ret; - unsigned int flags = 0; - const char *specials; - - specials = getenv("LDB_SPECIALS"); - if (specials && atoi(specials) == 0) { - printf("LDB_SPECIALS disabled - skipping index test\n"); - return; - } - - if (options->nosync) { - flags |= LDB_FLG_NOSYNC; - } - - printf("Starting index test\n"); - - indexlist = ldb_dn_new(*ldb, *ldb, "@INDEXLIST"); - - ldb_delete(*ldb, indexlist); - - msg = ldb_msg_new(NULL); - if (msg == NULL) { - printf("ldb_msg_new failed\n"); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - msg->dn = indexlist; - ldb_msg_add_string(msg, "@IDXATTR", strdup("uid")); - - if (ldb_add(*ldb, msg) != 0) { - printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb)); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - basedn = ldb_dn_new(*ldb, *ldb, options->basedn); - - memset(msg, 0, sizeof(*msg)); - msg->dn = ldb_dn_copy(msg, basedn); - ldb_dn_add_child_fmt(msg->dn, "cn=test"); - ldb_msg_add_string(msg, "cn", strdup("test")); - ldb_msg_add_string(msg, "sn", strdup("test")); - ldb_msg_add_string(msg, "uid", strdup("test")); - ldb_msg_add_string(msg, "objectClass", strdup("OpenLDAPperson")); - - if (ldb_add(*ldb, msg) != LDB_SUCCESS) { - printf("Add of %s failed - %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(*ldb)); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - if (talloc_free(*ldb) != 0) { - printf("failed to free/close ldb database"); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - (*ldb) = ldb_init(options, NULL); - - ret = ldb_connect(*ldb, options->url, flags, NULL); - if (ret != LDB_SUCCESS) { - printf("failed to connect to %s\n", options->url); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - basedn = ldb_dn_new(*ldb, *ldb, options->basedn); - msg->dn = basedn; - ldb_dn_add_child_fmt(msg->dn, "cn=test"); - - ret = ldb_search(*ldb, *ldb, &res, basedn, LDB_SCOPE_SUBTREE, NULL, "uid=test"); - if (ret != LDB_SUCCESS) { - printf("Search with (uid=test) filter failed!\n"); - exit(LDB_ERR_OPERATIONS_ERROR); - } - if(res->count != 1) { - printf("Should have found 1 record - found %d\n", res->count); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - indexlist = ldb_dn_new(*ldb, *ldb, "@INDEXLIST"); - - if (ldb_delete(*ldb, msg->dn) != 0 || - ldb_delete(*ldb, indexlist) != 0) { - printf("cleanup failed - %s\n", ldb_errstring(*ldb)); - exit(LDB_ERR_OPERATIONS_ERROR); - } - - printf("Finished index test\n"); -} - - -static void usage(struct ldb_context *ldb) -{ - printf("Usage: ldbtest \n"); - printf("Options:\n"); - printf(" -H ldb_url choose the database (or $LDB_URL)\n"); - printf(" --num-records nrecords database size to use\n"); - printf(" --num-searches nsearches number of searches to do\n"); - printf("\n"); - printf("tests ldb API\n\n"); - exit(LDB_ERR_OPERATIONS_ERROR); -} - -int main(int argc, const char **argv) -{ - TALLOC_CTX *mem_ctx = talloc_new(NULL); - struct ldb_context *ldb; - - ldb = ldb_init(mem_ctx, NULL); - if (ldb == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - - options = ldb_cmdline_process(ldb, argc, argv, usage); - - talloc_steal(mem_ctx, options); - - if (options->basedn == NULL) { - options->basedn = "ou=Ldb Test,ou=People,o=University of Michigan,c=TEST"; - } - - srandom(1); - - printf("Testing with num-records=%d and num-searches=%d\n", - options->num_records, options->num_searches); - - start_test(ldb, - (unsigned int) options->num_records, - (unsigned int) options->num_searches); - - start_test_index(&ldb); - - talloc_free(mem_ctx); - - return LDB_SUCCESS; -} diff --git a/ldb-2.0.8/tools/ldbutil.c b/ldb-2.0.8/tools/ldbutil.c deleted file mode 100644 index 9ff7fad..0000000 --- a/ldb-2.0.8/tools/ldbutil.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - ldb database library utility - - Copyright (C) Matthieu Patou 2009 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Description: Common function used by ldb_add/ldb_modify/ldb_delete - * - * Author: Matthieu Patou - */ - -#include "replace.h" -#include "ldb.h" -#include "ldb_module.h" -#include "ldbutil.h" - - -/* autostarts a transacion if none active */ -static int ldb_do_autotransaction(struct ldb_context *ldb, - struct ldb_request *req) -{ - int ret; - - ret = ldb_transaction_start(ldb); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_request(ldb, req); - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - - if (ret == LDB_SUCCESS) { - return ldb_transaction_commit(ldb); - } - ldb_transaction_cancel(ldb); - - if (ldb_errstring(ldb) == NULL) { - /* no error string was setup by the backend */ - ldb_asprintf_errstring(ldb, "%s (%d)", ldb_strerror(ret), ret); - } - - return ret; -} -/* - Same as ldb_add but accept control -*/ -int ldb_add_ctrl(struct ldb_context *ldb, - const struct ldb_message *message, - struct ldb_control **controls) -{ - struct ldb_request *req; - int ret; - - ret = ldb_msg_sanity_check(ldb, message); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_build_add_req(&req, ldb, ldb, - message, - controls, - NULL, - ldb_op_default_callback, - NULL); - - if (ret != LDB_SUCCESS) return ret; - - /* do request and autostart a transaction */ - ret = ldb_do_autotransaction(ldb, req); - - talloc_free(req); - return ret; -} - -/* - same as ldb_delete but accept control -*/ -int ldb_delete_ctrl(struct ldb_context *ldb, struct ldb_dn *dn, - struct ldb_control **controls) -{ - struct ldb_request *req; - int ret; - - ret = ldb_build_del_req(&req, ldb, ldb, - dn, - controls, - NULL, - ldb_op_default_callback, - NULL); - - if (ret != LDB_SUCCESS) return ret; - - /* do request and autostart a transaction */ - ret = ldb_do_autotransaction(ldb, req); - - talloc_free(req); - return ret; -} - - -/* - same as ldb_modify, but accepts controls -*/ -int ldb_modify_ctrl(struct ldb_context *ldb, - const struct ldb_message *message, - struct ldb_control **controls) -{ - struct ldb_request *req; - int ret; - - ret = ldb_msg_sanity_check(ldb, message); - if (ret != LDB_SUCCESS) { - return ret; - } - - ret = ldb_build_mod_req(&req, ldb, ldb, - message, - controls, - NULL, - ldb_op_default_callback, - NULL); - - if (ret != LDB_SUCCESS) return ret; - - /* do request and autostart a transaction */ - ret = ldb_do_autotransaction(ldb, req); - - talloc_free(req); - return ret; -} - - -/* - ldb_search with controls -*/ -int ldb_search_ctrl(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - struct ldb_result **result, struct ldb_dn *base, - enum ldb_scope scope, const char * const *attrs, - struct ldb_control **controls, - const char *exp_fmt, ...) -{ - struct ldb_request *req; - struct ldb_result *res; - char *expression; - va_list ap; - int ret; - - expression = NULL; - *result = NULL; - req = NULL; - - res = talloc_zero(mem_ctx, struct ldb_result); - if (!res) { - return LDB_ERR_OPERATIONS_ERROR; - } - - if (exp_fmt) { - va_start(ap, exp_fmt); - expression = talloc_vasprintf(mem_ctx, exp_fmt, ap); - va_end(ap); - - if (!expression) { - talloc_free(res); - return LDB_ERR_OPERATIONS_ERROR; - } - } - - ret = ldb_build_search_req(&req, ldb, mem_ctx, - base?base:ldb_get_default_basedn(ldb), - scope, - expression, - attrs, - controls, - res, - ldb_search_default_callback, - NULL); - ldb_req_set_location(req, "ldb_search_ctrl"); - - if (ret != LDB_SUCCESS) goto done; - - ret = ldb_request(ldb, req); - - if (ret == LDB_SUCCESS) { - ret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - -done: - if (ret != LDB_SUCCESS) { - talloc_free(res); - res = NULL; - } - - talloc_free(expression); - talloc_free(req); - - *result = res; - return ret; -} diff --git a/ldb-2.0.8/tools/ldbutil.h b/ldb-2.0.8/tools/ldbutil.h deleted file mode 100644 index 6723863..0000000 --- a/ldb-2.0.8/tools/ldbutil.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - ldb database library utility header file - - Copyright (C) Matthieu Patou 2009 - - ** NOTE! The following LGPL license applies to the ldb - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -/* - * Name: ldb - * - * Description: Common function used by ldb_add/ldb_modify/ldb_delete - * - * Author: Matthieu Patou - */ - -#include "ldb.h" - -int ldb_add_ctrl(struct ldb_context *ldb, - const struct ldb_message *message, - struct ldb_control **controls); -int ldb_delete_ctrl(struct ldb_context *ldb, struct ldb_dn *dn, - struct ldb_control **controls); -int ldb_modify_ctrl(struct ldb_context *ldb, - const struct ldb_message *message, - struct ldb_control **controls); -int ldb_search_ctrl(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, - struct ldb_result **result, struct ldb_dn *base, - enum ldb_scope scope, const char * const *attrs, - struct ldb_control **controls, - const char *exp_fmt, ...) PRINTF_ATTRIBUTE(8,9); diff --git a/ldb-2.0.8/web/index.html b/ldb-2.0.8/web/index.html deleted file mode 100644 index 7f50cdc..0000000 --- a/ldb-2.0.8/web/index.html +++ /dev/null @@ -1,74 +0,0 @@ - - - -ldb - - - -

      ldb

      - -ldb is a LDAP-like embedded database. It is not at all -LDAP -standards compliant, so if you want a standards compliant database then please -see the excellent OpenLDAP -project.

      - -What ldb does is provide a fast database with an LDAP-like API -designed to be used within an application. In some ways it can be seen -as a intermediate solution between key-value pair databases and a real -LDAP database.

      - -ldb is the database engine used in Samba4. - -

      Features

      - -The main features that separate ldb from other solutions are: - -
        -
      • Safe multi-reader, multi-writer, using byte range locking -
      • LDAP-like API -
      • fast operation -
      • choice of local tdb or remote LDAP backends -
      • integration with talloc -
      • schema-less operation, for trivial setup -
      • modules for extensions (such as schema support) -
      • easy setup of indexes and attribute properties -
      • LDIF for import/export -
      • ldbedit tool for database (via LDIF) editing (reminiscent of 'vipw') -
      - -

      Documentation

      - -Currently ldb is completely lacking in programmer or user -documentation. This is your opportunity to make a contribution! Start -with the public functions declared in ldb.h -and the example code in the tools -directory. Documentation in the same docbook format used by Samba -would be preferred. - -

      Discussion and bug reports

      - -ldb does not have its own mailing list or bug tracking system. Please -use -the samba-technical -mailing list, and the Samba -bugzilla bug tracking system. - -

      Download

      - -You can download the latest release here:
      - http://samba.org/ftp/pub/ldb - -Alternatively, you can fetch via git. See the following guide:
      -Using Git for Samba Development
      - -
      - -Andrew Tridgell
      -ldb AT tridgell.net -
      - - - diff --git a/ldb-2.0.8/wscript b/ldb-2.0.8/wscript deleted file mode 100644 index 5b5c42d..0000000 --- a/ldb-2.0.8/wscript +++ /dev/null @@ -1,650 +0,0 @@ -#!/usr/bin/env python - -APPNAME = 'ldb' -VERSION = '2.0.8' - -import sys, os - -# find the buildtools directory -top = '.' -while not os.path.exists(top+'/buildtools') and len(top.split('/')) < 5: - top = top + '/..' -sys.path.insert(0, top + '/buildtools/wafsamba') - -out = 'bin' - -import wafsamba -from wafsamba import samba_dist, samba_utils -from waflib import Errors, Options, Logs, Context -import shutil - -samba_dist.DIST_DIRS('''lib/ldb:. lib/replace:lib/replace lib/talloc:lib/talloc - lib/tdb:lib/tdb lib/tdb:lib/tdb lib/tevent:lib/tevent - third_party/popt:third_party/popt - third_party/cmocka:third_party/cmocka - buildtools:buildtools third_party/waf:third_party/waf''') - -samba_dist.DIST_FILES('''lib/util/binsearch.h:lib/util/binsearch.h - lib/util/attr.h:lib/util/attr.h''') - -def options(opt): - opt.BUILTIN_DEFAULT('replace') - opt.PRIVATE_EXTENSION_DEFAULT('ldb', noextension='ldb') - opt.RECURSE('lib/tdb') - opt.RECURSE('lib/tevent') - opt.RECURSE('lib/replace') - opt.load('python') # options for disabling pyc or pyo compilation - - opt.add_option('--without-ldb-lmdb', - help='disable new LMDB backend for LDB', - action='store_true', dest='without_ldb_lmdb', default=False) - - -def configure(conf): - conf.RECURSE('lib/tdb') - conf.RECURSE('lib/tevent') - - if conf.CHECK_FOR_THIRD_PARTY(): - conf.RECURSE('third_party/popt') - conf.RECURSE('third_party/cmocka') - else: - if not conf.CHECK_POPT(): - raise Errors.WafError('popt development packages have not been found.\nIf third_party is installed, check that it is in the proper place.') - else: - conf.define('USING_SYSTEM_POPT', 1) - - if not conf.CHECK_CMOCKA(): - raise Errors.WafError('cmocka development package have not been found.\nIf third_party is installed, check that it is in the proper place.') - else: - conf.define('USING_SYSTEM_CMOCKA', 1) - - conf.RECURSE('lib/replace') - conf.find_program('xsltproc', var='XSLTPROC') - conf.SAMBA_CHECK_PYTHON() - conf.SAMBA_CHECK_PYTHON_HEADERS() - - # where does the default LIBDIR end up? in conf.env somewhere? - # - conf.CONFIG_PATH('LDB_MODULESDIR', conf.SUBST_ENV_VAR('MODULESDIR') + '/ldb') - - conf.env.standalone_ldb = conf.IN_LAUNCH_DIR() - - if not conf.env.standalone_ldb: - max_ldb_version = [int(x) for x in VERSION.split(".")] - max_ldb_version[2] = 999 - max_ldb_version_dots = "%d.%d.%d" % tuple(max_ldb_version) - - if conf.env.disable_python: - if conf.CHECK_BUNDLED_SYSTEM_PKG('ldb', - minversion=VERSION, - maxversion=max_ldb_version_dots, - onlyif='talloc tdb tevent', - implied_deps='replace talloc tdb tevent'): - conf.define('USING_SYSTEM_LDB', 1) - else: - using_system_pyldb_util = True - dflt_name = 'pyldb-util' + conf.all_envs['default']['PYTHON_SO_ABI_FLAG'] - if not conf.CHECK_BUNDLED_SYSTEM_PKG(dflt_name, - minversion=VERSION, - maxversion=max_ldb_version_dots, - onlyif='talloc tdb tevent', - implied_deps='replace talloc tdb tevent ldb'): - using_system_pyldb_util = False - - if using_system_pyldb_util: - conf.define('USING_SYSTEM_PYLDB_UTIL', 1) - - if conf.CHECK_BUNDLED_SYSTEM_PKG('ldb', - minversion=VERSION, - maxversion=max_ldb_version_dots, - onlyif='talloc tdb tevent %s' % dflt_name, - implied_deps='replace talloc tdb tevent'): - conf.define('USING_SYSTEM_LDB', 1) - - if not conf.CHECK_CODE('return !(sizeof(size_t) >= 8)', - "HAVE_64_BIT_SIZE_T_FOR_LMDB", - execute=True, - msg='Checking for a 64-bit host to ' - 'support lmdb'): - Logs.warn("--without-ldb-lmdb implied as this " - "host is not 64-bit") - - if not conf.env.standalone_ldb and \ - not Options.options.without_ad_dc and \ - conf.CONFIG_GET('ENABLE_SELFTEST'): - Logs.warn("NOTE: Some AD DC parts of selftest will fail") - - conf.env.REQUIRE_LMDB = False - else: - if conf.env.standalone_ldb: - if Options.options.without_ldb_lmdb: - conf.env.REQUIRE_LMDB = False - else: - conf.env.REQUIRE_LMDB = True - elif Options.options.without_ad_dc: - conf.env.REQUIRE_LMDB = False - else: - if Options.options.without_ldb_lmdb: - if not Options.options.without_ad_dc and \ - conf.CONFIG_GET('ENABLE_SELFTEST'): - raise Errors.WafError('--without-ldb-lmdb conflicts ' - 'with --enable-selftest while ' - 'building the AD DC') - - conf.env.REQUIRE_LMDB = False - else: - conf.env.REQUIRE_LMDB = True - - - if conf.CONFIG_SET('USING_SYSTEM_LDB'): - v = VERSION.split('.') - conf.DEFINE('EXPECTED_SYSTEM_LDB_VERSION_MAJOR', int(v[0])) - conf.DEFINE('EXPECTED_SYSTEM_LDB_VERSION_MINOR', int(v[1])) - conf.DEFINE('EXPECTED_SYSTEM_LDB_VERSION_RELEASE', int(v[2])) - - if conf.env.standalone_ldb: - conf.CHECK_XSLTPROC_MANPAGES() - - # we need this for the ldap backend - if conf.CHECK_FUNCS_IN('ber_flush ldap_open ldap_initialize', 'lber ldap', headers='lber.h ldap.h'): - conf.env.ENABLE_LDAP_BACKEND = True - - # we don't want any libraries or modules to rely on runtime - # resolution of symbols - if not sys.platform.startswith("openbsd"): - conf.ADD_LDFLAGS('-Wl,-no-undefined', testflags=True) - - # if lmdb support is enabled then we require lmdb - # is present, build the mdb back end and enable lmdb support in - # the tools. - if conf.env.REQUIRE_LMDB and \ - not conf.CONFIG_SET('USING_SYSTEM_LDB'): - if not conf.CHECK_CFG(package='lmdb', - args='"lmdb >= 0.9.16" --cflags --libs', - msg='Checking for lmdb >= 0.9.16', - mandatory=False): - if not conf.CHECK_CODE(''' - #if MDB_VERSION_MAJOR == 0 \ - && MDB_VERSION_MINOR <= 9 \ - && MDB_VERSION_PATCH < 16 - #error LMDB too old - #endif - ''', - 'HAVE_GOOD_LMDB_VERSION', - headers='lmdb.h', - msg='Checking for lmdb >= 0.9.16 via header check'): - - if conf.env.standalone_ldb: - raise Errors.WafError('ldb build (unless --without-ldb-lmdb) ' - 'requires ' - 'lmdb 0.9.16 or later') - elif not Options.options.without_ad_dc: - raise Errors.WafError('Samba AD DC and --enable-selftest ' - 'requires ' - 'lmdb 0.9.16 or later') - - if conf.CHECK_FUNCS_IN('mdb_env_create', 'lmdb', headers='lmdb.h'): - conf.DEFINE('HAVE_LMDB', '1') - conf.env.HAVE_LMDB = True - - - conf.DEFINE('HAVE_CONFIG_H', 1, add_to_cflags=True) - - conf.SAMBA_CONFIG_H() - - conf.SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS() - -def build(bld): - bld.RECURSE('lib/tevent') - - if bld.CHECK_FOR_THIRD_PARTY(): - bld.RECURSE('third_party/popt') - bld.RECURSE('third_party/cmocka') - - bld.RECURSE('lib/replace') - bld.RECURSE('lib/tdb') - - if bld.env.standalone_ldb: - if not 'PACKAGE_VERSION' in bld.env: - bld.env.PACKAGE_VERSION = VERSION - bld.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig' - private_library = False - else: - private_library = True - # we're not currently linking against the ldap libs, but ldb.pc.in - # has @LDAP_LIBS@ - bld.env.LDAP_LIBS = '' - - LDB_MAP_SRC = bld.SUBDIR('ldb_map', - 'ldb_map.c ldb_map_inbound.c ldb_map_outbound.c') - - COMMON_SRC = bld.SUBDIR('common', - '''ldb_modules.c ldb_ldif.c ldb_parse.c ldb_msg.c ldb_utf8.c - ldb_debug.c ldb_dn.c ldb_match.c ldb_options.c ldb_pack.c - ldb_attributes.c attrib_handlers.c ldb_controls.c qsort.c''') - - bld.SAMBA_MODULE('ldb_ldap', 'ldb_ldap/ldb_ldap.c', - init_function='ldb_ldap_init', - module_init_name='ldb_init_module', - deps='talloc lber ldap ldb', - enabled=bld.env.ENABLE_LDAP_BACKEND, - internal_module=False, - subsystem='ldb') - - if bld.PYTHON_BUILD_IS_ENABLED(): - if not bld.CONFIG_SET('USING_SYSTEM_PYLDB_UTIL'): - name = bld.pyembed_libname('pyldb-util') - bld.SAMBA_LIBRARY(name, - deps='replace ldb', - source='pyldb_util.c', - public_headers=('' if private_library else 'pyldb.h'), - public_headers_install=not private_library, - vnum=VERSION, - private_library=private_library, - pc_files='pyldb-util.pc', - pyembed=True, - enabled=bld.PYTHON_BUILD_IS_ENABLED(), - abi_directory='ABI', - abi_match='pyldb_*') - - if not bld.CONFIG_SET('USING_SYSTEM_LDB'): - bld.SAMBA_PYTHON('pyldb', 'pyldb.c', - deps='replace ldb ' + name, - realname='ldb.so', - cflags='-DPACKAGE_VERSION=\"%s\"' % VERSION) - - # Do only install this file as part of the Samba build if we do not - # use the system libldb! - if not bld.CONFIG_SET('USING_SYSTEM_PYLDB_UTIL'): - bld.SAMBA_SCRIPT('_ldb_text.py', - pattern='_ldb_text.py', - installdir='python') - - bld.INSTALL_FILES('${PYTHONARCHDIR}', '_ldb_text.py') - - if not bld.CONFIG_SET('USING_SYSTEM_LDB'): - if bld.is_install: - modules_dir = bld.EXPAND_VARIABLES('${LDB_MODULESDIR}') - else: - # when we run from the source directory, we want to use - # the current modules, not the installed ones - modules_dir = os.path.join(os.getcwd(), 'bin/modules/ldb') - - abi_match = '!ldb_*module_ops !ldb_*backend_ops ldb_*' - - ldb_headers = ('include/ldb.h include/ldb_errors.h ' - 'include/ldb_module.h include/ldb_handlers.h') - - bld.SAMBA_LIBRARY('ldb', - COMMON_SRC + ' ' + LDB_MAP_SRC, - deps='tevent LIBLDB_MAIN replace', - includes='include', - public_headers=('' if private_library else ldb_headers), - public_headers_install=not private_library, - pc_files='ldb.pc', - vnum=VERSION, - private_library=private_library, - manpages='man/ldb.3', - abi_directory='ABI', - abi_match = abi_match) - - # generate a include/ldb_version.h - def generate_ldb_version_h(t): - '''generate a vscript file for our public libraries''' - - tgt = t.outputs[0].bldpath(t.env) - - v = t.env.LDB_VERSION.split('.') - - f = open(tgt, mode='w') - try: - f.write('#define LDB_VERSION "%s"\n' % t.env.LDB_VERSION) - f.write('#define LDB_VERSION_MAJOR %d\n' % int(v[0])) - f.write('#define LDB_VERSION_MINOR %d\n' % int(v[1])) - f.write('#define LDB_VERSION_RELEASE %d\n' % int(v[2])) - finally: - f.close() - return - t = bld.SAMBA_GENERATOR('ldb_version.h', - rule=generate_ldb_version_h, - dep_vars=['LDB_VERSION'], - target='include/ldb_version.h', - public_headers='include/ldb_version.h', - public_headers_install=not private_library) - t.env.LDB_VERSION = VERSION - - bld.SAMBA_MODULE('ldb_asq', - 'modules/asq.c', - init_function='ldb_asq_init', - module_init_name='ldb_init_module', - internal_module=False, - deps='ldb', - subsystem='ldb') - - bld.SAMBA_MODULE('ldb_server_sort', - 'modules/sort.c', - init_function='ldb_server_sort_init', - internal_module=False, - module_init_name='ldb_init_module', - deps='ldb', - subsystem='ldb') - - bld.SAMBA_MODULE('ldb_paged_searches', - 'modules/paged_searches.c', - init_function='ldb_paged_searches_init', - internal_module=False, - module_init_name='ldb_init_module', - deps='ldb', - subsystem='ldb') - - bld.SAMBA_MODULE('ldb_rdn_name', - 'modules/rdn_name.c', - init_function='ldb_rdn_name_init', - internal_module=False, - module_init_name='ldb_init_module', - deps='ldb', - subsystem='ldb') - - bld.SAMBA_MODULE('ldb_sample', - 'tests/sample_module.c', - init_function='ldb_sample_init', - internal_module=False, - module_init_name='ldb_init_module', - deps='ldb', - subsystem='ldb') - - bld.SAMBA_MODULE('ldb_skel', - 'modules/skel.c', - init_function='ldb_skel_init', - internal_module=False, - module_init_name='ldb_init_module', - deps='ldb', - subsystem='ldb') - - bld.SAMBA_MODULE('ldb_sqlite3', - 'sqlite3/ldb_sqlite3.c', - init_function='ldb_sqlite3_init', - internal_module=False, - module_init_name='ldb_init_module', - enabled=False, - deps='ldb', - subsystem='ldb') - - bld.SAMBA_MODULE('ldb_tdb', - bld.SUBDIR('ldb_tdb', - '''ldb_tdb_init.c'''), - init_function='ldb_tdb_init', - module_init_name='ldb_init_module', - internal_module=False, - deps='ldb ldb_tdb_int ldb_key_value', - subsystem='ldb') - - bld.SAMBA_LIBRARY('ldb_tdb_int', - bld.SUBDIR('ldb_tdb', - '''ldb_tdb_wrap.c ldb_tdb.c'''), - private_library=True, - deps='ldb tdb ldb_key_value ldb_tdb_err_map') - - bld.SAMBA_LIBRARY('ldb_tdb_err_map', - bld.SUBDIR('ldb_tdb', - '''ldb_tdb_err_map.c '''), - private_library=True, - deps='ldb tdb') - - bld.SAMBA_LIBRARY('ldb_key_value', - bld.SUBDIR('ldb_key_value', - '''ldb_kv.c ldb_kv_search.c ldb_kv_index.c - ldb_kv_cache.c'''), - private_library=True, - deps='tdb ldb ldb_tdb_err_map') - - if bld.CONFIG_SET('HAVE_LMDB'): - bld.SAMBA_MODULE('ldb_mdb', - bld.SUBDIR('ldb_mdb', - '''ldb_mdb_init.c'''), - init_function='ldb_mdb_init', - module_init_name='ldb_init_module', - internal_module=False, - deps='ldb ldb_key_value ldb_mdb_int', - subsystem='ldb') - - bld.SAMBA_LIBRARY('ldb_mdb_int', - bld.SUBDIR('ldb_mdb', - '''ldb_mdb.c '''), - private_library=True, - deps='ldb lmdb ldb_key_value') - lmdb_deps = ' ldb_mdb_int' - else: - lmdb_deps = '' - - - bld.SAMBA_MODULE('ldb_ldb', - bld.SUBDIR('ldb_ldb', - '''ldb_ldb.c'''), - init_function='ldb_ldb_init', - module_init_name='ldb_init_module', - internal_module=False, - deps='ldb ldb_tdb_int ldb_key_value' + lmdb_deps, - subsystem='ldb') - - # have a separate subsystem for common/ldb.c, so it can rebuild - # for install with a different -DLDB_MODULESDIR= - bld.SAMBA_SUBSYSTEM('LIBLDB_MAIN', - 'common/ldb.c', - deps='tevent tdb', - includes='include', - cflags=['-DLDB_MODULESDIR=\"%s\"' % modules_dir]) - - LDB_TOOLS='ldbadd ldbsearch ldbdel ldbmodify ldbedit ldbrename' - for t in LDB_TOOLS.split(): - bld.SAMBA_BINARY(t, 'tools/%s.c' % t, deps='ldb-cmdline ldb', - manpages='man/%s.1' % t) - - # ldbtest doesn't get installed - bld.SAMBA_BINARY('ldbtest', 'tools/ldbtest.c', deps='ldb-cmdline ldb', - install=False) - - if bld.CONFIG_SET('HAVE_LMDB'): - lmdb_deps = ' lmdb' - else: - lmdb_deps = '' - # ldbdump doesn't get installed - bld.SAMBA_BINARY('ldbdump', - 'tools/ldbdump.c', - deps='ldb-cmdline ldb' + lmdb_deps, - install=False) - - bld.SAMBA_LIBRARY('ldb-cmdline', - source='tools/ldbutil.c tools/cmdline.c', - deps='ldb dl popt', - private_library=True) - - bld.SAMBA_BINARY('ldb_tdb_mod_op_test', - source='tests/ldb_mod_op_test.c', - cflags='-DTEST_BE=\"tdb\"', - deps='cmocka ldb', - install=False) - - bld.SAMBA_BINARY('ldb_tdb_guid_mod_op_test', - source='tests/ldb_mod_op_test.c', - cflags='-DTEST_BE=\"tdb\" -DGUID_IDX=1', - deps='cmocka ldb', - install=False) - - bld.SAMBA_BINARY('ldb_tdb_kv_ops_test', - source='tests/ldb_kv_ops_test.c', - cflags='-DTEST_BE=\"tdb\"', - deps='cmocka ldb', - install=False) - - bld.SAMBA_BINARY('ldb_tdb_test', - source='tests/ldb_tdb_test.c', - deps='cmocka ldb', - install=False) - - bld.SAMBA_BINARY('ldb_msg_test', - source='tests/ldb_msg.c', - deps='cmocka ldb', - install=False) - - bld.SAMBA_BINARY('test_ldb_qsort', - source='tests/test_ldb_qsort.c', - deps='cmocka ldb', - install=False) - - bld.SAMBA_BINARY('test_ldb_dn', - source='tests/test_ldb_dn.c', - deps='cmocka ldb', - install=False) - - bld.SAMBA_BINARY('ldb_match_test', - source='tests/ldb_match_test.c', - deps='cmocka ldb', - install=False) - - bld.SAMBA_BINARY('ldb_key_value_test', - source='tests/ldb_key_value_test.c', - deps='cmocka ldb ldb_tdb_err_map', - install=False) - - bld.SAMBA_BINARY('ldb_parse_test', - source='tests/ldb_parse_test.c', - deps='cmocka ldb ldb_tdb_err_map', - install=False) - - bld.SAMBA_BINARY('ldb_filter_attrs_test', - source='tests/ldb_filter_attrs_test.c', - deps='cmocka ldb ldb_tdb_err_map', - install=False) - - bld.SAMBA_BINARY('ldb_key_value_sub_txn_tdb_test', - bld.SUBDIR('ldb_key_value', - '''ldb_kv_search.c - ldb_kv_index.c - ldb_kv_cache.c''') + - 'tests/ldb_key_value_sub_txn_test.c', - cflags='-DTEST_BE=\"tdb\"', - deps='cmocka ldb ldb_tdb_err_map', - install=False) - - if bld.CONFIG_SET('HAVE_LMDB'): - bld.SAMBA_BINARY('ldb_mdb_mod_op_test', - source='tests/ldb_mod_op_test.c', - cflags='-DTEST_BE=\"mdb\" -DGUID_IDX=1 ' - + '-DTEST_LMDB=1', - deps='cmocka ldb lmdb', - install=False) - - bld.SAMBA_BINARY('ldb_lmdb_test', - source='tests/ldb_lmdb_test.c', - deps='cmocka ldb', - install=False) - - bld.SAMBA_BINARY('ldb_lmdb_size_test', - source='tests/ldb_lmdb_size_test.c', - deps='cmocka ldb', - install=False) - - bld.SAMBA_BINARY('ldb_mdb_kv_ops_test', - source='tests/ldb_kv_ops_test.c', - cflags='-DTEST_BE=\"mdb\" -DTEST_LMDB=1', - deps='cmocka ldb', - install=False) - - # - # We rely on the versions of the ldb_key_value functions included - # in ldb_key_value_sub_txn_test.c taking priority over the versions - # in the ldb_key_value shared library. - # If this turns out to not be the case, the dependencies will - # need to be unrolled, and all the source files included and the - # ldb_tdb module initialization code will need to be called - # manually. - bld.SAMBA_BINARY('ldb_key_value_sub_txn_mdb_test', - bld.SUBDIR('ldb_key_value', - '''ldb_kv_search.c - ldb_kv_index.c - ldb_kv_cache.c''') + - 'tests/ldb_key_value_sub_txn_test.c', - cflags='-DTEST_BE=\"mdb\"', - deps='cmocka ldb ldb_tdb_err_map', - install=False) - else: - bld.SAMBA_BINARY('ldb_no_lmdb_test', - source='tests/ldb_no_lmdb_test.c', - deps='cmocka ldb', - install=False) - -def test(ctx): - '''run ldb testsuite''' - env = samba_utils.LOAD_ENVIRONMENT() - ctx.env = env - - test_prefix = "%s/st" % (Context.g_module.out) - shutil.rmtree(test_prefix, ignore_errors=True) - os.makedirs(test_prefix) - os.environ['TEST_DATA_PREFIX'] = test_prefix - os.environ['LDB_MODULES_PATH'] = Context.g_module.out + "/modules/ldb" - if env.HAVE_LMDB: - os.environ['HAVE_LMDB'] = '1' - else: - os.environ['HAVE_LMDB'] = '0' - samba_utils.ADD_LD_LIBRARY_PATH('bin/shared') - samba_utils.ADD_LD_LIBRARY_PATH('bin/shared/private') - - cmd = 'tests/test-tdb.sh %s' % Context.g_module.out - ret = samba_utils.RUN_COMMAND(cmd) - print("testsuite returned %d" % ret) - - tmp_dir = os.path.join(test_prefix, 'tmp') - if not os.path.exists(tmp_dir): - os.mkdir(tmp_dir) - pyret = samba_utils.RUN_PYTHON_TESTS( - ['tests/python/api.py', - 'tests/python/index.py', - 'tests/python/repack.py'], - extra_env={'SELFTEST_PREFIX': test_prefix}) - print("Python testsuite returned %d" % pyret) - - cmocka_ret = 0 - test_exes = ['test_ldb_qsort', - 'test_ldb_dn', - 'ldb_msg_test', - 'ldb_tdb_mod_op_test', - 'ldb_tdb_guid_mod_op_test', - 'ldb_msg_test', - 'ldb_tdb_kv_ops_test', - 'ldb_tdb_test', - 'ldb_match_test', - 'ldb_key_value_test', - # we currently don't run ldb_key_value_sub_txn_tdb_test as it - # tests the nested/sub transaction handling - # on operations which the TDB backend does not currently - # support - # 'ldb_key_value_sub_txn_tdb_test' - 'ldb_parse_test'] - - if env.HAVE_LMDB: - test_exes += ['ldb_mdb_mod_op_test', - 'ldb_lmdb_test', - # we don't want to run ldb_lmdb_size_test (which proves we can - # fit > 4G of data into the DB), it would fill up the disk on - # many of our test instances - 'ldb_mdb_kv_ops_test', - 'ldb_key_value_sub_txn_mdb_test'] - else: - test_exes += ['ldb_no_lmdb_test'] - - for test_exe in test_exes: - cmd = os.path.join(Context.g_module.out, test_exe) - cmocka_ret = cmocka_ret or samba_utils.RUN_COMMAND(cmd) - - sys.exit(ret or pyret or cmocka_ret) - -def dist(): - '''makes a tarball for distribution''' - samba_dist.dist() - -def reconfigure(ctx): - '''reconfigure if config scripts have changed''' - import samba_utils - samba_utils.reconfigure(ctx) diff --git a/libldb.spec b/libldb.spec index a1fd727..cad7dc8 100644 --- a/libldb.spec +++ b/libldb.spec @@ -87,7 +87,6 @@ doxygen Doxyfile %check echo disabling one assertion in tests/python/repack.py sed -e '/test_guid_indexed_v1_db/,+18{/toggle_guidindex_check_pack/d}' -i tests/python/repack.py - make %{?_smp_mflags} check %install -- Gitee
    3. k?Sdah|1Tl2w8DJ%u`sUU5?1~egKyK-2RV{!7 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